diff --git a/.gitignore b/.gitignore index 0c32d88d4..40ceff4fc 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,7 @@ jar .classpath .cproject .csettings +.pydevproject *~ *.[ao] /TAGS @@ -112,6 +113,7 @@ src/api/dcps/java/saj/manifest/ install/VC install/HDE install/RTS +install/DRE install/DEMOS install/STE etc/idlpp/SACPP @@ -137,8 +139,11 @@ release_info/RELEASE install/*.HDE*.opensplice.xml install/*.RTS*.opensplice.xml install/*.STE*.opensplice.xml +install/*.DRE*.opensplice.xml +src/services/ddsi2/code examples/tmp/demo/ishapes-java5/generated etc/protobuf/SAJ5/DescriptorProtos.java +etc/protobuf src/tools/cm/dataadapter/code/org/opensplice/cmdataadapter/protobuf/ProtobufDataAdapterImpl.java src/tools/cm/dataadapter/manifest src/tools/protobuf/generated @@ -161,3 +166,10 @@ examples/protobuf/java5/standalone/generated/ src/api/streams/sacpp/include/ccpp_streams_if.h src/api/streams/sacpp/include/streams_dcps.h src/api/streams/sacpp/include/streams_dcpsSplDcps.h +src/api/dcps/sacs/code/DDS/AssemblyAttributes.cs +src/api/dcps/java/cj_y2038_ready/manifest +src/api/face/java/manifest +examples/**/target +examples/**/*.jar +src/api/dcps/java**/target +src/api/dcps/java**/*.jar diff --git a/LICENSE b/LICENSE new file mode 100644 index 000000000..93f99f22e --- /dev/null +++ b/LICENSE @@ -0,0 +1,526 @@ + SOFTWARE LICENSE AGREEMENT + +This license agreement ('Agreement') is a legal agreement between +you, a single corporate entity ('Licensee') and ADLINK Technology +Limited or its affiliated company with which your purchase order +is placed and accepted ('Licensor'), for use of Licensor's +(and / or its affiliates) and / or its licensor's proprietary +software products,which include any computer software, printed +materials, "online" or electronic documentation and any upgrades +or modifications thereto ("the Software"). +By placing a purchase order for the Software, installing, +copying, or otherwise using the Software, Licensee agrees to be +bound by the terms and conditions of this Agreement. +IF LICENSEE DOES NOT AGREE TO THE TERMS AND CONDITIONS +OF THIS AGREEMENT THEN DO NOT INSTALL COPY OR USE THE SOFTWARE +and either immediately destroy the Software or return it within +15 days of receipt to the place of purchase in exchange for a full +refund. Clauses 3 and 4 of this Agreement are not applicable to +Licensee, if Licensee has not purchased the Software license(s) +directly from Licensor, in which event use of the Software shall +be subject to all other clauses of this Agreement. + +THIRD PARTY OPENSOURCE SOFTWARE ('OS SOFTWARE') MAY BE SUPPLIED +WITH THE SOFTWARE. IN THIS EVENT SUCH OS SOFTWARE IS SUBJECT TO +THE APPLICABLE LICENSE TERMS INCORPORATED IN THE OS SOFTWARE. +LICENSEE ACKNOWLEDGES THAT THE OS SOFTWARE IS SUPPLIED FREE, +WITHOUT LICENSE FEES AND IS THEREFORE PROVIDED WITH NO WARRANTIES +OF ANY KIND INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY +AND FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR ARISING +FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. EXCEPT TO THE +EXTENT PROHIBITED BY APPLICABLE LAW LICENSOR SHALL HAVE NO +LIABILITY IN RESPECT OF THE OS SOFTWARE, FOR DAMAGES OF ANY KIND +INCLUDING ANY INDIRECT OR CONSEQUENTIAL LOSS (INCLUDING WITHOUT +LIMITATION, LOSS OF USE; DATA; INFORMATION; BUSINESS; PRODUCTION +OR GOODWILL), EXEMPLARY OR INCIDENTAL DAMAGES, LOST PROFITS OR +OTHER SPECIAL OR PUNITIVE DAMAGES WHATSOEVER, WHETHER IN CONTRACT, +TORT, (INCLUDING NEGLIGENCE, STRICT LIABILITY AND ALL OTHERS), +WARRANTY, INDEMNITY OR UNDER STATUTE, EVEN IF LICENSOR HAS BEEN +ADVISED OF THE LIKELIHOOD OF SAME. + +The following terms and conditions of this Agreement apply to the +Software but do not apply to any OS Software that may be supplied +with the Software: + +The parties hereby agree as follows: + +1. Grant of License + +1.1 The Software and all associated copyrights and other +intellectual property rights are the property of the Licensor, its +affiliated companies, or its licensors. Licensee acquires no +title, right or interest in the Software other than the license +granted herein. + +1.2 Licensor hereby grants to Licensee, subject to payment of the +appropriate license fees, the non-exclusive non-transferable +(without the right to sub- license) license to use the Software in +object code form only, subject to the terms and conditions of this +Agreement. + +1.3 The particular Software licensed, license term, type and +number of licenses and any additional restrictions, not contained +herein, concerning use of the Software, such as specified Licensee +site(s), designated computer hardware, and/or operating system, use +in conjunction with particular other software, or the number of +authorized users shall be in accordance with the particular +transaction between us, as confirmed in Licensor's order +acknowledgement. + +1.4 Unless otherwise agreed in writing, the following +restrictions apply to development and deployment Software licenses +purchased for use of Licensor's middleware products: + +1.4.1 Single User Development License - a per user license +permitting a single person to use the Software for development +purposes only, to develop and/or test Licensee applications on a +single self contained computer hardware system, on one operating +system platform only, on one specified project only. The term "use" +comprises designing, developing, testing, or maintaining software +which invokes functionality of the Software. The Software shall not +be used for deploying a particular application created with the +Software, for which purposes a Deployment License is required. All +individuals who are authorized by Licensee to use the Software as +described herein regardless of whether the individual is actively +using the Software at any given time must be covered by a Single +User Development License. Licenses are non-transferable between +computer systems and users; + +1.4.2 Project Unlimited User Development License - a multi user +license permitting any number of persons assigned to a specified +project, to use the Software for development purposes only, to +develop and/or test Licensee applications on a single self +contained computer hardware system, on one operating system +platform only. The term "use" comprises designing, developing, +testing, or maintaining Licensee application software source code +which either directly or indirectly invokes the Application +Programming Interfaces ("APIs") of the Software. The Software +shall not be used for deploying a particular application created +with the Software in an production environment, for which purposes +a Deployment License is required. Licenses are non-transferable +between computer systems and users. + +1.4.3 Floating Development License - a user license permitting +Licensee to install the Software on multiple computer hardware +systems and to use the Software for the same purposes as under a +Single User Development License, on one operating system only, +on one specified project only, provided there is never more than +one (1) concurrent user per license. + +1.4.4 Deployment License: a machine license permitting Licensee +to run the Software with Licensee's applications in a live +operational environment on a specified project. + +1.5 Unless otherwise agreed in writing, the following +restrictions apply to Software licenses purchased for use of +Licensor's development productivity tools: + +1.5.1 Single User Tools License - a per user license permitting +a single person to use the Software to develop, test, and +demonstrate Licensee applications on a single self contained host +computer hardware system on one operating system platform only, on +one specified project only. All individuals who are authorized by +Licensee to use the Software as described herein regardless of +whether the individual is actively using the Software at any given +time must be covered by a Single User Tools License. Licenses are +non-transferable between computer systems and users. One license +is required per host operating system and one license is required +per target language and per target operating system. The +intellectual property rights in any application code generated by +Licensee using the Software, excluding any code that is a +derivative of the Software shall be vested immediately on its +creation, in the Licensee. + +1.5.2 Floating Tools License - a license permitting Licensee to +install the Software on multiple host computer hardware systems, +and to use the Software for the same purposes as under a Single +User Tools License, on one operating system platform only, on one +specified project only, provided there is never more than one +(1) concurrent user per license. One license is required per host +operating system and one license is required per target language +and per target operating system. The intellectual property rights +in any application code generated by Licensee using the Software, +excluding any code that is a derivative of the Software, +shall be vested immediately on its creation, in the Licensee. + +1.6 Licensee acknowledges that the Software may not operate +without a license key ('License Key') and Licensee agrees to +provide Licensor with any necessary information requested by +Licensor in order to generate and provide the License Key(s). Such +information may include specific computer IP and / or Host ID +addresses and / or other relevant information relating to the type +and number of licenses purchased. Licensor reserves the right to +withhold or delay the issue of any permanent License Key(s) in the +event the Licensee is in breach of this Agreement, until such +breach has been remedied. Licensee shall maintain records of the +number and type of licenses purchased including appropriate +details such as named users allocated and computers on which +Software is installed and shall provide a copy of such records to +Licensor on request. + +1.7 Licensee shall use the Software solely for its own internal +business purposes. Licensee shall not provide or otherwise make +available the Software in whole or in part to any third party and +Licensee shall not permit any third party to use the Software +without the written consent of Licensor. Licensee shall not, or +permit any third party to, publish or disclose the results of any +performance or benchmark tests relating to the Software without +the written consent of Licensor. + +1.8 Subject to compliance with all other terms of this Agreement +by Licensee, Licensor's consent referred to in Clauses 1.7 and +9.1 is granted hereunder to make the Software available to third +party contractors of Licensee provided that such contractors must +be bound by written agreement to compliance with the terms of this +Agreement (save for Clauses 3 and 4). Licensee shall ensure +compliance by such third party contractors to such terms. + +1.9 Licensee may make a reasonable number of copies of the +Software for back- up, archival or disaster recovery purposes. Any +copy must include Licensor's copyright notice and is fully subject +to the terms of this Agreement. Licensee shall not other than as +permitted by the Agreement or Licensor's written authorization or +by law copy, reproduce, translate, adapt, de-compile, modify, +reverse engineer, disassemble the Software or create derivative +works of the Software. If Licensee requires information relating +to the Software necessary to achieve inter-operability with an +independently created software program, Licensee shall make a +written request to Licensor to make available such information. +Licensee shall not be entitled to make any copies of any hard copy +documentation supplied by Licensor relating to the Software. + +1.10 In the event that the Software contains or is accompanied by +certain third party software products such third party software is +subject to the respective third party license terms as may be set +forth within the third party software. + +2 Example Code + +IN THE EVENT ANY ANCILLARY EXAMPLE COMPUTER SOFTWARE SOURCE CODE +IS SUPPLIED WITH THE SOFTWARE, (INCLUDING BUT NOT LIMITED TO JAVA +OR C++ EXAMPLE CODE) SUCH CODE IS SUPPLIED AS IS WITHOUT WARRANTY +OF ANY KIND. LICENSEE IS GRANTED A ROYALTY FREE LICENSE TO USE, +COPY AND MODIFY SUCH CODE ENTIRELY AT ITS OWN RISK. IN VIEW +HOWEVER OF THE LIMITED NATURE OF SUCH CODE LICENSOR SHALL (EXCEPT +AS OTHERWISE PROHIBITED BY LAW) HAVE NO LIABILITY WHATSOEVER IN +RELATION TO ITS USE. IN ALL OTHER RESPECTS USE OF SUCH CODE SHALL +BE SUBJECT TO THE TERMS AND CONDITIONS OF THIS AGREEMENT. + +3 License Fee + +3.1 Unless otherwise advised prior to acceptance of order by +Licensor. Licensor shall grant Licensee a credit facility and +Licensee shall pay Licensor the license fee within 30 days of the +date of Licensor's invoice. + +3.2 The license fee excludes any updates, maintenance, support, +training or consulting in respect of the Software. + +3.3 The license fee is exclusive of all sales or value added +taxes, customs duties or government levies (if any) which if +applicable shall be reimbursed by Licensee at cost to Licensor. + +3.4 In the event payment is not made within 30 days of invoice, by +the Licensee, Licensor shall be entitled to charge Licensee a late +payment fee of 1% per month, of the overdue amount during the +period of delayed payment (both before and after any judgment) +without prejudice to Licensor's right to receive payments on the +due dates. + +3.5 In the event of non-payment by Licensee of any sum due +hereunder by the due date, Licensor may serve notice of such +default upon Licensee, and if Licensee fails to pay in full all +amounts owed hereunder within a period of 30 days of receipt of +such notice, then Licensor may immediately terminate this +Agreement in addition to any other rights Licensor may have in +respect of such non-payment. Licensor also reserves the right, +without liability, to forthwith suspend the licenses granted under +this Agreement, in the event any payment is overdue from Licensee. + +4 Delivery and Acceptance + +Further to acceptance of Licensee's order, Licensor shall deliver +one copy of the Software in machine-readable object code form and +applicable License Key(s), or if a copy of the Software is already +in possession of Licensee under the terms of a prior evaluation +license, then applicable License Key(s) only. Licensor shall use +reasonable endeavors to deliver within two (2) working days of order +acceptance but shall be under no liability in the event of failure +to deliver within this time-scale, which is an estimate only. +Unless otherwise agreed in writing delivery terms are FCA (as +defined in IncoTerms 2000) Licensor's premises. In the event the +Software has been evaluated by the Licensee under the terms of an +evaluation license, prior to purchase, the Software shall be +deemed accepted upon use of the Software under this Agreement. If +the Software has not been subject to such prior evaluation, +Licensee may reject the Software within 30 days of delivery if the +Software does not materially comply with the user documentation +provided and return it to Licensor in exchange for a full refund. + +5 Term + +The license under this Agreement commences upon delivery of the +Software to Licensee or if a copy of the Software is already in +possession of Licensee under the terms of a prior evaluation +license, upon issue of Licensor's order acknowledgment and shall +continue for the term specified in the particular transaction +between us, as confirmed in Licensor?s order acknowledgement, +unless terminated sooner in accordance with this Agreement. + +6 Warranty and Liability + +6.1 LICENSOR SPECIFICALLY DISCLAIMS ANY WARRANTY THAT USE OF THE +SOFTWARE WILL BE UNINTERRUPTED OR ERROR-FREE OR THAT THE FUNCTIONS +CONTAINED IN THE SOFTWARE OR THE RESULTS OF USE WILL MEET +LICENSEE'S REQUIREMENTS. + +6.2 IF WITHIN 90 DAYS OF DELIVERY OF THE SOFTWARE TO LICENSEE THE +LICENSEE DISCOVERS ANY PHYSICAL DEFECTS IN THE MEDIUM ON WHICH THE +SOFTWARE IS SUPPLIED AND LICENSOR IS GIVEN WRITTEN NOTICE OF THIS +BY LICENSEE WITHIN THAT 90 DAY PERIOD AND THE DEFECTIVE MEDIUM IS +RETURNED TO LICENSOR THEN LICENSOR SHALL REPLACE SUCH MEDIUM AND +COPY OF THE SOFTWARE AT NO CHARGE TO LICENSEE. + +6.3 LICENSOR DOES NOT EXCLUDE OR LIMIT ITS LIABILITY IN NEGLIGENCE +FOR DEATH OR PERSONAL INJURY, OR FOR FRAUD, OR OTHERWISE INSOFAR +AS ANY EXCLUSION OR LIMITATION OF ITS LIABILITY IS VOID, +PROHIBITED OR UNENFORCEABLE BY LAW. + +6.4 SUBJECT TO CLAUSE 6.5 BELOW, LICENSOR WILL ACCEPT LIABILITY +FOR DAMAGE TO PHYSICAL PROPERTY CAUSED DIRECTLY BY LICENSOR OR ITS +EMPLOYEES, NOT EXCEEDING THE SUM OF US$1,000,000 (ONE MILLION US +DOLLARS) PER CLAIM OR SERIES OF CLAIMS. + +6.5 SAVE AS PROVIDED IN CLAUSE 6.3 ABOVE, IN NO EVENT WHATSOEVER +WILL LICENSOR BE LIABLE FOR ANY INDIRECT OR CONSEQUENTIAL LOSS +(OTHER THAN DIRECT PHYSICAL DAMAGE TO TANGIBLE PROPERTY UNDER +CLAUSE 6.4 ABOVE) OR ECONOMIC LOSS: LOSS OF USE, DATA, +INFORMATION, BUSINESS, REVENUE, PROFITS, PRODUCTION, GOODWILL +OR ANTICIPATED SAVINGS), EXEMPLARY OR INCIDENTAL DAMAGES, OR OTHER +SPECIAL OR PUNITIVE DAMAGES WHATSOEVER, WHETHER IN CONTRACT, TORT, +(INCLUDING NEGLIGENCE, STRICT LIABILITY AND ALL OTHERS), WARRANTY, +INDEMNITY OR UNDER STATUTE, EVEN IF LICENSOR HAS BEEN ADVISED OF +THE LIKELIHOOD OF SAME. + +6.6 ANY CONDITION, REPRESENTATION OR WARRANTY WHICH MIGHT +OTHERWISE BE IMPLIED OR INCORPORATED WITHIN THIS AGREEMENT BY +REASON OF STATUTE OR COMMON LAW OR OTHERWISE, INCLUDING WITHOUT +LIMITATION THE IMPLIED WARRANTIES OF MERCHANTABLE OR SATISFACTORY +QUALITY AND FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON- +INFRINGEMENT ARE HEREBY EXPRESSLY EXCLUDED TO THE FULLEST EXTENT +PERMITTED BY LAW. + +6.7 SUBJECT TO CLAUSE 6.3 ABOVE, IN THE EVENT THAT LICENSEE +CHOOSES TO USE A VERSION OF THE SOFTWARE NO LONGER GENERALLY +SUPPORTED BY LICENSOR UNDER THE TERMS OF LICENSOR'S SOFTWARE +SUPPORT AGREEMENT AND DOES NOT PURCHASE AND MAINTAIN A VALID +SUPPORT CONTRACT FOR THAT SPECIFIC VERSION THEN LICENSEE USES SUCH +VERSION ENTIRELY AT ITS OWN RISK AND LICENSOR SHALL HAVE NO +LIABILITY WHATSOEVER RELATED TO ITS USE. + +6.8 SUBJECT TO CLAUSE 6.3 ABOVE, IN THE EVENT THAT NOTWITHSTANDING +THE PROVISIONS OF THIS AGREEMENT LICENSOR IS FOUND LIABLE FOR ANY +LOSS OR DAMAGE SUFFERED BY LICENSEE ARISING OUT OF OR IN +CONNECTION WITH THIS AGREEMENT, WHETHER IN CONTRACT, TORT +(INCLUDING NEGLIGENCE, STRICT LIABILITY AND ALL OTHERS) BREACH OF +STATUTORY DUTY OR OTHERWISE THAT LIABILITY SHALL IN NO EVENT +EXCEED THE SUMS RECEIVED BY LICENSOR FOR THE SOFTWARE LICENSED +UNDER THIS AGREEMENT. + +6.9 LICENSEE HEREBY WAIVES ANY RIGHT TO ANY OTHER REMEDIES OR +RELIEFS NOT SET OUT IN THIS AGREEMENT AND SUCH WAIVER SHALL +SURVIVE THE TERMINATION OF THIS AGREEMENT HOWEVER SUCH TERMINATION +ARISES. + +7 Intellectual Property Rights + +7.1 All title, trademarks and copyrights in and pertaining to the +Software (including but not limited to any images, photographs, +animation, video, audio, music, text, and applets incorporated +into the Software), and any copies of the Software are owned by +Licensor, its affiliated companies, or licensors. The Software is +protected by copyright, other intellectual property rights, +trademark laws and international treaty provisions. Licensee must +treat the Software like any other copyrighted material for +archival purposes, and Licensee may not copy the printed materials +accompanying the Software. + +7.2 Licensee may not remove, modify or alter any Licensor +copyright or trademark notice from any part or copies of the +Software, including but not limited to any such notices contained +in the physical and/or electronic media or documentation, in +Licensor's installation dialogue or 'about' boxes, in any of the +run-time resources and/or in any web-presence or web-enabled +notices, code or other embodiments originally contained in or +dynamically or otherwise created by the Software. + +7.3 If the Software is, or in Licensor's opinion may become, the +subject of a claim for infringement of the intellectual property +rights of a third party, Licensor may at its option and as +Licensee's sole remedy: + +7.3.1 procure the right to continued use of the Software; + +7.3.2 replace or modify the Software to make it non-infringing; +or + +7.3.3 repay to the Licensee the license fee (less a fair value +for prior use) and terminate this Agreement. + +8 Termination + +8.1 Licensor may by notice in writing to Licensee terminate this +Agreement if Licensee: + +8.1.1 commits a breach of this Agreement; or + +8.1.2 has ceased business, been adjudged bankrupt or insolvent +under the laws of any jurisdiction, made an assignment for the +benefit of creditors, or filed, or had filed against it, a +petition of bankruptcy, re-organization or other insolvency +proceeding. + +8.2 Within 14 days following the date of termination of this +Agreement, Licensee shall cease to use the Software and shall at +Licensor's direction either destroy or return to Licensor all of +the Software including copies together with Licensee's written +certification by a duly authorized officer that this clause has +been complied with in full. + +8.3 Termination of this Agreement shall be in addition to and not +a waiver of any remedy available to Licensor arising from +Licensee's breach of this Agreement. + +9 Assignment + +9.1 Licensee shall not assign sub-license or otherwise transfer +any of the rights or obligations under this Agreement without the +prior written consent of Licensor. + +9.2 Licensor shall be entitled without the prior written consent +of Licensee to assign sub-contract or otherwise transfer its +rights and obligations under this Agreement. + +10 Reference + +Licensee permits Licensor to reference Licensee as a user of the +Software and display Licensee's logo in Licensor's marketing +documentation and on its worldwide web site. + +11 Export Regulations + +By downloading or using the Software, Licensee represents and +warrants that it is not located in under the control of or a +national or resident of any country which is subject to an +applicable embargo or other trade restriction imposed by the U.S. +or other government. Licensee shall not import, export, or re- +export the Software to or from any country in contravention of any +applicable import or export laws or regulations of the United +States or other government. + +12 High Risk Activities + +The Software is not designed, produced or intended for fail-safe +performance in applications used in hazardous environments in +which the failure of the Software itself could lead directly to +death, personal injury, or severe physical or environmental +damage, such as in the operation of nuclear facilities, aircraft +navigation or communication systems, air traffic control, direct +life support machines, or weapons systems, ("High Risk +Activities"). Licensor specifically disclaims any express or +implied warranty of fitness for High Risk Activities and Licensee +hereby indemnifies and holds harmless Licensor against claims of +any nature arising from failure of the Software when used by it or +its customers for High Risk Activities. + +13 Audit Rights + +Licensor reserves the right, with reasonable notice and at +reasonable times, not exceeding one time per year, to conduct an +audit of Licensee's records to the extent only that is reasonably +necessary to confirm Licensee's compliance with the terms of this +Agreement. Without prejudice to any other rights of Licensor, in +the event such audit reveals that copies of the Software have been +made or are in use in breach of this Agreement, Licensee shall be +liable to pay to the Licensor, as liquidated damages, Licensor's +prevailing list price for each such copy and shall reimburse +Licensor's costs of conducting such audit. + +14 US Government End Users + +The Software and documentation included therein are 'commercial +items' as that term is defined in 48 C.F.R. 2.101 (October 1995) +consisting of 'commercial computer software' and 'commercial +computer software documentation' as such terms are used in +48 C.F.R. 227.7202-1, 227.7202-3 and 227.7202-4 (June 1995). If +the Licensee hereunder is the U.S. Government or any agency or +department thereof, the Software is licensed hereunder (i) only as +a commercial item, and (ii) with only those rights as are granted +to all other end users pursuant to the terms and conditions of +this Agreement. + +15 General + +15.1 If this Agreement is entered into with an ADLINK Technology +Limited affiliated company located in the United States of America, +then this Agreement shall be governed by and construed in +accordance with the substantive laws of the Commonwealth of +Massachusetts, without giving effect to the principles of conflict +or choice of law of such Commonwealth. If this Agreement is +entered into with an ADLINK Technology Limited affiliated company +located in any other jurisdiction than the United States of +America, then this Agreement: (i) shall be governed by and +construed in accordance with the laws of England and all disputes +arising in connection with this Agreement shall be subject to the +non-exclusive jurisdiction of the English courts and (ii) is +enforceable by the original parties to it and by their successors +in title and permitted assignees. No term of this Agreement is +enforceable under the Contracts (Rights of Third Parties) Act 1999 +by a person who is not a party to this Agreement. +The original of this Agreement has been written in +English. The parties hereto waive any statute, law, or regulation +that might provide an alternative law or forum or to have this +Agreement written in any language other than English. + +15.2 Neither party shall be in breach of this Agreement if +there is any total or partial failure of performance by it of its +duties and obligations under this Agreement which is due to causes +beyond its reasonable control provided that the party affected by +such causes gives notice in writing to the other party at the +commencement and cessation of these causes. + +15.3 Any notice or other communication required or permitted +under this Agreement shall be given in writing to the address of +the recipient as notified from time to time and will be deemed to +have been given or made when delivered personally; if properly +addressed and posted by prepaid certified or registered mail +within three business days of posting; if sent by facsimile upon +being sent, if confirmed by post; or electronically upon receipt +if acknowledged to have been received. + +15.4 This Agreement contains the entire agreement between the +Licensor and the Licensee relating to the licensing of the +Software and subject to Clause 6.3, supersedes all prior oral or +written understanding, arrangements, representations or agreements +between them relating to the subject matter of this Agreement. No +amendment, variation or discharge of this Agreement is valid +unless accepted in writing by both parties. The parties expressly +agree that the terms and conditions of this Agreement shall +prevail over any standard terms and conditions printed or referred +to in any purchase order or other written documentation issued by +the Licensee. + +15.5 The failure of either party to exercise or enforce any +rights under this Agreement shall not amount to a waiver of those +rights. + +15.6 The illegality or invalidity of any part of this Agreement +shall not affect the legality or validity of the remainder of it. +Any provision of the Agreement held to be to be excessively broad +as to scope, activity, subject or otherwise so as to be +unenforceable at law shall be constructed by limiting or reducing +it so as to be enforceable to the maximum extent compatible with +the applicable law then prevailing. + +Licenseterms Rev 2.7 2nd October 2014 + diff --git a/MPC/config/_repetitive_c99_example_types.mpb b/MPC/config/_repetitive_c99_example_types.mpb old mode 100644 new mode 100755 diff --git a/MPC/config/_repetitive_isocpp_example_impl.mpb b/MPC/config/_repetitive_isocpp_example_impl.mpb deleted file mode 100644 index 038fddf14..000000000 --- a/MPC/config/_repetitive_isocpp_example_impl.mpb +++ /dev/null @@ -1,16 +0,0 @@ -// -*- MPC -*- -// $Id:$ - -project : ospl_dcpsisocpp, _example_dcps_impl_lib, c_or_cplusplus_example { - after += ISO_Cxx*Types - libs += ISO_Cxx*Types - libpaths += . - requires += dcps_isocpp_example - Source_Files { - implementation.cpp - } - - Documentation_Files { - ../../. - } -} diff --git a/MPC/config/_repetitive_isocpp_example_ping.mpb b/MPC/config/_repetitive_isocpp_example_ping.mpb deleted file mode 100644 index 8de36cdac..000000000 --- a/MPC/config/_repetitive_isocpp_example_ping.mpb +++ /dev/null @@ -1,15 +0,0 @@ -// -*- MPC -*- -// $Id:$ - -project : ospl_dcpsisocpp, c_or_cplusplus_example { - libpaths += . - requires += dcps_isocpp_example - after += ISO_Cxx*Impl - libs += ISO_Cxx*Impl ISO_Cxx*Types - Header_Files { - } - - Source_Files { - ping.cpp - } -} diff --git a/MPC/config/_repetitive_isocpp_example_pong.mpb b/MPC/config/_repetitive_isocpp_example_pong.mpb deleted file mode 100644 index f65a73be8..000000000 --- a/MPC/config/_repetitive_isocpp_example_pong.mpb +++ /dev/null @@ -1,15 +0,0 @@ -// -*- MPC -*- -// $Id:$ - -project : ospl_dcpsisocpp, c_or_cplusplus_example { - libpaths += . - requires += dcps_isocpp_example - after += ISO_Cxx*Impl - libs += ISO_Cxx*Impl ISO_Cxx*Types - Header_Files { - } - - Source_Files { - pong.cpp - } -} diff --git a/MPC/config/_repetitive_isocpp_example_pub.mpb b/MPC/config/_repetitive_isocpp_example_pub.mpb deleted file mode 100644 index 7dfba9f64..000000000 --- a/MPC/config/_repetitive_isocpp_example_pub.mpb +++ /dev/null @@ -1,15 +0,0 @@ -// -*- MPC -*- -// $Id:$ - -project : ospl_dcpsisocpp, c_or_cplusplus_example { - libpaths += . - requires += dcps_isocpp_example - after += ISO_Cxx*Impl - libs += ISO_Cxx*Impl ISO_Cxx*Types - Header_Files { - } - - Source_Files { - publisher.cpp - } -} diff --git a/MPC/config/_repetitive_isocpp_example_sub.mpb b/MPC/config/_repetitive_isocpp_example_sub.mpb deleted file mode 100644 index 4b58b732e..000000000 --- a/MPC/config/_repetitive_isocpp_example_sub.mpb +++ /dev/null @@ -1,15 +0,0 @@ -// -*- MPC -*- -// $Id:$ - -project : ospl_dcpsisocpp, c_or_cplusplus_example { - libpaths += . - requires += dcps_isocpp_example - after += ISO_Cxx*Impl - libs += ISO_Cxx*Impl ISO_Cxx*Types - Header_Files { - } - - Source_Files { - subscriber.cpp - } -} diff --git a/MPC/config/_repetitive_isocpp_example_types.mpb b/MPC/config/_repetitive_isocpp_example_types.mpb deleted file mode 100644 index 213c724dd..000000000 --- a/MPC/config/_repetitive_isocpp_example_types.mpb +++ /dev/null @@ -1,16 +0,0 @@ -// -*- MPC -*- -// $Id:$ - -project : dcps_typesupport_base, ospl_dcpsisocpp, ospl_dcps_cpp_app_base_libs, _example_dcps_type_lib, c_or_cplusplus_example { - splice_ts_flags += -l isocpp - requires += dcps_isocpp_example - TypeSupport_Files { - ../idl - } - Source_Files { - } - - Documentation_Files { - ../. - } -} diff --git a/MPC/config/build_ospl_dcpsisocpp2.mpb b/MPC/config/build_ospl_dcpsisocpp2.mpb index f17f3e61f..de244049e 100644 --- a/MPC/config/build_ospl_dcpsisocpp2.mpb +++ b/MPC/config/build_ospl_dcpsisocpp2.mpb @@ -6,8 +6,8 @@ project : ospl_build_lib, dcps_typesupport_base, ospl_base, ospl_ddsuser { specific(prop:windows) { splice_ts_flags += -P OS_API,cpp_dcps_if.h - } + } sharedname = dcpsisocpp2 // Always put $BOOST_ROOT on 'in case' users want to rebuild. DO NOT remove the trailing /. @@ -18,12 +18,16 @@ feature(isocpp2_cxx11) { specific (make) { extracppflags += -std=c++0x } + specific (prop:windows) { + macros += OSPL_USE_CXX11 + } } feature(!src_co) { includes += isocpp2/generated includes += $(OSPL_HOME)/include/dcps/C++/SACPP includes += $(OSPL_HOME)/include/dcps/C++/isocpp2 + includes += isocpp2/generatedIoTData specific (make) { obj_dir = .objisocpp2/ @@ -37,8 +41,14 @@ feature(!src_co) { $(OSPL_HOME)/etc/idl/dds_namedQosTypes.idl } + TypeSupport_Files { + splice_ts_flags += -l isocpp2 -d isocpp2/generatedIoTData + $(OSPL_HOME)/etc/idl/dds_IoTData.idl + } + // Put the headers and inline code into the include dir postbuild = <%cp%> .<%slash%>isocpp2<%slash%>generated<%slash%>*.h <%quote%>$(OSPL_HOME)<%slash%>include<%slash%>dcps<%slash%>C++<%slash%>SACPP<%quote%> + postbuild += <%cp%> .<%slash%>isocpp2<%slash%>generatedIoTData<%slash%>*.h* <%quote%>$(OSPL_HOME)<%slash%>include<%slash%>dcps<%slash%>C++<%slash%>isocpp2<%slash%>org<%slash%>opensplice<%slash%>dds<%slash%>iot<%quote%> recurse = 1 Source_Files { isocpp2 @@ -58,6 +68,7 @@ feature(src_co) { includes += $(OSPL_HOME_NORMALIZED)/src/api/dcps/c++/sacpp/include includes += $(OSPL_HOME_NORMALIZED)/src/api/dcps/c++/sacpp/bld/$(SPLICE_TARGET) includes += include + includes += $(OSPL_HOME_NORMALIZED)/src/api/dcps/isocpp2/bld/$(SPLICE_TARGET) // idlpp code generation TypeSupport_Files { @@ -66,6 +77,11 @@ feature(src_co) { $(OSPL_HOME_NORMALIZED)/etc/idl/dds_dcps_builtintopics.idl $(OSPL_HOME_NORMALIZED)/etc/idl/dds_namedQosTypes.idl } + + TypeSupport_Files { + splice_ts_flags += -l isocpp2 -d $(OSPL_HOME_NORMALIZED)/src/api/dcps/isocpp2/bld/$(SPLICE_TARGET) + $(OSPL_HOME)/etc/idl/dds_IoTData.idl + } recurse = 1 Source_Files { code diff --git a/MPC/config/c99_dcps_app_libs.mpb b/MPC/config/c99_dcps_app_libs.mpb old mode 100644 new mode 100755 diff --git a/MPC/config/c99_dcps_application.mpb b/MPC/config/c99_dcps_application.mpb old mode 100644 new mode 100755 diff --git a/MPC/config/c99_typesupport.mpb b/MPC/config/c99_typesupport.mpb old mode 100644 new mode 100755 diff --git a/MPC/config/csharp.mpb b/MPC/config/csharp.mpb index fe3e138fd..adcc1719d 100644 --- a/MPC/config/csharp.mpb +++ b/MPC/config/csharp.mpb @@ -20,7 +20,16 @@ project { // add '.' as a reference path as it is relative. Please specify // an absolute path." on C# project load into the IDE libpaths -= . - } + } + // needed to expand the env var into an actual value + expand(ospl_dotnet) { + $DOTNET + } + + specific(prop:windows) { + TargetFrameworkVersion = $(ospl_dotnet) + } + } // force platform to 32 bit when compiling for a 32 bit platform // default AnyCPU gives problems when compiled on a 64 bit architecture see OSPL-6171 diff --git a/MPC/config/default.features b/MPC/config/default.features old mode 100644 new mode 100755 index b57077617..f3e51113f --- a/MPC/config/default.features +++ b/MPC/config/default.features @@ -71,6 +71,8 @@ ospl_os_host_solaris = 0 // Compilers (and other variations) ospl_compiler_studio = 0 ospl_compiler_gcc = 0 +ospl_gcc_5 = 0 +ospl_gcc_6 = 0 // VxWorks 6.5, 6.6, and 6.7 have libs under target/usr/lib, so set to 1 ospl_vxworks_libs_in_target_usr_lib=0 @@ -102,7 +104,9 @@ cortexa9t_neon_WRlinux5_gcc = 0 cortexa9t_yocto = 0 armv7l_linux = 0 armv7a_vfp_neon_linux = 0 +armv7a_lafp_neon_linux = 0 armv7at2_vfp_neon_WRlinux7_gcc = 0 +aarch64_zynqmp_linux = 0 intel_atom_WRlinux5_gcc = 0 x86_WRlinux7_gcc = 0 x86_64_WRlinux7_gcc = 0 diff --git a/MPC/config/ospl_dcpsc99.mpb b/MPC/config/ospl_dcpsc99.mpb old mode 100644 new mode 100755 diff --git a/MPC/config/ospl_dcpsisocpp2.mpb b/MPC/config/ospl_dcpsisocpp2.mpb index b30ba040c..7a8f09aa7 100644 --- a/MPC/config/ospl_dcpsisocpp2.mpb +++ b/MPC/config/ospl_dcpsisocpp2.mpb @@ -14,6 +14,9 @@ feature(isocpp2_cxx11) { specific (make) { extracppflags += -std=c++0x } + specific (prop:windows) { + macros += OSPL_USE_CXX11 + } } feature(!src_co) { diff --git a/MPC/config/splice_targets.mpb b/MPC/config/splice_targets.mpb index ef4c731aa..a8b108761 100644 --- a/MPC/config/splice_targets.mpb +++ b/MPC/config/splice_targets.mpb @@ -168,12 +168,18 @@ feature (ospl_os_linux, ospl_arch_PPCe5500) { } } -feature (ospl_os_linux, ospl_arch_armhf) { +feature (ospl_os_linux, ospl_arch_armhf, ospl_gcc_5) { specific (make) { compilers = arm-linux-gnueabihf-gcc-5 } } +feature (ospl_os_linux, ospl_arch_armhf, ospl_gcc_6) { + specific (make) { + compilers = arm-linux-gnueabihf-gcc-6 + } +} + feature (ospl_os_qnx, ospl_arch_x86) { specific (make) { compilers = x86-qcc @@ -603,12 +609,24 @@ feature(armv7a_vfp_neon_linux) { } } +feature(armv7a_lafp_neon_linux) { + specific (make) { + compilers = arm-lafp-linux-gnueabi-gcc + } +} + feature(armv7at2_vfp_neon_WRlinux7_gcc) { specific (make) { compilers = armv7at2-vfp-neon-WRlinux7-gcc } } +feature(aarch64_zynqmp_linux, cross_compile) { + specific (make) { + compilers = aarch64-linux-gnu-gcc + } +} + feature(cortexa9t_neon_WRlinux5_gcc) { specific (make) { compilers = cortexa9t-neon-wrswrap-linux-gnueabi-gcc diff --git a/MPC/templates/user_makedll.mpt b/MPC/templates/user_makedll.mpt index 82fba7cbc..04a637ab7 100644 --- a/MPC/templates/user_makedll.mpt +++ b/MPC/templates/user_makedll.mpt @@ -45,6 +45,19 @@ arm-linux-gnueabihf-gcc-5 { visopt = -fvisibility=hidden -fvisibility-inlines-hidden } +arm-linux-gnueabihf-gcc-6 { + cc = arm-linux-gnueabihf-gcc-6 + cxx = arm-linux-gnueabihf-g++-6 + linkflags = + pic = -fpic + shflags = -shared + platforms = plat_armhf_linux + pchcreate = "-o " + pchnobj = 1 + checkopt = -Wall -Wextra -pedantic -fsyntax-only + visopt = -fvisibility=hidden -fvisibility-inlines-hidden +} + powerpc-fsl-linux-gcc { cc = powerpc-fsl-linux-gcc cxx = powerpc-fsl-linux-g++ @@ -175,6 +188,17 @@ arm7a-vfp-neon-linux-gcc { } +arm-lafp-linux-gnueabi-gcc { + cc = arm-lafp-linux-gnueabi-gcc + cxx = arm-lafp-linux-gnueabi-g++ + platforms = armv7a_lafp_neon_linux + compilerflags = -march=armv7-a -mtune=cortex-a9 -marm -mfloat-abi=hard -mfpu=neon --sysroot=$(SDKTARGETSYSROOT) + linker = arm-lafp-linux-gnueabi-ld + pic = -fPIC + shflags = -shared + +} + armv7at2-vfp-neon-WRlinux7-gcc { cc = arm-wrs-linux-gnueabi-gcc cxx = arm-wrs-linux-gnueabi-g++ @@ -459,6 +483,18 @@ clang { covopt = -fprofile-arcs -ftest-coverage } +aarch64-linux-gnu-gcc { + cc = aarch64-linux-gnu-gcc + cxx = aarch64-linux-gnu-g++ + pic = -fPIC + shflags = -shared + platforms = armv7l_linux + pchcreate = "-o " + pchnobj = 1 + checkopt = -Wall -Wextra -pedantic -fsyntax-only + visopt = -fvisibility=hidden -fvisibility-inlines-hidden +} + // *********************************************************************** // Platform Section // *********************************************************************** @@ -498,7 +534,7 @@ plat_PPCe5500_linux { plat_armhf_linux { gnumake = 1 - compile_flags = + compile_flags = ldlibs = -lpthread } @@ -558,6 +594,13 @@ armv7a-vfp-neon_linux_gcc{ ldlibs = -lpthread } +armv7a_lafp_neon_linux{ + gnumake = 1 + cputype = arm + linkflags = -Wl,-O1 -Wl,--hash-style=gnu -Wl,--as-needed -mfloat-abi=hard --sysroot=$(SDKTARGETSYSROOT) + ldlibs = -lpthread +} + armv7at2-vfp-neon_WRlinux7_gcc{ gnumake = 1 cputype = arm diff --git a/bin/checkconf b/bin/checkconf index d1a8b06e8..a34caf239 100755 --- a/bin/checkconf +++ b/bin/checkconf @@ -322,18 +322,6 @@ gcc_check () set_var GCC_HAS_NO_MAYBE_UNINITIALIZED yes fi - # GCC >= 4.8 supports building Fujitsu system-tests (except when cross-compiling) - if echo $GCC_FULLVERSION | gawk '{ exit $1 >= 4.8 ? 0 : 1 }'; then - if [ ${SPLICE_TARGET} = ${SPLICE_HOST} ]; then - echo " NOTE - Building Fujitsu system-tests" - set_var INCLUDE_FUJITSU_ST_TEST yes - else - echo " NOTE - Not building Fujitsu system-tests (cross-compile not supported)" - fi - else - echo " NOTE - Not building Fujitsu system-tests (requires GCC >= 4.8)" - fi - return 0 } @@ -937,6 +925,47 @@ no_javac() fi } +key_value_store_check() +{ + echo -n "Key-value store implementations - SQLITE: " + if [ -n "$SQLITE_HOME" -a -f "$SQLITE_HOME/sqlite3.c" ] + then + echo -n "OK, " + set_var INCLUDE_SQLITE "yes" + elif [ "$STRICT_CHECKS" = "yes" ] + then + echo "ERROR - sqlite source not found." + return 1 + else + echo -n "Warning - Not found, " + unset_var INCLUDE_SQLITE + fi + echo -n "LEVELDB: " + case `uname` in + CYGWIN_NT-*) + echo "Disabled pending Windows port" + ;; + SunOS) + echo "Disabled for Solaris : OSPL-4283" + ;; + *) + if [ -n "$LEVELDB_HOME" -a -f "$LEVELDB_HOME/Makefile" ] + then + echo "OK" + set_var INCLUDE_LEVELDB "yes" + elif [ "$STRICT_CHECKS" = "yes" ] + then + echo "ERROR - library not found" + return 1 + else + echo "Warning - Not found" + unset_var INCLUDE_LEVELDB + fi + ;; + esac + return 0 +} + gmcs_check() { if [ "$STRICT_CHECKS" = "yes" ] @@ -1280,8 +1309,6 @@ c99_check() no_protoc() { - set_var INCLUDE_FUJITSU_ST_TEST no - export INCLUDE_FUJITSU_ST_TEST if [ "$STRICT_CHECKS" = "yes" ] then # this needs to be to an error before protobuf functionality is released @@ -1431,6 +1458,207 @@ protoc_check() } +python3_check() +{ + echo -n "Python3: " + + # the component depends on C99 api, so check that first + if [ "$INCLUDE_API_DCPS_C99" != "yes" ] + then + echo "Warning: C99 API not included in setup. Cannot build Python DCPS API." + set_var INCLUDE_API_DCPS_PYTHON no + return 0 + fi + + result=1 + # Check explicitly defined location for python installs + if [ -n "$PYTHON3_HOME" ] + then + for pyexec in $(echo "$PYTHON3_HOME" | tr ":" "\n") + do + python3_check_fn "$pyexec" && \ + result=0; python3_tmps="$python3_tmps:$pyexec"; set_undefined_var PYTHON3_EXEC $pyexec + done + set_var PYTHON3_EXECS $python3_tmps + python3_tmps= + # Else check if python3 is installed normally in host env + else + pyexec=$(which python3 2> /dev/null) + python3_check_fn "$pyexec" && \ + result=0; set_var PYTHON3_EXECS $pyexec; set_var PYTHON3_EXEC=$pyexec + fi + + if [ $result -eq 0 ] + then + set_var INCLUDE_API_DCPS_PYTHON yes + set_var INCLUDE_DBT_API_DCPS_PYTHON yes + else + set_var INCLUDE_API_DCPS_PYTHON no + fi + +} + +python3_check_fn() +{ + pyexec="$1" + if [ -x "$pyexec" ] + then + (echo "import platform"; + echo "import sys"; + echo "if platform.system().find('Windows') == 0:"; + echo " ver=[3,5,0]"; + echo "elif platform.system().find('CYGWIN') == 0:"; + echo " print('Warning: Cygwin python3 detected, this is invalid for DCPS Python api')"; + echo " sys.exit(1)"; + echo "else:"; + echo " ver=[3,4,0]"; + echo "if [int(num) for num in platform.python_version().split('.')] <= ver:"; + echo " print('Warning: Your version of python is below {0}.{1}.{2}'.format(ver[0],ver[1],ver[2]))"; + echo " sys.exit(1)") | $pyexec; + if [ $? -eq 0 ] + then + #Already a good version of python available + pyver=`$pyexec -c "import platform; print(platform.python_version())"` + echo "OK - Using `which $pyexec` v$pyver" + modules_ok=0 + declare -a modules=("Cython" "wheel") + for m in "${modules[@]}" + do + mod_version=$(python3_module_check $pyexec $m) + if [ $? -eq 0 ] + then + echo " $m OK - using $m v$mod_version" + else + echo " Warning: $m module not found. Cannot build Python DCPS API" + set_var INCLUDE_API_DCPS_PYTHON no + modules_ok=1 + fi + done + return $modules_ok + fi + else + echo "Warning: Python3 not available. Cannot build Python DCPS API." + set_var INCLUDE_API_DCPS_PYTHON no + fi + return 1 +} + +maven_check_inner() +{ + echo -n "MAVEN: " + + # first check whether there is any maven in the path + MAVEN_FOUND=`which mvn 2> /dev/null` + + if [ -z "$MAVEN_FOUND" ] + then + # No, it is not yet in the path + + if [ -n "$M2_HOME" ] + then + if [ ! -x "$M2_HOME/bin/mvn" ] + then + echo "Error - $M2_HOME is invalid" + return 1 + fi + MAVEN_FOUND="$M2_HOME/bin/mvn" + PATH="$M2_HOME/bin:$PATH" + set_var PATH "$PATH" + fi + fi + + if [ -z "$MAVEN_FOUND" ] + then + # Maven was not found + echo "maven is not installed (properly):" + echo " mvn not found in path" + echo " M2_HOME variable not set" + else + # maven was found, now check the version number + MAVEN_CHECK=`mvn --version | grep "Apache Maven 3."` + if [ -z "$MAVEN_CHECK" ] + then + # found unsupported version + MAVEN_CHECK=`mvn --version | grep "Apache Maven"` + echo " Found maven version $MAVEN_CHECK" + echo " WARNING - Maven version 3 would be better" + else + echo "OK - Using $MAVEN_CHECK" + fi + fi + + unset MAVEN_FOUND MAVEN_CHECK + return 0 +} + +python3_module_check() +{ + interp=$1 + module=$2 + (echo "modversion=''"; + echo "try:"; + echo " import $module"; + echo " try:"; + echo " modversion=str($module.__version__)"; + echo " except AttributeError:"; + echo " modversion=str('.'.join(map(str,$module.VERSION)))"; + echo "except ImportError:"; + echo " print('Warning: Invalid python module')"; + echo " exit(1)"; + echo "if modversion == '':"; + echo " exit(-1)"; + echo "print(modversion)") | $interp + return $? +} + +nodejs_check() +{ + chkmsg="OK" + + # first check whether the NODEJS install directory exists + if [ ! -d "$NODEJS_HOME" ] + then + chkmsg="nodejs install dir not found" + fi + + # the component depends on C99 api, so check that too + if [ "$INCLUDE_API_DCPS_C99" != "yes" ] + then + chkmsg="C99 API not included in setup" + fi + + # DBT's depend on python, so check for existing native python + PYTHON_FOUND=`which python 2> /dev/null` + if [ ! -x "$PYTHON_FOUND" ] + then + chkmsg="Python not found" + fi + + if [ "$chkmsg" != "OK" ] + then + chkmsg="$chkmsg - skipping build of NodeJS DCPS API and unit tests." + else + chkmsg="$chkmsg - NODEJS DCPS API will be built. NODEJS unit tests enabled." + set_var INCLUDE_API_DCPS_NODEJS "yes" + set_var INCLUDE_DBT_API_DCPS_NODEJS "yes" + convert_windows_path "$NODEJS_HOME" + case `uname` in + CYGWIN_NT-*) + PATH="$UNIX_CONV_PATH:$PATH" + set_var PATH "$PATH" + ;; + esac + case `uname` in + Linux) + PATH="$UNIX_CONV_PATH/bin:$PATH" + set_var PATH "$PATH" + ;; + esac + fi + echo "NODEJS: $chkmsg" + return 0 +} + cleanup_checks () { unset msvs_check @@ -1451,7 +1679,10 @@ cleanup_checks () unset protoc_check unset no_protoc unset c99_check + unset python3_check + unset python3_module_check unset launch4j_check + unset maven_check_inner unset PATHCHECK_FOUND unset GCC_FULLVERSION BISON_VERSION FLEX_VERSION JAVAC_REAL_VERSION unset GMCS_VERSION GMCS_REAL_VERSION GMCS_VERSION_OUTPUT GMCS_REQUIRED_VERSION GMCS_REQUIRED_VER diff --git a/bin/common/parse_compiler_output.pm b/bin/common/parse_compiler_output.pm index 56c89b640..fd9d4c0a0 100644 --- a/bin/common/parse_compiler_output.pm +++ b/bin/common/parse_compiler_output.pm @@ -220,6 +220,12 @@ sub handle_compiler_output_line($) { return; } + if ($s =~ m/^\s*Generating.*ERRORCODE.*html/) { + # Javadoc generation with ERROR in the filename + $self->Output_Normal ($s); + return; + } + if ($s =~ m/ is deprecated. use /) { # Among these are glibc warnings to stop using the deprecated # pthread_setstackaddr in favor of pthread_setstack. @@ -268,7 +274,7 @@ sub handle_compiler_output_line($) { } if ($s =~ /printf\("native error: %d\\n",nativeError\)/) { - # This output comes for ODBC and is just a printf + # This output comes for ODBC and is just a printf # statement that is getting output for some reason $self->Output_Normal ($s); return; @@ -279,7 +285,7 @@ sub handle_compiler_output_line($) { # which is wrongly classed as an error in the build log on ubuntu1604 $self->Output_Normal ($s); return; - } + } if ($s =~ m/Rule line too long/) { # Can be given by Borland make @@ -313,7 +319,7 @@ sub handle_compiler_output_line($) { # This is a warning from building c99 error_utests and is not an error $self->Output_Warning ($s); return; - } + } if ($s =~ m/cannot execute binary file/) { # Means we can't execute the binary, probably using target executable on host @@ -333,6 +339,13 @@ sub handle_compiler_output_line($) { $self->Detected_Build_Error($1); } + # Building with debug flag - definition statements printed out on some + # platforms + if ($s =~ m/c_bool error = FALSE/) { + $self->Output_Normal ($s); + return; + } + if ($s =~ m/^.*:[0-9]+: /) { # filename:linenumber is the typical format for an error if(# ... unless it is a warning @@ -349,19 +362,29 @@ sub handle_compiler_output_line($) { $self->Output_Warning ($s); return; } + if( $s =~ m/configure.ac:[0-9]+: installing/) { + # Not an error but allowed output from configure.ac + return; + } # It could also be part of a split line warning relating to # mktemp/mkstemp if (/mkstemp/) { $self->Output_Normal ($s); return; } - + if ($s =~ m/^.*.cpp:[0-9]+:[0-9]+:\s+required from here/) { # This is output on some platforms for some reason but is not an error $self->Output_Normal ($s); return; } - + + if ($s =~ m/^.*.*:[0-9]+:[0-9]+:\s+required from\s/) { + # This is output on some platforms for some reason but is not an error + $self->Output_Normal ($s); + return; + } + # Definitely an error $self->Output_Error ($s); return; @@ -642,7 +665,7 @@ sub handle_compiler_output_line($) { $self->Output_Normal ($s); return; } - + # OSPL additions from dcps_functions if ($s =~ m/No such file or directory/) { $self->Output_Error ($s); diff --git a/bin/decode-ddsi-log b/bin/decode-ddsi-log new file mode 100755 index 000000000..ab79a59ee --- /dev/null +++ b/bin/decode-ddsi-log @@ -0,0 +1,1168 @@ +#!/usr/bin/perl -w + +use strict; +use Getopt::Long; + +my @showopts = (); +my %shows = ("topic" => 0, "durability" => 0, "localdisc" => 0, "remotedisc" => 0, "user" => 1, "ack" => 1, "throttle" => 0, "block" => 1, "rematch" => 0, "in" => 1, "out" => 1, "partition" => 0, "builtin" => 0, "mtreader" => 0); +my $topic_filter = '.'; +my $topic_xfilter = '$^'; +my $t0opt = undef; +my $scint = undef; +my $rawip2name = undef; +my $helpflag = 0; +GetOptions ("help" => \$helpflag, "show=s" => \@showopts, "topic-filter=s" => \$topic_filter, "topic-xfilter=s" => \$topic_xfilter, "t0=s" => \$t0opt, "sc=s" => \$scint, "hn=s" => \$rawip2name) + or die "Error in command line arguments\n"; +usage() if $helpflag; +for (@showopts) { + $_ =~ /^((no-?)?)(.*)/; + die "--show $_: not a known category\n" unless exists $shows{$3}; + $shows{$3} = ($1 eq '') ? 1 : 0; +} + +my $guidre = "[0-9a-f]+(?::[0-9a-f]+){3}"; +my $gidre = "[0-9a-f]+(?::[0-9a-f]+){2}"; +my %opstr = ("00" => "R ", "01" => "W ", # index by $stinfo.$dflag + "10" => " D ", "11" => "WD ", + "20" => " U", "21" => "W U", + "30" => " DU", "31" => "WDU"); +my %pp = (); +my %rd = (); +my %wr = (); +my %rdgid = (); +my %wrgid = (); +my %sysid = (); +my %proxypp = (); +my %pwr = (); +my %prd = (); +my %pub = (); +my %sub = (); +my %ftrflag = (); +my @ackcheck; +my ($t0sec, $t0usec); +my $prevtjump = -1e9; +my %prevts = (); +my %tlastpkt = (); +my $self_seen = 0; +my $ownip; +my $txblock = undef; +my $txblockwr = undef; +my $txblocktp = undef; +my $tlast_txblock = 0; +my $tlast_non_spdp_check = 0; +my %scint = (); +my %scintcache = (); +my $last_infots; +my %spdp_infots; + +# Readers, writers for DDSI discovery data have entity ids, minus the +# source and kind of 2, 3, &c., with the following interpretation +# (actually, there are more ... but these are the ones I am most +# interested in) +my %discentitystr = ("2" => "TOPIC", "3" => "WRITER", "4" => "READER"); + +%scint = do $scint if defined $scint; +$rawip2name = do $rawip2name if defined $rawip2name; +sub ip2name { + if (defined $rawip2name) { + return &$rawip2name(@_); + } else { + return $_[0]; + } +} + +if (defined $t0opt) { + $t0sec = int($t0opt); + $t0usec = int(1e6 * int($t0opt - $t0sec)); +} + +my @durstate = ("init", "disc.f.grp", "disc.l.grp", + "disc.p.src", "inj.pers", "f.init", + "complete", "fetch", "align", "f.align", + "terminating", "terminated"); + +$| = 1; # let outbut not be fully buffered +my $ts; +my (%psgid, %psguid, %rwgid, %rwguid); +while(<>) { + s/[\r\n]+$//; # chomp; + last unless /^(\d+)\.(\d+)\/ *([^:]+)/; + unless (defined $t0sec) { + ($t0sec, $t0usec) = ($1, $2); + printf "T0 = %d.%06d\n", $t0sec, $t0usec; + } + $ts = ($1 - $t0sec) + ($2 - $t0usec) / 1e6; + my $tid = $3; + $prevts{$tid} = $ts unless exists $prevts{$tid}; + if ($ts < $prevts{$tid}) { + printf "%8.3f %24s %30.30s TJMP time jumped %.3fs (line $.)\n", $ts, "", "", $ts - $prevts{$tid}, $tid if $ts - $prevtjump > 1; + $prevtjump = $ts; + } elsif ($tid eq "xmit.user" && $ts > $prevts{$tid} + 3) { + printf "%8.3f %24s %30.30s TJMP possible time jump %.3fs (line $.)\n", $ts, "", "", $ts - $prevts{$tid}, $tid if $ts - $prevtjump > 1; + } + $prevts{$tid} = $ts; + + while (@ackcheck && $ackcheck[0]->{ts} < $ts) { + my $x = shift @ackcheck; + my $nsamp = scalar(acklate($ts, $x->{wrguid}, $x->{seq})); + if ($nsamp > 0) { + # note: sample count is against check reqt, not current position + # of the writer + printf "%8.3f %24s %30.30s ACK lagging by %d samples (last seq from writer: %d)\n", + $x->{ts}, fmtguid($x->{wrguid}), $wr{$x->{wrguid}}->{stopic}, $nsamp, $wr{$x->{wrguid}}->{seq} + unless $wr{$x->{wrguid}}->{acklate} || !$shows{ack} || !show_topic($wr{$x->{wrguid}}->{topic}); + $wr{$x->{wrguid}}->{acklate} = $x->{tswrite}; + } + } + + # Check whether something other than an SPDP reasonably recently + # arrived (to guard against only SPDP keeping things alive, which is + # known to happen when network routing is configured incorrectly) + if ($ts - $tlast_non_spdp_check >= 1.0) { + while (my ($k, $v) = each %proxypp) { + if (!defined $v->{tdel} && $ts - $v->{tcreate} > 5.0 && $v->{non_spdp_seen} == 0) { + printf "%8.3f %24s %30.30s CONN nothing other than SPDP received for 5s, possible connectivity issue\n", $ts, fmtguid($k), ""; + $v->{non_spdp_seen} = -1; # flagging it so we don't keep repeating it + } + } + $tlast_non_spdp_check = $ts; + } + + if ($shows{block} && defined $txblock && $ts > $txblock + 1.0 && $txblock > $tlast_txblock) { + my $stopic = (exists $wr{$txblockwr}) ? $wr{$txblockwr}->{stopic} : ""; + printf "%8.3f %24s %30.30s BLCK already blocked for %.3fs\n", $ts, fmtguid($txblockwr), $stopic, $ts - $txblock; + if (exists $wr{$txblockwr}) { + my @lates = acklate(1e100, $txblockwr); + for (@lates) { + my $cause = ($_->{haveack} ? sprintf "%d behind", $_->{nsamp} : "no ack yet"); + printf "%8.3f %24s %30.30s BLCK %s (%s)\n", $ts, fmtguid($txblockwr), $stopic, fmtguid($_->{guid}), $cause; + } + } + $tlast_txblock = $txblock; + } + + if (/HDR\(([0-9a-f]+):[0-9a-f]+:[0-9a-f]+/) { + $tlastpkt{$1} = $ts; + undef $last_infots; + if (exists $sysid{$1} && exists $sysid{$1}->{tlastpkt} && !exists $sysid{$1}->{tresumepkt}) { + $sysid{$1}->{tresumepkt} = $ts; + } + } + + # Special handling of ACKNACK of built-in reader/writer pairs: + # generally the script completely ignores the built-in ones (maybe I + # should change that?) but it is interesting to know when all + # discovery for a participant has completed. The "happy-now" is a + # decent proxy for that. + if (/: ACKNACK\(F?#\d+:\d+\/\d+:[01]* (?:L\([0-9a-f:]+\s+[0-9.]+\)\s*)?([0-9a-f]+(?::[0-9a-f]+){2}:[234]c7) -\> ([0-9a-f]+(?::[0-9a-f]+){2}:[234]c2) .*happy-now/) { + check_disccomplete("A", $1); + } elsif (/: HEARTBEAT\(F?#\d+:\d+\.\.\d+\s+(?:L\([0-9a-f:]+\s+[0-9.]+\)\s*)?([0-9a-f]+(?::[0-9a-f]+){2}:[234]c2)/) { + check_disccomplete("H", $1); + } elsif (/tev: acknack (?:$guidre) -\> ([0-9a-f]+(?::[0-9a-f]+){2}:[234]c2): #\d+:(\d+)\/0:$/ && $2 > 1) { + check_disccomplete("B", $1); + } + + # Special handling of INFOTS & SPDP for extracting start times of remote nodes + if (/recv: INFOTS\((\d+)\.(\d+)\)/) { + $last_infots = ($1 - $t0sec) + ($2/1e3 - $t0usec) / 1e6; + } elsif (/recv: DATA\(((?:[0-9a-f]+:){3}100c2) /) { + (my $ppguid = $1) =~ s/:100c2$/:1c1/; + $spdp_infots{$ppguid} = $last_infots; + } + + if (/: ownip: ([0-9.]+)/) { + $ownip = $1; + } elsif (/: new_participant\(($guidre)/o) { + my $guid = $1; + (my $gid = $guid) =~ s/:[^:]+$//; + $pp{$guid} = { gid => $gid, guid => $guid, sub => {}, pub => {} }; + if (! $self_seen) { + $self_seen = 1; + $guid =~ /^([^:]+)/; + $sysid{$1} = { self => 1, ip => $ownip, name => ip2name($ownip, $guid) }; + printf "%8.3f %24s %30.30s SELF node %s (%u; %s) alive\n", $ts, $1, "", $ownip, hex($1), $sysid{$1}->{name}; + } + printf "%8.3f LOCAL PARTICIPANT %s (%s)\n", $ts, fmtguid($guid), $gid if $shows{localdisc}; + } elsif (/: unref_participant\(($guidre) .*user 0 builtin 0/) { + my $guid = $1; + (my $gid = $guid) =~ s/:[^:]+$//; + printf "%8.3f DELETE LOCAL PARTICIPANT %s (%s)\n", $ts, fmtguid($guid), $gid if $shows{localdisc}; + } elsif (/: map group ($gidre) -> ($guidre)/o) { + $psgid{$tid} = $1; + $psguid{$tid} = $2; + } elsif (/: new_(reader|writer)\(gid ($gidre)\)$/o) { + $rwgid{$tid} = $2; + } elsif (/: new_(reader|writer)\(guid ($guidre)/o) { + $rwguid{$tid} = $2; + } elsif (/new_fictitious_transient_reader/) { + $ftrflag{$tid} = 1; # no GID or subscriber + } elsif (/: (READER|WRITER) ($guidre) QOS=\{(.*)/o) { + my $kind = $1; + my $g = ($1 eq "READER") ? \%sub : \%pub; + my $h = ($1 eq "READER") ? \%rd : \%wr; + my $hgid = ($1 eq "READER") ? \%rdgid : \%wrgid; + my $gk = ($1 eq "READER") ? "sub" : "pub"; + my $hk = ($1 eq "READER") ? "rd" : "wr"; + my $qos = $3; + die "$2 $rwguid{$tid}" unless $2 eq $rwguid{$tid}; + unless ($3 =~ /topic=([^,]+?),type=([^,]+?).*?,partition=\{([^}]*?)\}.*?,history=([01]):/) { + # no topic, type: DDSI built-in reader/writer + if (defined $rwgid{$tid} || $ftrflag{$tid}) { + die; + } + if (defined $psgid{$tid} || defined $psguid{$tid}) { + # in some cases, we have a pub/sub gid+guid set for an + # internal reader (depends on the order of discovery) + die unless $rwguid{$tid} =~ /[4c][27]$/; + } + $psgid{$tid} = $psguid{$tid} = $rwguid{$tid} = undef; + } else { + my $topic = $1; my $type = $2; my $partitions = $3, my $keepall = $4; + unless (defined $rwguid{$tid} && ($ftrflag{$tid} || (defined $psgid{$tid} && defined $psguid{$tid} && defined $rwgid{$tid}))) { + die; + } + my @ps = split ',', $partitions; + $psgid{$tid} = $psguid{$tid} = $rwgid{$tid} = "" if $ftrflag{$tid}; + (my $ppguid = $rwguid{$tid}) =~ s/:[^:]+$/:1c1/; + if (! exists $pp{$ppguid}->{$gk}->{$psguid{$tid}}) { + $pp{$ppguid}->{$gk}->{$psguid{$tid}} = + { gid => $psgid{$tid}, guid => $psguid{$tid}, ppguid => $ppguid, $hk => {} }; + } + my $stopic = make_stopic($partitions, $topic); + #print "FTR $topic\n" if $ftrflag; + my $rw = { gid => $rwgid{$tid}, guid => $rwguid{$tid}, psguid => $psguid{$tid}, ppguid => $ppguid, + topic => $topic, stopic => $stopic, type => $type, partition => \@ps, + matches => {}, nhappy => 0, seq => 0, acklate => 0, cs => undef, keepall => $keepall }; + $pp{$ppguid}->{$gk}->{$psguid{$tid}}->{$rwguid{$tid}} = $rw; + $h->{$rwguid{$tid}} = $rw; + $hgid->{$rwgid{$tid}} = $rw; + $g->{$psguid{$tid}} = { gid => $psgid{$tid}, guid => $psguid{$tid}, es => {}, txn => 0 } unless exists $g->{$psguid{$tid}}; + $g->{$psguid{$tid}}->{es}->{$rwguid{$tid}} = 1; + my $gidstr; + if ($rwgid{$tid} eq '') { + $gidstr = "no gid"; + } else { + $gidstr = sprintf "gid %s ${gk}gid %s", $rwgid{$tid}, $psgid{$tid}; + } + printf "%8.3f LOCAL $kind %s %s {%s} (%s)\n", $ts, fmtguid($rwguid{$tid}), $topic, $partitions, $gidstr if $shows{localdisc} && $topic =~ /$topic_filter/o && $topic !~ /$topic_xfilter/o; + check_qos($ts, $kind, fmtguid($rwguid{$tid}), $topic, $partitions, $qos); + $psgid{$tid} = $psguid{$tid} = $rwgid{$tid} = $rwguid{$tid} = undef; + $ftrflag{$tid} = 0; + } + } elsif (/rtps_write\(gid ($gidre)\) - seq (\d+) txn id (\d+) (begin|end)s/o) { + my $wrgid = $1; my $kseq = $2; my $ktxnid = $3; my $op = uc $4; + die unless defined $wrgid{$wrgid}; + my $wrguid = $wrgid{$wrgid}->{guid}; + my $wr = $wr{$wrguid}; + die unless defined $wr; + my $pub = $pub{$wr->{psguid}}; + die unless defined $pub; + if ($op eq "BEGIN") { + die if defined $wr->{cs}; + if ($pub->{txn} == 0) { + $pub->{txn} = keys %{$pub->{es}}; + printf "%8.3f %24s %30.30s %16s XMT BEGIN [%d writers]\n", $ts, fmtguid($pub->{guid}), "", "", $pub->{txn} if $shows{out}; + } + $wr->{cs} = { seq => undef, ktxn => $ktxnid, kseq => $kseq }; # seq will be filled in with the first sample + } elsif ($op eq "END") { + if (defined $wr->{cs}) { + my $nk = $kseq - $wr->{cs}->{kseq}; + my $nd = defined $wr->{cs}->{seq} ? $wr->{seq} - $wr->{cs}->{seq} + 1 : 0; + if ($nk != $nd) { + my $keeplastmsg = $wr->{keepall} ? " (weird)" : " - change writer to use a keep-all history"; + printf "%8.3f %24s %30.30s %s #%-4d %-6s EOTX kernel has %d but DDSI %d samples in txn%s\n", $ts, fmtguid($wrguid), $wr->{stopic}, "", $wr->{seq}, "", $nk, $nd, $keeplastmsg; + } + } else { + # assume empty transaction + $wr->{cs} = { seq => $wr->{seq}+1, ktxn => $ktxnid, kseq => $kseq } unless defined $wr->{cs}; + } + # not clearing: doing that when seeing the EoT + } else { + die; + } + } elsif (/: write_sample ($guidre) #(\d+)((?: C#(?:\d+))?): ST(\d+) [^\{]+?(\{.*(?:\}|\(trunc\))|:k:\{.*\}|:e:\(blob\))/o) { + my $wrguid = $1; my $seq = $2; my $cseq = $3; my $st = $4; my $data = $5; + my $dflag = ($data =~ /^:[ek]:/ ? 0 : 1); + $cseq =~ s/^ C#//; + # all but built-in writers must have been found in the log; we don't care for OSPL internal stuff + if (!defined $wr{$wrguid} && $wrguid !~ /[4c]2$/) { + die; + } + if (!defined ($wr{$wrguid}->{topic})) { + die; + } + my $wr = $wr{$wrguid}; + $cseq = "C#$cseq" if $cseq ne ""; + my $dest = getdest($wrguid); + $wr->{seq} = $seq; + if (defined $wr->{cs}) { + $wr->{cs}->{seq} = $seq unless defined $wr->{cs}->{seq}; + } + if (scalar (keys %{$wr->{matches}}) > 0) { + push @ackcheck, { ts => $ts + 1, tswrite => $ts, wrguid => $wrguid, seq => $seq }; + } + my $op = ($data =~ /^:e:/) ? "W " : $opstr{$st.$dflag}; + my $print = 0; + my $printlim = 1; + $print = show_topic($wr->{topic}) && $shows{out}; + if ($wr->{topic} =~ /^d_/ && $shows{durability} && $data =~ /^\{/) { + $print = ($wr->{topic} =~ /$topic_filter/o || $data =~ /$topic_filter/o) && $wr->{topic} !~ /$topic_xfilter/o && $shows{out}; + if ($print) { + $data = interpret_durability($wr->{topic}, $data); + $printlim = 0; + } + } + my $sdata = $printlim ? (sprintf "%-100.100s", $data) : (sprintf "%-100s", $data); + printf "%8.3f %24s %30.30s %s #%-4d %-6s XMT %s -> %s\n", $ts, fmtguid($wrguid), $wr->{stopic}, $op, $seq, $cseq, $sdata, $dest if $print; + if ($data =~ /^:e:/ && defined $wr->{cs}) { + # assume empty transaction if no $wr->{cs} + my $pub = $pub{$wr->{psguid}}; + die unless defined $pub; + $wr->{cs} = undef; + if ($pub->{txn} == 0) { + # presumably an empty transaction + $pub->{txn} = keys %{$pub->{es}}; + printf "%8.3f %24s %30.30s %16s XMT BEGIN [empty, %d writers]\n", $ts, fmtguid($pub->{guid}), "", "", $pub->{txn} if $shows{out}; + } + if (--$pub->{txn} == 0) { + printf "%8.3f %24s %30.30s %16s XMT COMMIT\n", $ts, fmtguid($pub->{guid}), "", "" if $shows{out}; + } + } + } elsif (/: SPDP ST(\d) ($guidre)\s+bes\s+([0-9a-f]+)\s+.*NEW.*?meta(?: [0-9.]+:\d+)*? ([0-9.]+):\d+\)/o) { + my $st = $1; my $ppguid = $2; my $bes = hex $3; my $ip = $4; + (my $sysid = $ppguid) =~ s/:.*//; + my $note = ""; + if (exists $sysid{$sysid} && defined $sysid{$sysid}->{tcrash}) { + printf "%8.3f %24s %30.30s DISC node %s apparently not disconnected as assumed before\n", + $ts, $sysid, "", $ip; + $sysid{$sysid}->{tcrash} = undef; + } + if ($st != 0) { + # should know it, but I guess it might not if one were to receive a dispose followed by an unregister + # actually deleting is deferred + #printf "%8.3f LEAVE %s\n", $ts, $ppguid; + } else { + $sysid{$sysid} = { npp => 0, ip => $ip, name => ip2name($ip, $ppguid), tdel => undef, tcrash => undef } unless defined $sysid{$sysid}; + if ($sysid{$sysid}->{npp}++ > 0) { + die if defined $sysid{$sysid}->{tdel}; + } elsif (! defined $sysid{$sysid}->{tdel}) { + my $x = defined $spdp_infots{$ppguid} ? sprintf " (started at %.3fs)", $spdp_infots{$ppguid} : ""; + printf "%8.3f %24s %30.30s DISC node %s (%u; %s) alive%s\n", $ts, $sysid, "", $ip, hex($sysid), $sysid{$sysid}->{name}, $x; + } else { + my $dt = $ts - $sysid{$sysid}->{tdel}; + my $dtgap = $sysid{$sysid}->{tresumepkt} - $sysid{$sysid}->{tlastpkt}; + $sysid{$sysid}->{tdel} = undef; + delete $sysid{$sysid}->{tlastpkt}; + delete $sysid{$sysid}->{tresumepkt}; + printf "%8.3f %24s %30.30s DISC node %s (%u; %s) alive again after %.3fs (disconnect estimate %.3fs)\n", $ts, $sysid, "", $ip, hex($sysid), $sysid{$sysid}->{name}, $dt, $dtgap; + } + if (! exists $proxypp{$ppguid}) { + $proxypp{$ppguid} = + { guid => $ppguid, + ip => $ip, + name => ip2name($ip, $ppguid), + infots => $spdp_infots{$ppguid}, + tcreate => $ts, + non_spdp_seen => 0, + disccomplete => init_proxypp_disccomplete($bes), + disccompleteflag => 0 }; + #printf "%8.3f DISCOVER %s @ %s\n", $ts, $ppguid, $ip; + } else { + die unless defined $proxypp{$ppguid}->{tdel}; + my $dt = $ts - $proxypp{$ppguid}->{tdel}; + $proxypp{$ppguid}->{tdel} = undef; + $proxypp{$ppguid}->{tcreate} = $ts; + $proxypp{$ppguid}->{non_spdp_seen} = 0; + $proxypp{$ppguid}->{disccomplete} = {}; + $proxypp{$ppguid}->{disccompleteflag} = 0; + #printf "%8.3f REDISCOVER %s @ %s - gone for %.3fs\n", $ts, $ppguid, $ip, $dt; + #if (defined $proxypp{$ppguid}->{isdurability}) { + # printf "%8.3f REDISCOVER durability %s @ %s - gone for %.3fs\n", $ts, $ppguid, $ip, $dt; + #} + } + } + } elsif (/lease expired:.*? guid ($guidre)/o) { + # actually deleting is deferred + my $ppguid = $1; + (my $sysid = $ppguid) =~ s/:.*//; + # participant lease expiry doesn't necessarily mean a + # disconnection, but let's assume it does + die unless defined $sysid{$sysid}; + if (!defined $sysid{$sysid}->{tcrash}) { + my $lastpacketmsg = exists $tlastpkt{$sysid} ? sprintf " last packet %.3fs ago", $ts - $tlastpkt{$sysid} : ""; + printf "%8.3f %24s %30.30s DIED assuming disconnect of node %s (%u; %s)%s\n", + $ts, fmtguid($ppguid), "", $sysid{$sysid}->{ip}, hex($sysid), $sysid{$sysid}->{name}, $lastpacketmsg; + $sysid{$sysid}->{tcrash} = $ts; + $sysid{$sysid}->{tlastpkt} = exists $tlastpkt{$sysid} ? $tlastpkt{$sysid} : $ts; + } + if (defined $proxypp{$ppguid}->{isdurability}) { + printf "%8.3f %24s %30.30s DIED durability gone on node %s (%u; %s)\n", $ts, fmtguid($ppguid), "", $sysid{$sysid}->{ip}, hex($sysid), $sysid{$sysid}->{name}; + } + } elsif (/unref_proxy_participant\(($guidre)\).*freeing/o) { + die unless exists $proxypp{$1} && ! defined $proxypp{$1}->{tdel}; + delete_proxypp($ts, $1); + } elsif (/: SEDP ST0 ($guidre) [a-z_ -]*(reader|writer): .*QOS=\{(.*)/o) { + my $prwguid = $1; my $kind = uc $2; + my $h = ($kind eq "READER") ? \%prd : \%pwr; + my $hk = ($kind eq "READER") ? "prd" : "pwr"; + my $qos = $3; + unless ($3 =~ /topic=([^,]+?),type=([^,]+?),presentation=(\d+):\d+:\d+,partition=\{([^}]*?)\}.*?,durability=(\d+)/) { + die unless $prwguid =~ /[4c][27]$/; + } else { + my $topic = $1; my $type = $2; my $access_scope = $3; my $partitions = $4; my $durkind = $5; + (my $ppguid = $prwguid) =~ s/:[0-9a-f]+$/:1c1/; + die unless exists $proxypp{$ppguid} && !defined $proxypp{$ppguid}->{tdel}; + my @ps = split ',', $partitions; + my $stopic = make_stopic($partitions, $topic); + if ($topic =~ /^d_/) { + $proxypp{$ppguid}->{isdurability} = 1; + } + #print "$kind $topic\n" if $durkind >= 2 && ($kind eq "READER" || $access_scope >= 2); + my $prw = { guid => $prwguid, ppguid => $ppguid, + topic => $topic, stopic => $stopic, type => $type, partition => \@ps, + matches => {}, checklost => 0, suppressbegin => 0, tcreate => $ts }; + if (! exists $h->{$prwguid}) { + $proxypp{$ppguid}->{$hk}->{$prwguid} = $prw; + $h->{$prwguid} = $prw; + printf "%8.3f DISCOVER $kind %s %s {%s}\n", $ts, fmtguid($prwguid), $topic, $partitions + if $shows{remotedisc} && $topic =~ /$topic_filter/o && $topic !~ /$topic_xfilter/o; + } else { + my $x = $h->{$prwguid}; + die unless defined $x->{tdel}; + die unless $x->{topic} eq $prw->{topic}; + my $dt = $ts - $x->{tdel}; + $x->{tdel} = undef; + if ($x->{explicitdel}) { + printf "%8.3f REDISCOVER ZOMBIE $kind %s %s - gone for %.3fs\n", $ts, fmtguid($prwguid), $stopic, $dt; + } else { + printf "%8.3f REDISCOVER $kind %s %s - gone for %.3fs\n", $ts, fmtguid($prwguid), $stopic, $dt + if $shows{remotedisc} && $topic =~ /$topic_filter/o && $topic !~ /$topic_xfilter/o; + } + } + check_qos($ts, $kind, fmtguid($prwguid), $topic, $partitions, $qos); + } + } elsif (/((?:SEDP ST3 (?:$guidre))?)delete_proxy_(reader|writer) \(($guidre)/o) { + if ($2 eq "reader") { + delete_prd($ts, $3, ($1 eq "") ? 1 : 0); + } else { + delete_pwr($ts, $3, ($1 eq "") ? 1 : 0); + } + } elsif (/gc_delete_(reader|writer)\((?:0[xX])?[0-9a-f]+, ($guidre)/o) { + # somewhat imprecise, as deleting a writer may take a significant amount of time + my $kind = uc $1; my $guid = $2; + my $g = ($kind eq "READER") ? \%sub : \%pub; + my $h = ($kind eq "READER") ? \%rd : \%wr; + next unless exists $h->{$guid}; + my $x = $h->{$guid}; + die + if exists $x->{tdel}; + my $topic = $x->{topic}; + my $gk = ($kind eq "READER") ? "sub" : "pub"; + printf "%8.3f DELETE LOCAL $kind %s %s%s\n", $ts, fmtguid($guid), $topic, ($kind eq "WRITER" && $x->{nhappy} < scalar (keys %{$x->{matches}})) ? " (while unhappy)" : "" if $shows{localdisc} && $topic =~ /$topic_filter/o && $topic !~ /$topic_xfilter/o; + $x->{tdel} = $ts; + } elsif (/proxy_writer_add_connection\(pwr ($guidre) rd ($guidre)\)/o) { + my $pwrguid = $1; my $rdguid = $2; + die unless exists $pwr{$pwrguid} || $pwrguid =~ /[4c]2$/; + die unless exists $rd{$rdguid} || $rdguid =~ /[4c]7$/; + die if defined $pwr{$pwrguid}->{tdel}; + next if $pwrguid =~ /[4c]2$/; + $pwr{$pwrguid}->{matches}->{$rdguid} = {}; + $rd{$rdguid}->{matches}->{$pwrguid} = {}; + } elsif (/writer_add_connection\(wr ($guidre) prd ($guidre)\)((?: - ack seq 9223372036854775807)?)/o) { + my $wrguid = $1; my $prdguid = $2; my $bereader = $3 ne ''; + die unless exists $wr{$wrguid} || $wrguid =~ /[4c]2$/; + die unless exists $prd{$prdguid} || $prdguid =~ /[4c]7$/; + die if defined $prd{$prdguid}->{tdel}; + next if $wrguid =~ /[4c]2$/; + my $wr = $wr{$wrguid}; + my $prd = $prd{$prdguid}; + $wr->{matches}->{$prdguid} = { seqp1 => 0, happy => ($bereader ? 1 : 0), thappy => ($bereader ? $ts : 1e100), tmatch => $ts }; + $wr->{nhappy}++ if $bereader; + if (! exists $prd->{matches}->{$wrguid}) { + $prd->{matches}->{$wrguid} = {}; + } else { + die unless defined $prd->{matches}->{$wrguid}->{seqp1del}; + # nlost can become -1 if $wr->{seq} is still 0, which can happen + # if we sent a GAP for seq 1 to get a valid HEARTBEAT out in + # response to an ACKNACK; seqp1del can be 0, too ... + my $nlost; + if ($wr->{seq} == 0) { + die + if $prd->{matches}->{$wrguid}->{seqp1del} > 2; + $nlost = 0; + } else { + $nlost = $wr->{seq} - $prd->{matches}->{$wrguid}->{seqp1del} + 1; + } + printf "%8.3f %24s %30.30s MTCH %s rematch %d lost\n", $ts, fmtguid($wrguid), $wr->{stopic}, $prdguid, $nlost + if $nlost > 0 && $shows{rematch}; + delete $prd->{matches}->{$wrguid}->{seqp1del}; + } + } elsif (/ACKNACK\(F?#\d+:(\d+)\/\d+:([01]*) (?:L\(:1c1 [0-9.]+\) )?($guidre) -> ($guidre)(\??)/o) { + my $seqp1 = $1; my $nackset = $2; my $prdguid = $3; my $wrguid = $4; my $wrknown = ($5 eq ""); + my $wr = $wr{$wrguid}; + my $cnt = ($nackset =~ y/1//); + my $op = ($cnt == 0) ? " ACK" : "NACK"; + next unless defined $wr; + if (exists $wr->{tdel} && $ts - $wr->{tdel} > 0.5) { + (my $prdsysid = $prdguid) =~ s/:.*//; + if (!$wr->{zombiewarn}->{$prdsysid} && exists $proxypp{$prdsysid} && exists $proxypp{$prdsysid}->{non_spdp_seen}) { + # shouldn't be getting ACKs this late + # but if no proper connection established yet, can be false positive + # (could take time of discovery of proxy participant into account as well) + $wr->{zombiewarn}->{$prdsysid} = 1; + if ($seqp1 <= 1) { + printf "%8.3f %24s %30.30s $op %s pre-emptive but writer deleted %.3fs ago, likely zombie\n", + $ts, fmtguid($wrguid), $wr->{stopic}, $prdguid, $ts - $wr->{tdel}; + } else { + printf "%8.3f %24s %30.30s $op %s writer deleted %.3fs ago, seemingly no progress\n", + $ts, fmtguid($wrguid), $wr->{stopic}, $prdguid, $ts - $wr->{tdel}; + } + } + } + next unless exists $prd{$prdguid}; + next unless exists $wr->{matches}->{$prdguid}; + if (defined $prd{$prdguid}->{tdel}) { + my $dt = $ts - $prd{$prdguid}->{tdel}; + printf "%8.3f %24s %30.30s $op %s undiscovered %.3fs ago\n", $ts, fmtguid($wrguid), $wr->{stopic}, $prdguid, $dt; + next; + } + $proxypp{$prd{$prdguid}->{ppguid}}->{non_spdp_seen} = 1; + $wr->{matches}->{$prdguid}->{seqp1} = $seqp1; + if ($cnt == 0) { + # $seqp1 <= 1 => pre-emptive ACKNACK < which is not proof of a happy reader + if ($seqp1 > 1 && !$wr->{matches}->{$prdguid}->{happy}) { + $wr->{matches}->{$prdguid}->{happy} = 1; + $wr->{matches}->{$prdguid}->{thappy} = $ts; + $wr->{nhappy}++; + } + if (defined $wr->{matches}->{$prdguid}->{tnack}) { + my $dt = $ts - $wr->{matches}->{$prdguid}->{tnack}; + printf "%8.3f %24s %30.30s $op %s caught up after %.3fs\n", $ts, fmtguid($wrguid), $wr->{stopic}, fmtguid($prdguid), $dt if $shows{ack} && show_topic($wr->{topic}); + $wr->{matches}->{$prdguid}->{tnack} = undef; + } + } elsif ($wr->{matches}->{$prdguid}->{happy}) { + # initial rexmit requests are not that interesting, so we + # suppress tracking/printing them until the reader has sent a + # pure ACK (the same reasoning as the "happy" flag of DDSI2, + # which uses it to classify requests as historical data or + # recovery from packet loss) + $wr->{matches}->{$prdguid}->{tnack} = $ts unless defined $wr->{matches}->{$prdguid}->{tnack}; + printf "%8.3f %24s %30.30s $op %s rexmit request for %d samples starting from %d\n", + $ts, fmtguid($wrguid), $wr->{stopic}, fmtguid($prdguid), $cnt, $seqp1 if $shows{ack} && show_topic($wr->{topic}); + } + if ($wr->{acklate} && acklate($ts, $wrguid) == 0) { + my $dt = $ts - $wr->{acklate}; + printf "%8.3f %24s %30.30s ACK caught up after %.3fs since triggering write\n", + $ts, fmtguid($wrguid), $wr->{stopic}, $dt if $shows{ack} && show_topic($wr->{topic}); + $wr->{acklate} = 0; + } + } elsif (/\(begin ($guidre) txn (\d+)\)/o) { + my $pwr = $pwr{$1}; + die unless defined $pwr; + die if ! $pwr->{suppressbegin}; + $pwr->{suppressbegin} = 0; + #printf "%8.3f %24s %30.30s %16s RCV BEGIN txn %d\n", $ts, $1, $pwr->{stopic}, "", $2 if $shows{in}; + } elsif (/\(commit ($guidre) txn (\d+) (\d+) seq_offset (\d+)/o) { + my $pwrguid = $1; + my $pwr = $pwr{$pwrguid}; + die unless defined $pwr; + die if $pwr->{suppressbegin}; + my $n = (defined $pwr->{cseq} && defined $pwr->{seq}) ? $pwr->{seq} - $pwr->{cseq} + 1 : 0; + my $nr = keys %{$pwr->{matches}}; + printf "%8.3f %24s %30.30s %16s RCV COMMIT txn %d %d [%d samples %d readers]\n", $ts, fmtguid($pwrguid), $pwr->{stopic}, "", $2, $3, $n, $nr if $shows{in}; + $pwr->{cseq} = undef; + } elsif (/data\(application, vendor \d+\.\d+\): ($guidre) #(\d+)((?: C#\d+)?): ST(\d+) [^\{]+?(\{.*|:k:\{.*|:e:\(blob\))/o) { + my $pwrguid = $1; my $seq = $2; my $cseq = $3; my $st = $4; my $data = $5; + my $pwr = $pwr{$pwrguid}; + my $dflag = ($data =~ /^:[ek]:/ ? 0 : 1); + next unless defined $pwr; + die if $pwr->{suppressbegin}; + my $oldcseq = $pwr->{cseq}; + my $nr = keys %{$pwr->{matches}}; + $pwr->{seq} = $seq; + if ($cseq =~ /C#(\d+)/) { + $pwr->{cseq} = $1; + } else { + $pwr->{cseq} = undef; + } + if (defined $pwr->{cseq}) { + if (! defined $oldcseq) { + printf "%8.3f %24s %30.30s %16s RCV BEGIN\n", $ts, fmtguid($pwrguid), $pwr->{stopic}, "" if $shows{in}; + $pwr->{suppressbegin} = 1; + } elsif ($oldcseq != $pwr->{cseq}) { + printf "%8.3f %24s %30.30s %16s RCV IMPLICIT COMMIT + BEGIN\n", $ts, fmtguid($pwrguid), $pwr->{stopic}, "" if $shows{in}; + } + } elsif (defined $oldcseq) { + printf "%8.3f %24s %30.30s %16s RCV IMPLICIT COMMIT\n", $ts, fmtguid($pwrguid), $pwr->{stopic}, "" if $shows{in}; + } + my $op = ($data =~ /^:e:/) ? "W " : $opstr{$st.$dflag}; + my $print = 0; + my $printlim = 1; + $print = show_topic($pwr->{topic}) && $shows{in}; + if ($pwr->{topic} =~ /^d_/ && $shows{durability} && $data =~ /^\{/) { + $print = ($pwr->{topic} =~ /$topic_filter/o || $data =~ /$topic_filter/o) && $pwr->{topic} !~ /$topic_xfilter/o && $shows{in}; + if ($print) { + $data = interpret_durability($pwr->{topic}, $data); + $printlim = 0; + } + } + my $sdata = $printlim ? (sprintf "%-100.100s", $data) : (sprintf "%-100s", $data); + printf "%8.3f %24s %30.30s %s #%-4d %-6s RCV %s [%d readers]\n", $ts, fmtguid($pwrguid), $pwr->{stopic}, $op, $seq, $cseq, $sdata, $nr if $print; + } elsif (/DATA\(($guidre)/o) { + my $pwrguid = $1; + (my $ppguid = $pwrguid) =~ s/:[0-9a-f]+$/:1c1/; + # 100c2 is entity id of SPDP writer + $proxypp{$ppguid}->{non_spdp_seen} = 1 if exists $proxypp{$ppguid} && !defined $proxypp{$ppguid}->{tdel} && $pwrguid !~ /:100c2$/; + } elsif (/HEARTBEAT\(F?#\d+:(\d+)\.\.(\d+) ($guidre)/o) { + my $prdguid = $3; + (my $ppguid = $prdguid) =~ s/:[0-9a-f]+$/:1c1/; + $proxypp{$ppguid}->{non_spdp_seen} = 1 if exists $proxypp{$ppguid} && !defined $proxypp{$ppguid}->{tdel}; + } elsif (/: SEDP_TOPIC ST\d+ ([^\/]+)\/([^ ]+) QOS=(.*)/) { + my $topic = $1; my $type = $2; my $qos = $3; + my $sysid = "0"; + printf "%8.3f %24s %30.30s %16s RCV %s (%s)\n", $ts, $sysid, "TOPIC", "", $topic, $type if $shows{topic} && $shows{in}; + } elsif (/: sedp: write topic ([^ ]+)/) { + my $topic = $1; + printf "%8.3f %24s %30.30s %16s XMT %s\n", $ts, "0", "TOPIC", "", $topic if $shows{topic} && $shows{out}; + } elsif (/writer ($guidre) topic ([^ ]+) waiting/o) { + my $wrguid = $1; + $txblock = $ts; + $txblockwr = $wrguid; + $txblocktp = $2; + printf "%8.3f %24s %30.30s BLCK\n", $ts, fmtguid($wrguid), $txblocktp if $shows{throttle} || $shows{block}; + } elsif (/writer ($guidre) done waiting/o) { + my $wrguid = $1; + my $dt = $ts - $txblock; + my $mustprint = ($tlast_txblock == $txblock); + $txblock = undef; + $txblockwr = undef; + $txblocktp = undef; + if ($shows{throttle} || $shows{block} || $mustprint) { + if (!exists $wr{$wrguid}) { + printf "%8.3f %24s %30.30s UNBK after %.3fs\n", $ts, fmtguid($wrguid), "", $dt; + } else { + my $wr = $wr{$wrguid}; + printf "%8.3f %24s %30.30s UNBK after %.3fs\n", $ts, fmtguid($wrguid), $wr->{stopic}, $dt; + } + } + } elsif (/message dropped because sender ($gidre) is unknown/o) { + my $gid = $1; + $gid =~ /^([0-9a-f]+):([0-9a-f]+):([0-9a-f]+)/; + my $decgid = sprintf "{%d,%d,%d}", hex $1, hex $2, hex $3; + printf "%8.3f %55s DROP unknown writer %s (a.k.a. %s) \n", $ts, "", $gid, $decgid; + } elsif (/: update_mtreader: (.*)/) { + printf "%8.3f %55s UMTR %s\n", $ts, "", $1 if $shows{mtreader}; + } +} +# blocking on whc is generally very bad if it is not resolved by the time the log ends +if (defined $txblock && $shows{block}) { + my $dt = $ts - $txblock; + my $wrguid = $txblockwr; + printf "%8.3f %24s %30.30s BLCK still blocked at end of log after %.3fs\n", $ts, fmtguid($wrguid), $txblocktp, $dt; + if (exists $wr{$txblockwr}) { + my @lates = acklate(1e100, $txblockwr); + for (@lates) { + my $cause = ($_->{haveack} ? sprintf "%d behind", $_->{nsamp} : "no ack yet"); + printf "%8.3f %24s %30.30s BLCK %s (%s)\n", $ts, fmtguid($txblockwr), $txblocktp, fmtguid($_->{guid}), $cause; + } + } +} + +sub make_stopic { + my ($partitions, $topic) = @_; + my $stopic; + if ($shows{partition}) { + $stopic = "$partitions/$topic"; + if (length $stopic < 30) { + # nop + } elsif (length $partitions < 15) { + my $max = 26 - length $partitions; + $stopic =~ s/\/.*?(.{1,$max})$/\/...$1/; + } elsif (length $topic < 15) { + my $max = 26 - length $topic; + $stopic =~ s/.*?(.{1,$max})\//...$1\//; + } else { + $stopic =~ s/.*?(.{1,11})\/.*?(.{1,11})$/...$1\/...$2/; + } + } else { + if (length $topic < 30) { + $stopic = $topic; + } else { + $topic =~ /(.{1,27})$/; + $stopic = "...$1"; + } + } + return $stopic; +} + +sub fmtguid { + my ($guid) = @_; + return $guid unless defined $rawip2name; + $guid =~ /^([0-9a-f]+)/; + return $guid unless exists $sysid{$1}; + my $n = $sysid{$1}->{name}; + $guid =~ s/^[0-9a-f]+/$n/; + return $guid; +} + +sub acklate { # returns ({ "guid" => guid, "nsamp" => nr of samples not acked}) + my ($ts, $wrguid, $seq) = @_; + if ($wr{$wrguid}->{seq} == 0) { + return (); + } else { + #my $x; + #for (values %{$wr{$wrguid}->{matches}}) { + # next if $_->{seqp1} == 0; # nothing from reader yet, so not really lagging yet + # $x = $_->{seqp1} if !(defined $x) || $_->{seqp1} < $x; + #} + #return 0 unless defined $x; + #$seq = $wr{$wrguid}->{seq} unless defined $seq; + #return ($x > $seq) ? 0 : ($seq - $x + 1); + my @r; + $seq = $wr{$wrguid}->{seq} unless defined $seq; + while (my ($k,$v) = each %{$wr{$wrguid}->{matches}}) { + # nothing from reader yet, and less than 2s passed since + # matching, so not really lagging yet + next if $v->{seqp1} == 0 && $ts < $v->{tmatch} + 2; + push @r, { "guid" => $k, "nsamp" => $seq - $v->{seqp1} + 1, "haveack" => ($v->{seqp1} > 0) } if $v->{seqp1} <= $seq; + } + return @r; + } +} + +sub init_proxypp_disccomplete { + my ($bes) = @_; + # keys are TOPIC, WRITER, READER + # A = ACK received, i.e., remote reader exists + # H = HB received, i.e., remote writer exists + # B = pure ack sent, i.e., remote writer exists + # first element in arrays is bit in $bes indicating existence of the "announcer", i.e., the writer + # second is the bit indicating existence of the "detector", i.e., the reader + my %tab = ("WRITER" => [ 2, 3 ], "READER" => [ 4, 5 ], "TOPIC" => [ 12, 13 ]); + my $res = {}; + while (my ($k, $v) = each %tab) { + $res->{"H$k"} = $res->{"B$k"} = 1 unless $bes & (1 << $v->[0]); + $res->{"A$k"} = 1 unless $bes & (1 << $v->[1]); + } + return $res; +} + +sub check_disccomplete { + my ($which, $guid) = @_; + (my $kind = $guid) =~ s/^[0-9a-f:]+:([234])c[27]$/$1/; + (my $ppguid = $guid) =~ s/:[^:]+$/:1c1/; + (my $sysid = $ppguid) =~ s/:.*//; + if (exists $proxypp{$ppguid} && exists $proxypp{$ppguid}->{tcreate}) { + $proxypp{$ppguid}->{disccomplete}->{"$which$discentitystr{$kind}"} = 1; + if (! $proxypp{$ppguid}->{disccompleteflag} && keys %{$proxypp{$ppguid}->{disccomplete}} == 3 * keys %discentitystr) { + $proxypp{$ppguid}->{disccompleteflag} = 1; + my $dt = $ts - $proxypp{$ppguid}->{tcreate}; + printf "%8.3f %24s %30.30s DISC node %s (%u; %s) discovery complete after %.3fs\n", $ts, $sysid, "", $sysid{$sysid}->{ip}, hex($sysid), $sysid{$sysid}->{name}, $dt; + } + } +} + +sub delete_pwr { + my ($ts, $pwrguid, $isimplicit) = @_; + (my $ppguid = $pwrguid) =~ s/:[0-9a-f]+$/:1c1/; + #proxy endpoint doesn't necessarily exist, so shouldn't die + #die unless exists $pwr{$pwrguid} || $pwrguid =~ /[4c]2$/; + return unless exists $pwr{$pwrguid}; + my $pwr = $pwr{$pwrguid}; + my $proxypp = $proxypp{$ppguid}; + die unless defined $proxypp; + for (keys %{$pwr->{matches}}) { + die unless $rd{$_}->{matches}->{$pwrguid}; + delete $rd{$_}->{matches}->{$pwrguid}; + } + # removal from GUID hash and actual deletion are separate events, so + # this is imprecise; built-ins get rougher treatmeant as they are + # not explicitly discovered + if ($pwrguid !~ /[4c]2$/) { + $pwr->{matches} = {}; + $pwr{$pwrguid}->{tdel} = $ts; + $pwr{$pwrguid}->{explicitdel} = 1 unless $isimplicit; + if ($shows{remotedisc} && $pwr{$pwrguid}->{topic} =~ /$topic_filter/o && $pwr{$pwrguid}->{topic} !~ /$topic_xfilter/o) { + printf "%8.3f %24s %30.30s UNDISCOVER %s\n", $ts, $pwrguid, $pwr{$pwrguid}->{stopic}, $isimplicit ? " (implicit)" : ""; + } + } else { + delete $proxypp->{pwr}->{$pwrguid}; + delete $pwr{$pwrguid}; + } +} + +sub delete_prd { + my ($ts, $prdguid, $isimplicit) = @_; + (my $ppguid = $prdguid) =~ s/:[0-9a-f]+$/:1c1/; + #proxy endpoint doesn't necessarily exist, so shouldn't die + #die unless exists $prd{$prdguid} || $prdguid =~ /[4c]7$/; + return unless exists $prd{$prdguid}; + my $prd = $prd{$prdguid}; + my $proxypp = $proxypp{$ppguid}; + die unless defined $proxypp; + for (keys %{$prd->{matches}}) { + next if defined $prd->{matches}->{$_}->{seqp1del}; + die unless $wr{$_}->{matches}->{$prdguid}; + my $x = $wr{$_}->{matches}->{$prdguid}; + $wr{$_}->{nhappy}-- if $x->{happy}; + my $dtmatch = $ts - $x->{tmatch}; + if ($x->{seqp1} == 0) { + # also happens when a writer with an empty WHC has written + # nothing since the match, hence disabling it for now + printf "%8.3f %24s %30.30s DEL %s no ACKs received, reader matched for %.3fs\n", $ts, $_, $wr{$_}->{stopic}, $prdguid, $dtmatch + if $shows{ack} && 0; + } elsif ($wr{$_}->{seq} >= $x->{seqp1}) { + printf "%8.3f %24s %30.30s DEL %s %d samples behind, reader matched for %.3fs\n", $ts, $_, $wr{$_}->{stopic}, $prdguid, $wr{$_}->{seq} - $x->{seqp1} + 1, $dtmatch + if $shows{ack} && show_topic($wr{$_}->{topic}); + } + $prd->{matches}->{$_}->{seqp1del} = $x->{seqp1}; + delete $wr{$_}->{matches}->{$prdguid}; + if ($wr{$_}->{acklate} && acklate($ts, $_) == 0) { + printf "%8.3f %24s %30.30s ACK caught up because of unmatch\n", $ts, fmtguid($_), $wr{$_}->{stopic} if $shows{ack} && show_topic($wr{$_}->{topic}); + $wr{$_}->{acklate} = 0; + } + } + if ($prdguid !~ /[4c]7$/) { + #$prd->{matches} = {}; + $prd{$prdguid}->{tdel} = $ts; + $prd{$prdguid}->{explicitdel} = 1 unless $isimplicit; + if ($shows{remotedisc} && $prd{$prdguid}->{topic} =~ /$topic_filter/o && $prd{$prdguid}->{topic} !~ /$topic_xfilter/o) { + printf "%8.3f %24s %30.30s UNDISCOVER %s\n", $ts, $prdguid, $prd{$prdguid}->{stopic}, $isimplicit ? " (implicit)" : ""; + } + } else { + delete $proxypp->{prd}->{$prdguid}; + delete $prd{$prdguid}; + } +} + +sub delete_proxypp { + my ($ts, $ppguid) = @_; + my $proxypp = $proxypp{$ppguid}; + (my $sysid = $ppguid) =~ s/:.*//; + die unless defined $proxypp; + #my @pwrguids = keys %{$proxypp->{pwr}}; + #die unless @pwrguids == 0; + #my @prdguids = keys %{$proxypp->{prd}}; + #die unless @prdguids == 0; + $proxypp{$ppguid}->{tdel} = $ts; + #delete $proxypp{$ppguid}; + die unless $sysid{$sysid}->{npp} > 0; + if (--$sysid{$sysid}->{npp} == 0) { + my $dt = (defined $sysid{$sysid}->{tcrash}) ? $ts - $sysid{$sysid}->{tcrash} : undef; + my $dtmsg = (defined $dt) ? sprintf " (cleanup took %.3fs)", $dt : ""; + printf "%8.3f %24s %30.30s DISC node %s (%u; %s) no proxy participants left%s\n", + $ts, $sysid, "", $sysid{$sysid}->{ip}, hex($sysid), $sysid{$sysid}->{name}, $dtmsg; + $sysid{$sysid}->{tdel} = $ts; + $sysid{$sysid}->{tcrash} = undef; + } +} + +sub getdest { + my ($wrguid) = @_; + my $wr = $wr{$wrguid}; + die unless defined $wr; + my @xs = sort { $a cmp $b } (keys %{$wr->{matches}}); + my $d = ""; + my $l = ""; + my $n = 0; + for (@xs, "0") { + my $pp = $proxypp{"$1:1c1"} if /^(.*):[0-9a-f]+$/; + die unless defined $pp || $_ eq "0"; + /^([0-9a-f]+)/; + if ($l eq $1) { + $n++; + } else { + $d .= "*$n" if $n > 1; + $n = 0; + $l = $1; + $d .= " $pp->{ip}" if defined $pp; + } + } + $d =~ s/^ +//; + return ($d eq "") ? "(no prd)" : $d; +} + +sub interpret_durability_nameSpaces { + my ($ds, $d) = @_; + unless ($d =~ s/"([^"]+)","[^"]*",(\d+),(true|false) \(\d\),(\d+),\{(\d+),(\d+)\},(\d+),\{(\d+),\d+,\d+\},(?:true|false) \((\d+)\),(?:true|false) \((\d+)\),\{"([^"]*)",(\d+)\},//) { + print $d; + die; + } + my ($name, $dkind, $aligner, $akind, $initqsec, $initqnsec, $total, $master, $complete, $mconfirmed, $role, $nativestate) = ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12); + # $dkind, $aligner, $akind, $total, $role: all config options + $dkind = $aligner = $akind = $role = undef; # kill warning + # $initqsec, $initqnsec: only interesting if discovering persistent source + # -- i.e., if $ds == 3 + $master = sprintf "%x", $master; + my $mip = ""; + if (exists $sysid{$master} && exists $sysid{$master}->{self}) { + $master .= "/ME"; + } elsif (exists $sysid{$master}) { + $master .= "/$sysid{$master}->{ip}"; + } + if ($ds == 3) { + sprintf "%s: master %s%s quality %d.%09u [%d]", $name, $master, ($mconfirmed ? "" : "?"), $initqsec, $initqnsec, $total; + } else { + $nativestate = unpack("l", pack("L", $nativestate)); + sprintf "%s: master %s%s nsState %d [%d]", $name, $master, ($mconfirmed ? "" : "?"), $nativestate, $total; + } +} + +sub bigE_readOctet { + my ($dref, $sref) = @_; # the handling of printable sequences is a bit of a hack + if (!$$sref) { + if ($$dref =~ s/^(\d+)(?: '.')?,//) { + return $1; + } elsif ($$dref =~ s/^"(.)//) { + $$sref = 1; + return ord($1); + } else { + print "$$sref/$$dref\n"; + die; + } + } else { + $$dref =~ s/^(.)//; + my $ret = ord($1); + if ($$dref =~ s/^",(?=\d+)//) { + $$sref = 0; + } + return $ret; + } +} + +sub bigE_read4 { + my ($n, @x) = (4); push @x, bigE_readOctet(@_) while $n--; return unpack("N", pack("C*", @x)); +} +sub bigE_read8 { + my ($n, @x) = (8); push @x, bigE_readOctet(@_) while $n--; return unpack("Q>", pack("C*", @x)); +} +sub bigE_readT { + my ($n, @x) = (2); push @x, bigE_read4(@_) while $n--; return \@x; +} +sub bigE_readGID { + my ($n, @x) = (3); push @x, bigE_read4(@_) while $n--; return \@x; +} + +sub bigE_unpack { + my ($template, $dref, $sref) = @_; + my @res = (); + my ($w, $n, $last, $op); + my $idx = 0; + while ($idx < length $template) { + die unless (substr $template, $idx) =~ /^(\/?)([CbLQTGx])(\d*)/; + die if $1 ne '' && $3 ne ''; + $idx += (length $1) + 1 + (length $3); + $w = $2; + $n = ($1 eq '/') ? $last : ($3 eq '') ? 1 : $3; + if ($w eq 'x') { + bigE_readOctet($dref, $sref) while $n--; + } else { + if ($w eq 'C') { $op = \&bigE_readOctet; } + elsif ($w eq 'b') { $op = \&bigE_readOctet; } + elsif ($w eq 'L') { $op = \&bigE_read4; } + elsif ($w eq 'Q') { $op = \&bigE_read8; } + elsif ($w eq 'T') { $op = \&bigE_readT; } + elsif ($w eq 'G') { $op = \&bigE_readGID; } + else { die; } + push @res, ($last = &$op($dref, $sref)) while $n--; + } + } + return @res; +} + +sub interpret_durability_sampleChain { + my ($d) = @_; + my ($topic, $part, $pre); + unless ($d =~ s/^"([^"]*)","([^"]*)",//) { + return $d; + } + $part = $1; + $topic = $2; + $pre = "part=\"$part\" topic=\"$topic\""; + unless ($d =~ /(.*?),0:\{\{83 'S',50 '2',0,1,(.*)/) { + return "$pre $d"; + } else { + my ($e, $s) = ($2, 0); + my ($size, $isvalid, $state, $aTime, $wTime, $wGid, $wiGid, $seqno, $txnId) = + bigE_unpack("LbLTTGGLL", \$e, \$s); + my $vmsg = sprintf "size=%u state=%u at=%u.%09u wt=%u.%09u wg=%x:%x:%x wig=%x:%x:%x seq=%u txn=%u", + $size, $state, $aTime->[0], $aTime->[1], $wTime->[0], $wTime->[1], + $wGid->[0], $wGid->[1], $wGid->[2], $wiGid->[0], $wiGid->[1], $wiGid->[2], + $seqno, $txnId; + # skip QoS - perhaps include unpack-msg-qos.pl to decode it + bigE_unpack("L/C", \$e, \$s) if bigE_readOctet(\$e, \$s); + my $int = $scintcache{$topic}; + if (! defined $int) { + for my $k (keys %scint) { if ($topic =~ /$k/) { $int = $scintcache{$topic} = $scint{$k}; last; } } + $int = $scintcache{$topic} = sub { return ""; } unless defined $int; + } + # 1 is write, 4 is disposed, 256 is register and 512 is unregister + # any of those and there are key values present, any others, not so much + my $content = &$int(\$e, \$s) if $state & (1 | 4 | 256 | 512); + if (defined $content && $content ne "") { + return "$pre $vmsg $content $d"; + } else { + return "$pre $vmsg $d"; + } + } +} + +sub interpret_durability { + my ($topic, $d) = @_; + return $d if $topic =~ /^d_(historical|durability)/; + unless ($d =~ s/^\{\{\{(\d+),\d+,\d+\},\{(\d+),\d+,\d+\},(\d+),\{(\d+),(\d+)\},\d+\}[},]//) { + print $d; + die; + } + die unless defined $t0sec && defined $t0usec; + #my $ts = ($4 - $t0sec) + (($5 & 0x7fffffff) / 1000.0 - $t0usec) / 1e6; + my $dst = sprintf "%x", $1; + if ($1 == 0) { + $dst = "to ALL"; + } elsif (exists $sysid{$dst} && exists $sysid{$dst}->{self}) { + $dst = "to ME"; + } elsif (exists $sysid{$dst}) { + #$dst = "to $sysid{$dst}->{ip}"; + $dst = "to $sysid{$dst}->{name}"; + } else { + $dst = "to UNK"; + } + my $src = sprintf "%x", $2; + if ($2 == 0) { + $src = "0 " + } elsif (exists $sysid{$src} && exists $sysid{$src}->{self}) { + $src = ""; + } elsif (exists $sysid{$src}) { + #$src = "$sysid{$src}->{ip} "; + $src = "$sysid{$src}->{name} "; + } else { + $src = "UNK "; + } + my $ds = $3; + my $dstext = $durstate[$ds]; + #return sprintf "[%s%s t=%.3f %s] %s", $src, $dst, $ts, $ds, $d; + if ($topic eq "d_nameSpaces") { + $d = interpret_durability_nameSpaces($ds, $d); + } elsif ($topic eq "d_sampleChain") { + $d = interpret_durability_sampleChain($d); + } + return sprintf "[%s%s %s] %s", $src, $dst, $dstext, $d; +} + +sub show_topic { + my ($topic) = @_; + return $shows{topic} if $topic =~ /^DCPSTopic/; + return $shows{builtin} if $topic =~ /^(CM|DCPS|q_)/; + return $shows{durability} if $topic =~ /^d_/; + return $shows{user} && $topic =~ /$topic_filter/o && $topic !~ /$topic_xfilter/o; +} + +sub check_qos { + my ($ts, $kind, $guid, $topic, $partitions, $qos) = @_; + if ($kind eq 'WRITER' && $qos =~ /,presentation=2:1:/ && $qos =~ /,history=0:/) { + printf "%8.3f $kind %s %s {%s} is keep-last and group coherent\n", $ts, $guid, $topic, $partitions; + } +} + +sub usage { + print << 'EOT' +Usage: ddsi-log [OPTIONS] INPUT + +--show KEYWORD enable/disable showing of certain categories of + events (see below) +--topic-filter REGEX limit output to topics matching REGEX (and for + durability, durability protocol data that somehow + matches REGEX) +--topic-xfilter REGEX do not show anything related to topics matching REGEX + (even when it matches the topic-filter) +--t0 TIMESTAMP set timestamp reference to TIMESTAMP, timestamps + printed are relative to this; defaults to the first + timestamp in the input +--sc PERLFILE durability 'sample chain' interpreter, user code + to decode (part of) the samples transferred by + durability. Included using perl's "do" statement, + it should return a hash table that maps regular + expressions for topic names to a code reference given + the durability message payload (see below) +--hn PERLFILE IP-address to name translator, included using perl's + "do" statement, it should return a code reference + that takes the IP-address and the name as strings and + returns the name to use (which can be just the IP + address, the default) + +The --show option gives some control over the kinds of events that are +shown in the output. Below is a list of keywords with the defaults. +Enabling is the default, disabling is done by prefixing the keyword +with "no" (i.e., --show noin means no input is shown). + +KEYWORD DEF DESCRIPTION +* topic no show data related to topic discovery +* durability no show durability traffic +* builtin no show writes for OpenSplice built-in topics +* localdisc no show discovery events for local readers and writers +* remotedisc no show discovery events for remote readers and writers +* mtreader no show events on multi-topic reader for local discovery +* user yes show user traffic +* ack yes show some ACK-related events (retransmit requests, + long delays until an ACK is received, catching up + after there has been an issue) +* block yes show blocking (and unblocking) events in transmit + path if it is blocked for some time +* throttle no show all blocking (and unblocking) events in + transmit path +* rematch no show matching events for local writers and remote + readers +* in yes show incoming traffic +* out yes show outgoing traffic +* partition no include partition names in output + +The sample chain interpreters get an OSPL 'BigE' serialised message, +possibly truncated. Some simple cases for decoding these have been +covered by the bigE_unpack function taking a string template and an +unspecified set of additional parameters (these additional parameters +are the passed into the sample chain interpreter). The bigE_unpack +function is provided in this script and accessible as ::bigE_unpack +within a sample chain interpreter. It is reminiscent of perl's native +unpack functions in its use of templates to decode the contents, but +it is not quite the same. Templates can use: + +* C decodes an unsigned 8-bit integer +* b decodes a boolean +* L decodes an unsigned 32-bit integer +* Q decodes an unsigned 64-bit integer (this assumes + perl supporting 64-bit integers) +* T decode 2 unsigned 32-bit integers, returned as a + reference to an array +* G decode 3 unsigned 32-bit integers, returned as a + reference to an array +* x skip input +* a numerical suffix repeat count for unpacking multiple of the same +* / prefix take repeat count from preceding decoded value + +I.e., L3x4L/C means unpack 3 32-bit integers, then skip 4 bytes, +decode a 32-bit integer, read as many bytes as the preceding integer +value, and return that as a list of (4+n) elements. The return value +of the function is spliced in as text. + +For example: + package sc; + sub intp_PubSub { + # struct { unsigned long seq; long keyval; ... }; + my @ks = ::bigE_unpack("x4L", @_); + return sprintf "key={%u}", @ks; + } + return ('PubSub' => \&intp_PubSub); + +LIMITATIONS + +The script started out for analysing DDSI2 traces from a shared-memory +configuration in SquashParticipants mode and with a known mapping of +IP addresses to host names (hence the translation functions). It +handles single-process and non-SquashParticipants just fine, but the +output is mostly based on IP addresses and host names and may be +somewhat confusing in those (more standard) configurations. +EOT +; + exit 1; + return; +} diff --git a/bin/magic_make.pl b/bin/magic_make.pl index 56ecdb38f..5c8bd9769 100755 --- a/bin/magic_make.pl +++ b/bin/magic_make.pl @@ -50,6 +50,9 @@ my $config = 'Release'; +# When set enable the lib modifier which is set when release build and a debug build is included +my $ospl_lib_modifier = 0; + my $splice_target = $ENV{SPLICE_TARGET}; if ($debug_override == '') { @@ -67,6 +70,7 @@ { $config = '"Release Debug"'; $ndebug = 1; + $ospl_lib_modifier = 1; } } @@ -387,6 +391,10 @@ sub do_mpc { unshift(@mpc_args, '--ospl-home', "$ospl_home"); } + if ($ospl_lib_modifier) + { + unshift(@mpc_args, '--ospl-libmod'); + } my $command = "mwc.pl @mpc_args"; print STDERR "$scriptname: Generating MPC build file(s): $command\n"; $ret = system($command); diff --git a/bin/mwc.pl b/bin/mwc.pl index d6f0c1401..d26d8cdfe 100755 --- a/bin/mwc.pl +++ b/bin/mwc.pl @@ -36,9 +36,11 @@ my $left_over_args; my $ret; my $ospl_home_hack; +my $ospl_libmod; ($ret, $left_over_args) = GetOptions('src-co' => \$src_checkout, 'java-only' => \$java_only, - 'ospl-home=s' => \$ospl_home_hack); + 'ospl-home=s' => \$ospl_home_hack, + 'ospl-libmod' => \$ospl_libmod); my($basePath) = (defined $FindBin::RealBin ? $FindBin::RealBin : File::Spec->rel2abs(dirname($0))); @@ -162,7 +164,10 @@ $build_bit_64 = 1; } -unshift(@ARGV, '--value_template', 'lib_modifier='); +# When ospl_libmod is set then do not disable the lib_modifier +if (!defined $ospl_libmod) { + unshift(@ARGV, '--value_template', 'lib_modifier='); +} unshift(@ARGV, '--features', 'ospl_64_bit=' . $build_bit_64); if (defined $just_os) { diff --git a/build/docs/ConfGuide/source/conf.py b/build/docs/ConfGuide/source/conf.py index 35564a60f..f5b0ba8ed 100644 --- a/build/docs/ConfGuide/source/conf.py +++ b/build/docs/ConfGuide/source/conf.py @@ -48,9 +48,8 @@ # General information about the project. project = u'OpenSplice Configuration Guide' -#copyright = u'2015, PrismTech' this_year = time.strftime( '%Y' ) -copyright = u'{y}, PrismTech'.format( y = this_year ) +copyright = u'{y}, ADLINK Technology Limited'.format( y = this_year ) print 'Copyright string is:', copyright # The version info for the project you're documenting, acts as replacement for @@ -244,7 +243,7 @@ # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). -man_pages = [('index', 'OpenSplice_Configuration_Guide', u'OpenSplice_Configuration_Guide Documentation', [u'PrismTech'], 1)] +man_pages = [('index', 'OpenSplice_Configuration_Guide', u'OpenSplice_Configuration_Guide Documentation', [u'ADLINK'], 1)] # -- Additional options -------------------------------------------------------- diff --git a/build/docs/DDSLabVIEWGuide/Makefile b/build/docs/DDSLabVIEWGuide/Makefile new file mode 100644 index 000000000..fe415b065 --- /dev/null +++ b/build/docs/DDSLabVIEWGuide/Makefile @@ -0,0 +1,130 @@ +# Makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = sphinx-build +PAPER = +BUILDDIR = build + +# Internal variables. +PAPEROPT_a4 = -D latex_paper_size=a4 +PAPEROPT_letter = -D latex_paper_size=letter +ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source + +.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest + +help: + @echo "Please use \`make ' where is one of" + @echo " html to make standalone HTML files" + @echo " dirhtml to make HTML files named index.html in directories" + @echo " singlehtml to make a single large HTML file" + @echo " pickle to make pickle files" + @echo " json to make JSON files" + @echo " htmlhelp to make HTML files and a HTML help project" + @echo " qthelp to make HTML files and a qthelp project" + @echo " devhelp to make HTML files and a Devhelp project" + @echo " epub to make an epub" + @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" + @echo " latexpdf to make LaTeX files and run them through pdflatex" + @echo " text to make text files" + @echo " man to make manual pages" + @echo " changes to make an overview of all changed/added/deprecated items" + @echo " linkcheck to check all external links for integrity" + @echo " doctest to run all doctests embedded in the documentation (if enabled)" + +clean: + -rm -rf $(BUILDDIR)/* + +html: + $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." + +dirhtml: + $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." + +singlehtml: + $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml + @echo + @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." + +pickle: + $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle + @echo + @echo "Build finished; now you can process the pickle files." + +json: + $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json + @echo + @echo "Build finished; now you can process the JSON files." + +htmlhelp: + $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp + @echo + @echo "Build finished; now you can run HTML Help Workshop with the" \ + ".hhp project file in $(BUILDDIR)/htmlhelp." + +qthelp: + $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp + @echo + @echo "Build finished; now you can run "qcollectiongenerator" with the" \ + ".qhcp project file in $(BUILDDIR)/qthelp, like this:" + @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/OpenSplice_Getting_Started_Guide.qhcp" + @echo "To view the help file:" + @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/OpenSplice_Getting_Started_Guide.qhc" + +devhelp: + $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp + @echo + @echo "Build finished." + @echo "To view the help file:" + @echo "# mkdir -p $$HOME/.local/share/devhelp/OpenSplice_Getting_Started_Guide" + @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/OpenSplice_Getting_Started_Guide" + @echo "# devhelp" + +epub: + $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub + @echo + @echo "Build finished. The epub file is in $(BUILDDIR)/epub." + +latex: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo + @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." + @echo "Run \`make' in that directory to run these through (pdf)latex" \ + "(use \`make latexpdf' here to do that automatically)." + +latexpdf: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo "Running LaTeX files through latexpdf..." + make -C $(BUILDDIR)/latex all-pdf + @echo "latexpdf finished; the PDF files are in $(BUILDDIR)/latexpdf." + +text: + $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text + @echo + @echo "Build finished. The text files are in $(BUILDDIR)/text." + +man: + $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man + @echo + @echo "Build finished. The manual pages are in $(BUILDDIR)/man." + +changes: + $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes + @echo + @echo "The overview file is in $(BUILDDIR)/changes." + +linkcheck: + $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck + @echo + @echo "Link check complete; look for any errors in the above output " \ + "or in $(BUILDDIR)/linkcheck/output.txt." + +doctest: + $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest + @echo "Testing of doctests in the sources finished, look at the " \ + "results in $(BUILDDIR)/doctest/output.txt." diff --git a/build/docs/DDSLabVIEWGuide/make.bat b/build/docs/DDSLabVIEWGuide/make.bat new file mode 100644 index 000000000..fff4f8663 --- /dev/null +++ b/build/docs/DDSLabVIEWGuide/make.bat @@ -0,0 +1,183 @@ +@ECHO OFF + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set BUILDDIR=build +set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% source +if NOT "%PAPER%" == "" ( + set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS% +) + +if "%1" == "" goto help + +if "%1" == "help" ( + :help + echo.Please use `make ^` where ^ is one of + echo. html to make standalone HTML files + echo. dirhtml to make HTML files named index.html in directories + echo. singlehtml to make a single large HTML file + echo. pickle to make pickle files + echo. json to make JSON files + echo. htmlhelp to make HTML files and a HTML help project + echo. qthelp to make HTML files and a qthelp project + echo. devhelp to make HTML files and a Devhelp project + echo. epub to make an epub + echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter + echo. text to make text files + echo. man to make manual pages + echo. changes to make an overview over all changed/added/deprecated items + echo. linkcheck to check all external links for integrity + echo. doctest to run all doctests embedded in the documentation if enabled + goto end +) + +if "%1" == "clean" ( + for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i + del /q /s %BUILDDIR%\* + goto end +) + +if "%1" == "html" ( + %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The HTML pages are in %BUILDDIR%/html. + goto end +) + +if "%1" == "dirhtml" ( + %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml. + goto end +) + +if "%1" == "singlehtml" ( + %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml. + goto end +) + +if "%1" == "pickle" ( + %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can process the pickle files. + goto end +) + +if "%1" == "json" ( + %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can process the JSON files. + goto end +) + +if "%1" == "htmlhelp" ( + %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can run HTML Help Workshop with the ^ +.hhp project file in %BUILDDIR%/htmlhelp. + goto end +) + +if "%1" == "qthelp" ( + %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can run "qcollectiongenerator" with the ^ +.qhcp project file in %BUILDDIR%/qthelp, like this: + echo.^> qcollectiongenerator %BUILDDIR%\qthelp\OpenSplice_Getting_Started_Guide.qhcp + echo.To view the help file: + echo.^> assistant -collectionFile %BUILDDIR%\qthelp\OpenSplice_Getting_Started_Guide.ghc + goto end +) + +if "%1" == "devhelp" ( + %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. + goto end +) + +if "%1" == "epub" ( + %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The epub file is in %BUILDDIR%/epub. + goto end +) + +if "%1" == "latex" ( + %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; the LaTeX files are in %BUILDDIR%/latex. + goto end +) + +if "%1" == "latexpdf" ( + %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latexpdf + echo %BUILDDIR%/latexpdf +REM Typical path: "c:\Program Files (x86)\GnuWin32\bin\make.exe" -C %BUILDDIR%\latexpdf all-pdf +REM Actual path on this system: C:\apps\GnuWin32\bin\make.exe -C %BUILDDIR%\latexpdf all-pdf + C:\apps\GnuWin32\bin\make.exe -C %BUILDDIR%\latexpdf all-pdf + echo.Build done + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; the LaTeX files are in %BUILDDIR%/latexpdf. + goto end +) + +if "%1" == "text" ( + %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The text files are in %BUILDDIR%/text. + goto end +) + +if "%1" == "man" ( + %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The manual pages are in %BUILDDIR%/man. + goto end +) + +if "%1" == "changes" ( + %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes + if errorlevel 1 exit /b 1 + echo. + echo.The overview file is in %BUILDDIR%/changes. + goto end +) + +if "%1" == "linkcheck" ( + %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck + if errorlevel 1 exit /b 1 + echo. + echo.Link check complete; look for any errors in the above output ^ +or in %BUILDDIR%/linkcheck/output.txt. + goto end +) + +if "%1" == "doctest" ( + %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest + if errorlevel 1 exit /b 1 + echo. + echo.Testing of doctests in the sources finished, look at the ^ +results in %BUILDDIR%/doctest/output.txt. + goto end +) + +:end diff --git a/build/docs/DDSLabVIEWGuide/source/IDL-LabVIEW.rst b/build/docs/DDSLabVIEWGuide/source/IDL-LabVIEW.rst new file mode 100644 index 000000000..73b61ab71 --- /dev/null +++ b/build/docs/DDSLabVIEWGuide/source/IDL-LabVIEW.rst @@ -0,0 +1,275 @@ +.. _`LabVIEW Generation from IDL`: + +########################### +LabVIEW Generation from IDL +########################### + +While creating a DDS application in LabVIEW, the user must create Topic VIs which map to DDS topic types. In addition to registering a topic, the user neeeds to create DDS Read and DDS Write VIs. LabVIEW data is represented in clusters. The DDS Read and Write VIs have terminals that require a LabVIEW cluster. On data writes, the LabVIEW clusters are converted to DDS topic types and on data reads, the DDS topic types are converted to LabVIEW clusters. + +The user can generate the LabVIEW clusters and DDS VIs from an IDL file. + +The DDS LabVIEW Integration supports generation of LabVIEW typedefs and VIs from IDL. This chapter describes the details of the IDL-LabVIEW binding. + +Generating LabVIEW VIs from an IDL File IDLPP +********************************************* + +DDS Topic Types can be described in an IDL file. The LabVIEW IDL generation is done using the **Import_IDL** Tools menu in LabVIEW. + +*Tools/VortexDDS/Import_IDL* + +.. figure:: images/import_idl.png + :alt: Import IDL + +In the IDL file, ensure that any topic structures have the OSPL specific annotation *pragma keylist* defined. This value is added as a **keylist constant** to the *key* terminal of the generated RegisterTopic.vi. + +Select the IDL file and a folder for the generated VIs. + +.. figure:: images/import_idl_dialog.png + :alt: Import IDL + +Upon successful generation the VIs are located in the folder that was chosen. A dialog box appears indicating the path of the generated VIs and the IDL file. + +.. figure:: images/idl_import_success.png + :alt: Import IDL + + +.. raw:: latex + + \newpage + + +Generated Artifacts +******************* + +The following table defines the LabVIEW artifacts generated from IDL concepts: + +=========== =============== ======================================================= +IDL Concept LabVIEW Concept Comment +=========== =============== ======================================================= +module Appended to the name of each VI contained in the module +enum enum a LabVIEW .ctl file. +enum value enum value +struct cluster a LabVIEW .ctl file. +field cluster field +sequence array +array array +=========== =============== ======================================================= + + +**Datatype mappings** + +The following table shows the LabVIEW equivalents to IDL primitive types: + +.. table:: + + +--------------------------+-------------------------------+ + |**DDS IDL** |**LabVIEW Type** | + +==========================+===============================+ + |boolean |Boolean | + +--------------------------+-------------------------------+ + |char |int8 | + +--------------------------+-------------------------------+ + |octet |uint8 | + +--------------------------+-------------------------------+ + |short |int16 | + +--------------------------+-------------------------------+ + |unsigned short |uint16 | + +--------------------------+-------------------------------+ + |long |int32 | + +--------------------------+-------------------------------+ + |unsigned long |uint32 | + +--------------------------+-------------------------------+ + |long long |int64 | + +--------------------------+-------------------------------+ + |unsigned long long |uint64 | + +--------------------------+-------------------------------+ + |float |single-precision floating point| + +--------------------------+-------------------------------+ + |double |double-precision floating point| + +--------------------------+-------------------------------+ + |string |String | + +--------------------------+-------------------------------+ + | **Unsupported DDS data types** | + +--------------------------+-------------------------------+ + |wchar |*not supported* | + +--------------------------+-------------------------------+ + |wstring |*not supported* | + +--------------------------+-------------------------------+ + |any |*not supported* | + +--------------------------+-------------------------------+ + |long double |*not supported* | + +--------------------------+-------------------------------+ + |union |*not supported* | + +--------------------------+-------------------------------+ + |inheritance |*not supported* | + +--------------------------+-------------------------------+ + + +**Generated VIs and controls** + +For each struct in the IDL file, the following VIs and controls are generated: + +- RegisterTopic.vi +- Write.vi +- Read.vi +- CicoTable.vi (Copy-in copy-out) +- Topic cluster.ctl (corresponds to each struct in IDL File) +- Enum.ctl (corresponds to each enum in IDL File) + +The "moduleName_structName" is appended to the name of each VI and control that is generated. + +.. raw:: latex + + \newpage + +RegisterTopic.vi +**************** + +The RegisterTopic.vi represents a DDS topic type. The DDS topic corresponds to a single data type. In DDS, data is distributed by publishing and subscribing topic data samples. + +.. figure:: images/register_topic.png + :alt: Register Topic + + + +============= ========= ======================= =========================== ============================ +Terminal Type Optional Name Description Output consumed by +============= ========= ======================= =========================== ============================ +Input no DomainParticipantHandle DDS Domain Participant + entity instance + +Input no TopicName DDS Topic Name + +Input yes QosProfilePath QoS file uri + +Input yes QoSProfileName Name of QoS profile + +Input yes error in (no error) Input Error cluster + +Output no topicHandle DDS Topic entity instance create_reader.vi + create_writer.vi + +Output yes error out Error out cluster +============= ========= ======================= =========================== ============================ + + +.. raw:: latex + + \newpage + +Read.vi +******* + +The DDS Read.vi is used to read DDS samples from a specific topic. + +.. figure:: images/dds_read.png + :alt: Register Topic + + + +============= ========= ======================= =========================== ============================ +Terminal Type Optional Name Description Output consumed by +============= ========= ======================= =========================== ============================ +Input no readerHandle DDS Reader + entity instance + +Input yes mask read_condition masks + LabVIEW cluster + +Input yes max_samples maximum number of samples + to read + +Input yes read_operation READ or TAKE + default operation is TAKE + +Input yes query_expression expression to filter + samples based on a query + +Input yes query_parameters parameters for the query + expression + +Input yes wait_available_data wait for data available + _timeout timeout (seconds) + +Input yes error in (no error) Input Error cluster + +Output yes no_of_samples Number of samples read user + +Output no samples LabVIEW cluster user + +Output yes dds_sample_info_array sample information user + +Output yes error out Error out cluster +============= ========= ======================= =========================== ============================ + + +.. raw:: latex + + \newpage + +Filters +======= + +The filtering of incoming samples can happen based on a query and/or on a sample read condition(s). + +**Query** + +query_expression: The expression is a SQL condition. + +query_parameters: Each parameter element must be an array element. + +*Note: Query expressions are only validated at runtime. If they are incorrect, errors will occur while running the VI.* + + +**Read Condition** + +The read condition mask specified will filter the samples that are read or take(n). + +Example: For a reader, the Sample State has **Not Read** selected and **Read** deselected. + +Only samples with a Sample State **Not Read** will be processed with read or take. +Any samples with the **Read** sample state will not be read or take(n). + + +.. figure:: images/read_filter.png + :alt: Reader Filter + + +.. raw:: latex + + \newpage + + +Write.vi +******** + +The DDS Write.vi is used to write DDS samples to a specific topic. + +.. figure:: images/dds_write.png + :alt: Write + + + +============= ========= ======================= =========================== ============================ +Terminal Type Optional Name Description Output consumed by +============= ========= ======================= =========================== ============================ +Input no writerHandle DDS Writer + entity instance + +Input yes write_op write operation: WRITE, + DISPOSE, WRITE_DISPOSE + Default operation: WRITE + +Input no data samples LabVIEW cluster DDS + +Input yes wait_pub_matched wait for publication + _timeout matched timeout (seconds) + +Input yes write_after_timeout write samples + after timeout + +Input yes error in (no error) Input Error cluster + +Output yes error out Error out cluster +============= ========= ======================= =========================== ============================ + diff --git a/build/docs/DDSLabVIEWGuide/source/conf.py b/build/docs/DDSLabVIEWGuide/source/conf.py new file mode 100644 index 000000000..f05fea338 --- /dev/null +++ b/build/docs/DDSLabVIEWGuide/source/conf.py @@ -0,0 +1,282 @@ +# -*- coding: utf-8 -*- +# +# OpenSplice_Deployment_Guide build configuration file, created by +# ReST Editor on 06-Jul-2015 +# +# This file is execfile()d with the current directory set to its containing dir. +# +# Note that not all possible configuration values are present in this +# autogenerated file. +# +# All configuration values have a default; values that are commented out +# serve to show the default. + +import sys, os +import time + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +#sys.path.insert(0, os.path.abspath('.')) + +# -- General configuration ----------------------------------------------------- + +# If your documentation needs a minimal Sphinx version, state it here. +#needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be extensions +# coming with Sphinx (named 'sphinx.ext.*') or your custom ones. +#extensions = ['sphinx.ext.todo'] + +extensions = ['sphinx.ext.todo', 'sphinx.ext.ifconfig'] + +def setup(app): + app.add_config_value('rmi_languages', '', True) + +#rmi_languages = 'C++ and Java' +rmi_languages = 'C++' +#rmi_languages = 'Java' +rst_prolog = """ +.. |rmi_langs| replace:: C++ +.. |product_name| replace:: OpenSplice +""" + +#.. |rmi_langs| replace:: C++ and Java + + + +# Add any paths that contain templates here, relative to this directory. +templates_path = [u'_templates'] + + +# The suffix of source filenames. +source_suffix = '.rst' + +# The encoding of source files. +source_encoding = u'utf-8-sig' + + +# The master toctree document. +master_doc = u'index' + + +# General information about the project. +project = u'Vortex OpenSplice LabVIEW Guide' + +this_year = time.strftime( '%Y' ) +copyright = u'{y}, ADLINK Technology Limited'.format( y = this_year ) +print 'Copyright string is:', copyright + + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# +# The short X.Y version. +version = u'6.x' + +# The full version, including alpha/beta/rc tags. +release = version +#release = u'.0' +print 'Short version string is:', version +print 'Full version string is:', release + + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +language = u'en' + + +# There are two options for replacing |today|: either, you set today to some +# non-false value, then it is used: +today = ' ' +# Else, today_fmt is used as the format for a strftime call. +#today_fmt = '%B %d, %Y' + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +exclude_patterns = [] + +# The reST default role (used for this markup: `text`) to use for all documents. +#default_role = None + +# If true, '()' will be appended to :func: etc. cross-reference text. +#add_function_parentheses = True + +# If true, the current module name will be prepended to all description +# unit titles (such as .. function::). +#add_module_names = True + +# If true, sectionauthor and moduleauthor directives will be shown in the +# output. They are ignored by default. +#show_authors = False + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + +# A list of ignored prefixes for module index sorting. +#modindex_common_prefix = [] + + +# -- Options for HTML output --------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# html_theme = u'sphinxdoc' +html_theme = u'vortextheme' +# LINUX PATH: +html_theme_path = ['../../.'] +# WINDOWS PATH: +# html_theme_path = ['..\..\.'] +#build theme directory in lite using environment variable, so shared amongst books +# insight team can delete, +#html_theme_path = [os.environ['VL_HOME'] + '/build/docs'] + + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +#html_theme_options = {} + +# Add any paths that contain custom themes here, relative to this directory. +#html_theme_path = [] + +# The name for this set of Sphinx documents. If None, it defaults to +# " v documentation". +#html_title = None +html_title = 'The Vortex OpenSplice LabVIEW Guide' + +# A shorter title for the navigation bar. Default is the same as html_title. +#html_short_title = None +#html_short_title = 'HTML short Title conf.py' +html_short_title = 'OpenSplice LabVIEW Guide' + +# The name of an image file (relative to this directory) to place at the top +# of the sidebar. +html_logo = './images/Vortex_logo_2014.png' + +# The name of an image file (within the static path) to use as favicon of the +# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 +# pixels large. +#html_favicon = None + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = [u'_static'] + + +# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, +# using the given strftime format. +#html_last_updated_fmt = '%b %d, %Y' + +# If true, SmartyPants will be used to convert quotes and dashes to +# typographically correct entities. +#html_use_smartypants = True + +# Custom sidebar templates, maps document names to template names. +#html_sidebars = {} + +# Additional templates that should be rendered to pages, maps page names to +# template names. +#html_additional_pages = {} + +# If false, no module index is generated. +#html_domain_indices = True + +# If false, no index is generated. +#html_use_index = True + +# If true, the index is split into individual pages for each letter. +#html_split_index = False + +# If true, links to the reST sources are added to the pages. +#html_show_sourcelink = True + +# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. +#html_show_sphinx = True +html_show_sphinx = False + +# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. +#html_show_copyright = True + +# If true, an OpenSearch description file will be output, and all pages will +# contain a tag referring to it. The value of this option must be the +# base URL from which the finished HTML is served. +#html_use_opensearch = '' + +# This is the file name suffix for HTML files (e.g. ".xhtml"). +#html_file_suffix = None + +# Output file base name for HTML help builder. +htmlhelp_basename = 'The Vortex OpenSplice LabVIEW Guide' + + +# -- Options for LaTeX output -------------------------------------------------- + +# The paper size ('letter' or 'a4'). +latex_paper_size = u'a4' + + +# The font size ('10pt', '11pt' or '12pt'). +latex_font_size = u'10pt' + + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, author, documentclass [howto/manual]). +latex_documents = [('index', 'OpenSplice_DDSLabVIEWGuide.tex', u'OpenSplice LabVIEW Guide', u'', 'manual', True)] +# Note 'author' field empty +# Added 'True' to end of generated line to suppress 'Index & Tables' + + +# A dictionary that contains LaTeX snippets that override those Sphinx usually +# puts into the generated .tex files. +latex_elements = { 'babel': '\\usepackage[english]{babel}' } + + +# The name of an image file (relative to this directory) to place at the top of +# the title page. +latex_logo = './images/Vortex-Cover.png' + +# For "manual" documents, if this is true, then toplevel headings are parts, +# not chapters. +latex_use_parts = False + + +# If true, show page references after internal links. +#latex_show_pagerefs = False + +# If true, show URL addresses after external links. +#latex_show_urls = False + +# Additional stuff for the LaTeX preamble. +latex_preamble = r""" +\setcounter {tocdepth} {5} +\setcounter{secnumdepth}{5} + +""" + +# * THIS GETS RID OF BLANK PAGES AT ENDS OF CHAPTERS & ToC +latex_elements = { + 'classoptions': ',openany, oneside', + 'babel': '\\usepackage[english]{babel}' +} + + +# Documents to append as an appendix to all manuals. +#latex_appendices = [] + +# If false, no module index is generated. +#latex_domain_indices = True + + +# -- Options for manual page output -------------------------------------------- + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [('index', 'OpenSplice_DDSLabVIEWGuide', u'OpenSplice_DDSLabVIEW Documentation', [u'ADLINK Technology Limited'], 1)] + + +# -- Additional options -------------------------------------------------------- + +todo_include_todos = True diff --git a/build/docs/DDSLabVIEWGuide/source/contacts.rst b/build/docs/DDSLabVIEWGuide/source/contacts.rst new file mode 100644 index 000000000..d32f6016f --- /dev/null +++ b/build/docs/DDSLabVIEWGuide/source/contacts.rst @@ -0,0 +1 @@ +.. include:: ../../common/contacts.rst diff --git a/build/docs/DDSLabVIEWGuide/source/dds_vis.rst b/build/docs/DDSLabVIEWGuide/source/dds_vis.rst new file mode 100644 index 000000000..df9084946 --- /dev/null +++ b/build/docs/DDSLabVIEWGuide/source/dds_vis.rst @@ -0,0 +1,257 @@ +.. _`Vortex DDS Virtual Instruments`: + + +#################################### +Vortex DDS Virtual Instruments (VIs) +#################################### + + +The DDS LabVIEW Integration provides a function palette with custom virtual instruments (VIs) to model reading and writing data with DDS. + +.. figure:: images/dds_palette.png + :alt: VortexDDS VIs + +The Vortex DDS LabVIEW VIs are included in **VortexDDS** functions palette. + +The following DDS VIs are provided: + + - create_participant.vi + - create_publisher.vi + - create_subscriber.vi + - create_writer.vi + - create_reader.vi + - wait_historical_data.vi + - delete_entity.vi + +DDS VIs usage +************* + +The typical way to model a DDS application in LabVIEW is as follows: + +* model your DDS topics using IDL +* using the LabVIEW IDLPP process generate DDS Topic, Read and Write VIs from the IDL file +* add the generated VIs to your LabVIEW project +* create a DDS LabVIEW application using the VortexDDS functions palette and the generated VIs from the previous step + +QoS Profiles +************ + +In DDS - “The Data-Distribution Service (DDS) relies on the usage of QoS. A QoS (Quality of Service) is a set of characteristics that controls some aspect of the behavior of the DDS Service." + +Each DDS entity VI has an associated QoS profile. By default, the OSPL default profile is used. An XML file that specifies QoS profiles can be used to set the QoS of a DDS entity. + +The QoS profile of an entity is set using the **qos_uri** and **qos_profile** terminals. + + +Please see section :ref:`QoS Provider` for more information. + + +create_participant.vi +********************* + +The create_participant VI represents a DDS domain participant entity. + +In DDS - "A domain participant represents the local membership of the application in a domain. A domain is a distributed concept that links all the applications able to communicate with each other. It represents a communication plane: only the publishers and subscribers attached to the same domain may interact." + +The domain id is the OSPL default domain id specified in the OSPL configuration file (file pointed by "OSPL_URI" environment variable). + + +.. figure:: images/dds_participant.png + :alt: create_participant VI + + +============= ========= ======================= =========================== ============================ +Terminal Type Optional Name Description Output consumed by +============= ========= ======================= =========================== ============================ +Output no pp DDS Domain Participant create_publisher.vi + entity instance create_subscriber.vi + RegisterTopic.vi + +Input yes qos_uri QoS file uri + +Input yes qos_profile Name of QoS profile + +Input yes error in (no error) Input Error cluster + +Output yes error out Error out cluster +============= ========= ======================= =========================== ============================ + +.. raw:: latex + + \newpage + +create_publisher.vi +******************* + +The create_publisher VI represents a DDS publisher entity. + +In DDS, a publisher is "an object responsible for data distribution. It may publish data of different data types." + + +.. figure:: images/create_publisher.png + :alt: create_publisher VI + + +============= ========= ======================= =========================== ============================ +Terminal Type Optional Name Description Output consumed by +============= ========= ======================= =========================== ============================ +Input no pp DDS Domain Participant + entity instance + +Input yes qos_uri QoS file uri + +Input yes qos_profile Name of QoS profile + +Input yes error in (no error) Input Error cluster + +Output no pub DDS publisher create_writer.vi + entity instance + +Output yes error out Error out cluster +============= ========= ======================= =========================== ============================ + +.. raw:: latex + + \newpage + +create_subscriber.vi +******************** + +The create_subscriber VI represents a DDS subscriber entity. + +In DDS, a subscriber is "an object responsible for receiving published data and making it available to the receiving application. It may receive and dispatch data of different specified types." + + +.. figure:: images/create_subscriber.png + :alt: create_subscriber VI + + +============= ========= ======================= =========================== ============================ +Terminal Type Optional Name Description Output consumed by +============= ========= ======================= =========================== ============================ +Input no pp DDS Domain Participant + entity instance + +Input yes qos_uri QoS file uri + +Input yes qos_profile Name of QoS profile + +Input yes error in (no error) Input Error cluster + +Output no sub DDS subscriber create_reader.vi + entity instance + +Output yes error out Error out cluster +============= ========= ======================= =========================== ============================ + + +create_writer.vi +**************** + +The create_writer VI represents a DDS data writer entity. + +In DDS - "The DataWriter is the object the application must use to communicate to a publisher the existence and value of data-objects of a given type." + +.. figure:: images/create_writer.png + :alt: create_writer VI + + +============= ========= ======================= =========================== ============================ +Terminal Type Optional Name Description Output consumed by +============= ========= ======================= =========================== ============================ +Input no pub DDS publisher + entity instance + +Input no topic DDS Topic + entity instance + +Input yes qos_uri QoS file uri + +Input yes qos_profile Name of QoS profile + +Input yes error in (no error) Input Error cluster + +Output no writer DDS writer write.vi + entity instance + +Output yes error out Error out cluster +============= ========= ======================= =========================== ============================ + + +create_reader.vi +**************** + +The create_reader VI represents a DDS data reader entity. + +In DDS - "To access the received data, the application must use a typed DataReader attached to the subscriber." + + +.. figure:: images/create_reader.png + :alt: create_reader VI + + +============= ========= ======================= =========================== ============================ +Terminal Type Optional Name Description Output consumed by +============= ========= ======================= =========================== ============================ +Input no sub DDS subscriber + entity instance + +Input no topic DDS Topic + entity instance + +Input yes qos_uri QoS file uri + +Input yes qos_profile Name of QoS profile + +Input yes error in (no error) Input Error cluster + +Output no reader DDS reader read.vi + entity instance + +Output yes error out Error out cluster +============= ========= ======================= =========================== ============================ + + +wait_historical_data.vi +*********************** + +The wait_historical_data VI specifies that the Reader will wait for historical data to arrive. The timeout terminal is for setting time period (in seconds) determining how long the Reader should wait for the historical data. If the timeout is reached, then any remaining historical data may be interleaved with new data. + + +.. figure:: images/wait_historical.png + :alt: wait_historical VI + + +============= ========= ======================= =========================== ============================ +Terminal Type Optional Name Description Output consumed by +============= ========= ======================= =========================== ============================ +Input no reader DDS Reader + entity instance + +Input yes historical_timeout wait for historical data + timeout (seconds) + +Input yes error in (no error) Input Error cluster + +Output yes error out Error out cluster +============= ========= ======================= =========================== ============================ + + +delete_entity.vi +**************** + +The delete_entity VI is used to delete a DDS entity. Connect the DDS participant to the entity terminal to delete the participant (pp) in a LabVIEW DDS application. + + *NOTE: If the user application VI stops due to an error and does not run to completion, the participant entity is not deleted and leaks occur. The participants are deleted once the user closes LabVIEW.* + +.. figure:: images/delete_entity.png + :alt: delete_entity VI + + +============= ========= ======================= =========================== ============================ +Terminal Type Optional Name Description Output consumed by +============= ========= ======================= =========================== ============================ +Input no entity DDS entity instance +============= ========= ======================= =========================== ============================ + + diff --git a/build/docs/DDSLabVIEWGuide/source/example.rst b/build/docs/DDSLabVIEWGuide/source/example.rst new file mode 100755 index 000000000..9e3cea27f --- /dev/null +++ b/build/docs/DDSLabVIEWGuide/source/example.rst @@ -0,0 +1,175 @@ +.. _`Demo iShapes Example`: + +#################### +Demo iShapes Example +#################### + +A simple demo iShapes example is provided to demonstrates the basic capabilities of the LabVIEW DDS integration. It displays DDS communication between LabVIEW and pure DDS applications. + +The demo_ishapes.vi example (LabVIEW application) can be found using the **NI Example Finder** in LabVIEW: + +.. figure:: images/example_finder.png + :alt: NI Example Finder + +The demo_ishapes.exe (DDS application) can be found in the following directory. + + `OSPL_HOME`/bin/demo_ishapes.exe + +.. raw:: latex + + \newpage + +Example Files +************* + +An explanation of what each example file does is provided below. + +.. figure:: images/demo_ishapes_files.png + :alt: Demo ishapes files + + +**DDS_Data Folder** + +This folder contains the idl file and artifacts generated from idlpp process. + +**ishape.idl** + +- Defines the ShapeType in idl +- Used to generate the LabVIEW DDS VIs via idlpp + +**ishape.idl.xml** + +- Defines the topic descriptor from idl file + +**ShapeType_CicoTable.vi** + +- Defines the copy-in, copy-out table information for mapping IDL to LabVIEW types + +**ShapeType.ctl** + +- Defines a ShapeType cluster in LabVIEW; generated from idlpp +- The ShapeType represents a DDS topic type +- ShapeType specifies 4 properties: color, x, y, shapesize + +**ShapeType_Read.vi** + +- DDS Read ShapeType samples + +**ShapeType_Write.vi** + +- DDS Write ShapeType samples + +**ShapeType_Topic.vi** + +- DDS Register ShapeType topic + +**DDS_PersistentQoS_All.xml** + +- XML file that specifies the DDS QoS (quality of service) settings for RegisterTopic + +**DDS_VolatileQoS_All.xml** + +- XML file that specifies the DDS QoS (quality of service) settings for Reader and Writer entities + +**demo_ishapes.vi** + +- Creates a participant on the default DDS domain +- Registers a ShapeType Topic to Read and to Write to one of the three topics: Circle, Square or Triangle +- Subscribes to the shape and color from demo_ishapes.exe DDS application +- As soon as they match, demo_ishapes.vi publishes to the DDS application and follows the subscribed shape + +.. raw:: latex + + \newpage + +Steps to run example +******************** + +Steps: + +1. Open command shell and run script to setup environment variables. + + **Linux** + + - Open a Linux terminal. + + - Navigate to directory containing release.com file. + + */INSTALLDIR/ADLINK/Vortex_v2/Device/VortexOpenSplice/6.9.x/HDE/x86_64.linux* + + - Run release.com. (Type in “. release.com†at command line.) + + + **Windows** + + - Open a command prompt. + + - Navigate to directory containing release.bat file. + + *INSTALLDIR/ADLINK/Vortex_v2/Device/VortexOpenSplice/6.9.x/HDE/x86_64.win64* + + - Run release.bat. (Type in “release.bat†at command line.) + +2. Navigate to the directory that contains demo_ishapes.exe DDS application and run the application using the command shell used in Step 1. + + **Linux** + + */INSTALLDIR/ADLINK/Vortex_v2/Device/VortexOpenSplice/6.9.x/HDE/x86_64.linux/bin* + + - Run demo_ishapes.exe (Type in “./demo_ishapes.exe &†at command line) + + **Windows** + + *INSTALLDIR/ADLINK/Vortex_v2/Device/VortexOpenSplice/6.9.x/HDE/x86_64.win64/bin* + + - Run demo_ishapes.exe (Type in “demo_ishapes.exe &†at command line) + +3. Start LabVIEW using the **SAME** command shell used in Step 1. Open the demo_ishapes.vi using the **NI Example Finder** in LabVIEW. + + *NOTE: If LabVIEW and the demo_ishapes.exe application are NOT started from a command shell with the correct OSPL environment variables set, the example will not work.* + +.. raw:: latex + + \newpage + +4. In the LabVIEW demo_ishapes.vi application make the following selections: + + Read Shape: Circle + Track color: GREEN + + Write Shape: Triangle + Write color: MAGENTA + + .. figure:: images/labview_example_selection.png + :alt: Demo ishapes LabVIEW selection + +.. raw:: latex + + \newpage + +5. In the demo_ishapes.exe DDS application make the following selections: + + Shape: Circle + Color: Green + Click **Publish** + + Shape: Triangle + Click **Subscribe** + + .. figure:: images/dds_example_selection.png + :alt: Demo ishapes DDS application selection + +6. Run the LabVIEW demo_ishapes.vi application + +7. To stop the LabVIEW application, click on **STOP** on the front panel of the demo_ishapes.vi. + + +Output +****** + +LabVIEW application publishes samples to the DDS application. In the demo_ishapes.exe application, the Triangle follows the Circle. + + +.. figure:: images/example_output.png + :alt: Example outputss + diff --git a/build/docs/DDSLabVIEWGuide/source/images/Vortex-Cover.png b/build/docs/DDSLabVIEWGuide/source/images/Vortex-Cover.png new file mode 100644 index 000000000..d82d6b313 Binary files /dev/null and b/build/docs/DDSLabVIEWGuide/source/images/Vortex-Cover.png differ diff --git a/build/docs/DDSLabVIEWGuide/source/images/Vortex_logo_2014.png b/build/docs/DDSLabVIEWGuide/source/images/Vortex_logo_2014.png new file mode 100644 index 000000000..e7de4f525 Binary files /dev/null and b/build/docs/DDSLabVIEWGuide/source/images/Vortex_logo_2014.png differ diff --git a/build/docs/DDSLabVIEWGuide/source/images/create_publisher.png b/build/docs/DDSLabVIEWGuide/source/images/create_publisher.png new file mode 100755 index 000000000..769e42af2 Binary files /dev/null and b/build/docs/DDSLabVIEWGuide/source/images/create_publisher.png differ diff --git a/build/docs/DDSLabVIEWGuide/source/images/create_reader.png b/build/docs/DDSLabVIEWGuide/source/images/create_reader.png new file mode 100755 index 000000000..498f17211 Binary files /dev/null and b/build/docs/DDSLabVIEWGuide/source/images/create_reader.png differ diff --git a/build/docs/DDSLabVIEWGuide/source/images/create_subscriber.png b/build/docs/DDSLabVIEWGuide/source/images/create_subscriber.png new file mode 100755 index 000000000..36a622368 Binary files /dev/null and b/build/docs/DDSLabVIEWGuide/source/images/create_subscriber.png differ diff --git a/build/docs/DDSLabVIEWGuide/source/images/create_writer.png b/build/docs/DDSLabVIEWGuide/source/images/create_writer.png new file mode 100755 index 000000000..3654db92d Binary files /dev/null and b/build/docs/DDSLabVIEWGuide/source/images/create_writer.png differ diff --git a/build/docs/DDSLabVIEWGuide/source/images/dds_example_selection.png b/build/docs/DDSLabVIEWGuide/source/images/dds_example_selection.png new file mode 100755 index 000000000..c1675afc4 Binary files /dev/null and b/build/docs/DDSLabVIEWGuide/source/images/dds_example_selection.png differ diff --git a/build/docs/DDSLabVIEWGuide/source/images/dds_overview.png b/build/docs/DDSLabVIEWGuide/source/images/dds_overview.png new file mode 100755 index 000000000..c7490ddb4 Binary files /dev/null and b/build/docs/DDSLabVIEWGuide/source/images/dds_overview.png differ diff --git a/build/docs/DDSLabVIEWGuide/source/images/dds_palette.png b/build/docs/DDSLabVIEWGuide/source/images/dds_palette.png new file mode 100755 index 000000000..74aa71207 Binary files /dev/null and b/build/docs/DDSLabVIEWGuide/source/images/dds_palette.png differ diff --git a/build/docs/DDSLabVIEWGuide/source/images/dds_participant.png b/build/docs/DDSLabVIEWGuide/source/images/dds_participant.png new file mode 100755 index 000000000..69432da36 Binary files /dev/null and b/build/docs/DDSLabVIEWGuide/source/images/dds_participant.png differ diff --git a/build/docs/DDSLabVIEWGuide/source/images/dds_read.png b/build/docs/DDSLabVIEWGuide/source/images/dds_read.png new file mode 100755 index 000000000..414512c4e Binary files /dev/null and b/build/docs/DDSLabVIEWGuide/source/images/dds_read.png differ diff --git a/build/docs/DDSLabVIEWGuide/source/images/dds_write.png b/build/docs/DDSLabVIEWGuide/source/images/dds_write.png new file mode 100755 index 000000000..3fe69db12 Binary files /dev/null and b/build/docs/DDSLabVIEWGuide/source/images/dds_write.png differ diff --git a/build/docs/DDSLabVIEWGuide/source/images/delete_entity.png b/build/docs/DDSLabVIEWGuide/source/images/delete_entity.png new file mode 100755 index 000000000..4c306edce Binary files /dev/null and b/build/docs/DDSLabVIEWGuide/source/images/delete_entity.png differ diff --git a/build/docs/DDSLabVIEWGuide/source/images/demo_ishapes_files.png b/build/docs/DDSLabVIEWGuide/source/images/demo_ishapes_files.png new file mode 100755 index 000000000..9da432fcb Binary files /dev/null and b/build/docs/DDSLabVIEWGuide/source/images/demo_ishapes_files.png differ diff --git a/build/docs/DDSLabVIEWGuide/source/images/example_finder.png b/build/docs/DDSLabVIEWGuide/source/images/example_finder.png new file mode 100755 index 000000000..e497f4663 Binary files /dev/null and b/build/docs/DDSLabVIEWGuide/source/images/example_finder.png differ diff --git a/build/docs/DDSLabVIEWGuide/source/images/example_output.png b/build/docs/DDSLabVIEWGuide/source/images/example_output.png new file mode 100755 index 000000000..bb9b2168d Binary files /dev/null and b/build/docs/DDSLabVIEWGuide/source/images/example_output.png differ diff --git a/build/docs/DDSLabVIEWGuide/source/images/idl_import_success.png b/build/docs/DDSLabVIEWGuide/source/images/idl_import_success.png new file mode 100755 index 000000000..1f2d87741 Binary files /dev/null and b/build/docs/DDSLabVIEWGuide/source/images/idl_import_success.png differ diff --git a/build/docs/DDSLabVIEWGuide/source/images/import_idl.png b/build/docs/DDSLabVIEWGuide/source/images/import_idl.png new file mode 100755 index 000000000..fd1e1a1cd Binary files /dev/null and b/build/docs/DDSLabVIEWGuide/source/images/import_idl.png differ diff --git a/build/docs/DDSLabVIEWGuide/source/images/import_idl_dialog.png b/build/docs/DDSLabVIEWGuide/source/images/import_idl_dialog.png new file mode 100755 index 000000000..947a8ca23 Binary files /dev/null and b/build/docs/DDSLabVIEWGuide/source/images/import_idl_dialog.png differ diff --git a/build/docs/DDSLabVIEWGuide/source/images/labview_example_selection.png b/build/docs/DDSLabVIEWGuide/source/images/labview_example_selection.png new file mode 100755 index 000000000..4e53fb638 Binary files /dev/null and b/build/docs/DDSLabVIEWGuide/source/images/labview_example_selection.png differ diff --git a/build/docs/DDSLabVIEWGuide/source/images/list_qos_profiles.png b/build/docs/DDSLabVIEWGuide/source/images/list_qos_profiles.png new file mode 100755 index 000000000..7e2adea36 Binary files /dev/null and b/build/docs/DDSLabVIEWGuide/source/images/list_qos_profiles.png differ diff --git a/build/docs/DDSLabVIEWGuide/source/images/qos_profile_tools.png b/build/docs/DDSLabVIEWGuide/source/images/qos_profile_tools.png new file mode 100755 index 000000000..534890f6d Binary files /dev/null and b/build/docs/DDSLabVIEWGuide/source/images/qos_profile_tools.png differ diff --git a/build/docs/DDSLabVIEWGuide/source/images/read_filter.png b/build/docs/DDSLabVIEWGuide/source/images/read_filter.png new file mode 100755 index 000000000..fe5b5a4fd Binary files /dev/null and b/build/docs/DDSLabVIEWGuide/source/images/read_filter.png differ diff --git a/build/docs/DDSLabVIEWGuide/source/images/register_topic.png b/build/docs/DDSLabVIEWGuide/source/images/register_topic.png new file mode 100755 index 000000000..8406925b6 Binary files /dev/null and b/build/docs/DDSLabVIEWGuide/source/images/register_topic.png differ diff --git a/build/docs/DDSLabVIEWGuide/source/images/set_qos.png b/build/docs/DDSLabVIEWGuide/source/images/set_qos.png new file mode 100755 index 000000000..3f001ef27 Binary files /dev/null and b/build/docs/DDSLabVIEWGuide/source/images/set_qos.png differ diff --git a/build/docs/DDSLabVIEWGuide/source/images/wait_historical.png b/build/docs/DDSLabVIEWGuide/source/images/wait_historical.png new file mode 100755 index 000000000..36fd2aae6 Binary files /dev/null and b/build/docs/DDSLabVIEWGuide/source/images/wait_historical.png differ diff --git a/build/docs/DDSLabVIEWGuide/source/images/windowsInstall1.png b/build/docs/DDSLabVIEWGuide/source/images/windowsInstall1.png new file mode 100755 index 000000000..bada3d8dc Binary files /dev/null and b/build/docs/DDSLabVIEWGuide/source/images/windowsInstall1.png differ diff --git a/build/docs/DDSLabVIEWGuide/source/index.rst b/build/docs/DDSLabVIEWGuide/source/index.rst new file mode 100644 index 000000000..77a5b1c5d --- /dev/null +++ b/build/docs/DDSLabVIEWGuide/source/index.rst @@ -0,0 +1,26 @@ +.. The Vortex OpenSplice LabVIEW Guide + +.. Doc Issue 01, 11 December 2017 + +################## +DDS LabVIEW Guide +################## + +.. toctree:: + :maxdepth: 6 + :numbered: + + introduction + installation + dds_vis + IDL-LabVIEW + qos_provider + example + + contacts + + +Indices and tables +================== + +* :ref:`search` diff --git a/build/docs/DDSLabVIEWGuide/source/installation.rst b/build/docs/DDSLabVIEWGuide/source/installation.rst new file mode 100644 index 000000000..42394815e --- /dev/null +++ b/build/docs/DDSLabVIEWGuide/source/installation.rst @@ -0,0 +1,112 @@ +.. _`Installation`: + +############ +Installation +############ + +This section describes the procedure to install the Vortex DDS LabVIEW Integration on a Linux or Windows platform. + +System Requirements +******************* + +- Operating System: Windows or Linux +- LabVIEW 2017 installed + +OpenSplice (OSPL) and DDS LabVIEW Installation +*********************************************** + +Steps: + +1. Install OSPL. The DDS LabVIEW Integration is included in this installer. + +2. Setup OSPL license. Copy the license.lic file into the appropriate license directory. + + */INSTALLDIR/ADLINK/Vortex_v2/license* + +3. LabVIEW installation files are contained in a tools/labview folder. + + Example: + */INSTALLDIR/ADLINK/Vortex_v2/Device/VortexOpenSplice/6.9.x/HDE/x86_64.linux/tools/labview* + +OpenSplice (OSPL) Configuration +******************************* + +By default OSPL uses single process configuration. + +DDS LabVIEW Installation +************************ + +Linux +===== + +1. Open a command shell and navigate to + + */INSTALLDIR/ADLINK/Vortex_v2/Device/VortexOpenSplice/6.9.x/HDE/x86_64.linux/tools/labview* + +2. Unzip the "adlink-dds-labview-linux-install.tar.gz". + +3. Run the install_vortex_dds_ubuntu.sh script as a super user. + + sudo ./install_vortex_dds_ubuntu.sh + + *NOTE: The installer sets the default LabVIEW installation path to /usr/local/natinst/LabVIEW-2017-64.* *To override this installation directory, run the install script and pass the install directory as an argument:* + + *sudo ./install_vortex_dds_ubuntu.sh /path/to/your/LabVIEW/installation* + +4. LabVIEW will open and allow the installation Virtual Instrument (VI) run to completion. + +5. After the installation is complete close LabVIEW. Installation takes effect the next time you start LabVIEW. + +Windows +======= + +1. In a file browser, navigate to + + */INSTALLDIR/ADLINK/Vortex_v2/Device/VortexOpenSplice/6.9.x/HDE/x86_64.windows/tools/labview* + +2. Double click on the file “adlink_lib_vortexdds-1.0.0.1â€. This will bring up the VI Package Manager installer dialog box. Select the LabVIEW version to install (32-bit or 64-bit). Select **Install**. + +.. figure:: images/windowsInstall1.png + :alt: DDS windows install + +3. After the installation is complete close LabVIEW. Installation takes effect the next time you start LabVIEW. + +.. raw:: latex + + \newpage + +Running LabVIEW +*************** + +Steps: + +1. Open command shell and run script to setup environment variables. + + **Linux** + + - Open a Linux terminal. + + - Navigate to directory containing release.com file. + + */INSTALLDIR/ADLINK/Vortex_v2/Device/VortexOpenSplice/6.9.x/HDE/x86_64.linux* + + - Run release.com. (Type in “. release.com†at command line.) + + + **Windows** + + - Open a command prompt. + + - Navigate to directory containing release.bat file. + + *INSTALLDIR/ADLINK/Vortex_v2/Device/VortexOpenSplice/6.9.x/HDE/x86_64.win64* + + - Run release.bat. (Type in “release.bat†at command line.) + + +2. Start LabVIEW using the **SAME** command shell used in Step 1. + + *NOTE: If LabVIEW is NOT started from a command shell with the correct OSPL environment variables set, errors will occur when attempting to use DDS LabVIEW virtual instruments.* + + + diff --git a/build/docs/DDSLabVIEWGuide/source/introduction.rst b/build/docs/DDSLabVIEWGuide/source/introduction.rst new file mode 100644 index 000000000..e6ce33b31 --- /dev/null +++ b/build/docs/DDSLabVIEWGuide/source/introduction.rst @@ -0,0 +1,39 @@ +.. _`Introduction`: + + +############ +Introduction +############ + +The DDS LabVIEW Integration provides users with DDS custom virtual instruments (VIs) to model DDS communication between LabVIEW and pure DDS applications. + +DDS +*** + +**What is DDS?** + +“The Data Distribution Service (DDSâ„¢) is a middleware protocol and API standard for data-centric connectivity from the Object Management Group® (OMG®). It integrates the components of a system together, providing low-latency data connectivity, extreme reliability, and a scalable architecture that business and mission-critical Internet of Things (IoT) applications need.†+ +“The main goal of DDS is to share the right data at the right place at the right time, even between time-decoupled publishers and consumers. DDS implements global data space by carefully replicating relevant portions of the logically shared dataspace.†DDS specification + +.. figure:: images/dds_overview.png + :alt: DDS + +**Further Documentation** + +http://portals.omg.org/dds/ + +http://ist.adlinktech.com/ + +LabVIEW +******** + +**What is LabVIEW?** + +“LabVIEW is systems engineering software for applications that require test, measurement, and control with rapid access to hardware and data insights. The LabVIEW programming environment simplifies hardware integration for engineering applications so that you have a consistent way to acquire data from NI and third-party hardware. +The LabVIEW programming environment simplifies hardware integration for engineering applications so that you have a consistent way to acquire data from NI and third-party hardware. LabVIEW reduces the complexity of programming, so you can focus on your unique engineering problem. LabVIEW enables you to immediately visualize results with built-in, drag-and-drop engineering user interface creation and integrated data viewers. To turn your acquired data into real business results, you can develop algorithms for data analysis and advanced control with included math and signal processing IP or reuse your own libraries from a variety of tools. To ensure compatibility with other engineering tools, LabVIEW can interoperate with, and reuse libraries from, other software and open-source languages.†+ +http://www.ni.com/en-ca/shop/labview/buy-labview.html + + + diff --git a/build/docs/DDSLabVIEWGuide/source/qos_provider.rst b/build/docs/DDSLabVIEWGuide/source/qos_provider.rst new file mode 100644 index 000000000..b9ba9f346 --- /dev/null +++ b/build/docs/DDSLabVIEWGuide/source/qos_provider.rst @@ -0,0 +1,99 @@ +.. _`QoS Provider`: + + +############ +QoS Provider +############ + +Each Vortex DDS virtual instrument (VI) has a QoS file uri terminal and a QoS profile terminal. +These terminals are used to set the QoS profile. By default, the OSPL default profile is used. +In DDS - The Data-Distribution Service (DDS) relies on the usage of QoS. A QoS (Quality of Service) is a set of +characteristics that controls some aspect of the behavior of the DDS Service. + +Each DDS VI has an associated QoS profile. By default, the OSPL default profile is used. An XML file that +specifies QoS profiles can be used to set the QoS of a DDS block. + +The following section explains how the QoS is set for a DDS entity using the QoS Provider. + + +QoS Provider File +***************** + +Quality of Service for DDS entities is set using XML files based on the XML schema file DDS_QoSProfile.xsd. +These XML files contain one or more QoS profiles for DDS entities. + +**Note:** Sample QoS Profile XML files can be found in the LabVIEW DDS examples directories. + +QoS Profile +*********** + +A QoS profile consists of a name. The file contains QoS +elements for one or more DDS entities. A skeleton file without any QoS values is displayed below to show +the structure of the file. + + +.. code-block:: xml + + + + + + + + + + + + +**Example: Specify Publisher Partition** + +The example below specifies the publisher's partitions as A and B. + +.. code-block:: xml + + + + + A + B + + + + + +Setting QoS Profile in LabVIEW +****************************** + +The QoS Profiles from the XML file can be obtained using the **List_qos_profiles** Tools menu in LabVIEW. + +*Tools/VortexDDS/List_qos_profiles* + +.. figure:: images/qos_profile_tools.png + :alt: QoS Profile Tools + +.. raw:: latex + + \newpage + +**Steps to set the QoS Profile** + +1. A QoS Provider file can be selected by browsing to the XML file from the **List_qos_profiles** dialog box. Once a valid QoS file is chosen the **Available qos profiles** table is populated with the list of qos profiles that are available in the QoS XML file. If there are QoS profiles found in the file, then **Copy to Clipboard** button will be enabled. + +2. Select the QoS Profile that you want to use and click on **Copy to Clipboard**. + +.. figure:: images/list_qos_profiles.png + :alt: List qos profiles + +3. In your VI, create a String constant and press Ctrl + V. Connect this String constant to the DDS VI **qos_profile** terminal. Set the **qos_uri** as a LabVIEW control or constant and navigate to the path of the QoS Provider file. + +.. figure:: images/set_qos.png + :alt: Set QoS + +The **qos_profile** and **qos_uri** are optional terminals. If they are not set then the default QoS settings will be used. + +**Note:** Seeing the QoS Profile in the list only guarantees the QoS Profile exists in the file. +It does not mean the qos tag exists for the entity. The user is responsible for verifying the entity qos +tag exists in the file. + + diff --git a/build/docs/DDSMATLABGuide/Makefile b/build/docs/DDSMATLABGuide/Makefile new file mode 100644 index 000000000..fe415b065 --- /dev/null +++ b/build/docs/DDSMATLABGuide/Makefile @@ -0,0 +1,130 @@ +# Makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = sphinx-build +PAPER = +BUILDDIR = build + +# Internal variables. +PAPEROPT_a4 = -D latex_paper_size=a4 +PAPEROPT_letter = -D latex_paper_size=letter +ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source + +.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest + +help: + @echo "Please use \`make ' where is one of" + @echo " html to make standalone HTML files" + @echo " dirhtml to make HTML files named index.html in directories" + @echo " singlehtml to make a single large HTML file" + @echo " pickle to make pickle files" + @echo " json to make JSON files" + @echo " htmlhelp to make HTML files and a HTML help project" + @echo " qthelp to make HTML files and a qthelp project" + @echo " devhelp to make HTML files and a Devhelp project" + @echo " epub to make an epub" + @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" + @echo " latexpdf to make LaTeX files and run them through pdflatex" + @echo " text to make text files" + @echo " man to make manual pages" + @echo " changes to make an overview of all changed/added/deprecated items" + @echo " linkcheck to check all external links for integrity" + @echo " doctest to run all doctests embedded in the documentation (if enabled)" + +clean: + -rm -rf $(BUILDDIR)/* + +html: + $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." + +dirhtml: + $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." + +singlehtml: + $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml + @echo + @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." + +pickle: + $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle + @echo + @echo "Build finished; now you can process the pickle files." + +json: + $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json + @echo + @echo "Build finished; now you can process the JSON files." + +htmlhelp: + $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp + @echo + @echo "Build finished; now you can run HTML Help Workshop with the" \ + ".hhp project file in $(BUILDDIR)/htmlhelp." + +qthelp: + $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp + @echo + @echo "Build finished; now you can run "qcollectiongenerator" with the" \ + ".qhcp project file in $(BUILDDIR)/qthelp, like this:" + @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/OpenSplice_Getting_Started_Guide.qhcp" + @echo "To view the help file:" + @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/OpenSplice_Getting_Started_Guide.qhc" + +devhelp: + $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp + @echo + @echo "Build finished." + @echo "To view the help file:" + @echo "# mkdir -p $$HOME/.local/share/devhelp/OpenSplice_Getting_Started_Guide" + @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/OpenSplice_Getting_Started_Guide" + @echo "# devhelp" + +epub: + $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub + @echo + @echo "Build finished. The epub file is in $(BUILDDIR)/epub." + +latex: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo + @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." + @echo "Run \`make' in that directory to run these through (pdf)latex" \ + "(use \`make latexpdf' here to do that automatically)." + +latexpdf: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo "Running LaTeX files through latexpdf..." + make -C $(BUILDDIR)/latex all-pdf + @echo "latexpdf finished; the PDF files are in $(BUILDDIR)/latexpdf." + +text: + $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text + @echo + @echo "Build finished. The text files are in $(BUILDDIR)/text." + +man: + $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man + @echo + @echo "Build finished. The manual pages are in $(BUILDDIR)/man." + +changes: + $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes + @echo + @echo "The overview file is in $(BUILDDIR)/changes." + +linkcheck: + $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck + @echo + @echo "Link check complete; look for any errors in the above output " \ + "or in $(BUILDDIR)/linkcheck/output.txt." + +doctest: + $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest + @echo "Testing of doctests in the sources finished, look at the " \ + "results in $(BUILDDIR)/doctest/output.txt." diff --git a/build/docs/DDSMATLABGuide/make.bat b/build/docs/DDSMATLABGuide/make.bat new file mode 100644 index 000000000..fff4f8663 --- /dev/null +++ b/build/docs/DDSMATLABGuide/make.bat @@ -0,0 +1,183 @@ +@ECHO OFF + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set BUILDDIR=build +set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% source +if NOT "%PAPER%" == "" ( + set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS% +) + +if "%1" == "" goto help + +if "%1" == "help" ( + :help + echo.Please use `make ^` where ^ is one of + echo. html to make standalone HTML files + echo. dirhtml to make HTML files named index.html in directories + echo. singlehtml to make a single large HTML file + echo. pickle to make pickle files + echo. json to make JSON files + echo. htmlhelp to make HTML files and a HTML help project + echo. qthelp to make HTML files and a qthelp project + echo. devhelp to make HTML files and a Devhelp project + echo. epub to make an epub + echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter + echo. text to make text files + echo. man to make manual pages + echo. changes to make an overview over all changed/added/deprecated items + echo. linkcheck to check all external links for integrity + echo. doctest to run all doctests embedded in the documentation if enabled + goto end +) + +if "%1" == "clean" ( + for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i + del /q /s %BUILDDIR%\* + goto end +) + +if "%1" == "html" ( + %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The HTML pages are in %BUILDDIR%/html. + goto end +) + +if "%1" == "dirhtml" ( + %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml. + goto end +) + +if "%1" == "singlehtml" ( + %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml. + goto end +) + +if "%1" == "pickle" ( + %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can process the pickle files. + goto end +) + +if "%1" == "json" ( + %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can process the JSON files. + goto end +) + +if "%1" == "htmlhelp" ( + %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can run HTML Help Workshop with the ^ +.hhp project file in %BUILDDIR%/htmlhelp. + goto end +) + +if "%1" == "qthelp" ( + %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can run "qcollectiongenerator" with the ^ +.qhcp project file in %BUILDDIR%/qthelp, like this: + echo.^> qcollectiongenerator %BUILDDIR%\qthelp\OpenSplice_Getting_Started_Guide.qhcp + echo.To view the help file: + echo.^> assistant -collectionFile %BUILDDIR%\qthelp\OpenSplice_Getting_Started_Guide.ghc + goto end +) + +if "%1" == "devhelp" ( + %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. + goto end +) + +if "%1" == "epub" ( + %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The epub file is in %BUILDDIR%/epub. + goto end +) + +if "%1" == "latex" ( + %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; the LaTeX files are in %BUILDDIR%/latex. + goto end +) + +if "%1" == "latexpdf" ( + %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latexpdf + echo %BUILDDIR%/latexpdf +REM Typical path: "c:\Program Files (x86)\GnuWin32\bin\make.exe" -C %BUILDDIR%\latexpdf all-pdf +REM Actual path on this system: C:\apps\GnuWin32\bin\make.exe -C %BUILDDIR%\latexpdf all-pdf + C:\apps\GnuWin32\bin\make.exe -C %BUILDDIR%\latexpdf all-pdf + echo.Build done + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; the LaTeX files are in %BUILDDIR%/latexpdf. + goto end +) + +if "%1" == "text" ( + %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The text files are in %BUILDDIR%/text. + goto end +) + +if "%1" == "man" ( + %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The manual pages are in %BUILDDIR%/man. + goto end +) + +if "%1" == "changes" ( + %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes + if errorlevel 1 exit /b 1 + echo. + echo.The overview file is in %BUILDDIR%/changes. + goto end +) + +if "%1" == "linkcheck" ( + %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck + if errorlevel 1 exit /b 1 + echo. + echo.Link check complete; look for any errors in the above output ^ +or in %BUILDDIR%/linkcheck/output.txt. + goto end +) + +if "%1" == "doctest" ( + %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest + if errorlevel 1 exit /b 1 + echo. + echo.Testing of doctests in the sources finished, look at the ^ +results in %BUILDDIR%/doctest/output.txt. + goto end +) + +:end diff --git a/build/docs/DDSMATLABGuide/source/DDS-Classes.rst b/build/docs/DDSMATLABGuide/source/DDS-Classes.rst new file mode 100644 index 000000000..27a96be6b --- /dev/null +++ b/build/docs/DDSMATLABGuide/source/DDS-Classes.rst @@ -0,0 +1,433 @@ +.. _`MATLAB DDS Classes`: + +################################# +MATLAB API for Vortex DDS Classes +################################# + +The DDS MATLAB Integration provides a class library with custom classes to read and write data with DDS. + +The MATLAB DDS Classes are included in a **Vortex** package. + +API Usage patterns +****************** + +The typical usage pattern for the MATLAB API for Vortex DDS is the following: + +* model your DDS topics using IDL +* using ``idlpp -l matlab`` to compile your IDL into MATLAB topic classes. See :ref:`MATLAB Generation from IDL`. +* start writting your MATLAB program using the MATLAB API for Vortex DDS. + +The core classes you must use are ``Vortex.Topic`` and either ``Vortex.Reader`` or ``Vortex.Writer``. +Other classes may be required, especially if you need to adjust the Quality of Service (QoS) defaults. +For details on setting QoS values with the API, see :ref:`QoS Provider`. +The following list shows the sequence in which you would use the Vortex classes: + +* If you require participant-level non-default QoS settings, create a ``Vortex.Participant`` instance. Pass the participant to subsequently created Vortex entities. +* Create one or more ``Vortex.Topic`` instances for the IDL topics your program will read or write. +* If you require publisher or subscriber level non-default QoS settings, create ``Vortex.Publisher`` and/or ``Vortex.Subscriber`` instances. Pass these to any created reader or writers. (The most common reason for changing publisher/subscriber QoS is to define non-default partitions.) +* Create ``Vortex.Reader`` and/or ``Vortex.Writer`` classes from the ``Vortex.Topic`` instances that you created. +* If you required data filtering, create ``Vortex.Query`` objects. +* Create the core of program, creating instances of your topic classes and writing them; or, reading data and processing it. + +Vortex.Topic +************ + +The MATLAB Topic class represents a DDS topic type. The DDS topic corresponds to a single data type. In DDS, data is distributed by publishing and subscribing topic data samples. + +For a DDS Topic type definition, a corresponding MATLAB class must be defined in the MATLAB workspace. +This is either a class created by ``idlpp`` (see :ref:`MATLAB Generation from IDL`) or a manually +created MATLAB class (see :ref:`MATLAB without IDL`). +It is recommend that you create DDS Topic type definitions via IDL and `idlpp`. + +**API Examples** + +Create a Vortex DDS domain topic. Returns a topic instance, or throws a ``Vortex.DDSException`` if the topic cannot be created. + +Create a topic named 'Circle' based on the DDS Topic type ``ShapeType`` with default participant and QoS:: + + topic = Vortex.Topic('Circle', ?ShapeType); + +**Note**: In MATLAB, references to classes such as ShapeType are created by prefixing them with a +question mark (?). If the class is in a MATLAB package, then the fully qualified name must be used. +For example: ``?ShapesDemo.Topics.ShapeType``. + +Create the 'Circle' topic with an explicitly created participant:: + + % dp: a Vortex.DomainParticipant instance + topic = Vortex.Topic(dp, 'Circle', ?ShapeType); + +Create the 'Circle' topic with default participant and QoS profile:: + + % qosFileURI: a char array representing a file: URI + % qosProfile: a char array containing the name of a profile defined in the QoS File + topic = Vortex.Topic('Circle', ?ShapeType, qosFileURI, qosProfile); + +Create the 'Circle' topic with explicit participant and QoS profile:: + + % dp: a Vortex.DomainParticipant instance + % qosFileURI: a char array representing a file: URI + % qosProfile: a char array containing the name of a profile defined in the QoS File + topic = Vortex.Topic(dp, 'Circle', ?ShapeType, qosFileURI, qosProfile); + +Vortex.DomainParticipant +************************ + +The ``Vortex.DomainParticipant`` class represents a DDS domain participant entity. + +In DDS - “A domain participant represents the local membership of the application in a domain. A domain is a distributed concept that links all the applications able to communicate with each other. It represents a communication plane: only the publishers and subscribers attached to the same domain may interact.†+ +Use of the ``Vortex.DomainParticipant`` class is optional. +The API provides a 'default participant', which is used if no explicit domain participant is provided. +The default participant is created on first usage, and is disposed when MATLAB exits. +Reasons for using an explicitly created domain participant are: + +* to provide non-default QoS settings. +* to control the timing of participant creation and destruction. + +**API Examples** + +Create a Vortex DDS domain participant. Returns participant or throws a ``Vortex.DDSException`` if the participant cannot be created. + +Create a domain participant in the default DDS domain (the one specified by the OSLP_URI environment variable):: + + dp = Vortex.DomainParticipant(); + +Create a domain participant on domain, specifying a domain id:: + + % domainId: an integer value + dp = Vortex.DomainParticipant(domainId); + +**Note**: The underlying DCPS C99 API used by `Vortex.DomainParticipant` does not currently support this operation, and will result in a ``Vortex.DDSException`` being raised. + +Create a participant on default domain with QoS profile:: + + % qosFileURI: a char array representing a file: URI + % qosProfile: a char array containing the name of a profile defined in the QoS File + dp = Vortex.DomainParticipant(qosFileURI, qosProfile); + +Create a participant on domain with QoS profile:: + + % domainId: an integer value + % qosFileURI: a char array representing a file: URI + % qosProfile: a char array containing the name of a profile defined in the QoS File + dp = Vortex.DomainParticipant(domainId, qosFileURI, qosProfile); + +Vortex.Publisher +**************** + +The MATLAB ``Vortex.Publisher`` class represents a DDS publisher entity. + +In DDS, a publisher is “an object responsible for data distribution. It may publish data of different data types.†+ +Use of the ``Vortex.Publisher`` class is optional. +In it's place, you can use a ``Vortex.DomainParticipant`` instance, or default to the *default domain participant*. +Reasons for explicitly creating a ``Vortex.Publisher`` instance are: + +* to specify non-default QoS settings, including specifying the DDS *partition* upon which samples are written. +* to control the timing of publisher creation and deletion. + +**API Examples** + +Create a DDS Publisher entity. Returns publisher or throws a ``Vortex.DDSException`` if the publisher cannot be created. + +Create a default publisher with default participant:: + + pub = Vortex.Publisher(); + +Create a publisher with an explicit participant:: + + % dp: a Vortex.DomainParticipant instance + pub = Vortex.Publisher(dp); + +Create default publisher with default participant and QoS profile:: + + % qosFileURI: a char array representing a file: URI + % qosProfile: a char array containing the name of a profile defined in the QoS File + pub = Vortex.Publisher(qosFileURI, qosProfile); + +Create a publisher with participant and QoS profile:: + + % dp: a Vortex.DomainParticipant instance + % qosFileURI: a char array representing a file: URI + % qosProfile: a char array containing the name of a profile defined in the QoS File + pub = Vortex.Publisher(dp, qosFileURI, qosProfile); + +Vortex.Writer +************* + +The MATLAB ``Vortex.Writer`` class represents a DDS data writer entity. + +In DDS - “The DataWriter is the object the application must use to communicate to a publisher the existence and value of data-objects of a given type.†+ +A ``Vortex.Writer`` class is required in order to write data to a DDS domain. +It may be explicitly attached to a DDS publisher or a DDS domain participant; or, it is implicitly attached to the *default domain participant*. + +A ``Vortex.Writer`` class instance references an existing ``Vortex.Topic`` instance. + +**API Examples** + +Create a Vortex DDS domain writer. Returns writer or throws a ``Vortex.DDSException`` if the writer cannot be created. + +Create a writer for a topic, in the default domain participant and default QoS settings:: + + % topic: a Vortex.Topic instance + writer = Vortex.Writer(topic); + +Create a writer within an explicitly specified publisher or domain participant:: + + % pubOrDp: a Vortex.Publisher or Vortex.DomainParticipant instance + % topic: a Vortex.Topic instance + writer = Vortex.Writer(pubOrDp, topic); + +Create writer for a topic with explicit QoS profile:: + + % topic: a Vortex.Topic instance + % qosFileURI: a char array representing a file: URI + % qosProfile: a char array containing the name of a profile defined in the QoS File + writer = Vortex.Writer(topic, qosFileURI, qosProfile); + +Create a writer with publisher or participant, topic and QoS profile:: + + % pubOrDp: a Vortex.Publisher or Vortex.DomainParticipant instance + % topic: a Vortex.Topic instance + % qosFileURI: a char array representing a file: URI + % qosProfile: a char array containing the name of a profile defined in the QoS File + writer = Vortex.Writer(pubOrDp, topic, qosFileURI, qosProfile); + +Write a ShapeType topic class instance to a writer:: + + % writer: a Vortex.Writer instance + % ShapeType: a 'topic class' created manually or via IDLPP + data = ShapeType(); % create an object instance + % set data values... + data.color = 'RED'; + % ... set other values ... + + ddsStatus = writer.write(data); + +**Note**: the returned status value is 0 for success, and negative for failure. Use the ``Vortex.DDSException`` class to decode an failure status. + +Dispose a DDS topic instance:: + + % writer: a Vortex.Writer instance + % ShapeType: a 'topic class' created manually or via IDLPP + data = ShapeType(); % create an object instance + % set data key values... + data.color = 'RED'; + + ddsStatus = writer.dispose(data); + +**Note**: the returned status value is 0 for success, and negative for failure. Use the ``Vortex.DDSException`` class to decode an failure status. + +Unregister a DDS topic instance:: + + % writer: a Vortex.Writer instance + % ShapeType: a 'topic class' created manually or via IDLPP + data = ShapeType(); % create an object instance + % set data key values... + data.color = 'RED'; + + ddsStatus = writer.unregister(data); + +**Note**: the returned status value is 0 for success, and negative for failure. Use the ``Vortex.DDSException`` class to decode an failure status. + +Vortex.Subscriber +***************** + +The MATLAB ``Vortex.Subscriber`` class represents a DDS subscriber entity. + +In DDS, a subscriber is “an object responsible for receiving published data and making it available to the receiving application. It may receive and dispatch data of different specified types.†+ +Use of the ``Vortex.Subscriber`` class is optional. +In it's place, you can use a ``Vortex.DomainParticipant`` instance, or default to the *default domain participant*. +Reasons for explicitly creating a ``Vortex.Subscriber`` instance are: + +* to specify non-default QoS settings, including specifying the DDS *partition* upon which samples are written. +* to control the timing of subscriber creation and deletion. + +**API Examples** + + +Create a Vortex DDS domain subscriber. Returns subscriber or throw a ``Vortex.DDSException`` if the subscriber cannot be created. + +Create a subscriber within the default domain participant:: + + sub = Vortex.Subscriber(); + +Create a subscriber within an explicit participant:: + + % dp: a Vortex.DomainParticipant instance + sub = Vortex.Subscriber(dp); + +Create subscriber within the default domain participant and with a QoS profile:: + + % qosFileURI: a char array representing a file: URI + % qosProfile: a char array containing the name of a profile defined in the QoS File + sub = Vortex.Subscriber(qosFileURI, qosProfile); + +Create a subscriber with participant and QoS profile:: + + % dp: a Vortex.DomainParticipant instance + % qosFileURI: a char array representing a file: URI + % qosProfile: a char array containing the name of a profile defined in the QoS File + sub = Vortex.Subscriber(dp, qosFileURI, qosProfile); + + +Vortex.Reader +************* + +The MATLAB ``Vortex.Reader`` class represents a DDS data reader entity. + +In DDS - “To access the received data, the application must use a typed DataReader attached to the subscriber.†+ +A ``Vortex.Reader`` class is required in order to write data to a DDS domain. +It may be explicitly attached to a DDS subscriber or a DDS domain participant; or, it is implicitly attached to the *default domain participant*. + +A ``Vortex.Reader`` class instance references an existing ``Vortex.Topic`` instance. + +**API Examples** + +Create a Vortex DDS domain reader. Returns reader or throw a ``Vortex.DDSException`` instance if the reader cannot be created. + +Create a reader for a topic within the default domain participant, and with default QoS:: + + % topic: a Vortex.Topic instance + reader = Vortex.Reader(topic); + +Create a reader for a topic within a subscriber or participant, and with default QoS:: + + % subOrDp: a Vortex.Subscriber or Vortex.DomainParticipant instance + % topic: a Vortex.Topic instance + reader = Vortex.Reader(subOrDp, topic); + +Create reader for a topic within the default domain participant and with a QoS profile:: + + % topic: a Vortex.Topic instance + % qosFileURI: a char array representing a file: URI + % qosProfile: a char array containing the name of a profile defined in the QoS File + reader = Vortex.Reader(topic, qosFileURI, qosProfile); + +Create a reader for a topic within a subscriber or participant, with with a QoS profile:: + + % subOrDp: a Vortex.Subscriber or Vortex.DomainParticipant instance + % topic: a Vortex.Topic instance + % qosFileURI: a char array representing a file: URI + % qosProfile: a char array containing the name of a profile defined in the QoS File + reader = Vortex.Reader(subOrDp, topic, qosFileURI, qosProfile); + +Take data from a data reader:: + + % reader: a Vortex.Reader + [data, dataState] = reader.take; + % data: an array of topic class instances (e.g. ShapeType); possibly empty + % dataState: an struct array; each entry describes the + % state of the corresponding data entry + +Read data from a data reader:: + + % reader: a Vortex.Reader + [data, dataState] = reader.read; + % data: an array of topic class instances (e.g. ShapeType); possibly empty + % dataState: an struct array; each entry describes the + % state of the corresponding data entry + +Specify a wait timeout, in seconds, before read or take will return without receiving data:: + + % reader: a Vortex.Reader + reader.waitsetTimeout(2.0); + +Vortex.Query +************ + +The MATLAB ``Vortex.Query`` class represents a DDS query entity. + +A query is a data reader, restricted to accessing data that matches specific status conditions and/or a filter expression. + +A ``Vortex.Query`` class instance references an existing ``Vortex.Reader`` instance. + +**API Examples** + +Create a ``Vortex.Query`` instance or throw a ``Vortex.DDSException`` if an error occurs. + +Create a query based on a state mask only:: + + % reader: a Vortex.Reader + % only receive samples that: + % * have not been read by this application + % * AND for instances that previously seen by this application + % * AND for which there is a live writer + mask = Vortex.DataState.withNew().withNotRead().withAlive(); + query = Vortex.Query(reader, mask); + +Create a query based on a state mask and a filter expression:: + + % reader: a Vortex.Reader + mask = Vortex.DataState.withAnyState(); + filter = 'color = %0 and x > %1'; + % filter for 'RED' shapes with x > 10... + query = Vortex.Query(reader, mask, filter, {'RED', 10'}); + +Take data from a query:: + + % query: a Vortex.Query + [data, dataState] = query.take; + % data: an array of topic class instances (e.g. ShapeType); possibly empty + % dataState: an struct array; each entry describes the + % state of the corresponding data entry + +Read data from a query:: + + % query: a Vortex.Query + [data, dataState] = query.read; + % data: an array of topic class instances (e.g. ShapeType); possibly empty + % dataState: an struct array; each entry describes the + % state of the corresponding data entry + +Specify a wait timeout, in seconds, before read or take will return without receiving data:: + + % query: a Vortex.Query + + % specify the waitset timeout on the reader + query.waitsetTimeout(2.0); + + % now, read or take 'query' + +Vortex.DDSException +******************* + +The ``Vortex.DDSException`` class is thrown in the case of a DDS error arising. +The class can also be used to decode an error status code returned by methods such as ``Vortex.Writer.write``. + +**API Examples** + +Catch a DDS error while creating a DDS entity:: + + % dp: a Vortex.DomainParticipant + try + topic = Vortex.topic('Circle', ?SomeAlternateDef.ShapeType); + catch ex + switch ex.identifier + case 'Vortex:DDSError' + % it's a Vortex Error + fprintf(['DDS reports error:\n' ... + ' %s\n' ... + ' DDS ret code: %s (%d)\n'], ... + ex.message, char(ex.dds_ret_code), ex.dds_ret_code); + otherwise + rethrow ex; + end + end + +Decode a dds status code returned by ``Vortex.Writer.write``:: + + % ddsstatus: a Vortex.Writer.write return value + ex = Vortex.DDSException('', ddsstatus); + switch ex.dds_ret_code + case Vortex.DDSReturnCode.DDS_RETCODE_OK + % ... + case Vortex.DDSReturnCode.DDS_BAD_PARAMETER + % ... + case Vortex.DDSReturnCode.DDS_RETCODE_INCONSISTENT_POLICY + % ... + end + diff --git a/build/docs/DDSMATLABGuide/source/IDL-MATLAB.rst b/build/docs/DDSMATLABGuide/source/IDL-MATLAB.rst new file mode 100644 index 000000000..eba560168 --- /dev/null +++ b/build/docs/DDSMATLABGuide/source/IDL-MATLAB.rst @@ -0,0 +1,84 @@ +.. _`MATLAB Generation from IDL`: + +########################## +MATLAB Generation from IDL +########################## + +The DDS MATLAB Integration supports generation of MATLAB classes from IDL. This chapter describes the details of the IDL-MATLAB binding. + +Running IDLPP +************* + +Compiling IDL into MATLAB code is done using the ``-l matlab`` switch on idlpp:: + + idlpp -l matlab idl-file-to-compile.idl + +**Generated Artifacts** + +The following table defines the MATLAB artifacts generated from IDL concepts: + +=========== ============== =============================================== +IDL Concept MATLAB Concept Comment +=========== ============== =============================================== +module package a MATLAB package is a folder starting with '+'. +enum class a MATLAB .m file. +enum value enum value +struct class a MATLAB .m file. +field class property +typedef IDL typedef's are inlined. +union Unsupported +inheritance Unsupported +=========== ============== =============================================== + +**Datatype mappings** + +The following table shows the MATLAB equivalents to IDL primitive types: + +=========== =========== +IDL Type MATLAB Type +=========== =========== +boolean logical +char int8 +octet uint8 +short int16 +ushort uint16 +long int32 +ulong uint32 +long long int64 +ulong long uint64 +float single +double double +string char +wchar Unsupported +wstring Unsupported +any Unsupported +long double Unsupported +=========== =========== + +**Implementing Arrays and Sequences in MATLAB** + +Both IDL arrays and IDL sequences are mapped to MATLAB arrays. +MATLAB supports both native array types, which must have homogenenous contents and *cell arrays*, which may have heterogenous content. +In general, IDLPP prefers native arrays, as they support more straight forward type checking. +However, some situations require cell arrays. +The following table summarizes the cases where IDLPP will generate cell arrays: + +==================== ======================== ===================================================== +Datatype Sample Syntax Reason for using cell array +==================== ======================== ===================================================== +sequence of sequence sequence> f; Nested sequences need not have a homogeneous length +array of sequence sequence f[N]; Sequences lengths need not be homogeneous +sequence of array sequence f; A multi-dim array makes adding elements too difficult +sequence of string sequence f; Nested strings need not have a homogeneous length +string array string f[N]; Nested strings need not have a homogeneous length +==================== ======================== ===================================================== + +Limitations of MATLAB Support +***************************** + +The IDL-to-MATLAB binding has the following limitations: + +* IDL unions are not supported +* the following IDL data types are not supported: wchar, wstring, any and long double +* arrays of sequences of structures are not supported + diff --git a/build/docs/DDSMATLABGuide/source/IDLless-MATLAB.rst b/build/docs/DDSMATLABGuide/source/IDLless-MATLAB.rst new file mode 100644 index 000000000..84b810ad6 --- /dev/null +++ b/build/docs/DDSMATLABGuide/source/IDLless-MATLAB.rst @@ -0,0 +1,105 @@ +.. _`MATLAB without IDL`: + +################## +MATLAB without IDL +################## + +It is possible, but not recommended, to directly create MATLAB classes that represent DDS topics. +This approach allows you to quickly start using Vortex DDS, but it has a number of disadvantages: + +* without IDL, you cannot reliably define the topic in other language bindings. +* not all IDL types are available. + +Creating a MATLAB Topic class +***************************** + +To create a Topic Class without IDL, create a MATLAB class that inherits from Vortex.AbstractType. +The class will be interpreted as an IDL struct. +Class properties will be interpreted as IDL struct fields. +Finally, the class must define a static method `getKey` which returns a comma separated list of key +fields for the topic. + +The following shows a simple MATLAB class, ShapeType:: + + classdef ShapeType < Vortex.AbstractType + properties + color char % IDL: string color; + x int32 % IDL: long x; + y int32 % IDL: long y; + shapesize int32 % IDL: long shapesize; + end + + methods (Static) + function keys = getKey + keys = 'color'; + end + end + end + +The topic class defines four fields, and identifies the ``color`` field as the topic key. + +You would use the topic class in the same way as one generated by IDLPP. The following example +shows the creation of a DDS topic object from a topic class:: + + % define a Vortex DDS topic called 'Circle' + circleTopic = Vortex.Topic('Circle', ?ShapeType); + +With the `circleTopic` variable, you can then create appropriate Vortex DDS readers and writers. + +Mapping of MATLAB types to IDL types +************************************ + +When using an IDL-less Topic class, the Vortex DDS API for MATLAB makes maps property types +to IDL types as follows: + +=========== ===================== +MATLAB Type IDL Type +=========== ===================== +logical boolean +int8 char +uint8 octet +int16 short +uint16 unsigned short +int32 long +uint32 unsigned long +int64 long long +uint64 unsigned long long +single float +double double +char string +class equivalent IDL struct +enum class equivalent IDL enum +not type double +=========== ===================== + +Creating arrays +*************** + +When defining a topic class, you can make a field map to an IDL array by initializing it to an array of the appropriate dimensions. +The MATLAB API for Vortex DDS recognizes arrays of most types as identifying IDL arrays. +The one exception is that arrays of MATLAB ``char`` are still interpreted as an IDL string. + +The following example shows an topic class that defines arrays:: + + classdef ArrayTopic < Vortex.AbstractType + properties + x = zeros([1 4]) %IDL: double x[4]; + y int32 = zeros([3 4]) %IDL: long y[3][4]; + end + methods (Static) + function keys = getKey + keys = ''; %No Key + end + end + end + +Unsupported Types +***************** + +When creating topics with out IDL, you must accept the following restrictions: + +* IDL sequences cannot be defined. +* arrays of IDL strings cannot be defined. +* bounded IDL strings cannot be defined. + + diff --git a/build/docs/DDSMATLABGuide/source/conf.py b/build/docs/DDSMATLABGuide/source/conf.py new file mode 100644 index 000000000..4d9734d49 --- /dev/null +++ b/build/docs/DDSMATLABGuide/source/conf.py @@ -0,0 +1,282 @@ +# -*- coding: utf-8 -*- +# +# OpenSplice_Deployment_Guide build configuration file, created by +# ReST Editor on 06-Jul-2015 +# +# This file is execfile()d with the current directory set to its containing dir. +# +# Note that not all possible configuration values are present in this +# autogenerated file. +# +# All configuration values have a default; values that are commented out +# serve to show the default. + +import sys, os +import time + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +#sys.path.insert(0, os.path.abspath('.')) + +# -- General configuration ----------------------------------------------------- + +# If your documentation needs a minimal Sphinx version, state it here. +#needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be extensions +# coming with Sphinx (named 'sphinx.ext.*') or your custom ones. +#extensions = ['sphinx.ext.todo'] + +extensions = ['sphinx.ext.todo', 'sphinx.ext.ifconfig'] + +def setup(app): + app.add_config_value('rmi_languages', '', True) + +#rmi_languages = 'C++ and Java' +rmi_languages = 'C++' +#rmi_languages = 'Java' +rst_prolog = """ +.. |rmi_langs| replace:: C++ +.. |product_name| replace:: OpenSplice +""" + +#.. |rmi_langs| replace:: C++ and Java + + + +# Add any paths that contain templates here, relative to this directory. +templates_path = [u'_templates'] + + +# The suffix of source filenames. +source_suffix = '.rst' + +# The encoding of source files. +source_encoding = u'utf-8-sig' + + +# The master toctree document. +master_doc = u'index' + + +# General information about the project. +project = u'Vortex OpenSplice MATLAB Guide' + +this_year = time.strftime( '%Y' ) +copyright = u'{y}, ADLINK Technology Limited'.format( y = this_year ) +print 'Copyright string is:', copyright + + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# +# The short X.Y version. +version = u'6.x' + +# The full version, including alpha/beta/rc tags. +release = version +#release = u'.0' +print 'Short version string is:', version +print 'Full version string is:', release + + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +language = u'en' + + +# There are two options for replacing |today|: either, you set today to some +# non-false value, then it is used: +today = ' ' +# Else, today_fmt is used as the format for a strftime call. +#today_fmt = '%B %d, %Y' + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +exclude_patterns = [] + +# The reST default role (used for this markup: `text`) to use for all documents. +#default_role = None + +# If true, '()' will be appended to :func: etc. cross-reference text. +#add_function_parentheses = True + +# If true, the current module name will be prepended to all description +# unit titles (such as .. function::). +#add_module_names = True + +# If true, sectionauthor and moduleauthor directives will be shown in the +# output. They are ignored by default. +#show_authors = False + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + +# A list of ignored prefixes for module index sorting. +#modindex_common_prefix = [] + + +# -- Options for HTML output --------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# html_theme = u'sphinxdoc' +html_theme = u'vortextheme' +# LINUX PATH: +html_theme_path = ['../../.'] +# WINDOWS PATH: +# html_theme_path = ['..\..\.'] +#build theme directory in lite using environment variable, so shared amongst books +# insight team can delete, +#html_theme_path = [os.environ['VL_HOME'] + '/build/docs'] + + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +#html_theme_options = {} + +# Add any paths that contain custom themes here, relative to this directory. +#html_theme_path = [] + +# The name for this set of Sphinx documents. If None, it defaults to +# " v documentation". +#html_title = None +html_title = 'The Vortex OpenSplice MATLAB Guide' + +# A shorter title for the navigation bar. Default is the same as html_title. +#html_short_title = None +#html_short_title = 'HTML short Title conf.py' +html_short_title = 'OpenSplice MATLAB Guide' + +# The name of an image file (relative to this directory) to place at the top +# of the sidebar. +html_logo = './images/Vortex_logo_2014.png' + +# The name of an image file (within the static path) to use as favicon of the +# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 +# pixels large. +#html_favicon = None + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = [u'_static'] + + +# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, +# using the given strftime format. +#html_last_updated_fmt = '%b %d, %Y' + +# If true, SmartyPants will be used to convert quotes and dashes to +# typographically correct entities. +#html_use_smartypants = True + +# Custom sidebar templates, maps document names to template names. +#html_sidebars = {} + +# Additional templates that should be rendered to pages, maps page names to +# template names. +#html_additional_pages = {} + +# If false, no module index is generated. +#html_domain_indices = True + +# If false, no index is generated. +#html_use_index = True + +# If true, the index is split into individual pages for each letter. +#html_split_index = False + +# If true, links to the reST sources are added to the pages. +#html_show_sourcelink = True + +# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. +#html_show_sphinx = True +html_show_sphinx = False + +# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. +#html_show_copyright = True + +# If true, an OpenSearch description file will be output, and all pages will +# contain a tag referring to it. The value of this option must be the +# base URL from which the finished HTML is served. +#html_use_opensearch = '' + +# This is the file name suffix for HTML files (e.g. ".xhtml"). +#html_file_suffix = None + +# Output file base name for HTML help builder. +htmlhelp_basename = 'The Vortex OpenSplice MATLAB Guide' + + +# -- Options for LaTeX output -------------------------------------------------- + +# The paper size ('letter' or 'a4'). +latex_paper_size = u'a4' + + +# The font size ('10pt', '11pt' or '12pt'). +latex_font_size = u'10pt' + + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, author, documentclass [howto/manual]). +latex_documents = [('index', 'OpenSplice_DDSMATLABGuide.tex', u'DDS MATLAB Guide', u'', 'manual', True)] +# Note 'author' field empty +# Added 'True' to end of generated line to suppress 'Index & Tables' + + +# A dictionary that contains LaTeX snippets that override those Sphinx usually +# puts into the generated .tex files. +latex_elements = { 'babel': '\\usepackage[english]{babel}' } + + +# The name of an image file (relative to this directory) to place at the top of +# the title page. +latex_logo = './images/Vortex-Cover.png' + +# For "manual" documents, if this is true, then toplevel headings are parts, +# not chapters. +latex_use_parts = False + + +# If true, show page references after internal links. +#latex_show_pagerefs = False + +# If true, show URL addresses after external links. +#latex_show_urls = False + +# Additional stuff for the LaTeX preamble. +latex_preamble = r""" +\setcounter {tocdepth} {5} +\setcounter{secnumdepth}{5} + +""" + +# * THIS GETS RID OF BLANK PAGES AT ENDS OF CHAPTERS & ToC +latex_elements = { + 'classoptions': ',openany, oneside', + 'babel': '\\usepackage[english]{babel}' +} + + +# Documents to append as an appendix to all manuals. +#latex_appendices = [] + +# If false, no module index is generated. +#latex_domain_indices = True + + +# -- Options for manual page output -------------------------------------------- + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [('index', 'OpenSplice_DDSMATLABGuide', u'OpenSplice_DDSMATLAB Documentation', [u'ADLINK Technology Limited'], 1)] + + +# -- Additional options -------------------------------------------------------- + +todo_include_todos = True diff --git a/build/docs/DDSMATLABGuide/source/contacts.rst b/build/docs/DDSMATLABGuide/source/contacts.rst new file mode 100644 index 000000000..d32f6016f --- /dev/null +++ b/build/docs/DDSMATLABGuide/source/contacts.rst @@ -0,0 +1 @@ +.. include:: ../../common/contacts.rst diff --git a/build/docs/DDSMATLABGuide/source/example-ping-pong.rst b/build/docs/DDSMATLABGuide/source/example-ping-pong.rst new file mode 100644 index 000000000..53dc1de79 --- /dev/null +++ b/build/docs/DDSMATLABGuide/source/example-ping-pong.rst @@ -0,0 +1,81 @@ +.. _`Ping Pong Example`: + +################# +Ping Pong Example +################# + +A simple ping pong example is provided to demonstrate the basic capabilities of the MATLAB DDS integration. + +The ping pong example can be found in the following directory: + + `OSPL_HOME`/tools/matlab/examples/matlab/pingpong + +The ping pong example creates two participants. + +1. A pinger that writes to the PING partition and reads from the PONG partition. +2. A ponger that writes to the PONG partition and reads from the PING partition. + +A matlab script is provided that writes and reads sample data in the pinger and ponger participants. + +Example Files +************* + +Files with the .m extension are MATLAB script files. + +An explanation of what each example file does is provided below. + +**pingpong.idl** + +- Defines the PingPongType in idl +- Used to generate the MATLAB file PingPongType.m via:: +idlpp -l matlab pingpong.idl + +**PingPongType.m** + +- Defines a PingPongType; generated from idlpp +- The PingPongType represents a DDS topic type. +- PingPongType specifies two properties: id, count. + +**DDS_PingerVolatileQoS.xml** + +- XML file that specifies the DDS QoS (quality of service) settings for pinger. + +**DDS_PongerVolatileQoS.xml** + +- XML file that specifies the DDS QoS (quality of service) settings for ponger. + +**setup_pinger.m** + +- Creates the pinger participant on the default DDS domain, with specified QoS profile. +- Creates the topic PingPongType. +- Creates the publisher using the domain participant on the PING partition specified in the specified QoS profile. +- Creates the writer using the publisher and the specified QoS profile. +- Creates the subscriber using the domain participant on the PONG partition specified in the QoS profile. +- Creates the reader using the subscriber and the specified QoS profile. + +**setup_ponger.m** + +- Creates the ponger participant on default domain with specified QoS profile. +- Creates the topic PingPongType. +- Creates the publisher using the domain participant on the PONG partition specified in the QoS profile. +- Creates the writer using the publisher and the specified QoS profile. +- Creates the subscriber using the domain participant on the PING partition specified in the QoS profile. +- Creates the reader using the subscriber and the specified QoS profile. + +**pinger_ponger.m** + +- MATLAB script that writes and reads sample data in the pinger and ponger participants. +- This script calls the setup_pinger.m and setup_ponger.m scripts. +- This is the main script to run the ping pong example. +- This script is run from the MATLAB Command Window. + + +Steps to run example +******************** + +1. In the MATLAB command window, run pinger_ponger.m. + - Type "pinger_ponger". + - Hit enter. + + + diff --git a/build/docs/DDSMATLABGuide/source/images/Vortex-Cover.png b/build/docs/DDSMATLABGuide/source/images/Vortex-Cover.png new file mode 100644 index 000000000..d82d6b313 Binary files /dev/null and b/build/docs/DDSMATLABGuide/source/images/Vortex-Cover.png differ diff --git a/build/docs/DDSMATLABGuide/source/images/Vortex_logo_2014.png b/build/docs/DDSMATLABGuide/source/images/Vortex_logo_2014.png new file mode 100644 index 000000000..e7de4f525 Binary files /dev/null and b/build/docs/DDSMATLABGuide/source/images/Vortex_logo_2014.png differ diff --git a/build/docs/DDSMATLABGuide/source/images/dds_overview.png b/build/docs/DDSMATLABGuide/source/images/dds_overview.png new file mode 100755 index 000000000..c7490ddb4 Binary files /dev/null and b/build/docs/DDSMATLABGuide/source/images/dds_overview.png differ diff --git a/build/docs/DDSMATLABGuide/source/images/linuxInstall1.png b/build/docs/DDSMATLABGuide/source/images/linuxInstall1.png new file mode 100644 index 000000000..11a145754 Binary files /dev/null and b/build/docs/DDSMATLABGuide/source/images/linuxInstall1.png differ diff --git a/build/docs/DDSMATLABGuide/source/index.rst b/build/docs/DDSMATLABGuide/source/index.rst new file mode 100644 index 000000000..c0cdec51d --- /dev/null +++ b/build/docs/DDSMATLABGuide/source/index.rst @@ -0,0 +1,27 @@ +.. The Vortex OpenSplice MATLAB Guide + +.. Doc Issue 01, 28 February 2017 + +################ +DDS MATLAB Guide +################ + +.. toctree:: + :maxdepth: 6 + :numbered: + + introduction + installation + DDS-Classes + IDL-MATLAB + IDLless-MATLAB + qos_provider + example-ping-pong + + contacts + + +Indices and tables +================== + +* :ref:`search` diff --git a/build/docs/DDSMATLABGuide/source/installation.rst b/build/docs/DDSMATLABGuide/source/installation.rst new file mode 100644 index 000000000..35e39736e --- /dev/null +++ b/build/docs/DDSMATLABGuide/source/installation.rst @@ -0,0 +1,83 @@ +.. _`Installation`: + +############ +Installation +############ + +This section describes the procedure to install the Vortex DDS MATLAB Integration on a Linux or Windows platform. + +System Requirements +******************* + +- Operating System: Windows or Linux +- MATLAB installed +- Java 1.7 or greater + +OpenSplice (OSPL) and DDS MATLAB Installation +********************************************* + +Steps: + +1. Install OSPL. The DDS MATLAB Integration is included in this installer. + + +2. Setup OSPL license. Copy the license.lic file into the appropriate license directory. + + */INSTALLDIR/Vortex_v2/license* + +3. DDS MATLAB files are contained in a tools/matlab folder + + Example: + */INSTALLDIR/Vortex_v2/Device/VortexOpenSplice/6.8.1/HDE/x86_64.linux/tools/matlab* + +MATLAB and DDS Setup +******************** + +Steps: + +1. Open command shell and run script to setup environment variables. + + **Linux** + + - Open a Linux terminal. + + - Navigate to directory containing release.com file. + + */INSTALLDIR/Vortex_v2/Device/VortexOpenSplice/6.8.1/HDE/x86_64.linux* + + - Run release.com. (Type in “. release.com†at command line.) + + + **Windows** + + - Open a command prompt. + + - Navigate to directory containing release.bat file. + + *INSTALLDIR/Vortex_v2/Device/VortexOpenSplice/6.8.1/HDE/x86_64.win64* + + - Run release.bat. (Type in “release.bat†at command line.) + + +2. Start MATLAB using the **SAME** command shell used in Step 1. + + *NOTE: If MATLAB is NOT started from a command shell with the correct OSPL environment variables set, exceptions will occur when attempting to use DDS MATLAB classes.* + +3. In MATLAB, navigate to file “Vortex_DDS_MATLAB_API.mltbx†by typing:: + + cd(fullfile(getenv('OSPL_HOME'),'tools','matlab')) + +4. Double click on the file “Vortex_DDS_MATLAB_API.mltbxâ€. This will bring up a dialog entitled **Vortex_DDS_MATLAB_API**. + Select **Install**. + +.. figure:: images/linuxInstall1.png + :alt: DDS + +Examples +******** + +Example models have been provided in the examples folder. + +Example: +*/INSTALLDIR/Vortex_v2/Device/VortexOpenSplice/6.8.1/HDE/x86_64.linux/tools/matlab/examples/matlab* + diff --git a/build/docs/DDSMATLABGuide/source/introduction.rst b/build/docs/DDSMATLABGuide/source/introduction.rst new file mode 100644 index 000000000..984031ff1 --- /dev/null +++ b/build/docs/DDSMATLABGuide/source/introduction.rst @@ -0,0 +1,51 @@ +.. _`Introduction`: + + +############ +Introduction +############ + +The DDS MATLAB Integration provides users with DDS MATLAB classes to model DDS communication using MATLAB and pure DDS applications. + +Please refer to the DDS and MATLAB documentation for detailed information. + +DDS +*** + +**What is DDS?** + +“The Data Distribution Service (DDSâ„¢) is a middleware protocol and API standard for data-centric connectivity from the Object Management Group® (OMG®). It integrates the components of a system together, providing low-latency data connectivity, extreme reliability, and a scalable architecture that business and mission-critical Internet of Things (IoT) applications need.†+ +“The main goal of DDS is to share the right data at the right place at the right time, even between time-decoupled publishers and consumers. DDS implements global data space by carefully replicating relevant portions of the logically shared dataspace.†DDS specification + +.. figure:: images/dds_overview.png + :alt: DDS + +**Further Documentation** + +http://portals.omg.org/dds/ + +http://ist.adlinktech.com/ + +MATLAB +****** + +**What is MATLAB?** + +"The Language of Technical Computing + +Millions of engineers and scientists worldwide use MATLAB® to analyze and design the systems and products transforming our world. MATLAB is in automobile active safety systems, interplanetary spacecraft, health monitoring devices, smart power grids, and LTE cellular networks. It is used for machine learning, signal processing, image processing, computer vision, communications, computational finance, control design, robotics, and much more. + +Math. Graphics. Programming. + +The MATLAB platform is optimized for solving engineering and scientific problems. The matrix-based MATLAB language is the world’s most natural way to express computational mathematics. Built-in graphics make it easy to visualize and gain insights from data. A vast library of prebuilt toolboxes lets you get started right away with algorithms essential to your domain. The desktop environment invites experimentation, exploration, and discovery. These MATLAB tools and capabilities are all rigorously tested and designed to work together. + +Scale. Integrate. Deploy. + +MATLAB helps you take your ideas beyond the desktop. You can run your analyses on larger data sets and scale up to clusters and clouds. MATLAB code can be integrated with other languages, enabling you to deploy algorithms and applications within web, enterprise, and production systems." + +https://www.mathworks.com/products/matlab.html + + + + diff --git a/build/docs/DDSMATLABGuide/source/qos_provider.rst b/build/docs/DDSMATLABGuide/source/qos_provider.rst new file mode 100644 index 000000000..2f0985e20 --- /dev/null +++ b/build/docs/DDSMATLABGuide/source/qos_provider.rst @@ -0,0 +1,92 @@ +.. _`QoS Provider`: + + +############ +QoS Provider +############ + +The following section explains how the QoS is set for a DDS entity using the QoS Provider. + + +QoS Provider File +***************** + +Quality of Service for DDS entities is set using XML files based on the XML schema file QoSProfile.xsd_. +These XML files contain one or more QoS profiles for DDS entities. An example with a default QoS profile +for all entity types can be found at DDS_DefaultQoS.xml_. + +**Note:** Sample QoS Profile XML files can be found in the examples directories. + +QoS Profile +*********** + +A QoS profile consists of a name and optionally a base_name attribute. The base_name attribute allows a +QoS or a profile to inherit values from another QoS or profile in the same file. The file contains QoS +elements for one or more DDS entities. A skeleton file without any QoS values is displayed below to show +the structure of the file. + +.. code-block:: xml + + + + + + + + + + + + +**Example: Specify Publisher Partition** + +The example below specifies the publisher's partitions as A and B. + +.. code-block:: xml + + + + + A + B + + + + + +Setting QoS Profile in MATLAB +***************************** +To set the QoS profile for a DDS entity in MATLAB the user must specify the File URI and the QoS profile name. +If the file is not specified, the DDS entity will be created with the default QoS values. + +.. code-block:: matlab + + % QOS File + PINGER_QOS_FILE = '/home/dds/matlab_examples/pingpong/DDS_PingerVolatileQoS.xml'; + PINGER_QOS_PROFILE = 'DDS VolatileQosProfile'; + + % create the pinger participant on default domain with specified qos profile + dp = Vortex.DomainParticipant(['file://', PINGER_QOS_FILE], PINGER_QOS_PROFILE); + +The file for the above would minimally contain the following tag. + +.. code-block:: xml + + + + + + + + + + true + + + + + + +.. external links +.. _QoSProfile.xsd: http://www.omg.org/spec/dds4ccm/20110201/DDS_QoSProfile.xsd +.. _DDS_DefaultQoS.xml: http://www.omg.org/spec/dds4ccm/20110201/DDS_DefaultQoS.xml diff --git a/build/docs/DDSSimulinkGuide/Makefile b/build/docs/DDSSimulinkGuide/Makefile new file mode 100644 index 000000000..fe415b065 --- /dev/null +++ b/build/docs/DDSSimulinkGuide/Makefile @@ -0,0 +1,130 @@ +# Makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = sphinx-build +PAPER = +BUILDDIR = build + +# Internal variables. +PAPEROPT_a4 = -D latex_paper_size=a4 +PAPEROPT_letter = -D latex_paper_size=letter +ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source + +.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest + +help: + @echo "Please use \`make ' where is one of" + @echo " html to make standalone HTML files" + @echo " dirhtml to make HTML files named index.html in directories" + @echo " singlehtml to make a single large HTML file" + @echo " pickle to make pickle files" + @echo " json to make JSON files" + @echo " htmlhelp to make HTML files and a HTML help project" + @echo " qthelp to make HTML files and a qthelp project" + @echo " devhelp to make HTML files and a Devhelp project" + @echo " epub to make an epub" + @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" + @echo " latexpdf to make LaTeX files and run them through pdflatex" + @echo " text to make text files" + @echo " man to make manual pages" + @echo " changes to make an overview of all changed/added/deprecated items" + @echo " linkcheck to check all external links for integrity" + @echo " doctest to run all doctests embedded in the documentation (if enabled)" + +clean: + -rm -rf $(BUILDDIR)/* + +html: + $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." + +dirhtml: + $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." + +singlehtml: + $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml + @echo + @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." + +pickle: + $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle + @echo + @echo "Build finished; now you can process the pickle files." + +json: + $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json + @echo + @echo "Build finished; now you can process the JSON files." + +htmlhelp: + $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp + @echo + @echo "Build finished; now you can run HTML Help Workshop with the" \ + ".hhp project file in $(BUILDDIR)/htmlhelp." + +qthelp: + $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp + @echo + @echo "Build finished; now you can run "qcollectiongenerator" with the" \ + ".qhcp project file in $(BUILDDIR)/qthelp, like this:" + @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/OpenSplice_Getting_Started_Guide.qhcp" + @echo "To view the help file:" + @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/OpenSplice_Getting_Started_Guide.qhc" + +devhelp: + $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp + @echo + @echo "Build finished." + @echo "To view the help file:" + @echo "# mkdir -p $$HOME/.local/share/devhelp/OpenSplice_Getting_Started_Guide" + @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/OpenSplice_Getting_Started_Guide" + @echo "# devhelp" + +epub: + $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub + @echo + @echo "Build finished. The epub file is in $(BUILDDIR)/epub." + +latex: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo + @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." + @echo "Run \`make' in that directory to run these through (pdf)latex" \ + "(use \`make latexpdf' here to do that automatically)." + +latexpdf: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo "Running LaTeX files through latexpdf..." + make -C $(BUILDDIR)/latex all-pdf + @echo "latexpdf finished; the PDF files are in $(BUILDDIR)/latexpdf." + +text: + $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text + @echo + @echo "Build finished. The text files are in $(BUILDDIR)/text." + +man: + $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man + @echo + @echo "Build finished. The manual pages are in $(BUILDDIR)/man." + +changes: + $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes + @echo + @echo "The overview file is in $(BUILDDIR)/changes." + +linkcheck: + $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck + @echo + @echo "Link check complete; look for any errors in the above output " \ + "or in $(BUILDDIR)/linkcheck/output.txt." + +doctest: + $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest + @echo "Testing of doctests in the sources finished, look at the " \ + "results in $(BUILDDIR)/doctest/output.txt." diff --git a/build/docs/DDSSimulinkGuide/make.bat b/build/docs/DDSSimulinkGuide/make.bat new file mode 100644 index 000000000..fff4f8663 --- /dev/null +++ b/build/docs/DDSSimulinkGuide/make.bat @@ -0,0 +1,183 @@ +@ECHO OFF + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set BUILDDIR=build +set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% source +if NOT "%PAPER%" == "" ( + set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS% +) + +if "%1" == "" goto help + +if "%1" == "help" ( + :help + echo.Please use `make ^` where ^ is one of + echo. html to make standalone HTML files + echo. dirhtml to make HTML files named index.html in directories + echo. singlehtml to make a single large HTML file + echo. pickle to make pickle files + echo. json to make JSON files + echo. htmlhelp to make HTML files and a HTML help project + echo. qthelp to make HTML files and a qthelp project + echo. devhelp to make HTML files and a Devhelp project + echo. epub to make an epub + echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter + echo. text to make text files + echo. man to make manual pages + echo. changes to make an overview over all changed/added/deprecated items + echo. linkcheck to check all external links for integrity + echo. doctest to run all doctests embedded in the documentation if enabled + goto end +) + +if "%1" == "clean" ( + for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i + del /q /s %BUILDDIR%\* + goto end +) + +if "%1" == "html" ( + %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The HTML pages are in %BUILDDIR%/html. + goto end +) + +if "%1" == "dirhtml" ( + %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml. + goto end +) + +if "%1" == "singlehtml" ( + %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml. + goto end +) + +if "%1" == "pickle" ( + %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can process the pickle files. + goto end +) + +if "%1" == "json" ( + %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can process the JSON files. + goto end +) + +if "%1" == "htmlhelp" ( + %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can run HTML Help Workshop with the ^ +.hhp project file in %BUILDDIR%/htmlhelp. + goto end +) + +if "%1" == "qthelp" ( + %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can run "qcollectiongenerator" with the ^ +.qhcp project file in %BUILDDIR%/qthelp, like this: + echo.^> qcollectiongenerator %BUILDDIR%\qthelp\OpenSplice_Getting_Started_Guide.qhcp + echo.To view the help file: + echo.^> assistant -collectionFile %BUILDDIR%\qthelp\OpenSplice_Getting_Started_Guide.ghc + goto end +) + +if "%1" == "devhelp" ( + %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. + goto end +) + +if "%1" == "epub" ( + %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The epub file is in %BUILDDIR%/epub. + goto end +) + +if "%1" == "latex" ( + %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; the LaTeX files are in %BUILDDIR%/latex. + goto end +) + +if "%1" == "latexpdf" ( + %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latexpdf + echo %BUILDDIR%/latexpdf +REM Typical path: "c:\Program Files (x86)\GnuWin32\bin\make.exe" -C %BUILDDIR%\latexpdf all-pdf +REM Actual path on this system: C:\apps\GnuWin32\bin\make.exe -C %BUILDDIR%\latexpdf all-pdf + C:\apps\GnuWin32\bin\make.exe -C %BUILDDIR%\latexpdf all-pdf + echo.Build done + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; the LaTeX files are in %BUILDDIR%/latexpdf. + goto end +) + +if "%1" == "text" ( + %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The text files are in %BUILDDIR%/text. + goto end +) + +if "%1" == "man" ( + %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The manual pages are in %BUILDDIR%/man. + goto end +) + +if "%1" == "changes" ( + %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes + if errorlevel 1 exit /b 1 + echo. + echo.The overview file is in %BUILDDIR%/changes. + goto end +) + +if "%1" == "linkcheck" ( + %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck + if errorlevel 1 exit /b 1 + echo. + echo.Link check complete; look for any errors in the above output ^ +or in %BUILDDIR%/linkcheck/output.txt. + goto end +) + +if "%1" == "doctest" ( + %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest + if errorlevel 1 exit /b 1 + echo. + echo.Testing of doctests in the sources finished, look at the ^ +results in %BUILDDIR%/doctest/output.txt. + goto end +) + +:end diff --git a/build/docs/DDSSimulinkGuide/source/blocks.rst b/build/docs/DDSSimulinkGuide/source/blocks.rst new file mode 100644 index 000000000..2ef6a6c7d --- /dev/null +++ b/build/docs/DDSSimulinkGuide/source/blocks.rst @@ -0,0 +1,89 @@ +.. _`Vortex DDS Blocks`: + + +################# +Vortex DDS Blocks +################# + + +The DDS Simulink Integration provides a block library with custom blocks to model reading and writing data with DDS. + +The Vortex DDS Simulink block library provides blocks which correspond to DDS entities. (Each DDS block is covered in its own section in this user guide.) + +The following DDS block types are provided: + + - Topic + - Domain + - Publisher + - Subscriber + - Writer + - Reader + +Optional DDS Blocks and Ports +***************************** + +Some of the DDS blocks are optional. (Domain, Publisher and Subscriber) + +When the optional blocks are not added to model diagrams, defaults are used. This allows for simpler model diagrams. +If the model requires block parameter customization, the optional blocks can be added to a model to use non-default settings. + +Many of the ports for the DDS blocks are also optional. They can be toggled on or off in the **Block Parameters** dialog, in the **Ports** tab. + +QoS Profiles +************ + +In DDS - “The Data-Distribution Service (DDS) relies on the usage of QoS. A QoS (Quality of Service) is a set of characteristics that controls some aspect of the behavior of the DDS Service." + +Each DDS block has an associated QoS profile. By default, the OSPL default profile is used. An XML file that specifies QoS profiles can be used to set the QoS of a DDS block. + +The QoS profile of a block is set in the **QoS** tab of the **Block Parameters** dialog. (This dialog is opened by double clicking on a selected block.) + + +Please see section :ref:`QoS Provider` for more information. + +.. raw:: latex + + \newpage + +Simulink Block Sample Time +************************** + +**"What is sample time?"** + +**"The sample time of a block is a parameter that indicates when, during simulation, the block produces outputs and if appropriate, updates its internal state." +-Simulink documentation** + + + +The DDS blocks have different sample times set. The only DDS block that allows for the user specification of a sample time is the **Reader** block. +A reader's sample time can be set in the **Block Parameters** **Data** tab. + +A sample time of 0 means that the block step will only execute once. + +A sample time of -1 means that the block will inherit its sample time from its inputs or from the parent model. + + ++---------------------+--------------------------------------+ +|DDS Block Type |Sample Time | ++=====================+======================================+ +|Topic | -1 (inherits) uneditable | ++---------------------+--------------------------------------+ +|Domain | -1 (inherits) uneditable | ++---------------------+--------------------------------------+ +|Publisher | -1 (inherits) uneditable | ++---------------------+--------------------------------------+ +|Subscriber | -1 (inherits) uneditable | ++---------------------+--------------------------------------+ +|Writer | -1 (inherits) uneditable | ++---------------------+--------------------------------------+ +|Reader | - default -1 (inherits) editable | +| | - Inherits from inputs or model | +| | - Valid values: -1 and Numeric > 0 | ++---------------------+--------------------------------------+ + + + + + + + diff --git a/build/docs/DDSSimulinkGuide/source/bus-dds.rst b/build/docs/DDSSimulinkGuide/source/bus-dds.rst new file mode 100644 index 000000000..e9de907fa --- /dev/null +++ b/build/docs/DDSSimulinkGuide/source/bus-dds.rst @@ -0,0 +1,258 @@ +.. _`Simulink Bus to DDS Topic Mapping`: + + +################################# +Simulink Bus to DDS Topic Mapping +################################# + +Simulink data is represented in buses whose types are not compatible with DDS topic data types. + +When using the Simulink Vortex DDS library, the user must create Simulink buses that will be mapped to DDS topic types. + +The Vortex DDS **Reader**, **Writer** and **Topic** blocks have block parameters that require a Simulink bus type. On data writes, the Simulink bus types are converted to DDS topic types and on data reads, the DDS topic types are converted to Simulink bus types. + +The user can generate/create the Simulink bus definitions by either generating them from an IDL file, or by using the Simulink bus editor. + + +Generate Simulink bus definitions from an IDL file +************************************************** + +DDS Topic Types can be described in an IDL file. The public Vortex.idlImportSl function can be called to generate Simulink bus definitions from an IDL file. + +**idlImportSl(IDLFILENAME,DICTIONARYFILE)** + + Given an IDLFILENAME, invokes the idlpp tool to generate a MATLAB script. + This script is then used to create Simulink.Bus objects and import them into the specified data dictionary DICTIONARYFILE. + The values are inserted into the 'Design Data' section of the data dictionary. + If the target data dictionary already contains definitions for the bus or enum names, they are overwritten. + If idlpp returns non-zero, the function returns immediately with the error code. + + Input Arguments: + + IDLFILENAME A character array with the value of the IDL file name to process. + + DICTIONARYFILE A character array with the value of the data dictionary file name. + + +**Steps:** + +1. In the IDL file, ensure that any topic structures have the OSPL specific annotation *pragma keylist* defined. + + If you want a given IDL structure to serve as the topic type, the structure requires an OSPL specific annotation. + The #pragma keylist * declaration should be defined after the structure declaration. + + IMPORTANT NOTE: The IDL file has to have a blank line after the pragma keylist declaration. (BUG) + + More information can be found at: IDLPreProcGuide_ + +2. In MATLAB, navigate to the directory that contains the IDL file. Set this directory to be the MATLAB **Current Folder**. + +3. Call the idlImportSl function in the MATLAB command window. + + Example: + >> Vortex.idlImportSl('ShapeType.idl', 'shape.sldd') + + +Overriding default values for Vortex.idlImportSl +************************************************ + +The ``Vortex.idlImportSl`` function makes a number assumptions when generating a Simulink data dictionary +from your IDL file. These are documented in the following table: + ++-------------------------+---------------------------------+ +| **IDL Element** | **Default Simulink Equivalent** | ++=========================+=================================+ +| struct name | Unqualified bus name | ++-------------------------+---------------------------------+ +| enum name | Unqualified enum name | ++-------------------------+---------------------------------+ +| sequence<*T*, *N*> name | *seqN_T* | ++-------------------------+---------------------------------+ +| sequence<*T*> name | *seq_T* | ++-------------------------+---------------------------------+ +| unbounded string | maximum 256 characters | ++-------------------------+---------------------------------+ +| unbounded sequence | maximum 16 elements | ++-------------------------+---------------------------------+ + +The following subsections illustrate how to override each of these defaults. + +Overriding struct and enum names +++++++++++++++++++++++++++++++++ + +IDL allows you to describe a hierarchical set of namespaces for structs and enums by defining modules. +Simulink, however, has a flat namespace for all busses and enumerations. +This can present problems when the same unqualified struct name is used to two or more different modules. + +Consider the following idl:: + + module A { + enum Status { + INFO, + WARNING, + ERROR + }; + struct Message { + long id; + Status status; + }; + #pragma keylist Message id + }; + + module B { + enum Status { + SUCCESS, + FAILURE + }; + struct Message { + long id; + Status status; + }; + #pragma keylist Message id + }; + +In it, both ``Status`` and ``Message`` are used in the context of both module A and module B. When you run ``Vortex.idlImportSl`` against it, +you will receive the following messages:: + + Error: IDL element B::Status translates to the Simulink artifact named Status, + which already corresponds to another IDL element A::Status. + Edit the idl_defaults.properties file to assign unique Simulink names to each IDL element. + + Error: IDL element B::Message translates to the Simulink artifact named Message, + which already corresponds to another IDL element A::Message. + Edit the idl_defaults.properties file to assign unique Simulink names to each IDL element. + +To help you solve the problem, the IDL import function generates a *properties file* with the same name as the original IDL file, but with a *properties* extension. +Here is the generated properties file:: + + # + # + # To change the generated Simulink element, change one or more values in this file, and then + # re-run the IDL import. + + A::Message#name = Message + A::Status#name = Status + B::Message#name = Message + B::Status#name = Status + +The properties file shows the names the IDL import attempted to used. Each line is of the format:: + + #name = + +You can modify any value after the equals sign (=), to create a unique name. Once you have finished +editing the properties file, re-run the IDL import to update actual Simulink entities. + +Suppose we make the following changes to the properties file:: + + A::Message#name = MessageA + A::Status#name = StatusA + B::Message#name = Message + B::Status#name = Status + +On re-running ``Vortex.idlImportSl``, the generated Simulink data dictionary would have contents as seen in the figure below. + +.. figure:: images/linuxIDLPP_SLDD_ChangedNames.png + :alt: DDS + + *View of generated Simulink Data Dictionary, showing renamed busses and enumerations*. + +Changing unbound string maximum sizes ++++++++++++++++++++++++++++++++++++++ + +Although IDL unbound strings can be of any length, in Simulink they are mapped to fixed length arrays of int8. +The default length the ``Vortex.idlImportSl`` assigns to such arrays is 256 characters. +You can change this default value, per string, using the generated properties file. + +Suppose we modify A::Message to contain a string field:: + + module A { + enum Status { + INFO, + WARNING, + ERROR + }; + struct Message { + long id; + Status status; + string body; + }; + #pragma keylist Message id + }; + +On running the IDL import, the properties file would be updated to show a new line:: + + A::Message.body#stringMax = 256 + +Changes the value to something new (say 128), and rerun the IDL import to update the generated Simulink bus. + +Changing sequence attributes +++++++++++++++++++++++++++++ + +IDL import generates a simulink bus for each IDL sequence discovered. For an unbound sequence, the default +name for such sequences is *seq_T*, where *T* is the type of elements in the sequence. +For bounded sequences, the default sequence name is *seqN_T*, where *N* is the declared upper bound of the sequence. + +The following IDL enhances our example IDL to use a sequence of string field for the body attribute:: + + module A { + enum Status { + INFO, + WARNING, + ERROR + }; + struct Message { + long id; + Status status; + sequence body; + }; + #pragma keylist Message id + }; + +On running IDL import, the generated property file now contains the following lines:: + + A::Message.seq_string#name = seq_string + A::Message.seq_string#seqMax = 16 + A::Message.seq_string#stringMax = 256 + +You can edit the value of ``A::Message.seq_string#name`` to change the name of the generated Simulink bus representing the sequences. +You can change the maximum number of elements stored in the Simulink representation of the sequence by editing ``A::Message.seq_string#seqMax``. +Finally, because the type of elements in this sequence are unbounded strings, you can also change the maximum size of each string in the sequence (``A::Message.seq_string#stringMax``). + +Add Simulink bus definitions using bus editor +********************************************* + +Users can also model the Simulink buses using the Simulink bus editor. + +Please see :ref:`Tutorial` for an example with detailed steps. + + +Bus definition limitations +************************** + +The DDS Simulink integration has some limitations. Provided below is a table of unsupported types. +Some of these bus definition limitations will be removed in later release(s). + +Please refer to :ref:`Appendix A` for more detailed implementation details. + + +-------------------------------+ + |Unsupported Simulink Types | + +===============================+ + | long long | + +-------------------------------+ + | unsigned long long | + +-------------------------------+ + | wchar | + +-------------------------------+ + | wstring | + +-------------------------------+ + | any | + +-------------------------------+ + | long double | + +-------------------------------+ + | union | + +-------------------------------+ + | inheritance | + +-------------------------------+ + +See also IDL PreProcessor Guide chapter Keys. + diff --git a/build/docs/DDSSimulinkGuide/source/bus_to_dds_mapping.rst b/build/docs/DDSSimulinkGuide/source/bus_to_dds_mapping.rst new file mode 100644 index 000000000..ed35afc62 --- /dev/null +++ b/build/docs/DDSSimulinkGuide/source/bus_to_dds_mapping.rst @@ -0,0 +1,172 @@ +.. _`Appendix A`: + +########## +Appendix A +########## + +Appendix A provides a description of the Simulink Bus to DDS Mapping implementation. + +Simulink Bus to DDS Mapping +*************************** + +Simulink data is represented in buses whose types are not compatable with DDS types. +Therfore sending Simulink data to DDS requires a conversion from Simulink types to DDS types. +Conversly sending DDS data to Simulink requires a conversion from DDS types to Simulink types. +This document describes the mapping between these types, the type descriptors generated for Topic +registration and any annotations needed to describe keys, namespaces, ... for two different workflows. + + + +Workflow 1: Using idlpp to Generate Simulink Bus and Type Descriptor +==================================================================== + +DDS Topic Types are described in IDL. To be compatible with DDS, these types must be +represented in Sumlink as Bus Types. On writes, these Simulink Bus types are converted +to DDS types and on read DDS types are converted to Simulink Bus types. + +IDL can be defined in an IDL file and the corresponding Simulink Bus Types can be created +by ``Vortex.idlImportSl`` at the MATLAB command line. This will create the necessary Simulink Bus +Types and Elements in a Simulink dictionary. It also creates the XML type descriptor for +the Simulink Bus types that is used to create the Topic. The type descriptor is a Simulink variable +of the form TypeDescriptor. The type descriptor is necessary for the block set to work correctly, +but you will not directly address this when creating Simulink blocks. + + +**DDS IDL to Simulink Bus Mapping** + +The table below describes the generated Simulink artifacts when ``Vortex.idlImportSl`` is invoked from MATLAB. + + +.. table:: + + +--------------------------+----------------------------+----------------+--------------------------------+ + |**DDS IDL** |**Simulink Type** |**Annotation** |**Comments** | + +==========================+============================+================+================================+ + |struct B |Simulink.Bus B | | Creates Simulink Bus | + +--------------------------+----------------------------+----------------+--------------------------------+ + |enum E | Simulink Enum E | | Creates Simulink Enum type | + +--------------------------+----------------------------+----------------+--------------------------------+ + |module A | |@Scope(A) |Added to each enum or struct | + | | | |contained in the module. | + +--------------------------+----------------------------+----------------+--------------------------------+ + |#pragma keylist | |@Key |Every topic bus has @Key in its | + | | | |description. | + +--------------------------+----------------------------+----------------+--------------------------------+ + |boolean |boolean | | | + +--------------------------+----------------------------+----------------+--------------------------------+ + |char |int8 | | | + +--------------------------+----------------------------+----------------+--------------------------------+ + |octet |uint8 | | | + +--------------------------+----------------------------+----------------+--------------------------------+ + |short |int16 | | | + +--------------------------+----------------------------+----------------+--------------------------------+ + |unsigned short |uint16 | | | + +--------------------------+----------------------------+----------------+--------------------------------+ + |long |int32 | | | + +--------------------------+----------------------------+----------------+--------------------------------+ + |unsigned long |uint32 | | | + +--------------------------+----------------------------+----------------+--------------------------------+ + |long long |double | |No int64 in Simulink. Copied | + | | | |into the memory allocated for | + | | | |a double. | + +--------------------------+----------------------------+----------------+--------------------------------+ + |unsigned long long |double | |No int64 in Simulink. Copied | + | | | |into the memory allocated for | + | | | |a double. | + +--------------------------+----------------------------+----------------+--------------------------------+ + |float |single | | | + +--------------------------+----------------------------+----------------+--------------------------------+ + |double |double | | | + +--------------------------+----------------------------+----------------+--------------------------------+ + |string |int8 |@String | Default dimension is 256 | + +--------------------------+----------------------------+----------------+--------------------------------+ + |string | int8 |@BString | | + | | Dimension N | | | + +--------------------------+----------------------------+----------------+--------------------------------+ + |T field[N] | Mapped type for T. | |Multidimensional arrays are | + | | Dimension N | |supported. | + +--------------------------+----------------------------+----------------+--------------------------------+ + |sequence | Bus: seqN_T. | |E.g. sequence becomes | + | | Dimension: N | |"Bus: seq3_int32" | + +--------------------------+----------------------------+----------------+--------------------------------+ + |sequence | Bus: seq_T | |E.g. sequence becomes | + | | Dimension: 16 | |"Bus: seq_int32" with default | + | | | |dimension of 16 | + +--------------------------+----------------------------+----------------+--------------------------------+ + |typedef | | |expanded in place | + +--------------------------+----------------------------+----------------+--------------------------------+ + | **Unsupported DDS data types** | + +--------------------------+----------------------------+----------------+--------------------------------+ + |wchar |*not supported* | | | + +--------------------------+----------------------------+----------------+--------------------------------+ + |wstring |*not supported* | | | + +--------------------------+----------------------------+----------------+--------------------------------+ + |any |*not supported* | | | + +--------------------------+----------------------------+----------------+--------------------------------+ + |long double |*not supported* | | | + +--------------------------+----------------------------+----------------+--------------------------------+ + |union |*not supported* | | | + +--------------------------+----------------------------+----------------+--------------------------------+ + |inheritance |*not supported* | | | + +--------------------------+----------------------------+----------------+--------------------------------+ + + + +Workflow 2: Manually Modeling DDS data in the Simulink Bus Editor +================================================================= + +DDS IDL is not necessary to interact with DDS applicatoins. +You can also model the Simulink buses directly. +In this case, the block set will infer the DDS data types from the Simulink types. + +Defining Simulink busses without first defining the IDL is not recommended; it has the following limitations: + +* fewer IDL concepts are supported. In particular, sequences are unsupported. +* it will be difficult for your Simulink application to interact with applications written in other languages, as those languages will required IDL to define the topic data. + + +**IDL-less mapping of Simulink bus IDL concepts** + +The table below describes how a Simulink bus that was not created from an IDL file +is mapped to IDL concepts. + +.. table:: + + +-------------------------------+------------------+---------------------------------+ + |**Simulink Type** |**IDL equivalent**|**Description** | + +===============================+==================+=================================+ + |Simulink.Bus B |struct B |Defines DDS topic type B | + +-------------------------------+------------------+---------------------------------+ + | bus annotation: @Scope(A::B) |module |Creates DDS namespace for struct | + +-------------------------------+------------------+---------------------------------+ + |bus annotation: @Key(f1,f2) |#pragma keylist |Defines topic key field(s) | + +-------------------------------+------------------+---------------------------------+ + |boolean |boolean |IDL array if Dimensions > 1 | + +-------------------------------+------------------+---------------------------------+ + |int8 |char |IDL array if Dimensions > 1 | + +-------------------------------+------------------+---------------------------------+ + |uint8 |octet |IDL array if Dimensions > 1 | + +-------------------------------+------------------+---------------------------------+ + |int16 |short |IDL array if Dimensions > 1 | + +-------------------------------+------------------+---------------------------------+ + |uint16 |unsigned short |IDL array if Dimensions > 1 | + +-------------------------------+------------------+---------------------------------+ + |int32 |long |IDL array if Dimensions > 1 | + +-------------------------------+------------------+---------------------------------+ + |uint32 |unsigned long |IDL array if Dimensions > 1 | + +-------------------------------+------------------+---------------------------------+ + |single |float |IDL array if Dimensions > 1 | + +-------------------------------+------------------+---------------------------------+ + |double |double |IDL array if Dimensions > 1 | + +-------------------------------+------------------+---------------------------------+ + | | int8, annotated @String |string | | max length of read strings is | + | | uint8, annotated @String | | | determined by field dimension | + +-------------------------------+------------------+---------------------------------+ + | | int8, annotated @BString |string | | + | | uint8, annotated @BString | | | + | | Dimension N | | | + +-------------------------------+------------------+---------------------------------+ + |Simulink enumeration, E |enum E |IDL array if Dimensions > 1 | + +-------------------------------+------------------+---------------------------------+ + + diff --git a/build/docs/DDSSimulinkGuide/source/conf.py b/build/docs/DDSSimulinkGuide/source/conf.py new file mode 100644 index 000000000..06455746d --- /dev/null +++ b/build/docs/DDSSimulinkGuide/source/conf.py @@ -0,0 +1,282 @@ +# -*- coding: utf-8 -*- +# +# OpenSplice_Deployment_Guide build configuration file, created by +# ReST Editor on 06-Jul-2015 +# +# This file is execfile()d with the current directory set to its containing dir. +# +# Note that not all possible configuration values are present in this +# autogenerated file. +# +# All configuration values have a default; values that are commented out +# serve to show the default. + +import sys, os +import time + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +#sys.path.insert(0, os.path.abspath('.')) + +# -- General configuration ----------------------------------------------------- + +# If your documentation needs a minimal Sphinx version, state it here. +#needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be extensions +# coming with Sphinx (named 'sphinx.ext.*') or your custom ones. +#extensions = ['sphinx.ext.todo'] + +extensions = ['sphinx.ext.todo', 'sphinx.ext.ifconfig'] + +def setup(app): + app.add_config_value('rmi_languages', '', True) + +#rmi_languages = 'C++ and Java' +rmi_languages = 'C++' +#rmi_languages = 'Java' +rst_prolog = """ +.. |rmi_langs| replace:: C++ +.. |product_name| replace:: OpenSplice +""" + +#.. |rmi_langs| replace:: C++ and Java + + + +# Add any paths that contain templates here, relative to this directory. +templates_path = [u'_templates'] + + +# The suffix of source filenames. +source_suffix = '.rst' + +# The encoding of source files. +source_encoding = u'utf-8-sig' + + +# The master toctree document. +master_doc = u'index' + + +# General information about the project. +project = u'Vortex OpenSplice Simulink Guide' + +this_year = time.strftime( '%Y' ) +copyright = u'{y}, ADLINK Technology Limited'.format( y = this_year ) +print 'Copyright string is:', copyright + + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# +# The short X.Y version. +version = u'6.x' + +# The full version, including alpha/beta/rc tags. +release = version +#release = u'.0' +print 'Short version string is:', version +print 'Full version string is:', release + + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +language = u'en' + + +# There are two options for replacing |today|: either, you set today to some +# non-false value, then it is used: +today = ' ' +# Else, today_fmt is used as the format for a strftime call. +#today_fmt = '%B %d, %Y' + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +exclude_patterns = [] + +# The reST default role (used for this markup: `text`) to use for all documents. +#default_role = None + +# If true, '()' will be appended to :func: etc. cross-reference text. +#add_function_parentheses = True + +# If true, the current module name will be prepended to all description +# unit titles (such as .. function::). +#add_module_names = True + +# If true, sectionauthor and moduleauthor directives will be shown in the +# output. They are ignored by default. +#show_authors = False + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + +# A list of ignored prefixes for module index sorting. +#modindex_common_prefix = [] + + +# -- Options for HTML output --------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# html_theme = u'sphinxdoc' +html_theme = u'vortextheme' +# LINUX PATH: +html_theme_path = ['../../.'] +# WINDOWS PATH: +# html_theme_path = ['..\..\.'] +#build theme directory in lite using environment variable, so shared amongst books +# insight team can delete, +#html_theme_path = [os.environ['VL_HOME'] + '/build/docs'] + + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +#html_theme_options = {} + +# Add any paths that contain custom themes here, relative to this directory. +#html_theme_path = [] + +# The name for this set of Sphinx documents. If None, it defaults to +# " v documentation". +#html_title = None +html_title = 'The Vortex OpenSplice Simulink Guide' + +# A shorter title for the navigation bar. Default is the same as html_title. +#html_short_title = None +#html_short_title = 'HTML short Title conf.py' +html_short_title = 'OpenSplice Simulink Guide' + +# The name of an image file (relative to this directory) to place at the top +# of the sidebar. +html_logo = './images/Vortex_logo_2014.png' + +# The name of an image file (within the static path) to use as favicon of the +# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 +# pixels large. +#html_favicon = None + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = [u'_static'] + + +# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, +# using the given strftime format. +#html_last_updated_fmt = '%b %d, %Y' + +# If true, SmartyPants will be used to convert quotes and dashes to +# typographically correct entities. +#html_use_smartypants = True + +# Custom sidebar templates, maps document names to template names. +#html_sidebars = {} + +# Additional templates that should be rendered to pages, maps page names to +# template names. +#html_additional_pages = {} + +# If false, no module index is generated. +#html_domain_indices = True + +# If false, no index is generated. +#html_use_index = True + +# If true, the index is split into individual pages for each letter. +#html_split_index = False + +# If true, links to the reST sources are added to the pages. +#html_show_sourcelink = True + +# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. +#html_show_sphinx = True +html_show_sphinx = False + +# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. +#html_show_copyright = True + +# If true, an OpenSearch description file will be output, and all pages will +# contain a tag referring to it. The value of this option must be the +# base URL from which the finished HTML is served. +#html_use_opensearch = '' + +# This is the file name suffix for HTML files (e.g. ".xhtml"). +#html_file_suffix = None + +# Output file base name for HTML help builder. +htmlhelp_basename = 'The Vortex OpenSplice Simulink Guide' + + +# -- Options for LaTeX output -------------------------------------------------- + +# The paper size ('letter' or 'a4'). +latex_paper_size = u'a4' + + +# The font size ('10pt', '11pt' or '12pt'). +latex_font_size = u'10pt' + + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, author, documentclass [howto/manual]). +latex_documents = [('index', 'OpenSplice_DDSSimulinkGuide.tex', u'OpenSplice Simulink Guide', u'', 'manual', True)] +# Note 'author' field empty +# Added 'True' to end of generated line to suppress 'Index & Tables' + + +# A dictionary that contains LaTeX snippets that override those Sphinx usually +# puts into the generated .tex files. +latex_elements = { 'babel': '\\usepackage[english]{babel}' } + + +# The name of an image file (relative to this directory) to place at the top of +# the title page. +latex_logo = './images/Vortex-Cover.png' + +# For "manual" documents, if this is true, then toplevel headings are parts, +# not chapters. +latex_use_parts = False + + +# If true, show page references after internal links. +#latex_show_pagerefs = False + +# If true, show URL addresses after external links. +#latex_show_urls = False + +# Additional stuff for the LaTeX preamble. +latex_preamble = r""" +\setcounter {tocdepth} {5} +\setcounter{secnumdepth}{5} + +""" + +# * THIS GETS RID OF BLANK PAGES AT ENDS OF CHAPTERS & ToC +latex_elements = { + 'classoptions': ',openany, oneside', + 'babel': '\\usepackage[english]{babel}' +} + + +# Documents to append as an appendix to all manuals. +#latex_appendices = [] + +# If false, no module index is generated. +#latex_domain_indices = True + + +# -- Options for manual page output -------------------------------------------- + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [('index', 'OpenSplice_DDSSimulinkGuide', u'OpenSplice_DDSSimulink Documentation', [u'ADLINK Technology Limited'], 1)] + + +# -- Additional options -------------------------------------------------------- + +todo_include_todos = True diff --git a/build/docs/DDSSimulinkGuide/source/contacts.rst b/build/docs/DDSSimulinkGuide/source/contacts.rst new file mode 100644 index 000000000..d32f6016f --- /dev/null +++ b/build/docs/DDSSimulinkGuide/source/contacts.rst @@ -0,0 +1 @@ +.. include:: ../../common/contacts.rst diff --git a/build/docs/DDSSimulinkGuide/source/domain.rst b/build/docs/DDSSimulinkGuide/source/domain.rst new file mode 100755 index 000000000..6babb0959 --- /dev/null +++ b/build/docs/DDSSimulinkGuide/source/domain.rst @@ -0,0 +1,44 @@ +.. _`Domain Block`: + + + +############ +Domain Block +############ + +The Domain block represents a DDS domain participant entity. + +In DDS - "A domain participant represents the local membership of the application in a domain. A domain is a distributed concept that links all the applications able to communicate with each other. It represents a communication plane: only the publishers and subscribers attached to the same domain may interact." + +This block is optional on a DDS Simulink model diagram. If it is not present on a model diagram, a default participant will be created by either a topic, writer or reader block. + +.. figure:: images/domain_block.png + :alt: DDS Domain Block + + +=========== ========= ======= =========================== ==================== + Port Type Optional Name Description Output consumed by +=========== ========= ======= =========================== ==================== +Output no pp DDS Domain Participant Publisher, + entity instance Subscriber, Topic +=========== ========= ======= =========================== ==================== + + +Domain Block Parameters +*********************** + +.. figure:: images/domain_block_parameters.png + :alt: Domain Block Parameters + +Domain Tab +========== +The domain id is read only. The domain id is the OSPL default domain id specified in the OSPL configuration file. + +QoS Tab +======= +The **QoS** tab is used to set the QoS profile. By default, the OSPL default profile is used. + +In DDS - The Data-Distribution Service (DDS) relies on the usage of QoS. A QoS (Quality of Service) is a set of characteristics that controls some aspect of the behavior of the DDS Service. + +Each DDS block has an associated QoS profile. By default, the OSPL default profile is used. An XML file that specifies QoS profiles can be used to set the QoS of a DDS block. + diff --git a/build/docs/DDSSimulinkGuide/source/images/Vortex-Cover.png b/build/docs/DDSSimulinkGuide/source/images/Vortex-Cover.png new file mode 100644 index 000000000..d82d6b313 Binary files /dev/null and b/build/docs/DDSSimulinkGuide/source/images/Vortex-Cover.png differ diff --git a/build/docs/DDSSimulinkGuide/source/images/Vortex_logo_2014.png b/build/docs/DDSSimulinkGuide/source/images/Vortex_logo_2014.png new file mode 100644 index 000000000..e7de4f525 Binary files /dev/null and b/build/docs/DDSSimulinkGuide/source/images/Vortex_logo_2014.png differ diff --git a/build/docs/DDSSimulinkGuide/source/images/addBus.png b/build/docs/DDSSimulinkGuide/source/images/addBus.png new file mode 100755 index 000000000..d1f1f9e2f Binary files /dev/null and b/build/docs/DDSSimulinkGuide/source/images/addBus.png differ diff --git a/build/docs/DDSSimulinkGuide/source/images/addBusElement.png b/build/docs/DDSSimulinkGuide/source/images/addBusElement.png new file mode 100755 index 000000000..c9cd9bfe2 Binary files /dev/null and b/build/docs/DDSSimulinkGuide/source/images/addBusElement.png differ diff --git a/build/docs/DDSSimulinkGuide/source/images/addShapeType.png b/build/docs/DDSSimulinkGuide/source/images/addShapeType.png new file mode 100755 index 000000000..42dda505b Binary files /dev/null and b/build/docs/DDSSimulinkGuide/source/images/addShapeType.png differ diff --git a/build/docs/DDSSimulinkGuide/source/images/busExport.png b/build/docs/DDSSimulinkGuide/source/images/busExport.png new file mode 100755 index 000000000..7125e686f Binary files /dev/null and b/build/docs/DDSSimulinkGuide/source/images/busExport.png differ diff --git a/build/docs/DDSSimulinkGuide/source/images/buscreator_constants.png b/build/docs/DDSSimulinkGuide/source/images/buscreator_constants.png new file mode 100755 index 000000000..a6ffe4bc9 Binary files /dev/null and b/build/docs/DDSSimulinkGuide/source/images/buscreator_constants.png differ diff --git a/build/docs/DDSSimulinkGuide/source/images/colorBusElement.png b/build/docs/DDSSimulinkGuide/source/images/colorBusElement.png new file mode 100755 index 000000000..dffeea454 Binary files /dev/null and b/build/docs/DDSSimulinkGuide/source/images/colorBusElement.png differ diff --git a/build/docs/DDSSimulinkGuide/source/images/colorConstant2.png b/build/docs/DDSSimulinkGuide/source/images/colorConstant2.png new file mode 100755 index 000000000..68fa308d2 Binary files /dev/null and b/build/docs/DDSSimulinkGuide/source/images/colorConstant2.png differ diff --git a/build/docs/DDSSimulinkGuide/source/images/constant_x.png b/build/docs/DDSSimulinkGuide/source/images/constant_x.png new file mode 100755 index 000000000..4a0e85c27 Binary files /dev/null and b/build/docs/DDSSimulinkGuide/source/images/constant_x.png differ diff --git a/build/docs/DDSSimulinkGuide/source/images/ddsLibrary.png b/build/docs/DDSSimulinkGuide/source/images/ddsLibrary.png new file mode 100755 index 000000000..b4b086257 Binary files /dev/null and b/build/docs/DDSSimulinkGuide/source/images/ddsLibrary.png differ diff --git a/build/docs/DDSSimulinkGuide/source/images/dds_overview.png b/build/docs/DDSSimulinkGuide/source/images/dds_overview.png new file mode 100755 index 000000000..c7490ddb4 Binary files /dev/null and b/build/docs/DDSSimulinkGuide/source/images/dds_overview.png differ diff --git a/build/docs/DDSSimulinkGuide/source/images/default_qos_params.png b/build/docs/DDSSimulinkGuide/source/images/default_qos_params.png new file mode 100755 index 000000000..02b9bfe60 Binary files /dev/null and b/build/docs/DDSSimulinkGuide/source/images/default_qos_params.png differ diff --git a/build/docs/DDSSimulinkGuide/source/images/domain_block.png b/build/docs/DDSSimulinkGuide/source/images/domain_block.png new file mode 100755 index 000000000..812c58541 Binary files /dev/null and b/build/docs/DDSSimulinkGuide/source/images/domain_block.png differ diff --git a/build/docs/DDSSimulinkGuide/source/images/domain_block_parameters.png b/build/docs/DDSSimulinkGuide/source/images/domain_block_parameters.png new file mode 100755 index 000000000..666779a11 Binary files /dev/null and b/build/docs/DDSSimulinkGuide/source/images/domain_block_parameters.png differ diff --git a/build/docs/DDSSimulinkGuide/source/images/linuxCodeGenNoANSI_OPTS.png b/build/docs/DDSSimulinkGuide/source/images/linuxCodeGenNoANSI_OPTS.png new file mode 100644 index 000000000..cc1465e51 Binary files /dev/null and b/build/docs/DDSSimulinkGuide/source/images/linuxCodeGenNoANSI_OPTS.png differ diff --git a/build/docs/DDSSimulinkGuide/source/images/linuxIDLPP_SLDD_ChangedNames.png b/build/docs/DDSSimulinkGuide/source/images/linuxIDLPP_SLDD_ChangedNames.png new file mode 100644 index 000000000..e4df8d5b8 Binary files /dev/null and b/build/docs/DDSSimulinkGuide/source/images/linuxIDLPP_SLDD_ChangedNames.png differ diff --git a/build/docs/DDSSimulinkGuide/source/images/linuxInstall2.png b/build/docs/DDSSimulinkGuide/source/images/linuxInstall2.png new file mode 100755 index 000000000..cd75ee2fa Binary files /dev/null and b/build/docs/DDSSimulinkGuide/source/images/linuxInstall2.png differ diff --git a/build/docs/DDSSimulinkGuide/source/images/modBlock.png b/build/docs/DDSSimulinkGuide/source/images/modBlock.png new file mode 100755 index 000000000..ba6d9f5b4 Binary files /dev/null and b/build/docs/DDSSimulinkGuide/source/images/modBlock.png differ diff --git a/build/docs/DDSSimulinkGuide/source/images/modBlock2.png b/build/docs/DDSSimulinkGuide/source/images/modBlock2.png new file mode 100755 index 000000000..6e059e5f4 Binary files /dev/null and b/build/docs/DDSSimulinkGuide/source/images/modBlock2.png differ diff --git a/build/docs/DDSSimulinkGuide/source/images/modelExplorer.png b/build/docs/DDSSimulinkGuide/source/images/modelExplorer.png new file mode 100755 index 000000000..ea80d9414 Binary files /dev/null and b/build/docs/DDSSimulinkGuide/source/images/modelExplorer.png differ diff --git a/build/docs/DDSSimulinkGuide/source/images/openBusEditor.png b/build/docs/DDSSimulinkGuide/source/images/openBusEditor.png new file mode 100755 index 000000000..9a2b6cc67 Binary files /dev/null and b/build/docs/DDSSimulinkGuide/source/images/openBusEditor.png differ diff --git a/build/docs/DDSSimulinkGuide/source/images/openLibraryBrowser.png b/build/docs/DDSSimulinkGuide/source/images/openLibraryBrowser.png new file mode 100755 index 000000000..2c53c6b93 Binary files /dev/null and b/build/docs/DDSSimulinkGuide/source/images/openLibraryBrowser.png differ diff --git a/build/docs/DDSSimulinkGuide/source/images/persistent_qos_params.png b/build/docs/DDSSimulinkGuide/source/images/persistent_qos_params.png new file mode 100755 index 000000000..21cd7d768 Binary files /dev/null and b/build/docs/DDSSimulinkGuide/source/images/persistent_qos_params.png differ diff --git a/build/docs/DDSSimulinkGuide/source/images/publisher_block.png b/build/docs/DDSSimulinkGuide/source/images/publisher_block.png new file mode 100755 index 000000000..fc3b2bd17 Binary files /dev/null and b/build/docs/DDSSimulinkGuide/source/images/publisher_block.png differ diff --git a/build/docs/DDSSimulinkGuide/source/images/publisher_block_parameters.png b/build/docs/DDSSimulinkGuide/source/images/publisher_block_parameters.png new file mode 100755 index 000000000..1bc354e7a Binary files /dev/null and b/build/docs/DDSSimulinkGuide/source/images/publisher_block_parameters.png differ diff --git a/build/docs/DDSSimulinkGuide/source/images/read_blocks.png b/build/docs/DDSSimulinkGuide/source/images/read_blocks.png new file mode 100755 index 000000000..3f91df58d Binary files /dev/null and b/build/docs/DDSSimulinkGuide/source/images/read_blocks.png differ diff --git a/build/docs/DDSSimulinkGuide/source/images/read_busSelectorOutputs.png b/build/docs/DDSSimulinkGuide/source/images/read_busSelectorOutputs.png new file mode 100755 index 000000000..f0e959dfb Binary files /dev/null and b/build/docs/DDSSimulinkGuide/source/images/read_busSelectorOutputs.png differ diff --git a/build/docs/DDSSimulinkGuide/source/images/read_busSelector_display.png b/build/docs/DDSSimulinkGuide/source/images/read_busSelector_display.png new file mode 100755 index 000000000..d38213b1b Binary files /dev/null and b/build/docs/DDSSimulinkGuide/source/images/read_busSelector_display.png differ diff --git a/build/docs/DDSSimulinkGuide/source/images/read_complete.png b/build/docs/DDSSimulinkGuide/source/images/read_complete.png new file mode 100755 index 000000000..1932b7072 Binary files /dev/null and b/build/docs/DDSSimulinkGuide/source/images/read_complete.png differ diff --git a/build/docs/DDSSimulinkGuide/source/images/read_connect.png b/build/docs/DDSSimulinkGuide/source/images/read_connect.png new file mode 100755 index 000000000..d92d7d264 Binary files /dev/null and b/build/docs/DDSSimulinkGuide/source/images/read_connect.png differ diff --git a/build/docs/DDSSimulinkGuide/source/images/read_model_settings.png b/build/docs/DDSSimulinkGuide/source/images/read_model_settings.png new file mode 100755 index 000000000..d82dd6d8b Binary files /dev/null and b/build/docs/DDSSimulinkGuide/source/images/read_model_settings.png differ diff --git a/build/docs/DDSSimulinkGuide/source/images/read_topic_qos.png b/build/docs/DDSSimulinkGuide/source/images/read_topic_qos.png new file mode 100755 index 000000000..c1639e586 Binary files /dev/null and b/build/docs/DDSSimulinkGuide/source/images/read_topic_qos.png differ diff --git a/build/docs/DDSSimulinkGuide/source/images/read_topic_topic.png b/build/docs/DDSSimulinkGuide/source/images/read_topic_topic.png new file mode 100755 index 000000000..dbe6a9298 Binary files /dev/null and b/build/docs/DDSSimulinkGuide/source/images/read_topic_topic.png differ diff --git a/build/docs/DDSSimulinkGuide/source/images/reader_block.png b/build/docs/DDSSimulinkGuide/source/images/reader_block.png new file mode 100755 index 000000000..a41c7f24d Binary files /dev/null and b/build/docs/DDSSimulinkGuide/source/images/reader_block.png differ diff --git a/build/docs/DDSSimulinkGuide/source/images/reader_block_parameters.png b/build/docs/DDSSimulinkGuide/source/images/reader_block_parameters.png new file mode 100755 index 000000000..27bec302a Binary files /dev/null and b/build/docs/DDSSimulinkGuide/source/images/reader_block_parameters.png differ diff --git a/build/docs/DDSSimulinkGuide/source/images/reader_filters_tab.png b/build/docs/DDSSimulinkGuide/source/images/reader_filters_tab.png new file mode 100755 index 000000000..de09fdacb Binary files /dev/null and b/build/docs/DDSSimulinkGuide/source/images/reader_filters_tab.png differ diff --git a/build/docs/DDSSimulinkGuide/source/images/results.png b/build/docs/DDSSimulinkGuide/source/images/results.png new file mode 100755 index 000000000..a14ff5d73 Binary files /dev/null and b/build/docs/DDSSimulinkGuide/source/images/results.png differ diff --git a/build/docs/DDSSimulinkGuide/source/images/run.png b/build/docs/DDSSimulinkGuide/source/images/run.png new file mode 100755 index 000000000..27760626a Binary files /dev/null and b/build/docs/DDSSimulinkGuide/source/images/run.png differ diff --git a/build/docs/DDSSimulinkGuide/source/images/shapesizeBusElement.png b/build/docs/DDSSimulinkGuide/source/images/shapesizeBusElement.png new file mode 100755 index 000000000..cbabbf03b Binary files /dev/null and b/build/docs/DDSSimulinkGuide/source/images/shapesizeBusElement.png differ diff --git a/build/docs/DDSSimulinkGuide/source/images/shapesizeConstantBLock.png b/build/docs/DDSSimulinkGuide/source/images/shapesizeConstantBLock.png new file mode 100755 index 000000000..31d9068df Binary files /dev/null and b/build/docs/DDSSimulinkGuide/source/images/shapesizeConstantBLock.png differ diff --git a/build/docs/DDSSimulinkGuide/source/images/simulinkStartPage.png b/build/docs/DDSSimulinkGuide/source/images/simulinkStartPage.png new file mode 100755 index 000000000..1d1f3000b Binary files /dev/null and b/build/docs/DDSSimulinkGuide/source/images/simulinkStartPage.png differ diff --git a/build/docs/DDSSimulinkGuide/source/images/sineWaveBlockParamters.png b/build/docs/DDSSimulinkGuide/source/images/sineWaveBlockParamters.png new file mode 100755 index 000000000..220200f34 Binary files /dev/null and b/build/docs/DDSSimulinkGuide/source/images/sineWaveBlockParamters.png differ diff --git a/build/docs/DDSSimulinkGuide/source/images/sinewave.png b/build/docs/DDSSimulinkGuide/source/images/sinewave.png new file mode 100755 index 000000000..14497d2e7 Binary files /dev/null and b/build/docs/DDSSimulinkGuide/source/images/sinewave.png differ diff --git a/build/docs/DDSSimulinkGuide/source/images/startSimulink.png b/build/docs/DDSSimulinkGuide/source/images/startSimulink.png new file mode 100755 index 000000000..dddfac90c Binary files /dev/null and b/build/docs/DDSSimulinkGuide/source/images/startSimulink.png differ diff --git a/build/docs/DDSSimulinkGuide/source/images/sub_annotations_qos.png b/build/docs/DDSSimulinkGuide/source/images/sub_annotations_qos.png new file mode 100755 index 000000000..0ee32f463 Binary files /dev/null and b/build/docs/DDSSimulinkGuide/source/images/sub_annotations_qos.png differ diff --git a/build/docs/DDSSimulinkGuide/source/images/subscriber_block.png b/build/docs/DDSSimulinkGuide/source/images/subscriber_block.png new file mode 100755 index 000000000..5a5a2dd15 Binary files /dev/null and b/build/docs/DDSSimulinkGuide/source/images/subscriber_block.png differ diff --git a/build/docs/DDSSimulinkGuide/source/images/subscriber_block_parameters.png b/build/docs/DDSSimulinkGuide/source/images/subscriber_block_parameters.png new file mode 100755 index 000000000..37b33a45e Binary files /dev/null and b/build/docs/DDSSimulinkGuide/source/images/subscriber_block_parameters.png differ diff --git a/build/docs/DDSSimulinkGuide/source/images/topic_block.png b/build/docs/DDSSimulinkGuide/source/images/topic_block.png new file mode 100755 index 000000000..e5170e28b Binary files /dev/null and b/build/docs/DDSSimulinkGuide/source/images/topic_block.png differ diff --git a/build/docs/DDSSimulinkGuide/source/images/topic_block_parameters.png b/build/docs/DDSSimulinkGuide/source/images/topic_block_parameters.png new file mode 100755 index 000000000..48398ab10 Binary files /dev/null and b/build/docs/DDSSimulinkGuide/source/images/topic_block_parameters.png differ diff --git a/build/docs/DDSSimulinkGuide/source/images/upDownBusElement.png b/build/docs/DDSSimulinkGuide/source/images/upDownBusElement.png new file mode 100755 index 000000000..80ac9f72b Binary files /dev/null and b/build/docs/DDSSimulinkGuide/source/images/upDownBusElement.png differ diff --git a/build/docs/DDSSimulinkGuide/source/images/write_busCreator.png b/build/docs/DDSSimulinkGuide/source/images/write_busCreator.png new file mode 100755 index 000000000..dcd0e29a2 Binary files /dev/null and b/build/docs/DDSSimulinkGuide/source/images/write_busCreator.png differ diff --git a/build/docs/DDSSimulinkGuide/source/images/write_buscreator_params.png b/build/docs/DDSSimulinkGuide/source/images/write_buscreator_params.png new file mode 100755 index 000000000..ab342d2ae Binary files /dev/null and b/build/docs/DDSSimulinkGuide/source/images/write_buscreator_params.png differ diff --git a/build/docs/DDSSimulinkGuide/source/images/write_complete.png b/build/docs/DDSSimulinkGuide/source/images/write_complete.png new file mode 100755 index 000000000..138981296 Binary files /dev/null and b/build/docs/DDSSimulinkGuide/source/images/write_complete.png differ diff --git a/build/docs/DDSSimulinkGuide/source/images/write_connect_domain.png b/build/docs/DDSSimulinkGuide/source/images/write_connect_domain.png new file mode 100755 index 000000000..334c3ff01 Binary files /dev/null and b/build/docs/DDSSimulinkGuide/source/images/write_connect_domain.png differ diff --git a/build/docs/DDSSimulinkGuide/source/images/write_domain_parameters.png b/build/docs/DDSSimulinkGuide/source/images/write_domain_parameters.png new file mode 100755 index 000000000..2d0ba6864 Binary files /dev/null and b/build/docs/DDSSimulinkGuide/source/images/write_domain_parameters.png differ diff --git a/build/docs/DDSSimulinkGuide/source/images/write_mathFunctionBlockParams.png b/build/docs/DDSSimulinkGuide/source/images/write_mathFunctionBlockParams.png new file mode 100755 index 000000000..2cdb32c6e Binary files /dev/null and b/build/docs/DDSSimulinkGuide/source/images/write_mathFunctionBlockParams.png differ diff --git a/build/docs/DDSSimulinkGuide/source/images/write_model_setup.png b/build/docs/DDSSimulinkGuide/source/images/write_model_setup.png new file mode 100755 index 000000000..939797064 Binary files /dev/null and b/build/docs/DDSSimulinkGuide/source/images/write_model_setup.png differ diff --git a/build/docs/DDSSimulinkGuide/source/images/write_topic_parameters.png b/build/docs/DDSSimulinkGuide/source/images/write_topic_parameters.png new file mode 100755 index 000000000..22bf10b91 Binary files /dev/null and b/build/docs/DDSSimulinkGuide/source/images/write_topic_parameters.png differ diff --git a/build/docs/DDSSimulinkGuide/source/images/write_writer_qos.png b/build/docs/DDSSimulinkGuide/source/images/write_writer_qos.png new file mode 100755 index 000000000..5480380c1 Binary files /dev/null and b/build/docs/DDSSimulinkGuide/source/images/write_writer_qos.png differ diff --git a/build/docs/DDSSimulinkGuide/source/images/writer_block.png b/build/docs/DDSSimulinkGuide/source/images/writer_block.png new file mode 100755 index 000000000..4074aa42b Binary files /dev/null and b/build/docs/DDSSimulinkGuide/source/images/writer_block.png differ diff --git a/build/docs/DDSSimulinkGuide/source/images/writer_block_parameters.png b/build/docs/DDSSimulinkGuide/source/images/writer_block_parameters.png new file mode 100755 index 000000000..aeaa16081 Binary files /dev/null and b/build/docs/DDSSimulinkGuide/source/images/writer_block_parameters.png differ diff --git a/build/docs/DDSSimulinkGuide/source/images/writer_write_parameters.png b/build/docs/DDSSimulinkGuide/source/images/writer_write_parameters.png new file mode 100755 index 000000000..7b8caaa42 Binary files /dev/null and b/build/docs/DDSSimulinkGuide/source/images/writer_write_parameters.png differ diff --git a/build/docs/DDSSimulinkGuide/source/images/xBusElement.png b/build/docs/DDSSimulinkGuide/source/images/xBusElement.png new file mode 100755 index 000000000..90d300b6f Binary files /dev/null and b/build/docs/DDSSimulinkGuide/source/images/xBusElement.png differ diff --git a/build/docs/DDSSimulinkGuide/source/images/xyGraph2.png b/build/docs/DDSSimulinkGuide/source/images/xyGraph2.png new file mode 100755 index 000000000..953e58ecc Binary files /dev/null and b/build/docs/DDSSimulinkGuide/source/images/xyGraph2.png differ diff --git a/build/docs/DDSSimulinkGuide/source/images/yBusElement.png b/build/docs/DDSSimulinkGuide/source/images/yBusElement.png new file mode 100755 index 000000000..fa2fa98fb Binary files /dev/null and b/build/docs/DDSSimulinkGuide/source/images/yBusElement.png differ diff --git a/build/docs/DDSSimulinkGuide/source/index.rst b/build/docs/DDSSimulinkGuide/source/index.rst new file mode 100644 index 000000000..162a5ba59 --- /dev/null +++ b/build/docs/DDSSimulinkGuide/source/index.rst @@ -0,0 +1,36 @@ +.. The Vortex OpenSplice Simulink Guide + +.. Doc Issue 01, 28 February 2017 + +################## +DDS Simulink Guide +################## + +.. toctree:: + :maxdepth: 6 + :numbered: + + introduction + installation + blocks + bus-dds + qos_provider + topic + domain + publisher + subscriber + writer + reader + tutorial + simulink_coder + troubleshooting + + bus_to_dds_mapping + + contacts + + +Indices and tables +================== + +* :ref:`search` diff --git a/build/docs/DDSSimulinkGuide/source/installation.rst b/build/docs/DDSSimulinkGuide/source/installation.rst new file mode 100644 index 000000000..3e9104d12 --- /dev/null +++ b/build/docs/DDSSimulinkGuide/source/installation.rst @@ -0,0 +1,133 @@ +.. _`Installation`: + +############ +Installation +############ + +This section describes the procedure to install the Vortex DDS Simulink Integration on a Linux or Windows platform. + +System Requirements +******************* + +- Operating System: Windows or Linux +- MATLAB Simulink installed +- Java 1.7 or greater + +OpenSplice (OSPL) and DDS Simulink Installation +*********************************************** + +Steps: + +1. Install OSPL. The DDS Simulink Integration is included in this installer. + + +2. Setup OSPL license. Copy the license.lic file into the appropriate license directory. + + */INSTALLDIR/ADLINK/Vortex_v2/license* + +3. MATLAB and Simulink files are contained in a tools/matlab folder + + Example: + */INSTALLDIR/ADLINK/Vortex_v2/Device/VortexOpenSplice/6.8.x/HDE/x86_64.linux/tools/matlab* + + +OpenSplice (OSPL) Configuration +******************************* + +By default OSPL uses single process configuration. + +If however, shared memory configuration is used, additional OSPL configuration steps need to be taken to work with MATLAB Simulink. + +Linux +===== + +OSPL-9882 Linux: MATLAB/Simulink hangs when connecting to shared memory domain + +**Description** +On Linux, a MATLAB script or Simulink model connecting to a Vortex OpenSplice domain via shared memory will hang. + +**Resolution** +MATLAB, like Java applications requires that the environment variable LD_PRELOAD be set to reference the active Java installations libjsig.so library. +The MATLAB user interface uses Java, and thus requires the same signal handling strategy as Java applications connecting to Vortex OpenSplice. +The precise syntax for setting the LD_PRELOAD environment variable will depend on the shell being used. + +For Oracle JVMs, LD_PRELOAD should contain this value: + $JAVA_HOME/jre/lib/amd64/libjsig.so + +Windows +======= + +OSPL-10018 MATLAB: Shared Memory Database Address on Windows needs to be changed from default + +**Description** +On a Windows 64-bit system, an OpenSplice system configured with Shared Memory, MATLAB cannot connect to the OpenSplice domain if the Shared Memory Database Address is set to its default value of 0x40000000. The error log (ospl-error.log) will show entries such as: +Report : Can not Map View Of file: Attempt to access invalid address. +Internals : OS Abstraction/code/os_sharedmem.c/1764/0/1487951812.565129500 + +**Resolution** +Use the configuration editor to change the default data base address. Use the 'Domain' tab, and select the 'Database' element in the tree. If necessary, right click the Database element to add an 'Address' element. Change the address. In general, a larger number is less likely to be problematic. On a test machine, appending two zeros to the default address allowed for successful connections. + + +Simulink Setup +************** + +Steps: + +1. Open command shell and run script to setup environment variables. + + **Linux** + + - Open a Linux terminal. + + - Navigate to directory containing release.com file. + + */INSTALLDIR/ADLINK/Vortex_v2/Device/VortexOpenSplice/6.8.x/HDE/x86_64.linux* + + - Run release.com. (Type in “. release.com†at command line.) + + + **Windows** + + - Open a command prompt. + + - Navigate to directory containing release.bat file. + + *INSTALLDIR/ADLINK/Vortex_v2/Device/VortexOpenSplice/6.8.x/HDE/x86_64.win64* + + - Run release.bat. (Type in “release.bat†at command line.) + + +2. Start MATLAB using the **SAME** command shell used in Step 1. + + *NOTE: If MATLAB is NOT started from a command shell with the correct OSPL environment variables set, exceptions will occur when attempting to use DDS Simulink blocks.* + +3. In MATLAB, navigate to file “Vortex_DDS_Block_Set.mltbx†by typing:: + + cd(fullfile(getenv('OSPL_HOME'),'tools','matlab')) + +.. raw:: latex + + \newpage + +4. Double click on the file “Vortex_DDS_Block_Set.mltbxâ€. This will bring up a dialog entitled **Install Vortex_DDS_Block_Set**. Select **Install**. + +.. figure:: images/linuxInstall2.png + :alt: DDS + + +**Setup is complete!** + + + +Examples +******** + +Example models have been provided in the examples folder. + +*../tools/matlab/examples/simulink* + + + + + + diff --git a/build/docs/DDSSimulinkGuide/source/introduction.rst b/build/docs/DDSSimulinkGuide/source/introduction.rst new file mode 100644 index 000000000..f2694b631 --- /dev/null +++ b/build/docs/DDSSimulinkGuide/source/introduction.rst @@ -0,0 +1,35 @@ +.. _`Introduction`: + + +############ +Introduction +############ + +The DDS Simulink Integration provides users with DDS custom blocks to model DDS communication between Simulink models and pure DDS applications. + +DDS +*** + +**What is DDS?** + +“The Data Distribution Service (DDSâ„¢) is a middleware protocol and API standard for data-centric connectivity from the Object Management Group® (OMG®). It integrates the components of a system together, providing low-latency data connectivity, extreme reliability, and a scalable architecture that business and mission-critical Internet of Things (IoT) applications need.†+ +“The main goal of DDS is to share the right data at the right place at the right time, even between time-decoupled publishers and consumers. DDS implements global data space by carefully replicating relevant portions of the logically shared dataspace.†DDS specification + +.. figure:: images/dds_overview.png + :alt: DDS + +**Further Documentation** + +http://portals.omg.org/dds/ + +http://ist.adlinktech.com/ + +Simulink +******** + +**What is Simulink?** + +“Simulink® is a block diagram environment for multidomain simulation and Model-Based Design. It supports system-level design, simulation, automatic code generation, and continuous test and verification of embedded systems. Simulink provides a graphical editor, customizable block libraries, and solvers for modeling and simulating dynamic systems. It is integrated with MATLAB®, enabling you to incorporate MATLAB algorithms into models and export simulation results to MATLAB for further analysis.†Simulink Help + + diff --git a/build/docs/DDSSimulinkGuide/source/publisher.rst b/build/docs/DDSSimulinkGuide/source/publisher.rst new file mode 100755 index 000000000..343f27bf7 --- /dev/null +++ b/build/docs/DDSSimulinkGuide/source/publisher.rst @@ -0,0 +1,47 @@ +.. _`Publisher Block`: + + + +############### +Publisher Block +############### + +The Publisher block represents a DDS publisher entity. + +In DDS, a publisher is "an object responsible for data distribution. It may publish data of different data types." + +This block is optional on a DDS Simulink model diagram. If it is not present on a model diagram, each writer will create a default publisher. + +.. figure:: images/publisher_block.png + :alt: DDS Publisher Block + + + +=========== ========= ======= =========================== ==================== + Port Type Optional Name Description Output consumed by +=========== ========= ======= =========================== ==================== +Input yes pp DDS Domain Participant + entity instance +Output no ppub DDS Publisher entity Writer + instance +=========== ========= ======= =========================== ==================== + + +Publisher Block Parameters +************************** + +.. figure:: images/publisher_block_parameters.png + :alt: Publisher Block Parameters + +Ports Tab +========= +The **Ports** tab allows the user to toggle on or off optional ports. + +QoS Tab +======= +The **QoS** tab is used to set the QoS profile. By default, the OSPL default profile is used. + +In DDS - The Data-Distribution Service (DDS) relies on the usage of QoS. A QoS (Quality of Service) is a set of characteristics that controls some aspect of the behavior of the DDS Service. + +Each DDS block has an associated QoS profile. By default, the OSPL default profile is used. An XML file that specifies QoS profiles can be used to set the QoS of a DDS block. + diff --git a/build/docs/DDSSimulinkGuide/source/qos_provider.rst b/build/docs/DDSSimulinkGuide/source/qos_provider.rst new file mode 100644 index 000000000..191e69174 --- /dev/null +++ b/build/docs/DDSSimulinkGuide/source/qos_provider.rst @@ -0,0 +1,101 @@ +.. _`QoS Provider`: + + +############ +QoS Provider +############ + +Each Vortex DDS block has a QoS that can be set using the **Block Parameters**. + +The following section explains how the QoS is set for a DDS entity using the QoS Provider. + + +QoS Provider File +***************** + +Quality of Service for DDS entities is set using XML files based on the XML schema file DDS_QoSProfile.xsd. +These XML files contain one or more QoS profiles for DDS entities. An example with a default QoS profile +for all entity types can be found at DDS_DefaultQoS.xml_. + +**Note:** Sample QoS Profile XML files can be found in the examples directories. + +QoS Profile +*********** + +A QoS profile consists of a name. The file contains QoS +elements for one or more DDS entities. A skeleton file without any QoS values is displayed below to show +the structure of the file. + + +.. code-block:: xml + + + + + + + + + + + + +**Example: Specify Publisher Partition** + +The example below specifies the publisher's partitions as A and B. + +.. code-block:: xml + + + + + A + B + + + + + +Setting QoS Profile in Simulink +******************************* +QoS profiles are set using the Simulink block's parameters dialog under the QoS tab. If the +QoS File parameter is set to None the default QoS settings will be used. The Reset button sets +the parameters to the default values. + +.. figure:: images/default_qos_params.png + :alt: Default QoS Provider Parameters + +A QoS Provider file can be selected by browsing to the XML file. Once the file is chosen the +file name is displayed and the user is presented with a drop down list of all QoS Providers in +the file. + +.. figure:: images/persistent_qos_params.png + :alt: DDS User Selected QoS Provider Parameters + + +**Note:** Seeing the QoS Profile in the drop down list only guarantees the QoS Profile exists in the file. +It does not mean the qos tag exists for the entity. The user is responsible for verifying the entity qos +tag exists in the file. + +.. raw:: latex + + \newpage + +Simulink block annotations are visible by default to display the QoS File Name and the QoS Profile settings. + +.. figure:: images/sub_annotations_qos.png + :alt: QoS File and Profile annotations + +Known Limitations +***************** + +See `QoS Provider Known Limitations <../qos_provider.html#KnownLimitations>`_ for a list of limitations +on QoS Provider support. + +.. external links +.. _QoSProfile.xsd: http://www.omg.org/spec/dds4ccm/20110201/DDS_QoSProfile.xsd +.. _DDS_DefaultQoS.xml: http://www.omg.org/spec/dds4ccm/20110201/DDS_DefaultQoS.xml + + + diff --git a/build/docs/DDSSimulinkGuide/source/reader.rst b/build/docs/DDSSimulinkGuide/source/reader.rst new file mode 100755 index 000000000..aff83602c --- /dev/null +++ b/build/docs/DDSSimulinkGuide/source/reader.rst @@ -0,0 +1,124 @@ +.. _`Reader Block`: + + + +############ +Reader Block +############ + +The Reader block represents a DDS data reader entity. + +In DDS - "To access the received data, the application must use a typed DataReader attached to the subscriber." + + +.. figure:: images/reader_block.png + :alt: DDS Reader Block + + + +=========== ========= ============= =========================== ==================== + Port Type Optional Name Description Output consumed by +=========== ========= ============= =========================== ==================== +Input yes psub DDS Subscriber + entity instance +Input no topic DDS Topic entity instance +Output yes status 0 for successful reader + creation +Output no data BUS user +Output yes info BUS user +Output yes samples read Number of samples read user +=========== ========= ============= =========================== ==================== + +.. raw:: latex + + \newpage + +Reader Block Parameters +*********************** + + +.. figure:: images/reader_block_parameters.png + :alt: Reader Block Parameters + +Data Tab +======== +The **Data** tab is used to set: + +- Bus Type + + The output data type (BUS) for the **data** output port + +- Mode: take or read + + Specify whether the reader block is accessing the samples using DDS take or DDS read. + +- Sample Time + + "The sample time of a block is a parameter that indicates when, during simulation, the block produces outputs and if appropriate, updates its internal state." -Simulink documentation + + Default is -1, meaning it will inherit the Simulink sample time from inputs or the model. + Valid values: -1 and Numeric > 0 + +- Bus Width + + The bus width is the maximum number of samples that can be read or take(n) per block step. + Valid values for the bus width are: integers >= 1. + +.. raw:: latex + + \newpage + +- Wait for + + Checking the Historical Data field in the Wait for section specifies that the Reader will wait for historical data to arrive. The Timeout field is for setting time period (in seconds) determining how long the Reader should wait for the historical data. + If the timeout is reached, then any remaining historical data may be interleaved with new data. + + The Data Available field is for specifying whether the Reader should read only if the data is available. The following Timeouts field determines how long the Reader should wait for the availability of data. + If the timeout is reached, then the block returns no data and the simulation continues. + +Ports Tab +========= +The **Ports** tab allows the user to toggle on or off optional ports. + +QoS Tab +======= +The **QoS** tab is used to set the QoS profile. By default, the OSPL default profile is used. + +In DDS - The Data-Distribution Service (DDS) relies on the usage of QoS. A QoS (Quality of Service) is a set of characteristics that controls some aspect of the behavior of the DDS Service. + +Each DDS block has an associated QoS profile. By default, the OSPL default profile is used. An XML file that specifies QoS profiles can be used to set the QoS of a DDS block. + +.. raw:: latex + + \newpage + +Filters Tab +=========== + +The filters tab allows for the filtering of incoming samples. +The filtering can happen based on a query and/or on a sample read condition(s). + +**Query** + +Expression: The expression is a SQL condition. + +Parameters: N parameters in the format {'a', 'b'} +Each parameter element must be a char array (string). + +*Note: Query expressions are only validated at runtime.* + + +**Read Condition** + +The read conditions specified will filter the samples that are read or take(n). + +Example: For a reader, the Sample State has **Read** selected and **Not Read** deselected. + +Only samples with a Sample State **Read** will be processed with read or take. +Any samples with the **Not Read** sample state will not be read or take(n). + +*Note: At least one read condition must be selected for each category of Sample State, View State, or Instance State. +If not, an error will be thrown when a diagram simulation is run.* + +.. figure:: images/reader_filters_tab.png + :alt: Reader Block Parameters : Filters diff --git a/build/docs/DDSSimulinkGuide/source/simulink_coder.rst b/build/docs/DDSSimulinkGuide/source/simulink_coder.rst new file mode 100644 index 000000000..68feb66fe --- /dev/null +++ b/build/docs/DDSSimulinkGuide/source/simulink_coder.rst @@ -0,0 +1,100 @@ +.. _`Generating C code with Simulink Coder`: + +##################################### +Generating C code with Simulink Coder +##################################### + +The Vortex DDS Blockset for Simulink supports Simulink Coder generation of C code, if you have a Simulink Coder license from MathWorks. + +Prerequisites for C generation +****************************** + +In order to generate and compile C code containing DDS blocks, you must: + +* Have Simulink Coder and MATLAB Coder installed and licensed from MathWorks. +* You have an appropriate C compile installed, as described by the MATLAB documentation. +* Vortex OpenSplice must be installed, and the appropriate ``release.com`` (Linux) or ``release.bat`` (Windows) script must have been executed in a command window. +* MATLAB must have been started from the same command window. You can check this by running the MATLAB command ``getenv('OSPL_HOME')``. It should return a non-empty value. +* Your Simulink mode should execute correctly in simulation mode. + +Preparing for C generation +************************** + +Once your model has been validated via simulation mode, you are ready to generate and compile code. +Because of an issue with the OpenSplice C99 language headers, you must manualy change the code generation options for your model. +Follow these steps: + +- From the model's menu, choose **Code > C/C++ Code > Code Generation Options**. +- Click on the **Code Generation** tab in the left-hand pane. +- In the **Build Configurations** drop-down, choose **Specify**. +- In the table that appears below this, edit the **Options** value in the **C Compiler** row to remove the text **$(ANSI_OPTS)**. +- Click **OK** or **Apply** to save your changes, then close the Code Generation Options dialog. + +See the image, below, for an example of the code generation dialog. + +.. figure:: images/linuxCodeGenNoANSI_OPTS.png + :alt: Removing $(ANSI_OPTS) from C Compiler options + + C/C++ Code Generation Options. Remove the text $(ANSI_OPTS) for C Compiler to avoid compile errors. + +Generating code +*************** + +At least from the Vortex DDS Blockset point of view, you are ready to generate code. Follow these steps: + +- From the model's menu, choose **Code > C/C++ Code > Build Model**. +- Simulink will get busy. You may see the following warnings in the Diagnostic View. These are OK, but are explained below. + +**Domain Participant Warning** + +A warning may appear about the domain participant block:: + + Source 'SimpleDomain/Domain/Participant_Entity ' specifies that its sample time (-1) + is back-inherited. You should explicitly specify the sample time of sources. You can + disable this diagnostic by setting the 'Source block specifies -1 sample time' + diagnostic to 'none' in the Sample Time group on the Diagnostics pane of the + Configuration Parameters dialog box. + + Component:Simulink | Category:Blockwarning + +As the message states, this is because the block specifies a sample time of -1. The block only creates meaningful output on initialization (it connects to DDS), +so any inherited sample time is sufficient. Specifying a sample time of -1 allows the block to be place into a function-call subblock. + +**Full header search warning** + +The following warning about reverting to full header searches may appear:: + + The following error occurred while attempting to run the preprocessor to find the + minimum needed set of include files: + + While parsing the source file '/source/debug_utils.c' the following error + occurred + + /source/debug_utils.c:14: cannot open source file "os_stdlib.h" + | #include "os_stdlib.h" + | ^ + + Reverting to full header search. + +This may occur as you are trying to package code from compilation on another platform. The referenced header file is part of the OpenSplice distrubution. +When you compile on another platform, you will need to have that platform's OpenSplice distribution installed, and ``release`` variables set. The warning may be ignored. + +**Copy File information messages** + +If you are creating a source distrubution, you may see information messages such as the following:: + + cp: cannot stat ‘/libdcpsc99’: No such file or directory + +The build is attempting to copy OpenSplice shared libraries (which are refered to via environment variables). These should not be copied by the build. Instead, when you +compile the source on a target platform, these libraries will be found in the local OpenSplice installation. + +Running built models +******************** + +When you run a compiled Simulink executable, you will need: + +* An appropriate OpenSplice runtime installation on the machine executing the model +* The correct OpenSplice environment variables, which are set by the ``release`` script in the installation root directory. + + + diff --git a/build/docs/DDSSimulinkGuide/source/subscriber.rst b/build/docs/DDSSimulinkGuide/source/subscriber.rst new file mode 100755 index 000000000..8ce520f64 --- /dev/null +++ b/build/docs/DDSSimulinkGuide/source/subscriber.rst @@ -0,0 +1,47 @@ +.. _`Subscriber Block`: + + + +################ +Subscriber Block +################ + +The Subscriber block represents a DDS subscriber entity. + +In DDS, a subscriber is "an object responsible for receiving published data and making it available to the receiving application. It may receive and dispatch data of different specified types." + +This block is optional on a DDS Simulink model diagram. If it is not present on a model diagram, each reader will create its own default subscriber. + + +.. figure:: images/subscriber_block.png + :alt: DDS Subscriber Block + + +=========== ========= ======= =========================== ==================== + Port Type Optional Name Description Output consumed by +=========== ========= ======= =========================== ==================== +Input yes pp DDS Domain Participant + entity instance +Output no psub DDS Subscriber entity Reader + instance +=========== ========= ======= =========================== ==================== + + +Subscriber Block Parameters +*************************** + +.. figure:: images/subscriber_block_parameters.png + :alt: Subscriber Block Parameters + +Ports Tab +========= +The **Ports** tab allows the user to toggle on or off optional ports. + +QoS Tab +======= +The **QoS** tab is used to set the QoS profile. By default, the OSPL default profile is used. + +In DDS - The Data-Distribution Service (DDS) relies on the usage of QoS. A QoS (Quality of Service) is a set of characteristics that controls some aspect of the behavior of the DDS Service. + +Each DDS block has an associated QoS profile. By default, the OSPL default profile is used. An XML file that specifies QoS profiles can be used to set the QoS of a DDS block. + diff --git a/build/docs/DDSSimulinkGuide/source/topic.rst b/build/docs/DDSSimulinkGuide/source/topic.rst new file mode 100755 index 000000000..b25d5af6f --- /dev/null +++ b/build/docs/DDSSimulinkGuide/source/topic.rst @@ -0,0 +1,51 @@ +.. _`Topic Block`: + + + +########### +Topic Block +########### + +The topic block represents a DDS topic type. The DDS topic corresponds to a single data type. In DDS, data is distributed by publishing and subscribing topic data samples. + +For a DDS Topic type definition, a corresponding BUS should be defined in the MATLAB workspace. The name of the BUS and the fields and field types should correspond to the DDS topic IDL definition. + +In Simulink, a BUS definition can be used as an input or output signal of the Simulink building blocks. + + +.. figure:: images/topic_block.png + :alt: DDS Topic Block + + + +=========== ========= ======= =========================== ==================== + Port Type Optional Name Description Output consumed by +=========== ========= ======= =========================== ==================== +Input yes pp DDS Domain Participant + entity instance +Output no topic DDS Topic entity instance Writer, Reader +=========== ========= ======= =========================== ==================== + + +Topic Block Parameters +********************** + +.. figure:: images/topic_block_parameters.png + :alt: Topic Block Parameters + +Topic Tab +========= +The output port named **topic**, needs to be configured by the user. No defaults are provided. To configure the **topic** output port, edit the required parameters in the **Block Parameters / Topic** tab. The following topic parameters must be specified: **Bus Type** and **Topic Name**. + +Ports Tab +========= +The **Ports** tab allows the user to toggle on or off optional ports. + +QoS Tab +======= +The **QoS** tab is used to set the QoS profile. By default, the OSPL default profile is used. + +In DDS - The Data-Distribution Service (DDS) relies on the usage of QoS. A QoS (Quality of Service) is a set of characteristics that controls some aspect of the behavior of the DDS Service. + +Each DDS block has an associated QoS profile. By default, the OSPL default profile is used. An XML file that specifies QoS profiles can be used to set the QoS of a DDS block. + diff --git a/build/docs/DDSSimulinkGuide/source/troubleshooting.rst b/build/docs/DDSSimulinkGuide/source/troubleshooting.rst new file mode 100644 index 000000000..696e9849a --- /dev/null +++ b/build/docs/DDSSimulinkGuide/source/troubleshooting.rst @@ -0,0 +1,33 @@ +.. _`Troubleshooting`: + + +############### +Troubleshooting +############### + +**When double clicking on a DDS block to view the block parameters, an error dialog is shown with the message: Error evaluating 'MaskDialog' callback of SubSystem block (mask).** + +*Cause: The OSPL environment variables have not been setup correctly.* + +*Solution: Open a command shell and run the script to setup OSPL environment variables.* + + Linux + + - Open a Linux terminal. + + - Navigate to directory containing release.com file. + + */INSTALLDIR/ADLINK/Vortex_v2/Device/VortexOpenSplice/6.8.x/HDE/x86_64.linux* + + - Run release.com. (Type in “. release.com†at command line.) + + + Windows + + - Open a command prompt. + + - Navigate to directory containing release.bat file. + + *INSTALLDIR/ADLINK/Vortex_v2/Device/VortexOpenSplice/6.8.x/HDE/x86_64.win64* + + - Run release.bat. (Type in “release.bat†at command line.) diff --git a/build/docs/DDSSimulinkGuide/source/tutorial.rst b/build/docs/DDSSimulinkGuide/source/tutorial.rst new file mode 100644 index 000000000..dfc0dc734 --- /dev/null +++ b/build/docs/DDSSimulinkGuide/source/tutorial.rst @@ -0,0 +1,692 @@ +.. _`Tutorial`: + + +######## +Tutorial +######## + +To demonstrate the capabilities of the DDS Simulink Integration, this tutorial will create two Simulink models. One model will write DDS samples, and the second model will read the DDS samples. + +Both models will be run simultaneously, and use a DDS system for communication. + +A Simulink bus named ShapeType is created as part of this tutorial. The bus can be created by either using the Simulink bus editor, or by generation from an IDL file. +Both options are covered in this tutorial. + + +Create ShapeType Bus Using Simulink Bus Editor +********************************************** + +Buses define the data which will be published and read. Both the read and write Simulink models will make use of a bus to read and write sample data. + +For this tutorial, we will create a BUS named **ShapeType**. + +Open the bus editor from the MATLAB command window +================================================== + +.. figure:: images/openBusEditor.png + :alt: Open Bus Editor + +Add a new BUS named ShapeType +============================= + +Select Add Bus button +--------------------- + +.. figure:: images/addBus.png + :alt: Add Bus + +Set Bus name and Key +------------------------- + +- Set the new bus name to: **ShapeType**. +- Set Description to: @Key(color). This sets the Topic key. +- Select **Apply** button to save. + +.. figure:: images/addShapeType.png + :alt: Bus Name + +Note: If the Key is not set, the topic block's Key annotation in the model will be shown empty and it will result in a keyless topic. Keyless topics have only one instance. + + +Add BusElements +=============== + +The **ShapeType** bus will have 4 bus elements: color, x, y and shapesize. + +A BusElement can be added to the ShapeType bus by selecting the **Add/Insert BusElement** button. + +.. figure:: images/addBusElement.png + :alt: Add/Insert BusElement + +A BusElement can be moved up or down using the **Move Element Up** and **Move Element Down** buttons. + +.. figure:: images/upDownBusElement.png + :alt: Move Element + +.. raw:: latex + + \newpage + +Add color +--------- + +- Select **Add/Insert BusElement** button +- Set name to: color +- Set DataType to: uint8 +- Set Dimensions to: 10 +- Set Description to: @String +- Select **Apply** to save + +.. figure:: images/colorBusElement.png + :alt: BusElement color + +Note: This creates a DDS 'string' type. Bus elements of type 'int8' or 'uint8' with an annotation of @String in the Description field define a DDS string. Dimension set to 10 means Simulink is going to read only the first ten bytes of the string. You can also use the '\@BString' annotation to define a DDS bounded string. The dimension of the field is treated as the maximum string size. + +.. raw:: latex + + \newpage + +Add x +----- + +- Select **Add/Insert BusElement** button +- Set name to: x +- Set DataType to: int32 +- Select **Apply** to save + +.. figure:: images/xBusElement.png + :alt: BusElement x + +Add y +----- + +- Select **Add/Insert BusElement** button +- Set name to: y +- Set DataType to: int32 +- Select **Apply** to save + +.. figure:: images/yBusElement.png + :alt: BusElement y + +.. raw:: latex + + \newpage + +Add shapesize +------------- + +- Select **Add/Insert BusElement** button +- Set name to: shapesize +- Set DataType to: int32 +- Select **Apply** to save + +.. figure:: images/shapesizeBusElement.png + :alt: BusElement shapesize + + +Export BUS objects +================== + +When bus objects are added to the MATLAB workspace, they will be lost on MATLAB close or workspace clear. To persist the bus objects, they can be exported. + +A quick way to export the **ShapeType** bus using the bus editor, is to right click on the bus and select **Export ShapeType to File…** + +.. figure:: images/busExport.png + :alt: export bus + +The **ShapeType** bus is complete. + + +Create ShapeType Using IDL +**************************** + +The public Vortex.idlImportSl function can be called to generate Simulink bus definitions from an IDL file. +The generated bus definitions are inserted into the 'Design Data' section of a data dictionary. + +From the Simulink documentation - + *"A data dictionary is a persistent repository of data that are relevant to your model. You can also use the base workspace to store design data that are used by your model during simulation."* + +The data dictionary can then be referenced from your models. + + +Create IDL File +=============== + +Create an IDL file to define your ShapeType topic structure. For this tutorial we will name the file *ShapeType.idl*. + +.. code-block:: idl + + struct ShapeType { + string color; //@Key + long x; + long y; + long shapesize; + }; + #pragma keylist ShapeType color + +IMPORTANT NOTE: The IDL file has to have a blank line after the pragma keylist declaration. (known bug) + + +Generate Simulink bus definitions from an IDL file +================================================== + +Steps: + +1. In MATLAB, navigate to the directory that contains the *ShapeType.idl* file. Set this directory to be the MATLAB **Current Folder**. + +2. Call the idlImportSl function in the MATLAB command window. + + >> Vortex.idlImportSl('ShapeType.idl', 'shape.sldd') + + where: + + 'ShapeType.idl' is the name of the IDL file + + 'shape.sldd' is the name of the target data dictionary for the generated bus definitions + +.. raw:: latex + + \newpage + +Model Explorer +============== + +To make use of the bus definitions generated into the data dictionary, Simulink models can specify design data using the **Model Explorer**. + +.. figure:: images/modelExplorer.png + :alt: Model Explorer Design Data + + +Shapes Write Model +****************** + +This section outlines how to create a new DDS Simulink model that will write sample data for the topic type **ShapeType**. + +Although not necessary, this model will use the optional Domain and Publisher blocks. + +Create a new Simulink model +=========================== + +Start Simulink +-------------- + +.. figure:: images/startSimulink.png + :alt: Start Simulink + +.. raw:: latex + + \newpage + +Add a new blank model +--------------------- + +.. figure:: images/simulinkStartPage.png + :alt: Start Add new blank model + +Save As... +---------- + +- Save the model as *“shapes_write_model.slxâ€*. + +.. raw:: latex + + \newpage + +Model Settings +-------------- + +- Open Model Configuration Parameters dialog, by selecting menu **Simulation / Model Configuration Parameters**. + +- Set the simulation stop time to 1000.0 seconds. (Note: “Simulation time is not the same as clock time. For example, running a simulation for 10 seconds usually does not take 10 seconds. Total simulation time depends on factors such as model complexity, solver step sizes, and computer speed.†Simulink Help documentation) + +- Set the Solver Type to Fixed-step. + +.. figure:: images/write_model_setup.png + :alt: Model Settings + +Add Simulink DDS Blocks +======================= + +Open the Simulink Library Browser +--------------------------------- + +- Open the Simulink Library Browser + +- Browse to and select **Vortex DDS** to view DDS custom blocks + + +.. figure:: images/openLibraryBrowser.png + :alt: Open Simulink Library Browser + +.. figure:: images/ddsLibrary.png + :alt: Vortex DDS Blocks + +.. raw:: latex + + \newpage + +Add a Domain block +------------------ + +- Drag a Domain participant block from the Simulink Library Browser onto the Simulink model diagram. + +Set domain block properties +--------------------------- + +- To set a block’s parameters, double click on the block to bring up the **Block Parameters** dialog. +- The domain id is read only and set to DDS_DOMAIN_DEFAULT. This default is specified in the OSPL configuration file. +- The **QoS** tab defaults to the OSPL defaults. +- For this tutorial example, we are going to use the defaults, therefore no block parameters need to be specified. + +.. figure:: images/write_domain_parameters.png + :alt: Domain Block Parameters + + +Add blocks (Topic, Publisher, and Writer) +----------------------------------------------------- + +Using the Simulink Library Browser drag the following block types onto your diagram: + - 1 Topic + - 1 Publisher + - 1 Writer + +.. raw:: latex + + \newpage + +Connect Domain to Topic and Publisher +------------------------------------- + +- Connect the Domain **pp** output to Topic **pp** input. +- Connect the Domain **pp** output to Publisher **pp** input. + +.. figure:: images/write_connect_domain.png + :alt: Connecting participant ports + +.. raw:: latex + + \newpage + +Set Topic Block Parameters +-------------------------- + +- Double click on the Topic to bring up the **Block Parameters** dialog. +- In the **Topic** tab: + - Set **Bus Type** to: ShapeType + - Set **Topic Name** to: Circle +- The **Ports** tab allows for the setting of optional ports. For this model, we will not change the defaults. +- Select the **QoS** tab. +- Set the QoS file to: Shapes_Demo_QoS.xml. + /INSTALLDIR/ADLINK/Vortex_v2/Device/VortexOpenSplice/6.8.x/HDE/x86_64.linux/tools/matlab/ + /examples/simulink/dds_reader_writer_model/Shapes_Demo_QoS.xml + + +.. figure:: images/write_topic_parameters.png + :alt: Set Topic Block Parameters + + +.. raw:: latex + + \newpage + +Connect Topic, Publisher and Writer Blocks & Set Writer Block Parameters +------------------------------------------------------------------------ + +- Connect the Topic **topic** output to the Writer **topic** input. +- Connect the Publisher **ppub** output to the Writer **ppub** input. + +- Double click on the Writer block to edit the **Block Parameters**. Set the **Input Data Type** to the bus: ShapeType. +- Select the Writer **QoS** tab. +- Set the QoS file to: Shapes_Demo_QoS.xml. + + - /INSTALLDIR/ADLINK/Vortex_v2/Device/VortexOpenSplice/6.8.x/HDE/x86_64.linux/tools/matlab/ + /examples/simulink/dds_reader_writer_model/Shapes_Demo_QoS.xml + + +.. figure:: images/writer_write_parameters.png + :alt: Connect Blocks + + +.. raw:: latex + + \newpage + +Add a Bus Creator to Set Sample Data +------------------------------------ + +To generate sample data, we will add a **Simulink / Signal Routing / BusCreator** block to our diagram. + +.. figure:: images/write_buscreator_params.png + :alt: Set Bus Creator Block Parameters + +Add Bus Creator Inputs +---------------------- + +For demonstration purposes, we will input to the **BusCreator** signals using **Constant**, **Clock** and **Sine Wave** blocks. + +Note: To change the positioning of block ports, you can use the **Rotate & Flip** block menu item, accessible by right clicking on a block. + + - Drag 2 **Simulink / Sources / Constant** blocks onto the diagram + - Connect one **Constant** block to color input signal + - Connect one **Constant** block to shapesize input signal + +.. figure:: images/buscreator_constants.png + :alt: Bus Creator Constants + +.. raw:: latex + + \newpage + +- Set the **Block Parameters** for color signal **Constant** block +- Set **Constant value** to: uint8(pad('GREEN',10,'right', char( 0 ) )) +- Select **OK** + +.. figure:: images/colorConstant2.png + :alt: color Constant + +.. raw:: latex + + \newpage + +- Set the **Block Parameters** for shapesize signal **Constant** block +- Set **Constant value** to: 25 +- Set **Output data type** to: int32 + +.. figure:: images/shapesizeConstantBLock.png + :alt: shapesize Constant + +- Drag a **Simulink / Sources / Sine Wave** block onto diagram +- Connect **Sine Wave** block to y input signal +- Drag a **Simulink / Signal Attributes / Data Type Conversion** block onto **Sine Wave** connector. +- Set **Output data type** to: int32 + +.. figure:: images/sinewave.png + :alt: Sine Wave y + +.. raw:: latex + + \newpage + +- Set **Block Parameters** for **Sine Wave** block. +- Set **Amplitude** to: 150 +- Set **Bias** to: 175 +- Set **Sample time** to: 0.5 + +.. figure:: images/sineWaveBlockParamters.png + :alt: Sine Wave Block Parameters + +- For the **x** input signal, drag 3 new blocks onto diagram: + - **Simulink / Sources / Constant** + - **Simulink / Sources / Clock** + - **Simulink / Math Operations / Math Function** + +- Set **Block Parameters** for **Math Function** block. +- Set **Function** to: mod +- Set **Output signal type** to: real + +.. figure:: images/write_mathFunctionBlockParams.png + :alt: Math Function Block Parameters + +.. raw:: latex + + \newpage + +- Set **Block Parameters** for **Constant** block. +- Set **Constant value** to: 350 + +.. figure:: images/constant_x.png + :alt: Constant Block Parameters + +- Connect the **Clock** and **Constant** blocks to the mod **Math Function** +- Connect the mod **Math Function** to the **BusCreator** x input signal + +.. figure:: images/modBlock.png + :alt: Connect mod block + + +.. raw:: latex + + \newpage + +- Drag a **Simulink / Signal Attributes / Data Type Conversion** block onto **Math Function** connector. +- Set **Output data type** to: int32 + +.. figure:: images/modBlock2.png + :alt: Connect mod block + + +**Save your model. Your model is now complete!** + + + + + +Shapes Read Model +***************** + +Create a new Simulink model +=========================== + +This section outlines how to create a new DDS Simulink model that will read and display sample data for the topic type **ShapeType**. + +In this model example, we will be making use of many of the defaults, so the optional blocks will not be included in this model. + +.. raw:: latex + + \newpage + +Start Simulink +-------------- + +.. figure:: images/startSimulink.png + :alt: Start Simulink + + +Add a new blank model +--------------------- + +.. figure:: images/simulinkStartPage.png + :alt: Start Add new blank model + +Save As... +---------- + +- Save the model as *“shapes_read_model.slxâ€*. + +.. raw:: latex + + \newpage + +Model Settings +-------------- + +- Open Model Configuration Parameters dialog, by selecting menu **Simulation / Model Configuration Parameters**. + +- Set the simulation stop time to **inf**. (Note: “Specify inf to run a simulation or generated program until you explicitly pause or stop it.†Simulink Help documentation) + +- Set the Solver Type to **Fixed-step**. + +.. figure:: images/read_model_settings.png + :alt: Setup Read Model + +.. raw:: latex + + \newpage + +Add Simulink DDS Blocks +======================= + +Open the Simulink Library Browser +--------------------------------- + +.. figure:: images/ddsLibrary.png + :alt: Vortex DDS Library + +Add all required blocks (Topic and Reader) +------------------------------------------ + +Using the Simulink Library Browser drag the following block types onto your diagram: + - 1 Topic + - 1 Reader + +Note: For this example model, we will be using the block defaults for the Domain and Subscriber, therefore they will not be included on the model. + +To set a block’s parameters, double click on the block to bring up the **Block Parameters** dialog. + +.. figure:: images/read_blocks.png + :alt: Add Blocks + + +Toggle off optional ports +------------------------- + +- Double click on the Topic to bring up the **Block Parameters** dialog. +- In the Topic **Ports** tab deselect the Participant port. + +- Double click on the Reader to bring up the **Block Parameters** dialog. +- In the Reader **Ports** tab deselect the Subscriber, Reader, Status, Info and Samples Read ports. + +.. raw:: latex + + \newpage + +Set Topic Block Parameters +-------------------------- + +- Double click on the Topic to bring up the **Block Parameters** dialog, select **Topic** tab. +- Set the **Bus Type**: ShapeType bus + Note: If the ShapeType bus is not displayed, select Refresh data types from dropdown list. +- Set the **Topic Name** to: Circle. + +.. figure:: images/read_topic_topic.png + :alt: Topic Block Parameters + +- Select the **QoS** tab. +- Set the QoS file to : Shapes_Demo_QoS.xml. + INSTALLDIR/ADLINK/Vortex_v2/Device/VortexOpenSplice/6.8.x/HDE/x86_64.linux/tools/matlab/ + examples/simulink/dds_reader_writer_model/Shapes_Demo_QoS.xml + +Set Reader Block Parameters +--------------------------- + +- Double click on the Reader block to edit the **Block Parameters**. Set the **Input Data Type** to the bus: ShapeType. +- Select the **QoS** tab. +- Set the QoS file to : Shapes_Demo_QoS.xml. + INSTALLDIR/ADLINK/Vortex_v2/Device/VortexOpenSplice/6.8.x/HDE/x86_64.linux/tools/matlab/ + examples/simulink/dds_reader_writer_model/Shapes_Demo_QoS.xml + +.. raw:: latex + + \newpage + +Connect Topic and Reader +------------------------ + +- Connect the Topic block **topic** output to the Reader block **topic** input. + +.. figure:: images/read_connect.png + :alt: Connect Topic and Reader + + +Add a Bus Selector to read and display sample data +-------------------------------------------------- + +To read and display sample data, we will add a **Simulink / Signal Routing / Bus Selector** block to our diagram. + +Set Bus Selector Block Parameters +--------------------------------- + +Specify the output signals we would like to display in our simulation. For this example, we will display all the ShapeType BUS signals in the running simulation. + +- Connect the Reader **data** output to the **Bus Selector**. +- Double click on the **Bus Selector** block to edit the **Block Parameters**. +- Add all the signals in the bus to the **Selected signals**. + +.. figure:: images/read_busSelectorOutputs.png + :alt: Bus Selector Block Parameters + +.. raw:: latex + + \newpage + +Add Bus Selector outputs +------------------------ + +For demonstration purposes, we will output the bus signals using 2 Simulink **Display** blocks and an **XY Graph**. + +Note: To change the positioning of block ports, you can use the **Rotate & Flip** block menu item, accessible by right clicking on a block. + +- Drag 2 **Simulink / Sinks / Display** blocks onto the diagram. +- Connect the **Display** blocks to the **Bus Selector** output signals. + - Connect the Bus Selector color output signal to a Display block. + - Connect the Bus Selector shapesize output signal to a Display block. + +Note: Default Display block settings used. + +.. figure:: images/read_busSelector_display.png + :alt: Bus Selector Outputs + +.. raw:: latex + + \newpage + +- Drag **Simulink / Sinks / XY Graph** block onto diagram +- Connect the **BusSelector** x and y outputs to the **XY Graph** block. +- Set the Block Parameters on the **XY Graph**: + X-min: 0 + X-max: 400 + Y-min: 0 + Y-max: 400 + +.. figure:: images/xyGraph2.png + :alt: Bus Selector XY Graph + + +**Save your model!!! The model is now complete!** + + +.. raw:: latex + + \newpage + +Running Simulations +******************* + +We now have two Simulink models. We will run both models and see that data samples are being written by one model and read be the second model. + +Setup Write Model +================= + +1. Open shapes_write_model.slx. +2. Select menu item **Simulation / Update Diagram** to diagnose any possible model problems. +3. Fix any issues. + +Setup Read Model +================ + +1. Open shapes_read_model.slx. +2. Select menu item **Simulation / Update Diagram** to diagnose any possible model problems. +3. Fix any issues. + +Run Simulations +=============== + +1. Position models side by side. +2. Start the read model simulation. +3. Start the write model simulation. +4. Expected: The write model will write samples, that are received by the read model and displayed in that model’s **XY Graph** and **Display** blocks. +5. The write model will run to completion. The read model needs to be stopped manually. + +.. figure:: images/run.png + :alt: Run Simulations + +.. raw:: latex + + \newpage + +**Run Results** + +.. figure:: images/results.png + :alt: Run results + + diff --git a/build/docs/DDSSimulinkGuide/source/writer.rst b/build/docs/DDSSimulinkGuide/source/writer.rst new file mode 100755 index 000000000..173391afd --- /dev/null +++ b/build/docs/DDSSimulinkGuide/source/writer.rst @@ -0,0 +1,69 @@ +.. _`Writer Block`: + + + +############ +Writer Block +############ + +The Writer block represents a DDS data writer entity. + +In DDS - "The DataWriter is the object the application must use to communicate to a publisher the existence and value of data-objects of a given type." + +.. figure:: images/writer_block.png + :alt: DDS Writer Block + + +=========== ========= =============== =========================== ==================== + Port Type Optional Name Description Output consumed by +=========== ========= =============== =========================== ==================== +Input yes ppub DDS Publisher + entity instance +Input no topic DDS Topic entity instance +Input no data BUS +Input yes action 0 write, + 1 dispose, + 2 write dispose, + 3 no operation +Output yes status 0 for successful writer + creation +Output yes samples written Number of samples written User +=========== ========= =============== =========================== ==================== + +.. raw:: latex + + \newpage + +Writer Block Parameters +*********************** + + +.. figure:: images/writer_block_parameters.png + :alt: Writer Block Parameters + +Data Tab +======== +The **Data** tab is used to set the input data type (BUS) for the **data** input port and the **bus width**. + +The bus width is the maximum number of samples that can be written per block step. +The user must configure the source blocks that feed the Writer's data port so that it produces an array of the right size. + +Valid values for the bus width are: integers >= 1. + +The Reader Available field in the Wait for section is used for specifying if the Writer should wait for the Reader to become available. +The associated Timeout field is to specify how long (in seconds) the Writer should wait for the Reader to become available. + +The Write after timeout field can only be enabled when the Reader Available field is checked. It specifies if the Writer should write after the Wait for Reader Available timeout. + +Ports Tab +========= +The **Ports** tab allows the user to toggle on or off optional ports. + +QoS Tab +======= +The **QoS** tab is used to set the QoS profile. By default, the OSPL default profile is used. + +In DDS - The Data-Distribution Service (DDS) relies on the usage of QoS. A QoS (Quality of Service) is a set of characteristics that controls some aspect of the behavior of the DDS Service. + +Each DDS block has an associated QoS profile. By default, the OSPL default profile is used. An XML file that specifies QoS profiles can be used to set the QoS of a DDS block. + diff --git a/build/docs/DDSTutorial/source/appendix-A.rst b/build/docs/DDSTutorial/source/appendix-A.rst index adfe0ead6..7b963bcac 100644 --- a/build/docs/DDSTutorial/source/appendix-A.rst +++ b/build/docs/DDSTutorial/source/appendix-A.rst @@ -27,16 +27,16 @@ Getting a DDS Implementation At the time of writing, the only open source DDS implementation that supports the new ISO C++ API is *Vortex OpenSplice*, which -is freely available at http://www.opensplice.org. +is freely available at http://ist.adlinktech.com/dds-community. Commercial versions of Vortex OpenSplice and Vortex Lite are also available -which support the ISO C++ API from http://prismtech.com/vortex. +which support the ISO C++ API from http://vortex.adlinktech.com. C++11 Considerations ==================== Although some of the examples in this Tutorial take advantage of C++11, -the new C++ API can also be used with C++03 compilers. That said, if +the new C++ API can also be used with C++03 compilers. That said, if you have the opportunity to use a C++11 compiler, then there are some additional aspects of the language that can be enabled. diff --git a/build/docs/DDSTutorial/source/code/isocpp2/ch1/README.html b/build/docs/DDSTutorial/source/code/isocpp2/ch1/README.html index 47d05a401..fe713a11d 100644 --- a/build/docs/DDSTutorial/source/code/isocpp2/ch1/README.html +++ b/build/docs/DDSTutorial/source/code/isocpp2/ch1/README.html @@ -6,7 +6,7 @@

Compiling the example

Once you have installed the required tools simply do:

 $ cmake .
diff --git a/build/docs/DDSTutorial/source/code/isocpp2/ch1/README.md b/build/docs/DDSTutorial/source/code/isocpp2/ch1/README.md
index 241968a3d..c45374fc4 100644
--- a/build/docs/DDSTutorial/source/code/isocpp2/ch1/README.md
+++ b/build/docs/DDSTutorial/source/code/isocpp2/ch1/README.md
@@ -1,4 +1,4 @@
-## Chapter 1 Code Example 
+## Chapter 1 Code Example
 
 This folder contains the full source for the example shown in the
 first chapter of the tutorial.
@@ -12,7 +12,7 @@ To compile the example you need:
 
    - g++ v4.6 or higher (clang++ would also be fine)
    - CMake v2.6 or higher
-   - [OpenSplice DDS](http://www.opensplice.org) v6.4 or higher
+   - [DDS Community Edition](http://ist.adlinktech.com/dds-community) v6.7 or higher
 
 Once you have installed the required tools simply do:
 
@@ -25,7 +25,7 @@ Once you have installed the required tools simply do:
 
 To run the examples do:
 
-   $ ./tspub 
+   $ ./tspub
    USAGE:
 	 tspub 
 
diff --git a/build/docs/DDSTutorial/source/code/isocpp2/ch2/README.html b/build/docs/DDSTutorial/source/code/isocpp2/ch2/README.html
index 9ab1b5f8c..61bbd8561 100644
--- a/build/docs/DDSTutorial/source/code/isocpp2/ch2/README.html
+++ b/build/docs/DDSTutorial/source/code/isocpp2/ch2/README.html
@@ -16,7 +16,7 @@ 

Compiling the example

Once you have installed the required tools simply do:

 $ cmake .
@@ -26,7 +26,7 @@ 

Running the Examples

 $ ./tspub 0

This will start producing data.

Then start the consumer:

-
 $ ./tssub 
+
 $ ./tssub
  USAGE:
 tssub <filter-expression>

Where the filter-expression should have the same syntax of a SQL WHERE clause. For instance, if you were interested in getting the data only when the temperature was higher than 28.0 C and the humidity higher than 0.65 then you could run the application as follows:

diff --git a/build/docs/DDSTutorial/source/code/isocpp2/ch2/README.md b/build/docs/DDSTutorial/source/code/isocpp2/ch2/README.md index 4f1bdfbd5..9540ad364 100644 --- a/build/docs/DDSTutorial/source/code/isocpp2/ch2/README.md +++ b/build/docs/DDSTutorial/source/code/isocpp2/ch2/README.md @@ -1,4 +1,4 @@ -## Chapter 1 Code Example +## Chapter 1 Code Example This folder contains the full source for the example shown in the first chapter of the tutorial. @@ -12,7 +12,7 @@ To compile the example you need: - g++ v4.6 or higher (clang++ would also be fine) - CMake v2.6 or higher - - [OpenSplice DDS](http://www.opensplice.org) v6.4 or higher + - [DDS Community Edition](http://ist.adlinktech.com/dds-community) v6.7 or higher Once you have installed the required tools simply do: @@ -31,7 +31,7 @@ This will start producing data. Then start the consumer: - $ ./tssub + $ ./tssub USAGE: tssub diff --git a/build/docs/DDSTutorial/source/code/isocpp2/cmake/FindOpenSplice.cmake b/build/docs/DDSTutorial/source/code/isocpp2/cmake/FindOpenSplice.cmake index 02df5368f..24c83211e 100644 --- a/build/docs/DDSTutorial/source/code/isocpp2/cmake/FindOpenSplice.cmake +++ b/build/docs/DDSTutorial/source/code/isocpp2/cmake/FindOpenSplice.cmake @@ -66,10 +66,10 @@ IF (OpenSplice_INCLUDE_DIRS AND OpenSplice_LIBRARIES) ENDIF (OpenSplice_INCLUDE_DIRS AND OpenSplice_LIBRARIES) IF (OpenSplice_FOUND) - MESSAGE(STATUS "Found OpenSplice DDS libraries: ${OpenSplice_LIBRARIES}") + MESSAGE(STATUS "Found Vortex OpenSplice libraries: ${OpenSplice_LIBRARIES}") ELSE (OpenSplice_FOUND) IF (OpenSplice_FIND_REQUIRED) - MESSAGE(FATAL_ERROR "Could not find OpenSplice DDS") + MESSAGE(FATAL_ERROR "Could not find Vortex OpenSplice") ENDIF (OpenSplice_FIND_REQUIRED) ENDIF (OpenSplice_FOUND) diff --git a/build/docs/DDSTutorial/source/code/isocpp2/cmake/MacroOpenSplice.cmake b/build/docs/DDSTutorial/source/code/isocpp2/cmake/MacroOpenSplice.cmake index b90d62f37..d8f21d97d 100644 --- a/build/docs/DDSTutorial/source/code/isocpp2/cmake/MacroOpenSplice.cmake +++ b/build/docs/DDSTutorial/source/code/isocpp2/cmake/MacroOpenSplice.cmake @@ -1,7 +1,7 @@ ############################################################################## # OpenSplice_IDLGEN(idlfilename) # -# Macro to generate OpenSplice DDS sources from a given idl file with the +# Macro to generate Vortex OpenSplice sources from a given idl file with the # data structures. # You must include the extension .idl in the name of the data file. # diff --git a/build/docs/DDSTutorial/source/conf.py b/build/docs/DDSTutorial/source/conf.py index 7b0efd700..87306ec67 100644 --- a/build/docs/DDSTutorial/source/conf.py +++ b/build/docs/DDSTutorial/source/conf.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # -# OpenSplice DDS Tutorial build configuration file, created by +# Vortex OpenSplice Tutorial build configuration file, created by # ReST Editor on 24-Mar-2015 # # This file is execfile()d with the current directory set to its containing dir. @@ -64,9 +64,8 @@ def setup(app): # General information about the project. project = u'The Data Distribution Service Tutorial' -#copyright = u'2015, PrismTech' this_year = time.strftime( '%Y' ) -copyright = u'{y}, PrismTech'.format( y = this_year ) +copyright = u'{y}, ADLINK Technology Limited'.format( y = this_year ) print 'Copyright string is:', copyright # The version info for the project you're documenting, acts as replacement for @@ -226,7 +225,7 @@ def setup(app): # Note 'author' field empty # Added 'True' to end of generated line to suppress 'Index & Tables' -# A dictionary that contains LaTeX snippets that override those Sphinx usually +# A dictionary that contains LaTeX snippets that override those Sphinx usually # puts into the generated .tex files. latex_elements = { 'babel': '\\usepackage[english]{babel}' } @@ -264,7 +263,7 @@ def setup(app): # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). -man_pages = [('index', 'DDS_Tutorial', u'DDS_Tutorial Documentation', [u'PrismTech'], 1)] +man_pages = [('index', 'DDS_Tutorial', u'DDS_Tutorial Documentation', [u'ADLINK Technology Limited'], 1)] # -- Additional options -------------------------------------------------------- diff --git a/build/docs/DDSTutorial/source/contacts.rst b/build/docs/DDSTutorial/source/contacts.rst index 7f7869976..e5c52db85 100644 --- a/build/docs/DDSTutorial/source/contacts.rst +++ b/build/docs/DDSTutorial/source/contacts.rst @@ -1,48 +1,57 @@ -.. _`Contacts & Notices`: - -################## -Contacts & Notices -################## - -******** -Contacts -******** - -| **PrismTech Corporation** -| 400 TradeCenter -| Suite 5900 -| Woburn, MA -| 01801 -| USA -| Tel: +1 781 569 5819 - -| **PrismTech Limited** -| PrismTech House -| 5th Avenue Business Park -| Gateshead -| NE11 0NG -| UK -| Tel: +44 (0)191 497 9900 - -| **PrismTech France** -| 28 rue Jean Rostand -| 91400 Orsay -| France -| Tel: +33 (1) 69 015354 - - -Web: http://www.prismtech.com - -E-mail: \info@prismtech.com - -******* -Notices -******* - -*This work is made available under a Creative Commons -Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license* -https://creativecommons.org/licenses/by-sa/4.0/legalcode - -The information contained in this document is subject to change without notice and is made available in good faith without liability on the part of PrismTech Limited or PrismTech Corporation. -All trademarks acknowledged. - +.. _`Contacts & Notices`: + +################## +Contacts & Notices +################## + +******** +Contacts +******** + +| **ADLINK Technology Corporation** +| 400 TradeCenter +| Suite 5900 +| Woburn, MA +| 01801 +| USA +| Tel: +1 781 569 5819 + +| **ADLINK Technology Limited** +| The Edge +| 5th Avenue +| Team Valley +| Gateshead +| NE11 0XA +| UK +| Tel: +44 (0)191 497 9900 + +| **ADLINK Technology SARL** +| 28 rue Jean Rostand +| 91400 Orsay +| France +| Tel: +33 (1) 69 015354 + + +Web: http://ist.adlinktech.com/ + +Contact: http://ist.adlinktech.com/ + +E-mail: \ist_info@adlinktech.com + +LinkedIn: https://www.linkedin.com/company/79111/ + +Twitter: https://twitter.com/ADLINKTech_usa + +Facebook: https://www.facebook.com/ADLINKTECH + +******* +Notices +******* + +*This work is made available under a Creative Commons +Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license* +https://creativecommons.org/licenses/by-sa/4.0/legalcode + +*This document may be reproduced in whole but not in part. The information contained in this +document is subject to change without notice and is made available in good faith without +liability on the part of ADLINK Technology Limited. All trademarks acknowledged.* diff --git a/build/docs/DDSTutorial/source/images/Vortex-Cover.png b/build/docs/DDSTutorial/source/images/Vortex-Cover.png index 3e0a7596f..d82d6b313 100644 Binary files a/build/docs/DDSTutorial/source/images/Vortex-Cover.png and b/build/docs/DDSTutorial/source/images/Vortex-Cover.png differ diff --git a/build/docs/DDSTutorial/source/index.rst b/build/docs/DDSTutorial/source/index.rst index e187e2b7c..5dba8ef84 100644 --- a/build/docs/DDSTutorial/source/index.rst +++ b/build/docs/DDSTutorial/source/index.rst @@ -9,7 +9,7 @@ The Data Distribution Service Tutorial .. toctree:: :maxdepth: 4 :numbered: - + foundations topics-etc readandwrite @@ -18,8 +18,8 @@ The Data Distribution Service Tutorial acronyms biblio - contacts - + contacts + Indices and tables ================== diff --git a/build/docs/DDSTutorial/source/preface.rst b/build/docs/DDSTutorial/source/preface.rst index 469377c95..5b8e7e669 100644 --- a/build/docs/DDSTutorial/source/preface.rst +++ b/build/docs/DDSTutorial/source/preface.rst @@ -10,13 +10,13 @@ Preface About the DDS Tutorial ********************** -The *DDS Tutorial* is included with the OpenSplice DDS +The *DDS Tutorial* is included with the Vortex OpenSplice Documentation Set. This Guide is the starting point for anyone using, -developing or running applications with OpenSplice DDS. +developing or running applications with Vortex OpenSplice. *This DDS Tutorial contains:* -+ a general introduction to the ++ a general introduction to the Data Distibution Service (DDS) + descriptions of how to develop applications which @@ -24,7 +24,7 @@ developing or running applications with OpenSplice DDS. + *etc.* -*Intended Audience* +*Intended Audience* The *DDS Tutorial* is intended to be used by anyone who wishes to make use of a DDS product. @@ -35,24 +35,24 @@ wishes to make use of a DDS product. Conventions *********** -The icons shown below are used in PrismTech product documentation -to help readers to quickly identify information relevant to their -specific use of OpenSplice DDS. +The icons shown below are used in ADLINK product documentation +to help readers to quickly identify information relevant to their +specific use of Vortex OpenSplice. - ========= ================================================================== - *Icon* *Meaning* - ========= ================================================================== - |caution| Item of special significance or where caution needs to be taken. - |info| Item contains helpful hint or special information. - |windows| Information applies to Windows (*e.g.* XP, 2003, Windows 7) only. - |unix| Information applies to Unix-based systems (*e.g.* Solaris) only. - |linux| Information applies to Linux-based systems (*e.g.* Ubuntu) only. - |c| C language specific. - |cpp| C++ language specific. - |csharp| C# language specific. - |java| Java language specific. - ========= ================================================================== + ========= ================================================================== + *Icon* *Meaning* + ========= ================================================================== + |caution| Item of special significance or where caution needs to be taken. + |info| Item contains helpful hint or special information. + |windows| Information applies to Windows (*e.g.* XP, 2003, Windows 7) only. + |unix| Information applies to Unix-based systems (*e.g.* Solaris) only. + |linux| Information applies to Linux-based systems (*e.g.* Ubuntu) only. + |c| C language specific. + |cpp| C++ language specific. + |csharp| C# language specific. + |java| Java language specific. + ========= ================================================================== @@ -76,4 +76,3 @@ specific use of OpenSplice DDS. .. |java| image:: ./images/icon-java.* :height: 6mm - \ No newline at end of file diff --git a/build/docs/DDSTutorial/source/topics-etc.rst b/build/docs/DDSTutorial/source/topics-etc.rst index b053d762a..6a5ce4f05 100644 --- a/build/docs/DDSTutorial/source/topics-etc.rst +++ b/build/docs/DDSTutorial/source/topics-etc.rst @@ -6,7 +6,7 @@ Topics, Domains and Partitions The previous chapter introduced the basic concepts of DDS and walked -through the steps required to write a simple Pub/Sub application. +through the steps required to write a simple Pub/Sub application. This chapter will look at DDS in more depth, starting with data management. @@ -28,7 +28,7 @@ Operating System (OS), so it defines its type system along with a space- and time-efficient binary encoding for its types. Different syntaxes can be used to express DDS topic types, such as :ref:`IDL `, :ref:`XML `. -Some vendors, such as PrismTech, also support +Some vendors, such as ADLINK, also support Google Protocol Buffers. This Tutorial will focus on the subset of IDL that can be used to @@ -77,11 +77,11 @@ essentially what you would expect, with just one exception: the ``int`` type is not there! This should not be a problem since the IDL integral types ``short``, ``long`` and ``long long`` are equivalent to the C99 ``int16_t``, ``int32_t`` and ``int64_t``. -And what is more: in contrast to the ``int`` type, which can have a different -footprint on different platforms, each of these types has specified exactly what -its footprint is. +And what is more: in contrast to the ``int`` type, which can have a different +footprint on different platforms, each of these types has specified exactly what +its footprint is. + - .. _`IDL Template Types`: | **IDL Template Types** @@ -99,22 +99,22 @@ its footprint is. | | | sequence mtseq; | | | | sequence$ mtseq10;| +--------------------------------+----------------------------------+ - - - -In the table `IDL Template Types`_, the ``string`` can be -parameterized only with respect to their maximum length, while -the ``sequence`` type can be parameterized with respect to both its -maximum length and its contained type. -The ``sequence`` type abstracts a homogeneous random access container, pretty -much like the ``std::vector`` in C++ or ``java.util.Vector`` in Java. - -Finally, it is important to point out that when the maximum length is -not provided the type is assumed to have an unbounded length, meaning -that the middleware will allocate as much memory as necessary to store -the values that the application provides. - -The table `IDL Constructed Types`_ shows that DDS supports three different + + + +In the table `IDL Template Types`_, the ``string`` can be +parameterized only with respect to their maximum length, while +the ``sequence`` type can be parameterized with respect to both its +maximum length and its contained type. +The ``sequence`` type abstracts a homogeneous random access container, pretty +much like the ``std::vector`` in C++ or ``java.util.Vector`` in Java. + +Finally, it is important to point out that when the maximum length is +not provided the type is assumed to have an unbounded length, meaning +that the middleware will allocate as much memory as necessary to store +the values that the application provides. + +The table `IDL Constructed Types`_ shows that DDS supports three different kinds of IDL constructed types: ``enum``, ``struct``, and ``union``. @@ -145,13 +145,13 @@ kinds of IDL constructed types: ``enum``, ``struct``, and ``union``. -It should be clear from this that a Topic type is a ``struct`` that can +It should be clear from this that a Topic type is a ``struct`` that can contain (as fields) nested structures, unions, enumerations, and template types, as well as primitive types. In addition, it is possible to define multi-dimensional arrays of any DDS-supported or user-defined type. To tie things together, there are language-specific mappings from the -IDL types described above to mainstream programming languages such as +IDL types described above to mainstream programming languages such as C++, Java, and C#. @@ -165,10 +165,10 @@ Each Topic comes with an associated key-set. This key-set might be empty or it can include an arbitrary number of attributes defined by the Topic Type. There are no limitations on the number, kind, or level of nesting, of attributes used to establish the key. There are some limitations to -its kind though: a key should either be a primitive type (see table -`Primitive Types`_), an enumeration or a string. A key cannot be constructed -type (although it may consist of one or more members of an embedded constructed -type), an array or a sequence of any type. +its kind though: a key should either be a primitive type (see table +`Primitive Types`_), an enumeration or a string. A key cannot be constructed +type (although it may consist of one or more members of an embedded constructed +type), an array or a sequence of any type. .. _`Keyed and Keyless Topics`: @@ -187,8 +187,8 @@ monitoring system), it is possible to define a keyless variant of the ``TempSensorType`` defined in the :ref:`Foundations ` chapter. -`Keyed and Keyless Topics`_ shows the ``TempSensorType`` with the -``id`` attribute defined as its key, along with the ``KeylessTempSensorType`` +`Keyed and Keyless Topics`_ shows the ``TempSensorType`` with the +``id`` attribute defined as its key, along with the ``KeylessTempSensorType`` showing off an empty key-set as defined in its ``#pragma keylist`` directive. If two topics associated with the types declared in @@ -258,7 +258,7 @@ associated with the singleton instance, as shown in If we write the same samples for the ``TempSensorTopic``, the end-result is quite different. The two samples written in the code fragment below -have two different ``id`` values, respectively ``1`` and ``2``; +have two different ``id`` values, respectively ``1`` and ``2``; they are referring to two different instances. .. literalinclude:: ./code/isocpp2/ch2/tspub.cpp @@ -281,7 +281,7 @@ one queue for each instance. In summary, Topics should be thought of as classes in an object-oriented -language, and each unique key-value identifies an instance. +language, and each unique key-value identifies an instance. The life-cycle of topic instances is managed by DDS and to each topic instance are allocated memory resources; think of it as a queue on the reader side. Keys identify specific data streams @@ -294,14 +294,14 @@ track the lifecycle of the sensor by tracking the lifecycle of its associated instance. It is possible to detect when a new sensor is added into the system, because it introduces a new instance; it is possible to detect when a sensor has failed, because DDS can report -when there are no more writers for a specific instance. -It is even possible to detect when a sensor has crashed and then recovered +when there are no more writers for a specific instance. +It is even possible to detect when a sensor has crashed and then recovered thanks to information about state transitions that is provided by DDS. Finally, before moving on from DDS instances, it is emphasized that -DDS subscriptions concern *Topics*. Thus *a subscriber receives* +DDS subscriptions concern *Topics*. Thus *a subscriber receives* **all** *of the instances produced for that topic*. In some cases -this is not desirable and some scoping actions are necessary. +this is not desirable and some scoping actions are necessary. Scoping is discussed in the next section. @@ -343,11 +343,11 @@ The mechanism provided by DDS for joining a partition is very flexible as a publisher or a subscriber can join by providing its full name, such as ``SensorDataPartition``, or it can join all the partitions that match a regular expression, such as ``Sens*`` or ``*Data*``. Supported regular -expressions are the same as those accepted by the POSIX ``fnmatch`` +expressions are the same as those accepted by the POSIX ``fnmatch`` function (see :ref:`POSIX fmatch `). To recap: *partitions provide a way of* **scoping** *information*. -This scoping mechanism can be used to organize topics into different +This scoping mechanism can be used to organize topics into different coherent sets. Partitions can also be used to segregate topic instances. *Instance @@ -371,9 +371,9 @@ partitions for all of the rooms at the first floor in building 1. In a nutshell, *partitions* can be used to *scope* information, and *naming conventions* (such as those used for the example temperature control -applications) can be used to *emulate hierarchical organization of data* -starting from flat partitions. Using the same technique it is possible to -slice and access data across different dimensions or views, depending on the +applications) can be used to *emulate hierarchical organization of data* +starting from flat partitions. Using the same technique it is possible to +slice and access data across different dimensions or views, depending on the needs of the application. .. _`Content Filtering`: @@ -383,7 +383,7 @@ Content Filtering ***************** Domains and Partitions are useful mechanisms for the *structural* -organization of data, but what if it is neccessary to control the data +organization of data, but what if it is neccessary to control the data received based on its *content*? Content Filtering enables the creation of topics that constrain the values that their instances might take. @@ -476,11 +476,11 @@ This chapter has covered the most important aspects of data management in DDS: topics-types and topic instances, and the various mechanisms provided by DDS for scoping information. -Information can be structurally organized by means of domains and +Information can be structurally organized by means of domains and partitions, and special views can be created using content-filtered -topics and query conditions. +topics and query conditions. -It is recommended again that the reader compiles and runs the examples +It is recommended again that the reader compiles and runs the examples and experiments with the programs developed so far. - + diff --git a/build/docs/DeploymentGuide/source/conf.py b/build/docs/DeploymentGuide/source/conf.py index f66263d10..e27d0d075 100644 --- a/build/docs/DeploymentGuide/source/conf.py +++ b/build/docs/DeploymentGuide/source/conf.py @@ -63,9 +63,8 @@ def setup(app): # General information about the project. project = u'OpenSplice Deployment Guide' -#copyright = u'2016, PrismTech' this_year = time.strftime( '%Y' ) -copyright = u'{y}, PrismTech'.format( y = this_year ) +copyright = u'{y}, ADLINK Technology Limited'.format( y = this_year ) print 'Copyright string is:', copyright @@ -230,7 +229,7 @@ def setup(app): # Added 'True' to end of generated line to suppress 'Index & Tables' -# A dictionary that contains LaTeX snippets that override those Sphinx usually +# A dictionary that contains LaTeX snippets that override those Sphinx usually # puts into the generated .tex files. latex_elements = { 'babel': '\\usepackage[english]{babel}' } @@ -275,7 +274,7 @@ def setup(app): # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). -man_pages = [('index', 'OpenSplice_Deployment_Guide', u'OpenSplice_Deployment_Guide Documentation', [u'PrismTech'], 1)] +man_pages = [('index', 'OpenSplice_Deployment_Guide', u'OpenSplice_Deployment_Guide Documentation', [u'ADLINK Technology Limited'], 1)] # -- Additional options -------------------------------------------------------- diff --git a/build/docs/DeploymentGuide/source/contacts.rst b/build/docs/DeploymentGuide/source/contacts.rst index 0f2f36ea3..d32f6016f 100644 --- a/build/docs/DeploymentGuide/source/contacts.rst +++ b/build/docs/DeploymentGuide/source/contacts.rst @@ -1,47 +1 @@ -.. _`Contacts & Notices`: - -################## -Contacts & Notices -################## - -******** -Contacts -******** - -| **PrismTech Corporation** -| 400 TradeCenter -| Suite 5900 -| Woburn, MA -| 01801 -| USA -| Tel: +1 781 569 5819 - -| **PrismTech Limited** -| PrismTech House -| 5th Avenue Business Park -| Gateshead -| NE11 0NG -| UK -| Tel: +44 (0)191 497 9900 - -| **PrismTech France** -| 28 rue Jean Rostand -| 91400 Orsay -| France -| Tel: +33 (1) 69 015354 - - -Web: http://www.prismtech.com - -E-mail: \info@prismtech.com - -******* -Notices -******* - -**Copyright** © 2016 PrismTech Limited. All rights reserved. - -*This document may be reproduced in whole but not in part. -The information contained in this document is subject to change without notice and is made available in good faith without liability on the part of PrismTech Limited or PrismTech Corporation. -All trademarks acknowledged.* - +.. include:: ../../common/contacts.rst diff --git a/build/docs/DeploymentGuide/source/ddsi2-networking-service.rst b/build/docs/DeploymentGuide/source/ddsi2-networking-service.rst index 877ccdcb6..8f39774f9 100644 --- a/build/docs/DeploymentGuide/source/ddsi2-networking-service.rst +++ b/build/docs/DeploymentGuide/source/ddsi2-networking-service.rst @@ -37,7 +37,7 @@ giving extra features for: options can be controlled. The remainder of this section gives background on these two services and describes -how the various mechanisms and their configuration parameters interact. +how the various mechanisms and their configuration parameters interact. Please refer to the :ref:`Configuration ` section fully-detailed descriptions of: @@ -50,15 +50,15 @@ section fully-detailed descriptions of: DDSI Concepts ************* -The DDSI 2.1 standard is very intimately related to the DDS 1.2 standard, with a -clear correspondence between the entities in DDSI and those in DCPS. However, -this correspondence is not one-to-one. +Both DDSI 2.1 and 2.2 standards are very intimately related to the DDS 1.2 and 1.4 +standards, with a clear correspondence between the entities in DDSI and those in DCPS. +However, this correspondence is not one-to-one. In this section we give a high-level description of the concepts of the DDSI -specification, with hardly any reference to the specifics of the OpenSplice +specification, with hardly any reference to the specifics of the Vortex OpenSplice implementation, DDSI2, which are addressed in subsequent sections. This division was chosen to aid readers interested in interoperability to understand -where the specification ends and the OpenSplice implementation begins. +where the specification ends and the Vortex OpenSplice implementation begins. .. _`Mapping of DCPS domains to DDSI domains`: @@ -70,7 +70,7 @@ In DCPS, a domain is uniquely identified by a non-negative integer, the domain i DDSI maps this domain id to UDP/IP port numbers to be used for communicating with the peer nodes — these port numbers are particularly important for the discovery protocol — and this mapping of domain ids to UDP/IP port numbers -ensures that accidental cross-domain communication is impossible with the +ensures that accidental cross-domain communication is impossible with the default mapping. DDSI does not communicate the DCPS port number in the discovery protocol; it @@ -155,23 +155,23 @@ DDSI-specific transient-local behaviour ======================================= The above describes the essentials of the mechanism used for samples of the -*‘volatile’* durability kind, but the DCPS specification also provides -*‘transient-local’*, *‘transient’* and *‘persistent’* data. Of these, the -DDSI specification currently only covers *transient-local*, and this is +*‘volatile’* durability kind, but the DCPS specification also provides +*‘transient-local’*, *‘transient’* and *‘persistent’* data. Of these, the +DDSI specification currently only covers *transient-local*, and this is the only form of durable data available when interoperating across vendors. In DDSI, transient-local data is implemented using the WHC that is normally used for reliable communication. For transient-local data, samples are retained even when all readers have acknowledged them. With the default history setting of -``KEEP_LAST`` with ``history_depth = 1``, this means that late-joining readers +``KEEP_LAST`` with ``history_depth = 1``, this means that late-joining readers can still obtain the latest sample for each existing instance. Naturally, once the DCPS writer is deleted (or disappears for whatever reason), the DDSI writer disappears as well, and with it, its history. For this reason, transient -data is generally much to be preferred over transient-local data. In OpenSplice the +data is generally much to be preferred over transient-local data. In Vortex OpenSplice the durability service implements all three durability kinds without requiring any -special support from the networking services, ensuring that the full set of -durability features is always available between OpenSplice nodes. +special support from the networking services, ensuring that the full set of +durability features is always available between Vortex OpenSplice nodes. .. _`Discovery of participants & endpoints`: @@ -183,7 +183,7 @@ DDSI participants discover each other by means of the *‘Simple Participant Discovery Protocol’*, or *‘SPDP*’ for short. This protocol is based on periodically sending a message containing the specifics of the participant to a set of known addresses. By default, this is a standardised multicast address (``239.255.0.1``; -the port number is derived from the domain id) that all DDSI implementations +the port number is derived from the domain id) that all DDSI implementations listen to. Particularly important in the SPDP message are the unicast and multicast addresses @@ -215,34 +215,34 @@ now received the complete set. |info| Note that the discovery process necessarily creates a burst of traffic each time - a participant is added to the system: *all* existing participants respond to the + a participant is added to the system: *all* existing participants respond to the SPDP message, following which all start exchanging SEDP data. -.. _`OpenSplice DDSI2 specifics`: +.. _`Vortex OpenSplice DDSI2 specifics`: -OpenSplice DDSI2 specifics -************************** +Vortex OpenSplice DDSI2 specifics +********************************* -.. _`Translating between OpenSplice and DDSI`: +.. _`Translating between Vortex OpenSplice and DDSI`: -Translating between OpenSplice and DDSI -======================================= +Translating between Vortex OpenSplice and DDSI +============================================== Given that DDSI is the DDS interoperability specification, that the mapping -between DCPS entities and DDSI entities is straightforward, and that OpenSplice is +between DCPS entities and DDSI entities is straightforward, and that Vortex OpenSplice is a full implementation of the DDS specification, one might expect that relationship -between OpenSplice and its DDSI implementation, DDSI2, is trivial. Unfortunately, +between Vortex OpenSplice and its DDSI implementation, DDSI2, is trivial. Unfortunately, this is not the case, and it does show in a number of areas. A high-level overview -such as this paragraph is not the place for the details of these cases, but they +such as this paragraph is not the place for the details of these cases, but they will be described in due course. The root cause of these complexities is a difference in design philosophy between -OpenSplice and the more recent DDSI. +Vortex OpenSplice and the more recent DDSI. DDSI is very strictly a *peer-to-peer* protocol at the level of individual endpoints, requiring lots of discovery traffic, and (at least when implemented naively) very bad -scalability. It is exactly these three problems that OpenSplice was designed to avoid, +scalability. It is exactly these three problems that Vortex OpenSplice was designed to avoid, and it does so successfully with its native *RTNetworking* service. Because of this design for scalability and the consequent use of service processes @@ -251,7 +251,7 @@ various ways in which DDSI2 has to translate between the two worlds. For example queuing and buffering and, consequently, blocking behaviour are subtly different; DDSI2 needs to also perform local discovery of DCPS endpoints to gather enough information for faithfully representing the system in terms of DDSI, it needs to -translate between completely different namespaces (native OpenSplice identifiers +translate between completely different namespaces (native Vortex OpenSplice identifiers are very different from the GUIDs used by DDSI), and it needs to work around receiving asynchronous notifications for events one would expect to be synchronous in DDSI. @@ -266,20 +266,20 @@ Federated versus Standalone deployment ====================================== As has been described elsewhere (see the :ref:`Overview ` in this -*Guide* and also the *Getting Started Guide*), OpenSplice has multiple -deployment models selectable in the configuration file (some of these require +*Guide* and also the *Getting Started Guide*), Vortex OpenSplice has multiple +deployment models selectable in the configuration file (some of these require a license). For DDSI2, there is no difference between the various models: it simply serves whatever DCPS participants are in the same ‘instance’, whether that instance be a federation of processes on a single node, all attached to a shared memory segment -managed by a set of OpenSplice service processes on that node, or a standalone one -in which a single process incorporates the OpenSplice services as libraries. +managed by a set of Vortex OpenSplice service processes on that node, or a standalone one +in which a single process incorporates the Vortex OpenSplice services as libraries. This *Guide* ignores the various deployment modes, using the terminology associated with the federated deployment mode because that mode is the driving force behind several of the user-visible design decisions in DDSI2. In consequence, -for a standalone deployment, the term *‘node’* as used in this *Guide* refers +for a standalone deployment, the term *‘node’* as used in this *Guide* refers to a single process. @@ -305,10 +305,10 @@ is to instruct DDSI2 to completely ignore them using the DCPS topic/partition to network partition mapping available in the enhanced version, DDSI2E. A separate issue is that of the DCPS built-in topics when interoperating with other -implementations. In OpenSplice the built-in topics are first-class topics, *i.e.* the -only difference between application topics and the built-in topics in OpenSplice is +implementations. In Vortex OpenSplice the built-in topics are first-class topics, *i.e.* the +only difference between application topics and the built-in topics in Vortex OpenSplice is that the built-in topics are pre-defined and that they are published and used by the -OpenSplice services. This in turn allows the RTNetworking service to avoid +Vortex OpenSplice services. This in turn allows the RTNetworking service to avoid discovery of individual domain participants and endpoints, enabling its excellent scalability. @@ -320,7 +320,7 @@ this also means that the DCPS built-in topics become a special case. Taken together, DDSI2 is in the unfortunate situation of having to straddle two very different approaches. While local reconstruction of the DCPS built-in topics by DDSI2 is clearly possible, it would negatively impact the handling of transient data. -Since handling transient data is one of the true strengths of OpenSplice, DDSI2 +Since handling transient data is one of the true strengths of Vortex OpenSplice, DDSI2 currently does not perform this reconstruction, with the unfortunate implication that loss of liveliness will not be handled fully when interoperating with another DDSI implementation. @@ -370,11 +370,11 @@ Instead of implementing the protocol as suggested by the standard, DDSI2 shares discovery activities amongst the participants, allowing one to add participants on a node with only a minimal impact on the system. It is even possible to have only a single DDSI participant on each node, which then becomes the virtual owner of all -the endpoints serviced by that instance of DDSI2. (See +the endpoints serviced by that instance of DDSI2. (See `Combining multiple participants`_ and refer to the :ref:`Configuration ` section for a detailed description of -``//OpenSplice/DDSI2Service/Internal/SquashParticipants``.) In this latter mode, -there is no discovery penalty at all for having many participants, but evidently, +``//OpenSplice/DDSI2Service/Internal/SquashParticipants``.) In this latter mode, +there is no discovery penalty at all for having many participants, but evidently, any participant-based liveliness monitoring will be affected. Because other implementations of the DDSI specification may be written on the @@ -384,10 +384,10 @@ participant independently, but it will generate the network traffic *as if* it d Please refer to the :ref:`Configuration ` section for detailed descriptions of: -+ ``//OOpenSplice/DDSI2Service/Internal/BuiltinEndpointSet`` ++ ``//OpenSplice/DDSI2Service/Internal/BuiltinEndpointSet`` + ``//OpenSplice/DDSI2Service/Internal/ConservativeBuiltinReaderStartup`` -However, please note that at the time of writing, we are not aware of any +However, please note that at the time of writing, we are not aware of any DDSI implementation requiring the use of these settings.) By sharing the discovery information across all participants in a single node, each @@ -410,7 +410,7 @@ When an application deletes a reliable DCPS data writer, there is no guarantee t all its readers have already acknowledged the correct receipt of all samples. In such a case, DDSI2 lets the writer (and the owning participant if necessary) linger in the system for some time, controlled by the ``Internal/WriterLingerDuration`` option. -The writer is deleted when all samples have been acknowledged by all readers or +The writer is deleted when all samples have been acknowledged by all readers or the linger duration has elapsed, whichever comes first. The writer linger duration setting is currently not applied when DDSI2 is requested @@ -475,7 +475,7 @@ Writer history QoS and throttling The DDSI specification heavily relies on the notion of a writer history cache (WHC) within which a sequence number uniquely identifies each sample. The original -OpenSplice design has a different division of responsibilities between various +Vortex OpenSplice design has a different division of responsibilities between various components than what is assumed by the DDSI specification and this includes the WHC. Despite the different division, the resulting behaviour is the same. @@ -493,18 +493,18 @@ The index on sequence number is required for retransmitting old data, and is therefore needed for all reliable writers. The index on key values is always needed for transient-local data, and can optionally be used for other writers using a history setting of ``KEEP_LAST`` with depth ``1``. (The ``Internal/AggressiveKeepLast1Whc`` -setting controls this behaviour.) The advantage of an index on key value in such -a case is that superseded samples can be dropped aggressively, instead of having -to deliver them to all readers; the disadvantage is that it is somewhat more +setting controls this behaviour.) The advantage of an index on key value in such +a case is that superseded samples can be dropped aggressively, instead of having +to deliver them to all readers; the disadvantage is that it is somewhat more resource-intensive. Writer throttling is based on the WHC size using a simple bang-bang controller. Once the WHC contains ``Internal/Watermarks/WhcHigh`` bytes in -unacknowledged samples, it stalls the writer until the number of bytes in +unacknowledged samples, it stalls the writer until the number of bytes in unacknowledged samples drops below ``Internal/Watermarks/WhcLow``. While ideally only the one writer would be stalled, the interface between the -OpenSplice kernel and DDSI2 is such that other outgoing traffic may be stalled as +Vortex OpenSplice kernel and DDSI2 is such that other outgoing traffic may be stalled as well. See `Unresponsive readers & head-of-stream blocking`_. Please refer to the :ref:`Configuration ` section for @@ -523,12 +523,12 @@ Unresponsive readers & head-of-stream blocking For reliable communications, DDSI2 must retain sent samples in the WHC until they have been acknowledged. Especially in case of a ``KEEP_ALL`` history kind, but also in the default case when the WHC is not aggressively dropping old samples of -instances (``Internal/AggressiveKeepLast1Whc``), a reader that fails to acknowledge +instances (``Internal/AggressiveKeepLast1Whc``), a reader that fails to acknowledge the samples timely will cause the WHC to run into resource limits. The correct treatment suggested by the DDS specification is to simply take the writer history QoS setting, apply this to the DDSI2 WHC, and block the writer up to -its ‘max_blocking_time’ QoS setting. However, the scalable architecture of +its ‘max_blocking_time’ QoS setting. However, the scalable architecture of Vortex OpenSplice renders this simple approach infeasible because of the division of labour between the application processes and the various services. Of course, even if it were a possible approach, the problem would still not be gone entirely, as one @@ -539,8 +539,8 @@ writer is a critical one. Because of this, once DDSI2 hits a resource limit on a WHC, it blocks the sequence of outgoing samples for up to ``Internal/ResponsivenessTimeout``. If this timeout is set larger than roughly the domain expiry time -(``//OpenSplice/Domain/Lease/ExpiryTime``), it may cause entire nodes to lose -liveliness. The enhanced version, DDSI2E, has the ability to use multiple queues +(``//OpenSplice/Domain/Lease/ExpiryTime``), it may cause entire nodes to lose +liveliness. The enhanced version, DDSI2E, has the ability to use multiple queues and can avoid this problem; please refer to `Channel configuration`_. Any readers that fail to acknowledge samples in time will be marked ‘unresponsive’ @@ -584,14 +584,14 @@ Handling of multiple partitions and wildcards Publishing in multiple partitions --------------------------------- -A variety of design choices allow OpenSplice in combination with its +A variety of design choices allow Vortex OpenSplice in combination with its RTNetworking service to be fully dynamically discovered, yet without requiring an expensive discovery protocol. A side effect of these choices is that a DCPS writer publishing a single sample in multiple partitions simultaneously will be translated by the current version of DDSI2 as a writer publishing multiple identical samples in all these partitions, but with unique sequence numbers. -When DDSI2 is used to communicate between OpenSplice nodes, this is not an +When DDSI2 is used to communicate between Vortex OpenSplice nodes, this is not an application-visible issue, but it is visible when interoperating with other implementations. Fortunately, publishing in multiple partitions is rarely a wise choice in a system design. @@ -612,7 +612,7 @@ partition wildcards for publishing data can easily lead to the replication of da mentioned in the previous subsection (`Publishing in multiple partitions`_). Secondly, because DDSI2 implements transient-local data internally in a different -way from the way the OpenSplice durability service does, it is strongly +way from the way the Vortex OpenSplice durability service does, it is strongly recommended that the combination of transient-local data and publishing using partition wildcards be avoided completely. @@ -627,8 +627,8 @@ Network and discovery configuration Networking interfaces ===================== -DDSI2 uses a single network interface, the *‘preferred’* interface, for transmitting -its multicast packets and advertises only the address corresponding to this interface +DDSI2 uses a single network interface, the *‘preferred’* interface, for transmitting +its multicast packets and advertises only the address corresponding to this interface in the DDSI discovery protocol. To determine the default network interface, DDSI2 ranks the eligible interfaces by @@ -637,7 +637,7 @@ are of the highest quality, it will select the first enumerated one. Eligible in are those that are up and have the right kind of address family (IPv4 or IPv6). Priority is then determined as follows: -+ interfaces with a non-link-local address are preferred over those with ++ interfaces with a non-link-local address are preferred over those with a link-local one; + multicast-capable is preferred, or if none is available + non-multicast capable but neither point-to-point, or if none is available @@ -700,19 +700,19 @@ DDSI2 allows configuring to what extent multicast is to be used: It is advised to allow multicasting to be used. However, if there are restrictions on the use of multicasting, or if the network reliability is dramatically different for multicast than for unicast, it may be attractive to disable multicast for normal -communications. In this case, setting ``General/AllowMulticast`` to ``false`` will -force DDSI2 to use unicast communications for everything except the periodic +communications. In this case, setting ``General/AllowMulticast`` to ``false`` will +force DDSI2 to use unicast communications for everything except the periodic distribution of the participant discovery messages. -If at all possible, it is strongly advised to leave multicast-based participant -discovery enabled, because that avoids having to specify a list of nodes to -contact, and it furthermore reduces the network load considerably. However, -if need be, one can disable the participant discovery from sending multicasts +If at all possible, it is strongly advised to leave multicast-based participant +discovery enabled, because that avoids having to specify a list of nodes to +contact, and it furthermore reduces the network load considerably. However, +if need be, one can disable the participant discovery from sending multicasts by setting ``Internal/SuppressSpdpMulticast`` to ``true``. -To disable incoming multicasts, or to control from which interfaces multicasts are +To disable incoming multicasts, or to control from which interfaces multicasts are to be accepted, one can use the ``General/MulticastRecvInterfaceAddresses`` setting. -This allows listening on no interface, the preferred, all or a specific set +This allows listening on no interface, the preferred, all or a specific set of interfaces. Please refer to the :ref:`Configuration ` section for @@ -734,7 +734,7 @@ Discovery addresses ................... The DDSI discovery protocols, SPDP for the domain participants and SEDP for -their endpoints, usually operate well without any explicit configuration. +their endpoints, usually operate well without any explicit configuration. Indeed, the SEDP protocol never requires any configuration. DDSI2 by default uses the domain id as specified in ``//OpenSplice/Domain/Id`` @@ -767,7 +767,7 @@ making this rather wasteful behaviour. DDSI2 allows explicitly adding a port number to the IP address, formatted as IP:PORT, to avoid this waste, but this requires manually calculating the port number. In practice it also requires fixing the participant index using -``Discovery/ParticipantIndex`` (see the description of ‘PI’ in +``Discovery/ParticipantIndex`` (see the description of ‘PI’ in `Controlling port numbers`_) to ensure that the configured port number indeed corresponds to the remote DDSI2 (or other DDSI implementation), and therefore is really practicable only in a federated deployment. @@ -790,8 +790,8 @@ Asymmetrical discovery On reception of an SPDP packet, DDSI2 adds the addresses advertised in that SPDP packet to this set, allowing asymmetrical discovery. In an extreme example, if SPDP -multicasting is disabled entirely, host A has the address of host B in its peer list -and host B has an empty peer list, then B will eventually discover A because of an +multicasting is disabled entirely, host A has the address of host B in its peer list +and host B has an empty peer list, then B will eventually discover A because of an SPDP message sent by A, at which point it adds A’s address to its own set and starts sending its own SPDP message to A, allowing A to discover B. This takes a bit longer than normal multicast based discovery, though. @@ -814,7 +814,7 @@ Endpoint discovery .................. Although the SEDP protocol never requires any configuration, the network -partitioning of OpenSplice DDSI2E does interact with it: so-called ‘ignored +partitioning of Vortex OpenSplice DDSI2E does interact with it: so-called ‘ignored partitions’ can be used to instruct DDSI2 to completely ignore certain DCPS topic and partition combinations, which will prevent DDSI2 from forwarding data for these topic/partition combinations to and from the network. @@ -830,20 +830,20 @@ DDSI2. Combining multiple participants =============================== -In an OpenSplice standalone deployment the various configured services, such as +In a Vortex OpenSplice standalone deployment the various configured services, such as spliced and DDSI2, still retain their identity by creating their own DCPS domain participants. DDSI2 faithfully mirrors all these participants in DDSI, and it will appear at the DDSI level as if there is a large system with many participants, whereas in reality there are only a few application participants. -The ``Internal/SquashParticipants`` option can be used to simulate the existence -of only one participant, the DDSI2 service itself, which owns all endpoints on -that node. This reduces the background messages because far fewer liveliness +The ``Internal/SquashParticipants`` option can be used to simulate the existence +of only one participant, the DDSI2 service itself, which owns all endpoints on +that node. This reduces the background messages because far fewer liveliness assertions need to be sent. Clearly, the liveliness monitoring features that are related to domain participants will be affected if multiple DCPS domain participants are combined into a single -DDSI domain participant. The OpenSplice services all use a liveliness QoS setting +DDSI domain participant. The Vortex OpenSplice services all use a liveliness QoS setting of AUTOMATIC, which works fine. In a federated deployment, the effect of this option is to have only a single DDSI @@ -851,10 +851,10 @@ domain participant per node. This is of course much more scalable, but in no way resembles the actual structure of the system if there are in fact multiple application processes running on that node. -However, in OpenSplice the built-in topics are not derived from the DDSI -discovery, and hence in an OpenSplice-only network the use of the -``Internal/SquashParticipants`` setting will not result in any loss of information -in the DCPS API or in the OpenSplice tools such as the Tester. +However, in Vortex OpenSplice the built-in topics are not derived from the DDSI +discovery, and hence in a Vortex OpenSplice-only network the use of the +``Internal/SquashParticipants`` setting will not result in any loss of information +in the DCPS API or in the Vortex OpenSplice tools such as the Tester. When interoperability with another vendor is not needed, enabling the ``SquashParticipants`` option is often a good choice. @@ -877,7 +877,7 @@ of serving multiple participants by a single DDSI instance: + 2 ‘well-known’ multicast ports: ``B`` and ``B+1`` + 2 unicast ports at which only this instance of DDSI2 is listening: ``B+PG*PI+10`` and ``B+PG*PI+11`` -+ 1 unicast port per domain participant it serves, chosen by the kernel ++ 1 unicast port per domain participant it serves, chosen by the kernel from the anonymous ports, *i.e.* >= 32768 where: @@ -889,8 +889,8 @@ where: The default values, taken from the DDSI specification, are in parentheses. There are actually even more parameters, here simply turned into constants as there is -absolutely no point in ever changing these values; however, they *are* configurable -and the interested reader is referred to the DDSI 2.1 specification, section 9.6.1. +absolutely no point in ever changing these values; however, they *are* configurable +and the interested reader is referred to the DDSI 2.1 or 2.2 specification, section 9.6.1. PI is the most interesting, as it relates to having multiple instances of DDSI2 in the same domain on a single node. In a federated deployment, this never happens @@ -913,7 +913,7 @@ non-negative integer. This setting matters: alternative is hardly useful. Clearly, to fully control port numbers, setting ``Discovery/ParticipantIndex`` (= PI) -to a hard-coded value is the only possibility. In a federated deployment this is an +to a hard-coded value is the only possibility. In a federated deployment this is an option that has very few downsides, and generally ``0`` will be a good choice. By fixing PI, the port numbers needed for unicast discovery are fixed as well. This @@ -949,15 +949,15 @@ detailed descriptions of: + ``//OpenSplice/DDSI2Service/Compatibility/ManySocketsMode`` -.. _`Coexistence with OpenSplice RTNetworking`: +.. _`Coexistence with Vortex OpenSplice RTNetworking`: -Coexistence with OpenSplice RTNetworking +Coexistence with Vortex OpenSplice RTNetworking ======================================== -DDSI2 has a special mode, configured using ``General/CoexistWithNativeNetworking``, -to allow it to operate in conjunction with OpenSplice RTNetworking: in this mode -DDSI2 only handles packets sent by other vendors’ implementations, allowing all -intra-OpenSplice traffic to be handled by the RTNetworking service while still +DDSI2 has a special mode, configured using ``General/CoexistWithNativeNetworking``, +to allow it to operate in conjunction with Vortex OpenSplice RTNetworking: in this mode +DDSI2 only handles packets sent by other vendors’ implementations, allowing all +intra-Vortex OpenSplice traffic to be handled by the RTNetworking service while still providing interoperability with other vendors. Please refer to the :ref:`Configuration ` section for @@ -977,7 +977,7 @@ Data path architecture ====================== The data path in DDSI2 consists of a transmitting and a receiving side. The main -path in the transmit side accepts data to be transmitted from the OpenSplice kernel +path in the transmit side accepts data to be transmitted from the Vortex OpenSplice kernel *via* a network queue and administrates and formats the data for transmission over the network. @@ -987,9 +987,9 @@ to writers, in addition to handling the retransmission of old data on request. T requests can originate in packet loss, but also in requests for historical data from transient-local readers. -The diagram `Data flow using two channels`_ gives an overview of the main data -flow and the threads in a configuration using two channels. Configuring multiple -channels is an enhanced feature that is available only in DDSI2E, but the +The diagram `Data flow using two channels`_ gives an overview of the main data +flow and the threads in a configuration using two channels. Configuring multiple +channels is an enhanced feature that is available only in DDSI2E, but the principle is the same in both variants. .. _`Data flow using two channels`: @@ -1020,7 +1020,7 @@ restricted to what in DDSI2E is the default channel if none are configured expli For details on configuring channels, see `Channel configuration`_. Each channel has its own transmit thread, draining a queue with samples to be -transmitted from the OpenSplice kernel. The maximum size of the queue can be +transmitted from the Vortex OpenSplice kernel. The maximum size of the queue can be configured per channel, and the default for the individual channels is configured using the ``Sizing/NetworkQueueSize`` setting. In DDSI2, this setting simply controls the queue size, as the default channel of DDSI2E has the default queue size. A larger @@ -1030,7 +1030,7 @@ bursts. Once a networking service has taken a sample from the queue, it takes responsibility for it. Consequently, if it is to be sent reliably and there are insufficient resources to -store it in the WHC, it must wait for resources to become available. +store it in the WHC, it must wait for resources to become available. See `Unresponsive readers & head-of-stream blocking`_. The DDSI control messages (Heartbeat, AckNack, *etc.*) are sent by a thread @@ -1059,9 +1059,9 @@ retransmissions too often, in an interoperable system the writers should be robu against it. In DDSI2, upon receiving a Heartbeat that indicates samples are missing, a reader -will schedule a retransmission request to be sent after ``Internal/NackDelay``, -or combine it with an already scheduled request if possible. Any samples received -in between receipt of the Heartbeat and the sending of the AckNack will not need +will schedule a retransmission request to be sent after ``Internal/NackDelay``, +or combine it with an already scheduled request if possible. Any samples received +in between receipt of the Heartbeat and the sending of the AckNack will not need to be retransmitted. Secondly, a writer attempts to combine retransmit requests in two different ways. @@ -1069,10 +1069,10 @@ The first is to change messages from unicast to multicast when another retransmi request arrives while the retransmit has not yet taken place. This is particularly effective when bandwidth limiting causes a backlog of samples to be retransmitted. The behaviour of the second can be configured using the ``Internal/RetransmitMerging`` -setting. Based on this setting, a retransmit request for a sample is either honoured -unconditionally, or it may be suppressed (or ‘merged’) if it comes in shortly after -a multicasted retransmission of that very sample, on the assumption that the second -reader will likely receive the retransmit, too. The ``Internal/RetransmitMergingPeriod`` +setting. Based on this setting, a retransmit request for a sample is either honoured +unconditionally, or it may be suppressed (or ‘merged’) if it comes in shortly after +a multicasted retransmission of that very sample, on the assumption that the second +reader will likely receive the retransmit, too. The ``Internal/RetransmitMergingPeriod`` controls the length of this time window. Please refer to the :ref:`Configuration ` section for @@ -1103,10 +1103,10 @@ settings governing the size of these queues, and the limits are applied per timed-event thread (*i.e.* the global one, and typically one for each configured channel with limited bandwidth when using DDSI2E). The first is ``Internal/MaxQueuedRexmitMessages``, which limits the number of retransmit -messages, the second ``Internal/MaxQueuedRexmitBytes`` which limits the number of +messages, the second ``Internal/MaxQueuedRexmitBytes`` which limits the number of bytes. The latter is automatically set based on the combination -of the allowed transmit bandwidth and the ``Internal/NackDelay`` setting, as an -approximation of the likely time until the next potential retransmit request +of the allowed transmit bandwidth and the ``Internal/NackDelay`` setting, as an +approximation of the likely time until the next potential retransmit request from the reader. Please refer to the :ref:`Configuration ` section for @@ -1129,16 +1129,16 @@ network packets. The DDSI specification states that one must not unnecessarily fragment at the DDSI level, but DDSI2 simply provides a fully configurable behaviour. -If the serialised form of a sample is at least ``Internal/FragmentSize``, -it will be fragmented using the DDSI fragmentation. All but the last fragment +If the serialised form of a sample is at least ``Internal/FragmentSize``, +it will be fragmented using the DDSI fragmentation. All but the last fragment will be exactly this size; the last one may be smaller. Control messages, non-fragmented samples, and sample fragments are all subject to packing into datagrams before sending it out on the network, based on various attributes such as the destination address, to reduce the number of network packets. This packing allows datagram payloads of up to ``Internal/MaxMessageSize``, -overshooting this size if the set maximum is too small to contain what must be -sent as a single unit. Note that in this case, there is a real problem anyway, +overshooting this size if the set maximum is too small to contain what must be +sent as a single unit. Note that in this case, there is a real problem anyway, and it no longer matters where the data is rejected, if it is rejected at all. UDP/IP header sizes are not taken into account in this maximum message size. @@ -1169,7 +1169,7 @@ Receive processing Receiving of data is split into multiple threads, as also depicted in the overall DDSI2 data path diagram `Data flow using two channels`_: -+ A single receive thread responsible for retrieving network packets and running ++ A single receive thread responsible for retrieving network packets and running the protocol state machine; + A delivery thread dedicated to processing DDSI built-in data: participant discovery, endpoint discovery and liveliness assertions; @@ -1182,7 +1182,7 @@ Heartbeat messages and queueing of samples that must be retransmitted, and for defragmenting and ordering incoming samples. For a specific proxy writer—the local manifestation of a remote DDSI data writer— -with a number of data readers, the organisation is as shown in +with a number of data readers, the organisation is as shown in the diagram `Proxy writer with multiple data readers`_. .. _`Proxy writer with multiple data readers`: @@ -1202,13 +1202,13 @@ and for unreliable data to ``Internal/DefragUnreliableMaxSamples``. Samples (defragmented if necessary) received out of sequence are buffered, primarily per proxy writer, but, secondarily, per reader catching up on historical (transient-local) data. The size of the first is limited to -``Internal/PrimaryReorderMaxSamples``, the size of the second to +``Internal/PrimaryReorderMaxSamples``, the size of the second to ``Internal/SecondaryReorderMaxSamples``. In between the receive thread and the delivery threads sit queues, of which the maximum size is controlled by the ``Internal/DeliveryQueueMaxSamples`` -setting. Generally there is no need for these queues to be very large, their -primary function is to smooth out the processing when batches of samples become +setting. Generally there is no need for these queues to be very large, their +primary function is to smooth out the processing when batches of samples become available at once, for example following a retransmission. When any of these receive buffers hit their size limit, DDSI2 will drop incoming @@ -1257,16 +1257,16 @@ Direction-independent settings Maximum sample size ------------------- -DDSI2 provides a setting, ``Internal/MaxSampleSize``, to control the maximum size -of samples that the service is willing to process. The size is the size of -the (CDR) serialised payload, and the limit holds both for built-in data and for -application data. The (CDR) serialised payload is never larger than the in-memory +DDSI2 provides a setting, ``Internal/MaxSampleSize``, to control the maximum size +of samples that the service is willing to process. The size is the size of +the (CDR) serialised payload, and the limit holds both for built-in data and for +application data. The (CDR) serialised payload is never larger than the in-memory representation of the data. On the transmitting side, samples larger than ``MaxSampleSize`` are dropped with a -warning in the OpenSplice info log. DDSI2 behaves as if the sample never existed. -The current structure of the interface between the OpenSplice kernel and the -OpenSplice networking services unfortunately prevents DDSI2 from properly +warning in the Vortex OpenSplice info log. DDSI2 behaves as if the sample never existed. +The current structure of the interface between the Vortex OpenSplice kernel and the +Vortex OpenSplice networking services unfortunately prevents DDSI2 from properly reporting this back to the application that wrote the sample, so the only guaranteed way of detecting the dropping of the sample is by checking the info log. @@ -1289,9 +1289,9 @@ whether or not dropping a particular sample has been recorded in the log already Under normal operational circumstances, DDSI2 will report a single event for each sample dropped, but it may on occasion report multiple events for the same sample. -Finally, it is technically allowed to set ``MaxSampleSize`` to very small sizes, -even to the point that the discovery data can’t be communicated anymore. -The dropping of the discovery data will be duly reported, but the usefulness +Finally, it is technically allowed to set ``MaxSampleSize`` to very small sizes, +even to the point that the discovery data can’t be communicated anymore. +The dropping of the discovery data will be duly reported, but the usefulness of such a configuration seems doubtful. Please refer to the :ref:`Configuration ` section for @@ -1332,7 +1332,7 @@ Channel configuration overview ------------------------------ DDSI2E allows defining *channels*, which are independent data paths within the -DDSI service. OpenSplice chooses a channel based by matching the transport +DDSI service. Vortex OpenSplice chooses a channel based by matching the transport priority QoS setting of the data writer with the threshold specified for the various channels. Because each channel has a set of dedicated threads to perform the processing and the thread priorities can all be configured, it is straightforward to @@ -1353,7 +1353,7 @@ receive thread only performs minimal work on each incoming packet, and never has to wait for the processing of user data. The existence of the receive thread is the only major difference between DDSI2E -channels and those of the OpenSplice RTNetworking service: in the RTNetworking +channels and those of the Vortex OpenSplice RTNetworking service: in the RTNetworking service, each thread is truly independent. This change is the consequence of DDSI2E interoperating with implementations that are not aware of channels and with DDSI2E nodes that have differently configured channels, unlike the @@ -1378,7 +1378,7 @@ priority that is higher than the writer’s transport priority. If there is no s *i.e.* the writer has a transport priority higher than the highest channel threshold, the channel with the highest threshold is used. -Each channel has its own network queue into which the OpenSplice kernel writes +Each channel has its own network queue into which the Vortex OpenSplice kernel writes samples to be transmitted and that DDSI2E reads. The size of this queue can be set for each channel independently by using ``Channels/Channel/QueueSize``, with the default taken from the global ``Sizing/NetworkQueueSize``. @@ -1411,8 +1411,8 @@ event thread handles the generation of auxiliary data for that channel. But if n is given, the global event thread instead handles all auxiliary data for the channel. The global event thread has an auxiliary credit of its own, configured using -``Internal/AuxiliaryBandwidthLimit``. This credit applies to all discovery-related -traffic, as well as to all auxiliary data generated by channels without their own +``Internal/AuxiliaryBandwidthLimit``. This credit applies to all discovery-related +traffic, as well as to all auxiliary data generated by channels without their own event thread. Generally, it is best to simply specify both the data and the auxiliary bandwidth for @@ -1456,7 +1456,7 @@ and always processed by the special delivery thread for DDSI built-in data (‘dq.builtin’). By explicitly creating a timed-event thread, one effectively separates application data from all discovery data. One way of creating such a thread is by setting properties for it (see `Thread configuration`_), -another is by setting a bandwidth limit on the auxiliary data of the channel +another is by setting a bandwidth limit on the auxiliary data of the channel (see `Transmit side`_). Please refer to the :ref:`Configuration ` section for @@ -1508,7 +1508,7 @@ Matching rules Matching of a DCPS partition/topic combination proceeds in the order in which the partition mappings are specified in the configuration. The first matching mapping is -the one that will be used. The ``*`` and ``?`` wildcards are available for +the one that will be used. The ``*`` and ``?`` wildcards are available for the DCPS partition/topic combination in the partition mapping. As mentioned earlier (see `Local discovery and built-in topics`_), @@ -1565,7 +1565,7 @@ be found, or if the associated key or cipher differs, the receiver will ignore t encrypted data. It is therefore not necessary to share keys with nodes that have no need for the encrypted data. -The encryption is performed *per-packet*; there is no chaining from one packet to +The encryption is performed *per-packet*; there is no chaining from one packet to the next. @@ -1596,7 +1596,7 @@ The properties that can be controlled are: + scheduling priority. The threads are named and the attribute ``Threads/Thread[@name]`` -is used to set the properties by thread name. Any subset of threads can be +is used to set the properties by thread name. Any subset of threads can be given special properties; anything not specified explicitly is left at the default value. @@ -1608,41 +1608,41 @@ The following threads exist: + *gc*: garbage collector, which sleeps until garbage collection is requested for an - entity, at which point it starts monitoring the state of DDSI2, pushing the - entity through whatever state transitions are needed once it is safe to do + entity, at which point it starts monitoring the state of DDSI2, pushing the + entity through whatever state transitions are needed once it is safe to do so, ending with the freeing of the memory. + *main*: the main thread of DDSI2, which performs start-up and teardown and - monitors the creation and deletion of entities in the local node using + monitors the creation and deletion of entities in the local node using the built-in topics. + *recv*: accepts incoming network packets from all sockets/ports, performs all - protocol processing, queues (nearly) all protocol messages sent in response - for handling by the timed-event thread, queues for delivery or, in special + protocol processing, queues (nearly) all protocol messages sent in response + for handling by the timed-event thread, queues for delivery or, in special cases, delivers it directly to the data readers. + *dq.builtins*: processes all discovery data coming in from the network. + *lease*: performs internal liveliness monitoring of DDSI2 and renews the - OpenSplice kernel lease if the status is satisfactory. + Vortex OpenSplice kernel lease if the status is satisfactory. + *tev*: timed-event handling, used for all kinds of things, such as: periodic - transmission of participant discovery and liveliness messages, transmission - of control messages for reliable writers and readers (except those that have - their own timed-event thread), retransmitting of reliable data on request - (except those that have their own timed-event thread), and handling of + transmission of participant discovery and liveliness messages, transmission + of control messages for reliable writers and readers (except those that have + their own timed-event thread), retransmitting of reliable data on request + (except those that have their own timed-event thread), and handling of start-up mode to normal mode transition. and, for each defined channel: + *xmit.channel-name*: - takes data from the OpenSplice kernel’s queue for this channel, serialises + takes data from the Vortex OpenSplice kernel’s queue for this channel, serialises it and forwards it to the network. + *dq.channel-name*: deserialisation and asynchronous delivery of all user data. + *tev.channel-name*: - channel-specific ‘timed-event’ handling: transmission of control messages - for reliable writers and readers and retransmission of data on request. + channel-specific ‘timed-event’ handling: transmission of control messages + for reliable writers and readers and retransmission of data on request. Channel-specific threads exist only if the configuration includes an element for it or if an auxiliary bandwidth limit is set for the channel. @@ -1657,14 +1657,14 @@ Reporting and tracing DDSI2 can produce highly detailed traces of all traffic and internal activities. It enables individual categories of information, as well as having a simple verbosity level that enables fixed sets of categories and of which the definition -corresponds to that of the other OpenSplice services. +corresponds to that of the other Vortex OpenSplice services. The categorisation of tracing output is incomplete and hence most of the verbosity levels and categories are not of much use in the current release. This is an ongoing process and here we describe the target situation rather than the current situation. All *‘fatal’* and *‘error’* messages are written both to the DDSI2 log and to the -``ospl-error.log`` file; similarly all ‘warning’ messages are written to the DDSI2 +``ospl-error.log`` file; similarly all ‘warning’ messages are written to the DDSI2 log and the ``ospl-info.log`` file. The Tracing element has the following sub elements: @@ -1702,20 +1702,20 @@ In addition, the keyword *trace* enables all but *radmin*. + *OutputFile*: the file to write the DDSI2 log to + *AppendToFile*: - boolean, set to ``true`` to append to the log instead of replacing + boolean, set to ``true`` to append to the log instead of replacing the file. Currently, the useful verbosity settings are *config* and *finest*. -*Config* writes the full configuration to the DDSI2 log file as well as -any warnings or errors, which can be a good way to verify everything is +*Config* writes the full configuration to the DDSI2 log file as well as +any warnings or errors, which can be a good way to verify everything is configured and behaving as expected. -*Finest* provides a detailed trace of everything that occurs and is an -indispensable source of information when analysing problems; however, +*Finest* provides a detailed trace of everything that occurs and is an +indispensable source of information when analysing problems; however, it also requires a significant amount of time and results in huge log files. -Whether these logging levels are set using the verbosity level or by enabling +Whether these logging levels are set using the verbosity level or by enabling the corresponding categories is immaterial. .. _`Compatibility and conformance`: @@ -1729,42 +1729,42 @@ Conformance modes ================= The DDSI2 service operates in one of three modes: *pedantic*, *strict* and *lax*; -the mode is configured using the ``Compatibility/StandardsConformance`` setting. +the mode is configured using the ``Compatibility/StandardsConformance`` setting. The default is *lax*. (Please refer to the :ref:`Configuration ` section for -a detailed description of +a detailed description of ``//OpenSplice/DDSI2Service/Compatibility/StandardsConformance``.) -In *pedantic* mode, it strives very hard to strictly conform to the DDSI 2.1 -standard. It even uses a vendor-specific extension for an essential element -missing in the specification, used for specifying the GUID of a DCPS data reader -or data writer in the discovery protocol; and it adheres to the specified -encoding of the reliability QoS. This mode is of interest for compliancy -testing but not for practical use, even though there is no application-level -observable difference between an all-OpenSplice system using the DDSI2 +In *pedantic* mode, it strives very hard to strictly conform to the DDSI 2.1 +and 2.2 standards. It even uses a vendor-specific extension for an essential element +missing in the specification, used for specifying the GUID of a DCPS data reader +or data writer in the discovery protocol; and it adheres to the specified +encoding of the reliability QoS. This mode is of interest for compliancy +testing but not for practical use, even though there is no application-level +observable difference between an all-Vortex OpenSplice system using the DDSI2 service in pedantic mode and one operating in any of the other modes. -The second mode, *strict*, instead attempts to follow the *intent* of the -specification while staying close to the letter of it. The points in which -it deviates from the standard are in all probability editing errors that -will be rectified in the next update. When operated in this mode, one -would expect it to be fully interoperable with other vendors’ implementations, -but this is not the case. The deviations in other vendors’ implementations -are not required to implement DDSI 2.1, as is proven by the OpenSplice DDSI2 -service, and they cannot rightly be considered ‘true’ implementations of -the DDSI 2.1 standard. - -The default mode, *lax*, attempts to work around (most of) the deviations +The second mode, *strict*, instead attempts to follow the *intent* of the +specification while staying close to the letter of it. The points in which +it deviates from the standard are in all probability editing errors that +will be rectified in the next update. When operated in this mode, one +would expect it to be fully interoperable with other vendors’ implementations, +but this is not the case. The deviations in other vendors’ implementations +are not required to implement DDSI 2.1 (or 2.2), as is proven by the Vortex OpenSplice DDSI2 +service, and they cannot rightly be considered ‘true’ implementations of +the DDSI 2.1 (or 2.2) standard. + +The default mode, *lax*, attempts to work around (most of) the deviations of other implementations, and provides interoperability with (at least) RTI DDS and InterCOM/Gallium DDS. (For compatibility with TwinOaks CoreDX DDS, -additional settings are needed. See -:ref:`the next section ` -for more information.) -In lax mode, the OpenSplice DDSI2 service not only accepts some invalid -messages, but will even transmit them. The consequences for interoperability +additional settings are needed. See +:ref:`the next section ` +for more information.) +In lax mode, the Vortex OpenSplice DDSI2 service not only accepts some invalid +messages, but will even transmit them. The consequences for interoperability of not doing this are simply too severe. -It should be noted that if one configures two OpenSplice nodes with DDSI2 in +It should be noted that if one configures two Vortex OpenSplice nodes with DDSI2 in different compliancy modes, the one in the stricter mode will complain about messages sent by the one in the less strict mode. Pedantic mode will complain about invalid encodings used in strict mode, strict mode will complain about illegal @@ -1779,7 +1779,7 @@ Compatibility issues with RTI In *lax* mode, there should be no major issues with most topic types when working across a network, but within a single host there is a known problem with the way RTI DDS uses, or attempts to use, its shared memory transport to communicate with -OpenSplice, which clearly advertises only UDP/IP addresses at which it is +Vortex OpenSplice, which clearly advertises only UDP/IP addresses at which it is reachable. The result is an inability to reliably establish bidirectional communication between the two. @@ -1796,8 +1796,8 @@ maximum length larger than 11 bytes. See the DDSI specification for details. In *strict* mode, there is interoperation with RTI DDS, but at the cost of incredibly high CPU and network load, caused by a Heartbeats and AckNacks going -back-and-forth between a reliable RTI DDS data writer and a reliable OpenSplice -DCPS data reader. The problem is that once the OpenSplice reader informs the RTI +back-and-forth between a reliable RTI DDS data writer and a reliable Vortex OpenSplice +DCPS data reader. The problem is that once the Vortex OpenSplice reader informs the RTI writer that it has received all data (using a valid AckNack message), the RTI writer immediately publishes a message listing the range of available sequence numbers and requesting an acknowledgement, which becomes an endless loop. diff --git a/build/docs/DeploymentGuide/source/durability-service.rst b/build/docs/DeploymentGuide/source/durability-service.rst index 9e9d2f8d3..cd4cb1499 100644 --- a/build/docs/DeploymentGuide/source/durability-service.rst +++ b/build/docs/DeploymentGuide/source/durability-service.rst @@ -10,7 +10,7 @@ purpose of the service. After that all its concepts and mechanisms are described The exact fulfilment of the durability responsibilities is determined by the configuration of the Durability Service. -There are detailed descriptions of all of the available configuration +There are detailed descriptions of all of the available configuration parameters and their purpose in the :ref:`Configuration ` section. @@ -41,7 +41,7 @@ the DDS middleware and comes in four flavours: running on at least one of the nodes. *PERSISTENT* Data needs to outlive system downtime. This implies that it - must be kept somewhere on permanent storage in order to be able to make + must be kept somewhere on permanent storage in order to be able to make it available again for subscribers after the middleware is restarted. In Vortex OpenSplice, the realisation of the non-volatile properties is the @@ -113,8 +113,8 @@ collection are always handled as an atomic data-set by the durability service. I other words, the data is guaranteed to be stored and reinserted as a whole. This atomicity also implies that a name-space is a system-wide concept, meaning -that different durability services need to agree on its definition, *i.e.* which -partitions belong to one name-space. This doesn’t mean that each durability service +that different durability services need to agree on its definition, *i.e.* which +partitions belong to one name-space. This doesn’t mean that each durability service needs to know all name-spaces, as long as the name-spaces one does know don’t conflict with one of the others in the domain. Name-spaces that are completely disjoint can co-exist (their intersection is an empty set); name-spaces conflict when they @@ -160,7 +160,7 @@ This section describes the policies that can be configured per name-space giving user full control over the fault-tolerance versus performance aspect on a per name-space level. -Please refer to the :ref:`Configuration ` section for +Please refer to the :ref:`Configuration ` section for a detailed description of: + ``//OpenSplice/DurabilityService/NameSpaces/Policy`` @@ -230,7 +230,7 @@ associated with the data, for instance by storing persistent data only in memory it were transient. Reasons for this are performance impact (CPU load, disk I/O) or simply because no permanent storage (in the form of some hard-disk) is available on a node. Be aware that it is not possible to ‘strengthen’ the durability of the data -(Persistent > Transient > Volatile). +(Persistent > Transient > Volatile). The durability service has the following options for maintaining a set of historical data: @@ -259,10 +259,10 @@ Delayed alignment policy The durability service has a mechanism in place to make sure that when multiple services with a persistent dataset exist, only one set (typically the one with the -newest state) will be injected in the system (see `Persistent data injection`_). -This mechanism will, during the startup of the durability service, negotiate with -other services which one has the best set (see `Master selection`_). -After negotiation the ‘best’ persistent set (which can be empty) is restored +newest state) will be injected in the system (see `Persistent data injection`_). +This mechanism will, during the startup of the durability service, negotiate with +other services which one has the best set (see `Master selection`_). +After negotiation the ‘best’ persistent set (which can be empty) is restored and aligned to all durability services. Once persistent data has been re-published in the domain by a durability service for @@ -271,11 +271,11 @@ re-publish their own set for that name-space from disk any longer. Applications already have started their processing based on the already-published set, and re-publishing another set of data may confuse the business logic inside applications. Other durability services will therefore back-up their own set of data and align and -store the set that is already available in the domain. +store the set that is already available in the domain. -It is important to realise that an empty set of data is also considered a set. +It is important to realise that an empty set of data is also considered a set. This means that once a durability service in the domain decides that there is no data -(and has triggered applications that the set is complete), other late-joining +(and has triggered applications that the set is complete), other late-joining durability services will not re-publish any persistent data that they potentially have available. @@ -310,12 +310,12 @@ nodes may have been publishing information for the same topic in the same partition without this information reaching the other party. Therefore their perception of the set of data will be different. -In many cases, after this has occurred the exchange of information is no longer +In many cases, after this has occurred the exchange of information is no longer allowed, because there is no guarantee that data between the connected systems doesn’t -conflict. For example, consider a fault-tolerant (distributed) global id service: -this service will provide globally-unique ids, but this will be guaranteed +conflict. For example, consider a fault-tolerant (distributed) global id service: +this service will provide globally-unique ids, but this will be guaranteed *if and only if* there is no disruption of communication between all services. In such -a case a disruption must be considered permanent and a reconnection must be avoided +a case a disruption must be considered permanent and a reconnection must be avoided at any cost. Some new environments demand supporting the possibility to (re)connect two @@ -397,7 +397,7 @@ Prevent aligning equal data sets As explained in previous sections, temporary disconnections can cause durability services to get out-of-sync, meaning that their data sets may diverge. To recover -from such situations merge policies have been defined (see `Merge policy`_) +from such situations merge policies have been defined (see `Merge policy`_) where a user can specify how to combine divergent data sets when they become reconnected. Many of these situations involve the transfer of data sets from one durability service to the other. This may generate a considerable @@ -561,19 +561,19 @@ a detailed description of: Interaction with applications ============================= -The durability service is responsible for providing historical data to +The durability service is responsible for providing historical data to late-joining subscribers. Applications can use the DCPS API call ``wait_for_historical_data`` on a DataReader -to synchronise on the availability of the complete set of historical data. -Depending on whether the historical data is already available locally, data can be -delivered immediately after the DataReader has been created or must be aligned from -another durability service in the domain first. Once all historical data is delivered -to the newly-created DataReader, the durability service will trigger the DataReader -unblocking the ``wait_for_historical_data`` performed by the application. If the -application does not need to block until the complete set of historical data is -available before it starts processing, there is no need to call -``wait_for_historical_data``. It should be noted that in such a case historical +to synchronise on the availability of the complete set of historical data. +Depending on whether the historical data is already available locally, data can be +delivered immediately after the DataReader has been created or must be aligned from +another durability service in the domain first. Once all historical data is delivered +to the newly-created DataReader, the durability service will trigger the DataReader +unblocking the ``wait_for_historical_data`` performed by the application. If the +application does not need to block until the complete set of historical data is +available before it starts processing, there is no need to call +``wait_for_historical_data``. It should be noted that in such a case historical data still is delivered by the durability service when it becomes available. @@ -722,24 +722,51 @@ for every name-space, which is the next phase in its lifecycle. Master selection ================ -To ensure a single source for re-publishing of persistent data and to allow parallel -alignment, each durability service will select a master for every name-space. - -The rules for determining a master are: - -1. If some other durability service in the domain already selected - a master, pick the same one. - -2. If no master has been selected, pick the one with the newest - initial set of persistent data. - -3. If multiple durability services exist with the newest set of - initial persistent data, pick the one with the highest id - (this id is a domain-wide unique number that is - generated at start-up of each OpenSplice federation). - -If an existing master is no longer available, due to a disconnection, crash or -regular termination, a new master is selected based on the same rules. +For each Namespace and Role combination there shall be at most one Master Durability +Service. The Master Durability Service coordinates single source re-publishing of +persistent data and to allow parallel alignment after system start-up, +and to coordinate recovery of a split brain syndrome after connecting nodes having +selected a different Master indicating that more than one state of the data may exist. + +Therefore after system start-up as well as after any topology change (i.e. late joining +nodes or leaving master node) a master selection process will take place for each +affected Namespace/Role combination. + +To control the master selection process a masterPriority attribute can be used. + +Each Durability Service will have a configured masterPriority attribute per namespace +which is an integer value between 0 and 255 and which specifies the eagerness of the +Durability Service to become Master for that namespace. +The values 0 and 255 have a special meaning. +Value 0 is used to indicate that the Durability Service will never become Master. +The value 255 is used to indicate that the Durability Service will not use priorities +but instead uses the legacy selection algorithm. +If not configured the default is 255. + +During the master selection process each Durability service will exchange for each +namespace the masterPriority and quality. The namespace quality is the timestamp of the +latest update of the persistent data set stored on disk and only plays a role in master +selection initially when no master has been chosen before and persistent data has not +been injected yet. + +Each Durability Service will determine the Master based upon the highest non zero +masterPriority and in case of multiple masters further select based on namespace +quality (but only if persistent data has not been injected before) and again in case of +multiple masters select the highest system id. The local system id is an arbitrary +value which unique identifies a durability service. +After selection each Durability Service will communicate their determined master and on +agreement effectuate the selection, on disagreement which may occur if some Durability +Services had a temporary different view of the system this process of master selection +will restart until all Durability Services have the same view of the system and have +made the same selection. +If no durability services exists having a masterPriority greater than zero then no +master will be selected. + +Summarizing, the precedence rules for master selection are (from high to low): + +1. The namespace masterPriority +2. The namespace quality, if no data has been injected before. +3. The Durability Service system id, which is unique for each durability service. Please refer to the :ref:`Configuration ` section for a detailed description of: @@ -753,88 +780,88 @@ Persistent data injection ========================= As persistent data needs to outlive system downtime, this data needs to be -re-published in DDS once a domain is started. +re-published in DDS once a domain is started. -If only one node is started, the durability service on that node can simply -re-publish the persistent data from its disk. However, if multiple nodes are -started at the same time, things become more difficult. Each one of them may -have a different set available on permanent storage due to the fact that +If only one node is started, the durability service on that node can simply +re-publish the persistent data from its disk. However, if multiple nodes are +started at the same time, things become more difficult. Each one of them may +have a different set available on permanent storage due to the fact that durability services have been stopped at a different moment in time. Therefore only one of them should be allowed to re-publish its data, to prevent -inconsistencies and duplication of data. +inconsistencies and duplication of data. -The steps below describe how a durability service currently determines whether or +The steps below describe how a durability service currently determines whether or not to inject its data during start-up: -1. *Determine validity of own persistent data* — - During this step the durability service determines whether its persistent - store has initially been completely filled with all persistent data in the - domain in the last run. If the service was shut down in the last run - during initial alignment of the persistent data, the set of data will be - incomplete and the service will restore its back-up of a full set of (older) +1. *Determine validity of own persistent data* — + During this step the durability service determines whether its persistent + store has initially been completely filled with all persistent data in the + domain in the last run. If the service was shut down in the last run + during initial alignment of the persistent data, the set of data will be + incomplete and the service will restore its back-up of a full set of (older) data if that is available from a run before that. This is done because it - is considered better to re-publish an older but complete set of data instead + is considered better to re-publish an older but complete set of data instead of a part of a newer set. -2. *Determine quality of own persistent data* — - If persistence has been configured, the durability service will inspect the - quality of its persistent data on start-up. The quality is determined on a - *per-name-space* level by looking at the time-stamps of the persistent data - on disk. The latest time-stamp of the data on disk is used as the quality - of the name-space. This information is useful when multiple nodes are started - at the same time. Since there can only be one source per name-space that is - allowed to actually inject the data from disk into DDS, this mechanism allows - the durability services to select the source that has the latest data, because - this is generally considered the best data. If this is not true then an - intervention is required. The data on the node must be replaced by the - correct data either by a supervisory (human or system management application) +2. *Determine quality of own persistent data* — + If persistence has been configured, the durability service will inspect the + quality of its persistent data on start-up. The quality is determined on a + *per-name-space* level by looking at the time-stamps of the persistent data + on disk. The latest time-stamp of the data on disk is used as the quality + of the name-space. This information is useful when multiple nodes are started + at the same time. Since there can only be one source per name-space that is + allowed to actually inject the data from disk into DDS, this mechanism allows + the durability services to select the source that has the latest data, because + this is generally considered the best data. If this is not true then an + intervention is required. The data on the node must be replaced by the + correct data either by a supervisory (human or system management application) replacing the data files or starting the nodes in the desired sequence so that data is replaced by alignment. -3. *Determine topology* — - During this step, the durability service determines whether there are other +3. *Determine topology* — + During this step, the durability service determines whether there are other durability services in the domain and what their state is. - If this service is the only one, it will select itself as the ‘best’ source + If this service is the only one, it will select itself as the ‘best’ source for the persistent data. -4. *Determine master* — +4. *Determine master* — During this step the durability service will determine who - will inject persistent data or who has injected persistent data already. - The one that will or already has injected persistent data is called the - *‘master’*. This process is done on a per name-space level + will inject persistent data or who has injected persistent data already. + The one that will or already has injected persistent data is called the + *‘master’*. This process is done on a per name-space level (see previous section). - a) *Find existing master* – - In case the durability service joins an already-running domain, - the master has already been determined and this one has already - injected the persistent data from its disk or is doing it right now. - In this case, the durability service will set its current set of - persistent data aside and will align data from the already existing - master node. If there is no master yet, persistent data has not + a) *Find existing master* – + In case the durability service joins an already-running domain, + the master has already been determined and this one has already + injected the persistent data from its disk or is doing it right now. + In this case, the durability service will set its current set of + persistent data aside and will align data from the already existing + master node. If there is no master yet, persistent data has not been injected yet. - b) *Determine new master* – - If the master has not been determined yet, the durability service - determines the master for itself based on who has the best quality + b) *Determine new master* – + If the master has not been determined yet, the durability service + determines the master for itself based on who has the best quality of persistent data. In case there is more than one service with the ‘best’ quality, the one with the highest system id (unique number) is - selected. Furthermore, a durability service that is marked as not - being an aligner for a name-space cannot become master for + selected. Furthermore, a durability service that is marked as not + being an aligner for a name-space cannot become master for that name-space. -5. *Inject persistent data* — - During this final step the durability service injects its persistent data - from disk into the running domain. This is *only* done when the service has +5. *Inject persistent data* — + During this final step the durability service injects its persistent data + from disk into the running domain. This is *only* done when the service has determined that it is the master. In any other situation the durability - service backs up its current persistent store and fills a new store with - the data it aligns from the master durability service in the domain, or + service backs up its current persistent store and fills a new store with + the data it aligns from the master durability service in the domain, or postpones alignment until a master becomes available in the domain. |caution| - It is strongly discouraged to re-inject persistent data from a persistent - store in a running system after persistent data has been published. - Behaviour of re-injecting persistent stores in a running system is not + It is strongly discouraged to re-inject persistent data from a persistent + store in a running system after persistent data has been published. + Behaviour of re-injecting persistent stores in a running system is not specified and may be changed over time. @@ -859,8 +886,8 @@ Align historical data Once all topic and partition information for all configured name-spaces are known, the initial alignment of historical data takes place. Depending on the configuration -of the service, data is obtained either immediately after discovering it or only once -local interest in the data arises. The process of aligning historical data continues +of the service, data is obtained either immediately after discovering it or only once +local interest in the data arises. The process of aligning historical data continues during the entire lifecycle of the durability service. @@ -869,8 +896,8 @@ during the entire lifecycle of the durability service. Provide historical data ======================= -Once (a part of) the historical data is available in the durability service, it is -able to provide historical data to local DataReaders as well as other durability +Once (a part of) the historical data is available in the durability service, it is +able to provide historical data to local DataReaders as well as other durability services. Providing of historical data to local DataReaders is performed automatically as soon @@ -898,6 +925,239 @@ the configured merge-policies will determine what actions are performed to recov from this situation. The process of merging historical data will be performed every time two separately running systems get (re-)connected. +.. _`Threads description`: + +Threads description +******************* + +This section contains a short description of each durability thread. When applicable, +relevant configuration parameters are mentioned. + +ospl_durability +=============== +This is the main durability service thread. It starts most of the other threads, e.g. +the listener threads that are used to receive the durability protocol messages, +and it initiates initial alignment when necessary. This thread is responsible for +periodically updating the service-lease so that the splice-daemon is aware the service +is still alive. It also periodically (every 10 seconds) checks the state of all other +service threads to detect if deadlock has occurred. If deadlock has occurred the service +will indicate which thread didn't make progress and action can be taken (e.g. the service +refrains from updating its service-lease, causing the splice daemon to execute a failure +action). Most of the time this thread is asleep. + +conflictResolver +================ +This thread is responsible for resolving conflicts. If a conflict has been detected and +stored in the conflictQueue, the conflictResolver thread takes the conflict, checks +whether the conflict still exists, and if so, starts the procedure to resolve the conflict +(i.e., start to determine a new master, send out sample requests, etc). + +statusThread +============ +This thread is responsible for the sending status messages to other durability services. +These messages are periodically sent between durability services to inform each other +about their state (.e.,g INITIALIZING or TERMINATING). + +Configuration parameters: + ++ ``//OpenSplice/DurabilityService/Watchdog/Scheduling`` + +d_adminActionQueue +================== +The durability service maintains a queue to schedule timed action. The d_adminActionQueue +periodically checks (every 100 ms) if an action is scheduled. +Example actions are: electing a new master, detection of new local groups and deleting +historical data. + +Configuration parameters: + ++ ``//OpenSplice/DurabilityService/Network/Heartbeat/Scheduling`` + +AdminEventDispatcher +==================== +Communication between the splice-daemon and durability service is managed by events. The +AdminEventDispatcher thread listens and acts upon these events. For example, the creation +of a new topic is noticed by the splice-daemon, which generates an event for the +durability service, which schedules an action on to request historical data for the topic. + +groupCreationThread +=================== +The groupCreationThread is responsible for the creation of groups that exist in other +federations. When a durability service receives a newGroup message from another +federation, it must create the group locally in order to acquire data for it. +Creation of a group may fail in case a topic is not yet known. The thread will retry with +a 10ms interval. + +sampleRequestHandler +==================== +This thread is responsible for the handling of sampleRequests. When a durability +service receives a d_sampleRequest message (see the sampleRequestListener thread) it +will not immediately answer the request, but wait some time until the time to combine +requests has been expired (see +//OpenSplice/DurabilityService/Network/Alignment/RequestCombinePeriod). When this time +has expired the sampleRequestHandler will answer the request by collecting the requested +data and sending the data as d_sampleChain messages to the requestor. + +Configuration parameters: + ++ ``//OpenSplice/DurabilityService/Network/Alignment/AlignerScheduling`` + +resendQueue +=========== +This thread is responsible for injection of message in the group after it has been rejected +before. When a durability service has received historical data from another fellow, +historical data is injected in the group (see d_sampleChain). Injection of historical data +can be rejected, e.g., when a resource limits are being used. When this happens, a new attempt +to inject the data is scheduled overusing the resendQueue thread. This thread will try to +deliver the data 1s later. + +Configuration parameters: + ++ ``//OpenSplice/DurabilityService/Network/Alignment/AligneeScheduling`` + +masterMonitor +============= +The masterMonitor is the thread that handles the selection of a new master. This thread is +invoked when the conflict resolver detects that a master conflict has occurred. The +masterMonitor is responsible for collecting master proposals from other fellows and sending +out proposals to other fellows. + +groupLocalListenerActionQueue +============================= +This thread is used to handle historical data requests from specific readers, and to handle +delayed alignment (see //OpenSplice/DurabilityService/NameSpaces/Policy[@delayedAlignment]) + +d_groupsRequest +=============== +The d_groupsRequest thread is responsible for processing incoming d_groupsRequest messages +from other fellows. When a durability service receives a message from a fellow, the durability +service will send information about its groups to the requestor by means of d_newGroup messages. +This thread collects group information, packs it in d_newGroup messages and send them to the +requestor. This thread will only do something when a d_groupsRequest has been received from a +fellow. Most of the time it will sleep. + +d_nameSpaces +============ +This thread is responsible for processing incoming d_nameSpaces messages from other fellows. +Durability services send each other their namespaces state so that they can detect potential +conflicts. The d_nameSpaces thread processes and administrates every incoming d_nameSpace. When +a conflict is detected, the conflict is scheduled which may cause the conflictResolver thread +to kick in. + +d_nameSpacesRequest +=================== +The d_nameSpacesRequest thread is responsible for processing incoming d_nameSpacesRequest +messages from other fellows. A durability service can request the namespaces form a fellow by +sending a d_nameSpacesRequest message to the fellow. Whenever a durability service receives a +d_nameSpacesRequest messages it will respond by sending its set of namespaces to the fellow. +The thread handles incoming d_nameSpacesRequest messages. As a side effect new fellows can be +discovered if a nameSpacesRequest is received from an unknown fellow. + +d_status +======== +The d_status thread is responsible for processing incoming d_status messages from other fellows. +Durability services periodically send each other status information (see the statusThread). +NOTE: in earlier versions missing d_status messages could lead to the conclusion that a fellows +has been removed. In recent versions this mechanism has been replaced so that the durability +service slaves itself to the liveness of remote federations based on heartbeats +(see thread dcpsHeartbeatListener). Effectivily, the d_status message is not used anymore to +verify liveliness of remote federations, it is only used to transfer the durability state of +a remote federation. + +d_newGroup +========== +The d_newGroup thread is responsible for handling incoming d_newGroup messages from other fellows. +Durability services inform each other about groups in the namespaces. They do that by sending +d_newGroup messages to each other (see also thread d_groupsRequest). The d_newGroup thread is +responsible for handling incoming groups. + +d_sampleChain +============= +The d_sampleChain thread handles incoming d_sampleChain messages from other fellows. When a +durability service answers an d_sampleRequest, it must collect the requested data and send it +to the requestor. The collected data is packed in d_sampleChain messages. The d_sampleChain thread +handles incoming d_sampleChain messages and applies the configured merge policy for the data. +For example, in case of a MERGE it injects all the received data in the local group and delivers +the data to the available readers. + +Configuration parameters: + ++ ``//OpenSplice/DurabilityService/Network/Alignment/AligneeScheduling`` + +d_sampleRequest +=============== +The d_sampleRequest thread is responsible for handling incoming d_sampleRequest messages from +other fellows. A durability service can request historical data from a fellow by sending a +d_sampleRequest message. The d_sampleRequest thread is used to process d_sampleRequest messages. +Because d_sampleRequest messages are not handled immediately, they are stored in a list and handled +later on (see thread sampleRequestHandler). + +d_deleteData +============ +The d_deleteData thread is responsible for handling incoming d_deleteData messages from other fellows. +An application can call delete_historical_data(). This causes all historical data up till now to be +deleted. To propagate deletion of historical data to all available durability services in the system, +durability services send each other a d_deleteData message. The d_deleteData thread handles incoming +d_deleteData messages and takes care that the relevant data is deleted. This thread will only be active +after delete_historical_data() is called. + +dcpsHeartbeatListener +===================== +The dcpsHeartbeatListener is responsible for the liveliness detection of remote federations. This +thread listens to DCPSHeartbeat messages that are sent by federation. It is used to detect new +federations or federations that disconnect. This thread will only do something when there is a change +in federation topology. Most of the time it will be asleep. + +d_capability +============ +The thread is responsible for processing d_cability messages from other fellows. As soon as a durability +service detects a fellow it will send its list of capabilities to the fellow. The fellow can use this +list to find what functionality is supported by the durability service. Similarly, the durability +service can receive capabilities from the fellow. This thread is used to process the capabilities sent by +a fellow. This thread will only do something when a fellow is detected. | | + +remoteReader +============ +The remoteReader thread is responsible for the detection of remote readers on other federations. The DDSI +service performs discovery and reader-writing matching. This is an asynchronous mechanism. When a +durability service (say A) receives a request from a fellow durability service (say B) and DDSI is used +as networking service, then A cannot be sure that DDSI has already detected the reader on B that should +receive the answer to the request. To ensure that durability services will only answer if all relevant +remote readers have been detected, the remoteReader thread keeps track of the readers that have been +discovered by ddsi. Only when all relevant readers have been discovered durability services are allowed +to answer requests. This prevents DDSI from dropping messages destined for readers that have not been +discovered yet. + +persistentDataListener +====================== +The persistentDataListenerThread is responsible for persisting durable data. When a durability service +retrieves persistent data, the data is stored in a queue. The persistentDataListener thread retrieves the +data from the queue and stores it in the persistent store. For large data sets persisting the data can take +quite some time, depending mostly on the performance of the disk. + +Note this thread is only created when persistency is enabled +(//OpenSplice/DurabilityService/Persistent/StoreDirectory has a value set): + +Configuration parameters: + ++ ``//OpenSplice/DurabilityService/Persistent/Scheduling`` + +historicalDataRequestHandler +============================ +This thread is responsible for handling incoming historicalDataRequest messages from durability clients. In +case an application does not have the resources to run a durability service but still wants to acquire +historical data it can configure a client. The client sends HistoricalDataRequest messages to the durability +service. These messages are handled by the historicalDataRequestHandler thread. + +Note this thread is only created when client durability is enabled +(//OpenSplice/DurabilityService/ClientDurability element exists) + +durabilityStateListener +======================= +This thread is responsible for handling incoming durabilityStateRequest messages from durability clients. + +Note this thread is only created when client durability is enabled +(//OpenSplice/DurabilityService/ClientDurability element exists) .. EoF diff --git a/build/docs/DeploymentGuide/source/images/Vortex-OpenSplice-Cover.png b/build/docs/DeploymentGuide/source/images/Vortex-OpenSplice-Cover.png index ce86c6d94..801c02bb8 100644 Binary files a/build/docs/DeploymentGuide/source/images/Vortex-OpenSplice-Cover.png and b/build/docs/DeploymentGuide/source/images/Vortex-OpenSplice-Cover.png differ diff --git a/build/docs/DeploymentGuide/source/index.rst b/build/docs/DeploymentGuide/source/index.rst index e127b43fe..0fb60c779 100644 --- a/build/docs/DeploymentGuide/source/index.rst +++ b/build/docs/DeploymentGuide/source/index.rst @@ -7,10 +7,10 @@ The Vortex OpenSplice Deployment Guide .. toctree:: :maxdepth: 8 :numbered: - + preface overview - + service-feature-list domain-service durability-service @@ -19,15 +19,17 @@ The Vortex OpenSplice Deployment Guide networkingbridge-service tuner-service dbmsconnect-service - + tools - + guide referencesystems - contacts - + logrotate + + contacts + Indices and tables ================== diff --git a/build/docs/DeploymentGuide/source/logrotate.rst b/build/docs/DeploymentGuide/source/logrotate.rst new file mode 100644 index 000000000..017a78f24 --- /dev/null +++ b/build/docs/DeploymentGuide/source/logrotate.rst @@ -0,0 +1,74 @@ +.. _`Logrotate`: + + +######### +Logrotate +######### + +*The OpenSplice middleware can produce several trace and log files +depending on the applied configuration settings. Log files and in +particular trace files can become very large over time and run into +resource limitations. It is advised to use the logrotate function +to manage resource consumption of log and trace files. The logrotate +function is standard available on linux distributions and for windows +an opensource version is available on sourceforge (LogRotateWin).** + +.. _`Description`: + +Description +*********** + +logrotate is designed to ease administration of systems that generate +large numbers of log files. It allows automatic rotation, compression, +removal, and mailing of log files. Each log file may be handled daily, +weekly, monthly, or when it grows too large. +Normally, logrotate is run as a daily cron job. It will not modify a +log multiple times in one day unless the criterion for that log is +based on the log's size and logrotate is being run multiple times each +day, or unless the -f or --forceoption is used. For example, logrotate +can also be run by a supervisory process at any time to process log +files specified in the config_file. +For a more detailed description of logrotate see the linux man pages. + +.. _`Configuration file`: + +Configuration file +****************** + +logrotate reads everything about the log files it should be handling +from the series of configuration files specified on the command line. +Each configuration file can set global options (local definitions +override global ones, and later definitions override earlier ones) +and specify log files to rotate. + +.. _`Example configuration`: + +Example configuration +********************* + +For OpenSplice the following example config_file arguments are advised for logrotate: + +.. code-block:: bash + + # sample logrotate configuration file + + # The copytruncate option specifies that logfiles are first copied and + # then truncate. This option is required for OpenSplice instead of using + # the create option to avoid closing the file descriptors used by + # OpenSplice. + # + copytruncate + + # The compress option is used to compress the logfile copies. + compress + + # The following options specify that the log files in the current directory + # will be rotates when the file size exceeds 100k and that at most the 5 + # most recent rotated files are maintained. + "./\*.log" { + rotate 5 + size 100k + } + +.. EoF + diff --git a/build/docs/DeploymentGuide/source/overview.rst b/build/docs/DeploymentGuide/source/overview.rst index 351522fc7..91ed5119a 100644 --- a/build/docs/DeploymentGuide/source/overview.rst +++ b/build/docs/DeploymentGuide/source/overview.rst @@ -4,47 +4,47 @@ Overview ######## -*This chapter explains the Vortex OpenSplice middleware from -a configuration perspective. It shows the different components -running on a single node and briefly explains the role of each -entity. Furthermore, it defines a reference system that will +*This chapter explains the Vortex OpenSplice middleware from +a configuration perspective. It shows the different components +running on a single node and briefly explains the role of each +entity. Furthermore, it defines a reference system that will be used throughout the rest of the document as an example.* -.. _`Vortex OpenSplice DDS architecture`: +.. _`Vortex OpenSplice architecture`: Vortex OpenSplice Architecture ****************************** -Vortex OpenSplice is highly configurable, even allowing the architectural +Vortex OpenSplice is highly configurable, even allowing the architectural structure of the DDS middleware to be chosen by the user at deployment time. -Vortex OpenSplice can be configured to run using a so-called ‘federated’ -*shared memory* architecture, where both the DDS related administration -(including the optional pluggable services) and DDS applications interface +Vortex OpenSplice can be configured to run using a so-called ‘federated’ +*shared memory* architecture, where both the DDS related administration +(including the optional pluggable services) and DDS applications interface directly with shared memory. -Alternatively, Vortex OpenSplice also supports a so-called ‘standalone’ -*single process* architecture, where one or more DDS applications, -together with the OpenSplice administration and services, can all be -grouped into a single operating system process. +Alternatively, Vortex OpenSplice also supports a so-called ‘standalone’ +*single process* architecture, where one or more DDS applications, +together with the OpenSplice administration and services, can all be +grouped into a single operating system process. -Both deployment modes support a configurable and extensible set +Both deployment modes support a configurable and extensible set of services, providing functionality such as: + *networking* - providing QoS-driven real-time networking based on multiple reliable multicast ‘channels’ -+ *durability* - providing fault-tolerant storage for both real-time state ++ *durability* - providing fault-tolerant storage for both real-time state data as well as persistent settings + *remote control and monitoring SOAP service* - providing remote web-based access using the SOAP protocol from various Vortex OpenSplice tools -+ *dbms service* - providing a connection between the real-time and the ++ *dbms service* - providing a connection between the real-time and the enterprise domain by bridging data from DDS to DBMS and *vice versa* -The Vortex OpenSplice middleware can be easily configured, on the fly, using -its pluggable service architecture: the services that are needed can be -specified together with their configuration for the particular application +The Vortex OpenSplice middleware can be easily configured, on the fly, using +its pluggable service architecture: the services that are needed can be +specified together with their configuration for the particular application domain, including networking parameters, and durability levels for example). There are advantages to both the single process and shared memory deployment @@ -121,7 +121,7 @@ The diagram `The Vortex OpenSplice Shared Memory Architecture`_ shows an overview of the shared memory architecture of Vortex OpenSplice on *one* computing node. Typically, there are *many* nodes within a system. -.. _`The Vortex OpenSplice Shared Memory Architecture`: +.. _`The Vortex OpenSplice Shared Memory Architecture`: .. centered:: **The Vortex OpenSplice Shared Memory Architecture** @@ -129,7 +129,7 @@ shows an overview of the shared memory architecture of Vortex OpenSplice on :height: 70mm :align: center :alt: The Vortex OpenSplice Shared Memory Architecture - + .. _`Comparison of Deployment Architectures`: @@ -157,14 +157,14 @@ basically about going for out-of-the-box simplicity or for maximum performance: :height: 35mm :align: center :alt: Federated Application Cluster - + **Non-federated, `single process’ Applications** - - Each application links the required DDS services as libraries + - Each application links the required DDS services as libraries into a standalone ‘single process’ - Resources are managed by each individual application - - Added value: Ease-of-use (‘zero-configuration’, middleware + - Added value: Ease-of-use (‘zero-configuration’, middleware lifecycle is simply coupled to that of the application process) @@ -222,7 +222,7 @@ single-process architecture start with ``ospl_sp_`` whereas federated-deployment configurations start with ``ospl_shmem_``. -.. _`Vortex OpenSplice DDS Usage`: +.. _`Vortex OpenSplice Usage`: Vortex OpenSplice Usage @@ -233,14 +233,14 @@ and libraries can be found in order to be able to start the Domain Service. |unix| |linux| - On UNIX-like platforms this can be realized by starting a shell and - sourcing the ``release.com`` file located in the root directory of + On UNIX-like platforms this can be realized by starting a shell and + sourcing the ``release.com`` file located in the root directory of the Vortex OpenSplice installation: -:: +:: % . ./release.com - + |windows| @@ -249,7 +249,7 @@ and libraries can be found in order to be able to start the Domain Service. -.. _`Starting Vortex OpenSplice DDS for a Single Process Deployment`: +.. _`Starting Vortex OpenSplice for a Single Process Deployment`: Starting Vortex OpenSplice for a Single Process Deployment ========================================================== @@ -261,7 +261,7 @@ associated services at the point when the DDS ``create_participant`` operation i invoked by the standalone application process. -.. _`Starting Vortex OpenSplice DDS for a Shared Memory Deployment`: +.. _`Starting Vortex OpenSplice for a Shared Memory Deployment`: Starting Vortex OpenSplice for a Shared Memory Deployment ========================================================= @@ -271,10 +271,10 @@ Domain Service prior to running a DDS application. The ``ospl`` command-tool is provided to manage Vortex OpenSplice for shared memory deployments. To start Vortex OpenSplice in this way, enter: -:: +:: % . ./release.com - + This will start the Domain Service using the default configuration. |caution| @@ -287,7 +287,7 @@ This will start the Domain Service using the default configuration. |caution| **NOTE**: The **VxWorks** version of Vortex OpenSplice does not include the ``ospl`` - program. Please refer to the *Getting Started Guide* for details of how to use + program. Please refer to the *Getting Started Guide* for details of how to use VxWorks projects and Real Time Processes to deploy Vortex OpenSplice applications. @@ -319,7 +319,7 @@ specifying ````). The names of these log files can also be changed by se Vortex OpenSplice also accepts the environment properties ``OSPL_VERBOSITY`` and ``OSPL_LOGAPPEND``. These provide an alternate method of specifying values for -Attribute ``append`` and Attribute ``verbosity`` of the ``Domain/Report`` +Attribute ``append`` and Attribute ``verbosity`` of the ``Domain/Report`` configuration element (see the :ref:`Configuration ` section for details). @@ -363,12 +363,12 @@ for detailed information about ``mmstat``. |caution| - Please note that ``mmstat`` is only suitable for diagnostic purposes, + Please note that ``mmstat`` is only suitable for diagnostic purposes, and its use is only applicable in shared memory mode. -.. _`Stopping Vortex OpenSplice DDS`: +.. _`Stopping Vortex OpenSplice`: Stopping Vortex OpenSplice ========================== @@ -381,8 +381,8 @@ Stopping a Single Process deployment When deployed as a single process, the application can either be terminated naturally when the end of the main function is reached, or stopped prematurely by -means of a signal interrupt, for example ``Ctrl-C``. In either case, the -Vortex OpenSplice middleware running within the process will be stopped and the +means of a signal interrupt, for example ``Ctrl-C``. In either case, the +Vortex OpenSplice middleware running within the process will be stopped and the process will terminate. @@ -394,7 +394,7 @@ Stopping a Shared Memory deployment In shared memory deployment mode, the Vortex OpenSplice Domain Service can be stopped by issuing the following command on the command-line. -:: +:: % ospl stop @@ -410,7 +410,7 @@ Stopping OSPL by using signals ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Alternatively the Vortex OpenSplice domain service can also be stopped by sending a -signal to the ``ospl`` process, assuming the process was started using the ``-f`` +signal to the ``ospl`` process, assuming the process was started using the ``-f`` option. |unix| @@ -418,7 +418,7 @@ option. For example, on Unix you could use the following command to send a termination signal to the ``ospl`` tool, where ```` identifies the ``ospl`` tool pid: -:: +:: % kill –SIGTERM @@ -510,7 +510,7 @@ application is terminated by other means (*e.g.* by terminating with ``Ctrl+C``) or even if the application crashes in the user code. |caution| - + The cleanup mechanisms are *not* executed when an application is terminated with a ``KILL`` signal. For this reason a user must not terminate an application with a ``kill -9`` command (or, on Windows, must not use TaskManager’s *End Process* @@ -521,7 +521,7 @@ or even if the application crashes in the user code. node. -.. _`Deploying Vortex OpenSplice DDS on VxWorks 6.x`: +.. _`Deploying Vortex OpenSplice on VxWorks 6.x`: Deploying Vortex OpenSplice on VxWorks 6.x ========================================== @@ -532,7 +532,7 @@ VxWorks projects and Real Time Processes to deploy Vortex OpenSplice applications. -.. _`Deploying Vortex OpenSplice DDS on Integrity`: +.. _`Deploying Vortex OpenSplice on Integrity`: Deploying Vortex OpenSplice on Integrity ======================================== @@ -545,7 +545,7 @@ Vortex OpenSplice deployment on Integrity. -.. _`Installing/Uninstalling the Vortex OpenSplice DDS C# Assembly to the Global Assembly Cache`: +.. _`Installing/Uninstalling the Vortex OpenSplice C# Assembly to the Global Assembly Cache`: Installing/Uninstalling the Vortex OpenSplice C# Assembly to the Global Assembly Cache ====================================================================================== @@ -576,7 +576,7 @@ to the following: :: % C:\Program Files\Microsoft Visual Studio 9.0\VC>gacutil.exe /i - "C:\Program Files \PrismTech\VortexOpenSplice\V6.6.0\HDE\x86.win32\ + "C:\Program Files \ADLINK\VortexOpenSplice\V6.6.0\HDE\x86.win32\ bin\dcpssacsAssembly.dll" % % Microsoft (R) .NET Global Assembly Cache Utility. Version @@ -628,7 +628,7 @@ If you are successful you will see a message similar to the following: |caution| +---------------------------------------------------------------------------+ - | If you do not specify a version to the uninstall option, then all | + | If you do not specify a version to the uninstall option, then all | | installed Vortex OpenSplice C# Assemblies in the GAC called | | ``dcpssacsAssembly`` will be removed from the GAC, so take care with | | this option as it can adversely affect any deployed applications that | @@ -640,7 +640,7 @@ If you are successful you will see a message similar to the following: -.. _`Vortex OpenSplice DDS Configuration`: +.. _`Vortex OpenSplice Configuration`: Vortex OpenSplice Configuration ******************************* @@ -688,7 +688,7 @@ environment variables. When specifying configuration parameter values in a configuration file, environment variables can be referenced using the notation ``${VARIABLE}``. -When parsing the XML configuration, the Domain Service will replace the symbol +When parsing the XML configuration, the Domain Service will replace the symbol with the variable value found in the environment. @@ -704,7 +704,7 @@ be overridden to refer to a customer configuration. For single process mode operation this variable is required; see also `Single Process architecture`_ in this *Guide*, and -the detailed description of the Element ``//OpenSplice/Domain/SingleProcess`` +the detailed description of the Element ``//OpenSplice/Domain/SingleProcess`` in the :ref:`Configuration ` section. @@ -727,9 +727,9 @@ Configuration of Single Process deployment A single process deployment is enabled when the ``OSPL_URI`` environment variable refers to an XML configuration containing the ```` attribute within -the Domain section (``//OpenSplice/Domain/SingleProcess``). +the Domain section (``//OpenSplice/Domain/SingleProcess``). See the :ref:`Configuration ` section for full details. -In such a deployment, each Vortex OpenSplice service including the Domain Service +In such a deployment, each Vortex OpenSplice service including the Domain Service will be started as threads within the existing application process. In this case there is no need to start the Vortex OpenSplice administration manually @@ -750,7 +750,7 @@ In order to have Vortex OpenSplice start with a custom configuration file, use: % ospl start -where ```` denotes the URI of the Domain Service configuration file. +where ```` denotes the URI of the Domain Service configuration file. In order to stop a specific Vortex OpenSplice instance, the same mechanism holds. Use: @@ -778,7 +778,7 @@ To stop all active Vortex OpenSplice Domains, use: Note that the ```` parameter to the above commands is not required if the -``OSPL_URI`` environment variable refers to the configuration that is intended +``OSPL_URI`` environment variable refers to the configuration that is intended to be started or stopped. @@ -800,7 +800,7 @@ need to manipulate these files directly. if ``TEMP`` is not set) environment variable. These locations can be over-ridden, if required, by setting the ``OSPL_TEMP`` variable to a location on disk by specifying a path. - Please note, however, that this **must** be consistent for **all** + Please note, however, that this **must** be consistent for **all** environments on a particular node. @@ -833,7 +833,7 @@ Vortex OpenSplice daemon (and any services) for that domain and the application This requires some thought when configuring multiple Vortex OpenSplice domains on a single node. Care must be taken to ensure that the XML configuration files contain unique and non-overlapping addresses for the shared memory mapping (please also -see the description of the XML element ``//OpenSplice/Domain/Database/Address`` in +see the description of the XML element ``//OpenSplice/Domain/Database/Address`` in the :ref:`Configuration ` section). When designing and coding applications, care must also be taken with regard to @@ -879,7 +879,7 @@ history of an instance based on either the source time stamp or the reception time stamp. This is controlled by means of the ``DestinationOrderQosPolicy``. The ``HistoryQosPolicy`` controls how many historic samples are stored in a -reader. By default, a DataReader has a ``KEEP_LAST`` history with a depth +reader. By default, a DataReader has a ``KEEP_LAST`` history with a depth of ``1``. This means that only the ‘last’ (based on the ordering defined by the ``DestinationOrderQosPolicy``) sample for each instance is maintained by the middleware. When a sample is received by the subscriber, it determines whether and @@ -888,10 +888,10 @@ where to insert the sample in the history of an instance based on either the sou the instance. ``BY_SOURCE_ time stamp`` - If samples are ordered by source time stamp - and time is set back 1 hour on the subscriber node, nothing changes. If it - is set back one hour on the publisher node, samples written after the time - has changed have ‘older’ source time stamps and will therefore not overwrite + If samples are ordered by source time stamp + and time is set back 1 hour on the subscriber node, nothing changes. If it + is set back one hour on the publisher node, samples written after the time + has changed have ‘older’ source time stamps and will therefore not overwrite the samples in the history from before the time changed. ``BY_RECEPTION_ time stamp`` @@ -945,16 +945,16 @@ if supported by the OS. *Real-time clock* This is the main clock used for time stamps on data and - data-related actions. This time is typically kept close to the actual + data-related actions. This time is typically kept close to the actual time by the OS by means of NTP or the like. This clock can also be provided - by the customer through the *`UserClock’* functionality - (``//OpenSplice/Domain/UserClockService`` is fully described in + by the customer through the *`UserClock’* functionality + (``//OpenSplice/Domain/UserClockService`` is fully described in the :ref:`Configuration ` section). -*Monotonic clock* +*Monotonic clock* This is a clock that never jumps back and which provides a measure for the time a machine has been running since boot. When the time - is adjusted, this clock will not jump forward or backward. This clock + is adjusted, this clock will not jump forward or backward. This clock doesn’t include the time spent when a machine was suspended. *Elapsed time clock* @@ -976,11 +976,11 @@ For now this change is only done for CORBA C++ and CORBA Java and all internal D All other language bindings still use the 32-bit representation. Version 6.7 is fully compatible with older versions and will communicate by default in the 32-bit time representation with other nodes. If the domain/y2038Ready option is set, the node will use the new 64-bit second representation which -makes it incompatible with older nodes prior to version 6.7. (``//OpenSplice/Domain/y2038Ready`` is fully described +makes it incompatible with older nodes prior to version 6.7. (``//OpenSplice/Domain/y2038Ready`` is fully described in the :ref:`Configuration ` section) -.. _`CORBA C++`: +.. _`CORBA C++`: CORBA C++ ========= @@ -990,14 +990,14 @@ To rebuild this library to get support for the new 64-bit DDS_Time_t representat document which explains how to do this. -.. _`CORBA Java`: +.. _`CORBA Java`: CORBA Java ========== By default the CORBA Java library (dcpscj.jar) that comes with OpenSplice is built with support for the 32-bit DDS_Time_t representation. A new library dcpscj_y2038_ready.jar is added which supports the new 64-bit DDS_Time_t representation. This library can be used when -time stamps beyond year 2038 are needed. +time stamps beyond year 2038 are needed. .. _`Migration`: @@ -1006,19 +1006,19 @@ Migration ========= *client-durability* - Users that use client-durability cannot use times beyond 2038. This is because the client + Users that use client-durability cannot use times beyond 2038. This is because the client durability protocol uses DDS_Time_t in 32-bit. Also, Lite and Cafe do not support 64-bit yet. *DDS_Time_t in user data model* Users that currently use DDS_Time_t in their user-defined data structures cannot migrate a running system. If they want to migrate, the complete system must be shut down and delete all storages containing the old - 32-bit dds_time topics stored by the durability service. Rebuild the data models with the new 64-bit - dds_time topics and restart the system. Running a mixed environment with old and new dds_time structures + 32-bit dds_time topics stored by the durability service. Rebuild the data models with the new 64-bit + dds_time topics and restart the system. Running a mixed environment with old and new dds_time structures will result in topic mismatches. *Record and Replay (RnR) service* Users that use the Record and Replay service cannot use time beyond 2038. This is because the RnR service uses 32-bit times in the provided api. *No client durability and no DDS_Time_t usage* - Customers that do not use DDS_Time_t in their user-defined data structures AND do not use + Customers that do not use DDS_Time_t in their user-defined data structures AND do not use client durability can migrate in two steps: * First update all nodes to minimal version 6.7 to be compatible with the 64-bit time stamps, but don't set the domain/y2038Ready option @@ -1032,16 +1032,16 @@ Platform support ================ * Linux 64-bit: On 64-bit platforms linux already supports 64-bit time. No action required. -* Linux 32-bit: On 32-bit platforms linux support for 64-bit time stamps is still in development. - To provide y2038 safe time in GLIBC it is proposed - that the user code defines _TIME_BITS=64 to get 64bit time support. When GLIBC sees _TIME_BITS=64 or when - the system is 64bit it will set __USE_TIME_BITS64 to indicate that it will use 64bit time. +* Linux 32-bit: On 32-bit platforms linux support for 64-bit time stamps is still in development. + To provide y2038 safe time in GLIBC it is proposed + that the user code defines _TIME_BITS=64 to get 64bit time support. When GLIBC sees _TIME_BITS=64 or when + the system is 64bit it will set __USE_TIME_BITS64 to indicate that it will use 64bit time. Note that this is not yet supported. See: https://sourceware.org/glibc/wiki/Y2038ProofnessDesign?rev=83 -* Windows: 64-bit time stamps are supported +* Windows: 64-bit time stamps are supported -**NOTE**: Network Time Protocol: (This is outside the scope of OpenSplice) When NTP is used then there may be a problem -that the time stamp will rollover in 2036. This may not be an issue when version 4 of the NTP protocol is -used which provides specification of an era number and era offset. +**NOTE**: Network Time Protocol: (This is outside the scope of OpenSplice) When NTP is used then there may be a problem +that the time stamp will rollover in 2036. This may not be an issue when version 4 of the NTP protocol is +used which provides specification of an era number and era offset. .. _`DDS_Time structure change`: @@ -1087,7 +1087,7 @@ The original DDS_Time representation with a 32-bit second field: .. |java| image:: ./images/icon-java.* :height: 6mm - + .. EoF diff --git a/build/docs/DeploymentGuide/source/preface.rst b/build/docs/DeploymentGuide/source/preface.rst index 35ad4a8eb..ae096e47e 100644 --- a/build/docs/DeploymentGuide/source/preface.rst +++ b/build/docs/DeploymentGuide/source/preface.rst @@ -31,13 +31,13 @@ Organisation The :ref:`Overview ` gives a general description of the Vortex OpenSplice architecture. -This is followed by :ref:`Service Descriptions `, which -explain how Vortex OpenSplice provides integration of real-time DDS and the +This is followed by :ref:`Service Descriptions `, which +explain how Vortex OpenSplice provides integration of real-time DDS and the non-/near-real-time enterprise DBMS domains. The :ref:`Tools ` section introduces the OpenSplice system management tools. -Full details of the configuration elements and attributes of all +Full details of the configuration elements and attributes of all Vortex OpenSplice services are given in the :ref:`Configuration ` section. @@ -45,24 +45,24 @@ section. Conventions *********** -The icons shown below are used in PrismTech product documentation -to help readers to quickly identify information relevant to their +The icons shown below are used in ADLINK product documentation +to help readers to quickly identify information relevant to their specific use of Vortex OpenSplice. - ========= ================================================================== - *Icon* *Meaning* - ========= ================================================================== - |caution| Item of special significance or where caution needs to be taken. - |info| Item contains helpful hint or special information. - |windows| Information applies to Windows (*e.g.* XP, 2003, Windows 7) only. - |unix| Information applies to Unix-based systems (*e.g.* Solaris) only. - |linux| Information applies to Linux-based systems (*e.g.* Ubuntu) only. - |c| C language specific. - |cpp| C++ language specific. - |csharp| C# language specific. - |java| Java language specific. - ========= ================================================================== + ========= ================================================================== + *Icon* *Meaning* + ========= ================================================================== + |caution| Item of special significance or where caution needs to be taken. + |info| Item contains helpful hint or special information. + |windows| Information applies to Windows (*e.g.* XP, 2003, Windows 7) only. + |unix| Information applies to Unix-based systems (*e.g.* Solaris) only. + |linux| Information applies to Linux-based systems (*e.g.* Ubuntu) only. + |c| C language specific. + |cpp| C++ language specific. + |csharp| C# language specific. + |java| Java language specific. + ========= ================================================================== @@ -86,4 +86,4 @@ specific use of Vortex OpenSplice. .. |java| image:: ./images/icon-java.* :height: 6mm - + diff --git a/build/docs/DeploymentGuide/source/service-feature-list.rst b/build/docs/DeploymentGuide/source/service-feature-list.rst index bdac83dc3..fec45e7b5 100644 --- a/build/docs/DeploymentGuide/source/service-feature-list.rst +++ b/build/docs/DeploymentGuide/source/service-feature-list.rst @@ -40,7 +40,7 @@ Vortex OpenSplice middleware and its services can be configured using easy-to-maintain XML files. Full details of how to use XML files to configure -the elements and attributes of all OpenSplice DDS +the elements and attributes of all Vortex OpenSplice services are given in the :ref:`Configuration ` section. .. EoF diff --git a/build/docs/EvaluationGuide/source/architectural.rst b/build/docs/EvaluationGuide/source/architectural.rst index 75c6de1d2..a705f6572 100644 --- a/build/docs/EvaluationGuide/source/architectural.rst +++ b/build/docs/EvaluationGuide/source/architectural.rst @@ -1,10 +1,10 @@ -.. _`OpenSplice Architectural Modes`: +.. _`Vortex OpenSplice Architectural Modes`: -############################## -OpenSplice Architectural Modes -############################## +##################################### +Vortex OpenSplice Architectural Modes +##################################### -OpenSplice Enterprise provides two main architectural modes. These +Vortex OpenSplice provides two main architectural modes. These are the **Single Process** deployment mode, which provides a **Standalone** architecture, and, unique to OpenSplice, the **Shared Memory** deployment mode which provides a **Federated** architecture. @@ -21,7 +21,7 @@ Features of this mode are: + Uses in-process heap memory for the DDS database. -+ OpenSplice Enterprise services run as threads within the ++ Vortex OpenSplice services run as threads within the application process. + When there are multiple DDS application processes on a single @@ -60,7 +60,7 @@ Features of this mode are: more efficient than having to actually move the data *via* a networking service, allowing for improved performance and scalability. -+ OpenSplice Enterprise services are able to arbitrate over all of the ++ Vortex OpenSplice services are able to arbitrate over all of the DDS data on the node, and so can make smart decisions with respect to data delivery so that priority QoS values (for example) are respected; this is not possible when there are multiple standalone @@ -116,7 +116,7 @@ attribute but does contain a '' attribute.** |caution| Note that by default the ``OSPL_URI`` environment variable refers to a *Single Process* configuration, so to see the extra performance and -scalability benefits of OpenSplice DDS's Shared Memory +scalability benefits of Vortex OpenSplice's Shared Memory architecture it is necessary to switch from the default. diff --git a/build/docs/EvaluationGuide/source/basics.rst b/build/docs/EvaluationGuide/source/basics.rst index 57c583c52..0397b7d5f 100644 --- a/build/docs/EvaluationGuide/source/basics.rst +++ b/build/docs/EvaluationGuide/source/basics.rst @@ -1,25 +1,25 @@ -.. _`OpenSplice Enterprise Basics`: +.. _`Vortex OpenSplice Basics`: ############################ -OpenSplice Enterprise Basics +Vortex OpenSplice Basics ############################ -OpenSplice Enterprise is configured using an XML configuration file. +Vortex OpenSplice is configured using an XML configuration file. In this file, the user specifies the architectural model and the -OpenSplice Enterprise services that are to run when the DDS +Vortex OpenSplice services that are to run when the DDS infrastructure is started. The ``OSPL_URI`` environment variable refers to the specific XML configuration file that is used for the current deployment. The default value refers to the ``ospl.xml`` file located in the ``etc/config`` -directory of the OpenSplice Enterprise installation. The installation +directory of the Vortex OpenSplice installation. The installation directory itself can be referred to by the ``OSPL_HOME`` environment -variable. Please see :ref:`The OpenSplice Enterprise Environment` for -details of how to set up the OpenSplice Enterprise environment. +variable. Please see :ref:`The Vortex OpenSplice Environment` for +details of how to set up the Vortex OpenSplice environment. A number of other sample configuration files that can be used when -benchmarking OpenSplice Enterprise are also provided in +benchmarking Vortex OpenSplice are also provided in the ``etc/config`` directory. The ``OSPL_URI`` variable is of the form: @@ -35,7 +35,7 @@ of the ``OSPL_URI`` variable; for now, let us see what aspects of the OpenSplice deployment are controlled by this file. |info| - The OpenSplice Enterprise Launcher tool assists with the + The Vortex OpenSplice Launcher tool assists with the selection of the ``OSPL_URI`` variable. There is a *Configurations* menu that lists the sample configuration files that are available. @@ -48,7 +48,7 @@ OpenSplice deployment are controlled by this file. **The Launcher tool** -The OpenSplice Enterprise Launcher tool is also able to run the +The Vortex OpenSplice Launcher tool is also able to run the examples and performance tests that are described later in this document. diff --git a/build/docs/EvaluationGuide/source/biblio.rst b/build/docs/EvaluationGuide/source/biblio.rst index 5185f1c1a..c37b2d903 100644 --- a/build/docs/EvaluationGuide/source/biblio.rst +++ b/build/docs/EvaluationGuide/source/biblio.rst @@ -8,29 +8,43 @@ Bibliography HTML and PDF than 'official' reST/Sphinx citations In same order as original -.. _`OMG DDS 1.2`: +.. _`OMG DDS 1.2`: -**OMG DDS 1.2** - | Object Management Group, +**OMG DDS 1.2** + | Object Management Group, | *'Data Distribution Service for Real-Time Systems Version 1.2'*, | Available specification formal/07-01-01 +.. _`OMG DDS 1.4`: + +**OMG DDS 1.4** + | Object Management Group, + | *'Data Distribution Service for Real-Time Systems Version 1.4'*, + | Available specification formal/15-04-10 + .. _`OMG DDSI 2.1`: -**OMG DDSI 2.1** - | Object Management Group, +**OMG DDSI 2.1** + | Object Management Group, | *'The Real-Time Publish-Subscribe Wire Protocol DDS* | *Interoperability Wire Protocol Specification Version 2.1'*, | Document Number: formal/2009-01-05 +.. _`OMG DDSI 2.1`: + +**OMG DDSI 2.2** + | Object Management Group, + | *'The Real-Time Publish-Subscribe Wire Protocol DDS* + | *Interoperability Wire Protocol Specification Version 2.2'*, + | Document Number: formal/2014-09-01 .. _`OMG DDS XTYPES 1.0`: -**OMG DDS XTYPES 1.0** +**OMG DDS XTYPES 1.0** | Object Management Group, | *'Extensible and Dynamic Topic Types for DDS Version 1.0'*, | Document Number: formal/2012-11-10 - - + + .. END diff --git a/build/docs/EvaluationGuide/source/conf.py b/build/docs/EvaluationGuide/source/conf.py index 1b8b65580..316728a7f 100644 --- a/build/docs/EvaluationGuide/source/conf.py +++ b/build/docs/EvaluationGuide/source/conf.py @@ -65,9 +65,8 @@ # General information about the project. project = u'OpenSplice Evaluation and Benchmarking Guide' -#copyright = u'2016, PrismTech' this_year = time.strftime( '%Y' ) -copyright = u'{y}, PrismTech'.format( y = this_year ) +copyright = u'{y}, ADLINK Technology Limited'.format( y = this_year ) print 'Copyright string is:', copyright # The version info for the project you're documenting, acts as replacement for @@ -239,7 +238,7 @@ # Added 'True' to end of generated line to suppress 'Index & Tables' -# A dictionary that contains LaTeX snippets that override those Sphinx usually +# A dictionary that contains LaTeX snippets that override those Sphinx usually # puts into the generated .tex files. latex_elements = { 'babel': '\\usepackage[english]{babel}' } @@ -286,7 +285,7 @@ # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). -man_pages = [('index', 'OpenSplice_Evaluation_Guide', u'OpenSplice_Evaluation_Guide', [u'PrismTech'], 1)] +man_pages = [('index', 'OpenSplice_Evaluation_Guide', u'OpenSplice_Evaluation_Guide', [u'ADLINK Technology Limited'], 1)] # * NOT TESTED diff --git a/build/docs/EvaluationGuide/source/contacts.rst b/build/docs/EvaluationGuide/source/contacts.rst index b437fd808..d32f6016f 100644 --- a/build/docs/EvaluationGuide/source/contacts.rst +++ b/build/docs/EvaluationGuide/source/contacts.rst @@ -1,49 +1 @@ -.. _`Contacts & Notices`: - -################## -Contacts & Notices -################## - -******** -Contacts -******** - -| **PrismTech Corporation** -| 400 TradeCenter -| Suite 5900 -| Woburn, MA -| 01801 -| USA -| Tel: +1 781 569 5819 - -| **PrismTech Limited** -| PrismTech House -| 5th Avenue Business Park -| Gateshead -| NE11 0NG -| UK -| Tel: +44 (0)191 497 9900 - -| **PrismTech France** -| 28 rue Jean Rostand -| 91400 Orsay -| France -| Tel: +33 (1) 69 015354 - - -Web: http://www.prismtech.com - -E-mail: \info@prismtech.com - -******* -Notices -******* - -**Copyright** © 2016 PrismTech Limited. - -The information contained in this document is subject to change without notice and is -made available in good faith without liability on the part of PrismTech Limited or -PrismTech Corporation. - -All trademarks acknowledged. - +.. include:: ../../common/contacts.rst diff --git a/build/docs/EvaluationGuide/source/decisions.rst b/build/docs/EvaluationGuide/source/decisions.rst index d98cb4b55..a72c121d5 100644 --- a/build/docs/EvaluationGuide/source/decisions.rst +++ b/build/docs/EvaluationGuide/source/decisions.rst @@ -7,7 +7,7 @@ Benchmarking OpenSplice: Decision Trees DDS provides many functional benefits that set it apart from other middleware technologies, but users often still have specific performance requirements for latency, throughput, CPU and network -utilization. OpenSplice Enterprise provides the functional benefits +utilization. Vortex OpenSplice provides the functional benefits of the technology whilst remaining committed to excellent performance. diff --git a/build/docs/EvaluationGuide/source/images/LauncherTools.png b/build/docs/EvaluationGuide/source/images/LauncherTools.png old mode 100644 new mode 100755 index 01c11a0ef..746dec8f6 Binary files a/build/docs/EvaluationGuide/source/images/LauncherTools.png and b/build/docs/EvaluationGuide/source/images/LauncherTools.png differ diff --git a/build/docs/EvaluationGuide/source/images/Vortex-OpenSplice-Cover.png b/build/docs/EvaluationGuide/source/images/Vortex-OpenSplice-Cover.png index ce86c6d94..801c02bb8 100644 Binary files a/build/docs/EvaluationGuide/source/images/Vortex-OpenSplice-Cover.png and b/build/docs/EvaluationGuide/source/images/Vortex-OpenSplice-Cover.png differ diff --git a/build/docs/EvaluationGuide/source/index.rst b/build/docs/EvaluationGuide/source/index.rst index ed21213c3..9d7d6476b 100644 --- a/build/docs/EvaluationGuide/source/index.rst +++ b/build/docs/EvaluationGuide/source/index.rst @@ -9,7 +9,7 @@ OpenSplice Evaluation & Benchmarking Guide .. toctree:: :maxdepth: 2 :numbered: - + preface introduction basics @@ -20,8 +20,8 @@ OpenSplice Evaluation & Benchmarking Guide tests biblio - contacts - + contacts + Indices and tables ================== diff --git a/build/docs/EvaluationGuide/source/introduction.rst b/build/docs/EvaluationGuide/source/introduction.rst index f9e36c42c..57c8f1b40 100644 --- a/build/docs/EvaluationGuide/source/introduction.rst +++ b/build/docs/EvaluationGuide/source/introduction.rst @@ -4,26 +4,26 @@ Introduction ############ -One of the key differentiators of OpenSplice Enterprise is that it +One of the key differentiators of Vortex OpenSplice is that it provides a user with the ability to choose exactly how to deploy Data Distribution Service (DDS) applications, *i.e.* there are different DDS system architecture deployment modes and also different networking service protocols. This allows a user to maximize both *intra*-nodal and *inter*-nodal performance based on requirements specific to their -own use case. When evaluating OpenSplice Enterprise it is very +own use case. When evaluating Vortex OpenSplice it is very important to understand all of these features and benefits to ensure that the most appropriate combination is evaluated against your specific performance criteria. Once the performance figures have been observed the choice is usually clear. Every customer use case and set of requirements is different, so let -us briefly guide you through how to best deploy OpenSplice Enterprise +us briefly guide you through how to best deploy Vortex OpenSplice so that it meets and exceeds your expectations. Here we explain how -easy it is to get started with OpenSplice Enterprise and observe the -excellent performance and scalability it provides. OpenSplice -Enterprise is even shipped with dedicated performance tests that the -user can build and run easily. +easy it is to get started with Vortex OpenSplice and observe the +excellent performance and scalability it provides. Vortex OpenSplice +is even shipped with dedicated performance tests that the user can +build and run easily. *Note that this* Guide *serves only as an introduction and does not -replace the full OpenSplice Enterprise reference and user guides*. +replace the full Vortex OpenSplice reference and user guides*. diff --git a/build/docs/EvaluationGuide/source/networking.rst b/build/docs/EvaluationGuide/source/networking.rst index d99e9b1de..f662800a5 100644 --- a/build/docs/EvaluationGuide/source/networking.rst +++ b/build/docs/EvaluationGuide/source/networking.rst @@ -1,29 +1,29 @@ -.. _`OpenSplice Networking Options`: +.. _`Vortex OpenSplice Networking Options`: -############################# -OpenSplice Networking Options -############################# +#################################### +Vortex OpenSplice Networking Options +#################################### -OpenSplice Enterprise provides several networking options for the +Vortex OpenSplice provides several networking options for the delivery of DDS data between nodes. The networking service selection is largely transparent to the user; the difference is observed in the CPU consumption, networking load, and ultimately how fast and efficiently the data is delivered between nodes. The most applicable service is dependent on the requirements of the use case. -**OpenSplice DDSI** is the industry standard protocol providing vendor +**Vortex OpenSplice DDSI** is the industry standard protocol providing vendor interoperability that operates using a typed 'pull' style model. -**OpenSplice RTNetworking** is an alternative to the DDSI wire protocol. +**Vortex OpenSplice RTNetworking** is an alternative to the DDSI wire protocol. RTNetworking uses a type-less 'push' style model in contrast to DDSI and is often the more performant, scalable option. RTNetworking also offers prioritization of network traffic via -‘channels’, partitioning to separate data flows and +'channels', partitioning to separate data flows and optional compression for low-bandwidth environments. -**OpenSplice SecureRTNetworking** provides these features together +**Vortex OpenSplice SecureRTNetworking** provides these features together with encryption and access control. -**OpenSplice DDSI2E** is the 'enhanced' version of the +**Vortex OpenSplice DDSI2E** is the 'enhanced' version of the interoperable service. DDSI2E offers the benefits of the DDSI protocol (such as its automatic unicast delivery in the case of there being a single subscribing endpoint), together with some of the @@ -62,7 +62,7 @@ memory with any of the networking service protocols. |caution| Note that by default, the ``OSPL_URI`` environment variable refers to a *DDSI* configuration, so to see the extra performance and scalability - benefits of OpenSplice DDS's RTNetworking or DDSI2E it is + benefits of Vortex OpenSplice's RTNetworking or DDSI2E it is necessary to switch from the default. diff --git a/build/docs/EvaluationGuide/source/preface.rst b/build/docs/EvaluationGuide/source/preface.rst index 694b6b859..191ac8c74 100644 --- a/build/docs/EvaluationGuide/source/preface.rst +++ b/build/docs/EvaluationGuide/source/preface.rst @@ -10,8 +10,8 @@ Preface About the Evaluation & Benchmarking Guide ***************************************** -The *Evaluation & Benchmarking Guide* is the starting point -for anyone who wants to evaluate OpenSplice DDS. +The *Evaluation & Benchmarking Guide* is the starting point +for anyone who wants to evaluate Vortex OpenSplice. *This Evaluation Guide contains:* @@ -27,24 +27,24 @@ for anyone who wants to evaluate OpenSplice DDS. Conventions *********** -The icons shown below are used in PrismTech product documentation -to help readers to quickly identify information relevant to their +The icons shown below are used in ADLINK product documentation +to help readers to quickly identify information relevant to their specific use of OpenSplice. - ========= ================================================================== - *Icon* *Meaning* - ========= ================================================================== - |caution| Item of special significance or where caution needs to be taken. - |info| Item contains helpful hint or special information. - |windows| Information applies to Windows (*e.g.* XP, 2003, Windows 7) only. - |unix| Information applies to Unix-based systems (*e.g.* Solaris) only. - |linux| Information applies to Linux-based systems (*e.g.* Ubuntu) only. - |c| C language specific. - |cpp| C++ language specific. - |csharp| C# language specific. - |java| Java language specific. - ========= ================================================================== + ========= ================================================================== + *Icon* *Meaning* + ========= ================================================================== + |caution| Item of special significance or where caution needs to be taken. + |info| Item contains helpful hint or special information. + |windows| Information applies to Windows (*e.g.* XP, 2003, Windows 7) only. + |unix| Information applies to Unix-based systems (*e.g.* Solaris) only. + |linux| Information applies to Linux-based systems (*e.g.* Ubuntu) only. + |c| C language specific. + |cpp| C++ language specific. + |csharp| C# language specific. + |java| Java language specific. + ========= ================================================================== @@ -68,4 +68,3 @@ specific use of OpenSplice. .. |java| image:: ./images/icon-java.* :height: 6mm - \ No newline at end of file diff --git a/build/docs/EvaluationGuide/source/running.rst b/build/docs/EvaluationGuide/source/running.rst index dbfa2247b..436d6495c 100644 --- a/build/docs/EvaluationGuide/source/running.rst +++ b/build/docs/EvaluationGuide/source/running.rst @@ -1,48 +1,48 @@ -.. _`How to run OpenSplice Enterprise`: +. _`How to run Vortex OpenSplice`: ################################ -How to run OpenSplice Enterprise +How to run Vortex OpenSplice ################################ -.. _`The OpenSplice Enterprise Environment`: +.. _`The Vortex OpenSplice Environment`: ************************************* -The OpenSplice Enterprise Environment +The Vortex OpenSplice Environment ************************************* -A release file is provided with the OpenSplice Enterprise +A release file is provided with the Vortex OpenSplice installation which contains the environment variables that are required. -Create an OpenSplice Enterprise environment as follows. +Create an Vortex OpenSplice environment as follows. **First:** |linux| Open a shell and source the ``release.com`` file from - the OpenSplice Enterprise installation directory. + the Vortex OpenSplice installation directory. |windows| Open a *Windows Command prompt* and run the ``release.bat`` - file in the OpenSplice Enterprise installation directory. + file in the Vortex OpenSplice installation directory. |windows| - Alternatively, use the *OpenSplice DDS Command Prompt* + Alternatively, use the *Vortex OpenSplice Command Prompt* that can be accessed from the Windows *Start* menu (this will implicitly run ``release.bat``). |info| - Note that the OpenSplice Enterprise Launcher tool also provides a - ``Console`` option which sets up the OpenSplice Enterprise environment. + Note that the Vortex OpenSplice Launcher tool also provides a + ``Console`` option which sets up the Vortex OpenSplice environment. **Next:** -Set the ``OSPL_URI`` variable to refer to the OpenSplice Enterprise +Set the ``OSPL_URI`` variable to refer to the Vortex OpenSplice configuration that is required (see the section :ref:`How to select the Architectural Mode`). diff --git a/build/docs/EvaluationGuide/source/tests.rst b/build/docs/EvaluationGuide/source/tests.rst index 72abf0807..79cb110ed 100644 --- a/build/docs/EvaluationGuide/source/tests.rst +++ b/build/docs/EvaluationGuide/source/tests.rst @@ -4,20 +4,20 @@ Performance Tests and Examples ############################## -To make the evaluation process as easy as possible, OpenSplice -Enterprise is shipped with dedicated performance tests that can be -used to measure latency and throughput. The tests are simple and -clear, allowing the user to obtain performance results easily. +To make the evaluation process as easy as possible, Vortex OpenSplice +is shipped with dedicated performance tests that can be used to measure +latency and throughput. The tests are simple and clear, allowing the +user to obtain performance results easily. The easiest way to build and run the performance tests is to use the -OpenSplice Enterprise *Launcher* tool. In the *Examples* menu select the +Vortex OpenSplice *Launcher* tool. In the *Examples* menu select the specific example and the appropriate language and configuration. Click the *Compile Example* button and then *Run Example*. This will run the DDS applications, and if running with a shared memory configuration it will also manage the starting and stopping of -OpenSplice Enterprise. +Vortex OpenSplice. -OpenSplice Enterprise also provides dedicated performance testing +Vortex OpenSplice also provides dedicated performance testing scripts which: + Test multiple API bindings @@ -43,7 +43,7 @@ Application A to Application B and back again, so importantly it includes metrics for both data delivery and reception. The easiest way to build and run the performance tests is to use the -OpenSplice Enterprise *Launcher* tool as explained above. +Vortex OpenSplice *Launcher* tool as explained above. Alternatively, to manually build and run the round-trip performance test, for example for the ISO C++ API: @@ -52,7 +52,7 @@ test, for example for the ISO C++ API: .. code-block:: bash - # In an OpenSplice Enterprise environment: + # In an Vortex OpenSplice environment: cd $OSPL_HOME/examples/dcps/RoundTrip/isocpp make @@ -61,7 +61,7 @@ test, for example for the ISO C++ API: ./pong # If using shared memory do "ospl stop" - # In another OpenSplice Enterprise environment: + # In another Vortex OpenSplice environment: cd $OSPL_HOME/examples/dcps/RoundTrip/isocpp # If using shared memory do "ospl start" ./ping 20 100 @@ -74,16 +74,16 @@ test, for example for the ISO C++ API: .. code-block:: bat - # Load the OpenSplice DDS examples project solution + # Load the Vortex OpenSplice examples project solution # into Visual Studio and build the required projects - # In an OpenSplice Enterprise environment: + # In an Vortex OpenSplice environment: cd %OSPL_HOME%\examples\dcps\RoundTrip\isocpp # If using shared memory do "ospl start" pong.exe # If using shared memory do "ospl stop" - # In another OpenSplice Enterprise environment: + # In another Vortex OpenSplice environment: cd %OSPL_HOME%\examples\dcps\RoundTrip\isocpp # If using shared memory do "ospl start" ping.exe 20 100 @@ -124,7 +124,7 @@ it describes the ability of the DDS implementation to effectively deliver DDS data without data loss. As with the round-trip test, the easiest way to build and run the -throughput performance test is to use the OpenSplice Enterprise +throughput performance test is to use the Vortex OpenSplice *Launcher* tool. Alternatively, to manually build and run the throughput performance @@ -134,7 +134,7 @@ test, for example for the ISO C++ API: .. code-block:: bash - # In an OpenSplice Enterprise environment: + # In an Vortex OpenSplice environment: cd $OSPL_HOME/examples/dcps/Throughput/isocpp make cd $OSPL_HOME/examples/dcps/Throughput/isocpp @@ -142,7 +142,7 @@ test, for example for the ISO C++ API: ./publisher # If using shared memory do "ospl stop" - # In another In an OpenSplice Enterprise environment: + # In another In an Vortex OpenSplice environment: cd $OSPL_HOME/examples/dcps/Throughput/isocpp # If using shared memory do "ospl start" ./subscriber @@ -154,16 +154,16 @@ test, for example for the ISO C++ API: .. code-block:: bat - # Load the OpenSplice DDS examples project solution + # Load the Vortex OpenSplice examples project solution # into Visual Studio and build the required projects - # In an OpenSplice Enterprise environment: + # In an Vortex OpenSplice environment: cd %OSPL_HOME%\examples\dcps\Throughput\isocpp # If using shared memory do "ospl start" publisher.exe # If using shared memory do "ospl stop" - # In another OpenSplice Enterprise environment: + # In another Vortex OpenSplice environment: cd %OSPL_HOME%\examples\dcps\Throughput\isocpp # If using shared memory do "ospl start" subscriber.exe @@ -201,7 +201,7 @@ Achieving Maximum Throughput Where there is a requirement to support continuous flows or 'streams' of data with minimal overhead consider the use -of OpenSplice Streams. The ability to deliver potentially millions of +of Vortex OpenSplice Streams. The ability to deliver potentially millions of samples per second is realized by the Streams feature transparently batching (packing and queuing) the periodic samples. diff --git a/build/docs/GPBTutorial/source/conf.py b/build/docs/GPBTutorial/source/conf.py index c56d2db74..eb2c64f40 100755 --- a/build/docs/GPBTutorial/source/conf.py +++ b/build/docs/GPBTutorial/source/conf.py @@ -48,9 +48,8 @@ # General information about the project. project = u'OpenSplice GPB Tutorial' -#copyright = u'2015, PrismTech' this_year = time.strftime( '%Y' ) -copyright = u'{y}, PrismTech'.format( y = this_year ) +copyright = u'{y}, ADLINK Technology Limited'.format( y = this_year ) print 'Copyright string is:', copyright # The version info for the project you're documenting, acts as replacement for @@ -269,7 +268,7 @@ # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). -man_pages = [('index', 'OpenSpliceGPBTutorial', u'OpenSplice GPB Tutorial', [u'PrismTech'], 1)] +man_pages = [('index', 'OpenSpliceGPBTutorial', u'OpenSplice GPB Tutorial', [u'ADLINK Technology Limited'], 1)] # * NOT TESTED diff --git a/build/docs/GPBTutorial/source/contacts.rst b/build/docs/GPBTutorial/source/contacts.rst old mode 100755 new mode 100644 index f4260856b..d32f6016f --- a/build/docs/GPBTutorial/source/contacts.rst +++ b/build/docs/GPBTutorial/source/contacts.rst @@ -1,48 +1 @@ -.. _`Contacts & Notices`: - -################## -Contacts & Notices -################## - -******** -Contacts -******** - -| **PrismTech Corporation** -| 400 TradeCenter -| Suite 5900 -| Woburn, MA -| 01801 -| USA -| Tel: +1 781 569 5819 - -| **PrismTech Limited** -| PrismTech House -| 5th Avenue Business Park -| Gateshead -| NE11 0NG -| UK -| Tel: +44 (0)191 497 9900 - -| **PrismTech France** -| 28 rue Jean Rostand -| 91400 Orsay -| France -| Tel: +33 (1) 69 015354 - - -Web: http://www.prismtech.com - -E-mail: \info@prismtech.com - -******* -Notices -******* - -**Copyright** © 2016 PrismTech Limited. - -*This document may be reproduced in whole but not in part. -The information contained in this document is subject to change -without notice and is made available in good faith without -liability on the part of PrismTech Limited or PrismTech Corporation. -All trademarks acknowledged.* +.. include:: ../../common/contacts.rst diff --git a/build/docs/GPBTutorial/source/images/Vortex-OpenSplice-Cover.png b/build/docs/GPBTutorial/source/images/Vortex-OpenSplice-Cover.png index ce86c6d94..801c02bb8 100644 Binary files a/build/docs/GPBTutorial/source/images/Vortex-OpenSplice-Cover.png and b/build/docs/GPBTutorial/source/images/Vortex-OpenSplice-Cover.png differ diff --git a/build/docs/GPBTutorial/source/index.rst b/build/docs/GPBTutorial/source/index.rst index e97983d6c..a93e522c7 100755 --- a/build/docs/GPBTutorial/source/index.rst +++ b/build/docs/GPBTutorial/source/index.rst @@ -9,7 +9,7 @@ DDS Java and C++ API Google Protocol Buffers Tutorial .. toctree:: :maxdepth: 2 :numbered: - + preface introduction proto-message @@ -17,8 +17,8 @@ DDS Java and C++ API Google Protocol Buffers Tutorial using-generated-api evolving-data-models - contacts - + contacts + Indices and tables ================== diff --git a/build/docs/GPBTutorial/source/preface.rst b/build/docs/GPBTutorial/source/preface.rst index 265641ebe..fa03a2ebf 100755 --- a/build/docs/GPBTutorial/source/preface.rst +++ b/build/docs/GPBTutorial/source/preface.rst @@ -8,14 +8,14 @@ Preface About the Vortex OpenSplice Google Protocol Buffers Tutorial ************************************************************ -This *OpenSplice GPB Tutorial* is included with the OpenSplice DDS +This *Vortex OpenSplice GPB Tutorial* is included with the Vortex OpenSplice Documentation Set. It describes how to use the Vortex OpenSplice **ISO C++ API** and **Java 5 API** in combination with **Google Protocol Buffers** (*GPB*) data models. This Tutorial assumes that the user is already familiar with the -DDS API as well as the OpenSplice product. +DDS API as well as the Vortex OpenSplice product. *Intended Audience* @@ -28,7 +28,7 @@ applications with Vortex OpenSplice. Detailed information about Vortex OpenSplice itself is provided in the *User* and *Deployment* Guides, which also give details of where additional information -can be found, such as the OpenSplice FAQs, Knowledge Base, +can be found, such as the Vortex OpenSplice FAQs, Knowledge Base, bug reports, *etc.* diff --git a/build/docs/GettingStartedGuide/source/Vortex-OpenSplice-Cover.png b/build/docs/GettingStartedGuide/source/Vortex-OpenSplice-Cover.png index ce86c6d94..801c02bb8 100644 Binary files a/build/docs/GettingStartedGuide/source/Vortex-OpenSplice-Cover.png and b/build/docs/GettingStartedGuide/source/Vortex-OpenSplice-Cover.png differ diff --git a/build/docs/GettingStartedGuide/source/about-ospl.rst b/build/docs/GettingStartedGuide/source/about-ospl.rst index b80aa4919..5c61ec360 100644 --- a/build/docs/GettingStartedGuide/source/about-ospl.rst +++ b/build/docs/GettingStartedGuide/source/about-ospl.rst @@ -1,4 +1,4 @@ -.. _`About OpenSplice`: +.. _`About Vortex OpenSplice`: ####################### About Vortex Opensplice @@ -71,9 +71,9 @@ time--even in the *largest-scale mission- and business-critical systems*. typical 'stream' data -Please go to http://www.prismtech.com to obtain evaluation copies of -Vortex OpenSplice, and http://www.opensplice.org for free downloads of the -community version. +Please go to http://ist.adlinktech.com/ to obtain evaluation copies of +Vortex OpenSplice, and http://ist.adlinktech.com/dds-community for free downloads of the +DDS Community Edition. ****************************** @@ -93,7 +93,7 @@ networking (providing QoS driven real-time networking based on multiple reliable multicast \`channels'), durability (providing fault tolerant storage for both real-time \`state' data as well as persistent \`settings'), and remote control & monitoring \`soap service' (providing -remote web based access using the SOAP protocol from the OpenSplice DDS +remote web based access using the SOAP protocol from the Vortex OpenSplice Tuner tools). @@ -106,7 +106,7 @@ administration still provides each subscriber with his own private \`view' on this data. This allows a subscriber's data cache to be perceived as an individual \`database' that can be content-filtered, queried, etc. (using the content-subscription profile as supported by -OpenSplice DDS). This shared-memory architecture results in an extremely +Vortex OpenSplice). This shared-memory architecture results in an extremely small footprint, excellent scalability and optimal performance when compared to implementations where each reader/writer are \`communication endpoints' each with its own storage (in other words, historical data @@ -116,7 +116,7 @@ moved, even within the same physical node. Configuration ============= - + Vortex OpenSplice is highly configurable, even allowing the architectural structure of the DDS middleware to be chosen by the user at deployment time. Vortex OpenSplice can be configured to run using a *shared memory* @@ -124,7 +124,7 @@ architecture, where both the DDS related administration (including the optional pluggable services) and DDS applications interface directly with shared memory. Alternatively, Vortex OpenSplice also supports a *single process* library architecture, where one or more DDS -applications, together with the OpenSplice administration and services, +applications, together with the Vortex OpenSplice administration and services, can all be grouped into a single operating system process. Both deployment modes support a configurable and extensible set of services, providing functionality such as: @@ -137,7 +137,7 @@ providing functionality such as: data as well as persistent settings + *remote control and monitoring SOAP service* - providing remote web-based - access using the SOAP protocol from the OpenSplice Tuner tool + access using the SOAP protocol from the Vortex OpenSplice Tuner tool + *dbms service* - providing a connection between the real-time and the enterprise domain by bridging data from DDS to DBMS and *vice versa* @@ -157,7 +157,7 @@ depends on the user's exact requirements and DDS scenario. Single Process Library Architecture *********************************** -This deployment allows the DDS applications and OpenSplice +This deployment allows the DDS applications and Vortex OpenSplice administration to be contained together within one single operating system process. This single process deployment option is most useful in environments where shared memory is unavailable or undesirable. As @@ -190,16 +190,16 @@ The Single Process deployment is the default architecture provided within Vortex OpenSplice and allows for easy deployment with minimal configuration required for a running DDS system. -The figure `The OpenSplice Single Process Architecture`_ +The figure `The Vortex OpenSplice Single Process Architecture`_ shows an overview of the single process architecture of Vortex OpenSplice. -.. _`The OpenSplice Single Process Architecture`: +.. _`The Vortex OpenSplice Single Process Architecture`: .. figure:: /images/SingleProcessArchitecture.png :height: 70mm - :alt: The OpenSplice Single Process Architecture + :alt: The Vortex OpenSplice Single Process Architecture - **The OpenSplice Single Process Architecture** + **The Vortex OpenSplice Single Process Architecture** ************************** @@ -209,10 +209,10 @@ Shared Memory architecture In the shared memory architecture data is physically present only once on any machine but smart administration still provides each subscriber with his own private view on this data. Both the DDS applications and -OpenSplice administration interface directly with the shared memory -which is created by the OpenSplice daemon on start up. This architecture +Vortex OpenSplice administration interface directly with the shared memory +which is created by the Vortex OpenSplice daemon on start up. This architecture enables a subscriber's data cache to be seen as an individual database -and the content can be filtered, queried, etc. by using the OpenSplice +and the content can be filtered, queried, etc. by using the Vortex OpenSplice content subscription profile. Typically for advanced DDS users, the shared memory architecture is a @@ -223,32 +223,32 @@ each with its own storage (*i.e.* historical data both at reader and writer) and where the data itself still has to be moved, even within the same platform. -The figure `The OpenSplice Shared Memory Architecture`_ -shows an overview of the shared memory architecture of +The figure `The Vortex OpenSplice Shared Memory Architecture`_ +shows an overview of the shared memory architecture of Vortex OpenSplice on *one* computing node. Typically, there are *many* nodes within a system. -.. _`The OpenSplice Shared Memory Architecture`: +.. _`The Vortex OpenSplice Shared Memory Architecture`: .. figure:: /images/SharedMemoryArchitecture.png :height: 70mm - :alt: The OpenSplice Shared Memory Architecture - - **The OpenSplice Shared Memory Architecture** + :alt: The Vortex OpenSplice Shared Memory Architecture + + **The Vortex OpenSplice Shared Memory Architecture** -************************************ +*************************************** Vortex OpenSplice Features and Benefits -************************************ +*************************************** The table below shows the following aspects of Vortex OpenSplice, where: - *Features* are significant characteristics of OpenSplice + *Features* are significant characteristics of Vortex OpenSplice *Advantages* shows why a feature is important - *Benefits* describes how users of OpenSplice can exploit the advantages + *Benefits* describes how users of Vortex OpenSplice can exploit the advantages +----------------+-------------------+--------------------------+-------+ @@ -366,7 +366,7 @@ aspects of Vortex OpenSplice, where: Conclusion ********** -PrismTech's Vortex OpenSplice product complemented by its tool support +ADLINK's Vortex OpenSplice product complemented by its tool support together encompass the industry's most profound expertise on the OMG's DDS standard and products. diff --git a/build/docs/GettingStartedGuide/source/conf.py b/build/docs/GettingStartedGuide/source/conf.py index 7d876c0ed..b2ee68ccb 100644 --- a/build/docs/GettingStartedGuide/source/conf.py +++ b/build/docs/GettingStartedGuide/source/conf.py @@ -48,9 +48,8 @@ # General information about the project. project = u'OpenSplice Getting Started Guide' -#copyright = u'2015, PrismTech' this_year = time.strftime( '%Y' ) -copyright = u'{y}, PrismTech'.format( y = this_year ) +copyright = u'{y}, ADLINK Technology Limited'.format( y = this_year ) print 'Copyright string is:', copyright # The version info for the project you're documenting, acts as replacement for @@ -221,7 +220,7 @@ # Added 'True' to end of generated line to suppress 'Index & Tables' -# A dictionary that contains LaTeX snippets that override those Sphinx usually +# A dictionary that contains LaTeX snippets that override those Sphinx usually # puts into the generated .tex files. latex_elements = { 'babel': '\\usepackage[english]{babel}' } @@ -268,7 +267,7 @@ # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). -man_pages = [('index', 'OpenSplice_Getting_Started_Guide', u'OpenSplice_Getting_Started_Guide Documentation', [u'PrismTech'], 1)] +man_pages = [('index', 'OpenSplice_Getting_Started_Guide', u'OpenSplice_Getting_Started_Guide Documentation', [u'ADLINK Technology Limited'], 1)] # * NOT TESTED diff --git a/build/docs/GettingStartedGuide/source/contacts.rst b/build/docs/GettingStartedGuide/source/contacts.rst index 53613a9d7..d32f6016f 100644 --- a/build/docs/GettingStartedGuide/source/contacts.rst +++ b/build/docs/GettingStartedGuide/source/contacts.rst @@ -1,49 +1 @@ -.. _`Contacts & Notices`: - -################## -Contacts & Notices -################## - -******** -Contacts -******** - -| **PrismTech Corporation** -| 400 TradeCenter -| Suite 5900 -| Woburn, MA -| 01801 -| USA -| Tel: +1 781 569 5819 - -| **PrismTech Limited** -| PrismTech House -| 5th Avenue Business Park -| Gateshead -| NE11 0NG -| UK -| Tel: +44 (0)191 497 9900 - -| **PrismTech France** -| 28 rue Jean Rostand -| 91400 Orsay -| France -| Tel: +33 (1) 69 015354 - - -Web: http://www.prismtech.com - -E-mail: \info@prismtech.com - -******* -Notices -******* - -**Copyright** © 2016 PrismTech Limited. All rights reserved. - -*This document may be reproduced in whole but not in part. -The information contained in this document is subject to change without notice and is made available in good faith without liability on the part of PrismTech Limited or PrismTech Corporation. -All trademarks acknowledged.* - -Doc Issue 01, 24 March 2015 - +.. include:: ../../common/contacts.rst diff --git a/build/docs/GettingStartedGuide/source/documentation.rst b/build/docs/GettingStartedGuide/source/documentation.rst index cb14e47b4..329a7665c 100644 --- a/build/docs/GettingStartedGuide/source/documentation.rst +++ b/build/docs/GettingStartedGuide/source/documentation.rst @@ -27,9 +27,10 @@ Vortex OpenSplice Documentation Set | | who need to be aware of the latest changes which may | | | affect the Service's performance and usage. | | | A link to the Release Notes is in ``index.html`` | -| | located in the directory where OpenSplice is installed. | +| | located in the directory where Vortex OpenSplice is | +| | installed. | +--------------+---------------------------------------------------------+ -| Getting | General information about OpenSplice, including | +| Getting | General information about Vortex OpenSplice, including | | Started | installation instructions, initial configuration | | Guide | requirements and instructions for running the | | | Opensplice examples on supported platforms. | @@ -37,27 +38,27 @@ Vortex OpenSplice Documentation Set | | For managers, administrators, and developers | | | to gain an initial understanding of the product, | | | as well as for product installers for | -| | installing and administering OpenSplice. | +| | installing and administering Vortex OpenSplice. | | | | | | *Essential reading for users new to DDS.* | +--------------+---------------------------------------------------------+ | Evaluation | A short guide to help new users evaluate Vortex | | Guide | OpenSplice. | +--------------+---------------------------------------------------------+ -| Tutorial | A short course on developing applications with | +| Tutorial | A short course on developing applications with Vortex | | Guide | OpenSplice. Includes example code in C, C++ and Java. | +--------------+---------------------------------------------------------+ | Deployment | *A complete reference on how to configure and | -| Guide | tune the OpenSplice service.* | +| Guide | tune the Vortex OpenSplice service.* | +--------------+---------------------------------------------------------+ | Tuner | Describes how to use the Tuner tool for monitoring | | Guide | and controlling Opensplice. | | | | | | For programmers, testers, system designers and | -| | system integrators using OpenSplice. | +| | system integrators using Vortex OpenSplice. | +--------------+---------------------------------------------------------+ -| IDL Pre-\ | Describes how to use the Opensplice IDL pre-processor | -| processor | for C, C++ and Java. | +| IDL Pre-\ | Describes how to use the Vortex Opensplice IDL | +| processor | pre-processor for C, C++ and Java. | | Guide | | +--------------+---------------------------------------------------------+ | OpenSplice | Provides a complete reference on how to configure the | @@ -92,22 +93,22 @@ Vortex OpenSplice Documentation Set | | | +--------------+---------------------------------------------------------+ | RMI over DDS | Explains how to take advantage of the client/server | -| Getting | interaction paradigm provided by OpenSplice RMI | +| Getting | interaction paradigm provided by Vortex OpenSplice RMI | | Started | layered over the publish/subscribe paradigm of | | Guide | Vortex OpenSplice. | +--------------+---------------------------------------------------------+ | Streams User | Explains the Streams API where continuous flows or | -| Guide | ‘streams’ of data have to be transported with minimal | +| Guide | streams of data have to be transported with minimal | | | overhead and therefore maximal achievable throughput. | +--------------+---------------------------------------------------------+ | GPB User | Explains how to use Google Protocol Buffers with the | | Guide | new ISO C++ and Java 5 APIs. | +--------------+---------------------------------------------------------+ -| Record and | Explains how to configure and use the Record and Replay | +| Record and | Explains how to configure and use the Record and Replay | | Replay | Service. | | Service Guide| | +--------------+---------------------------------------------------------+ -| Security User| Explains how to configure security when using the | +| Security User| Explains how to configure security when using the | | Configuration| Real Time Native Networking Protocol. | | Guide | | +--------------+---------------------------------------------------------+ @@ -119,14 +120,14 @@ Vortex OpenSplice Documentation Set | | and used. | | | | | | Documentation for the examples can be found in the | -| | OpenSplice Release Notes. | +| | Vortex OpenSplice Release Notes. | +--------------+---------------------------------------------------------+ | White Papers | Technical papers providing information about | | and Data | Vortex Opensplice. | | Sheets | | | | These technical papers are in PDF format and they | -| | can be obtained from the PrismTech web site at | -| | http://www.prismtech.com | +| | can be obtained from the ADLINK web site at | +| | http://ist.adlinktech.com/ | +--------------+---------------------------------------------------------+ @@ -137,32 +138,32 @@ Information Sources Product Information =================== -Links to useful technical information for PrismTech's products, +Links to useful technical information for ADLINK's products, including the Vortex OpenSplice and associated components, are listed below. |caution| These links are provided for the reader's convenience and may become - out-of-date if changes are made on the PrismTech Web site after + out-of-date if changes are made on the ADLINK Web site after publication of this guide. Nonetheless, these links should still be - reachable from the main PrismTech Web page located at - http://www.prismtech.com. + reachable from the main ADLINK Web page located at + http://ist.adlinktech.com/. Knowledge Base ============== -The PrismTech Knowledge Base is a collection of documents and resources -intended to assist our customers in getting the most out of the +The ADLINK Knowledge Base is a collection of documents and resources +intended to assist our customers in getting the most out of the Vortex OpenSplice products. The Knowledge Base has the most up-to-date information about bug fixes, product issues and technical support for difficulties that you may experience. The Knowledge Base can be found at: - http://www.prismtech.com/knowledge-base + http://ist.adlinktech.com/knowledge-base @@ -171,25 +172,25 @@ Additional Technical Information Information provided by independent publishers, newsgroups, web sites, and organisations, such as the Object Management Group, can be found on -the Prismtech Web site: +the ADLINK Web site: - http://www.prismtech.com + http://ist.adlinktech.com/ ******* Support ******* -PrismTech provides a range of product support, consultancy and +ADLINK provides a range of product support, consultancy and educational programmes to help you from product evaluation and -development, through to deployment of applications using OpenSplice DDS. +development, through to deployment of applications using Vortex OpenSplice. The support programmes are designed to meet customers' particular needs and range from a basic Standard programme to the Gold programme, which provides comprehensive, 24 x 7 support. -Detailed information about PrismTech's product support services, general -support contacts and enquiries are described on the PrismTech Support -page reached via the PrismTech Home page at http://www.prismtech.com. +Detailed information about ADLINK's product support services, general +support contacts and enquiries are described on the ADLINK Support +page reached via the ADLINK Home page at http://ist.adlinktech.com/. diff --git a/build/docs/GettingStartedGuide/source/elinos.rst b/build/docs/GettingStartedGuide/source/elinos.rst index c8b6f334e..7c70eb55a 100644 --- a/build/docs/GettingStartedGuide/source/elinos.rst +++ b/build/docs/GettingStartedGuide/source/elinos.rst @@ -5,7 +5,7 @@ ELinOS ###### -*This chapter provides notes about deploying OpenSplice DDS on ELinOS.* +*This chapter provides notes about deploying Vortex OpenSplice on ELinOS.* **************** diff --git a/build/docs/GettingStartedGuide/source/images/Launcher-starting.png b/build/docs/GettingStartedGuide/source/images/Launcher-starting.png old mode 100644 new mode 100755 index 037e76f45..8132e8f0d Binary files a/build/docs/GettingStartedGuide/source/images/Launcher-starting.png and b/build/docs/GettingStartedGuide/source/images/Launcher-starting.png differ diff --git a/build/docs/GettingStartedGuide/source/images/Launcher-utility.png b/build/docs/GettingStartedGuide/source/images/Launcher-utility.png old mode 100644 new mode 100755 index e0864c396..4fb77644c Binary files a/build/docs/GettingStartedGuide/source/images/Launcher-utility.png and b/build/docs/GettingStartedGuide/source/images/Launcher-utility.png differ diff --git a/build/docs/GettingStartedGuide/source/index.rst b/build/docs/GettingStartedGuide/source/index.rst index 59e507f61..4444929d0 100644 --- a/build/docs/GettingStartedGuide/source/index.rst +++ b/build/docs/GettingStartedGuide/source/index.rst @@ -8,7 +8,7 @@ OpenSplice Getting Started Guide .. toctree:: :maxdepth: 2 :numbered: - + preface about-ospl product-info @@ -27,7 +27,7 @@ OpenSplice Getting Started Guide unixarm elinos contacts - + Indices and tables ================== diff --git a/build/docs/GettingStartedGuide/source/install-configure.rst b/build/docs/GettingStartedGuide/source/install-configure.rst index adb47d444..c9d899edd 100644 --- a/build/docs/GettingStartedGuide/source/install-configure.rst +++ b/build/docs/GettingStartedGuide/source/install-configure.rst @@ -5,7 +5,7 @@ Installation and Configuration ############################## *Follow the instructions in this chapter to install and configure -Vortex OpenSplice and its tools. Information on running the OpenSplice +Vortex OpenSplice and its tools. Information on running the Vortex OpenSplice examples are provided at the end of the chapter under* `Examples`_. @@ -14,14 +14,12 @@ Vortex OpenSplice Development and Run-Time ****************************************** Vortex OpenSplice is provided in two installers. The **HDE** (Host -Development Environment) is the standard and it requires approximately -60 Mb of disk space after installation; the **RTS** (Run Time System) -requires approximately 35 Mb of disk space. +Development Environment) is the standard and the **RTS** (Run Time System). The HDE contains all of the services, libraries, header files and tools -needed to develop applications using OpenSplice, and the RTS is a subset +needed to develop applications using Vortex OpenSplice, and the RTS is a subset of the HDE which contains all of the services, libraries and tools -needed to deploy applications using OpenSplice. +needed to deploy applications using Vortex OpenSplice. .. _`Installation for UNIX and Windows Platforms`: @@ -31,7 +29,7 @@ Installation for UNIX and Windows Platforms This section describes the normal procedure to install Vortex OpenSplice on a UNIX or Windows platform. The exception is the procedure to install -Vortex OpenSplice on a UNIX ARM platform which is described in section :ref:`UNIX ARM platform` +Vortex OpenSplice on a UNIX ARM platform which is described in section :ref:`UNIX ARM platform` **Step 1** @@ -44,7 +42,7 @@ Vortex OpenSplice on a UNIX ARM platform which is described in section :ref:`UNI where, some being optional, - ** - PrismTech's code for the platform + ** - ADLINK's code for the platform ** - the Vortex OpenSplice version number, for example ``V6.0`` @@ -76,7 +74,7 @@ Vortex OpenSplice on a UNIX ARM platform which is described in section :ref:`UNI *Configure the Vortex OpenSplice environment variables.* (This is only necessary on UNIX, as the Windows environment - is configured by the OpenSplice installer.) + is configured by the Vortex OpenSplice installer.) Go to the *//* directory, where ** is ``HDE`` or ``RTS`` and ** is, for example, ``x86.linux2.6``. @@ -90,7 +88,7 @@ Vortex OpenSplice on a UNIX ARM platform which is described in section :ref:`UNI Usually not required, but install your desired ORB when the C++ language mapping is used with CORBA cohabitation. Ensure your chosen ORB and compiler is appropriate - for the CCPP library being used (either OpenSplice's default library or + for the CCPP library being used (either Vortex OpenSplice's default library or other custom-built library). Refer to the *Release Notes* for ORB and compiler information pertaining to Vortex OpenSplice' default CCPP library. @@ -111,8 +109,8 @@ Configuration Vortex OpenSplice is configured using an XML configuration file, as shown under `Example XML Configuration Settings`_ . -It is advisable to use the ``osplconf`` tool (UNIX) -or *OpenSplice DDS Configurator Tool* (Windows *Start Menu* ) to +It is advisable to use the ``osplconf`` tool (UNIX) +or *Vortex OpenSplice Configurator Tool* (Windows *Start Menu* ) to edit your xml files. The configurator tool provides explanations of each attribute and also validates the input. @@ -122,7 +120,7 @@ available in this directory, to assist in other scenarios). The default value of the environment variable ``OSPL_URI`` is set to this configuration file. -The configuration file defines and configures the following OpenSplice +The configuration file defines and configures the following Vortex OpenSplice services: *spliced* @@ -139,11 +137,11 @@ services: in a domain. *tuner* - This service provides a SOAP interface for the OpenSplice Tuner to connect + This service provides a SOAP interface for the Vortex OpenSplice Tuner to connect to the node remotely from any other reachable node. The default deployment specified by the XML configuration file is for a -*Single Process* deployment. This means that the OpenSplice Domain +*Single Process* deployment. This means that the Vortex OpenSplice Domain Service, database administration and associated services are all started within the DDS application process. This is implicitly done when the user's application invokes the DDS *create\_participant* operation. @@ -152,7 +150,7 @@ The deployment mode and other configurable properties can be changed by using a different ``OSPL_URI`` file. Several sample configuration files are provided at the same location. -|info| +|info| If using a shared memory configuration, a ** attribute is specified in the XML configuration. The default Database Size that is mapped on @@ -161,8 +159,8 @@ are provided at the same location. |caution| *Note:* The maximum user-creatable shared-memory segment is limited - on certain machines, including Solaris, so it must either be - adjusted or OpenSplice must be started as root. + on certain machines, including Solaris, so it must either be + adjusted or Vortex OpenSplice must be started as root. A complete configuration file that enables durability as well as Real Time Native Networking is shown below. (The relevant lines are not enabled in @@ -179,7 +177,7 @@ created). In the example below this directory is ``/tmp/Pdata``. For the networking service, the network interface-address that is to be used is specified by the ** element. The -default value is set to ``first available`` , meaning that OpenSplice will +default value is set to ``first available`` , meaning that Vortex OpenSplice will determine the first available interface that is broadcast or multicast enabled. However, an alternative address may be specified as well (specify as ``a.b.c.d``). @@ -351,13 +349,13 @@ and run it on Unix/Linux and Windows systems. For VxWorks and Integrity, please refer to :ref:`VxWorks 5.5.1`, :ref:`VxWorks 6.x RTP`, and :ref:`Integrity` in this *Guide*. -Using the OpenSplice Tools -========================== +Using the Vortex OpenSplice Tools +================================= |caution| *Note:* The following instructions apply only to the *shared memory* deployment of Vortex OpenSplice. When deploying in single process - configuration, there is no need to manually start the OpenSplice + configuration, there is no need to manually start the Vortex OpenSplice infrastructure prior to running a DDS application process, as the administration will be created within the application process. Please refer to the Vortex OpenSplice *Deployment Guide* for a discussion of these @@ -369,12 +367,12 @@ Windows *Start Menu* , as well as the Tuner and Configurator. **Step 1** - *Manually start the OpenSplice infrastructure* + *Manually start the Vortex OpenSplice infrastructure* 1. Enter ``ospl start`` on the command line [#f1]_. - This starts the OpenSplice services. + This starts the Vortex OpenSplice services. - These log files may be created in the current directory when OpenSplice + These log files may be created in the current directory when Vortex OpenSplice is started: *ospl-info.log* - contains information and warning reports @@ -390,9 +388,9 @@ Windows *Start Menu* , as well as the Tuner and Configurator. **Step 2** - *Start the OpenSplice Tuner Tool* + *Start the Vortex OpenSplice Tuner Tool* - 1. Read the *OpenSplice Tuner Guide* (``TunerGuide.pdf``) + 1. Read the *Vortex OpenSplice Tuner Guide* (``TunerGuide.pdf``) before running the Tuner Tool. 2. Start the tool by entering ``ospltun`` on the command line. @@ -402,30 +400,30 @@ Windows *Start Menu* , as well as the Tuner and Configurator. environment variable (the default URI is: ``file://$OSPL_HOME/etc/config/ospl.xml``). - The OpenSplice system can now be monitored. + The Vortex OpenSplice system can now be monitored. **Step 3** - *Experiment with the OpenSplice tools and applications* + *Experiment with the Vortex OpenSplice tools and applications* - Use the OpenSplice Tuner to monitor all DDS entities and + Use the Vortex OpenSplice Tuner to monitor all DDS entities and their (dynamic) relationships. **Step 4** - *Manually stop the OpenSplice infrastructure* + *Manually stop the Vortex OpenSplice infrastructure* - 1. Choose *File > Disconnect* from the OpenSplice Tuner menu. + 1. Choose *File > Disconnect* from the Vortex OpenSplice Tuner menu. 2. Enter ``ospl stop`` on the command line; this stops all - OpenSplice services. + Vortex OpenSplice services. + + - -  .. rubric:: Footnotes -  -.. [#f1] ``ospl`` is the command executable for OpenSplice DDS. + +.. [#f1] ``ospl`` is the command executable for Vortex OpenSplice. @@ -449,4 +447,4 @@ Windows *Start Menu* , as well as the Tuner and Configurator. .. |java| image:: ./images/icon-java.* :height: 6mm - + diff --git a/build/docs/GettingStartedGuide/source/integrity.rst b/build/docs/GettingStartedGuide/source/integrity.rst index e77e0d61a..e1a10e62d 100644 --- a/build/docs/GettingStartedGuide/source/integrity.rst +++ b/build/docs/GettingStartedGuide/source/integrity.rst @@ -249,7 +249,7 @@ hand in order for the project to build correctly. The following section describes the second method. -Changing the generated OpenSplice DDS project using *Multi* +Changing the generated Vortex OpenSplice project using *Multi* =========================================================== You can make changes to any of the settings you specified with @@ -266,7 +266,7 @@ Select the *All Options* tab and expand the *Advanced* section. **Step 3** -Select *Advanced OpenSplice DDS XML To Int Convertor Options*. In the +Select *Advanced Vortex OpenSplice XML To Int Convertor Options*. In the right-hand pane you will see the options that you have set with the ``ospl_projgen`` tool with their values, similar to `Integrity: changing project options in Multi`_ below. @@ -295,7 +295,7 @@ please see section `The ospl_xml2int command`_.) Note that if you do remove filesystem support from the kernel image you should also remove all references to the ``ivfs`` library, and make appropriate changes to the ``ospl_log.c`` file as well. See section - `Amending OpenSplice DDS Configuration with Multi`_ for information + `Amending Vortex OpenSplice Configuration with Multi`_ for information about ``ospl_log.c``. Similarly you can change any other option and the changes are applied @@ -309,7 +309,7 @@ When the changes are complete, rebuild the project by right-clicking on The ospl_xml2int Tool ===================== -The ``ospl_xml2int`` tool is used to inspect your OpenSplice DDS +The ``ospl_xml2int`` tool is used to inspect your Vortex OpenSplice configuration file (``ospl.xml``) and generate an appropriate Integrate file (``ospl.int``). For more information on Integrate files please consult the Integrity manual. @@ -374,7 +374,7 @@ the arguments are described in detail below. ``-o `` Name of the generated Integrate file. -Applications linking with OpenSplice DDS must comply with the following +Applications linking with Vortex OpenSplice must comply with the following requirements: + The ``First`` and ``Length`` parameters must match those of ``spliced`` @@ -446,8 +446,8 @@ files to match your setup. These files can be found under Once you have made all of the required changes to ``ospl.int``, you must -rebuild the whole project. Your changes will be picked up by OpenSplice -DDS automatically. +rebuild the whole project. Your changes will be picked up by Vortex OpenSplice +automatically. ************************************************** Critical Warning about *Object 10* and *Object 11* @@ -463,32 +463,32 @@ Critical Warning about *Object 10* and *Object 11* ``Object 11`` are defined (except those for ``ResourceStore`` as noted below). The value replacing ``10`` must be the same for every address space, and likewise for the value replacing ``11``. You **must** change - **all** references in order for OpenSplice DDS to work correctly. + **all** references in order for Vortex OpenSplice to work correctly. *The only exception is the* ``ResourceStore`` *address space.* - ``Object 10`` *and* ``Object 11`` *are unique to the OpenSplice DDS* + ``Object 10`` *and* ``Object 11`` *are unique to the Vortex OpenSplice* *ResourceStore and they* **MUST NOT** *be altered.* - *If you do change them, OpenSplice DDS* **WILL NOT WORK!** + *If you do change them, Vortex OpenSplice* **WILL NOT WORK!** |caution| |caution| -************************************************** -Amending OpenSplice DDS Configuration with *Multi* -************************************************** +***************************************************** +Amending Vortex OpenSplice Configuration with *Multi* +***************************************************** -You can make changes to the OpenSplice DDS configuration from Multi by +You can make changes to the Vortex OpenSplice configuration from Multi by editing the files under the project ``src/projgen.gpj/opensplice_configuration.gpj/libospl_cfg.gpj``. See -`Integrity: changing OpenSplice DDS configuration in Multi`_ below: +`Integrity: changing Vortex OpenSplice configuration in Multi`_ below: -.. _`Integrity: changing OpenSplice DDS configuration in Multi`: +.. _`Integrity: changing Vortex OpenSplice configuration in Multi`: .. figure:: /images/Integrity-DDSconfigMulti.png :height: 70mm - :alt: Integrity: changing OpenSplice DDS configuration in Multi + :alt: Integrity: changing Vortex OpenSplice configuration in Multi - **Integrity: changing OpenSplice DDS configuration in Multi** + **Integrity: changing Vortex OpenSplice configuration in Multi** |caution| @@ -496,13 +496,13 @@ editing the files under the project ``ospl_log.c``. The others must **NOT** be altered! ``ospl.xml`` - This is your OpenSplice DDS configuration file. (See - :ref:`Configuration` for more information about the options an OpenSplice DDS + This is your Vortex OpenSplice configuration file. (See + :ref:`Configuration` for more information about the options an Vortex OpenSplice configuration file may have.) ``ospl_log.c`` This file determines where the log entries (errors, - warnings and informational messages) from OpenSplice DDS go. The way the + warnings and informational messages) from Vortex OpenSplice go. The way the default file is generated by ``ospl_projgen`` depends on whether you have specified filesystem support or not. (See comments within the file for more information.) diff --git a/build/docs/GettingStartedGuide/source/licensing.rst b/build/docs/GettingStartedGuide/source/licensing.rst index ee727a4c9..8a0a22839 100644 --- a/build/docs/GettingStartedGuide/source/licensing.rst +++ b/build/docs/GettingStartedGuide/source/licensing.rst @@ -1,8 +1,8 @@ -.. _`Licensing OpenSplice`: +.. _`Licensing Vortex OpenSplice`: -#################### -Licensing OpenSplice -#################### +########################### +Licensing Vortex OpenSplice +########################### *Vortex OpenSplice uses Reprise License Manager (RLM) to manage licenses. This section describes how to install a license file for Vortex OpenSplice @@ -14,7 +14,7 @@ General ******* The licensing software is automatically installed on the host machine as -part of the OpenSplice distribution. The software consists of two parts: +part of the Vortex OpenSplice distribution. The software consists of two parts: + *Vortex OpenSplice binary files* | which are installed in ``//./bin``, @@ -22,14 +22,14 @@ part of the OpenSplice distribution. The software consists of two parts: | where Vortex OpenSplice is installed. + *License files* - | which determine the terms of the license. - | These will be supplied by PrismTech. + | which determine the terms of the license. + | These will be supplied by ADLINK. |info| - **Licenses:** PrismTech supplies an Vortex OpenSplice license file, + **Licenses:** ADLINK supplies an Vortex OpenSplice license file, ``license.lic``. This file is *not* included in the software - distribution, but is sent separately by PrismTech. + distribution, but is sent separately by ADLINK. *********************************** @@ -43,7 +43,7 @@ Vortex OpenSplice is also physically licensed on enterprise platforms for deployment. |caution| - Some OpenSplice components are licensed individually and you will need + Some Vortex OpenSplice components are licensed individually and you will need the correct feature to be unlocked for you to use them. @@ -53,7 +53,7 @@ Installing the License File Copy the license file to ``/etc/license.lic`` on the machine that will run the license manager. -```` is the directory where OpenSplice is +```` is the directory where Vortex OpenSplice is installed. This is the recommended location for the license file but you can put @@ -61,14 +61,14 @@ the file in any location that can be accessed by the license manager ``rlm``. If another location is used or the environment has not been setup, then -an environment variable, either ``RLM_LICENSE`` or ``prismtech_LICENSE``, +an environment variable, either ``RLM_LICENSE`` or ``ADLINK_LICENSE``, must be set to the full path and filename of the license file (either variable can be set; there is no need to set both). For example: - ``prismtech_LICENSE=/my/lic/dir/license.lic`` + ``ADLINK_LICENSE=/my/lic/dir/license.lic`` If licenses are distributed between multiple license files, the -``RLM_LICENSE`` or ``prismtech_LICENSE`` variable can be set to point to +``RLM_LICENSE`` or ``ADLINK_LICENSE`` variable can be set to point to the directory which contains the license files. @@ -78,13 +78,13 @@ Running the License Manager Daemon It is only necessary to run the License Manager Daemon for floating or counted licenses. In this case, the license manager must be running -before OpenSplice DDS can be used. The license manager software is +before Vortex OpenSplice can be used. The license manager software is responsible for allocating licenses to developers and ensuring that the allowed number of concurrent licenses is not exceeded. For node-locked licenses, as is the case with all evaluation licenses, then it is not necessary to run the License Manager Daemon but the -``RLM_LICENSE`` or ``prismtech_LICENSE`` variable must be set to the +``RLM_LICENSE`` or ``ADLINK_LICENSE`` variable must be set to the correct license file location. To run the license manager, use the following command: @@ -97,12 +97,12 @@ where ```` is the full path and filename of the license file. If licenses are distributed between multiple files, ```` should be the path to the directory that contains the license files. -The ``rlm`` command will start the PrismTech vendor daemon ``prismtech``, -which controls the licensing of the OpenSplice DDS software. +The ``rlm`` command will start the ADLINK vendor daemon ``prismtech``, +which controls the licensing of the Vortex OpenSplice software. -To obtain a license for OpenSplice DDS from a License Manager Daemon -that is running on a different machine, set either the ``RLM_LICENSE`` -or ``prismtech_LICENSE`` environment variable to point to the License +To obtain a license for Vortex OpenSplice from a License Manager Daemon +that is running on a different machine, set either the ``RLM_LICENSE`` +or ``ADLINK_LICENSE`` environment variable to point to the License Manager Daemon, using the following syntax: .. code-block:: bash @@ -146,11 +146,11 @@ following example: 07/05 12:05 (prismtech) license.lic 07/05 12:05 (prismtech) -.. +.. The ```` value should be taken from the first line of the output. The ```` value should be taken from the last line. From this -example, the value for ``RLM_LICENSE`` or ``prismtech_LICENSE`` would be: +example, the value for ``RLM_LICENSE`` or ``ADLINK_LICENSE`` would be: ``35562@rhel4e`` @@ -162,8 +162,8 @@ Utilities A utility program, ``rlmutil``, is available for license server management and administration. One feature of this utility is its ability to gracefully shut down the license manager. To shut down the -license manager, preventing the checkout of licenses for the OpenSplice -DDS software, run either of the following commands: +license manager, preventing the checkout of licenses for the Vortex OpenSplice +software, run either of the following commands: .. code-block:: bash @@ -194,7 +194,7 @@ This returns an ID code for the server, which will look similar to: ``Hostid of this machine: 0025643ad2a7`` -This ID code must be supplied to PrismTech so that your license key can +This ID code must be supplied to ADLINK so that your license key can be generated. diff --git a/build/docs/GettingStartedGuide/source/preface.rst b/build/docs/GettingStartedGuide/source/preface.rst index 069bc8fcb..05d0ea29d 100644 --- a/build/docs/GettingStartedGuide/source/preface.rst +++ b/build/docs/GettingStartedGuide/source/preface.rst @@ -10,7 +10,7 @@ About the Getting Started Guide The *Getting Started Guide* is included with the Vortex OpenSplice Documentation Set. This Guide is the starting point for anyone using, -developing or running applications with OpenSplice DDS. +developing or running applications with Vortex OpenSplice. *This Getting Started Guide contains:* @@ -23,7 +23,7 @@ developing or running applications with OpenSplice DDS. information is provided in the *User* and *Deployment* Guides) - details of where additional information can be found, such as the - OpenSplice FAQs, Knowledge Base, bug reports, *etc.* + Vortex OpenSplice FAQs, Knowledge Base, bug reports, *etc.* *Intended Audience* @@ -77,4 +77,3 @@ specific use of Vortex OpenSplice. .. |java| image:: ./images/icon-java.* :height: 6mm - \ No newline at end of file diff --git a/build/docs/GettingStartedGuide/source/product-info.rst b/build/docs/GettingStartedGuide/source/product-info.rst index 34f707bc4..d7a24d49b 100644 --- a/build/docs/GettingStartedGuide/source/product-info.rst +++ b/build/docs/GettingStartedGuide/source/product-info.rst @@ -25,21 +25,21 @@ Services node and the rest of the nodes on \`the network'. + **Tuner Service** (``cmsoap``) - Responsible for providing remote SOAP-based access to a deployed + Responsible for providing remote SOAP-based access to a deployed DDS system by providing a control-and-monitoring (C&M) API + **Networking Bridge Service** - Responsible for bridging DDS traffic between multiple + Responsible for bridging DDS traffic between multiple networks (each with a related Networking Service) - + + **Recording and Replay Service** Responsible for recording and replaying of real-time DDS - data, controlled a topic-based API (as also used by the + data, controlled a topic-based API (as also used by the Vortex RnR Manager tool) - + + **DBMS Connect Service** Responsible for bi-directional bridging between DDS and a - relational database (RDBMS) system + relational database (RDBMS) system Tools ===== @@ -48,13 +48,13 @@ Tools Generates topic types, type-specific readers and writers. + **OpenSplice Tuner** - Allows local and/or remote 'white-box' inspection and tuning + Allows local and/or remote 'white-box' inspection and tuning of a deployed Vortex OpenSplice federation and/or appliciation. + **OpenSplice Tester** Allows for script-based 'black-box' regression-testing of locally or remotely deployed Vortex OpenSplice Systems. - + + **OpenSplice Configurator** Simplifies the process for configuring the services. @@ -79,7 +79,7 @@ Key Features + It offers total lifecycle support from prototyping through to remote maintenance. + Vortex OpenSplice supports both Single Process (library) and Shared Memory (federated) - deployment architectures, targeting either ease of use or advanced scalability + deployment architectures, targeting either ease of use or advanced scalability and determinism scenarios. @@ -123,21 +123,21 @@ this can be found in the *Release Notes*. These compilers are the officially-supported set, but we have experience of customers who will use the delivered libraries with slight variants -of the compiler. In most cases this works, but PrismTech has provided +of the compiler. In most cases this works, but ADLINK has provided the source code so that customers can rebuild the C++ APIs for their compiler of choice. |caution| - **NOTE:** PrismTech only provides support on the officially-supported + **NOTE:** ADLINK only provides support on the officially-supported platforms due to difficult-to-fix issues with compiler-generated code, but some customers will fund us to qualify OpenSplice on their platform. If you wish to use a variant of an official platform, then as long as the issue can be recreated on the official platform it will be covered under an Vortex OpenSplice support contract. If you wish to request support - on a specific platform then please contact PrismTech - (http://www.prismtech.com/contact-us) + on a specific platform then please contact ADLINK + (http://ist.adlinktech.com/) + - ******************** Interaction patterns ******************** @@ -154,13 +154,13 @@ Support for evolutionary data models ************************************ Apart from the OMG IDL based data-modeling, Vortex OpenSplice also supports modeling of -evolutionary types using the popular Google Protocol Buffers (GPB) technology (and the +evolutionary types using the popular Google Protocol Buffers (GPB) technology (and the related .proto files). - + ********************* -Building your own C++ +Building your own C++ ********************* Building your own ISO C++ API @@ -220,4 +220,4 @@ about using Vortex OpenSplice on specific platforms. .. |java| image:: ./images/icon-java.* :height: 6mm - + diff --git a/build/docs/GettingStartedGuide/source/unixarm.rst b/build/docs/GettingStartedGuide/source/unixarm.rst index bc3313c69..589eb0186 100644 --- a/build/docs/GettingStartedGuide/source/unixarm.rst +++ b/build/docs/GettingStartedGuide/source/unixarm.rst @@ -38,7 +38,7 @@ When the installer is provided as an tar file follow the procedure described bel where, some being optional, - ** - PrismTech's code for the platform + ** - ADLINK's code for the platform ** - the Vortex OpenSplice version number, for example ``V6.0`` @@ -57,7 +57,7 @@ When the installer is provided as an tar file follow the procedure described bel ** - the target architecture for host/target builds. **Step 2** - + *Configure the Vortex OpenSplice environment.* Go to the *//* directory, where ** is ``HDE`` of ``RTS`` diff --git a/build/docs/GettingStartedGuide/source/vxworks-551.rst b/build/docs/GettingStartedGuide/source/vxworks-551.rst index ffb4363c0..2da3c00be 100644 --- a/build/docs/GettingStartedGuide/source/vxworks-551.rst +++ b/build/docs/GettingStartedGuide/source/vxworks-551.rst @@ -35,12 +35,12 @@ additional information describing how VxWorks kernels can be built. + Operating system components - POSIX components - + * POSIX timers * POSIX threads - File System and Disk Utilities - + * File System and Disk Utilities @@ -53,11 +53,11 @@ deploying from the Tornado front end: + Development tool components - WDB agent components - + * WDB agent services - WDB target server file system - + * symbol table components @@ -66,7 +66,7 @@ deploying from the Tornado front end: - synchronize host and target symbol tables - target shell components - + * target shell @@ -169,7 +169,7 @@ pre-loaded by the user. Running the Examples ******************** -If you included the additional modules listed above +If you included the additional modules listed above (see `Building a VxWorks Kernel`_) in the kernel, deployment is done *via* the target server setup from the Tornado shell connection. @@ -320,8 +320,8 @@ The osplconf2c command The OpenSplice Examples (Alternative scenario, with multiple DKMs) ****************************************************************** -|caution| - Loading separate DKMs is not recommended by PrismTech. +|caution| + Loading separate DKMs is not recommended by ADLINK. @@ -369,7 +369,7 @@ point can then be invoked to start OpenSplice. |caution| Please note that in order to deploy the cmsoap service for use with the - OpenSplice DDS Tuner, it must be configured in ``ospl.xml`` and the + Vortex OpenSplice Tuner, it must be configured in ``ospl.xml`` and the libraries named ``libcmxml.so`` and ``libddsrrstorage.so`` must be pre-loaded: diff --git a/build/docs/GettingStartedGuide/source/vxworks-6-kernel.rst b/build/docs/GettingStartedGuide/source/vxworks-6-kernel.rst index ba161c534..2ccd2142b 100644 --- a/build/docs/GettingStartedGuide/source/vxworks-6-kernel.rst +++ b/build/docs/GettingStartedGuide/source/vxworks-6-kernel.rst @@ -33,10 +33,10 @@ which must match the Vortex OpenSplice build you are working with. |caution| The *SMP* option must *only* be checked for SMP builds of OpenSplice. - + On the *Configuration Profile* dialog choose ``PROFILE_DEVELOPMENT`` from the drop-down list. - + Once the kernel configuration project has been generated, the additional required functionality can be enabled: @@ -71,7 +71,7 @@ OpenSplice Examples .. note: xref to install-configure.rst -PrismTech provides the *pingpong* example both for C and C++ that are described +ADLINK provides the *pingpong* example both for C and C++ that are described in the :ref:`Examples` section. These example are provided in the form of Workbench projects which can be easily built and then deployed on to the target hardware in a similar process to that described above. @@ -204,8 +204,8 @@ Open a target shell connection to each board and in the C mode shell run: ld 1,0,"/tgtsvr/sacpp_pingpong_kernel.out" ospl_spliced - -**Step 5** + +**Step 5** Open another target shell connection to one board and run: @@ -310,7 +310,7 @@ Open a target shell connection and in the C mode shell run: ld 1,0,"/tgtsvr/sacpp_pingpong_kernel.out" ospl_spliced - + Open another target shell connection and run: pong "PongRead PongWrite" @@ -353,7 +353,7 @@ Running the Examples (Alternative scenario, with multiple DKMs – ‘AppOnly’ ********************************************************************************* |caution| - Loading separate DKMs is not recommended by PrismTech. + Loading separate DKMs is not recommended by ADLINK. |info| |cpp| *NOTE:* There are no C++ examples provided for the AppOnly style and there is no @@ -555,7 +555,7 @@ The osplconf2c command .. code-block:: bash osplconf2c -h - + osplconf2c [-u ] [-e ]... [-o ] @@ -564,13 +564,13 @@ The osplconf2c command ``-h, -?`` List available command line arguments and give brief reminders of their functions. - + ``-u `` Identifies the configuration file to use (default: ``${OSPL_URI}``). - + ``-o `` Name of the generated file. - + ``-e `` Environment setting for configuration of OpenSplice e.g. ``-e "OSPL_LOGPATH=/xxx/yyy"`` diff --git a/build/docs/GettingStartedGuide/source/vxworks-6-rtp.rst b/build/docs/GettingStartedGuide/source/vxworks-6-rtp.rst index e3b6a0003..30f9cfe9e 100644 --- a/build/docs/GettingStartedGuide/source/vxworks-6-rtp.rst +++ b/build/docs/GettingStartedGuide/source/vxworks-6-rtp.rst @@ -24,17 +24,17 @@ Installation The following instructions describe installing Vortex OpenSplice for VxWorks 6.x on the Windows host environment. -Start the installation process by double-clicking the Vortex OpenSplice +Start the installation process by double-clicking the Vortex OpenSplice Host Development Environment (HDE) installer file. Follow the on-screen instructions and complete the installation. When asked to configure the installation with a license file, choose *No*. The installer will create an Vortex OpenSplice entry in *Start > Programs* which contains -links to the OpenSplice tools, documentation, and an Uninstall option. +links to the Vortex OpenSplice tools, documentation, and an Uninstall option. |caution| Please note that WindRiver's Workbench GUI must be run in an environment - where the OpenSplice variables have already been set. If you chose to - set the OpenSplice variables globally during the installation stage, + where the Vortex OpenSplice variables have already been set. If you chose to + set the Vortex OpenSplice variables globally during the installation stage, then Workbench can be run directly. Otherwise, Workbench must be run from the Vortex OpenSplice command prompt. Start the command prompt by clicking *Start > Programs > Vortex OpenSplice menu entry > Vortex OpenSplice @@ -84,7 +84,7 @@ Vortex OpenSplice domain service ``spliced`` and a number of optional services described within the Vortex OpenSplice configuration file (``ospl.xml``). On VxWorks 6.x, a Real Time Process for each of these services is deployed on to the target hardware. The sample ``ospl.xml`` configuration file -provided with the VxWorks 6.x edition of OpenSplice has particular +provided with the VxWorks 6.x edition of Vortex OpenSplice has particular settings so that these RTPs can operate effectively. The instructions below describe how to deploy these RTPs using the @@ -118,7 +118,7 @@ connection and choosing *Run > Run RTP on Target...*. **Step 5** Create a new configuration for the *spliced* deployment that points to -the ``spliced.vxe`` executable from the OpenSplice installation. The +the ``spliced.vxe`` executable from the Vortex OpenSplice installation. The following parameters should be set in the dialog: +------------------------+----------------------------------------+ @@ -143,7 +143,7 @@ For simplicity it has been assumed that ``spliced.vxe`` and the other executables (located in the ``bin`` directory of the installation) and ``ospl.xml`` (located in the ``etc/config`` directory of the installation) have been copied to the directory made available as ``/tgtsvr`` described -above. It is possible, if required, to copy the entire OpenSplice +above. It is possible, if required, to copy the entire Vortex OpenSplice installation directory to the ``/tgtsvr`` location so that all files are available, but please be aware that log and information files will be written to the same ``/tgtsvr`` location when the ``spliced.vxe`` is @@ -165,7 +165,7 @@ The configuration can be deployed by clicking *Run*, where an RTP for each service described in the configuration file should be created. These can be seen in Workbench in the Real Time Processes list for the target connection. An example is shown below in -`Workbench showing deployed OpenSplice RTPs`_. +`Workbench showing deployed Vortex OpenSplice RTPs`_. (The list may need to be refreshed with the *F5* key.) Deployment problems are listed in ``ospl-error.txt`` and ``ospl-info.txt``, @@ -173,22 +173,22 @@ which are created in the ``/tgtsvr`` directory if the configuration described above is used. -.. _`Workbench showing deployed OpenSplice RTPs`: +.. _`Workbench showing deployed Vortex OpenSplice RTPs`: .. figure:: /images/VxWorks-deployedRTPs.png :height: 70mm - :alt: Workbench showing deployed OpenSplice RTPs + :alt: Workbench showing deployed Vortex OpenSplice RTPs - **Workbench showing deployed OpenSplice RTPs** + **Workbench showing deployed Vortex OpenSplice RTPs** -******************* -OpenSplice Examples -******************* +************************** +Vortex OpenSplice Examples +************************** .. note: xref to install-configure.rst -PrismTech provides a number of examples both for C and C++ that are +ADLINK provides a number of examples both for C and C++ that are described in the :ref:`Examples` section. These example are provided in the form of Workbench projects which can be easily built and then deployed on to the target hardware in a similar process to that described above. @@ -204,7 +204,7 @@ The example projects can be imported into Workbench by clicking *File > Import... > General > Existing Projects into Workspace*. In the *Import Projects* dialog, browse to the ``examples`` directory of -the OpenSplice installation. Select the required projects for importing +the Vortex OpenSplice installation. Select the required projects for importing from the list that Workbench has detected. Ensure that the *Copy projects into workspace* box is un-checked. @@ -221,7 +221,7 @@ Projects in a workspace can be built individually or as a group. *Project > Build All*. -Deploying OpenSplice Examples +Deploying Vortex OpenSplice Examples ============================= The PingPong and the Tutorial examples are run in identical ways with @@ -234,7 +234,7 @@ Deploying PingPong The PingPong example consists of the ``ping.vxe`` and ``pong.vxe`` executables. If these executables have been copied to the directory made -available as ``/tgtsvr`` as described in `Deploying OpenSplice DDS`_, +available as ``/tgtsvr`` as described in `Deploying Vortex OpenSplice`_, RTP configurations should have the following parameters: +-----------------------------------+----------------------------------------+ @@ -251,8 +251,8 @@ RTP configurations should have the following parameters: +-----------------------------------+----------------------------------------+ | Stack Size | ``0x10000`` | +-----------------------------------+----------------------------------------+ - - + + +-----------------------------------+----------------------------------------+ | RTP configuration for ping | +===================================+========================================+ @@ -280,7 +280,7 @@ Deploying the Chat Tutorial The Chat Tutorial consists of the ``chatter.vxe``, ``messageboard.vxe`` and ``userload.vxe`` executables. If these executables have been copied to the directory made available as ``/tgtsvr`` as described in -`Deploying OpenSplice DDS`_, RTP configurations should have the following +`Deploying Vortex OpenSplice`_, RTP configurations should have the following parameters: +-----------------------------------+----------------------------------------+ @@ -297,8 +297,8 @@ parameters: +-----------------------------------+----------------------------------------+ | Stack Size | ``0x10000`` | +-----------------------------------+----------------------------------------+ - - + + +-----------------------------------+----------------------------------------+ | RTP configuration for messageboard | +===================================+========================================+ @@ -313,8 +313,8 @@ parameters: +-----------------------------------+----------------------------------------+ | Stack Size | ``0x10000`` | +-----------------------------------+----------------------------------------+ - - + + +-----------------------------------+----------------------------------------+ | RTP configuration for chatter | +===================================+========================================+ @@ -329,8 +329,8 @@ parameters: +-----------------------------------+----------------------------------------+ | Stack Size | ``0x10000`` | +-----------------------------------+----------------------------------------+ - - + + When deployment is successful, the console will show output from each RTP. In particular the message board will show the messages sent by the ``chatter`` process. The console view can be switched to show the output diff --git a/build/docs/GettingStartedGuide/source/windowsce.rst b/build/docs/GettingStartedGuide/source/windowsce.rst index e5d337ca3..52a96330d 100644 --- a/build/docs/GettingStartedGuide/source/windowsce.rst +++ b/build/docs/GettingStartedGuide/source/windowsce.rst @@ -75,7 +75,7 @@ Alternatives to CAB file Microsoft's Windows CE Remote Registry Editor can be used instead of a ``CAB`` file to set the necessary registry values. Alternatively, -PrismTech also provides a convenient method of editing the registry +ADLINK also provides a convenient method of editing the registry variables by way of the ``ospl`` utility using the ``getenv`` and ``putenv`` parameters (described below). @@ -83,9 +83,9 @@ Please refer to Microsoft's Windows CE documentation for detailed information about ``CAB`` files and the Remote Registry Editor. -****************************** +********************************* The Vortex OpenSplice Environment -****************************** +********************************* Vortex OpenSplice requires the contents of the *bin* , *lib* and *etc* directories from within the Vortex OpenSplice installation to be available @@ -114,7 +114,7 @@ executables. For example: copied into the ```\Windows`` directory on the Windows CE device prior to deployment.) -When running OpenSplice executables on the command prompt, it is useful +When running Vortex OpenSplice executables on the command prompt, it is useful to redirect any output to text files by using the ``>`` operator. If the ``PATH`` and ``OSPL_URI`` variables have not already been set *via* @@ -143,7 +143,7 @@ The secure networking service uses OpenSSL for cryptography support. To use this feature, the library ``libeay32.dll`` is required; it must be copied to the ``\Windows`` directory on the Windows CE device. -OpenSplice is tested against OpenSSL version 0.9.8i. This may be built +Vortex OpenSplice is tested against OpenSSL version 0.9.8i. This may be built as described below. Building OpenSSL for Windows CE 6.0 @@ -170,7 +170,7 @@ The following are needed to make an OpenSSL build for Windows CE 6.0: + An installed WinCE 6.0 SDK to be targeted In this description the target SDK is ``'WinCE-GS3Target'`` - + + Perl You will need to install Active Perl, from http://www.activestate.com/ActivePerl. @@ -212,11 +212,11 @@ any location you want. .. code-block:: make set OSVERSION=WCE600 - + set TARGETCPU=ARMV4I - + set PLATFORM=VC-CE - + set PATH=C:\Program Files\Microsoft Visual Studio 8\VC\ce\bin\x86_arm; C:\Program Files\Microsoft Visual Studio 8\Common7\IDE;%PATH% @@ -226,7 +226,7 @@ any location you want. set LIB=C:\Program Files\Windows CE Tools\wce600\WinCE-GS3Target\lib\ ARMV4I;C:\Program Files\\Microsoft Visual Studio 8\VC\ce\lib\armv4 -.. +.. If you target a different SDK, replace the text *WinCE-GS3Target* in the lines above with your own SDK. @@ -302,7 +302,7 @@ Build OpenSSL set WCECOMPAT=C:\wcecompat -.. +.. If you target a different SDK, replace the text ``WinCE-GS3Target`` in the lines above with your own SDK. Also, change the *wcecompat* @@ -351,13 +351,13 @@ If you get the following error message: Remove ``/WX`` in the makefile (``ce.mak``). -************************ -Deploying OpenSplice DDS -************************ +*************************** +Deploying Vortex OpenSplice +*************************** ``ospl start`` - This command will start the OpenSplice DDS ``splicedaemon`` and OpenSplice - DDS services specified within the configuration referred to by the + This command will start the Vortex OpenSplice ``splicedaemon`` and Vortex + OpenSplice services specified within the configuration referred to by the ``OSPL_URI`` variable: ``ospl start > osplstart.txt`` @@ -369,14 +369,14 @@ Deploying OpenSplice DDS | ``HDE/armv4i.wince/etc/config/ospl.xml" > osplstart.txt`` ``ospl list`` - This command will list all the OpenSplice DDS configurations that are + This command will list all the Vortex OpenSplice configurations that are currently running on the node. ``ospl list > ospllist.txt`` ``ospl stop`` - This command will stop the OpenSplice DDS ``splicedaemon`` and OpenSplice - DDS services specified within the configuration referred to by the + This command will stop the Vortex OpenSplice ``splicedaemon`` and Vortex + OpenSplice services specified within the configuration referred to by the ``OSPL_URI`` variable: ``ospl stop > osplstop.txt`` @@ -415,14 +415,14 @@ where ** is displayed in the output for the particular instance of ``mmstat``. -******************* -OpenSplice Examples -******************* +************************** +Vortex OpenSplice Examples +************************** .. note: xref to install-configure.rst Please refer to the :ref:`Examples` section for descriptions of the -OpenSplice DDS examples. +Vortex OpenSplice examples. Building the examples @@ -436,7 +436,7 @@ Once the projects are open in Microsoft Visual Studio, click *Build/Rebuild Solution* at the appropriate level to build the required examples. -Copy the produced executable files to the OpenSplice DDS ``bin`` directory +Copy the produced executable files to the Vortex OpenSplice ``bin`` directory (*i.e.* ``\NAND Flash\OpenSpliceDDS\\HDE\armv4i.wince\bin``) on the Windows CE device. For the PingPong example the executable files are @@ -448,7 +448,7 @@ for a new project perform the following steps: **Step 1** - Run the OpenSplice command prompt from the *OpenSplice* entry under the + Run the Vortex OpenSplice command prompt from the *OpenSplice* entry under the Windows *Start* button: *Start > Programs > OpenSpliceDDS armv4i.wince HDE @@ -461,7 +461,7 @@ for a new project perform the following steps: the *Visual Studio 2005 Command Prompt* entry located at *Start > Programs > Microsoft Visual Studio 2005 > Visual Studio Tools > Visual Studio 2005 Command Prompt* , and paste the *Shortcut Target* entry into - the OpenSplice command prompt. For example this could be + the Vortex OpenSplice command prompt. For example this could be ``%comspec% /k ""C:\Program Files\Microsoft Visual Studio 8\VC\vcvarsall.bat"" x86`` @@ -485,7 +485,7 @@ Start Vortex OpenSplice as described above. The Ping and Pong executables can then be started as follows: ``start pong PongRead PongWrite > pong.txt`` - + ``start ping 100 100 m PongRead PongWrite > ping.txt`` The ``ping.txt`` file produced should contain the expected Ping Pong diff --git a/build/docs/IDLPreProcGuide/source/commandline.rst b/build/docs/IDLPreProcGuide/source/commandline.rst index 7ccc219b0..e32169602 100644 --- a/build/docs/IDLPreProcGuide/source/commandline.rst +++ b/build/docs/IDLPreProcGuide/source/commandline.rst @@ -16,7 +16,7 @@ command line options: [ -I ] [ -D [=] ] < -S | -C > - < -l (c | c++ | cpp | java | cs | isocpp | isoc++ | c99) > + < -l (c | c++ | cpp | java | cs | isocpp | isoc++ | c99 | simulink) > [ -F ] [ -j [old]:] [ -o | | | ] @@ -72,7 +72,7 @@ All of these options are described in full detail below. Specifies ORB integrated mode, which allows application programs to be built and run integrated with an ORB. -**-l (c | c++ | cpp | java | cs | isocpp | isoc++ | isocpp2 | isoc++2 | c99)** +**-l (c | c++ | cpp | java | cs | isocpp | isoc++ | isocpp2 | isoc++2 | c99 | simulink)** Selects the target language. Note that the Vortex OpenSplice IDL Pre-processor does not support every combination of modes and languages. This option is mandatory; when no @@ -135,6 +135,11 @@ All of these options are described in full detail below. size one larger than specified in the idl definition to allow for the terminating 0 character. + |simulink| + - For Simulink a MATLAB .m file is created representing the simulink + bus for the input IDL file. Typically this option is used when + invoking a script from MATLAB to import the IDL into Simulink. + See also :ref:`OpenSplice Modes and Languages ` for a complete list of supported modes and languages. diff --git a/build/docs/IDLPreProcGuide/source/conf.py b/build/docs/IDLPreProcGuide/source/conf.py index eda0ce749..445826116 100644 --- a/build/docs/IDLPreProcGuide/source/conf.py +++ b/build/docs/IDLPreProcGuide/source/conf.py @@ -63,9 +63,8 @@ def setup(app): # General information about the project. project = u'IDL PreProcessor Guide' -#copyright = u'2015, PrismTech' this_year = time.strftime( '%Y' ) -copyright = u'{y}, PrismTech'.format( y = this_year ) +copyright = u'{y}, ADLINK Technology Limited'.format( y = this_year ) print 'Copyright string is:', copyright @@ -230,7 +229,7 @@ def setup(app): # Added 'True' to end of generated line to suppress 'Index & Tables' -# A dictionary that contains LaTeX snippets that override those Sphinx usually +# A dictionary that contains LaTeX snippets that override those Sphinx usually # puts into the generated .tex files. latex_elements = { 'babel': '\\usepackage[english]{babel}' } @@ -271,7 +270,7 @@ def setup(app): # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). -man_pages = [('index', 'IDL_PreProcessor_Guide', u'IDL_PreProcessor_Guide', [u'PrismTech'], 1)] +man_pages = [('index', 'IDL_PreProcessor_Guide', u'IDL_PreProcessor_Guide', [u'ADLINK Technology Limited'], 1)] # -- Additional options -------------------------------------------------------- diff --git a/build/docs/IDLPreProcGuide/source/contacts.rst b/build/docs/IDLPreProcGuide/source/contacts.rst index fc6442d3a..d32f6016f 100644 --- a/build/docs/IDLPreProcGuide/source/contacts.rst +++ b/build/docs/IDLPreProcGuide/source/contacts.rst @@ -1,53 +1 @@ -.. _`Contacts & Notices`: - -.. VERY LITTLE EVER CHANGES IN HERE !! - Just keep an eye on the copyright notice. - -################## -Contacts & Notices -################## - -******** -Contacts -******** - -| **PrismTech Corporation** -| 400 TradeCenter -| Suite 5900 -| Woburn, MA -| 01801 -| USA -| Tel: +1 781 569 5819 - -| **PrismTech Limited** -| PrismTech House -| 5th Avenue Business Park -| Gateshead -| NE11 0NG -| UK -| Tel: +44 (0)191 497 9900 - -| **PrismTech France** -| 28 rue Jean Rostand -| 91400 Orsay -| France -| Tel: +33 (1) 69 015354 - - -Web: http://www.prismtech.com - -E-mail: \info@prismtech.com - -******* -Notices -******* - -**Copyright** © 2016 PrismTech Limited. All rights reserved. - -*This document may be reproduced in whole but not in part. -The information contained in this document is subject to change -without notice and is made available in good faith without -liability on the part of PrismTech Limited or PrismTech Corporation. -All trademarks acknowledged.* - -.. END +.. include:: ../../common/contacts.rst diff --git a/build/docs/IDLPreProcGuide/source/images/Vortex-OpenSplice-Cover.png b/build/docs/IDLPreProcGuide/source/images/Vortex-OpenSplice-Cover.png index ce86c6d94..801c02bb8 100644 Binary files a/build/docs/IDLPreProcGuide/source/images/Vortex-OpenSplice-Cover.png and b/build/docs/IDLPreProcGuide/source/images/Vortex-OpenSplice-Cover.png differ diff --git a/build/docs/IDLPreProcGuide/source/index.rst b/build/docs/IDLPreProcGuide/source/index.rst index 5fb15a92a..0162eca9a 100644 --- a/build/docs/IDLPreProcGuide/source/index.rst +++ b/build/docs/IDLPreProcGuide/source/index.rst @@ -9,10 +9,10 @@ The IDL PreProcessor Guide .. toctree:: :maxdepth: 6 :numbered: - + preface overview - + prerequisites commandline ddsmodes @@ -21,11 +21,11 @@ The IDL PreProcessor Guide modeslanguages topictypes ddsdatatypes - + bibliography - - contacts - + + contacts + Indices and tables ================== diff --git a/build/docs/IDLPreProcGuide/source/modeslanguages.rst b/build/docs/IDLPreProcGuide/source/modeslanguages.rst index c5081bf57..5626a5ea8 100644 --- a/build/docs/IDLPreProcGuide/source/modeslanguages.rst +++ b/build/docs/IDLPreProcGuide/source/modeslanguages.rst @@ -15,10 +15,10 @@ The Vortex OpenSplice IDL Pre-processor generates IDL code for the specialized *TypeSupport*, *DataReader* and *DataWriter*, as well as C++ implementations and support code. The ORB pre-processor generates from the generated IDL interfaces the C++ specialized interfaces for that specific ORB. These interfaces -are included by the application C++ code as well as the OpenSplice DDS generated +are included by the application C++ code as well as the Vortex OpenSplice generated specialized C++ implementation code. The application C++ code as well as the specialized C++ implementation code (with the support functions) is compiled into -object code and linked together with the applicable OpenSplice libraries and the +object code and linked together with the applicable Vortex OpenSplice libraries and the ORB libraries. |info| @@ -38,19 +38,19 @@ ORB libraries. The role of the Vortex OpenSplice IDL Pre-processor functionality is expanded in -`Integrated C++ ORB OpenSplice IDL Pre-processor Details`_. +`Integrated C++ ORB Vortex OpenSplice IDL Pre-processor Details`_. It shows in more detail which files are generated, given an input file (in this example ``foo.idl``). -.. _`Integrated C++ ORB OpenSplice IDL Pre-processor Details`: +.. _`Integrated C++ ORB Vortex OpenSplice IDL Pre-processor Details`: -.. centered:: **Integrated C++ ORB OpenSplice IDL Pre-processor Details** +.. centered:: **Integrated C++ ORB Vortex OpenSplice IDL Pre-processor Details** .. image:: /images/IntegratedCppORB_detail.png :width: 150mm :align: center - :alt: Integrated C++ ORB OpenSplice IDL Pre-processor Details + :alt: Integrated C++ ORB Vortex OpenSplice IDL Pre-processor Details The file ``foo.h`` is the only file that needs to be included by the application. It includes all files needed by the application to interact with the DCPS interface. @@ -61,9 +61,9 @@ C++ interface files. The ``fooDcps_impl.*`` files contain the specialized *TypeSupport*, *DataReader* and *DataWriter* implementation classes needed to communicate the type *via* -OpenSplice DDS. +Vortex OpenSplice. -The ``fooSplDcps.*`` files contain support functions required by OpenSplice DDS +The ``fooSplDcps.*`` files contain support functions required by Vortex OpenSplice in order to be able to handle the specific data types. @@ -83,7 +83,7 @@ The diagram `C Standalone`_ is an overview of the artifacts and processing stages related to the C standalone context. For C++ the different stages are equal to the C standalone context. Because there is no ORB involved, all pre-processing is performed by the -OpenSplice DDS IDL Pre-processor. The generated specialized implementations +Vortex OpenSplice IDL Pre-processor. The generated specialized implementations and the application’s C++ code must be compiled into object code, plus all objects must be linked with the appropriate Vortex OpenSplice libraries. @@ -111,7 +111,7 @@ scope is not used but ``C99`` types are used in place of C Standalone ************ -The *C standalone* mode provides an OpenSplice DDS context which does not need +The *C standalone* mode provides an Vortex OpenSplice context which does not need an ORB. Vortex OpenSplice resolves all implied IDL to C language mapping functions and requirements. The only difference when using the standalone mode is that DDS is used as the naming scope for definitions and functions. @@ -135,19 +135,19 @@ plus all objects must be linked with the appropriate Vortex OpenSplice libraries The role of the Vortex OpenSplice IDL Pre-processor functionality is expanded in -the diagram `C Standalone OpenSplice IDL Pre-processor Details`_, +the diagram `C Standalone Vortex OpenSplice IDL Pre-processor Details`_, providing more detail about the files generated when provided with an input file (``foo.idl`` this example). -.. _`C Standalone OpenSplice IDL Pre-processor Details`: +.. _`C Standalone Vortex OpenSplice IDL Pre-processor Details`: -.. centered:: **C Standalone OpenSplice IDL Pre-processor Details** +.. centered:: **C Standalone Vortex OpenSplice IDL Pre-processor Details** .. image:: /images/CStandalone_detail.png :width: 150mm :align: center - :alt: C Standalone OpenSplice IDL Pre-processor Details + :alt: C Standalone Vortex OpenSplice IDL Pre-processor Details The file ``foo.h`` is the only file that needs to be included by the application. It itself includes all necessary files needed by the application in order to @@ -158,9 +158,9 @@ accordance with the :ref:`OMG's IDL-to-C language mapping specification `. The ``fooSacDcps.*`` files contain the specialized *TypeSupport*, *DataReader* -and *DataWriter* classes needed to communicate the type *via* OpenSplice DDS. +and *DataWriter* classes needed to communicate the type *via* Vortex OpenSplice. -The ``fooSplDcps.*`` files contain support functions required by OpenSplice DDS in +The ``fooSplDcps.*`` files contain support functions required by Vortex OpenSplice in order to be able to handle the specific data types. C99 Standalone @@ -178,7 +178,7 @@ with a upperboundone larger than specified in the idl to allow for the terminati 0 character. Further an additional file ``fooDcps.c`` is generated which contains the information -to register the type information with OpenSplice DDS. +to register the type information with Vortex OpenSplice. Java Standalone *************** @@ -230,11 +230,11 @@ ORB. The Vortex OpenSplice IDL Pre-processor generates IDL code for the specialized *TypeSupport*, *DataReader* and *DataWriter*, as well as Java implementations and support code. The ORB pre-processor generates the Java ``‘Foo’`` classes, which must be done manually. These classes are -included with the application Java code as well as the OpenSplice DDS +included with the application Java code as well as the Vortex OpenSplice generated specialized Java implementation code. The application Java code as well as the specialized Java implementation code (with the support functions) is compiled into class files and can be used -together with the applicable OpenSplice libraries and the ORB libraries. +together with the applicable Vortex OpenSplice libraries and the ORB libraries. The artifacts and processing stages related to the Java CORBA cohabitation context are similar to those of the standalone mode, with one exception: diff --git a/build/docs/IDLPreProcGuide/source/preface.rst b/build/docs/IDLPreProcGuide/source/preface.rst index 82bc0c583..a710203f9 100644 --- a/build/docs/IDLPreProcGuide/source/preface.rst +++ b/build/docs/IDLPreProcGuide/source/preface.rst @@ -11,7 +11,7 @@ About the IDL PreProcessor Guide The *IDL Pre-processor Guide* describes what the Vortex OpenSplice IDL Pre-processor is, and how to use it. -The Vortex OpenSplice IDL Pre-processor is included with +The Vortex OpenSplice IDL Pre-processor is included with the Vortex OpenSplice product. @@ -25,62 +25,62 @@ applications which use Vortex OpenSplice. Organisation ************ -The :ref:`Overview ` gives a general description of +The :ref:`Overview ` gives a general description of and brief introduction to the IDL Pre-processor. -:ref:`Prerequisites ` describes the prerequisites needed +:ref:`Prerequisites ` describes the prerequisites needed to run the pre-processor. -:ref:`IDL Pre-processor Command Line Options ` -gives detailed descriptions of the options that are available for +:ref:`IDL Pre-processor Command Line Options ` +gives detailed descriptions of the options that are available for running the pre-processor. :ref:`OpenSplice Modes and Languages ` -provides a summary of OpenSplice’s supported modes and languages, as well as +provides a summary of OpenSplice’s supported modes and languages, as well as an overview of the applicable Vortex OpenSplice libraries. -:ref:`IDL Pre-processor Grammar ` +:ref:`IDL Pre-processor Grammar ` shows the IDL grammar that is supported by the Vortex OpenSplice IDL Pre-processor. -:ref:`Keys ` -describes the mechanism for the use of keys with particular data types. +:ref:`Keys ` +describes the mechanism for the use of keys with particular data types. -:ref:`Modes, Languages and Processing steps ` -describes the steps required for creating programs for each of the modes and +:ref:`Modes, Languages and Processing steps ` +describes the steps required for creating programs for each of the modes and languages supported by the Pre-processor. -:ref:`Extensible and Dynamic Topic Types for DDS annotation support ` +:ref:`Extensible and Dynamic Topic Types for DDS annotation support ` describes how the IDL Pre-processor handles the annotation language extension. -:ref:`Built-in DDS data types ` -describes the built-in DDS data types and provides language-specific +:ref:`Built-in DDS data types ` +describes the built-in DDS data types and provides language-specific guidelines on how to use them. Finally, there is :ref:`a bibliography ` which lists -all of the publications referred to in this *Guide*. +all of the publications referred to in this *Guide*. Conventions *********** -The icons shown below are used in PrismTech product documentation -to help readers to quickly identify information relevant to their +The icons shown below are used in ADLINK product documentation +to help readers to quickly identify information relevant to their specific use of Vortex OpenSplice. - ========= ================================================================== - *Icon* *Meaning* - ========= ================================================================== - |caution| Item of special significance or where caution needs to be taken. - |info| Item contains helpful hint or special information. - |windows| Information applies to Windows (*e.g.* XP, 2003, Windows 7) only. - |unix| Information applies to Unix-based systems (*e.g.* Solaris) only. - |linux| Information applies to Linux-based systems (*e.g.* Ubuntu) only. - |c| C language specific. - |cpp| C++ language specific. - |csharp| C# language specific. - |java| Java language specific. - ========= ================================================================== + ========= ================================================================== + *Icon* *Meaning* + ========= ================================================================== + |caution| Item of special significance or where caution needs to be taken. + |info| Item contains helpful hint or special information. + |windows| Information applies to Windows (*e.g.* XP, 2003, Windows 7) only. + |unix| Information applies to Unix-based systems (*e.g.* Solaris) only. + |linux| Information applies to Linux-based systems (*e.g.* Ubuntu) only. + |c| C language specific. + |cpp| C++ language specific. + |csharp| C# language specific. + |java| Java language specific. + ========= ================================================================== @@ -104,4 +104,3 @@ specific use of Vortex OpenSplice. .. |java| image:: ./images/icon-java.* :height: 6mm - \ No newline at end of file diff --git a/build/docs/Makefile b/build/docs/Makefile index 8ff536c3e..2b87de0af 100644 --- a/build/docs/Makefile +++ b/build/docs/Makefile @@ -46,6 +46,21 @@ generate: $(MAKE) -C ModelingGuide html $(MAKE) -C ModelingGuide latexpdf + $(MAKE) -C DDSMATLABGuide html + $(MAKE) -C DDSMATLABGuide latexpdf + + $(MAKE) -C DDSSimulinkGuide html + $(MAKE) -C DDSSimulinkGuide latexpdf + + $(MAKE) -C DDSLabVIEWGuide html + $(MAKE) -C DDSLabVIEWGuide latexpdf + + $(MAKE) -C PythonDCPSAPIGuide html + $(MAKE) -C PythonDCPSAPIGuide latexpdf + + $(MAKE) -C NodeJSDCPSAPIGuide html + $(MAKE) -C NodeJSDCPSAPIGuide latexpdf + docclean: $(MAKE) -C ConfGuide clean $(MAKE) -C GettingStartedGuide clean @@ -61,6 +76,11 @@ docclean: $(MAKE) -C RnRManagerGuide clean $(MAKE) -C StreamsAPIReference clean $(MAKE) -C ModelingGuide clean + $(MAKE) -C DDSMATLABGuide clean + $(MAKE) -C DDSSimulinkGuide clean + $(MAKE) -C DDSLabVIEWGuide clean + $(MAKE) -C PythonDCPSAPIGuide clean + $(MAKE) -C NodeJSDCPSAPIGuide clean rm -rf configuide/source/ddsi2e.xml diff --git a/build/docs/ModelingGuide/source/appendixa.rst b/build/docs/ModelingGuide/source/appendixa.rst index 9be515422..aaa0e3448 100644 --- a/build/docs/ModelingGuide/source/appendixa.rst +++ b/build/docs/ModelingGuide/source/appendixa.rst @@ -38,7 +38,7 @@ Chatter Application ChatterApplication.java /******************************************************************************* - * Copyright (c) 2012 to 2016 PrismTech Ltd. All rights Reserved. + * Copyright (c) 2012 to 2018 ADLINK Technology Limited. All rights Reserved. * LOGICAL_NAME: ChatterApplication.java * FUNCTION: Vortex OpenSplice Modeler Tutorial example code. * MODULE: Tutorial for the Java programming language. @@ -205,8 +205,8 @@ MessageBoard Application /************************************************************************ * - * Copyright (c) 2012 to 2016 - * PrismTech Ltd. + * Copyright (c) 2012 to 2018 + * ADLINK Technology Limited * All rights Reserved. * * LOGICAL_NAME: MessageBoardApplication.java @@ -396,7 +396,7 @@ ChatMessageDataReaderListenerImpl.java ChatMessageDataReaderListenerImpl.java /************************************************************************ - * Copyright (c) 2012 to 2016 PrismTech Ltd. All rights Reserved. + * Copyright (c) 2012 to 2018 ADLINK Technology Limited. All rights Reserved. * LOGICAL_NAME: ChatMessageDataReaderListenerImpl.java * FUNCTION: Vortex OpenSplice Modeler Tutorial example code * MODULE: Tutorial for the Java programming language @@ -625,8 +625,8 @@ NamedMessageDataReaderListenerImpl.java /************************************************************************ * - * Copyright (c) 2012 to 2016 - * PrismTech Ltd. + * Copyright (c) 2012 to 2018 + * ADLINK Technology Limited * All rights Reserved. * * LOGICAL_NAME: NamedMessageDataReaderListenerImpl.java @@ -719,8 +719,8 @@ UserLoad Application /******************************************************************************* - * Copyright (c) 2012 to 2016 - * PrismTech Ltd. + * Copyright (c) 2012 to 2018 + * ADLINK Technology Limited * All rights Reserved. * * LOGICAL_NAME: UserLoadApplication.java @@ -972,8 +972,8 @@ Error Handler /************************************************************************ * - * Copyright (c) 2012 to 2016 - * PrismTech Ltd. + * Copyright (c) 2012 to 2018 + * ADLINK Technology Limited * All rights Reserved. * * LOGICAL_NAME: ErrorHandler.java diff --git a/build/docs/ModelingGuide/source/appendixb.rst b/build/docs/ModelingGuide/source/appendixb.rst index 464c3786d..179d4f098 100644 --- a/build/docs/ModelingGuide/source/appendixb.rst +++ b/build/docs/ModelingGuide/source/appendixb.rst @@ -75,8 +75,8 @@ ChatterApplication.cpp, Linux Version /************************************************************************ * - * Copyright (c) 2012 to 2016 - * PrismTech Ltd. + * Copyright (c) 2012 to 2018 + * ADLINK Technology Limited * All rights Reserved. * * LOGICAL_NAME: ChatterApplication.cpp @@ -233,8 +233,8 @@ ChatterApplication.cpp, Windows Version /************************************************************************ * - * Copyright (c) 2012 to 2016 - * PrismTech Ltd. + * Copyright (c) 2012 to 2018 + * ADLINK Technology Limited * All rights Reserved. * * LOGICAL_NAME: ChatterApplication.cpp @@ -391,8 +391,8 @@ MessageBoardApplication.cpp, Linux Version /************************************************************************ * - * Copyright (c) 2012 to 2016 - * PrismTech Ltd. + * Copyright (c) 2012 to 2018 + * ADLINK Technology Limited * All rights Reserved. * * LOGICAL_NAME: MessageBoardApplication.cpp @@ -539,8 +539,8 @@ MessageBoardApplication.cpp, Windows Version /************************************************************************ * - * Copyright (c) 2012 to 2016 - * PrismTech Ltd. + * Copyright (c) 2012 to 2018 + * ADLINK Technology Limited * All rights Reserved. * * LOGICAL_NAME: MessageBoardApplication.cpp @@ -679,8 +679,8 @@ ChatMessageDataReaderListenerImpl.h, Linux version /************************************************************************ * - * Copyright (c) 2012 to 2016 - * PrismTech Ltd. + * Copyright (c) 2012 to 2018 + * ADLINK Technology Limited * All rights Reserved. * * LOGICAL_NAME: ChatMessageDataReaderListenerImpl.h @@ -785,8 +785,8 @@ ChatMessageDataReaderListenerImpl.h, Windows version /************************************************************************ * - * Copyright (c) 2012 to 2016 - * PrismTech Ltd. + * Copyright (c) 2012 to 2018 + * ADLINK Technology Limited * All rights Reserved. * * LOGICAL_NAME: ChatMessageDataReaderListenerImpl.h @@ -888,8 +888,8 @@ ChatMessageDataReaderListenerImpl.cpp /************************************************************************ * - * Copyright (c) 2012 to 2016 - * PrismTech Ltd. + * Copyright (c) 2012 to 2018 + * ADLINK Technology Limited * All rights Reserved. * * LOGICAL_NAME: ChatMessageDataReaderListenerImpl.cpp @@ -1067,8 +1067,8 @@ NamedMessageDataReaderListenerImpl.h, Linux Version /************************************************************************ * - * Copyright (c) 2012 to 2016 - * PrismTech Ltd. + * Copyright (c) 2012 to 2018 + * ADLINK Technology Limited * All rights Reserved. * * LOGICAL_NAME: NamedMessageDataReaderListenerImpl.h @@ -1154,8 +1154,8 @@ NamedMessageDataReaderListenerImpl.h, Windows Version /************************************************************************ * - * Copyright (c) 2012 to 2016 - * PrismTech Ltd. + * Copyright (c) 2012 to 2018 + * ADLINK Technology Limited * All rights Reserved. * * LOGICAL_NAME: NamedMessageDataReaderListenerImpl.h @@ -1240,8 +1240,8 @@ NamedMessageDataReaderListenerImpl.cpp /************************************************************************ * - * Copyright (c) 2012 to 2016 - * PrismTech Ltd. + * Copyright (c) 2012 to 2018 + * ADLINK Technology Limited * All rights Reserved. * * LOGICAL_NAME: NamedMessageDataReaderListenerImpl.cpp @@ -1319,8 +1319,8 @@ UserLoadApplication.cpp, Linux Version /************************************************************************ * - * Copyright (c) 2012 to 2016 - * PrismTech Ltd. + * Copyright (c) 2012 to 2018 + * ADLINK Technology Limited * All rights Reserved. * * LOGICAL_NAME: UserLoadApplication.cpp @@ -1535,8 +1535,8 @@ UserLoadApplication.cpp, Windows Version /************************************************************************ * - * Copyright (c) 2012 to 2016 - * PrismTech Ltd. + * Copyright (c) 2012 to 2018 + * ADLINK Technology Limited * All rights Reserved. * * LOGICAL_NAME: UserLoadApplication.cpp @@ -1755,8 +1755,8 @@ CheckStatus.h /************************************************************************ * - * Copyright (c) 2012 to 2016 - * PrismTech Ltd. + * Copyright (c) 2012 to 2018 + * ADLINK Technology Limited * All rights Reserved. * * LOGICAL_NAME: CheckStatus.h @@ -1804,8 +1804,8 @@ CheckStatus.cpp /************************************************************************ * - * Copyright (c) 2012 to 2016 - * PrismTech Ltd. + * Copyright (c) 2012 to 2018 + * ADLINK Technology Limited * All rights Reserved. * * LOGICAL_NAME: CheckStatus.cpp diff --git a/build/docs/ModelingGuide/source/codegeneration.rst b/build/docs/ModelingGuide/source/codegeneration.rst index 44f17ecc5..b5c4325b3 100644 --- a/build/docs/ModelingGuide/source/codegeneration.rst +++ b/build/docs/ModelingGuide/source/codegeneration.rst @@ -15,9 +15,9 @@ an easy-to-use, Eclipse-based graphical interface.* |caution| +------------------------------------------------------------------+ - | The OpenSplice HDE (version 6.1 or above) must be installed and | - | configured in order to generate code for OpenSplice from Vortex | - | OpenSplice Modeler. | + | The Vortex OpenSplice HDE (version 6.1 or above) must be | + | installed and configured in order to generate code for Vortex | + | OpenSplice from Vortex OpenSplice Modeler. | | | | Vortex Lite (version 1.2 or above) must be installed and | | configured in order to generate code targeting Vortex Lite from | @@ -31,7 +31,7 @@ aim and is able to generate: + code for DDS data types, including - - IDL specifications for Vortex OpenSplice DDS Data Types + - IDL specifications for Vortex OpenSplice Data Types - Native language interfaces for Vortex OpenSplice Data Types (*via* the Vortex OpenSplice IDL Pre-Processor) @@ -1674,4 +1674,3 @@ This class defines the following methods: .. |java| image:: ./images/icon-java.* :height: 6mm - \ No newline at end of file diff --git a/build/docs/ModelingGuide/source/conf.py b/build/docs/ModelingGuide/source/conf.py index 9de05c8eb..8bac62e8a 100644 --- a/build/docs/ModelingGuide/source/conf.py +++ b/build/docs/ModelingGuide/source/conf.py @@ -63,9 +63,8 @@ def setup(app): # General information about the project. project = u'Modeling Guide' -#copyright = u'2015, PrismTech' this_year = time.strftime( '%Y' ) -copyright = u'{y}, PrismTech'.format( y = this_year ) +copyright = u'{y}, ADLINK Technology Limited'.format( y = this_year ) print 'Copyright string is:', copyright @@ -230,7 +229,7 @@ def setup(app): # Added 'True' to end of generated line to suppress 'Index & Tables' -# A dictionary that contains LaTeX snippets that override those Sphinx usually +# A dictionary that contains LaTeX snippets that override those Sphinx usually # puts into the generated .tex files. latex_elements = { 'babel': '\\usepackage[english]{babel}' } @@ -271,7 +270,7 @@ def setup(app): # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). -man_pages = [('index', 'Modeling_Guide', u'Modeling_Guide', [u'PrismTech'], 1)] +man_pages = [('index', 'Modeling_Guide', u'Modeling_Guide', [u'ADLINK Technology Limited'], 1)] # -- Additional options -------------------------------------------------------- diff --git a/build/docs/ModelingGuide/source/contacts.rst b/build/docs/ModelingGuide/source/contacts.rst index fc6442d3a..d32f6016f 100644 --- a/build/docs/ModelingGuide/source/contacts.rst +++ b/build/docs/ModelingGuide/source/contacts.rst @@ -1,53 +1 @@ -.. _`Contacts & Notices`: - -.. VERY LITTLE EVER CHANGES IN HERE !! - Just keep an eye on the copyright notice. - -################## -Contacts & Notices -################## - -******** -Contacts -******** - -| **PrismTech Corporation** -| 400 TradeCenter -| Suite 5900 -| Woburn, MA -| 01801 -| USA -| Tel: +1 781 569 5819 - -| **PrismTech Limited** -| PrismTech House -| 5th Avenue Business Park -| Gateshead -| NE11 0NG -| UK -| Tel: +44 (0)191 497 9900 - -| **PrismTech France** -| 28 rue Jean Rostand -| 91400 Orsay -| France -| Tel: +33 (1) 69 015354 - - -Web: http://www.prismtech.com - -E-mail: \info@prismtech.com - -******* -Notices -******* - -**Copyright** © 2016 PrismTech Limited. All rights reserved. - -*This document may be reproduced in whole but not in part. -The information contained in this document is subject to change -without notice and is made available in good faith without -liability on the part of PrismTech Limited or PrismTech Corporation. -All trademarks acknowledged.* - -.. END +.. include:: ../../common/contacts.rst diff --git a/build/docs/ModelingGuide/source/images/003_DesignPerspec_EgProj.png b/build/docs/ModelingGuide/source/images/003_DesignPerspec_EgProj.png index 9867d4e5a..7a0268791 100644 Binary files a/build/docs/ModelingGuide/source/images/003_DesignPerspec_EgProj.png and b/build/docs/ModelingGuide/source/images/003_DesignPerspec_EgProj.png differ diff --git a/build/docs/ModelingGuide/source/images/004_NewProjectDialog.png b/build/docs/ModelingGuide/source/images/004_NewProjectDialog.png index 82c0764ad..14706667a 100644 Binary files a/build/docs/ModelingGuide/source/images/004_NewProjectDialog.png and b/build/docs/ModelingGuide/source/images/004_NewProjectDialog.png differ diff --git a/build/docs/ModelingGuide/source/images/006_QoSsetEditor_overview.png b/build/docs/ModelingGuide/source/images/006_QoSsetEditor_overview.png index 3a7bff862..3c154cf3e 100644 Binary files a/build/docs/ModelingGuide/source/images/006_QoSsetEditor_overview.png and b/build/docs/ModelingGuide/source/images/006_QoSsetEditor_overview.png differ diff --git a/build/docs/ModelingGuide/source/images/016_ExportApplicationDialog.png b/build/docs/ModelingGuide/source/images/016_ExportApplicationDialog.png index 528d3ea88..2f37ac4ad 100644 Binary files a/build/docs/ModelingGuide/source/images/016_ExportApplicationDialog.png and b/build/docs/ModelingGuide/source/images/016_ExportApplicationDialog.png differ diff --git a/build/docs/ModelingGuide/source/images/Vortex-OpenSplice-Cover.png b/build/docs/ModelingGuide/source/images/Vortex-OpenSplice-Cover.png index ce86c6d94..801c02bb8 100644 Binary files a/build/docs/ModelingGuide/source/images/Vortex-OpenSplice-Cover.png and b/build/docs/ModelingGuide/source/images/Vortex-OpenSplice-Cover.png differ diff --git a/build/docs/ModelingGuide/source/index.rst b/build/docs/ModelingGuide/source/index.rst index c9058abe5..4b2d0865b 100644 --- a/build/docs/ModelingGuide/source/index.rst +++ b/build/docs/ModelingGuide/source/index.rst @@ -9,7 +9,7 @@ Modeling Guide .. toctree:: :maxdepth: 8 :numbered: - + preface introduction installation @@ -19,12 +19,12 @@ Modeling Guide launchconfig compileandrun tutorial - + appendixa appendixb - - contacts - + + contacts + Indices and tables ================== diff --git a/build/docs/ModelingGuide/source/installation.rst b/build/docs/ModelingGuide/source/installation.rst index 54d78d7d7..6a008bbd1 100644 --- a/build/docs/ModelingGuide/source/installation.rst +++ b/build/docs/ModelingGuide/source/installation.rst @@ -14,7 +14,7 @@ Modeler. **Step 1:** Prerequisites - Ensure that Java Version 6 (*required*) and the OpenSplice Host + Ensure that Java Version 6 (*required*) and the Vortex OpenSplice Host Development Environment [#]_ (*recommended*), plus any other supporting software (such as native compilers, for example), are installed and working. @@ -24,7 +24,7 @@ Modeler. *Release Notes* included with your Modeler product distribution. The Release Notes can be viewed by opening ``index.html`` located in - the root (or base) directory of your OpenSplice installation and + the root (or base) directory of your Vortex OpenSplice installation and following the *Release Notes* link. **Step 2:** Run the Vortex OpenSplice Modeler installer @@ -63,11 +63,11 @@ Modeler. **Step 3:** Install the license file - A license file must be obtained from PrismTech, then copied to + A license file must be obtained from ADLINK, then copied to the ``eclipse`` or ``eclipse/etc`` subdirectories where the Vortex OpenSplice Modeler has been installed, or copied to - the ``PrismTech/Vortex_v2/license`` directory, or have the - ``prismtech_LICENSE`` environment variable defined with the file + the ``ADLINK/Vortex_v2/license`` directory, or have the + ``ADLINK_LICENSE`` environment variable defined with the file path to the license file. @@ -75,21 +75,21 @@ Modeler. |unix| |linux| - ``/home/myHomeDir/PrismTech/Vortex_v2/Tools/VortexModeler/2.5.12/eclipse/etc`` + ``/home/myHomeDir/ADLINK/Vortex_v2/Tools/VortexModeler/2.5.12/eclipse/etc`` |windows| - ``\PrismTech\Vortex_v2\Tools\VortexModeler\2.5.12\eclipse`` + ``\ADLINK\Vortex_v2\Tools\VortexModeler\2.5.12\eclipse`` For more information about licensing, please refer to the *Getting Started Guide*. -Setting OpenSplice Preferences -****************************** +Setting Vortex OpenSplice Preferences +************************************* After installing the Vortex OpenSplice Modeler it is necessary -to specify the location of the OpenSplice DDS installation to be +to specify the location of the Vortex OpenSplice installation to be used. **Step 1:** Start the Vortex OpenSplice Modeler. @@ -98,12 +98,12 @@ used. **Step 3:** Select *OpenSplice*. -**Step 4:** Add the location of the OpenSplice DDS installation +**Step 4:** Add the location of the Vortex OpenSplice installation to ``OSPL_HOME``. In the ``OSPL_HOME`` path field enter (for example) - ``/home/apps/PrismTech/Vortex_v2/Device/VortexOpenSplice/6.6.0p1/HDE/x86_64.linux`` + ``/home/apps/ADLINK/Vortex_v2/Device/VortexOpenSplice/6.6.0p1/HDE/x86_64.linux`` The *Browse* button can be used to navigate through your file system to point to the installation. @@ -115,34 +115,34 @@ to ``OSPL_HOME``. Set the ``LITE_HOME`` path field, *e.g.* - ``/home/apps/PrismTech/Device/VortexLite/2.0.0`` + ``/home/apps/ADLINK/Device/VortexLite/2.0.0`` As before, you can set the ``LITE_URI`` path to a Vortex Lite configuration file if required. - .. _`The OpenSplice Preferences`: + .. _`The Vortex OpenSplice Preferences`: - .. centered:: **The OpenSplice Preferences** + .. centered:: **The Vortex OpenSplice Preferences** .. image:: /images/001_OpenSplicePreferences.png :width: 120mm :align: center - :alt: The OpenSplice Preferences + :alt: The Vortex OpenSplice Preferences The license location can also be specified using the *Licensing - Preferences* page, which is below the *OpenSplice Preferences* + Preferences* page, which is below the *Vortex OpenSplice Preferences* page described above. -.. _`OpenSplice licensing`: +.. _`Vortex OpenSplice licensing`: -.. centered:: **OpenSplice licensing** +.. centered:: **Vortex OpenSplice licensing** .. image:: /images/002_OpenSpliceLicensing.png :width: 120mm :align: center - :alt: OpenSplice licensing + :alt: Vortex OpenSplice licensing .. the illo above *ought* to be indented 2 spaces to align properly with the previous one in the PDF, but it actually @@ -174,7 +174,7 @@ OpenSplice Modeler installation. On **Unix-based platforms** (including Linux), the default path will be: - ``/home/myHomeDir/PrismTech/Vortex_v2/Tools/VortexModeler//uninstall`` + ``/home/myHomeDir/ADLINK/Vortex_v2/Tools/VortexModeler//uninstall`` where ```` is the release version number. @@ -182,7 +182,7 @@ OpenSplice Modeler installation. On **Windows-based platforms**, the default path will be: - ``\PrismTech\Vortex_v2\Tools\VortexModeler\\uninstall`` + ``\ADLINK\Vortex_v2\Tools\VortexModeler\\uninstall`` where ```` is the release version number. @@ -254,4 +254,3 @@ OpenSplice Modeler installation. .. |java| image:: ./images/icon-java.* :height: 6mm - \ No newline at end of file diff --git a/build/docs/ModelingGuide/source/introduction.rst b/build/docs/ModelingGuide/source/introduction.rst index 95f657e7a..8a1c5bd45 100644 --- a/build/docs/ModelingGuide/source/introduction.rst +++ b/build/docs/ModelingGuide/source/introduction.rst @@ -8,7 +8,7 @@ Introduction *The* Vortex OpenSplice Modeler *is an integrated Eclipse-based tool chain based on Data Distribution Service (DDS) domain-specific model driven techniques. It provides the -essential productivity tools of PrismTech’s third generation +essential productivity tools of ADLINK's third generation OMG-DDS suite.* Vortex OpenSplice is a suite of software products comprised of a diff --git a/build/docs/ModelingGuide/source/launchconfig.rst b/build/docs/ModelingGuide/source/launchconfig.rst index fa4126a4b..2467b8bfe 100644 --- a/build/docs/ModelingGuide/source/launchconfig.rst +++ b/build/docs/ModelingGuide/source/launchconfig.rst @@ -84,7 +84,7 @@ Creating the ``start`` Configuration *Location* text box. For example, on Windows this could be - ``"C:\Program Files (x86)\PrismTech\Vortex_v2\Device\VortexOpenSplice\6.6.0p1\HDE\x86.win32\bin\ospl.exe"``. + ``"C:\Program Files (x86)\ADLINK\Vortex_v2\Device\VortexOpenSplice\6.6.0p1\HDE\x86.win32\bin\ospl.exe"``. **Step 5** diff --git a/build/docs/ModelingGuide/source/preface.rst b/build/docs/ModelingGuide/source/preface.rst index ecf66c995..200225ad1 100644 --- a/build/docs/ModelingGuide/source/preface.rst +++ b/build/docs/ModelingGuide/source/preface.rst @@ -67,9 +67,9 @@ in the :ref:`Tutorial `. Conventions *********** -The icons shown below are used in PrismTech product documentation +The icons shown below are used in the Vortex product documentation to help readers to quickly identify information relevant to their -specific use of Vortex OpenSplice DDS. +specific use of Vortex OpenSplice. ========= ================================================================== @@ -108,4 +108,4 @@ specific use of Vortex OpenSplice DDS. .. |java| image:: ./images/icon-java.* :height: 6mm - \ No newline at end of file + diff --git a/build/docs/ModelingGuide/source/tutorial.rst b/build/docs/ModelingGuide/source/tutorial.rst index ce9aab254..502757658 100644 --- a/build/docs/ModelingGuide/source/tutorial.rst +++ b/build/docs/ModelingGuide/source/tutorial.rst @@ -366,8 +366,8 @@ following code extract. /***************************************************************** * - * Copyright (c) 2006 to 2016 - * PrismTech Ltd. + * Copyright (c) 2006 to 2018 + * ADLINK Technology Limited * All rights Reserved. * * LOGICAL_NAME: Chat.idl @@ -1408,4 +1408,4 @@ The output of each application should be as shown below: .. |java| image:: ./images/icon-java.* :height: 6mm - \ No newline at end of file + diff --git a/build/docs/NodeJSDCPSAPIGuide/Makefile b/build/docs/NodeJSDCPSAPIGuide/Makefile new file mode 100644 index 000000000..fe415b065 --- /dev/null +++ b/build/docs/NodeJSDCPSAPIGuide/Makefile @@ -0,0 +1,130 @@ +# Makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = sphinx-build +PAPER = +BUILDDIR = build + +# Internal variables. +PAPEROPT_a4 = -D latex_paper_size=a4 +PAPEROPT_letter = -D latex_paper_size=letter +ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source + +.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest + +help: + @echo "Please use \`make ' where is one of" + @echo " html to make standalone HTML files" + @echo " dirhtml to make HTML files named index.html in directories" + @echo " singlehtml to make a single large HTML file" + @echo " pickle to make pickle files" + @echo " json to make JSON files" + @echo " htmlhelp to make HTML files and a HTML help project" + @echo " qthelp to make HTML files and a qthelp project" + @echo " devhelp to make HTML files and a Devhelp project" + @echo " epub to make an epub" + @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" + @echo " latexpdf to make LaTeX files and run them through pdflatex" + @echo " text to make text files" + @echo " man to make manual pages" + @echo " changes to make an overview of all changed/added/deprecated items" + @echo " linkcheck to check all external links for integrity" + @echo " doctest to run all doctests embedded in the documentation (if enabled)" + +clean: + -rm -rf $(BUILDDIR)/* + +html: + $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." + +dirhtml: + $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." + +singlehtml: + $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml + @echo + @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." + +pickle: + $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle + @echo + @echo "Build finished; now you can process the pickle files." + +json: + $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json + @echo + @echo "Build finished; now you can process the JSON files." + +htmlhelp: + $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp + @echo + @echo "Build finished; now you can run HTML Help Workshop with the" \ + ".hhp project file in $(BUILDDIR)/htmlhelp." + +qthelp: + $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp + @echo + @echo "Build finished; now you can run "qcollectiongenerator" with the" \ + ".qhcp project file in $(BUILDDIR)/qthelp, like this:" + @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/OpenSplice_Getting_Started_Guide.qhcp" + @echo "To view the help file:" + @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/OpenSplice_Getting_Started_Guide.qhc" + +devhelp: + $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp + @echo + @echo "Build finished." + @echo "To view the help file:" + @echo "# mkdir -p $$HOME/.local/share/devhelp/OpenSplice_Getting_Started_Guide" + @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/OpenSplice_Getting_Started_Guide" + @echo "# devhelp" + +epub: + $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub + @echo + @echo "Build finished. The epub file is in $(BUILDDIR)/epub." + +latex: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo + @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." + @echo "Run \`make' in that directory to run these through (pdf)latex" \ + "(use \`make latexpdf' here to do that automatically)." + +latexpdf: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo "Running LaTeX files through latexpdf..." + make -C $(BUILDDIR)/latex all-pdf + @echo "latexpdf finished; the PDF files are in $(BUILDDIR)/latexpdf." + +text: + $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text + @echo + @echo "Build finished. The text files are in $(BUILDDIR)/text." + +man: + $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man + @echo + @echo "Build finished. The manual pages are in $(BUILDDIR)/man." + +changes: + $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes + @echo + @echo "The overview file is in $(BUILDDIR)/changes." + +linkcheck: + $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck + @echo + @echo "Link check complete; look for any errors in the above output " \ + "or in $(BUILDDIR)/linkcheck/output.txt." + +doctest: + $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest + @echo "Testing of doctests in the sources finished, look at the " \ + "results in $(BUILDDIR)/doctest/output.txt." diff --git a/build/docs/NodeJSDCPSAPIGuide/make.bat b/build/docs/NodeJSDCPSAPIGuide/make.bat new file mode 100644 index 000000000..fff4f8663 --- /dev/null +++ b/build/docs/NodeJSDCPSAPIGuide/make.bat @@ -0,0 +1,183 @@ +@ECHO OFF + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set BUILDDIR=build +set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% source +if NOT "%PAPER%" == "" ( + set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS% +) + +if "%1" == "" goto help + +if "%1" == "help" ( + :help + echo.Please use `make ^` where ^ is one of + echo. html to make standalone HTML files + echo. dirhtml to make HTML files named index.html in directories + echo. singlehtml to make a single large HTML file + echo. pickle to make pickle files + echo. json to make JSON files + echo. htmlhelp to make HTML files and a HTML help project + echo. qthelp to make HTML files and a qthelp project + echo. devhelp to make HTML files and a Devhelp project + echo. epub to make an epub + echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter + echo. text to make text files + echo. man to make manual pages + echo. changes to make an overview over all changed/added/deprecated items + echo. linkcheck to check all external links for integrity + echo. doctest to run all doctests embedded in the documentation if enabled + goto end +) + +if "%1" == "clean" ( + for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i + del /q /s %BUILDDIR%\* + goto end +) + +if "%1" == "html" ( + %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The HTML pages are in %BUILDDIR%/html. + goto end +) + +if "%1" == "dirhtml" ( + %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml. + goto end +) + +if "%1" == "singlehtml" ( + %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml. + goto end +) + +if "%1" == "pickle" ( + %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can process the pickle files. + goto end +) + +if "%1" == "json" ( + %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can process the JSON files. + goto end +) + +if "%1" == "htmlhelp" ( + %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can run HTML Help Workshop with the ^ +.hhp project file in %BUILDDIR%/htmlhelp. + goto end +) + +if "%1" == "qthelp" ( + %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can run "qcollectiongenerator" with the ^ +.qhcp project file in %BUILDDIR%/qthelp, like this: + echo.^> qcollectiongenerator %BUILDDIR%\qthelp\OpenSplice_Getting_Started_Guide.qhcp + echo.To view the help file: + echo.^> assistant -collectionFile %BUILDDIR%\qthelp\OpenSplice_Getting_Started_Guide.ghc + goto end +) + +if "%1" == "devhelp" ( + %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. + goto end +) + +if "%1" == "epub" ( + %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The epub file is in %BUILDDIR%/epub. + goto end +) + +if "%1" == "latex" ( + %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; the LaTeX files are in %BUILDDIR%/latex. + goto end +) + +if "%1" == "latexpdf" ( + %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latexpdf + echo %BUILDDIR%/latexpdf +REM Typical path: "c:\Program Files (x86)\GnuWin32\bin\make.exe" -C %BUILDDIR%\latexpdf all-pdf +REM Actual path on this system: C:\apps\GnuWin32\bin\make.exe -C %BUILDDIR%\latexpdf all-pdf + C:\apps\GnuWin32\bin\make.exe -C %BUILDDIR%\latexpdf all-pdf + echo.Build done + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; the LaTeX files are in %BUILDDIR%/latexpdf. + goto end +) + +if "%1" == "text" ( + %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The text files are in %BUILDDIR%/text. + goto end +) + +if "%1" == "man" ( + %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The manual pages are in %BUILDDIR%/man. + goto end +) + +if "%1" == "changes" ( + %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes + if errorlevel 1 exit /b 1 + echo. + echo.The overview file is in %BUILDDIR%/changes. + goto end +) + +if "%1" == "linkcheck" ( + %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck + if errorlevel 1 exit /b 1 + echo. + echo.Link check complete; look for any errors in the above output ^ +or in %BUILDDIR%/linkcheck/output.txt. + goto end +) + +if "%1" == "doctest" ( + %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest + if errorlevel 1 exit /b 1 + echo. + echo.Testing of doctests in the sources finished, look at the ^ +results in %BUILDDIR%/doctest/output.txt. + goto end +) + +:end diff --git a/build/docs/NodeJSDCPSAPIGuide/source/conf.py b/build/docs/NodeJSDCPSAPIGuide/source/conf.py new file mode 100644 index 000000000..ed5e5ac1b --- /dev/null +++ b/build/docs/NodeJSDCPSAPIGuide/source/conf.py @@ -0,0 +1,267 @@ +# -*- coding: utf-8 -*- +# +# NodeJSDCPSAPIGuide build configuration file, created by +# ReST Editor on 28-Nov-2017 +# +# This file is execfile()d with the current directory set to its containing dir. +# +# Note that not all possible configuration values are present in this +# autogenerated file. +# +# All configuration values have a default; values that are commented out +# serve to show the default. + +import sys, os +import time + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +#sys.path.insert(0, os.path.abspath('.')) + +# -- General configuration ----------------------------------------------------- + +# If your documentation needs a minimal Sphinx version, state it here. +#needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be extensions +# coming with Sphinx (named 'sphinx.ext.*') or your custom ones. +#extensions = ['sphinx.ext.todo'] + +extensions = ['sphinx.ext.todo', 'sphinx.ext.ifconfig'] + +# Add any paths that contain templates here, relative to this directory. +templates_path = [u'_templates'] + + +# The suffix of source filenames. +source_suffix = '.rst' + +# The encoding of source files. +source_encoding = u'utf-8-sig' + + +# The master toctree document. +master_doc = u'index' + + +# General information about the project. +project = u'Node.js DCPS API Guide' + +this_year = time.strftime( '%Y' ) +copyright = u'{y}, ADLINK Technology Limited'.format( y = this_year ) +print 'Copyright string is:', copyright + + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# +# The short X.Y version. +version = u'Beta 6.x' + +# The full version, including alpha/beta/rc tags. +release = version +#release = u'.0' +print 'Short version string is:', version +print 'Full version string is:', release + + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +language = u'en' + + +# There are two options for replacing |today|: either, you set today to some +# non-false value, then it is used: +today = ' ' +# Else, today_fmt is used as the format for a strftime call. +#today_fmt = '%B %d, %Y' + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +exclude_patterns = [] + +# The reST default role (used for this markup: `text`) to use for all documents. +#default_role = None + +# If true, '()' will be appended to :func: etc. cross-reference text. +#add_function_parentheses = True + +# If true, the current module name will be prepended to all description +# unit titles (such as .. function::). +#add_module_names = True + +# If true, sectionauthor and moduleauthor directives will be shown in the +# output. They are ignored by default. +#show_authors = False + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + +# A list of ignored prefixes for module index sorting. +#modindex_common_prefix = [] + + +# -- Options for HTML output --------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# html_theme = u'sphinxdoc' +html_theme = u'vortextheme' +# LINUX PATH: +html_theme_path = ['../../.'] +# WINDOWS PATH: +# html_theme_path = ['..\..\.'] +#build theme directory in lite using environment variable, so shared amongst books +# insight team can delete, +#html_theme_path = [os.environ['VL_HOME'] + '/build/docs'] + + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +#html_theme_options = {} + +# Add any paths that contain custom themes here, relative to this directory. +#html_theme_path = [] + +# The name for this set of Sphinx documents. If None, it defaults to +# " v documentation". +#html_title = None +html_title = 'Node.js DCPS API Guide' + +# A shorter title for the navigation bar. Default is the same as html_title. +#html_short_title = None +#html_short_title = 'HTML short Title conf.py' +html_short_title = 'Node.js DCPS API Guide' + +# The name of an image file (relative to this directory) to place at the top +# of the sidebar. +html_logo = './images/Vortex_logo_2014.png' + +# The name of an image file (within the static path) to use as favicon of the +# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 +# pixels large. +#html_favicon = None + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = [u'_static'] + + +# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, +# using the given strftime format. +#html_last_updated_fmt = '%b %d, %Y' + +# If true, SmartyPants will be used to convert quotes and dashes to +# typographically correct entities. +#html_use_smartypants = True + +# Custom sidebar templates, maps document names to template names. +#html_sidebars = {} + +# Additional templates that should be rendered to pages, maps page names to +# template names. +#html_additional_pages = {} + +# If false, no module index is generated. +#html_domain_indices = True + +# If false, no index is generated. +#html_use_index = True + +# If true, the index is split into individual pages for each letter. +#html_split_index = False + +# If true, links to the reST sources are added to the pages. +#html_show_sourcelink = True + +# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. +#html_show_sphinx = True +html_show_sphinx = False + +# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. +#html_show_copyright = True + +# If true, an OpenSearch description file will be output, and all pages will +# contain a tag referring to it. The value of this option must be the +# base URL from which the finished HTML is served. +#html_use_opensearch = '' + +# This is the file name suffix for HTML files (e.g. ".xhtml"). +#html_file_suffix = None + +# Output file base name for HTML help builder. +htmlhelp_basename = 'Node.js DCPS API Guide' + + +# -- Options for LaTeX output -------------------------------------------------- + +# The paper size ('letter' or 'a4'). +latex_paper_size = u'a4' + + +# The font size ('10pt', '11pt' or '12pt'). +latex_font_size = u'10pt' + + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, author, documentclass [howto/manual]). +latex_documents = [('index', 'OpenSplice_NodeJSDCPSAPIGuide.tex', u'Node.js DCPS API Guide', u'', 'manual', True)] +# Note 'author' field empty +# Added 'True' to end of generated line to suppress 'Index & Tables' + + +# A dictionary that contains LaTeX snippets that override those Sphinx usually +# puts into the generated .tex files. +latex_elements = { 'babel': '\\usepackage[english]{babel}' } + + +# The name of an image file (relative to this directory) to place at the top of +# the title page. +latex_logo = './images/Vortex-Cover.png' + +# For "manual" documents, if this is true, then toplevel headings are parts, +# not chapters. +latex_use_parts = False + + +# If true, show page references after internal links. +#latex_show_pagerefs = False + +# If true, show URL addresses after external links. +#latex_show_urls = False + +# Additional stuff for the LaTeX preamble. +latex_preamble = r""" +\setcounter {tocdepth} {5} +\setcounter{secnumdepth}{5} + +""" + +# * THIS GETS RID OF BLANK PAGES AT ENDS OF CHAPTERS & ToC +latex_elements = { + 'classoptions': ',openany, oneside', + 'babel': '\\usepackage[english]{babel}' +} + + +# Documents to append as an appendix to all manuals. +#latex_appendices = [] + +# If false, no module index is generated. +#latex_domain_indices = True + + +# -- Options for manual page output -------------------------------------------- + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [('index', 'OpenSplice_NodeJSDCPSAPIGuide', u'OpenSplice_NodeJSDCPSAPI Documentation', [u'ADLINK Technology Limited'], 1)] + + +# -- Additional options -------------------------------------------------------- + +todo_include_todos = True diff --git a/build/docs/NodeJSDCPSAPIGuide/source/contacts.rst b/build/docs/NodeJSDCPSAPIGuide/source/contacts.rst new file mode 100644 index 000000000..d32f6016f --- /dev/null +++ b/build/docs/NodeJSDCPSAPIGuide/source/contacts.rst @@ -0,0 +1 @@ +.. include:: ../../common/contacts.rst diff --git a/build/docs/NodeJSDCPSAPIGuide/source/dds_entities.rst b/build/docs/NodeJSDCPSAPIGuide/source/dds_entities.rst new file mode 100644 index 000000000..d1c636416 --- /dev/null +++ b/build/docs/NodeJSDCPSAPIGuide/source/dds_entities.rst @@ -0,0 +1,622 @@ +.. _`Node.js API for Vortex DDS`: + +########################## +Node.js API for Vortex DDS +########################## + +The Node.js DCPS API provides users with Node.js classes to model DDS communication using JavaScript and pure +DDS applications. + +The Node.js DCPS API consists of one module. + +* vortexdds + +This section provides an overview of the main DDS concepts and Node.js API examples for these DDS concepts. + +.. note:: + + - The Node.js DCPS API documentation can be found in the following directory: + + *$OSPL_HOME/docs/nodejs/html* + + +API Usage Patterns +****************** + +The typical usage pattern for the Node.js DCPS API for Vortex DDS is the following: + +* Model your DDS topics using IDL and generate Node.js topic classes from IDL. +* AND/OR generate Node.js topic classes for topics that already exist in the DDS system. +* Start writing your Node.js program using the Node.js API for Vortex DDS. + +The core classes are ``Participant``, ``Topic``, ``Reader`` and ``Writer``. +``Publisher`` and ``Subscriber`` classes can be used to adjust the Quality of Service (QoS) defaults. + +For details on setting QoS values with the API, see :ref:`QoS Provider`. + +The following list shows the sequence in which you would use the Vortex classes: + +* Create a ``Participant`` instance. +* Create one or more ``Topic`` instances. +* If you require publisher or subscriber level non-default QoS settings, create ``Publisher`` and/or ``Subscriber`` instances. (The most common reason for changing publisher/subscriber QoS is to define non-default partitions.) +* Create ``Reader`` and/or ``Writer`` classes using the ``Topic`` instances that you created. +* If you required data filtering, create ``QueryCondition`` objects. +* Create the core of program, writing and/or reading data and processing it. + + +Participant +*********** + +The Node.js ``Participant`` class represents a DDS domain participant entity. + +In DDS - “A domain participant represents the local membership of the application in a domain. A domain is a distributed concept that links all the applications able to communicate with each other. It represents a communication plane: only the publishers and subscribers attached to the same domain may interact.†+ +Parameters: + +* {number} domainId 0 <= domainId <= 230 (Default: DDSConstants.DDS_DOMAIN_DEFAULT) +* {QoS} qos (Default: undefined) +* {object} listener (Default: undefined) + +The optional parameters have defaults if not specified. If the qos is undefined, the OSPL default QoS is used. + + +**Examples** + +Create a Vortex DDS domain participant. Returns participant or throws a ``DDSError`` if the participant cannot be created. + +Create a domain participant in the default DDS domain (the one specified by the OSPL_URI environment variable). + +.. code-block:: javascript + + const dds = require('vortexdds'); + + // create domain participant + const participant = new dds.Participant(); + +Create a participant on the default domain with a QoS profile. Consider the code snippet below taken from example: GetSetQoSExample/GetSetQoSExample.js file. + +.. code-block:: javascript + + const QOS_PATH = 'DDS_Get_Set_QoS.xml'; + const QOS_PROFILE = 'DDS GetSetQosProfile'; + const DOMAIN_ID = dds.DDS_DOMAIN_DEFAULT; + + async function main(){ + + // create a qos provider using qos xml file + let qp = new dds.QoSProvider(QOS_PATH, QOS_PROFILE); + + // get participant qos from qos provider + let pqos = qp.getParticipantQos(); + let participant = new dds.Participant(DOMAIN_ID, pqos); + + } + +.. _Topic: + +Topic +***** + +The Node.js ``Topic`` class represents a DDS topic type. The DDS topic corresponds to a single data type. In DDS, data is distributed by publishing and subscribing topic data samples. + +Javascript ``Topic`` instances can be created using an IDL file. + +**Step 1 - Generate TypeSupport objects from IDL file** + +The function ``getTopicTypeSupportsForIDL(idlPath)`` is provided to generate a ``TypeSupport`` instance for every topic defined in an IDL file. This function returns a promise, therefore should be called from an async function. + +**Step 2 - Create Topic instance using TypeSupport** + +The ``createTopicFor`` method in the ``Participant`` class can then be used to create a topic instance. + +.. code-block:: javascript + + /** + * Create a Topic on this participant given a TypeSupport object. + * @param {string} topicName + * @param {TypeSupport} typeSupport + * @param {QoS} QoS (default undefined) + * @param {object} listener (default undefined) + * @returns {Topic} topic instance + */ + createTopicFor( + topicName, + typeSupport, + qos = null, + listener = null + ) { + + + + +**Example** + +Create a Vortex DDS topic named 'HelloWorldData_Msg' based on the DDS Topic type ``Msg`` from the ``HelloWorldData.idl`` file. This topic is created using the getTopicTypeSupportsForIDL function, and the ``Participant`` createTopicFor method. + +Consider the code snippet below taken from example: HelloWorld/HelloWorldTopic.js file. + +.. code-block:: javascript + + const dds = require('vortexdds'); + const path = require('path'); + + module.exports.create = async function(participant) { + + const topicName = 'HelloWorldData_Msg'; + const idlName = 'HelloWorldData.idl'; + const idlPath = path.resolve(idlName); + + //wait for dds.getTopicTypeSupportsForIDL to return a Map of typeSupports + let typeSupports = await dds.getTopicTypeSupportsForIDL(idlPath); + + //HelloWorldData.idl contains 1 topic + let typeSupport = typeSupports.get('HelloWorldData::Msg'); + + //create topic qos + let tqos = dds.QoS.topicDefault(); + tqos.durability = dds.DurabilityKind.Transient; + tqos.reliability = dds.ReliabilityKind.Reliable; + + //create topic + return participant.createTopicFor(topicName, typeSupport, tqos); + + }; + + +Publisher +********* + +The Node.js ``Publisher`` class represents a DDS publisher entity. + +In DDS, a publisher is “an object responsible for data distribution. It may publish data of different data types.†+ +Use of the ``Publisher`` class is optional. +In its place, you can use a ``Participant`` instance. +Reasons for explicitly creating a ``Publisher`` instance are: + +* to specify non-default QoS settings, including specifying the DDS *partition* upon which samples are written. +* to control the timing of publisher creation and deletion. + +**Examples** + +Create a DDS Publisher entity. Returns publisher or throws a ``DDSError`` if the publisher cannot be created. + +Create a publisher with participant. + +.. code-block:: javascript + + const dds = require('vortexdds'); + + //create participant + const participant = new dds.Participant(); + + //create publisher + const pub = participant.createPublisher(); + +Create a publisher with a participant and QoS profile. Consider the code snippet below taken from example: GetSetQoSExample/GetSetQoSExample.js file. + +.. code-block:: javascript + + const QOS_PATH = 'DDS_Get_Set_QoS.xml'; + const QOS_PROFILE = 'DDS GetSetQosProfile'; + const DOMAIN_ID = dds.DDS_DOMAIN_DEFAULT; + + async function main(){ + + // create a qos provider using qos xml file + let qp = new dds.QoSProvider(QOS_PATH, QOS_PROFILE); + + // get participant qos from qos provider + let pqos = qp.getParticipantQos(); + let participant = new dds.Participant(DOMAIN_ID, pqos); + + // get publisher qos from qos provider and create a publisher + let pubqos = qp.getPublisherQos(); + let publisher = new dds.Publisher(participant, pubqos); + } + +Writer +****** + +The Node.js ``Writer`` class represents a DDS data writer entity. + +In DDS - “The writer is the object the application must use to communicate to a publisher the existence and value of data-objects of a given type.†+ +A ``Writer`` class is required in order to write data to a DDS domain. +It is attached to a DDS publisher or a DDS domain participant. + +A ``Writer`` class instance references an existing ``Topic`` instance. + +**Examples** + +Create a Vortex DDS domain writer and write data. Returns writer or throws a ``DDSError`` if the writer cannot be created. The example below uses the 'HelloWorldData_Msg' topic from the 'HelloWorldTopic.js' file as shown in :ref:`Topic` example. Consider the code snippet below taken from example: HelloWorld/HelloWorldPublisher.js file. + +.. code-block:: javascript + + const dds = require('vortexdds'); + const HelloWorldTopic = require('./HelloWorldTopic'); + + main(); + + async function main(){ + + //create domain participant + let participant = new dds.Participant(); + + //wait for topic to be created + let topic = await HelloWorldTopic.create(participant); + + //create a publisher with publisher QoS + let pqos = dds.QoS.publisherDefault(); + pqos.partition = 'HelloWorld example'; + let pub = participant.createPublisher(pqos, null); + + //create a writer with writer QoS + let wqos = dds.QoS.writerDefault(); + wqos.durability = dds.DurabilityKind.Transient; + wqos.reliability = dds.ReliabilityKind.Reliable; + let writer = pub.createWriter(topic, wqos, null); + + //write one sample + let msg = {userID: 1, message: 'Hello World'}; + + console.log('=== HelloWorldPublisher'); + console.log('=== [Publisher] writing a message containing :'); + console.log(' userID : ' + msg.userID); + console.log(' Message : ' + msg.message); + + writer.write(msg); + + } + + +Subscriber +********** + +The Node.js ``Subscriber`` class represents a DDS subscriber entity. + +In DDS, a subscriber is “an object responsible for receiving published data and making it available to the receiving application. It may receive and dispatch data of different specified types.†+ +Use of the ``Subscriber`` class is optional. +In its place, you can use a ``Participant`` instance. +Reasons for explicitly creating a ``Subscriber`` instance are: + +* to specify non-default QoS settings, including specifying the DDS *partition* upon which samples are written. +* to control the timing of subscriber creation and deletion. + +**Examples** + + +Create a Vortex DDS domain subscriber. Returns subscriber or throw a ``DDSError`` if the subscriber cannot be created. + + +Create a subscriber with participant. + +.. code-block:: javascript + + const dds = require('vortexdds'); + + //create participant + consr participant = new dds.Participant(); + + //create Subscriber + const sub = participant.createSubscriber(); + +Create a subscriber with participant and QoS profile, where the DDS_DefaultQoS_All.xml file is located in the project directory. + +.. code-block:: javascript + + const QOS_PATH = 'DDS_Get_Set_QoS.xml'; + const QOS_PROFILE = 'DDS GetSetQosProfile'; + const DOMAIN_ID = dds.DDS_DOMAIN_DEFAULT; + + async function main(){ + + // create a qos provider using qos xml file + let qp = new dds.QoSProvider(QOS_PATH, QOS_PROFILE); + + // get participant qos from qos provider + let pqos = qp.getParticipantQos(); + let participant = new dds.Participant(DOMAIN_ID, pqos); + + /* + Get subscriber qos from qos provider and create a subscriber + In the qos xml file provided with this example, there are + two subscriber qos. The subscriber qos with + id 'subscriber1' is chosen below + + NOTE: If there are more than one qos entries in the xml file + for a dds entity, then the entity qos id must be specified. + Otherwise an error will be thrown while trying to get the + respective entity qos from the qos provider + */ + let subqos = qp.getSubscriberQos('subscriber1'); + let subscriber = new dds.Subscriber(participant, subqos); + } + + +Reader +****** + +The Node.js ``Reader`` class represents a DDS data reader entity. + +In DDS - “To access the received data, the application must use a typed reader attached to the subscriber.†+ +A ``Reader`` class is required in order to write data to a DDS domain. +It is attached to a DDS subscriber or a DDS participant. + +A ``Reader`` class instance references an existing ``Topic`` instance. + +**Examples** + +Create a Vortex DDS domain reader with a subscriber and read/take data. Returns reader or throw a ``DDSError`` instance if the reader cannot be created. Consider the code snippet below taken from example: HelloWorld/HelloWorldSubscriber.js file. + +.. code-block:: javascript + + const dds = require('vortexdds'); + const HelloWorldTopic = require('./HelloWorldTopic'); + + main(); + + async function main(){ + + //create domain participant + let participant = new dds.Participant(); + + //wait for topic to be created + let topic = await HelloWorldTopic.create(participant); + + //create subscriber with subscriber QoS + let sqos = dds.QoS.subscriberDefault(); + sqos.partition = 'HelloWorld example'; + let sub = participant.createSubscriber(sqos, null); + + //create reader with reader QoS + let rqos = dds.QoS.readerDefault(); + rqos.durability = dds.DurabilityKind.Transient; + rqos.reliability = dds.ReliabilityKind.Reliable; + let reader = sub.createReader(topic, rqos, null); + + console.log('=== [Subscriber] Ready ...'); + + attemptTake(participant, reader, 0); + + participant.delete(); + } + + /* Attempt to take from the reader every 200 ms. + * If a successful take occurs, we are done. + * If a successful take does not occur after 100 attempts, + * return. + */ + function attemptTake(participant, reader, numberAttempts){ + + setTimeout(function() { + let takeArray = reader.take(1); + if (takeArray.length > 0 && (takeArray[0].info.valid_data === 1)) { + console.log('=== [Subscriber] message received :'); + console.log(' userID : ' + takeArray[0].sample.userID); + console.log(' Message : ' + takeArray[0].sample.message); + } else { + if (numberAttempts < 100){ + return attemptTake(participant, reader, numberAttempts + 1); + } + } + participant.delete(); + return; + }, 200); + } + +Take data with read condition from a data reader. + +.. code-block:: javascript + + const numberOfSamples = 10; + const cond = new dds.ReadCondition(reader, dds.StateMask.any); + let readArray = reader.takeCond(numberOfSamples, cond); + +Read data with read condition from a data reader. + +.. code-block:: javascript + + const numberOfSamples = 10; + const cond = new dds.ReadCondition(reader, dds.StateMask.any); + let readArray = reader.readCond(numberOfSamples, cond); + +WaitSet +******* + +The Node.js ``WaitSet`` class represents a DDS wait set. + +A WaitSet object allows an application to wait until one or more of the attached Condition objects evaluates to true or until the timeout expires. + +**Example** + +Create a ``WaitSet`` with a read condition to wait until publication is matched. Consider the code snippet below taken from example: PingPong/ping.js file. + +.. code-block:: javascript + + const dds = require('vortexdds'); + const PingPongTopic = require('./PingPongTopic'); + + // we iterate for 20 samples + const numSamples = 20; + main(); + + async function main() { + // create our entities + let participant = new dds.Participant(); + let topic = await PingPongTopic.create(participant); + + // create publisher on partition 'Ping' and writer on the publisher + // on pong, we have a subscriber on the same partition and topic + let pqos = dds.QoS.publisherDefault(); + pqos.partition = 'Ping'; + let publisher = participant.createPublisher(pqos, null); + let writer = publisher.createWriter(topic); + + // create a subscriber on partition 'Pong' and a reader on the subscriber + let sqos = dds.QoS.subscriberDefault(); + sqos.partition = 'Pong'; + let subscriber = participant.createSubscriber(sqos); + let reader = subscriber.createReader(topic); + + // create waitset which waits until pong subscriber on partition + // 'Ping' is found + let pubMatchedWaitset = new dds.Waitset(); + let statCond = new dds.StatusCondition(writer); + statCond.enable(dds.StatusMask.publication_matched); + pubMatchedWaitset.attach(statCond, writer); + + // waitset for new data + let newDataWaitset = new dds.Waitset(); + let newDataCond = new dds.ReadCondition(reader, + dds.StateMask.sample.not_read); + newDataWaitset.attach(newDataCond, reader); + + // block until pong has been found + console.log('Waiting for pong subscriber to be found...'); + pubMatchedWaitset.wait(dds.DDSConstants.DDS_INFINITY, function(err, res) { + if (err) throw err; + console.log('Found pong subscriber.'); + // Ping writes the first message + let msg = {userID: 0, message: 'from ping'}; + console.log('sending ' + JSON.stringify(msg)); + writer.write(msg); + onDataAvailable(participant, newDataWaitset, reader, writer, 0); + }); + } + + /* onDataAvailable waits for new data. When we have new data, it + * reads it, prints it, and sends back a message with the userID + * field incremented by one and 'from ping' in the message field. + * It then calls onDataAvailable again. + * We quit when iterLower === numSamples (20 iterations in this example). + */ + function onDataAvailable( + participant, + ws, + reader, + writer, + iterLower + ) { + if (iterLower === numSamples) { + console.log('Done'); + participant.delete(); + return; + } + // when we get a message from pong, read it, then send it back + // with userID+1 and message 'from ping' + ws.wait(dds.DDSConstants.DDS_INFINITY, function(err, res) { + if (err) throw err; + let takeArray = reader.take(1); + if (takeArray.length > 0 && (takeArray[0].info.valid_data === 1)) { + let sample = takeArray[0].sample; + console.log('received: ' + JSON.stringify(sample)); + let msg = {userID: sample.userID + 1, message: 'from ping'}; + console.log('sending ' + JSON.stringify(msg)); + writer.write(msg); + } + onDataAvailable(participant, ws, reader, writer, iterLower + 1); + }); + } + + +QueryCondition +************** + +The Node.js ``QueryCondition`` class represents a DDS query entity. + +A query is a data reader, restricted to accessing data that matches specific status conditions and/or a filter expression. + +A ``QueryCondition`` class instance references an existing ``Reader`` instance. + +**Example** + +Create a ``QueryCondition`` with a state mask and a filter expression for a reader and take data. Consider the code snippet below taken from example: jsshapes/read.js file. + +.. code-block:: javascript + + const dds = require('vortexdds'); + const ShapeTopicHelper = require('./ShapeTopicHelper'); + const util = require('util'); + + // we are reading 100 samples of a blue circle + const shapeName = 'Circle'; + const numSamples = 100; + const mask = dds.StateMask.sample.not_read; + const sqlExpression = 'color=%0'; + const params = ['BLUE']; + + main(); + + async function main() { + const participant = new dds.Participant(); + + // set up our topic + const circleTopic = await ShapeTopicHelper.create(participant, 'Circle'); + + // our reader has volatile qos + let readerqosprovider = new dds.QoSProvider( + './DDS_VolatileQoS_All.xml', + 'DDS VolatileQosProfile' + ); + + // set up circle reader + const circleReader = participant.createReader(circleTopic, + readerqosprovider.getReaderQos()); + + // set up waitset + const newDataWs = new dds.Waitset(); + const queryCond = new dds.QueryCondition( + circleReader, + mask, + sqlExpression, + params, + 1 + ); + // attach the query condition + newDataWs.attach(queryCond, circleReader); + + console.log('Waiting for demo_ishapes to publish a blue circle...'); + onDataAvailable(participant, newDataWs, circleReader, queryCond, 0); + }; + + /* onDataAvailable waits until we have new data (with the query condition). + * when we do, we read it, print the data (shape data), and then call + * onDataAvailable with iterLower incremented by one, to wait for more data. + * This repeats until iterLower === numSamples (100 samples in this case). + * When iterLower === numSamples, we delete the participant and quit. + */ + function onDataAvailable( + participant, + ws, + reader, + queryCond, + iterLower + ) { + if (iterLower === numSamples) { + console.log('Done.'); + participant.delete(); + return; + } + ws.wait(dds.DDSConstants.DDS_INFINITY, function(err, res) { + if (err) throw err; + let sampleArray = reader.takeCond(1, queryCond); + if (sampleArray.length > 0 && (sampleArray[0].info.valid_data === 1)) { + let sample = sampleArray[0].sample; + console.log( + util.format( + '%s %s of size %d at (%d,%d)', + sample.color, + shapeName, + sample.shapesize, + sample.x, + sample.y + ) + ); + } + onDataAvailable(participant, ws, reader, queryCond, iterLower + 1); + }); + } + diff --git a/build/docs/NodeJSDCPSAPIGuide/source/examples.rst b/build/docs/NodeJSDCPSAPIGuide/source/examples.rst new file mode 100644 index 000000000..2c0a34eb3 --- /dev/null +++ b/build/docs/NodeJSDCPSAPIGuide/source/examples.rst @@ -0,0 +1,142 @@ +.. _`Examples`: + +######## +Examples +######## + +Examples are provided to demonstrate the Node.js DCPS features. + +The examples can be found in the following directory: + + *$OSPL_HOME/tools/nodejs/examples* + +WHERE: + + Linux + + OSPL_HOME = *INSTALLDIR/ADLINK/Vortex_v2/Device/VortexOpenSplice/6.9.x/HDE/x86_64.linux* + + Windows + + OSPL_HOME = *INSTALLDIR\\ADLINK\\Vortex_v2\\Device\\VortexOpenSplice\\6.9.x\\HDE\\x86_64.win64* + +Example Files +************* + +Each subfolder consists of a Node.js example project. + +.. _`ExamplesTable`: + +Examples +======== + +.. tabularcolumns:: | p{3.3cm} | p{11cm} | ++-------------------+-----------------------------------------------------+ +| **Example** | **Description** | ++===================+=====================================================+ +| HelloWorld | Demonstrates how to read and write a simple | +| | topic in DDS | +| | | ++-------------------+-----------------------------------------------------+ +| jsshapes | Demonstrates how to read and write to a | +| | DDS application | +| | | ++-------------------+-----------------------------------------------------+ +| IoTData | Demonstrates reading and writing an IoTData topic | +| | | +| | | ++-------------------+-----------------------------------------------------+ +| PingPong | Demonstrates reading, writing, and waitsets | +| | | +| | | ++-------------------+-----------------------------------------------------+ +| QoSExample | Demonstrates QoS settings | +| | | +| | | ++-------------------+-----------------------------------------------------+ +| GetSetQoSExample | Demonstrates getting and setting QoS using | +| | QoS Provider and DCPS api | +| | | ++-------------------+-----------------------------------------------------+ + + +.. raw:: latex + + \newpage + +File Types +========== + +The examples directory contains files of different types. + + +============= ========================================================================================= +**File Type** **Description** +============= ========================================================================================= +js A program file or script written in JavaScript +package.json Lists the packages that a project depends on +xml An XML file that contains one or more Quality of Service (QoS) profiles for DDS entities +idl An interface description language file used to define topic(s) +============= ========================================================================================= + + + +Running Examples +**************** + +To run a Node.js example: + +1. Setup OSPL environment variables + + **Linux** + + - For each example javascript file to be run, open a Linux terminal + + - Navigate to directory containing release.com file (OSPL_HOME) + + */INSTALLDIR/ADLINK/Vortex_v2/Device/VortexOpenSplice/6.9.x/HDE/x86_64.linux* + + - Run release.com (“. release.comâ€) + + + **Windows** + + - For each example javascript file to be run, open a command prompt + + - Navigate to directory containing release.bat file (OSPL_HOME) + + *\\INSTALLDIR\\ADLINK\\Vortex_v2\\Device\\VortexOpenSplice\\6.9.x\\HDE\\x86_64.win64* + + - Run release.bat (“release.batâ€), if OSPL environment variables are not set system wide + +2. Change directory to the example folder + + Example: + + *$OSPL_HOME/tools/nodejs/examples/HelloWorld* + + +3. Run npm install to install the Node.js DCPS API (vortexdds-x.y.z.tgz) and all other dependencies + + npm install + +.. note:: + + If you are running the examples from another directory outside the OSPL install, then you will need to manually install the Node.js DCPS API first and then run npm install for the example dependencies as follows: + + npm install $OSPL_HOME/tools/nodejs/vortexdds-x.y.z.tgz + + npm install + +4. Run .js file(s) in a terminal/command shell + + Example: + + node HelloWorldSubscriber.js + + + + + + + diff --git a/build/docs/NodeJSDCPSAPIGuide/source/images/Vortex-Cover.png b/build/docs/NodeJSDCPSAPIGuide/source/images/Vortex-Cover.png new file mode 100644 index 000000000..d82d6b313 Binary files /dev/null and b/build/docs/NodeJSDCPSAPIGuide/source/images/Vortex-Cover.png differ diff --git a/build/docs/NodeJSDCPSAPIGuide/source/images/Vortex_logo_2014.png b/build/docs/NodeJSDCPSAPIGuide/source/images/Vortex_logo_2014.png new file mode 100644 index 000000000..e7de4f525 Binary files /dev/null and b/build/docs/NodeJSDCPSAPIGuide/source/images/Vortex_logo_2014.png differ diff --git a/build/docs/NodeJSDCPSAPIGuide/source/images/dds_overview.png b/build/docs/NodeJSDCPSAPIGuide/source/images/dds_overview.png new file mode 100755 index 000000000..c7490ddb4 Binary files /dev/null and b/build/docs/NodeJSDCPSAPIGuide/source/images/dds_overview.png differ diff --git a/build/docs/NodeJSDCPSAPIGuide/source/index.rst b/build/docs/NodeJSDCPSAPIGuide/source/index.rst new file mode 100644 index 000000000..0e2a13788 --- /dev/null +++ b/build/docs/NodeJSDCPSAPIGuide/source/index.rst @@ -0,0 +1,27 @@ +.. Node.js DCSP API Guide + +.. Doc Issue 01, 04 April 2018 + +###################### +Node.js DCPS API Guide +###################### + +.. toctree:: + :maxdepth: 6 + :numbered: + + preface + introduction + installation + examples + dds_entities + qos_provider + topic + + contacts + + +Indices and tables +================== + +* :ref:`search` diff --git a/build/docs/NodeJSDCPSAPIGuide/source/installation.rst b/build/docs/NodeJSDCPSAPIGuide/source/installation.rst new file mode 100644 index 000000000..a3a1d3a53 --- /dev/null +++ b/build/docs/NodeJSDCPSAPIGuide/source/installation.rst @@ -0,0 +1,143 @@ +.. _`Installation`: + +############ +Installation +############ + +This section describes the procedure to install the Node.js DCPS API on a Linux or Windows platform. + +Dependencies +************ + +The Node.js DCPS API has several dependencies that must be installed. + +Linux 64-bit +============ + + - Node.js LTS 8.11.1 or later (preferably Node.js LTS 8.x version) + - npm (node package manager) version 5.6.0 or later (typically included with a Node.js install) + - Python 2.7 (v3.x.x is not supported) + - make + - C/C++ compiler toolchain like GCC + + +Windows 64-bit +============== + + - Node.js LTS 8.11.1 or later (preferably Node.js LTS 8.x version) + - npm (node package manager) version 5.6.0 or later (typically included with a Node.js install) + - Python 2.7 (v3.x.x is not supported) + - Visual C++ build tools (VS 2015 or VS 2017) + +Python and Visual C++ build tools install +----------------------------------------- + + + - Install all the required tools and configurations using Microsoft's windows-build-tools by running the following from a command prompt as an administrator: + + npm install - -global - -production windows-build-tools + + (or) + + - Install tools and configuration manually + + - Visual C++ build tools (VS 2015 or VS 2017) + - Python 2.7 (v3.x.x is not supported) + +More detailed information on installing Python and Visual C++ build tools on Windows can be found at: https://github.com/Microsoft/nodejs-guidelines/blob/master/windows-environment.md#compiling-native-addon-modules + + +OpenSplice (OSPL) and Node.js DCPS API Installation +*************************************************** + +Steps: + +1. Install OSPL. Choose an HDE type installer which is a Host Development Environment. This contains all of the services, libraries, header files and tools needed to develop + applications using OpenSplice. The Node.js DCPS API is included in the following installers: + + + .. _`Installers Table`: + .. tabularcolumns:: | p{5cm} | p{5cm} | + +-------------------+----------------------+ + | **Platform** | **Platform Code** | + +===================+======================+ + | Ubuntu1404 64 bit | P704 | + | | | + +-------------------+----------------------+ + | Ubuntu1604 64 bit | P768 | + | | | + +-------------------+----------------------+ + | Windows10 64 bit | P738 | + | | | + +-------------------+----------------------+ + + Example installer: + + P704-VortexOpenSplice-6.9.x-HDE-x86.linux-gcc4.1.2-glibc2.5-installer.run + +2. Setup OSPL license. Copy the license.lic file into the appropriate license directory + + */INSTALLDIR/Vortex_v2/license* + +3. Node.js DCPS API files are contained in a tools/nodejs folder + + Example: + *$OSPL_HOME/tools/nodejs* + +Installing Node.js DCPS API in a Node.js application +**************************************************** + +1. Start a command shell. Setup OSPL environment variables by running release.com or release.bat which can be found in + + **Linux** + + */INSTALLDIR/ADLINK/Vortex_v2/Device/VortexOpenSplice/6.9.x/HDE/x86_64.linux/* + + **Windows** + + *\\INSTALLDIR\\ADLINK\\Vortex_v2\\Device\\VortexOpenSplice\\6.9.x\\HDE\\x86_64.windows\\* + +2. Create a node project folder, if not created + + mkdir + + cd + + npm init + +3. Change directory to node project folder + +4. Install the Node.js DCPS API to your project by executing: + + **Linux** + + npm install $OSPL_HOME/tools/nodejs/vortexdds-x.y.z.tgz + + **Windows** + + npm install %OSPL_HOME%\\tools\\nodejs\\vortexdds-x.y.z.tgz + +Examples and Documentation +************************** + +1. Examples directory: + + *$OSPL_HOME/tools/nodejs/examples* + + +2. Node.js DCPS API documentation directory: + + *$OSPL_HOME/docs/nodejs/html* + + +3. Node.js DCPS User Guide (HTML and PDF) directory: + + *$OSPL_HOME/docs* + + + + + + + + diff --git a/build/docs/NodeJSDCPSAPIGuide/source/introduction.rst b/build/docs/NodeJSDCPSAPIGuide/source/introduction.rst new file mode 100644 index 000000000..f9b44446f --- /dev/null +++ b/build/docs/NodeJSDCPSAPIGuide/source/introduction.rst @@ -0,0 +1,38 @@ +.. _`Introduction`: + + +############ +Introduction +############ + +The Node.js DCPS API provides users with Node.js classes to model DDS communication using JavaScript and pure DDS applications. + +The Node.js DCPS API is a native JavaScript binding that supports DDS functionality. The language binding consists of Node.js classes and wrapper implementations of the C99 API (C API for DDS). It makes use of ECMAScript 2015 (ES6) JavaScript language features and leverages ease of use by providing a higher level of abstraction. + +Please see :ref:`Limitations` for limitations of Node.js DDS API support. + +.. raw:: latex + + \newpage + +DDS +*** + +**What is DDS?** + +“The Data Distribution Service (DDSâ„¢) is a middleware protocol and API standard for data-centric connectivity from the Object Management Group® (OMG®). It integrates the components of a system together, providing low-latency data connectivity, extreme reliability, and a scalable architecture that business and mission-critical Internet of Things (IoT) applications need.†+ +“The main goal of DDS is to share the right data at the right place at the right time, even between time-decoupled publishers and consumers. DDS implements global data space by carefully replicating relevant portions of the logically shared dataspace.†DDS specification + +.. figure:: images/dds_overview.png + :alt: DDS + +**Further Documentation** + +http://portals.omg.org/dds/ + +http://ist.adlinktech.com/ + + + + diff --git a/build/docs/NodeJSDCPSAPIGuide/source/preface.rst b/build/docs/NodeJSDCPSAPIGuide/source/preface.rst new file mode 100644 index 000000000..0e8e8140b --- /dev/null +++ b/build/docs/NodeJSDCPSAPIGuide/source/preface.rst @@ -0,0 +1,31 @@ +.. _`Preface`: + +####### +Preface +####### + +About the Node.js DCPS API Guide +******************************** + +The Node.js DCPS API Guide is a starting point for anyone using, developing or running Node.js applications with Vortex OpenSplice. + +This guide contains: + + - Node.js DCSP API setup instructions + - location of Node.js DCPS API dds module documentation + - overview of general DDS concepts and Node.js API for Vortex DDS + - a listing of examples, and how to run them + - detailed information on how to specify DDS entity Quality of Service (QoS) + - how to register DDS topics + +This reference guide is based on the OMG’s Data Distribution Service Specification. + +Please note that this guide is not intended to provide a detailed explanation of the aforementioned OMG specifications or the Vortex OpenSplice product. It provides an introduction to the essential concepts and enables users to begin using the Node.js DCPS API as quickly as possible. + +Intended Audience +***************** + +The Node.js Reference Guide is intended to be used by JavaScript programmers who are +using Vortex OpenSplice to develop Node.js applications. + + diff --git a/build/docs/NodeJSDCPSAPIGuide/source/qos_provider.rst b/build/docs/NodeJSDCPSAPIGuide/source/qos_provider.rst new file mode 100644 index 000000000..f3306a686 --- /dev/null +++ b/build/docs/NodeJSDCPSAPIGuide/source/qos_provider.rst @@ -0,0 +1,516 @@ +.. _`QoS Provider`: + + +######################## +Quality of Service (QoS) +######################## + +The following section explains how to set the Quality of Service (QoS) for a DDS entity. + +Users have two options available to set the QoS for an entity or entities. They can define the QoS settings using an XML file, or they can use the Node.js DCPS APIs. Both of these options are explained. + +If a QoS setting for an entity is not set using an xml file or the Node.js DCPS APIs, the defaults will be used. This allows a user the ability to override only those settings that require non-default values. + +The code snippets referenced are taken from the runnable examples. + +.. note:: + + - The :ref:`Examples` section provides the examples directory location, example descriptions and running instructions. + + +Setting QoS Using QoS Provider XML File +*************************************** + +QoS for DDS entities can be set using XML files based on the XML schema file QoSProfile.xsd_. +These XML files contain one or more QoS profiles for DDS entities. OSPL includes an XSD (XML schema), that is located in $OSPL_HOME/etc/DDS_QoSProfile.xml. This can be used with XML schema core editors to help create valid XML files. + +Sample QoS Profile XML files can be found in the examples directory. Typically you will place the qos files in a subdirectory of your Node.js application. + +.. _QoSProfile: + +QoS Profile +=========== + +A QoS profile consists of a name and optionally a base_name attribute. The base_name attribute allows a +QoS or a profile to inherit values from another QoS or profile in the same file. The file contains QoS +elements for one or more DDS entities. + +A skeleton file without any QoS values is displayed below to show the structure of the file. + +.. code-block:: xml + + + + + + + + + + + + + +**Example: Persistent QoS XML file** + +The example below specifies the persistent QoS XML file which is used by the QoSProvider. + +.. code-block:: xml + + + + + + + + + + true + + + + + INSTANCE_PRESENTATION_QOS + true + true + + + partition1 + + + + + + true + + + + + INSTANCE_PRESENTATION_QOS + false + false + + + + + + + + + true + + + + + INSTANCE_PRESENTATION_QOS + true + true + + + partition1 + + + + + + true + + + + + PERSISTENT_DURABILITY_QOS + + + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + + 0 + 0 + + + + AUTOMATIC_LIVELINESS_QOS + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + RELIABLE_RELIABILITY_QOS + + 0 + 100000000 + + + + BY_RECEPTION_TIMESTAMP_DESTINATIONORDER_QOS + + + KEEP_LAST_HISTORY_QOS + 100 + + + LENGTH_UNLIMITED + LENGTH_UNLIMITED + LENGTH_UNLIMITED + + + 0 + + + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + + + + SHARED_OWNERSHIP_QOS + + + 0 + + + true + + + + + PERSISTENT_DURABILITY_QOS + + + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + + 0 + 0 + + + + AUTOMATIC_LIVELINESS_QOS + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + BEST_EFFORT_RELIABILITY_QOS + + 0 + 100000000 + + + + BY_RECEPTION_TIMESTAMP_DESTINATIONORDER_QOS + + + KEEP_ALL_HISTORY_QOS + + + LENGTH_UNLIMITED + LENGTH_UNLIMITED + LENGTH_UNLIMITED + + + + + + SHARED_OWNERSHIP_QOS + + + + 0 + 0 + + + + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + + + + + + PERSISTENT_DURABILITY_QOS + + + + 3600 + 0 + + KEEP_LAST_HISTORY_QOS + 100 + 8192 + 4196 + 8192 + + + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + + 0 + 0 + + + + AUTOMATIC_LIVELINESS_QOS + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + BEST_EFFORT_RELIABILITY_QOS + + 0 + 100000000 + + + + BY_RECEPTION_TIMESTAMP_DESTINATIONORDER_QOS + + + KEEP_LAST_HISTORY_QOS + 1 + + + LENGTH_UNLIMITED + LENGTH_UNLIMITED + LENGTH_UNLIMITED + + + 0 + + + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + SHARED_OWNERSHIP_QOS + + + + + +Applying QoS Profile +==================== + +To set the QoS profile for a DDS entity using the Node.js DCPS API and an XML file, the user specifies the qos file URI or file path and the QoS profile name as parameters. + +**Example** + +Create a QoS provider and get the respective entity QoS. The example below uses the QoS XML file referred in :ref:`QoSProfile`. For a detailed example refer to 'GetSetQoSExample.js' file referred in :ref:`GetSetQoSExample` example. + +.. code-block:: javascript + + const dds = require('vortexdds'); + const HelloWorldTopic = require('./HelloWorldTopic.js'); + + /** + * Path of the qos xml file + * The DDS_PersistentQoS.xml file is used for this example + * It is located in the same directory of this example + * */ + const QOS_PATH = 'DDS_PersistentQoS.xml'; + const QOS_PROFILE = 'DDS PersistentQosProfile'; + const DOMAIN_ID = dds.DDS_DOMAIN_DEFAULT; + + main(); + + async function main(){ + + /** + * Set QoS using QoS XML file + */ + + // create a qos provider using qos xml file + let qp = new dds.QoSProvider(QOS_PATH, QOS_PROFILE); + + // get participant qos from qos provider and create a participant + let pqos = qp.getParticipantQos(); + let participant = new dds.Participant(DOMAIN_ID, pqos); + + // get publisher qos from qos provider and create a publisher + let pubqos = qp.getPublisherQos(); + let publisher = new dds.Publisher(participant, pubqos); + + let subqos = qp.getSubscriberQos('subscriber1'); + let subscriber = new dds.Subscriber(participant, subqos); + + // get topic qos from qos provider and create a topic + let tqos = qp.getTopicQos(); + let topic = await HelloWorldTopic.create(participant, tqos); + + // get reader qos from qos provider and create a reader + let rqos = qp.getReaderQos(); + let reader = new dds.Reader(subscriber, topic, rqos); + + // get writer qos from qos provider and create a writer + let wqos = qp.getWriterQos(); + let writer = new dds.Writer(publisher, topic, wqos); + + // delete the participant + participant.delete(); + } + +Setting QoS Using Node.js DCPS API Classes +****************************************** + +QoS settings can also be set by using the Node.js classes alone. (No XML files required.) + +**Example** + +Below is a code snippet similar to the 'GetSetQoSExample/GetSetQoSExample.js' file. It demonstrates how to specify the QoS settings for a topic, writer and reader using the Node.js DCPS APIs. + +.. code-block:: javascript + + const dds = require('vortexdds'); + const HelloWorldTopic = require('./HelloWorldTopic.js'); + + main(); + + async function main(){ + + let participant = new dds.Participant(); + + // get the default topic qos + let tqos = dds.QoS.topicDefault(); + + // modify the topic qos policies + + // All of the policy variables can be set + tqos.durabilityService = { + serviceCleanupDelay: 5000, + historyKind: dds.HistoryKind.KeepLast, + historyDepth: 10, + maxSamples: 10, + maxInstances: 5, + maxSamplesPerInstance: -1, + }; + + // Or a subset of the policy variables can be set + tqos.durabilityService = { + historyKind: dds.HistoryKind.KeepLast, + }; + + tqos.reliability = dds.ReliabilityKind.reliable; + tqos.durability = dds.DurabilityKind.Volatile; + tqos.topicdata = 'Hello world topic'; + tqos.userdata = 'connected to hello world'; + tqos.groupdata = 'hello world group'; + tqos.history = { + kind: dds.HistoryKind.KeepLast, + depth: 10, + }; + tqos.resourceLimits = { + maxSamples: 10, + maxInstances: 5, + }; + tqos.lifespan = 5000; + tqos.deadline = 3000; + tqos.latencyBudget = 4000; + tqos.ownership = dds.OwnershipKind.Exclusive; + tqos.liveliness = { + kind: dds.LivelinessKind.ManualByTopic, + leaseDuration: 10, + }; + tqos.reliability = { + kind: dds.ReliabilityKind.Reliable, + maxBlockingTime: 100, + }; + tqos.transportPriority = 5; + tqos.destinationOrder = dds.DestinationOrderKind.BySourceTimestamp; + + // create topic with qos + let topic = await HelloWorldTopic.create(participant, tqos); + + // get topic qos policies + console.log('\n', '** Topic QoS **'); + console.log('Reliability: ', tqos.reliability); + console.log('Durability: ', tqos.durability); + console.log('Topic data: ', tqos.topicdata); + console.log('User data: ', tqos.userdata); + console.log('Group data: ', tqos.groupdata); + console.log('History: ', tqos.history); + console.log('Resource Limits: ', tqos.resourceLimits); + console.log('Lifespan: ', tqos.lifespan); + console.log('Deadline: ', tqos.deadline); + console.log('Latency Budget: ', tqos.latencyBudget); + console.log('Ownership: ', tqos.ownership); + console.log('Liveliness: ', tqos.liveliness); + console.log('Transport Priority: ', tqos.transportPriority); + console.log('Destination Order: ', tqos.destinationOrder); + console.log('Durability Service: ', tqos.durabilityService); + + // get the default writer qos + let wqos = dds.QoS.writerDefault(); + + // modify the writer qos policies + wqos.writerDataLifecycle = false; + + // create a writer with qos + let writer = new dds.Writer(publisher, topic, wqos); + + // get writer qos policies + console.log('\n', '** Writer QoS **'); + console.log('Writer data lifecyle: ', wqos.writerDataLifecycle); + + // get the default reader qos + let rqos = dds.QoS.readerDefault(); + + // modify the reader qos policies + rqos.partition = 'partition1'; + rqos.timebasedFilter = 60000; + rqos.readerDataLifecycle = { + autopurgeNoWriterSamples: 100, + autopurgeDisposedSamplesDelay: 500, + }; + + // create a reader with qos + let reader = new dds.Reader(subscriber, topic, rqos); + + // get reader qos policies + console.log('\n', '** Reader QoS **'); + console.log('Partition: ', rqos.partition); + console.log('Time based filter: ', rqos.timebasedFilter); + console.log('Reader data lifecycle: ', rqos.readerDataLifecycle); + + // delete the participant + participant.delete(); + + // NOTE: Actual reading and writing data is not demonstrated in this example + } + + + +.. external links +.. _QoSProfile.xsd: http://www.omg.org/spec/dds4ccm/20110201/DDS_QoSProfile.xsd +.. _DDS_DefaultQoS.xml: http://www.omg.org/spec/dds4ccm/20110201/DDS_DefaultQoS.xml diff --git a/build/docs/NodeJSDCPSAPIGuide/source/topic.rst b/build/docs/NodeJSDCPSAPIGuide/source/topic.rst new file mode 100644 index 000000000..e23cc866e --- /dev/null +++ b/build/docs/NodeJSDCPSAPIGuide/source/topic.rst @@ -0,0 +1,153 @@ +.. _`Topic Generation and Discovery`: + +############################## +Topic Generation and Discovery +############################## + +A DDS Topic represents the unit for information that can be produced or consumed by a DDS application. Topics are defined by a name, a type, and a set of QoS policies. + +The Node.js DCPS API provides several ways of generating Node.js classes to represent DDS topics. + + - over the wire discovery + - dynamic generation of Node.js classes using parameters IDL file and topic name + +.. note:: + + - The :ref:`Examples` section provides the examples directory location, example descriptions and running instructions. + + +Over the Wire Discovery +************************ + +Node.js topic classes can be generated for existing DDS topics in the DDS system. These topics are "discovered over the wire". + +The Node.js classes are generated when the topic is requested by name. + +A code snippet is provided from findTopicExample.js. This example finds a topic registered by another process, and writes a sample to that topic. + +**Example** + +.. code-block:: javascript + + ... + const dds = require('vortexdds'); + + console.log('Connecting to DDS domain...'); + const participant = new dds.Participant(); + + console.log('Finding topic...'); + let topic = participant.findTopic('HelloWorldData_Msg'); + + console.log('Creating writer and sample data to write...'); + let writer = participant.createWriter(topic); + let sample = { userID: 4, message: 7 }; + + console.log('Writing sample data...'); + let status = writer.write(sample); + ... + + +Dynamic Generation of Node.js Topic Classes Using IDL and Name +************************************************************** + +The Node.js DCPS API supports generation of Node.js topic classes from IDL. This section describes the details of the IDL-Node.js binding. + +Dynamic Generation +================== + +The Node.js DCPS API provides an asynchronous function that returns a Map of ``TypeSupport`` objects. + +A ``TypeSupport`` object includes the topic typename, keys and descriptor. + +The structure type representation of a topic is created by the TypeSupport object. However, the usage +of the structure type is internal to the Node.js DCPS API. + +In order to create a topic, a topic name and a ``TypeSupport`` are passed into the ``Participant`` createTopicFor function. (qos and listener parameters are optional) + +The code snippet below is taken from the 'IoTTopicHelper.js' file referred in :ref:`IoTData` example. + +.. code-block:: javascript + + const dds = require('vortexdds'); + const path = require('path'); + + //asynchronous function to create the topic + module.exports.create = async function(participant) { + + const topicName = 'IoTData'; + const idlName = 'dds_IoTData.idl'; + const idlPath = path.resolve(idlName); + + //wait for dds.getTopicTypeSupportsForIDL to return a map of typeSupports + let typeSupports = await dds.getTopicTypeSupportsForIDL(idlPath); + + //idl contains 1 topic. + let typeSupport = typeSupports.get('DDS::IoT::IoTData'); + + return participant.createTopicFor(topicName, typeSupport); + }; + +Generated Artifacts +=================== + +The following table defines the Node.js artifacts generated from IDL concepts: + +=========== ====================================== +IDL Concept Node.js Concept +=========== ====================================== +module N/A +enum enum from npm 'enum' package +enum value enum value +struct object +field object property +union object (IoTValue from dds_IoTData.idl + is the only supported union) +=========== ====================================== + +**Datatype mappings** + +The following table shows the Node.js equivalents to IDL primitive types: + +=========== ============== +IDL Type Node.js Type +=========== ============== +boolean Boolean +char Number +octet Number +short Number +ushort Number +long Number +ulong Number +long long Number +ulong long Number +float Number +double Number +string String +wchar Unsupported +wstring Unsupported +any Unsupported +long double Unsupported +=========== ============== + + +**Implementing Arrays and Sequences in Node.js** + +Both IDL arrays and IDL sequences are mapped to JavaScript arrays. + + +.. _Limitations: + +Limitations of Node.js Support +****************************** + +The Node.js binding has the following limitations: + + - Listeners are not supported + + - Only the IoTValue union from dds_IoTData.idl is supported in the beta + + - JavaScript does not currently include standard support for 64-bit integer values. 64-bit integers with more than 53 bits of data are represented by String values to avoid loss of precision. If the value will fit inside a JavaScript Number without losing precision, a Number can be used, otherwise use a String. (Refer to :ref:`IoTData` example which demonstrates the usage and ranges for the unsigned and signed 64 bit integers within nodejs.) + + + + diff --git a/build/docs/NodeMonitorGuide/source/conf.py b/build/docs/NodeMonitorGuide/source/conf.py index 03cb5132e..c94ca298c 100644 --- a/build/docs/NodeMonitorGuide/source/conf.py +++ b/build/docs/NodeMonitorGuide/source/conf.py @@ -65,9 +65,8 @@ # General information about the project. project = u'OpenSplice Node Monitor User Guide' -#copyright = u'2015, PrismTech' this_year = time.strftime( '%Y' ) -copyright = u'{y}, PrismTech'.format( y = this_year ) +copyright = u'{y}, ADLINK Technology Limited'.format( y = this_year ) print 'Copyright string is:', copyright # The version info for the project you're documenting, acts as replacement for @@ -239,7 +238,7 @@ # Added 'True' to end of generated line to suppress 'Index & Tables' -# A dictionary that contains LaTeX snippets that override those Sphinx usually +# A dictionary that contains LaTeX snippets that override those Sphinx usually # puts into the generated .tex files. latex_elements = { 'babel': '\\usepackage[english]{babel}' } @@ -286,7 +285,7 @@ # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). -man_pages = [('index', 'OpenSplice_NodeMonitor_Guide', u'OpenSplice_NodeMonitor_Guide', [u'PrismTech'], 1)] +man_pages = [('index', 'OpenSplice_NodeMonitor_Guide', u'OpenSplice_NodeMonitor_Guide', [u'ADLINK Technology Limited'], 1)] # * NOT TESTED diff --git a/build/docs/NodeMonitorGuide/source/contacts.rst b/build/docs/NodeMonitorGuide/source/contacts.rst index b437fd808..d32f6016f 100644 --- a/build/docs/NodeMonitorGuide/source/contacts.rst +++ b/build/docs/NodeMonitorGuide/source/contacts.rst @@ -1,49 +1 @@ -.. _`Contacts & Notices`: - -################## -Contacts & Notices -################## - -******** -Contacts -******** - -| **PrismTech Corporation** -| 400 TradeCenter -| Suite 5900 -| Woburn, MA -| 01801 -| USA -| Tel: +1 781 569 5819 - -| **PrismTech Limited** -| PrismTech House -| 5th Avenue Business Park -| Gateshead -| NE11 0NG -| UK -| Tel: +44 (0)191 497 9900 - -| **PrismTech France** -| 28 rue Jean Rostand -| 91400 Orsay -| France -| Tel: +33 (1) 69 015354 - - -Web: http://www.prismtech.com - -E-mail: \info@prismtech.com - -******* -Notices -******* - -**Copyright** © 2016 PrismTech Limited. - -The information contained in this document is subject to change without notice and is -made available in good faith without liability on the part of PrismTech Limited or -PrismTech Corporation. - -All trademarks acknowledged. - +.. include:: ../../common/contacts.rst diff --git a/build/docs/NodeMonitorGuide/source/images/Vortex-OpenSplice-Cover.png b/build/docs/NodeMonitorGuide/source/images/Vortex-OpenSplice-Cover.png old mode 100644 new mode 100755 index ce86c6d94..801c02bb8 Binary files a/build/docs/NodeMonitorGuide/source/images/Vortex-OpenSplice-Cover.png and b/build/docs/NodeMonitorGuide/source/images/Vortex-OpenSplice-Cover.png differ diff --git a/build/docs/NodeMonitorGuide/source/index.rst b/build/docs/NodeMonitorGuide/source/index.rst index 07aaf6f48..e1777a25c 100644 --- a/build/docs/NodeMonitorGuide/source/index.rst +++ b/build/docs/NodeMonitorGuide/source/index.rst @@ -9,7 +9,7 @@ OpenSplice NodeMonitor User Guide .. toctree:: :maxdepth: 2 :numbered: - + preface introduction startstop @@ -17,8 +17,8 @@ OpenSplice NodeMonitor User Guide dataavailable biblio - contacts - + contacts + Indices and tables ================== diff --git a/build/docs/NodeMonitorGuide/source/preface.rst b/build/docs/NodeMonitorGuide/source/preface.rst index 71d6892d5..c0b496068 100644 --- a/build/docs/NodeMonitorGuide/source/preface.rst +++ b/build/docs/NodeMonitorGuide/source/preface.rst @@ -32,7 +32,7 @@ statistics about the performance of a system. Conventions *********** -The icons shown below are used in PrismTech product documentation +The icons shown below are used in the Vortex product documentation to help readers to quickly identify information relevant to their specific use of OpenSplice. @@ -73,4 +73,4 @@ specific use of OpenSplice. .. |java| image:: ./images/icon-java.* :height: 6mm - \ No newline at end of file + diff --git a/build/docs/PythonDCPSAPIGuide/Makefile b/build/docs/PythonDCPSAPIGuide/Makefile new file mode 100644 index 000000000..fe415b065 --- /dev/null +++ b/build/docs/PythonDCPSAPIGuide/Makefile @@ -0,0 +1,130 @@ +# Makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = sphinx-build +PAPER = +BUILDDIR = build + +# Internal variables. +PAPEROPT_a4 = -D latex_paper_size=a4 +PAPEROPT_letter = -D latex_paper_size=letter +ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source + +.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest + +help: + @echo "Please use \`make ' where is one of" + @echo " html to make standalone HTML files" + @echo " dirhtml to make HTML files named index.html in directories" + @echo " singlehtml to make a single large HTML file" + @echo " pickle to make pickle files" + @echo " json to make JSON files" + @echo " htmlhelp to make HTML files and a HTML help project" + @echo " qthelp to make HTML files and a qthelp project" + @echo " devhelp to make HTML files and a Devhelp project" + @echo " epub to make an epub" + @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" + @echo " latexpdf to make LaTeX files and run them through pdflatex" + @echo " text to make text files" + @echo " man to make manual pages" + @echo " changes to make an overview of all changed/added/deprecated items" + @echo " linkcheck to check all external links for integrity" + @echo " doctest to run all doctests embedded in the documentation (if enabled)" + +clean: + -rm -rf $(BUILDDIR)/* + +html: + $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." + +dirhtml: + $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." + +singlehtml: + $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml + @echo + @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." + +pickle: + $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle + @echo + @echo "Build finished; now you can process the pickle files." + +json: + $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json + @echo + @echo "Build finished; now you can process the JSON files." + +htmlhelp: + $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp + @echo + @echo "Build finished; now you can run HTML Help Workshop with the" \ + ".hhp project file in $(BUILDDIR)/htmlhelp." + +qthelp: + $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp + @echo + @echo "Build finished; now you can run "qcollectiongenerator" with the" \ + ".qhcp project file in $(BUILDDIR)/qthelp, like this:" + @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/OpenSplice_Getting_Started_Guide.qhcp" + @echo "To view the help file:" + @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/OpenSplice_Getting_Started_Guide.qhc" + +devhelp: + $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp + @echo + @echo "Build finished." + @echo "To view the help file:" + @echo "# mkdir -p $$HOME/.local/share/devhelp/OpenSplice_Getting_Started_Guide" + @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/OpenSplice_Getting_Started_Guide" + @echo "# devhelp" + +epub: + $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub + @echo + @echo "Build finished. The epub file is in $(BUILDDIR)/epub." + +latex: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo + @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." + @echo "Run \`make' in that directory to run these through (pdf)latex" \ + "(use \`make latexpdf' here to do that automatically)." + +latexpdf: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo "Running LaTeX files through latexpdf..." + make -C $(BUILDDIR)/latex all-pdf + @echo "latexpdf finished; the PDF files are in $(BUILDDIR)/latexpdf." + +text: + $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text + @echo + @echo "Build finished. The text files are in $(BUILDDIR)/text." + +man: + $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man + @echo + @echo "Build finished. The manual pages are in $(BUILDDIR)/man." + +changes: + $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes + @echo + @echo "The overview file is in $(BUILDDIR)/changes." + +linkcheck: + $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck + @echo + @echo "Link check complete; look for any errors in the above output " \ + "or in $(BUILDDIR)/linkcheck/output.txt." + +doctest: + $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest + @echo "Testing of doctests in the sources finished, look at the " \ + "results in $(BUILDDIR)/doctest/output.txt." diff --git a/build/docs/PythonDCPSAPIGuide/make.bat b/build/docs/PythonDCPSAPIGuide/make.bat new file mode 100644 index 000000000..fff4f8663 --- /dev/null +++ b/build/docs/PythonDCPSAPIGuide/make.bat @@ -0,0 +1,183 @@ +@ECHO OFF + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set BUILDDIR=build +set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% source +if NOT "%PAPER%" == "" ( + set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS% +) + +if "%1" == "" goto help + +if "%1" == "help" ( + :help + echo.Please use `make ^` where ^ is one of + echo. html to make standalone HTML files + echo. dirhtml to make HTML files named index.html in directories + echo. singlehtml to make a single large HTML file + echo. pickle to make pickle files + echo. json to make JSON files + echo. htmlhelp to make HTML files and a HTML help project + echo. qthelp to make HTML files and a qthelp project + echo. devhelp to make HTML files and a Devhelp project + echo. epub to make an epub + echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter + echo. text to make text files + echo. man to make manual pages + echo. changes to make an overview over all changed/added/deprecated items + echo. linkcheck to check all external links for integrity + echo. doctest to run all doctests embedded in the documentation if enabled + goto end +) + +if "%1" == "clean" ( + for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i + del /q /s %BUILDDIR%\* + goto end +) + +if "%1" == "html" ( + %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The HTML pages are in %BUILDDIR%/html. + goto end +) + +if "%1" == "dirhtml" ( + %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml. + goto end +) + +if "%1" == "singlehtml" ( + %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml. + goto end +) + +if "%1" == "pickle" ( + %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can process the pickle files. + goto end +) + +if "%1" == "json" ( + %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can process the JSON files. + goto end +) + +if "%1" == "htmlhelp" ( + %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can run HTML Help Workshop with the ^ +.hhp project file in %BUILDDIR%/htmlhelp. + goto end +) + +if "%1" == "qthelp" ( + %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can run "qcollectiongenerator" with the ^ +.qhcp project file in %BUILDDIR%/qthelp, like this: + echo.^> qcollectiongenerator %BUILDDIR%\qthelp\OpenSplice_Getting_Started_Guide.qhcp + echo.To view the help file: + echo.^> assistant -collectionFile %BUILDDIR%\qthelp\OpenSplice_Getting_Started_Guide.ghc + goto end +) + +if "%1" == "devhelp" ( + %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. + goto end +) + +if "%1" == "epub" ( + %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The epub file is in %BUILDDIR%/epub. + goto end +) + +if "%1" == "latex" ( + %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; the LaTeX files are in %BUILDDIR%/latex. + goto end +) + +if "%1" == "latexpdf" ( + %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latexpdf + echo %BUILDDIR%/latexpdf +REM Typical path: "c:\Program Files (x86)\GnuWin32\bin\make.exe" -C %BUILDDIR%\latexpdf all-pdf +REM Actual path on this system: C:\apps\GnuWin32\bin\make.exe -C %BUILDDIR%\latexpdf all-pdf + C:\apps\GnuWin32\bin\make.exe -C %BUILDDIR%\latexpdf all-pdf + echo.Build done + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; the LaTeX files are in %BUILDDIR%/latexpdf. + goto end +) + +if "%1" == "text" ( + %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The text files are in %BUILDDIR%/text. + goto end +) + +if "%1" == "man" ( + %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The manual pages are in %BUILDDIR%/man. + goto end +) + +if "%1" == "changes" ( + %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes + if errorlevel 1 exit /b 1 + echo. + echo.The overview file is in %BUILDDIR%/changes. + goto end +) + +if "%1" == "linkcheck" ( + %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck + if errorlevel 1 exit /b 1 + echo. + echo.Link check complete; look for any errors in the above output ^ +or in %BUILDDIR%/linkcheck/output.txt. + goto end +) + +if "%1" == "doctest" ( + %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest + if errorlevel 1 exit /b 1 + echo. + echo.Testing of doctests in the sources finished, look at the ^ +results in %BUILDDIR%/doctest/output.txt. + goto end +) + +:end diff --git a/build/docs/PythonDCPSAPIGuide/source/conf.py b/build/docs/PythonDCPSAPIGuide/source/conf.py new file mode 100644 index 000000000..172310882 --- /dev/null +++ b/build/docs/PythonDCPSAPIGuide/source/conf.py @@ -0,0 +1,282 @@ +# -*- coding: utf-8 -*- +# +# PythonDCPSAPIGuide build configuration file, created by +# ReST Editor on 28-Nov-2017 +# +# This file is execfile()d with the current directory set to its containing dir. +# +# Note that not all possible configuration values are present in this +# autogenerated file. +# +# All configuration values have a default; values that are commented out +# serve to show the default. + +import sys, os +import time + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +#sys.path.insert(0, os.path.abspath('.')) + +# -- General configuration ----------------------------------------------------- + +# If your documentation needs a minimal Sphinx version, state it here. +#needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be extensions +# coming with Sphinx (named 'sphinx.ext.*') or your custom ones. +#extensions = ['sphinx.ext.todo'] + +extensions = ['sphinx.ext.todo', 'sphinx.ext.ifconfig'] + +def setup(app): + app.add_config_value('rmi_languages', '', True) + +#rmi_languages = 'C++ and Java' +rmi_languages = 'Python' +#rmi_languages = 'Java' +rst_prolog = """ +.. |rmi_langs| replace:: Python +.. |product_name| replace:: OpenSplice +""" + +#.. |rmi_langs| replace:: C++ and Java + + + +# Add any paths that contain templates here, relative to this directory. +templates_path = [u'_templates'] + + +# The suffix of source filenames. +source_suffix = '.rst' + +# The encoding of source files. +source_encoding = u'utf-8-sig' + + +# The master toctree document. +master_doc = u'index' + + +# General information about the project. +project = u'Python DCPS API Guide' + +this_year = time.strftime( '%Y' ) +copyright = u'{y}, ADLINK Technology Limited'.format( y = this_year ) +print 'Copyright string is:', copyright + + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# +# The short X.Y version. +version = u'6.x' + +# The full version, including alpha/beta/rc tags. +release = version +#release = u'.0' +print 'Short version string is:', version +print 'Full version string is:', release + + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +language = u'en' + + +# There are two options for replacing |today|: either, you set today to some +# non-false value, then it is used: +today = ' ' +# Else, today_fmt is used as the format for a strftime call. +#today_fmt = '%B %d, %Y' + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +exclude_patterns = [] + +# The reST default role (used for this markup: `text`) to use for all documents. +#default_role = None + +# If true, '()' will be appended to :func: etc. cross-reference text. +#add_function_parentheses = True + +# If true, the current module name will be prepended to all description +# unit titles (such as .. function::). +#add_module_names = True + +# If true, sectionauthor and moduleauthor directives will be shown in the +# output. They are ignored by default. +#show_authors = False + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + +# A list of ignored prefixes for module index sorting. +#modindex_common_prefix = [] + + +# -- Options for HTML output --------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# html_theme = u'sphinxdoc' +html_theme = u'vortextheme' +# LINUX PATH: +html_theme_path = ['../../.'] +# WINDOWS PATH: +# html_theme_path = ['..\..\.'] +#build theme directory in lite using environment variable, so shared amongst books +# insight team can delete, +#html_theme_path = [os.environ['VL_HOME'] + '/build/docs'] + + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +#html_theme_options = {} + +# Add any paths that contain custom themes here, relative to this directory. +#html_theme_path = [] + +# The name for this set of Sphinx documents. If None, it defaults to +# " v documentation". +#html_title = None +html_title = 'Python DCPS API Guide' + +# A shorter title for the navigation bar. Default is the same as html_title. +#html_short_title = None +#html_short_title = 'HTML short Title conf.py' +html_short_title = 'Python DCPS API Guide' + +# The name of an image file (relative to this directory) to place at the top +# of the sidebar. +html_logo = './images/Vortex_logo_2014.png' + +# The name of an image file (within the static path) to use as favicon of the +# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 +# pixels large. +#html_favicon = None + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = [u'_static'] + + +# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, +# using the given strftime format. +#html_last_updated_fmt = '%b %d, %Y' + +# If true, SmartyPants will be used to convert quotes and dashes to +# typographically correct entities. +#html_use_smartypants = True + +# Custom sidebar templates, maps document names to template names. +#html_sidebars = {} + +# Additional templates that should be rendered to pages, maps page names to +# template names. +#html_additional_pages = {} + +# If false, no module index is generated. +#html_domain_indices = True + +# If false, no index is generated. +#html_use_index = True + +# If true, the index is split into individual pages for each letter. +#html_split_index = False + +# If true, links to the reST sources are added to the pages. +#html_show_sourcelink = True + +# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. +#html_show_sphinx = True +html_show_sphinx = False + +# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. +#html_show_copyright = True + +# If true, an OpenSearch description file will be output, and all pages will +# contain a tag referring to it. The value of this option must be the +# base URL from which the finished HTML is served. +#html_use_opensearch = '' + +# This is the file name suffix for HTML files (e.g. ".xhtml"). +#html_file_suffix = None + +# Output file base name for HTML help builder. +htmlhelp_basename = 'Python DCPS API Guide' + + +# -- Options for LaTeX output -------------------------------------------------- + +# The paper size ('letter' or 'a4'). +latex_paper_size = u'a4' + + +# The font size ('10pt', '11pt' or '12pt'). +latex_font_size = u'10pt' + + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, author, documentclass [howto/manual]). +latex_documents = [('index', 'OpenSplice_PythonDCPSAPIGuide.tex', u'Python DCPS API Guide', u'', 'manual', True)] +# Note 'author' field empty +# Added 'True' to end of generated line to suppress 'Index & Tables' + + +# A dictionary that contains LaTeX snippets that override those Sphinx usually +# puts into the generated .tex files. +latex_elements = { 'babel': '\\usepackage[english]{babel}' } + + +# The name of an image file (relative to this directory) to place at the top of +# the title page. +latex_logo = './images/Vortex-Cover.png' + +# For "manual" documents, if this is true, then toplevel headings are parts, +# not chapters. +latex_use_parts = False + + +# If true, show page references after internal links. +#latex_show_pagerefs = False + +# If true, show URL addresses after external links. +#latex_show_urls = False + +# Additional stuff for the LaTeX preamble. +latex_preamble = r""" +\setcounter {tocdepth} {5} +\setcounter{secnumdepth}{5} + +""" + +# * THIS GETS RID OF BLANK PAGES AT ENDS OF CHAPTERS & ToC +latex_elements = { + 'classoptions': ',openany, oneside', + 'babel': '\\usepackage[english]{babel}' +} + + +# Documents to append as an appendix to all manuals. +#latex_appendices = [] + +# If false, no module index is generated. +#latex_domain_indices = True + + +# -- Options for manual page output -------------------------------------------- + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [('index', 'OpenSplice_PythonDCPSAPIGuide', u'OpenSplice_PythonDCPSAPI Documentation', [u'ADLINK Technology Limited'], 1)] + + +# -- Additional options -------------------------------------------------------- + +todo_include_todos = True diff --git a/build/docs/PythonDCPSAPIGuide/source/contacts.rst b/build/docs/PythonDCPSAPIGuide/source/contacts.rst new file mode 100644 index 000000000..d32f6016f --- /dev/null +++ b/build/docs/PythonDCPSAPIGuide/source/contacts.rst @@ -0,0 +1 @@ +.. include:: ../../common/contacts.rst diff --git a/build/docs/PythonDCPSAPIGuide/source/dds_entities.rst b/build/docs/PythonDCPSAPIGuide/source/dds_entities.rst new file mode 100644 index 000000000..972ed9a1d --- /dev/null +++ b/build/docs/PythonDCPSAPIGuide/source/dds_entities.rst @@ -0,0 +1,436 @@ +.. _`Python API for Vortex DDS`: + +######################### +Python API for Vortex DDS +######################### + +The Python DCPS API provides users with Python classes to model DDS communication using Python and pure +DDS applications. + +The Python DCPS API consists of 2 modules. + +* dds module +* ddsutil module + +This section provides an overview of the main DDS concepts and Python API examples for these DDS concepts. + +.. note:: + + - The Python DCPS API can be found in the following directory: + + *$OSPL_HOME/tools/python/docs/html* + +API Usage Patterns +****************** + +The typical usage pattern for the Python DCPS API for Vortex DDS is the following: + +* optional - Model your DDS topics using IDL. Alternatively, the python scripts can use topics that already exist in the DDS system. +* optional - Statically generate Python topic classes using ``idlpp -l python``. If using IDL, the user also has the option to dynamically generate Python topic classes in python scripts. See :ref:`Python Generation from IDL`. +* Start writing your Python program using the Python API for Vortex DDS. + +The core classes you must use are ``dds.Topic``, ``dds.DomainParticipant`` and either ``dds.DataReader`` or ``dds.DataWriter``. +Other classes may be required, especially if you need to adjust the Quality of Service (QoS) defaults. +For details on setting QoS values with the API, see :ref:`QoS Provider`. + +The following list shows the sequence in which you would use the Vortex classes: + +* Create a ``dds.DomainParticipant`` instance. +* Create one or more ``dds.Topic`` instances for the IDL topics your program will read or write. +* If you require publisher or subscriber level non-default QoS settings, create ``dds.Publisher`` and/or ``dds.Subscriber`` instances. (The most common reason for changing publisher/subscriber QoS is to define non-default partitions.) +* Create ``dds.DataReader`` and/or ``dds.DataWriter`` classes using the ``dds.Topic`` instances that you created. +* If you required data filtering, create ``dds.QueryCondition`` objects. +* Create the core of program, creating instances of your topic classes and writing them; or, reading data and processing it. + +dds.Topic +********* + +The Python Topic class represents a DDS topic type. The DDS topic corresponds to a single data type. In DDS, data is distributed by publishing and subscribing topic data samples. + +For a DDS Topic type definition, a corresponding Python class must be defined. +These topic classes are either a class created statically using ``idlpp``, dynamically using an idl file or dynamically for an existing topic discovered in the system. (see :ref:`Topic Generation and Discovery`) + +**API Examples** + +Create a Vortex DDS topic named 'Msg1' based on the DDS Topic type ``Msg``. + +.. code-block:: python + + TOPIC_NAME = 'Msg1' + TOPIC_TYPE = 'HelloWorldData::Msg' + IDL_FILE = 'idl/HelloWorldData.idl' + + # Create domain participant + dp = DomainParticipant() + + # Generate python classes from IDL file + gen_info = ddsutil.get_dds_classes_from_idl(IDL_FILE, TOPIC_TYPE) + + # Type support class + qos = Qos([DurabilityQosPolicy(DDSDurabilityKind.TRANSIENT), + ReliabilityQosPolicy(DDSReliabilityKind.RELIABLE)]) + topic = gen_info.register_topic(dp, TOPIC_NAME, qos) + +dds.DomainParticipant +********************* + +The Python``dds.DomainParticipant`` class represents a DDS domain participant entity. + +In DDS - “A domain participant represents the local membership of the application in a domain. A domain is a distributed concept that links all the applications able to communicate with each other. It represents a communication plane: only the publishers and subscribers attached to the same domain may interact.†+ +The dds.DomainParticipant has two optional parameters on creation. If these parameters are not provided, defaults are used. + +Parameters: + +* qos (Qos) – Participant QoS. Default: None +* listener (Listener) – Participant listener Default: None + + +**API Examples** + +Create a Vortex DDS domain participant. Returns participant or throws a ``dds.DDSException`` if the participant cannot be created. + +Create a domain participant in the default DDS domain (the one specified by the OSLP_URI environment variable). + +.. code-block:: python + + # Create domain participant + dp = DomainParticipant() + +Create a participant on default domain with QoS profile. + +.. code-block:: python + + qp = QosProvider('file://DDS_DefaultQoS_All.xml', 'DDS DefaultQosProfile') + + # Create participant + dp = DomainParticipant(qos = qp.get_participant_qos()) + +Create a participant on domain with QoS profile and listener. TODO + +.. code-block:: python + + qp = QosProvider('file://DDS_DefaultQoS_All.xml', 'DDS DefaultQosProfile') + + # Create participant + dp = DomainParticipant(qos = qp.get_participant_qos()) + +dds.Publisher +************* + +The Python ``dds.Publisher`` class represents a DDS publisher entity. + +In DDS, a publisher is “an object responsible for data distribution. It may publish data of different data types.†+ +Use of the ``dds.Publisher`` class is optional. +In it's place, you can use a ``dds.DomainParticipant`` instance. +Reasons for explicitly creating a ``dds.Publisher`` instance are: + +* to specify non-default QoS settings, including specifying the DDS *partition* upon which samples are written. +* to control the timing of publisher creation and deletion. + +**API Examples** + +Create a DDS Publisher entity. Returns publisher or throws a ``dds.DDSException`` if the publisher cannot be created. + +Create a publisher with participant. + +.. code-block:: python + + # Create participant + dp = DomainParticipant() + + # Create publisher + pub = dp.create_publisher() + +Create a publisher with participant and QoS profile. + +.. code-block:: python + + qp = QosProvider('file://DDS_DefaultQoS_All.xml', 'DDS DefaultQosProfile') + + # Create participant + dp = DomainParticipant(qos = qp.get_participant_qos()) + + # Create publisher + pub = dp.create_publisher(qos = qp.get_publisher_qos()) + +dds.DataWriter +************** + +The Python ``dds.Writer`` class represents a DDS data writer entity. + +In DDS - “The DataWriter is the object the application must use to communicate to a publisher the existence and value of data-objects of a given type.†+ +A ``dds.DataWriter`` class is required in order to write data to a DDS domain. +It is attached to a DDS publisher or a DDS domain participant. + +A ``dds.DataWriter`` class instance references an existing ``dds.Topic`` instance. + +**API Examples** + +Create a Vortex DDS domain writer. Returns writer or throws a ``dds.DDSException`` if the writer cannot be created. + +Create a writer within a domain participant, and with default QoS. + +.. code-block:: python + + # Create domain participant + dp = DomainParticipant() + + # Generate python classes from IDL file + gen_info = ddsutil.get_dds_classes_from_idl('idl/HelloWorldData.idl', 'HelloWorldData::Msg') + + # Type support class + qos = Qos([DurabilityQosPolicy(DDSDurabilityKind.TRANSIENT), ReliabilityQosPolicy(DDSReliabilityKind.RELIABLE)]) + topic = gen_info.register_topic(dp, 'Msg1', qos) + + # Create a writer + writer = dp.create_datawriter(topic) + +Create a writer within a publisher, and with default QoS. + +.. code-block:: python + + # Create domain participant + dp = DomainParticipant() + + # Create publisher + pub = dp.create_publisher() + + # Generate python classes from IDL file + gen_info = ddsutil.get_dds_classes_from_idl('idl/HelloWorldData.idl', 'HelloWorldData::Msg') + + # Type support class + qos = Qos([DurabilityQosPolicy(DDSDurabilityKind.TRANSIENT), ReliabilityQosPolicy(DDSReliabilityKind.RELIABLE)]) + topic = gen_info.register_topic(dp, 'Msg1', qos) + + # Create a writer + writer = pub.create_datawriter(topic) + +Create a writer with publisher or participant, topic and QoS profile. + + .. code-block:: python + + # Create domain participant + dp = DomainParticipant() + + # Create publisher + pub = dp.create_publisher() + + # Generate python classes from IDL file + gen_info = ddsutil.get_dds_classes_from_idl('idl/HelloWorldData.idl', 'HelloWorldData::Msg') + + # Type support class + qos = Qos([DurabilityQosPolicy(DDSDurabilityKind.TRANSIENT), ReliabilityQosPolicy(DDSReliabilityKind.RELIABLE)]) + topic = gen_info.register_topic(dp, 'Msg1', qos) + + # Create a writer + qp = QosProvider('file://DDS_DefaultQoS_All.xml', 'DDS DefaultQosProfile') + writer = pub.create_datawriter(topic) + writer = pub.create_datawriter(topic, qp.get_writer_qos()) + +Write a Msg topic class instance to a writer. + +.. code-block:: python + + # Topic data class + idMessage = 1 + message1 = 'Hello World' + s = gen_info.topic_data_class(userID = idMessage, message = message1) + + # Write data + writer.write(s) + +Dispose a DDS topic instance. + +.. code-block:: python + + # dispose instance + writer.dispose_instance(s) + +Unregister a DDS topic instance. TODO no equivalent in Python API + + % writer: a Vortex.Writer instance + % ShapeType: a 'topic class' created manually or via IDLPP + data = ShapeType(); % create an object instance + % set data key values... + data.color = 'RED'; + + ddsStatus = writer.unregister(data); + +dds.Subscriber +************** + +The Python ``dds.Subscriber`` class represents a DDS subscriber entity. + +In DDS, a subscriber is “an object responsible for receiving published data and making it available to the receiving application. It may receive and dispatch data of different specified types.†+ +Use of the ``dds.Subscriber`` class is optional. +In it's place, you can use a ``dds.DomainParticipant`` instance. +Reasons for explicitly creating a ``dds.Subscriber`` instance are: + +* to specify non-default QoS settings, including specifying the DDS *partition* upon which samples are written. +* to control the timing of subscriber creation and deletion. + +**API Examples** + + +Create a Vortex DDS domain subscriber. Returns subscriber or throw a ``dds.DDSException`` if the subscriber cannot be created. + + +Create a subscriber with participant. + +.. code-block:: python + + # Create participant + dp = DomainParticipant() + + # Create Subscriber + sub = dp.create_subscriber() + +Create a subscriber with participant and QoS profile. + +.. code-block:: python + + qp = QosProvider('file://DDS_DefaultQoS_All.xml', 'DDS DefaultQosProfile') + + # Create participant + dp = DomainParticipant(qos = qp.get_participant_qos()) + + # Create Subscriber + sub = dp.create_subscriber(qos = qp.get_subscriber_qos()) + + +dds.DataReader +************** + +The Python ``Vortex.Reader`` class represents a DDS data reader entity. + +In DDS - “To access the received data, the application must use a typed DataReader attached to the subscriber.†+ +A ``dds.DataReader`` class is required in order to write data to a DDS domain. +It is attached to a DDS subscriber or a DDS domain participant. + +A ``dds.DataReader`` class instance references an existing ``dds.Topic`` instance. + +**API Examples** + +Create a Vortex DDS domain reader. Returns reader or throw a ``dds.DDSException`` instance if the reader cannot be created. + +Create a reader for a topic within a participant, and with default QoS. + +.. code-block:: python + + # Create domain participant + dp = DomainParticipant() + + # Generate python classes from IDL file + gen_info = ddsutil.get_dds_classes_from_idl('idl/HelloWorldData.idl', 'HelloWorldData::Msg') + + # Type support class + qos = Qos([DurabilityQosPolicy(DDSDurabilityKind.TRANSIENT), ReliabilityQosPolicy(DDSReliabilityKind.RELIABLE)]) + topic = gen_info.register_topic(dp, 'Msg1', qos) + + # Create a reader + reader = dp.create_datareader(topic) + +Create a reader for a topic within a subscriber, and with default QoS. + +.. code-block:: python + + # Create domain participant + dp = DomainParticipant() + + # Create subscriber + sub = dp.create_subscriber() + + # Generate python classes from IDL file + gen_info = ddsutil.get_dds_classes_from_idl(IDL_FILE, TOPIC_TYPE) + + # Type support class + qos = Qos([DurabilityQosPolicy(DDSDurabilityKind.TRANSIENT), ReliabilityQosPolicy(DDSReliabilityKind.RELIABLE)]) + topic = gen_info.register_topic(dp, TOPIC_NAME, qos) + + # Create a reader + reader = sub.create_datareader(topic) + +Create a reader for a topic within a subscriber or participant, with with a QoS profile. + +.. code-block:: python + + # Create domain participant + dp = DomainParticipant() + + # Create subscriber + sub = dp.create_subscriber() + + # Generate python classes from IDL file + gen_info = ddsutil.get_dds_classes_from_idl(IDL_FILE, TOPIC_TYPE) + + # Type support class + qos = Qos([DurabilityQosPolicy(DDSDurabilityKind.TRANSIENT), ReliabilityQosPolicy(DDSReliabilityKind.RELIABLE)]) + topic = gen_info.register_topic(dp, TOPIC_NAME, qos) + + # Create a reader + qp = QosProvider('file://DDS_DefaultQoS_All.xml', 'DDS DefaultQosProfile') + reader = sub.create_datareader(topic, qp.get_reader_qos()) + +Take data from a data reader. + +.. code-block:: python + + l = reader.take(10) + +Read data from a data reader. + +.. code-block:: python + + l = reader.read(10) + +Specify a wait timeout, in seconds, before read or take will return without receiving data TODO change description the code is wrong + +.. code-block:: python + + # Create waitset + waitset = WaitSet() + qc = QueryCondition(reader, DDSMaskUtil.all_samples(), 'long1 > 1') + + waitset.attach(qc) + + # Wait for data + conditions = waitset.wait() + + # Print data + l = reader.take(10) + +dds.QueryCondition +****************** + +The Python ``dds.QueryCondition`` class represents a DDS query entity. + +A query is a data reader, restricted to accessing data that matches specific status conditions and/or a filter expression. + +A ``dds.Query`` class instance references an existing ``dds.DataReader`` instance. + +**API Examples** + +Create a ``dds.QueryCondition`` with a state mask and a filter expression for a reader and take data. + +.. code-block:: python + + # Create waitset + waitset = WaitSet() + qc = QueryCondition(reader, DDSMaskUtil.all_samples(), 'long1 > 1') + + waitset.attach(qc) + + # Wait for data + conditions = waitset.wait() + + # Print data + l = reader.take(10) + for sd, si in l: + sd.print_vars() + + diff --git a/build/docs/PythonDCPSAPIGuide/source/examples.rst b/build/docs/PythonDCPSAPIGuide/source/examples.rst new file mode 100644 index 000000000..c0eed334a --- /dev/null +++ b/build/docs/PythonDCPSAPIGuide/source/examples.rst @@ -0,0 +1,87 @@ +.. _`Examples`: + +######## +Examples +######## + +Several examples are provided to demonstrate the Python DCPS features. + +The examples can be found in the following directory: + + - *$OSPL_HOME/tools/python/examples* + +Example Files +************* + +File Types +========== + +The examples directory contains files of different types. The runnable python script files reference the xml and idl files. + + +============= ========================================================================================= +**File Type** **Description** +============= ========================================================================================= +py A program file or script written in Python +xml An XML file that contains one or more Quality of Service (QoS) profiles for DDS entities. +idl An interface description language file used to define topic(s). +============= ========================================================================================= + + + + +Examples +======== + +.. _`Examples Table`: +.. tabularcolumns:: | p{3.3cm} | p{11cm} | ++-------------------+-----------------------------------------------------+ +| **Example** | **Description** | ++===================+=====================================================+ +| qos_example.py | An example that demonstrates how to specify QoS | +| | settings using Python DCPS APIs. Also shows | +| | usage of a waitset. | +| | | ++-------------------+-----------------------------------------------------+ +| example1.py | Dynamic generation of Python Topic classes | +| | using IDL file and name. Uses a topic with a | +| | sequence. | +| | | ++-------------------+-----------------------------------------------------+ +| example2.py | Dynamic generation of Python Topic classes | +| | using Enumeration and nested modules. | +| | | +| | | ++-------------------+-----------------------------------------------------+ +| example4.py | Demonstrate finding DDS topics over-the-wire. | +| | Find topics registered by other processes, and | +| | read and write samples to those topics. | +| | | ++-------------------+-----------------------------------------------------+ + + + +Running Examples +**************** + +To run an example python script: + +1. Setup OSPL environment variables. + + **Linux** + + - source release.com + + **Windows** + - release.bat + + +2. Run an example python script + + - > python3 example1.py + + + + + + diff --git a/build/docs/PythonDCPSAPIGuide/source/images/Vortex-Cover.png b/build/docs/PythonDCPSAPIGuide/source/images/Vortex-Cover.png new file mode 100644 index 000000000..d82d6b313 Binary files /dev/null and b/build/docs/PythonDCPSAPIGuide/source/images/Vortex-Cover.png differ diff --git a/build/docs/PythonDCPSAPIGuide/source/images/Vortex_logo_2014.png b/build/docs/PythonDCPSAPIGuide/source/images/Vortex_logo_2014.png new file mode 100644 index 000000000..e7de4f525 Binary files /dev/null and b/build/docs/PythonDCPSAPIGuide/source/images/Vortex_logo_2014.png differ diff --git a/build/docs/PythonDCPSAPIGuide/source/images/dds_overview.png b/build/docs/PythonDCPSAPIGuide/source/images/dds_overview.png new file mode 100755 index 000000000..c7490ddb4 Binary files /dev/null and b/build/docs/PythonDCPSAPIGuide/source/images/dds_overview.png differ diff --git a/build/docs/PythonDCPSAPIGuide/source/images/pythonDir.png b/build/docs/PythonDCPSAPIGuide/source/images/pythonDir.png new file mode 100755 index 000000000..15ed91df0 Binary files /dev/null and b/build/docs/PythonDCPSAPIGuide/source/images/pythonDir.png differ diff --git a/build/docs/PythonDCPSAPIGuide/source/index.rst b/build/docs/PythonDCPSAPIGuide/source/index.rst new file mode 100644 index 000000000..ee2c9ad4f --- /dev/null +++ b/build/docs/PythonDCPSAPIGuide/source/index.rst @@ -0,0 +1,28 @@ +.. Python DCSP API Guide + +.. Doc Issue 01, 30 November 2017 + +##################### +Python DCPS API Guide +##################### + +.. toctree:: + :maxdepth: 6 + :numbered: + + preface + introduction + installation + examples + dds_entities + qos_provider + topic + python_idl_mapping + + contacts + + +Indices and tables +================== + +* :ref:`search` diff --git a/build/docs/PythonDCPSAPIGuide/source/installation.rst b/build/docs/PythonDCPSAPIGuide/source/installation.rst new file mode 100644 index 000000000..99ed780e8 --- /dev/null +++ b/build/docs/PythonDCPSAPIGuide/source/installation.rst @@ -0,0 +1,120 @@ +.. _`Installation`: + +############ +Installation +############ + +This section describes the procedure to install the Python DCPS API on a Linux or Windows platform. + +System Requirements +******************* + +Operating System: Linux or Windows + +Dependencies +************ + + **Linux** + - Python3 version 3.4.0 or later + - pip3 (package "python3-pip" on most linux package managers) + - GCC 4.8 or later + + **Windows** + - Python version 3.5.0 + - pip (usually already included in Python for Windows) + - Visual Studio 14 (2015) C compiler or later + + **Python modules** + - Cython version 0.27 or later (install using "pip3 install Cython") + + +OpenSplice (OSPL) and Python DCPS API Installation +*************************************************** + +Steps: + +1. Install OSPL. The Python DCPS API is included in this installer. + +2. Setup OSPL license. Copy the license.lic file into the appropriate license directory. + + */INSTALLDIR/Vortex_v2/license* + +3. Python DCPS API files are contained in a tools/python folder + + Example: + *$OSPL_HOME/tools/python* + +.. figure:: images/pythonDir.png + :alt: Python Directory + +.. _PythonDCPSAPI: + +Python DCPS API Setup +********************* + +Install Python DCPS API package from python wheel +================================================= + +In certain Vortex OpenSplice installs, the python api is bundled as a python wheel file in +the $OSPL_HOME/tools/python directory. This way it avoids needing a native compiler and Cython +prerequisites before installation. + +Simply install using pip. For example, executing the command will install the wheel package, +which is targeted for python 3.4 64-bit Linux: + + $pip3 install dds-6.9.0-cp34-cp34m-linux_x86_64.whl + +Or similarly, for python 3.5 64-bit Windows: + + >pip install dds-6.9.0-cp35-cp35m-win_amd64.whl + +If the binary wheel package is not present or is not compatible with your python version, +then it is preferable to install the api from source. + +Install Python DCPS API package from source +=========================================== + +If the dependencies are satisfied, and the Vortex OpenSplice environment is set +(OSPL_HOME and associated environment variables), then installation is just one command +to execute in the $OSPL_HOME/python/src directory: + + $python3 setup.py install + +.. note:: + + - In either case, installing from wheel or from source may require administrator or superuser privileges if python was installed for all users. + + - To check modules are installed correctly try importing the installed modules. + + >>> import dds + >>> import ddsutil + + +Examples and Documentation +************************** + +1. Examples + + The examples can be found in the following directory: + + - *$OSPL_HOME/tools/python/examples* + +2. Python DCPS API Documentation + + The Python DCPS API can be found in the following directory: + + - *$OSPL_HOME/tools/python/docs/html* + +3. Python DCPS User Guide (HTML and PDF) + + The user guide can be found in the following directories: + + - *$OSPL_HOME/docs/html* + + - *$OSPL_HOME/docs/pdf* + + + + + + diff --git a/build/docs/PythonDCPSAPIGuide/source/introduction.rst b/build/docs/PythonDCPSAPIGuide/source/introduction.rst new file mode 100644 index 000000000..ebd798f7d --- /dev/null +++ b/build/docs/PythonDCPSAPIGuide/source/introduction.rst @@ -0,0 +1,32 @@ +.. _`Introduction`: + + +############ +Introduction +############ + +The Python DCPS API provides users with Python classes to model DDS communication using Python and pure DDS applications. + +The Python DCPS API is a native Python binding that supports full DDS functionality. The language binding consists of a Python interface and a C wrapper implementation of the C99 API (C API for DDS). It makes use of Python language features and leverages ease of use by providing a higher level of abstraction. + +DDS +*** + +**What is DDS?** + +“The Data Distribution Service (DDSâ„¢) is a middleware protocol and API standard for data-centric connectivity from the Object Management Group® (OMG®). It integrates the components of a system together, providing low-latency data connectivity, extreme reliability, and a scalable architecture that business and mission-critical Internet of Things (IoT) applications need.†+ +“The main goal of DDS is to share the right data at the right place at the right time, even between time-decoupled publishers and consumers. DDS implements global data space by carefully replicating relevant portions of the logically shared dataspace.†DDS specification + +.. figure:: images/dds_overview.png + :alt: DDS + +**Further Documentation** + +http://portals.omg.org/dds/ + +http://ist.adlinktech.com/ + + + + diff --git a/build/docs/PythonDCPSAPIGuide/source/preface.rst b/build/docs/PythonDCPSAPIGuide/source/preface.rst new file mode 100644 index 000000000..1a8a9f522 --- /dev/null +++ b/build/docs/PythonDCPSAPIGuide/source/preface.rst @@ -0,0 +1,31 @@ +.. _`Preface`: + +####### +Preface +####### + +About the Python DCPS API Guide +******************************* + +The Python DCPS API Guide is a starting point for anyone using, developing or running Python applications with Vortex OpenSplice. + +This guide contains: + + - Python DCSP API installation instructions + - location of Python DCPS API dds module documentation + - overview of general DDS concepts and Python API for Vortex DDS + - a listing of examples, and how to run them + - detailed information on how to specify DDS entity Quality of Service (QoS) + - how to discover and register DDS topics + +This reference guide is based on the OMG’s Data Distribution Service Specification and Python Language Mapping Specification. + +Please note that this guide is not intended to provide a detailed explanation of the aforementioned OMG specifications or the Vortex OpenSplice product. It provides an introduction to the essential concepts and enables users to begin using the Python DCPS API as quickly as possible. + +Intended Audience +***************** + +The Python Reference Guide is intended to be used by Python programmers who are +using Vortex OpenSplice to develop applications. + + diff --git a/build/docs/PythonDCPSAPIGuide/source/python_idl_mapping.rst b/build/docs/PythonDCPSAPIGuide/source/python_idl_mapping.rst new file mode 100644 index 000000000..2ed0be78e --- /dev/null +++ b/build/docs/PythonDCPSAPIGuide/source/python_idl_mapping.rst @@ -0,0 +1,134 @@ +.. _`Python Generation from IDL`: + +########################## +Python Generation from IDL +########################## + +The Python DCPS API supports generation of Python topic classes from IDL. This chapter describes the details of the IDL-Python binding. + +Running IDLPP +************* + +.. _StaticGeneration: + +Static Generation +================= + +The Python topic classes can be generated statically using an IDL file. + +Compiling IDL into python code is done using the ``-l python`` switch on idlpp:: + + idlpp -l python idl-file-to-compile.idl + +.. note:: + + - A Python package with the same name as the idl file (without the .idl extension) is always created. + + - It defines types not included in an IDL module. IDL modules become Python packages within this base package. + +.. _DynamicGeneration: + +Dynamic Generation +================== + +The Python topic classes can be generated dynamically using an IDL file, and the topic name. An api, ``ddsutil.get_dds_classes_from_idl``, is provided to generate the topic classes at runtime from within a Python script. + +**HelloWorldDataPublisher.py** + +.. code-block:: python + + ... + TOPIC_NAME = 'Msg1' + TOPIC_TYPE = 'HelloWorldData::Msg' + IDL_FILE = 'idl/HelloWorldData.idl' + + # Create domain participant + dp = DomainParticipant() + + # Create publisher + pub = dp.create_publisher() + + # Generate python topic classes from IDL file + gen_info = ddsutil.get_dds_classes_from_idl(IDL_FILE, TOPIC_TYPE) + + # Type support class + qos = Qos([DurabilityQosPolicy(DDSDurabilityKind.TRANSIENT), + ReliabilityQosPolicy(DDSReliabilityKind.RELIABLE)]) + + # Register topic + topic = gen_info.register_topic(dp, TOPIC_NAME, qos) + + # Create a writer + writer = pub.create_datawriter(topic) + + # Topic data class + idMessage = 1 + message1 = 'Hello World' + s = gen_info.topic_data_class(userID = idMessage, message = message1) + + # Write data + writer.write(s) + + #output to console + print('=== [Publisher] writing a message containing : ') + print('userID :', idMessage) + print('message :', message1) + ... + +Generated Artifacts +=================== + +The following table defines the Python artifacts generated from IDL concepts: + +=========== ============== =============================================== +IDL Concept Python Concept Comment +=========== ============== =============================================== +module package Folder with module name, plus __init__.py that + defines types defined within the module. +enum class Defined in __init__.py files. +enum value enum value Defined in __init__.py files. +struct class Defined in __init__.py files. +field class property Defined in __init__.py files. +union union Defined in __init__.py files. (Only statically + generated supported) +=========== ============== =============================================== + +**Datatype mappings** + +The following table shows the Python equivalents to IDL primitive types: + +=========== ============== +IDL Type Python Type +=========== ============== +boolean bool +char str, length==1 +octet int +short int +ushort int +long int +ulong int +long long int +ulong long int +float float +double float +string str +wchar Unsupported +wstring Unsupported +any Unsupported +long double Unsupported +=========== ============== + +**Implementing Arrays and Sequences in Python** + +Both IDL arrays and IDL sequences are mapped to Python lists. + +The constructors for generated classes always fully allocate any array fields. Sequences are always initialized to the empty list. + +Limitations of Python Support +***************************** + +The IDL-to-Python binding has the following limitations: + +* IDL unions are Supported by statically generated Python, but not by dynamic or over-the-wire. +* The following IDL data types are not supported: wchar, wstring, any and long double . + diff --git a/build/docs/PythonDCPSAPIGuide/source/qos_provider.rst b/build/docs/PythonDCPSAPIGuide/source/qos_provider.rst new file mode 100644 index 000000000..db4ecaa0e --- /dev/null +++ b/build/docs/PythonDCPSAPIGuide/source/qos_provider.rst @@ -0,0 +1,142 @@ +.. _`QoS Provider`: + + +######################## +Quality of Service (QoS) +######################## + +The following section explains how to set the Quality of Service (QoS) for a DDS entity. + +Users have two options available to set the QoS for an entity or entities. They can define the QoS settings using an XML file, or they can use the Python DCPS APIs. Both of these options are explained. + +If a QoS setting for an entity is not set using an xml file or the Python DCPS APIs, the defaults will be used. This allows a user the ability to override only those settings that require non-default values. + +The code snippets referenced are taken from the runnable examples. + +.. note:: + + - The :ref:`Examples` section provides the examples directory location, example descriptions and running instructions. + + +Setting QoS Using QoS Provider XML File +*************************************** + +QoS for DDS entities can be set using XML files based on the XML schema file QoSProfile.xsd_. +These XML files contain one or more QoS profiles for DDS entities. + +Sample QoS Profile XML files can be found in the examples directory. + +QoS Profile +=========== + +A QoS profile consists of a name and optionally a base_name attribute. The base_name attribute allows a +QoS or a profile to inherit values from another QoS or profile in the same file. The file contains QoS +elements for one or more DDS entities. A skeleton file without any QoS values is displayed below to show +the structure of the file. + +.. code-block:: xml + + + + + + + + + + + + +**Example: Specify Publisher Partition** + +The example below specifies the publisher's partitions as A and B. + +.. code-block:: xml + + + + + A + B + + + + +Applying QoS Profile +==================== + +To set the QoS profile for a DDS entity using the Python DCPS API and an XML file, the user specifies the File URI and the QoS profile name as parameters. + +**example1.py** + +.. code-block:: python + + ... + qp = QosProvider('file://DDS_DefaultQoS_All.xml', 'DDS DefaultQosProfile') + + # Create participant + dp = DomainParticipant(qos = qp.get_participant_qos()) + + # Create publisher + pub = dp.create_publisher(qos = qp.get_publisher_qos()) + + # Create Subscriber + sub = dp.create_subscriber(qos = qp.get_subscriber_qos()) + ... + + +Setting QoS Using Python DCPS API Classes +***************************************** + +QoS settings can also be set by using the python classes alone. (No XML files required.) + +Below is a code snippet that demonstrates how to specify the QoS settings for a writer using the python DCPS apis. In this example, all the QoS settings for the writer are set and all of the default QoS settings are overridden. If a QoS setting for an entity is not set, the default is used. + +**qos_example.py** + +.. code-block:: python + + ... + writer_qos = Qos([DurabilityQosPolicy(DDSDurabilityKind.TRANSIENT), + DeadlineQosPolicy(DDSDuration(500)), + LatencyBudgetQosPolicy(DDSDuration(3000)), + LivelinessQosPolicy(DDSLivelinessKind.MANUAL_BY_PARTICIPANT), + ReliabilityQosPolicy(DDSReliabilityKind.RELIABLE, DDSDuration.infinity()), + DestinationOrderQosPolicy(DDSDestinationOrderKind.BY_SOURCE_TIMESTAMP), + HistoryQosPolicy(DDSHistoryKind.KEEP_ALL), + ResourceLimitsQosPolicy(10,10,10), + TransportPriorityQosPolicy(700), + LifespanQosPolicy(DDSDuration(10, 500)), + OwnershipQosPolicy(DDSOwnershipKind.EXCLUSIVE), + OwnershipStrengthQosPolicy(100), + WriterDataLifecycleQosPolicy(False) + ]) + ... + + +In the next example, a topic QoS is created that overrides only a subset of the QoS settings. + +**HelloWorldDataSubscriber.py** + +.. code-block:: python + + ... + # Create domain participant + dp = DomainParticipant() + + # Create subscriber + sub = dp.create_subscriber() + + # Generate python classes from IDL file + gen_info = ddsutil.get_dds_classes_from_idl(IDL_FILE, TOPIC_TYPE) + + # Create a topic QoS that overrides defaults for durability and reliability + qos = Qos([DurabilityQosPolicy(DDSDurabilityKind.TRANSIENT), + ReliabilityQosPolicy(DDSReliabilityKind.RELIABLE)]) + topic = gen_info.register_topic(dp, TOPIC_NAME, qos) + ... + + +.. external links +.. _QoSProfile.xsd: http://www.omg.org/spec/dds4ccm/20110201/DDS_QoSProfile.xsd +.. _DDS_DefaultQoS.xml: http://www.omg.org/spec/dds4ccm/20110201/DDS_DefaultQoS.xml diff --git a/build/docs/PythonDCPSAPIGuide/source/topic.rst b/build/docs/PythonDCPSAPIGuide/source/topic.rst new file mode 100644 index 000000000..89a553c57 --- /dev/null +++ b/build/docs/PythonDCPSAPIGuide/source/topic.rst @@ -0,0 +1,75 @@ +.. _`Topic Generation and Discovery`: + +############################## +Topic Generation and Discovery +############################## + +A DDS Topic represents the unit for information that can be produced or consumed by a DDS application. Topics are defined by a name, a type, and a set of QoS policies. + +The Python DCPS API provides several ways of generating Python classes to represent DDS topics. + + - over the wire discovery + - dynamic generation of Python Topic classes using parameters IDL file and topic name + - static generation of Python Topic classes using IDL + +.. note:: + + - The :ref:`Examples` section provides the examples directory location, example descriptions and running instructions. + + +Over the Wire Discovery +************************ + +Python topic classes can be generated for existing DDS topics in the DDS system. These topics are "discovered over the wire". + +The Python classes are generated when the topic is requested by name. + +A code snippet is provided from example4.py. This example finds a topic registered by another process, and reads and writes samples to that topic. + +**example4.py** + +.. code-block:: python + + ... + print('Connecting to DDS domain...') + dp = dds.DomainParticipant() + + print('Finding OsplTestTopic...') + found_topic = dp.find_topic('OsplTestTopic') + + print('Registering OsplTestTopic locally') + local_topic = ddsutil.register_found_topic_as_local(found_topic) + + print('Getting Python classes for the found topic...') + gen_info = ddsutil.get_dds_classes_for_found_topic(found_topic) + OsplTestTopic = gen_info.get_class(found_topic.type_name) + Tstate = gen_info.get_class('ospllog::Tstate') + + print('Creating sample data to write...') + data = OsplTestTopic(id=11,index=22, x=1.2, y=2.3, z= 3.4, t=9.8, + state=Tstate.init, description='Hello from Python') + + print('Creating readers and writers...') + pub = dp.create_publisher() + wr = pub.create_datawriter(local_topic, found_topic.qos) + sub = dp.create_subscriber() + rd = sub.create_datareader(local_topic, found_topic.qos) + + print('Writing sample data...') + wr.write(data) + print('Wrote: %s' % (str(data))) + ... + +Static Generation of Python Topic Classes Using IDL +*************************************************** + +The Python topic classes can be generated statically using an IDL file. Please see :ref:`StaticGeneration` for more information. + +Dynamic Generation of Python Topic Classes Using IDL and Name +************************************************************* + +The Python topic classes can be generated dynamically using an IDL file, and the topic name. Please see :ref:`DynamicGeneration` for more information. + + + + diff --git a/build/docs/RMIGettingStarted/source/conf.py b/build/docs/RMIGettingStarted/source/conf.py index 620ae4814..1d3d3cd52 100644 --- a/build/docs/RMIGettingStarted/source/conf.py +++ b/build/docs/RMIGettingStarted/source/conf.py @@ -56,9 +56,8 @@ def setup(app): # General information about the project. project = u'RMI User Guide' -#copyright = u'2015, PrismTech' this_year = time.strftime( '%Y' ) -copyright = u'{y}, PrismTech'.format( y = this_year ) +copyright = u'{y}, ADLINK Technology Limited'.format( y = this_year ) print 'Copyright string is:', copyright # The version info for the project you're documenting, acts as replacement for @@ -228,7 +227,7 @@ def setup(app): # Added 'True' to end of generated line to suppress 'Index & Tables' -# A dictionary that contains LaTeX snippets that override those Sphinx usually +# A dictionary that contains LaTeX snippets that override those Sphinx usually # puts into the generated .tex files. latex_elements = { 'babel': '\\usepackage[english]{babel}' } @@ -275,7 +274,7 @@ def setup(app): # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). -man_pages = [('index', 'RMIUserGuide', u'RMIUserGuide Documentation', [u'PrismTech'], 1)] +man_pages = [('index', 'RMIUserGuide', u'RMIUserGuide Documentation', [u'ADLINK Technology Limited'], 1)] # * NOT TESTED # -- Additional options -------------------------------------------------------- diff --git a/build/docs/RMIGettingStarted/source/contacts.rst b/build/docs/RMIGettingStarted/source/contacts.rst index c13319efa..d32f6016f 100644 --- a/build/docs/RMIGettingStarted/source/contacts.rst +++ b/build/docs/RMIGettingStarted/source/contacts.rst @@ -1,49 +1 @@ -.. _`Contacts & Notices`: - -################## -Contacts & Notices -################## - -******** -Contacts -******** - -| **PrismTech Corporation** -| 400 TradeCenter -| Suite 5900 -| Woburn, MA -| 01801 -| USA -| Tel: +1 781 569 5819 - -| **PrismTech Limited** -| PrismTech House -| 5th Avenue Business Park -| Gateshead -| NE11 0NG -| UK -| Tel: +44 (0)191 497 9900 - -| **PrismTech France** -| 28 rue Jean Rostand -| 91400 Orsay -| France -| Tel: +33 (1) 69 015354 - - -Web: http://www.prismtech.com - -E-mail: \info@prismtech.com - -******* -Notices -******* - -**Copyright** © 2016 PrismTech Limited. All rights reserved. - -*This document may be reproduced in whole but not in part. -The information contained in this document is subject to change -without notice and is made available in good faith without -liability on the part of PrismTech Limited or PrismTech Corporation. -All trademarks acknowledged.* - +.. include:: ../../common/contacts.rst diff --git a/build/docs/RMIGettingStarted/source/images/Vortex-OpenSplice-Cover.png b/build/docs/RMIGettingStarted/source/images/Vortex-OpenSplice-Cover.png index ce86c6d94..801c02bb8 100644 Binary files a/build/docs/RMIGettingStarted/source/images/Vortex-OpenSplice-Cover.png and b/build/docs/RMIGettingStarted/source/images/Vortex-OpenSplice-Cover.png differ diff --git a/build/docs/RMIGettingStarted/source/index.rst b/build/docs/RMIGettingStarted/source/index.rst index bb7da9e17..e9672fcf6 100644 --- a/build/docs/RMIGettingStarted/source/index.rst +++ b/build/docs/RMIGettingStarted/source/index.rst @@ -21,7 +21,7 @@ Vortex OpenSplice RMI User Guide qos-policies contacts - + Indices and tables ================== diff --git a/build/docs/RMIGettingStarted/source/language-map.rst b/build/docs/RMIGettingStarted/source/language-map.rst index 16f007206..62d884992 100644 --- a/build/docs/RMIGettingStarted/source/language-map.rst +++ b/build/docs/RMIGettingStarted/source/language-map.rst @@ -143,6 +143,14 @@ IDL sequences are mapped as specified by the DDS standard. string DDS::String =================== ============== +|caution| |cpp| + Please be aware that the RMI middleware assumes ownership of any + ``DDS::String`` that is provided to it (either by an in/inout argument + or return value). This also means that it'll free the given string. This + can cause issues when the application keeps using the provided string after + the RMI call or if RMI is called with a const string literal. It is advised + to apply ``DDS::string_dup(str)`` when using strings in conjunction with + RMI. This is also applicable to sequences of strings. diff --git a/build/docs/RMIGettingStarted/source/runtime-config.rst b/build/docs/RMIGettingStarted/source/runtime-config.rst index 3ba485cf7..6076ea731 100644 --- a/build/docs/RMIGettingStarted/source/runtime-config.rst +++ b/build/docs/RMIGettingStarted/source/runtime-config.rst @@ -30,7 +30,7 @@ RMIServiceDiscoveryTimeout option This is a client-side option that specifies the maximum duration (in seconds) that a client application can wait to find services. -It influences the execution time of the DDS_Service.getServerProxy +It influences the execution time of the DDS_Service.getServerProxy operation that is used to find a given service. The default value is set to 10 seconds. The need to set this value may come from some specific deployment environements with bad communication conditions. @@ -41,7 +41,7 @@ RMIServerThreadingModel option ``--RMIServerThreadingModel=ST | MT | TPS [,]`` -This is a server-side option that specifies the threading policy of +This is a server-side option that specifies the threading policy of the server runtime including the threading policy name and the thread pool size. **ST** selects *Single Threaded* policy. @@ -79,8 +79,8 @@ RMIDurability option .. [[!! DEVELOPMENT NOTE: Check status of this feature on each release !! !!]] - -|cpp| + +|cpp| ``--RMIDurability = yes | no`` @@ -90,16 +90,16 @@ underlying DDS middleware support the non-default durability Qos policies By default, this option value is ``yes``. -RMI servers uses non-volatile topics for services advertising to allow -late-joining clients to discover them. This option is useful for adapting -services registration and discovery mechanisms when the durability support +RMI servers uses non-volatile topics for services advertising to allow +late-joining clients to discover them. This option is useful for adapting +services registration and discovery mechanisms when the durability support is missing in the underlying DDS middleware. |caution| - Note that this feature must be *either* enabled *or* disabled for *all* of - the RMI applications in a given DDS domain. It means that durability-*en*abled - (option value is ``yes``) RMI applications cannot be deployed with - durability-*dis*abled (option value is ``no``) RMI applications in + Note that this feature must be *either* enabled *or* disabled for *all* of + the RMI applications in a given DDS domain. It means that durability-*en*abled + (option value is ``yes``) RMI applications cannot be deployed with + durability-*dis*abled (option value is ``no``) RMI applications in the same DDS domain. @@ -109,8 +109,8 @@ RMIClientSchedulingModel option |caution| **Note**: The ``RMIClientSchedulingModel`` option is currently *only* implemented for *Java*. - - + + .. [[!! DEVELOPMENT NOTE: Check status of this feature on each release !! !!]] @@ -124,6 +124,30 @@ by OpenSplice RMI at the client side, including the AsyncWaiter thread, which is one that waits for asynchronous replies. +******************************* +RMILegacyTopicNames option +******************************* +|caution| + **Note**: The ``RMILegacyTopicNames`` option applies *only* to *C++*. + +|cpp| + +``--RMILegacyTopicNames = yes | no`` + +This client- and server-side option allows to switch topic names between a legacy-mode +and a Java-compatible mode. + +In legacy-mode, topics are named ``DDS_ServiceDefinition`` and +``DDS_ServiceIdentification``. In this mode, a C++ RMI client or server is compatible +with previous releases of C++ RMI. Since Java RMI uses different topic names, a C++ +RMI client cannot communicate with a Java RMI server (or vice-versa). This is the +default behaviour. + +When legacy-mode is disabled, topics are named ``DDS_RMIDefinition`` and +``DDS_RMIIdentification``. This enables compatibility with Java RMI which has always +used these topic names, but unfortunately doesn't allow communication with older +versions of C++ RMI that don't support this option. + .. |caution| image:: ./images/icon-caution.* :height: 6mm .. |info| image:: ./images/icon-info.* @@ -143,4 +167,4 @@ one that waits for asynchronous replies. .. |java| image:: ./images/icon-java.* :height: 6mm - + diff --git a/build/docs/RnRAPIReference/source/conf.py b/build/docs/RnRAPIReference/source/conf.py index fce819bef..8ee6db2f4 100644 --- a/build/docs/RnRAPIReference/source/conf.py +++ b/build/docs/RnRAPIReference/source/conf.py @@ -63,9 +63,8 @@ def setup(app): # General information about the project. project = u'RnR API Reference' -#copyright = u'2015, PrismTech' this_year = time.strftime( '%Y' ) -copyright = u'{y}, PrismTech'.format( y = this_year ) +copyright = u'{y}, ADLINK Technology Limited'.format( y = this_year ) print 'Copyright string is:', copyright @@ -229,7 +228,7 @@ def setup(app): # Added 'True' to end of generated line to suppress 'Index & Tables' -# A dictionary that contains LaTeX snippets that override those Sphinx usually +# A dictionary that contains LaTeX snippets that override those Sphinx usually # puts into the generated .tex files. latex_elements = { 'babel': '\\usepackage[english]{babel}' } @@ -270,7 +269,7 @@ def setup(app): # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). -man_pages = [('index', 'RnR_API_Reference', u'RnR_API_Reference', [u'PrismTech'], 1)] +man_pages = [('index', 'RnR_API_Reference', u'RnR_API_Reference', [u'ADLINK Technology Limited'], 1)] # -- Additional options -------------------------------------------------------- diff --git a/build/docs/RnRAPIReference/source/contacts.rst b/build/docs/RnRAPIReference/source/contacts.rst index fc6442d3a..d32f6016f 100644 --- a/build/docs/RnRAPIReference/source/contacts.rst +++ b/build/docs/RnRAPIReference/source/contacts.rst @@ -1,53 +1 @@ -.. _`Contacts & Notices`: - -.. VERY LITTLE EVER CHANGES IN HERE !! - Just keep an eye on the copyright notice. - -################## -Contacts & Notices -################## - -******** -Contacts -******** - -| **PrismTech Corporation** -| 400 TradeCenter -| Suite 5900 -| Woburn, MA -| 01801 -| USA -| Tel: +1 781 569 5819 - -| **PrismTech Limited** -| PrismTech House -| 5th Avenue Business Park -| Gateshead -| NE11 0NG -| UK -| Tel: +44 (0)191 497 9900 - -| **PrismTech France** -| 28 rue Jean Rostand -| 91400 Orsay -| France -| Tel: +33 (1) 69 015354 - - -Web: http://www.prismtech.com - -E-mail: \info@prismtech.com - -******* -Notices -******* - -**Copyright** © 2016 PrismTech Limited. All rights reserved. - -*This document may be reproduced in whole but not in part. -The information contained in this document is subject to change -without notice and is made available in good faith without -liability on the part of PrismTech Limited or PrismTech Corporation. -All trademarks acknowledged.* - -.. END +.. include:: ../../common/contacts.rst diff --git a/build/docs/RnRAPIReference/source/images/Vortex-OpenSplice-Cover.png b/build/docs/RnRAPIReference/source/images/Vortex-OpenSplice-Cover.png index ce86c6d94..801c02bb8 100644 Binary files a/build/docs/RnRAPIReference/source/images/Vortex-OpenSplice-Cover.png and b/build/docs/RnRAPIReference/source/images/Vortex-OpenSplice-Cover.png differ diff --git a/build/docs/RnRAPIReference/source/index.rst b/build/docs/RnRAPIReference/source/index.rst index 4ee35f4f7..95798a315 100644 --- a/build/docs/RnRAPIReference/source/index.rst +++ b/build/docs/RnRAPIReference/source/index.rst @@ -9,19 +9,19 @@ The Vortex Record and Replay API Reference .. toctree:: :maxdepth: 6 :numbered: - + preface introduction scenarios topic-api-overview issues impact - + appendixa bibliography - - contacts - + + contacts + Indices and tables ================== diff --git a/build/docs/RnRAPIReference/source/preface.rst b/build/docs/RnRAPIReference/source/preface.rst index ae53e792d..912b2400d 100644 --- a/build/docs/RnRAPIReference/source/preface.rst +++ b/build/docs/RnRAPIReference/source/preface.rst @@ -8,8 +8,8 @@ Preface About The Record and Replay API Reference ****************************************** -The *Record and Replay (RnR) API Reference* provides a complete description of the functions -available *via* the API of the OpenSplice Record and Replay Service +The *Record and Replay (RnR) API Reference* provides a complete description of the functions +available *via* the API of the OpenSplice Record and Replay Service (RnR Service). This API Reference is intended to be used after the Vortex OpenSplice software @@ -19,58 +19,58 @@ according to the instructions in the Vortex OpenSplice *Getting Started Guide*. Intended Audience ***************** -The API Reference is intended to be used by all Record and Replay -Service users, including programmers, testers, system designers and +The API Reference is intended to be used by all Record and Replay +Service users, including programmers, testers, system designers and system integrators. Organisation ************ -The :ref:`Introduction ` gives an overview of the purpose +The :ref:`Introduction ` gives an overview of the purpose and design of the Record and Replay Service. -The :ref:`Scenarios ` section explains the key concept of the +The :ref:`Scenarios ` section explains the key concept of the ‘scenario’ used in the RnR Service. -:ref:`All of the functions of the RnR Service ` +:ref:`All of the functions of the RnR Service ` are then described in full detail. -There is a (very short) list of :ref:`known issues ` which +There is a (very short) list of :ref:`known issues ` which describes current limitations of the RnR Service. -The next section describes how the RnR Service is designed to -minimize its :ref:`intrusiveness ` on +The next section describes how the RnR Service is designed to +minimize its :ref:`intrusiveness ` on existing systems. -The :ref:`RnR Topic API IDL specification ` contains +The :ref:`RnR Topic API IDL specification ` contains the complete IDL definition of the RnR Service API. Finally, there is a :ref:`bibliography ` which lists -all of the publications referred to in this *Guide*. +all of the publications referred to in this *Guide*. Conventions *********** -The icons shown below are used in PrismTech product documentation -to help readers to quickly identify information relevant to their +The icons shown below are used in ADLINK product documentation +to help readers to quickly identify information relevant to their specific use of Vortex OpenSplice. - ========= ================================================================== - *Icon* *Meaning* - ========= ================================================================== - |caution| Item of special significance or where caution needs to be taken. - |info| Item contains helpful hint or special information. - |windows| Information applies to Windows (*e.g.* XP, 2003, Windows 7) only. - |unix| Information applies to Unix-based systems (*e.g.* Solaris) only. - |linux| Information applies to Linux-based systems (*e.g.* Ubuntu) only. - |c| C language specific. - |cpp| C++ language specific. - |csharp| C# language specific. - |java| Java language specific. - ========= ================================================================== + ========= ================================================================== + *Icon* *Meaning* + ========= ================================================================== + |caution| Item of special significance or where caution needs to be taken. + |info| Item contains helpful hint or special information. + |windows| Information applies to Windows (*e.g.* XP, 2003, Windows 7) only. + |unix| Information applies to Unix-based systems (*e.g.* Solaris) only. + |linux| Information applies to Linux-based systems (*e.g.* Ubuntu) only. + |c| C language specific. + |cpp| C++ language specific. + |csharp| C# language specific. + |java| Java language specific. + ========= ================================================================== @@ -94,4 +94,3 @@ specific use of Vortex OpenSplice. .. |java| image:: ./images/icon-java.* :height: 6mm - \ No newline at end of file diff --git a/build/docs/RnRManagerGuide/source/conf.py b/build/docs/RnRManagerGuide/source/conf.py index 2433b137e..aaff4e41a 100644 --- a/build/docs/RnRManagerGuide/source/conf.py +++ b/build/docs/RnRManagerGuide/source/conf.py @@ -63,9 +63,8 @@ def setup(app): # General information about the project. project = u'RnR Manager User Guide' -#copyright = u'2015, PrismTech' this_year = time.strftime( '%Y' ) -copyright = u'{y}, PrismTech'.format( y = this_year ) +copyright = u'{y}, ADLINK Technology Limited'.format( y = this_year ) print 'Copyright string is:', copyright @@ -74,7 +73,7 @@ def setup(app): # built documents. # # The short X.Y version. -version = u'6.7.0' +version = u'6.8.3' # The full version, including alpha/beta/rc tags. release = version @@ -230,14 +229,14 @@ def setup(app): # Added 'True' to end of generated line to suppress 'Index & Tables' -# A dictionary that contains LaTeX snippets that override those Sphinx usually +# A dictionary that contains LaTeX snippets that override those Sphinx usually # puts into the generated .tex files. latex_elements = { 'babel': '\\usepackage[english]{babel}' } # The name of an image file (relative to this directory) to place at the top of # the title page. -latex_logo = './images/Vortex-OpenSplice-Cover.png' +latex_logo = './images/Vortex_UserGuide_Cover_OpenSplice.png' # For "manual" documents, if this is true, then toplevel headings are parts, # not chapters. @@ -271,7 +270,7 @@ def setup(app): # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). -man_pages = [('index', 'RnR_Manager_User_Guide', u'RnR_Manager_User_Guide', [u'PrismTech'], 1)] +man_pages = [('index', 'RnR_Manager_User_Guide', u'RnR_Manager_User_Guide', [u'ADLINK Technology Limited'], 1)] # -- Additional options -------------------------------------------------------- diff --git a/build/docs/RnRManagerGuide/source/contacts.rst b/build/docs/RnRManagerGuide/source/contacts.rst index fc6442d3a..d32f6016f 100644 --- a/build/docs/RnRManagerGuide/source/contacts.rst +++ b/build/docs/RnRManagerGuide/source/contacts.rst @@ -1,53 +1 @@ -.. _`Contacts & Notices`: - -.. VERY LITTLE EVER CHANGES IN HERE !! - Just keep an eye on the copyright notice. - -################## -Contacts & Notices -################## - -******** -Contacts -******** - -| **PrismTech Corporation** -| 400 TradeCenter -| Suite 5900 -| Woburn, MA -| 01801 -| USA -| Tel: +1 781 569 5819 - -| **PrismTech Limited** -| PrismTech House -| 5th Avenue Business Park -| Gateshead -| NE11 0NG -| UK -| Tel: +44 (0)191 497 9900 - -| **PrismTech France** -| 28 rue Jean Rostand -| 91400 Orsay -| France -| Tel: +33 (1) 69 015354 - - -Web: http://www.prismtech.com - -E-mail: \info@prismtech.com - -******* -Notices -******* - -**Copyright** © 2016 PrismTech Limited. All rights reserved. - -*This document may be reproduced in whole but not in part. -The information contained in this document is subject to change -without notice and is made available in good faith without -liability on the part of PrismTech Limited or PrismTech Corporation. -All trademarks acknowledged.* - -.. END +.. include:: ../../common/contacts.rst diff --git a/build/docs/RnRManagerGuide/source/images/011_Domain_Wizard.png b/build/docs/RnRManagerGuide/source/images/011_Domain_Wizard.png old mode 100644 new mode 100755 index d37e34fe1..11e9cf5a5 Binary files a/build/docs/RnRManagerGuide/source/images/011_Domain_Wizard.png and b/build/docs/RnRManagerGuide/source/images/011_Domain_Wizard.png differ diff --git a/build/docs/RnRManagerGuide/source/images/058_ImportStorage.png b/build/docs/RnRManagerGuide/source/images/058_ImportStorage.png old mode 100644 new mode 100755 index 552adceec..000b30dde Binary files a/build/docs/RnRManagerGuide/source/images/058_ImportStorage.png and b/build/docs/RnRManagerGuide/source/images/058_ImportStorage.png differ diff --git a/build/docs/RnRManagerGuide/source/images/Vortex-OpenSplice-Cover.png b/build/docs/RnRManagerGuide/source/images/Vortex-OpenSplice-Cover.png index ce86c6d94..801c02bb8 100644 Binary files a/build/docs/RnRManagerGuide/source/images/Vortex-OpenSplice-Cover.png and b/build/docs/RnRManagerGuide/source/images/Vortex-OpenSplice-Cover.png differ diff --git a/build/docs/RnRManagerGuide/source/images/Vortex_UserGuide_Cover_OpenSplice.png b/build/docs/RnRManagerGuide/source/images/Vortex_UserGuide_Cover_OpenSplice.png new file mode 100755 index 000000000..801c02bb8 Binary files /dev/null and b/build/docs/RnRManagerGuide/source/images/Vortex_UserGuide_Cover_OpenSplice.png differ diff --git a/build/docs/RnRManagerGuide/source/index.rst b/build/docs/RnRManagerGuide/source/index.rst index dfa6ace20..f34c14b04 100644 --- a/build/docs/RnRManagerGuide/source/index.rst +++ b/build/docs/RnRManagerGuide/source/index.rst @@ -7,14 +7,14 @@ The Vortex Record and Replay Manager User Guide .. toctree:: :maxdepth: 6 :numbered: - + preface introduction installation using01 - - contacts - + + contacts + Indices and tables ================== diff --git a/build/docs/RnRManagerGuide/source/installation.rst b/build/docs/RnRManagerGuide/source/installation.rst index ee4fd66cf..ae87cf510 100644 --- a/build/docs/RnRManagerGuide/source/installation.rst +++ b/build/docs/RnRManagerGuide/source/installation.rst @@ -71,7 +71,7 @@ Installing the license file Please refer to the Vortex OpenSplice *Getting Started Guide* for full details of how Vortex OpenSplice is licensed. -PrismTech supplies a license file for the RnR Manager product. This file +ADLINK supplies a license file for the RnR Manager product. This file is *not* included in the software distribution. During the installation, you have the option of specifying the license @@ -125,4 +125,4 @@ Click the button *Restart Workbench* after importing the license file. .. |java| image:: ./images/icon-java.* :height: 6mm - \ No newline at end of file + diff --git a/build/docs/RnRManagerGuide/source/introduction.rst b/build/docs/RnRManagerGuide/source/introduction.rst index c2a8a10de..791b9a1df 100644 --- a/build/docs/RnRManagerGuide/source/introduction.rst +++ b/build/docs/RnRManagerGuide/source/introduction.rst @@ -12,12 +12,12 @@ Introduction Overview ******** -This section provides a brief introduction to the OpenSplice DDS +This section provides a brief introduction to the Vortex OpenSplice RnR Service and the RnR Manager tool. |caution| Version 6.4 of RnR Manager is compatible with Vortex OpenSplice - version 6.4. It is not compatible with earlier versions of OpenSplice. + version 6.4. It is not compatible with earlier versions of Vortex OpenSplice. Vortex OpenSplice Record and Replay Service @@ -83,7 +83,7 @@ for an existing system are: b) In the case of a dedicated RnR node, this partition can be configured to be a so-called ‘local partition’, thus bounding all control/status traffic to the RnR node (see Section 2.5.2.6 in the - OpenSplice *Deployment Guide*). + Vortex OpenSplice *Deployment Guide*). 3. Replaying (subsets) of recorded data ‘by definition’ has an impact on an existing system: @@ -106,7 +106,7 @@ data in a multicast-enabled network is non-intrusive. Note: *The few shared topic-definitions (definitions ONLY, not actual samples of these topics when these are ‘confined’ to the RnR node) that would be visible system-wide when inspecting the built-in topics of - the system (for instance with a tool like the OpenSplice Tuner) are + the system (for instance with a tool like the Vortex OpenSplice Tuner) are considered not instrusive as they only imply a small amount of static data space occupied by the related built-in topic samples.)* @@ -117,7 +117,7 @@ Please refer to the Vortex OpenSplice *Deployment Guide* (``OpenSplice_Deployment.pdf``) for more detailed information on how to configure Vortex OpenSplice. -The OpenSplice configuration editor (``osplconf``) provides facilities to +The Vortex OpenSplice configuration editor (``osplconf``) provides facilities to create, modify and save configuration files. This tool is described in Section 3.2 in the Vortex OpenSplice *Deployment Guide*. @@ -152,7 +152,7 @@ inspect and change recorded data. RnR Manager uses the internal Control and Monitoring API for access to the Vortex OpenSplice Middleware. Connections to local nodes *via* JNI and remote nodes (*via* SOAP) are supported. The manager tool does not need to have -OpenSplice DDS installed locally. A connection can be made remotely to a +Vortex OpenSplice installed locally. A connection can be made remotely to a node that is running Vortex OpenSplice. RnR Manager Features @@ -384,4 +384,4 @@ A range is defined with a start and an end timestamp. .. |java| image:: ./images/icon-java.* :height: 6mm - \ No newline at end of file + diff --git a/build/docs/RnRManagerGuide/source/preface.rst b/build/docs/RnRManagerGuide/source/preface.rst index 8cf390b3b..72e0656bb 100644 --- a/build/docs/RnRManagerGuide/source/preface.rst +++ b/build/docs/RnRManagerGuide/source/preface.rst @@ -45,7 +45,7 @@ of RnR Manager. Conventions *********** -The icons shown below are used in PrismTech product documentation +The icons shown below are used in Vortex product documentation to help readers to quickly identify information relevant to their specific use of Vortex OpenSplice. @@ -86,4 +86,4 @@ specific use of Vortex OpenSplice. .. |java| image:: ./images/icon-java.* :height: 6mm - \ No newline at end of file + diff --git a/build/docs/SecureNetworking/source/conf.py b/build/docs/SecureNetworking/source/conf.py index 8ccd20c0f..4b0292b93 100644 --- a/build/docs/SecureNetworking/source/conf.py +++ b/build/docs/SecureNetworking/source/conf.py @@ -63,9 +63,8 @@ def setup(app): # General information about the project. project = u'Secure Networking Configuration Guide' -#copyright = u'2015, PrismTech' this_year = time.strftime( '%Y' ) -copyright = u'{y}, PrismTech'.format( y = this_year ) +copyright = u'{y}, ADLINK Technology Limited'.format( y = this_year ) print 'Copyright string is:', copyright @@ -230,7 +229,7 @@ def setup(app): # Added 'True' to end of generated line to suppress 'Index & Tables' -# A dictionary that contains LaTeX snippets that override those Sphinx usually +# A dictionary that contains LaTeX snippets that override those Sphinx usually # puts into the generated .tex files. latex_elements = { 'babel': '\\usepackage[english]{babel}' } @@ -271,7 +270,7 @@ def setup(app): # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). -man_pages = [('index', 'Secure_Networking_Configuration_Guide', u'Secure_Networking_Configuration_Guide', [u'PrismTech'], 1)] +man_pages = [('index', 'Secure_Networking_Configuration_Guide', u'Secure_Networking_Configuration_Guide', [u'ADLINK Technology Limited'], 1)] # -- Additional options -------------------------------------------------------- diff --git a/build/docs/SecureNetworking/source/contacts.rst b/build/docs/SecureNetworking/source/contacts.rst index fc6442d3a..d32f6016f 100644 --- a/build/docs/SecureNetworking/source/contacts.rst +++ b/build/docs/SecureNetworking/source/contacts.rst @@ -1,53 +1 @@ -.. _`Contacts & Notices`: - -.. VERY LITTLE EVER CHANGES IN HERE !! - Just keep an eye on the copyright notice. - -################## -Contacts & Notices -################## - -******** -Contacts -******** - -| **PrismTech Corporation** -| 400 TradeCenter -| Suite 5900 -| Woburn, MA -| 01801 -| USA -| Tel: +1 781 569 5819 - -| **PrismTech Limited** -| PrismTech House -| 5th Avenue Business Park -| Gateshead -| NE11 0NG -| UK -| Tel: +44 (0)191 497 9900 - -| **PrismTech France** -| 28 rue Jean Rostand -| 91400 Orsay -| France -| Tel: +33 (1) 69 015354 - - -Web: http://www.prismtech.com - -E-mail: \info@prismtech.com - -******* -Notices -******* - -**Copyright** © 2016 PrismTech Limited. All rights reserved. - -*This document may be reproduced in whole but not in part. -The information contained in this document is subject to change -without notice and is made available in good faith without -liability on the part of PrismTech Limited or PrismTech Corporation. -All trademarks acknowledged.* - -.. END +.. include:: ../../common/contacts.rst diff --git a/build/docs/SecureNetworking/source/images/Vortex-OpenSplice-Cover.png b/build/docs/SecureNetworking/source/images/Vortex-OpenSplice-Cover.png index ce86c6d94..801c02bb8 100644 Binary files a/build/docs/SecureNetworking/source/images/Vortex-OpenSplice-Cover.png and b/build/docs/SecureNetworking/source/images/Vortex-OpenSplice-Cover.png differ diff --git a/build/docs/SecureNetworking/source/index.rst b/build/docs/SecureNetworking/source/index.rst index 331981dc7..4bba652d5 100644 --- a/build/docs/SecureNetworking/source/index.rst +++ b/build/docs/SecureNetworking/source/index.rst @@ -9,7 +9,7 @@ Secure Networking Configuration Guide .. toctree:: :maxdepth: 8 :numbered: - + preface overview securenetconfig @@ -17,9 +17,9 @@ Secure Networking Configuration Guide accesscontrol accessctrlconfig troubleshoot - - contacts - + + contacts + Indices and tables ================== diff --git a/build/docs/SecureNetworking/source/preface.rst b/build/docs/SecureNetworking/source/preface.rst index 1d0607483..b576a93aa 100644 --- a/build/docs/SecureNetworking/source/preface.rst +++ b/build/docs/SecureNetworking/source/preface.rst @@ -10,15 +10,15 @@ About The Secure Networking Configuration Guide *********************************************** The *Vortex OpenSplice Secure Networking Configuration Guide* -is intended to be a complete reference for configuring and managing the +is intended to be a complete reference for configuring and managing the Vortex OpenSplice Secure Networking Module. Intended Audience ***************** -The *Secure Networking Configuration Guide* -is the starting point for anyone who wishes to use and configure the +The *Secure Networking Configuration Guide* +is the starting point for anyone who wishes to use and configure the Vortex OpenSplice Secure Networking Module for securing information transmission between DDS applications across multiple system nodes. @@ -29,21 +29,21 @@ Organisation The *Guide* is organised as follows: -The :ref:`Overview ` provides an introduction to the secure +The :ref:`Overview ` provides an introduction to the secure networking module. :ref:`Secure Networking Configuration ` -describes how to configure the OpenSplice Secure Networking Module. +describes how to configure the Vortex OpenSplice Secure Networking Module. -The :ref:`Tutorial ` -gives a step-by-step example showing how to configure the -OpenSplice Secure Networking Module. +The :ref:`Tutorial ` +gives a step-by-step example showing how to configure the +Vortex OpenSplice Secure Networking Module. -The next section explains how :ref:`Access Control ` -is realized in OpenSplice. +The next section explains how :ref:`Access Control ` +is realized in Vortex OpenSplice. :ref:`Access Control Configuration ` -describes how to configure the OpenSplice Mandatory Access Control Module. +describes how to configure the Vortex OpenSplice Mandatory Access Control Module. Finally, the :ref:`Troubleshooting ` section provides information to help with the diagnosis of common @@ -53,24 +53,24 @@ security-related error messages and configuration problems. Conventions *********** -The icons shown below are used in PrismTech product documentation -to help readers to quickly identify information relevant to their -specific use of OpenSplice DDS. +The icons shown below are used in ADLINK product documentation +to help readers to quickly identify information relevant to their +specific use of Vortex OpenSplice. - ========= ================================================================== - *Icon* *Meaning* - ========= ================================================================== - |caution| Item of special significance or where caution needs to be taken. - |info| Item contains helpful hint or special information. - |windows| Information applies to Windows (*e.g.* XP, 2003, Windows 7) only. - |unix| Information applies to Unix-based systems (*e.g.* Solaris) only. - |linux| Information applies to Linux-based systems (*e.g.* Ubuntu) only. - |c| C language specific. - |cpp| C++ language specific. - |csharp| C# language specific. - |java| Java language specific. - ========= ================================================================== + ========= ================================================================== + *Icon* *Meaning* + ========= ================================================================== + |caution| Item of special significance or where caution needs to be taken. + |info| Item contains helpful hint or special information. + |windows| Information applies to Windows (*e.g.* XP, 2003, Windows 7) only. + |unix| Information applies to Unix-based systems (*e.g.* Solaris) only. + |linux| Information applies to Linux-based systems (*e.g.* Ubuntu) only. + |c| C language specific. + |cpp| C++ language specific. + |csharp| C# language specific. + |java| Java language specific. + ========= ================================================================== @@ -94,4 +94,4 @@ specific use of OpenSplice DDS. .. |java| image:: ./images/icon-java.* :height: 6mm - \ No newline at end of file + diff --git a/build/docs/SecureNetworking/source/securenettutorial.rst b/build/docs/SecureNetworking/source/securenettutorial.rst index 8160e1a1a..f5e66a4a1 100644 --- a/build/docs/SecureNetworking/source/securenettutorial.rst +++ b/build/docs/SecureNetworking/source/securenettutorial.rst @@ -5,44 +5,44 @@ Secure Networking Tutorial ########################## -*This tutorial demonstrates secure networking features of +*This tutorial demonstrates secure networking features of Vortex OpenSplice.* Prerequisites ************* -DDS applications on a single host use shared memory for inter -process communication. Network communication is needed only in -scenarios running DDS applications on multiple hosts. To follow -the demonstration of OpenSplice’s secure networking features you -will need at least two machines connected to the same IP network -and OpenSplice installed. Please refer to OpenSplice Getting +DDS applications on a single host use shared memory for inter +process communication. Network communication is needed only in +scenarios running DDS applications on multiple hosts. To follow +the demonstration of OpenSplice’s secure networking features you +will need at least two machines connected to the same IP network +and OpenSplice installed. Please refer to OpenSplice Getting Started Guide to install OpenSplice on these hosts. -This tutorial is based on the Chat Tutorial delivered with +This tutorial is based on the Chat Tutorial delivered with OpenSplice (see ``$OSPL_HOME/examples/dcps/standalone/*/Tutorial``). - -To demonstrate OpenSplice’s secure networking features, no -changes to the applications’ source code is necessary. Please -refer to the Chat Tutorial ``README.txt`` file and be familiar with -building and running the applications (of your preferred -programming language) before continuing. Please build and run -the Chat Tutorial applications on all hosts. A more in-depth -description of the Chat Tutorial can be found in the + +To demonstrate OpenSplice’s secure networking features, no +changes to the applications’ source code is necessary. Please +refer to the Chat Tutorial ``README.txt`` file and be familiar with +building and running the applications (of your preferred +programming language) before continuing. Please build and run +the Chat Tutorial applications on all hosts. A more in-depth +description of the Chat Tutorial can be found in the *DCPS C Tutorial Guide*. Preparation *********** -The Chat Tutorial gave a brief introduction to a typical DDS -application. +The Chat Tutorial gave a brief introduction to a typical DDS +application. -Before activating any security configurations you should know -how to start OpenSplice with a customized configuration. +Before activating any security configurations you should know +how to start OpenSplice with a customized configuration. |caution| -Modifying the default configuration is not recommended +Modifying the default configuration is not recommended because it might affect other users or applications. .. _`Customizing OpenSplice Configuration`: @@ -50,13 +50,13 @@ because it might affect other users or applications. Customizing OpenSplice Configuration ==================================== -Default settings for OpenSplice are read from a +Default settings for OpenSplice are read from a configuration file located at ``/etc/configs/ospl.xml``. - -To customize settings it is best to run OpenSplice using a + +To customize settings it is best to run OpenSplice using a *different* configuration file. -Create a file named ``ospl.xml`` with the content listed below in +Create a file named ``ospl.xml`` with the content listed below in the Chat Tutorial’s directory: :: @@ -79,11 +79,11 @@ the Chat Tutorial’s directory: - 3340 - 3350 @@ -95,73 +95,73 @@ the Chat Tutorial’s directory: |windows| -Windows users should change the value of the configuration +Windows users should change the value of the configuration element at ``OpenSplice/Domain/Service/Command`` to ``snetworking.exe``. Stop OpenSplice if it is already running. -To tell OpenSplice to use this file for configuration, the -system variable ``OSPL_URI`` has to be set with a file URI pointing +To tell OpenSplice to use this file for configuration, the +system variable ``OSPL_URI`` has to be set with a file URI pointing to the just-created configuration file. For example: -:: - +:: + % export OSPL_URI=file://ospl.xml -will point to a file named ``ospl.xml`` in the current working -directory and +will point to a file named ``ospl.xml`` in the current working +directory and :: - + % export OSPL_URI=file:///home/user/ospl.xml -will point to ``ospl.xml`` in a ``/home/user`` directory. Ensure that +will point to ``ospl.xml`` in a ``/home/user`` directory. Ensure that you have read and write permissions for the file pointed at. -Now start OpenSplice again. You will see that the status message +Now start OpenSplice again. You will see that the status message contains a new DDS domain name. -:: - +:: + % ospl start % Starting up domain "OpenSplice Security" . Ready -Note that when running OpenSplice with the configuration listed -above, each OpenSplice node will broadcast heartbeat messages -every second, targeting the UDP port 3360. +Note that when running OpenSplice with the configuration listed +above, each OpenSplice node will broadcast heartbeat messages +every second, targeting the UDP port 3360. -These messages are used to discover other OpenSplice nodes in -the network. Only when a second OpenSplice node has been -discovered in the network by heartbeats ChatRoom messages will -be broadcasted to the UDP target port 3340 (best effort) and -3350 (reliable). So, do not expect any ChatRoom messages to show -up in the network traces as long as you operate with a single -OpenSplice node. +These messages are used to discover other OpenSplice nodes in +the network. Only when a second OpenSplice node has been +discovered in the network by heartbeats ChatRoom messages will +be broadcasted to the UDP target port 3340 (best effort) and +3350 (reliable). So, do not expect any ChatRoom messages to show +up in the network traces as long as you operate with a single +OpenSplice node. Running Chat Tutorial Without Security ====================================== -Before securing the Chat Tutorial we will run the applications -without security activated by using the configuration presented -above. This way we can analyse network traffic and identify +Before securing the Chat Tutorial we will run the applications +without security activated by using the configuration presented +above. This way we can analyse network traffic and identify potential vulnerabilities. Run the MessageBoard application on one host by executing: :: - + % ./exec/MessageBoard On the other host run the Chatter application by executing: -:: - +:: + % ./exec/Chatter The MessageBoard application will print the following output: -:: - +:: + % Chatter 1: Hi there, I will send you 10 more messages. % Chatter 1: Message no. 1 % Chatter 1: Message no. 2 @@ -169,16 +169,16 @@ The MessageBoard application will print the following output: % … |caution| -If running the applications in another shell, ensure that the -system variable ``OSPL_URI`` points to the same configuration file -as indicated above when starting OpenSplice. Otherwise the +If running the applications in another shell, ensure that the +system variable ``OSPL_URI`` points to the same configuration file +as indicated above when starting OpenSplice. Otherwise the applications won’t start up correctly. -To analyse network traffic you may use a tool like Wireshark [#]_. -Re-run the Chatter application with Wireshark capturing traffic -from your network interface. You should see some UDP packets -being captured. Analysing packets sent to UDP port 3350 shows -the plain text content of our Chat Tutorial messages as you can +To analyse network traffic you may use a tool like Wireshark [#]_. +Re-run the Chatter application with Wireshark capturing traffic +from your network interface. You should see some UDP packets +being captured. Analysing packets sent to UDP port 3350 shows +the plain text content of our Chat Tutorial messages as you can see in the following screen: .. _`OSPL Sniff Showing Unencrypted Traffic`: @@ -195,8 +195,8 @@ see in the following screen: Activating Secure Networking **************************** -At this point the Chat Tutorial applications should work fine -using your own configuration file on both hosts. Up to now all +At this point the Chat Tutorial applications should work fine +using your own configuration file on both hosts. Up to now all network traffic is sent unencrypted as you can see in the illustration above (`OSPL Sniff Showing Unencrypted Traffic`_). @@ -204,15 +204,15 @@ illustration above (`OSPL Sniff Showing Unencrypted Traffic`_). Simple Setup Using GlobalPartition ================================== -To activate encryption, you must shut down the tutorial +To activate encryption, you must shut down the tutorial applications and OpenSplice before modifying the configuration file. - -Two steps have to be done for a simple setup. -*First*, add a new security profile to the network service -configuration. This defines details of encryption, like the +Two steps have to be done for a simple setup. + +*First*, add a new security profile to the network service +configuration. This defines details of encryption, like the algorithm and the secret cipher key to be used. - + :: @@ -220,16 +220,16 @@ algorithm and the secret cipher key to be used. … -*Second*, you have to associate this security profile with a -network partition. Enhance the existing global network partition -with a new attribute: ``SecurityProfile="GlobalProfile"``. All -network traffic sent by the global partition is encrypted using +*Second*, you have to associate this security profile with a +network partition. Enhance the existing global network partition +with a new attribute: ``SecurityProfile="GlobalProfile"``. All +network traffic sent by the global partition is encrypted using settings from the assigned security profile. :: @@ -244,14 +244,14 @@ settings from the assigned security profile. … -As an alternative to modifying the configuration file as -described above, you can use the complete example configuration -listed below for setup. To avoid problems, ensure that all hosts -use the same configuration. Restarting OpenSplice and the Chat -Tutorial applications using the modified configuration will -enable encrypted network traffic. Again, you may use Wireshark -to analyse messages sent through the network. As you can see in -the screen shown below, it is not possible to read plain text +As an alternative to modifying the configuration file as +described above, you can use the complete example configuration +listed below for setup. To avoid problems, ensure that all hosts +use the same configuration. Restarting OpenSplice and the Chat +Tutorial applications using the modified configuration will +enable encrypted network traffic. Again, you may use Wireshark +to analyse messages sent through the network. As you can see in +the screen shown below, it is not possible to read plain text from chat messages exchanged. .. _`OSPL Sniff Showing Encrypted Traffic`: @@ -285,16 +285,16 @@ from chat messages exchanged. SecurityProfile="GlobalProfile"/> - - 3340 - 3350 @@ -305,48 +305,48 @@ from chat messages exchanged. -If the cipher key is changed in the configuration of only one -host (ensure that the key-length is kept the same) and -OpenSplice and the Chat Tutorial applications are restarted you -will notice that messages sent by the Chatter application won’t -reach the MessageBoard running on the other host. On the -receiving host a warning message will be logged in the -``ospl-info.log`` file. This file is located in the start-up +If the cipher key is changed in the configuration of only one +host (ensure that the key-length is kept the same) and +OpenSplice and the Chat Tutorial applications are restarted you +will notice that messages sent by the Chatter application won’t +reach the MessageBoard running on the other host. On the +receiving host a warning message will be logged in the +``ospl-info.log`` file. This file is located in the start-up directory, by default. :: - + ### Report Message ### Type : WARNING - Context : networking + Context : networking nw_plugReceiveChannelReadSocketNonBlocking File : ../../code/nw_plugReceiveChannel.c Line : 1560 Code : 0 Description : decoding failed - Node : shark1.de.prismtech.com + Node : shark1 Process : networking (5338) Thread : Discovery[@enabled!='false'] b7d1dbb0 Timestamp : 1184225057.899220000 (Thu Jul 12 09:24:17 2007) - + |caution| -Before following the instructions in the next section, please -restore the correct cipher-keys and restart the OpenSplice +Before following the instructions in the next section, please +restore the correct cipher-keys and restart the OpenSplice services. Advanced Setup Using Network Partitions ======================================= -In OpenSplice, ``DDS topics`` and ``DDS partitions`` can be mapped -onto additional network partitions. This allows the separation of -network traffic between different applications sharing the same -DDS domain. OpenSplice secure networking enables you to use -different cipher keys for each network partition to enable -confidentiality and integrity of the data exchanged between -different applications. For example, the following declaration -maps all topics from *ChatRoom* partition onto a dedicated -*ChatRoom network partition* using an exclusive multicast address -instead of using the *GlobalPartition*: +In OpenSplice, ``DDS topics`` and ``DDS partitions`` can be mapped +onto additional network partitions. This allows the separation of +network traffic between different applications sharing the same +DDS domain. OpenSplice secure networking enables you to use +different cipher keys for each network partition to enable +confidentiality and integrity of the data exchanged between +different applications. For example, the following declaration +maps all topics from *ChatRoom* partition onto a dedicated +*ChatRoom network partition* using an exclusive multicast address +instead of using the *GlobalPartition*: :: @@ -367,7 +367,7 @@ instead of using the *GlobalPartition*: - @@ -375,26 +375,26 @@ instead of using the *GlobalPartition*: -With the security feature enabled, the global partition and each -network partition can be associated with its own security -profile. In our example we refer to *GlobalProfile* and -*ChatRoomProfile*. Each security profile defines the cipher to be -used. The ``NULL`` cipher used in *GlobalProfile* may be used for -debugging purposes or for single topics/partitions that do not +With the security feature enabled, the global partition and each +network partition can be associated with its own security +profile. In our example we refer to *GlobalProfile* and +*ChatRoomProfile*. Each security profile defines the cipher to be +used. The ``NULL`` cipher used in *GlobalProfile* may be used for +debugging purposes or for single topics/partitions that do not require protection. -The configuration sample above also demonstrates the cipher keys -may be stored in an external file too. The key within the file -is encoded as a hexadecimal-string, in other words a 16-Byte key -is formed of 32 characters, for example: -``0f0e0d0c0b0a09080706050403020100``. External files are the -preferred way to store keys, to keep them confidential. +The configuration sample above also demonstrates the cipher keys +may be stored in an external file too. The key within the file +is encoded as a hexadecimal-string, in other words a 16-Byte key +is formed of 32 characters, for example: +``0f0e0d0c0b0a09080706050403020100``. External files are the +preferred way to store keys, to keep them confidential. |caution| -**Permissions for the key files should be set so that nobody -except the OpenSplice core services may read the files.** -Storing the keys in-place in the configuration file which is -read by each DDS application on start up would be a potential +**Permissions for the key files should be set so that nobody +except the OpenSplice core services may read the files.** +Storing the keys in-place in the configuration file which is +read by each DDS application on start up would be a potential leak of secret information. @@ -421,4 +421,3 @@ leak of secret information. .. |java| image:: ./images/icon-java.* :height: 6mm - \ No newline at end of file diff --git a/build/docs/StreamsAPIReference/source/API-ref.rst b/build/docs/StreamsAPIReference/source/API-ref.rst index bdd19306e..e5252160a 100644 --- a/build/docs/StreamsAPIReference/source/API-ref.rst +++ b/build/docs/StreamsAPIReference/source/API-ref.rst @@ -8,11 +8,11 @@ API Reference Introduction ************ -*As described in :ref:`Getting Started `, the OpenSplice +*As described in :ref:`Getting Started `, the Vortex OpenSplice IDL preprocessor generates typed Streams API classes for each type that is annotated with a streams pragma.* -As in the OpenSplice DDS *C++ Reference Guide*, the fictional type ``Foo``, +As in the Vortex OpenSplice *C++ Reference Guide*, the fictional type ``Foo``, defined in module Space, is used as an example. When the ``Foo`` type is annotated with a pragma streams, ``FooStreamDataWriter`` and ``FooStreamDataReader`` classes will be generated. @@ -176,7 +176,7 @@ Constructors Constructors cannot return a value, therefore they throw exceptions when the object cannot be constructed. Besides exceptions, the regular - OpenSplice error logging framework is used to report additional + Vortex OpenSplice error logging framework is used to report additional information when a constructor fails. The constructors throw a ``StreamsException`` if an error occurs. The @@ -319,7 +319,7 @@ flush ``RETCODE_PRECONDITION_NOT_MET`` A precondition failed; most likely the stream doesn’t exist. - See the OpenSplice DDS *C++ Reference Guide* for + See the Vortex OpenSplice *C++ Reference Guide* for possible result codes returned by a DDS ``write`` operation. get_qos @@ -491,7 +491,7 @@ Constructors Constructors cannot return a value, therefore they throw exceptions when the object cannot be constructed. Besides exceptions, the regular - OpenSplice error logging framework is used to report additional + Vortex OpenSplice error logging framework is used to report additional information when a constructor fails. The constructors throw a ``StreamsException`` if an error occurs. The @@ -617,7 +617,7 @@ get ``waitset.wait()`` returns a ``DDS::RETCODE_TIMEOUT``, this return code is translated to a ``DDS::RETCODE_NO_DATA`` return code. - See the OpenSplice DDS *C++ Reference Guide* for possible result + See the Vortex OpenSplice *C++ Reference Guide* for possible result codes returned by a DDS ``take_instance`` operation and for ``waitset.wait()``. @@ -706,7 +706,7 @@ get_w_filter ``waitset.wait()`` returns a ``DDS::RETCODE_TIMEOUT``, this return code is translated to a ``DDS::RETCODE_NO_DATA`` return code. - See the OpenSplice DDS *C++ Reference Guide* for possible result codes + See the Vortex OpenSplice *C++ Reference Guide* for possible result codes returned by a DDS ``take_instance`` operation and ``waitset.wait()``. return_loan diff --git a/build/docs/StreamsAPIReference/source/conf.py b/build/docs/StreamsAPIReference/source/conf.py index 623356788..74596bb19 100644 --- a/build/docs/StreamsAPIReference/source/conf.py +++ b/build/docs/StreamsAPIReference/source/conf.py @@ -63,9 +63,8 @@ def setup(app): # General information about the project. project = u'StreamsAPIReference' -#copyright = u'2015, PrismTech' this_year = time.strftime( '%Y' ) -copyright = u'{y}, PrismTech'.format( y = this_year ) +copyright = u'{y}, ADLINK Technology Limited'.format( y = this_year ) print 'Copyright string is:', copyright @@ -230,7 +229,7 @@ def setup(app): # Added 'True' to end of generated line to suppress 'Index & Tables' -# A dictionary that contains LaTeX snippets that override those Sphinx usually +# A dictionary that contains LaTeX snippets that override those Sphinx usually # puts into the generated .tex files. latex_elements = { 'babel': '\\usepackage[english]{babel}' } @@ -271,7 +270,7 @@ def setup(app): # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). -man_pages = [('index', 'Streams_API_Reference_Guide', u'Streams_API_Reference_Guide', [u'PrismTech'], 1)] +man_pages = [('index', 'Streams_API_Reference_Guide', u'Streams_API_Reference_Guide', [u'ADLINK Technology Limited'], 1)] # -- Additional options -------------------------------------------------------- diff --git a/build/docs/StreamsAPIReference/source/contacts.rst b/build/docs/StreamsAPIReference/source/contacts.rst index fc6442d3a..d32f6016f 100644 --- a/build/docs/StreamsAPIReference/source/contacts.rst +++ b/build/docs/StreamsAPIReference/source/contacts.rst @@ -1,53 +1 @@ -.. _`Contacts & Notices`: - -.. VERY LITTLE EVER CHANGES IN HERE !! - Just keep an eye on the copyright notice. - -################## -Contacts & Notices -################## - -******** -Contacts -******** - -| **PrismTech Corporation** -| 400 TradeCenter -| Suite 5900 -| Woburn, MA -| 01801 -| USA -| Tel: +1 781 569 5819 - -| **PrismTech Limited** -| PrismTech House -| 5th Avenue Business Park -| Gateshead -| NE11 0NG -| UK -| Tel: +44 (0)191 497 9900 - -| **PrismTech France** -| 28 rue Jean Rostand -| 91400 Orsay -| France -| Tel: +33 (1) 69 015354 - - -Web: http://www.prismtech.com - -E-mail: \info@prismtech.com - -******* -Notices -******* - -**Copyright** © 2016 PrismTech Limited. All rights reserved. - -*This document may be reproduced in whole but not in part. -The information contained in this document is subject to change -without notice and is made available in good faith without -liability on the part of PrismTech Limited or PrismTech Corporation. -All trademarks acknowledged.* - -.. END +.. include:: ../../common/contacts.rst diff --git a/build/docs/StreamsAPIReference/source/images/Vortex-OpenSplice-Cover.png b/build/docs/StreamsAPIReference/source/images/Vortex-OpenSplice-Cover.png index ce86c6d94..801c02bb8 100644 Binary files a/build/docs/StreamsAPIReference/source/images/Vortex-OpenSplice-Cover.png and b/build/docs/StreamsAPIReference/source/images/Vortex-OpenSplice-Cover.png differ diff --git a/build/docs/StreamsAPIReference/source/index.rst b/build/docs/StreamsAPIReference/source/index.rst index af5994067..63574373d 100644 --- a/build/docs/StreamsAPIReference/source/index.rst +++ b/build/docs/StreamsAPIReference/source/index.rst @@ -9,13 +9,13 @@ The Streams API Reference Guide .. toctree:: :maxdepth: 6 :numbered: - + preface introduction API-ref - - contacts - + + contacts + Indices and tables ================== diff --git a/build/docs/StreamsAPIReference/source/introduction.rst b/build/docs/StreamsAPIReference/source/introduction.rst index 47eee663d..77a5c1ec0 100644 --- a/build/docs/StreamsAPIReference/source/introduction.rst +++ b/build/docs/StreamsAPIReference/source/introduction.rst @@ -23,14 +23,14 @@ Getting Started The Vortex OpenSplice Streams API is divided in two main components: -+ type-specific code that can be generated using the OpenSplice ++ type-specific code that can be generated using the Vortex OpenSplice IDL Pre-Processor + a Streams library. Applications that wish to use the Streams API are required to do two things: -1. Link against *one* of the OpenSplice Streams libraries available +1. Link against *one* of the Vortex OpenSplice Streams libraries available within the Vortex OpenSplice distribution. There are separate libraries for either *CORBA-Cohabitation* mode or *Standalone C++* mode. @@ -81,7 +81,7 @@ model for ``Foo``: It is recommended to use smart references to the ``StreamDataWriter`` and ``StreamDataReader`` classes in applications. The regular Vortex OpenSplice C++ smart-pointer ``_var`` types are available for this purpose. See -the section on *Memory Management* in the Vortex OpenSplice DDS *C++ Reference +the section on *Memory Management* in the Vortex OpenSplice *C++ Reference Guide* for more information. CORBA Cohabitation Mode @@ -96,7 +96,7 @@ First ``idlpp`` is executed on the ``Space.idl`` file: $ idlpp -I$OSPL_HOME/etc/idl -l cpp -C Space.idl -The standard Vortex OpenSplice DDS IDL directory is referenced as ``include-path``, +The standard Vortex OpenSplice IDL directory is referenced as ``include-path``, since it contains definitions of some basic data-types and interfaces that are required if DDS Topics are created for any of the types in the IDL file. The other parameters are used to put ``idlpp`` in C++ @@ -125,7 +125,7 @@ Standalone Mode In *Standalone C++* mode, the generated interfaces are *not* required to be processed by an IDL compiler. Instead, ``idlpp`` will use the ``cppgen`` -code-generator that is part of the Vortex OpenSplice DDS distribution. ``idlpp`` +code-generator that is part of the Vortex OpenSplice distribution. ``idlpp`` will automatically call ``cppgen`` to process certain files; the user is only required to execute ``idlpp``, first on the original IDL file: @@ -168,4 +168,4 @@ streams, interfaces should not be ignored. .. |java| image:: ./images/icon-java.* :height: 6mm - \ No newline at end of file + diff --git a/build/docs/StreamsAPIReference/source/preface.rst b/build/docs/StreamsAPIReference/source/preface.rst index 6e9efdb62..57f9aead6 100644 --- a/build/docs/StreamsAPIReference/source/preface.rst +++ b/build/docs/StreamsAPIReference/source/preface.rst @@ -22,8 +22,8 @@ Intended Audience The *Streams API Reference Guide* is intended to be used by C++ programmers who are using the OpenSplice Streams API to develop -applications. While not strictly required, it is assumed that the -reader has a basic understanding of the DDS C++ API as detailed +applications. While not strictly required, it is assumed that the +reader has a basic understanding of the DDS C++ API as detailed in the Vortex OpenSplice *C++ Reference Guide*. Organisation @@ -31,36 +31,36 @@ Organisation This *Guide* is organised in two parts. -The :ref:`Introduction ` provides some background -information about the features of the Streams API and how to use -them. It also gives a broad overview of all entities and relations +The :ref:`Introduction ` provides some background +information about the features of the Streams API and how to use +them. It also gives a broad overview of all entities and relations between entities in the Streams API. -The :ref:`API Reference ` provides detailed +The :ref:`API Reference ` provides detailed descriptions of all of the classes and operations of the Streams API. Conventions *********** -The icons shown below are used in PrismTech product documentation -to help readers to quickly identify information relevant to their +The icons shown below are used in ADLINK product documentation +to help readers to quickly identify information relevant to their specific use of Vortex OpenSplice. - ========= ================================================================== - *Icon* *Meaning* - ========= ================================================================== - |caution| Item of special significance or where caution needs to be taken. - |info| Item contains helpful hint or special information. - |windows| Information applies to Windows (*e.g.* XP, 2003, Windows 7) only. - |unix| Information applies to Unix-based systems (*e.g.* Solaris) only. - |linux| Information applies to Linux-based systems (*e.g.* Ubuntu) only. - |c| C language specific. - |cpp| C++ language specific. - |csharp| C# language specific. - |java| Java language specific. - ========= ================================================================== + ========= ================================================================== + *Icon* *Meaning* + ========= ================================================================== + |caution| Item of special significance or where caution needs to be taken. + |info| Item contains helpful hint or special information. + |windows| Information applies to Windows (*e.g.* XP, 2003, Windows 7) only. + |unix| Information applies to Unix-based systems (*e.g.* Solaris) only. + |linux| Information applies to Linux-based systems (*e.g.* Ubuntu) only. + |c| C language specific. + |cpp| C++ language specific. + |csharp| C# language specific. + |java| Java language specific. + ========= ================================================================== @@ -84,4 +84,3 @@ specific use of Vortex OpenSplice. .. |java| image:: ./images/icon-java.* :height: 6mm - \ No newline at end of file diff --git a/build/docs/TesterUserGuide/source/conf.py b/build/docs/TesterUserGuide/source/conf.py index 96b70bc57..0952ff4d5 100644 --- a/build/docs/TesterUserGuide/source/conf.py +++ b/build/docs/TesterUserGuide/source/conf.py @@ -63,9 +63,8 @@ def setup(app): # General information about the project. project = u'Test Tool User Guide' -#copyright = u'2015, PrismTech' this_year = time.strftime( '%Y' ) -copyright = u'{y}, PrismTech'.format( y = this_year ) +copyright = u'{y}, ADLINK Technology Limited'.format( y = this_year ) print 'Copyright string is:', copyright @@ -230,7 +229,7 @@ def setup(app): # Added 'True' to end of generated line to suppress 'Index & Tables' -# A dictionary that contains LaTeX snippets that override those Sphinx usually +# A dictionary that contains LaTeX snippets that override those Sphinx usually # puts into the generated .tex files. latex_elements = { 'babel': '\\usepackage[english]{babel}' } @@ -271,7 +270,7 @@ def setup(app): # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). -man_pages = [('index', 'Tester_User_Guide', u'Tester_User_Guide', [u'PrismTech'], 1)] +man_pages = [('index', 'Tester_User_Guide', u'Tester_User_Guide', [u'ADLINK Technology Limited'], 1)] # -- Additional options -------------------------------------------------------- diff --git a/build/docs/TesterUserGuide/source/contacts.rst b/build/docs/TesterUserGuide/source/contacts.rst index fc6442d3a..d32f6016f 100644 --- a/build/docs/TesterUserGuide/source/contacts.rst +++ b/build/docs/TesterUserGuide/source/contacts.rst @@ -1,53 +1 @@ -.. _`Contacts & Notices`: - -.. VERY LITTLE EVER CHANGES IN HERE !! - Just keep an eye on the copyright notice. - -################## -Contacts & Notices -################## - -******** -Contacts -******** - -| **PrismTech Corporation** -| 400 TradeCenter -| Suite 5900 -| Woburn, MA -| 01801 -| USA -| Tel: +1 781 569 5819 - -| **PrismTech Limited** -| PrismTech House -| 5th Avenue Business Park -| Gateshead -| NE11 0NG -| UK -| Tel: +44 (0)191 497 9900 - -| **PrismTech France** -| 28 rue Jean Rostand -| 91400 Orsay -| France -| Tel: +33 (1) 69 015354 - - -Web: http://www.prismtech.com - -E-mail: \info@prismtech.com - -******* -Notices -******* - -**Copyright** © 2016 PrismTech Limited. All rights reserved. - -*This document may be reproduced in whole but not in part. -The information contained in this document is subject to change -without notice and is made available in good faith without -liability on the part of PrismTech Limited or PrismTech Corporation. -All trademarks acknowledged.* - -.. END +.. include:: ../../common/contacts.rst diff --git a/build/docs/TesterUserGuide/source/familiarization.rst b/build/docs/TesterUserGuide/source/familiarization.rst index 57073d869..a9f8ec868 100644 --- a/build/docs/TesterUserGuide/source/familiarization.rst +++ b/build/docs/TesterUserGuide/source/familiarization.rst @@ -25,8 +25,8 @@ Step 2: Start the Tester: + On Linux, run ``ospltest``. -+ On Windows, choose Vortex OpenSplice Tester from the *Start* menu - or run ``ospltest`` from the Vortex OpenSplice command prompt. ++ On Windows, choose Launcher from the *Start* menu. In the Launcher *Tools* tab, click on the *Tester* button. + Or run ``ospltest`` from a command prompt. .. _`Starting Tester`: diff --git a/build/docs/TesterUserGuide/source/images/001_mainwindow.png b/build/docs/TesterUserGuide/source/images/001_mainwindow.png index b98b500ba..36b858db0 100644 Binary files a/build/docs/TesterUserGuide/source/images/001_mainwindow.png and b/build/docs/TesterUserGuide/source/images/001_mainwindow.png differ diff --git a/build/docs/TesterUserGuide/source/images/010_statistics.png b/build/docs/TesterUserGuide/source/images/010_statistics.png index 757b887fb..0960631ad 100644 Binary files a/build/docs/TesterUserGuide/source/images/010_statistics.png and b/build/docs/TesterUserGuide/source/images/010_statistics.png differ diff --git a/build/docs/TesterUserGuide/source/images/011_browser.png b/build/docs/TesterUserGuide/source/images/011_browser.png index 5c447f61b..c1354db90 100644 Binary files a/build/docs/TesterUserGuide/source/images/011_browser.png and b/build/docs/TesterUserGuide/source/images/011_browser.png differ diff --git a/build/docs/TesterUserGuide/source/images/012_editscript.png b/build/docs/TesterUserGuide/source/images/012_editscript.png index bc2cee0bd..ff9c5a94c 100644 Binary files a/build/docs/TesterUserGuide/source/images/012_editscript.png and b/build/docs/TesterUserGuide/source/images/012_editscript.png differ diff --git a/build/docs/TesterUserGuide/source/images/020_start.png b/build/docs/TesterUserGuide/source/images/020_start.png old mode 100644 new mode 100755 index f8f740fb9..9972a548e Binary files a/build/docs/TesterUserGuide/source/images/020_start.png and b/build/docs/TesterUserGuide/source/images/020_start.png differ diff --git a/build/docs/TesterUserGuide/source/images/021_connect_a.png b/build/docs/TesterUserGuide/source/images/021_connect_a.png index fb9e8748b..b6404424b 100644 Binary files a/build/docs/TesterUserGuide/source/images/021_connect_a.png and b/build/docs/TesterUserGuide/source/images/021_connect_a.png differ diff --git a/build/docs/TesterUserGuide/source/images/022_connect_b.png b/build/docs/TesterUserGuide/source/images/022_connect_b.png index 9d42d8113..48baee02f 100644 Binary files a/build/docs/TesterUserGuide/source/images/022_connect_b.png and b/build/docs/TesterUserGuide/source/images/022_connect_b.png differ diff --git a/build/docs/TesterUserGuide/source/images/024_readerfromtopic.png b/build/docs/TesterUserGuide/source/images/024_readerfromtopic.png index 765caa3d4..858d77cda 100644 Binary files a/build/docs/TesterUserGuide/source/images/024_readerfromtopic.png and b/build/docs/TesterUserGuide/source/images/024_readerfromtopic.png differ diff --git a/build/docs/TesterUserGuide/source/images/026_readerfromfilemenu.png b/build/docs/TesterUserGuide/source/images/026_readerfromfilemenu.png index 45becaf1c..b72c94fe7 100644 Binary files a/build/docs/TesterUserGuide/source/images/026_readerfromfilemenu.png and b/build/docs/TesterUserGuide/source/images/026_readerfromfilemenu.png differ diff --git a/build/docs/TesterUserGuide/source/images/027_addmultiplereaders.png b/build/docs/TesterUserGuide/source/images/027_addmultiplereaders.png index ad1994cb2..8d8498f8e 100644 Binary files a/build/docs/TesterUserGuide/source/images/027_addmultiplereaders.png and b/build/docs/TesterUserGuide/source/images/027_addmultiplereaders.png differ diff --git a/build/docs/TesterUserGuide/source/images/031_extrafieldsadded.png b/build/docs/TesterUserGuide/source/images/031_extrafieldsadded.png index bf8d626b5..2a23a435c 100644 Binary files a/build/docs/TesterUserGuide/source/images/031_extrafieldsadded.png and b/build/docs/TesterUserGuide/source/images/031_extrafieldsadded.png differ diff --git a/build/docs/TesterUserGuide/source/images/032_comparesamples.png b/build/docs/TesterUserGuide/source/images/032_comparesamples.png index 3cbcec2ea..2091de0ab 100644 Binary files a/build/docs/TesterUserGuide/source/images/032_comparesamples.png and b/build/docs/TesterUserGuide/source/images/032_comparesamples.png differ diff --git a/build/docs/TesterUserGuide/source/images/033_unfilteredtopics.png b/build/docs/TesterUserGuide/source/images/033_unfilteredtopics.png index 1cee8ac9c..7f025c10e 100644 Binary files a/build/docs/TesterUserGuide/source/images/033_unfilteredtopics.png and b/build/docs/TesterUserGuide/source/images/033_unfilteredtopics.png differ diff --git a/build/docs/TesterUserGuide/source/images/034_samplelistbytopic.png b/build/docs/TesterUserGuide/source/images/034_samplelistbytopic.png index b4c5a652f..0695fa1f3 100644 Binary files a/build/docs/TesterUserGuide/source/images/034_samplelistbytopic.png and b/build/docs/TesterUserGuide/source/images/034_samplelistbytopic.png differ diff --git a/build/docs/TesterUserGuide/source/images/035_listbytopicandkey.png b/build/docs/TesterUserGuide/source/images/035_listbytopicandkey.png index 7b7f0fe8b..e01978458 100644 Binary files a/build/docs/TesterUserGuide/source/images/035_listbytopicandkey.png and b/build/docs/TesterUserGuide/source/images/035_listbytopicandkey.png differ diff --git a/build/docs/TesterUserGuide/source/images/036_listbystate.png b/build/docs/TesterUserGuide/source/images/036_listbystate.png index dd5a5c5c7..2e0eeea7a 100644 Binary files a/build/docs/TesterUserGuide/source/images/036_listbystate.png and b/build/docs/TesterUserGuide/source/images/036_listbystate.png differ diff --git a/build/docs/TesterUserGuide/source/images/037_listbykeyvalue.png b/build/docs/TesterUserGuide/source/images/037_listbykeyvalue.png index 45e7923d6..1e06a6576 100644 Binary files a/build/docs/TesterUserGuide/source/images/037_listbykeyvalue.png and b/build/docs/TesterUserGuide/source/images/037_listbykeyvalue.png differ diff --git a/build/docs/TesterUserGuide/source/images/038_listbycolmtext.png b/build/docs/TesterUserGuide/source/images/038_listbycolmtext.png index cf6c5a4d1..a97e9f50f 100644 Binary files a/build/docs/TesterUserGuide/source/images/038_listbycolmtext.png and b/build/docs/TesterUserGuide/source/images/038_listbycolmtext.png differ diff --git a/build/docs/TesterUserGuide/source/images/040_colmdeleted.png b/build/docs/TesterUserGuide/source/images/040_colmdeleted.png index d800739be..787470a45 100644 Binary files a/build/docs/TesterUserGuide/source/images/040_colmdeleted.png and b/build/docs/TesterUserGuide/source/images/040_colmdeleted.png differ diff --git a/build/docs/TesterUserGuide/source/images/042_disposealive.png b/build/docs/TesterUserGuide/source/images/042_disposealive.png index 0f3cd3fd7..bd258cbe5 100644 Binary files a/build/docs/TesterUserGuide/source/images/042_disposealive.png and b/build/docs/TesterUserGuide/source/images/042_disposealive.png differ diff --git a/build/docs/TesterUserGuide/source/images/044_browser.png b/build/docs/TesterUserGuide/source/images/044_browser.png index ba7aa89f1..047610f59 100644 Binary files a/build/docs/TesterUserGuide/source/images/044_browser.png and b/build/docs/TesterUserGuide/source/images/044_browser.png differ diff --git a/build/docs/TesterUserGuide/source/images/045_tableupdated.png b/build/docs/TesterUserGuide/source/images/045_tableupdated.png index 7969cf601..82f1cd16d 100644 Binary files a/build/docs/TesterUserGuide/source/images/045_tableupdated.png and b/build/docs/TesterUserGuide/source/images/045_tableupdated.png differ diff --git a/build/docs/TesterUserGuide/source/images/046_readerdeleted.png b/build/docs/TesterUserGuide/source/images/046_readerdeleted.png index a2a7f492c..c18c50976 100644 Binary files a/build/docs/TesterUserGuide/source/images/046_readerdeleted.png and b/build/docs/TesterUserGuide/source/images/046_readerdeleted.png differ diff --git a/build/docs/TesterUserGuide/source/images/047_selectreader.png b/build/docs/TesterUserGuide/source/images/047_selectreader.png index 858b590c7..0eda85cad 100644 Binary files a/build/docs/TesterUserGuide/source/images/047_selectreader.png and b/build/docs/TesterUserGuide/source/images/047_selectreader.png differ diff --git a/build/docs/TesterUserGuide/source/images/048_selectreaderboo.png b/build/docs/TesterUserGuide/source/images/048_selectreaderboo.png index b8acd45c8..a5ef3add3 100644 Binary files a/build/docs/TesterUserGuide/source/images/048_selectreaderboo.png and b/build/docs/TesterUserGuide/source/images/048_selectreaderboo.png differ diff --git a/build/docs/TesterUserGuide/source/images/049_selectreaderhoo.png b/build/docs/TesterUserGuide/source/images/049_selectreaderhoo.png index 23474171c..46d9c89ec 100644 Binary files a/build/docs/TesterUserGuide/source/images/049_selectreaderhoo.png and b/build/docs/TesterUserGuide/source/images/049_selectreaderhoo.png differ diff --git a/build/docs/TesterUserGuide/source/images/050_disposedparticipants.png b/build/docs/TesterUserGuide/source/images/050_disposedparticipants.png index b747e47e2..254a6cfec 100644 Binary files a/build/docs/TesterUserGuide/source/images/050_disposedparticipants.png and b/build/docs/TesterUserGuide/source/images/050_disposedparticipants.png differ diff --git a/build/docs/TesterUserGuide/source/images/051_statistics.png b/build/docs/TesterUserGuide/source/images/051_statistics.png index de21a9352..6eb8e6618 100644 Binary files a/build/docs/TesterUserGuide/source/images/051_statistics.png and b/build/docs/TesterUserGuide/source/images/051_statistics.png differ diff --git a/build/docs/TesterUserGuide/source/images/052_codecompletesend.png b/build/docs/TesterUserGuide/source/images/052_codecompletesend.png index 5877baa3d..fb58ad8c9 100644 Binary files a/build/docs/TesterUserGuide/source/images/052_codecompletesend.png and b/build/docs/TesterUserGuide/source/images/052_codecompletesend.png differ diff --git a/build/docs/TesterUserGuide/source/images/053_codecompletecheck.png b/build/docs/TesterUserGuide/source/images/053_codecompletecheck.png index 2f21bdcb4..c1f08a6d1 100644 Binary files a/build/docs/TesterUserGuide/source/images/053_codecompletecheck.png and b/build/docs/TesterUserGuide/source/images/053_codecompletecheck.png differ diff --git a/build/docs/TesterUserGuide/source/images/054_debugging.png b/build/docs/TesterUserGuide/source/images/054_debugging.png index aafa18ab9..e083cd8f7 100644 Binary files a/build/docs/TesterUserGuide/source/images/054_debugging.png and b/build/docs/TesterUserGuide/source/images/054_debugging.png differ diff --git a/build/docs/TesterUserGuide/source/images/060_OsplTestTopic.png b/build/docs/TesterUserGuide/source/images/060_OsplTestTopic.png index 0cbefe500..4eb02e950 100644 Binary files a/build/docs/TesterUserGuide/source/images/060_OsplTestTopic.png and b/build/docs/TesterUserGuide/source/images/060_OsplTestTopic.png differ diff --git a/build/docs/TesterUserGuide/source/images/087_testifrunning.png b/build/docs/TesterUserGuide/source/images/087_testifrunning.png index e26bb2bcc..a08f8dd33 100644 Binary files a/build/docs/TesterUserGuide/source/images/087_testifrunning.png and b/build/docs/TesterUserGuide/source/images/087_testifrunning.png differ diff --git a/build/docs/TesterUserGuide/source/images/088_viewtopictype.png b/build/docs/TesterUserGuide/source/images/088_viewtopictype.png index 64021d839..b851277f1 100644 Binary files a/build/docs/TesterUserGuide/source/images/088_viewtopictype.png and b/build/docs/TesterUserGuide/source/images/088_viewtopictype.png differ diff --git a/build/docs/TesterUserGuide/source/images/Vortex-OpenSplice-Cover.png b/build/docs/TesterUserGuide/source/images/Vortex-OpenSplice-Cover.png index ce86c6d94..801c02bb8 100644 Binary files a/build/docs/TesterUserGuide/source/images/Vortex-OpenSplice-Cover.png and b/build/docs/TesterUserGuide/source/images/Vortex-OpenSplice-Cover.png differ diff --git a/build/docs/TesterUserGuide/source/index.rst b/build/docs/TesterUserGuide/source/index.rst index ce91ab66f..4ee61184c 100644 --- a/build/docs/TesterUserGuide/source/index.rst +++ b/build/docs/TesterUserGuide/source/index.rst @@ -9,7 +9,7 @@ The Vortex OpenSplice Tester User Guide .. toctree:: :maxdepth: 6 :numbered: - + preface introduction getstarted @@ -19,11 +19,11 @@ The Vortex OpenSplice Tester User Guide messageinterfaces gpbuffers pythonscripting - + appendixa - - contacts - + + contacts + Indices and tables ================== diff --git a/build/docs/TesterUserGuide/source/preface.rst b/build/docs/TesterUserGuide/source/preface.rst index af6b6b9e3..dcf2547d4 100644 --- a/build/docs/TesterUserGuide/source/preface.rst +++ b/build/docs/TesterUserGuide/source/preface.rst @@ -60,7 +60,7 @@ for reference. Conventions *********** -The icons shown below are used in PrismTech product documentation +The icons shown below are used in the Vortex product documentation to help readers to quickly identify information relevant to their specific use of Vortex OpenSplice. diff --git a/build/docs/TesterUserGuide/source/pythonscripting.rst b/build/docs/TesterUserGuide/source/pythonscripting.rst index cbb507b4d..bf1ad39a8 100644 --- a/build/docs/TesterUserGuide/source/pythonscripting.rst +++ b/build/docs/TesterUserGuide/source/pythonscripting.rst @@ -43,13 +43,13 @@ Prerequisites A Java 7 or later runtime (JRE) is required. The JAVA_HOME environment variable must be set to the JRE installation directory. -Check that the following command yields a Java version of 1.7 or later. On Linux systems, use:: +Check that the following command yields a Java version of 1.7 or later:: - $JAVA_HOME/bin/java -version + #Linux + $JAVA_HOME/bin/java -version -On Windows systems, use:: - - %JAVA_HOME%\bin\java -version + #Windows + "%JAVA_HOME%\bin\java" -version Note that during the installation, it is assumed the the environment variable OSPL_HOME refers the the fully qualified path of the Vortex OpenSplice installation. @@ -61,50 +61,96 @@ The Tester Scripting package does not include the Jython scripting engine - it m Jython is an open source project licensed under the Python Software Foundation License Version 2 (http://www.jython.org/license.html). The license is OSI Approved (https://opensource.org/licenses/alphabetical). -Tester Scripting requires Jython 2.7.0 or later. Follow the following steps to download and install Jython: +Tester Scripting requires Jython 2.7.0 or later. Download the Jython 2.7.0 Installer from the Jython Download page (http://www.jython.org/downloads.html). -1. Download the Jython 2.7.0 Installer from the Jython Download page (http://www.jython.org/downloads.html). +Automated installation and configuration +----------------------------------------- +Once the Jython installer has been downloaded, the osplscript command can be used to install Jython in your +Vortex OpenSpice home directory. Follow the following steps: -2. Install Jython. It is recommended, but not necessary that Jython be installed in the $OSPL_HOME/jython directory (linux) or the %OSPL_HOME%\jython directory (Windows). The following command line will install the standard Jython distribution:: +1. Start a command prompt (Windows) or Terminal window (Linux). The Vortex OpenSplice Launcher can create a Console window that eliminates the need for the step 2. +2. Ensure that the OSPL_HOME environment variable is set by running the release script. On Linux run:: - # for Linux systems - $JAVA_HOME/bin/java -jar jython-installer-2.7.0.jar -s -d $OSPL_HOME/jython -t standard + #linux + source $OSPL_HOME/release.com + + #Windows + "%OSPL_HOME%\release.bat" + +3. Change to the directory containing the Jython 2.7.0 installer, jython-installer-2.7.0.jar +4. Enter the command:: + + osplscript + +5. The command will display a message similar to the following, and then prompt you to continue:: + + ************************************************************** + Your OSPL installation has not been configured for osplscript; + no Jython installation was found in the OSPL install directory: + + A jython installer has been found in the current directory. + Do you wish to install Jython and configure osplscript? [yes|no]: + +6. Enter 'yes' (without the quotes), and press Enter; osplscript will be configured. +7. When completed, the Jython interpreter will be started. Either type 'exit()' or continue on to verifying the installation with the instructions in the next secion. + +Manual installation and configuration +------------------------------------- - # For Windows Systems - "%JAVA_HOME%\bin\java" -jar jython-installer.2.7.0.jar -s -d "%OSPL_HOME%\jython" -t standard +If you do not want place a Jython interpreter in the OSPL_HOME directory, or if you already +have Jython interpreter installed in another location, you can use the following manual installation +and configuration procedure. -3. Change to the OSPL_HOME directory. +Install a Jython interpreter in a location of your choice +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +If you want to install Jython in another location, do the following steps: -4. Install the Tester Scripting python package. Use the following command:: +1. Start a command prompt (Windows) or Terminal window (Linux). +2. Ensure that your JAVA_HOME environment variable refers to an appropriate Java installation (Java 7 or later). +3. From the directory containing the downloaded Jython installer, enter the following command:: + + jython-installer-2.7.0.jar -s -d -t standard + +If you prefer, you can remove the (-s) option (silent install), in which case, a graphical installation +wizard will appear. Proceed through the wizard to select a 'Standard' installation. + +Configure the Jython interpreter with OSPLScript package +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +To your Jython interpreter for Python scripting, you must install the OSPLScript Python package. Follow these steps: + +1. Ensure that the Jython 'bin' directory in the system PATH environment variable. +2. Start a command prompt (Windows) or terminal window (Linux). The Vortex OpenSplice Launcher can create a Console window that eliminates the need for the step 3. +3. Ensure the Vortex OpenSplice environment variables are set by running the 'release' script. +4. Start the Jython easy_install program. The following command line will install the standard Jython distribution:: # for Linux systems - jython/bin/easy_install tools/scripting/OSPLScript-1.0.0.tar.gz + easy_install "$OSPL_HOME/tools/scripting/OSPLScript-1.0.0.tar.gz" # for Windows systems - jython\bin\easy_install tools\scripting\OSPLScript-1.0.0.tar.gz + easy_install "%OSPL_HOME%\tools\scripting\OSPLScript-1.0.0.zip" + +Once the package installation has completed, you may proceed with verifying the installation. Verifying the installation ========================== -The following steps will verify that the Jython installation is correctly configured. +The following steps will verify that the Jython installation is correctly configured. The following steps +are done from a command window: -1. Ensure OpenSplice is running by issuing the following command:: +1. Ensure that the Vortex OpenSplice environment variables are set by running the 'release' command script. +2. Ensure OpenSplice is running by issuing the following command:: ospl start -2. Start OpenSplice Tester to create some test topics used below:: +3. Start OpenSplice Tester to create some test topics used below:: ospltest -3. Start the Jython interpreter:: - - # for Linux systems - jython/bin/jython -Djava.ext.dirs=$OSPL_HOME/jar +4. Start the Jython interpreter:: - # for Windows systems - jython\bin\jython -Djava.ext.dirs=%OSPL_HOME%\jar + osplscript -4. Enter the following commands at the interpreter command prompt: +5. Enter the following commands at the interpreter command prompt: >>> from osplscript import dds >>> topic = dds.findTopic('OsplTestTopic') @@ -134,12 +180,18 @@ Prerequisites ============= This demo assumes a shell instance that has been initialized with the release.com script found in the OSPL installation directory. -In particular, the quick tour relies on the $OSPL_HOME, $OSPL_URI and $LD_LIBRARY_PATH variables being appropriately set. -To run the script, do the following:: - - cd OSPL-install-directory - . release.com - +In particular, the quick tour relies on the following environment variables be set: OSPL_HOME, OSPL_URI and LD_LIBRARY_PATH. +The easiest way to set these variables is to use the Vortex OpenSplice launcher to start a Console window. +Alternatively, run the 'release' script in your Vortex OpenSplice installation directory. To run the script, do the following:: + + # linux + cd OSPL-install-directory + . release.com + + # Windows + cd OSPL-install-directory + release.bat + Preliminaries ============= @@ -155,10 +207,9 @@ Tester is used to define topics used in the scripting engine, and to observe sam Writing and Reading samples =========================== -The instructions below assume that you have installed and configured Jython in $OSPL_HOME/jython. Start the OSPL Scripting engine:: - $OSPL_HOME/jython/bin/jython -Djava.ext.dirs=$OSPL_HOME/jar + osplscript You will see a standard start up banner from the Jython engine similar to the following:: @@ -267,21 +318,21 @@ OSPL Scripting implements DDS wait sets with read conditions, query conditions a available on a data reader. Here is a simple example: >>> from osplscript import dds - >>> + >>> # find the topic, create a data reader and wait set >>> topic = dds.findTopic('OsplTestTopic') >>> dr = dds.Reader(topic) >>> ws = dds.WaitSet() - >>> + >>> # create a read condition of Alive, NotRead, New samples >>> rc = dr.readCondition(dds.DataState().withAlive().withNotRead().withNew()) - >>> + >>> # attach the read condition to the wait set >>> ws.attachCondition(rc) - >>> + >>> # wait... >>> ws.waitForConditions() - >>> + >>> # waiting returned, we have a sample >>> sample = dr.take() >>> # do something with the sample @@ -298,11 +349,11 @@ A selector is created via a reader's newSelectBuilder() method. A 'select builde The following example creates a selector: >>> from osplscript import dds - >>> + >>> # find the topic, create a data reader >>> topic = dds.findTopic('OsplTestTopic') >>> dr = dds.Reader(topic) - >>> + >>> # create a selector for Alive, NotRead, New samples with 'index = 100' >>> selector = dr.newSelectBuilder().withAlive().withNotRead().withNew() \ >>> .content('index = 100').build() @@ -348,11 +399,11 @@ substitution parameters of the form {n}, where n is a zero-based index into an l For example, we could filter OsplTestTopic's index value to be between an upper and lower bound, and specify the query as follows: >>> from osplscript import dds - >>> + >>> # find the topic, create a data reader >>> topic = dds.findTopic('OsplTestTopic') >>> dr = dds.Reader(topic) - >>> + >>> # create a selector for Alive, NotRead, New samples with 'index = 100' >>> selector = dr.newSelectBuilder().withAlive().withNotRead().withNew() \ >>> .content('index >= {0} and index < {1}', ['100', '200']) \ @@ -403,14 +454,14 @@ To establish a publisher or subscriber with coherent access, use the Presentatio publisher or subscriber QoS: >>> from osplscript import dds, qos - >>> + >>> # create a presentation policy, enabling Group coherence and ordered access >>> groupPresentation = qos.Presentation().withCoherentAccess().withGroup() \ >>> .withOrderedAccess() - >>> + >>> # create a publisher with the policy >>> pub = dds.Publisher(qos.PublisherQos().withPolicy(groupPresentation)) - >>> + >>> # create a subscriber with the policy >>> sub = dds.Subscriber(qos.SubscriberQos().withPolicy(groupPresentation)) @@ -468,12 +519,12 @@ As a work around, attached status conditions from each of the subscriber's reade >>> # This will work >>> ws = dds.WaitSet() - >>> + >>> # do this for each reader (dr) you care about >>> sc = dr.statusCondition() >>> sc.setEnabledStatuses([status.DataAvailableStatus]) >>> ws.attachCondition(sc) - >>> + >>> ws.waitForConditions() Creating a unit test script @@ -522,7 +573,7 @@ Start by created a text file in your favourite editor. Call the file firstUnitTe This test case essentially repeats the test we created in the interpreter. To run the test, enter the following command in your shell command prompt:: - $OSPL_HOME/jython/bin/jython -Djava.ext.dirs=$OSPL_HOME/jar firstUnitTest.py + osplscript firstUnitTest.py The script engine will respond with output like the following:: @@ -541,7 +592,7 @@ The OsplTestTopic used above is simple. This section examines working with more As with the preceding examples, Tester should be running, as it creates the samples that are used in this example. If OSPL Scripting is not running, start it:: -$OSPL_HOME/jython/bin/jython -Djava.ext.dirs=$OSPL_HOME/jar + osplscript The use the following Python to find the OsplSequenceTopic DDS topic and create a Python class from it: @@ -618,11 +669,8 @@ Once PyDev is installed, you must configure it with the location of you Jython i 5. Enter a name for the Jython interpreter. Example: Tester Script 6. Browser for the jython.jar file in the root directory of the Tester Script Jython installation. 7. Click OK. -8. Still in the Preferences dialog on the PyDev > Interpreters > Jython interpreters page, select your -newly created interpreter entry in the upper list. Then click the **Environment** tab in the lower half -of the dialog. -9. Add the following environment variables: OSPL_HOME, OSPL_URI and LD_LIBRARY_PATH. Their values should -be the same as those found in your command line environment. +8. Still in the Preferences dialog on the PyDev > Interpreters > Jython interpreters page, select your newly created interpreter entry in the upper list. Then click the **Environment** tab in the lower half of the dialog. +9. Add the following environment variables: OSPL_HOME, OSPL_URI and LD_LIBRARY_PATH. Their values should be the same as those found in your command line environment. 10. Click the **Libraries** tab in the lower half of the dialog. 11. Click **New Folder** and browse for and select the **jar** directory under your Vortex OpenSplice installation directory. 12. Click **OK** to complete the folder selection. diff --git a/build/docs/TunerGuide/source/conf.py b/build/docs/TunerGuide/source/conf.py index 42ff606b7..0a0ef9ae7 100644 --- a/build/docs/TunerGuide/source/conf.py +++ b/build/docs/TunerGuide/source/conf.py @@ -63,9 +63,8 @@ def setup(app): # General information about the project. project = u'TunerGuide' -#copyright = u'2015, PrismTech' this_year = time.strftime( '%Y' ) -copyright = u'{y}, PrismTech'.format( y = this_year ) +copyright = u'{y}, ADLINK Technology Limited'.format( y = this_year ) print 'Copyright string is:', copyright @@ -230,7 +229,7 @@ def setup(app): # Added 'True' to end of generated line to suppress 'Index & Tables' -# A dictionary that contains LaTeX snippets that override those Sphinx usually +# A dictionary that contains LaTeX snippets that override those Sphinx usually # puts into the generated .tex files. latex_elements = { 'babel': '\\usepackage[english]{babel}' } @@ -271,7 +270,7 @@ def setup(app): # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). -man_pages = [('index', 'Tuner_Guide', u'Tuner_Guide', [u'PrismTech'], 1)] +man_pages = [('index', 'Tuner_Guide', u'Tuner_Guide', [u'ADLINK Technology Limited'], 1)] # -- Additional options -------------------------------------------------------- diff --git a/build/docs/TunerGuide/source/contacts.rst b/build/docs/TunerGuide/source/contacts.rst index fc6442d3a..d32f6016f 100644 --- a/build/docs/TunerGuide/source/contacts.rst +++ b/build/docs/TunerGuide/source/contacts.rst @@ -1,53 +1 @@ -.. _`Contacts & Notices`: - -.. VERY LITTLE EVER CHANGES IN HERE !! - Just keep an eye on the copyright notice. - -################## -Contacts & Notices -################## - -******** -Contacts -******** - -| **PrismTech Corporation** -| 400 TradeCenter -| Suite 5900 -| Woburn, MA -| 01801 -| USA -| Tel: +1 781 569 5819 - -| **PrismTech Limited** -| PrismTech House -| 5th Avenue Business Park -| Gateshead -| NE11 0NG -| UK -| Tel: +44 (0)191 497 9900 - -| **PrismTech France** -| 28 rue Jean Rostand -| 91400 Orsay -| France -| Tel: +33 (1) 69 015354 - - -Web: http://www.prismtech.com - -E-mail: \info@prismtech.com - -******* -Notices -******* - -**Copyright** © 2016 PrismTech Limited. All rights reserved. - -*This document may be reproduced in whole but not in part. -The information contained in this document is subject to change -without notice and is made available in good faith without -liability on the part of PrismTech Limited or PrismTech Corporation. -All trademarks acknowledged.* - -.. END +.. include:: ../../common/contacts.rst diff --git a/build/docs/TunerGuide/source/images/001a_LocalConnection.png b/build/docs/TunerGuide/source/images/001a_LocalConnection.png new file mode 100644 index 000000000..90a1ded4c Binary files /dev/null and b/build/docs/TunerGuide/source/images/001a_LocalConnection.png differ diff --git a/build/docs/TunerGuide/source/images/001b_RemoteConnection.png b/build/docs/TunerGuide/source/images/001b_RemoteConnection.png new file mode 100644 index 000000000..1f8bbb608 Binary files /dev/null and b/build/docs/TunerGuide/source/images/001b_RemoteConnection.png differ diff --git a/build/docs/TunerGuide/source/images/047_EditPreferences.png b/build/docs/TunerGuide/source/images/047_EditPreferences.png index a9fd3438b..2d7ee347b 100644 Binary files a/build/docs/TunerGuide/source/images/047_EditPreferences.png and b/build/docs/TunerGuide/source/images/047_EditPreferences.png differ diff --git a/build/docs/TunerGuide/source/images/Vortex-OpenSplice-Cover.png b/build/docs/TunerGuide/source/images/Vortex-OpenSplice-Cover.png index ce86c6d94..801c02bb8 100644 Binary files a/build/docs/TunerGuide/source/images/Vortex-OpenSplice-Cover.png and b/build/docs/TunerGuide/source/images/Vortex-OpenSplice-Cover.png differ diff --git a/build/docs/TunerGuide/source/index.rst b/build/docs/TunerGuide/source/index.rst index 048e80677..2f296579b 100644 --- a/build/docs/TunerGuide/source/index.rst +++ b/build/docs/TunerGuide/source/index.rst @@ -9,13 +9,13 @@ The Vortex OpenSplice Tuner Guide .. toctree:: :maxdepth: 6 :numbered: - + preface introduction using01 - - contacts - + + contacts + Indices and tables ================== diff --git a/build/docs/TunerGuide/source/introduction.rst b/build/docs/TunerGuide/source/introduction.rst index 179e2b453..4bb01ffa0 100644 --- a/build/docs/TunerGuide/source/introduction.rst +++ b/build/docs/TunerGuide/source/introduction.rst @@ -13,76 +13,55 @@ General Description Vortex OpenSplice Tuner has been implemented in the Java language. It is possible to use it on every platform where a Java Virtual Machine (JVM) implementation is available. That means that Vortex OpenSplice Tuner -does not require OpenSplice to be available on the local system (see -Vortex OpenSplice Tuner Z at Node C). - -The diagram below shows a high-level view of a typical environment with -both Vortex OpenSplice and Vortex OpenSplice Tuner. - -Vortex OpenSplice is available at Node A and Node B. Vortex OpenSplice -Tuner is available at Node A and Node C. At both Node A and Node B -there are some Vortex OpenSplice applications running (Applications 1 - -5). - -.. _`Typical OpenSplice Tuner Environment`: - -.. centered:: **Typical OpenSplice Tuner Environment** - -.. image:: /images/001_TunerEnvironment.png - :width: 160mm - :align: center - :alt: Typical OpenSplice Tuner Environment - - -.. XXX Figure 1 Typical OpenSplice Tuner Environment - - - - +does not require OpenSplice to be available on the local system. Vortex OpenSplice Tuner is able to connect to one specific OpenSplice -DDS domain at one specific node, both locally and remotely. A local -connection is achieved by directly accessing OpenSplice at the local -node. The diagram shows two local connections. Both OpenSplice Tuner X -and Y are connected to Domain II. This implies it is possible to -simultaneous connect two Vortex OpenSplice Tuners to one specific domain -and node. +DDS domain at one specific node, both locally and remotely. It is possible +to simultaneously connect one or more Vortex OpenSplice Tuners to a specific +domainand node. -A remote connection can be achieved by means of an agent within -Vortex OpenSplice. This agent allows Vortex OpenSplice Tuner to communicate -with a remote node. In the diagram, the red dashed line indicates the -possible remote connections of SPLICE-Tuner Z at Node C to the -Vortex OpenSplice domains at the other two nodes. +The diagram below shows an overview of a Vortex OpenSplice Tuner process +connecting locally to a Vortex OpenSplicefederation (shared memory +deployment) on one computing node. +(Typically, there are many nodes within a system.) -Possible connections of Vortex OpenSplice Tuners to a domain and node -shown are: + _`Vortex OpenSplice Tuner Local Connection`: - OpenSplice Tuner X ---> Domain I at Node A +.. centered:: **Vortex OpenSplice Tuner Local Connection** - OpenSplice Tuner X ---> Domain II at Node A - - OpenSplice Tuner X ---> Domain I at Node B - - OpenSplice Tuner X ---> Domain II at Node B +.. image:: /images/001a_LocalConnection.png + :width: 175mm + :align: center + :alt: Vortex OpenSplice Tuner Local Connection - OpenSplice Tuner Y ---> Domain I at Node A - OpenSplice Tuner Y ---> Domain II at Node A +.. XXX Figure 1A Vortex OpenSplice Tuner Local Connection - OpenSplice Tuner Y ---> Domain I at Node B - OpenSplice Tuner Y ---> Domain II at Node B + \newpage - OpenSplice Tuner Z ---> Domain I at Node A +The diagram below shows an overview of a Vortex OpenSplice Tuner +process connecting remotely to a Vortex OpenSplice application +(single process deployment). The Tuner service (aka the SOAP service) +must be enabled in the Vortex OpenSplice configuration file to allow +remote connection for tools. - OpenSplice Tuner Z ---> Domain II at Node A +_`Vortex OpenSplice Tuner Remote Connection`: - OpenSplice Tuner Z ---> Domain I at Node B +.. centered:: **Vortex OpenSplice Tuner Remote Connection** - OpenSplice Tuner Z ---> Domain II at Node B +.. image:: /images/001b_RemoteConnection.png + :width: 175mm + :align: center + :alt: Vortex OpenSplice Tuner Remote Connection +.. XXX Figure 1B Vortex OpenSplice Tuner Remote Connection +While the figure details a remote connection to a single process +deployment, one can also use the remote connection capability to +connect to a shared memory deployment in the exact same way. +.. raw:: latex .. |caution| image:: ./images/icon-caution.* @@ -104,4 +83,4 @@ shown are: .. |java| image:: ./images/icon-java.* :height: 6mm - \ No newline at end of file + diff --git a/build/docs/TunerGuide/source/preface.rst b/build/docs/TunerGuide/source/preface.rst index e33982a2f..1c02fc2d1 100644 --- a/build/docs/TunerGuide/source/preface.rst +++ b/build/docs/TunerGuide/source/preface.rst @@ -38,7 +38,7 @@ describes how to use the OpenSplice Tuner. Conventions *********** -The icons shown below are used in PrismTech product documentation +The icons shown below are used in the Vortex product documentation to help readers to quickly identify information relevant to their specific use of Vortex OpenSplice. diff --git a/build/docs/TunerGuide/source/using01.rst b/build/docs/TunerGuide/source/using01.rst index 15406e1ba..06aa503ce 100644 --- a/build/docs/TunerGuide/source/using01.rst +++ b/build/docs/TunerGuide/source/using01.rst @@ -13,14 +13,27 @@ entities and data, and perform other related tasks.* Starting and Stopping the Tuner ******************************* -Starting -======== - Vortex OpenSplice Tuner has been implemented in the Java language. The supported platforms for the Tuner are listed in the *Release Notes* in the section ‘Supported Platforms’. The Tuner will work on all platforms that support JAVA (SAJ) SDK. +Starting Tuner Using Launcher +============================= + +The Vortex OpenSplice Launcher application provides easy access to the Vortex OpenSplice tools, configurations, documentation and examples. + +Vortex OpenSplice Tuner can be quickly started using the Vortex OpenSplice Launcher application. + +Instructions for starting Launcher can be found in the ‘Launcher’ section of the *OpenSplice_GettingStartedGuide.pdf* document. + +In Launcher, select the *Tools* tab, and select the *Tuner* button. +This will open the Tuner application. + + +Starting Tuner Using Command Line +================================= + The Vortex OpenSplice Tuner provides a command line instruction for specifying the domain config file that the tuner needs to connect to. @@ -52,8 +65,7 @@ of the OpenSplice installation (from now on referred to by % . /release.com -Once the environment has been initialized correctly, the OpenSplice -DDS Tuner can be started by typing the following command in the shell: +Once the environment has been initialized correctly, the Vortex OpenSplice Tuner can be started by typing the following command in the shell: :: @@ -255,7 +267,7 @@ This domain URI can represent any of the following values: *a*: Integer Domain ID (*e.g.* ``1``) - *b*: Domain URI (*e.g.* ``file:///home/Prismtech/ospl.xml``) + *b*: Domain URI (*e.g.* ``file:///home/ADLINK/ospl.xml``) *c*: SOAP service URL (*e.g.* ``http://192.168.1.20:8000``) @@ -948,7 +960,7 @@ in the domain where OpenSplice Tuner is currently participating. To create a subscriber, choose *Edit > Create Subscriber* in the menu bar of the main window (see `Main Window Edit Menu`_) or right-click -the SPLICE Tuner participant in the entity tree then choose the *Create +the Vortex OpenSplice Tuner participant in the entity tree then choose the *Create Subscriber* item. Both of these actions will result in the display of the dialog box @@ -997,6 +1009,14 @@ in the status bar of the dialog box. The Create subscriber action can be cancelled by clicking the *Cancel* button. In this case, no subscriber will be created. +|info| If the subscriber was created with *coherent_access* and *GROUP* +*access_scope*, then it will be created in the disabled state, regardless of +the value of the entity factory policy of the parent participant. For group +coherent subscribers, data readers can only be created while it is disabled. +When the subscriber is explicitly enabled, then the contained readers can begin +their access to the data. After the subscriber is enabled, no further data readers +can be created under it. + Creating a Reader ================= @@ -1080,7 +1100,7 @@ allows a reader-writer to inject and consume in multiple partitions. To create such a reader-writer, choose *Edit > Create Reader-Writer > Partition expression* in the menu bar of the main window (see -`Main Window Edit Menu`_) *or* right-click on the SPLICE Tuner participant +`Main Window Edit Menu`_) *or* right-click on the Vortex OpenSplice Tuner participant in the entity tree then choose the *Create Reader-Writer > Partition expression* item. @@ -1148,7 +1168,7 @@ partition. To create such a reader-writer, choose *Edit > Create Reader-Writer > Existing Partition* in the menu bar of the main window -(`Main Window Edit Menu`_) *or* right-click on the SPLICE Tuner participant +(`Main Window Edit Menu`_) *or* right-click on the Vortex OpenSplice Tuner participant in the entity tree then choose the *Create Reader-Writer > Existing Partition* item. @@ -2643,6 +2663,9 @@ the import window (`The Import Window`_) is displayed. By using the import window a subset of the data can be injected or disposed in the specified partition. +.. raw:: latex + + \newpage Preferences *********** @@ -2667,13 +2690,7 @@ dialog to edit the preferences. .. XX Figure 47 Edit Preferences -There are seven configuration options and four tabs for creating and -editing Writer, Reader, Publisher and Subscriber QoS Profiles (see -also `QoS Profiles`_). - -All options, their meaning and their possible values are explained in -the following subsections. The preferences are saved to disk so they -will be remembered when OpenSplice Tuner is exited. +The *Edit preferences* dialog allows user to save preferences to disk, so they will be remembered when OpenSplice Tuner is exited. Once the options are set to the desired value, they can be saved by clicking the *OK* button. This action triggers OpenSplice Tuner to save @@ -2685,8 +2702,19 @@ window. The Edit preferences action can be cancelled by clicking the *Cancel* button. In this case, the preferences will not be saved. +The *Edit preferences* dialog has 6 tabs. + ++ The *Attributes* tab has seven configuration options (see also `Attributes Tab`_). + ++ The *Topic Filters* tab provides filters to hide/show built-in topics in the different views (see also `Topic Filters Tab`_). + ++ There are four tabs for creating and editing Writer, Reader, Publisher and Subscriber QoS Profiles (see also `QoS Profiles`_). + +Attributes Tab +============== + Auto Update Entity information -============================== +------------------------------ This option determines whether the information in an entity information window is updated automatically and at what frequency. @@ -2703,7 +2731,7 @@ The default value for this option is ``2000``. .. _`Auto update entity tree`: Auto Update Entity Tree -======================= +----------------------- This option determines whether the entity relations (see `Entity Relationships`_) in the entity tree in the main window @@ -2722,7 +2750,7 @@ The default value for this option is ``"-1"``. .. _`Default entity tree type`: Default Entity Tree Type -======================== +------------------------ This option determines the default view for the entity tree in the main window. There are three options: ``"participant"``, ``"topic"`` @@ -2732,7 +2760,7 @@ and ``"partition"``. The view can be changed during execution The default value for this option is ``"topic"``. Logging -======= +------- This option can be used to log internal OpenSplice Tuner information. @@ -2743,7 +2771,7 @@ only and should *not* be used. The default value for this option is ``""``. Datatype Content Type -===================== +--------------------- This option determines the default content type for the displaying of entity data types in the Data type tab of an entity information @@ -2753,7 +2781,7 @@ window. There are two options: ``"text/plain"`` and ``"text/html"``. The default value for this option is ``"text/plain"``. Display Entity Relations -======================== +------------------------ This option determines whether entity relations are visible by default. There are two possibilities: ``"true"`` and ``"false"``. @@ -2761,7 +2789,7 @@ default. There are two possibilities: ``"true"`` and ``"false"``. The default value for this option is ``"false"``. Display Internals -================= +----------------- This option determines whether OpenSplice internals are visible in the information that is shown by OpenSplice Tuner. There are two @@ -2775,6 +2803,12 @@ entity are displayed. The default value for this option is ``"false"``. +Topic Filters Tab +================= + +The topic filters allow the user to hide and show built-in topics in the different views (Participant, Topic and Partition). + +By default the specification (DCPS) built-in topics are shown, and the other topic filters for internal built-in product topics are hidden. (CM, d\_, q\_, rr\_) QoS Profiles ************ diff --git a/build/docs/common/contacts.rst b/build/docs/common/contacts.rst new file mode 100644 index 000000000..77682339c --- /dev/null +++ b/build/docs/common/contacts.rst @@ -0,0 +1,55 @@ +.. _`Contacts & Notices`: + +################## +Contacts & Notices +################## + +******** +Contacts +******** + +| **ADLINK Technology Corporation** +| 400 TradeCenter +| Suite 5900 +| Woburn, MA +| 01801 +| USA +| Tel: +1 781 569 5819 + +| **ADLINK Technology Limited** +| The Edge +| 5th Avenue +| Team Valley +| Gateshead +| NE11 0XA +| UK +| Tel: +44 (0)191 497 9900 + +| **ADLINK Technology SARL** +| 28 rue Jean Rostand +| 91400 Orsay +| France +| Tel: +33 (1) 69 015354 + + +Web: http://ist.adlinktech.com/ + +Contact: http://ist.adlinktech.com + +E-mail: \ist_info@adlinktech.com + +LinkedIn: https://www.linkedin.com/company/79111/ + +Twitter: https://twitter.com/ADLINKTech_usa + +Facebook: https://www.facebook.com/ADLINKTECH + +******* +Notices +******* + +**Copyright** © 2018 ADLINK Technology Limited. All rights reserved. + +*This document may be reproduced in whole but not in part. The information contained in this +document is subject to change without notice and is made available in good faith without +liability on the part of ADLINK Technology Limited. All trademarks acknowledged.* diff --git a/build/docs/docs-commit-sha b/build/docs/docs-commit-sha index 43ddaa393..97c02960e 100644 --- a/build/docs/docs-commit-sha +++ b/build/docs/docs-commit-sha @@ -1,20 +1,25 @@ MCNF f48525adbd2fdac2d32b9a4e5bce00543dbfab39 -MCNX d9a47071e01698c6763092c68b2d378d6108b1b2 -MCGE 5f4d4834d80ac8eb66eace1b53814b6a27b5b711 -CONF 2e63829ab803e41442c310ef9c09f68586a3384c -DDST 4408c09a6a127b840637c1d85b7d5ea54870ff76 -DEPL 4042efe27c86685020d80daff863de2e67b2a19b -EVAL 2e63829ab803e41442c310ef9c09f68586a3384c -GSTA 2e63829ab803e41442c310ef9c09f68586a3384c -IDLP 557d731ad4b79345c9a9331755ea170f0ef03df6 -NODE 2e63829ab803e41442c310ef9c09f68586a3384c -GPBT 2e63829ab803e41442c310ef9c09f68586a3384c -RMIG 2e63829ab803e41442c310ef9c09f68586a3384c -RNRR 2e63829ab803e41442c310ef9c09f68586a3384c -RNRM 0a12881751954908322a5366342a89e42d058acb -STRM 2e63829ab803e41442c310ef9c09f68586a3384c -TEST 5e4175279f92eaab0ca25001a6c9fc0c8ebb10c2 -TUNE 86fe575168418c42fbc8bb78a7a4012706a5d36e -SNET 2e63829ab803e41442c310ef9c09f68586a3384c -MODL 2e63829ab803e41442c310ef9c09f68586a3384c - +MCNX 555ab5522e91fa206598b676b2fc68b4c0bacd35 +MCGE 890d7f61770c5493c4c8e91b228a0b6ede4d0e79 +CONF b8e79f0a23303b84528005f82b300cf40ba17e4f +DDST 3b7337fbf099471e00474ee7eb0f0d5e9ce86503 +DEPL dad17f8c9dee2612ab79e3788f29f61eaf024816 +EVAL 2843f37f3ab94f054e1070ea3cb271f47bac3a8e +GSTA 3b7337fbf099471e00474ee7eb0f0d5e9ce86503 +IDLP 2843f37f3ab94f054e1070ea3cb271f47bac3a8e +NODE 5cbcd44b55f15a94ac9f0ae0387c9ceacba859e4 +GPBT 2843f37f3ab94f054e1070ea3cb271f47bac3a8e +RMIG 2843f37f3ab94f054e1070ea3cb271f47bac3a8e +RNRR 2843f37f3ab94f054e1070ea3cb271f47bac3a8e +RNRM 5cbcd44b55f15a94ac9f0ae0387c9ceacba859e4 +STRM 2843f37f3ab94f054e1070ea3cb271f47bac3a8e +TEST 5cbcd44b55f15a94ac9f0ae0387c9ceacba859e4 +TUNE 298908065a30269ff0a74605d94ae51c945b14c1 +SNET 2843f37f3ab94f054e1070ea3cb271f47bac3a8e +MODL 467c0e8a3d95226cdc40979d27deba4bbfd7e8a1 +MATL ed964886c4623774fad18b432b99307ad68ec5ac +SIMU ed964886c4623774fad18b432b99307ad68ec5ac +COMN c25d662213db2f98fdd820e36335fb42d4d85035 +PYTH 37ba054db23058c7eb29a4a492096b9902e16293 +LABV c1b744bd1861ede21949b39d14f702ba30638d28 +NODEJS 0 diff --git a/build/docs/gen-changed-docs b/build/docs/gen-changed-docs index 052bcd2e5..5e42b6325 100755 --- a/build/docs/gen-changed-docs +++ b/build/docs/gen-changed-docs @@ -21,6 +21,7 @@ then fi docs_changed="False" +comn_changed="False" DOCS_DIR=$OSPL_HOME/build/docs @@ -89,6 +90,24 @@ do "MODL") modl_sha=$sha ;; + "MATL") + matl_sha=$sha + ;; + "SIMU") + simu_sha=$sha + ;; + "COMN") + comn_sha=$sha + ;; + "PYTH") + pyth_sha=$sha + ;; + "LABV") + labv_sha=$sha + ;; + "NODEJS") + nodejs_sha=$sha + ;; *) esac done < $DOCS_DIR/docs-commit-sha @@ -96,8 +115,17 @@ done < $DOCS_DIR/docs-commit-sha generate_conf_guide () { make xml + if [ $? != 0 ] + then + exit 1 + fi + cd $DOCS_DIR/ConfGuide make html + if [ $? != 0 ] + then + exit 1 + fi cd ../ cat $DOCS_DIR/ConfGuide/source/intro.rst > $DOCS_DIR/DeploymentGuide/source/guide.rst @@ -174,17 +202,41 @@ check_for_changes() echo "saved_sha is ${saved_sha}" echo "last_sha is ${last_sha}" - if [ "${saved_sha}" == "${last_sha}" ]; + changed="False" + + if [ "${key}" == "COMN" ]; then - echo "No change to $1" + if [ "${saved_sha}" == "${last_sha}" ]; + then + echo "No change to $1" + else + comn_changed="True" + sed -i "s/${key} ${saved_sha}/${key} ${last_sha}/g" docs-commit-sha + fi else - echo "$1 has changed" - build_docs $1 - sed -i "s/${key} ${saved_sha}/${key} ${last_sha}/g" docs-commit-sha - docs_changed="True" + if [ "${saved_sha}" == "${last_sha}" ]; + then + if [ "$comn_changed" == "False" -o "${key}" == "DDST" ]; + then + echo "No change to $1" + else + changed="True" + fi + else + changed="True" + fi + + if [ "$changed" == "True" ]; + then + echo "$1 has changed" + build_docs $1 + sed -i "s/${key} ${saved_sha}/${key} ${last_sha}/g" docs-commit-sha + docs_changed="True" + fi fi } +check_for_changes "common/contacts.rst" ${comn_sha} "COMN" check_for_changes "extract.py" ${mcnf_sha} "MCNF" check_for_changes "xml2rst.py" ${mcnx_sha} "MCNX" check_for_changes "../../src/tools/cm/config/code/splice_metaconfig_6.1.xml" ${mcge_sha} "MCGE" @@ -204,6 +256,11 @@ check_for_changes "TesterUserGuide" ${test_sha} "TEST" check_for_changes "TunerGuide" ${tune_sha} "TUNE" check_for_changes "SecureNetworking" ${snet_sha} "SNET" check_for_changes "ModelingGuide" ${modl_sha} "MODL" +check_for_changes "DDSMATLABGuide" ${matl_sha} "MATL" +check_for_changes "DDSSimulinkGuide" ${simu_sha} "SIMU" +check_for_changes "PythonDCPSAPIGuide" ${pyth_sha} "PYTH" +check_for_changes "DDSLabVIEWGuide" ${labv_sha} "LABV" +check_for_changes "NodeJSDCPSAPIGuide" ${nodejs_sha} "NODEJS" cd $OSPL_HOME/docs @@ -211,7 +268,7 @@ if [ "$docs_changed" == "True" ]; then git add -A :/ git commit -a -m "$TAG Updated documentation generated" - git push origin HEAD:$BRANCH + GIT_SSH="$OSPL_HOME/build/docs/gitsshdocs" git push origin HEAD:$BRANCH else echo "No doc changes to commit" fi diff --git a/build/docs/gitsshdocs b/build/docs/gitsshdocs new file mode 100755 index 000000000..5302babd9 --- /dev/null +++ b/build/docs/gitsshdocs @@ -0,0 +1,3 @@ +#!/bin/sh + +ssh -oIdentitiesOnly=yes -i /home/jenkins/.ssh/id_rsa_jenkins_ospl_docs_write $@ diff --git a/build/docs/xml2rst.py b/build/docs/xml2rst.py index 5e4cb998c..116aadaef 100755 --- a/build/docs/xml2rst.py +++ b/build/docs/xml2rst.py @@ -205,7 +205,10 @@ def output_elements(element, depth): if get_dimension(element) is not None: file.write("- Dimension: " + get_dimension(element) + "\n") if get_default_value(element): - file.write("- Default value: " + get_default_value(element) + "\n") + defstring = get_default_value(element) + if defstring == "__BUILT-IN PARTITION__": + defstring = "__BUILT-IN PARTITION\__" + file.write("- Default value: " + defstring + "\n") if get_valid_values(element) is not None: file.write("- Valid values: " + get_valid_values(element) + "\n") if get_occurrences(element) is not None: diff --git a/build/scripts/overnight/build_escrow b/build/scripts/overnight/build_escrow index 1241bf188..1d9c94d53 100755 --- a/build/scripts/overnight/build_escrow +++ b/build/scripts/overnight/build_escrow @@ -198,7 +198,7 @@ then wget $9 zip -rq $ZIP_DATE.zip Vortex*.zip ospl-3rd-party-software.zip - scp -i ~/.ssh/id_rsa_releases $ZIP_DATE.zip releases@repository2.prismtech.com:~/Vortex/$ZIP_DATE/ + scp -i ~/.ssh/id_rsa_releases $ZIP_DATE.zip releases@releases.prismtech.com:~/Vortex/$ZIP_DATE/ else echo "Not building final zip " fi diff --git a/build/scripts/overnight/build_examples.bat b/build/scripts/overnight/build_examples.bat index 14ccfe2cc..45e0dfacd 100644 --- a/build/scripts/overnight/build_examples.bat +++ b/build/scripts/overnight/build_examples.bat @@ -7,7 +7,7 @@ ECHO Set Microsoft Visual Studio Environment using VS supplied batch file IF "%VS_ENV_SCRIPT%"=="" EXIT 1 -IF NOT "%VS_ENV_SCRIPT%"=="" call "%VS_ENV_SCRIPT%" +IF NOT "%VS_ENV_SCRIPT%"=="" call "%VS_ENV_SCRIPT%" %VS_ENV_SCRIPT_ARGS% cd "%OSPL_HOME%" @@ -26,6 +26,9 @@ REM the forst line always in case a different "wrong" environment variable is re REM So: we set BOOST_ROOT to some harmless nonsense value if it's not already set. IF "%BOOST_ROOT%"=="" SET BOOST_ROOT=bibble +REM Output environment +set + ECHO Change to the examples directory cd "%OSPL_HOME%"/examples @@ -60,12 +63,13 @@ FOR %%f IN (BUILD*.bat) DO ( ECHO ----------------------------------------------------------------------- -cd "%OSPL_HOME%"/examples/protobuf/java5/standalone +ECHO Building Java5 examples.... +cd "%OSPL_HOME%"/examples/ IF ERRORLEVEL 1 ( - ECHO ***** java5 protobuf example not found. Return code %ERRORLEVEL% + ECHO ***** examples not found. Return code %ERRORLEVEL% ) else ( - call BUILD.bat - IF ERRORLEVEL 1 ECHO ***** building java5 protobuf example failed. Return code %ERRORLEVEL% + call mvn package + IF ERRORLEVEL 1 ECHO ***** building java5 examples failed. Return code %ERRORLEVEL% ) ECHO Building Isocpp2 protobuf example.... diff --git a/build/scripts/overnight/config_runs_opensplice b/build/scripts/overnight/config_runs_opensplice index e7c3514ae..fca3639b3 100644 --- a/build/scripts/overnight/config_runs_opensplice +++ b/build/scripts/overnight/config_runs_opensplice @@ -1,66 +1,12 @@ -E opensplice/rhel4e/x86.linux-dev 25 #First# none -E opensplice/rhel4e/x86.linux-release 25 #First# none - -E opensplice/win7a/x86.win32-dev 30 #First# none -E opensplice/win7a/x86.win32-release 30 #First# none - -E opensplice/win7a-64/x86_64.win64-dev 30 #First# none -E opensplice/win7a-64/x86_64.win64-release 30 #First# none - -E opensplice/ubuntu1204b/x86.linux-dev 25 #First# none -E opensplice/ubuntu1204b/x86.linux-release 25 #First# none - -E opensplice/ubuntu1204-64b/x86_64.linux-dev 25 #First# none -E opensplice/ubuntu1204-64b/x86_64.linux-release 25 #First# none - -E opensplice/rhel62a/x86.linux-dev 25 #First# none -E opensplice/rhel62a/x86.linux-release 25 #First# none - -E opensplice/rhel62-64b/x86_64.linux-dev 25 #First# none -E opensplice/rhel62-64b/x86_64.linux-release 25 #First# none - -E opensplice/rhel53a/x86.linux-dev 25 #First# none -E opensplice/rhel53a/x86.linux-release 25 #First# none - -E opensplice/rhel54-64c/x86_64.linux-dev 25 #First# none -E opensplice/rhel54-64c/x86_64.linux-release 25 #First# none - -E opensplice/rhel62-32a/x86.linux-dev 25 #First# none -E opensplice/rhel62-32a/x86.linux-release 25 #First# none - -E opensplice/rhel62-64a/x86_64.linux-dev 25 #First# none -E opensplice/rhel62-64a/x86_64.linux-release 25 #First# none - -E opensplice/ubuntu1204/x86.linux-dev 25 #First# none -E opensplice/ubuntu1204/x86.linux-release 25 #First# none - -E opensplice/ubuntu1204-64/x86_64.linux-dev 25 #First# none -E opensplice/ubuntu1204-64/x86_64.linux-release 25 #First# none - -E opensplice/raspberry1/armv6l.linux-dev 25 #First# none -E opensplice/raspberry1/armv6l.linux-release 25 #First# none - E opensplice/pi3a/armv7l.linux-dev 25 #First# none E opensplice/pi3a/armv7l.linux-release 25 #First# none E opensplice/bone1/armv7l.linux-dev 25 #First# none E opensplice/bone1/armv7l.linux-release 25 #First# none -E opensplice/jetson1/armv7l.linux-dev 25 #First# none -E opensplice/jetson1/armv7l.linux-release 25 #First# none - -E opensplice/win7b/x86.win32-dev-vs11 30 #First# none -E opensplice/win7b/x86.win32-release-vs11 30 #First# none - E opensplice/win7c/x86.win32-dev-vs12 30 #First# none E opensplice/win7c/x86.win32-release-vs12 30 #First# none -E opensplice/win7d/x86_64.win64-dev-vs11 30 #First# none -E opensplice/win7d/x86_64.win64-release-vs11 30 #First# none - -E opensplice/win7e/x86_64.win64-dev-vs12 30 #First# none -E opensplice/win7e/x86_64.win64-release-vs12 30 #First# none - E opensplice/rhel72a/x86_64.linux-dev 25 #First# none E opensplice/rhel72a/x86_64.linux-release 25 #First# none @@ -85,8 +31,8 @@ E opensplice/win10-64-vor-c/x86_64.win64-release-vs14 30 #First# none E opensplice/win10-64-vor-d/x86_64.win64-dev-vs14 30 #First# none E opensplice/win10-64-vor-d/x86_64.win64-release-vs14 30 #First# none -E opensplice/win10-64-ospl-vs17/x86_64.win64-dev-vs17 30 #First# none -E opensplice/win10-64-ospl-vs17/x86_64.win64-release-vs17 30 #First# none +E opensplice/win10-64-ospl-7/x86_64.win64-dev-vs17 30 #First# none +E opensplice/win10-64-ospl-7/x86_64.win64-release-vs17 30 #First# none E opensplice/macmini/x86_64.darwin10_clang-dev 25 #First# none E opensplice/macmini/x86_64.darwin10_clang-release 25 #First# none diff --git a/build/scripts/overnight/config_runs_opensplice-test b/build/scripts/overnight/config_runs_opensplice-test index 95828c4c3..8b313762a 100644 --- a/build/scripts/overnight/config_runs_opensplice-test +++ b/build/scripts/overnight/config_runs_opensplice-test @@ -1,66 +1,12 @@ -E opensplice-test/rhel4e/x86.linux-dev 25 #First# none -E opensplice-test/rhel4e/x86.linux-release 25 #First# none - -E opensplice-test/win7a/x86.win32-dev 30 #First# none -E opensplice-test/win7a/x86.win32-release 30 #First# none - -E opensplice-test/win7a-64/x86_64.win64-dev 30 #First# none -E opensplice-test/win7a-64/x86_64.win64-release 30 #First# none - -E opensplice-test/ubuntu1204b/x86.linux-dev 25 #First# none -E opensplice-test/ubuntu1204b/x86.linux-release 25 #First# none - -E opensplice-test/ubuntu1204-64b/x86_64.linux-dev 25 #First# none -E opensplice-test/ubuntu1204-64b/x86_64.linux-release 25 #First# none - -E opensplice-test/rhel62a/x86.linux-dev 25 #First# none -E opensplice-test/rhel62a/x86.linux-release 25 #First# none - -E opensplice-test/rhel62-64b/x86_64.linux-dev 25 #First# none -E opensplice-test/rhel62-64b/x86_64.linux-release 25 #First# none - -E opensplice-test/rhel53a/x86.linux-dev 25 #First# none -E opensplice-test/rhel53a/x86.linux-release 25 #First# none - -E opensplice-test/rhel54-64c/x86_64.linux-dev 25 #First# none -E opensplice-test/rhel54-64c/x86_64.linux-release 25 #First# none - -E opensplice-test/rhel62-32a/x86.linux-dev 25 #First# none -E opensplice-test/rhel62-32a/x86.linux-release 25 #First# none - -E opensplice-test/rhel62-64a/x86_64.linux-dev 25 #First# none -E opensplice-test/rhel62-64a/x86_64.linux-release 25 #First# none - -E opensplice-test/ubuntu1204/x86.linux-dev 25 #First# none -E opensplice-test/ubuntu1204/x86.linux-release 25 #First# none - -E opensplice-test/ubuntu1204-64/x86_64.linux-dev 25 #First# none -E opensplice-test/ubuntu1204-64/x86_64.linux-release 25 #First# none - -E opensplice-test/raspberry1/armv6l.linux-dev 25 #First# none -E opensplice-test/raspberry1/armv6l.linux-release 25 #First# none - E opensplice-test/pi3a/armv7l.linux-dev 25 #First# none E opensplice-test/pi3a/armv7l.linux-release 25 #First# none E opensplice-test/bone1/armv7l.linux-dev 25 #First# none E opensplice-test/bone1/armv7l.linux-release 25 #First# none -E opensplice-test/jetson1/armv7l.linux-dev 25 #First# none -E opensplice-test/jetson1/armv7l.linux-release 25 #First# none - -E opensplice-test/win7b/x86.win32-dev-vs11 30 #First# none -E opensplice-test/win7b/x86.win32-release-vs11 30 #First# none - E opensplice-test/win7c/x86.win32-dev-vs12 30 #First# none E opensplice-test/win7c/x86.win32-release-vs12 30 #First# none -E opensplice-test/win7d/x86_64.win64-dev-vs11 30 #First# none -E opensplice-test/win7d/x86_64.win64-release-vs11 30 #First# none - -E opensplice-test/win7e/x86_64.win64-dev-vs12 30 #First# none -E opensplice-test/win7e/x86_64.win64-release-vs12 30 #First# none - E opensplice-test/rhel72a/x86_64.linux-dev 25 #First# none E opensplice-test/rhel72a/x86_64.linux-release 25 #First# none @@ -85,8 +31,8 @@ E opensplice-test/win10-64-vor-c/x86_64.win64-release-vs14 30 #First# none E opensplice-test/win10-64-vor-d/x86_64.win64-dev-vs14 30 #First# none E opensplice-test/win10-64-vor-d/x86_64.win64-release-vs14 30 #First# none -E opensplice-test/win10-64-ospl-vs17/x86_64.win64-dev-vs17 30 #First# none -E opensplice-test/win10-64-ospl-vs17/x86_64.win64-release-vs17 30 #First# none +E opensplice-test/win10-64-ospl-7/x86_64.win64-dev-vs17 30 #First# none +E opensplice-test/win10-64-ospl-7/x86_64.win64-release-vs17 30 #First# none E opensplice-test/macmini/x86_64.darwin10_clang-dev 25 #First# none E opensplice-test/macmini/x86_64.darwin10_clang-release 25 #First# none diff --git a/build/scripts/overnight/config_runs_ospli b/build/scripts/overnight/config_runs_ospli index df41e7468..6a7f9f494 100644 --- a/build/scripts/overnight/config_runs_ospli +++ b/build/scripts/overnight/config_runs_ospli @@ -7,38 +7,25 @@ E ospli/rhel62-64a/x86_64.linux-release-coverity-inner 1 heads/OSPL_V6_4_0p6c1 ################################ end Coverity Runs ################################## ################################ First Runs ################################## -M ospli/ebmr-p/ppc_e5500-linux-release-inner 1 #First# none -E ospli/ebmr-p/ppc_e5500-linux-dev-inner 1 #First# none -M ospli/ebmr-p/armhf-linux-release-inner 1 #First# none -E ospli/ebmr-p/armhf-linux-dev-inner 1 #First# none - -M ospli/ubuntu1004c/cortexa9t_neon.WRlinux5_gcc-release-inner 1 #Third# none +E ospli/ubuntu1004c/cortexa9t_neon.WRlinux5_gcc-release-inner 1 #First# none E ospli/ubuntu1004c/cortexa9t_neon.WRlinux5_gcc-dev-inner 1 #First# none -M ospli/priva0912-linux-dev/armv6l.linux-release-inner 10 #First# none +E ospli/priva0912-linux-dev/armv6l.linux-release-inner 10 #First# none E ospli/priva0912-linux-dev/armv6l.linux-dev-inner 10 #First# none - E ospli/winxp2/PPC604.vxworks6.6.win32-dev-inner 1 #First# none -M ospli/winxp2/PPC604.vxworks6.6.win32-release-inner 1 #First# none +E ospli/winxp2/PPC604.vxworks6.6.win32-release-inner 1 #First# none E ospli/ubuntu1004b/mpc8308_glibc_small.WRlinux4u3_gcc-release-inner 1 #First# none E ospli/ubuntu1004b/mpc8308_glibc_small.WRlinux4u3_gcc-dev-inner 1 #First# none E ospli/ubuntu1004b/common_pc_glibc_small.WRlinux4u3_gcc-release-inner 1 #First# none E ospli/ubuntu1004b/common_pc_glibc_small.WRlinux4u3_gcc-dev-inner 1 #First# none -E ospli/rhel4g/x86.linux-dev 25 #First# none -E ospli/rhel4g/x86.linux-release 25 #First# none -E ospli/rhel4g/x86.linux-dev-inner 1 #First# none -E ospli/rhel4g/x86.linux-dev-notest-inner 1 #First# none -M ospli/rhel4g/x86.linux-release-inner 1 #First# none -E ospli/rhel4g/x86.linux-release-notest-inner 1 #First# none -E ospli/rhel4g/x86.linux-release-examples-inner 1 #First# none - E ospli/rhel4d/x86.linux-dev 25 #First# none E ospli/rhel4d/x86.linux-release 25 #First# none -M ospli/rhel4d/x86.linux-dev-inner 1 #First# none +E ospli/rhel4d/x86.linux-dev-inner 1 #First# none + E ospli/rhel4d/x86.linux-dev-notest-inner 1 #First# none E ospli/rhel4d/x86.linux-release-inner 1 #First# none E ospli/rhel4d/x86.linux-release-notest-inner 1 #First# none @@ -49,7 +36,7 @@ E ospli/rhel4e/x86.linux-release 25 #First# none E ospli/rhel4e/x86.linux-debug-notest-noexample-inner 1 #First# none E ospli/rhel4e/x86.linux-dev-inner 1 #First# none E ospli/rhel4e/x86.linux-dev-notest-inner 1 #First# none -M ospli/rhel4e/x86.linux-release-inner 1 #First# none +E ospli/rhel4e/x86.linux-release-inner 1 #First# none E ospli/rhel4e/x86.linux-release-notest-inner 1 #First# none E ospli/rhel4e/x86.linux-release-examples-inner 1 #First# none E ospli/rhel4e/x86.linux-release-nodbt-inner 1 #First# none @@ -57,18 +44,6 @@ E ospli/rhel4e/x86.linux-release-testsingleprocess-inner 1 #First# none E ospli/rhel4/x86.linux-gcov-inner 1 #First# none -E ospli/winxp12/x86.win32-dev 40 #First# none -E ospli/winxp12/x86.win32-release 40 #First# none -E ospli/winxp12/x86.win32-dev-inner 1 #First# none -E ospli/winxp12/x86.win32-dev-notest-inner 1 #First# none -M ospli/winxp12/x86.win32-dev-notao-inner 1 #First# none -E ospli/winxp12/x86.win32-dev-notest-notao-inner 1 #First# none -E ospli/winxp12/x86.win32-release-inner 1 #First# none -E ospli/winxp12/x86.win32-release-notest-inner 1 #First# none -E ospli/winxp12/x86.win32-release-nodbt-inner 1 #First# none -E ospli/winxp12/x86.vxworks5.5-dev-inner 1 #First# none -M ospli/winxp12/x86.vxworks5.5-release-inner 1 #First# none - E ospli/winxp13/pentium.vxworks6.9.3.1-dev-inner 1 #First# none E ospli/winxp13/pentium.vxworks6.9.3.1-release-inner 1 #First# none E ospli/winxp13/pentium.vxworks6.9.3.1_km-dev-inner 1 #First# none @@ -77,7 +52,7 @@ E ospli/winxp13/pentium4.vxworks6.8.2-release-inner 1 #First# none E ospli/winxp13/pentium4.vxworks6.8.2-dev-inner 1 #First# none E ospli/winxp13/pentium4.vxworks6.8.2_km-release-inner 1 #First# none E ospli/winxp13/pentium4.vxworks6.8.2_km-dev-inner 1 #First# none -M ospli/winxp13/pentium4.vxworks6.8.2_km_smp-release-inner 1 #First# none +E ospli/winxp13/pentium4.vxworks6.8.2_km_smp-release-inner 1 #First# none E ospli/winxp13/pentium4.vxworks6.8.2_km_smp-dev-inner 1 #First# none E ospli/winxp13/pentium4.vxworks6.9.3.1-dev-inner 1 #First# none E ospli/winxp13/pentium4.vxworks6.9.3.1-release-inner 1 #First# none @@ -110,7 +85,7 @@ E ospli/winxp13-new/pentium4.vxworks6.8.2_km-release-inner 1 #First# none E ospli/winxp13-new/pentium4.vxworks6.8.2_km-dev-inner 1 #First# none E ospli/winxp13-new/pentium4.vxworks6.8.2_km_smp-release-inner 1 #First# none E ospli/winxp13-new/pentium4.vxworks6.8.2_km_smp-dev-inner 1 #First# none -M ospli/winxp13-new/pentium4.vxworks6.8.3_km_smp-release-inner 1 #First# none +E ospli/winxp13-new/pentium4.vxworks6.8.3_km_smp-release-inner 1 #First# none E ospli/winxp13-new/pentium4.vxworks6.8.3_km_smp-dev-inner 1 #First# none E ospli/winxp13-new/pentium4.vxworks6.9.3.1-dev-inner 1 #First# none E ospli/winxp13-new/pentium4.vxworks6.9.3.1-release-inner 1 #First# none @@ -126,16 +101,16 @@ E ospli/winxp13-new/PPC85XXe500v2.vxworks6.9.3.1_km-release-inner 1 #First# no E ospli/winxp13-new/PPC85XXe500v2.vxworks6.9.3.1_km-dev-inner 1 #First# none E ospli/winxp13-new/pentium4.vxworks6.9.4.1-dev-inner 1 #First# none -M ospli/winxp13-new/pentium4.vxworks6.9.4.1-release-inner 1 #First# none +E ospli/winxp13-new/pentium4.vxworks6.9.4.1-release-inner 1 #First# none E ospli/winxp13-new/pentium4.vxworks6.9.4.1-shlib-dev-inner 1 #First# none -M ospli/winxp13-new/pentium4.vxworks6.9.4.1-shlib-release-inner 1 #First# none +E ospli/winxp13-new/pentium4.vxworks6.9.4.1-shlib-release-inner 1 #First# none E ospli/winxp13-new/atom.vxworks6.9.4.1-dev-inner 1 #First# none -M ospli/winxp13-new/atom.vxworks6.9.4.1-release-inner 1 #First# none +E ospli/winxp13-new/atom.vxworks6.9.4.1-release-inner 1 #First# none E ospli/winxp13-new/atom.vxworks6.9.4.1-shlib-dev-inner 1 #First# none -M ospli/winxp13-new/atom.vxworks6.9.4.1-shlib-release-inner 1 #First# none -M ospli/winxp13-new/E500v2.vxworks6.9.4.1-release-inner 1 #First# none +E ospli/winxp13-new/atom.vxworks6.9.4.1-shlib-release-inner 1 #First# none +E ospli/winxp13-new/E500v2.vxworks6.9.4.1-release-inner 1 #First# none E ospli/winxp13-new/E500v2.vxworks6.9.4.1-dev-inner 1 #First# none -M ospli/winxp13-new/E500v2.vxworks6.9.4.1-shlib-release-inner 1 #First# none +E ospli/winxp13-new/E500v2.vxworks6.9.4.1-shlib-release-inner 1 #First# none E ospli/winxp13-new/x86.win32-dev 40 #First# none E ospli/winxp13-new/x86.win32-dev-inner 1 #First# none @@ -144,18 +119,19 @@ E ospli/winxp13-new/x86.win32-release 40 #First# none E ospli/winxp13-new/x86.win32-release-inner 1 #First# none E ospli/winxp13-new/x86.win32-release-nodbt-inner 1 #First# none E ospli/winxp13-new/x86.win32-release-notest-inner 1 #First# none +E ospli/winxp13-new/x86.win32-release-examples-inner 1 #First# none E ospli/sles11/p4-vx6.9.3.1-c2d-dev-inner 1 #First# none -M ospli/sles11/p4-vx6.9.3.1-c2d-rel-inner 1 #First# none +E ospli/sles11/p4-vx6.9.3.1-c2d-rel-inner 1 #First# none E ospli/sles11/p4-vx6.9.3.1_km-c2d-dev-inner 1 #First# none -M ospli/sles11/p4-vx6.9.3.1_km-c2d-rel-inner 1 #First# none +E ospli/sles11/p4-vx6.9.3.1_km-c2d-rel-inner 1 #First# none E ospli/sles11/p4-vx6.9.4.1-c2d-dev-inner 1 #First# none -M ospli/sles11/p4-vx6.9.4.1-c2d-rel-inner 1 #First# none +E ospli/sles11/p4-vx6.9.4.1-c2d-rel-inner 1 #First# none E ospli/sles11/p4-vx6.9.4.1-shlib-c2d-dev-inner 1 #First# none -M ospli/sles11/p4-vx6.9.4.1-shlib-c2d-rel-inner 1 #First# none +E ospli/sles11/p4-vx6.9.4.1-shlib-c2d-rel-inner 1 #First# none E ospli/sles11/p4-vx6.9.4.1_km-c2d-dev-inner 1 #First# none -M ospli/sles11/p4-vx6.9.4.1_km-c2d-rel-inner 1 #First# none +E ospli/sles11/p4-vx6.9.4.1_km-c2d-rel-inner 1 #First# none E ospli/sles11/MIPS32R2sf-vxworks6.8.2-dev-inner 1 #First# none E ospli/sles11/MIPS32R2sf-vxworks6.8.2-release-inner 1 #First# none @@ -171,7 +147,7 @@ E ospli/sles11/pentium4-vxworks6.8.2_km-release-inner 1 #First# none E ospli/sles11/pentium4-vxworks6.8.2_km_smp-dev-inner 1 #First# none E ospli/sles11/pentium4-vxworks6.8.2_km_smp-release-inner 1 #First# none E ospli/sles11/pentium4-vxworks6.8.2_km_smp-dev-inner 1 #First# none -M ospli/sles11/pentium4-vxworks6.8.3_km_smp-release-inner 1 #First# none +E ospli/sles11/pentium4-vxworks6.8.3_km_smp-release-inner 1 #First# none E ospli/sles11/pentium4-vxworks6.8.3_km_smp-dev-inner 1 #First# none E ospli/sles11/pentium4-vxworks6.9.3.1-dev-inner 1 #First# none E ospli/sles11/pentium4-vxworks6.9.3.1-shlib-release-inner 1 #First# none @@ -187,71 +163,42 @@ E ospli/sles11/pentium-vxworks6.9.3.1_km-release-inner 1 #First# none E ospli/sles11/E500v2-vxworks6.9.3.1-dev-inner 1 #First# none E ospli/sles11/E500v2-vxworks6.9.3.1-release-inner 1 #First# none E ospli/sles11/E500v2-vxworks6.9.3.1-shlib-dev-inner 1 #First# none -M ospli/sles11/E500v2-vxworks6.9.3.1-shlib-release-inner 1 #Third# none +E ospli/sles11/E500v2-vxworks6.9.3.1-shlib-release-inner 1 #First# none E ospli/sles11/PPC85XXe500v2-vxworks6.9.3.1_km-dev-inner 1 #First# none E ospli/sles11/PPC85XXe500v2-vxworks6.9.3.1_km-release-inner 1 #First# none E ospli/sles11/pentium4-vxworks6.9.4.1-dev-inner 1 #First# none -M ospli/sles11/pentium4-vxworks6.9.4.1-release-inner 1 #First# none -M ospli/sles11/pentium4-vxworks6.9.4.1-shlib-release-inner 1 #First# none +E ospli/sles11/pentium4-vxworks6.9.4.1-release-inner 1 #First# none +E ospli/sles11/pentium4-vxworks6.9.4.1-shlib-release-inner 1 #First# none E ospli/sles11/pentium4-vxworks6.9.4.1-shlib-dev-inner 1 #First# none E ospli/sles11/atom-vxworks6.9.4.1-dev-inner 1 #First# none -M ospli/sles11/atom-vxworks6.9.4.1-release-inner 1 #First# none -M ospli/sles11/atom-vxworks6.9.4.1-shlib-release-inner 1 #First# none +E ospli/sles11/atom-vxworks6.9.4.1-release-inner 1 #First# none +E ospli/sles11/atom-vxworks6.9.4.1-shlib-release-inner 1 #First# none E ospli/sles11/atom-vxworks6.9.4.1-shlib-dev-inner 1 #First# none E ospli/sles11/E500v2-vxworks6.9.4.1-dev-inner 1 #First# none -M ospli/sles11/E500v2-vxworks6.9.4.1-release-inner 1 #First# none -M ospli/sles11/E500v2-vxworks6.9.4.1-shlib-release-inner 1 #First# none +E ospli/sles11/E500v2-vxworks6.9.4.1-release-inner 1 #First# none +E ospli/sles11/E500v2-vxworks6.9.4.1-shlib-release-inner 1 #First# none E ospli/ssso10/PPC604.vxworks5.5-dev-inner 1 #First# none E ospli/ssso10/PPCE500.vxworks5.5-dev-inner 1 #First# none -M ospli/ssso10/PPC604.vxworks5.5-release-inner 1 #First# none +E ospli/ssso10/PPC604.vxworks5.5-release-inner 1 #First# none E ospli/ssso10/PPCE500.vxworks5.5-release-inner 1 #First# none -E ospli/DDS1-WIN2K3/armv4i.wince6-dev-inner 1 #First# none -M ospli/DDS1-WIN2K3/armv4i.wince6-release-inner 1 #First# none -MT ospli/DDS1-WIN2K3/armv4i.wince6-release-inner 1 #First# none -E ospli/DDS1-WIN2K3/armv4i.wince6-debug-inner 1 #First# none - -E ospli/DDS1-WIN2K3/x86.win32-dev 40 #First# none -E ospli/DDS1-WIN2K3/x86.win32-release 40 #First# none -E ospli/DDS1-WIN2K3/x86.win32-dev-inner 1 #First# none -E ospli/DDS1-WIN2K3/x86.win32-dev-notest-inner 1 #First# none -E ospli/DDS1-WIN2K3/x86.win32-release-inner 1 #First# none -M ospli/DDS1-WIN2K3/x86.win32-release-notest-inner 1 #First# none -E ospli/DDS1-WIN2K3/x86.win32-release-examples-inner 1 #First# none -E ospli/DDS1-WIN2K3/x86.win32-release-nodbt-inner 1 #First# none -E ospli/DDS1-WIN2K3/x86.win32-release-netsrc-inner 1 #First# none - -E ospli/dds2-win2k3/x86.win32-dev 40 #First# none -E ospli/dds2-win2k3/x86.win32-release 40 #First# none -E ospli/dds2-win2k3/x86.win32-dev-inner 1 #First# none -E ospli/dds2-win2k3/x86.win32-release-inner 1 #First# none -E ospli/dds2-win2k3/x86.win32-release-nolic-inner 1 #First# none -M ospli/dds2-win2k3/x86.win32-release-notest-inner 1 #First# none -E ospli/dds2-win2k3/x86.win32-release-notest-nolic-inner 1 #First# none -E ospli/dds2-win2k3/x86.win32-release-nodbt-inner 1 #First# none -E ospli/dds2-win2k3/x86.win32-release-netsrc-inner 1 #First# none -E ospli/dds2-win2k3/x86.win32-debug-inner 1 #First# none -E ospli/dds2-win2k3/x86.win32-debug-notest-inner 1 #First# none -E ospli/dds2-win2k3/x86.win32-debug-notest-notao-inner 1 #First# none - E ospli/dds3-win2k3/x86.win32-dev 40 #First# none E ospli/dds3-win2k3/x86.win32-release 40 #First# none E ospli/dds3-win2k3/x86.win32-dev-inner 1 #First# none E ospli/dds3-win2k3/x86.win32-dev-notest-inner 1 #First# none -M ospli/dds3-win2k3/x86.win32-release-inner 1 #First# none +E ospli/dds3-win2k3/x86.win32-release-inner 1 #First# none E ospli/dds3-win2k3/x86.win32-release-netsrc-inner 1 #First# none E ospli/dds3-win2k3/x86.win32-release-nolic-inner 1 #First# none E ospli/dds3-win2k3/x86.win32-release-notest-inner 1 #First# none E ospli/dds3-win2k3/x86.win32-release-notest-nolic-inner 1 #First# none E ospli/dds3-win2k3/x86.win32-release-nodbt-inner 1 #First# none +E ospli/dds3-win2k3/x86.win32-release-examples-inner 1 #First# none E ospli/dds3-win2k3/x86.win32-dev-notestbuild-inner 40 #First# none E ospli/dds3-win2k3/x86.win32-debug-inner 1 #First# none E ospli/dds3-win2k3/x86.win32-debug-notest-inner 1 #First# none -E ospli/blade1/x86_64.linux_opencc-release-inner 1 #First# none - E ospli/rhel5a/x86.linux-dev 30 #First# none E ospli/rhel5a/x86.linux-release 30 #First# none E ospli/rhel5a/x86.linux-dev-inner 1 #First# none @@ -261,7 +208,7 @@ E ospli/rhel5a/x86.linux-memcheck-notest-inner 1 #First# none E ospli/rhel5a/x86.linux-dev-notest-inner 1 #First# none E ospli/rhel5a/x86.linux-release-notest-inner 1 #First# none E ospli/rhel5a/x86.linux-release-examples-inner 1 #First# none -M ospli/rhel5a/x86.linux-release-inner 1 #First# none +E ospli/rhel5a/x86.linux-release-inner 1 #First# none E ospli/rhel5a/mpc8313e.linux-dev-inner 1 #First# none E ospli/rhel5a/mpc8313e.linux-release-inner 1 #First# none @@ -285,20 +232,20 @@ E ospli/rhel53a/mpc8313e.linux-release-inner 1 #First# none E ospli/rhel53a/x86.elinos4.2-dev-inner 1 #First# none E ospli/rhel53a/x86.elinos4.2-release-inner 1 #First# none E ospli/rhel53a/x86.elinos4.2_perc-dev-inner 1 #First# none -M ospli/rhel53a/x86.elinos4.2_perc-release-inner 1 #First# none -M ospli/rhel53a/x86.elinos5.1_rhel5.3-release-inner 1 #First# none +E ospli/rhel53a/x86.elinos4.2_perc-release-inner 1 #First# none +E ospli/rhel53a/x86.elinos5.1_rhel5.3-release-inner 1 #First# none E ospli/rhel53a/x86.elinos5.1_rhel5.3-dev-inner 1 #First# none -M ospli/rhel53a/x86.elinos5.2_rhel5.3-release-inner 1 #First# none +E ospli/rhel53a/x86.elinos5.2_rhel5.3-release-inner 1 #First# none E ospli/rhel53a/x86.elinos5.2_rhel5.3-dev-inner 1 #First# none E ospli/rhel53a/x86.elinos5.2_perc-release-inner 1 #First# none E ospli/rhel53a/E500mc.linux-dev-inner 1 #First# none -M ospli/rhel53a/E500mc.linux-release-inner 1 #First# none +E ospli/rhel53a/E500mc.linux-release-inner 1 #First# none E ospli/rhel53a/E500mc.linux-debug-inner 1 #First# none E ospli/rhel53a/arm.elinos5.2_rhel5.3-dev-normi-inner 1 #First# none E ospli/rhel53a/arm.elinos5.2_rhel5.3-release-normi-inner 1 #First# none E ospli/rhel53a/arm.elinos5.2_rhel5.3-dev-thales-inner 1 #First# none -M ospli/rhel53a/arm.elinos5.2_rhel5.3-release-thales-inner 1 #Third# none +E ospli/rhel53a/arm.elinos5.2_rhel5.3-release-thales-inner 1 #First# none E ospli/rhel54b/x86.linux-release-inner 1 #First# none E ospli/rhel54b/x86.linux-release-netsrc-inner 1 #First# none @@ -312,24 +259,12 @@ E ospli/rhel54b/x86.linux-dev-notest-inner 1 #First# none E ospli/rhel54b/x86.linux-debug-inner 1 #First# none E ospli/rhel54b/x86.linux-debug-notest-inner 1 #First# none E ospli/rhel54b/x86.linux-debug-notest-noexample-inner 1 #First# none -M ospli/rhel54b/x86.linux-gcov-inner 1 #First# none +E ospli/rhel54b/x86.linux-gcov-inner 1 #First# none E ospli/rhel54b/x86.linux-release-TAO161-inner 1 #First# none -M ospli/rhel54b/x86.linux-release-notest-TAO161-inner 1 #First# none +E ospli/rhel54b/x86.linux-release-notest-TAO161-inner 1 #First# none E ospli/rhel54b/x86.linux-debug-TAO161-inner 1 #First# none E ospli/rhel54b/x86.linux-debug-notest-TAO161-inner 1 #First# none -E ospli/rhel53-64/x86_64.linux-dev 35 #Broken# none -E ospli/rhel53-64/x86_64.linux-release 35 #Broken# none -E ospli/rhel53-64/x86_64.linux-dev-inner 1 #Broken# none -E ospli/rhel53-64/x86_64.linux-dev-notest-inner 1 #Broken# none -E ospli/rhel53-64/x86_64.linux-release-inner 1 #Broken# none -E ospli/rhel53-64/x86_64.linux-release-nodbt-inner 1 #Broken# none -E ospli/rhel53-64/x86_64.linux-release-notest-inner 1 #Broken# none -E ospli/rhel53-64/x86_64.linux-debug-inner 1 #Broken# none -E ospli/rhel53-64/x86_64.linux-debug-notest-inner 1 #Broken# none -E ospli/rhel53-64/arm.elinos5.2_rhel5.3-dev-inner 1 #Broken# none -E ospli/rhel53-64/arm.elinos5.2_rhel5.3-release-inner 1 #Broken# none - E ospli/rhel54-64b/x86_64.linux-dev 25 #First# none E ospli/rhel54-64b/x86_64.linux-release 25 #First# none E ospli/rhel54-64b/x86_64.linux-dev-inner 1 #First# none @@ -339,7 +274,7 @@ E ospli/rhel54-64b/x86_64.linux-release-notest-inner 1 #First# none E ospli/rhel54-64b/x86_64.linux-release-examples-inner 1 #First# none E ospli/rhel54-64b/x86_64.linux-release-nolic-inner 1 #First# none E ospli/rhel54-64b/x86_64.linux-release-notest-nolic-inner 1 #First# none -M ospli/rhel54-64b/x86_64.linux-release-notest-TAO161-inner 1 #First# none +E ospli/rhel54-64b/x86_64.linux-release-notest-TAO161-inner 1 #First# none E ospli/rhel54-64b/x86_64.linux-debug-inner 1 #First# none E ospli/rhel54-64b/x86_64.linux-debug-notest-inner 1 #First# none E ospli/rhel54-64b/x86_64.linux-debug-nolic-inner 1 #First# none @@ -351,17 +286,18 @@ E ospli/rhel54-64c/x86_64.linux-dev 25 #First# none E ospli/rhel54-64c/x86_64.linux-release 25 #First# none E ospli/rhel54-64c/x86_64.linux-dev-inner 1 #First# none E ospli/rhel54-64c/x86_64.linux-dev-notest-inner 1 #First# none -M ospli/rhel54-64c/x86_64.linux-release-inner 1 #First# none +E ospli/rhel54-64c/x86_64.linux-release-inner 1 #First# none E ospli/rhel54-64c/x86_64.linux-release-notest-inner 1 #First# none E ospli/rhel54-64c/x86_64.linux-release-examples-inner 1 #First# none E ospli/rhel54-64c/x86_64.linux-debug-inner 1 #First# none E ospli/rhel54-64c/x86_64.linux-debug-notest-inner 1 #First# none E ospli/rhel54-64c/x86_64.linux-release-notest-TAO161-inner 1 #First# none E ospli/rhel54-64c/x86_64.linux-debug-notest-TAO161-inner 1 #First# none + E ospli/rhel72-64a/x86_64.elinos6.0-dev-inner 1 #First# none E ospli/rhel72-64a/x86_64.elinos6.0-release-inner 1 #First# none E ospli/rhel72-64a/x86_64.elinos6.1-dev-inner 1 #First# none -M ospli/rhel72-64a/x86_64.elinos6.1-release-inner 1 #First# none +E ospli/rhel72-64a/x86_64.elinos6.1-release-inner 1 #First# none E ospli/v240a/studio12-dev 60 #First# none E ospli/v240a/studio12-release 60 #First# none @@ -369,7 +305,7 @@ E ospli/v240a/studio12-dev-notest-inner 1 #First# none E ospli/v240a/studio12-dev-inner 1 #First# none E ospli/v240a/studio12-debug-notao-inner 1 #First# none E ospli/v240a/studio12-release 60 #First# none -M ospli/v240a/studio12-release-inner 1 #First# none +E ospli/v240a/studio12-release-inner 1 #First# none E ospli/v240a/studio12-release-notest-inner 1 #First# none E ospli/v240a/studio12-release-examples-inner 1 #First# none E ospli/v240a/studio12-release-nodbt-inner 1 #First# none @@ -390,7 +326,7 @@ E ospli/ultra4/studio12-release-inner 1 #First# none E ospli/ultra4/studio12-release-notest-inner 1 #First# none E ospli/ultra4/studio12_64-release 60 #First# none E ospli/ultra4/studio12_64-release-inner 60 #First# none -M ospli/ultra4/gcc-release-inner 1 #First# none +E ospli/ultra4/gcc-release-inner 1 #First# none E ospli/ultra4/gcc-release-notest-inner 1 #First# none E ospli/ultra4/gcc-dev-inner 1 #First# none @@ -398,7 +334,7 @@ E ospli/win7a/x86.win32-dev 30 #First# none E ospli/win7a/x86.win32-release 30 #First# none E ospli/win7a/x86.win32-dev-inner 1 #First# none E ospli/win7a/x86.win32-dev-notest-inner 1 #First# none -M ospli/win7a/x86.win32-release-inner 1 #First# none +E ospli/win7a/x86.win32-release-inner 1 #First# none E ospli/win7a/x86.win32-release-notest-inner 1 #First# none E ospli/win7a/x86.win32-release-examples-inner 1 #First# none E ospli/win7a/x86.win32-release-nodbt-inner 1 #First# none @@ -416,14 +352,22 @@ E ospli/win7c/x86.win32-dev-vs12-notest-normi-inner 1 #First# none E ospli/win7c/x86.win32-release-vs12-normi-inner 1 #First# none E ospli/win7c/x86.win32-release-vs12-notest-normi-inner 1 #First# none -M ospli/winx/x86.win32-dev-vs12-inner 30 #Third# none -E ospli/winx/x86.win32-release-vs12-notest-inner 30 #First# none +E ospli/win7g/x86.win32-release-vs12-notest-inner 1 #First# none +E ospli/win7g/x86.win32-release-vs12-nodbt-inner 1 #First# none +E ospli/win7g/x86.win32-release-vs12-inner 1 #First# none +E ospli/win7g/x86.win32-dev-vs12-inner 1 #First# none +E ospli/win7g/x86.win32-dev-vs12-notest-inner 1 #First# none +E ospli/win7g/x86.win32-dev-vs12-normi-inner 1 #First# none +E ospli/win7g/x86.win32-dev-vs12-notest-normi-inner 1 #First# none +E ospli/win7g/x86.win32-release-vs12-notest-normi-inner 1 #First# none +E ospli/win7g/x86.win32-release-vs12-normi-inner 1 #First# none +E ospli/win7g/x86.win32-release-vs12-nolic-inner 1 #First# none E ospli/win7b/x86.win32-dev-vs11 30 #First# none E ospli/win7b/x86.win32-release-vs11 30 #First# none E ospli/win7b/x86.win32-dev-vs11-inner 1 #First# none E ospli/win7b/x86.win32-dev-vs11-notest-inner 1 #First# none -M ospli/win7b/x86.win32-release-vs11-inner 1 #First# none +E ospli/win7b/x86.win32-release-vs11-inner 1 #First# none E ospli/win7b/x86.win32-release-vs11-notest-inner 1 #First# none E ospli/win7b/x86.win32-release-vs11-nodbt-inner 1 #First# none E ospli/win7b/x86.win32-dev-vs11-normi-inner 1 #First# none @@ -439,7 +383,7 @@ E ospli/win7-32-ospl-1/x86.win32-release-vs10-inner 1 #First# none E ospli/win7-32-ospl-1/x86.win32-release-vs10-nodbt-inner 1 #First# none E ospli/win7-32-ospl-1/x86.win32-release-vs10-nolic-inner 1 #First# none E ospli/win7-32-ospl-1/x86.win32-release-vs10-notao-inner 1 #First# none -M ospli/win7-32-ospl-1/x86.win32-release-vs10-notest-inner 1 #First# none +E ospli/win7-32-ospl-1/x86.win32-release-vs10-notest-inner 1 #First# none E ospli/win7-32-ospl-1/x86.win32-release-vs10-notest-notao-inner 1 #First# none E ospli/win7-32-ospl-1/x86.win32-release-vs10-netsrc-inner 1 #First# none E ospli/win7-32-ospl-1/x86.win32-release-vs10-examples-inner 1 #First# none @@ -454,7 +398,7 @@ E ospli/win7-32-ospl-2/x86.win32-release-vs10-nolic-inner 1 #First# none E ospli/win7-32-ospl-2/x86.win32-release-vs10-notao-inner 1 #First# none E ospli/win7-32-ospl-2/x86.win32-release-vs10-notest-inner 1 #First# none E ospli/win7-32-ospl-2/x86.win32-release-vs10-notest-notao-inner 1 #First# none -M ospli/win7-32-ospl-2/x86.win32-release-vs10-netsrc-inner 1 #First# none +E ospli/win7-32-ospl-2/x86.win32-release-vs10-netsrc-inner 1 #First# none E ospli/win7-32-ospl-3/x86.win32-dev-vs10-inner 1 #First# none E ospli/win7-32-ospl-3/x86.win32-dev-vs10-notao-inner 1 #First# none @@ -473,7 +417,7 @@ E ospli/win7-32-ospl-4/x86.win32-dev-vs10-inner 1 #First# none E ospli/win7-32-ospl-4/x86.win32-dev-vs10-notao-inner 1 #First# none E ospli/win7-32-ospl-4/x86.win32-dev-vs10-notest-inner 1 #First# none E ospli/win7-32-ospl-4/x86.win32-dev-vs10-notest-notao-inner 1 #First# none -M ospli/win7-32-ospl-4/x86.win32-release-vs10-inner 1 #First# none +E ospli/win7-32-ospl-4/x86.win32-release-vs10-inner 1 #First# none E ospli/win7-32-ospl-4/x86.win32-release-vs10-nodbt-inner 1 #First# none E ospli/win7-32-ospl-4/x86.win32-release-vs10-nolic-inner 1 #First# none E ospli/win7-32-ospl-4/x86.win32-release-vs10-notao-inner 1 #First# none @@ -487,7 +431,7 @@ E ospli/win7a-64/x86_64.win64-dev-inner 1 #First# none E ospli/win7a-64/x86_64.win64-dev-notest-inner 1 #First# none E ospli/win7a-64/x86_64.win64-dev-nocpp-inner 1 #First# none E ospli/win7a-64/x86_64.win64-dev-nojava-inner 1 #First# none -M ospli/win7a-64/x86_64.win64-release-inner 1 #First# none +E ospli/win7a-64/x86_64.win64-release-inner 1 #First# none E ospli/win7a-64/x86_64.win64-release-notao-inner 1 #First# none E ospli/win7a-64/x86_64.win64-release-notest-notao-inner 1 #First# none E ospli/win7a-64/x86_64.win64-release-notest-inner 1 #First# none @@ -537,7 +481,7 @@ E ospli/win7-64-ospl-1/x86_64.win64-dev-inner 1 #First# none E ospli/win7-64-ospl-1/x86_64.win64-dev-notest-inner 1 #First# none E ospli/win7-64-ospl-1/x86_64.win64-dev-nocpp-inner 1 #First# none E ospli/win7-64-ospl-1/x86_64.win64-dev-nojava-inner 1 #First# none -M ospli/win7-64-ospl-1/x86_64.win64-release-inner 1 #First# none +E ospli/win7-64-ospl-1/x86_64.win64-release-inner 1 #First# none E ospli/win7-64-ospl-1/x86_64.win64-release-notao-inner 1 #First# none E ospli/win7-64-ospl-1/x86_64.win64-release-notest-notao-inner 1 #First# none E ospli/win7-64-ospl-1/x86_64.win64-release-notest-inner 1 #First# none @@ -554,7 +498,7 @@ E ospli/win7-64-ospl-2/x86_64.win64-dev-nojava-inner 1 #First# none E ospli/win7-64-ospl-2/x86_64.win64-release-inner 1 #First# none E ospli/win7-64-ospl-2/x86_64.win64-release-notao-inner 1 #First# none E ospli/win7-64-ospl-2/x86_64.win64-release-notest-notao-inner 1 #First# none -M ospli/win7-64-ospl-2/x86_64.win64-release-notest-inner 1 #First# none +E ospli/win7-64-ospl-2/x86_64.win64-release-notest-inner 1 #First# none E ospli/win7-64-ospl-2/x86_64.win64-release-notest-noexamples-inner 1 #First# none E ospli/win7-64-ospl-2/x86_64.win64-release-nodbt-inner 1 #First# none E ospli/win7-64-ospl-2/x86_64.win64-release-nolic-inner 1 #First# none @@ -562,7 +506,7 @@ E ospli/win7-64-ospl-2/x86_64.win64-release-examples-inner 1 #First# none E ospli/win7-64-ospl-3/x86_64.win64-dev 30 #First# none E ospli/win7-64-ospl-3/x86_64.win64-release 30 #First# none -M ospli/win7-64-ospl-3/x86_64.win64-dev-inner 1 #First# none +E ospli/win7-64-ospl-3/x86_64.win64-dev-inner 1 #First# none E ospli/win7-64-ospl-3/x86_64.win64-dev-notest-inner 1 #First# none E ospli/win7-64-ospl-3/x86_64.win64-dev-nocpp-inner 1 #First# none E ospli/win7-64-ospl-3/x86_64.win64-dev-nojava-inner 1 #First# none @@ -580,7 +524,7 @@ E ospli/win7-64-ospl-4/x86_64.win64-dev-inner 1 #First# none E ospli/win7-64-ospl-4/x86_64.win64-dev-notest-inner 1 #First# none E ospli/win7-64-ospl-4/x86_64.win64-dev-nocpp-inner 1 #First# none E ospli/win7-64-ospl-4/x86_64.win64-dev-nojava-inner 1 #First# none -M ospli/win7-64-ospl-4/x86_64.win64-release-inner 1 #Third# none +E ospli/win7-64-ospl-4/x86_64.win64-release-inner 1 #First# none E ospli/win7-64-ospl-4/x86_64.win64-release-notao-inner 1 #First# none E ospli/win7-64-ospl-4/x86_64.win64-release-notest-notao-inner 1 #First# none E ospli/win7-64-ospl-4/x86_64.win64-release-notest-inner 1 #First# none @@ -592,7 +536,7 @@ E ospli/win7e/x86_64.win64-dev-vs12 30 #First# none E ospli/win7e/x86_64.win64-release-vs12 30 #First# none E ospli/win7e/x86_64.win64-dev-vs12-inner 1 #First# none E ospli/win7e/x86_64.win64-dev-vs12-notest-inner 1 #First# none -M ospli/win7e/x86_64.win64-release-vs12-inner 1 #First# none +E ospli/win7e/x86_64.win64-release-vs12-inner 1 #First# none E ospli/win7e/x86_64.win64-release-vs12-notest-inner 1 #First# none E ospli/win7e/x86_64.win64-release-vs12-nolic-inner 1 #First# none E ospli/win7e/x86_64.win64-release-vs12-nodbt-inner 1 #First# none @@ -617,17 +561,29 @@ E ospli/win7f/x86_64.win64-dev-vs14-normi-inner 1 #First# none E ospli/win7f/x86_64.win64-dev-vs14-notest-normi-inner 1 #First# none E ospli/win7f/x86_64.win64-release-vs14-normi-inner 1 #First# none E ospli/win7f/x86_64.win64-release-vs14-notest-normi-inner 1 #First# none -M ospli/win7f/x86_64.win64-dev-vs14-nocpp-inner 1 #First# none +E ospli/win7f/x86_64.win64-dev-vs14-nocpp-inner 1 #First# none E ospli/win7f/x86_64.win64-dev-vs14-nojava-inner 1 #First# none E ospli/win7f/x86_64.win64-debug-vs14-inner 1 #First# none E ospli/win7f/x86_64.win64-debug-vs14-notest-inner 1 #First# none +E ospli/win7h/x86_64.win64-dev-vs12 30 #First# none +E ospli/win7h/x86_64.win64-release-vs12 30 #First# none +E ospli/win7h/x86_64.win64-dev-vs12-inner 1 #First# none +E ospli/win7h/x86_64.win64-dev-vs12-notest-inner 1 #First# none +E ospli/win7h/x86_64.win64-release-vs12-inner 1 #First# none +E ospli/win7h/x86_64.win64-release-vs12-notest-inner 1 #First# none +E ospli/win7h/x86_64.win64-release-vs12-nolic-inner 1 #First# none +E ospli/win7h/x86_64.win64-release-vs12-nodbt-inner 1 #First# none +E ospli/win7h/x86_64.win64-dev-vs12-nocpp-inner 1 #First# none +E ospli/win7h/x86_64.win64-dev-vs12-nojava-inner 1 #First# none +E ospli/win7h/x86_64.win64-debug-vs12-inner 1 #First# none +E ospli/win7h/x86_64.win64-debug-vs12-notest-inner 1 #First# none E ospli/win7d/x86_64.win64-dev-vs11 30 #First# none E ospli/win7d/x86_64.win64-release-vs11 30 #First# none E ospli/win7d/x86_64.win64-dev-vs11-inner 1 #First# none E ospli/win7d/x86_64.win64-dev-vs11-notest-inner 1 #First# none -M ospli/win7d/x86_64.win64-release-vs11-inner 1 #First# none +E ospli/win7d/x86_64.win64-release-vs11-inner 1 #First# none E ospli/win7d/x86_64.win64-release-vs11-notest-inner 1 #First# none E ospli/win7d/x86_64.win64-release-vs11-nodbt-inner 1 #First# none E ospli/win7d/x86_64.win64-dev-vs11-normi-inner 1 #First# none @@ -658,6 +614,14 @@ E ospli/win7-64e/mvme5100_750.int5010.win32-rtec-inner 1 #First# none E ospli/win7-64d/arm.qnx6.5-release-inner 1 #First# none +E ospli/win10-32-ospl-1/x86.win32-dev-vs14-inner 1 #First# none +E ospli/win10-32-ospl-1/x86.win32-dev-vs14-notest-inner 1 #First# none +E ospli/win10-32-ospl-1/x86.win32-release-vs14-inner 1 #First# none +E ospli/win10-32-ospl-1/x86.win32-release-vs14-examples-inner 1 #First# none +E ospli/win10-32-ospl-1/x86.win32-release-vs14-nodbt-inner 1 #First# none +E ospli/win10-32-ospl-1/x86.win32-release-vs14-nolic-inner 1 #First# none +E ospli/win10-32-ospl-1/x86.win32-release-vs14-notest-inner 1 #First# none + E ospli/win10-64-vor-a/x86_64.win64-dev-vs14 30 #First# none E ospli/win10-64-vor-a/x86_64.win64-release-vs14 30 #First# none E ospli/win10-64-vor-a/x86_64.win64-dev-vs14-inner 1 #First# none @@ -692,6 +656,43 @@ E ospli/win10-64-vor-b/x86_64.win64-dev-vs14-nojava-inner 1 #First# none E ospli/win10-64-vor-b/x86_64.win64-debug-vs14-inner 1 #First# none E ospli/win10-64-vor-b/x86_64.win64-debug-vs14-notest-inner 1 #First# none +E ospli/win10-64-vor-c/x86_64.win64-dev-vs14 30 #First# none +E ospli/win10-64-vor-c/x86_64.win64-release-vs14 30 #First# none +E ospli/win10-64-vor-c/x86_64.win64-dev-vs14-inner 1 #First# none +E ospli/win10-64-vor-c/x86_64.win64-dev-vs14-notest-inner 1 #First# none +E ospli/win10-64-vor-c/x86_64.win64-release-vs14-inner 1 #First# none +E ospli/win10-64-vor-c/x86_64.win64-release-vs14-notest-inner 1 #First# none +E ospli/win10-64-vor-c/x86_64.win64-release-vs14-notest-inner 1 #First# none +E ospli/win10-64-vor-c/x86_64.win64-release-vs14-nodbt-inner 1 #First# none +E ospli/win10-64-vor-c/x86_64.win64-dev-vs14-normi-inner 1 #First# none +E ospli/win10-64-vor-c/x86_64.win64-dev-vs14-notest-normi-inner 1 #First# none +E ospli/win10-64-vor-c/x86_64.win64-release-vs14-normi-inner 1 #First# none +E ospli/win10-64-vor-c/x86_64.win64-release-vs14-notest-normi-inner 1 #First# none +E ospli/win10-64-vor-c/x86_64.win64-dev-vs14-nocpp-inner 1 #First# none +E ospli/win10-64-vor-c/x86_64.win64-dev-vs14-nojava-inner 1 #First# none +E ospli/win10-64-vor-c/x86_64.win64-debug-vs14-inner 1 #First# none +E ospli/win10-64-vor-c/x86_64.win64-debug-vs14-notest-inner 1 #First# none + +E ospli/win10-64-vor-d/x86_64.win64-dev-vs14 30 #First# none +E ospli/win10-64-vor-d/x86_64.win64-release-vs14 30 #First# none +E ospli/win10-64-vor-d/x86_64.win64-dev-vs14-inner 1 #First# none +E ospli/win10-64-vor-d/x86_64.win64-dev-vs14-notest-inner 1 #First# none +E ospli/win10-64-vor-d/x86_64.win64-release-vs14-inner 1 #First# none +E ospli/win10-64-vor-d/x86_64.win64-release-vs14-notest-inner 1 #First# none +E ospli/win10-64-vor-d/x86_64.win64-release-vs14-notest-inner 1 #First# none +E ospli/win10-64-vor-d/x86_64.win64-release-vs14-nodbt-inner 1 #First# none +E ospli/win10-64-vor-d/x86_64.win64-dev-vs14-normi-inner 1 #First# none +E ospli/win10-64-vor-d/x86_64.win64-dev-vs14-notest-normi-inner 1 #First# none +E ospli/win10-64-vor-d/x86_64.win64-release-vs14-normi-inner 1 #First# none +E ospli/win10-64-vor-d/x86_64.win64-release-vs14-notest-normi-inner 1 #First# none +E ospli/win10-64-vor-d/x86_64.win64-dev-vs14-nocpp-inner 1 #First# none +E ospli/win10-64-vor-d/x86_64.win64-dev-vs14-nojava-inner 1 #First# none +E ospli/win10-64-vor-d/x86_64.win64-debug-vs14-inner 1 #First# none +E ospli/win10-64-vor-d/x86_64.win64-debug-vs14-notest-inner 1 #First# none + +E ospli/win10-64-ospl-7/x86_64.win64-dev-vs17 30 #First# none +E ospli/win10-64-ospl-7/x86_64.win64-release-vs17 30 #First# none + E ospli/winxp17/x86.win32-dev-vs9 30 #First# none E ospli/winxp17/x86.win32-release-vs9 30 #First# none E ospli/winxp17/x86.win32-dev-vs9-inner 1 #First# none @@ -700,14 +701,6 @@ E ospli/winxp17/x86.win32-release-vs9-inner 1 #First# none E ospli/winxp17/x86.win32-release-vs9-notest-inner 1 #First# none E ospli/winxp17/x86.win32-release-vs9-nodbt-inner 1 #First# none -E ospli/win2008-64a/x86.win32-dev 30 #First# none -E ospli/win2008-64a/x86.win32-release 30 #First# none -E ospli/win2008-64a/x86.win32-dev-inner 1 #First# none -E ospli/win2008-64a/x86.win32-dev-notest-inner 1 #First# none -E ospli/win2008-64a/x86.win32-release-inner 1 #First# none -E ospli/win2008-64a/x86.win32-release-notest-inner 1 #First# none -E ospli/win2008-64a/x86.win32-release-nodbt-inner 1 #First# none - E ospli/win2008-64a/x86_64.win64-debug-notest-notao-inner 1 #First# none E ospli/win2008-64a/x86_64.win64-dev 30 #First# none E ospli/win2008-64a/x86_64.win64-release 30 #First# none @@ -717,23 +710,12 @@ E ospli/win2008-64a/x86_64.win64-dev-nocpp-inner 1 #First# none E ospli/win2008-64a/x86_64.win64-release-inner 1 #First# none E ospli/win2008-64a/x86_64.win64-release-notest-inner 1 #First# none E ospli/win2008-64a/x86_64.win64-release-nodbt-inner 1 #First# none -M ospli/win2008-64a/x86_64.win64-release-notao-inner 1 #First# none +E ospli/win2008-64a/x86_64.win64-release-notao-inner 1 #First# none E ospli/win2008-64a/armv4i.wince7-dev-inner 1 #First# none E ospli/win2008-64a/armv4i.wince7-release-inner 1 #First# none -E ospli/rhel60-64a/x86.linux-dev-inner 1 #First# none -E ospli/rhel60-64a/x86.linux-dev-notest-inner 1 #First# none -E ospli/rhel60-64a/x86.linux-release-inner 1 #First# none -E ospli/rhel60-64a/x86.linux-release-notest-inner 1 #First# none -E ospli/rhel60-64a/x86.linux-release-notao-inner 1 #First# none -E ospli/rhel60-64a/x86.linux-debug-inner 1 #First# none -E ospli/rhel60-64a/x86.linux-debug-notest-inner 1 #First# none -E ospli/rhel60-64a/x86.linux-debug-notao-inner 1 #First# none -E ospli/rhel60-64a/x86.linux-debug-notest-notao-inner 1 #First# none -E ospli/rhel60-64a/x86_64.linux-dev-inner 1 #First# none - -M ospli/rhel60-64a/x86_64.linux-memcheck-inner 1 #First# none +E ospli/rhel60-64a/x86_64.linux-memcheck-inner 1 #First# none E ospli/rhel60-64a/x86_64.linux-dev-notest-inner 1 #First# none E ospli/rhel60-64a/x86_64.linux-release-inner 1 #First# none E ospli/rhel60-64a/x86_64.linux-release-notest-inner 1 #First# none @@ -746,7 +728,7 @@ E ospli/rhel60-64a/x86_64.linux-debug-notest-notao-inner 1 #First# none E ospli/rhel62-64a/x86_64.linux-dev 25 #First# none E ospli/rhel62-64a/x86_64.linux-release 25 #First# none -M ospli/rhel62-64a/x86_64.linux-dev-inner 1 #Third# none +E ospli/rhel62-64a/x86_64.linux-dev-inner 1 #First# none E ospli/rhel62-64a/x86_64.linux-dev-notest-inner 1 #First# none E ospli/rhel62-64a/x86_64.linux-release-inner 1 #First# none E ospli/rhel62-64a/x86_64.linux-release-notest-inner 1 #First# none @@ -769,7 +751,7 @@ E ospli/rhel62-64b/x86_64.linux-dev 25 #First# none E ospli/rhel62-64b/x86_64.linux-release 25 #First# none E ospli/rhel62-64b/x86_64.linux-dev-inner 1 #First# none E ospli/rhel62-64b/x86_64.linux-dev-notest-inner 1 #First# none -M ospli/rhel62-64b/x86_64.linux-release-inner 1 #First# none +E ospli/rhel62-64b/x86_64.linux-release-inner 1 #First# none E ospli/rhel62-64b/x86_64.linux-release-osplo-src-inner 1 #First# none E ospli/rhel62-64b/x86_64.linux-release-notest-inner 1 #First# none E ospli/rhel62-64b/x86_64.linux-release-examples-inner 1 #First# none @@ -797,7 +779,7 @@ E ospli/rhel62-64c/x86_64.linux-debug-notest-inner 1 #First# none E ospli/rhel62-64c/x86_64.linux-debug-notao-inner 1 #First# none E ospli/rhel62-64c/x86_64.linux-debug-notest-notao-inner 1 #First# none E ospli/rhel62-64c/x86_64.linux-release-TAO161-inner 1 #First# none -M ospli/rhel62-64c/x86_64.linux-debug-TAO161-inner 1 #First# none +E ospli/rhel62-64c/x86_64.linux-debug-TAO161-inner 1 #First# none E ospli/rhel62-64c/x86_64.linux-debug-notest-TAO161-inner 1 #First# none @@ -805,26 +787,27 @@ E ospli/rhel64-64b/armv7a_vfp_neon.linux-release-inner 1 #First# none E ospli/rhel64-64b/armv7a_vfp_neon.linux-dev-inner 1 #First# none E ospli/rhel64-64b/E500mc.linux-release-inner 1 #First# none E ospli/rhel64-64b/E500mc.linux-dev-inner 1 #First# none -M ospli/rhel64-64d/E500mc.linux-release-inner 1 #First# none +E ospli/rhel64-64d/E500mc.linux-release-inner 1 #First# none E ospli/rhel64-64d/E500mc.linux-dev-inner 1 #First# none +E ospli/rhel64-64d/E500mc.linux-debug-inner 1 #First# none -M ospli/rhel64-64d/E500mc.linux-release-inner 1 #First# none +E ospli/rhel64-64d/E500mc.linux-release-inner 1 #First# none E ospli/rhel64-64d/E500mc.linux-dev-inner 1 #First# none -M ospli/rhel64-64d/armv7a_vfp_neon.linux-release-inner 1 #First# none +E ospli/rhel64-64d/armv7a_vfp_neon.linux-release-inner 1 #First# none E ospli/rhel64-64d/armv7a_vfp_neon.linux-dev-inner 1 #First# none -M ospli/rhel64-64d/armv7a_vfp_neon.linux-debug-inner 1 #First# none +E ospli/rhel64-64d/armv7a_vfp_neon.linux-debug-inner 1 #First# none E ospli/rhel64-64d/armv7a_vfp_neon.linux-examples-inner 1 #First# none E ospli/rhel64-64c/x86.qnx6.5-release-inner 1 #First# none -M ospli/rhel64-64c/arm.qnx6.5-release-inner 1 #First# none -M ospli/rhel64-64c/x86_64.linux-dev-notestbuild-sp-vg-inner 1 #First# none +E ospli/rhel64-64c/arm.qnx6.5-release-inner 1 #First# none +E ospli/rhel64-64c/x86_64.linux-dev-notestbuild-sp-vg-inner 1 #First# none E ospli/rhel64-64c/x86_64.linux-release-inner 1 #First# none E ospli/rhel64-64c/x86_64.linux-release-notest-inner 1 #First# none E ospli/rhel64-64c/x86_64.linux-dev-inner 1 #First# none E ospli/rhel64-64c/x86_64.linux-dev-notest-inner 1 #First# none E ospli/rhel64-64c/mpc8313e.linux-dev-inner 1 #First# none -M ospli/rhel64-64c/mpc8313e.linux-release-inner 1 #First# none +E ospli/rhel64-64c/mpc8313e.linux-release-inner 1 #First# none E ospli/debian40/x86.linux-dev-inner 1 #First# none E ospli/debian40/x86.linux-dev-notest-inner 1 #First# none @@ -837,7 +820,7 @@ E ospli/rhel60a/x86.linux-dev 25 #First# none E ospli/rhel60a/x86.linux-release 25 #First# none E ospli/rhel60a/x86.linux-dev-inner 1 #First# none E ospli/rhel60a/x86.linux-dev-notest-inner 1 #First# none -M ospli/rhel60a/x86.linux-release-inner 1 #Third# none +E ospli/rhel60a/x86.linux-release-inner 1 #First# none E ospli/rhel60a/x86.linux-release-nolic-inner 1 #First# none E ospli/rhel60a/x86.linux-release-notest-inner 1 #First# none E ospli/rhel60a/x86.linux-release-examples-inner 1 #First# none @@ -849,7 +832,7 @@ E ospli/rhel60a/x86.linux-debug-notest-nolic-inner 1 #First# none E ospli/rhel62-32a/x86.linux-dev 25 #First# none E ospli/rhel62-32a/x86.linux-release 25 #First# none -M ospli/rhel62-32a/x86.linux-dev-inner 1 #First# none +E ospli/rhel62-32a/x86.linux-dev-inner 1 #First# none E ospli/rhel62-32a/x86.linux-dev-notest-inner 1 #First# none E ospli/rhel62-32a/x86.linux-release-inner 1 #First# none E ospli/rhel62-32a/x86.linux-release-nolic-inner 1 #First# none @@ -865,7 +848,7 @@ E ospli/rhel62a/x86.linux-dev 25 #First# none E ospli/rhel62a/x86.linux-release 25 #First# none E ospli/rhel62a/x86.linux-dev-inner 1 #First# none E ospli/rhel62a/x86.linux-dev-notest-inner 1 #First# none -M ospli/rhel62a/x86.linux-release-inner 1 #First# none +E ospli/rhel62a/x86.linux-release-inner 1 #First# none E ospli/rhel62a/x86.linux-release-nolic-inner 1 #First# none E ospli/rhel62a/x86.linux-release-notest-inner 1 #First# none E ospli/rhel62a/x86.linux-release-examples-inner 1 #First# none @@ -885,6 +868,7 @@ E ospli/rhel72a/x86_64.linux-release-examples-inner 1 #First# none E ospli/rhel72a/x86_64.linux-dev 1 #First# none E ospli/rhel72a/x86_64.linux-dev-inner 1 #First# none E ospli/rhel72a/x86_64.linux-debug-inner 1 #First# none +E ospli/rhel72a/x86_64.linux-release-coverity-inner 1 #First# none E ospli/pi3a/armv7l.linux-dev 1 #First# none E ospli/pi3a/armv7l.linux-dev-inner 1 #First# none @@ -904,14 +888,9 @@ E ospli/raspberry1/armv6l.linux-release-notest-inner 1 #First# none E ospli/raspberry1/armv6l.linux-release-nodbt-inner 1 #First# none E ospli/raspberry1/armv6l.linux-debug-notest-noexample-inner 1 #First# none E ospli/raspberry1/armv6l.linux-debug-inner 1 #First# none -E ospli/raspberry1/armv6l.linux-dev 25 #First# none -E ospli/raspberry1/armv6l.linux-release 25 #First# none - -E ospli/bone1/armv7l.linux-dev 25 #First# none -E ospli/bone1/armv7l.linux-release 25 #First# none E ospli/jetson1/armv7l.linux-dev-inner 1 #First# none -M ospli/jetson1/armv7l.linux-release-inner 1 #First# none +E ospli/jetson1/armv7l.linux-release-inner 1 #First# none E ospli/jetson1/armv7l.linux-release-notest-inner 1 #First# none E ospli/jetson1/armv7l.linux-release-examples-inner 1 #First# none @@ -926,7 +905,7 @@ E ospli/bone3/armv7l.linux-release-inner 1 #First# none E ospli/bone3/armv7l.linux-release-notest-inner 1 #First# none E ospli/bone6/armv7l.linux-dev-inner 1 #First# none -M ospli/bone6/armv7l.linux-release-inner 1 #First# none +E ospli/bone6/armv7l.linux-release-inner 1 #First# none E ospli/bone6/armv7l.linux-release-notest-inner 1 #First# none E ospli/bone7/armv7l.linux-dev-inner 1 #First# none @@ -937,61 +916,69 @@ E ospli/ubuntu1204/x86.linux-dev-notest-inner 1 #First# none E ospli/ubuntu1204/x86.linux-dev 25 #First# none E ospli/ubuntu1204/x86.linux-release 25 #First# none E ospli/ubuntu1204/x86.linux-release-inner 1 #First# none -M ospli/ubuntu1204/x86.linux-release-notest-inner 1 #First# none +E ospli/ubuntu1204/x86.linux-release-notest-inner 1 #First# none E ospli/ubuntu1204/x86.linux-release-doxygen-inner 1 #First# none E ospli/ubuntu1204/x86.linux-gcov-inner 1 #First# none E ospli/ubuntu1204-64/x86_64.linux-dev 25 #First# none E ospli/ubuntu1204-64/x86_64.linux-release 25 #First# none E ospli/ubuntu1204-64/x86_64.linux-release-inner 1 #First# none -M ospli/ubuntu1204-64/x86_64.linux-release-notest-inner 1 #First# none +E ospli/ubuntu1204-64/x86_64.linux-release-notest-inner 1 #First# none +E ospli/ubuntu1204-64/x86_64.linux-release-nolic-inner 1 #First# none +E ospli/ubuntu1204-64/x86_64.linux-release-notest-nolic-inner 1 #First# none E ospli/ubuntu1204-64/arm.linaro-release-inner 1 #First# none -M ospli/ubuntu1204-64/cortexa9t.yocto-release-inner 1 #First# none +E ospli/ubuntu1204-64/cortexa9t.yocto-release-inner 1 #First# none E ospli/ubuntu1204b/x86.linux-dev 25 #First# none E ospli/ubuntu1204b/x86.linux-release 25 #First# none E ospli/ubuntu1204b/x86.linux-gcov-inner 25 #First# none E ospli/ubuntu1204b/x86.linux-release-inner 1 #First# none E ospli/ubuntu1204b/x86.linux-release-notest-inner 1 #First# none -M ospli/ubuntu1204b/x86.linux-gcc482-release-inner 1 #First# none +E ospli/ubuntu1204b/x86.linux-gcc482-release-inner 1 #First# none E ospli/ubuntu1204b/x86.linux-gcc482-release-notest-inner 1 #First# none E ospli/ubuntu1204b/x86.linux-gcc482-debug-inner 1 #First# none E ospli/ubuntu1204b/x86.linux-gcc482-dev-inner 1 #First# none -M ospli/ubuntu1204b/cortexa9t_neon.WRlinux5_gcc-release-inner 1 #First# none +E ospli/ubuntu1204b/cortexa9t_neon.WRlinux5_gcc-release-inner 1 #First# none E ospli/ubuntu1204b/cortexa9t_neon.WRlinux5_gcc-dev-inner 1 #First# none -M ospli/ubuntu1204b/intel_atom.WRlinux5_gcc-release-inner 1 #First# none +E ospli/ubuntu1204b/intel_atom.WRlinux5_gcc-release-inner 1 #First# none E ospli/ubuntu1204b/intel_atom.WRlinux5_gcc-dev-inner 1 #First# none -MT ospli/ubuntu1204b/x86.linux-release-werror-inner 1 #Third# none +ET ospli/ubuntu1204b/x86.linux-release-werror-inner 1 #First# none E ospli/ubuntu1204b/x86.linux-release-examples-inner 1 #First# none E ospli/ubuntu1204-64b/x86_64.linux-dev 25 #First# none E ospli/ubuntu1204-64b/x86_64.linux-release 25 #First# none E ospli/ubuntu1204-64b/x86_64.linux-release-inner 1 #First# none E ospli/ubuntu1204-64b/x86_64.linux-release-notest-inner 1 #First# none -M ospli/ubuntu1204-64b/x86_64.linux-gcc482-release-inner 1 #First# none +E ospli/ubuntu1204-64b/x86_64.linux-release-nolic-inner 1 #First# none +E ospli/ubuntu1204-64b/x86_64.linux-release-notest-nolic-inner 1 #First# none +E ospli/ubuntu1204-64b/x86_64.linux-gcc482-release-inner 1 #First# none E ospli/ubuntu1204-64b/x86_64.linux-gcc482-release-notest-inner 1 #First# none E ospli/ubuntu1204-64b/x86_64.linux-gcc482-debug-inner 1 #First# none E ospli/ubuntu1204-64b/x86_64.linux-gcc482-dev-inner 1 #First# none -M ospli/ubuntu1204-64b/armv7l.linux-release-inner 1 #First# none +E ospli/ubuntu1204-64b/armv7l.linux-release-inner 1 #First# none ET ospli/ubuntu1204-64b/x86_64.linux-release-werror-inner 1 #First# none E ospli/ubuntu1404-64a/x86_64.linux-dev-inner 25 #First# none E ospli/ubuntu1404-64a/x86_64.linux-dev-notest-inner 25 #First# none E ospli/ubuntu1404-64a/x86_64.linux-release-inner 1 #First# none E ospli/ubuntu1404-64a/x86_64.linux-release-notest-inner 1 #First# none -M ospli/ubuntu1404-64a/x86.WRlinux7_gcc-release-inner 1 #First# none +E ospli/ubuntu1404-64a/x86.WRlinux7_gcc-release-inner 1 #First# none E ospli/ubuntu1404-64a/x86.WRlinux7_gcc-dev-inner 1 #First# none E ospli/ubuntu1404-64a/x86_64.WRlinux8_gcc-release-inner 1 #First# none E ospli/ubuntu1404-64a/x86_64.WRlinux8_gcc-dev-inner 1 #First# none E ospli/ubuntu1404-64a/armv7l.linux-release-inner 1 #First# none -M ospli/ubuntu1404-64a/armv7l.linux-release-nojava-inner 1 #First# none +E ospli/ubuntu1404-64a/armv7l.linux-release-nojava-inner 1 #First# none E ospli/ubuntu1404-64a/armv7l.linux-release-marvell-inner 1 #First# none -M ospli/ubuntu1404-64a/armv7l.linux-release-nojava-marvell-inner 1 #First# none +E ospli/ubuntu1404-64a/armv7l.linux-release-nojava-marvell-inner 1 #First# none E ospli/ubuntu1404-64a/arm.elinos5.2_linux64-release-thales-inner 1 #First# none -M ospli/ubuntu1404-64a/x86_64.WRlinux7_gcc-release-inner 1 #First# none +E ospli/ubuntu1404-64a/x86_64.WRlinux7_gcc-release-inner 1 #First# none -M ospli/ubuntu1404-64a/armv7at2-vfp-neon.WRlinux7_gcc-release-inner 1 #First# none +E ospli/ubuntu1404-64a/armv7at2-vfp-neon.WRlinux7_gcc-release-inner 1 #First# none +E ospli/ubuntu1404-64a/armv7at2-vfp-neon.WRlinux7_gcc-release-examples-inner 1 #First# none E ospli/ubuntu1404-64a/armv7at2-vfp-neon.WRlinux7_gcc-dev-inner 1 #First# none +E ospli/ubuntu1404-64a/armv7at2-vfp-neon.WRlinux7_gcc-dev-examples-inner 1 #First# none + +E ospli/ubuntu1404-64a/cortexa9t-use.linux-release-inner 1 #First# none E ospli/ubuntu1604-32a/x86.linux-release 120 #First# none E ospli/ubuntu1604-32a/x86.linux-release-inner 120 #First# none @@ -1008,15 +995,9 @@ E ospli/ubuntu1604-64a/x86_64.linux-release-inner 120 #First# none E ospli/ubuntu1604-64a/x86_64.linux-release-notest-inner 120 #First# none E ospli/ubuntu1604-64a/x86_64.linux-release-examples-inner 120 #First# none E ospli/ubuntu1604-64a/x86_64.linux-dev 120 #First# none -E ospli/ubuntu1604-64a/x86_64.linux-dev-inner 120 #First# none +E ospli/ubuntu1604-64a/x86_64.linux-dev-inner 120 #First# none E ospli/ubuntu1604-64a/x86_64.linux-dev-notest-inner 120 #First# none -E ospli/ubuntu1604-64b/x86_64.linux-release-inner 120 #First# none -E ospli/ubuntu1604-64b/x86_64.linux-release-notest-inner 120 #First# none -E ospli/ubuntu1604-64b/x86_64.linux-release-examples-inner 120 #First# none -E ospli/ubuntu1604-64b/x86_64.linux-dev-inner 120 #First# none -E ospli/ubuntu1604-64b/x86_64.linux-dev-notest-inner 120 #First# none - E ospli/ubuntu1804-64a/x86_64.linux-release 120 #First# none E ospli/ubuntu1804-64a/x86_64.linux-release-inner 120 #First# none E ospli/ubuntu1804-64a/x86_64.linux-release-notest-inner 120 #First# none @@ -1028,34 +1009,155 @@ E ospli/ubuntu1804-64a/x86_64.linux-dev-notest-inner 120 #First# none E ospli/rhel4y/PPC7448.lynxos5.linux32-dev-inner 1 #First# none E ospli/rhel4y/PPC7448.lynxos5.linux32-release-inner 1 #First# none E ospli/rhel4y/PPCE600.lynxos5.linux32-dev-inner 1 #First# none -M ospli/rhel4y/PPCE600.lynxos5.linux32-release-inner 1 #First# none +E ospli/rhel4y/PPCE600.lynxos5.linux32-release-inner 1 #First# none E ospli/debian6a-64/PPC440.linux-dev-inner 1 #First# none E ospli/debian6a-64/PPC440.linux-release-inner 1 #First# none -M ospli/debian6a-32/x86.linux_perc-release-inner 1 #First# none +E ospli/debian6a-32/x86.linux_perc-release-inner 1 #First# none E ospli/debian6a-32/x86.linux_perc-release-notest-inner 1 #First# none E ospli/debian6a-32/x86.linux_perc-release-examples-inner 1 #First# none +E ospli/debian9-32-a/x86.linux-release-inner 1 #First# none +E ospli/debian9-32-a/x86.linux-release-notest-inner 1 #First# none +E ospli/debian9-32-a/x86.linux-release-examples-inner 1 #First# none +E ospli/debian9-32-a/x86.linux-release-nodbt-inner 1 #First# none +E ospli/debian9-32-a/x86.linux-dev-inner 1 #First# none +E ospli/debian9-32-a/x86.linux-dev-notest-inner 1 #First# none + +E ospli/debian9-64-p/x86_64.linux-release-inner 1 #First# none +E ospli/debian9-64-p/x86_64.linux-release-notest-inner 1 #First# none +E ospli/debian9-64-p/x86_64.linux-release-notest-nolic-inner 1 #First# none +E ospli/debian9-64-p/x86_64.linux-release-examples-inner 1 #First# none +E ospli/debian9-64-p/x86_64.linux-dev-inner 1 #First# none +E ospli/debian9-64-p/x86_64.linux-dev-notest-inner 1 #First# none +E ospli/debian9-64-p/armhf.linux-release-inner 1 #First# none +E ospli/debian9-64-p/armhf.linux-dev-inner 1 #First# none + E ospli/ultra9/PPC604.vxworks5.5.2-release-inner 1 #First# none -M ospli/rhel5a/PPC604.vxworks6.6-dev-inner 1 #First# none +E ospli/rhel5a/PPC604.vxworks6.6-dev-inner 1 #First# none E ospli/rhel5a/PPC604.vxworks6.6-release-inner 1 #First# none E ospli/priva-debian7/armv7l.linux-release-inner 1 #First# none E ospli/priva-debian7/armv7l.linux-debug-inner 1 #First# none E ospli/priva-debian7/armv7l.linux-dev-inner 1 #First# none +E ospli/macmini/x86_64.darwin10_clang-release 120 #First# none E ospli/macmini/x86_64.darwin10_clang-release-inner 1 #First# none E ospli/macmini/x86_64.darwin10_clang-release-notest-inner 1 #First# none E ospli/macmini/x86_64.darwin10_clang-release-examples-inner 1 #First# none -E ospli/macmini/x86_64.darwin10_clang-release-examples-dbt-inner 1 #First# none +E ospli/macmini/x86_64.darwin10_clang-release-dbt-inner 1 #First# none +E ospli/macmini/x86_64.darwin10_clang-dev 120 #First# none E ospli/macmini/x86_64.darwin10_clang-dev-inner 1 #First# none +E ospli/DDSs-Mac-mini.testnet.ptnl/x86_64.darwin10_clang-release-inner 1 #First# none +E ospli/DDSs-Mac-mini.testnet.ptnl/x86_64.darwin10_clang-release-notest-inner 1 #First# none +E ospli/DDSs-Mac-mini.testnet.ptnl/x86_64.darwin10_clang-release-examples-inner 1 #First# none +E ospli/DDSs-Mac-mini.testnet.ptnl/x86_64.darwin10_clang-release-dbt-inner 1 #First# none +E ospli/DDSs-Mac-mini.testnet.ptnl/x86_64.darwin10_clang-dev-inner 1 #First# none + E ospli/debian8-64a.testnet.ptnl/armv7a_lafp_neon.linux-release-inner 1 #First# none E ospli/debian8-64a.testnet.ptnl/armv7a_lafp_neon.linux-debug-inner 1 #First# none E ospli/debian8-64a.testnet.ptnl/armv7a_lafp_neon.linux-dev-inner 1 #First# none +E ospli/ub1604-epro.testnet.ptnl/aarch64_zynqmp.linux-dev-inner 1 #First# none +E ospli/ub1604-epro.testnet.ptnl/aarch64_zynqmp.linux-release-inner 1 #First# none + +# Replaced by t1040 builds but may be needed in future +#E ospli/ebmr-p/ppc_e5500-linux-release-inner 1 #First# none +#E ospli/ebmr-p/ppc_e5500-linux-dev-inner 1 #First# none +#E ospli/ebmr-p/armhf-linux-release-inner 1 #First# none +#E ospli/ebmr-p/armhf-linux-dev-inner 1 #First# none + +#E ospli/t1040/ppc_e5500-linux-release-inner 1 #First# none +#E ospli/t1040/ppc_e5500-linux-dev-inner 1 #First# none + +#E ospli/rhel4g/x86.linux-dev 25 #Broken# none +#E ospli/rhel4g/x86.linux-release 25 #Broken# none +#E ospli/rhel4g/x86.linux-dev-inner 1 #Broken# none +#E ospli/rhel4g/x86.linux-dev-notest-inner 1 #Broken# none +#E ospli/rhel4g/x86.linux-release-inner 1 #Broken# none +#E ospli/rhel4g/x86.linux-release-notest-inner 1 #Broken# none +#E ospli/rhel4g/x86.linux-release-examples-inner 1 #Broken# none + +# winxp12 cygwin is broken +#E ospli/winxp12/x86.win32-dev 40 #First# none +#E ospli/winxp12/x86.win32-release 40 #First# none +#E ospli/winxp12/x86.win32-dev-inner 1 #First# none +#E ospli/winxp12/x86.win32-dev-notest-inner 1 #First# none +#E ospli/winxp12/x86.win32-dev-notao-inner 1 #First# none +#E ospli/winxp12/x86.win32-dev-notest-notao-inner 1 #Third# none +#E ospli/winxp12/x86.win32-release-inner 1 #First# none +#E ospli/winxp12/x86.win32-release-notest-inner 1 #First# none +#E ospli/winxp12/x86.win32-release-nodbt-inner 1 #First# none +#E ospli/winxp12/x86.vxworks5.5-dev-inner 1 #First# none +#E ospli/winxp12/x86.vxworks5.5-release-inner 1 #Second# none + +# DDS1-WIN2K3 - cygwin is broken +#E ospli/DDS1-WIN2K3/armv4i.wince6-dev-inner 1 #First# none +#E ospli/DDS1-WIN2K3/armv4i.wince6-release-inner 1 #First# none +#E ospli/DDS1-WIN2K3/armv4i.wince6-release-inner 1 #First# none +#E ospli/DDS1-WIN2K3/armv4i.wince6-debug-inner 1 #First# none +#E ospli/DDS1-WIN2K3/x86.win32-dev 40 #First# none +#E ospli/DDS1-WIN2K3/x86.win32-release 40 #First# none +#E ospli/DDS1-WIN2K3/x86.win32-dev-inner 1 #First# none +#E ospli/DDS1-WIN2K3/x86.win32-dev-notest-inner 1 #First# none +#E ospli/DDS1-WIN2K3/x86.win32-release-inner 1 #First# none +#E ospli/DDS1-WIN2K3/x86.win32-release-notest-inner 1 #First# none +#E ospli/DDS1-WIN2K3/x86.win32-release-examples-inner 1 #First# none +#E ospli/DDS1-WIN2K3/x86.win32-release-nodbt-inner 1 #First# none +#E ospli/DDS1-WIN2K3/x86.win32-release-netsrc-inner 1 #First# none + +#E ospli/dds2-win2k3/x86.win32-dev 40 #First# none +#E ospli/dds2-win2k3/x86.win32-release 40 #First# none +#E ospli/dds2-win2k3/x86.win32-dev-inner 1 #First# none +#E ospli/dds2-win2k3/x86.win32-release-inner 1 #First# none +#E ospli/dds2-win2k3/x86.win32-release-nolic-inner 1 #First# none +#E ospli/dds2-win2k3/x86.win32-release-notest-inner 1 #First# none +#E ospli/dds2-win2k3/x86.win32-release-notest-nolic-inner 1 #First# none +#E ospli/dds2-win2k3/x86.win32-release-nodbt-inner 1 #First# none +#E ospli/dds2-win2k3/x86.win32-release-netsrc-inner 1 #First# none +#E ospli/dds2-win2k3/x86.win32-debug-inner 1 #First# none +#E ospli/dds2-win2k3/x86.win32-debug-notest-inner 1 #First# none +#E ospli/dds2-win2k3/x86.win32-debug-notest-notao-inner 1 #First# none + +#E ospli/blade1/x86_64.linux_opencc-release-inner 1 #First# none + +#E ospli/rhel53-64/x86_64.linux-dev 35 #Broken# none +#E ospli/rhel53-64/x86_64.linux-release 35 #Broken# none +#E ospli/rhel53-64/x86_64.linux-dev-inner 1 #Broken# none +#E ospli/rhel53-64/x86_64.linux-dev-notest-inner 1 #Broken# none +#E ospli/rhel53-64/x86_64.linux-release-inner 1 #Broken# none +#E ospli/rhel53-64/x86_64.linux-release-nodbt-inner 1 #Broken# none +#E ospli/rhel53-64/x86_64.linux-release-notest-inner 1 #Broken# none +#E ospli/rhel53-64/x86_64.linux-debug-inner 1 #Broken# none +#E ospli/rhel53-64/x86_64.linux-debug-notest-inner 1 #Broken# none +#E ospli/rhel53-64/arm.elinos5.2_rhel5.3-dev-inner 1 #Broken# none +#E ospli/rhel53-64/arm.elinos5.2_rhel5.3-release-inner 1 #Broken# none + +#M ospli/winx/x86.win32-dev-vs12-inner 30 #Missing# none +#E ospli/winx/x86.win32-release-vs12-notest-inner 30 #Missing# none + +#E ospli/win2008-64a/x86.win32-dev 30 #First# none +#E ospli/win2008-64a/x86.win32-release 30 #First# none +#E ospli/win2008-64a/x86.win32-dev-inner 1 #First# none +#E ospli/win2008-64a/x86.win32-dev-notest-inner 1 #First# none +#E ospli/win2008-64a/x86.win32-release-inner 1 #First# none +#E ospli/win2008-64a/x86.win32-release-notest-inner 1 #First# none +#E ospli/win2008-64a/x86.win32-release-nodbt-inner 1 #First# none + +#E ospli/rhel60-64a/x86.linux-dev-inner 1 #First# none +#E ospli/rhel60-64a/x86.linux-dev-notest-inner 1 #First# none +#E ospli/rhel60-64a/x86.linux-release-inner 1 #First# none +#E ospli/rhel60-64a/x86.linux-release-notest-inner 1 #First# none +#E ospli/rhel60-64a/x86.linux-release-notao-inner 1 #First# none +#E ospli/rhel60-64a/x86.linux-debug-inner 1 #First# none +#E ospli/rhel60-64a/x86.linux-debug-notest-inner 1 #First# none +#E ospli/rhel60-64a/x86.linux-debug-notao-inner 1 #First# none +#E ospli/rhel60-64a/x86.linux-debug-notest-notao-inner 1 #First# none +#E ospli/rhel60-64a/x86_64.linux-dev-inner 1 #First# none + ################################# end First Runs ############################# ############################# Old lic builds Runs ############################# @@ -1247,9 +1349,9 @@ E ospli/ultra9/solaris-dev-notest-gcc342-inner 1 #Old# none E ospli/ultra9/solaris-release-gcc342-inner 1 #Old# none E ospli/ultra9/solaris-release-notest-gcc342-inner 1 #Old# none E ospli/winxp16/PENTIUM3.vxworks6.6-release-inner 1 #Old# none -E ospli/winxp16/PENTIUM3.vxworks6.6-dev-inner 1 #Old# none +E ospli/winxp16/PENTIUM3.vxworks6.6-dev-inner 1 #Old# none E ospli/winxp16/PENTIUM.vxworks6.9.2-release-inner 1 #Old# none -E ospli/winxp16/PENTIUM.vxworks6.9.2-dev-inner 1 #Old# none +E ospli/winxp16/PENTIUM.vxworks6.9.2-dev-inner 1 #Old# none E ospli/winxp17/PPC604.vxworks6.7.win32-dev-inner 1 #Old# none E ospli/winxp17/PPC604.vxworks6.7.win32-release-inner 1 #Old# none E ospli/win7a/ppc.pikeos3.1-release-inner 1 #Old# none diff --git a/build/scripts/overnight/configs/DDS1-WIN2K3/common b/build/scripts/overnight/configs/DDS1-WIN2K3/common index 7bbdce687..7cc1010c6 100644 --- a/build/scripts/overnight/configs/DDS1-WIN2K3/common +++ b/build/scripts/overnight/configs/DDS1-WIN2K3/common @@ -1,7 +1,7 @@ export VS_HOME='/cygdrive/C/Program Files/Microsoft Visual Studio 8/' export VS_ENV_SCRIPT="C:\Program Files\Microsoft Visual Studio 8\Common7\Tools\vsvars32.bat" export WINDOWSSDKDIR='/cygdrive/C/Program Files/Microsoft SDKs/Windows/v6.0A' -export JAVA_HOME="c:/Program Files/Java/jdk1.6.0_18" +export JAVA6_HOME="c:/Program Files/Java/jdk1.6.0_18" export TAO_ROOT=/home/dds/INSTALLED_FOR_DDS/TAO161_0-Windows-vc8-inline-32bit-OpenSpliceDDS_v4.1_UNSUPPORTED_091104 export JACORB_HOME=/home/dds/INSTALLED\ FOR\ DDS/JacORB-v2.3.1.0 export BOOST_ROOT=c:\\cygwin\\home\\dds\\INSTALLED_FOR_DDS\\boost_1_53_0 @@ -9,4 +9,6 @@ export QTDIR=c:\\cygwin\\home\\dds\\INSTALLED_FOR_DDS\\Qt\\4.8.4_vs2010_32bit export GSOAPHOME=/home/dds/INSTALLED\ FOR\ DDS/gsoap-v2.7 export PROTOBUF_HOME=/home/dds/INSTALLED_FOR_DDS/protobuf-2.6.0 export LAUNCH4J_HOME=/home/dds/INSTALLED_FOR_DDS/Launch4j -export PATH=/usr/local/bin:$PATH \ No newline at end of file +export PATH=/usr/local/bin:$PATH +export JAVA_HOME="c:/Program Files/Java/jdk1.7.0_79" +export M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-3.5.3 diff --git a/build/scripts/overnight/configs/DDSs-Mac-mini.testnet.ptnl/common b/build/scripts/overnight/configs/DDSs-Mac-mini.testnet.ptnl/common new file mode 100644 index 000000000..3106fcac9 --- /dev/null +++ b/build/scripts/overnight/configs/DDSs-Mac-mini.testnet.ptnl/common @@ -0,0 +1 @@ +export M2_HOME=/Users/dds/INSTALLED_FOR_DDS/apache-maven-3.5.3 diff --git a/build/scripts/overnight/configs/DDSs-Mac-mini.testnet.ptnl/x86_64.darwin10_clang-dev-inner b/build/scripts/overnight/configs/DDSs-Mac-mini.testnet.ptnl/x86_64.darwin10_clang-dev-inner new file mode 100644 index 000000000..e2803a23a --- /dev/null +++ b/build/scripts/overnight/configs/DDSs-Mac-mini.testnet.ptnl/x86_64.darwin10_clang-dev-inner @@ -0,0 +1 @@ +. configs/common-inner \ No newline at end of file diff --git a/build/scripts/overnight/configs/DDSs-Mac-mini.testnet.ptnl/x86_64.darwin10_clang-release-dbt-inner b/build/scripts/overnight/configs/DDSs-Mac-mini.testnet.ptnl/x86_64.darwin10_clang-release-dbt-inner new file mode 100644 index 000000000..e2803a23a --- /dev/null +++ b/build/scripts/overnight/configs/DDSs-Mac-mini.testnet.ptnl/x86_64.darwin10_clang-release-dbt-inner @@ -0,0 +1 @@ +. configs/common-inner \ No newline at end of file diff --git a/build/scripts/overnight/configs/DDSs-Mac-mini.testnet.ptnl/x86_64.darwin10_clang-release-examples-inner b/build/scripts/overnight/configs/DDSs-Mac-mini.testnet.ptnl/x86_64.darwin10_clang-release-examples-inner new file mode 100644 index 000000000..e2803a23a --- /dev/null +++ b/build/scripts/overnight/configs/DDSs-Mac-mini.testnet.ptnl/x86_64.darwin10_clang-release-examples-inner @@ -0,0 +1 @@ +. configs/common-inner \ No newline at end of file diff --git a/build/scripts/overnight/configs/DDSs-Mac-mini.testnet.ptnl/x86_64.darwin10_clang-release-inner b/build/scripts/overnight/configs/DDSs-Mac-mini.testnet.ptnl/x86_64.darwin10_clang-release-inner new file mode 100644 index 000000000..e2803a23a --- /dev/null +++ b/build/scripts/overnight/configs/DDSs-Mac-mini.testnet.ptnl/x86_64.darwin10_clang-release-inner @@ -0,0 +1 @@ +. configs/common-inner \ No newline at end of file diff --git a/build/scripts/overnight/configs/DDSs-Mac-mini.testnet.ptnl/x86_64.darwin10_clang-release-notest-inner b/build/scripts/overnight/configs/DDSs-Mac-mini.testnet.ptnl/x86_64.darwin10_clang-release-notest-inner new file mode 100644 index 000000000..e2803a23a --- /dev/null +++ b/build/scripts/overnight/configs/DDSs-Mac-mini.testnet.ptnl/x86_64.darwin10_clang-release-notest-inner @@ -0,0 +1 @@ +. configs/common-inner \ No newline at end of file diff --git a/build/scripts/overnight/configs/blade1/common b/build/scripts/overnight/configs/blade1/common new file mode 100644 index 000000000..a146a8403 --- /dev/null +++ b/build/scripts/overnight/configs/blade1/common @@ -0,0 +1 @@ +export M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-3.5.3 diff --git a/build/scripts/overnight/configs/bone1/common b/build/scripts/overnight/configs/bone1/common index 3131a5796..bcdf164b4 100644 --- a/build/scripts/overnight/configs/bone1/common +++ b/build/scripts/overnight/configs/bone1/common @@ -1,5 +1,5 @@ -export JAVA_HOME=/usr/local/jdk1.7.0_60 -export JAVA_COMPATJAR=$JAVA_HOME/jre/lib/rt.jar +export JAVA6_HOME=/usr/local/jdk1.7.0_60 +export JAVA_COMPATJAR=$JAVA6_HOME/jre/lib/rt.jar export JAVA_VERSION_OVERRIDE=1.7 export JACORB_HOME=/home/dds/INSTALLED_FOR_DDS/JacORB-v2.3.1.0 export GSOAPHOME=/home/dds/INSTALLED_FOR_DDS/gsoap_arm @@ -7,3 +7,8 @@ export PROTOBUF_HOME=/home/dds/INSTALLED_FOR_DDS/protobuf-2.6.0 export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib export OVERRIDE_STRICT_CHECKS=no +export JAVA_HOME=/usr/local/jdk1.7.0 +export M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-3.5.3 +export SQLITE_HOME=/home/dds/INSTALLED_FOR_DDS/sqlite-amalgamation-3071602 +export LEVELDB_HOME=/home/dds/INSTALLED_FOR_DDS/leveldb-1.9.0 + diff --git a/build/scripts/overnight/configs/bone3/common b/build/scripts/overnight/configs/bone3/common index 3131a5796..1a766159d 100644 --- a/build/scripts/overnight/configs/bone3/common +++ b/build/scripts/overnight/configs/bone3/common @@ -1,5 +1,5 @@ -export JAVA_HOME=/usr/local/jdk1.7.0_60 -export JAVA_COMPATJAR=$JAVA_HOME/jre/lib/rt.jar +export JAVA6_HOME=/usr/local/jdk1.7.0_60 +export JAVA_COMPATJAR=$JAVA6_HOME/jre/lib/rt.jar export JAVA_VERSION_OVERRIDE=1.7 export JACORB_HOME=/home/dds/INSTALLED_FOR_DDS/JacORB-v2.3.1.0 export GSOAPHOME=/home/dds/INSTALLED_FOR_DDS/gsoap_arm @@ -7,3 +7,5 @@ export PROTOBUF_HOME=/home/dds/INSTALLED_FOR_DDS/protobuf-2.6.0 export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib export OVERRIDE_STRICT_CHECKS=no +export JAVA_HOME=/usr/local/jdk1.7.0 +export M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-3.5.3 diff --git a/build/scripts/overnight/configs/bone6/common b/build/scripts/overnight/configs/bone6/common index 3131a5796..57f12b5de 100644 --- a/build/scripts/overnight/configs/bone6/common +++ b/build/scripts/overnight/configs/bone6/common @@ -1,5 +1,5 @@ -export JAVA_HOME=/usr/local/jdk1.7.0_60 -export JAVA_COMPATJAR=$JAVA_HOME/jre/lib/rt.jar +export JAVA6_HOME=/usr/local/jdk1.7.0_60 +export JAVA_COMPATJAR=$JAVA6_HOME/jre/lib/rt.jar export JAVA_VERSION_OVERRIDE=1.7 export JACORB_HOME=/home/dds/INSTALLED_FOR_DDS/JacORB-v2.3.1.0 export GSOAPHOME=/home/dds/INSTALLED_FOR_DDS/gsoap_arm @@ -7,3 +7,6 @@ export PROTOBUF_HOME=/home/dds/INSTALLED_FOR_DDS/protobuf-2.6.0 export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib export OVERRIDE_STRICT_CHECKS=no +export JAVA_HOME=/usr/local/jdk1.7.0 +export M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-3.5.3 +export PATH=$M2_HOME/bin:$PATH diff --git a/build/scripts/overnight/configs/bone7/common b/build/scripts/overnight/configs/bone7/common index 3131a5796..57f12b5de 100644 --- a/build/scripts/overnight/configs/bone7/common +++ b/build/scripts/overnight/configs/bone7/common @@ -1,5 +1,5 @@ -export JAVA_HOME=/usr/local/jdk1.7.0_60 -export JAVA_COMPATJAR=$JAVA_HOME/jre/lib/rt.jar +export JAVA6_HOME=/usr/local/jdk1.7.0_60 +export JAVA_COMPATJAR=$JAVA6_HOME/jre/lib/rt.jar export JAVA_VERSION_OVERRIDE=1.7 export JACORB_HOME=/home/dds/INSTALLED_FOR_DDS/JacORB-v2.3.1.0 export GSOAPHOME=/home/dds/INSTALLED_FOR_DDS/gsoap_arm @@ -7,3 +7,6 @@ export PROTOBUF_HOME=/home/dds/INSTALLED_FOR_DDS/protobuf-2.6.0 export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib export OVERRIDE_STRICT_CHECKS=no +export JAVA_HOME=/usr/local/jdk1.7.0 +export M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-3.5.3 +export PATH=$M2_HOME/bin:$PATH diff --git a/build/scripts/overnight/configs/dds2-win2k3/common b/build/scripts/overnight/configs/dds2-win2k3/common index 4ce2753df..5327acf30 100644 --- a/build/scripts/overnight/configs/dds2-win2k3/common +++ b/build/scripts/overnight/configs/dds2-win2k3/common @@ -1,11 +1,13 @@ export VS_HOME='/cygdrive/C/Program Files/Microsoft Visual Studio 9.0/' export VS_ENV_SCRIPT="C:\Program Files\Microsoft Visual Studio 9.0\Common7\Tools\vsvars32.bat" export WINDOWSSDKDIR='/cygdrive/C/Program Files/Microsoft SDKs/Windows/v6.0A' -export JAVA_HOME="c:/Program Files/Java/jdk1.6.0_18" +export JAVA6_HOME="c:/Program Files/Java/jdk1.6.0_18" export TAO_ROOT=/home/dds/INSTALLED_FOR_DDS/TAO161_0-Windows-vc9-inline-32bit-OpenSpliceDDS_v4.1_UNSUPPORTED_091104 export JACORB_HOME=/home/dds/INSTALLED\ FOR\ DDS/JacORB-v2.3.1.0 export QTDIR=c:\\cygwin\\home\\dds\\INSTALLED_FOR_DDS\\Qt\\4.8.4_vs2010_32bit export GSOAPHOME=/home/dds/INSTALLED\ FOR\ DDS/gsoap-v2.7 export PROTOBUF_HOME=/home/dds/INSTALLED_FOR_DDS/protobuf-2.6.0 export LAUNCH4J_HOME=/home/dds/INSTALLED_FOR_DDS/Launch4j -export PATH=/usr/local/bin:$PATH \ No newline at end of file +export PATH=/usr/local/bin:$PATH +export JAVA_HOME="c:/Program Files/Java/jdk1.7.0_79" +export M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-3.5.3 diff --git a/build/scripts/overnight/configs/dds3-win2k3/common b/build/scripts/overnight/configs/dds3-win2k3/common index 671081b52..0797db7a4 100644 --- a/build/scripts/overnight/configs/dds3-win2k3/common +++ b/build/scripts/overnight/configs/dds3-win2k3/common @@ -1,11 +1,13 @@ export VS_HOME='/cygdrive/C/Program Files/Microsoft Visual Studio 9.0/' export VS_ENV_SCRIPT="C:\Program Files\Microsoft Visual Studio 9.0\Common7\Tools\vsvars32.bat" export WINDOWSSDKDIR='/cygdrive/C/Program Files/Microsoft SDKs/Windows/v6.0A' -export JAVA_HOME="c:/Program Files/Java/jdk1.6.0_19" +export JAVA6_HOME="c:/Program Files/Java/jdk1.6.0_19" export TAO_ROOT=/home/dds/INSTALLED_FOR_DDS/TAO161_0-Windows-vc9-inline-32bit-OpenSpliceDDS_v4.1_UNSUPPORTED_091104 export JACORB_HOME=/home/dds/INSTALLED\ FOR\ DDS/JacORB-v2.3.1.0 export QTDIR=c:\\cygwin\\home\\dds\\INSTALLED_FOR_DDS\\Qt\\4.8.4_vs2010_32bit export GSOAPHOME=/home/dds/INSTALLED\ FOR\ DDS/gsoap-v2.7 export PROTOBUF_HOME=/home/dds/INSTALLED_FOR_DDS/protobuf-2.6.0 export LAUNCH4J_HOME=/home/dds/INSTALLED_FOR_DDS/Launch4j -export PATH=/usr/local/bin:$PATH \ No newline at end of file +export PATH=/usr/local/bin:$PATH +export JAVA_HOME="c:/Program Files/Java/jdk1.7.0_79" +export M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-3.5.3 diff --git a/build/scripts/overnight/configs/dds3-win2k3/x86.win32-release-examples-inner b/build/scripts/overnight/configs/dds3-win2k3/x86.win32-release-examples-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/dds3-win2k3/x86.win32-release-examples-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/debian40/common b/build/scripts/overnight/configs/debian40/common index 8d2524db2..b4af2ea9b 100644 --- a/build/scripts/overnight/configs/debian40/common +++ b/build/scripts/overnight/configs/debian40/common @@ -1,4 +1,6 @@ -export JAVA_HOME=/usr/local/jdk1.6.0 +export JAVA6_HOME=/usr/local/jdk1.6.0 export JACORB_HOME=/home/dds/INSTALLED\ FOR\ DDS/JacORB-v2.3.1.0 export GSOAPHOME=/home/dds/INSTALLED\ FOR\ DDS/GSOAP -export PROTOBUF_HOME=/home/dds/INSTALLED_FOR_DDS/protobuf-2.6.0 \ No newline at end of file +export PROTOBUF_HOME=/home/dds/INSTALLED_FOR_DDS/protobuf-2.6.0export +export JAVA_HOME=/usr/local/jdk1.7.0 +export M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-3.5.3 diff --git a/build/scripts/overnight/configs/debian6a-64/common b/build/scripts/overnight/configs/debian6a-64/common index 2309fce2a..c3238d4f4 100644 --- a/build/scripts/overnight/configs/debian6a-64/common +++ b/build/scripts/overnight/configs/debian6a-64/common @@ -1,5 +1,7 @@ -export JAVA_HOME=/usr/local/jdk1.6.0 +export JAVA6_HOME=/usr/local/jdk1.6.0 export TAO_ROOT=/home/dds/INSTALLED_FOR_DDS/TAO161_0-RedHat-EL53-gcc412-inline-64bit-OpenSpliceDDS_v4.1_UNSUPPORTED_091104 export JACORB_HOME=/home/dds/INSTALLED\ FOR\ DDS/JacORB-v2.3.1.0 export GSOAPHOME=/home/dds/INSTALLED\ FOR\ DDS/GSOAP -export PROTOBUF_HOME=/home/dds/INSTALLED_FOR_DDS/protobuf-2.6.0 \ No newline at end of file +export PROTOBUF_HOME=/home/dds/INSTALLED_FOR_DDS/protobuf-2.6.0 +export JAVA_HOME=/usr/local/jdk1.7.0 +export M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-3.5.3 diff --git a/build/scripts/overnight/configs/debian8-64a.testnet.ptnl/armv7a_lafp_neon.linux-debug-inner b/build/scripts/overnight/configs/debian8-64a.testnet.ptnl/armv7a_lafp_neon.linux-debug-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/debian8-64a.testnet.ptnl/armv7a_lafp_neon.linux-debug-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/debian8-64a.testnet.ptnl/armv7a_lafp_neon.linux-dev-inner b/build/scripts/overnight/configs/debian8-64a.testnet.ptnl/armv7a_lafp_neon.linux-dev-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/debian8-64a.testnet.ptnl/armv7a_lafp_neon.linux-dev-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/debian8-64a.testnet.ptnl/armv7a_lafp_neon.linux-release-inner b/build/scripts/overnight/configs/debian8-64a.testnet.ptnl/armv7a_lafp_neon.linux-release-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/debian8-64a.testnet.ptnl/armv7a_lafp_neon.linux-release-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/debian8-64a.testnet.ptnl/common b/build/scripts/overnight/configs/debian8-64a.testnet.ptnl/common new file mode 100644 index 000000000..a146a8403 --- /dev/null +++ b/build/scripts/overnight/configs/debian8-64a.testnet.ptnl/common @@ -0,0 +1 @@ +export M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-3.5.3 diff --git a/build/scripts/overnight/configs/debian9-32-a/common b/build/scripts/overnight/configs/debian9-32-a/common new file mode 100644 index 000000000..7ca2a365f --- /dev/null +++ b/build/scripts/overnight/configs/debian9-32-a/common @@ -0,0 +1,9 @@ +export JAVA6_HOME=/usr/local/jdk1.6.0 +export TAO_ROOT=/home/dds/INSTALLED_FOR_DDS/TAO211_0-RedHat-EL62-gcc446-inline-32bit-120927-head +export JACORB_HOME=/home/dds/INSTALLED\ FOR\ DDS/JacORB-v2.3.1.0 +export GSOAPHOME=/home/dds/INSTALLED\ FOR\ DDS/GSOAP +export PROTOBUF_HOME=/home/dds/INSTALLED_FOR_DDS/protobuf-2.6.0 +export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib +unset QTDIR +export JAVA_HOME=/usr/local/jdk1.7.0 +export M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-3.5.3 diff --git a/build/scripts/overnight/configs/debian9-32-a/x86.linux-dev-inner b/build/scripts/overnight/configs/debian9-32-a/x86.linux-dev-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/debian9-32-a/x86.linux-dev-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/debian9-32-a/x86.linux-dev-notest-inner b/build/scripts/overnight/configs/debian9-32-a/x86.linux-dev-notest-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/debian9-32-a/x86.linux-dev-notest-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/debian9-32-a/x86.linux-release-examples-inner b/build/scripts/overnight/configs/debian9-32-a/x86.linux-release-examples-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/debian9-32-a/x86.linux-release-examples-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/debian9-32-a/x86.linux-release-inner b/build/scripts/overnight/configs/debian9-32-a/x86.linux-release-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/debian9-32-a/x86.linux-release-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/debian9-32-a/x86.linux-release-nodbt-inner b/build/scripts/overnight/configs/debian9-32-a/x86.linux-release-nodbt-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/debian9-32-a/x86.linux-release-nodbt-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/debian9-32-a/x86.linux-release-notest-inner b/build/scripts/overnight/configs/debian9-32-a/x86.linux-release-notest-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/debian9-32-a/x86.linux-release-notest-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/debian9-64-p/armhf.linux-dev-inner b/build/scripts/overnight/configs/debian9-64-p/armhf.linux-dev-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/debian9-64-p/armhf.linux-dev-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/debian9-64-p/armhf.linux-release-inner b/build/scripts/overnight/configs/debian9-64-p/armhf.linux-release-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/debian9-64-p/armhf.linux-release-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/debian9-64-p/common b/build/scripts/overnight/configs/debian9-64-p/common new file mode 100644 index 000000000..0db4acfb9 --- /dev/null +++ b/build/scripts/overnight/configs/debian9-64-p/common @@ -0,0 +1,8 @@ +export JAVA_HOME=/usr/local/jdk1.7.0_79 +export M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-3.5.3 +export PATH=$M2_HOME/bin:$PATH +export NODEJS_HOME=/home/dds/INSTALLED_FOR_DDS/nodejs/node-v8.11.1-linux-x64 +export SQLITE_HOME=/home/dds/INSTALLED_FOR_DDS/sqlite-amalgamation-3071602 +export LEVELDB_HOME=/home/dds/INSTALLED_FOR_DDS/leveldb-1.9.0 +export PYTHON_HOME=/home/dds/INSTALLED_FOR_DDS/python/virtualenv/bin + diff --git a/build/scripts/overnight/configs/debian9-64-p/x86_64.linux-dev-inner b/build/scripts/overnight/configs/debian9-64-p/x86_64.linux-dev-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/debian9-64-p/x86_64.linux-dev-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/debian9-64-p/x86_64.linux-dev-notest-inner b/build/scripts/overnight/configs/debian9-64-p/x86_64.linux-dev-notest-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/debian9-64-p/x86_64.linux-dev-notest-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/debian9-64-p/x86_64.linux-release-examples-inner b/build/scripts/overnight/configs/debian9-64-p/x86_64.linux-release-examples-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/debian9-64-p/x86_64.linux-release-examples-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/debian9-64-p/x86_64.linux-release-inner b/build/scripts/overnight/configs/debian9-64-p/x86_64.linux-release-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/debian9-64-p/x86_64.linux-release-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/debian9-64-p/x86_64.linux-release-notest-inner b/build/scripts/overnight/configs/debian9-64-p/x86_64.linux-release-notest-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/debian9-64-p/x86_64.linux-release-notest-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/debian9-64-p/x86_64.linux-release-notest-nolic-inner b/build/scripts/overnight/configs/debian9-64-p/x86_64.linux-release-notest-nolic-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/debian9-64-p/x86_64.linux-release-notest-nolic-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/ebmr-p/common b/build/scripts/overnight/configs/ebmr-p/common new file mode 100644 index 000000000..93eedc2b2 --- /dev/null +++ b/build/scripts/overnight/configs/ebmr-p/common @@ -0,0 +1,2 @@ +export JAVA_HOME=/usr/local/jdk1.7.0 +export M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-3.5.3 diff --git a/build/scripts/overnight/configs/ibmp5/common b/build/scripts/overnight/configs/ibmp5/common index c6b532571..8484a58a8 100644 --- a/build/scripts/overnight/configs/ibmp5/common +++ b/build/scripts/overnight/configs/ibmp5/common @@ -2,3 +2,4 @@ export JAVA_HOME=/usr/local/jdk1.5.0 #export TAO_ROOT=TAO161_0-AIX_53-xlC_EEv80-inline-32bit-OpenSpliceDDS_v4.1_UNSUPPORTED_091104 export EORBHOME=/home/dds/INSTALLED\ FOR\ DDS/eorb-V1-5-4_9th_April_2009 export GSOAPHOME=/home/dds/INSTALLED\ FOR\ DDS/gsoap-v2.7.8 +export M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-3.5.3 diff --git a/build/scripts/overnight/configs/jetson1/common b/build/scripts/overnight/configs/jetson1/common index 993e61921..54d78f603 100644 --- a/build/scripts/overnight/configs/jetson1/common +++ b/build/scripts/overnight/configs/jetson1/common @@ -1,8 +1,10 @@ -export JAVA_HOME=/usr/local/jdk1.7.0_60 -export JAVA_COMPATJAR=$JAVA_HOME/jre/lib/rt.jar +export JAVA6_HOME=/usr/local/jdk1.7.0_60 +export JAVA_COMPATJAR=$JAVA6_HOME/jre/lib/rt.jar export JAVA_VERSION_OVERRIDE=1.7 export JACORB_HOME=/home/dds/INSTALLED_FOR_DDS/JacORB-v2.3.1.0 export GSOAPHOME=/home/dds/INSTALLED_FOR_DDS/gsoap_arm export PROTOBUF_HOME=/home/dds/INSTALLED_FOR_DDS/protobuf-2.6.0 export OVERRIDE_STRICT_CHECKS=no +export JAVA_HOME=/usr/local/jdk1.7.0 +export M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-3.5.3 diff --git a/build/scripts/overnight/configs/macmini/common b/build/scripts/overnight/configs/macmini/common index 7eb4616af..3ebd641a8 100644 --- a/build/scripts/overnight/configs/macmini/common +++ b/build/scripts/overnight/configs/macmini/common @@ -1,12 +1,12 @@ -export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.7.0_80.jdk/Contents/Home/ -export JACORB_HOME=/Users/dds/INSTALLED\ FOR\ DDS/JacORB-v2.3.1.0 -export GSOAPHOME=/Users/dds/INSTALLED_FOR_DDS/gsoap-2.8 +export M2_HOME=/Users/dds/INSTALLED_FOR_DDS/apache-maven-3.5.3 +export MAVEN_UTILS=/Users/dds/INSTALLED_FOR_DDS/maven-utils +#export JACORB_HOME=/Users/dds/INSTALLED\ FOR\ DDS/JacORB-v2.3.1.0 +export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_60.jdk/Contents/Home/ export PROTOBUF_HOME=/Users/dds/INSTALLED_FOR_DDS/protobuf-2.6.1-src export PROTOBUF_LIB_HOME=/Users/dds/INSTALLED_FOR_DDS/protobuf-2.6.1/lib +export GSOAPHOME=/Users/dds/INSTALLED_FOR_DDS/gsoap-2.8 -unset TAO_ROOT +export PATH=$JAVA_HOME/bin:/usr/local/bin:$PATH:/opt/local/bin/:$PROTOBUF_LIB_HOME/../bin export OVERRIDE_STRICT_CHECKS=no -export JAVA_VERSION_OVERRIDE=1.7 -PATH=/Applications/BitRock-15.10.1/bin:/Library/Java/JavaVirtualMachines/jdk1.7.0_80.jdk/Contents/Home/bin:/usr/local/bin:$PATH:/opt/local/bin/:/Users/dds/INSTALLED_FOR_DDS/protobuf-2.6.1/bin/:/usr/bin/ - - +export SQLITE_HOME=/Users/dds/INSTALLED_FOR_DDS/sqlite-amalgamation-3071602 +export LEVELDB_HOME=/Users/dds/INSTALLED_FOR_DDS/leveldb-1.9.0 diff --git a/build/scripts/overnight/configs/pi3a/common b/build/scripts/overnight/configs/pi3a/common index d9e68db3a..218f7a6df 100644 --- a/build/scripts/overnight/configs/pi3a/common +++ b/build/scripts/overnight/configs/pi3a/common @@ -9,3 +9,6 @@ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib unset QTDIR unset TAO_ROOT export OVERRIDE_STRICT_CHECKS=no +export M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-3.5.3 +export SQLITE_HOME=/home/dds/INSTALLED_FOR_DDS/sqlite-amalgamation-3071602 +export LEVELDB_HOME=/home/dds/INSTALLED_FOR_DDS/leveldb-1.9.0 diff --git a/build/scripts/overnight/configs/priva-debian7/common b/build/scripts/overnight/configs/priva-debian7/common new file mode 100644 index 000000000..adc8139ae --- /dev/null +++ b/build/scripts/overnight/configs/priva-debian7/common @@ -0,0 +1,2 @@ +export JAVA_HOME=/home/dds/INSTALLED_FOR_DDS/jdk1.7.0_71 +export M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-3.5.3 diff --git a/build/scripts/overnight/configs/priva0912-linux-dev/common b/build/scripts/overnight/configs/priva0912-linux-dev/common new file mode 100644 index 000000000..2dc4a6990 --- /dev/null +++ b/build/scripts/overnight/configs/priva0912-linux-dev/common @@ -0,0 +1,2 @@ +export JAVA_HOME=/usr/local/jdk1.7.0_79 +export M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-3.5.3 diff --git a/build/scripts/overnight/configs/raspberry1/common b/build/scripts/overnight/configs/raspberry1/common index d80ed61a3..54ec80ac0 100644 --- a/build/scripts/overnight/configs/raspberry1/common +++ b/build/scripts/overnight/configs/raspberry1/common @@ -9,3 +9,4 @@ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib unset QTDIR unset TAO_ROOT export OVERRIDE_STRICT_CHECKS=no +export M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-3.5.3 diff --git a/build/scripts/overnight/configs/rhel4/common b/build/scripts/overnight/configs/rhel4/common new file mode 100644 index 000000000..93eedc2b2 --- /dev/null +++ b/build/scripts/overnight/configs/rhel4/common @@ -0,0 +1,2 @@ +export JAVA_HOME=/usr/local/jdk1.7.0 +export M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-3.5.3 diff --git a/build/scripts/overnight/configs/rhel4d/common b/build/scripts/overnight/configs/rhel4d/common index 1a6787cc7..115e6bfc3 100644 --- a/build/scripts/overnight/configs/rhel4d/common +++ b/build/scripts/overnight/configs/rhel4d/common @@ -1,4 +1,4 @@ -export JAVA_HOME=/usr/local/jdk1.6.0 +export JAVA6_HOME=/usr/local/jdk1.6.0 export TAO_ROOT=/home/dds/INSTALLED_FOR_DDS/TAO161_0-RedHat-ES4-gcc346-inline-32bit-OpenSpliceDDS_v4.1_UNSUPPORTED_091104 export JACORB_HOME=/home/dds/INSTALLED\ FOR\ DDS/JacORB-v2.3.1.0 export GSOAPHOME=/home/dds/INSTALLED\ FOR\ DDS/GSOAP @@ -6,3 +6,5 @@ export PROTOBUF_HOME=/home/dds/INSTALLED_FOR_DDS/protobuf-2.6.0 export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib unset QTDIR +export JAVA_HOME=/usr/local/jdk1.7.0 +export M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-3.5.3 diff --git a/build/scripts/overnight/configs/rhel4e/common b/build/scripts/overnight/configs/rhel4e/common index 3dbdbcc44..5fe9f2722 100644 --- a/build/scripts/overnight/configs/rhel4e/common +++ b/build/scripts/overnight/configs/rhel4e/common @@ -1,7 +1,9 @@ -export JAVA_HOME=/usr/local/jdk1.6.0 +export JAVA6_HOME=/usr/local/jdk1.6.0 export TAO_ROOT=/home/dds/INSTALLED_FOR_DDS/TAO161_0-RedHat-ES4-gcc346-inline-32bit-OpenSpliceDDS_v4.1_UNSUPPORTED_091104 export JACORB_HOME=/home/dds/INSTALLED\ FOR\ DDS/JacORB-v2.3.1.0 export GSOAPHOME=/home/dds/INSTALLED\ FOR\ DDS/GSOAP export PROTOBUF_HOME=/home/dds/INSTALLED_FOR_DDS/protobuf-2.6.0 export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib unset QTDIR +export JAVA_HOME=/usr/local/jdk1.7.0 +export M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-3.5.3 diff --git a/build/scripts/overnight/configs/rhel4g/common b/build/scripts/overnight/configs/rhel4g/common index 3dbdbcc44..5fe9f2722 100644 --- a/build/scripts/overnight/configs/rhel4g/common +++ b/build/scripts/overnight/configs/rhel4g/common @@ -1,7 +1,9 @@ -export JAVA_HOME=/usr/local/jdk1.6.0 +export JAVA6_HOME=/usr/local/jdk1.6.0 export TAO_ROOT=/home/dds/INSTALLED_FOR_DDS/TAO161_0-RedHat-ES4-gcc346-inline-32bit-OpenSpliceDDS_v4.1_UNSUPPORTED_091104 export JACORB_HOME=/home/dds/INSTALLED\ FOR\ DDS/JacORB-v2.3.1.0 export GSOAPHOME=/home/dds/INSTALLED\ FOR\ DDS/GSOAP export PROTOBUF_HOME=/home/dds/INSTALLED_FOR_DDS/protobuf-2.6.0 export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib unset QTDIR +export JAVA_HOME=/usr/local/jdk1.7.0 +export M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-3.5.3 diff --git a/build/scripts/overnight/configs/rhel4y/common b/build/scripts/overnight/configs/rhel4y/common index 4e6bff57f..d9772e1fe 100644 --- a/build/scripts/overnight/configs/rhel4y/common +++ b/build/scripts/overnight/configs/rhel4y/common @@ -1,4 +1,4 @@ -export JAVA_HOME=/usr/local/jdk1.6.0 +export JAVA6_HOME=/usr/local/jdk1.6.0 export TAO_ROOT=/home/dds/INSTALLED_FOR_DDS/TAO161_0-RedHat-ES4-gcc346-inline-32bit-OpenSpliceDDS_v4.1_UNSUPPORTED_091104 export JACORB_HOME=/home/dds/INSTALLED\ FOR\ DDS/JacORB-v2.3.1.0 export BOOST_ROOT=/home/dds/INSTALLED_FOR_DDS/boost_1_53_0 @@ -6,3 +6,5 @@ export GSOAPHOME=/home/dds/INSTALLED\ FOR\ DDS/GSOAP export PROTOBUF_HOME=/home/dds/INSTALLED_FOR_DDS/protobuf-2.6.0 export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib unset QTDIR +export JAVA_HOME=/usr/local/jdk1.7.0 +export M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-3.5.3 diff --git a/build/scripts/overnight/configs/rhel53-64/common b/build/scripts/overnight/configs/rhel53-64/common index 63e6f40f1..e9ab6a763 100644 --- a/build/scripts/overnight/configs/rhel53-64/common +++ b/build/scripts/overnight/configs/rhel53-64/common @@ -1,7 +1,9 @@ -export JAVA_HOME=/usr/local/jdk1.6.0 +export JAVA6_HOME=/usr/local/jdk1.6.0 export TAO_ROOT=/home/dds/INSTALLED_FOR_DDS/TAO211_0-RedHat-EL53-gcc412-inline-64bit-120927-head export JACORB_HOME=/home/dds/INSTALLED\ FOR\ DDS/JacORB-v2.3.1.0 export GSOAPHOME=/home/dds/INSTALLED\ FOR\ DDS/GSOAP export QTDIR=/usr/local/Trolltech/Qt-4.8.5 export PROTOBUF_HOME=/home/dds/INSTALLED_FOR_DDS/protobuf-2.6.0 -export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib \ No newline at end of file +export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib +export JAVA_HOME=/usr/local/jdk1.7.0 +export M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-3.5.3 diff --git a/build/scripts/overnight/configs/rhel53a/common b/build/scripts/overnight/configs/rhel53a/common index 5d7bdd246..008f7ea71 100644 --- a/build/scripts/overnight/configs/rhel53a/common +++ b/build/scripts/overnight/configs/rhel53a/common @@ -1,7 +1,9 @@ -export JAVA_HOME=/usr/local/jdk1.6.0 +export JAVA6_HOME=/usr/local/jdk1.6.0 export TAO_ROOT=/home/dds/INSTALLED_FOR_DDS/TAO211_0-RedHat-EL53-gcc412-inline-32bit-120927 export QTDIR=/usr/local/Trolltech/Qt-4.8.5 export GSOAPHOME=/home/dds/INSTALLED\ FOR\ DDS/GSOAP export JACORB_HOME=/home/dds/INSTALLED_FOR_DDS/JacORB-v2.3.1.0 export PROTOBUF_HOME=/home/dds/INSTALLED_FOR_DDS/protobuf-2.6.0 -export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib \ No newline at end of file +export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib +export JAVA_HOME=/usr/local/jdk1.7.0 +export M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-3.5.3 diff --git a/build/scripts/overnight/configs/rhel54-64b/common b/build/scripts/overnight/configs/rhel54-64b/common index a95148343..264b52d12 100644 --- a/build/scripts/overnight/configs/rhel54-64b/common +++ b/build/scripts/overnight/configs/rhel54-64b/common @@ -1,7 +1,9 @@ -export JAVA_HOME=/usr/local/jdk1.6.0 +export JAVA6_HOME=/usr/local/jdk1.6.0 export TAO_ROOT=/home/dds/INSTALLED_FOR_DDS/TAO211_0-RedHat-EL54-gcc412-inline-64bit-120927-head export JACORB_HOME=/home/dds/INSTALLED\ FOR\ DDS/JacORB-v2.3.1.0 export QTDIR=/usr/local/Trolltech/Qt-4.8.5 export GSOAPHOME=/home/dds/INSTALLED\ FOR\ DDS/GSOAP export PROTOBUF_HOME=/home/dds/INSTALLED_FOR_DDS/protobuf-2.6.0 -export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib \ No newline at end of file +export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib +export JAVA_HOME=/usr/local/jdk1.7.0 +export M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-3.5.3 diff --git a/build/scripts/overnight/configs/rhel54-64c/common b/build/scripts/overnight/configs/rhel54-64c/common index fc15426b7..0968b0817 100644 --- a/build/scripts/overnight/configs/rhel54-64c/common +++ b/build/scripts/overnight/configs/rhel54-64c/common @@ -1,8 +1,10 @@ -export JAVA_HOME=/usr/local/jdk1.6.0 +export JAVA6_HOME=/usr/local/jdk1.6.0 export TAO_ROOT=/home/dds/INSTALLED_FOR_DDS/TAO211_0-RedHat-EL54-gcc412-inline-64bit-120927-head export JACORB_HOME=/home/dds/INSTALLED\ FOR\ DDS/JacORB-v2.3.1.0 export ODBCHOME=/home/dds/INSTALLED\ FOR\ DDS/ODBC export GSOAPHOME=/home/dds/INSTALLED\ FOR\ DDS/GSOAP export QTDIR=/usr/local/Trolltech/Qt-4.8.5 export PROTOBUF_HOME=/home/dds/INSTALLED_FOR_DDS/protobuf-2.6.0 -export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib \ No newline at end of file +export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib +export JAVA_HOME=/usr/local/jdk1.7.0 +export M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-3.5.3 diff --git a/build/scripts/overnight/configs/rhel54b/common b/build/scripts/overnight/configs/rhel54b/common index fcc3977b4..d4c14479b 100644 --- a/build/scripts/overnight/configs/rhel54b/common +++ b/build/scripts/overnight/configs/rhel54b/common @@ -1,7 +1,9 @@ -export JAVA_HOME=/usr/local/jdk1.6.0 +export JAVA6_HOME=/usr/local/jdk1.6.0 export TAO_ROOT=/home/dds/INSTALLED_FOR_DDS/TAO211_0-RedHat-EL54-gcc412-inline-32bit-120927-head export JACORB_HOME=/home/dds/INSTALLED\ FOR\ DDS/JacORB-v2.3.1.0 export QTDIR=/usr/local/Trolltech/Qt-4.8.5 export GSOAPHOME=/home/dds/INSTALLED\ FOR\ DDS/GSOAP export PROTOBUF_HOME=/home/dds/INSTALLED_FOR_DDS/protobuf-2.6.0 -export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib \ No newline at end of file +export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib +export JAVA_HOME=/usr/local/jdk1.7.0 +export M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-3.5.3 diff --git a/build/scripts/overnight/configs/rhel5a/common b/build/scripts/overnight/configs/rhel5a/common index 036c77554..abef37864 100644 --- a/build/scripts/overnight/configs/rhel5a/common +++ b/build/scripts/overnight/configs/rhel5a/common @@ -1,7 +1,9 @@ -export JAVA_HOME=/usr/local/jdk1.6.0 +export JAVA6_HOME=/usr/local/jdk1.6.0 export TAO_ROOT=/home/dds/INSTALLED_FOR_DDS/TAO211_0-RedHat-EL53-gcc412-inline-32bit-120927-head export JACORB_HOME=/home/dds/INSTALLED\ FOR\ DDS/JacORB-v2.3.1.0 export QTDIR=/usr/local/Trolltech/Qt-4.8.5 export GSOAPHOME=/home/dds/INSTALLED\ FOR\ DDS/GSOAP export PROTOBUF_HOME=/home/dds/INSTALLED_FOR_DDS/protobuf-2.6.0 -export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib \ No newline at end of file +export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib +export JAVA_HOME=/usr/local/jdk1.7.0 +export M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-3.5.3 diff --git a/build/scripts/overnight/configs/rhel60-64a/common b/build/scripts/overnight/configs/rhel60-64a/common index 03fe748e6..8524fde67 100644 --- a/build/scripts/overnight/configs/rhel60-64a/common +++ b/build/scripts/overnight/configs/rhel60-64a/common @@ -2,3 +2,5 @@ export PROTOBUF_HOME=/home/dds/INSTALLED_FOR_DDS/protobuf-2.6.0 export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib +export JAVA7_HOME=/usr/local/jdk1.7.0 +export M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-3.5.3 diff --git a/build/scripts/overnight/configs/rhel60a/common b/build/scripts/overnight/configs/rhel60a/common index 80903f2aa..fda35093d 100644 --- a/build/scripts/overnight/configs/rhel60a/common +++ b/build/scripts/overnight/configs/rhel60a/common @@ -1,7 +1,9 @@ -export JAVA_HOME=/usr/local/jdk1.6.0 +export JAVA6_HOME=/usr/local/jdk1.6.0 export TAO_ROOT=/home/dds/INSTALLED_FOR_DDS/TAO211_0-RedHat-EL60-gcc444-inline-32bit-120927-head export GSOAPHOME=/home/dds/INSTALLED\ FOR\ DDS/GSOAP export JACORB_HOME=/home/dds/INSTALLED\ FOR\ DDS/JacORB-v2.3.1.0 export PROTOBUF_HOME=/home/dds/INSTALLED_FOR_DDS/protobuf-2.6.0 export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib unset QTDIR +export JAVA_HOME=/usr/local/jdk1.7.0 +export M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-3.5.3 diff --git a/build/scripts/overnight/configs/rhel62-32a/common b/build/scripts/overnight/configs/rhel62-32a/common index b47e73728..7100d9b2c 100644 --- a/build/scripts/overnight/configs/rhel62-32a/common +++ b/build/scripts/overnight/configs/rhel62-32a/common @@ -1,7 +1,9 @@ -export JAVA_HOME=/usr/local/jdk1.6.0 +export JAVA6_HOME=/usr/local/jdk1.6.0 export TAO_ROOT=/home/dds/INSTALLED_FOR_DDS/TAO211_0-RedHat-EL62-gcc446-inline-32bit-120927-head export QTDIR=/usr/local/Trolltech/Qt-4.8.5 export JACORB_HOME=/home/dds/INSTALLED\ FOR\ DDS/JacORB-v2.3.1.0 export GSOAPHOME=/home/dds/INSTALLED\ FOR\ DDS/GSOAP export PROTOBUF_HOME=/home/dds/INSTALLED_FOR_DDS/protobuf-2.6.0 -export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib \ No newline at end of file +export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib +export JAVA_HOME=/usr/local/jdk1.7.0 +export M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-3.5.3 diff --git a/build/scripts/overnight/configs/rhel62-64a/common b/build/scripts/overnight/configs/rhel62-64a/common index 16fcedec5..14f873514 100644 --- a/build/scripts/overnight/configs/rhel62-64a/common +++ b/build/scripts/overnight/configs/rhel62-64a/common @@ -11,3 +11,4 @@ else fi unset TMP_PLAT_ARCH unset QTDIR +export M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-3.5.3 diff --git a/build/scripts/overnight/configs/rhel62-64a/common-32bit b/build/scripts/overnight/configs/rhel62-64a/common-32bit index 93ca95540..1c778c146 100644 --- a/build/scripts/overnight/configs/rhel62-64a/common-32bit +++ b/build/scripts/overnight/configs/rhel62-64a/common-32bit @@ -1,3 +1,4 @@ -export JAVA_HOME=/home/dds/INSTALLED_FOR_DDS/jdk1.6.0_26_32 +export JAVA6_HOME=/home/dds/INSTALLED_FOR_DDS/jdk1.6.0_26_32 export TAO_ROOT=/home/dds/INSTALLED_FOR_DDS/TAO211_0-RedHat-EL62-gcc446-inline-32bit-120927-head unset QTDIR +export JAVA_HOME=/home/dds/INSTALLED_FOR_DDS/jdk1.7.0_79_32 diff --git a/build/scripts/overnight/configs/rhel62-64a/common-64bit b/build/scripts/overnight/configs/rhel62-64a/common-64bit index b081dc11a..835ea8ab4 100644 --- a/build/scripts/overnight/configs/rhel62-64a/common-64bit +++ b/build/scripts/overnight/configs/rhel62-64a/common-64bit @@ -1,3 +1,4 @@ -export JAVA_HOME=/home/dds/INSTALLED_FOR_DDS/jdk1.6.0_23_64 +export JAVA6_HOME=/home/dds/INSTALLED_FOR_DDS/jdk1.6.0_23_64 export TAO_ROOT=/home/dds/INSTALLED_FOR_DDS/TAO211_0-RedHat-EL62-gcc446-inline-64bit-120927-head unset QTDIR +export JAVA_HOME=/usr/local/jdk1.7.0 \ No newline at end of file diff --git a/build/scripts/overnight/configs/rhel62-64b/common b/build/scripts/overnight/configs/rhel62-64b/common index 7bd5a140f..97b457ef3 100644 --- a/build/scripts/overnight/configs/rhel62-64b/common +++ b/build/scripts/overnight/configs/rhel62-64b/common @@ -1,7 +1,9 @@ -export JAVA_HOME=/home/dds/INSTALLED_FOR_DDS/jdk1.6.0_23_64 +export JAVA6_HOME=/home/dds/INSTALLED_FOR_DDS/jdk1.6.0_23_64 export JACORB_HOME=/home/dds/INSTALLED\ FOR\ DDS/JacORB-v2.3.1.0 export GSOAPHOME=/home/dds/INSTALLED_FOR_DDS/GSOAP export TAO_ROOT=/home/dds/INSTALLED_FOR_DDS/TAO211_0-RedHat-EL62-gcc446-inline-64bit-120927-head export PROTOBUF_HOME=/home/dds/INSTALLED_FOR_DDS/protobuf-2.6.0 export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib unset QTDIR +export JAVA_HOME=/usr/local/jdk1.7.0 +export M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-3.5.3 diff --git a/build/scripts/overnight/configs/rhel62-64c/common b/build/scripts/overnight/configs/rhel62-64c/common index 802940595..6b27b3b9d 100644 --- a/build/scripts/overnight/configs/rhel62-64c/common +++ b/build/scripts/overnight/configs/rhel62-64c/common @@ -4,3 +4,5 @@ export PROTOBUF_HOME=/home/dds/INSTALLED_FOR_DDS/protobuf-2.6.0 export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib unset QTDIR +export JAVA_HOME=/usr/local/jdk1.7.0 +export M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-3.5.3 diff --git a/build/scripts/overnight/configs/rhel62a/common b/build/scripts/overnight/configs/rhel62a/common index bcf4d3493..7ca2a365f 100644 --- a/build/scripts/overnight/configs/rhel62a/common +++ b/build/scripts/overnight/configs/rhel62a/common @@ -1,7 +1,9 @@ -export JAVA_HOME=/usr/local/jdk1.6.0 +export JAVA6_HOME=/usr/local/jdk1.6.0 export TAO_ROOT=/home/dds/INSTALLED_FOR_DDS/TAO211_0-RedHat-EL62-gcc446-inline-32bit-120927-head export JACORB_HOME=/home/dds/INSTALLED\ FOR\ DDS/JacORB-v2.3.1.0 export GSOAPHOME=/home/dds/INSTALLED\ FOR\ DDS/GSOAP export PROTOBUF_HOME=/home/dds/INSTALLED_FOR_DDS/protobuf-2.6.0 export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib unset QTDIR +export JAVA_HOME=/usr/local/jdk1.7.0 +export M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-3.5.3 diff --git a/build/scripts/overnight/configs/rhel63-64b/common b/build/scripts/overnight/configs/rhel63-64b/common new file mode 100644 index 000000000..93eedc2b2 --- /dev/null +++ b/build/scripts/overnight/configs/rhel63-64b/common @@ -0,0 +1,2 @@ +export JAVA_HOME=/usr/local/jdk1.7.0 +export M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-3.5.3 diff --git a/build/scripts/overnight/configs/rhel64-32a/common b/build/scripts/overnight/configs/rhel64-32a/common index 506bc0636..57d364048 100644 --- a/build/scripts/overnight/configs/rhel64-32a/common +++ b/build/scripts/overnight/configs/rhel64-32a/common @@ -1,7 +1,9 @@ -export JAVA_HOME=/usr/local/jdk1.6.0 +export JAVA6_HOME=/usr/local/jdk1.6.0 export TAO_ROOT=/home/dds/INSTALLED_FOR_DDS/TAO161_0-RedHat-EL62-gcc446-inline-FT-120320-head export GSOAPHOME=/home/dds/INSTALLED\ FOR\ DDS/GSOAP export JACORB_HOME=/home/dds/INSTALLED\ FOR\ DDS/JacORB-v2.3.1.0 export PROTOBUF_HOME=/home/dds/INSTALLED_FOR_DDS/protobuf-2.6.0 export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib unset QTDIR +export JAVA_HOME=/usr/local/jdk1.7.0 +export M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-3.5.3 diff --git a/build/scripts/overnight/configs/rhel64-32b/common b/build/scripts/overnight/configs/rhel64-32b/common index 72b0ec403..0aa6517c2 100644 --- a/build/scripts/overnight/configs/rhel64-32b/common +++ b/build/scripts/overnight/configs/rhel64-32b/common @@ -1,5 +1,7 @@ -export JAVA_HOME=/usr/local/jdk1.6.0 +export JAVA6_HOME=/usr/local/jdk1.6.0 export TAO_ROOT=/home/dds/INSTALLED_FOR_DDS/TAO161_0-RedHat-EL62-gcc446-inline-FT-120320-head export GSOAPHOME=/home/dds/INSTALLED\ FOR\ DDS/GSOAP export JACORB_HOME=/home/dds/INSTALLED\ FOR\ DDS/JacORB-v2.3.1.0 unset QTDIR +export JAVA_HOME=/usr/local/jdk1.7.0 +export M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-3.5.3 diff --git a/build/scripts/overnight/configs/rhel64-64a/common b/build/scripts/overnight/configs/rhel64-64a/common new file mode 100644 index 000000000..93eedc2b2 --- /dev/null +++ b/build/scripts/overnight/configs/rhel64-64a/common @@ -0,0 +1,2 @@ +export JAVA_HOME=/usr/local/jdk1.7.0 +export M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-3.5.3 diff --git a/build/scripts/overnight/configs/rhel64-64b/common b/build/scripts/overnight/configs/rhel64-64b/common index a59116cbf..13611008c 100644 --- a/build/scripts/overnight/configs/rhel64-64b/common +++ b/build/scripts/overnight/configs/rhel64-64b/common @@ -1,7 +1,9 @@ export QTDIR=/usr/local/Trolltech/Qt-4.8.5 export GSOAPHOME=/home/dds/INSTALLED_FOR_DDS/GSOAP -export JAVA_HOME=/home/dds/INSTALLED_FOR_DDS/jdk1.6.0_23_64 +export JAVA6_HOME=/home/dds/INSTALLED_FOR_DDS/jdk1.6.0_23_64 export TAO_ROOT=/home/dds/INSTALLED_FOR_DDS/TAO161_0-RedHat-EL62-gcc446-inline-FT-64bit-120320-head export JACORB_HOME=/home/dds/INSTALLED\ FOR\ DDS/JacORB-v2.3.1.0 export PROTOBUF_HOME=/home/dds/INSTALLED_FOR_DDS/protobuf-2.6.0 -export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib \ No newline at end of file +export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib +export JAVA_HOME=/usr/local/jdk1.7.0 +export M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-3.5.3 diff --git a/build/scripts/overnight/configs/rhel64-64c/common b/build/scripts/overnight/configs/rhel64-64c/common new file mode 100644 index 000000000..a146a8403 --- /dev/null +++ b/build/scripts/overnight/configs/rhel64-64c/common @@ -0,0 +1 @@ +export M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-3.5.3 diff --git a/build/scripts/overnight/configs/rhel64-64d/E500mc.linux-debug-inner b/build/scripts/overnight/configs/rhel64-64d/E500mc.linux-debug-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/rhel64-64d/E500mc.linux-debug-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/rhel64-64d/common b/build/scripts/overnight/configs/rhel64-64d/common new file mode 100644 index 000000000..93eedc2b2 --- /dev/null +++ b/build/scripts/overnight/configs/rhel64-64d/common @@ -0,0 +1,2 @@ +export JAVA_HOME=/usr/local/jdk1.7.0 +export M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-3.5.3 diff --git a/build/scripts/overnight/configs/rhel72-64a/common b/build/scripts/overnight/configs/rhel72-64a/common new file mode 100644 index 000000000..3428096a5 --- /dev/null +++ b/build/scripts/overnight/configs/rhel72-64a/common @@ -0,0 +1,6 @@ +JAVA_HOME=/home/dds/INSTALLED_FOR_DDS/jdk1.7.0_80 +export JAVA_HOME +M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-3.5.3 +export M2_HOME +PATH=$M2_HOME/bin:$PATH +export PATH diff --git a/build/scripts/overnight/configs/rhel72a/common b/build/scripts/overnight/configs/rhel72a/common index 87a720262..0a6a245a9 100644 --- a/build/scripts/overnight/configs/rhel72a/common +++ b/build/scripts/overnight/configs/rhel72a/common @@ -1,4 +1,4 @@ -export JAVA_HOME=/home/dds/INSTALLED_FOR_DDS/jdk1.6.0_31 +export JAVA6_HOME=/home/dds/INSTALLED_FOR_DDS/jdk1.6.0_31 export JACORB_HOME=/home/dds/INSTALLED_FOR_DDS/JacORB-v2.3.1.0 export GSOAPHOME=/home/dds/INSTALLED_FOR_DDS/GSOAP export PROTOBUF_HOME=/home/dds/INSTALLED_FOR_DDS/protobuf-2.6.0 @@ -7,3 +7,13 @@ export PATH=$PATH:$PROTOBUF_HOME/src unset TAO_ROOT export OVERRIDE_STRICT_CHECKS=no +export JAVA_HOME=/home/dds/INSTALLED_FOR_DDS/jdk1.7.0_80 +export M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-3.5.3 +export PATH=$M2_HOME/bin:$PATH + + +export SQLITE_HOME=/home/dds/INSTALLED_FOR_DDS/sqlite-amalgamation-3071602 +export LEVELDB_HOME=/home/dds/INSTALLED_FOR_DDS/leveldb-1.9.0 +export NODEJS_HOME=/home/dds/INSTALLED_FOR_DDS/nodejs/node-v8.11.1-linux-x64 + + diff --git a/build/scripts/overnight/configs/rhel72a/x86_64.linux-release-coverity-inner b/build/scripts/overnight/configs/rhel72a/x86_64.linux-release-coverity-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/rhel72a/x86_64.linux-release-coverity-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/sles11/common b/build/scripts/overnight/configs/sles11/common new file mode 100644 index 000000000..93eedc2b2 --- /dev/null +++ b/build/scripts/overnight/configs/sles11/common @@ -0,0 +1,2 @@ +export JAVA_HOME=/usr/local/jdk1.7.0 +export M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-3.5.3 diff --git a/build/scripts/overnight/configs/suse100-vx65-vm1/common b/build/scripts/overnight/configs/suse100-vx65-vm1/common new file mode 100644 index 000000000..a146a8403 --- /dev/null +++ b/build/scripts/overnight/configs/suse100-vx65-vm1/common @@ -0,0 +1 @@ +export M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-3.5.3 diff --git a/build/scripts/overnight/configs/ub1604-epro.testnet.ptnl/aarch64_zynqmp.linux-dev-inner b/build/scripts/overnight/configs/ub1604-epro.testnet.ptnl/aarch64_zynqmp.linux-dev-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/ub1604-epro.testnet.ptnl/aarch64_zynqmp.linux-dev-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/ub1604-epro.testnet.ptnl/aarch64_zynqmp.linux-release-inner b/build/scripts/overnight/configs/ub1604-epro.testnet.ptnl/aarch64_zynqmp.linux-release-inner new file mode 100644 index 000000000..e2803a23a --- /dev/null +++ b/build/scripts/overnight/configs/ub1604-epro.testnet.ptnl/aarch64_zynqmp.linux-release-inner @@ -0,0 +1 @@ +. configs/common-inner \ No newline at end of file diff --git a/build/scripts/overnight/configs/ubuntu1004b/common b/build/scripts/overnight/configs/ubuntu1004b/common new file mode 100644 index 000000000..93eedc2b2 --- /dev/null +++ b/build/scripts/overnight/configs/ubuntu1004b/common @@ -0,0 +1,2 @@ +export JAVA_HOME=/usr/local/jdk1.7.0 +export M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-3.5.3 diff --git a/build/scripts/overnight/configs/ubuntu1004c/common b/build/scripts/overnight/configs/ubuntu1004c/common new file mode 100644 index 000000000..93eedc2b2 --- /dev/null +++ b/build/scripts/overnight/configs/ubuntu1004c/common @@ -0,0 +1,2 @@ +export JAVA_HOME=/usr/local/jdk1.7.0 +export M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-3.5.3 diff --git a/build/scripts/overnight/configs/ubuntu1204-64/common b/build/scripts/overnight/configs/ubuntu1204-64/common index f535aad02..b3c3e2f75 100644 --- a/build/scripts/overnight/configs/ubuntu1204-64/common +++ b/build/scripts/overnight/configs/ubuntu1204-64/common @@ -1,6 +1,8 @@ -export JAVA_HOME=/usr/local/jdk1.6.0 +export JAVA6_HOME=/usr/local/jdk1.6.0 export TAO_ROOT=/home/dds/INSTALLED_FOR_DDS/TAO211_0-RedHat-EL62-gcc446-inline-64bit-120927-head export JACORB_HOME="/home/dds/INSTALLED FOR DDS/JacORB-v2.3.1.0" export GSOAPHOME=/home/dds/INSTALLED_FOR_DDS/GSOAP export PROTOBUF_HOME=/home/dds/INSTALLED_FOR_DDS/protobuf-2.6.0 -export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib \ No newline at end of file +export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib +export JAVA_HOME=/usr/local/jdk1.7.0 +export M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-3.5.3 diff --git a/build/scripts/overnight/configs/ubuntu1204-64b/common b/build/scripts/overnight/configs/ubuntu1204-64b/common index f535aad02..b3c3e2f75 100644 --- a/build/scripts/overnight/configs/ubuntu1204-64b/common +++ b/build/scripts/overnight/configs/ubuntu1204-64b/common @@ -1,6 +1,8 @@ -export JAVA_HOME=/usr/local/jdk1.6.0 +export JAVA6_HOME=/usr/local/jdk1.6.0 export TAO_ROOT=/home/dds/INSTALLED_FOR_DDS/TAO211_0-RedHat-EL62-gcc446-inline-64bit-120927-head export JACORB_HOME="/home/dds/INSTALLED FOR DDS/JacORB-v2.3.1.0" export GSOAPHOME=/home/dds/INSTALLED_FOR_DDS/GSOAP export PROTOBUF_HOME=/home/dds/INSTALLED_FOR_DDS/protobuf-2.6.0 -export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib \ No newline at end of file +export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib +export JAVA_HOME=/usr/local/jdk1.7.0 +export M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-3.5.3 diff --git a/build/scripts/overnight/configs/ubuntu1204/common b/build/scripts/overnight/configs/ubuntu1204/common index 922c641ba..91724ff05 100644 --- a/build/scripts/overnight/configs/ubuntu1204/common +++ b/build/scripts/overnight/configs/ubuntu1204/common @@ -1,6 +1,8 @@ -export JAVA_HOME=/usr/local/jdk1.6.0 +export JAVA6_HOME=/usr/local/jdk1.6.0 export TAO_ROOT=/home/dds/INSTALLED_FOR_DDS/TAO211_0-RedHat-EL62-gcc446-inline-32bit-120927-head export JACORB_HOME="/home/dds/INSTALLED FOR DDS/JacORB-v2.3.1.0" export GSOAPHOME=/home/dds/INSTALLED_FOR_DDS/GSOAP export PROTOBUF_HOME=/home/dds/INSTALLED_FOR_DDS/protobuf-2.6.0 export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib +export JAVA_HOME=/usr/local/jdk1.7.0 +export M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-3.5.3 diff --git a/build/scripts/overnight/configs/ubuntu1204b/common b/build/scripts/overnight/configs/ubuntu1204b/common index 922c641ba..91724ff05 100644 --- a/build/scripts/overnight/configs/ubuntu1204b/common +++ b/build/scripts/overnight/configs/ubuntu1204b/common @@ -1,6 +1,8 @@ -export JAVA_HOME=/usr/local/jdk1.6.0 +export JAVA6_HOME=/usr/local/jdk1.6.0 export TAO_ROOT=/home/dds/INSTALLED_FOR_DDS/TAO211_0-RedHat-EL62-gcc446-inline-32bit-120927-head export JACORB_HOME="/home/dds/INSTALLED FOR DDS/JacORB-v2.3.1.0" export GSOAPHOME=/home/dds/INSTALLED_FOR_DDS/GSOAP export PROTOBUF_HOME=/home/dds/INSTALLED_FOR_DDS/protobuf-2.6.0 export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib +export JAVA_HOME=/usr/local/jdk1.7.0 +export M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-3.5.3 diff --git a/build/scripts/overnight/configs/ubuntu1404-64a/armv7at2-vfp-neon.WRlinux7_gcc-dev-examples-inner b/build/scripts/overnight/configs/ubuntu1404-64a/armv7at2-vfp-neon.WRlinux7_gcc-dev-examples-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/ubuntu1404-64a/armv7at2-vfp-neon.WRlinux7_gcc-dev-examples-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/ubuntu1404-64a/armv7at2-vfp-neon.WRlinux7_gcc-release-examples-inner b/build/scripts/overnight/configs/ubuntu1404-64a/armv7at2-vfp-neon.WRlinux7_gcc-release-examples-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/ubuntu1404-64a/armv7at2-vfp-neon.WRlinux7_gcc-release-examples-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/ubuntu1404-64a/common b/build/scripts/overnight/configs/ubuntu1404-64a/common index f535aad02..1f09198af 100644 --- a/build/scripts/overnight/configs/ubuntu1404-64a/common +++ b/build/scripts/overnight/configs/ubuntu1404-64a/common @@ -1,6 +1,10 @@ -export JAVA_HOME=/usr/local/jdk1.6.0 +export JAVA6_HOME=/usr/local/jdk1.6.0 export TAO_ROOT=/home/dds/INSTALLED_FOR_DDS/TAO211_0-RedHat-EL62-gcc446-inline-64bit-120927-head export JACORB_HOME="/home/dds/INSTALLED FOR DDS/JacORB-v2.3.1.0" export GSOAPHOME=/home/dds/INSTALLED_FOR_DDS/GSOAP export PROTOBUF_HOME=/home/dds/INSTALLED_FOR_DDS/protobuf-2.6.0 -export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib \ No newline at end of file +export NODEJS_HOME=/home/dds/INSTALLED_FOR_DDS/nodejs/node-v8.11.1-linux-x64 +export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib +export JAVA_HOME=/usr/local/jdk1.7.0 +export M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-3.5.3 + diff --git a/build/scripts/overnight/configs/ubuntu1404-64a/cortexa9t-use.linux-release-inner b/build/scripts/overnight/configs/ubuntu1404-64a/cortexa9t-use.linux-release-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/ubuntu1404-64a/cortexa9t-use.linux-release-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/ubuntu1404-64a/x86_64.WRlinux7_gcc-release-noexamples-inner b/build/scripts/overnight/configs/ubuntu1404-64a/x86_64.WRlinux7_gcc-release-noexamples-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/ubuntu1404-64a/x86_64.WRlinux7_gcc-release-noexamples-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/ubuntu1604-32a/common b/build/scripts/overnight/configs/ubuntu1604-32a/common index f47813eca..99f98879e 100644 --- a/build/scripts/overnight/configs/ubuntu1604-32a/common +++ b/build/scripts/overnight/configs/ubuntu1604-32a/common @@ -1,7 +1,12 @@ -export JAVA_HOME=/usr/local/jdk1.6.0 +export JAVA6_HOME=/usr/local/jdk1.6.0 export JACORB_HOME=/home/dds/INSTALLED_FOR_DDS/JacORB-v2.3.1.0 export GSOAPHOME=/home/dds/INSTALLED_FOR_DDS/GSOAP export PROTOBUF_HOME=/home/dds/INSTALLED_FOR_DDS/protobuf-2.6.0 export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib unset TAO_ROOT -export OVERRIDE_STRICT_CHECKS=no \ No newline at end of file +export OVERRIDE_STRICT_CHECKS=no +export JAVA_HOME=/usr/local/jdk1.7.0 +export M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-3.5.3 +export SQLITE_HOME=/home/dds/INSTALLED_FOR_DDS/sqlite-amalgamation-3071602 +export LEVELDB_HOME=/home/dds/INSTALLED_FOR_DDS/leveldb-1.9.0 +export PYTHON_HOME=/home/dds/INSTALLED_FOR_DDS/python/virtualenv/bin diff --git a/build/scripts/overnight/configs/ubuntu1604-64a/common b/build/scripts/overnight/configs/ubuntu1604-64a/common index f47813eca..47e6ed500 100644 --- a/build/scripts/overnight/configs/ubuntu1604-64a/common +++ b/build/scripts/overnight/configs/ubuntu1604-64a/common @@ -1,7 +1,15 @@ -export JAVA_HOME=/usr/local/jdk1.6.0 -export JACORB_HOME=/home/dds/INSTALLED_FOR_DDS/JacORB-v2.3.1.0 +export JAVA6_HOME=/usr/local/jdk1.6.0 export GSOAPHOME=/home/dds/INSTALLED_FOR_DDS/GSOAP export PROTOBUF_HOME=/home/dds/INSTALLED_FOR_DDS/protobuf-2.6.0 export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib +#export JACORB_HOME=/home/dds/INSTALLED_FOR_DDS/JacORB-v2.3.1.0 unset TAO_ROOT -export OVERRIDE_STRICT_CHECKS=no \ No newline at end of file +export OVERRIDE_STRICT_CHECKS=no +export JAVA_HOME=/home/dds/INSTALLED_FOR_DDS/jdk1.7.0_79 +export M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-3.5.3 +export NODEJS_HOME=/home/dds/INSTALLED_FOR_DDS/nodejs/node-v8.11.1-linux-x64 +export SQLITE_HOME=/home/dds/INSTALLED_FOR_DDS/sqlite-amalgamation-3071602 +export LEVELDB_HOME=/home/dds/INSTALLED_FOR_DDS/leveldb-1.9.0 +export PYTHON_HOME=/home/dds/INSTALLED_FOR_DDS/python/virtualenv/bin + + diff --git a/build/scripts/overnight/configs/ubuntu1804-64a/common b/build/scripts/overnight/configs/ubuntu1804-64a/common index f47813eca..2b4eeec4f 100644 --- a/build/scripts/overnight/configs/ubuntu1804-64a/common +++ b/build/scripts/overnight/configs/ubuntu1804-64a/common @@ -1,7 +1,11 @@ -export JAVA_HOME=/usr/local/jdk1.6.0 -export JACORB_HOME=/home/dds/INSTALLED_FOR_DDS/JacORB-v2.3.1.0 +export JAVA6_HOME=/usr/local/jdk1.6.0 +export JAVA_HOME=/usr/local/jdk1.8.0 +#export JACORB_HOME=/home/dds/INSTALLED_FOR_DDS/JacORB-v2.3.1.0 export GSOAPHOME=/home/dds/INSTALLED_FOR_DDS/GSOAP export PROTOBUF_HOME=/home/dds/INSTALLED_FOR_DDS/protobuf-2.6.0 -export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib -unset TAO_ROOT -export OVERRIDE_STRICT_CHECKS=no \ No newline at end of file +export M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-3.5.3 + +export OVERRIDE_STRICT_CHECKS=no +#export PATH=$JAVA_HOME/bin:$PATH +export SQLITE_HOME=/home/dds/INSTALLED_FOR_DDS/sqlite-amalgamation-3071602 +export LEVELDB_HOME=/home/dds/INSTALLED_FOR_DDS/leveldb-1.9.0 diff --git a/build/scripts/overnight/configs/ultra4/common b/build/scripts/overnight/configs/ultra4/common index baa9e70b6..2ae750c91 100644 --- a/build/scripts/overnight/configs/ultra4/common +++ b/build/scripts/overnight/configs/ultra4/common @@ -1,7 +1,11 @@ -JAVA_HOME=/usr/local/jdk1.6.0 +JAVA6_HOME=/usr/local/jdk1.6.0 JACORB_HOME=/export/home/dds/INSTALLED\ FOR\ DDS/JacORB-v2.3.1.0 GSOAPHOME=/export/home/dds/INSTALLED\ FOR\ DDS/GSOAP/ -export JAVA_HOME +export JAVA6_HOME export JACORB_HOME export GSOAPHOME +JAVA_HOME=/usr/local/jdk1.7.0 +export JAVA_HOME +M2_HOME=/export/home/dds/INSTALLED_FOR_DDS/apache-maven-3.5.3 +export M2_HOME diff --git a/build/scripts/overnight/configs/ultra9/common b/build/scripts/overnight/configs/ultra9/common index b20a37fcf..39c7312c1 100644 --- a/build/scripts/overnight/configs/ultra9/common +++ b/build/scripts/overnight/configs/ultra9/common @@ -1,7 +1,11 @@ -JAVA_HOME=/usr/local/jdk1.6.0 +JAVA6_HOME=/usr/local/jdk1.6.0 GSOAPHOME=/home/dds/INSTALLED_FOR_DDS/GSOAP/ JACORB_HOME=/home/dds/INSTALLED_FOR_DDS/JacORB-v2.3.1.0 -export JAVA_HOME +export JAVA6_HOME export GSOAPHOME export JACORB_HOME +JAVA_HOME=/usr/local/jdk1.7.0 +export JAVA_HOME +M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-3.5.3 +export M2_HOME diff --git a/build/scripts/overnight/configs/v240a/common b/build/scripts/overnight/configs/v240a/common index 67c0991e4..ba7b44acc 100644 --- a/build/scripts/overnight/configs/v240a/common +++ b/build/scripts/overnight/configs/v240a/common @@ -1,7 +1,11 @@ -JAVA_HOME=/usr/local/jdk1.6.0 +JAVA6_HOME=/usr/local/jdk1.6.0 JACORB_HOME=/usr/users/dds/INSTALLED\ FOR\ DDS/JacORB-v2.3.1.0 GSOAPHOME=/usr/users/dds/INSTALLED\ FOR\ DDS/GSOAP/ -export JAVA_HOME +export JAVA6_HOME export JACORB_HOME export GSOAPHOME +JAVA_HOME=/usr/local/jdk1.7.0 +export JAVA_HOME +M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-3.5.3 +export M2_HOME diff --git a/build/scripts/overnight/configs/win10-32-ospl-1/common b/build/scripts/overnight/configs/win10-32-ospl-1/common new file mode 100644 index 000000000..b9aedea4a --- /dev/null +++ b/build/scripts/overnight/configs/win10-32-ospl-1/common @@ -0,0 +1,2 @@ +export JAVA7_HOME="c:/Program Files/Java/jdk1.7.0_80" +export M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-3.5.3 diff --git a/build/scripts/overnight/configs/win10-32-ospl-1/x86.win32-dev-vs14-inner b/build/scripts/overnight/configs/win10-32-ospl-1/x86.win32-dev-vs14-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/win10-32-ospl-1/x86.win32-dev-vs14-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/win10-32-ospl-1/x86.win32-dev-vs14-notest-inner b/build/scripts/overnight/configs/win10-32-ospl-1/x86.win32-dev-vs14-notest-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/win10-32-ospl-1/x86.win32-dev-vs14-notest-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/win10-32-ospl-1/x86.win32-release-vs14-examples-inner b/build/scripts/overnight/configs/win10-32-ospl-1/x86.win32-release-vs14-examples-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/win10-32-ospl-1/x86.win32-release-vs14-examples-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/win10-32-ospl-1/x86.win32-release-vs14-inner b/build/scripts/overnight/configs/win10-32-ospl-1/x86.win32-release-vs14-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/win10-32-ospl-1/x86.win32-release-vs14-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/win10-32-ospl-1/x86.win32-release-vs14-netsrc-inner b/build/scripts/overnight/configs/win10-32-ospl-1/x86.win32-release-vs14-netsrc-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/win10-32-ospl-1/x86.win32-release-vs14-netsrc-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/win10-32-ospl-1/x86.win32-release-vs14-nodbt-inner b/build/scripts/overnight/configs/win10-32-ospl-1/x86.win32-release-vs14-nodbt-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/win10-32-ospl-1/x86.win32-release-vs14-nodbt-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/win10-32-ospl-1/x86.win32-release-vs14-nolic-inner b/build/scripts/overnight/configs/win10-32-ospl-1/x86.win32-release-vs14-nolic-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/win10-32-ospl-1/x86.win32-release-vs14-nolic-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/win10-32-ospl-1/x86.win32-release-vs14-notest-inner b/build/scripts/overnight/configs/win10-32-ospl-1/x86.win32-release-vs14-notest-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/win10-32-ospl-1/x86.win32-release-vs14-notest-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/win10-64-ospl-7/common b/build/scripts/overnight/configs/win10-64-ospl-7/common new file mode 100644 index 000000000..4df61d191 --- /dev/null +++ b/build/scripts/overnight/configs/win10-64-ospl-7/common @@ -0,0 +1,13 @@ +export VS_HOME='/cygdrive/c/Program Files (x86)/Microsoft Visual Studio/2017/Community' +export VS_ENV_SCRIPT=`cygpath -w "${VS_HOME}/Common7/Tools/VsDevCmd.bat"` +export WINDOWSSDKDIR='/cygdrive/C/Program Files (x86)/Windows Kits/10' +export GSOAPHOME=/home/dds/INSTALLED_FOR_DDS/gsoap-2.7 +export PROTOBUF_HOME=/home/dds/INSTALLED_FOR_DDS/protobuf-2.6.0 +export PROTOBUF_LIB_HOME=/home/dds/INSTALLED_FOR_DDS/protobuf-2.6.0/src +export LAUNCH4J_HOME=/home/dds/INSTALLED_FOR_DDS/Launch4j +export PATH=$PROTOBUF_HOME/bin:$PATH + +#There is no TAO for VS2015 +unset TAO_ROOT +export OVERRIDE_STRICT_CHECKS=no +export M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-3.5.3 diff --git a/build/scripts/overnight/configs/win10-64-ospl-7/common_64bit b/build/scripts/overnight/configs/win10-64-ospl-7/common_64bit new file mode 100644 index 000000000..7ef172e49 --- /dev/null +++ b/build/scripts/overnight/configs/win10-64-ospl-7/common_64bit @@ -0,0 +1,9 @@ +. ./configs/`hostname`/common + +export VS_ENV_SCRIPT_ARGS="-arch=x64" + +export JAVA6_HOME="c:/Program Files/Java/jdk1.6.0_45" +export JAVA_HOME="c:/Program Files/Java/jdk1.8.0_171" + +export ZLIB_HOME= +export QTDIR=c:\\cygwin\\home\\dds\\INSTALLED_FOR_DDS\\Qt\\4.8.4_vs2010_64bit diff --git a/build/scripts/overnight/configs/win10-64-ospl-7/x86_64.win64-dev-vs17 b/build/scripts/overnight/configs/win10-64-ospl-7/x86_64.win64-dev-vs17 new file mode 100644 index 000000000..07846e1bf --- /dev/null +++ b/build/scripts/overnight/configs/win10-64-ospl-7/x86_64.win64-dev-vs17 @@ -0,0 +1,12 @@ +BUILD=yes +SETUP_TYPE=x86_64.win64-dev +BUILD_DIST=yes +BUILD_EXAMPLES=yes +KEEP_DIST=yes +RUN_DBT=no +RUN_RBT=no +RUN_EXAMPLES_SP=yes +RUN_EXAMPLES_SHM=no +VALGRIND=no + +. configs/`hostname`/common_64bit diff --git a/build/scripts/overnight/configs/win10-64-ospl-7/x86_64.win64-release-vs17 b/build/scripts/overnight/configs/win10-64-ospl-7/x86_64.win64-release-vs17 new file mode 100644 index 000000000..1f3de6e2b --- /dev/null +++ b/build/scripts/overnight/configs/win10-64-ospl-7/x86_64.win64-release-vs17 @@ -0,0 +1,12 @@ +BUILD=yes +SETUP_TYPE=x86_64.win64-release +BUILD_DIST=yes +BUILD_EXAMPLES=yes +KEEP_DIST=yes +RUN_DBT=no +RUN_RBT=no +RUN_EXAMPLES_SP=yes +RUN_EXAMPLES_SHM=no +VALGRIND=no + +. configs/`hostname`/common_64bit diff --git a/build/scripts/overnight/configs/win10-64-vor-a/common b/build/scripts/overnight/configs/win10-64-vor-a/common index 679b2116d..c81438dcd 100644 --- a/build/scripts/overnight/configs/win10-64-vor-a/common +++ b/build/scripts/overnight/configs/win10-64-vor-a/common @@ -4,8 +4,7 @@ export VS_HOME='/cygdrive/C/Program Files (x86)/Microsoft Visual Studio 14.0' export WINDOWSSDKDIR='/cygdrive/C/Program Files (x86)/Windows Kits/10' export JACORB_HOME=/home/dds/INSTALLED_FOR_DDS/JacORB-v2.3.1.0 export GSOAPHOME=/home/dds/INSTALLED_FOR_DDS/gsoap-v2.7 -export PROTOBUF_HOME=/home/dds/INSTALLED_FOR_DDS/protobuf-2.6.0 -export PROTOBUF_LIB_HOME=/home/dds/INSTALLED_FOR_DDS/protobuf-2.6.0/src +export PROTOBUF_HOME=/home/dds/INSTALLED_FOR_DDS/protobuf-2.6.0-vs2015 export LAUNCH4J_HOME=/home/dds/INSTALLED_FOR_DDS/Launch4j export PATH=/usr/local/bin:$PROTOBUF_HOME/bin:$PATH @@ -17,3 +16,6 @@ unset USERPROFILE #There is no TAO for VS2015 unset TAO_ROOT export OVERRIDE_STRICT_CHECKS=no +export M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-3.5.3 +export SQLITE_HOME=/home/dds/INSTALLED_FOR_DDS/sqlite-amalgamation-3071602 +export PYTHON_HOME=/home/dds/INSTALLED_FOR_DDS/portablepython-2.7.3.1 diff --git a/build/scripts/overnight/configs/win10-64-vor-a/common_64bit b/build/scripts/overnight/configs/win10-64-vor-a/common_64bit index f703c1438..385b42ce3 100644 --- a/build/scripts/overnight/configs/win10-64-vor-a/common_64bit +++ b/build/scripts/overnight/configs/win10-64-vor-a/common_64bit @@ -2,6 +2,7 @@ export VS_ENV_SCRIPT="C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\x86_amd64\vcvarsx86_amd64.bat" -export JAVA_HOME="c:/Program Files/Java/jdk1.6.0_39" +export JAVA6_HOME="c:/Program Files/Java/jdk1.6.0_37" +export JAVA_HOME="c:/Program Files/Java/jdk1.7.0_80" export ZLIB_HOME= -export QTDIR=c:\\cygwin\\home\\dds\\INSTALLED_FOR_DDS\\Qt\\4.8.4_vs2010_64bit +export QTDIR=c:\\cygwin64\\home\\dds\\INSTALLED_FOR_DDS\\Qt\\4.8.4_vs2010_64bit diff --git a/build/scripts/overnight/configs/win10-64-vor-a/x86_64.win64-debug-vs14-inner b/build/scripts/overnight/configs/win10-64-vor-a/x86_64.win64-debug-vs14-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/win10-64-vor-a/x86_64.win64-debug-vs14-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/win10-64-vor-a/x86_64.win64-debug-vs14-notest-inner b/build/scripts/overnight/configs/win10-64-vor-a/x86_64.win64-debug-vs14-notest-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/win10-64-vor-a/x86_64.win64-debug-vs14-notest-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/win10-64-vor-a/x86_64.win64-dev-vs14-inner b/build/scripts/overnight/configs/win10-64-vor-a/x86_64.win64-dev-vs14-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/win10-64-vor-a/x86_64.win64-dev-vs14-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/win10-64-vor-a/x86_64.win64-dev-vs14-nocpp-inner b/build/scripts/overnight/configs/win10-64-vor-a/x86_64.win64-dev-vs14-nocpp-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/win10-64-vor-a/x86_64.win64-dev-vs14-nocpp-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/win10-64-vor-a/x86_64.win64-dev-vs14-nojava-inner b/build/scripts/overnight/configs/win10-64-vor-a/x86_64.win64-dev-vs14-nojava-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/win10-64-vor-a/x86_64.win64-dev-vs14-nojava-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/win10-64-vor-a/x86_64.win64-dev-vs14-normi-inner b/build/scripts/overnight/configs/win10-64-vor-a/x86_64.win64-dev-vs14-normi-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/win10-64-vor-a/x86_64.win64-dev-vs14-normi-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/win10-64-vor-a/x86_64.win64-dev-vs14-notest-inner b/build/scripts/overnight/configs/win10-64-vor-a/x86_64.win64-dev-vs14-notest-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/win10-64-vor-a/x86_64.win64-dev-vs14-notest-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/win10-64-vor-a/x86_64.win64-dev-vs14-notest-normi-inner b/build/scripts/overnight/configs/win10-64-vor-a/x86_64.win64-dev-vs14-notest-normi-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/win10-64-vor-a/x86_64.win64-dev-vs14-notest-normi-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/win10-64-vor-a/x86_64.win64-release-vs14-examples-inner b/build/scripts/overnight/configs/win10-64-vor-a/x86_64.win64-release-vs14-examples-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/win10-64-vor-a/x86_64.win64-release-vs14-examples-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/win10-64-vor-a/x86_64.win64-release-vs14-inner b/build/scripts/overnight/configs/win10-64-vor-a/x86_64.win64-release-vs14-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/win10-64-vor-a/x86_64.win64-release-vs14-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/win10-64-vor-a/x86_64.win64-release-vs14-nodbt-inner b/build/scripts/overnight/configs/win10-64-vor-a/x86_64.win64-release-vs14-nodbt-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/win10-64-vor-a/x86_64.win64-release-vs14-nodbt-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/win10-64-vor-a/x86_64.win64-release-vs14-normi-inner b/build/scripts/overnight/configs/win10-64-vor-a/x86_64.win64-release-vs14-normi-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/win10-64-vor-a/x86_64.win64-release-vs14-normi-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/win10-64-vor-a/x86_64.win64-release-vs14-notest-inner b/build/scripts/overnight/configs/win10-64-vor-a/x86_64.win64-release-vs14-notest-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/win10-64-vor-a/x86_64.win64-release-vs14-notest-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/win10-64-vor-a/x86_64.win64-release-vs14-notest-normi-inner b/build/scripts/overnight/configs/win10-64-vor-a/x86_64.win64-release-vs14-notest-normi-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/win10-64-vor-a/x86_64.win64-release-vs14-notest-normi-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/win10-64-vor-b/common b/build/scripts/overnight/configs/win10-64-vor-b/common index eb76060d5..c81438dcd 100644 --- a/build/scripts/overnight/configs/win10-64-vor-b/common +++ b/build/scripts/overnight/configs/win10-64-vor-b/common @@ -16,3 +16,6 @@ unset USERPROFILE #There is no TAO for VS2015 unset TAO_ROOT export OVERRIDE_STRICT_CHECKS=no +export M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-3.5.3 +export SQLITE_HOME=/home/dds/INSTALLED_FOR_DDS/sqlite-amalgamation-3071602 +export PYTHON_HOME=/home/dds/INSTALLED_FOR_DDS/portablepython-2.7.3.1 diff --git a/build/scripts/overnight/configs/win10-64-vor-b/common_64bit b/build/scripts/overnight/configs/win10-64-vor-b/common_64bit index d5986dd29..8bc0b3727 100644 --- a/build/scripts/overnight/configs/win10-64-vor-b/common_64bit +++ b/build/scripts/overnight/configs/win10-64-vor-b/common_64bit @@ -2,7 +2,8 @@ export VS_ENV_SCRIPT="C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\x86_amd64\vcvarsx86_amd64.bat" -export JAVA_HOME="c:/Program Files/Java/jdk1.6.0_37" +export JAVA6_HOME="c:/Program Files/Java/jdk1.6.0_37" +export JAVA_HOME="c:/Program Files/Java/jdk1.7.0_80" export ZLIB_HOME= export QTDIR=c:\\cygwin64\\home\\dds\\INSTALLED_FOR_DDS\\Qt\\4.8.4_vs2010_64bit export PROTOBUF_HOME=/home/dds/INSTALLED_FOR_DDS/protobuf-2.6.0-vs2015 diff --git a/build/scripts/overnight/configs/win10-64-vor-b/x86_64.win64-debug-vs14-inner b/build/scripts/overnight/configs/win10-64-vor-b/x86_64.win64-debug-vs14-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/win10-64-vor-b/x86_64.win64-debug-vs14-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/win10-64-vor-b/x86_64.win64-debug-vs14-notest-inner b/build/scripts/overnight/configs/win10-64-vor-b/x86_64.win64-debug-vs14-notest-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/win10-64-vor-b/x86_64.win64-debug-vs14-notest-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/win10-64-vor-b/x86_64.win64-dev-vs14-inner b/build/scripts/overnight/configs/win10-64-vor-b/x86_64.win64-dev-vs14-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/win10-64-vor-b/x86_64.win64-dev-vs14-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/win10-64-vor-b/x86_64.win64-dev-vs14-nocpp-inner b/build/scripts/overnight/configs/win10-64-vor-b/x86_64.win64-dev-vs14-nocpp-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/win10-64-vor-b/x86_64.win64-dev-vs14-nocpp-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/win10-64-vor-b/x86_64.win64-dev-vs14-nojava-inner b/build/scripts/overnight/configs/win10-64-vor-b/x86_64.win64-dev-vs14-nojava-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/win10-64-vor-b/x86_64.win64-dev-vs14-nojava-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/win10-64-vor-b/x86_64.win64-dev-vs14-normi-inner b/build/scripts/overnight/configs/win10-64-vor-b/x86_64.win64-dev-vs14-normi-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/win10-64-vor-b/x86_64.win64-dev-vs14-normi-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/win10-64-vor-b/x86_64.win64-dev-vs14-notest-inner b/build/scripts/overnight/configs/win10-64-vor-b/x86_64.win64-dev-vs14-notest-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/win10-64-vor-b/x86_64.win64-dev-vs14-notest-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/win10-64-vor-b/x86_64.win64-dev-vs14-notest-normi-inner b/build/scripts/overnight/configs/win10-64-vor-b/x86_64.win64-dev-vs14-notest-normi-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/win10-64-vor-b/x86_64.win64-dev-vs14-notest-normi-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/win10-64-vor-b/x86_64.win64-release-vs14-inner b/build/scripts/overnight/configs/win10-64-vor-b/x86_64.win64-release-vs14-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/win10-64-vor-b/x86_64.win64-release-vs14-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/win10-64-vor-b/x86_64.win64-release-vs14-nodbt-inner b/build/scripts/overnight/configs/win10-64-vor-b/x86_64.win64-release-vs14-nodbt-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/win10-64-vor-b/x86_64.win64-release-vs14-nodbt-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/win10-64-vor-b/x86_64.win64-release-vs14-normi-inner b/build/scripts/overnight/configs/win10-64-vor-b/x86_64.win64-release-vs14-normi-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/win10-64-vor-b/x86_64.win64-release-vs14-normi-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/win10-64-vor-b/x86_64.win64-release-vs14-notest-inner b/build/scripts/overnight/configs/win10-64-vor-b/x86_64.win64-release-vs14-notest-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/win10-64-vor-b/x86_64.win64-release-vs14-notest-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/win10-64-vor-b/x86_64.win64-release-vs14-notest-normi-inner b/build/scripts/overnight/configs/win10-64-vor-b/x86_64.win64-release-vs14-notest-normi-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/win10-64-vor-b/x86_64.win64-release-vs14-notest-normi-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/win10-64-vor-c/common b/build/scripts/overnight/configs/win10-64-vor-c/common index 6cd432ca7..21c6e1b59 100644 --- a/build/scripts/overnight/configs/win10-64-vor-c/common +++ b/build/scripts/overnight/configs/win10-64-vor-c/common @@ -7,8 +7,11 @@ export GSOAPHOME=/home/dds/INSTALLED_FOR_DDS/gsoap-v2.7 export PROTOBUF_HOME=/home/dds/INSTALLED_FOR_DDS/protobuf-2.6.0 export PROTOBUF_LIB_HOME=/home/dds/INSTALLED_FOR_DDS/protobuf-2.6.0/src export LAUNCH4J_HOME=/home/dds/INSTALLED_FOR_DDS/Launch4j -export PATH=$PROTOBUF_HOME/bin:$PATH +export PATH=/usr/local/bin:$PROTOBUF_HOME/bin:$PATH #There is no TAO for VS2015 unset TAO_ROOT export OVERRIDE_STRICT_CHECKS=no +export M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-3.5.3 +export SQLITE_HOME=/home/dds/INSTALLED_FOR_DDS/sqlite-amalgamation-3071602 +export PYTHON_HOME=/home/dds/INSTALLED_FOR_DDS/portablepython-2.7.3.1 diff --git a/build/scripts/overnight/configs/win10-64-vor-c/common_64bit b/build/scripts/overnight/configs/win10-64-vor-c/common_64bit index f703c1438..3bb3c135d 100644 --- a/build/scripts/overnight/configs/win10-64-vor-c/common_64bit +++ b/build/scripts/overnight/configs/win10-64-vor-c/common_64bit @@ -2,6 +2,14 @@ export VS_ENV_SCRIPT="C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\x86_amd64\vcvarsx86_amd64.bat" -export JAVA_HOME="c:/Program Files/Java/jdk1.6.0_39" +export JAVA6_HOME="c:/Program Files/Java/jdk1.6.0_37" +export JAVA_HOME="c:/Program Files/Java/jdk1.7.0_80" export ZLIB_HOME= export QTDIR=c:\\cygwin\\home\\dds\\INSTALLED_FOR_DDS\\Qt\\4.8.4_vs2010_64bit + +#Multiple python3 installs separated with ':' +export PYTHON3_HOME=\ +/home/dds/INSTALLED_FOR_DDS/python-3.5.4-win64/python:\ +/home/dds/INSTALLED_FOR_DDS/python-3.6.4-win64/python + +export NODEJS_HOME=/home/dds/INSTALLED_FOR_DDS/nodejs/node-v8.11.1-win-x64 diff --git a/build/scripts/overnight/configs/win10-64-vor-c/x86_64.win64-debug-vs14-inner b/build/scripts/overnight/configs/win10-64-vor-c/x86_64.win64-debug-vs14-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/win10-64-vor-c/x86_64.win64-debug-vs14-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/win10-64-vor-c/x86_64.win64-debug-vs14-notest-inner b/build/scripts/overnight/configs/win10-64-vor-c/x86_64.win64-debug-vs14-notest-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/win10-64-vor-c/x86_64.win64-debug-vs14-notest-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/win10-64-vor-c/x86_64.win64-dev-vs14-inner b/build/scripts/overnight/configs/win10-64-vor-c/x86_64.win64-dev-vs14-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/win10-64-vor-c/x86_64.win64-dev-vs14-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/win10-64-vor-c/x86_64.win64-dev-vs14-nocpp-inner b/build/scripts/overnight/configs/win10-64-vor-c/x86_64.win64-dev-vs14-nocpp-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/win10-64-vor-c/x86_64.win64-dev-vs14-nocpp-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/win10-64-vor-c/x86_64.win64-dev-vs14-nojava-inner b/build/scripts/overnight/configs/win10-64-vor-c/x86_64.win64-dev-vs14-nojava-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/win10-64-vor-c/x86_64.win64-dev-vs14-nojava-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/win10-64-vor-c/x86_64.win64-dev-vs14-normi-inner b/build/scripts/overnight/configs/win10-64-vor-c/x86_64.win64-dev-vs14-normi-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/win10-64-vor-c/x86_64.win64-dev-vs14-normi-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/win10-64-vor-c/x86_64.win64-dev-vs14-notest-inner b/build/scripts/overnight/configs/win10-64-vor-c/x86_64.win64-dev-vs14-notest-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/win10-64-vor-c/x86_64.win64-dev-vs14-notest-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/win10-64-vor-c/x86_64.win64-dev-vs14-notest-normi-inner b/build/scripts/overnight/configs/win10-64-vor-c/x86_64.win64-dev-vs14-notest-normi-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/win10-64-vor-c/x86_64.win64-dev-vs14-notest-normi-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/win10-64-vor-c/x86_64.win64-release-vs14-examples-inner b/build/scripts/overnight/configs/win10-64-vor-c/x86_64.win64-release-vs14-examples-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/win10-64-vor-c/x86_64.win64-release-vs14-examples-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/win10-64-vor-c/x86_64.win64-release-vs14-inner b/build/scripts/overnight/configs/win10-64-vor-c/x86_64.win64-release-vs14-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/win10-64-vor-c/x86_64.win64-release-vs14-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/win10-64-vor-c/x86_64.win64-release-vs14-nodbt-inner b/build/scripts/overnight/configs/win10-64-vor-c/x86_64.win64-release-vs14-nodbt-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/win10-64-vor-c/x86_64.win64-release-vs14-nodbt-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/win10-64-vor-c/x86_64.win64-release-vs14-normi-inner b/build/scripts/overnight/configs/win10-64-vor-c/x86_64.win64-release-vs14-normi-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/win10-64-vor-c/x86_64.win64-release-vs14-normi-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/win10-64-vor-c/x86_64.win64-release-vs14-notest-inner b/build/scripts/overnight/configs/win10-64-vor-c/x86_64.win64-release-vs14-notest-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/win10-64-vor-c/x86_64.win64-release-vs14-notest-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/win10-64-vor-c/x86_64.win64-release-vs14-notest-normi-inner b/build/scripts/overnight/configs/win10-64-vor-c/x86_64.win64-release-vs14-notest-normi-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/win10-64-vor-c/x86_64.win64-release-vs14-notest-normi-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/win10-64-vor-d/common b/build/scripts/overnight/configs/win10-64-vor-d/common index 6cd432ca7..1a0942606 100644 --- a/build/scripts/overnight/configs/win10-64-vor-d/common +++ b/build/scripts/overnight/configs/win10-64-vor-d/common @@ -4,11 +4,13 @@ export VS_HOME='/cygdrive/C/Program Files (x86)/Microsoft Visual Studio 14.0' export WINDOWSSDKDIR='/cygdrive/C/Program Files (x86)/Windows Kits/10' export JACORB_HOME=/home/dds/INSTALLED_FOR_DDS/JacORB-v2.3.1.0 export GSOAPHOME=/home/dds/INSTALLED_FOR_DDS/gsoap-v2.7 -export PROTOBUF_HOME=/home/dds/INSTALLED_FOR_DDS/protobuf-2.6.0 -export PROTOBUF_LIB_HOME=/home/dds/INSTALLED_FOR_DDS/protobuf-2.6.0/src +export PROTOBUF_HOME=/home/dds/INSTALLED_FOR_DDS/protobuf-2.6.0-vs2015 export LAUNCH4J_HOME=/home/dds/INSTALLED_FOR_DDS/Launch4j -export PATH=$PROTOBUF_HOME/bin:$PATH +export PATH=/usr/local/bin:$PROTOBUF_HOME/bin:$PATH #There is no TAO for VS2015 unset TAO_ROOT export OVERRIDE_STRICT_CHECKS=no +export M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-3.5.3 +export SQLITE_HOME=/home/dds/INSTALLED_FOR_DDS/sqlite-amalgamation-3071602 +export PYTHON_HOME=/home/dds/INSTALLED_FOR_DDS/portablepython-2.7.3.1 diff --git a/build/scripts/overnight/configs/win10-64-vor-d/common_64bit b/build/scripts/overnight/configs/win10-64-vor-d/common_64bit index e794b7288..e0660f3c9 100644 --- a/build/scripts/overnight/configs/win10-64-vor-d/common_64bit +++ b/build/scripts/overnight/configs/win10-64-vor-d/common_64bit @@ -2,6 +2,14 @@ export VS_ENV_SCRIPT="C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\x86_amd64\vcvarsx86_amd64.bat" -export JAVA_HOME="c:/Program Files/Java/jdk1.6.0_37" +export JAVA6_HOME="c:/Program Files/Java/jdk1.6.0_39" +export JAVA_HOME="c:/Program Files/Java/jdk1.7.0_80" export ZLIB_HOME= -export QTDIR=c:\\cygwin64\\home\\dds\\INSTALLED_FOR_DDS\\Qt\\4.8.4_vs2010_64bit +export QTDIR=c:\\cygwin\\home\\dds\\INSTALLED_FOR_DDS\\Qt\\4.8.4_vs2010_64bit + +#Multiple python3 installs separated with ':' +export PYTHON3_HOME=\ +/home/dds/INSTALLED_FOR_DDS/python-3.5.4-win64/python:\ +/home/dds/INSTALLED_FOR_DDS/python-3.6.4-win64/python + +export NODEJS_HOME=/home/dds/INSTALLED_FOR_DDS/nodejs/node-v8.11.1-win-x64 diff --git a/build/scripts/overnight/configs/win10-64-vor-d/x86_64.win64-debug-vs14-inner b/build/scripts/overnight/configs/win10-64-vor-d/x86_64.win64-debug-vs14-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/win10-64-vor-d/x86_64.win64-debug-vs14-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/win10-64-vor-d/x86_64.win64-debug-vs14-notest-inner b/build/scripts/overnight/configs/win10-64-vor-d/x86_64.win64-debug-vs14-notest-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/win10-64-vor-d/x86_64.win64-debug-vs14-notest-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/win10-64-vor-d/x86_64.win64-dev-vs14-inner b/build/scripts/overnight/configs/win10-64-vor-d/x86_64.win64-dev-vs14-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/win10-64-vor-d/x86_64.win64-dev-vs14-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/win10-64-vor-d/x86_64.win64-dev-vs14-nocpp-inner b/build/scripts/overnight/configs/win10-64-vor-d/x86_64.win64-dev-vs14-nocpp-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/win10-64-vor-d/x86_64.win64-dev-vs14-nocpp-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/win10-64-vor-d/x86_64.win64-dev-vs14-nojava-inner b/build/scripts/overnight/configs/win10-64-vor-d/x86_64.win64-dev-vs14-nojava-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/win10-64-vor-d/x86_64.win64-dev-vs14-nojava-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/win10-64-vor-d/x86_64.win64-dev-vs14-normi-inner b/build/scripts/overnight/configs/win10-64-vor-d/x86_64.win64-dev-vs14-normi-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/win10-64-vor-d/x86_64.win64-dev-vs14-normi-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/win10-64-vor-d/x86_64.win64-dev-vs14-notest-inner b/build/scripts/overnight/configs/win10-64-vor-d/x86_64.win64-dev-vs14-notest-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/win10-64-vor-d/x86_64.win64-dev-vs14-notest-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/win10-64-vor-d/x86_64.win64-dev-vs14-notest-normi-inner b/build/scripts/overnight/configs/win10-64-vor-d/x86_64.win64-dev-vs14-notest-normi-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/win10-64-vor-d/x86_64.win64-dev-vs14-notest-normi-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/win10-64-vor-d/x86_64.win64-release-vs14-inner b/build/scripts/overnight/configs/win10-64-vor-d/x86_64.win64-release-vs14-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/win10-64-vor-d/x86_64.win64-release-vs14-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/win10-64-vor-d/x86_64.win64-release-vs14-nodbt-inner b/build/scripts/overnight/configs/win10-64-vor-d/x86_64.win64-release-vs14-nodbt-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/win10-64-vor-d/x86_64.win64-release-vs14-nodbt-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/win10-64-vor-d/x86_64.win64-release-vs14-normi-inner b/build/scripts/overnight/configs/win10-64-vor-d/x86_64.win64-release-vs14-normi-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/win10-64-vor-d/x86_64.win64-release-vs14-normi-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/win10-64-vor-d/x86_64.win64-release-vs14-notest-inner b/build/scripts/overnight/configs/win10-64-vor-d/x86_64.win64-release-vs14-notest-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/win10-64-vor-d/x86_64.win64-release-vs14-notest-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/win10-64-vor-d/x86_64.win64-release-vs14-notest-normi-inner b/build/scripts/overnight/configs/win10-64-vor-d/x86_64.win64-release-vs14-notest-normi-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/win10-64-vor-d/x86_64.win64-release-vs14-notest-normi-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/win2008-64a/common b/build/scripts/overnight/configs/win2008-64a/common index af3361775..1f4a4f73b 100644 --- a/build/scripts/overnight/configs/win2008-64a/common +++ b/build/scripts/overnight/configs/win2008-64a/common @@ -10,3 +10,4 @@ export PATH=/usr/local/bin:$PATH #as the native calls done via TAO ask for a temp directory and windows fallback to using #USERPROFILE which has spaces in and does not work, unsetting solves the problem unset USERPROFILE +export M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-3.5.3 diff --git a/build/scripts/overnight/configs/win2008-64a/common_32bit b/build/scripts/overnight/configs/win2008-64a/common_32bit index a1bfbbbb2..58133ae00 100644 --- a/build/scripts/overnight/configs/win2008-64a/common_32bit +++ b/build/scripts/overnight/configs/win2008-64a/common_32bit @@ -1,7 +1,8 @@ . ./configs/`hostname`/common export VS_ENV_SCRIPT="C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\Tools\vsvars32.bat" -export JAVA_HOME="c:/Program Files (x86)/Java/jdk1.6.0_24" +export JAVA6_HOME="c:/Program Files (x86)/Java/jdk1.6.0_24" +export JAVA_HOME="c:/Program Files (x86)/Java/jdk1.7.0_79" export TAO_ROOT= export QTDIR=c:\\cygwin\\home\\dds\\INSTALLED_FOR_DDS\\Qt\\4.8.4_vs2010_64bit export REDIST_OVERRIDE='/cygdrive/C/Program Files (x86)/Microsoft SDKs/Windows/v6.0A' diff --git a/build/scripts/overnight/configs/win2008-64a/common_64bit b/build/scripts/overnight/configs/win2008-64a/common_64bit index 9c858f997..644caa5cb 100644 --- a/build/scripts/overnight/configs/win2008-64a/common_64bit +++ b/build/scripts/overnight/configs/win2008-64a/common_64bit @@ -1,6 +1,7 @@ . ./configs/`hostname`/common export VS_ENV_SCRIPT="C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\bin\amd64\vcvarsamd64.bat" -export JAVA_HOME="c:/Program Files/Java/jdk1.6.0_24" +export JAVA6_HOME="c:/Program Files/Java/jdk1.6.0_24" +export JAVA_HOME="c:/Program Files/Java/jdk1.7.0_79" export TAO_ROOT=/home/dds/INSTALLED_FOR_DDS/TAO161_0-Windows-vc10-inline-64bit_110704 export QTDIR=c:\\cygwin\\home\\dds\\INSTALLED_FOR_DDS\\Qt\\4.8.4_vs2010_64bit diff --git a/build/scripts/overnight/configs/win7-32-ospl-1/common b/build/scripts/overnight/configs/win7-32-ospl-1/common index 06caecdd5..567bce803 100644 --- a/build/scripts/overnight/configs/win7-32-ospl-1/common +++ b/build/scripts/overnight/configs/win7-32-ospl-1/common @@ -2,7 +2,7 @@ export VS_HOME='/cygdrive/C/Program Files/Microsoft Visual Studio 10.0/' export WINDOWSSDKDIR='/cygdrive/C/Program Files/Microsoft SDKs/Windows/v7.0A' export JACORB_HOME=/home/dds/INSTALLED\ FOR\ DDS/JacORB-v2.3.1.0 export VS_ENV_SCRIPT="C:\Program Files\Microsoft Visual Studio 10.0\Common7\Tools\vsvars32.bat" -export JAVA_HOME="c:/Program Files/Java/jdk1.6.0_37" +export JAVA6_HOME="c:/Program Files/Java/jdk1.6.0_37" export TAO_ROOT=/home/dds/INSTALLED_FOR_DDS/TAO161_0-Windows-vc10-inline-32bit-OpenSpliceDDS_v6.1_UNSUPPORTED_110704 export GSOAPHOME=/home/dds/INSTALLED\ FOR\ DDS/gsoap-v2.7 @@ -11,3 +11,5 @@ export GSOAPHOME=/home/dds/INSTALLED\ FOR\ DDS/gsoap-v2.7 #USERPROFILE which has spaces in and does not work, unsetting solves the problem unset USERPROFILE export QTDIR=c:\\cygwin\\home\\dds\\INSTALLED_FOR_DDS\\Qt\\4.8.4_vs2010_32bit +export JAVA_HOME="c:/Program Files/Java/jdk1.7.0_79" +export M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-3.5.3 diff --git a/build/scripts/overnight/configs/win7-32-ospl-2/common b/build/scripts/overnight/configs/win7-32-ospl-2/common index 06caecdd5..567bce803 100644 --- a/build/scripts/overnight/configs/win7-32-ospl-2/common +++ b/build/scripts/overnight/configs/win7-32-ospl-2/common @@ -2,7 +2,7 @@ export VS_HOME='/cygdrive/C/Program Files/Microsoft Visual Studio 10.0/' export WINDOWSSDKDIR='/cygdrive/C/Program Files/Microsoft SDKs/Windows/v7.0A' export JACORB_HOME=/home/dds/INSTALLED\ FOR\ DDS/JacORB-v2.3.1.0 export VS_ENV_SCRIPT="C:\Program Files\Microsoft Visual Studio 10.0\Common7\Tools\vsvars32.bat" -export JAVA_HOME="c:/Program Files/Java/jdk1.6.0_37" +export JAVA6_HOME="c:/Program Files/Java/jdk1.6.0_37" export TAO_ROOT=/home/dds/INSTALLED_FOR_DDS/TAO161_0-Windows-vc10-inline-32bit-OpenSpliceDDS_v6.1_UNSUPPORTED_110704 export GSOAPHOME=/home/dds/INSTALLED\ FOR\ DDS/gsoap-v2.7 @@ -11,3 +11,5 @@ export GSOAPHOME=/home/dds/INSTALLED\ FOR\ DDS/gsoap-v2.7 #USERPROFILE which has spaces in and does not work, unsetting solves the problem unset USERPROFILE export QTDIR=c:\\cygwin\\home\\dds\\INSTALLED_FOR_DDS\\Qt\\4.8.4_vs2010_32bit +export JAVA_HOME="c:/Program Files/Java/jdk1.7.0_79" +export M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-3.5.3 diff --git a/build/scripts/overnight/configs/win7-32-ospl-3/common b/build/scripts/overnight/configs/win7-32-ospl-3/common index 06caecdd5..567bce803 100644 --- a/build/scripts/overnight/configs/win7-32-ospl-3/common +++ b/build/scripts/overnight/configs/win7-32-ospl-3/common @@ -2,7 +2,7 @@ export VS_HOME='/cygdrive/C/Program Files/Microsoft Visual Studio 10.0/' export WINDOWSSDKDIR='/cygdrive/C/Program Files/Microsoft SDKs/Windows/v7.0A' export JACORB_HOME=/home/dds/INSTALLED\ FOR\ DDS/JacORB-v2.3.1.0 export VS_ENV_SCRIPT="C:\Program Files\Microsoft Visual Studio 10.0\Common7\Tools\vsvars32.bat" -export JAVA_HOME="c:/Program Files/Java/jdk1.6.0_37" +export JAVA6_HOME="c:/Program Files/Java/jdk1.6.0_37" export TAO_ROOT=/home/dds/INSTALLED_FOR_DDS/TAO161_0-Windows-vc10-inline-32bit-OpenSpliceDDS_v6.1_UNSUPPORTED_110704 export GSOAPHOME=/home/dds/INSTALLED\ FOR\ DDS/gsoap-v2.7 @@ -11,3 +11,5 @@ export GSOAPHOME=/home/dds/INSTALLED\ FOR\ DDS/gsoap-v2.7 #USERPROFILE which has spaces in and does not work, unsetting solves the problem unset USERPROFILE export QTDIR=c:\\cygwin\\home\\dds\\INSTALLED_FOR_DDS\\Qt\\4.8.4_vs2010_32bit +export JAVA_HOME="c:/Program Files/Java/jdk1.7.0_79" +export M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-3.5.3 diff --git a/build/scripts/overnight/configs/win7-32-ospl-4/common b/build/scripts/overnight/configs/win7-32-ospl-4/common index 06caecdd5..567bce803 100644 --- a/build/scripts/overnight/configs/win7-32-ospl-4/common +++ b/build/scripts/overnight/configs/win7-32-ospl-4/common @@ -2,7 +2,7 @@ export VS_HOME='/cygdrive/C/Program Files/Microsoft Visual Studio 10.0/' export WINDOWSSDKDIR='/cygdrive/C/Program Files/Microsoft SDKs/Windows/v7.0A' export JACORB_HOME=/home/dds/INSTALLED\ FOR\ DDS/JacORB-v2.3.1.0 export VS_ENV_SCRIPT="C:\Program Files\Microsoft Visual Studio 10.0\Common7\Tools\vsvars32.bat" -export JAVA_HOME="c:/Program Files/Java/jdk1.6.0_37" +export JAVA6_HOME="c:/Program Files/Java/jdk1.6.0_37" export TAO_ROOT=/home/dds/INSTALLED_FOR_DDS/TAO161_0-Windows-vc10-inline-32bit-OpenSpliceDDS_v6.1_UNSUPPORTED_110704 export GSOAPHOME=/home/dds/INSTALLED\ FOR\ DDS/gsoap-v2.7 @@ -11,3 +11,5 @@ export GSOAPHOME=/home/dds/INSTALLED\ FOR\ DDS/gsoap-v2.7 #USERPROFILE which has spaces in and does not work, unsetting solves the problem unset USERPROFILE export QTDIR=c:\\cygwin\\home\\dds\\INSTALLED_FOR_DDS\\Qt\\4.8.4_vs2010_32bit +export JAVA_HOME="c:/Program Files/Java/jdk1.7.0_79" +export M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-3.5.3 diff --git a/build/scripts/overnight/configs/win7-32a/common b/build/scripts/overnight/configs/win7-32a/common index 3830b5f2a..3d7b64a95 100755 --- a/build/scripts/overnight/configs/win7-32a/common +++ b/build/scripts/overnight/configs/win7-32a/common @@ -2,10 +2,9 @@ export VS_HOME='/cygdrive/C/Program Files/Microsoft Visual Studio 10.0/' export VS_ENV_SCRIPT="C:\Program Files\Microsoft Visual Studio 10.0\Common7\Tools\vsvars32.bat" export WINDOWSSDKDIR='/cygdrive/C/Program Files/Microsoft SDKs/Windows/v7.0A' export JACORB_HOME=/home/dds/INSTALLED\ FOR\ DDS/JacORB-v2.3.1.0 -export OSPL_BUILDER=/home/dds/INSTALLED\ FOR\ DDS/BitRock-v9.0.1/bin/builder export GSOAPHOME=/home/dds/INSTALLED\ FOR\ DDS/gsoap-v2.7 -export M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-2.2.1 -export JAVA_HOME="c:/Program Files/Java/jdk1.6.0_24" +export M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-3.5.3 +export JAVA6_HOME="c:/Program Files/Java/jdk1.6.0_24" export OPENSSL_HOST_HOME=/home/dds/INSTALLED\ FOR\ DDS/openssl-v1.0.1g export OPENSSL_TARGET_HOME=$OPENSSL_HOST_HOME export ZLIB_HOME=/home/dds/INSTALLED\ FOR\ DDS/zlib-1.2.4 @@ -27,3 +26,5 @@ export PYTHON_HOME=/home/dds/INSTALLED_FOR_DDS/portablepython-2.7.3.1 export PROTOBUF_HOME=/home/dds/INSTALLED_FOR_DDS/protobuf-2.6.0 #export LAUNCH4J_HOME=/home/dds/INSTALLED_FOR_DDS/Launch4j export PATH=/usr/local/bin:$PATH +export JAVA_HOME="c:/Program Files/Java/jdk1.7.0_80" +export M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-3.5.3 diff --git a/build/scripts/overnight/configs/win7-32a/x86.win32-dev-vs10 b/build/scripts/overnight/configs/win7-32a/x86.win32-dev-vs10 index 179c1b6cd..1e24bcd73 100755 --- a/build/scripts/overnight/configs/win7-32a/x86.win32-dev-vs10 +++ b/build/scripts/overnight/configs/win7-32a/x86.win32-dev-vs10 @@ -6,7 +6,7 @@ BUILD_DBT=yes BUILD_RBT=yes RUN_DBT=yes RUN_RBT_SP=yes -RUN_RBT_SHM=yes +RUN_RBT_SHM=no RUN_EXAMPLES_SHM=no RUN_EXAMPLES_SP=yes diff --git a/build/scripts/overnight/configs/win7-32a/x86.win32-dev-vs10-notao b/build/scripts/overnight/configs/win7-32a/x86.win32-dev-vs10-notao index 0fef5218d..28e7f1ee3 100755 --- a/build/scripts/overnight/configs/win7-32a/x86.win32-dev-vs10-notao +++ b/build/scripts/overnight/configs/win7-32a/x86.win32-dev-vs10-notao @@ -6,7 +6,7 @@ BUILD_DBT=yes BUILD_RBT=yes RUN_DBT=yes RUN_RBT_SP=yes -RUN_RBT_SHM=yes +RUN_RBT_SHM=no RUN_EXAMPLES_SHM=no RUN_EXAMPLES_SP=no diff --git a/build/scripts/overnight/configs/win7-32a/x86.win32-release-vs10 b/build/scripts/overnight/configs/win7-32a/x86.win32-release-vs10 index 17e0e9c49..f0d23e314 100755 --- a/build/scripts/overnight/configs/win7-32a/x86.win32-release-vs10 +++ b/build/scripts/overnight/configs/win7-32a/x86.win32-release-vs10 @@ -6,7 +6,7 @@ BUILD_DBT=yes BUILD_RBT=yes RUN_DBT=yes RUN_RBT_SP=yes -RUN_RBT_SHM=yes +RUN_RBT_SHM=no RUN_EXAMPLES_SHM=no RUN_EXAMPLES_SP=yes diff --git a/build/scripts/overnight/configs/win7-32a/x86.win32-release-vs10-nodbt b/build/scripts/overnight/configs/win7-32a/x86.win32-release-vs10-nodbt index eca059b32..3b4e6e995 100755 --- a/build/scripts/overnight/configs/win7-32a/x86.win32-release-vs10-nodbt +++ b/build/scripts/overnight/configs/win7-32a/x86.win32-release-vs10-nodbt @@ -6,7 +6,7 @@ BUILD_DBT=yes BUILD_RBT=yes RUN_DBT=no RUN_RBT_SP=yes -RUN_RBT_SHM=yes +RUN_RBT_SHM=no RUN_EXAMPLES_SHM=no RUN_EXAMPLES_SP=yes diff --git a/build/scripts/overnight/configs/win7-32a/x86.win32-release-vs10-notao b/build/scripts/overnight/configs/win7-32a/x86.win32-release-vs10-notao index 8366f2923..8a8308f81 100755 --- a/build/scripts/overnight/configs/win7-32a/x86.win32-release-vs10-notao +++ b/build/scripts/overnight/configs/win7-32a/x86.win32-release-vs10-notao @@ -6,7 +6,7 @@ BUILD_DBT=yes BUILD_RBT=yes RUN_DBT=yes RUN_RBT_SP=yes -RUN_RBT_SHM=yes +RUN_RBT_SHM=no RUN_EXAMPLES_SHM=no RUN_EXAMPLES_SP=no diff --git a/build/scripts/overnight/configs/win7-64-ospl-1/common b/build/scripts/overnight/configs/win7-64-ospl-1/common index c2ebd9f42..37992d379 100755 --- a/build/scripts/overnight/configs/win7-64-ospl-1/common +++ b/build/scripts/overnight/configs/win7-64-ospl-1/common @@ -1,13 +1,12 @@ export VS_HOME='/cygdrive/C/Program Files (x86)/Microsoft Visual Studio 10.0' export WINDOWSSDKDIR='/cygdrive/C/Program Files (x86)/Microsoft SDKs/Windows/v7.0A' export JACORB_HOME=/home/dds/INSTALLED\ FOR\ DDS/JacORB-v2.3.1.0 -export OSPL_BUILDER=/home/dds/INSTALLED\ FOR\ DDS/BitRock-v9.0.1/bin/builder export GSOAPHOME=/home/dds/INSTALLED\ FOR\ DDS/gsoap-v2.7 -export M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-2.2.1 +export M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-3.5.3 export LEVELDB_HOME=/home/dds/INSTALLED_FOR_DDS/leveldb-1.9.0 export SQLITE_HOME=/home/dds/INSTALLED_FOR_DDS/sqlite-amalgamation-3071602 export VS_ENV_SCRIPT="C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\bin\amd64\vcvars64.bat" -export JAVA_HOME="c:/Program Files/Java/jdk1.6.0_37" +export JAVA6_HOME="c:/Program Files/Java/jdk1.6.0_37" export OPENSSL_HOST_HOME=/home/dds/INSTALLED\ FOR\ DDS/openssl-v1.0.1g_X64 export OPENSSL_TARGET_HOME=$OPENSSL_HOST_HOME export TAO_ROOT=/home/dds/INSTALLED_FOR_DDS/TAO161_0-Windows-vc10-inline-64bit_110704 @@ -29,3 +28,5 @@ export PYTHON_HOME=/home/dds/INSTALLED_FOR_DDS/portablepython-2.7.3.1 export PROTOBUF_HOME=/home/dds/INSTALLED_FOR_DDS/protobuf-2.6.0 export LAUNCH4J_HOME=/home/dds/INSTALLED_FOR_DDS/Launch4j export PATH=/usr/local/bin:$PATH:$ZLIB_HOME +export JAVA_HOME="c:/Program Files/Java/jdk1.7.0_79" +export M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-3.5.3 diff --git a/build/scripts/overnight/configs/win7-64-ospl-1/x86_64.win64-release b/build/scripts/overnight/configs/win7-64-ospl-1/x86_64.win64-release index 99942904e..414bf77eb 100755 --- a/build/scripts/overnight/configs/win7-64-ospl-1/x86_64.win64-release +++ b/build/scripts/overnight/configs/win7-64-ospl-1/x86_64.win64-release @@ -4,7 +4,7 @@ BUILD_EXAMPLES=yes KEEP_DIST=yes RUN_DBT=no RUN_RBT_SP=no -RUN_RBT_SHM=yes +RUN_RBT_SHM=no RUN_EXAMPLES_SHM=no RUN_EXAMPLES_SP=yes diff --git a/build/scripts/overnight/configs/win7-64-ospl-2/common b/build/scripts/overnight/configs/win7-64-ospl-2/common index c2ebd9f42..37992d379 100755 --- a/build/scripts/overnight/configs/win7-64-ospl-2/common +++ b/build/scripts/overnight/configs/win7-64-ospl-2/common @@ -1,13 +1,12 @@ export VS_HOME='/cygdrive/C/Program Files (x86)/Microsoft Visual Studio 10.0' export WINDOWSSDKDIR='/cygdrive/C/Program Files (x86)/Microsoft SDKs/Windows/v7.0A' export JACORB_HOME=/home/dds/INSTALLED\ FOR\ DDS/JacORB-v2.3.1.0 -export OSPL_BUILDER=/home/dds/INSTALLED\ FOR\ DDS/BitRock-v9.0.1/bin/builder export GSOAPHOME=/home/dds/INSTALLED\ FOR\ DDS/gsoap-v2.7 -export M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-2.2.1 +export M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-3.5.3 export LEVELDB_HOME=/home/dds/INSTALLED_FOR_DDS/leveldb-1.9.0 export SQLITE_HOME=/home/dds/INSTALLED_FOR_DDS/sqlite-amalgamation-3071602 export VS_ENV_SCRIPT="C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\bin\amd64\vcvars64.bat" -export JAVA_HOME="c:/Program Files/Java/jdk1.6.0_37" +export JAVA6_HOME="c:/Program Files/Java/jdk1.6.0_37" export OPENSSL_HOST_HOME=/home/dds/INSTALLED\ FOR\ DDS/openssl-v1.0.1g_X64 export OPENSSL_TARGET_HOME=$OPENSSL_HOST_HOME export TAO_ROOT=/home/dds/INSTALLED_FOR_DDS/TAO161_0-Windows-vc10-inline-64bit_110704 @@ -29,3 +28,5 @@ export PYTHON_HOME=/home/dds/INSTALLED_FOR_DDS/portablepython-2.7.3.1 export PROTOBUF_HOME=/home/dds/INSTALLED_FOR_DDS/protobuf-2.6.0 export LAUNCH4J_HOME=/home/dds/INSTALLED_FOR_DDS/Launch4j export PATH=/usr/local/bin:$PATH:$ZLIB_HOME +export JAVA_HOME="c:/Program Files/Java/jdk1.7.0_79" +export M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-3.5.3 diff --git a/build/scripts/overnight/configs/win7-64-ospl-2/x86_64.win64-release b/build/scripts/overnight/configs/win7-64-ospl-2/x86_64.win64-release index 99942904e..414bf77eb 100755 --- a/build/scripts/overnight/configs/win7-64-ospl-2/x86_64.win64-release +++ b/build/scripts/overnight/configs/win7-64-ospl-2/x86_64.win64-release @@ -4,7 +4,7 @@ BUILD_EXAMPLES=yes KEEP_DIST=yes RUN_DBT=no RUN_RBT_SP=no -RUN_RBT_SHM=yes +RUN_RBT_SHM=no RUN_EXAMPLES_SHM=no RUN_EXAMPLES_SP=yes diff --git a/build/scripts/overnight/configs/win7-64-ospl-3/common b/build/scripts/overnight/configs/win7-64-ospl-3/common index c2ebd9f42..37992d379 100755 --- a/build/scripts/overnight/configs/win7-64-ospl-3/common +++ b/build/scripts/overnight/configs/win7-64-ospl-3/common @@ -1,13 +1,12 @@ export VS_HOME='/cygdrive/C/Program Files (x86)/Microsoft Visual Studio 10.0' export WINDOWSSDKDIR='/cygdrive/C/Program Files (x86)/Microsoft SDKs/Windows/v7.0A' export JACORB_HOME=/home/dds/INSTALLED\ FOR\ DDS/JacORB-v2.3.1.0 -export OSPL_BUILDER=/home/dds/INSTALLED\ FOR\ DDS/BitRock-v9.0.1/bin/builder export GSOAPHOME=/home/dds/INSTALLED\ FOR\ DDS/gsoap-v2.7 -export M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-2.2.1 +export M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-3.5.3 export LEVELDB_HOME=/home/dds/INSTALLED_FOR_DDS/leveldb-1.9.0 export SQLITE_HOME=/home/dds/INSTALLED_FOR_DDS/sqlite-amalgamation-3071602 export VS_ENV_SCRIPT="C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\bin\amd64\vcvars64.bat" -export JAVA_HOME="c:/Program Files/Java/jdk1.6.0_37" +export JAVA6_HOME="c:/Program Files/Java/jdk1.6.0_37" export OPENSSL_HOST_HOME=/home/dds/INSTALLED\ FOR\ DDS/openssl-v1.0.1g_X64 export OPENSSL_TARGET_HOME=$OPENSSL_HOST_HOME export TAO_ROOT=/home/dds/INSTALLED_FOR_DDS/TAO161_0-Windows-vc10-inline-64bit_110704 @@ -29,3 +28,5 @@ export PYTHON_HOME=/home/dds/INSTALLED_FOR_DDS/portablepython-2.7.3.1 export PROTOBUF_HOME=/home/dds/INSTALLED_FOR_DDS/protobuf-2.6.0 export LAUNCH4J_HOME=/home/dds/INSTALLED_FOR_DDS/Launch4j export PATH=/usr/local/bin:$PATH:$ZLIB_HOME +export JAVA_HOME="c:/Program Files/Java/jdk1.7.0_79" +export M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-3.5.3 diff --git a/build/scripts/overnight/configs/win7-64-ospl-3/x86_64.win64-release b/build/scripts/overnight/configs/win7-64-ospl-3/x86_64.win64-release index 99942904e..414bf77eb 100755 --- a/build/scripts/overnight/configs/win7-64-ospl-3/x86_64.win64-release +++ b/build/scripts/overnight/configs/win7-64-ospl-3/x86_64.win64-release @@ -4,7 +4,7 @@ BUILD_EXAMPLES=yes KEEP_DIST=yes RUN_DBT=no RUN_RBT_SP=no -RUN_RBT_SHM=yes +RUN_RBT_SHM=no RUN_EXAMPLES_SHM=no RUN_EXAMPLES_SP=yes diff --git a/build/scripts/overnight/configs/win7-64-ospl-4/common b/build/scripts/overnight/configs/win7-64-ospl-4/common index c2ebd9f42..37992d379 100755 --- a/build/scripts/overnight/configs/win7-64-ospl-4/common +++ b/build/scripts/overnight/configs/win7-64-ospl-4/common @@ -1,13 +1,12 @@ export VS_HOME='/cygdrive/C/Program Files (x86)/Microsoft Visual Studio 10.0' export WINDOWSSDKDIR='/cygdrive/C/Program Files (x86)/Microsoft SDKs/Windows/v7.0A' export JACORB_HOME=/home/dds/INSTALLED\ FOR\ DDS/JacORB-v2.3.1.0 -export OSPL_BUILDER=/home/dds/INSTALLED\ FOR\ DDS/BitRock-v9.0.1/bin/builder export GSOAPHOME=/home/dds/INSTALLED\ FOR\ DDS/gsoap-v2.7 -export M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-2.2.1 +export M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-3.5.3 export LEVELDB_HOME=/home/dds/INSTALLED_FOR_DDS/leveldb-1.9.0 export SQLITE_HOME=/home/dds/INSTALLED_FOR_DDS/sqlite-amalgamation-3071602 export VS_ENV_SCRIPT="C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\bin\amd64\vcvars64.bat" -export JAVA_HOME="c:/Program Files/Java/jdk1.6.0_37" +export JAVA6_HOME="c:/Program Files/Java/jdk1.6.0_37" export OPENSSL_HOST_HOME=/home/dds/INSTALLED\ FOR\ DDS/openssl-v1.0.1g_X64 export OPENSSL_TARGET_HOME=$OPENSSL_HOST_HOME export TAO_ROOT=/home/dds/INSTALLED_FOR_DDS/TAO161_0-Windows-vc10-inline-64bit_110704 @@ -29,3 +28,5 @@ export PYTHON_HOME=/home/dds/INSTALLED_FOR_DDS/portablepython-2.7.3.1 export PROTOBUF_HOME=/home/dds/INSTALLED_FOR_DDS/protobuf-2.6.0 export LAUNCH4J_HOME=/home/dds/INSTALLED_FOR_DDS/Launch4j export PATH=/usr/local/bin:$PATH:$ZLIB_HOME +export JAVA_HOME="c:/Program Files/Java/jdk1.7.0_79" +export M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-3.5.3 diff --git a/build/scripts/overnight/configs/win7-64-ospl-4/x86_64.win64-release b/build/scripts/overnight/configs/win7-64-ospl-4/x86_64.win64-release index 99942904e..414bf77eb 100755 --- a/build/scripts/overnight/configs/win7-64-ospl-4/x86_64.win64-release +++ b/build/scripts/overnight/configs/win7-64-ospl-4/x86_64.win64-release @@ -4,7 +4,7 @@ BUILD_EXAMPLES=yes KEEP_DIST=yes RUN_DBT=no RUN_RBT_SP=no -RUN_RBT_SHM=yes +RUN_RBT_SHM=no RUN_EXAMPLES_SHM=no RUN_EXAMPLES_SP=yes diff --git a/build/scripts/overnight/configs/win7-64a/common b/build/scripts/overnight/configs/win7-64a/common index c14aa8e49..e39b030f1 100755 --- a/build/scripts/overnight/configs/win7-64a/common +++ b/build/scripts/overnight/configs/win7-64a/common @@ -1,9 +1,8 @@ export VS_HOME='/cygdrive/C/Program Files (x86)/Microsoft Visual Studio 10.0' export WINDOWSSDKDIR='/cygdrive/C/Program Files (x86)/Microsoft SDKs/Windows/v7.0A' export JACORB_HOME=/home/dds/INSTALLED\ FOR\ DDS/JacORB-v2.3.1.0 -export OSPL_BUILDER=/home/dds/INSTALLED\ FOR\ DDS/BitRock-v9.0.1/bin/builder export GSOAPHOME=/home/dds/INSTALLED\ FOR\ DDS/gsoap-v2.7 -export M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-2.2.1 +export M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-3.5.3 export LEVELDB_HOME=/home/dds/INSTALLED_FOR_DDS/leveldb-1.9.0 export SQLITE_HOME=/home/dds/INSTALLED_FOR_DDS/sqlite-amalgamation-3071602 @@ -15,4 +14,4 @@ unset USERPROFILE export PYTHON_HOME=/home/dds/INSTALLED_FOR_DDS/portablepython-2.7.3.1 export PROTOBUF_HOME=/home/dds/INSTALLED_FOR_DDS/protobuf-2.6.0 export LAUNCH4J_HOME=/home/dds/INSTALLED_FOR_DDS/Launch4j -export PATH=/usr/local/bin:$PATH \ No newline at end of file +export PATH=/usr/local/bin:$PATHexport M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-3.5.3 diff --git a/build/scripts/overnight/configs/win7-64a/common_32bit b/build/scripts/overnight/configs/win7-64a/common_32bit index 4808f0533..c5cc59f67 100755 --- a/build/scripts/overnight/configs/win7-64a/common_32bit +++ b/build/scripts/overnight/configs/win7-64a/common_32bit @@ -1,7 +1,8 @@ . ./configs/`hostname`/common export VS_ENV_SCRIPT="C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\Tools\vsvars32.bat" -export JAVA_HOME="c:/Program Files (x86)/Java/jdk1.6.0_24" +export JAVA6_HOME="c:/Program Files (x86)/Java/jdk1.6.0_24" +export JAVA_HOME="c:/Program Files (x86)/Java/jdk1.7.0_79" export OPENSSL_HOST_HOME=/home/dds/INSTALLED\ FOR\ DDS/openssl-v1.0.1g export OPENSSL_TARGET_HOME=$OPENSSL_HOST_HOME export TAO_ROOT=/home/dds/INSTALLED_FOR_DDS/TAO161_0-Windows-vc10-inline-32bit-OpenSpliceDDS_v6.1_UNSUPPORTED_110704 diff --git a/build/scripts/overnight/configs/win7-64a/common_64bit b/build/scripts/overnight/configs/win7-64a/common_64bit index 816c58ba9..2421ed2a8 100755 --- a/build/scripts/overnight/configs/win7-64a/common_64bit +++ b/build/scripts/overnight/configs/win7-64a/common_64bit @@ -1,7 +1,8 @@ . ./configs/`hostname`/common export VS_ENV_SCRIPT="C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\bin\amd64\vcvars64.bat" -export JAVA_HOME="c:/Program Files/Java/jdk1.6.0_24" +export JAVA6_HOME="c:/Program Files/Java/jdk1.6.0_24" +export JAVA_HOME="c:/Program Files/Java/jdk1.7.0_80" export OPENSSL_HOST_HOME=/home/dds/INSTALLED\ FOR\ DDS/openssl-v1.0.1g_X64 export OPENSSL_TARGET_HOME=$OPENSSL_HOST_HOME export TAO_ROOT=/home/dds/INSTALLED_FOR_DDS/TAO161_0-Windows-vc10-inline-64bit_110704 diff --git a/build/scripts/overnight/configs/win7-64a/x86.win32-dev b/build/scripts/overnight/configs/win7-64a/x86.win32-dev index ffe6a8852..134965b8e 100755 --- a/build/scripts/overnight/configs/win7-64a/x86.win32-dev +++ b/build/scripts/overnight/configs/win7-64a/x86.win32-dev @@ -6,7 +6,7 @@ BUILD_DBT=yes BUILD_RBT=yes RUN_DBT=yes RUN_RBT_SP=yes -RUN_RBT_SHM=yes +RUN_RBT_SHM=no RUN_EXAMPLES_SHM=no RUN_EXAMPLES_SP=yes diff --git a/build/scripts/overnight/configs/win7-64a/x86.win32-dev-notao b/build/scripts/overnight/configs/win7-64a/x86.win32-dev-notao index c4241d453..4310f67d2 100755 --- a/build/scripts/overnight/configs/win7-64a/x86.win32-dev-notao +++ b/build/scripts/overnight/configs/win7-64a/x86.win32-dev-notao @@ -6,7 +6,7 @@ BUILD_DBT=yes BUILD_RBT=yes RUN_DBT=yes RUN_RBT_SP=yes -RUN_RBT_SHM=yes +RUN_RBT_SHM=no RUN_EXAMPLES_SHM=no RUN_EXAMPLES_SP=no diff --git a/build/scripts/overnight/configs/win7-64a/x86.win32-release b/build/scripts/overnight/configs/win7-64a/x86.win32-release index 1c40fedc3..87a005cbe 100755 --- a/build/scripts/overnight/configs/win7-64a/x86.win32-release +++ b/build/scripts/overnight/configs/win7-64a/x86.win32-release @@ -6,7 +6,7 @@ BUILD_DBT=yes BUILD_RBT=yes RUN_DBT=yes RUN_RBT_SP=yes -RUN_RBT_SHM=yes +RUN_RBT_SHM=no RUN_EXAMPLES_SHM=no RUN_EXAMPLES_SP=yes diff --git a/build/scripts/overnight/configs/win7-64a/x86.win32-release-nodbt b/build/scripts/overnight/configs/win7-64a/x86.win32-release-nodbt index 834cfccab..26f626987 100755 --- a/build/scripts/overnight/configs/win7-64a/x86.win32-release-nodbt +++ b/build/scripts/overnight/configs/win7-64a/x86.win32-release-nodbt @@ -6,7 +6,7 @@ BUILD_DBT=yes BUILD_RBT=yes RUN_DBT=no RUN_RBT_SP=yes -RUN_RBT_SHM=yes +RUN_RBT_SHM=no RUN_EXAMPLES_SHM=no RUN_EXAMPLES_SP=yes diff --git a/build/scripts/overnight/configs/win7-64a/x86.win32-release-noextras b/build/scripts/overnight/configs/win7-64a/x86.win32-release-noextras index 16ed7cb5e..5dfcbb768 100755 --- a/build/scripts/overnight/configs/win7-64a/x86.win32-release-noextras +++ b/build/scripts/overnight/configs/win7-64a/x86.win32-release-noextras @@ -26,5 +26,4 @@ unset RLM_HOME unset RLM_TARGET unset RLM_VERSION unset JACORB_HOME -unset OSPL_BUILDER unset M2_HOME diff --git a/build/scripts/overnight/configs/win7-64a/x86.win32-release-notao b/build/scripts/overnight/configs/win7-64a/x86.win32-release-notao index f9888de6d..69b1cbd5e 100755 --- a/build/scripts/overnight/configs/win7-64a/x86.win32-release-notao +++ b/build/scripts/overnight/configs/win7-64a/x86.win32-release-notao @@ -6,7 +6,7 @@ BUILD_DBT=yes BUILD_RBT=yes RUN_DBT=yes RUN_RBT_SP=yes -RUN_RBT_SHM=yes +RUN_RBT_SHM=no RUN_EXAMPLES_SHM=no RUN_EXAMPLES_SP=no diff --git a/build/scripts/overnight/configs/win7-64a/x86_64.win64-dev b/build/scripts/overnight/configs/win7-64a/x86_64.win64-dev index 3be7db9c3..8878cfe61 100755 --- a/build/scripts/overnight/configs/win7-64a/x86_64.win64-dev +++ b/build/scripts/overnight/configs/win7-64a/x86_64.win64-dev @@ -6,7 +6,7 @@ BUILD_DBT=yes BUILD_RBT=yes RUN_DBT=yes RUN_RBT_SP=yes -RUN_RBT_SHM=yes +RUN_RBT_SHM=no RUN_EXAMPLES_SHM=no RUN_EXAMPLES_SP=yes diff --git a/build/scripts/overnight/configs/win7-64a/x86_64.win64-dev-nocpp b/build/scripts/overnight/configs/win7-64a/x86_64.win64-dev-nocpp index 8740e292a..768857805 100755 --- a/build/scripts/overnight/configs/win7-64a/x86_64.win64-dev-nocpp +++ b/build/scripts/overnight/configs/win7-64a/x86_64.win64-dev-nocpp @@ -6,7 +6,7 @@ BUILD_DBT=yes BUILD_RBT=yes RUN_DBT=yes RUN_RBT_SP=yes -RUN_RBT_SHM=yes +RUN_RBT_SHM=no RUN_EXAMPLES_SHM=no RUN_EXAMPLES_SP=yes diff --git a/build/scripts/overnight/configs/win7-64a/x86_64.win64-dev-nojava b/build/scripts/overnight/configs/win7-64a/x86_64.win64-dev-nojava index 2f627cf1d..516653d12 100755 --- a/build/scripts/overnight/configs/win7-64a/x86_64.win64-dev-nojava +++ b/build/scripts/overnight/configs/win7-64a/x86_64.win64-dev-nojava @@ -6,7 +6,7 @@ BUILD_DBT=yes BUILD_RBT=yes RUN_DBT=yes RUN_RBT_SP=yes -RUN_RBT_SHM=yes +RUN_RBT_SHM=no RUN_EXAMPLES_SHM=no RUN_EXAMPLES_SP=yes diff --git a/build/scripts/overnight/configs/win7-64a/x86_64.win64-release b/build/scripts/overnight/configs/win7-64a/x86_64.win64-release index 275d7112e..e2e9880bc 100755 --- a/build/scripts/overnight/configs/win7-64a/x86_64.win64-release +++ b/build/scripts/overnight/configs/win7-64a/x86_64.win64-release @@ -6,7 +6,7 @@ BUILD_DBT=yes BUILD_RBT=yes RUN_DBT=yes RUN_RBT_SP=yes -RUN_RBT_SHM=yes +RUN_RBT_SHM=no RUN_EXAMPLES_SHM=no RUN_EXAMPLES_SP=yes diff --git a/build/scripts/overnight/configs/win7-64a/x86_64.win64-release-nodbt b/build/scripts/overnight/configs/win7-64a/x86_64.win64-release-nodbt index 30c7bcb96..63a68569b 100755 --- a/build/scripts/overnight/configs/win7-64a/x86_64.win64-release-nodbt +++ b/build/scripts/overnight/configs/win7-64a/x86_64.win64-release-nodbt @@ -6,7 +6,7 @@ BUILD_DBT=yes BUILD_RBT=yes RUN_DBT=no RUN_RBT_SP=yes -RUN_RBT_SHM=yes +RUN_RBT_SHM=no RUN_EXAMPLES_SHM=no RUN_EXAMPLES_SP=yes diff --git a/build/scripts/overnight/configs/win7-64a/x86_64.win64-release-notao b/build/scripts/overnight/configs/win7-64a/x86_64.win64-release-notao index 467115336..016146ad2 100755 --- a/build/scripts/overnight/configs/win7-64a/x86_64.win64-release-notao +++ b/build/scripts/overnight/configs/win7-64a/x86_64.win64-release-notao @@ -6,7 +6,7 @@ BUILD_DBT=yes BUILD_RBT=yes RUN_DBT=yes RUN_RBT_SP=yes -RUN_RBT_SHM=yes +RUN_RBT_SHM=no RUN_EXAMPLES_SHM=no RUN_EXAMPLES_SP=no diff --git a/build/scripts/overnight/configs/win7-64d/common b/build/scripts/overnight/configs/win7-64d/common new file mode 100644 index 000000000..a146a8403 --- /dev/null +++ b/build/scripts/overnight/configs/win7-64d/common @@ -0,0 +1 @@ +export M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-3.5.3 diff --git a/build/scripts/overnight/configs/win7-64e/common b/build/scripts/overnight/configs/win7-64e/common index ab381e05b..58fa7d8bc 100644 --- a/build/scripts/overnight/configs/win7-64e/common +++ b/build/scripts/overnight/configs/win7-64e/common @@ -11,3 +11,4 @@ unset USERPROFILE #There is no TAO for VS2013 unset TAO_ROOT export OVERRIDE_STRICT_CHECKS=no +export M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-3.5.3 diff --git a/build/scripts/overnight/configs/win7-64e/common_64bit b/build/scripts/overnight/configs/win7-64e/common_64bit index bacf69d91..e339a9e46 100644 --- a/build/scripts/overnight/configs/win7-64e/common_64bit +++ b/build/scripts/overnight/configs/win7-64e/common_64bit @@ -1,5 +1,6 @@ . ./configs/`hostname`/common export VS_ENV_SCRIPT="C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\bin\amd64\vcvars64.bat" -export JAVA_HOME="c:/Program Files/Java/jdk1.6.0_37" +export JAVA6_HOME="c:/Program Files/Java/jdk1.6.0_37" +export JAVA_HOME="c:/Program Files/Java/jdk1.7.0_79" export QTDIR=c:\\cygwin\\home\\dds\\INSTALLED_FOR_DDS\\Qt\\4.8.4_vs2010_64bit diff --git a/build/scripts/overnight/configs/win7a-64/common b/build/scripts/overnight/configs/win7a-64/common index 625a6a2ec..d9766b43e 100644 --- a/build/scripts/overnight/configs/win7a-64/common +++ b/build/scripts/overnight/configs/win7a-64/common @@ -10,3 +10,4 @@ export PATH=/usr/local/bin:$PATH #as the native calls done via TAO ask for a temp directory and windows fallback to using #USERPROFILE which has spaces in and does not work, unsetting solves the problem unset USERPROFILE +export M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-3.5.3 diff --git a/build/scripts/overnight/configs/win7a-64/common_32bit b/build/scripts/overnight/configs/win7a-64/common_32bit index 861e44cf6..60f2b0f27 100644 --- a/build/scripts/overnight/configs/win7a-64/common_32bit +++ b/build/scripts/overnight/configs/win7a-64/common_32bit @@ -1,6 +1,7 @@ . ./configs/`hostname`/common export VS_ENV_SCRIPT="C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\Tools\vsvars32.bat" -export JAVA_HOME="c:/Program Files (x86)/Java/jdk1.6.0_24" +export JAVA6_HOME="c:/Program Files (x86)/Java/jdk1.6.0_24" +export JAVA_HOME="c:/Program Files (x86)/Java/jdk1.7.0_79" export TAO_ROOT=/home/dds/INSTALLED_FOR_DDS/TAO161_0-Windows-vc10-inline-32bit-OpenSpliceDDS_v6.1_UNSUPPORTED_110704 export QTDIR=c:\\cygwin\\home\\dds\\INSTALLED_FOR_DDS\\Qt\\4.8.4_vs2010_32bit diff --git a/build/scripts/overnight/configs/win7a-64/common_64bit b/build/scripts/overnight/configs/win7a-64/common_64bit index 5e6370b3d..98c6fd1f8 100644 --- a/build/scripts/overnight/configs/win7a-64/common_64bit +++ b/build/scripts/overnight/configs/win7a-64/common_64bit @@ -1,6 +1,7 @@ . ./configs/`hostname`/common export VS_ENV_SCRIPT="C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\bin\amd64\vcvars64.bat" -export JAVA_HOME="c:/Program Files/Java/jdk1.6.0_24" +export JAVA6_HOME="c:/Program Files/Java/jdk1.6.0_24" +export JAVA_HOME="c:/Program Files/Java/jdk1.7.0_75" export TAO_ROOT=/home/dds/INSTALLED_FOR_DDS/TAO161_0-Windows-vc10-inline-64bit_110704 export QTDIR=c:\\cygwin\\home\\dds\\INSTALLED_FOR_DDS\\Qt\\4.8.4_vs2010_64bit diff --git a/build/scripts/overnight/configs/win7a/common b/build/scripts/overnight/configs/win7a/common index 209ee25f5..54865005c 100644 --- a/build/scripts/overnight/configs/win7a/common +++ b/build/scripts/overnight/configs/win7a/common @@ -1,11 +1,13 @@ export VS_HOME='/cygdrive/C/Program Files/Microsoft Visual Studio 9.0/' export WINDOWSSDKDIR='/cygdrive/C/Program Files/Microsoft SDKs/Windows/v6.0A' export VS_ENV_SCRIPT="C:\Program Files\Microsoft Visual Studio 9.0\Common7\Tools\vsvars32.bat" -export JAVA_HOME="c:/Program Files/Java/jdk1.6.0_20" +export JAVA6_HOME="c:/Program Files/Java/jdk1.6.0_20" export TAO_ROOT=/home/dds/INSTALLED_FOR_DDS/TAO161_0-Windows-vc9-inline-32bit-OpenSpliceDDS_v5.1_UNSUPPORTED_100324 export JACORB_HOME=/home/dds/INSTALLED\ FOR\ DDS/JacORB-v2.3.1.0 export QTDIR=c:\\cygwin\\home\\dds\\INSTALLED_FOR_DDS\\Qt\\4.8.4_vs2010_32bit export GSOAPHOME=/home/dds/INSTALLED\ FOR\ DDS/gsoap-v2.7 export PROTOBUF_HOME=/home/dds/INSTALLED_FOR_DDS/protobuf-2.6.0 export LAUNCH4J_HOME=/home/dds/INSTALLED_FOR_DDS/Launch4j -export PATH=/usr/local/bin:$PATH \ No newline at end of file +export PATH=/usr/local/bin:$PATH +export JAVA_HOME="c:/Program Files/Java/jdk1.7.0_79" +export M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-3.5.3 diff --git a/build/scripts/overnight/configs/win7b/common b/build/scripts/overnight/configs/win7b/common index 0288c0f8e..80bee8e6c 100644 --- a/build/scripts/overnight/configs/win7b/common +++ b/build/scripts/overnight/configs/win7b/common @@ -3,7 +3,7 @@ export OPENORB_VERSION=1.4.0e export VS_HOME='/cygdrive/C/Program Files/Microsoft Visual Studio 11.0/' export WINDOWSSDKDIR='/cygdrive/C/Program Files/Windows Kits/8.0' export VS_ENV_SCRIPT="C:\Program Files\Microsoft Visual Studio 11.0\Common7\Tools\vsvars32.bat" -export JAVA_HOME="c:/Program Files/Java/jdk1.6.0_37" +export JAVA6_HOME="c:/Program Files/Java/jdk1.6.0_37" export JACORB_HOME=/home/dds/INSTALLED\ FOR\ DDS/JacORB-v2.3.1.0 export QTDIR=c:\\cygwin\\home\\dds\\INSTALLED_FOR_DDS\\Qt\\4.8.4_vs2010_32bit export GSOAPHOME=/home/dds/INSTALLED\ FOR\ DDS/gsoap-v2.7 @@ -14,3 +14,5 @@ export PATH=/usr/local/bin:$PATH #There is no TAO for VS2012 unset TAO_ROOT export OVERRIDE_STRICT_CHECKS=no +export JAVA_HOME="c:/Program Files/Java/jdk1.7.0_75" +export M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-3.5.3 diff --git a/build/scripts/overnight/configs/win7c/common b/build/scripts/overnight/configs/win7c/common index 2f33f7212..219bc69c6 100644 --- a/build/scripts/overnight/configs/win7c/common +++ b/build/scripts/overnight/configs/win7c/common @@ -3,8 +3,9 @@ export OPENORB_VERSION=1.4.0e export VS_HOME='/cygdrive/C/Program Files/Microsoft Visual Studio 12.0/' export WINDOWSSDKDIR='/cygdrive/C/Program Files/Windows Kits/8.1' export VS_ENV_SCRIPT="C:\Program Files\Microsoft Visual Studio 12.0\Common7\Tools\vsvars32.bat" -export JAVA_HOME="c:/Program Files/Java/jdk1.6.0_37" +export JAVA6_HOME="c:/Program Files/Java/jdk1.6.0_37" export JACORB_HOME=/home/dds/INSTALLED\ FOR\ DDS/JacORB-v2.3.1.0 +export ZLIB_HOME=/home/dds/INSTALLED\ FOR\ DDS/zlib-1.2.4 export QTDIR=c:\\cygwin\\home\\dds\\INSTALLED_FOR_DDS\\Qt\\4.8.4_vs2010_32bit export GSOAPHOME=/home/dds/INSTALLED\ FOR\ DDS/gsoap-v2.7 export PROTOBUF_HOME=/home/dds/INSTALLED_FOR_DDS/protobuf-2.6.0 @@ -16,3 +17,8 @@ export PATH=/usr/local/bin:$PROTOBUF_HOME/bin:$PATH unset TAO_ROOT export OVERRIDE_STRICT_CHECKS=no export PATH=$PATH:$ZLIB_HOME +export JAVA_HOME="c:/Program Files/Java/jdk1.7.0" +export M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-3.5.3 +export PYTHON_HOME=/home/dds/INSTALLED_FOR_DDS/portablepython-2.7.3.1 +export SQLITE_HOME=/home/dds/INSTALLED_FOR_DDS/sqlite-amalgamation-3071602 + diff --git a/build/scripts/overnight/configs/win7d/common b/build/scripts/overnight/configs/win7d/common index 7583fad7a..0f9d79d48 100644 --- a/build/scripts/overnight/configs/win7d/common +++ b/build/scripts/overnight/configs/win7d/common @@ -13,3 +13,4 @@ unset USERPROFILE #There is no TAO for VS2012 unset TAO_ROOT export OVERRIDE_STRICT_CHECKS=no +export M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-3.5.3 diff --git a/build/scripts/overnight/configs/win7d/common_64bit b/build/scripts/overnight/configs/win7d/common_64bit index 6f983bbb2..0121c2d33 100644 --- a/build/scripts/overnight/configs/win7d/common_64bit +++ b/build/scripts/overnight/configs/win7d/common_64bit @@ -1,6 +1,7 @@ . ./configs/`hostname`/common export VS_ENV_SCRIPT="C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\bin\amd64\vcvars64.bat" -export JAVA_HOME="c:/Program Files/Java/jdk1.6.0_37" +export JAVA6_HOME="c:/Program Files/Java/jdk1.6.0_37" +export JAVA_HOME="c:/Program Files/Java/jdk1.7.0_79" export QTDIR=c:\\cygwin\\home\\dds\\INSTALLED_FOR_DDS\\Qt\\4.8.4_vs2010_64bit export GSOAPHOME=/home/dds/INSTALLED\ FOR\ DDS/gsoap-v2.7 diff --git a/build/scripts/overnight/configs/win7e/common b/build/scripts/overnight/configs/win7e/common index 3cefa7469..5ba74e02f 100644 --- a/build/scripts/overnight/configs/win7e/common +++ b/build/scripts/overnight/configs/win7e/common @@ -15,3 +15,4 @@ unset USERPROFILE #There is no TAO for VS2013 unset TAO_ROOT export OVERRIDE_STRICT_CHECKS=no +export M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-3.5.3 diff --git a/build/scripts/overnight/configs/win7e/common_64bit b/build/scripts/overnight/configs/win7e/common_64bit index 4c67bb85e..ea7f14c68 100644 --- a/build/scripts/overnight/configs/win7e/common_64bit +++ b/build/scripts/overnight/configs/win7e/common_64bit @@ -1,4 +1,7 @@ . ./configs/`hostname`/common -export JAVA_HOME="c:/Program Files/Java/jdk1.6.0_37" +export JAVA6_HOME="c:/Program Files/Java/jdk1.6.0_37" +export JAVA_HOME="c:/Program Files/Java/jdk1.7.0_79" export ZLIB_HOME= export QTDIR=c:\\cygwin\\home\\dds\\INSTALLED_FOR_DDS\\Qt\\4.8.4_vs2010_64bit +export NODEJS_HOME=/home/dds/INSTALLED_FOR_DDS/nodejs/node-v8.11.1-win-x64 + diff --git a/build/scripts/overnight/configs/win7f/common b/build/scripts/overnight/configs/win7f/common index cd711482e..213112409 100644 --- a/build/scripts/overnight/configs/win7f/common +++ b/build/scripts/overnight/configs/win7f/common @@ -16,3 +16,4 @@ unset USERPROFILE #There is no TAO for VS2015 unset TAO_ROOT export OVERRIDE_STRICT_CHECKS=no +export M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-3.5.3 diff --git a/build/scripts/overnight/configs/win7f/common_64bit b/build/scripts/overnight/configs/win7f/common_64bit index e794b7288..8862913f4 100644 --- a/build/scripts/overnight/configs/win7f/common_64bit +++ b/build/scripts/overnight/configs/win7f/common_64bit @@ -2,6 +2,7 @@ export VS_ENV_SCRIPT="C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\x86_amd64\vcvarsx86_amd64.bat" -export JAVA_HOME="c:/Program Files/Java/jdk1.6.0_37" +export JAVA6_HOME="c:/Program Files/Java/jdk1.6.0_37" +export JAVA_HOME="c:/Program Files/Java/jdk1.7.0_79" export ZLIB_HOME= export QTDIR=c:\\cygwin64\\home\\dds\\INSTALLED_FOR_DDS\\Qt\\4.8.4_vs2010_64bit diff --git a/build/scripts/overnight/configs/win7g/common b/build/scripts/overnight/configs/win7g/common new file mode 100644 index 000000000..dff468682 --- /dev/null +++ b/build/scripts/overnight/configs/win7g/common @@ -0,0 +1,21 @@ +export OPENORB_HOME=/home/dds/INSTALLED\ FOR\ DDS/openorb-v1.4.0 +export OPENORB_VERSION=1.4.0e +export VS_HOME='/cygdrive/C/Program Files/Microsoft Visual Studio 12.0/' +export WINDOWSSDKDIR='/cygdrive/C/Program Files/Windows Kits/8.1' +export VS_ENV_SCRIPT="C:\Program Files\Microsoft Visual Studio 12.0\Common7\Tools\vsvars32.bat" +export JAVA6_HOME="c:/Program Files/Java/jdk1.6.0_37" +export JACORB_HOME=/home/dds/INSTALLED\ FOR\ DDS/JacORB-v2.3.1.0 +export ZLIB_HOME=/home/dds/INSTALLED\ FOR\ DDS/zlib-1.2.4 +export QTDIR=c:\\cygwin\\home\\dds\\INSTALLED_FOR_DDS\\Qt\\4.8.4_vs2010_32bit +export GSOAPHOME=/home/dds/INSTALLED\ FOR\ DDS/gsoap-v2.7 +export PROTOBUF_HOME=/home/dds/INSTALLED_FOR_DDS/protobuf-2.6.0 +export PROTOBUF_LIB_HOME=/home/dds/INSTALLED_FOR_DDS/protobuf-2.6.0/src +export LAUNCH4J_HOME=/home/dds/INSTALLED_FOR_DDS/Launch4j +export PATH=/usr/local/bin:$PROTOBUF_HOME/bin:$PATH + +#There is no TAO for VS2013 +unset TAO_ROOT +export OVERRIDE_STRICT_CHECKS=no +export PATH=$PATH:$ZLIB_HOME +export JAVA_HOME="c:/Program Files/Java/jdk1.7.0" +export M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-3.5.3 diff --git a/build/scripts/overnight/configs/win7g/dev_build b/build/scripts/overnight/configs/win7g/dev_build new file mode 100644 index 000000000..be58c3790 --- /dev/null +++ b/build/scripts/overnight/configs/win7g/dev_build @@ -0,0 +1 @@ +#export TAO_ROOT=/home/dds/INSTALLED_FOR_DDS/TAO161_0-Windows-vc9-debug-32bit-OpenSpliceDDS_v5.1_UNSUPPORTED_100324 diff --git a/build/scripts/overnight/configs/win7g/x86.win32-debug-vs12-inner b/build/scripts/overnight/configs/win7g/x86.win32-debug-vs12-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/win7g/x86.win32-debug-vs12-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/win7g/x86.win32-debug-vs12-notest-inner b/build/scripts/overnight/configs/win7g/x86.win32-debug-vs12-notest-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/win7g/x86.win32-debug-vs12-notest-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/win7g/x86.win32-dev-vs12 b/build/scripts/overnight/configs/win7g/x86.win32-dev-vs12 new file mode 100644 index 000000000..d8bf3363e --- /dev/null +++ b/build/scripts/overnight/configs/win7g/x86.win32-dev-vs12 @@ -0,0 +1,13 @@ +BUILD=yes +SETUP_TYPE=x86.win32-dev +BUILD_DIST=yes +BUILD_EXAMPLES=yes +KEEP_DIST=yes +RUN_DBT=no +RUN_RBT=no +RUN_EXAMPLES_SP=yes +RUN_EXAMPLES_SHM=no +VALGRIND=no + +. configs/`hostname`/common +. configs/`hostname`/dev_build diff --git a/build/scripts/overnight/configs/win7g/x86.win32-dev-vs12-inner b/build/scripts/overnight/configs/win7g/x86.win32-dev-vs12-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/win7g/x86.win32-dev-vs12-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/win7g/x86.win32-dev-vs12-normi-inner b/build/scripts/overnight/configs/win7g/x86.win32-dev-vs12-normi-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/win7g/x86.win32-dev-vs12-normi-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/win7g/x86.win32-dev-vs12-notest-inner b/build/scripts/overnight/configs/win7g/x86.win32-dev-vs12-notest-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/win7g/x86.win32-dev-vs12-notest-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/win7g/x86.win32-dev-vs12-notest-normi-inner b/build/scripts/overnight/configs/win7g/x86.win32-dev-vs12-notest-normi-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/win7g/x86.win32-dev-vs12-notest-normi-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/win7g/x86.win32-release-vs12 b/build/scripts/overnight/configs/win7g/x86.win32-release-vs12 new file mode 100644 index 000000000..6e568d391 --- /dev/null +++ b/build/scripts/overnight/configs/win7g/x86.win32-release-vs12 @@ -0,0 +1,12 @@ +BUILD=yes +SETUP_TYPE=x86.win32-release +BUILD_DIST=yes +BUILD_EXAMPLES=yes +KEEP_DIST=yes +RUN_DBT=no +RUN_RBT=no +RUN_EXAMPLES_SP=yes +RUN_EXAMPLES_SHM=no +VALGRIND=no + +. configs/`hostname`/common diff --git a/build/scripts/overnight/configs/win7g/x86.win32-release-vs12-inner b/build/scripts/overnight/configs/win7g/x86.win32-release-vs12-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/win7g/x86.win32-release-vs12-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/win7g/x86.win32-release-vs12-nodbt-inner b/build/scripts/overnight/configs/win7g/x86.win32-release-vs12-nodbt-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/win7g/x86.win32-release-vs12-nodbt-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/win7g/x86.win32-release-vs12-nodbt-normi-inner b/build/scripts/overnight/configs/win7g/x86.win32-release-vs12-nodbt-normi-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/win7g/x86.win32-release-vs12-nodbt-normi-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/win7g/x86.win32-release-vs12-nolic-inner b/build/scripts/overnight/configs/win7g/x86.win32-release-vs12-nolic-inner new file mode 100644 index 000000000..b5697c245 --- /dev/null +++ b/build/scripts/overnight/configs/win7g/x86.win32-release-vs12-nolic-inner @@ -0,0 +1,4 @@ +. configs/common-inner +unset RLM_HOME +unset RLM_TARGET +unset RLM_VERSION \ No newline at end of file diff --git a/build/scripts/overnight/configs/win7g/x86.win32-release-vs12-normi-inner b/build/scripts/overnight/configs/win7g/x86.win32-release-vs12-normi-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/win7g/x86.win32-release-vs12-normi-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/win7g/x86.win32-release-vs12-notest-inner b/build/scripts/overnight/configs/win7g/x86.win32-release-vs12-notest-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/win7g/x86.win32-release-vs12-notest-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/win7g/x86.win32-release-vs12-notest-normi-inner b/build/scripts/overnight/configs/win7g/x86.win32-release-vs12-notest-normi-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/win7g/x86.win32-release-vs12-notest-normi-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/win7h/common b/build/scripts/overnight/configs/win7h/common new file mode 100644 index 000000000..5ba74e02f --- /dev/null +++ b/build/scripts/overnight/configs/win7h/common @@ -0,0 +1,18 @@ +export OPENORB_HOME=/home/dds/INSTALLED\ FOR\ DDS/openorb-v1.4.0 +export OPENORB_VERSION=1.4.0e +export JACORB_HOME=/home/dds/INSTALLED\ FOR\ DDS/JacORB-v2.3.1.0 +export GSOAPHOME=/home/dds/INSTALLED\ FOR\ DDS/gsoap-v2.7 +export PROTOBUF_HOME=/home/dds/INSTALLED_FOR_DDS/protobuf-2.6.0 +export LAUNCH4J_HOME=/home/dds/INSTALLED_FOR_DDS/Launch4j +export PATH=/usr/local/bin:$PATH +export VS_HOME='/cygdrive/C/Program Files (x86)/Microsoft Visual Studio 12.0' + +#Winxp combined with new cygwin does not set TMP or TEMP even when in the windows settings +#as the native calls done via TAO ask for a temp directory and windows fallback to using +#USERPROFILE which has spaces in and does not work, unsetting solves the problem +unset USERPROFILE + +#There is no TAO for VS2013 +unset TAO_ROOT +export OVERRIDE_STRICT_CHECKS=no +export M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-3.5.3 diff --git a/build/scripts/overnight/configs/win7h/common_64bit b/build/scripts/overnight/configs/win7h/common_64bit new file mode 100644 index 000000000..491000b98 --- /dev/null +++ b/build/scripts/overnight/configs/win7h/common_64bit @@ -0,0 +1,5 @@ +. ./configs/`hostname`/common +export JAVA6_HOME="c:/Program Files/Java/jdk1.6.0_37" +export JAVA_HOME="c:/Program Files/Java/jdk1.7.0_79" +export ZLIB_HOME= +export QTDIR=c:\\cygwin\\home\\dds\\INSTALLED_FOR_DDS\\Qt\\4.8.4_vs2010_64bit diff --git a/build/scripts/overnight/configs/win7h/dev_build_64bit b/build/scripts/overnight/configs/win7h/dev_build_64bit new file mode 100644 index 000000000..2239a893a --- /dev/null +++ b/build/scripts/overnight/configs/win7h/dev_build_64bit @@ -0,0 +1,2 @@ +#export TAO_ROOT=/home/dds/INSTALLED_FOR_DDS/TAO161_0-Windows-vc10-debug-64bit_110704 + diff --git a/build/scripts/overnight/configs/win7h/x86_64.win64-debug-vs12-inner b/build/scripts/overnight/configs/win7h/x86_64.win64-debug-vs12-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/win7h/x86_64.win64-debug-vs12-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/win7h/x86_64.win64-debug-vs12-notest-inner b/build/scripts/overnight/configs/win7h/x86_64.win64-debug-vs12-notest-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/win7h/x86_64.win64-debug-vs12-notest-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/win7h/x86_64.win64-dev-vs12 b/build/scripts/overnight/configs/win7h/x86_64.win64-dev-vs12 new file mode 100644 index 000000000..70f283814 --- /dev/null +++ b/build/scripts/overnight/configs/win7h/x86_64.win64-dev-vs12 @@ -0,0 +1,13 @@ +BUILD=yes +SETUP_TYPE=x86_64.win64-dev +BUILD_DIST=yes +BUILD_EXAMPLES=yes +KEEP_DIST=yes +RUN_DBT=no +RUN_RBT=no +RUN_EXAMPLES_SP=yes +RUN_EXAMPLES_SHM=no +VALGRIND=no + +. configs/`hostname`/common_64bit +. configs/`hostname`/dev_build_64bit diff --git a/build/scripts/overnight/configs/win7h/x86_64.win64-dev-vs12-inner b/build/scripts/overnight/configs/win7h/x86_64.win64-dev-vs12-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/win7h/x86_64.win64-dev-vs12-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/win7h/x86_64.win64-dev-vs12-nocpp-inner b/build/scripts/overnight/configs/win7h/x86_64.win64-dev-vs12-nocpp-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/win7h/x86_64.win64-dev-vs12-nocpp-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/win7h/x86_64.win64-dev-vs12-nojava-inner b/build/scripts/overnight/configs/win7h/x86_64.win64-dev-vs12-nojava-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/win7h/x86_64.win64-dev-vs12-nojava-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/win7h/x86_64.win64-dev-vs12-notest-inner b/build/scripts/overnight/configs/win7h/x86_64.win64-dev-vs12-notest-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/win7h/x86_64.win64-dev-vs12-notest-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/win7h/x86_64.win64-release-vs12 b/build/scripts/overnight/configs/win7h/x86_64.win64-release-vs12 new file mode 100644 index 000000000..1f3de6e2b --- /dev/null +++ b/build/scripts/overnight/configs/win7h/x86_64.win64-release-vs12 @@ -0,0 +1,12 @@ +BUILD=yes +SETUP_TYPE=x86_64.win64-release +BUILD_DIST=yes +BUILD_EXAMPLES=yes +KEEP_DIST=yes +RUN_DBT=no +RUN_RBT=no +RUN_EXAMPLES_SP=yes +RUN_EXAMPLES_SHM=no +VALGRIND=no + +. configs/`hostname`/common_64bit diff --git a/build/scripts/overnight/configs/win7h/x86_64.win64-release-vs12-inner b/build/scripts/overnight/configs/win7h/x86_64.win64-release-vs12-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/win7h/x86_64.win64-release-vs12-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/win7h/x86_64.win64-release-vs12-nodbt-inner b/build/scripts/overnight/configs/win7h/x86_64.win64-release-vs12-nodbt-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/win7h/x86_64.win64-release-vs12-nodbt-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/win7h/x86_64.win64-release-vs12-nolic-inner b/build/scripts/overnight/configs/win7h/x86_64.win64-release-vs12-nolic-inner new file mode 100644 index 000000000..b5697c245 --- /dev/null +++ b/build/scripts/overnight/configs/win7h/x86_64.win64-release-vs12-nolic-inner @@ -0,0 +1,4 @@ +. configs/common-inner +unset RLM_HOME +unset RLM_TARGET +unset RLM_VERSION \ No newline at end of file diff --git a/build/scripts/overnight/configs/win7h/x86_64.win64-release-vs12-notest-inner b/build/scripts/overnight/configs/win7h/x86_64.win64-release-vs12-notest-inner new file mode 100644 index 000000000..0fdccf92a --- /dev/null +++ b/build/scripts/overnight/configs/win7h/x86_64.win64-release-vs12-notest-inner @@ -0,0 +1 @@ +. configs/common-inner diff --git a/build/scripts/overnight/configs/winx/common b/build/scripts/overnight/configs/winx/common index 0229c535b..bcb61c4dd 100644 --- a/build/scripts/overnight/configs/winx/common +++ b/build/scripts/overnight/configs/winx/common @@ -8,3 +8,4 @@ export GSOAPHOME=/home/dds/INSTALLED\ FOR\ DDS/gsoap-v2.7 #There is no TAO for VS2013 unset TAO_ROOT export OVERRIDE_STRICT_CHECKS=no +export M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-3.5.3 diff --git a/build/scripts/overnight/configs/winxp12/common b/build/scripts/overnight/configs/winxp12/common index 0fab88d7f..75906ed79 100644 --- a/build/scripts/overnight/configs/winxp12/common +++ b/build/scripts/overnight/configs/winxp12/common @@ -1,6 +1,6 @@ export VS_HOME='/cygdrive/C/Program Files/Microsoft Visual Studio 8/' export VS_ENV_SCRIPT="C:\Program Files\Microsoft Visual Studio 8\Common7\Tools\vsvars32.bat" -export JAVA_HOME="c:/Program Files/Java/jdk1.6.0_20" +export JAVA6_HOME="c:/Program Files/Java/jdk1.6.0_20" export TAO_ROOT=/home/dds/INSTALLED_FOR_DDS/TAO161_0-Windows-vc8-inline-32bit-OpenSpliceDDS_v4.1_UNSUPPORTED_091104 export JACORB_HOME=/home/dds/INSTALLED\ FOR\ DDS/JacORB-v2.3.1.0 export GSOAPHOME=/home/dds/INSTALLED\ FOR\ DDS/gsoap-v2.7 @@ -13,3 +13,5 @@ export PATH=/usr/local/bin:$PATH #USERPROFILE which has spaces in and does not work, unsetting solves the problem unset USERPROFILE export QTDIR=c:\\cygwin\\home\\dds\\INSTALLED_FOR_DDS\\Qt\\4.8.4_vs2010_32bit +export JAVA_HOME="c:/Program Files/Java/jdk1.7.0_51" +export M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-3.5.3 diff --git a/build/scripts/overnight/configs/winxp13-new/common b/build/scripts/overnight/configs/winxp13-new/common index 8b922a1c8..60898b1a5 100644 --- a/build/scripts/overnight/configs/winxp13-new/common +++ b/build/scripts/overnight/configs/winxp13-new/common @@ -1,6 +1,6 @@ export VS_HOME='/cygdrive/C/Program Files/Microsoft Visual Studio 8/' export VS_ENV_SCRIPT="C:\Program Files\Microsoft Visual Studio 8\Common7\Tools\vsvars32.bat" -export JAVA_HOME="c:/Program Files/Java/jdk1.6.0_22" +export JAVA6_HOME="c:/Program Files/Java/jdk1.6.0_22" export TAO_ROOT=/home/dds/INSTALLED_FOR_DDS/TAO161_0-Windows-vc8-inline-32bit-OpenSpliceDDS_v4.1_UNSUPPORTED_091104 export JACORB_HOME=/home/dds/INSTALLED\ FOR\ DDS/JacORB-v2.3.1.0 export GSOAPHOME=/home/dds/INSTALLED\ FOR\ DDS/gsoap-v2.7 @@ -13,3 +13,5 @@ export PATH=/usr/local/bin:$PATH #USERPROFILE which has spaces in and does not work, unsetting solves the problem unset USERPROFILE export QTDIR=c:\\cygwin\\home\\dds\\INSTALLED_FOR_DDS\\Qt\\4.8.4_vs2010_32bit +export JAVA_HOME="c:/Program Files/Java/jdk1.7.0_21" +export M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-3.5.3 diff --git a/build/scripts/overnight/configs/winxp13-new/x86.win32-release-examples-inner b/build/scripts/overnight/configs/winxp13-new/x86.win32-release-examples-inner new file mode 100644 index 000000000..4b8028f8d --- /dev/null +++ b/build/scripts/overnight/configs/winxp13-new/x86.win32-release-examples-inner @@ -0,0 +1,3 @@ +. configs/common-inner +#export QTDIR=c:\\cygwin\\home\dds\\INSTALLED_FOR_DDS\\Qt\\4.8.4_vs2010_32bit +export BOOST_ROOT=c:\\cygwin\\home\\dds\\INSTALLED_FOR_DDS\\boost_1_53_0 diff --git a/build/scripts/overnight/configs/winxp13/common b/build/scripts/overnight/configs/winxp13/common index c3a9f8d5f..bdea43925 100644 --- a/build/scripts/overnight/configs/winxp13/common +++ b/build/scripts/overnight/configs/winxp13/common @@ -1,6 +1,6 @@ export VS_HOME='/cygdrive/C/Program Files/Microsoft Visual Studio 8/' export VS_ENV_SCRIPT="C:\Program Files\Microsoft Visual Studio 8\Common7\Tools\vsvars32.bat" -export JAVA_HOME="c:/Program Files/Java/jdk1.6.0_22" +export JAVA6_HOME="c:/Program Files/Java/jdk1.6.0_22" export TAO_ROOT=/home/dds/INSTALLED_FOR_DDS/TAO161_0-Windows-vc8-inline-32bit-OpenSpliceDDS_v4.1_UNSUPPORTED_091104 export JACORB_HOME=/home/dds/INSTALLED\ FOR\ DDS/JacORB-v2.3.1.0 export GSOAPHOME=/home/dds/INSTALLED\ FOR\ DDS/gsoap-v2.7 @@ -12,4 +12,6 @@ unset USERPROFILE export QTDIR=c:\\cygwin\\home\\dds\\INSTALLED_FOR_DDS\\Qt\\4.8.4_vs2010_32bit export PROTOBUF_HOME=/home/dds/INSTALLED_FOR_DDS/protobuf-2.6.0 export LAUNCH4J_HOME=/home/dds/INSTALLED_FOR_DDS/Launch4j -export PATH=/usr/local/bin:$PATH \ No newline at end of file +export PATH=/usr/local/bin:$PATH +export JAVA_HOME="c:/Program Files/Java/jdk1.7.0_79" +export M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-3.5.3 diff --git a/build/scripts/overnight/configs/winxp16/common b/build/scripts/overnight/configs/winxp16/common index c2293694f..6f3a977f5 100644 --- a/build/scripts/overnight/configs/winxp16/common +++ b/build/scripts/overnight/configs/winxp16/common @@ -11,3 +11,4 @@ export GSOAPHOME=/home/dds/INSTALLED\ FOR\ DDS/gsoap-v2.7 #USERPROFILE which has spaces in and does not work, unsetting solves the problem unset USERPROFILE export QTDIR=c:\\cygwin\\home\\dds\\INSTALLED_FOR_DDS\\Qt\\4.8.4_vs2010_32bit +export M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-3.5.3 diff --git a/build/scripts/overnight/configs/winxp17/common b/build/scripts/overnight/configs/winxp17/common index 32f913a34..2a19482eb 100644 --- a/build/scripts/overnight/configs/winxp17/common +++ b/build/scripts/overnight/configs/winxp17/common @@ -2,8 +2,10 @@ export VS_HOME='/cygdrive/C/Program Files (x86)/Microsoft Visual Studio 10.0/' export VS_HOME='/cygdrive/C/Program Files/Microsoft Visual Studio 9.0/' export VS_ENV_SCRIPT="C:\Program Files\Microsoft Visual Studio 9.0\Common7\Tools\vsvars32.bat" export WINDOWSSDKDIR='/cygdrive/C/Program Files/Microsoft SDKs/Windows/v6.0A' -export JAVA_HOME="c:/Program Files/Java/jdk1.6.0_24" +export JAVA6_HOME="c:/Program Files/Java/jdk1.6.0_24" export TAO_ROOT=/home/dds/INSTALLED_FOR_DDS/TAO161_0-Windows-vc9-inline-32bit-OpenSpliceDDS_v4.1_UNSUPPORTED_091104 export JACORB_HOME=/home/dds/INSTALLED\ FOR\ DDS/JacORB-v2.3.1.0 export QTDIR=c:\\cygwin\\home\\dds\\INSTALLED_FOR_DDS\\Qt\\4.8.4_vs2010_32bit export GSOAPHOME=/home/dds/INSTALLED\ FOR\ DDS/gsoap-v2.7 +export JAVA_HOME="c:/Program Files/Java/jdk1.7.0_79" +export M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-3.5.3 diff --git a/build/scripts/overnight/configs/winxp2/common b/build/scripts/overnight/configs/winxp2/common new file mode 100644 index 000000000..20aac3b80 --- /dev/null +++ b/build/scripts/overnight/configs/winxp2/common @@ -0,0 +1,2 @@ +export JAVA_HOME="c:/Program Files/Java/jdk1.7.0_79" +export M2_HOME=/home/dds/INSTALLED_FOR_DDS/apache-maven-3.5.3 diff --git a/build/scripts/overnight/dcps_build b/build/scripts/overnight/dcps_build index a0ed7cede..4156ac398 100755 --- a/build/scripts/overnight/dcps_build +++ b/build/scripts/overnight/dcps_build @@ -77,40 +77,22 @@ fi if [ "$COVERITY" = "yes" ] then - for i in $ANALYSIS_TYPE - do - STREAM="${i}_${BRANCH_NAME}_${HOSTNAME}_${SPLICE_PLATFORM}" - echo "++++++++COVERITY analyze $i" - echo "++++++++COVERITY stream setup is $STREAM" - if [ "$i" = "CandC++" ] - then - echo "++++++++COMMAND [cov-analyze --dir $CACHE_DIR --user-model-file $MODEL_DB_FILE $COV_C_CPP_ANALYSIS_OPTIONS $COV_C_CPP_ANALYSIS_EXTRA_OPTIONS]" - cov-analyze --dir $CACHE_DIR --user-model-file $MODEL_DB_FILE \ - $COV_C_CPP_ANALYSIS_OPTIONS $COV_C_CPP_ANALYSIS_EXTRA_OPTIONS - if [ $? != 0 ] - then - exit 2 - fi - fi - if [ "$i" = "JAVA" ] - then - echo "++++++++COMMAND [cov-analyze-java --dir $CACHE_DIR --user-model-file $MODEL_DB_FILE $COV_JAVA_ANALYSIS_OPTIONS $COV_JAVA_ANALYSIS_EXTRA_OPTIONS]" - cov-analyze-java --dir $CACHE_DIR --user-model-file $MODEL_DB_FILE \ - $COV_JAVA_ANALYSIS_OPTIONS $COV_JAVA_ANALYSIS_EXTRA_OPTIONS - if [ $? != 0 ] - then - exit 2 - fi - fi - echo "++++++++COVERITY commiting defects to $STREAM" - echo "++++++++COMMAND [cov-commit-defects --dir $CACHE_DIR --host $COV_SERVER --port $COV_PORT --user $COV_USER --password $COV_PASSWORD --stream $STREAM]" - cov-commit-defects --dir $CACHE_DIR --host $COV_SERVER --port $COV_PORT \ - --user $COV_USER --password $COV_PASSWORD --stream $STREAM - if [ $? != 0 ] - then - exit 2 - fi - done + STREAM="CandC++_${BRANCH_NAME}_${HOSTNAME}_${SPLICE_PLATFORM}" + echo "++++++++COVERITY analyze CandC++/Java" + echo "++++++++COVERITY stream setup is $STREAM" + echo "++++++++COMMAND [cov-analyze --dir $CACHE_DIR --user-model-file $MODEL_DB_FILE $COV_ANALYSIS_OPTIONS $COV_ANALYSIS_EXTRA_OPTIONS]" + cov-analyze --dir $CACHE_DIR --user-model-file $MODEL_DB_FILE $COV_ANALYSIS_OPTIONS $COV_ANALYSIS_EXTRA_OPTIONS + if [ $? != 0 ] + then + exit 2 + fi + echo "++++++++COVERITY commiting defects to $STREAM" + echo "++++++++COMMAND [cov-commit-defects --dir $CACHE_DIR --host $COV_SERVER --port $COV_PORT --user $COV_USER --password $COV_PASSWORD --stream $STREAM]" + cov-commit-defects --dir $CACHE_DIR --host $COV_SERVER --port $COV_PORT --user $COV_USER --password $COV_PASSWORD --stream $STREAM + if [ $? != 0 ] + then + exit 2 + fi fi # Create all features file as a reference for the features enabled found on the scoreboard. diff --git a/build/scripts/overnight/dcps_build_examples b/build/scripts/overnight/dcps_build_examples index 4834b880b..ae01dec10 100755 --- a/build/scripts/overnight/dcps_build_examples +++ b/build/scripts/overnight/dcps_build_examples @@ -451,7 +451,7 @@ unix_windows_examples() if check_platform then PATH="$JAVA_HOME/bin:$PATH" - PATH="$PATH:$TAO_ROOT/bin:$JACORB_HOME/bin" + PATH="$PATH:$TAO_ROOT/bin:$JACORB_HOME/bin:$M2_HOME/bin" LD_LIBRARY_PATH="$LD_LIBRARY_PATH:$TAO_ROOT/lib" @@ -468,7 +468,7 @@ unix_windows_examples() ODBCINI="$ODBCHOME/etc/odbc.ini" ODBCINST="$ODBCHOME/etc/odbcinst.ini" - ODBC_MSSQL_SERVER="10.1.0.189" + ODBC_MSSQL_SERVER="10.1.5.197" ODBC_MYSQL_SERVER="10.1.0.191" ODBCSYSINI="$ODBCHOME/etc" ODBC_LIB_NAME="odbc" @@ -482,11 +482,22 @@ unix_windows_examples() PATH=$OSPL_EXAMPLE_BUILD_PREFIX_PATH:$PATH fi - # Temporary debugging to try and see why corba builds fail - works OK building - # manually on ubunt1604 - REMOVE when done.... - env | sort > env.log - echo " #### Example Build Begin #### " + #build all java examples + + if [ -f "pom.xml" ] + then + mvn package + if [ $? != 0 ] + then + echo "Failed to build Java5 examples" + else + echo "Building Java5 examples" + fi + else + echo "No pom.xml not building Java5 examples" + fi + for PROJECT in $PROJECTS do if [ -f "$PROJECT" ] @@ -503,24 +514,6 @@ unix_windows_examples() fi done - #The protobuf example has it's own BUILD files and is not built using MPC - cd "$EXAMPLESDIR/protobuf/java5/standalone" - if [ $? != 0 ] - then - echo "INFO: Couldn't locate protobuf java5 example directory in installed HDE." - else - #Protocol buffers is not currently supported on all platforms so only build - #if a BUILD file exists - if [ -f "BUILD" ] - then - bash ./BUILD - if [ $? != 0 ] - then - echo "Building java5 protobuf example failed" - BUILD_ERROR=1 - fi - fi - fi cd "$EXAMPLESDIR/protobuf/isocpp2/standalone" if [ $? != 0 ] then @@ -580,12 +573,24 @@ unix_windows_examples() echo "set JAVA_HOME=$JAVA_HOME" >> setenv.bat - echo "set PATH=%JAVA_HOME%\bin;%TAO_ROOT%\bin;%TAO_ROOT%\lib;%PATH%;%JACORB_HOME%\bin;%PROTOBUF_HOME%\bin;C:\Python27" >> setenv.bat + XPATH=`cygpath -d "$M2_HOME"` + echo "set MAVEN_HOME=$XPATH" >> setenv.bat + echo "set M2_HOME=$XPATH" >> setenv.bat + XPATH=`cygpath -d "$MAVEN_UTILS"` + echo "set MAVEN_UTILS=$XPATH" >> setenv.bat + + echo "set PATH=%MAVEN_HOME%\bin;%JAVA_HOME%\bin;%TAO_ROOT%\bin;%TAO_ROOT%\lib;%PATH%;%JACORB_HOME%\bin;%PROTOBUF_HOME%\bin;C:\Python27" >> setenv.bat echo "set CLASSPATH=%CLASSPATH%;%JACORB_HOME%\lib\endorsed\jacorb.jar;%JACORB_HOME%\lib\endorsed\logkit.jar;%JACORB_HOME%\lib\idl.jar" >> setenv.bat echo "set VS_ENV_SCRIPT=$VS_ENV_SCRIPT" >> setenv.bat + if [ -n "$BOOST_ROOT" ] + then + XPATH=`cygpath -w "$BOOST_ROOT"` + echo "set BOOST_ROOT=$XPATH" >> setenv.bat + fi + XPATH=`cygpath -w "$BASE"` echo "set OSPLI_BASE=$XPATH" >> setenv.bat diff --git a/build/scripts/overnight/dcps_create_source b/build/scripts/overnight/dcps_create_source index 5a44ee222..25ee7f982 100755 --- a/build/scripts/overnight/dcps_create_source +++ b/build/scripts/overnight/dcps_create_source @@ -1,6 +1,6 @@ #!/bin/bash -CURR_YEAR=2017 +CURR_YEAR=2018 . buildsys/functions diff --git a/build/scripts/overnight/dcps_functions b/build/scripts/overnight/dcps_functions index c6dffa4cd..f8bea2375 100644 --- a/build/scripts/overnight/dcps_functions +++ b/build/scripts/overnight/dcps_functions @@ -202,12 +202,12 @@ test_perform_dbt_tests () XPASS=`grep 'DBT XPASS count' $1/management_summary.txt | awk -F': ' '{ print $2 }'` MISSING=`grep 'DBT missing testcases' $1/management_summary.txt | awk -F': ' '{ print $2 }'` CORES=`grep 'DBT Core dumps' $1/management_summary.txt | awk -F': ' '{ print $2 }'` - if [ $FAIL = 0 -a $XPASS = 0 -a $MISSING = 0 ] + if [ $FAIL = 0 -a $XPASS = 0 -a $MISSING = 0 -a $CORES = 0 ] then test_configure $2 T_PERFORM_DBT_1=$? if [ "$3" = 0 -a "$T_PERFORM_DBT_1" != 0 ] - then + then return 0 else DBT_INFO="RUN/DBT=FAIL" diff --git a/build/scripts/overnight/dcps_run_examples b/build/scripts/overnight/dcps_run_examples index 37b1ae384..16c3fde5a 100755 --- a/build/scripts/overnight/dcps_run_examples +++ b/build/scripts/overnight/dcps_run_examples @@ -54,7 +54,7 @@ add_example() # The protobuf example is not built with MPC so there is no # Makefile and the example should be added as we check it has # been built before we add it anyway. - if [ "$1" != "protobuf/java5/standalone" -a "$1" != "protobuf/isocpp2/standalone" ] + if [ "$1" != "protobuf/isocpp2/standalone" ] then if test -f "$1/Makefile" then @@ -289,24 +289,6 @@ else add_example dcps/Throughput/c99/ fi - # isocpp - need to check for more than a directory because the - # run scripts are copied in as a whole so there will always be - # an isocpp directory - if [ -f "$EXAMPLESDIR/dcps/HelloWorld/isocpp/HelloWorld.mpc" ] - then - add_example dcps/BuiltInTopics/isocpp - add_example dcps/ContentFilteredTopic/isocpp - add_example dcps/HelloWorld/isocpp - add_example dcps/Lifecycle/isocpp - add_example dcps/Listener/isocpp - add_example dcps/Ownership/isocpp - add_example dcps/QueryCondition/isocpp - add_example dcps/RoundTrip/isocpp - add_example dcps/Throughput/isocpp - add_example dcps/Tutorial/isocpp - add_example dcps/WaitSet/isocpp - fi - # isocpp2 - need to check for more than a directory because the # run scripts are copied in as a whole so there will always be # an isocpp2 directory @@ -331,7 +313,7 @@ else # java standalone add_example dcps/ContentFilteredTopic/java/standalone add_example dcps/HelloWorld/java/standalone - add_example dcps/HelloWorld/java5/ + add_example dcps/HelloWorld/java5 add_example dcps/Lifecycle/java/standalone add_example dcps/Listener/java/standalone add_example dcps/Ownership/java/standalone @@ -343,8 +325,7 @@ else add_example dcps/RoundTrip/java5 add_example dcps/Throughput/java5 add_example dcps/Tutorial/java5 - add_example dcps/PingPong/java5/corba - add_example dcps/PingPong/java5/standalone + add_example dcps/PingPong/java5 add_example dcps/BuiltInTopics/java5 add_example dcps/ContentFilteredTopic/java5 add_example dcps/Lifecycle/java5 @@ -400,9 +381,9 @@ else fi #Add the protobuf example if it has built successfully - just check for the publishers - if [ -f "$EXAMPLESDIR/protobuf/java5/standalone/saj5-protobuf-publisher.jar" ] + if [ -f "$EXAMPLESDIR/protobuf/java5/pub/java5_protobuf_pub.jar" ] then - add_example protobuf/java5/standalone + add_example protobuf/java5 fi if [ -f "$EXAMPLESDIR/protobuf/isocpp2/standalone/publisher" ] then @@ -414,6 +395,22 @@ else fi fi + # The Durability and DBMS connect examples have their own config files + # so run them last + add_example dcps/Durability/c/standalone + add_example dcps/Durability/cpp/standalone + add_example dcps/Durability/java/standalone + + # Always need to check for more than the isocpp2 directory as + # the run scripts are copied in regardless so there will always + # be an isocpp2 directory. run the durability example last as + # it has a it's own config file. + if [ -f "$EXAMPLESDIR/dcps/Durability/isocpp2/Durability.mpc" ] + then + add_example dcps/Durability/isocpp2 + fi + + if [ "$DEP" != "none" ] then add_example services/dbmsconnect/SQL/C++/ODBC @@ -440,9 +437,9 @@ else export PATH XPATH="$(cygpath -w $BASE)"; - - echo "Running examples " - cmd.exe /C $XPATH/run_python_examples.bat >> $LOGDIR/examples/run_$EXRUNTYPE/run_results.txt + + echo "Running examples " + cmd.exe /C $XPATH/run_python_examples.bat >> $LOGDIR/examples/run_$EXRUNTYPE/run_results.txt 2>&1 grep "Examples Failed = 0" $SUMMARY_HTML RESULT=$? else @@ -463,7 +460,7 @@ else sh $BASE/run_python_examples.sh >> $LOGDIR/examples/run_$EXRUNTYPE/run_results.txt fi grep "Examples Failed = 0" $SUMMARY_HTML - RESULT=$? + RESULT=$? else echo "Running VxWorks examples" cd .. @@ -499,6 +496,7 @@ else echo export LD_LIBRARY_PATH >> $RRSCRIPT echo OVERRIDE_LD_LIBRARY_PATH='$LD_LIBRARY_PATH' >> $RRSCRIPT echo export OVERRIDE_LD_LIBRARY_PATH >> $RRSCRIPT + echo export SPLICE_TARGET_HOST=$SPLICE_TARGET_HOST >> $RRSCRIPT echo sh ./run_examples.sh >> $RRSCRIPT chmod +x $RRSCRIPT cp $BASE/run_examples.sh $EXAMPLESDIR diff --git a/build/scripts/overnight/dcps_uninstall_distro b/build/scripts/overnight/dcps_uninstall_distro index 5eb2e550f..02e392542 100755 --- a/build/scripts/overnight/dcps_uninstall_distro +++ b/build/scripts/overnight/dcps_uninstall_distro @@ -83,7 +83,7 @@ fi UNINSTALLER_NAME="$WORKDIR/$EXAMPLE_INSTALL_DIR/$VORTEX_INSTALL_DIR/uninstall-$SHORTSETUP-HDE$SFX" -if [ -f $UNINSTALLER_NAME ] +if [ -f "$UNINSTALLER_NAME" ] then echo "Uninstalling HDE..." uninstall $EXAMPLE_INSTALL_DIR/$VORTEX_INSTALL_DIR @@ -91,7 +91,7 @@ fi UNINSTALLER_NAME="$WORKDIR/$EXAMPLE_INSTALL_DIR/$PACKAGE_VERSION/uninstall-$SHORTSETUP-TEST" -if [ -f $UNINSTALLER_NAME ] +if [ -f "$UNINSTALLER_NAME" ] then echo "Uninstalling TEST ..." uninstall $EXAMPLE_INSTALL_DIR/$PACKAGE_VERSION @@ -99,7 +99,7 @@ fi UNINSTALLER_NAME="$WORKDIR/$RTS_INSTALL_DIR/$VORTEX_INSTALL_DIR/uninstall-$SHORTSETUP-RTS$SFX" -if [ -f $UNINSTALLER_NAME ] +if [ -f "$UNINSTALLER_NAME" ] then echo "Uninstalling RTS..." uninstall $RTS_INSTALL_DIR/$VORTEX_INSTALL_DIR diff --git a/build/scripts/overnight/example_automation_scripts/examples/Functions.bat b/build/scripts/overnight/example_automation_scripts/examples/Functions.bat index a65aaa0f0..6e11fdda9 100644 --- a/build/scripts/overnight/example_automation_scripts/examples/Functions.bat +++ b/build/scripts/overnight/example_automation_scripts/examples/Functions.bat @@ -92,7 +92,7 @@ goto:EOF echo "=== Launching Throughput %EXAMPLE_LANG% " start CMD /C RUNPUB.bat %SLEEP2% >NUL - start "" /B java -classpath "classes;%OSPL_HOME%/jar/dcpssaj5.jar" subscriber 10 > subResult.txt 2>&1 + start "" /B java -jar sub/java5_Throughput_sub.jar 10 > subResult.txt 2>&1 set SUB_RESULT=%errorlevel% %SLEEP15% >NUL set /p PUB_RESULT=NUL - start "" /B java -classpath "classes;%OSPL_HOME%/jar/dcpssaj5.jar" ping 100 0 10 > pingResult.txt 2>&1 + start "" /B java -jar ping/java5_ping.jar 100 0 10 > pingResult.txt 2>&1 set PUB_RESULT=%errorlevel% %SLEEP15% >NUL - start "" /B java -classpath "classes;%OSPL_HOME%/jar/dcpssaj5.jar" ping quit >NUL + start "" /B java -jar pong/java5_pong.jar quit >NUL %SLEEP5% >NUL set /p SUB_RESULT= subResult.txt & +cmd_pid=$! sleep 1 echo === Waiting for processes to terminate -waitForProcessTermination sac_builtintopics_sub 30 +waitForProcessTermination $cmd_pid 30 builtintopicsCheckResult diff --git a/build/scripts/overnight/example_automation_scripts/examples/dcps/BuiltInTopics/cpp/standalone/RUN b/build/scripts/overnight/example_automation_scripts/examples/dcps/BuiltInTopics/cpp/standalone/RUN index ce4d9ee7c..aae7dc2c9 100755 --- a/build/scripts/overnight/example_automation_scripts/examples/dcps/BuiltInTopics/cpp/standalone/RUN +++ b/build/scripts/overnight/example_automation_scripts/examples/dcps/BuiltInTopics/cpp/standalone/RUN @@ -7,10 +7,11 @@ startOSPL echo "=== Launching BuiltInTopics " ./sacpp_builtintopics_sub > subResult.txt & +cmd_pid=$! sleep 1 echo === Waiting for processes to terminate -waitForProcessTermination sacpp_builtintopics_sub 30 +waitForProcessTermination $cmd_pid 30 builtintopicsCheckResult diff --git a/build/scripts/overnight/example_automation_scripts/examples/dcps/BuiltInTopics/isocpp/RUN b/build/scripts/overnight/example_automation_scripts/examples/dcps/BuiltInTopics/isocpp/RUN deleted file mode 100755 index 911b4d018..000000000 --- a/build/scripts/overnight/example_automation_scripts/examples/dcps/BuiltInTopics/isocpp/RUN +++ /dev/null @@ -1,19 +0,0 @@ -. $OSPL_HOME/examples/functions - -check_osplhome - -startOSPL - -echo "=== Launching BuiltInTopics " - -./subscriber > subResult.txt -sleep 1 - -echo === Waiting for processes to terminate -waitForProcessTermination subscriber 30 - -builtintopicsCheckResult - -sleep 5 - -stopOSPL diff --git a/build/scripts/overnight/example_automation_scripts/examples/dcps/BuiltInTopics/isocpp/RUN.bat b/build/scripts/overnight/example_automation_scripts/examples/dcps/BuiltInTopics/isocpp/RUN.bat deleted file mode 100755 index 59f6955b9..000000000 --- a/build/scripts/overnight/example_automation_scripts/examples/dcps/BuiltInTopics/isocpp/RUN.bat +++ /dev/null @@ -1,11 +0,0 @@ -@echo OFF -SETLOCAL - -echo "===== calling runBuiltInTopics for isocpp =====" - -set EXAMPLE_LANG=isocpp - -call %FUNCTIONS% :runBuiltInTopicsISOCPP - -call %FUNCTIONS% :builtintopicsCheckResult >> run.log - diff --git a/build/scripts/overnight/example_automation_scripts/examples/dcps/BuiltInTopics/isocpp2/RUN b/build/scripts/overnight/example_automation_scripts/examples/dcps/BuiltInTopics/isocpp2/RUN index 911b4d018..3c63fc666 100755 --- a/build/scripts/overnight/example_automation_scripts/examples/dcps/BuiltInTopics/isocpp2/RUN +++ b/build/scripts/overnight/example_automation_scripts/examples/dcps/BuiltInTopics/isocpp2/RUN @@ -6,11 +6,12 @@ startOSPL echo "=== Launching BuiltInTopics " -./subscriber > subResult.txt +./subscriber > subResult.txt & +cmd_pid=$! sleep 1 echo === Waiting for processes to terminate -waitForProcessTermination subscriber 30 +waitForProcessTermination $cmd_pid 30 builtintopicsCheckResult diff --git a/build/scripts/overnight/example_automation_scripts/examples/dcps/BuiltInTopics/java/standalone/RUN b/build/scripts/overnight/example_automation_scripts/examples/dcps/BuiltInTopics/java/standalone/RUN index 5caa55ff6..322a30cff 100755 --- a/build/scripts/overnight/example_automation_scripts/examples/dcps/BuiltInTopics/java/standalone/RUN +++ b/build/scripts/overnight/example_automation_scripts/examples/dcps/BuiltInTopics/java/standalone/RUN @@ -8,10 +8,10 @@ startOSPL echo "=== Launching BuiltInTopics" -LD_PRELOAD=$OSPL_JSIG $SPLICE_JAVA -classpath $OSPL_HOME/jar/dcpssaj.jar:classes:$SPLICE_EXTRA_CP BuildInTopicsDataSubscriber > subResult.txt +LD_PRELOAD=$OSPL_JSIG $SPLICE_JAVA -jar java_BuiltInTopics.jar > subResult.txt builtintopicsCheckResult sleep 5 -stopOSPL +stopOSPL \ No newline at end of file diff --git a/build/scripts/overnight/example_automation_scripts/examples/dcps/BuiltInTopics/java/standalone/RUN.bat b/build/scripts/overnight/example_automation_scripts/examples/dcps/BuiltInTopics/java/standalone/RUN.bat index 9281b0d96..06f1088a7 100755 --- a/build/scripts/overnight/example_automation_scripts/examples/dcps/BuiltInTopics/java/standalone/RUN.bat +++ b/build/scripts/overnight/example_automation_scripts/examples/dcps/BuiltInTopics/java/standalone/RUN.bat @@ -16,12 +16,12 @@ echo "==== Calling startOSPL ====" call %FUNCTIONS% :startOSPL echo "==== Starting java subscriber =====" -java -classpath "%OSPL_HOME%\jar\dcpssaj.jar";classes BuildInTopicsDataSubscriber > subResult.txt +java -jar java5_BuiltInTopics.jar > subResult.txt %SLEEP5% > NUL echo "===== Calling builtintopicsCheckResult ====" call %FUNCTIONS% :builtintopicsCheckResult >> run.log - + echo "===== calling stopOSPL ====" rem Don't kill it too soon. call %FUNCTIONS% :stopOSPL diff --git a/build/scripts/overnight/example_automation_scripts/examples/dcps/BuiltInTopics/java5/RUN b/build/scripts/overnight/example_automation_scripts/examples/dcps/BuiltInTopics/java5/RUN index aa4eb04b7..019f5fc3f 100755 --- a/build/scripts/overnight/example_automation_scripts/examples/dcps/BuiltInTopics/java5/RUN +++ b/build/scripts/overnight/example_automation_scripts/examples/dcps/BuiltInTopics/java5/RUN @@ -8,7 +8,7 @@ startOSPL echo "=== Launching BuiltInTopics" -LD_PRELOAD=$OSPL_JSIG $SPLICE_JAVA -classpath $OSPL_HOME/jar/dcpssaj5.jar:classes:$SPLICE_EXTRA_CP BuildInTopicsDataSubscriber > subResult.txt +LD_PRELOAD=$OSPL_JSIG $SPLICE_JAVA -jar java5_BuiltInTopics.jar > subResult.txt builtintopicsCheckResult diff --git a/build/scripts/overnight/example_automation_scripts/examples/dcps/BuiltInTopics/java5/RUN.bat b/build/scripts/overnight/example_automation_scripts/examples/dcps/BuiltInTopics/java5/RUN.bat index 399d78680..bfaf37e5a 100755 --- a/build/scripts/overnight/example_automation_scripts/examples/dcps/BuiltInTopics/java5/RUN.bat +++ b/build/scripts/overnight/example_automation_scripts/examples/dcps/BuiltInTopics/java5/RUN.bat @@ -11,7 +11,7 @@ echo "==== Calling startOSPL ====" call %FUNCTIONS% :startOSPL echo "==== Starting java subscriber =====" -java -classpath "%OSPL_HOME%\jar\dcpssaj5.jar";classes BuildInTopicsDataSubscriber > subResult.txt +java -jar java5_BuiltInTopics.jar > subResult.txt %SLEEP5% > NUL echo "===== Calling builtintopicsCheckResult ====" diff --git a/build/scripts/overnight/example_automation_scripts/examples/dcps/ContentFilteredTopic/c/standalone/RUN b/build/scripts/overnight/example_automation_scripts/examples/dcps/ContentFilteredTopic/c/standalone/RUN index b5958f545..dbf9366d7 100755 --- a/build/scripts/overnight/example_automation_scripts/examples/dcps/ContentFilteredTopic/c/standalone/RUN +++ b/build/scripts/overnight/example_automation_scripts/examples/dcps/ContentFilteredTopic/c/standalone/RUN @@ -7,14 +7,13 @@ startOSPL echo "=== Launching ContentFilteredTopic " ./sac_contentfilteredtopic_sub GE > subResult.txt & - +cmd_pid=$! sleep 2 ./sac_contentfilteredtopic_pub > pubResult.txt echo === Waiting for processes to terminate -waitForProcessTermination sac_contentfilteredtopic_pub 40 -waitForProcessTermination sac_contentfilteredtopic_sub 40 +waitForProcessTermination $cmd_pid 40 contentfilteredtopicCheckResult diff --git a/build/scripts/overnight/example_automation_scripts/examples/dcps/ContentFilteredTopic/cpp/standalone/RUN b/build/scripts/overnight/example_automation_scripts/examples/dcps/ContentFilteredTopic/cpp/standalone/RUN index 57114bd50..0056137d8 100755 --- a/build/scripts/overnight/example_automation_scripts/examples/dcps/ContentFilteredTopic/cpp/standalone/RUN +++ b/build/scripts/overnight/example_automation_scripts/examples/dcps/ContentFilteredTopic/cpp/standalone/RUN @@ -7,14 +7,13 @@ startOSPL echo "=== Launching ContentFilteredTopic " ./sacpp_contentfilteredtopic_sub GE > subResult.txt & - +cmd_pid=$! sleep 2 ./sacpp_contentfilteredtopic_pub > pubResult.txt echo === Waiting for processes to terminate -waitForProcessTermination sacpp_contentfilteredtopic_pub 40 -waitForProcessTermination sacpp_contentfilteredtopic_sub 40 +waitForProcessTermination $cmd_pid 40 contentfilteredtopicCheckResult diff --git a/build/scripts/overnight/example_automation_scripts/examples/dcps/ContentFilteredTopic/isocpp/RUN b/build/scripts/overnight/example_automation_scripts/examples/dcps/ContentFilteredTopic/isocpp/RUN deleted file mode 100755 index 19711ff0f..000000000 --- a/build/scripts/overnight/example_automation_scripts/examples/dcps/ContentFilteredTopic/isocpp/RUN +++ /dev/null @@ -1,15 +0,0 @@ -. $OSPL_HOME/examples/functions - -check_osplhome - -NAME=ContentFilteredTopic -SUB_PARAMS=GE -PUB_PARAMS= - -startOSPL - -runZero $NAME $SUB_PARAMS $PUB_PARAMS - -checkResultZero $SUB_RESULT $PUB_RESULT $NAME - -stopOSPL diff --git a/build/scripts/overnight/example_automation_scripts/examples/dcps/ContentFilteredTopic/isocpp/RUN.bat b/build/scripts/overnight/example_automation_scripts/examples/dcps/ContentFilteredTopic/isocpp/RUN.bat deleted file mode 100755 index a0a750fe5..000000000 --- a/build/scripts/overnight/example_automation_scripts/examples/dcps/ContentFilteredTopic/isocpp/RUN.bat +++ /dev/null @@ -1,11 +0,0 @@ -@echo OFF -SETLOCAL - -set EXAMPLE_LANG=isocpp -set NAME=ContentFilteredTopic -set SUB_PARAMS=GE -set PUB_PARAMS= - -call %FUNCTIONS% :runZero - -call %FUNCTIONS% :checkResultZero diff --git a/build/scripts/overnight/example_automation_scripts/examples/dcps/ContentFilteredTopic/isocpp/RUNSUB.bat b/build/scripts/overnight/example_automation_scripts/examples/dcps/ContentFilteredTopic/isocpp/RUNSUB.bat deleted file mode 100755 index 012c1a2ab..000000000 --- a/build/scripts/overnight/example_automation_scripts/examples/dcps/ContentFilteredTopic/isocpp/RUNSUB.bat +++ /dev/null @@ -1,2 +0,0 @@ -call subscriber.exe %SUB_PARAMS% > subResult.txt 2>&1 -echo %errorlevel% > subReturn.txt 2>&1 diff --git a/build/scripts/overnight/example_automation_scripts/examples/dcps/ContentFilteredTopic/java5/RUN b/build/scripts/overnight/example_automation_scripts/examples/dcps/ContentFilteredTopic/java5/RUN index 9670318eb..76097af4a 100755 --- a/build/scripts/overnight/example_automation_scripts/examples/dcps/ContentFilteredTopic/java5/RUN +++ b/build/scripts/overnight/example_automation_scripts/examples/dcps/ContentFilteredTopic/java5/RUN @@ -8,11 +8,11 @@ startOSPL echo "=== Launching ContentFilteredTopic " -LD_PRELOAD=$OSPL_JSIG $SPLICE_JAVA -classpath $OSPL_HOME/jar/dcpssaj5.jar:classes:$SPLICE_EXTRA_CP ContentFilteredTopicDataSubscriber GE > subResult.txt & +LD_PRELOAD=$OSPL_JSIG $SPLICE_JAVA -jar sub/java5_ContentFilteredTopic_sub.jar GE > subResult.txt & sleep 2 -LD_PRELOAD=$OSPL_JSIG $SPLICE_JAVA -classpath $OSPL_HOME/jar/dcpssaj5.jar:classes:$SPLICE_EXTRA_CP ContentFilteredTopicDataPublisher +LD_PRELOAD=$OSPL_JSIG $SPLICE_JAVA -jar pub/java5_ContentFilteredTopic_pub.jar sleep 5 diff --git a/build/scripts/overnight/example_automation_scripts/examples/dcps/ContentFilteredTopic/java5/RUN.bat b/build/scripts/overnight/example_automation_scripts/examples/dcps/ContentFilteredTopic/java5/RUN.bat index bc54c7ce0..66fa665ae 100755 --- a/build/scripts/overnight/example_automation_scripts/examples/dcps/ContentFilteredTopic/java5/RUN.bat +++ b/build/scripts/overnight/example_automation_scripts/examples/dcps/ContentFilteredTopic/java5/RUN.bat @@ -12,11 +12,11 @@ call %FUNCTIONS% :startOSPL echo "=== Launching ContentFilteredTopic " -start "" /B java -classpath "%OSPL_HOME%\jar\dcpssaj5.jar";classes ContentFilteredTopicDataSubscriber GE > subResult.txt +start "" /B java -jar sub/java5_ContentFilteredTopic_sub.jar GE > subResult.txt %SLEEP5% >NUL -java -classpath "%OSPL_HOME%\jar\dcpssaj5.jar";classes ContentFilteredTopicDataPublisher > pubResult.txt +java -jar pub/java5_ContentFilteredTopic_pub.jar > pubResult.txt %SLEEP5% > NUL diff --git a/build/scripts/overnight/example_automation_scripts/examples/dcps/Durability/c/standalone/RUN b/build/scripts/overnight/example_automation_scripts/examples/dcps/Durability/c/standalone/RUN index e197388ca..0d529194e 100755 --- a/build/scripts/overnight/example_automation_scripts/examples/dcps/Durability/c/standalone/RUN +++ b/build/scripts/overnight/example_automation_scripts/examples/dcps/Durability/c/standalone/RUN @@ -17,16 +17,18 @@ echo "=============================" echo " ===== Launching durability subscriber" ./sac_durability_sub transient > subResult_3_1.txt & - +sub_pid=$! sleep 5 echo " ===== Launching durability publisher" ./sac_durability_pub transient true true > pubResult_3_1.txt & +pub_pid=$! #Rather than kill the publisher just wait till it completes. echo "===== Wait to let the publisher complete " -waitForProcessTermination sac_durability_pub 40 +waitForProcessTermination $sub_pid 20 +waitForProcessTermination $pub_pid 40 echo "=== Scenario 3.1 done" @@ -40,6 +42,7 @@ startOSPL echo === running a first Subscriber ./sac_durability_sub transient > subResult_3_2_1.txt & +sub1_pid=$! echo "=== End of first DurabilityDataSubscriber (Scenario 3.2)" sleep 5 @@ -47,16 +50,20 @@ sleep 5 echo " ===== Launching durability publisher" ./sac_durability_pub transient false true > pubResult_3_2.txt & +pub_pid=$! sleep 5 echo === running a second Subscriber ./sac_durability_sub transient > subResult_3_2_2.txt & +sub2_pid=$! echo "=== End of second DurabilityDataSubscriber (Scenario 3.2)" #Rather than kill the publisher just wait till it completes. echo "===== Wait to let the publisher complete " -waitForProcessTermination sac_durability_pub 40 +waitForProcessTermination $sub1_pid 20 +waitForProcessTermination $sub2_pid 20 +waitForProcessTermination $pub_pid 40 echo "=============================" echo "==== Scenario 3.3 ======" @@ -68,6 +75,7 @@ startOSPL echo === running a first Subscriber ./sac_durability_sub persistent > subResult_3_3_1.txt & +sub_pid=$! echo "=== End of first DurabilityDataSubscriber (Scenario 3.3)" sleep 5 @@ -75,10 +83,12 @@ sleep 5 echo " ===== Launching durability publisher" ./sac_durability_pub persistent false true > pubResult_3_3.txt & +pub_pid=$! #Rather than kill the publisher just wait till it completes. echo "===== Wait to let the publisher complete " -waitForProcessTermination sac_durability_pub 40 +waitForProcessTermination $sub_pid 20 +waitForProcessTermination $pub_pid 40 stopOSPL @@ -88,11 +98,11 @@ sleep 15 echo === running a second Subscriber ./sac_durability_sub persistent > subResult_3_3_2.txt & +sub_pid=$! echo "=== End of second DurabilityDataSubscriber (Scenario 3.3)" echo "=== Waiting for processes to terminate" -waitForProcessTermination sac_durability_pub 40 -waitForProcessTermination sac_durability_sub 40 +waitForProcessTermination $sub_pid 20 durabilityCheckResult diff --git a/build/scripts/overnight/example_automation_scripts/examples/dcps/Durability/cpp/standalone/RUN b/build/scripts/overnight/example_automation_scripts/examples/dcps/Durability/cpp/standalone/RUN index 1dc00cbc1..618979a00 100755 --- a/build/scripts/overnight/example_automation_scripts/examples/dcps/Durability/cpp/standalone/RUN +++ b/build/scripts/overnight/example_automation_scripts/examples/dcps/Durability/cpp/standalone/RUN @@ -17,16 +17,18 @@ echo "=============================" echo " ===== Launching durability subscriber" ./sacpp_durability_sub transient > subResult_3_1.txt & - +sub_pid=$! sleep 5 echo " ===== Launching durability publisher" ./sacpp_durability_pub transient true true > pubResult_3_1.txt & +pub_pid=$! #Rather than kill the publisher just wait till it completes. echo "===== Wait to let the publisher complete " -waitForProcessTermination sacpp_durability_pub 40 +waitForProcessTermination $sub_pid 20 +waitForProcessTermination $pub_pid 40 echo "=== Scenario 3.1 done" @@ -40,6 +42,7 @@ startOSPL echo === running a first Subscriber ./sacpp_durability_sub transient > subResult_3_2_1.txt & +sub1_pid=$! echo "=== End of first DurabilityDataSubscriber (Scenario 3.2)" sleep 5 @@ -47,16 +50,20 @@ sleep 5 echo " ===== Launching durability publisher" ./sacpp_durability_pub transient false true > pubResult_3_2.txt & +pub_pid=$! sleep 5 echo === running a second Subscriber ./sacpp_durability_sub transient > subResult_3_2_2.txt & +sub2_pid=$! echo "=== End of second DurabilityDataSubscriber (Scenario 3.2)" #Rather than kill the publisher just wait till it completes. echo "===== Wait to let the publisher complete " -waitForProcessTermination sacpp_durability_pub 40 +waitForProcessTermination $sub1_pid 20 +waitForProcessTermination $sub2_pid 20 +waitForProcessTermination $pub_pid 40 echo "=============================" echo "==== Scenario 3.3 ======" @@ -68,6 +75,7 @@ startOSPL echo === running a first Subscriber ./sacpp_durability_sub persistent > subResult_3_3_1.txt & +sub_pid=$! echo "=== End of first DurabilityDataSubscriber (Scenario 3.3)" sleep 5 @@ -75,10 +83,12 @@ sleep 5 echo " ===== Launching durability publisher" ./sacpp_durability_pub persistent false true > pubResult_3_3.txt & +pub_pid=$! #Rather than kill the publisher just wait till it completes. echo "===== Wait to let the publisher complete " -waitForProcessTermination sacpp_durability_pub 40 +waitForProcessTermination $sub_pid 20 +waitForProcessTermination $pub_pid 40 stopOSPL @@ -88,11 +98,13 @@ sleep 15 echo === running a second Subscriber ./sacpp_durability_sub persistent > subResult_3_3_2.txt & +sub_pid=$! +cmd_pid=$! + echo "=== End of second DurabilityDataSubscriber (Scenario 3.3)" echo "=== Waiting for processes to terminate" -waitForProcessTermination sacpp_durability_pub 40 -waitForProcessTermination sacpp_durability_sub 40 +waitForProcessTermination $sub_pid 20 durabilityCheckResult diff --git a/build/scripts/overnight/example_automation_scripts/examples/dcps/Durability/isocpp/RUN b/build/scripts/overnight/example_automation_scripts/examples/dcps/Durability/isocpp/RUN deleted file mode 100755 index ca8e2cd38..000000000 --- a/build/scripts/overnight/example_automation_scripts/examples/dcps/Durability/isocpp/RUN +++ /dev/null @@ -1,98 +0,0 @@ -. $OSPL_HOME/examples/functions - -rm -rf ./tmp/pstore/* -rm -f *.txt - -durabilitySetOSPLURI - -check_osplhome - -stopOSPL - -startOSPL - -echo "=============================" -echo "==== Scenario 3.1 ======" -echo "=============================" -echo " ===== Launching durability subscriber" - -./subscriber transient > subResult_3_1.txt & - -sleep 8 - -echo " ===== Launching durability publisher" - -./publisher transient true true > pubResult_3_1.txt & - -#Rather than kill the publisher just wait till it completes. -echo "===== Wait to let the publisher complete " -waitForProcessTermination publisher 40 - -echo "=== Scenario 3.1 done" - -echo "=============================" -echo "==== Scenario 3.2 ======" -echo "=============================" - -stopOSPL - -startOSPL - -echo === running a first Subscriber -./subscriber transient > subResult_3_2_1.txt & -echo "=== End of first DurabilityDataSubscriber (Scenario 3.2)" - -sleep 8 - -echo " ===== Launching durability publisher" - -./publisher transient false true > pubResult_3_2.txt & - -sleep 8 - -echo === running a second Subscriber -./subscriber transient > subResult_3_2_2.txt & -echo "=== End of second DurabilityDataSubscriber (Scenario 3.2)" - -#Rather than kill the publisher just wait till it completes. -echo "===== Wait to let the publisher complete " -waitForProcessTermination publisher 40 - -echo "=============================" -echo "==== Scenario 3.3 ======" -echo "=============================" - -stopOSPL - -startOSPL - -echo === running a first Subscriber -./subscriber persistent > subResult_3_3_1.txt & -echo "=== End of first DurabilityDataSubscriber (Scenario 3.3)" - -sleep 8 - -echo " ===== Launching durability publisher" - -./publisher persistent false true > pubResult_3_3.txt & - -#Rather than kill the publisher just wait till it completes. -echo "===== Wait to let the publisher complete " -waitForProcessTermination publisher 40 - -stopOSPL - -startOSPL - -sleep 20 - -echo === running a second Subscriber -./subscriber persistent > subResult_3_3_2.txt & -echo "=== End of second DurabilityDataSubscriber (Scenario 3.3)" - -sleep 25 - -durabilityCheckResultISOCPP - -stopOSPL - diff --git a/build/scripts/overnight/example_automation_scripts/examples/dcps/Durability/isocpp/RUN.bat b/build/scripts/overnight/example_automation_scripts/examples/dcps/Durability/isocpp/RUN.bat deleted file mode 100755 index 3823b68d6..000000000 --- a/build/scripts/overnight/example_automation_scripts/examples/dcps/Durability/isocpp/RUN.bat +++ /dev/null @@ -1,14 +0,0 @@ -@echo OFF -IF EXIST C:\tmp\pstore rmdir /S /Q C:\tmp\pstore -IF EXIST .\tmp\pstore rmdir /S /Q .\tmp\pstore - -del /F /Q *.txt - -set EXAMPLE_LANG=isocpp - -echo "===== calling runDurability with isocpp =====" - -call %FUNCTIONS% :runDurabilityInit -call %FUNCTIONS% :runDurabilityISOCPP -call %FUNCTIONS% :durabilityCheckResultsISOCPP >> run.log - diff --git a/build/scripts/overnight/example_automation_scripts/examples/dcps/Durability/isocpp2/RUN b/build/scripts/overnight/example_automation_scripts/examples/dcps/Durability/isocpp2/RUN index 7e9f66452..073ed0c5c 100755 --- a/build/scripts/overnight/example_automation_scripts/examples/dcps/Durability/isocpp2/RUN +++ b/build/scripts/overnight/example_automation_scripts/examples/dcps/Durability/isocpp2/RUN @@ -17,16 +17,19 @@ echo "=============================" echo " ===== Launching durability subscriber" ./subscriber transient > subResult_3_1.txt & +sub_pid=$! sleep 5 echo " ===== Launching durability publisher" ./publisher transient true true > pubResult_3_1.txt & +pub_pid=$! #Rather than kill the publisher just wait till it completes. echo "===== Wait to let the publisher complete " -waitForProcessTermination publisher 40 +waitForProcessTermination $sub_pid 20 +waitForProcessTermination $pub_pid 40 echo "=== Scenario 3.1 done" @@ -40,6 +43,7 @@ startOSPL echo === running a first Subscriber ./subscriber transient > subResult_3_2_1.txt & +sub1_pid=$! echo "=== End of first DurabilityDataSubscriber (Scenario 3.2)" sleep 5 @@ -47,16 +51,20 @@ sleep 5 echo " ===== Launching durability publisher" ./publisher transient false true > pubResult_3_2.txt & +pub_pid=$! sleep 5 echo === running a second Subscriber ./subscriber transient > subResult_3_2_2.txt & +sub2_pid=$! echo "=== End of second DurabilityDataSubscriber (Scenario 3.2)" #Rather than kill the publisher just wait till it completes. echo "===== Wait to let the publisher complete " -waitForProcessTermination publisher 40 +waitForProcessTermination $sub1_pid 20 +waitForProcessTermination $sub2_pid 20 +waitForProcessTermination $pub_pid 40 echo "=============================" echo "==== Scenario 3.3 ======" @@ -68,6 +76,7 @@ startOSPL echo === running a first Subscriber ./subscriber persistent > subResult_3_3_1.txt & +sub_pid=$! echo "=== End of first DurabilityDataSubscriber (Scenario 3.3)" sleep 5 @@ -75,10 +84,12 @@ sleep 5 echo " ===== Launching durability publisher" ./publisher persistent false true > pubResult_3_3.txt & +pub_pid=$! #Rather than kill the publisher just wait till it completes. echo "===== Wait to let the publisher complete " -waitForProcessTermination publisher 40 +waitForProcessTermination $sub_pid 20 +waitForProcessTermination $pub_pid 40 stopOSPL @@ -88,10 +99,13 @@ sleep 15 echo === running a second Subscriber ./subscriber persistent > subResult_3_3_2.txt & +sub_pid=$! echo "=== End of second DurabilityDataSubscriber (Scenario 3.3)" sleep 20 +waitForProcessTermination $sub_pid 20 + durabilityCheckResultISOCPP stopOSPL diff --git a/build/scripts/overnight/example_automation_scripts/examples/dcps/Durability/java5/RUN b/build/scripts/overnight/example_automation_scripts/examples/dcps/Durability/java5/RUN index 4a7c9e937..f6870706a 100755 --- a/build/scripts/overnight/example_automation_scripts/examples/dcps/Durability/java5/RUN +++ b/build/scripts/overnight/example_automation_scripts/examples/dcps/Durability/java5/RUN @@ -53,13 +53,13 @@ echo "==== Scenario 3.1 ======" echo "=============================" echo " ===== Launching durability subscriber" -LD_PRELOAD=$OSPL_JSIG $SPLICE_JAVA -classpath $OSPL_HOME/jar/dcpssaj5.jar:classes:$SPLICE_EXTRA_CP DurabilityDataSubscriber transient > subResult_3_1.txt & +LD_PRELOAD=$OSPL_JSIG $SPLICE_JAVA -jar sub/java5_Durability_sub.jar transient > subResult_3_1.txt & sleep 5 echo " ===== Launching durability publisher" -LD_PRELOAD=$OSPL_JSIG $SPLICE_JAVA -classpath $OSPL_HOME/jar/dcpssaj5.jar:classes:$SPLICE_EXTRA_CP DurabilityDataPublisher transient true true > pubResult_3_1.txt & +LD_PRELOAD=$OSPL_JSIG $SPLICE_JAVA -jar pub/java5_Durability_pub.jar transient true true > pubResult_3_1.txt & #Rather than kill the publisher just wait till it completes. echo "===== Sleep 30s to let the publisher complete " @@ -93,19 +93,19 @@ then fi echo === running a first Subscriber -LD_PRELOAD=$OSPL_JSIG $SPLICE_JAVA -classpath $OSPL_HOME/jar/dcpssaj5.jar:classes:$SPLICE_EXTRA_CP DurabilityDataSubscriber transient > subResult_3_2_1.txt & +LD_PRELOAD=$OSPL_JSIG $SPLICE_JAVA -jar sub/java5_Durability_sub.jar transient > subResult_3_2_1.txt & echo "=== End of first DurabilityDataSubscriber (Scenario 3.2)" sleep 5 echo " ===== Launching durability publisher" -LD_PRELOAD=$OSPL_JSIG $SPLICE_JAVA -classpath $OSPL_HOME/jar/dcpssaj5.jar:classes:$SPLICE_EXTRA_CP DurabilityDataPublisher transient false true > pubResult_3_2.txt & +LD_PRELOAD=$OSPL_JSIG $SPLICE_JAVA -jar pub/java5_Durability_pub.jar transient false true > pubResult_3_2.txt & sleep 5 echo === running a second Subscriber -LD_PRELOAD=$OSPL_JSIG $SPLICE_JAVA -classpath $OSPL_HOME/jar/dcpssaj5.jar:classes:$SPLICE_EXTRA_CP DurabilityDataSubscriber transient > subResult_3_2_2.txt & +LD_PRELOAD=$OSPL_JSIG $SPLICE_JAVA -jar sub/java5_Durability_sub.jar transient > subResult_3_2_2.txt & echo "=== End of second DurabilityDataSubscriber (Scenario 3.2)" #Rather than kill the publisher just wait till it completes. @@ -139,14 +139,14 @@ then fi echo === running a first Subscriber -LD_PRELOAD=$OSPL_JSIG $SPLICE_JAVA -classpath $OSPL_HOME/jar/dcpssaj5.jar:classes:$SPLICE_EXTRA_CP DurabilityDataSubscriber persistent > subResult_3_3_1.txt & +LD_PRELOAD=$OSPL_JSIG $SPLICE_JAVA -jar sub/java5_Durability_sub.jar persistent > subResult_3_3_1.txt & echo "=== End of first DurabilityDataSubscriber (Scenario 3.3)" sleep 5 echo " ===== Launching durability publisher" -LD_PRELOAD=$OSPL_JSIG $SPLICE_JAVA -classpath $OSPL_HOME/jar/dcpssaj5.jar:classes:$SPLICE_EXTRA_CP DurabilityDataPublisher persistent false true > pubResult_3_3.txt & +LD_PRELOAD=$OSPL_JSIG $SPLICE_JAVA -jar pub/java5_Durability_pub.jar persistent false true > pubResult_3_3.txt & #Rather than kill the publisher just wait till it completes. echo "===== Sleep 30s to let the publisher complete " @@ -164,7 +164,7 @@ then fi echo === running a second Subscriber -LD_PRELOAD=$OSPL_JSIG $SPLICE_JAVA -classpath $OSPL_HOME/jar/dcpssaj5.jar:classes:$SPLICE_EXTRA_CP DurabilityDataSubscriber persistent > subResult_3_3_2.txt & +LD_PRELOAD=$OSPL_JSIG $SPLICE_JAVA -jar sub/java5_Durability_sub.jar persistent > subResult_3_3_2.txt & echo "=== End of first DurabilityDataSubscriber (Scenario 3.3)" sleep 20 diff --git a/build/scripts/overnight/example_automation_scripts/examples/dcps/Durability/java5/RUN.bat b/build/scripts/overnight/example_automation_scripts/examples/dcps/Durability/java5/RUN.bat index 8a31efa27..0490f2a61 100755 --- a/build/scripts/overnight/example_automation_scripts/examples/dcps/Durability/java5/RUN.bat +++ b/build/scripts/overnight/example_automation_scripts/examples/dcps/Durability/java5/RUN.bat @@ -7,12 +7,12 @@ call %FUNCTIONS% :runDurabilityInit echo "=== Launching Durability " echo "=== Scenario 3.1" echo "=== running the Subscriber" -start "DurabilityExample" /B java -classpath "%OSPL_HOME%\jar\dcpssaj5.jar;classes" DurabilityDataSubscriber transient > subResult_3_1.txt +start "DurabilityExample" /B java -jar sub/java5_Durability_sub.jar transient > subResult_3_1.txt %SLEEP5% > NUL echo "=== running the Publisher" -start "" /B java -classpath "%OSPL_HOME%\jar\dcpssaj5.jar;classes" DurabilityDataPublisher transient true true > pubResult_3_1.txt +start "" /B java -jar pub/java5_Durability_pub.jar transient true true > pubResult_3_1.txt REM Wait 30s to allow the publisher to complete and terminate rather than kill it %SLEEP30% > NUL @@ -25,17 +25,17 @@ call %FUNCTIONS% :startOSPL echo "=== Scenario 3.2" echo "=== running a first Subscriber" -start "" /B java -classpath "%OSPL_HOME%\jar\dcpssaj5.jar;classes" DurabilityDataSubscriber transient > subResult_3_2_1.txt +start "" /B java -jar sub/java5_Durability_sub.jar transient > subResult_3_2_1.txt %SLEEP2% >NUL echo "=== running the Publisher" -start "" /B java -classpath "%OSPL_HOME%\jar\dcpssaj5.jar;classes" DurabilityDataPublisher transient false true > pubResult_3_2.txt +start "" /B java -jar pub/java5_Durability_pub.jar transient false true > pubResult_3_2.txt %SLEEP5% >NUL echo "=== running a second Subscriber" -start "" /B java -classpath "%OSPL_HOME%\jar\dcpssaj5.jar;classes" DurabilityDataSubscriber transient > subResult_3_2_2.txt +start "" /B java -jar sub/java5_Durability_sub.jar transient > subResult_3_2_2.txt REM Wait 30s to allow the publisher to complete and terminate rather than kill it %SLEEP30% >NUL @@ -48,11 +48,11 @@ call %FUNCTIONS% :stopOSPL call %FUNCTIONS% :startOSPL echo "=== running a first Subscriber" -start "" /B java -classpath "%OSPL_HOME%\jar\dcpssaj5.jar;classes" DurabilityDataSubscriber persistent > subResult_3_3_1.txt +start "" /B java -jar sub/java5_Durability_sub.jar persistent > subResult_3_3_1.txt %SLEEP2% >NUL echo "=== running the Publisher" -start "" /B java -classpath "%OSPL_HOME%\jar\dcpssaj5.jar;classes" DurabilityDataPublisher persistent false true > pubResult_3_3.txt +start "" /B java -jar pub/java5_Durability_pub.jar persistent false true > pubResult_3_3.txt REM Wait 30s to allow the publisher to complete and terminate rather than kill it %SLEEP30% >NUL @@ -62,7 +62,7 @@ call %FUNCTIONS% :stopOSPL call %FUNCTIONS% :startOSPL echo "=== running a second Subscriber after stop/start of OpenSplice" -start "" /B java -classpath "%OSPL_HOME%\jar\dcpssaj5.jar;classes" DurabilityDataSubscriber persistent > subResult_3_3_2.txt +start "" /B java -jar sub/java5_Durability_sub.jar persistent > subResult_3_3_2.txt %SLEEP10% >NUL diff --git a/build/scripts/overnight/example_automation_scripts/examples/dcps/HelloWorld/c/standalone/RUN b/build/scripts/overnight/example_automation_scripts/examples/dcps/HelloWorld/c/standalone/RUN index 3e5ce2922..2c3fa7bed 100755 --- a/build/scripts/overnight/example_automation_scripts/examples/dcps/HelloWorld/c/standalone/RUN +++ b/build/scripts/overnight/example_automation_scripts/examples/dcps/HelloWorld/c/standalone/RUN @@ -6,14 +6,14 @@ startOSPL echo "=== Launching HelloWorld " ./sac_helloworld_sub > subResult.txt& +cmd_pid=$! sleep 5 ./sac_helloworld_pub > pubResult.txt echo "=== Waiting for processes to terminate" -waitForProcessTermination sac_helloworld_pub 30 -waitForProcessTermination sac_helloworld_sub 30 +waitForProcessTermination $cmd_pid 30 helloworldCheckResult diff --git a/build/scripts/overnight/example_automation_scripts/examples/dcps/HelloWorld/cpp/corba/RUN b/build/scripts/overnight/example_automation_scripts/examples/dcps/HelloWorld/cpp/corba/RUN index 3e03d12f5..2a2aa0c1c 100755 --- a/build/scripts/overnight/example_automation_scripts/examples/dcps/HelloWorld/cpp/corba/RUN +++ b/build/scripts/overnight/example_automation_scripts/examples/dcps/HelloWorld/cpp/corba/RUN @@ -6,13 +6,13 @@ startOSPL echo "=== Launching HelloWorld " ./HelloWorldDataSubscriber > subResult.txt& +cmd_pid=$! sleep 5 ./HelloWorldDataPublisher > pubResult.txt echo "=== Waiting for processes to terminate" -waitForProcessTermination HelloWorldDataPublisher 30 -waitForProcessTermination HelloWorldDataSubscriber 30 +waitForProcessTermination $cmd_pid 30 helloworldCheckResult diff --git a/build/scripts/overnight/example_automation_scripts/examples/dcps/HelloWorld/cpp/standalone/RUN b/build/scripts/overnight/example_automation_scripts/examples/dcps/HelloWorld/cpp/standalone/RUN index 1730084da..71092eed9 100755 --- a/build/scripts/overnight/example_automation_scripts/examples/dcps/HelloWorld/cpp/standalone/RUN +++ b/build/scripts/overnight/example_automation_scripts/examples/dcps/HelloWorld/cpp/standalone/RUN @@ -7,14 +7,14 @@ startOSPL echo "=== Launching HelloWorld " ./sacpp_helloworld_sub > subResult.txt & +cmd_pid=$! sleep 5 ./sacpp_helloworld_pub > pubResult.txt echo "=== Waiting for processes to terminate" -waitForProcessTermination sacpp_helloworld_pub 30 -waitForProcessTermination sacpp_helloworld_sub 30 +waitForProcessTermination $cmd_pid 30 helloworldCheckResult diff --git a/build/scripts/overnight/example_automation_scripts/examples/dcps/HelloWorld/isocpp/RUN b/build/scripts/overnight/example_automation_scripts/examples/dcps/HelloWorld/isocpp/RUN deleted file mode 100755 index b6547ba17..000000000 --- a/build/scripts/overnight/example_automation_scripts/examples/dcps/HelloWorld/isocpp/RUN +++ /dev/null @@ -1,15 +0,0 @@ -. $OSPL_HOME/examples/functions - -check_osplhome - -NAME=HelloWorld -SUB_PARAMS= -PUB_PARAMS= - -startOSPL - -runZero $NAME $SUB_PARAMS $PUB_PARAMS - -checkResultZero $SUB_RESULT $PUB_RESULT $NAME - -stopOSPL diff --git a/build/scripts/overnight/example_automation_scripts/examples/dcps/HelloWorld/isocpp/RUN.bat b/build/scripts/overnight/example_automation_scripts/examples/dcps/HelloWorld/isocpp/RUN.bat deleted file mode 100755 index df476bfc6..000000000 --- a/build/scripts/overnight/example_automation_scripts/examples/dcps/HelloWorld/isocpp/RUN.bat +++ /dev/null @@ -1,11 +0,0 @@ -@echo OFF -SETLOCAL - -set EXAMPLE_LANG=isocpp -set NAME=HelloWorld -set SUB_PARAMS= -set PUB_PARAMS= - -call %FUNCTIONS% :runZero - -call %FUNCTIONS% :checkResultZero diff --git a/build/scripts/overnight/example_automation_scripts/examples/dcps/HelloWorld/isocpp/RUNSUB.bat b/build/scripts/overnight/example_automation_scripts/examples/dcps/HelloWorld/isocpp/RUNSUB.bat deleted file mode 100755 index 012c1a2ab..000000000 --- a/build/scripts/overnight/example_automation_scripts/examples/dcps/HelloWorld/isocpp/RUNSUB.bat +++ /dev/null @@ -1,2 +0,0 @@ -call subscriber.exe %SUB_PARAMS% > subResult.txt 2>&1 -echo %errorlevel% > subReturn.txt 2>&1 diff --git a/build/scripts/overnight/example_automation_scripts/examples/dcps/HelloWorld/java5/RUN b/build/scripts/overnight/example_automation_scripts/examples/dcps/HelloWorld/java5/RUN index be6ffdd1e..fcb6a7c0a 100755 --- a/build/scripts/overnight/example_automation_scripts/examples/dcps/HelloWorld/java5/RUN +++ b/build/scripts/overnight/example_automation_scripts/examples/dcps/HelloWorld/java5/RUN @@ -7,12 +7,12 @@ get_libjsig startOSPL echo "=== Launching HelloWorld " -LD_PRELOAD=$OSPL_JSIG $SPLICE_JAVA -classpath $OSPL_HOME/jar/dcpssaj5.jar:classes:$SPLICE_EXTRA_CP HelloWorldDataSubscriber > subResult.txt& +LD_PRELOAD=$OSPL_JSIG $SPLICE_JAVA -jar sub/java5_HelloWorld_sub.jar > subResult.txt& cmd_pid=$! sleep 5 -LD_PRELOAD=$OSPL_JSIG $SPLICE_JAVA -classpath $OSPL_HOME/jar/dcpssaj5.jar:classes:$SPLICE_EXTRA_CP HelloWorldDataPublisher > pubResult.txt +LD_PRELOAD=$OSPL_JSIG $SPLICE_JAVA -jar pub/java5_HelloWorld_pub.jar > pubResult.txt PUB_RESULT=$? wait $cmd_pid &> /dev/null diff --git a/build/scripts/overnight/example_automation_scripts/examples/dcps/HelloWorld/java5/RUN.bat b/build/scripts/overnight/example_automation_scripts/examples/dcps/HelloWorld/java5/RUN.bat index 64c3fba34..88c1ecf10 100755 --- a/build/scripts/overnight/example_automation_scripts/examples/dcps/HelloWorld/java5/RUN.bat +++ b/build/scripts/overnight/example_automation_scripts/examples/dcps/HelloWorld/java5/RUN.bat @@ -17,7 +17,7 @@ start CMD /C RUNSUB.bat %SLEEP5% >NUL -java -classpath "%OSPL_HOME%\jar\dcpssaj5.jar";classes HelloWorldDataPublisher > pubResult.txt +java -jar pub/java5_HelloWorld_pub.jar > pubResult.txt set PUB_RESULT=%errorlevel% set /p SUB_RESULT= subResult.txt +start "" /B java -jar sub/java5_HelloWorld_sub.jar > subResult.txt echo %errorlevel% > subReturn.txt 2>&1 diff --git a/build/scripts/overnight/example_automation_scripts/examples/dcps/Lifecycle/c/standalone/RUN b/build/scripts/overnight/example_automation_scripts/examples/dcps/Lifecycle/c/standalone/RUN index 2c2f4ce7c..27da0dfd9 100755 --- a/build/scripts/overnight/example_automation_scripts/examples/dcps/Lifecycle/c/standalone/RUN +++ b/build/scripts/overnight/example_automation_scripts/examples/dcps/Lifecycle/c/standalone/RUN @@ -13,14 +13,13 @@ echo "=== Launching Lifecycle " echo "=== (step 1)" ./sac_lifecycle_sub > subResult_1.txt & +cmd_pid=$! + sleep 2 ./sac_lifecycle_pub false dispose > pubResult_1.txt echo "=== Waiting for processes to terminate" -waitForProcessTermination sac_lifecycle_pub 30 -waitForProcessTermination sac_lifecycle_sub 30 - - +waitForProcessTermination $cmd_pid 30 stopOSPL @@ -29,14 +28,13 @@ startOSPL echo "=== (step 2)" ./sac_lifecycle_sub > subResult_2.txt & +cmd_pid=$! + sleep 2 ./sac_lifecycle_pub false unregister > pubResult_2.txt echo "=== Waiting for processes to terminate" -waitForProcessTermination sac_lifecycle_pub 30 -waitForProcessTermination sac_lifecycle_sub 30 - - +waitForProcessTermination $cmd_pid 30 stopOSPL @@ -45,14 +43,13 @@ startOSPL echo "=== (step 3)" ./sac_lifecycle_sub > subResult_3.txt & +cmd_pid=$! + sleep 2 ./sac_lifecycle_pub false stoppub > pubResult_3.txt echo "=== Waiting for processes to terminate" -waitForProcessTermination sac_lifecycle_pub 30 -waitForProcessTermination sac_lifecycle_sub 30 - - +waitForProcessTermination $cmd_pid 30 lifecycleCheckResult diff --git a/build/scripts/overnight/example_automation_scripts/examples/dcps/Lifecycle/cpp/standalone/RUN b/build/scripts/overnight/example_automation_scripts/examples/dcps/Lifecycle/cpp/standalone/RUN index 12156f994..463ee1403 100755 --- a/build/scripts/overnight/example_automation_scripts/examples/dcps/Lifecycle/cpp/standalone/RUN +++ b/build/scripts/overnight/example_automation_scripts/examples/dcps/Lifecycle/cpp/standalone/RUN @@ -13,14 +13,12 @@ echo "=== Launching Lifecycle " echo "=== (step 1)" ./sacpp_lifecycle_sub > subResult_1.txt & +cmd_pid=$! sleep 2 ./sacpp_lifecycle_pub false dispose > pubResult_1.txt echo "=== Waiting for processes to terminate" -waitForProcessTermination sacpp_lifecycle_pub 30 -waitForProcessTermination sacpp_lifecycle_sub 30 - - +waitForProcessTermination $cmd_pid 30 stopOSPL @@ -29,14 +27,12 @@ startOSPL echo "=== (step 2)" ./sacpp_lifecycle_sub > subResult_2.txt & +cmd_pid=$! sleep 2 ./sacpp_lifecycle_pub false unregister > pubResult_2.txt echo "=== Waiting for processes to terminate" -waitForProcessTermination sacpp_lifecycle_pub 30 -waitForProcessTermination sacpp_lifecycle_sub 30 - - +waitForProcessTermination $cmd_pid 30 stopOSPL @@ -45,14 +41,12 @@ startOSPL echo "=== (step 3)" ./sacpp_lifecycle_sub > subResult_3.txt & +cmd_pid=$! sleep 2 ./sacpp_lifecycle_pub false stoppub > pubResult_3.txt echo "=== Waiting for processes to terminate" -waitForProcessTermination sacpp_lifecycle_pub 30 -waitForProcessTermination sacpp_lifecycle_sub 30 - - +waitForProcessTermination $cmd_pid 30 lifecycleCheckResult diff --git a/build/scripts/overnight/example_automation_scripts/examples/dcps/Lifecycle/isocpp/RUN b/build/scripts/overnight/example_automation_scripts/examples/dcps/Lifecycle/isocpp/RUN deleted file mode 100755 index cd5e4e9fd..000000000 --- a/build/scripts/overnight/example_automation_scripts/examples/dcps/Lifecycle/isocpp/RUN +++ /dev/null @@ -1,39 +0,0 @@ -. $OSPL_HOME/examples/functions - -check_osplhome - -stopOSPL - -startOSPL - -echo "=== Launching Lifecycle " - -echo "=== (step 1)" - -./subscriber > subResult_1.txt & -sleep 2 -./publisher false dispose > pubResult_1.txt - -stopOSPL - -startOSPL - -echo "=== (step 2)" - -./subscriber > subResult_2.txt & -sleep 2 -./publisher false unregister > pubResult_2.txt - -stopOSPL - -startOSPL - -echo "=== (step 3)" - -./subscriber > subResult_3.txt & -sleep 2 -./publisher false stoppub > pubResult_3.txt - -lifecycleCheckResult - -stopOSPL diff --git a/build/scripts/overnight/example_automation_scripts/examples/dcps/Lifecycle/isocpp/RUN.bat b/build/scripts/overnight/example_automation_scripts/examples/dcps/Lifecycle/isocpp/RUN.bat deleted file mode 100755 index a8b651587..000000000 --- a/build/scripts/overnight/example_automation_scripts/examples/dcps/Lifecycle/isocpp/RUN.bat +++ /dev/null @@ -1,11 +0,0 @@ - -@echo OFF -SETLOCAL - -echo "===== calling runLifecycle for isocpp =====" - -set EXAMPLE_LANG=isocpp - -call %FUNCTIONS% :runLifecycleISOCPP - -call %FUNCTIONS% :lifecycleCheckResults \ No newline at end of file diff --git a/build/scripts/overnight/example_automation_scripts/examples/dcps/Lifecycle/isocpp2/RUN b/build/scripts/overnight/example_automation_scripts/examples/dcps/Lifecycle/isocpp2/RUN index cd5e4e9fd..2d08592fd 100755 --- a/build/scripts/overnight/example_automation_scripts/examples/dcps/Lifecycle/isocpp2/RUN +++ b/build/scripts/overnight/example_automation_scripts/examples/dcps/Lifecycle/isocpp2/RUN @@ -11,9 +11,12 @@ echo "=== Launching Lifecycle " echo "=== (step 1)" ./subscriber > subResult_1.txt & +cmd_pid=$! sleep 2 ./publisher false dispose > pubResult_1.txt +waitForProcessTermination $cmd_pid 30 + stopOSPL startOSPL @@ -21,9 +24,12 @@ startOSPL echo "=== (step 2)" ./subscriber > subResult_2.txt & +cmd_pid=$! sleep 2 ./publisher false unregister > pubResult_2.txt +waitForProcessTermination $cmd_pid 30 + stopOSPL startOSPL @@ -31,9 +37,12 @@ startOSPL echo "=== (step 3)" ./subscriber > subResult_3.txt & +cmd_pid=$! sleep 2 ./publisher false stoppub > pubResult_3.txt +waitForProcessTermination $cmd_pid 30 + lifecycleCheckResult stopOSPL diff --git a/build/scripts/overnight/example_automation_scripts/examples/dcps/Lifecycle/java5/RUN b/build/scripts/overnight/example_automation_scripts/examples/dcps/Lifecycle/java5/RUN index ddf4a7de6..78f2d1d38 100755 --- a/build/scripts/overnight/example_automation_scripts/examples/dcps/Lifecycle/java5/RUN +++ b/build/scripts/overnight/example_automation_scripts/examples/dcps/Lifecycle/java5/RUN @@ -11,9 +11,9 @@ echo "=== Launching Lifecycle " echo "=== (step 1)" -LD_PRELOAD=$OSPL_JSIG $SPLICE_JAVA -classpath $OSPL_HOME/jar/dcpssaj5.jar:classes:$SPLICE_EXTRA_CP LifecycleDataSubscriber > subResult_1.txt & +LD_PRELOAD=$OSPL_JSIG $SPLICE_JAVA -jar sub/java5_Lifecycle_sub.jar > subResult_1.txt & -LD_PRELOAD=$OSPL_JSIG $SPLICE_JAVA -classpath $OSPL_HOME/jar/dcpssaj5.jar:classes:$SPLICE_EXTRA_CP LifecycleDataPublisher false dispose > pubResult_1.txt +LD_PRELOAD=$OSPL_JSIG $SPLICE_JAVA -jar pub/java5_Lifecycle_pub.jar false dispose > pubResult_1.txt stopOSPL startOSPL @@ -21,18 +21,18 @@ sleep 2 echo "=== (step 2)" -LD_PRELOAD=$OSPL_JSIG $SPLICE_JAVA -classpath $OSPL_HOME/jar/dcpssaj5.jar:classes:$SPLICE_EXTRA_CP LifecycleDataSubscriber > subResult_2.txt & +LD_PRELOAD=$OSPL_JSIG $SPLICE_JAVA -jar sub/java5_Lifecycle_sub.jar > subResult_2.txt & -LD_PRELOAD=$OSPL_JSIG $SPLICE_JAVA -classpath $OSPL_HOME/jar/dcpssaj5.jar:classes:$SPLICE_EXTRA_CP LifecycleDataPublisher false unregister > pubResult_2.txt +LD_PRELOAD=$OSPL_JSIG $SPLICE_JAVA -jar pub/java5_Lifecycle_pub.jar false unregister > pubResult_2.txt stopOSPL startOSPL sleep 2 echo "=== (step 3)" -LD_PRELOAD=$OSPL_JSIG $SPLICE_JAVA -classpath $OSPL_HOME/jar/dcpssaj5.jar:classes:$SPLICE_EXTRA_CP LifecycleDataSubscriber > subResult_3.txt & +LD_PRELOAD=$OSPL_JSIG $SPLICE_JAVA -jar sub/java5_Lifecycle_sub.jar > subResult_3.txt & -LD_PRELOAD=$OSPL_JSIG $SPLICE_JAVA -classpath $OSPL_HOME/jar/dcpssaj5.jar:classes:$SPLICE_EXTRA_CP LifecycleDataPublisher false stoppub > pubResult_3.txt +LD_PRELOAD=$OSPL_JSIG $SPLICE_JAVA -jar pub/java5_Lifecycle_pub.jar false stoppub > pubResult_3.txt lifecycleCheckResult diff --git a/build/scripts/overnight/example_automation_scripts/examples/dcps/Lifecycle/java5/RUN.bat b/build/scripts/overnight/example_automation_scripts/examples/dcps/Lifecycle/java5/RUN.bat index 0bbdec5c7..8c268a8a9 100755 --- a/build/scripts/overnight/example_automation_scripts/examples/dcps/Lifecycle/java5/RUN.bat +++ b/build/scripts/overnight/example_automation_scripts/examples/dcps/Lifecycle/java5/RUN.bat @@ -11,11 +11,11 @@ call %FUNCTIONS% :startOSPL echo "=== Launching Lifecycle " echo "=== (step 1)" -start "" /B java -classpath "%OSPL_HOME%\jar\dcpssaj.jar";classes LifecycleDataSubscriber > subResult_1.txt +start "" /B java -jar sub/java5_Lifecycle_sub.jar > subResult_1.txt %SLEEP2% > NUL -java -classpath "%OSPL_HOME%\jar\dcpssaj.jar";classes LifecycleDataPublisher false dispose > pubResult_1.txt +java -jar pub/java5_Lifecycle_pub.jar false dispose > pubResult_1.txt %SLEEP5% > NUL @@ -27,11 +27,11 @@ rem == step_2 == rem ======================================================= call %FUNCTIONS% :startOSPL -echo "=== (step 2)" -start "" /B java -classpath "%OSPL_HOME%\jar\dcpssaj.jar";classes LifecycleDataSubscriber > subResult_2.txt +echo "=== (step 2)" +start "" /B java -jar sub/java5_Lifecycle_sub.jar > subResult_2.txt %SLEEP2% >NUL -java -classpath "%OSPL_HOME%\jar\dcpssaj.jar";classes LifecycleDataPublisher false unregister > pubResult_2.txt +java -jar pub/java5_Lifecycle_pub.jar false unregister > pubResult_2.txt %SLEEP5% > NUL @@ -42,13 +42,13 @@ rem == step_3 == rem ======================================================= call %FUNCTIONS% :startOSPL -echo "=== (step 3)" -start "" /B java -classpath "%OSPL_HOME%\jar\dcpssaj.jar";classes LifecycleDataSubscriber > subResult_3.txt +echo "=== (step 3)" +start "" /B java -jar sub/java5_Lifecycle_sub.jar > subResult_3.txt %SLEEP2% > NUL -java -classpath "%OSPL_HOME%\jar\dcpssaj.jar";classes LifecycleDataPublisher false unregister > pubResult_3.txt +java -jar pub/java5_Lifecycle_pub.jar false unregister > pubResult_3.txt -%SLEEP5% > NUL +%SLEEP5% > NUL call %FUNCTIONS% :lifecycleCheckResults >> run.log \ No newline at end of file diff --git a/build/scripts/overnight/example_automation_scripts/examples/dcps/Listener/c/standalone/RUN b/build/scripts/overnight/example_automation_scripts/examples/dcps/Listener/c/standalone/RUN index 8d3d77548..197a4c238 100755 --- a/build/scripts/overnight/example_automation_scripts/examples/dcps/Listener/c/standalone/RUN +++ b/build/scripts/overnight/example_automation_scripts/examples/dcps/Listener/c/standalone/RUN @@ -6,6 +6,7 @@ startOSPL echo "=== Launching Subscriber " ./sac_listener_sub > subResult.txt & +cmd_pid=$! sleep 5 @@ -14,8 +15,7 @@ echo "=== Launching Publisher " ./sac_listener_pub > pubResult.txt echo "=== Waiting for processes to terminate" -waitForProcessTermination sac_listener_pub 30 -waitForProcessTermination sac_listener_sub 30 +waitForProcessTermination $cmd_pid 30 listenerCheckResult diff --git a/build/scripts/overnight/example_automation_scripts/examples/dcps/Listener/cpp/standalone/RUN b/build/scripts/overnight/example_automation_scripts/examples/dcps/Listener/cpp/standalone/RUN index 9f55c68db..62862fce6 100755 --- a/build/scripts/overnight/example_automation_scripts/examples/dcps/Listener/cpp/standalone/RUN +++ b/build/scripts/overnight/example_automation_scripts/examples/dcps/Listener/cpp/standalone/RUN @@ -7,14 +7,14 @@ startOSPL echo "=== Launching Listener " ./sacpp_listener_sub > subResult.txt & +cmd_pid=$! sleep 5 ./sacpp_listener_pub > pubResult.txt echo "=== Waiting for processes to terminate" -waitForProcessTermination sacpp_listener_pub 30 -waitForProcessTermination sacpp_listener_sub 30 +waitForProcessTermination $cmd_pid 30 listenerCheckResult diff --git a/build/scripts/overnight/example_automation_scripts/examples/dcps/Listener/isocpp/RUN b/build/scripts/overnight/example_automation_scripts/examples/dcps/Listener/isocpp/RUN deleted file mode 100755 index ec1a710d5..000000000 --- a/build/scripts/overnight/example_automation_scripts/examples/dcps/Listener/isocpp/RUN +++ /dev/null @@ -1,15 +0,0 @@ -. $OSPL_HOME/examples/functions - -check_osplhome - -NAME=Listener -SUB_PARAMS= -PUB_PARAMS= - -startOSPL - -runZero $NAME $SUB_PARAMS $PUB_PARAMS - -checkResultZero $SUB_RESULT $PUB_RESULT $NAME - -stopOSPL diff --git a/build/scripts/overnight/example_automation_scripts/examples/dcps/Listener/isocpp/RUN.bat b/build/scripts/overnight/example_automation_scripts/examples/dcps/Listener/isocpp/RUN.bat deleted file mode 100755 index 2feb702f1..000000000 --- a/build/scripts/overnight/example_automation_scripts/examples/dcps/Listener/isocpp/RUN.bat +++ /dev/null @@ -1,11 +0,0 @@ -@echo OFF -SETLOCAL - -set EXAMPLE_LANG=isocpp -set NAME=Listener -set SUB_PARAMS= -set PUB_PARAMS= - -call %FUNCTIONS% :runZero - -call %FUNCTIONS% :checkResultZero diff --git a/build/scripts/overnight/example_automation_scripts/examples/dcps/Listener/isocpp/RUNSUB.bat b/build/scripts/overnight/example_automation_scripts/examples/dcps/Listener/isocpp/RUNSUB.bat deleted file mode 100755 index 012c1a2ab..000000000 --- a/build/scripts/overnight/example_automation_scripts/examples/dcps/Listener/isocpp/RUNSUB.bat +++ /dev/null @@ -1,2 +0,0 @@ -call subscriber.exe %SUB_PARAMS% > subResult.txt 2>&1 -echo %errorlevel% > subReturn.txt 2>&1 diff --git a/build/scripts/overnight/example_automation_scripts/examples/dcps/Listener/java5/RUN b/build/scripts/overnight/example_automation_scripts/examples/dcps/Listener/java5/RUN index 42c41ac22..159a21ccb 100755 --- a/build/scripts/overnight/example_automation_scripts/examples/dcps/Listener/java5/RUN +++ b/build/scripts/overnight/example_automation_scripts/examples/dcps/Listener/java5/RUN @@ -8,11 +8,11 @@ startOSPL echo "=== Launching Listener " -LD_PRELOAD=$OSPL_JSIG $SPLICE_JAVA -classpath $OSPL_HOME/jar/dcpssaj5.jar:classes:$SPLICE_EXTRA_CP ListenerDataSubscriber > subResult.txt & +LD_PRELOAD=$OSPL_JSIG $SPLICE_JAVA -jar sub/java5_Listener_sub.jar > subResult.txt & sleep 5 -LD_PRELOAD=$OSPL_JSIG $SPLICE_JAVA -classpath $OSPL_HOME/jar/dcpssaj5.jar:classes:$SPLICE_EXTRA_CP ListenerDataPublisher > pubResult.txt +LD_PRELOAD=$OSPL_JSIG $SPLICE_JAVA -jar pub/java5_Listener_pub.jar > pubResult.txt sleep 10 listenerCheckResult diff --git a/build/scripts/overnight/example_automation_scripts/examples/dcps/Listener/java5/RUN.bat b/build/scripts/overnight/example_automation_scripts/examples/dcps/Listener/java5/RUN.bat index 0f0767ab3..99de233c7 100755 --- a/build/scripts/overnight/example_automation_scripts/examples/dcps/Listener/java5/RUN.bat +++ b/build/scripts/overnight/example_automation_scripts/examples/dcps/Listener/java5/RUN.bat @@ -6,9 +6,9 @@ call %FUNCTIONS% :stopOSPL call %FUNCTIONS% :startOSPL echo "== Launching Listener " -start "" /B java -classpath "%OSPL_HOME%\jar\dcpssaj5.jar";classes ListenerDataSubscriber > subResult.txt +start "" /B java -jar sub/java5_Listener_sub.jar > subResult.txt %SLEEP2% >NUL -java -classpath "%OSPL_HOME%\jar\dcpssaj5.jar";classes ListenerDataPublisher > pubResult.txt +java -jar pub/java5_Listener_pub.jar > pubResult.txt call %FUNCTIONS% :listenerCheckResults >> run.log diff --git a/build/scripts/overnight/example_automation_scripts/examples/dcps/Ownership/c/standalone/RUN b/build/scripts/overnight/example_automation_scripts/examples/dcps/Ownership/c/standalone/RUN index 05548808a..e4f46dfa4 100644 --- a/build/scripts/overnight/example_automation_scripts/examples/dcps/Ownership/c/standalone/RUN +++ b/build/scripts/overnight/example_automation_scripts/examples/dcps/Ownership/c/standalone/RUN @@ -6,20 +6,24 @@ startOSPL echo "=== Launching Ownership " ./sac_ownership_sub > subResult.txt & +sub_pid=$! sleep 7 echo === starting publisher "pub1" with ownership strength 5 -./sac_ownership_pub pub1 5 40 1 > pubResult_1.txt & +./sac_ownership_pub pub1 5 40 1 > pubResult_1.txt & +pub1_pid=$! echo === Waiting 2 seconds ... sleep 2 echo === starting publisher "pub2" with ownership strength 10 ./sac_ownership_pub pub2 10 5 0 > pubResult_2.txt & +pub2_pid=$! echo === Waiting for processes to terminate -waitForProcessTermination sac_ownership_pub 30 -waitForProcessTermination sac_ownership_sub 30 +waitForProcessTermination $sub_pid 30 +waitForProcessTermination $pub1_pid 30 +waitForProcessTermination $pub2_pid 30 ownershipCheckResult diff --git a/build/scripts/overnight/example_automation_scripts/examples/dcps/Ownership/cpp/standalone/RUN b/build/scripts/overnight/example_automation_scripts/examples/dcps/Ownership/cpp/standalone/RUN index 1de04f730..0f6752416 100644 --- a/build/scripts/overnight/example_automation_scripts/examples/dcps/Ownership/cpp/standalone/RUN +++ b/build/scripts/overnight/example_automation_scripts/examples/dcps/Ownership/cpp/standalone/RUN @@ -6,20 +6,24 @@ startOSPL echo "=== Launching Ownership " ./sacpp_ownership_sub > subResult.txt & +sub_pid=$! sleep 5 echo === starting publisher "pub1" with ownership strength 5 ./sacpp_ownership_pub pub1 5 40 1 > pubResult_1.txt & +pub1_pid=$! echo === Waiting 2 seconds ... sleep 2 echo === starting publisher "pub2" with ownership strength 10 ./sacpp_ownership_pub pub2 10 5 0 > pubResult_2.txt & +pub2_pid=$! echo === Waiting for processes to terminate -waitForProcessTermination sacpp_ownership_pub 30 -waitForProcessTermination sacpp_ownership_sub 30 +waitForProcessTermination $sub_pid 30 +waitForProcessTermination $pub1_pid 30 +waitForProcessTermination $pub2_pid 30 ownershipCheckResult diff --git a/build/scripts/overnight/example_automation_scripts/examples/dcps/Ownership/isocpp/RUN b/build/scripts/overnight/example_automation_scripts/examples/dcps/Ownership/isocpp/RUN deleted file mode 100755 index 160d4f221..000000000 --- a/build/scripts/overnight/example_automation_scripts/examples/dcps/Ownership/isocpp/RUN +++ /dev/null @@ -1,24 +0,0 @@ -. $OSPL_HOME/examples/functions - -check_osplhome - -startOSPL - -echo "=== Launching Ownership " -./subscriber > subResult.txt & -sleep 5 - -echo === starting publisher "pub1" with ownership strength 5 -./publisher pub1 5 40 1 > pubResult_1.txt & - -echo === Waiting 2 seconds ... -sleep 2 - -echo === starting publisher "pub2" with ownership strength 10 -./publisher pub2 10 5 0 > pubResult_2.txt & - -sleep 15 - -ownershipCheckResult - -stopOSPL \ No newline at end of file diff --git a/build/scripts/overnight/example_automation_scripts/examples/dcps/Ownership/isocpp/RUN.bat b/build/scripts/overnight/example_automation_scripts/examples/dcps/Ownership/isocpp/RUN.bat deleted file mode 100755 index 265d90f87..000000000 --- a/build/scripts/overnight/example_automation_scripts/examples/dcps/Ownership/isocpp/RUN.bat +++ /dev/null @@ -1,10 +0,0 @@ -echo OFF -SETLOCAL - -echo "===== calling Ownership for isocpp =====" - -set EXAMPLE_LANG=isocpp - -call %FUNCTIONS% :runOwnershipISOCPP - -call %FUNCTIONS% :ownershipCheckResults diff --git a/build/scripts/overnight/example_automation_scripts/examples/dcps/Ownership/isocpp2/RUN b/build/scripts/overnight/example_automation_scripts/examples/dcps/Ownership/isocpp2/RUN index 160d4f221..d3a6ae002 100755 --- a/build/scripts/overnight/example_automation_scripts/examples/dcps/Ownership/isocpp2/RUN +++ b/build/scripts/overnight/example_automation_scripts/examples/dcps/Ownership/isocpp2/RUN @@ -6,19 +6,26 @@ startOSPL echo "=== Launching Ownership " ./subscriber > subResult.txt & +sub_pid=$! sleep 5 echo === starting publisher "pub1" with ownership strength 5 ./publisher pub1 5 40 1 > pubResult_1.txt & +pub1_pid=$! echo === Waiting 2 seconds ... sleep 2 echo === starting publisher "pub2" with ownership strength 10 ./publisher pub2 10 5 0 > pubResult_2.txt & +pub2_pid=$! sleep 15 +waitForProcessTermination $sub_pid 30 +waitForProcessTermination $pub1_pid 30 +waitForProcessTermination $pub2_pid 30 + ownershipCheckResult stopOSPL \ No newline at end of file diff --git a/build/scripts/overnight/example_automation_scripts/examples/dcps/Ownership/java5/RUN b/build/scripts/overnight/example_automation_scripts/examples/dcps/Ownership/java5/RUN index 58fca1359..e0dbd125e 100755 --- a/build/scripts/overnight/example_automation_scripts/examples/dcps/Ownership/java5/RUN +++ b/build/scripts/overnight/example_automation_scripts/examples/dcps/Ownership/java5/RUN @@ -8,19 +8,19 @@ startOSPL echo "=== Launching Ownership " -LD_PRELOAD=$OSPL_JSIG $SPLICE_JAVA -classpath $OSPL_HOME/jar/dcpssaj5.jar:classes:$SPLICE_EXTRA_CP OwnershipDataSubscriber > subResult.txt & +LD_PRELOAD=$OSPL_JSIG $SPLICE_JAVA -jar sub/java5_Ownership_sub.jar > subResult.txt & sleep 5 echo === starting publisher "pub1" with ownership strength 5 -LD_PRELOAD=$OSPL_JSIG $SPLICE_JAVA -classpath $OSPL_HOME/jar/dcpssaj5.jar:classes:$SPLICE_EXTRA_CP OwnershipDataPublisher pub1 5 40 1 > pubResult_1.txt & +LD_PRELOAD=$OSPL_JSIG $SPLICE_JAVA -jar pub/java5_Ownership_pub.jar pub1 5 40 1 > pubResult_1.txt & echo === Waiting 2 seconds ... sleep 2 echo === starting publisher "pub2" with ownership strength 10 -LD_PRELOAD=$OSPL_JSIG $SPLICE_JAVA -classpath $OSPL_HOME/jar/dcpssaj5.jar:classes:$SPLICE_EXTRA_CP OwnershipDataPublisher pub2 10 5 0 > pubResult_2.txt +LD_PRELOAD=$OSPL_JSIG $SPLICE_JAVA -jar pub/java5_Ownership_pub.jar pub2 10 5 0 > pubResult_2.txt sleep 10 diff --git a/build/scripts/overnight/example_automation_scripts/examples/dcps/Ownership/java5/RUN.bat b/build/scripts/overnight/example_automation_scripts/examples/dcps/Ownership/java5/RUN.bat index a58a20145..6d5919cf5 100755 --- a/build/scripts/overnight/example_automation_scripts/examples/dcps/Ownership/java5/RUN.bat +++ b/build/scripts/overnight/example_automation_scripts/examples/dcps/Ownership/java5/RUN.bat @@ -6,13 +6,13 @@ call %FUNCTIONS% :stopOSPL call %FUNCTIONS% :startOSPL echo "=== Launching Ownership " -start "" /B java -classpath "%OSPL_HOME%\jar\dcpssaj5.jar";classes OwnershipDataSubscriber > subResult.txt +start "" /B java -jar sub/java5_Ownership_sub.jar > subResult.txt %SLEEP2% >NUL -start "" /B java -classpath "%OSPL_HOME%\jar\dcpssaj5.jar";classes OwnershipDataPublisher "pub1" 5 40 1 > pub1Result.txt +start "" /B java -jar pub/java5_Ownership_pub.jar "pub1" 5 40 1 > pub1Result.txt %SLEEP2% >NUL -call java -classpath "%OSPL_HOME%\jar\dcpssaj5.jar";classes OwnershipDataPublisher "pub2" 10 5 0 > pub2Result.txt +call java -jar pub/java5_Ownership_pub.jar "pub2" 10 5 0 > pub2Result.txt call %FUNCTIONS% :ownershipCheckResults >> run.log diff --git a/build/scripts/overnight/example_automation_scripts/examples/dcps/PingPong/java5/RUN b/build/scripts/overnight/example_automation_scripts/examples/dcps/PingPong/java5/RUN new file mode 100755 index 000000000..c491eadf1 --- /dev/null +++ b/build/scripts/overnight/example_automation_scripts/examples/dcps/PingPong/java5/RUN @@ -0,0 +1,36 @@ +. $OSPL_HOME/examples/functions + +check_osplhome + +get_libjsig + +startOSPL + +BLOKSIZE=100 +BLOKCOUNT=100 + +LD_PRELOAD=$OSPL_JSIG $SPLICE_JAVA -jar pong/java5_pong.jar PongRead PongWrite& + +sleep 2 + +LD_PRELOAD=$OSPL_JSIG $SPLICE_JAVA -jar ping/java5_ping.jar $BLOKCOUNT $BLOKSIZE m PongRead PongWrite + +sleep 2 + +LD_PRELOAD=$OSPL_JSIG $SPLICE_JAVA -jar ping/java5_ping.jar $BLOKCOUNT $BLOKSIZE q PongRead PongWrite + +sleep 2 + +LD_PRELOAD=$OSPL_JSIG $SPLICE_JAVA -jar ping/java5_ping.jar $BLOKCOUNT $BLOKSIZE s PongRead PongWrite + +sleep 2 + +LD_PRELOAD=$OSPL_JSIG $SPLICE_JAVA -jar ping/java5_ping.jar $BLOKCOUNT $BLOKSIZE f PongRead PongWrite + +sleep 2 + +LD_PRELOAD=$OSPL_JSIG $SPLICE_JAVA -jar ping/java5_ping.jar 1 10 t PongRead PongWrite + +sleep 4 + +stopOSPL \ No newline at end of file diff --git a/build/scripts/overnight/example_automation_scripts/examples/dcps/PingPong/java5/RUN.bat b/build/scripts/overnight/example_automation_scripts/examples/dcps/PingPong/java5/RUN.bat new file mode 100755 index 000000000..8e06b50ca --- /dev/null +++ b/build/scripts/overnight/example_automation_scripts/examples/dcps/PingPong/java5/RUN.bat @@ -0,0 +1,64 @@ +@ECHO OFF +SETLOCAL +echo "==== Calling check_osplhome====" +call %FUNCTIONS% :check_osplhome + +echo "====Calling stopOSPL ====" +call %FUNCTIONS% :stopOSPL + +set BLOKSIZE=100 +set BLOKCOUNT=100 + +echo "==== Calling startOSPL ====" +call %FUNCTIONS% :startOSPL + +ECHO Starting pong +set LEVEL=Starting pong +start java -jar pong/java5_pong.jar PongRead PongWrite +if %ERRORLEVEL% NEQ 0 GOTO error + +%SLEEP4% >NUL + +ECHO Starting ping with m +set LEVEL=Starting ping with m +java -jar ping/java5_ping.jar %BLOKCOUNT% %BLOKSIZE% m PongRead PongWrite >> %LOGFILE% +if %ERRORLEVEL% NEQ 0 GOTO error + +%SLEEP4% >NUL + +ECHO Starting ping with q +set LEVEL=Starting ping with q +java -jar ping/java5_ping.jar %BLOKCOUNT% %BLOKSIZE% q PongRead PongWrite >> %LOGFILE% +if %ERRORLEVEL% NEQ 0 GOTO error + +%SLEEP4% >NUL + +ECHO Starting ping with s +set LEVEL=Starting ping with s +java -jar ping/java5_ping.jar %BLOKCOUNT% %BLOKSIZE% s PongRead PongWrite >> %LOGFILE% +if %ERRORLEVEL% NEQ 0 GOTO error + +%SLEEP4% >NUL + +ECHO Starting ping with f +set LEVEL=Starting ping with f +java -jar ping/java5_ping.jar %BLOKCOUNT% %BLOKSIZE% f PongRead PongWrite >> %LOGFILE% +if %ERRORLEVEL% NEQ 0 GOTO error + +%SLEEP4% >NUL + +ECHO Starting ping with t +set LEVEL=Starting ping with t +java -jar ping/java5_ping.jar 1 10 t PongRead PongWrite >> %LOGFILE% +if %ERRORLEVEL% NEQ 0 GOTO error + +GOTO end + +:error +ECHO An error occurred %LEVEL%, exiting example ... >> %LOGFILE% +REM Do not exit as this prevents the test run reporting correctly +GOTO end + +:end +echo "===== calling stopOSPL ====" +call %FUNCTIONS% :stopOSPL diff --git a/build/scripts/overnight/example_automation_scripts/examples/dcps/QueryCondition/c/standalone/RUN b/build/scripts/overnight/example_automation_scripts/examples/dcps/QueryCondition/c/standalone/RUN index e498d9207..024d68956 100644 --- a/build/scripts/overnight/example_automation_scripts/examples/dcps/QueryCondition/c/standalone/RUN +++ b/build/scripts/overnight/example_automation_scripts/examples/dcps/QueryCondition/c/standalone/RUN @@ -7,14 +7,14 @@ startOSPL echo "=== Launching QueryCondition " ./sac_querycondition_sub MSFT > subResult.txt & +cmd_pid=$! sleep 2 ./sac_querycondition_pub > pubResult.txt echo === Waiting for processes to terminate -waitForProcessTermination sac_querycondition_pub 30 -waitForProcessTermination sac_querycondition_sub 30 +waitForProcessTermination $cmd_pid 30 queryconditionCheckResult diff --git a/build/scripts/overnight/example_automation_scripts/examples/dcps/QueryCondition/cpp/standalone/RUN b/build/scripts/overnight/example_automation_scripts/examples/dcps/QueryCondition/cpp/standalone/RUN index 6b82e8846..5b3d9af06 100644 --- a/build/scripts/overnight/example_automation_scripts/examples/dcps/QueryCondition/cpp/standalone/RUN +++ b/build/scripts/overnight/example_automation_scripts/examples/dcps/QueryCondition/cpp/standalone/RUN @@ -7,14 +7,14 @@ startOSPL echo "=== Launching QueryCondition " ./sacpp_querycondition_sub MSFT > subResult.txt & +cmd_pid=$! sleep 2 ./sacpp_querycondition_pub > pubResult.txt echo === Waiting for processes to terminate -waitForProcessTermination sacpp_querycondition_pub 30 -waitForProcessTermination sacpp_querycondition_sub 30 +waitForProcessTermination $cmd_pid 30 queryconditionCheckResult diff --git a/build/scripts/overnight/example_automation_scripts/examples/dcps/QueryCondition/isocpp/RUN b/build/scripts/overnight/example_automation_scripts/examples/dcps/QueryCondition/isocpp/RUN deleted file mode 100755 index 59a0c1eeb..000000000 --- a/build/scripts/overnight/example_automation_scripts/examples/dcps/QueryCondition/isocpp/RUN +++ /dev/null @@ -1,15 +0,0 @@ -. $OSPL_HOME/examples/functions - -check_osplhome - -NAME=QueryCondition -SUB_PARAMS=GE -PUB_PARAMS= - -startOSPL - -runZero $NAME $SUB_PARAMS $PUB_PARAMS - -checkResultZero $SUB_RESULT $PUB_RESULT $NAME - -stopOSPL diff --git a/build/scripts/overnight/example_automation_scripts/examples/dcps/QueryCondition/isocpp/RUN.bat b/build/scripts/overnight/example_automation_scripts/examples/dcps/QueryCondition/isocpp/RUN.bat deleted file mode 100755 index 99125ef9c..000000000 --- a/build/scripts/overnight/example_automation_scripts/examples/dcps/QueryCondition/isocpp/RUN.bat +++ /dev/null @@ -1,11 +0,0 @@ -@echo OFF -SETLOCAL - -set EXAMPLE_LANG=isocpp -set NAME=QueryCondition -set SUB_PARAMS=GE -set PUB_PARAMS= - -call %FUNCTIONS% :runZero - -call %FUNCTIONS% :checkResultZero diff --git a/build/scripts/overnight/example_automation_scripts/examples/dcps/QueryCondition/isocpp/RUNSUB.bat b/build/scripts/overnight/example_automation_scripts/examples/dcps/QueryCondition/isocpp/RUNSUB.bat deleted file mode 100755 index 012c1a2ab..000000000 --- a/build/scripts/overnight/example_automation_scripts/examples/dcps/QueryCondition/isocpp/RUNSUB.bat +++ /dev/null @@ -1,2 +0,0 @@ -call subscriber.exe %SUB_PARAMS% > subResult.txt 2>&1 -echo %errorlevel% > subReturn.txt 2>&1 diff --git a/build/scripts/overnight/example_automation_scripts/examples/dcps/QueryCondition/java5/RUN b/build/scripts/overnight/example_automation_scripts/examples/dcps/QueryCondition/java5/RUN index 1c74bb667..3f85996db 100755 --- a/build/scripts/overnight/example_automation_scripts/examples/dcps/QueryCondition/java5/RUN +++ b/build/scripts/overnight/example_automation_scripts/examples/dcps/QueryCondition/java5/RUN @@ -7,11 +7,11 @@ get_libjsig startOSPL echo "=== Launching QueryCondition " -LD_PRELOAD=$OSPL_JSIG $SPLICE_JAVA -classpath $OSPL_HOME/jar/dcpssaj5.jar:classes:$SPLICE_EXTRA_CP QueryConditionDataSubscriber MSFT > subResult.txt & +LD_PRELOAD=$OSPL_JSIG $SPLICE_JAVA -jar sub/java5_QueryCondition_sub.jar MSFT > subResult.txt & sleep 2 -LD_PRELOAD=$OSPL_JSIG $SPLICE_JAVA -classpath $OSPL_HOME/jar/dcpssaj5.jar:classes:$SPLICE_EXTRA_CP QueryConditionDataPublisher > pubResult.txt +LD_PRELOAD=$OSPL_JSIG $SPLICE_JAVA -jar pub/java5_QueryCondition_pub.jar > pubResult.txt queryconditionCheckResult diff --git a/build/scripts/overnight/example_automation_scripts/examples/dcps/QueryCondition/java5/RUN.bat b/build/scripts/overnight/example_automation_scripts/examples/dcps/QueryCondition/java5/RUN.bat index ae7b05fb5..7a5640f91 100755 --- a/build/scripts/overnight/example_automation_scripts/examples/dcps/QueryCondition/java5/RUN.bat +++ b/build/scripts/overnight/example_automation_scripts/examples/dcps/QueryCondition/java5/RUN.bat @@ -6,10 +6,10 @@ call %FUNCTIONS% :stopOSPL call %FUNCTIONS% :startOSPL echo "=== Launching QueryCondition " -start "" /B java -classpath "%OSPL_HOME%\jar\dcpssaj5.jar";classes QueryConditionDataSubscriber MSFT > subResult.txt +start "" /B java -jar sub/java5_QueryCondition_sub.jar MSFT > subResult.txt %SLEEP5% >NUL -call java -classpath "%OSPL_HOME%\jar\dcpssaj5.jar";classes QueryConditionDataPublisher > pubResult.txt +call java -jar pub/java5_QueryCondition_pub.jar > pubResult.txt %SLEEP5% >NUL call %FUNCTIONS% :queryconditionCheckResults >> run.log \ No newline at end of file diff --git a/build/scripts/overnight/example_automation_scripts/examples/dcps/RoundTrip/c99/RUN b/build/scripts/overnight/example_automation_scripts/examples/dcps/RoundTrip/c99/RUN old mode 100644 new mode 100755 diff --git a/build/scripts/overnight/example_automation_scripts/examples/dcps/RoundTrip/c99/RUN.bat b/build/scripts/overnight/example_automation_scripts/examples/dcps/RoundTrip/c99/RUN.bat old mode 100644 new mode 100755 diff --git a/build/scripts/overnight/example_automation_scripts/examples/dcps/RoundTrip/c99/RUNSUB.bat b/build/scripts/overnight/example_automation_scripts/examples/dcps/RoundTrip/c99/RUNSUB.bat old mode 100644 new mode 100755 diff --git a/build/scripts/overnight/example_automation_scripts/examples/dcps/RoundTrip/isocpp/RUN b/build/scripts/overnight/example_automation_scripts/examples/dcps/RoundTrip/isocpp/RUN deleted file mode 100755 index 52ddcffd5..000000000 --- a/build/scripts/overnight/example_automation_scripts/examples/dcps/RoundTrip/isocpp/RUN +++ /dev/null @@ -1,13 +0,0 @@ -. $OSPL_HOME/examples/functions - -check_osplhome - -NAME=RoundTrip - -startOSPL - -runZeroRoundTrip - -checkResultZero $SUB_RESULT $PUB_RESULT $NAME - -stopOSPL diff --git a/build/scripts/overnight/example_automation_scripts/examples/dcps/RoundTrip/isocpp/RUN.bat b/build/scripts/overnight/example_automation_scripts/examples/dcps/RoundTrip/isocpp/RUN.bat deleted file mode 100755 index 23b4a860c..000000000 --- a/build/scripts/overnight/example_automation_scripts/examples/dcps/RoundTrip/isocpp/RUN.bat +++ /dev/null @@ -1,11 +0,0 @@ -@echo OFF -SETLOCAL - -set EXAMPLE_LANG=isocpp -set NAME=RoundTrip -set SUB_PARAMS= -set PUB_PARAMS= - -call %FUNCTIONS% :runZeroRoundTrip - -call %FUNCTIONS% :checkResultZero diff --git a/build/scripts/overnight/example_automation_scripts/examples/dcps/RoundTrip/isocpp/RUNSUB.bat b/build/scripts/overnight/example_automation_scripts/examples/dcps/RoundTrip/isocpp/RUNSUB.bat deleted file mode 100755 index f38e70092..000000000 --- a/build/scripts/overnight/example_automation_scripts/examples/dcps/RoundTrip/isocpp/RUNSUB.bat +++ /dev/null @@ -1,2 +0,0 @@ -call pong.exe %SUB_PARAMS% > pongResult.txt 2>&1 -echo %errorlevel% > subReturn.txt 2>&1 diff --git a/build/scripts/overnight/example_automation_scripts/examples/dcps/RoundTrip/java5/RUNSUB.bat b/build/scripts/overnight/example_automation_scripts/examples/dcps/RoundTrip/java5/RUNSUB.bat index b127bd424..253fd0a85 100755 --- a/build/scripts/overnight/example_automation_scripts/examples/dcps/RoundTrip/java5/RUNSUB.bat +++ b/build/scripts/overnight/example_automation_scripts/examples/dcps/RoundTrip/java5/RUNSUB.bat @@ -1,2 +1,2 @@ -start "" /B java -classpath "classes;%OSPL_HOME%/jar/dcpssaj5.jar" pong %SUB_PARAMS% > pongResult.txt 2>&1 +start "" /B java -jar pong/java5_pong.jar %SUB_PARAMS% > pongResult.txt 2>&1 echo %errorlevel% > subReturn.txt 2>&1 diff --git a/build/scripts/overnight/example_automation_scripts/examples/dcps/Throughput/c99/RUN b/build/scripts/overnight/example_automation_scripts/examples/dcps/Throughput/c99/RUN old mode 100644 new mode 100755 diff --git a/build/scripts/overnight/example_automation_scripts/examples/dcps/Throughput/c99/RUN.bat b/build/scripts/overnight/example_automation_scripts/examples/dcps/Throughput/c99/RUN.bat old mode 100644 new mode 100755 diff --git a/build/scripts/overnight/example_automation_scripts/examples/dcps/Throughput/c99/RUNPUB.bat b/build/scripts/overnight/example_automation_scripts/examples/dcps/Throughput/c99/RUNPUB.bat old mode 100644 new mode 100755 diff --git a/build/scripts/overnight/example_automation_scripts/examples/dcps/Throughput/isocpp/RUN b/build/scripts/overnight/example_automation_scripts/examples/dcps/Throughput/isocpp/RUN deleted file mode 100755 index c0a2beab7..000000000 --- a/build/scripts/overnight/example_automation_scripts/examples/dcps/Throughput/isocpp/RUN +++ /dev/null @@ -1,21 +0,0 @@ -. $OSPL_HOME/examples/functions - -check_osplhome - -NAME=Throughput - -startOSPL - -runZeroThroughput - -echo "=== Checking $NAME results" - -if [ $SUB_RESULT -ne 0 ] -then - echo NOK - echo "*** ERROR : example $NAME failed " -else - echo OK -fi - -stopOSPL diff --git a/build/scripts/overnight/example_automation_scripts/examples/dcps/Throughput/isocpp/RUN.bat b/build/scripts/overnight/example_automation_scripts/examples/dcps/Throughput/isocpp/RUN.bat deleted file mode 100755 index ef2924842..000000000 --- a/build/scripts/overnight/example_automation_scripts/examples/dcps/Throughput/isocpp/RUN.bat +++ /dev/null @@ -1,9 +0,0 @@ -@echo OFF -SETLOCAL - -set EXAMPLE_LANG=isocpp -set NAME=Throughtput - -call %FUNCTIONS% :runZeroThroughput - -call %FUNCTIONS% :checkResultZero diff --git a/build/scripts/overnight/example_automation_scripts/examples/dcps/Throughput/isocpp/RUNPUB.bat b/build/scripts/overnight/example_automation_scripts/examples/dcps/Throughput/isocpp/RUNPUB.bat deleted file mode 100755 index 3783e3d36..000000000 --- a/build/scripts/overnight/example_automation_scripts/examples/dcps/Throughput/isocpp/RUNPUB.bat +++ /dev/null @@ -1,2 +0,0 @@ -call publisher.exe 1 0 1 15 > pubResult.txt 2>&1 -echo %errorlevel% > pubReturn.txt 2>&1 diff --git a/build/scripts/overnight/example_automation_scripts/examples/dcps/Throughput/java5/RUNPUB.bat b/build/scripts/overnight/example_automation_scripts/examples/dcps/Throughput/java5/RUNPUB.bat index 9fa350846..c989ecd70 100755 --- a/build/scripts/overnight/example_automation_scripts/examples/dcps/Throughput/java5/RUNPUB.bat +++ b/build/scripts/overnight/example_automation_scripts/examples/dcps/Throughput/java5/RUNPUB.bat @@ -1,2 +1,2 @@ -start "" /B java -classpath "classes;%OSPL_HOME%/jar/dcpssaj5.jar" publisher 1 0 1 15 > pubResult.txt 2>&1 +start "" /B java -jar pub/java5_Throughput_pub.jar 1 0 1 15 > pubResult.txt 2>&1 echo %errorlevel% > pubReturn.txt 2>&1 diff --git a/build/scripts/overnight/example_automation_scripts/examples/dcps/Tutorial/isocpp/RUN b/build/scripts/overnight/example_automation_scripts/examples/dcps/Tutorial/isocpp/RUN deleted file mode 100644 index 82b69ea51..000000000 --- a/build/scripts/overnight/example_automation_scripts/examples/dcps/Tutorial/isocpp/RUN +++ /dev/null @@ -1,9 +0,0 @@ -. $OSPL_HOME/examples/functions - -check_osplhome - -startOSPL - -runTutorial - -stopOSPL \ No newline at end of file diff --git a/build/scripts/overnight/example_automation_scripts/examples/dcps/Tutorial/isocpp/RUN.bat b/build/scripts/overnight/example_automation_scripts/examples/dcps/Tutorial/isocpp/RUN.bat deleted file mode 100755 index c79883c68..000000000 --- a/build/scripts/overnight/example_automation_scripts/examples/dcps/Tutorial/isocpp/RUN.bat +++ /dev/null @@ -1,4 +0,0 @@ -@ECHO OFF - - -call %FUNCTIONS% :runTutorial diff --git a/build/scripts/overnight/example_automation_scripts/examples/dcps/Tutorial/java5/RUN b/build/scripts/overnight/example_automation_scripts/examples/dcps/Tutorial/java5/RUN index f112815fe..0be27c1ff 100755 --- a/build/scripts/overnight/example_automation_scripts/examples/dcps/Tutorial/java5/RUN +++ b/build/scripts/overnight/example_automation_scripts/examples/dcps/Tutorial/java5/RUN @@ -7,22 +7,22 @@ get_libjsig startOSPL echo start MessageBoard -LD_PRELOAD=$OSPL_JSIG $SPLICE_JAVA -classpath $OSPL_HOME/jar/dcpssaj5.jar:classes:$SPLICE_EXTRA_CP chatroom.MessageBoard & +LD_PRELOAD=$OSPL_JSIG $SPLICE_JAVA -jar messageboard/java5_Messageboard.jar & sleep 2 echo start UserLoad -LD_PRELOAD=$OSPL_JSIG $SPLICE_JAVA -classpath $OSPL_HOME/jar/dcpssaj5.jar:classes:$SPLICE_EXTRA_CP chatroom.UserLoad & +LD_PRELOAD=$OSPL_JSIG $SPLICE_JAVA -jar userload/java5_UserLoad.jar & sleep 2 echo start Chatter -LD_PRELOAD=$OSPL_JSIG $SPLICE_JAVA -classpath $OSPL_HOME/jar/dcpssaj5.jar:classes:$SPLICE_EXTRA_CP chatroom.Chatter +LD_PRELOAD=$OSPL_JSIG $SPLICE_JAVA -jar chatter/java5_Chatter.jar sleep 4 echo start Chatter with terminate message -LD_PRELOAD=$OSPL_JSIG $SPLICE_JAVA -classpath $OSPL_HOME/jar/dcpssaj5.jar:classes:$SPLICE_EXTRA_CP chatroom.Chatter -1 +LD_PRELOAD=$OSPL_JSIG $SPLICE_JAVA -jar chatter/java5_Chatter.jar -1 sleep 4 diff --git a/build/scripts/overnight/example_automation_scripts/examples/dcps/Tutorial/java5/RUN.bat b/build/scripts/overnight/example_automation_scripts/examples/dcps/Tutorial/java5/RUN.bat index 15ad15511..6f2a87349 100755 --- a/build/scripts/overnight/example_automation_scripts/examples/dcps/Tutorial/java5/RUN.bat +++ b/build/scripts/overnight/example_automation_scripts/examples/dcps/Tutorial/java5/RUN.bat @@ -7,27 +7,27 @@ call %FUNCTIONS% :startOSPL ECHO Starting MessageBoard SET LEVEL=Starting MessageBoard -start CMD /C java -classpath "%OSPL_HOME%\jar\dcpssaj5.jar;classes" chatroom.MessageBoard ^> messageBoard.log +start CMD /C java -jar messageboard/java5_Messageboard.jar ^> messageBoard.log if %ERRORLEVEL% NEQ 0 GOTO error %SLEEP4% >NUL ECHO Starting UserLoad SET LEVEL=Starting UserLoad -start CMD /C java -classpath "%OSPL_HOME%\jar\dcpssaj5.jar;classes" chatroom.UserLoad ^> userLoad.log +start CMD /C java -jar userload/java5_UserLoad.jar ^> userLoad.log if %ERRORLEVEL% NEQ 0 ECHO An error occurred starting UserLoad %ERRORLEVEL% %SLEEP4% >NUL ECHO Starting Chatter SET LEVEL=Starting Chatter -java -classpath "%OSPL_HOME%\jar\dcpssaj5.jar;classes" chatroom.Chatter >> %LOGFILE% +java -jar chatter/java5_Chatter.jar >> %LOGFILE% if %ERRORLEVEL% NEQ 0 GOTO error %SLEEP4% >NUL ECHO Starting Chatter with terminate message>> %LOGFILE% -java -classpath "%OSPL_HOME%\jar\dcpssaj5.jar;classes" chatroom.Chatter -1 >> %LOGFILE% +java -jar chatter/java5_Chatter.jar -1 >> %LOGFILE% if %ERRORLEVEL% NEQ 0 GOTO error GOTO end diff --git a/build/scripts/overnight/example_automation_scripts/examples/dcps/WaitSet/c/standalone/RUN b/build/scripts/overnight/example_automation_scripts/examples/dcps/WaitSet/c/standalone/RUN index 0435d2c72..e9a3a4863 100755 --- a/build/scripts/overnight/example_automation_scripts/examples/dcps/WaitSet/c/standalone/RUN +++ b/build/scripts/overnight/example_automation_scripts/examples/dcps/WaitSet/c/standalone/RUN @@ -6,6 +6,7 @@ startOSPL echo "=== Launching WaitSet " ./sac_waitset_sub > subResult.txt & +cmd_pid=$! sleep 2 @@ -13,8 +14,7 @@ sleep 2 sleep 1 echo "=== Waiting for processes to terminate" -waitForProcessTermination sac_waitset_pub 30 -waitForProcessTermination sac_waitset_sub 30 +waitForProcessTermination $cmd_pid 30 waitsetCheckResult diff --git a/build/scripts/overnight/example_automation_scripts/examples/dcps/WaitSet/cpp/standalone/RUN b/build/scripts/overnight/example_automation_scripts/examples/dcps/WaitSet/cpp/standalone/RUN index 553e207ea..627c05624 100755 --- a/build/scripts/overnight/example_automation_scripts/examples/dcps/WaitSet/cpp/standalone/RUN +++ b/build/scripts/overnight/example_automation_scripts/examples/dcps/WaitSet/cpp/standalone/RUN @@ -6,6 +6,7 @@ startOSPL echo "=== Launching WaitSet " ./sacpp_waitset_sub > subResult.txt & +cmd_pid=$! sleep 2 @@ -13,8 +14,7 @@ sleep 2 sleep 1 echo "=== Waiting for processes to terminate" -waitForProcessTermination sacpp_waitset_pub 30 -waitForProcessTermination sacpp_waitset_sub 30 +waitForProcessTermination $cmd_pid 30 waitsetCheckResult diff --git a/build/scripts/overnight/example_automation_scripts/examples/dcps/WaitSet/isocpp/RUN b/build/scripts/overnight/example_automation_scripts/examples/dcps/WaitSet/isocpp/RUN deleted file mode 100755 index 75130ce38..000000000 --- a/build/scripts/overnight/example_automation_scripts/examples/dcps/WaitSet/isocpp/RUN +++ /dev/null @@ -1,15 +0,0 @@ -. $OSPL_HOME/examples/functions - -check_osplhome - -NAME=WaitSet -SUB_PARAMS= -PUB_PARAMS= - -startOSPL - -runZero $NAME $SUB_PARAMS $PUB_PARAMS - -checkResultZero $SUB_RESULT $PUB_RESULT $NAME - -stopOSPL diff --git a/build/scripts/overnight/example_automation_scripts/examples/dcps/WaitSet/isocpp/RUN.bat b/build/scripts/overnight/example_automation_scripts/examples/dcps/WaitSet/isocpp/RUN.bat deleted file mode 100755 index 8403b7997..000000000 --- a/build/scripts/overnight/example_automation_scripts/examples/dcps/WaitSet/isocpp/RUN.bat +++ /dev/null @@ -1,11 +0,0 @@ -@echo OFF -SETLOCAL - -set EXAMPLE_LANG=isocpp -set NAME=WaitSet -set SUB_PARAMS= -set PUB_PARAMS= - -call %FUNCTIONS% :runZero - -call %FUNCTIONS% :checkResultZero diff --git a/build/scripts/overnight/example_automation_scripts/examples/dcps/WaitSet/isocpp/RUNSUB.bat b/build/scripts/overnight/example_automation_scripts/examples/dcps/WaitSet/isocpp/RUNSUB.bat deleted file mode 100755 index 012c1a2ab..000000000 --- a/build/scripts/overnight/example_automation_scripts/examples/dcps/WaitSet/isocpp/RUNSUB.bat +++ /dev/null @@ -1,2 +0,0 @@ -call subscriber.exe %SUB_PARAMS% > subResult.txt 2>&1 -echo %errorlevel% > subReturn.txt 2>&1 diff --git a/build/scripts/overnight/example_automation_scripts/examples/dcps/WaitSet/java5/RUN b/build/scripts/overnight/example_automation_scripts/examples/dcps/WaitSet/java5/RUN index 82b141161..3b7f1aafb 100755 --- a/build/scripts/overnight/example_automation_scripts/examples/dcps/WaitSet/java5/RUN +++ b/build/scripts/overnight/example_automation_scripts/examples/dcps/WaitSet/java5/RUN @@ -8,11 +8,11 @@ startOSPL echo "=== Launching WaitSet " -LD_PRELOAD=$OSPL_JSIG $SPLICE_JAVA -classpath $OSPL_HOME/jar/dcpssaj5.jar:classes:$SPLICE_EXTRA_CP WaitSetDataSubscriber > subResult.txt & +LD_PRELOAD=$OSPL_JSIG $SPLICE_JAVA -jar sub/java5_WaitSet_sub.jar > subResult.txt & sleep 5 -LD_PRELOAD=$OSPL_JSIG $SPLICE_JAVA -classpath $OSPL_HOME/jar/dcpssaj5.jar:classes:$SPLICE_EXTRA_CP WaitSetDataPublisher > pubResult.txt +LD_PRELOAD=$OSPL_JSIG $SPLICE_JAVA -jar pub/java5_WaitSet_pub.jar > pubResult.txt sleep 10 diff --git a/build/scripts/overnight/example_automation_scripts/examples/dcps/WaitSet/java5/RUN.bat b/build/scripts/overnight/example_automation_scripts/examples/dcps/WaitSet/java5/RUN.bat index b355fb0a6..a81ca0e69 100755 --- a/build/scripts/overnight/example_automation_scripts/examples/dcps/WaitSet/java5/RUN.bat +++ b/build/scripts/overnight/example_automation_scripts/examples/dcps/WaitSet/java5/RUN.bat @@ -7,10 +7,10 @@ call %FUNCTIONS% :startOSPL echo "=== Launching WaitSet " -start "" /B java -classpath "%OSPL_HOME%\jar\dcpssaj.jar";classes WaitSetDataSubscriber > subResult.txt +start "" /B java -jar sub/java5_WaitSet_sub.jar > subResult.txt %SLEEP2% >NUL -call java -classpath "%OSPL_HOME%\jar\dcpssaj.jar";classes WaitSetDataPublisher > pubResult.txt +call java -jar pub/java5_WaitSet_pub.jar > pubResult.txt call %FUNCTIONS% :waitsetCheckResults >> run.log \ No newline at end of file diff --git a/build/scripts/overnight/example_automation_scripts/examples/face/HelloWorld/java/RUN b/build/scripts/overnight/example_automation_scripts/examples/face/HelloWorld/java/RUN index 6a1a43cfb..511d8b2ae 100755 --- a/build/scripts/overnight/example_automation_scripts/examples/face/HelloWorld/java/RUN +++ b/build/scripts/overnight/example_automation_scripts/examples/face/HelloWorld/java/RUN @@ -7,10 +7,10 @@ get_libjsig startOSPL echo "=== Launching HelloWorld " -LD_PRELOAD=$OSPL_JSIG $SPLICE_JAVA -classpath $OSPL_HOME/jar/ddsface.jar:classes:$SPLICE_EXTRA_CP HelloWorldDataSubscriber | tee subResult.txt& +LD_PRELOAD=$OSPL_JSIG $SPLICE_JAVA -jar sub/face_HelloWorld_sub.jar | tee subResult.txt& cmd_pid=$! -LD_PRELOAD=$OSPL_JSIG $SPLICE_JAVA -classpath $OSPL_HOME/jar/ddsface.jar:classes:$SPLICE_EXTRA_CP HelloWorldDataPublisher | tee pubResult.txt +LD_PRELOAD=$OSPL_JSIG $SPLICE_JAVA -jar pub/face_HelloWorld_pub.jar | tee pubResult.txt PUB_RESULT=$? wait $cmd_pid &> /dev/null diff --git a/build/scripts/overnight/example_automation_scripts/examples/face/HelloWorld/java/RUN.bat b/build/scripts/overnight/example_automation_scripts/examples/face/HelloWorld/java/RUN.bat index c392f78b7..10fbfd98e 100755 --- a/build/scripts/overnight/example_automation_scripts/examples/face/HelloWorld/java/RUN.bat +++ b/build/scripts/overnight/example_automation_scripts/examples/face/HelloWorld/java/RUN.bat @@ -17,7 +17,7 @@ start CMD /C RUNSUB.bat %SLEEP5% >NUL -java -classpath "%OSPL_HOME%\jar\ddsface.jar";classes HelloWorldDataPublisher > pubResult.txt +java -jar pub/face_HelloWorld_pub.jar > pubResult.txt set PUB_RESULT=%errorlevel% set /p SUB_RESULT= subResult.txt +start "" /B java -jar sub/face_HelloWorld_sub.jar > subResult.txt echo %errorlevel% > subReturn.txt 2>&1 diff --git a/build/scripts/overnight/example_automation_scripts/examples/functions b/build/scripts/overnight/example_automation_scripts/examples/functions index d79b8c838..ee5d6d58b 100644 --- a/build/scripts/overnight/example_automation_scripts/examples/functions +++ b/build/scripts/overnight/example_automation_scripts/examples/functions @@ -55,21 +55,21 @@ waitForProcessTermination() PSARGS="" # for testing on WRLinux 7 - ps -h 2>&1 | grep 'BusyBox v1.22.1 (2016-02-19 09:26:32 CET) multi-call binary.' > /dev/null - if [ $? != 0 ] - then - # for testing on linux on mpc8313e - ps -h 2>&1 | grep 'BusyBox v1.14.1 (2015-09-23 16:49:28 CEST) multi-call binary' > /dev/null - if [ $? != 0 ] - then - # for testing on linux on armv7a_vfp_neon - ps -h 2>&1 | grep 'BusyBox v1.22.1 (2015-10-16 20:13:35 BST) multi-call binary.' > /dev/null - if [ $? != 0 ] - then - PSARGS="-o args" - fi - fi - fi + #ps -h 2>&1 | grep 'BusyBox v1.22.1 (2016-02-19 09:26:32 CET) multi-call binary.' > /dev/null + #if [ $? != 0 ] + #then + # # for testing on linux on mpc8313e + # ps -h 2>&1 | grep 'BusyBox v1.14.1 (2015-09-23 16:49:28 CEST) multi-call binary' > /dev/null + # if [ $? != 0 ] + # then + # # for testing on linux on armv7a_vfp_neon + # ps -h 2>&1 | grep 'BusyBox v1.22.1 (2015-10-16 20:13:35 BST) multi-call binary.' > /dev/null + # if [ $? != 0 ] + # then + # PSARGS="-o args" + # fi + # fi + #fi # Do as long as the process is available or until timeout while [ ! "x$AVAILABLE" = "x" -a ! "$TIMEOUT" = "0" ] @@ -79,11 +79,12 @@ waitForProcessTermination() # Also sleep 1 when process was terminated to allow # for any piping to finish - sleep 1; + sleep 1 done if [ ! "x$AVAILABLE" = "x" ] ; then echo "WARNING: Process $PROCESS not terminated within timeout!" + kill -9 $1 > /dev/null fi } @@ -103,8 +104,7 @@ runZero() ./publisher > pubResult.txt $PUB_PARAMS 2>&1 PUB_RESULT=$? - wait $cmd_pid &> /dev/null - SUB_RESULT=$? + waitForProcessTermination $cmd_pid 10 sleep 5 } @@ -119,8 +119,7 @@ runZeroThroughput() ./subscriber > subResult.txt 10 2>&1 SUB_RESULT=$? - wait $cmd_pid &> /dev/null - PUB_RESULT=$? + waitForProcessTermination $cmd_pid 30 sleep 5 } @@ -133,11 +132,9 @@ runZeroStreamsThroughput() ./subscriber > subResult.txt 10 10 2>&1 & cmd_pid=$! - - wait $cmd_pid &> /dev/null SUB_RESULT=$? - (sleep 30 ; echo "timeout: kill sub"; kill -9 $cmd_pid) & + (sleep 40 ; echo "timeout: kill sub"; kill -9 $cmd_pid) & killerPid=$! (kill -0 $killerPid 2>/dev/null && kill $killerPid) || true @@ -169,10 +166,10 @@ runZeroThroughputJava5() echo "=== Launching Throughput " - LD_PRELOAD=$OSPL_JSIG $SPLICE_JAVA -classpath $OSPL_HOME/jar/dcpssaj5.jar:classes:$SPLICE_EXTRA_CP publisher 1 0 1 15 > pubResult.txt 2>&1 & + LD_PRELOAD=$OSPL_JSIG $SPLICE_JAVA -jar pub/java5_Throughput_pub.jar 1 0 1 15 > pubResult.txt 2>&1 & cmd_pid=$! - LD_PRELOAD=$OSPL_JSIG $SPLICE_JAVA -classpath $OSPL_HOME/jar/dcpssaj5.jar:classes:$SPLICE_EXTRA_CP subscriber > subResult.txt 10 2>&1 + LD_PRELOAD=$OSPL_JSIG $SPLICE_JAVA -jar sub/java5_Throughput_sub.jar > subResult.txt 10 2>&1 SUB_RESULT=$? wait $cmd_pid &> /dev/null @@ -196,10 +193,10 @@ runZeroRoundTrip() sleep 5 ./ping quit >/dev/null - - wait $cmd_pid &> /dev/null SUB_RESULT=$? + waitForProcessTermination $cmd_pid 30 + sleep 5 } @@ -220,8 +217,6 @@ runZeroRoundTripJava() sleep 5 LD_PRELOAD=$OSPL_JSIG $SPLICE_JAVA -classpath $OSPL_HOME/jar/dcpssaj.jar:classes:$SPLICE_EXTRA_CP ping quit >/dev/null - - wait $cmd_pid &> /dev/null SUB_RESULT=$? sleep 5 @@ -232,19 +227,17 @@ runZeroRoundTripJava5() echo "=== Launching RoundTrip " - LD_PRELOAD=$OSPL_JSIG $SPLICE_JAVA -classpath $OSPL_HOME/jar/dcpssaj5.jar:classes:$SPLICE_EXTRA_CP pong > pongResult.txt 2>&1 & + LD_PRELOAD=$OSPL_JSIG $SPLICE_JAVA -jar pong/java5_pong.jar > pongResult.txt 2>&1 & cmd_pid=$! sleep 10 - LD_PRELOAD=$OSPL_JSIG $SPLICE_JAVA -classpath $OSPL_HOME/jar/dcpssaj5.jar:classes:$SPLICE_EXTRA_CP ping > pingResult.txt 100 0 10 2>&1 + LD_PRELOAD=$OSPL_JSIG $SPLICE_JAVA -jar ping/java5_ping.jar > pingResult.txt 100 0 10 2>&1 PUB_RESULT=$? sleep 5 - LD_PRELOAD=$OSPL_JSIG $SPLICE_JAVA -classpath $OSPL_HOME/jar/dcpssaj5.jar:classes:$SPLICE_EXTRA_CP ping quit >/dev/null - - wait $cmd_pid &> /dev/null + LD_PRELOAD=$OSPL_JSIG $SPLICE_JAVA -jar ping/java5_ping.jar quit >/dev/null SUB_RESULT=$? sleep 5 @@ -521,6 +514,7 @@ runPingPong() BLOKCOUNT=100 $VG_PONG ./pong PongRead PongWrite & + cmd_pid=$! sleep 4 @@ -547,17 +541,20 @@ runPingPong() $VG_PING_T ./ping 1 10 t PongRead PongWrite sleep 4 + + waitForProcessTermination $cmd_pid 30 } runTutorial() { echo start MessageBoard $VG_MESSAGEBOARD ./MessageBoard& - + mboard_pid=$! sleep 7 echo start UserLoad $VG_USERLOAD ./UserLoad& + uload_pid=$! sleep 2 @@ -570,4 +567,7 @@ runTutorial() $VG_CHATTER_T ./Chatter -1 sleep 4 + + waitForProcessTermination $mboard_pid 30 + waitForProcessTermination $uload_pid 30 } diff --git a/build/scripts/overnight/example_automation_scripts/examples/protobuf/java5/RUN b/build/scripts/overnight/example_automation_scripts/examples/protobuf/java5/RUN new file mode 100644 index 000000000..4978f7f76 --- /dev/null +++ b/build/scripts/overnight/example_automation_scripts/examples/protobuf/java5/RUN @@ -0,0 +1,16 @@ +. $OSPL_HOME/examples/functions + +check_osplhome + +get_libjsig + +startOSPL + +export LD_PRELOAD=$OSPL_JSIG + +java -jar sub/java5_protobuf_sub.jar & +java -jar pub/java5_protobuf_pub.jar + +sleep 4 + +stopOSPL \ No newline at end of file diff --git a/build/scripts/overnight/example_automation_scripts/examples/protobuf/java5/RUN.bat b/build/scripts/overnight/example_automation_scripts/examples/protobuf/java5/RUN.bat new file mode 100644 index 000000000..9483a740d --- /dev/null +++ b/build/scripts/overnight/example_automation_scripts/examples/protobuf/java5/RUN.bat @@ -0,0 +1,19 @@ +@ECHO OFF +SETLOCAL +echo "==== Calling check_osplhome====" +call %FUNCTIONS% :check_osplhome + +echo "====Calling stopOSPL ====" +call %FUNCTIONS% :stopOSPL + +echo "==== Calling startOSPL ====" +call %FUNCTIONS% :startOSPL + +echo "==== start ProtobufSubscriber ====" +start /B java -jar sub/java5_protobuf_sub.jar > subResult.txt + +echo "==== start ProtobufPublisher ====" +java -jar pub/java5_protobuf_pub.jar > pubResult.txt + +echo "====Calling stopOSPL ====" +call %FUNCTIONS% :stopOSPL \ No newline at end of file diff --git a/build/scripts/overnight/example_automation_scripts/examples/streams/Throughput/isocpp/RUN b/build/scripts/overnight/example_automation_scripts/examples/streams/Throughput/isocpp/RUN deleted file mode 100755 index bd3fd7532..000000000 --- a/build/scripts/overnight/example_automation_scripts/examples/streams/Throughput/isocpp/RUN +++ /dev/null @@ -1,23 +0,0 @@ -. $OSPL_HOME/examples/functions - -check_osplhome - -NAME=StreamsThroughput - -startOSPL - -runZeroStreamsThroughput - -echo "=== Checking $NAME results" - -NUMLINES=`grep Payload subResult.txt | wc -l`; echo NUMLINES=$NUMLINES - -if [ $NUMLINES -ne 10 ] -then - echo NOK - echo "*** ERROR : example $NAME failed " -else - echo OK -fi - -stopOSPL diff --git a/build/scripts/overnight/example_automation_scripts/examples/streams/Throughput/isocpp/RUN.bat b/build/scripts/overnight/example_automation_scripts/examples/streams/Throughput/isocpp/RUN.bat deleted file mode 100755 index cebede2ee..000000000 --- a/build/scripts/overnight/example_automation_scripts/examples/streams/Throughput/isocpp/RUN.bat +++ /dev/null @@ -1,9 +0,0 @@ -@echo OFF -SETLOCAL - -set EXAMPLE_LANG=isocpp -set NAME=StreamsThroughtput - -call %FUNCTIONS% :runZeroStreamsThroughput - -call %FUNCTIONS% :checkResultZero diff --git a/build/scripts/overnight/example_automation_scripts/examples/streams/Throughput/isocpp/RUNPUB.bat b/build/scripts/overnight/example_automation_scripts/examples/streams/Throughput/isocpp/RUNPUB.bat deleted file mode 100755 index 3c9c97f69..000000000 --- a/build/scripts/overnight/example_automation_scripts/examples/streams/Throughput/isocpp/RUNPUB.bat +++ /dev/null @@ -1,2 +0,0 @@ -call publisher.exe 1 10 0 15 > pubResult.txt 2>&1 -echo %errorlevel% > pubReturn.txt 2>&1 diff --git a/build/scripts/overnight/example_results_fns b/build/scripts/overnight/example_results_fns index 4f7332b35..14879334d 100644 --- a/build/scripts/overnight/example_results_fns +++ b/build/scripts/overnight/example_results_fns @@ -102,7 +102,9 @@ check_example_result() NWINTERFACE=`grep -i "using network interface" ./ospl-info.log | grep -c "selected arbitrarily from"` DURABLITYRESEND=`grep -i "Already tried to resend .* message" ./ospl-info.log | grep -c "times"` DURABILITYFSEND=`grep -i "Failed to send d_sampleChain message with result 'U_RESULT_TIMEOUT'" ./ospl-info.log | grep -c "Failed to send"` - CONCESSIONED=`expr $NONRESP + $SENDKILL + $TIMEJUMP + $NWINTERFACE + $DURABLITYRESEND + $DURABILITYFSEND` + THREADNOPROGRESS=`grep -i "thread .* failed to make progress" ./ospl-info.log | grep -c "thread"` + THREADPROGRESS=`grep -i "thread .* once again made progress" ./ospl-info.log | grep -c "thread"` + CONCESSIONED=`expr $NONRESP + $SENDKILL + $TIMEJUMP + $NWINTERFACE + $DURABLITYRESEND + $DURABILITYFSEND + $THREADNOPROGRESS + $THREADPROGRESS` if [ "$WARNINGS" = "$CONCESSIONED" ] then MESSAGE="$MESSAGE $WARNINGS WARNINGS in ospl-info.log - all are concessioned - OK" diff --git a/build/scripts/overnight/getInstallers b/build/scripts/overnight/getInstallers index 99b72d9ed..50c4c5cf4 100755 --- a/build/scripts/overnight/getInstallers +++ b/build/scripts/overnight/getInstallers @@ -27,7 +27,7 @@ else REL_DIR=$VERSION fi -ssh -i ~/.ssh/id_rsa_releases releases@repository2 'cd Vortex/OpenSplice/; mkdir ' ${REL_DIR} '' +ssh -i ~/.ssh/id_rsa_releases releases@releases 'cd Vortex/OpenSplice/; mkdir ' ${REL_DIR} '' echo "This script retrieves most of the installers and logs that are required for a release from the overnight scoreboard.\n" echo "It is retrieving using the following linux6.prismtech.com:81/results/overnight/osplo/$YEAR/$MONTH/$DAY/$TYPE/$TAG\n" @@ -56,13 +56,13 @@ linux64Bit=("rhel54/rhel54-64c/x86_64.linux-release/distro/P615-VortexOpenSplice "ubuntu1204/ubuntu1204-64/x86_64.linux-release-notest/distro/P665-VortexOpenSplice-$VERSION-RTS-x86_64.linux-gcc4.6-glibc2.15-installer-lgpl.run" "ubuntu1204/ubuntu1204-64/x86_64.linux-release-notest/distro/P665-VortexOpenSplice-$VERSION-RTS-x86_64.linux-gcc4.6-glibc2.15-installer.run") -ssh -i ~/.ssh/id_rsa_releases releases@repository2 'cd Vortex/OpenSplice/; cd' ${REL_DIR} '; mkdir LINUX-64Bit' +ssh -i ~/.ssh/id_rsa_releases releases@releases 'cd Vortex/OpenSplice/; cd' ${REL_DIR} '; mkdir LINUX-64Bit' for instName in "${linux64Bit[@]}" do fullInstName=http://linux6.prismtech.com:81/results/overnight/osplo/$YEAR/$MONTH/$DAY/$TYPE/$TAG/"$instName" - ssh -i ~/.ssh/id_rsa_releases releases@repository2 'cd Vortex/OpenSplice/; cd' ${REL_DIR} '; cd LINUX-64Bit; wget -q http://linux6.prismtech.com:81/results/overnight/osplo/' ${fullInstName} '; chmod 755 *; rm index.html' + ssh -i ~/.ssh/id_rsa_releases releases@releases 'cd Vortex/OpenSplice/; cd' ${REL_DIR} '; cd LINUX-64Bit; wget -q http://linux6.prismtech.com:81/results/overnight/osplo/' ${fullInstName} '; chmod 755 *; rm index.html' if [ $? != 0 ] then @@ -70,7 +70,7 @@ do fi done -ssh -i ~/.ssh/id_rsa_releases releases@repository2 'cd Vortex/OpenSplice/; cd' ${REL_DIR} '; mkdir LINUX-32Bit' +ssh -i ~/.ssh/id_rsa_releases releases@releases 'cd Vortex/OpenSplice/; cd' ${REL_DIR} '; mkdir LINUX-32Bit' linux32Bit=("rhel6/rhel62a/x86.linux-release/distro/P641-VortexOpenSplice-$VERSION-HDE-x86.linux-gcc4.4.6-glibc2.12-installer-eval.run" @@ -103,7 +103,7 @@ for instName in "${linux32Bit[@]}" do fullInstName=http://linux6.prismtech.com:81/results/overnight/osplo/$YEAR/$MONTH/$DAY/$TYPE/$TAG/"$instName" - ssh -i ~/.ssh/id_rsa_releases releases@repository2 'cd Vortex/OpenSplice/; cd' ${REL_DIR} '; cd LINUX-32Bit; wget -q http://linux6.prismtech.com:81/results/overnight/osplo/' ${fullInstName} '; chmod 755 *; rm index.html' + ssh -i ~/.ssh/id_rsa_releases releases@releases 'cd Vortex/OpenSplice/; cd' ${REL_DIR} '; cd LINUX-32Bit; wget -q http://linux6.prismtech.com:81/results/overnight/osplo/' ${fullInstName} '; chmod 755 *; rm index.html' if [ $? != 0 ] then @@ -111,7 +111,7 @@ do fi done -ssh -i ~/.ssh/id_rsa_releases releases@repository2 'cd Vortex/OpenSplice/; cd' ${REL_DIR} '; mkdir WINDOWS-2008' +ssh -i ~/.ssh/id_rsa_releases releases@releases 'cd Vortex/OpenSplice/; cd' ${REL_DIR} '; mkdir WINDOWS-2008' win2008=("Win2003/dds3-win2k3/x86.win32-release/distro/P616-VortexOpenSplice-$VERSION-HDE-x86.win-vs2008-installer-eval.exe" "Win2003/dds3-win2k3/x86.win32-release/distro/P616-VortexOpenSplice-$VERSION-HDE-x86.win-vs2008-installer-lgpl.exe" @@ -123,14 +123,14 @@ for instName in "${win2008[@]}" do fullInstName=http://linux6.prismtech.com:81/results/overnight/osplo/$YEAR/$MONTH/$DAY/$TYPE/$TAG/"$instName" - ssh -i ~/.ssh/id_rsa_releases releases@repository2 'cd Vortex/OpenSplice/; cd' ${REL_DIR} '; cd WINDOWS-2008; wget -q http://linux6.prismtech.com:81/results/overnight/osplo/' ${fullInstName} '; chmod 755 *; rm index.html' + ssh -i ~/.ssh/id_rsa_releases releases@releases 'cd Vortex/OpenSplice/; cd' ${REL_DIR} '; cd WINDOWS-2008; wget -q http://linux6.prismtech.com:81/results/overnight/osplo/' ${fullInstName} '; chmod 755 *; rm index.html' if [ $? != 0 ] then echo "${instName}" >> $WORKSPACE/MissingBuilds.txt fi done -ssh -i ~/.ssh/id_rsa_releases releases@repository2 'cd Vortex/OpenSplice/; cd' ${REL_DIR} '; mkdir WINDOWS-2010' +ssh -i ~/.ssh/id_rsa_releases releases@releases 'cd Vortex/OpenSplice/; cd' ${REL_DIR} '; mkdir WINDOWS-2010' win2010=("Windows7/win7-32-ospl-4/x86.win32-release-vs10/distro/P637-VortexOpenSplice-$VERSION-HDE-x86.win-vs2010-installer-eval.exe" "Windows7/win7-32-ospl-4/x86.win32-release-vs10/distro/P637-VortexOpenSplice-$VERSION-HDE-x86.win-vs2010-installer-lgpl.exe" @@ -147,7 +147,7 @@ for instName in "${win2010[@]}" do fullInstName=http://linux6.prismtech.com:81/results/overnight/osplo/$YEAR/$MONTH/$DAY/$TYPE/$TAG/"$instName" - ssh -i ~/.ssh/id_rsa_releases releases@repository2 'cd Vortex/OpenSplice/; cd' ${REL_DIR} '; cd WINDOWS-2010; wget -q http://linux6.prismtech.com:81/results/overnight/osplo/' ${fullInstName} '; chmod 755 *; rm index.html' + ssh -i ~/.ssh/id_rsa_releases releases@releases 'cd Vortex/OpenSplice/; cd' ${REL_DIR} '; cd WINDOWS-2010; wget -q http://linux6.prismtech.com:81/results/overnight/osplo/' ${fullInstName} '; chmod 755 *; rm index.html' if [ $? != 0 ] then @@ -155,7 +155,7 @@ do fi done -ssh -i ~/.ssh/id_rsa_releases releases@repository2 'cd Vortex/OpenSplice/; cd' ${REL_DIR} '; mkdir WINDOWS-2012' +ssh -i ~/.ssh/id_rsa_releases releases@releases 'cd Vortex/OpenSplice/; cd' ${REL_DIR} '; mkdir WINDOWS-2012' win2012=("Windows7/win7b/x86.win32-release-vs11/distro/P669-VortexOpenSplice-$VERSION-HDE-x86.win-vs2012-installer-eval.exe" "Windows7/win7b/x86.win32-release-vs11/distro/P669-VortexOpenSplice-$VERSION-HDE-x86.win-vs2012-installer-lgpl.exe" @@ -172,7 +172,7 @@ for instName in "${win2012[@]}" do fullInstName=http://linux6.prismtech.com:81/results/overnight/osplo/$YEAR/$MONTH/$DAY/$TYPE/$TAG/"$instName" - ssh -i ~/.ssh/id_rsa_releases releases@repository2 'cd Vortex/OpenSplice/; cd' ${REL_DIR} '; cd WINDOWS-2012; wget -q http://linux6.prismtech.com:81/results/overnight/osplo/' ${fullInstName} '; chmod 755 *; rm index.html' + ssh -i ~/.ssh/id_rsa_releases releases@releases 'cd Vortex/OpenSplice/; cd' ${REL_DIR} '; cd WINDOWS-2012; wget -q http://linux6.prismtech.com:81/results/overnight/osplo/' ${fullInstName} '; chmod 755 *; rm index.html' if [ $? != 0 ] then @@ -180,7 +180,7 @@ do fi done -ssh -i ~/.ssh/id_rsa_releases releases@repository2 'cd Vortex/OpenSplice/; cd' ${REL_DIR} '; mkdir WINDOWS-2013' +ssh -i ~/.ssh/id_rsa_releases releases@releases 'cd Vortex/OpenSplice/; cd' ${REL_DIR} '; mkdir WINDOWS-2013' win2013=("Windows7/win7c/x86.win32-release-vs12/distro/P671-VortexOpenSplice-$VERSION-HDE-x86.win-vs2013-installer-eval.exe" @@ -198,7 +198,7 @@ for instName in "${win2013[@]}" do fullInstName=http://linux6.prismtech.com:81/results/overnight/osplo/$YEAR/$MONTH/$DAY/$TYPE/$TAG/"$instName" - ssh -i ~/.ssh/id_rsa_releases releases@repository2 'cd Vortex/OpenSplice/; cd' ${REL_DIR} '; cd WINDOWS-2013; wget -q http://linux6.prismtech.com:81/results/overnight/osplo/' ${fullInstName} '; chmod 755 *; rm index.html' + ssh -i ~/.ssh/id_rsa_releases releases@releases 'cd Vortex/OpenSplice/; cd' ${REL_DIR} '; cd WINDOWS-2013; wget -q http://linux6.prismtech.com:81/results/overnight/osplo/' ${fullInstName} '; chmod 755 *; rm index.html' if [ $? != 0 ] then @@ -206,7 +206,7 @@ do fi done -ssh -i ~/.ssh/id_rsa_releases releases@repository2 'cd Vortex/OpenSplice/; cd' ${REL_DIR} '; mkdir SOLARIS-10' +ssh -i ~/.ssh/id_rsa_releases releases@releases 'cd Vortex/OpenSplice/; cd' ${REL_DIR} '; mkdir SOLARIS-10' sol10=("Solaris10/v240a/studio12-release/distro/P610-VortexOpenSplice-$VERSION-HDE-solaris10_studio12.2-installer-eval.run" "Solaris10/v240a/studio12-release/distro/P610-VortexOpenSplice-$VERSION-HDE-solaris10_studio12.2-installer-lgpl.run" @@ -223,7 +223,7 @@ for instName in "${sol10[@]}" do fullInstName=http://linux6.prismtech.com:81/results/overnight/osplo/$YEAR/$MONTH/$DAY/$TYPE/$TAG/"$instName" - ssh -i ~/.ssh/id_rsa_releases releases@repository2 'cd Vortex/OpenSplice/; cd' ${REL_DIR} '; cd SOLARIS-10; wget -q http://linux6.prismtech.com:81/results/overnight/osplo/' ${fullInstName} '; chmod 755 *; rm index.html' + ssh -i ~/.ssh/id_rsa_releases releases@releases 'cd Vortex/OpenSplice/; cd' ${REL_DIR} '; cd SOLARIS-10; wget -q http://linux6.prismtech.com:81/results/overnight/osplo/' ${fullInstName} '; chmod 755 *; rm index.html' if [ $? != 0 ] then @@ -231,7 +231,7 @@ do fi done -ssh -i ~/.ssh/id_rsa_releases releases@repository2 'cd Vortex/OpenSplice/; cd' ${REL_DIR} '; mkdir LINUX-32Bit-TAO161' +ssh -i ~/.ssh/id_rsa_releases releases@releases 'cd Vortex/OpenSplice/; cd' ${REL_DIR} '; mkdir LINUX-32Bit-TAO161' cof32bit=("rhel4/rhel4g/x86.linux-release/distro/P611-VortexOpenSplice-$VERSION-HDE-x86.linux-gcc3.4.6-glibc2.3.4-installer.run" "rhel4/rhel4g/x86.linux-release/distro/P611-VortexOpenSplice-$VERSION-RTS-x86.linux-gcc3.4.6-glibc2.3.4-installer.run" @@ -242,7 +242,7 @@ for instName in "${cof32bit[@]}" do fullInstName=http://linux6.prismtech.com:81/results/overnight/osplo/$YEAR/$MONTH/$DAY/$TYPE/$TAG/"$instName" - ssh -i ~/.ssh/id_rsa_releases releases@repository2 'cd Vortex/OpenSplice/; cd' ${REL_DIR} '; cd LINUX-32Bit-TAO161; wget -q http://linux6.prismtech.com:81/results/overnight/osplo/' ${fullInstName} '; chmod 755 *; rm index.html' + ssh -i ~/.ssh/id_rsa_releases releases@releases 'cd Vortex/OpenSplice/; cd' ${REL_DIR} '; cd LINUX-32Bit-TAO161; wget -q http://linux6.prismtech.com:81/results/overnight/osplo/' ${fullInstName} '; chmod 755 *; rm index.html' if [ $? != 0 ] then @@ -250,7 +250,7 @@ do fi done -ssh -i ~/.ssh/id_rsa_releases releases@repository2 'cd Vortex/OpenSplice/; cd' ${REL_DIR} '; mkdir LINUX-64Bit-TAO161' +ssh -i ~/.ssh/id_rsa_releases releases@releases 'cd Vortex/OpenSplice/; cd' ${REL_DIR} '; mkdir LINUX-64Bit-TAO161' cof64bit=("rhel54/rhel54-64b/x86_64.linux-release-notest-TAO161/distro/P615-VortexOpenSplice-$VERSION-HDE-x86_64.linux-gcc4.1.2-glibc2.5-installer.run" "rhel54/rhel54-64b/x86_64.linux-release-notest-TAO161/distro/P615-VortexOpenSplice-$VERSION-RTS-x86_64.linux-gcc4.1.2-glibc2.5-installer.run" @@ -261,7 +261,7 @@ for instName in "${cof64bit[@]}" do fullInstName=http://linux6.prismtech.com:81/results/overnight/osplo/$YEAR/$MONTH/$DAY/$TYPE/$TAG/"$instName" - ssh -i ~/.ssh/id_rsa_releases releases@repository2 'cd Vortex/OpenSplice/; cd' ${REL_DIR} '; cd LINUX-64Bit-TAO161; wget -q http://linux6.prismtech.com:81/results/overnight/osplo/' ${fullInstName} '; chmod 755 *; rm index.html' + ssh -i ~/.ssh/id_rsa_releases releases@releases 'cd Vortex/OpenSplice/; cd' ${REL_DIR} '; cd LINUX-64Bit-TAO161; wget -q http://linux6.prismtech.com:81/results/overnight/osplo/' ${fullInstName} '; chmod 755 *; rm index.html' if [ $? != 0 ] then @@ -269,7 +269,7 @@ do fi done -ssh -i ~/.ssh/id_rsa_releases releases@repository2 'cd Vortex/OpenSplice/; cd' ${REL_DIR} '; mkdir RTE' +ssh -i ~/.ssh/id_rsa_releases releases@releases 'cd Vortex/OpenSplice/; cd' ${REL_DIR} '; mkdir RTE' rte=("WinXP/winxp13-new/E500v2.vxworks6.9.4.1-release/distro/P655-VortexOpenSpliceRTE-$VERSION-HDE-x86.win-vs2005-RTS-E500v2.vxworks6.9-gcc-installer-lgpl.exe" "WinXP/winxp13-new/E500v2.vxworks6.9.4.1-release/distro/P655-VortexOpenSpliceRTE-$VERSION-HDE-x86.win-vs2005-RTS-E500v2.vxworks6.9-gcc-installer.exe" @@ -296,7 +296,7 @@ for instName in "${rte[@]}" do fullInstName=http://linux6.prismtech.com:81/results/overnight/osplo/$YEAR/$MONTH/$DAY/$TYPE/$TAG/"$instName" - ssh -i ~/.ssh/id_rsa_releases releases@repository2 'cd Vortex/OpenSplice/; cd' ${REL_DIR} '; cd RTE; wget -q http://linux6.prismtech.com:81/results/overnight/osplo/' ${fullInstName} '; chmod 755 *; rm index.html' + ssh -i ~/.ssh/id_rsa_releases releases@releases 'cd Vortex/OpenSplice/; cd' ${REL_DIR} '; cd RTE; wget -q http://linux6.prismtech.com:81/results/overnight/osplo/' ${fullInstName} '; chmod 755 *; rm index.html' if [ $? != 0 ] then @@ -304,7 +304,7 @@ do fi done -ssh -i ~/.ssh/id_rsa_releases releases@repository2 'cd Vortex/OpenSplice/; cd' ${REL_DIR} '; mkdir DEMOS' +ssh -i ~/.ssh/id_rsa_releases releases@releases 'cd Vortex/OpenSplice/; cd' ${REL_DIR} '; mkdir DEMOS' demos=("Windows7-64/win7-64-ospl-2/x86_64.win64-release-notest/distro/P638-VortexOpenSplice-$VERSION-DEMOS-x86_64.win-vs2010-installer.zip" "Windows7/win7-32-ospl-4/x86.win32-release-vs10/distro/P637-VortexOpenSplice-$VERSION-DEMOS-x86.win-vs2010-installer.zip" @@ -315,7 +315,7 @@ for instName in "${demos[@]}" do fullInstName=http://linux6.prismtech.com:81/results/overnight/osplo/$YEAR/$MONTH/$DAY/$TYPE/$TAG/"$instName" - ssh -i ~/.ssh/id_rsa_releases releases@repository2 'cd Vortex/OpenSplice/; cd' ${REL_DIR} '; cd DEMOS; wget -q http://linux6.prismtech.com:81/results/overnight/osplo/' ${fullInstName} '; chmod 755 *; rm index.html' + ssh -i ~/.ssh/id_rsa_releases releases@releases 'cd Vortex/OpenSplice/; cd' ${REL_DIR} '; cd DEMOS; wget -q http://linux6.prismtech.com:81/results/overnight/osplo/' ${fullInstName} '; chmod 755 *; rm index.html' if [ $? != 0 ] then @@ -323,7 +323,7 @@ do fi done -ssh -i ~/.ssh/id_rsa_releases releases@repository2 'cd Vortex/OpenSplice/; cd' ${REL_DIR} '; mkdir STE' +ssh -i ~/.ssh/id_rsa_releases releases@releases 'cd Vortex/OpenSplice/; cd' ${REL_DIR} '; mkdir STE' ste=("Windows7-64/win7-64-ospl-2/x86_64.win64-release-notest/distro/P638-VortexOpenSplice-$VERSION-STE-x86_64.win-vs2010-installer.exe" "Windows7/win7-32-ospl-4/x86.win32-release-vs10/distro/P637-VortexOpenSplice-$VERSION-STE-x86.win-vs2010-installer.exe" @@ -334,7 +334,7 @@ for instName in "${ste[@]}" do fullInstName=http://linux6.prismtech.com:81/results/overnight/osplo/$YEAR/$MONTH/$DAY/$TYPE/$TAG/"$instName" - ssh -i ~/.ssh/id_rsa_releases releases@repository2 'cd Vortex/OpenSplice/; cd' ${REL_DIR} '; cd STE; wget -q http://linux6.prismtech.com:81/results/overnight/osplo/' ${fullInstName} '; chmod 755 *; rm index.html' + ssh -i ~/.ssh/id_rsa_releases releases@releases 'cd Vortex/OpenSplice/; cd' ${REL_DIR} '; cd STE; wget -q http://linux6.prismtech.com:81/results/overnight/osplo/' ${fullInstName} '; chmod 755 *; rm index.html' if [ $? != 0 ] then @@ -342,7 +342,7 @@ do fi done -ssh -i ~/.ssh/id_rsa_releases releases@repository2 'cd Vortex/OpenSplice/; cd' ${REL_DIR} '; mkdir logs; cd logs; mkdir LINUX32BitLogs; mkdir LINUX64BitLogs' +ssh -i ~/.ssh/id_rsa_releases releases@releases 'cd Vortex/OpenSplice/; cd' ${REL_DIR} '; mkdir logs; cd logs; mkdir LINUX32BitLogs; mkdir LINUX64BitLogs' logs64bit=("rhel6/rhel62-64b/x86_64.linux-release/logs/build.txt" "rhel6/rhel62-64b/x86_64.linux-release/logs/DBT-Results/dbt.log" @@ -357,7 +357,7 @@ for logName in "${logs64bit[@]}" do fulllogName=http://linux6.prismtech.com:81/results/overnight/osplo/$YEAR/$MONTH/$DAY/$TYPE/$TAG/"$logName" - ssh -i ~/.ssh/id_rsa_releases releases@repository2 'cd Vortex/OpenSplice/; cd' ${REL_DIR}'/logs/LINUX64BitLogs; wget -q http://linux6.prismtech.com:81/results/overnight/osplo/' ${fulllogName} '; rm index.html' + ssh -i ~/.ssh/id_rsa_releases releases@releases 'cd Vortex/OpenSplice/; cd' ${REL_DIR}'/logs/LINUX64BitLogs; wget -q http://linux6.prismtech.com:81/results/overnight/osplo/' ${fulllogName} '; rm index.html' if [ $? != 0 ] then @@ -367,7 +367,7 @@ done date=$YEAR$MONTH$DAY -ssh -i ~/.ssh/id_rsa_releases releases@repository2 'cd Vortex/OpenSplice/; cd' ${REL_DIR}'/logs/LINUX64BitLogs; mv RBT_'${date}'.log SHM-RBT_'${date}'.log; mv RBTmetrics_'${date}'.txt SHM-RBTmetrics_'${date}'.txt ; mv RBTtestinfo_'${date}'.txt SHM-RBTtestinfo_'${date}'.txt ; mv examples.log SHM-examples.log' +ssh -i ~/.ssh/id_rsa_releases releases@releases 'cd Vortex/OpenSplice/; cd' ${REL_DIR}'/logs/LINUX64BitLogs; mv RBT_'${date}'.log SHM-RBT_'${date}'.log; mv RBTmetrics_'${date}'.txt SHM-RBTmetrics_'${date}'.txt ; mv RBTtestinfo_'${date}'.txt SHM-RBTtestinfo_'${date}'.txt ; mv examples.log SHM-examples.log' logssp64bit=("rhel6/rhel62-64b/x86_64.linux-release/logs/RBT-Results-SP/RBT_$YEAR$MONTH$DAY.log" "rhel6/rhel62-64b/x86_64.linux-release/logs/RBT-Results-SP/RBTmetrics_$YEAR$MONTH$DAY.txt" @@ -378,7 +378,7 @@ for logName in "${logssp64bit[@]}" do fulllogName=http://linux6.prismtech.com:81/results/overnight/osplo/$YEAR/$MONTH/$DAY/$TYPE/$TAG/"$logName" - ssh -i ~/.ssh/id_rsa_releases releases@repository2 'cd Vortex/OpenSplice/; cd' ${REL_DIR}'/logs/LINUX64BitLogs; wget -q http://linux6.prismtech.com:81/results/overnight/osplo/' ${fulllogName} '; rm index.html' + ssh -i ~/.ssh/id_rsa_releases releases@releases 'cd Vortex/OpenSplice/; cd' ${REL_DIR}'/logs/LINUX64BitLogs; wget -q http://linux6.prismtech.com:81/results/overnight/osplo/' ${fulllogName} '; rm index.html' if [ $? != 0 ] then @@ -386,7 +386,7 @@ do fi done -ssh -i ~/.ssh/id_rsa_releases releases@repository2 'cd Vortex/OpenSplice/; cd' ${REL_DIR}'/logs/LINUX64BitLogs; mv RBT_'${date}'.log SP-RBT_'${date}'.log; mv RBTmetrics_'${date}'.txt SP-RBTmetrics_'${date}'.txt ; mv RBTtestinfo_'${date}'.txt SP-RBTtestinfo_'${date}'.txt; mv examples.log SP-examples.log' +ssh -i ~/.ssh/id_rsa_releases releases@releases 'cd Vortex/OpenSplice/; cd' ${REL_DIR}'/logs/LINUX64BitLogs; mv RBT_'${date}'.log SP-RBT_'${date}'.log; mv RBTmetrics_'${date}'.txt SP-RBTmetrics_'${date}'.txt ; mv RBTtestinfo_'${date}'.txt SP-RBTtestinfo_'${date}'.txt; mv examples.log SP-examples.log' logs32bit=("rhel6/rhel62a/x86.linux-release/logs/build.txt" "rhel6/rhel62a/x86.linux-release/logs/DBT-Results/dbt.log" @@ -401,7 +401,7 @@ for logName in "${logs32bit[@]}" do fulllogName=http://linux6.prismtech.com:81/results/overnight/osplo/$YEAR/$MONTH/$DAY/$TYPE/$TAG/"$logName" - ssh -i ~/.ssh/id_rsa_releases releases@repository2 'cd Vortex/OpenSplice/; cd' ${REL_DIR}'/logs/LINUX32BitLogs; wget -q http://linux6.prismtech.com:81/results/overnight/osplo/' ${fulllogName} '; rm index.html' + ssh -i ~/.ssh/id_rsa_releases releases@releases 'cd Vortex/OpenSplice/; cd' ${REL_DIR}'/logs/LINUX32BitLogs; wget -q http://linux6.prismtech.com:81/results/overnight/osplo/' ${fulllogName} '; rm index.html' if [ $? != 0 ] then @@ -409,7 +409,7 @@ do fi done -ssh -i ~/.ssh/id_rsa_releases releases@repository2 'cd Vortex/OpenSplice/; cd' ${REL_DIR}'/logs/LINUX32BitLogs; mv RBT_'${date}'.log SHM-RBT_'${date}'.log; mv RBTmetrics_'${date}'.txt SHM-RBTmetrics_'${date}'.txt ; mv RBTtestinfo_'${date}'.txt SHM-RBTtestinfo_'${date}'.txt; mv examples.log SHM-examples.log' +ssh -i ~/.ssh/id_rsa_releases releases@releases 'cd Vortex/OpenSplice/; cd' ${REL_DIR}'/logs/LINUX32BitLogs; mv RBT_'${date}'.log SHM-RBT_'${date}'.log; mv RBTmetrics_'${date}'.txt SHM-RBTmetrics_'${date}'.txt ; mv RBTtestinfo_'${date}'.txt SHM-RBTtestinfo_'${date}'.txt; mv examples.log SHM-examples.log' logssp32bit=("rhel6/rhel62a/x86.linux-release/logs/RBT-Results-SP/RBT_$YEAR$MONTH$DA.log" "rhel6/rhel62a/x86.linux-release/logs/RBT-Results-SP/RBTmetrics_$YEAR$MONTH$DAY.txt" @@ -420,7 +420,7 @@ for logName in "${logssp32bit[@]}" do fulllogName=http://linux6.prismtech.com:81/results/overnight/osplo/$YEAR/$MONTH/$DAY/$TYPE/$TAG/"$logName" - ssh -i ~/.ssh/id_rsa_releases releases@repository2 'cd Vortex/OpenSplice/; cd' ${REL_DIR}'/logs/LINUX32BitLogs; wget -q http://linux6.prismtech.com:81/results/overnight/osplo/' ${fulllogName} '; rm index.html' + ssh -i ~/.ssh/id_rsa_releases releases@releases 'cd Vortex/OpenSplice/; cd' ${REL_DIR}'/logs/LINUX32BitLogs; wget -q http://linux6.prismtech.com:81/results/overnight/osplo/' ${fulllogName} '; rm index.html' if [ $? != 0 ] then @@ -428,4 +428,4 @@ do fi done -ssh -i ~/.ssh/id_rsa_releases releases@repository2 'cd Vortex/OpenSplice/; cd' ${REL_DIR}'/logs/LINUX32BitLogs; mv RBT_'${date}'.log SP-RBT_'${date}'.log; mv RBTmetrics_'${date}'.txt SP-RBTmetrics_'${date}'.txt ; mv RBTtestinfo_'${date}'.txt SP-RBTtestinfo_'${date}'.txt; mv examples.log SP-examples.log' +ssh -i ~/.ssh/id_rsa_releases releases@releases 'cd Vortex/OpenSplice/; cd' ${REL_DIR}'/logs/LINUX32BitLogs; mv RBT_'${date}'.log SP-RBT_'${date}'.log; mv RBTmetrics_'${date}'.txt SP-RBTmetrics_'${date}'.txt ; mv RBTtestinfo_'${date}'.txt SP-RBTtestinfo_'${date}'.txt; mv examples.log SP-examples.log' diff --git a/build/scripts/overnight/python/DBMSConnect.py b/build/scripts/overnight/python/DBMSConnect.py index 5e2512def..a355db34e 100644 --- a/build/scripts/overnight/python/DBMSConnect.py +++ b/build/scripts/overnight/python/DBMSConnect.py @@ -3,6 +3,8 @@ import json import shutil import subprocess +import fileinput +import platform import time from shutil import copy import example_logparser @@ -50,12 +52,11 @@ def __init__(self, host, logger): def runExample(self): - print("In runExample for " + self.expath + ": " + self.name) + print "In runExample for " + self.expath + ": " + self.name currPath = os.getcwd() try: - self.exdir = "servicesdbmsconnectSQLCPPODBC" exSfx = "" @@ -69,10 +70,16 @@ def runExample(self): msg = "NONE" result = "PASS" + dsn = self.odbcMsgBoard_params[0] + os.putenv("MY_DSN", dsn); + os.environ["MY_DSN"]= dsn; + os.putenv("OSPL_URI", self.uri) os.environ["OSPL_URI"] = self.uri try: + self.convertConfig() + self.setLogPathAndLogs("", "") odbcMsgBoardLog = os.path.join(self.pPath, 'odbcMsgBoard.log') odbcChatter1Log = os.path.join(self.pPath, 'odbcChatter1.log') @@ -179,7 +186,7 @@ def runExample(self): try: self.stopOSPL() except Exception as ex: - print("Exception stopping OpenSplice ", str(ex)) + print "Exception stopping OpenSplice ", str(ex) if msg == "NONE": try: @@ -190,13 +197,13 @@ def runExample(self): if os.path.isfile (self.ospl_error_log): msg = "ospl-error.log found" - print("checking odbcMsgBoardLog with odbcmsgboard_conds", odbcMsgBoardLog, odbcmsgboard_conds) + print "checking odbcMsgBoardLog with odbcmsgboard_conds", odbcMsgBoardLog, odbcmsgboard_conds self.checkResults(odbcMsgBoardLog, odbcmsgboard_conds) - print("checking odbcChatter1Log with odbcchatter_conds", odbcChatter1Log, odbcchatter_conds) + print "checking odbcChatter1Log with odbcchatter_conds", odbcChatter1Log, odbcchatter_conds self.checkResults(odbcChatter1Log, odbcchatter_conds) - print("checking odbcChatter2Log with odbcchatter_conds", odbcChatter2Log, odbcchatter_conds) + print "checking odbcChatter2Log with odbcchatter_conds", odbcChatter2Log, odbcchatter_conds self.checkResults(odbcChatter2Log, odbcchatter_conds) self.checkResults(cppMsgBoardLog, cppmsgboard_conds) @@ -215,7 +222,7 @@ def runExample(self): logdir = os.path.join(os.environ['LOGDIR'], "examples", "run_" + os.environ['EXRUNTYPE'], self.exdir) dbmsconnLog = os.path.join(self.pPath, 'dbmsconnect.log') - print("dbmsconnect.log is ", dbmsconnLog) + print "dbmsconnect.log is ", dbmsconnLog copy(dbmsconnLog, logdir) @@ -225,14 +232,32 @@ def runExample(self): try: self.writeResult (result, self.exdir, "", msg) except Exception as ex: - print("Exception writing result", str(ex)) + print "Exception writing result", str(ex) try: self.cleanUp() except Exception as ex: - print("Exception cleaning up", str(ex)) + print "Exception cleaning up", str(ex) except Exception as ex: - print("Unexpected exception ", str(ex)) + print "Unexpected exception ", str(ex) finally: - os.chdir(currPath) + os.chdir(currPath) + + def convertConfig(self): + if os.environ['EXRUNTYPE'] == "shm": + uri = self.shm_uri + else: + uri = self.sp_uri + fcfg = os.path.join(os.environ['OSPL_HOME'], 'examples', 'services', 'dbmsconnect', uri) + forig = os.path.join(os.environ['OSPL_HOME'], 'examples', 'services', 'dbmsconnect', uri+'.orig') + os.rename(fcfg, forig) + if self.host.name != "default": + hn = self.host.name + else: + hn = platform.uname()[1] + prefix = hn[:16].replace('-', '_') + '_' + fout = open(fcfg, "w") + for line in fileinput.input(forig): + fout.write(line.replace("Sql", prefix)) + fout.close() diff --git a/build/scripts/overnight/python/Durability.py b/build/scripts/overnight/python/Durability.py index 159f62518..aef607276 100644 --- a/build/scripts/overnight/python/Durability.py +++ b/build/scripts/overnight/python/Durability.py @@ -35,23 +35,23 @@ def __init__(self, host, logger): def runExample(self, lang, extra, types): if lang == "cs" and not self.host.isWindows(): - print("C# not supported on " + self.host.name) + print "C# not supported on " + self.host.name else: if lang == "all": self.runExampleAll(extra) - else: + else: if extra == "all": self.runExampleAllExtra(lang, extra, types) else: - print("In runExample for " + self.expath + ": " + self.name + ": " + lang + ":" + extra) + print "In runExample for " + self.expath + ": " + self.name + ": " + lang + ":" + extra currPath = os.getcwd() try: super(durability, self).setExampleResultDir(lang, extra) exSfx = "" - + if self.host.isWindows() and not "java" in lang: exSfx = ".exe" @@ -79,8 +79,8 @@ def runExample(self, lang, extra, types): if os.path.isdir(tmpDir): shutil.rmtree (tmpDir) except: - print("Failed to remove", tmpDir) - + print "Failed to remove", tmpDir + with open ('examples.json') as data_file: data = json.load(data_file) @@ -109,7 +109,7 @@ def runExample(self, lang, extra, types): else: pubExe = subName - if msg == "NONE": + if msg == "NONE": transSub1_Thread = ExeThread(self.classpath, transSub1Log, lang, subExe, self.transSub_params, self.example_timeout * 2) transSub2_Thread = ExeThread(self.classpath, transSub2Log, lang, subExe, self.transSub_params, self.example_timeout * 2) transSub3_Thread = ExeThread(self.classpath, transSub3Log, lang, subExe, self.transSub_params, self.example_timeout * 2) @@ -120,14 +120,15 @@ def runExample(self, lang, extra, types): pub1Thread = ExeThread(self.classpath, pub1Log, lang, pubExe, self.pub1_params, self.example_timeout * 2) pub2Thread = ExeThread(self.classpath, pub2Log, lang, pubExe, self.pub2_params, self.example_timeout * 2) pub3Thread = ExeThread(self.classpath, pub3Log, lang, pubExe, self.pub3_params, self.example_timeout * 2) - os.chdir(self.pPath) + os.chdir(self.pPath) self.startOSPL() transSub1_Thread.start() pub1Thread.start() - + pub1Thread.join(self.example_timeout) + transSub1_Thread.join(self.example_timeout) self.stopOSPL() @@ -136,9 +137,11 @@ def runExample(self, lang, extra, types): pub2Thread.start() time.sleep(2) - transSub3_Thread.start() - + transSub3_Thread.start() + pub2Thread.join(self.example_timeout) + transSub2_Thread.join(self.example_timeout) + transSub3_Thread.join(self.example_timeout) self.stopOSPL() @@ -147,6 +150,7 @@ def runExample(self, lang, extra, types): persSub1_Thread.start() pub3Thread.start() pub3Thread.join(self.example_timeout) + persSub1_Thread.join(self.example_timeout) self.stopOSPL() @@ -161,7 +165,7 @@ def runExample(self, lang, extra, types): try: self.stopOSPL() except Exception as ex: - print("Exception stopping OpenSplice ", str(ex)) + print "Exception stopping OpenSplice ", str(ex) if msg == "NONE": try: @@ -174,7 +178,7 @@ def runExample(self, lang, extra, types): # the java versions of the Durability example do not write anything # to the publisher output log - so only check the publisher log if # the language is not a java language - if not "java" in lang: + if not "java" in lang: self.checkResults(pub1Log, pub_conds) self.checkResults(pub2Log, pub_conds) self.checkResults(pub3Log, pub_conds) @@ -196,21 +200,21 @@ def runExample(self, lang, extra, types): except Exception: msg = "Exception checking logs " + str(sys.exc_info()[0]) - + if msg != "NONE": result = "FAIL" try: self.writeResult (result, self.expath + self.name, lang, msg) except Exception as ex: - print("Exception writing result ", str(ex)) + print "Exception writing result ", str(ex) try: self.cleanUp() except Exception as ex: - print("Exception cleaning up ", str(ex)) + print "Exception cleaning up ", str(ex) except Exception as ex: - print("Unexpected exception", str(ex)) + print "Unexpected exception", str(ex) finally: - os.chdir(currPath) + os.chdir(currPath) diff --git a/build/scripts/overnight/python/Example.py b/build/scripts/overnight/python/Example.py old mode 100644 new mode 100755 index 9879ebf76..a345d5b51 --- a/build/scripts/overnight/python/Example.py +++ b/build/scripts/overnight/python/Example.py @@ -1,3 +1,4 @@ +import commands import sys import os import glob @@ -13,8 +14,9 @@ from example_exceptions import ExampleFail from ExampleLogger import examplelogger import pdb +import splicedCheck -""" +""" Main Example class which is the basis for most of the straightforward examples. If an example inolves just a single client/server, publisher/subscriber then this class can be used to run it. An entry should be made in the examples.json file for any new @@ -43,7 +45,7 @@ def __init__(self, host, logger, example, expath): # path to the example self.path = os.path.join(os.environ['OSPL_HOME'], 'examples', self.expath) - # languages this example runs in e.g. c / c++ / cs / java / java5 / isocpp / isocpp2 + # languages this example runs in e.g. c / c++ / cs / java / java5 / isocpp2 self.langs = data[expath][example]["langs"] # corba languages if the example has a corba version @@ -60,7 +62,7 @@ def __init__(self, host, logger, example, expath): # location of yaml file containing details of expected / allowed output self.example_conditions_path = "" - + # location of yaml file containing details of errors that are not accepted self.error_conditions_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'yaml', 'error_conditions.yaml') @@ -93,7 +95,7 @@ def __init__(self, host, logger, example, expath): # suffix for c language - used in results directory self.csfx = data["languages"]["c"]["prefix"] - # suffix for c++ language - used in results directory + # suffix for c++ language - used in results directory self.cppsfx = data["languages"]["cpp"]["prefix"] # suffix for corba c++ language - used in results directory @@ -106,7 +108,7 @@ def __init__(self, host, logger, example, expath): self.javasfx = data["languages"]["java"]["prefix"] # suffix for java5 language - used in results directory - self.java5sfx = data["languages"]["java5"]["prefix"] + self.java5sfx = data["languages"]["java5"]["prefix"] # suffix for corba java language - used in results directory self.cjsfx = data["languages"]["java"]["corba_prefix"] @@ -121,7 +123,7 @@ def __init__(self, host, logger, example, expath): # classpath - used for java examples - set at run time self.classpath = "" - # location of executables + # location of executables self.pPath = "" # example result directory @@ -133,6 +135,7 @@ def __init__(self, host, logger, example, expath): # set the OSPL_URI for this test self.setURI() + # Called by sub classes to set the path where it is non-standard e.g. DBMSConnect example def setPath(self, path): self.path = path @@ -140,9 +143,9 @@ def setPath(self, path): # Sets the OSPL_URI for this instance of the example def setURI(self): if self.shm_uri != "" and os.environ['EXRUNTYPE'] == "shm": - self.uri = "file://" + os.path.join(self.path, self.name, self.shm_uri) + self.uri = "file://" + os.path.join(self.path, self.name, self.shm_uri) elif self.sp_uri != "" and os.environ['EXRUNTYPE'] == "sp": - self.uri = "file://" + os.path.join(self.path, self.name, self.sp_uri) + self.uri = "file://" + os.path.join(self.path, self.name, self.sp_uri) else: self.uri = os.environ['OSPL_URI'] @@ -152,50 +155,54 @@ def runExampleAllTypes(self): self.extra can be set in .json file as standalone / corba. This does not apply to all examples and so will be an empty string if not found """ - if self.extra != "": + if self.extra != "": for ex in self.extra: - self.runExampleAll(ex) + self.runExampleAll(ex) else: - self.runExampleAll("") + self.runExampleAll("") """ Run all languages for type specified - extra can be + extra can be "all" - values obtained from the .json file "standalone" or "corba" - can be specified at the command line - "" - where there is no extra type e.g. for RoundTrip / Throughput + "" - where there is no extra type e.g. for RoundTrip / Throughput the runExample.py script will determine appropriate entry if none supplied on the command line """ def runExampleAll(self, extra): if extra == "all": - if self.extra != "": + if self.extra != "": for ex in self.extra: - self.runExampleAll(ex) + if "java5" in lang: + self.runExampleAll ("") + break + else: + self.runExampleAll(ex) else: self.runExampleAll ("") - else: + else: if extra == "corba": if self.corba_langs == "": - print("No corba version for " + self.name + " example") + print "No corba version for " + self.name + " example" else: # run the corba example for each language found for lang in self.corba_langs: if self.host.runExample(self.expath, self.name, "c" + lang): - self.runExample(lang, extra, "all") - else: + self.runExample(lang, extra, "all") + else: # run the example for each language found (non-corba) for lang in self.langs: if self.host.runExample(self.expath, self.name, lang): - self.runExample(lang, extra, "all") + self.runExample(lang, extra, "all") """ Run language for all types - this method will only be called if a language is - specified but the extra is *all* - the possible values will be obtained from + specified but the extra is *all* - the possible values will be obtained from the examples.json file """ - def runExampleAllExtra(self, lang, extra, types): - if self.extra != "": + def runExampleAllExtra(self, lang, extra, types): + if self.extra != "": for ex in self.extra: self.runExample(lang, ex, types) else: @@ -203,23 +210,23 @@ def runExampleAllExtra(self, lang, extra, types): """ Run the example - lang - can be c / cpp / cs / java / java5 / isocpp / isocpp2 + lang - can be c / cpp / cs / java / java5 / isocpp2 could be "" for instance if DBMSConnect example could be "all" if running all versions of an example extra - can be standalone / corba / "" / all - types - only really valid for PingPong where running the different + types - only really valid for PingPong where running the different topic types e.g. s / f / q etc - not really handled at present """ def runExample(self, lang, extra, types): if lang == "cs" and not self.host.isWindows(): - print("C# not supported on " + self.host.name) + print "C# not supported on " + self.host.name else: if lang == "all": self.runExampleAll(extra) - else: + else: if extra == "all": self.runExampleAllExtra(lang, extra, types) - else: + else: # get the current location currPath = os.getcwd() @@ -229,11 +236,11 @@ def runExample(self, lang, extra, types): else: exKey = self.expath - print("In runExample for " + exKey + ": " + self.name + ": " + lang) + print "In runExample for " + exKey + ": " + self.name + ": " + lang # set the example result directory name e.g. dcpsPingPongsac self.setExampleResultDir(lang, extra) - + exSfx = "" if self.host.isWindows() and not "java" in lang: @@ -251,27 +258,20 @@ def runExample(self, lang, extra, types): else: exes = "executables" - """ - On windows we have to run the protobuf java5 example using the class rather than the jar. - """ - if self.name == "protobuf" and self.host.isWindows() and "java5" in lang: - pubName = "ProtobufPublisher" - subName = "ProtobufSubscriber" - else: - pubName = data[exKey][self.name][exes][lang]["pubName"] - subName = data[exKey][self.name][exes][lang]["subName"] + pubName = data[exKey][self.name][exes][lang]["pubName"] + subName = data[exKey][self.name][exes][lang]["subName"] """ Get the runtime parameters for this example Obtained from the example.json file - """ - pubParams = data[exKey][self.name]["params"]["pub_params"] - subParams = data[exKey][self.name]["params"]["sub_params"] - + """ + pubParams = data[exKey][self.name]["params"]["pub_params"] + subParams = data[exKey][self.name]["params"]["sub_params"] + """ Get the yaml conditions file for this example Obtained from the example.json file - """ + """ sub_conds_file = data[exKey][self.name]["log_conditions_file"][lang]["sub_conds"] pub_conds_file = data[exKey][self.name]["log_conditions_file"][lang]["pub_conds"] @@ -280,7 +280,7 @@ def runExample(self, lang, extra, types): msg = "NONE" result = "PASS" - + try: self.setLogPathAndLogs(lang, extra) @@ -291,7 +291,7 @@ def runExample(self, lang, extra, types): subLog = os.path.join(self.pPath, 'subscriber.log') - os.chdir(self.pPath) + os.chdir(self.pPath) # Set the classpath and the runLang which is needed to identify corba versions of java as opposed to non-corba if extra == "corba" and lang == "java": @@ -302,48 +302,28 @@ def runExample(self, lang, extra, types): else: runLang = lang - """ - On windows we have to run the protobuf java5 example using the class rather than the jar. So set the - various jars and classpaths required and set self.classpath to point to the publisher path first. It - gets changed to the subscriber classpath later. - """ - if self.name == "protobuf" and self.host.isWindows() and "java5" in lang: - ospljar = os.path.join(os.environ['OSPL_HOME'], "jar", "dcpssaj5.jar") - pbufjar = os.path.join(os.environ['OSPL_HOME'], "jar", "dcpsprotobuf.jar") - pbufsubjar = os.path.join(os.environ['OSPL_HOME'], "examples", self.name, lang, extra, "saj5-protobuf-subscriber.jar") - pbufpubjar = os.path.join(os.environ['OSPL_HOME'], "examples", self.name, lang, extra, "saj5-protobuf-publisher.jar") - pub_classpath = pbufpubjar + os.pathsep + ospljar + os.pathsep + pbufjar - sub_classpath = pbufsubjar + os.pathsep + ospljar + os.pathsep + pbufjar - self.classpath = pub_classpath - - if pubName != "": + if pubName != "": """ Check that the executable actually exists if it's not a java class. The classpath is not set if we are running a jar file, not all java examples currently run with a jar file. - """ + """ if self.classpath == "" and runLang is not "cj": pubexe = os.path.join(self.pPath, pubName) + exSfx if not os.path.isfile (pubexe): msg = "MissingExecutable: " + pubexe else: pubexe = pubName - + # If we found the executable create the thread in which to run it if msg == "NONE": - pubThread = ExeThread(self.classpath, pubLog, runLang, pubexe, pubParams, self.example_timeout * 2) + pubThread = ExeThread(self.classpath, pubLog, runLang, pubexe, pubParams, self.example_timeout * 2) if subName != "": - """ - On windows we have to run the protobuf java5 example using the class rather than the jar. So set the - classpath to point to the subscriber classpath now - """ - if self.name == "protobuf" and self.host.isWindows() and "java5" in lang: - self.classpath = sub_classpath """ Check that the executable actually exists if it's not a java class. The classpath is not set if we are running a jar file, not all java examples currently run with a jar file. - """ + """ if self.classpath == "" and runLang is not "cj": subexe = os.path.join(self.pPath, subName) + exSfx if not os.path.isfile (subexe): @@ -353,8 +333,8 @@ def runExample(self, lang, extra, types): # If we found the executable create the thread in which to run it if msg == "NONE": - subThread = ExeThread(self.classpath, subLog, runLang, subexe, subParams, self.example_timeout) - + subThread = ExeThread(self.classpath, subLog, runLang, subexe, subParams, self.example_timeout) + if msg == "NONE": # start the ospl daemon, this will only happen if it's SHM self.startOSPL() @@ -362,14 +342,16 @@ def runExample(self, lang, extra, types): # start the publisher if it exists and is to start first if self.pubFirst == "True" and pubName != "": pubThread.start() + # Wait for publisher to get fully set up time.sleep(3) - # start the subscriber + # start the subscriber if subName != "": subThread.start() # Start the publisher if it wasn't to start first + if self.pubFirst == "False" and pubName != "": # Wait for subscriber to get fully set up time.sleep(3) @@ -377,40 +359,40 @@ def runExample(self, lang, extra, types): # Wait for the subscriber and publisher threads to complete if subName != "": - subThread.join(self.example_timeout) + subThread.join(self.example_timeout) if pubName != "": pubThread.join(self.example_timeout) - except Exception: - msg = "Exception running " + str(sys.exc_info()[0]) + except Exception as ex: + msg = "Exception running " + str(ex) try: if self.logger.debug: - print("Going to stop OSPL") + print "Going to stopOSPL" sys.stdout.flush() - # start the ospl daemon, this will only happen if it's SHM + # start the ospl daemon, this will only happen if it's SHM self.stopOSPL() if self.logger.debug: - print("Back from stopping OSPL") + print "Back from stopping OSPL" sys.stdout.flush() except Exception as ex: - print("Exception stopping OpenSplice ", str(ex)) + print "Exception stopping OpenSplice ", str(ex) if msg == "NONE": try: #Allow some time for all output to be written to the logs - time.sleep(10) + time.sleep(10) # copy the logs to the results directory self.copyLogs() # Check if an ospl-error.log exists - if so this is a failure if os.path.isfile (self.ospl_error_log): msg = "ospl-error.log found" - else: + else: # check the results in the subscriber logfile using the yaml conditions file self.checkResults(subLog, sub_conds) @@ -418,7 +400,7 @@ def runExample(self, lang, extra, types): if pubLog != "": self.checkResults(pubLog, pub_conds) - # check the contents of the ospl-info.log + # check the contents of the ospl-info.log self.checkOSPLInfoLog(self.ospl_info_log) except LogCheckFail as lf: @@ -427,8 +409,8 @@ def runExample(self, lang, extra, types): msg = "LogCheckFail: OpenSpliceDDS Warnings in ospl-info.log" else: msg = "LogCheckFail: " + str(lf) - except Exception: - msg = "Exception checking logs " + str(sys.exc_info()[0]) + except Exception as ex: + msg = "Exception checking logs " + str(ex) if msg != "NONE": result = "FAIL" @@ -447,7 +429,7 @@ def runExample(self, lang, extra, types): # Write the result for this instance of the example to the summary log self.writeResult (result, self.expath + self.name, resultLang, msg) except Exception as ex: - print("Exception writing result ", str(ex)) + print "Exception writing result ", str(ex) if self.host.isWindows(): time.sleep(5) @@ -456,16 +438,16 @@ def runExample(self, lang, extra, types): # Tidy up - deletes logs and things like pstore so clean for next run of the example self.cleanUp() except Exception as ex: - print("Exception cleaning up ", str(ex)) + print "Exception cleaning up ", str(ex) except Exception as ex: - print("Unexpected exception ", str(ex)) + print "Unexpected exception ", str(ex) finally: - os.chdir(currPath) + os.chdir(currPath) + + print "Completed " + self.name + ": " + lang + ":" + extra - print("Completed " + self.name + ": " + lang + ":" + extra) - """ Start the ospl daemon if appropriate @@ -473,42 +455,55 @@ def runExample(self, lang, extra, types): def startOSPL(self): if self.logger.debug: - print("STARTING OSPL *****") + print "STARTING OSPL *****" sys.stdout.flush() - if os.environ["EXRUNTYPE"] == "shm": + if os.environ["EXRUNTYPE"] == "shm": command = ['ospl', 'start'] - print(command) - ospl = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + print command + ospl = subprocess.Popen(command) + sys.stdout.flush() """ - Check that the ospl daemon has started within 20 seconds + Check that the ospl daemon has started within expected time """ count = 0 + cmax = 20 splicedFound = False if self.host.isWindows(): - while splicedFound == False and count < 20: - try: - time.sleep(1) - s = subprocess.check_output('tasklist', shell=True) - if "spliced.exe" in s: - splicedFound = True - else: + if self.host.use_psutil == "True": + splicedFound = splicedCheck.splicedCheck ("start") + + if splicedFound == False: + count = cmax + else: + while splicedFound == False and count < cmax: + try: + time.sleep(1) + s = subprocess.check_output('tasklist', shell=True) + if "spliced.exe" in s: + splicedFound = True + else: + count += 1 + + except Exception as e: + print "Exception checking if OSPL has started ...", str(e) + sys.stdout.flush() count += 1 - except: - count += 1 else: - output = subprocess.check_output(['ps', '-A']) - while not 'spliced' in output and count < 20: + output = commands.getoutput('ps -A') + while not 'spliced' in output and count < cmax: time.sleep(1) - output = subprocess.check_output(['ps', '-A']) + output = commands.getoutput('ps -A') count += 1 - if count == 20: + if count == cmax: + print "spliced failed to start" + sys.stdout.flush() raise Exception("spliced not started ....") else: - print("OpenSplice started. ....") + print "OpenSplice started. ...." """ stop the ospl daemon if appropriate @@ -516,7 +511,7 @@ def startOSPL(self): def stopOSPL(self): if self.logger.debug: - print("STOPPING OSPL *****") + print "STOPPING OSPL *****" sys.stdout.flush() if os.environ["EXRUNTYPE"] == "shm": @@ -525,43 +520,53 @@ def stopOSPL(self): else: command = ['ospl', 'stop'] - print(command) - ospl = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + print command + ospl = subprocess.Popen(command) """ - Check that the ospl daemon has stopped within 20 seconds + Check that the ospl daemon has stopped within expected time """ count = 0 + cmax = 20 splicedFound = True if self.host.isWindows(): - while splicedFound == True and count < 20: - try: - time.sleep(1) - s = subprocess.check_output('tasklist', shell=True) - if "spliced.exe" in s: + if self.host.use_psutil == "True": + splicedFound = splicedCheck.splicedCheck ("stop") + if splicedFound == True: + count = cmax + else: + while splicedFound == True and count < cmax: + try: + time.sleep(1) + s = subprocess.check_output('tasklist', shell=True) + if "spliced.exe" in s: + count += 1 + else: + splicedFound = False + + except Exception as e: + print "Exception checking if OSPL has stopped ...", str(e) + sys.stdout.flush() count += 1 - else: - splicedFound = False - except: - count += 1 + else: - output = subprocess.check_output(['ps', '-A']) - while 'spliced' in output and count < 20: + output = commands.getoutput('ps -A') + while 'spliced' in output and count < cmax: time.sleep(1) - output = subprocess.check_output(['ps', '-A']) + output = commands.getoutput('ps -A') count += 1 - if count == 20: - raise Exception("spliced not stopped within 20 seconds ....") + if count == cmax: + raise Exception("spliced not stopped within expected time ....") else: - print("OpenSplice stopped. ....") + print "OpenSplice stopped. ...." """ Set the path to this instance of the example and the directory for the logs - lang - can be c / cpp / cs / java / java5 / isocpp / isocpp2 + lang - can be c / cpp / cs / java / java5 / isocpp2 extra - can be standalone / corba / "" - """ + """ def setLogPathAndLogs(self, lang, extra): if lang == "": @@ -583,7 +588,7 @@ def setLogPathAndLogs(self, lang, extra): """ def setExampleResultDir(self, lang, extra): if self.expath == "dcps": - if lang == "isocpp" or lang == "isocpp2": + if lang == "isocpp2": sfx = lang elif lang == "c99": sfx = lang @@ -600,14 +605,14 @@ def setExampleResultDir(self, lang, extra): """ Delete the logs from the example directory so clean for next instance of this example - """ + """ def cleanUp(self): logs = os.path.join(self.pPath, '*.log') for log in glob.glob(logs): os.remove(log) """ - Get the suffix for this instance of the example. Used to set the + Get the suffix for this instance of the example. Used to set the example result directory """ def getSuffix (self, lang, extra): @@ -646,11 +651,11 @@ def getSuffix (self, lang, extra): def copyLogs (self): if self.logger.debug: - print("Copying logs and checking results") + print "Copying logs and checking results" sys.stdout.flush() logdir = os.path.join(os.environ['LOGDIR'], "examples", "run_" + os.environ['EXRUNTYPE'], self.exdir) - + logs = os.path.join(self.pPath, '*.log') if not os.path.exists(logdir): @@ -673,14 +678,14 @@ def copyLogs (self): check the results for this instance of the example """ def checkResults(self, log, conds): - if os.path.isfile (log): + if os.path.isfile (log): with open(log) as f: example_logparser.checkLogs(self.error_conditions_path, f) with open(log) as f: example_logparser.checkLogs(conds, f) - + """ check the ospl-info.log """ @@ -711,7 +716,7 @@ def writeResult(self, result, name, lang, msg): else: bcol = "F1BAAD" self.logger.addFail() - + fs.write("" + name + "" + lang + "" + fres + "" + result + "
\n") fs.close() @@ -734,27 +739,55 @@ def __init__(self, classpath, runLog, lang, prog, params, timeout): self.log = runLog self.timeout = timeout self.classpath = classpath - - def run(self): - f = open(self.log, 'a') + + def terminate(self, proc): + pid = str(proc.pid) + print "Terminating proc: {}".format(pid) + + cmd_exists = lambda x: any(os.access(os.path.join(path, x), os.X_OK) for path in os.environ["PATH"].split(os.pathsep)) + if cmd_exists('gdb'): + cmd = ['gdb', '-p','{}'.format(pid), '--batch','-ex', 'thread apply all bt full', '-ex','quit'] + gdb = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + timer = Timer(self.timeout, gdb.kill) + try: + timer.start() + gdboutput, _ = gdb.communicate() + res = gdb.returncode + print "GDB return code is ", res + if gdboutput: + with open(self.log, 'a') as f: + f.write(gdboutput) + except Exception as e: + print str(e) + finally: + timer.cancel() + + proc.kill() + + def run(self): isJava = False proc = None - print("OSPL_URI is ", os.environ["OSPL_URI"]) + print "OSPL_URI is ", os.environ["OSPL_URI"] if self.lang == "java" or self.lang == "java5" or self.lang == "cj" or self.lang == "cj5": isJava = True - + if isJava: - spliceJava = "java" + envJava = "java" spliceExtraCP = "" try: - spliceJava = os.environ['SPLICE_JAVA'] + envJava = os.environ['SPLICE_JAVA'] spliceExtraCP = os.environ['SPLICE_EXTRA_CP'] except KeyError: - print("Ignoring KeyError getting SPLICE_EXTRA_CP") + print "Ignoring KeyError getting SPLICE_EXTRA_CP" + + if envJava != "java": + spliceJava = envJava + else: + spliceJava = os.path.join(os.environ['JAVA_HOME'], "bin", envJava) if self.lang == "cj" or self.lang == "cj5": jacend = "-Djava.endorsed.dirs=" + os.path.join(os.environ['JACORB_HOME'], "lib", "endorsed") @@ -764,11 +797,11 @@ def run(self): else: if self.classpath == "": args = [self.prog] - command = ['java', '-jar'] + command = [spliceJava, '-jar'] command.extend (list(args)) else: args = [self.classpath, self.prog] - command = ['java', '-classpath'] + command = [spliceJava, '-classpath'] command.extend (list(args)) else: command = [self.prog] @@ -777,32 +810,33 @@ def run(self): args = [self.params] command.extend (list(self.params)) - print(command) + print command res = 0 proc = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) """ - If the processes runs then set a timer to kill it if it exceeds the timeout + If the processes runs then set a timer to kill it if it exceeds the timeout specified in the examples.json file for this particular example """ if proc: - timer = Timer(self.timeout, proc.kill) + timer = Timer(self.timeout, self.terminate, (proc,)) try: timer.start() exeOutput, _ = proc.communicate() res = proc.returncode - print("Process return code is ", res) + print "Process return code is ", res finally: timer.cancel() - + # Write the output to the log for this executable - f.write(exeOutput) + with open(self.log, 'a') as f: + f.write(exeOutput) """ Check if the example returned a non-zero return code. """ if res != 0: - raise Exception("Non zero return code from ...", self.prog) + raise Exception("Non zero return code from ...", self.prog) else: - print("Process not created ...") + print "Process not created ..." diff --git a/build/scripts/overnight/python/ExampleLogger.py b/build/scripts/overnight/python/ExampleLogger.py index d32b7a0bb..917d29de2 100644 --- a/build/scripts/overnight/python/ExampleLogger.py +++ b/build/scripts/overnight/python/ExampleLogger.py @@ -80,7 +80,7 @@ def finalizeResults(self): if os.path.isfile (summ_log): os.remove(summ_log) except: - print("Exception trying to delete summary.log ") + print "Exception trying to delete summary.log " fs = open(totals_log, 'w') fs.write("Examples Run = " + str(total) + "\n") diff --git a/build/scripts/overnight/python/Lifecycle.py b/build/scripts/overnight/python/Lifecycle.py index 46033e449..71f6f8ac2 100644 --- a/build/scripts/overnight/python/Lifecycle.py +++ b/build/scripts/overnight/python/Lifecycle.py @@ -27,11 +27,11 @@ def __init__(self, host, logger): self.pub2_params = data["dcps"]["Lifecycle"]["params"]["pub2_params"] - self.pub3_params = data["dcps"]["Lifecycle"]["params"]["pub3_params"] + self.pub3_params = data["dcps"]["Lifecycle"]["params"]["pub3_params"] def runExample(self, lang, extra, types): if lang == "cs" and not self.host.isWindows(): - print("C# not supported on " + self.host.name) + print "C# not supported on " + self.host.name else: if lang == "all": self.runExampleAll(extra) @@ -40,7 +40,7 @@ def runExample(self, lang, extra, types): self.runExampleAllExtra(lang, extra, types) else: currPath = os.getcwd() - print("In runExample for " + self.expath + ": " + self.name + ": " + lang) + print "In runExample for " + self.expath + ": " + self.name + ": " + lang try: super(lifecycle, self).setExampleResultDir(lang, extra) @@ -58,7 +58,7 @@ def runExample(self, lang, extra, types): pub_conds = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'yaml', pub_conds_file) exSfx = "" - + if self.host.isWindows() and not "java" in lang: exSfx = ".exe" @@ -74,7 +74,7 @@ def runExample(self, lang, extra, types): sub2Log = os.path.join(self.pPath, 'subscriber2.log') sub3Log = os.path.join(self.pPath, 'subscriber3.log') - os.chdir(self.pPath) + os.chdir(self.pPath) pubexe = os.path.join(self.pPath, pubName) + exSfx @@ -86,19 +86,19 @@ def runExample(self, lang, extra, types): subexe = os.path.join(self.pPath, subName) + exSfx if os.path.isfile (subexe): - sub1Thread = ExeThread(self.classpath, sub1Log, lang, subexe, self.sub_params, self.example_timeout) + sub1Thread = ExeThread(self.classpath, sub1Log, lang, subexe, self.sub_params, self.example_timeout) else: msg = "MissingExecutable: " + subexe if msg == "NONE": self.startOSPL() - print("Starting sub1Thread for ", subexe) + print "Starting sub1Thread for ", subexe sub1Thread.start() - print("Starting pub1Thread for ", pubexe) + print "Starting pub1Thread for ", pubexe pub1Thread.start() - + pub1Thread.join(self.example_timeout) - sub1Thread.join(self.example_timeout) + sub1Thread.join(self.example_timeout) except Exception as ex: msg = "Exception running " + str(ex) @@ -107,32 +107,32 @@ def runExample(self, lang, extra, types): if msg == "NONE": pub2Thread = ExeThread(self.classpath, pub2Log, lang, pubexe, self.pub2_params, self.example_timeout * 2) - - sub2Thread = ExeThread(self.classpath, sub2Log, lang, subexe, self.sub_params, self.example_timeout) + + sub2Thread = ExeThread(self.classpath, sub2Log, lang, subexe, self.sub_params, self.example_timeout) self.startOSPL() - print("Starting sub2Thread for ", subexe) + print "Starting sub2Thread for ", subexe sub2Thread.start() - print("Starting pub2Thread for ", pubexe) + print "Starting pub2Thread for ", pubexe pub2Thread.start() - + pub2Thread.join(self.example_timeout) - sub2Thread.join(self.example_timeout) + sub2Thread.join(self.example_timeout) self.stopOSPL() pub3Thread = ExeThread(self.classpath, pub3Log, lang, pubexe, self.pub3_params, self.example_timeout * 2) - - sub3Thread = ExeThread(self.classpath, sub3Log, lang, subexe, self.sub_params, self.example_timeout) - + + sub3Thread = ExeThread(self.classpath, sub3Log, lang, subexe, self.sub_params, self.example_timeout) + self.startOSPL() - print("Starting sub3Thread for ", subexe) + print "Starting sub3Thread for ", subexe sub3Thread.start() - print("Starting pub3Thread for ", pubexe) + print "Starting pub3Thread for ", pubexe pub3Thread.start() - + pub3Thread.join(self.example_timeout) - sub3Thread.join(self.example_timeout) + sub3Thread.join(self.example_timeout) self.stopOSPL() @@ -142,7 +142,7 @@ def runExample(self, lang, extra, types): if os.path.isfile (self.ospl_error_log): msg = "ospl-error.log found" - + self.checkResults(sub1Log, sub_conds) self.checkResults(sub2Log, sub_conds) self.checkResults(sub3Log, sub_conds) @@ -157,7 +157,7 @@ def runExample(self, lang, extra, types): if "OpenSpliceDDS Warnings" in reason: msg = "LogCheckFail: OpenSpliceDDS Warnings in ospl-info.log" else: - msg = "LogCheckFail: " + str(lf) + msg = "LogCheckFail: " + str(lf) except Exception as ex: msg = "Exception checking logs " + str(ex) @@ -167,7 +167,7 @@ def runExample(self, lang, extra, types): try: self.writeResult (result, self.expath + self.name, lang, msg) except Exception as ex: - print("Exception checking logs ", str(ex)) + print "Exception checking logs ", str(ex) if self.host.isWindows(): time.sleep(5) @@ -175,10 +175,10 @@ def runExample(self, lang, extra, types): try: self.cleanUp() except Exception as ex: - print("Exception cleaning up ", str(ex)) + print "Exception cleaning up ", str(ex) except Exception as ex: - print("Unexpected exception ", str(ex)) + print "Unexpected exception ", str(ex) finally: os.chdir(currPath) diff --git a/build/scripts/overnight/python/Ownership.py b/build/scripts/overnight/python/Ownership.py index 42793f99f..e2cad30d6 100644 --- a/build/scripts/overnight/python/Ownership.py +++ b/build/scripts/overnight/python/Ownership.py @@ -28,7 +28,7 @@ def __init__(self, host, logger): def runExample(self, lang, extra, types): if lang == "cs" and not self.host.isWindows(): - print("C# not supported on " + self.host.name) + print "C# not supported on " + self.host.name else: if lang == "all": self.runExampleAll(extra) @@ -142,14 +142,14 @@ def runExample(self, lang, extra, types): try: self.writeResult (result, self.expath + self.name, lang, msg) except Exception as ex: - print("Failure writing result", str(ex)) + print "Failure writing result", str(ex) try: self.cleanUp() except Exception as ex: - print("Failure cleaning up", str(ex)) + print "Failure cleaning up", str(ex) except Exception as ex: - print("Unexpected exception", str(ex)) + print "Unexpected exception", str(ex) finally: os.chdir(currPath) diff --git a/build/scripts/overnight/python/PingPong.py b/build/scripts/overnight/python/PingPong.py index 195e3b240..b273f603b 100644 --- a/build/scripts/overnight/python/PingPong.py +++ b/build/scripts/overnight/python/PingPong.py @@ -37,10 +37,56 @@ def __init__(self, host, logger): self.pingQuitArgs = self.quit_params self.pingQuitArgs.extend(self.partitions) + """ + The yaml check for the block doesn't work if the output isn't in + the correct order, so the example fails even though it may have + worked. This function checks the block instead of using yaml + """ + def blockCheck(self, pingLog): + blocks = 0 + timeouts = 0 + intlines = 0 + excessTimeouts = False + insufficientLines = False + + with open (pingLog) as f: + for line in f: + if "Starting ping example" in line: + blocks = blocks +1 + + if blocks > 1: + if timeouts > 5: + excessTimeouts = True + + if blocks < 5 and intlines < 100: + insufficientLines = True + + intlines = 0 + timeouts = 0 + else: + if "TIMEOUT" in line: + timeouts = timeouts +1 + else: + isText = False + vals = line.split() + for val in vals: + try: + intval = int(val) + except ValueError: + isText = True + + if isText == False: + intlines = intlines + 1 + + f.close() + + if excessTimeouts == True or insufficientLines == True: + raise LogCheckFail ("Ping results do not match expected results") + def runExample(self, lang, extra, types): - print("runExample ", lang, extra, types) + print "runExample ", lang, extra, types if lang == "cs" and not self.host.isWindows(): - print("C# not supported on " + self.host.name) + print "C# not supported on " + self.host.name else: if lang == "all": self.runExampleAll(extra) @@ -48,12 +94,9 @@ def runExample(self, lang, extra, types): if extra == "all": self.runExampleAllExtra(lang, extra, types) else: - currPath = os.getcwd() - - if lang == "cs": - ping_conds = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'yaml', 'ping_cs_conditions.yaml') - else: - ping_conds = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'yaml', 'ping_conditions.yaml') + currPath = os.getcwd() + + ping_conds = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'yaml', 'ping_conditions.yaml') pong_conds = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'yaml', 'pong_conds.yaml') @@ -88,9 +131,6 @@ def runExample(self, lang, extra, types): if lang == "java": runLang = "cj" corbaJar = "dcpscj.jar" - else: - runLang = "cj5" - corbaJar = "dcpscj5.jar" ospljar = os.path.join(os.environ['OSPL_HOME'], "jar", corbaJar) classes = os.path.join(os.environ['OSPL_HOME'], "examples", self.expath, self.name, lang, extra, "classes") @@ -98,10 +138,12 @@ def runExample(self, lang, extra, types): else: runLang = lang - print("runLang is ", runLang) + print "runLang is ", runLang if extra == "corba": exes = "corba_executables" + if lang == "java5": + exes = "executables" else: exes = "executables" @@ -128,8 +170,8 @@ def runExample(self, lang, extra, types): if msg == "NONE": self.startOSPL() - print("Going to start pong thread") - pongThread = ExeThread(self.classpath, pongLog, runLang, pongExe, self.partitions, self.pongTimeout) + print "Going to start pong thread" + pongThread = ExeThread(self.classpath, pongLog, runLang, pongExe, self.partitions, self.pongTimeout) pongThread.start() except Exception as ex: @@ -143,16 +185,16 @@ def runExample(self, lang, extra, types): runTypes = types for t in runTypes: - print("Running ping with", t) + print "Running ping with", t pingArgs = [self.BLOCKSIZE, self.BLOCKCOUNT, t] pingArgs.extend(self.partitions) - pingThread = ExeThread(self.classpath, pingLog, runLang, pingExe, pingArgs, self.pingTimeout) + pingThread = ExeThread(self.classpath, pingLog, runLang, pingExe, pingArgs, self.pingTimeout) pingThread.start() pingThread.join(self.pingTimeout) # Allow time for output to be written to log - time.sleep(2) + time.sleep(5) except Exception as ex: msg = "Failure running PingPong: ping " + str(ex) @@ -164,22 +206,24 @@ def runExample(self, lang, extra, types): pongThread.join(self.pongTimeout) except: msg = "Failure running PingPong: ping quit " + str(sys.exc_info()[0]) - + try: self.stopOSPL() except Exception as ex: - print("Exception stopping OpenSplice ", str(ex)) + print "Exception stopping OpenSplice ", str(ex) try: self.copyLogs() if os.path.isfile (self.ospl_error_log): msg = "ospl-error.log found" - + self.checkResults(pingLog, ping_conds) + self.blockCheck (pingLog) + self.checkResults(pongLog, pong_conds) - + self.checkOSPLInfoLog(self.ospl_info_log) except LogCheckFail as lf: reason = str(lf) @@ -204,21 +248,19 @@ def runExample(self, lang, extra, types): resultLang = "ccpp" elif lang == "java": resultLang = "cj" - elif lang == "java5": - resultLang = "cj5" try: - print("WRiting result for ", self.name + " " + resultLang) + print "WRiting result for ", self.name + " " + resultLang self.writeResult (result, self.expath + self.name, resultLang, msg) except Exception as ex: - print("Exception writing result", str(ex)) + print "Exception writing result", str(ex) try: self.cleanUp() except Exception as ex: - print("Exception cleaning up", str(ex)) + print "Exception cleaning up", str(ex) except Exception as ex: - print("Unexpected exception", str(ex)) + print "Unexpected exception", str(ex) finally: os.chdir(currPath) diff --git a/build/scripts/overnight/python/RMIHelloWorld.py b/build/scripts/overnight/python/RMIHelloWorld.py index 01e8705ee..e56115556 100644 --- a/build/scripts/overnight/python/RMIHelloWorld.py +++ b/build/scripts/overnight/python/RMIHelloWorld.py @@ -22,7 +22,7 @@ def __init__(self, host, logger): def runExample(self, lang, extra, types): if lang == "cs" and not self.host.isWindows(): - print("C# not supported on " + self.host.name) + print "C# not supported on " + self.host.name else: if lang == "all": self.runExampleAll(extra) @@ -111,7 +111,7 @@ def runExample(self, lang, extra, types): try: self.stopOSPL() except Exception as ex: - print("Exception stopping OpenSplice ", str(ex)) + print "Exception stopping OpenSplice ", str(ex) if msg == "NONE": try: @@ -141,14 +141,14 @@ def runExample(self, lang, extra, types): try: self.writeResult (result, self.expath + self.name, lang, msg) except Exception as ex: - print("Exception writing result", str(ex)) + print "Exception writing result", str(ex) try: self.cleanUp() except Exception as ex: - print("Exception cleaning up", str(ex)) + print "Exception cleaning up", str(ex) except Exception as ex: - print("Unexpected exception", str(ex)) + print "Unexpected exception", str(ex) finally: os.chdir(currPath) diff --git a/build/scripts/overnight/python/RoundTrip.py b/build/scripts/overnight/python/RoundTrip.py index 0692260d7..0250ef9ca 100644 --- a/build/scripts/overnight/python/RoundTrip.py +++ b/build/scripts/overnight/python/RoundTrip.py @@ -28,29 +28,29 @@ def __init__(self, host, logger): def runExample(self, lang, extra, types): - print("RoundTrip - runExample ...") + print "RoundTrip - runExample ..." if lang == "cs" and not self.host.isWindows(): - print("C# not supported on " + self.host.name) + print "C# not supported on " + self.host.name else: if lang == "all": self.runExampleAll(extra) else: - print("In runExample for " + self.expath + ": " + self.name + ": " + lang) + print "In runExample for " + self.expath + ": " + self.name + ": " + lang - currPath = os.getcwd() + currPath = os.getcwd() try: super(roundtrip, self).setExampleResultDir(lang, extra) if lang == "java": pubName = "Saj_RoundTrip_Pong.jar" - subName = "Saj_RoundTrip_Ping.jar" - elif lang == "java5": - pubName = "Saj5_RoundTrip_Pong.jar" - subName = "Saj5_RoundTrip_Ping.jar" - else: + subName = "Saj_RoundTrip_Ping.jar" + elif lang == "java5": + pubName = "pong/java5_pong.jar" + subName = "ping/java5_ping.jar" + else: pubName = "pong" subName = "ping" @@ -64,7 +64,7 @@ def runExample(self, lang, extra, types): pub_conds = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'yaml', pub_conds_file) exSfx = "" - + if self.host.isWindows() and not "java" in lang: exSfx = ".exe" @@ -86,28 +86,28 @@ def runExample(self, lang, extra, types): subexe = os.path.join(self.pPath, subName) + exSfx if os.path.isfile (pubexe): - subThread = ExeThread(self.classpath, subLog, lang, subexe, self.sub_params, self.example_timeout) + subThread = ExeThread(self.classpath, subLog, lang, subexe, self.sub_params, self.example_timeout) else: msg = "MissingExecutable: " + subexe - + quitexe = os.path.join(self.pPath, subName) + exSfx - if os.path.isfile (pubexe): + if os.path.isfile (pubexe): quitThread = ExeThread(self.classpath, subLog, lang, quitexe, self.quit_params, self.example_timeout) else: msg = "MissingExecutable: " + quitexe - os.chdir(self.pPath) + os.chdir(self.pPath) if msg == "NONE": self.startOSPL() - print("Starting pubThread for ", pubexe) + print "Starting pubThread for ", pubexe pubThread.start() - print("Starting subThread for ", subexe) + print "Starting subThread for ", subexe subThread.start() - + subThread.join(self.example_timeout) - print("Starting quitThread for ", quitexe) + print "Starting quitThread for ", quitexe quitThread.start() pubThread.join(self.example_timeout) quitThread.join(self.example_timeout) @@ -118,7 +118,7 @@ def runExample(self, lang, extra, types): try: self.stopOSPL() except Exception as ex: - print("Exception stopping OpenSplice ", str(ex)) + print "Exception stopping OpenSplice ", str(ex) if msg == "NONE": try: @@ -126,7 +126,7 @@ def runExample(self, lang, extra, types): if os.path.isfile (self.ospl_error_log): msg = "ospl-error.log found" - #pdb.set_trace() + #pdb.set_trace() self.checkResults(subLog, sub_conds) self.checkResults(pubLog, pub_conds) @@ -147,14 +147,14 @@ def runExample(self, lang, extra, types): try: self.writeResult (result, self.expath + self.name, lang, msg) except Exception as ex: - print("Exception writing result", str(ex)) + print "Exception writing result", str(ex) - try: + try: self.cleanUp() except Exception as ex: - print("Exception cleaning up", str(ex)) + print "Exception cleaning up", str(ex) except Exception as ex: - print("Unexpected exception ", str(ex)) + print "Unexpected exception ", str(ex) finally: - os.chdir(currPath) + os.chdir(currPath) diff --git a/build/scripts/overnight/python/Running Manually b/build/scripts/overnight/python/Running Manually index 769226249..a945a5e67 100644 --- a/build/scripts/overnight/python/Running Manually +++ b/build/scripts/overnight/python/Running Manually @@ -25,13 +25,13 @@ JACORB_HOME=/home/dds/INSTALLED_FOR_DDS/JacORB-v2.3.1.0 (as appropriate for mach ODBCHOME=/home/dds/INSTALLED_FOR_DDS/ODBC ODBCINI=$ODBCHOME/etc/odbc.ini ODBCINST=$ODBCHOME/etc/odbcinst.ini -ODBC_MSSQL_SERVER=10.1.0.189 +ODBC_MSSQL_SERVER=10.1.5.197 ODBC_MYSQL_SERVER=10.1.0.191 ODBCSYSINI=$ODBCHOME/etc LD_LIBRARY_PATH="$ODBCHOME/lib:.:$LD_LIBRARY_PATH" ODBC_LIB_NAME="odbc" - + On windows also set @@ -57,7 +57,7 @@ Where lang is from c, cpp, cs, isocpp, isocpp2, java, java5 and where type is fr Note: the use of standalone / corba will only be effective where applicable and is handled internally - + ExampleName will be from diff --git a/build/scripts/overnight/python/Tutorial.py b/build/scripts/overnight/python/Tutorial.py index 6219413fe..c8e9b6118 100644 --- a/build/scripts/overnight/python/Tutorial.py +++ b/build/scripts/overnight/python/Tutorial.py @@ -30,7 +30,7 @@ def __init__(self, host, logger): def runExample(self, lang, extra, types): if lang == "cs" and not self.host.isWindows(): - print("C# not supported on " + self.host.name) + print "C# not supported on " + self.host.name else: if lang == "all": self.runExampleAll(extra) @@ -38,7 +38,7 @@ def runExample(self, lang, extra, types): if extra == "all": self.runExampleAllExtra(lang, extra, types) else: - print("In runExample for " + self.expath + ": " + self.name + ": " + lang + ":" + extra) + print "In runExample for " + self.expath + ": " + self.name + ": " + lang + ":" + extra currPath = os.getcwd() @@ -146,7 +146,7 @@ def runExample(self, lang, extra, types): try: self.stopOSPL() except Exception as ex: - print("Exception stopping OpenSplice ", str(ex)) + print "Exception stopping OpenSplice ", str(ex) if msg == "NONE": try: @@ -183,14 +183,14 @@ def runExample(self, lang, extra, types): try: self.writeResult (result, self.expath + self.name, resultLang, msg) except Exception as ex: - print("Exception writing result", str(ex)) + print "Exception writing result", str(ex) try: self.cleanUp() except Exception as ex: - print("Exception cleaning up", str(ex)) + print "Exception cleaning up", str(ex) except Exception as ex: - print("Unexpected exception ", str(ex)) + print "Unexpected exception ", str(ex) finally: os.chdir(currPath) diff --git a/build/scripts/overnight/python/example_logparser.py b/build/scripts/overnight/python/example_logparser.py index 6895c0483..b4eaf0bbb 100644 --- a/build/scripts/overnight/python/example_logparser.py +++ b/build/scripts/overnight/python/example_logparser.py @@ -133,7 +133,7 @@ def process_block( cond, loglines, logname ): err_return ='' diffcount = 0 - pluscount = 0 + pluscount = 0 firstlinedetected = False maxplusinst = 0 instcount = 0 @@ -194,7 +194,7 @@ def process_block( cond, loglines, logname ): pluscount = 0 contigcount = 0 # single plusline at present - + if not ignored and firstlinedetected: blockline = "{}\n{}".format(blockline, logline) @@ -210,9 +210,9 @@ def process_block( cond, loglines, logname ): if logline == plusline["line"]: pluscount += 1 - + if not ignored and contains(lastline, logline) and firstlinedetected: - + firstlinedetected = False lline = diffcount @@ -322,6 +322,8 @@ def process_line( cond, loglines, logname ): logline = line.strip() if contains(condline, logline): instcount += 1 + if contains("A debugging session is active", logline): + err_return += 'Debug trace found in ' + logname + ' process did not terminate properly; ' if maxinst != 'All': if instcount < int(maxinst): @@ -329,6 +331,9 @@ def process_line( cond, loglines, logname ): elif instcount > int(maxinst): err_return += 'Too many instances in ' + logname + ': ' + condname + ' ' + str(instcount) + '; ' + if instcount == 0: + err_return += 'No instances in ' + logname + ': ' + condname + '; ' + else: # condition not allowed in log file for line in loglines: diff --git a/build/scripts/overnight/python/examples.json b/build/scripts/overnight/python/examples.json old mode 100644 new mode 100755 index 92ad06ec1..d1e5be98f --- a/build/scripts/overnight/python/examples.json +++ b/build/scripts/overnight/python/examples.json @@ -4,7 +4,7 @@ "PingPong": { "langs": ["c", "cpp", "java", "java5", "cs"], - "corba_langs": ["cpp", "java", "java5"], + "corba_langs": ["cpp", "java"], "corba_executables": { "cpp": @@ -14,12 +14,6 @@ }, "java": - { - "pubName": "pong", - "subName": "ping" - }, - - "java5": { "pubName": "pong", "subName": "ping" @@ -65,8 +59,8 @@ "java5": { - "pubName": "saj5_pingpong_pong.jar", - "subName": "saj5_pingpong_ping.jar" + "pubName": "pong/java5_pong.jar", + "subName": "ping/java5_ping.jar" } }, @@ -81,7 +75,7 @@ "BuiltInTopics": { - "langs": ["c", "cpp", "cs", "isocpp","isocpp2", "java", "java5"], + "langs": ["c", "cpp", "cs", "isocpp2", "java", "java5"], "corba_langs": "", "extra": ["standalone"], @@ -132,7 +126,7 @@ "java5": { "pubName": "", - "subName": "saj5_builtintopics_sub.jar" + "subName": "java5_BuiltInTopics.jar" } }, @@ -181,7 +175,7 @@ } }, - "timeout": "10", + "timeout": "20", "sp-uri": "", @@ -192,7 +186,7 @@ "ContentFilteredTopic": { - "langs": ["c", "cpp", "cs", "isocpp", "isocpp2", "java", "java5"], + "langs": ["c", "cpp", "cs", "isocpp2", "java", "java5"], "corba_langs": "", "extra": ["standalone"], @@ -242,8 +236,8 @@ "java5": { - "pubName": "saj5_contentfilteredtopic_pub.jar", - "subName": "saj5_contentfilteredtopic_sub.jar" + "pubName": "pub/java5_ContentFilteredTopic_pub.jar", + "subName": "sub/java5_ContentFilteredTopic_sub.jar" } }, @@ -282,17 +276,17 @@ "java": { "sub_conds": "contentfilteredtopic_java_conditions.yaml", - "pub_conds": "contentfilteredtopic_java_conditions.yaml" + "pub_conds": "contentfilteredtopic_javapub_conditions.yaml" }, "java5": { "sub_conds": "contentfilteredtopic_java_conditions.yaml", - "pub_conds": "contentfilteredtopic_java_conditions.yaml" + "pub_conds": "contentfilteredtopic_javapub_conditions.yaml" } }, - "timeout": "30", + "timeout": "60", "sp-uri": "", @@ -303,7 +297,7 @@ "Durability": { - "langs": ["c", "cpp", "isocpp2", "isocpp", "java", "java5"], + "langs": ["c", "cpp", "isocpp2", "java", "java5"], "corba_langs": "", "extra": ["standalone"], @@ -357,8 +351,8 @@ "java5": { - "pubName": "saj5_durability_pub.jar", - "subName": "saj5_durability_sub.jar" + "pubName": "pub/java5_Durability_pub.jar", + "subName": "sub/java5_Durability_sub.jar" } }, @@ -407,7 +401,7 @@ } }, - "timeout": "50", + "timeout": "60", "sp-uri": "ospl_sp.xml", @@ -418,7 +412,7 @@ "HelloWorld": { - "langs": ["c", "cpp", "cs", "isocpp", "isocpp2", "java", "java5"], + "langs": ["c", "cpp", "cs", "isocpp2", "java", "java5"], "corba_langs": ["cpp", "java"], "corba_executables": @@ -484,8 +478,8 @@ "java5": { - "pubName": "saj5_helloworld_pub.jar", - "subName": "saj5_helloworld_sub.jar" + "pubName": "pub/java5_HelloWorld_pub.jar", + "subName": "sub/java5_HelloWorld_sub.jar" } }, @@ -534,7 +528,7 @@ } }, - "timeout": "15", + "timeout": "60", "sp-uri": "", @@ -545,7 +539,7 @@ "Lifecycle": { - "langs": ["c", "cpp", "cs", "isocpp2", "isocpp", "java", "java5"], + "langs": ["c", "cpp", "cs", "isocpp2", "java", "java5"], "corba_langs": "", "extra": ["standalone"], @@ -597,8 +591,8 @@ "java5": { - "pubName": "saj5_lifecycle_pub.jar", - "subName": "saj5_lifecycle_sub.jar" + "pubName": "pub/java5_Lifecycle_pub.jar", + "subName": "sub/java5_Lifecycle_sub.jar" } }, @@ -658,7 +652,7 @@ "Listener": { - "langs": ["c", "cpp", "cs", "isocpp2", "isocpp", "java", "java5"], + "langs": ["c", "cpp", "cs", "isocpp2", "java", "java5"], "corba_langs": "", "extra": ["standalone"], @@ -708,8 +702,8 @@ "java5": { - "pubName": "saj5_listener_pub.jar", - "subName": "saj5_listener_sub.jar" + "pubName": "pub/java5_Listener_pub.jar", + "subName": "sub/java5_Listener_sub.jar" } }, @@ -758,7 +752,7 @@ } }, - "timeout": "30", + "timeout": "60", "sp-uri": "", @@ -769,7 +763,7 @@ "Ownership": { - "langs": ["c", "cpp", "cs", "isocpp", "isocpp2", "java", "java5"], + "langs": ["c", "cpp", "cs", "isocpp2", "java", "java5"], "corba_langs": "", "extra": ["standalone"], @@ -819,8 +813,8 @@ "java5": { - "pubName": "saj5_ownership_pub.jar", - "subName": "saj5_ownership_sub.jar" + "pubName": "pub/java5_Ownership_pub.jar", + "subName": "sub/java5_Ownership_sub.jar" } }, @@ -869,7 +863,7 @@ } }, - "timeout": "20", + "timeout": "60", "sp-uri": "", @@ -880,7 +874,7 @@ "QueryCondition": { - "langs": ["c", "cpp", "cs", "isocpp", "isocpp2", "java", "java5"], + "langs": ["c", "cpp", "cs", "isocpp2", "java", "java5"], "corba_langs": "", "extra": ["standalone"], @@ -930,8 +924,8 @@ "java5": { - "pubName": "saj5_querycondition_pub.jar", - "subName": "saj5_querycondition_sub.jar" + "pubName": "pub/java5_QueryCondition_pub.jar", + "subName": "sub/java5_QueryCondition_sub.jar" } }, @@ -980,7 +974,7 @@ } }, - "timeout": "10", + "timeout": "60", "sp-uri": "", @@ -991,7 +985,7 @@ "RoundTrip": { - "langs": ["c", "cpp", "isocpp", "isocpp2", "java", "java5", "c99"], + "langs": ["c", "cpp", "isocpp2", "java", "java5", "c99"], "corba_langs": "", "extra": [""], @@ -1063,7 +1057,7 @@ "Throughput": { - "langs": ["c", "cpp", "isocpp", "isocpp2", "java", "java5", "c99"], + "langs": ["c", "cpp", "isocpp2", "java", "java5", "c99"], "corba_langs": "", "extra": [""], @@ -1107,8 +1101,8 @@ "java5": { - "pubName": "Saj5_Throughput_Publisher.jar", - "subName": "Saj5_Throughput_Subscriber.jar" + "pubName": "pub/java5_Throughput_pub.jar", + "subName": "sub/java5_Throughput_sub.jar" }, "c99": @@ -1163,7 +1157,7 @@ } }, - "timeout": "30", + "timeout": "60", "sp-uri": "", @@ -1174,7 +1168,7 @@ "Tutorial": { - "langs": ["c", "cpp", "cs", "isocpp", "isocpp2", "java", "java5"], + "langs": ["c", "cpp", "cs", "isocpp2", "java", "java5"], "corba_langs": ["cpp", "java"], "corba_executables": @@ -1250,9 +1244,9 @@ "java5": { - "msgBoardName": "saj5_tutorial_messageboard.jar", - "userLoadName": "saj5_tutorial_userload.jar", - "chatterName": "saj5_tutorial_chatter.jar" + "msgBoardName": "messageboard/java5_Messageboard.jar", + "userLoadName": "userload/java5_Userload.jar", + "chatterName": "chatter/java5_Chatter.jar" } }, @@ -1312,7 +1306,7 @@ "WaitSet": { - "langs": ["c", "cpp", "cs", "isocpp2", "isocpp", "java", "java5"], + "langs": ["c", "cpp", "cs", "isocpp2", "java", "java5"], "corba_langs": "", "extra": ["standalone"], @@ -1362,8 +1356,8 @@ "java5": { - "pubName": "saj5_waitset_pub.jar", - "subName": "saj5_waitset_sub.jar" + "pubName": "pub/java5_WaitSet_pub.jar", + "subName": "sub/java5_WaitSet_sub.jar" } }, @@ -1406,7 +1400,7 @@ } }, - "timeout": "10", + "timeout": "60", "sp-uri": "", @@ -1567,7 +1561,7 @@ } }, - "timeout": "30", + "timeout": "60", "sp-uri": "", @@ -1609,7 +1603,7 @@ } }, - "timeout": "25", + "timeout": "60", "sp-uri": "", @@ -1643,8 +1637,8 @@ "java": { - "pubName": "face_helloworld_pub.jar", - "subName": "face_helloworld_sub.jar" + "pubName": "pub/face_HelloWorld_pub.jar", + "subName": "sub/face_HelloWorld_sub.jar" } }, @@ -1697,8 +1691,8 @@ "java5": { - "pubName": "saj5-protobuf-publisher.jar", - "subName": "saj5-protobuf-subscriber.jar" + "pubName": "pub/java5_protobuf_pub.jar", + "subName": "sub/java5_protobuf_sub.jar" } }, @@ -1741,7 +1735,7 @@ "odbcChatter1_params": ["my_dsn", "SYSTEM", "SYSTEM", "1", "SqlToDdsOnly"], "odbcChatter2_params": ["my_dsn", "SYSTEM", "SYSTEM", "2", "SqlToDdsAndDbms"], "cppChatter1_params": ["1", "DdsToDdsOnly"], - "cppChatter2_params": ["1", "DdsToDdsAndDbms"], + "cppChatter2_params": ["2", "DdsToDdsAndDbms"], "odbcChatterQuit_params": ["my_dsn", "SYSTEM", "SYSTEM", "-1", "terminate"], "cppChatterQuit_params": ["-1"] }, diff --git a/build/scripts/overnight/python/host.py b/build/scripts/overnight/python/host.py index 89191549c..6bbf40c43 100644 --- a/build/scripts/overnight/python/host.py +++ b/build/scripts/overnight/python/host.py @@ -7,7 +7,7 @@ Class holding details of the host on which the example is running """ class host(object): - + def __init__(self): """ Get the name of the host - not always set the same when @@ -24,24 +24,36 @@ def __init__(self): with open ('hosts.json') as data_file: data = json.load(data_file) + """ + if host is not in the hosts.json fallback to the default host config + which runs all examples + """ + if not self.name in data: + self.name = "default" + self.excludedLangs = data[self.name]["excluded_langs"] self.excludedExamples = data[self.name]["excluded_examples"] self.partialExamples = data[self.name]["partial_examples"] + try: + self.use_psutil = data[self.name]["use_psutil"] + except KeyError: + self.use_psutil = "False" + def isWindows(self): return "win" in self.name """ Check whether the example is to run on this host. If so check that the example is to run in the specified language - """ + """ def runExample(self, xpath, example, lang): runExample = True - + """ - To cater for dcpsHelloWorld, rmiHelloWorld, faceHelloWorld etc we need to + To cater for dcpsHelloWorld, rmiHelloWorld, faceHelloWorld etc we need to include the extra bit e.g. dcps/rmi/face to avoid the json file becoming too complicated """ @@ -60,39 +72,39 @@ def runExample(self, xpath, example, lang): runExample = False """ - If a language is excluded for all examples it will be in the excludedLangs list + If a language is excluded for all examples it will be in the excludedLangs list """ if runExample and lang != "": for l in self.excludedLangs: if l == lang: - runExample = False + runExample = False """ - If an example can run in some but not all languages it will be in the partialExamples list + If an example can run in some but not all languages it will be in the partialExamples list """ if runExample and lang != "": for p in self.partialExamples: if p == exkey: - + with open ('hosts.json') as data_file: data = json.load(data_file) - + langs = data[self.name]["partial_examples"][exkey]["langs"] for l in langs: if l == lang: - runExample = False + runExample = False if runExample == False: - print("Not running " + exkey + ":" + lang + " on " +self.name) + print "Not running " + exkey + ":" + lang + " on " +self.name return runExample if __name__ == "__main__": - + me = host() if me.isWindows() == True: - print("It's windows") + print "It's windows" else: - print("It's not windows") + print "It's not windows" diff --git a/build/scripts/overnight/python/hosts.json b/build/scripts/overnight/python/hosts.json old mode 100644 new mode 100755 index 35ed65944..9f2ecad44 --- a/build/scripts/overnight/python/hosts.json +++ b/build/scripts/overnight/python/hosts.json @@ -14,7 +14,7 @@ "excluded_examples": ["dbmsconnect"], "partial_examples": "" }, - + "bone6": { "examples": ["AllStandalone"], @@ -30,13 +30,14 @@ "excluded_examples": ["dbmsconnect"], "partial_examples": "" }, - + "dds1-win2k3": { "examples": ["All"], "excluded_langs": ["c99"], "excluded_examples": ["PingPong"], - "partial_examples": "" + "partial_examples": "", + "use_psutil": "True" }, "dds2-win2k3": @@ -44,25 +45,43 @@ "examples": ["All"], "excluded_langs": ["c99"], "excluded_examples": [""], - "partial_examples": "" + "partial_examples": "", + "use_psutil": "True" }, - + "dds3-win2k3": { "examples": ["All"], "excluded_langs": ["c99"], "excluded_examples": [""], - "partial_examples": "" + "partial_examples": "", + "use_psutil": "True" }, - + "debian6a-32": { "examples": ["AllStandalone"], "excluded_langs": [""], - "excluded_examples": ["protobuf", "dbmsconnect"], + "excluded_examples": ["protobuf", "dbmsconnect"], "partial_examples": "" }, + "debian9-32-a": + { + "examples": ["AllStandalone"], + "excluded_langs": [""], + "excluded_examples": ["dbmsconnect"], + "partial_examples": "" + }, + + "debian9-64-p": + { + "examples": ["AllStandalone"], + "excluded_langs": [""], + "excluded_examples": ["dbmsconnect"], + "partial_examples": "" + }, + "jetson1": { "examples": ["All"], @@ -70,22 +89,22 @@ "excluded_examples": ["dbmsconnect"], "partial_examples": { - "dcpsPingPong": + "dcpsPingPong": { "langs": ["ccpp"] }, - "dcpsTutorial": + "dcpsTutorial": { "langs": ["ccpp"] }, - "dcpsHelloWorld": + "dcpsHelloWorld": { "langs": ["ccpp"] }, - "protobuf": + "protobuf": { "langs": ["isocpp2"] } @@ -115,12 +134,12 @@ "excluded_examples": [""], "partial_examples": { - "protobuf": + "protobuf": { "langs": ["cpp"] }, - "faceHelloWorld": + "faceHelloWorld": { "langs": ["cpp"] } @@ -134,12 +153,12 @@ "excluded_examples": [""], "partial_examples": { - "protobuf": + "protobuf": { "langs": ["cpp"] }, - "faceHelloWorld": + "faceHelloWorld": { "langs": ["cpp"] } @@ -153,12 +172,12 @@ "excluded_examples": [""], "partial_examples": { - "protobuf": + "protobuf": { "langs": ["cpp"] }, - "faceHelloWorld": + "faceHelloWorld": { "langs": ["cpp"] } @@ -276,17 +295,17 @@ "excluded_examples": [""], "partial_examples": { - "dcpsPingPong": + "dcpsPingPong": { "langs": ["ccpp"] }, - "dcpsTutorial": + "dcpsTutorial": { "langs": ["ccpp"] }, - "dcpsHelloWorld": + "dcpsHelloWorld": { "langs": ["ccpp"] } @@ -327,21 +346,13 @@ "ubuntu1404-64a": { - "examples": ["All"], + "examples": ["AllStandalone"], "excluded_langs": [""], "excluded_examples": [""], "partial_examples": "" }, "ubuntu1604-32a": - { - "examples": ["AllStandalone"], - "excluded_langs": [""], - "excluded_examples": ["dbmsconnect"], - "partial_examples": "" - }, - - "ubuntu1604-64a": { "examples": ["AllStandalone"], "excluded_langs": [""], @@ -349,7 +360,7 @@ "partial_examples": "" }, - "ubuntu1804-64a": + "ubuntu1604-64a": { "examples": ["AllStandalone"], "excluded_langs": [""], @@ -364,27 +375,29 @@ "excluded_examples": ["protobuf"], "partial_examples": { - "faceHelloWorld": + "faceHelloWorld": { "langs": ["cpp"] } } }, - + "win2008-64a": { "examples": ["AllStandalone"], "excluded_langs": ["c99"], "excluded_examples": [""], - "partial_examples": "" + "partial_examples": "", + "use_psutil": "False" }, - + "win7-32-ospl-1": { "examples": ["All"], "excluded_langs": ["c99"], "excluded_examples": [""], - "partial_examples": "" + "partial_examples": "", + "use_psutil": "False" }, "win7-32-ospl-2": @@ -392,7 +405,8 @@ "examples": ["All"], "excluded_langs": ["c99"], "excluded_examples": [""], - "partial_examples": "" + "partial_examples": "", + "use_psutil": "False" }, "win7-32-ospl-3": @@ -400,7 +414,8 @@ "examples": ["All"], "excluded_langs": ["c99"], "excluded_examples": [""], - "partial_examples": "" + "partial_examples": "", + "use_psutil": "False" }, "win7-32-ospl-4": @@ -408,7 +423,8 @@ "examples": ["All"], "excluded_langs": ["c99"], "excluded_examples": [""], - "partial_examples": "" + "partial_examples": "", + "use_psutil": "False" }, "win7-64-ospl-1": @@ -416,7 +432,8 @@ "examples": ["All"], "excluded_langs": ["c99"], "excluded_examples": [""], - "partial_examples": "" + "partial_examples": "", + "use_psutil": "False" }, "win7-64-ospl-2": @@ -424,7 +441,8 @@ "examples": ["All"], "excluded_langs": ["c99"], "excluded_examples": [""], - "partial_examples": "" + "partial_examples": "", + "use_psutil": "False" }, "win7-64-ospl-3": @@ -432,7 +450,8 @@ "examples": ["All"], "excluded_langs": ["c99"], "excluded_examples": [""], - "partial_examples": "" + "partial_examples": "", + "use_psutil": "False" }, "win7-64-ospl-4": @@ -440,7 +459,8 @@ "examples": ["All"], "excluded_langs": ["c99"], "excluded_examples": [""], - "partial_examples": "" + "partial_examples": "", + "use_psutil": "False" }, "win7a-64": @@ -448,7 +468,8 @@ "examples": ["All"], "excluded_langs": ["c99"], "excluded_examples": [""], - "partial_examples": "" + "partial_examples": "", + "use_psutil": "False" }, "win7a": @@ -456,7 +477,8 @@ "examples": ["All"], "excluded_langs": ["c99"], "excluded_examples": [""], - "partial_examples": "" + "partial_examples": "", + "use_psutil": "False" }, "win7b": @@ -466,21 +488,23 @@ "excluded_examples": [""], "partial_examples": { - "dcpsPingPong": + "dcpsPingPong": { "langs": ["ccpp"] }, - "dcpsTutorial": + "dcpsTutorial": { "langs": ["ccpp"] }, - "dcpsHelloWorld": + "dcpsHelloWorld": { "langs": ["ccpp"] } - } + }, + + "use_psutil": "False" }, "win7c": @@ -490,21 +514,23 @@ "excluded_examples": [""], "partial_examples": { - "dcpsPingPong": + "dcpsPingPong": { "langs": ["ccpp"] }, - "dcpsTutorial": + "dcpsTutorial": { "langs": ["ccpp"] }, - "dcpsHelloWorld": + "dcpsHelloWorld": { "langs": ["ccpp"] } - } + }, + + "use_psutil": "False" }, "win7d": @@ -514,21 +540,23 @@ "excluded_examples": [""], "partial_examples": { - "dcpsPingPong": + "dcpsPingPong": { "langs": ["ccpp"] }, - "dcpsTutorial": + "dcpsTutorial": { "langs": ["ccpp"] }, - "dcpsHelloWorld": + "dcpsHelloWorld": { "langs": ["ccpp"] } - } + }, + + "use_psutil": "False" }, "win7e": @@ -538,69 +566,127 @@ "excluded_examples": [""], "partial_examples": { - "dcpsPingPong": + "dcpsPingPong": { "langs": ["ccpp"] }, - "dcpsTutorial": + "dcpsTutorial": { "langs": ["ccpp"] }, - "dcpsHelloWorld": + "dcpsHelloWorld": { "langs": ["ccpp"] } - } + }, + + "use_psutil": "False" }, - "win10-64-vor-a": + "win7g": + { + "examples": ["AllStandalone"], + "excluded_langs": ["c99"], + "excluded_examples": [""], + "partial_examples": + { + "dcpsPingPong": + { + "langs": ["ccpp"] + }, + + "dcpsTutorial": + { + "langs": ["ccpp"] + }, + + "dcpsHelloWorld": + { + "langs": ["ccpp"] + } + }, + + "use_psutil": "False" + }, + + "win7h": + { + "examples": ["AllStandalone"], + "excluded_langs": ["c99"], + "excluded_examples": [""], + "partial_examples": + { + "dcpsPingPong": + { + "langs": ["ccpp"] + }, + + "dcpsTutorial": + { + "langs": ["ccpp"] + }, + + "dcpsHelloWorld": + { + "langs": ["ccpp"] + } + }, + + "use_psutil": "False" + }, + + "win10-32-ospl-1": { "examples": ["AllStandalone"], "excluded_langs": [""], "excluded_examples": [""], "partial_examples": { - "dcpsPingPong": + "dcpsPingPong": { "langs": ["ccpp"] }, - "dcpsTutorial": + "dcpsTutorial": { "langs": ["ccpp"] }, - "dcpsHelloWorld": + "dcpsHelloWorld": { "langs": ["ccpp"] } - } + }, + + "use_psutil": "False" }, - "win10-64-vor-b": + "win10-64-vor-a": { "examples": ["AllStandalone"], "excluded_langs": [""], "excluded_examples": [""], "partial_examples": { - "dcpsPingPong": + "dcpsPingPong": { "langs": ["ccpp"] }, - "dcpsTutorial": + "dcpsTutorial": { "langs": ["ccpp"] }, - "dcpsHelloWorld": + "dcpsHelloWorld": { "langs": ["ccpp"] } - } + }, + + "use_psutil": "False" }, "win10-64-vor-c": @@ -624,7 +710,9 @@ { "langs": ["ccpp"] } - } + }, + + "use_psutil": "False" }, "win10-64-vor-d": @@ -648,13 +736,15 @@ { "langs": ["ccpp"] } - } - }, + }, + + "use_psutil": "False" + }, - "win10-64-ospl-vs17": + "win10-64-ospl-7": { "examples": ["AllStandalone"], - "excluded_langs": ["c99"], + "excluded_langs": [""], "excluded_examples": [""], "partial_examples": { @@ -672,15 +762,19 @@ { "langs": ["ccpp"] } - } + }, + + "use_psutil": "False" }, + "winxp12": { "examples": ["All"], "excluded_langs": ["c99"], "excluded_examples": [""], - "partial_examples": "" + "partial_examples": "", + "use_psutil": "True" }, "winxp13": @@ -688,7 +782,8 @@ "examples": ["All"], "excluded_langs": ["c99"], "excluded_examples": [""], - "partial_examples": "" + "partial_examples": "", + "use_psutil": "True" }, "winxp13-new": @@ -696,9 +791,16 @@ "examples": ["All"], "excluded_langs": ["c99"], "excluded_examples": [""], - "partial_examples": "" - } -} + "partial_examples": "", + "use_psutil": "True" + }, - - + "default": + { + "examples": ["AllStandalone"], + "excluded_langs": ["c99"], + "excluded_examples": [""], + "partial_examples": "", + "use_psutil": "False" + } +} diff --git a/build/scripts/overnight/python/known_issues b/build/scripts/overnight/python/known_issues index 56ac775bd..1f4d748b3 100644 --- a/build/scripts/overnight/python/known_issues +++ b/build/scripts/overnight/python/known_issues @@ -2,10 +2,8 @@ Known Issues
OSPL-6901 Finding builtin readers doesn't work with gcc <= 4.4.5
-OSPL-7869 dcpsPingPongjava5SA example appears to trigger without data available
OSPL-8209 Inconsistency handling stop_subscriber flag in Ownership example
OSPL-8811 dcpsBuiltInTopicsisocpp2 example error
-OSPL-9143 Durability examples failing
OSPL-9168 dbmsconnect reported as passed when it didn't run correctly - windows - V6.7 branch
-OSPL-9371 SPIKE: Example dbmsConnect fails with an abort (signal 6)
-OSPL-9405 QueryCondition and ContentFilteredTopics IsoCpp(2) examples fail intermittently
+OSPL-10834 isocpp2 BuiltInTopics example fails to build on winxp13-new
+OSPL-10971 C# compilation failure in pinger.cs prior to .NET 4.0
\ No newline at end of file diff --git a/build/scripts/overnight/python/runExample.py b/build/scripts/overnight/python/runExample.py index e5e27c866..7d70d63ac 100644 --- a/build/scripts/overnight/python/runExample.py +++ b/build/scripts/overnight/python/runExample.py @@ -3,7 +3,7 @@ import os import sys import json -from host import host +from host import host from Durability import durability from Example import Example from Lifecycle import lifecycle @@ -23,7 +23,7 @@ def getLogger(debug): return examplelogger(debug) """ - Get the host for this test run + Get the host for this test run """ def getHost(): return host() @@ -32,7 +32,7 @@ def getHost(): Run all the examples - called if -a provided at the command line - extype will be "" """ def runAllExamples(host, logger, extype): - print("Running all examples") + print "Running all examples" runExampleAll(host, logger, "BuiltInTopics", extype) runExampleAll(host, logger, "ContentFilteredTopic", extype) runExampleAll(host, logger, "HelloWorld", extype) @@ -44,28 +44,33 @@ def runAllExamples(host, logger, extype): runExampleAll(host, logger, "RoundTrip", extype) runExampleAll(host, logger, "Throughput", extype) runExampleAll(host, logger, "Tutorial", extype) + runExampleAll(host, logger, "RMIClientServer", extype) + runExampleAll(host, logger, "RMIHelloWorld", extype) + runExampleAll(host, logger, "RMIPrinter", extype) runExampleAll(host, logger, "WaitSet", extype) runExampleAll(host, logger, "StreamsThroughput", extype) runExampleAll(host, logger, "FaceHelloWorld", extype) runExampleAll(host, logger, "protobuf", extype) + runExampleAll(host, logger, "Durability", extype) + runExampleAll(host, logger, "DBMSconnect", extype) """ Run all versions of the specifed example e.g. standalone/corba, all languages as appropriate to the example called from runAllExamples when -a specified at the command line or - called from main if -s specified at the command line with args other than example name + called from main if -s specified at the command line with args other than example name or all other args specified as "all" """ def runExampleAll(host, logger, example, extype): """ - Running the example expects that the OSPL_URI has been set - done via release.com/release.bat + Running the example expects that the OSPL_URI has been set - done via release.com/release.bat or via scripts on overnight test runs """ try: cur_uri = os.environ['OSPL_URI'] - except Exception: - print("Exception obtaining OSPL_URI") - raise Exception (str(sys.exc_info()[0])) + except Exception as e: + print "Exception obtaining OSPL_URI" + raise Exception (str(e)) expath = "" ex_uri = "" @@ -75,7 +80,7 @@ def runExampleAll(host, logger, example, extype): """ Durability has a separate python script due to the complexity of - the run i.e. it's not a single publisher/subscriber so set the + the run i.e. it's not a single publisher/subscriber so set the expath here """ if example == "Durability": @@ -97,10 +102,10 @@ def runExampleAll(host, logger, example, extype): Get the example class - usually Example.py but may be non-standard """ ex = getExample(host, logger, example) - print("Got the example - ", example) + print "Got the example - ", example try: - print("Running the " + example + " example on " + host.name) + print "Running the " + example + " example on " + host.name if example == "DBMSconnect" and ex.runDBMSConnect: ex.runExample() @@ -109,15 +114,15 @@ def runExampleAll(host, logger, example, extype): """ Run all types of this example e.g. standalone/corba, all languages """ - ex.runExampleAllTypes() + ex.runExampleAllTypes() else: """ Run type of example specified e.g. standalone OR corba, all languages """ ex.runExampleAll(extype) - - except Exception: - print("Exception running " + str(sys.exc_info()[0])) + + except Exception as e: + print "Exception running " + str(e) os.environ["OSPL_URI"] = cur_uri @@ -126,7 +131,7 @@ def runExampleAll(host, logger, example, extype): """ def getExample(host, logger, example): - print("Getting example for ", example) + print "Getting example for ", example if "RMI" in example: if "ClientServer" in example: @@ -162,53 +167,53 @@ def getExample(host, logger, example): """ Called when a single example has been requested at the command line - language can be c / cpp / cs / java / java5 / isocpp / isoccp2 or "all" + language can be c / cpp / cs / java / java5 / isoccp2 or "all" extype can be standalone / corba / "all" or "" types - meant for things like PingPong s / q / f etc - not actually implemented """ def runExampleSingle(host, example, language, extype, types): ex = getExample(host, logger, example) - print("Got the example") + print "Got the example" if example == "DBMSconnect" and ex.runDBMSConnect: ex.runExample() elif language == "all" and extype == "": ex.runExampleAllTypes() elif language == "all" and extype == "all": - ex.runExampleAllTypes() + ex.runExampleAllTypes() else: - print("Running example ", example, extype, types) + print "Running example ", example, extype, types if host.runExample(ex.expath, ex.name, language): ex.runExample(language, extype, types) def usage(): - print("Usage :-") - print("-a to run all examples") - print("") - print("-f use to provide a list of examples to run (NOT YET IMPLEMENTED)") - print(" is name of file containing list of examples") - print(" in format [types]") - print(" e.g. PingPong java standalone all") - print(" e.g. PingPong") - print(" e.g. c cpp java java5 isocpp isocpp2 or all to run all languages") - print(" e.g. standalone or corba where this exist") - print(" e.g. \"m\", \"s\" etc in PingPong example \"all\" (for all types) - can be blank") - print(" ") - print("-s to run a single example") - print(" e.g. -s PingPong java standalone all") - print(" -s PingPong all corba") - print(" -s HelloWorld ") - print(" -s HelloWorld cpp standalone") - print(" -s HelloWorld all") - print(" -s HelloWorld all standalone") - print(" -s DBMSConnect all") - print(" e.g. -s RMIClientServer cpp") - print(" -s StreamsThroughout cpp") - print(" -s FaceHelloWorld java") - print(" ") - print(" If only the -s is specified then all versions of the example will be run") - print("If you want to run with debug (to get extra output) then use -ad, -sd or -fd") + print "Usage :-" + print "-a to run all examples" + print "" + print "-f use to provide a list of examples to run (NOT YET IMPLEMENTED)" + print " is name of file containing list of examples" + print " in format [types]" + print " e.g. PingPong java standalone all" + print " e.g. PingPong" + print " e.g. c cpp java java5 isocpp2 or all to run all languages" + print " e.g. standalone or corba where this exist" + print " e.g. \"m\", \"s\" etc in PingPong example \"all\" (for all types) - can be blank" + print " " + print "-s to run a single example" + print " e.g. -s PingPong java standalone all" + print " -s PingPong all corba" + print " -s HelloWorld " + print " -s HelloWorld cpp standalone" + print " -s HelloWorld all" + print " -s HelloWorld all standalone" + print " -s DBMSConnect all" + print " e.g. -s RMIClientServer cpp " + print " -s StreamsThroughout cpp " + print " -s FaceHelloWorld java" + print " " + print " If only the -s is specified then all versions of the example will be run" + print "If you want to run with debug (to get extra output) then use -ad, -sd or -fd" exit() if __name__ == "__main__": @@ -220,28 +225,28 @@ def usage(): runArg = sys.argv[1] - print("runArg is " + runArg) + print "runArg is " + runArg if runArg == "-a": run_all = 1 elif runArg == "-s": run_single = 1 - elif runArg == "-ad": + elif runArg == "-ad": debug = 1 run_all = 1 elif runArg == "-sd": debug = 1 run_single = 1 elif runArg == "-h": - usage() + usage() else: usage() - - try: + + try: host = getHost() - except Exception: - print("Unable to get host ") - raise Exception (str(sys.exc_info()[0])) + except Exception as e: + print "Unable to get host " + raise Exception (str(e)) logger = getLogger(debug) @@ -249,26 +254,26 @@ def usage(): with open ('hosts.json') as data_file: data = json.load(data_file) - print("Hostname is ", host.name.strip()) - types = data[host.name.strip()]["examples"] + print "Hostname is ", host.name.strip() + types = data[host.name.strip()]["examples"] if run_all: if types[0] == "All": runAllExamples(host, logger, "") elif types[0] == "AllStandalone": - runAllExamples(host, logger, "standalone") + runAllExamples(host, logger, "standalone") else: - print("TO BE IMPLEMENTED...") + print "TO BE IMPLEMENTED..." else: - print("The number of args is " + str(len(sys.argv))) + print "The number of args is " + str(len(sys.argv)) if str(len(sys.argv)) < 3: - print("If not running all using -a you must provide -s as a minimum") + print "If not running all using -a you must provide -s as a minimum" usage() if runArg == "-f": - print("NOT YET IMPLEMENTED") - #print("The file name is " + sys.argv[2]) + print "NOT YET IMPLEMENTED" + #print "The file name is " + sys.argv[2] elif run_single: if types[0] == "AllStandalone": @@ -279,27 +284,27 @@ def usage(): types = "all" language = "all" - print("The example is " + sys.argv[2]) + print "The example is " + sys.argv[2] example = sys.argv[2] if len(sys.argv) > 3: - print("The language is " + sys.argv[3]) + print "The language is " + sys.argv[3] language = sys.argv[3] if len(sys.argv) > 4: - print("The type is " + sys.argv[4]) + print "The type is " + sys.argv[4] extype = sys.argv[4] if len(sys.argv) == 6: - print("The types is " + sys.argv[5]) - types = sys.argv[5] - print("Calling runExampleSingle with ", host.name, example, language, extype, types) + print "The types is " + sys.argv[5] + types = sys.argv[5] + print "Calling runExampleSingle with ", host.name, example, language, extype, types runExampleSingle(host, example, language, extype, types) sys.stdout.flush() - except Exception: - print("Exception running examples ", str(sys.exc_info()[0])) + except Exception as e: + print "Exception running examples ", str(e) sys.stdout.flush() finally: logger.finalizeResults() diff --git a/build/scripts/overnight/python/splicedCheck.py b/build/scripts/overnight/python/splicedCheck.py new file mode 100644 index 000000000..6014e1e9f --- /dev/null +++ b/build/scripts/overnight/python/splicedCheck.py @@ -0,0 +1,47 @@ +import sys +import time + +try: + import psutil + hasPsutil = True +except ImportError: + hasPsutil = False + + +def splicedCheck (mode): + + splicedFound = True + + if hasPsutil == True: + if mode == "start": + splicedFound = False + count = 0 + + while splicedFound == False and count < 10: + + time.sleep(1) + for proc in psutil.process_iter(): + if proc.name() == u"spliced.exe": + splicedFound = True + + if splicedFound == False: + count += 1 + + elif mode == "stop": + + count = 0 + splicedFound = True + while splicedFound == True and count < 10: + + time.sleep(1) + splicedFound = False + for proc in psutil.process_iter(): + if proc.name() == u"spliced.exe": + splicedFound = True + count += 1 + break + + else: + raise Exception("Invalid mode for splicedCheck..") + + return splicedFound diff --git a/build/scripts/overnight/python/test.py b/build/scripts/overnight/python/test.py index 2ba621cb2..22aaec745 100644 --- a/build/scripts/overnight/python/test.py +++ b/build/scripts/overnight/python/test.py @@ -2,6 +2,6 @@ import os -print("Content-Type: text/plain\n\n") +print "Content-Type: text/plain\n\n" for key in os.environ.keys(): - print("%30s %s \n" % (key,os.environ[key])) + print "%30s %s \n" % (key,os.environ[key]) diff --git a/build/scripts/overnight/python/yaml/contentfilteredtopic_javapub_conditions.yaml b/build/scripts/overnight/python/yaml/contentfilteredtopic_javapub_conditions.yaml new file mode 100644 index 000000000..eb441994f --- /dev/null +++ b/build/scripts/overnight/python/yaml/contentfilteredtopic_javapub_conditions.yaml @@ -0,0 +1,15 @@ +parseconditions: + desc: ContentFilteredTopic LogParser Conditions + + file: run.log + parsecontents: yes + type: local + + product: Vortex OpenSplice + + conditions: + - name: ge_entry + type: line + inst: All + required: yes + line: "GE: *" diff --git a/build/scripts/overnight/python/yaml/contentfilteredtopic_sub_conditions.yaml b/build/scripts/overnight/python/yaml/contentfilteredtopic_sub_conditions.yaml index f671c9fd6..63dee83b8 100644 --- a/build/scripts/overnight/python/yaml/contentfilteredtopic_sub_conditions.yaml +++ b/build/scripts/overnight/python/yaml/contentfilteredtopic_sub_conditions.yaml @@ -7,15 +7,15 @@ parseconditions: product: Vortex OpenSplice - conditions: + conditions: - name: sub_receive_ge type: line inst: All required: yes - line: "=== [ContentFilteredTopicDataSubscriber] receives stockQuote : (GE, *" + line: "*(*GE*,*" - name: sub_receive_msft type: line inst: 0 required: no - line: "=== [ContentFilteredTopicDataSubscriber] receives stockQuote : (MSFT, *" \ No newline at end of file + line: "*(*MSFT*,*" \ No newline at end of file diff --git a/build/scripts/overnight/python/yaml/lifecycle_pub_conditions.yaml b/build/scripts/overnight/python/yaml/lifecycle_pub_conditions.yaml index e64db0cfd..0f65459af 100644 --- a/build/scripts/overnight/python/yaml/lifecycle_pub_conditions.yaml +++ b/build/scripts/overnight/python/yaml/lifecycle_pub_conditions.yaml @@ -7,28 +7,28 @@ parseconditions: product: Vortex OpenSplice - conditions: + conditions: - name: msg_lifecycle type: line inst: All required: yes - line: "Message : *Lifecycle_*" + line: "*Message* : *Lifecycle_*" - name: ls_userid_1 type: line inst: All required: yes - line: "userID : 1" + line: "*userID* : *" - name: sample_sent type: line inst: All required: yes - line: "writerStates : *SAMPLE_SENT *" + line: "*writerStates* : *SAMPLE_SENT *" - name: stopping_subscriber type: line inst: All required: yes - line: "writerStates : *STOPPING_SUBSCRIBER*" + line: "*writerStates* : *STOPPING_SUBSCRIBER*" diff --git a/build/scripts/overnight/python/yaml/lifecycle_sub_conditions.yaml b/build/scripts/overnight/python/yaml/lifecycle_sub_conditions.yaml index 82d27da15..1344e131c 100644 --- a/build/scripts/overnight/python/yaml/lifecycle_sub_conditions.yaml +++ b/build/scripts/overnight/python/yaml/lifecycle_sub_conditions.yaml @@ -7,22 +7,22 @@ parseconditions: product: Vortex OpenSplice - conditions: + conditions: - name: msg_lifecycle type: line inst: All required: yes - line: "Message : *Lifecycle_*" + line: "*Message* : *Lifecycle_*" - name: sample_sent type: line inst: All required: yes - line: "writerStates : *SAMPLE_SENT *" + line: "*riterStates* : *SAMPLE_SENT *" - name: stopping_subscriber type: line inst: All required: yes - line: "writerStates : *STOPPING_SUBSCRIBER*" + line: "*riterStates* : *STOPPING_SUBSCRIBER*" diff --git a/build/scripts/overnight/python/yaml/odbcmsgboard_conditions.yaml b/build/scripts/overnight/python/yaml/odbcmsgboard_conditions.yaml index 3144e6d38..4a81881de 100644 --- a/build/scripts/overnight/python/yaml/odbcmsgboard_conditions.yaml +++ b/build/scripts/overnight/python/yaml/odbcmsgboard_conditions.yaml @@ -25,4 +25,4 @@ parseconditions: type: line inst: 10 required: yes - line: "SqlToDdsAndDbms: Message no*" + line: "DdsToDdsAndDbms: Message no*" diff --git a/build/scripts/overnight/python/yaml/ospl_info_conds.yaml b/build/scripts/overnight/python/yaml/ospl_info_conds.yaml index ee9fff533..a49ce9750 100644 --- a/build/scripts/overnight/python/yaml/ospl_info_conds.yaml +++ b/build/scripts/overnight/python/yaml/ospl_info_conds.yaml @@ -47,3 +47,5 @@ parseconditions: 'Description : Already tried to resend * message * times' 'Description : using network interface * selected arbitrarily from: *' 'Description : Failed to send * message * ' + 'Description : writer * topic * waiting on high watermark due to reader *' + 'Description : Time jumps are not supported on this platform.' diff --git a/build/scripts/overnight/python/yaml/ownership_sub_conditions.yaml b/build/scripts/overnight/python/yaml/ownership_sub_conditions.yaml index f6e2cced6..f600c429c 100644 --- a/build/scripts/overnight/python/yaml/ownership_sub_conditions.yaml +++ b/build/scripts/overnight/python/yaml/ownership_sub_conditions.yaml @@ -5,7 +5,7 @@ parseconditions: parsecontents: yes type: local - conditions: + conditions: - name: msft_inst type: line inst: All @@ -16,10 +16,10 @@ parseconditions: type: line inst: All required: yes - line: "MSFT * pub1 5" + line: "MSFT * pub1 * 5" - name: msft_pub2 type: line inst: All required: yes - line: "MSFT * pub2 10" \ No newline at end of file + line: "MSFT * pub2 * 10" \ No newline at end of file diff --git a/build/scripts/overnight/python/yaml/ping_conditions.yaml b/build/scripts/overnight/python/yaml/ping_conditions.yaml index 8ebd6e841..9126cbc80 100644 --- a/build/scripts/overnight/python/yaml/ping_conditions.yaml +++ b/build/scripts/overnight/python/yaml/ping_conditions.yaml @@ -27,21 +27,3 @@ parseconditions: inst: 0 required: no line: "Usage * blocks blocksize topic_id WRITE_PARTITION READ_PARTITION" - - - name: Active Ping Table - type: block - inst: 4 - threshold: 20 - linecount: 105 - firstline: Starting ping example - lastline: Completed ping example - pluslines: - # colon-space in next line hence quotes - - line: "PING: TIMEOUT - message lost" - maxinst: 5 - - line: "PING: TIMEOUT 2 - message lost" - maxinst: 5 - - line: "Invalid *" - maxinst: 1 - - line: "Usage *" - maxinst: 1 diff --git a/build/scripts/overnight/python/yaml/querycondition_pub_conditions.yaml b/build/scripts/overnight/python/yaml/querycondition_pub_conditions.yaml index e76de33a0..83e486dc4 100644 --- a/build/scripts/overnight/python/yaml/querycondition_pub_conditions.yaml +++ b/build/scripts/overnight/python/yaml/querycondition_pub_conditions.yaml @@ -1,15 +1,15 @@ parseconditions: desc: QueryCondition LogParser Conditions - + file: run.log parsecontents: yes type: local - + product: Vortex OpenSplice - - conditions: + + conditions: - name: pub_send type: line inst: All required: yes - line: "GE : * MSFT : *" \ No newline at end of file + line: "*GE*:*MSFT*:*" \ No newline at end of file diff --git a/build/scripts/overnight/python/yaml/querycondition_sub_conditions.yaml b/build/scripts/overnight/python/yaml/querycondition_sub_conditions.yaml index f6412322a..6447baeb6 100644 --- a/build/scripts/overnight/python/yaml/querycondition_sub_conditions.yaml +++ b/build/scripts/overnight/python/yaml/querycondition_sub_conditions.yaml @@ -1,16 +1,16 @@ parseconditions: desc: QueryCondition LogParser Conditions - + file: run.log parsecontents: yes type: local - + product: Vortex OpenSplice - - conditions: - + + conditions: + - name: sub_receive_msft type: line inst: All required: yes - line: "MSFT: *" \ No newline at end of file + line: "*MSFT*:*" \ No newline at end of file diff --git a/build/scripts/overnight/python/yaml/streams_throughput_conditions.yaml b/build/scripts/overnight/python/yaml/streams_throughput_conditions.yaml index 3ebc01ecf..b91495b2b 100644 --- a/build/scripts/overnight/python/yaml/streams_throughput_conditions.yaml +++ b/build/scripts/overnight/python/yaml/streams_throughput_conditions.yaml @@ -7,19 +7,13 @@ parseconditions: product: Vortex OpenSplice - conditions: + conditions: - name: tp_results type: line inst: All required: yes line: "payloadSize: 1 | flushMaxSamples: 10 | flushTimeOut: 0 | programTimeOut: 15 | partitionName: Streams Throughput example" - - name: tp_write - type: line - inst: All - required: yes - line: "Writing samples ....." - - name: tp_samples_written type: line inst: All diff --git a/build/scripts/overnight/python/yaml/throughput_pub_conditions.yaml b/build/scripts/overnight/python/yaml/throughput_pub_conditions.yaml index 03d13872d..e955826e8 100644 --- a/build/scripts/overnight/python/yaml/throughput_pub_conditions.yaml +++ b/build/scripts/overnight/python/yaml/throughput_pub_conditions.yaml @@ -7,15 +7,9 @@ parseconditions: product: Vortex OpenSplice - conditions: - - name: tp_results - type: line - inst: All - required: yes - line: "Payload size: * | Total received: * samples, * bytes | Out of order: * samples | Transfer rate: * samples/s, * Mbit/s" - + conditions: - name: tp_samples_written type: line inst: All required: yes - line: " * samples" \ No newline at end of file + line: " * samples written" \ No newline at end of file diff --git a/build/scripts/overnight/run_examples.bat b/build/scripts/overnight/run_examples.bat index a1b0e2447..a7ad35583 100644 --- a/build/scripts/overnight/run_examples.bat +++ b/build/scripts/overnight/run_examples.bat @@ -39,7 +39,7 @@ ECHO Set Microsoft Visual Studio Environment using VS supplied batch file IF "%VS_ENV_SCRIPT%"=="" EXIT 1 -IF NOT "%VS_ENV_SCRIPT%"=="" call "%VS_ENV_SCRIPT%" +IF NOT "%VS_ENV_SCRIPT%"=="" call "%VS_ENV_SCRIPT%" %VS_ENV_SCRIPT_ARGS% cd "%OSPL_HOME%" diff --git a/build/scripts/overnight/run_examples.sh b/build/scripts/overnight/run_examples.sh index fb04b36c1..10e4c38aa 100755 --- a/build/scripts/overnight/run_examples.sh +++ b/build/scripts/overnight/run_examples.sh @@ -1,6 +1,6 @@ #set -x -# For platforms which have suid busybox as /bin/sh so reset LD_LIBRARY_PATH +# For platforms which have suid busybox as /bin/sh so reset LD_LIBRARY_PATH if [ "$OVERRIDE_LD_LIBRARY_PATH" != "" ] then echo "Setting LD_LIBRARY_PATH from OVERRIDE_LD_LBIRARY_PATH" @@ -17,7 +17,7 @@ then export PATH fi -. $BASE/example_results_fns +. $BASE/example_results_fns if [ "$JAVA_HOME" != "" ] then @@ -64,11 +64,11 @@ else if [ -n "$UNIQUE_MC_ADDRESS" ] - then + then grep SPDPMulticastAddress $XMLFILE if [ $? = 0 ] then - echo "ERROR : SPDPMulticastAddress already exists" + echo "ERROR : SPDPMulticastAddress already exists" exit 1; fi sed -e "s@ospl_[^<]*@oex_$UNIQID@" \ @@ -85,16 +85,13 @@ else grep MulticastRecvNetworkInterfaceAddresses $XMLFILE if [ $? = 0 ] then - echo "ERROR : MulticastRecvNetworkInterfaceAddresses already exists" + echo "ERROR : MulticastRecvNetworkInterfaceAddresses already exists" exit 1; fi sed -e "s@ospl_[^<]*@oex_$UNIQID@" \ -e "s@0@$UNIQID@" \ -e 's@AUTO@127.0.0.1\ 127.0.0.1@' < $XMLFILE > $NEWXMLFILE - - sed -e '//a*' -i $NEWXMLFILE - # sanity check that the sed'ing worked (i.e. that the strings existed in the first place) grep MulticastRecvNetworkInterfaceAddresses $NEWXMLFILE if [ $? = 1 ] @@ -112,7 +109,7 @@ echo "NEWXMLFILE is $NEWXMLFILE" ODBCINI="$ODBCHOME/etc/odbc.ini" ODBCINST="$ODBCHOME/etc/odbcinst.ini" -ODBC_MSSQL_SERVER="10.1.0.189" +ODBC_MSSQL_SERVER="10.1.5.197" ODBC_MYSQL_SERVER="10.1.0.191" ODBCSYSINI="$ODBCHOME/etc" LD_LIBRARY_PATH="$ODBCHOME/lib:.:$LD_LIBRARY_PATH" @@ -132,8 +129,9 @@ RUN_SUMMARY_LOG=$LOGDIR/examples/run_$EXRUNTYPE/run_results_summary.txt RUN_LOG=$LOGDIR/examples/run_$EXRUNTYPE/run_results.txt SUMMARY_LOG=$LOGDIR/examples/run_$EXRUNTYPE/examples.log TOTALS_LOG=$LOGDIR/examples/run_$EXRUNTYPE/totals.log +KILLED_LOG=$LOGDIR/examples/run_$EXRUNTYPE/killed_processes.log -export RUN_SUMMARY_LOG RUN_LOG SUMMARY_LOG TOTALS_LOG +export RUN_SUMMARY_LOG RUN_LOG SUMMARY_LOG TOTALS_LOG KILLED_LOG CUR_PATH=`pwd` echo " Begin running examples - `date`" @@ -186,7 +184,7 @@ do sh RUN $EXRUNTYPE >> run.log 2>&1 status=$? - check_example_result $PROJECT + check_example_result $PROJECT mkdir $LOGDIR/examples/run_$EXRUNTYPE/$EXAMPLEDIR cp $CUR_PATH/$PROJECT/*.log $LOGDIR/examples/run_$EXRUNTYPE/$EXAMPLEDIR diff --git a/build/scripts/overnight/run_python_examples.bat b/build/scripts/overnight/run_python_examples.bat index c5c6b7d8d..2f47ec915 100644 --- a/build/scripts/overnight/run_python_examples.bat +++ b/build/scripts/overnight/run_python_examples.bat @@ -1,12 +1,11 @@ @ECHO OFF +SETLOCAL + pwd call setenv.bat -REM run set to see what is actually set -set - REM RUN_LOG is a logfile containing the full test results ECHO cd %OSPL_HOME% (OSPL_HOME) @@ -17,6 +16,9 @@ call release.bat set PATH=c:\Python27;%PATH% set HOSTNAME +REM run set to see what is actually set +set + mkdir "%OSPL_HOME%\etc\tmp" IF "%TMP%"=="" set TMP=%OSPL_HOME%\etc\tmp IF "%TEMP%"=="" set TEMP=%OSPL_HOME%\etc\tmp @@ -37,3 +39,5 @@ cd %OSPLI_BASE% cd python python runExample.py -a + +ENDLOCAL diff --git a/build/scripts/overnight/run_python_examples.sh b/build/scripts/overnight/run_python_examples.sh index 909f6541e..140ef468e 100755 --- a/build/scripts/overnight/run_python_examples.sh +++ b/build/scripts/overnight/run_python_examples.sh @@ -45,8 +45,8 @@ if [ "$EXRUNTYPE" = "shm" ] then XMLFILE=`echo $OSPL_URI | sed 's@file://@@' | sed 's/ospl.xml$/ospl_shmem_no_network.xml/'` NEWXMLFILE=`echo $XMLFILE | sed 's/_no_network.xml$/_no_network_uniq.xml/'` - - # Mac OS builds seem to have a problem with the \ in the sed command + + # Mac OS builds seem to have a problem with the \ in the sed command if [ "$CURRENT_PL_DARWIN" != "" ] then sed -e "s@ospl_[^<]*@oex_$UNIQID@" -e "s@0@$UNIQID@" -e "s@50000@Auto@" -e "s@10485760@$DBSIZE@" < $XMLFILE > $NEWXMLFILE @@ -63,11 +63,11 @@ else NEWXMLFILE=`echo $XMLFILE | sed 's/ospl_sp_ddsi.xml$/ospl_sp_ddsi_uniq.xml/'` if [ -n "$UNIQE_MC_ADDRESS" ] - then + then grep SPDPMulticastAddress $XMLFILE if [ $? = 0 ] then - echo "ERROR : SPDPMulticastAddress already exists" + echo "ERROR : SPDPMulticastAddress already exists" exit 1; fi @@ -86,7 +86,7 @@ else grep MulticastRecvNetworkInterfaceAddresses $XMLFILE if [ $? = 0 ] then - echo "ERROR : MulticastRecvNetworkInterfaceAddresses already exists" + echo "ERROR : MulticastRecvNetworkInterfaceAddresses already exists" exit 1; fi @@ -95,8 +95,6 @@ else -e 's@AUTO@127.0.0.1\ 127.0.0.1@' < $XMLFILE > $NEWXMLFILE - sed -e '//a*' -i $NEWXMLFILE - # sanity check that the sed'ing worked (i.e. that the strings existed in the first place) grep MulticastRecvNetworkInterfaceAddresses $NEWXMLFILE if [ $? = 1 ] @@ -114,7 +112,7 @@ echo "NEWXMLFILE is $NEWXMLFILE" ODBCINI="$ODBCHOME/etc/odbc.ini" ODBCINST="$ODBCHOME/etc/odbcinst.ini" -ODBC_MSSQL_SERVER="10.1.0.189" +ODBC_MSSQL_SERVER="10.1.5.197" ODBC_MYSQL_SERVER="10.1.0.191" ODBCSYSINI="$ODBCHOME/etc" LD_LIBRARY_PATH="$ODBCHOME/lib:.:$LD_LIBRARY_PATH" diff --git a/demos/iShapes/BouncingShapeDynamics.hpp b/demos/iShapes/BouncingShapeDynamics.hpp index 826f26cca..d6c0beac7 100644 --- a/demos/iShapes/BouncingShapeDynamics.hpp +++ b/demos/iShapes/BouncingShapeDynamics.hpp @@ -1,5 +1,5 @@ #ifndef _BOUNCINGSHAPEDYNAMICS_HPP -#define _BOUNCINGSHAPEDYNAMICS_HPP +#define _BOUNCINGSHAPEDYNAMICS_HPP /** @file */ /** diff --git a/demos/iShapes/Circle.hpp b/demos/iShapes/Circle.hpp index a31686eec..12a1f46a6 100644 --- a/demos/iShapes/Circle.hpp +++ b/demos/iShapes/Circle.hpp @@ -1,5 +1,5 @@ #ifndef _CIRCLE_HPP -#define _CIRCLE_HPP +#define _CIRCLE_HPP /** @file */ /** @@ -7,7 +7,6 @@ */ /** @{*/ -//#include #include #include diff --git a/demos/iShapes/DDSShapeDynamics.cpp b/demos/iShapes/DDSShapeDynamics.cpp index 0f506faf1..ee09bf1ea 100644 --- a/demos/iShapes/DDSShapeDynamics.cpp +++ b/demos/iShapes/DDSShapeDynamics.cpp @@ -47,11 +47,10 @@ DDSShapeDynamics::simulate() QPoint tmp; - //samples::iterator sample; samples = shapeReader_.read(); plist_.erase(plist_.begin(), plist_.end()); - //Create a dummy when the subscribe button is clicked until the first sample arrives + // Create a dummy when the subscribe button is clicked until the first sample arrives if(dummy_ == true) { SharedShape shape; diff --git a/demos/iShapes/DDSShapeDynamics.hpp b/demos/iShapes/DDSShapeDynamics.hpp index 6135166db..b0c8af8d2 100644 --- a/demos/iShapes/DDSShapeDynamics.hpp +++ b/demos/iShapes/DDSShapeDynamics.hpp @@ -1,5 +1,5 @@ #ifndef _DDSSHAPEDYNAMICS_HPP -#define _DDSSHAPEDYNAMICS_HPP +#define _DDSSHAPEDYNAMICS_HPP /** @file */ @@ -61,7 +61,6 @@ class DDSShapeDynamics : public ShapeDynamics virtual void simulate(); private: - //DDSShapeDynamics(const DDSShapeDynamics& orig); WeakSharedShape shape_; int x0_; int y0_; diff --git a/demos/iShapes/ReaderQosDialog.cpp b/demos/iShapes/ReaderQosDialog.cpp index dcd8adfdb..33feb33cf 100644 --- a/demos/iShapes/ReaderQosDialog.cpp +++ b/demos/iShapes/ReaderQosDialog.cpp @@ -36,7 +36,13 @@ ReaderQosDialog::get_qos() qos_ << dds::core::policy::LatencyBudget(dds::core::Duration::infinite()); if (qosForm_.reliableRButt->isChecked()) + { qos_ << dds::core::policy::Reliability::Reliable(); + } + else + { + qos_ << dds::core::policy::Reliability::BestEffort(); + } switch (qosForm_.durabilityComboBox->currentIndex()) { @@ -55,7 +61,14 @@ ReaderQosDialog::get_qos() }; if (qosForm_.exclusiveRButt->isChecked()) + { qos_ << dds::core::policy::Ownership::Exclusive(); + } + else + { + qos_ << dds::core::policy::Ownership::Shared(); + } + if (qosForm_.keepLastRButton->isChecked()) { qos_ << dds::core::policy::History::KeepLast(qosForm_.depthSpinBox->value()); @@ -66,11 +79,12 @@ ReaderQosDialog::get_qos() h.depth(-1); qos_ << h; } + if (qosForm_.timeBasedFilterActive->isChecked()) { int64_t period = qosForm_.timeBasedFilterValue->text().toInt(); dds::core::Duration d; qos_ << dds::core::policy::TimeBasedFilter(d.from_millisecs(period)); - } + } return qos_; } diff --git a/demos/iShapes/Shape.hpp b/demos/iShapes/Shape.hpp index f7a3691ee..eff023455 100644 --- a/demos/iShapes/Shape.hpp +++ b/demos/iShapes/Shape.hpp @@ -1,5 +1,5 @@ #ifndef _SHAPE_HPP -#define _SHAPE_HPP +#define _SHAPE_HPP /** @file */ /** diff --git a/demos/iShapes/ShapeDynamics.hpp b/demos/iShapes/ShapeDynamics.hpp index e02fb6d6d..9256431b9 100644 --- a/demos/iShapes/ShapeDynamics.hpp +++ b/demos/iShapes/ShapeDynamics.hpp @@ -1,5 +1,5 @@ #ifndef _SHAPEDYNAMICS_HPP -#define _SHAPEDYNAMICS_HPP +#define _SHAPEDYNAMICS_HPP /** @file */ /** diff --git a/demos/iShapes/ShapesDialog.cpp b/demos/iShapes/ShapesDialog.cpp index c0bb122c6..1f3af33f3 100644 --- a/demos/iShapes/ShapesDialog.cpp +++ b/demos/iShapes/ShapesDialog.cpp @@ -139,7 +139,6 @@ ShapesDialog::onPublishButtonClicked() QRect constr(0, 0, IS_WIDTH, IS_HEIGHT); - // QRect constr = this->geometry(); int x = constr.width() * ((float)rand() / RAND_MAX); int y = constr.height() * ((float)rand() / RAND_MAX); int cIdx = mainWidget.colorList->currentIndex(); diff --git a/demos/iShapes/ShapesDialog.hpp b/demos/iShapes/ShapesDialog.hpp index 2cb0eaf49..6cfb990ae 100644 --- a/demos/iShapes/ShapesDialog.hpp +++ b/demos/iShapes/ShapesDialog.hpp @@ -1,5 +1,5 @@ #ifndef _ISHAPESFORM_HPP -#define _ISHAPESFORM_HPP +#define _ISHAPESFORM_HPP /** @file */ @@ -101,12 +101,12 @@ private slots: #endif private: - QTimer timer; + QTimer timer; Ui::ShapesDialog mainWidget; ShapesWidget* shapesWidget; - ReaderQosDialog readerQos_; - WriterQosDialog writerQos_; - FilterDialog* filterDialog_; + ReaderQosDialog readerQos_; + WriterQosDialog writerQos_; + FilterDialog* filterDialog_; dds::domain::DomainParticipant dp_; dds::core::policy::Partition gQos_; diff --git a/demos/iShapes/ShapesWidget.cpp b/demos/iShapes/ShapesWidget.cpp index 2e7c4bd77..37539260b 100644 --- a/demos/iShapes/ShapesWidget.cpp +++ b/demos/iShapes/ShapesWidget.cpp @@ -13,7 +13,6 @@ ShapesWidget::ShapesWidget(QWidget *parent) : QWidget(parent), showCurrentFilter_(false), logo_(":/images/ospl-dds-br.png"), - ptpcm_(":/images/pt_pcm.png"), paused_(false) { this->setBackgroundRole(QPalette::Base); @@ -52,8 +51,6 @@ ShapesWidget::paintEvent(QPaintEvent*) QPainter painter(this); painter.setRenderHint(QPainter::Antialiasing, true); painter.drawPixmap(ISOCPP_LOGO_X, ISOCPP_LOGO_Y, logo_); - /* This code adds the PrismTech logo to the top-centre of the iShapes canvas. */ - /* painter.drawPixmap(BRAND_LOGO_X, BRAND_LOGO_Y, ptpcm_);*/ if (showCurrentFilter_) { QBrush brush(QColor(0x99,0x99,0x99,0x99), Qt::SolidPattern); diff --git a/demos/iShapes/ShapesWidget.hpp b/demos/iShapes/ShapesWidget.hpp index e83fcdd56..f02cf62fc 100644 --- a/demos/iShapes/ShapesWidget.hpp +++ b/demos/iShapes/ShapesWidget.hpp @@ -1,5 +1,5 @@ #ifndef _SHAPESWIDGET_HPP -#define _SHAPESWIDGET_HPP +#define _SHAPESWIDGET_HPP /** @file */ /** @@ -54,7 +54,6 @@ public slots: QRect currentFilter_; bool showCurrentFilter_; QPixmap logo_; - QPixmap ptpcm_; QPixmap simd_; bool paused_; }; diff --git a/demos/iShapes/Square.cpp b/demos/iShapes/Square.cpp index 71c5861cd..253c83921 100644 --- a/demos/iShapes/Square.cpp +++ b/demos/iShapes/Square.cpp @@ -18,7 +18,6 @@ Square::Square(const QRect& bounds, void Square::update() { - // std::cout << ">>SQUARE::simulate" << std::endl; dynamics_->simulate(); } @@ -28,13 +27,6 @@ Square::paint(QPainter& painter) painter.setBrush(brush_); painter.setPen(pen_); - /* - painter.drawRect(dynamics_->getPosition().x(), - dynamics_->getPosition().y(), - bounds_.width(), - bounds_.height()); - */ - // std::cout << "SQUARE::paint" << std::endl; std::vector plist = dynamics_->getPositionList(); std::vector::iterator idx = plist.begin(); QBrush black( QColor(0x33, 0x33, 0x33), Qt::SolidPattern); diff --git a/demos/iShapes/Square.hpp b/demos/iShapes/Square.hpp index 9362b29bd..826146dbf 100644 --- a/demos/iShapes/Square.hpp +++ b/demos/iShapes/Square.hpp @@ -1,5 +1,5 @@ #ifndef _SQUARE_HPP -#define _SQUARE_HPP +#define _SQUARE_HPP /** @file */ /** diff --git a/demos/iShapes/Triangle.hpp b/demos/iShapes/Triangle.hpp index 919a27041..38fc5e7d9 100644 --- a/demos/iShapes/Triangle.hpp +++ b/demos/iShapes/Triangle.hpp @@ -1,5 +1,5 @@ #ifndef _TRIANGLE_HPP -#define _TRIANGLE_HPP +#define _TRIANGLE_HPP /** @file */ #include diff --git a/demos/iShapes/WriterQosDialog.cpp b/demos/iShapes/WriterQosDialog.cpp index b49e73efa..77fbe3535 100644 --- a/demos/iShapes/WriterQosDialog.cpp +++ b/demos/iShapes/WriterQosDialog.cpp @@ -34,7 +34,13 @@ WriterQosDialog::get_qos() qos_ = tmpQos; if (qosForm_.reliableRButt->isChecked()) + { qos_ << dds::core::policy::Reliability::Reliable(); + } + else + { + qos_ << dds::core::policy::Reliability::BestEffort(); + } switch (qosForm_.durabilityComboBox->currentIndex()) { @@ -59,6 +65,10 @@ WriterQosDialog::get_qos() qos_ << dds::core::policy::Ownership::Exclusive(); qos_ << dds::core::policy::OwnershipStrength(qosForm_.strengthSpinBox->value()); } + else + { + qos_ << dds::core::policy::Ownership::Shared(); + } if (qosForm_.keepLastWButton->isChecked()) { diff --git a/demos/iShapes/config.hpp b/demos/iShapes/config.hpp index 12eaf00b9..1c66981dc 100644 --- a/demos/iShapes/config.hpp +++ b/demos/iShapes/config.hpp @@ -18,10 +18,6 @@ #define DS_MAX_INSTANCES 4196 #define DS_MAX_SAMPLES_X_INSTANCE 8192 -/* - painter.drawPixmap(15, 300, logo_); - painter.drawPixmap(200, 10, simd_); - */ #if (ISHAPES_WIDE_FORMAT == 1) # define IS_WIDTH 501 # define IS_HEIGHT 361 diff --git a/demos/iShapes/distrib/ishapes-lan.xml b/demos/iShapes/distrib/ishapes-lan.xml index ecab8750d..e30dd70d6 100644 --- a/demos/iShapes/distrib/ishapes-lan.xml +++ b/demos/iShapes/distrib/ishapes-lan.xml @@ -1,28 +1,48 @@ - - - prismtech_ishapes_demo - 0 - true - - ddsi2 - - - - - - - - AUTO - true - true - false - - - - lax - - - - + + + prismtech_ishapes_demo + 0 + true + + ddsi2 + + + durability + + + + + AUTO + true + true + false + + + + lax + + + + + + + false + + 2.5 + 0.1 + + + + ddsi2 + + + + + * + + + + + diff --git a/demos/iShapes/iShapes.mpc b/demos/iShapes/iShapes.mpc index 10bc108d7..deee8bcdb 100644 --- a/demos/iShapes/iShapes.mpc +++ b/demos/iShapes/iShapes.mpc @@ -1,5 +1,4 @@ // -*- MPC -*- -// $Id$ project (Build*) : ospl_qt4, ospl_dcpsisocpp2, isosacpp2_typesupport, ospl_build_lib { TypeSupport_Files { diff --git a/demos/iShapes/images/logo.png b/demos/iShapes/images/logo.png deleted file mode 100644 index 09e8bb961..000000000 Binary files a/demos/iShapes/images/logo.png and /dev/null differ diff --git a/demos/iShapes/images/pt_pcm.png b/demos/iShapes/images/pt_pcm.png deleted file mode 100644 index 4c1a231ff..000000000 Binary files a/demos/iShapes/images/pt_pcm.png and /dev/null differ diff --git a/demos/iShapes/images/simd.png b/demos/iShapes/images/simd.png deleted file mode 100644 index 397754c3b..000000000 Binary files a/demos/iShapes/images/simd.png and /dev/null differ diff --git a/demos/iShapes/ishape.qrc b/demos/iShapes/ishape.qrc index dc9c5f266..249a6ff95 100644 --- a/demos/iShapes/ishape.qrc +++ b/demos/iShapes/ishape.qrc @@ -1,7 +1,5 @@ images/ospl-dds-br.png -images/simd.png -images/pt_pcm.png diff --git a/demos/iShapes/ishape.qrc.depends b/demos/iShapes/ishape.qrc.depends index dc9c5f266..249a6ff95 100644 --- a/demos/iShapes/ishape.qrc.depends +++ b/demos/iShapes/ishape.qrc.depends @@ -1,7 +1,5 @@ images/ospl-dds-br.png -images/simd.png -images/pt_pcm.png diff --git a/demos/iShapes/main.cpp b/demos/iShapes/main.cpp index 429342dbf..fd86521ad 100644 --- a/demos/iShapes/main.cpp +++ b/demos/iShapes/main.cpp @@ -4,7 +4,7 @@ #include #include #ifdef _WIN32 - #include + #include #endif #ifdef TESTBUILD #include @@ -48,7 +48,6 @@ int main(int argc, char *argv[]) srand(clock()); demo::ishapes::iShapes app(argc, argv); #ifdef TESTBUILD - /** @todo Simon - sort this out */ Q_INIT_RESOURCE(ishape_qrc); #else Q_INIT_RESOURCE(ishape); @@ -74,12 +73,12 @@ int main(int argc, char *argv[]) } #endif #ifdef TESTBUILD - //Start publishing a circle with default QoS + // Start publishing a circle with default QoS QTest::qExec(&shapes, argc, argv); #else - #ifdef _WIN32 - FreeConsole(); - #endif + #ifdef _WIN32 + FreeConsole(); + #endif shapes.show(); #endif retval = app.exec(); diff --git a/demos/iShapes/topic-traits.hpp b/demos/iShapes/topic-traits.hpp index ced09d78e..734046bfa 100644 --- a/demos/iShapes/topic-traits.hpp +++ b/demos/iShapes/topic-traits.hpp @@ -1,5 +1,5 @@ #ifndef _TOPIC_TRAITS_HPP -#define _TOPIC_TRAITS_HPP +#define _TOPIC_TRAITS_HPP /** @file */ /** diff --git a/docs/css/prismstyle.css b/docs/css/style.css similarity index 100% rename from docs/css/prismstyle.css rename to docs/css/style.css diff --git a/docs/html/ConfGuide/_sources/guide.txt b/docs/html/ConfGuide/_sources/guide.txt index ea48d0af6..0c74aa17b 100644 --- a/docs/html/ConfGuide/_sources/guide.txt +++ b/docs/html/ConfGuide/_sources/guide.txt @@ -35,9 +35,8 @@ OpenSplice The OpenSplice middleware including its services can be configured by means of easy maintainable XML-file(s). -- Full path: //OpenSplice +- Full path: /OpenSplice - Occurrences min-max: 1-1 -- Child elements: Description Domain ****** @@ -56,9 +55,9 @@ Domain to terminate elegantly. Once this has succeeded, the Domain service will destroy the administration and finally terminate itself. -- Full path: //OpenSplice/Domain +- Full path: /Domain - Occurrences min-max: 1-1 -- Child elements: Name, Id, Role, ServiceTerminatePeriod, SingleProcess, Description, CPUAffinity, InProcessExceptionHandling, RetentionPeriod, y2038Ready +- Child elements: Name, Id, Role, ServiceTerminatePeriod, SingleProcess, CPUAffinity, InProcessExceptionHandling, RetentionPeriod Name ==== @@ -67,7 +66,7 @@ Name this name to a name that identifies the domain. If several different DDS domains are required to run simultaneously, then they all need to have their own domain name. -- Full path: //OpenSplice/Domain/Name +- Full path: /Domain/Name - Format: string - Default value: OpenSpliceV6 - Occurrences min-max: 1-1 @@ -83,26 +82,20 @@ Id Please see section 9.6.1 of the Real-time Publish-Subscribe Wire Protocol DDS Interoperability Wire Protocol specification (DDSI), v2.1, formal/2009-01-05 at http://www.omg.org/spec/DDSI/2.1/ for further information. -- Full path: //OpenSplice/Domain/Id +- Full path: /Domain/Id - Format: integer - Default value: 0 -- Valid values: 0 / 2147483646 -- Occurrences min-max: 0-1 +- Occurrences min-max: 1-1 Role ==== - Within a system and depending on the hosted application a Domain Service can - have a specific role and interaction with other Domain Services may depend on this - role. - The Role element is a user-defined string value that is communicated through the - system, the behavior of other Domain Services i.e. how they interact with a Domain - Service can be configured depend of the role by means of string matching - expressions. For example, a Domain Service could limit its communication with - other Domain Services by only accepting specific roles. (See also - OpenSplice/NetworkService/Discovery[@Scope] ) + This (optional) element specifies the role of the instantiated domain. For dynamic discovery, this role will + be used to define the communication scope of instantiated domains on other nodes in the system. The purpose + of specifying roles within the system is to 'overlay' the underlying physical network with a node's scope-of-interest + that allows to bound topology discovery effort and related overhead in large scale (WAN) systems. -- Full path: //OpenSplice/Domain/Role +- Full path: /Domain/Role - Format: string - Default value: DefaultRole - Occurrences min-max: 0-1 @@ -110,13 +103,10 @@ Role Lease ===== - The Lease parameter specifies the death detection time of the Domain Service. All - internal tasks performed by the Domain Service will periodically update their - liveliness; when one or more tasks fail to update its liveliness the Domain will take - action to either repair the failing functionality, continue in a degraded mode, or halt, - depending on the configured desired behaviour. + The Lease parameters specify how the Domain service as well as the services started by the + Domain service must announce their liveliness in the DDS administration. -- Full path: //OpenSplice/Domain/Lease +- Full path: /Domain/Lease - Occurrences min-max: 0-1 - Child elements: ExpiryTime @@ -131,11 +121,8 @@ ExpiryTime non-responsiveness of a service is detected, but leads to more processing. Increasing it has the opposite effect. -- Full path: //OpenSplice/Domain/Lease/ExpiryTime -- Format: float -- Dimension: seconds +- Full path: /Domain/Lease/ExpiryTime - Default value: 10.0 -- Valid values: 0.2 / - - Occurrences min-max: 1-1 - Required attributes: update_factor @@ -148,10 +135,8 @@ update_factor often than required by the *ExpiryTime*. Services will report their liveliness every *ExpiryTime* multiplied by this *update_factor*. -- Full path: //OpenSplice/Domain/Lease/ExpiryTime[@update_factor] -- Format: float +- Full path: /Domain/Lease/ExpiryTime/update_factor - Default value: 0.2 -- Valid values: 0.01 / 1.0 - Required: true GeneralWatchdog @@ -162,7 +147,7 @@ GeneralWatchdog Every service has its own Watchdog thread, that is responsible for automatically renewing the lease for that service. Services that do not renew their lease in time will loose the liveliness of all their writers -- Full path: //OpenSplice/Domain/GeneralWatchdog +- Full path: /Domain/GeneralWatchdog - Occurrences min-max: 0-1 Scheduling @@ -171,7 +156,7 @@ Scheduling This element specifies the type of OS scheduling class will be used by the thread that announces its liveliness periodically. -- Full path: //OpenSplice/Domain/GeneralWatchdog/Scheduling +- Full path: /Domain/GeneralWatchdog/Scheduling - Occurrences min-max: 1-1 - Child elements: Priority, Class @@ -184,7 +169,7 @@ Priority The user may need special privileges from the underlying operating system to be able to assign some of the privileged priorities. -- Full path: //OpenSplice/Domain/GeneralWatchdog/Scheduling/Priority +- Full path: /Domain/GeneralWatchdog/Scheduling/Priority - Format: integer - Default value: 0 - Occurrences min-max: 1-1 @@ -196,7 +181,7 @@ priority_kind This attribute specifies whether the specified Priority is a relative or absolute priority. -- Full path: //OpenSplice/Domain/GeneralWatchdog/Scheduling/Priority[@priority_kind] +- Full path: /Domain/GeneralWatchdog/Scheduling/Priority/priority_kind - Format: enumeration - Default value: Relative - Valid values: Relative, Absolute @@ -210,7 +195,7 @@ Class the underlying operating system to be able to assign some of the privileged scheduling classes. -- Full path: //OpenSplice/Domain/GeneralWatchdog/Scheduling/Class +- Full path: /Domain/GeneralWatchdog/Scheduling/Class - Format: enumeration - Default value: Default - Valid values: Timeshare, Realtime, Default @@ -230,11 +215,8 @@ ServiceTerminatePeriod Consequently the '0' value should only be used when there is some form of process management on top of OpenSplice DDS. -- Full path: //OpenSplice/Domain/ServiceTerminatePeriod -- Format: float -- Dimension: seconds +- Full path: /Domain/ServiceTerminatePeriod - Default value: 10.0 -- Valid values: 0.0 / 60.0 - Occurrences min-max: 0-1 SingleProcess @@ -246,12 +228,9 @@ SingleProcess Please note that the choice to use the single process deployment also implies the use of heap memory for the OpenSplice database management instead of shared - memory that would be used otherwise. If no database size or size 0 is configured - the heap memory is limited by the Operating System, so the Database element under - Domain does not take effect when SingleProcess has a value of True. - If the database size is configured with a value, a database will be allocated on - heap with that size and the domain service will use it's own memory manager to - manage that memory + memory that would be used otherwise. The heap memory is limited by the + Operating System, so the Database element under Domain does not take effect + when SingleProcess has a value of True. There are two ways in which to deploy an OpenSplice DDS application as a single process: @@ -276,27 +255,17 @@ SingleProcess take effect when this SingleProcess attribute has a value of true. -- Full path: //OpenSplice/Domain/SingleProcess +- Full path: /Domain/SingleProcess - Format: boolean - Default value: false - Occurrences min-max: 0-1 -Description -=========== - - The content of this (optional) element is visualised by the Launcher tool and is meant - to describe the configuration in a human-readable form. - -- Full path: //OpenSplice/Domain/Description -- Format: string -- Occurrences min-max: 0-1 - CPUAffinity =========== This (optional) element specifies a comma separated list of CPU numbers for the CPUs which opensplice, and its services should be restricted to use. (Supported on VxWorks kernel mode only) -- Full path: //OpenSplice/Domain/CPUAffinity +- Full path: /Domain/CPUAffinity - Format: string - Occurrences min-max: 0-1 @@ -318,7 +287,7 @@ InProcessExceptionHandling By default this configuration item is set to true. -- Full path: //OpenSplice/Domain/InProcessExceptionHandling +- Full path: /Domain/InProcessExceptionHandling - Format: boolean - Default value: true - Occurrences min-max: 0-1 @@ -332,7 +301,7 @@ Daemon look for several child-elements. Each of these child elements is listed and explained. -- Full path: //OpenSplice/Domain/Daemon +- Full path: /Domain/Daemon - Occurrences min-max: 0-1 - Child elements: Locking @@ -351,7 +320,7 @@ Locking appropriate privileges from the underlying operating system to be able to use this option. -- Full path: //OpenSplice/Domain/Daemon/Locking +- Full path: /Domain/Daemon/Locking - Format: boolean - Default value: false - Occurrences min-max: 0-1 @@ -359,14 +328,10 @@ Locking Watchdog -------- - This element controls the scheduling characteristics of the Watchdog thread. This - thread is responsible for sending domain service heartbeats, updating liveliness of - the service builtin DataWriters and monitoring the health of internal services and - heartbeats of remote domain services. + This element controls the characteristics of the Spliced Daemon Watchdog thread -- Full path: //OpenSplice/Domain/Daemon/Watchdog +- Full path: /Domain/Daemon/Watchdog - Occurrences min-max: 0-1 -- Child elements: StackSize Scheduling ^^^^^^^^^^ @@ -374,7 +339,7 @@ Scheduling This element specifies the type of OS scheduling class will be used by the thread that announces its liveliness periodically. -- Full path: //OpenSplice/Domain/Daemon/Watchdog/Scheduling +- Full path: /Domain/Daemon/Watchdog/Scheduling - Occurrences min-max: 1-1 - Child elements: Priority, Class @@ -387,23 +352,10 @@ Priority The user may need special privileges from the underlying operating system to be able to assign some of the privileged priorities. -- Full path: //OpenSplice/Domain/Daemon/Watchdog/Scheduling/Priority +- Full path: /Domain/Daemon/Watchdog/Scheduling/Priority - Format: integer - Default value: 0 - Occurrences min-max: 1-1 -- Optional attributes: priority_kind - -priority_kind -+++++++++++++ - - This attribute specifies whether the specified Priority is a relative or absolute priority - -- Full path: //OpenSplice/Domain/Daemon/Watchdog/Scheduling/Priority[@priority_kind] -- Format: enumeration -- Default value: Relative -- Valid values: Relative, Absolute -- Occurrences min-max: 0-1 -- Required: false Class ~~~~~ @@ -413,114 +365,27 @@ Class the underlying operating system to be able to assign some of the privileged scheduling classes. -- Full path: //OpenSplice/Domain/Daemon/Watchdog/Scheduling/Class -- Format: enumeration -- Default value: Default -- Valid values: Timeshare, Realtime, Default -- Occurrences min-max: 1-1 - -StackSize -^^^^^^^^^ - - This element specifies the thread stacksize that will be used by the - Watchdog thread. By default this is 512 Kb. - -- Full path: //OpenSplice/Domain/Daemon/Watchdog/StackSize -- Format: integer -- Dimension: bytes -- Default value: 524288 -- Occurrences min-max: 0-1 - -shmMonitor ----------- - - This element controls the scheduling characteristics of the shmMonitor thread. This - thread is responsible cleaning up resources that are left behind by unexpected termination of other - dds services and applications. - -- Full path: //OpenSplice/Domain/Daemon/shmMonitor -- Occurrences min-max: 0-1 -- Child elements: StackSize - -Scheduling -^^^^^^^^^^ - - This element specifies the type of OS scheduling class will be - used by the thread that announces its liveliness periodically. - -- Full path: //OpenSplice/Domain/Daemon/shmMonitor/Scheduling -- Occurrences min-max: 1-1 -- Child elements: Priority, Class - -Priority -~~~~~~~~ - - This element specifies the thread priority that will be used by the - shmMonitor thread. Only priorities that are supported by the - underlying operating system can be assigned to this element. - The user may need special privileges from the underlying operating - system to be able to assign some of the privileged priorities. - -- Full path: //OpenSplice/Domain/Daemon/shmMonitor/Scheduling/Priority -- Format: integer -- Default value: 0 -- Occurrences min-max: 1-1 -- Optional attributes: priority_kind - -priority_kind -+++++++++++++ - - This attribute specifies whether the specified Priority is a relative or absolute priority - -- Full path: //OpenSplice/Domain/Daemon/shmMonitor/Scheduling/Priority[@priority_kind] -- Format: enumeration -- Default value: Relative -- Valid values: Relative, Absolute -- Occurrences min-max: 0-1 -- Required: false - -Class -~~~~~ - - This element specifies the thread scheduling class that will be used by - the shmMonitor thread. The user may need the appropriate privileges from - the underlying operating system to be able to assign some of the - privileged scheduling classes. - -- Full path: //OpenSplice/Domain/Daemon/shmMonitor/Scheduling/Class +- Full path: /Domain/Daemon/Watchdog/Scheduling/Class - Format: enumeration - Default value: Default - Valid values: Timeshare, Realtime, Default - Occurrences min-max: 1-1 -StackSize -^^^^^^^^^ - - This element specifies the thread stacksize that will be used by the - shmMonitor thread. By default this is 512 Kb. - -- Full path: //OpenSplice/Domain/Daemon/shmMonitor/StackSize -- Format: integer -- Dimension: bytes -- Default value: 524288 -- Occurrences min-max: 0-1 - KernelManager ------------- - The Kernel Manager monitors Builtin Topic on status changes of DataWriters and - inconsistencies between Topics and QoS policies, and it will notify all participants - interested in any of these events, i.e. it updates status fields and wakeup blocking - waitset and listener threads. - Controlling the scheduling behaviour of the Kernel Manager will therefore infuence - the reactivity on detecting events, but it will not infuence the event handling itself as - this is the responsibility of the participants waitset or listener thread. - Note that the Kernel Manager has no or limited value when Builtin Topics are - disabled. + This element specifies the behaviour of the KernelManager. -- Full path: //OpenSplice/Domain/Daemon/KernelManager + The kernel manager actively monitors the OpenSplice kernel + and executes administrative tasks: + + + - check topic consistency + - determine liveliness status of readers and writers + - notify readers and writers on incompatible QoS + +- Full path: /Domain/Daemon/KernelManager - Occurrences min-max: 0-1 -- Child elements: StackSize Scheduling ^^^^^^^^^^ @@ -528,7 +393,7 @@ Scheduling This element specifies the scheduling policies used to control the KernelManager thread. -- Full path: //OpenSplice/Domain/Daemon/KernelManager/Scheduling +- Full path: /Domain/Daemon/KernelManager/Scheduling - Occurrences min-max: 1-1 - Child elements: Priority, Class @@ -541,7 +406,7 @@ Priority The user may need special privileges from the underlying operating system to be able to assign some of the privileged priorities. -- Full path: //OpenSplice/Domain/Daemon/KernelManager/Scheduling/Priority +- Full path: /Domain/Daemon/KernelManager/Scheduling/Priority - Format: integer - Default value: 0 - Occurrences min-max: 1-1 @@ -553,7 +418,7 @@ priority_kind This attribute specifies whether the specified Priority is a relative or absolute priority. -- Full path: //OpenSplice/Domain/Daemon/KernelManager/Scheduling/Priority[@priority_kind] +- Full path: /Domain/Daemon/KernelManager/Scheduling/Priority/priority_kind - Format: enumeration - Default value: Relative - Valid values: Relative, Absolute @@ -567,24 +432,12 @@ Class privileges from the underlying operating system to be able to assign some of the privileged scheduling classes. -- Full path: //OpenSplice/Domain/Daemon/KernelManager/Scheduling/Class +- Full path: /Domain/Daemon/KernelManager/Scheduling/Class - Format: enumeration - Default value: Default - Valid values: Timeshare, Realtime, Default - Occurrences min-max: 1-1 -StackSize -^^^^^^^^^ - - This element specifies the thread stacksize that will be used by the - KernelManager thread. By default this is 512 Kb. - -- Full path: //OpenSplice/Domain/Daemon/KernelManager/StackSize -- Format: integer -- Dimension: bytes -- Default value: 524288 -- Occurrences min-max: 0-1 - GarbageCollector ---------------- @@ -594,9 +447,8 @@ GarbageCollector reclaiming resources in case an application or remote node does not terminate properly. -- Full path: //OpenSplice/Domain/Daemon/GarbageCollector +- Full path: /Domain/Daemon/GarbageCollector - Occurrences min-max: 0-1 -- Child elements: StackSize Scheduling ^^^^^^^^^^ @@ -604,7 +456,7 @@ Scheduling This element specifies the scheduling policies used to control the GarbageCollector thread. -- Full path: //OpenSplice/Domain/Daemon/GarbageCollector/Scheduling +- Full path: /Domain/Daemon/GarbageCollector/Scheduling - Occurrences min-max: 1-1 - Child elements: Priority, Class @@ -617,7 +469,7 @@ Priority The user may need special privileges from the underlying operating system to be able to assign some of the privileged priorities. -- Full path: //OpenSplice/Domain/Daemon/GarbageCollector/Scheduling/Priority +- Full path: /Domain/Daemon/GarbageCollector/Scheduling/Priority - Format: integer - Default value: 0 - Occurrences min-max: 1-1 @@ -629,7 +481,7 @@ priority_kind This attribute specifies whether the specified Priority is a relative or absolute priority. -- Full path: //OpenSplice/Domain/Daemon/GarbageCollector/Scheduling/Priority[@priority_kind] +- Full path: /Domain/Daemon/GarbageCollector/Scheduling/Priority/priority_kind - Format: enumeration - Default value: Relative - Valid values: Relative, Absolute @@ -643,24 +495,12 @@ Class appropriate privileges from the underlying operating system to be able to assign some of the privileged scheduling classes. -- Full path: //OpenSplice/Domain/Daemon/GarbageCollector/Scheduling/Class +- Full path: /Domain/Daemon/GarbageCollector/Scheduling/Class - Format: enumeration - Default value: Default - Valid values: Timeshare, Realtime, Default - Occurrences min-max: 1-1 -StackSize -^^^^^^^^^ - - This element specifies the thread stacksize that will be used by the - GarbageCollector thread. By default this is 512 Kb. - -- Full path: //OpenSplice/Domain/Daemon/GarbageCollector/StackSize -- Format: integer -- Dimension: bytes -- Default value: 524288 -- Occurrences min-max: 0-1 - ResendManager ------------- @@ -669,9 +509,8 @@ ResendManager first attempt (for example because the application or service ran out of queue space) will store that sample in its own history queue, from which the Resend manager will periodically try to re-transmit it. -- Full path: //OpenSplice/Domain/Daemon/ResendManager +- Full path: /Domain/Daemon/ResendManager - Occurrences min-max: 0-1 -- Child elements: StackSize Scheduling ^^^^^^^^^^ @@ -679,7 +518,7 @@ Scheduling This element specifies the type of OS scheduling class used by the thread that does local resends for the builtin participant. -- Full path: //OpenSplice/Domain/Daemon/ResendManager/Scheduling +- Full path: /Domain/Daemon/ResendManager/Scheduling - Occurrences min-max: 1-1 - Child elements: Priority, Class @@ -692,7 +531,7 @@ Priority The user may need special privileges from the underlying operating system to be able to assign some of the privileged priorities. -- Full path: //OpenSplice/Domain/Daemon/ResendManager/Scheduling/Priority +- Full path: /Domain/Daemon/ResendManager/Scheduling/Priority - Format: integer - Default value: 0 - Occurrences min-max: 1-1 @@ -704,7 +543,7 @@ priority_kind This attribute specifies whether the specified Priority is a relative or absolute priority. -- Full path: //OpenSplice/Domain/Daemon/ResendManager/Scheduling/Priority[@priority_kind] +- Full path: /Domain/Daemon/ResendManager/Scheduling/Priority/priority_kind - Format: enumeration - Default value: Relative - Valid values: Relative, Absolute @@ -718,24 +557,12 @@ Class the underlying operating system to be able to assign some of the privileged scheduling classes. -- Full path: //OpenSplice/Domain/Daemon/ResendManager/Scheduling/Class +- Full path: /Domain/Daemon/ResendManager/Scheduling/Class - Format: enumeration - Default value: Default - Valid values: Timeshare, Realtime, Default - Occurrences min-max: 1-1 -StackSize -^^^^^^^^^ - - This element specifies the thread stacksize that will be used by the - ResendManager thread. By default this is 512 Kb. - -- Full path: //OpenSplice/Domain/Daemon/ResendManager/StackSize -- Format: integer -- Dimension: bytes -- Default value: 524288 -- Occurrences min-max: 0-1 - Heartbeat --------- @@ -746,9 +573,9 @@ Heartbeat Please note this heartbeat mechanism is similar to but not the same as the service liveliness assertion. -- Full path: //OpenSplice/Domain/Daemon/Heartbeat +- Full path: /Domain/Daemon/Heartbeat - Occurrences min-max: 0-1 -- Child elements: ExpiryTime, StackSize +- Child elements: ExpiryTime - Optional attributes: transport_priority transport_priority @@ -757,10 +584,9 @@ transport_priority This attribute controls the transport priority QoS setting (in seconds) that is only used by the Splice Daemom for for sending its heartbeats. -- Full path: //OpenSplice/Domain/Daemon/Heartbeat[@transport_priority] +- Full path: /Domain/Daemon/Heartbeat/transport_priority - Format: integer - Default value: 0 -- Valid values: 0 / - - Required: false Scheduling @@ -769,7 +595,7 @@ Scheduling This element specifies the scheduling parameters used by the thread that periodically sends the heartbeats. -- Full path: //OpenSplice/Domain/Daemon/Heartbeat/Scheduling +- Full path: /Domain/Daemon/Heartbeat/Scheduling - Occurrences min-max: 0-1 - Child elements: Priority, Class @@ -783,7 +609,7 @@ Priority special privileges from the underlying operating system to be able to assign some of the privileged priorities. -- Full path: //OpenSplice/Domain/Daemon/Heartbeat/Scheduling/Priority +- Full path: /Domain/Daemon/Heartbeat/Scheduling/Priority - Format: integer - Default value: 0 - Occurrences min-max: 1-1 @@ -795,7 +621,7 @@ priority_kind This attribute specifies whether the specified Priority is a relative or absolute priority. -- Full path: //OpenSplice/Domain/Daemon/Heartbeat/Scheduling/Priority[@priority_kind] +- Full path: /Domain/Daemon/Heartbeat/Scheduling/Priority/priority_kind - Format: enumeration - Default value: Relative - Valid values: Relative, Absolute @@ -810,7 +636,7 @@ Class operating system to be able to assign some of the privileged scheduling classes. -- Full path: //OpenSplice/Domain/Daemon/Heartbeat/Scheduling/Class +- Full path: /Domain/Daemon/Heartbeat/Scheduling/Class - Format: enumeration - Default value: Default - Valid values: Timeshare, Realtime, Default @@ -831,10 +657,9 @@ ExpiryTime this value according to the need of your system with respect to these aspects. -- Full path: //OpenSplice/Domain/Daemon/Heartbeat/ExpiryTime +- Full path: /Domain/Daemon/Heartbeat/ExpiryTime - Default value: 4.0 -- Valid values: 0.2 / - -- Occurrences min-max: 0-1 +- Occurrences min-max: 1-1 - Required attributes: update_factor update_factor @@ -852,132 +677,30 @@ update_factor every *ExpiryTime* multiplied by this *update_factor*. -- Full path: //OpenSplice/Domain/Daemon/Heartbeat/ExpiryTime[@update_factor] +- Full path: /Domain/Daemon/Heartbeat/ExpiryTime/update_factor - Default value: 0.25 -- Valid values: 0.1 / 0.9 - Required: true -StackSize -^^^^^^^^^ - - This element specifies the thread stacksize that will be used by the - Heartbeat thread. By default this is 512 Kb. - -- Full path: //OpenSplice/Domain/Daemon/Heartbeat/StackSize -- Format: integer -- Dimension: bytes -- Default value: 524288 -- Occurrences min-max: 0-1 - -Tracing -------- - - This element controls the amount and type of information that is - written into the tracing log by the Splice Daemon. This is - useful to track the Durability Service during application - development. In the runtime system it should be turned off. - -- Full path: //OpenSplice/Domain/Daemon/Tracing -- Occurrences min-max: 0-1 -- Child elements: OutputFile, Timestamps, Verbosity -- Optional attributes: synchronous - -synchronous -^^^^^^^^^^^ -- Full path: //OpenSplice/Domain/Daemon/Tracing[@synchronous] -- Format: boolean -- Default value: FALSE -- Required: false - -OutputFile -^^^^^^^^^^ - - This option specifies where the logging is printed to. Note that - "stdout" is considered a legal value that represents "standard out" - and "stderr" is a legal value representing "standard error". - The default value is an empty string, indicating that all tracing - is disabled. - -- Full path: //OpenSplice/Domain/Daemon/Tracing/OutputFile -- Format: string -- Default value: durability.log -- Occurrences min-max: 0-1 - -Timestamps -^^^^^^^^^^ - - This element specifies whether the logging must contain timestamps. - -- Full path: //OpenSplice/Domain/Daemon/Tracing/Timestamps -- Format: boolean -- Default value: true -- Occurrences min-max: 0-1 -- Optional attributes: absolute - -absolute -~~~~~~~~ - - This attribute specifies whether the timestamps are absolute or - relative to the startup time of the service. - -- Full path: //OpenSplice/Domain/Daemon/Tracing/Timestamps[@absolute] -- Format: boolean -- Default value: true -- Required: false - -Verbosity -^^^^^^^^^ - - This element specifies the verbosity level of the loggin - information. The higher the level, the more (detailed) - information will be logged. - -- Full path: //OpenSplice/Domain/Daemon/Tracing/Verbosity -- Format: enumeration -- Default value: INFO -- Valid values: SEVERE, WARNING, INFO, CONFIG, FINE, FINER, FINEST -- Occurrences min-max: 0-1 - Database ======== - The Database element drives how the administration within the federation is managed. - In federated deployment this administration is managed in a shared memory segment - and in single-process deployment it is managed on heap. + This element contains information about the nodal administration (shared memory) to be used. -- Full path: //OpenSplice/Domain/Database +- Full path: /Domain/Database - Occurrences min-max: 0-1 - Child elements: Size, Threshold, Address, Locking Size ---- - This element specifies the maximum size of the memory segment for maintaining - the nodal administration. The memory management behaviour depends on the deployment mode - (federated vs single-process, driven by the //OpenSplice/Domain/SingleProcess element) - and the size configured within this element: - - - **Single process mode** In this mode the database is managed on heap. - If the size is set to zero, the heap is managed by the operating system memory - manager and limited to the operating system limit. If a non-zero size is - configured, the database is still allocated on heap, but the domain service - pre-allocates the entire size at once and will use its own memory manager - to manage this memory segment. The default value in this mode is 0 bytes. - - **Federated mode** In this mode, the database is managed in shared memory segment - and the domain service will use its own memory manager to manage the - shared memory segment. The default value in this mode is 10 Mbytes. - - Change this value if your system requires more memory than the default. Please note - that the operating system should be configured support the requested size. - On most platforms you need 'root' privileges to set large sizes. - The human-readable option lets the user postfix the value with - K(ilobyte), M(egabyte) or G(igabtye). For example, 10M results in 10485760 bytes. - -- Full path: //OpenSplice/Domain/Database/Size -- Dimension: bytes + This element specifies the size of the shared memory segment holding the database. Change + this value if your system requires more memory than the default. Please note that the + operating system should be configured support the requested size. On most platforms you need + 'root' privileges to set large sizes. + +- Full path: /Domain/Database/Size - Default value: 10485760 -- Valid values: 0 / - -- Occurrences min-max: 0-1 +- Occurrences min-max: 1-1 Threshold --------- @@ -988,13 +711,9 @@ Threshold 50% of the threshold value is available. It is strongly discouraged to configure a threshold value of less then the default value, but for some embedded systems it might be needed as only limited memory is available. - The human-readable option lets the user postfix the value with K(ilobyte), - M(egabyte) or G(igabtye). For example, 10M results in 10485760 bytes. -- Full path: //OpenSplice/Domain/Database/Threshold -- Dimension: bytes +- Full path: /Domain/Database/Threshold - Default value: 1048576 -- Valid values: 0 / - - Occurrences min-max: 0-1 Address @@ -1009,23 +728,9 @@ Address use, for example by another Domain Service or another product. - default values per platform: - - - - 0x20000000 (Linux2.6 on x86) - - 00x140000000 (Linux2.6 on x86_64) - - 00x40000000 (Windows on x86) - - 00x40000000 (Windows on x86_64) - - 00xA0000000 (Solaris on SPARC) - - 00xA0000000 (AIX5.3 on POWER5+) - - 00x0 (VxWorks 5.5.1 on PowerPC604) - - 00x60000000 (VxWorks 6.x on PowerPC604) - - 00x20000000 (Integrity on mvme5100) - -- Full path: //OpenSplice/Domain/Database/Address +- Full path: /Domain/Database/Address - Format: string -- Default value: 0x40000000 -- Valid values: 0x0 / - +- Default value: 0x40000000 - Occurrences min-max: 0-1 Locking @@ -1048,7 +753,7 @@ Locking - **False**: don't lock the pages in memory. - **Default**: use the platform-dependent default value. -- Full path: //OpenSplice/Domain/Database/Locking +- Full path: /Domain/Database/Locking - Format: enumeration - Default value: Default - Valid values: True, False, Default @@ -1060,7 +765,7 @@ Listeners This element specifies policies for the thread that services the listeners that the application specifies on the API-level. -- Full path: //OpenSplice/Domain/Listeners +- Full path: /Domain/Listeners - Occurrences min-max: 0-1 - Child elements: StackSize @@ -1069,9 +774,8 @@ StackSize This element specifies the stack size of the listener thread. -- Full path: //OpenSplice/Domain/Listeners/StackSize +- Full path: /Domain/Listeners/StackSize - Default value: 128000 -- Valid values: 64000 / - - Occurrences min-max: 1-1 Service @@ -1079,14 +783,8 @@ Service The Domain service is responsible for starting, monitoring and stopping the pluggable services. One Service element must be specified for every service that needs to be started by the Domain service. - When run in shared memory mode, the Domain Service will start each service as a - new process that will interface directly with the shared memory for DDS - communication. - When run in single process mode, the Domain Service will start each service as a - new thread within the existing process that will have access to the heap memory - for the DDS communication. - -- Full path: //OpenSplice/Domain/Service + +- Full path: /Domain/Service - Occurrences min-max: 0-* - Child elements: Command, MemoryPoolSize, HeapSize, StackSize, Configuration, Locking, FailureAction - Required attributes: name @@ -1105,7 +803,7 @@ name the configuration file. The name specified here must match the name attribute of the main element of the corresponding service. -- Full path: //OpenSplice/Domain/Service[@name] +- Full path: /Domain/Service/name - Format: string - Default value: durability - Required: true @@ -1118,7 +816,7 @@ enabled Toggling a service between enabled and disabled is a quick alternative for commenting out the corresponding lines in the configuration file. -- Full path: //OpenSplice/Domain/Service[@enabled] +- Full path: /Domain/Service/enabled - Format: boolean - Default value: true - Required: false @@ -1128,20 +826,13 @@ Command This element specifies the command to be executed in order to start the service. - In shared memory mode, Command element specifies the name of the actual service - executable (possibly including its path, but always including its extension, e.g. - .exe on the Windows platform). When no path is included, the Domain Service - will search the PATH environment variable for the corresponding executable. Once - located, it will be started as a separate process. - - In single process mode, Command is the name of the entry point function to be - invoked and the name of the shared library to be dynamically loaded into the - process. The signature of the entry point function is the same as argc/argv usually - seen with main. The OpenSplice services are implemented in such a way that the - entry point name matches that of the shared library, so (for example) specifying - durability is all that is required. + OpenSplice DDS comes with a set of pluggable services. The Command element specifies + the name of the actual service executable (possibly including its path, but always + including its extension, e.g. '.exe' on the Windows platform). When no path is included, + the Domain Service will search the *PATH* environment variable for the corresponding + executable. Once located, it will be started as a separate process. -- Full path: //OpenSplice/Domain/Service/Command +- Full path: /Domain/Service/Command - Format: string - Default value: durability - Occurrences min-max: 1-1 @@ -1156,13 +847,7 @@ MemoryPoolSize further information on this setting. Valid values are decimal or hexadecimal numbers and they express the number of bytes. - The default setting for this element is dependent on the service for which it is configured. - 0xa00000 for spliced, - 0x280000 for durability, - 0x280000 for networking, - 0x100000 for cmsoap - -- Full path: //OpenSplice/Domain/Service/MemoryPoolSize +- Full path: /Domain/Service/MemoryPoolSize - Format: string - Default value: 0 - Occurrences min-max: 0-1 @@ -1177,13 +862,7 @@ HeapSize further information on this setting. Valid values are decimal or hexadecimal numbers and they express the number of bytes. - The default setting for this element is dependent on the service for which it is configured. - 0x800000 for spliced, - 0x240000 for durability, - 0x240000 for networking, - 0x200000 for cmsoap - -- Full path: //OpenSplice/Domain/Service/HeapSize +- Full path: /Domain/Service/HeapSize - Format: string - Default value: 0 - Occurrences min-max: 0-1 @@ -1198,13 +877,7 @@ StackSize further information on this setting. Valid values are decimal or hexadecimal numbers and they express the number of bytes. - The default setting for this element is dependent on the service for which it is configured - 0x10000 for spliced - 0x10000 for durability - 0x10000 for networking - 0x10000 for cmsoap - -- Full path: //OpenSplice/Domain/Service/StackSize +- Full path: /Domain/Service/StackSize - Format: string - Default value: 0 - Occurrences min-max: 0-1 @@ -1227,7 +900,7 @@ Configuration resource file, a separate URI identifying that particular resource file must be specified in this element. -- Full path: //OpenSplice/Domain/Service/Configuration +- Full path: /Domain/Service/Configuration - Format: string - Default value: ${OSPL_URI} - Occurrences min-max: 0-1 @@ -1240,7 +913,7 @@ Scheduling can only be started within the scheduling classes that are supported by the underlying operating system. -- Full path: //OpenSplice/Domain/Service/Scheduling +- Full path: /Domain/Service/Scheduling - Occurrences min-max: 0-1 - Child elements: Priority, Class @@ -1253,7 +926,7 @@ Priority element. The user may need special privileges from the underlying operating system to be able to assign some of the privileged priorities. -- Full path: //OpenSplice/Domain/Service/Scheduling/Priority +- Full path: /Domain/Service/Scheduling/Priority - Format: integer - Default value: 0 - Occurrences min-max: 1-1 @@ -1265,7 +938,7 @@ priority_kind This attribute specifies whether the specified Priority is a relative or absolute priority. -- Full path: //OpenSplice/Domain/Service/Scheduling/Priority[@priority_kind] +- Full path: /Domain/Service/Scheduling/Priority/priority_kind - Format: enumeration - Default value: Relative - Valid values: Relative, Absolute @@ -1280,7 +953,7 @@ Class operating system to be able to assign some of the privileged scheduling classes. -- Full path: //OpenSplice/Domain/Service/Scheduling/Class +- Full path: /Domain/Service/Scheduling/Class - Format: enumeration - Default value: Default - Valid values: Timeshare, Realtime, Default @@ -1301,7 +974,7 @@ Locking appropriate privileges from the underlying operating system to be able to use this option. -- Full path: //OpenSplice/Domain/Service/Locking +- Full path: /Domain/Service/Locking - Format: boolean - Default value: false - Occurrences min-max: 0-1 @@ -1325,7 +998,7 @@ FailureAction - **restart**: End the service process by force and restart it. - **systemhalt**: End all OpenSplice services including the Domain service (for the current DDS Domain on this computing node). -- Full path: //OpenSplice/Domain/Service/FailureAction +- Full path: /Domain/Service/FailureAction - Format: enumeration - Default value: skip - Valid values: kill, restart, skip, systemhalt @@ -1337,13 +1010,10 @@ Application When in the single process deployment mode, the Domain service can deploy DDS applications by dynamically loading application shared libraries and starting threads within the existing process. - A user can add a multiple Application elements to the configuration when they want - to 'cluster' multiple DDS applications within an OpenSplice DDS single process. - The entry point and shared library for each Application can be specified by using the - Command and Library elements that are described below.>/p> + **Note that Applications only take effect when the single process configuration is enabled by way of the SingleProcess element.** -- Full path: //OpenSplice/Domain/Application +- Full path: /Domain/Application - Occurrences min-max: 0-* - Child elements: Command, Arguments, Library - Required attributes: name @@ -1352,12 +1022,11 @@ Application name ---- - This attribute assigns a configuration label to the application, but it is of no further - use; it can have any valid string value + The name uniquely identifies the application -- Full path: //OpenSplice/Domain/Application[@name] +- Full path: /Domain/Application/name - Format: string -- Default value: n/a +- Default value: application1 - Required: true enabled @@ -1368,7 +1037,7 @@ enabled Toggling an applicatione between enabled and disabled is a quick alternative for commenting out the corresponding lines in the configuration file. -- Full path: //OpenSplice/Domain/Application[@enabled] +- Full path: /Domain/Application/enabled - Format: boolean - Default value: true - Required: false @@ -1390,10 +1059,7 @@ Command The shared library is located by way of the current working directory, or LD_LIBRARY_PATH for Unix systems, and PATH for Windows systems. - Note that this has the same meaning as the Service/Command element when in the - single process mode of operation. - -- Full path: //OpenSplice/Domain/Application/Command +- Full path: /Domain/Application/Command - Format: string - Default value: application1 - Occurrences min-max: 1-1 @@ -1407,7 +1073,7 @@ Arguments For example, if Command is "HelloWorld" and Arguments is "arg1 arg2", OpenSplice will invoke the HelloWorld function with the argc = 3 and argv = {"HelloWorld", "arg1", "arg2"} -- Full path: //OpenSplice/Domain/Application/Arguments +- Full path: /Domain/Application/Arguments - Format: string - Occurrences min-max: 0-1 @@ -1420,8 +1086,9 @@ Library The shared library is located by way of the current working directory, or LD_LIBRARY_PATH for Unix systems, and PATH for Windows systems. -- Full path: //OpenSplice/Domain/Application/Library +- Full path: /Domain/Application/Library - Format: string +- Default value: application1 - Occurrences min-max: 0-1 BuiltinTopics @@ -1429,7 +1096,7 @@ BuiltinTopics This element specifies the granularity of the builtin topics. -- Full path: //OpenSplice/Domain/BuiltinTopics +- Full path: /Domain/BuiltinTopics - Occurrences min-max: 0-1 - Required attributes: enabled @@ -1441,7 +1108,7 @@ enabled The existence of Topics will always be communicated by means of builtin topics, regardless of the value specified here. -- Full path: //OpenSplice/Domain/BuiltinTopics[@enabled] +- Full path: /Domain/BuiltinTopics/enabled - Format: boolean - Default value: true - Required: true @@ -1451,7 +1118,7 @@ PriorityInheritance This element specifies the usage on Priority Inheritance on Muexes in this domain. -- Full path: //OpenSplice/Domain/PriorityInheritance +- Full path: /Domain/PriorityInheritance - Occurrences min-max: 0-1 - Required attributes: enabled @@ -1460,10 +1127,8 @@ enabled This attribute enables or disables priority inheritance for mutexes, if that is supported by the underlying Operating System. - If the parent Element PriorityInheritance is not specified (does not exist), then the - 'default' value of this attribute is false. -- Full path: //OpenSplice/Domain/PriorityInheritance[@enabled] +- Full path: /Domain/PriorityInheritance/enabled - Format: boolean - Default value: true - Required: true @@ -1474,7 +1139,7 @@ Report The Report element controls some aspects of the OpenSplice domain logging functionality. -- Full path: //OpenSplice/Domain/Report +- Full path: /Domain/Report - Occurrences min-max: 0-1 - Optional attributes: append, verbosity @@ -1485,7 +1150,7 @@ append append to the previous error and info log files when the domain is (re)started or whether the previous file should be deleted and fresh ones created. -- Full path: //OpenSplice/Domain/Report[@append] +- Full path: /Domain/Report/append - Format: boolean - Default value: true - Required: false @@ -1510,7 +1175,7 @@ verbosity The level specified as this attribute is the lowest level that will be emitted to the logs. All logging can be suppressed by specifying the value 8 or NONE. -- Full path: //OpenSplice/Domain/Report[@verbosity] +- Full path: /Domain/Report/verbosity - Format: enumeration - Default value: INFO - Valid values: DEBUG, INFO, WARNING, API_INFO, ERROR, CRITICAL, FATAL, REPAIRED, NONE @@ -1524,7 +1189,7 @@ Statistics behaviour during application development. Since this introduces extra overhead, it is generally turned off in a runtime system. -- Full path: //OpenSplice/Domain/Statistics +- Full path: /Domain/Statistics - Occurrences min-max: 0-1 Category @@ -1532,7 +1197,7 @@ Category This element specifies the properties for a particular category of statistics. -- Full path: //OpenSplice/Domain/Statistics/Category +- Full path: /Domain/Statistics/Category - Occurrences min-max: 0-* - Required attributes: name - Optional attributes: enabled @@ -1543,7 +1208,7 @@ enabled This attribute enables or disables the generation of statistics for the specified category. -- Full path: //OpenSplice/Domain/Statistics/Category[@enabled] +- Full path: /Domain/Statistics/Category/enabled - Format: boolean - Default value: true - Required: false @@ -1553,7 +1218,7 @@ name This attribute specifies the name of a particular category of statistics. -- Full path: //OpenSplice/Domain/Statistics/Category[@name] +- Full path: /Domain/Statistics/Category/name - Format: enumeration - Default value: reader - Valid values: durability, reader, writer, networking @@ -1568,10 +1233,9 @@ RetentionPeriod This value should only be decreased when the expected lifetime of an instance is extremely short while the instance generation frequency is extremely high, to avoid running out of resources. The value should be increased when you know you can expect out-of-order deliveries with a maximum delay higher than the currently configured RetentionPeriod. -- Full path: //OpenSplice/Domain/RetentionPeriod +- Full path: /Domain/RetentionPeriod - Format: integer - Default value: 500 -- Valid values: 1 / - - Occurrences min-max: 0-1 ReportPlugin @@ -1583,8 +1247,8 @@ ReportPlugin The report interface consists of three operations; initialize, report and finalize. -- Full path: //OpenSplice/Domain/ReportPlugin -- Occurrences min-max: 0-* +- Full path: /Domain/ReportPlugin +- Occurrences min-max: 0-1 - Child elements: SuppressDefaultLogs, ServicesOnly Library @@ -1592,7 +1256,7 @@ Library This tag specifies the library to be loaded. -- Full path: //OpenSplice/Domain/ReportPlugin/Library +- Full path: /Domain/ReportPlugin/Library - Occurrences min-max: 1-1 - Required attributes: file_name @@ -1601,7 +1265,7 @@ file_name This attribute specifies the library to be loaded. -- Full path: //OpenSplice/Domain/ReportPlugin/Library[@file_name] +- Full path: /Domain/ReportPlugin/Library/file_name - Format: string - Default value: n/a - Required: true @@ -1614,7 +1278,7 @@ Initialize initially after loading the library to perform initialization of the report facility if needed. -- Full path: //OpenSplice/Domain/ReportPlugin/Initialize +- Full path: /Domain/ReportPlugin/Initialize - Occurrences min-max: 1-1 - Required attributes: symbol_name - Optional attributes: argument @@ -1622,21 +1286,12 @@ Initialize symbol_name ^^^^^^^^^^^ - This attribute specifies the name of the function to be called to initialize the report - plugin. The symbol_name is required, if it is not specified or cannot be resolved, an - error message will be generated and the service will not attempt to resolve other - symbol_names for the report plugin. - The implementation of this function must have the following signature: - int symbol_name (const char \*argument, void \*\*context) + This attribute specifies the library symbol that will be + assigned to the report Initialize operation. This operation + will be invoked initially after loading the library to + perform initialization of the report facility if needed. - The result value is used to return the status of the call. If it is 0 then the operation - was successful. If it is not 0 then there was an error and details of the error and the - result value are reported to the OpenSplice DDS default report service. - The context parameter is an out reference that can be set to plugin-specific data that - will subsequently be passed to any of the other plugin functions. The value of the - parameter is meaningless to the service - -- Full path: //OpenSplice/Domain/ReportPlugin/Initialize[@symbol_name] +- Full path: /Domain/ReportPlugin/Initialize/symbol_name - Format: string - Default value: n/a - Required: true @@ -1644,12 +1299,12 @@ symbol_name argument ^^^^^^^^ - The argument attribute is a string value that is passed to the function specified by the - symbol_name. The string value has no meaning to the service and is used to pass - any context-specific information that may be required. The argument is optional; if - it is not provided then a NULL pointer is passed to the initalize function. + This attribute is a string value that is passed to the function + specified by the symbol_name. The string value has no meaning + to the service and is used to pass any context-specific + information that may be required. -- Full path: //OpenSplice/Domain/ReportPlugin/Initialize[@argument] +- Full path: /Domain/ReportPlugin/Initialize/argument - Format: string - Default value: "" - Required: false @@ -1661,118 +1316,18 @@ Report the report Report operation. This operation will be invoked on all reports performed by the DDS service. -- Full path: //OpenSplice/Domain/ReportPlugin/Report +- Full path: /Domain/ReportPlugin/Report - Occurrences min-max: 0-1 - Required attributes: symbol_name symbol_name ^^^^^^^^^^^ - This attribute specifies the name of the function to be called to pass report data to - the report plugin. The symbol_name is required; if it is not specified or cannot be - resolved, an error message will be generated and the service will not attempt to - resolve other symbol_names for the report plugin. - The function is invoked slightly differently for applications using the DDS API and - OpenSplice services. OpenSplice services invoke the function once for every report. - For applications using the DDS API the function is invoked once per API call, in - which case the XML is extended by one or more DETAIL elements. - The implementation of this function must have the following signature: - int symbol_name (void \*context, const char \*report) - - The result value is used to return the status of the call. If it is 0 then the operation - was successful. If it is not 0 then there was an error and details of the error and the - result value are reported to the OpenSplice DDS default report service. - The context parameter is a reference to the plugin-specific data retrieved from the - initialize operation. - The report parameter is an XML string representation of the report data. - Below is an example of the mapping that the XML string representation will use - when invoked by a service: - - - - -The object "my_topic" not found - -c_base::resolve - -c_base.c - -1234 - -0 - - - -1234 - -ProcessName - - - - - -1234 - -ThreadName - - - -6.5 - -... - - - - - Below is an example of the mapping that the XML string representation will use for - applications: - - - - -Operation failed. - -c_base::resolve - -c_base.c - -1234 - -0 - - - -1234 - -ProcessName - - - - - -1234 - -ThreadName - - - -6.5 - -... - - - -The object "my_topic" not found. - -... - - - - - - + This attribute specifies the library symbol that will be + assigned to the report Report operation. This operation will + be invoked on all reports performed by the DDS service. -- Full path: //OpenSplice/Domain/ReportPlugin/Report[@symbol_name] +- Full path: /Domain/ReportPlugin/Report/symbol_name - Format: string - Default value: n/a - Required: true @@ -1784,26 +1339,18 @@ TypedReport the report TypedReport operation. This operation will be invoked on all reports performed by the DDS service. -- Full path: //OpenSplice/Domain/ReportPlugin/TypedReport +- Full path: /Domain/ReportPlugin/TypedReport - Occurrences min-max: 0-1 - Required attributes: symbol_name symbol_name ^^^^^^^^^^^ - This attribute specifies the name of the function to be called to finalize the report - plugin, when the domain unregisters any registered plugin. The symbol_name is - required. If it is not specified or cannot be resolved, an error message will be - generated and the service will not attempt to resolve other symbol_names for the - report plugin. - The implementation of this function must have the following signature: - int symbol_name (void \*context) + This attribute specifies the library symbol that will be + assigned to the report TypedReport operation. This operation will + be invoked on all reports performed by the DDS service. - The result value is used to return the status of the call. If it is 0 then the operation - was successful. If it is not 0 then there was an error and details of the error and the - result value are reported to the OpenSplice DDS default report service. - -- Full path: //OpenSplice/Domain/ReportPlugin/TypedReport[@symbol_name] +- Full path: /Domain/ReportPlugin/TypedReport/symbol_name - Format: string - Default value: n/a - Required: true @@ -1816,27 +1363,19 @@ Finalize invoked upon process termination to perform de-initialization of the report facility if needed. -- Full path: //OpenSplice/Domain/ReportPlugin/Finalize +- Full path: /Domain/ReportPlugin/Finalize - Occurrences min-max: 1-1 - Required attributes: symbol_name symbol_name ^^^^^^^^^^^ - This attribute specifies the name of the function to be called to finalize the report - plugin, when the domain unregisters any registered plugin. The symbol_name is - required. If it is not specified or cannot be resolved, an error message will be - generated and the service will not attempt to resolve other symbol_names for the - report plugin. - The implementation of this function must have the following signature: - int symbol_name (void \*context) - The result value is used to return the status of the call. If it is 0 then the operation - was successful. If it is not 0 then there was an error and details of the error and the - result value are reported to the OpenSplice DDS default report service. - The context parameter is a reference to the plugin-specific data retrieved from the - initialize operation. - -- Full path: //OpenSplice/Domain/ReportPlugin/Finalize[@symbol_name] + This attribute specifies the library symbol that will be assigned + to the report Finalize operation. This operation will be + invoked upon process termination to perform de-initialization + of the report facility if needed. + +- Full path: /Domain/ReportPlugin/Finalize/symbol_name - Format: string - Default value: n/a - Required: true @@ -1850,7 +1389,7 @@ SuppressDefaultLogs default error and info logs will not be suppressed regardless of the value of this attribute -- Full path: //OpenSplice/Domain/ReportPlugin/SuppressDefaultLogs +- Full path: /Domain/ReportPlugin/SuppressDefaultLogs - Format: boolean - Default value: false - Occurrences min-max: 0-1 @@ -1863,7 +1402,7 @@ ServicesOnly not be used for user applications and/or OpenSplice services collocated with user applications in single process mode. -- Full path: //OpenSplice/Domain/ReportPlugin/ServicesOnly +- Full path: /Domain/ReportPlugin/ServicesOnly - Format: boolean - Default value: false - Occurrences min-max: 0-1 @@ -1875,7 +1414,7 @@ ResourceLimits characteristics of resource limits that will be applied throughout the domain -- Full path: //OpenSplice/Domain/ResourceLimits +- Full path: /Domain/ResourceLimits - Occurrences min-max: 0-1 MaxSamples @@ -1885,7 +1424,7 @@ MaxSamples characteristics of the max samples resource limit that will be applied throughout the domain -- Full path: //OpenSplice/Domain/ResourceLimits/MaxSamples +- Full path: /Domain/ResourceLimits/MaxSamples - Occurrences min-max: 0-1 - Child elements: WarnAt @@ -1897,9 +1436,8 @@ WarnAt the info log. This is to allow the detection of excessive use of resources within the domain more easily. -- Full path: //OpenSplice/Domain/ResourceLimits/MaxSamples/WarnAt +- Full path: /Domain/ResourceLimits/MaxSamples/WarnAt - Default value: 5000 -- Valid values: 1 / - - Occurrences min-max: 0-1 MaxInstances @@ -1909,7 +1447,7 @@ MaxInstances characteristics of the max instances resource limit that will be applied throughout the domain -- Full path: //OpenSplice/Domain/ResourceLimits/MaxInstances +- Full path: /Domain/ResourceLimits/MaxInstances - Occurrences min-max: 0-1 - Child elements: WarnAt @@ -1921,9 +1459,8 @@ WarnAt the info log. This is to allow the detection of excessive use of resources within the domain more easily. -- Full path: //OpenSplice/Domain/ResourceLimits/MaxInstances/WarnAt +- Full path: /Domain/ResourceLimits/MaxInstances/WarnAt - Default value: 5000 -- Valid values: 1 / - - Occurrences min-max: 0-1 MaxSamplesPerInstance @@ -1933,7 +1470,7 @@ MaxSamplesPerInstance characteristics of the max samples per instance resource limit that will be applied throughout the domain -- Full path: //OpenSplice/Domain/ResourceLimits/MaxSamplesPerInstance +- Full path: /Domain/ResourceLimits/MaxSamplesPerInstance - Occurrences min-max: 0-1 - Child elements: WarnAt @@ -1946,27 +1483,17 @@ WarnAt detection of excessive use of resources within the domain more easily. -- Full path: //OpenSplice/Domain/ResourceLimits/MaxSamplesPerInstance/WarnAt +- Full path: /Domain/ResourceLimits/MaxSamplesPerInstance/WarnAt - Default value: 5000 -- Valid values: 1 / - - Occurrences min-max: 0-1 PartitionAccess =============== - This element is used to configure the partition access rights. By default all partitions - have read and write access, which means that subscribers and publishers may be - created for all partitions. However by changing the access level of specific partitions - it is possible to prevent publishers and/or subscribers from attaching to these - partitions. The access rights is Domain Service specific, each Domain Service can - have its own policy. - The PartitionAccess element facilitates the configuration of such behavior. This - is done by allowing the definition of a partition expression along with a specific - access mode for the matched partitions. The PartitionAccess element resides as - a child element within the Domain element. The exact definition of the - PartitionAccess element is as follows: - -- Full path: //OpenSplice/Domain/PartitionAccess + This configuration tag specifies the access rights for a + selection of partitions. + +- Full path: /Domain/PartitionAccess - Occurrences min-max: 0-* - Required attributes: partition_expression, access_mode @@ -1974,12 +1501,12 @@ partition_expression -------------------- This attribute specifies the partitions by name. - The wildcards '\*' and '?' are allowed and the specified + The wildcards '*' and '?' are allowed and the specified access rights will be applied to all matching partitions. In case partitions match multiple rules the rules will be applied in sequence of declaration. -- Full path: //OpenSplice/Domain/PartitionAccess[@partition_expression] +- Full path: /Domain/PartitionAccess/partition_expression - Format: string - Default value: * - Required: true @@ -1987,26 +1514,16 @@ partition_expression access_mode ----------- - This attribute identifies the access level for partitions specified by the - partition_expression attribute. The following values are allowed: - - - read Indicates domain participants can only read from this partition - - write Indicates domain participants can only write to this partition - - readwrite Indicates domain participants can read from and write to this partition - - none Indicates that domain participants have no access on partitions matching the partition_expression. - + This attribute specifies the access rights that will be + applied to the specified partitions. The following values + are applicable: + + - none + - read + - write + - readwrite - When multiple expressions overlap each other, the following rules are applied: - - Access mode 1 Access mode 2 Resulting access mode - read write readwrite - read readwrite readwrite - read none none - write readwrite readwrite - write none none - readwrite none none - -- Full path: //OpenSplice/Domain/PartitionAccess[@access_mode] +- Full path: /Domain/PartitionAccess/access_mode - Format: enumeration - Default value: readwrite - Valid values: none, read, write, readwrite @@ -2016,7 +1533,7 @@ SystemId ======== This configures the generation of the unique System IDs -- Full path: //OpenSplice/Domain/SystemId +- Full path: /Domain/SystemId - Occurrences min-max: 0-1 - Child elements: UserEntropy @@ -2024,7 +1541,7 @@ Range ----- This configures the range of the generated System IDs -- Full path: //OpenSplice/Domain/SystemId/Range +- Full path: /Domain/SystemId/Range - Occurrences min-max: 0-1 - Optional attributes: min, max @@ -2032,45 +1549,35 @@ min ^^^ This attribute specifies the minimum allowed System ID. In addition to being within range, it must be less than or equal to the "max" attribute. -- Full path: //OpenSplice/Domain/SystemId/Range[@min] +- Full path: /Domain/SystemId/Range/min - Format: integer - Default value: 1 -- Valid values: 1 / 2147483647 - Required: false max ^^^ This attribute specifies the maximum allowed System ID. In addition to being within range, it must be greater than or equal to the "min" attribute. -- Full path: //OpenSplice/Domain/SystemId/Range[@max] +- Full path: /Domain/SystemId/Range/max - Format: integer - Default value: 2147483647 -- Valid values: 1 / 2147483647 - Required: false UserEntropy ----------- This attribute specifies a string that is used as an additional source of entropy in the System ID generation. The string is not interpreted. -- Full path: //OpenSplice/Domain/SystemId/UserEntropy +- Full path: /Domain/SystemId/UserEntropy - Format: string - Occurrences min-max: 0-1 TopicAccess =========== - This element is used to configure the topic access rights. By default all topics have - read and write access (built-in topics have a default access mode of read), which - means that datareaders and datawriters may be created for all topics. However by - changing the access level of specific topics it is possible to prevent datawriters - and/or datareaders from being created for these topics. The access rights is Domain - Service specific, each Domain Service can have its own policy. - The TopicAccess element facilitates the configuration of such behavior. This is - done by allowing the definition of a topic expression along with a specific access - mode for the matched topics. - The TopicAccess element resides as a child element within the Domain element - -- Full path: //OpenSplice/Domain/TopicAccess + This configuration tag specifies the access rights for a + selection of topics. + +- Full path: /Domain/TopicAccess - Occurrences min-max: 0-* - Required attributes: topic_expression, access_mode @@ -2078,12 +1585,12 @@ topic_expression ---------------- This attribute specifies the topics by name. - The wildcards '\*' and '?' are allowed and the specified + The wildcards '*' and '?' are allowed and the specified access rights will be applied to all matching topics. In case topics match multiple rules the rules will be applied in sequence of declaration. -- Full path: //OpenSplice/Domain/TopicAccess[@topic_expression] +- Full path: /Domain/TopicAccess/topic_expression - Format: string - Default value: * - Required: true @@ -2100,57 +1607,38 @@ access_mode - write - readwrite -- Full path: //OpenSplice/Domain/TopicAccess[@access_mode] +- Full path: /Domain/TopicAccess/access_mode - Format: enumeration - Default value: readwrite - Valid values: none, read, write, readwrite - Required: true -UserClock -========= +UserClockService +================ The UserClock Service allows you to plug in a custom clock library, allowing OpenSplice to read the time from an external clock source. It expects a root - element named *OpenSplice/Domain/UserClock*. Within this root element, + element named *OpenSplice/UserClockService*. Within this root element, the userclock will look for several child-elements. Each of these is listed and explained. -- Full path: //OpenSplice/Domain/UserClock +- Full path: /Domain/UserClockService - Occurrences min-max: 0-1 -- Child elements: UserClockModule, UserClockStart, UserClockStop, UserClockQuery -- Optional attributes: y2038Ready +- Child elements: UserClockModule +- Required attributes: name -y2038Ready ----------- +name +---- - This element specifies whether or not the registered user - clock is returning a 64-bit seconds field. - - Default this setting is following the y2038Ready setting on - domain level. (default /domain/y2038Ready is FALSE) - The user is able to make some mixed environments by using this - configuration option. For example a 64-bit user clock can already - be implemented (by setting this option to true) while the node - must be compatible with older versions, - so domain/y2038Ready can not be set. A warning is printed when - the Domain/y2038Ready element is true and the - Domain/UserClock/y2038Ready attribute is false. - The 64-bit layout returned by the userclock must be: - -struct dds_userclock_t { - - os_int64 seconds; - - os_int32 nanoseconds; - -}; - -See 'Time stamps and year 2038 limit' for more background information. - -- Full path: //OpenSplice/Domain/UserClock[@y2038Ready] -- Format: boolean -- Default value: False -- Required: false + This attribute identifies the configuration for the UserClock Service. + The value of the *name* attribute must match the one specified under the + *OpenSplice/Domain/Service[@name]* in the configuration of the + Domain Service. + +- Full path: /Domain/UserClockService/name +- Format: string +- Default value: userclock +- Required: true UserClockModule --------------- @@ -2160,7 +1648,7 @@ UserClockModule this will be a reallocatable object file. On VxWorks this tag may be empty or discarded if the functions are pre-loaded on the target. -- Full path: //OpenSplice/Domain/UserClock/UserClockModule +- Full path: /Domain/UserClockService/UserClockModule - Format: string - Occurrences min-max: 1-1 @@ -2169,25 +1657,22 @@ UserClockStart This element specifies if the user clock requires a start function to be called when the process first creates a participant. - This element specifies the name of the start function. - This start function should not have any parameters, and needs - to return an int that represents 0 if there are no problems, - and any other value if a problem is encountered. -- Full path: //OpenSplice/Domain/UserClock/UserClockStart -- Format: string -- Default value: clockStart +- Full path: /Domain/UserClockService/UserClockStart - Occurrences min-max: 0-1 -- Required attributes: enabled +- Required attributes: name -enabled -^^^^^^^ +name +^^^^ - This attribute specifies if the start function is enabled and should be used. + This attribute specifies the name of the start function. + This start function should not have any parameters, and needs + to return an int that represents 0 if there are no problems, + and any other value if a problem is encountered. -- Full path: //OpenSplice/Domain/UserClock/UserClockStart[@enabled] -- Format: boolean -- Default value: true +- Full path: /Domain/UserClockService/UserClockStart/name +- Format: string +- Default value: clockStart - Required: true UserClockStop @@ -2195,188 +1680,54 @@ UserClockStop This element specifies if the user clock requires a stop function to be called when the process deletes the last participant. - This attribute specifies the name of the stop function. This stop - function should not have any parameters, and needs to return an - int that represents 0 if there are no problems, and any other - value if a problem is encountered. -- Full path: //OpenSplice/Domain/UserClock/UserClockStop -- Format: string -- Default value: clockStop +- Full path: /Domain/UserClockService/UserClockStop - Occurrences min-max: 0-1 -- Required attributes: enabled +- Required attributes: name -enabled -^^^^^^^ +name +^^^^ - This attribute specifies if the stop function is enabled and should be used. + This attribute specifies the name of the stop function. This stop + function should not have any parameters, and needs to return an + int that represents 0 if there are no problems, and any other + value if a problem is encountered. -- Full path: //OpenSplice/Domain/UserClock/UserClockStop[@enabled] -- Format: boolean -- Default value: true +- Full path: /Domain/UserClockService/UserClockStop/name +- Format: string +- Default value: clockStop - Required: true UserClockQuery -------------- This element specifies the clock query function. - This attribute specifies the name of the function that gets the - current time. This *clockGet* function should not have any parameters, - and needs to return the current time as an *os_time* type. - - The definition of the *os_time* type can be found in *os_time.h*. - -- Full path: //OpenSplice/Domain/UserClock/UserClockQuery -- Format: string -- Default value: clockGet -- Occurrences min-max: 0-1 -- Required attributes: enabled - -enabled -^^^^^^^ - - This attribute specifies if the query function is enabled and should be used. -- Full path: //OpenSplice/Domain/UserClock/UserClockQuery[@enabled] -- Format: boolean -- Default value: true -- Required: true - -DurablePolicies -=============== - - There are two ways for a late joining reader to retrieve historical - data as a result of calling wait_for_historical_data() or - DDS_wait_for_historical_data(). - - - The first way is to configure a local durability service - that is responsible for the alignment of historical data (see - //OpenSplice/DurabilityService). In this case the local durability - service will provide historical data to interested readers - on the local federations. - - The second way is NOT to run a local durability service, but - to request data from a durability service on a remote federation - using the client-durability feature. This makes sense in environments - where running a full-fledged durability service is not possible or - unwanted, e.g., due to resource limitations. - - - - - The element //OpenSplice/Domain/DurablePolicies specifies how - historical data that is retrieved from a remote durability federation - using the client-durability feature is handled locally. More specifically, - this element allows the user to indicate whether historical data that - is requested by a late joining reader using the client-durability feature - will be made available to the requesting reader only, or to all readers in the - federation. The behaviour can be specified per partition/topic combination - in the //OpenSplice/Domain/DurablePolicies/Policy elements. - - In most situations it is sufficient to either configure a local durability - service to acquire historical data, or to use the client-durability feature, - but not both. However, it is not forbidden to use both methods concurrently. - In that case it is advised to configure the system in such a way that historical - data for a particular partition/topic combination is either provided using - method 1 or 2. In the event that historical data for the same partition/topic - combination can be requested via both methods, methods 1 will be used. - -- Full path: //OpenSplice/Domain/DurablePolicies -- Occurrences min-max: 0-1 - -Policy ------- - - The policy specifies whether historical data that matches the pattern - specified in the //OpenSplice/Domain/DurablePolicies/Policy[@obtain] - attribute is cached or not. Caching means that the same data is available - for late joining readers on the local federation. - - Multiple policies can be specified. The order of these policies is - important: the first policy that matches (from top to bottom) will - be applied. - - If no policy is specified then the default policy is applied. The - default policy is to deliver requested historical data to all readers. +- Full path: /Domain/UserClockService/UserClockQuery +- Occurrences min-max: 1-1 +- Required attributes: name -- Full path: //OpenSplice/Domain/DurablePolicies/Policy -- Occurrences min-max: 0-* -- Required attributes: obtain -- Optional attributes: cache +name +^^^^ -obtain -^^^^^^ + This attribute specifies the name of the function that gets the + current time. This *clockGet* function should not have any parameters, + and needs to return the current time as an *os_time* type. - This element specifies the pattern of the partition/topic for - which the policy must be applied. The default is \*.\*. + The definition of the *os_time* type can be found in *os_time.h*. -- Full path: //OpenSplice/Domain/DurablePolicies/Policy[@obtain] +- Full path: /Domain/UserClockService/UserClockQuery/name - Format: string -- Default value: *.* +- Default value: clockGet - Required: true -cache -^^^^^ - - This element specifies whether or not to cache historical data. - If set to TRUE historical data is cached in the local federation - for potential other late joiners in the same federation. In this - case historical data will only be aligned once for the - federation, no matter how many readers are interested. This - saves bandwidth and CPU when more than one readers are expected - with (partly) the same interest. The downside is that caching - historical data will require additional memory even after the - reader has taken all its data. If set to FALSE data is not cached. - - The recommended setting is TRUE when more than one readers - for the data are expected and the cost of extra memory can be afforded. - In all other circumstances FALSE should be used. The default is TRUE. - -- Full path: //OpenSplice/Domain/DurablePolicies/Policy[@cache] -- Format: boolean -- Default value: True -- Required: false - -y2038Ready -========== - - The y2038Ready element determines that OpenSplice will send timestamps to other nodes - in a 64-bit format which is capable to contain time stamps beyond the year 2038. - - Setting this option to true will force the middleware to communicate with time stamps able to go - beyond 2038. - Other nodes before version 6.7 are not able to handle these new time stamps and will no longer - interact correctly with the node configured with this option. - - From version 6.7 the middleware is internally prepared and calculating with time stamps capable with - timestamps beyond 2038. - From version 6.7 nodes are able to detect the timestamps containing time beyond 2038 and - the older time format. So these nodes will interact correctly with all other nodes. - In a mixed environment containing versions before 6.7, communication must be in the old timestamp format, - so this configuration option can not be set. - In a mixed environment with only versions 6.7 and higher, this configuration option may be set. The - nodes with this configuration will send timestamps capable beyond 2038. All other nodes will be able - to interpret these values correctly. - -See ' time stamps and year 2038 limit' for more background information. - - - By default this configuration item is set to false. - -- Full path: //OpenSplice/Domain/y2038Ready -- Format: boolean -- Default value: false -- Occurrences min-max: 0-1 - DurabilityService ***************** - The responsibilities of the durability service are to realize the durable properties of - data in an OpenSplice system. The Durability Service looks for its configuration - within the 'OpenSplice/DurabilityService' element. The configuration parameters - that the Durability Service will look for within this element are listed and explained - in the following subsections. + The responsibilities of the durability service are to realize the + durable properties of data in an OpenSplice system. -- Full path: //OpenSplice/DurabilityService +- Full path: /DurabilityService - Occurrences min-max: 0-1 - Required attributes: name @@ -2390,7 +1741,7 @@ name *OpenSplice/Domain/Service[@name]* in the configuration of the DomainService. -- Full path: //OpenSplice/DurabilityService[@name] +- Full path: /DurabilityService/name - Format: string - Default value: durability - Required: true @@ -2404,25 +1755,19 @@ ClientDurability controls the characteristics of the client-durability feature. When enabled, this durability server will be able to responds to requests for historical data from such clients. - If the *OpenSplice/DurabilityService/ClientDurability* element is not - provided, then the durability service will not respond to historical - data requests from clients. -- Full path: //OpenSplice/DurabilityService/ClientDurability +- Full path: /DurabilityService/ClientDurability - Occurrences min-max: 0-1 - Optional attributes: enabled enabled ------- - This attribute enables or disables the ability of the durability service - to respond to requests for historical data from clients. When the - *OpenSplice/DurabilityService/ClientDurability[@enabled]* attribute - is not provided then it is assumed to be TRUE. + This attribute enables or disables the client-durability feature. -- Full path: //OpenSplice/DurabilityService/ClientDurability[@enabled] +- Full path: /DurabilityService/ClientDurability/enabled - Format: boolean -- Default value: TRUE +- Default value: False - Required: false EntityNames @@ -2433,7 +1778,7 @@ EntityNames here will be displayed in the OpenSplice DDS Tuner when viewing the DurabilityService. -- Full path: //OpenSplice/DurabilityService/ClientDurability/EntityNames +- Full path: /DurabilityService/ClientDurability/EntityNames - Occurrences min-max: 0-1 - Child elements: Publisher, Subscriber, Partition @@ -2442,7 +1787,7 @@ Publisher This element specifies the name of the client-durability publisher. -- Full path: //OpenSplice/DurabilityService/ClientDurability/EntityNames/Publisher +- Full path: /DurabilityService/ClientDurability/EntityNames/Publisher - Format: string - Default value: durabilityPublisher - Occurrences min-max: 0-1 @@ -2452,7 +1797,7 @@ Subscriber This element specifies the name of the client-durability subscriber. -- Full path: //OpenSplice/DurabilityService/ClientDurability/EntityNames/Subscriber +- Full path: /DurabilityService/ClientDurability/EntityNames/Subscriber - Format: string - Default value: durabilitySubscriber - Occurrences min-max: 0-1 @@ -2465,7 +1810,7 @@ Partition the partition specified for durability (see Opensplice/DurabilityService/EntityNames/Partition) -- Full path: //OpenSplice/DurabilityService/ClientDurability/EntityNames/Partition +- Full path: /DurabilityService/ClientDurability/EntityNames/Partition - Format: string - Default value: durabilityPartition - Occurrences min-max: 0-1 @@ -2475,7 +1820,7 @@ Watchdog This element controls the characteristics of the Watchdog thread. -- Full path: //OpenSplice/DurabilityService/Watchdog +- Full path: /DurabilityService/Watchdog - Occurrences min-max: 0-1 - Optional attributes: deadlockDetection @@ -2488,7 +1833,7 @@ deadlockDetection helpful to ensure certain responsiveness of the durability service and the detection of potential deadlocks. -- Full path: //OpenSplice/DurabilityService/Watchdog[@deadlockDetection] +- Full path: /DurabilityService/Watchdog/deadlockDetection - Format: boolean - Default value: False - Required: false @@ -2499,7 +1844,7 @@ Scheduling This element specifies the type of OS scheduling class will be used by the thread that announces its liveliness periodically. -- Full path: //OpenSplice/DurabilityService/Watchdog/Scheduling +- Full path: /DurabilityService/Watchdog/Scheduling - Occurrences min-max: 1-1 - Child elements: Priority, Class @@ -2512,7 +1857,7 @@ Priority The user may need special privileges from the underlying operating system to be able to assign some of the privileged priorities. -- Full path: //OpenSplice/DurabilityService/Watchdog/Scheduling/Priority +- Full path: /DurabilityService/Watchdog/Scheduling/Priority - Format: integer - Default value: 0 - Occurrences min-max: 1-1 @@ -2524,7 +1869,7 @@ priority_kind This attribute specifies whether the specified Priority is a relative or absolute priority. -- Full path: //OpenSplice/DurabilityService/Watchdog/Scheduling/Priority[@priority_kind] +- Full path: /DurabilityService/Watchdog/Scheduling/Priority/priority_kind - Format: enumeration - Default value: Relative - Valid values: Relative, Absolute @@ -2538,7 +1883,7 @@ Class the underlying operating system to be able to assign some of the privileged scheduling classes. -- Full path: //OpenSplice/DurabilityService/Watchdog/Scheduling/Class +- Full path: /DurabilityService/Watchdog/Scheduling/Class - Format: enumeration - Default value: Default - Valid values: Timeshare, Realtime, Default @@ -2560,7 +1905,7 @@ Network communication between Durability services on different computing nodes on network level. These settings only apply when the Networking service is active. -- Full path: //OpenSplice/DurabilityService/Network +- Full path: /DurabilityService/Network - Occurrences min-max: 0-1 - Child elements: InitialDiscoveryPeriod - Optional attributes: latency_budget, transport_priority @@ -2578,10 +1923,8 @@ latency_budget notified of the fact. The default value is zero, indicating the delay should be minimized. -- Full path: //OpenSplice/DurabilityService/Network[@latency_budget] -- Dimension: seconds +- Full path: /DurabilityService/Network/latency_budget - Default value: 0.0 -- Valid values: 0.0 / - - Required: false transport_priority @@ -2599,14 +1942,9 @@ transport_priority of user applications and communication of the Durability service. - For example, if the latency of timing-critical application data should not be - disturbed by alignment activities between durability services, then this transport - priority should be configured lower than the application policy. - -- Full path: //OpenSplice/DurabilityService/Network[@transport_priority] +- Full path: /DurabilityService/Network/transport_priority - Format: integer - Default value: 0 -- Valid values: 0 / - - Required: false Heartbeat @@ -2624,7 +1962,7 @@ Heartbeat Please note this heartbeat mechanism is similar to but not the same as the service liveliness assertion. -- Full path: //OpenSplice/DurabilityService/Network/Heartbeat +- Full path: /DurabilityService/Network/Heartbeat - Occurrences min-max: 0-1 - Child elements: ExpiryTime - Optional attributes: latency_budget, transport_priority @@ -2636,9 +1974,8 @@ latency_budget is only used by the Durability service for sending its heartbeats. It overrules the value of the *DurabilityService/Network[@latency_budget]*. -- Full path: //OpenSplice/DurabilityService/Network/Heartbeat[@latency_budget] +- Full path: /DurabilityService/Network/Heartbeat/latency_budget - Default value: 0.0 -- Valid values: 0.0 / - - Required: false transport_priority @@ -2648,10 +1985,9 @@ transport_priority is only used by the Durability service for for sending its heartbeats. It overrules the value of the *DurabilityService/Network[@transport_priorrity]*. -- Full path: //OpenSplice/DurabilityService/Network/Heartbeat[@transport_priority] +- Full path: /DurabilityService/Network/Heartbeat/transport_priority - Format: integer - Default value: 0 -- Valid values: 0 / - - Required: false Scheduling @@ -2660,7 +1996,7 @@ Scheduling This element specifies the scheduling parameters used by the thread that periodically sends the heartbeats. -- Full path: //OpenSplice/DurabilityService/Network/Heartbeat/Scheduling +- Full path: /DurabilityService/Network/Heartbeat/Scheduling - Occurrences min-max: 0-1 - Child elements: Priority, Class @@ -2674,7 +2010,7 @@ Priority special privileges from the underlying operating system to be able to assign some of the privileged priorities. -- Full path: //OpenSplice/DurabilityService/Network/Heartbeat/Scheduling/Priority +- Full path: /DurabilityService/Network/Heartbeat/Scheduling/Priority - Format: integer - Default value: 0 - Occurrences min-max: 1-1 @@ -2686,7 +2022,7 @@ priority_kind This attribute specifies whether the specified Priority is a relative or absolute priority. -- Full path: //OpenSplice/DurabilityService/Network/Heartbeat/Scheduling/Priority[@priority_kind] +- Full path: /DurabilityService/Network/Heartbeat/Scheduling/Priority/priority_kind - Format: enumeration - Default value: Relative - Valid values: Relative, Absolute @@ -2701,7 +2037,7 @@ Class operating system to be able to assign some of the privileged scheduling classes. -- Full path: //OpenSplice/DurabilityService/Network/Heartbeat/Scheduling/Class +- Full path: /DurabilityService/Network/Heartbeat/Scheduling/Class - Format: enumeration - Default value: Default - Valid values: Timeshare, Realtime, Default @@ -2722,9 +2058,8 @@ ExpiryTime this value according to the need of your system with respect to these aspects. -- Full path: //OpenSplice/DurabilityService/Network/Heartbeat/ExpiryTime -- Default value: 10.0 -- Valid values: 0.2 / - +- Full path: /DurabilityService/Network/Heartbeat/ExpiryTime +- Default value: 4.0 - Occurrences min-max: 1-1 - Required attributes: update_factor @@ -2743,39 +2078,25 @@ update_factor every *ExpiryTime* multiplied by this *update_factor*. -- Full path: //OpenSplice/DurabilityService/Network/Heartbeat/ExpiryTime[@update_factor] -- Default value: 0.2 -- Valid values: 0.1 / 0.9 +- Full path: /DurabilityService/Network/Heartbeat/ExpiryTime/update_factor +- Default value: 0.25 - Required: true InitialDiscoveryPeriod ---------------------- - On startup the Durability Service needs to determine, for each namespace, if it has - to align with other Durability Services in the system or if it has to load the initial - state from disk (load persistent data). For this the Durability Service will publish a - request for information and wait for the specified initial discovery period for all - Durability services to respond. The Durability Service will load the persistent data - from disk if no response is received within the specified initial discovery period. - This initial discovery period should be configured greater than the worst case - expected discovery time which is related to underlying hardware, type of network, - network configuration, and expected load. If the initial discovery period is too short - the Durability Service may conclude that there is no running system and load the - data from disk, which will result in conflicting states ('split-brain syndrome') i.e. - two separate systems. - The Durabiltiy Service will wait for at least the full initial discovery period before it - can continue and become operational, so for fast startup times it is important to keep - the initial discovery period as small as possible. - .The metaphoric term 'split-brain syndrome' is sometimes used to highlight the results of - a temporary outage of communications between two parts of a system. In such a - situation, the states of the disconnected parts evolve separately and become - incompatible, so that by the time communication is restored the system has become - 'schizophrenic'. - -- Full path: //OpenSplice/DurabilityService/Network/InitialDiscoveryPeriod -- Dimension: seconds + To be able to ensure data consistency of historical data, the + Durability service needs to know which other Durability services + are available in the system. The value of this element determines + the amount of time the Durability service takes at startup to get + acquinted with all other Durability services in the system. + + Increasing the value will increase the startup time of the + Durability service, but is required in larger domains where a lot + of network bandwidth is used. + +- Full path: /DurabilityService/Network/InitialDiscoveryPeriod - Default value: 3.0 -- Valid values: 0.1 / 10.0 - Occurrences min-max: 0-1 Alignment @@ -2788,7 +2109,7 @@ Alignment consistency is called alignment. This element allows fine-tuning alignment behaviour of the Durability service. -- Full path: //OpenSplice/DurabilityService/Network/Alignment +- Full path: /DurabilityService/Network/Alignment - Occurrences min-max: 0-1 - Child elements: TimeAlignment, TimeToWaitForAligner - Optional attributes: latency_budget, transport_priority @@ -2801,9 +2122,8 @@ latency_budget It overrules the value of the OpenSplice/DurabilityService/Network[@latency_budget]. -- Full path: //OpenSplice/DurabilityService/Network/Alignment[@latency_budget] +- Full path: /DurabilityService/Network/Alignment/latency_budget - Default value: 0.0 -- Valid values: 0.0 / - - Required: false transport_priority @@ -2815,10 +2135,9 @@ transport_priority *DurabilityService/Network[@transport_priorrity]* for the alignment of data only. -- Full path: //OpenSplice/DurabilityService/Network/Alignment[@transport_priority] +- Full path: /DurabilityService/Network/Alignment/transport_priority - Format: integer - Default value: 0 -- Valid values: 0 / - - Required: false TimeAlignment @@ -2831,7 +2150,7 @@ TimeAlignment service needs to align more data since to compensate possible timing gaps between different nodes in the domain. -- Full path: //OpenSplice/DurabilityService/Network/Alignment/TimeAlignment +- Full path: /DurabilityService/Network/Alignment/TimeAlignment - Format: boolean - Default value: true - Occurrences min-max: 0-1 @@ -2842,7 +2161,7 @@ AlignerScheduling This element specifies the scheduling parameters used to control the thread that aligns other durability services. -- Full path: //OpenSplice/DurabilityService/Network/Alignment/AlignerScheduling +- Full path: /DurabilityService/Network/Alignment/AlignerScheduling - Occurrences min-max: 0-1 - Child elements: Priority, Class @@ -2856,7 +2175,7 @@ Priority privileges from the underlying operating system to be able to assign some of the privileged priorities. -- Full path: //OpenSplice/DurabilityService/Network/Alignment/AlignerScheduling/Priority +- Full path: /DurabilityService/Network/Alignment/AlignerScheduling/Priority - Format: integer - Default value: 0 - Occurrences min-max: 1-1 @@ -2868,7 +2187,7 @@ priority_kind This attribute specifies whether the specified Priority is a relative or absolute priority. -- Full path: //OpenSplice/DurabilityService/Network/Alignment/AlignerScheduling/Priority[@priority_kind] +- Full path: /DurabilityService/Network/Alignment/AlignerScheduling/Priority/priority_kind - Format: enumeration - Default value: Relative - Valid values: Relative, Absolute @@ -2883,7 +2202,7 @@ Class system to be able to assign some of the privileged scheduling classes. -- Full path: //OpenSplice/DurabilityService/Network/Alignment/AlignerScheduling/Class +- Full path: /DurabilityService/Network/Alignment/AlignerScheduling/Class - Format: enumeration - Default value: Default - Valid values: Timeshare, Realtime, Default @@ -2896,7 +2215,7 @@ AligneeScheduling control the thread that makes sure the local node becomes and stays aligned. -- Full path: //OpenSplice/DurabilityService/Network/Alignment/AligneeScheduling +- Full path: /DurabilityService/Network/Alignment/AligneeScheduling - Occurrences min-max: 0-1 - Child elements: Priority, Class @@ -2910,7 +2229,7 @@ Priority privileges from the underlying operating system to be able to assign some of the privileged priorities. -- Full path: //OpenSplice/DurabilityService/Network/Alignment/AligneeScheduling/Priority +- Full path: /DurabilityService/Network/Alignment/AligneeScheduling/Priority - Format: integer - Default value: 0 - Occurrences min-max: 1-1 @@ -2922,7 +2241,7 @@ priority_kind This attribute specifies whether the specified Priority is a relative or absolute priority. -- Full path: //OpenSplice/DurabilityService/Network/Alignment/AligneeScheduling/Priority[@priority_kind] +- Full path: /DurabilityService/Network/Alignment/AligneeScheduling/Priority/priority_kind - Format: enumeration - Default value: Relative - Valid values: Relative, Absolute @@ -2937,7 +2256,7 @@ Class system to be able to assign some of the privileged scheduling classes -- Full path: //OpenSplice/DurabilityService/Network/Alignment/AligneeScheduling/Class +- Full path: /DurabilityService/Network/Alignment/AligneeScheduling/Class - Format: enumeration - Default value: Default - Valid values: Timeshare, Realtime, Default @@ -2971,22 +2290,21 @@ RequestCombinePeriod is useful in case OpenSplice is started at the same time with more than two computing nodes. -- Full path: //OpenSplice/DurabilityService/Network/Alignment/RequestCombinePeriod +- Full path: /DurabilityService/Network/Alignment/RequestCombinePeriod - Occurrences min-max: 0-1 - Child elements: Initial, Operational Initial ~~~~~~~ - This element specifies the maximum amount of time the Durability - Service is allowed to wait with alignment after an alignment - request has been received and the service itself is not yet - considered operational because it has not yet aligned itself - with all other Durability Services. + This element specifies the maximum amount of time the Durability + Service is allowed to wait with alignment after an alignment + request has been received and the service itself is not yet + considered operational because it has not yet aligned itself + with all other Durability Services. -- Full path: //OpenSplice/DurabilityService/Network/Alignment/RequestCombinePeriod/Initial +- Full path: /DurabilityService/Network/Alignment/RequestCombinePeriod/Initial - Default value: 0.5 -- Valid values: 0.01 / 5.0 - Occurrences min-max: 0-1 Operational @@ -2997,9 +2315,8 @@ Operational request has been received and the service itself is already considered operational. -- Full path: //OpenSplice/DurabilityService/Network/Alignment/RequestCombinePeriod/Operational +- Full path: /DurabilityService/Network/Alignment/RequestCombinePeriod/Operational - Default value: 0.01 -- Valid values: 0.01 / 5.0 - Occurrences min-max: 0-1 Partition @@ -3016,7 +2333,7 @@ Partition that inherits the default qos policies and has the default alignment_priority. -- Full path: //OpenSplice/DurabilityService/Network/Alignment/Partition +- Full path: /DurabilityService/Network/Alignment/Partition - Occurrences min-max: 0-* - Required attributes: Name - Optional attributes: alignment_priority, latency_budget, transport_priority @@ -3026,7 +2343,7 @@ Name The name of the partition to use for alignment. -- Full path: //OpenSplice/DurabilityService/Network/Alignment/Partition[@Name] +- Full path: /DurabilityService/Network/Alignment/Partition/Name - Format: string - Default value: partition - Required: true @@ -3040,10 +2357,9 @@ alignment_priority no alignment_priority is configured, the service uses 0 as default. -- Full path: //OpenSplice/DurabilityService/Network/Alignment/Partition[@alignment_priority] +- Full path: /DurabilityService/Network/Alignment/Partition/alignment_priority - Format: integer - Default value: 0 -- Valid values: 0 / - - Required: false latency_budget @@ -3052,9 +2368,8 @@ latency_budget This attribute overrules the latency budget for this partition specified at this point. -- Full path: //OpenSplice/DurabilityService/Network/Alignment/Partition[@latency_budget] +- Full path: /DurabilityService/Network/Alignment/Partition/latency_budget - Default value: 0.0 -- Valid values: 0.0 / - - Required: false transport_priority @@ -3063,34 +2378,22 @@ transport_priority This attribute overrules the transport priority for this partition specified at this point. -- Full path: //OpenSplice/DurabilityService/Network/Alignment/Partition[@transport_priority] +- Full path: /DurabilityService/Network/Alignment/Partition/transport_priority - Format: integer - Default value: 0 -- Valid values: 0 / - - Required: false TimeToWaitForAligner ^^^^^^^^^^^^^^^^^^^^ - When all Durability Services in the domain have configured their aligner element - as false , none of them is able - to act as an aligner for newly-started Durability Services. Therefore late-joining - Durability Services will not be able to obtain historical data that is available in the - domain. - This element specifies the period (in seconds) to wait until an aligner becomes - available in the domain. If an aligner does not become available within the period - specified by this element, the entire federation will terminate and return with error - code 1 (recoverable error). - Currently only values between 0.0 and 1.0 are supported, and all non-zero values - are interpreted as infinite (so basically the time-out is currently either zero or - infinite). The default is 1.0. Note that when the element aligner - is set to true the current Durability Service is able to act as aligner for - other Durability Services with respect to the specified namespace and the federation - will not terminate. - -- Full path: //OpenSplice/DurabilityService/Network/Alignment/TimeToWaitForAligner + The period (in seconds) to wait until an aligner is available in the domain. + If an aligner does not become available within this period the entire federation + will terminate and returns with error code 1 (recoverable error). Currently only + values between 0.0 and 1.0 are supported, and all non-zero values are interpreted + as infinite. + +- Full path: /DurabilityService/Network/Alignment/TimeToWaitForAligner - Default value: 1.0 -- Valid values: 0.0 / 1.0 - Occurrences min-max: 0-1 WaitForAttachment @@ -3103,7 +2406,7 @@ WaitForAttachment be available and how long the Durability service must wait for them to become available before sending any data. -- Full path: //OpenSplice/DurabilityService/Network/WaitForAttachment +- Full path: /DurabilityService/Network/WaitForAttachment - Occurrences min-max: 0-1 - Child elements: ServiceName - Optional attributes: maxWaitCount @@ -3114,29 +2417,27 @@ maxWaitCount This attribute specifies the number of times the Durability service checks if the services specified in the *DurabilityService/Network/WaitForAttachment/ServiceName* - elements are available before sending any data. The time between - two checks is 100ms, so a maxWaitCount of 100 represents 10 seconds. - An error is logged if one of the services still is unavailable - afterwards. The service will continue after that, but this indicates - a problem in the configuration and the service might not function - correctly anymore. + elements are available before sending any data. An error is + logged if one of the services still is unavailable afterwards. + The service will continue after that, but this indicates + a problem in the configuration and the service might not + function correctly anymore. -- Full path: //OpenSplice/DurabilityService/Network/WaitForAttachment[@maxWaitCount] +- Full path: /DurabilityService/Network/WaitForAttachment/maxWaitCount - Format: integer - Default value: 200 -- Valid values: 1 / 1000 - Required: false ServiceName ^^^^^^^^^^^ - This element specifies the name of the service(s) that the Durability Service waits - for, before starting alignment activities for a specific topic-partition combination. If - (for example) the communication between Durability Services is dependent on the - availability of certain local Network Services, then the Durability Service must wait - until these are operational. + This element specifies the name of the service(s) that the + Durability service waits for, before starting alignment activities + for a specific topic-partition combination. In a multinode + environment the name of the Networking service MUST be included + here to assure a proper functioning of the Durability service. -- Full path: //OpenSplice/DurabilityService/Network/WaitForAttachment/ServiceName +- Full path: /DurabilityService/Network/WaitForAttachment/ServiceName - Format: string - Default value: networking - Occurrences min-max: 1-* @@ -3156,9 +2457,9 @@ Persistent Note these elements are only available as part of the DDS persistence profile of OpenSplice. -- Full path: //OpenSplice/DurabilityService/Persistent +- Full path: /DurabilityService/Persistent - Occurrences min-max: 0-1 -- Child elements: StoreDirectory, StoreSessionTime, StoreSleepTime, StoreMode, StoreOptimizeInterval, QueueSize +- Child elements: StoreDirectory, StoreSessionTime, StoreSleepTime, StoreMode, StoreOptimizeInterval - Optional attributes: SmpCount StoreDirectory @@ -3168,7 +2469,7 @@ StoreDirectory be stored on disk. If this parameter is not configured, the Durability service will not manage persistent data. -- Full path: //OpenSplice/DurabilityService/Persistent/StoreDirectory +- Full path: /DurabilityService/Persistent/StoreDirectory - Format: string - Default value: /tmp/pstore - Occurrences min-max: 1-1 @@ -3176,16 +2477,12 @@ StoreDirectory StoreSessionTime ---------------- - The Durability Service has a persistency thread that periodically (in sessions) writes - persistent data to disk, this element together with the Element StoreSleepTime can be - used to optimize disk access. This element specifies the maximum session time (in - seconds) for the persistency thread. After this period of time, it makes sure data is - flushed to disk + This element specifies the maximum session time (in seconds) + for the persistency thread. After this period of time, it makes + sure data is flushed to disk. -- Full path: //OpenSplice/DurabilityService/Persistent/StoreSessionTime -- Dimension: seconds +- Full path: /DurabilityService/Persistent/StoreSessionTime - Default value: 20.0 -- Valid values: 0.001 / 60.0 - Occurrences min-max: 0-1 StoreSleepTime @@ -3200,9 +2497,8 @@ StoreSleepTime so that it prevents other threads from progressing a non-zero value should be used. -- Full path: //OpenSplice/DurabilityService/Persistent/StoreSleepTime +- Full path: /DurabilityService/Persistent/StoreSleepTime - Default value: 0.0 -- Valid values: 0.0 / 10.0 - Occurrences min-max: 0-1 StoreMode @@ -3215,12 +2511,9 @@ StoreMode the memory that is being used by the persistent store. With "KV" mode the service will store persistent data in a key-value store using either sqlite of leveldb to store the data on disk. - !!! The "MMF" store is deprecated from version 6.3 and was only implemented on linux !!!, + !!! The "MMF" store is currently only implemented on linux !!! - !!! For "KV" stores, SQLite is supported on linux, Windows, and Solaris; LevelDB is only - supported on linux. - -- Full path: //OpenSplice/DurabilityService/Persistent/StoreMode +- Full path: /DurabilityService/Persistent/StoreMode - Format: enumeration - Default value: XML - Valid values: XML, MMF, KV @@ -3229,19 +2522,13 @@ StoreMode SmpCount -------- - This element determines how many threads the Durability service will spawn to - write persistent data to disk. Note that this attribute is currently only supported for - MMF (memory mapped file) StoreMode. - Please also note that although technically the maximum valid value for this element - is maxInt, the operating system may impose a lower limit, to prevent 'runaway' - consumption of resources and loss of performance. It is recommended that increases - of this value are carefully considered! - !!! The "MMF" store is deprecated from version 6.3 and was only implemented on linux !!!, + This element determines how many threads the durability + service will spawn to persist data to disk. Currently only supported for MMF + (memory mapped file) storemode. -- Full path: //OpenSplice/DurabilityService/Persistent[@SmpCount] +- Full path: /DurabilityService/Persistent/SmpCount - Format: integer - Default value: 1 -- Valid values: 1 / - - Required: false KeyValueStore @@ -3253,9 +2540,8 @@ KeyValueStore element parameters specific to the used storage implementation can be defined which are passed to the selected storage implementation. This element is only valid when the Persistent/StoreMode element is set to "KV". - The "KV" store is currenly only supported on linux (SQLite and LevelDB), Windows (SQLite), and Solaris (SQLite). -- Full path: //OpenSplice/DurabilityService/Persistent/KeyValueStore +- Full path: /DurabilityService/Persistent/KeyValueStore - Occurrences min-max: 0-1 - Child elements: StorageParameters - Required attributes: type @@ -3263,80 +2549,26 @@ KeyValueStore type ^^^^ - This attribute specifies the third-party product that is used to implement the KV store. - Products currently supported are SQLite and LevelDB + This attribute specifies the specific storage product used to implement the key-value store. -- Full path: //OpenSplice/DurabilityService/Persistent/KeyValueStore[@type] +- Full path: /DurabilityService/Persistent/KeyValueStore/type - Format: enumeration - Default value: sqlite3 -- Valid values: sqlite3, sqlite, leveldb +- Valid values: sqlite3, leveldb - Required: true StorageParameters ^^^^^^^^^^^^^^^^^ - This element is used to set parameters that are specific to the third-party product - used to implement the KV store. The element consists of a list of parameters which - are separated by semicolons (';'). Each parameter is either a single name or a - key-value pair where the key and the value are separated by a '=' character. - Invalid or 'not recognized' values are ignored. - \* When SQLite is selected as KV store implementation, refer to the Sqlite - documentation for full details of the available parameters (see - http://www.sqlite.org/pragma.html). The only exceptions are the parameters that - the KV store uses itself, which are: locking_mode, journal_mode, - wal_autocheckpoint and synchronous. - - \* When LevelDB is selected as the KV store the following parameters are available - (the information below has been taken from the current LevelDB - documentation the project home page is at http://code.google.com/p/leveldb/) - - paranoid_checks - boolean - -If true, the implementation will do aggressive checking of the data it is - processing and it will stop early if it detects any errors. This may have - unforeseen ramifications: for example, a corruption of one database entry may - cause a large number of entries to become unreadable or for the entire database - to become unopenable. - Default: false - - write_buffer_size - integer - -Amount of data to build up in memory (backed by an unsorted log on disk) - before converting to a sorted on-disk file. Larger values improve performance, - especially during bulk loads. Up to two write buffers may be held in memory at - the same time, so you may wish to adjust this parameter to control memory - usage. Also, a larger write buffer will result in a longer recovery time the next - time the database is opened. - Default: 4MB - - max_open_files - integer - -Number of open files that can be used by the database. You may need to - increase this if your database has a large working set (budget one open file per - 2MB of working set). - Default: 1000 - - block_size - integer - -Approximate size of user data packed per block. Note that the block size - specified here corresponds to uncompressed data. The actual size of the unit - read from disk may be smaller if compression is enabled. This parameter can be - changed dynamically. - Set by the KV store to 1M. - - verify_checksums - boolean - -If true, all data read from underlying storage will be verified against - corresponding checksums. - Default: false - - fill_cache - boolean - -Should the data read for this iteration be cached in memory? Callers may wish - to set this field to false for bulk scans. - Default: true - -- Full path: //OpenSplice/DurabilityService/Persistent/KeyValueStore/StorageParameters + This element specifies the configuration settings of the used storage implementation. + These configuration parameters are specific to the used storage which are documented + in the storage specific documentation. The configuration parameters are transparently + passed to the used storage. The StorageParameters consists of a list of configuration + items where each item is seperated by a ';'. Dependent on the storage an item can be + a single name or a name-value pair. In case of a name-value pair the name and the value + are seperated by an '=' character (name = value). + +- Full path: /DurabilityService/Persistent/KeyValueStore/StorageParameters - Format: string - Default value: 0 - Occurrences min-max: 0-1 @@ -3353,7 +2585,7 @@ Compression Compression is set at store creation time. Changing these settings after the store is created will result in an error. -- Full path: //OpenSplice/DurabilityService/Persistent/KeyValueStore/Compression +- Full path: /DurabilityService/Persistent/KeyValueStore/Compression - Occurrences min-max: 0-1 - Required attributes: algorithm - Optional attributes: enabled @@ -3369,7 +2601,7 @@ algorithm system, and it must be locatable by way of the current working directory, or via LD_LIBRARY_PATH (on Unix systems) or PATH (on Windows systems). -- Full path: //OpenSplice/DurabilityService/Persistent/KeyValueStore/Compression[@algorithm] +- Full path: /DurabilityService/Persistent/KeyValueStore/Compression/algorithm - Format: enumeration - Default value: lzf - Valid values: lzf, snappy, zlib @@ -3381,7 +2613,7 @@ enabled This attribute specifies whether the key-value store will apply compression for storing persistent data to limit disk usage. -- Full path: //OpenSplice/DurabilityService/Persistent/KeyValueStore/Compression[@enabled] +- Full path: /DurabilityService/Persistent/KeyValueStore/Compression/enabled - Format: boolean - Default value: true - Required: false @@ -3391,10 +2623,8 @@ MemoryMappedFileStore This element specifies the memory mapped file store mode parameters. This element is only valid when the Persistent/StoreMode element is set to "MMF". - The size and the starting address of the memory file must be supplied - The "MMF" store is deprecated from version 6.3. and was only implemented in Linux -- Full path: //OpenSplice/DurabilityService/Persistent/MemoryMappedFileStore +- Full path: /DurabilityService/Persistent/MemoryMappedFileStore - Occurrences min-max: 0-1 - Child elements: Size, Address @@ -3417,9 +2647,8 @@ Size If this value is not specified, the size of the persistent store will be set to twice the size of the shared memory segment. -- Full path: //OpenSplice/DurabilityService/Persistent/MemoryMappedFileStore/Size +- Full path: /DurabilityService/Persistent/MemoryMappedFileStore/Size - Default value: 10485760 -- Valid values: 1048576 / - - Occurrences min-max: 0-1 Address @@ -3436,7 +2665,7 @@ Address If this value is not specified, the file will be mapped just after the shared memory segment. -- Full path: //OpenSplice/DurabilityService/Persistent/MemoryMappedFileStore/Address +- Full path: /DurabilityService/Persistent/MemoryMappedFileStore/Address - Format: string - Default value: 0x80000000 - Occurrences min-max: 0-1 @@ -3444,17 +2673,13 @@ Address StoreOptimizeInterval --------------------- - This element determines after how many write actions the persistent set for a - specific partition-topic combination is optimized on disk. Persistent data is - sequentially written to disk without removing data that according to key values and - history policies can be removed. During a store optimize action the Durability - Service will rewrite the file and thereby remove all disposable data. Note that a long - interval will minimize the induced mean load but instead increases burst load. + This element determines after how many write actions the + persistent set for a specific partition-topic combination + is optimized on disk. -- Full path: //OpenSplice/DurabilityService/Persistent/StoreOptimizeInterval +- Full path: /DurabilityService/Persistent/StoreOptimizeInterval - Format: integer - Default value: 0 -- Valid values: 0 / 1000000000 - Occurrences min-max: 0-1 Scheduling @@ -3464,7 +2689,7 @@ Scheduling control the thread that stores persistent data on permanent storage. -- Full path: //OpenSplice/DurabilityService/Persistent/Scheduling +- Full path: /DurabilityService/Persistent/Scheduling - Occurrences min-max: 0-1 - Child elements: Priority, Class @@ -3477,7 +2702,7 @@ Priority The user may need special privileges from the underlying operating system to be able to assign some of the privileged priorities. -- Full path: //OpenSplice/DurabilityService/Persistent/Scheduling/Priority +- Full path: /DurabilityService/Persistent/Scheduling/Priority - Format: integer - Default value: 0 - Occurrences min-max: 1-1 @@ -3489,7 +2714,7 @@ priority_kind This attribute specifies whether the specified Priority is a relative or absolute priority. -- Full path: //OpenSplice/DurabilityService/Persistent/Scheduling/Priority[@priority_kind] +- Full path: /DurabilityService/Persistent/Scheduling/Priority/priority_kind - Format: enumeration - Default value: Relative - Valid values: Relative, Absolute @@ -3503,7 +2728,7 @@ Class privileges from the underlying operating system to be able to assign some of the privileged scheduling classes. -- Full path: //OpenSplice/DurabilityService/Persistent/Scheduling/Class +- Full path: /DurabilityService/Persistent/Scheduling/Class - Format: enumeration - Default value: Default - Valid values: Timeshare, Realtime, Default @@ -3512,34 +2737,15 @@ Class NameSpaces ========== - When a durability service wants to fulfill a particular role for some of the - namespaces in a domain, it must have some way of deducing the desired behavior - for those when encountered. For static, small-scale systems this can easily be solved - by statically configurating this role-behavior for all relevant namespaces for each - durability service in the domain. - In dynamic, large scale environments, the updating and maintaining of - configurations for each durability service when new namespaces enter the domain - can become quite cumbersome. Dynamic namespaces offer a solution for this - problem. - Instead of specifying each namespace seperately, dynamic namespaces introduce - the concept of namespace policies. A policy defines a generic role for the durability - service, together with a namespace expression. This expression can contain - wildcards, and is used to match against each namespace the durability service - encounters in a domain. The first policy with a matching expression is then applied - to the new namespace. - Specifying policies - Policies are specified in a fall-through manner, which means that the first (top) - policy to match a namespace is applied. Policies specify a range of options for - namespaces, which tell the durability service how to handle the data. - The following items can be configured: - \* Durability - \* Alignee - \* Aligner - In the dynamic namespace configuration, the NameSpace element (a child of the - NameSpaces element) only supports a name attribute, which is mandatory. This - name will be used to match against policies. - -- Full path: //OpenSplice/DurabilityService/NameSpaces + Scalability of durable data is an issue in large systems. Keeping + all historical data on each node may not be feasible. Often nodes are + interested in a small part of the total system data, on one hand + driven by application interest, on the other hand driven by + fault-tolerance (the need for replicates). This setting controls + which historical data is managed by this Durability service + (both transient and persistent). + +- Full path: /DurabilityService/NameSpaces - Occurrences min-max: 1-1 NameSpace @@ -3553,10 +2759,10 @@ NameSpace be managed by the Durability service. Data that does not match any of the namespaces, is ignored by the Durability service. -- Full path: //OpenSplice/DurabilityService/NameSpaces/NameSpace +- Full path: /DurabilityService/NameSpaces/NameSpace - Occurrences min-max: 1-* - Child elements: Partition, PartitionTopic -- Optional attributes: name, durabilityKind, alignmentKind, mergePolicy +- Required attributes: name name ^^^^ @@ -3564,10 +2770,11 @@ name This element specifies the name for a namespace. A name is used to match a namespace with a policy. -- Full path: //OpenSplice/DurabilityService/NameSpaces/NameSpace[@name] +- Full path: /DurabilityService/NameSpaces/NameSpace/name - Format: string - Default value: defaultNameSpace -- Required: false +- Occurrences min-max: 1-1 +- Required: true Partition ^^^^^^^^^ @@ -3579,10 +2786,10 @@ Partition different namespaces do not have an overlap in partitions. The default configuration has one namespace containing all partitions. A partition may contain the - wildcards '\*' to match any number of characters and '?' + wildcards '*' to match any number of characters and '?' to match one single character. -- Full path: //OpenSplice/DurabilityService/NameSpaces/NameSpace/Partition +- Full path: /DurabilityService/NameSpaces/NameSpace/Partition - Format: string - Default value: * - Occurrences min-max: 0-* @@ -3599,11 +2806,11 @@ PartitionTopic to the namespace. Make sure the different namespaces do not have an overlap in expressions. The default configuration has one namespace containing all - combinations (\*.\*). A partition-topic expression may - contain the wildcards '\*' to match any number of + combinations (*.*). A partition-topic expression may + contain the wildcards '*' to match any number of characters and '?' to match one single character. -- Full path: //OpenSplice/DurabilityService/NameSpaces/NameSpace/PartitionTopic +- Full path: /DurabilityService/NameSpaces/NameSpace/PartitionTopic - Format: string - Default value: *.* - Occurrences min-max: 0-* @@ -3626,8 +2833,8 @@ Policy important, as the first matching template will be the one that is selected for a namespace. -- Full path: //OpenSplice/DurabilityService/NameSpaces/Policy -- Occurrences min-max: 0-* +- Full path: /DurabilityService/NameSpaces/Policy +- Occurrences min-max: 1-* - Required attributes: nameSpace, durability, aligner, alignee - Optional attributes: delayedAlignment, equalityCheck @@ -3653,40 +2860,16 @@ Merge merge policy the instance state of the instances that are not changed will remain untouched. The scope attribute specifies for which role(s) the mergepolicy will be applied. - A scope may contain the wildcards '\*' to match any number of characters and '?' to match one + A scope may contain the wildcards '*' to match any number of characters and '?' to match one single character. -- Full path: //OpenSplice/DurabilityService/NameSpaces/Policy/Merge +- Full path: /DurabilityService/NameSpaces/Policy/Merge - Occurrences min-max: 0-* - Required attributes: type, scope type ~~~~ - - The type attribute describes the kind of action required on a namespace state mismatch. - - - Ignore: Do nothing in case of a state mismatch. No samples are aligned, and - namespace states will not be updated. - - Merge: Merge historical data from other namespace state. This will result in a - new namespace state for the durability service that specifies this value. - - Delete: Dispose and delete historical data in case of a state mismatch. - Immediately after successful completion of the Delete merge action no transient - or persistent data will be available for late-joining readers, and all data in the - reader queue of existing readers will be disposed. - - Replace: Dispose and delete historical data in case of a state mismatch, and merge - data from another namespace state. This will result in a new namespace state for - the durability service that specifies this value. Immediately after successful - completion of the Replace merge action the replacement data will be available to - late-joining readers, the data in the reader queue of existing readers will be - disposed and replaced with the replacement data, and the generation count of the - replacement data is increased. - - Catchup: When a state mismatch occurs, instances that do not exist any more are - disposed, and instances that have been added or changed are updated. Instances - for which no state mismatch occurs are left untouched. Immediately after - successful completion of the Catchup merge action the data will be available to - existing readers and late-joining readers. - -- Full path: //OpenSplice/DurabilityService/NameSpaces/Policy/Merge[@type] +- Full path: /DurabilityService/NameSpaces/Policy/Merge/type - Format: enumeration - Default value: Ignore - Valid values: Ignore, Merge, Delete, Replace, Catchup @@ -3694,15 +2877,7 @@ type scope ~~~~~ - - The scope attribute describes for which scope the merge policy is valid. The scope - is a role-expression in which wildcards ('\*' and '?') are allowed. Roles are matched - at runtime against this expression to determine which policy applies for that role. - When a role doesn't match any policy, 'Ignore' is assumed. The order of - specifying policies is important: the first scope expression that matches a role is - selected for that role. - -- Full path: //OpenSplice/DurabilityService/NameSpaces/Policy/Merge[@scope] +- Full path: /DurabilityService/NameSpaces/Policy/Merge/scope - Format: string - Default value: * - Required: true @@ -3711,10 +2886,10 @@ nameSpace ^^^^^^^^^ The element specifies an expression that matches a namespace name. - A namespace may contain the wildcards '\*' to match any number of + A namespace may contain the wildcards '*' to match any number of characters and '?' to match one single character. -- Full path: //OpenSplice/DurabilityService/NameSpaces/Policy[@nameSpace] +- Full path: /DurabilityService/NameSpaces/Policy/nameSpace - Format: string - Default value: * - Required: true @@ -3743,7 +2918,7 @@ durability - **Transient_Local**: Data is maximally handled as if it were published with a transient_local durability QoS. - **Durable**: Convenience value that behaves equal to Persistent. -- Full path: //OpenSplice/DurabilityService/NameSpaces/Policy[@durability] +- Full path: /DurabilityService/NameSpaces/Policy/durability - Format: enumeration - Default value: Durable - Valid values: Durable, Persistent, Transient, Transient_Local @@ -3752,10 +2927,10 @@ durability aligner ^^^^^^^ -This mandatory attribute determines whether the durability service can act as aligner -(provide historical data) for other durability services. + This element determines if the durability service will provide + historical data to other durability services. -- Full path: //OpenSplice/DurabilityService/NameSpaces/Policy[@aligner] +- Full path: /DurabilityService/NameSpaces/Policy/aligner - Format: boolean - Default value: True - Required: true @@ -3778,7 +2953,7 @@ alignee - **Lazy**: The Durability service caches historical data after local application interest arises for the first time and a remote Durability service aligns the first data reader. Historical data is available relatively slow for the first data reader, but for every new data reader it is relatively fast. The caching resources are only used when local interest in the data arises, so it only requires resources if there is actual local interest. However, this method provides no fault-tolerance for the domain, because the local Durability service is only partly a replica and is not able to provide historical data to remote Durability service and/or remote data readers. - **On_Request**: The Durability service will not cache historical data, but will align each separate DataReader on a request basis (in the situation where it calls wait_for_historical_data). Each new DataReader that wants historical data therefore leads to a new alignment action. This is a good setting to limit the amount of resources used on the node, but will potentially lead to more network traffic. This method provides no fault-tolerance for the domain. -- Full path: //OpenSplice/DurabilityService/NameSpaces/Policy[@alignee] +- Full path: /DurabilityService/NameSpaces/Policy/alignee - Format: enumeration - Default value: Initial - Valid values: Initial, Lazy, On_Request @@ -3787,13 +2962,13 @@ alignee delayedAlignment ^^^^^^^^^^^^^^^^ - This element determines if the durability allows delayed alignment of initial data. + [BETA] This element determines if the durability allows delayed alignment of initial data. This can be usefull for systems where there can be late-joining nodes with a persistent dataset, which by default are then not inserted. When this option is enabled, durability will only insert a persistent set from a late joining node when no writers have been created in the partitions matched by the namespace! -- Full path: //OpenSplice/DurabilityService/NameSpaces/Policy[@delayedAlignment] +- Full path: /DurabilityService/NameSpaces/Policy/delayedAlignment - Format: boolean - Default value: False - Required: false @@ -3819,7 +2994,7 @@ equalityCheck enabled for data sets that change often then chances of set equality are small, while the penalty to calculate hashes still exists. -- Full path: //OpenSplice/DurabilityService/NameSpaces/Policy[@equalityCheck] +- Full path: /DurabilityService/NameSpaces/Policy/equalityCheck - Format: boolean - Default value: False - Required: false @@ -3844,7 +3019,7 @@ Filters point in time, then only this subset will be aligned to the other nodes. -- Full path: //OpenSplice/DurabilityService/NameSpaces/Filters +- Full path: /DurabilityService/NameSpaces/Filters - Occurrences min-max: 0-1 Filter @@ -3860,7 +3035,7 @@ Filter aligned for this partition-topic combination. If multiple filters are defined then the first one that matches will be applied. -- Full path: //OpenSplice/DurabilityService/NameSpaces/Filters/Filter +- Full path: /DurabilityService/NameSpaces/Filters/Filter - Occurrences min-max: 0-* - Child elements: PartitionTopic - Required attributes: content @@ -3891,7 +3066,7 @@ content If an invalid filter expression is provided an error will be logged in ospl-error.log. -- Full path: //OpenSplice/DurabilityService/NameSpaces/Filters/Filter[@content] +- Full path: /DurabilityService/NameSpaces/Filters/Filter/content - Format: string - Default value: n/a - Required: true @@ -3901,10 +3076,10 @@ PartitionTopic This element specifies the partition-topics to which the filter expression is applied. A partition-topic - expression may contain the wildcards '\*' to match any number of + expression may contain the wildcards '*' to match any number of characters and '?' to match one single character. -- Full path: //OpenSplice/DurabilityService/NameSpaces/Filters/Filter/PartitionTopic +- Full path: /DurabilityService/NameSpaces/Filters/Filter/PartitionTopic - Format: string - Default value: *.* - Occurrences min-max: 0-* @@ -3916,7 +3091,7 @@ EntityNames DurabilityService. The names specified here will be displayed in the OpenSplice DDS Tuner when viewing the DurabilityService. -- Full path: //OpenSplice/DurabilityService/EntityNames +- Full path: /DurabilityService/EntityNames - Occurrences min-max: 0-1 - Child elements: Publisher, Subscriber, Partition @@ -3925,7 +3100,7 @@ Publisher This element specifies the name of the durability publisher. -- Full path: //OpenSplice/DurabilityService/EntityNames/Publisher +- Full path: /DurabilityService/EntityNames/Publisher - Format: string - Default value: durabilityPublisher - Occurrences min-max: 0-1 @@ -3935,7 +3110,7 @@ Subscriber This element specifies the name of the durability subscriber. -- Full path: //OpenSplice/DurabilityService/EntityNames/Subscriber +- Full path: /DurabilityService/EntityNames/Subscriber - Format: string - Default value: durabilitySubscriber - Occurrences min-max: 0-1 @@ -3945,7 +3120,7 @@ Partition This element specifies the name of the durability partition. -- Full path: //OpenSplice/DurabilityService/EntityNames/Partition +- Full path: /DurabilityService/EntityNames/Partition - Format: string - Default value: durabilityPartition - Occurrences min-max: 0-1 @@ -3958,7 +3133,7 @@ Tracing useful to track the Durability Service during application development. In the runtime system it should be turned off. -- Full path: //OpenSplice/DurabilityService/Tracing +- Full path: /DurabilityService/Tracing - Occurrences min-max: 0-1 - Child elements: OutputFile, Timestamps, Verbosity - Optional attributes: synchronous @@ -3972,7 +3147,7 @@ synchronous option if you are debugging and you want to make sure all Tracing info is on disk when the service crashes. -- Full path: //OpenSplice/DurabilityService/Tracing[@synchronous] +- Full path: /DurabilityService/Tracing/synchronous - Format: boolean - Default value: FALSE - Required: false @@ -3986,7 +3161,7 @@ OutputFile The default value is an empty string, indicating that all tracing is disabled. -- Full path: //OpenSplice/DurabilityService/Tracing/OutputFile +- Full path: /DurabilityService/Tracing/OutputFile - Format: string - Default value: durability.log - Occurrences min-max: 0-1 @@ -3996,7 +3171,7 @@ Timestamps This element specifies whether the logging must contain timestamps. -- Full path: //OpenSplice/DurabilityService/Tracing/Timestamps +- Full path: /DurabilityService/Tracing/Timestamps - Format: boolean - Default value: true - Occurrences min-max: 0-1 @@ -4008,7 +3183,7 @@ absolute This attribute specifies whether the timestamps are absolute or relative to the startup time of the service. -- Full path: //OpenSplice/DurabilityService/Tracing/Timestamps[@absolute] +- Full path: /DurabilityService/Tracing/Timestamps/absolute - Format: boolean - Default value: true - Required: false @@ -4020,7 +3195,7 @@ Verbosity information. The higher the level, the more (detailed) information will be logged. -- Full path: //OpenSplice/DurabilityService/Tracing/Verbosity +- Full path: /DurabilityService/Tracing/Verbosity - Format: enumeration - Default value: INFO - Valid values: SEVERE, WARNING, INFO, CONFIG, FINE, FINER, FINEST, NONE @@ -4041,7 +3216,7 @@ SNetworkService to schedule sending and receival of specific messages to provide optimal performance for a specific application domain. -- Full path: //OpenSplice/SNetworkService +- Full path: /SNetworkService - Occurrences min-max: 0-* - Required attributes: name @@ -4055,7 +3230,7 @@ name *//OpenSplice/Domain/Service[@name]* in the configuration of the DomainService. -- Full path: //OpenSplice/SNetworkService[@name] +- Full path: /SNetworkService/name - Format: string - Default value: snetworking - Required: true @@ -4065,7 +3240,7 @@ Watchdog This element controls the characteristics of the Watchdog thread. -- Full path: //OpenSplice/SNetworkService/Watchdog +- Full path: /SNetworkService/Watchdog - Occurrences min-max: 0-1 Scheduling @@ -4074,7 +3249,7 @@ Scheduling This element specifies the type of OS scheduling class will be used by the thread that announces its liveliness periodically. -- Full path: //OpenSplice/SNetworkService/Watchdog/Scheduling +- Full path: /SNetworkService/Watchdog/Scheduling - Occurrences min-max: 1-1 - Child elements: Priority, Class @@ -4087,7 +3262,7 @@ Priority The user may need special privileges from the underlying operating system to be able to assign some of the privileged priorities. -- Full path: //OpenSplice/SNetworkService/Watchdog/Scheduling/Priority +- Full path: /SNetworkService/Watchdog/Scheduling/Priority - Format: integer - Default value: 0 - Occurrences min-max: 1-1 @@ -4099,7 +3274,7 @@ priority_kind This attribute specifies whether the specified Priority is a relative or absolute priority. -- Full path: //OpenSplice/SNetworkService/Watchdog/Scheduling/Priority[@priority_kind] +- Full path: /SNetworkService/Watchdog/Scheduling/Priority/priority_kind - Format: enumeration - Default value: Relative - Valid values: Relative, Absolute @@ -4113,7 +3288,7 @@ Class the underlying operating system to be able to assign some of the privileged scheduling classes. -- Full path: //OpenSplice/SNetworkService/Watchdog/Scheduling/Class +- Full path: /SNetworkService/Watchdog/Scheduling/Class - Format: enumeration - Default value: Default - Valid values: Timeshare, Realtime, Default @@ -4125,7 +3300,7 @@ General This element contains general parameters that concern the secure networking service as a whole. -- Full path: //OpenSplice/SNetworkService/General +- Full path: /SNetworkService/General - Occurrences min-max: 0-1 - Child elements: NetworkInterfaceAddress, EnableMulticastLoopback, LegacyCompression @@ -4140,7 +3315,7 @@ NetworkInterfaceAddress middleware will try to look up an interface that has the required capabilities. -- Full path: //OpenSplice/SNetworkService/General/NetworkInterfaceAddress +- Full path: /SNetworkService/General/NetworkInterfaceAddress - Format: string - Default value: first available - Occurrences min-max: 0-1 @@ -4154,7 +3329,7 @@ forced - false - Specifies that the NetworkInterfaceAddress is first used but when not available another, when available, is used. (default). - true - Specifies that only the selected NetworkInterfaceAddress can be used. -- Full path: //OpenSplice/SNetworkService/General/NetworkInterfaceAddress[@forced] +- Full path: /SNetworkService/General/NetworkInterfaceAddress/forced - Format: boolean - Default value: false - Required: false @@ -4173,7 +3348,7 @@ ipv6 optionally required to specify IPv6 communication when special values like "first available" or an interface name are used instead of IP addresses. -- Full path: //OpenSplice/SNetworkService/General/NetworkInterfaceAddress[@ipv6] +- Full path: /SNetworkService/General/NetworkInterfaceAddress/ipv6 - Format: boolean - Default value: false - Required: false @@ -4187,7 +3362,7 @@ bind - any - Specifies that the service should bind to the wildcard-address (INADDR_ANY) (default). - strict - Specifies that the service should bind to the NetworkingInterfaceAddress. -- Full path: //OpenSplice/SNetworkService/General/NetworkInterfaceAddress[@bind] +- Full path: /SNetworkService/General/NetworkInterfaceAddress/bind - Format: enumeration - Default value: any - Valid values: any, strict @@ -4205,7 +3380,7 @@ allowReuse - true - Ports can be reused (SO_REUSEADDR enabled) (default). - false - Ports are bound exclusively. -- Full path: //OpenSplice/SNetworkService/General/NetworkInterfaceAddress[@allowReuse] +- Full path: /SNetworkService/General/NetworkInterfaceAddress/allowReuse - Format: boolean - Default value: true - Required: false @@ -4218,7 +3393,7 @@ EnableMulticastLoopback specifies whether the secure networking service will all but if a node runs only a single OpenSplice secure networking service and does not host any other networking-capable programs, it may be set to FALSE for improved performance. -- Full path: //OpenSplice/SNetworkService/General/EnableMulticastLoopback +- Full path: /SNetworkService/General/EnableMulticastLoopback - Format: boolean - Default value: True - Valid values: True, False @@ -4232,7 +3407,7 @@ LegacyCompression backward compatibility. When set to FALSE compression is applied before fragmentation. The default value is TRUE. -- Full path: //OpenSplice/SNetworkService/General/LegacyCompression +- Full path: /SNetworkService/General/LegacyCompression - Format: boolean - Default value: True - Valid values: True, False @@ -4250,7 +3425,7 @@ Reconnection If automatic reconnection is allowed, communication channels with the now-reachable-again node will be restored, even though reliable data might have been lost during the disconnection period. -- Full path: //OpenSplice/SNetworkService/General/Reconnection +- Full path: /SNetworkService/General/Reconnection - Occurrences min-max: 0-1 - Required attributes: allowed @@ -4265,7 +3440,7 @@ allowed - false - Specifies that the network service must NOT resume communication. (default). - true - Specifies that the network service must resume communication. -- Full path: //OpenSplice/SNetworkService/General/Reconnection[@allowed] +- Full path: /SNetworkService/General/Reconnection/allowed - Format: boolean - Default value: false - Required: true @@ -4299,7 +3474,7 @@ Partitioning onto a specific networking partition, which on its turn is only connected to those nodes that are capable of handling high volume data. -- Full path: //OpenSplice/SNetworkService/Partitioning +- Full path: /SNetworkService/Partitioning - Occurrences min-max: 0-1 GlobalPartition @@ -4307,7 +3482,7 @@ GlobalPartition This element specifies the global or default secure networking partition. -- Full path: //OpenSplice/SNetworkService/Partitioning/GlobalPartition +- Full path: /SNetworkService/Partitioning/GlobalPartition - Occurrences min-max: 0-1 - Required attributes: Address - Optional attributes: SecurityProfile, MulticastTimeToLive @@ -4329,7 +3504,7 @@ Address symbolic hostname, in which case the middleware will try to resolve the corresponding IP address. -- Full path: //OpenSplice/SNetworkService/Partitioning/GlobalPartition[@Address] +- Full path: /SNetworkService/Partitioning/GlobalPartition/Address - Format: string - Default value: broadcast - Required: true @@ -4346,21 +3521,17 @@ SecurityProfile security feature has been enabled, but no profile is declared, then the NULL profile is used by default: this means that no security is added to the transport -- Full path: //OpenSplice/SNetworkService/Partitioning/GlobalPartition[@SecurityProfile] +- Full path: /SNetworkService/Partitioning/GlobalPartition/SecurityProfile - Format: string - Default value: nullProfile - Required: false MulticastTimeToLive ^^^^^^^^^^^^^^^^^^^ - For each UDP packet sent out, The TimeToLive header value is set to this value for Multicast packets. -By specifying a value of '0', multicast traffic can be confined to the local node, and -such 'loopback' performance is typically optimized by the operating system. -- Full path: //OpenSplice/SNetworkService/Partitioning/GlobalPartition[@MulticastTimeToLive] +- Full path: /SNetworkService/Partitioning/GlobalPartition/MulticastTimeToLive - Default value: 32 -- Valid values: 0 / 255 - Required: false NetworkPartitions @@ -4369,7 +3540,7 @@ NetworkPartitions Networking configuration can contain a set of networking partitions, which are grouped under the NetworkPartitions element. -- Full path: //OpenSplice/SNetworkService/Partitioning/NetworkPartitions +- Full path: /SNetworkService/Partitioning/NetworkPartitions - Occurrences min-max: 0-1 NetworkPartition @@ -4377,18 +3548,17 @@ NetworkPartition Every NetworkPartition has a name, an address and a connected flag. -- Full path: //OpenSplice/SNetworkService/Partitioning/NetworkPartitions/NetworkPartition +- Full path: /SNetworkService/Partitioning/NetworkPartitions/NetworkPartition - Occurrences min-max: 1-* -- Required attributes: Address -- Optional attributes: Name, Connected, Compression, SecurityProfile, MulticastTimeToLive +- Required attributes: Address, Connected +- Optional attributes: Name, Compression, SecurityProfile, MulticastTimeToLive Name ~~~~ - The Name attribute identifies a Network Partition; it must be unique to create - associations with Element PartitionMappings. + A networking partition is uniquely identified by its name. -- Full path: //OpenSplice/SNetworkService/Partitioning/NetworkPartitions/NetworkPartition[@Name] +- Full path: /SNetworkService/Partitioning/NetworkPartitions/NetworkPartition/Name - Format: string - Default value: networkPartition - Required: false @@ -4396,16 +3566,18 @@ Name Address ~~~~~~~ -The address is a list of one or more unicast, multicast or broadcast addresses. If -more than one address is specified, then the different addresses should separated by -commas (,) semicolons (;) or spaces ( ). Samples for this partition will be sent to -all addresses that are specified in this list of addresses. To specify the default -broadcast address, use the expression "broadcast". Addresses can be entered as -'dotted decimal' IPv4 or 'colon-separated hexadecimal' IPv6 notation or as the -symbolic hostname, in which case OpenSplice will try to resolve the corresponding -IP address. + The address is a list + of one or more unicast, multicast or broadcast addresses. If more + than one address is specified, then the different + addresses are separated by a colon (,) semicolon (;) or space ( ). + Samples for this network partition will be sent to all addresses + that are specified in this list of addresses. To specify the + default broadcast address, use the expression "broadcast". + Addresses can be entered as dotted decimal notation or as the + symbolic hostname, in which case the middleware will try to + resolve the corresponding IP address. -- Full path: //OpenSplice/SNetworkService/Partitioning/NetworkPartitions/NetworkPartition[@Address] +- Full path: /SNetworkService/Partitioning/NetworkPartitions/NetworkPartition/Address - Format: string - Default value: broadcast - Required: true @@ -4424,10 +3596,10 @@ Connected filtered by the networking interface or multicast enabled switches. -- Full path: //OpenSplice/SNetworkService/Partitioning/NetworkPartitions/NetworkPartition[@Connected] +- Full path: /SNetworkService/Partitioning/NetworkPartitions/NetworkPartition/Connected - Format: boolean - Default value: true -- Required: false +- Required: true Compression ~~~~~~~~~~~ @@ -4442,7 +3614,7 @@ Compression - false - No compression is applied. This is also the default value if not specified. - true - Compression is applicable -- Full path: //OpenSplice/SNetworkService/Partitioning/NetworkPartitions/NetworkPartition[@Compression] +- Full path: /SNetworkService/Partitioning/NetworkPartitions/NetworkPartition/Compression - Format: boolean - Default value: false - Required: false @@ -4465,21 +3637,17 @@ SecurityProfile evaluated or initialized, and the associated secret cipher keys need not to be defined for the OpenSplice node in question. -- Full path: //OpenSplice/SNetworkService/Partitioning/NetworkPartitions/NetworkPartition[@SecurityProfile] +- Full path: /SNetworkService/Partitioning/NetworkPartitions/NetworkPartition/SecurityProfile - Format: string - Default value: nullProfile - Required: false MulticastTimeToLive ~~~~~~~~~~~~~~~~~~~ - For each UDP packet sent out, The TimeToLive header value is set to this value for Multicast packets. -By specifying a value of '0', multicast traffic can be confined to the local node, and -such 'loopback' performance is typically optimized by the operating system -- Full path: //OpenSplice/SNetworkService/Partitioning/NetworkPartitions/NetworkPartition[@MulticastTimeToLive] +- Full path: /SNetworkService/Partitioning/NetworkPartitions/NetworkPartition/MulticastTimeToLive - Default value: 32 -- Valid values: 0 / 255 - Required: false IgnoredPartitions @@ -4487,7 +3655,7 @@ IgnoredPartitions This element is used to group the set of IgnoredPartition elements. -- Full path: //OpenSplice/SNetworkService/Partitioning/IgnoredPartitions +- Full path: /SNetworkService/Partitioning/IgnoredPartitions - Occurrences min-max: 0-1 IgnoredPartition @@ -4498,7 +3666,7 @@ IgnoredPartition generate network-load. Any DCPS partition-topic combination specified in this element will not be distibuted by the Networking service. -- Full path: //OpenSplice/SNetworkService/Partitioning/IgnoredPartitions/IgnoredPartition +- Full path: /SNetworkService/Partitioning/IgnoredPartitions/IgnoredPartition - Occurrences min-max: 1-* - Required attributes: DCPSPartitionTopic @@ -4508,12 +3676,12 @@ DCPSPartitionTopic The Networking service will match any DCPS messages to the DCPSPartitionTopic expression and determine if it matches. The PartitionExpression and - TopicExpression are allowed to contain a '\*' wildcard, + TopicExpression are allowed to contain a '*' wildcard, meaning that anything matches. An exact match is considered better than a wildcard match. If a DCPS messages matches an expression it will not be send to the network. -- Full path: //OpenSplice/SNetworkService/Partitioning/IgnoredPartitions/IgnoredPartition[@DCPSPartitionTopic] +- Full path: /SNetworkService/Partitioning/IgnoredPartitions/IgnoredPartition/DCPSPartitionTopic - Format: string - Default value: *.* - Required: true @@ -4523,7 +3691,7 @@ PartitionMappings This element is used to group the set of PartitionMapping elements. -- Full path: //OpenSplice/SNetworkService/Partitioning/PartitionMappings +- Full path: /SNetworkService/Partitioning/PartitionMappings - Occurrences min-max: 0-1 PartitionMapping @@ -4537,7 +3705,7 @@ PartitionMapping partitions should be defined. Networking allows for a set of partition mappings to be defined. -- Full path: //OpenSplice/SNetworkService/Partitioning/PartitionMappings/PartitionMapping +- Full path: /SNetworkService/Partitioning/PartitionMappings/PartitionMapping - Occurrences min-max: 1-* - Required attributes: NetworkPartition, DCPSPartitionTopic @@ -4549,7 +3717,7 @@ NetworkPartition specific DCPS partition of a specific DCPS topic should be sent to. -- Full path: //OpenSplice/SNetworkService/Partitioning/PartitionMappings/PartitionMapping[@NetworkPartition] +- Full path: /SNetworkService/Partitioning/PartitionMappings/PartitionMapping/NetworkPartition - Format: string - Default value: networkPartition - Required: true @@ -4560,7 +3728,7 @@ DCPSPartitionTopic The Networking service will match any DCPS messages to the DCPSPartitionTopic expression and determine if it matches. The PartitionExpression and - TopicExpression are allowed to contain a '\*' wildcard, + TopicExpression are allowed to contain a '*' wildcard, meaning that anything matches. An exact match is considered better than a wildcard match. For every DCPS message, the best matching partition is determined @@ -4568,7 +3736,7 @@ DCPSPartitionTopic partition as specified by the matching *NetworkPartition* element. -- Full path: //OpenSplice/SNetworkService/Partitioning/PartitionMappings/PartitionMapping[@DCPSPartitionTopic] +- Full path: /SNetworkService/Partitioning/PartitionMappings/PartitionMapping/DCPSPartitionTopic - Format: string - Default value: *.* - Required: true @@ -4583,7 +3751,7 @@ Security required for a network partition, the network partition must be associated with a security profile -- Full path: //OpenSplice/SNetworkService/Security +- Full path: /SNetworkService/Security - Occurrences min-max: 0-1 - Optional attributes: enabled @@ -4599,7 +3767,7 @@ enabled defined in the configuration file will not take effect, but will cause the system to log warnings. -- Full path: //OpenSplice/SNetworkService/Security[@enabled] +- Full path: /SNetworkService/Security/enabled - Format: boolean - Default value: false - Required: false @@ -4610,7 +3778,7 @@ SecurityProfile This element defines the security profile which can be applied to one or more network partitions. This element is optional. -- Full path: //OpenSplice/SNetworkService/Security/SecurityProfile +- Full path: /SNetworkService/Security/SecurityProfile - Occurrences min-max: 0-* - Required attributes: Name, Cipher, CipherKey @@ -4621,7 +3789,7 @@ Name being declared. If the name is not specified, the security profile will be ignored as it cannot be referenced anyway. -- Full path: //OpenSplice/SNetworkService/Security/SecurityProfile[@Name] +- Full path: /SNetworkService/Security/SecurityProfile/Name - Format: string - Default value: aSecurityProfile - Required: true @@ -4644,7 +3812,7 @@ Cipher integrity. Also, the rsa- prefix can be added to the ciphers. In this case, digital signatures using RSA will be available. -- Full path: //OpenSplice/SNetworkService/Security/SecurityProfile[@Cipher] +- Full path: /SNetworkService/Security/SecurityProfile/Cipher - Format: string - Default value: null - Valid values: aes128, aes192, aes256, blowfish, null, rsa-aes128, rsa-aes192, rsa-aes256, rsa-blowfish, rsa-null @@ -4673,7 +3841,7 @@ CipherKey read/write access to all DDS applications joining the same OpenSplice node. Because of this, the 'in-place' method is strongly discouraged. -- Full path: //OpenSplice/SNetworkService/Security/SecurityProfile[@CipherKey] +- Full path: /SNetworkService/Security/SecurityProfile/CipherKey - Format: string - Default value: n/a - Required: true @@ -4684,7 +3852,7 @@ AccessControl The optional AccessControl element defines settings for access control enforcement and which access control module shall be used. -- Full path: //OpenSplice/SNetworkService/Security/AccessControl +- Full path: /SNetworkService/Security/AccessControl - Occurrences min-max: 0-1 - Optional attributes: enabled, policy @@ -4693,7 +3861,7 @@ enabled The access control feature will be activated when enabled="true" -- Full path: //OpenSplice/SNetworkService/Security/AccessControl[@enabled] +- Full path: /SNetworkService/Security/AccessControl/enabled - Format: boolean - Default value: false - Required: false @@ -4703,7 +3871,7 @@ policy The policy attribute references a file containing the access control policy. -- Full path: //OpenSplice/SNetworkService/Security/AccessControl[@policy] +- Full path: /SNetworkService/Security/AccessControl/policy - Format: string - Default value: "" - Required: false @@ -4715,7 +3883,7 @@ AccessControlModule used. More than one module may be defined. All defined and enabled modules will be used to determine if access should be granted. -- Full path: //OpenSplice/SNetworkService/Security/AccessControl/AccessControlModule +- Full path: /SNetworkService/Security/AccessControl/AccessControlModule - Occurrences min-max: 0-* - Optional attributes: enabled, type @@ -4725,7 +3893,7 @@ enabled The module specified in the type attribute is used to evaluate access control rules when enabled="true". -- Full path: //OpenSplice/SNetworkService/Security/AccessControl/AccessControlModule[@enabled] +- Full path: /SNetworkService/Security/AccessControl/AccessControlModule/enabled - Format: boolean - Default value: true - Required: false @@ -4737,7 +3905,7 @@ type supports mandatory access control, accordingly the only valid value for this attribute is "MAC". -- Full path: //OpenSplice/SNetworkService/Security/AccessControl/AccessControlModule[@type] +- Full path: /SNetworkService/Security/AccessControl/AccessControlModule/type - Format: string - Default value: none - Required: false @@ -4749,7 +3917,7 @@ Authentication authorization shall be performed. Enabling Authentication requires that a cipher, including RSA (such as rsa-aes256), is used. -- Full path: //OpenSplice/SNetworkService/Security/Authentication +- Full path: /SNetworkService/Security/Authentication - Occurrences min-max: 0-1 - Optional attributes: enabled @@ -4758,7 +3926,7 @@ enabled Authentication is performed when enabled is set to true. -- Full path: //OpenSplice/SNetworkService/Security/Authentication[@enabled] +- Full path: /SNetworkService/Security/Authentication/enabled - Format: boolean - Default value: true - Required: false @@ -4769,7 +3937,7 @@ X509Authentication The X509Authentication element defines where keys and certificates required for X509 authentication may be found. -- Full path: //OpenSplice/SNetworkService/Security/Authentication/X509Authentication +- Full path: /SNetworkService/Security/Authentication/X509Authentication - Occurrences min-max: 0-1 - Child elements: TrustedCertificates @@ -4779,7 +3947,7 @@ Credentials The Credentials element is an optional element. If it is missing, then the node does not sign messages (in other words, does not send credentials). -- Full path: //OpenSplice/SNetworkService/Security/Authentication/X509Authentication/Credentials +- Full path: /SNetworkService/Security/Authentication/X509Authentication/Credentials - Occurrences min-max: 0-1 - Child elements: Key, Cert @@ -4792,7 +3960,7 @@ Key will be interpreted relative to the directory from which the OpenSplice daemon is started. -- Full path: //OpenSplice/SNetworkService/Security/Authentication/X509Authentication/Credentials/Key +- Full path: /SNetworkService/Security/Authentication/X509Authentication/Credentials/Key - Format: string - Occurrences min-max: 1-1 @@ -4805,7 +3973,7 @@ Cert will be interpreted relative to the directory from which the OpenSplice daemon is started. -- Full path: //OpenSplice/SNetworkService/Security/Authentication/X509Authentication/Credentials/Cert +- Full path: /SNetworkService/Security/Authentication/X509Authentication/Credentials/Cert - Format: string - Occurrences min-max: 1-1 @@ -4818,7 +3986,7 @@ TrustedCertificates will be interpreted relative to the directory from which the OpenSplice daemon is started. -- Full path: //OpenSplice/SNetworkService/Security/Authentication/X509Authentication/TrustedCertificates +- Full path: /SNetworkService/Security/Authentication/X509Authentication/TrustedCertificates - Format: string - Occurrences min-max: 1-1 @@ -4834,7 +4002,7 @@ Channels application-defined DDS QoS policies of the data to select the most appropriate channel to send the data. -- Full path: //OpenSplice/SNetworkService/Channels +- Full path: /SNetworkService/Channels - Occurrences min-max: 1-1 - Child elements: AllowedPorts @@ -4850,7 +4018,7 @@ Channel performance depends heavily on the compatbility of the configured channels with the used DDS QoS policies of the applications. -- Full path: //OpenSplice/SNetworkService/Channels/Channel +- Full path: /SNetworkService/Channels/Channel - Occurrences min-max: 1-42 - Child elements: PortNr, FragmentSize, Resolution, AdminQueueSize, CompressionBufferSize, CompressionThreshold, AllowedPorts - Required attributes: name, reliable, enabled @@ -4861,7 +4029,7 @@ name The name uniquely identifies the channel. -- Full path: //OpenSplice/SNetworkService/Channels/Channel[@name] +- Full path: /SNetworkService/Channels/Channel/name - Format: string - Default value: aChannel - Required: true @@ -4878,7 +4046,7 @@ reliable reliable attribute happens to be set to true, the message will be sent over the network using a reliability protocol. -- Full path: //OpenSplice/SNetworkService/Channels/Channel[@reliable] +- Full path: /SNetworkService/Channels/Channel/reliable - Format: boolean - Default value: false - Required: true @@ -4900,7 +4068,7 @@ default Note that only one channel is allowed to have this attribute set to true -- Full path: //OpenSplice/SNetworkService/Channels/Channel[@default] +- Full path: /SNetworkService/Channels/Channel/default - Format: boolean - Default value: false - Required: false @@ -4913,7 +4081,7 @@ enabled for commenting out the corresponding lines in the configuration file. -- Full path: //OpenSplice/SNetworkService/Channels/Channel[@enabled] +- Full path: /SNetworkService/Channels/Channel/enabled - Format: boolean - Default value: false - Required: true @@ -4930,7 +4098,7 @@ priority into intervals. Within a channel, messages are sorted in order of priority. -- Full path: //OpenSplice/SNetworkService/Channels/Channel[@priority] +- Full path: /SNetworkService/Channels/Channel/priority - Format: integer - Default value: 0 - Required: false @@ -4944,10 +4112,9 @@ PortNr that 'reliable' channels use a second port, which is the specified PortNr + 1. -- Full path: //OpenSplice/SNetworkService/Channels/Channel/PortNr +- Full path: /SNetworkService/Channels/Channel/PortNr - Format: integer - Default value: 53400 -- Valid values: 1 / 65535 - Occurrences min-max: 1-1 FragmentSize @@ -4957,14 +4124,9 @@ FragmentSize fragments with size **FragmentSize**. These fragments are sent as datagrams to the UDP stack. OS-settings determine the maximum datagram size. - The human-readable option lets the user postfix the value with K(ilobyte), - M(egabyte) or G(igabtye). For example, 10M results in 10485760 bytes. -- Full path: //OpenSplice/SNetworkService/Channels/Channel/FragmentSize -- Format: unsigned int -- Dimension: bytes +- Full path: /SNetworkService/Channels/Channel/FragmentSize - Default value: 1300 -- Valid values: 200 / 65535 - Occurrences min-max: 0-1 Resolution @@ -4978,11 +4140,9 @@ Resolution It is considered good practice to specify the ThrottleTreshold consistently throughout the system. -- Full path: //OpenSplice/SNetworkService/Channels/Channel/Resolution -- Format: unsigned int -- Dimension: milliseconds +- Full path: /SNetworkService/Channels/Channel/Resolution +- Format: integer - Default value: 10 -- Valid values: 1 / - - Occurrences min-max: 0-1 AdminQueueSize @@ -4995,10 +4155,9 @@ AdminQueueSize size of this queue, and it must be greater than the maximum number of reliable messages send or received during each "Resolution" milliseconds. -- Full path: //OpenSplice/SNetworkService/Channels/Channel/AdminQueueSize +- Full path: /SNetworkService/Channels/Channel/AdminQueueSize - Format: integer - Default value: 4000 -- Valid values: 400 / - - Occurrences min-max: 0-1 CompressionBufferSize @@ -5010,10 +4169,9 @@ CompressionBufferSize the received compressed messages. Note that the actual size of these buffers may be increased when needed. -- Full path: //OpenSplice/SNetworkService/Channels/Channel/CompressionBufferSize +- Full path: /SNetworkService/Channels/Channel/CompressionBufferSize - Format: integer - Default value: 131072 -- Valid values: 65536 / - - Occurrences min-max: 0-1 CompressionThreshold @@ -5023,10 +4181,9 @@ CompressionThreshold to start compressing the accumulated data and sending the compressed data on the network. The CompressionThreshold is used to estimate the size of the compressed messages. -- Full path: //OpenSplice/SNetworkService/Channels/Channel/CompressionThreshold +- Full path: /SNetworkService/Channels/Channel/CompressionThreshold - Format: integer - Default value: 0 -- Valid values: 0 / - - Occurrences min-max: 0-1 Sending @@ -5035,7 +4192,7 @@ Sending This element describes all properties for the transmitting side of the Channel. -- Full path: //OpenSplice/SNetworkService/Channels/Channel/Sending +- Full path: /SNetworkService/Channels/Channel/Sending - Occurrences min-max: 0-1 - Child elements: CrcCheck, QueueSize, MaxBurstSize, ThrottleLimit, ThrottleThreshold, MaxRetries, RecoveryFactor, DiffServField, DontRoute, TimeToLive @@ -5049,7 +4206,7 @@ CrcCheck When the sending side is enabled the network packet will contain a valid crc field. -- Full path: //OpenSplice/SNetworkService/Channels/Channel/Sending/CrcCheck +- Full path: /SNetworkService/Channels/Channel/Sending/CrcCheck - Format: boolean - Default value: false - Occurrences min-max: 0-1 @@ -5065,10 +4222,9 @@ QueueSize and will retry until success. Note that a full networking queue is a symptom of an improperly designed system. -- Full path: //OpenSplice/SNetworkService/Channels/Channel/Sending/QueueSize +- Full path: /SNetworkService/Channels/Channel/Sending/QueueSize - Format: integer - Default value: 400 -- Valid values: 1 / - - Occurrences min-max: 0-1 MaxBurstSize @@ -5077,13 +4233,9 @@ MaxBurstSize Amount in bytes to be sent at maximum every "Resolution" milliseconds. The default value is set to 1GB per resolution tick. This can be considered "unlimited" as this far exceeds the capacity of modern physical networks. - The human-readable option lets the user postfix the value with K(ilobyte), - M(egabyte) or G(igabtye). For example, 10M results in 10485760 bytes -- Full path: //OpenSplice/SNetworkService/Channels/Channel/Sending/MaxBurstSize -- Dimension: bytes/(resolution interval) +- Full path: /SNetworkService/Channels/Channel/Sending/MaxBurstSize - Default value: 1073741823 -- Valid values: 1024 / 1073741823 - Occurrences min-max: 0-1 ThrottleLimit @@ -5096,13 +4248,9 @@ ThrottleLimit value (or higher) as MaxBurstSize throttling is disabled. The ThrottleLimit value is not allowed be smaller than the FragmentSize. If a lower value is provided, then the value of FragmentSize is used as ThrottleLimit. - The human-readable option lets the user postfix the value with K(ilobyte), - M(egabyte) or G(igabtye). For example, 10K results in 10240 bytes -- Full path: //OpenSplice/SNetworkService/Channels/Channel/Sending/ThrottleLimit -- Dimension: bytes/(resolution interval) +- Full path: /SNetworkService/Channels/Channel/Sending/ThrottleLimit - Default value: 10240 -- Valid values: - / 4294967295 - Occurrences min-max: 0-1 ThrottleThreshold @@ -5116,45 +4264,29 @@ ThrottleThreshold It is considered good practice to specify the ThrottleTreshold consistently throughout the system. -- Full path: //OpenSplice/SNetworkService/Channels/Channel/Sending/ThrottleThreshold +- Full path: /SNetworkService/Channels/Channel/Sending/ThrottleThreshold - Format: integer -- Dimension: fragments - Default value: 50 -- Valid values: 2 / - - Occurrences min-max: 0-1 MaxRetries ~~~~~~~~~~ -This element is only applicable for reliable channels. -A reliable channel implements a reliability protocol in which it builds a list of -connected remote services. This protocol expects all connected services to -acknowledge messages within a specific period of time, otherwise messages will be -resent. This element specifies the number of retransmissions the service has to -execute before considering that the addressed service has become unresponsive. -When this happens the remote service will be removed from the reliability protocol -and the channel will no longer expect messages to be acknowledged. + The number of retransmissions the service has to execute before considering the addressed node + as not responding. -- Full path: //OpenSplice/SNetworkService/Channels/Channel/Sending/MaxRetries +- Full path: /SNetworkService/Channels/Channel/Sending/MaxRetries - Format: integer - Default value: 100 -- Valid values: 1 / - - Occurrences min-max: 0-1 RecoveryFactor ~~~~~~~~~~~~~~ +A lost message is resent after Resolution * RecoveryFactor milliseconds. -A reliable channel implements a reliability protocol in which it builds a list of -connected remote services. This protocol expects all connected services to -acknowledge messages within a specific period of time otherwise messages will be -resent. The expected period of time is specified by this attribute as the number of -resolution ticks. (See also Section 4.4.1.5.1.9, Element Resolution, on page 218.) -The lost message is resent after Resolution \* RecoveryFactor milliseconds. - -- Full path: //OpenSplice/SNetworkService/Channels/Channel/Sending/RecoveryFactor +- Full path: /SNetworkService/Channels/Channel/Sending/RecoveryFactor - Format: integer - Default value: 3 -- Valid values: 2 / - - Occurrences min-max: 0-1 DiffServField @@ -5185,10 +4317,9 @@ DiffServField 1-8 background traffic; 9-40 excellent traffic; 41-55 audio/video traffic; 56 voice traffic; 57-63 control traffic. When OpenSplice is run without Administrative priveleges then only the diffserv value of 0, 8, 40 or 56 is allowed. -- Full path: //OpenSplice/SNetworkService/Channels/Channel/Sending/DiffServField +- Full path: /SNetworkService/Channels/Channel/Sending/DiffServField - Format: integer - Default value: 0 -- Valid values: 0 / 255 - Occurrences min-max: 0-1 DontRoute @@ -5196,7 +4327,7 @@ DontRoute The IP DONTROUTE socket option is set to the value specified. -- Full path: //OpenSplice/SNetworkService/Channels/Channel/Sending/DontRoute +- Full path: /SNetworkService/Channels/Channel/Sending/DontRoute - Format: boolean - Default value: True - Valid values: True, False @@ -5207,10 +4338,9 @@ TimeToLive For each UDP packet sent out, the IP Time To Live header value is set to the value specified. -- Full path: //OpenSplice/SNetworkService/Channels/Channel/Sending/TimeToLive +- Full path: /SNetworkService/Channels/Channel/Sending/TimeToLive - Format: integer - Default value: 0 -- Valid values: 0 / 255 - Occurrences min-max: 0-1 Scheduling @@ -5219,7 +4349,7 @@ Scheduling This element specifies the scheduling policies used to control the transmitter thread of the current Channel. -- Full path: //OpenSplice/SNetworkService/Channels/Channel/Sending/Scheduling +- Full path: /SNetworkService/Channels/Channel/Sending/Scheduling - Occurrences min-max: 0-1 - Child elements: Priority, Class @@ -5231,7 +4361,7 @@ Priority can be assigned to this element. The user may need special privileges from the underlying operating system to be able to assign some of the privileged priorities. -- Full path: //OpenSplice/SNetworkService/Channels/Channel/Sending/Scheduling/Priority +- Full path: /SNetworkService/Channels/Channel/Sending/Scheduling/Priority - Format: integer - Default value: 0 - Occurrences min-max: 1-1 @@ -5243,7 +4373,7 @@ priority_kind This attribute specifies whether the specified *Priority* is a relative or absolute priority. -- Full path: //OpenSplice/SNetworkService/Channels/Channel/Sending/Scheduling/Priority[@priority_kind] +- Full path: /SNetworkService/Channels/Channel/Sending/Scheduling/Priority/priority_kind - Format: enumeration - Default value: Relative - Valid values: Relative, Absolute @@ -5256,7 +4386,7 @@ Class thread. The user may need the appropriate privileges from the underlying operating system to be able to assign some of the privileged scheduling classes. -- Full path: //OpenSplice/SNetworkService/Channels/Channel/Sending/Scheduling/Class +- Full path: /SNetworkService/Channels/Channel/Sending/Scheduling/Class - Format: enumeration - Default value: Default - Valid values: Timeshare, Realtime, Default @@ -5268,7 +4398,7 @@ Receiving This element describes all properties for the receiving side of the Channel. -- Full path: //OpenSplice/SNetworkService/Channels/Channel/Receiving +- Full path: /SNetworkService/Channels/Channel/Receiving - Occurrences min-max: 0-1 - Child elements: CrcCheck, ReceiveBufferSize, DefragBufferSize, MaxReliabBacklog, PacketRetentionPeriod, ReliabilityRecoveryPeriod @@ -5282,7 +4412,7 @@ CrcCheck When the receiving side is enabled only network packets that contain a valid crc field are accepted. -- Full path: //OpenSplice/SNetworkService/Channels/Channel/Receiving/CrcCheck +- Full path: /SNetworkService/Channels/Channel/Receiving/CrcCheck - Format: boolean - Default value: false - Occurrences min-max: 0-1 @@ -5293,12 +4423,9 @@ ReceiveBufferSize The UDP receive buffer of the best effort channel socket is set to the value given. If many message are lost, the receive buffer size has to be increased. - The human-readable option lets the user postfix the value with K(ilobyte), - M(egabyte) or G(igabtye). For example, 10M results in 10485760 bytes. -- Full path: //OpenSplice/SNetworkService/Channels/Channel/Receiving/ReceiveBufferSize +- Full path: /SNetworkService/Channels/Channel/Receiving/ReceiveBufferSize - Default value: 1000000 -- Valid values: 1024 / - - Occurrences min-max: 0-1 Scheduling @@ -5307,7 +4434,7 @@ Scheduling This element specifies the scheduling policies used to control the receiver thread of the current Channel. -- Full path: //OpenSplice/SNetworkService/Channels/Channel/Receiving/Scheduling +- Full path: /SNetworkService/Channels/Channel/Receiving/Scheduling - Occurrences min-max: 0-1 - Child elements: Priority, Class @@ -5320,7 +4447,7 @@ Priority the underlying operating system to be able to assign some of the privileged priorities. -- Full path: //OpenSplice/SNetworkService/Channels/Channel/Receiving/Scheduling/Priority +- Full path: /SNetworkService/Channels/Channel/Receiving/Scheduling/Priority - Format: integer - Default value: 0 - Occurrences min-max: 1-1 @@ -5332,7 +4459,7 @@ priority_kind This attribute specifies whether the specified *Priority* is a relative or absolute priority. -- Full path: //OpenSplice/SNetworkService/Channels/Channel/Receiving/Scheduling/Priority[@priority_kind] +- Full path: /SNetworkService/Channels/Channel/Receiving/Scheduling/Priority/priority_kind - Format: enumeration - Default value: Relative - Valid values: Relative, Absolute @@ -5345,7 +4472,7 @@ Class thread. The user may need the appropriate privileges from the underlying operating system to be able to assign some of the privileged scheduling classes. -- Full path: //OpenSplice/SNetworkService/Channels/Channel/Receiving/Scheduling/Class +- Full path: /SNetworkService/Channels/Channel/Receiving/Scheduling/Class - Format: enumeration - Default value: Default - Valid values: Timeshare, Realtime, Default @@ -5357,13 +4484,9 @@ DefragBufferSize The maximum number of Fragment buffers that will be allocated for this channel. These buffers are used to store incoming fragments waiting to be processed, as well as fragments that are being processed. - With respect to very large messages be aware that the number of buffers times the - fragment size must be sufficient to process the messages otherwise they will be - dropped. (See also Element FragmentSize) -- Full path: //OpenSplice/SNetworkService/Channels/Channel/Receiving/DefragBufferSize +- Full path: /SNetworkService/Channels/Channel/Receiving/DefragBufferSize - Default value: 5000 -- Valid values: 500 / - - Occurrences min-max: 0-1 SMPOptimization @@ -5372,7 +4495,7 @@ SMPOptimization This option will distribute the processing done for incoming fragements over multiple threads, which will lead to an improved throughput on SMP nodes. -- Full path: //OpenSplice/SNetworkService/Channels/Channel/Receiving/SMPOptimization +- Full path: /SNetworkService/Channels/Channel/Receiving/SMPOptimization - Occurrences min-max: 0-1 - Required attributes: enabled @@ -5381,7 +4504,7 @@ enabled This attribute toggles the Optimization on or off. -- Full path: //OpenSplice/SNetworkService/Channels/Channel/Receiving/SMPOptimization[@enabled] +- Full path: /SNetworkService/Channels/Channel/Receiving/SMPOptimization/enabled - Format: boolean - Default value: true - Required: true @@ -5389,17 +4512,14 @@ enabled MaxReliabBacklog ~~~~~~~~~~~~~~~~ -This element specifies the maximum number of received fragments maintained in -the channel from a single sender for the purpose of order preservation because an -earlier fragment from that sender is missing. A sender is disconnected and all -maintained fragments are discarded when this number is exceeded. Future -fragments from this sender are only accepted after a disconnect if reconnection is set -to true (see Element Reconnection). + This is a lower limit to the DefragBufferSize that specifies the number of received fragments + from a single remote node allocated for the purpose of order preservation because an earlier + fragment from that remote node is missing. If this number is exceeded, then that particular + remote node that didn't resend the missing fragent in time is considered dead for this channel. -- Full path: //OpenSplice/SNetworkService/Channels/Channel/Receiving/MaxReliabBacklog +- Full path: /SNetworkService/Channels/Channel/Receiving/MaxReliabBacklog - Format: integer - Default value: 1000 -- Valid values: 100 / - - Occurrences min-max: 0-1 PacketRetentionPeriod @@ -5418,10 +4538,9 @@ PacketRetentionPeriod exceeds the worst-case death-detection time as configured for the discovery protocol of the set of distributed networking services in the system. -- Full path: //OpenSplice/SNetworkService/Channels/Channel/Receiving/PacketRetentionPeriod +- Full path: /SNetworkService/Channels/Channel/Receiving/PacketRetentionPeriod - Format: integer - Default value: 0 -- Valid values: 0 / - - Occurrences min-max: 0-1 ReliabilityRecoveryPeriod @@ -5436,10 +4555,9 @@ ReliabilityRecoveryPeriod for the worst-case alignment-time of any "missed" data by individual receiving nodes following the disappearance of a sending node in the system. -- Full path: //OpenSplice/SNetworkService/Channels/Channel/Receiving/ReliabilityRecoveryPeriod +- Full path: /SNetworkService/Channels/Channel/Receiving/ReliabilityRecoveryPeriod - Format: integer - Default value: 1000 -- Valid values: 0 / - - Occurrences min-max: 0-1 AllowedPorts @@ -5459,7 +4577,7 @@ AllowedPorts comma (,). A port number range consists of the lower and the upper bound of the port number range, where the lower and the upper bound are seperated by a minus (-). -- Full path: //OpenSplice/SNetworkService/Channels/Channel/AllowedPorts +- Full path: /SNetworkService/Channels/Channel/AllowedPorts - Format: string - Occurrences min-max: 0-1 @@ -5480,7 +4598,7 @@ AllowedPorts comma (,). A port number range consists of the lower and the upper bound of the port number range, where the lower and the upper bound are seperated by a minus (-). -- Full path: //OpenSplice/SNetworkService/Channels/AllowedPorts +- Full path: /SNetworkService/Channels/AllowedPorts - Format: string - Occurrences min-max: 0-1 @@ -5495,7 +4613,7 @@ Discovery can be dynamically expanded and maintained by the dynamic-discovery process driven by the node's Role and Scope. -- Full path: //OpenSplice/SNetworkService/Discovery +- Full path: /SNetworkService/Discovery - Occurrences min-max: 0-1 - Child elements: PortNr, ProbeList - Optional attributes: enabled, Scope @@ -5507,7 +4625,7 @@ enabled Channel is disabled, entities will only detect each others presence implicitly once messages are received for the first time. -- Full path: //OpenSplice/SNetworkService/Discovery[@enabled] +- Full path: /SNetworkService/Discovery/enabled - Format: boolean - Default value: true - Occurrences min-max: 0-1 @@ -5526,7 +4644,7 @@ Scope considered a match and will become part of the communication reach (i.e. the Global Partition) of the current domain. -- Full path: //OpenSplice/SNetworkService/Discovery[@Scope] +- Full path: /SNetworkService/Discovery/Scope - Format: string - Occurrences min-max: 0-1 - Required: false @@ -5536,10 +4654,9 @@ PortNr This element specifies the Port number used by the Discovery Channel. -- Full path: //OpenSplice/SNetworkService/Discovery/PortNr +- Full path: /SNetworkService/Discovery/PortNr - Format: integer - Default value: 3369 -- Valid values: 1 / 65536 - Occurrences min-max: 1-1 ProbeList @@ -5551,7 +4668,7 @@ ProbeList The addresses can be entered as dotted decimal notation or as the symbolic hostname, in which case the middleware will try to resolve the corresponding IP address. -- Full path: //OpenSplice/SNetworkService/Discovery/ProbeList +- Full path: /SNetworkService/Discovery/ProbeList - Format: string - Occurrences min-max: 0-1 @@ -5561,7 +4678,7 @@ Sending This element describes all properties for the transmitting side of the Discovery Channel. -- Full path: //OpenSplice/SNetworkService/Discovery/Sending +- Full path: /SNetworkService/Discovery/Sending - Occurrences min-max: 0-1 - Child elements: CrcCheck, DiffServField, DontRoute, TimeToLive, Interval, SafetyFactor, SalvoSize @@ -5575,7 +4692,7 @@ CrcCheck When the sending side is enabled the network packet will contain a valid crc field. -- Full path: //OpenSplice/SNetworkService/Discovery/Sending/CrcCheck +- Full path: /SNetworkService/Discovery/Sending/CrcCheck - Format: boolean - Default value: false - Occurrences min-max: 0-1 @@ -5608,10 +4725,9 @@ DiffServField 1-8 background traffic; 9-40 excellent traffic; 41-55 audio/video traffic; 56 voice traffic; 57-63 control traffic. When OpenSplice is run without Administrative priveleges then only the diffserv value of 0, 8, 40 or 56 is allowed. -- Full path: //OpenSplice/SNetworkService/Discovery/Sending/DiffServField +- Full path: /SNetworkService/Discovery/Sending/DiffServField - Format: integer - Default value: 0 -- Valid values: 0 / 255 - Occurrences min-max: 0-1 DontRoute @@ -5619,7 +4735,7 @@ DontRoute The IP DONTROUTE socket option is set to the value specified. -- Full path: //OpenSplice/SNetworkService/Discovery/Sending/DontRoute +- Full path: /SNetworkService/Discovery/Sending/DontRoute - Format: boolean - Default value: True - Valid values: True, False @@ -5630,10 +4746,9 @@ TimeToLive For each UDP packet sent out, the IP Time To Live header value is set to the value specified. -- Full path: //OpenSplice/SNetworkService/Discovery/Sending/TimeToLive +- Full path: /SNetworkService/Discovery/Sending/TimeToLive - Format: integer - Default value: 0 -- Valid values: 0 / 255 - Occurrences min-max: 0-1 Scheduling @@ -5642,7 +4757,7 @@ Scheduling This element specifies the scheduling policies used to control the transmitter thread of the Discovery Channel. -- Full path: //OpenSplice/SNetworkService/Discovery/Sending/Scheduling +- Full path: /SNetworkService/Discovery/Sending/Scheduling - Occurrences min-max: 0-1 - Child elements: Priority, Class @@ -5654,7 +4769,7 @@ Priority system can be assigned to this element. The user may need special privileges from the underlying operating system to be able to assign some of the privileged priorities. -- Full path: //OpenSplice/SNetworkService/Discovery/Sending/Scheduling/Priority +- Full path: /SNetworkService/Discovery/Sending/Scheduling/Priority - Format: integer - Default value: 0 - Occurrences min-max: 1-1 @@ -5666,7 +4781,7 @@ priority_kind This attribute specifies whether the specified *Priority* is a relative or absolute priority. -- Full path: //OpenSplice/SNetworkService/Discovery/Sending/Scheduling/Priority[@priority_kind] +- Full path: /SNetworkService/Discovery/Sending/Scheduling/Priority/priority_kind - Format: enumeration - Default value: Relative - Valid values: Relative, Absolute @@ -5679,7 +4794,7 @@ Class thread of the Discovery Channel. The user may need the appropriate privileges from the underlying operating system to be able to assign some of the privileged scheduling classes. -- Full path: //OpenSplice/SNetworkService/Discovery/Sending/Scheduling/Class +- Full path: /SNetworkService/Discovery/Sending/Scheduling/Class - Format: enumeration - Default value: Default - Valid values: Timeshare, Realtime, Default @@ -5690,10 +4805,9 @@ Interval This element describes the interval(in milliseconds) at which remote nodes will expect heartbeats from this node. -- Full path: //OpenSplice/SNetworkService/Discovery/Sending/Interval +- Full path: /SNetworkService/Discovery/Sending/Interval - Format: integer - Default value: 333 -- Valid values: 10 / - - Occurrences min-max: 0-1 SafetyFactor @@ -5701,9 +4815,8 @@ SafetyFactor The SafetyFactor is used to set a margin on the discovery sending. This avoids tight timing issues. -- Full path: //OpenSplice/SNetworkService/Discovery/Sending/SafetyFactor +- Full path: /SNetworkService/Discovery/Sending/SafetyFactor - Default value: 0.9 -- Valid values: 0.2 / 1.0 - Occurrences min-max: 0-1 SalvoSize @@ -5712,10 +4825,9 @@ SalvoSize During starting and stopping, discovery messages are sent at higher frequency. This SalvoSize sets the number of messages to send during these phases. -- Full path: //OpenSplice/SNetworkService/Discovery/Sending/SalvoSize +- Full path: /SNetworkService/Discovery/Sending/SalvoSize - Format: integer - Default value: 3 -- Valid values: 1 / - - Occurrences min-max: 0-1 Receiving @@ -5724,7 +4836,7 @@ Receiving This element describes all properties for the receiving side of the Discovery Channel. -- Full path: //OpenSplice/SNetworkService/Discovery/Receiving +- Full path: /SNetworkService/Discovery/Receiving - Occurrences min-max: 0-1 - Child elements: CrcCheck, DeathDetectionCount, ReceiveBufferSize @@ -5738,7 +4850,7 @@ CrcCheck When the sending side is enabled the network packet will contain a valid crc field. -- Full path: //OpenSplice/SNetworkService/Discovery/Receiving/CrcCheck +- Full path: /SNetworkService/Discovery/Receiving/CrcCheck - Format: boolean - Default value: false - Occurrences min-max: 0-1 @@ -5749,7 +4861,7 @@ Scheduling This element specifies the scheduling policies used to control the receiver thread of the Discovery Channel. -- Full path: //OpenSplice/SNetworkService/Discovery/Receiving/Scheduling +- Full path: /SNetworkService/Discovery/Receiving/Scheduling - Occurrences min-max: 0-1 - Child elements: Priority, Class @@ -5761,7 +4873,7 @@ Priority system can be assigned to this element. The user may need special privileges from the underlying operating system to be able to assign some of the privileged priorities. -- Full path: //OpenSplice/SNetworkService/Discovery/Receiving/Scheduling/Priority +- Full path: /SNetworkService/Discovery/Receiving/Scheduling/Priority - Format: integer - Default value: 0 - Occurrences min-max: 1-1 @@ -5773,7 +4885,7 @@ priority_kind This attribute specifies whether the specified *Priority* is a relative or absolute priority. -- Full path: //OpenSplice/SNetworkService/Discovery/Receiving/Scheduling/Priority[@priority_kind] +- Full path: /SNetworkService/Discovery/Receiving/Scheduling/Priority/priority_kind - Format: enumeration - Default value: Relative - Valid values: Relative, Absolute @@ -5786,7 +4898,7 @@ Class thread of the Discovery Channel. The user may need the appropriate privileges from the underlying operating system to be able to assign some of the privileged scheduling classes. -- Full path: //OpenSplice/SNetworkService/Discovery/Receiving/Scheduling/Class +- Full path: /SNetworkService/Discovery/Receiving/Scheduling/Class - Format: enumeration - Default value: Default - Valid values: Timeshare, Realtime, Default @@ -5798,10 +4910,9 @@ DeathDetectionCount This element specifies how often a heartbeat from a remote node must miss its Interval before that remote node is considered dead. -- Full path: //OpenSplice/SNetworkService/Discovery/Receiving/DeathDetectionCount +- Full path: /SNetworkService/Discovery/Receiving/DeathDetectionCount - Format: integer - Default value: 6 -- Valid values: 1 / - - Occurrences min-max: 0-1 ReceiveBufferSize @@ -5810,9 +4921,8 @@ ReceiveBufferSize The UDP receive buffer of the Discovery Channel socket is set to the value given. If many message are lost, the receive buffer size has to be increased. -- Full path: //OpenSplice/SNetworkService/Discovery/Receiving/ReceiveBufferSize +- Full path: /SNetworkService/Discovery/Receiving/ReceiveBufferSize - Default value: 1000000 -- Valid values: 1 / - - Occurrences min-max: 0-1 Tracing @@ -5822,20 +4932,9 @@ Tracing tracing log by the Networking Service. This is useful to track the Networking Service during application development. In the runtime system it should be turned off. -- Full path: //OpenSplice/SNetworkService/Tracing +- Full path: /SNetworkService/Tracing - Occurrences min-max: 0-1 - Child elements: OutputFile, Timestamps -- Optional attributes: enabled - -enabled -------- - - This attribute controls whether the tracing option is enabled or not. - -- Full path: //OpenSplice/SNetworkService/Tracing[@enabled] -- Format: boolean -- Default value: true -- Required: false OutputFile ---------- @@ -5844,7 +4943,7 @@ OutputFile legal value that represents "standard out". The default value is an empty string, indicating that the tracing log will be written to standard out. -- Full path: //OpenSplice/SNetworkService/Tracing/OutputFile +- Full path: /SNetworkService/Tracing/OutputFile - Format: string - Default value: networking.log - Occurrences min-max: 1-1 @@ -5854,10 +4953,10 @@ Timestamps This element specifies whether the logging must contain timestamps. -- Full path: //OpenSplice/SNetworkService/Tracing/Timestamps +- Full path: /SNetworkService/Tracing/Timestamps - Format: boolean - Default value: true -- Occurrences min-max: 0-1 +- Occurrences min-max: 1-1 - Optional attributes: absolute absolute @@ -5866,7 +4965,7 @@ absolute This attribute specifies whether the timestamps are absolute or relative to the startup time of the service. -- Full path: //OpenSplice/SNetworkService/Tracing/Timestamps[@absolute] +- Full path: /SNetworkService/Tracing/Timestamps/absolute - Format: boolean - Default value: true - Required: false @@ -5876,7 +4975,7 @@ Categories This element contains the logging properties for various networking categories. -- Full path: //OpenSplice/SNetworkService/Tracing/Categories +- Full path: /SNetworkService/Tracing/Categories - Occurrences min-max: 1-1 - Child elements: Default, Configuration, Construction, Destruction, Mainloop, Groups, Send, Receive, Throttling, Test, Discovery @@ -5887,11 +4986,10 @@ Default explicitly specified. Level 0 indicates no tracing, level 6 indicates the most detailed level of tracing. -- Full path: //OpenSplice/SNetworkService/Tracing/Categories/Default +- Full path: /SNetworkService/Tracing/Categories/Default - Format: integer - Default value: 0 -- Valid values: 0 / 6 -- Occurrences min-max: 0-1 +- Occurrences min-max: 1-1 Configuration ^^^^^^^^^^^^^ @@ -5901,10 +4999,9 @@ Configuration Level 0 indicates no tracing, level 6 indicates the most detailed level of tracing. -- Full path: //OpenSplice/SNetworkService/Tracing/Categories/Configuration +- Full path: /SNetworkService/Tracing/Categories/Configuration - Format: integer - Default value: 0 -- Valid values: 0 / 6 - Occurrences min-max: 0-1 Construction @@ -5915,10 +5012,9 @@ Construction Level 0 indicates no tracing, level 6 indicates the most detailed level of tracing. -- Full path: //OpenSplice/SNetworkService/Tracing/Categories/Construction +- Full path: /SNetworkService/Tracing/Categories/Construction - Format: integer - Default value: 0 -- Valid values: 0 / 6 - Occurrences min-max: 0-1 Destruction @@ -5929,10 +5025,9 @@ Destruction NetworkService terminates. Level 0 indicates no tracing, level 6 indicates the most detailed level of tracing. -- Full path: //OpenSplice/SNetworkService/Tracing/Categories/Destruction +- Full path: /SNetworkService/Tracing/Categories/Destruction - Format: integer - Default value: 0 -- Valid values: 0 / 6 - Occurrences min-max: 0-1 Mainloop @@ -5943,10 +5038,9 @@ Mainloop Level 0 indicates no tracing, level 6 indicates the most detailed level of tracing. -- Full path: //OpenSplice/SNetworkService/Tracing/Categories/Mainloop +- Full path: /SNetworkService/Tracing/Categories/Mainloop - Format: integer - Default value: 0 -- Valid values: 0 / 6 - Occurrences min-max: 0-1 Groups @@ -5957,10 +5051,9 @@ Groups Level 0 indicates no tracing, level 6 indicates the most detailed level of tracing. -- Full path: //OpenSplice/SNetworkService/Tracing/Categories/Groups +- Full path: /SNetworkService/Tracing/Categories/Groups - Format: integer - Default value: 0 -- Valid values: 0 / 6 - Occurrences min-max: 0-1 Send @@ -5971,10 +5064,9 @@ Send Level 0 indicates no tracing, level 6 indicates the most detailed level of tracing. -- Full path: //OpenSplice/SNetworkService/Tracing/Categories/Send +- Full path: /SNetworkService/Tracing/Categories/Send - Format: integer - Default value: 0 -- Valid values: 0 / 6 - Occurrences min-max: 0-1 Receive @@ -5985,10 +5077,9 @@ Receive Level 0 indicates no tracing, level 6 indicates the most detailed level of tracing. -- Full path: //OpenSplice/SNetworkService/Tracing/Categories/Receive +- Full path: /SNetworkService/Tracing/Categories/Receive - Format: integer - Default value: 0 -- Valid values: 0 / 6 - Occurrences min-max: 0-1 Throttling @@ -5999,10 +5090,9 @@ Throttling Level 0 indicates no tracing, level 6 indicates the most detailed level of tracing. -- Full path: //OpenSplice/SNetworkService/Tracing/Categories/Throttling +- Full path: /SNetworkService/Tracing/Categories/Throttling - Format: integer - Default value: 0 -- Valid values: 0 / 6 - Occurrences min-max: 0-1 Test @@ -6013,10 +5103,9 @@ Test Level 0 indicates no tracing, level 6 indicates the most detailed level of tracing. -- Full path: //OpenSplice/SNetworkService/Tracing/Categories/Test +- Full path: /SNetworkService/Tracing/Categories/Test - Format: integer - Default value: 0 -- Valid values: 0 / 6 - Occurrences min-max: 0-1 Discovery @@ -6027,10 +5116,9 @@ Discovery Level 0 indicates no tracing, level 6 indicates the most detailed level of tracing. -- Full path: //OpenSplice/SNetworkService/Tracing/Categories/Discovery +- Full path: /SNetworkService/Tracing/Categories/Discovery - Format: integer - Default value: 0 -- Valid values: 0 / 6 - Occurrences min-max: 0-1 Compression @@ -6047,7 +5135,7 @@ Compression It is imperative that all nodes exchanging compressed data have the same configuration in this section. -- Full path: //OpenSplice/SNetworkService/Compression +- Full path: /SNetworkService/Compression - Occurrences min-max: 0-1 - Optional attributes: PluginLibrary, PluginInitFunction, PluginParameter @@ -6059,7 +5147,7 @@ PluginLibrary the network data. This may be left blank for the built-in compressors. -- Full path: //OpenSplice/SNetworkService/Compression[@PluginLibrary] +- Full path: /SNetworkService/Compression/PluginLibrary - Format: string - Default value: "" - Required: false @@ -6073,7 +5161,7 @@ PluginInitFunction ospl_comp_lzf_init and ospl_comp_snappy_init but for convenience they may be specified here as as zlib, lzf or snappy. -- Full path: //OpenSplice/SNetworkService/Compression[@PluginInitFunction] +- Full path: /SNetworkService/Compression/PluginInitFunction - Format: string - Default value: "" - Required: false @@ -6087,7 +5175,7 @@ PluginParameter the zlib compressor is configured with an integer between 0 (for no compression) to 9 (for maximum compression). -- Full path: //OpenSplice/SNetworkService/Compression[@PluginParameter] +- Full path: /SNetworkService/Compression/PluginParameter - Format: string - Default value: "" - Required: false @@ -6095,40 +5183,19 @@ PluginParameter NetworkService ************** -The Network Service provides a bridge between the local DDS service and a -network interface. -The OpenSplice NetworkService supports both Internet Protocol -Versions 4 and 6 (IPv4 & IPv6) where possible. Please refer to the Release Notes -(Known Issues section) to see if the IPv6 capability is present on your operating -system. - -Note that each service instance will only communicate using one of these protocols. -It is an error to specify IPv6 ('colon-separated hexadecimal') and IPv4 ('dotted -decimal') addresses in the same NetworkService configuration. - -Multiple Network Services can exist next to each other, each serving one physical -network interface. -Please refer to Applications which operate in multiple domains, for notes about -applications operating in multiple domains and interactions with the Network Service. -The Network Service is responsible for forwarding data to the network and for -receiving data from the network. It can be configured to distinguish multiple -communication channels with different QoS policies assigned to be able to schedule -sending and receival of specific messages to provide optimal performance for a -specific application domain. -The Network Service is selected by using the following configuration element to the -Domain section of the configuration file (Element Application). -* - - -networking - -* - -The network configuration expects a root element named -OpenSplice/NetworkService. Within this root element, the Network Service -will look for several child-elements. Each of these is listed and explained. - -- Full path: //OpenSplice/NetworkService + When communication endpoints are located on different computing nodes, + the data produced using the local DDS service must be communicated to + the remote DDS service and the other way around. The Networking service + provides a bridge between the local DDS service and a network interface. + Multiple Networking services can exist next to each other; each serving + one (or more) physical network interface(s). The Networking service + is responsible for forwarding data to the network and for receiving data + from the network. It can be configured to distinguish multiple + communication channels with different QoS policies assigned to be able + to schedule sending and receival of specific messages to provide optimal + performance for a specific application domain. + +- Full path: /NetworkService - Occurrences min-max: 0-* - Required attributes: name @@ -6142,7 +5209,7 @@ name *//OpenSplice/Domain/Service[@name]* in the configuration of the DomainService. -- Full path: //OpenSplice/NetworkService[@name] +- Full path: /NetworkService/name - Format: string - Default value: networking - Required: true @@ -6152,7 +5219,7 @@ Watchdog This element controls the characteristics of the Watchdog thread. -- Full path: //OpenSplice/NetworkService/Watchdog +- Full path: /NetworkService/Watchdog - Occurrences min-max: 0-1 Scheduling @@ -6161,7 +5228,7 @@ Scheduling This element specifies the type of OS scheduling class will be used by the thread that announces its liveliness periodically. -- Full path: //OpenSplice/NetworkService/Watchdog/Scheduling +- Full path: /NetworkService/Watchdog/Scheduling - Occurrences min-max: 1-1 - Child elements: Priority, Class @@ -6174,7 +5241,7 @@ Priority The user may need special privileges from the underlying operating system to be able to assign some of the privileged priorities. -- Full path: //OpenSplice/NetworkService/Watchdog/Scheduling/Priority +- Full path: /NetworkService/Watchdog/Scheduling/Priority - Format: integer - Default value: 0 - Occurrences min-max: 1-1 @@ -6186,7 +5253,7 @@ priority_kind This attribute specifies whether the specified Priority is a relative or absolute priority. -- Full path: //OpenSplice/NetworkService/Watchdog/Scheduling/Priority[@priority_kind] +- Full path: /NetworkService/Watchdog/Scheduling/Priority/priority_kind - Format: enumeration - Default value: Relative - Valid values: Relative, Absolute @@ -6200,7 +5267,7 @@ Class the underlying operating system to be able to assign some of the privileged scheduling classes. -- Full path: //OpenSplice/NetworkService/Watchdog/Scheduling/Class +- Full path: /NetworkService/Watchdog/Scheduling/Class - Format: enumeration - Default value: Default - Valid values: Timeshare, Realtime, Default @@ -6212,7 +5279,7 @@ General This element contains general parameters that concern the networking service as a whole. -- Full path: //OpenSplice/NetworkService/General +- Full path: /NetworkService/General - Occurrences min-max: 0-1 - Child elements: NetworkInterfaceAddress, EnableMulticastLoopback, LegacyCompression @@ -6227,7 +5294,7 @@ NetworkInterfaceAddress middleware will try to look up an interface that has the required capabilities. -- Full path: //OpenSplice/NetworkService/General/NetworkInterfaceAddress +- Full path: /NetworkService/General/NetworkInterfaceAddress - Format: string - Default value: first available - Occurrences min-max: 0-1 @@ -6241,7 +5308,7 @@ forced - false - Specifies that the NetworkInterfaceAddress is first used but when not available another, when available, is used. (default). - true - Specifies that only the selected NetworkInterfaceAddress can be used. -- Full path: //OpenSplice/NetworkService/General/NetworkInterfaceAddress[@forced] +- Full path: /NetworkService/General/NetworkInterfaceAddress/forced - Format: boolean - Default value: false - Required: false @@ -6260,7 +5327,7 @@ ipv6 optionally required to specify IPv6 communication when special values like "first available" or an interface name are used instead of IP addresses. -- Full path: //OpenSplice/NetworkService/General/NetworkInterfaceAddress[@ipv6] +- Full path: /NetworkService/General/NetworkInterfaceAddress/ipv6 - Format: boolean - Default value: false - Required: false @@ -6274,7 +5341,7 @@ bind - any - Specifies that the service should bind to the wildcard-address (INADDR_ANY) (default). - strict - Specifies that the service should bind to the NetworkingInterfaceAddress. -- Full path: //OpenSplice/NetworkService/General/NetworkInterfaceAddress[@bind] +- Full path: /NetworkService/General/NetworkInterfaceAddress/bind - Format: enumeration - Default value: any - Valid values: any, strict @@ -6292,21 +5359,20 @@ allowReuse - true - Ports can be reused (SO_REUSEADDR enabled) (default). - false - Ports are bound exclusively. -- Full path: //OpenSplice/NetworkService/General/NetworkInterfaceAddress[@allowReuse] +- Full path: /NetworkService/General/NetworkInterfaceAddress/allowReuse - Format: boolean - Default value: true - Required: false EnableMulticastLoopback ----------------------- - - EnableMulticastLoopback specifies whether the networking service will allow +EnableMulticastLoopback specifies whether the networking service will allow IP multicast packets within the node to be visible to all networking participants in the node, including itself. It must be TRUE for intra-node multicast communications, but if a node runs only a single OpenSplice networking service and does not host any other networking-capable programs, it may be set to FALSE for improved performance. -- Full path: //OpenSplice/NetworkService/General/EnableMulticastLoopback +- Full path: /NetworkService/General/EnableMulticastLoopback - Format: boolean - Default value: True - Valid values: True, False @@ -6320,7 +5386,7 @@ LegacyCompression backward compatibility. When set to FALSE compression is applied before fragmentation. The default value is TRUE. -- Full path: //OpenSplice/NetworkService/General/LegacyCompression +- Full path: /NetworkService/General/LegacyCompression - Format: boolean - Default value: True - Valid values: True, False @@ -6338,7 +5404,7 @@ Reconnection If automatic reconnection is allowed, communication channels with the now-reachable-again node will be restored, even though reliable data might have been lost during the disconnection period. -- Full path: //OpenSplice/NetworkService/General/Reconnection +- Full path: /NetworkService/General/Reconnection - Occurrences min-max: 0-1 - Required attributes: allowed @@ -6353,7 +5419,7 @@ allowed - false - Specifies that the network service must NOT resume communication. (default). - true - Specifies that the network service must resume communication. -- Full path: //OpenSplice/NetworkService/General/Reconnection[@allowed] +- Full path: /NetworkService/General/Reconnection/allowed - Format: boolean - Default value: false - Required: true @@ -6387,17 +5453,15 @@ Partitioning onto a specific networking partition, which on its turn is only connected to those nodes that are capable of handling high volume data. -- Full path: //OpenSplice/NetworkService/Partitioning +- Full path: /NetworkService/Partitioning - Occurrences min-max: 0-1 GlobalPartition --------------- This element specifies the global or default networking partition. - This global network partition transports data that is either meant to be global, like discovery heartbeats, - or that is not mapped onto any other network partition. -- Full path: //OpenSplice/NetworkService/Partitioning/GlobalPartition +- Full path: /NetworkService/Partitioning/GlobalPartition - Occurrences min-max: 0-1 - Required attributes: Address - Optional attributes: MulticastTimeToLive @@ -6418,26 +5482,18 @@ Address Addresses can be entered as dotted decimal notation or as the symbolic hostname, in which case the middleware will try to resolve the corresponding IP address. - If the value for this attribute is one, or more, 'colon-separated hexadecimal' Internet - Protocol Version 6 (IPv6) address(es), then the NetworkService will be - configured to use IPv6 for communication. -- Full path: //OpenSplice/NetworkService/Partitioning/GlobalPartition[@Address] +- Full path: /NetworkService/Partitioning/GlobalPartition/Address - Format: string - Default value: broadcast - Required: true MulticastTimeToLive ^^^^^^^^^^^^^^^^^^^ +For each UDP packet sent out, The TimeToLive header value is set to this value for Multicast packets. - For each UDP packet sent out, the TimeToLive header value is set to this value for - Multicast packets. - By specifying a value of '0', multicast traffic can be confined to the local node, and - such 'loopback' performance is typically optimized by the operating system - -- Full path: //OpenSplice/NetworkService/Partitioning/GlobalPartition[@MulticastTimeToLive] +- Full path: /NetworkService/Partitioning/GlobalPartition/MulticastTimeToLive - Default value: 32 -- Valid values: 0 / 255 - Required: false NetworkPartitions @@ -6446,7 +5502,7 @@ NetworkPartitions Networking configuration can contain a set of networking partitions, which are grouped under the NetworkPartitions element. -- Full path: //OpenSplice/NetworkService/Partitioning/NetworkPartitions +- Full path: /NetworkService/Partitioning/NetworkPartitions - Occurrences min-max: 0-1 NetworkPartition @@ -6454,17 +5510,17 @@ NetworkPartition Every NetworkPartition has a name, an address and a connected flag. -- Full path: //OpenSplice/NetworkService/Partitioning/NetworkPartitions/NetworkPartition +- Full path: /NetworkService/Partitioning/NetworkPartitions/NetworkPartition - Occurrences min-max: 1-* -- Required attributes: Address -- Optional attributes: Name, Connected, Compression, SecurityProfile, MulticastTimeToLive +- Required attributes: Address, Connected +- Optional attributes: Name, Compression, SecurityProfile, MulticastTimeToLive Name ~~~~ A networking partition is uniquely identified by its name. -- Full path: //OpenSplice/NetworkService/Partitioning/NetworkPartitions/NetworkPartition[@Name] +- Full path: /NetworkService/Partitioning/NetworkPartitions/NetworkPartition/Name - Format: string - Default value: networkPartition - Required: false @@ -6483,7 +5539,7 @@ Address symbolic hostname, in which case the middleware will try to resolve the corresponding IP address. -- Full path: //OpenSplice/NetworkService/Partitioning/NetworkPartitions/NetworkPartition[@Address] +- Full path: /NetworkService/Partitioning/NetworkPartitions/NetworkPartition/Address - Format: string - Default value: broadcast - Required: true @@ -6502,10 +5558,10 @@ Connected filtered by the networking interface or multicast enabled switches. -- Full path: //OpenSplice/NetworkService/Partitioning/NetworkPartitions/NetworkPartition[@Connected] +- Full path: /NetworkService/Partitioning/NetworkPartitions/NetworkPartition/Connected - Format: boolean - Default value: true -- Required: false +- Required: true Compression ~~~~~~~~~~~ @@ -6520,7 +5576,7 @@ Compression - false - No compression is applied. This is also the default value if not specified. - true - Compression is applicable -- Full path: //OpenSplice/NetworkService/Partitioning/NetworkPartitions/NetworkPartition[@Compression] +- Full path: /NetworkService/Partitioning/NetworkPartitions/NetworkPartition/Compression - Format: boolean - Default value: false - Required: false @@ -6543,7 +5599,7 @@ SecurityProfile evaluated or initialized, and the associated secret cipher keys need not to be defined for the OpenSplice node in question. -- Full path: //OpenSplice/NetworkService/Partitioning/NetworkPartitions/NetworkPartition[@SecurityProfile] +- Full path: /NetworkService/Partitioning/NetworkPartitions/NetworkPartition/SecurityProfile - Format: string - Default value: nullProfile - Required: false @@ -6552,9 +5608,8 @@ MulticastTimeToLive ~~~~~~~~~~~~~~~~~~~ For each UDP packet sent out, The TimeToLive header value is set to this value for Multicast packets. -- Full path: //OpenSplice/NetworkService/Partitioning/NetworkPartitions/NetworkPartition[@MulticastTimeToLive] +- Full path: /NetworkService/Partitioning/NetworkPartitions/NetworkPartition/MulticastTimeToLive - Default value: 32 -- Valid values: 0 / 255 - Required: false IgnoredPartitions @@ -6562,7 +5617,7 @@ IgnoredPartitions This element is used to group the set of IgnoredPartition elements. -- Full path: //OpenSplice/NetworkService/Partitioning/IgnoredPartitions +- Full path: /NetworkService/Partitioning/IgnoredPartitions - Occurrences min-max: 0-1 IgnoredPartition @@ -6573,7 +5628,7 @@ IgnoredPartition generate network-load. Any DCPS partition-topic combination specified in this element will not be distibuted by the Networking service. -- Full path: //OpenSplice/NetworkService/Partitioning/IgnoredPartitions/IgnoredPartition +- Full path: /NetworkService/Partitioning/IgnoredPartitions/IgnoredPartition - Occurrences min-max: 1-* - Required attributes: DCPSPartitionTopic @@ -6583,12 +5638,12 @@ DCPSPartitionTopic The Networking service will match any DCPS messages to the DCPSPartitionTopic expression and determine if it matches. The PartitionExpression and - TopicExpression are allowed to contain a '\*' wildcard, + TopicExpression are allowed to contain a '*' wildcard, meaning that anything matches. An exact match is considered better than a wildcard match. If a DCPS messages matches an expression it will not be send to the network. -- Full path: //OpenSplice/NetworkService/Partitioning/IgnoredPartitions/IgnoredPartition[@DCPSPartitionTopic] +- Full path: /NetworkService/Partitioning/IgnoredPartitions/IgnoredPartition/DCPSPartitionTopic - Format: string - Default value: *.* - Required: true @@ -6598,7 +5653,7 @@ PartitionMappings This element is used to group the set of PartitionMapping elements. -- Full path: //OpenSplice/NetworkService/Partitioning/PartitionMappings +- Full path: /NetworkService/Partitioning/PartitionMappings - Occurrences min-max: 0-1 PartitionMapping @@ -6612,7 +5667,7 @@ PartitionMapping partitions should be defined. Networking allows for a set of partition mappings to be defined. -- Full path: //OpenSplice/NetworkService/Partitioning/PartitionMappings/PartitionMapping +- Full path: /NetworkService/Partitioning/PartitionMappings/PartitionMapping - Occurrences min-max: 1-* - Required attributes: NetworkPartition, DCPSPartitionTopic @@ -6624,7 +5679,7 @@ NetworkPartition specific DCPS partition of a specific DCPS topic should be sent to. -- Full path: //OpenSplice/NetworkService/Partitioning/PartitionMappings/PartitionMapping[@NetworkPartition] +- Full path: /NetworkService/Partitioning/PartitionMappings/PartitionMapping/NetworkPartition - Format: string - Default value: networkPartition - Required: true @@ -6635,7 +5690,7 @@ DCPSPartitionTopic The Networking service will match any DCPS messages to the DCPSPartitionTopic expression and determine if it matches. The PartitionExpression and - TopicExpression are allowed to contain a '\*' wildcard, + TopicExpression are allowed to contain a '*' wildcard, meaning that anything matches. An exact match is considered better than a wildcard match. For every DCPS message, the best matching partition is determined @@ -6643,7 +5698,7 @@ DCPSPartitionTopic partition as specified by the matching *NetworkPartition* element. -- Full path: //OpenSplice/NetworkService/Partitioning/PartitionMappings/PartitionMapping[@DCPSPartitionTopic] +- Full path: /NetworkService/Partitioning/PartitionMappings/PartitionMapping/DCPSPartitionTopic - Format: string - Default value: *.* - Required: true @@ -6660,7 +5715,7 @@ Channels application-defined DDS QoS policies of the data to select the most appropriate channel to send the data. -- Full path: //OpenSplice/NetworkService/Channels +- Full path: /NetworkService/Channels - Occurrences min-max: 1-1 - Child elements: AllowedPorts @@ -6676,7 +5731,7 @@ Channel performance depends heavily on the compatbility of the configured channels with the used DDS QoS policies of the applications. -- Full path: //OpenSplice/NetworkService/Channels/Channel +- Full path: /NetworkService/Channels/Channel - Occurrences min-max: 1-42 - Child elements: PortNr, FragmentSize, Resolution, AdminQueueSize, CompressionBufferSize, CompressionThreshold, AllowedPorts - Required attributes: name, reliable, enabled @@ -6687,7 +5742,7 @@ name The name uniquely identifies the channel. -- Full path: //OpenSplice/NetworkService/Channels/Channel[@name] +- Full path: /NetworkService/Channels/Channel/name - Format: string - Default value: aChannel - Required: true @@ -6704,7 +5759,7 @@ reliable reliable attribute happens to be set to true, the message will be sent over the network using a reliability protocol. -- Full path: //OpenSplice/NetworkService/Channels/Channel[@reliable] +- Full path: /NetworkService/Channels/Channel/reliable - Format: boolean - Default value: false - Required: true @@ -6726,7 +5781,7 @@ default Note that only one channel is allowed to have this attribute set to true -- Full path: //OpenSplice/NetworkService/Channels/Channel[@default] +- Full path: /NetworkService/Channels/Channel/default - Format: boolean - Default value: false - Required: false @@ -6739,7 +5794,7 @@ enabled for commenting out the corresponding lines in the configuration file. -- Full path: //OpenSplice/NetworkService/Channels/Channel[@enabled] +- Full path: /NetworkService/Channels/Channel/enabled - Format: boolean - Default value: false - Required: true @@ -6756,7 +5811,7 @@ priority into intervals. Within a channel, messages are sorted in order of priority. -- Full path: //OpenSplice/NetworkService/Channels/Channel[@priority] +- Full path: /NetworkService/Channels/Channel/priority - Format: integer - Default value: 0 - Required: false @@ -6770,10 +5825,9 @@ PortNr that 'reliable' channels use a second port, which is the specified PortNr + 1. -- Full path: //OpenSplice/NetworkService/Channels/Channel/PortNr +- Full path: /NetworkService/Channels/Channel/PortNr - Format: integer - Default value: 53400 -- Valid values: 1 / 65535 - Occurrences min-max: 1-1 FragmentSize @@ -6784,9 +5838,8 @@ FragmentSize are sent as datagrams to the UDP stack. OS-settings determine the maximum datagram size. -- Full path: //OpenSplice/NetworkService/Channels/Channel/FragmentSize +- Full path: /NetworkService/Channels/Channel/FragmentSize - Default value: 1300 -- Valid values: 200 / 65535 - Occurrences min-max: 0-1 Resolution @@ -6800,10 +5853,9 @@ Resolution It is considered good practice to specify the ThrottleTreshold consistently throughout the system. -- Full path: //OpenSplice/NetworkService/Channels/Channel/Resolution +- Full path: /NetworkService/Channels/Channel/Resolution - Format: integer - Default value: 10 -- Valid values: 1 / - - Occurrences min-max: 0-1 AdminQueueSize @@ -6816,10 +5868,9 @@ AdminQueueSize size of this queue, and it must be greater than the maximum number of reliable messages send or received during each "Resolution" milliseconds. -- Full path: //OpenSplice/NetworkService/Channels/Channel/AdminQueueSize +- Full path: /NetworkService/Channels/Channel/AdminQueueSize - Format: integer - Default value: 4000 -- Valid values: 400 / - - Occurrences min-max: 0-1 CompressionBufferSize @@ -6831,10 +5882,9 @@ CompressionBufferSize the received compressed messages. Note that the actual size of these buffers may be increased when needed. -- Full path: //OpenSplice/NetworkService/Channels/Channel/CompressionBufferSize +- Full path: /NetworkService/Channels/Channel/CompressionBufferSize - Format: integer - Default value: 131072 -- Valid values: 65536 / - - Occurrences min-max: 0-1 CompressionThreshold @@ -6844,10 +5894,9 @@ CompressionThreshold to start compressing the accumulated data and sending the compressed data on the network. The CompressionThreshold is used to estimate the size of the compressed messages. -- Full path: //OpenSplice/NetworkService/Channels/Channel/CompressionThreshold +- Full path: /NetworkService/Channels/Channel/CompressionThreshold - Format: integer - Default value: 0 -- Valid values: 0 / - - Occurrences min-max: 0-1 Sending @@ -6856,9 +5905,9 @@ Sending This element describes all properties for the transmitting side of the Channel. -- Full path: //OpenSplice/NetworkService/Channels/Channel/Sending +- Full path: /NetworkService/Channels/Channel/Sending - Occurrences min-max: 0-1 -- Child elements: CrcCheck, QueueSize, MaxBurstSize, ThrottleLimit, ThrottleThreshold, MaxRetries, RecoveryFactor, DiffServField, DontRoute, TimeToLive, ReportInterval +- Child elements: CrcCheck, QueueSize, MaxBurstSize, ThrottleLimit, ThrottleThreshold, MaxRetries, RecoveryFactor, DiffServField, DontRoute, TimeToLive CrcCheck ~~~~~~~~ @@ -6870,7 +5919,7 @@ CrcCheck When the sending side is enabled the network packet will contain a valid crc field. -- Full path: //OpenSplice/NetworkService/Channels/Channel/Sending/CrcCheck +- Full path: /NetworkService/Channels/Channel/Sending/CrcCheck - Format: boolean - Default value: false - Occurrences min-max: 0-1 @@ -6886,10 +5935,9 @@ QueueSize and will retry until success. Note that a full networking queue is a symptom of an improperly designed system. -- Full path: //OpenSplice/NetworkService/Channels/Channel/Sending/QueueSize +- Full path: /NetworkService/Channels/Channel/Sending/QueueSize - Format: integer - Default value: 400 -- Valid values: 1 / - - Occurrences min-max: 0-1 MaxBurstSize @@ -6899,9 +5947,8 @@ MaxBurstSize "Resolution" milliseconds. The default value is set to 1GB per resolution tick. This can be considered "unlimited" as this far exceeds the capacity of modern physical networks. -- Full path: //OpenSplice/NetworkService/Channels/Channel/Sending/MaxBurstSize +- Full path: /NetworkService/Channels/Channel/Sending/MaxBurstSize - Default value: 1073741823 -- Valid values: 1024 / 1073741823 - Occurrences min-max: 0-1 ThrottleLimit @@ -6915,7 +5962,7 @@ ThrottleLimit The ThrottleLimit value is not allowed be smaller than the FragmentSize. If a lower value is provided, then the value of FragmentSize is used as ThrottleLimit. -- Full path: //OpenSplice/NetworkService/Channels/Channel/Sending/ThrottleLimit +- Full path: /NetworkService/Channels/Channel/Sending/ThrottleLimit - Default value: 10240 - Occurrences min-max: 0-1 @@ -6930,10 +5977,9 @@ ThrottleThreshold It is considered good practice to specify the ThrottleTreshold consistently throughout the system. -- Full path: //OpenSplice/NetworkService/Channels/Channel/Sending/ThrottleThreshold +- Full path: /NetworkService/Channels/Channel/Sending/ThrottleThreshold - Format: integer - Default value: 50 -- Valid values: 2 / - - Occurrences min-max: 0-1 MaxRetries @@ -6942,20 +5988,18 @@ MaxRetries The number of retransmissions the service has to execute before considering the addressed node as not responding. -- Full path: //OpenSplice/NetworkService/Channels/Channel/Sending/MaxRetries +- Full path: /NetworkService/Channels/Channel/Sending/MaxRetries - Format: integer - Default value: 100 -- Valid values: 1 / - - Occurrences min-max: 0-1 RecoveryFactor ~~~~~~~~~~~~~~ -A lost message is resent after Resolution \* RecoveryFactor milliseconds. +A lost message is resent after Resolution * RecoveryFactor milliseconds. -- Full path: //OpenSplice/NetworkService/Channels/Channel/Sending/RecoveryFactor +- Full path: /NetworkService/Channels/Channel/Sending/RecoveryFactor - Format: integer - Default value: 3 -- Valid values: 2 / - - Occurrences min-max: 0-1 DiffServField @@ -6986,10 +6030,9 @@ DiffServField 1-8 background traffic; 9-40 excellent traffic; 41-55 audio/video traffic; 56 voice traffic; 57-63 control traffic. When OpenSplice is run without Administrative priveleges then only the diffserv value of 0, 8, 40 or 56 is allowed. -- Full path: //OpenSplice/NetworkService/Channels/Channel/Sending/DiffServField +- Full path: /NetworkService/Channels/Channel/Sending/DiffServField - Format: integer - Default value: 0 -- Valid values: 0 / 255 - Occurrences min-max: 0-1 DontRoute @@ -6997,7 +6040,7 @@ DontRoute The IP DONTROUTE socket option is set to the value specified. -- Full path: //OpenSplice/NetworkService/Channels/Channel/Sending/DontRoute +- Full path: /NetworkService/Channels/Channel/Sending/DontRoute - Format: boolean - Default value: True - Valid values: True, False @@ -7008,10 +6051,9 @@ TimeToLive For each UDP packet sent out, the IP Time To Live header value is set to the value specified. -- Full path: //OpenSplice/NetworkService/Channels/Channel/Sending/TimeToLive +- Full path: /NetworkService/Channels/Channel/Sending/TimeToLive - Format: integer -- Default value: 1 -- Valid values: 1 / 255 +- Default value: 0 - Occurrences min-max: 0-1 Scheduling @@ -7020,7 +6062,7 @@ Scheduling This element specifies the scheduling policies used to control the transmitter thread of the current Channel. -- Full path: //OpenSplice/NetworkService/Channels/Channel/Sending/Scheduling +- Full path: /NetworkService/Channels/Channel/Sending/Scheduling - Occurrences min-max: 0-1 - Child elements: Priority, Class @@ -7032,7 +6074,7 @@ Priority can be assigned to this element. The user may need special privileges from the underlying operating system to be able to assign some of the privileged priorities. -- Full path: //OpenSplice/NetworkService/Channels/Channel/Sending/Scheduling/Priority +- Full path: /NetworkService/Channels/Channel/Sending/Scheduling/Priority - Format: integer - Default value: 0 - Occurrences min-max: 1-1 @@ -7044,7 +6086,7 @@ priority_kind This attribute specifies whether the specified *Priority* is a relative or absolute priority. -- Full path: //OpenSplice/NetworkService/Channels/Channel/Sending/Scheduling/Priority[@priority_kind] +- Full path: /NetworkService/Channels/Channel/Sending/Scheduling/Priority/priority_kind - Format: enumeration - Default value: Relative - Valid values: Relative, Absolute @@ -7057,7 +6099,7 @@ Class thread. The user may need the appropriate privileges from the underlying operating system to be able to assign some of the privileged scheduling classes. -- Full path: //OpenSplice/NetworkService/Channels/Channel/Sending/Scheduling/Class +- Full path: /NetworkService/Channels/Channel/Sending/Scheduling/Class - Format: enumeration - Default value: Default - Valid values: Timeshare, Realtime, Default @@ -7069,7 +6111,7 @@ Receiving This element describes all properties for the receiving side of the Channel. -- Full path: //OpenSplice/NetworkService/Channels/Channel/Receiving +- Full path: /NetworkService/Channels/Channel/Receiving - Occurrences min-max: 0-1 - Child elements: CrcCheck, ReceiveBufferSize, DefragBufferSize, MaxReliabBacklog, PacketRetentionPeriod, ReliabilityRecoveryPeriod @@ -7083,7 +6125,7 @@ CrcCheck When the receiving side is enabled only network packets that contain a valid crc field are accepted. -- Full path: //OpenSplice/NetworkService/Channels/Channel/Receiving/CrcCheck +- Full path: /NetworkService/Channels/Channel/Receiving/CrcCheck - Format: boolean - Default value: false - Occurrences min-max: 0-1 @@ -7095,9 +6137,8 @@ ReceiveBufferSize set to the value given. If many message are lost, the receive buffer size has to be increased. -- Full path: //OpenSplice/NetworkService/Channels/Channel/Receiving/ReceiveBufferSize +- Full path: /NetworkService/Channels/Channel/Receiving/ReceiveBufferSize - Default value: 1000000 -- Valid values: 1024 / - - Occurrences min-max: 0-1 Scheduling @@ -7106,9 +6147,9 @@ Scheduling This element specifies the scheduling policies used to control the receiver thread of the current Channel. -- Full path: //OpenSplice/NetworkService/Channels/Channel/Receiving/Scheduling +- Full path: /NetworkService/Channels/Channel/Receiving/Scheduling - Occurrences min-max: 0-1 -- Child elements: Priority, Class, ReportInterval +- Child elements: Priority, Class Priority ++++++++ @@ -7119,7 +6160,7 @@ Priority the underlying operating system to be able to assign some of the privileged priorities. -- Full path: //OpenSplice/NetworkService/Channels/Channel/Receiving/Scheduling/Priority +- Full path: /NetworkService/Channels/Channel/Receiving/Scheduling/Priority - Format: integer - Default value: 0 - Occurrences min-max: 1-1 @@ -7131,7 +6172,7 @@ priority_kind This attribute specifies whether the specified *Priority* is a relative or absolute priority. -- Full path: //OpenSplice/NetworkService/Channels/Channel/Receiving/Scheduling/Priority[@priority_kind] +- Full path: /NetworkService/Channels/Channel/Receiving/Scheduling/Priority/priority_kind - Format: enumeration - Default value: Relative - Valid values: Relative, Absolute @@ -7144,7 +6185,7 @@ Class thread. The user may need the appropriate privileges from the underlying operating system to be able to assign some of the privileged scheduling classes. -- Full path: //OpenSplice/NetworkService/Channels/Channel/Receiving/Scheduling/Class +- Full path: /NetworkService/Channels/Channel/Receiving/Scheduling/Class - Format: enumeration - Default value: Default - Valid values: Timeshare, Realtime, Default @@ -7157,9 +6198,8 @@ DefragBufferSize this channel. These buffers are used to store incoming fragments waiting to be processed, as well as fragments that are being processed. -- Full path: //OpenSplice/NetworkService/Channels/Channel/Receiving/DefragBufferSize +- Full path: /NetworkService/Channels/Channel/Receiving/DefragBufferSize - Default value: 5000 -- Valid values: 500 / - - Occurrences min-max: 0-1 SMPOptimization @@ -7168,7 +6208,7 @@ SMPOptimization This option will distribute the processing done for incoming fragements over multiple threads, which will lead to an improved throughput on SMP nodes. -- Full path: //OpenSplice/NetworkService/Channels/Channel/Receiving/SMPOptimization +- Full path: /NetworkService/Channels/Channel/Receiving/SMPOptimization - Occurrences min-max: 0-1 - Required attributes: enabled @@ -7177,7 +6217,7 @@ enabled This attribute toggles the Optimization on or off. -- Full path: //OpenSplice/NetworkService/Channels/Channel/Receiving/SMPOptimization[@enabled] +- Full path: /NetworkService/Channels/Channel/Receiving/SMPOptimization/enabled - Format: boolean - Default value: true - Required: true @@ -7190,10 +6230,9 @@ MaxReliabBacklog fragment from that remote node is missing. If this number is exceeded, then that particular remote node that didn't resend the missing fragent in time is considered dead for this channel. -- Full path: //OpenSplice/NetworkService/Channels/Channel/Receiving/MaxReliabBacklog +- Full path: /NetworkService/Channels/Channel/Receiving/MaxReliabBacklog - Format: integer - Default value: 1000 -- Valid values: 100 / - - Occurrences min-max: 0-1 PacketRetentionPeriod @@ -7212,10 +6251,9 @@ PacketRetentionPeriod exceeds the worst-case death-detection time as configured for the discovery protocol of the set of distributed networking services in the system. -- Full path: //OpenSplice/NetworkService/Channels/Channel/Receiving/PacketRetentionPeriod +- Full path: /NetworkService/Channels/Channel/Receiving/PacketRetentionPeriod - Format: integer - Default value: 0 -- Valid values: 0 / - - Occurrences min-max: 0-1 ReliabilityRecoveryPeriod @@ -7230,10 +6268,9 @@ ReliabilityRecoveryPeriod for the worst-case alignment-time of any "missed" data by individual receiving nodes following the disappearance of a sending node in the system. -- Full path: //OpenSplice/NetworkService/Channels/Channel/Receiving/ReliabilityRecoveryPeriod +- Full path: /NetworkService/Channels/Channel/Receiving/ReliabilityRecoveryPeriod - Format: integer - Default value: 1000 -- Valid values: 0 / - - Occurrences min-max: 0-1 AllowedPorts @@ -7253,7 +6290,7 @@ AllowedPorts comma (,). A port number range consists of the lower and the upper bound of the port number range, where the lower and the upper bound are seperated by a minus (-). -- Full path: //OpenSplice/NetworkService/Channels/Channel/AllowedPorts +- Full path: /NetworkService/Channels/Channel/AllowedPorts - Format: string - Occurrences min-max: 0-1 @@ -7274,40 +6311,22 @@ AllowedPorts comma (,). A port number range consists of the lower and the upper bound of the port number range, where the lower and the upper bound are seperated by a minus (-). -- Full path: //OpenSplice/NetworkService/Channels/AllowedPorts +- Full path: /NetworkService/Channels/AllowedPorts - Format: string - Occurrences min-max: 0-1 Discovery ========= -This element controls various parameters of the Network Services Discovery -mechanism. -Discovery reduces the Network Service configuration and minimizes network -traffic. Without Discovery, data is always sent to the network and all Networking -Services need to configure the addresses (This can be multicast addresses and/or -uni-cast addresses, especially in an uni-cast environment with many nodes the -configuration of the Network Service's lists can be cumbersome.) -of all Network Services they need to -communicate with. With Discovery, data is only sent to where interest exists and -connectivity is discovered based on a minimum configuration (Only a subset of -addresses of nodes are initially specified, these nodes are assumed to be -available as a discovery source, all nodes will make themselves known to these discovery -nodes and thereby making its existence and address available for all other nodes) (see Element ProbeList). -Discovery is based on a heartbeat mechanism to advertize the service's availability. -The Network Service starts by announcing its existence by sending heartbeats to the -Global Partition (The Global Partition contains all the addresses that the Network Service communicate -with) which is initially filled with the addresses specified in the -ProbeList; remote Network Services receiving the heartbeat will start sending -heartbeats in return. All Network Services that discover new heartbeats will -automatically request address information that match their Scope (see Attribute Scope) -from the Network Service sending the -heartbeat, and add the retrieved address information to their Global Partition. -Currently only uni-cast addresses are exchanged. Addresses are removed from the -Global Partition when a remote Network Service stops and heartbeats are no longer -received. - -- Full path: //OpenSplice/NetworkService/Discovery + This element is used to configure the various parameters of the Discovery Channel, + which is used to discover all relevant participating entities in the current Domain. + The purpose of the discovery process is to build-up and maintain a notion of all + relevant active nodes within the domain. The relevance of discovered remote nodes + can be defined statically (by definition of the so-called Global Partition) and/or + can be dynamically expanded and maintained by the dynamic-discovery process driven + by the node's Role and Scope. + +- Full path: /NetworkService/Discovery - Occurrences min-max: 0-1 - Child elements: PortNr, ProbeList - Optional attributes: enabled, Scope @@ -7319,7 +6338,7 @@ enabled Channel is disabled, entities will only detect each others presence implicitly once messages are received for the first time. -- Full path: //OpenSplice/NetworkService/Discovery[@enabled] +- Full path: /NetworkService/Discovery/enabled - Format: boolean - Default value: true - Occurrences min-max: 0-1 @@ -7338,7 +6357,7 @@ Scope considered a match and will become part of the communication reach (i.e. the Global Partition) of the current domain. -- Full path: //OpenSplice/NetworkService/Discovery[@Scope] +- Full path: /NetworkService/Discovery/Scope - Format: string - Occurrences min-max: 0-1 - Required: false @@ -7348,10 +6367,9 @@ PortNr This element specifies the Port number used by the Discovery Channel. -- Full path: //OpenSplice/NetworkService/Discovery/PortNr +- Full path: /NetworkService/Discovery/PortNr - Format: integer - Default value: 3369 -- Valid values: 1 / 65536 - Occurrences min-max: 1-1 ProbeList @@ -7363,7 +6381,7 @@ ProbeList The addresses can be entered as dotted decimal notation or as the symbolic hostname, in which case the middleware will try to resolve the corresponding IP address. -- Full path: //OpenSplice/NetworkService/Discovery/ProbeList +- Full path: /NetworkService/Discovery/ProbeList - Format: string - Occurrences min-max: 0-1 @@ -7373,7 +6391,7 @@ Sending This element describes all properties for the transmitting side of the Discovery Channel. -- Full path: //OpenSplice/NetworkService/Discovery/Sending +- Full path: /NetworkService/Discovery/Sending - Occurrences min-max: 0-1 - Child elements: CrcCheck, DiffServField, DontRoute, TimeToLive, Interval, SafetyFactor, SalvoSize @@ -7387,7 +6405,7 @@ CrcCheck When the sending side is enabled the network packet will contain a valid crc field. -- Full path: //OpenSplice/NetworkService/Discovery/Sending/CrcCheck +- Full path: /NetworkService/Discovery/Sending/CrcCheck - Format: boolean - Default value: false - Occurrences min-max: 0-1 @@ -7420,10 +6438,9 @@ DiffServField 1-8 background traffic; 9-40 excellent traffic; 41-55 audio/video traffic; 56 voice traffic; 57-63 control traffic. When OpenSplice is run without Administrative priveleges then only the diffserv value of 0, 8, 40 or 56 is allowed. -- Full path: //OpenSplice/NetworkService/Discovery/Sending/DiffServField +- Full path: /NetworkService/Discovery/Sending/DiffServField - Format: integer - Default value: 0 -- Valid values: 0 / 255 - Occurrences min-max: 0-1 DontRoute @@ -7431,7 +6448,7 @@ DontRoute The IP DONTROUTE socket option is set to the value specified. -- Full path: //OpenSplice/NetworkService/Discovery/Sending/DontRoute +- Full path: /NetworkService/Discovery/Sending/DontRoute - Format: boolean - Default value: True - Valid values: True, False @@ -7442,10 +6459,9 @@ TimeToLive For each UDP packet sent out, the IP Time To Live header value is set to the value specified. -- Full path: //OpenSplice/NetworkService/Discovery/Sending/TimeToLive +- Full path: /NetworkService/Discovery/Sending/TimeToLive - Format: integer -- Default value: 1 -- Valid values: 1 / 255 +- Default value: 0 - Occurrences min-max: 0-1 Scheduling @@ -7454,7 +6470,7 @@ Scheduling This element specifies the scheduling policies used to control the transmitter thread of the Discovery Channel. -- Full path: //OpenSplice/NetworkService/Discovery/Sending/Scheduling +- Full path: /NetworkService/Discovery/Sending/Scheduling - Occurrences min-max: 0-1 - Child elements: Priority, Class @@ -7466,7 +6482,7 @@ Priority system can be assigned to this element. The user may need special privileges from the underlying operating system to be able to assign some of the privileged priorities. -- Full path: //OpenSplice/NetworkService/Discovery/Sending/Scheduling/Priority +- Full path: /NetworkService/Discovery/Sending/Scheduling/Priority - Format: integer - Default value: 0 - Occurrences min-max: 1-1 @@ -7478,7 +6494,7 @@ priority_kind This attribute specifies whether the specified *Priority* is a relative or absolute priority. -- Full path: //OpenSplice/NetworkService/Discovery/Sending/Scheduling/Priority[@priority_kind] +- Full path: /NetworkService/Discovery/Sending/Scheduling/Priority/priority_kind - Format: enumeration - Default value: Relative - Valid values: Relative, Absolute @@ -7491,7 +6507,7 @@ Class thread of the Discovery Channel. The user may need the appropriate privileges from the underlying operating system to be able to assign some of the privileged scheduling classes. -- Full path: //OpenSplice/NetworkService/Discovery/Sending/Scheduling/Class +- Full path: /NetworkService/Discovery/Sending/Scheduling/Class - Format: enumeration - Default value: Default - Valid values: Timeshare, Realtime, Default @@ -7502,43 +6518,29 @@ Interval This element describes the interval(in milliseconds) at which remote nodes will expect heartbeats from this node. -- Full path: //OpenSplice/NetworkService/Discovery/Sending/Interval +- Full path: /NetworkService/Discovery/Sending/Interval - Format: integer -- Dimension: milliseconds - Default value: 333 -- Valid values: 10 / - - Occurrences min-max: 0-1 SafetyFactor ^^^^^^^^^^^^ -The SafetyFactor is used to set a margin (< 1) on the expected heartbeat interval. -The actual interval at which the heartbeats are sent is the specified interval -multiplied by this factor, so the actual interval will be equal to or smaller than the -specified value. This can be used to avoid timing issues such as those caused by -typical scheduling or network latencies. + The SafetyFactor is used to set a margin on the discovery sending. This avoids tight timing issues. -- Full path: //OpenSplice/NetworkService/Discovery/Sending/SafetyFactor +- Full path: /NetworkService/Discovery/Sending/SafetyFactor - Default value: 0.9 -- Valid values: 0.2 / 1.0 - Occurrences min-max: 0-1 SalvoSize ^^^^^^^^^ - The reactivity of discovery depends on the heartbeat frequency, a higher heartbeat - frequency gives a faster reactivity but also imposes a higher network load, which is - not desirable. Ideally the heartbeat frequency must be kept as low as possible but - from a startup (and shutdown) perspective a high reactivity is often desired. So the - Network Service has the capability to send an additional salvo of heartbeats at - startup and shutdown at ten times the normal heartbeat speed to maximize reactivity - during these phases without requiring a continuous high heartbeat frequency. The - SalvoSize sets the number of messages to send during these phases. + During starting and stopping, discovery messages are sent at higher frequency. This SalvoSize sets + the number of messages to send during these phases. -- Full path: //OpenSplice/NetworkService/Discovery/Sending/SalvoSize +- Full path: /NetworkService/Discovery/Sending/SalvoSize - Format: integer - Default value: 3 -- Valid values: 1 / - - Occurrences min-max: 0-1 Receiving @@ -7547,7 +6549,7 @@ Receiving This element describes all properties for the receiving side of the Discovery Channel. -- Full path: //OpenSplice/NetworkService/Discovery/Receiving +- Full path: /NetworkService/Discovery/Receiving - Occurrences min-max: 0-1 - Child elements: CrcCheck, DeathDetectionCount, ReceiveBufferSize @@ -7561,7 +6563,7 @@ CrcCheck When the sending side is enabled the network packet will contain a valid crc field. -- Full path: //OpenSplice/NetworkService/Discovery/Receiving/CrcCheck +- Full path: /NetworkService/Discovery/Receiving/CrcCheck - Format: boolean - Default value: false - Occurrences min-max: 0-1 @@ -7572,7 +6574,7 @@ Scheduling This element specifies the scheduling policies used to control the receiver thread of the Discovery Channel. -- Full path: //OpenSplice/NetworkService/Discovery/Receiving/Scheduling +- Full path: /NetworkService/Discovery/Receiving/Scheduling - Occurrences min-max: 0-1 - Child elements: Priority, Class @@ -7584,7 +6586,7 @@ Priority system can be assigned to this element. The user may need special privileges from the underlying operating system to be able to assign some of the privileged priorities. -- Full path: //OpenSplice/NetworkService/Discovery/Receiving/Scheduling/Priority +- Full path: /NetworkService/Discovery/Receiving/Scheduling/Priority - Format: integer - Default value: 0 - Occurrences min-max: 1-1 @@ -7596,7 +6598,7 @@ priority_kind This attribute specifies whether the specified *Priority* is a relative or absolute priority. -- Full path: //OpenSplice/NetworkService/Discovery/Receiving/Scheduling/Priority[@priority_kind] +- Full path: /NetworkService/Discovery/Receiving/Scheduling/Priority/priority_kind - Format: enumeration - Default value: Relative - Valid values: Relative, Absolute @@ -7609,7 +6611,7 @@ Class thread of the Discovery Channel. The user may need the appropriate privileges from the underlying operating system to be able to assign some of the privileged scheduling classes. -- Full path: //OpenSplice/NetworkService/Discovery/Receiving/Scheduling/Class +- Full path: /NetworkService/Discovery/Receiving/Scheduling/Class - Format: enumeration - Default value: Default - Valid values: Timeshare, Realtime, Default @@ -7621,10 +6623,9 @@ DeathDetectionCount This element specifies how often a heartbeat from a remote node must miss its Interval before that remote node is considered dead. -- Full path: //OpenSplice/NetworkService/Discovery/Receiving/DeathDetectionCount +- Full path: /NetworkService/Discovery/Receiving/DeathDetectionCount - Format: integer - Default value: 6 -- Valid values: 1 / - - Occurrences min-max: 0-1 ReceiveBufferSize @@ -7633,10 +6634,8 @@ ReceiveBufferSize The UDP receive buffer of the Discovery Channel socket is set to the value given. If many message are lost, the receive buffer size has to be increased. -- Full path: //OpenSplice/NetworkService/Discovery/Receiving/ReceiveBufferSize -- Dimension: bytes +- Full path: /NetworkService/Discovery/Receiving/ReceiveBufferSize - Default value: 1000000 -- Valid values: 1 / - - Occurrences min-max: 0-1 Tracing @@ -7646,20 +6645,9 @@ Tracing tracing log by the Networking Service. This is useful to track the Networking Service during application development. In the runtime system it should be turned off. -- Full path: //OpenSplice/NetworkService/Tracing +- Full path: /NetworkService/Tracing - Occurrences min-max: 0-1 - Child elements: OutputFile, Timestamps -- Optional attributes: enabled - -enabled -------- - - This attribute controls whether the tracing option is enabled or not. - -- Full path: //OpenSplice/NetworkService/Tracing[@enabled] -- Format: boolean -- Default value: true -- Required: false OutputFile ---------- @@ -7668,7 +6656,7 @@ OutputFile legal value that represents "standard out". The default value is an empty string, indicating that the tracing log will be written to standard out. -- Full path: //OpenSplice/NetworkService/Tracing/OutputFile +- Full path: /NetworkService/Tracing/OutputFile - Format: string - Default value: networking.log - Occurrences min-max: 1-1 @@ -7678,10 +6666,10 @@ Timestamps This element specifies whether the logging must contain timestamps. -- Full path: //OpenSplice/NetworkService/Tracing/Timestamps +- Full path: /NetworkService/Tracing/Timestamps - Format: boolean - Default value: true -- Occurrences min-max: 0-1 +- Occurrences min-max: 1-1 - Optional attributes: absolute absolute @@ -7690,7 +6678,7 @@ absolute This attribute specifies whether the timestamps are absolute or relative to the startup time of the service. -- Full path: //OpenSplice/NetworkService/Tracing/Timestamps[@absolute] +- Full path: /NetworkService/Tracing/Timestamps/absolute - Format: boolean - Default value: true - Required: false @@ -7700,7 +6688,7 @@ Categories This element contains the logging properties for various networking categories. -- Full path: //OpenSplice/NetworkService/Tracing/Categories +- Full path: /NetworkService/Tracing/Categories - Occurrences min-max: 1-1 - Child elements: Default, Configuration, Construction, Destruction, Mainloop, Groups, Send, Receive, Throttling, Test, Discovery @@ -7711,11 +6699,10 @@ Default explicitly specified. Level 0 indicates no tracing, level 6 indicates the most detailed level of tracing. -- Full path: //OpenSplice/NetworkService/Tracing/Categories/Default +- Full path: /NetworkService/Tracing/Categories/Default - Format: integer - Default value: 0 -- Valid values: 0 / 6 -- Occurrences min-max: 0-1 +- Occurrences min-max: 1-1 Configuration ^^^^^^^^^^^^^ @@ -7725,10 +6712,9 @@ Configuration Level 0 indicates no tracing, level 6 indicates the most detailed level of tracing. -- Full path: //OpenSplice/NetworkService/Tracing/Categories/Configuration +- Full path: /NetworkService/Tracing/Categories/Configuration - Format: integer - Default value: 0 -- Valid values: 0 / 6 - Occurrences min-max: 0-1 Construction @@ -7739,10 +6725,9 @@ Construction Level 0 indicates no tracing, level 6 indicates the most detailed level of tracing. -- Full path: //OpenSplice/NetworkService/Tracing/Categories/Construction +- Full path: /NetworkService/Tracing/Categories/Construction - Format: integer - Default value: 0 -- Valid values: 0 / 6 - Occurrences min-max: 0-1 Destruction @@ -7753,10 +6738,9 @@ Destruction NetworkService terminates. Level 0 indicates no tracing, level 6 indicates the most detailed level of tracing. -- Full path: //OpenSplice/NetworkService/Tracing/Categories/Destruction +- Full path: /NetworkService/Tracing/Categories/Destruction - Format: integer - Default value: 0 -- Valid values: 0 / 6 - Occurrences min-max: 0-1 Mainloop @@ -7767,10 +6751,9 @@ Mainloop Level 0 indicates no tracing, level 6 indicates the most detailed level of tracing. -- Full path: //OpenSplice/NetworkService/Tracing/Categories/Mainloop +- Full path: /NetworkService/Tracing/Categories/Mainloop - Format: integer - Default value: 0 -- Valid values: 0 / 6 - Occurrences min-max: 0-1 Groups @@ -7781,10 +6764,9 @@ Groups Level 0 indicates no tracing, level 6 indicates the most detailed level of tracing. -- Full path: //OpenSplice/NetworkService/Tracing/Categories/Groups +- Full path: /NetworkService/Tracing/Categories/Groups - Format: integer - Default value: 0 -- Valid values: 0 / 6 - Occurrences min-max: 0-1 Send @@ -7795,10 +6777,9 @@ Send Level 0 indicates no tracing, level 6 indicates the most detailed level of tracing. -- Full path: //OpenSplice/NetworkService/Tracing/Categories/Send +- Full path: /NetworkService/Tracing/Categories/Send - Format: integer - Default value: 0 -- Valid values: 0 / 6 - Occurrences min-max: 0-1 Receive @@ -7809,10 +6790,9 @@ Receive Level 0 indicates no tracing, level 6 indicates the most detailed level of tracing. -- Full path: //OpenSplice/NetworkService/Tracing/Categories/Receive +- Full path: /NetworkService/Tracing/Categories/Receive - Format: integer - Default value: 0 -- Valid values: 0 / 6 - Occurrences min-max: 0-1 Throttling @@ -7823,10 +6803,9 @@ Throttling Level 0 indicates no tracing, level 6 indicates the most detailed level of tracing. -- Full path: //OpenSplice/NetworkService/Tracing/Categories/Throttling +- Full path: /NetworkService/Tracing/Categories/Throttling - Format: integer - Default value: 0 -- Valid values: 0 / 6 - Occurrences min-max: 0-1 Test @@ -7837,10 +6816,9 @@ Test Level 0 indicates no tracing, level 6 indicates the most detailed level of tracing. -- Full path: //OpenSplice/NetworkService/Tracing/Categories/Test +- Full path: /NetworkService/Tracing/Categories/Test - Format: integer - Default value: 0 -- Valid values: 0 / 6 - Occurrences min-max: 0-1 Discovery @@ -7851,10 +6829,9 @@ Discovery Level 0 indicates no tracing, level 6 indicates the most detailed level of tracing. -- Full path: //OpenSplice/NetworkService/Tracing/Categories/Discovery +- Full path: /NetworkService/Tracing/Categories/Discovery - Format: integer - Default value: 0 -- Valid values: 0 / 6 - Occurrences min-max: 0-1 Compression @@ -7871,7 +6848,7 @@ Compression It is imperative that all nodes exchanging compressed data have the same configuration in this section. -- Full path: //OpenSplice/NetworkService/Compression +- Full path: /NetworkService/Compression - Occurrences min-max: 0-1 - Optional attributes: PluginLibrary, PluginInitFunction, PluginParameter @@ -7883,7 +6860,7 @@ PluginLibrary the network data. This may be left blank for the built-in compressors. -- Full path: //OpenSplice/NetworkService/Compression[@PluginLibrary] +- Full path: /NetworkService/Compression/PluginLibrary - Format: string - Default value: "" - Required: false @@ -7897,7 +6874,7 @@ PluginInitFunction ospl_comp_lzf_init and ospl_comp_snappy_init but for convenience they may be specified here as as zlib, lzf or snappy. -- Full path: //OpenSplice/NetworkService/Compression[@PluginInitFunction] +- Full path: /NetworkService/Compression/PluginInitFunction - Format: string - Default value: "" - Required: false @@ -7911,7 +6888,7 @@ PluginParameter the zlib compressor is configured with an integer between 0 (for no compression) to 9 (for maximum compression). -- Full path: //OpenSplice/NetworkService/Compression[@PluginParameter] +- Full path: /NetworkService/Compression/PluginParameter - Format: string - Default value: "" - Required: false @@ -7921,7 +6898,7 @@ NetworkingBridgeService The root element of a networking bridge service configuration. -- Full path: //OpenSplice/NetworkingBridgeService +- Full path: /NetworkingBridgeService - Occurrences min-max: 0-* - Required attributes: name @@ -7930,7 +6907,7 @@ name This attribute identifies the configuration for the Networking Bridge Service. Multiple service configurations can be specified in one single XML file. The actual applicable configuration is determined by the value of the name attribute, which must match the specified under the element OpenSplice/Domain/Service[@name] in the Domain Service configuration. -- Full path: //OpenSplice/NetworkingBridgeService[@name] +- Full path: /NetworkingBridgeService/name - Format: string - Default value: networkingbridge - Required: true @@ -7940,7 +6917,7 @@ Exclude This element specifies which partition/topic combinations may not be forwarded. -- Full path: //OpenSplice/NetworkingBridgeService/Exclude +- Full path: /NetworkingBridgeService/Exclude - Occurrences min-max: 0-* Entry @@ -7948,16 +6925,16 @@ Entry This element configures a single partition/topic combination for exclusion in the set of forwarded partition/topic combinations. -- Full path: //OpenSplice/NetworkingBridgeService/Exclude/Entry +- Full path: /NetworkingBridgeService/Exclude/Entry - Occurrences min-max: 0-* - Required attributes: DCPSPartitionTopic DCPSPartitionTopic ^^^^^^^^^^^^^^^^^^ -This attribute specifies a partition and a topic expression, separated by a single '.', that are used to determine if a given partition and topic will be excluded w.r.t. forwarding. The expressions may use the usual wildcards '\*' and '?'. +This attribute specifies a partition and a topic expression, separated by a single '.', that are used to determine if a given partition and topic will be excluded w.r.t. forwarding. The expressions may use the usual wildcards '*' and '?'. -- Full path: //OpenSplice/NetworkingBridgeService/Exclude/Entry[@DCPSPartitionTopic] +- Full path: /NetworkingBridgeService/Exclude/Entry/DCPSPartitionTopic - Format: string - Default value: n/a - Required: true @@ -7967,7 +6944,7 @@ Include This element specifies which partition/topic combinations are to be forwarded, provided they are not listed in the Exclude section. -- Full path: //OpenSplice/NetworkingBridgeService/Include +- Full path: /NetworkingBridgeService/Include - Occurrences min-max: 0-* Entry @@ -7975,16 +6952,16 @@ Entry This element configures a single partition/topic combination for inclusion in the set of forwarded partition/topic combinations. -- Full path: //OpenSplice/NetworkingBridgeService/Include/Entry +- Full path: /NetworkingBridgeService/Include/Entry - Occurrences min-max: 0-* - Required attributes: DCPSPartitionTopic DCPSPartitionTopic ^^^^^^^^^^^^^^^^^^ -This attribute specifies a partition and a topic expression, separated by a single '.', that are used to determine if a given partition and topic will be included w.r.t. forwarding. The expressions may use the usual wildcards '\*' and '?'. +This attribute specifies a partition and a topic expression, separated by a single '.', that are used to determine if a given partition and topic will be included w.r.t. forwarding. The expressions may use the usual wildcards '*' and '?'. -- Full path: //OpenSplice/NetworkingBridgeService/Include/Entry[@DCPSPartitionTopic] +- Full path: /NetworkingBridgeService/Include/Entry/DCPSPartitionTopic - Format: string - Default value: n/a - Required: true @@ -7994,7 +6971,7 @@ Tracing The Tracing element controls the amount and type of information that is written into the tracing log by the DDSI service. This is useful to track the DDSI service during application development. -- Full path: //OpenSplice/NetworkingBridgeService/Tracing +- Full path: /NetworkingBridgeService/Tracing - Occurrences min-max: 0-* - Child elements: AppendToFile, EnableCategory, OutputFile, Verbosity @@ -8003,7 +6980,7 @@ AppendToFile This option specifies whether the output is to be appended to an existing log file. The default is to create a new log file each time, which is generally the best option if a detailed log is generated. -- Full path: //OpenSplice/NetworkingBridgeService/Tracing/AppendToFile +- Full path: /NetworkingBridgeService/Tracing/AppendToFile - Format: boolean - Default value: false - Occurrences min-max: 0-1 @@ -8020,7 +6997,7 @@ This element enables individual logging categories. These are enabled in additio In addition, there is the keyword *trace* that enables all but *radmin* -- Full path: //OpenSplice/NetworkingBridgeService/Tracing/EnableCategory +- Full path: /NetworkingBridgeService/Tracing/EnableCategory - Format: string - Occurrences min-max: 0-1 @@ -8029,7 +7006,7 @@ OutputFile This option specifies where the logging is printed to. Note that *stdout* and *stderr* are treated as special values, representing "standard out" and "standard error" respectively. No file is created unless logging categories are enabled using the Tracing/Verbosity or Tracing/EnabledCategory settings. -- Full path: //OpenSplice/NetworkingBridgeService/Tracing/OutputFile +- Full path: /NetworkingBridgeService/Tracing/OutputFile - Format: string - Default value: nwbridge.log - Occurrences min-max: 0-1 @@ -8048,7 +7025,7 @@ This element enables standard groups of categories, based on a desired verbosity While *none* prevents any message from being written to a NetworkingBridge log file, warnings and errors are still logged in the ospl-info.log and ospl-error.log files. -- Full path: //OpenSplice/NetworkingBridgeService/Tracing/Verbosity +- Full path: /NetworkingBridgeService/Tracing/Verbosity - Format: enumeration - Default value: none - Valid values: finest, fine, config, info, warning, severe, none @@ -8059,7 +7036,7 @@ Watchdog This element specifies the type of OS scheduling class will be used by the thread that announces its liveliness periodically. -- Full path: //OpenSplice/NetworkingBridgeService/Watchdog +- Full path: /NetworkingBridgeService/Watchdog - Occurrences min-max: 0-* Scheduling @@ -8067,7 +7044,7 @@ Scheduling This element specifies the type of OS scheduling class will be used by the thread that announces its liveliness periodically. -- Full path: //OpenSplice/NetworkingBridgeService/Watchdog/Scheduling +- Full path: /NetworkingBridgeService/Watchdog/Scheduling - Occurrences min-max: 0-1 - Child elements: Class, Priority @@ -8076,7 +7053,7 @@ Class This element specifies the thread scheduling class that will be used by the watchdog thread. The user may need the appropriate privileges from the underlying operating system to be able to assign some of the privileged scheduling classes. -- Full path: //OpenSplice/NetworkingBridgeService/Watchdog/Scheduling/Class +- Full path: /NetworkingBridgeService/Watchdog/Scheduling/Class - Format: enumeration - Default value: default - Valid values: realtime, timeshare, default @@ -8087,7 +7064,7 @@ Priority This element specifies the thread priority. Only priorities that are supported by the underlying operating system can be assigned to this element. The user may need special privileges from the underlying operating system to be able to assign some of the privileged priorities. -- Full path: //OpenSplice/NetworkingBridgeService/Watchdog/Scheduling/Priority +- Full path: /NetworkingBridgeService/Watchdog/Scheduling/Priority - Format: integer - Default value: 0 - Occurrences min-max: 0-1 @@ -8098,179 +7075,68 @@ priority_kind This attribute specifies whether the specified Priority is a relative or absolute priority. -- Full path: //OpenSplice/NetworkingBridgeService/Watchdog/Scheduling/Priority[@priority_kind] +- Full path: /NetworkingBridgeService/Watchdog/Scheduling/Priority/priority_kind - Format: enumeration - Default value: relative - Valid values: relative, absolute - Required: false -DDSI2EService -************* +DDSI2Service +************ -The root element of a DDSI2E networking service configuration. +The root element of a DDSI2 networking service configuration. -- Full path: //OpenSplice/DDSI2EService +- Full path: /DDSI2Service - Occurrences min-max: 0-* - Required attributes: name name ==== -This attribute identifies the configuration for the DDSI2E Service. Multiple DDSI2E service configurations can be specified in one single resource. The actual applicable configuration is determined by the value of the name attribute, which must match the specified under the element OpenSplice/Domain/Service[@name] in the Domain Service configuration. +This attribute identifies the configuration for the DDSI2 Service. Multiple DDSI2 service configurations can be specified in one single resource. The actual applicable configuration is determined by the value of the name attribute, which must match the specified under the element OpenSplice/Domain/Service[@name] in the Domain Service configuration. -- Full path: //OpenSplice/DDSI2EService[@name] +- Full path: /DDSI2Service/name - Format: string -- Default value: ddsi2e +- Default value: ddsi2 - Required: true -Channels -======== +Compatibility +============= -This element is used to group a set of channels. The channels are independent data paths through DDSI2E and by using separate threads and setting their priorities appropriately, chanenls can be used to map transport priorities to operating system scheduler priorities, ensuring system-wide end-to-end priority preservation. +The Compatibility elements allows specifying various settings related to compatability with standards and with other DDSI implementations. -- Full path: //OpenSplice/DDSI2EService/Channels +- Full path: /DDSI2Service/Compatibility - Occurrences min-max: 0-1 +- Child elements: AckNackNumbitsEmptySet, ArrivalOfDataAssertsPpAndEpLiveliness, AssumeRtiHasPmdEndpoints, ExplicitlyPublishQosSetToDefault, ManySocketsMode, RespondToRtiInitZeroAckWithInvalidHeartbeat, StandardsConformance -Channel -------- - -This element defines a channel. - -- Full path: //OpenSplice/DDSI2EService/Channels/Channel -- Occurrences min-max: 0-42 -- Child elements: AuxiliaryBandwidthLimit, DataBandwidthLimit, DiffServField, QueueSize -- Required attributes: Name -- Optional attributes: TransportPriority, Resolution - -Name -^^^^ - -This attribute specifies name of this channel. The name should uniquely identify the channel. - -- Full path: //OpenSplice/DDSI2EService/Channels/Channel[@Name] -- Format: string -- Default value: n/a -- Required: true +AckNackNumbitsEmptySet +---------------------- -TransportPriority -^^^^^^^^^^^^^^^^^ +This element governs the representation of an acknowledgement message that does not also negatively-acknowledge some samples. If set to 0, the generated acknowledgements have an invalid form and will be reject by the strict and pedantic conformance modes, but several other implementation require this setting for smooth interoperation. -This attribute sets the transport priority threshold for the channel. Each DCPS data writer has a "transport_priority" QoS and this QoS is used to select a channel for use by this writer. The selected channel is the one with the largest threshold not greater than the writer's transport priority, and if no such channel exists, the channel with the lowest threshold. +If set to 1, all acknowledgements sent by DDSI2 adhere the form of acknowledgement messages allowed by the standard, but this causes problems when interoperating with these other implementations. The strict and pedantic standards conformance modes always overrule a AckNackNumbitsEmptySet=0 to prevent the transmitting of invalid messages. -- Full path: //OpenSplice/DDSI2EService/Channels/Channel[@TransportPriority] +- Full path: /DDSI2Service/Compatibility/AckNackNumbitsEmptySet - Format: integer - Default value: 0 -- Required: false - -AuxiliaryBandwidthLimit -^^^^^^^^^^^^^^^^^^^^^^^ +- Occurrences min-max: 0-1 -This element specifies the maximum transmit rate of auxiliary traffic on this channel (e.g. retransmits, heartbeats, etc). Bandwidth limiting uses a leaky bucket scheme. The default value "inf" means DDSI2E imposes no limitation, the underlying operating system and hardware will likely limit the maimum transmit rate. +ArrivalOfDataAssertsPpAndEpLiveliness +------------------------------------- -The unit must be specified explicitly. Recognised units: *X*b/s, *X*bps for bits/s or *X*B/s, *X*Bps for bytes/s; where *X* is an optional prefix: k for 10 :sup:`3`, Ki for 2 :sup:`10`, M for 10 :sup:`6`, Mi for 2 :sup:`20`, G for 10 :sup:`9`, Gi for 2 :sup:`30`. +This setting is currently ignored (accepted for backwards compatibility). -- Full path: //OpenSplice/DDSI2EService/Channels/Channel/AuxiliaryBandwidthLimit -- Format: string -- Default value: inf +- Full path: /DDSI2Service/Compatibility/ArrivalOfDataAssertsPpAndEpLiveliness +- Format: boolean +- Default value: true - Occurrences min-max: 0-1 -DataBandwidthLimit -^^^^^^^^^^^^^^^^^^ - -This element specifies the maximum transmit rate of new samples and directly related data, for this channel. Bandwidth limiting uses a leaky bucket scheme. The default value "inf" means DDSI2E imposes no limitation, the underlying operating system and hardware will likely limit the maimum transmit rate. +AssumeRtiHasPmdEndpoints +------------------------ -The unit must be specified explicitly. Recognised units: *X*b/s, *X*bps for bits/s or *X*B/s, *X*Bps for bytes/s; where *X* is an optional prefix: k for 10 :sup:`3`, Ki for 2 :sup:`10`, M for 10 :sup:`6`, Mi for 2 :sup:`20`, G for 10 :sup:`9`, Gi for 2 :sup:`30`. +This option assumes ParticipantMessageData endpoints required by the liveliness protocol are present in RTI participants even when not properly advertised by the participant discovery protocol. -- Full path: //OpenSplice/DDSI2EService/Channels/Channel/DataBandwidthLimit -- Format: string -- Default value: inf -- Occurrences min-max: 0-1 - -DiffServField -^^^^^^^^^^^^^ - -This element describes the DiffServ setting the channel will apply to the networking messages. This parameter determines the value of the diffserv field of the IP version 4 packets sent on this channel which allows QoS setting to be applied to the network traffic send on this channel. - -Windows platform support for setting the diffserv field is dependent on the OS version. - -For Windows versions XP SP2 and 2003 to use the diffserv field the following parameter should be added to the register: - - -HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\TcpIp\\Parameters\\DisableUserTOSSetting - - -The type of this parameter is a DWORD and its value should be set to 0 to allow setting of the diffserv field. - - -For Windows version 7 or higher a new API (qWAVE) has been introduced. For these platforms the specified diffserv value is mapped to one of the support traffic types. -The mapping is as follows: 1-8 background traffic; 9-40 excellent traffic; 41-55 audio/video traffic; 56 voice traffic; 57-63 control traffic. -When an application is run without Administrative priveleges then only the diffserv value of 0, 8, 40 or 56 is allowed. - -- Full path: //OpenSplice/DDSI2EService/Channels/Channel/DiffServField -- Format: integer -- Default value: 0 -- Occurrences min-max: 0-1 - -QueueSize -^^^^^^^^^ - -This element specifies the number of messages the network queue for this channel can contain. The OpenSplice kernel writes data to be transmitted to the network queue, and DDSI2E takes them from this queue. If this queue is full when an application tries to write a sample, the sample will be dropped or the writer suspended, depending on the QoS settings of the writer. OpenSplice and its services are optimised for a well-balanced system design, where the queue never becomes full. - -- Full path: //OpenSplice/DDSI2EService/Channels/Channel/QueueSize -- Format: integer -- Default value: 0 -- Occurrences min-max: 0-1 - -Resolution -^^^^^^^^^^ - -This element specifies the interval at which the DDSI2E transmit thread for this channel wakes up, and which controls the smallest latency_budget that has an effect. A shorter latency_budget is rounded to 0. The downside of a reducing this setting is that it increases the number of idle wake-ups of the transmit thread when there is no data to be sent. - -The unit must be specified explicitly. Recognised units: ns, us, ms, s, min, hr, day. - -- Full path: //OpenSplice/DDSI2EService/Channels/Channel[@Resolution] -- Format: string -- Default value: 1s -- Valid values: 0 / 1s -- Required: false - -Compatibility -============= - -The Compatibility elements allows specifying various settings related to compatability with standards and with other DDSI implementations. - -- Full path: //OpenSplice/DDSI2EService/Compatibility -- Occurrences min-max: 0-1 -- Child elements: AckNackNumbitsEmptySet, ArrivalOfDataAssertsPpAndEpLiveliness, AssumeRtiHasPmdEndpoints, ExplicitlyPublishQosSetToDefault, ManySocketsMode, RespondToRtiInitZeroAckWithInvalidHeartbeat, StandardsConformance - -AckNackNumbitsEmptySet ----------------------- - -This element governs the representation of an acknowledgement message that does not also negatively-acknowledge some samples. If set to 0, the generated acknowledgements have an invalid form and will be reject by the strict and pedantic conformance modes, but several other implementation require this setting for smooth interoperation. - -If set to 1, all acknowledgements sent by DDSI2E adhere the form of acknowledgement messages allowed by the standard, but this causes problems when interoperating with these other implementations. The strict and pedantic standards conformance modes always overrule an AckNackNumbitsEmptySet=0 to prevent the transmitting of invalid messages. - -- Full path: //OpenSplice/DDSI2EService/Compatibility/AckNackNumbitsEmptySet -- Format: integer -- Default value: 0 -- Occurrences min-max: 0-1 - -ArrivalOfDataAssertsPpAndEpLiveliness -------------------------------------- - -When set to true, arrival of a message from a peer asserts liveliness of that peer. When set to false, only SPDP and explicit lease renewals have this effect. - -- Full path: //OpenSplice/DDSI2EService/Compatibility/ArrivalOfDataAssertsPpAndEpLiveliness -- Format: boolean -- Default value: true -- Occurrences min-max: 0-1 - -AssumeRtiHasPmdEndpoints ------------------------- - -This option assumes ParticipantMessageData endpoints required by the liveliness protocol are present in RTI participants even when not properly advertised by the participant discovery protocol. - -- Full path: //OpenSplice/DDSI2EService/Compatibility/AssumeRtiHasPmdEndpoints +- Full path: /DDSI2Service/Compatibility/AssumeRtiHasPmdEndpoints - Format: boolean - Default value: false - Occurrences min-max: 0-1 @@ -8282,7 +7148,7 @@ This element specifies whether QoS settings set to default values are explicitly When interoperability is required with an implementation that does not follow the specifications in this regard, setting this option to true will help. -- Full path: //OpenSplice/DDSI2EService/Compatibility/ExplicitlyPublishQosSetToDefault +- Full path: /DDSI2Service/Compatibility/ExplicitlyPublishQosSetToDefault - Format: boolean - Default value: false - Occurrences min-max: 0-1 @@ -8290,11 +7156,11 @@ When interoperability is required with an implementation that does not follow th ManySocketsMode --------------- -This option specifies whether a network socket will be created for each domain participant on a host. The specification seems to assume that each participant has a unique address, and setting this option will ensure this to be the case. This is not the defeault. +This option specifies whether a network socket will be created for each domain participant on a host. The specification seems to assume that each participant has a unique address, and setting this option will ensure this to be the case. This is not the default. -Disabling it slightly improves performance and reduces network traffic somewhat. It also causes the set of port numbers needed by DDSI2E to become predictable, which may be useful for firewall and NAT configuration. +Disabling it slightly improves performance and reduces network traffic somewhat. It also causes the set of port numbers needed by DDSI2 to become predictable, which may be useful for firewall and NAT configuration. -- Full path: //OpenSplice/DDSI2EService/Compatibility/ManySocketsMode +- Full path: /DDSI2Service/Compatibility/ManySocketsMode - Format: boolean - Default value: false - Occurrences min-max: 0-1 @@ -8306,7 +7172,7 @@ This element allows a closer mimicking of the behaviour of some other DDSI imple The latter is fully compliant with the specification, and no adverse effects have been observed. It is the default. -- Full path: //OpenSplice/DDSI2EService/Compatibility/RespondToRtiInitZeroAckWithInvalidHeartbeat +- Full path: /DDSI2Service/Compatibility/RespondToRtiInitZeroAckWithInvalidHeartbeat - Format: boolean - Default value: false - Occurrences min-max: 0-1 @@ -8314,7 +7180,7 @@ The latter is fully compliant with the specification, and no adverse effects hav StandardsConformance -------------------- -This element sets the level of standards conformance of this instance of the DDSI2E Service. Stricter conformance typically means less interoperability with other implementations. Currently three modes are defined: +This element sets the level of standards conformance of this instance of the DDSI2 Service. Stricter conformance typically means less interoperability with other implementations. Currently three modes are defined: - *pedantic*: very strictly conform to the specification, ultimately for compliancy testing, but currently of little value because it adheres even to what will most likely turn out to be editing errors in the DDSI standard. Arguably, as long as no errata have been published it is the current text that is in effect, and that is what pedantic currently does. - *strict*: a slightly less strict view of the standard than does pedantic: it follows the established behaviour where the standard is obviously in error. @@ -8322,7 +7188,7 @@ This element sets the level of standards conformance of this instance of the DDS The default setting is "lax". -- Full path: //OpenSplice/DDSI2EService/Compatibility/StandardsConformance +- Full path: /DDSI2Service/Compatibility/StandardsConformance - Format: enumeration - Default value: lax - Valid values: lax, strict, pedantic @@ -8333,36 +7199,28 @@ Discovery The Discovery element allows specifying various parameters related to the discovery of peers. -- Full path: //OpenSplice/DDSI2EService/Discovery +- Full path: /DDSI2Service/Discovery - Occurrences min-max: 0-1 -- Child elements: AdvertiseBuiltinTopicWriters, DefaultMulticastAddress, DomainId, GenerateBuiltinTopics, LocalDiscoveryPartition, MaxAutoParticipantIndex, ParticipantIndex, SPDPInterval, SPDPMulticastAddress - -AdvertiseBuiltinTopicWriters ----------------------------- - -This element controls whether or not DDSI2E advertises writers for the built-in topics from its discovery for backwards compatibility with older OpenSplice versions. +- Child elements: DSClusterLeaseDuration, DomainId, GenerateBuiltinTopics, LocalDiscoveryPartition, MaxAutoParticipantIndex, ParticipantIndex, SPDPInterval, SPDPMulticastAddress -- Full path: //OpenSplice/DDSI2EService/Discovery/AdvertiseBuiltinTopicWriters -- Format: boolean -- Default value: true -- Occurrences min-max: 0-1 +DSClusterLeaseDuration +---------------------- -DefaultMulticastAddress ------------------------ +This element specifies the lease duration for entities discovered through a discovery service. -This element specifies the default multicast address for all traffic other than participant discovery packets. It defaults to Discovery/SPDPMulticastAddress. +Valid values are finite durations with an explicit unit or the keyword 'inf' for infinity. Recognised units: ns, us, ms, s, min, hr, day. -- Full path: //OpenSplice/DDSI2EService/Discovery/DefaultMulticastAddress +- Full path: /DDSI2Service/Discovery/DSClusterLeaseDuration - Format: string -- Default value: auto +- Default value: 300 s - Occurrences min-max: 0-1 DomainId -------- -This element allows overriding of the DDS Domain Id that is used for DDSI2E. +This element allows overriding of the DDS Domain Id that is used for this DDSI2 service. -- Full path: //OpenSplice/DDSI2EService/Discovery/DomainId +- Full path: /DDSI2Service/Discovery/DomainId - Format: string - Default value: default - Occurrences min-max: 0-1 @@ -8370,9 +7228,9 @@ This element allows overriding of the DDS Domain Id that is used for DDSI2E. GenerateBuiltinTopics --------------------- -This element controls whether or not DDSI2E generates built-in topics from its discovery. When disabled, it relies on the durability service. +This element controls whether or not the DDSI2 service generates built-in topics from its discovery. When disabled, it relies on the durability service. -- Full path: //OpenSplice/DDSI2EService/Discovery/GenerateBuiltinTopics +- Full path: /DDSI2Service/Discovery/GenerateBuiltinTopics - Format: boolean - Default value: true - Occurrences min-max: 0-1 @@ -8380,9 +7238,9 @@ This element controls whether or not DDSI2E generates built-in topics from its d LocalDiscoveryPartition ----------------------- -This element controls which partition is monitored by DDSI2E for built-in topics describing entities the it mirrors in DDSI. +This element controls which partition is monitored by DDSI2 for built-in topics describing entities the it mirrors in DDSI. -- Full path: //OpenSplice/DDSI2EService/Discovery/LocalDiscoveryPartition +- Full path: /DDSI2Service/Discovery/LocalDiscoveryPartition - Format: string - Default value: __BUILT_IN_PARTITION__ - Occurrences min-max: 0-1 @@ -8390,9 +7248,9 @@ This element controls which partition is monitored by DDSI2E for built-in topics MaxAutoParticipantIndex ----------------------- -This element specifies the maximum DDSI participant index selected by this instance of the DDSI2E service if the Discovery/ParticipantIndex is "auto". +This element specifies the maximum DDSI participant index selected by this instance of the DDSI service if the Discovery/ParticipantIndex is "auto". -- Full path: //OpenSplice/DDSI2EService/Discovery/MaxAutoParticipantIndex +- Full path: /DDSI2Service/Discovery/MaxAutoParticipantIndex - Format: integer - Default value: 9 - Occurrences min-max: 0-1 @@ -8400,7 +7258,7 @@ This element specifies the maximum DDSI participant index selected by this insta ParticipantIndex ---------------- -This element specifies the DDSI participant index used by this instance of the DDSI2E service for discovery purposes. Only one such participant id is used, independent of the number of actual DomainParticipants on the node. It is either: +This element specifies the DDSI participant index used by this instance of the DDSI service for discovery purposes. Only one such participant id is used, independent of the number of actual DomainParticipants on the node. It is either: - *auto*: which will attempt to automatically determine an available participant index (see also Discovery/MaxAutoParticipantIndex), or - a non-negative integer less than 120, or @@ -8408,7 +7266,7 @@ This element specifies the DDSI participant index used by this instance of the D The default is *auto*. The participant index is part of the port number calculation and if predictable port numbers are needed and fixing the participant index has no adverse effects, it is recommended that the second be option be used. -- Full path: //OpenSplice/DDSI2EService/Discovery/ParticipantIndex +- Full path: /DDSI2Service/Discovery/ParticipantIndex - Format: string - Default value: auto - Occurrences min-max: 0-1 @@ -8418,7 +7276,7 @@ Peers This element statically configures addresses for discovery. -- Full path: //OpenSplice/DDSI2EService/Discovery/Peers +- Full path: /DDSI2Service/Discovery/Peers - Occurrences min-max: 0-1 Group @@ -8426,7 +7284,7 @@ Group This element statically configures a fault tolerant group of addresses for discovery. Each member of the group is tried in sequence until one succeeds. -- Full path: //OpenSplice/DDSI2EService/Discovery/Peers/Group +- Full path: /DDSI2Service/Discovery/Peers/Group - Occurrences min-max: 0-* Peer @@ -8434,16 +7292,16 @@ Peer This element statically configures an addresses for discovery. -- Full path: //OpenSplice/DDSI2EService/Discovery/Peers/Group/Peer +- Full path: /DDSI2Service/Discovery/Peers/Group/Peer - Occurrences min-max: 0-* - Required attributes: Address Address +++++++ -This element specifies an IP address to which discovery packets must be sent, in addition to the default multicast address (see also General/AllowMulticast). Both a hostnames and a numerical IP address is accepted; the hostname or IP address may be suffixed with :PORT to explicitly set the port to which it must be sent. Multiple Peers may be specified. +This element specifies an IP address to which discovery packets must be sent, in addition to the default multicast address (see also General/AllowMulticast and Internal/SuppressSPDPMulticast). Both a hostnames and a numerical IP address is accepted; the hostname or IP address may be suffixed with :PORT to explicitly set the port to which it must be sent. Multiple Peers may be specified. -- Full path: //OpenSplice/DDSI2EService/Discovery/Peers/Group/Peer[@Address] +- Full path: /DDSI2Service/Discovery/Peers/Group/Peer/Address - Format: string - Default value: n/a - Required: true @@ -8451,18 +7309,18 @@ This element specifies an IP address to which discovery packets must be sent, in Peer ^^^^ -This element statically configures an addresses for discovery. +This element statically configures an address for discovery. -- Full path: //OpenSplice/DDSI2EService/Discovery/Peers/Peer +- Full path: /DDSI2Service/Discovery/Peers/Peer - Occurrences min-max: 0-* - Required attributes: Address Address ~~~~~~~ -This element specifies an IP address to which discovery packets must be sent, in addition to the default multicast address (see also General/AllowMulticast). Both a hostnames and a numerical IP address is accepted; the hostname or IP address may be suffixed with :PORT to explicitly set the port to which it must be sent. Multiple Peers may be specified. +This element specifies an IP address to which discovery packets must be sent, in addition to the default multicast address (see also General/AllowMulticast and Internal/SuppressSPDPMulticast). Both a hostnames and a numerical IP address is accepted; the hostname or IP address may be suffixed with :PORT to explicitly set the port to which it must be sent. Multiple Peers may be specified. -- Full path: //OpenSplice/DDSI2EService/Discovery/Peers/Peer[@Address] +- Full path: /DDSI2Service/Discovery/Peers/Peer/Address - Format: string - Default value: n/a - Required: true @@ -8472,7 +7330,9 @@ Ports The Ports element allows specifying various parameters related to the port numbers used for discovery. These all have default values specified by the DDSI 2.1 specification and rarely need to be changed. -- Full path: //OpenSplice/DDSI2EService/Discovery/Ports +Valid values are finite durations with an explicit unit or the keyword 'inf' for infinity. Recognised units: ns, us, ms, s, min, hr, day. + +- Full path: /DDSI2Service/Discovery/Ports - Occurrences min-max: 0-1 - Child elements: Base, DomainGain, MulticastDataOffset, MulticastMetaOffset, ParticipantGain, UnicastDataOffset, UnicastMetaOffset @@ -8481,10 +7341,9 @@ Base This element specifies the base port number (refer to the DDSI 2.1 specification, section 9.6.1, constant PB). -- Full path: //OpenSplice/DDSI2EService/Discovery/Ports/Base +- Full path: /DDSI2Service/Discovery/Ports/Base - Format: integer - Default value: 7400 -- Valid values: 1 / 65535 - Occurrences min-max: 0-1 DomainGain @@ -8492,7 +7351,7 @@ DomainGain This element specifies the domain gain, relating domain ids to sets of port numbers (refer to the DDSI 2.1 specification, section 9.6.1, constant DG). -- Full path: //OpenSplice/DDSI2EService/Discovery/Ports/DomainGain +- Full path: /DDSI2Service/Discovery/Ports/DomainGain - Format: integer - Default value: 250 - Occurrences min-max: 0-1 @@ -8502,7 +7361,7 @@ MulticastDataOffset This element specifies the port number for multicast meta traffic (refer to the DDSI 2.1 specification, section 9.6.1, constant d2). -- Full path: //OpenSplice/DDSI2EService/Discovery/Ports/MulticastDataOffset +- Full path: /DDSI2Service/Discovery/Ports/MulticastDataOffset - Format: integer - Default value: 1 - Occurrences min-max: 0-1 @@ -8512,7 +7371,7 @@ MulticastMetaOffset This element specifies the port number for multicast meta traffic (refer to the DDSI 2.1 specification, section 9.6.1, constant d0). -- Full path: //OpenSplice/DDSI2EService/Discovery/Ports/MulticastMetaOffset +- Full path: /DDSI2Service/Discovery/Ports/MulticastMetaOffset - Format: integer - Default value: 0 - Occurrences min-max: 0-1 @@ -8522,7 +7381,7 @@ ParticipantGain This element specifies the participant gain, relating p0, articipant index to sets of port numbers (refer to the DDSI 2.1 specification, section 9.6.1, constant PG). -- Full path: //OpenSplice/DDSI2EService/Discovery/Ports/ParticipantGain +- Full path: /DDSI2Service/Discovery/Ports/ParticipantGain - Format: integer - Default value: 2 - Occurrences min-max: 0-1 @@ -8532,7 +7391,7 @@ UnicastDataOffset This element specifies the port number for unicast meta traffic (refer to the DDSI 2.1 specification, section 9.6.1, constant d3). -- Full path: //OpenSplice/DDSI2EService/Discovery/Ports/UnicastDataOffset +- Full path: /DDSI2Service/Discovery/Ports/UnicastDataOffset - Format: integer - Default value: 11 - Occurrences min-max: 0-1 @@ -8542,7 +7401,7 @@ UnicastMetaOffset This element specifies the port number for unicast meta traffic (refer to the DDSI 2.1 specification, section 9.6.1, constant d1). -- Full path: //OpenSplice/DDSI2EService/Discovery/Ports/UnicastMetaOffset +- Full path: /DDSI2Service/Discovery/Ports/UnicastMetaOffset - Format: integer - Default value: 10 - Occurrences min-max: 0-1 @@ -8554,10 +7413,9 @@ This element specifies the interval between spontaneous transmissions of partici The unit must be specified explicitly. Recognised units: ns, us, ms, s, min, hr, day. -- Full path: //OpenSplice/DDSI2EService/Discovery/SPDPInterval +- Full path: /DDSI2Service/Discovery/SPDPInterval - Format: string - Default value: 30 s -- Valid values: 0 / 1hr - Occurrences min-max: 0-1 SPDPMulticastAddress @@ -8565,7 +7423,7 @@ SPDPMulticastAddress This element specifies the multicast address that is used as the destination for the participant discovery packets. In IPv4 mode the default is the (standardised) 239.255.0.1, in IPv6 mode it becomes ff02::ffff:239.255.0.1, which is a non-standardised link-local multicast address. -- Full path: //OpenSplice/DDSI2EService/Discovery/SPDPMulticastAddress +- Full path: /DDSI2Service/Discovery/SPDPMulticastAddress - Format: string - Default value: 239.255.0.1 - Occurrences min-max: 0-1 @@ -8573,38 +7431,32 @@ This element specifies the multicast address that is used as the destination for General ======= -The General element specifies overall DDSI2E service settings. +The General element specifies overall DDSI2 service settings. -- Full path: //OpenSplice/DDSI2EService/General +- Full path: /DDSI2Service/General - Occurrences min-max: 0-1 -- Child elements: AllowMulticast, CoexistWithNativeNetworking, DontRoute, EnableMulticastLoopback, ExternalNetworkAddress, ExternalNetworkMask, FragmentSize, MaxMessageSize, MulticastRecvNetworkInterfaceAddresses, MulticastTimeToLive, NetworkInterfaceAddress, StartupModeCoversTransient, StartupModeDuration, UseIPv6 +- Child elements: AllowMulticast, CoexistWithNativeNetworking, DontRoute, EnableMulticastLoopback, ExternalNetworkAddress, ExternalNetworkMask, MulticastRecvNetworkInterfaceAddresses, MulticastTimeToLive, NetworkInterfaceAddress, StartupModeCoversTransient, StartupModeDuration, UseIPv6 AllowMulticast -------------- -This element controls whether DDSI2E uses multicasts for data traffic. - -It is a comma-separated list of some of the following keywords: "spdp", "asm", "ssm", or either of "false" or "true". - - -- *spdp*: enables the use of ASM (any-source multicast) for participant discovery -- *asm*: enables the use of ASM for all traffic (including SPDP) -- *ssm*: enables the use of SSM (source-specific multicast) for all non-SPDP traffic (if supported) +This element controls whether the DDSI2 service uses multicasts for data traffic. +When set to "false", DDSI2 will never advertise multicast addresses and never accept multicast addresses advertised by remote nodes, but it will still listen for multicast packets and perform multicast-based participant discovery. Listening for multicasts can be controlled by General/MulticastRecvNetworkInterfaceAddresses, and transmitting participant discovery multicasts by Internal/SuppressSPDPMulticast. -When set to "false" all multicasting is disabled. The default, "true" enables full use of multicasts. Listening for multicasts can be controlled by General/MulticastRecvNetworkInterfaceAddresses. +The default, "true", enables full use of multicasts. -- Full path: //OpenSplice/DDSI2EService/General/AllowMulticast -- Format: string +- Full path: /DDSI2Service/General/AllowMulticast +- Format: boolean - Default value: true - Occurrences min-max: 0-1 CoexistWithNativeNetworking --------------------------- -This element specifies whether the DDSI2E service operates in conjunction with the OpenSplice RT Networking service. When "false", the DDSI2E service will take care of all communications, including those between OpenSplice nodes; when "true", the DDSI2E service only communicates with DDS implementations other than OpenSplice. In this case the RT Networking service should be configured as well. +This element specifies whether the DDSI2 service operates in conjunction with the OpenSplice RT Networking service. When "false", the DDSI2 service will take care of all communications, including those between OpenSplice nodes; when "true", the DDSI2 service only communicates with DDS implementations other than OpenSplice. In this case the RT Networking service should be configured as well. -- Full path: //OpenSplice/DDSI2EService/General/CoexistWithNativeNetworking +- Full path: /DDSI2Service/General/CoexistWithNativeNetworking - Format: boolean - Default value: false - Occurrences min-max: 0-1 @@ -8614,7 +7466,7 @@ DontRoute This element allows setting the SO_DONTROUTE option for outgoing packets, to bypass the local routing tables. This is generally useful only when the routing tables cannot be trusted, which is highly unusual. -- Full path: //OpenSplice/DDSI2EService/General/DontRoute +- Full path: /DDSI2Service/General/DontRoute - Format: boolean - Default value: false - Occurrences min-max: 0-1 @@ -8622,9 +7474,9 @@ This element allows setting the SO_DONTROUTE option for outgoing packets, to byp EnableMulticastLoopback ----------------------- -This element specifies whether DDSI2E allows IP multicast packets to be visible to all DDSI participants in the same node, including itself. It must be "true" for intra-node multicast communications, but if a node runs only a single DDSI2E service and does not host any other DDSI-capable programs, it should be set to "false" for improved performance. +This element specifies whether the DDSI2 service will allow IP multicast packets to be visible to all DDSI participants in the same node, including itself. It must be "true" for intra-node multicast communications, but if a node runs only a single DDSI2 service and does not host any other DDSI-capable programs, it may be set to "false" for improved performance. -- Full path: //OpenSplice/DDSI2EService/General/EnableMulticastLoopback +- Full path: /DDSI2Service/General/EnableMulticastLoopback - Format: boolean - Default value: true - Occurrences min-max: 0-1 @@ -8632,9 +7484,9 @@ This element specifies whether DDSI2E allows IP multicast packets to be visible ExternalNetworkAddress ---------------------- -This element allows explicitly overruling the network address DDSI2E advertises in the discovery protocol, which by default is the address of the preferred network interface (General/NetworkInterfaceAddress), to allow DDSI2E to communicate across a Network Address Translation (NAT) device. +This element allows explicitly overruling the network address the DDSI2 service advertises in the discovery protocol, which by default is the address of the preferred network interface (General/NetworkInterfaceAddress), to allow DDSI2 to communicate across a Network Address Translation (NAT) device. -- Full path: //OpenSplice/DDSI2EService/General/ExternalNetworkAddress +- Full path: /DDSI2Service/General/ExternalNetworkAddress - Format: string - Default value: auto - Occurrences min-max: 0-1 @@ -8644,53 +7496,25 @@ ExternalNetworkMask This element specifies the network mask of the external network address. This element is relevant only when an external network address (General/ExternalNetworkAddress) is explicitly configured. In this case locators received via the discovery protocol that are within the same external subnet (as defined by this mask) will be translated to an internal address by replacing the network portion of the external address with the corresponding portion of the preferred network interface address. This option is IPv4-only. -- Full path: //OpenSplice/DDSI2EService/General/ExternalNetworkMask +- Full path: /DDSI2Service/General/ExternalNetworkMask - Format: string - Default value: 0.0.0.0 - Occurrences min-max: 0-1 -FragmentSize ------------- - -This element specifies the size of DDSI sample fragments generated by DDSI2E. Samples larger than FragmentSize are fragmented into fragments of FragmentSize bytes each, except the last one, which may be smaller. The DDSI spec mandates a minimum fragment size of 1025 bytes, but DDSI2E will do whatever size is requested, accepting fragments of which the size is at least the minimum of 1025 and FragmentSize. - -The unit must be specified explicitly. Recognised units: B (bytes), kB & KiB (2 :sup:`10` bytes), MB & MiB (2 :sup:`20` bytes), GB & GiB (2 :sup:`30` bytes). - -- Full path: //OpenSplice/DDSI2EService/General/FragmentSize -- Format: string -- Default value: 1280 B -- Occurrences min-max: 0-1 - -MaxMessageSize --------------- - -This element specifies the maximum size of the UDP payload that DDSI2E will generate. DDSI2E will try to maintain this limit within the bounds of the DDSI specification, which means that in some cases (especially for very low values of MaxMessageSize) larger payloads may sporadically be observed (currently up to 1192 B). - -On some networks it may be necessary to set this item to keep the packetsize below the MTU to prevent IP fragmentation. In those cases, it is generally advisable to also consider reducing Internal/FragmentSize. - -The unit must be specified explicitly. Recognised units: B (bytes), kB & KiB (2 :sup:`10` bytes), MB & MiB (2 :sup:`20` bytes), GB & GiB (2 :sup:`30` bytes). - -- Full path: //OpenSplice/DDSI2EService/General/MaxMessageSize -- Format: string -- Default value: 4096 B -- Occurrences min-max: 0-1 - MulticastRecvNetworkInterfaceAddresses -------------------------------------- -This element specifies on which network interfaces DDSI2E listens to multicasts. The following options are available: - +This element specifies on which network interfaces DDSI2 listens to multicasts. The following options are available: +- *preferred*: listen for multicasts on the preferred interface (General/NetworkInterfaceAddress); or - *all*: listen for multicasts on all multicast-capable interfaces; or - *any*: listen for multicasts on the operating system default interface; or -- *preferred*: listen for multicasts on the preferred interface (General/NetworkInterfaceAddress); or - *none*: does not listen for multicasts on any interface; or -- a comma-separated list of network addresses: configures DDSI2E to listen for multicasts on all of the listed addresses. - +- a comma-separated list of network addresses: configures DDSI2 to listen for multicasts on all of the listed addresses. -If DDSI2E is in IPv6 mode and the address of the preferred network interface is a link-local address, "all" is treated as a synonym for "preferred" and a comma-separated list is treated as "preferred" if it contains the preferred interface and as "none" if not. +If DDSI2 is in IPv6 mode and the address of the preferred network interface is a link-local address, "all" is treated as a synonym for "preferred" and a comma-separated list is treated as "preferred" if it contains the preferred interface and as "none" if not. -- Full path: //OpenSplice/DDSI2EService/General/MulticastRecvNetworkInterfaceAddresses +- Full path: /DDSI2Service/General/MulticastRecvNetworkInterfaceAddresses - Format: string - Default value: preferred - Occurrences min-max: 0-1 @@ -8700,18 +7524,17 @@ MulticastTimeToLive This element specifies the time-to-live setting for outgoing multicast packets. -- Full path: //OpenSplice/DDSI2EService/General/MulticastTimeToLive +- Full path: /DDSI2Service/General/MulticastTimeToLive - Format: integer - Default value: 32 -- Valid values: 0 / 255 - Occurrences min-max: 0-1 NetworkInterfaceAddress ----------------------- -This element specifies the preferred network interface for use by DDSI2E. The preferred network interface determines the IP address that DDSI2E advertises in the discovery protocol (but see also General/ExternalNetworkAddress), and is also the only interface over which multicasts are transmitted. The interface can be identified by its IP address, network interface name or network portion of the address. If the value "auto" is entered here, DDSI2E will select what it considers the most suitable interface. +This element specifies the preferred network interface for use by DDSI2. The preferred network interface determines the IP address that DDSI2 advertises in the discovery protocol (but see also General/ExternalNetworkAddress), and is also the only interface over which multicasts are transmitted. The interface can be identified by its IP address, network interface name or network portion of the address. If the value "auto" is entered here, DDSI2 will select what it considers the most suitable interface. -- Full path: //OpenSplice/DDSI2EService/General/NetworkInterfaceAddress +- Full path: /DDSI2Service/General/NetworkInterfaceAddress - Format: string - Default value: auto - Occurrences min-max: 0-1 @@ -8719,9 +7542,9 @@ This element specifies the preferred network interface for use by DDSI2E. The pr StartupModeCoversTransient -------------------------- -This element configures whether startup-mode should also cover transient and persistent data, for configurations where the durability service does not take care of it. Configurations without defined merge policies best leave this enabled. +This element configures whether startup-mode should also cover transient and persistent data, for configurations where the durability servie does not take care of it. Configurations without defined merge policies best leave this enabled. -- Full path: //OpenSplice/DDSI2EService/General/StartupModeCoversTransient +- Full path: /DDSI2Service/General/StartupModeCoversTransient - Format: boolean - Default value: true - Occurrences min-max: 0-1 @@ -8729,26 +7552,25 @@ This element configures whether startup-mode should also cover transient and per StartupModeDuration ------------------- -This element specifies how long the DDSI2E remains in its "startup" mode. While in "startup" mode all volatile reliable data published on the local node is retained as-if it were transient-local data, allowing existing readers on remote nodes to obtain the data even though discovering them takes some time. Best-effort data by definition need not arrive, and transient and persistent data are covered by the durability service. +This element specifies how long the DDSI2 remains in its "startup" mode. While in "startup" mode all volatile reliable data published on the local node is retained as-if it were transient-local data, allowing existing readers on remote nodes to obtain the data even though discovering them takes some time. Best-effort data by definition need not arrive, and transient and persistent data are covered by the durability service. -Once the system is stable, DDSI2E keeps track of the existence of remote readers whether or not matching writers exist locally, avoiding this discovery delay and ensuring this is merely a node startup issue. +Once the system is stable, the DDSI2 service keeps track of the existence of remote readers whether or not matching writers exist locally, avoiding this discovery delay and ensuring this is merely a node startup issue. Setting General/StartupModeDuration to 0s will disable it. The unit must be specified explicitly. Recognised units: ns, us, ms, s, min, hr, day. -- Full path: //OpenSplice/DDSI2EService/General/StartupModeDuration +- Full path: /DDSI2Service/General/StartupModeDuration - Format: string - Default value: 2 s -- Valid values: 0 / 60000 - Occurrences min-max: 0-1 UseIPv6 ------- -This element can be used to DDSI2E use IPv6 instead of IPv4. This is currently an either/or switch. +This element can be used to make DDSI2 service use IPv6 instead of IPv4. This is currently an either/or switch. -- Full path: //OpenSplice/DDSI2EService/General/UseIPv6 +- Full path: /DDSI2Service/General/UseIPv6 - Format: boolean - Default value: false - Occurrences min-max: 0-1 @@ -8758,59 +7580,37 @@ Internal The Internal elements deal with a variety of settings that evolving and that are not necessarily fully supported. For the vast majority of the Internal settings, the functionality per-se is supported, but the right to change the way the options control the functionality is reserved. This includes renaming or moving options. -- Full path: //OpenSplice/DDSI2EService/Internal +- Full path: /DDSI2Service/Internal - Occurrences min-max: 0-1 -- Child elements: AccelerateRexmitBlockSize, AggressiveKeepLastWhc, AggressiveKeepLastWhc, AssumeMulticastCapable, AuxiliaryBandwidthLimit, BuiltinEndpointSet, ConservativeBuiltinReaderStartup, DDSI2DirectMaxThreads, DefragReliableMaxSamples, DefragUnreliableMaxSamples, DeliveryQueueMaxSamples, ForwardAllMessages, ForwardRemoteData, GenerateKeyhash, LateAckMode, LeaseDuration, LegacyFragmentation, LogStackTraces, MaxParticipants, MaxQueuedRexmitBytes, MaxQueuedRexmitMessages, MaxSampleSize, MeasureHbToAckLatency, MinimumSocketReceiveBufferSize, MinimumSocketSendBufferSize, MirrorRemoteEntities, MonitorPort, NackDelay, PreEmptiveAckDelay, PrimaryReorderMaxSamples, PrioritizeRetransmit, RediscoveryBlacklistDuration, ResponsivenessTimeout, RetransmitMerging, RetransmitMergingPeriod, RetryOnRejectBestEffort, RetryOnRejectDuration, SPDPResponseMaxDelay, ScheduleTimeRounding, SecondaryReorderMaxSamples, SquashParticipants, SuppressSPDPMulticast, SynchronousDeliveryLatencyBound, SynchronousDeliveryPriorityThreshold, UnicastResponseToSPDPMessages, UseMulticastIfMreqn, WriterLingerDuration +- Child elements: AccelerateRexmitBlockSize, AggressiveKeepLast1Whc, AssumeMulticastCapable, BuiltinEndpointSet, ConservativeBuiltinReaderStartup, DDSI2DirectMaxThreads, DefragReliableMaxSamples, DefragUnreliableMaxSamples, DeliveryQueueMaxSamples, ForwardAllMessages, ForwardRemoteData, FragmentSize, GenerateKeyhash, LateAckMode, LeaseDuration, LegacyFragmentation, LogStackTraces, MaxMessageSize, MaxParticipants, MaxQueuedRexmitBytes, MaxQueuedRexmitMessages, MaxSampleSize, MeasureHbToAckLatency, MinimumSocketReceiveBufferSize, MinimumSocketSendBufferSize, MirrorRemoteEntities, NackDelay, PreEmptiveAckDelay, PrimaryReorderMaxSamples, ResponsivenessTimeout, RetransmitMerging, RetransmitMergingPeriod, RetryOnRejectBestEffort, RetryOnRejectDuration, SPDPResponseMaxDelay, ScheduleTimeRounding, SecondaryReorderMaxSamples, SquashParticipants, SuppressSPDPMulticast, SynchronousDeliveryLatencyBound, SynchronousDeliveryPriorityThreshold, UnicastResponseToSPDPMessages, WriterLingerDuration AccelerateRexmitBlockSize ------------------------- **Internal** Proxy readers that are assumed to sill be retrieving historical data get this many samples retransmitted when they NACK something, even if some of these samples have sequence numbers outside the set covered by the NACK. -- Full path: //OpenSplice/DDSI2EService/Internal/AccelerateRexmitBlockSize +- Full path: /DDSI2Service/Internal/AccelerateRexmitBlockSize - Format: integer - Default value: 0 - Occurrences min-max: 0-1 -AggressiveKeepLastWhc ---------------------- - -**Internal** This element controls whether to drop a reliable sample from a DDSI2E WHC before all readers have acknowledged it as soon as a later sample becomes available. It only affects DCPS data writers with a history QoS setting of KEEP_LAST with depth 1. The default setting, *false*, mimics the behaviour of the OpenSplice RT networking and is necessary to make the behaviour of wait_for_acknowledgements() consistent across the networking services. - -- Full path: //OpenSplice/DDSI2EService/Internal/AggressiveKeepLastWhc -- Format: boolean -- Default value: true -- Occurrences min-max: 0-1 - -AggressiveKeepLastWhc ---------------------- +AggressiveKeepLast1Whc +---------------------- -**Internal** This element controls whether to drop a reliable sample from a DDSI2E WHC before all readers have acknowledged it as soon as a later sample becomes available. It only affects DCPS data writers with a history QoS setting of KEEP_LAST with depth 1. The default setting, *false*, mimics the behaviour of the OpenSplice RT networking and is necessary to make the behaviour of wait_for_acknowledgements() consistent across the networking services. +**Internal** This element controls whether to drop a reliable sample from a DDSI2 WHC before all readers have acknowledged it as soon as a later sample becomes available. It only affects DCPS data writers with a history QoS setting of KEEP_LAST with depth 1. The default setting, *false*, mimics the behaviour of the OpenSplice RT networking and is necessary to make the behaviour of wait_for_acknowledgements() consistent across the networking services. -- Full path: //OpenSplice/DDSI2EService/Internal/AggressiveKeepLastWhc +- Full path: /DDSI2Service/Internal/AggressiveKeepLast1Whc - Format: boolean -- Default value: true +- Default value: false - Occurrences min-max: 0-1 AssumeMulticastCapable ---------------------- -**Internal** This element controls which network interfaces are assumed to be capable of multicasting even when the interface flags returned by the operating system state it is not (this provides a workaround for some platforms). It is a comma-separated lists of patterns (with ? and \* wildcards) against which the interface names are matched. - -- Full path: //OpenSplice/DDSI2EService/Internal/AssumeMulticastCapable -- Format: string -- Occurrences min-max: 0-1 - -AuxiliaryBandwidthLimit ------------------------ - -**Internal** This element specifies the maximum transmit rate of auxiliary traffic not bound to a specific channel, such as discovery traffic, as well as auxiliary traffic related to a certain channel if that channel has elected to share this global AuxiliaryBandwidthLimit. Bandwidth limiting uses a leaky bucket scheme. The default value "inf" means DDSI2E imposes no limitation, the underlying operating system and hardware will likely limit the maimum transmit rate. - -The unit must be specified explicitly. Recognised units: *X*b/s, *X*bps for bits/s or *X*B/s, *X*Bps for bytes/s; where *X* is an optional prefix: k for 10 :sup:`3`, Ki for 2 :sup:`10`, M for 10 :sup:`6`, Mi for 2 :sup:`20`, G for 10 :sup:`9`, Gi for 2 :sup:`30`. +**Internal** This element controls which network interfaces are assumed to be capable of multicasting even when the interface flags returned by the operating system state it is not (this provides a workaround for some platforms). It is a comma-separated lists of patterns (with ? and * wildcards) against which the interface names are matched. -- Full path: //OpenSplice/DDSI2EService/Internal/AuxiliaryBandwidthLimit +- Full path: /DDSI2Service/Internal/AssumeMulticastCapable - Format: string -- Default value: inf - Occurrences min-max: 0-1 BuiltinEndpointSet @@ -8824,7 +7624,7 @@ BuiltinEndpointSet The default is *writers*, as this is thought to be compliant and reasonably efficient. *Minimal* may or may not be compliant but is most efficient, and *full* is inefficient but certain to be compliant. See also Internal/ConservativeBuiltinReaderStartup. -- Full path: //OpenSplice/DDSI2EService/Internal/BuiltinEndpointSet +- Full path: /DDSI2Service/Internal/BuiltinEndpointSet - Format: enumeration - Default value: writers - Valid values: full, writers, minimal @@ -8833,41 +7633,11 @@ The default is *writers*, as this is thought to be compliant and reasonably effi ConservativeBuiltinReaderStartup -------------------------------- -**Internal** This element forces all DDSI2E built-in discovery-related readers to request all historical data, instead of just one for each "topic". There is no indication that any of the current DDSI implementations requires changing of this setting, but it is conceivable that an implementation might track which participants have been informed of the existence of endpoints and which have not been, refusing communication with those that have "can't" know. - -Should it be necessary to hide DDSI2E's shared discovery behaviour, set this to *true* and Internal/BuiltinEndpointSet to *full*. - -- Full path: //OpenSplice/DDSI2EService/Internal/ConservativeBuiltinReaderStartup -- Format: boolean -- Default value: false -- Occurrences min-max: 0-1 - -ControlTopic ------------- - -**Internal** The ControlTopic element allows configured whether DDSI2E provides a special control interface via a predefined topic or not. - -- Full path: //OpenSplice/DDSI2EService/Internal/ControlTopic -- Occurrences min-max: 0-1 -- Child elements: DeafMute -- Optional attributes: enable - -enable -^^^^^^ - -**Internal** This attribute controls whether the DDSI2E control topic is defined and acted upon by DDSI2 - -- Full path: //OpenSplice/DDSI2EService/Internal/ControlTopic[@enable] -- Format: boolean -- Default value: false -- Required: false - -DeafMute -^^^^^^^^ +**Internal** This element forces all DDSI2 built-in discovery-related readers to request all historical data, instead of just one for each "topic". There is no indication that any of the current DDSI implementations requires changing of this setting, but it is conceivable that an implementation might track which participants have been informed of the existence of endpoints and which have not been, refusing communication with those that have "can't" know. -**Internal** This element controls whether DDSI2E defaults to deaf-mute mode or to normal mode. This controls both the initial behaviour and what behaviour it auto-reverts to. +Should it be necessary to hide DDSI2's shared discovery behaviour, set this to *true* and Internal/BuiltinEndpointSet to *full*. -- Full path: //OpenSplice/DDSI2EService/Internal/ControlTopic/DeafMute +- Full path: /DDSI2Service/Internal/ConservativeBuiltinReaderStartup - Format: boolean - Default value: false - Occurrences min-max: 0-1 @@ -8877,7 +7647,7 @@ DDSI2DirectMaxThreads **Internal** This element sets the maximum number of extra threads for an experimental, undocumented and unsupported direct mode. -- Full path: //OpenSplice/DDSI2EService/Internal/DDSI2DirectMaxThreads +- Full path: /DDSI2Service/Internal/DDSI2DirectMaxThreads - Format: integer - Default value: 1 - Occurrences min-max: 0-1 @@ -8885,9 +7655,9 @@ DDSI2DirectMaxThreads DefragReliableMaxSamples ------------------------ -**Internal** This element sets the maximum number of samples that can be defragmented simultaneously for a reliable writer. This has to be large enough to handle retransmissions of historical data in addition to new samples. +**Internal** This element sets the maximum number of samples that can be defragmneted simultaneously for a reliable writer. This has to be large enough to handle retransmissions of historical data in addition to new samples. -- Full path: //OpenSplice/DDSI2EService/Internal/DefragReliableMaxSamples +- Full path: /DDSI2Service/Internal/DefragReliableMaxSamples - Format: integer - Default value: 16 - Occurrences min-max: 0-1 @@ -8897,7 +7667,7 @@ DefragUnreliableMaxSamples **Internal** This element sets the maximum number of samples that can be defragmented simultaneously for a best-effort writers. -- Full path: //OpenSplice/DDSI2EService/Internal/DefragUnreliableMaxSamples +- Full path: /DDSI2Service/Internal/DefragUnreliableMaxSamples - Format: integer - Default value: 4 - Occurrences min-max: 0-1 @@ -8907,7 +7677,7 @@ DeliveryQueueMaxSamples **Internal** This element controls the Maximum size of a delivery queue, expressed in samples. Once a delivery queue is full, incoming samples destined for that queue are dropped until space becomes available again. -- Full path: //OpenSplice/DDSI2EService/Internal/DeliveryQueueMaxSamples +- Full path: /DDSI2Service/Internal/DeliveryQueueMaxSamples - Format: integer - Default value: 256 - Occurrences min-max: 0-1 @@ -8915,9 +7685,9 @@ DeliveryQueueMaxSamples ForwardAllMessages ------------------ -**Internal** Forward all messages from a writer, rather than trying to forward each sample only once. The default of trying to forward each sample only once filters out duplicates for writers in multiple partitions under nearly all circumstances, but may still publish the odd duplicate. Note: the current implementation also can lose in contrived test cases, that publish more than 2\*\*32 samples using a single data writer in conjunction with carefully controlled management of the writer history via cooperating local readers. +**Internal** Forward all messages from a writer, rather than trying to forward each sample only once. The default of trying to forward each sample only once filters out duplicates for writers in multiple partitions under nearly all circumstances, but may still publish the odd duplicate. Note: the current implementation also can lose in contrived test cases, that publish more than 2**32 samples using a single data writer in conjunction with carefully controlled management of the writer history via cooperating local readers. -- Full path: //OpenSplice/DDSI2EService/Internal/ForwardAllMessages +- Full path: /DDSI2Service/Internal/ForwardAllMessages - Format: boolean - Default value: false - Occurrences min-max: 0-1 @@ -8925,12 +7695,24 @@ ForwardAllMessages ForwardRemoteData ----------------- -**Internal** This element controls whether DDSI2E forwards data received from other network services in the domain. +This element controls whether DDSI2 forwards data received from other network services in the domain. -- Full path: //OpenSplice/DDSI2EService/Internal/ForwardRemoteData +- Full path: /DDSI2Service/Internal/ForwardRemoteData - Format: enumeration - Default value: default -- Valid values: false, true, default +- Valid values: false, default, true +- Occurrences min-max: 0-1 + +FragmentSize +------------ + +**Internal** This element specifies the size of DDSI sample fragments generated by DDSI2. Samples larger than FragmentSize are fragmented into fragments of FragmentSize bytes each, except the last one, which may be smaller. The DDSI spec mandates a minimum fragment size of 1025 bytes, but DDSI2 will do whatever size is requested, accepting fragments of which the size is at least the minimum of 1025 and FragmentSize. + +The unit must be specified explicitly. Recognised units: B (bytes), kB & KiB (2 :sup:`10` bytes), MB & MiB (2 :sup:`20` bytes), GB & GiB (2 :sup:`30` bytes). + +- Full path: /DDSI2Service/Internal/FragmentSize +- Format: string +- Default value: 1280 B - Occurrences min-max: 0-1 GenerateKeyhash @@ -8938,7 +7720,7 @@ GenerateKeyhash **Internal** When true, include keyhashes in outgoing data for topics with keys. -- Full path: //OpenSplice/DDSI2EService/Internal/GenerateKeyhash +- Full path: /DDSI2Service/Internal/GenerateKeyhash - Format: boolean - Default value: true - Occurrences min-max: 0-1 @@ -8948,7 +7730,7 @@ LateAckMode **Internal** Ack a sample only when it has been delivered, instead of when committed to delivering it. -- Full path: //OpenSplice/DDSI2EService/Internal/LateAckMode +- Full path: /DDSI2Service/Internal/LateAckMode - Format: boolean - Default value: false - Occurrences min-max: 0-1 @@ -8956,21 +7738,20 @@ LateAckMode LeaseDuration ------------- -**Internal** This setting controls the default participant lease duration. +**Internal** This setting controls the default participant lease duration, with 0s (the default) indicating that it is to be derived from the domain ExpiryTime: either 10% or 1s longer, whichever is shortest. The unit must be specified explicitly. Recognised units: ns, us, ms, s, min, hr, day. -- Full path: //OpenSplice/DDSI2EService/Internal/LeaseDuration +- Full path: /DDSI2Service/Internal/LeaseDuration - Format: string - Default value: 0 s -- Valid values: 0 / 1hr - Occurrences min-max: 0-1 LegacyFragmentation ------------------- -**Internal** This option enables a backwards-compatible, non-compliant setting and interpretation of the control flags in fragmented data messages. To be enabled *only* when requiring interoperability between compliant and non-compliant versions of DDSI2E for large messages. +**Internal** This option enables a backwards-compatible, non-compliant setting and interpretation of the control flags in fragmented data messages. To be enabled *only* when requiring interoperability between compliant and non-compliant versions of DDSI2 for large messages. -- Full path: //OpenSplice/DDSI2EService/Internal/LegacyFragmentation +- Full path: /DDSI2Service/Internal/LegacyFragmentation - Format: boolean - Default value: false - Occurrences min-max: 0-1 @@ -8978,19 +7759,33 @@ LegacyFragmentation LogStackTraces -------------- -**Internal** This element controls whether or not to write stack traces to the DDSI2 trace when a thread fails to make progress (on select platforms only). +This element controls whether or not to write stack traces to the DDSI2 trace when a thread fails to make progress (on select platforms only). -- Full path: //OpenSplice/DDSI2EService/Internal/LogStackTraces +- Full path: /DDSI2Service/Internal/LogStackTraces - Format: boolean -- Default value: true +- Default value: false +- Occurrences min-max: 0-1 + +MaxMessageSize +-------------- + +**Internal** This element specifies the maximum size of the UDP payload that DDSI2 will generate. DDSI2 will try to maintain this limit within the bounds of the DDSI specification, which means that in some cases (especially for very low values of MaxMessageSize) larger payloads may sporadically be observed (currently up to 1192 B). + +On some networks it may be necessary to set this item to keep the packetsize below the MTU to prevent IP fragmentation. In those cases, it is generally advisable to also consider reducing Internal/FragmentSize. + +The unit must be specified explicitly. Recognised units: B (bytes), kB & KiB (2 :sup:`10` bytes), MB & MiB (2 :sup:`20` bytes), GB & GiB (2 :sup:`30` bytes). + +- Full path: /DDSI2Service/Internal/MaxMessageSize +- Format: string +- Default value: 4096 B - Occurrences min-max: 0-1 MaxParticipants --------------- -**Internal** This elements configures the maximum number of DCPS domain participants this DDSI2E instance is willing to service. 0 is unlimited. +**Internal** This elements configures the maximum number of DCPS domain participants this DDSI2 service instance is willing to service. 0 is unlimited. -- Full path: //OpenSplice/DDSI2EService/Internal/MaxParticipants +- Full path: /DDSI2Service/Internal/MaxParticipants - Format: integer - Default value: 0 - Occurrences min-max: 0-1 @@ -8998,13 +7793,13 @@ MaxParticipants MaxQueuedRexmitBytes -------------------- -**Internal** This setting limits the maximum number of bytes queued for retransmission. The default value of 0 is unlimited unless an AuxiliaryBandwidthLimit has been set, in which case it becomes NackDelay \* AuxiliaryBandwidthLimit. It must be large enough to contain the largest sample that may need to be retransmitted. +**Internal** This setting limits the maximum number of bytes queued for retransmission. The default value of 0 is unlimited unless an AuxiliaryBandwidthLimit has been set, in which case it becomes NackDelay * AuxiliaryBandwidthLimit. It must be large enough to contain the largest sample that may need to be retransmitted. The unit must be specified explicitly. Recognised units: B (bytes), kB & KiB (2 :sup:`10` bytes), MB & MiB (2 :sup:`20` bytes), GB & GiB (2 :sup:`30` bytes). -- Full path: //OpenSplice/DDSI2EService/Internal/MaxQueuedRexmitBytes +- Full path: /DDSI2Service/Internal/MaxQueuedRexmitBytes - Format: string -- Default value: 50 kB +- Default value: 0 B - Occurrences min-max: 0-1 MaxQueuedRexmitMessages @@ -9012,7 +7807,7 @@ MaxQueuedRexmitMessages **Internal** This settings limits the maximum number of samples queued for retransmission. -- Full path: //OpenSplice/DDSI2EService/Internal/MaxQueuedRexmitMessages +- Full path: /DDSI2Service/Internal/MaxQueuedRexmitMessages - Format: integer - Default value: 200 - Occurrences min-max: 0-1 @@ -9020,11 +7815,11 @@ MaxQueuedRexmitMessages MaxSampleSize ------------- -**Internal** This setting controls the maximum (CDR) serialised size of samples that DDSI2E will forward in either direction. Samples larger than this are discarded with a warning. +**Internal** This setting controls the maximum (CDR) serialised size of samples that DDSI2 will forward in either direction. Samples larger than this are discarded with a warning. The unit must be specified explicitly. Recognised units: B (bytes), kB & KiB (2 :sup:`10` bytes), MB & MiB (2 :sup:`20` bytes), GB & GiB (2 :sup:`30` bytes). -- Full path: //OpenSplice/DDSI2EService/Internal/MaxSampleSize +- Full path: /DDSI2Service/Internal/MaxSampleSize - Format: string - Default value: 2147483647 B - Occurrences min-max: 0-1 @@ -9032,9 +7827,9 @@ The unit must be specified explicitly. Recognised units: B (bytes), kB & KiB (2 MeasureHbToAckLatency --------------------- -**Internal** This element enables heartbeat-to-ack latency among DDSI2E services by prepending timestamps to Heartbeat and AckNack messages and calculating round trip times. This is non-standard behaviour. The measured latencies are quite noisy and are currently not used anywhere. +**Internal** This element enables heartbeat-to-ack latency among DDSI2 services by prepending timestamps to Heartbeat and AckNack messages and calculating round trip times. This is non-standard behaviour. The measured latencies are quite noisy and are currently not used anywhere. -- Full path: //OpenSplice/DDSI2EService/Internal/MeasureHbToAckLatency +- Full path: /DDSI2Service/Internal/MeasureHbToAckLatency - Format: boolean - Default value: false - Occurrences min-max: 0-1 @@ -9042,13 +7837,11 @@ MeasureHbToAckLatency MinimumSocketReceiveBufferSize ------------------------------ -**Internal** This setting controls the minimum size of socket receive buffers. The operating system provides some size receive buffer upon creation of the socket, this option can be used to increase the size of the buffer beyond that initially provided by the operating system. If the buffer size cannot be increased to the specified size, an error is reported. - -The default setting is the word "default", which means DDSI2E will attempt to increase the buffer size to 1MB, but will silently accept a smaller buffer should that attempt fail. +**Internal** This setting controls the minimum size of socket receive buffers. This setting can only increase the size of the receive buffer, if the operating system by default creates a larger buffer, it is left unchanged. The unit must be specified explicitly. Recognised units: B (bytes), kB & KiB (2 :sup:`10` bytes), MB & MiB (2 :sup:`20` bytes), GB & GiB (2 :sup:`30` bytes). -- Full path: //OpenSplice/DDSI2EService/Internal/MinimumSocketReceiveBufferSize +- Full path: /DDSI2Service/Internal/MinimumSocketReceiveBufferSize - Format: string - Default value: default - Occurrences min-max: 0-1 @@ -9060,7 +7853,7 @@ MinimumSocketSendBufferSize The unit must be specified explicitly. Recognised units: B (bytes), kB & KiB (2 :sup:`10` bytes), MB & MiB (2 :sup:`20` bytes), GB & GiB (2 :sup:`30` bytes). -- Full path: //OpenSplice/DDSI2EService/Internal/MinimumSocketSendBufferSize +- Full path: /DDSI2Service/Internal/MinimumSocketSendBufferSize - Format: string - Default value: 64 KiB - Occurrences min-max: 0-1 @@ -9068,22 +7861,12 @@ The unit must be specified explicitly. Recognised units: B (bytes), kB & KiB (2 MirrorRemoteEntities -------------------- -**Internal** This element controls whether DDSI2 mirrors all entities in the domain in DDSI or only local ones. Default is to discover remote ones iff General/LocalDiscoveryPartition is not the built-in partition. +This element controls whether DDSI2 mirrors all entities in the domain in DDSI or only local ones. Default is to discover remote ones iff General/LocalDiscoveryPartition is not the built-in partition. -- Full path: //OpenSplice/DDSI2EService/Internal/MirrorRemoteEntities +- Full path: /DDSI2Service/Internal/MirrorRemoteEntities - Format: enumeration - Default value: default -- Valid values: false, true, default -- Occurrences min-max: 0-1 - -MonitorPort ------------ - -**Internal** This element allows configuring a service that dumps a text description of part the internal state to TCP clients. By default (-1), this is disabled; specifying 0 means a kernel-allocated port is used; a positive number is used as the TCP port number. - -- Full path: //OpenSplice/DDSI2EService/Internal/MonitorPort -- Format: integer -- Default value: -1 +- Valid values: false, default, true - Occurrences min-max: 0-1 NackDelay @@ -9093,10 +7876,9 @@ NackDelay The unit must be specified explicitly. Recognised units: ns, us, ms, s, min, hr, day. -- Full path: //OpenSplice/DDSI2EService/Internal/NackDelay +- Full path: /DDSI2Service/Internal/NackDelay - Format: string - Default value: 10 ms -- Valid values: 0 / 1hr - Occurrences min-max: 0-1 PreEmptiveAckDelay @@ -9106,10 +7888,9 @@ PreEmptiveAckDelay The unit must be specified explicitly. Recognised units: ns, us, ms, s, min, hr, day. -- Full path: //OpenSplice/DDSI2EService/Internal/PreEmptiveAckDelay +- Full path: /DDSI2Service/Internal/PreEmptiveAckDelay - Format: string - Default value: 10 ms -- Valid values: 0 / 1hr - Occurrences min-max: 0-1 PrimaryReorderMaxSamples @@ -9117,54 +7898,21 @@ PrimaryReorderMaxSamples **Internal** This element sets the maximum size in samples of a primary re-order administration. Each proxy writer has one primary re-order administration to buffer the packet flow in case some packets arrive out of order. Old samples are forwarded to secondary re-order administrations associated with readers in need of historical data. -- Full path: //OpenSplice/DDSI2EService/Internal/PrimaryReorderMaxSamples +- Full path: /DDSI2Service/Internal/PrimaryReorderMaxSamples - Format: integer - Default value: 64 - Occurrences min-max: 0-1 -PrioritizeRetransmit --------------------- - -**Internal** This element controls whether retransmits are prioritized over new data, speeding up recovery. - -- Full path: //OpenSplice/DDSI2EService/Internal/PrioritizeRetransmit -- Format: boolean -- Default value: true -- Occurrences min-max: 0-1 - -RediscoveryBlacklistDuration ----------------------------- - -**Internal** This element controls for how long a remote participant that was previously deleted will remain on a blacklist to prevent rediscovery, giving the software on a node time to perform any cleanup actions it needs to do. To some extent this delay is required internally by DDSI2E, but in the default configuration with the 'enforce' attribute set to false, DDSI2E will reallow rediscovery as soon as it has cleared its internal administration. Setting it to too small a value may result in the entry being pruned from the blacklist before DDSI2E is ready, it is therefore recommended to set it to at least several seconds. - -Valid values are finite durations with an explicit unit or the keyword 'inf' for infinity. Recognised units: ns, us, ms, s, min, hr, day. - -- Full path: //OpenSplice/DDSI2EService/Internal/RediscoveryBlacklistDuration -- Format: string -- Default value: 10s -- Occurrences min-max: 0-1 -- Optional attributes: enforce - -enforce -^^^^^^^ - -**Internal** This attribute controls whether the configured time during which recently deleted participants will not be rediscovered (i.e., "black listed") is enforced and following complete removal of the participant in DDSI2E, or whether it can be rediscovered earlier provided all traces of that participant have been removed already. - -- Full path: //OpenSplice/DDSI2EService/Internal/RediscoveryBlacklistDuration[@enforce] -- Format: boolean -- Default value: false -- Required: false - ResponsivenessTimeout --------------------- -**Internal** This element controls for how long an unresponsive reader can block the transmit thread by failing to acknowledge data when a writer's DDSI2E write cache is full. If after this time the writer's cache has not shrunk to below the low-water mark, the reader is considered unresponsive and degraded to unreliable. It will be restored to reliable service once it resumes acknowledging samples. +**Internal** This element controls for how long an unresponsive reader can block the transmit thread by failing to acknowledge data when a writer's DDSI2 WHC is full. If after this time the writer's WHC has not shrunk to below the low-water mark, the reader is considered unresponsive and degraded to unreliable. It will be restored to reliable service once it resumes acknowledging ing samples. -Valid values are finite durations with an explicit unit or the keyword 'inf' for infinity. Recognised units: ns, us, ms, s, min, hr, day. +The unit must be specified explicitly. Recognised units: ns, us, ms, s, min, hr, day. -- Full path: //OpenSplice/DDSI2EService/Internal/ResponsivenessTimeout +- Full path: /DDSI2Service/Internal/ResponsivenessTimeout - Format: string -- Default value: inf +- Default value: 1 s - Occurrences min-max: 0-1 RetransmitMerging @@ -9178,7 +7926,7 @@ RetransmitMerging The default is *adaptive*. See also Internal/RetransmitMergingPeriod. -- Full path: //OpenSplice/DDSI2EService/Internal/RetransmitMerging +- Full path: /DDSI2Service/Internal/RetransmitMerging - Format: enumeration - Default value: adaptive - Valid values: never, adaptive, always @@ -9187,24 +7935,23 @@ The default is *adaptive*. See also Internal/RetransmitMergingPeriod. RetransmitMergingPeriod ----------------------- -**Internal** This setting determines the size of the time window in which a NACK of some sample is ignored because a retransmit of that sample has been multicasted too recently. This setting has no effect on unicasted retransmits. +**Internal** This setting determines the size of the time window in which a NACK of some sample is ignored because a retransmit of that sample has been multicasted too recently. This setting has no effect of unicasted retransmits. See also Internal/RetransmitMerging. The unit must be specified explicitly. Recognised units: ns, us, ms, s, min, hr, day. -- Full path: //OpenSplice/DDSI2EService/Internal/RetransmitMergingPeriod +- Full path: /DDSI2Service/Internal/RetransmitMergingPeriod - Format: string - Default value: 5 ms -- Valid values: 0 / 1s - Occurrences min-max: 0-1 RetryOnRejectBestEffort ----------------------- -**Internal** Whether or not to locally retry pushing a received best-effort sample into the reader caches when resource limits are reached. +**Internal** Whether or not to locally retry pusing a received best-effort sample into the reader caches when resource limits are reached. -- Full path: //OpenSplice/DDSI2EService/Internal/RetryOnRejectBestEffort +- Full path: /DDSI2Service/Internal/RetryOnRejectBestEffort - Format: boolean - Default value: false - Occurrences min-max: 0-1 @@ -9216,7 +7963,7 @@ RetryOnRejectDuration Valid values are finite durations with an explicit unit or the keyword 'inf' for infinity. Recognised units: ns, us, ms, s, min, hr, day. -- Full path: //OpenSplice/DDSI2EService/Internal/RetryOnRejectDuration +- Full path: /DDSI2Service/Internal/RetryOnRejectDuration - Format: string - Default value: default - Occurrences min-max: 0-1 @@ -9224,14 +7971,13 @@ Valid values are finite durations with an explicit unit or the keyword 'inf' for SPDPResponseMaxDelay -------------------- -**Internal** Maximum pseudo-random delay in milliseconds between discovering a remote participant and responding to it. +**Internal** Maximum pseudo-random delay in milliseocnds between discovering a remote participant and responding to it. The unit must be specified explicitly. Recognised units: ns, us, ms, s, min, hr, day. -- Full path: //OpenSplice/DDSI2EService/Internal/SPDPResponseMaxDelay +- Full path: /DDSI2Service/Internal/SPDPResponseMaxDelay - Format: string - Default value: 0 ms -- Valid values: 0 / 1s - Occurrences min-max: 0-1 ScheduleTimeRounding @@ -9241,10 +7987,9 @@ ScheduleTimeRounding The unit must be specified explicitly. Recognised units: ns, us, ms, s, min, hr, day. -- Full path: //OpenSplice/DDSI2EService/Internal/ScheduleTimeRounding +- Full path: /DDSI2Service/Internal/ScheduleTimeRounding - Format: string - Default value: 0 ms -- Valid values: 0 / 1hr - Occurrences min-max: 0-1 SecondaryReorderMaxSamples @@ -9252,7 +7997,7 @@ SecondaryReorderMaxSamples **Internal** This element sets the maximum size in samples of a secondary re-order administration. The secondary re-order administration is per reader in need of historical data. -- Full path: //OpenSplice/DDSI2EService/Internal/SecondaryReorderMaxSamples +- Full path: /DDSI2Service/Internal/SecondaryReorderMaxSamples - Format: integer - Default value: 16 - Occurrences min-max: 0-1 @@ -9260,9 +8005,9 @@ SecondaryReorderMaxSamples SquashParticipants ------------------ -**Internal** This element controls whether DDSI2E advertises all the domain participants it serves in DDSI (when set to *false*), or rather only one domain participant (the one corresponding to the DDSI2E process; when set to *true*). In the latter case DDSI2E becomes the virtual owner of all readers and writers of all domain participants, dramatically reducing discovery traffic (a similar effect can be obtained by setting Internal/BuiltinEndpointSet to "minimal" but with less loss of information). +**Internal** This element controls whether DDSI2 advertises all the domain participants it serves in DDSI (when set to *false*), or rather only one domain participant (the one corresponding to the DDSI2 process; when set to *true*). In the latter case DDSI2 becomes the virtual owner of all readers and writers of all domain participants, dramatically reducing discovery traffic. -- Full path: //OpenSplice/DDSI2EService/Internal/SquashParticipants +- Full path: /DDSI2Service/Internal/SquashParticipants - Format: boolean - Default value: false - Occurrences min-max: 0-1 @@ -9274,7 +8019,7 @@ SuppressSPDPMulticast See also General/AllowMulticast. -- Full path: //OpenSplice/DDSI2EService/Internal/SuppressSPDPMulticast +- Full path: /DDSI2Service/Internal/SuppressSPDPMulticast - Format: boolean - Default value: false - Occurrences min-max: 0-1 @@ -9286,7 +8031,7 @@ SynchronousDeliveryLatencyBound Valid values are finite durations with an explicit unit or the keyword 'inf' for infinity. Recognised units: ns, us, ms, s, min, hr, day. -- Full path: //OpenSplice/DDSI2EService/Internal/SynchronousDeliveryLatencyBound +- Full path: /DDSI2Service/Internal/SynchronousDeliveryLatencyBound - Format: string - Default value: inf - Occurrences min-max: 0-1 @@ -9296,7 +8041,7 @@ SynchronousDeliveryPriorityThreshold **Internal** This element controls whether samples sent by a writer with QoS settings latency_budget <= SynchronousDeliveryLatencyBound and transport_priority greater than or equal to this element's value will be delivered synchronously from the "recv" thread, all others will be delivered asynchronously through delivery queues. This reduces latency at the expense of aggregate bandwidth. -- Full path: //OpenSplice/DDSI2EService/Internal/SynchronousDeliveryPriorityThreshold +- Full path: /DDSI2Service/Internal/SynchronousDeliveryPriorityThreshold - Format: integer - Default value: 0 - Occurrences min-max: 0-1 @@ -9306,16 +8051,16 @@ Test **Internal** Testing options. -- Full path: //OpenSplice/DDSI2EService/Internal/Test +- Full path: /DDSI2Service/Internal/Test - Occurrences min-max: 0-1 - Child elements: XmitLossiness XmitLossiness ^^^^^^^^^^^^^ -**Internal** This element controls the fraction of outgoing packets to drop, specified as samples per thousand. +**Internal** This element controls the fraction of outgoing packets to drop, specified as a per mil. -- Full path: //OpenSplice/DDSI2EService/Internal/Test/XmitLossiness +- Full path: /DDSI2Service/Internal/Test/XmitLossiness - Format: integer - Default value: 0 - Occurrences min-max: 0-1 @@ -9325,72 +8070,40 @@ UnicastResponseToSPDPMessages **Internal** This element controls whether the response to a newly discovered participant is sent as a unicasted SPDP packet, instead of rescheduling the periodic multicasted one. There is no known benefit to setting this to *false*. -- Full path: //OpenSplice/DDSI2EService/Internal/UnicastResponseToSPDPMessages +- Full path: /DDSI2Service/Internal/UnicastResponseToSPDPMessages - Format: boolean - Default value: true - Occurrences min-max: 0-1 -UseMulticastIfMreqn -------------------- +Watermarks +---------- -**Internal** Do not use. +**Internal** Watermarks for flow-control. -- Full path: //OpenSplice/DDSI2EService/Internal/UseMulticastIfMreqn -- Format: integer -- Default value: 0 -- Occurrences min-max: 0-1 - -Watermarks ----------- - -**Internal** Watermarks for flow-control. - -- Full path: //OpenSplice/DDSI2EService/Internal/Watermarks -- Occurrences min-max: 0-1 -- Child elements: WhcAdaptive, WhcHigh, WhcHighInit, WhcLow - -WhcAdaptive -^^^^^^^^^^^ - -**Internal** This element controls whether DDSI2E will adapt the high-water mark to current traffic conditions, based on retransmit requests and transmit pressure. - -- Full path: //OpenSplice/DDSI2EService/Internal/Watermarks/WhcAdaptive -- Format: boolean -- Default value: true +- Full path: /DDSI2Service/Internal/Watermarks - Occurrences min-max: 0-1 +- Child elements: WhcHigh, WhcLow WhcHigh ^^^^^^^ -**Internal** This element sets the maximum allowed high-water mark for the DDSI2E WHCs, expressed in bytes. A writer is suspended when the WHC reaches this size. +**Internal** This element sets the high-water mark for the DDSI2 WHCs, expressed in bytes. A writer is suspended when the WHC reaches this size. The unit must be specified explicitly. Recognised units: B (bytes), kB & KiB (2 :sup:`10` bytes), MB & MiB (2 :sup:`20` bytes), GB & GiB (2 :sup:`30` bytes). -- Full path: //OpenSplice/DDSI2EService/Internal/Watermarks/WhcHigh +- Full path: /DDSI2Service/Internal/Watermarks/WhcHigh - Format: string - Default value: 100 kB - Occurrences min-max: 0-1 -WhcHighInit -^^^^^^^^^^^ - -**Internal** This element sets the initial level of the high-water mark for the DDSI2E WHCs, expressed in bytes. - -The unit must be specified explicitly. Recognised units: B (bytes), kB & KiB (2 :sup:`10` bytes), MB & MiB (2 :sup:`20` bytes), GB & GiB (2 :sup:`30` bytes). - -- Full path: //OpenSplice/DDSI2EService/Internal/Watermarks/WhcHighInit -- Format: string -- Default value: 30 kB -- Occurrences min-max: 0-1 - WhcLow ^^^^^^ -**Internal** This element sets the low-water mark for the DDSI2E WHCs, expressed in bytes. A suspended writer resumes transmitting when its DDSI2E WHC shrinks to this size. +**Internal** This element sets the low-water mark for the DDSI2 WHCs, expressed in bytes. A suspended writer resumes transmitting when its DDSI2 WHC shrinks to this size. The unit must be specified explicitly. Recognised units: B (bytes), kB & KiB (2 :sup:`10` bytes), MB & MiB (2 :sup:`20` bytes), GB & GiB (2 :sup:`30` bytes). -- Full path: //OpenSplice/DDSI2EService/Internal/Watermarks/WhcLow +- Full path: /DDSI2Service/Internal/Watermarks/WhcLow - Format: string - Default value: 1 kB - Occurrences min-max: 0-1 @@ -9401,148 +8114,17 @@ WriterLingerDuration **Internal** This setting controls the maximum duration for which actual deletion of a reliable writer with unacknowledged data in its history will be postponed to provide proper reliable transmission. The unit must be specified explicitly. Recognised units: ns, us, ms, s, min, hr, day. -- Full path: //OpenSplice/DDSI2EService/Internal/WriterLingerDuration +- Full path: /DDSI2Service/Internal/WriterLingerDuration - Format: string - Default value: 1 s -- Valid values: 0 / 1hr -- Occurrences min-max: 0-1 - -Partitioning -============ - -The Partitioning element specifies DDSI2E network partitions and how DCPS partition/topic combinations are mapped onto the network partitions. - -- Full path: //OpenSplice/DDSI2EService/Partitioning - Occurrences min-max: 0-1 -IgnoredPartitions ------------------ - -The IgnoredPartitions element specifies DCPS partition/topic combinations that are not distributed over the network. - -- Full path: //OpenSplice/DDSI2EService/Partitioning/IgnoredPartitions -- Occurrences min-max: 0-* - -IgnoredPartition -^^^^^^^^^^^^^^^^ - -This element can be used to prevent certain combinations of DCPS partition and topic from being transmitted over the network. DDSI2E will complete ignore readers and writers for which all DCPS partitions as well as their topic is ignored, not even creating DDSI readers and writers to mirror the DCPS ones. - -- Full path: //OpenSplice/DDSI2EService/Partitioning/IgnoredPartitions/IgnoredPartition -- Occurrences min-max: 0-* -- Required attributes: DCPSPartitionTopic - -DCPSPartitionTopic -~~~~~~~~~~~~~~~~~~ - -This attribute specifies a partition and a topic expression, separated by a single '.', that are used to determine if a given partition and topic will be ignored or not. The expressions may use the usual wildcards '\*' and '?'. DDSI2E will consider an wildcard DCPS partition to match an expression iff there exists a string that satisfies both expressions. - -- Full path: //OpenSplice/DDSI2EService/Partitioning/IgnoredPartitions/IgnoredPartition[@DCPSPartitionTopic] -- Format: string -- Default value: n/a -- Required: true - -NetworkPartitions ------------------ - -The NetworkPartitions element specifies the DDSI2E network partitions. - -- Full path: //OpenSplice/DDSI2EService/Partitioning/NetworkPartitions -- Occurrences min-max: 0-* - -NetworkPartition -^^^^^^^^^^^^^^^^ - -This element defines a DDSI2E network partition. - -- Full path: //OpenSplice/DDSI2EService/Partitioning/NetworkPartitions/NetworkPartition -- Occurrences min-max: 0-* -- Required attributes: Address, Name -- Optional attributes: Connected, SecurityProfile - -Address -~~~~~~~ - -This attribute specifies the multicast addresses associated with the network partition as a comma-separated list. Readers matching this network partition (cf. Partitioning/PartitionMappings) will listen for multicasts on all of these addresses and advertise them in the discovery protocol. The writers will select the most suitable address from the addresses advertised by the readers. - -- Full path: //OpenSplice/DDSI2EService/Partitioning/NetworkPartitions/NetworkPartition[@Address] -- Format: string -- Default value: n/a -- Required: true - -Connected -~~~~~~~~~ - -This attribute is a placeholder. - -- Full path: //OpenSplice/DDSI2EService/Partitioning/NetworkPartitions/NetworkPartition[@Connected] -- Format: boolean -- Default value: true -- Required: false - -Name -~~~~ - -This attribute specifies the name of this DDSI2E network partition. Two network partitions cannot have the same name. - -- Full path: //OpenSplice/DDSI2EService/Partitioning/NetworkPartitions/NetworkPartition[@Name] -- Format: string -- Default value: n/a -- Required: true - -SecurityProfile -~~~~~~~~~~~~~~~ - -This attribute selects the DDSI2E security profile for encrypting the traffic mapped to this DDSI2E network partition. The default "null" means the network partition is unsecured; any other name refers to a security profile defined using the Security/SecurityProfile elements. - -- Full path: //OpenSplice/DDSI2EService/Partitioning/NetworkPartitions/NetworkPartition[@SecurityProfile] -- Format: string -- Default value: null -- Required: false - -PartitionMappings ------------------ - -The PartitionMappings element specifies the mapping from DCPS partition/topic combinations to DDSI2E network partitions. - -- Full path: //OpenSplice/DDSI2EService/Partitioning/PartitionMappings -- Occurrences min-max: 0-* - -PartitionMapping -^^^^^^^^^^^^^^^^ - -This element defines a mapping from a DCPS partition/topic combination to a DDSI2E network partition. This allows partitioning data flows by using special multicast addresses for part of the data and possibly also encrypting the data flow. - -- Full path: //OpenSplice/DDSI2EService/Partitioning/PartitionMappings/PartitionMapping -- Occurrences min-max: 0-* -- Required attributes: DCPSPartitionTopic, NetworkPartition - -DCPSPartitionTopic -~~~~~~~~~~~~~~~~~~ - -This attribute specifies a partition and a topic expression, separated by a single '.', that are used to determine if a given partition and topic maps to the DDSI2E network partition named by the NetworkPartition attribute in this PartitionMapping element. The expressions may use the usual wildcards '\*' and '?'. DDSI2E will consider a wildcard DCPS partition to match an expression if there exists a string that satisfies both expressions. - -- Full path: //OpenSplice/DDSI2EService/Partitioning/PartitionMappings/PartitionMapping[@DCPSPartitionTopic] -- Format: string -- Default value: n/a -- Required: true - -NetworkPartition -~~~~~~~~~~~~~~~~ - -This attribute specifies which DDSI2E network partition is to be used for DCPS partition/topic combinations matching the DCPSPartitionTopic attribute within this PartitionMapping element. - -- Full path: //OpenSplice/DDSI2EService/Partitioning/PartitionMappings/PartitionMapping[@NetworkPartition] -- Format: string -- Default value: n/a -- Required: true - SSL === The SSL element allows specifying various parameters related to using SSL/TLS for DDSI over TCP. -- Full path: //OpenSplice/DDSI2EService/SSL +- Full path: /DDSI2Service/SSL - Occurrences min-max: 0-1 - Child elements: CertificateVerification, Ciphers, Enable, EntropyFile, KeyPassphrase, KeystoreFile, SelfSignedCertificates, VerifyClient @@ -9551,7 +8133,7 @@ CertificateVerification If disabled this allows SSL connections to occur even if an X509 certificate fails verification. -- Full path: //OpenSplice/DDSI2EService/SSL/CertificateVerification +- Full path: /DDSI2Service/SSL/CertificateVerification - Format: boolean - Default value: true - Occurrences min-max: 0-1 @@ -9561,7 +8143,7 @@ Ciphers The set of ciphers used by SSL/TLS -- Full path: //OpenSplice/DDSI2EService/SSL/Ciphers +- Full path: /DDSI2Service/SSL/Ciphers - Format: string - Default value: ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH - Occurrences min-max: 0-1 @@ -9571,7 +8153,7 @@ Enable This enables SSL/TLS for TCP. -- Full path: //OpenSplice/DDSI2EService/SSL/Enable +- Full path: /DDSI2Service/SSL/Enable - Format: boolean - Default value: false - Occurrences min-max: 0-1 @@ -9581,7 +8163,7 @@ EntropyFile The SSL/TLS random entropy file name. -- Full path: //OpenSplice/DDSI2EService/SSL/EntropyFile +- Full path: /DDSI2Service/SSL/EntropyFile - Format: string - Occurrences min-max: 0-1 @@ -9590,7 +8172,7 @@ KeyPassphrase The SSL/TLS key pass phrase for encrypted keys. -- Full path: //OpenSplice/DDSI2EService/SSL/KeyPassphrase +- Full path: /DDSI2Service/SSL/KeyPassphrase - Format: string - Default value: secret - Occurrences min-max: 0-1 @@ -9600,7 +8182,7 @@ KeystoreFile The SSL/TLS key and certificate store file name. The keystore must be in PEM format. -- Full path: //OpenSplice/DDSI2EService/SSL/KeystoreFile +- Full path: /DDSI2Service/SSL/KeystoreFile - Format: string - Default value: keystore - Occurrences min-max: 0-1 @@ -9610,7 +8192,7 @@ SelfSignedCertificates This enables the use of self signed X509 certificates. -- Full path: //OpenSplice/DDSI2EService/SSL/SelfSignedCertificates +- Full path: /DDSI2Service/SSL/SelfSignedCertificates - Format: boolean - Default value: false - Occurrences min-max: 0-1 @@ -9620,99 +8202,26 @@ VerifyClient This enables an SSL server checking the X509 certificate of a connecting client. -- Full path: //OpenSplice/DDSI2EService/SSL/VerifyClient +- Full path: /DDSI2Service/SSL/VerifyClient - Format: boolean - Default value: false - Occurrences min-max: 0-1 -Security -======== - -The Security element specifies DDSI2E security profiles that can be used to encrypt traffic mapped to DDSI2E network partitions. - -- Full path: //OpenSplice/DDSI2EService/Security -- Occurrences min-max: 0-1 - -SecurityProfile ---------------- - -This element defines a DDSI2E security profile. - -- Full path: //OpenSplice/DDSI2EService/Security/SecurityProfile -- Occurrences min-max: 0-* -- Required attributes: Name -- Optional attributes: Cipher, CipherKey - -Cipher -^^^^^^ - -This attribute specifies the cipher to be used for encrypting traffic over network partitions secured by this security profile. The possible ciphers are: - -- *aes128*: AES with a 128-bit key; -- *aes192*: AES with a 192-bit key; -- *aes256*: AES with a 256-bit key; -- *blowfish*: the Blowfish cipher with a 128 bit key; -- *null*: no encryption; - -SHA1 is used on conjunction with all ciphers except "null" to ensure data integrity. - -- Full path: //OpenSplice/DDSI2EService/Security/SecurityProfile[@Cipher] -- Format: enumeration -- Default value: null -- Valid values: null, blowfish, aes128, aes192, aes256 -- Required: false - -CipherKey -^^^^^^^^^ - -The CipherKey attribute is used to define the secret key required by the cipher selected using the Cipher attribute. The value can be a URI referencing an external file containing the secret key, or the secret key can be defined in-place as a string value. - -The key must be specified as a hexadecimal string with each character representing 4 bits of the key. E.g., 1ABC represents the 16-bit key 0001 1010 1011 1100. The key should not follow a well-known pattern and must exactly match the key length of the selected cipher. - -A malformed key will cause the security profile to be marked as invalid, and disable all network partitions secured by the (invalid) security profile to prevent information leaks. - -As all DDS applications require read access to the XML configuration file, for security reasons it is recommended to store the secret key in an external file in the file system, referenced by its URI. The file should be protected against read and write access from other users on the host. - -- Full path: //OpenSplice/DDSI2EService/Security/SecurityProfile[@CipherKey] -- Format: string -- Default value: "" -- Required: false - -Name -^^^^ - -This attribute specifies the name of this DDSI2E security profile. Two security profiles cannot have the same name. - -- Full path: //OpenSplice/DDSI2EService/Security/SecurityProfile[@Name] -- Format: string -- Default value: n/a -- Required: true - Sizing ====== The Sizing element specifies a variety of configuration settings dealing with expected system sizes, buffer sizes, &c. -- Full path: //OpenSplice/DDSI2EService/Sizing -- Occurrences min-max: 0-1 -- Child elements: EndpointsInSystem, EndpointsInSystem, LocalEndpoints, NetworkQueueSize, NetworkQueueSize, ReceiveBufferChunkSize, ReceiveBufferChunkSize - -EndpointsInSystem ------------------ - -This endpoint specifies the expected maximum number of endpoints in the network. Underestimating this number will have a significant performance impact, but will not affect correctness; signficantly overestimating it will cause more memory to be used than necessary. - -- Full path: //OpenSplice/DDSI2EService/Sizing/EndpointsInSystem -- Format: integer -- Default value: 20000 +- Full path: /DDSI2Service/Sizing - Occurrences min-max: 0-1 +- Child elements: EndpointsInSystem, LocalEndpoints, NetworkQueueSize, ReceiveBufferChunkSize, ReceiveBufferSize EndpointsInSystem ----------------- This endpoint specifies the expected maximum number of endpoints in the network. Underestimating this number will have a significant performance impact, but will not affect correctness; signficantly overestimating it will cause more memory to be used than necessary. -- Full path: //OpenSplice/DDSI2EService/Sizing/EndpointsInSystem +- Full path: /DDSI2Service/Sizing/EndpointsInSystem - Format: integer - Default value: 20000 - Occurrences min-max: 0-1 @@ -9720,19 +8229,9 @@ This endpoint specifies the expected maximum number of endpoints in the network. LocalEndpoints -------------- -This element specifies the expected maximum number of endpoints local to one DDSI2E service. Underestimating this number will have a significant performance impact, but will not affect correctness; signficantly overestimating it will cause more memory to be used than necessary. - -- Full path: //OpenSplice/DDSI2EService/Sizing/LocalEndpoints -- Format: integer -- Default value: 1000 -- Occurrences min-max: 0-1 - -NetworkQueueSize ----------------- - -This element specifies the maximum number of samples in the network queue. Write/dispose operations add samples to this queue, the DDSI2E service drains it. Larger values allow large bursts of writes to occur without forcing synchronization between the application and the DDSI2E service, but do introduce the potential for longer latencies and increase the maximum amount of memory potentially occupied by messages in the queue. +This element specifies the expected maximum number of endpoints local to one DDSI2 service. Underestimating this number will have a significant performance impact, but will not affect correctness; signficantly overestimating it will cause more memory to be used than necessary. -- Full path: //OpenSplice/DDSI2EService/Sizing/NetworkQueueSize +- Full path: /DDSI2Service/Sizing/LocalEndpoints - Format: integer - Default value: 1000 - Occurrences min-max: 0-1 @@ -9740,9 +8239,9 @@ This element specifies the maximum number of samples in the network queue. Write NetworkQueueSize ---------------- -This element specifies the maximum number of samples in the network queue. Write/dispose operations add samples to this queue, the DDSI2E service drains it. Larger values allow large bursts of writes to occur without forcing synchronization between the application and the DDSI2E service, but do introduce the potential for longer latencies and increase the maximum amount of memory potentially occupied by messages in the queue. +This element specifies the maximum number of samples in the network queue. Write/dispose operations add samples to this queue, the DDSI2 service drains it. Larger values allow large bursts of writes to occur without forcing synchronization between the application and the DDSI2 service, but do introduce the potential for longer latencies and increase the maximum amount of memory potentially occupied by messages in the queue. -- Full path: //OpenSplice/DDSI2EService/Sizing/NetworkQueueSize +- Full path: /DDSI2Service/Sizing/NetworkQueueSize - Format: integer - Default value: 1000 - Occurrences min-max: 0-1 @@ -9750,80 +8249,25 @@ This element specifies the maximum number of samples in the network queue. Write ReceiveBufferChunkSize ---------------------- -This element specifies the size of one allocation unit in the receive buffer. Must be greater than the maximum packet size by a modest amount (too large packets are dropped). Each allocation is shrunk immediately after processing a message, or freed straightaway. - -The unit must be specified explicitly. Recognised units: B (bytes), kB & KiB (2 :sup:`10` bytes), MB & MiB (2 :sup:`20` bytes), GB & GiB (2 :sup:`30` bytes). - -- Full path: //OpenSplice/DDSI2EService/Sizing/ReceiveBufferChunkSize -- Format: string -- Default value: 128 KiB -- Occurrences min-max: 0-1 - -ReceiveBufferChunkSize ----------------------- - -This element specifies the size of one allocation unit in the receive buffer. Must be greater than the maximum packet size by a modest amount (too large packets are dropped). Each allocation is shrunk immediately after processing a message, or freed straightaway. +Size of one allocation unit in the receive buffer. Must be greater than the maximum packet size by a modest amount (too large packets are dropped). Each allocation is shrunk immediately after processing a message, or freed straightaway. The unit must be specified explicitly. Recognised units: B (bytes), kB & KiB (2 :sup:`10` bytes), MB & MiB (2 :sup:`20` bytes), GB & GiB (2 :sup:`30` bytes). -- Full path: //OpenSplice/DDSI2EService/Sizing/ReceiveBufferChunkSize +- Full path: /DDSI2Service/Sizing/ReceiveBufferChunkSize - Format: string - Default value: 128 KiB - Occurrences min-max: 0-1 -Watermarks ----------- - -#if LITE { LEAF ("ReceiveBufferSize"), 1, "128 KiB", ABSOFF (rbuf_size), 0, uf_memsize, 0, pf_memsize, "This element sets the size of a single receive buffer. Many receive buffers may be needed. Their size must be greater than ReceiveBufferChunkSize by a modest amount. - -- Full path: //OpenSplice/DDSI2EService/Sizing/Watermarks -- Occurrences min-max: 0-1 -- Child elements: WhcAdaptive, WhcHigh, WhcHighInit, WhcLow - -WhcAdaptive -^^^^^^^^^^^ - -This element controls whether DDSI2E will adapt the high-water mark to current traffic conditions, based on retransmit requests and transmit pressure. - -- Full path: //OpenSplice/DDSI2EService/Sizing/Watermarks/WhcAdaptive -- Format: boolean -- Default value: true -- Occurrences min-max: 0-1 - -WhcHigh -^^^^^^^ - -This element sets the maximum allowed high-water mark for the DDSI2E WHCs, expressed in bytes. A writer is suspended when the WHC reaches this size. - -The unit must be specified explicitly. Recognised units: B (bytes), kB & KiB (2 :sup:`10` bytes), MB & MiB (2 :sup:`20` bytes), GB & GiB (2 :sup:`30` bytes). - -- Full path: //OpenSplice/DDSI2EService/Sizing/Watermarks/WhcHigh -- Format: string -- Default value: 100 kB -- Occurrences min-max: 0-1 - -WhcHighInit -^^^^^^^^^^^ - -This element sets the initial level of the high-water mark for the DDSI2E WHCs, expressed in bytes. - -The unit must be specified explicitly. Recognised units: B (bytes), kB & KiB (2 :sup:`10` bytes), MB & MiB (2 :sup:`20` bytes), GB & GiB (2 :sup:`30` bytes). - -- Full path: //OpenSplice/DDSI2EService/Sizing/Watermarks/WhcHighInit -- Format: string -- Default value: 30 kB -- Occurrences min-max: 0-1 - -WhcLow -^^^^^^ +ReceiveBufferSize +----------------- -This element sets the low-water mark for the DDSI2E WHCs, expressed in bytes. A suspended writer resumes transmitting when its DDSI2E WHC shrinks to this size. +This element sets the size of a single receive buffer. Many receive buffers may be needed. Their size must be greater than ReceiveBufferChunkSize by a modest amount. The unit must be specified explicitly. Recognised units: B (bytes), kB & KiB (2 :sup:`10` bytes), MB & MiB (2 :sup:`20` bytes), GB & GiB (2 :sup:`30` bytes). -- Full path: //OpenSplice/DDSI2EService/Sizing/Watermarks/WhcLow +- Full path: /DDSI2Service/Sizing/ReceiveBufferSize - Format: string -- Default value: 1 kB +- Default value: 1 MiB - Occurrences min-max: 0-1 TCP @@ -9831,7 +8275,7 @@ TCP The TCP element allows specifying various parameters related to running DDSI over TCP. -- Full path: //OpenSplice/DDSI2EService/TCP +- Full path: /DDSI2Service/TCP - Occurrences min-max: 0-1 - Child elements: Enable, NoDelay, Port, ReadTimeout, WriteTimeout @@ -9840,7 +8284,7 @@ Enable This element enables the optional TCP transport. -- Full path: //OpenSplice/DDSI2EService/TCP/Enable +- Full path: /DDSI2Service/TCP/Enable - Format: boolean - Default value: false - Occurrences min-max: 0-1 @@ -9850,7 +8294,7 @@ NoDelay This element enables the TCP_NODELAY socket option, preventing multiple DDSI messages being sent in the same TCP request. Setting this option typically optimises latency over throughput. -- Full path: //OpenSplice/DDSI2EService/TCP/NoDelay +- Full path: /DDSI2Service/TCP/NoDelay - Format: boolean - Default value: true - Occurrences min-max: 0-1 @@ -9858,12 +8302,11 @@ This element enables the TCP_NODELAY socket option, preventing multiple DDSI mes Port ---- -This element specifies the TCP port number on which DDSI2E accepts connections. If the port is set it is used in entity locators, published with DDSI discovery. Dynamically allocated if zero. Disabled if -1 or not configured. If disabled other DDSI services will not be able to establish connections with the service, the service can only communicate by establishing connections to other services. +This element specifies the TCP port number on which the service accepts connections. If the port is set it is used in entity locators, published with DDSI discovery. Dynamically allocated if zero. Disabled if -1 or not configured. If disabled other DDSI services will not be able to establish connections with the service, the service can only communicate by establishing connections to other services. -- Full path: //OpenSplice/DDSI2EService/TCP/Port +- Full path: /DDSI2Service/TCP/Port - Format: integer - Default value: -1 -- Valid values: -1 / 65535 - Occurrences min-max: 0-1 ReadTimeout @@ -9873,10 +8316,9 @@ This element specifies the timeout for blocking TCP read operations. If this tim The unit must be specified explicitly. Recognised units: ns, us, ms, s, min, hr, day. -- Full path: //OpenSplice/DDSI2EService/TCP/ReadTimeout +- Full path: /DDSI2Service/TCP/ReadTimeout - Format: string - Default value: 2 s -- Valid values: 0 / 1hr - Occurrences min-max: 0-1 WriteTimeout @@ -9886,10 +8328,9 @@ This element specifies the timeout for blocking TCP write operations. If this ti The unit must be specified explicitly. Recognised units: ns, us, ms, s, min, hr, day. -- Full path: //OpenSplice/DDSI2EService/TCP/WriteTimeout +- Full path: /DDSI2Service/TCP/WriteTimeout - Format: string - Default value: 2 s -- Valid values: 0 / 1hr - Occurrences min-max: 0-1 ThreadPool @@ -9897,7 +8338,7 @@ ThreadPool The ThreadPool element allows specifying various parameters related to using a thread pool to send DDSI messages to multiple unicast addresses (TCP or UDP). -- Full path: //OpenSplice/DDSI2EService/ThreadPool +- Full path: /DDSI2Service/ThreadPool - Occurrences min-max: 0-1 - Child elements: Enable, ThreadMax, Threads @@ -9906,7 +8347,7 @@ Enable This element enables the optional thread pool. -- Full path: //OpenSplice/DDSI2EService/ThreadPool/Enable +- Full path: /DDSI2Service/ThreadPool/Enable - Format: boolean - Default value: false - Occurrences min-max: 0-1 @@ -9916,7 +8357,7 @@ ThreadMax This elements configures the maximum number of threads in the thread pool. -- Full path: //OpenSplice/DDSI2EService/ThreadPool/ThreadMax +- Full path: /DDSI2Service/ThreadPool/ThreadMax - Format: integer - Default value: 8 - Occurrences min-max: 0-1 @@ -9926,7 +8367,7 @@ Threads This elements configures the initial number of threads in the thread pool. -- Full path: //OpenSplice/DDSI2EService/ThreadPool/Threads +- Full path: /DDSI2Service/ThreadPool/Threads - Format: integer - Default value: 4 - Occurrences min-max: 0-1 @@ -9936,15 +8377,15 @@ Threads This element is used to set thread properties. -- Full path: //OpenSplice/DDSI2EService/Threads +- Full path: /DDSI2Service/Threads - Occurrences min-max: 0-1 Thread ------ -This element is used to set thread properties. +This element specifies thread properties, such as scheduling parameters and stack size. -- Full path: //OpenSplice/DDSI2EService/Threads/Thread +- Full path: /DDSI2Service/Threads/Thread - Occurrences min-max: 0-1000 - Child elements: StackSize - Required attributes: Name @@ -9955,15 +8396,16 @@ Name The Name of the thread for which properties are being set. The following threads exist: - *gc*: garbage collector thread involved in deleting entities; +- *main*: main thread, primarily handling local discovery; - *recv*: receive thread, taking data from the network and running the protocol state machine; - *dq.builtins*: delivery thread for DDSI-builtin data, primarily for discovery; -- *lease*: DDSI liveliness monitoring; +- *lease*: DDSI2 liveliness monitoring; - *tev*: general timed-event handling, retransmits and discovery; - *xmit.CHAN*: transmit thread for channel CHAN; - *dq.CHAN*: delivery thread for channel CHAN; - *tev.CHAN*: timed-even thread for channel CHAN. -- Full path: //OpenSplice/DDSI2EService/Threads/Thread[@Name] +- Full path: /DDSI2Service/Threads/Thread/Name - Format: string - Default value: n/a - Required: true @@ -9973,7 +8415,7 @@ Scheduling This element configures the scheduling properties of the thread. -- Full path: //OpenSplice/DDSI2EService/Threads/Thread/Scheduling +- Full path: /DDSI2Service/Threads/Thread/Scheduling - Occurrences min-max: 0-1 - Child elements: Class, Priority @@ -9982,7 +8424,7 @@ Class This element specifies the thread scheduling class (*realtime*, *timeshare* or *default*). The user may need special privileges from the underlying operating system to be able to assign some of the privileged scheduling classes. -- Full path: //OpenSplice/DDSI2EService/Threads/Thread/Scheduling/Class +- Full path: /DDSI2Service/Threads/Thread/Scheduling/Class - Format: enumeration - Default value: default - Valid values: realtime, timeshare, default @@ -9993,7 +8435,7 @@ Priority This element specifies the thread priority (decimal integer or *default*). Only priorities that are supported by the underlying operating system can be assigned to this element. The user may need special privileges from the underlying operating system to be able to assign some of the privileged priorities. -- Full path: //OpenSplice/DDSI2EService/Threads/Thread/Scheduling/Priority +- Full path: /DDSI2Service/Threads/Thread/Scheduling/Priority - Format: string - Default value: default - Occurrences min-max: 0-1 @@ -10001,11 +8443,11 @@ This element specifies the thread priority (decimal integer or *default*). Only StackSize ^^^^^^^^^ -This element configures the stack size for this thread. The default value *default* leaves the stack size at the operating system default. +This element configures the stack size for this thread. The default value *default* leaves the stack size at the the operating system default. The unit must be specified explicitly. Recognised units: B (bytes), kB & KiB (2 :sup:`10` bytes), MB & MiB (2 :sup:`20` bytes), GB & GiB (2 :sup:`30` bytes). -- Full path: //OpenSplice/DDSI2EService/Threads/Thread/StackSize +- Full path: /DDSI2Service/Threads/Thread/StackSize - Format: string - Default value: default - Occurrences min-max: 0-1 @@ -10015,7 +8457,7 @@ Tracing The Tracing element controls the amount and type of information that is written into the tracing log by the DDSI service. This is useful to track the DDSI service during application development. -- Full path: //OpenSplice/DDSI2EService/Tracing +- Full path: /DDSI2Service/Tracing - Occurrences min-max: 0-1 - Child elements: AppendToFile, EnableCategory, OutputFile, PacketCaptureFile, Timestamps, Verbosity @@ -10024,7 +8466,7 @@ AppendToFile This option specifies whether the output is to be appended to an existing log file. The default is to create a new log file each time, which is generally the best option if a detailed log is generated. -- Full path: //OpenSplice/DDSI2EService/Tracing/AppendToFile +- Full path: /DDSI2Service/Tracing/AppendToFile - Format: boolean - Default value: false - Occurrences min-max: 0-1 @@ -10044,16 +8486,12 @@ This element enables individual logging categories. These are enabled in additio - *radmin*: receive buffer administration - *timing*: periodic reporting of CPU loads per thread - *traffic*: periodic reporting of total outgoing data -- *whc*: tracing of writer history cache changes -- *tcp*: tracing of TCP-specific activity -- *topic*: tracing of topic definitions -- >i>plist*: tracing of discovery parameter list interpretation -In addition, there is the keyword *trace* that enables all but *radmin*, *topic*, *plist* and *whc* +In addition, there is the keyword *trace* that enables all but *radmin* . The categorisation of tracing output is incomplete and hence most of the verbosity levels and categories are not of much use in the current release. This is an ongoing process and here we describe the target situation rather than the current situation. Currently, the most useful is *trace*. -- Full path: //OpenSplice/DDSI2EService/Tracing/EnableCategory +- Full path: /DDSI2Service/Tracing/EnableCategory - Format: string - Occurrences min-max: 0-1 @@ -10062,7 +8500,7 @@ OutputFile This option specifies where the logging is printed to. Note that *stdout* and *stderr* are treated as special values, representing "standard out" and "standard error" respectively. No file is created unless logging categories are enabled using the Tracing/Verbosity or Tracing/EnabledCategory settings. -- Full path: //OpenSplice/DDSI2EService/Tracing/OutputFile +- Full path: /DDSI2Service/Tracing/OutputFile - Format: string - Default value: ddsi2.log - Occurrences min-max: 0-1 @@ -10072,7 +8510,7 @@ PacketCaptureFile This option specifies the file to which received and sent packets will be logged in the "pcap" format suitable for analysis using common networking tools, such as WireShark. IP and UDP headers are ficitious, in particular the destination address of received packets. The TTL may be used to distinguish between sent and received packets: it is 255 for sent packets and 128 for received ones. Currently IPv4 only. -- Full path: //OpenSplice/DDSI2EService/Tracing/PacketCaptureFile +- Full path: /DDSI2Service/Tracing/PacketCaptureFile - Format: string - Occurrences min-max: 0-1 @@ -10081,7 +8519,7 @@ Timestamps This option has no effect. -- Full path: //OpenSplice/DDSI2EService/Tracing/Timestamps +- Full path: /DDSI2Service/Tracing/Timestamps - Format: boolean - Default value: true - Occurrences min-max: 0-1 @@ -10090,9 +8528,9 @@ This option has no effect. absolute ^^^^^^^^ -This option has no effect +This attribute specifies whether the timestamps in the log file are absolute or relative to the startup time of the service. Currently not implemented in DDSI2, all timestamps are absolute. -- Full path: //OpenSplice/DDSI2EService/Tracing/Timestamps[@absolute] +- Full path: /DDSI2Service/Tracing/Timestamps/absolute - Format: boolean - Default value: true - Required: false @@ -10102,18 +8540,20 @@ Verbosity This element enables standard groups of categories, based on a desired verbosity level. This is in addition to the categories enabled by the Tracing/EnableCategory setting. Recognised verbosity levels and the categories they map to are: -- *none*: no DDSI2E log +- *none*: no DDSI2 log - *severe*: error and fatal - *warning*: *severe* + warning -- *info*: *warning* + info +- *info*: equivalent to *warning* - *config*: *info* + config - *fine*: *config* + discovery -- *finer*: *fine* + traffic and timing +- *finer*: *fine* + traffic, timing & info - *finest*: *finer* + trace -The categorisation of tracing output is incomplete and hence most of the verbosity levels and categories are not of much use in the current release. This is an ongoing process and here we describe the target situation rather than the current situation. Currently, the most useful verbosity levels are *config*, *fine* and *finest*. +While *none* prevents any message from being written to a DDSI2 log file, warnings and errors are still logged in the ospl-info.log and ospl-error.log files. + +The categorisation of tracing output is incomplete and hence most of the verbosity levels and categories are not of much use in the current release. This is an ongoing process and here we describe the target situation rather than the current situation. Currently, the most useful verbosity levels are *config* and *finest*. -- Full path: //OpenSplice/DDSI2EService/Tracing/Verbosity +- Full path: /DDSI2Service/Tracing/Verbosity - Format: enumeration - Default value: none - Valid values: finest, finer, fine, config, info, warning, severe, none @@ -10124,7 +8564,7 @@ Watchdog This element specifies the type of OS scheduling class will be used by the thread that announces its liveliness periodically. -- Full path: //OpenSplice/DDSI2EService/Watchdog +- Full path: /DDSI2Service/Watchdog - Occurrences min-max: 0-1 Scheduling @@ -10132,7 +8572,7 @@ Scheduling This element specifies the type of OS scheduling class will be used by the thread that announces its liveliness periodically. -- Full path: //OpenSplice/DDSI2EService/Watchdog/Scheduling +- Full path: /DDSI2Service/Watchdog/Scheduling - Occurrences min-max: 0-1 - Child elements: Class, Priority @@ -10141,7 +8581,7 @@ Class This element specifies the thread scheduling class that will be used by the watchdog thread. The user may need the appropriate privileges from the underlying operating system to be able to assign some of the privileged scheduling classes. -- Full path: //OpenSplice/DDSI2EService/Watchdog/Scheduling/Class +- Full path: /DDSI2Service/Watchdog/Scheduling/Class - Format: enumeration - Default value: default - Valid values: realtime, timeshare, default @@ -10152,7 +8592,7 @@ Priority This element specifies the thread priority. Only priorities that are supported by the underlying operating system can be assigned to this element. The user may need special privileges from the underlying operating system to be able to assign some of the privileged priorities. -- Full path: //OpenSplice/DDSI2EService/Watchdog/Scheduling/Priority +- Full path: /DDSI2Service/Watchdog/Scheduling/Priority - Format: integer - Default value: 0 - Occurrences min-max: 0-1 @@ -10163,37 +8603,146 @@ priority_kind This attribute specifies whether the specified Priority is a relative or absolute priority. -- Full path: //OpenSplice/DDSI2EService/Watchdog/Scheduling/Priority[@priority_kind] +- Full path: /DDSI2Service/Watchdog/Scheduling/Priority/priority_kind - Format: enumeration - Default value: relative - Valid values: relative, absolute - Required: false -DDSI2Service -************ +DDSI2EService +************* -The root element of a DDSI2 networking service configuration. +The root element of a DDSI2E networking service configuration. -- Full path: //OpenSplice/DDSI2Service +- Full path: /DDSI2EService - Occurrences min-max: 0-* - Required attributes: name name ==== -This attribute identifies the configuration for the DDSI2 Service. Multiple DDSI2 service configurations can be specified in one single resource. The actual applicable configuration is determined by the value of the name attribute, which must match the specified under the element OpenSplice/Domain/Service[@name] in the Domain Service configuration. +This attribute identifies the configuration for the DDSI2E Service. Multiple DDSI2E service configurations can be specified in one single resource. The actual applicable configuration is determined by the value of the name attribute, which must match the specified under the element OpenSplice/Domain/Service[@name] in the Domain Service configuration. -- Full path: //OpenSplice/DDSI2Service[@name] +- Full path: /DDSI2EService/name - Format: string -- Default value: ddsi2 +- Default value: ddsi2e +- Required: true + +Channels +======== + +This element is used to group a set of channels. The channels are independent data paths through DDSI2E and by using separate threads and setting their priorities appropriately, chanenls can be used to map transport priorities to operating system scheduler priorities, ensuring system-wide end-to-end priority preservation. + +- Full path: /DDSI2EService/Channels +- Occurrences min-max: 0-1 + +Channel +------- + +This element defines a channel. + +- Full path: /DDSI2EService/Channels/Channel +- Occurrences min-max: 0-42 +- Child elements: AuxiliaryBandwidthLimit, DataBandwidthLimit, DiffServField, QueueSize, Resolution +- Required attributes: Name +- Optional attributes: TransportPriority + +Name +^^^^ + +This attribute specifies name of this channel. The name should uniquely identify the channel. + +- Full path: /DDSI2EService/Channels/Channel/Name +- Format: string +- Default value: n/a - Required: true +TransportPriority +^^^^^^^^^^^^^^^^^ + +This attribute sets the transport priority threshold for the channel. Each DCPS data writer has a "transport_priority" QoS and this QoS is used to select a channel for use by this writer. The selected channel is the one with the largest threshold not greater than the writer's transport priority, and if no such channel exists, the channel with the lowest threshold. + +- Full path: /DDSI2EService/Channels/Channel/TransportPriority +- Format: integer +- Default value: 0 +- Required: false + +AuxiliaryBandwidthLimit +^^^^^^^^^^^^^^^^^^^^^^^ + +This element specifies the maximum transmit rate of auxiliary traffic on this channel (e.g. retransmits, heartbeats, etc). Bandwidth limiting uses a leaky bucket scheme. The default value "inf" means DDSI2E imposes no limitation, the underlying operating system and hardware will likely limit the maimum transmit rate. +The unit must be specified explicitly. Recognised units: *X*b/s, *X*bps for bits/s or *X*B/s, *X*Bps for bytes/s; where *X* is an optional prefix: k for 10 :sup:`3`, Ki for 2 :sup:`10`, M for 10 :sup:`6`, Mi for 2 :sup:`20`, G for 10 :sup:`9`, Gi for 2 :sup:`30`. + +- Full path: /DDSI2EService/Channels/Channel/AuxiliaryBandwidthLimit +- Format: string +- Default value: inf +- Occurrences min-max: 0-1 + +DataBandwidthLimit +^^^^^^^^^^^^^^^^^^ + +This element specifies the maximum transmit rate of new samples and directly related data, for this channel. Bandwidth limiting uses a leaky bucket scheme. The default value "inf" means DDSI2E imposes no limitation, the underlying operating system and hardware will likely limit the maimum transmit rate. + +The unit must be specified explicitly. Recognised units: *X*b/s, *X*bps for bits/s or *X*B/s, *X*Bps for bytes/s; where *X* is an optional prefix: k for 10 :sup:`3`, Ki for 2 :sup:`10`, M for 10 :sup:`6`, Mi for 2 :sup:`20`, G for 10 :sup:`9`, Gi for 2 :sup:`30`. + +- Full path: /DDSI2EService/Channels/Channel/DataBandwidthLimit +- Format: string +- Default value: inf +- Occurrences min-max: 0-1 + +DiffServField +^^^^^^^^^^^^^ + +This element describes the DiffServ setting the channel will apply to the networking messages. This parameter determines the value of the diffserv field of the IP version 4 packets send on this channel which allows QoS setting to be applied to the network traffic send on this channel. + +Windows platform support for setting the diffserv field is dependent on the OS version. + +For Windows versions XP SP2 and 2003 to use the diffserv field the following parameter should be added to the register: + + +HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\TcpIp\\Parameters\\DisableUserTOSSetting + + +The type of this parameter is a DWORD and it's value should be set to 0 to allow setting of the diffserv field. + + +For Windows version 7 or higher a new API (qWAVE) has been introduced For these platforms the specified diffserv value is mapped to one of the support traffic types. +The mapping is as follows: 1-8 background traffic; 9-40 excellent traffic; 41-55 audio/video traffic; 56 voice traffic; 57-63 control traffic. +When an application is run without Administrative priveleges then only the diffserv value of 0, 8, 40 or 56 is allowed. + +- Full path: /DDSI2EService/Channels/Channel/DiffServField +- Format: integer +- Default value: 0 +- Occurrences min-max: 0-1 + +QueueSize +^^^^^^^^^ + +This element specifies the number of messages the network queue for this channel can contain. The OpenSplice kernel writes data to be transmitted to the network queue, and DDSI2E takes them from this queue. If this queue is full when an application tries to write a sample, the sample will be dropped or the writer suspended, depending on the QoS settings of the writer. OpenSplice and its services are optimised for a well-balanced system design, where the queue never becomes full. + +- Full path: /DDSI2EService/Channels/Channel/QueueSize +- Format: integer +- Default value: 0 +- Occurrences min-max: 0-1 + +Resolution +^^^^^^^^^^ + +This element specifies the interval at which the DDSI transmit thread for this channel wakes up, and which controls the smallest latency_budget that has an effect. A shorter latency_budget is rounded to 0. The downside of a reducing this setting is that it increases the number of idle wake-ups of the transmit thread when there is no data to be sent. + +Valid values are finite durations with an explicit unit or the keyword 'inf' for infinity. Recognised units: ns, us, ms, s, min, hr, day. + +- Full path: /DDSI2EService/Channels/Channel/Resolution +- Format: string +- Default value: 1s +- Occurrences min-max: 0-1 + Compatibility ============= The Compatibility elements allows specifying various settings related to compatability with standards and with other DDSI implementations. -- Full path: //OpenSplice/DDSI2Service/Compatibility +- Full path: /DDSI2EService/Compatibility - Occurrences min-max: 0-1 - Child elements: AckNackNumbitsEmptySet, ArrivalOfDataAssertsPpAndEpLiveliness, AssumeRtiHasPmdEndpoints, ExplicitlyPublishQosSetToDefault, ManySocketsMode, RespondToRtiInitZeroAckWithInvalidHeartbeat, StandardsConformance @@ -10202,9 +8751,9 @@ AckNackNumbitsEmptySet This element governs the representation of an acknowledgement message that does not also negatively-acknowledge some samples. If set to 0, the generated acknowledgements have an invalid form and will be reject by the strict and pedantic conformance modes, but several other implementation require this setting for smooth interoperation. -If set to 1, all acknowledgements sent by DDSI2 adhere the form of acknowledgement messages allowed by the standard, but this causes problems when interoperating with these other implementations. The strict and pedantic standards conformance modes always overrule an AckNackNumbitsEmptySet=0 to prevent the transmitting of invalid messages. +If set to 1, all acknowledgements sent by DDSI2E adhere the form of acknowledgement messages allowed by the standard, but this causes problems when interoperating with these other implementations. The strict and pedantic standards conformance modes always overrule a AckNackNumbitsEmptySet=0 to prevent the transmitting of invalid messages. -- Full path: //OpenSplice/DDSI2Service/Compatibility/AckNackNumbitsEmptySet +- Full path: /DDSI2EService/Compatibility/AckNackNumbitsEmptySet - Format: integer - Default value: 0 - Occurrences min-max: 0-1 @@ -10212,9 +8761,9 @@ If set to 1, all acknowledgements sent by DDSI2 adhere the form of acknowledgeme ArrivalOfDataAssertsPpAndEpLiveliness ------------------------------------- -When set to true, arrival of a message from a peer asserts liveliness of that peer. When set to false, only SPDP and explicit lease renewals have this effect. +This setting is currently ignored (accepted for backwards compatibility). -- Full path: //OpenSplice/DDSI2Service/Compatibility/ArrivalOfDataAssertsPpAndEpLiveliness +- Full path: /DDSI2EService/Compatibility/ArrivalOfDataAssertsPpAndEpLiveliness - Format: boolean - Default value: true - Occurrences min-max: 0-1 @@ -10224,7 +8773,7 @@ AssumeRtiHasPmdEndpoints This option assumes ParticipantMessageData endpoints required by the liveliness protocol are present in RTI participants even when not properly advertised by the participant discovery protocol. -- Full path: //OpenSplice/DDSI2Service/Compatibility/AssumeRtiHasPmdEndpoints +- Full path: /DDSI2EService/Compatibility/AssumeRtiHasPmdEndpoints - Format: boolean - Default value: false - Occurrences min-max: 0-1 @@ -10236,7 +8785,7 @@ This element specifies whether QoS settings set to default values are explicitly When interoperability is required with an implementation that does not follow the specifications in this regard, setting this option to true will help. -- Full path: //OpenSplice/DDSI2Service/Compatibility/ExplicitlyPublishQosSetToDefault +- Full path: /DDSI2EService/Compatibility/ExplicitlyPublishQosSetToDefault - Format: boolean - Default value: false - Occurrences min-max: 0-1 @@ -10244,11 +8793,11 @@ When interoperability is required with an implementation that does not follow th ManySocketsMode --------------- -This option specifies whether a network socket will be created for each domain participant on a host. The specification seems to assume that each participant has a unique address, and setting this option will ensure this to be the case. This is not the defeault. +This option specifies whether a network socket will be created for each domain participant on a host. The specification seems to assume that each participant has a unique address, and setting this option will ensure this to be the case. This is not the default. -Disabling it slightly improves performance and reduces network traffic somewhat. It also causes the set of port numbers needed by DDSI2 to become predictable, which may be useful for firewall and NAT configuration. +Disabling it slightly improves performance and reduces network traffic somewhat. It also causes the set of port numbers needed by DDSI2E to become predictable, which may be useful for firewall and NAT configuration. -- Full path: //OpenSplice/DDSI2Service/Compatibility/ManySocketsMode +- Full path: /DDSI2EService/Compatibility/ManySocketsMode - Format: boolean - Default value: false - Occurrences min-max: 0-1 @@ -10260,7 +8809,7 @@ This element allows a closer mimicking of the behaviour of some other DDSI imple The latter is fully compliant with the specification, and no adverse effects have been observed. It is the default. -- Full path: //OpenSplice/DDSI2Service/Compatibility/RespondToRtiInitZeroAckWithInvalidHeartbeat +- Full path: /DDSI2EService/Compatibility/RespondToRtiInitZeroAckWithInvalidHeartbeat - Format: boolean - Default value: false - Occurrences min-max: 0-1 @@ -10268,7 +8817,7 @@ The latter is fully compliant with the specification, and no adverse effects hav StandardsConformance -------------------- -This element sets the level of standards conformance of this instance of the DDSI2 Service. Stricter conformance typically means less interoperability with other implementations. Currently three modes are defined: +This element sets the level of standards conformance of this instance of the DDSI2E Service. Stricter conformance typically means less interoperability with other implementations. Currently three modes are defined: - *pedantic*: very strictly conform to the specification, ultimately for compliancy testing, but currently of little value because it adheres even to what will most likely turn out to be editing errors in the DDSI standard. Arguably, as long as no errata have been published it is the current text that is in effect, and that is what pedantic currently does. - *strict*: a slightly less strict view of the standard than does pedantic: it follows the established behaviour where the standard is obviously in error. @@ -10276,7 +8825,7 @@ This element sets the level of standards conformance of this instance of the DDS The default setting is "lax". -- Full path: //OpenSplice/DDSI2Service/Compatibility/StandardsConformance +- Full path: /DDSI2EService/Compatibility/StandardsConformance - Format: enumeration - Default value: lax - Valid values: lax, strict, pedantic @@ -10286,27 +8835,17 @@ Discovery ========= The Discovery element allows specifying various parameters related to the discovery of peers. - -- Full path: //OpenSplice/DDSI2Service/Discovery -- Occurrences min-max: 0-1 -- Child elements: AdvertiseBuiltinTopicWriters, DefaultMulticastAddress, DomainId, GenerateBuiltinTopics, LocalDiscoveryPartition, MaxAutoParticipantIndex, ParticipantIndex, SPDPInterval, SPDPMulticastAddress - -AdvertiseBuiltinTopicWriters ----------------------------- - -This element controls whether or not DDSI2 advertises writers for the built-in topics from its discovery for backwards compatibility with older OpenSplice versions. - -- Full path: //OpenSplice/DDSI2Service/Discovery/AdvertiseBuiltinTopicWriters -- Format: boolean -- Default value: true + +- Full path: /DDSI2EService/Discovery - Occurrences min-max: 0-1 +- Child elements: DefaultMulticastAddress, DomainId, DSClusterLeaseDuration, GenerateBuiltinTopics, LocalDiscoveryPartition, MaxAutoParticipantIndex, ParticipantIndex, SPDPInterval, SPDPMulticastAddress DefaultMulticastAddress ----------------------- -This element specifies the default multicast address for all traffic other than participant discovery packets. It defaults to Discovery/SPDPMulticastAddress. + This element specifies the default multicast address for all multicast traffic other than the SPDP participant discovery data. The default value "auto" uses the configured SPDPMulticastAddress. On source-specific multicast capable platforms, this is may be an source-specific multicast address. -- Full path: //OpenSplice/DDSI2Service/Discovery/DefaultMulticastAddress +- Full path: /DDSI2EService/Discovery/DefaultMulticastAddress - Format: string - Default value: auto - Occurrences min-max: 0-1 @@ -10314,19 +8853,31 @@ This element specifies the default multicast address for all traffic other than DomainId -------- -This element allows overriding of the DDS Domain Id that is used for DDSI2. +This element allows overriding of the DDS Domain Id that is used for this DDSI2E service. -- Full path: //OpenSplice/DDSI2Service/Discovery/DomainId +- Full path: /DDSI2EService/Discovery/DomainId - Format: string - Default value: default - Occurrences min-max: 0-1 +DSClusterLeaseDuration +---------------------- + + This element specifies the lease duration for entities discovered through a discovery service. + + Valid values are finite durations with an explicit unit or the keyword 'inf' for infinity. Recognised units: ns, us, ms, s, min, hr, day. + +- Full path: /DDSI2EService/Discovery/DSClusterLeaseDuration +- Format: string +- Default value: 300 s +- Occurrences min-max: 0-1 + GenerateBuiltinTopics --------------------- -This element controls whether or not DDSI2 generates built-in topics from its discovery. When disabled, it relies on the durability service. +This element controls whether or not the DDSI2E service generates built-in topics from its discovery. When disabled, it relies on the durability service. -- Full path: //OpenSplice/DDSI2Service/Discovery/GenerateBuiltinTopics +- Full path: /DDSI2EService/Discovery/GenerateBuiltinTopics - Format: boolean - Default value: true - Occurrences min-max: 0-1 @@ -10334,9 +8885,9 @@ This element controls whether or not DDSI2 generates built-in topics from its di LocalDiscoveryPartition ----------------------- -This element controls which partition is monitored by DDSI2 for built-in topics describing entities the it mirrors in DDSI. +This element controls which partition is monitored by DDSI2E for built-in topics describing entities the it mirrors in DDSI. -- Full path: //OpenSplice/DDSI2Service/Discovery/LocalDiscoveryPartition +- Full path: /DDSI2EService/Discovery/LocalDiscoveryPartition - Format: string - Default value: __BUILT_IN_PARTITION__ - Occurrences min-max: 0-1 @@ -10344,9 +8895,9 @@ This element controls which partition is monitored by DDSI2 for built-in topics MaxAutoParticipantIndex ----------------------- -This element specifies the maximum DDSI participant index selected by this instance of the DDSI2 service if the Discovery/ParticipantIndex is "auto". +This element specifies the maximum DDSI participant index selected by this instance of the DDSI2E service if the Discovery/ParticipantIndex is "auto". -- Full path: //OpenSplice/DDSI2Service/Discovery/MaxAutoParticipantIndex +- Full path: /DDSI2EService/Discovery/MaxAutoParticipantIndex - Format: integer - Default value: 9 - Occurrences min-max: 0-1 @@ -10354,7 +8905,7 @@ This element specifies the maximum DDSI participant index selected by this insta ParticipantIndex ---------------- -This element specifies the DDSI participant index used by this instance of the DDSI2 service for discovery purposes. Only one such participant id is used, independent of the number of actual DomainParticipants on the node. It is either: +This element specifies the DDSI participant index used by this instance of the DDSI2E service for discovery purposes. Only one such participant id is used, independent of the number of actual DomainParticipants on the node. It is either: - *auto*: which will attempt to automatically determine an available participant index (see also Discovery/MaxAutoParticipantIndex), or - a non-negative integer less than 120, or @@ -10362,7 +8913,7 @@ This element specifies the DDSI participant index used by this instance of the D The default is *auto*. The participant index is part of the port number calculation and if predictable port numbers are needed and fixing the participant index has no adverse effects, it is recommended that the second be option be used. -- Full path: //OpenSplice/DDSI2Service/Discovery/ParticipantIndex +- Full path: /DDSI2EService/Discovery/ParticipantIndex - Format: string - Default value: auto - Occurrences min-max: 0-1 @@ -10372,7 +8923,7 @@ Peers This element statically configures addresses for discovery. -- Full path: //OpenSplice/DDSI2Service/Discovery/Peers +- Full path: /DDSI2EService/Discovery/Peers - Occurrences min-max: 0-1 Group @@ -10380,7 +8931,7 @@ Group This element statically configures a fault tolerant group of addresses for discovery. Each member of the group is tried in sequence until one succeeds. -- Full path: //OpenSplice/DDSI2Service/Discovery/Peers/Group +- Full path: /DDSI2EService/Discovery/Peers/Group - Occurrences min-max: 0-* Peer @@ -10388,16 +8939,16 @@ Peer This element statically configures an addresses for discovery. -- Full path: //OpenSplice/DDSI2Service/Discovery/Peers/Group/Peer +- Full path: /DDSI2EService/Discovery/Peers/Group/Peer - Occurrences min-max: 0-* - Required attributes: Address Address +++++++ -This element specifies an IP address to which discovery packets must be sent, in addition to the default multicast address (see also General/AllowMulticast). Both a hostnames and a numerical IP address is accepted; the hostname or IP address may be suffixed with :PORT to explicitly set the port to which it must be sent. Multiple Peers may be specified. +This element specifies an IP address to which discovery packets must be sent, in addition to the default multicast address (see also General/AllowMulticast and Internal/SuppressSPDPMulticast). Both a hostnames and a numerical IP address is accepted; the hostname or IP address may be suffixed with :PORT to explicitly set the port to which it must be sent. Multiple Peers may be specified. -- Full path: //OpenSplice/DDSI2Service/Discovery/Peers/Group/Peer[@Address] +- Full path: /DDSI2EService/Discovery/Peers/Group/Peer/Address - Format: string - Default value: n/a - Required: true @@ -10405,18 +8956,18 @@ This element specifies an IP address to which discovery packets must be sent, in Peer ^^^^ -This element statically configures an addresses for discovery. +This element statically configures an address for discovery. -- Full path: //OpenSplice/DDSI2Service/Discovery/Peers/Peer +- Full path: /DDSI2EService/Discovery/Peers/Peer - Occurrences min-max: 0-* - Required attributes: Address Address ~~~~~~~ -This element specifies an IP address to which discovery packets must be sent, in addition to the default multicast address (see also General/AllowMulticast). Both a hostnames and a numerical IP address is accepted; the hostname or IP address may be suffixed with :PORT to explicitly set the port to which it must be sent. Multiple Peers may be specified. +This element specifies an IP address to which discovery packets must be sent, in addition to the default multicast address (see also General/AllowMulticast and Internal/SuppressSPDPMulticast). Both a hostnames and a numerical IP address is accepted; the hostname or IP address may be suffixed with :PORT to explicitly set the port to which it must be sent. Multiple Peers may be specified. -- Full path: //OpenSplice/DDSI2Service/Discovery/Peers/Peer[@Address] +- Full path: /DDSI2EService/Discovery/Peers/Peer/Address - Format: string - Default value: n/a - Required: true @@ -10426,7 +8977,9 @@ Ports The Ports element allows specifying various parameters related to the port numbers used for discovery. These all have default values specified by the DDSI 2.1 specification and rarely need to be changed. -- Full path: //OpenSplice/DDSI2Service/Discovery/Ports +Valid values are finite durations with an explicit unit or the keyword 'inf' for infinity. Recognised units: ns, us, ms, s, min, hr, day. + +- Full path: /DDSI2EService/Discovery/Ports - Occurrences min-max: 0-1 - Child elements: Base, DomainGain, MulticastDataOffset, MulticastMetaOffset, ParticipantGain, UnicastDataOffset, UnicastMetaOffset @@ -10435,10 +8988,9 @@ Base This element specifies the base port number (refer to the DDSI 2.1 specification, section 9.6.1, constant PB). -- Full path: //OpenSplice/DDSI2Service/Discovery/Ports/Base +- Full path: /DDSI2EService/Discovery/Ports/Base - Format: integer - Default value: 7400 -- Valid values: 1 / 65535 - Occurrences min-max: 0-1 DomainGain @@ -10446,7 +8998,7 @@ DomainGain This element specifies the domain gain, relating domain ids to sets of port numbers (refer to the DDSI 2.1 specification, section 9.6.1, constant DG). -- Full path: //OpenSplice/DDSI2Service/Discovery/Ports/DomainGain +- Full path: /DDSI2EService/Discovery/Ports/DomainGain - Format: integer - Default value: 250 - Occurrences min-max: 0-1 @@ -10456,7 +9008,7 @@ MulticastDataOffset This element specifies the port number for multicast meta traffic (refer to the DDSI 2.1 specification, section 9.6.1, constant d2). -- Full path: //OpenSplice/DDSI2Service/Discovery/Ports/MulticastDataOffset +- Full path: /DDSI2EService/Discovery/Ports/MulticastDataOffset - Format: integer - Default value: 1 - Occurrences min-max: 0-1 @@ -10466,7 +9018,7 @@ MulticastMetaOffset This element specifies the port number for multicast meta traffic (refer to the DDSI 2.1 specification, section 9.6.1, constant d0). -- Full path: //OpenSplice/DDSI2Service/Discovery/Ports/MulticastMetaOffset +- Full path: /DDSI2EService/Discovery/Ports/MulticastMetaOffset - Format: integer - Default value: 0 - Occurrences min-max: 0-1 @@ -10476,7 +9028,7 @@ ParticipantGain This element specifies the participant gain, relating p0, articipant index to sets of port numbers (refer to the DDSI 2.1 specification, section 9.6.1, constant PG). -- Full path: //OpenSplice/DDSI2Service/Discovery/Ports/ParticipantGain +- Full path: /DDSI2EService/Discovery/Ports/ParticipantGain - Format: integer - Default value: 2 - Occurrences min-max: 0-1 @@ -10486,7 +9038,7 @@ UnicastDataOffset This element specifies the port number for unicast meta traffic (refer to the DDSI 2.1 specification, section 9.6.1, constant d3). -- Full path: //OpenSplice/DDSI2Service/Discovery/Ports/UnicastDataOffset +- Full path: /DDSI2EService/Discovery/Ports/UnicastDataOffset - Format: integer - Default value: 11 - Occurrences min-max: 0-1 @@ -10496,7 +9048,7 @@ UnicastMetaOffset This element specifies the port number for unicast meta traffic (refer to the DDSI 2.1 specification, section 9.6.1, constant d1). -- Full path: //OpenSplice/DDSI2Service/Discovery/Ports/UnicastMetaOffset +- Full path: /DDSI2EService/Discovery/Ports/UnicastMetaOffset - Format: integer - Default value: 10 - Occurrences min-max: 0-1 @@ -10508,10 +9060,9 @@ This element specifies the interval between spontaneous transmissions of partici The unit must be specified explicitly. Recognised units: ns, us, ms, s, min, hr, day. -- Full path: //OpenSplice/DDSI2Service/Discovery/SPDPInterval +- Full path: /DDSI2EService/Discovery/SPDPInterval - Format: string - Default value: 30 s -- Valid values: 0 / 1hr - Occurrences min-max: 0-1 SPDPMulticastAddress @@ -10519,7 +9070,7 @@ SPDPMulticastAddress This element specifies the multicast address that is used as the destination for the participant discovery packets. In IPv4 mode the default is the (standardised) 239.255.0.1, in IPv6 mode it becomes ff02::ffff:239.255.0.1, which is a non-standardised link-local multicast address. -- Full path: //OpenSplice/DDSI2Service/Discovery/SPDPMulticastAddress +- Full path: /DDSI2EService/Discovery/SPDPMulticastAddress - Format: string - Default value: 239.255.0.1 - Occurrences min-max: 0-1 @@ -10527,28 +9078,28 @@ This element specifies the multicast address that is used as the destination for General ======= -The General element specifies overall DDSI2 service settings. +The General element specifies overall DDSI2E service settings. -- Full path: //OpenSplice/DDSI2Service/General +- Full path: /DDSI2EService/General - Occurrences min-max: 0-1 -- Child elements: AllowMulticast, CoexistWithNativeNetworking, DontRoute, EnableMulticastLoopback, ExternalNetworkAddress, ExternalNetworkMask, FragmentSize, MaxMessageSize, MulticastRecvNetworkInterfaceAddresses, MulticastTimeToLive, NetworkInterfaceAddress, StartupModeCoversTransient, StartupModeDuration, UseIPv6 +- Child elements: AllowMulticast, CoexistWithNativeNetworking, DontRoute, EnableMulticastLoopback, ExternalNetworkAddress, ExternalNetworkMask, MulticastRecvNetworkInterfaceAddresses, MulticastTimeToLive, NetworkInterfaceAddress, StartupModeCoversTransient, StartupModeDuration, UseIPv6 AllowMulticast -------------- -This element controls whether DDSI2 uses multicasts for data traffic. +This element controls whether the DDSI2E service uses multicasts for data traffic. It is a comma-separated list of keywords, with the following keywords defined: -It is a comma-separated list of some of the following keywords: "spdp", "asm", "ssm", or either of "false" or "true". +- *spdp*: allow multicast for the SPDP participant discovery protocol. This is the initial step in the discovery protocol, and benefits tremendously from using multicast. +- *asm*: allow (any-source) multicast for all traffic. +- *ssm*: allow source-specific multicast for all traffic (on supported platforms). -- *spdp*: enables the use of ASM (any-source multicast) for participant discovery -- *asm*: enables the use of ASM for all traffic (including SPDP) -- *ssm*: enables the use of SSM (source-specific multicast) for all non-SPDP traffic (if supported) +Additionally, "false" is allowed as a synonym for an empty list, and "true" for "spdp,asm,ssm". -When set to "false" all multicasting is disabled. The default, "true" enables full use of multicasts. Listening for multicasts can be controlled by General/MulticastRecvNetworkInterfaceAddresses. +The default is to allow unlimited use of multicast. -- Full path: //OpenSplice/DDSI2Service/General/AllowMulticast +- Full path: /DDSI2EService/General/AllowMulticast - Format: string - Default value: true - Occurrences min-max: 0-1 @@ -10556,9 +9107,9 @@ When set to "false" all multicasting is disabled. The default, "true" enables fu CoexistWithNativeNetworking --------------------------- -This element specifies whether the DDSI2 service operates in conjunction with the OpenSplice RT Networking service. When "false", the DDSI2 service will take care of all communications, including those between OpenSplice nodes; when "true", the DDSI2 service only communicates with DDS implementations other than OpenSplice. In this case the RT Networking service should be configured as well. +This element specifies whether the DDSI2E service operates in conjunction with the OpenSplice RT Networking service. When "false", the DDSI2E service will take care of all communications, including those between OpenSplice nodes; when "true", the DDSI2E service only communicates with DDS implementations other than OpenSplice. In this case the RT Networking service should be configured as well. -- Full path: //OpenSplice/DDSI2Service/General/CoexistWithNativeNetworking +- Full path: /DDSI2EService/General/CoexistWithNativeNetworking - Format: boolean - Default value: false - Occurrences min-max: 0-1 @@ -10568,7 +9119,7 @@ DontRoute This element allows setting the SO_DONTROUTE option for outgoing packets, to bypass the local routing tables. This is generally useful only when the routing tables cannot be trusted, which is highly unusual. -- Full path: //OpenSplice/DDSI2Service/General/DontRoute +- Full path: /DDSI2EService/General/DontRoute - Format: boolean - Default value: false - Occurrences min-max: 0-1 @@ -10576,9 +9127,9 @@ This element allows setting the SO_DONTROUTE option for outgoing packets, to byp EnableMulticastLoopback ----------------------- -This element specifies whether DDSI2 allows IP multicast packets to be visible to all DDSI participants in the same node, including itself. It must be "true" for intra-node multicast communications, but if a node runs only a single DDSI2 service and does not host any other DDSI-capable programs, it should be set to "false" for improved performance. +This element specifies whether the DDSI2E service will allow IP multicast packets to be visible to all DDSI participants in the same node, including itself. It must be "true" for intra-node multicast communications, but if a node runs only a single DDSI2E service and does not host any other DDSI-capable programs, it may be set to "false" for improved performance. -- Full path: //OpenSplice/DDSI2Service/General/EnableMulticastLoopback +- Full path: /DDSI2EService/General/EnableMulticastLoopback - Format: boolean - Default value: true - Occurrences min-max: 0-1 @@ -10586,9 +9137,9 @@ This element specifies whether DDSI2 allows IP multicast packets to be visible t ExternalNetworkAddress ---------------------- -This element allows explicitly overruling the network address DDSI2 advertises in the discovery protocol, which by default is the address of the preferred network interface (General/NetworkInterfaceAddress), to allow DDSI2 to communicate across a Network Address Translation (NAT) device. +This element allows explicitly overruling the network address the DDSI2E service advertises in the discovery protocol, which by default is the address of the preferred network interface (General/NetworkInterfaceAddress), to allow DDSI2E to communicate across a Network Address Translation (NAT) device. -- Full path: //OpenSplice/DDSI2Service/General/ExternalNetworkAddress +- Full path: /DDSI2EService/General/ExternalNetworkAddress - Format: string - Default value: auto - Occurrences min-max: 0-1 @@ -10598,53 +9149,25 @@ ExternalNetworkMask This element specifies the network mask of the external network address. This element is relevant only when an external network address (General/ExternalNetworkAddress) is explicitly configured. In this case locators received via the discovery protocol that are within the same external subnet (as defined by this mask) will be translated to an internal address by replacing the network portion of the external address with the corresponding portion of the preferred network interface address. This option is IPv4-only. -- Full path: //OpenSplice/DDSI2Service/General/ExternalNetworkMask +- Full path: /DDSI2EService/General/ExternalNetworkMask - Format: string - Default value: 0.0.0.0 - Occurrences min-max: 0-1 -FragmentSize ------------- - -This element specifies the size of DDSI sample fragments generated by DDSI2. Samples larger than FragmentSize are fragmented into fragments of FragmentSize bytes each, except the last one, which may be smaller. The DDSI spec mandates a minimum fragment size of 1025 bytes, but DDSI2 will do whatever size is requested, accepting fragments of which the size is at least the minimum of 1025 and FragmentSize. - -The unit must be specified explicitly. Recognised units: B (bytes), kB & KiB (2 :sup:`10` bytes), MB & MiB (2 :sup:`20` bytes), GB & GiB (2 :sup:`30` bytes). - -- Full path: //OpenSplice/DDSI2Service/General/FragmentSize -- Format: string -- Default value: 1280 B -- Occurrences min-max: 0-1 - -MaxMessageSize --------------- - -This element specifies the maximum size of the UDP payload that DDSI2 will generate. DDSI2 will try to maintain this limit within the bounds of the DDSI specification, which means that in some cases (especially for very low values of MaxMessageSize) larger payloads may sporadically be observed (currently up to 1192 B). - -On some networks it may be necessary to set this item to keep the packetsize below the MTU to prevent IP fragmentation. In those cases, it is generally advisable to also consider reducing Internal/FragmentSize. - -The unit must be specified explicitly. Recognised units: B (bytes), kB & KiB (2 :sup:`10` bytes), MB & MiB (2 :sup:`20` bytes), GB & GiB (2 :sup:`30` bytes). - -- Full path: //OpenSplice/DDSI2Service/General/MaxMessageSize -- Format: string -- Default value: 4096 B -- Occurrences min-max: 0-1 - MulticastRecvNetworkInterfaceAddresses -------------------------------------- -This element specifies on which network interfaces DDSI2 listens to multicasts. The following options are available: - +This element specifies on which network interfaces DDSI2E listens to multicasts. The following options are available: +- *preferred*: listen for multicasts on the preferred interface (General/NetworkInterfaceAddress); or - *all*: listen for multicasts on all multicast-capable interfaces; or - *any*: listen for multicasts on the operating system default interface; or -- *preferred*: listen for multicasts on the preferred interface (General/NetworkInterfaceAddress); or - *none*: does not listen for multicasts on any interface; or -- a comma-separated list of network addresses: configures DDSI2 to listen for multicasts on all of the listed addresses. - +- a comma-separated list of network addresses: configures DDSI2E to listen for multicasts on all of the listed addresses. -If DDSI2 is in IPv6 mode and the address of the preferred network interface is a link-local address, "all" is treated as a synonym for "preferred" and a comma-separated list is treated as "preferred" if it contains the preferred interface and as "none" if not. +If DDSI2E is in IPv6 mode and the address of the preferred network interface is a link-local address, "all" is treated as a synonym for "preferred" and a comma-separated list is treated as "preferred" if it contains the preferred interface and as "none" if not. -- Full path: //OpenSplice/DDSI2Service/General/MulticastRecvNetworkInterfaceAddresses +- Full path: /DDSI2EService/General/MulticastRecvNetworkInterfaceAddresses - Format: string - Default value: preferred - Occurrences min-max: 0-1 @@ -10654,18 +9177,17 @@ MulticastTimeToLive This element specifies the time-to-live setting for outgoing multicast packets. -- Full path: //OpenSplice/DDSI2Service/General/MulticastTimeToLive +- Full path: /DDSI2EService/General/MulticastTimeToLive - Format: integer - Default value: 32 -- Valid values: 0 / 255 - Occurrences min-max: 0-1 NetworkInterfaceAddress ----------------------- -This element specifies the preferred network interface for use by DDSI2. The preferred network interface determines the IP address that DDSI2 advertises in the discovery protocol (but see also General/ExternalNetworkAddress), and is also the only interface over which multicasts are transmitted. The interface can be identified by its IP address, network interface name or network portion of the address. If the value "auto" is entered here, DDSI2 will select what it considers the most suitable interface. +This element specifies the preferred network interface for use by DDSI2E. The preferred network interface determines the IP address that DDSI2E advertises in the discovery protocol (but see also General/ExternalNetworkAddress), and is also the only interface over which multicasts are transmitted. The interface can be identified by its IP address, network interface name or network portion of the address. If the value "auto" is entered here, DDSI2E will select what it considers the most suitable interface. -- Full path: //OpenSplice/DDSI2Service/General/NetworkInterfaceAddress +- Full path: /DDSI2EService/General/NetworkInterfaceAddress - Format: string - Default value: auto - Occurrences min-max: 0-1 @@ -10673,9 +9195,9 @@ This element specifies the preferred network interface for use by DDSI2. The pre StartupModeCoversTransient -------------------------- -This element configures whether startup-mode should also cover transient and persistent data, for configurations where the durability service does not take care of it. Configurations without defined merge policies best leave this enabled. +This element configures whether startup-mode should also cover transient and persistent data, for configurations where the durability servie does not take care of it. Configurations without defined merge policies best leave this enabled. -- Full path: //OpenSplice/DDSI2Service/General/StartupModeCoversTransient +- Full path: /DDSI2EService/General/StartupModeCoversTransient - Format: boolean - Default value: true - Occurrences min-max: 0-1 @@ -10683,26 +9205,25 @@ This element configures whether startup-mode should also cover transient and per StartupModeDuration ------------------- -This element specifies how long the DDSI2 remains in its "startup" mode. While in "startup" mode all volatile reliable data published on the local node is retained as-if it were transient-local data, allowing existing readers on remote nodes to obtain the data even though discovering them takes some time. Best-effort data by definition need not arrive, and transient and persistent data are covered by the durability service. +This element specifies how long the DDSI2E remains in its "startup" mode. While in "startup" mode all volatile reliable data published on the local node is retained as-if it were transient-local data, allowing existing readers on remote nodes to obtain the data even though discovering them takes some time. Best-effort data by definition need not arrive, and transient and persistent data are covered by the durability service. -Once the system is stable, DDSI2 keeps track of the existence of remote readers whether or not matching writers exist locally, avoiding this discovery delay and ensuring this is merely a node startup issue. +Once the system is stable, the DDSI2E service keeps track of the existence of remote readers whether or not matching writers exist locally, avoiding this discovery delay and ensuring this is merely a node startup issue. Setting General/StartupModeDuration to 0s will disable it. The unit must be specified explicitly. Recognised units: ns, us, ms, s, min, hr, day. -- Full path: //OpenSplice/DDSI2Service/General/StartupModeDuration +- Full path: /DDSI2EService/General/StartupModeDuration - Format: string - Default value: 2 s -- Valid values: 0 / 60000 - Occurrences min-max: 0-1 UseIPv6 ------- -This element can be used to DDSI2 use IPv6 instead of IPv4. This is currently an either/or switch. +This element can be used to make DDSI2E service use IPv6 instead of IPv4. This is currently an either/or switch. -- Full path: //OpenSplice/DDSI2Service/General/UseIPv6 +- Full path: /DDSI2EService/General/UseIPv6 - Format: boolean - Default value: false - Occurrences min-max: 0-1 @@ -10712,26 +9233,26 @@ Internal The Internal elements deal with a variety of settings that evolving and that are not necessarily fully supported. For the vast majority of the Internal settings, the functionality per-se is supported, but the right to change the way the options control the functionality is reserved. This includes renaming or moving options. -- Full path: //OpenSplice/DDSI2Service/Internal +- Full path: /DDSI2EService/Internal - Occurrences min-max: 0-1 -- Child elements: AccelerateRexmitBlockSize, AggressiveKeepLastWhc, AssumeMulticastCapable, BuiltinEndpointSet, ConservativeBuiltinReaderStartup, DDSI2DirectMaxThreads, DefragReliableMaxSamples, DefragUnreliableMaxSamples, DeliveryQueueMaxSamples, ForwardAllMessages, ForwardRemoteData, GenerateKeyhash, LateAckMode, LeaseDuration, LegacyFragmentation, LogStackTraces, MaxParticipants, MaxQueuedRexmitBytes, MaxQueuedRexmitMessages, MaxSampleSize, MeasureHbToAckLatency, MinimumSocketReceiveBufferSize, MinimumSocketSendBufferSize, MirrorRemoteEntities, MonitorPort, NackDelay, PreEmptiveAckDelay, PrimaryReorderMaxSamples, PrioritizeRetransmit, RediscoveryBlacklistDuration, ResponsivenessTimeout, RetransmitMerging, RetransmitMergingPeriod, RetryOnRejectBestEffort, RetryOnRejectDuration, SPDPResponseMaxDelay, ScheduleTimeRounding, SecondaryReorderMaxSamples, SquashParticipants, SuppressSPDPMulticast, SynchronousDeliveryLatencyBound, SynchronousDeliveryPriorityThreshold, UnicastResponseToSPDPMessages, UseMulticastIfMreqn, WriterLingerDuration +- Child elements: AccelerateRexmitBlockSize, AggressiveKeepLast1Whc, AssumeMulticastCapable, AuxiliaryBandwidthLimit, BuiltinEndpointSet, ConservativeBuiltinReaderStartup, DDSI2DirectMaxThreads, DefragReliableMaxSamples, DefragUnreliableMaxSamples, DeliveryQueueMaxSamples, ForwardAllMessages, ForwardRemoteData, FragmentSize, GenerateKeyhash, LateAckMode, LeaseDuration, LegacyFragmentation, LogStackTraces, MaxMessageSize, MaxParticipants, MaxQueuedRexmitBytes, MaxQueuedRexmitMessages, MaxSampleSize, MeasureHbToAckLatency, MinimumSocketReceiveBufferSize, MinimumSocketSendBufferSize, MirrorRemoteEntities, NackDelay, PreEmptiveAckDelay, PrimaryReorderMaxSamples, ResponsivenessTimeout, RetransmitMerging, RetransmitMergingPeriod, RetryOnRejectBestEffort, RetryOnRejectDuration, SPDPResponseMaxDelay, ScheduleTimeRounding, SecondaryReorderMaxSamples, SquashParticipants, SuppressSPDPMulticast, SynchronousDeliveryLatencyBound, SynchronousDeliveryPriorityThreshold, UnicastResponseToSPDPMessages, WriterLingerDuration AccelerateRexmitBlockSize ------------------------- **Internal** Proxy readers that are assumed to sill be retrieving historical data get this many samples retransmitted when they NACK something, even if some of these samples have sequence numbers outside the set covered by the NACK. -- Full path: //OpenSplice/DDSI2Service/Internal/AccelerateRexmitBlockSize +- Full path: /DDSI2EService/Internal/AccelerateRexmitBlockSize - Format: integer - Default value: 0 - Occurrences min-max: 0-1 -AggressiveKeepLastWhc ---------------------- +AggressiveKeepLast1Whc +---------------------- -**Internal** This element controls whether to drop a reliable sample from a DDSI2 WHC before all readers have acknowledged it as soon as a later sample becomes available. It only affects DCPS data writers with a history QoS setting of KEEP_LAST with depth 1. The default setting, *false*, mimics the behaviour of the OpenSplice RT networking and is necessary to make the behaviour of wait_for_acknowledgements() consistent across the networking services. +**Internal** This element controls whether to drop a reliable sample from a DDSI2E WHC before all readers have acknowledged it as soon as a later sample becomes available. It only affects DCPS data writers with a history QoS setting of KEEP_LAST with depth 1. The default setting, *false*, mimics the behaviour of the OpenSplice RT networking and is necessary to make the behaviour of wait_for_acknowledgements() consistent across the networking services. -- Full path: //OpenSplice/DDSI2Service/Internal/AggressiveKeepLastWhc +- Full path: /DDSI2EService/Internal/AggressiveKeepLast1Whc - Format: boolean - Default value: false - Occurrences min-max: 0-1 @@ -10739,10 +9260,22 @@ AggressiveKeepLastWhc AssumeMulticastCapable ---------------------- -**Internal** This element controls which network interfaces are assumed to be capable of multicasting even when the interface flags returned by the operating system state it is not (this provides a workaround for some platforms). It is a comma-separated lists of patterns (with ? and \* wildcards) against which the interface names are matched. +**Internal** This element controls which network interfaces are assumed to be capable of multicasting even when the interface flags returned by the operating system state it is not (this provides a workaround for some platforms). It is a comma-separated lists of patterns (with ? and * wildcards) against which the interface names are matched. + +- Full path: /DDSI2EService/Internal/AssumeMulticastCapable +- Format: string +- Occurrences min-max: 0-1 + +AuxiliaryBandwidthLimit +----------------------- + +**Internal** This element specifies the maximum transmit rate of auxiliary traffic not bound to a specific channel, such as discovery traffic, as well as auxiliary traffic related to a certain channel if that channel has elected to share this global AuxiliaryBandwidthLimit. Bandwidth limiting uses a leaky bucket scheme. The default value "inf" means DDSI2E imposes no limitation, the underlying operating system and hardware will likely limit the maimum transmit rate. + +The unit must be specified explicitly. Recognised units: *X*b/s, *X*bps for bits/s or *X*B/s, *X*Bps for bytes/s; where *X* is an optional prefix: k for 10 :sup:`3`, Ki for 2 :sup:`10`, M for 10 :sup:`6`, Mi for 2 :sup:`20`, G for 10 :sup:`9`, Gi for 2 :sup:`30`. -- Full path: //OpenSplice/DDSI2Service/Internal/AssumeMulticastCapable +- Full path: /DDSI2EService/Internal/AuxiliaryBandwidthLimit - Format: string +- Default value: inf - Occurrences min-max: 0-1 BuiltinEndpointSet @@ -10756,7 +9289,7 @@ BuiltinEndpointSet The default is *writers*, as this is thought to be compliant and reasonably efficient. *Minimal* may or may not be compliant but is most efficient, and *full* is inefficient but certain to be compliant. See also Internal/ConservativeBuiltinReaderStartup. -- Full path: //OpenSplice/DDSI2Service/Internal/BuiltinEndpointSet +- Full path: /DDSI2EService/Internal/BuiltinEndpointSet - Format: enumeration - Default value: writers - Valid values: full, writers, minimal @@ -10765,41 +9298,11 @@ The default is *writers*, as this is thought to be compliant and reasonably effi ConservativeBuiltinReaderStartup -------------------------------- -**Internal** This element forces all DDSI2 built-in discovery-related readers to request all historical data, instead of just one for each "topic". There is no indication that any of the current DDSI implementations requires changing of this setting, but it is conceivable that an implementation might track which participants have been informed of the existence of endpoints and which have not been, refusing communication with those that have "can't" know. - -Should it be necessary to hide DDSI2's shared discovery behaviour, set this to *true* and Internal/BuiltinEndpointSet to *full*. - -- Full path: //OpenSplice/DDSI2Service/Internal/ConservativeBuiltinReaderStartup -- Format: boolean -- Default value: false -- Occurrences min-max: 0-1 - -ControlTopic ------------- - -**Internal** The ControlTopic element allows configured whether DDSI2 provides a special control interface via a predefined topic or not. - -- Full path: //OpenSplice/DDSI2Service/Internal/ControlTopic -- Occurrences min-max: 0-1 -- Child elements: DeafMute -- Optional attributes: enable - -enable -^^^^^^ - -**Internal** This attribute controls whether the DDSI2 control topic is defined and acted upon by DDSI2 - -- Full path: //OpenSplice/DDSI2Service/Internal/ControlTopic[@enable] -- Format: boolean -- Default value: false -- Required: false - -DeafMute -^^^^^^^^ +**Internal** This element forces all DDSI2E built-in discovery-related readers to request all historical data, instead of just one for each "topic". There is no indication that any of the current DDSI implementations requires changing of this setting, but it is conceivable that an implementation might track which participants have been informed of the existence of endpoints and which have not been, refusing communication with those that have "can't" know. -**Internal** This element controls whether DDSI2 defaults to deaf-mute mode or to normal mode. This controls both the initial behaviour and what behaviour it auto-reverts to. +Should it be necessary to hide DDSI2E's shared discovery behaviour, set this to *true* and Internal/BuiltinEndpointSet to *full*. -- Full path: //OpenSplice/DDSI2Service/Internal/ControlTopic/DeafMute +- Full path: /DDSI2EService/Internal/ConservativeBuiltinReaderStartup - Format: boolean - Default value: false - Occurrences min-max: 0-1 @@ -10809,7 +9312,7 @@ DDSI2DirectMaxThreads **Internal** This element sets the maximum number of extra threads for an experimental, undocumented and unsupported direct mode. -- Full path: //OpenSplice/DDSI2Service/Internal/DDSI2DirectMaxThreads +- Full path: /DDSI2EService/Internal/DDSI2DirectMaxThreads - Format: integer - Default value: 1 - Occurrences min-max: 0-1 @@ -10817,9 +9320,9 @@ DDSI2DirectMaxThreads DefragReliableMaxSamples ------------------------ -**Internal** This element sets the maximum number of samples that can be defragmented simultaneously for a reliable writer. This has to be large enough to handle retransmissions of historical data in addition to new samples. +**Internal** This element sets the maximum number of samples that can be defragmneted simultaneously for a reliable writer. This has to be large enough to handle retransmissions of historical data in addition to new samples. -- Full path: //OpenSplice/DDSI2Service/Internal/DefragReliableMaxSamples +- Full path: /DDSI2EService/Internal/DefragReliableMaxSamples - Format: integer - Default value: 16 - Occurrences min-max: 0-1 @@ -10829,7 +9332,7 @@ DefragUnreliableMaxSamples **Internal** This element sets the maximum number of samples that can be defragmented simultaneously for a best-effort writers. -- Full path: //OpenSplice/DDSI2Service/Internal/DefragUnreliableMaxSamples +- Full path: /DDSI2EService/Internal/DefragUnreliableMaxSamples - Format: integer - Default value: 4 - Occurrences min-max: 0-1 @@ -10839,7 +9342,7 @@ DeliveryQueueMaxSamples **Internal** This element controls the Maximum size of a delivery queue, expressed in samples. Once a delivery queue is full, incoming samples destined for that queue are dropped until space becomes available again. -- Full path: //OpenSplice/DDSI2Service/Internal/DeliveryQueueMaxSamples +- Full path: /DDSI2EService/Internal/DeliveryQueueMaxSamples - Format: integer - Default value: 256 - Occurrences min-max: 0-1 @@ -10847,9 +9350,9 @@ DeliveryQueueMaxSamples ForwardAllMessages ------------------ -**Internal** Forward all messages from a writer, rather than trying to forward each sample only once. The default of trying to forward each sample only once filters out duplicates for writers in multiple partitions under nearly all circumstances, but may still publish the odd duplicate. Note: the current implementation also can lose in contrived test cases, that publish more than 2\*\*32 samples using a single data writer in conjunction with carefully controlled management of the writer history via cooperating local readers. +**Internal** Forward all messages from a writer, rather than trying to forward each sample only once. The default of trying to forward each sample only once filters out duplicates for writers in multiple partitions under nearly all circumstances, but may still publish the odd duplicate. Note: the current implementation also can lose in contrived test cases, that publish more than 2**32 samples using a single data writer in conjunction with carefully controlled management of the writer history via cooperating local readers. -- Full path: //OpenSplice/DDSI2Service/Internal/ForwardAllMessages +- Full path: /DDSI2EService/Internal/ForwardAllMessages - Format: boolean - Default value: false - Occurrences min-max: 0-1 @@ -10857,12 +9360,24 @@ ForwardAllMessages ForwardRemoteData ----------------- -**Internal** This element controls whether DDSI2 forwards data received from other network services in the domain. +This element controls whether DDSI2E forwards data received from other network services in the domain. -- Full path: //OpenSplice/DDSI2Service/Internal/ForwardRemoteData +- Full path: /DDSI2EService/Internal/ForwardRemoteData - Format: enumeration - Default value: default -- Valid values: false, true, default +- Valid values: false, default, true +- Occurrences min-max: 0-1 + +FragmentSize +------------ + +**Internal** This element specifies the size of DDSI sample fragments generated by DDSI2E. Samples larger than FragmentSize are fragmented into fragments of FragmentSize bytes each, except the last one, which may be smaller. The DDSI spec mandates a minimum fragment size of 1025 bytes, but DDSI2E will do whatever size is requested, accepting fragments of which the size is at least the minimum of 1025 and FragmentSize. + +The unit must be specified explicitly. Recognised units: B (bytes), kB & KiB (2 :sup:`10` bytes), MB & MiB (2 :sup:`20` bytes), GB & GiB (2 :sup:`30` bytes). + +- Full path: /DDSI2EService/Internal/FragmentSize +- Format: string +- Default value: 1280 B - Occurrences min-max: 0-1 GenerateKeyhash @@ -10870,7 +9385,7 @@ GenerateKeyhash **Internal** When true, include keyhashes in outgoing data for topics with keys. -- Full path: //OpenSplice/DDSI2Service/Internal/GenerateKeyhash +- Full path: /DDSI2EService/Internal/GenerateKeyhash - Format: boolean - Default value: true - Occurrences min-max: 0-1 @@ -10880,7 +9395,7 @@ LateAckMode **Internal** Ack a sample only when it has been delivered, instead of when committed to delivering it. -- Full path: //OpenSplice/DDSI2Service/Internal/LateAckMode +- Full path: /DDSI2EService/Internal/LateAckMode - Format: boolean - Default value: false - Occurrences min-max: 0-1 @@ -10888,21 +9403,20 @@ LateAckMode LeaseDuration ------------- -**Internal** This setting controls the default participant lease duration. +**Internal** This setting controls the default participant lease duration, with 0s (the default) indicating that it is to be derived from the domain ExpiryTime: either 10% or 1s longer, whichever is shortest. The unit must be specified explicitly. Recognised units: ns, us, ms, s, min, hr, day. -- Full path: //OpenSplice/DDSI2Service/Internal/LeaseDuration +- Full path: /DDSI2EService/Internal/LeaseDuration - Format: string - Default value: 0 s -- Valid values: 0 / 1hr - Occurrences min-max: 0-1 LegacyFragmentation ------------------- -**Internal** This option enables a backwards-compatible, non-compliant setting and interpretation of the control flags in fragmented data messages. To be enabled *only* when requiring interoperability between compliant and non-compliant versions of DDSI2 for large messages. +**Internal** This option enables a backwards-compatible, non-compliant setting and interpretation of the control flags in fragmented data messages. To be enabled *only* when requiring interoperability between compliant and non-compliant versions of DDSI2E for large messages. -- Full path: //OpenSplice/DDSI2Service/Internal/LegacyFragmentation +- Full path: /DDSI2EService/Internal/LegacyFragmentation - Format: boolean - Default value: false - Occurrences min-max: 0-1 @@ -10910,19 +9424,33 @@ LegacyFragmentation LogStackTraces -------------- -**Internal** This element controls whether or not to write stack traces to the DDSI2 trace when a thread fails to make progress (on select platforms only). +This element controls whether or not to write stack traces to the DDSI2 trace when a thread fails to make progress (on select platforms only). -- Full path: //OpenSplice/DDSI2Service/Internal/LogStackTraces +- Full path: /DDSI2EService/Internal/LogStackTraces - Format: boolean -- Default value: true +- Default value: false +- Occurrences min-max: 0-1 + +MaxMessageSize +-------------- + +**Internal** This element specifies the maximum size of the UDP payload that DDSI2E will generate. DDSI2E will try to maintain this limit within the bounds of the DDSI specification, which means that in some cases (especially for very low values of MaxMessageSize) larger payloads may sporadically be observed (currently up to 1192 B). + +On some networks it may be necessary to set this item to keep the packetsize below the MTU to prevent IP fragmentation. In those cases, it is generally advisable to also consider reducing Internal/FragmentSize. + +The unit must be specified explicitly. Recognised units: B (bytes), kB & KiB (2 :sup:`10` bytes), MB & MiB (2 :sup:`20` bytes), GB & GiB (2 :sup:`30` bytes). + +- Full path: /DDSI2EService/Internal/MaxMessageSize +- Format: string +- Default value: 4096 B - Occurrences min-max: 0-1 MaxParticipants --------------- -**Internal** This elements configures the maximum number of DCPS domain participants this DDSI2 instance is willing to service. 0 is unlimited. +**Internal** This elements configures the maximum number of DCPS domain participants this DDSI2E service instance is willing to service. 0 is unlimited. -- Full path: //OpenSplice/DDSI2Service/Internal/MaxParticipants +- Full path: /DDSI2EService/Internal/MaxParticipants - Format: integer - Default value: 0 - Occurrences min-max: 0-1 @@ -10930,13 +9458,13 @@ MaxParticipants MaxQueuedRexmitBytes -------------------- -**Internal** This setting limits the maximum number of bytes queued for retransmission. The default value of 0 is unlimited unless an AuxiliaryBandwidthLimit has been set, in which case it becomes NackDelay \* AuxiliaryBandwidthLimit. It must be large enough to contain the largest sample that may need to be retransmitted. +**Internal** This setting limits the maximum number of bytes queued for retransmission. The default value of 0 is unlimited unless an AuxiliaryBandwidthLimit has been set, in which case it becomes NackDelay * AuxiliaryBandwidthLimit. It must be large enough to contain the largest sample that may need to be retransmitted. The unit must be specified explicitly. Recognised units: B (bytes), kB & KiB (2 :sup:`10` bytes), MB & MiB (2 :sup:`20` bytes), GB & GiB (2 :sup:`30` bytes). -- Full path: //OpenSplice/DDSI2Service/Internal/MaxQueuedRexmitBytes +- Full path: /DDSI2EService/Internal/MaxQueuedRexmitBytes - Format: string -- Default value: 50 kB +- Default value: 0 B - Occurrences min-max: 0-1 MaxQueuedRexmitMessages @@ -10944,7 +9472,7 @@ MaxQueuedRexmitMessages **Internal** This settings limits the maximum number of samples queued for retransmission. -- Full path: //OpenSplice/DDSI2Service/Internal/MaxQueuedRexmitMessages +- Full path: /DDSI2EService/Internal/MaxQueuedRexmitMessages - Format: integer - Default value: 200 - Occurrences min-max: 0-1 @@ -10952,11 +9480,11 @@ MaxQueuedRexmitMessages MaxSampleSize ------------- -**Internal** This setting controls the maximum (CDR) serialised size of samples that DDSI2 will forward in either direction. Samples larger than this are discarded with a warning. +**Internal** This setting controls the maximum (CDR) serialised size of samples that DDSI2E will forward in either direction. Samples larger than this are discarded with a warning. The unit must be specified explicitly. Recognised units: B (bytes), kB & KiB (2 :sup:`10` bytes), MB & MiB (2 :sup:`20` bytes), GB & GiB (2 :sup:`30` bytes). -- Full path: //OpenSplice/DDSI2Service/Internal/MaxSampleSize +- Full path: /DDSI2EService/Internal/MaxSampleSize - Format: string - Default value: 2147483647 B - Occurrences min-max: 0-1 @@ -10964,9 +9492,9 @@ The unit must be specified explicitly. Recognised units: B (bytes), kB & KiB (2 MeasureHbToAckLatency --------------------- -**Internal** This element enables heartbeat-to-ack latency among DDSI2 services by prepending timestamps to Heartbeat and AckNack messages and calculating round trip times. This is non-standard behaviour. The measured latencies are quite noisy and are currently not used anywhere. +**Internal** This element enables heartbeat-to-ack latency among DDSI2E services by prepending timestamps to Heartbeat and AckNack messages and calculating round trip times. This is non-standard behaviour. The measured latencies are quite noisy and are currently not used anywhere. -- Full path: //OpenSplice/DDSI2Service/Internal/MeasureHbToAckLatency +- Full path: /DDSI2EService/Internal/MeasureHbToAckLatency - Format: boolean - Default value: false - Occurrences min-max: 0-1 @@ -10974,13 +9502,11 @@ MeasureHbToAckLatency MinimumSocketReceiveBufferSize ------------------------------ -**Internal** This setting controls the minimum size of socket receive buffers. The operating system provides some size receive buffer upon creation of the socket, this option can be used to increase the size of the buffer beyond that initially provided by the operating system. If the buffer size cannot be increased to the specified size, an error is reported. - -The default setting is the word "default", which means DDSI2 will attempt to increase the buffer size to 1MB, but will silently accept a smaller buffer should that attempt fail. +**Internal** This setting controls the minimum size of socket receive buffers. This setting can only increase the size of the receive buffer, if the operating system by default creates a larger buffer, it is left unchanged. The unit must be specified explicitly. Recognised units: B (bytes), kB & KiB (2 :sup:`10` bytes), MB & MiB (2 :sup:`20` bytes), GB & GiB (2 :sup:`30` bytes). -- Full path: //OpenSplice/DDSI2Service/Internal/MinimumSocketReceiveBufferSize +- Full path: /DDSI2EService/Internal/MinimumSocketReceiveBufferSize - Format: string - Default value: default - Occurrences min-max: 0-1 @@ -10992,7 +9518,7 @@ MinimumSocketSendBufferSize The unit must be specified explicitly. Recognised units: B (bytes), kB & KiB (2 :sup:`10` bytes), MB & MiB (2 :sup:`20` bytes), GB & GiB (2 :sup:`30` bytes). -- Full path: //OpenSplice/DDSI2Service/Internal/MinimumSocketSendBufferSize +- Full path: /DDSI2EService/Internal/MinimumSocketSendBufferSize - Format: string - Default value: 64 KiB - Occurrences min-max: 0-1 @@ -11000,22 +9526,12 @@ The unit must be specified explicitly. Recognised units: B (bytes), kB & KiB (2 MirrorRemoteEntities -------------------- -**Internal** This element controls whether DDSI2 mirrors all entities in the domain in DDSI or only local ones. Default is to discover remote ones iff General/LocalDiscoveryPartition is not the built-in partition. +This element controls whether DDSI2E mirrors all entities in the domain in DDSI or only local ones. Default is to discover remote ones iff General/LocalDiscoveryPartition is not the built-in partition. -- Full path: //OpenSplice/DDSI2Service/Internal/MirrorRemoteEntities +- Full path: /DDSI2EService/Internal/MirrorRemoteEntities - Format: enumeration - Default value: default -- Valid values: false, true, default -- Occurrences min-max: 0-1 - -MonitorPort ------------ - -**Internal** This element allows configuring a service that dumps a text description of part the internal state to TCP clients. By default (-1), this is disabled; specifying 0 means a kernel-allocated port is used; a positive number is used as the TCP port number. - -- Full path: //OpenSplice/DDSI2Service/Internal/MonitorPort -- Format: integer -- Default value: -1 +- Valid values: false, default, true - Occurrences min-max: 0-1 NackDelay @@ -11025,10 +9541,9 @@ NackDelay The unit must be specified explicitly. Recognised units: ns, us, ms, s, min, hr, day. -- Full path: //OpenSplice/DDSI2Service/Internal/NackDelay +- Full path: /DDSI2EService/Internal/NackDelay - Format: string - Default value: 10 ms -- Valid values: 0 / 1hr - Occurrences min-max: 0-1 PreEmptiveAckDelay @@ -11038,10 +9553,9 @@ PreEmptiveAckDelay The unit must be specified explicitly. Recognised units: ns, us, ms, s, min, hr, day. -- Full path: //OpenSplice/DDSI2Service/Internal/PreEmptiveAckDelay +- Full path: /DDSI2EService/Internal/PreEmptiveAckDelay - Format: string - Default value: 10 ms -- Valid values: 0 / 1hr - Occurrences min-max: 0-1 PrimaryReorderMaxSamples @@ -11049,54 +9563,21 @@ PrimaryReorderMaxSamples **Internal** This element sets the maximum size in samples of a primary re-order administration. Each proxy writer has one primary re-order administration to buffer the packet flow in case some packets arrive out of order. Old samples are forwarded to secondary re-order administrations associated with readers in need of historical data. -- Full path: //OpenSplice/DDSI2Service/Internal/PrimaryReorderMaxSamples +- Full path: /DDSI2EService/Internal/PrimaryReorderMaxSamples - Format: integer - Default value: 64 - Occurrences min-max: 0-1 -PrioritizeRetransmit --------------------- - -**Internal** This element controls whether retransmits are prioritized over new data, speeding up recovery. - -- Full path: //OpenSplice/DDSI2Service/Internal/PrioritizeRetransmit -- Format: boolean -- Default value: true -- Occurrences min-max: 0-1 - -RediscoveryBlacklistDuration ----------------------------- - -**Internal** This element controls for how long a remote participant that was previously deleted will remain on a blacklist to prevent rediscovery, giving the software on a node time to perform any cleanup actions it needs to do. To some extent this delay is required internally by DDSI2, but in the default configuration with the 'enforce' attribute set to false, DDSI2 will reallow rediscovery as soon as it has cleared its internal administration. Setting it to too small a value may result in the entry being pruned from the blacklist before DDSI2 is ready, it is therefore recommended to set it to at least several seconds. - -Valid values are finite durations with an explicit unit or the keyword 'inf' for infinity. Recognised units: ns, us, ms, s, min, hr, day. - -- Full path: //OpenSplice/DDSI2Service/Internal/RediscoveryBlacklistDuration -- Format: string -- Default value: 10s -- Occurrences min-max: 0-1 -- Optional attributes: enforce - -enforce -^^^^^^^ - -**Internal** This attribute controls whether the configured time during which recently deleted participants will not be rediscovered (i.e., "black listed") is enforced and following complete removal of the participant in DDSI2, or whether it can be rediscovered earlier provided all traces of that participant have been removed already. - -- Full path: //OpenSplice/DDSI2Service/Internal/RediscoveryBlacklistDuration[@enforce] -- Format: boolean -- Default value: false -- Required: false - ResponsivenessTimeout --------------------- -**Internal** This element controls for how long an unresponsive reader can block the transmit thread by failing to acknowledge data when a writer's DDSI2 write cache is full. If after this time the writer's cache has not shrunk to below the low-water mark, the reader is considered unresponsive and degraded to unreliable. It will be restored to reliable service once it resumes acknowledging samples. +**Internal** This element controls for how long an unresponsive reader can block the transmit thread by failing to acknowledge data when a writer's DDSI2E WHC is full. If after this time the writer's WHC has not shrunk to below the low-water mark, the reader is considered unresponsive and degraded to unreliable. It will be restored to reliable service once it resumes acknowledging ing samples. -Valid values are finite durations with an explicit unit or the keyword 'inf' for infinity. Recognised units: ns, us, ms, s, min, hr, day. +The unit must be specified explicitly. Recognised units: ns, us, ms, s, min, hr, day. -- Full path: //OpenSplice/DDSI2Service/Internal/ResponsivenessTimeout +- Full path: /DDSI2EService/Internal/ResponsivenessTimeout - Format: string -- Default value: inf +- Default value: 1 s - Occurrences min-max: 0-1 RetransmitMerging @@ -11110,7 +9591,7 @@ RetransmitMerging The default is *adaptive*. See also Internal/RetransmitMergingPeriod. -- Full path: //OpenSplice/DDSI2Service/Internal/RetransmitMerging +- Full path: /DDSI2EService/Internal/RetransmitMerging - Format: enumeration - Default value: adaptive - Valid values: never, adaptive, always @@ -11119,24 +9600,23 @@ The default is *adaptive*. See also Internal/RetransmitMergingPeriod. RetransmitMergingPeriod ----------------------- -**Internal** This setting determines the size of the time window in which a NACK of some sample is ignored because a retransmit of that sample has been multicasted too recently. This setting has no effect on unicasted retransmits. +**Internal** This setting determines the size of the time window in which a NACK of some sample is ignored because a retransmit of that sample has been multicasted too recently. This setting has no effect of unicasted retransmits. See also Internal/RetransmitMerging. The unit must be specified explicitly. Recognised units: ns, us, ms, s, min, hr, day. -- Full path: //OpenSplice/DDSI2Service/Internal/RetransmitMergingPeriod +- Full path: /DDSI2EService/Internal/RetransmitMergingPeriod - Format: string - Default value: 5 ms -- Valid values: 0 / 1s - Occurrences min-max: 0-1 RetryOnRejectBestEffort ----------------------- -**Internal** Whether or not to locally retry pushing a received best-effort sample into the reader caches when resource limits are reached. +**Internal** Whether or not to locally retry pusing a received best-effort sample into the reader caches when resource limits are reached. -- Full path: //OpenSplice/DDSI2Service/Internal/RetryOnRejectBestEffort +- Full path: /DDSI2EService/Internal/RetryOnRejectBestEffort - Format: boolean - Default value: false - Occurrences min-max: 0-1 @@ -11148,7 +9628,7 @@ RetryOnRejectDuration Valid values are finite durations with an explicit unit or the keyword 'inf' for infinity. Recognised units: ns, us, ms, s, min, hr, day. -- Full path: //OpenSplice/DDSI2Service/Internal/RetryOnRejectDuration +- Full path: /DDSI2EService/Internal/RetryOnRejectDuration - Format: string - Default value: default - Occurrences min-max: 0-1 @@ -11156,14 +9636,13 @@ Valid values are finite durations with an explicit unit or the keyword 'inf' for SPDPResponseMaxDelay -------------------- -**Internal** Maximum pseudo-random delay in milliseconds between discovering a remote participant and responding to it. +**Internal** Maximum pseudo-random delay in milliseocnds between discovering a remote participant and responding to it. The unit must be specified explicitly. Recognised units: ns, us, ms, s, min, hr, day. -- Full path: //OpenSplice/DDSI2Service/Internal/SPDPResponseMaxDelay +- Full path: /DDSI2EService/Internal/SPDPResponseMaxDelay - Format: string - Default value: 0 ms -- Valid values: 0 / 1s - Occurrences min-max: 0-1 ScheduleTimeRounding @@ -11173,10 +9652,9 @@ ScheduleTimeRounding The unit must be specified explicitly. Recognised units: ns, us, ms, s, min, hr, day. -- Full path: //OpenSplice/DDSI2Service/Internal/ScheduleTimeRounding +- Full path: /DDSI2EService/Internal/ScheduleTimeRounding - Format: string - Default value: 0 ms -- Valid values: 0 / 1hr - Occurrences min-max: 0-1 SecondaryReorderMaxSamples @@ -11184,7 +9662,7 @@ SecondaryReorderMaxSamples **Internal** This element sets the maximum size in samples of a secondary re-order administration. The secondary re-order administration is per reader in need of historical data. -- Full path: //OpenSplice/DDSI2Service/Internal/SecondaryReorderMaxSamples +- Full path: /DDSI2EService/Internal/SecondaryReorderMaxSamples - Format: integer - Default value: 16 - Occurrences min-max: 0-1 @@ -11192,9 +9670,9 @@ SecondaryReorderMaxSamples SquashParticipants ------------------ -**Internal** This element controls whether DDSI2 advertises all the domain participants it serves in DDSI (when set to *false*), or rather only one domain participant (the one corresponding to the DDSI2 process; when set to *true*). In the latter case DDSI2 becomes the virtual owner of all readers and writers of all domain participants, dramatically reducing discovery traffic (a similar effect can be obtained by setting Internal/BuiltinEndpointSet to "minimal" but with less loss of information). +**Internal** This element controls whether DDSI2E advertises all the domain participants it serves in DDSI (when set to *false*), or rather only one domain participant (the one corresponding to the DDSI2E process; when set to *true*). In the latter case DDSI2E becomes the virtual owner of all readers and writers of all domain participants, dramatically reducing discovery traffic. -- Full path: //OpenSplice/DDSI2Service/Internal/SquashParticipants +- Full path: /DDSI2EService/Internal/SquashParticipants - Format: boolean - Default value: false - Occurrences min-max: 0-1 @@ -11206,7 +9684,7 @@ SuppressSPDPMulticast See also General/AllowMulticast. -- Full path: //OpenSplice/DDSI2Service/Internal/SuppressSPDPMulticast +- Full path: /DDSI2EService/Internal/SuppressSPDPMulticast - Format: boolean - Default value: false - Occurrences min-max: 0-1 @@ -11218,7 +9696,7 @@ SynchronousDeliveryLatencyBound Valid values are finite durations with an explicit unit or the keyword 'inf' for infinity. Recognised units: ns, us, ms, s, min, hr, day. -- Full path: //OpenSplice/DDSI2Service/Internal/SynchronousDeliveryLatencyBound +- Full path: /DDSI2EService/Internal/SynchronousDeliveryLatencyBound - Format: string - Default value: inf - Occurrences min-max: 0-1 @@ -11228,7 +9706,7 @@ SynchronousDeliveryPriorityThreshold **Internal** This element controls whether samples sent by a writer with QoS settings latency_budget <= SynchronousDeliveryLatencyBound and transport_priority greater than or equal to this element's value will be delivered synchronously from the "recv" thread, all others will be delivered asynchronously through delivery queues. This reduces latency at the expense of aggregate bandwidth. -- Full path: //OpenSplice/DDSI2Service/Internal/SynchronousDeliveryPriorityThreshold +- Full path: /DDSI2EService/Internal/SynchronousDeliveryPriorityThreshold - Format: integer - Default value: 0 - Occurrences min-max: 0-1 @@ -11238,16 +9716,16 @@ Test **Internal** Testing options. -- Full path: //OpenSplice/DDSI2Service/Internal/Test +- Full path: /DDSI2EService/Internal/Test - Occurrences min-max: 0-1 - Child elements: XmitLossiness XmitLossiness ^^^^^^^^^^^^^ -**Internal** This element controls the fraction of outgoing packets to drop, specified as samples per thousand. +**Internal** This element controls the fraction of outgoing packets to drop, specified as a per mil. -- Full path: //OpenSplice/DDSI2Service/Internal/Test/XmitLossiness +- Full path: /DDSI2EService/Internal/Test/XmitLossiness - Format: integer - Default value: 0 - Occurrences min-max: 0-1 @@ -11257,94 +9735,191 @@ UnicastResponseToSPDPMessages **Internal** This element controls whether the response to a newly discovered participant is sent as a unicasted SPDP packet, instead of rescheduling the periodic multicasted one. There is no known benefit to setting this to *false*. -- Full path: //OpenSplice/DDSI2Service/Internal/UnicastResponseToSPDPMessages +- Full path: /DDSI2EService/Internal/UnicastResponseToSPDPMessages - Format: boolean - Default value: true - Occurrences min-max: 0-1 -UseMulticastIfMreqn -------------------- +Watermarks +---------- + +**Internal** Watermarks for flow-control. -**Internal** Do not use. +- Full path: /DDSI2EService/Internal/Watermarks +- Occurrences min-max: 0-1 +- Child elements: WhcHigh, WhcLow -- Full path: //OpenSplice/DDSI2Service/Internal/UseMulticastIfMreqn -- Format: integer -- Default value: 0 +WhcHigh +^^^^^^^ + +**Internal** This element sets the high-water mark for the DDSI2E WHCs, expressed in bytes. A writer is suspended when the WHC reaches this size. + +The unit must be specified explicitly. Recognised units: B (bytes), kB & KiB (2 :sup:`10` bytes), MB & MiB (2 :sup:`20` bytes), GB & GiB (2 :sup:`30` bytes). + +- Full path: /DDSI2EService/Internal/Watermarks/WhcHigh +- Format: string +- Default value: 100 kB - Occurrences min-max: 0-1 -Watermarks ----------- +WhcLow +^^^^^^ -**Internal** Watermarks for flow-control. +**Internal** This element sets the low-water mark for the DDSI2E WHCs, expressed in bytes. A suspended writer resumes transmitting when its DDSI2E WHC shrinks to this size. + +The unit must be specified explicitly. Recognised units: B (bytes), kB & KiB (2 :sup:`10` bytes), MB & MiB (2 :sup:`20` bytes), GB & GiB (2 :sup:`30` bytes). -- Full path: //OpenSplice/DDSI2Service/Internal/Watermarks +- Full path: /DDSI2EService/Internal/Watermarks/WhcLow +- Format: string +- Default value: 1 kB - Occurrences min-max: 0-1 -- Child elements: WhcAdaptive, WhcHigh, WhcHighInit, WhcLow -WhcAdaptive -^^^^^^^^^^^ +WriterLingerDuration +-------------------- + +**Internal** This setting controls the maximum duration for which actual deletion of a reliable writer with unacknowledged data in its history will be postponed to provide proper reliable transmission. +The unit must be specified explicitly. Recognised units: ns, us, ms, s, min, hr, day. + +- Full path: /DDSI2EService/Internal/WriterLingerDuration +- Format: string +- Default value: 1 s +- Occurrences min-max: 0-1 + +Partitioning +============ + +The Partitioning element specifies DDSI2E network partitions and how DCPS partition/topic combinations are mapped onto the network partitions. + +- Full path: /DDSI2EService/Partitioning +- Occurrences min-max: 0-1 + +IgnoredPartitions +----------------- + +The IgnoredPartitions element specifies DCPS partition/topic combinations that are not distributed over the network. + +- Full path: /DDSI2EService/Partitioning/IgnoredPartitions +- Occurrences min-max: 0-* + +IgnoredPartition +^^^^^^^^^^^^^^^^ + +This element can be used to prevent certain combinations of DCPS partition and topic from being transmitted over the network. DDSI2E will complete ignore readers and writers for which all DCPS partitions as well as their topic is ignored, not even creating DDSI readers and writers to mirror the DCPS ones. + +- Full path: /DDSI2EService/Partitioning/IgnoredPartitions/IgnoredPartition +- Occurrences min-max: 0-* +- Required attributes: DCPSPartitionTopic + +DCPSPartitionTopic +~~~~~~~~~~~~~~~~~~ + +This attribute specifies a partition and a topic expression, separated by a single '.', that are used to determine if a given partition and topic will be ignored or not. The expressions may use the usual wildcards '*' and '?'. DDSI2E will consider an wildcard DCPS partition to match an expression iff there exists a string that satisfies both expressions. + +- Full path: /DDSI2EService/Partitioning/IgnoredPartitions/IgnoredPartition/DCPSPartitionTopic +- Format: string +- Default value: n/a +- Required: true + +NetworkPartitions +----------------- + +The NetworkPartitions element specifies the DDSI2E network partitions. + +- Full path: /DDSI2EService/Partitioning/NetworkPartitions +- Occurrences min-max: 0-* + +NetworkPartition +^^^^^^^^^^^^^^^^ + +This element defines a DDSI2E network partition. + +- Full path: /DDSI2EService/Partitioning/NetworkPartitions/NetworkPartition +- Occurrences min-max: 0-* +- Required attributes: Address, Name +- Optional attributes: Connected, SecurityProfile + +Address +~~~~~~~ + +This attribute specifies the multicast addresses associated with the network partition as a comma-separated list. Readers matching this network partition (cf. Partitioning/PartitionMappings) will listen for multicasts on all of these addresses and advertise them in the discovery protocol. The writers will select the most suitable address from the addresses advertised by the readers. + +- Full path: /DDSI2EService/Partitioning/NetworkPartitions/NetworkPartition/Address +- Format: string +- Default value: n/a +- Required: true + +Connected +~~~~~~~~~ + +This attribute is a placeholder. + +- Full path: /DDSI2EService/Partitioning/NetworkPartitions/NetworkPartition/Connected +- Format: boolean +- Default value: true +- Required: false -**Internal** This element controls whether DDSI2 will adapt the high-water mark to current traffic conditions, based on retransmit requests and transmit pressure. +Name +~~~~ -- Full path: //OpenSplice/DDSI2Service/Internal/Watermarks/WhcAdaptive -- Format: boolean -- Default value: true -- Occurrences min-max: 0-1 +This attribute specifies the name of this DDSI2E network partition. Two network partitions cannot have the same name. -WhcHigh -^^^^^^^ +- Full path: /DDSI2EService/Partitioning/NetworkPartitions/NetworkPartition/Name +- Format: string +- Default value: n/a +- Required: true -**Internal** This element sets the maximum allowed high-water mark for the DDSI2 WHCs, expressed in bytes. A writer is suspended when the WHC reaches this size. +SecurityProfile +~~~~~~~~~~~~~~~ -The unit must be specified explicitly. Recognised units: B (bytes), kB & KiB (2 :sup:`10` bytes), MB & MiB (2 :sup:`20` bytes), GB & GiB (2 :sup:`30` bytes). +This attribute selects the DDSI2E security profile for encrypting the traffic mapped to this DDSI2E network partition. The default "null" means the network partition is unsecured; any other name refers to a security profile defined using the Security/SecurityProfile elements. -- Full path: //OpenSplice/DDSI2Service/Internal/Watermarks/WhcHigh +- Full path: /DDSI2EService/Partitioning/NetworkPartitions/NetworkPartition/SecurityProfile - Format: string -- Default value: 100 kB -- Occurrences min-max: 0-1 +- Default value: null +- Required: false -WhcHighInit -^^^^^^^^^^^ +PartitionMappings +----------------- -**Internal** This element sets the initial level of the high-water mark for the DDSI2 WHCs, expressed in bytes. +The PartitionMappings element specifies the mapping from DCPS partition/topic combinations to DDSI2E network partitions. -The unit must be specified explicitly. Recognised units: B (bytes), kB & KiB (2 :sup:`10` bytes), MB & MiB (2 :sup:`20` bytes), GB & GiB (2 :sup:`30` bytes). +- Full path: /DDSI2EService/Partitioning/PartitionMappings +- Occurrences min-max: 0-* -- Full path: //OpenSplice/DDSI2Service/Internal/Watermarks/WhcHighInit -- Format: string -- Default value: 30 kB -- Occurrences min-max: 0-1 +PartitionMapping +^^^^^^^^^^^^^^^^ -WhcLow -^^^^^^ +This element defines a mapping from a DCPS partition/topic combination to a DDSI2E network partition. This allows partitioning data flows by using special multicast addresses for part of the data and possibly also encrypting the data flow. -**Internal** This element sets the low-water mark for the DDSI2 WHCs, expressed in bytes. A suspended writer resumes transmitting when its DDSI2 WHC shrinks to this size. +- Full path: /DDSI2EService/Partitioning/PartitionMappings/PartitionMapping +- Occurrences min-max: 0-* +- Required attributes: DCPSPartitionTopic, NetworkPartition -The unit must be specified explicitly. Recognised units: B (bytes), kB & KiB (2 :sup:`10` bytes), MB & MiB (2 :sup:`20` bytes), GB & GiB (2 :sup:`30` bytes). +DCPSPartitionTopic +~~~~~~~~~~~~~~~~~~ -- Full path: //OpenSplice/DDSI2Service/Internal/Watermarks/WhcLow +This attribute specifies a partition and a topic expression, separated by a single '.', that are used to determine if a given partition and topic maps to the DDSI2E network partition named by the NetworkPartition attribute in this PartitionMapping element. The expressions may use the usual wildcards '*' and '?'. DDSI2E will consider an wildcard DCPS partition to match an expression iff there exists a string that satisfies both expressions. + +- Full path: /DDSI2EService/Partitioning/PartitionMappings/PartitionMapping/DCPSPartitionTopic - Format: string -- Default value: 1 kB -- Occurrences min-max: 0-1 +- Default value: n/a +- Required: true -WriterLingerDuration --------------------- +NetworkPartition +~~~~~~~~~~~~~~~~ -**Internal** This setting controls the maximum duration for which actual deletion of a reliable writer with unacknowledged data in its history will be postponed to provide proper reliable transmission. -The unit must be specified explicitly. Recognised units: ns, us, ms, s, min, hr, day. +This attribute specifies which DDSI2E network partition is to be used for DCPS partition/topic combinations matching the DCPSPartitionTopic attribute within this PartitionMapping element. -- Full path: //OpenSplice/DDSI2Service/Internal/WriterLingerDuration +- Full path: /DDSI2EService/Partitioning/PartitionMappings/PartitionMapping/NetworkPartition - Format: string -- Default value: 1 s -- Valid values: 0 / 1hr -- Occurrences min-max: 0-1 +- Default value: n/a +- Required: true SSL === The SSL element allows specifying various parameters related to using SSL/TLS for DDSI over TCP. -- Full path: //OpenSplice/DDSI2Service/SSL +- Full path: /DDSI2EService/SSL - Occurrences min-max: 0-1 - Child elements: CertificateVerification, Ciphers, Enable, EntropyFile, KeyPassphrase, KeystoreFile, SelfSignedCertificates, VerifyClient @@ -11353,7 +9928,7 @@ CertificateVerification If disabled this allows SSL connections to occur even if an X509 certificate fails verification. -- Full path: //OpenSplice/DDSI2Service/SSL/CertificateVerification +- Full path: /DDSI2EService/SSL/CertificateVerification - Format: boolean - Default value: true - Occurrences min-max: 0-1 @@ -11363,7 +9938,7 @@ Ciphers The set of ciphers used by SSL/TLS -- Full path: //OpenSplice/DDSI2Service/SSL/Ciphers +- Full path: /DDSI2EService/SSL/Ciphers - Format: string - Default value: ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH - Occurrences min-max: 0-1 @@ -11373,7 +9948,7 @@ Enable This enables SSL/TLS for TCP. -- Full path: //OpenSplice/DDSI2Service/SSL/Enable +- Full path: /DDSI2EService/SSL/Enable - Format: boolean - Default value: false - Occurrences min-max: 0-1 @@ -11383,7 +9958,7 @@ EntropyFile The SSL/TLS random entropy file name. -- Full path: //OpenSplice/DDSI2Service/SSL/EntropyFile +- Full path: /DDSI2EService/SSL/EntropyFile - Format: string - Occurrences min-max: 0-1 @@ -11392,7 +9967,7 @@ KeyPassphrase The SSL/TLS key pass phrase for encrypted keys. -- Full path: //OpenSplice/DDSI2Service/SSL/KeyPassphrase +- Full path: /DDSI2EService/SSL/KeyPassphrase - Format: string - Default value: secret - Occurrences min-max: 0-1 @@ -11402,7 +9977,7 @@ KeystoreFile The SSL/TLS key and certificate store file name. The keystore must be in PEM format. -- Full path: //OpenSplice/DDSI2Service/SSL/KeystoreFile +- Full path: /DDSI2EService/SSL/KeystoreFile - Format: string - Default value: keystore - Occurrences min-max: 0-1 @@ -11412,7 +9987,7 @@ SelfSignedCertificates This enables the use of self signed X509 certificates. -- Full path: //OpenSplice/DDSI2Service/SSL/SelfSignedCertificates +- Full path: /DDSI2EService/SSL/SelfSignedCertificates - Format: boolean - Default value: false - Occurrences min-max: 0-1 @@ -11422,26 +9997,89 @@ VerifyClient This enables an SSL server checking the X509 certificate of a connecting client. -- Full path: //OpenSplice/DDSI2Service/SSL/VerifyClient +- Full path: /DDSI2EService/SSL/VerifyClient - Format: boolean - Default value: false - Occurrences min-max: 0-1 +Security +======== + +The Security element specifies DDSI2E security profiles that can be used to encrypt traffic mapped to DDSI2E network partitions. + +- Full path: /DDSI2EService/Security +- Occurrences min-max: 0-1 + +SecurityProfile +--------------- + +This element defines a DDSI2E security profile. + +- Full path: /DDSI2EService/Security/SecurityProfile +- Occurrences min-max: 0-* +- Required attributes: Name +- Optional attributes: Cipher, CipherKey + +Cipher +^^^^^^ + +This attribute specifies the cipher to be used for encrypting traffic over network partitions secured by this security profile. The possible ciphers are: + +- *aes128*: AES with a 128-bit key; +- *aes192*: AES with a 192-bit key; +- *aes256*: AES with a 256-bit key; +- *blowfish*: the Blowfish cipher with a 128 bit key; +- *null*: no encryption; + +SHA1 is used on conjunction with all ciphers except "null" to ensure data integrity. + +- Full path: /DDSI2EService/Security/SecurityProfile/Cipher +- Format: enumeration +- Default value: null +- Valid values: null, blowfish, aes128, aes192, aes256 +- Required: false + +CipherKey +^^^^^^^^^ + +The CipherKey attribute is used to define the secret key required by the cipher selected using the Cipher attribtue. The value can be a URI referencing an external file containing the secret key, or the secret key can be defined in-place as a string value. + +The key must be specified as a hexadecimal string with each character representing 4 bits of the key. E.g., 1ABC represents the 16-bit key 0001 1010 1011 1100. The key should not follow a well-known pattern and must exactly match the key length of the selected cipher. + +A malformed key will cause the security profile to be marked as invalid, and disable all network partitions secured by the (invalid) security profile to prevent information leaks. + +As all DDS applications require read access to the XML configuration file, for security reasons it is recommended to store the secret key in an external file in the file system, referenced by its URI. The file should be protected against read and write access from other users on the host. + +- Full path: /DDSI2EService/Security/SecurityProfile/CipherKey +- Format: string +- Default value: "" +- Required: false + +Name +^^^^ + +This attribute specifies the name of this DDSI2E security profile. Two security profiles cannot have the same name. + +- Full path: /DDSI2EService/Security/SecurityProfile/Name +- Format: string +- Default value: n/a +- Required: true + Sizing ====== The Sizing element specifies a variety of configuration settings dealing with expected system sizes, buffer sizes, &c. -- Full path: //OpenSplice/DDSI2Service/Sizing +- Full path: /DDSI2EService/Sizing - Occurrences min-max: 0-1 -- Child elements: EndpointsInSystem, LocalEndpoints, NetworkQueueSize, ReceiveBufferChunkSize +- Child elements: EndpointsInSystem, LocalEndpoints, NetworkQueueSize, ReceiveBufferChunkSize, ReceiveBufferSize EndpointsInSystem ----------------- This endpoint specifies the expected maximum number of endpoints in the network. Underestimating this number will have a significant performance impact, but will not affect correctness; signficantly overestimating it will cause more memory to be used than necessary. -- Full path: //OpenSplice/DDSI2Service/Sizing/EndpointsInSystem +- Full path: /DDSI2EService/Sizing/EndpointsInSystem - Format: integer - Default value: 20000 - Occurrences min-max: 0-1 @@ -11449,9 +10087,9 @@ This endpoint specifies the expected maximum number of endpoints in the network. LocalEndpoints -------------- -This element specifies the expected maximum number of endpoints local to one DDSI2 service. Underestimating this number will have a significant performance impact, but will not affect correctness; signficantly overestimating it will cause more memory to be used than necessary. +This element specifies the expected maximum number of endpoints local to one DDSI2E service. Underestimating this number will have a significant performance impact, but will not affect correctness; signficantly overestimating it will cause more memory to be used than necessary. -- Full path: //OpenSplice/DDSI2Service/Sizing/LocalEndpoints +- Full path: /DDSI2EService/Sizing/LocalEndpoints - Format: integer - Default value: 1000 - Occurrences min-max: 0-1 @@ -11459,9 +10097,9 @@ This element specifies the expected maximum number of endpoints local to one DDS NetworkQueueSize ---------------- -This element specifies the maximum number of samples in the network queue. Write/dispose operations add samples to this queue, the DDSI2 service drains it. Larger values allow large bursts of writes to occur without forcing synchronization between the application and the DDSI2 service, but do introduce the potential for longer latencies and increase the maximum amount of memory potentially occupied by messages in the queue. +This element specifies the maximum number of samples in the network queue. Write/dispose operations add samples to this queue, the DDSI2E service drains it. Larger values allow large bursts of writes to occur without forcing synchronization between the application and the DDSI2E service, but do introduce the potential for longer latencies and increase the maximum amount of memory potentially occupied by messages in the queue. -- Full path: //OpenSplice/DDSI2Service/Sizing/NetworkQueueSize +- Full path: /DDSI2EService/Sizing/NetworkQueueSize - Format: integer - Default value: 1000 - Occurrences min-max: 0-1 @@ -11469,68 +10107,25 @@ This element specifies the maximum number of samples in the network queue. Write ReceiveBufferChunkSize ---------------------- -This element specifies the size of one allocation unit in the receive buffer. Must be greater than the maximum packet size by a modest amount (too large packets are dropped). Each allocation is shrunk immediately after processing a message, or freed straightaway. +Size of one allocation unit in the receive buffer. Must be greater than the maximum packet size by a modest amount (too large packets are dropped). Each allocation is shrunk immediately after processing a message, or freed straightaway. The unit must be specified explicitly. Recognised units: B (bytes), kB & KiB (2 :sup:`10` bytes), MB & MiB (2 :sup:`20` bytes), GB & GiB (2 :sup:`30` bytes). -- Full path: //OpenSplice/DDSI2Service/Sizing/ReceiveBufferChunkSize +- Full path: /DDSI2EService/Sizing/ReceiveBufferChunkSize - Format: string - Default value: 128 KiB - Occurrences min-max: 0-1 -Watermarks ----------- - - { LEAF ("ReceiveBufferSize"), 1, "1 MiB", ABSOFF (rbuf_size), 0, uf_memsize, 0, pf_memsize, "This element sets the size of a single receive buffer. Many receive buffers may be needed. Their size must be greater than ReceiveBufferChunkSize by a modest amount. - -- Full path: //OpenSplice/DDSI2Service/Sizing/Watermarks -- Occurrences min-max: 0-1 -- Child elements: WhcAdaptive, WhcHigh, WhcHighInit, WhcLow - -WhcAdaptive -^^^^^^^^^^^ - -This element controls whether DDSI2 will adapt the high-water mark to current traffic conditions, based on retransmit requests and transmit pressure. - -- Full path: //OpenSplice/DDSI2Service/Sizing/Watermarks/WhcAdaptive -- Format: boolean -- Default value: true -- Occurrences min-max: 0-1 - -WhcHigh -^^^^^^^ - -This element sets the maximum allowed high-water mark for the DDSI2 WHCs, expressed in bytes. A writer is suspended when the WHC reaches this size. - -The unit must be specified explicitly. Recognised units: B (bytes), kB & KiB (2 :sup:`10` bytes), MB & MiB (2 :sup:`20` bytes), GB & GiB (2 :sup:`30` bytes). - -- Full path: //OpenSplice/DDSI2Service/Sizing/Watermarks/WhcHigh -- Format: string -- Default value: 100 kB -- Occurrences min-max: 0-1 - -WhcHighInit -^^^^^^^^^^^ - -This element sets the initial level of the high-water mark for the DDSI2 WHCs, expressed in bytes. - -The unit must be specified explicitly. Recognised units: B (bytes), kB & KiB (2 :sup:`10` bytes), MB & MiB (2 :sup:`20` bytes), GB & GiB (2 :sup:`30` bytes). - -- Full path: //OpenSplice/DDSI2Service/Sizing/Watermarks/WhcHighInit -- Format: string -- Default value: 30 kB -- Occurrences min-max: 0-1 - -WhcLow -^^^^^^ +ReceiveBufferSize +----------------- -This element sets the low-water mark for the DDSI2 WHCs, expressed in bytes. A suspended writer resumes transmitting when its DDSI2 WHC shrinks to this size. +This element sets the size of a single receive buffer. Many receive buffers may be needed. Their size must be greater than ReceiveBufferChunkSize by a modest amount. The unit must be specified explicitly. Recognised units: B (bytes), kB & KiB (2 :sup:`10` bytes), MB & MiB (2 :sup:`20` bytes), GB & GiB (2 :sup:`30` bytes). -- Full path: //OpenSplice/DDSI2Service/Sizing/Watermarks/WhcLow +- Full path: /DDSI2EService/Sizing/ReceiveBufferSize - Format: string -- Default value: 1 kB +- Default value: 1 MiB - Occurrences min-max: 0-1 TCP @@ -11538,7 +10133,7 @@ TCP The TCP element allows specifying various parameters related to running DDSI over TCP. -- Full path: //OpenSplice/DDSI2Service/TCP +- Full path: /DDSI2EService/TCP - Occurrences min-max: 0-1 - Child elements: Enable, NoDelay, Port, ReadTimeout, WriteTimeout @@ -11547,7 +10142,7 @@ Enable This element enables the optional TCP transport. -- Full path: //OpenSplice/DDSI2Service/TCP/Enable +- Full path: /DDSI2EService/TCP/Enable - Format: boolean - Default value: false - Occurrences min-max: 0-1 @@ -11557,7 +10152,7 @@ NoDelay This element enables the TCP_NODELAY socket option, preventing multiple DDSI messages being sent in the same TCP request. Setting this option typically optimises latency over throughput. -- Full path: //OpenSplice/DDSI2Service/TCP/NoDelay +- Full path: /DDSI2EService/TCP/NoDelay - Format: boolean - Default value: true - Occurrences min-max: 0-1 @@ -11565,12 +10160,11 @@ This element enables the TCP_NODELAY socket option, preventing multiple DDSI mes Port ---- -This element specifies the TCP port number on which DDSI2 accepts connections. If the port is set it is used in entity locators, published with DDSI discovery. Dynamically allocated if zero. Disabled if -1 or not configured. If disabled other DDSI services will not be able to establish connections with the service, the service can only communicate by establishing connections to other services. +This element specifies the TCP port number on which the service accepts connections. If the port is set it is used in entity locators, published with DDSI discovery. Dynamically allocated if zero. Disabled if -1 or not configured. If disabled other DDSI services will not be able to establish connections with the service, the service can only communicate by establishing connections to other services. -- Full path: //OpenSplice/DDSI2Service/TCP/Port +- Full path: /DDSI2EService/TCP/Port - Format: integer - Default value: -1 -- Valid values: -1 / 65535 - Occurrences min-max: 0-1 ReadTimeout @@ -11580,10 +10174,9 @@ This element specifies the timeout for blocking TCP read operations. If this tim The unit must be specified explicitly. Recognised units: ns, us, ms, s, min, hr, day. -- Full path: //OpenSplice/DDSI2Service/TCP/ReadTimeout +- Full path: /DDSI2EService/TCP/ReadTimeout - Format: string - Default value: 2 s -- Valid values: 0 / 1hr - Occurrences min-max: 0-1 WriteTimeout @@ -11593,10 +10186,9 @@ This element specifies the timeout for blocking TCP write operations. If this ti The unit must be specified explicitly. Recognised units: ns, us, ms, s, min, hr, day. -- Full path: //OpenSplice/DDSI2Service/TCP/WriteTimeout +- Full path: /DDSI2EService/TCP/WriteTimeout - Format: string - Default value: 2 s -- Valid values: 0 / 1hr - Occurrences min-max: 0-1 ThreadPool @@ -11604,7 +10196,7 @@ ThreadPool The ThreadPool element allows specifying various parameters related to using a thread pool to send DDSI messages to multiple unicast addresses (TCP or UDP). -- Full path: //OpenSplice/DDSI2Service/ThreadPool +- Full path: /DDSI2EService/ThreadPool - Occurrences min-max: 0-1 - Child elements: Enable, ThreadMax, Threads @@ -11613,7 +10205,7 @@ Enable This element enables the optional thread pool. -- Full path: //OpenSplice/DDSI2Service/ThreadPool/Enable +- Full path: /DDSI2EService/ThreadPool/Enable - Format: boolean - Default value: false - Occurrences min-max: 0-1 @@ -11623,7 +10215,7 @@ ThreadMax This elements configures the maximum number of threads in the thread pool. -- Full path: //OpenSplice/DDSI2Service/ThreadPool/ThreadMax +- Full path: /DDSI2EService/ThreadPool/ThreadMax - Format: integer - Default value: 8 - Occurrences min-max: 0-1 @@ -11633,7 +10225,7 @@ Threads This elements configures the initial number of threads in the thread pool. -- Full path: //OpenSplice/DDSI2Service/ThreadPool/Threads +- Full path: /DDSI2EService/ThreadPool/Threads - Format: integer - Default value: 4 - Occurrences min-max: 0-1 @@ -11643,15 +10235,15 @@ Threads This element is used to set thread properties. -- Full path: //OpenSplice/DDSI2Service/Threads +- Full path: /DDSI2EService/Threads - Occurrences min-max: 0-1 Thread ------ -This element is used to set thread properties. +This element specifies thread properties, such as scheduling parameters and stack size. -- Full path: //OpenSplice/DDSI2Service/Threads/Thread +- Full path: /DDSI2EService/Threads/Thread - Occurrences min-max: 0-1000 - Child elements: StackSize - Required attributes: Name @@ -11662,15 +10254,16 @@ Name The Name of the thread for which properties are being set. The following threads exist: - *gc*: garbage collector thread involved in deleting entities; +- *main*: main thread, primarily handling local discovery; - *recv*: receive thread, taking data from the network and running the protocol state machine; - *dq.builtins*: delivery thread for DDSI-builtin data, primarily for discovery; -- *lease*: DDSI liveliness monitoring; +- *lease*: DDSI2E liveliness monitoring; - *tev*: general timed-event handling, retransmits and discovery; - *xmit.CHAN*: transmit thread for channel CHAN; - *dq.CHAN*: delivery thread for channel CHAN; - *tev.CHAN*: timed-even thread for channel CHAN. -- Full path: //OpenSplice/DDSI2Service/Threads/Thread[@Name] +- Full path: /DDSI2EService/Threads/Thread/Name - Format: string - Default value: n/a - Required: true @@ -11680,7 +10273,7 @@ Scheduling This element configures the scheduling properties of the thread. -- Full path: //OpenSplice/DDSI2Service/Threads/Thread/Scheduling +- Full path: /DDSI2EService/Threads/Thread/Scheduling - Occurrences min-max: 0-1 - Child elements: Class, Priority @@ -11689,7 +10282,7 @@ Class This element specifies the thread scheduling class (*realtime*, *timeshare* or *default*). The user may need special privileges from the underlying operating system to be able to assign some of the privileged scheduling classes. -- Full path: //OpenSplice/DDSI2Service/Threads/Thread/Scheduling/Class +- Full path: /DDSI2EService/Threads/Thread/Scheduling/Class - Format: enumeration - Default value: default - Valid values: realtime, timeshare, default @@ -11700,7 +10293,7 @@ Priority This element specifies the thread priority (decimal integer or *default*). Only priorities that are supported by the underlying operating system can be assigned to this element. The user may need special privileges from the underlying operating system to be able to assign some of the privileged priorities. -- Full path: //OpenSplice/DDSI2Service/Threads/Thread/Scheduling/Priority +- Full path: /DDSI2EService/Threads/Thread/Scheduling/Priority - Format: string - Default value: default - Occurrences min-max: 0-1 @@ -11708,11 +10301,11 @@ This element specifies the thread priority (decimal integer or *default*). Only StackSize ^^^^^^^^^ -This element configures the stack size for this thread. The default value *default* leaves the stack size at the operating system default. +This element configures the stack size for this thread. The default value *default* leaves the stack size at the the operating system default. The unit must be specified explicitly. Recognised units: B (bytes), kB & KiB (2 :sup:`10` bytes), MB & MiB (2 :sup:`20` bytes), GB & GiB (2 :sup:`30` bytes). -- Full path: //OpenSplice/DDSI2Service/Threads/Thread/StackSize +- Full path: /DDSI2EService/Threads/Thread/StackSize - Format: string - Default value: default - Occurrences min-max: 0-1 @@ -11722,7 +10315,7 @@ Tracing The Tracing element controls the amount and type of information that is written into the tracing log by the DDSI service. This is useful to track the DDSI service during application development. -- Full path: //OpenSplice/DDSI2Service/Tracing +- Full path: /DDSI2EService/Tracing - Occurrences min-max: 0-1 - Child elements: AppendToFile, EnableCategory, OutputFile, PacketCaptureFile, Timestamps, Verbosity @@ -11731,7 +10324,7 @@ AppendToFile This option specifies whether the output is to be appended to an existing log file. The default is to create a new log file each time, which is generally the best option if a detailed log is generated. -- Full path: //OpenSplice/DDSI2Service/Tracing/AppendToFile +- Full path: /DDSI2EService/Tracing/AppendToFile - Format: boolean - Default value: false - Occurrences min-max: 0-1 @@ -11751,16 +10344,12 @@ This element enables individual logging categories. These are enabled in additio - *radmin*: receive buffer administration - *timing*: periodic reporting of CPU loads per thread - *traffic*: periodic reporting of total outgoing data -- *whc*: tracing of writer history cache changes -- *tcp*: tracing of TCP-specific activity -- *topic*: tracing of topic definitions -- >i>plist*: tracing of discovery parameter list interpretation -In addition, there is the keyword *trace* that enables all but *radmin*, *topic*, *plist* and *whc* +In addition, there is the keyword *trace* that enables all but *radmin* . The categorisation of tracing output is incomplete and hence most of the verbosity levels and categories are not of much use in the current release. This is an ongoing process and here we describe the target situation rather than the current situation. Currently, the most useful is *trace*. -- Full path: //OpenSplice/DDSI2Service/Tracing/EnableCategory +- Full path: /DDSI2EService/Tracing/EnableCategory - Format: string - Occurrences min-max: 0-1 @@ -11769,7 +10358,7 @@ OutputFile This option specifies where the logging is printed to. Note that *stdout* and *stderr* are treated as special values, representing "standard out" and "standard error" respectively. No file is created unless logging categories are enabled using the Tracing/Verbosity or Tracing/EnabledCategory settings. -- Full path: //OpenSplice/DDSI2Service/Tracing/OutputFile +- Full path: /DDSI2EService/Tracing/OutputFile - Format: string - Default value: ddsi2.log - Occurrences min-max: 0-1 @@ -11779,7 +10368,7 @@ PacketCaptureFile This option specifies the file to which received and sent packets will be logged in the "pcap" format suitable for analysis using common networking tools, such as WireShark. IP and UDP headers are ficitious, in particular the destination address of received packets. The TTL may be used to distinguish between sent and received packets: it is 255 for sent packets and 128 for received ones. Currently IPv4 only. -- Full path: //OpenSplice/DDSI2Service/Tracing/PacketCaptureFile +- Full path: /DDSI2EService/Tracing/PacketCaptureFile - Format: string - Occurrences min-max: 0-1 @@ -11788,7 +10377,7 @@ Timestamps This option has no effect. -- Full path: //OpenSplice/DDSI2Service/Tracing/Timestamps +- Full path: /DDSI2EService/Tracing/Timestamps - Format: boolean - Default value: true - Occurrences min-max: 0-1 @@ -11797,9 +10386,9 @@ This option has no effect. absolute ^^^^^^^^ -This option has no effect +This attribute specifies whether the timestamps in the log file are absolute or relative to the startup time of the service. Currently not implemented in DDSI2E, all timestamps are absolute. -- Full path: //OpenSplice/DDSI2Service/Tracing/Timestamps[@absolute] +- Full path: /DDSI2EService/Tracing/Timestamps/absolute - Format: boolean - Default value: true - Required: false @@ -11809,18 +10398,20 @@ Verbosity This element enables standard groups of categories, based on a desired verbosity level. This is in addition to the categories enabled by the Tracing/EnableCategory setting. Recognised verbosity levels and the categories they map to are: -- *none*: no DDSI2 log +- *none*: no DDSI2E log - *severe*: error and fatal - *warning*: *severe* + warning -- *info*: *warning* + info +- *info*: equivalent to *warning* - *config*: *info* + config - *fine*: *config* + discovery -- *finer*: *fine* + traffic and timing +- *finer*: *fine* + traffic, timing & info - *finest*: *finer* + trace -The categorisation of tracing output is incomplete and hence most of the verbosity levels and categories are not of much use in the current release. This is an ongoing process and here we describe the target situation rather than the current situation. Currently, the most useful verbosity levels are *config*, *fine* and *finest*. +While *none* prevents any message from being written to a DDSI2 log file, warnings and errors are still logged in the ospl-info.log and ospl-error.log files. + +The categorisation of tracing output is incomplete and hence most of the verbosity levels and categories are not of much use in the current release. This is an ongoing process and here we describe the target situation rather than the current situation. Currently, the most useful verbosity levels are *config* and *finest*. -- Full path: //OpenSplice/DDSI2Service/Tracing/Verbosity +- Full path: /DDSI2EService/Tracing/Verbosity - Format: enumeration - Default value: none - Valid values: finest, finer, fine, config, info, warning, severe, none @@ -11831,7 +10422,7 @@ Watchdog This element specifies the type of OS scheduling class will be used by the thread that announces its liveliness periodically. -- Full path: //OpenSplice/DDSI2Service/Watchdog +- Full path: /DDSI2EService/Watchdog - Occurrences min-max: 0-1 Scheduling @@ -11839,7 +10430,7 @@ Scheduling This element specifies the type of OS scheduling class will be used by the thread that announces its liveliness periodically. -- Full path: //OpenSplice/DDSI2Service/Watchdog/Scheduling +- Full path: /DDSI2EService/Watchdog/Scheduling - Occurrences min-max: 0-1 - Child elements: Class, Priority @@ -11848,7 +10439,7 @@ Class This element specifies the thread scheduling class that will be used by the watchdog thread. The user may need the appropriate privileges from the underlying operating system to be able to assign some of the privileged scheduling classes. -- Full path: //OpenSplice/DDSI2Service/Watchdog/Scheduling/Class +- Full path: /DDSI2EService/Watchdog/Scheduling/Class - Format: enumeration - Default value: default - Valid values: realtime, timeshare, default @@ -11859,7 +10450,7 @@ Priority This element specifies the thread priority. Only priorities that are supported by the underlying operating system can be assigned to this element. The user may need special privileges from the underlying operating system to be able to assign some of the privileged priorities. -- Full path: //OpenSplice/DDSI2Service/Watchdog/Scheduling/Priority +- Full path: /DDSI2EService/Watchdog/Scheduling/Priority - Format: integer - Default value: 0 - Occurrences min-max: 0-1 @@ -11870,7 +10461,7 @@ priority_kind This attribute specifies whether the specified Priority is a relative or absolute priority. -- Full path: //OpenSplice/DDSI2Service/Watchdog/Scheduling/Priority[@priority_kind] +- Full path: /DDSI2EService/Watchdog/Scheduling/Priority/priority_kind - Format: enumeration - Default value: relative - Valid values: relative, absolute @@ -11879,12 +10470,10 @@ This attribute specifies whether the specified Priority is a relative or absolut TunerService ************ -The TunerService configuration determines how the Tuner Service handles the -incoming client connections. It expects a root element named -OpenSplice/TunerService, in which several child-elements may be specified. -Each of these are listed and explained. + The purpose of the control & monitoring SOAP service is to provide + remote access to the node for OpenSplice tooling. -- Full path: //OpenSplice/TunerService +- Full path: /TunerService - Occurrences min-max: 0-* - Required attributes: name @@ -11898,7 +10487,7 @@ name under the *OpenSplice/Domain/Service[@name]* in the configuration of the Domain Service. -- Full path: //OpenSplice/TunerService[@name] +- Full path: /TunerService/name - Format: string - Default value: cmsoap - Required: true @@ -11908,7 +10497,7 @@ Watchdog This element controls the characteristics of the Watchdog thread. -- Full path: //OpenSplice/TunerService/Watchdog +- Full path: /TunerService/Watchdog - Occurrences min-max: 0-1 Scheduling @@ -11917,7 +10506,7 @@ Scheduling This element specifies the type of OS scheduling class will be used by the thread that announces its liveliness periodically. -- Full path: //OpenSplice/TunerService/Watchdog/Scheduling +- Full path: /TunerService/Watchdog/Scheduling - Occurrences min-max: 1-1 - Child elements: Priority, Class @@ -11930,7 +10519,7 @@ Priority The user may need special privileges from the underlying operating system to be able to assign some of the privileged priorities. -- Full path: //OpenSplice/TunerService/Watchdog/Scheduling/Priority +- Full path: /TunerService/Watchdog/Scheduling/Priority - Format: integer - Default value: 0 - Occurrences min-max: 1-1 @@ -11942,7 +10531,7 @@ priority_kind This attribute specifies whether the specified Priority is a relative or absolute priority. -- Full path: //OpenSplice/TunerService/Watchdog/Scheduling/Priority[@priority_kind] +- Full path: /TunerService/Watchdog/Scheduling/Priority/priority_kind - Format: enumeration - Default value: Relative - Valid values: Relative, Absolute @@ -11956,7 +10545,7 @@ Class the underlying operating system to be able to assign some of the privileged scheduling classes. -- Full path: //OpenSplice/TunerService/Watchdog/Scheduling/Class +- Full path: /TunerService/Watchdog/Scheduling/Class - Format: enumeration - Default value: Default - Valid values: Timeshare, Realtime, Default @@ -11967,7 +10556,7 @@ Server This element determines the serverside behaviour of the Tuner service. -- Full path: //OpenSplice/TunerService/Server +- Full path: /TunerService/Server - Occurrences min-max: 0-1 - Child elements: PortNr, Backlog, Verbosity @@ -11980,9 +10569,9 @@ PortNr Valid portnumbers are 1 till 65535. When using the single process option set this value to Auto. -- Full path: //OpenSplice/TunerService/Server/PortNr +- Full path: /TunerService/Server/PortNr - Format: string -- Default value: 8000 +- Default value: 50000 - Occurrences min-max: 0-1 Backlog @@ -11992,10 +10581,9 @@ Backlog that are allowed to be waiting when the maximum number of concurrent requests is reached. -- Full path: //OpenSplice/TunerService/Server/Backlog +- Full path: /TunerService/Server/Backlog - Format: integer - Default value: 5 -- Valid values: 0 / - - Occurrences min-max: 0-1 Verbosity @@ -12003,7 +10591,7 @@ Verbosity This element specifies the verbosity level of the logging of the service. -- Full path: //OpenSplice/TunerService/Server/Verbosity +- Full path: /TunerService/Server/Verbosity - Format: enumeration - Default value: 0 - Valid values: 0, 1, 2, 3, 4, 5 @@ -12015,7 +10603,7 @@ Client This element determines how the Tuner service handles the incoming client connections. -- Full path: //OpenSplice/TunerService/Client +- Full path: /TunerService/Client - Occurrences min-max: 0-1 - Child elements: MaxClients, MaxThreadsPerClient, LeasePeriod @@ -12026,10 +10614,9 @@ MaxClients that are allowed to be concurrently connected to the Tuner service. Clients are identified by IP-address. -- Full path: //OpenSplice/TunerService/Client/MaxClients +- Full path: /TunerService/Client/MaxClients - Format: integer - Default value: 10 -- Valid values: 1 / - - Occurrences min-max: 0-1 MaxThreadsPerClient @@ -12040,10 +10627,9 @@ MaxThreadsPerClient The number of threads determines the maximum number of concurrent requests for a client. -- Full path: //OpenSplice/TunerService/Client/MaxThreadsPerClient +- Full path: /TunerService/Client/MaxThreadsPerClient - Format: integer - Default value: 10 -- Valid values: 1 / - - Occurrences min-max: 0-1 LeasePeriod @@ -12057,10 +10643,8 @@ LeasePeriod This ensures that all resources are cleaned up automatically if the client fails to update its lease within this period. -- Full path: //OpenSplice/TunerService/Client/LeasePeriod -- Dimension: seconds +- Full path: /TunerService/Client/LeasePeriod - Default value: 15.0 -- Valid values: 10.0 / - - Occurrences min-max: 0-1 Scheduling @@ -12069,7 +10653,7 @@ Scheduling This element specifies the scheduling policies used to control the threads that handle the client requests to the Tuner Service. -- Full path: //OpenSplice/TunerService/Client/Scheduling +- Full path: /TunerService/Client/Scheduling - Occurrences min-max: 0-1 - Child elements: Priority, Class @@ -12081,7 +10665,7 @@ Priority operating system can be assigned to this element. The user may need special privileges from the underlying operating system to be able to assign some of the privileged priorities. -- Full path: //OpenSplice/TunerService/Client/Scheduling/Priority +- Full path: /TunerService/Client/Scheduling/Priority - Format: integer - Default value: 0 - Occurrences min-max: 1-1 @@ -12093,7 +10677,7 @@ priority_kind This attribute specifies whether the specified *Priority* is a relative or absolute priority. -- Full path: //OpenSplice/TunerService/Client/Scheduling/Priority[@priority_kind] +- Full path: /TunerService/Client/Scheduling/Priority/priority_kind - Format: enumeration - Default value: Relative - Valid values: Relative, Absolute @@ -12107,7 +10691,7 @@ Class from the underlying operating system to be able to assign some of the privileged scheduling classes. -- Full path: //OpenSplice/TunerService/Client/Scheduling/Class +- Full path: /TunerService/Client/Scheduling/Class - Format: enumeration - Default value: Default - Valid values: Timeshare, Realtime, Default @@ -12119,7 +10703,7 @@ GarbageCollector This element specifies the behaviour of the garbage collection thread of the service. -- Full path: //OpenSplice/TunerService/GarbageCollector +- Full path: /TunerService/GarbageCollector - Occurrences min-max: 0-1 Scheduling @@ -12128,7 +10712,7 @@ Scheduling This element specifies the scheduling policies used to control the garbagage collection thread of the Tuner Service. -- Full path: //OpenSplice/TunerService/GarbageCollector/Scheduling +- Full path: /TunerService/GarbageCollector/Scheduling - Occurrences min-max: 0-1 - Child elements: Priority, Class @@ -12140,7 +10724,7 @@ Priority operating system can be assigned to this element. The user may need special privileges from the underlying operating system to be able to assign some of the privileged priorities. -- Full path: //OpenSplice/TunerService/GarbageCollector/Scheduling/Priority +- Full path: /TunerService/GarbageCollector/Scheduling/Priority - Format: integer - Default value: 0 - Occurrences min-max: 1-1 @@ -12152,7 +10736,7 @@ priority_kind This attribute specifies whether the specified *Priority* is a relative or absolute priority. -- Full path: //OpenSplice/TunerService/GarbageCollector/Scheduling/Priority[@priority_kind] +- Full path: /TunerService/GarbageCollector/Scheduling/Priority/priority_kind - Format: enumeration - Default value: Relative - Valid values: Relative, Absolute @@ -12166,7 +10750,7 @@ Class from the underlying operating system to be able to assign some of the privileged scheduling classes. -- Full path: //OpenSplice/TunerService/GarbageCollector/Scheduling/Class +- Full path: /TunerService/GarbageCollector/Scheduling/Class - Format: enumeration - Default value: Default - Valid values: Timeshare, Realtime, Default @@ -12178,7 +10762,7 @@ LeaseManagement This element specifies the behaviour of the lease management thread of the Tuner Service. -- Full path: //OpenSplice/TunerService/LeaseManagement +- Full path: /TunerService/LeaseManagement - Occurrences min-max: 0-1 Scheduling @@ -12187,7 +10771,7 @@ Scheduling This element specifies the scheduling policies used to control the lease management thread of the Tuner Service. -- Full path: //OpenSplice/TunerService/LeaseManagement/Scheduling +- Full path: /TunerService/LeaseManagement/Scheduling - Occurrences min-max: 0-1 - Child elements: Priority, Class @@ -12199,7 +10783,7 @@ Priority operating system can be assigned to this element. The user may need special privileges from the underlying operating system to be able to assign some of the privileged priorities. -- Full path: //OpenSplice/TunerService/LeaseManagement/Scheduling/Priority +- Full path: /TunerService/LeaseManagement/Scheduling/Priority - Format: integer - Default value: 0 - Occurrences min-max: 1-1 @@ -12211,7 +10795,7 @@ priority_kind This attribute specifies whether the specified *Priority* is a relative or absolute priority. -- Full path: //OpenSplice/TunerService/LeaseManagement/Scheduling/Priority[@priority_kind] +- Full path: /TunerService/LeaseManagement/Scheduling/Priority/priority_kind - Format: enumeration - Default value: Relative - Valid values: Relative, Absolute @@ -12225,7 +10809,7 @@ Class from the underlying operating system to be able to assign some of the privileged scheduling classes. -- Full path: //OpenSplice/TunerService/LeaseManagement/Scheduling/Class +- Full path: /TunerService/LeaseManagement/Scheduling/Class - Format: enumeration - Default value: Default - Valid values: Timeshare, Realtime, Default @@ -12239,7 +10823,7 @@ DbmsConnectService this root element, the DbmsConnect Service will look for several child-elements. Each of these is listed and explained. -- Full path: //OpenSplice/DbmsConnectService +- Full path: /DbmsConnectService - Occurrences min-max: 0-* - Required attributes: name @@ -12253,7 +10837,7 @@ name *OpenSplice/Domain/Service[@name]* in the configuration of the DomainService. -- Full path: //OpenSplice/DbmsConnectService[@name] +- Full path: /DbmsConnectService/name - Format: string - Default value: dbmsconnect - Required: true @@ -12263,7 +10847,7 @@ Watchdog This element controls the characteristics of the Watchdog thread -- Full path: //OpenSplice/DbmsConnectService/Watchdog +- Full path: /DbmsConnectService/Watchdog - Occurrences min-max: 0-1 Scheduling @@ -12272,7 +10856,7 @@ Scheduling This element specifies the type of OS scheduling class will be used by the thread that announces its liveliness periodically. -- Full path: //OpenSplice/DbmsConnectService/Watchdog/Scheduling +- Full path: /DbmsConnectService/Watchdog/Scheduling - Occurrences min-max: 1-1 - Child elements: Priority, Class @@ -12285,7 +10869,7 @@ Priority The user may need special privileges from the underlying operating system to be able to assign some of the privileged priorities. -- Full path: //OpenSplice/DbmsConnectService/Watchdog/Scheduling/Priority +- Full path: /DbmsConnectService/Watchdog/Scheduling/Priority - Format: integer - Default value: 0 - Occurrences min-max: 1-1 @@ -12297,7 +10881,7 @@ priority_kind This attribute specifies whether the specified Priority is a relative or absolute priority. -- Full path: //OpenSplice/DbmsConnectService/Watchdog/Scheduling/Priority[@priority_kind] +- Full path: /DbmsConnectService/Watchdog/Scheduling/Priority/priority_kind - Format: enumeration - Default value: Relative - Valid values: Relative, Absolute @@ -12311,7 +10895,7 @@ Class the underlying operating system to be able to assign some of the privileged scheduling classes. -- Full path: //OpenSplice/DbmsConnectService/Watchdog/Scheduling/Class +- Full path: /DbmsConnectService/Watchdog/Scheduling/Class - Format: enumeration - Default value: Default - Valid values: Timeshare, Realtime, Default @@ -12322,7 +10906,7 @@ DdsToDbms This element specifies the configuration properties concerning DDS to DBMS bridging. -- Full path: //OpenSplice/DbmsConnectService/DdsToDbms +- Full path: /DbmsConnectService/DdsToDbms - Occurrences min-max: 0-1 - Optional attributes: replication_mode @@ -12353,7 +10937,7 @@ replication_mode *DbmsToDds* or *DbmsToDds/NameSpace* elements should be set appropriately as well! -- Full path: //OpenSplice/DbmsConnectService/DdsToDbms[@replication_mode] +- Full path: /DbmsConnectService/DdsToDbms/replication_mode - Format: boolean - Default value: FALSE - Required: false @@ -12366,7 +10950,7 @@ NameSpace At least one *NameSpace* element has to be present in a *DdsToDbms* element. -- Full path: //OpenSplice/DbmsConnectService/DdsToDbms/NameSpace +- Full path: /DbmsConnectService/DdsToDbms/NameSpace - Occurrences min-max: 1-* - Required attributes: dsn, usr, pwd - Optional attributes: name, odbc, partition, topic, update_frequency, schema, catalog, replication_mode @@ -12377,7 +10961,7 @@ name The name of the namespace. If not specified, the namespace will be named "(nameless)". -- Full path: //OpenSplice/DbmsConnectService/DdsToDbms/NameSpace[@name] +- Full path: /DbmsConnectService/DdsToDbms/NameSpace/name - Format: string - Default value: (nameless) - Required: false @@ -12393,7 +10977,7 @@ odbc generic ODBC library. The resulting behaviour is dependent on the platform on which the DbmsConnect Service is running. -- Full path: //OpenSplice/DbmsConnectService/DdsToDbms/NameSpace[@odbc] +- Full path: /DbmsConnectService/DdsToDbms/NameSpace/odbc - Format: string - Default value: "" - Required: false @@ -12402,14 +10986,14 @@ partition ^^^^^^^^^ This attribute specifies an expression that represents one or more DDS - partitions. It is allowed to use wildcards in the expression: a '\*' + partitions. It is allowed to use wildcards in the expression: a '*' represents any sequence of characters and a '?' represents one single character. This expression is used to specify the DDS partition(s) from which DDS samples must be 'bridged' to the DBMS domain. -- Full path: //OpenSplice/DbmsConnectService/DdsToDbms/NameSpace[@partition] +- Full path: /DbmsConnectService/DdsToDbms/NameSpace/partition - Format: string - Default value: * - Required: false @@ -12418,7 +11002,7 @@ topic ^^^^^ This attribute specifies an expression that represents one or more DDS - topic names. It is allowed to use wildcards in the expression: a '\*' + topic names. It is allowed to use wildcards in the expression: a '*' represents any sequence of characters and a '?' represents one single character. @@ -12429,7 +11013,7 @@ topic of the topic, unless specified otherwise in the *table* attribute of a *Mapping* element. -- Full path: //OpenSplice/DbmsConnectService/DdsToDbms/NameSpace[@topic] +- Full path: /DbmsConnectService/DdsToDbms/NameSpace/topic - Format: string - Default value: * - Required: false @@ -12441,10 +11025,8 @@ update_frequency will update the DBMS domain with DDS data. By default, it is 0.0Hz which means it is done event based (every time new DDS data arrives). -- Full path: //OpenSplice/DbmsConnectService/DdsToDbms/NameSpace[@update_frequency] -- Dimension: Hz +- Full path: /DbmsConnectService/DdsToDbms/NameSpace/update_frequency - Default value: 0.0 -- Valid values: 0.0 / - - Required: false dsn @@ -12453,7 +11035,7 @@ dsn Represents the ODBC Data Source Name, that represents the DBMS where the service must bridge the DDS data to. -- Full path: //OpenSplice/DbmsConnectService/DdsToDbms/NameSpace[@dsn] +- Full path: /DbmsConnectService/DdsToDbms/NameSpace/dsn - Format: string - Default value: n/a - Required: true @@ -12463,7 +11045,7 @@ usr Represents the user name that is used when connecting to the DBMS. -- Full path: //OpenSplice/DbmsConnectService/DdsToDbms/NameSpace[@usr] +- Full path: /DbmsConnectService/DdsToDbms/NameSpace/usr - Format: string - Default value: n/a - Required: true @@ -12473,7 +11055,7 @@ pwd Represents the password that is used when connecting to the DBMS. -- Full path: //OpenSplice/DbmsConnectService/DdsToDbms/NameSpace[@pwd] +- Full path: /DbmsConnectService/DdsToDbms/NameSpace/pwd - Format: string - Default value: n/a - Required: true @@ -12485,7 +11067,7 @@ schema The exact schema content may be dependent on the DBMS that is being used, so consult your DBMS documentation for more details on this subject. -- Full path: //OpenSplice/DbmsConnectService/DdsToDbms/NameSpace[@schema] +- Full path: /DbmsConnectService/DdsToDbms/NameSpace/schema - Format: string - Default value: "" - Required: false @@ -12497,7 +11079,7 @@ catalog The exact catalog content may be dependent on the DBMS that is being used, so consult your DBMS documentation for more details on this subject. -- Full path: //OpenSplice/DbmsConnectService/DdsToDbms/NameSpace[@catalog] +- Full path: /DbmsConnectService/DdsToDbms/NameSpace/catalog - Format: string - Default value: "" - Required: false @@ -12532,7 +11114,7 @@ replication_mode *DbmsToDds* or *DbmsToDds/NameSpace* elements should be set appropriately as well! -- Full path: //OpenSplice/DbmsConnectService/DdsToDbms/NameSpace[@replication_mode] +- Full path: /DbmsConnectService/DdsToDbms/NameSpace/replication_mode - Format: boolean - Default value: FALSE - Required: false @@ -12545,7 +11127,7 @@ Mapping are used to configure the responsibilities of the service concerning the bridging of data from DDS to DBMS. -- Full path: //OpenSplice/DbmsConnectService/DdsToDbms/NameSpace/Mapping +- Full path: /DbmsConnectService/DdsToDbms/NameSpace/Mapping - Occurrences min-max: 0-* - Required attributes: topic - Optional attributes: table, query, filter @@ -12553,10 +11135,9 @@ Mapping topic ~~~~~ - This attribute specifies the name of the topic where the Mapping applies to. If you - specify no particular topic, it will create tables for all topics + This attribute specifies the name of the topic where the Mapping applies to. -- Full path: //OpenSplice/DbmsConnectService/DdsToDbms/NameSpace/Mapping[@topic] +- Full path: /DbmsConnectService/DdsToDbms/NameSpace/Mapping/topic - Format: string - Default value: n/a - Required: true @@ -12568,7 +11149,7 @@ table must be associated with the topic. By default the table name is equal to the topic name. -- Full path: //OpenSplice/DbmsConnectService/DdsToDbms/NameSpace/Mapping[@table] +- Full path: /DbmsConnectService/DdsToDbms/NameSpace/Mapping/table - Format: string - Default value: "" - Required: false @@ -12582,7 +11163,7 @@ query is an empty string, representing all available samples of the selected topic. -- Full path: //OpenSplice/DbmsConnectService/DdsToDbms/NameSpace/Mapping[@query] +- Full path: /DbmsConnectService/DdsToDbms/NameSpace/Mapping/query - Format: string - Default value: "" - Required: false @@ -12596,7 +11177,7 @@ filter value is an empty string, representing all available samples of the selected topic. -- Full path: //OpenSplice/DbmsConnectService/DdsToDbms/NameSpace/Mapping[@filter] +- Full path: /DbmsConnectService/DdsToDbms/NameSpace/Mapping/filter - Format: string - Default value: "" - Required: false @@ -12606,7 +11187,7 @@ DbmsToDds Holds the configuration of the service concerning DBMS to DDS bridging -- Full path: //OpenSplice/DbmsConnectService/DbmsToDds +- Full path: /DbmsConnectService/DbmsToDds - Occurrences min-max: 0-1 - Optional attributes: publish_initial_data, event_table_policy, trigger_policy, replication_user @@ -12619,7 +11200,7 @@ publish_initial_data The value of this attribute is ignored when the corresponding event_table_policy is set to NONE. -- Full path: //OpenSplice/DbmsConnectService/DbmsToDds[@publish_initial_data] +- Full path: /DbmsConnectService/DbmsToDds/publish_initial_data - Format: boolean - Default value: true - Required: false @@ -12638,7 +11219,7 @@ event_table_policy - **LAZY**: An 'event table' will only be created if it is not available when the service connects, and it will not be deleted when the service disconnects. - **NONE**: An 'event table' will neither be created nor deleted by the service. For each specified *NameSpace*, the service will poll for the existence of a consistent table with a frequency specified in the coresponding *update_frequency* attribute. It will start using the table as soon as it is available. With this policy set, no initial data will be published regardless of the value of the applicable *publish_initial_data* attribute. -- Full path: //OpenSplice/DbmsConnectService/DbmsToDds[@event_table_policy] +- Full path: /DbmsConnectService/DbmsToDds/event_table_policy - Format: enumeration - Default value: FULL - Valid values: FULL, LAZY, NONE @@ -12658,7 +11239,7 @@ trigger_policy - **LAZY**: Triggers will only be created if they are not available when the service connects, and will not be deleted when the service disconnects. - **NONE**: Triggers will neither be created nor deleted by the service. This allows you to build your own custom triggering mechanism. -- Full path: //OpenSplice/DbmsConnectService/DbmsToDds[@trigger_policy] +- Full path: /DbmsConnectService/DbmsToDds/trigger_policy - Format: enumeration - Default value: FULL - Valid values: FULL, LAZY, NONE @@ -12694,7 +11275,7 @@ replication_user the *DssToDbms* or *DssToDbms/NameSpace* elements should be set appropriately as well! -- Full path: //OpenSplice/DbmsConnectService/DbmsToDds[@replication_user] +- Full path: /DbmsConnectService/DbmsToDds/replication_user - Format: string - Default value: "" - Required: false @@ -12706,7 +11287,7 @@ NameSpace the bridging of data from DBMS to DDS. At least one *NameSpace* element has to be present in a *DbmsToDds* element. -- Full path: //OpenSplice/DbmsConnectService/DbmsToDds/NameSpace +- Full path: /DbmsConnectService/DbmsToDds/NameSpace - Occurrences min-max: 1-* - Required attributes: dsn, usr, pwd - Optional attributes: name, odbc, partition, table, update_frequency, publish_initial_data, force_key_equality, event_table_policy, trigger_policy, schema, catalog, replication_user @@ -12717,7 +11298,7 @@ name The name of the namespace. If not specified, the namespace will be named "(nameless)". -- Full path: //OpenSplice/DbmsConnectService/DbmsToDds/NameSpace[@name] +- Full path: /DbmsConnectService/DbmsToDds/NameSpace/name - Format: string - Default value: (nameless) - Required: false @@ -12733,7 +11314,7 @@ odbc generic ODBC library. The resulting behaviour is dependent on the platform on which the DbmsConnect Service is running. -- Full path: //OpenSplice/DbmsConnectService/DbmsToDds/NameSpace[@odbc] +- Full path: /DbmsConnectService/DbmsToDds/NameSpace/odbc - Format: string - Default value: "" - Required: false @@ -12742,13 +11323,13 @@ partition ^^^^^^^^^ This attribute specifies an expression represents one or more DDS partitions. - It is allowed to use wildcards in the expression: a '\*' represents any + It is allowed to use wildcards in the expression: a '*' represents any sequence of characters and a '?' represents one single character. This expression is used to specify the DDS partition(s) where DBMS records will be written to as DDS samples by the service. -- Full path: //OpenSplice/DbmsConnectService/DbmsToDds/NameSpace[@partition] +- Full path: /DbmsConnectService/DbmsToDds/NameSpace/partition - Format: string - Default value: * - Required: false @@ -12757,14 +11338,14 @@ table ^^^^^ This attribute specifies an expression that represents one or more DBMS - table names. It is allowed to use wildcards in the expression: a '\*' + table names. It is allowed to use wildcards in the expression: a '*' represents any sequence of characters and a '?' represents one single character. This expression is used to specify the tables from which DBMS data must be 'bridged' to the DDS domain. -- Full path: //OpenSplice/DbmsConnectService/DbmsToDds/NameSpace[@table] +- Full path: /DbmsConnectService/DbmsToDds/NameSpace/table - Format: string - Default value: * - Required: false @@ -12778,10 +11359,8 @@ update_frequency supported. If 0.0Hz is specified, the default of 2.0Hz will be used. -- Full path: //OpenSplice/DbmsConnectService/DbmsToDds/NameSpace[@update_frequency] -- Dimension: Hz +- Full path: /DbmsConnectService/DbmsToDds/NameSpace/update_frequency - Default value: 2.0 -- Valid values: 0.0 / - - Required: false dsn @@ -12790,7 +11369,7 @@ dsn Represents the Data Source Name, that represents the DBMS where the service must bridge the DDS data from. -- Full path: //OpenSplice/DbmsConnectService/DbmsToDds/NameSpace[@dsn] +- Full path: /DbmsConnectService/DbmsToDds/NameSpace/dsn - Format: string - Default value: n/a - Required: true @@ -12800,7 +11379,7 @@ usr Represents the user name that is used when connecting to the DBMS. -- Full path: //OpenSplice/DbmsConnectService/DbmsToDds/NameSpace[@usr] +- Full path: /DbmsConnectService/DbmsToDds/NameSpace/usr - Format: string - Default value: n/a - Required: true @@ -12810,7 +11389,7 @@ pwd Represents the password that is used when connecting to the DBMS. -- Full path: //OpenSplice/DbmsConnectService/DbmsToDds/NameSpace[@pwd] +- Full path: /DbmsConnectService/DbmsToDds/NameSpace/pwd - Format: string - Default value: n/a - Required: true @@ -12825,7 +11404,7 @@ publish_initial_data *DbmsToDds* element, which defaults to true. The value of this attribute is ignored when the corresponding *event_table_policy* is set to NONE. -- Full path: //OpenSplice/DbmsConnectService/DbmsToDds/NameSpace[@publish_initial_data] +- Full path: /DbmsConnectService/DbmsToDds/NameSpace/publish_initial_data - Format: boolean - Default value: true - Required: false @@ -12838,7 +11417,7 @@ force_key_equality key equality between table and topic definitions. If true, key definitions from the table and topic must match, otherwise key definitions may differ. -- Full path: //OpenSplice/DbmsConnectService/DbmsToDds/NameSpace[@force_key_equality] +- Full path: /DbmsConnectService/DbmsToDds/NameSpace/force_key_equality - Format: boolean - Default value: true - Required: false @@ -12857,7 +11436,7 @@ event_table_policy - **LAZY**: An 'event table' will only be created if it is not available when the service connects, and it will not be deleted when the service disconnects. - **NONE**: An 'event table' will neither be created nor deleted by the service. For each specified *NameSpace*, the service will poll for the existence of a consistent table with a frequency specified in the coresponding *update_frequency* attribute. It will start using the table as soon as it is available. With this policy set, no initial data will be published regardless of the value of the applicable *publish_initial_data* attribute. -- Full path: //OpenSplice/DbmsConnectService/DbmsToDds/NameSpace[@event_table_policy] +- Full path: /DbmsConnectService/DbmsToDds/NameSpace/event_table_policy - Format: enumeration - Default value: FULL - Valid values: FULL, LAZY, NONE @@ -12877,7 +11456,7 @@ trigger_policy - **LAZY**: Triggers will only be created if they are not available when the service connects, and will not be deleted when the service disconnects. - **NONE**: Triggers will neither be created nor deleted by the service. This allows you to build your own custom triggering mechanism. -- Full path: //OpenSplice/DbmsConnectService/DbmsToDds/NameSpace[@trigger_policy] +- Full path: /DbmsConnectService/DbmsToDds/NameSpace/trigger_policy - Format: enumeration - Default value: FULL - Valid values: FULL, LAZY, NONE @@ -12888,7 +11467,7 @@ schema Represents the schema that is used when communicating with the DBMS. -- Full path: //OpenSplice/DbmsConnectService/DbmsToDds/NameSpace[@schema] +- Full path: /DbmsConnectService/DbmsToDds/NameSpace/schema - Format: string - Default value: "" - Required: false @@ -12898,7 +11477,7 @@ catalog Represents the catalog that is used when communicating with the DBMS. -- Full path: //OpenSplice/DbmsConnectService/DbmsToDds/NameSpace[@catalog] +- Full path: /DbmsConnectService/DbmsToDds/NameSpace/catalog - Format: string - Default value: "" - Required: false @@ -12935,7 +11514,7 @@ replication_user the *DssToDbms* or *DssToDbms/NameSpace* elements should be set appropriately as well! -- Full path: //OpenSplice/DbmsConnectService/DbmsToDds/NameSpace[@replication_user] +- Full path: /DbmsConnectService/DbmsToDds/NameSpace/replication_user - Format: string - Default value: "" - Required: false @@ -12948,7 +11527,7 @@ Mapping are used to configure the responsibilities of the service concerning the bridging of data from DBMS to DDS -- Full path: //OpenSplice/DbmsConnectService/DbmsToDds/NameSpace/Mapping +- Full path: /DbmsConnectService/DbmsToDds/NameSpace/Mapping - Occurrences min-max: 0-* - Required attributes: table - Optional attributes: topic, query, publish_initial_data, force_key_equality, event_table_policy, trigger_policy @@ -12958,7 +11537,7 @@ table This attribute specifies the name of the table where the Mapping applies to. -- Full path: //OpenSplice/DbmsConnectService/DbmsToDds/NameSpace/Mapping[@table] +- Full path: /DbmsConnectService/DbmsToDds/NameSpace/Mapping/table - Format: string - Default value: n/a - Required: true @@ -12970,7 +11549,7 @@ topic must be associated with the table. By default the topic name is equal to the table name. -- Full path: //OpenSplice/DbmsConnectService/DbmsToDds/NameSpace/Mapping[@topic] +- Full path: /DbmsConnectService/DbmsToDds/NameSpace/Mapping/topic - Format: string - Default value: "" - Required: false @@ -12983,7 +11562,7 @@ query means of a SQL query. The default value is an empty string, representing all available data in the selected table. -- Full path: //OpenSplice/DbmsConnectService/DbmsToDds/NameSpace/Mapping[@query] +- Full path: /DbmsConnectService/DbmsToDds/NameSpace/Mapping/query - Format: string - Default value: "" - Required: false @@ -13000,7 +11579,7 @@ publish_initial_data The value of this attribute is ignored when the corresponding *event_table_policy* is set to NONE. -- Full path: //OpenSplice/DbmsConnectService/DbmsToDds/NameSpace/Mapping[@publish_initial_data] +- Full path: /DbmsConnectService/DbmsToDds/NameSpace/Mapping/publish_initial_data - Format: boolean - Default value: true - Required: false @@ -13014,7 +11593,7 @@ force_key_equality the value will be inherited from the *force_key_equality* of the parent *NameSpace* element, which if not explicitly specified defaults to true. -- Full path: //OpenSplice/DbmsConnectService/DbmsToDds/NameSpace/Mapping[@force_key_equality] +- Full path: /DbmsConnectService/DbmsToDds/NameSpace/Mapping/force_key_equality - Format: boolean - Default value: true - Required: false @@ -13033,7 +11612,7 @@ event_table_policy - **LAZY**: An 'event table' will only be created if it is not available when the service connects, and it will not be deleted when the service disconnects. - **NONE**: An 'event table' will neither be created nor deleted by the service. For the specified table, the service will poll with a frequency specified in the coresponding *update_frequency* attribute of the parent *NameSpace*. It will start using the table as soon as it is available. With this policy set, no initial data will be published regardless of the value of the applicable *publish_initial_data* attribute. -- Full path: //OpenSplice/DbmsConnectService/DbmsToDds/NameSpace/Mapping[@event_table_policy] +- Full path: /DbmsConnectService/DbmsToDds/NameSpace/Mapping/event_table_policy - Format: enumeration - Default value: FULL - Valid values: FULL, LAZY, NONE @@ -13053,7 +11632,7 @@ trigger_policy - **LAZY**: Triggers will only be created if they are not available when the service connects, and will not be deleted when the service disconnects. - **NONE**: Triggers will neither be created nor deleted by the service. This allows you to build your own custom triggering mechanism. -- Full path: //OpenSplice/DbmsConnectService/DbmsToDds/NameSpace/Mapping[@trigger_policy] +- Full path: /DbmsConnectService/DbmsToDds/NameSpace/Mapping/trigger_policy - Format: enumeration - Default value: FULL - Valid values: FULL, LAZY, NONE @@ -13067,7 +11646,7 @@ Tracing This is useful to track the DbmsConnect Service during application development. In the runtime system it should be turned off. -- Full path: //OpenSplice/DbmsConnectService/Tracing +- Full path: /DbmsConnectService/Tracing - Occurrences min-max: 0-1 - Child elements: OutputFile, Timestamps, Verbosity @@ -13079,9 +11658,8 @@ OutputFile "standard out" and "standard error" respectively. The default value is an empty string, indicating that all tracing is disabled. -- Full path: //OpenSplice/DbmsConnectService/Tracing/OutputFile +- Full path: /DbmsConnectService/Tracing/OutputFile - Format: string -- Dimension: file name - Default value: dbmsconnect.log - Occurrences min-max: 0-1 @@ -13090,7 +11668,7 @@ Timestamps This element specifies whether the logging must contain timestamps. -- Full path: //OpenSplice/DbmsConnectService/Tracing/Timestamps +- Full path: /DbmsConnectService/Tracing/Timestamps - Format: boolean - Default value: true - Occurrences min-max: 0-1 @@ -13102,7 +11680,7 @@ absolute This attribute specifies whether the timestamps are absolute or relative to the startup time of the service. -- Full path: //OpenSplice/DbmsConnectService/Tracing/Timestamps[@absolute] +- Full path: /DbmsConnectService/Tracing/Timestamps/absolute - Format: boolean - Default value: true - Required: false @@ -13112,7 +11690,7 @@ Verbosity This element specifies the verbosity level of the logging. -- Full path: //OpenSplice/DbmsConnectService/Tracing/Verbosity +- Full path: /DbmsConnectService/Tracing/Verbosity - Format: enumeration - Default value: INFO - Valid values: SEVERE, WARNING, INFO, CONFIG, FINE, FINER, FINEST @@ -13124,7 +11702,7 @@ RnRService The Record and Replay Service allows to record data from a DDS domain to a storage, and replay data from a storage back into the DDS domain. -- Full path: //OpenSplice/RnRService +- Full path: /RnRService - Occurrences min-max: 0-* - Required attributes: name @@ -13137,7 +11715,7 @@ name must match the one specified under the *OpenSplice/Domain/Service[@name]* in the configuration of the Domain Service. -- Full path: //OpenSplice/RnRService[@name] +- Full path: /RnRService/name - Format: string - Default value: rnr - Required: true @@ -13147,7 +11725,7 @@ Watchdog This element controls the characteristics of the Watchdog thread. -- Full path: //OpenSplice/RnRService/Watchdog +- Full path: /RnRService/Watchdog - Occurrences min-max: 0-1 Scheduling @@ -13156,7 +11734,7 @@ Scheduling This element specifies the type of OS scheduling class will be used by the thread that announces its liveliness periodically. -- Full path: //OpenSplice/RnRService/Watchdog/Scheduling +- Full path: /RnRService/Watchdog/Scheduling - Occurrences min-max: 1-1 - Child elements: Priority, Class @@ -13169,7 +11747,7 @@ Priority The user may need special privileges from the underlying operating system to be able to assign some of the privileged priorities. -- Full path: //OpenSplice/RnRService/Watchdog/Scheduling/Priority +- Full path: /RnRService/Watchdog/Scheduling/Priority - Format: integer - Default value: 0 - Occurrences min-max: 1-1 @@ -13181,7 +11759,7 @@ priority_kind This attribute specifies whether the specified Priority is a relative or absolute priority. -- Full path: //OpenSplice/RnRService/Watchdog/Scheduling/Priority[@priority_kind] +- Full path: /RnRService/Watchdog/Scheduling/Priority/priority_kind - Format: enumeration - Default value: Relative - Valid values: Relative, Absolute @@ -13195,7 +11773,7 @@ Class the underlying operating system to be able to assign some of the privileged scheduling classes. -- Full path: //OpenSplice/RnRService/Watchdog/Scheduling/Class +- Full path: /RnRService/Watchdog/Scheduling/Class - Format: enumeration - Default value: Default - Valid values: Timeshare, Realtime, Default @@ -13203,47 +11781,52 @@ Class Storage ======= -This element specifies a storage to use for recording and/or replaying data. + + This element specifies a storage to use for recording and/or replaying data. Currently the supported storage backends are XML and CDR. Note that storages can also be created, or their properties modified, by Record and Replay configuration-commands. These commands use the same syntax to specify configuration data as the OpenSplice configuration file, so the description given here also applies to commands. -- Full path: //OpenSplice/RnRService/Storage +- Full path: /RnRService/Storage - Occurrences min-max: 0-* - Required attributes: name name ---- -The name used to identify the storage in Record and Replay commands. -- Full path: //OpenSplice/RnRService/Storage[@name] + The name used to identify the storage in Record and Replay commands. + +- Full path: /RnRService/Storage/name - Format: string - Default value: default - Required: true rr_storageAttrXML ----------------- -Attributes describing an XML storage. -- Full path: //OpenSplice/RnRService/Storage/rr_storageAttrXML + Attributes describing an XML storage. + +- Full path: /RnRService/Storage/rr_storageAttrXML - Occurrences min-max: 0-1 - Child elements: filename, MaxFileSize filename ^^^^^^^^ -The filename template used for files that comprise a storage. + + The filename template used for files that comprise a storage. The filename may contain a relative or absolute path. If a path is omitted, the storage files are created in the current working directory. -- Full path: //OpenSplice/RnRService/Storage/rr_storageAttrXML/filename +- Full path: /RnRService/Storage/rr_storageAttrXML/filename - Format: string - Default value: rnr-storage.dat - Occurrences min-max: 1-1 MaxFileSize ^^^^^^^^^^^ -The maximum size per storage file. When approaching the maximum size while recording, + + The maximum size per storage file. When approaching the maximum size while recording, a new storage file is automatically created with a sequence number appended to the filename. The active file is also switched transparently while replaying from a storage that contains multiple data files. @@ -13252,34 +11835,35 @@ The maximum size per storage file. When approaching the maximum size while recor This element is optional, when omitted or when 0 is configured, the file size is not monitored by the service and limited only by filesystem and/or platform-specific limits. -- Full path: //OpenSplice/RnRService/Storage/rr_storageAttrXML/MaxFileSize -- Dimension: bytes +- Full path: /RnRService/Storage/rr_storageAttrXML/MaxFileSize - Default value: 0 -- Valid values: 0 / - - Occurrences min-max: 0-1 rr_storageAttrCDR ----------------- -Attributes describing an CDR storage. -- Full path: //OpenSplice/RnRService/Storage/rr_storageAttrCDR + Attributes describing an CDR storage. + +- Full path: /RnRService/Storage/rr_storageAttrCDR - Occurrences min-max: 0-1 - Child elements: filename, MaxFileSize filename ^^^^^^^^ -The filename template used for files that comprise a storage. + + The filename template used for files that comprise a storage. The filename may contain a relative or absolute path. If a path is omitted, the storage files are created in the current working directory. -- Full path: //OpenSplice/RnRService/Storage/rr_storageAttrCDR/filename +- Full path: /RnRService/Storage/rr_storageAttrCDR/filename - Format: string - Default value: rnr-storage.dat - Occurrences min-max: 1-1 MaxFileSize ^^^^^^^^^^^ -The maximum size per storage file. When approaching the maximum size while recording, + + The maximum size per storage file. When approaching the maximum size while recording, a new storage file is automatically created with a sequence number appended to the filename. The active file is also switched transparently while replaying from a storage that contains multiple data files. @@ -13288,25 +11872,25 @@ The maximum size per storage file. When approaching the maximum size while recor This element is optional, when omitted or when 0 is configured, the file size is not monitored by the service and limited only by filesystem and/or platform-specific limits. -- Full path: //OpenSplice/RnRService/Storage/rr_storageAttrCDR/MaxFileSize -- Dimension: bytes +- Full path: /RnRService/Storage/rr_storageAttrCDR/MaxFileSize - Default value: 0 -- Valid values: 0 / - - Occurrences min-max: 0-1 Statistics ---------- -Maintain and optionally publish statistics for this storage. -- Full path: //OpenSplice/RnRService/Storage/Statistics + Maintain and optionally publish statistics for this storage. + +- Full path: /RnRService/Storage/Statistics - Occurrences min-max: 0-1 - Optional attributes: enabled, publish_interval, reset enabled ^^^^^^^ -This attribute specifies if statistics should be maintained for this storage. -- Full path: //OpenSplice/RnRService/Storage/Statistics[@enabled] + This attribute specifies if statistics should be maintained for this storage. + +- Full path: /RnRService/Storage/Statistics/enabled - Format: boolean - Default value: true - Occurrences min-max: 1-1 @@ -13314,25 +11898,26 @@ This attribute specifies if statistics should be maintained for this storage. publish_interval ^^^^^^^^^^^^^^^^ -This attribute specifies the publication interval of the statistics belonging to this storage, + + This attribute specifies the publication interval of the statistics belonging to this storage, in a Record and Replay storage-statistics topic. The publish interval is a value in seconds but may also be set to -1. This means the statistics are published when the storage is closed. Note that a value of 0 means statistics are never published. -- Full path: //OpenSplice/RnRService/Storage/Statistics[@publish_interval] +- Full path: /RnRService/Storage/Statistics/publish_interval - Format: integer -- Dimension: seconds - Default value: 30 - Occurrences min-max: 1-1 - Required: false reset ^^^^^ -This attribute allows to reset the current values of statistics belonging to the storage. Note + + This attribute allows to reset the current values of statistics belonging to the storage. Note that this only makes sense in a configuration-command for an existing storage, since new storages created from the OpenSplice configuration file always start out with empty statistics. -- Full path: //OpenSplice/RnRService/Storage/Statistics[@reset] +- Full path: /RnRService/Storage/Statistics/reset - Format: boolean - Default value: false - Occurrences min-max: 0-1 @@ -13340,39 +11925,43 @@ This attribute allows to reset the current values of statistics belonging to the Tracing ======= -This element enables debug output of the R&R service to a logfile. -- Full path: //OpenSplice/RnRService/Tracing + This element enables debug output of the R&R service to a logfile. + +- Full path: /RnRService/Tracing - Occurrences min-max: 0-1 - Child elements: OutputFile, AppendToFile, Verbosity, EnableCategory OutputFile ---------- -This option specifies where the logging is printed to. + + This option specifies where the logging is printed to. Note that "stdout" is considered a legal value that represents "standard out" and "stderr" is a legal value representing "standard error". -- Full path: //OpenSplice/RnRService/Tracing/OutputFile +- Full path: /RnRService/Tracing/OutputFile - Format: string - Default value: rnr.log - Occurrences min-max: 1-1 AppendToFile ------------ -This option specifies whether the output is to be appended to an existing log file. + + This option specifies whether the output is to be appended to an existing log file. The default is to overwrite the log file if it exists. -- Full path: //OpenSplice/RnRService/Tracing/AppendToFile +- Full path: /RnRService/Tracing/AppendToFile - Format: boolean - Default value: false - Occurrences min-max: 0-1 Verbosity --------- -This element specifies the verbosity level of the logging information. + + This element specifies the verbosity level of the logging information. The higher the level, the more (detailed) information will be logged. -- Full path: //OpenSplice/RnRService/Tracing/Verbosity +- Full path: /RnRService/Tracing/Verbosity - Format: enumeration - Default value: INFO - Valid values: SEVERE, WARNING, INFO, CONFIG, FINE, FINER, FINEST, NONE @@ -13380,7 +11969,8 @@ This element specifies the verbosity level of the logging information. EnableCategory -------------- -This option allows to enable specific logging categories independently of the + + This option allows to enable specific logging categories independently of the categories selected by specifiying a verbosity level. Multiple categories, seperated by a comma, can be supplied. The following categories are available: @@ -13394,116 +11984,7 @@ This option allows to enable specific logging categories independently of the - **RECORD**: Messages for each recorded sample. - **REPLAY**: Messages for each replayed sample. -- Full path: //OpenSplice/RnRService/Tracing/EnableCategory -- Format: string -- Occurrences min-max: 0-1 - -Agent -***** -The root element of a Control and Monitoring Agent configuration. - -- Full path: //OpenSplice/Agent -- Occurrences min-max: 0-1 -- Required attributes: name - -name -==== -This attribute identifies the configuration for the Control and Monitoring Agent. Multiple service configurations can be specified in one single XML file. The actual applicable configuration is determined by the value of the name attribute, which must match the string specified in the element OpenSplice/Domain/Service[@name] in the Domain Service configuration. - -- Full path: //OpenSplice/Agent[@name] -- Format: string -- Default value: cmagent -- Required: true - -Tracing -======= -The Tracing element controls the amount and type of information that is written into the tracing log by the Control and Monitoring Agent service. This is useful to track the service during application development. - -- Full path: //OpenSplice/Agent/Tracing -- Occurrences min-max: 0-1 -- Child elements: EnableCategory, Verbosity, OutputFile, AppendToFile - -EnableCategory --------------- -This element enables individual logging categories. These are enabled in addition to those enabled by Tracing/Verbosity. Recognised categories are:- *fatal*: all fatal errors, errors causing immediate termination- *error*: failures probably impacting correctness but not necessarily causing immediate termination- *warning*: abnormal situations that will likely not impact correctness- *config*: full dump of the configuration- *info*: general informational notices -In addition, there is the keyword *trace* that enables all categories - -- Full path: //OpenSplice/Agent/Tracing/EnableCategory -- Format: string -- Occurrences min-max: 0-1 - -Verbosity ---------- -This element enables standard groups of categories, based on a desired verbosity level. This is in addition to the categories enabled by the Tracing/EnableCategory setting. Recognised verbosity levels and the categories they map to are:- *none*: no Control and Monitoring Agent log- *severe*: error and fatal- *warning*: *severe* + warning- *info*: *warning* + general information messages- *config*: *info* + config- *fine*: equivalent to *config*- *finest*: *fine* + trace -While *none* prevents any message from being written to a Control and Monitoring Agent log file, warnings and errors are still logged in the ospl-info.log and ospl-error.log files. - -- Full path: //OpenSplice/Agent/Tracing/Verbosity -- Format: enumeration -- Default value: none -- Valid values: finest, finer, fine, config, info, warning, severe, none -- Occurrences min-max: 0-1 - -OutputFile ----------- -This option specifies where the logging is printed to. Note that *stdout* and *stderr* are treated as special values, representing "standard out" and "standard error" respectively. No file is created unless logging categories are enabled using the Tracing/Verbosity or Tracing/EnabledCategory settings. - -- Full path: //OpenSplice/Agent/Tracing/OutputFile +- Full path: /RnRService/Tracing/EnableCategory - Format: string -- Dimension: file path -- Default value: cmagent.log -- Occurrences min-max: 0-1 - -AppendToFile ------------- -This option specifies whether the output is to be appended to an existing log file. The default is to create a new log file each time, which is generally the best option if a detailed log is generated. - -- Full path: //OpenSplice/Agent/Tracing/AppendToFile -- Format: boolean -- Default value: false -- Occurrences min-max: 0-1 - -Watchdog -======== -This element specifies the type of OS scheduling class will be used by the thread that announces its liveliness periodically. - -- Full path: //OpenSplice/Agent/Watchdog -- Occurrences min-max: 0-1 - -Scheduling ----------- -This element specifies the type of OS scheduling class will be used by the thread that announces its liveliness periodically. - -- Full path: //OpenSplice/Agent/Watchdog/Scheduling -- Occurrences min-max: 0-1 -- Child elements: Class, Priority - -Class -^^^^^ -This element specifies the thread scheduling class that will be used by the watchdog thread. The user may need the appropriate privileges from the underlying operating system to be able to assign some of the privileged scheduling classes. - -- Full path: //OpenSplice/Agent/Watchdog/Scheduling/Class -- Format: enumeration -- Default value: default -- Valid values: realtime, timeshare, default -- Occurrences min-max: 0-1 - -Priority -^^^^^^^^ -This element specifies the thread priority. Only priorities that are supported by the underlying operating system can be assigned to this element. The user may need special privileges from the underlying operating system to be able to assign some of the privileged priorities. - -- Full path: //OpenSplice/Agent/Watchdog/Scheduling/Priority -- Format: integer -- Default value: 0 - Occurrences min-max: 0-1 -- Required attributes: priority_kind - -priority_kind -~~~~~~~~~~~~~ -This attribute specifies whether the specified Priority is a relative or absolute priority. - -- Full path: //OpenSplice/Agent/Watchdog/Scheduling/Priority[@priority_kind] -- Format: enumeration -- Default value: relative -- Valid values: relative, absolute -- Required: true diff --git a/docs/html/ConfGuide/_sources/intro.txt b/docs/html/ConfGuide/_sources/intro.txt index d66edb731..23173f39f 100644 --- a/docs/html/ConfGuide/_sources/intro.txt +++ b/docs/html/ConfGuide/_sources/intro.txt @@ -1,8 +1,5 @@ -.. _`Configuration`: - -############# Introduction -############# +############ This guide describes the various configuration elements and attributes available for Vortex OpenSplice. The configuration items should be added to an XML file @@ -55,7 +52,7 @@ The ospl.xml file supplied with Vortex OpenSplice contains the following: 0.1 - + ddsi2 diff --git a/docs/html/ConfGuide/genindex.html b/docs/html/ConfGuide/genindex.html index 9c212eb4a..b8ecbbaa3 100644 --- a/docs/html/ConfGuide/genindex.html +++ b/docs/html/ConfGuide/genindex.html @@ -88,7 +88,7 @@

Navigation

\ No newline at end of file diff --git a/docs/html/ConfGuide/guide.html b/docs/html/ConfGuide/guide.html index 79229ffbb..967a6db70 100644 --- a/docs/html/ConfGuide/guide.html +++ b/docs/html/ConfGuide/guide.html @@ -76,9 +76,8 @@

2   OpenSplice
    -
  • Full path: //OpenSplice
  • +
  • Full path: /OpenSplice
  • Occurrences min-max: 1-1
  • -
  • Child elements: Description

3.3   Role¶

-
Within a system and depending on the hosted application a Domain Service can -have a specific role and interaction with other Domain Services may depend on this -role. -The Role element is a user-defined string value that is communicated through the -system, the behavior of other Domain Services i.e. how they interact with a Domain -Service can be configured depend of the role by means of string matching -expressions. For example, a Domain Service could limit its communication with -other Domain Services by only accepting specific roles. (See also -OpenSplice/NetworkService/Discovery[@Scope] )
+
This (optional) element specifies the role of the instantiated domain. For dynamic discovery, this role will +be used to define the communication scope of instantiated domains on other nodes in the system. The purpose +of specifying roles within the system is to ‘overlay’ the underlying physical network with a node’s scope-of-interest +that allows to bound topology discovery effort and related overhead in large scale (WAN) systems.
    -
  • Full path: //OpenSplice/Domain/Role
  • +
  • Full path: /Domain/Role
  • Format: string
  • Default value: DefaultRole
  • Occurrences min-max: 0-1
  • @@ -153,13 +146,10 @@

    3.3   Role

    3.4   Lease¶

    -
    The Lease parameter specifies the death detection time of the Domain Service. All -internal tasks performed by the Domain Service will periodically update their -liveliness; when one or more tasks fail to update its liveliness the Domain will take -action to either repair the failing functionality, continue in a degraded mode, or halt, -depending on the configured desired behaviour.
    +
    The Lease parameters specify how the Domain service as well as the services started by the +Domain service must announce their liveliness in the DDS administration.
      -
    • Full path: //OpenSplice/Domain/Lease
    • +
    • Full path: /Domain/Lease
    • Occurrences min-max: 0-1
    • Child elements: ExpiryTime
    @@ -174,11 +164,8 @@

    3.4.1   ExpiryTime

    -
  • Full path: //OpenSplice/Domain/Lease/ExpiryTime
  • -
  • Format: float
  • -
  • Dimension: seconds
  • +
  • Full path: /Domain/Lease/ExpiryTime
  • Default value: 10.0
  • -
  • Valid values: 0.2 / -
  • Occurrences min-max: 1-1
  • Required attributes: update_factor
@@ -191,10 +178,8 @@

3.4.1.1   update_factor -
  • Full path: //OpenSplice/Domain/Lease/ExpiryTime[@update_factor]
  • -
  • Format: float
  • +
  • Full path: /Domain/Lease/ExpiryTime/update_factor
  • Default value: 0.2
  • -
  • Valid values: 0.01 / 1.0
  • Required: true
  • @@ -208,7 +193,7 @@

    3.5   GeneralWatchdog -
  • Full path: //OpenSplice/Domain/GeneralWatchdog
  • +
  • Full path: /Domain/GeneralWatchdog
  • Occurrences min-max: 0-1
    • -
    • Full path: //OpenSplice/Domain/GeneralWatchdog/Scheduling
    • +
    • Full path: /Domain/GeneralWatchdog/Scheduling
    • Occurrences min-max: 1-1
    • Child elements: Priority, Class
    @@ -230,7 +215,7 @@

    3.5.1.1   Priority @@ -298,12 +280,9 @@

    3.7   SingleProcess: The user starts an application as a @@ -327,35 +306,24 @@

    3.7   SingleProcess -
  • Full path: //OpenSplice/Domain/SingleProcess
  • +
  • Full path: /Domain/SingleProcess
  • Format: boolean
  • Default value: false
  • Occurrences min-max: 0-1
  • -
    -

    3.8   Description¶

    -
    -
    The content of this (optional) element is visualised by the Launcher tool and is meant -to describe the configuration in a human-readable form.
    -
      -
    • Full path: //OpenSplice/Domain/Description
    • -
    • Format: string
    • -
    • Occurrences min-max: 0-1
    • -
    -
    -

    3.9   CPUAffinity¶

    +

    3.8   CPUAffinity¶

    This (optional) element specifies a comma separated list of CPU numbers for the CPUs which opensplice, and its services should be restricted to use. (Supported on VxWorks kernel mode only)
      -
    • Full path: //OpenSplice/Domain/CPUAffinity
    • +
    • Full path: /Domain/CPUAffinity
    • Format: string
    • Occurrences min-max: 0-1
    -

    3.10   InProcessExceptionHandling¶

    +

    3.9   InProcessExceptionHandling¶

    The InProcessExceptionHandling element determines whether a process that uses OpenSplice will
    @@ -373,14 +341,14 @@

    3.10   InProcessExceptionHandling -
  • Full path: //OpenSplice/Domain/InProcessExceptionHandling
  • +
  • Full path: /Domain/InProcessExceptionHandling
  • Format: boolean
  • Default value: true
  • Occurrences min-max: 0-1
  • -

    3.11   Daemon¶

    +

    3.10   Daemon¶

    Every domain is controlled by exactly one daemon: the Splice Daemon. The Splice Daemon configuration expects a root element named @@ -388,12 +356,12 @@

    3.11   Daemon -
  • Full path: //OpenSplice/Domain/Daemon
  • +
  • Full path: /Domain/Daemon
  • Occurrences min-max: 0-1
  • Child elements: Locking
  • -

    3.11.1   Locking¶

    +

    3.10.1   Locking¶

    This element specifies the locking policy for the Splice Deamon process, indicating whether its pages should be locked in physical @@ -407,36 +375,32 @@

    3.11.1   Locking -
  • Full path: //OpenSplice/Domain/Daemon/Locking
  • +
  • Full path: /Domain/Daemon/Locking
  • Format: boolean
  • Default value: false
  • Occurrences min-max: 0-1
  • -

    3.11.2   Watchdog¶

    +

    3.10.2   Watchdog¶

    -
    This element controls the scheduling characteristics of the Watchdog thread. This -thread is responsible for sending domain service heartbeats, updating liveliness of -the service builtin DataWriters and monitoring the health of internal services and -heartbeats of remote domain services.
    +
    This element controls the characteristics of the Spliced Daemon Watchdog thread
      -
    • Full path: //OpenSplice/Domain/Daemon/Watchdog
    • +
    • Full path: /Domain/Daemon/Watchdog
    • Occurrences min-max: 0-1
    • -
    • Child elements: StackSize
    -

    3.11.2.1   Scheduling¶

    +

    3.10.2.1   Scheduling¶

    This element specifies the type of OS scheduling class will be used by the thread that announces its liveliness periodically.
      -
    • Full path: //OpenSplice/Domain/Daemon/Watchdog/Scheduling
    • +
    • Full path: /Domain/Daemon/Watchdog/Scheduling
    • Occurrences min-max: 1-1
    • Child elements: Priority, Class
    -
    3.11.2.1.1   Priority¶
    +
    3.10.2.1.1   Priority¶
    This element specifies the thread priority that will be used by the watchdog thread. Only priorities that are supported by the @@ -444,35 +408,21 @@
    3.11.2.1.1   Priority
      -
    • Full path: //OpenSplice/Domain/Daemon/Watchdog/Scheduling/Priority
    • +
    • Full path: /Domain/Daemon/Watchdog/Scheduling/Priority
    • Format: integer
    • Default value: 0
    • Occurrences min-max: 1-1
    • -
    • Optional attributes: priority_kind
    • -
    -
    -
    3.11.2.1.1.1   priority_kind¶
    -
    -
    This attribute specifies whether the specified Priority is a relative or absolute priority
    -
      -
    • Full path: //OpenSplice/Domain/Daemon/Watchdog/Scheduling/Priority[@priority_kind]
    • -
    • Format: enumeration
    • -
    • Default value: Relative
    • -
    • Valid values: Relative, Absolute
    • -
    • Occurrences min-max: 0-1
    • -
    • Required: false
    -
    -
    -
    3.11.2.1.2   Class¶
    +
    +
    3.10.2.1.2   Class¶
    This element specifies the thread scheduling class that will be used by the watchdog thread. The user may need the appropriate privileges from the underlying operating system to be able to assign some of the privileged scheduling classes.
      -
    • Full path: //OpenSplice/Domain/Daemon/Watchdog/Scheduling/Class
    • +
    • Full path: /Domain/Daemon/Watchdog/Scheduling/Class
    • Format: enumeration
    • Default value: Default
    • Valid values: Timeshare, Realtime, Default
    • @@ -480,129 +430,37 @@
      3.11.2.1.2   Class -

      3.11.2.2   StackSize¶

      -
      -
      This element specifies the thread stacksize that will be used by the -Watchdog thread. By default this is 512 Kb.
      -
        -
      • Full path: //OpenSplice/Domain/Daemon/Watchdog/StackSize
      • -
      • Format: integer
      • -
      • Dimension: bytes
      • -
      • Default value: 524288
      • -
      • Occurrences min-max: 0-1
      • -
      -
    -
    -
    -

    3.11.3   shmMonitor¶

    -
    -
    This element controls the scheduling characteristics of the shmMonitor thread. This -thread is responsible cleaning up resources that are left behind by unexpected termination of other -dds services and applications.
    -
      -
    • Full path: //OpenSplice/Domain/Daemon/shmMonitor
    • -
    • Occurrences min-max: 0-1
    • -
    • Child elements: StackSize
    • -
    -
    -

    3.11.3.1   Scheduling¶

    -
    -
    This element specifies the type of OS scheduling class will be -used by the thread that announces its liveliness periodically.
    -
      -
    • Full path: //OpenSplice/Domain/Daemon/shmMonitor/Scheduling
    • -
    • Occurrences min-max: 1-1
    • -
    • Child elements: Priority, Class
    • -
    -
    -
    3.11.3.1.1   Priority¶
    -
    -
    This element specifies the thread priority that will be used by the -shmMonitor thread. Only priorities that are supported by the -underlying operating system can be assigned to this element. -The user may need special privileges from the underlying operating -system to be able to assign some of the privileged priorities.
    -
      -
    • Full path: //OpenSplice/Domain/Daemon/shmMonitor/Scheduling/Priority
    • -
    • Format: integer
    • -
    • Default value: 0
    • -
    • Occurrences min-max: 1-1
    • -
    • Optional attributes: priority_kind
    • -
    -
    -
    3.11.3.1.1.1   priority_kind¶
    -
    -
    This attribute specifies whether the specified Priority is a relative or absolute priority
    -
      -
    • Full path: //OpenSplice/Domain/Daemon/shmMonitor/Scheduling/Priority[@priority_kind]
    • -
    • Format: enumeration
    • -
    • Default value: Relative
    • -
    • Valid values: Relative, Absolute
    • -
    • Occurrences min-max: 0-1
    • -
    • Required: false
    • -
    -
    -
    -
    3.11.3.1.2   Class¶
    +
    +

    3.10.3   KernelManager¶

    -
    This element specifies the thread scheduling class that will be used by -the shmMonitor thread. The user may need the appropriate privileges from -the underlying operating system to be able to assign some of the -privileged scheduling classes.
    -
      -
    • Full path: //OpenSplice/Domain/Daemon/shmMonitor/Scheduling/Class
    • -
    • Format: enumeration
    • -
    • Default value: Default
    • -
    • Valid values: Timeshare, Realtime, Default
    • -
    • Occurrences min-max: 1-1
    • -
    -
    -
    -
    -

    3.11.3.2   StackSize¶

    +

    This element specifies the behaviour of the KernelManager.

    +

    The kernel manager actively monitors the OpenSplice kernel +and executes administrative tasks:

    -
    This element specifies the thread stacksize that will be used by the -shmMonitor thread. By default this is 512 Kb.
    -
      -
    • Full path: //OpenSplice/Domain/Daemon/shmMonitor/StackSize
    • -
    • Format: integer
    • -
    • Dimension: bytes
    • -
    • Default value: 524288
    • -
    • Occurrences min-max: 0-1
    • +
        +
      • check topic consistency
      • +
      • determine liveliness status of readers and writers
      • +
      • notify readers and writers on incompatible QoS
      -
      -
    -
    -

    3.11.4   KernelManager¶

    -
    -
    The Kernel Manager monitors Builtin Topic on status changes of DataWriters and -inconsistencies between Topics and QoS policies, and it will notify all participants -interested in any of these events, i.e. it updates status fields and wakeup blocking -waitset and listener threads. -Controlling the scheduling behaviour of the Kernel Manager will therefore infuence -the reactivity on detecting events, but it will not infuence the event handling itself as -this is the responsibility of the participants waitset or listener thread. -Note that the Kernel Manager has no or limited value when Builtin Topics are -disabled.
    +

    +
      -
    • Full path: //OpenSplice/Domain/Daemon/KernelManager
    • +
    • Full path: /Domain/Daemon/KernelManager
    • Occurrences min-max: 0-1
    • -
    • Child elements: StackSize
    -
    -

    3.11.4.1   Scheduling¶

    +
    +

    3.10.3.1   Scheduling¶

    This element specifies the scheduling policies used to control the KernelManager thread.
      -
    • Full path: //OpenSplice/Domain/Daemon/KernelManager/Scheduling
    • +
    • Full path: /Domain/Daemon/KernelManager/Scheduling
    • Occurrences min-max: 1-1
    • Child elements: Priority, Class
    -
    -
    3.11.4.1.1   Priority¶
    +
    +
    3.10.3.1.1   Priority¶
    This element specifies the thread priority that will be used by the KernelManager thread. Only priorities that are supported by the @@ -610,19 +468,19 @@
    3.11.4.1.1   Priority
      -
    • Full path: //OpenSplice/Domain/Daemon/KernelManager/Scheduling/Priority
    • +
    • Full path: /Domain/Daemon/KernelManager/Scheduling/Priority
    • Format: integer
    • Default value: 0
    • Occurrences min-max: 1-1
    • Optional attributes: priority_kind
    -
    -
    3.11.4.1.1.1   priority_kind¶
    +
    +
    3.10.3.1.1.1   priority_kind¶
    This attribute specifies whether the specified Priority is a relative or absolute priority.
      -
    • Full path: //OpenSplice/Domain/Daemon/KernelManager/Scheduling/Priority[@priority_kind]
    • +
    • Full path: /Domain/Daemon/KernelManager/Scheduling/Priority/priority_kind
    • Format: enumeration
    • Default value: Relative
    • Valid values: Relative, Absolute
    • @@ -630,15 +488,15 @@
      3.11.4.1.1.1   priority_kind -
      3.11.4.1.2   Class¶
      +
      +
      3.10.3.1.2   Class¶
      This element specifies the thread scheduling class that will be used by the KernelManager thread. The user may need the appropriate privileges from the underlying operating system to be able to assign some of the privileged scheduling classes.
        -
      • Full path: //OpenSplice/Domain/Daemon/KernelManager/Scheduling/Class
      • +
      • Full path: /Domain/Daemon/KernelManager/Scheduling/Class
      • Format: enumeration
      • Default value: Default
      • Valid values: Timeshare, Realtime, Default
      • @@ -646,22 +504,9 @@
        3.11.4.1.2   Class -

        3.11.4.2   StackSize¶

        -
        -
        This element specifies the thread stacksize that will be used by the -KernelManager thread. By default this is 512 Kb.
        -
          -
        • Full path: //OpenSplice/Domain/Daemon/KernelManager/StackSize
        • -
        • Format: integer
        • -
        • Dimension: bytes
        • -
        • Default value: 524288
        • -
        • Occurrences min-max: 0-1
        • -
        -
    -

    3.11.5   GarbageCollector¶

    +

    3.10.4   GarbageCollector¶

    This element specifies the behaviour of the GarbageCollector.

    The garbage collector is a safety mechanism and is responsible for @@ -669,22 +514,21 @@

    3.11.5   GarbageCollector -
  • Full path: //OpenSplice/Domain/Daemon/GarbageCollector
  • +
  • Full path: /Domain/Daemon/GarbageCollector
  • Occurrences min-max: 0-1
  • -
  • Child elements: StackSize
  • -
    -

    3.11.5.1   Scheduling¶

    +
    +

    3.10.4.1   Scheduling¶

    This element specifies the scheduling policies used to control the GarbageCollector thread.
      -
    • Full path: //OpenSplice/Domain/Daemon/GarbageCollector/Scheduling
    • +
    • Full path: /Domain/Daemon/GarbageCollector/Scheduling
    • Occurrences min-max: 1-1
    • Child elements: Priority, Class
    -
    -
    3.11.5.1.1   Priority¶
    +
    +
    3.10.4.1.1   Priority¶
    This element specifies the thread priority that will be used by the GarbageCollector thread. Only priorities that are supported @@ -692,19 +536,19 @@
    3.11.5.1.1   Priority
      -
    • Full path: //OpenSplice/Domain/Daemon/GarbageCollector/Scheduling/Priority
    • +
    • Full path: /Domain/Daemon/GarbageCollector/Scheduling/Priority
    • Format: integer
    • Default value: 0
    • Occurrences min-max: 1-1
    • Optional attributes: priority_kind
    -
    -
    3.11.5.1.1.1   priority_kind¶
    +
    +
    3.10.4.1.1.1   priority_kind¶
    This attribute specifies whether the specified Priority is a relative or absolute priority.
      -
    • Full path: //OpenSplice/Domain/Daemon/GarbageCollector/Scheduling/Priority[@priority_kind]
    • +
    • Full path: /Domain/Daemon/GarbageCollector/Scheduling/Priority/priority_kind
    • Format: enumeration
    • Default value: Relative
    • Valid values: Relative, Absolute
    • @@ -712,15 +556,15 @@
      3.11.5.1.1.1   priority_kind -
      3.11.5.1.2   Class¶
      +
      +
      3.10.4.1.2   Class¶
      This element specifies the thread scheduling class that will be used by the GarbageCollector thread. The user may need the appropriate privileges from the underlying operating system to be able to assign some of the privileged scheduling classes.
        -
      • Full path: //OpenSplice/Domain/Daemon/GarbageCollector/Scheduling/Class
      • +
      • Full path: /Domain/Daemon/GarbageCollector/Scheduling/Class
      • Format: enumeration
      • Default value: Default
      • Valid values: Timeshare, Realtime, Default
      • @@ -728,44 +572,30 @@
        3.11.5.1.2   Class -

        3.11.5.2   StackSize¶

        -
        -
        This element specifies the thread stacksize that will be used by the -GarbageCollector thread. By default this is 512 Kb.
        -
          -
        • Full path: //OpenSplice/Domain/Daemon/GarbageCollector/StackSize
        • -
        • Format: integer
        • -
        • Dimension: bytes
        • -
        • Default value: 524288
        • -
        • Occurrences min-max: 0-1
        • -
        -
    -

    3.11.6   ResendManager¶

    +

    3.10.5   ResendManager¶

    Every service has its own ResendManager thread, that is responsible for attempting to resend samples in the history queue of its writers. A writer that cannot successfully deliver a sample to a local service or application in the first attempt (for example because the application or service ran out of queue space) will store that sample in its own history queue, from which the Resend manager will periodically try to re-transmit it.
      -
    • Full path: //OpenSplice/Domain/Daemon/ResendManager
    • +
    • Full path: /Domain/Daemon/ResendManager
    • Occurrences min-max: 0-1
    • -
    • Child elements: StackSize
    -
    -

    3.11.6.1   Scheduling¶

    +
    +

    3.10.5.1   Scheduling¶

    This element specifies the type of OS scheduling class used by the thread that does local resends for the builtin participant.
      -
    • Full path: //OpenSplice/Domain/Daemon/ResendManager/Scheduling
    • +
    • Full path: /Domain/Daemon/ResendManager/Scheduling
    • Occurrences min-max: 1-1
    • Child elements: Priority, Class
    -
    -
    3.11.6.1.1   Priority¶
    +
    +
    3.10.5.1.1   Priority¶
    This element specifies the thread priority that will be used by the ResendManager thread. Only priorities that are supported by the @@ -773,19 +603,19 @@
    3.11.6.1.1   Priority
      -
    • Full path: //OpenSplice/Domain/Daemon/ResendManager/Scheduling/Priority
    • +
    • Full path: /Domain/Daemon/ResendManager/Scheduling/Priority
    • Format: integer
    • Default value: 0
    • Occurrences min-max: 1-1
    • Optional attributes: priority_kind
    -
    -
    3.11.6.1.1.1   priority_kind¶
    +
    +
    3.10.5.1.1.1   priority_kind¶
    This attribute specifies whether the specified Priority is a relative or absolute priority.
      -
    • Full path: //OpenSplice/Domain/Daemon/ResendManager/Scheduling/Priority[@priority_kind]
    • +
    • Full path: /Domain/Daemon/ResendManager/Scheduling/Priority/priority_kind
    • Format: enumeration
    • Default value: Relative
    • Valid values: Relative, Absolute
    • @@ -793,15 +623,15 @@
      3.11.6.1.1.1   priority_kind -
      3.11.6.1.2   Class¶
      +
      +
      3.10.5.1.2   Class¶
      This element specifies the thread scheduling class that will be used by the ResendManager thread. The user may need the appropriate privileges from the underlying operating system to be able to assign some of the privileged scheduling classes.
        -
      • Full path: //OpenSplice/Domain/Daemon/ResendManager/Scheduling/Class
      • +
      • Full path: /Domain/Daemon/ResendManager/Scheduling/Class
      • Format: enumeration
      • Default value: Default
      • Valid values: Timeshare, Realtime, Default
      • @@ -809,22 +639,9 @@
        3.11.6.1.2   Class -

        3.11.6.2   StackSize¶

        -
        -
        This element specifies the thread stacksize that will be used by the -ResendManager thread. By default this is 512 Kb.
        -
          -
        • Full path: //OpenSplice/Domain/Daemon/ResendManager/StackSize
        • -
        • Format: integer
        • -
        • Dimension: bytes
        • -
        • Default value: 524288
        • -
        • Occurrences min-max: 0-1
        • -
        -
    -

    3.11.7   Heartbeat¶

    +

    3.10.6   Heartbeat¶

    The Splice Daemon uses an heartbeat mechanism to monitor the health of the remote domain services. This element allows @@ -833,36 +650,35 @@

    3.11.7   Heartbeat

      -
    • Full path: //OpenSplice/Domain/Daemon/Heartbeat
    • +
    • Full path: /Domain/Daemon/Heartbeat
    • Occurrences min-max: 0-1
    • -
    • Child elements: ExpiryTime, StackSize
    • +
    • Child elements: ExpiryTime
    • Optional attributes: transport_priority
    -

    3.11.7.1   transport_priority¶

    +

    3.10.6.1   transport_priority¶

    This attribute controls the transport priority QoS setting (in seconds) that is only used by the Splice Daemom for for sending its heartbeats.
      -
    • Full path: //OpenSplice/Domain/Daemon/Heartbeat[@transport_priority]
    • +
    • Full path: /Domain/Daemon/Heartbeat/transport_priority
    • Format: integer
    • Default value: 0
    • -
    • Valid values: 0 / -
    • Required: false
    -
    -

    3.11.7.2   Scheduling¶

    +
    +

    3.10.6.2   Scheduling¶

    This element specifies the scheduling parameters used by the thread that periodically sends the heartbeats.
      -
    • Full path: //OpenSplice/Domain/Daemon/Heartbeat/Scheduling
    • +
    • Full path: /Domain/Daemon/Heartbeat/Scheduling
    • Occurrences min-max: 0-1
    • Child elements: Priority, Class
    -
    -
    3.11.7.2.1   Priority¶
    +
    +
    3.10.6.2.1   Priority¶
    This element specifies the thread priority that will be used by the thread that periodically sends the heartbeats. Only @@ -871,19 +687,19 @@
    3.11.7.2.1   Priority
      -
    • Full path: //OpenSplice/Domain/Daemon/Heartbeat/Scheduling/Priority
    • +
    • Full path: /Domain/Daemon/Heartbeat/Scheduling/Priority
    • Format: integer
    • Default value: 0
    • Occurrences min-max: 1-1
    • Optional attributes: priority_kind
    -
    -
    3.11.7.2.1.1   priority_kind¶
    +
    +
    3.10.6.2.1.1   priority_kind¶
    This attribute specifies whether the specified Priority is a relative or absolute priority.
      -
    • Full path: //OpenSplice/Domain/Daemon/Heartbeat/Scheduling/Priority[@priority_kind]
    • +
    • Full path: /Domain/Daemon/Heartbeat/Scheduling/Priority/priority_kind
    • Format: enumeration
    • Default value: Relative
    • Valid values: Relative, Absolute
    • @@ -891,8 +707,8 @@
      3.11.7.2.1.1   priority_kind -
      3.11.7.2.2   Class¶
      +
      +
      3.10.6.2.2   Class¶
      This element specifies the thread scheduling class that will be used by the thread that periodically sends the heartbeats. @@ -900,7 +716,7 @@
      3.11.7.2.2   Class -
    • Full path: //OpenSplice/Domain/Daemon/Heartbeat/Scheduling/Class
    • +
    • Full path: /Domain/Daemon/Heartbeat/Scheduling/Class
    • Format: enumeration
    • Default value: Default
    • Valid values: Timeshare, Realtime, Default
    • @@ -908,8 +724,8 @@
      3.11.7.2.2   Class -

      3.11.7.3   ExpiryTime¶

      +
      +

      3.10.6.3   ExpiryTime¶

      This element specifies the maximum amount of time(in seconds) in which the Splice Daemon expects a new heartbeat of @@ -923,14 +739,13 @@

      3.11.7.3   ExpiryTime

        -
      • Full path: //OpenSplice/Domain/Daemon/Heartbeat/ExpiryTime
      • +
      • Full path: /Domain/Daemon/Heartbeat/ExpiryTime
      • Default value: 4.0
      • -
      • Valid values: 0.2 / -
      • -
      • Occurrences min-max: 0-1
      • +
      • Occurrences min-max: 1-1
      • Required attributes: update_factor
      -
      -
      3.11.7.3.1   update_factor¶
      +
      +
      3.10.6.3.1   update_factor¶

      In case of a (temporary) high CPU load, the scheduling behaviour of the operating system might affect the @@ -944,176 +759,53 @@

      3.11.7.3.1   update_factorupdate_factor.

        -
      • Full path: //OpenSplice/Domain/Daemon/Heartbeat/ExpiryTime[@update_factor]
      • +
      • Full path: /Domain/Daemon/Heartbeat/ExpiryTime/update_factor
      • Default value: 0.25
      • -
      • Valid values: 0.1 / 0.9
      • Required: true
      -
      -

      3.11.7.4   StackSize¶

      -
      -
      This element specifies the thread stacksize that will be used by the -Heartbeat thread. By default this is 512 Kb.
      -
        -
      • Full path: //OpenSplice/Domain/Daemon/Heartbeat/StackSize
      • -
      • Format: integer
      • -
      • Dimension: bytes
      • -
      • Default value: 524288
      • -
      • Occurrences min-max: 0-1
      • -
      -
      -
      -
      -

      3.11.8   Tracing¶

      -
      -
      This element controls the amount and type of information that is -written into the tracing log by the Splice Daemon. This is -useful to track the Durability Service during application -development. In the runtime system it should be turned off.
      -
        -
      • Full path: //OpenSplice/Domain/Daemon/Tracing
      • -
      • Occurrences min-max: 0-1
      • -
      • Child elements: OutputFile, Timestamps, Verbosity
      • -
      • Optional attributes: synchronous
      • -
      -
      -

      3.11.8.1   synchronous¶

      -
        -
      • Full path: //OpenSplice/Domain/Daemon/Tracing[@synchronous]
      • -
      • Format: boolean
      • -
      • Default value: FALSE
      • -
      • Required: false
      • -
      -
      -
      -

      3.11.8.2   OutputFile¶

      -
      -
      This option specifies where the logging is printed to. Note that -“stdout” is considered a legal value that represents “standard out” -and “stderr” is a legal value representing “standard error”. -The default value is an empty string, indicating that all tracing -is disabled.
      -
        -
      • Full path: //OpenSplice/Domain/Daemon/Tracing/OutputFile
      • -
      • Format: string
      • -
      • Default value: durability.log
      • -
      • Occurrences min-max: 0-1
      • -
      -
      -
      -

      3.11.8.3   Timestamps¶

      -
      -
      This element specifies whether the logging must contain timestamps.
      -
        -
      • Full path: //OpenSplice/Domain/Daemon/Tracing/Timestamps
      • -
      • Format: boolean
      • -
      • Default value: true
      • -
      • Occurrences min-max: 0-1
      • -
      • Optional attributes: absolute
      • -
      -
      -
      3.11.8.3.1   absolute¶
      -
      -
      This attribute specifies whether the timestamps are absolute or -relative to the startup time of the service.
      -
        -
      • Full path: //OpenSplice/Domain/Daemon/Tracing/Timestamps[@absolute]
      • -
      • Format: boolean
      • -
      • Default value: true
      • -
      • Required: false
      • -
      -
      -
      -
      -

      3.11.8.4   Verbosity¶

      -
      -
      This element specifies the verbosity level of the loggin -information. The higher the level, the more (detailed) -information will be logged.
      -
        -
      • Full path: //OpenSplice/Domain/Daemon/Tracing/Verbosity
      • -
      • Format: enumeration
      • -
      • Default value: INFO
      • -
      • Valid values: SEVERE, WARNING, INFO, CONFIG, FINE, FINER, FINEST
      • -
      • Occurrences min-max: 0-1
      • -
      -
      -

      3.12   Database¶

      +

      3.11   Database¶

      -
      The Database element drives how the administration within the federation is managed. -In federated deployment this administration is managed in a shared memory segment -and in single-process deployment it is managed on heap.
      +
      This element contains information about the nodal administration (shared memory) to be used.
        -
      • Full path: //OpenSplice/Domain/Database
      • +
      • Full path: /Domain/Database
      • Occurrences min-max: 0-1
      • Child elements: Size, Threshold, Address, Locking
      -

      3.12.1   Size¶

      +

      3.11.1   Size¶

      -

      This element specifies the maximum size of the memory segment for maintaining -the nodal administration. The memory management behaviour depends on the deployment mode -(federated vs single-process, driven by the //OpenSplice/Domain/SingleProcess element) -and the size configured within this element:

      -
        -
      • -
        Single process mode In this mode the database is managed on heap.
        -

        If the size is set to zero, the heap is managed by the operating system memory -manager and limited to the operating system limit. If a non-zero size is -configured, the database is still allocated on heap, but the domain service -pre-allocates the entire size at once and will use its own memory manager -to manage this memory segment. The default value in this mode is 0 bytes.

        -
        -
        -
      • -
      • -
        Federated mode In this mode, the database is managed in shared memory segment
        -

        and the domain service will use its own memory manager to manage the -shared memory segment. The default value in this mode is 10 Mbytes.

        -
        -
        -
      • -
      -

      Change this value if your system requires more memory than the default. Please note -that the operating system should be configured support the requested size. -On most platforms you need ‘root’ privileges to set large sizes. -The human-readable option lets the user postfix the value with -K(ilobyte), M(egabyte) or G(igabtye). For example, 10M results in 10485760 bytes.

      -
      +
      This element specifies the size of the shared memory segment holding the database. Change +this value if your system requires more memory than the default. Please note that the +operating system should be configured support the requested size. On most platforms you need +‘root’ privileges to set large sizes.

      -
    • Full path: //OpenSplice/Domain/Database/Size
    • -
    • Dimension: bytes
    • +
    • Full path: /Domain/Database/Size
    • Default value: 10485760
    • -
    • Valid values: 0 / -
    • -
    • Occurrences min-max: 0-1
    • +
    • Occurrences min-max: 1-1
    -

    3.12.2   Threshold¶

    +

    3.11.2   Threshold¶

    This element specifies the threshold size used by OpenSplice DDS. Whenever there is less free shared memory then indicated by the threshold then no new allocations will be allowed within shared memory. Services are allowed to continue allocating shared memory until less then 50% of the threshold value is available. It is strongly discouraged to configure a threshold value of less then the default value, but for some embedded systems it might be needed as -only limited memory is available. -The human-readable option lets the user postfix the value with K(ilobyte), -M(egabyte) or G(igabtye). For example, 10M results in 10485760 bytes.
    +only limited memory is available.
      -
    • Full path: //OpenSplice/Domain/Database/Threshold
    • -
    • Dimension: bytes
    • +
    • Full path: /Domain/Database/Threshold
    • Default value: 1048576
    • -
    • Valid values: 0 / -
    • Occurrences min-max: 0-1
    -
    -

    3.12.4   Locking¶

    +
    +

    3.11.4   Locking¶

    This element specifies the locking policy of the Database, indicating whether to lock pages in physical memory or not.

    @@ -1162,7 +841,7 @@

    3.12.4   Locking -
  • Full path: //OpenSplice/Domain/Database/Locking
  • +
  • Full path: /Domain/Database/Locking
  • Format: enumeration
  • Default value: Default
  • Valid values: True, False, Default
  • @@ -1171,47 +850,40 @@

    3.12.4   Locking -

    3.13   Listeners¶

    +

    3.12   Listeners¶

    This element specifies policies for the thread that services the listeners that the application specifies on the API-level.
      -
    • Full path: //OpenSplice/Domain/Listeners
    • +
    • Full path: /Domain/Listeners
    • Occurrences min-max: 0-1
    • Child elements: StackSize
    -
    -

    3.13.1   StackSize¶

    +
    +

    3.12.1   StackSize¶

    This element specifies the stack size of the listener thread.
      -
    • Full path: //OpenSplice/Domain/Listeners/StackSize
    • +
    • Full path: /Domain/Listeners/StackSize
    • Default value: 128000
    • -
    • Valid values: 64000 / -
    • Occurrences min-max: 1-1
    -

    3.14   Service¶

    +

    3.13   Service¶

    The Domain service is responsible for starting, monitoring and stopping the pluggable services. -One Service element must be specified for every service that needs to be started by the Domain service. -When run in shared memory mode, the Domain Service will start each service as a -new process that will interface directly with the shared memory for DDS -communication. -When run in single process mode, the Domain Service will start each service as a -new thread within the existing process that will have access to the heap memory -for the DDS communication.
    -
      -
    • Full path: //OpenSplice/Domain/Service
    • +One Service element must be specified for every service that needs to be started by the Domain service.

    +
      +
    • Full path: /Domain/Service
    • Occurrences min-max: 0-*
    • Child elements: Command, MemoryPoolSize, HeapSize, StackSize, Configuration, Locking, FailureAction
    • Required attributes: name
    • Optional attributes: enabled
    -
    -

    3.14.1   name¶

    +
    +

    3.13.1   name¶

    This attribute specifies the name by which the corresponding service is identified in the rest of the configuration file.

    @@ -1223,118 +895,96 @@

    3.14.1   name -
  • Full path: //OpenSplice/Domain/Service[@name]
  • +
  • Full path: /Domain/Service/name
  • Format: string
  • Default value: durability
  • Required: true
  • -

    3.14.2   enabled¶

    +

    3.13.2   enabled¶

    This attribute indicates whether the service is actually started or not.

    Toggling a service between enabled and disabled is a quick alternative for commenting out the corresponding lines in the configuration file.

      -
    • Full path: //OpenSplice/Domain/Service[@enabled]
    • +
    • Full path: /Domain/Service/enabled
    • Format: boolean
    • Default value: true
    • Required: false
    -

    3.14.3   Command¶

    +

    3.13.3   Command¶

    This element specifies the command to be executed in order to start the service.

    -

    In shared memory mode, Command element specifies the name of the actual service -executable (possibly including its path, but always including its extension, e.g. -.exe on the Windows platform). When no path is included, the Domain Service -will search the PATH environment variable for the corresponding executable. Once -located, it will be started as a separate process.

    -

    In single process mode, Command is the name of the entry point function to be -invoked and the name of the shared library to be dynamically loaded into the -process. The signature of the entry point function is the same as argc/argv usually -seen with main. The OpenSplice services are implemented in such a way that the -entry point name matches that of the shared library, so (for example) specifying -durability is all that is required.

    +

    OpenSplice DDS comes with a set of pluggable services. The Command element specifies +the name of the actual service executable or a script to launch this service +(possibly including its path, but always including its extension, e.g. ‘.exe’ +on the Windows platform). When no path is included, the Domain Service will search +the PATH environment variable for the corresponding executable. Once located, +it will be started as a separate process.

      -
    • Full path: //OpenSplice/Domain/Service/Command
    • +
    • Full path: /Domain/Service/Command
    • Format: string
    • Default value: durability
    • Occurrences min-max: 1-1
    -

    3.14.4   MemoryPoolSize¶

    +

    3.13.4   MemoryPoolSize¶

    CAUTION: This element should only be used on the GHS Integrity platform!!

    -

    This element maps directly into the integrate file +

    This element maps directly into the integrate file for the address space for this service. Consult the GHS Integrate documentation for further information on this setting. Valid values are decimal or hexadecimal numbers and -they express the number of bytes.

    -

    The default setting for this element is dependent on the service for which it is configured. -0xa00000 for spliced, -0x280000 for durability, -0x280000 for networking, -0x100000 for cmsoap

    -
    +they express the number of bytes.
      -
    • Full path: //OpenSplice/Domain/Service/MemoryPoolSize
    • +
    • Full path: /Domain/Service/MemoryPoolSize
    • Format: string
    • Default value: 0
    • Occurrences min-max: 0-1
    -

    3.14.5   HeapSize¶

    +

    3.13.5   HeapSize¶

    CAUTION: This element should only be used on the GHS Integrity platform!!

    This element maps directly into the integrate file for the address space for this service. Consult the GHS Integrate documentation for further information on this setting. Valid values are decimal or hexadecimal numbers and they express the number of bytes.

    -

    The default setting for this element is dependent on the service for which it is configured. -0x800000 for spliced, -0x240000 for durability, -0x240000 for networking, -0x200000 for cmsoap

      -
    • Full path: //OpenSplice/Domain/Service/HeapSize
    • +
    • Full path: /Domain/Service/HeapSize
    • Format: string
    • Default value: 0
    • Occurrences min-max: 0-1
    -
    -

    3.14.6   StackSize¶

    +
    +

    3.13.6   StackSize¶

    CAUTION: This element should only be used on the GHS Integrity platform!!

    -

    This element maps directly into the integrate file +

    This element maps directly into the integrate file for the address space for this service. Consult the GHS Integrate documentation for further information on this setting. Valid values are decimal or hexadecimal numbers and -they express the number of bytes.

    -

    The default setting for this element is dependent on the service for which it is configured -0x10000 for spliced -0x10000 for durability -0x10000 for networking -0x10000 for cmsoap

    -
    +they express the number of bytes.
      -
    • Full path: //OpenSplice/Domain/Service/StackSize
    • +
    • Full path: /Domain/Service/StackSize
    • Format: string
    • Default value: 0
    • Occurrences min-max: 0-1
    -

    3.14.7   Configuration¶

    +

    3.13.7   Configuration¶

    This element allows overriding of the default URI (specified in the OSPL_URI environment variable, or passed explicitly as command- @@ -1350,26 +1000,26 @@

    3.14.7   Configuration -
  • Full path: //OpenSplice/Domain/Service/Configuration
  • +
  • Full path: /Domain/Service/Configuration
  • Format: string
  • Default value: ${OSPL_URI}
  • Occurrences min-max: 0-1
  • -
    -

    3.14.8   Scheduling¶

    +
    +

    3.13.8   Scheduling¶

    This element specifies the type of OS scheduling class will be used by the Domain service to create the service process. Services can only be started within the scheduling classes that are supported by the underlying operating system.
      -
    • Full path: //OpenSplice/Domain/Service/Scheduling
    • +
    • Full path: /Domain/Service/Scheduling
    • Occurrences min-max: 0-1
    • Child elements: Priority, Class
    -
    -

    3.14.8.1   Priority¶

    +
    +

    3.13.8.1   Priority¶

    This element specifies the thread priority that the Domain Service will assign to the current Service when it is started. Only priorities that @@ -1377,19 +1027,19 @@

    3.14.8.1   Priority -
  • Full path: //OpenSplice/Domain/Service/Scheduling/Priority
  • +
  • Full path: /Domain/Service/Scheduling/Priority
  • Format: integer
  • Default value: 0
  • Occurrences min-max: 1-1
  • Optional attributes: priority_kind
  • -
    -
    3.14.8.1.1   priority_kind¶
    +
    +
    3.13.8.1.1   priority_kind¶
    This attribute specifies whether the specified Priority is a relative or absolute priority.
      -
    • Full path: //OpenSplice/Domain/Service/Scheduling/Priority[@priority_kind]
    • +
    • Full path: /Domain/Service/Scheduling/Priority/priority_kind
    • Format: enumeration
    • Default value: Relative
    • Valid values: Relative, Absolute
    • @@ -1397,8 +1047,8 @@
      3.14.8.1.1   priority_kind
    -
    -

    3.14.8.2   Class¶

    +
    +

    3.13.8.2   Class¶

    This element specifies the thread scheduling class that the Domain Service will assign to the current Service when it is started. @@ -1406,7 +1056,7 @@

    3.14.8.2   Class -
  • Full path: //OpenSplice/Domain/Service/Scheduling/Class
  • +
  • Full path: /Domain/Service/Scheduling/Class
  • Format: enumeration
  • Default value: Default
  • Valid values: Timeshare, Realtime, Default
  • @@ -1414,8 +1064,8 @@

    3.14.8.2   Class -

    3.14.9   Locking¶

    +
    +

    3.13.9   Locking¶

    This element specifies the locking policy of the current Service process, indicating whether pages should be locked in physical memory @@ -1429,14 +1079,14 @@

    3.14.9   Locking -
  • Full path: //OpenSplice/Domain/Service/Locking
  • +
  • Full path: /Domain/Service/Locking
  • Format: boolean
  • Default value: false
  • Occurrences min-max: 0-1
  • -

    3.14.10   FailureAction¶

    +

    3.13.10   FailureAction¶

    This element specifies what action to take at the moment that the service seems to have become non-responsive.

    @@ -1455,7 +1105,7 @@

    3.14.10   FailureAction -
  • Full path: //OpenSplice/Domain/Service/FailureAction
  • +
  • Full path: /Domain/Service/FailureAction
  • Format: enumeration
  • Default value: skip
  • Valid values: kill, restart, skip, systemhalt
  • @@ -1464,51 +1114,47 @@

    3.14.10   FailureAction -

    3.15   Application¶

    +

    3.14   Application¶

    -
    When in the single process deployment mode, the Domain service can deploy +

    When in the single process deployment mode, the Domain service can deploy DDS applications by dynamically loading application shared libraries and -starting threads within the existing process. -A user can add a multiple Application elements to the configuration when they want -to ‘cluster’ multiple DDS applications within an OpenSplice DDS single process. -The entry point and shared library for each Application can be specified by using the -Command and Library elements that are described below.>/p> -Note that Applications only take effect when the single process configuration is enabled by way of the SingleProcess element.

    -
      -
    • Full path: //OpenSplice/Domain/Application
    • +starting threads within the existing process.

      +

      Note that Applications only take effect when the single process configuration is enabled by way of the SingleProcess element.

      +

    +
      +
    • Full path: /Domain/Application
    • Occurrences min-max: 0-*
    • Child elements: Command, Arguments, Library
    • Required attributes: name
    • Optional attributes: enabled
    -
    -

    3.15.1   name¶

    +
    +

    3.14.1   name¶

    -
    This attribute assigns a configuration label to the application, but it is of no further -use; it can have any valid string value
    +
    The name uniquely identifies the application
      -
    • Full path: //OpenSplice/Domain/Application[@name]
    • +
    • Full path: /Domain/Application/name
    • Format: string
    • -
    • Default value: n/a
    • +
    • Default value: application1
    • Required: true
    -
    -

    3.15.2   enabled¶

    +
    +

    3.14.2   enabled¶

    This attribute indicates whether the application is actually started or not.

    Toggling an applicatione between enabled and disabled is a quick alternative for commenting out the corresponding lines in the configuration file.

      -
    • Full path: //OpenSplice/Domain/Application[@enabled]
    • +
    • Full path: /Domain/Application/enabled
    • Format: boolean
    • Default value: true
    • Required: false
    -
    -

    3.15.3   Command¶

    +
    +

    3.14.3   Command¶

    Command is the name of both the entry point function to invoked and the name of the shared library to be dynamically loaded into the process. The signature of the entry @@ -1520,18 +1166,16 @@

    3.15.3   Command -
  • Full path: //OpenSplice/Domain/Application/Command
  • +
  • Full path: /Domain/Application/Command
  • Format: string
  • Default value: application1
  • Occurrences min-max: 1-1
  • -

    3.15.4   Arguments¶

    +

    3.14.4   Arguments¶

    This optional attribute allows the user to specify arguments to be passed to the DDS application’s entry point when it is invoked.

    @@ -1539,13 +1183,13 @@

    3.15.4   Arguments

      -
    • Full path: //OpenSplice/Domain/Application/Arguments
    • +
    • Full path: /Domain/Application/Arguments
    • Format: string
    • Occurrences min-max: 0-1
    -

    3.15.5   Library¶

    +

    3.14.5   Library¶

    This optional attribute allows the user to override the name of the shared library if it is different to the name of the entry point specified by Command.

    @@ -1553,30 +1197,31 @@

    3.15.5   Library -
  • Full path: //OpenSplice/Domain/Application/Library
  • +
  • Full path: /Domain/Application/Library
  • Format: string
  • +
  • Default value: application1
  • Occurrences min-max: 0-1
  • -

    3.16   BuiltinTopics¶

    +

    3.15   BuiltinTopics¶

    This element specifies the granularity of the builtin topics.
      -
    • Full path: //OpenSplice/Domain/BuiltinTopics
    • +
    • Full path: /Domain/BuiltinTopics
    • Occurrences min-max: 0-1
    • Required attributes: enabled
    -
    -

    3.16.1   enabled¶

    +
    +

    3.15.1   enabled¶

    This attribute enables or disables the publication of builtin topics for the existence of individual Participants/DataWriters/DataReaders. The existence of Topics will always be communicated by means of builtin topics, regardless of the value specified here.
      -
    • Full path: //OpenSplice/Domain/BuiltinTopics[@enabled]
    • +
    • Full path: /Domain/BuiltinTopics/enabled
    • Format: boolean
    • Default value: true
    • Required: true
    • @@ -1584,23 +1229,21 @@

      3.16.1   enabled -

      3.17   PriorityInheritance¶

      +

      3.16   PriorityInheritance¶

      This element specifies the usage on Priority Inheritance on Muexes in this domain.
        -
      • Full path: //OpenSplice/Domain/PriorityInheritance
      • +
      • Full path: /Domain/PriorityInheritance
      • Occurrences min-max: 0-1
      • Required attributes: enabled
      -
      -

      3.17.1   enabled¶

      +
      +

      3.16.1   enabled¶

      This attribute enables or disables priority inheritance for mutexes, -if that is supported by the underlying Operating System. -If the parent Element PriorityInheritance is not specified (does not exist), then the -‘default’ value of this attribute is false.
      +if that is supported by the underlying Operating System.
      -
    • Full path: //OpenSplice/Domain/PriorityInheritance[@enabled]
    • +
    • Full path: /Domain/PriorityInheritance/enabled
    • Format: boolean
    • Default value: true
    • Required: true
    • @@ -1608,30 +1251,30 @@

      3.17.1   enabled -

      3.18   Report¶

      +

      3.17   Report¶

      The Report element controls some aspects of the OpenSplice domain logging functionality.
        -
      • Full path: //OpenSplice/Domain/Report
      • +
      • Full path: /Domain/Report
      • Occurrences min-max: 0-1
      • Optional attributes: append, verbosity
      -

      3.18.1   append¶

      +

      3.17.1   append¶

      This attribute determines whether logging for this domain should continue to append to the previous error and info log files when the domain is (re)started or whether the previous file should be deleted and fresh ones created.
        -
      • Full path: //OpenSplice/Domain/Report[@append]
      • +
      • Full path: /Domain/Report/append
      • Format: boolean
      • Default value: true
      • Required: false
      -
      -

      3.18.2   verbosity¶

      +
      +

      3.17.2   verbosity¶

      This attribute determines what level of logging should be in effect for this domain. The levels or logging verbosity are:

      @@ -1652,7 +1295,7 @@

      3.18.2   verbosity -
    • Full path: //OpenSplice/Domain/Report[@verbosity]
    • +
    • Full path: /Domain/Report/verbosity
    • Format: enumeration
    • Default value: INFO
    • Valid values: DEBUG, INFO, WARNING, API_INFO, ERROR, CRITICAL, FATAL, REPAIRED, NONE
    • @@ -1661,44 +1304,44 @@

      3.18.2   verbosity -

      3.19   Statistics¶

      +

      3.18   Statistics¶

      This element specifies the policies regarding statistics. Various statistics can be generated by OpenSplice DDS to help you analyze and tune application behaviour during application development. Since this introduces extra overhead, it is generally turned off in a runtime system.
        -
      • Full path: //OpenSplice/Domain/Statistics
      • +
      • Full path: /Domain/Statistics
      • Occurrences min-max: 0-1
      -

      3.19.1   Category¶

      +

      3.18.1   Category¶

      This element specifies the properties for a particular category of statistics.
        -
      • Full path: //OpenSplice/Domain/Statistics/Category
      • +
      • Full path: /Domain/Statistics/Category
      • Occurrences min-max: 0-*
      • Required attributes: name
      • Optional attributes: enabled
      -
      -

      3.19.1.1   enabled¶

      +
      +

      3.18.1.1   enabled¶

      This attribute enables or disables the generation of statistics for the specified category.
        -
      • Full path: //OpenSplice/Domain/Statistics/Category[@enabled]
      • +
      • Full path: /Domain/Statistics/Category/enabled
      • Format: boolean
      • Default value: true
      • Required: false
      -
      -

      3.19.1.2   name¶

      +
      +

      3.18.1.2   name¶

      This attribute specifies the name of a particular category of statistics.
      -

      3.21   ReportPlugin¶

      +

      3.20   ReportPlugin¶

      This Tag specifies user defined report functionality to be used by the domain. All services and applications will load a user provides @@ -1732,25 +1374,25 @@

      3.21   ReportPlugin

        -
      • Full path: //OpenSplice/Domain/ReportPlugin
      • -
      • Occurrences min-max: 0-*
      • +
      • Full path: /Domain/ReportPlugin
      • +
      • Occurrences min-max: 0-1
      • Child elements: SuppressDefaultLogs, ServicesOnly
      -
      -

      3.21.1   Library¶

      +
      +

      3.20.1   Library¶

      This tag specifies the library to be loaded.
        -
      • Full path: //OpenSplice/Domain/ReportPlugin/Library
      • +
      • Full path: /Domain/ReportPlugin/Library
      • Occurrences min-max: 1-1
      • Required attributes: file_name
      -

      3.21.1.1   file_name¶

      +

      3.20.1.1   file_name¶

      This attribute specifies the library to be loaded.
        -
      • Full path: //OpenSplice/Domain/ReportPlugin/Library[@file_name]
      • +
      • Full path: /Domain/ReportPlugin/Library/file_name
      • Format: string
      • Default value: n/a
      • Required: true
      • @@ -1758,133 +1400,66 @@

        3.21.1.1   file_name

      -

      3.21.2   Initialize¶

      +

      3.20.2   Initialize¶

      This tag specifies the library symbol that will be assigned to the report Initialize operation. This operation will be invoked initially after loading the library to perform initialization of the report facility if needed.
        -
      • Full path: //OpenSplice/Domain/ReportPlugin/Initialize
      • +
      • Full path: /Domain/ReportPlugin/Initialize
      • Occurrences min-max: 1-1
      • Required attributes: symbol_name
      • Optional attributes: argument
      -

      3.21.2.1   symbol_name¶

      +

      3.20.2.1   symbol_name¶

      -

      This attribute specifies the name of the function to be called to initialize the report -plugin. The symbol_name is required, if it is not specified or cannot be resolved, an -error message will be generated and the service will not attempt to resolve other -symbol_names for the report plugin. -The implementation of this function must have the following signature: -int symbol_name (const char *argument, void **context)

      -

      The result value is used to return the status of the call. If it is 0 then the operation -was successful. If it is not 0 then there was an error and details of the error and the -result value are reported to the OpenSplice DDS default report service. -The context parameter is an out reference that can be set to plugin-specific data that -will subsequently be passed to any of the other plugin functions. The value of the -parameter is meaningless to the service

      -
      +
      This attribute specifies the library symbol that will be +assigned to the report Initialize operation. This operation +will be invoked initially after loading the library to +perform initialization of the report facility if needed.

        -
      • Full path: //OpenSplice/Domain/ReportPlugin/Initialize[@symbol_name]
      • +
      • Full path: /Domain/ReportPlugin/Initialize/symbol_name
      • Format: string
      • Default value: n/a
      • Required: true
      -

      3.21.2.2   argument¶

      +

      3.20.2.2   argument¶

      -
      The argument attribute is a string value that is passed to the function specified by the -symbol_name. The string value has no meaning to the service and is used to pass -any context-specific information that may be required. The argument is optional; if -it is not provided then a NULL pointer is passed to the initalize function.
      +
      This attribute is a string value that is passed to the function +specified by the symbol_name. The string value has no meaning +to the service and is used to pass any context-specific +information that may be required.

      -
    • Full path: //OpenSplice/Domain/ReportPlugin/Initialize[@argument]
    • +
    • Full path: /Domain/ReportPlugin/Initialize/argument
    • Format: string
    • Default value: “”
    • Required: false
    -
    -

    3.21.3   Report¶

    +
    +

    3.20.3   Report¶

    This tag specifies the library symbol that will be assigned to the report Report operation. This operation will be invoked on all reports performed by the DDS service.
      -
    • Full path: //OpenSplice/Domain/ReportPlugin/Report
    • +
    • Full path: /Domain/ReportPlugin/Report
    • Occurrences min-max: 0-1
    • Required attributes: symbol_name
    -
    -

    3.21.3.1   symbol_name¶

    -
    -

    This attribute specifies the name of the function to be called to pass report data to -the report plugin. The symbol_name is required; if it is not specified or cannot be -resolved, an error message will be generated and the service will not attempt to -resolve other symbol_names for the report plugin. -The function is invoked slightly differently for applications using the DDS API and -OpenSplice services. OpenSplice services invoke the function once for every report. -For applications using the DDS API the function is invoked once per API call, in -which case the XML is extended by one or more DETAIL elements. -The implementation of this function must have the following signature: -int symbol_name (void *context, const char *report)

    -

    The result value is used to return the status of the call. If it is 0 then the operation -was successful. If it is not 0 then there was an error and details of the error and the -result value are reported to the OpenSplice DDS default report service. -The context parameter is a reference to the plugin-specific data retrieved from the -initialize operation. -The report parameter is an XML string representation of the report data. -Below is an example of the mapping that the XML string representation will use -when invoked by a service:

    -
    -

    <ERROR>

    -

    <DESCRIPTION>The object “my_topic” not found</DESCRIPTION>

    -

    <CONTEXT>c_base::resolve</CONTEXT>

    -

    <FILE>c_base.c</FILE>

    -

    <LINE>1234</LINE>

    -

    <CODE>0</CODE>

    -

    <PROCESS>

    -

    <ID>1234</ID>

    -

    <NAME>ProcessName</NAME>

    -

    </PROCESS>

    -

    <THREAD>

    -

    <ID>1234</ID>

    -

    <NAME>ThreadName</NAME>

    -

    </THREAD>

    -

    <COMMERCIAL>6.5</COMMERCIAL>

    -

    <REVISION>...</REVISION>

    -

    </ERROR>

    -
    -
    Below is an example of the mapping that the XML string representation will use for -applications:
    -

    <ERROR>

    -

    <DESCRIPTION>Operation failed.</DESCRIPTION>

    -

    <CONTEXT>c_base::resolve</CONTEXT>

    -

    <FILE>c_base.c</FILE>

    -

    <LINE>1234</LINE>

    -

    <CODE>0</CODE>

    -

    <PROCESS>

    -

    <ID>1234</ID>

    -

    <NAME>ProcessName</NAME>

    -

    </PROCESS>

    -

    <THREAD>

    -

    <ID>1234</ID>

    -

    <NAME>ThreadName</NAME>

    -

    </THREAD>

    -

    <COMMERCIAL>6.5</COMMERCIAL>

    -

    <REVISION>...</REVISION>

    -

    <DETAIL>

    -

    <REPORT>The object “my_topic” not found.</REPORT>

    -

    <INTERNALS>...</INTERNALS>

    -

    </DETAIL>

    -

    <!– optionally more DETAIL elements –>

    -

    </ERROR>

    -
      -
    • Full path: //OpenSplice/Domain/ReportPlugin/Report[@symbol_name]
    • +
      +

      3.20.3.1   symbol_name¶

      +
      +
      This attribute specifies the library symbol that will be +assigned to the report Report operation. This operation will +be invoked on all reports performed by the DDS service.
      +
        +
      • Full path: /Domain/ReportPlugin/Report/symbol_name
      • Format: string
      • Default value: n/a
      • Required: true
      • @@ -1892,32 +1467,24 @@

        3.21.3.1   symbol_name

      -

      3.21.4   TypedReport¶

      +

      3.20.4   TypedReport¶

      This tag specifies the library symbol that will be assigned to the report TypedReport operation. This operation will be invoked on all reports performed by the DDS service.
        -
      • Full path: //OpenSplice/Domain/ReportPlugin/TypedReport
      • +
      • Full path: /Domain/ReportPlugin/TypedReport
      • Occurrences min-max: 0-1
      • Required attributes: symbol_name
      -
      -

      3.21.4.1   symbol_name¶

      +
      +

      3.20.4.1   symbol_name¶

      -

      This attribute specifies the name of the function to be called to finalize the report -plugin, when the domain unregisters any registered plugin. The symbol_name is -required. If it is not specified or cannot be resolved, an error message will be -generated and the service will not attempt to resolve other symbol_names for the -report plugin. -The implementation of this function must have the following signature: -int symbol_name (void *context)

      -

      The result value is used to return the status of the call. If it is 0 then the operation -was successful. If it is not 0 then there was an error and details of the error and the -result value are reported to the OpenSplice DDS default report service.

      -
      +
      This attribute specifies the library symbol that will be +assigned to the report TypedReport operation. This operation will +be invoked on all reports performed by the DDS service.

      -
    • Full path: //OpenSplice/Domain/ReportPlugin/TypedReport[@symbol_name]
    • +
    • Full path: /Domain/ReportPlugin/TypedReport/symbol_name
    • Format: string
    • Default value: n/a
    • Required: true
    • @@ -1925,34 +1492,26 @@

      3.21.4.1   symbol_name

    -

    3.21.5   Finalize¶

    +

    3.20.5   Finalize¶

    This tag specifies the library symbol that will be assigned to the report Finalize operation. This operation will be invoked upon process termination to perform de-initialization of the report facility if needed.
      -
    • Full path: //OpenSplice/Domain/ReportPlugin/Finalize
    • +
    • Full path: /Domain/ReportPlugin/Finalize
    • Occurrences min-max: 1-1
    • Required attributes: symbol_name
    -
    -

    3.21.5.1   symbol_name¶

    -
    -
    This attribute specifies the name of the function to be called to finalize the report -plugin, when the domain unregisters any registered plugin. The symbol_name is -required. If it is not specified or cannot be resolved, an error message will be -generated and the service will not attempt to resolve other symbol_names for the -report plugin. -The implementation of this function must have the following signature: -int symbol_name (void *context) -The result value is used to return the status of the call. If it is 0 then the operation -was successful. If it is not 0 then there was an error and details of the error and the -result value are reported to the OpenSplice DDS default report service. -The context parameter is a reference to the plugin-specific data retrieved from the -initialize operation.
    -
    -

    3.21.7   ServicesOnly¶

    +

    3.20.7   ServicesOnly¶

    This attribute specifies whether the log plug-in is to be effective only for processes that are exclusively OpenSplice services. If this value is true then the plug-in will not be used for user applications and/or OpenSplice services collocated with user applications in single process mode.
      -
    • Full path: //OpenSplice/Domain/ReportPlugin/ServicesOnly
    • +
    • Full path: /Domain/ReportPlugin/ServicesOnly
    • Format: boolean
    • Default value: false
    • Occurrences min-max: 0-1
    • @@ -1990,80 +1549,78 @@

      3.21.7   ServicesOnly -

      3.22   ResourceLimits¶

      +

      3.21   ResourceLimits¶

      This configuration tag allows for the specification of certain characteristics of resource limits that will be applied throughout the domain
        -
      • Full path: //OpenSplice/Domain/ResourceLimits
      • +
      • Full path: /Domain/ResourceLimits
      • Occurrences min-max: 0-1
      -

      3.22.1   MaxSamples¶

      +

      3.21.1   MaxSamples¶

      This configuration tag allows for the specification of certain characteristics of the max samples resource limit that will be applied throughout the domain
        -
      • Full path: //OpenSplice/Domain/ResourceLimits/MaxSamples
      • +
      • Full path: /Domain/ResourceLimits/MaxSamples
      • Occurrences min-max: 0-1
      • Child elements: WarnAt
      -

      3.22.1.1   WarnAt¶

      +

      3.21.1.1   WarnAt¶

      This element specifies the number of samples that, once reached, will result in a warning message printed in the info log. This is to allow the detection of excessive use of resources within the domain more easily.
        -
      • Full path: //OpenSplice/Domain/ResourceLimits/MaxSamples/WarnAt
      • +
      • Full path: /Domain/ResourceLimits/MaxSamples/WarnAt
      • Default value: 5000
      • -
      • Valid values: 1 / -
      • Occurrences min-max: 0-1
      -

      3.22.2   MaxInstances¶

      +

      3.21.2   MaxInstances¶

      This configuration tag allows for the specification of certain characteristics of the max instances resource limit that will be applied throughout the domain
        -
      • Full path: //OpenSplice/Domain/ResourceLimits/MaxInstances
      • +
      • Full path: /Domain/ResourceLimits/MaxInstances
      • Occurrences min-max: 0-1
      • Child elements: WarnAt
      -
      -

      3.22.2.1   WarnAt¶

      +
      +

      3.21.2.1   WarnAt¶

      This element specifies the number of instances that, once reached, will result in a warning message printed in the info log. This is to allow the detection of excessive use of resources within the domain more easily.
        -
      • Full path: //OpenSplice/Domain/ResourceLimits/MaxInstances/WarnAt
      • +
      • Full path: /Domain/ResourceLimits/MaxInstances/WarnAt
      • Default value: 5000
      • -
      • Valid values: 1 / -
      • Occurrences min-max: 0-1
      -

      3.22.3   MaxSamplesPerInstance¶

      +

      3.21.3   MaxSamplesPerInstance¶

      This configuration tag allows for the specification of certain characteristics of the max samples per instance resource limit that will be applied throughout the domain
        -
      • Full path: //OpenSplice/Domain/ResourceLimits/MaxSamplesPerInstance
      • +
      • Full path: /Domain/ResourceLimits/MaxSamplesPerInstance
      • Occurrences min-max: 0-1
      • Child elements: WarnAt
      -
      -

      3.22.3.1   WarnAt¶

      +
      +

      3.21.3.1   WarnAt¶

      This element specifies the number of samples per instance that, once reached, will result in a warning @@ -2071,35 +1628,25 @@

      3.22.3.1   WarnAt -
    • Full path: //OpenSplice/Domain/ResourceLimits/MaxSamplesPerInstance/WarnAt
    • +
    • Full path: /Domain/ResourceLimits/MaxSamplesPerInstance/WarnAt
    • Default value: 5000
    • -
    • Valid values: 1 / -
    • Occurrences min-max: 0-1
    -

    3.23   PartitionAccess¶

    -
    -
    This element is used to configure the partition access rights. By default all partitions -have read and write access, which means that subscribers and publishers may be -created for all partitions. However by changing the access level of specific partitions -it is possible to prevent publishers and/or subscribers from attaching to these -partitions. The access rights is Domain Service specific, each Domain Service can -have its own policy. -The PartitionAccess element facilitates the configuration of such behavior. This -is done by allowing the definition of a partition expression along with a specific -access mode for the matched partitions. The PartitionAccess element resides as -a child element within the Domain element. The exact definition of the -PartitionAccess element is as follows:
    -
    -

    3.23.2   access_mode¶

    +

    3.22.2   access_mode¶

    -

    This attribute identifies the access level for partitions specified by the -partition_expression attribute. The following values are allowed:

    +

    This attribute specifies the access rights that will be +applied to the specified partitions. The following values +are applicable:

      -
    • read Indicates domain participants can only read from this partition
    • -
    • write Indicates domain participants can only write to this partition
    • -
    • readwrite Indicates domain participants can read from and write to this partition
    • -
    • none Indicates that domain participants have no access on partitions matching the partition_expression.
    • +
    • none
    • +
    • read
    • +
    • write
    • +
    • readwrite
    -

    When multiple expressions overlap each other, the following rules are applied:

    -
    -
    Access mode 1 Access mode 2 Resulting access mode -read write readwrite -read readwrite readwrite -read none none -write readwrite readwrite -write none none -readwrite none none
      -
    • Full path: //OpenSplice/Domain/PartitionAccess[@access_mode]
    • +
    • Full path: /Domain/PartitionAccess/access_mode
    • Format: enumeration
    • Default value: readwrite
    • Valid values: none, read, write, readwrite
    • @@ -2146,74 +1685,64 @@

      3.23.2   access_mode

    -

    3.24   SystemId¶

    +

    3.23   SystemId¶

    This configures the generation of the unique System IDs

      -
    • Full path: //OpenSplice/Domain/SystemId
    • +
    • Full path: /Domain/SystemId
    • Occurrences min-max: 0-1
    • Child elements: UserEntropy
    -

    3.24.1   Range¶

    +

    3.23.1   Range¶

    This configures the range of the generated System IDs

      -
    • Full path: //OpenSplice/Domain/SystemId/Range
    • +
    • Full path: /Domain/SystemId/Range
    • Occurrences min-max: 0-1
    • Optional attributes: min, max
    -

    3.24.1.1   min¶

    +

    3.23.1.1   min¶

    This attribute specifies the minimum allowed System ID. In addition to being within range, it must be less than or equal to the “max” attribute.

      -
    • Full path: //OpenSplice/Domain/SystemId/Range[@min]
    • +
    • Full path: /Domain/SystemId/Range/min
    • Format: integer
    • Default value: 1
    • -
    • Valid values: 1 / 2147483647
    • Required: false
    -

    3.24.1.2   max¶

    +

    3.23.1.2   max¶

    This attribute specifies the maximum allowed System ID. In addition to being within range, it must be greater than or equal to the “min” attribute.

      -
    • Full path: //OpenSplice/Domain/SystemId/Range[@max]
    • +
    • Full path: /Domain/SystemId/Range/max
    • Format: integer
    • Default value: 2147483647
    • -
    • Valid values: 1 / 2147483647
    • Required: false
    -

    3.24.2   UserEntropy¶

    +

    3.23.2   UserEntropy¶

    This attribute specifies a string that is used as an additional source of entropy in the System ID generation. The string is not interpreted.

      -
    • Full path: //OpenSplice/Domain/SystemId/UserEntropy
    • +
    • Full path: /Domain/SystemId/UserEntropy
    • Format: string
    • Occurrences min-max: 0-1
    -

    3.25   TopicAccess¶

    -
    -
    This element is used to configure the topic access rights. By default all topics have -read and write access (built-in topics have a default access mode of read), which -means that datareaders and datawriters may be created for all topics. However by -changing the access level of specific topics it is possible to prevent datawriters -and/or datareaders from being created for these topics. The access rights is Domain -Service specific, each Domain Service can have its own policy. -The TopicAccess element facilitates the configuration of such behavior. This is -done by allowing the definition of a topic expression along with a specific access -mode for the matched topics. -The TopicAccess element resides as a child element within the Domain element
    -
    -
    -

    3.25.2   access_mode¶

    +
    +

    3.24.2   access_mode¶

    This attribute specifies the access rights that will be applied to the specified topics. The following values @@ -2243,7 +1772,7 @@

    3.25.2   access_mode

    -
    -

    3.26   UserClock¶

    +
    +

    3.25   UserClockService¶

    The UserClock Service allows you to plug in a custom clock library, allowing OpenSplice to read the time from an external clock source. It expects a root -element named OpenSplice/Domain/UserClock. Within this root element, +element named OpenSplice/UserClockService. Within this root element, the userclock will look for several child-elements. Each of these is listed and explained.
      -
    • Full path: //OpenSplice/Domain/UserClock
    • +
    • Full path: /Domain/UserClockService
    • Occurrences min-max: 0-1
    • -
    • Child elements: UserClockModule, UserClockStart, UserClockStop, UserClockQuery
    • -
    • Optional attributes: y2038Ready
    • +
    • Child elements: UserClockModule
    • +
    • Required attributes: name
    -
    -

    3.26.1   y2038Ready¶

    -
    -

    This element specifies whether or not the registered user -clock is returning a 64-bit seconds field.

    -

    Default this setting is following the y2038Ready setting on -domain level. (default /domain/y2038Ready is FALSE) -The user is able to make some mixed environments by using this -configuration option. For example a 64-bit user clock can already -be implemented (by setting this option to true) while the node -must be compatible with older versions, -so domain/y2038Ready can not be set. A warning is printed when -the Domain/y2038Ready element is true and the -Domain/UserClock/y2038Ready attribute is false. -The 64-bit layout returned by the userclock must be:

    -
    -

    struct dds_userclock_t {

    +
    +

    3.25.1   name¶

    -

    os_int64 seconds;

    -

    os_int32 nanoseconds;

    -
    -

    };

    -

    See ‘Time stamps and year 2038 limit’ for more background information.

    +
    This attribute identifies the configuration for the UserClock Service. +The value of the name attribute must match the one specified under the +OpenSplice/Domain/Service[@name] in the configuration of the +Domain Service.
      -
    • Full path: //OpenSplice/Domain/UserClock[@y2038Ready]
    • -
    • Format: boolean
    • -
    • Default value: False
    • -
    • Required: false
    • +
    • Full path: /Domain/UserClockService/name
    • +
    • Format: string
    • +
    • Default value: userclock
    • +
    • Required: true
    -

    3.26.2   UserClockModule¶

    +

    3.25.2   UserClockModule¶

    This element specifies the User Clock Service library file. On UNIX like and Windows platforms this will be a shared library. On VxWorks this will be a reallocatable object file. On VxWorks this tag may be empty or discarded if the functions are pre-loaded on the target.
      -
    • Full path: //OpenSplice/Domain/UserClock/UserClockModule
    • +
    • Full path: /Domain/UserClockService/UserClockModule
    • Format: string
    • Occurrences min-max: 1-1
    -

    3.26.3   UserClockStart¶

    +

    3.25.3   UserClockStart¶

    This element specifies if the user clock requires a start function to -be called when the process first creates a participant. -This element specifies the name of the start function. +be called when the process first creates a participant.
    +
      +
    • Full path: /Domain/UserClockService/UserClockStart
    • +
    • Occurrences min-max: 0-1
    • +
    • Required attributes: name
    • +
    +
    +

    3.25.3.1   name¶

    +
    +
    This attribute specifies the name of the start function. This start function should not have any parameters, and needs to return an int that represents 0 if there are no problems, and any other value if a problem is encountered.
      -
    • Full path: //OpenSplice/Domain/UserClock/UserClockStart
    • +
    • Full path: /Domain/UserClockService/UserClockStart/name
    • Format: string
    • Default value: clockStart
    • -
    • Occurrences min-max: 0-1
    • -
    • Required attributes: enabled
    • -
    -
    -

    3.26.3.1   enabled¶

    -
    -
    This attribute specifies if the start function is enabled and should be used.
    -
      -
    • Full path: //OpenSplice/Domain/UserClock/UserClockStart[@enabled]
    • -
    • Format: boolean
    • -
    • Default value: true
    • Required: true
    -

    3.26.4   UserClockStop¶

    +

    3.25.4   UserClockStop¶

    This element specifies if the user clock requires a stop function to -be called when the process deletes the last participant. -This attribute specifies the name of the stop function. This stop +be called when the process deletes the last participant.
    +
      +
    • Full path: /Domain/UserClockService/UserClockStop
    • +
    • Occurrences min-max: 0-1
    • +
    • Required attributes: name
    • +
    +
    +

    3.25.4.1   name¶

    +
    +
    This attribute specifies the name of the stop function. This stop function should not have any parameters, and needs to return an int that represents 0 if there are no problems, and any other value if a problem is encountered.
      -
    • Full path: //OpenSplice/Domain/UserClock/UserClockStop
    • +
    • Full path: /Domain/UserClockService/UserClockStop/name
    • Format: string
    • Default value: clockStop
    • -
    • Occurrences min-max: 0-1
    • -
    • Required attributes: enabled
    • -
    -
    -

    3.26.4.1   enabled¶

    -
    -
    This attribute specifies if the stop function is enabled and should be used.
    -
      -
    • Full path: //OpenSplice/Domain/UserClock/UserClockStop[@enabled]
    • -
    • Format: boolean
    • -
    • Default value: true
    • Required: true
    -

    3.26.5   UserClockQuery¶

    +

    3.25.5   UserClockQuery¶

    +
    +
    This element specifies the clock query function.
    +
      +
    • Full path: /Domain/UserClockService/UserClockQuery
    • +
    • Occurrences min-max: 1-1
    • +
    • Required attributes: name
    • +
    +
    +

    3.25.5.1   name¶

    -

    This element specifies the clock query function. -This attribute specifies the name of the function that gets the +

    This attribute specifies the name of the function that gets the current time. This clockGet function should not have any parameters, and needs to return the current time as an os_time type.

    The definition of the os_time type can be found in os_time.h.

      -
    • Full path: //OpenSplice/Domain/UserClock/UserClockQuery
    • +
    • Full path: /Domain/UserClockService/UserClockQuery/name
    • Format: string
    • Default value: clockGet
    • -
    • Occurrences min-max: 0-1
    • -
    • Required attributes: enabled
    • -
    -
    -

    3.26.5.1   enabled¶

    -
    -
    This attribute specifies if the query function is enabled and should be used.
    -
      -
    • Full path: //OpenSplice/Domain/UserClock/UserClockQuery[@enabled]
    • -
    • Format: boolean
    • -
    • Default value: true
    • -
    • Required: true
    • -
    -
    -
    -
    -
    -

    3.27   DurablePolicies¶

    -
    -

    There are two ways for a late joining reader to retrieve historical -data as a result of calling <tt>wait_for_historical_data()</tt> or -<tt>DDS_wait_for_historical_data()</tt>.

    -
    -
      -
    • -
      The first way is to configure a local durability service
      -

      that is responsible for the alignment of historical data (see -//OpenSplice/DurabilityService). In this case the local durability -service will provide historical data to interested readers -on the local federations.

      -
      -
      -
    • -
    • -
      The second way is NOT to run a local durability service, but
      -

      to request data from a durability service on a remote federation -using the client-durability feature. This makes sense in environments -where running a full-fledged durability service is not possible or -unwanted, e.g., due to resource limitations.

      -
      -
      -
    • -
    -
    -

    The element //OpenSplice/Domain/DurablePolicies specifies how -historical data that is retrieved from a remote durability federation -using the client-durability feature is handled locally. More specifically, -this element allows the user to indicate whether historical data that -is requested by a late joining reader using the client-durability feature -will be made available to the requesting reader only, or to all readers in the -federation. The behaviour can be specified per partition/topic combination -in the //OpenSplice/Domain/DurablePolicies/Policy elements.

    -

    In most situations it is sufficient to either configure a local durability -service to acquire historical data, or to use the client-durability feature, -but not both. However, it is not forbidden to use both methods concurrently. -In that case it is advised to configure the system in such a way that historical -data for a particular partition/topic combination is either provided using -method 1 or 2. In the event that historical data for the same partition/topic -combination can be requested via both methods, methods 1 will be used.

    -
    -
      -
    • Full path: //OpenSplice/Domain/DurablePolicies
    • -
    • Occurrences min-max: 0-1
    • -
    -
    -

    3.27.1   Policy¶

    -
    -

    The policy specifies whether historical data that matches the pattern -specified in the //OpenSplice/Domain/DurablePolicies/Policy[@obtain] -attribute is cached or not. Caching means that the same data is available -for late joining readers on the local federation.

    -

    Multiple policies can be specified. The order of these policies is -important: the first policy that matches (from top to bottom) will -be applied.

    -

    If no policy is specified then the default policy is applied. The -default policy is to deliver requested historical data to all readers.

    -
    -
      -
    • Full path: //OpenSplice/Domain/DurablePolicies/Policy
    • -
    • Occurrences min-max: 0-*
    • -
    • Required attributes: obtain
    • -
    • Optional attributes: cache
    • -
    -
    -

    3.27.1.1   obtain¶

    -
    -
    This element specifies the pattern of the partition/topic for -which the policy must be applied. The default is *.*.
    -
      -
    • Full path: //OpenSplice/Domain/DurablePolicies/Policy[@obtain]
    • -
    • Format: string
    • -
    • Default value: .
    • Required: true
    -
    -

    3.27.1.2   cache¶

    -
    -

    This element specifies whether or not to cache historical data. -If set to TRUE historical data is cached in the local federation -for potential other late joiners in the same federation. In this -case historical data will only be aligned once for the -federation, no matter how many readers are interested. This -saves bandwidth and CPU when more than one readers are expected -with (partly) the same interest. The downside is that caching -historical data will require additional memory even after the -reader has taken all its data. If set to FALSE data is not cached.

    -

    The recommended setting is TRUE when more than one readers -for the data are expected and the cost of extra memory can be afforded. -In all other circumstances FALSE should be used. The default is TRUE.

    -
    -
      -
    • Full path: //OpenSplice/Domain/DurablePolicies/Policy[@cache]
    • -
    • Format: boolean
    • -
    • Default value: True
    • -
    • Required: false
    • -
    -
    -
    -
    -

    3.28   y2038Ready¶

    -
    -

    The y2038Ready element determines that OpenSplice will send timestamps to other nodes -in a 64-bit format which is capable to contain time stamps beyond the year 2038.

    -

    Setting this option to true will force the middleware to communicate with time stamps able to go -beyond 2038. -Other nodes before version 6.7 are not able to handle these new time stamps and will no longer -interact correctly with the node configured with this option.

    -

    From version 6.7 the middleware is internally prepared and calculating with time stamps capable with -timestamps beyond 2038. -From version 6.7 nodes are able to detect the timestamps containing time beyond 2038 and -the older time format. So these nodes will interact correctly with all other nodes. -In a mixed environment containing versions before 6.7, communication must be in the old timestamp format, -so this configuration option can not be set. -In a mixed environment with only versions 6.7 and higher, this configuration option may be set. The -nodes with this configuration will send timestamps capable beyond 2038. All other nodes will be able -to interpret these values correctly.

    -
    -

    See ‘ time stamps and year 2038 limit’ for more background information.

    -
    -
    By default this configuration item is set to false.
    -
      -
    • Full path: //OpenSplice/Domain/y2038Ready
    • -
    • Format: boolean
    • -
    • Default value: false
    • -
    • Occurrences min-max: 0-1
    • -

    4   DurabilityService¶

    -
    The responsibilities of the durability service are to realize the durable properties of -data in an OpenSplice system. The Durability Service looks for its configuration -within the ‘OpenSplice/DurabilityService’ element. The configuration parameters -that the Durability Service will look for within this element are listed and explained -in the following subsections.
    +
    The responsibilities of the durability service are to realize the +durable properties of data in an OpenSplice system.
      -
    • Full path: //OpenSplice/DurabilityService
    • +
    • Full path: /DurabilityService
    • Occurrences min-max: 0-1
    • Required attributes: name
    -
    -

    4.1   name¶

    +
    +

    4.1   name¶

    This attribute identifies the configuration for the Durability service. Multiple Durability service configurations can be specified in one single @@ -2550,7 +1918,7 @@

    4.1   name -
  • Full path: //OpenSplice/DurabilityService[@name]
  • +
  • Full path: /DurabilityService/name
  • Format: string
  • Default value: durability
  • Required: true
  • @@ -2564,26 +1932,20 @@

    4.2   ClientDurability -
  • Full path: //OpenSplice/DurabilityService/ClientDurability
  • +
  • Full path: /DurabilityService/ClientDurability
  • Occurrences min-max: 0-1
  • Optional attributes: enabled
  • -
    -

    4.2.1   enabled¶

    +
    +

    4.2.1   enabled¶

    -
    This attribute enables or disables the ability of the durability service -to respond to requests for historical data from clients. When the -OpenSplice/DurabilityService/ClientDurability[@enabled] attribute -is not provided then it is assumed to be TRUE.
    +
    This attribute enables or disables the client-durability feature.

      -
    • Full path: //OpenSplice/DurabilityService/ClientDurability[@enabled]
    • +
    • Full path: /DurabilityService/ClientDurability/enabled
    • Format: boolean
    • -
    • Default value: TRUE
    • +
    • Default value: False
    • Required: false
    @@ -2595,7 +1957,7 @@

    4.2.2   EntityNames
      -
    • Full path: //OpenSplice/DurabilityService/ClientDurability/EntityNames
    • +
    • Full path: /DurabilityService/ClientDurability/EntityNames
    • Occurrences min-max: 0-1
    • Child elements: Publisher, Subscriber, Partition
    @@ -2604,7 +1966,7 @@

    4.2.2.1   Publisher
    This element specifies the name of the client-durability publisher.

    -
    -

    4.3   Watchdog¶

    +
    +

    4.3   Watchdog¶

    This element controls the characteristics of the Watchdog thread.
      -
    • Full path: //OpenSplice/DurabilityService/Watchdog
    • +
    • Full path: /DurabilityService/Watchdog
    • Occurrences min-max: 0-1
    • Optional attributes: deadlockDetection
    @@ -2655,24 +2017,24 @@

    4.3.1   deadlockDetection -
  • Full path: //OpenSplice/DurabilityService/Watchdog[@deadlockDetection]
  • +
  • Full path: /DurabilityService/Watchdog/deadlockDetection
  • Format: boolean
  • Default value: False
  • Required: false
  • -
    -

    4.3.2   Scheduling¶

    +
    +

    4.3.2   Scheduling¶

    This element specifies the type of OS scheduling class will be used by the thread that announces its liveliness periodically.
      -
    • Full path: //OpenSplice/DurabilityService/Watchdog/Scheduling
    • +
    • Full path: /DurabilityService/Watchdog/Scheduling
    • Occurrences min-max: 1-1
    • Child elements: Priority, Class
    -
    -

    4.3.2.1   Priority¶

    +
    +

    4.3.2.1   Priority¶

    This element specifies the thread priority that will be used by the watchdog thread. Only priorities that are supported by the @@ -2680,19 +2042,19 @@

    4.3.2.1   Priority -
  • Full path: //OpenSplice/DurabilityService/Watchdog/Scheduling/Priority
  • +
  • Full path: /DurabilityService/Watchdog/Scheduling/Priority
  • Format: integer
  • Default value: 0
  • Occurrences min-max: 1-1
  • Optional attributes: priority_kind
  • -
    -
    4.3.2.1.1   priority_kind¶
    +
    +
    4.3.2.1.1   priority_kind¶
    This attribute specifies whether the specified Priority is a relative or absolute priority.
      -
    • Full path: //OpenSplice/DurabilityService/Watchdog/Scheduling/Priority[@priority_kind]
    • +
    • Full path: /DurabilityService/Watchdog/Scheduling/Priority/priority_kind
    • Format: enumeration
    • Default value: Relative
    • Valid values: Relative, Absolute
    • @@ -2700,15 +2062,15 @@
      4.3.2.1.1   priority_kind
    -
    -

    4.3.2.2   Class¶

    +
    +

    4.3.2.2   Class¶

    This element specifies the thread scheduling class that will be used by the watchdog thread. The user may need the appropriate privileges from the underlying operating system to be able to assign some of the privileged scheduling classes.
    -
    -

    4.4.2   transport_priority¶

    + -
    -

    4.4.3   Heartbeat¶

    +
    +

    4.4.3   Heartbeat¶

    During startup and at runtime, the network topology can change dynamically. This happens when OpenSplice services are started/stopped @@ -2796,50 +2152,48 @@

    4.4.3   Heartbeat -
  • Full path: //OpenSplice/DurabilityService/Network/Heartbeat
  • +
  • Full path: /DurabilityService/Network/Heartbeat
  • Occurrences min-max: 0-1
  • Child elements: ExpiryTime
  • Optional attributes: latency_budget, transport_priority
  • -
    -

    4.4.3.1   latency_budget¶

    +
    +

    4.4.3.1   latency_budget¶

    This attribute controls the latency budget QoS setting that is only used by the Durability service for sending its heartbeats. It overrules the value of the DurabilityService/Network[@latency_budget].
      -
    • Full path: //OpenSplice/DurabilityService/Network/Heartbeat[@latency_budget]
    • +
    • Full path: /DurabilityService/Network/Heartbeat/latency_budget
    • Default value: 0.0
    • -
    • Valid values: 0.0 / -
    • Required: false
    -
    -

    4.4.3.2   transport_priority¶

    +
    +

    4.4.3.2   transport_priority¶

    This attribute controls the transport priority QoS setting (in seconds) that is only used by the Durability service for for sending its heartbeats. It overrules the value of the DurabilityService/Network[@transport_priorrity].
      -
    • Full path: //OpenSplice/DurabilityService/Network/Heartbeat[@transport_priority]
    • +
    • Full path: /DurabilityService/Network/Heartbeat/transport_priority
    • Format: integer
    • Default value: 0
    • -
    • Valid values: 0 / -
    • Required: false
    -
    -

    4.4.3.3   Scheduling¶

    +
    +

    4.4.3.3   Scheduling¶

    This element specifies the scheduling parameters used by the thread that periodically sends the heartbeats.
      -
    • Full path: //OpenSplice/DurabilityService/Network/Heartbeat/Scheduling
    • +
    • Full path: /DurabilityService/Network/Heartbeat/Scheduling
    • Occurrences min-max: 0-1
    • Child elements: Priority, Class
    -
    -
    4.4.3.3.1   Priority¶
    +
    +
    4.4.3.3.1   Priority¶
    This element specifies the thread priority that will be used by the thread that periodically sends the heartbeats. Only @@ -2848,19 +2202,19 @@
    4.4.3.3.1   Priority
      -
    • Full path: //OpenSplice/DurabilityService/Network/Heartbeat/Scheduling/Priority
    • +
    • Full path: /DurabilityService/Network/Heartbeat/Scheduling/Priority
    • Format: integer
    • Default value: 0
    • Occurrences min-max: 1-1
    • Optional attributes: priority_kind
    -
    -
    4.4.3.3.1.1   priority_kind¶
    +
    +
    4.4.3.3.1.1   priority_kind¶
    This attribute specifies whether the specified Priority is a relative or absolute priority.
      -
    • Full path: //OpenSplice/DurabilityService/Network/Heartbeat/Scheduling/Priority[@priority_kind]
    • +
    • Full path: /DurabilityService/Network/Heartbeat/Scheduling/Priority/priority_kind
    • Format: enumeration
    • Default value: Relative
    • Valid values: Relative, Absolute
    • @@ -2868,8 +2222,8 @@
      4.4.3.3.1.1   priority_kind
    -
    -
    4.4.3.3.2   Class¶
    +
    +
    4.4.3.3.2   Class¶
    This element specifies the thread scheduling class that will be used by the thread that periodically sends the heartbeats. @@ -2877,7 +2231,7 @@
    4.4.3.3.2   Class -
  • Full path: //OpenSplice/DurabilityService/Network/Heartbeat/Scheduling/Class
  • +
  • Full path: /DurabilityService/Network/Heartbeat/Scheduling/Class
  • Format: enumeration
  • Default value: Default
  • Valid values: Timeshare, Realtime, Default
  • @@ -2885,8 +2239,8 @@
    4.4.3.3.2   Class -

    4.4.3.4   ExpiryTime¶

    +
    +

    4.4.3.4   ExpiryTime¶

    This element specifies the maximum amount of time(in seconds) in which the Durability service expects a new heartbeat of @@ -2900,14 +2254,13 @@

    4.4.3.4   ExpiryTime

      -
    • Full path: //OpenSplice/DurabilityService/Network/Heartbeat/ExpiryTime
    • -
    • Default value: 10.0
    • -
    • Valid values: 0.2 / -
    • +
    • Full path: /DurabilityService/Network/Heartbeat/ExpiryTime
    • +
    • Default value: 4.0
    • Occurrences min-max: 1-1
    • Required attributes: update_factor
    -
    -
    4.4.3.4.1   update_factor¶
    +
    +
    4.4.3.4.1   update_factor¶

    In case of a (temporary) high CPU load, the scheduling behaviour of the operating system might affect the @@ -2921,9 +2274,8 @@

    4.4.3.4.1   update_factorupdate_factor.

      -
    • Full path: //OpenSplice/DurabilityService/Network/Heartbeat/ExpiryTime[@update_factor]
    • -
    • Default value: 0.2
    • -
    • Valid values: 0.1 / 0.9
    • +
    • Full path: /DurabilityService/Network/Heartbeat/ExpiryTime/update_factor
    • +
    • Default value: 0.25
    • Required: true
    @@ -2932,31 +2284,18 @@
    4.4.3.4.1   update_factor

    4.4.4   InitialDiscoveryPeriod¶

    -
    On startup the Durability Service needs to determine, for each namespace, if it has -to align with other Durability Services in the system or if it has to load the initial -state from disk (load persistent data). For this the Durability Service will publish a -request for information and wait for the specified initial discovery period for all -Durability services to respond. The Durability Service will load the persistent data -from disk if no response is received within the specified initial discovery period. -This initial discovery period should be configured greater than the worst case -expected discovery time which is related to underlying hardware, type of network, -network configuration, and expected load. If the initial discovery period is too short -the Durability Service may conclude that there is no running system and load the -data from disk, which will result in conflicting states (‘split-brain syndrome’) i.e. -two separate systems. -The Durabiltiy Service will wait for at least the full initial discovery period before it -can continue and become operational, so for fast startup times it is important to keep -the initial discovery period as small as possible. -.The metaphoric term ‘split-brain syndrome’ is sometimes used to highlight the results of -a temporary outage of communications between two parts of a system. In such a -situation, the states of the disconnected parts evolve separately and become -incompatible, so that by the time communication is restored the system has become -‘schizophrenic’.
    -
      -
    • Full path: //OpenSplice/DurabilityService/Network/InitialDiscoveryPeriod
    • -
    • Dimension: seconds
    • +

      To be able to ensure data consistency of historical data, the +Durability service needs to know which other Durability services +are available in the system. The value of this element determines +the amount of time the Durability service takes at startup to get +acquinted with all other Durability services in the system.

      +

      Increasing the value will increase the startup time of the +Durability service, but is required in larger domains where a lot +of network bandwidth is used.

      +
    +
      +
    • Full path: /DurabilityService/Network/InitialDiscoveryPeriod
    • Default value: 3.0
    • -
    • Valid values: 0.1 / 10.0
    • Occurrences min-max: 0-1
    @@ -2970,27 +2309,26 @@

    4.4.5   Alignment

      -
    • Full path: //OpenSplice/DurabilityService/Network/Alignment
    • +
    • Full path: /DurabilityService/Network/Alignment
    • Occurrences min-max: 0-1
    • Child elements: TimeAlignment, TimeToWaitForAligner
    • Optional attributes: latency_budget, transport_priority
    -
    -

    4.4.5.1   latency_budget¶

    +
    +

    4.4.5.1   latency_budget¶

    This attribute specifies the latency budget QoS setting (in seconds) that is only used by the Durability service for the alignment of data. It overrules the value of the OpenSplice/DurabilityService/Network[@latency_budget].
      -
    • Full path: //OpenSplice/DurabilityService/Network/Alignment[@latency_budget]
    • +
    • Full path: /DurabilityService/Network/Alignment/latency_budget
    • Default value: 0.0
    • -
    • Valid values: 0.0 / -
    • Required: false
    -
    -

    4.4.5.2   transport_priority¶

    +
    +

    4.4.5.2   transport_priority¶

    This attribute specifies the transport priority QoS setting that is used by the Durability service for the alignment of data. @@ -2998,10 +2336,9 @@

    4.4.5.2   transport_priority -
  • Full path: //OpenSplice/DurabilityService/Network/Alignment[@transport_priority]
  • +
  • Full path: /DurabilityService/Network/Alignment/transport_priority
  • Format: integer
  • Default value: 0
  • -
  • Valid values: 0 / -
  • Required: false
  • @@ -3015,7 +2352,7 @@

    4.4.5.3   TimeAlignment -
  • Full path: //OpenSplice/DurabilityService/Network/Alignment/TimeAlignment
  • +
  • Full path: /DurabilityService/Network/Alignment/TimeAlignment
  • Format: boolean
  • Default value: true
  • Occurrences min-max: 0-1
  • @@ -3027,12 +2364,12 @@

    4.4.5.4   AlignerScheduling -
  • Full path: //OpenSplice/DurabilityService/Network/Alignment/AlignerScheduling
  • +
  • Full path: /DurabilityService/Network/Alignment/AlignerScheduling
  • Occurrences min-max: 0-1
  • Child elements: Priority, Class
  • -
    -
    4.4.5.4.1   Priority¶
    +
    +
    4.4.5.4.1   Priority¶
    This element specifies the thread priority that will be used by the aligner thread. Only priorities that are @@ -3041,19 +2378,19 @@
    4.4.5.4.1   Priority
      -
    • Full path: //OpenSplice/DurabilityService/Network/Alignment/AlignerScheduling/Priority
    • +
    • Full path: /DurabilityService/Network/Alignment/AlignerScheduling/Priority
    • Format: integer
    • Default value: 0
    • Occurrences min-max: 1-1
    • Optional attributes: priority_kind
    -
    -
    4.4.5.4.1.1   priority_kind¶
    +
    +
    4.4.5.4.1.1   priority_kind¶
    This attribute specifies whether the specified Priority is a relative or absolute priority.
      -
    • Full path: //OpenSplice/DurabilityService/Network/Alignment/AlignerScheduling/Priority[@priority_kind]
    • +
    • Full path: /DurabilityService/Network/Alignment/AlignerScheduling/Priority/priority_kind
    • Format: enumeration
    • Default value: Relative
    • Valid values: Relative, Absolute
    • @@ -3061,8 +2398,8 @@
      4.4.5.4.1.1   priority_kind
    -
    -
    4.4.5.4.2   Class¶
    +
    +
    4.4.5.4.2   Class¶
    This element specifies the thread scheduling class that will be used by the aligner thread. The user may need the @@ -3070,7 +2407,7 @@
    4.4.5.4.2   Class -
  • Full path: //OpenSplice/DurabilityService/Network/Alignment/AlignerScheduling/Class
  • +
  • Full path: /DurabilityService/Network/Alignment/AlignerScheduling/Class
  • Format: enumeration
  • Default value: Default
  • Valid values: Timeshare, Realtime, Default
  • @@ -3085,12 +2422,12 @@

    4.4.5.5   AligneeScheduling -
  • Full path: //OpenSplice/DurabilityService/Network/Alignment/AligneeScheduling
  • +
  • Full path: /DurabilityService/Network/Alignment/AligneeScheduling
  • Occurrences min-max: 0-1
  • Child elements: Priority, Class
  • -
    -
    4.4.5.5.1   Priority¶
    +
    +
    4.4.5.5.1   Priority¶
    This element specifies the thread priority that will be used by the alignee thread. Only priorities that are @@ -3099,19 +2436,19 @@
    4.4.5.5.1   Priority
      -
    • Full path: //OpenSplice/DurabilityService/Network/Alignment/AligneeScheduling/Priority
    • +
    • Full path: /DurabilityService/Network/Alignment/AligneeScheduling/Priority
    • Format: integer
    • Default value: 0
    • Occurrences min-max: 1-1
    • Optional attributes: priority_kind
    -
    -
    4.4.5.5.1.1   priority_kind¶
    +
    +
    4.4.5.5.1.1   priority_kind¶
    This attribute specifies whether the specified Priority is a relative or absolute priority.
      -
    • Full path: //OpenSplice/DurabilityService/Network/Alignment/AligneeScheduling/Priority[@priority_kind]
    • +
    • Full path: /DurabilityService/Network/Alignment/AligneeScheduling/Priority/priority_kind
    • Format: enumeration
    • Default value: Relative
    • Valid values: Relative, Absolute
    • @@ -3119,8 +2456,8 @@
      4.4.5.5.1.1   priority_kind
    -
    -
    -

    4.4.5.7   Partition¶

    +
    +

    4.4.5.7   Partition¶

    This tag specified an inter durability communication partition with specific qos settings. Alignment between @@ -3211,17 +2546,17 @@

    4.4.5.7   Partition -
  • Full path: //OpenSplice/DurabilityService/Network/Alignment/Partition
  • +
  • Full path: /DurabilityService/Network/Alignment/Partition
  • Occurrences min-max: 0-*
  • Required attributes: Name
  • Optional attributes: alignment_priority, latency_budget, transport_priority
  • -
    -
    4.4.5.7.1   Name¶
    +
    +
    4.4.5.7.1   Name¶
    The name of the partition to use for alignment.
    -
    -
    4.4.5.7.3   latency_budget¶
    +
    +
    4.4.5.7.3   latency_budget¶
    This attribute overrules the latency budget for this partition specified at this point.
      -
    • Full path: //OpenSplice/DurabilityService/Network/Alignment/Partition[@latency_budget]
    • +
    • Full path: /DurabilityService/Network/Alignment/Partition/latency_budget
    • Default value: 0.0
    • -
    • Valid values: 0.0 / -
    • Required: false
    -
    -
    4.4.5.7.4   transport_priority¶
    +
    +
    4.4.5.7.4   transport_priority¶
    This attribute overrules the transport priority for this partition specified at this point.
      -
    • Full path: //OpenSplice/DurabilityService/Network/Alignment/Partition[@transport_priority]
    • +
    • Full path: /DurabilityService/Network/Alignment/Partition/transport_priority
    • Format: integer
    • Default value: 0
    • -
    • Valid values: 0 / -
    • Required: false
    @@ -3272,25 +2604,14 @@
    4.4.5.7.4   transport_priority

    4.4.5.8   TimeToWaitForAligner¶

    -
    When all Durability Services in the domain have configured their aligner element -as false , none of them is able -to act as an aligner for newly-started Durability Services. Therefore late-joining -Durability Services will not be able to obtain historical data that is available in the -domain. -This element specifies the period (in seconds) to wait until an aligner becomes -available in the domain. If an aligner does not become available within the period -specified by this element, the entire federation will terminate and return with error -code 1 (recoverable error). -Currently only values between 0.0 and 1.0 are supported, and all non-zero values -are interpreted as infinite (so basically the time-out is currently either zero or -infinite). The default is 1.0. Note that when the element aligner -is set to true the current Durability Service is able to act as aligner for -other Durability Services with respect to the specified namespace and the federation -will not terminate.
    -
      -
    • Full path: //OpenSplice/DurabilityService/Network/Alignment/TimeToWaitForAligner
    • +
      The period (in seconds) to wait until an aligner is available in the domain. +If an aligner does not become available within this period the entire federation +will terminate and returns with error code 1 (recoverable error). Currently only +values between 0.0 and 1.0 are supported, and all non-zero values are interpreted +as infinite.

    +
      +
    • Full path: /DurabilityService/Network/Alignment/TimeToWaitForAligner
    • Default value: 1.0
    • -
    • Valid values: 0.0 / 1.0
    • Occurrences min-max: 0-1
    @@ -3305,7 +2626,7 @@

    4.4.6   WaitForAttachment -
  • Full path: //OpenSplice/DurabilityService/Network/WaitForAttachment
  • +
  • Full path: /DurabilityService/Network/WaitForAttachment
  • Occurrences min-max: 0-1
  • Child elements: ServiceName
  • Optional attributes: maxWaitCount
  • @@ -3316,30 +2637,28 @@

    4.4.6.1   maxWaitCount -
  • Full path: //OpenSplice/DurabilityService/Network/WaitForAttachment[@maxWaitCount]
  • +
  • Full path: /DurabilityService/Network/WaitForAttachment/maxWaitCount
  • Format: integer
  • Default value: 200
  • -
  • Valid values: 1 / 1000
  • Required: false
  • 4.4.6.2   ServiceName¶

    -
    This element specifies the name of the service(s) that the Durability Service waits -for, before starting alignment activities for a specific topic-partition combination. If -(for example) the communication between Durability Services is dependent on the -availability of certain local Network Services, then the Durability Service must wait -until these are operational.
    +
    This element specifies the name of the service(s) that the +Durability service waits for, before starting alignment activities +for a specific topic-partition combination. In a multinode +environment the name of the Networking service MUST be included +here to assure a proper functioning of the Durability service.

      -
    • Full path: //OpenSplice/DurabilityService/Network/WaitForAttachment/ServiceName
    • +
    • Full path: /DurabilityService/Network/WaitForAttachment/ServiceName
    • Format: string
    • Default value: networking
    • Occurrences min-max: 1-*
    • @@ -3362,9 +2681,9 @@

      4.5   Persistent

      -
    • Full path: //OpenSplice/DurabilityService/Persistent
    • +
    • Full path: /DurabilityService/Persistent
    • Occurrences min-max: 0-1
    • -
    • Child elements: StoreDirectory, StoreSessionTime, StoreSleepTime, StoreMode, StoreOptimizeInterval, QueueSize
    • +
    • Child elements: StoreDirectory, StoreSessionTime, StoreSleepTime, StoreMode, StoreOptimizeInterval
    • Optional attributes: SmpCount
    @@ -3374,7 +2693,7 @@

    4.5.1   StoreDirectory -
  • Full path: //OpenSplice/DurabilityService/Persistent/StoreDirectory
  • +
  • Full path: /DurabilityService/Persistent/StoreDirectory
  • Format: string
  • Default value: /tmp/pstore
  • Occurrences min-max: 1-1
  • @@ -3383,16 +2702,12 @@

    4.5.1   StoreDirectory

    4.5.2   StoreSessionTime¶

    -
    The Durability Service has a persistency thread that periodically (in sessions) writes -persistent data to disk, this element together with the Element StoreSleepTime can be -used to optimize disk access. This element specifies the maximum session time (in -seconds) for the persistency thread. After this period of time, it makes sure data is -flushed to disk
    +
    This element specifies the maximum session time (in seconds) +for the persistency thread. After this period of time, it makes +sure data is flushed to disk.

      -
    • Full path: //OpenSplice/DurabilityService/Persistent/StoreSessionTime
    • -
    • Dimension: seconds
    • +
    • Full path: /DurabilityService/Persistent/StoreSessionTime
    • Default value: 20.0
    • -
    • Valid values: 0.001 / 60.0
    • Occurrences min-max: 0-1
    @@ -3408,28 +2723,24 @@

    4.5.3   StoreSleepTime -
  • Full path: //OpenSplice/DurabilityService/Persistent/StoreSleepTime
  • +
  • Full path: /DurabilityService/Persistent/StoreSleepTime
  • Default value: 0.0
  • -
  • Valid values: 0.0 / 10.0
  • Occurrences min-max: 0-1
  • 4.5.4   StoreMode¶

    -

    This element specifies the plug-in that is used to store the +

    This element specifies the plug-in that is used to store the persistent data on disk. With “XML” mode, the service will store persistent data in XML files. With “MMF”, the service will store persistent data in a Memory Mapped File that exactly represents the memory that is being used by the persistent store. With “KV” mode the service will store persistent data in a key-value store using either sqlite of leveldb to store the data on disk. -!!! The “MMF” store is deprecated from version 6.3 and was only implemented on linux !!!,

    -

    !!! For “KV” stores, SQLite is supported on linux, Windows, and Solaris; LevelDB is only -supported on linux.

    -
    +!!! The “MMF” store is currently only implemented on linux !!!
      -
    • Full path: //OpenSplice/DurabilityService/Persistent/StoreMode
    • +
    • Full path: /DurabilityService/Persistent/StoreMode
    • Format: enumeration
    • Default value: XML
    • Valid values: XML, MMF, KV
    • @@ -3439,19 +2750,13 @@

      4.5.4   StoreMode

      4.5.5   SmpCount¶

      -
      This element determines how many threads the Durability service will spawn to -write persistent data to disk. Note that this attribute is currently only supported for -MMF (memory mapped file) StoreMode. -Please also note that although technically the maximum valid value for this element -is maxInt, the operating system may impose a lower limit, to prevent ‘runaway’ -consumption of resources and loss of performance. It is recommended that increases -of this value are carefully considered! -!!! The “MMF” store is deprecated from version 6.3 and was only implemented on linux !!!,
      +
      This element determines how many threads the durability +service will spawn to persist data to disk. Currently only supported for MMF +(memory mapped file) storemode.
        -
      • Full path: //OpenSplice/DurabilityService/Persistent[@SmpCount]
      • +
      • Full path: /DurabilityService/Persistent/SmpCount
      • Format: integer
      • Default value: 1
      • -
      • Valid values: 1 / -
      • Required: false

    @@ -3463,10 +2768,9 @@

    4.5.6   KeyValueStore -
  • Full path: //OpenSplice/DurabilityService/Persistent/KeyValueStore
  • +
  • Full path: /DurabilityService/Persistent/KeyValueStore
  • Occurrences min-max: 0-1
  • Child elements: StorageParameters
  • Required attributes: type
  • @@ -3474,76 +2778,27 @@

    4.5.6   KeyValueStore

    4.5.6.1   type¶

    -
    This attribute specifies the third-party product that is used to implement the KV store. -Products currently supported are SQLite and LevelDB
    +
    This attribute specifies the specific storage product used to implement the key-value store.
      -
    • Full path: //OpenSplice/DurabilityService/Persistent/KeyValueStore[@type]
    • +
    • Full path: /DurabilityService/Persistent/KeyValueStore/type
    • Format: enumeration
    • Default value: sqlite3
    • -
    • Valid values: sqlite3, sqlite, leveldb
    • +
    • Valid values: sqlite3, leveldb
    • Required: true

    4.5.6.2   StorageParameters¶

    -

    This element is used to set parameters that are specific to the third-party product -used to implement the KV store. The element consists of a list of parameters which -are separated by semicolons (‘;’). Each parameter is either a single name or a -key-value pair where the key and the value are separated by a ‘=’ character. -Invalid or ‘not recognized’ values are ignored. -* When SQLite is selected as KV store implementation, refer to the Sqlite -documentation for full details of the available parameters (see -http://www.sqlite.org/pragma.html). The only exceptions are the parameters that -the KV store uses itself, which are: locking_mode, journal_mode, -wal_autocheckpoint and synchronous.

    -

    * When LevelDB is selected as the KV store the following parameters are available -(the information below has been taken from the current LevelDB -documentation the project home page is at http://code.google.com/p/leveldb/)

    -

    paranoid_checks - boolean

    -
    -
    -
    If true, the implementation will do aggressive checking of the data it is
    -

    processing and it will stop early if it detects any errors. This may have -unforeseen ramifications: for example, a corruption of one database entry may -cause a large number of entries to become unreadable or for the entire database -to become unopenable. -Default: false

    -

    write_buffer_size - integer

    -
    -
    Amount of data to build up in memory (backed by an unsorted log on disk)
    -

    before converting to a sorted on-disk file. Larger values improve performance, -especially during bulk loads. Up to two write buffers may be held in memory at -the same time, so you may wish to adjust this parameter to control memory -usage. Also, a larger write buffer will result in a longer recovery time the next -time the database is opened. -Default: 4MB

    -

    max_open_files - integer

    -
    -
    Number of open files that can be used by the database. You may need to
    -

    increase this if your database has a large working set (budget one open file per -2MB of working set). -Default: 1000

    -

    block_size - integer

    -
    -
    Approximate size of user data packed per block. Note that the block size
    -

    specified here corresponds to uncompressed data. The actual size of the unit -read from disk may be smaller if compression is enabled. This parameter can be -changed dynamically. -Set by the KV store to 1M.

    -

    verify_checksums - boolean

    -
    -
    If true, all data read from underlying storage will be verified against
    -

    corresponding checksums. -Default: false

    -

    fill_cache - boolean

    -
    -
    Should the data read for this iteration be cached in memory? Callers may wish
    -
    to set this field to false for bulk scans. -Default: true
    -
    +
    This element specifies the configuration settings of the used storage implementation. +These configuration parameters are specific to the used storage which are documented +in the storage specific documentation. The configuration parameters are transparently +passed to the used storage. The StorageParameters consists of a list of configuration +items where each item is seperated by a ‘;’. Dependent on the storage an item can be +a single name or a name-value pair. In case of a name-value pair the name and the value +are seperated by an ‘=’ character (name = value).
      -
    • Full path: //OpenSplice/DurabilityService/Persistent/KeyValueStore/Compression[@algorithm]
    • +
    • Full path: /DurabilityService/Persistent/KeyValueStore/Compression/algorithm
    • Format: enumeration
    • Default value: lzf
    • Valid values: lzf, snappy, zlib
    • Required: true
    -
    -
    4.5.6.3.2   enabled¶
    +
    +
    4.5.6.3.2   enabled¶
    This attribute specifies whether the key-value store will apply compression for storing persistent data to limit disk usage.
      -
    • Full path: //OpenSplice/DurabilityService/Persistent/KeyValueStore/Compression[@enabled]
    • +
    • Full path: /DurabilityService/Persistent/KeyValueStore/Compression/enabled
    • Format: boolean
    • Default value: true
    • Required: false
    • @@ -3601,16 +2856,14 @@
      4.5.6.3.2   enabled¶
      This element specifies the memory mapped file store mode parameters. This -element is only valid when the Persistent/StoreMode element is set to “MMF”. -The size and the starting address of the memory file must be supplied -The “MMF” store is deprecated from version 6.3. and was only implemented in Linux
      +element is only valid when the Persistent/StoreMode element is set to “MMF”.
      -
    • Full path: //OpenSplice/DurabilityService/Persistent/MemoryMappedFileStore
    • +
    • Full path: /DurabilityService/Persistent/MemoryMappedFileStore
    • Occurrences min-max: 0-1
    • Child elements: Size, Address
    -
    -

    4.5.7.1   Size¶

    +
    +

    4.5.7.1   Size¶

    This element specifies the size of the memory mapped file used to store persistent data. Change this value according to the size of @@ -3628,14 +2881,13 @@

    4.5.7.1   Size -
  • Full path: //OpenSplice/DurabilityService/Persistent/MemoryMappedFileStore/Size
  • +
  • Full path: /DurabilityService/Persistent/MemoryMappedFileStore/Size
  • Default value: 10485760
  • -
  • Valid values: 1048576 / -
  • Occurrences min-max: 0-1
  • -
    -

    4.5.7.2   Address¶

    +
    +

    4.5.7.2   Address¶

    This element specifies the start address where the file is mapped into the virtual memory. @@ -3648,7 +2900,7 @@

    4.5.7.2   Address -
  • Full path: //OpenSplice/DurabilityService/Persistent/MemoryMappedFileStore/Address
  • +
  • Full path: /DurabilityService/Persistent/MemoryMappedFileStore/Address
  • Format: string
  • Default value: 0x80000000
  • Occurrences min-max: 0-1
  • @@ -3658,33 +2910,29 @@

    4.5.7.2   Address

    4.5.8   StoreOptimizeInterval¶

    -
    This element determines after how many write actions the persistent set for a -specific partition-topic combination is optimized on disk. Persistent data is -sequentially written to disk without removing data that according to key values and -history policies can be removed. During a store optimize action the Durability -Service will rewrite the file and thereby remove all disposable data. Note that a long -interval will minimize the induced mean load but instead increases burst load.
    +
    This element determines after how many write actions the +persistent set for a specific partition-topic combination +is optimized on disk.

      -
    • Full path: //OpenSplice/DurabilityService/Persistent/StoreOptimizeInterval
    • +
    • Full path: /DurabilityService/Persistent/StoreOptimizeInterval
    • Format: integer
    • Default value: 0
    • -
    • Valid values: 0 / 1000000000
    • Occurrences min-max: 0-1
    -
    -

    4.5.9   Scheduling¶

    +
    +

    4.5.9   Scheduling¶

    This element specifies the scheduling parameters used to control the thread that stores persistent data on permanent storage.
      -
    • Full path: //OpenSplice/DurabilityService/Persistent/Scheduling
    • +
    • Full path: /DurabilityService/Persistent/Scheduling
    • Occurrences min-max: 0-1
    • Child elements: Priority, Class
    -
    -

    4.5.9.1   Priority¶

    +
    +

    4.5.9.1   Priority¶

    This element specifies the thread priority that will be used by the persistent thread. Only priorities that are supported by the @@ -3692,19 +2940,19 @@

    4.5.9.1   Priority -
  • Full path: //OpenSplice/DurabilityService/Persistent/Scheduling/Priority
  • +
  • Full path: /DurabilityService/Persistent/Scheduling/Priority
  • Format: integer
  • Default value: 0
  • Occurrences min-max: 1-1
  • Optional attributes: priority_kind
  • -
    -
    4.5.9.1.1   priority_kind¶
    +
    +
    4.5.9.1.1   priority_kind¶
    This attribute specifies whether the specified Priority is a relative or absolute priority.
      -
    • Full path: //OpenSplice/DurabilityService/Persistent/Scheduling/Priority[@priority_kind]
    • +
    • Full path: /DurabilityService/Persistent/Scheduling/Priority/priority_kind
    • Format: enumeration
    • Default value: Relative
    • Valid values: Relative, Absolute
    • @@ -3712,15 +2960,15 @@
      4.5.9.1.1   priority_kind
    -
    -

    4.5.9.2   Class¶

    +
    +

    4.5.9.2   Class¶

    This element specifies the thread scheduling class that will be used by the persistent thread. The user may need the appropriate privileges from the underlying operating system to be able to assign some of the privileged scheduling classes.
      -
    • Full path: //OpenSplice/DurabilityService/Persistent/Scheduling/Class
    • +
    • Full path: /DurabilityService/Persistent/Scheduling/Class
    • Format: enumeration
    • Default value: Default
    • Valid values: Timeshare, Realtime, Default
    • @@ -3732,34 +2980,15 @@

      4.5.9.2   Class

      4.6   NameSpaces¶

      -
      When a durability service wants to fulfill a particular role for some of the -namespaces in a domain, it must have some way of deducing the desired behavior -for those when encountered. For static, small-scale systems this can easily be solved -by statically configurating this role-behavior for all relevant namespaces for each -durability service in the domain. -In dynamic, large scale environments, the updating and maintaining of -configurations for each durability service when new namespaces enter the domain -can become quite cumbersome. Dynamic namespaces offer a solution for this -problem. -Instead of specifying each namespace seperately, dynamic namespaces introduce -the concept of namespace policies. A policy defines a generic role for the durability -service, together with a namespace expression. This expression can contain -wildcards, and is used to match against each namespace the durability service -encounters in a domain. The first policy with a matching expression is then applied -to the new namespace. -Specifying policies -Policies are specified in a fall-through manner, which means that the first (top) -policy to match a namespace is applied. Policies specify a range of options for -namespaces, which tell the durability service how to handle the data. -The following items can be configured: -* Durability -* Alignee -* Aligner -In the dynamic namespace configuration, the NameSpace element (a child of the -NameSpaces element) only supports a name attribute, which is mandatory. This -name will be used to match against policies.
      -
        -
      • Full path: //OpenSplice/DurabilityService/NameSpaces
      • +
        Scalability of durable data is an issue in large systems. Keeping +all historical data on each node may not be feasible. Often nodes are +interested in a small part of the total system data, on one hand +driven by application interest, on the other hand driven by +fault-tolerance (the need for replicates). This setting controls +which historical data is managed by this Durability service +(both transient and persistent).

    +
      +
    • Full path: /DurabilityService/NameSpaces
    • Occurrences min-max: 1-1
    @@ -3773,25 +3002,26 @@

    4.6.1   NameSpace

      -
    • Full path: //OpenSplice/DurabilityService/NameSpaces/NameSpace
    • +
    • Full path: /DurabilityService/NameSpaces/NameSpace
    • Occurrences min-max: 1-*
    • Child elements: Partition, PartitionTopic
    • -
    • Optional attributes: name, durabilityKind, alignmentKind, mergePolicy
    • +
    • Required attributes: name
    -
    -

    4.6.1.1   name¶

    +
    +

    4.6.1.1   name¶

    This element specifies the name for a namespace. A name is used to match a namespace with a policy.
      -
    • Full path: //OpenSplice/DurabilityService/NameSpaces/NameSpace[@name]
    • +
    • Full path: /DurabilityService/NameSpaces/NameSpace/name
    • Format: string
    • Default value: defaultNameSpace
    • -
    • Required: false
    • +
    • Occurrences min-max: 1-1
    • +
    • Required: true
    -
    -

    4.6.1.2   Partition¶

    + -
    -

    4.6.2   Policy¶

    +
    +

    4.6.2   Policy¶

    A namespace describes a dependency between data in two or more partitions by means of a partition expression. The @@ -3850,8 +3080,8 @@

    4.6.2   Policy -
  • Full path: //OpenSplice/DurabilityService/NameSpaces/Policy
  • -
  • Occurrences min-max: 0-*
  • +
  • Full path: /DurabilityService/NameSpaces/Policy
  • +
  • Occurrences min-max: 1-*
  • Required attributes: nameSpace, durability, aligner, alignee
  • Optional attributes: delayedAlignment, equalityCheck
  • @@ -3887,39 +3117,14 @@

    4.6.2.1   Merge -
  • Full path: //OpenSplice/DurabilityService/NameSpaces/Policy/Merge
  • +
  • Full path: /DurabilityService/NameSpaces/Policy/Merge
  • Occurrences min-max: 0-*
  • Required attributes: type, scope
  • -
    -
    4.6.2.1.1   type¶
    -
    -

    The type attribute describes the kind of action required on a namespace state mismatch.

    -
      -
    • Ignore: Do nothing in case of a state mismatch. No samples are aligned, and -namespace states will not be updated.
    • -
    • Merge: Merge historical data from other namespace state. This will result in a -new namespace state for the durability service that specifies this value.
    • -
    • Delete: Dispose and delete historical data in case of a state mismatch. -Immediately after successful completion of the Delete merge action no transient -or persistent data will be available for late-joining readers, and all data in the -reader queue of existing readers will be disposed.
    • -
    • Replace: Dispose and delete historical data in case of a state mismatch, and merge -data from another namespace state. This will result in a new namespace state for -the durability service that specifies this value. Immediately after successful -completion of the Replace merge action the replacement data will be available to -late-joining readers, the data in the reader queue of existing readers will be -disposed and replaced with the replacement data, and the generation count of the -replacement data is increased.
    • -
    • Catchup: When a state mismatch occurs, instances that do not exist any more are -disposed, and instances that have been added or changed are updated. Instances -for which no state mismatch occurs are left untouched. Immediately after -successful completion of the Catchup merge action the data will be available to -existing readers and late-joining readers.
    • -
    -
    -
      -
    • Full path: //OpenSplice/DurabilityService/NameSpaces/Policy/Merge[@type]
    • +
      +
      4.6.2.1.1   type¶
      +
        +
      • Full path: /DurabilityService/NameSpaces/Policy/Merge/type
      • Format: enumeration
      • Default value: Ignore
      • Valid values: Ignore, Merge, Delete, Replace, Catchup
      • @@ -3928,29 +3133,22 @@
        4.6.2.1.1   type
        4.6.2.1.2   scope¶
        -
        -
        The scope attribute describes for which scope the merge policy is valid. The scope -is a role-expression in which wildcards (‘*’ and ‘?’) are allowed. Roles are matched -at runtime against this expression to determine which policy applies for that role. -When a role doesn’t match any policy, ‘Ignore’ is assumed. The order of -specifying policies is important: the first scope expression that matches a role is -selected for that role.
          -
        • Full path: //OpenSplice/DurabilityService/NameSpaces/Policy/Merge[@scope]
        • +
        • Full path: /DurabilityService/NameSpaces/Policy/Merge/scope
        • Format: string
        • Default value: *
        • Required: true
    -
    -

    4.6.2.2   nameSpace¶

    +
    +

    4.6.2.2   nameSpace¶

    The element specifies an expression that matches a namespace name. A namespace may contain the wildcards ‘*’ to match any number of characters and ‘?’ to match one single character.
      -
    • Full path: //OpenSplice/DurabilityService/NameSpaces/Policy[@nameSpace]
    • +
    • Full path: /DurabilityService/NameSpaces/Policy/nameSpace
    • Format: string
    • Default value: *
    • Required: true
    • @@ -3982,7 +3180,7 @@

      4.6.2.3   durability

    -
    -
    4.6.3.1.2   PartitionTopic¶
    +
    +
    4.6.3.1.2   PartitionTopic¶
    This element specifies the partition-topics to which the filter expression is applied. A partition-topic expression may contain the wildcards ‘*’ to match any number of characters and ‘?’ to match one single character.
      -
    • Full path: //OpenSplice/DurabilityService/NameSpaces/Filters/Filter/PartitionTopic
    • +
    • Full path: /DurabilityService/NameSpaces/Filters/Filter/PartitionTopic
    • Format: string
    • Default value: .
    • Occurrences min-max: 0-*
    • @@ -4150,66 +3349,66 @@
      4.6.3.1.2   PartitionTopic
    -
    -

    4.7   EntityNames¶

    +
    +

    4.7   EntityNames¶

    This element specifies the names of the various entities used by the DurabilityService. The names specified here will be displayed in the OpenSplice DDS Tuner when viewing the DurabilityService.
      -
    • Full path: //OpenSplice/DurabilityService/EntityNames
    • +
    • Full path: /DurabilityService/EntityNames
    • Occurrences min-max: 0-1
    • Child elements: Publisher, Subscriber, Partition
    -
    -

    4.7.1   Publisher¶

    +
    +

    4.7.1   Publisher¶

    This element specifies the name of the durability publisher.
      -
    • Full path: //OpenSplice/DurabilityService/EntityNames/Publisher
    • +
    • Full path: /DurabilityService/EntityNames/Publisher
    • Format: string
    • Default value: durabilityPublisher
    • Occurrences min-max: 0-1
    -
    -

    4.7.2   Subscriber¶

    +
    +

    4.7.2   Subscriber¶

    This element specifies the name of the durability subscriber.
      -
    • Full path: //OpenSplice/DurabilityService/EntityNames/Subscriber
    • +
    • Full path: /DurabilityService/EntityNames/Subscriber
    • Format: string
    • Default value: durabilitySubscriber
    • Occurrences min-max: 0-1
    -
    -

    4.7.3   Partition¶

    +
    +

    4.7.3   Partition¶

    This element specifies the name of the durability partition.
      -
    • Full path: //OpenSplice/DurabilityService/EntityNames/Partition
    • +
    • Full path: /DurabilityService/EntityNames/Partition
    • Format: string
    • Default value: durabilityPartition
    • Occurrences min-max: 0-1
    -
    -

    4.8   Tracing¶

    +
    +

    4.8   Tracing¶

    This element controls the amount and type of information that is written into the tracing log by the Durability Service. This is useful to track the Durability Service during application development. In the runtime system it should be turned off.
      -
    • Full path: //OpenSplice/DurabilityService/Tracing
    • +
    • Full path: /DurabilityService/Tracing
    • Occurrences min-max: 0-1
    • Child elements: OutputFile, Timestamps, Verbosity
    • Optional attributes: synchronous
    -
    -

    4.8.1   synchronous¶

    +
    +

    4.8.1   synchronous¶

    This attribute specifies whether tracing log updates are synchronous or not. A synchronous update is immediately flushed to disk: there is @@ -4217,14 +3416,14 @@

    4.8.1   synchronous

      -
    • Full path: //OpenSplice/DurabilityService/Tracing[@synchronous]
    • +
    • Full path: /DurabilityService/Tracing/synchronous
    • Format: boolean
    • Default value: FALSE
    • Required: false
    -
    -

    4.8.2   OutputFile¶

    +
    +

    4.8.2   OutputFile¶

    This option specifies where the logging is printed to. Note that “stdout” is considered a legal value that represents “standard out” @@ -4232,44 +3431,44 @@

    4.8.2   OutputFile -
  • Full path: //OpenSplice/DurabilityService/Tracing/OutputFile
  • +
  • Full path: /DurabilityService/Tracing/OutputFile
  • Format: string
  • Default value: durability.log
  • Occurrences min-max: 0-1
  • -
    -

    4.8.3   Timestamps¶

    +
    +

    4.8.3   Timestamps¶

    This element specifies whether the logging must contain timestamps.
      -
    • Full path: //OpenSplice/DurabilityService/Tracing/Timestamps
    • +
    • Full path: /DurabilityService/Tracing/Timestamps
    • Format: boolean
    • Default value: true
    • Occurrences min-max: 0-1
    • Optional attributes: absolute
    -
    -

    4.8.3.1   absolute¶

    +
    +

    4.8.3.1   absolute¶

    This attribute specifies whether the timestamps are absolute or relative to the startup time of the service.
      -
    • Full path: //OpenSplice/DurabilityService/Tracing/Timestamps[@absolute]
    • +
    • Full path: /DurabilityService/Tracing/Timestamps/absolute
    • Format: boolean
    • Default value: true
    • Required: false
    -
    -

    4.8.4   Verbosity¶

    +
    +

    4.8.4   Verbosity¶

    This element specifies the verbosity level of the logging information. The higher the level, the more (detailed) information will be logged.
    -
    -

    5.1   name¶

    +
    +

    5.1   name¶

    This attribute identifies the configuration for the Secure Networking service. Multiple Network service configurations can be specified in one single @@ -4307,32 +3506,32 @@

    5.1   name -
  • Full path: //OpenSplice/SNetworkService[@name]
  • +
  • Full path: /SNetworkService/name
  • Format: string
  • Default value: snetworking
  • Required: true
  • -
    -

    5.2   Watchdog¶

    +
    +

    5.2   Watchdog¶

    This element controls the characteristics of the Watchdog thread.
      -
    • Full path: //OpenSplice/SNetworkService/Watchdog
    • +
    • Full path: /SNetworkService/Watchdog
    • Occurrences min-max: 0-1
    -
    -

    5.2.1   Scheduling¶

    +
    +

    5.2.1   Scheduling¶

    This element specifies the type of OS scheduling class will be used by the thread that announces its liveliness periodically.
      -
    • Full path: //OpenSplice/SNetworkService/Watchdog/Scheduling
    • +
    • Full path: /SNetworkService/Watchdog/Scheduling
    • Occurrences min-max: 1-1
    • Child elements: Priority, Class
    -
    -

    5.2.1.1   Priority¶

    +
    +

    5.2.1.1   Priority¶

    This element specifies the thread priority that will be used by the watchdog thread. Only priorities that are supported by the @@ -4340,19 +3539,19 @@

    5.2.1.1   Priority -
  • Full path: //OpenSplice/SNetworkService/Watchdog/Scheduling/Priority
  • +
  • Full path: /SNetworkService/Watchdog/Scheduling/Priority
  • Format: integer
  • Default value: 0
  • Occurrences min-max: 1-1
  • Optional attributes: priority_kind
  • -
    -
    5.2.1.1.1   priority_kind¶
    +
    +
    5.2.1.1.1   priority_kind¶
    This attribute specifies whether the specified Priority is a relative or absolute priority.
      -
    • Full path: //OpenSplice/SNetworkService/Watchdog/Scheduling/Priority[@priority_kind]
    • +
    • Full path: /SNetworkService/Watchdog/Scheduling/Priority/priority_kind
    • Format: enumeration
    • Default value: Relative
    • Valid values: Relative, Absolute
    • @@ -4360,15 +3559,15 @@
      5.2.1.1.1   priority_kind
    -
    -

    5.2.1.2   Class¶

    +
    +

    5.2.1.2   Class¶

    This element specifies the thread scheduling class that will be used by the watchdog thread. The user may need the appropriate privileges from the underlying operating system to be able to assign some of the privileged scheduling classes.
    @@ -4398,7 +3597,7 @@

    5.3.1   NetworkInterfaceAddress -
  • Full path: //OpenSplice/SNetworkService/General/NetworkInterfaceAddress
  • +
  • Full path: /SNetworkService/General/NetworkInterfaceAddress
  • Format: string
  • Default value: first available
  • Occurrences min-max: 0-1
  • @@ -4416,7 +3615,7 @@

    5.3.1.1   forced -
  • Full path: //OpenSplice/SNetworkService/General/NetworkInterfaceAddress[@forced]
  • +
  • Full path: /SNetworkService/General/NetworkInterfaceAddress/forced
  • Format: boolean
  • Default value: false
  • Required: false
  • @@ -4440,7 +3639,7 @@

    5.3.1.2   ipv6 -
  • Full path: //OpenSplice/SNetworkService/General/NetworkInterfaceAddress[@ipv6]
  • +
  • Full path: /SNetworkService/General/NetworkInterfaceAddress/ipv6
  • Format: boolean
  • Default value: false
  • Required: false
  • @@ -4459,7 +3658,7 @@

    5.3.1.3   bind -
  • Full path: //OpenSplice/SNetworkService/General/NetworkInterfaceAddress[@bind]
  • +
  • Full path: /SNetworkService/General/NetworkInterfaceAddress/bind
  • Format: enumeration
  • Default value: any
  • Valid values: any, strict
  • @@ -4482,7 +3681,7 @@

    5.3.1.4   allowReuse

    @@ -4552,7 +3751,7 @@

    5.3.4.1   allowed

      -
    • Full path: //OpenSplice/SNetworkService/Partitioning
    • +
    • Full path: /SNetworkService/Partitioning
    • Occurrences min-max: 0-1
    @@ -4596,13 +3795,13 @@

    5.4.1   GlobalPartition -
  • Full path: //OpenSplice/SNetworkService/Partitioning/GlobalPartition
  • +
  • Full path: /SNetworkService/Partitioning/GlobalPartition
  • Occurrences min-max: 0-1
  • Required attributes: Address
  • Optional attributes: SecurityProfile, MulticastTimeToLive
  • -
    -

    5.4.1.1   Address¶

    +
    +

    5.4.1.1   Address¶

    The global networking partition transports data that is either meant @@ -4618,7 +3817,7 @@

    5.4.1.1   Address -
  • Full path: //OpenSplice/SNetworkService/Partitioning/GlobalPartition[@Address]
  • +
  • Full path: /SNetworkService/Partitioning/GlobalPartition/Address
  • Format: string
  • Default value: broadcast
  • Required: true
  • @@ -4636,7 +3835,7 @@

    5.4.1.2   SecurityProfile -
  • Full path: //OpenSplice/SNetworkService/Partitioning/GlobalPartition[@SecurityProfile]
  • +
  • Full path: /SNetworkService/Partitioning/GlobalPartition/SecurityProfile
  • Format: string
  • Default value: nullProfile
  • Required: false
  • @@ -4644,13 +3843,10 @@

    5.4.1.2   SecurityProfile

    5.4.1.3   MulticastTimeToLive¶

    -

    For each UDP packet sent out, The TimeToLive header value is set to this value for Multicast packets. -By specifying a value of ‘0’, multicast traffic can be confined to the local node, and -such ‘loopback’ performance is typically optimized by the operating system.

    +

    For each UDP packet sent out, The TimeToLive header value is set to this value for Multicast packets.

      -
    • Full path: //OpenSplice/SNetworkService/Partitioning/GlobalPartition[@MulticastTimeToLive]
    • +
    • Full path: /SNetworkService/Partitioning/GlobalPartition/MulticastTimeToLive
    • Default value: 32
    • -
    • Valid values: 0 / 255
    • Required: false

    @@ -4661,7 +3857,7 @@

    5.4.2   NetworkPartitions -
  • Full path: //OpenSplice/SNetworkService/Partitioning/NetworkPartitions
  • +
  • Full path: /SNetworkService/Partitioning/NetworkPartitions
  • Occurrences min-max: 0-1
    • -
    • Full path: //OpenSplice/SNetworkService/Partitioning/NetworkPartitions/NetworkPartition[@Name]
    • +
    • Full path: /SNetworkService/Partitioning/NetworkPartitions/NetworkPartition/Name
    • Format: string
    • Default value: networkPartition
    • Required: false
    -
    -
    5.4.2.1.2   Address¶
    -

    The address is a list of one or more unicast, multicast or broadcast addresses. If -more than one address is specified, then the different addresses should separated by -commas (,) semicolons (;) or spaces ( ). Samples for this partition will be sent to -all addresses that are specified in this list of addresses. To specify the default -broadcast address, use the expression “broadcast”. Addresses can be entered as -‘dotted decimal’ IPv4 or ‘colon-separated hexadecimal’ IPv6 notation or as the -symbolic hostname, in which case OpenSplice will try to resolve the corresponding -IP address.

    -
    -
    -
    5.4.2.1.4   Compression¶
    +
    +
    5.4.2.1.4   Compression¶

    This attribute specifies if networking will apply compression to limit bandwidth for a specific network partition. This provides great flexibility as network @@ -4740,14 +3938,14 @@

    5.4.2.1.4   Compression
      -
    • Full path: //OpenSplice/SNetworkService/Partitioning/NetworkPartitions/NetworkPartition[@Compression]
    • +
    • Full path: /SNetworkService/Partitioning/NetworkPartitions/NetworkPartition/Compression
    • Format: boolean
    • Default value: false
    • Required: false
    -
    -
    5.4.2.1.5   SecurityProfile¶
    +
    +
    5.4.2.1.5   SecurityProfile¶
    In the context of secure networking, the NetworkPartition element provides support for the attribute SecurityProfile. The attribute is referencing a security @@ -4764,21 +3962,18 @@
    5.4.2.1.5   SecurityProfile -
  • Full path: //OpenSplice/SNetworkService/Partitioning/NetworkPartitions/NetworkPartition[@SecurityProfile]
  • +
  • Full path: /SNetworkService/Partitioning/NetworkPartitions/NetworkPartition/SecurityProfile
  • Format: string
  • Default value: nullProfile
  • Required: false
  • -
    -
    5.4.2.1.6   MulticastTimeToLive¶
    -

    For each UDP packet sent out, The TimeToLive header value is set to this value for Multicast packets. -By specifying a value of ‘0’, multicast traffic can be confined to the local node, and -such ‘loopback’ performance is typically optimized by the operating system

    +
    +
    5.4.2.1.6   MulticastTimeToLive¶
    +

    For each UDP packet sent out, The TimeToLive header value is set to this value for Multicast packets.

      -
    • Full path: //OpenSplice/SNetworkService/Partitioning/NetworkPartitions/NetworkPartition[@MulticastTimeToLive]
    • +
    • Full path: /SNetworkService/Partitioning/NetworkPartitions/NetworkPartition/MulticastTimeToLive
    • Default value: 32
    • -
    • Valid values: 0 / 255
    • Required: false
    @@ -4789,7 +3984,7 @@

    5.4.3   IgnoredPartitions -
  • Full path: //OpenSplice/SNetworkService/Partitioning/IgnoredPartitions
  • +
  • Full path: /SNetworkService/Partitioning/IgnoredPartitions
  • Occurrences min-max: 0-1
  • @@ -4800,7 +3995,7 @@

    5.4.3.1   IgnoredPartition -
  • Full path: //OpenSplice/SNetworkService/Partitioning/IgnoredPartitions/IgnoredPartition
  • +
  • Full path: /SNetworkService/Partitioning/IgnoredPartitions/IgnoredPartition
  • Occurrences min-max: 1-*
  • Required attributes: DCPSPartitionTopic
  • @@ -4815,7 +4010,7 @@
    5.4.3.1.1   DCPSPartitionTopic -
  • Full path: //OpenSplice/SNetworkService/Partitioning/IgnoredPartitions/IgnoredPartition[@DCPSPartitionTopic]
  • +
  • Full path: /SNetworkService/Partitioning/IgnoredPartitions/IgnoredPartition/DCPSPartitionTopic
  • Format: string
  • Default value: .
  • Required: true
  • @@ -4828,7 +4023,7 @@

    5.4.4   PartitionMappings -
  • Full path: //OpenSplice/SNetworkService/Partitioning/PartitionMappings
  • +
  • Full path: /SNetworkService/Partitioning/PartitionMappings
  • Occurrences min-max: 0-1
  • @@ -4842,26 +4037,26 @@

    5.4.4.1   PartitionMapping -
  • Full path: //OpenSplice/SNetworkService/Partitioning/PartitionMappings/PartitionMapping
  • +
  • Full path: /SNetworkService/Partitioning/PartitionMappings/PartitionMapping
  • Occurrences min-max: 1-*
  • Required attributes: NetworkPartition, DCPSPartitionTopic
  • -
    -
    5.4.4.1.1   NetworkPartition¶
    +
    +
    5.4.4.1.1   NetworkPartition¶
    The NetworkPartition attribute of a partition mapping defines that networking partitition that data in a specific DCPS partition of a specific DCPS topic should be sent to.
      -
    • Full path: //OpenSplice/SNetworkService/Partitioning/PartitionMappings/PartitionMapping[@NetworkPartition]
    • +
    • Full path: /SNetworkService/Partitioning/PartitionMappings/PartitionMapping/NetworkPartition
    • Format: string
    • Default value: networkPartition
    • Required: true
    -
    -
    5.4.4.1.2   DCPSPartitionTopic¶
    +
    +
    5.4.4.1.2   DCPSPartitionTopic¶
    The Networking service will match any DCPS messages to the DCPSPartitionTopic expression and determine @@ -4874,7 +4069,7 @@
    5.4.4.1.2   DCPSPartitionTopic -
  • Full path: //OpenSplice/SNetworkService/Partitioning/PartitionMappings/PartitionMapping[@DCPSPartitionTopic]
  • +
  • Full path: /SNetworkService/Partitioning/PartitionMappings/PartitionMapping/DCPSPartitionTopic
  • Format: string
  • Default value: .
  • Required: true
  • @@ -4893,12 +4088,12 @@

    5.5   Security -
  • Full path: //OpenSplice/SNetworkService/Security
  • +
  • Full path: /SNetworkService/Security
  • Occurrences min-max: 0-1
  • Optional attributes: enabled
  • -
    -

    5.5.1   enabled¶

    +
    +

    5.5.1   enabled¶

    This is an optional attribute. If not defined it defaults to true and all network partitions, if not specified otherwise, will be encoded using the NULL cipher. The @@ -4909,30 +4104,30 @@

    5.5.1   enabled -
  • Full path: //OpenSplice/SNetworkService/Security[@enabled]
  • +
  • Full path: /SNetworkService/Security/enabled
  • Format: boolean
  • Default value: false
  • Required: false
  • -
    -

    5.5.2   SecurityProfile¶

    +
    +

    5.5.2   SecurityProfile¶

    This element defines the security profile which can be applied to one or more network partitions. This element is optional.
      -
    • Full path: //OpenSplice/SNetworkService/Security/SecurityProfile
    • +
    • Full path: /SNetworkService/Security/SecurityProfile
    • Occurrences min-max: 0-*
    • Required attributes: Name, Cipher, CipherKey
    -
    -

    5.5.2.1   Name¶

    +
    +

    5.5.2.1   Name¶

    This is a mandatory attribute. The name must be unique for all Security Profiles being declared. If the name is not specified, the security profile will be ignored as it cannot be referenced anyway.
    -
    -

    5.5.3.1   enabled¶

    +
    +

    5.5.3.1   enabled¶

    The access control feature will be activated when enabled=”true”
      -
    • Full path: //OpenSplice/SNetworkService/Security/AccessControl[@enabled]
    • +
    • Full path: /SNetworkService/Security/AccessControl/enabled
    • Format: boolean
    • Default value: false
    • Required: false
    -
    -

    5.5.3.2   policy¶

    +
    +

    5.5.3.2   policy¶

    The policy attribute references a file containing the access control policy.
    -
    -
    5.5.3.3.1   enabled¶
    +
    +
    5.5.3.3.1   enabled¶
    The module specified in the type attribute is used to evaluate access control rules when enabled=”true”.
      -
    • Full path: //OpenSplice/SNetworkService/Security/AccessControl/AccessControlModule[@enabled]
    • +
    • Full path: /SNetworkService/Security/AccessControl/AccessControlModule/enabled
    • Format: boolean
    • Default value: true
    • Required: false
    -
    -
    5.5.3.3.2   type¶
    +
    +
    5.5.3.3.2   type¶
    The type attribute defines the access control model type. Currently, OpenSplice only supports mandatory access control, accordingly the only valid value for this attribute is “MAC”.
    -
    -

    5.5.4.1   enabled¶

    +
    +

    5.5.4.1   enabled¶

    Authentication is performed when enabled is set to true.
    @@ -5103,7 +4298,7 @@
    5.5.4.2.1   Credentials -
  • Full path: //OpenSplice/SNetworkService/Security/Authentication/X509Authentication/Credentials
  • +
  • Full path: /SNetworkService/Security/Authentication/X509Authentication/Credentials
  • Occurrences min-max: 0-1
  • Child elements: Key, Cert
  • @@ -5116,7 +4311,7 @@
    5.5.4.2.1.1   Key -
  • Full path: //OpenSplice/SNetworkService/Security/Authentication/X509Authentication/Credentials/Key
  • +
  • Full path: /SNetworkService/Security/Authentication/X509Authentication/Credentials/Key
  • Format: string
  • Occurrences min-max: 1-1
  • @@ -5130,7 +4325,7 @@
    5.5.4.2.1.2   Cert -
  • Full path: //OpenSplice/SNetworkService/Security/Authentication/X509Authentication/Credentials/Cert
  • +
  • Full path: /SNetworkService/Security/Authentication/X509Authentication/Credentials/Cert
  • Format: string
  • Occurrences min-max: 1-1
  • @@ -5145,7 +4340,7 @@
    5.5.4.2.2   TrustedCertificates -
  • Full path: //OpenSplice/SNetworkService/Security/Authentication/X509Authentication/TrustedCertificates
  • +
  • Full path: /SNetworkService/Security/Authentication/X509Authentication/TrustedCertificates
  • Format: string
  • Occurrences min-max: 1-1
  • @@ -5165,7 +4360,7 @@

    5.6   Channels -
  • Full path: //OpenSplice/SNetworkService/Channels
  • +
  • Full path: /SNetworkService/Channels
  • Occurrences min-max: 1-1
  • Child elements: AllowedPorts
  • @@ -5181,18 +4376,18 @@

    5.6.1   Channel -
  • Full path: //OpenSplice/SNetworkService/Channels/Channel
  • +
  • Full path: /SNetworkService/Channels/Channel
  • Occurrences min-max: 1-42
  • Child elements: PortNr, FragmentSize, Resolution, AdminQueueSize, CompressionBufferSize, CompressionThreshold, AllowedPorts
  • Required attributes: name, reliable, enabled
  • Optional attributes: default, priority
  • -
    -

    5.6.1.1   name¶

    +
    +

    5.6.1.1   name¶

    The name uniquely identifies the channel.
      -
    • Full path: //OpenSplice/SNetworkService/Channels/Channel[@name]
    • +
    • Full path: /SNetworkService/Channels/Channel/name
    • Format: string
    • Default value: aChannel
    • Required: true
    • @@ -5210,7 +4405,7 @@

      5.6.1.2   reliable

      -
    • Full path: //OpenSplice/SNetworkService/Channels/Channel[@default]
    • +
    • Full path: /SNetworkService/Channels/Channel/default
    • Format: boolean
    • Default value: false
    • Required: false
    -
    -

    5.6.1.4   enabled¶

    +
    +

    5.6.1.4   enabled¶

    This attribute toggles a channel on or off. Toggling a channel between enabled and disabled is a quick alternative for commenting out the corresponding lines in the configuration file.
      -
    • Full path: //OpenSplice/SNetworkService/Channels/Channel[@enabled]
    • +
    • Full path: /SNetworkService/Channels/Channel/enabled
    • Format: boolean
    • Default value: false
    • Required: true
    -
      -
    • Full path: //OpenSplice/SNetworkService/Channels/Channel/Resolution
    • -
    • Format: unsigned int
    • -
    • Dimension: milliseconds
    • +
    • Full path: /SNetworkService/Channels/Channel/Resolution
    • +
    • Format: integer
    • Default value: 10
    • -
    • Valid values: 1 / -
    • Occurrences min-max: 0-1
    @@ -5333,10 +4520,9 @@

    5.6.1.9   AdminQueueSize -
  • Full path: //OpenSplice/SNetworkService/Channels/Channel/AdminQueueSize
  • +
  • Full path: /SNetworkService/Channels/Channel/AdminQueueSize
  • Format: integer
  • Default value: 4000
  • -
  • Valid values: 400 / -
  • Occurrences min-max: 0-1
  • @@ -5349,10 +4535,9 @@

    5.6.1.10   CompressionBufferSize -
  • Full path: //OpenSplice/SNetworkService/Channels/Channel/CompressionBufferSize
  • +
  • Full path: /SNetworkService/Channels/Channel/CompressionBufferSize
  • Format: integer
  • Default value: 131072
  • -
  • Valid values: 65536 / -
  • Occurrences min-max: 0-1
  • @@ -5363,10 +4548,9 @@

    5.6.1.11   CompressionThreshold -
  • Full path: //OpenSplice/SNetworkService/Channels/Channel/CompressionThreshold
  • +
  • Full path: /SNetworkService/Channels/Channel/CompressionThreshold
  • Format: integer
  • Default value: 0
  • -
  • Valid values: 0 / -
  • Occurrences min-max: 0-1
  • @@ -5376,7 +4560,7 @@

    5.6.1.12   SendingThis element describes all properties for the transmitting side of the Channel.

      -
    • Full path: //OpenSplice/SNetworkService/Channels/Channel/Sending
    • +
    • Full path: /SNetworkService/Channels/Channel/Sending
    • Occurrences min-max: 0-1
    • Child elements: CrcCheck, QueueSize, MaxBurstSize, ThrottleLimit, ThrottleThreshold, MaxRetries, RecoveryFactor, DiffServField, DontRoute, TimeToLive
    @@ -5390,7 +4574,7 @@
    5.6.1.12.1   CrcCheckWhen the sending side is enabled the network packet will contain a valid crc field.

    @@ -5419,14 +4602,10 @@
    5.6.1.12.3   MaxBurstSize -
  • Full path: //OpenSplice/SNetworkService/Channels/Channel/Sending/MaxBurstSize
  • -
  • Dimension: bytes/(resolution interval)
  • +
  • Full path: /SNetworkService/Channels/Channel/Sending/MaxBurstSize
  • Default value: 1073741823
  • -
  • Valid values: 1024 / 1073741823
  • Occurrences min-max: 0-1
  • @@ -5439,14 +4618,10 @@
    5.6.1.12.4   ThrottleLimit -
  • Full path: //OpenSplice/SNetworkService/Channels/Channel/Sending/ThrottleLimit
  • -
  • Dimension: bytes/(resolution interval)
  • +
  • Full path: /SNetworkService/Channels/Channel/Sending/ThrottleLimit
  • Default value: 10240
  • -
  • Valid values: - / 4294967295
  • Occurrences min-max: 0-1
  • @@ -5461,45 +4636,31 @@
    5.6.1.12.5   ThrottleThreshold -
  • Full path: //OpenSplice/SNetworkService/Channels/Channel/Sending/ThrottleThreshold
  • +
  • Full path: /SNetworkService/Channels/Channel/Sending/ThrottleThreshold
  • Format: integer
  • -
  • Dimension: fragments
  • Default value: 50
  • -
  • Valid values: 2 / -
  • Occurrences min-max: 0-1
  • 5.6.1.12.6   MaxRetries¶
    -

    This element is only applicable for reliable channels. -A reliable channel implements a reliability protocol in which it builds a list of -connected remote services. This protocol expects all connected services to -acknowledge messages within a specific period of time, otherwise messages will be -resent. This element specifies the number of retransmissions the service has to -execute before considering that the addressed service has become unresponsive. -When this happens the remote service will be removed from the reliability protocol -and the channel will no longer expect messages to be acknowledged.

    +
    +
    The number of retransmissions the service has to execute before considering the addressed node +as not responding.
      -
    • Full path: //OpenSplice/SNetworkService/Channels/Channel/Sending/MaxRetries
    • +
    • Full path: /SNetworkService/Channels/Channel/Sending/MaxRetries
    • Format: integer
    • Default value: 100
    • -
    • Valid values: 1 / -
    • Occurrences min-max: 0-1
    5.6.1.12.7   RecoveryFactor¶
    -

    A reliable channel implements a reliability protocol in which it builds a list of -connected remote services. This protocol expects all connected services to -acknowledge messages within a specific period of time otherwise messages will be -resent. The expected period of time is specified by this attribute as the number of -resolution ticks. (See also Section 4.4.1.5.1.9, Element Resolution, on page 218.) -The lost message is resent after Resolution * RecoveryFactor milliseconds.

    +

    A lost message is resent after Resolution * RecoveryFactor milliseconds.

      -
    • Full path: //OpenSplice/SNetworkService/Channels/Channel/Sending/RecoveryFactor
    • +
    • Full path: /SNetworkService/Channels/Channel/Sending/RecoveryFactor
    • Format: integer
    • Default value: 3
    • -
    • Valid values: 2 / -
    • Occurrences min-max: 0-1
    @@ -5520,10 +4681,9 @@
    5.6.1.12.8   DiffServField -
  • Full path: //OpenSplice/SNetworkService/Channels/Channel/Sending/DiffServField
  • +
  • Full path: /SNetworkService/Channels/Channel/Sending/DiffServField
  • Format: integer
  • Default value: 0
  • -
  • Valid values: 0 / 255
  • Occurrences min-max: 0-1
  • @@ -5534,7 +4694,7 @@
    5.6.1.12.9   DontRoutesocket option is set to the value specified.
    -
    -
    5.6.1.12.11   Scheduling¶
    +
    +
    5.6.1.12.11   Scheduling¶
    This element specifies the scheduling policies used to control the transmitter thread of the current Channel.
      -
    • Full path: //OpenSplice/SNetworkService/Channels/Channel/Sending/Scheduling
    • +
    • Full path: /SNetworkService/Channels/Channel/Sending/Scheduling
    • Occurrences min-max: 0-1
    • Child elements: Priority, Class
    -
    -
    5.6.1.12.11.1   Priority¶
    +
    +
    5.6.1.12.11.1   Priority¶
    This element specifies the thread priority that will be used by the transmitter thread. Only priorities that are supported by the underlying operating system can be assigned to this element. The user may need special privileges from the underlying operating system to be able to assign some of the privileged priorities.
      -
    • Full path: //OpenSplice/SNetworkService/Channels/Channel/Sending/Scheduling/Priority
    • +
    • Full path: /SNetworkService/Channels/Channel/Sending/Scheduling/Priority
    • Format: integer
    • Default value: 0
    • Occurrences min-max: 1-1
    • Optional attributes: priority_kind
    -
    -5.6.1.12.11.1.1   priority_kind¶ +
    +5.6.1.12.11.1.1   priority_kind¶
    This attribute specifies whether the specified Priority is a relative or absolute priority.
      -
    • Full path: //OpenSplice/SNetworkService/Channels/Channel/Sending/Scheduling/Priority[@priority_kind]
    • +
    • Full path: /SNetworkService/Channels/Channel/Sending/Scheduling/Priority/priority_kind
    • Format: enumeration
    • Default value: Relative
    • Valid values: Relative, Absolute
    • @@ -5593,14 +4752,14 @@
      5.6.1.12.11.1   Priority
    -
    -
    5.6.1.12.11.2   Class¶
    +
    +
    5.6.1.12.11.2   Class¶
    This element specifies the thread scheduling class that will be used by the transmitter thread. The user may need the appropriate privileges from the underlying operating system to be able to assign some of the privileged scheduling classes.
      -
    • Full path: //OpenSplice/SNetworkService/Channels/Channel/Receiving
    • +
    • Full path: /SNetworkService/Channels/Channel/Receiving
    • Occurrences min-max: 0-1
    • Child elements: CrcCheck, ReceiveBufferSize, DefragBufferSize, MaxReliabBacklog, PacketRetentionPeriod, ReliabilityRecoveryPeriod
    -
    -
    5.6.1.13.1   CrcCheck¶
    + -
    -
    5.6.1.13.3   Scheduling¶
    +
    +
    5.6.1.13.3   Scheduling¶
    This element specifies the scheduling policies used to control the receiver thread of the current Channel.
      -
    • Full path: //OpenSplice/SNetworkService/Channels/Channel/Receiving/Scheduling
    • +
    • Full path: /SNetworkService/Channels/Channel/Receiving/Scheduling
    • Occurrences min-max: 0-1
    • Child elements: Priority, Class
    -
    -
    5.6.1.13.3.1   Priority¶
    +
    +
    5.6.1.13.3.1   Priority¶
    This element specifies the thread priority that will be used by the receiver thread. Only priorities that are supported by the underlying operating system @@ -5669,19 +4825,19 @@
    5.6.1.13.3.1   Priority
      -
    • Full path: //OpenSplice/SNetworkService/Channels/Channel/Receiving/Scheduling/Priority
    • +
    • Full path: /SNetworkService/Channels/Channel/Receiving/Scheduling/Priority
    • Format: integer
    • Default value: 0
    • Occurrences min-max: 1-1
    • Optional attributes: priority_kind
    -
    -5.6.1.13.3.1.1   priority_kind¶ +
    +5.6.1.13.3.1.1   priority_kind¶
    This attribute specifies whether the specified Priority is a relative or absolute priority.
      -
    • Full path: //OpenSplice/SNetworkService/Channels/Channel/Receiving/Scheduling/Priority[@priority_kind]
    • +
    • Full path: /SNetworkService/Channels/Channel/Receiving/Scheduling/Priority/priority_kind
    • Format: enumeration
    • Default value: Relative
    • Valid values: Relative, Absolute
    • @@ -5689,14 +4845,14 @@
      5.6.1.13.3.1   Priority
    -
    -
    5.6.1.13.3.2   Class¶
    +
    +
    5.6.1.13.3.2   Class¶
    This element specifies the thread scheduling class that will be used by the receiver thread. The user may need the appropriate privileges from the underlying operating system to be able to assign some of the privileged scheduling classes.
    @@ -5726,16 +4878,16 @@
    5.6.1.13.5   SMPOptimization -
  • Full path: //OpenSplice/SNetworkService/Channels/Channel/Receiving/SMPOptimization
  • +
  • Full path: /SNetworkService/Channels/Channel/Receiving/SMPOptimization
  • Occurrences min-max: 0-1
  • Required attributes: enabled
  • -
    -
    5.6.1.13.5.1   enabled¶
    +
    +
    5.6.1.13.5.1   enabled¶
    This attribute toggles the Optimization on or off.
      -
    • Full path: //OpenSplice/SNetworkService/Channels/Channel/Receiving/SMPOptimization[@enabled]
    • +
    • Full path: /SNetworkService/Channels/Channel/Receiving/SMPOptimization/enabled
    • Format: boolean
    • Default value: true
    • Required: true
    • @@ -5744,17 +4896,15 @@
      5.6.1.13.5.1   enabled
      5.6.1.13.6   MaxReliabBacklog¶
      -

      This element specifies the maximum number of received fragments maintained in -the channel from a single sender for the purpose of order preservation because an -earlier fragment from that sender is missing. A sender is disconnected and all -maintained fragments are discarded when this number is exceeded. Future -fragments from this sender are only accepted after a disconnect if reconnection is set -to true (see Element Reconnection).

      +
      +
      This is a lower limit to the DefragBufferSize that specifies the number of received fragments +from a single remote node allocated for the purpose of order preservation because an earlier +fragment from that remote node is missing. If this number is exceeded, then that particular +remote node that didn’t resend the missing fragent in time is considered dead for this channel.
        -
      • Full path: //OpenSplice/SNetworkService/Channels/Channel/Receiving/MaxReliabBacklog
      • +
      • Full path: /SNetworkService/Channels/Channel/Receiving/MaxReliabBacklog
      • Format: integer
      • Default value: 1000
      • -
      • Valid values: 100 / -
      • Occurrences min-max: 0-1
      @@ -5774,10 +4924,9 @@
      5.6.1.13.7   PacketRetentionPeriod
        -
      • Full path: //OpenSplice/SNetworkService/Channels/Channel/Receiving/PacketRetentionPeriod
      • +
      • Full path: /SNetworkService/Channels/Channel/Receiving/PacketRetentionPeriod
      • Format: integer
      • Default value: 0
      • -
      • Valid values: 0 / -
      • Occurrences min-max: 0-1
    @@ -5793,10 +4942,9 @@
    5.6.1.13.8   ReliabilityRecoveryPeriod
      -
    • Full path: //OpenSplice/SNetworkService/Channels/Channel/Receiving/ReliabilityRecoveryPeriod
    • +
    • Full path: /SNetworkService/Channels/Channel/Receiving/ReliabilityRecoveryPeriod
    • Format: integer
    • Default value: 1000
    • -
    • Valid values: 0 / -
    • Occurrences min-max: 0-1
    @@ -5818,14 +4966,14 @@

    5.6.1.14   AllowedPorts -
  • Full path: //OpenSplice/SNetworkService/Channels/Channel/AllowedPorts
  • +
  • Full path: /SNetworkService/Channels/Channel/AllowedPorts
  • Format: string
  • Occurrences min-max: 0-1
  • -
    -

    5.6.2   AllowedPorts¶

    +
    +

    5.6.2   AllowedPorts¶

    AllowedPorts specifies the port numbers available for the network service to be used by the reliable network channels. The network channel is configured with a unique port number. However @@ -5841,7 +4989,7 @@

    5.6.2   AllowedPorts

      -
    • Full path: //OpenSplice/SNetworkService/Channels/AllowedPorts
    • +
    • Full path: /SNetworkService/Channels/AllowedPorts
    • Format: string
    • Occurrences min-max: 0-1
    @@ -5858,27 +5006,27 @@

    5.7   Discovery
      -
    • Full path: //OpenSplice/SNetworkService/Discovery
    • +
    • Full path: /SNetworkService/Discovery
    • Occurrences min-max: 0-1
    • Child elements: PortNr, ProbeList
    • Optional attributes: enabled, Scope
    -
    -

    5.7.1   enabled¶

    +
    +

    5.7.1   enabled¶

    This element can be used to enable or disable the Discovery Channel. In case the Discovery Channel is disabled, entities will only detect each others presence implicitly once messages are received for the first time.
      -
    • Full path: //OpenSplice/SNetworkService/Discovery[@enabled]
    • +
    • Full path: /SNetworkService/Discovery/enabled
    • Format: boolean
    • Default value: true
    • Occurrences min-max: 0-1
    • Required: false
    -
    -

    5.7.2   Scope¶

    +
    +

    5.7.2   Scope¶

    This attribute controls the dynamic discovery behaviour of this node within the current Domain. If it is not set, dynamic discovery will be disabled and the networking service will only @@ -5890,21 +5038,20 @@

    5.7.2   Scope -
  • Full path: //OpenSplice/SNetworkService/Discovery[@Scope]
  • +
  • Full path: /SNetworkService/Discovery/Scope
  • Format: string
  • Occurrences min-max: 0-1
  • Required: false
  • -
    -

    5.7.3   PortNr¶

    +
    +

    5.7.3   PortNr¶

    This element specifies the Port number used by the Discovery Channel.
      -
    • Full path: //OpenSplice/SNetworkService/Discovery/PortNr
    • +
    • Full path: /SNetworkService/Discovery/PortNr
    • Format: integer
    • Default value: 3369
    • -
    • Valid values: 1 / 65536
    • Occurrences min-max: 1-1
    @@ -5917,23 +5064,23 @@

    5.7.4   ProbeList

      -
    • Full path: //OpenSplice/SNetworkService/Discovery/ProbeList
    • +
    • Full path: /SNetworkService/Discovery/ProbeList
    • Format: string
    • Occurrences min-max: 0-1
    -
    -

    5.7.5   Sending¶

    +
    +

    5.7.5   Sending¶

    This element describes all properties for the transmitting side of the Discovery Channel.
      -
    • Full path: //OpenSplice/SNetworkService/Discovery/Sending
    • +
    • Full path: /SNetworkService/Discovery/Sending
    • Occurrences min-max: 0-1
    • Child elements: CrcCheck, DiffServField, DontRoute, TimeToLive, Interval, SafetyFactor, SalvoSize
    -
    -

    5.7.5.1   CrcCheck¶

    +
    +

    5.7.5.1   CrcCheck¶

    In order to protect OpenSplice network packets from malicious attack the CrcCheck(cyclic redundancy check) configuration item has been added. CRCs are specifically designed to protect against common types of errors on communication channels. @@ -5942,14 +5089,14 @@

    5.7.5.1   CrcCheck -
  • Full path: //OpenSplice/SNetworkService/Discovery/Sending/CrcCheck
  • +
  • Full path: /SNetworkService/Discovery/Sending/CrcCheck
  • Format: boolean
  • Default value: false
  • Occurrences min-max: 0-1
  • -
    -

    5.7.5.2   DiffServField¶

    +
    +

    5.7.5.2   DiffServField¶

    This element describes the DiffServ setting the channel will apply to the networking messages. This parameter determines the value of the diffserv field of the IP version 4 packets send @@ -5965,72 +5112,70 @@

    5.7.5.2   DiffServField

      -
    • Full path: //OpenSplice/SNetworkService/Discovery/Sending/DiffServField
    • +
    • Full path: /SNetworkService/Discovery/Sending/DiffServField
    • Format: integer
    • Default value: 0
    • -
    • Valid values: 0 / 255
    • Occurrences min-max: 0-1
    -
    -

    5.7.5.3   DontRoute¶

    +
    +

    5.7.5.3   DontRoute¶

    The IP DONTROUTE
    socket option is set to the value specified.
      -
    • Full path: //OpenSplice/SNetworkService/Discovery/Sending/DontRoute
    • +
    • Full path: /SNetworkService/Discovery/Sending/DontRoute
    • Format: boolean
    • Default value: True
    • Valid values: True, False
    • Occurrences min-max: 0-1
    -
    -

    5.7.5.4   TimeToLive¶

    +
    +

    5.7.5.4   TimeToLive¶

    For each UDP packet sent out, the IP Time To Live
    header value is set to the value specified.
      -
    • Full path: //OpenSplice/SNetworkService/Discovery/Sending/TimeToLive
    • +
    • Full path: /SNetworkService/Discovery/Sending/TimeToLive
    • Format: integer
    • Default value: 0
    • -
    • Valid values: 0 / 255
    • Occurrences min-max: 0-1
    -
    -

    5.7.5.5   Scheduling¶

    +
    +

    5.7.5.5   Scheduling¶

    This element specifies the scheduling policies used to control the transmitter thread of the Discovery Channel.
      -
    • Full path: //OpenSplice/SNetworkService/Discovery/Sending/Scheduling
    • +
    • Full path: /SNetworkService/Discovery/Sending/Scheduling
    • Occurrences min-max: 0-1
    • Child elements: Priority, Class
    -
    -
    5.7.5.5.1   Priority¶
    +
    +
    5.7.5.5.1   Priority¶
    This element specifies the thread priority that will be used by the transmitter thread of the Discovery Channel. Only priorities that are supported by the underlying operating system can be assigned to this element. The user may need special privileges from the underlying operating system to be able to assign some of the privileged priorities.
      -
    • Full path: //OpenSplice/SNetworkService/Discovery/Sending/Scheduling/Priority
    • +
    • Full path: /SNetworkService/Discovery/Sending/Scheduling/Priority
    • Format: integer
    • Default value: 0
    • Occurrences min-max: 1-1
    • Optional attributes: priority_kind
    -
    -
    5.7.5.5.1.1   priority_kind¶
    +
    +
    5.7.5.5.1.1   priority_kind¶
    This attribute specifies whether the specified Priority is a relative or absolute priority.
      -
    • Full path: //OpenSplice/SNetworkService/Discovery/Sending/Scheduling/Priority[@priority_kind]
    • +
    • Full path: /SNetworkService/Discovery/Sending/Scheduling/Priority/priority_kind
    • Format: enumeration
    • Default value: Relative
    • Valid values: Relative, Absolute
    • @@ -6038,14 +5183,14 @@
      5.7.5.5.1.1   priority_kind -
      5.7.5.5.2   Class¶
      +
      +
      5.7.5.5.2   Class¶
      This element specifies the thread scheduling class that will be used by the transmitter thread of the Discovery Channel. The user may need the appropriate privileges from the underlying operating system to be able to assign some of the privileged scheduling classes.
      -
    • Full path: //OpenSplice/SNetworkService/Discovery/Sending/Interval
    • +
    • Full path: /SNetworkService/Discovery/Sending/Interval
    • Format: integer
    • Default value: 333
    • -
    • Valid values: 10 / -
    • Occurrences min-max: 0-1
    @@ -6070,9 +5214,8 @@

    5.7.5.7   SafetyFactor -
  • Full path: //OpenSplice/SNetworkService/Discovery/Sending/SafetyFactor
  • +
  • Full path: /SNetworkService/Discovery/Sending/SafetyFactor
  • Default value: 0.9
  • -
  • Valid values: 0.2 / 1.0
  • Occurrences min-max: 0-1
  • @@ -6082,26 +5225,25 @@

    5.7.5.8   SalvoSizeDuring starting and stopping, discovery messages are sent at higher frequency. This SalvoSize sets the number of messages to send during these phases.

      -
    • Full path: //OpenSplice/SNetworkService/Discovery/Sending/SalvoSize
    • +
    • Full path: /SNetworkService/Discovery/Sending/SalvoSize
    • Format: integer
    • Default value: 3
    • -
    • Valid values: 1 / -
    • Occurrences min-max: 0-1
    -
    -

    5.7.6   Receiving¶

    +
    +

    5.7.6   Receiving¶

    This element describes all properties for the receiving side of the Discovery Channel.
      -
    • Full path: //OpenSplice/SNetworkService/Discovery/Receiving
    • +
    • Full path: /SNetworkService/Discovery/Receiving
    • Occurrences min-max: 0-1
    • Child elements: CrcCheck, DeathDetectionCount, ReceiveBufferSize
    -
    -

    5.7.6.1   CrcCheck¶

    +
    +

    5.7.6.1   CrcCheck¶

    In order to protect OpenSplice network packets from malicious attack the CrcCheck(cyclic redundancy check) configuration item has been added. CRCs are specifically designed to protect against common types of errors on communication channels. @@ -6110,43 +5252,43 @@

    5.7.6.1   CrcCheck -
  • Full path: //OpenSplice/SNetworkService/Discovery/Receiving/CrcCheck
  • +
  • Full path: /SNetworkService/Discovery/Receiving/CrcCheck
  • Format: boolean
  • Default value: false
  • Occurrences min-max: 0-1
  • -
    -

    5.7.6.2   Scheduling¶

    +
    +

    5.7.6.2   Scheduling¶

    This element specifies the scheduling policies used to control the receiver thread of the Discovery Channel.
      -
    • Full path: //OpenSplice/SNetworkService/Discovery/Receiving/Scheduling
    • +
    • Full path: /SNetworkService/Discovery/Receiving/Scheduling
    • Occurrences min-max: 0-1
    • Child elements: Priority, Class
    -
    -
    5.7.6.2.1   Priority¶
    +
    +
    5.7.6.2.1   Priority¶
    This element specifies the thread priority that will be used by the receiver thread of the Discovery Channel. Only priorities that are supported by the underlying operating system can be assigned to this element. The user may need special privileges from the underlying operating system to be able to assign some of the privileged priorities.
      -
    • Full path: //OpenSplice/SNetworkService/Discovery/Receiving/Scheduling/Priority
    • +
    • Full path: /SNetworkService/Discovery/Receiving/Scheduling/Priority
    • Format: integer
    • Default value: 0
    • Occurrences min-max: 1-1
    • Optional attributes: priority_kind
    -
    -
    5.7.6.2.1.1   priority_kind¶
    +
    +
    5.7.6.2.1.1   priority_kind¶
    This attribute specifies whether the specified Priority is a relative or absolute priority.
      -
    • Full path: //OpenSplice/SNetworkService/Discovery/Receiving/Scheduling/Priority[@priority_kind]
    • +
    • Full path: /SNetworkService/Discovery/Receiving/Scheduling/Priority/priority_kind
    • Format: enumeration
    • Default value: Relative
    • Valid values: Relative, Absolute
    • @@ -6154,14 +5296,14 @@
      5.7.6.2.1.1   priority_kind -
      5.7.6.2.2   Class¶
      +
      +
      5.7.6.2.2   Class¶
      This element specifies the thread scheduling class that will be used by the receiver thread of the Discovery Channel. The user may need the appropriate privileges from the underlying operating system to be able to assign some of the privileged scheduling classes.
      -
      -

      5.7.6.4   ReceiveBufferSize¶

      +
      +

      5.7.6.4   ReceiveBufferSize¶

      The UDP receive buffer of the Discovery Channel socket is set to the value given. If many message are lost, the receive buffer size has to be increased.
        -
      • Full path: //OpenSplice/SNetworkService/Discovery/Receiving/ReceiveBufferSize
      • +
      • Full path: /SNetworkService/Discovery/Receiving/ReceiveBufferSize
      • Default value: 1000000
      • -
      • Valid values: 1 / -
      • Occurrences min-max: 0-1
    -
    -

    5.8   Tracing¶

    +
    +

    5.8   Tracing¶

    This element controls the amount and type of information that is written into the tracing log by the Networking Service. This is useful to track the Networking Service during application development. In the runtime system it should be turned off.
      -
    • Full path: //OpenSplice/SNetworkService/Tracing
    • +
    • Full path: /SNetworkService/Tracing
    • Occurrences min-max: 0-1
    • Child elements: OutputFile, Timestamps
    • -
    • Optional attributes: enabled
    • -
    -
    -

    5.8.1   enabled¶

    -
    -
    This attribute controls whether the tracing option is enabled or not.
    -
      -
    • Full path: //OpenSplice/SNetworkService/Tracing[@enabled]
    • -
    • Format: boolean
    • -
    • Default value: true
    • -
    • Required: false
    -
    -
    -

    5.8.2   OutputFile¶

    +
    +

    5.8.1   OutputFile¶

    This option specifies where the logging is printed to. Note that “stdout” is considered a legal value that represents “standard out”. The default value is an empty string, indicating that the tracing log will be written to standard out.
      -
    • Full path: //OpenSplice/SNetworkService/Tracing/OutputFile
    • +
    • Full path: /SNetworkService/Tracing/OutputFile
    • Format: string
    • Default value: networking.log
    • Occurrences min-max: 1-1
    -
    -

    5.8.3   Timestamps¶

    +
    +

    5.8.2   Timestamps¶

    This element specifies whether the logging must contain timestamps.
      -
    • Full path: //OpenSplice/SNetworkService/Tracing/Timestamps
    • +
    • Full path: /SNetworkService/Tracing/Timestamps
    • Format: boolean
    • Default value: true
    • -
    • Occurrences min-max: 0-1
    • +
    • Occurrences min-max: 1-1
    • Optional attributes: absolute
    -
    -

    5.8.3.1   absolute¶

    +
    +

    5.8.2.1   absolute¶

    This attribute specifies whether the timestamps are absolute or relative to the startup time of the service.
      -
    • Full path: //OpenSplice/SNetworkService/Tracing/Timestamps[@absolute]
    • +
    • Full path: /SNetworkService/Tracing/Timestamps/absolute
    • Format: boolean
    • Default value: true
    • Required: false
    • @@ -6257,182 +5385,171 @@

      5.8.3.1   absolute -

      5.8.4   Categories¶

      +

      5.8.3   Categories¶

      This element contains the logging properties for various networking categories.
        -
      • Full path: //OpenSplice/SNetworkService/Tracing/Categories
      • +
      • Full path: /SNetworkService/Tracing/Categories
      • Occurrences min-max: 1-1
      • Child elements: Default, Configuration, Construction, Destruction, Mainloop, Groups, Send, Receive, Throttling, Test, Discovery
      -
      -

      5.8.4.1   Default¶

      +
      +

      5.8.3.1   Default¶

      This element specifies the tracing level used for categories that are not explicitly specified. Level 0 indicates no tracing, level 6 indicates the most detailed level of tracing.
        -
      • Full path: //OpenSplice/SNetworkService/Tracing/Categories/Default
      • +
      • Full path: /SNetworkService/Tracing/Categories/Default
      • Format: integer
      • Default value: 0
      • -
      • Valid values: 0 / 6
      • -
      • Occurrences min-max: 0-1
      • +
      • Occurrences min-max: 1-1
      -
      -

      5.8.4.2   Configuration¶

      +
      +

      5.8.3.2   Configuration¶

      This element specifies the tracing level for the Configuration category. This includes the processing of all NetworkService parameters in the config file. Level 0 indicates no tracing, level 6 indicates the most detailed level of tracing.
        -
      • Full path: //OpenSplice/SNetworkService/Tracing/Categories/Configuration
      • +
      • Full path: /SNetworkService/Tracing/Categories/Configuration
      • Format: integer
      • Default value: 0
      • -
      • Valid values: 0 / 6
      • Occurrences min-max: 0-1
      -

      5.8.4.3   Construction¶

      +

      5.8.3.3   Construction¶

      This element specifies the tracing level for the Construction category. This includes the creation of all internal processing entities. Level 0 indicates no tracing, level 6 indicates the most detailed level of tracing.
        -
      • Full path: //OpenSplice/SNetworkService/Tracing/Categories/Construction
      • +
      • Full path: /SNetworkService/Tracing/Categories/Construction
      • Format: integer
      • Default value: 0
      • -
      • Valid values: 0 / 6
      • Occurrences min-max: 0-1
      -

      5.8.4.4   Destruction¶

      +

      5.8.3.4   Destruction¶

      This element specifies the tracing level for the Destruction category. This includes the destruction of all internal processing entities when the NetworkService terminates. Level 0 indicates no tracing, level 6 indicates the most detailed level of tracing.
        -
      • Full path: //OpenSplice/SNetworkService/Tracing/Categories/Destruction
      • +
      • Full path: /SNetworkService/Tracing/Categories/Destruction
      • Format: integer
      • Default value: 0
      • -
      • Valid values: 0 / 6
      • Occurrences min-max: 0-1
      -

      5.8.4.5   Mainloop¶

      +

      5.8.3.5   Mainloop¶

      This element specifies the tracing level for the Mainloop category. This includes information about each of the threads spawned by the NetworkService. Level 0 indicates no tracing, level 6 indicates the most detailed level of tracing.
        -
      • Full path: //OpenSplice/SNetworkService/Tracing/Categories/Mainloop
      • +
      • Full path: /SNetworkService/Tracing/Categories/Mainloop
      • Format: integer
      • Default value: 0
      • -
      • Valid values: 0 / 6
      • Occurrences min-max: 0-1
      -

      5.8.4.6   Groups¶

      +

      5.8.3.6   Groups¶

      This element specifies the tracing level for the Groups category. This includes the management of local groups (partition-topic combinations). Level 0 indicates no tracing, level 6 indicates the most detailed level of tracing.
        -
      • Full path: //OpenSplice/SNetworkService/Tracing/Categories/Groups
      • +
      • Full path: /SNetworkService/Tracing/Categories/Groups
      • Format: integer
      • Default value: 0
      • -
      • Valid values: 0 / 6
      • Occurrences min-max: 0-1
      -

      5.8.4.7   Send¶

      +

      5.8.3.7   Send¶

      This element specifies the tracing level for the Send category. This includes information about outgoing data. Level 0 indicates no tracing, level 6 indicates the most detailed level of tracing.
        -
      • Full path: //OpenSplice/SNetworkService/Tracing/Categories/Send
      • +
      • Full path: /SNetworkService/Tracing/Categories/Send
      • Format: integer
      • Default value: 0
      • -
      • Valid values: 0 / 6
      • Occurrences min-max: 0-1
      -

      5.8.4.8   Receive¶

      +

      5.8.3.8   Receive¶

      This element specifies the tracing level for the Receive category. This includes information about incoming data. Level 0 indicates no tracing, level 6 indicates the most detailed level of tracing.
        -
      • Full path: //OpenSplice/SNetworkService/Tracing/Categories/Receive
      • +
      • Full path: /SNetworkService/Tracing/Categories/Receive
      • Format: integer
      • Default value: 0
      • -
      • Valid values: 0 / 6
      • Occurrences min-max: 0-1
      -

      5.8.4.9   Throttling¶

      +

      5.8.3.9   Throttling¶

      This element specifies the tracing level for the Throttling category. This includes information about throttling. Level 0 indicates no tracing, level 6 indicates the most detailed level of tracing.
        -
      • Full path: //OpenSplice/SNetworkService/Tracing/Categories/Throttling
      • +
      • Full path: /SNetworkService/Tracing/Categories/Throttling
      • Format: integer
      • Default value: 0
      • -
      • Valid values: 0 / 6
      • Occurrences min-max: 0-1
      -

      5.8.4.10   Test¶

      +

      5.8.3.10   Test¶

      This element specifies the tracing level for the Test category. This is a reserved category used for testing purposes. Level 0 indicates no tracing, level 6 indicates the most detailed level of tracing.
        -
      • Full path: //OpenSplice/SNetworkService/Tracing/Categories/Test
      • +
      • Full path: /SNetworkService/Tracing/Categories/Test
      • Format: integer
      • Default value: 0
      • -
      • Valid values: 0 / 6
      • Occurrences min-max: 0-1
      -
      -

      5.8.4.11   Discovery¶

      +
      +

      5.8.3.11   Discovery¶

      This element specifies the tracing level for the Discovery category. This includes all activity related to the discovery channel. Level 0 indicates no tracing, level 6 indicates the most detailed level of tracing.
        -
      • Full path: //OpenSplice/SNetworkService/Tracing/Categories/Discovery
      • +
      • Full path: /SNetworkService/Tracing/Categories/Discovery
      • Format: integer
      • Default value: 0
      • -
      • Valid values: 0 / 6
      • Occurrences min-max: 0-1
      -
      -

      5.9   Compression¶

      +
      +

      5.9   Compression¶

      This group of attributes specifies a compression method to use within the service in partitions where it is enabled. The @@ -6445,7 +5562,7 @@

      5.9   Compression -
    • Full path: //OpenSplice/SNetworkService/Compression
    • +
    • Full path: /SNetworkService/Compression
    • Occurrences min-max: 0-1
    • Optional attributes: PluginLibrary, PluginInitFunction, PluginParameter
    @@ -6457,7 +5574,7 @@

    5.9.1   PluginLibrary -
  • Full path: //OpenSplice/SNetworkService/Compression[@PluginLibrary]
  • +
  • Full path: /SNetworkService/Compression/PluginLibrary
  • Format: string
  • Default value: “”
  • Required: false
  • @@ -6472,7 +5589,7 @@

    5.9.2   PluginInitFunction -
  • Full path: //OpenSplice/SNetworkService/Compression[@PluginInitFunction]
  • +
  • Full path: /SNetworkService/Compression/PluginInitFunction
  • Format: string
  • Default value: “”
  • Required: false
  • @@ -6487,7 +5604,7 @@

    5.9.3   PluginParameter -
  • Full path: //OpenSplice/SNetworkService/Compression[@PluginParameter]
  • +
  • Full path: /SNetworkService/Compression/PluginParameter
  • Format: string
  • Default value: “”
  • Required: false
  • @@ -6497,40 +5614,25 @@

    5.9.3   PluginParameter

    6   NetworkService¶

    -

    The Network Service provides a bridge between the local DDS service and a -network interface. -The OpenSplice NetworkService supports both Internet Protocol -Versions 4 and 6 (IPv4 & IPv6) where possible. Please refer to the Release Notes -(Known Issues section) to see if the IPv6 capability is present on your operating -system.

    -

    Note that each service instance will only communicate using one of these protocols. -It is an error to specify IPv6 (‘colon-separated hexadecimal’) and IPv4 (‘dotted -decimal’) addresses in the same NetworkService configuration.

    -

    Multiple Network Services can exist next to each other, each serving one physical -network interface. -Please refer to Applications which operate in multiple domains, for notes about -applications operating in multiple domains and interactions with the Network Service. -The Network Service is responsible for forwarding data to the network and for -receiving data from the network. It can be configured to distinguish multiple -communication channels with different QoS policies assigned to be able to schedule -sending and receival of specific messages to provide optimal performance for a -specific application domain. -The Network Service is selected by using the following configuration element to the -Domain section of the configuration file (Element Application). -* -<Service name=”networking”>

    -

    <Command>networking</Command>

    -

    </Service>*

    -

    The network configuration expects a root element named -OpenSplice/NetworkService. Within this root element, the Network Service -will look for several child-elements. Each of these is listed and explained.

    -
      -
    • Full path: //OpenSplice/NetworkService
    • +
      +
      When communication endpoints are located on different computing nodes, +the data produced using the local DDS service must be communicated to +the remote DDS service and the other way around. The Networking service +provides a bridge between the local DDS service and a network interface. +Multiple Networking services can exist next to each other; each serving +one (or more) physical network interface(s). The Networking service +is responsible for forwarding data to the network and for receiving data +from the network. It can be configured to distinguish multiple +communication channels with different QoS policies assigned to be able +to schedule sending and receival of specific messages to provide optimal +performance for a specific application domain.
      +
        +
      • Full path: /NetworkService
      • Occurrences min-max: 0-*
      • Required attributes: name
      -
      -

      6.1   name¶

      +
      +

      6.1   name¶

      This attribute identifies the configuration for the Networking service. Multiple Network service configurations can be specified in one single @@ -6539,32 +5641,32 @@

      6.1   name -
    • Full path: //OpenSplice/NetworkService[@name]
    • +
    • Full path: /NetworkService/name
    • Format: string
    • Default value: networking
    • Required: true

    -
    -

    6.2   Watchdog¶

    +
    +

    6.2   Watchdog¶

    This element controls the characteristics of the Watchdog thread.
      -
    • Full path: //OpenSplice/NetworkService/Watchdog
    • +
    • Full path: /NetworkService/Watchdog
    • Occurrences min-max: 0-1
    -
    -

    6.2.1   Scheduling¶

    +
    +

    6.2.1   Scheduling¶

    This element specifies the type of OS scheduling class will be used by the thread that announces its liveliness periodically.
      -
    • Full path: //OpenSplice/NetworkService/Watchdog/Scheduling
    • +
    • Full path: /NetworkService/Watchdog/Scheduling
    • Occurrences min-max: 1-1
    • Child elements: Priority, Class
    -
    -

    6.2.1.1   Priority¶

    +
    +

    6.2.1.1   Priority¶

    This element specifies the thread priority that will be used by the watchdog thread. Only priorities that are supported by the @@ -6572,19 +5674,19 @@

    6.2.1.1   Priority -
  • Full path: //OpenSplice/NetworkService/Watchdog/Scheduling/Priority
  • +
  • Full path: /NetworkService/Watchdog/Scheduling/Priority
  • Format: integer
  • Default value: 0
  • Occurrences min-max: 1-1
  • Optional attributes: priority_kind
  • -
    -
    6.2.1.1.1   priority_kind¶
    +
    +
    6.2.1.1.1   priority_kind¶
    This attribute specifies whether the specified Priority is a relative or absolute priority.
      -
    • Full path: //OpenSplice/NetworkService/Watchdog/Scheduling/Priority[@priority_kind]
    • +
    • Full path: /NetworkService/Watchdog/Scheduling/Priority/priority_kind
    • Format: enumeration
    • Default value: Relative
    • Valid values: Relative, Absolute
    • @@ -6592,15 +5694,15 @@
      6.2.1.1.1   priority_kind
    -
    -

    6.2.1.2   Class¶

    +
    +

    6.2.1.2   Class¶

    This element specifies the thread scheduling class that will be used by the watchdog thread. The user may need the appropriate privileges from the underlying operating system to be able to assign some of the privileged scheduling classes.
    -
    -

    6.3.1.1   forced¶

    +
    +

    6.3.1.1   forced¶

    This attribute specifies whether only the selected NetworkInterfaceAddress should be used or others can be used too.

    @@ -6648,14 +5750,14 @@

    6.3.1.1   forced -
  • Full path: //OpenSplice/NetworkService/General/NetworkInterfaceAddress[@forced]
  • +
  • Full path: /NetworkService/General/NetworkInterfaceAddress/forced
  • Format: boolean
  • Default value: false
  • Required: false
  • -
    -

    6.3.1.2   ipv6¶

    +
    +

    6.3.1.2   ipv6¶

    - -
    -

    6.3.2   EnableMulticastLoopback¶

    -
    -
    EnableMulticastLoopback specifies whether the networking service will allow -IP multicast packets within the node to be visible to all networking participants in the node, +
    +

    6.3.2   EnableMulticastLoopback¶

    +
    +
    EnableMulticastLoopback specifies whether the networking service will allow
    +
    IP multicast packets within the node to be visible to all networking participants in the node, including itself. It must be TRUE for intra-node multicast communications, but if a node runs only a single OpenSplice networking service and does not host -any other networking-capable programs, it may be set to FALSE for improved performance.
    +any other networking-capable programs, it may be set to FALSE for improved performance. +
      -
    • Full path: //OpenSplice/NetworkService/General/EnableMulticastLoopback
    • +
    • Full path: /NetworkService/General/EnableMulticastLoopback
    • Format: boolean
    • Default value: True
    • Valid values: True, False
    • Occurrences min-max: 0-1
    -
    -

    6.3.3   LegacyCompression¶

    +
    +

    6.3.3   LegacyCompression¶

    This element specifies if compression is applied after of before fragmentations. When set to TRUE compression is applied after fragmentation which is provided for backward compatibility. When set to FALSE compression is applied before fragmentation. The default value is TRUE.
      -
    • Full path: //OpenSplice/NetworkService/General/LegacyCompression
    • +
    • Full path: /NetworkService/General/LegacyCompression
    • Format: boolean
    • Default value: True
    • Valid values: True, False
    • Occurrences min-max: 0-1
    -
    -

    6.3.4   Reconnection¶

    +
    +

    6.3.4   Reconnection¶

    This element specifies the desired networking-behavior with respect to the validity of restoring lost connectivity with remote nodes. @@ -6764,12 +5867,12 @@

    6.3.4   Reconnection

      -
    • Full path: //OpenSplice/NetworkService/General/Reconnection
    • +
    • Full path: /NetworkService/General/Reconnection
    • Occurrences min-max: 0-1
    • Required attributes: allowed
    -
    -

    6.3.4.1   allowed¶

    +
    +

    6.3.4.1   allowed¶

    This attribute specifies whether the network service must resume communication with an other network service when it @@ -6783,7 +5886,7 @@

    6.3.4.1   allowed -
  • Full path: //OpenSplice/NetworkService/General/Reconnection[@allowed]
  • +
  • Full path: /NetworkService/General/Reconnection/allowed
  • Format: boolean
  • Default value: false
  • Required: true
  • @@ -6791,8 +5894,8 @@

    6.3.4.1   allowed -

    6.4   Partitioning¶

    +
    +

    6.4   Partitioning¶

    The OpenSplice Networking service is capable of leveraging the network’s multicast and routing capabilities. If some a-priori @@ -6819,23 +5922,21 @@

    6.4   Partitioning -
  • Full path: //OpenSplice/NetworkService/Partitioning
  • +
  • Full path: /NetworkService/Partitioning
  • Occurrences min-max: 0-1
  • -
    -

    6.4.1   GlobalPartition¶

    +
    +

    6.4.1   GlobalPartition¶

    -
    This element specifies the global or default networking partition. -This global network partition transports data that is either meant to be global, like discovery heartbeats, -or that is not mapped onto any other network partition.
    +
    This element specifies the global or default networking partition.

      -
    • Full path: //OpenSplice/NetworkService/Partitioning/GlobalPartition
    • +
    • Full path: /NetworkService/Partitioning/GlobalPartition
    • Occurrences min-max: 0-1
    • Required attributes: Address
    • Optional attributes: MulticastTimeToLive
    -
    -

    6.4.1.1   Address¶

    +
    +

    6.4.1.1   Address¶

    -
    -

    6.4.1.2   MulticastTimeToLive¶

    -
    -
    For each UDP packet sent out, the TimeToLive header value is set to this value for -Multicast packets. -By specifying a value of ‘0’, multicast traffic can be confined to the local node, and -such ‘loopback’ performance is typically optimized by the operating system
    +
    +

    6.4.1.2   MulticastTimeToLive¶

    +

    For each UDP packet sent out, The TimeToLive header value is set to this value for Multicast packets.

      -
    • Full path: //OpenSplice/NetworkService/Partitioning/GlobalPartition[@MulticastTimeToLive]
    • +
    • Full path: /NetworkService/Partitioning/GlobalPartition/MulticastTimeToLive
    • Default value: 32
    • -
    • Valid values: 0 / 255
    • Required: false
    -
    -

    6.4.2   NetworkPartitions¶

    +
    +

    6.4.2   NetworkPartitions¶

    Networking configuration can contain a set of networking partitions, which are grouped under the NetworkPartitions element.
      -
    • Full path: //OpenSplice/NetworkService/Partitioning/NetworkPartitions
    • +
    • Full path: /NetworkService/Partitioning/NetworkPartitions
    • Occurrences min-max: 0-1
    -
    -

    6.4.2.1   NetworkPartition¶

    +
    +

    6.4.2.1   NetworkPartition¶

    Every NetworkPartition has a name, an address and a connected flag.
      -
    • Full path: //OpenSplice/NetworkService/Partitioning/NetworkPartitions/NetworkPartition
    • +
    • Full path: /NetworkService/Partitioning/NetworkPartitions/NetworkPartition
    • Occurrences min-max: 1-*
    • -
    • Required attributes: Address
    • -
    • Optional attributes: Name, Connected, Compression, SecurityProfile, MulticastTimeToLive
    • +
    • Required attributes: Address, Connected
    • +
    • Optional attributes: Name, Compression, SecurityProfile, MulticastTimeToLive
    -
    -
    6.4.2.1.1   Name¶
    +
    +
    6.4.2.1.1   Name¶
    A networking partition is uniquely identified by its name.
      -
    • Full path: //OpenSplice/NetworkService/Partitioning/NetworkPartitions/NetworkPartition[@Name]
    • +
    • Full path: /NetworkService/Partitioning/NetworkPartitions/NetworkPartition/Name
    • Format: string
    • Default value: networkPartition
    • Required: false
    -
    -
    6.4.2.1.2   Address¶
    + -
    -
    6.4.2.1.3   Connected¶
    +
    +
    6.4.2.1.3   Connected¶

    A node can choose to be not connected to a networking partition by setting the Connected attribute.

    @@ -6939,14 +6032,14 @@
    6.4.2.1.3   Connected
      -
    • Full path: //OpenSplice/NetworkService/Partitioning/NetworkPartitions/NetworkPartition[@Connected]
    • +
    • Full path: /NetworkService/Partitioning/NetworkPartitions/NetworkPartition/Connected
    • Format: boolean
    • Default value: true
    • -
    • Required: false
    • +
    • Required: true
    -
    -
    6.4.2.1.4   Compression¶
    +
    +
    6.4.2.1.4   Compression¶

    This attribute specifies if networking will apply compression to limit bandwidth for a specific network partition. This provides great flexibility as network @@ -6962,14 +6055,14 @@

    6.4.2.1.4   Compression
      -
    • Full path: //OpenSplice/NetworkService/Partitioning/NetworkPartitions/NetworkPartition[@Compression]
    • +
    • Full path: /NetworkService/Partitioning/NetworkPartitions/NetworkPartition/Compression
    • Format: boolean
    • Default value: false
    • Required: false
    -
    -
    6.4.2.1.5   SecurityProfile¶
    +
    +
    6.4.2.1.5   SecurityProfile¶
    In the context of secure networking, the NetworkPartition element provides support for the attribute SecurityProfile. The attribute is referencing a security @@ -6986,46 +6079,45 @@
    6.4.2.1.5   SecurityProfile -
  • Full path: //OpenSplice/NetworkService/Partitioning/NetworkPartitions/NetworkPartition[@SecurityProfile]
  • +
  • Full path: /NetworkService/Partitioning/NetworkPartitions/NetworkPartition/SecurityProfile
  • Format: string
  • Default value: nullProfile
  • Required: false
  • -
    -
    6.4.2.1.6   MulticastTimeToLive¶
    +
    +
    6.4.2.1.6   MulticastTimeToLive¶

    For each UDP packet sent out, The TimeToLive header value is set to this value for Multicast packets.

      -
    • Full path: //OpenSplice/NetworkService/Partitioning/NetworkPartitions/NetworkPartition[@MulticastTimeToLive]
    • +
    • Full path: /NetworkService/Partitioning/NetworkPartitions/NetworkPartition/MulticastTimeToLive
    • Default value: 32
    • -
    • Valid values: 0 / 255
    • Required: false
    -
    -

    6.4.3   IgnoredPartitions¶

    +
    +

    6.4.3   IgnoredPartitions¶

    This element is used to group the set of IgnoredPartition elements.
      -
    • Full path: //OpenSplice/NetworkService/Partitioning/IgnoredPartitions
    • +
    • Full path: /NetworkService/Partitioning/IgnoredPartitions
    • Occurrences min-max: 0-1
    -
    -

    6.4.3.1   IgnoredPartition¶

    +
    +

    6.4.3.1   IgnoredPartition¶

    This element can be used to create a “Local Partition” that is only available on the node on which it is specified, and therefore won’t generate network-load. Any DCPS partition-topic combination specified in this element will not be distibuted by the Networking service.
      -
    • Full path: //OpenSplice/NetworkService/Partitioning/IgnoredPartitions/IgnoredPartition
    • +
    • Full path: /NetworkService/Partitioning/IgnoredPartitions/IgnoredPartition
    • Occurrences min-max: 1-*
    • Required attributes: DCPSPartitionTopic
    -
    -
    6.4.3.1.1   DCPSPartitionTopic¶
    +
    +
    6.4.3.1.1   DCPSPartitionTopic¶
    The Networking service will match any DCPS messages to the DCPSPartitionTopic expression and determine @@ -7035,7 +6127,7 @@
    6.4.3.1.1   DCPSPartitionTopic -
  • Full path: //OpenSplice/NetworkService/Partitioning/IgnoredPartitions/IgnoredPartition[@DCPSPartitionTopic]
  • +
  • Full path: /NetworkService/Partitioning/IgnoredPartitions/IgnoredPartition/DCPSPartitionTopic
  • Format: string
  • Default value: .
  • Required: true
  • @@ -7043,16 +6135,16 @@
    6.4.3.1.1   DCPSPartitionTopic -

    6.4.4   PartitionMappings¶

    +
    +

    6.4.4   PartitionMappings¶

    This element is used to group the set of PartitionMapping elements.
      -
    • Full path: //OpenSplice/NetworkService/Partitioning/PartitionMappings
    • +
    • Full path: /NetworkService/Partitioning/PartitionMappings
    • Occurrences min-max: 0-1
    -
    -

    6.4.4.1   PartitionMapping¶

    +
    +

    6.4.4.1   PartitionMapping¶

    This element specifies a mapping between a network partition and a partition-topic combination.

    @@ -7062,26 +6154,26 @@

    6.4.4.1   PartitionMapping

      -
    • Full path: //OpenSplice/NetworkService/Partitioning/PartitionMappings/PartitionMapping
    • +
    • Full path: /NetworkService/Partitioning/PartitionMappings/PartitionMapping
    • Occurrences min-max: 1-*
    • Required attributes: NetworkPartition, DCPSPartitionTopic
    -
    -
    6.4.4.1.1   NetworkPartition¶
    +
    +
    6.4.4.1.1   NetworkPartition¶
    The NetworkPartition attribute of a partition mapping defines that networking partitition that data in a specific DCPS partition of a specific DCPS topic should be sent to.
      -
    • Full path: //OpenSplice/NetworkService/Partitioning/PartitionMappings/PartitionMapping[@NetworkPartition]
    • +
    • Full path: /NetworkService/Partitioning/PartitionMappings/PartitionMapping/NetworkPartition
    • Format: string
    • Default value: networkPartition
    • Required: true
    -
    -
    6.4.4.1.2   DCPSPartitionTopic¶
    +
    +
    6.4.4.1.2   DCPSPartitionTopic¶
    The Networking service will match any DCPS messages to the DCPSPartitionTopic expression and determine @@ -7094,7 +6186,7 @@
    6.4.4.1.2   DCPSPartitionTopic -
  • Full path: //OpenSplice/NetworkService/Partitioning/PartitionMappings/PartitionMapping[@DCPSPartitionTopic]
  • +
  • Full path: /NetworkService/Partitioning/PartitionMappings/PartitionMapping/DCPSPartitionTopic
  • Format: string
  • Default value: .
  • Required: true
  • @@ -7103,8 +6195,8 @@
    6.4.4.1.2   DCPSPartitionTopic -

    6.5   Channels¶

    +
    +

    6.5   Channels¶

    This element is used to group a set of Channels.

    The set of channels define the behaviour of the ‘network’ concerning @@ -7115,12 +6207,12 @@

    6.5   Channels -
  • Full path: //OpenSplice/NetworkService/Channels
  • +
  • Full path: /NetworkService/Channels
  • Occurrences min-max: 1-1
  • Child elements: AllowedPorts
  • -
    -

    6.5.1   Channel¶

    +
    +

    6.5.1   Channel¶

    This element specifies all properties of an individual Channel.

    The Networking service will make sure messages with a higher @@ -7131,25 +6223,25 @@

    6.5.1   Channel -
  • Full path: //OpenSplice/NetworkService/Channels/Channel
  • +
  • Full path: /NetworkService/Channels/Channel
  • Occurrences min-max: 1-42
  • Child elements: PortNr, FragmentSize, Resolution, AdminQueueSize, CompressionBufferSize, CompressionThreshold, AllowedPorts
  • Required attributes: name, reliable, enabled
  • Optional attributes: default, priority
  • -
    -

    6.5.1.1   name¶

    +
    +

    6.5.1.1   name¶

    The name uniquely identifies the channel.
      -
    • Full path: //OpenSplice/NetworkService/Channels/Channel[@name]
    • +
    • Full path: /NetworkService/Channels/Channel/name
    • Format: string
    • Default value: aChannel
    • Required: true
    -
    -

    6.5.1.2   reliable¶

    +
    +

    6.5.1.2   reliable¶

    If this attribute is set to true, the channel sends all messages reliably. If not, data is sent only once (fire-and-forget).

    @@ -7160,14 +6252,14 @@

    6.5.1.2   reliable -
  • Full path: //OpenSplice/NetworkService/Channels/Channel[@reliable]
  • +
  • Full path: /NetworkService/Channels/Channel/reliable
  • Format: boolean
  • Default value: false
  • Required: true
  • -
    -

    6.5.1.3   default¶

    +
    +

    6.5.1.3   default¶

    This attribute indicates whether the channel is selected as the default channel in case no channel offers the quality of service @@ -7182,28 +6274,28 @@

    6.5.1.3   default -
  • Full path: //OpenSplice/NetworkService/Channels/Channel[@default]
  • +
  • Full path: /NetworkService/Channels/Channel/default
  • Format: boolean
  • Default value: false
  • Required: false
  • -
    -

    6.5.1.4   enabled¶

    +
    +

    6.5.1.4   enabled¶

    This attribute toggles a channel on or off. Toggling a channel between enabled and disabled is a quick alternative for commenting out the corresponding lines in the configuration file.
      -
    • Full path: //OpenSplice/NetworkService/Channels/Channel[@enabled]
    • +
    • Full path: /NetworkService/Channels/Channel/enabled
    • Format: boolean
    • Default value: false
    • Required: true
    -
    -

    6.5.1.5   priority¶

    +
    +

    6.5.1.5   priority¶

    This attribute sets the transport priority of the channel. Messages sent to the network have a transport_priority @@ -7214,14 +6306,14 @@

    6.5.1.5   priority -
  • Full path: //OpenSplice/NetworkService/Channels/Channel[@priority]
  • +
  • Full path: /NetworkService/Channels/Channel/priority
  • Format: integer
  • Default value: 0
  • Required: false
  • -
    -

    6.5.1.6   PortNr¶

    +
    +

    6.5.1.6   PortNr¶

    This element specifies the port number used by the Channel. Messages for the channel are sent to the port number given. @@ -7229,29 +6321,27 @@

    6.5.1.6   PortNr -
  • Full path: //OpenSplice/NetworkService/Channels/Channel/PortNr
  • +
  • Full path: /NetworkService/Channels/Channel/PortNr
  • Format: integer
  • Default value: 53400
  • -
  • Valid values: 1 / 65535
  • Occurrences min-max: 1-1
  • -
    -

    6.5.1.7   FragmentSize¶

    +
    +

    6.5.1.7   FragmentSize¶

    The networking module will fragment large message into smaller fragments with size FragmentSize. These fragments are sent as datagrams to the UDP stack. OS-settings determine the maximum datagram size.
      -
    • Full path: //OpenSplice/NetworkService/Channels/Channel/FragmentSize
    • +
    • Full path: /NetworkService/Channels/Channel/FragmentSize
    • Default value: 1300
    • -
    • Valid values: 200 / 65535
    • Occurrences min-max: 0-1
    -
    -

    6.5.1.8   Resolution¶

    +
    +

    6.5.1.8   Resolution¶

    The resolution indicates the number of milliseconds that this channel sleeps between two consecutive resend or @@ -7261,15 +6351,14 @@

    6.5.1.8   Resolution

      -
    • Full path: //OpenSplice/NetworkService/Channels/Channel/Resolution
    • +
    • Full path: /NetworkService/Channels/Channel/Resolution
    • Format: integer
    • Default value: 10
    • -
    • Valid values: 1 / -
    • Occurrences min-max: 0-1
    -
    -

    6.5.1.9   AdminQueueSize¶

    +
    +

    6.5.1.9   AdminQueueSize¶

    For reliable channels the receiving side needs to keep the sending side informed about the received data and the received control messages.

    @@ -7278,15 +6367,14 @@

    6.5.1.9   AdminQueueSize

      -
    • Full path: //OpenSplice/NetworkService/Channels/Channel/AdminQueueSize
    • +
    • Full path: /NetworkService/Channels/Channel/AdminQueueSize
    • Format: integer
    • Default value: 4000
    • -
    • Valid values: 400 / -
    • Occurrences min-max: 0-1
    -
    -

    6.5.1.10   CompressionBufferSize¶

    +
    +

    6.5.1.10   CompressionBufferSize¶

    When compression on messages is enabled then the CompressionBufferSize specifies the initial size of the compression/decompression buffer. The compression buffer is used to store the messages @@ -7294,39 +6382,37 @@

    6.5.1.10   CompressionBufferSize -
  • Full path: //OpenSplice/NetworkService/Channels/Channel/CompressionBufferSize
  • +
  • Full path: /NetworkService/Channels/Channel/CompressionBufferSize
  • Format: integer
  • Default value: 131072
  • -
  • Valid values: 65536 / -
  • Occurrences min-max: 0-1
  • -
    -

    6.5.1.11   CompressionThreshold¶

    +
    +

    6.5.1.11   CompressionThreshold¶

    When compression on messages is enabled then the CompressionThreshold provides a threshold to start compressing the accumulated data and sending the compressed data on the network. The CompressionThreshold is used to estimate the size of the compressed messages.
      -
    • Full path: //OpenSplice/NetworkService/Channels/Channel/CompressionThreshold
    • +
    • Full path: /NetworkService/Channels/Channel/CompressionThreshold
    • Format: integer
    • Default value: 0
    • -
    • Valid values: 0 / -
    • Occurrences min-max: 0-1
    -
    -

    6.5.1.12   Sending¶

    +
    +

    6.5.1.12   Sending¶

    This element describes all properties for the transmitting side of the Channel.
      -
    • Full path: //OpenSplice/NetworkService/Channels/Channel/Sending
    • +
    • Full path: /NetworkService/Channels/Channel/Sending
    • Occurrences min-max: 0-1
    • -
    • Child elements: CrcCheck, QueueSize, MaxBurstSize, ThrottleLimit, ThrottleThreshold, MaxRetries, RecoveryFactor, DiffServField, DontRoute, TimeToLive, ReportInterval
    • +
    • Child elements: CrcCheck, QueueSize, MaxBurstSize, ThrottleLimit, ThrottleThreshold, MaxRetries, RecoveryFactor, DiffServField, DontRoute, TimeToLive
    -
    -
    6.5.1.12.1   CrcCheck¶
    +
    +
    6.5.1.12.1   CrcCheck¶

    In order to protect OpenSplice network packets from malicious attack the CrcCheck(cyclic redundancy check) configuration item has been added. CRCs are specifically designed to protect against common types of errors on communication channels. @@ -7335,14 +6421,14 @@

    6.5.1.12.1   CrcCheckWhen the sending side is enabled the network packet will contain a valid crc field.

      -
    • Full path: //OpenSplice/NetworkService/Channels/Channel/Sending/CrcCheck
    • +
    • Full path: /NetworkService/Channels/Channel/Sending/CrcCheck
    • Format: boolean
    • Default value: false
    • Occurrences min-max: 0-1
    -
    -
    6.5.1.12.2   QueueSize¶
    +
    +
    6.5.1.12.2   QueueSize¶
    This element specifies the number of messages the networking queue can contain. @@ -7352,28 +6438,26 @@
    6.5.1.12.2   QueueSize
      -
    • Full path: //OpenSplice/NetworkService/Channels/Channel/Sending/QueueSize
    • +
    • Full path: /NetworkService/Channels/Channel/Sending/QueueSize
    • Format: integer
    • Default value: 400
    • -
    • Valid values: 1 / -
    • Occurrences min-max: 0-1
    -
    -
    6.5.1.12.3   MaxBurstSize¶
    +
    +
    6.5.1.12.3   MaxBurstSize¶
    Amount in bytes to be sent at maximum every “Resolution” milliseconds. The default value is set to 1GB per resolution tick. This can be considered “unlimited” as this far exceeds the capacity of modern physical networks.
      -
    • Full path: //OpenSplice/NetworkService/Channels/Channel/Sending/MaxBurstSize
    • +
    • Full path: /NetworkService/Channels/Channel/Sending/MaxBurstSize
    • Default value: 1073741823
    • -
    • Valid values: 1024 / 1073741823
    • Occurrences min-max: 0-1
    -
    -
    6.5.1.12.4   ThrottleLimit¶
    +
    +
    6.5.1.12.4   ThrottleLimit¶
    Throttling will enable you to further limit (below MaxBurstSize) the amount of data that is sent every Resolution interval. This happens if one of the receiving nodes in the network @@ -7383,13 +6467,13 @@
    6.5.1.12.4   ThrottleLimit
      -
    • Full path: //OpenSplice/NetworkService/Channels/Channel/Sending/ThrottleLimit
    • +
    • Full path: /NetworkService/Channels/Channel/Sending/ThrottleLimit
    • Default value: 10240
    • Occurrences min-max: 0-1
    -
    -
    6.5.1.12.5   ThrottleThreshold¶
    +
    +
    6.5.1.12.5   ThrottleThreshold¶

    This is the number of unprocessed network fragments that a node will store before it will inform the other nodes in the network that it has trouble processing the incoming data. Those other nodes @@ -7399,39 +6483,36 @@

    6.5.1.12.5   ThrottleThreshold -
  • Full path: //OpenSplice/NetworkService/Channels/Channel/Sending/ThrottleThreshold
  • +
  • Full path: /NetworkService/Channels/Channel/Sending/ThrottleThreshold
  • Format: integer
  • Default value: 50
  • -
  • Valid values: 2 / -
  • Occurrences min-max: 0-1
  • -
    -
    6.5.1.12.6   MaxRetries¶
    +
    +
    6.5.1.12.6   MaxRetries¶
    The number of retransmissions the service has to execute before considering the addressed node as not responding.
      -
    • Full path: //OpenSplice/NetworkService/Channels/Channel/Sending/MaxRetries
    • +
    • Full path: /NetworkService/Channels/Channel/Sending/MaxRetries
    • Format: integer
    • Default value: 100
    • -
    • Valid values: 1 / -
    • Occurrences min-max: 0-1
    -
    -
    6.5.1.12.7   RecoveryFactor¶
    +
    +
    6.5.1.12.7   RecoveryFactor¶

    A lost message is resent after Resolution * RecoveryFactor milliseconds.

      -
    • Full path: //OpenSplice/NetworkService/Channels/Channel/Sending/RecoveryFactor
    • +
    • Full path: /NetworkService/Channels/Channel/Sending/RecoveryFactor
    • Format: integer
    • Default value: 3
    • -
    • Valid values: 2 / -
    • Occurrences min-max: 0-1
    -
    -
    6.5.1.12.8   DiffServField¶
    +
    +
    6.5.1.12.8   DiffServField¶

    This element describes the DiffServ setting the channel will apply to the networking messages. This parameter determines the value of the diffserv field of the IP version 4 packets send @@ -7447,72 +6528,70 @@

    6.5.1.12.8   DiffServField
      -
    • Full path: //OpenSplice/NetworkService/Channels/Channel/Sending/DiffServField
    • +
    • Full path: /NetworkService/Channels/Channel/Sending/DiffServField
    • Format: integer
    • Default value: 0
    • -
    • Valid values: 0 / 255
    • Occurrences min-max: 0-1
    -
    -
    6.5.1.12.9   DontRoute¶
    +
    +
    6.5.1.12.9   DontRoute¶
    The IP DONTROUTE
    socket option is set to the value specified.
      -
    • Full path: //OpenSplice/NetworkService/Channels/Channel/Sending/DontRoute
    • +
    • Full path: /NetworkService/Channels/Channel/Sending/DontRoute
    • Format: boolean
    • Default value: True
    • Valid values: True, False
    • Occurrences min-max: 0-1
    -
    -
    6.5.1.12.10   TimeToLive¶
    +
    +
    6.5.1.12.10   TimeToLive¶
    For each UDP packet sent out, the IP Time To Live
    header value is set to the value specified.
      -
    • Full path: //OpenSplice/NetworkService/Channels/Channel/Sending/TimeToLive
    • +
    • Full path: /NetworkService/Channels/Channel/Sending/TimeToLive
    • Format: integer
    • -
    • Default value: 1
    • -
    • Valid values: 1 / 255
    • +
    • Default value: 0
    • Occurrences min-max: 0-1
    -
    -
    6.5.1.12.11   Scheduling¶
    +
    +
    6.5.1.12.11   Scheduling¶
    This element specifies the scheduling policies used to control the transmitter thread of the current Channel.
      -
    • Full path: //OpenSplice/NetworkService/Channels/Channel/Sending/Scheduling
    • +
    • Full path: /NetworkService/Channels/Channel/Sending/Scheduling
    • Occurrences min-max: 0-1
    • Child elements: Priority, Class
    -
    -
    6.5.1.12.11.1   Priority¶
    +
    +
    6.5.1.12.11.1   Priority¶
    This element specifies the thread priority that will be used by the transmitter thread. Only priorities that are supported by the underlying operating system can be assigned to this element. The user may need special privileges from the underlying operating system to be able to assign some of the privileged priorities.
      -
    • Full path: //OpenSplice/NetworkService/Channels/Channel/Sending/Scheduling/Priority
    • +
    • Full path: /NetworkService/Channels/Channel/Sending/Scheduling/Priority
    • Format: integer
    • Default value: 0
    • Occurrences min-max: 1-1
    • Optional attributes: priority_kind
    -
    -6.5.1.12.11.1.1   priority_kind¶ +
    +6.5.1.12.11.1.1   priority_kind¶
    This attribute specifies whether the specified Priority is a relative or absolute priority.
      -
    • Full path: //OpenSplice/NetworkService/Channels/Channel/Sending/Scheduling/Priority[@priority_kind]
    • +
    • Full path: /NetworkService/Channels/Channel/Sending/Scheduling/Priority/priority_kind
    • Format: enumeration
    • Default value: Relative
    • Valid values: Relative, Absolute
    • @@ -7520,14 +6599,14 @@
      6.5.1.12.11.1   Priority
    -
    -
    6.5.1.12.11.2   Class¶
    +
    +
    6.5.1.12.11.2   Class¶
    This element specifies the thread scheduling class that will be used by the transmitter thread. The user may need the appropriate privileges from the underlying operating system to be able to assign some of the privileged scheduling classes.
      -
    • Full path: //OpenSplice/NetworkService/Channels/Channel/Sending/Scheduling/Class
    • +
    • Full path: /NetworkService/Channels/Channel/Sending/Scheduling/Class
    • Format: enumeration
    • Default value: Default
    • Valid values: Timeshare, Realtime, Default
    • @@ -7536,18 +6615,18 @@
      6.5.1.12.11.2   Class
    -
    -

    6.5.1.13   Receiving¶

    +
    +

    6.5.1.13   Receiving¶

    This element describes all properties for the receiving side of the Channel.
      -
    • Full path: //OpenSplice/NetworkService/Channels/Channel/Receiving
    • +
    • Full path: /NetworkService/Channels/Channel/Receiving
    • Occurrences min-max: 0-1
    • Child elements: CrcCheck, ReceiveBufferSize, DefragBufferSize, MaxReliabBacklog, PacketRetentionPeriod, ReliabilityRecoveryPeriod
    -
    -
    6.5.1.13.1   CrcCheck¶
    +
    +
    6.5.1.13.1   CrcCheck¶

    In order to protect OpenSplice network packets from malicious attack the CrcCheck(cyclic redundancy check) configuration item has been added. CRCs are specifically designed to protect against common types of errors on communication channels. @@ -7556,37 +6635,36 @@

    6.5.1.13.1   CrcCheckWhen the receiving side is enabled only network packets that contain a valid crc field are accepted.

      -
    • Full path: //OpenSplice/NetworkService/Channels/Channel/Receiving/CrcCheck
    • +
    • Full path: /NetworkService/Channels/Channel/Receiving/CrcCheck
    • Format: boolean
    • Default value: false
    • Occurrences min-max: 0-1
    -
    -
    6.5.1.13.2   ReceiveBufferSize¶
    +
    +
    6.5.1.13.2   ReceiveBufferSize¶
    The UDP receive buffer of the best effort channel socket is set to the value given. If many message are lost, the receive buffer size has to be increased.
      -
    • Full path: //OpenSplice/NetworkService/Channels/Channel/Receiving/ReceiveBufferSize
    • +
    • Full path: /NetworkService/Channels/Channel/Receiving/ReceiveBufferSize
    • Default value: 1000000
    • -
    • Valid values: 1024 / -
    • Occurrences min-max: 0-1
    -
    -
    6.5.1.13.3   Scheduling¶
    +
    +
    6.5.1.13.3   Scheduling¶
    This element specifies the scheduling policies used to control the receiver thread of the current Channel.
      -
    • Full path: //OpenSplice/NetworkService/Channels/Channel/Receiving/Scheduling
    • +
    • Full path: /NetworkService/Channels/Channel/Receiving/Scheduling
    • Occurrences min-max: 0-1
    • -
    • Child elements: Priority, Class, ReportInterval
    • +
    • Child elements: Priority, Class
    -
    -
    6.5.1.13.3.1   Priority¶
    +
    +
    6.5.1.13.3.1   Priority¶
    This element specifies the thread priority that will be used by the receiver thread. Only priorities that are supported by the underlying operating system @@ -7594,19 +6672,19 @@
    6.5.1.13.3.1   Priority
      -
    • Full path: //OpenSplice/NetworkService/Channels/Channel/Receiving/Scheduling/Priority
    • +
    • Full path: /NetworkService/Channels/Channel/Receiving/Scheduling/Priority
    • Format: integer
    • Default value: 0
    • Occurrences min-max: 1-1
    • Optional attributes: priority_kind
    -
    -6.5.1.13.3.1.1   priority_kind¶ +
    +6.5.1.13.3.1.1   priority_kind¶
    This attribute specifies whether the specified Priority is a relative or absolute priority.
      -
    • Full path: //OpenSplice/NetworkService/Channels/Channel/Receiving/Scheduling/Priority[@priority_kind]
    • +
    • Full path: /NetworkService/Channels/Channel/Receiving/Scheduling/Priority/priority_kind
    • Format: enumeration
    • Default value: Relative
    • Valid values: Relative, Absolute
    • @@ -7614,14 +6692,14 @@
      6.5.1.13.3.1   Priority
    -
    -
    6.5.1.13.3.2   Class¶
    +
    +
    6.5.1.13.3.2   Class¶
    This element specifies the thread scheduling class that will be used by the receiver thread. The user may need the appropriate privileges from the underlying operating system to be able to assign some of the privileged scheduling classes.
      -
    • Full path: //OpenSplice/NetworkService/Channels/Channel/Receiving/Scheduling/Class
    • +
    • Full path: /NetworkService/Channels/Channel/Receiving/Scheduling/Class
    • Format: enumeration
    • Default value: Default
    • Valid values: Timeshare, Realtime, Default
    • @@ -7629,58 +6707,56 @@
      6.5.1.13.3.2   Class
    -
    -
    6.5.1.13.4   DefragBufferSize¶
    +
    +
    6.5.1.13.4   DefragBufferSize¶
    The maximum number of Fragment buffers that will be allocated for this channel. These buffers are used to store incoming fragments waiting to be processed, as well as fragments that are being processed.
      -
    • Full path: //OpenSplice/NetworkService/Channels/Channel/Receiving/DefragBufferSize
    • +
    • Full path: /NetworkService/Channels/Channel/Receiving/DefragBufferSize
    • Default value: 5000
    • -
    • Valid values: 500 / -
    • Occurrences min-max: 0-1
    -
    -
    6.5.1.13.5   SMPOptimization¶
    +
    +
    6.5.1.13.5   SMPOptimization¶
    This option will distribute the processing done for incoming fragements over multiple threads, which will lead to an improved throughput on SMP nodes.
      -
    • Full path: //OpenSplice/NetworkService/Channels/Channel/Receiving/SMPOptimization
    • +
    • Full path: /NetworkService/Channels/Channel/Receiving/SMPOptimization
    • Occurrences min-max: 0-1
    • Required attributes: enabled
    -
    -
    6.5.1.13.5.1   enabled¶
    +
    +
    6.5.1.13.5.1   enabled¶
    This attribute toggles the Optimization on or off.
      -
    • Full path: //OpenSplice/NetworkService/Channels/Channel/Receiving/SMPOptimization[@enabled]
    • +
    • Full path: /NetworkService/Channels/Channel/Receiving/SMPOptimization/enabled
    • Format: boolean
    • Default value: true
    • Required: true
    -
    -
    6.5.1.13.6   MaxReliabBacklog¶
    +
    +
    6.5.1.13.6   MaxReliabBacklog¶
    This is a lower limit to the DefragBufferSize that specifies the number of received fragments from a single remote node allocated for the purpose of order preservation because an earlier fragment from that remote node is missing. If this number is exceeded, then that particular remote node that didn’t resend the missing fragent in time is considered dead for this channel.
      -
    • Full path: //OpenSplice/NetworkService/Channels/Channel/Receiving/MaxReliabBacklog
    • +
    • Full path: /NetworkService/Channels/Channel/Receiving/MaxReliabBacklog
    • Format: integer
    • Default value: 1000
    • -
    • Valid values: 100 / -
    • Occurrences min-max: 0-1
    -
    -
    6.5.1.13.7   PacketRetentionPeriod¶
    +
    +
    6.5.1.13.7   PacketRetentionPeriod¶
    This element specifies the number of milliseconds received packets are retained by the network service for its so-called “reliability-under-publisher-crash” extended reliability @@ -7695,15 +6771,14 @@
    6.5.1.13.7   PacketRetentionPeriod
      -
    • Full path: //OpenSplice/NetworkService/Channels/Channel/Receiving/PacketRetentionPeriod
    • +
    • Full path: /NetworkService/Channels/Channel/Receiving/PacketRetentionPeriod
    • Format: integer
    • Default value: 0
    • -
    • Valid values: 0 / -
    • Occurrences min-max: 0-1
    -
    -
    6.5.1.13.8   ReliabilityRecoveryPeriod¶
    +
    +
    6.5.1.13.8   ReliabilityRecoveryPeriod¶
    This element specifies a timeout period (in milliseconds) for the alignment phase of the extended reliability protocol. It only has an effect when the related @@ -7714,16 +6789,15 @@
    6.5.1.13.8   ReliabilityRecoveryPeriod
      -
    • Full path: //OpenSplice/NetworkService/Channels/Channel/Receiving/ReliabilityRecoveryPeriod
    • +
    • Full path: /NetworkService/Channels/Channel/Receiving/ReliabilityRecoveryPeriod
    • Format: integer
    • Default value: 1000
    • -
    • Valid values: 0 / -
    • Occurrences min-max: 0-1
    -
    -

    6.5.1.14   AllowedPorts¶

    +
    +

    6.5.1.14   AllowedPorts¶

    AllowedPorts specifies the port numbers available for the network service to be used by the reliable network channels. The network channel is configured with a unique port number. However @@ -7739,14 +6813,14 @@

    6.5.1.14   AllowedPorts

      -
    • Full path: //OpenSplice/NetworkService/Channels/Channel/AllowedPorts
    • +
    • Full path: /NetworkService/Channels/Channel/AllowedPorts
    • Format: string
    • Occurrences min-max: 0-1
    -
    -

    6.5.2   AllowedPorts¶

    +
    +

    6.5.2   AllowedPorts¶

    AllowedPorts specifies the port numbers available for the network service to be used by the reliable network channels. The network channel is configured with a unique port number. However @@ -7762,61 +6836,44 @@

    6.5.2   AllowedPorts

      -
    • Full path: //OpenSplice/NetworkService/Channels/AllowedPorts
    • +
    • Full path: /NetworkService/Channels/AllowedPorts
    • Format: string
    • Occurrences min-max: 0-1
    -
    -

    6.6   Discovery¶

    -

    This element controls various parameters of the Network Services Discovery -mechanism. -Discovery reduces the Network Service configuration and minimizes network -traffic. Without Discovery, data is always sent to the network and all Networking -Services need to configure the addresses (This can be multicast addresses and/or -uni-cast addresses, especially in an uni-cast environment with many nodes the -configuration of the Network Service’s lists can be cumbersome.) -of all Network Services they need to -communicate with. With Discovery, data is only sent to where interest exists and -connectivity is discovered based on a minimum configuration (Only a subset of -addresses of nodes are initially specified, these nodes are assumed to be -available as a discovery source, all nodes will make themselves known to these discovery -nodes and thereby making its existence and address available for all other nodes) (see Element ProbeList). -Discovery is based on a heartbeat mechanism to advertize the service’s availability. -The Network Service starts by announcing its existence by sending heartbeats to the -Global Partition (The Global Partition contains all the addresses that the Network Service communicate -with) which is initially filled with the addresses specified in the -ProbeList; remote Network Services receiving the heartbeat will start sending -heartbeats in return. All Network Services that discover new heartbeats will -automatically request address information that match their Scope (see Attribute Scope) -from the Network Service sending the -heartbeat, and add the retrieved address information to their Global Partition. -Currently only uni-cast addresses are exchanged. Addresses are removed from the -Global Partition when a remote Network Service stops and heartbeats are no longer -received.

    -
      -
    • Full path: //OpenSplice/NetworkService/Discovery
    • +
      +

      6.6   Discovery¶

      +
      +
      This element is used to configure the various parameters of the Discovery Channel, +which is used to discover all relevant participating entities in the current Domain. +The purpose of the discovery process is to build-up and maintain a notion of all +relevant active nodes within the domain. The relevance of discovered remote nodes +can be defined statically (by definition of the so-called Global Partition) and/or +can be dynamically expanded and maintained by the dynamic-discovery process driven +by the node’s Role and Scope.
      +
        +
      • Full path: /NetworkService/Discovery
      • Occurrences min-max: 0-1
      • Child elements: PortNr, ProbeList
      • Optional attributes: enabled, Scope
      -
      -

      6.6.1   enabled¶

      +
      +

      6.6.1   enabled¶

      This element can be used to enable or disable the Discovery Channel. In case the Discovery Channel is disabled, entities will only detect each others presence implicitly once messages are received for the first time.
        -
      • Full path: //OpenSplice/NetworkService/Discovery[@enabled]
      • +
      • Full path: /NetworkService/Discovery/enabled
      • Format: boolean
      • Default value: true
      • Occurrences min-max: 0-1
      • Required: false
      -
      -

      6.6.2   Scope¶

      +
      +

      6.6.2   Scope¶

      This attribute controls the dynamic discovery behaviour of this node within the current Domain. If it is not set, dynamic discovery will be disabled and the networking service will only @@ -7828,26 +6885,25 @@

      6.6.2   Scope -
    • Full path: //OpenSplice/NetworkService/Discovery[@Scope]
    • +
    • Full path: /NetworkService/Discovery/Scope
    • Format: string
    • Occurrences min-max: 0-1
    • Required: false
    -
    -

    6.6.3   PortNr¶

    +
    +

    6.6.3   PortNr¶

    This element specifies the Port number used by the Discovery Channel.
      -
    • Full path: //OpenSplice/NetworkService/Discovery/PortNr
    • +
    • Full path: /NetworkService/Discovery/PortNr
    • Format: integer
    • Default value: 3369
    • -
    • Valid values: 1 / 65536
    • Occurrences min-max: 1-1
    -
    -

    6.6.4   ProbeList¶

    +
    +

    6.6.4   ProbeList¶

    This element contains the addresses of the nodes that will be contacted to retrieve an initial list of participating nodes in the current domain that match the specified Scope. Multiple @@ -7855,23 +6911,23 @@

    6.6.4   ProbeList -
  • Full path: //OpenSplice/NetworkService/Discovery/ProbeList
  • +
  • Full path: /NetworkService/Discovery/ProbeList
  • Format: string
  • Occurrences min-max: 0-1
  • -
    -

    6.6.5   Sending¶

    +
    +

    6.6.5   Sending¶

    This element describes all properties for the transmitting side of the Discovery Channel.
      -
    • Full path: //OpenSplice/NetworkService/Discovery/Sending
    • +
    • Full path: /NetworkService/Discovery/Sending
    • Occurrences min-max: 0-1
    • Child elements: CrcCheck, DiffServField, DontRoute, TimeToLive, Interval, SafetyFactor, SalvoSize
    -
    -

    6.6.5.1   CrcCheck¶

    +
    +

    6.6.5.1   CrcCheck¶

    In order to protect OpenSplice network packets from malicious attack the CrcCheck(cyclic redundancy check) configuration item has been added. CRCs are specifically designed to protect against common types of errors on communication channels. @@ -7880,14 +6936,14 @@

    6.6.5.1   CrcCheck -
  • Full path: //OpenSplice/NetworkService/Discovery/Sending/CrcCheck
  • +
  • Full path: /NetworkService/Discovery/Sending/CrcCheck
  • Format: boolean
  • Default value: false
  • Occurrences min-max: 0-1
  • -
    -

    6.6.5.2   DiffServField¶

    +
    +

    6.6.5.2   DiffServField¶

    This element describes the DiffServ setting the channel will apply to the networking messages. This parameter determines the value of the diffserv field of the IP version 4 packets send @@ -7903,72 +6959,70 @@

    6.6.5.2   DiffServField

      -
    • Full path: //OpenSplice/NetworkService/Discovery/Sending/DiffServField
    • +
    • Full path: /NetworkService/Discovery/Sending/DiffServField
    • Format: integer
    • Default value: 0
    • -
    • Valid values: 0 / 255
    • Occurrences min-max: 0-1
    -
    -

    6.6.5.3   DontRoute¶

    +
    +

    6.6.5.3   DontRoute¶

    The IP DONTROUTE
    socket option is set to the value specified.
      -
    • Full path: //OpenSplice/NetworkService/Discovery/Sending/DontRoute
    • +
    • Full path: /NetworkService/Discovery/Sending/DontRoute
    • Format: boolean
    • Default value: True
    • Valid values: True, False
    • Occurrences min-max: 0-1
    -
    -

    6.6.5.4   TimeToLive¶

    +
    +

    6.6.5.4   TimeToLive¶

    For each UDP packet sent out, the IP Time To Live
    header value is set to the value specified.
      -
    • Full path: //OpenSplice/NetworkService/Discovery/Sending/TimeToLive
    • +
    • Full path: /NetworkService/Discovery/Sending/TimeToLive
    • Format: integer
    • -
    • Default value: 1
    • -
    • Valid values: 1 / 255
    • +
    • Default value: 0
    • Occurrences min-max: 0-1
    -
    -

    6.6.5.5   Scheduling¶

    +
    +

    6.6.5.5   Scheduling¶

    This element specifies the scheduling policies used to control the transmitter thread of the Discovery Channel.
      -
    • Full path: //OpenSplice/NetworkService/Discovery/Sending/Scheduling
    • +
    • Full path: /NetworkService/Discovery/Sending/Scheduling
    • Occurrences min-max: 0-1
    • Child elements: Priority, Class
    -
    -
    6.6.5.5.1   Priority¶
    +
    +
    6.6.5.5.1   Priority¶
    This element specifies the thread priority that will be used by the transmitter thread of the Discovery Channel. Only priorities that are supported by the underlying operating system can be assigned to this element. The user may need special privileges from the underlying operating system to be able to assign some of the privileged priorities.
      -
    • Full path: //OpenSplice/NetworkService/Discovery/Sending/Scheduling/Priority
    • +
    • Full path: /NetworkService/Discovery/Sending/Scheduling/Priority
    • Format: integer
    • Default value: 0
    • Occurrences min-max: 1-1
    • Optional attributes: priority_kind
    -
    -
    6.6.5.5.1.1   priority_kind¶
    +
    +
    6.6.5.5.1.1   priority_kind¶
    This attribute specifies whether the specified Priority is a relative or absolute priority.
      -
    • Full path: //OpenSplice/NetworkService/Discovery/Sending/Scheduling/Priority[@priority_kind]
    • +
    • Full path: /NetworkService/Discovery/Sending/Scheduling/Priority/priority_kind
    • Format: enumeration
    • Default value: Relative
    • Valid values: Relative, Absolute
    • @@ -7976,14 +7030,14 @@
      6.6.5.5.1.1   priority_kind -
      6.6.5.5.2   Class¶
      +
      +
      6.6.5.5.2   Class¶
      This element specifies the thread scheduling class that will be used by the transmitter thread of the Discovery Channel. The user may need the appropriate privileges from the underlying operating system to be able to assign some of the privileged scheduling classes.
        -
      • Full path: //OpenSplice/NetworkService/Discovery/Sending/Scheduling/Class
      • +
      • Full path: /NetworkService/Discovery/Sending/Scheduling/Class
      • Format: enumeration
      • Default value: Default
      • Valid values: Timeshare, Realtime, Default
      • @@ -7991,65 +7045,52 @@
        6.6.5.5.2   Class -

        6.6.5.6   Interval¶

        +
        +

        6.6.5.6   Interval¶

        This element describes the interval(in milliseconds) at which remote nodes will expect heartbeats from this node.
          -
        • Full path: //OpenSplice/NetworkService/Discovery/Sending/Interval
        • +
        • Full path: /NetworkService/Discovery/Sending/Interval
        • Format: integer
        • -
        • Dimension: milliseconds
        • Default value: 333
        • -
        • Valid values: 10 / -
        • Occurrences min-max: 0-1
        -
        -

        6.6.5.7   SafetyFactor¶

        -

        The SafetyFactor is used to set a margin (< 1) on the expected heartbeat interval. -The actual interval at which the heartbeats are sent is the specified interval -multiplied by this factor, so the actual interval will be equal to or smaller than the -specified value. This can be used to avoid timing issues such as those caused by -typical scheduling or network latencies.

        -
          -
        • Full path: //OpenSplice/NetworkService/Discovery/Sending/SafetyFactor
        • +
          +

          6.6.5.7   SafetyFactor¶

          +
          +
          The SafetyFactor is used to set a margin on the discovery sending. This avoids tight timing issues.
          +
            +
          • Full path: /NetworkService/Discovery/Sending/SafetyFactor
          • Default value: 0.9
          • -
          • Valid values: 0.2 / 1.0
          • Occurrences min-max: 0-1
          -
          -

          6.6.5.8   SalvoSize¶

          +
          +

          6.6.5.8   SalvoSize¶

          -
          The reactivity of discovery depends on the heartbeat frequency, a higher heartbeat -frequency gives a faster reactivity but also imposes a higher network load, which is -not desirable. Ideally the heartbeat frequency must be kept as low as possible but -from a startup (and shutdown) perspective a high reactivity is often desired. So the -Network Service has the capability to send an additional salvo of heartbeats at -startup and shutdown at ten times the normal heartbeat speed to maximize reactivity -during these phases without requiring a continuous high heartbeat frequency. The -SalvoSize sets the number of messages to send during these phases.
          +
          During starting and stopping, discovery messages are sent at higher frequency. This SalvoSize sets +the number of messages to send during these phases.
      -
    • Full path: //OpenSplice/NetworkService/Discovery/Sending/SalvoSize
    • +
    • Full path: /NetworkService/Discovery/Sending/SalvoSize
    • Format: integer
    • Default value: 3
    • -
    • Valid values: 1 / -
    • Occurrences min-max: 0-1
    -
    -

    6.6.6   Receiving¶

    +
    +

    6.6.6   Receiving¶

    This element describes all properties for the receiving side of the Discovery Channel.
      -
    • Full path: //OpenSplice/NetworkService/Discovery/Receiving
    • +
    • Full path: /NetworkService/Discovery/Receiving
    • Occurrences min-max: 0-1
    • Child elements: CrcCheck, DeathDetectionCount, ReceiveBufferSize
    -
    -

    6.6.6.1   CrcCheck¶

    +
    +

    6.6.6.1   CrcCheck¶

    In order to protect OpenSplice network packets from malicious attack the CrcCheck(cyclic redundancy check) configuration item has been added. CRCs are specifically designed to protect against common types of errors on communication channels. @@ -8058,43 +7099,43 @@

    6.6.6.1   CrcCheck -
  • Full path: //OpenSplice/NetworkService/Discovery/Receiving/CrcCheck
  • +
  • Full path: /NetworkService/Discovery/Receiving/CrcCheck
  • Format: boolean
  • Default value: false
  • Occurrences min-max: 0-1
  • -
    -

    6.6.6.2   Scheduling¶

    +
    +

    6.6.6.2   Scheduling¶

    This element specifies the scheduling policies used to control the receiver thread of the Discovery Channel.
      -
    • Full path: //OpenSplice/NetworkService/Discovery/Receiving/Scheduling
    • +
    • Full path: /NetworkService/Discovery/Receiving/Scheduling
    • Occurrences min-max: 0-1
    • Child elements: Priority, Class
    -
    -
    6.6.6.2.1   Priority¶
    +
    +
    6.6.6.2.1   Priority¶
    This element specifies the thread priority that will be used by the receiver thread of the Discovery Channel. Only priorities that are supported by the underlying operating system can be assigned to this element. The user may need special privileges from the underlying operating system to be able to assign some of the privileged priorities.
      -
    • Full path: //OpenSplice/NetworkService/Discovery/Receiving/Scheduling/Priority
    • +
    • Full path: /NetworkService/Discovery/Receiving/Scheduling/Priority
    • Format: integer
    • Default value: 0
    • Occurrences min-max: 1-1
    • Optional attributes: priority_kind
    -
    -
    6.6.6.2.1.1   priority_kind¶
    +
    +
    6.6.6.2.1.1   priority_kind¶
    This attribute specifies whether the specified Priority is a relative or absolute priority.
      -
    • Full path: //OpenSplice/NetworkService/Discovery/Receiving/Scheduling/Priority[@priority_kind]
    • +
    • Full path: /NetworkService/Discovery/Receiving/Scheduling/Priority/priority_kind
    • Format: enumeration
    • Default value: Relative
    • Valid values: Relative, Absolute
    • @@ -8102,14 +7143,14 @@
      6.6.6.2.1.1   priority_kind -
      6.6.6.2.2   Class¶
      +
      +
      6.6.6.2.2   Class¶
      This element specifies the thread scheduling class that will be used by the receiver thread of the Discovery Channel. The user may need the appropriate privileges from the underlying operating system to be able to assign some of the privileged scheduling classes.
        -
      • Full path: //OpenSplice/NetworkService/Discovery/Receiving/Scheduling/Class
      • +
      • Full path: /NetworkService/Discovery/Receiving/Scheduling/Class
      • Format: enumeration
      • Default value: Default
      • Valid values: Timeshare, Realtime, Default
      • @@ -8117,271 +7158,245 @@
        6.6.6.2.2   Class -

        6.6.6.3   DeathDetectionCount¶

        +
        +

        6.6.6.3   DeathDetectionCount¶

        This element specifies how often a heartbeat from a remote node must miss its Interval before that remote node is considered dead.
          -
        • Full path: //OpenSplice/NetworkService/Discovery/Receiving/DeathDetectionCount
        • +
        • Full path: /NetworkService/Discovery/Receiving/DeathDetectionCount
        • Format: integer
        • Default value: 6
        • -
        • Valid values: 1 / -
        • Occurrences min-max: 0-1
        -
        -

        6.6.6.4   ReceiveBufferSize¶

        +
        +

        6.6.6.4   ReceiveBufferSize¶

        The UDP receive buffer of the Discovery Channel socket is set to the value given. If many message are lost, the receive buffer size has to be increased.
          -
        • Full path: //OpenSplice/NetworkService/Discovery/Receiving/ReceiveBufferSize
        • -
        • Dimension: bytes
        • +
        • Full path: /NetworkService/Discovery/Receiving/ReceiveBufferSize
        • Default value: 1000000
        • -
        • Valid values: 1 / -
        • Occurrences min-max: 0-1
      -
      -

      6.7   Tracing¶

      +
      +

      6.7   Tracing¶

      This element controls the amount and type of information that is written into the tracing log by the Networking Service. This is useful to track the Networking Service during application development. In the runtime system it should be turned off.
        -
      • Full path: //OpenSplice/NetworkService/Tracing
      • +
      • Full path: /NetworkService/Tracing
      • Occurrences min-max: 0-1
      • Child elements: OutputFile, Timestamps
      • -
      • Optional attributes: enabled
      • -
      -
      -

      6.7.1   enabled¶

      -
      -
      This attribute controls whether the tracing option is enabled or not.
      -
        -
      • Full path: //OpenSplice/NetworkService/Tracing[@enabled]
      • -
      • Format: boolean
      • -
      • Default value: true
      • -
      • Required: false
      -
      -
      -

      6.7.2   OutputFile¶

      +
      +

      6.7.1   OutputFile¶

      This option specifies where the logging is printed to. Note that “stdout” is considered a legal value that represents “standard out”. The default value is an empty string, indicating that the tracing log will be written to standard out.
        -
      • Full path: //OpenSplice/NetworkService/Tracing/OutputFile
      • +
      • Full path: /NetworkService/Tracing/OutputFile
      • Format: string
      • Default value: networking.log
      • Occurrences min-max: 1-1
      -
      -

      6.7.3   Timestamps¶

      +
      +

      6.7.2   Timestamps¶

      This element specifies whether the logging must contain timestamps.
        -
      • Full path: //OpenSplice/NetworkService/Tracing/Timestamps
      • +
      • Full path: /NetworkService/Tracing/Timestamps
      • Format: boolean
      • Default value: true
      • -
      • Occurrences min-max: 0-1
      • +
      • Occurrences min-max: 1-1
      • Optional attributes: absolute
      -
      -

      6.7.3.1   absolute¶

      +
      +

      6.7.2.1   absolute¶

      This attribute specifies whether the timestamps are absolute or relative to the startup time of the service.
        -
      • Full path: //OpenSplice/NetworkService/Tracing/Timestamps[@absolute]
      • +
      • Full path: /NetworkService/Tracing/Timestamps/absolute
      • Format: boolean
      • Default value: true
      • Required: false
      -
      -

      6.7.4   Categories¶

      +
      +

      6.7.3   Categories¶

      This element contains the logging properties for various networking categories.
        -
      • Full path: //OpenSplice/NetworkService/Tracing/Categories
      • +
      • Full path: /NetworkService/Tracing/Categories
      • Occurrences min-max: 1-1
      • Child elements: Default, Configuration, Construction, Destruction, Mainloop, Groups, Send, Receive, Throttling, Test, Discovery
      -
      -

      6.7.4.1   Default¶

      +
      +

      6.7.3.1   Default¶

      This element specifies the tracing level used for categories that are not explicitly specified. Level 0 indicates no tracing, level 6 indicates the most detailed level of tracing.
        -
      • Full path: //OpenSplice/NetworkService/Tracing/Categories/Default
      • +
      • Full path: /NetworkService/Tracing/Categories/Default
      • Format: integer
      • Default value: 0
      • -
      • Valid values: 0 / 6
      • -
      • Occurrences min-max: 0-1
      • +
      • Occurrences min-max: 1-1
      -
      -

      6.7.4.2   Configuration¶

      +
      +

      6.7.3.2   Configuration¶

      This element specifies the tracing level for the Configuration category. This includes the processing of all NetworkService parameters in the config file. Level 0 indicates no tracing, level 6 indicates the most detailed level of tracing.
        -
      • Full path: //OpenSplice/NetworkService/Tracing/Categories/Configuration
      • +
      • Full path: /NetworkService/Tracing/Categories/Configuration
      • Format: integer
      • Default value: 0
      • -
      • Valid values: 0 / 6
      • Occurrences min-max: 0-1
      -
      -

      6.7.4.3   Construction¶

      +
      +

      6.7.3.3   Construction¶

      This element specifies the tracing level for the Construction category. This includes the creation of all internal processing entities. Level 0 indicates no tracing, level 6 indicates the most detailed level of tracing.
        -
      • Full path: //OpenSplice/NetworkService/Tracing/Categories/Construction
      • +
      • Full path: /NetworkService/Tracing/Categories/Construction
      • Format: integer
      • Default value: 0
      • -
      • Valid values: 0 / 6
      • Occurrences min-max: 0-1
      -
      -

      6.7.4.4   Destruction¶

      +
      +

      6.7.3.4   Destruction¶

      This element specifies the tracing level for the Destruction category. This includes the destruction of all internal processing entities when the NetworkService terminates. Level 0 indicates no tracing, level 6 indicates the most detailed level of tracing.
        -
      • Full path: //OpenSplice/NetworkService/Tracing/Categories/Destruction
      • +
      • Full path: /NetworkService/Tracing/Categories/Destruction
      • Format: integer
      • Default value: 0
      • -
      • Valid values: 0 / 6
      • Occurrences min-max: 0-1
      -
      -

      6.7.4.5   Mainloop¶

      +
      +

      6.7.3.5   Mainloop¶

      This element specifies the tracing level for the Mainloop category. This includes information about each of the threads spawned by the NetworkService. Level 0 indicates no tracing, level 6 indicates the most detailed level of tracing.
        -
      • Full path: //OpenSplice/NetworkService/Tracing/Categories/Mainloop
      • +
      • Full path: /NetworkService/Tracing/Categories/Mainloop
      • Format: integer
      • Default value: 0
      • -
      • Valid values: 0 / 6
      • Occurrences min-max: 0-1
      -
      -

      6.7.4.6   Groups¶

      +
      +

      6.7.3.6   Groups¶

      This element specifies the tracing level for the Groups category. This includes the management of local groups (partition-topic combinations). Level 0 indicates no tracing, level 6 indicates the most detailed level of tracing.
        -
      • Full path: //OpenSplice/NetworkService/Tracing/Categories/Groups
      • +
      • Full path: /NetworkService/Tracing/Categories/Groups
      • Format: integer
      • Default value: 0
      • -
      • Valid values: 0 / 6
      • Occurrences min-max: 0-1
      -
      -

      6.7.4.7   Send¶

      +
      +

      6.7.3.7   Send¶

      This element specifies the tracing level for the Send category. This includes information about outgoing data. Level 0 indicates no tracing, level 6 indicates the most detailed level of tracing.
        -
      • Full path: //OpenSplice/NetworkService/Tracing/Categories/Send
      • +
      • Full path: /NetworkService/Tracing/Categories/Send
      • Format: integer
      • Default value: 0
      • -
      • Valid values: 0 / 6
      • Occurrences min-max: 0-1
      -
      -

      6.7.4.8   Receive¶

      +
      +

      6.7.3.8   Receive¶

      This element specifies the tracing level for the Receive category. This includes information about incoming data. Level 0 indicates no tracing, level 6 indicates the most detailed level of tracing.
        -
      • Full path: //OpenSplice/NetworkService/Tracing/Categories/Receive
      • +
      • Full path: /NetworkService/Tracing/Categories/Receive
      • Format: integer
      • Default value: 0
      • -
      • Valid values: 0 / 6
      • Occurrences min-max: 0-1
      -
      -

      6.7.4.9   Throttling¶

      +
      +

      6.7.3.9   Throttling¶

      This element specifies the tracing level for the Throttling category. This includes information about throttling. Level 0 indicates no tracing, level 6 indicates the most detailed level of tracing.
        -
      • Full path: //OpenSplice/NetworkService/Tracing/Categories/Throttling
      • +
      • Full path: /NetworkService/Tracing/Categories/Throttling
      • Format: integer
      • Default value: 0
      • -
      • Valid values: 0 / 6
      • Occurrences min-max: 0-1
      -
      -

      6.7.4.10   Test¶

      +
      +

      6.7.3.10   Test¶

      This element specifies the tracing level for the Test category. This is a reserved category used for testing purposes. Level 0 indicates no tracing, level 6 indicates the most detailed level of tracing.
        -
      • Full path: //OpenSplice/NetworkService/Tracing/Categories/Test
      • +
      • Full path: /NetworkService/Tracing/Categories/Test
      • Format: integer
      • Default value: 0
      • -
      • Valid values: 0 / 6
      • Occurrences min-max: 0-1
      -
      -

      6.7.4.11   Discovery¶

      +
      +

      6.7.3.11   Discovery¶

      This element specifies the tracing level for the Discovery category. This includes all activity related to the discovery channel. Level 0 indicates no tracing, level 6 indicates the most detailed level of tracing.
        -
      • Full path: //OpenSplice/NetworkService/Tracing/Categories/Discovery
      • +
      • Full path: /NetworkService/Tracing/Categories/Discovery
      • Format: integer
      • Default value: 0
      • -
      • Valid values: 0 / 6
      • Occurrences min-max: 0-1
      -
      -

      6.8   Compression¶

      +
      +

      6.8   Compression¶

      This group of attributes specifies a compression method to use within the service in partitions where it is enabled. The @@ -8394,26 +7409,26 @@

      6.8   Compression -
    • Full path: //OpenSplice/NetworkService/Compression
    • +
    • Full path: /NetworkService/Compression
    • Occurrences min-max: 0-1
    • Optional attributes: PluginLibrary, PluginInitFunction, PluginParameter
    -
    -

    6.8.1   PluginLibrary¶

    +
    +

    6.8.1   PluginLibrary¶

    This attribute names a dynamically loadable library which must contain the code for compressing and decompressing the network data. This may be left blank for the built-in compressors.
      -
    • Full path: //OpenSplice/NetworkService/Compression[@PluginLibrary]
    • +
    • Full path: /NetworkService/Compression/PluginLibrary
    • Format: string
    • Default value: “”
    • Required: false
    -
    -

    6.8.2   PluginInitFunction¶

    +
    +

    6.8.2   PluginInitFunction¶

    This attribute specifies an initialization function for a compression plugin to be used within the service. The functions @@ -8421,14 +7436,14 @@

    6.8.2   PluginInitFunction

      -
    • Full path: //OpenSplice/NetworkService/Compression[@PluginInitFunction]
    • +
    • Full path: /NetworkService/Compression/PluginInitFunction
    • Format: string
    • Default value: “”
    • Required: false
    -
    -

    6.8.3   PluginParameter¶

    +
    +

    6.8.3   PluginParameter¶

    Some compression implementations are configurable with respect to the tradeoff between speed and effectiveness. A @@ -8436,7 +7451,7 @@

    6.8.3   PluginParameter

      -
    • Full path: //OpenSplice/NetworkService/Compression[@PluginParameter]
    • +
    • Full path: /NetworkService/Compression/PluginParameter
    • Format: string
    • Default value: “”
    • Required: false
    • @@ -8448,15 +7463,15 @@

      6.8.3   PluginParameter7   NetworkingBridgeService¶

      The root element of a networking bridge service configuration.

        -
      • Full path: //OpenSplice/NetworkingBridgeService
      • +
      • Full path: /NetworkingBridgeService
      • Occurrences min-max: 0-*
      • Required attributes: name
      -
      -

      7.1   name¶

      +
      +

      7.1   name¶

      This attribute identifies the configuration for the Networking Bridge Service. Multiple service configurations can be specified in one single XML file. The actual applicable configuration is determined by the value of the name attribute, which must match the specified under the element OpenSplice/Domain/Service[@name] in the Domain Service configuration.

        -
      • Full path: //OpenSplice/NetworkingBridgeService[@name]
      • +
      • Full path: /NetworkingBridgeService/name
      • Format: string
      • Default value: networkingbridge
      • Required: true
      • @@ -8466,22 +7481,22 @@

        7.1   name¶

        This element specifies which partition/topic combinations may not be forwarded.

          -
        • Full path: //OpenSplice/NetworkingBridgeService/Exclude
        • +
        • Full path: /NetworkingBridgeService/Exclude
        • Occurrences min-max: 0-*

        7.2.1   Entry¶

        This element configures a single partition/topic combination for exclusion in the set of forwarded partition/topic combinations.

          -
        • Full path: //OpenSplice/NetworkingBridgeService/Exclude/Entry
        • +
        • Full path: /NetworkingBridgeService/Exclude/Entry
        • Occurrences min-max: 0-*
        • Required attributes: DCPSPartitionTopic
        -
        -

        7.2.1.1   DCPSPartitionTopic¶

        +
        +

        7.2.1.1   DCPSPartitionTopic¶

        This attribute specifies a partition and a topic expression, separated by a single ‘.’, that are used to determine if a given partition and topic will be excluded w.r.t. forwarding. The expressions may use the usual wildcards ‘*’ and ‘?’.

          -
        • Full path: //OpenSplice/NetworkingBridgeService/Exclude/Entry[@DCPSPartitionTopic]
        • +
        • Full path: /NetworkingBridgeService/Exclude/Entry/DCPSPartitionTopic
        • Format: string
        • Default value: n/a
        • Required: true
        • @@ -8493,22 +7508,22 @@

          7.2.1.1   DCPSPartitionTopic¶

          This element specifies which partition/topic combinations are to be forwarded, provided they are not listed in the Exclude section.

            -
          • Full path: //OpenSplice/NetworkingBridgeService/Include
          • +
          • Full path: /NetworkingBridgeService/Include
          • Occurrences min-max: 0-*
          -
          -

          7.3.1   Entry¶

          +
          +

          7.3.1   Entry¶

          This element configures a single partition/topic combination for inclusion in the set of forwarded partition/topic combinations.

            -
          • Full path: //OpenSplice/NetworkingBridgeService/Include/Entry
          • +
          • Full path: /NetworkingBridgeService/Include/Entry
          • Occurrences min-max: 0-*
          • Required attributes: DCPSPartitionTopic
          -
          -

          7.3.1.1   DCPSPartitionTopic¶

          +
          +

          7.3.1.1   DCPSPartitionTopic¶

          This attribute specifies a partition and a topic expression, separated by a single ‘.’, that are used to determine if a given partition and topic will be included w.r.t. forwarding. The expressions may use the usual wildcards ‘*’ and ‘?’.

            -
          • Full path: //OpenSplice/NetworkingBridgeService/Include/Entry[@DCPSPartitionTopic]
          • +
          • Full path: /NetworkingBridgeService/Include/Entry/DCPSPartitionTopic
          • Format: string
          • Default value: n/a
          • Required: true
          • @@ -8516,11 +7531,11 @@

            7.3.1.1   DCPSPartitionTopic -

            7.4   Tracing¶

            +
            +

            7.4   Tracing¶

            The Tracing element controls the amount and type of information that is written into the tracing log by the DDSI service. This is useful to track the DDSI service during application development.

              -
            • Full path: //OpenSplice/NetworkingBridgeService/Tracing
            • +
            • Full path: /NetworkingBridgeService/Tracing
            • Occurrences min-max: 0-*
            • Child elements: AppendToFile, EnableCategory, OutputFile, Verbosity
            @@ -8528,7 +7543,7 @@

            7.4   Tracing¶

            This option specifies whether the output is to be appended to an existing log file. The default is to create a new log file each time, which is generally the best option if a detailed log is generated.

            -
            -

            7.4.3   OutputFile¶

            +
            +

            7.4.3   OutputFile¶

            This option specifies where the logging is printed to. Note that stdout and stderr are treated as special values, representing “standard out” and “standard error” respectively. No file is created unless logging categories are enabled using the Tracing/Verbosity or Tracing/EnabledCategory settings.

              -
            • Full path: //OpenSplice/NetworkingBridgeService/Tracing/OutputFile
            • +
            • Full path: /NetworkingBridgeService/Tracing/OutputFile
            • Format: string
            • Default value: nwbridge.log
            • Occurrences min-max: 0-1
            -
            -

            7.4.4   Verbosity¶

            +
            +

            7.4.4   Verbosity¶

            This element enables standard groups of categories, based on a desired verbosity level. This is in addition to the categories enabled by the Tracing/EnableCategory setting. Recognised verbosity levels and the categories they map to are: - none: no NetworkingBridge log - severe: error and fatal @@ -8571,7 +7586,7 @@

            7.4.4   Verbosity -
          • Full path: //OpenSplice/NetworkingBridgeService/Tracing/Verbosity
          • +
          • Full path: /NetworkingBridgeService/Tracing/Verbosity
          • Format: enumeration
          • Default value: none
          • Valid values: finest, fine, config, info, warning, severe, none
          • @@ -8579,47 +7594,47 @@

            7.4.4   Verbosity -

            7.5   Watchdog¶

            +
            +

            7.5   Watchdog¶

            This element specifies the type of OS scheduling class will be used by the thread that announces its liveliness periodically.

              -
            • Full path: //OpenSplice/NetworkingBridgeService/Watchdog
            • +
            • Full path: /NetworkingBridgeService/Watchdog
            • Occurrences min-max: 0-*
            -
            -

            7.5.1   Scheduling¶

            +
            +

            7.5.1   Scheduling¶

            This element specifies the type of OS scheduling class will be used by the thread that announces its liveliness periodically.

              -
            • Full path: //OpenSplice/NetworkingBridgeService/Watchdog/Scheduling
            • +
            • Full path: /NetworkingBridgeService/Watchdog/Scheduling
            • Occurrences min-max: 0-1
            • Child elements: Class, Priority
            -
            -

            7.5.1.1   Class¶

            +
            +

            7.5.1.1   Class¶

            This element specifies the thread scheduling class that will be used by the watchdog thread. The user may need the appropriate privileges from the underlying operating system to be able to assign some of the privileged scheduling classes.

              -
            • Full path: //OpenSplice/NetworkingBridgeService/Watchdog/Scheduling/Class
            • +
            • Full path: /NetworkingBridgeService/Watchdog/Scheduling/Class
            • Format: enumeration
            • Default value: default
            • Valid values: realtime, timeshare, default
            • Occurrences min-max: 0-1
            -
            -

            7.5.1.2   Priority¶

            +
            +

            7.5.1.2   Priority¶

            This element specifies the thread priority. Only priorities that are supported by the underlying operating system can be assigned to this element. The user may need special privileges from the underlying operating system to be able to assign some of the privileged priorities.

              -
            • Full path: //OpenSplice/NetworkingBridgeService/Watchdog/Scheduling/Priority
            • +
            • Full path: /NetworkingBridgeService/Watchdog/Scheduling/Priority
            • Format: integer
            • Default value: 0
            • Occurrences min-max: 0-1
            • Optional attributes: priority_kind
            -
            -
            7.5.1.2.1   priority_kind¶
            +
            +
            7.5.1.2.1   priority_kind¶

            This attribute specifies whether the specified Priority is a relative or absolute priority.

              -
            • Full path: //OpenSplice/NetworkingBridgeService/Watchdog/Scheduling/Priority[@priority_kind]
            • +
            • Full path: /NetworkingBridgeService/Watchdog/Scheduling/Priority/priority_kind
            • Format: enumeration
            • Default value: relative
            • Valid values: relative, absolute
            • @@ -8630,199 +7645,99 @@
              7.5.1.2.1   priority_kind
            -
            -

            8   DDSI2EService¶

            -

            The root element of a DDSI2E networking service configuration.

            +
            +

            8   DDSI2Service¶

            +

            The root element of a DDSI2 networking service configuration.

              -
            • Full path: //OpenSplice/DDSI2EService
            • +
            • Full path: /DDSI2Service
            • Occurrences min-max: 0-*
            • Required attributes: name
            -
            -

            8.1   name¶

            -

            This attribute identifies the configuration for the DDSI2E Service. Multiple DDSI2E service configurations can be specified in one single resource. The actual applicable configuration is determined by the value of the name attribute, which must match the specified under the element OpenSplice/Domain/Service[@name] in the Domain Service configuration.

            -
              -
            • Full path: //OpenSplice/DDSI2EService[@name]
            • -
            • Format: string
            • -
            • Default value: ddsi2e
            • -
            • Required: true
            • -
            -
            -
            -

            8.2   Channels¶

            -

            This element is used to group a set of channels. The channels are independent data paths through DDSI2E and by using separate threads and setting their priorities appropriately, chanenls can be used to map transport priorities to operating system scheduler priorities, ensuring system-wide end-to-end priority preservation.

            -
              -
            • Full path: //OpenSplice/DDSI2EService/Channels
            • -
            • Occurrences min-max: 0-1
            • -
            -
            -

            8.2.1   Channel¶

            -

            This element defines a channel.

            -
              -
            • Full path: //OpenSplice/DDSI2EService/Channels/Channel
            • -
            • Occurrences min-max: 0-42
            • -
            • Child elements: AuxiliaryBandwidthLimit, DataBandwidthLimit, DiffServField, QueueSize
            • -
            • Required attributes: Name
            • -
            • Optional attributes: TransportPriority, Resolution
            • -
            -
            -

            8.2.1.1   Name¶

            -

            This attribute specifies name of this channel. The name should uniquely identify the channel.

            +
            +

            8.1   name¶

            +

            This attribute identifies the configuration for the DDSI2 Service. Multiple DDSI2 service configurations can be specified in one single resource. The actual applicable configuration is determined by the value of the name attribute, which must match the specified under the element OpenSplice/Domain/Service[@name] in the Domain Service configuration.

              -
            • Full path: //OpenSplice/DDSI2EService/Channels/Channel[@Name]
            • +
            • Full path: /DDSI2Service/name
            • Format: string
            • -
            • Default value: n/a
            • +
            • Default value: ddsi2
            • Required: true
            -
            -

            8.2.1.2   TransportPriority¶

            -

            This attribute sets the transport priority threshold for the channel. Each DCPS data writer has a “transport_priority” QoS and this QoS is used to select a channel for use by this writer. The selected channel is the one with the largest threshold not greater than the writer’s transport priority, and if no such channel exists, the channel with the lowest threshold.

            -
              -
            • Full path: //OpenSplice/DDSI2EService/Channels/Channel[@TransportPriority]
            • -
            • Format: integer
            • -
            • Default value: 0
            • -
            • Required: false
            • -
            -
            -
            -

            8.2.1.3   AuxiliaryBandwidthLimit¶

            -

            This element specifies the maximum transmit rate of auxiliary traffic on this channel (e.g. retransmits, heartbeats, etc). Bandwidth limiting uses a leaky bucket scheme. The default value “inf” means DDSI2E imposes no limitation, the underlying operating system and hardware will likely limit the maimum transmit rate.

            -

            The unit must be specified explicitly. Recognised units: X*b/s, *X*bps for bits/s or *X*B/s, *X*Bps for bytes/s; where *X is an optional prefix: k for 10 3, Ki for 2 10, M for 10 6, Mi for 2 20, G for 10 9, Gi for 2 30.

            -
              -
            • Full path: //OpenSplice/DDSI2EService/Channels/Channel/AuxiliaryBandwidthLimit
            • -
            • Format: string
            • -
            • Default value: inf
            • -
            • Occurrences min-max: 0-1
            • -
            -
            -
            -

            8.2.1.4   DataBandwidthLimit¶

            -

            This element specifies the maximum transmit rate of new samples and directly related data, for this channel. Bandwidth limiting uses a leaky bucket scheme. The default value “inf” means DDSI2E imposes no limitation, the underlying operating system and hardware will likely limit the maimum transmit rate.

            -

            The unit must be specified explicitly. Recognised units: X*b/s, *X*bps for bits/s or *X*B/s, *X*Bps for bytes/s; where *X is an optional prefix: k for 10 3, Ki for 2 10, M for 10 6, Mi for 2 20, G for 10 9, Gi for 2 30.

            -
              -
            • Full path: //OpenSplice/DDSI2EService/Channels/Channel/DataBandwidthLimit
            • -
            • Format: string
            • -
            • Default value: inf
            • -
            • Occurrences min-max: 0-1
            • -
            -
            -
            -

            8.2.1.5   DiffServField¶

            -

            This element describes the DiffServ setting the channel will apply to the networking messages. This parameter determines the value of the diffserv field of the IP version 4 packets sent on this channel which allows QoS setting to be applied to the network traffic send on this channel.

            -

            Windows platform support for setting the diffserv field is dependent on the OS version.

            -

            For Windows versions XP SP2 and 2003 to use the diffserv field the following parameter should be added to the register:

            -

            HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\TcpIp\Parameters\DisableUserTOSSetting

            -

            The type of this parameter is a DWORD and its value should be set to 0 to allow setting of the diffserv field.

            -

            For Windows version 7 or higher a new API (qWAVE) has been introduced. For these platforms the specified diffserv value is mapped to one of the support traffic types. -The mapping is as follows: 1-8 background traffic; 9-40 excellent traffic; 41-55 audio/video traffic; 56 voice traffic; 57-63 control traffic. -When an application is run without Administrative priveleges then only the diffserv value of 0, 8, 40 or 56 is allowed.

            -
              -
            • Full path: //OpenSplice/DDSI2EService/Channels/Channel/DiffServField
            • -
            • Format: integer
            • -
            • Default value: 0
            • -
            • Occurrences min-max: 0-1
            • -
            -
            -
            -

            8.2.1.6   QueueSize¶

            -

            This element specifies the number of messages the network queue for this channel can contain. The OpenSplice kernel writes data to be transmitted to the network queue, and DDSI2E takes them from this queue. If this queue is full when an application tries to write a sample, the sample will be dropped or the writer suspended, depending on the QoS settings of the writer. OpenSplice and its services are optimised for a well-balanced system design, where the queue never becomes full.

            -
              -
            • Full path: //OpenSplice/DDSI2EService/Channels/Channel/QueueSize
            • -
            • Format: integer
            • -
            • Default value: 0
            • -
            • Occurrences min-max: 0-1
            • -
            -
            -
            -

            8.2.1.7   Resolution¶

            -

            This element specifies the interval at which the DDSI2E transmit thread for this channel wakes up, and which controls the smallest latency_budget that has an effect. A shorter latency_budget is rounded to 0. The downside of a reducing this setting is that it increases the number of idle wake-ups of the transmit thread when there is no data to be sent.

            -

            The unit must be specified explicitly. Recognised units: ns, us, ms, s, min, hr, day.

            -
              -
            • Full path: //OpenSplice/DDSI2EService/Channels/Channel[@Resolution]
            • -
            • Format: string
            • -
            • Default value: 1s
            • -
            • Valid values: 0 / 1s
            • -
            • Required: false
            • -
            -
            -
            -
            -

            8.3   Compatibility¶

            +

            8.2   Compatibility¶

            The Compatibility elements allows specifying various settings related to compatability with standards and with other DDSI implementations.

              -
            • Full path: //OpenSplice/DDSI2EService/Compatibility
            • +
            • Full path: /DDSI2Service/Compatibility
            • Occurrences min-max: 0-1
            • Child elements: AckNackNumbitsEmptySet, ArrivalOfDataAssertsPpAndEpLiveliness, AssumeRtiHasPmdEndpoints, ExplicitlyPublishQosSetToDefault, ManySocketsMode, RespondToRtiInitZeroAckWithInvalidHeartbeat, StandardsConformance
            -

            8.3.1   AckNackNumbitsEmptySet¶

            +

            8.2.1   AckNackNumbitsEmptySet¶

            This element governs the representation of an acknowledgement message that does not also negatively-acknowledge some samples. If set to 0, the generated acknowledgements have an invalid form and will be reject by the strict and pedantic conformance modes, but several other implementation require this setting for smooth interoperation.

            -

            If set to 1, all acknowledgements sent by DDSI2E adhere the form of acknowledgement messages allowed by the standard, but this causes problems when interoperating with these other implementations. The strict and pedantic standards conformance modes always overrule an AckNackNumbitsEmptySet=0 to prevent the transmitting of invalid messages.

            +

            If set to 1, all acknowledgements sent by DDSI2 adhere the form of acknowledgement messages allowed by the standard, but this causes problems when interoperating with these other implementations. The strict and pedantic standards conformance modes always overrule a AckNackNumbitsEmptySet=0 to prevent the transmitting of invalid messages.

              -
            • Full path: //OpenSplice/DDSI2EService/Compatibility/AckNackNumbitsEmptySet
            • +
            • Full path: /DDSI2Service/Compatibility/AckNackNumbitsEmptySet
            • Format: integer
            • Default value: 0
            • Occurrences min-max: 0-1
            -

            8.3.2   ArrivalOfDataAssertsPpAndEpLiveliness¶

            -

            When set to true, arrival of a message from a peer asserts liveliness of that peer. When set to false, only SPDP and explicit lease renewals have this effect.

            +

            8.2.2   ArrivalOfDataAssertsPpAndEpLiveliness¶

            +

            This setting is currently ignored (accepted for backwards compatibility).

              -
            • Full path: //OpenSplice/DDSI2EService/Compatibility/ArrivalOfDataAssertsPpAndEpLiveliness
            • +
            • Full path: /DDSI2Service/Compatibility/ArrivalOfDataAssertsPpAndEpLiveliness
            • Format: boolean
            • Default value: true
            • Occurrences min-max: 0-1
            -

            8.3.3   AssumeRtiHasPmdEndpoints¶

            +

            8.2.3   AssumeRtiHasPmdEndpoints¶

            This option assumes ParticipantMessageData endpoints required by the liveliness protocol are present in RTI participants even when not properly advertised by the participant discovery protocol.

              -
            • Full path: //OpenSplice/DDSI2EService/Compatibility/AssumeRtiHasPmdEndpoints
            • +
            • Full path: /DDSI2Service/Compatibility/AssumeRtiHasPmdEndpoints
            • Format: boolean
            • Default value: false
            • Occurrences min-max: 0-1
            -

            8.3.4   ExplicitlyPublishQosSetToDefault¶

            +

            8.2.4   ExplicitlyPublishQosSetToDefault¶

            This element specifies whether QoS settings set to default values are explicitly published in the discovery protocol. Implementations are to use the default value for QoS settings not published, which allows a significant reduction of the amount of data that needs to be exchanged for the discovery protocol, but this requires all implementations to adhere to the default values specified by the specifications.

            When interoperability is required with an implementation that does not follow the specifications in this regard, setting this option to true will help.

              -
            • Full path: //OpenSplice/DDSI2EService/Compatibility/ExplicitlyPublishQosSetToDefault
            • +
            • Full path: /DDSI2Service/Compatibility/ExplicitlyPublishQosSetToDefault
            • Format: boolean
            • Default value: false
            • Occurrences min-max: 0-1
            -

            8.3.5   ManySocketsMode¶

            -

            This option specifies whether a network socket will be created for each domain participant on a host. The specification seems to assume that each participant has a unique address, and setting this option will ensure this to be the case. This is not the defeault.

            -

            Disabling it slightly improves performance and reduces network traffic somewhat. It also causes the set of port numbers needed by DDSI2E to become predictable, which may be useful for firewall and NAT configuration.

            +

            8.2.5   ManySocketsMode¶

            +

            This option specifies whether a network socket will be created for each domain participant on a host. The specification seems to assume that each participant has a unique address, and setting this option will ensure this to be the case. This is not the default.

            +

            Disabling it slightly improves performance and reduces network traffic somewhat. It also causes the set of port numbers needed by DDSI2 to become predictable, which may be useful for firewall and NAT configuration.

              -
            • Full path: //OpenSplice/DDSI2EService/Compatibility/ManySocketsMode
            • +
            • Full path: /DDSI2Service/Compatibility/ManySocketsMode
            • Format: boolean
            • Default value: false
            • Occurrences min-max: 0-1
            -

            8.3.6   RespondToRtiInitZeroAckWithInvalidHeartbeat¶

            +

            8.2.6   RespondToRtiInitZeroAckWithInvalidHeartbeat¶

            This element allows a closer mimicking of the behaviour of some other DDSI implementations, albeit at the cost of generating even more invalid messages. Setting it to true ensures a Heartbeat can be sent at any time when a remote node requests one, setting it to false delays it until a valid one can be sent.

            The latter is fully compliant with the specification, and no adverse effects have been observed. It is the default.

              -
            • Full path: //OpenSplice/DDSI2EService/Compatibility/RespondToRtiInitZeroAckWithInvalidHeartbeat
            • +
            • Full path: /DDSI2Service/Compatibility/RespondToRtiInitZeroAckWithInvalidHeartbeat
            • Format: boolean
            • Default value: false
            • Occurrences min-max: 0-1
            -

            8.3.7   StandardsConformance¶

            -

            This element sets the level of standards conformance of this instance of the DDSI2E Service. Stricter conformance typically means less interoperability with other implementations. Currently three modes are defined:

            +

            8.2.7   StandardsConformance¶

            +

            This element sets the level of standards conformance of this instance of the DDSI2 Service. Stricter conformance typically means less interoperability with other implementations. Currently three modes are defined:

            • pedantic: very strictly conform to the specification, ultimately for compliancy testing, but currently of little value because it adheres even to what will most likely turn out to be editing errors in the DDSI standard. Arguably, as long as no errata have been published it is the current text that is in effect, and that is what pedantic currently does.
            • strict: a slightly less strict view of the standard than does pedantic: it follows the established behaviour where the standard is obviously in error.
            • @@ -8830,7 +7745,7 @@

              8.3.7   StandardsConformance -
            • Full path: //OpenSplice/DDSI2EService/Compatibility/StandardsConformance
            • +
            • Full path: /DDSI2Service/Compatibility/StandardsConformance
            • Format: enumeration
            • Default value: lax
            • Valid values: lax, strict, pedantic
            • @@ -8838,77 +7753,68 @@

              8.3.7   StandardsConformance -

              8.4   Discovery¶

              +
              +

              8.3   Discovery¶

              The Discovery element allows specifying various parameters related to the discovery of peers.

                -
              • Full path: //OpenSplice/DDSI2EService/Discovery
              • -
              • Occurrences min-max: 0-1
              • -
              • Child elements: AdvertiseBuiltinTopicWriters, DefaultMulticastAddress, DomainId, GenerateBuiltinTopics, LocalDiscoveryPartition, MaxAutoParticipantIndex, ParticipantIndex, SPDPInterval, SPDPMulticastAddress
              • -
              -
              -

              8.4.1   AdvertiseBuiltinTopicWriters¶

              -

              This element controls whether or not DDSI2E advertises writers for the built-in topics from its discovery for backwards compatibility with older OpenSplice versions.

              -
                -
              • Full path: //OpenSplice/DDSI2EService/Discovery/AdvertiseBuiltinTopicWriters
              • -
              • Format: boolean
              • -
              • Default value: true
              • +
              • Full path: /DDSI2Service/Discovery
              • Occurrences min-max: 0-1
              • +
              • Child elements: DSClusterLeaseDuration, DomainId, GenerateBuiltinTopics, LocalDiscoveryPartition, MaxAutoParticipantIndex, ParticipantIndex, SPDPInterval, SPDPMulticastAddress
              -
              -
              -

              8.4.2   DefaultMulticastAddress¶

              -

              This element specifies the default multicast address for all traffic other than participant discovery packets. It defaults to Discovery/SPDPMulticastAddress.

              +
              +

              8.3.1   DSClusterLeaseDuration¶

              +

              This element specifies the lease duration for entities discovered through a discovery service.

              +

              Valid values are finite durations with an explicit unit or the keyword ‘inf’ for infinity. Recognised units: ns, us, ms, s, min, hr, day.

                -
              • Full path: //OpenSplice/DDSI2EService/Discovery/DefaultMulticastAddress
              • +
              • Full path: /DDSI2Service/Discovery/DSClusterLeaseDuration
              • Format: string
              • -
              • Default value: auto
              • +
              • Default value: 300 s
              • Occurrences min-max: 0-1
              -

              8.4.3   DomainId¶

              -

              This element allows overriding of the DDS Domain Id that is used for DDSI2E.

              +

              8.3.2   DomainId¶

              +

              This element allows overriding of the DDS Domain Id that is used for this DDSI2 service.

                -
              • Full path: //OpenSplice/DDSI2EService/Discovery/DomainId
              • +
              • Full path: /DDSI2Service/Discovery/DomainId
              • Format: string
              • Default value: default
              • Occurrences min-max: 0-1
              -

              8.4.4   GenerateBuiltinTopics¶

              -

              This element controls whether or not DDSI2E generates built-in topics from its discovery. When disabled, it relies on the durability service.

              +

              8.3.3   GenerateBuiltinTopics¶

              +

              This element controls whether or not the DDSI2 service generates built-in topics from its discovery. When disabled, it relies on the durability service.

                -
              • Full path: //OpenSplice/DDSI2EService/Discovery/GenerateBuiltinTopics
              • +
              • Full path: /DDSI2Service/Discovery/GenerateBuiltinTopics
              • Format: boolean
              • Default value: true
              • Occurrences min-max: 0-1
              -

              8.4.5   LocalDiscoveryPartition¶

              -

              This element controls which partition is monitored by DDSI2E for built-in topics describing entities the it mirrors in DDSI.

              +

              8.3.4   LocalDiscoveryPartition¶

              +

              This element controls which partition is monitored by DDSI2 for built-in topics describing entities the it mirrors in DDSI.

                -
              • Full path: //OpenSplice/DDSI2EService/Discovery/LocalDiscoveryPartition
              • +
              • Full path: /DDSI2Service/Discovery/LocalDiscoveryPartition
              • Format: string
              • -
              • Default value: __BUILT_IN_PARTITION__
              • +
              • Default value: __BUILT-IN PARTITION__
              • Occurrences min-max: 0-1
              -

              8.4.6   MaxAutoParticipantIndex¶

              -

              This element specifies the maximum DDSI participant index selected by this instance of the DDSI2E service if the Discovery/ParticipantIndex is “auto”.

              +

              8.3.5   MaxAutoParticipantIndex¶

              +

              This element specifies the maximum DDSI participant index selected by this instance of the DDSI service if the Discovery/ParticipantIndex is “auto”.

                -
              • Full path: //OpenSplice/DDSI2EService/Discovery/MaxAutoParticipantIndex
              • +
              • Full path: /DDSI2Service/Discovery/MaxAutoParticipantIndex
              • Format: integer
              • Default value: 9
              • Occurrences min-max: 0-1
              -

              8.4.7   ParticipantIndex¶

              -

              This element specifies the DDSI participant index used by this instance of the DDSI2E service for discovery purposes. Only one such participant id is used, independent of the number of actual DomainParticipants on the node. It is either:

              +

              8.3.6   ParticipantIndex¶

              +

              This element specifies the DDSI participant index used by this instance of the DDSI service for discovery purposes. Only one such participant id is used, independent of the number of actual DomainParticipants on the node. It is either:

              -

              8.4.8   Peers¶

              +

              8.3.7   Peers¶

              This element statically configures addresses for discovery.

                -
              • Full path: //OpenSplice/DDSI2EService/Discovery/Peers
              • +
              • Full path: /DDSI2Service/Discovery/Peers
              • Occurrences min-max: 0-1
              -

              8.4.8.1   Group¶

              +

              8.3.7.1   Group¶

              This element statically configures a fault tolerant group of addresses for discovery. Each member of the group is tried in sequence until one succeeds.

                -
              • Full path: //OpenSplice/DDSI2EService/Discovery/Peers/Group
              • +
              • Full path: /DDSI2Service/Discovery/Peers/Group
              • Occurrences min-max: 0-*
              -
              8.4.8.1.1   Peer¶
              +
              8.3.7.1.1   Peer¶

              This element statically configures an addresses for discovery.

                -
              • Full path: //OpenSplice/DDSI2EService/Discovery/Peers/Group/Peer
              • +
              • Full path: /DDSI2Service/Discovery/Peers/Group/Peer
              • Occurrences min-max: 0-*
              • Required attributes: Address
              -
              -
              8.4.8.1.1.1   Address¶
              -

              This element specifies an IP address to which discovery packets must be sent, in addition to the default multicast address (see also General/AllowMulticast). Both a hostnames and a numerical IP address is accepted; the hostname or IP address may be suffixed with :PORT to explicitly set the port to which it must be sent. Multiple Peers may be specified.

              +
              +
              8.3.7.1.1.1   Address¶
              +

              This element specifies an IP address to which discovery packets must be sent, in addition to the default multicast address (see also General/AllowMulticast and Internal/SuppressSPDPMulticast). Both a hostnames and a numerical IP address is accepted; the hostname or IP address may be suffixed with :PORT to explicitly set the port to which it must be sent. Multiple Peers may be specified.

                -
              • Full path: //OpenSplice/DDSI2EService/Discovery/Peers/Group/Peer[@Address]
              • +
              • Full path: /DDSI2Service/Discovery/Peers/Group/Peer/Address
              • Format: string
              • Default value: n/a
              • Required: true
              • @@ -8956,19 +7862,19 @@
                8.4.8.1.1.1   Address
              -
              -

              8.4.8.2   Peer¶

              -

              This element statically configures an addresses for discovery.

              +
              +

              8.3.7.2   Peer¶

              +

              This element statically configures an address for discovery.

                -
              • Full path: //OpenSplice/DDSI2EService/Discovery/Peers/Peer
              • +
              • Full path: /DDSI2Service/Discovery/Peers/Peer
              • Occurrences min-max: 0-*
              • Required attributes: Address
              -
              -
              8.4.8.2.1   Address¶
              -

              This element specifies an IP address to which discovery packets must be sent, in addition to the default multicast address (see also General/AllowMulticast). Both a hostnames and a numerical IP address is accepted; the hostname or IP address may be suffixed with :PORT to explicitly set the port to which it must be sent. Multiple Peers may be specified.

              +
              +
              8.3.7.2.1   Address¶
              +

              This element specifies an IP address to which discovery packets must be sent, in addition to the default multicast address (see also General/AllowMulticast and Internal/SuppressSPDPMulticast). Both a hostnames and a numerical IP address is accepted; the hostname or IP address may be suffixed with :PORT to explicitly set the port to which it must be sent. Multiple Peers may be specified.

                -
              • Full path: //OpenSplice/DDSI2EService/Discovery/Peers/Peer[@Address]
              • +
              • Full path: /DDSI2Service/Discovery/Peers/Peer/Address
              • Format: string
              • Default value: n/a
              • Required: true
              • @@ -8977,79 +7883,79 @@
                8.4.8.2.1   Address
              -

              8.4.9   Ports¶

              +

              8.3.8   Ports¶

              The Ports element allows specifying various parameters related to the port numbers used for discovery. These all have default values specified by the DDSI 2.1 specification and rarely need to be changed.

              +

              Valid values are finite durations with an explicit unit or the keyword ‘inf’ for infinity. Recognised units: ns, us, ms, s, min, hr, day.

                -
              • Full path: //OpenSplice/DDSI2EService/Discovery/Ports
              • +
              • Full path: /DDSI2Service/Discovery/Ports
              • Occurrences min-max: 0-1
              • Child elements: Base, DomainGain, MulticastDataOffset, MulticastMetaOffset, ParticipantGain, UnicastDataOffset, UnicastMetaOffset
              -

              8.4.9.1   Base¶

              +

              8.3.8.1   Base¶

              This element specifies the base port number (refer to the DDSI 2.1 specification, section 9.6.1, constant PB).

                -
              • Full path: //OpenSplice/DDSI2EService/Discovery/Ports/Base
              • +
              • Full path: /DDSI2Service/Discovery/Ports/Base
              • Format: integer
              • Default value: 7400
              • -
              • Valid values: 1 / 65535
              • Occurrences min-max: 0-1
              -

              8.4.9.2   DomainGain¶

              +

              8.3.8.2   DomainGain¶

              This element specifies the domain gain, relating domain ids to sets of port numbers (refer to the DDSI 2.1 specification, section 9.6.1, constant DG).

                -
              • Full path: //OpenSplice/DDSI2EService/Discovery/Ports/DomainGain
              • +
              • Full path: /DDSI2Service/Discovery/Ports/DomainGain
              • Format: integer
              • Default value: 250
              • Occurrences min-max: 0-1
              -

              8.4.9.3   MulticastDataOffset¶

              +

              8.3.8.3   MulticastDataOffset¶

              This element specifies the port number for multicast meta traffic (refer to the DDSI 2.1 specification, section 9.6.1, constant d2).

                -
              • Full path: //OpenSplice/DDSI2EService/Discovery/Ports/MulticastDataOffset
              • +
              • Full path: /DDSI2Service/Discovery/Ports/MulticastDataOffset
              • Format: integer
              • Default value: 1
              • Occurrences min-max: 0-1
              -

              8.4.9.4   MulticastMetaOffset¶

              +

              8.3.8.4   MulticastMetaOffset¶

              This element specifies the port number for multicast meta traffic (refer to the DDSI 2.1 specification, section 9.6.1, constant d0).

                -
              • Full path: //OpenSplice/DDSI2EService/Discovery/Ports/MulticastMetaOffset
              • +
              • Full path: /DDSI2Service/Discovery/Ports/MulticastMetaOffset
              • Format: integer
              • Default value: 0
              • Occurrences min-max: 0-1
              -

              8.4.9.5   ParticipantGain¶

              +

              8.3.8.5   ParticipantGain¶

              This element specifies the participant gain, relating p0, articipant index to sets of port numbers (refer to the DDSI 2.1 specification, section 9.6.1, constant PG).

                -
              • Full path: //OpenSplice/DDSI2EService/Discovery/Ports/ParticipantGain
              • +
              • Full path: /DDSI2Service/Discovery/Ports/ParticipantGain
              • Format: integer
              • Default value: 2
              • Occurrences min-max: 0-1
              -

              8.4.9.6   UnicastDataOffset¶

              +

              8.3.8.6   UnicastDataOffset¶

              This element specifies the port number for unicast meta traffic (refer to the DDSI 2.1 specification, section 9.6.1, constant d3).

                -
              • Full path: //OpenSplice/DDSI2EService/Discovery/Ports/UnicastDataOffset
              • +
              • Full path: /DDSI2Service/Discovery/Ports/UnicastDataOffset
              • Format: integer
              • Default value: 11
              • Occurrences min-max: 0-1
              -

              8.4.9.7   UnicastMetaOffset¶

              +

              8.3.8.7   UnicastMetaOffset¶

              This element specifies the port number for unicast meta traffic (refer to the DDSI 2.1 specification, section 9.6.1, constant d1).

                -
              • Full path: //OpenSplice/DDSI2EService/Discovery/Ports/UnicastMetaOffset
              • +
              • Full path: /DDSI2Service/Discovery/Ports/UnicastMetaOffset
              • Format: integer
              • Default value: 10
              • Occurrences min-max: 0-1
              • @@ -9057,194 +7963,163 @@

                8.4.9.7   UnicastMetaOffset -

                8.4.10   SPDPInterval¶

                +

                8.3.9   SPDPInterval¶

                This element specifies the interval between spontaneous transmissions of participant discovery packets.

                The unit must be specified explicitly. Recognised units: ns, us, ms, s, min, hr, day.

                  -
                • Full path: //OpenSplice/DDSI2EService/Discovery/SPDPInterval
                • +
                • Full path: /DDSI2Service/Discovery/SPDPInterval
                • Format: string
                • Default value: 30 s
                • -
                • Valid values: 0 / 1hr
                • Occurrences min-max: 0-1
              -

              8.4.11   SPDPMulticastAddress¶

              +

              8.3.10   SPDPMulticastAddress¶

              This element specifies the multicast address that is used as the destination for the participant discovery packets. In IPv4 mode the default is the (standardised) 239.255.0.1, in IPv6 mode it becomes ff02::ffff:239.255.0.1, which is a non-standardised link-local multicast address.

                -
              • Full path: //OpenSplice/DDSI2EService/Discovery/SPDPMulticastAddress
              • +
              • Full path: /DDSI2Service/Discovery/SPDPMulticastAddress
              • Format: string
              • Default value: 239.255.0.1
              • Occurrences min-max: 0-1
              -
              -

              8.5   General¶

              -

              The General element specifies overall DDSI2E service settings.

              +
              +

              8.4   General¶

              +

              The General element specifies overall DDSI2 service settings.

                -
              • Full path: //OpenSplice/DDSI2EService/General
              • +
              • Full path: /DDSI2Service/General
              • Occurrences min-max: 0-1
              • -
              • Child elements: AllowMulticast, CoexistWithNativeNetworking, DontRoute, EnableMulticastLoopback, ExternalNetworkAddress, ExternalNetworkMask, FragmentSize, MaxMessageSize, MulticastRecvNetworkInterfaceAddresses, MulticastTimeToLive, NetworkInterfaceAddress, StartupModeCoversTransient, StartupModeDuration, UseIPv6
              • +
              • Child elements: AllowMulticast, CoexistWithNativeNetworking, DontRoute, EnableMulticastLoopback, ExternalNetworkAddress, ExternalNetworkMask, MulticastRecvNetworkInterfaceAddresses, MulticastTimeToLive, NetworkInterfaceAddress, StartupModeCoversTransient, StartupModeDuration, UseIPv6
              -

              8.5.1   AllowMulticast¶

              -

              This element controls whether DDSI2E uses multicasts for data traffic.

              -

              It is a comma-separated list of some of the following keywords: “spdp”, “asm”, “ssm”, or either of “false” or “true”.

              -
                -
              • spdp: enables the use of ASM (any-source multicast) for participant discovery
              • -
              • asm: enables the use of ASM for all traffic (including SPDP)
              • -
              • ssm: enables the use of SSM (source-specific multicast) for all non-SPDP traffic (if supported)
              • -
              -

              When set to “false” all multicasting is disabled. The default, “true” enables full use of multicasts. Listening for multicasts can be controlled by General/MulticastRecvNetworkInterfaceAddresses.

              +

              8.4.1   AllowMulticast¶

              +

              This element controls whether the DDSI2 service uses multicasts for data traffic.

              +

              When set to “false”, DDSI2 will never advertise multicast addresses and never accept multicast addresses advertised by remote nodes, but it will still listen for multicast packets and perform multicast-based participant discovery. Listening for multicasts can be controlled by General/MulticastRecvNetworkInterfaceAddresses, and transmitting participant discovery multicasts by Internal/SuppressSPDPMulticast.

              +

              The default, “true”, enables full use of multicasts.

                -
              • Full path: //OpenSplice/DDSI2EService/General/AllowMulticast
              • -
              • Format: string
              • +
              • Full path: /DDSI2Service/General/AllowMulticast
              • +
              • Format: boolean
              • Default value: true
              • Occurrences min-max: 0-1
              -

              8.5.2   CoexistWithNativeNetworking¶

              -

              This element specifies whether the DDSI2E service operates in conjunction with the OpenSplice RT Networking service. When “false”, the DDSI2E service will take care of all communications, including those between OpenSplice nodes; when “true”, the DDSI2E service only communicates with DDS implementations other than OpenSplice. In this case the RT Networking service should be configured as well.

              +

              8.4.2   CoexistWithNativeNetworking¶

              +

              This element specifies whether the DDSI2 service operates in conjunction with the OpenSplice RT Networking service. When “false”, the DDSI2 service will take care of all communications, including those between OpenSplice nodes; when “true”, the DDSI2 service only communicates with DDS implementations other than OpenSplice. In this case the RT Networking service should be configured as well.

                -
              • Full path: //OpenSplice/DDSI2EService/General/CoexistWithNativeNetworking
              • +
              • Full path: /DDSI2Service/General/CoexistWithNativeNetworking
              • Format: boolean
              • Default value: false
              • Occurrences min-max: 0-1
              -
              -

              8.5.3   DontRoute¶

              +
              +

              8.4.3   DontRoute¶

              This element allows setting the SO_DONTROUTE option for outgoing packets, to bypass the local routing tables. This is generally useful only when the routing tables cannot be trusted, which is highly unusual.

                -
              • Full path: //OpenSplice/DDSI2EService/General/DontRoute
              • +
              • Full path: /DDSI2Service/General/DontRoute
              • Format: boolean
              • Default value: false
              • Occurrences min-max: 0-1
              -
              -

              8.5.4   EnableMulticastLoopback¶

              -

              This element specifies whether DDSI2E allows IP multicast packets to be visible to all DDSI participants in the same node, including itself. It must be “true” for intra-node multicast communications, but if a node runs only a single DDSI2E service and does not host any other DDSI-capable programs, it should be set to “false” for improved performance.

              +
              +

              8.4.4   EnableMulticastLoopback¶

              +

              This element specifies whether the DDSI2 service will allow IP multicast packets to be visible to all DDSI participants in the same node, including itself. It must be “true” for intra-node multicast communications, but if a node runs only a single DDSI2 service and does not host any other DDSI-capable programs, it may be set to “false” for improved performance.

                -
              • Full path: //OpenSplice/DDSI2EService/General/EnableMulticastLoopback
              • +
              • Full path: /DDSI2Service/General/EnableMulticastLoopback
              • Format: boolean
              • Default value: true
              • Occurrences min-max: 0-1
              -

              8.5.5   ExternalNetworkAddress¶

              -

              This element allows explicitly overruling the network address DDSI2E advertises in the discovery protocol, which by default is the address of the preferred network interface (General/NetworkInterfaceAddress), to allow DDSI2E to communicate across a Network Address Translation (NAT) device.

              +

              8.4.5   ExternalNetworkAddress¶

              +

              This element allows explicitly overruling the network address the DDSI2 service advertises in the discovery protocol, which by default is the address of the preferred network interface (General/NetworkInterfaceAddress), to allow DDSI2 to communicate across a Network Address Translation (NAT) device.

                -
              • Full path: //OpenSplice/DDSI2EService/General/ExternalNetworkAddress
              • +
              • Full path: /DDSI2Service/General/ExternalNetworkAddress
              • Format: string
              • Default value: auto
              • Occurrences min-max: 0-1
              -

              8.5.6   ExternalNetworkMask¶

              +

              8.4.6   ExternalNetworkMask¶

              This element specifies the network mask of the external network address. This element is relevant only when an external network address (General/ExternalNetworkAddress) is explicitly configured. In this case locators received via the discovery protocol that are within the same external subnet (as defined by this mask) will be translated to an internal address by replacing the network portion of the external address with the corresponding portion of the preferred network interface address. This option is IPv4-only.

                -
              • Full path: //OpenSplice/DDSI2EService/General/ExternalNetworkMask
              • +
              • Full path: /DDSI2Service/General/ExternalNetworkMask
              • Format: string
              • Default value: 0.0.0.0
              • Occurrences min-max: 0-1
              -
              -

              8.5.7   FragmentSize¶

              -

              This element specifies the size of DDSI sample fragments generated by DDSI2E. Samples larger than FragmentSize are fragmented into fragments of FragmentSize bytes each, except the last one, which may be smaller. The DDSI spec mandates a minimum fragment size of 1025 bytes, but DDSI2E will do whatever size is requested, accepting fragments of which the size is at least the minimum of 1025 and FragmentSize.

              -

              The unit must be specified explicitly. Recognised units: B (bytes), kB & KiB (2 10 bytes), MB & MiB (2 20 bytes), GB & GiB (2 30 bytes).

              -
                -
              • Full path: //OpenSplice/DDSI2EService/General/FragmentSize
              • -
              • Format: string
              • -
              • Default value: 1280 B
              • -
              • Occurrences min-max: 0-1
              • -
              -
              -
              -

              8.5.8   MaxMessageSize¶

              -

              This element specifies the maximum size of the UDP payload that DDSI2E will generate. DDSI2E will try to maintain this limit within the bounds of the DDSI specification, which means that in some cases (especially for very low values of MaxMessageSize) larger payloads may sporadically be observed (currently up to 1192 B).

              -

              On some networks it may be necessary to set this item to keep the packetsize below the MTU to prevent IP fragmentation. In those cases, it is generally advisable to also consider reducing Internal/FragmentSize.

              -

              The unit must be specified explicitly. Recognised units: B (bytes), kB & KiB (2 10 bytes), MB & MiB (2 20 bytes), GB & GiB (2 30 bytes).

              -
                -
              • Full path: //OpenSplice/DDSI2EService/General/MaxMessageSize
              • -
              • Format: string
              • -
              • Default value: 4096 B
              • -
              • Occurrences min-max: 0-1
              • -
              -
              -

              8.5.9   MulticastRecvNetworkInterfaceAddresses¶

              -

              This element specifies on which network interfaces DDSI2E listens to multicasts. The following options are available:

              +

              8.4.7   MulticastRecvNetworkInterfaceAddresses¶

              +

              This element specifies on which network interfaces DDSI2 listens to multicasts. The following options are available:

                +
              • preferred: listen for multicasts on the preferred interface (General/NetworkInterfaceAddress); or
              • all: listen for multicasts on all multicast-capable interfaces; or
              • any: listen for multicasts on the operating system default interface; or
              • -
              • preferred: listen for multicasts on the preferred interface (General/NetworkInterfaceAddress); or
              • none: does not listen for multicasts on any interface; or
              • -
              • a comma-separated list of network addresses: configures DDSI2E to listen for multicasts on all of the listed addresses.
              • +
              • a comma-separated list of network addresses: configures DDSI2 to listen for multicasts on all of the listed addresses.
              -

              If DDSI2E is in IPv6 mode and the address of the preferred network interface is a link-local address, “all” is treated as a synonym for “preferred” and a comma-separated list is treated as “preferred” if it contains the preferred interface and as “none” if not.

              +

              If DDSI2 is in IPv6 mode and the address of the preferred network interface is a link-local address, “all” is treated as a synonym for “preferred” and a comma-separated list is treated as “preferred” if it contains the preferred interface and as “none” if not.

                -
              • Full path: //OpenSplice/DDSI2EService/General/MulticastRecvNetworkInterfaceAddresses
              • +
              • Full path: /DDSI2Service/General/MulticastRecvNetworkInterfaceAddresses
              • Format: string
              • Default value: preferred
              • Occurrences min-max: 0-1
              -
              -

              8.5.10   MulticastTimeToLive¶

              +
              +

              8.4.8   MulticastTimeToLive¶

              This element specifies the time-to-live setting for outgoing multicast packets.

                -
              • Full path: //OpenSplice/DDSI2EService/General/MulticastTimeToLive
              • +
              • Full path: /DDSI2Service/General/MulticastTimeToLive
              • Format: integer
              • Default value: 32
              • -
              • Valid values: 0 / 255
              • Occurrences min-max: 0-1
              -
              -

              8.5.11   NetworkInterfaceAddress¶

              -

              This element specifies the preferred network interface for use by DDSI2E. The preferred network interface determines the IP address that DDSI2E advertises in the discovery protocol (but see also General/ExternalNetworkAddress), and is also the only interface over which multicasts are transmitted. The interface can be identified by its IP address, network interface name or network portion of the address. If the value “auto” is entered here, DDSI2E will select what it considers the most suitable interface.

              +
              +

              8.4.9   NetworkInterfaceAddress¶

              +

              This element specifies the preferred network interface for use by DDSI2. The preferred network interface determines the IP address that DDSI2 advertises in the discovery protocol (but see also General/ExternalNetworkAddress), and is also the only interface over which multicasts are transmitted. The interface can be identified by its IP address, network interface name or network portion of the address. If the value “auto” is entered here, DDSI2 will select what it considers the most suitable interface.

                -
              • Full path: //OpenSplice/DDSI2EService/General/NetworkInterfaceAddress
              • +
              • Full path: /DDSI2Service/General/NetworkInterfaceAddress
              • Format: string
              • Default value: auto
              • Occurrences min-max: 0-1
              -

              8.5.12   StartupModeCoversTransient¶

              -

              This element configures whether startup-mode should also cover transient and persistent data, for configurations where the durability service does not take care of it. Configurations without defined merge policies best leave this enabled.

              +

              8.4.10   StartupModeCoversTransient¶

              +

              This element configures whether startup-mode should also cover transient and persistent data, for configurations where the durability servie does not take care of it. Configurations without defined merge policies best leave this enabled.

                -
              • Full path: //OpenSplice/DDSI2EService/General/StartupModeCoversTransient
              • +
              • Full path: /DDSI2Service/General/StartupModeCoversTransient
              • Format: boolean
              • Default value: true
              • Occurrences min-max: 0-1
              -

              8.5.13   StartupModeDuration¶

              -

              This element specifies how long the DDSI2E remains in its “startup” mode. While in “startup” mode all volatile reliable data published on the local node is retained as-if it were transient-local data, allowing existing readers on remote nodes to obtain the data even though discovering them takes some time. Best-effort data by definition need not arrive, and transient and persistent data are covered by the durability service.

              -

              Once the system is stable, DDSI2E keeps track of the existence of remote readers whether or not matching writers exist locally, avoiding this discovery delay and ensuring this is merely a node startup issue.

              +

              8.4.11   StartupModeDuration¶

              +

              This element specifies how long the DDSI2 remains in its “startup” mode. While in “startup” mode all volatile reliable data published on the local node is retained as-if it were transient-local data, allowing existing readers on remote nodes to obtain the data even though discovering them takes some time. Best-effort data by definition need not arrive, and transient and persistent data are covered by the durability service.

              +

              Once the system is stable, the DDSI2 service keeps track of the existence of remote readers whether or not matching writers exist locally, avoiding this discovery delay and ensuring this is merely a node startup issue.

              Setting General/StartupModeDuration to 0s will disable it.

              The unit must be specified explicitly. Recognised units: ns, us, ms, s, min, hr, day.

                -
              • Full path: //OpenSplice/DDSI2EService/General/StartupModeDuration
              • +
              • Full path: /DDSI2Service/General/StartupModeDuration
              • Format: string
              • Default value: 2 s
              • -
              • Valid values: 0 / 60000
              • Occurrences min-max: 0-1
              -

              8.5.14   UseIPv6¶

              -

              This element can be used to DDSI2E use IPv6 instead of IPv4. This is currently an either/or switch.

              +

              8.4.12   UseIPv6¶

              +

              This element can be used to make DDSI2 service use IPv6 instead of IPv4. This is currently an either/or switch.

                -
              • Full path: //OpenSplice/DDSI2EService/General/UseIPv6
              • +
              • Full path: /DDSI2Service/General/UseIPv6
              • Format: boolean
              • Default value: false
              • Occurrences min-max: 0-1
              • @@ -9252,65 +8127,44 @@

                8.5.14   UseIPv6 -

                8.6   Internal¶

                +

                8.5   Internal¶

                The Internal elements deal with a variety of settings that evolving and that are not necessarily fully supported. For the vast majority of the Internal settings, the functionality per-se is supported, but the right to change the way the options control the functionality is reserved. This includes renaming or moving options.

                  -
                • Full path: //OpenSplice/DDSI2EService/Internal
                • +
                • Full path: /DDSI2Service/Internal
                • Occurrences min-max: 0-1
                • -
                • Child elements: AccelerateRexmitBlockSize, AggressiveKeepLastWhc, AggressiveKeepLastWhc, AssumeMulticastCapable, AuxiliaryBandwidthLimit, BuiltinEndpointSet, ConservativeBuiltinReaderStartup, DDSI2DirectMaxThreads, DefragReliableMaxSamples, DefragUnreliableMaxSamples, DeliveryQueueMaxSamples, ForwardAllMessages, ForwardRemoteData, GenerateKeyhash, LateAckMode, LeaseDuration, LegacyFragmentation, LogStackTraces, MaxParticipants, MaxQueuedRexmitBytes, MaxQueuedRexmitMessages, MaxSampleSize, MeasureHbToAckLatency, MinimumSocketReceiveBufferSize, MinimumSocketSendBufferSize, MirrorRemoteEntities, MonitorPort, NackDelay, PreEmptiveAckDelay, PrimaryReorderMaxSamples, PrioritizeRetransmit, RediscoveryBlacklistDuration, ResponsivenessTimeout, RetransmitMerging, RetransmitMergingPeriod, RetryOnRejectBestEffort, RetryOnRejectDuration, SPDPResponseMaxDelay, ScheduleTimeRounding, SecondaryReorderMaxSamples, SquashParticipants, SuppressSPDPMulticast, SynchronousDeliveryLatencyBound, SynchronousDeliveryPriorityThreshold, UnicastResponseToSPDPMessages, UseMulticastIfMreqn, WriterLingerDuration
                • +
                • Child elements: AccelerateRexmitBlockSize, AggressiveKeepLast1Whc, AssumeMulticastCapable, BuiltinEndpointSet, ConservativeBuiltinReaderStartup, DDSI2DirectMaxThreads, DefragReliableMaxSamples, DefragUnreliableMaxSamples, DeliveryQueueMaxSamples, ForwardAllMessages, ForwardRemoteData, FragmentSize, GenerateKeyhash, LateAckMode, LeaseDuration, LegacyFragmentation, LogStackTraces, MaxMessageSize, MaxParticipants, MaxQueuedRexmitBytes, MaxQueuedRexmitMessages, MaxSampleSize, MeasureHbToAckLatency, MinimumSocketReceiveBufferSize, MinimumSocketSendBufferSize, MirrorRemoteEntities, NackDelay, PreEmptiveAckDelay, PrimaryReorderMaxSamples, ResponsivenessTimeout, RetransmitMerging, RetransmitMergingPeriod, RetryOnRejectBestEffort, RetryOnRejectDuration, SPDPResponseMaxDelay, ScheduleTimeRounding, SecondaryReorderMaxSamples, SquashParticipants, SuppressSPDPMulticast, SynchronousDeliveryLatencyBound, SynchronousDeliveryPriorityThreshold, UnicastResponseToSPDPMessages, WriterLingerDuration
                -

                8.6.1   AccelerateRexmitBlockSize¶

                +

                8.5.1   AccelerateRexmitBlockSize¶

                Internal Proxy readers that are assumed to sill be retrieving historical data get this many samples retransmitted when they NACK something, even if some of these samples have sequence numbers outside the set covered by the NACK.

                  -
                • Full path: //OpenSplice/DDSI2EService/Internal/AccelerateRexmitBlockSize
                • +
                • Full path: /DDSI2Service/Internal/AccelerateRexmitBlockSize
                • Format: integer
                • Default value: 0
                • Occurrences min-max: 0-1
                -
                -

                8.6.2   AggressiveKeepLastWhc¶

                -

                Internal This element controls whether to drop a reliable sample from a DDSI2E WHC before all readers have acknowledged it as soon as a later sample becomes available. It only affects DCPS data writers with a history QoS setting of KEEP_LAST with depth 1. The default setting, false, mimics the behaviour of the OpenSplice RT networking and is necessary to make the behaviour of wait_for_acknowledgements() consistent across the networking services.

                -
                  -
                • Full path: //OpenSplice/DDSI2EService/Internal/AggressiveKeepLastWhc
                • -
                • Format: boolean
                • -
                • Default value: true
                • -
                • Occurrences min-max: 0-1
                • -
                -
                -
                -

                8.6.3   AggressiveKeepLastWhc¶

                -

                Internal This element controls whether to drop a reliable sample from a DDSI2E WHC before all readers have acknowledged it as soon as a later sample becomes available. It only affects DCPS data writers with a history QoS setting of KEEP_LAST with depth 1. The default setting, false, mimics the behaviour of the OpenSplice RT networking and is necessary to make the behaviour of wait_for_acknowledgements() consistent across the networking services.

                +
                +

                8.5.2   AggressiveKeepLast1Whc¶

                +

                Internal This element controls whether to drop a reliable sample from a DDSI2 WHC before all readers have acknowledged it as soon as a later sample becomes available. It only affects DCPS data writers with a history QoS setting of KEEP_LAST with depth 1. The default setting, false, mimics the behaviour of the OpenSplice RT networking and is necessary to make the behaviour of wait_for_acknowledgements() consistent across the networking services.

                  -
                • Full path: //OpenSplice/DDSI2EService/Internal/AggressiveKeepLastWhc
                • +
                • Full path: /DDSI2Service/Internal/AggressiveKeepLast1Whc
                • Format: boolean
                • -
                • Default value: true
                • +
                • Default value: false
                • Occurrences min-max: 0-1
                -

                8.6.4   AssumeMulticastCapable¶

                +

                8.5.3   AssumeMulticastCapable¶

                Internal This element controls which network interfaces are assumed to be capable of multicasting even when the interface flags returned by the operating system state it is not (this provides a workaround for some platforms). It is a comma-separated lists of patterns (with ? and * wildcards) against which the interface names are matched.

                  -
                • Full path: //OpenSplice/DDSI2EService/Internal/AssumeMulticastCapable
                • -
                • Format: string
                • -
                • Occurrences min-max: 0-1
                • -
                -
                -
                -

                8.6.5   AuxiliaryBandwidthLimit¶

                -

                Internal This element specifies the maximum transmit rate of auxiliary traffic not bound to a specific channel, such as discovery traffic, as well as auxiliary traffic related to a certain channel if that channel has elected to share this global AuxiliaryBandwidthLimit. Bandwidth limiting uses a leaky bucket scheme. The default value “inf” means DDSI2E imposes no limitation, the underlying operating system and hardware will likely limit the maimum transmit rate.

                -

                The unit must be specified explicitly. Recognised units: X*b/s, *X*bps for bits/s or *X*B/s, *X*Bps for bytes/s; where *X is an optional prefix: k for 10 3, Ki for 2 10, M for 10 6, Mi for 2 20, G for 10 9, Gi for 2 30.

                -
                  -
                • Full path: //OpenSplice/DDSI2EService/Internal/AuxiliaryBandwidthLimit
                • +
                • Full path: /DDSI2Service/Internal/AssumeMulticastCapable
                • Format: string
                • -
                • Default value: inf
                • Occurrences min-max: 0-1
                -

                8.6.6   BuiltinEndpointSet¶

                +

                8.5.4   BuiltinEndpointSet¶

                Internal This element controls which participants will have which built-in endpoints for the discovery and liveliness protocols. Valid values are:

                -
                -

                8.6.8   ControlTopic¶

                -

                Internal The ControlTopic element allows configured whether DDSI2E provides a special control interface via a predefined topic or not.

                -
                  -
                • Full path: //OpenSplice/DDSI2EService/Internal/ControlTopic
                • -
                • Occurrences min-max: 0-1
                • -
                • Child elements: DeafMute
                • -
                • Optional attributes: enable
                • -
                -
                -

                8.6.8.1   enable¶

                -

                Internal This attribute controls whether the DDSI2E control topic is defined and acted upon by DDSI2

                -
                  -
                • Full path: //OpenSplice/DDSI2EService/Internal/ControlTopic[@enable]
                • -
                • Format: boolean
                • -
                • Default value: false
                • -
                • Required: false
                • -
                -
                -
                -

                8.6.8.2   DeafMute¶

                -

                Internal This element controls whether DDSI2E defaults to deaf-mute mode or to normal mode. This controls both the initial behaviour and what behaviour it auto-reverts to.

                +

                8.5.5   ConservativeBuiltinReaderStartup¶

                +

                Internal This element forces all DDSI2 built-in discovery-related readers to request all historical data, instead of just one for each “topic”. There is no indication that any of the current DDSI implementations requires changing of this setting, but it is conceivable that an implementation might track which participants have been informed of the existence of endpoints and which have not been, refusing communication with those that have “can’t” know.

                +

                Should it be necessary to hide DDSI2’s shared discovery behaviour, set this to true and Internal/BuiltinEndpointSet to full.

                  -
                • Full path: //OpenSplice/DDSI2EService/Internal/ControlTopic/DeafMute
                • +
                • Full path: /DDSI2Service/Internal/ConservativeBuiltinReaderStartup
                • Format: boolean
                • Default value: false
                • Occurrences min-max: 0-1
                -
                -

                8.6.9   DDSI2DirectMaxThreads¶

                +

                8.5.6   DDSI2DirectMaxThreads¶

                Internal This element sets the maximum number of extra threads for an experimental, undocumented and unsupported direct mode.

                  -
                • Full path: //OpenSplice/DDSI2EService/Internal/DDSI2DirectMaxThreads
                • +
                • Full path: /DDSI2Service/Internal/DDSI2DirectMaxThreads
                • Format: integer
                • Default value: 1
                • Occurrences min-max: 0-1
                -

                8.6.10   DefragReliableMaxSamples¶

                -

                Internal This element sets the maximum number of samples that can be defragmented simultaneously for a reliable writer. This has to be large enough to handle retransmissions of historical data in addition to new samples.

                +

                8.5.7   DefragReliableMaxSamples¶

                +

                Internal This element sets the maximum number of samples that can be defragmneted simultaneously for a reliable writer. This has to be large enough to handle retransmissions of historical data in addition to new samples.

                  -
                • Full path: //OpenSplice/DDSI2EService/Internal/DefragReliableMaxSamples
                • +
                • Full path: /DDSI2Service/Internal/DefragReliableMaxSamples
                • Format: integer
                • Default value: 16
                • Occurrences min-max: 0-1
                -

                8.6.11   DefragUnreliableMaxSamples¶

                +

                8.5.8   DefragUnreliableMaxSamples¶

                Internal This element sets the maximum number of samples that can be defragmented simultaneously for a best-effort writers.

                  -
                • Full path: //OpenSplice/DDSI2EService/Internal/DefragUnreliableMaxSamples
                • +
                • Full path: /DDSI2Service/Internal/DefragUnreliableMaxSamples
                • Format: integer
                • Default value: 4
                • Occurrences min-max: 0-1
                -

                8.6.12   DeliveryQueueMaxSamples¶

                +

                8.5.9   DeliveryQueueMaxSamples¶

                Internal This element controls the Maximum size of a delivery queue, expressed in samples. Once a delivery queue is full, incoming samples destined for that queue are dropped until space becomes available again.

                  -
                • Full path: //OpenSplice/DDSI2EService/Internal/DeliveryQueueMaxSamples
                • +
                • Full path: /DDSI2Service/Internal/DeliveryQueueMaxSamples
                • Format: integer
                • Default value: 256
                • Occurrences min-max: 0-1
                -

                8.6.13   ForwardAllMessages¶

                +

                8.5.10   ForwardAllMessages¶

                Internal Forward all messages from a writer, rather than trying to forward each sample only once. The default of trying to forward each sample only once filters out duplicates for writers in multiple partitions under nearly all circumstances, but may still publish the odd duplicate. Note: the current implementation also can lose in contrived test cases, that publish more than 2**32 samples using a single data writer in conjunction with carefully controlled management of the writer history via cooperating local readers.

                  -
                • Full path: //OpenSplice/DDSI2EService/Internal/ForwardAllMessages
                • +
                • Full path: /DDSI2Service/Internal/ForwardAllMessages
                • Format: boolean
                • Default value: false
                • Occurrences min-max: 0-1
                -

                8.6.14   ForwardRemoteData¶

                -

                Internal This element controls whether DDSI2E forwards data received from other network services in the domain.

                +

                8.5.11   ForwardRemoteData¶

                +

                This element controls whether DDSI2 forwards data received from other network services in the domain.

                  -
                • Full path: //OpenSplice/DDSI2EService/Internal/ForwardRemoteData
                • +
                • Full path: /DDSI2Service/Internal/ForwardRemoteData
                • Format: enumeration
                • Default value: default
                • -
                • Valid values: false, true, default
                • +
                • Valid values: false, default, true
                • +
                • Occurrences min-max: 0-1
                • +
                +
                +
                +

                8.5.12   FragmentSize¶

                +

                Internal This element specifies the size of DDSI sample fragments generated by DDSI2. Samples larger than FragmentSize are fragmented into fragments of FragmentSize bytes each, except the last one, which may be smaller. The DDSI spec mandates a minimum fragment size of 1025 bytes, but DDSI2 will do whatever size is requested, accepting fragments of which the size is at least the minimum of 1025 and FragmentSize.

                +

                The unit must be specified explicitly. Recognised units: B (bytes), kB & KiB (2 10 bytes), MB & MiB (2 20 bytes), GB & GiB (2 30 bytes).

                +
                  +
                • Full path: /DDSI2Service/Internal/FragmentSize
                • +
                • Format: string
                • +
                • Default value: 1280 B
                • Occurrences min-max: 0-1
                -

                8.6.15   GenerateKeyhash¶

                +

                8.5.13   GenerateKeyhash¶

                Internal When true, include keyhashes in outgoing data for topics with keys.

                  -
                • Full path: //OpenSplice/DDSI2EService/Internal/GenerateKeyhash
                • +
                • Full path: /DDSI2Service/Internal/GenerateKeyhash
                • Format: boolean
                • Default value: true
                • Occurrences min-max: 0-1
                -

                8.6.16   LateAckMode¶

                +

                8.5.14   LateAckMode¶

                Internal Ack a sample only when it has been delivered, instead of when committed to delivering it.

                  -
                • Full path: //OpenSplice/DDSI2EService/Internal/LateAckMode
                • +
                • Full path: /DDSI2Service/Internal/LateAckMode
                • Format: boolean
                • Default value: false
                • Occurrences min-max: 0-1
                -

                8.6.17   LeaseDuration¶

                -

                Internal This setting controls the default participant lease duration. +

                8.5.15   LeaseDuration¶

                +

                Internal This setting controls the default participant lease duration, with 0s (the default) indicating that it is to be derived from the domain ExpiryTime: either 10% or 1s longer, whichever is shortest. The unit must be specified explicitly. Recognised units: ns, us, ms, s, min, hr, day.

                  -
                • Full path: //OpenSplice/DDSI2EService/Internal/LeaseDuration
                • +
                • Full path: /DDSI2Service/Internal/LeaseDuration
                • Format: string
                • Default value: 0 s
                • -
                • Valid values: 0 / 1hr
                • Occurrences min-max: 0-1
                -

                8.6.18   LegacyFragmentation¶

                -

                Internal This option enables a backwards-compatible, non-compliant setting and interpretation of the control flags in fragmented data messages. To be enabled only when requiring interoperability between compliant and non-compliant versions of DDSI2E for large messages.

                +

                8.5.16   LegacyFragmentation¶

                +

                Internal This option enables a backwards-compatible, non-compliant setting and interpretation of the control flags in fragmented data messages. To be enabled only when requiring interoperability between compliant and non-compliant versions of DDSI2 for large messages.

                  -
                • Full path: //OpenSplice/DDSI2EService/Internal/LegacyFragmentation
                • +
                • Full path: /DDSI2Service/Internal/LegacyFragmentation
                • Format: boolean
                • Default value: false
                • Occurrences min-max: 0-1
                -

                8.6.19   LogStackTraces¶

                -

                Internal This element controls whether or not to write stack traces to the DDSI2 trace when a thread fails to make progress (on select platforms only).

                +

                8.5.17   LogStackTraces¶

                +

                This element controls whether or not to write stack traces to the DDSI2 trace when a thread fails to make progress (on select platforms only).

                  -
                • Full path: //OpenSplice/DDSI2EService/Internal/LogStackTraces
                • +
                • Full path: /DDSI2Service/Internal/LogStackTraces
                • Format: boolean
                • -
                • Default value: true
                • +
                • Default value: false
                • +
                • Occurrences min-max: 0-1
                • +
                +
                +
                +

                8.5.18   MaxMessageSize¶

                +

                Internal This element specifies the maximum size of the UDP payload that DDSI2 will generate. DDSI2 will try to maintain this limit within the bounds of the DDSI specification, which means that in some cases (especially for very low values of MaxMessageSize) larger payloads may sporadically be observed (currently up to 1192 B).

                +

                On some networks it may be necessary to set this item to keep the packetsize below the MTU to prevent IP fragmentation. In those cases, it is generally advisable to also consider reducing Internal/FragmentSize.

                +

                The unit must be specified explicitly. Recognised units: B (bytes), kB & KiB (2 10 bytes), MB & MiB (2 20 bytes), GB & GiB (2 30 bytes).

                +
                  +
                • Full path: /DDSI2Service/Internal/MaxMessageSize
                • +
                • Format: string
                • +
                • Default value: 4096 B
                • Occurrences min-max: 0-1
                -

                8.6.20   MaxParticipants¶

                -

                Internal This elements configures the maximum number of DCPS domain participants this DDSI2E instance is willing to service. 0 is unlimited.

                +

                8.5.19   MaxParticipants¶

                +

                Internal This elements configures the maximum number of DCPS domain participants this DDSI2 service instance is willing to service. 0 is unlimited.

                  -
                • Full path: //OpenSplice/DDSI2EService/Internal/MaxParticipants
                • +
                • Full path: /DDSI2Service/Internal/MaxParticipants
                • Format: integer
                • Default value: 0
                • Occurrences min-max: 0-1
                -

                8.6.21   MaxQueuedRexmitBytes¶

                +

                8.5.20   MaxQueuedRexmitBytes¶

                Internal This setting limits the maximum number of bytes queued for retransmission. The default value of 0 is unlimited unless an AuxiliaryBandwidthLimit has been set, in which case it becomes NackDelay * AuxiliaryBandwidthLimit. It must be large enough to contain the largest sample that may need to be retransmitted.

                The unit must be specified explicitly. Recognised units: B (bytes), kB & KiB (2 10 bytes), MB & MiB (2 20 bytes), GB & GiB (2 30 bytes).

                  -
                • Full path: //OpenSplice/DDSI2EService/Internal/MaxQueuedRexmitBytes
                • +
                • Full path: /DDSI2Service/Internal/MaxQueuedRexmitBytes
                • Format: string
                • -
                • Default value: 50 kB
                • +
                • Default value: 0 B
                • Occurrences min-max: 0-1
                -

                8.6.22   MaxQueuedRexmitMessages¶

                +

                8.5.21   MaxQueuedRexmitMessages¶

                Internal This settings limits the maximum number of samples queued for retransmission.

                  -
                • Full path: //OpenSplice/DDSI2EService/Internal/MaxQueuedRexmitMessages
                • +
                • Full path: /DDSI2Service/Internal/MaxQueuedRexmitMessages
                • Format: integer
                • Default value: 200
                • Occurrences min-max: 0-1
                -

                8.6.23   MaxSampleSize¶

                -

                Internal This setting controls the maximum (CDR) serialised size of samples that DDSI2E will forward in either direction. Samples larger than this are discarded with a warning.

                +

                8.5.22   MaxSampleSize¶

                +

                Internal This setting controls the maximum (CDR) serialised size of samples that DDSI2 will forward in either direction. Samples larger than this are discarded with a warning.

                The unit must be specified explicitly. Recognised units: B (bytes), kB & KiB (2 10 bytes), MB & MiB (2 20 bytes), GB & GiB (2 30 bytes).

                  -
                • Full path: //OpenSplice/DDSI2EService/Internal/MaxSampleSize
                • +
                • Full path: /DDSI2Service/Internal/MaxSampleSize
                • Format: string
                • Default value: 2147483647 B
                • Occurrences min-max: 0-1
                -

                8.6.24   MeasureHbToAckLatency¶

                -

                Internal This element enables heartbeat-to-ack latency among DDSI2E services by prepending timestamps to Heartbeat and AckNack messages and calculating round trip times. This is non-standard behaviour. The measured latencies are quite noisy and are currently not used anywhere.

                +

                8.5.23   MeasureHbToAckLatency¶

                +

                Internal This element enables heartbeat-to-ack latency among DDSI2 services by prepending timestamps to Heartbeat and AckNack messages and calculating round trip times. This is non-standard behaviour. The measured latencies are quite noisy and are currently not used anywhere.

                  -
                • Full path: //OpenSplice/DDSI2EService/Internal/MeasureHbToAckLatency
                • +
                • Full path: /DDSI2Service/Internal/MeasureHbToAckLatency
                • Format: boolean
                • Default value: false
                • Occurrences min-max: 0-1
                -

                8.6.25   MinimumSocketReceiveBufferSize¶

                -

                Internal This setting controls the minimum size of socket receive buffers. The operating system provides some size receive buffer upon creation of the socket, this option can be used to increase the size of the buffer beyond that initially provided by the operating system. If the buffer size cannot be increased to the specified size, an error is reported.

                -

                The default setting is the word “default”, which means DDSI2E will attempt to increase the buffer size to 1MB, but will silently accept a smaller buffer should that attempt fail.

                +

                8.5.24   MinimumSocketReceiveBufferSize¶

                +

                Internal This setting controls the minimum size of socket receive buffers. This setting can only increase the size of the receive buffer, if the operating system by default creates a larger buffer, it is left unchanged.

                The unit must be specified explicitly. Recognised units: B (bytes), kB & KiB (2 10 bytes), MB & MiB (2 20 bytes), GB & GiB (2 30 bytes).

                  -
                • Full path: //OpenSplice/DDSI2EService/Internal/MinimumSocketReceiveBufferSize
                • +
                • Full path: /DDSI2Service/Internal/MinimumSocketReceiveBufferSize
                • Format: string
                • Default value: default
                • Occurrences min-max: 0-1
                -

                8.6.26   MinimumSocketSendBufferSize¶

                +

                8.5.25   MinimumSocketSendBufferSize¶

                Internal This setting controls the minimum size of socket send buffers. This setting can only increase the size of the send buffer, if the operating system by default creates a larger buffer, it is left unchanged.

                The unit must be specified explicitly. Recognised units: B (bytes), kB & KiB (2 10 bytes), MB & MiB (2 20 bytes), GB & GiB (2 30 bytes).

                  -
                • Full path: //OpenSplice/DDSI2EService/Internal/MinimumSocketSendBufferSize
                • +
                • Full path: /DDSI2Service/Internal/MinimumSocketSendBufferSize
                • Format: string
                • Default value: 64 KiB
                • Occurrences min-max: 0-1
                -

                8.6.27   MirrorRemoteEntities¶

                -

                Internal This element controls whether DDSI2 mirrors all entities in the domain in DDSI or only local ones. Default is to discover remote ones iff General/LocalDiscoveryPartition is not the built-in partition.

                +

                8.5.26   MirrorRemoteEntities¶

                +

                This element controls whether DDSI2 mirrors all entities in the domain in DDSI or only local ones. Default is to discover remote ones iff General/LocalDiscoveryPartition is not the built-in partition.

                  -
                • Full path: //OpenSplice/DDSI2EService/Internal/MirrorRemoteEntities
                • +
                • Full path: /DDSI2Service/Internal/MirrorRemoteEntities
                • Format: enumeration
                • Default value: default
                • -
                • Valid values: false, true, default
                • -
                • Occurrences min-max: 0-1
                • -
                -
                -
                -

                8.6.28   MonitorPort¶

                -

                Internal This element allows configuring a service that dumps a text description of part the internal state to TCP clients. By default (-1), this is disabled; specifying 0 means a kernel-allocated port is used; a positive number is used as the TCP port number.

                -
                  -
                • Full path: //OpenSplice/DDSI2EService/Internal/MonitorPort
                • -
                • Format: integer
                • -
                • Default value: -1
                • +
                • Valid values: false, default, true
                • Occurrences min-max: 0-1
                -

                8.6.29   NackDelay¶

                +

                8.5.27   NackDelay¶

                Internal This setting controls the delay between receipt of a HEARTBEAT indicating missing samples and a NACK (ignored when the HEARTBEAT requires an answer). However, no NACK is sent if a NACK had been scheduled already for a response earlier than the delay requests: then that NACK will incorporate the latest information.

                The unit must be specified explicitly. Recognised units: ns, us, ms, s, min, hr, day.

                  -
                • Full path: //OpenSplice/DDSI2EService/Internal/NackDelay
                • +
                • Full path: /DDSI2Service/Internal/NackDelay
                • Format: string
                • Default value: 10 ms
                • -
                • Valid values: 0 / 1hr
                • Occurrences min-max: 0-1
                -

                8.6.30   PreEmptiveAckDelay¶

                +

                8.5.28   PreEmptiveAckDelay¶

                Internal This setting controls the delay between the discovering a remote writer and sending a pre-emptive AckNack to discover the range of data available.

                The unit must be specified explicitly. Recognised units: ns, us, ms, s, min, hr, day.

                  -
                • Full path: //OpenSplice/DDSI2EService/Internal/PreEmptiveAckDelay
                • +
                • Full path: /DDSI2Service/Internal/PreEmptiveAckDelay
                • Format: string
                • Default value: 10 ms
                • -
                • Valid values: 0 / 1hr
                • Occurrences min-max: 0-1
                -

                8.6.31   PrimaryReorderMaxSamples¶

                +

                8.5.29   PrimaryReorderMaxSamples¶

                Internal This element sets the maximum size in samples of a primary re-order administration. Each proxy writer has one primary re-order administration to buffer the packet flow in case some packets arrive out of order. Old samples are forwarded to secondary re-order administrations associated with readers in need of historical data.

                  -
                • Full path: //OpenSplice/DDSI2EService/Internal/PrimaryReorderMaxSamples
                • +
                • Full path: /DDSI2Service/Internal/PrimaryReorderMaxSamples
                • Format: integer
                • Default value: 64
                • Occurrences min-max: 0-1
                -
                -

                8.6.32   PrioritizeRetransmit¶

                -

                Internal This element controls whether retransmits are prioritized over new data, speeding up recovery.

                +
                +

                8.5.30   ResponsivenessTimeout¶

                +

                Internal This element controls for how long an unresponsive reader can block the transmit thread by failing to acknowledge data when a writer’s DDSI2 WHC is full. If after this time the writer’s WHC has not shrunk to below the low-water mark, the reader is considered unresponsive and degraded to unreliable. It will be restored to reliable service once it resumes acknowledging ing samples.

                +

                The unit must be specified explicitly. Recognised units: ns, us, ms, s, min, hr, day.

                  -
                • Full path: //OpenSplice/DDSI2EService/Internal/PrioritizeRetransmit
                • -
                • Format: boolean
                • -
                • Default value: true
                • -
                • Occurrences min-max: 0-1
                • -
                -
                -
                -

                8.6.33   RediscoveryBlacklistDuration¶

                -

                Internal This element controls for how long a remote participant that was previously deleted will remain on a blacklist to prevent rediscovery, giving the software on a node time to perform any cleanup actions it needs to do. To some extent this delay is required internally by DDSI2E, but in the default configuration with the ‘enforce’ attribute set to false, DDSI2E will reallow rediscovery as soon as it has cleared its internal administration. Setting it to too small a value may result in the entry being pruned from the blacklist before DDSI2E is ready, it is therefore recommended to set it to at least several seconds.

                -

                Valid values are finite durations with an explicit unit or the keyword ‘inf’ for infinity. Recognised units: ns, us, ms, s, min, hr, day.

                -
                  -
                • Full path: //OpenSplice/DDSI2EService/Internal/RediscoveryBlacklistDuration
                • -
                • Format: string
                • -
                • Default value: 10s
                • -
                • Occurrences min-max: 0-1
                • -
                • Optional attributes: enforce
                • -
                -
                -

                8.6.33.1   enforce¶

                -

                Internal This attribute controls whether the configured time during which recently deleted participants will not be rediscovered (i.e., “black listed”) is enforced and following complete removal of the participant in DDSI2E, or whether it can be rediscovered earlier provided all traces of that participant have been removed already.

                -
                  -
                • Full path: //OpenSplice/DDSI2EService/Internal/RediscoveryBlacklistDuration[@enforce]
                • -
                • Format: boolean
                • -
                • Default value: false
                • -
                • Required: false
                • -
                -
                -
                -
                -

                8.6.34   ResponsivenessTimeout¶

                -

                Internal This element controls for how long an unresponsive reader can block the transmit thread by failing to acknowledge data when a writer’s DDSI2E write cache is full. If after this time the writer’s cache has not shrunk to below the low-water mark, the reader is considered unresponsive and degraded to unreliable. It will be restored to reliable service once it resumes acknowledging samples.

                -

                Valid values are finite durations with an explicit unit or the keyword ‘inf’ for infinity. Recognised units: ns, us, ms, s, min, hr, day.

                -
                  -
                • Full path: //OpenSplice/DDSI2EService/Internal/ResponsivenessTimeout
                • -
                • Format: string
                • -
                • Default value: inf
                • +
                • Full path: /DDSI2Service/Internal/ResponsivenessTimeout
                • +
                • Format: string
                • +
                • Default value: 1 s
                • Occurrences min-max: 0-1
                -

                8.6.35   RetransmitMerging¶

                +

                8.5.31   RetransmitMerging¶

                Internal This elements controls the addressing and timing of retransmits. Possible values are:

                -

                8.6.37   RetryOnRejectBestEffort¶

                -

                Internal Whether or not to locally retry pushing a received best-effort sample into the reader caches when resource limits are reached.

                +

                8.5.33   RetryOnRejectBestEffort¶

                +

                Internal Whether or not to locally retry pusing a received best-effort sample into the reader caches when resource limits are reached.

                  -
                • Full path: //OpenSplice/DDSI2EService/Internal/RetryOnRejectBestEffort
                • +
                • Full path: /DDSI2Service/Internal/RetryOnRejectBestEffort
                • Format: boolean
                • Default value: false
                • Occurrences min-max: 0-1
                -

                8.6.38   RetryOnRejectDuration¶

                +

                8.5.34   RetryOnRejectDuration¶

                Internal How long to keep locally retrying pushing a received sample into the reader caches when resource limits are reached. Default is dependent on Internal/LateAckMode: if the latter is false, it is 80% of Internal/ResponsivenessTimeout, otherwise it is 0.

                Valid values are finite durations with an explicit unit or the keyword ‘inf’ for infinity. Recognised units: ns, us, ms, s, min, hr, day.

                  -
                • Full path: //OpenSplice/DDSI2EService/Internal/RetryOnRejectDuration
                • +
                • Full path: /DDSI2Service/Internal/RetryOnRejectDuration
                • Format: string
                • Default value: default
                • Occurrences min-max: 0-1
                -

                8.6.39   SPDPResponseMaxDelay¶

                -

                Internal Maximum pseudo-random delay in milliseconds between discovering a remote participant and responding to it.

                +

                8.5.35   SPDPResponseMaxDelay¶

                +

                Internal Maximum pseudo-random delay in milliseocnds between discovering a remote participant and responding to it.

                The unit must be specified explicitly. Recognised units: ns, us, ms, s, min, hr, day.

                  -
                • Full path: //OpenSplice/DDSI2EService/Internal/SPDPResponseMaxDelay
                • +
                • Full path: /DDSI2Service/Internal/SPDPResponseMaxDelay
                • Format: string
                • Default value: 0 ms
                • -
                • Valid values: 0 / 1s
                • Occurrences min-max: 0-1
                -

                8.6.40   ScheduleTimeRounding¶

                +

                8.5.36   ScheduleTimeRounding¶

                Internal This setting allows the timing of scheduled events to be rounded up so that more events can be handled in a single cycle of the event queue. The default is 0 and causes no rounding at all, i.e. are scheduled exactly, whereas a value of 10ms would mean that events are rounded up to the nearest 10 milliseconds.

                The unit must be specified explicitly. Recognised units: ns, us, ms, s, min, hr, day.

                  -
                • Full path: //OpenSplice/DDSI2EService/Internal/ScheduleTimeRounding
                • +
                • Full path: /DDSI2Service/Internal/ScheduleTimeRounding
                • Format: string
                • Default value: 0 ms
                • -
                • Valid values: 0 / 1hr
                • Occurrences min-max: 0-1
                -

                8.6.41   SecondaryReorderMaxSamples¶

                +

                8.5.37   SecondaryReorderMaxSamples¶

                Internal This element sets the maximum size in samples of a secondary re-order administration. The secondary re-order administration is per reader in need of historical data.

                  -
                • Full path: //OpenSplice/DDSI2EService/Internal/SecondaryReorderMaxSamples
                • +
                • Full path: /DDSI2Service/Internal/SecondaryReorderMaxSamples
                • Format: integer
                • Default value: 16
                • Occurrences min-max: 0-1
                -

                8.6.42   SquashParticipants¶

                -

                Internal This element controls whether DDSI2E advertises all the domain participants it serves in DDSI (when set to false), or rather only one domain participant (the one corresponding to the DDSI2E process; when set to true). In the latter case DDSI2E becomes the virtual owner of all readers and writers of all domain participants, dramatically reducing discovery traffic (a similar effect can be obtained by setting Internal/BuiltinEndpointSet to “minimal” but with less loss of information).

                +

                8.5.38   SquashParticipants¶

                +

                Internal This element controls whether DDSI2 advertises all the domain participants it serves in DDSI (when set to false), or rather only one domain participant (the one corresponding to the DDSI2 process; when set to true). In the latter case DDSI2 becomes the virtual owner of all readers and writers of all domain participants, dramatically reducing discovery traffic.

                  -
                • Full path: //OpenSplice/DDSI2EService/Internal/SquashParticipants
                • +
                • Full path: /DDSI2Service/Internal/SquashParticipants
                • Format: boolean
                • Default value: false
                • Occurrences min-max: 0-1
                -

                8.6.43   SuppressSPDPMulticast¶

                +

                8.5.39   SuppressSPDPMulticast¶

                Internal The element controls whether the mandatory multicasting of the participant discovery packets occurs. Completely disabling multicasting requires this element be set to true, and generally requires explicitly listing peers to ping for unicast discovery.

                See also General/AllowMulticast.

                  -
                • Full path: //OpenSplice/DDSI2EService/Internal/SuppressSPDPMulticast
                • +
                • Full path: /DDSI2Service/Internal/SuppressSPDPMulticast
                • Format: boolean
                • Default value: false
                • Occurrences min-max: 0-1
                -

                8.6.44   SynchronousDeliveryLatencyBound¶

                +

                8.5.40   SynchronousDeliveryLatencyBound¶

                Internal This element controls whether samples sent by a writer with QoS settings transport_priority >= SynchronousDeliveryPriorityThreshold and a latency_budget at most this element’s value will be delivered synchronously from the “recv” thread, all others will be delivered asynchronously through delivery queues. This reduces latency at the expense of aggregate bandwidth.

                Valid values are finite durations with an explicit unit or the keyword ‘inf’ for infinity. Recognised units: ns, us, ms, s, min, hr, day.

                  -
                • Full path: //OpenSplice/DDSI2EService/Internal/SynchronousDeliveryLatencyBound
                • +
                • Full path: /DDSI2Service/Internal/SynchronousDeliveryLatencyBound
                • Format: string
                • Default value: inf
                • Occurrences min-max: 0-1
                -

                8.6.45   SynchronousDeliveryPriorityThreshold¶

                +

                8.5.41   SynchronousDeliveryPriorityThreshold¶

                Internal This element controls whether samples sent by a writer with QoS settings latency_budget <= SynchronousDeliveryLatencyBound and transport_priority greater than or equal to this element’s value will be delivered synchronously from the “recv” thread, all others will be delivered asynchronously through delivery queues. This reduces latency at the expense of aggregate bandwidth.

                  -
                • Full path: //OpenSplice/DDSI2EService/Internal/SynchronousDeliveryPriorityThreshold
                • +
                • Full path: /DDSI2Service/Internal/SynchronousDeliveryPriorityThreshold
                • Format: integer
                • Default value: 0
                • Occurrences min-max: 0-1
                -
                -

                8.6.46   Test¶

                +
                +

                8.5.42   Test¶

                Internal Testing options.

                  -
                • Full path: //OpenSplice/DDSI2EService/Internal/Test
                • +
                • Full path: /DDSI2Service/Internal/Test
                • Occurrences min-max: 0-1
                • Child elements: XmitLossiness
                -

                8.6.46.1   XmitLossiness¶

                -

                Internal This element controls the fraction of outgoing packets to drop, specified as samples per thousand.

                +

                8.5.42.1   XmitLossiness¶

                +

                Internal This element controls the fraction of outgoing packets to drop, specified as a per mil.

                  -
                • Full path: //OpenSplice/DDSI2EService/Internal/Test/XmitLossiness
                • +
                • Full path: /DDSI2Service/Internal/Test/XmitLossiness
                • Format: integer
                • Default value: 0
                • Occurrences min-max: 0-1
                • @@ -9800,71 +8598,40 @@

                  8.6.46.1   XmitLossiness -

                  8.6.47   UnicastResponseToSPDPMessages¶

                  +

                  8.5.43   UnicastResponseToSPDPMessages¶

                  Internal This element controls whether the response to a newly discovered participant is sent as a unicasted SPDP packet, instead of rescheduling the periodic multicasted one. There is no known benefit to setting this to false.

                    -
                  • Full path: //OpenSplice/DDSI2EService/Internal/UnicastResponseToSPDPMessages
                  • +
                  • Full path: /DDSI2Service/Internal/UnicastResponseToSPDPMessages
                  • Format: boolean
                  • Default value: true
                  • Occurrences min-max: 0-1
                -
                -

                8.6.48   UseMulticastIfMreqn¶

                -

                Internal Do not use.

                -
                  -
                • Full path: //OpenSplice/DDSI2EService/Internal/UseMulticastIfMreqn
                • -
                • Format: integer
                • -
                • Default value: 0
                • -
                • Occurrences min-max: 0-1
                • -
                -
                -

                8.6.49   Watermarks¶

                +

                8.5.44   Watermarks¶

                Internal Watermarks for flow-control.

                  -
                • Full path: //OpenSplice/DDSI2EService/Internal/Watermarks
                • -
                • Occurrences min-max: 0-1
                • -
                • Child elements: WhcAdaptive, WhcHigh, WhcHighInit, WhcLow
                • -
                -
                -

                8.6.49.1   WhcAdaptive¶

                -

                Internal This element controls whether DDSI2E will adapt the high-water mark to current traffic conditions, based on retransmit requests and transmit pressure.

                -
                  -
                • Full path: //OpenSplice/DDSI2EService/Internal/Watermarks/WhcAdaptive
                • -
                • Format: boolean
                • -
                • Default value: true
                • +
                • Full path: /DDSI2Service/Internal/Watermarks
                • Occurrences min-max: 0-1
                • +
                • Child elements: WhcHigh, WhcLow
                -
                -

                8.6.49.2   WhcHigh¶

                -

                Internal This element sets the maximum allowed high-water mark for the DDSI2E WHCs, expressed in bytes. A writer is suspended when the WHC reaches this size.

                +

                8.5.44.1   WhcHigh¶

                +

                Internal This element sets the high-water mark for the DDSI2 WHCs, expressed in bytes. A writer is suspended when the WHC reaches this size.

                The unit must be specified explicitly. Recognised units: B (bytes), kB & KiB (2 10 bytes), MB & MiB (2 20 bytes), GB & GiB (2 30 bytes).

                  -
                • Full path: //OpenSplice/DDSI2EService/Internal/Watermarks/WhcHigh
                • +
                • Full path: /DDSI2Service/Internal/Watermarks/WhcHigh
                • Format: string
                • Default value: 100 kB
                • Occurrences min-max: 0-1
                -
                -

                8.6.49.3   WhcHighInit¶

                -

                Internal This element sets the initial level of the high-water mark for the DDSI2E WHCs, expressed in bytes.

                -

                The unit must be specified explicitly. Recognised units: B (bytes), kB & KiB (2 10 bytes), MB & MiB (2 20 bytes), GB & GiB (2 30 bytes).

                -
                  -
                • Full path: //OpenSplice/DDSI2EService/Internal/Watermarks/WhcHighInit
                • -
                • Format: string
                • -
                • Default value: 30 kB
                • -
                • Occurrences min-max: 0-1
                • -
                -
                -

                8.6.49.4   WhcLow¶

                -

                Internal This element sets the low-water mark for the DDSI2E WHCs, expressed in bytes. A suspended writer resumes transmitting when its DDSI2E WHC shrinks to this size.

                +

                8.5.44.2   WhcLow¶

                +

                Internal This element sets the low-water mark for the DDSI2 WHCs, expressed in bytes. A suspended writer resumes transmitting when its DDSI2 WHC shrinks to this size.

                The unit must be specified explicitly. Recognised units: B (bytes), kB & KiB (2 10 bytes), MB & MiB (2 20 bytes), GB & GiB (2 30 bytes).

                  -
                • Full path: //OpenSplice/DDSI2EService/Internal/Watermarks/WhcLow
                • +
                • Full path: /DDSI2Service/Internal/Watermarks/WhcLow
                • Format: string
                • Default value: 1 kB
                • Occurrences min-max: 0-1
                • @@ -9872,602 +8639,337 @@

                  8.6.49.4   WhcLow -

                  8.6.50   WriterLingerDuration¶

                  +

                  8.5.45   WriterLingerDuration¶

                  Internal This setting controls the maximum duration for which actual deletion of a reliable writer with unacknowledged data in its history will be postponed to provide proper reliable transmission. The unit must be specified explicitly. Recognised units: ns, us, ms, s, min, hr, day.

                    -
                  • Full path: //OpenSplice/DDSI2EService/Internal/WriterLingerDuration
                  • +
                  • Full path: /DDSI2Service/Internal/WriterLingerDuration
                  • Format: string
                  • Default value: 1 s
                  • -
                  • Valid values: 0 / 1hr
                  • -
                  • Occurrences min-max: 0-1
                  • -
                  -
                -
                -
                -

                8.7   Partitioning¶

                -

                The Partitioning element specifies DDSI2E network partitions and how DCPS partition/topic combinations are mapped onto the network partitions.

                -
                  -
                • Full path: //OpenSplice/DDSI2EService/Partitioning
                • Occurrences min-max: 0-1
                -
                -

                8.7.1   IgnoredPartitions¶

                -

                The IgnoredPartitions element specifies DCPS partition/topic combinations that are not distributed over the network.

                -
                  -
                • Full path: //OpenSplice/DDSI2EService/Partitioning/IgnoredPartitions
                • -
                • Occurrences min-max: 0-*
                • -
                -
                -

                8.7.1.1   IgnoredPartition¶

                -

                This element can be used to prevent certain combinations of DCPS partition and topic from being transmitted over the network. DDSI2E will complete ignore readers and writers for which all DCPS partitions as well as their topic is ignored, not even creating DDSI readers and writers to mirror the DCPS ones.

                -
                  -
                • Full path: //OpenSplice/DDSI2EService/Partitioning/IgnoredPartitions/IgnoredPartition
                • -
                • Occurrences min-max: 0-*
                • -
                • Required attributes: DCPSPartitionTopic
                • -
                -
                -
                8.7.1.1.1   DCPSPartitionTopic¶
                -

                This attribute specifies a partition and a topic expression, separated by a single ‘.’, that are used to determine if a given partition and topic will be ignored or not. The expressions may use the usual wildcards ‘*’ and ‘?’. DDSI2E will consider an wildcard DCPS partition to match an expression iff there exists a string that satisfies both expressions.

                -
                  -
                • Full path: //OpenSplice/DDSI2EService/Partitioning/IgnoredPartitions/IgnoredPartition[@DCPSPartitionTopic]
                • -
                • Format: string
                • -
                • Default value: n/a
                • -
                • Required: true
                • -
                -
                -
                -
                -
                -

                8.7.2   NetworkPartitions¶

                -

                The NetworkPartitions element specifies the DDSI2E network partitions.

                -
                  -
                • Full path: //OpenSplice/DDSI2EService/Partitioning/NetworkPartitions
                • -
                • Occurrences min-max: 0-*
                • -
                -
                -

                8.7.2.1   NetworkPartition¶

                -

                This element defines a DDSI2E network partition.

                -
                  -
                • Full path: //OpenSplice/DDSI2EService/Partitioning/NetworkPartitions/NetworkPartition
                • -
                • Occurrences min-max: 0-*
                • -
                • Required attributes: Address, Name
                • -
                • Optional attributes: Connected, SecurityProfile
                • -
                -
                -
                8.7.2.1.1   Address¶
                -

                This attribute specifies the multicast addresses associated with the network partition as a comma-separated list. Readers matching this network partition (cf. Partitioning/PartitionMappings) will listen for multicasts on all of these addresses and advertise them in the discovery protocol. The writers will select the most suitable address from the addresses advertised by the readers.

                -
                  -
                • Full path: //OpenSplice/DDSI2EService/Partitioning/NetworkPartitions/NetworkPartition[@Address]
                • -
                • Format: string
                • -
                • Default value: n/a
                • -
                • Required: true
                • -
                -
                -
                -
                8.7.2.1.2   Connected¶
                -

                This attribute is a placeholder.

                -
                  -
                • Full path: //OpenSplice/DDSI2EService/Partitioning/NetworkPartitions/NetworkPartition[@Connected]
                • -
                • Format: boolean
                • -
                • Default value: true
                • -
                • Required: false
                • -
                -
                -
                -
                8.7.2.1.3   Name¶
                -

                This attribute specifies the name of this DDSI2E network partition. Two network partitions cannot have the same name.

                -
                  -
                • Full path: //OpenSplice/DDSI2EService/Partitioning/NetworkPartitions/NetworkPartition[@Name]
                • -
                • Format: string
                • -
                • Default value: n/a
                • -
                • Required: true
                • -
                -
                -
                -
                8.7.2.1.4   SecurityProfile¶
                -

                This attribute selects the DDSI2E security profile for encrypting the traffic mapped to this DDSI2E network partition. The default “null” means the network partition is unsecured; any other name refers to a security profile defined using the Security/SecurityProfile elements.

                -
                  -
                • Full path: //OpenSplice/DDSI2EService/Partitioning/NetworkPartitions/NetworkPartition[@SecurityProfile]
                • -
                • Format: string
                • -
                • Default value: null
                • -
                • Required: false
                • -
                -
                -
                -
                -
                -

                8.7.3   PartitionMappings¶

                -

                The PartitionMappings element specifies the mapping from DCPS partition/topic combinations to DDSI2E network partitions.

                -
                  -
                • Full path: //OpenSplice/DDSI2EService/Partitioning/PartitionMappings
                • -
                • Occurrences min-max: 0-*
                • -
                -
                -

                8.7.3.1   PartitionMapping¶

                -

                This element defines a mapping from a DCPS partition/topic combination to a DDSI2E network partition. This allows partitioning data flows by using special multicast addresses for part of the data and possibly also encrypting the data flow.

                -
                  -
                • Full path: //OpenSplice/DDSI2EService/Partitioning/PartitionMappings/PartitionMapping
                • -
                • Occurrences min-max: 0-*
                • -
                • Required attributes: DCPSPartitionTopic, NetworkPartition
                • -
                -
                -
                8.7.3.1.1   DCPSPartitionTopic¶
                -

                This attribute specifies a partition and a topic expression, separated by a single ‘.’, that are used to determine if a given partition and topic maps to the DDSI2E network partition named by the NetworkPartition attribute in this PartitionMapping element. The expressions may use the usual wildcards ‘*’ and ‘?’. DDSI2E will consider a wildcard DCPS partition to match an expression if there exists a string that satisfies both expressions.

                -
                  -
                • Full path: //OpenSplice/DDSI2EService/Partitioning/PartitionMappings/PartitionMapping[@DCPSPartitionTopic]
                • -
                • Format: string
                • -
                • Default value: n/a
                • -
                • Required: true
                • -
                -
                -
                -
                8.7.3.1.2   NetworkPartition¶
                -

                This attribute specifies which DDSI2E network partition is to be used for DCPS partition/topic combinations matching the DCPSPartitionTopic attribute within this PartitionMapping element.

                -
                  -
                • Full path: //OpenSplice/DDSI2EService/Partitioning/PartitionMappings/PartitionMapping[@NetworkPartition]
                • -
                • Format: string
                • -
                • Default value: n/a
                • -
                • Required: true
                • -
                -
                -
                -

                8.8   SSL¶

                +

                8.6   SSL¶

                The SSL element allows specifying various parameters related to using SSL/TLS for DDSI over TCP.

                  -
                • Full path: //OpenSplice/DDSI2EService/SSL
                • +
                • Full path: /DDSI2Service/SSL
                • Occurrences min-max: 0-1
                • Child elements: CertificateVerification, Ciphers, Enable, EntropyFile, KeyPassphrase, KeystoreFile, SelfSignedCertificates, VerifyClient
                -

                8.8.1   CertificateVerification¶

                +

                8.6.1   CertificateVerification¶

                If disabled this allows SSL connections to occur even if an X509 certificate fails verification.

                  -
                • Full path: //OpenSplice/DDSI2EService/SSL/CertificateVerification
                • +
                • Full path: /DDSI2Service/SSL/CertificateVerification
                • Format: boolean
                • Default value: true
                • Occurrences min-max: 0-1
                -

                8.8.2   Ciphers¶

                +

                8.6.2   Ciphers¶

                The set of ciphers used by SSL/TLS

                  -
                • Full path: //OpenSplice/DDSI2EService/SSL/Ciphers
                • +
                • Full path: /DDSI2Service/SSL/Ciphers
                • Format: string
                • Default value: ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH
                • Occurrences min-max: 0-1
                -
                -

                8.8.3   Enable¶

                +
                +

                8.6.3   Enable¶

                This enables SSL/TLS for TCP.

                  -
                • Full path: //OpenSplice/DDSI2EService/SSL/Enable
                • +
                • Full path: /DDSI2Service/SSL/Enable
                • Format: boolean
                • Default value: false
                • Occurrences min-max: 0-1
                -

                8.8.4   EntropyFile¶

                +

                8.6.4   EntropyFile¶

                The SSL/TLS random entropy file name.

                  -
                • Full path: //OpenSplice/DDSI2EService/SSL/EntropyFile
                • +
                • Full path: /DDSI2Service/SSL/EntropyFile
                • Format: string
                • Occurrences min-max: 0-1
                -

                8.8.5   KeyPassphrase¶

                +

                8.6.5   KeyPassphrase¶

                The SSL/TLS key pass phrase for encrypted keys.

                  -
                • Full path: //OpenSplice/DDSI2EService/SSL/KeyPassphrase
                • +
                • Full path: /DDSI2Service/SSL/KeyPassphrase
                • Format: string
                • Default value: secret
                • Occurrences min-max: 0-1
                -

                8.8.6   KeystoreFile¶

                +

                8.6.6   KeystoreFile¶

                The SSL/TLS key and certificate store file name. The keystore must be in PEM format.

                  -
                • Full path: //OpenSplice/DDSI2EService/SSL/KeystoreFile
                • +
                • Full path: /DDSI2Service/SSL/KeystoreFile
                • Format: string
                • Default value: keystore
                • Occurrences min-max: 0-1
                -

                8.8.7   SelfSignedCertificates¶

                +

                8.6.7   SelfSignedCertificates¶

                This enables the use of self signed X509 certificates.

                  -
                • Full path: //OpenSplice/DDSI2EService/SSL/SelfSignedCertificates
                • +
                • Full path: /DDSI2Service/SSL/SelfSignedCertificates
                • Format: boolean
                • Default value: false
                • Occurrences min-max: 0-1
                -

                8.8.8   VerifyClient¶

                +

                8.6.8   VerifyClient¶

                This enables an SSL server checking the X509 certificate of a connecting client.

                  -
                • Full path: //OpenSplice/DDSI2EService/SSL/VerifyClient
                • +
                • Full path: /DDSI2Service/SSL/VerifyClient
                • Format: boolean
                • Default value: false
                • Occurrences min-max: 0-1
                -
                -

                8.9   Security¶

                -

                The Security element specifies DDSI2E security profiles that can be used to encrypt traffic mapped to DDSI2E network partitions.

                -
                  -
                • Full path: //OpenSplice/DDSI2EService/Security
                • -
                • Occurrences min-max: 0-1
                • -
                -
                -

                8.9.1   SecurityProfile¶

                -

                This element defines a DDSI2E security profile.

                -
                  -
                • Full path: //OpenSplice/DDSI2EService/Security/SecurityProfile
                • -
                • Occurrences min-max: 0-*
                • -
                • Required attributes: Name
                • -
                • Optional attributes: Cipher, CipherKey
                • -
                -
                -

                8.9.1.1   Cipher¶

                -

                This attribute specifies the cipher to be used for encrypting traffic over network partitions secured by this security profile. The possible ciphers are:

                -
                  -
                • aes128: AES with a 128-bit key;
                • -
                • aes192: AES with a 192-bit key;
                • -
                • aes256: AES with a 256-bit key;
                • -
                • blowfish: the Blowfish cipher with a 128 bit key;
                • -
                • null: no encryption;
                • -
                -

                SHA1 is used on conjunction with all ciphers except “null” to ensure data integrity.

                -
                  -
                • Full path: //OpenSplice/DDSI2EService/Security/SecurityProfile[@Cipher]
                • -
                • Format: enumeration
                • -
                • Default value: null
                • -
                • Valid values: null, blowfish, aes128, aes192, aes256
                • -
                • Required: false
                • -
                -
                -
                -

                8.9.1.2   CipherKey¶

                -

                The CipherKey attribute is used to define the secret key required by the cipher selected using the Cipher attribute. The value can be a URI referencing an external file containing the secret key, or the secret key can be defined in-place as a string value.

                -

                The key must be specified as a hexadecimal string with each character representing 4 bits of the key. E.g., 1ABC represents the 16-bit key 0001 1010 1011 1100. The key should not follow a well-known pattern and must exactly match the key length of the selected cipher.

                -

                A malformed key will cause the security profile to be marked as invalid, and disable all network partitions secured by the (invalid) security profile to prevent information leaks.

                -

                As all DDS applications require read access to the XML configuration file, for security reasons it is recommended to store the secret key in an external file in the file system, referenced by its URI. The file should be protected against read and write access from other users on the host.

                -
                  -
                • Full path: //OpenSplice/DDSI2EService/Security/SecurityProfile[@CipherKey]
                • -
                • Format: string
                • -
                • Default value: “”
                • -
                • Required: false
                • -
                -
                -
                -

                8.9.1.3   Name¶

                -

                This attribute specifies the name of this DDSI2E security profile. Two security profiles cannot have the same name.

                -
                  -
                • Full path: //OpenSplice/DDSI2EService/Security/SecurityProfile[@Name]
                • -
                • Format: string
                • -
                • Default value: n/a
                • -
                • Required: true
                • -
                -
                -
                -
                -

                8.10   Sizing¶

                +

                8.7   Sizing¶

                The Sizing element specifies a variety of configuration settings dealing with expected system sizes, buffer sizes, &c.

                  -
                • Full path: //OpenSplice/DDSI2EService/Sizing
                • +
                • Full path: /DDSI2Service/Sizing
                • Occurrences min-max: 0-1
                • -
                • Child elements: EndpointsInSystem, EndpointsInSystem, LocalEndpoints, NetworkQueueSize, NetworkQueueSize, ReceiveBufferChunkSize, ReceiveBufferChunkSize
                • +
                • Child elements: EndpointsInSystem, LocalEndpoints, NetworkQueueSize, ReceiveBufferChunkSize, ReceiveBufferSize
                -

                8.10.1   EndpointsInSystem¶

                -

                This endpoint specifies the expected maximum number of endpoints in the network. Underestimating this number will have a significant performance impact, but will not affect correctness; signficantly overestimating it will cause more memory to be used than necessary.

                -
                  -
                • Full path: //OpenSplice/DDSI2EService/Sizing/EndpointsInSystem
                • -
                • Format: integer
                • -
                • Default value: 20000
                • -
                • Occurrences min-max: 0-1
                • -
                -
                -
                -

                8.10.2   EndpointsInSystem¶

                +

                8.7.1   EndpointsInSystem¶

                This endpoint specifies the expected maximum number of endpoints in the network. Underestimating this number will have a significant performance impact, but will not affect correctness; signficantly overestimating it will cause more memory to be used than necessary.

                  -
                • Full path: //OpenSplice/DDSI2EService/Sizing/EndpointsInSystem
                • +
                • Full path: /DDSI2Service/Sizing/EndpointsInSystem
                • Format: integer
                • Default value: 20000
                • Occurrences min-max: 0-1
                -

                8.10.3   LocalEndpoints¶

                -

                This element specifies the expected maximum number of endpoints local to one DDSI2E service. Underestimating this number will have a significant performance impact, but will not affect correctness; signficantly overestimating it will cause more memory to be used than necessary.

                +

                8.7.2   LocalEndpoints¶

                +

                This element specifies the expected maximum number of endpoints local to one DDSI2 service. Underestimating this number will have a significant performance impact, but will not affect correctness; signficantly overestimating it will cause more memory to be used than necessary.

                  -
                • Full path: //OpenSplice/DDSI2EService/Sizing/LocalEndpoints
                • +
                • Full path: /DDSI2Service/Sizing/LocalEndpoints
                • Format: integer
                • Default value: 1000
                • Occurrences min-max: 0-1
                -

                8.10.4   NetworkQueueSize¶

                -

                This element specifies the maximum number of samples in the network queue. Write/dispose operations add samples to this queue, the DDSI2E service drains it. Larger values allow large bursts of writes to occur without forcing synchronization between the application and the DDSI2E service, but do introduce the potential for longer latencies and increase the maximum amount of memory potentially occupied by messages in the queue.

                -
                  -
                • Full path: //OpenSplice/DDSI2EService/Sizing/NetworkQueueSize
                • -
                • Format: integer
                • -
                • Default value: 1000
                • -
                • Occurrences min-max: 0-1
                • -
                -
                -
                -

                8.10.5   NetworkQueueSize¶

                -

                This element specifies the maximum number of samples in the network queue. Write/dispose operations add samples to this queue, the DDSI2E service drains it. Larger values allow large bursts of writes to occur without forcing synchronization between the application and the DDSI2E service, but do introduce the potential for longer latencies and increase the maximum amount of memory potentially occupied by messages in the queue.

                +

                8.7.3   NetworkQueueSize¶

                +

                This element specifies the maximum number of samples in the network queue. Write/dispose operations add samples to this queue, the DDSI2 service drains it. Larger values allow large bursts of writes to occur without forcing synchronization between the application and the DDSI2 service, but do introduce the potential for longer latencies and increase the maximum amount of memory potentially occupied by messages in the queue.

                  -
                • Full path: //OpenSplice/DDSI2EService/Sizing/NetworkQueueSize
                • +
                • Full path: /DDSI2Service/Sizing/NetworkQueueSize
                • Format: integer
                • Default value: 1000
                • Occurrences min-max: 0-1
                -

                8.10.6   ReceiveBufferChunkSize¶

                -

                This element specifies the size of one allocation unit in the receive buffer. Must be greater than the maximum packet size by a modest amount (too large packets are dropped). Each allocation is shrunk immediately after processing a message, or freed straightaway.

                -

                The unit must be specified explicitly. Recognised units: B (bytes), kB & KiB (2 10 bytes), MB & MiB (2 20 bytes), GB & GiB (2 30 bytes).

                -
                  -
                • Full path: //OpenSplice/DDSI2EService/Sizing/ReceiveBufferChunkSize
                • -
                • Format: string
                • -
                • Default value: 128 KiB
                • -
                • Occurrences min-max: 0-1
                • -
                -
                -
                -

                8.10.7   ReceiveBufferChunkSize¶

                -

                This element specifies the size of one allocation unit in the receive buffer. Must be greater than the maximum packet size by a modest amount (too large packets are dropped). Each allocation is shrunk immediately after processing a message, or freed straightaway.

                +

                8.7.4   ReceiveBufferChunkSize¶

                +

                Size of one allocation unit in the receive buffer. Must be greater than the maximum packet size by a modest amount (too large packets are dropped). Each allocation is shrunk immediately after processing a message, or freed straightaway.

                The unit must be specified explicitly. Recognised units: B (bytes), kB & KiB (2 10 bytes), MB & MiB (2 20 bytes), GB & GiB (2 30 bytes).

                  -
                • Full path: //OpenSplice/DDSI2EService/Sizing/ReceiveBufferChunkSize
                • +
                • Full path: /DDSI2Service/Sizing/ReceiveBufferChunkSize
                • Format: string
                • Default value: 128 KiB
                • Occurrences min-max: 0-1
                -
                -

                8.10.8   Watermarks¶

                -

                #if LITE { LEAF (“ReceiveBufferSize”), 1, “128 KiB”, ABSOFF (rbuf_size), 0, uf_memsize, 0, pf_memsize, “This element sets the size of a single receive buffer. Many receive buffers may be needed. Their size must be greater than ReceiveBufferChunkSize by a modest amount.

                -
                  -
                • Full path: //OpenSplice/DDSI2EService/Sizing/Watermarks
                • -
                • Occurrences min-max: 0-1
                • -
                • Child elements: WhcAdaptive, WhcHigh, WhcHighInit, WhcLow
                • -
                -
                -

                8.10.8.1   WhcAdaptive¶

                -

                This element controls whether DDSI2E will adapt the high-water mark to current traffic conditions, based on retransmit requests and transmit pressure.

                -
                  -
                • Full path: //OpenSplice/DDSI2EService/Sizing/Watermarks/WhcAdaptive
                • -
                • Format: boolean
                • -
                • Default value: true
                • -
                • Occurrences min-max: 0-1
                • -
                -
                -
                -

                8.10.8.2   WhcHigh¶

                -

                This element sets the maximum allowed high-water mark for the DDSI2E WHCs, expressed in bytes. A writer is suspended when the WHC reaches this size.

                -

                The unit must be specified explicitly. Recognised units: B (bytes), kB & KiB (2 10 bytes), MB & MiB (2 20 bytes), GB & GiB (2 30 bytes).

                -
                  -
                • Full path: //OpenSplice/DDSI2EService/Sizing/Watermarks/WhcHigh
                • -
                • Format: string
                • -
                • Default value: 100 kB
                • -
                • Occurrences min-max: 0-1
                • -
                -
                -
                -

                8.10.8.3   WhcHighInit¶

                -

                This element sets the initial level of the high-water mark for the DDSI2E WHCs, expressed in bytes.

                -

                The unit must be specified explicitly. Recognised units: B (bytes), kB & KiB (2 10 bytes), MB & MiB (2 20 bytes), GB & GiB (2 30 bytes).

                -
                  -
                • Full path: //OpenSplice/DDSI2EService/Sizing/Watermarks/WhcHighInit
                • -
                • Format: string
                • -
                • Default value: 30 kB
                • -
                • Occurrences min-max: 0-1
                • -
                -
                -
                -

                8.10.8.4   WhcLow¶

                -

                This element sets the low-water mark for the DDSI2E WHCs, expressed in bytes. A suspended writer resumes transmitting when its DDSI2E WHC shrinks to this size.

                +
                +

                8.7.5   ReceiveBufferSize¶

                +

                This element sets the size of a single receive buffer. Many receive buffers may be needed. Their size must be greater than ReceiveBufferChunkSize by a modest amount.

                The unit must be specified explicitly. Recognised units: B (bytes), kB & KiB (2 10 bytes), MB & MiB (2 20 bytes), GB & GiB (2 30 bytes).

                  -
                • Full path: //OpenSplice/DDSI2EService/Sizing/Watermarks/WhcLow
                • +
                • Full path: /DDSI2Service/Sizing/ReceiveBufferSize
                • Format: string
                • -
                • Default value: 1 kB
                • +
                • Default value: 1 MiB
                • Occurrences min-max: 0-1
                -
                -

                8.11   TCP¶

                +

                8.8   TCP¶

                The TCP element allows specifying various parameters related to running DDSI over TCP.

                  -
                • Full path: //OpenSplice/DDSI2EService/TCP
                • +
                • Full path: /DDSI2Service/TCP
                • Occurrences min-max: 0-1
                • Child elements: Enable, NoDelay, Port, ReadTimeout, WriteTimeout
                -
                -

                8.11.1   Enable¶

                +
                +

                8.8.1   Enable¶

                This element enables the optional TCP transport.

                  -
                • Full path: //OpenSplice/DDSI2EService/TCP/Enable
                • +
                • Full path: /DDSI2Service/TCP/Enable
                • Format: boolean
                • Default value: false
                • Occurrences min-max: 0-1
                -

                8.11.2   NoDelay¶

                +

                8.8.2   NoDelay¶

                This element enables the TCP_NODELAY socket option, preventing multiple DDSI messages being sent in the same TCP request. Setting this option typically optimises latency over throughput.

                  -
                • Full path: //OpenSplice/DDSI2EService/TCP/NoDelay
                • +
                • Full path: /DDSI2Service/TCP/NoDelay
                • Format: boolean
                • Default value: true
                • Occurrences min-max: 0-1
                -

                8.11.3   Port¶

                -

                This element specifies the TCP port number on which DDSI2E accepts connections. If the port is set it is used in entity locators, published with DDSI discovery. Dynamically allocated if zero. Disabled if -1 or not configured. If disabled other DDSI services will not be able to establish connections with the service, the service can only communicate by establishing connections to other services.

                +

                8.8.3   Port¶

                +

                This element specifies the TCP port number on which the service accepts connections. If the port is set it is used in entity locators, published with DDSI discovery. Dynamically allocated if zero. Disabled if -1 or not configured. If disabled other DDSI services will not be able to establish connections with the service, the service can only communicate by establishing connections to other services.

                  -
                • Full path: //OpenSplice/DDSI2EService/TCP/Port
                • +
                • Full path: /DDSI2Service/TCP/Port
                • Format: integer
                • Default value: -1
                • -
                • Valid values: -1 / 65535
                • Occurrences min-max: 0-1
                -

                8.11.4   ReadTimeout¶

                +

                8.8.4   ReadTimeout¶

                This element specifies the timeout for blocking TCP read operations. If this timeout expires then the connection is closed.

                The unit must be specified explicitly. Recognised units: ns, us, ms, s, min, hr, day.

                  -
                • Full path: //OpenSplice/DDSI2EService/TCP/ReadTimeout
                • +
                • Full path: /DDSI2Service/TCP/ReadTimeout
                • Format: string
                • Default value: 2 s
                • -
                • Valid values: 0 / 1hr
                • Occurrences min-max: 0-1
                -

                8.11.5   WriteTimeout¶

                +

                8.8.5   WriteTimeout¶

                This element specifies the timeout for blocking TCP write operations. If this timeout expires then the connection is closed.

                The unit must be specified explicitly. Recognised units: ns, us, ms, s, min, hr, day.

                  -
                • Full path: //OpenSplice/DDSI2EService/TCP/WriteTimeout
                • +
                • Full path: /DDSI2Service/TCP/WriteTimeout
                • Format: string
                • Default value: 2 s
                • -
                • Valid values: 0 / 1hr
                • Occurrences min-max: 0-1
                -

                8.12   ThreadPool¶

                +

                8.9   ThreadPool¶

                The ThreadPool element allows specifying various parameters related to using a thread pool to send DDSI messages to multiple unicast addresses (TCP or UDP).

                  -
                • Full path: //OpenSplice/DDSI2EService/ThreadPool
                • +
                • Full path: /DDSI2Service/ThreadPool
                • Occurrences min-max: 0-1
                • Child elements: Enable, ThreadMax, Threads
                -
                -

                8.12.1   Enable¶

                +
                +

                8.9.1   Enable¶

                This element enables the optional thread pool.

                  -
                • Full path: //OpenSplice/DDSI2EService/ThreadPool/Enable
                • +
                • Full path: /DDSI2Service/ThreadPool/Enable
                • Format: boolean
                • Default value: false
                • Occurrences min-max: 0-1
                -

                8.12.2   ThreadMax¶

                +

                8.9.2   ThreadMax¶

                This elements configures the maximum number of threads in the thread pool.

                  -
                • Full path: //OpenSplice/DDSI2EService/ThreadPool/ThreadMax
                • +
                • Full path: /DDSI2Service/ThreadPool/ThreadMax
                • Format: integer
                • Default value: 8
                • Occurrences min-max: 0-1
                -

                8.12.3   Threads¶

                +

                8.9.3   Threads¶

                This elements configures the initial number of threads in the thread pool.

                  -
                • Full path: //OpenSplice/DDSI2EService/ThreadPool/Threads
                • +
                • Full path: /DDSI2Service/ThreadPool/Threads
                • Format: integer
                • Default value: 4
                • Occurrences min-max: 0-1
                -
                -

                8.13   Threads¶

                +
                +

                8.10   Threads¶

                This element is used to set thread properties.

                  -
                • Full path: //OpenSplice/DDSI2EService/Threads
                • +
                • Full path: /DDSI2Service/Threads
                • Occurrences min-max: 0-1
                -

                8.13.1   Thread¶

                -

                This element is used to set thread properties.

                +

                8.10.1   Thread¶

                +

                This element specifies thread properties, such as scheduling parameters and stack size.

                  -
                • Full path: //OpenSplice/DDSI2EService/Threads/Thread
                • +
                • Full path: /DDSI2Service/Threads/Thread
                • Occurrences min-max: 0-1000
                • Child elements: StackSize
                • Required attributes: Name
                -
                -

                8.13.1.1   Name¶

                +
                +

                8.10.1.1   Name¶

                The Name of the thread for which properties are being set. The following threads exist:

                • gc: garbage collector thread involved in deleting entities;
                • +
                • main: main thread, primarily handling local discovery;
                • recv: receive thread, taking data from the network and running the protocol state machine;
                • dq.builtins: delivery thread for DDSI-builtin data, primarily for discovery;
                • -
                • lease: DDSI liveliness monitoring;
                • +
                • lease: DDSI2 liveliness monitoring;
                • tev: general timed-event handling, retransmits and discovery;
                • xmit.CHAN: transmit thread for channel CHAN;
                • dq.CHAN: delivery thread for channel CHAN;
                • tev.CHAN: timed-even thread for channel CHAN.
                • -
                • Full path: //OpenSplice/DDSI2EService/Threads/Thread[@Name]
                • +
                • Full path: /DDSI2Service/Threads/Thread/Name
                • Format: string
                • Default value: n/a
                • Required: true
                -
                -

                8.13.1.2   Scheduling¶

                +
                +

                8.10.1.2   Scheduling¶

                This element configures the scheduling properties of the thread.

                  -
                • Full path: //OpenSplice/DDSI2EService/Threads/Thread/Scheduling
                • +
                • Full path: /DDSI2Service/Threads/Thread/Scheduling
                • Occurrences min-max: 0-1
                • Child elements: Class, Priority
                -
                -
                8.13.1.2.1   Class¶
                +
                +
                8.10.1.2.1   Class¶

                This element specifies the thread scheduling class (realtime, timeshare or default). The user may need special privileges from the underlying operating system to be able to assign some of the privileged scheduling classes.

                  -
                • Full path: //OpenSplice/DDSI2EService/Threads/Thread/Scheduling/Class
                • +
                • Full path: /DDSI2Service/Threads/Thread/Scheduling/Class
                • Format: enumeration
                • Default value: default
                • Valid values: realtime, timeshare, default
                • Occurrences min-max: 0-1
                -
                -
                8.13.1.2.2   Priority¶
                +
                +
                8.10.1.2.2   Priority¶

                This element specifies the thread priority (decimal integer or default). Only priorities that are supported by the underlying operating system can be assigned to this element. The user may need special privileges from the underlying operating system to be able to assign some of the privileged priorities.

                  -
                • Full path: //OpenSplice/DDSI2EService/Threads/Thread/Scheduling/Priority
                • +
                • Full path: /DDSI2Service/Threads/Thread/Scheduling/Priority
                • Format: string
                • Default value: default
                • Occurrences min-max: 0-1
                -
                -

                8.13.1.3   StackSize¶

                -

                This element configures the stack size for this thread. The default value default leaves the stack size at the operating system default.

                +
                +

                8.10.1.3   StackSize¶

                +

                This element configures the stack size for this thread. The default value default leaves the stack size at the the operating system default.

                The unit must be specified explicitly. Recognised units: B (bytes), kB & KiB (2 10 bytes), MB & MiB (2 20 bytes), GB & GiB (2 30 bytes).

                  -
                • Full path: //OpenSplice/DDSI2EService/Threads/Thread/StackSize
                • +
                • Full path: /DDSI2Service/Threads/Thread/StackSize
                • Format: string
                • Default value: default
                • Occurrences min-max: 0-1
                • @@ -10475,26 +8977,26 @@

                  8.13.1.3   StackSize

                -
                -

                8.14   Tracing¶

                +
                +

                8.11   Tracing¶

                The Tracing element controls the amount and type of information that is written into the tracing log by the DDSI service. This is useful to track the DDSI service during application development.

                  -
                • Full path: //OpenSplice/DDSI2EService/Tracing
                • +
                • Full path: /DDSI2Service/Tracing
                • Occurrences min-max: 0-1
                • Child elements: AppendToFile, EnableCategory, OutputFile, PacketCaptureFile, Timestamps, Verbosity
                -
                -

                8.14.1   AppendToFile¶

                +
                +

                8.11.1   AppendToFile¶

                This option specifies whether the output is to be appended to an existing log file. The default is to create a new log file each time, which is generally the best option if a detailed log is generated.

                  -
                • Full path: //OpenSplice/DDSI2EService/Tracing/AppendToFile
                • +
                • Full path: /DDSI2Service/Tracing/AppendToFile
                • Format: boolean
                • Default value: false
                • Occurrences min-max: 0-1
                -
                -

                8.14.2   EnableCategory¶

                + -
                -

                8.14.3   OutputFile¶

                +
                +

                8.11.3   OutputFile¶

                This option specifies where the logging is printed to. Note that stdout and stderr are treated as special values, representing “standard out” and “standard error” respectively. No file is created unless logging categories are enabled using the Tracing/Verbosity or Tracing/EnabledCategory settings.

                  -
                • Full path: //OpenSplice/DDSI2EService/Tracing/OutputFile
                • +
                • Full path: /DDSI2Service/Tracing/OutputFile
                • Format: string
                • Default value: ddsi2.log
                • Occurrences min-max: 0-1
                -

                8.14.4   PacketCaptureFile¶

                +

                8.11.4   PacketCaptureFile¶

                This option specifies the file to which received and sent packets will be logged in the “pcap” format suitable for analysis using common networking tools, such as WireShark. IP and UDP headers are ficitious, in particular the destination address of received packets. The TTL may be used to distinguish between sent and received packets: it is 255 for sent packets and 128 for received ones. Currently IPv4 only.

                  -
                • Full path: //OpenSplice/DDSI2EService/Tracing/PacketCaptureFile
                • +
                • Full path: /DDSI2Service/Tracing/PacketCaptureFile
                • Format: string
                • Occurrences min-max: 0-1
                -
                -

                8.14.5   Timestamps¶

                +
                +

                8.11.5   Timestamps¶

                This option has no effect.

                  -
                • Full path: //OpenSplice/DDSI2EService/Tracing/Timestamps
                • +
                • Full path: /DDSI2Service/Tracing/Timestamps
                • Format: boolean
                • Default value: true
                • Occurrences min-max: 0-1
                • Optional attributes: absolute
                -
                -

                8.14.5.1   absolute¶

                -

                This option has no effect

                +
                +

                8.11.5.1   absolute¶

                +

                This attribute specifies whether the timestamps in the log file are absolute or relative to the startup time of the service. Currently not implemented in DDSI2, all timestamps are absolute.

                  -
                • Full path: //OpenSplice/DDSI2EService/Tracing/Timestamps[@absolute]
                • +
                • Full path: /DDSI2Service/Tracing/Timestamps/absolute
                • Format: boolean
                • Default value: true
                • Required: false
                -
                -

                8.14.6   Verbosity¶

                +
                +

                8.11.6   Verbosity¶

                This element enables standard groups of categories, based on a desired verbosity level. This is in addition to the categories enabled by the Tracing/EnableCategory setting. Recognised verbosity levels and the categories they map to are:

                  -
                • none: no DDSI2E log
                • +
                • none: no DDSI2 log
                • severe: error and fatal
                • warning: severe + warning
                • -
                • info: warning + info
                • +
                • info: equivalent to warning
                • config: info + config
                • fine: config + discovery
                • -
                • finer: fine + traffic and timing
                • +
                • finer: fine + traffic, timing & info
                • finest: finer + trace
                -

                The categorisation of tracing output is incomplete and hence most of the verbosity levels and categories are not of much use in the current release. This is an ongoing process and here we describe the target situation rather than the current situation. Currently, the most useful verbosity levels are config, fine and finest.

                +

                While none prevents any message from being written to a DDSI2 log file, warnings and errors are still logged in the ospl-info.log and ospl-error.log files.

                +

                The categorisation of tracing output is incomplete and hence most of the verbosity levels and categories are not of much use in the current release. This is an ongoing process and here we describe the target situation rather than the current situation. Currently, the most useful verbosity levels are config and finest.

                  -
                • Full path: //OpenSplice/DDSI2EService/Tracing/Verbosity
                • +
                • Full path: /DDSI2Service/Tracing/Verbosity
                • Format: enumeration
                • Default value: none
                • Valid values: finest, finer, fine, config, info, warning, severe, none
                • @@ -10584,47 +9083,47 @@

                  8.14.6   Verbosity -

                  8.15   Watchdog¶

                  +
                  +

                  8.12   Watchdog¶

                  This element specifies the type of OS scheduling class will be used by the thread that announces its liveliness periodically.

                    -
                  • Full path: //OpenSplice/DDSI2EService/Watchdog
                  • +
                  • Full path: /DDSI2Service/Watchdog
                  • Occurrences min-max: 0-1
                  -
                  -

                  8.15.1   Scheduling¶

                  +
                  +

                  8.12.1   Scheduling¶

                  This element specifies the type of OS scheduling class will be used by the thread that announces its liveliness periodically.

                    -
                  • Full path: //OpenSplice/DDSI2EService/Watchdog/Scheduling
                  • +
                  • Full path: /DDSI2Service/Watchdog/Scheduling
                  • Occurrences min-max: 0-1
                  • Child elements: Class, Priority
                  -
                  -

                  8.15.1.1   Class¶

                  +
                  +

                  8.12.1.1   Class¶

                  This element specifies the thread scheduling class that will be used by the watchdog thread. The user may need the appropriate privileges from the underlying operating system to be able to assign some of the privileged scheduling classes.

                    -
                  • Full path: //OpenSplice/DDSI2EService/Watchdog/Scheduling/Class
                  • +
                  • Full path: /DDSI2Service/Watchdog/Scheduling/Class
                  • Format: enumeration
                  • Default value: default
                  • Valid values: realtime, timeshare, default
                  • Occurrences min-max: 0-1
                  -
                  -

                  8.15.1.2   Priority¶

                  +
                  +

                  8.12.1.2   Priority¶

                  This element specifies the thread priority. Only priorities that are supported by the underlying operating system can be assigned to this element. The user may need special privileges from the underlying operating system to be able to assign some of the privileged priorities.

                    -
                  • Full path: //OpenSplice/DDSI2EService/Watchdog/Scheduling/Priority
                  • +
                  • Full path: /DDSI2Service/Watchdog/Scheduling/Priority
                  • Format: integer
                  • Default value: 0
                  • Occurrences min-max: 0-1
                  • Optional attributes: priority_kind
                  -
                  -
                  8.15.1.2.1   priority_kind¶
                  +
                  +
                  8.12.1.2.1   priority_kind¶

                  This attribute specifies whether the specified Priority is a relative or absolute priority.

                    -
                  • Full path: //OpenSplice/DDSI2EService/Watchdog/Scheduling/Priority[@priority_kind]
                  • +
                  • Full path: /DDSI2Service/Watchdog/Scheduling/Priority/priority_kind
                  • Format: enumeration
                  • Default value: relative
                  • Valid values: relative, absolute
                  • @@ -10635,99 +9134,198 @@
                    8.15.1.2.1   priority_kind
                  -
                  -

                  9   DDSI2Service¶

                  -

                  The root element of a DDSI2 networking service configuration.

                  +
                  +

                  9   DDSI2EService¶

                  +

                  The root element of a DDSI2E networking service configuration.

                    -
                  • Full path: //OpenSplice/DDSI2Service
                  • +
                  • Full path: /DDSI2EService
                  • Occurrences min-max: 0-*
                  • Required attributes: name
                  -
                  -

                  9.1   name¶

                  -

                  This attribute identifies the configuration for the DDSI2 Service. Multiple DDSI2 service configurations can be specified in one single resource. The actual applicable configuration is determined by the value of the name attribute, which must match the specified under the element OpenSplice/Domain/Service[@name] in the Domain Service configuration.

                  +
                  +

                  9.1   name¶

                  +

                  This attribute identifies the configuration for the DDSI2E Service. Multiple DDSI2E service configurations can be specified in one single resource. The actual applicable configuration is determined by the value of the name attribute, which must match the specified under the element OpenSplice/Domain/Service[@name] in the Domain Service configuration.

                    -
                  • Full path: //OpenSplice/DDSI2Service[@name]
                  • +
                  • Full path: /DDSI2EService/name
                  • Format: string
                  • -
                  • Default value: ddsi2
                  • +
                  • Default value: ddsi2e
                  • Required: true
                  -
                  -

                  9.2   Compatibility¶

                  +
                  +

                  9.2   Channels¶

                  +

                  This element is used to group a set of channels. The channels are independent data paths through DDSI2E and by using separate threads and setting their priorities appropriately, chanenls can be used to map transport priorities to operating system scheduler priorities, ensuring system-wide end-to-end priority preservation.

                  +
                    +
                  • Full path: /DDSI2EService/Channels
                  • +
                  • Occurrences min-max: 0-1
                  • +
                  +
                  +

                  9.2.1   Channel¶

                  +

                  This element defines a channel.

                  +
                    +
                  • Full path: /DDSI2EService/Channels/Channel
                  • +
                  • Occurrences min-max: 0-42
                  • +
                  • Child elements: AuxiliaryBandwidthLimit, DataBandwidthLimit, DiffServField, QueueSize, Resolution
                  • +
                  • Required attributes: Name
                  • +
                  • Optional attributes: TransportPriority
                  • +
                  +
                  +

                  9.2.1.1   Name¶

                  +

                  This attribute specifies name of this channel. The name should uniquely identify the channel.

                  +
                    +
                  • Full path: /DDSI2EService/Channels/Channel/Name
                  • +
                  • Format: string
                  • +
                  • Default value: n/a
                  • +
                  • Required: true
                  • +
                  +
                  +
                  +

                  9.2.1.2   TransportPriority¶

                  +

                  This attribute sets the transport priority threshold for the channel. Each DCPS data writer has a “transport_priority” QoS and this QoS is used to select a channel for use by this writer. The selected channel is the one with the largest threshold not greater than the writer’s transport priority, and if no such channel exists, the channel with the lowest threshold.

                  +
                    +
                  • Full path: /DDSI2EService/Channels/Channel/TransportPriority
                  • +
                  • Format: integer
                  • +
                  • Default value: 0
                  • +
                  • Required: false
                  • +
                  +
                  +
                  +

                  9.2.1.3   AuxiliaryBandwidthLimit¶

                  +

                  This element specifies the maximum transmit rate of auxiliary traffic on this channel (e.g. retransmits, heartbeats, etc). Bandwidth limiting uses a leaky bucket scheme. The default value “inf” means DDSI2E imposes no limitation, the underlying operating system and hardware will likely limit the maimum transmit rate. +The unit must be specified explicitly. Recognised units: X*b/s, *X*bps for bits/s or *X*B/s, *X*Bps for bytes/s; where *X is an optional prefix: k for 10 3, Ki for 2 10, M for 10 6, Mi for 2 20, G for 10 9, Gi for 2 30.

                  +
                    +
                  • Full path: /DDSI2EService/Channels/Channel/AuxiliaryBandwidthLimit
                  • +
                  • Format: string
                  • +
                  • Default value: inf
                  • +
                  • Occurrences min-max: 0-1
                  • +
                  +
                  +
                  +

                  9.2.1.4   DataBandwidthLimit¶

                  +

                  This element specifies the maximum transmit rate of new samples and directly related data, for this channel. Bandwidth limiting uses a leaky bucket scheme. The default value “inf” means DDSI2E imposes no limitation, the underlying operating system and hardware will likely limit the maimum transmit rate.

                  +

                  The unit must be specified explicitly. Recognised units: X*b/s, *X*bps for bits/s or *X*B/s, *X*Bps for bytes/s; where *X is an optional prefix: k for 10 3, Ki for 2 10, M for 10 6, Mi for 2 20, G for 10 9, Gi for 2 30.

                  +
                    +
                  • Full path: /DDSI2EService/Channels/Channel/DataBandwidthLimit
                  • +
                  • Format: string
                  • +
                  • Default value: inf
                  • +
                  • Occurrences min-max: 0-1
                  • +
                  +
                  +
                  +

                  9.2.1.5   DiffServField¶

                  +

                  This element describes the DiffServ setting the channel will apply to the networking messages. This parameter determines the value of the diffserv field of the IP version 4 packets send on this channel which allows QoS setting to be applied to the network traffic send on this channel.

                  +

                  Windows platform support for setting the diffserv field is dependent on the OS version.

                  +

                  For Windows versions XP SP2 and 2003 to use the diffserv field the following parameter should be added to the register:

                  +

                  HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\TcpIp\Parameters\DisableUserTOSSetting

                  +

                  The type of this parameter is a DWORD and it’s value should be set to 0 to allow setting of the diffserv field.

                  +

                  For Windows version 7 or higher a new API (qWAVE) has been introduced For these platforms the specified diffserv value is mapped to one of the support traffic types. +The mapping is as follows: 1-8 background traffic; 9-40 excellent traffic; 41-55 audio/video traffic; 56 voice traffic; 57-63 control traffic. +When an application is run without Administrative priveleges then only the diffserv value of 0, 8, 40 or 56 is allowed.

                  +
                    +
                  • Full path: /DDSI2EService/Channels/Channel/DiffServField
                  • +
                  • Format: integer
                  • +
                  • Default value: 0
                  • +
                  • Occurrences min-max: 0-1
                  • +
                  +
                  +
                  +

                  9.2.1.6   QueueSize¶

                  +

                  This element specifies the number of messages the network queue for this channel can contain. The OpenSplice kernel writes data to be transmitted to the network queue, and DDSI2E takes them from this queue. If this queue is full when an application tries to write a sample, the sample will be dropped or the writer suspended, depending on the QoS settings of the writer. OpenSplice and its services are optimised for a well-balanced system design, where the queue never becomes full.

                  +
                    +
                  • Full path: /DDSI2EService/Channels/Channel/QueueSize
                  • +
                  • Format: integer
                  • +
                  • Default value: 0
                  • +
                  • Occurrences min-max: 0-1
                  • +
                  +
                  +
                  +

                  9.2.1.7   Resolution¶

                  +

                  This element specifies the interval at which the DDSI transmit thread for this channel wakes up, and which controls the smallest latency_budget that has an effect. A shorter latency_budget is rounded to 0. The downside of a reducing this setting is that it increases the number of idle wake-ups of the transmit thread when there is no data to be sent.

                  +

                  Valid values are finite durations with an explicit unit or the keyword ‘inf’ for infinity. Recognised units: ns, us, ms, s, min, hr, day.

                  +
                    +
                  • Full path: /DDSI2EService/Channels/Channel/Resolution
                  • +
                  • Format: string
                  • +
                  • Default value: 1s
                  • +
                  • Occurrences min-max: 0-1
                  • +
                  +
                  +
                  +
                  +
                  +

                  9.3   Compatibility¶

                  The Compatibility elements allows specifying various settings related to compatability with standards and with other DDSI implementations.

                    -
                  • Full path: //OpenSplice/DDSI2Service/Compatibility
                  • +
                  • Full path: /DDSI2EService/Compatibility
                  • Occurrences min-max: 0-1
                  • Child elements: AckNackNumbitsEmptySet, ArrivalOfDataAssertsPpAndEpLiveliness, AssumeRtiHasPmdEndpoints, ExplicitlyPublishQosSetToDefault, ManySocketsMode, RespondToRtiInitZeroAckWithInvalidHeartbeat, StandardsConformance
                  -
                  -

                  9.2.1   AckNackNumbitsEmptySet¶

                  +
                  +

                  9.3.1   AckNackNumbitsEmptySet¶

                  This element governs the representation of an acknowledgement message that does not also negatively-acknowledge some samples. If set to 0, the generated acknowledgements have an invalid form and will be reject by the strict and pedantic conformance modes, but several other implementation require this setting for smooth interoperation.

                  -

                  If set to 1, all acknowledgements sent by DDSI2 adhere the form of acknowledgement messages allowed by the standard, but this causes problems when interoperating with these other implementations. The strict and pedantic standards conformance modes always overrule an AckNackNumbitsEmptySet=0 to prevent the transmitting of invalid messages.

                  +

                  If set to 1, all acknowledgements sent by DDSI2E adhere the form of acknowledgement messages allowed by the standard, but this causes problems when interoperating with these other implementations. The strict and pedantic standards conformance modes always overrule a AckNackNumbitsEmptySet=0 to prevent the transmitting of invalid messages.

                    -
                  • Full path: //OpenSplice/DDSI2Service/Compatibility/AckNackNumbitsEmptySet
                  • +
                  • Full path: /DDSI2EService/Compatibility/AckNackNumbitsEmptySet
                  • Format: integer
                  • Default value: 0
                  • Occurrences min-max: 0-1
                  -
                  -

                  9.2.2   ArrivalOfDataAssertsPpAndEpLiveliness¶

                  -

                  When set to true, arrival of a message from a peer asserts liveliness of that peer. When set to false, only SPDP and explicit lease renewals have this effect.

                  +
                  +

                  9.3.2   ArrivalOfDataAssertsPpAndEpLiveliness¶

                  +

                  This setting is currently ignored (accepted for backwards compatibility).

                    -
                  • Full path: //OpenSplice/DDSI2Service/Compatibility/ArrivalOfDataAssertsPpAndEpLiveliness
                  • +
                  • Full path: /DDSI2EService/Compatibility/ArrivalOfDataAssertsPpAndEpLiveliness
                  • Format: boolean
                  • Default value: true
                  • Occurrences min-max: 0-1
                  -
                  -

                  9.2.3   AssumeRtiHasPmdEndpoints¶

                  +
                  +

                  9.3.3   AssumeRtiHasPmdEndpoints¶

                  This option assumes ParticipantMessageData endpoints required by the liveliness protocol are present in RTI participants even when not properly advertised by the participant discovery protocol.

                    -
                  • Full path: //OpenSplice/DDSI2Service/Compatibility/AssumeRtiHasPmdEndpoints
                  • +
                  • Full path: /DDSI2EService/Compatibility/AssumeRtiHasPmdEndpoints
                  • Format: boolean
                  • Default value: false
                  • Occurrences min-max: 0-1
                  -
                  -

                  9.2.4   ExplicitlyPublishQosSetToDefault¶

                  +
                  +

                  9.3.4   ExplicitlyPublishQosSetToDefault¶

                  This element specifies whether QoS settings set to default values are explicitly published in the discovery protocol. Implementations are to use the default value for QoS settings not published, which allows a significant reduction of the amount of data that needs to be exchanged for the discovery protocol, but this requires all implementations to adhere to the default values specified by the specifications.

                  When interoperability is required with an implementation that does not follow the specifications in this regard, setting this option to true will help.

                    -
                  • Full path: //OpenSplice/DDSI2Service/Compatibility/ExplicitlyPublishQosSetToDefault
                  • +
                  • Full path: /DDSI2EService/Compatibility/ExplicitlyPublishQosSetToDefault
                  • Format: boolean
                  • Default value: false
                  • Occurrences min-max: 0-1
                  -
                  -

                  9.2.5   ManySocketsMode¶

                  -

                  This option specifies whether a network socket will be created for each domain participant on a host. The specification seems to assume that each participant has a unique address, and setting this option will ensure this to be the case. This is not the defeault.

                  -

                  Disabling it slightly improves performance and reduces network traffic somewhat. It also causes the set of port numbers needed by DDSI2 to become predictable, which may be useful for firewall and NAT configuration.

                  +
                  +

                  9.3.5   ManySocketsMode¶

                  +

                  This option specifies whether a network socket will be created for each domain participant on a host. The specification seems to assume that each participant has a unique address, and setting this option will ensure this to be the case. This is not the default.

                  +

                  Disabling it slightly improves performance and reduces network traffic somewhat. It also causes the set of port numbers needed by DDSI2E to become predictable, which may be useful for firewall and NAT configuration.

                    -
                  • Full path: //OpenSplice/DDSI2Service/Compatibility/ManySocketsMode
                  • +
                  • Full path: /DDSI2EService/Compatibility/ManySocketsMode
                  • Format: boolean
                  • Default value: false
                  • Occurrences min-max: 0-1
                  -
                  -

                  9.2.6   RespondToRtiInitZeroAckWithInvalidHeartbeat¶

                  +
                  +

                  9.3.6   RespondToRtiInitZeroAckWithInvalidHeartbeat¶

                  This element allows a closer mimicking of the behaviour of some other DDSI implementations, albeit at the cost of generating even more invalid messages. Setting it to true ensures a Heartbeat can be sent at any time when a remote node requests one, setting it to false delays it until a valid one can be sent.

                  The latter is fully compliant with the specification, and no adverse effects have been observed. It is the default.

                    -
                  • Full path: //OpenSplice/DDSI2Service/Compatibility/RespondToRtiInitZeroAckWithInvalidHeartbeat
                  • +
                  • Full path: /DDSI2EService/Compatibility/RespondToRtiInitZeroAckWithInvalidHeartbeat
                  • Format: boolean
                  • Default value: false
                  • Occurrences min-max: 0-1
                  -
                  -

                  9.2.7   StandardsConformance¶

                  -

                  This element sets the level of standards conformance of this instance of the DDSI2 Service. Stricter conformance typically means less interoperability with other implementations. Currently three modes are defined:

                  +
                  +

                  9.3.7   StandardsConformance¶

                  +

                  This element sets the level of standards conformance of this instance of the DDSI2E Service. Stricter conformance typically means less interoperability with other implementations. Currently three modes are defined:

                  • pedantic: very strictly conform to the specification, ultimately for compliancy testing, but currently of little value because it adheres even to what will most likely turn out to be editing errors in the DDSI standard. Arguably, as long as no errata have been published it is the current text that is in effect, and that is what pedantic currently does.
                  • strict: a slightly less strict view of the standard than does pedantic: it follows the established behaviour where the standard is obviously in error.
                  • @@ -10735,7 +9333,7 @@

                    9.2.7   StandardsConformance -
                  • Full path: //OpenSplice/DDSI2Service/Compatibility/StandardsConformance
                  • +
                  • Full path: /DDSI2EService/Compatibility/StandardsConformance
                  • Format: enumeration
                  • Default value: lax
                  • Valid values: lax, strict, pedantic
                  • @@ -10743,77 +9341,81 @@

                    9.2.7   StandardsConformance -

                    9.3   Discovery¶

                    +
                    +

                    9.4   Discovery¶

                    The Discovery element allows specifying various parameters related to the discovery of peers.

                      -
                    • Full path: //OpenSplice/DDSI2Service/Discovery
                    • +
                    • Full path: /DDSI2EService/Discovery
                    • Occurrences min-max: 0-1
                    • -
                    • Child elements: AdvertiseBuiltinTopicWriters, DefaultMulticastAddress, DomainId, GenerateBuiltinTopics, LocalDiscoveryPartition, MaxAutoParticipantIndex, ParticipantIndex, SPDPInterval, SPDPMulticastAddress
                    • +
                    • Child elements: DefaultMulticastAddress, DomainId, DSClusterLeaseDuration, GenerateBuiltinTopics, LocalDiscoveryPartition, MaxAutoParticipantIndex, ParticipantIndex, SPDPInterval, SPDPMulticastAddress
                    -
                    -

                    9.3.1   AdvertiseBuiltinTopicWriters¶

                    -

                    This element controls whether or not DDSI2 advertises writers for the built-in topics from its discovery for backwards compatibility with older OpenSplice versions.

                    +
                    +

                    9.4.1   DefaultMulticastAddress¶

                    +
                    +
                    This element specifies the default multicast address for all multicast traffic other than the SPDP participant discovery data. The default value “auto” uses the configured SPDPMulticastAddress. On source-specific multicast capable platforms, this is may be an source-specific multicast address.
                      -
                    • Full path: //OpenSplice/DDSI2Service/Discovery/AdvertiseBuiltinTopicWriters
                    • -
                    • Format: boolean
                    • -
                    • Default value: true
                    • +
                    • Full path: /DDSI2EService/Discovery/DefaultMulticastAddress
                    • +
                    • Format: string
                    • +
                    • Default value: auto
                    • Occurrences min-max: 0-1
                    -
                    -

                    9.3.2   DefaultMulticastAddress¶

                    -

                    This element specifies the default multicast address for all traffic other than participant discovery packets. It defaults to Discovery/SPDPMulticastAddress.

                    +
                    +

                    9.4.2   DomainId¶

                    +

                    This element allows overriding of the DDS Domain Id that is used for this DDSI2E service.

                      -
                    • Full path: //OpenSplice/DDSI2Service/Discovery/DefaultMulticastAddress
                    • +
                    • Full path: /DDSI2EService/Discovery/DomainId
                    • Format: string
                    • -
                    • Default value: auto
                    • +
                    • Default value: default
                    • Occurrences min-max: 0-1
                    -
                    -

                    9.3.3   DomainId¶

                    -

                    This element allows overriding of the DDS Domain Id that is used for DDSI2.

                    +
                    +

                    9.4.3   DSClusterLeaseDuration¶

                    +
                    +

                    This element specifies the lease duration for entities discovered through a discovery service.

                    +

                    Valid values are finite durations with an explicit unit or the keyword ‘inf’ for infinity. Recognised units: ns, us, ms, s, min, hr, day.

                    +
                      -
                    • Full path: //OpenSplice/DDSI2Service/Discovery/DomainId
                    • +
                    • Full path: /DDSI2EService/Discovery/DSClusterLeaseDuration
                    • Format: string
                    • -
                    • Default value: default
                    • +
                    • Default value: 300 s
                    • Occurrences min-max: 0-1
                    -
                    -

                    9.3.4   GenerateBuiltinTopics¶

                    -

                    This element controls whether or not DDSI2 generates built-in topics from its discovery. When disabled, it relies on the durability service.

                    +
                    +

                    9.4.4   GenerateBuiltinTopics¶

                    +

                    This element controls whether or not the DDSI2E service generates built-in topics from its discovery. When disabled, it relies on the durability service.

                      -
                    • Full path: //OpenSplice/DDSI2Service/Discovery/GenerateBuiltinTopics
                    • +
                    • Full path: /DDSI2EService/Discovery/GenerateBuiltinTopics
                    • Format: boolean
                    • Default value: true
                    • Occurrences min-max: 0-1
                    -
                    -

                    9.3.5   LocalDiscoveryPartition¶

                    -

                    This element controls which partition is monitored by DDSI2 for built-in topics describing entities the it mirrors in DDSI.

                    +
                    +

                    9.4.5   LocalDiscoveryPartition¶

                    +

                    This element controls which partition is monitored by DDSI2E for built-in topics describing entities the it mirrors in DDSI.

                      -
                    • Full path: //OpenSplice/DDSI2Service/Discovery/LocalDiscoveryPartition
                    • +
                    • Full path: /DDSI2EService/Discovery/LocalDiscoveryPartition
                    • Format: string
                    • -
                    • Default value: __BUILT_IN_PARTITION__
                    • +
                    • Default value: __BUILT-IN PARTITION__
                    • Occurrences min-max: 0-1
                    -
                    -

                    9.3.6   MaxAutoParticipantIndex¶

                    -

                    This element specifies the maximum DDSI participant index selected by this instance of the DDSI2 service if the Discovery/ParticipantIndex is “auto”.

                    +
                    +

                    9.4.6   MaxAutoParticipantIndex¶

                    +

                    This element specifies the maximum DDSI participant index selected by this instance of the DDSI2E service if the Discovery/ParticipantIndex is “auto”.

                      -
                    • Full path: //OpenSplice/DDSI2Service/Discovery/MaxAutoParticipantIndex
                    • +
                    • Full path: /DDSI2EService/Discovery/MaxAutoParticipantIndex
                    • Format: integer
                    • Default value: 9
                    • Occurrences min-max: 0-1
                    -
                    -

                    9.3.7   ParticipantIndex¶

                    -

                    This element specifies the DDSI participant index used by this instance of the DDSI2 service for discovery purposes. Only one such participant id is used, independent of the number of actual DomainParticipants on the node. It is either:

                    +
                    +

                    9.4.7   ParticipantIndex¶

                    +

                    This element specifies the DDSI participant index used by this instance of the DDSI2E service for discovery purposes. Only one such participant id is used, independent of the number of actual DomainParticipants on the node. It is either:

                    -
                    -

                    9.3.8   Peers¶

                    +
                    +

                    9.4.8   Peers¶

                    This element statically configures addresses for discovery.

                      -
                    • Full path: //OpenSplice/DDSI2Service/Discovery/Peers
                    • +
                    • Full path: /DDSI2EService/Discovery/Peers
                    • Occurrences min-max: 0-1
                    -
                    -

                    9.3.8.1   Group¶

                    +
                    +

                    9.4.8.1   Group¶

                    This element statically configures a fault tolerant group of addresses for discovery. Each member of the group is tried in sequence until one succeeds.

                      -
                    • Full path: //OpenSplice/DDSI2Service/Discovery/Peers/Group
                    • +
                    • Full path: /DDSI2EService/Discovery/Peers/Group
                    • Occurrences min-max: 0-*
                    -
                    -
                    9.3.8.1.1   Peer¶
                    +
                    +
                    9.4.8.1.1   Peer¶

                    This element statically configures an addresses for discovery.

                      -
                    • Full path: //OpenSplice/DDSI2Service/Discovery/Peers/Group/Peer
                    • +
                    • Full path: /DDSI2EService/Discovery/Peers/Group/Peer
                    • Occurrences min-max: 0-*
                    • Required attributes: Address
                    -
                    -
                    9.3.8.1.1.1   Address¶
                    -

                    This element specifies an IP address to which discovery packets must be sent, in addition to the default multicast address (see also General/AllowMulticast). Both a hostnames and a numerical IP address is accepted; the hostname or IP address may be suffixed with :PORT to explicitly set the port to which it must be sent. Multiple Peers may be specified.

                    +
                    +
                    9.4.8.1.1.1   Address¶
                    +

                    This element specifies an IP address to which discovery packets must be sent, in addition to the default multicast address (see also General/AllowMulticast and Internal/SuppressSPDPMulticast). Both a hostnames and a numerical IP address is accepted; the hostname or IP address may be suffixed with :PORT to explicitly set the port to which it must be sent. Multiple Peers may be specified.

                      -
                    • Full path: //OpenSplice/DDSI2Service/Discovery/Peers/Group/Peer[@Address]
                    • +
                    • Full path: /DDSI2EService/Discovery/Peers/Group/Peer/Address
                    • Format: string
                    • Default value: n/a
                    • Required: true
                    • @@ -10861,19 +9463,19 @@
                      9.3.8.1.1.1   Address
                    -
                    -

                    9.3.8.2   Peer¶

                    -

                    This element statically configures an addresses for discovery.

                    +
                    +

                    9.4.8.2   Peer¶

                    +

                    This element statically configures an address for discovery.

                      -
                    • Full path: //OpenSplice/DDSI2Service/Discovery/Peers/Peer
                    • +
                    • Full path: /DDSI2EService/Discovery/Peers/Peer
                    • Occurrences min-max: 0-*
                    • Required attributes: Address
                    -
                    -
                    9.3.8.2.1   Address¶
                    -

                    This element specifies an IP address to which discovery packets must be sent, in addition to the default multicast address (see also General/AllowMulticast). Both a hostnames and a numerical IP address is accepted; the hostname or IP address may be suffixed with :PORT to explicitly set the port to which it must be sent. Multiple Peers may be specified.

                    +
                    +
                    9.4.8.2.1   Address¶
                    +

                    This element specifies an IP address to which discovery packets must be sent, in addition to the default multicast address (see also General/AllowMulticast and Internal/SuppressSPDPMulticast). Both a hostnames and a numerical IP address is accepted; the hostname or IP address may be suffixed with :PORT to explicitly set the port to which it must be sent. Multiple Peers may be specified.

                      -
                    • Full path: //OpenSplice/DDSI2Service/Discovery/Peers/Peer[@Address]
                    • +
                    • Full path: /DDSI2EService/Discovery/Peers/Peer/Address
                    • Format: string
                    • Default value: n/a
                    • Required: true
                    • @@ -10881,320 +9483,305 @@
                      9.3.8.2.1   Address
                    -
                    -

                    9.3.9   Ports¶

                    +
                    +

                    9.4.9   Ports¶

                    The Ports element allows specifying various parameters related to the port numbers used for discovery. These all have default values specified by the DDSI 2.1 specification and rarely need to be changed.

                    +

                    Valid values are finite durations with an explicit unit or the keyword ‘inf’ for infinity. Recognised units: ns, us, ms, s, min, hr, day.

                      -
                    • Full path: //OpenSplice/DDSI2Service/Discovery/Ports
                    • +
                    • Full path: /DDSI2EService/Discovery/Ports
                    • Occurrences min-max: 0-1
                    • Child elements: Base, DomainGain, MulticastDataOffset, MulticastMetaOffset, ParticipantGain, UnicastDataOffset, UnicastMetaOffset
                    -
                    -

                    9.3.9.1   Base¶

                    +
                    +

                    9.4.9.1   Base¶

                    This element specifies the base port number (refer to the DDSI 2.1 specification, section 9.6.1, constant PB).

                      -
                    • Full path: //OpenSplice/DDSI2Service/Discovery/Ports/Base
                    • +
                    • Full path: /DDSI2EService/Discovery/Ports/Base
                    • Format: integer
                    • Default value: 7400
                    • -
                    • Valid values: 1 / 65535
                    • Occurrences min-max: 0-1
                    -
                    -

                    9.3.9.2   DomainGain¶

                    +
                    +

                    9.4.9.2   DomainGain¶

                    This element specifies the domain gain, relating domain ids to sets of port numbers (refer to the DDSI 2.1 specification, section 9.6.1, constant DG).

                      -
                    • Full path: //OpenSplice/DDSI2Service/Discovery/Ports/DomainGain
                    • +
                    • Full path: /DDSI2EService/Discovery/Ports/DomainGain
                    • Format: integer
                    • Default value: 250
                    • Occurrences min-max: 0-1
                    -
                    -

                    9.3.9.3   MulticastDataOffset¶

                    +
                    +

                    9.4.9.3   MulticastDataOffset¶

                    This element specifies the port number for multicast meta traffic (refer to the DDSI 2.1 specification, section 9.6.1, constant d2).

                      -
                    • Full path: //OpenSplice/DDSI2Service/Discovery/Ports/MulticastDataOffset
                    • +
                    • Full path: /DDSI2EService/Discovery/Ports/MulticastDataOffset
                    • Format: integer
                    • Default value: 1
                    • Occurrences min-max: 0-1
                    -
                    -

                    9.3.9.4   MulticastMetaOffset¶

                    +
                    +

                    9.4.9.4   MulticastMetaOffset¶

                    This element specifies the port number for multicast meta traffic (refer to the DDSI 2.1 specification, section 9.6.1, constant d0).

                      -
                    • Full path: //OpenSplice/DDSI2Service/Discovery/Ports/MulticastMetaOffset
                    • +
                    • Full path: /DDSI2EService/Discovery/Ports/MulticastMetaOffset
                    • Format: integer
                    • Default value: 0
                    • Occurrences min-max: 0-1
                    -
                    -

                    9.3.9.5   ParticipantGain¶

                    +
                    +

                    9.4.9.5   ParticipantGain¶

                    This element specifies the participant gain, relating p0, articipant index to sets of port numbers (refer to the DDSI 2.1 specification, section 9.6.1, constant PG).

                      -
                    • Full path: //OpenSplice/DDSI2Service/Discovery/Ports/ParticipantGain
                    • +
                    • Full path: /DDSI2EService/Discovery/Ports/ParticipantGain
                    • Format: integer
                    • Default value: 2
                    • Occurrences min-max: 0-1
                    -
                    -

                    9.3.9.6   UnicastDataOffset¶

                    +
                    +

                    9.4.9.6   UnicastDataOffset¶

                    This element specifies the port number for unicast meta traffic (refer to the DDSI 2.1 specification, section 9.6.1, constant d3).

                      -
                    • Full path: //OpenSplice/DDSI2Service/Discovery/Ports/UnicastDataOffset
                    • +
                    • Full path: /DDSI2EService/Discovery/Ports/UnicastDataOffset
                    • Format: integer
                    • Default value: 11
                    • Occurrences min-max: 0-1
                    -
                    -

                    9.3.9.7   UnicastMetaOffset¶

                    +
                    +

                    9.4.9.7   UnicastMetaOffset¶

                    This element specifies the port number for unicast meta traffic (refer to the DDSI 2.1 specification, section 9.6.1, constant d1).

                      -
                    • Full path: //OpenSplice/DDSI2Service/Discovery/Ports/UnicastMetaOffset
                    • +
                    • Full path: /DDSI2EService/Discovery/Ports/UnicastMetaOffset
                    • Format: integer
                    • Default value: 10
                    • Occurrences min-max: 0-1
                    -
                    -

                    9.3.10   SPDPInterval¶

                    +
                    +

                    9.4.10   SPDPInterval¶

                    This element specifies the interval between spontaneous transmissions of participant discovery packets.

                    The unit must be specified explicitly. Recognised units: ns, us, ms, s, min, hr, day.

                      -
                    • Full path: //OpenSplice/DDSI2Service/Discovery/SPDPInterval
                    • +
                    • Full path: /DDSI2EService/Discovery/SPDPInterval
                    • Format: string
                    • Default value: 30 s
                    • -
                    • Valid values: 0 / 1hr
                    • Occurrences min-max: 0-1
                    -
                    -

                    9.3.11   SPDPMulticastAddress¶

                    +
                    +

                    9.4.11   SPDPMulticastAddress¶

                    This element specifies the multicast address that is used as the destination for the participant discovery packets. In IPv4 mode the default is the (standardised) 239.255.0.1, in IPv6 mode it becomes ff02::ffff:239.255.0.1, which is a non-standardised link-local multicast address.

                      -
                    • Full path: //OpenSplice/DDSI2Service/Discovery/SPDPMulticastAddress
                    • +
                    • Full path: /DDSI2EService/Discovery/SPDPMulticastAddress
                    • Format: string
                    • Default value: 239.255.0.1
                    • Occurrences min-max: 0-1
                    -
                    -

                    9.4   General¶

                    -

                    The General element specifies overall DDSI2 service settings.

                    +
                    +

                    9.5   General¶

                    +

                    The General element specifies overall DDSI2E service settings.

                      -
                    • Full path: //OpenSplice/DDSI2Service/General
                    • +
                    • Full path: /DDSI2EService/General
                    • Occurrences min-max: 0-1
                    • -
                    • Child elements: AllowMulticast, CoexistWithNativeNetworking, DontRoute, EnableMulticastLoopback, ExternalNetworkAddress, ExternalNetworkMask, FragmentSize, MaxMessageSize, MulticastRecvNetworkInterfaceAddresses, MulticastTimeToLive, NetworkInterfaceAddress, StartupModeCoversTransient, StartupModeDuration, UseIPv6
                    • +
                    • Child elements: AllowMulticast, CoexistWithNativeNetworking, DontRoute, EnableMulticastLoopback, ExternalNetworkAddress, ExternalNetworkMask, MulticastRecvNetworkInterfaceAddresses, MulticastTimeToLive, NetworkInterfaceAddress, StartupModeCoversTransient, StartupModeDuration, UseIPv6
                    -
                    -

                    9.4.1   AllowMulticast¶

                    -

                    This element controls whether DDSI2 uses multicasts for data traffic.

                    -

                    It is a comma-separated list of some of the following keywords: “spdp”, “asm”, “ssm”, or either of “false” or “true”.

                    +
                    +

                    9.5.1   AllowMulticast¶

                    +

                    This element controls whether the DDSI2E service uses multicasts for data traffic. It is a comma-separated list of keywords, with the following keywords defined:

                      -
                    • spdp: enables the use of ASM (any-source multicast) for participant discovery
                    • -
                    • asm: enables the use of ASM for all traffic (including SPDP)
                    • -
                    • ssm: enables the use of SSM (source-specific multicast) for all non-SPDP traffic (if supported)
                    • +
                    • spdp: allow multicast for the SPDP participant discovery protocol. This is the initial step in the discovery protocol, and benefits tremendously from using multicast.
                    • +
                    • asm: allow (any-source) multicast for all traffic.
                    • +
                    • ssm: allow source-specific multicast for all traffic (on supported platforms).
                    -

                    When set to “false” all multicasting is disabled. The default, “true” enables full use of multicasts. Listening for multicasts can be controlled by General/MulticastRecvNetworkInterfaceAddresses.

                    +

                    Additionally, “false” is allowed as a synonym for an empty list, and “true” for “spdp,asm,ssm”.

                    +

                    The default is to allow unlimited use of multicast.

                      -
                    • Full path: //OpenSplice/DDSI2Service/General/AllowMulticast
                    • +
                    • Full path: /DDSI2EService/General/AllowMulticast
                    • Format: string
                    • Default value: true
                    • Occurrences min-max: 0-1
                    -
                    -

                    9.4.2   CoexistWithNativeNetworking¶

                    -

                    This element specifies whether the DDSI2 service operates in conjunction with the OpenSplice RT Networking service. When “false”, the DDSI2 service will take care of all communications, including those between OpenSplice nodes; when “true”, the DDSI2 service only communicates with DDS implementations other than OpenSplice. In this case the RT Networking service should be configured as well.

                    +
                    +

                    9.5.2   CoexistWithNativeNetworking¶

                    +

                    This element specifies whether the DDSI2E service operates in conjunction with the OpenSplice RT Networking service. When “false”, the DDSI2E service will take care of all communications, including those between OpenSplice nodes; when “true”, the DDSI2E service only communicates with DDS implementations other than OpenSplice. In this case the RT Networking service should be configured as well.

                      -
                    • Full path: //OpenSplice/DDSI2Service/General/CoexistWithNativeNetworking
                    • +
                    • Full path: /DDSI2EService/General/CoexistWithNativeNetworking
                    • Format: boolean
                    • Default value: false
                    • Occurrences min-max: 0-1
                    -
                    -

                    9.4.3   DontRoute¶

                    +
                    +

                    9.5.3   DontRoute¶

                    This element allows setting the SO_DONTROUTE option for outgoing packets, to bypass the local routing tables. This is generally useful only when the routing tables cannot be trusted, which is highly unusual.

                      -
                    • Full path: //OpenSplice/DDSI2Service/General/DontRoute
                    • +
                    • Full path: /DDSI2EService/General/DontRoute
                    • Format: boolean
                    • Default value: false
                    • Occurrences min-max: 0-1
                    -
                    -

                    9.4.4   EnableMulticastLoopback¶

                    -

                    This element specifies whether DDSI2 allows IP multicast packets to be visible to all DDSI participants in the same node, including itself. It must be “true” for intra-node multicast communications, but if a node runs only a single DDSI2 service and does not host any other DDSI-capable programs, it should be set to “false” for improved performance.

                    +
                    +

                    9.5.4   EnableMulticastLoopback¶

                    +

                    This element specifies whether the DDSI2E service will allow IP multicast packets to be visible to all DDSI participants in the same node, including itself. It must be “true” for intra-node multicast communications, but if a node runs only a single DDSI2E service and does not host any other DDSI-capable programs, it may be set to “false” for improved performance.

                      -
                    • Full path: //OpenSplice/DDSI2Service/General/EnableMulticastLoopback
                    • +
                    • Full path: /DDSI2EService/General/EnableMulticastLoopback
                    • Format: boolean
                    • Default value: true
                    • Occurrences min-max: 0-1
                    -
                    -

                    9.4.5   ExternalNetworkAddress¶

                    -

                    This element allows explicitly overruling the network address DDSI2 advertises in the discovery protocol, which by default is the address of the preferred network interface (General/NetworkInterfaceAddress), to allow DDSI2 to communicate across a Network Address Translation (NAT) device.

                    +
                    +

                    9.5.5   ExternalNetworkAddress¶

                    +

                    This element allows explicitly overruling the network address the DDSI2E service advertises in the discovery protocol, which by default is the address of the preferred network interface (General/NetworkInterfaceAddress), to allow DDSI2E to communicate across a Network Address Translation (NAT) device.

                      -
                    • Full path: //OpenSplice/DDSI2Service/General/ExternalNetworkAddress
                    • +
                    • Full path: /DDSI2EService/General/ExternalNetworkAddress
                    • Format: string
                    • Default value: auto
                    • Occurrences min-max: 0-1
                    -
                    -

                    9.4.6   ExternalNetworkMask¶

                    +
                    +

                    9.5.6   ExternalNetworkMask¶

                    This element specifies the network mask of the external network address. This element is relevant only when an external network address (General/ExternalNetworkAddress) is explicitly configured. In this case locators received via the discovery protocol that are within the same external subnet (as defined by this mask) will be translated to an internal address by replacing the network portion of the external address with the corresponding portion of the preferred network interface address. This option is IPv4-only.

                      -
                    • Full path: //OpenSplice/DDSI2Service/General/ExternalNetworkMask
                    • +
                    • Full path: /DDSI2EService/General/ExternalNetworkMask
                    • Format: string
                    • Default value: 0.0.0.0
                    • Occurrences min-max: 0-1
                    -
                    -

                    9.4.7   FragmentSize¶

                    -

                    This element specifies the size of DDSI sample fragments generated by DDSI2. Samples larger than FragmentSize are fragmented into fragments of FragmentSize bytes each, except the last one, which may be smaller. The DDSI spec mandates a minimum fragment size of 1025 bytes, but DDSI2 will do whatever size is requested, accepting fragments of which the size is at least the minimum of 1025 and FragmentSize.

                    -

                    The unit must be specified explicitly. Recognised units: B (bytes), kB & KiB (2 10 bytes), MB & MiB (2 20 bytes), GB & GiB (2 30 bytes).

                    -
                      -
                    • Full path: //OpenSplice/DDSI2Service/General/FragmentSize
                    • -
                    • Format: string
                    • -
                    • Default value: 1280 B
                    • -
                    • Occurrences min-max: 0-1
                    • -
                    -
                    -
                    -

                    9.4.8   MaxMessageSize¶

                    -

                    This element specifies the maximum size of the UDP payload that DDSI2 will generate. DDSI2 will try to maintain this limit within the bounds of the DDSI specification, which means that in some cases (especially for very low values of MaxMessageSize) larger payloads may sporadically be observed (currently up to 1192 B).

                    -

                    On some networks it may be necessary to set this item to keep the packetsize below the MTU to prevent IP fragmentation. In those cases, it is generally advisable to also consider reducing Internal/FragmentSize.

                    -

                    The unit must be specified explicitly. Recognised units: B (bytes), kB & KiB (2 10 bytes), MB & MiB (2 20 bytes), GB & GiB (2 30 bytes).

                    -
                      -
                    • Full path: //OpenSplice/DDSI2Service/General/MaxMessageSize
                    • -
                    • Format: string
                    • -
                    • Default value: 4096 B
                    • -
                    • Occurrences min-max: 0-1
                    • -
                    -
                    -
                    -

                    9.4.9   MulticastRecvNetworkInterfaceAddresses¶

                    -

                    This element specifies on which network interfaces DDSI2 listens to multicasts. The following options are available:

                    +
                    +

                    9.5.7   MulticastRecvNetworkInterfaceAddresses¶

                    +

                    This element specifies on which network interfaces DDSI2E listens to multicasts. The following options are available:

                      +
                    • preferred: listen for multicasts on the preferred interface (General/NetworkInterfaceAddress); or
                    • all: listen for multicasts on all multicast-capable interfaces; or
                    • any: listen for multicasts on the operating system default interface; or
                    • -
                    • preferred: listen for multicasts on the preferred interface (General/NetworkInterfaceAddress); or
                    • none: does not listen for multicasts on any interface; or
                    • -
                    • a comma-separated list of network addresses: configures DDSI2 to listen for multicasts on all of the listed addresses.
                    • +
                    • a comma-separated list of network addresses: configures DDSI2E to listen for multicasts on all of the listed addresses.
                    -

                    If DDSI2 is in IPv6 mode and the address of the preferred network interface is a link-local address, “all” is treated as a synonym for “preferred” and a comma-separated list is treated as “preferred” if it contains the preferred interface and as “none” if not.

                    +

                    If DDSI2E is in IPv6 mode and the address of the preferred network interface is a link-local address, “all” is treated as a synonym for “preferred” and a comma-separated list is treated as “preferred” if it contains the preferred interface and as “none” if not.

                      -
                    • Full path: //OpenSplice/DDSI2Service/General/MulticastRecvNetworkInterfaceAddresses
                    • +
                    • Full path: /DDSI2EService/General/MulticastRecvNetworkInterfaceAddresses
                    • Format: string
                    • Default value: preferred
                    • Occurrences min-max: 0-1
                    -
                    -

                    9.4.10   MulticastTimeToLive¶

                    +
                    +

                    9.5.8   MulticastTimeToLive¶

                    This element specifies the time-to-live setting for outgoing multicast packets.

                      -
                    • Full path: //OpenSplice/DDSI2Service/General/MulticastTimeToLive
                    • +
                    • Full path: /DDSI2EService/General/MulticastTimeToLive
                    • Format: integer
                    • Default value: 32
                    • -
                    • Valid values: 0 / 255
                    • Occurrences min-max: 0-1
                    -
                    -

                    9.4.11   NetworkInterfaceAddress¶

                    -

                    This element specifies the preferred network interface for use by DDSI2. The preferred network interface determines the IP address that DDSI2 advertises in the discovery protocol (but see also General/ExternalNetworkAddress), and is also the only interface over which multicasts are transmitted. The interface can be identified by its IP address, network interface name or network portion of the address. If the value “auto” is entered here, DDSI2 will select what it considers the most suitable interface.

                    +
                    +

                    9.5.9   NetworkInterfaceAddress¶

                    +

                    This element specifies the preferred network interface for use by DDSI2E. The preferred network interface determines the IP address that DDSI2E advertises in the discovery protocol (but see also General/ExternalNetworkAddress), and is also the only interface over which multicasts are transmitted. The interface can be identified by its IP address, network interface name or network portion of the address. If the value “auto” is entered here, DDSI2E will select what it considers the most suitable interface.

                      -
                    • Full path: //OpenSplice/DDSI2Service/General/NetworkInterfaceAddress
                    • +
                    • Full path: /DDSI2EService/General/NetworkInterfaceAddress
                    • Format: string
                    • Default value: auto
                    • Occurrences min-max: 0-1
                    -
                    -

                    9.4.12   StartupModeCoversTransient¶

                    -

                    This element configures whether startup-mode should also cover transient and persistent data, for configurations where the durability service does not take care of it. Configurations without defined merge policies best leave this enabled.

                    +
                    +

                    9.5.10   StartupModeCoversTransient¶

                    +

                    This element configures whether startup-mode should also cover transient and persistent data, for configurations where the durability servie does not take care of it. Configurations without defined merge policies best leave this enabled.

                      -
                    • Full path: //OpenSplice/DDSI2Service/General/StartupModeCoversTransient
                    • +
                    • Full path: /DDSI2EService/General/StartupModeCoversTransient
                    • Format: boolean
                    • Default value: true
                    • Occurrences min-max: 0-1
                    -
                    -

                    9.4.13   StartupModeDuration¶

                    -

                    This element specifies how long the DDSI2 remains in its “startup” mode. While in “startup” mode all volatile reliable data published on the local node is retained as-if it were transient-local data, allowing existing readers on remote nodes to obtain the data even though discovering them takes some time. Best-effort data by definition need not arrive, and transient and persistent data are covered by the durability service.

                    -

                    Once the system is stable, DDSI2 keeps track of the existence of remote readers whether or not matching writers exist locally, avoiding this discovery delay and ensuring this is merely a node startup issue.

                    +
                    +

                    9.5.11   StartupModeDuration¶

                    +

                    This element specifies how long the DDSI2E remains in its “startup” mode. While in “startup” mode all volatile reliable data published on the local node is retained as-if it were transient-local data, allowing existing readers on remote nodes to obtain the data even though discovering them takes some time. Best-effort data by definition need not arrive, and transient and persistent data are covered by the durability service.

                    +

                    Once the system is stable, the DDSI2E service keeps track of the existence of remote readers whether or not matching writers exist locally, avoiding this discovery delay and ensuring this is merely a node startup issue.

                    Setting General/StartupModeDuration to 0s will disable it.

                    The unit must be specified explicitly. Recognised units: ns, us, ms, s, min, hr, day.

                      -
                    • Full path: //OpenSplice/DDSI2Service/General/StartupModeDuration
                    • +
                    • Full path: /DDSI2EService/General/StartupModeDuration
                    • Format: string
                    • Default value: 2 s
                    • -
                    • Valid values: 0 / 60000
                    • Occurrences min-max: 0-1
                    -
                    -

                    9.4.14   UseIPv6¶

                    -

                    This element can be used to DDSI2 use IPv6 instead of IPv4. This is currently an either/or switch.

                    +
                    +

                    9.5.12   UseIPv6¶

                    +

                    This element can be used to make DDSI2E service use IPv6 instead of IPv4. This is currently an either/or switch.

                      -
                    • Full path: //OpenSplice/DDSI2Service/General/UseIPv6
                    • +
                    • Full path: /DDSI2EService/General/UseIPv6
                    • Format: boolean
                    • Default value: false
                    • Occurrences min-max: 0-1
                    -
                    -

                    9.5   Internal¶

                    +
                    +

                    9.6   Internal¶

                    The Internal elements deal with a variety of settings that evolving and that are not necessarily fully supported. For the vast majority of the Internal settings, the functionality per-se is supported, but the right to change the way the options control the functionality is reserved. This includes renaming or moving options.

                      -
                    • Full path: //OpenSplice/DDSI2Service/Internal
                    • +
                    • Full path: /DDSI2EService/Internal
                    • Occurrences min-max: 0-1
                    • -
                    • Child elements: AccelerateRexmitBlockSize, AggressiveKeepLastWhc, AssumeMulticastCapable, BuiltinEndpointSet, ConservativeBuiltinReaderStartup, DDSI2DirectMaxThreads, DefragReliableMaxSamples, DefragUnreliableMaxSamples, DeliveryQueueMaxSamples, ForwardAllMessages, ForwardRemoteData, GenerateKeyhash, LateAckMode, LeaseDuration, LegacyFragmentation, LogStackTraces, MaxParticipants, MaxQueuedRexmitBytes, MaxQueuedRexmitMessages, MaxSampleSize, MeasureHbToAckLatency, MinimumSocketReceiveBufferSize, MinimumSocketSendBufferSize, MirrorRemoteEntities, MonitorPort, NackDelay, PreEmptiveAckDelay, PrimaryReorderMaxSamples, PrioritizeRetransmit, RediscoveryBlacklistDuration, ResponsivenessTimeout, RetransmitMerging, RetransmitMergingPeriod, RetryOnRejectBestEffort, RetryOnRejectDuration, SPDPResponseMaxDelay, ScheduleTimeRounding, SecondaryReorderMaxSamples, SquashParticipants, SuppressSPDPMulticast, SynchronousDeliveryLatencyBound, SynchronousDeliveryPriorityThreshold, UnicastResponseToSPDPMessages, UseMulticastIfMreqn, WriterLingerDuration
                    • +
                    • Child elements: AccelerateRexmitBlockSize, AggressiveKeepLast1Whc, AssumeMulticastCapable, AuxiliaryBandwidthLimit, BuiltinEndpointSet, ConservativeBuiltinReaderStartup, DDSI2DirectMaxThreads, DefragReliableMaxSamples, DefragUnreliableMaxSamples, DeliveryQueueMaxSamples, ForwardAllMessages, ForwardRemoteData, FragmentSize, GenerateKeyhash, LateAckMode, LeaseDuration, LegacyFragmentation, LogStackTraces, MaxMessageSize, MaxParticipants, MaxQueuedRexmitBytes, MaxQueuedRexmitMessages, MaxSampleSize, MeasureHbToAckLatency, MinimumSocketReceiveBufferSize, MinimumSocketSendBufferSize, MirrorRemoteEntities, NackDelay, PreEmptiveAckDelay, PrimaryReorderMaxSamples, ResponsivenessTimeout, RetransmitMerging, RetransmitMergingPeriod, RetryOnRejectBestEffort, RetryOnRejectDuration, SPDPResponseMaxDelay, ScheduleTimeRounding, SecondaryReorderMaxSamples, SquashParticipants, SuppressSPDPMulticast, SynchronousDeliveryLatencyBound, SynchronousDeliveryPriorityThreshold, UnicastResponseToSPDPMessages, WriterLingerDuration
                    -
                    -

                    9.5.1   AccelerateRexmitBlockSize¶

                    +
                    +

                    9.6.1   AccelerateRexmitBlockSize¶

                    Internal Proxy readers that are assumed to sill be retrieving historical data get this many samples retransmitted when they NACK something, even if some of these samples have sequence numbers outside the set covered by the NACK.

                      -
                    • Full path: //OpenSplice/DDSI2Service/Internal/AccelerateRexmitBlockSize
                    • +
                    • Full path: /DDSI2EService/Internal/AccelerateRexmitBlockSize
                    • Format: integer
                    • Default value: 0
                    • Occurrences min-max: 0-1
                    -
                    -

                    9.5.2   AggressiveKeepLastWhc¶

                    -

                    Internal This element controls whether to drop a reliable sample from a DDSI2 WHC before all readers have acknowledged it as soon as a later sample becomes available. It only affects DCPS data writers with a history QoS setting of KEEP_LAST with depth 1. The default setting, false, mimics the behaviour of the OpenSplice RT networking and is necessary to make the behaviour of wait_for_acknowledgements() consistent across the networking services.

                    +
                    +

                    9.6.2   AggressiveKeepLast1Whc¶

                    +

                    Internal This element controls whether to drop a reliable sample from a DDSI2E WHC before all readers have acknowledged it as soon as a later sample becomes available. It only affects DCPS data writers with a history QoS setting of KEEP_LAST with depth 1. The default setting, false, mimics the behaviour of the OpenSplice RT networking and is necessary to make the behaviour of wait_for_acknowledgements() consistent across the networking services.

                      -
                    • Full path: //OpenSplice/DDSI2Service/Internal/AggressiveKeepLastWhc
                    • +
                    • Full path: /DDSI2EService/Internal/AggressiveKeepLast1Whc
                    • Format: boolean
                    • Default value: false
                    • Occurrences min-max: 0-1
                    -
                    -

                    9.5.3   AssumeMulticastCapable¶

                    +
                    +

                    9.6.3   AssumeMulticastCapable¶

                    Internal This element controls which network interfaces are assumed to be capable of multicasting even when the interface flags returned by the operating system state it is not (this provides a workaround for some platforms). It is a comma-separated lists of patterns (with ? and * wildcards) against which the interface names are matched.

                      -
                    • Full path: //OpenSplice/DDSI2Service/Internal/AssumeMulticastCapable
                    • +
                    • Full path: /DDSI2EService/Internal/AssumeMulticastCapable
                    • Format: string
                    • Occurrences min-max: 0-1
                    -
                    -

                    9.5.4   BuiltinEndpointSet¶

                    +
                    +

                    9.6.4   AuxiliaryBandwidthLimit¶

                    +

                    Internal This element specifies the maximum transmit rate of auxiliary traffic not bound to a specific channel, such as discovery traffic, as well as auxiliary traffic related to a certain channel if that channel has elected to share this global AuxiliaryBandwidthLimit. Bandwidth limiting uses a leaky bucket scheme. The default value “inf” means DDSI2E imposes no limitation, the underlying operating system and hardware will likely limit the maimum transmit rate.

                    +

                    The unit must be specified explicitly. Recognised units: X*b/s, *X*bps for bits/s or *X*B/s, *X*Bps for bytes/s; where *X is an optional prefix: k for 10 3, Ki for 2 10, M for 10 6, Mi for 2 20, G for 10 9, Gi for 2 30.

                    +
                      +
                    • Full path: /DDSI2EService/Internal/AuxiliaryBandwidthLimit
                    • +
                    • Format: string
                    • +
                    • Default value: inf
                    • +
                    • Occurrences min-max: 0-1
                    • +
                    +
                    + -
                    -

                    9.5.5   ConservativeBuiltinReaderStartup¶

                    -

                    Internal This element forces all DDSI2 built-in discovery-related readers to request all historical data, instead of just one for each “topic”. There is no indication that any of the current DDSI implementations requires changing of this setting, but it is conceivable that an implementation might track which participants have been informed of the existence of endpoints and which have not been, refusing communication with those that have “can’t” know.

                    -

                    Should it be necessary to hide DDSI2’s shared discovery behaviour, set this to true and Internal/BuiltinEndpointSet to full.

                    -
                      -
                    • Full path: //OpenSplice/DDSI2Service/Internal/ConservativeBuiltinReaderStartup
                    • -
                    • Format: boolean
                    • -
                    • Default value: false
                    • -
                    • Occurrences min-max: 0-1
                    • -
                    -
                    -
                    -

                    9.5.6   ControlTopic¶

                    -

                    Internal The ControlTopic element allows configured whether DDSI2 provides a special control interface via a predefined topic or not.

                    -
                      -
                    • Full path: //OpenSplice/DDSI2Service/Internal/ControlTopic
                    • -
                    • Occurrences min-max: 0-1
                    • -
                    • Child elements: DeafMute
                    • -
                    • Optional attributes: enable
                    • -
                    -
                    -

                    9.5.6.1   enable¶

                    -

                    Internal This attribute controls whether the DDSI2 control topic is defined and acted upon by DDSI2

                    -
                      -
                    • Full path: //OpenSplice/DDSI2Service/Internal/ControlTopic[@enable]
                    • -
                    • Format: boolean
                    • -
                    • Default value: false
                    • -
                    • Required: false
                    • -
                    -
                    -
                    -

                    9.5.6.2   DeafMute¶

                    -

                    Internal This element controls whether DDSI2 defaults to deaf-mute mode or to normal mode. This controls both the initial behaviour and what behaviour it auto-reverts to.

                    +
                    +

                    9.6.6   ConservativeBuiltinReaderStartup¶

                    +

                    Internal This element forces all DDSI2E built-in discovery-related readers to request all historical data, instead of just one for each “topic”. There is no indication that any of the current DDSI implementations requires changing of this setting, but it is conceivable that an implementation might track which participants have been informed of the existence of endpoints and which have not been, refusing communication with those that have “can’t” know.

                    +

                    Should it be necessary to hide DDSI2E’s shared discovery behaviour, set this to true and Internal/BuiltinEndpointSet to full.

                      -
                    • Full path: //OpenSplice/DDSI2Service/Internal/ControlTopic/DeafMute
                    • +
                    • Full path: /DDSI2EService/Internal/ConservativeBuiltinReaderStartup
                    • Format: boolean
                    • Default value: false
                    • Occurrences min-max: 0-1
                    -
                    -
                    -

                    9.5.7   DDSI2DirectMaxThreads¶

                    +
                    +

                    9.6.7   DDSI2DirectMaxThreads¶

                    Internal This element sets the maximum number of extra threads for an experimental, undocumented and unsupported direct mode.

                      -
                    • Full path: //OpenSplice/DDSI2Service/Internal/DDSI2DirectMaxThreads
                    • +
                    • Full path: /DDSI2EService/Internal/DDSI2DirectMaxThreads
                    • Format: integer
                    • Default value: 1
                    • Occurrences min-max: 0-1
                    -
                    -

                    9.5.8   DefragReliableMaxSamples¶

                    -

                    Internal This element sets the maximum number of samples that can be defragmented simultaneously for a reliable writer. This has to be large enough to handle retransmissions of historical data in addition to new samples.

                    +
                    +

                    9.6.8   DefragReliableMaxSamples¶

                    +

                    Internal This element sets the maximum number of samples that can be defragmneted simultaneously for a reliable writer. This has to be large enough to handle retransmissions of historical data in addition to new samples.

                      -
                    • Full path: //OpenSplice/DDSI2Service/Internal/DefragReliableMaxSamples
                    • +
                    • Full path: /DDSI2EService/Internal/DefragReliableMaxSamples
                    • Format: integer
                    • Default value: 16
                    • Occurrences min-max: 0-1
                    -
                    -

                    9.5.9   DefragUnreliableMaxSamples¶

                    +
                    +

                    9.6.9   DefragUnreliableMaxSamples¶

                    Internal This element sets the maximum number of samples that can be defragmented simultaneously for a best-effort writers.

                      -
                    • Full path: //OpenSplice/DDSI2Service/Internal/DefragUnreliableMaxSamples
                    • +
                    • Full path: /DDSI2EService/Internal/DefragUnreliableMaxSamples
                    • Format: integer
                    • Default value: 4
                    • Occurrences min-max: 0-1
                    -
                    -

                    9.5.10   DeliveryQueueMaxSamples¶

                    +
                    +

                    9.6.10   DeliveryQueueMaxSamples¶

                    Internal This element controls the Maximum size of a delivery queue, expressed in samples. Once a delivery queue is full, incoming samples destined for that queue are dropped until space becomes available again.

                      -
                    • Full path: //OpenSplice/DDSI2Service/Internal/DeliveryQueueMaxSamples
                    • +
                    • Full path: /DDSI2EService/Internal/DeliveryQueueMaxSamples
                    • Format: integer
                    • Default value: 256
                    • Occurrences min-max: 0-1
                    -
                    -

                    9.5.11   ForwardAllMessages¶

                    +
                    +

                    9.6.11   ForwardAllMessages¶

                    Internal Forward all messages from a writer, rather than trying to forward each sample only once. The default of trying to forward each sample only once filters out duplicates for writers in multiple partitions under nearly all circumstances, but may still publish the odd duplicate. Note: the current implementation also can lose in contrived test cases, that publish more than 2**32 samples using a single data writer in conjunction with carefully controlled management of the writer history via cooperating local readers.

                      -
                    • Full path: //OpenSplice/DDSI2Service/Internal/ForwardAllMessages
                    • +
                    • Full path: /DDSI2EService/Internal/ForwardAllMessages
                    • Format: boolean
                    • Default value: false
                    • Occurrences min-max: 0-1
                    -
                    -

                    9.5.12   ForwardRemoteData¶

                    -

                    Internal This element controls whether DDSI2 forwards data received from other network services in the domain.

                    +
                    +

                    9.6.12   ForwardRemoteData¶

                    +

                    This element controls whether DDSI2E forwards data received from other network services in the domain.

                      -
                    • Full path: //OpenSplice/DDSI2Service/Internal/ForwardRemoteData
                    • +
                    • Full path: /DDSI2EService/Internal/ForwardRemoteData
                    • Format: enumeration
                    • Default value: default
                    • -
                    • Valid values: false, true, default
                    • +
                    • Valid values: false, default, true
                    • Occurrences min-max: 0-1
                    -
                    -

                    9.5.13   GenerateKeyhash¶

                    +
                    +

                    9.6.13   FragmentSize¶

                    +

                    Internal This element specifies the size of DDSI sample fragments generated by DDSI2E. Samples larger than FragmentSize are fragmented into fragments of FragmentSize bytes each, except the last one, which may be smaller. The DDSI spec mandates a minimum fragment size of 1025 bytes, but DDSI2E will do whatever size is requested, accepting fragments of which the size is at least the minimum of 1025 and FragmentSize.

                    +

                    The unit must be specified explicitly. Recognised units: B (bytes), kB & KiB (2 10 bytes), MB & MiB (2 20 bytes), GB & GiB (2 30 bytes).

                    +
                      +
                    • Full path: /DDSI2EService/Internal/FragmentSize
                    • +
                    • Format: string
                    • +
                    • Default value: 1280 B
                    • +
                    • Occurrences min-max: 0-1
                    • +
                    +
                    +
                    +

                    9.6.14   GenerateKeyhash¶

                    Internal When true, include keyhashes in outgoing data for topics with keys.

                      -
                    • Full path: //OpenSplice/DDSI2Service/Internal/GenerateKeyhash
                    • +
                    • Full path: /DDSI2EService/Internal/GenerateKeyhash
                    • Format: boolean
                    • Default value: true
                    • Occurrences min-max: 0-1
                    -
                    -

                    9.5.14   LateAckMode¶

                    +
                    +

                    9.6.15   LateAckMode¶

                    Internal Ack a sample only when it has been delivered, instead of when committed to delivering it.

                      -
                    • Full path: //OpenSplice/DDSI2Service/Internal/LateAckMode
                    • +
                    • Full path: /DDSI2EService/Internal/LateAckMode
                    • Format: boolean
                    • Default value: false
                    • Occurrences min-max: 0-1
                    -
                    -

                    9.5.15   LeaseDuration¶

                    -

                    Internal This setting controls the default participant lease duration. +

                    +

                    9.6.16   LeaseDuration¶

                    +

                    Internal This setting controls the default participant lease duration, with 0s (the default) indicating that it is to be derived from the domain ExpiryTime: either 10% or 1s longer, whichever is shortest. The unit must be specified explicitly. Recognised units: ns, us, ms, s, min, hr, day.

                      -
                    • Full path: //OpenSplice/DDSI2Service/Internal/LeaseDuration
                    • +
                    • Full path: /DDSI2EService/Internal/LeaseDuration
                    • Format: string
                    • Default value: 0 s
                    • -
                    • Valid values: 0 / 1hr
                    • Occurrences min-max: 0-1
                    -
                    -

                    9.5.16   LegacyFragmentation¶

                    -

                    Internal This option enables a backwards-compatible, non-compliant setting and interpretation of the control flags in fragmented data messages. To be enabled only when requiring interoperability between compliant and non-compliant versions of DDSI2 for large messages.

                    +
                    +

                    9.6.17   LegacyFragmentation¶

                    +

                    Internal This option enables a backwards-compatible, non-compliant setting and interpretation of the control flags in fragmented data messages. To be enabled only when requiring interoperability between compliant and non-compliant versions of DDSI2E for large messages.

                      -
                    • Full path: //OpenSplice/DDSI2Service/Internal/LegacyFragmentation
                    • +
                    • Full path: /DDSI2EService/Internal/LegacyFragmentation
                    • Format: boolean
                    • Default value: false
                    • Occurrences min-max: 0-1
                    -
                    -

                    9.5.17   LogStackTraces¶

                    -

                    Internal This element controls whether or not to write stack traces to the DDSI2 trace when a thread fails to make progress (on select platforms only).

                    +
                    +

                    9.6.18   LogStackTraces¶

                    +

                    This element controls whether or not to write stack traces to the DDSI2 trace when a thread fails to make progress (on select platforms only).

                      -
                    • Full path: //OpenSplice/DDSI2Service/Internal/LogStackTraces
                    • +
                    • Full path: /DDSI2EService/Internal/LogStackTraces
                    • Format: boolean
                    • -
                    • Default value: true
                    • +
                    • Default value: false
                    • Occurrences min-max: 0-1
                    -
                    -

                    9.5.18   MaxParticipants¶

                    -

                    Internal This elements configures the maximum number of DCPS domain participants this DDSI2 instance is willing to service. 0 is unlimited.

                    +
                    +

                    9.6.19   MaxMessageSize¶

                    +

                    Internal This element specifies the maximum size of the UDP payload that DDSI2E will generate. DDSI2E will try to maintain this limit within the bounds of the DDSI specification, which means that in some cases (especially for very low values of MaxMessageSize) larger payloads may sporadically be observed (currently up to 1192 B).

                    +

                    On some networks it may be necessary to set this item to keep the packetsize below the MTU to prevent IP fragmentation. In those cases, it is generally advisable to also consider reducing Internal/FragmentSize.

                    +

                    The unit must be specified explicitly. Recognised units: B (bytes), kB & KiB (2 10 bytes), MB & MiB (2 20 bytes), GB & GiB (2 30 bytes).

                    +
                      +
                    • Full path: /DDSI2EService/Internal/MaxMessageSize
                    • +
                    • Format: string
                    • +
                    • Default value: 4096 B
                    • +
                    • Occurrences min-max: 0-1
                    • +
                    +
                    +
                    +

                    9.6.20   MaxParticipants¶

                    +

                    Internal This elements configures the maximum number of DCPS domain participants this DDSI2E service instance is willing to service. 0 is unlimited.

                      -
                    • Full path: //OpenSplice/DDSI2Service/Internal/MaxParticipants
                    • +
                    • Full path: /DDSI2EService/Internal/MaxParticipants
                    • Format: integer
                    • Default value: 0
                    • Occurrences min-max: 0-1
                    -
                    -

                    9.5.19   MaxQueuedRexmitBytes¶

                    +
                    +

                    9.6.21   MaxQueuedRexmitBytes¶

                    Internal This setting limits the maximum number of bytes queued for retransmission. The default value of 0 is unlimited unless an AuxiliaryBandwidthLimit has been set, in which case it becomes NackDelay * AuxiliaryBandwidthLimit. It must be large enough to contain the largest sample that may need to be retransmitted.

                    The unit must be specified explicitly. Recognised units: B (bytes), kB & KiB (2 10 bytes), MB & MiB (2 20 bytes), GB & GiB (2 30 bytes).

                      -
                    • Full path: //OpenSplice/DDSI2Service/Internal/MaxQueuedRexmitBytes
                    • +
                    • Full path: /DDSI2EService/Internal/MaxQueuedRexmitBytes
                    • Format: string
                    • -
                    • Default value: 50 kB
                    • +
                    • Default value: 0 B
                    • Occurrences min-max: 0-1
                    -
                    -

                    9.5.20   MaxQueuedRexmitMessages¶

                    +
                    +

                    9.6.22   MaxQueuedRexmitMessages¶

                    Internal This settings limits the maximum number of samples queued for retransmission.

                      -
                    • Full path: //OpenSplice/DDSI2Service/Internal/MaxQueuedRexmitMessages
                    • +
                    • Full path: /DDSI2EService/Internal/MaxQueuedRexmitMessages
                    • Format: integer
                    • Default value: 200
                    • Occurrences min-max: 0-1
                    -
                    -

                    9.5.21   MaxSampleSize¶

                    -

                    Internal This setting controls the maximum (CDR) serialised size of samples that DDSI2 will forward in either direction. Samples larger than this are discarded with a warning.

                    +
                    +

                    9.6.23   MaxSampleSize¶

                    +

                    Internal This setting controls the maximum (CDR) serialised size of samples that DDSI2E will forward in either direction. Samples larger than this are discarded with a warning.

                    The unit must be specified explicitly. Recognised units: B (bytes), kB & KiB (2 10 bytes), MB & MiB (2 20 bytes), GB & GiB (2 30 bytes).

                      -
                    • Full path: //OpenSplice/DDSI2Service/Internal/MaxSampleSize
                    • +
                    • Full path: /DDSI2EService/Internal/MaxSampleSize
                    • Format: string
                    • Default value: 2147483647 B
                    • Occurrences min-max: 0-1
                    -
                    -

                    9.5.22   MeasureHbToAckLatency¶

                    -

                    Internal This element enables heartbeat-to-ack latency among DDSI2 services by prepending timestamps to Heartbeat and AckNack messages and calculating round trip times. This is non-standard behaviour. The measured latencies are quite noisy and are currently not used anywhere.

                    +
                    +

                    9.6.24   MeasureHbToAckLatency¶

                    +

                    Internal This element enables heartbeat-to-ack latency among DDSI2E services by prepending timestamps to Heartbeat and AckNack messages and calculating round trip times. This is non-standard behaviour. The measured latencies are quite noisy and are currently not used anywhere.

                      -
                    • Full path: //OpenSplice/DDSI2Service/Internal/MeasureHbToAckLatency
                    • +
                    • Full path: /DDSI2EService/Internal/MeasureHbToAckLatency
                    • Format: boolean
                    • Default value: false
                    • Occurrences min-max: 0-1
                    -
                    -

                    9.5.23   MinimumSocketReceiveBufferSize¶

                    -

                    Internal This setting controls the minimum size of socket receive buffers. The operating system provides some size receive buffer upon creation of the socket, this option can be used to increase the size of the buffer beyond that initially provided by the operating system. If the buffer size cannot be increased to the specified size, an error is reported.

                    -

                    The default setting is the word “default”, which means DDSI2 will attempt to increase the buffer size to 1MB, but will silently accept a smaller buffer should that attempt fail.

                    +
                    +

                    9.6.25   MinimumSocketReceiveBufferSize¶

                    +

                    Internal This setting controls the minimum size of socket receive buffers. This setting can only increase the size of the receive buffer, if the operating system by default creates a larger buffer, it is left unchanged.

                    The unit must be specified explicitly. Recognised units: B (bytes), kB & KiB (2 10 bytes), MB & MiB (2 20 bytes), GB & GiB (2 30 bytes).

                      -
                    • Full path: //OpenSplice/DDSI2Service/Internal/MinimumSocketReceiveBufferSize
                    • +
                    • Full path: /DDSI2EService/Internal/MinimumSocketReceiveBufferSize
                    • Format: string
                    • Default value: default
                    • Occurrences min-max: 0-1
                    -
                    -

                    9.5.24   MinimumSocketSendBufferSize¶

                    +
                    +

                    9.6.26   MinimumSocketSendBufferSize¶

                    Internal This setting controls the minimum size of socket send buffers. This setting can only increase the size of the send buffer, if the operating system by default creates a larger buffer, it is left unchanged.

                    The unit must be specified explicitly. Recognised units: B (bytes), kB & KiB (2 10 bytes), MB & MiB (2 20 bytes), GB & GiB (2 30 bytes).

                      -
                    • Full path: //OpenSplice/DDSI2Service/Internal/MinimumSocketSendBufferSize
                    • +
                    • Full path: /DDSI2EService/Internal/MinimumSocketSendBufferSize
                    • Format: string
                    • Default value: 64 KiB
                    • Occurrences min-max: 0-1
                    -
                    -

                    9.5.25   MirrorRemoteEntities¶

                    -

                    Internal This element controls whether DDSI2 mirrors all entities in the domain in DDSI or only local ones. Default is to discover remote ones iff General/LocalDiscoveryPartition is not the built-in partition.

                    +
                    +

                    9.6.27   MirrorRemoteEntities¶

                    +

                    This element controls whether DDSI2E mirrors all entities in the domain in DDSI or only local ones. Default is to discover remote ones iff General/LocalDiscoveryPartition is not the built-in partition.

                      -
                    • Full path: //OpenSplice/DDSI2Service/Internal/MirrorRemoteEntities
                    • +
                    • Full path: /DDSI2EService/Internal/MirrorRemoteEntities
                    • Format: enumeration
                    • Default value: default
                    • -
                    • Valid values: false, true, default
                    • +
                    • Valid values: false, default, true
                    • Occurrences min-max: 0-1
                    -
                    -

                    9.5.26   MonitorPort¶

                    -

                    Internal This element allows configuring a service that dumps a text description of part the internal state to TCP clients. By default (-1), this is disabled; specifying 0 means a kernel-allocated port is used; a positive number is used as the TCP port number.

                    -
                      -
                    • Full path: //OpenSplice/DDSI2Service/Internal/MonitorPort
                    • -
                    • Format: integer
                    • -
                    • Default value: -1
                    • -
                    • Occurrences min-max: 0-1
                    • -
                    -
                    -
                    -

                    9.5.27   NackDelay¶

                    +
                    +

                    9.6.28   NackDelay¶

                    Internal This setting controls the delay between receipt of a HEARTBEAT indicating missing samples and a NACK (ignored when the HEARTBEAT requires an answer). However, no NACK is sent if a NACK had been scheduled already for a response earlier than the delay requests: then that NACK will incorporate the latest information.

                    The unit must be specified explicitly. Recognised units: ns, us, ms, s, min, hr, day.

                      -
                    • Full path: //OpenSplice/DDSI2Service/Internal/NackDelay
                    • +
                    • Full path: /DDSI2EService/Internal/NackDelay
                    • Format: string
                    • Default value: 10 ms
                    • -
                    • Valid values: 0 / 1hr
                    • Occurrences min-max: 0-1
                    -
                    -

                    9.5.28   PreEmptiveAckDelay¶

                    +
                    +

                    9.6.29   PreEmptiveAckDelay¶

                    Internal This setting controls the delay between the discovering a remote writer and sending a pre-emptive AckNack to discover the range of data available.

                    The unit must be specified explicitly. Recognised units: ns, us, ms, s, min, hr, day.

                      -
                    • Full path: //OpenSplice/DDSI2Service/Internal/PreEmptiveAckDelay
                    • +
                    • Full path: /DDSI2EService/Internal/PreEmptiveAckDelay
                    • Format: string
                    • Default value: 10 ms
                    • -
                    • Valid values: 0 / 1hr
                    • Occurrences min-max: 0-1
                    -
                    -

                    9.5.29   PrimaryReorderMaxSamples¶

                    +
                    +

                    9.6.30   PrimaryReorderMaxSamples¶

                    Internal This element sets the maximum size in samples of a primary re-order administration. Each proxy writer has one primary re-order administration to buffer the packet flow in case some packets arrive out of order. Old samples are forwarded to secondary re-order administrations associated with readers in need of historical data.

                      -
                    • Full path: //OpenSplice/DDSI2Service/Internal/PrimaryReorderMaxSamples
                    • +
                    • Full path: /DDSI2EService/Internal/PrimaryReorderMaxSamples
                    • Format: integer
                    • Default value: 64
                    • Occurrences min-max: 0-1
                    -
                    -

                    9.5.30   PrioritizeRetransmit¶

                    -

                    Internal This element controls whether retransmits are prioritized over new data, speeding up recovery.

                    -
                      -
                    • Full path: //OpenSplice/DDSI2Service/Internal/PrioritizeRetransmit
                    • -
                    • Format: boolean
                    • -
                    • Default value: true
                    • -
                    • Occurrences min-max: 0-1
                    • -
                    -
                    -
                    -

                    9.5.31   RediscoveryBlacklistDuration¶

                    -

                    Internal This element controls for how long a remote participant that was previously deleted will remain on a blacklist to prevent rediscovery, giving the software on a node time to perform any cleanup actions it needs to do. To some extent this delay is required internally by DDSI2, but in the default configuration with the ‘enforce’ attribute set to false, DDSI2 will reallow rediscovery as soon as it has cleared its internal administration. Setting it to too small a value may result in the entry being pruned from the blacklist before DDSI2 is ready, it is therefore recommended to set it to at least several seconds.

                    -

                    Valid values are finite durations with an explicit unit or the keyword ‘inf’ for infinity. Recognised units: ns, us, ms, s, min, hr, day.

                    -
                      -
                    • Full path: //OpenSplice/DDSI2Service/Internal/RediscoveryBlacklistDuration
                    • -
                    • Format: string
                    • -
                    • Default value: 10s
                    • -
                    • Occurrences min-max: 0-1
                    • -
                    • Optional attributes: enforce
                    • -
                    -
                    -

                    9.5.31.1   enforce¶

                    -

                    Internal This attribute controls whether the configured time during which recently deleted participants will not be rediscovered (i.e., “black listed”) is enforced and following complete removal of the participant in DDSI2, or whether it can be rediscovered earlier provided all traces of that participant have been removed already.

                    -
                      -
                    • Full path: //OpenSplice/DDSI2Service/Internal/RediscoveryBlacklistDuration[@enforce]
                    • -
                    • Format: boolean
                    • -
                    • Default value: false
                    • -
                    • Required: false
                    • -
                    -
                    -
                    -
                    -

                    9.5.32   ResponsivenessTimeout¶

                    -

                    Internal This element controls for how long an unresponsive reader can block the transmit thread by failing to acknowledge data when a writer’s DDSI2 write cache is full. If after this time the writer’s cache has not shrunk to below the low-water mark, the reader is considered unresponsive and degraded to unreliable. It will be restored to reliable service once it resumes acknowledging samples.

                    -

                    Valid values are finite durations with an explicit unit or the keyword ‘inf’ for infinity. Recognised units: ns, us, ms, s, min, hr, day.

                    +
                    +

                    9.6.31   ResponsivenessTimeout¶

                    +

                    Internal This element controls for how long an unresponsive reader can block the transmit thread by failing to acknowledge data when a writer’s DDSI2E WHC is full. If after this time the writer’s WHC has not shrunk to below the low-water mark, the reader is considered unresponsive and degraded to unreliable. It will be restored to reliable service once it resumes acknowledging ing samples.

                    +

                    The unit must be specified explicitly. Recognised units: ns, us, ms, s, min, hr, day.

                      -
                    • Full path: //OpenSplice/DDSI2Service/Internal/ResponsivenessTimeout
                    • +
                    • Full path: /DDSI2EService/Internal/ResponsivenessTimeout
                    • Format: string
                    • -
                    • Default value: inf
                    • +
                    • Default value: 1 s
                    • Occurrences min-max: 0-1
                    -
                    -

                    9.5.33   RetransmitMerging¶

                    +
                    +

                    9.6.32   RetransmitMerging¶

                    Internal This elements controls the addressing and timing of retransmits. Possible values are:

                    -
                    -

                    9.5.34   RetransmitMergingPeriod¶

                    -

                    Internal This setting determines the size of the time window in which a NACK of some sample is ignored because a retransmit of that sample has been multicasted too recently. This setting has no effect on unicasted retransmits.

                    +
                    +

                    9.6.33   RetransmitMergingPeriod¶

                    +

                    Internal This setting determines the size of the time window in which a NACK of some sample is ignored because a retransmit of that sample has been multicasted too recently. This setting has no effect of unicasted retransmits.

                    See also Internal/RetransmitMerging.

                    The unit must be specified explicitly. Recognised units: ns, us, ms, s, min, hr, day.

                      -
                    • Full path: //OpenSplice/DDSI2Service/Internal/RetransmitMergingPeriod
                    • +
                    • Full path: /DDSI2EService/Internal/RetransmitMergingPeriod
                    • Format: string
                    • Default value: 5 ms
                    • -
                    • Valid values: 0 / 1s
                    • Occurrences min-max: 0-1
                    -
                    -

                    9.5.35   RetryOnRejectBestEffort¶

                    -

                    Internal Whether or not to locally retry pushing a received best-effort sample into the reader caches when resource limits are reached.

                    +
                    +

                    9.6.34   RetryOnRejectBestEffort¶

                    +

                    Internal Whether or not to locally retry pusing a received best-effort sample into the reader caches when resource limits are reached.

                      -
                    • Full path: //OpenSplice/DDSI2Service/Internal/RetryOnRejectBestEffort
                    • +
                    • Full path: /DDSI2EService/Internal/RetryOnRejectBestEffort
                    • Format: boolean
                    • Default value: false
                    • Occurrences min-max: 0-1
                    -
                    -

                    9.5.36   RetryOnRejectDuration¶

                    +
                    +

                    9.6.35   RetryOnRejectDuration¶

                    Internal How long to keep locally retrying pushing a received sample into the reader caches when resource limits are reached. Default is dependent on Internal/LateAckMode: if the latter is false, it is 80% of Internal/ResponsivenessTimeout, otherwise it is 0.

                    Valid values are finite durations with an explicit unit or the keyword ‘inf’ for infinity. Recognised units: ns, us, ms, s, min, hr, day.

                      -
                    • Full path: //OpenSplice/DDSI2Service/Internal/RetryOnRejectDuration
                    • +
                    • Full path: /DDSI2EService/Internal/RetryOnRejectDuration
                    • Format: string
                    • Default value: default
                    • Occurrences min-max: 0-1
                    -
                    -

                    9.5.37   SPDPResponseMaxDelay¶

                    -

                    Internal Maximum pseudo-random delay in milliseconds between discovering a remote participant and responding to it.

                    +
                    +

                    9.6.36   SPDPResponseMaxDelay¶

                    +

                    Internal Maximum pseudo-random delay in milliseocnds between discovering a remote participant and responding to it.

                    The unit must be specified explicitly. Recognised units: ns, us, ms, s, min, hr, day.

                      -
                    • Full path: //OpenSplice/DDSI2Service/Internal/SPDPResponseMaxDelay
                    • +
                    • Full path: /DDSI2EService/Internal/SPDPResponseMaxDelay
                    • Format: string
                    • Default value: 0 ms
                    • -
                    • Valid values: 0 / 1s
                    • Occurrences min-max: 0-1
                    -
                    -

                    9.5.38   ScheduleTimeRounding¶

                    +
                    +

                    9.6.37   ScheduleTimeRounding¶

                    Internal This setting allows the timing of scheduled events to be rounded up so that more events can be handled in a single cycle of the event queue. The default is 0 and causes no rounding at all, i.e. are scheduled exactly, whereas a value of 10ms would mean that events are rounded up to the nearest 10 milliseconds.

                    The unit must be specified explicitly. Recognised units: ns, us, ms, s, min, hr, day.

                      -
                    • Full path: //OpenSplice/DDSI2Service/Internal/ScheduleTimeRounding
                    • +
                    • Full path: /DDSI2EService/Internal/ScheduleTimeRounding
                    • Format: string
                    • Default value: 0 ms
                    • -
                    • Valid values: 0 / 1hr
                    • Occurrences min-max: 0-1
                    -
                    -

                    9.5.39   SecondaryReorderMaxSamples¶

                    +
                    +

                    9.6.38   SecondaryReorderMaxSamples¶

                    Internal This element sets the maximum size in samples of a secondary re-order administration. The secondary re-order administration is per reader in need of historical data.

                      -
                    • Full path: //OpenSplice/DDSI2Service/Internal/SecondaryReorderMaxSamples
                    • +
                    • Full path: /DDSI2EService/Internal/SecondaryReorderMaxSamples
                    • Format: integer
                    • Default value: 16
                    • Occurrences min-max: 0-1
                    -
                    -

                    9.5.40   SquashParticipants¶

                    -

                    Internal This element controls whether DDSI2 advertises all the domain participants it serves in DDSI (when set to false), or rather only one domain participant (the one corresponding to the DDSI2 process; when set to true). In the latter case DDSI2 becomes the virtual owner of all readers and writers of all domain participants, dramatically reducing discovery traffic (a similar effect can be obtained by setting Internal/BuiltinEndpointSet to “minimal” but with less loss of information).

                    +
                    +

                    9.6.39   SquashParticipants¶

                    +

                    Internal This element controls whether DDSI2E advertises all the domain participants it serves in DDSI (when set to false), or rather only one domain participant (the one corresponding to the DDSI2E process; when set to true). In the latter case DDSI2E becomes the virtual owner of all readers and writers of all domain participants, dramatically reducing discovery traffic.

                      -
                    • Full path: //OpenSplice/DDSI2Service/Internal/SquashParticipants
                    • +
                    • Full path: /DDSI2EService/Internal/SquashParticipants
                    • Format: boolean
                    • Default value: false
                    • Occurrences min-max: 0-1
                    -
                    -

                    9.5.41   SuppressSPDPMulticast¶

                    +
                    +

                    9.6.40   SuppressSPDPMulticast¶

                    Internal The element controls whether the mandatory multicasting of the participant discovery packets occurs. Completely disabling multicasting requires this element be set to true, and generally requires explicitly listing peers to ping for unicast discovery.

                    See also General/AllowMulticast.

                      -
                    • Full path: //OpenSplice/DDSI2Service/Internal/SuppressSPDPMulticast
                    • +
                    • Full path: /DDSI2EService/Internal/SuppressSPDPMulticast
                    • Format: boolean
                    • Default value: false
                    • Occurrences min-max: 0-1
                    -
                    -

                    9.5.42   SynchronousDeliveryLatencyBound¶

                    +
                    +

                    9.6.41   SynchronousDeliveryLatencyBound¶

                    Internal This element controls whether samples sent by a writer with QoS settings transport_priority >= SynchronousDeliveryPriorityThreshold and a latency_budget at most this element’s value will be delivered synchronously from the “recv” thread, all others will be delivered asynchronously through delivery queues. This reduces latency at the expense of aggregate bandwidth.

                    Valid values are finite durations with an explicit unit or the keyword ‘inf’ for infinity. Recognised units: ns, us, ms, s, min, hr, day.

                      -
                    • Full path: //OpenSplice/DDSI2Service/Internal/SynchronousDeliveryLatencyBound
                    • +
                    • Full path: /DDSI2EService/Internal/SynchronousDeliveryLatencyBound
                    • Format: string
                    • Default value: inf
                    • Occurrences min-max: 0-1
                    -
                    -

                    9.5.43   SynchronousDeliveryPriorityThreshold¶

                    +
                    +

                    9.6.42   SynchronousDeliveryPriorityThreshold¶

                    Internal This element controls whether samples sent by a writer with QoS settings latency_budget <= SynchronousDeliveryLatencyBound and transport_priority greater than or equal to this element’s value will be delivered synchronously from the “recv” thread, all others will be delivered asynchronously through delivery queues. This reduces latency at the expense of aggregate bandwidth.

                      -
                    • Full path: //OpenSplice/DDSI2Service/Internal/SynchronousDeliveryPriorityThreshold
                    • +
                    • Full path: /DDSI2EService/Internal/SynchronousDeliveryPriorityThreshold
                    • Format: integer
                    • Default value: 0
                    • Occurrences min-max: 0-1
                    -
                    -

                    9.5.44   Test¶

                    +
                    +

                    9.6.43   Test¶

                    Internal Testing options.

                      -
                    • Full path: //OpenSplice/DDSI2Service/Internal/Test
                    • +
                    • Full path: /DDSI2EService/Internal/Test
                    • Occurrences min-max: 0-1
                    • Child elements: XmitLossiness
                    -
                    -

                    9.5.44.1   XmitLossiness¶

                    -

                    Internal This element controls the fraction of outgoing packets to drop, specified as samples per thousand.

                    +
                    +

                    9.6.43.1   XmitLossiness¶

                    +

                    Internal This element controls the fraction of outgoing packets to drop, specified as a per mil.

                      -
                    • Full path: //OpenSplice/DDSI2Service/Internal/Test/XmitLossiness
                    • +
                    • Full path: /DDSI2EService/Internal/Test/XmitLossiness
                    • Format: integer
                    • Default value: 0
                    • Occurrences min-max: 0-1
                    -
                    -
                    -

                    9.5.45   UnicastResponseToSPDPMessages¶

                    -

                    Internal This element controls whether the response to a newly discovered participant is sent as a unicasted SPDP packet, instead of rescheduling the periodic multicasted one. There is no known benefit to setting this to false.

                    +
                    +
                    +

                    9.6.44   UnicastResponseToSPDPMessages¶

                    +

                    Internal This element controls whether the response to a newly discovered participant is sent as a unicasted SPDP packet, instead of rescheduling the periodic multicasted one. There is no known benefit to setting this to false.

                    +
                      +
                    • Full path: /DDSI2EService/Internal/UnicastResponseToSPDPMessages
                    • +
                    • Format: boolean
                    • +
                    • Default value: true
                    • +
                    • Occurrences min-max: 0-1
                    • +
                    +
                    +
                    +

                    9.6.45   Watermarks¶

                    +

                    Internal Watermarks for flow-control.

                    +
                      +
                    • Full path: /DDSI2EService/Internal/Watermarks
                    • +
                    • Occurrences min-max: 0-1
                    • +
                    • Child elements: WhcHigh, WhcLow
                    • +
                    +
                    +

                    9.6.45.1   WhcHigh¶

                    +

                    Internal This element sets the high-water mark for the DDSI2E WHCs, expressed in bytes. A writer is suspended when the WHC reaches this size.

                    +

                    The unit must be specified explicitly. Recognised units: B (bytes), kB & KiB (2 10 bytes), MB & MiB (2 20 bytes), GB & GiB (2 30 bytes).

                    +
                      +
                    • Full path: /DDSI2EService/Internal/Watermarks/WhcHigh
                    • +
                    • Format: string
                    • +
                    • Default value: 100 kB
                    • +
                    • Occurrences min-max: 0-1
                    • +
                    +
                    +
                    +

                    9.6.45.2   WhcLow¶

                    +

                    Internal This element sets the low-water mark for the DDSI2E WHCs, expressed in bytes. A suspended writer resumes transmitting when its DDSI2E WHC shrinks to this size.

                    +

                    The unit must be specified explicitly. Recognised units: B (bytes), kB & KiB (2 10 bytes), MB & MiB (2 20 bytes), GB & GiB (2 30 bytes).

                    +
                      +
                    • Full path: /DDSI2EService/Internal/Watermarks/WhcLow
                    • +
                    • Format: string
                    • +
                    • Default value: 1 kB
                    • +
                    • Occurrences min-max: 0-1
                    • +
                    +
                    +
                    +
                    +

                    9.6.46   WriterLingerDuration¶

                    +

                    Internal This setting controls the maximum duration for which actual deletion of a reliable writer with unacknowledged data in its history will be postponed to provide proper reliable transmission. +The unit must be specified explicitly. Recognised units: ns, us, ms, s, min, hr, day.

                    +
                      +
                    • Full path: /DDSI2EService/Internal/WriterLingerDuration
                    • +
                    • Format: string
                    • +
                    • Default value: 1 s
                    • +
                    • Occurrences min-max: 0-1
                    • +
                    +
                    +
                    +
                    +

                    9.7   Partitioning¶

                    +

                    The Partitioning element specifies DDSI2E network partitions and how DCPS partition/topic combinations are mapped onto the network partitions.

                    +
                      +
                    • Full path: /DDSI2EService/Partitioning
                    • +
                    • Occurrences min-max: 0-1
                    • +
                    +
                    +

                    9.7.1   IgnoredPartitions¶

                    +

                    The IgnoredPartitions element specifies DCPS partition/topic combinations that are not distributed over the network.

                    +
                      +
                    • Full path: /DDSI2EService/Partitioning/IgnoredPartitions
                    • +
                    • Occurrences min-max: 0-*
                    • +
                    +
                    +

                    9.7.1.1   IgnoredPartition¶

                    +

                    This element can be used to prevent certain combinations of DCPS partition and topic from being transmitted over the network. DDSI2E will complete ignore readers and writers for which all DCPS partitions as well as their topic is ignored, not even creating DDSI readers and writers to mirror the DCPS ones.

                    +
                      +
                    • Full path: /DDSI2EService/Partitioning/IgnoredPartitions/IgnoredPartition
                    • +
                    • Occurrences min-max: 0-*
                    • +
                    • Required attributes: DCPSPartitionTopic
                    • +
                    +
                    +
                    9.7.1.1.1   DCPSPartitionTopic¶
                    +

                    This attribute specifies a partition and a topic expression, separated by a single ‘.’, that are used to determine if a given partition and topic will be ignored or not. The expressions may use the usual wildcards ‘*’ and ‘?’. DDSI2E will consider an wildcard DCPS partition to match an expression iff there exists a string that satisfies both expressions.

                    +
                      +
                    • Full path: /DDSI2EService/Partitioning/IgnoredPartitions/IgnoredPartition/DCPSPartitionTopic
                    • +
                    • Format: string
                    • +
                    • Default value: n/a
                    • +
                    • Required: true
                    • +
                    +
                    +
                    +
                    +
                    +

                    9.7.2   NetworkPartitions¶

                    +

                    The NetworkPartitions element specifies the DDSI2E network partitions.

                    +
                      +
                    • Full path: /DDSI2EService/Partitioning/NetworkPartitions
                    • +
                    • Occurrences min-max: 0-*
                    • +
                    +
                    +

                    9.7.2.1   NetworkPartition¶

                    +

                    This element defines a DDSI2E network partition.

                    +
                      +
                    • Full path: /DDSI2EService/Partitioning/NetworkPartitions/NetworkPartition
                    • +
                    • Occurrences min-max: 0-*
                    • +
                    • Required attributes: Address, Name
                    • +
                    • Optional attributes: Connected, SecurityProfile
                    • +
                    +
                    +
                    9.7.2.1.1   Address¶
                    +

                    This attribute specifies the multicast addresses associated with the network partition as a comma-separated list. Readers matching this network partition (cf. Partitioning/PartitionMappings) will listen for multicasts on all of these addresses and advertise them in the discovery protocol. The writers will select the most suitable address from the addresses advertised by the readers.

                    +
                      +
                    • Full path: /DDSI2EService/Partitioning/NetworkPartitions/NetworkPartition/Address
                    • +
                    • Format: string
                    • +
                    • Default value: n/a
                    • +
                    • Required: true
                    • +
                    +
                    +
                    +
                    9.7.2.1.2   Connected¶
                    +

                    This attribute is a placeholder.

                      -
                    • Full path: //OpenSplice/DDSI2Service/Internal/UnicastResponseToSPDPMessages
                    • +
                    • Full path: /DDSI2EService/Partitioning/NetworkPartitions/NetworkPartition/Connected
                    • Format: boolean
                    • Default value: true
                    • -
                    • Occurrences min-max: 0-1
                    • +
                    • Required: false
                    -
                    -

                    9.5.46   UseMulticastIfMreqn¶

                    -

                    Internal Do not use.

                    +
                    +
                    9.7.2.1.3   Name¶
                    +

                    This attribute specifies the name of this DDSI2E network partition. Two network partitions cannot have the same name.

                      -
                    • Full path: //OpenSplice/DDSI2Service/Internal/UseMulticastIfMreqn
                    • -
                    • Format: integer
                    • -
                    • Default value: 0
                    • -
                    • Occurrences min-max: 0-1
                    • +
                    • Full path: /DDSI2EService/Partitioning/NetworkPartitions/NetworkPartition/Name
                    • +
                    • Format: string
                    • +
                    • Default value: n/a
                    • +
                    • Required: true
                    -
                    -

                    9.5.47   Watermarks¶

                    -

                    Internal Watermarks for flow-control.

                    +
                    +
                    9.7.2.1.4   SecurityProfile¶
                    +

                    This attribute selects the DDSI2E security profile for encrypting the traffic mapped to this DDSI2E network partition. The default “null” means the network partition is unsecured; any other name refers to a security profile defined using the Security/SecurityProfile elements.

                      -
                    • Full path: //OpenSplice/DDSI2Service/Internal/Watermarks
                    • -
                    • Occurrences min-max: 0-1
                    • -
                    • Child elements: WhcAdaptive, WhcHigh, WhcHighInit, WhcLow
                    • +
                    • Full path: /DDSI2EService/Partitioning/NetworkPartitions/NetworkPartition/SecurityProfile
                    • +
                    • Format: string
                    • +
                    • Default value: null
                    • +
                    • Required: false
                    -
                    -

                    9.5.47.1   WhcAdaptive¶

                    -

                    Internal This element controls whether DDSI2 will adapt the high-water mark to current traffic conditions, based on retransmit requests and transmit pressure.

                    +
                    +
                    +
                    +
                    +

                    9.7.3   PartitionMappings¶

                    +

                    The PartitionMappings element specifies the mapping from DCPS partition/topic combinations to DDSI2E network partitions.

                      -
                    • Full path: //OpenSplice/DDSI2Service/Internal/Watermarks/WhcAdaptive
                    • -
                    • Format: boolean
                    • -
                    • Default value: true
                    • -
                    • Occurrences min-max: 0-1
                    • +
                    • Full path: /DDSI2EService/Partitioning/PartitionMappings
                    • +
                    • Occurrences min-max: 0-*
                    -
                    -
                    -

                    9.5.47.2   WhcHigh¶

                    -

                    Internal This element sets the maximum allowed high-water mark for the DDSI2 WHCs, expressed in bytes. A writer is suspended when the WHC reaches this size.

                    -

                    The unit must be specified explicitly. Recognised units: B (bytes), kB & KiB (2 10 bytes), MB & MiB (2 20 bytes), GB & GiB (2 30 bytes).

                    +
                    +

                    9.7.3.1   PartitionMapping¶

                    +

                    This element defines a mapping from a DCPS partition/topic combination to a DDSI2E network partition. This allows partitioning data flows by using special multicast addresses for part of the data and possibly also encrypting the data flow.

                      -
                    • Full path: //OpenSplice/DDSI2Service/Internal/Watermarks/WhcHigh
                    • -
                    • Format: string
                    • -
                    • Default value: 100 kB
                    • -
                    • Occurrences min-max: 0-1
                    • +
                    • Full path: /DDSI2EService/Partitioning/PartitionMappings/PartitionMapping
                    • +
                    • Occurrences min-max: 0-*
                    • +
                    • Required attributes: DCPSPartitionTopic, NetworkPartition
                    -
                    -
                    -

                    9.5.47.3   WhcHighInit¶

                    -

                    Internal This element sets the initial level of the high-water mark for the DDSI2 WHCs, expressed in bytes.

                    -

                    The unit must be specified explicitly. Recognised units: B (bytes), kB & KiB (2 10 bytes), MB & MiB (2 20 bytes), GB & GiB (2 30 bytes).

                    +
                    +
                    9.7.3.1.1   DCPSPartitionTopic¶
                    +

                    This attribute specifies a partition and a topic expression, separated by a single ‘.’, that are used to determine if a given partition and topic maps to the DDSI2E network partition named by the NetworkPartition attribute in this PartitionMapping element. The expressions may use the usual wildcards ‘*’ and ‘?’. DDSI2E will consider an wildcard DCPS partition to match an expression iff there exists a string that satisfies both expressions.

                      -
                    • Full path: //OpenSplice/DDSI2Service/Internal/Watermarks/WhcHighInit
                    • +
                    • Full path: /DDSI2EService/Partitioning/PartitionMappings/PartitionMapping/DCPSPartitionTopic
                    • Format: string
                    • -
                    • Default value: 30 kB
                    • -
                    • Occurrences min-max: 0-1
                    • +
                    • Default value: n/a
                    • +
                    • Required: true
                    -
                    -

                    9.5.47.4   WhcLow¶

                    -

                    Internal This element sets the low-water mark for the DDSI2 WHCs, expressed in bytes. A suspended writer resumes transmitting when its DDSI2 WHC shrinks to this size.

                    -

                    The unit must be specified explicitly. Recognised units: B (bytes), kB & KiB (2 10 bytes), MB & MiB (2 20 bytes), GB & GiB (2 30 bytes).

                    +
                    +
                    9.7.3.1.2   NetworkPartition¶
                    +

                    This attribute specifies which DDSI2E network partition is to be used for DCPS partition/topic combinations matching the DCPSPartitionTopic attribute within this PartitionMapping element.

                      -
                    • Full path: //OpenSplice/DDSI2Service/Internal/Watermarks/WhcLow
                    • +
                    • Full path: /DDSI2EService/Partitioning/PartitionMappings/PartitionMapping/NetworkPartition
                    • Format: string
                    • -
                    • Default value: 1 kB
                    • -
                    • Occurrences min-max: 0-1
                    • +
                    • Default value: n/a
                    • +
                    • Required: true
                    -
                    -

                    9.5.48   WriterLingerDuration¶

                    -

                    Internal This setting controls the maximum duration for which actual deletion of a reliable writer with unacknowledged data in its history will be postponed to provide proper reliable transmission. -The unit must be specified explicitly. Recognised units: ns, us, ms, s, min, hr, day.

                    -
                      -
                    • Full path: //OpenSplice/DDSI2Service/Internal/WriterLingerDuration
                    • -
                    • Format: string
                    • -
                    • Default value: 1 s
                    • -
                    • Valid values: 0 / 1hr
                    • -
                    • Occurrences min-max: 0-1
                    • -
                    -
                    -

                    9.6   SSL¶

                    +
                    +

                    9.8   SSL¶

                    The SSL element allows specifying various parameters related to using SSL/TLS for DDSI over TCP.

                      -
                    • Full path: //OpenSplice/DDSI2Service/SSL
                    • +
                    • Full path: /DDSI2EService/SSL
                    • Occurrences min-max: 0-1
                    • Child elements: CertificateVerification, Ciphers, Enable, EntropyFile, KeyPassphrase, KeystoreFile, SelfSignedCertificates, VerifyClient
                    -
                    -

                    9.6.1   CertificateVerification¶

                    +
                    +

                    9.8.1   CertificateVerification¶

                    If disabled this allows SSL connections to occur even if an X509 certificate fails verification.

                      -
                    • Full path: //OpenSplice/DDSI2Service/SSL/CertificateVerification
                    • +
                    • Full path: /DDSI2EService/SSL/CertificateVerification
                    • Format: boolean
                    • Default value: true
                    • Occurrences min-max: 0-1
                    -
                    -

                    9.6.2   Ciphers¶

                    +
                    +

                    9.8.2   Ciphers¶

                    The set of ciphers used by SSL/TLS

                      -
                    • Full path: //OpenSplice/DDSI2Service/SSL/Ciphers
                    • +
                    • Full path: /DDSI2EService/SSL/Ciphers
                    • Format: string
                    • Default value: ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH
                    • Occurrences min-max: 0-1
                    -
                    -

                    9.6.3   Enable¶

                    +
                    +

                    9.8.3   Enable¶

                    This enables SSL/TLS for TCP.

                      -
                    • Full path: //OpenSplice/DDSI2Service/SSL/Enable
                    • +
                    • Full path: /DDSI2EService/SSL/Enable
                    • Format: boolean
                    • Default value: false
                    • Occurrences min-max: 0-1
                    -
                    -

                    9.6.4   EntropyFile¶

                    +
                    +

                    9.8.4   EntropyFile¶

                    The SSL/TLS random entropy file name.

                      -
                    • Full path: //OpenSplice/DDSI2Service/SSL/EntropyFile
                    • +
                    • Full path: /DDSI2EService/SSL/EntropyFile
                    • Format: string
                    • Occurrences min-max: 0-1
                    -
                    -

                    9.6.5   KeyPassphrase¶

                    +
                    +

                    9.8.5   KeyPassphrase¶

                    The SSL/TLS key pass phrase for encrypted keys.

                      -
                    • Full path: //OpenSplice/DDSI2Service/SSL/KeyPassphrase
                    • +
                    • Full path: /DDSI2EService/SSL/KeyPassphrase
                    • Format: string
                    • Default value: secret
                    • Occurrences min-max: 0-1
                    -
                    -

                    9.6.6   KeystoreFile¶

                    +
                    +

                    9.8.6   KeystoreFile¶

                    The SSL/TLS key and certificate store file name. The keystore must be in PEM format.

                      -
                    • Full path: //OpenSplice/DDSI2Service/SSL/KeystoreFile
                    • +
                    • Full path: /DDSI2EService/SSL/KeystoreFile
                    • Format: string
                    • Default value: keystore
                    • Occurrences min-max: 0-1
                    -
                    -

                    9.6.7   SelfSignedCertificates¶

                    +
                    +

                    9.8.7   SelfSignedCertificates¶

                    This enables the use of self signed X509 certificates.

                      -
                    • Full path: //OpenSplice/DDSI2Service/SSL/SelfSignedCertificates
                    • +
                    • Full path: /DDSI2EService/SSL/SelfSignedCertificates
                    • Format: boolean
                    • Default value: false
                    • Occurrences min-max: 0-1
                    -
                    -

                    9.6.8   VerifyClient¶

                    +
                    +

                    9.8.8   VerifyClient¶

                    This enables an SSL server checking the X509 certificate of a connecting client.

                      -
                    • Full path: //OpenSplice/DDSI2Service/SSL/VerifyClient
                    • +
                    • Full path: /DDSI2EService/SSL/VerifyClient
                    • Format: boolean
                    • Default value: false
                    • Occurrences min-max: 0-1
                    -
                    -

                    9.7   Sizing¶

                    -

                    The Sizing element specifies a variety of configuration settings dealing with expected system sizes, buffer sizes, &c.

                    +
                    +

                    9.9   Security¶

                    +

                    The Security element specifies DDSI2E security profiles that can be used to encrypt traffic mapped to DDSI2E network partitions.

                      -
                    • Full path: //OpenSplice/DDSI2Service/Sizing
                    • +
                    • Full path: /DDSI2EService/Security
                    • Occurrences min-max: 0-1
                    • -
                    • Child elements: EndpointsInSystem, LocalEndpoints, NetworkQueueSize, ReceiveBufferChunkSize
                    -
                    -

                    9.7.1   EndpointsInSystem¶

                    -

                    This endpoint specifies the expected maximum number of endpoints in the network. Underestimating this number will have a significant performance impact, but will not affect correctness; signficantly overestimating it will cause more memory to be used than necessary.

                    +
                    +

                    9.9.1   SecurityProfile¶

                    +

                    This element defines a DDSI2E security profile.

                      -
                    • Full path: //OpenSplice/DDSI2Service/Sizing/EndpointsInSystem
                    • -
                    • Format: integer
                    • -
                    • Default value: 20000
                    • -
                    • Occurrences min-max: 0-1
                    • +
                    • Full path: /DDSI2EService/Security/SecurityProfile
                    • +
                    • Occurrences min-max: 0-*
                    • +
                    • Required attributes: Name
                    • +
                    • Optional attributes: Cipher, CipherKey
                    -
                    -
                    -

                    9.7.2   LocalEndpoints¶

                    -

                    This element specifies the expected maximum number of endpoints local to one DDSI2 service. Underestimating this number will have a significant performance impact, but will not affect correctness; signficantly overestimating it will cause more memory to be used than necessary.

                    +
                    +

                    9.9.1.1   Cipher¶

                    +

                    This attribute specifies the cipher to be used for encrypting traffic over network partitions secured by this security profile. The possible ciphers are:

                      -
                    • Full path: //OpenSplice/DDSI2Service/Sizing/LocalEndpoints
                    • -
                    • Format: integer
                    • -
                    • Default value: 1000
                    • -
                    • Occurrences min-max: 0-1
                    • +
                    • aes128: AES with a 128-bit key;
                    • +
                    • aes192: AES with a 192-bit key;
                    • +
                    • aes256: AES with a 256-bit key;
                    • +
                    • blowfish: the Blowfish cipher with a 128 bit key;
                    • +
                    • null: no encryption;
                    • +
                    +

                    SHA1 is used on conjunction with all ciphers except “null” to ensure data integrity.

                    +
                      +
                    • Full path: /DDSI2EService/Security/SecurityProfile/Cipher
                    • +
                    • Format: enumeration
                    • +
                    • Default value: null
                    • +
                    • Valid values: null, blowfish, aes128, aes192, aes256
                    • +
                    • Required: false
                    -
                    -

                    9.7.3   NetworkQueueSize¶

                    -

                    This element specifies the maximum number of samples in the network queue. Write/dispose operations add samples to this queue, the DDSI2 service drains it. Larger values allow large bursts of writes to occur without forcing synchronization between the application and the DDSI2 service, but do introduce the potential for longer latencies and increase the maximum amount of memory potentially occupied by messages in the queue.

                    +
                    +

                    9.9.1.2   CipherKey¶

                    +

                    The CipherKey attribute is used to define the secret key required by the cipher selected using the Cipher attribtue. The value can be a URI referencing an external file containing the secret key, or the secret key can be defined in-place as a string value.

                    +

                    The key must be specified as a hexadecimal string with each character representing 4 bits of the key. E.g., 1ABC represents the 16-bit key 0001 1010 1011 1100. The key should not follow a well-known pattern and must exactly match the key length of the selected cipher.

                    +

                    A malformed key will cause the security profile to be marked as invalid, and disable all network partitions secured by the (invalid) security profile to prevent information leaks.

                    +

                    As all DDS applications require read access to the XML configuration file, for security reasons it is recommended to store the secret key in an external file in the file system, referenced by its URI. The file should be protected against read and write access from other users on the host.

                      -
                    • Full path: //OpenSplice/DDSI2Service/Sizing/NetworkQueueSize
                    • -
                    • Format: integer
                    • -
                    • Default value: 1000
                    • -
                    • Occurrences min-max: 0-1
                    • +
                    • Full path: /DDSI2EService/Security/SecurityProfile/CipherKey
                    • +
                    • Format: string
                    • +
                    • Default value: “”
                    • +
                    • Required: false
                    -
                    -

                    9.7.4   ReceiveBufferChunkSize¶

                    -

                    This element specifies the size of one allocation unit in the receive buffer. Must be greater than the maximum packet size by a modest amount (too large packets are dropped). Each allocation is shrunk immediately after processing a message, or freed straightaway.

                    -

                    The unit must be specified explicitly. Recognised units: B (bytes), kB & KiB (2 10 bytes), MB & MiB (2 20 bytes), GB & GiB (2 30 bytes).

                    +
                    +

                    9.9.1.3   Name¶

                    +

                    This attribute specifies the name of this DDSI2E security profile. Two security profiles cannot have the same name.

                      -
                    • Full path: //OpenSplice/DDSI2Service/Sizing/ReceiveBufferChunkSize
                    • +
                    • Full path: /DDSI2EService/Security/SecurityProfile/Name
                    • Format: string
                    • -
                    • Default value: 128 KiB
                    • -
                    • Occurrences min-max: 0-1
                    • +
                    • Default value: n/a
                    • +
                    • Required: true
                    -
                    -

                    9.7.5   Watermarks¶

                    -
                    -
                    { LEAF (“ReceiveBufferSize”), 1, “1 MiB”, ABSOFF (rbuf_size), 0, uf_memsize, 0, pf_memsize, “This element sets the size of a single receive buffer. Many receive buffers may be needed. Their size must be greater than ReceiveBufferChunkSize by a modest amount.
                    +
                    +
                    +
                    +

                    9.10   Sizing¶

                    +

                    The Sizing element specifies a variety of configuration settings dealing with expected system sizes, buffer sizes, &c.

                      -
                    • Full path: //OpenSplice/DDSI2Service/Sizing/Watermarks
                    • +
                    • Full path: /DDSI2EService/Sizing
                    • Occurrences min-max: 0-1
                    • -
                    • Child elements: WhcAdaptive, WhcHigh, WhcHighInit, WhcLow
                    • +
                    • Child elements: EndpointsInSystem, LocalEndpoints, NetworkQueueSize, ReceiveBufferChunkSize, ReceiveBufferSize
                    -
                    -

                    9.7.5.1   WhcAdaptive¶

                    -

                    This element controls whether DDSI2 will adapt the high-water mark to current traffic conditions, based on retransmit requests and transmit pressure.

                    +
                    +

                    9.10.1   EndpointsInSystem¶

                    +

                    This endpoint specifies the expected maximum number of endpoints in the network. Underestimating this number will have a significant performance impact, but will not affect correctness; signficantly overestimating it will cause more memory to be used than necessary.

                      -
                    • Full path: //OpenSplice/DDSI2Service/Sizing/Watermarks/WhcAdaptive
                    • -
                    • Format: boolean
                    • -
                    • Default value: true
                    • +
                    • Full path: /DDSI2EService/Sizing/EndpointsInSystem
                    • +
                    • Format: integer
                    • +
                    • Default value: 20000
                    • Occurrences min-max: 0-1
                    -
                    -

                    9.7.5.2   WhcHigh¶

                    -

                    This element sets the maximum allowed high-water mark for the DDSI2 WHCs, expressed in bytes. A writer is suspended when the WHC reaches this size.

                    -

                    The unit must be specified explicitly. Recognised units: B (bytes), kB & KiB (2 10 bytes), MB & MiB (2 20 bytes), GB & GiB (2 30 bytes).

                    +
                    +

                    9.10.2   LocalEndpoints¶

                    +

                    This element specifies the expected maximum number of endpoints local to one DDSI2E service. Underestimating this number will have a significant performance impact, but will not affect correctness; signficantly overestimating it will cause more memory to be used than necessary.

                      -
                    • Full path: //OpenSplice/DDSI2Service/Sizing/Watermarks/WhcHigh
                    • -
                    • Format: string
                    • -
                    • Default value: 100 kB
                    • +
                    • Full path: /DDSI2EService/Sizing/LocalEndpoints
                    • +
                    • Format: integer
                    • +
                    • Default value: 1000
                    • Occurrences min-max: 0-1
                    -
                    -

                    9.7.5.3   WhcHighInit¶

                    -

                    This element sets the initial level of the high-water mark for the DDSI2 WHCs, expressed in bytes.

                    +
                    +

                    9.10.3   NetworkQueueSize¶

                    +

                    This element specifies the maximum number of samples in the network queue. Write/dispose operations add samples to this queue, the DDSI2E service drains it. Larger values allow large bursts of writes to occur without forcing synchronization between the application and the DDSI2E service, but do introduce the potential for longer latencies and increase the maximum amount of memory potentially occupied by messages in the queue.

                    +
                      +
                    • Full path: /DDSI2EService/Sizing/NetworkQueueSize
                    • +
                    • Format: integer
                    • +
                    • Default value: 1000
                    • +
                    • Occurrences min-max: 0-1
                    • +
                    +
                    +
                    +

                    9.10.4   ReceiveBufferChunkSize¶

                    +

                    Size of one allocation unit in the receive buffer. Must be greater than the maximum packet size by a modest amount (too large packets are dropped). Each allocation is shrunk immediately after processing a message, or freed straightaway.

                    The unit must be specified explicitly. Recognised units: B (bytes), kB & KiB (2 10 bytes), MB & MiB (2 20 bytes), GB & GiB (2 30 bytes).

                      -
                    • Full path: //OpenSplice/DDSI2Service/Sizing/Watermarks/WhcHighInit
                    • +
                    • Full path: /DDSI2EService/Sizing/ReceiveBufferChunkSize
                    • Format: string
                    • -
                    • Default value: 30 kB
                    • +
                    • Default value: 128 KiB
                    • Occurrences min-max: 0-1
                    -
                    -

                    9.7.5.4   WhcLow¶

                    -

                    This element sets the low-water mark for the DDSI2 WHCs, expressed in bytes. A suspended writer resumes transmitting when its DDSI2 WHC shrinks to this size.

                    +
                    +

                    9.10.5   ReceiveBufferSize¶

                    +

                    This element sets the size of a single receive buffer. Many receive buffers may be needed. Their size must be greater than ReceiveBufferChunkSize by a modest amount.

                    The unit must be specified explicitly. Recognised units: B (bytes), kB & KiB (2 10 bytes), MB & MiB (2 20 bytes), GB & GiB (2 30 bytes).

                      -
                    • Full path: //OpenSplice/DDSI2Service/Sizing/Watermarks/WhcLow
                    • +
                    • Full path: /DDSI2EService/Sizing/ReceiveBufferSize
                    • Format: string
                    • -
                    • Default value: 1 kB
                    • +
                    • Default value: 1 MiB
                    • Occurrences min-max: 0-1
                    -
                    -
                    -

                    9.8   TCP¶

                    +
                    +

                    9.11   TCP¶

                    The TCP element allows specifying various parameters related to running DDSI over TCP.

                      -
                    • Full path: //OpenSplice/DDSI2Service/TCP
                    • +
                    • Full path: /DDSI2EService/TCP
                    • Occurrences min-max: 0-1
                    • Child elements: Enable, NoDelay, Port, ReadTimeout, WriteTimeout
                    -
                    -

                    9.8.1   Enable¶

                    +
                    +

                    9.11.1   Enable¶

                    This element enables the optional TCP transport.

                      -
                    • Full path: //OpenSplice/DDSI2Service/TCP/Enable
                    • +
                    • Full path: /DDSI2EService/TCP/Enable
                    • Format: boolean
                    • Default value: false
                    • Occurrences min-max: 0-1
                    -
                    -

                    9.8.2   NoDelay¶

                    +
                    +

                    9.11.2   NoDelay¶

                    This element enables the TCP_NODELAY socket option, preventing multiple DDSI messages being sent in the same TCP request. Setting this option typically optimises latency over throughput.

                      -
                    • Full path: //OpenSplice/DDSI2Service/TCP/NoDelay
                    • +
                    • Full path: /DDSI2EService/TCP/NoDelay
                    • Format: boolean
                    • Default value: true
                    • Occurrences min-max: 0-1
                    -
                    -

                    9.8.3   Port¶

                    -

                    This element specifies the TCP port number on which DDSI2 accepts connections. If the port is set it is used in entity locators, published with DDSI discovery. Dynamically allocated if zero. Disabled if -1 or not configured. If disabled other DDSI services will not be able to establish connections with the service, the service can only communicate by establishing connections to other services.

                    +
                    +

                    9.11.3   Port¶

                    +

                    This element specifies the TCP port number on which the service accepts connections. If the port is set it is used in entity locators, published with DDSI discovery. Dynamically allocated if zero. Disabled if -1 or not configured. If disabled other DDSI services will not be able to establish connections with the service, the service can only communicate by establishing connections to other services.

                      -
                    • Full path: //OpenSplice/DDSI2Service/TCP/Port
                    • +
                    • Full path: /DDSI2EService/TCP/Port
                    • Format: integer
                    • Default value: -1
                    • -
                    • Valid values: -1 / 65535
                    • Occurrences min-max: 0-1
                    -
                    -

                    9.8.4   ReadTimeout¶

                    +
                    +

                    9.11.4   ReadTimeout¶

                    This element specifies the timeout for blocking TCP read operations. If this timeout expires then the connection is closed.

                    The unit must be specified explicitly. Recognised units: ns, us, ms, s, min, hr, day.

                      -
                    • Full path: //OpenSplice/DDSI2Service/TCP/ReadTimeout
                    • +
                    • Full path: /DDSI2EService/TCP/ReadTimeout
                    • Format: string
                    • Default value: 2 s
                    • -
                    • Valid values: 0 / 1hr
                    • Occurrences min-max: 0-1
                    -
                    -

                    9.8.5   WriteTimeout¶

                    +
                    +

                    9.11.5   WriteTimeout¶

                    This element specifies the timeout for blocking TCP write operations. If this timeout expires then the connection is closed.

                    The unit must be specified explicitly. Recognised units: ns, us, ms, s, min, hr, day.

                      -
                    • Full path: //OpenSplice/DDSI2Service/TCP/WriteTimeout
                    • +
                    • Full path: /DDSI2EService/TCP/WriteTimeout
                    • Format: string
                    • Default value: 2 s
                    • -
                    • Valid values: 0 / 1hr
                    • Occurrences min-max: 0-1
                    -
                    -

                    9.9   ThreadPool¶

                    +
                    +

                    9.12   ThreadPool¶

                    The ThreadPool element allows specifying various parameters related to using a thread pool to send DDSI messages to multiple unicast addresses (TCP or UDP).

                      -
                    • Full path: //OpenSplice/DDSI2Service/ThreadPool
                    • +
                    • Full path: /DDSI2EService/ThreadPool
                    • Occurrences min-max: 0-1
                    • Child elements: Enable, ThreadMax, Threads
                    -
                    -

                    9.9.1   Enable¶

                    +
                    +

                    9.12.1   Enable¶

                    This element enables the optional thread pool.

                      -
                    • Full path: //OpenSplice/DDSI2Service/ThreadPool/Enable
                    • +
                    • Full path: /DDSI2EService/ThreadPool/Enable
                    • Format: boolean
                    • Default value: false
                    • Occurrences min-max: 0-1
                    -
                    -

                    9.9.2   ThreadMax¶

                    +
                    +

                    9.12.2   ThreadMax¶

                    This elements configures the maximum number of threads in the thread pool.

                      -
                    • Full path: //OpenSplice/DDSI2Service/ThreadPool/ThreadMax
                    • +
                    • Full path: /DDSI2EService/ThreadPool/ThreadMax
                    • Format: integer
                    • Default value: 8
                    • Occurrences min-max: 0-1
                    -
                    -

                    9.9.3   Threads¶

                    +
                    +

                    9.12.3   Threads¶

                    This elements configures the initial number of threads in the thread pool.

                      -
                    • Full path: //OpenSplice/DDSI2Service/ThreadPool/Threads
                    • +
                    • Full path: /DDSI2EService/ThreadPool/Threads
                    • Format: integer
                    • Default value: 4
                    • Occurrences min-max: 0-1
                    -
                    -

                    9.10   Threads¶

                    +
                    +

                    9.13   Threads¶

                    This element is used to set thread properties.

                      -
                    • Full path: //OpenSplice/DDSI2Service/Threads
                    • +
                    • Full path: /DDSI2EService/Threads
                    • Occurrences min-max: 0-1
                    -
                    -

                    9.10.1   Thread¶

                    -

                    This element is used to set thread properties.

                    +
                    +

                    9.13.1   Thread¶

                    +

                    This element specifies thread properties, such as scheduling parameters and stack size.

                      -
                    • Full path: //OpenSplice/DDSI2Service/Threads/Thread
                    • +
                    • Full path: /DDSI2EService/Threads/Thread
                    • Occurrences min-max: 0-1000
                    • Child elements: StackSize
                    • Required attributes: Name
                    -
                    -

                    9.10.1.1   Name¶

                    +
                    +

                    9.13.1.1   Name¶

                    The Name of the thread for which properties are being set. The following threads exist:

                    • gc: garbage collector thread involved in deleting entities;
                    • +
                    • main: main thread, primarily handling local discovery;
                    • recv: receive thread, taking data from the network and running the protocol state machine;
                    • dq.builtins: delivery thread for DDSI-builtin data, primarily for discovery;
                    • -
                    • lease: DDSI liveliness monitoring;
                    • +
                    • lease: DDSI2E liveliness monitoring;
                    • tev: general timed-event handling, retransmits and discovery;
                    • xmit.CHAN: transmit thread for channel CHAN;
                    • dq.CHAN: delivery thread for channel CHAN;
                    • tev.CHAN: timed-even thread for channel CHAN.
                    • -
                    • Full path: //OpenSplice/DDSI2Service/Threads/Thread[@Name]
                    • +
                    • Full path: /DDSI2EService/Threads/Thread/Name
                    • Format: string
                    • Default value: n/a
                    • Required: true
                    -
                    -

                    9.10.1.2   Scheduling¶

                    +
                    +

                    9.13.1.2   Scheduling¶

                    This element configures the scheduling properties of the thread.

                      -
                    • Full path: //OpenSplice/DDSI2Service/Threads/Thread/Scheduling
                    • +
                    • Full path: /DDSI2EService/Threads/Thread/Scheduling
                    • Occurrences min-max: 0-1
                    • Child elements: Class, Priority
                    -
                    -
                    9.10.1.2.1   Class¶
                    +
                    +
                    9.13.1.2.1   Class¶

                    This element specifies the thread scheduling class (realtime, timeshare or default). The user may need special privileges from the underlying operating system to be able to assign some of the privileged scheduling classes.

                      -
                    • Full path: //OpenSplice/DDSI2Service/Threads/Thread/Scheduling/Class
                    • +
                    • Full path: /DDSI2EService/Threads/Thread/Scheduling/Class
                    • Format: enumeration
                    • Default value: default
                    • Valid values: realtime, timeshare, default
                    • Occurrences min-max: 0-1
                    -
                    -
                    9.10.1.2.2   Priority¶
                    +
                    +
                    9.13.1.2.2   Priority¶

                    This element specifies the thread priority (decimal integer or default). Only priorities that are supported by the underlying operating system can be assigned to this element. The user may need special privileges from the underlying operating system to be able to assign some of the privileged priorities.

                      -
                    • Full path: //OpenSplice/DDSI2Service/Threads/Thread/Scheduling/Priority
                    • +
                    • Full path: /DDSI2EService/Threads/Thread/Scheduling/Priority
                    • Format: string
                    • Default value: default
                    • Occurrences min-max: 0-1
                    -
                    -

                    9.10.1.3   StackSize¶

                    -

                    This element configures the stack size for this thread. The default value default leaves the stack size at the operating system default.

                    +
                    +

                    9.13.1.3   StackSize¶

                    +

                    This element configures the stack size for this thread. The default value default leaves the stack size at the the operating system default.

                    The unit must be specified explicitly. Recognised units: B (bytes), kB & KiB (2 10 bytes), MB & MiB (2 20 bytes), GB & GiB (2 30 bytes).

                      -
                    • Full path: //OpenSplice/DDSI2Service/Threads/Thread/StackSize
                    • +
                    • Full path: /DDSI2EService/Threads/Thread/StackSize
                    • Format: string
                    • Default value: default
                    • Occurrences min-max: 0-1
                    • @@ -12139,26 +10784,26 @@

                      9.10.1.3   StackSize

                    -
                    -

                    9.11   Tracing¶

                    +
                    +

                    9.14   Tracing¶

                    The Tracing element controls the amount and type of information that is written into the tracing log by the DDSI service. This is useful to track the DDSI service during application development.

                      -
                    • Full path: //OpenSplice/DDSI2Service/Tracing
                    • +
                    • Full path: /DDSI2EService/Tracing
                    • Occurrences min-max: 0-1
                    • Child elements: AppendToFile, EnableCategory, OutputFile, PacketCaptureFile, Timestamps, Verbosity
                    -
                    -

                    9.11.1   AppendToFile¶

                    +
                    +

                    9.14.1   AppendToFile¶

                    This option specifies whether the output is to be appended to an existing log file. The default is to create a new log file each time, which is generally the best option if a detailed log is generated.

                      -
                    • Full path: //OpenSplice/DDSI2Service/Tracing/AppendToFile
                    • +
                    • Full path: /DDSI2EService/Tracing/AppendToFile
                    • Format: boolean
                    • Default value: false
                    • Occurrences min-max: 0-1
                    -
                    -

                    9.11.2   EnableCategory¶

                    + -
                    -

                    9.11.3   OutputFile¶

                    +
                    +

                    9.14.3   OutputFile¶

                    This option specifies where the logging is printed to. Note that stdout and stderr are treated as special values, representing “standard out” and “standard error” respectively. No file is created unless logging categories are enabled using the Tracing/Verbosity or Tracing/EnabledCategory settings.

                      -
                    • Full path: //OpenSplice/DDSI2Service/Tracing/OutputFile
                    • +
                    • Full path: /DDSI2EService/Tracing/OutputFile
                    • Format: string
                    • Default value: ddsi2.log
                    • Occurrences min-max: 0-1
                    -
                    -

                    9.11.4   PacketCaptureFile¶

                    +
                    +

                    9.14.4   PacketCaptureFile¶

                    This option specifies the file to which received and sent packets will be logged in the “pcap” format suitable for analysis using common networking tools, such as WireShark. IP and UDP headers are ficitious, in particular the destination address of received packets. The TTL may be used to distinguish between sent and received packets: it is 255 for sent packets and 128 for received ones. Currently IPv4 only.

                      -
                    • Full path: //OpenSplice/DDSI2Service/Tracing/PacketCaptureFile
                    • +
                    • Full path: /DDSI2EService/Tracing/PacketCaptureFile
                    • Format: string
                    • Occurrences min-max: 0-1
                    -
                    -

                    9.11.5   Timestamps¶

                    +
                    +

                    9.14.5   Timestamps¶

                    This option has no effect.

                      -
                    • Full path: //OpenSplice/DDSI2Service/Tracing/Timestamps
                    • +
                    • Full path: /DDSI2EService/Tracing/Timestamps
                    • Format: boolean
                    • Default value: true
                    • Occurrences min-max: 0-1
                    • Optional attributes: absolute
                    -
                    -

                    9.11.5.1   absolute¶

                    -

                    This option has no effect

                    +
                    +

                    9.14.5.1   absolute¶

                    +

                    This attribute specifies whether the timestamps in the log file are absolute or relative to the startup time of the service. Currently not implemented in DDSI2E, all timestamps are absolute.

                      -
                    • Full path: //OpenSplice/DDSI2Service/Tracing/Timestamps[@absolute]
                    • +
                    • Full path: /DDSI2EService/Tracing/Timestamps/absolute
                    • Format: boolean
                    • Default value: true
                    • Required: false
                    -
                    -

                    9.11.6   Verbosity¶

                    +
                    +

                    9.14.6   Verbosity¶

                    This element enables standard groups of categories, based on a desired verbosity level. This is in addition to the categories enabled by the Tracing/EnableCategory setting. Recognised verbosity levels and the categories they map to are:

                      -
                    • none: no DDSI2 log
                    • +
                    • none: no DDSI2E log
                    • severe: error and fatal
                    • warning: severe + warning
                    • -
                    • info: warning + info
                    • +
                    • info: equivalent to warning
                    • config: info + config
                    • fine: config + discovery
                    • -
                    • finer: fine + traffic and timing
                    • +
                    • finer: fine + traffic, timing & info
                    • finest: finer + trace
                    -

                    The categorisation of tracing output is incomplete and hence most of the verbosity levels and categories are not of much use in the current release. This is an ongoing process and here we describe the target situation rather than the current situation. Currently, the most useful verbosity levels are config, fine and finest.

                    +

                    While none prevents any message from being written to a DDSI2 log file, warnings and errors are still logged in the ospl-info.log and ospl-error.log files.

                    +

                    The categorisation of tracing output is incomplete and hence most of the verbosity levels and categories are not of much use in the current release. This is an ongoing process and here we describe the target situation rather than the current situation. Currently, the most useful verbosity levels are config and finest.

                      -
                    • Full path: //OpenSplice/DDSI2Service/Tracing/Verbosity
                    • +
                    • Full path: /DDSI2EService/Tracing/Verbosity
                    • Format: enumeration
                    • Default value: none
                    • Valid values: finest, finer, fine, config, info, warning, severe, none
                    • @@ -12248,47 +10890,47 @@

                      9.11.6   Verbosity -

                      9.12   Watchdog¶

                      +
                      +

                      9.15   Watchdog¶

                      This element specifies the type of OS scheduling class will be used by the thread that announces its liveliness periodically.

                        -
                      • Full path: //OpenSplice/DDSI2Service/Watchdog
                      • +
                      • Full path: /DDSI2EService/Watchdog
                      • Occurrences min-max: 0-1
                      -
                      -

                      9.12.1   Scheduling¶

                      +
                      +

                      9.15.1   Scheduling¶

                      This element specifies the type of OS scheduling class will be used by the thread that announces its liveliness periodically.

                        -
                      • Full path: //OpenSplice/DDSI2Service/Watchdog/Scheduling
                      • +
                      • Full path: /DDSI2EService/Watchdog/Scheduling
                      • Occurrences min-max: 0-1
                      • Child elements: Class, Priority
                      -
                      -

                      9.12.1.1   Class¶

                      +
                      +

                      9.15.1.1   Class¶

                      This element specifies the thread scheduling class that will be used by the watchdog thread. The user may need the appropriate privileges from the underlying operating system to be able to assign some of the privileged scheduling classes.

                        -
                      • Full path: //OpenSplice/DDSI2Service/Watchdog/Scheduling/Class
                      • +
                      • Full path: /DDSI2EService/Watchdog/Scheduling/Class
                      • Format: enumeration
                      • Default value: default
                      • Valid values: realtime, timeshare, default
                      • Occurrences min-max: 0-1
                      -
                      -

                      9.12.1.2   Priority¶

                      +
                      +

                      9.15.1.2   Priority¶

                      This element specifies the thread priority. Only priorities that are supported by the underlying operating system can be assigned to this element. The user may need special privileges from the underlying operating system to be able to assign some of the privileged priorities.

                        -
                      • Full path: //OpenSplice/DDSI2Service/Watchdog/Scheduling/Priority
                      • +
                      • Full path: /DDSI2EService/Watchdog/Scheduling/Priority
                      • Format: integer
                      • Default value: 0
                      • Occurrences min-max: 0-1
                      • Optional attributes: priority_kind
                      -
                      -
                      9.12.1.2.1   priority_kind¶
                      +
                      +
                      9.15.1.2.1   priority_kind¶

                      This attribute specifies whether the specified Priority is a relative or absolute priority.

                        -
                      • Full path: //OpenSplice/DDSI2Service/Watchdog/Scheduling/Priority[@priority_kind]
                      • +
                      • Full path: /DDSI2EService/Watchdog/Scheduling/Priority/priority_kind
                      • Format: enumeration
                      • Default value: relative
                      • Valid values: relative, absolute
                      • @@ -12301,17 +10943,16 @@
                        9.12.1.2.1   priority_kind

                        10   TunerService¶

                        -

                        The TunerService configuration determines how the Tuner Service handles the -incoming client connections. It expects a root element named -OpenSplice/TunerService, in which several child-elements may be specified. -Each of these are listed and explained.

                        +
                        +
                        The purpose of the control & monitoring SOAP service is to provide +remote access to the node for OpenSplice tooling.
                          -
                        • Full path: //OpenSplice/TunerService
                        • +
                        • Full path: /TunerService
                        • Occurrences min-max: 0-*
                        • Required attributes: name
                        -
                        -

                        10.1   name¶

                        +
                        +

                        10.1   name¶

                        This attribute identifies a configuration for the Tuner Service by name. Multiple Tuner Service configurations can be specified in one single @@ -12320,32 +10961,32 @@

                        10.1   name -
                      • Full path: //OpenSplice/TunerService[@name]
                      • +
                      • Full path: /TunerService/name
                      • Format: string
                      • Default value: cmsoap
                      • Required: true
                      -
                      -

                      10.2   Watchdog¶

                      +
                      +

                      10.2   Watchdog¶

                      This element controls the characteristics of the Watchdog thread.
                        -
                      • Full path: //OpenSplice/TunerService/Watchdog
                      • +
                      • Full path: /TunerService/Watchdog
                      • Occurrences min-max: 0-1
                      -
                      -

                      10.2.1   Scheduling¶

                      +
                      +

                      10.2.1   Scheduling¶

                      This element specifies the type of OS scheduling class will be used by the thread that announces its liveliness periodically.
                        -
                      • Full path: //OpenSplice/TunerService/Watchdog/Scheduling
                      • +
                      • Full path: /TunerService/Watchdog/Scheduling
                      • Occurrences min-max: 1-1
                      • Child elements: Priority, Class
                      -
                      -

                      10.2.1.1   Priority¶

                      +
                      +

                      10.2.1.1   Priority¶

                      This element specifies the thread priority that will be used by the watchdog thread. Only priorities that are supported by the @@ -12353,19 +10994,19 @@

                      10.2.1.1   Priority

                        -
                      • Full path: //OpenSplice/TunerService/Watchdog/Scheduling/Priority
                      • +
                      • Full path: /TunerService/Watchdog/Scheduling/Priority
                      • Format: integer
                      • Default value: 0
                      • Occurrences min-max: 1-1
                      • Optional attributes: priority_kind
                      -
                      -
                      10.2.1.1.1   priority_kind¶
                      +
                      +
                      10.2.1.1.1   priority_kind¶
                      This attribute specifies whether the specified Priority is a relative or absolute priority.
                        -
                      • Full path: //OpenSplice/TunerService/Watchdog/Scheduling/Priority[@priority_kind]
                      • +
                      • Full path: /TunerService/Watchdog/Scheduling/Priority/priority_kind
                      • Format: enumeration
                      • Default value: Relative
                      • Valid values: Relative, Absolute
                      • @@ -12373,15 +11014,15 @@
                        10.2.1.1.1   priority_kind
                      -
                      -

                      10.2.1.2   Class¶

                      +
                      +

                      10.2.1.2   Class¶

                      This element specifies the thread scheduling class that will be used by the watchdog thread. The user may need the appropriate privileges from the underlying operating system to be able to assign some of the privileged scheduling classes.
                      -
                      -

                      10.3.1   PortNr¶

                      +
                      +

                      10.3.1   PortNr¶

                      This element determines the port number that the TunerService will use to listen for incoming requests. This port number @@ -12408,9 +11049,9 @@

                      10.3.1   PortNr -
                    • Full path: //OpenSplice/TunerService/Server/PortNr
                    • +
                    • Full path: /TunerService/Server/PortNr
                    • Format: string
                    • -
                    • Default value: 8000
                    • +
                    • Default value: 50000
                    • Occurrences min-max: 0-1
                    @@ -12421,19 +11062,18 @@

                    10.3.2   Backlog -
                  • Full path: //OpenSplice/TunerService/Server/Backlog
                  • +
                  • Full path: /TunerService/Server/Backlog
                  • Format: integer
                  • Default value: 5
                  • -
                  • Valid values: 0 / -
                  • Occurrences min-max: 0-1
                  -
                  -

                  10.3.3   Verbosity¶

                  +
                  +

                  10.3.3   Verbosity¶

                  This element specifies the verbosity level of the logging of the service.
                  @@ -12458,10 +11098,9 @@

                  10.4.1   MaxClients

      -
    • Full path: //OpenSplice/TunerService/Client/MaxClients
    • +
    • Full path: /TunerService/Client/MaxClients
    • Format: integer
    • Default value: 10
    • -
    • Valid values: 1 / -
    • Occurrences min-max: 0-1
    @@ -12473,10 +11112,9 @@

    10.4.2   MaxThreadsPerClient -
  • Full path: //OpenSplice/TunerService/Client/MaxThreadsPerClient
  • +
  • Full path: /TunerService/Client/MaxThreadsPerClient
  • Format: integer
  • Default value: 10
  • -
  • Valid values: 1 / -
  • Occurrences min-max: 0-1
  • @@ -12491,44 +11129,42 @@

    10.4.3   LeasePeriod

      -
    • Full path: //OpenSplice/TunerService/Client/LeasePeriod
    • -
    • Dimension: seconds
    • +
    • Full path: /TunerService/Client/LeasePeriod
    • Default value: 15.0
    • -
    • Valid values: 10.0 / -
    • Occurrences min-max: 0-1
    -
    -

    10.4.4   Scheduling¶

    +
    +

    10.4.4   Scheduling¶

    This element specifies the scheduling policies used to control the threads that handle the client requests to the Tuner Service.
      -
    • Full path: //OpenSplice/TunerService/Client/Scheduling
    • +
    • Full path: /TunerService/Client/Scheduling
    • Occurrences min-max: 0-1
    • Child elements: Priority, Class
    -
    -

    10.4.4.1   Priority¶

    +
    +

    10.4.4.1   Priority¶

    This element specifies the thread priority that will be used by the threads that handle client requests to the Tuner Service. Only priorities that are supported by the underlying operating system can be assigned to this element. The user may need special privileges from the underlying operating system to be able to assign some of the privileged priorities.
      -
    • Full path: //OpenSplice/TunerService/Client/Scheduling/Priority
    • +
    • Full path: /TunerService/Client/Scheduling/Priority
    • Format: integer
    • Default value: 0
    • Occurrences min-max: 1-1
    • Optional attributes: priority_kind
    -
    -
    10.4.4.1.1   priority_kind¶
    +
    +
    10.4.4.1.1   priority_kind¶
    This attribute specifies whether the specified Priority is a relative or absolute priority.
      -
    • Full path: //OpenSplice/TunerService/Client/Scheduling/Priority[@priority_kind]
    • +
    • Full path: /TunerService/Client/Scheduling/Priority/priority_kind
    • Format: enumeration
    • Default value: Relative
    • Valid values: Relative, Absolute
    • @@ -12536,15 +11172,15 @@
      10.4.4.1.1   priority_kind
    -
    -

    10.4.4.2   Class¶

    +
    +

    10.4.4.2   Class¶

    This element specifies the thread scheduling class that will be used by the threads that handle client requests to the Tuner Service. The user may need the appropriate privileges from the underlying operating system to be able to assign some of the privileged scheduling classes.
      -
    • Full path: //OpenSplice/TunerService/Client/Scheduling/Class
    • +
    • Full path: /TunerService/Client/Scheduling/Class
    • Format: enumeration
    • Default value: Default
    • Valid values: Timeshare, Realtime, Default
    • @@ -12553,46 +11189,46 @@

      10.4.4.2   Class -

      10.5   GarbageCollector¶

      +
      +

      10.5   GarbageCollector¶

      This element specifies the behaviour of the garbage collection thread of the service.
        -
      • Full path: //OpenSplice/TunerService/GarbageCollector
      • +
      • Full path: /TunerService/GarbageCollector
      • Occurrences min-max: 0-1
      -
      -

      10.5.1   Scheduling¶

      +
      +

      10.5.1   Scheduling¶

      This element specifies the scheduling policies used to control the garbagage collection thread of the Tuner Service.
        -
      • Full path: //OpenSplice/TunerService/GarbageCollector/Scheduling
      • +
      • Full path: /TunerService/GarbageCollector/Scheduling
      • Occurrences min-max: 0-1
      • Child elements: Priority, Class
      -
      -

      10.5.1.1   Priority¶

      +
      +

      10.5.1.1   Priority¶

      This element specifies the thread priority that will be used by the garbage collection thread of the Tuner Service. Only priorities that are supported by the underlying operating system can be assigned to this element. The user may need special privileges from the underlying operating system to be able to assign some of the privileged priorities.
        -
      • Full path: //OpenSplice/TunerService/GarbageCollector/Scheduling/Priority
      • +
      • Full path: /TunerService/GarbageCollector/Scheduling/Priority
      • Format: integer
      • Default value: 0
      • Occurrences min-max: 1-1
      • Optional attributes: priority_kind
      -
      -
      10.5.1.1.1   priority_kind¶
      +
      +
      10.5.1.1.1   priority_kind¶
      This attribute specifies whether the specified Priority is a relative or absolute priority.
        -
      • Full path: //OpenSplice/TunerService/GarbageCollector/Scheduling/Priority[@priority_kind]
      • +
      • Full path: /TunerService/GarbageCollector/Scheduling/Priority/priority_kind
      • Format: enumeration
      • Default value: Relative
      • Valid values: Relative, Absolute
      • @@ -12600,15 +11236,15 @@
        10.5.1.1.1   priority_kind
      -
      -

      10.5.1.2   Class¶

      +
      +

      10.5.1.2   Class¶

      This element specifies the thread scheduling class that will be used by the garbage collection thread of the Tuner Service. The user may need the appropriate privileges from the underlying operating system to be able to assign some of the privileged scheduling classes.
      -
      -

      10.6.1   Scheduling¶

      +
      +

      10.6.1   Scheduling¶

      This element specifies the scheduling policies used to control the lease management thread of the Tuner Service.
        -
      • Full path: //OpenSplice/TunerService/LeaseManagement/Scheduling
      • +
      • Full path: /TunerService/LeaseManagement/Scheduling
      • Occurrences min-max: 0-1
      • Child elements: Priority, Class
      -
      -

      10.6.1.1   Priority¶

      +
      +

      10.6.1.1   Priority¶

      This element specifies the thread priority that will be used by the lease management thread of the Tuner Service. Only priorities that are supported by the underlying operating system can be assigned to this element. The user may need special privileges from the underlying operating system to be able to assign some of the privileged priorities.
        -
      • Full path: //OpenSplice/TunerService/LeaseManagement/Scheduling/Priority
      • +
      • Full path: /TunerService/LeaseManagement/Scheduling/Priority
      • Format: integer
      • Default value: 0
      • Occurrences min-max: 1-1
      • Optional attributes: priority_kind
      -
      -
      10.6.1.1.1   priority_kind¶
      +
      +
      10.6.1.1.1   priority_kind¶
      This attribute specifies whether the specified Priority is a relative or absolute priority.
        -
      • Full path: //OpenSplice/TunerService/LeaseManagement/Scheduling/Priority[@priority_kind]
      • +
      • Full path: /TunerService/LeaseManagement/Scheduling/Priority/priority_kind
      • Format: enumeration
      • Default value: Relative
      • Valid values: Relative, Absolute
      • @@ -12664,15 +11300,15 @@
        10.6.1.1.1   priority_kind
      -
      -

      10.6.1.2   Class¶

      +
      +

      10.6.1.2   Class¶

      This element specifies the thread scheduling class that will be used by the lease management thread of the Tuner Service. The user may need the appropriate privileges from the underlying operating system to be able to assign some of the privileged scheduling classes.
      -
      -

      11.1   name¶

      +
      +

      11.1   name¶

      This attribute identifies the configuration for the DBMS connect service by name. Multiple DBMS connect service configurations can be specified in one @@ -12704,32 +11340,32 @@

      11.1   name -
    • Full path: //OpenSplice/DbmsConnectService[@name]
    • +
    • Full path: /DbmsConnectService/name
    • Format: string
    • Default value: dbmsconnect
    • Required: true
    -
    -

    11.2   Watchdog¶

    +
    +

    11.2   Watchdog¶

    This element controls the characteristics of the Watchdog thread
      -
    • Full path: //OpenSplice/DbmsConnectService/Watchdog
    • +
    • Full path: /DbmsConnectService/Watchdog
    • Occurrences min-max: 0-1
    -
    -

    11.2.1   Scheduling¶

    +
    +

    11.2.1   Scheduling¶

    This element specifies the type of OS scheduling class will be used by the thread that announces its liveliness periodically.
      -
    • Full path: //OpenSplice/DbmsConnectService/Watchdog/Scheduling
    • +
    • Full path: /DbmsConnectService/Watchdog/Scheduling
    • Occurrences min-max: 1-1
    • Child elements: Priority, Class
    -
    -

    11.2.1.1   Priority¶

    +
    +

    11.2.1.1   Priority¶

    This element specifies the thread priority that will be used by the watchdog thread. Only priorities that are supported by the @@ -12737,19 +11373,19 @@

    11.2.1.1   Priority

      -
    • Full path: //OpenSplice/DbmsConnectService/Watchdog/Scheduling/Priority
    • +
    • Full path: /DbmsConnectService/Watchdog/Scheduling/Priority
    • Format: integer
    • Default value: 0
    • Occurrences min-max: 1-1
    • Optional attributes: priority_kind
    -
    -
    11.2.1.1.1   priority_kind¶
    +
    +
    11.2.1.1.1   priority_kind¶
    This attribute specifies whether the specified Priority is a relative or absolute priority.
      -
    • Full path: //OpenSplice/DbmsConnectService/Watchdog/Scheduling/Priority[@priority_kind]
    • +
    • Full path: /DbmsConnectService/Watchdog/Scheduling/Priority/priority_kind
    • Format: enumeration
    • Default value: Relative
    • Valid values: Relative, Absolute
    • @@ -12757,15 +11393,15 @@
      11.2.1.1.1   priority_kind
    -
    -

    11.2.1.2   Class¶

    +
    +

    11.2.1.2   Class¶

    This element specifies the thread scheduling class that will be used by the watchdog thread. The user may need the appropriate privileges from the underlying operating system to be able to assign some of the privileged scheduling classes.
      -
    • Full path: //OpenSplice/DbmsConnectService/DdsToDbms
    • +
    • Full path: /DbmsConnectService/DdsToDbms
    • Occurrences min-max: 0-1
    • Optional attributes: replication_mode
    @@ -12808,32 +11444,32 @@

    11.3.1   replication_mode -
  • Full path: //OpenSplice/DbmsConnectService/DdsToDbms[@replication_mode]
  • +
  • Full path: /DbmsConnectService/DdsToDbms/replication_mode
  • Format: boolean
  • Default value: FALSE
  • Required: false
  • -
    -

    11.3.2   NameSpace¶

    +
    +

    11.3.2   NameSpace¶

    This element specifies the responsibilities of the service concerning the bridging of particular data from DDS to DBMS. At least one NameSpace element has to be present in a DdsToDbms element.
      -
    • Full path: //OpenSplice/DbmsConnectService/DdsToDbms/NameSpace
    • +
    • Full path: /DbmsConnectService/DdsToDbms/NameSpace
    • Occurrences min-max: 1-*
    • Required attributes: dsn, usr, pwd
    • Optional attributes: name, odbc, partition, topic, update_frequency, schema, catalog, replication_mode
    -
    -

    11.3.2.1   name¶

    +
    +

    11.3.2.1   name¶

    The name of the namespace. If not specified, the namespace will be named “(nameless)”.
    -
    -

    11.3.2.3   partition¶

    + @@ -12914,7 +11548,7 @@

    11.3.2.6   dsn -
  • Full path: //OpenSplice/DbmsConnectService/DdsToDbms/NameSpace[@dsn]
  • +
  • Full path: /DbmsConnectService/DdsToDbms/NameSpace/dsn
  • Format: string
  • Default value: n/a
  • Required: true
  • @@ -12925,7 +11559,7 @@

    11.3.2.7   usr -
  • Full path: //OpenSplice/DbmsConnectService/DdsToDbms/NameSpace[@usr]
  • +
  • Full path: /DbmsConnectService/DdsToDbms/NameSpace/usr
  • Format: string
  • Default value: n/a
  • Required: true
  • @@ -12936,7 +11570,7 @@

    11.3.2.8   pwd -
  • Full path: //OpenSplice/DbmsConnectService/DdsToDbms/NameSpace[@pwd]
  • +
  • Full path: /DbmsConnectService/DdsToDbms/NameSpace/pwd
  • Format: string
  • Default value: n/a
  • Required: true
  • @@ -12949,7 +11583,7 @@

    11.3.2.9   schema -
  • Full path: //OpenSplice/DbmsConnectService/DdsToDbms/NameSpace[@schema]
  • +
  • Full path: /DbmsConnectService/DdsToDbms/NameSpace/schema
  • Format: string
  • Default value: “”
  • Required: false
  • @@ -12962,14 +11596,14 @@

    11.3.2.10   catalog

      -
    • Full path: //OpenSplice/DbmsConnectService/DdsToDbms/NameSpace[@catalog]
    • +
    • Full path: /DbmsConnectService/DdsToDbms/NameSpace/catalog
    • Format: string
    • Default value: “”
    • Required: false
    -
    -

    11.3.2.11   replication_mode¶

    +
    +

    11.3.2.11   replication_mode¶

      -
    • Full path: //OpenSplice/DbmsConnectService/DdsToDbms/NameSpace/Mapping
    • +
    • Full path: /DbmsConnectService/DdsToDbms/NameSpace/Mapping
    • Occurrences min-max: 0-*
    • Required attributes: topic
    • Optional attributes: table, query, filter
    -
    -
    11.3.2.12.1   topic¶
    +
    +
    11.3.2.12.1   topic¶
    -
    This attribute specifies the name of the topic where the Mapping applies to. If you -specify no particular topic, it will create tables for all topics
    +
    This attribute specifies the name of the topic where the Mapping applies to.
      -
    • Full path: //OpenSplice/DbmsConnectService/DdsToDbms/NameSpace/Mapping[@topic]
    • +
    • Full path: /DbmsConnectService/DdsToDbms/NameSpace/Mapping/topic
    • Format: string
    • Default value: n/a
    • Required: true
    • @@ -13034,7 +11667,7 @@
      11.3.2.12.2   table
      -
    • Full path: //OpenSplice/DbmsConnectService/DdsToDbms/NameSpace/Mapping[@query]
    • +
    • Full path: /DbmsConnectService/DdsToDbms/NameSpace/Mapping/query
    • Format: string
    • Default value: “”
    • Required: false
    -
      -
    • Full path: //OpenSplice/DbmsConnectService/DbmsToDds
    • +
    • Full path: /DbmsConnectService/DbmsToDds
    • Occurrences min-max: 0-1
    • Optional attributes: publish_initial_data, event_table_policy, trigger_policy, replication_user
    @@ -13091,7 +11724,7 @@

    11.4.1   publish_initial_data -
  • Full path: //OpenSplice/DbmsConnectService/DbmsToDds[@publish_initial_data]
  • +
  • Full path: /DbmsConnectService/DbmsToDds/publish_initial_data
  • Format: boolean
  • Default value: true
  • Required: false
  • @@ -13110,7 +11743,7 @@

    11.4.2   event_table_policy -
  • Full path: //OpenSplice/DbmsConnectService/DbmsToDds[@event_table_policy]
  • +
  • Full path: /DbmsConnectService/DbmsToDds/event_table_policy
  • Format: enumeration
  • Default value: FULL
  • Valid values: FULL, LAZY, NONE
  • @@ -13130,7 +11763,7 @@

    11.4.3   trigger_policy -
  • Full path: //OpenSplice/DbmsConnectService/DbmsToDds[@trigger_policy]
  • +
  • Full path: /DbmsConnectService/DbmsToDds/trigger_policy
  • Format: enumeration
  • Default value: FULL
  • Valid values: FULL, LAZY, NONE
  • @@ -13165,38 +11798,38 @@

    11.4.4   replication_user -
  • Full path: //OpenSplice/DbmsConnectService/DbmsToDds[@replication_user]
  • +
  • Full path: /DbmsConnectService/DbmsToDds/replication_user
  • Format: string
  • Default value: “”
  • Required: false
  • -
    -

    11.4.5   NameSpace¶

    +
    +

    11.4.5   NameSpace¶

    This element specifies the responsibilities of the service concerning the bridging of data from DBMS to DDS. At least one NameSpace element has to be present in a DbmsToDds element.
      -
    • Full path: //OpenSplice/DbmsConnectService/DbmsToDds/NameSpace
    • +
    • Full path: /DbmsConnectService/DbmsToDds/NameSpace
    • Occurrences min-max: 1-*
    • Required attributes: dsn, usr, pwd
    • Optional attributes: name, odbc, partition, table, update_frequency, publish_initial_data, force_key_equality, event_table_policy, trigger_policy, schema, catalog, replication_user
    -
    -

    11.4.5.1   name¶

    +
    +

    11.4.5.1   name¶

    The name of the namespace. If not specified, the namespace will be named “(nameless)”.
      -
    • Full path: //OpenSplice/DbmsConnectService/DbmsToDds/NameSpace[@name]
    • +
    • Full path: /DbmsConnectService/DbmsToDds/NameSpace/name
    • Format: string
    • Default value: (nameless)
    • Required: false
    -
    -

    11.4.5.2   odbc¶

    +
    +

    11.4.5.2   odbc¶

    The service dynamically loads an ODBC library at runtime. This attribute specifies the name of the ODBC library to be loaded. Platform specific @@ -13206,14 +11839,14 @@

    11.4.5.2   odbc -
  • Full path: //OpenSplice/DbmsConnectService/DbmsToDds/NameSpace[@odbc]
  • +
  • Full path: /DbmsConnectService/DbmsToDds/NameSpace/odbc
  • Format: string
  • Default value: “”
  • Required: false
  • -
    -

    11.4.5.3   partition¶

    +
    +

    11.4.5.3   partition¶

    This attribute specifies an expression represents one or more DDS partitions. It is allowed to use wildcards in the expression: a ‘*’ represents any @@ -13222,14 +11855,14 @@

    11.4.5.3   partition

      -
    • Full path: //OpenSplice/DbmsConnectService/DbmsToDds/NameSpace[@partition]
    • +
    • Full path: /DbmsConnectService/DbmsToDds/NameSpace/partition
    • Format: string
    • Default value: *
    • Required: false
    -
    -

    11.4.5.4   table¶

    +
    +

    11.4.5.4   table¶

    This attribute specifies an expression that represents one or more DBMS table names. It is allowed to use wildcards in the expression: a ‘*’ @@ -13239,14 +11872,14 @@

    11.4.5.4   table -
  • Full path: //OpenSplice/DbmsConnectService/DbmsToDds/NameSpace[@table]
  • +
  • Full path: /DbmsConnectService/DbmsToDds/NameSpace/table
  • Format: string
  • Default value: *
  • Required: false
  • -
    -

    11.4.5.5   update_frequency¶

    +
    +

    11.4.5.5   update_frequency¶

    This attribute specifies the frequency (in Hz) at which the service will update the DDS domain with DBMS data. @@ -13254,49 +11887,47 @@

    11.4.5.5   update_frequency -
  • Full path: //OpenSplice/DbmsConnectService/DbmsToDds/NameSpace[@update_frequency]
  • -
  • Dimension: Hz
  • +
  • Full path: /DbmsConnectService/DbmsToDds/NameSpace/update_frequency
  • Default value: 2.0
  • -
  • Valid values: 0.0 / -
  • Required: false
  • -
    -

    11.4.5.6   dsn¶

    +
    +

    11.4.5.6   dsn¶

    Represents the Data Source Name, that represents the DBMS where the service must bridge the DDS data from.
      -
    • Full path: //OpenSplice/DbmsConnectService/DbmsToDds/NameSpace[@dsn]
    • +
    • Full path: /DbmsConnectService/DbmsToDds/NameSpace/dsn
    • Format: string
    • Default value: n/a
    • Required: true
    -
    -

    11.4.5.7   usr¶

    +
    +

    11.4.5.7   usr¶

    Represents the user name that is used when connecting to the DBMS.
      -
    • Full path: //OpenSplice/DbmsConnectService/DbmsToDds/NameSpace[@usr]
    • +
    • Full path: /DbmsConnectService/DbmsToDds/NameSpace/usr
    • Format: string
    • Default value: n/a
    • Required: true
    -
    -

    11.4.5.8   pwd¶

    +
    +

    11.4.5.8   pwd¶

    Represents the password that is used when connecting to the DBMS.
      -
    • Full path: //OpenSplice/DbmsConnectService/DbmsToDds/NameSpace[@pwd]
    • +
    • Full path: /DbmsConnectService/DbmsToDds/NameSpace/pwd
    • Format: string
    • Default value: n/a
    • Required: true
    -
    -

    11.4.5.9   publish_initial_data¶

    +
    +

    11.4.5.9   publish_initial_data¶

    -
    -

    11.4.5.11   event_table_policy¶

    +
    +

    11.4.5.11   event_table_policy¶

    This attribute specifies the default setting of the event table policy for all Mapping elements in the current NameSpace element. If not specified, the value will be inherited from the event_table_policy of the parent DbmsToDds element, which if not explicitly specified defaults to FULL.

    An event table (sometimes referred to as ‘change table’ or ‘shadow table’) is a support-table that is slaved to an application-table, adding some status flags that are under the control of a trigger mechanism that responds to creation/modification/ deletion events in the application-table.

    @@ -13338,15 +11969,15 @@

    11.4.5.11   event_table_policy -
  • Full path: //OpenSplice/DbmsConnectService/DbmsToDds/NameSpace[@event_table_policy]
  • +
  • Full path: /DbmsConnectService/DbmsToDds/NameSpace/event_table_policy
  • Format: enumeration
  • Default value: FULL
  • Valid values: FULL, LAZY, NONE
  • Required: false
  • -
    -

    11.4.5.12   trigger_policy¶

    +
    +

    11.4.5.12   trigger_policy¶

    This attribute specifies the default trigger policy for all Mapping elements in the current NameSpace element. If not specified, the value will be inherited from the trigger_policy of the parent DbmsToDds element, which if not explicitly specified defaults to FULL.

    Triggers are used to to update the event table in case of creation/modification/ deletion events on the application-table.

    @@ -13358,37 +11989,37 @@

    11.4.5.12   trigger_policy

      -
    • Full path: //OpenSplice/DbmsConnectService/DbmsToDds/NameSpace[@trigger_policy]
    • +
    • Full path: /DbmsConnectService/DbmsToDds/NameSpace/trigger_policy
    • Format: enumeration
    • Default value: FULL
    • Valid values: FULL, LAZY, NONE
    • Required: false
    -
    -

    11.4.5.13   schema¶

    +
    +

    11.4.5.13   schema¶

    Represents the schema that is used when communicating with the DBMS.
      -
    • Full path: //OpenSplice/DbmsConnectService/DbmsToDds/NameSpace[@schema]
    • +
    • Full path: /DbmsConnectService/DbmsToDds/NameSpace/schema
    • Format: string
    • Default value: “”
    • Required: false
    -
    -

    11.4.5.14   catalog¶

    +
    +

    11.4.5.14   catalog¶

    Represents the catalog that is used when communicating with the DBMS.
      -
    • Full path: //OpenSplice/DbmsConnectService/DbmsToDds/NameSpace[@catalog]
    • +
    • Full path: /DbmsConnectService/DbmsToDds/NameSpace/catalog
    • Format: string
    • Default value: “”
    • Required: false
    -
    -

    11.4.5.15   replication_user¶

    +
    +

    11.4.5.15   replication_user¶

    This attribute specifies the default replication user for all Mapping elements in the current NameSpace @@ -13417,65 +12048,65 @@

    11.4.5.15   replication_user -
  • Full path: //OpenSplice/DbmsConnectService/DbmsToDds/NameSpace[@replication_user]
  • +
  • Full path: /DbmsConnectService/DbmsToDds/NameSpace/replication_user
  • Format: string
  • Default value: “”
  • Required: false
  • -
    -

    11.4.5.16   Mapping¶

    +
    +

    11.4.5.16   Mapping¶

    This element specifies a modification to the way that the service handles a pre-configured set of data within the specified NameSpace. Its attributes are used to configure the responsibilities of the service concerning the bridging of data from DBMS to DDS
      -
    • Full path: //OpenSplice/DbmsConnectService/DbmsToDds/NameSpace/Mapping
    • +
    • Full path: /DbmsConnectService/DbmsToDds/NameSpace/Mapping
    • Occurrences min-max: 0-*
    • Required attributes: table
    • Optional attributes: topic, query, publish_initial_data, force_key_equality, event_table_policy, trigger_policy
    -
    -
    11.4.5.16.1   table¶
    +
    +
    11.4.5.16.1   table¶
    This attribute specifies the name of the table where the Mapping applies to.
      -
    • Full path: //OpenSplice/DbmsConnectService/DbmsToDds/NameSpace/Mapping[@table]
    • +
    • Full path: /DbmsConnectService/DbmsToDds/NameSpace/Mapping/table
    • Format: string
    • Default value: n/a
    • Required: true
    -
    -
    11.4.5.16.2   topic¶
    +
    +
    11.4.5.16.2   topic¶
    This attribute specifies an alternative name for the topic that must be associated with the table. By default the topic name is equal to the table name.
      -
    • Full path: //OpenSplice/DbmsConnectService/DbmsToDds/NameSpace/Mapping[@topic]
    • +
    • Full path: /DbmsConnectService/DbmsToDds/NameSpace/Mapping/topic
    • Format: string
    • Default value: “”
    • Required: false
    -
    -
    11.4.5.16.3   query¶
    +
    +
    11.4.5.16.3   query¶
    Optional DBMS query expression. Only DBMS data that matches the query will be bridged to the DDS domain. This is realized by means of a SQL query. The default value is an empty string, representing all available data in the selected table.
      -
    • Full path: //OpenSplice/DbmsConnectService/DbmsToDds/NameSpace/Mapping[@query]
    • +
    • Full path: /DbmsConnectService/DbmsToDds/NameSpace/Mapping/query
    • Format: string
    • Default value: “”
    • Required: false
    -
    -
    11.4.5.16.4   publish_initial_data¶
    +
    +
    11.4.5.16.4   publish_initial_data¶
    This attribute specifies the behaviour with respect to publishing the initially available data specified in the current Mapping element @@ -13486,14 +12117,14 @@
    11.4.5.16.4   publish_initial_dataevent_table_policy is set to NONE.
      -
    • Full path: //OpenSplice/DbmsConnectService/DbmsToDds/NameSpace/Mapping[@publish_initial_data]
    • +
    • Full path: /DbmsConnectService/DbmsToDds/NameSpace/Mapping/publish_initial_data
    • Format: boolean
    • Default value: true
    • Required: false
    -
    -
    11.4.5.16.5   force_key_equality¶
    +
    +
    11.4.5.16.5   force_key_equality¶
    This attribute specifies the enforcement of key equality between table and topic definitions. If true, key definitions from the table and @@ -13501,14 +12132,14 @@
    11.4.5.16.5   force_key_equality -
  • Full path: //OpenSplice/DbmsConnectService/DbmsToDds/NameSpace/Mapping[@force_key_equality]
  • +
  • Full path: /DbmsConnectService/DbmsToDds/NameSpace/Mapping/force_key_equality
  • Format: boolean
  • Default value: true
  • Required: false
  • -
    -
    11.4.5.16.6   event_table_policy¶
    +
    +
    11.4.5.16.6   event_table_policy¶

    This attribute specifies the event table policy in the current Mapping element. If not specified, the value will be inherited from the event_table_policy of the parent NameSpace element, which if not explicitly specified inherits from the event_table_policy of the parent DbmsToDds element, which defaults to FULL.

    An event table (sometimes referred to as ‘change table’ or ‘shadow table’) is a support-table that is slaved to an application-table, adding some status flags that are under the control of a trigger mechanism that responds to creation/modification/ deletion events in the application-table.

    @@ -13520,15 +12151,15 @@
    11.4.5.16.6   event_table_policy -
  • Full path: //OpenSplice/DbmsConnectService/DbmsToDds/NameSpace/Mapping[@event_table_policy]
  • +
  • Full path: /DbmsConnectService/DbmsToDds/NameSpace/Mapping/event_table_policy
  • Format: enumeration
  • Default value: FULL
  • Valid values: FULL, LAZY, NONE
  • Required: false
  • -
    -
    11.4.5.16.7   trigger_policy¶
    +
    +
    11.4.5.16.7   trigger_policy¶

    This attribute specifies the trigger policy for the current Mapping element. If not specified, the value will be inherited from the trigger_policy of the parent DbmsToDds element, which if not explicitly specified inherits from the trigger_policy of the parent DbmsToDds element, which defaults to FULL.

    Triggers are used to to update the event table in case of creation/modification/ deletion events on the application-table.

    @@ -13540,7 +12171,7 @@
    11.4.5.16.7   trigger_policy -
  • Full path: //OpenSplice/DbmsConnectService/DbmsToDds/NameSpace/Mapping[@trigger_policy]
  • +
  • Full path: /DbmsConnectService/DbmsToDds/NameSpace/Mapping/trigger_policy
  • Format: enumeration
  • Default value: FULL
  • Valid values: FULL, LAZY, NONE
  • @@ -13550,63 +12181,62 @@
    11.4.5.16.7   trigger_policy -

    11.5   Tracing¶

    +
    +

    11.5   Tracing¶

    This element controls the amount and type of information that is written into the tracing log file by the DbmsConnect Service. This is useful to track the DbmsConnect Service during application development. In the runtime system it should be turned off.
      -
    • Full path: //OpenSplice/DbmsConnectService/Tracing
    • +
    • Full path: /DbmsConnectService/Tracing
    • Occurrences min-max: 0-1
    • Child elements: OutputFile, Timestamps, Verbosity
    -
    -

    11.5.1   OutputFile¶

    +
    +

    11.5.1   OutputFile¶

    This element specifies where the logging is printed to. Note that “stdout” and “stderr” are considered legal values that represent “standard out” and “standard error” respectively. The default value is an empty string, indicating that all tracing is disabled.
      -
    • Full path: //OpenSplice/DbmsConnectService/Tracing/OutputFile
    • +
    • Full path: /DbmsConnectService/Tracing/OutputFile
    • Format: string
    • -
    • Dimension: file name
    • Default value: dbmsconnect.log
    • Occurrences min-max: 0-1
    -
    -

    11.5.2   Timestamps¶

    +
    +

    11.5.2   Timestamps¶

    This element specifies whether the logging must contain timestamps.
      -
    • Full path: //OpenSplice/DbmsConnectService/Tracing/Timestamps
    • +
    • Full path: /DbmsConnectService/Tracing/Timestamps
    • Format: boolean
    • Default value: true
    • Occurrences min-max: 0-1
    • Optional attributes: absolute
    -
    -

    11.5.2.1   absolute¶

    +
    +

    11.5.2.1   absolute¶

    This attribute specifies whether the timestamps are absolute or relative to the startup time of the service.
      -
    • Full path: //OpenSplice/DbmsConnectService/Tracing/Timestamps[@absolute]
    • +
    • Full path: /DbmsConnectService/Tracing/Timestamps/absolute
    • Format: boolean
    • Default value: true
    • Required: false
    -
    -

    11.5.3   Verbosity¶

    +
    +

    11.5.3   Verbosity¶

    This element specifies the verbosity level of the logging.
      -
    • Full path: //OpenSplice/RnRService
    • +
    • Full path: /RnRService
    • Occurrences min-max: 0-*
    • Required attributes: name
    -
    -

    12.1   name¶

    +
    +

    12.1   name¶

    This attribute identifies a configuration for the Record and Replay Service by name. Multiple service configurations can be specified in one single resource file. The actual @@ -13634,32 +12264,32 @@

    12.1   name -
  • Full path: //OpenSplice/RnRService[@name]
  • +
  • Full path: /RnRService/name
  • Format: string
  • Default value: rnr
  • Required: true
  • -
    -

    12.2   Watchdog¶

    +
    +

    12.2   Watchdog¶

    This element controls the characteristics of the Watchdog thread.
      -
    • Full path: //OpenSplice/RnRService/Watchdog
    • +
    • Full path: /RnRService/Watchdog
    • Occurrences min-max: 0-1
    -
    -

    12.2.1   Scheduling¶

    +
    +

    12.2.1   Scheduling¶

    This element specifies the type of OS scheduling class will be used by the thread that announces its liveliness periodically.
      -
    • Full path: //OpenSplice/RnRService/Watchdog/Scheduling
    • +
    • Full path: /RnRService/Watchdog/Scheduling
    • Occurrences min-max: 1-1
    • Child elements: Priority, Class
    -
    -

    12.2.1.1   Priority¶

    +
    +

    12.2.1.1   Priority¶

    This element specifies the thread priority that will be used by the watchdog thread. Only priorities that are supported by the @@ -13667,19 +12297,19 @@

    12.2.1.1   Priority

      -
    • Full path: //OpenSplice/RnRService/Watchdog/Scheduling/Priority
    • +
    • Full path: /RnRService/Watchdog/Scheduling/Priority
    • Format: integer
    • Default value: 0
    • Occurrences min-max: 1-1
    • Optional attributes: priority_kind
    -
    -
    12.2.1.1.1   priority_kind¶
    +
    +
    12.2.1.1.1   priority_kind¶
    This attribute specifies whether the specified Priority is a relative or absolute priority.
      -
    • Full path: //OpenSplice/RnRService/Watchdog/Scheduling/Priority[@priority_kind]
    • +
    • Full path: /RnRService/Watchdog/Scheduling/Priority/priority_kind
    • Format: enumeration
    • Default value: Relative
    • Valid values: Relative, Absolute
    • @@ -13687,15 +12317,15 @@
      12.2.1.1.1   priority_kind
    -
    -

    12.2.1.2   Class¶

    +
    +

    12.2.1.2   Class¶

    This element specifies the thread scheduling class that will be used by the watchdog thread. The user may need the appropriate privileges from the underlying operating system to be able to assign some of the privileged scheduling classes.
      -
    • Full path: //OpenSplice/RnRService/Watchdog/Scheduling/Class
    • +
    • Full path: /RnRService/Watchdog/Scheduling/Class
    • Format: enumeration
    • Default value: Default
    • Valid values: Timeshare, Realtime, Default
    • @@ -13706,23 +12336,23 @@

      12.2.1.2   Class

      12.3   Storage¶

      -
      -
      This element specifies a storage to use for recording and/or replaying data.
      -
      Currently the supported storage backends are XML and CDR. +
      +
      This element specifies a storage to use for recording and/or replaying data. +Currently the supported storage backends are XML and CDR. Note that storages can also be created, or their properties modified, by Record and Replay configuration-commands. These commands use the same syntax to specify configuration data as the OpenSplice configuration file, -so the description given here also applies to commands.
      -
      +so the description given here also applies to commands.

      -
    • Full path: //OpenSplice/RnRService/Storage
    • +
    • Full path: /RnRService/Storage
    • Occurrences min-max: 0-*
    • Required attributes: name
    -
    -

    12.3.1   name¶

    -

    The name used to identify the storage in Record and Replay commands.

    +
    +

    12.3.1   name¶

    +
    +
    The name used to identify the storage in Record and Replay commands.
      -
    • Full path: //OpenSplice/RnRService/Storage[@name]
    • +
    • Full path: /RnRService/Storage/name
    • Format: string
    • Default value: default
    • Required: true
    • @@ -13730,21 +12360,21 @@

      12.3.1   name

      12.3.2   rr_storageAttrXML¶

      -

      Attributes describing an XML storage.

      +
      +
      Attributes describing an XML storage.
        -
      • Full path: //OpenSplice/RnRService/Storage/rr_storageAttrXML
      • +
      • Full path: /RnRService/Storage/rr_storageAttrXML
      • Occurrences min-max: 0-1
      • Child elements: filename, MaxFileSize

      12.3.2.1   filename¶

      -
      -
      The filename template used for files that comprise a storage.
      -
      The filename may contain a relative or absolute path. If a path is omitted, -the storage files are created in the current working directory.
      -
      +
      +
      The filename template used for files that comprise a storage. +The filename may contain a relative or absolute path. If a path is omitted, +the storage files are created in the current working directory.
        -
      • Full path: //OpenSplice/RnRService/Storage/rr_storageAttrXML/filename
      • +
      • Full path: /RnRService/Storage/rr_storageAttrXML/filename
      • Format: string
      • Default value: rnr-storage.dat
      • Occurrences min-max: 1-1
      • @@ -13752,81 +12382,77 @@

        12.3.2.1   filename

        12.3.2.2   MaxFileSize¶

        -
        -
        The maximum size per storage file. When approaching the maximum size while recording,
        -
        a new storage file is automatically created with a sequence number appended to the filename. +
        +
        The maximum size per storage file. When approaching the maximum size while recording, +a new storage file is automatically created with a sequence number appended to the filename. The active file is also switched transparently while replaying from a storage that contains multiple data files. The human-readable option lets the user postfix the value with K(ilobyte), M(egabyte) or G(igabtye). For example, 10M results in 10485760 bytes. This element is optional, when omitted or when 0 is configured, the file size is not monitored -by the service and limited only by filesystem and/or platform-specific limits.
        -
        +by the service and limited only by filesystem and/or platform-specific limits.

      -
    • Full path: //OpenSplice/RnRService/Storage/rr_storageAttrXML/MaxFileSize
    • -
    • Dimension: bytes
    • +
    • Full path: /RnRService/Storage/rr_storageAttrXML/MaxFileSize
    • Default value: 0
    • -
    • Valid values: 0 / -
    • Occurrences min-max: 0-1

    12.3.3   rr_storageAttrCDR¶

    -

    Attributes describing an CDR storage.

    +
    +
    Attributes describing an CDR storage.
      -
    • Full path: //OpenSplice/RnRService/Storage/rr_storageAttrCDR
    • +
    • Full path: /RnRService/Storage/rr_storageAttrCDR
    • Occurrences min-max: 0-1
    • Child elements: filename, MaxFileSize
    -
    -

    12.3.3.1   filename¶

    -
    -
    The filename template used for files that comprise a storage.
    -
    The filename may contain a relative or absolute path. If a path is omitted, -the storage files are created in the current working directory.
    -
    +
    +

    12.3.3.1   filename¶

    +
    +
    The filename template used for files that comprise a storage. +The filename may contain a relative or absolute path. If a path is omitted, +the storage files are created in the current working directory.
      -
    • Full path: //OpenSplice/RnRService/Storage/rr_storageAttrCDR/filename
    • +
    • Full path: /RnRService/Storage/rr_storageAttrCDR/filename
    • Format: string
    • Default value: rnr-storage.dat
    • Occurrences min-max: 1-1
    -
    -

    12.3.3.2   MaxFileSize¶

    -
    -
    The maximum size per storage file. When approaching the maximum size while recording,
    -
    a new storage file is automatically created with a sequence number appended to the filename. +
    +

    12.3.3.2   MaxFileSize¶

    +
    +
    The maximum size per storage file. When approaching the maximum size while recording, +a new storage file is automatically created with a sequence number appended to the filename. The active file is also switched transparently while replaying from a storage that contains multiple data files. The human-readable option lets the user postfix the value with K(ilobyte), M(egabyte) or G(igabtye). For example, 10M results in 10485760 bytes. This element is optional, when omitted or when 0 is configured, the file size is not monitored -by the service and limited only by filesystem and/or platform-specific limits.
    -
    +by the service and limited only by filesystem and/or platform-specific limits.
      -
    • Full path: //OpenSplice/RnRService/Storage/rr_storageAttrCDR/MaxFileSize
    • -
    • Dimension: bytes
    • +
    • Full path: /RnRService/Storage/rr_storageAttrCDR/MaxFileSize
    • Default value: 0
    • -
    • Valid values: 0 / -
    • Occurrences min-max: 0-1
    -
    -

    12.3.4   Statistics¶

    -

    Maintain and optionally publish statistics for this storage.

    +
    +

    12.3.4   Statistics¶

    +
    +
    Maintain and optionally publish statistics for this storage.
      -
    • Full path: //OpenSplice/RnRService/Storage/Statistics
    • +
    • Full path: /RnRService/Storage/Statistics
    • Occurrences min-max: 0-1
    • Optional attributes: enabled, publish_interval, reset
    -
    -

    12.3.4.1   enabled¶

    -

    This attribute specifies if statistics should be maintained for this storage.

    +
    +

    12.3.4.1   enabled¶

    +
    +
    This attribute specifies if statistics should be maintained for this storage.
      -
    • Full path: //OpenSplice/RnRService/Storage/Statistics[@enabled]
    • +
    • Full path: /RnRService/Storage/Statistics/enabled
    • Format: boolean
    • Default value: true
    • Occurrences min-max: 1-1
    • @@ -13835,16 +12461,14 @@

      12.3.4.1   enabled

      12.3.4.2   publish_interval¶

      -
      -
      This attribute specifies the publication interval of the statistics belonging to this storage,
      -
      in a Record and Replay storage-statistics topic. The publish interval is a value in seconds but may also +
      +
      This attribute specifies the publication interval of the statistics belonging to this storage, +in a Record and Replay storage-statistics topic. The publish interval is a value in seconds but may also be set to -1. This means the statistics are published when the storage is closed. Note that a value of 0 means -statistics are never published.
      -
      +statistics are never published.

      -
    • Full path: //OpenSplice/RnRService/Storage/Statistics[@publish_interval]
    • +
    • Full path: /RnRService/Storage/Statistics/publish_interval
    • Format: integer
    • -
    • Dimension: seconds
    • Default value: 30
    • Occurrences min-max: 1-1
    • Required: false
    • @@ -13852,13 +12476,12 @@

      12.3.4.2   publish_interval

      12.3.4.3   reset¶

      -
      -
      This attribute allows to reset the current values of statistics belonging to the storage. Note
      -
      that this only makes sense in a configuration-command for an existing storage, since new storages created -from the OpenSplice configuration file always start out with empty statistics.
      -
      +
      +
      This attribute allows to reset the current values of statistics belonging to the storage. Note +that this only makes sense in a configuration-command for an existing storage, since new storages created +from the OpenSplice configuration file always start out with empty statistics.
        -
      • Full path: //OpenSplice/RnRService/Storage/Statistics[@reset]
      • +
      • Full path: /RnRService/Storage/Statistics/reset
      • Format: boolean
      • Default value: false
      • Occurrences min-max: 0-1
      • @@ -13867,63 +12490,61 @@

        12.3.4.3   reset -

        12.4   Tracing¶

        -

        This element enables debug output of the R&R service to a logfile.

        +
        +

        12.4   Tracing¶

        +
        +
        This element enables debug output of the R&R service to a logfile.
          -
        • Full path: //OpenSplice/RnRService/Tracing
        • +
        • Full path: /RnRService/Tracing
        • Occurrences min-max: 0-1
        • Child elements: OutputFile, AppendToFile, Verbosity, EnableCategory
        -
        -

        12.4.1   OutputFile¶

        -
        -
        This option specifies where the logging is printed to.
        -
        Note that “stdout” is considered a legal value that represents “standard out” -and “stderr” is a legal value representing “standard error”.
        -
        +
        +

        12.4.1   OutputFile¶

        +
        +
        This option specifies where the logging is printed to. +Note that “stdout” is considered a legal value that represents “standard out” +and “stderr” is a legal value representing “standard error”.
          -
        • Full path: //OpenSplice/RnRService/Tracing/OutputFile
        • +
        • Full path: /RnRService/Tracing/OutputFile
        • Format: string
        • Default value: rnr.log
        • Occurrences min-max: 1-1
        -
        -

        12.4.2   AppendToFile¶

        -
        -
        This option specifies whether the output is to be appended to an existing log file.
        -
        The default is to overwrite the log file if it exists.
        -
        +
        +

        12.4.2   AppendToFile¶

        +
        +
        This option specifies whether the output is to be appended to an existing log file. +The default is to overwrite the log file if it exists.
          -
        • Full path: //OpenSplice/RnRService/Tracing/AppendToFile
        • +
        • Full path: /RnRService/Tracing/AppendToFile
        • Format: boolean
        • Default value: false
        • Occurrences min-max: 0-1
        -
        -

        12.4.3   Verbosity¶

        -
        -
        This element specifies the verbosity level of the logging information.
        -
        The higher the level, the more (detailed) information will be logged.
        -
        +
        +

        12.4.3   Verbosity¶

        +
        +
        This element specifies the verbosity level of the logging information. +The higher the level, the more (detailed) information will be logged.
          -
        • Full path: //OpenSplice/RnRService/Tracing/Verbosity
        • +
        • Full path: /RnRService/Tracing/Verbosity
        • Format: enumeration
        • Default value: INFO
        • Valid values: SEVERE, WARNING, INFO, CONFIG, FINE, FINER, FINEST, NONE
        • Occurrences min-max: 0-1
        -
        -

        12.4.4   EnableCategory¶

        -
        -
        This option allows to enable specific logging categories independently of the
        -

        categories selected by specifiying a verbosity level. +

        +

        12.4.4   EnableCategory¶

        +
        +

        This option allows to enable specific logging categories independently of the +categories selected by specifiying a verbosity level. Multiple categories, seperated by a comma, can be supplied. The following categories are available:

        -
        +
        -
        -
        -
          -
        • Full path: //OpenSplice/RnRService/Tracing/EnableCategory
        • -
        • Format: string
        • -
        • Occurrences min-max: 0-1
        • -
        -
        -
        -
        -
        -

        13   Agent¶

        -

        The root element of a Control and Monitoring Agent configuration.

        -
          -
        • Full path: //OpenSplice/Agent
        • -
        • Occurrences min-max: 0-1
        • -
        • Required attributes: name
        • -
        -
        -

        13.1   name¶

        -

        This attribute identifies the configuration for the Control and Monitoring Agent. Multiple service configurations can be specified in one single XML file. The actual applicable configuration is determined by the value of the name attribute, which must match the string specified in the element OpenSplice/Domain/Service[@name] in the Domain Service configuration.

        -
          -
        • Full path: //OpenSplice/Agent[@name]
        • -
        • Format: string
        • -
        • Default value: cmagent
        • -
        • Required: true
        • -
        -
        -
        -

        13.2   Tracing¶

        -

        The Tracing element controls the amount and type of information that is written into the tracing log by the Control and Monitoring Agent service. This is useful to track the service during application development.

        -
          -
        • Full path: //OpenSplice/Agent/Tracing
        • -
        • Occurrences min-max: 0-1
        • -
        • Child elements: EnableCategory, Verbosity, OutputFile, AppendToFile
        • -
        -
        -

        13.2.1   EnableCategory¶

        -

        This element enables individual logging categories. These are enabled in addition to those enabled by Tracing/Verbosity. Recognised categories are:- fatal: all fatal errors, errors causing immediate termination- error: failures probably impacting correctness but not necessarily causing immediate termination- warning: abnormal situations that will likely not impact correctness- config: full dump of the configuration- info: general informational notices -In addition, there is the keyword trace that enables all categories

        -
          -
        • Full path: //OpenSplice/Agent/Tracing/EnableCategory
        • -
        • Format: string
        • -
        • Occurrences min-max: 0-1
        • -
        -
        -
        -

        13.2.2   Verbosity¶

        -

        This element enables standard groups of categories, based on a desired verbosity level. This is in addition to the categories enabled by the Tracing/EnableCategory setting. Recognised verbosity levels and the categories they map to are:- none: no Control and Monitoring Agent log- severe: error and fatal- warning: severe + warning- info: warning + general information messages- config: info + config- fine: equivalent to config- finest: fine + trace -While none prevents any message from being written to a Control and Monitoring Agent log file, warnings and errors are still logged in the ospl-info.log and ospl-error.log files.

        -
          -
        • Full path: //OpenSplice/Agent/Tracing/Verbosity
        • -
        • Format: enumeration
        • -
        • Default value: none
        • -
        • Valid values: finest, finer, fine, config, info, warning, severe, none
        • -
        • Occurrences min-max: 0-1
        • -
        -
        -
        -

        13.2.3   OutputFile¶

        -

        This option specifies where the logging is printed to. Note that stdout and stderr are treated as special values, representing “standard out” and “standard error” respectively. No file is created unless logging categories are enabled using the Tracing/Verbosity or Tracing/EnabledCategory settings.

        +

      -
    • Full path: //OpenSplice/Agent/Tracing/OutputFile
    • +
    • Full path: /RnRService/Tracing/EnableCategory
    • Format: string
    • -
    • Dimension: file path
    • -
    • Default value: cmagent.log
    • -
    • Occurrences min-max: 0-1
    • -
    -
    -
    -

    13.2.4   AppendToFile¶

    -

    This option specifies whether the output is to be appended to an existing log file. The default is to create a new log file each time, which is generally the best option if a detailed log is generated.

    -
      -
    • Full path: //OpenSplice/Agent/Tracing/AppendToFile
    • -
    • Format: boolean
    • -
    • Default value: false
    • -
    • Occurrences min-max: 0-1
    • -
    -
    -
    -
    -

    13.3   Watchdog¶

    -

    This element specifies the type of OS scheduling class will be used by the thread that announces its liveliness periodically.

    -
      -
    • Full path: //OpenSplice/Agent/Watchdog
    • -
    • Occurrences min-max: 0-1
    • -
    -
    -

    13.3.1   Scheduling¶

    -

    This element specifies the type of OS scheduling class will be used by the thread that announces its liveliness periodically.

    -
      -
    • Full path: //OpenSplice/Agent/Watchdog/Scheduling
    • -
    • Occurrences min-max: 0-1
    • -
    • Child elements: Class, Priority
    • -
    -
    -

    13.3.1.1   Class¶

    -

    This element specifies the thread scheduling class that will be used by the watchdog thread. The user may need the appropriate privileges from the underlying operating system to be able to assign some of the privileged scheduling classes.

    -
      -
    • Full path: //OpenSplice/Agent/Watchdog/Scheduling/Class
    • -
    • Format: enumeration
    • -
    • Default value: default
    • -
    • Valid values: realtime, timeshare, default
    • -
    • Occurrences min-max: 0-1
    • -
    -
    -
    -

    13.3.1.2   Priority¶

    -

    This element specifies the thread priority. Only priorities that are supported by the underlying operating system can be assigned to this element. The user may need special privileges from the underlying operating system to be able to assign some of the privileged priorities.

    -
      -
    • Full path: //OpenSplice/Agent/Watchdog/Scheduling/Priority
    • -
    • Format: integer
    • -
    • Default value: 0
    • Occurrences min-max: 0-1
    • -
    • Required attributes: priority_kind
    • -
    -
    -
    13.3.1.2.1   priority_kind¶
    -

    This attribute specifies whether the specified Priority is a relative or absolute priority.

    -
      -
    • Full path: //OpenSplice/Agent/Watchdog/Scheduling/Priority[@priority_kind]
    • -
    • Format: enumeration
    • -
    • Default value: relative
    • -
    • Valid values: relative, absolute
    • -
    • Required: true
    -
    -
    @@ -14103,253 +12602,213 @@

    Table Of Contents

  • 3.6   ServiceTerminatePeriod
  • 3.7   SingleProcess
  • -
  • 3.8   Description
  • -
  • 3.9   CPUAffinity
  • -
  • 3.10   InProcessExceptionHandling
  • -
  • 3.11   Daemon
  • - \ No newline at end of file + diff --git a/docs/html/ConfGuide/index.html b/docs/html/ConfGuide/index.html index f52929496..29d0fd730 100644 --- a/docs/html/ConfGuide/index.html +++ b/docs/html/ConfGuide/index.html @@ -75,253 +75,213 @@

    Vortex OpenSplice Configuration Guide3.6   ServiceTerminatePeriod
  • 3.7   SingleProcess
  • -
  • 3.8   Description
  • -
  • 3.9   CPUAffinity
  • -
  • 3.10   InProcessExceptionHandling
  • -
  • 3.11   Daemon
  • \ No newline at end of file diff --git a/docs/html/ConfGuide/intro.html b/docs/html/ConfGuide/intro.html index 7c4db6335..40ebd705e 100644 --- a/docs/html/ConfGuide/intro.html +++ b/docs/html/ConfGuide/intro.html @@ -50,7 +50,7 @@

    Navigation

    -

    Introduction¶

    +

    Introduction¶

    This guide describes the various configuration elements and attributes available for Vortex OpenSplice. The configuration items should be added to an XML file and then the OSPL_URI environment variable should be set to point to the @@ -105,7 +105,7 @@

    Navigation

    <Operational>0.1</Operational> </RequestCombinePeriod> </Alignment> - <WaitForAttachment maxWaitCount="100"> + <WaitForAttachment maxWaitCount="10"> <ServiceName>ddsi2</ServiceName> </WaitForAttachment> </Network> @@ -222,7 +222,7 @@

    Navigation

    \ No newline at end of file diff --git a/docs/html/ConfGuide/objects.inv b/docs/html/ConfGuide/objects.inv index 2fd5477d2..e12de4744 100644 Binary files a/docs/html/ConfGuide/objects.inv and b/docs/html/ConfGuide/objects.inv differ diff --git a/docs/html/ConfGuide/search.html b/docs/html/ConfGuide/search.html index 09d5b5f3f..955b6df6c 100644 --- a/docs/html/ConfGuide/search.html +++ b/docs/html/ConfGuide/search.html @@ -95,7 +95,7 @@

    Navigation

    \ No newline at end of file diff --git a/docs/html/ConfGuide/searchindex.js b/docs/html/ConfGuide/searchindex.js index 6a971e053..2b9c77d4b 100644 --- a/docs/html/ConfGuide/searchindex.js +++ b/docs/html/ConfGuide/searchindex.js @@ -1 +1 @@ -Search.setIndex({envversion:42,terms:{entropi:2,communict:2,child:[1,2],prefix:[1,2],sleep:2,disappear:2,whose:2,"const":2,emptiv:2,swap:2,under:2,spec:2,digit:2,everi:2,"void":2,voic:2,govern:2,affect:2,vast:2,disturb:2,verif:2,mvme5100:2,initialis:2,x86_64:2,properti:2,"10m":2,seper:2,direct:2,histor:2,consequ:2,second:2,aggreg:2,even:2,hide:2,muex:2,neg:2,"new":[1,2],topolog:2,ongo:2,never:2,durabilitypartit:2,here:2,achannel:2,path:[1,2],interpret:2,anymor:2,coredx:1,unix:2,"0x80000000":2,total:2,unit:2,highli:2,describ:[1,2],would:[1,2],leaki:2,overhead:2,recommend:2,until:2,relat:2,notic:2,warn:[1,2],exce:2,compatbl:2,loss:2,hold:2,overrul:2,must:[1,2],join:2,restor:2,elegantli:2,work:2,root:2,overrid:2,give:2,indic:2,caution:2,unavail:2,want:[1,2],unsign:2,plist:2,end:2,quot:2,partitionexpress:2,how:[1,2],recoveri:2,answer:2,verifi:2,config:2,updat:2,recogn:2,x509:2,after:2,befor:2,ff02:2,lax:[1,2],attempt:2,third:2,grant:2,maintain:2,environ:[1,2],incorpor:2,enter:2,exclus:2,mechan:2,order:2,over:2,fall:2,becaus:2,privileg:2,flexibl:2,distibut:2,unforeseen:2,fix:2,better:2,them:2,thei:[1,2],fragment:2,safe:2,overestim:2,choic:2,timeout:2,each:[1,2],debug:2,side:2,mean:2,resum:2,locking_mod:2,collector:2,twinoak:1,newli:2,smp:2,rewrit:2,adapt:2,reader:2,navig:1,written:2,situat:2,infin:2,free:2,ineffici:2,egabyt:2,md5:2,reconfigur:2,spdp:2,renew:2,onto:2,"__built_in_partition__":2,"10k":2,independ:2,system:2,restrict:2,instruct:2,alreadi:2,primari:2,top:2,sometim:2,downsid:2,wal_autocheckpoint:2,master:2,too:2,power5:2,outag:2,tool:2,compressor:2,sha1:2,somewhat:2,technic:2,symptom:2,target:2,keyword:2,provid:2,ospl_sp_ddsi:1,pstore:2,project:2,matter:2,transient_loc:2,ran:2,modern:2,unicast:2,manner:2,seen:2,deamon:2,incompat:2,minu:2,strength:2,latter:2,currenli:2,contact:2,transmit:2,though:2,object:2,phase:2,acknack:2,broadcast:2,don:2,maimum:2,flow:2,doe:2,declar:2,wildcard:2,left:2,infuenc:2,dot:2,rediscoveri:2,opposit:2,random:2,syntax:2,protocol:2,involv:2,layout:2,acquir:2,explain:2,latenc:2,stop:2,"public":2,twice:2,respond:2,mandatori:2,result:[1,2],respons:2,corrupt:2,themselv:2,best:2,subject:2,awar:2,wait_for_acknowledg:2,approach:2,attribut:[1,2],inabl:2,accord:2,omg:2,extend:2,extens:2,lazi:2,extent:2,toler:2,advertis:2,tcpip:2,protect:2,fault:2,howev:2,against:2,logic:2,uni:2,com:2,ld_library_path:2,serversid:2,pre:2,assur:2,can:[1,2],trust:2,assum:2,duplic:2,three:[1,2],been:2,advert:2,accumul:2,much:2,interest:2,basic:2,suppress:2,ani:2,pf_memsiz:2,"catch":2,launcher:2,zlib:2,commerci:2,calcul:2,spawn:2,rediscov:2,need:2,smoothest:2,sever:2,perform:2,make:2,transpar:2,split:2,ddsi2e:[1,2],complet:2,nic:2,kib:2,tune:2,kept:2,thu:2,inherit:2,"0x100000":2,thi:[1,2],everyth:2,unchang:2,"1hr":2,identifi:2,just:2,domainparticip:2,bandwidth:2,human:2,participantmessagedata:2,yet:2,previous:2,easi:2,defrag:2,had:2,save:2,ospl_hom:1,preserv:2,background:2,rnr:2,shadow:2,measur:2,specif:2,arbitrari:2,keyhash:2,tcp_nodelai:2,specifii:2,underli:2,www:2,right:2,old:2,deal:2,deaf:2,maxim:2,dead:2,ospl_comp_lzf_init:2,successfulli:2,"0x40000000":2,transmiss:2,insensit:2,cooper:2,bottom:2,deploy:[1,2],datawrit:2,buffer:2,cmsoap:[1,2],middlewar:2,condit:2,plu:2,uncompress:2,systemhalt:2,plug:2,slightli:2,hearbeat:2,commit:2,produc:2,unrespons:2,"0xa00000":2,"float":2,contriv:2,bound:2,down:2,eth0:2,durabilitysubscrib:2,accordingli:2,wai:[1,2],nodal:2,support:2,avail:[1,2],reli:2,gib:2,fraction:2,call:[1,2],analysi:2,head:1,form:2,offer:2,qwave:2,heap:2,renam:2,"true":[1,2],maximum:2,mtu:2,emit:2,linux2:2,featur:2,semicolon:2,exist:2,trip:2,assembl:2,encrypt:2,when:[1,2],aes128:2,shrink:2,ilobyt:2,node:2,intend:2,os_int32:2,consid:2,sql:2,longer:2,packets:2,ignor:2,time:[1,2],push:2,backward:2,radmin:2,concept:2,skip:2,global:2,signific:2,inaddr_ani:2,millisecond:2,decid:2,depend:2,decim:2,readabl:2,downtim:2,sourc:2,string:2,realibl:2,feasibl:2,word:2,exact:2,administr:2,level:2,iter:2,item:[1,2],unsupport:2,quick:2,round:2,prevent:2,nwbridg:2,compens:2,sign:2,cost:2,appear:1,unsort:2,current:2,outliv:2,ampersand:2,portnumb:2,deriv:2,water:2,slow:2,modif:2,splice:2,along:[1,2],wait:2,not_alive_dispos:2,checksum:2,queue:2,multicast:2,throughput:2,behav:2,overriden:2,extrem:2,reclaim:2,elect:2,extra:2,modul:2,prefer:2,visibl:2,instal:2,memori:2,live:2,afford:2,claus:2,finit:2,refrain:2,"00x40000000":2,accept:2,reallocat:2,fly:2,prepar:2,uniqu:2,imper:2,whatev:2,"0x800000":2,purpos:2,nearest:2,underestim:2,predict:2,clockget:2,critic:2,application1:2,occur:[1,2],alwai:2,differenti:2,multipl:2,ping:2,write:2,till:2,product:2,sp2:2,mac:2,mai:[1,2],data:2,"0x10000":2,"2mb":2,practic:2,explicit:2,transport_priorr:2,inform:2,"switch":2,preced:2,combin:2,unequivoc:2,anticip:2,brain:2,ttl:2,still:2,pointer:2,dynam:2,entiti:2,conjunct:2,disconnect:2,monitor:2,platform:2,window:[1,2],main:2,confin:2,non:2,halt:2,encod:2,therebi:2,now:2,nor:2,introduct:0,term:2,perspect:2,drop:2,revert:2,separ:2,replai:2,arg1:2,individu:2,receipt:2,continu:2,"00xa0000000":2,year:2,happen:2,dispos:2,subnet:2,"100m":2,space:2,profil:2,internet:2,correct:2,earlier:2,argv:2,org:2,"byte":2,argc:2,card:2,care:2,suffici:2,frequenc:2,modest:2,refus:2,recov:2,turn:2,place:2,imposs:2,first:[1,2],origin:2,suspend:2,directli:2,carri:2,onc:2,fast:2,open:2,predefin:2,given:2,silent:2,workaround:2,necessarili:2,tell:2,waitset:2,conveni:2,especi:2,copi:2,specifi:2,blacklist:2,pragma:2,than:2,serv:2,wide:2,balanc:2,were:2,posit:2,dsstodbm:2,enabledcategori:2,lowest:2,sai:1,diffserv:2,anywher:2,deliv:2,recover:2,processnam:2,destroi:2,moreov:2,note:[1,2],ideal:2,take:2,advis:2,noth:2,sure:2,normal:2,multipli:2,snetwork:2,fragent:2,pair:2,synonym:2,later:2,drive:2,disableusertosset:2,runtim:2,ospl_comp_snappy_init:2,ddsi:[1,2],serialis:2,unprocess:2,concurr:2,xml:[1,2],onli:[1,2],explicitli:2,activ:2,behind:2,black:2,analyz:2,dword:2,nearli:2,variou:[1,2],get:2,secondari:2,ssm:2,cannot:2,requir:[1,2],dramat:2,where:2,kernel:2,burst:2,dbmsconnect:2,concern:2,infinit:2,detect:2,enumer:2,label:2,enough:2,volatil:2,between:2,"import":2,across:2,parent:[1,2],cycl:2,sparc:2,come:2,inconsist:2,mani:[1,2],among:2,undocu:2,"0x200000":2,period:2,runawai:2,colon:2,poll:2,ultim:2,"00x20000000":2,mark:2,bypass:2,thousand:2,wake:2,"1mb":2,those:2,"case":2,blowfish:[1,2],interoper:[1,2],pedant:2,cast:2,invok:2,margin:2,stdout:2,henc:2,topicqo:2,destin:2,cluster:2,develop:2,author:2,same:[1,2],check:2,html:2,circularli:2,document:2,mbyte:2,nest:1,confidenti:2,decompress:2,driven:2,capabl:2,improv:2,extern:2,postpon:2,retransmiss:2,appropri:2,choos:2,without:2,model:2,execut:2,excel:2,rest:2,kill:2,aspect:2,speed:2,death:2,struct:2,except:2,littl:2,versa:2,real:2,around:2,max_open_fil:2,read:2,categoris:2,traffic:2,mergepolici:2,topicexpress:2,realtim:2,integ:2,unlimit:2,benefit:2,"0x20000000":2,either:2,cascad:2,output:2,inter:2,manag:2,fulfil:2,cabl:2,loopback:2,keystor:2,definit:2,achiev:2,legal:2,evolv:2,corespond:2,apostroph:2,freed:2,os_tim:2,power:2,garbag:2,inspect:2,found:2,ack:2,stand:1,ospl:[1,2],act:2,backup:2,effici:2,liveli:2,unregist:2,your:[1,2],log:2,area:2,overwrit:2,start:2,compliant:2,interfac:2,low:2,strictli:2,conclud:2,regard:2,amongst:2,faster:2,notat:2,possibl:2,bucket:2,unusu:2,embed:2,deadlock:2,loadabl:2,creat:2,certain:2,strongli:2,catchup:2,decreas:2,file:[1,2],intra:2,fill:2,incorrect:2,again:2,googl:2,event:2,tight:2,valid:[1,2],you:[1,2],architectur:2,sequenc:2,symbol:2,signficantli:2,track:2,pool:2,reduc:2,assert:2,globalprofil:1,directori:2,mask:2,pseudo:2,mimic:2,potenti:2,escap:2,degrad:2,cpu:2,represent:2,all:2,forget:2,forbidden:2,standardis:2,improperli:2,disc:2,abil:2,follow:[1,2],disk:2,children:1,garbagag:2,reportinterv:2,init:2,program:2,os_int64:2,introduc:2,replic:2,fals:[1,2],durabiltii:2,worst:2,failur:2,veri:2,list:[1,2],helloworld:2,adjust:2,stderr:2,small:2,joiner:2,dimens:2,enterpris:2,ten:2,journal_mod:2,rate:2,pressur:2,design:2,pass:2,further:2,opensplicedd:2,tev:2,what:2,clock:2,section:2,ffff:2,delet:2,version:2,consecut:2,method:2,full:2,hash:2,behaviour:2,solari:2,excess:2,standard:[1,2],modifi:2,valu:[1,2],search:2,sender:2,verify_checksum:2,prior:2,amount:2,action:2,via:2,api_info:2,transit:2,paranoid_check:2,libhelloworld:2,deprec:2,establish:2,service_cleanup_delai:2,select:2,aggress:2,hexadecim:2,clockstart:2,regist:2,two:2,taken:2,asecurityprofil:2,toggl:2,more:2,reachabl:2,desir:2,flag:2,particular:2,known:2,none:2,endpoint:2,histori:2,opensplicev6:2,remain:2,hkey_local_machin:2,ficiti:2,scan:2,registr:2,share:2,templat:2,minimum:2,unreli:2,phrase:2,cours:2,divid:2,rather:2,anoth:[1,2],reject:2,resourc:2,referenc:2,associ:2,circumst:2,"short":2,postfix:2,caus:2,so_dontrout:2,help:2,soon:2,held:2,through:2,paramet:2,write_buffer_s:2,late:2,reschedul:2,exchang:2,might:2,finer:2,good:2,"return":2,lite:2,easili:2,iff:2,reactiv:2,compris:2,fulli:2,errata:2,truncat:2,hard:2,expect:2,http:2,beyond:2,reduct:2,safeti:2,payload:2,abl:2,health:2,readwrit:2,print:2,occurr:2,proxi:2,reason:2,mmf:2,recv:2,asm:2,basi:2,omit:2,perman:2,lifetim:2,assign:2,major:2,notifi:2,upper:2,nack:2,number:[1,2],placehold:2,done:2,blank:2,stabl:2,miss:2,differ:2,interact:2,networkingbridg:2,least:2,rbuf_siz:2,scheme:2,store:2,adher:2,option:[1,2],part:2,consult:2,grace:2,albeit:2,kind:2,whenev:2,remot:2,remov:2,executbal:2,reus:2,block_siz:2,consumpt:2,comput:2,c_base:2,expir:2,partitit:2,"null":2,built:2,zero:2,self:2,also:2,build:2,distribut:2,previou:2,reach:2,react:2,most:2,clear:2,cover:2,articip:2,abnorm:2,exp:2,usual:2,carefulli:2,rti:2,session:2,cdr:2,fine:2,find:[1,2],impact:2,colloc:2,firewal:2,writer:2,solut:2,queu:2,factor:2,express:2,resent:2,sill:2,restart:2,resend:2,cyclic:2,crc:2,common:2,wrote:2,certif:2,set:[1,2],dump:2,startup:2,see:[1,2],reserv:2,maxint:2,simultan:2,someth:2,particip:2,won:2,mutex:2,altern:2,signatur:2,numer:2,induc:2,defaultnamespac:[1,2],succeed:2,solv:2,pcap:2,both:2,last:2,fragement:2,context:2,forgotten:2,whole:2,load:2,point:[1,2],instanti:2,header:2,dds_userclock_t:2,shutdown:2,suppli:[1,2],bridg:2,backend:2,chanenl:2,stamp:2,loggin:2,devic:2,due:2,empti:2,secret:2,strategi:2,wish:2,fire:2,great:2,gap:2,partli:2,look:2,contentfilteredtop:2,budget:2,durat:2,ramif:2,"while":2,match:2,behavior:2,error:2,loos:2,pack:2,subsect:2,earli:2,aix5:2,readi:2,itself:2,seem:2,leveldb:2,minim:2,belong:2,nanosecond:2,shorter:2,sqlite3:2,conflict:2,higher:2,x86:2,optim:2,wherea:2,moment:2,temporari:2,user:2,typic:2,recent:2,lower:2,task:2,equival:2,discourag:2,older:2,expens:2,"0x240000":2,salvo:2,amp:2,regardless:2,mandat:2,snappi:2,unsecur:2,subsequ:2,format:[1,2],big:2,bit:2,characterist:2,formal:2,lost:2,resolv:2,collect:2,"boolean":2,encount:2,often:2,acknowledg:2,creation:2,some:[1,2],back:2,sampl:2,mirror:2,syndrom:2,scale:2,shall:2,per:2,pem:2,retri:2,larg:2,recognis:2,machin:2,run:2,my_top:2,from:2,impos:2,constraint:2,idl:2,"00x0":2,"1gb":2,block:2,repair:2,primarili:2,within:[1,2],drain:2,addtion:2,uf_mems:2,ensur:2,chang:2,announc:2,occupi:2,inclus:2,fledg:2,question:2,"long":2,custom:2,forward:2,properli:2,link:2,translat:2,line:2,info:2,consist:2,caller:2,transmitt:2,priveleg:2,highlight:2,similar:2,constant:2,dds_wait_for_historical_data:2,chan:2,doesn:2,repres:2,"char":2,incomplet:2,spontan:2,sequenti:2,invalid:2,application:2,priori:2,nat:2,clean:2,adminqueu:2,vice:2,dataread:2,notion:2,tradeoff:2,depth:2,far:2,fresh:2,pluggabl:2,code:2,durabilitypublish:2,effort:2,granular:2,outgo:2,aris:2,fatal:2,sent:2,"00x60000000":2,keep_last:2,volum:2,untouch:2,implicitli:2,relev:2,tri:2,"try":2,create_particip:2,refer:2,pleas:2,malici:2,impli:2,smaller:2,visualis:2,"0x0":2,video:2,odd:2,index:2,compar:2,access:2,absoff:2,experiment:2,deduc:2,wireshark:2,penalti:2,let:2,becom:2,sinc:2,convert:2,conceiv:2,larger:2,nameless:2,chanc:2,appli:2,approxim:2,xmit:2,api:2,apo:2,reallow:2,metaphor:2,commun:2,doubl:2,next:2,igabty:2,sort:2,mismatch:2,"transient":2,ospl_comp_zlib_init:2,actual:2,unacknowledg:2,retriev:2,scalabl:2,cumbersom:2,unopen:2,obvious:2,meet:2,unread:2,aliv:2,control:2,sqlite:2,malform:2,process:[1,2],high:2,tag:[1,2],daemom:2,weaken:2,delai:2,aes256:2,instead:2,domainservic:2,networkinginterfaceaddress:2,redund:2,physic:2,alloc:2,essenti:2,counter:2,correspond:2,element:[1,2],issu:2,mute:2,ospl_uri:[1,2],move:2,comma:2,currentcontrolset:2,chosen:2,therefor:2,crash:2,greater:2,nullprofil:2,handl:2,auto:[1,2],overal:2,dai:2,"0x280000":2,dat:2,clockstop:2,facilit:2,lzf:2,anyth:2,edit:2,mode:2,subset:2,meta:2,"static":2,special:2,out:2,variabl:[1,2],influenc:2,suitabl:2,rel:2,hardwar:2,shut:2,insid:1,releas:[1,2],afterward:2,complianc:2,unwant:2,could:2,keep:2,length:2,outsid:2,retain:2,softwar:2,finest:2,suffix:2,qualiti:2,date:2,owner:2,facil:2,strict:2,capac:2,messag:2,attach:2,attack:2,termin:2,ipv4:2,udp:2,defeault:2,rsa:2,exactli:2,prune:2,charact:2,sens:2,stricter:2,unencrypt:2,fail:2,have:2,aes192:2,close:2,optimis:2,rout:2,mib:2,mix:2,builtin:2,which:[1,2],soap:2,singl:[1,2],unless:2,whc:2,mimick:2,discov:2,useful:2,deploi:2,segment:2,request:2,uri:[1,2],durabilitykind:2,determin:2,fact:2,dbm:2,text:2,anywai:2,locat:2,should:[1,2],prolong:2,smallest:2,"1abc":2,local:2,meant:2,regularli:2,increas:2,integr:2,contain:[1,2],tuner:2,alignmentkind:2,view:2,conform:2,knowledg:2,packet:2,elast:2,"0hz":2,stack:2,closer:2,asynchron:2,statu:2,wire:2,throttletreshold:2,correctli:2,pattern:2,boundari:2,thumb:2,unregistr:2,dll:2,state:[1,2],progress:2,neither:2,entir:2,addit:2,plugin:2,equal:2,etc:[1,2],instanc:2,instert:2,comment:2,threadnam:2,arriv:2,distinguish:2,vxwork:2,respect:2,quit:2,treat:2,immedi:2,presenc:2,bulk:2,togeth:2,present:[1,2],cmagent:2,defin:2,wild:2,deliveri:2,observ:2,alon:1,incom:2,revis:2,so_reuseaddr:2,reviv:2,parti:2,satisfi:2,on_request:2,member:2,schizophren:2,largest:2,wakeup:2,slave:2,hostnam:2,upon:2,effect:2,logfil:2,expand:2,off:2,well:2,thought:2,exampl:[1,2],filesystem:2,undefin:2,audio:2,latest:2,sporad:2,less:2,defaultrol:2,timeshar:2,heavili:2,prepend:2,web:2,field:2,priorit:2,add:[1,2],cleanup:2,adh:2,arguabl:2,wait_for_historical_data:2,realiz:2,know:2,password:2,insert:2,resid:2,like:2,success:2,"00x140000000":2,"4mb":2,necessari:[1,2],lose:2,page:2,exceed:2,didn:2,retransmit:2,specfi:2,linux:[1,2],"export":1,flush:2,proper:2,home:2,transport:2,tmp:2,throughout:2,leaf:2,feder:2,lead:2,leak:2,avoid:2,overlap:2,estim:2,leav:2,fill_cach:2,usag:2,noisi:2,host:2,although:2,dcp:2,about:2,rare:2,socket:2,linger:2,datagram:2,lifecycl:2,discard:2,certainti:2,disabl:2,own:2,automat:2,dataset:2,mere:2,leverag:2,trigger:2,replac:2,arg2:2,"function":2,unexpect:2,advers:2,powerpc604:2,gain:2,overflow:2,highest:2,count:2,succe:2,made:2,whether:2,shrunk:2,smooth:2,displai:2,troubl:2,straightawai:2,record:2,below:2,limit:2,otherwis:2,problem:2,evalu:2,"int":2,dure:2,meaningless:2,replica:2,implement:2,inf:2,ing:2,probabl:2,tick:2,boot:2,detail:2,virtual:2,other:2,futur:2,varieti:2,ddsi2:[1,2],stai:2,rule:2,portion:2,auxiliari:2},objtypes:{},objnames:{},filenames:["index","intro","guide"],titles:["Vortex OpenSplice Configuration Guide","Introduction","2   OpenSplice"],objects:{},titleterms:{queri:2,systemid:2,force_key_equ:2,whchigh:2,storemod:2,priorityinherit:2,categori:2,retransmitmergingperiod:2,xmitlossi:2,leas:2,send:2,transport_prior:2,outputfil:2,assumemulticastcap:2,delayedalign:2,entropyfil:2,enablecategori:2,maxbursts:2,measurehbtoacklat:2,primaryreordermaxsampl:2,probelist:2,certificateverif:2,leasemanag:2,trustedcertif:2,port:2,append:2,compat:2,compressionbuffers:2,endpointsinsystem:2,partitionaccess:2,userclockstop:2,gener:2,startupmodedur:2,partition_express:2,address:2,alignerschedul:2,failureact:2,serviceterminateperiod:2,cert:2,base:2,whcadapt:2,databandwidthlimit:2,throttlethreshold:2,filenam:2,retryonrejectbesteffort:2,receivebufferchunks:2,retentionperiod:2,usr:2,typedreport:2,scope:2,type:2,rnrservic:2,verifycli:2,legacyfragment:2,cach:2,latency_budget:2,lock:2,dbmsconnectservic:2,agent:2,topic:2,ddsi2directmaxthread:2,aligneeschedul:2,manysocketsmod:2,auxiliarybandwidthlimit:2,resourcelimit:2,secur:2,enablemulticastloopback:2,maxqueuedrexmitmessag:2,threadpool:2,respondtortiinitzeroackwithinvalidheartbeat:2,map:2,max:2,catalog:2,diffservfield:2,bind:2,credenti:2,exclud:2,allow:2,reconnect:2,deathdetectioncount:2,portnr:2,group:2,maxsamplesperinst:2,polici:2,logstacktrac:2,nodelai:2,rr_storageattrxml:2,persist:2,requestcombineperiod:2,leasedur:2,durablepolici:2,maxfiles:2,userclockstart:2,timestamp:2,initi:2,globalpartit:2,maxsamples:2,minimumsocketsendbuffers:2,spdpmulticastaddress:2,priority_kind:2,introduct:1,maxsampl:2,name:2,rediscoveryblacklistdur:2,odbc:2,aligne:2,domain:2,packetcapturefil:2,access_mod:2,connect:2,multicasttimetol:2,suppressdefaultlog:2,network:2,externalnetworkaddress:2,publish:2,replication_us:2,multicastdataoffset:2,durabl:2,file_nam:2,appendtofil:2,mirrorremoteent:2,watermark:2,publish_initial_data:2,deafmut:2,y2038readi:2,defragbuffers:2,legacycompress:2,allowmulticast:2,assumertihaspmdendpoint:2,thread:2,synchron:2,filter:2,enforc:2,heartbeat:2,selfsignedcertif:2,networkinterfaceaddress:2,oper:2,rang:2,durabilityservic:2,maxparticip:2,generatebuiltintop:2,preemptiveackdelai:2,size:2,prioriti:2,networkservic:2,lateackmod:2,construct:2,unicastmetaoffset:2,"final":2,schema:2,namespac:2,usemulticastifmreqn:2,snetworkservic:2,userentropi:2,warnat:2,networkqueues:2,reliabilityrecoveryperiod:2,externalnetworkmask:2,listen:2,crccheck:2,argument:2,acknacknumbitsemptyset:2,tabl:2,deliveryqueuemaxsampl:2,accesscontrol:2,spdpinterv:2,squashparticip:2,min:2,queuesiz:2,standardsconform:2,event_table_polici:2,x509authent:2,userclockqueri:2,useipv6:2,trace:2,compress:2,trigger_polici:2,networkingbridgeservic:2,"class":2,synchronousdeliveryprioritythreshold:2,topic_express:2,garbagecollector:2,destruct:2,unicastdataoffset:2,replication_mod:2,partitiontop:2,mainloop:2,verbos:2,shmmonitor:2,forwardremotedata:2,threshold:2,keyvaluestor:2,absolut:2,configur:[0,2],minimumsocketreceivebuffers:2,suppressspdpmulticast:2,salvos:2,keystorefil:2,dcpspartitiontop:2,compressionthreshold:2,maxmessages:2,ssl:2,report:2,retryonrejectdur:2,securityprofil:2,multicastrecvnetworkinterfaceaddress:2,smpcount:2,enabl:2,statist:2,partit:2,safetyfactor:2,heapsiz:2,servic:2,threadmax:2,databas:2,defaultmulticastaddress:2,networkpartit:2,discoveri:2,plugininitfunct:2,localdiscoverypartit:2,clientdur:2,dsn:2,timetowaitforalign:2,maxinst:2,kei:2,transportprior:2,dbmstodd:2,entitynam:2,tunerservic:2,advertisebuiltintopicwrit:2,initialdiscoveryperiod:2,storesessiontim:2,defragunreliablemaxsampl:2,stacksiz:2,aggressivekeeplastwhc:2,retransmitmerg:2,ignoredpartit:2,schedul:2,maxwaitcount:2,symbol_nam:2,acceleraterexmitblocks:2,guid:0,update_frequ:2,maxclient:2,smpoptim:2,storeoptimizeinterv:2,subscrib:2,ddsi2eservic:2,partitionmap:2,waitforattach:2,resolut:2,secondaryreordermaxsampl:2,inprocessexceptionhandl:2,align:2,builtintop:2,dontrout:2,domainid:2,forwardallmessag:2,ddsi2servic:2,whclow:2,multicastmetaoffset:2,receiv:2,whchighinit:2,singleprocess:2,startupmodecoverstransi:2,maxautoparticipantindex:2,spdpresponsemaxdelai:2,ddstodbm:2,entri:2,client:2,command:2,generatekeyhash:2,allowedport:2,storageparamet:2,obtain:2,tcp:2,pluginlibrari:2,explicitlypublishqossettodefault:2,update_factor:2,participantgain:2,servicenam:2,resendmanag:2,applic:2,writerlingerdur:2,maxretri:2,storesleeptim:2,maxthreadspercli:2,daemon:2,participantindex:2,userclockmodul:2,deadlockdetect:2,memorypools:2,server:2,synchronousdeliverylatencybound:2,channel:2,unicastresponsetospdpmessag:2,backlog:2,interv:2,intern:2,authent:2,librari:2,throttlelimit:2,recoveryfactor:2,vortex:0,accesscontrolmodul:2,allowreus:2,topicaccess:2,generalwatchdog:2,fragments:2,content:2,monitorport:2,throttl:2,scheduletimeround:2,cpuaffin:2,packetretentionperiod:2,pluginparamet:2,peer:2,storedirectori:2,rr_storageattrcdr:2,prioritizeretransmit:2,cipher:2,writetimeout:2,timealign:2,reportplugin:2,opensplic:[0,2],publish_interv:2,watchdog:2,storag:2,controltop:2,merg:2,coexistwithnativenetwork:2,nackdelai:2,receivebuffers:2,keypassphras:2,includ:2,ipv6:2,forc:2,pwd:2,readtimeout:2,reset:2,"default":2,memorymappedfilestor:2,builtinendpointset:2,adminqueues:2,responsivenesstimeout:2,conservativebuiltinreaderstartup:2,alignment_prior:2,kernelmanag:2,role:2,maxreliabbacklog:2,test:2,maxqueuedrexmitbyt:2,arrivalofdataassertsppandepliveli:2,leaseperiod:2,expirytim:2,userclock:2,defragreliablemaxsampl:2,algorithm:2,localendpoint:2,reliabl:2,cipherkei:2,descript:2,timetol:2,equalitycheck:2,servicesonli:2,domaingain:2}}) \ No newline at end of file +Search.setIndex({envversion:42,terms:{entropi:2,communict:2,prefix:[1,2],sleep:2,whose:2,emptiv:2,swap:2,under:2,spec:2,digit:2,everi:2,voic:2,govern:2,affect:2,vast:2,verif:2,initialis:2,properti:2,"10m":2,seper:2,direct:2,histor:2,consequ:2,second:2,aggreg:2,even:2,hide:2,muex:2,neg:2,"new":[1,2],topolog:2,ongo:2,never:2,durabilitypartit:2,here:2,achannel:2,path:[1,2],interpret:2,anymor:2,coredx:1,tremend:2,unix:2,"0x80000000":2,total:2,unit:2,highli:2,describ:[1,2],would:[1,2],leaki:2,overhead:2,recommend:2,until:2,relat:2,notic:2,warn:[1,2],exce:2,compatbl:2,hold:2,overrul:2,must:[1,2],join:2,restor:2,elegantli:2,work:2,root:2,overrid:2,give:2,indic:2,caution:2,unavail:2,want:[1,2],end:2,quot:2,partitionexpress:2,how:[1,2],sever:2,answer:2,verifi:2,config:2,updat:2,x509:2,after:2,befor:2,ff02:2,lax:[1,2],attempt:2,grant:2,maintain:2,environ:[1,2],incorpor:2,enter:2,exclus:2,worst:2,order:2,over:2,becaus:2,privileg:2,flexibl:2,directli:2,fix:2,better:2,them:2,thei:[1,2],fragment:2,safe:2,overestim:2,choic:2,timeout:2,each:[1,2],debug:2,side:2,mean:2,resum:2,collector:2,twinoak:1,newli:2,smp:2,adapt:2,reader:2,navig:1,situat:2,infin:2,free:2,standard:[1,2],egabyt:2,md5:2,reconfigur:2,spdp:2,renew:2,onto:2,attribtu:2,"__built_in_partition__":2,independ:2,capac:2,restrict:2,instruct:2,alreadi:2,primari:2,top:2,sometim:2,downsid:2,master:2,too:2,servi:2,tool:2,compressor:2,sha1:2,somewhat:2,symptom:2,target:2,keyword:2,provid:2,pstore:2,transient_loc:2,ran:2,modern:2,unicast:2,seen:2,deamon:2,incompat:2,minu:2,strength:2,latter:2,transmit:2,shall:2,object:2,phase:2,acknack:2,don:2,maimum:2,flow:2,doe:2,declar:2,wildcard:2,left:2,notion:2,dot:2,prepend:2,ffff:2,random:2,syntax:2,protocol:2,involv:2,acquir:2,explain:2,latenc:2,stop:2,"public":2,twice:2,respond:2,mandatori:2,result:[1,2],respons:2,fail:2,aes192:2,best:2,subject:2,awar:2,wait_for_acknowledg:2,approach:2,attribut:[1,2],inabl:2,accord:2,omg:2,extend:2,extens:2,lazi:2,toler:2,advertis:2,tcpip:2,protect:2,fault:2,howev:2,against:2,logic:2,ld_library_path:2,serversid:2,enabledcategori:2,assur:2,trust:2,assum:2,duplic:2,three:[1,2],been:2,accumul:2,much:2,interest:2,advers:2,suppress:2,ani:2,child:[1,2],"catch":2,zlib:2,calcul:2,spawn:2,smoothest:2,disappear:2,perform:2,make:2,format:[1,2],ddsi2e:[1,2],complet:2,nic:2,hand:2,kib:2,tune:2,thu:2,inherit:2,contact:2,thi:[1,2],everyth:2,unchang:2,identifi:2,just:2,domainparticip:2,bandwidth:2,human:2,participantmessagedata:2,yet:2,easi:2,defrag:2,had:2,ospl_hom:1,preserv:2,background:2,rnr:2,shadow:2,daemom:2,specif:2,arbitrari:2,keyhash:2,tcp_nodelai:2,specifii:2,underli:2,www:2,right:2,old:2,deal:2,maxim:2,dead:2,ospl_comp_lzf_init:2,successfulli:2,"0x40000000":2,transmiss:2,insensit:2,cooper:2,whc:2,datawrit:2,multipli:2,cmsoap:[1,2],middlewar:2,condit:2,plu:2,uncompress:2,systemhalt:2,plug:2,slightli:2,hearbeat:2,done:2,commit:2,produc:2,unequivoc:2,contriv:2,bound:2,down:2,eth0:2,durabilitysubscrib:2,wan:2,accordingli:2,suffici:2,nodal:2,support:2,avail:[1,2],reli:2,gib:2,fraction:2,call:[1,2],lowest:2,head:1,form:2,offer:2,qwave:2,ospl_comp_snappy_init:2,synonym:2,"true":[1,2],maximum:2,mtu:2,emit:2,featur:2,semicolon:2,exist:2,trip:2,assembl:2,encrypt:2,excel:2,disableusertosset:2,shrink:2,ilobyt:2,node:2,intend:2,userclock:2,consid:2,sql:2,longer:2,packets:2,ignor:2,puse:2,time:[1,2],push:2,backward:2,radmin:2,skip:2,global:2,signific:2,inaddr_ani:2,millisecond:2,decid:2,depend:2,decim:2,readabl:2,downtim:2,sourc:2,string:2,realibl:2,feasibl:2,word:2,exact:2,administr:2,level:2,item:[1,2],unsupport:2,quick:2,round:2,prevent:2,nwbridg:2,compens:2,sign:2,cost:2,appear:1,current:2,hkey_local_machin:2,ampersand:2,portnumb:2,deriv:2,water:2,explicitli:2,modif:2,splice:2,along:1,wait:2,not_alive_dispos:2,queue:2,multicast:2,throughput:2,behav:2,overriden:2,extrem:2,reclaim:2,useful:2,extra:2,modul:2,prefer:2,visibl:2,instal:2,memori:2,live:2,claus:2,finit:2,refrain:2,templat:2,effort:2,fly:2,uniqu:2,imper:2,whatev:2,purpos:2,nearest:2,underestim:2,predict:2,clockget:2,critic:2,application1:2,occur:[1,2],alwai:2,differenti:2,multipl:2,ping:2,write:2,till:2,actual:2,product:2,sp2:2,mac:2,mai:[1,2],data:2,practic:2,explicit:2,transport_priorr:2,inform:2,"switch":2,preced:2,combin:2,unrespons:2,anticip:2,ttl:2,still:2,dynam:2,entiti:2,conjunct:2,disconnect:2,monitor:2,platform:2,window:[1,2],main:2,non:2,encod:2,therebi:2,now:2,nor:2,introduct:[],drop:2,separ:2,replai:2,arg1:2,individu:2,receipt:2,continu:2,happen:2,dispos:2,subnet:2,space:2,profil:2,correct:2,earlier:2,argv:2,org:2,"byte":2,argc:2,card:2,care:2,wai:[1,2],frequenc:2,modest:2,refus:2,recov:2,turn:2,place:2,imposs:2,first:[1,2],origin:2,suspend:2,distibut:2,carri:2,onc:2,fast:2,predefin:2,given:2,workaround:2,necessarili:2,conveni:2,especi:2,copi:2,specifi:2,broadcast:2,than:2,serv:2,wide:2,balanc:2,were:2,dsstodbm:2,pre:2,analysi:2,sai:1,diffserv:2,anywher:2,deliv:2,recover:2,destroi:2,moreov:2,note:[1,2],take:2,advis:2,sure:2,track:2,snetwork:2,fragent:2,beta:2,pair:2,renam:2,later:2,drive:2,aes128:2,runtim:2,heap:2,ddsi:[1,2],serialis:2,unprocess:2,concurr:2,xml:[1,2],onli:[1,2],slow:2,activ:2,state:[1,2],analyz:2,dword:2,nearli:2,variou:[1,2],get:2,secondari:2,ssm:2,cannot:2,requir:[1,2],dramat:2,where:2,kernel:2,burst:2,dbmsconnect:2,concern:2,infinit:2,detect:2,enumer:2,enough:2,volatil:2,between:2,"import":2,across:2,parent:[1,2],cycl:2,come:2,inconsist:2,mani:[1,2],among:2,undocu:2,period:2,colon:2,poll:2,ultim:2,mark:2,addit:2,reschedul:2,wake:2,those:2,"case":2,blowfish:[1,2],interoper:[1,2],pedant:2,invok:2,margin:2,stdout:2,henc:2,topicqo:2,destin:2,cluster:2,develop:2,author:2,same:[1,2],check:2,circularli:2,document:2,nest:1,confidenti:2,decompress:2,driven:2,capabl:2,improv:2,extern:2,postpon:2,retransmiss:2,appropri:2,without:2,model:2,execut:2,when:[1,2],rest:2,kill:2,aspect:2,speed:2,death:2,except:2,littl:2,versa:2,real:2,around:2,read:2,categoris:2,traffic:2,mergepolici:2,topicexpress:2,realtim:2,integ:2,unlimit:2,benefit:2,either:2,cascad:2,output:2,inter:2,manag:2,"function":2,cabl:2,keystor:2,definit:2,achiev:2,legal:2,evolv:2,corespond:2,apostroph:2,freed:2,os_tim:2,power:2,garbag:2,inspect:2,fulli:2,ack:2,stand:1,ospl:[1,2],act:2,backup:2,effici:2,liveli:2,unregist:2,multinod:2,your:[1,2],complianc:2,area:2,overwrit:2,strict:2,compliant:2,interfac:2,low:2,lot:2,strictli:2,regard:2,amongst:2,notat:2,possibl:2,bucket:2,unusu:2,embed:2,deadlock:2,loadabl:2,creat:2,certain:2,strongli:2,catchup:2,decreas:2,file:[1,2],intra:2,incorrect:2,again:2,event:2,field:2,valid:[1,2],you:[1,2],architectur:2,regardless:2,sequenc:2,symbol:2,signficantli:2,pool:2,reduc:2,globalprofil:1,directori:2,mask:2,pseudo:2,mimic:2,potenti:2,escap:2,degrad:2,cpu:2,represent:2,all:2,forget:2,standardis:2,improperli:2,disc:2,abil:2,follow:[1,2],disk:2,children:1,garbagag:2,program:2,introduc:2,fals:[1,2],mechan:2,failur:2,veri:2,list:[1,2],helloworld:2,adjust:2,stderr:2,small:2,enterpris:2,zero:2,design:2,pass:2,further:2,opensplicedd:2,tev:2,what:2,clock:2,section:2,abl:2,delet:2,version:2,consecut:2,method:2,full:2,hash:2,behaviour:2,excess:2,ineffici:2,modifi:2,valu:[1,2],search:2,sender:2,prior:2,amount:2,action:2,via:2,api_info:2,transit:2,libhelloworld:2,establish:2,service_cleanup_delai:2,select:2,hexadecim:2,clockstart:2,regist:2,two:2,taken:2,asecurityprofil:2,toggl:2,more:2,reachabl:2,desir:2,flag:2,particular:2,known:2,cach:2,none:2,endpoint:2,histori:2,opensplicev6:2,remain:2,outliv:2,ficiti:2,registr:2,share:2,accept:2,minimum:2,unreli:2,phrase:2,cours:2,divid:2,rather:2,anoth:[1,2],reject:2,resourc:2,referenc:2,buffer:2,associ:2,circumst:2,"short":2,postfix:2,caus:2,so_dontrout:2,help:2,soon:2,through:2,paramet:2,late:2,bypass:2,exchang:2,might:2,finer:2,good:2,"return":2,easili:2,iff:2,reactiv:2,compris:2,found:2,errata:2,truncat:2,hard:2,expect:2,http:2,reduct:2,safeti:2,payload:2,health:2,print:2,occurr:2,proxi:2,reason:2,mmf:2,recv:2,asm:2,basi:2,omit:2,perman:2,lifetim:2,assign:2,major:2,notifi:2,upper:2,nack:2,number:[1,2],placehold:2,instert:2,blank:2,stabl:2,miss:2,differ:2,networkingbridg:2,least:2,scheme:2,store:2,adher:2,option:[1,2],part:2,consult:2,grace:2,albeit:2,whenev:2,remot:2,remov:2,executbal:2,bridg:2,comput:2,expir:2,partitit:2,"null":2,built:2,equival:2,self:2,also:2,build:2,distribut:2,filesystem:2,reach:2,react:2,most:2,cover:2,articip:2,abnorm:2,exp:2,usual:2,carefulli:2,rti:2,session:2,cdr:2,reus:2,fine:2,find:[1,2],impact:2,colloc:2,firewal:2,writer:2,queu:2,express:2,resent:2,sill:2,restart:2,resend:2,cyclic:2,crc:2,common:2,wireshark:2,wrote:2,certif:2,set:[1,2],dump:2,startup:2,see:[1,2],close:2,someth:2,particip:2,won:2,mutex:2,altern:2,signatur:2,numer:2,defaultnamespac:[1,2],succeed:2,distinguish:2,pcap:2,both:2,last:2,fragement:2,context:2,forgotten:2,whole:2,load:2,point:[1,2],instanti:2,header:2,shutdown:2,linux:[1,2],throughout:2,backend:2,chanenl:2,devic:2,due:2,empti:2,secret:2,strategi:2,fire:2,gap:2,partli:2,look:2,contentfilteredtop:2,budget:2,durat:2,"while":2,match:2,behavior:2,error:2,loos:2,pack:2,readi:2,itself:2,seem:2,leveldb:2,minim:2,belong:2,shorter:2,sqlite3:2,higher:2,optim:2,wherea:2,moment:2,temporari:2,user:2,nameless:2,recent:2,lower:2,task:2,discourag:2,ospl_sp_ddsi:1,expens:2,amp:2,elect:2,mandat:2,snappi:2,unsecur:2,transpar:2,big:2,bit:2,characterist:2,formal:2,success:2,resolv:2,collect:2,api:2,encount:2,often:2,acknowledg:2,creation:2,some:[1,2],back:2,sampl:2,mirror:2,scale:2,though:2,per:2,pem:2,retri:2,larg:2,recognis:2,machin:2,previou:2,run:2,step:2,impos:2,constraint:2,idl:2,"1gb":2,block:2,repair:2,primarili:2,within:[1,2],drain:2,addtion:2,ensur:2,chang:2,announc:2,occupi:2,inclus:2,question:2,"long":2,custom:2,forward:2,properli:2,link:2,translat:2,line:2,info:2,consist:2,transmitt:2,priveleg:2,similar:2,constant:2,chan:2,repres:2,incomplet:2,spontan:2,invalid:2,application:2,priori:2,nat:2,clean:2,adminqueu:2,vice:2,dataread:2,tradeoff:2,depth:2,far:2,fresh:2,pluggabl:2,code:2,durabilitypublish:2,reallocat:2,granular:2,estim:2,opposit:2,aris:2,fatal:2,sent:2,whichev:2,keep_last:2,volum:2,untouch:2,implicitli:2,relev:2,tri:2,"try":2,create_particip:2,refer:2,pleas:2,malici:2,impli:2,smaller:2,video:2,odd:2,index:2,compar:2,access:2,experiment:2,can:[1,2],penalti:2,let:2,becom:2,sinc:2,great:2,conceiv:2,larger:2,typic:2,chanc:2,appli:2,xmit:2,"boolean":2,apo:2,from:2,commun:2,doubl:2,next:2,igabty:2,sort:2,defragmnet:2,"transient":2,ospl_comp_zlib_init:2,rare:2,unacknowledg:2,retriev:2,scalabl:2,obvious:2,meet:2,aliv:2,control:2,sqlite:2,malform:2,process:[1,2],high:2,tag:[1,2],weaken:2,delai:2,aes256:2,instead:2,domainservic:2,networkinginterfaceaddress:2,redund:2,physic:2,alloc:2,essenti:2,counter:2,correspond:2,element:[1,2],issu:2,ospl_uri:[1,2],move:2,acquint:2,comma:2,currentcontrolset:2,chosen:2,therefor:2,crash:2,greater:2,nullprofil:2,handl:2,auto:[1,2],overal:2,dai:2,dat:2,clockstop:2,lzf:2,anyth:2,edit:2,mode:2,subset:2,meta:2,"static":2,special:2,out:2,variabl:[1,2],influenc:2,suitabl:2,rel:2,hardwar:2,shut:2,insid:1,releas:[1,2],afterward:2,shortest:2,log:2,unwant:2,could:2,keep:2,length:2,enforc:2,outsid:2,retain:2,finest:2,suffix:2,qualiti:2,date:2,owner:2,facil:2,start:2,system:2,messag:2,attach:2,attack:2,termin:2,ipv4:2,udp:2,rsa:2,exactli:2,charact:2,sens:2,stricter:2,rate:2,unencrypt:2,have:2,reserv:2,need:2,optimis:2,mil:2,rout:2,mib:2,builtin:2,which:[1,2],soap:2,singl:[1,2],unless:2,deploy:[1,2],mimick:2,discov:2,deploi:2,segment:2,request:2,uri:[1,2],determin:2,fact:2,gain:2,milliseocnd:2,dbm:2,text:2,anywai:2,locat:2,should:[1,2],prolong:2,smallest:2,"1abc":2,local:2,meant:2,regularli:2,increas:2,integr:2,contain:[1,2],tuner:2,view:2,conform:2,knowledg:2,packet:2,elast:2,"0hz":2,stack:2,closer:2,straightawai:2,statu:2,wire:2,throttletreshold:2,correctli:2,pattern:2,boundari:2,unregistr:2,dll:2,written:2,progress:2,neither:2,entir:2,thumb:2,plugin:2,equal:2,etc:[1,2],instanc:2,comment:2,arriv:2,vxwork:2,respect:2,quit:2,addition:2,treat:2,immedi:2,presenc:2,assert:2,togeth:2,present:[1,2],replic:2,defin:2,wild:2,observ:2,alon:1,incom:2,revis:2,so_reuseaddr:2,reviv:2,satisfi:2,on_request:2,member:2,largest:2,slave:2,hostnam:2,upon:2,effect:2,logfil:2,expand:2,off:2,well:2,thought:2,exampl:[1,2],choos:2,undefin:2,audio:2,latest:2,sporad:2,less:2,obtain:2,defaultrol:2,timeshar:2,heavili:2,simultan:2,web:2,tight:2,add:[1,2],adh:2,arguabl:2,wait_for_historical_data:2,realiz:2,know:2,password:2,insert:2,resid:2,like:2,lost:2,necessari:[1,2],lose:2,page:2,exceed:2,didn:2,retransmit:2,specfi:2,suppli:[1,2],"export":1,flush:2,proper:2,transport:2,tmp:2,feder:2,lead:2,leak:2,avoid:2,overlap:2,outgo:2,leav:2,overlai:2,usag:2,noisi:2,host:2,dcp:2,about:2,readwrit:2,socket:2,linger:2,datagram:2,lifecycl:2,discard:2,certainti:2,disabl:2,own:2,automat:2,dataset:2,mere:2,leverag:2,trigger:2,replac:2,arg2:2,deliveri:2,measur:2,overflow:2,highest:2,succe:2,made:2,whether:2,shrunk:2,smooth:2,displai:2,troubl:2,asynchron:2,record:2,below:2,limit:2,otherwis:2,problem:2,evalu:2,"int":2,descript:[1,2],dure:2,replica:2,implement:2,inf:2,ing:2,probabl:2,tick:2,boot:2,detail:2,virtual:2,other:2,futur:2,varieti:2,ddsi2:[1,2],stai:2,rule:2,portion:2,auxiliari:2},objtypes:{},objnames:{},filenames:["index","intro","guide"],titles:["Vortex OpenSplice Configuration Guide","Introduction","2   OpenSplice"],objects:{},titleterms:{queri:2,systemid:2,force_key_equ:2,whchigh:2,storemod:2,priorityinherit:2,categori:2,retransmitmergingperiod:2,xmitlossi:2,leas:2,send:2,mainloop:2,outputfil:2,assumemulticastcap:2,delayedalign:2,entropyfil:2,enablecategori:2,measurehbtoacklat:2,primaryreordermaxsampl:2,probelist:2,certificateverif:2,leasemanag:2,trustedcertif:2,port:2,append:2,compat:2,compressionbuffers:2,endpointsinsystem:2,maxreliabbacklog:2,partitionaccess:2,userclockstop:2,gener:2,startupmodedur:2,partition_express:2,address:2,alignerschedul:2,failureact:2,serviceterminateperiod:2,cert:2,defragbuffers:2,userclockservic:2,databandwidthlimit:2,throttlethreshold:2,filenam:2,retryonrejectbesteffort:2,receivebufferchunks:2,retentionperiod:2,usr:2,typedreport:2,scope:2,type:2,rnrservic:2,verifycli:2,legacyfragment:2,dsclusterleasedur:2,latency_budget:2,aligneeschedul:2,lock:2,dbmsconnectservic:2,topic:2,ddsi2directmaxthread:2,compressionthreshold:2,manysocketsmod:2,auxiliarybandwidthlimit:2,resourcelimit:2,secur:2,enablemulticastloopback:2,maxqueuedrexmitmessag:2,threadpool:2,respondtortiinitzeroackwithinvalidheartbeat:2,map:2,max:2,catalog:2,diffservfield:2,bind:2,credenti:2,exclud:2,allow:2,reconnect:2,deathdetectioncount:2,portnr:2,group:2,opensplic:[0,2],polici:2,logstacktrac:2,nodelai:2,rr_storageattrxml:2,persist:2,requestcombineperiod:2,leasedur:2,maxfiles:2,userclockstart:2,timestamp:2,initi:2,globalpartit:2,maxsamples:2,minimumsocketsendbuffers:2,spdpmulticastaddress:2,priority_kind:2,introduct:1,maxsampl:2,name:2,odbc:2,aligne:2,domain:2,packetcapturefil:2,access_mod:2,connect:2,multicasttimetol:2,suppressdefaultlog:2,network:2,externalnetworkaddress:2,publish:2,replication_us:2,multicastdataoffset:2,file_nam:2,appendtofil:2,mirrorremoteent:2,watermark:2,publish_initial_data:2,base:2,legacycompress:2,allowmulticast:2,assumertihaspmdendpoint:2,thread:2,synchron:2,filter:2,heartbeat:2,selfsignedcertif:2,networkinterfaceaddress:2,oper:2,rang:2,durabilityservic:2,maxparticip:2,generatebuiltintop:2,preemptiveackdelai:2,size:2,prioriti:2,networkservic:2,lateackmod:2,construct:2,unicastmetaoffset:2,"final":2,schema:2,namespac:2,snetworkservic:2,userentropi:2,warnat:2,networkqueues:2,reliabilityrecoveryperiod:2,externalnetworkmask:2,listen:2,crccheck:2,argument:2,acknacknumbitsemptyset:2,tabl:2,deliveryqueuemaxsampl:2,accesscontrol:2,spdpinterv:2,squashparticip:2,min:2,queuesiz:2,standardsconform:2,event_table_polici:2,channel:2,userclockqueri:2,useipv6:2,recoveryfactor:2,compress:2,trigger_polici:2,networkingbridgeservic:2,"class":2,synchronousdeliveryprioritythreshold:2,topic_express:2,garbagecollector:2,destruct:2,unicastdataoffset:2,replication_mod:2,partitiontop:2,transport_prior:2,verbos:2,forwardremotedata:2,threshold:2,keyvaluestor:2,absolut:2,configur:[0,2],minimumsocketreceivebuffers:2,suppressspdpmulticast:2,salvos:2,keystorefil:2,dcpspartitiontop:2,reportplugin:2,maxmessages:2,ssl:2,report:2,retryonrejectdur:2,securityprofil:2,multicastrecvnetworkinterfaceaddress:2,smpcount:2,enabl:2,statist:2,partit:2,safetyfactor:2,heapsiz:2,servic:2,threadmax:2,databas:2,defaultmulticastaddress:2,networkpartit:2,discoveri:2,plugininitfunct:2,localdiscoverypartit:2,clientdur:2,dsn:2,aggressivekeeplast1whc:2,timetowaitforalign:2,maxinst:2,kei:2,transportprior:2,dbmstodd:2,entitynam:2,maxsamplesperinst:2,tunerservic:2,initialdiscoveryperiod:2,storesessiontim:2,defragunreliablemaxsampl:2,stacksiz:2,retransmitmerg:2,ignoredpartit:2,schedul:2,maxwaitcount:2,symbol_nam:2,acceleraterexmitblocks:2,guid:0,rr_storageattrcdr:2,maxclient:2,smpoptim:2,storeoptimizeinterv:2,subscrib:2,ddsi2eservic:2,partitionmap:2,waitforattach:2,resolut:2,secondaryreordermaxsampl:2,inprocessexceptionhandl:2,align:2,builtintop:2,dontrout:2,domainid:2,forwardallmessag:2,ddsi2servic:2,whclow:2,multicastmetaoffset:2,receiv:2,singleprocess:2,startupmodecoverstransi:2,maxautoparticipantindex:2,spdpresponsemaxdelai:2,ddstodbm:2,entri:2,client:2,command:2,generatekeyhash:2,allowedport:2,storageparamet:2,tcp:2,pluginlibrari:2,explicitlypublishqossettodefault:2,update_factor:2,participantgain:2,resendmanag:2,applic:2,writerlingerdur:2,maxretri:2,storesleeptim:2,maxthreadspercli:2,daemon:2,participantindex:2,userclockmodul:2,deadlockdetect:2,memorypools:2,server:2,synchronousdeliverylatencybound:2,x509authent:2,unicastresponsetospdpmessag:2,backlog:2,interv:2,intern:2,authent:2,librari:2,throttlelimit:2,trace:2,vortex:0,accesscontrolmodul:2,allowreus:2,topicaccess:2,generalwatchdog:2,fragments:2,content:2,throttl:2,scheduletimeround:2,cpuaffin:2,packetretentionperiod:2,pluginparamet:2,peer:2,storedirectori:2,update_frequ:2,cipher:2,writetimeout:2,timealign:2,maxbursts:2,publish_interv:2,watchdog:2,storag:2,durabl:2,merg:2,coexistwithnativenetwork:2,nackdelai:2,receivebuffers:2,keypassphras:2,includ:2,ipv6:2,forc:2,pwd:2,readtimeout:2,reset:2,"default":2,memorymappedfilestor:2,builtinendpointset:2,adminqueues:2,responsivenesstimeout:2,conservativebuiltinreaderstartup:2,alignment_prior:2,kernelmanag:2,role:2,servicenam:2,test:2,maxqueuedrexmitbyt:2,arrivalofdataassertsppandepliveli:2,leaseperiod:2,expirytim:2,defragreliablemaxsampl:2,algorithm:2,localendpoint:2,reliabl:2,cipherkei:2,timetol:2,equalitycheck:2,servicesonli:2,domaingain:2}}) \ No newline at end of file diff --git a/docs/html/DDSLabVIEWGuide/IDL-LabVIEW.html b/docs/html/DDSLabVIEWGuide/IDL-LabVIEW.html new file mode 100644 index 000000000..7db9af643 --- /dev/null +++ b/docs/html/DDSLabVIEWGuide/IDL-LabVIEW.html @@ -0,0 +1,542 @@ + + + + + + + + 4. LabVIEW Generation from IDL — The Vortex OpenSplice LabVIEW Guide + + + + + + + + + + + + + + + +
    +
    +
    +
    + +
    +

    4. LabVIEW Generation from IDL¶

    +

    While creating a DDS application in LabVIEW, the user must create Topic VIs which map to DDS topic types. In addition to registering a topic, the user neeeds to create DDS Read and DDS Write VIs. LabVIEW data is represented in clusters. The DDS Read and Write VIs have terminals that require a LabVIEW cluster. On data writes, the LabVIEW clusters are converted to DDS topic types and on data reads, the DDS topic types are converted to LabVIEW clusters.

    +

    The user can generate the LabVIEW clusters and DDS VIs from an IDL file.

    +

    The DDS LabVIEW Integration supports generation of LabVIEW typedefs and VIs from IDL. This chapter describes the details of the IDL-LabVIEW binding.

    +
    +

    4.1. Generating LabVIEW VIs from an IDL File IDLPP¶

    +

    DDS Topic Types can be described in an IDL file. The LabVIEW IDL generation is done using the Import_IDL Tools menu in LabVIEW.

    +

    Tools/VortexDDS/Import_IDL

    +
    +Import IDL +
    +

    In the IDL file, ensure that any topic structures have the OSPL specific annotation pragma keylist defined. This value is added as a keylist constant to the key terminal of the generated RegisterTopic.vi.

    +

    Select the IDL file and a folder for the generated VIs.

    +
    +Import IDL +
    +

    Upon successful generation the VIs are located in the folder that was chosen. A dialog box appears indicating the path of the generated VIs and the IDL file.

    +
    +Import IDL +
    +
    +
    +

    4.2. Generated Artifacts¶

    +

    The following table defines the LabVIEW artifacts generated from IDL concepts:

    + +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    IDL ConceptLabVIEW ConceptComment
    module Appended to the name of each VI contained in the module
    enumenuma LabVIEW .ctl file.
    enum valueenum value 
    structclustera LabVIEW .ctl file.
    fieldcluster field 
    sequencearray 
    arrayarray 
    +

    Datatype mappings

    +

    The following table shows the LabVIEW equivalents to IDL primitive types:

    + ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    DDS IDLLabVIEW Type
    booleanBoolean
    charint8
    octetuint8
    shortint16
    unsigned shortuint16
    longint32
    unsigned longuint32
    long longint64
    unsigned long longuint64
    floatsingle-precision floating point
    doubledouble-precision floating point
    stringString
    Unsupported DDS data types
    wcharnot supported
    wstringnot supported
    anynot supported
    long doublenot supported
    unionnot supported
    inheritancenot supported
    +

    Generated VIs and controls

    +

    For each struct in the IDL file, the following VIs and controls are generated:

    +
      +
    • RegisterTopic.vi
    • +
    • Write.vi
    • +
    • Read.vi
    • +
    • CicoTable.vi (Copy-in copy-out)
    • +
    • Topic cluster.ctl (corresponds to each struct in IDL File)
    • +
    • Enum.ctl (corresponds to each enum in IDL File)
    • +
    +

    The “moduleName_structName” is appended to the name of each VI and control that is generated.

    +
    +
    +

    4.3. RegisterTopic.vi¶

    +

    The RegisterTopic.vi represents a DDS topic type. The DDS topic corresponds to a single data type. In DDS, data is distributed by publishing and subscribing topic data samples.

    +
    +Register Topic +
    + +++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Terminal TypeOptionalNameDescriptionOutput consumed by
    InputnoDomainParticipantHandleDDS Domain Participant +entity instance 
    InputnoTopicNameDDS Topic Name 
    InputyesQosProfilePathQoS file uri 
    InputyesQoSProfileNameName of QoS profile 
    Inputyeserror in (no error)Input Error cluster 
    OutputnotopicHandleDDS Topic entity instancecreate_reader.vi +create_writer.vi
    Outputyeserror outError out cluster 
    +
    +
    +

    4.4. Read.vi¶

    +

    The DDS Read.vi is used to read DDS samples from a specific topic.

    +
    +Register Topic +
    + +++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Terminal TypeOptionalNameDescriptionOutput consumed by
    InputnoreaderHandleDDS Reader +entity instance 
    Inputyesmaskread_condition masks +LabVIEW cluster 
    Inputyesmax_samplesmaximum number of samples +to read 
    Inputyesread_operationREAD or TAKE +default operation is TAKE 
    Inputyesquery_expressionexpression to filter +samples based on a query 
    Inputyesquery_parametersparameters for the query +expression 
    Inputyeswait_available_data +_timeoutwait for data available +timeout (seconds) 
    Inputyeserror in (no error)Input Error cluster 
    Outputyesno_of_samplesNumber of samples readuser
    OutputnosamplesLabVIEW clusteruser
    Outputyesdds_sample_info_arraysample informationuser
    Outputyeserror outError out cluster 
    +
    +

    4.4.1. Filters¶

    +

    The filtering of incoming samples can happen based on a query and/or on a sample read condition(s).

    +

    Query

    +

    query_expression: The expression is a SQL condition.

    +

    query_parameters: Each parameter element must be an array element.

    +

    Note: Query expressions are only validated at runtime. If they are incorrect, errors will occur while running the VI.

    +

    Read Condition

    +

    The read condition mask specified will filter the samples that are read or take(n).

    +

    Example: For a reader, the Sample State has Not Read selected and Read deselected.

    +

    Only samples with a Sample State Not Read will be processed with read or take. +Any samples with the Read sample state will not be read or take(n).

    +
    +Reader Filter +
    +
    +
    +
    +

    4.5. Write.vi¶

    +

    The DDS Write.vi is used to write DDS samples to a specific topic.

    +
    +Write +
    + +++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Terminal TypeOptionalNameDescriptionOutput consumed by
    InputnowriterHandleDDS Writer +entity instance 
    Inputyeswrite_opwrite operation: WRITE, +DISPOSE, WRITE_DISPOSE +Default operation: WRITE 
    Inputnodatasamples LabVIEW clusterDDS
    Inputyeswait_pub_matched +_timeoutwait for publication +matched timeout (seconds) 
    Inputyeswrite_after_timeoutwrite samples +after timeout 
    Inputyeserror in (no error)Input Error cluster 
    Outputyeserror outError out cluster 
    +
    +
    + + +
    +
    +
    +
    +
    + +

    Table Of Contents

    + + +

    Previous topic

    +

    3. Vortex DDS Virtual Instruments (VIs)

    +

    Next topic

    +

    5. QoS Provider

    +

    This Page

    + + + +
    +
    +
    +
    + + + + \ No newline at end of file diff --git a/docs/html/DDSLabVIEWGuide/_images/create_publisher.png b/docs/html/DDSLabVIEWGuide/_images/create_publisher.png new file mode 100644 index 000000000..769e42af2 Binary files /dev/null and b/docs/html/DDSLabVIEWGuide/_images/create_publisher.png differ diff --git a/docs/html/DDSLabVIEWGuide/_images/create_reader.png b/docs/html/DDSLabVIEWGuide/_images/create_reader.png new file mode 100644 index 000000000..498f17211 Binary files /dev/null and b/docs/html/DDSLabVIEWGuide/_images/create_reader.png differ diff --git a/docs/html/DDSLabVIEWGuide/_images/create_subscriber.png b/docs/html/DDSLabVIEWGuide/_images/create_subscriber.png new file mode 100644 index 000000000..36a622368 Binary files /dev/null and b/docs/html/DDSLabVIEWGuide/_images/create_subscriber.png differ diff --git a/docs/html/DDSLabVIEWGuide/_images/create_writer.png b/docs/html/DDSLabVIEWGuide/_images/create_writer.png new file mode 100644 index 000000000..3654db92d Binary files /dev/null and b/docs/html/DDSLabVIEWGuide/_images/create_writer.png differ diff --git a/docs/html/DDSLabVIEWGuide/_images/dds_example_selection.png b/docs/html/DDSLabVIEWGuide/_images/dds_example_selection.png new file mode 100644 index 000000000..c1675afc4 Binary files /dev/null and b/docs/html/DDSLabVIEWGuide/_images/dds_example_selection.png differ diff --git a/docs/html/DDSLabVIEWGuide/_images/dds_overview.png b/docs/html/DDSLabVIEWGuide/_images/dds_overview.png new file mode 100644 index 000000000..c7490ddb4 Binary files /dev/null and b/docs/html/DDSLabVIEWGuide/_images/dds_overview.png differ diff --git a/docs/html/DDSLabVIEWGuide/_images/dds_palette.png b/docs/html/DDSLabVIEWGuide/_images/dds_palette.png new file mode 100644 index 000000000..74aa71207 Binary files /dev/null and b/docs/html/DDSLabVIEWGuide/_images/dds_palette.png differ diff --git a/docs/html/DDSLabVIEWGuide/_images/dds_participant.png b/docs/html/DDSLabVIEWGuide/_images/dds_participant.png new file mode 100644 index 000000000..69432da36 Binary files /dev/null and b/docs/html/DDSLabVIEWGuide/_images/dds_participant.png differ diff --git a/docs/html/DDSLabVIEWGuide/_images/dds_read.png b/docs/html/DDSLabVIEWGuide/_images/dds_read.png new file mode 100644 index 000000000..414512c4e Binary files /dev/null and b/docs/html/DDSLabVIEWGuide/_images/dds_read.png differ diff --git a/docs/html/DDSLabVIEWGuide/_images/dds_write.png b/docs/html/DDSLabVIEWGuide/_images/dds_write.png new file mode 100644 index 000000000..3fe69db12 Binary files /dev/null and b/docs/html/DDSLabVIEWGuide/_images/dds_write.png differ diff --git a/docs/html/DDSLabVIEWGuide/_images/delete_entity.png b/docs/html/DDSLabVIEWGuide/_images/delete_entity.png new file mode 100644 index 000000000..4c306edce Binary files /dev/null and b/docs/html/DDSLabVIEWGuide/_images/delete_entity.png differ diff --git a/docs/html/DDSLabVIEWGuide/_images/demo_ishapes_files.png b/docs/html/DDSLabVIEWGuide/_images/demo_ishapes_files.png new file mode 100644 index 000000000..9da432fcb Binary files /dev/null and b/docs/html/DDSLabVIEWGuide/_images/demo_ishapes_files.png differ diff --git a/docs/html/DDSLabVIEWGuide/_images/example_finder.png b/docs/html/DDSLabVIEWGuide/_images/example_finder.png new file mode 100644 index 000000000..e497f4663 Binary files /dev/null and b/docs/html/DDSLabVIEWGuide/_images/example_finder.png differ diff --git a/docs/html/DDSLabVIEWGuide/_images/example_output.png b/docs/html/DDSLabVIEWGuide/_images/example_output.png new file mode 100644 index 000000000..bb9b2168d Binary files /dev/null and b/docs/html/DDSLabVIEWGuide/_images/example_output.png differ diff --git a/docs/html/DDSLabVIEWGuide/_images/idl_import_success.png b/docs/html/DDSLabVIEWGuide/_images/idl_import_success.png new file mode 100644 index 000000000..1f2d87741 Binary files /dev/null and b/docs/html/DDSLabVIEWGuide/_images/idl_import_success.png differ diff --git a/docs/html/DDSLabVIEWGuide/_images/import_idl.png b/docs/html/DDSLabVIEWGuide/_images/import_idl.png new file mode 100644 index 000000000..fd1e1a1cd Binary files /dev/null and b/docs/html/DDSLabVIEWGuide/_images/import_idl.png differ diff --git a/docs/html/DDSLabVIEWGuide/_images/import_idl_dialog.png b/docs/html/DDSLabVIEWGuide/_images/import_idl_dialog.png new file mode 100644 index 000000000..947a8ca23 Binary files /dev/null and b/docs/html/DDSLabVIEWGuide/_images/import_idl_dialog.png differ diff --git a/docs/html/DDSLabVIEWGuide/_images/labview_example_selection.png b/docs/html/DDSLabVIEWGuide/_images/labview_example_selection.png new file mode 100644 index 000000000..4e53fb638 Binary files /dev/null and b/docs/html/DDSLabVIEWGuide/_images/labview_example_selection.png differ diff --git a/docs/html/DDSLabVIEWGuide/_images/list_qos_profiles.png b/docs/html/DDSLabVIEWGuide/_images/list_qos_profiles.png new file mode 100644 index 000000000..7e2adea36 Binary files /dev/null and b/docs/html/DDSLabVIEWGuide/_images/list_qos_profiles.png differ diff --git a/docs/html/DDSLabVIEWGuide/_images/qos_profile_tools.png b/docs/html/DDSLabVIEWGuide/_images/qos_profile_tools.png new file mode 100644 index 000000000..534890f6d Binary files /dev/null and b/docs/html/DDSLabVIEWGuide/_images/qos_profile_tools.png differ diff --git a/docs/html/DDSLabVIEWGuide/_images/read_filter.png b/docs/html/DDSLabVIEWGuide/_images/read_filter.png new file mode 100644 index 000000000..fe5b5a4fd Binary files /dev/null and b/docs/html/DDSLabVIEWGuide/_images/read_filter.png differ diff --git a/docs/html/DDSLabVIEWGuide/_images/register_topic.png b/docs/html/DDSLabVIEWGuide/_images/register_topic.png new file mode 100644 index 000000000..8406925b6 Binary files /dev/null and b/docs/html/DDSLabVIEWGuide/_images/register_topic.png differ diff --git a/docs/html/DDSLabVIEWGuide/_images/set_qos.png b/docs/html/DDSLabVIEWGuide/_images/set_qos.png new file mode 100644 index 000000000..3f001ef27 Binary files /dev/null and b/docs/html/DDSLabVIEWGuide/_images/set_qos.png differ diff --git a/docs/html/DDSLabVIEWGuide/_images/wait_historical.png b/docs/html/DDSLabVIEWGuide/_images/wait_historical.png new file mode 100644 index 000000000..36fd2aae6 Binary files /dev/null and b/docs/html/DDSLabVIEWGuide/_images/wait_historical.png differ diff --git a/docs/html/DDSLabVIEWGuide/_images/windowsInstall1.png b/docs/html/DDSLabVIEWGuide/_images/windowsInstall1.png new file mode 100644 index 000000000..bada3d8dc Binary files /dev/null and b/docs/html/DDSLabVIEWGuide/_images/windowsInstall1.png differ diff --git a/docs/html/DDSLabVIEWGuide/_sources/IDL-LabVIEW.txt b/docs/html/DDSLabVIEWGuide/_sources/IDL-LabVIEW.txt new file mode 100644 index 000000000..73b61ab71 --- /dev/null +++ b/docs/html/DDSLabVIEWGuide/_sources/IDL-LabVIEW.txt @@ -0,0 +1,275 @@ +.. _`LabVIEW Generation from IDL`: + +########################### +LabVIEW Generation from IDL +########################### + +While creating a DDS application in LabVIEW, the user must create Topic VIs which map to DDS topic types. In addition to registering a topic, the user neeeds to create DDS Read and DDS Write VIs. LabVIEW data is represented in clusters. The DDS Read and Write VIs have terminals that require a LabVIEW cluster. On data writes, the LabVIEW clusters are converted to DDS topic types and on data reads, the DDS topic types are converted to LabVIEW clusters. + +The user can generate the LabVIEW clusters and DDS VIs from an IDL file. + +The DDS LabVIEW Integration supports generation of LabVIEW typedefs and VIs from IDL. This chapter describes the details of the IDL-LabVIEW binding. + +Generating LabVIEW VIs from an IDL File IDLPP +********************************************* + +DDS Topic Types can be described in an IDL file. The LabVIEW IDL generation is done using the **Import_IDL** Tools menu in LabVIEW. + +*Tools/VortexDDS/Import_IDL* + +.. figure:: images/import_idl.png + :alt: Import IDL + +In the IDL file, ensure that any topic structures have the OSPL specific annotation *pragma keylist* defined. This value is added as a **keylist constant** to the *key* terminal of the generated RegisterTopic.vi. + +Select the IDL file and a folder for the generated VIs. + +.. figure:: images/import_idl_dialog.png + :alt: Import IDL + +Upon successful generation the VIs are located in the folder that was chosen. A dialog box appears indicating the path of the generated VIs and the IDL file. + +.. figure:: images/idl_import_success.png + :alt: Import IDL + + +.. raw:: latex + + \newpage + + +Generated Artifacts +******************* + +The following table defines the LabVIEW artifacts generated from IDL concepts: + +=========== =============== ======================================================= +IDL Concept LabVIEW Concept Comment +=========== =============== ======================================================= +module Appended to the name of each VI contained in the module +enum enum a LabVIEW .ctl file. +enum value enum value +struct cluster a LabVIEW .ctl file. +field cluster field +sequence array +array array +=========== =============== ======================================================= + + +**Datatype mappings** + +The following table shows the LabVIEW equivalents to IDL primitive types: + +.. table:: + + +--------------------------+-------------------------------+ + |**DDS IDL** |**LabVIEW Type** | + +==========================+===============================+ + |boolean |Boolean | + +--------------------------+-------------------------------+ + |char |int8 | + +--------------------------+-------------------------------+ + |octet |uint8 | + +--------------------------+-------------------------------+ + |short |int16 | + +--------------------------+-------------------------------+ + |unsigned short |uint16 | + +--------------------------+-------------------------------+ + |long |int32 | + +--------------------------+-------------------------------+ + |unsigned long |uint32 | + +--------------------------+-------------------------------+ + |long long |int64 | + +--------------------------+-------------------------------+ + |unsigned long long |uint64 | + +--------------------------+-------------------------------+ + |float |single-precision floating point| + +--------------------------+-------------------------------+ + |double |double-precision floating point| + +--------------------------+-------------------------------+ + |string |String | + +--------------------------+-------------------------------+ + | **Unsupported DDS data types** | + +--------------------------+-------------------------------+ + |wchar |*not supported* | + +--------------------------+-------------------------------+ + |wstring |*not supported* | + +--------------------------+-------------------------------+ + |any |*not supported* | + +--------------------------+-------------------------------+ + |long double |*not supported* | + +--------------------------+-------------------------------+ + |union |*not supported* | + +--------------------------+-------------------------------+ + |inheritance |*not supported* | + +--------------------------+-------------------------------+ + + +**Generated VIs and controls** + +For each struct in the IDL file, the following VIs and controls are generated: + +- RegisterTopic.vi +- Write.vi +- Read.vi +- CicoTable.vi (Copy-in copy-out) +- Topic cluster.ctl (corresponds to each struct in IDL File) +- Enum.ctl (corresponds to each enum in IDL File) + +The "moduleName_structName" is appended to the name of each VI and control that is generated. + +.. raw:: latex + + \newpage + +RegisterTopic.vi +**************** + +The RegisterTopic.vi represents a DDS topic type. The DDS topic corresponds to a single data type. In DDS, data is distributed by publishing and subscribing topic data samples. + +.. figure:: images/register_topic.png + :alt: Register Topic + + + +============= ========= ======================= =========================== ============================ +Terminal Type Optional Name Description Output consumed by +============= ========= ======================= =========================== ============================ +Input no DomainParticipantHandle DDS Domain Participant + entity instance + +Input no TopicName DDS Topic Name + +Input yes QosProfilePath QoS file uri + +Input yes QoSProfileName Name of QoS profile + +Input yes error in (no error) Input Error cluster + +Output no topicHandle DDS Topic entity instance create_reader.vi + create_writer.vi + +Output yes error out Error out cluster +============= ========= ======================= =========================== ============================ + + +.. raw:: latex + + \newpage + +Read.vi +******* + +The DDS Read.vi is used to read DDS samples from a specific topic. + +.. figure:: images/dds_read.png + :alt: Register Topic + + + +============= ========= ======================= =========================== ============================ +Terminal Type Optional Name Description Output consumed by +============= ========= ======================= =========================== ============================ +Input no readerHandle DDS Reader + entity instance + +Input yes mask read_condition masks + LabVIEW cluster + +Input yes max_samples maximum number of samples + to read + +Input yes read_operation READ or TAKE + default operation is TAKE + +Input yes query_expression expression to filter + samples based on a query + +Input yes query_parameters parameters for the query + expression + +Input yes wait_available_data wait for data available + _timeout timeout (seconds) + +Input yes error in (no error) Input Error cluster + +Output yes no_of_samples Number of samples read user + +Output no samples LabVIEW cluster user + +Output yes dds_sample_info_array sample information user + +Output yes error out Error out cluster +============= ========= ======================= =========================== ============================ + + +.. raw:: latex + + \newpage + +Filters +======= + +The filtering of incoming samples can happen based on a query and/or on a sample read condition(s). + +**Query** + +query_expression: The expression is a SQL condition. + +query_parameters: Each parameter element must be an array element. + +*Note: Query expressions are only validated at runtime. If they are incorrect, errors will occur while running the VI.* + + +**Read Condition** + +The read condition mask specified will filter the samples that are read or take(n). + +Example: For a reader, the Sample State has **Not Read** selected and **Read** deselected. + +Only samples with a Sample State **Not Read** will be processed with read or take. +Any samples with the **Read** sample state will not be read or take(n). + + +.. figure:: images/read_filter.png + :alt: Reader Filter + + +.. raw:: latex + + \newpage + + +Write.vi +******** + +The DDS Write.vi is used to write DDS samples to a specific topic. + +.. figure:: images/dds_write.png + :alt: Write + + + +============= ========= ======================= =========================== ============================ +Terminal Type Optional Name Description Output consumed by +============= ========= ======================= =========================== ============================ +Input no writerHandle DDS Writer + entity instance + +Input yes write_op write operation: WRITE, + DISPOSE, WRITE_DISPOSE + Default operation: WRITE + +Input no data samples LabVIEW cluster DDS + +Input yes wait_pub_matched wait for publication + _timeout matched timeout (seconds) + +Input yes write_after_timeout write samples + after timeout + +Input yes error in (no error) Input Error cluster + +Output yes error out Error out cluster +============= ========= ======================= =========================== ============================ + diff --git a/docs/html/DDSLabVIEWGuide/_sources/contacts.txt b/docs/html/DDSLabVIEWGuide/_sources/contacts.txt new file mode 100644 index 000000000..d32f6016f --- /dev/null +++ b/docs/html/DDSLabVIEWGuide/_sources/contacts.txt @@ -0,0 +1 @@ +.. include:: ../../common/contacts.rst diff --git a/docs/html/DDSLabVIEWGuide/_sources/dds_vis.txt b/docs/html/DDSLabVIEWGuide/_sources/dds_vis.txt new file mode 100644 index 000000000..df9084946 --- /dev/null +++ b/docs/html/DDSLabVIEWGuide/_sources/dds_vis.txt @@ -0,0 +1,257 @@ +.. _`Vortex DDS Virtual Instruments`: + + +#################################### +Vortex DDS Virtual Instruments (VIs) +#################################### + + +The DDS LabVIEW Integration provides a function palette with custom virtual instruments (VIs) to model reading and writing data with DDS. + +.. figure:: images/dds_palette.png + :alt: VortexDDS VIs + +The Vortex DDS LabVIEW VIs are included in **VortexDDS** functions palette. + +The following DDS VIs are provided: + + - create_participant.vi + - create_publisher.vi + - create_subscriber.vi + - create_writer.vi + - create_reader.vi + - wait_historical_data.vi + - delete_entity.vi + +DDS VIs usage +************* + +The typical way to model a DDS application in LabVIEW is as follows: + +* model your DDS topics using IDL +* using the LabVIEW IDLPP process generate DDS Topic, Read and Write VIs from the IDL file +* add the generated VIs to your LabVIEW project +* create a DDS LabVIEW application using the VortexDDS functions palette and the generated VIs from the previous step + +QoS Profiles +************ + +In DDS - “The Data-Distribution Service (DDS) relies on the usage of QoS. A QoS (Quality of Service) is a set of characteristics that controls some aspect of the behavior of the DDS Service." + +Each DDS entity VI has an associated QoS profile. By default, the OSPL default profile is used. An XML file that specifies QoS profiles can be used to set the QoS of a DDS entity. + +The QoS profile of an entity is set using the **qos_uri** and **qos_profile** terminals. + + +Please see section :ref:`QoS Provider` for more information. + + +create_participant.vi +********************* + +The create_participant VI represents a DDS domain participant entity. + +In DDS - "A domain participant represents the local membership of the application in a domain. A domain is a distributed concept that links all the applications able to communicate with each other. It represents a communication plane: only the publishers and subscribers attached to the same domain may interact." + +The domain id is the OSPL default domain id specified in the OSPL configuration file (file pointed by "OSPL_URI" environment variable). + + +.. figure:: images/dds_participant.png + :alt: create_participant VI + + +============= ========= ======================= =========================== ============================ +Terminal Type Optional Name Description Output consumed by +============= ========= ======================= =========================== ============================ +Output no pp DDS Domain Participant create_publisher.vi + entity instance create_subscriber.vi + RegisterTopic.vi + +Input yes qos_uri QoS file uri + +Input yes qos_profile Name of QoS profile + +Input yes error in (no error) Input Error cluster + +Output yes error out Error out cluster +============= ========= ======================= =========================== ============================ + +.. raw:: latex + + \newpage + +create_publisher.vi +******************* + +The create_publisher VI represents a DDS publisher entity. + +In DDS, a publisher is "an object responsible for data distribution. It may publish data of different data types." + + +.. figure:: images/create_publisher.png + :alt: create_publisher VI + + +============= ========= ======================= =========================== ============================ +Terminal Type Optional Name Description Output consumed by +============= ========= ======================= =========================== ============================ +Input no pp DDS Domain Participant + entity instance + +Input yes qos_uri QoS file uri + +Input yes qos_profile Name of QoS profile + +Input yes error in (no error) Input Error cluster + +Output no pub DDS publisher create_writer.vi + entity instance + +Output yes error out Error out cluster +============= ========= ======================= =========================== ============================ + +.. raw:: latex + + \newpage + +create_subscriber.vi +******************** + +The create_subscriber VI represents a DDS subscriber entity. + +In DDS, a subscriber is "an object responsible for receiving published data and making it available to the receiving application. It may receive and dispatch data of different specified types." + + +.. figure:: images/create_subscriber.png + :alt: create_subscriber VI + + +============= ========= ======================= =========================== ============================ +Terminal Type Optional Name Description Output consumed by +============= ========= ======================= =========================== ============================ +Input no pp DDS Domain Participant + entity instance + +Input yes qos_uri QoS file uri + +Input yes qos_profile Name of QoS profile + +Input yes error in (no error) Input Error cluster + +Output no sub DDS subscriber create_reader.vi + entity instance + +Output yes error out Error out cluster +============= ========= ======================= =========================== ============================ + + +create_writer.vi +**************** + +The create_writer VI represents a DDS data writer entity. + +In DDS - "The DataWriter is the object the application must use to communicate to a publisher the existence and value of data-objects of a given type." + +.. figure:: images/create_writer.png + :alt: create_writer VI + + +============= ========= ======================= =========================== ============================ +Terminal Type Optional Name Description Output consumed by +============= ========= ======================= =========================== ============================ +Input no pub DDS publisher + entity instance + +Input no topic DDS Topic + entity instance + +Input yes qos_uri QoS file uri + +Input yes qos_profile Name of QoS profile + +Input yes error in (no error) Input Error cluster + +Output no writer DDS writer write.vi + entity instance + +Output yes error out Error out cluster +============= ========= ======================= =========================== ============================ + + +create_reader.vi +**************** + +The create_reader VI represents a DDS data reader entity. + +In DDS - "To access the received data, the application must use a typed DataReader attached to the subscriber." + + +.. figure:: images/create_reader.png + :alt: create_reader VI + + +============= ========= ======================= =========================== ============================ +Terminal Type Optional Name Description Output consumed by +============= ========= ======================= =========================== ============================ +Input no sub DDS subscriber + entity instance + +Input no topic DDS Topic + entity instance + +Input yes qos_uri QoS file uri + +Input yes qos_profile Name of QoS profile + +Input yes error in (no error) Input Error cluster + +Output no reader DDS reader read.vi + entity instance + +Output yes error out Error out cluster +============= ========= ======================= =========================== ============================ + + +wait_historical_data.vi +*********************** + +The wait_historical_data VI specifies that the Reader will wait for historical data to arrive. The timeout terminal is for setting time period (in seconds) determining how long the Reader should wait for the historical data. If the timeout is reached, then any remaining historical data may be interleaved with new data. + + +.. figure:: images/wait_historical.png + :alt: wait_historical VI + + +============= ========= ======================= =========================== ============================ +Terminal Type Optional Name Description Output consumed by +============= ========= ======================= =========================== ============================ +Input no reader DDS Reader + entity instance + +Input yes historical_timeout wait for historical data + timeout (seconds) + +Input yes error in (no error) Input Error cluster + +Output yes error out Error out cluster +============= ========= ======================= =========================== ============================ + + +delete_entity.vi +**************** + +The delete_entity VI is used to delete a DDS entity. Connect the DDS participant to the entity terminal to delete the participant (pp) in a LabVIEW DDS application. + + *NOTE: If the user application VI stops due to an error and does not run to completion, the participant entity is not deleted and leaks occur. The participants are deleted once the user closes LabVIEW.* + +.. figure:: images/delete_entity.png + :alt: delete_entity VI + + +============= ========= ======================= =========================== ============================ +Terminal Type Optional Name Description Output consumed by +============= ========= ======================= =========================== ============================ +Input no entity DDS entity instance +============= ========= ======================= =========================== ============================ + + diff --git a/docs/html/DDSLabVIEWGuide/_sources/example.txt b/docs/html/DDSLabVIEWGuide/_sources/example.txt new file mode 100644 index 000000000..9e3cea27f --- /dev/null +++ b/docs/html/DDSLabVIEWGuide/_sources/example.txt @@ -0,0 +1,175 @@ +.. _`Demo iShapes Example`: + +#################### +Demo iShapes Example +#################### + +A simple demo iShapes example is provided to demonstrates the basic capabilities of the LabVIEW DDS integration. It displays DDS communication between LabVIEW and pure DDS applications. + +The demo_ishapes.vi example (LabVIEW application) can be found using the **NI Example Finder** in LabVIEW: + +.. figure:: images/example_finder.png + :alt: NI Example Finder + +The demo_ishapes.exe (DDS application) can be found in the following directory. + + `OSPL_HOME`/bin/demo_ishapes.exe + +.. raw:: latex + + \newpage + +Example Files +************* + +An explanation of what each example file does is provided below. + +.. figure:: images/demo_ishapes_files.png + :alt: Demo ishapes files + + +**DDS_Data Folder** + +This folder contains the idl file and artifacts generated from idlpp process. + +**ishape.idl** + +- Defines the ShapeType in idl +- Used to generate the LabVIEW DDS VIs via idlpp + +**ishape.idl.xml** + +- Defines the topic descriptor from idl file + +**ShapeType_CicoTable.vi** + +- Defines the copy-in, copy-out table information for mapping IDL to LabVIEW types + +**ShapeType.ctl** + +- Defines a ShapeType cluster in LabVIEW; generated from idlpp +- The ShapeType represents a DDS topic type +- ShapeType specifies 4 properties: color, x, y, shapesize + +**ShapeType_Read.vi** + +- DDS Read ShapeType samples + +**ShapeType_Write.vi** + +- DDS Write ShapeType samples + +**ShapeType_Topic.vi** + +- DDS Register ShapeType topic + +**DDS_PersistentQoS_All.xml** + +- XML file that specifies the DDS QoS (quality of service) settings for RegisterTopic + +**DDS_VolatileQoS_All.xml** + +- XML file that specifies the DDS QoS (quality of service) settings for Reader and Writer entities + +**demo_ishapes.vi** + +- Creates a participant on the default DDS domain +- Registers a ShapeType Topic to Read and to Write to one of the three topics: Circle, Square or Triangle +- Subscribes to the shape and color from demo_ishapes.exe DDS application +- As soon as they match, demo_ishapes.vi publishes to the DDS application and follows the subscribed shape + +.. raw:: latex + + \newpage + +Steps to run example +******************** + +Steps: + +1. Open command shell and run script to setup environment variables. + + **Linux** + + - Open a Linux terminal. + + - Navigate to directory containing release.com file. + + */INSTALLDIR/ADLINK/Vortex_v2/Device/VortexOpenSplice/6.9.x/HDE/x86_64.linux* + + - Run release.com. (Type in “. release.com†at command line.) + + + **Windows** + + - Open a command prompt. + + - Navigate to directory containing release.bat file. + + *INSTALLDIR/ADLINK/Vortex_v2/Device/VortexOpenSplice/6.9.x/HDE/x86_64.win64* + + - Run release.bat. (Type in “release.bat†at command line.) + +2. Navigate to the directory that contains demo_ishapes.exe DDS application and run the application using the command shell used in Step 1. + + **Linux** + + */INSTALLDIR/ADLINK/Vortex_v2/Device/VortexOpenSplice/6.9.x/HDE/x86_64.linux/bin* + + - Run demo_ishapes.exe (Type in “./demo_ishapes.exe &†at command line) + + **Windows** + + *INSTALLDIR/ADLINK/Vortex_v2/Device/VortexOpenSplice/6.9.x/HDE/x86_64.win64/bin* + + - Run demo_ishapes.exe (Type in “demo_ishapes.exe &†at command line) + +3. Start LabVIEW using the **SAME** command shell used in Step 1. Open the demo_ishapes.vi using the **NI Example Finder** in LabVIEW. + + *NOTE: If LabVIEW and the demo_ishapes.exe application are NOT started from a command shell with the correct OSPL environment variables set, the example will not work.* + +.. raw:: latex + + \newpage + +4. In the LabVIEW demo_ishapes.vi application make the following selections: + + Read Shape: Circle + Track color: GREEN + + Write Shape: Triangle + Write color: MAGENTA + + .. figure:: images/labview_example_selection.png + :alt: Demo ishapes LabVIEW selection + +.. raw:: latex + + \newpage + +5. In the demo_ishapes.exe DDS application make the following selections: + + Shape: Circle + Color: Green + Click **Publish** + + Shape: Triangle + Click **Subscribe** + + .. figure:: images/dds_example_selection.png + :alt: Demo ishapes DDS application selection + +6. Run the LabVIEW demo_ishapes.vi application + +7. To stop the LabVIEW application, click on **STOP** on the front panel of the demo_ishapes.vi. + + +Output +****** + +LabVIEW application publishes samples to the DDS application. In the demo_ishapes.exe application, the Triangle follows the Circle. + + +.. figure:: images/example_output.png + :alt: Example outputss + diff --git a/docs/html/DDSLabVIEWGuide/_sources/index.txt b/docs/html/DDSLabVIEWGuide/_sources/index.txt new file mode 100644 index 000000000..77a5b1c5d --- /dev/null +++ b/docs/html/DDSLabVIEWGuide/_sources/index.txt @@ -0,0 +1,26 @@ +.. The Vortex OpenSplice LabVIEW Guide + +.. Doc Issue 01, 11 December 2017 + +################## +DDS LabVIEW Guide +################## + +.. toctree:: + :maxdepth: 6 + :numbered: + + introduction + installation + dds_vis + IDL-LabVIEW + qos_provider + example + + contacts + + +Indices and tables +================== + +* :ref:`search` diff --git a/docs/html/DDSLabVIEWGuide/_sources/installation.txt b/docs/html/DDSLabVIEWGuide/_sources/installation.txt new file mode 100644 index 000000000..42394815e --- /dev/null +++ b/docs/html/DDSLabVIEWGuide/_sources/installation.txt @@ -0,0 +1,112 @@ +.. _`Installation`: + +############ +Installation +############ + +This section describes the procedure to install the Vortex DDS LabVIEW Integration on a Linux or Windows platform. + +System Requirements +******************* + +- Operating System: Windows or Linux +- LabVIEW 2017 installed + +OpenSplice (OSPL) and DDS LabVIEW Installation +*********************************************** + +Steps: + +1. Install OSPL. The DDS LabVIEW Integration is included in this installer. + +2. Setup OSPL license. Copy the license.lic file into the appropriate license directory. + + */INSTALLDIR/ADLINK/Vortex_v2/license* + +3. LabVIEW installation files are contained in a tools/labview folder. + + Example: + */INSTALLDIR/ADLINK/Vortex_v2/Device/VortexOpenSplice/6.9.x/HDE/x86_64.linux/tools/labview* + +OpenSplice (OSPL) Configuration +******************************* + +By default OSPL uses single process configuration. + +DDS LabVIEW Installation +************************ + +Linux +===== + +1. Open a command shell and navigate to + + */INSTALLDIR/ADLINK/Vortex_v2/Device/VortexOpenSplice/6.9.x/HDE/x86_64.linux/tools/labview* + +2. Unzip the "adlink-dds-labview-linux-install.tar.gz". + +3. Run the install_vortex_dds_ubuntu.sh script as a super user. + + sudo ./install_vortex_dds_ubuntu.sh + + *NOTE: The installer sets the default LabVIEW installation path to /usr/local/natinst/LabVIEW-2017-64.* *To override this installation directory, run the install script and pass the install directory as an argument:* + + *sudo ./install_vortex_dds_ubuntu.sh /path/to/your/LabVIEW/installation* + +4. LabVIEW will open and allow the installation Virtual Instrument (VI) run to completion. + +5. After the installation is complete close LabVIEW. Installation takes effect the next time you start LabVIEW. + +Windows +======= + +1. In a file browser, navigate to + + */INSTALLDIR/ADLINK/Vortex_v2/Device/VortexOpenSplice/6.9.x/HDE/x86_64.windows/tools/labview* + +2. Double click on the file “adlink_lib_vortexdds-1.0.0.1â€. This will bring up the VI Package Manager installer dialog box. Select the LabVIEW version to install (32-bit or 64-bit). Select **Install**. + +.. figure:: images/windowsInstall1.png + :alt: DDS windows install + +3. After the installation is complete close LabVIEW. Installation takes effect the next time you start LabVIEW. + +.. raw:: latex + + \newpage + +Running LabVIEW +*************** + +Steps: + +1. Open command shell and run script to setup environment variables. + + **Linux** + + - Open a Linux terminal. + + - Navigate to directory containing release.com file. + + */INSTALLDIR/ADLINK/Vortex_v2/Device/VortexOpenSplice/6.9.x/HDE/x86_64.linux* + + - Run release.com. (Type in “. release.com†at command line.) + + + **Windows** + + - Open a command prompt. + + - Navigate to directory containing release.bat file. + + *INSTALLDIR/ADLINK/Vortex_v2/Device/VortexOpenSplice/6.9.x/HDE/x86_64.win64* + + - Run release.bat. (Type in “release.bat†at command line.) + + +2. Start LabVIEW using the **SAME** command shell used in Step 1. + + *NOTE: If LabVIEW is NOT started from a command shell with the correct OSPL environment variables set, errors will occur when attempting to use DDS LabVIEW virtual instruments.* + + + diff --git a/docs/html/DDSLabVIEWGuide/_sources/introduction.txt b/docs/html/DDSLabVIEWGuide/_sources/introduction.txt new file mode 100644 index 000000000..e6ce33b31 --- /dev/null +++ b/docs/html/DDSLabVIEWGuide/_sources/introduction.txt @@ -0,0 +1,39 @@ +.. _`Introduction`: + + +############ +Introduction +############ + +The DDS LabVIEW Integration provides users with DDS custom virtual instruments (VIs) to model DDS communication between LabVIEW and pure DDS applications. + +DDS +*** + +**What is DDS?** + +“The Data Distribution Service (DDSâ„¢) is a middleware protocol and API standard for data-centric connectivity from the Object Management Group® (OMG®). It integrates the components of a system together, providing low-latency data connectivity, extreme reliability, and a scalable architecture that business and mission-critical Internet of Things (IoT) applications need.†+ +“The main goal of DDS is to share the right data at the right place at the right time, even between time-decoupled publishers and consumers. DDS implements global data space by carefully replicating relevant portions of the logically shared dataspace.†DDS specification + +.. figure:: images/dds_overview.png + :alt: DDS + +**Further Documentation** + +http://portals.omg.org/dds/ + +http://ist.adlinktech.com/ + +LabVIEW +******** + +**What is LabVIEW?** + +“LabVIEW is systems engineering software for applications that require test, measurement, and control with rapid access to hardware and data insights. The LabVIEW programming environment simplifies hardware integration for engineering applications so that you have a consistent way to acquire data from NI and third-party hardware. +The LabVIEW programming environment simplifies hardware integration for engineering applications so that you have a consistent way to acquire data from NI and third-party hardware. LabVIEW reduces the complexity of programming, so you can focus on your unique engineering problem. LabVIEW enables you to immediately visualize results with built-in, drag-and-drop engineering user interface creation and integrated data viewers. To turn your acquired data into real business results, you can develop algorithms for data analysis and advanced control with included math and signal processing IP or reuse your own libraries from a variety of tools. To ensure compatibility with other engineering tools, LabVIEW can interoperate with, and reuse libraries from, other software and open-source languages.†+ +http://www.ni.com/en-ca/shop/labview/buy-labview.html + + + diff --git a/docs/html/DDSLabVIEWGuide/_sources/qos_provider.txt b/docs/html/DDSLabVIEWGuide/_sources/qos_provider.txt new file mode 100644 index 000000000..b9ba9f346 --- /dev/null +++ b/docs/html/DDSLabVIEWGuide/_sources/qos_provider.txt @@ -0,0 +1,99 @@ +.. _`QoS Provider`: + + +############ +QoS Provider +############ + +Each Vortex DDS virtual instrument (VI) has a QoS file uri terminal and a QoS profile terminal. +These terminals are used to set the QoS profile. By default, the OSPL default profile is used. +In DDS - The Data-Distribution Service (DDS) relies on the usage of QoS. A QoS (Quality of Service) is a set of +characteristics that controls some aspect of the behavior of the DDS Service. + +Each DDS VI has an associated QoS profile. By default, the OSPL default profile is used. An XML file that +specifies QoS profiles can be used to set the QoS of a DDS block. + +The following section explains how the QoS is set for a DDS entity using the QoS Provider. + + +QoS Provider File +***************** + +Quality of Service for DDS entities is set using XML files based on the XML schema file DDS_QoSProfile.xsd. +These XML files contain one or more QoS profiles for DDS entities. + +**Note:** Sample QoS Profile XML files can be found in the LabVIEW DDS examples directories. + +QoS Profile +*********** + +A QoS profile consists of a name. The file contains QoS +elements for one or more DDS entities. A skeleton file without any QoS values is displayed below to show +the structure of the file. + + +.. code-block:: xml + + + + + + + + + + + + +**Example: Specify Publisher Partition** + +The example below specifies the publisher's partitions as A and B. + +.. code-block:: xml + + + + + A + B + + + + + +Setting QoS Profile in LabVIEW +****************************** + +The QoS Profiles from the XML file can be obtained using the **List_qos_profiles** Tools menu in LabVIEW. + +*Tools/VortexDDS/List_qos_profiles* + +.. figure:: images/qos_profile_tools.png + :alt: QoS Profile Tools + +.. raw:: latex + + \newpage + +**Steps to set the QoS Profile** + +1. A QoS Provider file can be selected by browsing to the XML file from the **List_qos_profiles** dialog box. Once a valid QoS file is chosen the **Available qos profiles** table is populated with the list of qos profiles that are available in the QoS XML file. If there are QoS profiles found in the file, then **Copy to Clipboard** button will be enabled. + +2. Select the QoS Profile that you want to use and click on **Copy to Clipboard**. + +.. figure:: images/list_qos_profiles.png + :alt: List qos profiles + +3. In your VI, create a String constant and press Ctrl + V. Connect this String constant to the DDS VI **qos_profile** terminal. Set the **qos_uri** as a LabVIEW control or constant and navigate to the path of the QoS Provider file. + +.. figure:: images/set_qos.png + :alt: Set QoS + +The **qos_profile** and **qos_uri** are optional terminals. If they are not set then the default QoS settings will be used. + +**Note:** Seeing the QoS Profile in the list only guarantees the QoS Profile exists in the file. +It does not mean the qos tag exists for the entity. The user is responsible for verifying the entity qos +tag exists in the file. + + diff --git a/docs/html/DDSLabVIEWGuide/_static/Vortex_logo_2014.png b/docs/html/DDSLabVIEWGuide/_static/Vortex_logo_2014.png new file mode 100644 index 000000000..e7de4f525 Binary files /dev/null and b/docs/html/DDSLabVIEWGuide/_static/Vortex_logo_2014.png differ diff --git a/docs/html/DDSLabVIEWGuide/_static/ajax-loader.gif b/docs/html/DDSLabVIEWGuide/_static/ajax-loader.gif new file mode 100644 index 000000000..61faf8cab Binary files /dev/null and b/docs/html/DDSLabVIEWGuide/_static/ajax-loader.gif differ diff --git a/docs/html/DDSLabVIEWGuide/_static/basic.css b/docs/html/DDSLabVIEWGuide/_static/basic.css new file mode 100644 index 000000000..967e36ce0 --- /dev/null +++ b/docs/html/DDSLabVIEWGuide/_static/basic.css @@ -0,0 +1,537 @@ +/* + * basic.css + * ~~~~~~~~~ + * + * Sphinx stylesheet -- basic theme. + * + * :copyright: Copyright 2007-2014 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +/* -- main layout ----------------------------------------------------------- */ + +div.clearer { + clear: both; +} + +/* -- relbar ---------------------------------------------------------------- */ + +div.related { + width: 100%; + font-size: 90%; +} + +div.related h3 { + display: none; +} + +div.related ul { + margin: 0; + padding: 0 0 0 10px; + list-style: none; +} + +div.related li { + display: inline; +} + +div.related li.right { + float: right; + margin-right: 5px; +} + +/* -- sidebar --------------------------------------------------------------- */ + +div.sphinxsidebarwrapper { + padding: 10px 5px 0 10px; +} + +div.sphinxsidebar { + float: left; + width: 230px; + margin-left: -100%; + font-size: 90%; +} + +div.sphinxsidebar ul { + list-style: none; +} + +div.sphinxsidebar ul ul, +div.sphinxsidebar ul.want-points { + margin-left: 20px; + list-style: square; +} + +div.sphinxsidebar ul ul { + margin-top: 0; + margin-bottom: 0; +} + +div.sphinxsidebar form { + margin-top: 10px; +} + +div.sphinxsidebar input { + border: 1px solid #98dbcc; + font-family: sans-serif; + font-size: 1em; +} + +div.sphinxsidebar #searchbox input[type="text"] { + width: 170px; +} + +div.sphinxsidebar #searchbox input[type="submit"] { + width: 30px; +} + +img { + border: 0; + max-width: 100%; +} + +/* -- search page ----------------------------------------------------------- */ + +ul.search { + margin: 10px 0 0 20px; + padding: 0; +} + +ul.search li { + padding: 5px 0 5px 20px; + background-image: url(file.png); + background-repeat: no-repeat; + background-position: 0 7px; +} + +ul.search li a { + font-weight: bold; +} + +ul.search li div.context { + color: #888; + margin: 2px 0 0 30px; + text-align: left; +} + +ul.keywordmatches li.goodmatch a { + font-weight: bold; +} + +/* -- index page ------------------------------------------------------------ */ + +table.contentstable { + width: 90%; +} + +table.contentstable p.biglink { + line-height: 150%; +} + +a.biglink { + font-size: 1.3em; +} + +span.linkdescr { + font-style: italic; + padding-top: 5px; + font-size: 90%; +} + +/* -- general index --------------------------------------------------------- */ + +table.indextable { + width: 100%; +} + +table.indextable td { + text-align: left; + vertical-align: top; +} + +table.indextable dl, table.indextable dd { + margin-top: 0; + margin-bottom: 0; +} + +table.indextable tr.pcap { + height: 10px; +} + +table.indextable tr.cap { + margin-top: 10px; + background-color: #f2f2f2; +} + +img.toggler { + margin-right: 3px; + margin-top: 3px; + cursor: pointer; +} + +div.modindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +div.genindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +/* -- general body styles --------------------------------------------------- */ + +a.headerlink { + visibility: hidden; +} + +h1:hover > a.headerlink, +h2:hover > a.headerlink, +h3:hover > a.headerlink, +h4:hover > a.headerlink, +h5:hover > a.headerlink, +h6:hover > a.headerlink, +dt:hover > a.headerlink { + visibility: visible; +} + +div.body p.caption { + text-align: inherit; +} + +div.body td { + text-align: left; +} + +.field-list ul { + padding-left: 1em; +} + +.first { + margin-top: 0 !important; +} + +p.rubric { + margin-top: 30px; + font-weight: bold; +} + +img.align-left, .figure.align-left, object.align-left { + clear: left; + float: left; + margin-right: 1em; +} + +img.align-right, .figure.align-right, object.align-right { + clear: right; + float: right; + margin-left: 1em; +} + +img.align-center, .figure.align-center, object.align-center { + display: block; + margin-left: auto; + margin-right: auto; +} + +.align-left { + text-align: left; +} + +.align-center { + text-align: center; +} + +.align-right { + text-align: right; +} + +/* -- sidebars -------------------------------------------------------------- */ + +div.sidebar { + margin: 0 0 0.5em 1em; + border: 1px solid #ddb; + padding: 7px 7px 0 7px; + background-color: #ffe; + width: 40%; + float: right; +} + +p.sidebar-title { + font-weight: bold; +} + +/* -- topics ---------------------------------------------------------------- */ + +div.topic { + border: 1px solid #ccc; + padding: 7px 7px 0 7px; + margin: 10px 0 10px 0; +} + +p.topic-title { + font-size: 1.1em; + font-weight: bold; + margin-top: 10px; +} + +/* -- admonitions ----------------------------------------------------------- */ + +div.admonition { + margin-top: 10px; + margin-bottom: 10px; + padding: 7px; +} + +div.admonition dt { + font-weight: bold; +} + +div.admonition dl { + margin-bottom: 0; +} + +p.admonition-title { + margin: 0px 10px 5px 0px; + font-weight: bold; +} + +div.body p.centered { + text-align: center; + margin-top: 25px; +} + +/* -- tables ---------------------------------------------------------------- */ + +table.docutils { + border: 0; + border-collapse: collapse; +} + +table.docutils td, table.docutils th { + padding: 1px 8px 1px 5px; + border-top: 0; + border-left: 0; + border-right: 0; + border-bottom: 1px solid #aaa; +} + +table.field-list td, table.field-list th { + border: 0 !important; +} + +table.footnote td, table.footnote th { + border: 0 !important; +} + +th { + text-align: left; + padding-right: 5px; +} + +table.citation { + border-left: solid 1px gray; + margin-left: 1px; +} + +table.citation td { + border-bottom: none; +} + +/* -- other body styles ----------------------------------------------------- */ + +ol.arabic { + list-style: decimal; +} + +ol.loweralpha { + list-style: lower-alpha; +} + +ol.upperalpha { + list-style: upper-alpha; +} + +ol.lowerroman { + list-style: lower-roman; +} + +ol.upperroman { + list-style: upper-roman; +} + +dl { + margin-bottom: 15px; +} + +dd p { + margin-top: 0px; +} + +dd ul, dd table { + margin-bottom: 10px; +} + +dd { + margin-top: 3px; + margin-bottom: 10px; + margin-left: 30px; +} + +dt:target, .highlighted { + background-color: #fbe54e; +} + +dl.glossary dt { + font-weight: bold; + font-size: 1.1em; +} + +.field-list ul { + margin: 0; + padding-left: 1em; +} + +.field-list p { + margin: 0; +} + +.optional { + font-size: 1.3em; +} + +.versionmodified { + font-style: italic; +} + +.system-message { + background-color: #fda; + padding: 5px; + border: 3px solid red; +} + +.footnote:target { + background-color: #ffa; +} + +.line-block { + display: block; + margin-top: 1em; + margin-bottom: 1em; +} + +.line-block .line-block { + margin-top: 0; + margin-bottom: 0; + margin-left: 1.5em; +} + +.guilabel, .menuselection { + font-family: sans-serif; +} + +.accelerator { + text-decoration: underline; +} + +.classifier { + font-style: oblique; +} + +abbr, acronym { + border-bottom: dotted 1px; + cursor: help; +} + +/* -- code displays --------------------------------------------------------- */ + +pre { + overflow: auto; + overflow-y: hidden; /* fixes display issues on Chrome browsers */ +} + +td.linenos pre { + padding: 5px 0px; + border: 0; + background-color: transparent; + color: #aaa; +} + +table.highlighttable { + margin-left: 0.5em; +} + +table.highlighttable td { + padding: 0 0.5em 0 0.5em; +} + +tt.descname { + background-color: transparent; + font-weight: bold; + font-size: 1.2em; +} + +tt.descclassname { + background-color: transparent; +} + +tt.xref, a tt { + background-color: transparent; + font-weight: bold; +} + +h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt { + background-color: transparent; +} + +.viewcode-link { + float: right; +} + +.viewcode-back { + float: right; + font-family: sans-serif; +} + +div.viewcode-block:target { + margin: -1px -10px; + padding: 0 10px; +} + +/* -- math display ---------------------------------------------------------- */ + +img.math { + vertical-align: middle; +} + +div.body div.math p { + text-align: center; +} + +span.eqno { + float: right; +} + +/* -- printout stylesheet --------------------------------------------------- */ + +@media print { + div.document, + div.documentwrapper, + div.bodywrapper { + margin: 0 !important; + width: 100%; + } + + div.sphinxsidebar, + div.related, + div.footer, + #top-link { + display: none; + } +} \ No newline at end of file diff --git a/docs/html/DDSLabVIEWGuide/_static/comment-bright.png b/docs/html/DDSLabVIEWGuide/_static/comment-bright.png new file mode 100644 index 000000000..551517b8c Binary files /dev/null and b/docs/html/DDSLabVIEWGuide/_static/comment-bright.png differ diff --git a/docs/html/DDSLabVIEWGuide/_static/comment-close.png b/docs/html/DDSLabVIEWGuide/_static/comment-close.png new file mode 100644 index 000000000..09b54be46 Binary files /dev/null and b/docs/html/DDSLabVIEWGuide/_static/comment-close.png differ diff --git a/docs/html/DDSLabVIEWGuide/_static/comment.png b/docs/html/DDSLabVIEWGuide/_static/comment.png new file mode 100644 index 000000000..92feb52b8 Binary files /dev/null and b/docs/html/DDSLabVIEWGuide/_static/comment.png differ diff --git a/docs/html/DDSLabVIEWGuide/_static/doctools.js b/docs/html/DDSLabVIEWGuide/_static/doctools.js new file mode 100644 index 000000000..c5455c905 --- /dev/null +++ b/docs/html/DDSLabVIEWGuide/_static/doctools.js @@ -0,0 +1,238 @@ +/* + * doctools.js + * ~~~~~~~~~~~ + * + * Sphinx JavaScript utilities for all documentation. + * + * :copyright: Copyright 2007-2014 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +/** + * select a different prefix for underscore + */ +$u = _.noConflict(); + +/** + * make the code below compatible with browsers without + * an installed firebug like debugger +if (!window.console || !console.firebug) { + var names = ["log", "debug", "info", "warn", "error", "assert", "dir", + "dirxml", "group", "groupEnd", "time", "timeEnd", "count", "trace", + "profile", "profileEnd"]; + window.console = {}; + for (var i = 0; i < names.length; ++i) + window.console[names[i]] = function() {}; +} + */ + +/** + * small helper function to urldecode strings + */ +jQuery.urldecode = function(x) { + return decodeURIComponent(x).replace(/\+/g, ' '); +}; + +/** + * small helper function to urlencode strings + */ +jQuery.urlencode = encodeURIComponent; + +/** + * This function returns the parsed url parameters of the + * current request. Multiple values per key are supported, + * it will always return arrays of strings for the value parts. + */ +jQuery.getQueryParameters = function(s) { + if (typeof s == 'undefined') + s = document.location.search; + var parts = s.substr(s.indexOf('?') + 1).split('&'); + var result = {}; + for (var i = 0; i < parts.length; i++) { + var tmp = parts[i].split('=', 2); + var key = jQuery.urldecode(tmp[0]); + var value = jQuery.urldecode(tmp[1]); + if (key in result) + result[key].push(value); + else + result[key] = [value]; + } + return result; +}; + +/** + * highlight a given string on a jquery object by wrapping it in + * span elements with the given class name. + */ +jQuery.fn.highlightText = function(text, className) { + function highlight(node) { + if (node.nodeType == 3) { + var val = node.nodeValue; + var pos = val.toLowerCase().indexOf(text); + if (pos >= 0 && !jQuery(node.parentNode).hasClass(className)) { + var span = document.createElement("span"); + span.className = className; + span.appendChild(document.createTextNode(val.substr(pos, text.length))); + node.parentNode.insertBefore(span, node.parentNode.insertBefore( + document.createTextNode(val.substr(pos + text.length)), + node.nextSibling)); + node.nodeValue = val.substr(0, pos); + } + } + else if (!jQuery(node).is("button, select, textarea")) { + jQuery.each(node.childNodes, function() { + highlight(this); + }); + } + } + return this.each(function() { + highlight(this); + }); +}; + +/** + * Small JavaScript module for the documentation. + */ +var Documentation = { + + init : function() { + this.fixFirefoxAnchorBug(); + this.highlightSearchWords(); + this.initIndexTable(); + }, + + /** + * i18n support + */ + TRANSLATIONS : {}, + PLURAL_EXPR : function(n) { return n == 1 ? 0 : 1; }, + LOCALE : 'unknown', + + // gettext and ngettext don't access this so that the functions + // can safely bound to a different name (_ = Documentation.gettext) + gettext : function(string) { + var translated = Documentation.TRANSLATIONS[string]; + if (typeof translated == 'undefined') + return string; + return (typeof translated == 'string') ? translated : translated[0]; + }, + + ngettext : function(singular, plural, n) { + var translated = Documentation.TRANSLATIONS[singular]; + if (typeof translated == 'undefined') + return (n == 1) ? singular : plural; + return translated[Documentation.PLURALEXPR(n)]; + }, + + addTranslations : function(catalog) { + for (var key in catalog.messages) + this.TRANSLATIONS[key] = catalog.messages[key]; + this.PLURAL_EXPR = new Function('n', 'return +(' + catalog.plural_expr + ')'); + this.LOCALE = catalog.locale; + }, + + /** + * add context elements like header anchor links + */ + addContextElements : function() { + $('div[id] > :header:first').each(function() { + $('\u00B6'). + attr('href', '#' + this.id). + attr('title', _('Permalink to this headline')). + appendTo(this); + }); + $('dt[id]').each(function() { + $('\u00B6'). + attr('href', '#' + this.id). + attr('title', _('Permalink to this definition')). + appendTo(this); + }); + }, + + /** + * workaround a firefox stupidity + */ + fixFirefoxAnchorBug : function() { + if (document.location.hash && $.browser.mozilla) + window.setTimeout(function() { + document.location.href += ''; + }, 10); + }, + + /** + * highlight the search words provided in the url in the text + */ + highlightSearchWords : function() { + var params = $.getQueryParameters(); + var terms = (params.highlight) ? params.highlight[0].split(/\s+/) : []; + if (terms.length) { + var body = $('div.body'); + if (!body.length) { + body = $('body'); + } + window.setTimeout(function() { + $.each(terms, function() { + body.highlightText(this.toLowerCase(), 'highlighted'); + }); + }, 10); + $('') + .appendTo($('#searchbox')); + } + }, + + /** + * init the domain index toggle buttons + */ + initIndexTable : function() { + var togglers = $('img.toggler').click(function() { + var src = $(this).attr('src'); + var idnum = $(this).attr('id').substr(7); + $('tr.cg-' + idnum).toggle(); + if (src.substr(-9) == 'minus.png') + $(this).attr('src', src.substr(0, src.length-9) + 'plus.png'); + else + $(this).attr('src', src.substr(0, src.length-8) + 'minus.png'); + }).css('display', ''); + if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) { + togglers.click(); + } + }, + + /** + * helper function to hide the search marks again + */ + hideSearchWords : function() { + $('#searchbox .highlight-link').fadeOut(300); + $('span.highlighted').removeClass('highlighted'); + }, + + /** + * make the url absolute + */ + makeURL : function(relativeURL) { + return DOCUMENTATION_OPTIONS.URL_ROOT + '/' + relativeURL; + }, + + /** + * get the current relative url + */ + getCurrentURL : function() { + var path = document.location.pathname; + var parts = path.split(/\//); + $.each(DOCUMENTATION_OPTIONS.URL_ROOT.split(/\//), function() { + if (this == '..') + parts.pop(); + }); + var url = parts.join('/'); + return path.substring(url.lastIndexOf('/') + 1, path.length - 1); + } +}; + +// quick alias for translations +_ = Documentation.gettext; + +$(document).ready(function() { + Documentation.init(); +}); diff --git a/docs/html/DDSLabVIEWGuide/_static/down-pressed.png b/docs/html/DDSLabVIEWGuide/_static/down-pressed.png new file mode 100644 index 000000000..6f7ad7827 Binary files /dev/null and b/docs/html/DDSLabVIEWGuide/_static/down-pressed.png differ diff --git a/docs/html/DDSLabVIEWGuide/_static/down.png b/docs/html/DDSLabVIEWGuide/_static/down.png new file mode 100644 index 000000000..3003a8877 Binary files /dev/null and b/docs/html/DDSLabVIEWGuide/_static/down.png differ diff --git a/docs/html/DDSLabVIEWGuide/_static/file.png b/docs/html/DDSLabVIEWGuide/_static/file.png new file mode 100644 index 000000000..d18082e39 Binary files /dev/null and b/docs/html/DDSLabVIEWGuide/_static/file.png differ diff --git a/docs/html/DDSLabVIEWGuide/_static/jquery.js b/docs/html/DDSLabVIEWGuide/_static/jquery.js new file mode 100644 index 000000000..e2efc335e --- /dev/null +++ b/docs/html/DDSLabVIEWGuide/_static/jquery.js @@ -0,0 +1,9404 @@ +/*! + * jQuery JavaScript Library v1.7.2 + * http://jquery.com/ + * + * Copyright 2011, John Resig + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * Includes Sizzle.js + * http://sizzlejs.com/ + * Copyright 2011, The Dojo Foundation + * Released under the MIT, BSD, and GPL Licenses. + * + * Date: Fri Jul 5 14:07:58 UTC 2013 + */ +(function( window, undefined ) { + +// Use the correct document accordingly with window argument (sandbox) +var document = window.document, + navigator = window.navigator, + location = window.location; +var jQuery = (function() { + +// Define a local copy of jQuery +var jQuery = function( selector, context ) { + // The jQuery object is actually just the init constructor 'enhanced' + return new jQuery.fn.init( selector, context, rootjQuery ); + }, + + // Map over jQuery in case of overwrite + _jQuery = window.jQuery, + + // Map over the $ in case of overwrite + _$ = window.$, + + // A central reference to the root jQuery(document) + rootjQuery, + + // A simple way to check for HTML strings or ID strings + // Prioritize #id over to avoid XSS via location.hash (#9521) + quickExpr = /^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/, + + // Check if a string has a non-whitespace character in it + rnotwhite = /\S/, + + // Used for trimming whitespace + trimLeft = /^\s+/, + trimRight = /\s+$/, + + // Match a standalone tag + rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>)?$/, + + // JSON RegExp + rvalidchars = /^[\],:{}\s]*$/, + rvalidescape = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, + rvalidtokens = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, + rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g, + + // Useragent RegExp + rwebkit = /(webkit)[ \/]([\w.]+)/, + ropera = /(opera)(?:.*version)?[ \/]([\w.]+)/, + rmsie = /(msie) ([\w.]+)/, + rmozilla = /(mozilla)(?:.*? rv:([\w.]+))?/, + + // Matches dashed string for camelizing + rdashAlpha = /-([a-z]|[0-9])/ig, + rmsPrefix = /^-ms-/, + + // Used by jQuery.camelCase as callback to replace() + fcamelCase = function( all, letter ) { + return ( letter + "" ).toUpperCase(); + }, + + // Keep a UserAgent string for use with jQuery.browser + userAgent = navigator.userAgent, + + // For matching the engine and version of the browser + browserMatch, + + // The deferred used on DOM ready + readyList, + + // The ready event handler + DOMContentLoaded, + + // Save a reference to some core methods + toString = Object.prototype.toString, + hasOwn = Object.prototype.hasOwnProperty, + push = Array.prototype.push, + slice = Array.prototype.slice, + trim = String.prototype.trim, + indexOf = Array.prototype.indexOf, + + // [[Class]] -> type pairs + class2type = {}; + +jQuery.fn = jQuery.prototype = { + constructor: jQuery, + init: function( selector, context, rootjQuery ) { + var match, elem, ret, doc; + + // Handle $(""), $(null), or $(undefined) + if ( !selector ) { + return this; + } + + // Handle $(DOMElement) + if ( selector.nodeType ) { + this.context = this[0] = selector; + this.length = 1; + return this; + } + + // The body element only exists once, optimize finding it + if ( selector === "body" && !context && document.body ) { + this.context = document; + this[0] = document.body; + this.selector = selector; + this.length = 1; + return this; + } + + // Handle HTML strings + if ( typeof selector === "string" ) { + // Are we dealing with HTML string or an ID? + if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) { + // Assume that strings that start and end with <> are HTML and skip the regex check + match = [ null, selector, null ]; + + } else { + match = quickExpr.exec( selector ); + } + + // Verify a match, and that no context was specified for #id + if ( match && (match[1] || !context) ) { + + // HANDLE: $(html) -> $(array) + if ( match[1] ) { + context = context instanceof jQuery ? context[0] : context; + doc = ( context ? context.ownerDocument || context : document ); + + // If a single string is passed in and it's a single tag + // just do a createElement and skip the rest + ret = rsingleTag.exec( selector ); + + if ( ret ) { + if ( jQuery.isPlainObject( context ) ) { + selector = [ document.createElement( ret[1] ) ]; + jQuery.fn.attr.call( selector, context, true ); + + } else { + selector = [ doc.createElement( ret[1] ) ]; + } + + } else { + ret = jQuery.buildFragment( [ match[1] ], [ doc ] ); + selector = ( ret.cacheable ? jQuery.clone(ret.fragment) : ret.fragment ).childNodes; + } + + return jQuery.merge( this, selector ); + + // HANDLE: $("#id") + } else { + elem = document.getElementById( match[2] ); + + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + if ( elem && elem.parentNode ) { + // Handle the case where IE and Opera return items + // by name instead of ID + if ( elem.id !== match[2] ) { + return rootjQuery.find( selector ); + } + + // Otherwise, we inject the element directly into the jQuery object + this.length = 1; + this[0] = elem; + } + + this.context = document; + this.selector = selector; + return this; + } + + // HANDLE: $(expr, $(...)) + } else if ( !context || context.jquery ) { + return ( context || rootjQuery ).find( selector ); + + // HANDLE: $(expr, context) + // (which is just equivalent to: $(context).find(expr) + } else { + return this.constructor( context ).find( selector ); + } + + // HANDLE: $(function) + // Shortcut for document ready + } else if ( jQuery.isFunction( selector ) ) { + return rootjQuery.ready( selector ); + } + + if ( selector.selector !== undefined ) { + this.selector = selector.selector; + this.context = selector.context; + } + + return jQuery.makeArray( selector, this ); + }, + + // Start with an empty selector + selector: "", + + // The current version of jQuery being used + jquery: "1.7.2", + + // The default length of a jQuery object is 0 + length: 0, + + // The number of elements contained in the matched element set + size: function() { + return this.length; + }, + + toArray: function() { + return slice.call( this, 0 ); + }, + + // Get the Nth element in the matched element set OR + // Get the whole matched element set as a clean array + get: function( num ) { + return num == null ? + + // Return a 'clean' array + this.toArray() : + + // Return just the object + ( num < 0 ? this[ this.length + num ] : this[ num ] ); + }, + + // Take an array of elements and push it onto the stack + // (returning the new matched element set) + pushStack: function( elems, name, selector ) { + // Build a new jQuery matched element set + var ret = this.constructor(); + + if ( jQuery.isArray( elems ) ) { + push.apply( ret, elems ); + + } else { + jQuery.merge( ret, elems ); + } + + // Add the old object onto the stack (as a reference) + ret.prevObject = this; + + ret.context = this.context; + + if ( name === "find" ) { + ret.selector = this.selector + ( this.selector ? " " : "" ) + selector; + } else if ( name ) { + ret.selector = this.selector + "." + name + "(" + selector + ")"; + } + + // Return the newly-formed element set + return ret; + }, + + // Execute a callback for every element in the matched set. + // (You can seed the arguments with an array of args, but this is + // only used internally.) + each: function( callback, args ) { + return jQuery.each( this, callback, args ); + }, + + ready: function( fn ) { + // Attach the listeners + jQuery.bindReady(); + + // Add the callback + readyList.add( fn ); + + return this; + }, + + eq: function( i ) { + i = +i; + return i === -1 ? + this.slice( i ) : + this.slice( i, i + 1 ); + }, + + first: function() { + return this.eq( 0 ); + }, + + last: function() { + return this.eq( -1 ); + }, + + slice: function() { + return this.pushStack( slice.apply( this, arguments ), + "slice", slice.call(arguments).join(",") ); + }, + + map: function( callback ) { + return this.pushStack( jQuery.map(this, function( elem, i ) { + return callback.call( elem, i, elem ); + })); + }, + + end: function() { + return this.prevObject || this.constructor(null); + }, + + // For internal use only. + // Behaves like an Array's method, not like a jQuery method. + push: push, + sort: [].sort, + splice: [].splice +}; + +// Give the init function the jQuery prototype for later instantiation +jQuery.fn.init.prototype = jQuery.fn; + +jQuery.extend = jQuery.fn.extend = function() { + var options, name, src, copy, copyIsArray, clone, + target = arguments[0] || {}, + i = 1, + length = arguments.length, + deep = false; + + // Handle a deep copy situation + if ( typeof target === "boolean" ) { + deep = target; + target = arguments[1] || {}; + // skip the boolean and the target + i = 2; + } + + // Handle case when target is a string or something (possible in deep copy) + if ( typeof target !== "object" && !jQuery.isFunction(target) ) { + target = {}; + } + + // extend jQuery itself if only one argument is passed + if ( length === i ) { + target = this; + --i; + } + + for ( ; i < length; i++ ) { + // Only deal with non-null/undefined values + if ( (options = arguments[ i ]) != null ) { + // Extend the base object + for ( name in options ) { + src = target[ name ]; + copy = options[ name ]; + + // Prevent never-ending loop + if ( target === copy ) { + continue; + } + + // Recurse if we're merging plain objects or arrays + if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) { + if ( copyIsArray ) { + copyIsArray = false; + clone = src && jQuery.isArray(src) ? src : []; + + } else { + clone = src && jQuery.isPlainObject(src) ? src : {}; + } + + // Never move original objects, clone them + target[ name ] = jQuery.extend( deep, clone, copy ); + + // Don't bring in undefined values + } else if ( copy !== undefined ) { + target[ name ] = copy; + } + } + } + } + + // Return the modified object + return target; +}; + +jQuery.extend({ + noConflict: function( deep ) { + if ( window.$ === jQuery ) { + window.$ = _$; + } + + if ( deep && window.jQuery === jQuery ) { + window.jQuery = _jQuery; + } + + return jQuery; + }, + + // Is the DOM ready to be used? Set to true once it occurs. + isReady: false, + + // A counter to track how many items to wait for before + // the ready event fires. See #6781 + readyWait: 1, + + // Hold (or release) the ready event + holdReady: function( hold ) { + if ( hold ) { + jQuery.readyWait++; + } else { + jQuery.ready( true ); + } + }, + + // Handle when the DOM is ready + ready: function( wait ) { + // Either a released hold or an DOMready/load event and not yet ready + if ( (wait === true && !--jQuery.readyWait) || (wait !== true && !jQuery.isReady) ) { + // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). + if ( !document.body ) { + return setTimeout( jQuery.ready, 1 ); + } + + // Remember that the DOM is ready + jQuery.isReady = true; + + // If a normal DOM Ready event fired, decrement, and wait if need be + if ( wait !== true && --jQuery.readyWait > 0 ) { + return; + } + + // If there are functions bound, to execute + readyList.fireWith( document, [ jQuery ] ); + + // Trigger any bound ready events + if ( jQuery.fn.trigger ) { + jQuery( document ).trigger( "ready" ).off( "ready" ); + } + } + }, + + bindReady: function() { + if ( readyList ) { + return; + } + + readyList = jQuery.Callbacks( "once memory" ); + + // Catch cases where $(document).ready() is called after the + // browser event has already occurred. + if ( document.readyState === "complete" ) { + // Handle it asynchronously to allow scripts the opportunity to delay ready + return setTimeout( jQuery.ready, 1 ); + } + + // Mozilla, Opera and webkit nightlies currently support this event + if ( document.addEventListener ) { + // Use the handy event callback + document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false ); + + // A fallback to window.onload, that will always work + window.addEventListener( "load", jQuery.ready, false ); + + // If IE event model is used + } else if ( document.attachEvent ) { + // ensure firing before onload, + // maybe late but safe also for iframes + document.attachEvent( "onreadystatechange", DOMContentLoaded ); + + // A fallback to window.onload, that will always work + window.attachEvent( "onload", jQuery.ready ); + + // If IE and not a frame + // continually check to see if the document is ready + var toplevel = false; + + try { + toplevel = window.frameElement == null; + } catch(e) {} + + if ( document.documentElement.doScroll && toplevel ) { + doScrollCheck(); + } + } + }, + + // See test/unit/core.js for details concerning isFunction. + // Since version 1.3, DOM methods and functions like alert + // aren't supported. They return false on IE (#2968). + isFunction: function( obj ) { + return jQuery.type(obj) === "function"; + }, + + isArray: Array.isArray || function( obj ) { + return jQuery.type(obj) === "array"; + }, + + isWindow: function( obj ) { + return obj != null && obj == obj.window; + }, + + isNumeric: function( obj ) { + return !isNaN( parseFloat(obj) ) && isFinite( obj ); + }, + + type: function( obj ) { + return obj == null ? + String( obj ) : + class2type[ toString.call(obj) ] || "object"; + }, + + isPlainObject: function( obj ) { + // Must be an Object. + // Because of IE, we also have to check the presence of the constructor property. + // Make sure that DOM nodes and window objects don't pass through, as well + if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) { + return false; + } + + try { + // Not own constructor property must be Object + if ( obj.constructor && + !hasOwn.call(obj, "constructor") && + !hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) { + return false; + } + } catch ( e ) { + // IE8,9 Will throw exceptions on certain host objects #9897 + return false; + } + + // Own properties are enumerated firstly, so to speed up, + // if last one is own, then all properties are own. + + var key; + for ( key in obj ) {} + + return key === undefined || hasOwn.call( obj, key ); + }, + + isEmptyObject: function( obj ) { + for ( var name in obj ) { + return false; + } + return true; + }, + + error: function( msg ) { + throw new Error( msg ); + }, + + parseJSON: function( data ) { + if ( typeof data !== "string" || !data ) { + return null; + } + + // Make sure leading/trailing whitespace is removed (IE can't handle it) + data = jQuery.trim( data ); + + // Attempt to parse using the native JSON parser first + if ( window.JSON && window.JSON.parse ) { + return window.JSON.parse( data ); + } + + // Make sure the incoming data is actual JSON + // Logic borrowed from http://json.org/json2.js + if ( rvalidchars.test( data.replace( rvalidescape, "@" ) + .replace( rvalidtokens, "]" ) + .replace( rvalidbraces, "")) ) { + + return ( new Function( "return " + data ) )(); + + } + jQuery.error( "Invalid JSON: " + data ); + }, + + // Cross-browser xml parsing + parseXML: function( data ) { + if ( typeof data !== "string" || !data ) { + return null; + } + var xml, tmp; + try { + if ( window.DOMParser ) { // Standard + tmp = new DOMParser(); + xml = tmp.parseFromString( data , "text/xml" ); + } else { // IE + xml = new ActiveXObject( "Microsoft.XMLDOM" ); + xml.async = "false"; + xml.loadXML( data ); + } + } catch( e ) { + xml = undefined; + } + if ( !xml || !xml.documentElement || xml.getElementsByTagName( "parsererror" ).length ) { + jQuery.error( "Invalid XML: " + data ); + } + return xml; + }, + + noop: function() {}, + + // Evaluates a script in a global context + // Workarounds based on findings by Jim Driscoll + // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context + globalEval: function( data ) { + if ( data && rnotwhite.test( data ) ) { + // We use execScript on Internet Explorer + // We use an anonymous function so that context is window + // rather than jQuery in Firefox + ( window.execScript || function( data ) { + window[ "eval" ].call( window, data ); + } )( data ); + } + }, + + // Convert dashed to camelCase; used by the css and data modules + // Microsoft forgot to hump their vendor prefix (#9572) + camelCase: function( string ) { + return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); + }, + + nodeName: function( elem, name ) { + return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase(); + }, + + // args is for internal usage only + each: function( object, callback, args ) { + var name, i = 0, + length = object.length, + isObj = length === undefined || jQuery.isFunction( object ); + + if ( args ) { + if ( isObj ) { + for ( name in object ) { + if ( callback.apply( object[ name ], args ) === false ) { + break; + } + } + } else { + for ( ; i < length; ) { + if ( callback.apply( object[ i++ ], args ) === false ) { + break; + } + } + } + + // A special, fast, case for the most common use of each + } else { + if ( isObj ) { + for ( name in object ) { + if ( callback.call( object[ name ], name, object[ name ] ) === false ) { + break; + } + } + } else { + for ( ; i < length; ) { + if ( callback.call( object[ i ], i, object[ i++ ] ) === false ) { + break; + } + } + } + } + + return object; + }, + + // Use native String.trim function wherever possible + trim: trim ? + function( text ) { + return text == null ? + "" : + trim.call( text ); + } : + + // Otherwise use our own trimming functionality + function( text ) { + return text == null ? + "" : + text.toString().replace( trimLeft, "" ).replace( trimRight, "" ); + }, + + // results is for internal usage only + makeArray: function( array, results ) { + var ret = results || []; + + if ( array != null ) { + // The window, strings (and functions) also have 'length' + // Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930 + var type = jQuery.type( array ); + + if ( array.length == null || type === "string" || type === "function" || type === "regexp" || jQuery.isWindow( array ) ) { + push.call( ret, array ); + } else { + jQuery.merge( ret, array ); + } + } + + return ret; + }, + + inArray: function( elem, array, i ) { + var len; + + if ( array ) { + if ( indexOf ) { + return indexOf.call( array, elem, i ); + } + + len = array.length; + i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0; + + for ( ; i < len; i++ ) { + // Skip accessing in sparse arrays + if ( i in array && array[ i ] === elem ) { + return i; + } + } + } + + return -1; + }, + + merge: function( first, second ) { + var i = first.length, + j = 0; + + if ( typeof second.length === "number" ) { + for ( var l = second.length; j < l; j++ ) { + first[ i++ ] = second[ j ]; + } + + } else { + while ( second[j] !== undefined ) { + first[ i++ ] = second[ j++ ]; + } + } + + first.length = i; + + return first; + }, + + grep: function( elems, callback, inv ) { + var ret = [], retVal; + inv = !!inv; + + // Go through the array, only saving the items + // that pass the validator function + for ( var i = 0, length = elems.length; i < length; i++ ) { + retVal = !!callback( elems[ i ], i ); + if ( inv !== retVal ) { + ret.push( elems[ i ] ); + } + } + + return ret; + }, + + // arg is for internal usage only + map: function( elems, callback, arg ) { + var value, key, ret = [], + i = 0, + length = elems.length, + // jquery objects are treated as arrays + isArray = elems instanceof jQuery || length !== undefined && typeof length === "number" && ( ( length > 0 && elems[ 0 ] && elems[ length -1 ] ) || length === 0 || jQuery.isArray( elems ) ) ; + + // Go through the array, translating each of the items to their + if ( isArray ) { + for ( ; i < length; i++ ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret[ ret.length ] = value; + } + } + + // Go through every key on the object, + } else { + for ( key in elems ) { + value = callback( elems[ key ], key, arg ); + + if ( value != null ) { + ret[ ret.length ] = value; + } + } + } + + // Flatten any nested arrays + return ret.concat.apply( [], ret ); + }, + + // A global GUID counter for objects + guid: 1, + + // Bind a function to a context, optionally partially applying any + // arguments. + proxy: function( fn, context ) { + if ( typeof context === "string" ) { + var tmp = fn[ context ]; + context = fn; + fn = tmp; + } + + // Quick check to determine if target is callable, in the spec + // this throws a TypeError, but we will just return undefined. + if ( !jQuery.isFunction( fn ) ) { + return undefined; + } + + // Simulated bind + var args = slice.call( arguments, 2 ), + proxy = function() { + return fn.apply( context, args.concat( slice.call( arguments ) ) ); + }; + + // Set the guid of unique handler to the same of original handler, so it can be removed + proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++; + + return proxy; + }, + + // Mutifunctional method to get and set values to a collection + // The value/s can optionally be executed if it's a function + access: function( elems, fn, key, value, chainable, emptyGet, pass ) { + var exec, + bulk = key == null, + i = 0, + length = elems.length; + + // Sets many values + if ( key && typeof key === "object" ) { + for ( i in key ) { + jQuery.access( elems, fn, i, key[i], 1, emptyGet, value ); + } + chainable = 1; + + // Sets one value + } else if ( value !== undefined ) { + // Optionally, function values get executed if exec is true + exec = pass === undefined && jQuery.isFunction( value ); + + if ( bulk ) { + // Bulk operations only iterate when executing function values + if ( exec ) { + exec = fn; + fn = function( elem, key, value ) { + return exec.call( jQuery( elem ), value ); + }; + + // Otherwise they run against the entire set + } else { + fn.call( elems, value ); + fn = null; + } + } + + if ( fn ) { + for (; i < length; i++ ) { + fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass ); + } + } + + chainable = 1; + } + + return chainable ? + elems : + + // Gets + bulk ? + fn.call( elems ) : + length ? fn( elems[0], key ) : emptyGet; + }, + + now: function() { + return ( new Date() ).getTime(); + }, + + // Use of jQuery.browser is frowned upon. + // More details: http://docs.jquery.com/Utilities/jQuery.browser + uaMatch: function( ua ) { + ua = ua.toLowerCase(); + + var match = rwebkit.exec( ua ) || + ropera.exec( ua ) || + rmsie.exec( ua ) || + ua.indexOf("compatible") < 0 && rmozilla.exec( ua ) || + []; + + return { browser: match[1] || "", version: match[2] || "0" }; + }, + + sub: function() { + function jQuerySub( selector, context ) { + return new jQuerySub.fn.init( selector, context ); + } + jQuery.extend( true, jQuerySub, this ); + jQuerySub.superclass = this; + jQuerySub.fn = jQuerySub.prototype = this(); + jQuerySub.fn.constructor = jQuerySub; + jQuerySub.sub = this.sub; + jQuerySub.fn.init = function init( selector, context ) { + if ( context && context instanceof jQuery && !(context instanceof jQuerySub) ) { + context = jQuerySub( context ); + } + + return jQuery.fn.init.call( this, selector, context, rootjQuerySub ); + }; + jQuerySub.fn.init.prototype = jQuerySub.fn; + var rootjQuerySub = jQuerySub(document); + return jQuerySub; + }, + + browser: {} +}); + +// Populate the class2type map +jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) { + class2type[ "[object " + name + "]" ] = name.toLowerCase(); +}); + +browserMatch = jQuery.uaMatch( userAgent ); +if ( browserMatch.browser ) { + jQuery.browser[ browserMatch.browser ] = true; + jQuery.browser.version = browserMatch.version; +} + +// Deprecated, use jQuery.browser.webkit instead +if ( jQuery.browser.webkit ) { + jQuery.browser.safari = true; +} + +// IE doesn't match non-breaking spaces with \s +if ( rnotwhite.test( "\xA0" ) ) { + trimLeft = /^[\s\xA0]+/; + trimRight = /[\s\xA0]+$/; +} + +// All jQuery objects should point back to these +rootjQuery = jQuery(document); + +// Cleanup functions for the document ready method +if ( document.addEventListener ) { + DOMContentLoaded = function() { + document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false ); + jQuery.ready(); + }; + +} else if ( document.attachEvent ) { + DOMContentLoaded = function() { + // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). + if ( document.readyState === "complete" ) { + document.detachEvent( "onreadystatechange", DOMContentLoaded ); + jQuery.ready(); + } + }; +} + +// The DOM ready check for Internet Explorer +function doScrollCheck() { + if ( jQuery.isReady ) { + return; + } + + try { + // If IE is used, use the trick by Diego Perini + // http://javascript.nwbox.com/IEContentLoaded/ + document.documentElement.doScroll("left"); + } catch(e) { + setTimeout( doScrollCheck, 1 ); + return; + } + + // and execute any waiting functions + jQuery.ready(); +} + +return jQuery; + +})(); + + +// String to Object flags format cache +var flagsCache = {}; + +// Convert String-formatted flags into Object-formatted ones and store in cache +function createFlags( flags ) { + var object = flagsCache[ flags ] = {}, + i, length; + flags = flags.split( /\s+/ ); + for ( i = 0, length = flags.length; i < length; i++ ) { + object[ flags[i] ] = true; + } + return object; +} + +/* + * Create a callback list using the following parameters: + * + * flags: an optional list of space-separated flags that will change how + * the callback list behaves + * + * By default a callback list will act like an event callback list and can be + * "fired" multiple times. + * + * Possible flags: + * + * once: will ensure the callback list can only be fired once (like a Deferred) + * + * memory: will keep track of previous values and will call any callback added + * after the list has been fired right away with the latest "memorized" + * values (like a Deferred) + * + * unique: will ensure a callback can only be added once (no duplicate in the list) + * + * stopOnFalse: interrupt callings when a callback returns false + * + */ +jQuery.Callbacks = function( flags ) { + + // Convert flags from String-formatted to Object-formatted + // (we check in cache first) + flags = flags ? ( flagsCache[ flags ] || createFlags( flags ) ) : {}; + + var // Actual callback list + list = [], + // Stack of fire calls for repeatable lists + stack = [], + // Last fire value (for non-forgettable lists) + memory, + // Flag to know if list was already fired + fired, + // Flag to know if list is currently firing + firing, + // First callback to fire (used internally by add and fireWith) + firingStart, + // End of the loop when firing + firingLength, + // Index of currently firing callback (modified by remove if needed) + firingIndex, + // Add one or several callbacks to the list + add = function( args ) { + var i, + length, + elem, + type, + actual; + for ( i = 0, length = args.length; i < length; i++ ) { + elem = args[ i ]; + type = jQuery.type( elem ); + if ( type === "array" ) { + // Inspect recursively + add( elem ); + } else if ( type === "function" ) { + // Add if not in unique mode and callback is not in + if ( !flags.unique || !self.has( elem ) ) { + list.push( elem ); + } + } + } + }, + // Fire callbacks + fire = function( context, args ) { + args = args || []; + memory = !flags.memory || [ context, args ]; + fired = true; + firing = true; + firingIndex = firingStart || 0; + firingStart = 0; + firingLength = list.length; + for ( ; list && firingIndex < firingLength; firingIndex++ ) { + if ( list[ firingIndex ].apply( context, args ) === false && flags.stopOnFalse ) { + memory = true; // Mark as halted + break; + } + } + firing = false; + if ( list ) { + if ( !flags.once ) { + if ( stack && stack.length ) { + memory = stack.shift(); + self.fireWith( memory[ 0 ], memory[ 1 ] ); + } + } else if ( memory === true ) { + self.disable(); + } else { + list = []; + } + } + }, + // Actual Callbacks object + self = { + // Add a callback or a collection of callbacks to the list + add: function() { + if ( list ) { + var length = list.length; + add( arguments ); + // Do we need to add the callbacks to the + // current firing batch? + if ( firing ) { + firingLength = list.length; + // With memory, if we're not firing then + // we should call right away, unless previous + // firing was halted (stopOnFalse) + } else if ( memory && memory !== true ) { + firingStart = length; + fire( memory[ 0 ], memory[ 1 ] ); + } + } + return this; + }, + // Remove a callback from the list + remove: function() { + if ( list ) { + var args = arguments, + argIndex = 0, + argLength = args.length; + for ( ; argIndex < argLength ; argIndex++ ) { + for ( var i = 0; i < list.length; i++ ) { + if ( args[ argIndex ] === list[ i ] ) { + // Handle firingIndex and firingLength + if ( firing ) { + if ( i <= firingLength ) { + firingLength--; + if ( i <= firingIndex ) { + firingIndex--; + } + } + } + // Remove the element + list.splice( i--, 1 ); + // If we have some unicity property then + // we only need to do this once + if ( flags.unique ) { + break; + } + } + } + } + } + return this; + }, + // Control if a given callback is in the list + has: function( fn ) { + if ( list ) { + var i = 0, + length = list.length; + for ( ; i < length; i++ ) { + if ( fn === list[ i ] ) { + return true; + } + } + } + return false; + }, + // Remove all callbacks from the list + empty: function() { + list = []; + return this; + }, + // Have the list do nothing anymore + disable: function() { + list = stack = memory = undefined; + return this; + }, + // Is it disabled? + disabled: function() { + return !list; + }, + // Lock the list in its current state + lock: function() { + stack = undefined; + if ( !memory || memory === true ) { + self.disable(); + } + return this; + }, + // Is it locked? + locked: function() { + return !stack; + }, + // Call all callbacks with the given context and arguments + fireWith: function( context, args ) { + if ( stack ) { + if ( firing ) { + if ( !flags.once ) { + stack.push( [ context, args ] ); + } + } else if ( !( flags.once && memory ) ) { + fire( context, args ); + } + } + return this; + }, + // Call all the callbacks with the given arguments + fire: function() { + self.fireWith( this, arguments ); + return this; + }, + // To know if the callbacks have already been called at least once + fired: function() { + return !!fired; + } + }; + + return self; +}; + + + + +var // Static reference to slice + sliceDeferred = [].slice; + +jQuery.extend({ + + Deferred: function( func ) { + var doneList = jQuery.Callbacks( "once memory" ), + failList = jQuery.Callbacks( "once memory" ), + progressList = jQuery.Callbacks( "memory" ), + state = "pending", + lists = { + resolve: doneList, + reject: failList, + notify: progressList + }, + promise = { + done: doneList.add, + fail: failList.add, + progress: progressList.add, + + state: function() { + return state; + }, + + // Deprecated + isResolved: doneList.fired, + isRejected: failList.fired, + + then: function( doneCallbacks, failCallbacks, progressCallbacks ) { + deferred.done( doneCallbacks ).fail( failCallbacks ).progress( progressCallbacks ); + return this; + }, + always: function() { + deferred.done.apply( deferred, arguments ).fail.apply( deferred, arguments ); + return this; + }, + pipe: function( fnDone, fnFail, fnProgress ) { + return jQuery.Deferred(function( newDefer ) { + jQuery.each( { + done: [ fnDone, "resolve" ], + fail: [ fnFail, "reject" ], + progress: [ fnProgress, "notify" ] + }, function( handler, data ) { + var fn = data[ 0 ], + action = data[ 1 ], + returned; + if ( jQuery.isFunction( fn ) ) { + deferred[ handler ](function() { + returned = fn.apply( this, arguments ); + if ( returned && jQuery.isFunction( returned.promise ) ) { + returned.promise().then( newDefer.resolve, newDefer.reject, newDefer.notify ); + } else { + newDefer[ action + "With" ]( this === deferred ? newDefer : this, [ returned ] ); + } + }); + } else { + deferred[ handler ]( newDefer[ action ] ); + } + }); + }).promise(); + }, + // Get a promise for this deferred + // If obj is provided, the promise aspect is added to the object + promise: function( obj ) { + if ( obj == null ) { + obj = promise; + } else { + for ( var key in promise ) { + obj[ key ] = promise[ key ]; + } + } + return obj; + } + }, + deferred = promise.promise({}), + key; + + for ( key in lists ) { + deferred[ key ] = lists[ key ].fire; + deferred[ key + "With" ] = lists[ key ].fireWith; + } + + // Handle state + deferred.done( function() { + state = "resolved"; + }, failList.disable, progressList.lock ).fail( function() { + state = "rejected"; + }, doneList.disable, progressList.lock ); + + // Call given func if any + if ( func ) { + func.call( deferred, deferred ); + } + + // All done! + return deferred; + }, + + // Deferred helper + when: function( firstParam ) { + var args = sliceDeferred.call( arguments, 0 ), + i = 0, + length = args.length, + pValues = new Array( length ), + count = length, + pCount = length, + deferred = length <= 1 && firstParam && jQuery.isFunction( firstParam.promise ) ? + firstParam : + jQuery.Deferred(), + promise = deferred.promise(); + function resolveFunc( i ) { + return function( value ) { + args[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value; + if ( !( --count ) ) { + deferred.resolveWith( deferred, args ); + } + }; + } + function progressFunc( i ) { + return function( value ) { + pValues[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value; + deferred.notifyWith( promise, pValues ); + }; + } + if ( length > 1 ) { + for ( ; i < length; i++ ) { + if ( args[ i ] && args[ i ].promise && jQuery.isFunction( args[ i ].promise ) ) { + args[ i ].promise().then( resolveFunc(i), deferred.reject, progressFunc(i) ); + } else { + --count; + } + } + if ( !count ) { + deferred.resolveWith( deferred, args ); + } + } else if ( deferred !== firstParam ) { + deferred.resolveWith( deferred, length ? [ firstParam ] : [] ); + } + return promise; + } +}); + + + + +jQuery.support = (function() { + + var support, + all, + a, + select, + opt, + input, + fragment, + tds, + events, + eventName, + i, + isSupported, + div = document.createElement( "div" ), + documentElement = document.documentElement; + + // Preliminary tests + div.setAttribute("className", "t"); + div.innerHTML = "
    a"; + + all = div.getElementsByTagName( "*" ); + a = div.getElementsByTagName( "a" )[ 0 ]; + + // Can't get basic test support + if ( !all || !all.length || !a ) { + return {}; + } + + // First batch of supports tests + select = document.createElement( "select" ); + opt = select.appendChild( document.createElement("option") ); + input = div.getElementsByTagName( "input" )[ 0 ]; + + support = { + // IE strips leading whitespace when .innerHTML is used + leadingWhitespace: ( div.firstChild.nodeType === 3 ), + + // Make sure that tbody elements aren't automatically inserted + // IE will insert them into empty tables + tbody: !div.getElementsByTagName("tbody").length, + + // Make sure that link elements get serialized correctly by innerHTML + // This requires a wrapper element in IE + htmlSerialize: !!div.getElementsByTagName("link").length, + + // Get the style information from getAttribute + // (IE uses .cssText instead) + style: /top/.test( a.getAttribute("style") ), + + // Make sure that URLs aren't manipulated + // (IE normalizes it by default) + hrefNormalized: ( a.getAttribute("href") === "/a" ), + + // Make sure that element opacity exists + // (IE uses filter instead) + // Use a regex to work around a WebKit issue. See #5145 + opacity: /^0.55/.test( a.style.opacity ), + + // Verify style float existence + // (IE uses styleFloat instead of cssFloat) + cssFloat: !!a.style.cssFloat, + + // Make sure that if no value is specified for a checkbox + // that it defaults to "on". + // (WebKit defaults to "" instead) + checkOn: ( input.value === "on" ), + + // Make sure that a selected-by-default option has a working selected property. + // (WebKit defaults to false instead of true, IE too, if it's in an optgroup) + optSelected: opt.selected, + + // Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7) + getSetAttribute: div.className !== "t", + + // Tests for enctype support on a form(#6743) + enctype: !!document.createElement("form").enctype, + + // Makes sure cloning an html5 element does not cause problems + // Where outerHTML is undefined, this still works + html5Clone: document.createElement("nav").cloneNode( true ).outerHTML !== "<:nav>", + + // Will be defined later + submitBubbles: true, + changeBubbles: true, + focusinBubbles: false, + deleteExpando: true, + noCloneEvent: true, + inlineBlockNeedsLayout: false, + shrinkWrapBlocks: false, + reliableMarginRight: true, + pixelMargin: true + }; + + // jQuery.boxModel DEPRECATED in 1.3, use jQuery.support.boxModel instead + jQuery.boxModel = support.boxModel = (document.compatMode === "CSS1Compat"); + + // Make sure checked status is properly cloned + input.checked = true; + support.noCloneChecked = input.cloneNode( true ).checked; + + // Make sure that the options inside disabled selects aren't marked as disabled + // (WebKit marks them as disabled) + select.disabled = true; + support.optDisabled = !opt.disabled; + + // Test to see if it's possible to delete an expando from an element + // Fails in Internet Explorer + try { + delete div.test; + } catch( e ) { + support.deleteExpando = false; + } + + if ( !div.addEventListener && div.attachEvent && div.fireEvent ) { + div.attachEvent( "onclick", function() { + // Cloning a node shouldn't copy over any + // bound event handlers (IE does this) + support.noCloneEvent = false; + }); + div.cloneNode( true ).fireEvent( "onclick" ); + } + + // Check if a radio maintains its value + // after being appended to the DOM + input = document.createElement("input"); + input.value = "t"; + input.setAttribute("type", "radio"); + support.radioValue = input.value === "t"; + + input.setAttribute("checked", "checked"); + + // #11217 - WebKit loses check when the name is after the checked attribute + input.setAttribute( "name", "t" ); + + div.appendChild( input ); + fragment = document.createDocumentFragment(); + fragment.appendChild( div.lastChild ); + + // WebKit doesn't clone checked state correctly in fragments + support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked; + + // Check if a disconnected checkbox will retain its checked + // value of true after appended to the DOM (IE6/7) + support.appendChecked = input.checked; + + fragment.removeChild( input ); + fragment.appendChild( div ); + + // Technique from Juriy Zaytsev + // http://perfectionkills.com/detecting-event-support-without-browser-sniffing/ + // We only care about the case where non-standard event systems + // are used, namely in IE. Short-circuiting here helps us to + // avoid an eval call (in setAttribute) which can cause CSP + // to go haywire. See: https://developer.mozilla.org/en/Security/CSP + if ( div.attachEvent ) { + for ( i in { + submit: 1, + change: 1, + focusin: 1 + }) { + eventName = "on" + i; + isSupported = ( eventName in div ); + if ( !isSupported ) { + div.setAttribute( eventName, "return;" ); + isSupported = ( typeof div[ eventName ] === "function" ); + } + support[ i + "Bubbles" ] = isSupported; + } + } + + fragment.removeChild( div ); + + // Null elements to avoid leaks in IE + fragment = select = opt = div = input = null; + + // Run tests that need a body at doc ready + jQuery(function() { + var container, outer, inner, table, td, offsetSupport, + marginDiv, conMarginTop, style, html, positionTopLeftWidthHeight, + paddingMarginBorderVisibility, paddingMarginBorder, + body = document.getElementsByTagName("body")[0]; + + if ( !body ) { + // Return for frameset docs that don't have a body + return; + } + + conMarginTop = 1; + paddingMarginBorder = "padding:0;margin:0;border:"; + positionTopLeftWidthHeight = "position:absolute;top:0;left:0;width:1px;height:1px;"; + paddingMarginBorderVisibility = paddingMarginBorder + "0;visibility:hidden;"; + style = "style='" + positionTopLeftWidthHeight + paddingMarginBorder + "5px solid #000;"; + html = "
    " + + "" + + "
    "; + + container = document.createElement("div"); + container.style.cssText = paddingMarginBorderVisibility + "width:0;height:0;position:static;top:0;margin-top:" + conMarginTop + "px"; + body.insertBefore( container, body.firstChild ); + + // Construct the test element + div = document.createElement("div"); + container.appendChild( div ); + + // Check if table cells still have offsetWidth/Height when they are set + // to display:none and there are still other visible table cells in a + // table row; if so, offsetWidth/Height are not reliable for use when + // determining if an element has been hidden directly using + // display:none (it is still safe to use offsets if a parent element is + // hidden; don safety goggles and see bug #4512 for more information). + // (only IE 8 fails this test) + div.innerHTML = "
    t
    "; + tds = div.getElementsByTagName( "td" ); + isSupported = ( tds[ 0 ].offsetHeight === 0 ); + + tds[ 0 ].style.display = ""; + tds[ 1 ].style.display = "none"; + + // Check if empty table cells still have offsetWidth/Height + // (IE <= 8 fail this test) + support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 ); + + // Check if div with explicit width and no margin-right incorrectly + // gets computed margin-right based on width of container. For more + // info see bug #3333 + // Fails in WebKit before Feb 2011 nightlies + // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right + if ( window.getComputedStyle ) { + div.innerHTML = ""; + marginDiv = document.createElement( "div" ); + marginDiv.style.width = "0"; + marginDiv.style.marginRight = "0"; + div.style.width = "2px"; + div.appendChild( marginDiv ); + support.reliableMarginRight = + ( parseInt( ( window.getComputedStyle( marginDiv, null ) || { marginRight: 0 } ).marginRight, 10 ) || 0 ) === 0; + } + + if ( typeof div.style.zoom !== "undefined" ) { + // Check if natively block-level elements act like inline-block + // elements when setting their display to 'inline' and giving + // them layout + // (IE < 8 does this) + div.innerHTML = ""; + div.style.width = div.style.padding = "1px"; + div.style.border = 0; + div.style.overflow = "hidden"; + div.style.display = "inline"; + div.style.zoom = 1; + support.inlineBlockNeedsLayout = ( div.offsetWidth === 3 ); + + // Check if elements with layout shrink-wrap their children + // (IE 6 does this) + div.style.display = "block"; + div.style.overflow = "visible"; + div.innerHTML = "
    "; + support.shrinkWrapBlocks = ( div.offsetWidth !== 3 ); + } + + div.style.cssText = positionTopLeftWidthHeight + paddingMarginBorderVisibility; + div.innerHTML = html; + + outer = div.firstChild; + inner = outer.firstChild; + td = outer.nextSibling.firstChild.firstChild; + + offsetSupport = { + doesNotAddBorder: ( inner.offsetTop !== 5 ), + doesAddBorderForTableAndCells: ( td.offsetTop === 5 ) + }; + + inner.style.position = "fixed"; + inner.style.top = "20px"; + + // safari subtracts parent border width here which is 5px + offsetSupport.fixedPosition = ( inner.offsetTop === 20 || inner.offsetTop === 15 ); + inner.style.position = inner.style.top = ""; + + outer.style.overflow = "hidden"; + outer.style.position = "relative"; + + offsetSupport.subtractsBorderForOverflowNotVisible = ( inner.offsetTop === -5 ); + offsetSupport.doesNotIncludeMarginInBodyOffset = ( body.offsetTop !== conMarginTop ); + + if ( window.getComputedStyle ) { + div.style.marginTop = "1%"; + support.pixelMargin = ( window.getComputedStyle( div, null ) || { marginTop: 0 } ).marginTop !== "1%"; + } + + if ( typeof container.style.zoom !== "undefined" ) { + container.style.zoom = 1; + } + + body.removeChild( container ); + marginDiv = div = container = null; + + jQuery.extend( support, offsetSupport ); + }); + + return support; +})(); + + + + +var rbrace = /^(?:\{.*\}|\[.*\])$/, + rmultiDash = /([A-Z])/g; + +jQuery.extend({ + cache: {}, + + // Please use with caution + uuid: 0, + + // Unique for each copy of jQuery on the page + // Non-digits removed to match rinlinejQuery + expando: "jQuery" + ( jQuery.fn.jquery + Math.random() ).replace( /\D/g, "" ), + + // The following elements throw uncatchable exceptions if you + // attempt to add expando properties to them. + noData: { + "embed": true, + // Ban all objects except for Flash (which handle expandos) + "object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000", + "applet": true + }, + + hasData: function( elem ) { + elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ]; + return !!elem && !isEmptyDataObject( elem ); + }, + + data: function( elem, name, data, pvt /* Internal Use Only */ ) { + if ( !jQuery.acceptData( elem ) ) { + return; + } + + var privateCache, thisCache, ret, + internalKey = jQuery.expando, + getByName = typeof name === "string", + + // We have to handle DOM nodes and JS objects differently because IE6-7 + // can't GC object references properly across the DOM-JS boundary + isNode = elem.nodeType, + + // Only DOM nodes need the global jQuery cache; JS object data is + // attached directly to the object so GC can occur automatically + cache = isNode ? jQuery.cache : elem, + + // Only defining an ID for JS objects if its cache already exists allows + // the code to shortcut on the same path as a DOM node with no cache + id = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey, + isEvents = name === "events"; + + // Avoid doing any more work than we need to when trying to get data on an + // object that has no data at all + if ( (!id || !cache[id] || (!isEvents && !pvt && !cache[id].data)) && getByName && data === undefined ) { + return; + } + + if ( !id ) { + // Only DOM nodes need a new unique ID for each element since their data + // ends up in the global cache + if ( isNode ) { + elem[ internalKey ] = id = ++jQuery.uuid; + } else { + id = internalKey; + } + } + + if ( !cache[ id ] ) { + cache[ id ] = {}; + + // Avoids exposing jQuery metadata on plain JS objects when the object + // is serialized using JSON.stringify + if ( !isNode ) { + cache[ id ].toJSON = jQuery.noop; + } + } + + // An object can be passed to jQuery.data instead of a key/value pair; this gets + // shallow copied over onto the existing cache + if ( typeof name === "object" || typeof name === "function" ) { + if ( pvt ) { + cache[ id ] = jQuery.extend( cache[ id ], name ); + } else { + cache[ id ].data = jQuery.extend( cache[ id ].data, name ); + } + } + + privateCache = thisCache = cache[ id ]; + + // jQuery data() is stored in a separate object inside the object's internal data + // cache in order to avoid key collisions between internal data and user-defined + // data. + if ( !pvt ) { + if ( !thisCache.data ) { + thisCache.data = {}; + } + + thisCache = thisCache.data; + } + + if ( data !== undefined ) { + thisCache[ jQuery.camelCase( name ) ] = data; + } + + // Users should not attempt to inspect the internal events object using jQuery.data, + // it is undocumented and subject to change. But does anyone listen? No. + if ( isEvents && !thisCache[ name ] ) { + return privateCache.events; + } + + // Check for both converted-to-camel and non-converted data property names + // If a data property was specified + if ( getByName ) { + + // First Try to find as-is property data + ret = thisCache[ name ]; + + // Test for null|undefined property data + if ( ret == null ) { + + // Try to find the camelCased property + ret = thisCache[ jQuery.camelCase( name ) ]; + } + } else { + ret = thisCache; + } + + return ret; + }, + + removeData: function( elem, name, pvt /* Internal Use Only */ ) { + if ( !jQuery.acceptData( elem ) ) { + return; + } + + var thisCache, i, l, + + // Reference to internal data cache key + internalKey = jQuery.expando, + + isNode = elem.nodeType, + + // See jQuery.data for more information + cache = isNode ? jQuery.cache : elem, + + // See jQuery.data for more information + id = isNode ? elem[ internalKey ] : internalKey; + + // If there is already no cache entry for this object, there is no + // purpose in continuing + if ( !cache[ id ] ) { + return; + } + + if ( name ) { + + thisCache = pvt ? cache[ id ] : cache[ id ].data; + + if ( thisCache ) { + + // Support array or space separated string names for data keys + if ( !jQuery.isArray( name ) ) { + + // try the string as a key before any manipulation + if ( name in thisCache ) { + name = [ name ]; + } else { + + // split the camel cased version by spaces unless a key with the spaces exists + name = jQuery.camelCase( name ); + if ( name in thisCache ) { + name = [ name ]; + } else { + name = name.split( " " ); + } + } + } + + for ( i = 0, l = name.length; i < l; i++ ) { + delete thisCache[ name[i] ]; + } + + // If there is no data left in the cache, we want to continue + // and let the cache object itself get destroyed + if ( !( pvt ? isEmptyDataObject : jQuery.isEmptyObject )( thisCache ) ) { + return; + } + } + } + + // See jQuery.data for more information + if ( !pvt ) { + delete cache[ id ].data; + + // Don't destroy the parent cache unless the internal data object + // had been the only thing left in it + if ( !isEmptyDataObject(cache[ id ]) ) { + return; + } + } + + // Browsers that fail expando deletion also refuse to delete expandos on + // the window, but it will allow it on all other JS objects; other browsers + // don't care + // Ensure that `cache` is not a window object #10080 + if ( jQuery.support.deleteExpando || !cache.setInterval ) { + delete cache[ id ]; + } else { + cache[ id ] = null; + } + + // We destroyed the cache and need to eliminate the expando on the node to avoid + // false lookups in the cache for entries that no longer exist + if ( isNode ) { + // IE does not allow us to delete expando properties from nodes, + // nor does it have a removeAttribute function on Document nodes; + // we must handle all of these cases + if ( jQuery.support.deleteExpando ) { + delete elem[ internalKey ]; + } else if ( elem.removeAttribute ) { + elem.removeAttribute( internalKey ); + } else { + elem[ internalKey ] = null; + } + } + }, + + // For internal use only. + _data: function( elem, name, data ) { + return jQuery.data( elem, name, data, true ); + }, + + // A method for determining if a DOM node can handle the data expando + acceptData: function( elem ) { + if ( elem.nodeName ) { + var match = jQuery.noData[ elem.nodeName.toLowerCase() ]; + + if ( match ) { + return !(match === true || elem.getAttribute("classid") !== match); + } + } + + return true; + } +}); + +jQuery.fn.extend({ + data: function( key, value ) { + var parts, part, attr, name, l, + elem = this[0], + i = 0, + data = null; + + // Gets all values + if ( key === undefined ) { + if ( this.length ) { + data = jQuery.data( elem ); + + if ( elem.nodeType === 1 && !jQuery._data( elem, "parsedAttrs" ) ) { + attr = elem.attributes; + for ( l = attr.length; i < l; i++ ) { + name = attr[i].name; + + if ( name.indexOf( "data-" ) === 0 ) { + name = jQuery.camelCase( name.substring(5) ); + + dataAttr( elem, name, data[ name ] ); + } + } + jQuery._data( elem, "parsedAttrs", true ); + } + } + + return data; + } + + // Sets multiple values + if ( typeof key === "object" ) { + return this.each(function() { + jQuery.data( this, key ); + }); + } + + parts = key.split( ".", 2 ); + parts[1] = parts[1] ? "." + parts[1] : ""; + part = parts[1] + "!"; + + return jQuery.access( this, function( value ) { + + if ( value === undefined ) { + data = this.triggerHandler( "getData" + part, [ parts[0] ] ); + + // Try to fetch any internally stored data first + if ( data === undefined && elem ) { + data = jQuery.data( elem, key ); + data = dataAttr( elem, key, data ); + } + + return data === undefined && parts[1] ? + this.data( parts[0] ) : + data; + } + + parts[1] = value; + this.each(function() { + var self = jQuery( this ); + + self.triggerHandler( "setData" + part, parts ); + jQuery.data( this, key, value ); + self.triggerHandler( "changeData" + part, parts ); + }); + }, null, value, arguments.length > 1, null, false ); + }, + + removeData: function( key ) { + return this.each(function() { + jQuery.removeData( this, key ); + }); + } +}); + +function dataAttr( elem, key, data ) { + // If nothing was found internally, try to fetch any + // data from the HTML5 data-* attribute + if ( data === undefined && elem.nodeType === 1 ) { + + var name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase(); + + data = elem.getAttribute( name ); + + if ( typeof data === "string" ) { + try { + data = data === "true" ? true : + data === "false" ? false : + data === "null" ? null : + jQuery.isNumeric( data ) ? +data : + rbrace.test( data ) ? jQuery.parseJSON( data ) : + data; + } catch( e ) {} + + // Make sure we set the data so it isn't changed later + jQuery.data( elem, key, data ); + + } else { + data = undefined; + } + } + + return data; +} + +// checks a cache object for emptiness +function isEmptyDataObject( obj ) { + for ( var name in obj ) { + + // if the public data object is empty, the private is still empty + if ( name === "data" && jQuery.isEmptyObject( obj[name] ) ) { + continue; + } + if ( name !== "toJSON" ) { + return false; + } + } + + return true; +} + + + + +function handleQueueMarkDefer( elem, type, src ) { + var deferDataKey = type + "defer", + queueDataKey = type + "queue", + markDataKey = type + "mark", + defer = jQuery._data( elem, deferDataKey ); + if ( defer && + ( src === "queue" || !jQuery._data(elem, queueDataKey) ) && + ( src === "mark" || !jQuery._data(elem, markDataKey) ) ) { + // Give room for hard-coded callbacks to fire first + // and eventually mark/queue something else on the element + setTimeout( function() { + if ( !jQuery._data( elem, queueDataKey ) && + !jQuery._data( elem, markDataKey ) ) { + jQuery.removeData( elem, deferDataKey, true ); + defer.fire(); + } + }, 0 ); + } +} + +jQuery.extend({ + + _mark: function( elem, type ) { + if ( elem ) { + type = ( type || "fx" ) + "mark"; + jQuery._data( elem, type, (jQuery._data( elem, type ) || 0) + 1 ); + } + }, + + _unmark: function( force, elem, type ) { + if ( force !== true ) { + type = elem; + elem = force; + force = false; + } + if ( elem ) { + type = type || "fx"; + var key = type + "mark", + count = force ? 0 : ( (jQuery._data( elem, key ) || 1) - 1 ); + if ( count ) { + jQuery._data( elem, key, count ); + } else { + jQuery.removeData( elem, key, true ); + handleQueueMarkDefer( elem, type, "mark" ); + } + } + }, + + queue: function( elem, type, data ) { + var q; + if ( elem ) { + type = ( type || "fx" ) + "queue"; + q = jQuery._data( elem, type ); + + // Speed up dequeue by getting out quickly if this is just a lookup + if ( data ) { + if ( !q || jQuery.isArray(data) ) { + q = jQuery._data( elem, type, jQuery.makeArray(data) ); + } else { + q.push( data ); + } + } + return q || []; + } + }, + + dequeue: function( elem, type ) { + type = type || "fx"; + + var queue = jQuery.queue( elem, type ), + fn = queue.shift(), + hooks = {}; + + // If the fx queue is dequeued, always remove the progress sentinel + if ( fn === "inprogress" ) { + fn = queue.shift(); + } + + if ( fn ) { + // Add a progress sentinel to prevent the fx queue from being + // automatically dequeued + if ( type === "fx" ) { + queue.unshift( "inprogress" ); + } + + jQuery._data( elem, type + ".run", hooks ); + fn.call( elem, function() { + jQuery.dequeue( elem, type ); + }, hooks ); + } + + if ( !queue.length ) { + jQuery.removeData( elem, type + "queue " + type + ".run", true ); + handleQueueMarkDefer( elem, type, "queue" ); + } + } +}); + +jQuery.fn.extend({ + queue: function( type, data ) { + var setter = 2; + + if ( typeof type !== "string" ) { + data = type; + type = "fx"; + setter--; + } + + if ( arguments.length < setter ) { + return jQuery.queue( this[0], type ); + } + + return data === undefined ? + this : + this.each(function() { + var queue = jQuery.queue( this, type, data ); + + if ( type === "fx" && queue[0] !== "inprogress" ) { + jQuery.dequeue( this, type ); + } + }); + }, + dequeue: function( type ) { + return this.each(function() { + jQuery.dequeue( this, type ); + }); + }, + // Based off of the plugin by Clint Helfers, with permission. + // http://blindsignals.com/index.php/2009/07/jquery-delay/ + delay: function( time, type ) { + time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time; + type = type || "fx"; + + return this.queue( type, function( next, hooks ) { + var timeout = setTimeout( next, time ); + hooks.stop = function() { + clearTimeout( timeout ); + }; + }); + }, + clearQueue: function( type ) { + return this.queue( type || "fx", [] ); + }, + // Get a promise resolved when queues of a certain type + // are emptied (fx is the type by default) + promise: function( type, object ) { + if ( typeof type !== "string" ) { + object = type; + type = undefined; + } + type = type || "fx"; + var defer = jQuery.Deferred(), + elements = this, + i = elements.length, + count = 1, + deferDataKey = type + "defer", + queueDataKey = type + "queue", + markDataKey = type + "mark", + tmp; + function resolve() { + if ( !( --count ) ) { + defer.resolveWith( elements, [ elements ] ); + } + } + while( i-- ) { + if (( tmp = jQuery.data( elements[ i ], deferDataKey, undefined, true ) || + ( jQuery.data( elements[ i ], queueDataKey, undefined, true ) || + jQuery.data( elements[ i ], markDataKey, undefined, true ) ) && + jQuery.data( elements[ i ], deferDataKey, jQuery.Callbacks( "once memory" ), true ) )) { + count++; + tmp.add( resolve ); + } + } + resolve(); + return defer.promise( object ); + } +}); + + + + +var rclass = /[\n\t\r]/g, + rspace = /\s+/, + rreturn = /\r/g, + rtype = /^(?:button|input)$/i, + rfocusable = /^(?:button|input|object|select|textarea)$/i, + rclickable = /^a(?:rea)?$/i, + rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i, + getSetAttribute = jQuery.support.getSetAttribute, + nodeHook, boolHook, fixSpecified; + +jQuery.fn.extend({ + attr: function( name, value ) { + return jQuery.access( this, jQuery.attr, name, value, arguments.length > 1 ); + }, + + removeAttr: function( name ) { + return this.each(function() { + jQuery.removeAttr( this, name ); + }); + }, + + prop: function( name, value ) { + return jQuery.access( this, jQuery.prop, name, value, arguments.length > 1 ); + }, + + removeProp: function( name ) { + name = jQuery.propFix[ name ] || name; + return this.each(function() { + // try/catch handles cases where IE balks (such as removing a property on window) + try { + this[ name ] = undefined; + delete this[ name ]; + } catch( e ) {} + }); + }, + + addClass: function( value ) { + var classNames, i, l, elem, + setClass, c, cl; + + if ( jQuery.isFunction( value ) ) { + return this.each(function( j ) { + jQuery( this ).addClass( value.call(this, j, this.className) ); + }); + } + + if ( value && typeof value === "string" ) { + classNames = value.split( rspace ); + + for ( i = 0, l = this.length; i < l; i++ ) { + elem = this[ i ]; + + if ( elem.nodeType === 1 ) { + if ( !elem.className && classNames.length === 1 ) { + elem.className = value; + + } else { + setClass = " " + elem.className + " "; + + for ( c = 0, cl = classNames.length; c < cl; c++ ) { + if ( !~setClass.indexOf( " " + classNames[ c ] + " " ) ) { + setClass += classNames[ c ] + " "; + } + } + elem.className = jQuery.trim( setClass ); + } + } + } + } + + return this; + }, + + removeClass: function( value ) { + var classNames, i, l, elem, className, c, cl; + + if ( jQuery.isFunction( value ) ) { + return this.each(function( j ) { + jQuery( this ).removeClass( value.call(this, j, this.className) ); + }); + } + + if ( (value && typeof value === "string") || value === undefined ) { + classNames = ( value || "" ).split( rspace ); + + for ( i = 0, l = this.length; i < l; i++ ) { + elem = this[ i ]; + + if ( elem.nodeType === 1 && elem.className ) { + if ( value ) { + className = (" " + elem.className + " ").replace( rclass, " " ); + for ( c = 0, cl = classNames.length; c < cl; c++ ) { + className = className.replace(" " + classNames[ c ] + " ", " "); + } + elem.className = jQuery.trim( className ); + + } else { + elem.className = ""; + } + } + } + } + + return this; + }, + + toggleClass: function( value, stateVal ) { + var type = typeof value, + isBool = typeof stateVal === "boolean"; + + if ( jQuery.isFunction( value ) ) { + return this.each(function( i ) { + jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal ); + }); + } + + return this.each(function() { + if ( type === "string" ) { + // toggle individual class names + var className, + i = 0, + self = jQuery( this ), + state = stateVal, + classNames = value.split( rspace ); + + while ( (className = classNames[ i++ ]) ) { + // check each className given, space seperated list + state = isBool ? state : !self.hasClass( className ); + self[ state ? "addClass" : "removeClass" ]( className ); + } + + } else if ( type === "undefined" || type === "boolean" ) { + if ( this.className ) { + // store className if set + jQuery._data( this, "__className__", this.className ); + } + + // toggle whole className + this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || ""; + } + }); + }, + + hasClass: function( selector ) { + var className = " " + selector + " ", + i = 0, + l = this.length; + for ( ; i < l; i++ ) { + if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) { + return true; + } + } + + return false; + }, + + val: function( value ) { + var hooks, ret, isFunction, + elem = this[0]; + + if ( !arguments.length ) { + if ( elem ) { + hooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ]; + + if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) { + return ret; + } + + ret = elem.value; + + return typeof ret === "string" ? + // handle most common string cases + ret.replace(rreturn, "") : + // handle cases where value is null/undef or number + ret == null ? "" : ret; + } + + return; + } + + isFunction = jQuery.isFunction( value ); + + return this.each(function( i ) { + var self = jQuery(this), val; + + if ( this.nodeType !== 1 ) { + return; + } + + if ( isFunction ) { + val = value.call( this, i, self.val() ); + } else { + val = value; + } + + // Treat null/undefined as ""; convert numbers to string + if ( val == null ) { + val = ""; + } else if ( typeof val === "number" ) { + val += ""; + } else if ( jQuery.isArray( val ) ) { + val = jQuery.map(val, function ( value ) { + return value == null ? "" : value + ""; + }); + } + + hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ]; + + // If set returns undefined, fall back to normal setting + if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) { + this.value = val; + } + }); + } +}); + +jQuery.extend({ + valHooks: { + option: { + get: function( elem ) { + // attributes.value is undefined in Blackberry 4.7 but + // uses .value. See #6932 + var val = elem.attributes.value; + return !val || val.specified ? elem.value : elem.text; + } + }, + select: { + get: function( elem ) { + var value, i, max, option, + index = elem.selectedIndex, + values = [], + options = elem.options, + one = elem.type === "select-one"; + + // Nothing was selected + if ( index < 0 ) { + return null; + } + + // Loop through all the selected options + i = one ? index : 0; + max = one ? index + 1 : options.length; + for ( ; i < max; i++ ) { + option = options[ i ]; + + // Don't return options that are disabled or in a disabled optgroup + if ( option.selected && (jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null) && + (!option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" )) ) { + + // Get the specific value for the option + value = jQuery( option ).val(); + + // We don't need an array for one selects + if ( one ) { + return value; + } + + // Multi-Selects return an array + values.push( value ); + } + } + + // Fixes Bug #2551 -- select.val() broken in IE after form.reset() + if ( one && !values.length && options.length ) { + return jQuery( options[ index ] ).val(); + } + + return values; + }, + + set: function( elem, value ) { + var values = jQuery.makeArray( value ); + + jQuery(elem).find("option").each(function() { + this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0; + }); + + if ( !values.length ) { + elem.selectedIndex = -1; + } + return values; + } + } + }, + + attrFn: { + val: true, + css: true, + html: true, + text: true, + data: true, + width: true, + height: true, + offset: true + }, + + attr: function( elem, name, value, pass ) { + var ret, hooks, notxml, + nType = elem.nodeType; + + // don't get/set attributes on text, comment and attribute nodes + if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + if ( pass && name in jQuery.attrFn ) { + return jQuery( elem )[ name ]( value ); + } + + // Fallback to prop when attributes are not supported + if ( typeof elem.getAttribute === "undefined" ) { + return jQuery.prop( elem, name, value ); + } + + notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); + + // All attributes are lowercase + // Grab necessary hook if one is defined + if ( notxml ) { + name = name.toLowerCase(); + hooks = jQuery.attrHooks[ name ] || ( rboolean.test( name ) ? boolHook : nodeHook ); + } + + if ( value !== undefined ) { + + if ( value === null ) { + jQuery.removeAttr( elem, name ); + return; + + } else if ( hooks && "set" in hooks && notxml && (ret = hooks.set( elem, value, name )) !== undefined ) { + return ret; + + } else { + elem.setAttribute( name, "" + value ); + return value; + } + + } else if ( hooks && "get" in hooks && notxml && (ret = hooks.get( elem, name )) !== null ) { + return ret; + + } else { + + ret = elem.getAttribute( name ); + + // Non-existent attributes return null, we normalize to undefined + return ret === null ? + undefined : + ret; + } + }, + + removeAttr: function( elem, value ) { + var propName, attrNames, name, l, isBool, + i = 0; + + if ( value && elem.nodeType === 1 ) { + attrNames = value.toLowerCase().split( rspace ); + l = attrNames.length; + + for ( ; i < l; i++ ) { + name = attrNames[ i ]; + + if ( name ) { + propName = jQuery.propFix[ name ] || name; + isBool = rboolean.test( name ); + + // See #9699 for explanation of this approach (setting first, then removal) + // Do not do this for boolean attributes (see #10870) + if ( !isBool ) { + jQuery.attr( elem, name, "" ); + } + elem.removeAttribute( getSetAttribute ? name : propName ); + + // Set corresponding property to false for boolean attributes + if ( isBool && propName in elem ) { + elem[ propName ] = false; + } + } + } + } + }, + + attrHooks: { + type: { + set: function( elem, value ) { + // We can't allow the type property to be changed (since it causes problems in IE) + if ( rtype.test( elem.nodeName ) && elem.parentNode ) { + jQuery.error( "type property can't be changed" ); + } else if ( !jQuery.support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) { + // Setting the type on a radio button after the value resets the value in IE6-9 + // Reset value to it's default in case type is set after value + // This is for element creation + var val = elem.value; + elem.setAttribute( "type", value ); + if ( val ) { + elem.value = val; + } + return value; + } + } + }, + // Use the value property for back compat + // Use the nodeHook for button elements in IE6/7 (#1954) + value: { + get: function( elem, name ) { + if ( nodeHook && jQuery.nodeName( elem, "button" ) ) { + return nodeHook.get( elem, name ); + } + return name in elem ? + elem.value : + null; + }, + set: function( elem, value, name ) { + if ( nodeHook && jQuery.nodeName( elem, "button" ) ) { + return nodeHook.set( elem, value, name ); + } + // Does not return so that setAttribute is also used + elem.value = value; + } + } + }, + + propFix: { + tabindex: "tabIndex", + readonly: "readOnly", + "for": "htmlFor", + "class": "className", + maxlength: "maxLength", + cellspacing: "cellSpacing", + cellpadding: "cellPadding", + rowspan: "rowSpan", + colspan: "colSpan", + usemap: "useMap", + frameborder: "frameBorder", + contenteditable: "contentEditable" + }, + + prop: function( elem, name, value ) { + var ret, hooks, notxml, + nType = elem.nodeType; + + // don't get/set properties on text, comment and attribute nodes + if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); + + if ( notxml ) { + // Fix name and attach hooks + name = jQuery.propFix[ name ] || name; + hooks = jQuery.propHooks[ name ]; + } + + if ( value !== undefined ) { + if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) { + return ret; + + } else { + return ( elem[ name ] = value ); + } + + } else { + if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) { + return ret; + + } else { + return elem[ name ]; + } + } + }, + + propHooks: { + tabIndex: { + get: function( elem ) { + // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set + // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ + var attributeNode = elem.getAttributeNode("tabindex"); + + return attributeNode && attributeNode.specified ? + parseInt( attributeNode.value, 10 ) : + rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ? + 0 : + undefined; + } + } + } +}); + +// Add the tabIndex propHook to attrHooks for back-compat (different case is intentional) +jQuery.attrHooks.tabindex = jQuery.propHooks.tabIndex; + +// Hook for boolean attributes +boolHook = { + get: function( elem, name ) { + // Align boolean attributes with corresponding properties + // Fall back to attribute presence where some booleans are not supported + var attrNode, + property = jQuery.prop( elem, name ); + return property === true || typeof property !== "boolean" && ( attrNode = elem.getAttributeNode(name) ) && attrNode.nodeValue !== false ? + name.toLowerCase() : + undefined; + }, + set: function( elem, value, name ) { + var propName; + if ( value === false ) { + // Remove boolean attributes when set to false + jQuery.removeAttr( elem, name ); + } else { + // value is true since we know at this point it's type boolean and not false + // Set boolean attributes to the same name and set the DOM property + propName = jQuery.propFix[ name ] || name; + if ( propName in elem ) { + // Only set the IDL specifically if it already exists on the element + elem[ propName ] = true; + } + + elem.setAttribute( name, name.toLowerCase() ); + } + return name; + } +}; + +// IE6/7 do not support getting/setting some attributes with get/setAttribute +if ( !getSetAttribute ) { + + fixSpecified = { + name: true, + id: true, + coords: true + }; + + // Use this for any attribute in IE6/7 + // This fixes almost every IE6/7 issue + nodeHook = jQuery.valHooks.button = { + get: function( elem, name ) { + var ret; + ret = elem.getAttributeNode( name ); + return ret && ( fixSpecified[ name ] ? ret.nodeValue !== "" : ret.specified ) ? + ret.nodeValue : + undefined; + }, + set: function( elem, value, name ) { + // Set the existing or create a new attribute node + var ret = elem.getAttributeNode( name ); + if ( !ret ) { + ret = document.createAttribute( name ); + elem.setAttributeNode( ret ); + } + return ( ret.nodeValue = value + "" ); + } + }; + + // Apply the nodeHook to tabindex + jQuery.attrHooks.tabindex.set = nodeHook.set; + + // Set width and height to auto instead of 0 on empty string( Bug #8150 ) + // This is for removals + jQuery.each([ "width", "height" ], function( i, name ) { + jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], { + set: function( elem, value ) { + if ( value === "" ) { + elem.setAttribute( name, "auto" ); + return value; + } + } + }); + }); + + // Set contenteditable to false on removals(#10429) + // Setting to empty string throws an error as an invalid value + jQuery.attrHooks.contenteditable = { + get: nodeHook.get, + set: function( elem, value, name ) { + if ( value === "" ) { + value = "false"; + } + nodeHook.set( elem, value, name ); + } + }; +} + + +// Some attributes require a special call on IE +if ( !jQuery.support.hrefNormalized ) { + jQuery.each([ "href", "src", "width", "height" ], function( i, name ) { + jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], { + get: function( elem ) { + var ret = elem.getAttribute( name, 2 ); + return ret === null ? undefined : ret; + } + }); + }); +} + +if ( !jQuery.support.style ) { + jQuery.attrHooks.style = { + get: function( elem ) { + // Return undefined in the case of empty string + // Normalize to lowercase since IE uppercases css property names + return elem.style.cssText.toLowerCase() || undefined; + }, + set: function( elem, value ) { + return ( elem.style.cssText = "" + value ); + } + }; +} + +// Safari mis-reports the default selected property of an option +// Accessing the parent's selectedIndex property fixes it +if ( !jQuery.support.optSelected ) { + jQuery.propHooks.selected = jQuery.extend( jQuery.propHooks.selected, { + get: function( elem ) { + var parent = elem.parentNode; + + if ( parent ) { + parent.selectedIndex; + + // Make sure that it also works with optgroups, see #5701 + if ( parent.parentNode ) { + parent.parentNode.selectedIndex; + } + } + return null; + } + }); +} + +// IE6/7 call enctype encoding +if ( !jQuery.support.enctype ) { + jQuery.propFix.enctype = "encoding"; +} + +// Radios and checkboxes getter/setter +if ( !jQuery.support.checkOn ) { + jQuery.each([ "radio", "checkbox" ], function() { + jQuery.valHooks[ this ] = { + get: function( elem ) { + // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified + return elem.getAttribute("value") === null ? "on" : elem.value; + } + }; + }); +} +jQuery.each([ "radio", "checkbox" ], function() { + jQuery.valHooks[ this ] = jQuery.extend( jQuery.valHooks[ this ], { + set: function( elem, value ) { + if ( jQuery.isArray( value ) ) { + return ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 ); + } + } + }); +}); + + + + +var rformElems = /^(?:textarea|input|select)$/i, + rtypenamespace = /^([^\.]*)?(?:\.(.+))?$/, + rhoverHack = /(?:^|\s)hover(\.\S+)?\b/, + rkeyEvent = /^key/, + rmouseEvent = /^(?:mouse|contextmenu)|click/, + rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, + rquickIs = /^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/, + quickParse = function( selector ) { + var quick = rquickIs.exec( selector ); + if ( quick ) { + // 0 1 2 3 + // [ _, tag, id, class ] + quick[1] = ( quick[1] || "" ).toLowerCase(); + quick[3] = quick[3] && new RegExp( "(?:^|\\s)" + quick[3] + "(?:\\s|$)" ); + } + return quick; + }, + quickIs = function( elem, m ) { + var attrs = elem.attributes || {}; + return ( + (!m[1] || elem.nodeName.toLowerCase() === m[1]) && + (!m[2] || (attrs.id || {}).value === m[2]) && + (!m[3] || m[3].test( (attrs[ "class" ] || {}).value )) + ); + }, + hoverHack = function( events ) { + return jQuery.event.special.hover ? events : events.replace( rhoverHack, "mouseenter$1 mouseleave$1" ); + }; + +/* + * Helper functions for managing events -- not part of the public interface. + * Props to Dean Edwards' addEvent library for many of the ideas. + */ +jQuery.event = { + + add: function( elem, types, handler, data, selector ) { + + var elemData, eventHandle, events, + t, tns, type, namespaces, handleObj, + handleObjIn, quick, handlers, special; + + // Don't attach events to noData or text/comment nodes (allow plain objects tho) + if ( elem.nodeType === 3 || elem.nodeType === 8 || !types || !handler || !(elemData = jQuery._data( elem )) ) { + return; + } + + // Caller can pass in an object of custom data in lieu of the handler + if ( handler.handler ) { + handleObjIn = handler; + handler = handleObjIn.handler; + selector = handleObjIn.selector; + } + + // Make sure that the handler has a unique ID, used to find/remove it later + if ( !handler.guid ) { + handler.guid = jQuery.guid++; + } + + // Init the element's event structure and main handler, if this is the first + events = elemData.events; + if ( !events ) { + elemData.events = events = {}; + } + eventHandle = elemData.handle; + if ( !eventHandle ) { + elemData.handle = eventHandle = function( e ) { + // Discard the second event of a jQuery.event.trigger() and + // when an event is called after a page has unloaded + return typeof jQuery !== "undefined" && (!e || jQuery.event.triggered !== e.type) ? + jQuery.event.dispatch.apply( eventHandle.elem, arguments ) : + undefined; + }; + // Add elem as a property of the handle fn to prevent a memory leak with IE non-native events + eventHandle.elem = elem; + } + + // Handle multiple events separated by a space + // jQuery(...).bind("mouseover mouseout", fn); + types = jQuery.trim( hoverHack(types) ).split( " " ); + for ( t = 0; t < types.length; t++ ) { + + tns = rtypenamespace.exec( types[t] ) || []; + type = tns[1]; + namespaces = ( tns[2] || "" ).split( "." ).sort(); + + // If event changes its type, use the special event handlers for the changed type + special = jQuery.event.special[ type ] || {}; + + // If selector defined, determine special event api type, otherwise given type + type = ( selector ? special.delegateType : special.bindType ) || type; + + // Update special based on newly reset type + special = jQuery.event.special[ type ] || {}; + + // handleObj is passed to all event handlers + handleObj = jQuery.extend({ + type: type, + origType: tns[1], + data: data, + handler: handler, + guid: handler.guid, + selector: selector, + quick: selector && quickParse( selector ), + namespace: namespaces.join(".") + }, handleObjIn ); + + // Init the event handler queue if we're the first + handlers = events[ type ]; + if ( !handlers ) { + handlers = events[ type ] = []; + handlers.delegateCount = 0; + + // Only use addEventListener/attachEvent if the special events handler returns false + if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) { + // Bind the global event handler to the element + if ( elem.addEventListener ) { + elem.addEventListener( type, eventHandle, false ); + + } else if ( elem.attachEvent ) { + elem.attachEvent( "on" + type, eventHandle ); + } + } + } + + if ( special.add ) { + special.add.call( elem, handleObj ); + + if ( !handleObj.handler.guid ) { + handleObj.handler.guid = handler.guid; + } + } + + // Add to the element's handler list, delegates in front + if ( selector ) { + handlers.splice( handlers.delegateCount++, 0, handleObj ); + } else { + handlers.push( handleObj ); + } + + // Keep track of which events have ever been used, for event optimization + jQuery.event.global[ type ] = true; + } + + // Nullify elem to prevent memory leaks in IE + elem = null; + }, + + global: {}, + + // Detach an event or set of events from an element + remove: function( elem, types, handler, selector, mappedTypes ) { + + var elemData = jQuery.hasData( elem ) && jQuery._data( elem ), + t, tns, type, origType, namespaces, origCount, + j, events, special, handle, eventType, handleObj; + + if ( !elemData || !(events = elemData.events) ) { + return; + } + + // Once for each type.namespace in types; type may be omitted + types = jQuery.trim( hoverHack( types || "" ) ).split(" "); + for ( t = 0; t < types.length; t++ ) { + tns = rtypenamespace.exec( types[t] ) || []; + type = origType = tns[1]; + namespaces = tns[2]; + + // Unbind all events (on this namespace, if provided) for the element + if ( !type ) { + for ( type in events ) { + jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); + } + continue; + } + + special = jQuery.event.special[ type ] || {}; + type = ( selector? special.delegateType : special.bindType ) || type; + eventType = events[ type ] || []; + origCount = eventType.length; + namespaces = namespaces ? new RegExp("(^|\\.)" + namespaces.split(".").sort().join("\\.(?:.*\\.)?") + "(\\.|$)") : null; + + // Remove matching events + for ( j = 0; j < eventType.length; j++ ) { + handleObj = eventType[ j ]; + + if ( ( mappedTypes || origType === handleObj.origType ) && + ( !handler || handler.guid === handleObj.guid ) && + ( !namespaces || namespaces.test( handleObj.namespace ) ) && + ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) { + eventType.splice( j--, 1 ); + + if ( handleObj.selector ) { + eventType.delegateCount--; + } + if ( special.remove ) { + special.remove.call( elem, handleObj ); + } + } + } + + // Remove generic event handler if we removed something and no more handlers exist + // (avoids potential for endless recursion during removal of special event handlers) + if ( eventType.length === 0 && origCount !== eventType.length ) { + if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) { + jQuery.removeEvent( elem, type, elemData.handle ); + } + + delete events[ type ]; + } + } + + // Remove the expando if it's no longer used + if ( jQuery.isEmptyObject( events ) ) { + handle = elemData.handle; + if ( handle ) { + handle.elem = null; + } + + // removeData also checks for emptiness and clears the expando if empty + // so use it instead of delete + jQuery.removeData( elem, [ "events", "handle" ], true ); + } + }, + + // Events that are safe to short-circuit if no handlers are attached. + // Native DOM events should not be added, they may have inline handlers. + customEvent: { + "getData": true, + "setData": true, + "changeData": true + }, + + trigger: function( event, data, elem, onlyHandlers ) { + // Don't do events on text and comment nodes + if ( elem && (elem.nodeType === 3 || elem.nodeType === 8) ) { + return; + } + + // Event object or event type + var type = event.type || event, + namespaces = [], + cache, exclusive, i, cur, old, ontype, special, handle, eventPath, bubbleType; + + // focus/blur morphs to focusin/out; ensure we're not firing them right now + if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { + return; + } + + if ( type.indexOf( "!" ) >= 0 ) { + // Exclusive events trigger only for the exact event (no namespaces) + type = type.slice(0, -1); + exclusive = true; + } + + if ( type.indexOf( "." ) >= 0 ) { + // Namespaced trigger; create a regexp to match event type in handle() + namespaces = type.split("."); + type = namespaces.shift(); + namespaces.sort(); + } + + if ( (!elem || jQuery.event.customEvent[ type ]) && !jQuery.event.global[ type ] ) { + // No jQuery handlers for this event type, and it can't have inline handlers + return; + } + + // Caller can pass in an Event, Object, or just an event type string + event = typeof event === "object" ? + // jQuery.Event object + event[ jQuery.expando ] ? event : + // Object literal + new jQuery.Event( type, event ) : + // Just the event type (string) + new jQuery.Event( type ); + + event.type = type; + event.isTrigger = true; + event.exclusive = exclusive; + event.namespace = namespaces.join( "." ); + event.namespace_re = event.namespace? new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.)?") + "(\\.|$)") : null; + ontype = type.indexOf( ":" ) < 0 ? "on" + type : ""; + + // Handle a global trigger + if ( !elem ) { + + // TODO: Stop taunting the data cache; remove global events and always attach to document + cache = jQuery.cache; + for ( i in cache ) { + if ( cache[ i ].events && cache[ i ].events[ type ] ) { + jQuery.event.trigger( event, data, cache[ i ].handle.elem, true ); + } + } + return; + } + + // Clean up the event in case it is being reused + event.result = undefined; + if ( !event.target ) { + event.target = elem; + } + + // Clone any incoming data and prepend the event, creating the handler arg list + data = data != null ? jQuery.makeArray( data ) : []; + data.unshift( event ); + + // Allow special events to draw outside the lines + special = jQuery.event.special[ type ] || {}; + if ( special.trigger && special.trigger.apply( elem, data ) === false ) { + return; + } + + // Determine event propagation path in advance, per W3C events spec (#9951) + // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) + eventPath = [[ elem, special.bindType || type ]]; + if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) { + + bubbleType = special.delegateType || type; + cur = rfocusMorph.test( bubbleType + type ) ? elem : elem.parentNode; + old = null; + for ( ; cur; cur = cur.parentNode ) { + eventPath.push([ cur, bubbleType ]); + old = cur; + } + + // Only add window if we got to document (e.g., not plain obj or detached DOM) + if ( old && old === elem.ownerDocument ) { + eventPath.push([ old.defaultView || old.parentWindow || window, bubbleType ]); + } + } + + // Fire handlers on the event path + for ( i = 0; i < eventPath.length && !event.isPropagationStopped(); i++ ) { + + cur = eventPath[i][0]; + event.type = eventPath[i][1]; + + handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] && jQuery._data( cur, "handle" ); + if ( handle ) { + handle.apply( cur, data ); + } + // Note that this is a bare JS function and not a jQuery handler + handle = ontype && cur[ ontype ]; + if ( handle && jQuery.acceptData( cur ) && handle.apply( cur, data ) === false ) { + event.preventDefault(); + } + } + event.type = type; + + // If nobody prevented the default action, do it now + if ( !onlyHandlers && !event.isDefaultPrevented() ) { + + if ( (!special._default || special._default.apply( elem.ownerDocument, data ) === false) && + !(type === "click" && jQuery.nodeName( elem, "a" )) && jQuery.acceptData( elem ) ) { + + // Call a native DOM method on the target with the same name name as the event. + // Can't use an .isFunction() check here because IE6/7 fails that test. + // Don't do default actions on window, that's where global variables be (#6170) + // IE<9 dies on focus/blur to hidden element (#1486) + if ( ontype && elem[ type ] && ((type !== "focus" && type !== "blur") || event.target.offsetWidth !== 0) && !jQuery.isWindow( elem ) ) { + + // Don't re-trigger an onFOO event when we call its FOO() method + old = elem[ ontype ]; + + if ( old ) { + elem[ ontype ] = null; + } + + // Prevent re-triggering of the same event, since we already bubbled it above + jQuery.event.triggered = type; + elem[ type ](); + jQuery.event.triggered = undefined; + + if ( old ) { + elem[ ontype ] = old; + } + } + } + } + + return event.result; + }, + + dispatch: function( event ) { + + // Make a writable jQuery.Event from the native event object + event = jQuery.event.fix( event || window.event ); + + var handlers = ( (jQuery._data( this, "events" ) || {} )[ event.type ] || []), + delegateCount = handlers.delegateCount, + args = [].slice.call( arguments, 0 ), + run_all = !event.exclusive && !event.namespace, + special = jQuery.event.special[ event.type ] || {}, + handlerQueue = [], + i, j, cur, jqcur, ret, selMatch, matched, matches, handleObj, sel, related; + + // Use the fix-ed jQuery.Event rather than the (read-only) native event + args[0] = event; + event.delegateTarget = this; + + // Call the preDispatch hook for the mapped type, and let it bail if desired + if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { + return; + } + + // Determine handlers that should run if there are delegated events + // Avoid non-left-click bubbling in Firefox (#3861) + if ( delegateCount && !(event.button && event.type === "click") ) { + + // Pregenerate a single jQuery object for reuse with .is() + jqcur = jQuery(this); + jqcur.context = this.ownerDocument || this; + + for ( cur = event.target; cur != this; cur = cur.parentNode || this ) { + + // Don't process events on disabled elements (#6911, #8165) + if ( cur.disabled !== true ) { + selMatch = {}; + matches = []; + jqcur[0] = cur; + for ( i = 0; i < delegateCount; i++ ) { + handleObj = handlers[ i ]; + sel = handleObj.selector; + + if ( selMatch[ sel ] === undefined ) { + selMatch[ sel ] = ( + handleObj.quick ? quickIs( cur, handleObj.quick ) : jqcur.is( sel ) + ); + } + if ( selMatch[ sel ] ) { + matches.push( handleObj ); + } + } + if ( matches.length ) { + handlerQueue.push({ elem: cur, matches: matches }); + } + } + } + } + + // Add the remaining (directly-bound) handlers + if ( handlers.length > delegateCount ) { + handlerQueue.push({ elem: this, matches: handlers.slice( delegateCount ) }); + } + + // Run delegates first; they may want to stop propagation beneath us + for ( i = 0; i < handlerQueue.length && !event.isPropagationStopped(); i++ ) { + matched = handlerQueue[ i ]; + event.currentTarget = matched.elem; + + for ( j = 0; j < matched.matches.length && !event.isImmediatePropagationStopped(); j++ ) { + handleObj = matched.matches[ j ]; + + // Triggered event must either 1) be non-exclusive and have no namespace, or + // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace). + if ( run_all || (!event.namespace && !handleObj.namespace) || event.namespace_re && event.namespace_re.test( handleObj.namespace ) ) { + + event.data = handleObj.data; + event.handleObj = handleObj; + + ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler ) + .apply( matched.elem, args ); + + if ( ret !== undefined ) { + event.result = ret; + if ( ret === false ) { + event.preventDefault(); + event.stopPropagation(); + } + } + } + } + } + + // Call the postDispatch hook for the mapped type + if ( special.postDispatch ) { + special.postDispatch.call( this, event ); + } + + return event.result; + }, + + // Includes some event props shared by KeyEvent and MouseEvent + // *** attrChange attrName relatedNode srcElement are not normalized, non-W3C, deprecated, will be removed in 1.8 *** + props: "attrChange attrName relatedNode srcElement altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "), + + fixHooks: {}, + + keyHooks: { + props: "char charCode key keyCode".split(" "), + filter: function( event, original ) { + + // Add which for key events + if ( event.which == null ) { + event.which = original.charCode != null ? original.charCode : original.keyCode; + } + + return event; + } + }, + + mouseHooks: { + props: "button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "), + filter: function( event, original ) { + var eventDoc, doc, body, + button = original.button, + fromElement = original.fromElement; + + // Calculate pageX/Y if missing and clientX/Y available + if ( event.pageX == null && original.clientX != null ) { + eventDoc = event.target.ownerDocument || document; + doc = eventDoc.documentElement; + body = eventDoc.body; + + event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 ); + event.pageY = original.clientY + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - ( doc && doc.clientTop || body && body.clientTop || 0 ); + } + + // Add relatedTarget, if necessary + if ( !event.relatedTarget && fromElement ) { + event.relatedTarget = fromElement === event.target ? original.toElement : fromElement; + } + + // Add which for click: 1 === left; 2 === middle; 3 === right + // Note: button is not normalized, so don't use it + if ( !event.which && button !== undefined ) { + event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) ); + } + + return event; + } + }, + + fix: function( event ) { + if ( event[ jQuery.expando ] ) { + return event; + } + + // Create a writable copy of the event object and normalize some properties + var i, prop, + originalEvent = event, + fixHook = jQuery.event.fixHooks[ event.type ] || {}, + copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props; + + event = jQuery.Event( originalEvent ); + + for ( i = copy.length; i; ) { + prop = copy[ --i ]; + event[ prop ] = originalEvent[ prop ]; + } + + // Fix target property, if necessary (#1925, IE 6/7/8 & Safari2) + if ( !event.target ) { + event.target = originalEvent.srcElement || document; + } + + // Target should not be a text node (#504, Safari) + if ( event.target.nodeType === 3 ) { + event.target = event.target.parentNode; + } + + // For mouse/key events; add metaKey if it's not there (#3368, IE6/7/8) + if ( event.metaKey === undefined ) { + event.metaKey = event.ctrlKey; + } + + return fixHook.filter? fixHook.filter( event, originalEvent ) : event; + }, + + special: { + ready: { + // Make sure the ready event is setup + setup: jQuery.bindReady + }, + + load: { + // Prevent triggered image.load events from bubbling to window.load + noBubble: true + }, + + focus: { + delegateType: "focusin" + }, + blur: { + delegateType: "focusout" + }, + + beforeunload: { + setup: function( data, namespaces, eventHandle ) { + // We only want to do this special case on windows + if ( jQuery.isWindow( this ) ) { + this.onbeforeunload = eventHandle; + } + }, + + teardown: function( namespaces, eventHandle ) { + if ( this.onbeforeunload === eventHandle ) { + this.onbeforeunload = null; + } + } + } + }, + + simulate: function( type, elem, event, bubble ) { + // Piggyback on a donor event to simulate a different one. + // Fake originalEvent to avoid donor's stopPropagation, but if the + // simulated event prevents default then we do the same on the donor. + var e = jQuery.extend( + new jQuery.Event(), + event, + { type: type, + isSimulated: true, + originalEvent: {} + } + ); + if ( bubble ) { + jQuery.event.trigger( e, null, elem ); + } else { + jQuery.event.dispatch.call( elem, e ); + } + if ( e.isDefaultPrevented() ) { + event.preventDefault(); + } + } +}; + +// Some plugins are using, but it's undocumented/deprecated and will be removed. +// The 1.7 special event interface should provide all the hooks needed now. +jQuery.event.handle = jQuery.event.dispatch; + +jQuery.removeEvent = document.removeEventListener ? + function( elem, type, handle ) { + if ( elem.removeEventListener ) { + elem.removeEventListener( type, handle, false ); + } + } : + function( elem, type, handle ) { + if ( elem.detachEvent ) { + elem.detachEvent( "on" + type, handle ); + } + }; + +jQuery.Event = function( src, props ) { + // Allow instantiation without the 'new' keyword + if ( !(this instanceof jQuery.Event) ) { + return new jQuery.Event( src, props ); + } + + // Event object + if ( src && src.type ) { + this.originalEvent = src; + this.type = src.type; + + // Events bubbling up the document may have been marked as prevented + // by a handler lower down the tree; reflect the correct value. + this.isDefaultPrevented = ( src.defaultPrevented || src.returnValue === false || + src.getPreventDefault && src.getPreventDefault() ) ? returnTrue : returnFalse; + + // Event type + } else { + this.type = src; + } + + // Put explicitly provided properties onto the event object + if ( props ) { + jQuery.extend( this, props ); + } + + // Create a timestamp if incoming event doesn't have one + this.timeStamp = src && src.timeStamp || jQuery.now(); + + // Mark it as fixed + this[ jQuery.expando ] = true; +}; + +function returnFalse() { + return false; +} +function returnTrue() { + return true; +} + +// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding +// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html +jQuery.Event.prototype = { + preventDefault: function() { + this.isDefaultPrevented = returnTrue; + + var e = this.originalEvent; + if ( !e ) { + return; + } + + // if preventDefault exists run it on the original event + if ( e.preventDefault ) { + e.preventDefault(); + + // otherwise set the returnValue property of the original event to false (IE) + } else { + e.returnValue = false; + } + }, + stopPropagation: function() { + this.isPropagationStopped = returnTrue; + + var e = this.originalEvent; + if ( !e ) { + return; + } + // if stopPropagation exists run it on the original event + if ( e.stopPropagation ) { + e.stopPropagation(); + } + // otherwise set the cancelBubble property of the original event to true (IE) + e.cancelBubble = true; + }, + stopImmediatePropagation: function() { + this.isImmediatePropagationStopped = returnTrue; + this.stopPropagation(); + }, + isDefaultPrevented: returnFalse, + isPropagationStopped: returnFalse, + isImmediatePropagationStopped: returnFalse +}; + +// Create mouseenter/leave events using mouseover/out and event-time checks +jQuery.each({ + mouseenter: "mouseover", + mouseleave: "mouseout" +}, function( orig, fix ) { + jQuery.event.special[ orig ] = { + delegateType: fix, + bindType: fix, + + handle: function( event ) { + var target = this, + related = event.relatedTarget, + handleObj = event.handleObj, + selector = handleObj.selector, + ret; + + // For mousenter/leave call the handler if related is outside the target. + // NB: No relatedTarget if the mouse left/entered the browser window + if ( !related || (related !== target && !jQuery.contains( target, related )) ) { + event.type = handleObj.origType; + ret = handleObj.handler.apply( this, arguments ); + event.type = fix; + } + return ret; + } + }; +}); + +// IE submit delegation +if ( !jQuery.support.submitBubbles ) { + + jQuery.event.special.submit = { + setup: function() { + // Only need this for delegated form submit events + if ( jQuery.nodeName( this, "form" ) ) { + return false; + } + + // Lazy-add a submit handler when a descendant form may potentially be submitted + jQuery.event.add( this, "click._submit keypress._submit", function( e ) { + // Node name check avoids a VML-related crash in IE (#9807) + var elem = e.target, + form = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ? elem.form : undefined; + if ( form && !form._submit_attached ) { + jQuery.event.add( form, "submit._submit", function( event ) { + event._submit_bubble = true; + }); + form._submit_attached = true; + } + }); + // return undefined since we don't need an event listener + }, + + postDispatch: function( event ) { + // If form was submitted by the user, bubble the event up the tree + if ( event._submit_bubble ) { + delete event._submit_bubble; + if ( this.parentNode && !event.isTrigger ) { + jQuery.event.simulate( "submit", this.parentNode, event, true ); + } + } + }, + + teardown: function() { + // Only need this for delegated form submit events + if ( jQuery.nodeName( this, "form" ) ) { + return false; + } + + // Remove delegated handlers; cleanData eventually reaps submit handlers attached above + jQuery.event.remove( this, "._submit" ); + } + }; +} + +// IE change delegation and checkbox/radio fix +if ( !jQuery.support.changeBubbles ) { + + jQuery.event.special.change = { + + setup: function() { + + if ( rformElems.test( this.nodeName ) ) { + // IE doesn't fire change on a check/radio until blur; trigger it on click + // after a propertychange. Eat the blur-change in special.change.handle. + // This still fires onchange a second time for check/radio after blur. + if ( this.type === "checkbox" || this.type === "radio" ) { + jQuery.event.add( this, "propertychange._change", function( event ) { + if ( event.originalEvent.propertyName === "checked" ) { + this._just_changed = true; + } + }); + jQuery.event.add( this, "click._change", function( event ) { + if ( this._just_changed && !event.isTrigger ) { + this._just_changed = false; + jQuery.event.simulate( "change", this, event, true ); + } + }); + } + return false; + } + // Delegated event; lazy-add a change handler on descendant inputs + jQuery.event.add( this, "beforeactivate._change", function( e ) { + var elem = e.target; + + if ( rformElems.test( elem.nodeName ) && !elem._change_attached ) { + jQuery.event.add( elem, "change._change", function( event ) { + if ( this.parentNode && !event.isSimulated && !event.isTrigger ) { + jQuery.event.simulate( "change", this.parentNode, event, true ); + } + }); + elem._change_attached = true; + } + }); + }, + + handle: function( event ) { + var elem = event.target; + + // Swallow native change events from checkbox/radio, we already triggered them above + if ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== "radio" && elem.type !== "checkbox") ) { + return event.handleObj.handler.apply( this, arguments ); + } + }, + + teardown: function() { + jQuery.event.remove( this, "._change" ); + + return rformElems.test( this.nodeName ); + } + }; +} + +// Create "bubbling" focus and blur events +if ( !jQuery.support.focusinBubbles ) { + jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) { + + // Attach a single capturing handler while someone wants focusin/focusout + var attaches = 0, + handler = function( event ) { + jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true ); + }; + + jQuery.event.special[ fix ] = { + setup: function() { + if ( attaches++ === 0 ) { + document.addEventListener( orig, handler, true ); + } + }, + teardown: function() { + if ( --attaches === 0 ) { + document.removeEventListener( orig, handler, true ); + } + } + }; + }); +} + +jQuery.fn.extend({ + + on: function( types, selector, data, fn, /*INTERNAL*/ one ) { + var origFn, type; + + // Types can be a map of types/handlers + if ( typeof types === "object" ) { + // ( types-Object, selector, data ) + if ( typeof selector !== "string" ) { // && selector != null + // ( types-Object, data ) + data = data || selector; + selector = undefined; + } + for ( type in types ) { + this.on( type, selector, data, types[ type ], one ); + } + return this; + } + + if ( data == null && fn == null ) { + // ( types, fn ) + fn = selector; + data = selector = undefined; + } else if ( fn == null ) { + if ( typeof selector === "string" ) { + // ( types, selector, fn ) + fn = data; + data = undefined; + } else { + // ( types, data, fn ) + fn = data; + data = selector; + selector = undefined; + } + } + if ( fn === false ) { + fn = returnFalse; + } else if ( !fn ) { + return this; + } + + if ( one === 1 ) { + origFn = fn; + fn = function( event ) { + // Can use an empty set, since event contains the info + jQuery().off( event ); + return origFn.apply( this, arguments ); + }; + // Use same guid so caller can remove using origFn + fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); + } + return this.each( function() { + jQuery.event.add( this, types, fn, data, selector ); + }); + }, + one: function( types, selector, data, fn ) { + return this.on( types, selector, data, fn, 1 ); + }, + off: function( types, selector, fn ) { + if ( types && types.preventDefault && types.handleObj ) { + // ( event ) dispatched jQuery.Event + var handleObj = types.handleObj; + jQuery( types.delegateTarget ).off( + handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType, + handleObj.selector, + handleObj.handler + ); + return this; + } + if ( typeof types === "object" ) { + // ( types-object [, selector] ) + for ( var type in types ) { + this.off( type, selector, types[ type ] ); + } + return this; + } + if ( selector === false || typeof selector === "function" ) { + // ( types [, fn] ) + fn = selector; + selector = undefined; + } + if ( fn === false ) { + fn = returnFalse; + } + return this.each(function() { + jQuery.event.remove( this, types, fn, selector ); + }); + }, + + bind: function( types, data, fn ) { + return this.on( types, null, data, fn ); + }, + unbind: function( types, fn ) { + return this.off( types, null, fn ); + }, + + live: function( types, data, fn ) { + jQuery( this.context ).on( types, this.selector, data, fn ); + return this; + }, + die: function( types, fn ) { + jQuery( this.context ).off( types, this.selector || "**", fn ); + return this; + }, + + delegate: function( selector, types, data, fn ) { + return this.on( types, selector, data, fn ); + }, + undelegate: function( selector, types, fn ) { + // ( namespace ) or ( selector, types [, fn] ) + return arguments.length == 1? this.off( selector, "**" ) : this.off( types, selector, fn ); + }, + + trigger: function( type, data ) { + return this.each(function() { + jQuery.event.trigger( type, data, this ); + }); + }, + triggerHandler: function( type, data ) { + if ( this[0] ) { + return jQuery.event.trigger( type, data, this[0], true ); + } + }, + + toggle: function( fn ) { + // Save reference to arguments for access in closure + var args = arguments, + guid = fn.guid || jQuery.guid++, + i = 0, + toggler = function( event ) { + // Figure out which function to execute + var lastToggle = ( jQuery._data( this, "lastToggle" + fn.guid ) || 0 ) % i; + jQuery._data( this, "lastToggle" + fn.guid, lastToggle + 1 ); + + // Make sure that clicks stop + event.preventDefault(); + + // and execute the function + return args[ lastToggle ].apply( this, arguments ) || false; + }; + + // link all the functions, so any of them can unbind this click handler + toggler.guid = guid; + while ( i < args.length ) { + args[ i++ ].guid = guid; + } + + return this.click( toggler ); + }, + + hover: function( fnOver, fnOut ) { + return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver ); + } +}); + +jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " + + "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " + + "change select submit keydown keypress keyup error contextmenu").split(" "), function( i, name ) { + + // Handle event binding + jQuery.fn[ name ] = function( data, fn ) { + if ( fn == null ) { + fn = data; + data = null; + } + + return arguments.length > 0 ? + this.on( name, null, data, fn ) : + this.trigger( name ); + }; + + if ( jQuery.attrFn ) { + jQuery.attrFn[ name ] = true; + } + + if ( rkeyEvent.test( name ) ) { + jQuery.event.fixHooks[ name ] = jQuery.event.keyHooks; + } + + if ( rmouseEvent.test( name ) ) { + jQuery.event.fixHooks[ name ] = jQuery.event.mouseHooks; + } +}); + + + +/*! + * Sizzle CSS Selector Engine + * Copyright 2011, The Dojo Foundation + * Released under the MIT, BSD, and GPL Licenses. + * More information: http://sizzlejs.com/ + */ +(function(){ + +var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g, + expando = "sizcache" + (Math.random() + '').replace('.', ''), + done = 0, + toString = Object.prototype.toString, + hasDuplicate = false, + baseHasDuplicate = true, + rBackslash = /\\/g, + rReturn = /\r\n/g, + rNonWord = /\W/; + +// Here we check if the JavaScript engine is using some sort of +// optimization where it does not always call our comparision +// function. If that is the case, discard the hasDuplicate value. +// Thus far that includes Google Chrome. +[0, 0].sort(function() { + baseHasDuplicate = false; + return 0; +}); + +var Sizzle = function( selector, context, results, seed ) { + results = results || []; + context = context || document; + + var origContext = context; + + if ( context.nodeType !== 1 && context.nodeType !== 9 ) { + return []; + } + + if ( !selector || typeof selector !== "string" ) { + return results; + } + + var m, set, checkSet, extra, ret, cur, pop, i, + prune = true, + contextXML = Sizzle.isXML( context ), + parts = [], + soFar = selector; + + // Reset the position of the chunker regexp (start from head) + do { + chunker.exec( "" ); + m = chunker.exec( soFar ); + + if ( m ) { + soFar = m[3]; + + parts.push( m[1] ); + + if ( m[2] ) { + extra = m[3]; + break; + } + } + } while ( m ); + + if ( parts.length > 1 && origPOS.exec( selector ) ) { + + if ( parts.length === 2 && Expr.relative[ parts[0] ] ) { + set = posProcess( parts[0] + parts[1], context, seed ); + + } else { + set = Expr.relative[ parts[0] ] ? + [ context ] : + Sizzle( parts.shift(), context ); + + while ( parts.length ) { + selector = parts.shift(); + + if ( Expr.relative[ selector ] ) { + selector += parts.shift(); + } + + set = posProcess( selector, set, seed ); + } + } + + } else { + // Take a shortcut and set the context if the root selector is an ID + // (but not if it'll be faster if the inner selector is an ID) + if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML && + Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) { + + ret = Sizzle.find( parts.shift(), context, contextXML ); + context = ret.expr ? + Sizzle.filter( ret.expr, ret.set )[0] : + ret.set[0]; + } + + if ( context ) { + ret = seed ? + { expr: parts.pop(), set: makeArray(seed) } : + Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML ); + + set = ret.expr ? + Sizzle.filter( ret.expr, ret.set ) : + ret.set; + + if ( parts.length > 0 ) { + checkSet = makeArray( set ); + + } else { + prune = false; + } + + while ( parts.length ) { + cur = parts.pop(); + pop = cur; + + if ( !Expr.relative[ cur ] ) { + cur = ""; + } else { + pop = parts.pop(); + } + + if ( pop == null ) { + pop = context; + } + + Expr.relative[ cur ]( checkSet, pop, contextXML ); + } + + } else { + checkSet = parts = []; + } + } + + if ( !checkSet ) { + checkSet = set; + } + + if ( !checkSet ) { + Sizzle.error( cur || selector ); + } + + if ( toString.call(checkSet) === "[object Array]" ) { + if ( !prune ) { + results.push.apply( results, checkSet ); + + } else if ( context && context.nodeType === 1 ) { + for ( i = 0; checkSet[i] != null; i++ ) { + if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && Sizzle.contains(context, checkSet[i])) ) { + results.push( set[i] ); + } + } + + } else { + for ( i = 0; checkSet[i] != null; i++ ) { + if ( checkSet[i] && checkSet[i].nodeType === 1 ) { + results.push( set[i] ); + } + } + } + + } else { + makeArray( checkSet, results ); + } + + if ( extra ) { + Sizzle( extra, origContext, results, seed ); + Sizzle.uniqueSort( results ); + } + + return results; +}; + +Sizzle.uniqueSort = function( results ) { + if ( sortOrder ) { + hasDuplicate = baseHasDuplicate; + results.sort( sortOrder ); + + if ( hasDuplicate ) { + for ( var i = 1; i < results.length; i++ ) { + if ( results[i] === results[ i - 1 ] ) { + results.splice( i--, 1 ); + } + } + } + } + + return results; +}; + +Sizzle.matches = function( expr, set ) { + return Sizzle( expr, null, null, set ); +}; + +Sizzle.matchesSelector = function( node, expr ) { + return Sizzle( expr, null, null, [node] ).length > 0; +}; + +Sizzle.find = function( expr, context, isXML ) { + var set, i, len, match, type, left; + + if ( !expr ) { + return []; + } + + for ( i = 0, len = Expr.order.length; i < len; i++ ) { + type = Expr.order[i]; + + if ( (match = Expr.leftMatch[ type ].exec( expr )) ) { + left = match[1]; + match.splice( 1, 1 ); + + if ( left.substr( left.length - 1 ) !== "\\" ) { + match[1] = (match[1] || "").replace( rBackslash, "" ); + set = Expr.find[ type ]( match, context, isXML ); + + if ( set != null ) { + expr = expr.replace( Expr.match[ type ], "" ); + break; + } + } + } + } + + if ( !set ) { + set = typeof context.getElementsByTagName !== "undefined" ? + context.getElementsByTagName( "*" ) : + []; + } + + return { set: set, expr: expr }; +}; + +Sizzle.filter = function( expr, set, inplace, not ) { + var match, anyFound, + type, found, item, filter, left, + i, pass, + old = expr, + result = [], + curLoop = set, + isXMLFilter = set && set[0] && Sizzle.isXML( set[0] ); + + while ( expr && set.length ) { + for ( type in Expr.filter ) { + if ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) { + filter = Expr.filter[ type ]; + left = match[1]; + + anyFound = false; + + match.splice(1,1); + + if ( left.substr( left.length - 1 ) === "\\" ) { + continue; + } + + if ( curLoop === result ) { + result = []; + } + + if ( Expr.preFilter[ type ] ) { + match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter ); + + if ( !match ) { + anyFound = found = true; + + } else if ( match === true ) { + continue; + } + } + + if ( match ) { + for ( i = 0; (item = curLoop[i]) != null; i++ ) { + if ( item ) { + found = filter( item, match, i, curLoop ); + pass = not ^ found; + + if ( inplace && found != null ) { + if ( pass ) { + anyFound = true; + + } else { + curLoop[i] = false; + } + + } else if ( pass ) { + result.push( item ); + anyFound = true; + } + } + } + } + + if ( found !== undefined ) { + if ( !inplace ) { + curLoop = result; + } + + expr = expr.replace( Expr.match[ type ], "" ); + + if ( !anyFound ) { + return []; + } + + break; + } + } + } + + // Improper expression + if ( expr === old ) { + if ( anyFound == null ) { + Sizzle.error( expr ); + + } else { + break; + } + } + + old = expr; + } + + return curLoop; +}; + +Sizzle.error = function( msg ) { + throw new Error( "Syntax error, unrecognized expression: " + msg ); +}; + +/** + * Utility function for retreiving the text value of an array of DOM nodes + * @param {Array|Element} elem + */ +var getText = Sizzle.getText = function( elem ) { + var i, node, + nodeType = elem.nodeType, + ret = ""; + + if ( nodeType ) { + if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { + // Use textContent || innerText for elements + if ( typeof elem.textContent === 'string' ) { + return elem.textContent; + } else if ( typeof elem.innerText === 'string' ) { + // Replace IE's carriage returns + return elem.innerText.replace( rReturn, '' ); + } else { + // Traverse it's children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling) { + ret += getText( elem ); + } + } + } else if ( nodeType === 3 || nodeType === 4 ) { + return elem.nodeValue; + } + } else { + + // If no nodeType, this is expected to be an array + for ( i = 0; (node = elem[i]); i++ ) { + // Do not traverse comment nodes + if ( node.nodeType !== 8 ) { + ret += getText( node ); + } + } + } + return ret; +}; + +var Expr = Sizzle.selectors = { + order: [ "ID", "NAME", "TAG" ], + + match: { + ID: /#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/, + CLASS: /\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/, + NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/, + ATTR: /\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/, + TAG: /^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/, + CHILD: /:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/, + POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/, + PSEUDO: /:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/ + }, + + leftMatch: {}, + + attrMap: { + "class": "className", + "for": "htmlFor" + }, + + attrHandle: { + href: function( elem ) { + return elem.getAttribute( "href" ); + }, + type: function( elem ) { + return elem.getAttribute( "type" ); + } + }, + + relative: { + "+": function(checkSet, part){ + var isPartStr = typeof part === "string", + isTag = isPartStr && !rNonWord.test( part ), + isPartStrNotTag = isPartStr && !isTag; + + if ( isTag ) { + part = part.toLowerCase(); + } + + for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) { + if ( (elem = checkSet[i]) ) { + while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {} + + checkSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ? + elem || false : + elem === part; + } + } + + if ( isPartStrNotTag ) { + Sizzle.filter( part, checkSet, true ); + } + }, + + ">": function( checkSet, part ) { + var elem, + isPartStr = typeof part === "string", + i = 0, + l = checkSet.length; + + if ( isPartStr && !rNonWord.test( part ) ) { + part = part.toLowerCase(); + + for ( ; i < l; i++ ) { + elem = checkSet[i]; + + if ( elem ) { + var parent = elem.parentNode; + checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false; + } + } + + } else { + for ( ; i < l; i++ ) { + elem = checkSet[i]; + + if ( elem ) { + checkSet[i] = isPartStr ? + elem.parentNode : + elem.parentNode === part; + } + } + + if ( isPartStr ) { + Sizzle.filter( part, checkSet, true ); + } + } + }, + + "": function(checkSet, part, isXML){ + var nodeCheck, + doneName = done++, + checkFn = dirCheck; + + if ( typeof part === "string" && !rNonWord.test( part ) ) { + part = part.toLowerCase(); + nodeCheck = part; + checkFn = dirNodeCheck; + } + + checkFn( "parentNode", part, doneName, checkSet, nodeCheck, isXML ); + }, + + "~": function( checkSet, part, isXML ) { + var nodeCheck, + doneName = done++, + checkFn = dirCheck; + + if ( typeof part === "string" && !rNonWord.test( part ) ) { + part = part.toLowerCase(); + nodeCheck = part; + checkFn = dirNodeCheck; + } + + checkFn( "previousSibling", part, doneName, checkSet, nodeCheck, isXML ); + } + }, + + find: { + ID: function( match, context, isXML ) { + if ( typeof context.getElementById !== "undefined" && !isXML ) { + var m = context.getElementById(match[1]); + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + return m && m.parentNode ? [m] : []; + } + }, + + NAME: function( match, context ) { + if ( typeof context.getElementsByName !== "undefined" ) { + var ret = [], + results = context.getElementsByName( match[1] ); + + for ( var i = 0, l = results.length; i < l; i++ ) { + if ( results[i].getAttribute("name") === match[1] ) { + ret.push( results[i] ); + } + } + + return ret.length === 0 ? null : ret; + } + }, + + TAG: function( match, context ) { + if ( typeof context.getElementsByTagName !== "undefined" ) { + return context.getElementsByTagName( match[1] ); + } + } + }, + preFilter: { + CLASS: function( match, curLoop, inplace, result, not, isXML ) { + match = " " + match[1].replace( rBackslash, "" ) + " "; + + if ( isXML ) { + return match; + } + + for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) { + if ( elem ) { + if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n\r]/g, " ").indexOf(match) >= 0) ) { + if ( !inplace ) { + result.push( elem ); + } + + } else if ( inplace ) { + curLoop[i] = false; + } + } + } + + return false; + }, + + ID: function( match ) { + return match[1].replace( rBackslash, "" ); + }, + + TAG: function( match, curLoop ) { + return match[1].replace( rBackslash, "" ).toLowerCase(); + }, + + CHILD: function( match ) { + if ( match[1] === "nth" ) { + if ( !match[2] ) { + Sizzle.error( match[0] ); + } + + match[2] = match[2].replace(/^\+|\s*/g, ''); + + // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6' + var test = /(-?)(\d*)(?:n([+\-]?\d*))?/.exec( + match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" || + !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]); + + // calculate the numbers (first)n+(last) including if they are negative + match[2] = (test[1] + (test[2] || 1)) - 0; + match[3] = test[3] - 0; + } + else if ( match[2] ) { + Sizzle.error( match[0] ); + } + + // TODO: Move to normal caching system + match[0] = done++; + + return match; + }, + + ATTR: function( match, curLoop, inplace, result, not, isXML ) { + var name = match[1] = match[1].replace( rBackslash, "" ); + + if ( !isXML && Expr.attrMap[name] ) { + match[1] = Expr.attrMap[name]; + } + + // Handle if an un-quoted value was used + match[4] = ( match[4] || match[5] || "" ).replace( rBackslash, "" ); + + if ( match[2] === "~=" ) { + match[4] = " " + match[4] + " "; + } + + return match; + }, + + PSEUDO: function( match, curLoop, inplace, result, not ) { + if ( match[1] === "not" ) { + // If we're dealing with a complex expression, or a simple one + if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) { + match[3] = Sizzle(match[3], null, null, curLoop); + + } else { + var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not); + + if ( !inplace ) { + result.push.apply( result, ret ); + } + + return false; + } + + } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) { + return true; + } + + return match; + }, + + POS: function( match ) { + match.unshift( true ); + + return match; + } + }, + + filters: { + enabled: function( elem ) { + return elem.disabled === false && elem.type !== "hidden"; + }, + + disabled: function( elem ) { + return elem.disabled === true; + }, + + checked: function( elem ) { + return elem.checked === true; + }, + + selected: function( elem ) { + // Accessing this property makes selected-by-default + // options in Safari work properly + if ( elem.parentNode ) { + elem.parentNode.selectedIndex; + } + + return elem.selected === true; + }, + + parent: function( elem ) { + return !!elem.firstChild; + }, + + empty: function( elem ) { + return !elem.firstChild; + }, + + has: function( elem, i, match ) { + return !!Sizzle( match[3], elem ).length; + }, + + header: function( elem ) { + return (/h\d/i).test( elem.nodeName ); + }, + + text: function( elem ) { + var attr = elem.getAttribute( "type" ), type = elem.type; + // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc) + // use getAttribute instead to test this case + return elem.nodeName.toLowerCase() === "input" && "text" === type && ( attr === type || attr === null ); + }, + + radio: function( elem ) { + return elem.nodeName.toLowerCase() === "input" && "radio" === elem.type; + }, + + checkbox: function( elem ) { + return elem.nodeName.toLowerCase() === "input" && "checkbox" === elem.type; + }, + + file: function( elem ) { + return elem.nodeName.toLowerCase() === "input" && "file" === elem.type; + }, + + password: function( elem ) { + return elem.nodeName.toLowerCase() === "input" && "password" === elem.type; + }, + + submit: function( elem ) { + var name = elem.nodeName.toLowerCase(); + return (name === "input" || name === "button") && "submit" === elem.type; + }, + + image: function( elem ) { + return elem.nodeName.toLowerCase() === "input" && "image" === elem.type; + }, + + reset: function( elem ) { + var name = elem.nodeName.toLowerCase(); + return (name === "input" || name === "button") && "reset" === elem.type; + }, + + button: function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && "button" === elem.type || name === "button"; + }, + + input: function( elem ) { + return (/input|select|textarea|button/i).test( elem.nodeName ); + }, + + focus: function( elem ) { + return elem === elem.ownerDocument.activeElement; + } + }, + setFilters: { + first: function( elem, i ) { + return i === 0; + }, + + last: function( elem, i, match, array ) { + return i === array.length - 1; + }, + + even: function( elem, i ) { + return i % 2 === 0; + }, + + odd: function( elem, i ) { + return i % 2 === 1; + }, + + lt: function( elem, i, match ) { + return i < match[3] - 0; + }, + + gt: function( elem, i, match ) { + return i > match[3] - 0; + }, + + nth: function( elem, i, match ) { + return match[3] - 0 === i; + }, + + eq: function( elem, i, match ) { + return match[3] - 0 === i; + } + }, + filter: { + PSEUDO: function( elem, match, i, array ) { + var name = match[1], + filter = Expr.filters[ name ]; + + if ( filter ) { + return filter( elem, i, match, array ); + + } else if ( name === "contains" ) { + return (elem.textContent || elem.innerText || getText([ elem ]) || "").indexOf(match[3]) >= 0; + + } else if ( name === "not" ) { + var not = match[3]; + + for ( var j = 0, l = not.length; j < l; j++ ) { + if ( not[j] === elem ) { + return false; + } + } + + return true; + + } else { + Sizzle.error( name ); + } + }, + + CHILD: function( elem, match ) { + var first, last, + doneName, parent, cache, + count, diff, + type = match[1], + node = elem; + + switch ( type ) { + case "only": + case "first": + while ( (node = node.previousSibling) ) { + if ( node.nodeType === 1 ) { + return false; + } + } + + if ( type === "first" ) { + return true; + } + + node = elem; + + /* falls through */ + case "last": + while ( (node = node.nextSibling) ) { + if ( node.nodeType === 1 ) { + return false; + } + } + + return true; + + case "nth": + first = match[2]; + last = match[3]; + + if ( first === 1 && last === 0 ) { + return true; + } + + doneName = match[0]; + parent = elem.parentNode; + + if ( parent && (parent[ expando ] !== doneName || !elem.nodeIndex) ) { + count = 0; + + for ( node = parent.firstChild; node; node = node.nextSibling ) { + if ( node.nodeType === 1 ) { + node.nodeIndex = ++count; + } + } + + parent[ expando ] = doneName; + } + + diff = elem.nodeIndex - last; + + if ( first === 0 ) { + return diff === 0; + + } else { + return ( diff % first === 0 && diff / first >= 0 ); + } + } + }, + + ID: function( elem, match ) { + return elem.nodeType === 1 && elem.getAttribute("id") === match; + }, + + TAG: function( elem, match ) { + return (match === "*" && elem.nodeType === 1) || !!elem.nodeName && elem.nodeName.toLowerCase() === match; + }, + + CLASS: function( elem, match ) { + return (" " + (elem.className || elem.getAttribute("class")) + " ") + .indexOf( match ) > -1; + }, + + ATTR: function( elem, match ) { + var name = match[1], + result = Sizzle.attr ? + Sizzle.attr( elem, name ) : + Expr.attrHandle[ name ] ? + Expr.attrHandle[ name ]( elem ) : + elem[ name ] != null ? + elem[ name ] : + elem.getAttribute( name ), + value = result + "", + type = match[2], + check = match[4]; + + return result == null ? + type === "!=" : + !type && Sizzle.attr ? + result != null : + type === "=" ? + value === check : + type === "*=" ? + value.indexOf(check) >= 0 : + type === "~=" ? + (" " + value + " ").indexOf(check) >= 0 : + !check ? + value && result !== false : + type === "!=" ? + value !== check : + type === "^=" ? + value.indexOf(check) === 0 : + type === "$=" ? + value.substr(value.length - check.length) === check : + type === "|=" ? + value === check || value.substr(0, check.length + 1) === check + "-" : + false; + }, + + POS: function( elem, match, i, array ) { + var name = match[2], + filter = Expr.setFilters[ name ]; + + if ( filter ) { + return filter( elem, i, match, array ); + } + } + } +}; + +var origPOS = Expr.match.POS, + fescape = function(all, num){ + return "\\" + (num - 0 + 1); + }; + +for ( var type in Expr.match ) { + Expr.match[ type ] = new RegExp( Expr.match[ type ].source + (/(?![^\[]*\])(?![^\(]*\))/.source) ); + Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source.replace(/\\(\d+)/g, fescape) ); +} +// Expose origPOS +// "global" as in regardless of relation to brackets/parens +Expr.match.globalPOS = origPOS; + +var makeArray = function( array, results ) { + array = Array.prototype.slice.call( array, 0 ); + + if ( results ) { + results.push.apply( results, array ); + return results; + } + + return array; +}; + +// Perform a simple check to determine if the browser is capable of +// converting a NodeList to an array using builtin methods. +// Also verifies that the returned array holds DOM nodes +// (which is not the case in the Blackberry browser) +try { + Array.prototype.slice.call( document.documentElement.childNodes, 0 )[0].nodeType; + +// Provide a fallback method if it does not work +} catch( e ) { + makeArray = function( array, results ) { + var i = 0, + ret = results || []; + + if ( toString.call(array) === "[object Array]" ) { + Array.prototype.push.apply( ret, array ); + + } else { + if ( typeof array.length === "number" ) { + for ( var l = array.length; i < l; i++ ) { + ret.push( array[i] ); + } + + } else { + for ( ; array[i]; i++ ) { + ret.push( array[i] ); + } + } + } + + return ret; + }; +} + +var sortOrder, siblingCheck; + +if ( document.documentElement.compareDocumentPosition ) { + sortOrder = function( a, b ) { + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) { + return a.compareDocumentPosition ? -1 : 1; + } + + return a.compareDocumentPosition(b) & 4 ? -1 : 1; + }; + +} else { + sortOrder = function( a, b ) { + // The nodes are identical, we can exit early + if ( a === b ) { + hasDuplicate = true; + return 0; + + // Fallback to using sourceIndex (in IE) if it's available on both nodes + } else if ( a.sourceIndex && b.sourceIndex ) { + return a.sourceIndex - b.sourceIndex; + } + + var al, bl, + ap = [], + bp = [], + aup = a.parentNode, + bup = b.parentNode, + cur = aup; + + // If the nodes are siblings (or identical) we can do a quick check + if ( aup === bup ) { + return siblingCheck( a, b ); + + // If no parents were found then the nodes are disconnected + } else if ( !aup ) { + return -1; + + } else if ( !bup ) { + return 1; + } + + // Otherwise they're somewhere else in the tree so we need + // to build up a full list of the parentNodes for comparison + while ( cur ) { + ap.unshift( cur ); + cur = cur.parentNode; + } + + cur = bup; + + while ( cur ) { + bp.unshift( cur ); + cur = cur.parentNode; + } + + al = ap.length; + bl = bp.length; + + // Start walking down the tree looking for a discrepancy + for ( var i = 0; i < al && i < bl; i++ ) { + if ( ap[i] !== bp[i] ) { + return siblingCheck( ap[i], bp[i] ); + } + } + + // We ended someplace up the tree so do a sibling check + return i === al ? + siblingCheck( a, bp[i], -1 ) : + siblingCheck( ap[i], b, 1 ); + }; + + siblingCheck = function( a, b, ret ) { + if ( a === b ) { + return ret; + } + + var cur = a.nextSibling; + + while ( cur ) { + if ( cur === b ) { + return -1; + } + + cur = cur.nextSibling; + } + + return 1; + }; +} + +// Check to see if the browser returns elements by name when +// querying by getElementById (and provide a workaround) +(function(){ + // We're going to inject a fake input element with a specified name + var form = document.createElement("div"), + id = "script" + (new Date()).getTime(), + root = document.documentElement; + + form.innerHTML = ""; + + // Inject it into the root element, check its status, and remove it quickly + root.insertBefore( form, root.firstChild ); + + // The workaround has to do additional checks after a getElementById + // Which slows things down for other browsers (hence the branching) + if ( document.getElementById( id ) ) { + Expr.find.ID = function( match, context, isXML ) { + if ( typeof context.getElementById !== "undefined" && !isXML ) { + var m = context.getElementById(match[1]); + + return m ? + m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ? + [m] : + undefined : + []; + } + }; + + Expr.filter.ID = function( elem, match ) { + var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id"); + + return elem.nodeType === 1 && node && node.nodeValue === match; + }; + } + + root.removeChild( form ); + + // release memory in IE + root = form = null; +})(); + +(function(){ + // Check to see if the browser returns only elements + // when doing getElementsByTagName("*") + + // Create a fake element + var div = document.createElement("div"); + div.appendChild( document.createComment("") ); + + // Make sure no comments are found + if ( div.getElementsByTagName("*").length > 0 ) { + Expr.find.TAG = function( match, context ) { + var results = context.getElementsByTagName( match[1] ); + + // Filter out possible comments + if ( match[1] === "*" ) { + var tmp = []; + + for ( var i = 0; results[i]; i++ ) { + if ( results[i].nodeType === 1 ) { + tmp.push( results[i] ); + } + } + + results = tmp; + } + + return results; + }; + } + + // Check to see if an attribute returns normalized href attributes + div.innerHTML = ""; + + if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" && + div.firstChild.getAttribute("href") !== "#" ) { + + Expr.attrHandle.href = function( elem ) { + return elem.getAttribute( "href", 2 ); + }; + } + + // release memory in IE + div = null; +})(); + +if ( document.querySelectorAll ) { + (function(){ + var oldSizzle = Sizzle, + div = document.createElement("div"), + id = "__sizzle__"; + + div.innerHTML = "

    "; + + // Safari can't handle uppercase or unicode characters when + // in quirks mode. + if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) { + return; + } + + Sizzle = function( query, context, extra, seed ) { + context = context || document; + + // Only use querySelectorAll on non-XML documents + // (ID selectors don't work in non-HTML documents) + if ( !seed && !Sizzle.isXML(context) ) { + // See if we find a selector to speed up + var match = /^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec( query ); + + if ( match && (context.nodeType === 1 || context.nodeType === 9) ) { + // Speed-up: Sizzle("TAG") + if ( match[1] ) { + return makeArray( context.getElementsByTagName( query ), extra ); + + // Speed-up: Sizzle(".CLASS") + } else if ( match[2] && Expr.find.CLASS && context.getElementsByClassName ) { + return makeArray( context.getElementsByClassName( match[2] ), extra ); + } + } + + if ( context.nodeType === 9 ) { + // Speed-up: Sizzle("body") + // The body element only exists once, optimize finding it + if ( query === "body" && context.body ) { + return makeArray( [ context.body ], extra ); + + // Speed-up: Sizzle("#ID") + } else if ( match && match[3] ) { + var elem = context.getElementById( match[3] ); + + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + if ( elem && elem.parentNode ) { + // Handle the case where IE and Opera return items + // by name instead of ID + if ( elem.id === match[3] ) { + return makeArray( [ elem ], extra ); + } + + } else { + return makeArray( [], extra ); + } + } + + try { + return makeArray( context.querySelectorAll(query), extra ); + } catch(qsaError) {} + + // qSA works strangely on Element-rooted queries + // We can work around this by specifying an extra ID on the root + // and working up from there (Thanks to Andrew Dupont for the technique) + // IE 8 doesn't work on object elements + } else if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) { + var oldContext = context, + old = context.getAttribute( "id" ), + nid = old || id, + hasParent = context.parentNode, + relativeHierarchySelector = /^\s*[+~]/.test( query ); + + if ( !old ) { + context.setAttribute( "id", nid ); + } else { + nid = nid.replace( /'/g, "\\$&" ); + } + if ( relativeHierarchySelector && hasParent ) { + context = context.parentNode; + } + + try { + if ( !relativeHierarchySelector || hasParent ) { + return makeArray( context.querySelectorAll( "[id='" + nid + "'] " + query ), extra ); + } + + } catch(pseudoError) { + } finally { + if ( !old ) { + oldContext.removeAttribute( "id" ); + } + } + } + } + + return oldSizzle(query, context, extra, seed); + }; + + for ( var prop in oldSizzle ) { + Sizzle[ prop ] = oldSizzle[ prop ]; + } + + // release memory in IE + div = null; + })(); +} + +(function(){ + var html = document.documentElement, + matches = html.matchesSelector || html.mozMatchesSelector || html.webkitMatchesSelector || html.msMatchesSelector; + + if ( matches ) { + // Check to see if it's possible to do matchesSelector + // on a disconnected node (IE 9 fails this) + var disconnectedMatch = !matches.call( document.createElement( "div" ), "div" ), + pseudoWorks = false; + + try { + // This should fail with an exception + // Gecko does not error, returns false instead + matches.call( document.documentElement, "[test!='']:sizzle" ); + + } catch( pseudoError ) { + pseudoWorks = true; + } + + Sizzle.matchesSelector = function( node, expr ) { + // Make sure that attribute selectors are quoted + expr = expr.replace(/\=\s*([^'"\]]*)\s*\]/g, "='$1']"); + + if ( !Sizzle.isXML( node ) ) { + try { + if ( pseudoWorks || !Expr.match.PSEUDO.test( expr ) && !/!=/.test( expr ) ) { + var ret = matches.call( node, expr ); + + // IE 9's matchesSelector returns false on disconnected nodes + if ( ret || !disconnectedMatch || + // As well, disconnected nodes are said to be in a document + // fragment in IE 9, so check for that + node.document && node.document.nodeType !== 11 ) { + return ret; + } + } + } catch(e) {} + } + + return Sizzle(expr, null, null, [node]).length > 0; + }; + } +})(); + +(function(){ + var div = document.createElement("div"); + + div.innerHTML = "
    "; + + // Opera can't find a second classname (in 9.6) + // Also, make sure that getElementsByClassName actually exists + if ( !div.getElementsByClassName || div.getElementsByClassName("e").length === 0 ) { + return; + } + + // Safari caches class attributes, doesn't catch changes (in 3.2) + div.lastChild.className = "e"; + + if ( div.getElementsByClassName("e").length === 1 ) { + return; + } + + Expr.order.splice(1, 0, "CLASS"); + Expr.find.CLASS = function( match, context, isXML ) { + if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) { + return context.getElementsByClassName(match[1]); + } + }; + + // release memory in IE + div = null; +})(); + +function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { + for ( var i = 0, l = checkSet.length; i < l; i++ ) { + var elem = checkSet[i]; + + if ( elem ) { + var match = false; + + elem = elem[dir]; + + while ( elem ) { + if ( elem[ expando ] === doneName ) { + match = checkSet[elem.sizset]; + break; + } + + if ( elem.nodeType === 1 && !isXML ){ + elem[ expando ] = doneName; + elem.sizset = i; + } + + if ( elem.nodeName.toLowerCase() === cur ) { + match = elem; + break; + } + + elem = elem[dir]; + } + + checkSet[i] = match; + } + } +} + +function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { + for ( var i = 0, l = checkSet.length; i < l; i++ ) { + var elem = checkSet[i]; + + if ( elem ) { + var match = false; + + elem = elem[dir]; + + while ( elem ) { + if ( elem[ expando ] === doneName ) { + match = checkSet[elem.sizset]; + break; + } + + if ( elem.nodeType === 1 ) { + if ( !isXML ) { + elem[ expando ] = doneName; + elem.sizset = i; + } + + if ( typeof cur !== "string" ) { + if ( elem === cur ) { + match = true; + break; + } + + } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) { + match = elem; + break; + } + } + + elem = elem[dir]; + } + + checkSet[i] = match; + } + } +} + +if ( document.documentElement.contains ) { + Sizzle.contains = function( a, b ) { + return a !== b && (a.contains ? a.contains(b) : true); + }; + +} else if ( document.documentElement.compareDocumentPosition ) { + Sizzle.contains = function( a, b ) { + return !!(a.compareDocumentPosition(b) & 16); + }; + +} else { + Sizzle.contains = function() { + return false; + }; +} + +Sizzle.isXML = function( elem ) { + // documentElement is verified for cases where it doesn't yet exist + // (such as loading iframes in IE - #4833) + var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement; + + return documentElement ? documentElement.nodeName !== "HTML" : false; +}; + +var posProcess = function( selector, context, seed ) { + var match, + tmpSet = [], + later = "", + root = context.nodeType ? [context] : context; + + // Position selectors must be done after the filter + // And so must :not(positional) so we move all PSEUDOs to the end + while ( (match = Expr.match.PSEUDO.exec( selector )) ) { + later += match[0]; + selector = selector.replace( Expr.match.PSEUDO, "" ); + } + + selector = Expr.relative[selector] ? selector + "*" : selector; + + for ( var i = 0, l = root.length; i < l; i++ ) { + Sizzle( selector, root[i], tmpSet, seed ); + } + + return Sizzle.filter( later, tmpSet ); +}; + +// EXPOSE +// Override sizzle attribute retrieval +Sizzle.attr = jQuery.attr; +Sizzle.selectors.attrMap = {}; +jQuery.find = Sizzle; +jQuery.expr = Sizzle.selectors; +jQuery.expr[":"] = jQuery.expr.filters; +jQuery.unique = Sizzle.uniqueSort; +jQuery.text = Sizzle.getText; +jQuery.isXMLDoc = Sizzle.isXML; +jQuery.contains = Sizzle.contains; + + +})(); + + +var runtil = /Until$/, + rparentsprev = /^(?:parents|prevUntil|prevAll)/, + // Note: This RegExp should be improved, or likely pulled from Sizzle + rmultiselector = /,/, + isSimple = /^.[^:#\[\.,]*$/, + slice = Array.prototype.slice, + POS = jQuery.expr.match.globalPOS, + // methods guaranteed to produce a unique set when starting from a unique set + guaranteedUnique = { + children: true, + contents: true, + next: true, + prev: true + }; + +jQuery.fn.extend({ + find: function( selector ) { + var self = this, + i, l; + + if ( typeof selector !== "string" ) { + return jQuery( selector ).filter(function() { + for ( i = 0, l = self.length; i < l; i++ ) { + if ( jQuery.contains( self[ i ], this ) ) { + return true; + } + } + }); + } + + var ret = this.pushStack( "", "find", selector ), + length, n, r; + + for ( i = 0, l = this.length; i < l; i++ ) { + length = ret.length; + jQuery.find( selector, this[i], ret ); + + if ( i > 0 ) { + // Make sure that the results are unique + for ( n = length; n < ret.length; n++ ) { + for ( r = 0; r < length; r++ ) { + if ( ret[r] === ret[n] ) { + ret.splice(n--, 1); + break; + } + } + } + } + } + + return ret; + }, + + has: function( target ) { + var targets = jQuery( target ); + return this.filter(function() { + for ( var i = 0, l = targets.length; i < l; i++ ) { + if ( jQuery.contains( this, targets[i] ) ) { + return true; + } + } + }); + }, + + not: function( selector ) { + return this.pushStack( winnow(this, selector, false), "not", selector); + }, + + filter: function( selector ) { + return this.pushStack( winnow(this, selector, true), "filter", selector ); + }, + + is: function( selector ) { + return !!selector && ( + typeof selector === "string" ? + // If this is a positional selector, check membership in the returned set + // so $("p:first").is("p:last") won't return true for a doc with two "p". + POS.test( selector ) ? + jQuery( selector, this.context ).index( this[0] ) >= 0 : + jQuery.filter( selector, this ).length > 0 : + this.filter( selector ).length > 0 ); + }, + + closest: function( selectors, context ) { + var ret = [], i, l, cur = this[0]; + + // Array (deprecated as of jQuery 1.7) + if ( jQuery.isArray( selectors ) ) { + var level = 1; + + while ( cur && cur.ownerDocument && cur !== context ) { + for ( i = 0; i < selectors.length; i++ ) { + + if ( jQuery( cur ).is( selectors[ i ] ) ) { + ret.push({ selector: selectors[ i ], elem: cur, level: level }); + } + } + + cur = cur.parentNode; + level++; + } + + return ret; + } + + // String + var pos = POS.test( selectors ) || typeof selectors !== "string" ? + jQuery( selectors, context || this.context ) : + 0; + + for ( i = 0, l = this.length; i < l; i++ ) { + cur = this[i]; + + while ( cur ) { + if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) { + ret.push( cur ); + break; + + } else { + cur = cur.parentNode; + if ( !cur || !cur.ownerDocument || cur === context || cur.nodeType === 11 ) { + break; + } + } + } + } + + ret = ret.length > 1 ? jQuery.unique( ret ) : ret; + + return this.pushStack( ret, "closest", selectors ); + }, + + // Determine the position of an element within + // the matched set of elements + index: function( elem ) { + + // No argument, return index in parent + if ( !elem ) { + return ( this[0] && this[0].parentNode ) ? this.prevAll().length : -1; + } + + // index in selector + if ( typeof elem === "string" ) { + return jQuery.inArray( this[0], jQuery( elem ) ); + } + + // Locate the position of the desired element + return jQuery.inArray( + // If it receives a jQuery object, the first element is used + elem.jquery ? elem[0] : elem, this ); + }, + + add: function( selector, context ) { + var set = typeof selector === "string" ? + jQuery( selector, context ) : + jQuery.makeArray( selector && selector.nodeType ? [ selector ] : selector ), + all = jQuery.merge( this.get(), set ); + + return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ? + all : + jQuery.unique( all ) ); + }, + + andSelf: function() { + return this.add( this.prevObject ); + } +}); + +// A painfully simple check to see if an element is disconnected +// from a document (should be improved, where feasible). +function isDisconnected( node ) { + return !node || !node.parentNode || node.parentNode.nodeType === 11; +} + +jQuery.each({ + parent: function( elem ) { + var parent = elem.parentNode; + return parent && parent.nodeType !== 11 ? parent : null; + }, + parents: function( elem ) { + return jQuery.dir( elem, "parentNode" ); + }, + parentsUntil: function( elem, i, until ) { + return jQuery.dir( elem, "parentNode", until ); + }, + next: function( elem ) { + return jQuery.nth( elem, 2, "nextSibling" ); + }, + prev: function( elem ) { + return jQuery.nth( elem, 2, "previousSibling" ); + }, + nextAll: function( elem ) { + return jQuery.dir( elem, "nextSibling" ); + }, + prevAll: function( elem ) { + return jQuery.dir( elem, "previousSibling" ); + }, + nextUntil: function( elem, i, until ) { + return jQuery.dir( elem, "nextSibling", until ); + }, + prevUntil: function( elem, i, until ) { + return jQuery.dir( elem, "previousSibling", until ); + }, + siblings: function( elem ) { + return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem ); + }, + children: function( elem ) { + return jQuery.sibling( elem.firstChild ); + }, + contents: function( elem ) { + return jQuery.nodeName( elem, "iframe" ) ? + elem.contentDocument || elem.contentWindow.document : + jQuery.makeArray( elem.childNodes ); + } +}, function( name, fn ) { + jQuery.fn[ name ] = function( until, selector ) { + var ret = jQuery.map( this, fn, until ); + + if ( !runtil.test( name ) ) { + selector = until; + } + + if ( selector && typeof selector === "string" ) { + ret = jQuery.filter( selector, ret ); + } + + ret = this.length > 1 && !guaranteedUnique[ name ] ? jQuery.unique( ret ) : ret; + + if ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( name ) ) { + ret = ret.reverse(); + } + + return this.pushStack( ret, name, slice.call( arguments ).join(",") ); + }; +}); + +jQuery.extend({ + filter: function( expr, elems, not ) { + if ( not ) { + expr = ":not(" + expr + ")"; + } + + return elems.length === 1 ? + jQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] : + jQuery.find.matches(expr, elems); + }, + + dir: function( elem, dir, until ) { + var matched = [], + cur = elem[ dir ]; + + while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) { + if ( cur.nodeType === 1 ) { + matched.push( cur ); + } + cur = cur[dir]; + } + return matched; + }, + + nth: function( cur, result, dir, elem ) { + result = result || 1; + var num = 0; + + for ( ; cur; cur = cur[dir] ) { + if ( cur.nodeType === 1 && ++num === result ) { + break; + } + } + + return cur; + }, + + sibling: function( n, elem ) { + var r = []; + + for ( ; n; n = n.nextSibling ) { + if ( n.nodeType === 1 && n !== elem ) { + r.push( n ); + } + } + + return r; + } +}); + +// Implement the identical functionality for filter and not +function winnow( elements, qualifier, keep ) { + + // Can't pass null or undefined to indexOf in Firefox 4 + // Set to 0 to skip string check + qualifier = qualifier || 0; + + if ( jQuery.isFunction( qualifier ) ) { + return jQuery.grep(elements, function( elem, i ) { + var retVal = !!qualifier.call( elem, i, elem ); + return retVal === keep; + }); + + } else if ( qualifier.nodeType ) { + return jQuery.grep(elements, function( elem, i ) { + return ( elem === qualifier ) === keep; + }); + + } else if ( typeof qualifier === "string" ) { + var filtered = jQuery.grep(elements, function( elem ) { + return elem.nodeType === 1; + }); + + if ( isSimple.test( qualifier ) ) { + return jQuery.filter(qualifier, filtered, !keep); + } else { + qualifier = jQuery.filter( qualifier, filtered ); + } + } + + return jQuery.grep(elements, function( elem, i ) { + return ( jQuery.inArray( elem, qualifier ) >= 0 ) === keep; + }); +} + + + + +function createSafeFragment( document ) { + var list = nodeNames.split( "|" ), + safeFrag = document.createDocumentFragment(); + + if ( safeFrag.createElement ) { + while ( list.length ) { + safeFrag.createElement( + list.pop() + ); + } + } + return safeFrag; +} + +var nodeNames = "abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|" + + "header|hgroup|mark|meter|nav|output|progress|section|summary|time|video", + rinlinejQuery = / jQuery\d+="(?:\d+|null)"/g, + rleadingWhitespace = /^\s+/, + rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig, + rtagName = /<([\w:]+)/, + rtbody = /]", "i"), + // checked="checked" or checked + rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i, + rscriptType = /\/(java|ecma)script/i, + rcleanScript = /^\s*", "" ], + legend: [ 1, "
    ", "
    " ], + thead: [ 1, "", "
    " ], + tr: [ 2, "", "
    " ], + td: [ 3, "", "
    " ], + col: [ 2, "", "
    " ], + area: [ 1, "", "" ], + _default: [ 0, "", "" ] + }, + safeFragment = createSafeFragment( document ); + +wrapMap.optgroup = wrapMap.option; +wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; +wrapMap.th = wrapMap.td; + +// IE can't serialize and + + + + + + + + + +
    +
    +
    +
    + +
    +

    7. Contacts & Notices¶

    +
    +

    7.1. Contacts¶

    +
    +
    ADLINK Technology Corporation
    +
    400 TradeCenter
    +
    Suite 5900
    +
    Woburn, MA
    +
    01801
    +
    USA
    +
    Tel: +1 781 569 5819
    +
    +
    +
    ADLINK Technology Limited
    +
    The Edge
    +
    5th Avenue
    +
    Team Valley
    +
    Gateshead
    +
    NE11 0XA
    +
    UK
    +
    Tel: +44 (0)191 497 9900
    +
    +
    +
    ADLINK Technology SARL
    +
    28 rue Jean Rostand
    +
    91400 Orsay
    +
    France
    +
    Tel: +33 (1) 69 015354
    +
    +

    Web: http://ist.adlinktech.com/

    +

    Contact: http://ist.adlinktech.com

    +

    E-mail: ist_info@adlinktech.com

    +

    LinkedIn: https://www.linkedin.com/company/79111/

    +

    Twitter: https://twitter.com/ADLINKTech_usa

    +

    Facebook: https://www.facebook.com/ADLINKTECH

    +
    +
    +

    7.2. Notices¶

    +

    Copyright © 2018 ADLINK Technology Limited. All rights reserved.

    +

    This document may be reproduced in whole but not in part. The information contained in this +document is subject to change without notice and is made available in good faith without +liability on the part of ADLINK Technology Limited. All trademarks acknowledged.

    +
    +
    + + +
    +
    +
    +
    +
    + +

    Table Of Contents

    + + +

    Previous topic

    +

    6. Demo iShapes Example

    +

    This Page

    + + + +
    +
    +
    +
    + + + + \ No newline at end of file diff --git a/docs/html/DDSLabVIEWGuide/dds_vis.html b/docs/html/DDSLabVIEWGuide/dds_vis.html new file mode 100644 index 000000000..a81d7259a --- /dev/null +++ b/docs/html/DDSLabVIEWGuide/dds_vis.html @@ -0,0 +1,583 @@ + + + + + + + + 3. Vortex DDS Virtual Instruments (VIs) — The Vortex OpenSplice LabVIEW Guide + + + + + + + + + + + + + + + +
    +
    +
    +
    + +
    +

    3. Vortex DDS Virtual Instruments (VIs)¶

    +

    The DDS LabVIEW Integration provides a function palette with custom virtual instruments (VIs) to model reading and writing data with DDS.

    +
    +VortexDDS VIs +
    +

    The Vortex DDS LabVIEW VIs are included in VortexDDS functions palette.

    +

    The following DDS VIs are provided:

    +
    +
      +
    • create_participant.vi
    • +
    • create_publisher.vi
    • +
    • create_subscriber.vi
    • +
    • create_writer.vi
    • +
    • create_reader.vi
    • +
    • wait_historical_data.vi
    • +
    • delete_entity.vi
    • +
    +
    +
    +

    3.1. DDS VIs usage¶

    +

    The typical way to model a DDS application in LabVIEW is as follows:

    +
      +
    • model your DDS topics using IDL
    • +
    • using the LabVIEW IDLPP process generate DDS Topic, Read and Write VIs from the IDL file
    • +
    • add the generated VIs to your LabVIEW project
    • +
    • create a DDS LabVIEW application using the VortexDDS functions palette and the generated VIs from the previous step
    • +
    +
    +
    +

    3.2. QoS Profiles¶

    +

    In DDS - “The Data-Distribution Service (DDS) relies on the usage of QoS. A QoS (Quality of Service) is a set of characteristics that controls some aspect of the behavior of the DDS Service.”

    +

    Each DDS entity VI has an associated QoS profile. By default, the OSPL default profile is used. An XML file that specifies QoS profiles can be used to set the QoS of a DDS entity.

    +

    The QoS profile of an entity is set using the qos_uri and qos_profile terminals.

    +

    Please see section QoS Provider for more information.

    +
    +
    +

    3.3. create_participant.vi¶

    +

    The create_participant VI represents a DDS domain participant entity.

    +

    In DDS - “A domain participant represents the local membership of the application in a domain. A domain is a distributed concept that links all the applications able to communicate with each other. It represents a communication plane: only the publishers and subscribers attached to the same domain may interact.”

    +

    The domain id is the OSPL default domain id specified in the OSPL configuration file (file pointed by “OSPL_URI” environment variable).

    +
    +create_participant VI +
    + +++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Terminal TypeOptionalNameDescriptionOutput consumed by
    OutputnoppDDS Domain Participant +entity instancecreate_publisher.vi +create_subscriber.vi +RegisterTopic.vi
    Inputyesqos_uriQoS file uri 
    Inputyesqos_profileName of QoS profile 
    Inputyeserror in (no error)Input Error cluster 
    Outputyeserror outError out cluster 
    +
    +
    +

    3.4. create_publisher.vi¶

    +

    The create_publisher VI represents a DDS publisher entity.

    +

    In DDS, a publisher is “an object responsible for data distribution. It may publish data of different data types.”

    +
    +create_publisher VI +
    + +++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Terminal TypeOptionalNameDescriptionOutput consumed by
    InputnoppDDS Domain Participant +entity instance 
    Inputyesqos_uriQoS file uri 
    Inputyesqos_profileName of QoS profile 
    Inputyeserror in (no error)Input Error cluster 
    OutputnopubDDS publisher +entity instancecreate_writer.vi
    Outputyeserror outError out cluster 
    +
    +
    +

    3.5. create_subscriber.vi¶

    +

    The create_subscriber VI represents a DDS subscriber entity.

    +

    In DDS, a subscriber is “an object responsible for receiving published data and making it available to the receiving application. It may receive and dispatch data of different specified types.”

    +
    +create_subscriber VI +
    + +++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Terminal TypeOptionalNameDescriptionOutput consumed by
    InputnoppDDS Domain Participant +entity instance 
    Inputyesqos_uriQoS file uri 
    Inputyesqos_profileName of QoS profile 
    Inputyeserror in (no error)Input Error cluster 
    OutputnosubDDS subscriber +entity instancecreate_reader.vi
    Outputyeserror outError out cluster 
    +
    +
    +

    3.6. create_writer.vi¶

    +

    The create_writer VI represents a DDS data writer entity.

    +

    In DDS - “The DataWriter is the object the application must use to communicate to a publisher the existence and value of data-objects of a given type.”

    +
    +create_writer VI +
    + +++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Terminal TypeOptionalNameDescriptionOutput consumed by
    InputnopubDDS publisher +entity instance 
    InputnotopicDDS Topic +entity instance 
    Inputyesqos_uriQoS file uri 
    Inputyesqos_profileName of QoS profile 
    Inputyeserror in (no error)Input Error cluster 
    OutputnowriterDDS writer +entity instancewrite.vi
    Outputyeserror outError out cluster 
    +
    +
    +

    3.7. create_reader.vi¶

    +

    The create_reader VI represents a DDS data reader entity.

    +

    In DDS - “To access the received data, the application must use a typed DataReader attached to the subscriber.”

    +
    +create_reader VI +
    + +++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Terminal TypeOptionalNameDescriptionOutput consumed by
    InputnosubDDS subscriber +entity instance 
    InputnotopicDDS Topic +entity instance 
    Inputyesqos_uriQoS file uri 
    Inputyesqos_profileName of QoS profile 
    Inputyeserror in (no error)Input Error cluster 
    OutputnoreaderDDS reader +entity instanceread.vi
    Outputyeserror outError out cluster 
    +
    +
    +

    3.8. wait_historical_data.vi¶

    +

    The wait_historical_data VI specifies that the Reader will wait for historical data to arrive. The timeout terminal is for setting time period (in seconds) determining how long the Reader should wait for the historical data. If the timeout is reached, then any remaining historical data may be interleaved with new data.

    +
    +wait_historical VI +
    + +++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Terminal TypeOptionalNameDescriptionOutput consumed by
    InputnoreaderDDS Reader +entity instance 
    Inputyeshistorical_timeoutwait for historical data +timeout (seconds) 
    Inputyeserror in (no error)Input Error cluster 
    Outputyeserror outError out cluster 
    +
    +
    +

    3.9. delete_entity.vi¶

    +

    The delete_entity VI is used to delete a DDS entity. Connect the DDS participant to the entity terminal to delete the participant (pp) in a LabVIEW DDS application.

    +
    +
    NOTE: If the user application VI stops due to an error and does not run to completion, the participant entity is not deleted and leaks occur. The participants are deleted once the user closes LabVIEW.
    +
    +delete_entity VI +
    + +++++++ + + + + + + + + + + + + + + + + +
    Terminal TypeOptionalNameDescriptionOutput consumed by
    InputnoentityDDS entity instance 
    +
    +
    + + +
    +
    +
    +
    + +
    +
    +
    + + + + \ No newline at end of file diff --git a/docs/html/DDSLabVIEWGuide/example.html b/docs/html/DDSLabVIEWGuide/example.html new file mode 100644 index 000000000..5d825d3f2 --- /dev/null +++ b/docs/html/DDSLabVIEWGuide/example.html @@ -0,0 +1,266 @@ + + + + + + + + 6. Demo iShapes Example — The Vortex OpenSplice LabVIEW Guide + + + + + + + + + + + + + + + +
    +
    +
    +
    + +
    +

    6. Demo iShapes Example¶

    +

    A simple demo iShapes example is provided to demonstrates the basic capabilities of the LabVIEW DDS integration. It displays DDS communication between LabVIEW and pure DDS applications.

    +

    The demo_ishapes.vi example (LabVIEW application) can be found using the NI Example Finder in LabVIEW:

    +
    +NI Example Finder +
    +

    The demo_ishapes.exe (DDS application) can be found in the following directory.

    +
    +
    OSPL_HOME/bin/demo_ishapes.exe
    +
    +

    6.1. Example Files¶

    +

    An explanation of what each example file does is provided below.

    +
    +Demo ishapes files +
    +

    DDS_Data Folder

    +

    This folder contains the idl file and artifacts generated from idlpp process.

    +

    ishape.idl

    +
      +
    • Defines the ShapeType in idl
    • +
    • Used to generate the LabVIEW DDS VIs via idlpp
    • +
    +

    ishape.idl.xml

    +
      +
    • Defines the topic descriptor from idl file
    • +
    +

    ShapeType_CicoTable.vi

    +
      +
    • Defines the copy-in, copy-out table information for mapping IDL to LabVIEW types
    • +
    +

    ShapeType.ctl

    +
      +
    • Defines a ShapeType cluster in LabVIEW; generated from idlpp
    • +
    • The ShapeType represents a DDS topic type
    • +
    • ShapeType specifies 4 properties: color, x, y, shapesize
    • +
    +

    ShapeType_Read.vi

    +
      +
    • DDS Read ShapeType samples
    • +
    +

    ShapeType_Write.vi

    +
      +
    • DDS Write ShapeType samples
    • +
    +

    ShapeType_Topic.vi

    +
      +
    • DDS Register ShapeType topic
    • +
    +

    DDS_PersistentQoS_All.xml

    +
      +
    • XML file that specifies the DDS QoS (quality of service) settings for RegisterTopic
    • +
    +

    DDS_VolatileQoS_All.xml

    +
      +
    • XML file that specifies the DDS QoS (quality of service) settings for Reader and Writer entities
    • +
    +

    demo_ishapes.vi

    +
      +
    • Creates a participant on the default DDS domain
    • +
    • Registers a ShapeType Topic to Read and to Write to one of the three topics: Circle, Square or Triangle
    • +
    • Subscribes to the shape and color from demo_ishapes.exe DDS application
    • +
    • As soon as they match, demo_ishapes.vi publishes to the DDS application and follows the subscribed shape
    • +
    +
    +
    +

    6.2. Steps to run example¶

    +

    Steps:

    +
      +
    1. Open command shell and run script to setup environment variables.

      +
      +

      Linux

      +
        +
      • Open a Linux terminal.

        +
      • +
      • Navigate to directory containing release.com file.

        +

        /INSTALLDIR/ADLINK/Vortex_v2/Device/VortexOpenSplice/6.9.x/HDE/x86_64.linux

        +
      • +
      • Run release.com. (Type in “. release.com†at command line.)

        +
      • +
      +

      Windows

      +
        +
      • Open a command prompt.

        +
      • +
      • Navigate to directory containing release.bat file.

        +

        INSTALLDIR/ADLINK/Vortex_v2/Device/VortexOpenSplice/6.9.x/HDE/x86_64.win64

        +
      • +
      • Run release.bat. (Type in “release.bat†at command line.)

        +
      • +
      +
      +
    2. +
    3. Navigate to the directory that contains demo_ishapes.exe DDS application and run the application using the command shell used in Step 1.

      +
      +

      Linux

      +

      /INSTALLDIR/ADLINK/Vortex_v2/Device/VortexOpenSplice/6.9.x/HDE/x86_64.linux/bin

      +
        +
      • Run demo_ishapes.exe (Type in “./demo_ishapes.exe &†at command line)
      • +
      +

      Windows

      +

      INSTALLDIR/ADLINK/Vortex_v2/Device/VortexOpenSplice/6.9.x/HDE/x86_64.win64/bin

      +
        +
      • Run demo_ishapes.exe (Type in “demo_ishapes.exe &†at command line)
      • +
      +
      +
    4. +
    5. Start LabVIEW using the SAME command shell used in Step 1. Open the demo_ishapes.vi using the NI Example Finder in LabVIEW.

      +

      NOTE: If LabVIEW and the demo_ishapes.exe application are NOT started from a command shell with the correct OSPL environment variables set, the example will not work.

      +
    6. +
    +
      +
    1. In the LabVIEW demo_ishapes.vi application make the following selections:

      +

      Read Shape: Circle +Track color: GREEN

      +

      Write Shape: Triangle +Write color: MAGENTA

      +
      +Demo ishapes LabVIEW selection +
      +
    2. +
    +
      +
    1. In the demo_ishapes.exe DDS application make the following selections:

      +

      Shape: Circle +Color: Green +Click Publish

      +

      Shape: Triangle +Click Subscribe

      +
      +Demo ishapes DDS application selection +
      +
    2. +
    3. Run the LabVIEW demo_ishapes.vi application

      +
    4. +
    5. To stop the LabVIEW application, click on STOP on the front panel of the demo_ishapes.vi.

      +
    6. +
    +
    +
    +

    6.3. Output¶

    +

    LabVIEW application publishes samples to the DDS application. In the demo_ishapes.exe application, the Triangle follows the Circle.

    +
    +Example outputss +
    +
    +
    + + +
    +
    +
    +
    +
    + +

    Table Of Contents

    + + +

    Previous topic

    +

    5. QoS Provider

    +

    Next topic

    +

    7. Contacts & Notices

    +

    This Page

    + + + +
    +
    +
    +
    + + + + \ No newline at end of file diff --git a/docs/html/DDSLabVIEWGuide/genindex.html b/docs/html/DDSLabVIEWGuide/genindex.html new file mode 100644 index 000000000..c017ffe06 --- /dev/null +++ b/docs/html/DDSLabVIEWGuide/genindex.html @@ -0,0 +1,94 @@ + + + + + + + + + Index — The Vortex OpenSplice LabVIEW Guide + + + + + + + + + + + + + +
    +
    +
    +
    + + +

    Index

    + +
    + +
    + + +
    +
    +
    +
    +
    + + + + + + +
    +
    +
    +
    + + + + \ No newline at end of file diff --git a/docs/html/DDSLabVIEWGuide/index.html b/docs/html/DDSLabVIEWGuide/index.html new file mode 100644 index 000000000..b402bfaa6 --- /dev/null +++ b/docs/html/DDSLabVIEWGuide/index.html @@ -0,0 +1,177 @@ + + + + + + + + DDS LabVIEW Guide — The Vortex OpenSplice LabVIEW Guide + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/html/DDSLabVIEWGuide/installation.html b/docs/html/DDSLabVIEWGuide/installation.html new file mode 100644 index 000000000..c7e5d958b --- /dev/null +++ b/docs/html/DDSLabVIEWGuide/installation.html @@ -0,0 +1,229 @@ + + + + + + + + 2. Installation — The Vortex OpenSplice LabVIEW Guide + + + + + + + + + + + + + + + +
    +
    +
    +
    + +
    +

    2. Installation¶

    +

    This section describes the procedure to install the Vortex DDS LabVIEW Integration on a Linux or Windows platform.

    +
    +

    2.1. System Requirements¶

    +
      +
    • Operating System: Windows or Linux
    • +
    • LabVIEW 2017 installed
    • +
    +
    +
    +

    2.2. OpenSplice (OSPL) and DDS LabVIEW Installation¶

    +

    Steps:

    +
      +
    1. Install OSPL. The DDS LabVIEW Integration is included in this installer.
    2. +
    3. Setup OSPL license. Copy the license.lic file into the appropriate license directory.
    4. +
    +
    +
    /INSTALLDIR/ADLINK/Vortex_v2/license
    +
      +
    1. LabVIEW installation files are contained in a tools/labview folder.
    2. +
    +
    +
    Example: +/INSTALLDIR/ADLINK/Vortex_v2/Device/VortexOpenSplice/6.9.x/HDE/x86_64.linux/tools/labview
    +
    +
    +

    2.3. OpenSplice (OSPL) Configuration¶

    +

    By default OSPL uses single process configuration.

    +
    +
    +

    2.4. DDS LabVIEW Installation¶

    +
    +

    2.4.1. Linux¶

    +
      +
    1. Open a command shell and navigate to

      +

      /INSTALLDIR/ADLINK/Vortex_v2/Device/VortexOpenSplice/6.9.x/HDE/x86_64.linux/tools/labview

      +
    2. +
    3. Unzip the “adlink-dds-labview-linux-install.tar.gz”.

      +
    4. +
    5. Run the install_vortex_dds_ubuntu.sh script as a super user.

      +

      sudo ./install_vortex_dds_ubuntu.sh

      +

      NOTE: The installer sets the default LabVIEW installation path to /usr/local/natinst/LabVIEW-2017-64. To override this installation directory, run the install script and pass the install directory as an argument:

      +

      sudo ./install_vortex_dds_ubuntu.sh /path/to/your/LabVIEW/installation

      +
    6. +
    7. LabVIEW will open and allow the installation Virtual Instrument (VI) run to completion.

      +
    8. +
    9. After the installation is complete close LabVIEW. Installation takes effect the next time you start LabVIEW.

      +
    10. +
    +
    +
    +

    2.4.2. Windows¶

    +
      +
    1. In a file browser, navigate to

      +

      /INSTALLDIR/ADLINK/Vortex_v2/Device/VortexOpenSplice/6.9.x/HDE/x86_64.windows/tools/labview

      +
    2. +
    3. Double click on the file “adlink_lib_vortexdds-1.0.0.1â€. This will bring up the VI Package Manager installer dialog box. Select the LabVIEW version to install (32-bit or 64-bit). Select Install.

      +
    4. +
    +
    +DDS windows install +
    +
      +
    1. After the installation is complete close LabVIEW. Installation takes effect the next time you start LabVIEW.
    2. +
    +
    +
    +
    +

    2.5. Running LabVIEW¶

    +

    Steps:

    +
      +
    1. Open command shell and run script to setup environment variables.

      +
      +

      Linux

      +
        +
      • Open a Linux terminal.

        +
      • +
      • Navigate to directory containing release.com file.

        +

        /INSTALLDIR/ADLINK/Vortex_v2/Device/VortexOpenSplice/6.9.x/HDE/x86_64.linux

        +
      • +
      • Run release.com. (Type in “. release.com†at command line.)

        +
      • +
      +

      Windows

      +
        +
      • Open a command prompt.

        +
      • +
      • Navigate to directory containing release.bat file.

        +

        INSTALLDIR/ADLINK/Vortex_v2/Device/VortexOpenSplice/6.9.x/HDE/x86_64.win64

        +
      • +
      • Run release.bat. (Type in “release.bat†at command line.)

        +
      • +
      +
      +
    2. +
    3. Start LabVIEW using the SAME command shell used in Step 1.

      +
      +

      NOTE: If LabVIEW is NOT started from a command shell with the correct OSPL environment variables set, errors will occur when attempting to use DDS LabVIEW virtual instruments.

      +
      +
    4. +
    +
    +
    + + +
    +
    +
    +
    +
    + +

    Table Of Contents

    + + +

    Previous topic

    +

    1. Introduction

    +

    Next topic

    +

    3. Vortex DDS Virtual Instruments (VIs)

    +

    This Page

    + + + +
    +
    +
    +
    + + + + \ No newline at end of file diff --git a/docs/html/DDSLabVIEWGuide/introduction.html b/docs/html/DDSLabVIEWGuide/introduction.html new file mode 100644 index 000000000..1ebf034be --- /dev/null +++ b/docs/html/DDSLabVIEWGuide/introduction.html @@ -0,0 +1,141 @@ + + + + + + + + 1. Introduction — The Vortex OpenSplice LabVIEW Guide + + + + + + + + + + + + + + + +
    +
    +
    +
    + +
    +

    1. Introduction¶

    +

    The DDS LabVIEW Integration provides users with DDS custom virtual instruments (VIs) to model DDS communication between LabVIEW and pure DDS applications.

    +
    +

    1.1. DDS¶

    +

    What is DDS?

    +

    “The Data Distribution Service (DDSâ„¢) is a middleware protocol and API standard for data-centric connectivity from the Object Management Group® (OMG®). It integrates the components of a system together, providing low-latency data connectivity, extreme reliability, and a scalable architecture that business and mission-critical Internet of Things (IoT) applications need.â€

    +

    “The main goal of DDS is to share the right data at the right place at the right time, even between time-decoupled publishers and consumers. DDS implements global data space by carefully replicating relevant portions of the logically shared dataspace.†DDS specification

    +
    +DDS +
    +

    Further Documentation

    +

    http://portals.omg.org/dds/

    +

    http://ist.adlinktech.com/

    +
    +
    +

    1.2. LabVIEW¶

    +

    What is LabVIEW?

    +

    “LabVIEW is systems engineering software for applications that require test, measurement, and control with rapid access to hardware and data insights. The LabVIEW programming environment simplifies hardware integration for engineering applications so that you have a consistent way to acquire data from NI and third-party hardware. +The LabVIEW programming environment simplifies hardware integration for engineering applications so that you have a consistent way to acquire data from NI and third-party hardware. LabVIEW reduces the complexity of programming, so you can focus on your unique engineering problem. LabVIEW enables you to immediately visualize results with built-in, drag-and-drop engineering user interface creation and integrated data viewers. To turn your acquired data into real business results, you can develop algorithms for data analysis and advanced control with included math and signal processing IP or reuse your own libraries from a variety of tools. To ensure compatibility with other engineering tools, LabVIEW can interoperate with, and reuse libraries from, other software and open-source languages.â€

    +

    http://www.ni.com/en-ca/shop/labview/buy-labview.html

    +
    +
    + + +
    +
    +
    +
    +
    + +

    Table Of Contents

    + + +

    Previous topic

    +

    DDS LabVIEW Guide

    +

    Next topic

    +

    2. Installation

    +

    This Page

    + + + +
    +
    +
    +
    + + + + \ No newline at end of file diff --git a/docs/html/DDSLabVIEWGuide/objects.inv b/docs/html/DDSLabVIEWGuide/objects.inv new file mode 100644 index 000000000..b6b7777b5 --- /dev/null +++ b/docs/html/DDSLabVIEWGuide/objects.inv @@ -0,0 +1,7 @@ +# Sphinx inventory version 2 +# Project: Vortex OpenSplice LabVIEW Guide +# Version: 6.x +# The remainder of this file is compressed using zlib. +xÚm’]KÃ0†ïó+(¢GðÖ[;¤0eR¨—#kŽ] Mj’ÕùïMwR»ŽÝ5ïÇsòÑ–¬¶ŠŽ¢z6rGð Ú¬>îcgn ¿…¶!JcdÔÎ.ãçWnSgÖDçÔ•)ý/NFôæÔÁPžHúf¿¬°–Ó6²%‘ƒ¦Ÿqçäy‹_Þu •YÊbk¹«ËÕ'crç&ŽM›9¯ÔI×}Únsí:fg¾ŽY³Q61ÀXuCa ˜|.O+œ²/sý%ñíôÞ Z‘_²’³æ%ÿ³®‚M^Eö²OSè(»>=Æ‚–EqÌqœâʼnQ1cÅ¢œéõ• +0hÒœþèÈƋçÐvÐùì\Ĥa.ây±fnQTPgnyfß×ex«ž +á \ No newline at end of file diff --git a/docs/html/DDSLabVIEWGuide/qos_provider.html b/docs/html/DDSLabVIEWGuide/qos_provider.html new file mode 100644 index 000000000..03129191f --- /dev/null +++ b/docs/html/DDSLabVIEWGuide/qos_provider.html @@ -0,0 +1,192 @@ + + + + + + + + 5. QoS Provider — The Vortex OpenSplice LabVIEW Guide + + + + + + + + + + + + + + + +
    +
    +
    +
    + +
    +

    5. QoS Provider¶

    +

    Each Vortex DDS virtual instrument (VI) has a QoS file uri terminal and a QoS profile terminal. +These terminals are used to set the QoS profile. By default, the OSPL default profile is used. +In DDS - The Data-Distribution Service (DDS) relies on the usage of QoS. A QoS (Quality of Service) is a set of +characteristics that controls some aspect of the behavior of the DDS Service.

    +

    Each DDS VI has an associated QoS profile. By default, the OSPL default profile is used. An XML file that +specifies QoS profiles can be used to set the QoS of a DDS block.

    +

    The following section explains how the QoS is set for a DDS entity using the QoS Provider.

    +
    +

    5.1. QoS Provider File¶

    +

    Quality of Service for DDS entities is set using XML files based on the XML schema file DDS_QoSProfile.xsd. +These XML files contain one or more QoS profiles for DDS entities.

    +

    Note: Sample QoS Profile XML files can be found in the LabVIEW DDS examples directories.

    +
    +
    +

    5.2. QoS Profile¶

    +

    A QoS profile consists of a name. The file contains QoS +elements for one or more DDS entities. A skeleton file without any QoS values is displayed below to show +the structure of the file.

    +
    <dds xmlns="http://www.omg.org/dds/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    +            xsi:schemaLocation="file:DDS_QoSProfile.xsd">
    +    <qos_profile name="DDS QoS Profile Name">
    +        <datareader_qos></datareader_qos>
    +        <datawriter_qos></datawriter_qos>
    +        <domainparticipant_qos></domainparticipant_qos>
    +        <subscriber_qos></subscriber_qos>
    +        <publisher_qos></publisher_qos>
    +        <topic_qos></topic_qos>
    +    </qos_profile>
    +</dds>
    +
    +
    +

    Example: Specify Publisher Partition

    +

    The example below specifies the publisher’s partitions as A and B.

    +
    <publisher_qos>
    +    <partition>
    +        <name>
    +            <element>A</element>
    +            <element>B</element>
    +        </name>
    +    </partition>
    +</publisher_qos>
    +
    +
    +
    +
    +

    5.3. Setting QoS Profile in LabVIEW¶

    +

    The QoS Profiles from the XML file can be obtained using the List_qos_profiles Tools menu in LabVIEW.

    +

    Tools/VortexDDS/List_qos_profiles

    +
    +QoS Profile Tools +
    +

    Steps to set the QoS Profile

    +
      +
    1. A QoS Provider file can be selected by browsing to the XML file from the List_qos_profiles dialog box. Once a valid QoS file is chosen the Available qos profiles table is populated with the list of qos profiles that are available in the QoS XML file. If there are QoS profiles found in the file, then Copy to Clipboard button will be enabled.
    2. +
    3. Select the QoS Profile that you want to use and click on Copy to Clipboard.
    4. +
    +
    +List qos profiles +
    +
      +
    1. In your VI, create a String constant and press Ctrl + V. Connect this String constant to the DDS VI qos_profile terminal. Set the qos_uri as a LabVIEW control or constant and navigate to the path of the QoS Provider file.
    2. +
    +
    +Set QoS +
    +

    The qos_profile and qos_uri are optional terminals. If they are not set then the default QoS settings will be used.

    +

    Note: Seeing the QoS Profile in the list only guarantees the QoS Profile exists in the file. +It does not mean the qos tag exists for the entity. The user is responsible for verifying the entity qos +tag exists in the file.

    +
    +
    + + +
    +
    +
    +
    +
    + +

    Table Of Contents

    + + +

    Previous topic

    +

    4. LabVIEW Generation from IDL

    +

    Next topic

    +

    6. Demo iShapes Example

    +

    This Page

    + + + +
    +
    +
    +
    + + + + \ No newline at end of file diff --git a/docs/html/DDSLabVIEWGuide/search.html b/docs/html/DDSLabVIEWGuide/search.html new file mode 100644 index 000000000..bcdc6c6be --- /dev/null +++ b/docs/html/DDSLabVIEWGuide/search.html @@ -0,0 +1,101 @@ + + + + + + + + Search — The Vortex OpenSplice LabVIEW Guide + + + + + + + + + + + + + + + + + + + +
    +
    +
    +
    + +

    Search

    +
    + +

    + Please activate JavaScript to enable the search + functionality. +

    +
    +

    + From here you can search these documents. Enter your search + words into the box below and click "search". Note that the search + function will automatically search for all of the words. Pages + containing fewer words won't appear in the result list. +

    +
    + + + +
    + +
    + +
    + +
    +
    +
    +
    +
    + +
    +
    +
    +
    + + + + \ No newline at end of file diff --git a/docs/html/DDSLabVIEWGuide/searchindex.js b/docs/html/DDSLabVIEWGuide/searchindex.js new file mode 100644 index 000000000..a6c8687e2 --- /dev/null +++ b/docs/html/DDSLabVIEWGuide/searchindex.js @@ -0,0 +1 @@ +Search.setIndex({envversion:42,terms:{all:[5,3],concept:[5,7],edg:3,queri:7,consum:[4,5,7],follow:[5,2,7,6],skeleton:2,program:4,shapetype_writ:6,keylist:7,ist_info:3,unzip:1,string:[2,7],internet:4,hardwar:4,facebook:3,xmlschema:2,brows:2,relev:4,button:2,list:2,dataread:5,uint32:7,unsupport:7,team:3,pleas:5,x86_64:[1,6],tel:3,annot:7,second:[5,7],pass:1,further:4,click:[1,2,6],append:7,compat:4,what:[4,6],appear:7,section:[5,1,2],abl:5,"while":7,access:[4,5],delet:5,version:1,run:[5,7],dds_volatileqos_al:6,qos_profil:[5,2],"new":5,"public":7,datareader_qo:2,centric:4,path:[1,2,7],"0xa":3,valu:[5,2,7],wait:[5,7],box:[1,2,7],search:0,technolog:3,precis:7,ctl:[6,7],extrem:4,chang:3,overrid:1,via:6,primit:7,modul:7,avenu:3,"boolean":7,uniqu:4,instal:0,installdir:[1,6],select:[7,1,2,6],describ:[1,7],usa:3,commun:[4,5,6],doubl:[1,7],regist:[6,7],next:1,busi:4,tradecent:3,wstring:7,type:[5,1,6,7],more:[5,2],uint8:7,visual:4,compani:3,must:[5,7],uint64:7,scalabl:4,writerhandl:7,setup:[1,6],work:6,focu:4,descriptor:6,remain:5,tag:2,can:[4,5,2,7,6],control:[4,5,2,7],prompt:[1,6],tar:1,process:[4,5,1,6,7],sudo:1,share:4,indic:7,topic:[5,6,7],critic:4,sourc:4,want:2,magenta:6,unsign:7,occur:[5,1,7],goal:4,thing:4,how:[5,2],pure:[4,6],verifi:2,simpl:6,map:[6,7],int16:7,dialog:[1,2,7],vortex_v2:[1,6],after:[1,7],membership:5,plane:5,mai:[5,3],data:[4,5,2,7],demonstr:6,modulename_structnam:7,"short":7,attempt:1,third:4,bind:7,correspond:7,element:[2,7],inform:[5,6,7,3],int64:7,allow:1,ospl_uri:5,insight:4,soon:6,entiti:[5,2,7,6],typedef:7,group:4,chosen:[2,7],platform:1,window:[0,6],complex:4,mail:3,main:4,domainparticipanthandl:7,good:3,thei:[7,2,6],topicnam:7,front:6,introduct:0,write_after_timeout:7,drop:4,timeout:[5,7],each:[5,2,7,6],"_timeout":7,found:[2,6],dds_qosprofil:2,mean:2,domain:[5,6,7],interleav:5,ne11:3,procedur:1,connect:[4,5,2],happen:7,dispos:7,out:[5,6,7],variabl:[5,1,6],read_condit:7,publish:[4,5,2,7,6],profil:7,reader:[5,6,7],dds_persistentqos_al:6,correct:[1,6],math:4,franc:3,partit:2,navig:[1,2,6],advanc:4,given:5,pub:5,standard:4,base:[2,7],releas:[1,6],org:[4,2],ist:[4,3],turn:4,place:4,natinst:1,"5th":3,oper:[1,7],softwar:4,onc:[5,2],arrai:7,qualiti:[5,2,6],number:7,done:7,open:[4,1,6],readerhandl:7,differ:5,script:[1,6],associ:[5,2],interact:5,system:0,attach:5,circl:6,termin:[5,1,2,7,6],schema:2,shell:[1,6],option:[5,2,7],dds_data:6,tool:[4,1,2,7],copi:[7,1,2,6],dataspac:4,specifi:[5,2,7,6],part:3,pragma:7,wchar:7,cicot:7,shapetype_top:6,provid:[4,0,5,6],structur:[2,7],publisher_qo:2,project:5,reus:4,qos_uri:[5,2],browser:1,"function":5,viewer:4,query_express:7,argument:1,packag:1,xmln:2,have:[4,7],close:[5,1],need:4,create_read:7,engin:4,squar:6,equival:7,lic:1,note:[5,1,2,7,6],without:[2,3],take:[1,7],which:7,environ:[4,5,1,6],singl:[1,7],even:4,distribut:[4,5,2,7],track:6,previou:5,reach:5,model:[4,5],sub:5,woburn:3,uri:[5,2,7],doe:[5,2,6],runtim:7,determin:5,adlink_lib_vortexdd:1,shop:4,show:[2,7],carefulli:4,bring:1,xml:[5,2,6],onli:[5,2,7],locat:7,acquir:4,copyright:3,menu:[2,7],explain:2,configur:[0,5],should:5,latenc:4,folder:[1,6,7],local:[5,1],palett:5,express:7,stop:[5,6],mission:4,newpag:[5,1,2,7,6],requir:[0,7],bat:[1,6],enabl:[4,2],integr:[4,5,1,6,7],neeed:7,contain:[6,1,2,7,3],valid:[2,7],set:[0,5,1,6],maximum:7,datatyp:7,see:[5,2],result:4,write_dispos:7,respons:[5,2],reserv:3,subject:3,particip:[5,6,7],state:7,between:[4,6],paramet:7,omg:[4,2],kei:7,popul:2,rostand:3,addit:7,read_oper:7,instanc:[5,2,7],logic:4,whole:3,topichandl:7,shapetype_read:6,point:[5,7],color:6,arriv:5,dispatch:5,linux:[0,6],typic:5,liabil:3,sarl:3,union:7,trademark:3,due:5,compon:4,basic:6,immedi:4,convert:7,ani:[5,2,7],togeth:4,replic:4,interoper:4,servic:[4,5,2,6],properti:6,histor:5,defin:[6,7],hde:[1,6],match:[6,7],behavior:[5,2],error:[5,1,7],bin:6,gateshead:3,create_writ:7,ctrl:2,tabl:[6,7],linkedin:3,cluster:[5,6,7],topic_qo:2,incom:7,shapetyp:6,develop:4,receiv:5,parti:4,make:[5,6],same:[5,1,6],writer:[5,6,7],domainparticipant_qo:2,html:4,document:[4,3],complet:[5,1],http:[4,2,3],iot:4,upon:7,effect:1,wait_pub_match:7,capabl:6,portal:4,user:[4,5,1,2,7],applic:[4,5,6,7],decoupl:4,implement:4,built:4,demo_ishap:6,appropri:1,com:[4,1,6,3],inherit:7,exampl:7,command:[1,6],wait_available_data:7,thi:[6,1,2,7,3],jean:3,max_sampl:7,explan:6,comment:7,protocol:4,obtain:2,detail:7,shape:6,aspect:[5,2],languag:4,web:3,rapid:4,struct:7,add:5,uint16:7,list_qos_profil:2,input:[5,7],finder:6,real:4,int32:7,subscriber_qo:2,ospl_hom:6,adlinktech:[4,3],period:5,datawriter_qo:2,press:2,bit:1,characterist:[5,2],licens:1,name:[5,2,7],measur:4,specif:[4,7],success:7,corpor:3,signal:4,shapes:6,api:4,xsd:2,output:[5,7],xsi:2,page:0,www:[4,2,3],right:[4,3],vortexopensplic:[1,6],simplifi:4,acknowledg:3,twitter:3,creation:4,some:[5,2],global:4,sampl:[7,2,6],guarante:2,librari:4,deselect:7,leak:5,octet:7,datawrit:5,middlewar:4,condit:7,reproduc:3,object:[4,5],vortexdd:[5,2,7],win64:[1,6],"enum":7,rue:3,step:5,historical_timeout:5,qosprofilepath:7,"super":1,panel:6,chapter:7,faith:3,query_paramet:7,manag:[4,1],dds_sample_info_arrai:7,includ:[4,5,1],ospl:[0,5,6,7],adlinktech_usa:3,no_of_sampl:7,block:2,own:4,opensplic:[0,5,6,7,3],devic:[1,6],"float":7,orsai:3,three:6,ensur:[4,7],your:[4,5,1,2],triangl:6,wai:[4,5],support:7,vallei:3,"long":[5,7],custom:[4,5],avail:[5,2,7,3],start:[1,6],reli:[5,2],interfac:4,low:4,suit:3,usr:1,analysi:4,schemaloc:2,subscrib:[5,6,7],bui:4,link:5,adlink:[1,6,3],line:[1,6],int8:7,made:3,consist:[4,2],"default":[5,1,2,7,6],displai:[2,6],below:[2,6],limit:3,write_op:7,problem:4,shapetype_cicot:6,constant:[2,7],creat:[5,2,7,6],mask:7,repres:[5,6,7],"char":7,exist:[5,2],incorrect:7,when:1,green:6,field:7,other:[4,5],install_vortex_dds_ubuntu:1,varieti:4,test:4,you:[4,1,2],import_idl:7,architectur:4,clipboard:2,sequenc:7,drag:4,sql:7,reduc:4,algorithm:4,directori:[1,2,6],reliabl:4,space:4,descript:[5,7],portion:4,qosprofilenam:7,time:[4,5,1]},objtypes:{},objnames:{},filenames:["index","installation","qos_provider","contacts","introduction","dds_vis","example","IDL-LabVIEW"],titles:["DDS LabVIEW Guide","2. Installation","5. QoS Provider","7. Contacts & Notices","1. Introduction","3. Vortex DDS Virtual Instruments (VIs)","6. Demo iShapes Example","4. LabVIEW Generation from IDL"],objects:{},titleterms:{set:2,create_writ:5,opensplic:1,demo:6,linux:1,indic:0,registertop:7,wait_historical_data:5,file:[7,2,6],tabl:0,instal:1,guid:0,idlpp:7,create_read:5,write:7,from:7,ishap:6,instrument:5,configur:1,system:1,virtual:5,profil:[5,2],delete_ent:5,window:1,contact:3,run:[1,6],read:7,vortex:5,gener:7,usag:5,artifact:7,step:6,notic:3,create_publish:5,requir:1,introduct:4,provid:2,filter:7,labview:[4,0,1,2,7],idl:7,exampl:6,create_particip:5,ospl:1,create_subscrib:5,output:6}}) \ No newline at end of file diff --git a/docs/html/DDSMATLABGuide/DDS-Classes.html b/docs/html/DDSMATLABGuide/DDS-Classes.html new file mode 100644 index 000000000..cba8a5238 --- /dev/null +++ b/docs/html/DDSMATLABGuide/DDS-Classes.html @@ -0,0 +1,511 @@ + + + + + + + + 3. MATLAB API for Vortex DDS Classes — The Vortex OpenSplice MATLAB Guide + + + + + + + + + + + + + + + +
    +
    +
    +
    + +
    +

    3. MATLAB API for Vortex DDS Classes¶

    +

    The DDS MATLAB Integration provides a class library with custom classes to read and write data with DDS.

    +

    The MATLAB DDS Classes are included in a Vortex package.

    +
    +

    3.1. API Usage patterns¶

    +

    The typical usage pattern for the MATLAB API for Vortex DDS is the following:

    +
      +
    • model your DDS topics using IDL
    • +
    • using idlpp -l matlab to compile your IDL into MATLAB topic classes. See MATLAB Generation from IDL.
    • +
    • start writting your MATLAB program using the MATLAB API for Vortex DDS.
    • +
    +

    The core classes you must use are Vortex.Topic and either Vortex.Reader or Vortex.Writer. +Other classes may be required, especially if you need to adjust the Quality of Service (QoS) defaults. +For details on setting QoS values with the API, see QoS Provider. +The following list shows the sequence in which you would use the Vortex classes:

    +
      +
    • If you require participant-level non-default QoS settings, create a Vortex.Participant instance. Pass the participant to subsequently created Vortex entities.
    • +
    • Create one or more Vortex.Topic instances for the IDL topics your program will read or write.
    • +
    • If you require publisher or subscriber level non-default QoS settings, create Vortex.Publisher and/or Vortex.Subscriber instances. Pass these to any created reader or writers. (The most common reason for changing publisher/subscriber QoS is to define non-default partitions.)
    • +
    • Create Vortex.Reader and/or Vortex.Writer classes from the Vortex.Topic instances that you created.
    • +
    • If you required data filtering, create Vortex.Query objects.
    • +
    • Create the core of program, creating instances of your topic classes and writing them; or, reading data and processing it.
    • +
    +
    +
    +

    3.2. Vortex.Topic¶

    +

    The MATLAB Topic class represents a DDS topic type. The DDS topic corresponds to a single data type. In DDS, data is distributed by publishing and subscribing topic data samples.

    +

    For a DDS Topic type definition, a corresponding MATLAB class must be defined in the MATLAB workspace. +This is either a class created by idlpp (see MATLAB Generation from IDL) or a manually +created MATLAB class (see MATLAB without IDL). +It is recommend that you create DDS Topic type definitions via IDL and idlpp.

    +

    API Examples

    +

    Create a Vortex DDS domain topic. Returns a topic instance, or throws a Vortex.DDSException if the topic cannot be created.

    +

    Create a topic named ‘Circle’ based on the DDS Topic type ShapeType with default participant and QoS:

    +
    topic = Vortex.Topic('Circle', ?ShapeType);
    +
    +
    +

    Note: In MATLAB, references to classes such as ShapeType are created by prefixing them with a +question mark (?). If the class is in a MATLAB package, then the fully qualified name must be used. +For example: ?ShapesDemo.Topics.ShapeType.

    +

    Create the ‘Circle’ topic with an explicitly created participant:

    +
    % dp: a Vortex.DomainParticipant instance
    +topic = Vortex.Topic(dp, 'Circle', ?ShapeType);
    +
    +
    +

    Create the ‘Circle’ topic with default participant and QoS profile:

    +
    % qosFileURI: a char array representing a file: URI
    +% qosProfile: a char array containing the name of a profile defined in the QoS File
    +topic = Vortex.Topic('Circle', ?ShapeType, qosFileURI, qosProfile);
    +
    +
    +

    Create the ‘Circle’ topic with explicit participant and QoS profile:

    +
    % dp: a Vortex.DomainParticipant instance
    +% qosFileURI: a char array representing a file: URI
    +% qosProfile: a char array containing the name of a profile defined in the QoS File
    +topic = Vortex.Topic(dp, 'Circle', ?ShapeType, qosFileURI, qosProfile);
    +
    +
    +
    +
    +

    3.3. Vortex.DomainParticipant¶

    +

    The Vortex.DomainParticipant class represents a DDS domain participant entity.

    +

    In DDS - “A domain participant represents the local membership of the application in a domain. A domain is a distributed concept that links all the applications able to communicate with each other. It represents a communication plane: only the publishers and subscribers attached to the same domain may interact.â€

    +

    Use of the Vortex.DomainParticipant class is optional. +The API provides a ‘default participant’, which is used if no explicit domain participant is provided. +The default participant is created on first usage, and is disposed when MATLAB exits. +Reasons for using an explicitly created domain participant are:

    +
      +
    • to provide non-default QoS settings.
    • +
    • to control the timing of participant creation and destruction.
    • +
    +

    API Examples

    +

    Create a Vortex DDS domain participant. Returns participant or throws a Vortex.DDSException if the participant cannot be created.

    +

    Create a domain participant in the default DDS domain (the one specified by the OSLP_URI environment variable):

    +
    dp = Vortex.DomainParticipant();
    +
    +
    +

    Create a domain participant on domain, specifying a domain id:

    +
    % domainId: an integer value
    +dp = Vortex.DomainParticipant(domainId);
    +
    +
    +

    Note: The underlying DCPS C99 API used by Vortex.DomainParticipant does not currently support this operation, and will result in a Vortex.DDSException being raised.

    +

    Create a participant on default domain with QoS profile:

    +
    % qosFileURI: a char array representing a file: URI
    +% qosProfile: a char array containing the name of a profile defined in the QoS File
    +dp = Vortex.DomainParticipant(qosFileURI, qosProfile);
    +
    +
    +

    Create a participant on domain with QoS profile:

    +
    % domainId: an integer value
    +% qosFileURI: a char array representing a file: URI
    +% qosProfile: a char array containing the name of a profile defined in the QoS File
    +dp = Vortex.DomainParticipant(domainId, qosFileURI, qosProfile);
    +
    +
    +
    +
    +

    3.4. Vortex.Publisher¶

    +

    The MATLAB Vortex.Publisher class represents a DDS publisher entity.

    +

    In DDS, a publisher is “an object responsible for data distribution. It may publish data of different data types.â€

    +

    Use of the Vortex.Publisher class is optional. +In it’s place, you can use a Vortex.DomainParticipant instance, or default to the default domain participant. +Reasons for explicitly creating a Vortex.Publisher instance are:

    +
      +
    • to specify non-default QoS settings, including specifying the DDS partition upon which samples are written.
    • +
    • to control the timing of publisher creation and deletion.
    • +
    +

    API Examples

    +

    Create a DDS Publisher entity. Returns publisher or throws a Vortex.DDSException if the publisher cannot be created.

    +

    Create a default publisher with default participant:

    +
    pub = Vortex.Publisher();
    +
    +
    +

    Create a publisher with an explicit participant:

    +
    % dp: a Vortex.DomainParticipant instance
    +pub = Vortex.Publisher(dp);
    +
    +
    +

    Create default publisher with default participant and QoS profile:

    +
    % qosFileURI: a char array representing a file: URI
    +% qosProfile: a char array containing the name of a profile defined in the QoS File
    +pub = Vortex.Publisher(qosFileURI, qosProfile);
    +
    +
    +

    Create a publisher with participant and QoS profile:

    +
    % dp: a Vortex.DomainParticipant instance
    +% qosFileURI: a char array representing a file: URI
    +% qosProfile: a char array containing the name of a profile defined in the QoS File
    +pub = Vortex.Publisher(dp, qosFileURI, qosProfile);
    +
    +
    +
    +
    +

    3.5. Vortex.Writer¶

    +

    The MATLAB Vortex.Writer class represents a DDS data writer entity.

    +

    In DDS - “The DataWriter is the object the application must use to communicate to a publisher the existence and value of data-objects of a given type.â€

    +

    A Vortex.Writer class is required in order to write data to a DDS domain. +It may be explicitly attached to a DDS publisher or a DDS domain participant; or, it is implicitly attached to the default domain participant.

    +

    A Vortex.Writer class instance references an existing Vortex.Topic instance.

    +

    API Examples

    +

    Create a Vortex DDS domain writer. Returns writer or throws a Vortex.DDSException if the writer cannot be created.

    +

    Create a writer for a topic, in the default domain participant and default QoS settings:

    +
    % topic: a Vortex.Topic instance
    +writer = Vortex.Writer(topic);
    +
    +
    +

    Create a writer within an explicitly specified publisher or domain participant:

    +
    % pubOrDp: a Vortex.Publisher or Vortex.DomainParticipant instance
    +% topic: a Vortex.Topic instance
    +writer = Vortex.Writer(pubOrDp, topic);
    +
    +
    +

    Create writer for a topic with explicit QoS profile:

    +
    % topic: a Vortex.Topic instance
    +% qosFileURI: a char array representing a file: URI
    +% qosProfile: a char array containing the name of a profile defined in the QoS File
    +writer = Vortex.Writer(topic, qosFileURI, qosProfile);
    +
    +
    +

    Create a writer with publisher or participant, topic and QoS profile:

    +
    % pubOrDp: a Vortex.Publisher or Vortex.DomainParticipant instance
    +% topic: a Vortex.Topic instance
    +% qosFileURI: a char array representing a file: URI
    +% qosProfile: a char array containing the name of a profile defined in the QoS File
    +writer = Vortex.Writer(pubOrDp, topic, qosFileURI, qosProfile);
    +
    +
    +

    Write a ShapeType topic class instance to a writer:

    +
    % writer: a Vortex.Writer instance
    +% ShapeType: a 'topic class' created manually or via IDLPP
    +data = ShapeType(); % create an object instance
    +% set data values...
    +data.color = 'RED';
    +% ... set other values ...
    +
    +ddsStatus = writer.write(data);
    +
    +
    +

    Note: the returned status value is 0 for success, and negative for failure. Use the Vortex.DDSException class to decode an failure status.

    +

    Dispose a DDS topic instance:

    +
    % writer: a Vortex.Writer instance
    +% ShapeType: a 'topic class' created manually or via IDLPP
    +data = ShapeType(); % create an object instance
    +% set data key values...
    +data.color = 'RED';
    +
    +ddsStatus = writer.dispose(data);
    +
    +
    +

    Note: the returned status value is 0 for success, and negative for failure. Use the Vortex.DDSException class to decode an failure status.

    +

    Unregister a DDS topic instance:

    +
    % writer: a Vortex.Writer instance
    +% ShapeType: a 'topic class' created manually or via IDLPP
    +data = ShapeType(); % create an object instance
    +% set data key values...
    +data.color = 'RED';
    +
    +ddsStatus = writer.unregister(data);
    +
    +
    +

    Note: the returned status value is 0 for success, and negative for failure. Use the Vortex.DDSException class to decode an failure status.

    +
    +
    +

    3.6. Vortex.Subscriber¶

    +

    The MATLAB Vortex.Subscriber class represents a DDS subscriber entity.

    +

    In DDS, a subscriber is “an object responsible for receiving published data and making it available to the receiving application. It may receive and dispatch data of different specified types.â€

    +

    Use of the Vortex.Subscriber class is optional. +In it’s place, you can use a Vortex.DomainParticipant instance, or default to the default domain participant. +Reasons for explicitly creating a Vortex.Subscriber instance are:

    +
      +
    • to specify non-default QoS settings, including specifying the DDS partition upon which samples are written.
    • +
    • to control the timing of subscriber creation and deletion.
    • +
    +

    API Examples

    +

    Create a Vortex DDS domain subscriber. Returns subscriber or throw a Vortex.DDSException if the subscriber cannot be created.

    +

    Create a subscriber within the default domain participant:

    +
    sub = Vortex.Subscriber();
    +
    +
    +

    Create a subscriber within an explicit participant:

    +
    % dp: a Vortex.DomainParticipant instance
    +sub = Vortex.Subscriber(dp);
    +
    +
    +

    Create subscriber within the default domain participant and with a QoS profile:

    +
    % qosFileURI: a char array representing a file: URI
    +% qosProfile: a char array containing the name of a profile defined in the QoS File
    +sub = Vortex.Subscriber(qosFileURI, qosProfile);
    +
    +
    +

    Create a subscriber with participant and QoS profile:

    +
    % dp: a Vortex.DomainParticipant instance
    +% qosFileURI: a char array representing a file: URI
    +% qosProfile: a char array containing the name of a profile defined in the QoS File
    +sub = Vortex.Subscriber(dp, qosFileURI, qosProfile);
    +
    +
    +
    +
    +

    3.7. Vortex.Reader¶

    +

    The MATLAB Vortex.Reader class represents a DDS data reader entity.

    +

    In DDS - “To access the received data, the application must use a typed DataReader attached to the subscriber.â€

    +

    A Vortex.Reader class is required in order to write data to a DDS domain. +It may be explicitly attached to a DDS subscriber or a DDS domain participant; or, it is implicitly attached to the default domain participant.

    +

    A Vortex.Reader class instance references an existing Vortex.Topic instance.

    +

    API Examples

    +

    Create a Vortex DDS domain reader. Returns reader or throw a Vortex.DDSException instance if the reader cannot be created.

    +

    Create a reader for a topic within the default domain participant, and with default QoS:

    +
    % topic: a Vortex.Topic instance
    +reader = Vortex.Reader(topic);
    +
    +
    +

    Create a reader for a topic within a subscriber or participant, and with default QoS:

    +
    % subOrDp: a Vortex.Subscriber or Vortex.DomainParticipant instance
    +% topic: a Vortex.Topic instance
    +reader = Vortex.Reader(subOrDp, topic);
    +
    +
    +

    Create reader for a topic within the default domain participant and with a QoS profile:

    +
    % topic: a Vortex.Topic instance
    +% qosFileURI: a char array representing a file: URI
    +% qosProfile: a char array containing the name of a profile defined in the QoS File
    +reader = Vortex.Reader(topic, qosFileURI, qosProfile);
    +
    +
    +

    Create a reader for a topic within a subscriber or participant, with with a QoS profile:

    +
    % subOrDp: a Vortex.Subscriber or Vortex.DomainParticipant instance
    +% topic: a Vortex.Topic instance
    +% qosFileURI: a char array representing a file: URI
    +% qosProfile: a char array containing the name of a profile defined in the QoS File
    +reader = Vortex.Reader(subOrDp, topic, qosFileURI, qosProfile);
    +
    +
    +

    Take data from a data reader:

    +
    % reader: a Vortex.Reader
    +[data, dataState] = reader.take;
    +% data: an array of topic class instances (e.g. ShapeType); possibly empty
    +% dataState: an struct array; each entry describes the
    +%    state of the corresponding data entry
    +
    +
    +

    Read data from a data reader:

    +
    % reader: a Vortex.Reader
    +[data, dataState] = reader.read;
    +% data: an array of topic class instances (e.g. ShapeType); possibly empty
    +% dataState: an struct array; each entry describes the
    +%    state of the corresponding data entry
    +
    +
    +

    Specify a wait timeout, in seconds, before read or take will return without receiving data:

    +
    % reader: a Vortex.Reader
    +reader.waitsetTimeout(2.0);
    +
    +
    +
    +
    +

    3.8. Vortex.Query¶

    +

    The MATLAB Vortex.Query class represents a DDS query entity.

    +

    A query is a data reader, restricted to accessing data that matches specific status conditions and/or a filter expression.

    +

    A Vortex.Query class instance references an existing Vortex.Reader instance.

    +

    API Examples

    +

    Create a Vortex.Query instance or throw a Vortex.DDSException if an error occurs.

    +

    Create a query based on a state mask only:

    +
    % reader: a Vortex.Reader
    +% only receive samples that:
    +%   * have not been read by this application
    +%   * AND for instances that previously seen by this application
    +%   * AND for which there is a live writer
    +mask = Vortex.DataState.withNew().withNotRead().withAlive();
    +query = Vortex.Query(reader, mask);
    +
    +
    +

    Create a query based on a state mask and a filter expression:

    +
    % reader: a Vortex.Reader
    +mask = Vortex.DataState.withAnyState();
    +filter = 'color = %0 and x > %1';
    +% filter for 'RED' shapes with x > 10...
    +query = Vortex.Query(reader, mask, filter, {'RED', 10'});
    +
    +
    +

    Take data from a query:

    +
    % query: a Vortex.Query
    +[data, dataState] = query.take;
    +% data: an array of topic class instances (e.g. ShapeType); possibly empty
    +% dataState: an struct array; each entry describes the
    +%    state of the corresponding data entry
    +
    +
    +

    Read data from a query:

    +
    % query: a Vortex.Query
    +[data, dataState] = query.read;
    +% data: an array of topic class instances (e.g. ShapeType); possibly empty
    +% dataState: an struct array; each entry describes the
    +%    state of the corresponding data entry
    +
    +
    +

    Specify a wait timeout, in seconds, before read or take will return without receiving data:

    +
    % query: a Vortex.Query
    +
    +% specify the waitset timeout on the reader
    +query.waitsetTimeout(2.0);
    +
    +% now, read or take 'query'
    +
    +
    +
    +
    +

    3.9. Vortex.DDSException¶

    +

    The Vortex.DDSException class is thrown in the case of a DDS error arising. +The class can also be used to decode an error status code returned by methods such as Vortex.Writer.write.

    +

    API Examples

    +

    Catch a DDS error while creating a DDS entity:

    +
    % dp: a Vortex.DomainParticipant
    +try
    +  topic = Vortex.topic('Circle', ?SomeAlternateDef.ShapeType);
    +catch ex
    +  switch ex.identifier
    +    case 'Vortex:DDSError'
    +      % it's a Vortex Error
    +      fprintf(['DDS reports error:\n' ...
    +         '  %s\n' ...
    +         '    DDS ret code: %s (%d)\n'], ...
    +         ex.message, char(ex.dds_ret_code), ex.dds_ret_code);
    +    otherwise
    +      rethrow ex;
    +  end
    +end
    +
    +
    +

    Decode a dds status code returned by Vortex.Writer.write:

    +
    % ddsstatus: a Vortex.Writer.write return value
    +ex = Vortex.DDSException('', ddsstatus);
    +switch ex.dds_ret_code
    +  case Vortex.DDSReturnCode.DDS_RETCODE_OK
    +    % ...
    +  case Vortex.DDSReturnCode.DDS_BAD_PARAMETER
    +    % ...
    +  case Vortex.DDSReturnCode.DDS_RETCODE_INCONSISTENT_POLICY
    +    % ...
    +end
    +
    +
    +
    +
    + + +
    +
    +
    +
    +
    + +

    Table Of Contents

    + + +

    Previous topic

    +

    2. Installation

    +

    Next topic

    +

    4. MATLAB Generation from IDL

    +

    This Page

    + + + +
    +
    +
    +
    + + + + \ No newline at end of file diff --git a/docs/html/DDSMATLABGuide/IDL-MATLAB.html b/docs/html/DDSMATLABGuide/IDL-MATLAB.html new file mode 100644 index 000000000..5d596e566 --- /dev/null +++ b/docs/html/DDSMATLABGuide/IDL-MATLAB.html @@ -0,0 +1,291 @@ + + + + + + + + 4. MATLAB Generation from IDL — The Vortex OpenSplice MATLAB Guide + + + + + + + + + + + + + + + +
    +
    +
    +
    + +
    +

    4. MATLAB Generation from IDL¶

    +

    The DDS MATLAB Integration supports generation of MATLAB classes from IDL. This chapter describes the details of the IDL-MATLAB binding.

    +
    +

    4.1. Running IDLPP¶

    +

    Compiling IDL into MATLAB code is done using the -l matlab switch on idlpp:

    +
    idlpp -l matlab idl-file-to-compile.idl
    +
    +
    +

    Generated Artifacts

    +

    The following table defines the MATLAB artifacts generated from IDL concepts:

    + +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    IDL ConceptMATLAB ConceptComment
    modulepackagea MATLAB package is a folder starting with ‘+’.
    enumclassa MATLAB .m file.
    enum valueenum value 
    structclassa MATLAB .m file.
    fieldclass property 
    typedef IDL typedef’s are inlined.
    unionUnsupported 
    inheritanceUnsupported 
    +

    Datatype mappings

    +

    The following table shows the MATLAB equivalents to IDL primitive types:

    + ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    IDL TypeMATLAB Type
    booleanlogical
    charint8
    octetuint8
    shortint16
    ushortuint16
    longint32
    ulonguint32
    long longint64
    ulong longuint64
    floatsingle
    doubledouble
    stringchar
    wcharUnsupported
    wstringUnsupported
    anyUnsupported
    long doubleUnsupported
    +

    Implementing Arrays and Sequences in MATLAB

    +

    Both IDL arrays and IDL sequences are mapped to MATLAB arrays. +MATLAB supports both native array types, which must have homogenenous contents and cell arrays, which may have heterogenous content. +In general, IDLPP prefers native arrays, as they support more straight forward type checking. +However, some situations require cell arrays. +The following table summarizes the cases where IDLPP will generate cell arrays:

    + +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    DatatypeSample SyntaxReason for using cell array
    sequence of sequencesequence<sequence<T>> f;Nested sequences need not have a homogeneous length
    array of sequencesequence<T> f[N];Sequences lengths need not be homogeneous
    sequence of arraysequence<A> f;A multi-dim array makes adding elements too difficult
    sequence of stringsequence<string> f;Nested strings need not have a homogeneous length
    string arraystring f[N];Nested strings need not have a homogeneous length
    +
    +
    +

    4.2. Limitations of MATLAB Support¶

    +

    The IDL-to-MATLAB binding has the following limitations:

    +
      +
    • IDL unions are not supported
    • +
    • the following IDL data types are not supported: wchar, wstring, any and long double
    • +
    • arrays of sequences of structures are not supported
    • +
    +
    +
    + + +
    +
    +
    +
    +
    + +

    Table Of Contents

    + + +

    Previous topic

    +

    3. MATLAB API for Vortex DDS Classes

    +

    Next topic

    +

    5. MATLAB without IDL

    +

    This Page

    + + + +
    +
    +
    +
    + + + + \ No newline at end of file diff --git a/docs/html/DDSMATLABGuide/IDLless-MATLAB.html b/docs/html/DDSMATLABGuide/IDLless-MATLAB.html new file mode 100644 index 000000000..10e86163b --- /dev/null +++ b/docs/html/DDSMATLABGuide/IDLless-MATLAB.html @@ -0,0 +1,254 @@ + + + + + + + + 5. MATLAB without IDL — The Vortex OpenSplice MATLAB Guide + + + + + + + + + + + + + + + +
    +
    +
    +
    + +
    +

    5. MATLAB without IDL¶

    +

    It is possible, but not recommended, to directly create MATLAB classes that represent DDS topics. +This approach allows you to quickly start using Vortex DDS, but it has a number of disadvantages:

    +
      +
    • without IDL, you cannot reliably define the topic in other language bindings.
    • +
    • not all IDL types are available.
    • +
    +
    +

    5.1. Creating a MATLAB Topic class¶

    +

    To create a Topic Class without IDL, create a MATLAB class that inherits from Vortex.AbstractType. +The class will be interpreted as an IDL struct. +Class properties will be interpreted as IDL struct fields. +Finally, the class must define a static method getKey which returns a comma separated list of key +fields for the topic.

    +

    The following shows a simple MATLAB class, ShapeType:

    +
    classdef ShapeType < Vortex.AbstractType
    +    properties
    +        color     char  % IDL: string color;
    +        x         int32 % IDL: long x;
    +        y         int32 % IDL: long y;
    +        shapesize int32 % IDL: long shapesize;
    +    end
    +
    +    methods (Static)
    +        function keys = getKey
    +            keys = 'color';
    +        end
    +    end
    +end
    +
    +
    +

    The topic class defines four fields, and identifies the color field as the topic key.

    +

    You would use the topic class in the same way as one generated by IDLPP. The following example +shows the creation of a DDS topic object from a topic class:

    +
    % define a Vortex DDS topic called 'Circle'
    +circleTopic = Vortex.Topic('Circle', ?ShapeType);
    +
    +
    +

    With the circleTopic variable, you can then create appropriate Vortex DDS readers and writers.

    +
    +
    +

    5.2. Mapping of MATLAB types to IDL types¶

    +

    When using an IDL-less Topic class, the Vortex DDS API for MATLAB makes maps property types +to IDL types as follows:

    + ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    MATLAB TypeIDL Type
    logicalboolean
    int8char
    uint8octet
    int16short
    uint16unsigned short
    int32long
    uint32unsigned long
    int64long long
    uint64unsigned long long
    singlefloat
    doubledouble
    charstring
    classequivalent IDL struct
    enum classequivalent IDL enum
    not typedouble
    +
    +
    +

    5.3. Creating arrays¶

    +

    When defining a topic class, you can make a field map to an IDL array by initializing it to an array of the appropriate dimensions. +The MATLAB API for Vortex DDS recognizes arrays of most types as identifying IDL arrays. +The one exception is that arrays of MATLAB char are still interpreted as an IDL string.

    +

    The following example shows an topic class that defines arrays:

    +
    classdef ArrayTopic < Vortex.AbstractType
    +    properties
    +        x = zeros([1 4])        %IDL: double x[4];
    +        y int32 = zeros([3 4])  %IDL: long y[3][4];
    +    end
    +    methods (Static)
    +        function keys = getKey
    +            keys = ''; %No Key
    +        end
    +    end
    +end
    +
    +
    +
    +
    +

    5.4. Unsupported Types¶

    +

    When creating topics with out IDL, you must accept the following restrictions:

    +
      +
    • IDL sequences cannot be defined.
    • +
    • arrays of IDL strings cannot be defined.
    • +
    • bounded IDL strings cannot be defined.
    • +
    +
    +
    + + +
    +
    +
    +
    +
    + +

    Table Of Contents

    + + +

    Previous topic

    +

    4. MATLAB Generation from IDL

    +

    Next topic

    +

    6. QoS Provider

    +

    This Page

    + + + +
    +
    +
    +
    + + + + \ No newline at end of file diff --git a/docs/html/DDSMATLABGuide/_images/dds_overview.png b/docs/html/DDSMATLABGuide/_images/dds_overview.png new file mode 100644 index 000000000..c7490ddb4 Binary files /dev/null and b/docs/html/DDSMATLABGuide/_images/dds_overview.png differ diff --git a/docs/html/DDSMATLABGuide/_images/linuxInstall1.png b/docs/html/DDSMATLABGuide/_images/linuxInstall1.png new file mode 100644 index 000000000..11a145754 Binary files /dev/null and b/docs/html/DDSMATLABGuide/_images/linuxInstall1.png differ diff --git a/docs/html/DDSMATLABGuide/_sources/DDS-Classes.txt b/docs/html/DDSMATLABGuide/_sources/DDS-Classes.txt new file mode 100644 index 000000000..27a96be6b --- /dev/null +++ b/docs/html/DDSMATLABGuide/_sources/DDS-Classes.txt @@ -0,0 +1,433 @@ +.. _`MATLAB DDS Classes`: + +################################# +MATLAB API for Vortex DDS Classes +################################# + +The DDS MATLAB Integration provides a class library with custom classes to read and write data with DDS. + +The MATLAB DDS Classes are included in a **Vortex** package. + +API Usage patterns +****************** + +The typical usage pattern for the MATLAB API for Vortex DDS is the following: + +* model your DDS topics using IDL +* using ``idlpp -l matlab`` to compile your IDL into MATLAB topic classes. See :ref:`MATLAB Generation from IDL`. +* start writting your MATLAB program using the MATLAB API for Vortex DDS. + +The core classes you must use are ``Vortex.Topic`` and either ``Vortex.Reader`` or ``Vortex.Writer``. +Other classes may be required, especially if you need to adjust the Quality of Service (QoS) defaults. +For details on setting QoS values with the API, see :ref:`QoS Provider`. +The following list shows the sequence in which you would use the Vortex classes: + +* If you require participant-level non-default QoS settings, create a ``Vortex.Participant`` instance. Pass the participant to subsequently created Vortex entities. +* Create one or more ``Vortex.Topic`` instances for the IDL topics your program will read or write. +* If you require publisher or subscriber level non-default QoS settings, create ``Vortex.Publisher`` and/or ``Vortex.Subscriber`` instances. Pass these to any created reader or writers. (The most common reason for changing publisher/subscriber QoS is to define non-default partitions.) +* Create ``Vortex.Reader`` and/or ``Vortex.Writer`` classes from the ``Vortex.Topic`` instances that you created. +* If you required data filtering, create ``Vortex.Query`` objects. +* Create the core of program, creating instances of your topic classes and writing them; or, reading data and processing it. + +Vortex.Topic +************ + +The MATLAB Topic class represents a DDS topic type. The DDS topic corresponds to a single data type. In DDS, data is distributed by publishing and subscribing topic data samples. + +For a DDS Topic type definition, a corresponding MATLAB class must be defined in the MATLAB workspace. +This is either a class created by ``idlpp`` (see :ref:`MATLAB Generation from IDL`) or a manually +created MATLAB class (see :ref:`MATLAB without IDL`). +It is recommend that you create DDS Topic type definitions via IDL and `idlpp`. + +**API Examples** + +Create a Vortex DDS domain topic. Returns a topic instance, or throws a ``Vortex.DDSException`` if the topic cannot be created. + +Create a topic named 'Circle' based on the DDS Topic type ``ShapeType`` with default participant and QoS:: + + topic = Vortex.Topic('Circle', ?ShapeType); + +**Note**: In MATLAB, references to classes such as ShapeType are created by prefixing them with a +question mark (?). If the class is in a MATLAB package, then the fully qualified name must be used. +For example: ``?ShapesDemo.Topics.ShapeType``. + +Create the 'Circle' topic with an explicitly created participant:: + + % dp: a Vortex.DomainParticipant instance + topic = Vortex.Topic(dp, 'Circle', ?ShapeType); + +Create the 'Circle' topic with default participant and QoS profile:: + + % qosFileURI: a char array representing a file: URI + % qosProfile: a char array containing the name of a profile defined in the QoS File + topic = Vortex.Topic('Circle', ?ShapeType, qosFileURI, qosProfile); + +Create the 'Circle' topic with explicit participant and QoS profile:: + + % dp: a Vortex.DomainParticipant instance + % qosFileURI: a char array representing a file: URI + % qosProfile: a char array containing the name of a profile defined in the QoS File + topic = Vortex.Topic(dp, 'Circle', ?ShapeType, qosFileURI, qosProfile); + +Vortex.DomainParticipant +************************ + +The ``Vortex.DomainParticipant`` class represents a DDS domain participant entity. + +In DDS - “A domain participant represents the local membership of the application in a domain. A domain is a distributed concept that links all the applications able to communicate with each other. It represents a communication plane: only the publishers and subscribers attached to the same domain may interact.†+ +Use of the ``Vortex.DomainParticipant`` class is optional. +The API provides a 'default participant', which is used if no explicit domain participant is provided. +The default participant is created on first usage, and is disposed when MATLAB exits. +Reasons for using an explicitly created domain participant are: + +* to provide non-default QoS settings. +* to control the timing of participant creation and destruction. + +**API Examples** + +Create a Vortex DDS domain participant. Returns participant or throws a ``Vortex.DDSException`` if the participant cannot be created. + +Create a domain participant in the default DDS domain (the one specified by the OSLP_URI environment variable):: + + dp = Vortex.DomainParticipant(); + +Create a domain participant on domain, specifying a domain id:: + + % domainId: an integer value + dp = Vortex.DomainParticipant(domainId); + +**Note**: The underlying DCPS C99 API used by `Vortex.DomainParticipant` does not currently support this operation, and will result in a ``Vortex.DDSException`` being raised. + +Create a participant on default domain with QoS profile:: + + % qosFileURI: a char array representing a file: URI + % qosProfile: a char array containing the name of a profile defined in the QoS File + dp = Vortex.DomainParticipant(qosFileURI, qosProfile); + +Create a participant on domain with QoS profile:: + + % domainId: an integer value + % qosFileURI: a char array representing a file: URI + % qosProfile: a char array containing the name of a profile defined in the QoS File + dp = Vortex.DomainParticipant(domainId, qosFileURI, qosProfile); + +Vortex.Publisher +**************** + +The MATLAB ``Vortex.Publisher`` class represents a DDS publisher entity. + +In DDS, a publisher is “an object responsible for data distribution. It may publish data of different data types.†+ +Use of the ``Vortex.Publisher`` class is optional. +In it's place, you can use a ``Vortex.DomainParticipant`` instance, or default to the *default domain participant*. +Reasons for explicitly creating a ``Vortex.Publisher`` instance are: + +* to specify non-default QoS settings, including specifying the DDS *partition* upon which samples are written. +* to control the timing of publisher creation and deletion. + +**API Examples** + +Create a DDS Publisher entity. Returns publisher or throws a ``Vortex.DDSException`` if the publisher cannot be created. + +Create a default publisher with default participant:: + + pub = Vortex.Publisher(); + +Create a publisher with an explicit participant:: + + % dp: a Vortex.DomainParticipant instance + pub = Vortex.Publisher(dp); + +Create default publisher with default participant and QoS profile:: + + % qosFileURI: a char array representing a file: URI + % qosProfile: a char array containing the name of a profile defined in the QoS File + pub = Vortex.Publisher(qosFileURI, qosProfile); + +Create a publisher with participant and QoS profile:: + + % dp: a Vortex.DomainParticipant instance + % qosFileURI: a char array representing a file: URI + % qosProfile: a char array containing the name of a profile defined in the QoS File + pub = Vortex.Publisher(dp, qosFileURI, qosProfile); + +Vortex.Writer +************* + +The MATLAB ``Vortex.Writer`` class represents a DDS data writer entity. + +In DDS - “The DataWriter is the object the application must use to communicate to a publisher the existence and value of data-objects of a given type.†+ +A ``Vortex.Writer`` class is required in order to write data to a DDS domain. +It may be explicitly attached to a DDS publisher or a DDS domain participant; or, it is implicitly attached to the *default domain participant*. + +A ``Vortex.Writer`` class instance references an existing ``Vortex.Topic`` instance. + +**API Examples** + +Create a Vortex DDS domain writer. Returns writer or throws a ``Vortex.DDSException`` if the writer cannot be created. + +Create a writer for a topic, in the default domain participant and default QoS settings:: + + % topic: a Vortex.Topic instance + writer = Vortex.Writer(topic); + +Create a writer within an explicitly specified publisher or domain participant:: + + % pubOrDp: a Vortex.Publisher or Vortex.DomainParticipant instance + % topic: a Vortex.Topic instance + writer = Vortex.Writer(pubOrDp, topic); + +Create writer for a topic with explicit QoS profile:: + + % topic: a Vortex.Topic instance + % qosFileURI: a char array representing a file: URI + % qosProfile: a char array containing the name of a profile defined in the QoS File + writer = Vortex.Writer(topic, qosFileURI, qosProfile); + +Create a writer with publisher or participant, topic and QoS profile:: + + % pubOrDp: a Vortex.Publisher or Vortex.DomainParticipant instance + % topic: a Vortex.Topic instance + % qosFileURI: a char array representing a file: URI + % qosProfile: a char array containing the name of a profile defined in the QoS File + writer = Vortex.Writer(pubOrDp, topic, qosFileURI, qosProfile); + +Write a ShapeType topic class instance to a writer:: + + % writer: a Vortex.Writer instance + % ShapeType: a 'topic class' created manually or via IDLPP + data = ShapeType(); % create an object instance + % set data values... + data.color = 'RED'; + % ... set other values ... + + ddsStatus = writer.write(data); + +**Note**: the returned status value is 0 for success, and negative for failure. Use the ``Vortex.DDSException`` class to decode an failure status. + +Dispose a DDS topic instance:: + + % writer: a Vortex.Writer instance + % ShapeType: a 'topic class' created manually or via IDLPP + data = ShapeType(); % create an object instance + % set data key values... + data.color = 'RED'; + + ddsStatus = writer.dispose(data); + +**Note**: the returned status value is 0 for success, and negative for failure. Use the ``Vortex.DDSException`` class to decode an failure status. + +Unregister a DDS topic instance:: + + % writer: a Vortex.Writer instance + % ShapeType: a 'topic class' created manually or via IDLPP + data = ShapeType(); % create an object instance + % set data key values... + data.color = 'RED'; + + ddsStatus = writer.unregister(data); + +**Note**: the returned status value is 0 for success, and negative for failure. Use the ``Vortex.DDSException`` class to decode an failure status. + +Vortex.Subscriber +***************** + +The MATLAB ``Vortex.Subscriber`` class represents a DDS subscriber entity. + +In DDS, a subscriber is “an object responsible for receiving published data and making it available to the receiving application. It may receive and dispatch data of different specified types.†+ +Use of the ``Vortex.Subscriber`` class is optional. +In it's place, you can use a ``Vortex.DomainParticipant`` instance, or default to the *default domain participant*. +Reasons for explicitly creating a ``Vortex.Subscriber`` instance are: + +* to specify non-default QoS settings, including specifying the DDS *partition* upon which samples are written. +* to control the timing of subscriber creation and deletion. + +**API Examples** + + +Create a Vortex DDS domain subscriber. Returns subscriber or throw a ``Vortex.DDSException`` if the subscriber cannot be created. + +Create a subscriber within the default domain participant:: + + sub = Vortex.Subscriber(); + +Create a subscriber within an explicit participant:: + + % dp: a Vortex.DomainParticipant instance + sub = Vortex.Subscriber(dp); + +Create subscriber within the default domain participant and with a QoS profile:: + + % qosFileURI: a char array representing a file: URI + % qosProfile: a char array containing the name of a profile defined in the QoS File + sub = Vortex.Subscriber(qosFileURI, qosProfile); + +Create a subscriber with participant and QoS profile:: + + % dp: a Vortex.DomainParticipant instance + % qosFileURI: a char array representing a file: URI + % qosProfile: a char array containing the name of a profile defined in the QoS File + sub = Vortex.Subscriber(dp, qosFileURI, qosProfile); + + +Vortex.Reader +************* + +The MATLAB ``Vortex.Reader`` class represents a DDS data reader entity. + +In DDS - “To access the received data, the application must use a typed DataReader attached to the subscriber.†+ +A ``Vortex.Reader`` class is required in order to write data to a DDS domain. +It may be explicitly attached to a DDS subscriber or a DDS domain participant; or, it is implicitly attached to the *default domain participant*. + +A ``Vortex.Reader`` class instance references an existing ``Vortex.Topic`` instance. + +**API Examples** + +Create a Vortex DDS domain reader. Returns reader or throw a ``Vortex.DDSException`` instance if the reader cannot be created. + +Create a reader for a topic within the default domain participant, and with default QoS:: + + % topic: a Vortex.Topic instance + reader = Vortex.Reader(topic); + +Create a reader for a topic within a subscriber or participant, and with default QoS:: + + % subOrDp: a Vortex.Subscriber or Vortex.DomainParticipant instance + % topic: a Vortex.Topic instance + reader = Vortex.Reader(subOrDp, topic); + +Create reader for a topic within the default domain participant and with a QoS profile:: + + % topic: a Vortex.Topic instance + % qosFileURI: a char array representing a file: URI + % qosProfile: a char array containing the name of a profile defined in the QoS File + reader = Vortex.Reader(topic, qosFileURI, qosProfile); + +Create a reader for a topic within a subscriber or participant, with with a QoS profile:: + + % subOrDp: a Vortex.Subscriber or Vortex.DomainParticipant instance + % topic: a Vortex.Topic instance + % qosFileURI: a char array representing a file: URI + % qosProfile: a char array containing the name of a profile defined in the QoS File + reader = Vortex.Reader(subOrDp, topic, qosFileURI, qosProfile); + +Take data from a data reader:: + + % reader: a Vortex.Reader + [data, dataState] = reader.take; + % data: an array of topic class instances (e.g. ShapeType); possibly empty + % dataState: an struct array; each entry describes the + % state of the corresponding data entry + +Read data from a data reader:: + + % reader: a Vortex.Reader + [data, dataState] = reader.read; + % data: an array of topic class instances (e.g. ShapeType); possibly empty + % dataState: an struct array; each entry describes the + % state of the corresponding data entry + +Specify a wait timeout, in seconds, before read or take will return without receiving data:: + + % reader: a Vortex.Reader + reader.waitsetTimeout(2.0); + +Vortex.Query +************ + +The MATLAB ``Vortex.Query`` class represents a DDS query entity. + +A query is a data reader, restricted to accessing data that matches specific status conditions and/or a filter expression. + +A ``Vortex.Query`` class instance references an existing ``Vortex.Reader`` instance. + +**API Examples** + +Create a ``Vortex.Query`` instance or throw a ``Vortex.DDSException`` if an error occurs. + +Create a query based on a state mask only:: + + % reader: a Vortex.Reader + % only receive samples that: + % * have not been read by this application + % * AND for instances that previously seen by this application + % * AND for which there is a live writer + mask = Vortex.DataState.withNew().withNotRead().withAlive(); + query = Vortex.Query(reader, mask); + +Create a query based on a state mask and a filter expression:: + + % reader: a Vortex.Reader + mask = Vortex.DataState.withAnyState(); + filter = 'color = %0 and x > %1'; + % filter for 'RED' shapes with x > 10... + query = Vortex.Query(reader, mask, filter, {'RED', 10'}); + +Take data from a query:: + + % query: a Vortex.Query + [data, dataState] = query.take; + % data: an array of topic class instances (e.g. ShapeType); possibly empty + % dataState: an struct array; each entry describes the + % state of the corresponding data entry + +Read data from a query:: + + % query: a Vortex.Query + [data, dataState] = query.read; + % data: an array of topic class instances (e.g. ShapeType); possibly empty + % dataState: an struct array; each entry describes the + % state of the corresponding data entry + +Specify a wait timeout, in seconds, before read or take will return without receiving data:: + + % query: a Vortex.Query + + % specify the waitset timeout on the reader + query.waitsetTimeout(2.0); + + % now, read or take 'query' + +Vortex.DDSException +******************* + +The ``Vortex.DDSException`` class is thrown in the case of a DDS error arising. +The class can also be used to decode an error status code returned by methods such as ``Vortex.Writer.write``. + +**API Examples** + +Catch a DDS error while creating a DDS entity:: + + % dp: a Vortex.DomainParticipant + try + topic = Vortex.topic('Circle', ?SomeAlternateDef.ShapeType); + catch ex + switch ex.identifier + case 'Vortex:DDSError' + % it's a Vortex Error + fprintf(['DDS reports error:\n' ... + ' %s\n' ... + ' DDS ret code: %s (%d)\n'], ... + ex.message, char(ex.dds_ret_code), ex.dds_ret_code); + otherwise + rethrow ex; + end + end + +Decode a dds status code returned by ``Vortex.Writer.write``:: + + % ddsstatus: a Vortex.Writer.write return value + ex = Vortex.DDSException('', ddsstatus); + switch ex.dds_ret_code + case Vortex.DDSReturnCode.DDS_RETCODE_OK + % ... + case Vortex.DDSReturnCode.DDS_BAD_PARAMETER + % ... + case Vortex.DDSReturnCode.DDS_RETCODE_INCONSISTENT_POLICY + % ... + end + diff --git a/docs/html/DDSMATLABGuide/_sources/IDL-MATLAB.txt b/docs/html/DDSMATLABGuide/_sources/IDL-MATLAB.txt new file mode 100644 index 000000000..eba560168 --- /dev/null +++ b/docs/html/DDSMATLABGuide/_sources/IDL-MATLAB.txt @@ -0,0 +1,84 @@ +.. _`MATLAB Generation from IDL`: + +########################## +MATLAB Generation from IDL +########################## + +The DDS MATLAB Integration supports generation of MATLAB classes from IDL. This chapter describes the details of the IDL-MATLAB binding. + +Running IDLPP +************* + +Compiling IDL into MATLAB code is done using the ``-l matlab`` switch on idlpp:: + + idlpp -l matlab idl-file-to-compile.idl + +**Generated Artifacts** + +The following table defines the MATLAB artifacts generated from IDL concepts: + +=========== ============== =============================================== +IDL Concept MATLAB Concept Comment +=========== ============== =============================================== +module package a MATLAB package is a folder starting with '+'. +enum class a MATLAB .m file. +enum value enum value +struct class a MATLAB .m file. +field class property +typedef IDL typedef's are inlined. +union Unsupported +inheritance Unsupported +=========== ============== =============================================== + +**Datatype mappings** + +The following table shows the MATLAB equivalents to IDL primitive types: + +=========== =========== +IDL Type MATLAB Type +=========== =========== +boolean logical +char int8 +octet uint8 +short int16 +ushort uint16 +long int32 +ulong uint32 +long long int64 +ulong long uint64 +float single +double double +string char +wchar Unsupported +wstring Unsupported +any Unsupported +long double Unsupported +=========== =========== + +**Implementing Arrays and Sequences in MATLAB** + +Both IDL arrays and IDL sequences are mapped to MATLAB arrays. +MATLAB supports both native array types, which must have homogenenous contents and *cell arrays*, which may have heterogenous content. +In general, IDLPP prefers native arrays, as they support more straight forward type checking. +However, some situations require cell arrays. +The following table summarizes the cases where IDLPP will generate cell arrays: + +==================== ======================== ===================================================== +Datatype Sample Syntax Reason for using cell array +==================== ======================== ===================================================== +sequence of sequence sequence> f; Nested sequences need not have a homogeneous length +array of sequence sequence f[N]; Sequences lengths need not be homogeneous +sequence of array sequence f; A multi-dim array makes adding elements too difficult +sequence of string sequence f; Nested strings need not have a homogeneous length +string array string f[N]; Nested strings need not have a homogeneous length +==================== ======================== ===================================================== + +Limitations of MATLAB Support +***************************** + +The IDL-to-MATLAB binding has the following limitations: + +* IDL unions are not supported +* the following IDL data types are not supported: wchar, wstring, any and long double +* arrays of sequences of structures are not supported + diff --git a/docs/html/DDSMATLABGuide/_sources/IDLless-MATLAB.txt b/docs/html/DDSMATLABGuide/_sources/IDLless-MATLAB.txt new file mode 100644 index 000000000..84b810ad6 --- /dev/null +++ b/docs/html/DDSMATLABGuide/_sources/IDLless-MATLAB.txt @@ -0,0 +1,105 @@ +.. _`MATLAB without IDL`: + +################## +MATLAB without IDL +################## + +It is possible, but not recommended, to directly create MATLAB classes that represent DDS topics. +This approach allows you to quickly start using Vortex DDS, but it has a number of disadvantages: + +* without IDL, you cannot reliably define the topic in other language bindings. +* not all IDL types are available. + +Creating a MATLAB Topic class +***************************** + +To create a Topic Class without IDL, create a MATLAB class that inherits from Vortex.AbstractType. +The class will be interpreted as an IDL struct. +Class properties will be interpreted as IDL struct fields. +Finally, the class must define a static method `getKey` which returns a comma separated list of key +fields for the topic. + +The following shows a simple MATLAB class, ShapeType:: + + classdef ShapeType < Vortex.AbstractType + properties + color char % IDL: string color; + x int32 % IDL: long x; + y int32 % IDL: long y; + shapesize int32 % IDL: long shapesize; + end + + methods (Static) + function keys = getKey + keys = 'color'; + end + end + end + +The topic class defines four fields, and identifies the ``color`` field as the topic key. + +You would use the topic class in the same way as one generated by IDLPP. The following example +shows the creation of a DDS topic object from a topic class:: + + % define a Vortex DDS topic called 'Circle' + circleTopic = Vortex.Topic('Circle', ?ShapeType); + +With the `circleTopic` variable, you can then create appropriate Vortex DDS readers and writers. + +Mapping of MATLAB types to IDL types +************************************ + +When using an IDL-less Topic class, the Vortex DDS API for MATLAB makes maps property types +to IDL types as follows: + +=========== ===================== +MATLAB Type IDL Type +=========== ===================== +logical boolean +int8 char +uint8 octet +int16 short +uint16 unsigned short +int32 long +uint32 unsigned long +int64 long long +uint64 unsigned long long +single float +double double +char string +class equivalent IDL struct +enum class equivalent IDL enum +not type double +=========== ===================== + +Creating arrays +*************** + +When defining a topic class, you can make a field map to an IDL array by initializing it to an array of the appropriate dimensions. +The MATLAB API for Vortex DDS recognizes arrays of most types as identifying IDL arrays. +The one exception is that arrays of MATLAB ``char`` are still interpreted as an IDL string. + +The following example shows an topic class that defines arrays:: + + classdef ArrayTopic < Vortex.AbstractType + properties + x = zeros([1 4]) %IDL: double x[4]; + y int32 = zeros([3 4]) %IDL: long y[3][4]; + end + methods (Static) + function keys = getKey + keys = ''; %No Key + end + end + end + +Unsupported Types +***************** + +When creating topics with out IDL, you must accept the following restrictions: + +* IDL sequences cannot be defined. +* arrays of IDL strings cannot be defined. +* bounded IDL strings cannot be defined. + + diff --git a/docs/html/DDSMATLABGuide/_sources/contacts.txt b/docs/html/DDSMATLABGuide/_sources/contacts.txt new file mode 100644 index 000000000..d32f6016f --- /dev/null +++ b/docs/html/DDSMATLABGuide/_sources/contacts.txt @@ -0,0 +1 @@ +.. include:: ../../common/contacts.rst diff --git a/docs/html/DDSMATLABGuide/_sources/example-ping-pong.txt b/docs/html/DDSMATLABGuide/_sources/example-ping-pong.txt new file mode 100644 index 000000000..53dc1de79 --- /dev/null +++ b/docs/html/DDSMATLABGuide/_sources/example-ping-pong.txt @@ -0,0 +1,81 @@ +.. _`Ping Pong Example`: + +################# +Ping Pong Example +################# + +A simple ping pong example is provided to demonstrate the basic capabilities of the MATLAB DDS integration. + +The ping pong example can be found in the following directory: + + `OSPL_HOME`/tools/matlab/examples/matlab/pingpong + +The ping pong example creates two participants. + +1. A pinger that writes to the PING partition and reads from the PONG partition. +2. A ponger that writes to the PONG partition and reads from the PING partition. + +A matlab script is provided that writes and reads sample data in the pinger and ponger participants. + +Example Files +************* + +Files with the .m extension are MATLAB script files. + +An explanation of what each example file does is provided below. + +**pingpong.idl** + +- Defines the PingPongType in idl +- Used to generate the MATLAB file PingPongType.m via:: +idlpp -l matlab pingpong.idl + +**PingPongType.m** + +- Defines a PingPongType; generated from idlpp +- The PingPongType represents a DDS topic type. +- PingPongType specifies two properties: id, count. + +**DDS_PingerVolatileQoS.xml** + +- XML file that specifies the DDS QoS (quality of service) settings for pinger. + +**DDS_PongerVolatileQoS.xml** + +- XML file that specifies the DDS QoS (quality of service) settings for ponger. + +**setup_pinger.m** + +- Creates the pinger participant on the default DDS domain, with specified QoS profile. +- Creates the topic PingPongType. +- Creates the publisher using the domain participant on the PING partition specified in the specified QoS profile. +- Creates the writer using the publisher and the specified QoS profile. +- Creates the subscriber using the domain participant on the PONG partition specified in the QoS profile. +- Creates the reader using the subscriber and the specified QoS profile. + +**setup_ponger.m** + +- Creates the ponger participant on default domain with specified QoS profile. +- Creates the topic PingPongType. +- Creates the publisher using the domain participant on the PONG partition specified in the QoS profile. +- Creates the writer using the publisher and the specified QoS profile. +- Creates the subscriber using the domain participant on the PING partition specified in the QoS profile. +- Creates the reader using the subscriber and the specified QoS profile. + +**pinger_ponger.m** + +- MATLAB script that writes and reads sample data in the pinger and ponger participants. +- This script calls the setup_pinger.m and setup_ponger.m scripts. +- This is the main script to run the ping pong example. +- This script is run from the MATLAB Command Window. + + +Steps to run example +******************** + +1. In the MATLAB command window, run pinger_ponger.m. + - Type "pinger_ponger". + - Hit enter. + + + diff --git a/docs/html/DDSMATLABGuide/_sources/index.txt b/docs/html/DDSMATLABGuide/_sources/index.txt new file mode 100644 index 000000000..c0cdec51d --- /dev/null +++ b/docs/html/DDSMATLABGuide/_sources/index.txt @@ -0,0 +1,27 @@ +.. The Vortex OpenSplice MATLAB Guide + +.. Doc Issue 01, 28 February 2017 + +################ +DDS MATLAB Guide +################ + +.. toctree:: + :maxdepth: 6 + :numbered: + + introduction + installation + DDS-Classes + IDL-MATLAB + IDLless-MATLAB + qos_provider + example-ping-pong + + contacts + + +Indices and tables +================== + +* :ref:`search` diff --git a/docs/html/DDSMATLABGuide/_sources/installation.txt b/docs/html/DDSMATLABGuide/_sources/installation.txt new file mode 100644 index 000000000..35e39736e --- /dev/null +++ b/docs/html/DDSMATLABGuide/_sources/installation.txt @@ -0,0 +1,83 @@ +.. _`Installation`: + +############ +Installation +############ + +This section describes the procedure to install the Vortex DDS MATLAB Integration on a Linux or Windows platform. + +System Requirements +******************* + +- Operating System: Windows or Linux +- MATLAB installed +- Java 1.7 or greater + +OpenSplice (OSPL) and DDS MATLAB Installation +********************************************* + +Steps: + +1. Install OSPL. The DDS MATLAB Integration is included in this installer. + + +2. Setup OSPL license. Copy the license.lic file into the appropriate license directory. + + */INSTALLDIR/Vortex_v2/license* + +3. DDS MATLAB files are contained in a tools/matlab folder + + Example: + */INSTALLDIR/Vortex_v2/Device/VortexOpenSplice/6.8.1/HDE/x86_64.linux/tools/matlab* + +MATLAB and DDS Setup +******************** + +Steps: + +1. Open command shell and run script to setup environment variables. + + **Linux** + + - Open a Linux terminal. + + - Navigate to directory containing release.com file. + + */INSTALLDIR/Vortex_v2/Device/VortexOpenSplice/6.8.1/HDE/x86_64.linux* + + - Run release.com. (Type in “. release.com†at command line.) + + + **Windows** + + - Open a command prompt. + + - Navigate to directory containing release.bat file. + + *INSTALLDIR/Vortex_v2/Device/VortexOpenSplice/6.8.1/HDE/x86_64.win64* + + - Run release.bat. (Type in “release.bat†at command line.) + + +2. Start MATLAB using the **SAME** command shell used in Step 1. + + *NOTE: If MATLAB is NOT started from a command shell with the correct OSPL environment variables set, exceptions will occur when attempting to use DDS MATLAB classes.* + +3. In MATLAB, navigate to file “Vortex_DDS_MATLAB_API.mltbx†by typing:: + + cd(fullfile(getenv('OSPL_HOME'),'tools','matlab')) + +4. Double click on the file “Vortex_DDS_MATLAB_API.mltbxâ€. This will bring up a dialog entitled **Vortex_DDS_MATLAB_API**. + Select **Install**. + +.. figure:: images/linuxInstall1.png + :alt: DDS + +Examples +******** + +Example models have been provided in the examples folder. + +Example: +*/INSTALLDIR/Vortex_v2/Device/VortexOpenSplice/6.8.1/HDE/x86_64.linux/tools/matlab/examples/matlab* + diff --git a/docs/html/DDSMATLABGuide/_sources/introduction.txt b/docs/html/DDSMATLABGuide/_sources/introduction.txt new file mode 100644 index 000000000..984031ff1 --- /dev/null +++ b/docs/html/DDSMATLABGuide/_sources/introduction.txt @@ -0,0 +1,51 @@ +.. _`Introduction`: + + +############ +Introduction +############ + +The DDS MATLAB Integration provides users with DDS MATLAB classes to model DDS communication using MATLAB and pure DDS applications. + +Please refer to the DDS and MATLAB documentation for detailed information. + +DDS +*** + +**What is DDS?** + +“The Data Distribution Service (DDSâ„¢) is a middleware protocol and API standard for data-centric connectivity from the Object Management Group® (OMG®). It integrates the components of a system together, providing low-latency data connectivity, extreme reliability, and a scalable architecture that business and mission-critical Internet of Things (IoT) applications need.†+ +“The main goal of DDS is to share the right data at the right place at the right time, even between time-decoupled publishers and consumers. DDS implements global data space by carefully replicating relevant portions of the logically shared dataspace.†DDS specification + +.. figure:: images/dds_overview.png + :alt: DDS + +**Further Documentation** + +http://portals.omg.org/dds/ + +http://ist.adlinktech.com/ + +MATLAB +****** + +**What is MATLAB?** + +"The Language of Technical Computing + +Millions of engineers and scientists worldwide use MATLAB® to analyze and design the systems and products transforming our world. MATLAB is in automobile active safety systems, interplanetary spacecraft, health monitoring devices, smart power grids, and LTE cellular networks. It is used for machine learning, signal processing, image processing, computer vision, communications, computational finance, control design, robotics, and much more. + +Math. Graphics. Programming. + +The MATLAB platform is optimized for solving engineering and scientific problems. The matrix-based MATLAB language is the world’s most natural way to express computational mathematics. Built-in graphics make it easy to visualize and gain insights from data. A vast library of prebuilt toolboxes lets you get started right away with algorithms essential to your domain. The desktop environment invites experimentation, exploration, and discovery. These MATLAB tools and capabilities are all rigorously tested and designed to work together. + +Scale. Integrate. Deploy. + +MATLAB helps you take your ideas beyond the desktop. You can run your analyses on larger data sets and scale up to clusters and clouds. MATLAB code can be integrated with other languages, enabling you to deploy algorithms and applications within web, enterprise, and production systems." + +https://www.mathworks.com/products/matlab.html + + + + diff --git a/docs/html/DDSMATLABGuide/_sources/qos_provider.txt b/docs/html/DDSMATLABGuide/_sources/qos_provider.txt new file mode 100644 index 000000000..2f0985e20 --- /dev/null +++ b/docs/html/DDSMATLABGuide/_sources/qos_provider.txt @@ -0,0 +1,92 @@ +.. _`QoS Provider`: + + +############ +QoS Provider +############ + +The following section explains how the QoS is set for a DDS entity using the QoS Provider. + + +QoS Provider File +***************** + +Quality of Service for DDS entities is set using XML files based on the XML schema file QoSProfile.xsd_. +These XML files contain one or more QoS profiles for DDS entities. An example with a default QoS profile +for all entity types can be found at DDS_DefaultQoS.xml_. + +**Note:** Sample QoS Profile XML files can be found in the examples directories. + +QoS Profile +*********** + +A QoS profile consists of a name and optionally a base_name attribute. The base_name attribute allows a +QoS or a profile to inherit values from another QoS or profile in the same file. The file contains QoS +elements for one or more DDS entities. A skeleton file without any QoS values is displayed below to show +the structure of the file. + +.. code-block:: xml + + + + + + + + + + + + +**Example: Specify Publisher Partition** + +The example below specifies the publisher's partitions as A and B. + +.. code-block:: xml + + + + + A + B + + + + + +Setting QoS Profile in MATLAB +***************************** +To set the QoS profile for a DDS entity in MATLAB the user must specify the File URI and the QoS profile name. +If the file is not specified, the DDS entity will be created with the default QoS values. + +.. code-block:: matlab + + % QOS File + PINGER_QOS_FILE = '/home/dds/matlab_examples/pingpong/DDS_PingerVolatileQoS.xml'; + PINGER_QOS_PROFILE = 'DDS VolatileQosProfile'; + + % create the pinger participant on default domain with specified qos profile + dp = Vortex.DomainParticipant(['file://', PINGER_QOS_FILE], PINGER_QOS_PROFILE); + +The file for the above would minimally contain the following tag. + +.. code-block:: xml + + + + + + + + + + true + + + + + + +.. external links +.. _QoSProfile.xsd: http://www.omg.org/spec/dds4ccm/20110201/DDS_QoSProfile.xsd +.. _DDS_DefaultQoS.xml: http://www.omg.org/spec/dds4ccm/20110201/DDS_DefaultQoS.xml diff --git a/docs/html/DDSMATLABGuide/_static/Vortex_logo_2014.png b/docs/html/DDSMATLABGuide/_static/Vortex_logo_2014.png new file mode 100644 index 000000000..e7de4f525 Binary files /dev/null and b/docs/html/DDSMATLABGuide/_static/Vortex_logo_2014.png differ diff --git a/docs/html/DDSMATLABGuide/_static/ajax-loader.gif b/docs/html/DDSMATLABGuide/_static/ajax-loader.gif new file mode 100644 index 000000000..61faf8cab Binary files /dev/null and b/docs/html/DDSMATLABGuide/_static/ajax-loader.gif differ diff --git a/docs/html/DDSMATLABGuide/_static/basic.css b/docs/html/DDSMATLABGuide/_static/basic.css new file mode 100644 index 000000000..967e36ce0 --- /dev/null +++ b/docs/html/DDSMATLABGuide/_static/basic.css @@ -0,0 +1,537 @@ +/* + * basic.css + * ~~~~~~~~~ + * + * Sphinx stylesheet -- basic theme. + * + * :copyright: Copyright 2007-2014 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +/* -- main layout ----------------------------------------------------------- */ + +div.clearer { + clear: both; +} + +/* -- relbar ---------------------------------------------------------------- */ + +div.related { + width: 100%; + font-size: 90%; +} + +div.related h3 { + display: none; +} + +div.related ul { + margin: 0; + padding: 0 0 0 10px; + list-style: none; +} + +div.related li { + display: inline; +} + +div.related li.right { + float: right; + margin-right: 5px; +} + +/* -- sidebar --------------------------------------------------------------- */ + +div.sphinxsidebarwrapper { + padding: 10px 5px 0 10px; +} + +div.sphinxsidebar { + float: left; + width: 230px; + margin-left: -100%; + font-size: 90%; +} + +div.sphinxsidebar ul { + list-style: none; +} + +div.sphinxsidebar ul ul, +div.sphinxsidebar ul.want-points { + margin-left: 20px; + list-style: square; +} + +div.sphinxsidebar ul ul { + margin-top: 0; + margin-bottom: 0; +} + +div.sphinxsidebar form { + margin-top: 10px; +} + +div.sphinxsidebar input { + border: 1px solid #98dbcc; + font-family: sans-serif; + font-size: 1em; +} + +div.sphinxsidebar #searchbox input[type="text"] { + width: 170px; +} + +div.sphinxsidebar #searchbox input[type="submit"] { + width: 30px; +} + +img { + border: 0; + max-width: 100%; +} + +/* -- search page ----------------------------------------------------------- */ + +ul.search { + margin: 10px 0 0 20px; + padding: 0; +} + +ul.search li { + padding: 5px 0 5px 20px; + background-image: url(file.png); + background-repeat: no-repeat; + background-position: 0 7px; +} + +ul.search li a { + font-weight: bold; +} + +ul.search li div.context { + color: #888; + margin: 2px 0 0 30px; + text-align: left; +} + +ul.keywordmatches li.goodmatch a { + font-weight: bold; +} + +/* -- index page ------------------------------------------------------------ */ + +table.contentstable { + width: 90%; +} + +table.contentstable p.biglink { + line-height: 150%; +} + +a.biglink { + font-size: 1.3em; +} + +span.linkdescr { + font-style: italic; + padding-top: 5px; + font-size: 90%; +} + +/* -- general index --------------------------------------------------------- */ + +table.indextable { + width: 100%; +} + +table.indextable td { + text-align: left; + vertical-align: top; +} + +table.indextable dl, table.indextable dd { + margin-top: 0; + margin-bottom: 0; +} + +table.indextable tr.pcap { + height: 10px; +} + +table.indextable tr.cap { + margin-top: 10px; + background-color: #f2f2f2; +} + +img.toggler { + margin-right: 3px; + margin-top: 3px; + cursor: pointer; +} + +div.modindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +div.genindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +/* -- general body styles --------------------------------------------------- */ + +a.headerlink { + visibility: hidden; +} + +h1:hover > a.headerlink, +h2:hover > a.headerlink, +h3:hover > a.headerlink, +h4:hover > a.headerlink, +h5:hover > a.headerlink, +h6:hover > a.headerlink, +dt:hover > a.headerlink { + visibility: visible; +} + +div.body p.caption { + text-align: inherit; +} + +div.body td { + text-align: left; +} + +.field-list ul { + padding-left: 1em; +} + +.first { + margin-top: 0 !important; +} + +p.rubric { + margin-top: 30px; + font-weight: bold; +} + +img.align-left, .figure.align-left, object.align-left { + clear: left; + float: left; + margin-right: 1em; +} + +img.align-right, .figure.align-right, object.align-right { + clear: right; + float: right; + margin-left: 1em; +} + +img.align-center, .figure.align-center, object.align-center { + display: block; + margin-left: auto; + margin-right: auto; +} + +.align-left { + text-align: left; +} + +.align-center { + text-align: center; +} + +.align-right { + text-align: right; +} + +/* -- sidebars -------------------------------------------------------------- */ + +div.sidebar { + margin: 0 0 0.5em 1em; + border: 1px solid #ddb; + padding: 7px 7px 0 7px; + background-color: #ffe; + width: 40%; + float: right; +} + +p.sidebar-title { + font-weight: bold; +} + +/* -- topics ---------------------------------------------------------------- */ + +div.topic { + border: 1px solid #ccc; + padding: 7px 7px 0 7px; + margin: 10px 0 10px 0; +} + +p.topic-title { + font-size: 1.1em; + font-weight: bold; + margin-top: 10px; +} + +/* -- admonitions ----------------------------------------------------------- */ + +div.admonition { + margin-top: 10px; + margin-bottom: 10px; + padding: 7px; +} + +div.admonition dt { + font-weight: bold; +} + +div.admonition dl { + margin-bottom: 0; +} + +p.admonition-title { + margin: 0px 10px 5px 0px; + font-weight: bold; +} + +div.body p.centered { + text-align: center; + margin-top: 25px; +} + +/* -- tables ---------------------------------------------------------------- */ + +table.docutils { + border: 0; + border-collapse: collapse; +} + +table.docutils td, table.docutils th { + padding: 1px 8px 1px 5px; + border-top: 0; + border-left: 0; + border-right: 0; + border-bottom: 1px solid #aaa; +} + +table.field-list td, table.field-list th { + border: 0 !important; +} + +table.footnote td, table.footnote th { + border: 0 !important; +} + +th { + text-align: left; + padding-right: 5px; +} + +table.citation { + border-left: solid 1px gray; + margin-left: 1px; +} + +table.citation td { + border-bottom: none; +} + +/* -- other body styles ----------------------------------------------------- */ + +ol.arabic { + list-style: decimal; +} + +ol.loweralpha { + list-style: lower-alpha; +} + +ol.upperalpha { + list-style: upper-alpha; +} + +ol.lowerroman { + list-style: lower-roman; +} + +ol.upperroman { + list-style: upper-roman; +} + +dl { + margin-bottom: 15px; +} + +dd p { + margin-top: 0px; +} + +dd ul, dd table { + margin-bottom: 10px; +} + +dd { + margin-top: 3px; + margin-bottom: 10px; + margin-left: 30px; +} + +dt:target, .highlighted { + background-color: #fbe54e; +} + +dl.glossary dt { + font-weight: bold; + font-size: 1.1em; +} + +.field-list ul { + margin: 0; + padding-left: 1em; +} + +.field-list p { + margin: 0; +} + +.optional { + font-size: 1.3em; +} + +.versionmodified { + font-style: italic; +} + +.system-message { + background-color: #fda; + padding: 5px; + border: 3px solid red; +} + +.footnote:target { + background-color: #ffa; +} + +.line-block { + display: block; + margin-top: 1em; + margin-bottom: 1em; +} + +.line-block .line-block { + margin-top: 0; + margin-bottom: 0; + margin-left: 1.5em; +} + +.guilabel, .menuselection { + font-family: sans-serif; +} + +.accelerator { + text-decoration: underline; +} + +.classifier { + font-style: oblique; +} + +abbr, acronym { + border-bottom: dotted 1px; + cursor: help; +} + +/* -- code displays --------------------------------------------------------- */ + +pre { + overflow: auto; + overflow-y: hidden; /* fixes display issues on Chrome browsers */ +} + +td.linenos pre { + padding: 5px 0px; + border: 0; + background-color: transparent; + color: #aaa; +} + +table.highlighttable { + margin-left: 0.5em; +} + +table.highlighttable td { + padding: 0 0.5em 0 0.5em; +} + +tt.descname { + background-color: transparent; + font-weight: bold; + font-size: 1.2em; +} + +tt.descclassname { + background-color: transparent; +} + +tt.xref, a tt { + background-color: transparent; + font-weight: bold; +} + +h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt { + background-color: transparent; +} + +.viewcode-link { + float: right; +} + +.viewcode-back { + float: right; + font-family: sans-serif; +} + +div.viewcode-block:target { + margin: -1px -10px; + padding: 0 10px; +} + +/* -- math display ---------------------------------------------------------- */ + +img.math { + vertical-align: middle; +} + +div.body div.math p { + text-align: center; +} + +span.eqno { + float: right; +} + +/* -- printout stylesheet --------------------------------------------------- */ + +@media print { + div.document, + div.documentwrapper, + div.bodywrapper { + margin: 0 !important; + width: 100%; + } + + div.sphinxsidebar, + div.related, + div.footer, + #top-link { + display: none; + } +} \ No newline at end of file diff --git a/docs/html/DDSMATLABGuide/_static/comment-bright.png b/docs/html/DDSMATLABGuide/_static/comment-bright.png new file mode 100644 index 000000000..551517b8c Binary files /dev/null and b/docs/html/DDSMATLABGuide/_static/comment-bright.png differ diff --git a/docs/html/DDSMATLABGuide/_static/comment-close.png b/docs/html/DDSMATLABGuide/_static/comment-close.png new file mode 100644 index 000000000..09b54be46 Binary files /dev/null and b/docs/html/DDSMATLABGuide/_static/comment-close.png differ diff --git a/docs/html/DDSMATLABGuide/_static/comment.png b/docs/html/DDSMATLABGuide/_static/comment.png new file mode 100644 index 000000000..92feb52b8 Binary files /dev/null and b/docs/html/DDSMATLABGuide/_static/comment.png differ diff --git a/docs/html/DDSMATLABGuide/_static/doctools.js b/docs/html/DDSMATLABGuide/_static/doctools.js new file mode 100644 index 000000000..c5455c905 --- /dev/null +++ b/docs/html/DDSMATLABGuide/_static/doctools.js @@ -0,0 +1,238 @@ +/* + * doctools.js + * ~~~~~~~~~~~ + * + * Sphinx JavaScript utilities for all documentation. + * + * :copyright: Copyright 2007-2014 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +/** + * select a different prefix for underscore + */ +$u = _.noConflict(); + +/** + * make the code below compatible with browsers without + * an installed firebug like debugger +if (!window.console || !console.firebug) { + var names = ["log", "debug", "info", "warn", "error", "assert", "dir", + "dirxml", "group", "groupEnd", "time", "timeEnd", "count", "trace", + "profile", "profileEnd"]; + window.console = {}; + for (var i = 0; i < names.length; ++i) + window.console[names[i]] = function() {}; +} + */ + +/** + * small helper function to urldecode strings + */ +jQuery.urldecode = function(x) { + return decodeURIComponent(x).replace(/\+/g, ' '); +}; + +/** + * small helper function to urlencode strings + */ +jQuery.urlencode = encodeURIComponent; + +/** + * This function returns the parsed url parameters of the + * current request. Multiple values per key are supported, + * it will always return arrays of strings for the value parts. + */ +jQuery.getQueryParameters = function(s) { + if (typeof s == 'undefined') + s = document.location.search; + var parts = s.substr(s.indexOf('?') + 1).split('&'); + var result = {}; + for (var i = 0; i < parts.length; i++) { + var tmp = parts[i].split('=', 2); + var key = jQuery.urldecode(tmp[0]); + var value = jQuery.urldecode(tmp[1]); + if (key in result) + result[key].push(value); + else + result[key] = [value]; + } + return result; +}; + +/** + * highlight a given string on a jquery object by wrapping it in + * span elements with the given class name. + */ +jQuery.fn.highlightText = function(text, className) { + function highlight(node) { + if (node.nodeType == 3) { + var val = node.nodeValue; + var pos = val.toLowerCase().indexOf(text); + if (pos >= 0 && !jQuery(node.parentNode).hasClass(className)) { + var span = document.createElement("span"); + span.className = className; + span.appendChild(document.createTextNode(val.substr(pos, text.length))); + node.parentNode.insertBefore(span, node.parentNode.insertBefore( + document.createTextNode(val.substr(pos + text.length)), + node.nextSibling)); + node.nodeValue = val.substr(0, pos); + } + } + else if (!jQuery(node).is("button, select, textarea")) { + jQuery.each(node.childNodes, function() { + highlight(this); + }); + } + } + return this.each(function() { + highlight(this); + }); +}; + +/** + * Small JavaScript module for the documentation. + */ +var Documentation = { + + init : function() { + this.fixFirefoxAnchorBug(); + this.highlightSearchWords(); + this.initIndexTable(); + }, + + /** + * i18n support + */ + TRANSLATIONS : {}, + PLURAL_EXPR : function(n) { return n == 1 ? 0 : 1; }, + LOCALE : 'unknown', + + // gettext and ngettext don't access this so that the functions + // can safely bound to a different name (_ = Documentation.gettext) + gettext : function(string) { + var translated = Documentation.TRANSLATIONS[string]; + if (typeof translated == 'undefined') + return string; + return (typeof translated == 'string') ? translated : translated[0]; + }, + + ngettext : function(singular, plural, n) { + var translated = Documentation.TRANSLATIONS[singular]; + if (typeof translated == 'undefined') + return (n == 1) ? singular : plural; + return translated[Documentation.PLURALEXPR(n)]; + }, + + addTranslations : function(catalog) { + for (var key in catalog.messages) + this.TRANSLATIONS[key] = catalog.messages[key]; + this.PLURAL_EXPR = new Function('n', 'return +(' + catalog.plural_expr + ')'); + this.LOCALE = catalog.locale; + }, + + /** + * add context elements like header anchor links + */ + addContextElements : function() { + $('div[id] > :header:first').each(function() { + $('\u00B6'). + attr('href', '#' + this.id). + attr('title', _('Permalink to this headline')). + appendTo(this); + }); + $('dt[id]').each(function() { + $('\u00B6'). + attr('href', '#' + this.id). + attr('title', _('Permalink to this definition')). + appendTo(this); + }); + }, + + /** + * workaround a firefox stupidity + */ + fixFirefoxAnchorBug : function() { + if (document.location.hash && $.browser.mozilla) + window.setTimeout(function() { + document.location.href += ''; + }, 10); + }, + + /** + * highlight the search words provided in the url in the text + */ + highlightSearchWords : function() { + var params = $.getQueryParameters(); + var terms = (params.highlight) ? params.highlight[0].split(/\s+/) : []; + if (terms.length) { + var body = $('div.body'); + if (!body.length) { + body = $('body'); + } + window.setTimeout(function() { + $.each(terms, function() { + body.highlightText(this.toLowerCase(), 'highlighted'); + }); + }, 10); + $('') + .appendTo($('#searchbox')); + } + }, + + /** + * init the domain index toggle buttons + */ + initIndexTable : function() { + var togglers = $('img.toggler').click(function() { + var src = $(this).attr('src'); + var idnum = $(this).attr('id').substr(7); + $('tr.cg-' + idnum).toggle(); + if (src.substr(-9) == 'minus.png') + $(this).attr('src', src.substr(0, src.length-9) + 'plus.png'); + else + $(this).attr('src', src.substr(0, src.length-8) + 'minus.png'); + }).css('display', ''); + if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) { + togglers.click(); + } + }, + + /** + * helper function to hide the search marks again + */ + hideSearchWords : function() { + $('#searchbox .highlight-link').fadeOut(300); + $('span.highlighted').removeClass('highlighted'); + }, + + /** + * make the url absolute + */ + makeURL : function(relativeURL) { + return DOCUMENTATION_OPTIONS.URL_ROOT + '/' + relativeURL; + }, + + /** + * get the current relative url + */ + getCurrentURL : function() { + var path = document.location.pathname; + var parts = path.split(/\//); + $.each(DOCUMENTATION_OPTIONS.URL_ROOT.split(/\//), function() { + if (this == '..') + parts.pop(); + }); + var url = parts.join('/'); + return path.substring(url.lastIndexOf('/') + 1, path.length - 1); + } +}; + +// quick alias for translations +_ = Documentation.gettext; + +$(document).ready(function() { + Documentation.init(); +}); diff --git a/docs/html/DDSMATLABGuide/_static/down-pressed.png b/docs/html/DDSMATLABGuide/_static/down-pressed.png new file mode 100644 index 000000000..6f7ad7827 Binary files /dev/null and b/docs/html/DDSMATLABGuide/_static/down-pressed.png differ diff --git a/docs/html/DDSMATLABGuide/_static/down.png b/docs/html/DDSMATLABGuide/_static/down.png new file mode 100644 index 000000000..3003a8877 Binary files /dev/null and b/docs/html/DDSMATLABGuide/_static/down.png differ diff --git a/docs/html/DDSMATLABGuide/_static/file.png b/docs/html/DDSMATLABGuide/_static/file.png new file mode 100644 index 000000000..d18082e39 Binary files /dev/null and b/docs/html/DDSMATLABGuide/_static/file.png differ diff --git a/docs/html/DDSMATLABGuide/_static/jquery.js b/docs/html/DDSMATLABGuide/_static/jquery.js new file mode 100644 index 000000000..e2efc335e --- /dev/null +++ b/docs/html/DDSMATLABGuide/_static/jquery.js @@ -0,0 +1,9404 @@ +/*! + * jQuery JavaScript Library v1.7.2 + * http://jquery.com/ + * + * Copyright 2011, John Resig + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * Includes Sizzle.js + * http://sizzlejs.com/ + * Copyright 2011, The Dojo Foundation + * Released under the MIT, BSD, and GPL Licenses. + * + * Date: Fri Jul 5 14:07:58 UTC 2013 + */ +(function( window, undefined ) { + +// Use the correct document accordingly with window argument (sandbox) +var document = window.document, + navigator = window.navigator, + location = window.location; +var jQuery = (function() { + +// Define a local copy of jQuery +var jQuery = function( selector, context ) { + // The jQuery object is actually just the init constructor 'enhanced' + return new jQuery.fn.init( selector, context, rootjQuery ); + }, + + // Map over jQuery in case of overwrite + _jQuery = window.jQuery, + + // Map over the $ in case of overwrite + _$ = window.$, + + // A central reference to the root jQuery(document) + rootjQuery, + + // A simple way to check for HTML strings or ID strings + // Prioritize #id over to avoid XSS via location.hash (#9521) + quickExpr = /^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/, + + // Check if a string has a non-whitespace character in it + rnotwhite = /\S/, + + // Used for trimming whitespace + trimLeft = /^\s+/, + trimRight = /\s+$/, + + // Match a standalone tag + rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>)?$/, + + // JSON RegExp + rvalidchars = /^[\],:{}\s]*$/, + rvalidescape = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, + rvalidtokens = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, + rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g, + + // Useragent RegExp + rwebkit = /(webkit)[ \/]([\w.]+)/, + ropera = /(opera)(?:.*version)?[ \/]([\w.]+)/, + rmsie = /(msie) ([\w.]+)/, + rmozilla = /(mozilla)(?:.*? rv:([\w.]+))?/, + + // Matches dashed string for camelizing + rdashAlpha = /-([a-z]|[0-9])/ig, + rmsPrefix = /^-ms-/, + + // Used by jQuery.camelCase as callback to replace() + fcamelCase = function( all, letter ) { + return ( letter + "" ).toUpperCase(); + }, + + // Keep a UserAgent string for use with jQuery.browser + userAgent = navigator.userAgent, + + // For matching the engine and version of the browser + browserMatch, + + // The deferred used on DOM ready + readyList, + + // The ready event handler + DOMContentLoaded, + + // Save a reference to some core methods + toString = Object.prototype.toString, + hasOwn = Object.prototype.hasOwnProperty, + push = Array.prototype.push, + slice = Array.prototype.slice, + trim = String.prototype.trim, + indexOf = Array.prototype.indexOf, + + // [[Class]] -> type pairs + class2type = {}; + +jQuery.fn = jQuery.prototype = { + constructor: jQuery, + init: function( selector, context, rootjQuery ) { + var match, elem, ret, doc; + + // Handle $(""), $(null), or $(undefined) + if ( !selector ) { + return this; + } + + // Handle $(DOMElement) + if ( selector.nodeType ) { + this.context = this[0] = selector; + this.length = 1; + return this; + } + + // The body element only exists once, optimize finding it + if ( selector === "body" && !context && document.body ) { + this.context = document; + this[0] = document.body; + this.selector = selector; + this.length = 1; + return this; + } + + // Handle HTML strings + if ( typeof selector === "string" ) { + // Are we dealing with HTML string or an ID? + if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) { + // Assume that strings that start and end with <> are HTML and skip the regex check + match = [ null, selector, null ]; + + } else { + match = quickExpr.exec( selector ); + } + + // Verify a match, and that no context was specified for #id + if ( match && (match[1] || !context) ) { + + // HANDLE: $(html) -> $(array) + if ( match[1] ) { + context = context instanceof jQuery ? context[0] : context; + doc = ( context ? context.ownerDocument || context : document ); + + // If a single string is passed in and it's a single tag + // just do a createElement and skip the rest + ret = rsingleTag.exec( selector ); + + if ( ret ) { + if ( jQuery.isPlainObject( context ) ) { + selector = [ document.createElement( ret[1] ) ]; + jQuery.fn.attr.call( selector, context, true ); + + } else { + selector = [ doc.createElement( ret[1] ) ]; + } + + } else { + ret = jQuery.buildFragment( [ match[1] ], [ doc ] ); + selector = ( ret.cacheable ? jQuery.clone(ret.fragment) : ret.fragment ).childNodes; + } + + return jQuery.merge( this, selector ); + + // HANDLE: $("#id") + } else { + elem = document.getElementById( match[2] ); + + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + if ( elem && elem.parentNode ) { + // Handle the case where IE and Opera return items + // by name instead of ID + if ( elem.id !== match[2] ) { + return rootjQuery.find( selector ); + } + + // Otherwise, we inject the element directly into the jQuery object + this.length = 1; + this[0] = elem; + } + + this.context = document; + this.selector = selector; + return this; + } + + // HANDLE: $(expr, $(...)) + } else if ( !context || context.jquery ) { + return ( context || rootjQuery ).find( selector ); + + // HANDLE: $(expr, context) + // (which is just equivalent to: $(context).find(expr) + } else { + return this.constructor( context ).find( selector ); + } + + // HANDLE: $(function) + // Shortcut for document ready + } else if ( jQuery.isFunction( selector ) ) { + return rootjQuery.ready( selector ); + } + + if ( selector.selector !== undefined ) { + this.selector = selector.selector; + this.context = selector.context; + } + + return jQuery.makeArray( selector, this ); + }, + + // Start with an empty selector + selector: "", + + // The current version of jQuery being used + jquery: "1.7.2", + + // The default length of a jQuery object is 0 + length: 0, + + // The number of elements contained in the matched element set + size: function() { + return this.length; + }, + + toArray: function() { + return slice.call( this, 0 ); + }, + + // Get the Nth element in the matched element set OR + // Get the whole matched element set as a clean array + get: function( num ) { + return num == null ? + + // Return a 'clean' array + this.toArray() : + + // Return just the object + ( num < 0 ? this[ this.length + num ] : this[ num ] ); + }, + + // Take an array of elements and push it onto the stack + // (returning the new matched element set) + pushStack: function( elems, name, selector ) { + // Build a new jQuery matched element set + var ret = this.constructor(); + + if ( jQuery.isArray( elems ) ) { + push.apply( ret, elems ); + + } else { + jQuery.merge( ret, elems ); + } + + // Add the old object onto the stack (as a reference) + ret.prevObject = this; + + ret.context = this.context; + + if ( name === "find" ) { + ret.selector = this.selector + ( this.selector ? " " : "" ) + selector; + } else if ( name ) { + ret.selector = this.selector + "." + name + "(" + selector + ")"; + } + + // Return the newly-formed element set + return ret; + }, + + // Execute a callback for every element in the matched set. + // (You can seed the arguments with an array of args, but this is + // only used internally.) + each: function( callback, args ) { + return jQuery.each( this, callback, args ); + }, + + ready: function( fn ) { + // Attach the listeners + jQuery.bindReady(); + + // Add the callback + readyList.add( fn ); + + return this; + }, + + eq: function( i ) { + i = +i; + return i === -1 ? + this.slice( i ) : + this.slice( i, i + 1 ); + }, + + first: function() { + return this.eq( 0 ); + }, + + last: function() { + return this.eq( -1 ); + }, + + slice: function() { + return this.pushStack( slice.apply( this, arguments ), + "slice", slice.call(arguments).join(",") ); + }, + + map: function( callback ) { + return this.pushStack( jQuery.map(this, function( elem, i ) { + return callback.call( elem, i, elem ); + })); + }, + + end: function() { + return this.prevObject || this.constructor(null); + }, + + // For internal use only. + // Behaves like an Array's method, not like a jQuery method. + push: push, + sort: [].sort, + splice: [].splice +}; + +// Give the init function the jQuery prototype for later instantiation +jQuery.fn.init.prototype = jQuery.fn; + +jQuery.extend = jQuery.fn.extend = function() { + var options, name, src, copy, copyIsArray, clone, + target = arguments[0] || {}, + i = 1, + length = arguments.length, + deep = false; + + // Handle a deep copy situation + if ( typeof target === "boolean" ) { + deep = target; + target = arguments[1] || {}; + // skip the boolean and the target + i = 2; + } + + // Handle case when target is a string or something (possible in deep copy) + if ( typeof target !== "object" && !jQuery.isFunction(target) ) { + target = {}; + } + + // extend jQuery itself if only one argument is passed + if ( length === i ) { + target = this; + --i; + } + + for ( ; i < length; i++ ) { + // Only deal with non-null/undefined values + if ( (options = arguments[ i ]) != null ) { + // Extend the base object + for ( name in options ) { + src = target[ name ]; + copy = options[ name ]; + + // Prevent never-ending loop + if ( target === copy ) { + continue; + } + + // Recurse if we're merging plain objects or arrays + if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) { + if ( copyIsArray ) { + copyIsArray = false; + clone = src && jQuery.isArray(src) ? src : []; + + } else { + clone = src && jQuery.isPlainObject(src) ? src : {}; + } + + // Never move original objects, clone them + target[ name ] = jQuery.extend( deep, clone, copy ); + + // Don't bring in undefined values + } else if ( copy !== undefined ) { + target[ name ] = copy; + } + } + } + } + + // Return the modified object + return target; +}; + +jQuery.extend({ + noConflict: function( deep ) { + if ( window.$ === jQuery ) { + window.$ = _$; + } + + if ( deep && window.jQuery === jQuery ) { + window.jQuery = _jQuery; + } + + return jQuery; + }, + + // Is the DOM ready to be used? Set to true once it occurs. + isReady: false, + + // A counter to track how many items to wait for before + // the ready event fires. See #6781 + readyWait: 1, + + // Hold (or release) the ready event + holdReady: function( hold ) { + if ( hold ) { + jQuery.readyWait++; + } else { + jQuery.ready( true ); + } + }, + + // Handle when the DOM is ready + ready: function( wait ) { + // Either a released hold or an DOMready/load event and not yet ready + if ( (wait === true && !--jQuery.readyWait) || (wait !== true && !jQuery.isReady) ) { + // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). + if ( !document.body ) { + return setTimeout( jQuery.ready, 1 ); + } + + // Remember that the DOM is ready + jQuery.isReady = true; + + // If a normal DOM Ready event fired, decrement, and wait if need be + if ( wait !== true && --jQuery.readyWait > 0 ) { + return; + } + + // If there are functions bound, to execute + readyList.fireWith( document, [ jQuery ] ); + + // Trigger any bound ready events + if ( jQuery.fn.trigger ) { + jQuery( document ).trigger( "ready" ).off( "ready" ); + } + } + }, + + bindReady: function() { + if ( readyList ) { + return; + } + + readyList = jQuery.Callbacks( "once memory" ); + + // Catch cases where $(document).ready() is called after the + // browser event has already occurred. + if ( document.readyState === "complete" ) { + // Handle it asynchronously to allow scripts the opportunity to delay ready + return setTimeout( jQuery.ready, 1 ); + } + + // Mozilla, Opera and webkit nightlies currently support this event + if ( document.addEventListener ) { + // Use the handy event callback + document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false ); + + // A fallback to window.onload, that will always work + window.addEventListener( "load", jQuery.ready, false ); + + // If IE event model is used + } else if ( document.attachEvent ) { + // ensure firing before onload, + // maybe late but safe also for iframes + document.attachEvent( "onreadystatechange", DOMContentLoaded ); + + // A fallback to window.onload, that will always work + window.attachEvent( "onload", jQuery.ready ); + + // If IE and not a frame + // continually check to see if the document is ready + var toplevel = false; + + try { + toplevel = window.frameElement == null; + } catch(e) {} + + if ( document.documentElement.doScroll && toplevel ) { + doScrollCheck(); + } + } + }, + + // See test/unit/core.js for details concerning isFunction. + // Since version 1.3, DOM methods and functions like alert + // aren't supported. They return false on IE (#2968). + isFunction: function( obj ) { + return jQuery.type(obj) === "function"; + }, + + isArray: Array.isArray || function( obj ) { + return jQuery.type(obj) === "array"; + }, + + isWindow: function( obj ) { + return obj != null && obj == obj.window; + }, + + isNumeric: function( obj ) { + return !isNaN( parseFloat(obj) ) && isFinite( obj ); + }, + + type: function( obj ) { + return obj == null ? + String( obj ) : + class2type[ toString.call(obj) ] || "object"; + }, + + isPlainObject: function( obj ) { + // Must be an Object. + // Because of IE, we also have to check the presence of the constructor property. + // Make sure that DOM nodes and window objects don't pass through, as well + if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) { + return false; + } + + try { + // Not own constructor property must be Object + if ( obj.constructor && + !hasOwn.call(obj, "constructor") && + !hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) { + return false; + } + } catch ( e ) { + // IE8,9 Will throw exceptions on certain host objects #9897 + return false; + } + + // Own properties are enumerated firstly, so to speed up, + // if last one is own, then all properties are own. + + var key; + for ( key in obj ) {} + + return key === undefined || hasOwn.call( obj, key ); + }, + + isEmptyObject: function( obj ) { + for ( var name in obj ) { + return false; + } + return true; + }, + + error: function( msg ) { + throw new Error( msg ); + }, + + parseJSON: function( data ) { + if ( typeof data !== "string" || !data ) { + return null; + } + + // Make sure leading/trailing whitespace is removed (IE can't handle it) + data = jQuery.trim( data ); + + // Attempt to parse using the native JSON parser first + if ( window.JSON && window.JSON.parse ) { + return window.JSON.parse( data ); + } + + // Make sure the incoming data is actual JSON + // Logic borrowed from http://json.org/json2.js + if ( rvalidchars.test( data.replace( rvalidescape, "@" ) + .replace( rvalidtokens, "]" ) + .replace( rvalidbraces, "")) ) { + + return ( new Function( "return " + data ) )(); + + } + jQuery.error( "Invalid JSON: " + data ); + }, + + // Cross-browser xml parsing + parseXML: function( data ) { + if ( typeof data !== "string" || !data ) { + return null; + } + var xml, tmp; + try { + if ( window.DOMParser ) { // Standard + tmp = new DOMParser(); + xml = tmp.parseFromString( data , "text/xml" ); + } else { // IE + xml = new ActiveXObject( "Microsoft.XMLDOM" ); + xml.async = "false"; + xml.loadXML( data ); + } + } catch( e ) { + xml = undefined; + } + if ( !xml || !xml.documentElement || xml.getElementsByTagName( "parsererror" ).length ) { + jQuery.error( "Invalid XML: " + data ); + } + return xml; + }, + + noop: function() {}, + + // Evaluates a script in a global context + // Workarounds based on findings by Jim Driscoll + // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context + globalEval: function( data ) { + if ( data && rnotwhite.test( data ) ) { + // We use execScript on Internet Explorer + // We use an anonymous function so that context is window + // rather than jQuery in Firefox + ( window.execScript || function( data ) { + window[ "eval" ].call( window, data ); + } )( data ); + } + }, + + // Convert dashed to camelCase; used by the css and data modules + // Microsoft forgot to hump their vendor prefix (#9572) + camelCase: function( string ) { + return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); + }, + + nodeName: function( elem, name ) { + return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase(); + }, + + // args is for internal usage only + each: function( object, callback, args ) { + var name, i = 0, + length = object.length, + isObj = length === undefined || jQuery.isFunction( object ); + + if ( args ) { + if ( isObj ) { + for ( name in object ) { + if ( callback.apply( object[ name ], args ) === false ) { + break; + } + } + } else { + for ( ; i < length; ) { + if ( callback.apply( object[ i++ ], args ) === false ) { + break; + } + } + } + + // A special, fast, case for the most common use of each + } else { + if ( isObj ) { + for ( name in object ) { + if ( callback.call( object[ name ], name, object[ name ] ) === false ) { + break; + } + } + } else { + for ( ; i < length; ) { + if ( callback.call( object[ i ], i, object[ i++ ] ) === false ) { + break; + } + } + } + } + + return object; + }, + + // Use native String.trim function wherever possible + trim: trim ? + function( text ) { + return text == null ? + "" : + trim.call( text ); + } : + + // Otherwise use our own trimming functionality + function( text ) { + return text == null ? + "" : + text.toString().replace( trimLeft, "" ).replace( trimRight, "" ); + }, + + // results is for internal usage only + makeArray: function( array, results ) { + var ret = results || []; + + if ( array != null ) { + // The window, strings (and functions) also have 'length' + // Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930 + var type = jQuery.type( array ); + + if ( array.length == null || type === "string" || type === "function" || type === "regexp" || jQuery.isWindow( array ) ) { + push.call( ret, array ); + } else { + jQuery.merge( ret, array ); + } + } + + return ret; + }, + + inArray: function( elem, array, i ) { + var len; + + if ( array ) { + if ( indexOf ) { + return indexOf.call( array, elem, i ); + } + + len = array.length; + i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0; + + for ( ; i < len; i++ ) { + // Skip accessing in sparse arrays + if ( i in array && array[ i ] === elem ) { + return i; + } + } + } + + return -1; + }, + + merge: function( first, second ) { + var i = first.length, + j = 0; + + if ( typeof second.length === "number" ) { + for ( var l = second.length; j < l; j++ ) { + first[ i++ ] = second[ j ]; + } + + } else { + while ( second[j] !== undefined ) { + first[ i++ ] = second[ j++ ]; + } + } + + first.length = i; + + return first; + }, + + grep: function( elems, callback, inv ) { + var ret = [], retVal; + inv = !!inv; + + // Go through the array, only saving the items + // that pass the validator function + for ( var i = 0, length = elems.length; i < length; i++ ) { + retVal = !!callback( elems[ i ], i ); + if ( inv !== retVal ) { + ret.push( elems[ i ] ); + } + } + + return ret; + }, + + // arg is for internal usage only + map: function( elems, callback, arg ) { + var value, key, ret = [], + i = 0, + length = elems.length, + // jquery objects are treated as arrays + isArray = elems instanceof jQuery || length !== undefined && typeof length === "number" && ( ( length > 0 && elems[ 0 ] && elems[ length -1 ] ) || length === 0 || jQuery.isArray( elems ) ) ; + + // Go through the array, translating each of the items to their + if ( isArray ) { + for ( ; i < length; i++ ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret[ ret.length ] = value; + } + } + + // Go through every key on the object, + } else { + for ( key in elems ) { + value = callback( elems[ key ], key, arg ); + + if ( value != null ) { + ret[ ret.length ] = value; + } + } + } + + // Flatten any nested arrays + return ret.concat.apply( [], ret ); + }, + + // A global GUID counter for objects + guid: 1, + + // Bind a function to a context, optionally partially applying any + // arguments. + proxy: function( fn, context ) { + if ( typeof context === "string" ) { + var tmp = fn[ context ]; + context = fn; + fn = tmp; + } + + // Quick check to determine if target is callable, in the spec + // this throws a TypeError, but we will just return undefined. + if ( !jQuery.isFunction( fn ) ) { + return undefined; + } + + // Simulated bind + var args = slice.call( arguments, 2 ), + proxy = function() { + return fn.apply( context, args.concat( slice.call( arguments ) ) ); + }; + + // Set the guid of unique handler to the same of original handler, so it can be removed + proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++; + + return proxy; + }, + + // Mutifunctional method to get and set values to a collection + // The value/s can optionally be executed if it's a function + access: function( elems, fn, key, value, chainable, emptyGet, pass ) { + var exec, + bulk = key == null, + i = 0, + length = elems.length; + + // Sets many values + if ( key && typeof key === "object" ) { + for ( i in key ) { + jQuery.access( elems, fn, i, key[i], 1, emptyGet, value ); + } + chainable = 1; + + // Sets one value + } else if ( value !== undefined ) { + // Optionally, function values get executed if exec is true + exec = pass === undefined && jQuery.isFunction( value ); + + if ( bulk ) { + // Bulk operations only iterate when executing function values + if ( exec ) { + exec = fn; + fn = function( elem, key, value ) { + return exec.call( jQuery( elem ), value ); + }; + + // Otherwise they run against the entire set + } else { + fn.call( elems, value ); + fn = null; + } + } + + if ( fn ) { + for (; i < length; i++ ) { + fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass ); + } + } + + chainable = 1; + } + + return chainable ? + elems : + + // Gets + bulk ? + fn.call( elems ) : + length ? fn( elems[0], key ) : emptyGet; + }, + + now: function() { + return ( new Date() ).getTime(); + }, + + // Use of jQuery.browser is frowned upon. + // More details: http://docs.jquery.com/Utilities/jQuery.browser + uaMatch: function( ua ) { + ua = ua.toLowerCase(); + + var match = rwebkit.exec( ua ) || + ropera.exec( ua ) || + rmsie.exec( ua ) || + ua.indexOf("compatible") < 0 && rmozilla.exec( ua ) || + []; + + return { browser: match[1] || "", version: match[2] || "0" }; + }, + + sub: function() { + function jQuerySub( selector, context ) { + return new jQuerySub.fn.init( selector, context ); + } + jQuery.extend( true, jQuerySub, this ); + jQuerySub.superclass = this; + jQuerySub.fn = jQuerySub.prototype = this(); + jQuerySub.fn.constructor = jQuerySub; + jQuerySub.sub = this.sub; + jQuerySub.fn.init = function init( selector, context ) { + if ( context && context instanceof jQuery && !(context instanceof jQuerySub) ) { + context = jQuerySub( context ); + } + + return jQuery.fn.init.call( this, selector, context, rootjQuerySub ); + }; + jQuerySub.fn.init.prototype = jQuerySub.fn; + var rootjQuerySub = jQuerySub(document); + return jQuerySub; + }, + + browser: {} +}); + +// Populate the class2type map +jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) { + class2type[ "[object " + name + "]" ] = name.toLowerCase(); +}); + +browserMatch = jQuery.uaMatch( userAgent ); +if ( browserMatch.browser ) { + jQuery.browser[ browserMatch.browser ] = true; + jQuery.browser.version = browserMatch.version; +} + +// Deprecated, use jQuery.browser.webkit instead +if ( jQuery.browser.webkit ) { + jQuery.browser.safari = true; +} + +// IE doesn't match non-breaking spaces with \s +if ( rnotwhite.test( "\xA0" ) ) { + trimLeft = /^[\s\xA0]+/; + trimRight = /[\s\xA0]+$/; +} + +// All jQuery objects should point back to these +rootjQuery = jQuery(document); + +// Cleanup functions for the document ready method +if ( document.addEventListener ) { + DOMContentLoaded = function() { + document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false ); + jQuery.ready(); + }; + +} else if ( document.attachEvent ) { + DOMContentLoaded = function() { + // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). + if ( document.readyState === "complete" ) { + document.detachEvent( "onreadystatechange", DOMContentLoaded ); + jQuery.ready(); + } + }; +} + +// The DOM ready check for Internet Explorer +function doScrollCheck() { + if ( jQuery.isReady ) { + return; + } + + try { + // If IE is used, use the trick by Diego Perini + // http://javascript.nwbox.com/IEContentLoaded/ + document.documentElement.doScroll("left"); + } catch(e) { + setTimeout( doScrollCheck, 1 ); + return; + } + + // and execute any waiting functions + jQuery.ready(); +} + +return jQuery; + +})(); + + +// String to Object flags format cache +var flagsCache = {}; + +// Convert String-formatted flags into Object-formatted ones and store in cache +function createFlags( flags ) { + var object = flagsCache[ flags ] = {}, + i, length; + flags = flags.split( /\s+/ ); + for ( i = 0, length = flags.length; i < length; i++ ) { + object[ flags[i] ] = true; + } + return object; +} + +/* + * Create a callback list using the following parameters: + * + * flags: an optional list of space-separated flags that will change how + * the callback list behaves + * + * By default a callback list will act like an event callback list and can be + * "fired" multiple times. + * + * Possible flags: + * + * once: will ensure the callback list can only be fired once (like a Deferred) + * + * memory: will keep track of previous values and will call any callback added + * after the list has been fired right away with the latest "memorized" + * values (like a Deferred) + * + * unique: will ensure a callback can only be added once (no duplicate in the list) + * + * stopOnFalse: interrupt callings when a callback returns false + * + */ +jQuery.Callbacks = function( flags ) { + + // Convert flags from String-formatted to Object-formatted + // (we check in cache first) + flags = flags ? ( flagsCache[ flags ] || createFlags( flags ) ) : {}; + + var // Actual callback list + list = [], + // Stack of fire calls for repeatable lists + stack = [], + // Last fire value (for non-forgettable lists) + memory, + // Flag to know if list was already fired + fired, + // Flag to know if list is currently firing + firing, + // First callback to fire (used internally by add and fireWith) + firingStart, + // End of the loop when firing + firingLength, + // Index of currently firing callback (modified by remove if needed) + firingIndex, + // Add one or several callbacks to the list + add = function( args ) { + var i, + length, + elem, + type, + actual; + for ( i = 0, length = args.length; i < length; i++ ) { + elem = args[ i ]; + type = jQuery.type( elem ); + if ( type === "array" ) { + // Inspect recursively + add( elem ); + } else if ( type === "function" ) { + // Add if not in unique mode and callback is not in + if ( !flags.unique || !self.has( elem ) ) { + list.push( elem ); + } + } + } + }, + // Fire callbacks + fire = function( context, args ) { + args = args || []; + memory = !flags.memory || [ context, args ]; + fired = true; + firing = true; + firingIndex = firingStart || 0; + firingStart = 0; + firingLength = list.length; + for ( ; list && firingIndex < firingLength; firingIndex++ ) { + if ( list[ firingIndex ].apply( context, args ) === false && flags.stopOnFalse ) { + memory = true; // Mark as halted + break; + } + } + firing = false; + if ( list ) { + if ( !flags.once ) { + if ( stack && stack.length ) { + memory = stack.shift(); + self.fireWith( memory[ 0 ], memory[ 1 ] ); + } + } else if ( memory === true ) { + self.disable(); + } else { + list = []; + } + } + }, + // Actual Callbacks object + self = { + // Add a callback or a collection of callbacks to the list + add: function() { + if ( list ) { + var length = list.length; + add( arguments ); + // Do we need to add the callbacks to the + // current firing batch? + if ( firing ) { + firingLength = list.length; + // With memory, if we're not firing then + // we should call right away, unless previous + // firing was halted (stopOnFalse) + } else if ( memory && memory !== true ) { + firingStart = length; + fire( memory[ 0 ], memory[ 1 ] ); + } + } + return this; + }, + // Remove a callback from the list + remove: function() { + if ( list ) { + var args = arguments, + argIndex = 0, + argLength = args.length; + for ( ; argIndex < argLength ; argIndex++ ) { + for ( var i = 0; i < list.length; i++ ) { + if ( args[ argIndex ] === list[ i ] ) { + // Handle firingIndex and firingLength + if ( firing ) { + if ( i <= firingLength ) { + firingLength--; + if ( i <= firingIndex ) { + firingIndex--; + } + } + } + // Remove the element + list.splice( i--, 1 ); + // If we have some unicity property then + // we only need to do this once + if ( flags.unique ) { + break; + } + } + } + } + } + return this; + }, + // Control if a given callback is in the list + has: function( fn ) { + if ( list ) { + var i = 0, + length = list.length; + for ( ; i < length; i++ ) { + if ( fn === list[ i ] ) { + return true; + } + } + } + return false; + }, + // Remove all callbacks from the list + empty: function() { + list = []; + return this; + }, + // Have the list do nothing anymore + disable: function() { + list = stack = memory = undefined; + return this; + }, + // Is it disabled? + disabled: function() { + return !list; + }, + // Lock the list in its current state + lock: function() { + stack = undefined; + if ( !memory || memory === true ) { + self.disable(); + } + return this; + }, + // Is it locked? + locked: function() { + return !stack; + }, + // Call all callbacks with the given context and arguments + fireWith: function( context, args ) { + if ( stack ) { + if ( firing ) { + if ( !flags.once ) { + stack.push( [ context, args ] ); + } + } else if ( !( flags.once && memory ) ) { + fire( context, args ); + } + } + return this; + }, + // Call all the callbacks with the given arguments + fire: function() { + self.fireWith( this, arguments ); + return this; + }, + // To know if the callbacks have already been called at least once + fired: function() { + return !!fired; + } + }; + + return self; +}; + + + + +var // Static reference to slice + sliceDeferred = [].slice; + +jQuery.extend({ + + Deferred: function( func ) { + var doneList = jQuery.Callbacks( "once memory" ), + failList = jQuery.Callbacks( "once memory" ), + progressList = jQuery.Callbacks( "memory" ), + state = "pending", + lists = { + resolve: doneList, + reject: failList, + notify: progressList + }, + promise = { + done: doneList.add, + fail: failList.add, + progress: progressList.add, + + state: function() { + return state; + }, + + // Deprecated + isResolved: doneList.fired, + isRejected: failList.fired, + + then: function( doneCallbacks, failCallbacks, progressCallbacks ) { + deferred.done( doneCallbacks ).fail( failCallbacks ).progress( progressCallbacks ); + return this; + }, + always: function() { + deferred.done.apply( deferred, arguments ).fail.apply( deferred, arguments ); + return this; + }, + pipe: function( fnDone, fnFail, fnProgress ) { + return jQuery.Deferred(function( newDefer ) { + jQuery.each( { + done: [ fnDone, "resolve" ], + fail: [ fnFail, "reject" ], + progress: [ fnProgress, "notify" ] + }, function( handler, data ) { + var fn = data[ 0 ], + action = data[ 1 ], + returned; + if ( jQuery.isFunction( fn ) ) { + deferred[ handler ](function() { + returned = fn.apply( this, arguments ); + if ( returned && jQuery.isFunction( returned.promise ) ) { + returned.promise().then( newDefer.resolve, newDefer.reject, newDefer.notify ); + } else { + newDefer[ action + "With" ]( this === deferred ? newDefer : this, [ returned ] ); + } + }); + } else { + deferred[ handler ]( newDefer[ action ] ); + } + }); + }).promise(); + }, + // Get a promise for this deferred + // If obj is provided, the promise aspect is added to the object + promise: function( obj ) { + if ( obj == null ) { + obj = promise; + } else { + for ( var key in promise ) { + obj[ key ] = promise[ key ]; + } + } + return obj; + } + }, + deferred = promise.promise({}), + key; + + for ( key in lists ) { + deferred[ key ] = lists[ key ].fire; + deferred[ key + "With" ] = lists[ key ].fireWith; + } + + // Handle state + deferred.done( function() { + state = "resolved"; + }, failList.disable, progressList.lock ).fail( function() { + state = "rejected"; + }, doneList.disable, progressList.lock ); + + // Call given func if any + if ( func ) { + func.call( deferred, deferred ); + } + + // All done! + return deferred; + }, + + // Deferred helper + when: function( firstParam ) { + var args = sliceDeferred.call( arguments, 0 ), + i = 0, + length = args.length, + pValues = new Array( length ), + count = length, + pCount = length, + deferred = length <= 1 && firstParam && jQuery.isFunction( firstParam.promise ) ? + firstParam : + jQuery.Deferred(), + promise = deferred.promise(); + function resolveFunc( i ) { + return function( value ) { + args[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value; + if ( !( --count ) ) { + deferred.resolveWith( deferred, args ); + } + }; + } + function progressFunc( i ) { + return function( value ) { + pValues[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value; + deferred.notifyWith( promise, pValues ); + }; + } + if ( length > 1 ) { + for ( ; i < length; i++ ) { + if ( args[ i ] && args[ i ].promise && jQuery.isFunction( args[ i ].promise ) ) { + args[ i ].promise().then( resolveFunc(i), deferred.reject, progressFunc(i) ); + } else { + --count; + } + } + if ( !count ) { + deferred.resolveWith( deferred, args ); + } + } else if ( deferred !== firstParam ) { + deferred.resolveWith( deferred, length ? [ firstParam ] : [] ); + } + return promise; + } +}); + + + + +jQuery.support = (function() { + + var support, + all, + a, + select, + opt, + input, + fragment, + tds, + events, + eventName, + i, + isSupported, + div = document.createElement( "div" ), + documentElement = document.documentElement; + + // Preliminary tests + div.setAttribute("className", "t"); + div.innerHTML = "
    a"; + + all = div.getElementsByTagName( "*" ); + a = div.getElementsByTagName( "a" )[ 0 ]; + + // Can't get basic test support + if ( !all || !all.length || !a ) { + return {}; + } + + // First batch of supports tests + select = document.createElement( "select" ); + opt = select.appendChild( document.createElement("option") ); + input = div.getElementsByTagName( "input" )[ 0 ]; + + support = { + // IE strips leading whitespace when .innerHTML is used + leadingWhitespace: ( div.firstChild.nodeType === 3 ), + + // Make sure that tbody elements aren't automatically inserted + // IE will insert them into empty tables + tbody: !div.getElementsByTagName("tbody").length, + + // Make sure that link elements get serialized correctly by innerHTML + // This requires a wrapper element in IE + htmlSerialize: !!div.getElementsByTagName("link").length, + + // Get the style information from getAttribute + // (IE uses .cssText instead) + style: /top/.test( a.getAttribute("style") ), + + // Make sure that URLs aren't manipulated + // (IE normalizes it by default) + hrefNormalized: ( a.getAttribute("href") === "/a" ), + + // Make sure that element opacity exists + // (IE uses filter instead) + // Use a regex to work around a WebKit issue. See #5145 + opacity: /^0.55/.test( a.style.opacity ), + + // Verify style float existence + // (IE uses styleFloat instead of cssFloat) + cssFloat: !!a.style.cssFloat, + + // Make sure that if no value is specified for a checkbox + // that it defaults to "on". + // (WebKit defaults to "" instead) + checkOn: ( input.value === "on" ), + + // Make sure that a selected-by-default option has a working selected property. + // (WebKit defaults to false instead of true, IE too, if it's in an optgroup) + optSelected: opt.selected, + + // Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7) + getSetAttribute: div.className !== "t", + + // Tests for enctype support on a form(#6743) + enctype: !!document.createElement("form").enctype, + + // Makes sure cloning an html5 element does not cause problems + // Where outerHTML is undefined, this still works + html5Clone: document.createElement("nav").cloneNode( true ).outerHTML !== "<:nav>", + + // Will be defined later + submitBubbles: true, + changeBubbles: true, + focusinBubbles: false, + deleteExpando: true, + noCloneEvent: true, + inlineBlockNeedsLayout: false, + shrinkWrapBlocks: false, + reliableMarginRight: true, + pixelMargin: true + }; + + // jQuery.boxModel DEPRECATED in 1.3, use jQuery.support.boxModel instead + jQuery.boxModel = support.boxModel = (document.compatMode === "CSS1Compat"); + + // Make sure checked status is properly cloned + input.checked = true; + support.noCloneChecked = input.cloneNode( true ).checked; + + // Make sure that the options inside disabled selects aren't marked as disabled + // (WebKit marks them as disabled) + select.disabled = true; + support.optDisabled = !opt.disabled; + + // Test to see if it's possible to delete an expando from an element + // Fails in Internet Explorer + try { + delete div.test; + } catch( e ) { + support.deleteExpando = false; + } + + if ( !div.addEventListener && div.attachEvent && div.fireEvent ) { + div.attachEvent( "onclick", function() { + // Cloning a node shouldn't copy over any + // bound event handlers (IE does this) + support.noCloneEvent = false; + }); + div.cloneNode( true ).fireEvent( "onclick" ); + } + + // Check if a radio maintains its value + // after being appended to the DOM + input = document.createElement("input"); + input.value = "t"; + input.setAttribute("type", "radio"); + support.radioValue = input.value === "t"; + + input.setAttribute("checked", "checked"); + + // #11217 - WebKit loses check when the name is after the checked attribute + input.setAttribute( "name", "t" ); + + div.appendChild( input ); + fragment = document.createDocumentFragment(); + fragment.appendChild( div.lastChild ); + + // WebKit doesn't clone checked state correctly in fragments + support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked; + + // Check if a disconnected checkbox will retain its checked + // value of true after appended to the DOM (IE6/7) + support.appendChecked = input.checked; + + fragment.removeChild( input ); + fragment.appendChild( div ); + + // Technique from Juriy Zaytsev + // http://perfectionkills.com/detecting-event-support-without-browser-sniffing/ + // We only care about the case where non-standard event systems + // are used, namely in IE. Short-circuiting here helps us to + // avoid an eval call (in setAttribute) which can cause CSP + // to go haywire. See: https://developer.mozilla.org/en/Security/CSP + if ( div.attachEvent ) { + for ( i in { + submit: 1, + change: 1, + focusin: 1 + }) { + eventName = "on" + i; + isSupported = ( eventName in div ); + if ( !isSupported ) { + div.setAttribute( eventName, "return;" ); + isSupported = ( typeof div[ eventName ] === "function" ); + } + support[ i + "Bubbles" ] = isSupported; + } + } + + fragment.removeChild( div ); + + // Null elements to avoid leaks in IE + fragment = select = opt = div = input = null; + + // Run tests that need a body at doc ready + jQuery(function() { + var container, outer, inner, table, td, offsetSupport, + marginDiv, conMarginTop, style, html, positionTopLeftWidthHeight, + paddingMarginBorderVisibility, paddingMarginBorder, + body = document.getElementsByTagName("body")[0]; + + if ( !body ) { + // Return for frameset docs that don't have a body + return; + } + + conMarginTop = 1; + paddingMarginBorder = "padding:0;margin:0;border:"; + positionTopLeftWidthHeight = "position:absolute;top:0;left:0;width:1px;height:1px;"; + paddingMarginBorderVisibility = paddingMarginBorder + "0;visibility:hidden;"; + style = "style='" + positionTopLeftWidthHeight + paddingMarginBorder + "5px solid #000;"; + html = "
    " + + "" + + "
    "; + + container = document.createElement("div"); + container.style.cssText = paddingMarginBorderVisibility + "width:0;height:0;position:static;top:0;margin-top:" + conMarginTop + "px"; + body.insertBefore( container, body.firstChild ); + + // Construct the test element + div = document.createElement("div"); + container.appendChild( div ); + + // Check if table cells still have offsetWidth/Height when they are set + // to display:none and there are still other visible table cells in a + // table row; if so, offsetWidth/Height are not reliable for use when + // determining if an element has been hidden directly using + // display:none (it is still safe to use offsets if a parent element is + // hidden; don safety goggles and see bug #4512 for more information). + // (only IE 8 fails this test) + div.innerHTML = "
    t
    "; + tds = div.getElementsByTagName( "td" ); + isSupported = ( tds[ 0 ].offsetHeight === 0 ); + + tds[ 0 ].style.display = ""; + tds[ 1 ].style.display = "none"; + + // Check if empty table cells still have offsetWidth/Height + // (IE <= 8 fail this test) + support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 ); + + // Check if div with explicit width and no margin-right incorrectly + // gets computed margin-right based on width of container. For more + // info see bug #3333 + // Fails in WebKit before Feb 2011 nightlies + // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right + if ( window.getComputedStyle ) { + div.innerHTML = ""; + marginDiv = document.createElement( "div" ); + marginDiv.style.width = "0"; + marginDiv.style.marginRight = "0"; + div.style.width = "2px"; + div.appendChild( marginDiv ); + support.reliableMarginRight = + ( parseInt( ( window.getComputedStyle( marginDiv, null ) || { marginRight: 0 } ).marginRight, 10 ) || 0 ) === 0; + } + + if ( typeof div.style.zoom !== "undefined" ) { + // Check if natively block-level elements act like inline-block + // elements when setting their display to 'inline' and giving + // them layout + // (IE < 8 does this) + div.innerHTML = ""; + div.style.width = div.style.padding = "1px"; + div.style.border = 0; + div.style.overflow = "hidden"; + div.style.display = "inline"; + div.style.zoom = 1; + support.inlineBlockNeedsLayout = ( div.offsetWidth === 3 ); + + // Check if elements with layout shrink-wrap their children + // (IE 6 does this) + div.style.display = "block"; + div.style.overflow = "visible"; + div.innerHTML = "
    "; + support.shrinkWrapBlocks = ( div.offsetWidth !== 3 ); + } + + div.style.cssText = positionTopLeftWidthHeight + paddingMarginBorderVisibility; + div.innerHTML = html; + + outer = div.firstChild; + inner = outer.firstChild; + td = outer.nextSibling.firstChild.firstChild; + + offsetSupport = { + doesNotAddBorder: ( inner.offsetTop !== 5 ), + doesAddBorderForTableAndCells: ( td.offsetTop === 5 ) + }; + + inner.style.position = "fixed"; + inner.style.top = "20px"; + + // safari subtracts parent border width here which is 5px + offsetSupport.fixedPosition = ( inner.offsetTop === 20 || inner.offsetTop === 15 ); + inner.style.position = inner.style.top = ""; + + outer.style.overflow = "hidden"; + outer.style.position = "relative"; + + offsetSupport.subtractsBorderForOverflowNotVisible = ( inner.offsetTop === -5 ); + offsetSupport.doesNotIncludeMarginInBodyOffset = ( body.offsetTop !== conMarginTop ); + + if ( window.getComputedStyle ) { + div.style.marginTop = "1%"; + support.pixelMargin = ( window.getComputedStyle( div, null ) || { marginTop: 0 } ).marginTop !== "1%"; + } + + if ( typeof container.style.zoom !== "undefined" ) { + container.style.zoom = 1; + } + + body.removeChild( container ); + marginDiv = div = container = null; + + jQuery.extend( support, offsetSupport ); + }); + + return support; +})(); + + + + +var rbrace = /^(?:\{.*\}|\[.*\])$/, + rmultiDash = /([A-Z])/g; + +jQuery.extend({ + cache: {}, + + // Please use with caution + uuid: 0, + + // Unique for each copy of jQuery on the page + // Non-digits removed to match rinlinejQuery + expando: "jQuery" + ( jQuery.fn.jquery + Math.random() ).replace( /\D/g, "" ), + + // The following elements throw uncatchable exceptions if you + // attempt to add expando properties to them. + noData: { + "embed": true, + // Ban all objects except for Flash (which handle expandos) + "object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000", + "applet": true + }, + + hasData: function( elem ) { + elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ]; + return !!elem && !isEmptyDataObject( elem ); + }, + + data: function( elem, name, data, pvt /* Internal Use Only */ ) { + if ( !jQuery.acceptData( elem ) ) { + return; + } + + var privateCache, thisCache, ret, + internalKey = jQuery.expando, + getByName = typeof name === "string", + + // We have to handle DOM nodes and JS objects differently because IE6-7 + // can't GC object references properly across the DOM-JS boundary + isNode = elem.nodeType, + + // Only DOM nodes need the global jQuery cache; JS object data is + // attached directly to the object so GC can occur automatically + cache = isNode ? jQuery.cache : elem, + + // Only defining an ID for JS objects if its cache already exists allows + // the code to shortcut on the same path as a DOM node with no cache + id = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey, + isEvents = name === "events"; + + // Avoid doing any more work than we need to when trying to get data on an + // object that has no data at all + if ( (!id || !cache[id] || (!isEvents && !pvt && !cache[id].data)) && getByName && data === undefined ) { + return; + } + + if ( !id ) { + // Only DOM nodes need a new unique ID for each element since their data + // ends up in the global cache + if ( isNode ) { + elem[ internalKey ] = id = ++jQuery.uuid; + } else { + id = internalKey; + } + } + + if ( !cache[ id ] ) { + cache[ id ] = {}; + + // Avoids exposing jQuery metadata on plain JS objects when the object + // is serialized using JSON.stringify + if ( !isNode ) { + cache[ id ].toJSON = jQuery.noop; + } + } + + // An object can be passed to jQuery.data instead of a key/value pair; this gets + // shallow copied over onto the existing cache + if ( typeof name === "object" || typeof name === "function" ) { + if ( pvt ) { + cache[ id ] = jQuery.extend( cache[ id ], name ); + } else { + cache[ id ].data = jQuery.extend( cache[ id ].data, name ); + } + } + + privateCache = thisCache = cache[ id ]; + + // jQuery data() is stored in a separate object inside the object's internal data + // cache in order to avoid key collisions between internal data and user-defined + // data. + if ( !pvt ) { + if ( !thisCache.data ) { + thisCache.data = {}; + } + + thisCache = thisCache.data; + } + + if ( data !== undefined ) { + thisCache[ jQuery.camelCase( name ) ] = data; + } + + // Users should not attempt to inspect the internal events object using jQuery.data, + // it is undocumented and subject to change. But does anyone listen? No. + if ( isEvents && !thisCache[ name ] ) { + return privateCache.events; + } + + // Check for both converted-to-camel and non-converted data property names + // If a data property was specified + if ( getByName ) { + + // First Try to find as-is property data + ret = thisCache[ name ]; + + // Test for null|undefined property data + if ( ret == null ) { + + // Try to find the camelCased property + ret = thisCache[ jQuery.camelCase( name ) ]; + } + } else { + ret = thisCache; + } + + return ret; + }, + + removeData: function( elem, name, pvt /* Internal Use Only */ ) { + if ( !jQuery.acceptData( elem ) ) { + return; + } + + var thisCache, i, l, + + // Reference to internal data cache key + internalKey = jQuery.expando, + + isNode = elem.nodeType, + + // See jQuery.data for more information + cache = isNode ? jQuery.cache : elem, + + // See jQuery.data for more information + id = isNode ? elem[ internalKey ] : internalKey; + + // If there is already no cache entry for this object, there is no + // purpose in continuing + if ( !cache[ id ] ) { + return; + } + + if ( name ) { + + thisCache = pvt ? cache[ id ] : cache[ id ].data; + + if ( thisCache ) { + + // Support array or space separated string names for data keys + if ( !jQuery.isArray( name ) ) { + + // try the string as a key before any manipulation + if ( name in thisCache ) { + name = [ name ]; + } else { + + // split the camel cased version by spaces unless a key with the spaces exists + name = jQuery.camelCase( name ); + if ( name in thisCache ) { + name = [ name ]; + } else { + name = name.split( " " ); + } + } + } + + for ( i = 0, l = name.length; i < l; i++ ) { + delete thisCache[ name[i] ]; + } + + // If there is no data left in the cache, we want to continue + // and let the cache object itself get destroyed + if ( !( pvt ? isEmptyDataObject : jQuery.isEmptyObject )( thisCache ) ) { + return; + } + } + } + + // See jQuery.data for more information + if ( !pvt ) { + delete cache[ id ].data; + + // Don't destroy the parent cache unless the internal data object + // had been the only thing left in it + if ( !isEmptyDataObject(cache[ id ]) ) { + return; + } + } + + // Browsers that fail expando deletion also refuse to delete expandos on + // the window, but it will allow it on all other JS objects; other browsers + // don't care + // Ensure that `cache` is not a window object #10080 + if ( jQuery.support.deleteExpando || !cache.setInterval ) { + delete cache[ id ]; + } else { + cache[ id ] = null; + } + + // We destroyed the cache and need to eliminate the expando on the node to avoid + // false lookups in the cache for entries that no longer exist + if ( isNode ) { + // IE does not allow us to delete expando properties from nodes, + // nor does it have a removeAttribute function on Document nodes; + // we must handle all of these cases + if ( jQuery.support.deleteExpando ) { + delete elem[ internalKey ]; + } else if ( elem.removeAttribute ) { + elem.removeAttribute( internalKey ); + } else { + elem[ internalKey ] = null; + } + } + }, + + // For internal use only. + _data: function( elem, name, data ) { + return jQuery.data( elem, name, data, true ); + }, + + // A method for determining if a DOM node can handle the data expando + acceptData: function( elem ) { + if ( elem.nodeName ) { + var match = jQuery.noData[ elem.nodeName.toLowerCase() ]; + + if ( match ) { + return !(match === true || elem.getAttribute("classid") !== match); + } + } + + return true; + } +}); + +jQuery.fn.extend({ + data: function( key, value ) { + var parts, part, attr, name, l, + elem = this[0], + i = 0, + data = null; + + // Gets all values + if ( key === undefined ) { + if ( this.length ) { + data = jQuery.data( elem ); + + if ( elem.nodeType === 1 && !jQuery._data( elem, "parsedAttrs" ) ) { + attr = elem.attributes; + for ( l = attr.length; i < l; i++ ) { + name = attr[i].name; + + if ( name.indexOf( "data-" ) === 0 ) { + name = jQuery.camelCase( name.substring(5) ); + + dataAttr( elem, name, data[ name ] ); + } + } + jQuery._data( elem, "parsedAttrs", true ); + } + } + + return data; + } + + // Sets multiple values + if ( typeof key === "object" ) { + return this.each(function() { + jQuery.data( this, key ); + }); + } + + parts = key.split( ".", 2 ); + parts[1] = parts[1] ? "." + parts[1] : ""; + part = parts[1] + "!"; + + return jQuery.access( this, function( value ) { + + if ( value === undefined ) { + data = this.triggerHandler( "getData" + part, [ parts[0] ] ); + + // Try to fetch any internally stored data first + if ( data === undefined && elem ) { + data = jQuery.data( elem, key ); + data = dataAttr( elem, key, data ); + } + + return data === undefined && parts[1] ? + this.data( parts[0] ) : + data; + } + + parts[1] = value; + this.each(function() { + var self = jQuery( this ); + + self.triggerHandler( "setData" + part, parts ); + jQuery.data( this, key, value ); + self.triggerHandler( "changeData" + part, parts ); + }); + }, null, value, arguments.length > 1, null, false ); + }, + + removeData: function( key ) { + return this.each(function() { + jQuery.removeData( this, key ); + }); + } +}); + +function dataAttr( elem, key, data ) { + // If nothing was found internally, try to fetch any + // data from the HTML5 data-* attribute + if ( data === undefined && elem.nodeType === 1 ) { + + var name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase(); + + data = elem.getAttribute( name ); + + if ( typeof data === "string" ) { + try { + data = data === "true" ? true : + data === "false" ? false : + data === "null" ? null : + jQuery.isNumeric( data ) ? +data : + rbrace.test( data ) ? jQuery.parseJSON( data ) : + data; + } catch( e ) {} + + // Make sure we set the data so it isn't changed later + jQuery.data( elem, key, data ); + + } else { + data = undefined; + } + } + + return data; +} + +// checks a cache object for emptiness +function isEmptyDataObject( obj ) { + for ( var name in obj ) { + + // if the public data object is empty, the private is still empty + if ( name === "data" && jQuery.isEmptyObject( obj[name] ) ) { + continue; + } + if ( name !== "toJSON" ) { + return false; + } + } + + return true; +} + + + + +function handleQueueMarkDefer( elem, type, src ) { + var deferDataKey = type + "defer", + queueDataKey = type + "queue", + markDataKey = type + "mark", + defer = jQuery._data( elem, deferDataKey ); + if ( defer && + ( src === "queue" || !jQuery._data(elem, queueDataKey) ) && + ( src === "mark" || !jQuery._data(elem, markDataKey) ) ) { + // Give room for hard-coded callbacks to fire first + // and eventually mark/queue something else on the element + setTimeout( function() { + if ( !jQuery._data( elem, queueDataKey ) && + !jQuery._data( elem, markDataKey ) ) { + jQuery.removeData( elem, deferDataKey, true ); + defer.fire(); + } + }, 0 ); + } +} + +jQuery.extend({ + + _mark: function( elem, type ) { + if ( elem ) { + type = ( type || "fx" ) + "mark"; + jQuery._data( elem, type, (jQuery._data( elem, type ) || 0) + 1 ); + } + }, + + _unmark: function( force, elem, type ) { + if ( force !== true ) { + type = elem; + elem = force; + force = false; + } + if ( elem ) { + type = type || "fx"; + var key = type + "mark", + count = force ? 0 : ( (jQuery._data( elem, key ) || 1) - 1 ); + if ( count ) { + jQuery._data( elem, key, count ); + } else { + jQuery.removeData( elem, key, true ); + handleQueueMarkDefer( elem, type, "mark" ); + } + } + }, + + queue: function( elem, type, data ) { + var q; + if ( elem ) { + type = ( type || "fx" ) + "queue"; + q = jQuery._data( elem, type ); + + // Speed up dequeue by getting out quickly if this is just a lookup + if ( data ) { + if ( !q || jQuery.isArray(data) ) { + q = jQuery._data( elem, type, jQuery.makeArray(data) ); + } else { + q.push( data ); + } + } + return q || []; + } + }, + + dequeue: function( elem, type ) { + type = type || "fx"; + + var queue = jQuery.queue( elem, type ), + fn = queue.shift(), + hooks = {}; + + // If the fx queue is dequeued, always remove the progress sentinel + if ( fn === "inprogress" ) { + fn = queue.shift(); + } + + if ( fn ) { + // Add a progress sentinel to prevent the fx queue from being + // automatically dequeued + if ( type === "fx" ) { + queue.unshift( "inprogress" ); + } + + jQuery._data( elem, type + ".run", hooks ); + fn.call( elem, function() { + jQuery.dequeue( elem, type ); + }, hooks ); + } + + if ( !queue.length ) { + jQuery.removeData( elem, type + "queue " + type + ".run", true ); + handleQueueMarkDefer( elem, type, "queue" ); + } + } +}); + +jQuery.fn.extend({ + queue: function( type, data ) { + var setter = 2; + + if ( typeof type !== "string" ) { + data = type; + type = "fx"; + setter--; + } + + if ( arguments.length < setter ) { + return jQuery.queue( this[0], type ); + } + + return data === undefined ? + this : + this.each(function() { + var queue = jQuery.queue( this, type, data ); + + if ( type === "fx" && queue[0] !== "inprogress" ) { + jQuery.dequeue( this, type ); + } + }); + }, + dequeue: function( type ) { + return this.each(function() { + jQuery.dequeue( this, type ); + }); + }, + // Based off of the plugin by Clint Helfers, with permission. + // http://blindsignals.com/index.php/2009/07/jquery-delay/ + delay: function( time, type ) { + time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time; + type = type || "fx"; + + return this.queue( type, function( next, hooks ) { + var timeout = setTimeout( next, time ); + hooks.stop = function() { + clearTimeout( timeout ); + }; + }); + }, + clearQueue: function( type ) { + return this.queue( type || "fx", [] ); + }, + // Get a promise resolved when queues of a certain type + // are emptied (fx is the type by default) + promise: function( type, object ) { + if ( typeof type !== "string" ) { + object = type; + type = undefined; + } + type = type || "fx"; + var defer = jQuery.Deferred(), + elements = this, + i = elements.length, + count = 1, + deferDataKey = type + "defer", + queueDataKey = type + "queue", + markDataKey = type + "mark", + tmp; + function resolve() { + if ( !( --count ) ) { + defer.resolveWith( elements, [ elements ] ); + } + } + while( i-- ) { + if (( tmp = jQuery.data( elements[ i ], deferDataKey, undefined, true ) || + ( jQuery.data( elements[ i ], queueDataKey, undefined, true ) || + jQuery.data( elements[ i ], markDataKey, undefined, true ) ) && + jQuery.data( elements[ i ], deferDataKey, jQuery.Callbacks( "once memory" ), true ) )) { + count++; + tmp.add( resolve ); + } + } + resolve(); + return defer.promise( object ); + } +}); + + + + +var rclass = /[\n\t\r]/g, + rspace = /\s+/, + rreturn = /\r/g, + rtype = /^(?:button|input)$/i, + rfocusable = /^(?:button|input|object|select|textarea)$/i, + rclickable = /^a(?:rea)?$/i, + rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i, + getSetAttribute = jQuery.support.getSetAttribute, + nodeHook, boolHook, fixSpecified; + +jQuery.fn.extend({ + attr: function( name, value ) { + return jQuery.access( this, jQuery.attr, name, value, arguments.length > 1 ); + }, + + removeAttr: function( name ) { + return this.each(function() { + jQuery.removeAttr( this, name ); + }); + }, + + prop: function( name, value ) { + return jQuery.access( this, jQuery.prop, name, value, arguments.length > 1 ); + }, + + removeProp: function( name ) { + name = jQuery.propFix[ name ] || name; + return this.each(function() { + // try/catch handles cases where IE balks (such as removing a property on window) + try { + this[ name ] = undefined; + delete this[ name ]; + } catch( e ) {} + }); + }, + + addClass: function( value ) { + var classNames, i, l, elem, + setClass, c, cl; + + if ( jQuery.isFunction( value ) ) { + return this.each(function( j ) { + jQuery( this ).addClass( value.call(this, j, this.className) ); + }); + } + + if ( value && typeof value === "string" ) { + classNames = value.split( rspace ); + + for ( i = 0, l = this.length; i < l; i++ ) { + elem = this[ i ]; + + if ( elem.nodeType === 1 ) { + if ( !elem.className && classNames.length === 1 ) { + elem.className = value; + + } else { + setClass = " " + elem.className + " "; + + for ( c = 0, cl = classNames.length; c < cl; c++ ) { + if ( !~setClass.indexOf( " " + classNames[ c ] + " " ) ) { + setClass += classNames[ c ] + " "; + } + } + elem.className = jQuery.trim( setClass ); + } + } + } + } + + return this; + }, + + removeClass: function( value ) { + var classNames, i, l, elem, className, c, cl; + + if ( jQuery.isFunction( value ) ) { + return this.each(function( j ) { + jQuery( this ).removeClass( value.call(this, j, this.className) ); + }); + } + + if ( (value && typeof value === "string") || value === undefined ) { + classNames = ( value || "" ).split( rspace ); + + for ( i = 0, l = this.length; i < l; i++ ) { + elem = this[ i ]; + + if ( elem.nodeType === 1 && elem.className ) { + if ( value ) { + className = (" " + elem.className + " ").replace( rclass, " " ); + for ( c = 0, cl = classNames.length; c < cl; c++ ) { + className = className.replace(" " + classNames[ c ] + " ", " "); + } + elem.className = jQuery.trim( className ); + + } else { + elem.className = ""; + } + } + } + } + + return this; + }, + + toggleClass: function( value, stateVal ) { + var type = typeof value, + isBool = typeof stateVal === "boolean"; + + if ( jQuery.isFunction( value ) ) { + return this.each(function( i ) { + jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal ); + }); + } + + return this.each(function() { + if ( type === "string" ) { + // toggle individual class names + var className, + i = 0, + self = jQuery( this ), + state = stateVal, + classNames = value.split( rspace ); + + while ( (className = classNames[ i++ ]) ) { + // check each className given, space seperated list + state = isBool ? state : !self.hasClass( className ); + self[ state ? "addClass" : "removeClass" ]( className ); + } + + } else if ( type === "undefined" || type === "boolean" ) { + if ( this.className ) { + // store className if set + jQuery._data( this, "__className__", this.className ); + } + + // toggle whole className + this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || ""; + } + }); + }, + + hasClass: function( selector ) { + var className = " " + selector + " ", + i = 0, + l = this.length; + for ( ; i < l; i++ ) { + if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) { + return true; + } + } + + return false; + }, + + val: function( value ) { + var hooks, ret, isFunction, + elem = this[0]; + + if ( !arguments.length ) { + if ( elem ) { + hooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ]; + + if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) { + return ret; + } + + ret = elem.value; + + return typeof ret === "string" ? + // handle most common string cases + ret.replace(rreturn, "") : + // handle cases where value is null/undef or number + ret == null ? "" : ret; + } + + return; + } + + isFunction = jQuery.isFunction( value ); + + return this.each(function( i ) { + var self = jQuery(this), val; + + if ( this.nodeType !== 1 ) { + return; + } + + if ( isFunction ) { + val = value.call( this, i, self.val() ); + } else { + val = value; + } + + // Treat null/undefined as ""; convert numbers to string + if ( val == null ) { + val = ""; + } else if ( typeof val === "number" ) { + val += ""; + } else if ( jQuery.isArray( val ) ) { + val = jQuery.map(val, function ( value ) { + return value == null ? "" : value + ""; + }); + } + + hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ]; + + // If set returns undefined, fall back to normal setting + if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) { + this.value = val; + } + }); + } +}); + +jQuery.extend({ + valHooks: { + option: { + get: function( elem ) { + // attributes.value is undefined in Blackberry 4.7 but + // uses .value. See #6932 + var val = elem.attributes.value; + return !val || val.specified ? elem.value : elem.text; + } + }, + select: { + get: function( elem ) { + var value, i, max, option, + index = elem.selectedIndex, + values = [], + options = elem.options, + one = elem.type === "select-one"; + + // Nothing was selected + if ( index < 0 ) { + return null; + } + + // Loop through all the selected options + i = one ? index : 0; + max = one ? index + 1 : options.length; + for ( ; i < max; i++ ) { + option = options[ i ]; + + // Don't return options that are disabled or in a disabled optgroup + if ( option.selected && (jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null) && + (!option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" )) ) { + + // Get the specific value for the option + value = jQuery( option ).val(); + + // We don't need an array for one selects + if ( one ) { + return value; + } + + // Multi-Selects return an array + values.push( value ); + } + } + + // Fixes Bug #2551 -- select.val() broken in IE after form.reset() + if ( one && !values.length && options.length ) { + return jQuery( options[ index ] ).val(); + } + + return values; + }, + + set: function( elem, value ) { + var values = jQuery.makeArray( value ); + + jQuery(elem).find("option").each(function() { + this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0; + }); + + if ( !values.length ) { + elem.selectedIndex = -1; + } + return values; + } + } + }, + + attrFn: { + val: true, + css: true, + html: true, + text: true, + data: true, + width: true, + height: true, + offset: true + }, + + attr: function( elem, name, value, pass ) { + var ret, hooks, notxml, + nType = elem.nodeType; + + // don't get/set attributes on text, comment and attribute nodes + if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + if ( pass && name in jQuery.attrFn ) { + return jQuery( elem )[ name ]( value ); + } + + // Fallback to prop when attributes are not supported + if ( typeof elem.getAttribute === "undefined" ) { + return jQuery.prop( elem, name, value ); + } + + notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); + + // All attributes are lowercase + // Grab necessary hook if one is defined + if ( notxml ) { + name = name.toLowerCase(); + hooks = jQuery.attrHooks[ name ] || ( rboolean.test( name ) ? boolHook : nodeHook ); + } + + if ( value !== undefined ) { + + if ( value === null ) { + jQuery.removeAttr( elem, name ); + return; + + } else if ( hooks && "set" in hooks && notxml && (ret = hooks.set( elem, value, name )) !== undefined ) { + return ret; + + } else { + elem.setAttribute( name, "" + value ); + return value; + } + + } else if ( hooks && "get" in hooks && notxml && (ret = hooks.get( elem, name )) !== null ) { + return ret; + + } else { + + ret = elem.getAttribute( name ); + + // Non-existent attributes return null, we normalize to undefined + return ret === null ? + undefined : + ret; + } + }, + + removeAttr: function( elem, value ) { + var propName, attrNames, name, l, isBool, + i = 0; + + if ( value && elem.nodeType === 1 ) { + attrNames = value.toLowerCase().split( rspace ); + l = attrNames.length; + + for ( ; i < l; i++ ) { + name = attrNames[ i ]; + + if ( name ) { + propName = jQuery.propFix[ name ] || name; + isBool = rboolean.test( name ); + + // See #9699 for explanation of this approach (setting first, then removal) + // Do not do this for boolean attributes (see #10870) + if ( !isBool ) { + jQuery.attr( elem, name, "" ); + } + elem.removeAttribute( getSetAttribute ? name : propName ); + + // Set corresponding property to false for boolean attributes + if ( isBool && propName in elem ) { + elem[ propName ] = false; + } + } + } + } + }, + + attrHooks: { + type: { + set: function( elem, value ) { + // We can't allow the type property to be changed (since it causes problems in IE) + if ( rtype.test( elem.nodeName ) && elem.parentNode ) { + jQuery.error( "type property can't be changed" ); + } else if ( !jQuery.support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) { + // Setting the type on a radio button after the value resets the value in IE6-9 + // Reset value to it's default in case type is set after value + // This is for element creation + var val = elem.value; + elem.setAttribute( "type", value ); + if ( val ) { + elem.value = val; + } + return value; + } + } + }, + // Use the value property for back compat + // Use the nodeHook for button elements in IE6/7 (#1954) + value: { + get: function( elem, name ) { + if ( nodeHook && jQuery.nodeName( elem, "button" ) ) { + return nodeHook.get( elem, name ); + } + return name in elem ? + elem.value : + null; + }, + set: function( elem, value, name ) { + if ( nodeHook && jQuery.nodeName( elem, "button" ) ) { + return nodeHook.set( elem, value, name ); + } + // Does not return so that setAttribute is also used + elem.value = value; + } + } + }, + + propFix: { + tabindex: "tabIndex", + readonly: "readOnly", + "for": "htmlFor", + "class": "className", + maxlength: "maxLength", + cellspacing: "cellSpacing", + cellpadding: "cellPadding", + rowspan: "rowSpan", + colspan: "colSpan", + usemap: "useMap", + frameborder: "frameBorder", + contenteditable: "contentEditable" + }, + + prop: function( elem, name, value ) { + var ret, hooks, notxml, + nType = elem.nodeType; + + // don't get/set properties on text, comment and attribute nodes + if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); + + if ( notxml ) { + // Fix name and attach hooks + name = jQuery.propFix[ name ] || name; + hooks = jQuery.propHooks[ name ]; + } + + if ( value !== undefined ) { + if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) { + return ret; + + } else { + return ( elem[ name ] = value ); + } + + } else { + if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) { + return ret; + + } else { + return elem[ name ]; + } + } + }, + + propHooks: { + tabIndex: { + get: function( elem ) { + // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set + // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ + var attributeNode = elem.getAttributeNode("tabindex"); + + return attributeNode && attributeNode.specified ? + parseInt( attributeNode.value, 10 ) : + rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ? + 0 : + undefined; + } + } + } +}); + +// Add the tabIndex propHook to attrHooks for back-compat (different case is intentional) +jQuery.attrHooks.tabindex = jQuery.propHooks.tabIndex; + +// Hook for boolean attributes +boolHook = { + get: function( elem, name ) { + // Align boolean attributes with corresponding properties + // Fall back to attribute presence where some booleans are not supported + var attrNode, + property = jQuery.prop( elem, name ); + return property === true || typeof property !== "boolean" && ( attrNode = elem.getAttributeNode(name) ) && attrNode.nodeValue !== false ? + name.toLowerCase() : + undefined; + }, + set: function( elem, value, name ) { + var propName; + if ( value === false ) { + // Remove boolean attributes when set to false + jQuery.removeAttr( elem, name ); + } else { + // value is true since we know at this point it's type boolean and not false + // Set boolean attributes to the same name and set the DOM property + propName = jQuery.propFix[ name ] || name; + if ( propName in elem ) { + // Only set the IDL specifically if it already exists on the element + elem[ propName ] = true; + } + + elem.setAttribute( name, name.toLowerCase() ); + } + return name; + } +}; + +// IE6/7 do not support getting/setting some attributes with get/setAttribute +if ( !getSetAttribute ) { + + fixSpecified = { + name: true, + id: true, + coords: true + }; + + // Use this for any attribute in IE6/7 + // This fixes almost every IE6/7 issue + nodeHook = jQuery.valHooks.button = { + get: function( elem, name ) { + var ret; + ret = elem.getAttributeNode( name ); + return ret && ( fixSpecified[ name ] ? ret.nodeValue !== "" : ret.specified ) ? + ret.nodeValue : + undefined; + }, + set: function( elem, value, name ) { + // Set the existing or create a new attribute node + var ret = elem.getAttributeNode( name ); + if ( !ret ) { + ret = document.createAttribute( name ); + elem.setAttributeNode( ret ); + } + return ( ret.nodeValue = value + "" ); + } + }; + + // Apply the nodeHook to tabindex + jQuery.attrHooks.tabindex.set = nodeHook.set; + + // Set width and height to auto instead of 0 on empty string( Bug #8150 ) + // This is for removals + jQuery.each([ "width", "height" ], function( i, name ) { + jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], { + set: function( elem, value ) { + if ( value === "" ) { + elem.setAttribute( name, "auto" ); + return value; + } + } + }); + }); + + // Set contenteditable to false on removals(#10429) + // Setting to empty string throws an error as an invalid value + jQuery.attrHooks.contenteditable = { + get: nodeHook.get, + set: function( elem, value, name ) { + if ( value === "" ) { + value = "false"; + } + nodeHook.set( elem, value, name ); + } + }; +} + + +// Some attributes require a special call on IE +if ( !jQuery.support.hrefNormalized ) { + jQuery.each([ "href", "src", "width", "height" ], function( i, name ) { + jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], { + get: function( elem ) { + var ret = elem.getAttribute( name, 2 ); + return ret === null ? undefined : ret; + } + }); + }); +} + +if ( !jQuery.support.style ) { + jQuery.attrHooks.style = { + get: function( elem ) { + // Return undefined in the case of empty string + // Normalize to lowercase since IE uppercases css property names + return elem.style.cssText.toLowerCase() || undefined; + }, + set: function( elem, value ) { + return ( elem.style.cssText = "" + value ); + } + }; +} + +// Safari mis-reports the default selected property of an option +// Accessing the parent's selectedIndex property fixes it +if ( !jQuery.support.optSelected ) { + jQuery.propHooks.selected = jQuery.extend( jQuery.propHooks.selected, { + get: function( elem ) { + var parent = elem.parentNode; + + if ( parent ) { + parent.selectedIndex; + + // Make sure that it also works with optgroups, see #5701 + if ( parent.parentNode ) { + parent.parentNode.selectedIndex; + } + } + return null; + } + }); +} + +// IE6/7 call enctype encoding +if ( !jQuery.support.enctype ) { + jQuery.propFix.enctype = "encoding"; +} + +// Radios and checkboxes getter/setter +if ( !jQuery.support.checkOn ) { + jQuery.each([ "radio", "checkbox" ], function() { + jQuery.valHooks[ this ] = { + get: function( elem ) { + // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified + return elem.getAttribute("value") === null ? "on" : elem.value; + } + }; + }); +} +jQuery.each([ "radio", "checkbox" ], function() { + jQuery.valHooks[ this ] = jQuery.extend( jQuery.valHooks[ this ], { + set: function( elem, value ) { + if ( jQuery.isArray( value ) ) { + return ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 ); + } + } + }); +}); + + + + +var rformElems = /^(?:textarea|input|select)$/i, + rtypenamespace = /^([^\.]*)?(?:\.(.+))?$/, + rhoverHack = /(?:^|\s)hover(\.\S+)?\b/, + rkeyEvent = /^key/, + rmouseEvent = /^(?:mouse|contextmenu)|click/, + rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, + rquickIs = /^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/, + quickParse = function( selector ) { + var quick = rquickIs.exec( selector ); + if ( quick ) { + // 0 1 2 3 + // [ _, tag, id, class ] + quick[1] = ( quick[1] || "" ).toLowerCase(); + quick[3] = quick[3] && new RegExp( "(?:^|\\s)" + quick[3] + "(?:\\s|$)" ); + } + return quick; + }, + quickIs = function( elem, m ) { + var attrs = elem.attributes || {}; + return ( + (!m[1] || elem.nodeName.toLowerCase() === m[1]) && + (!m[2] || (attrs.id || {}).value === m[2]) && + (!m[3] || m[3].test( (attrs[ "class" ] || {}).value )) + ); + }, + hoverHack = function( events ) { + return jQuery.event.special.hover ? events : events.replace( rhoverHack, "mouseenter$1 mouseleave$1" ); + }; + +/* + * Helper functions for managing events -- not part of the public interface. + * Props to Dean Edwards' addEvent library for many of the ideas. + */ +jQuery.event = { + + add: function( elem, types, handler, data, selector ) { + + var elemData, eventHandle, events, + t, tns, type, namespaces, handleObj, + handleObjIn, quick, handlers, special; + + // Don't attach events to noData or text/comment nodes (allow plain objects tho) + if ( elem.nodeType === 3 || elem.nodeType === 8 || !types || !handler || !(elemData = jQuery._data( elem )) ) { + return; + } + + // Caller can pass in an object of custom data in lieu of the handler + if ( handler.handler ) { + handleObjIn = handler; + handler = handleObjIn.handler; + selector = handleObjIn.selector; + } + + // Make sure that the handler has a unique ID, used to find/remove it later + if ( !handler.guid ) { + handler.guid = jQuery.guid++; + } + + // Init the element's event structure and main handler, if this is the first + events = elemData.events; + if ( !events ) { + elemData.events = events = {}; + } + eventHandle = elemData.handle; + if ( !eventHandle ) { + elemData.handle = eventHandle = function( e ) { + // Discard the second event of a jQuery.event.trigger() and + // when an event is called after a page has unloaded + return typeof jQuery !== "undefined" && (!e || jQuery.event.triggered !== e.type) ? + jQuery.event.dispatch.apply( eventHandle.elem, arguments ) : + undefined; + }; + // Add elem as a property of the handle fn to prevent a memory leak with IE non-native events + eventHandle.elem = elem; + } + + // Handle multiple events separated by a space + // jQuery(...).bind("mouseover mouseout", fn); + types = jQuery.trim( hoverHack(types) ).split( " " ); + for ( t = 0; t < types.length; t++ ) { + + tns = rtypenamespace.exec( types[t] ) || []; + type = tns[1]; + namespaces = ( tns[2] || "" ).split( "." ).sort(); + + // If event changes its type, use the special event handlers for the changed type + special = jQuery.event.special[ type ] || {}; + + // If selector defined, determine special event api type, otherwise given type + type = ( selector ? special.delegateType : special.bindType ) || type; + + // Update special based on newly reset type + special = jQuery.event.special[ type ] || {}; + + // handleObj is passed to all event handlers + handleObj = jQuery.extend({ + type: type, + origType: tns[1], + data: data, + handler: handler, + guid: handler.guid, + selector: selector, + quick: selector && quickParse( selector ), + namespace: namespaces.join(".") + }, handleObjIn ); + + // Init the event handler queue if we're the first + handlers = events[ type ]; + if ( !handlers ) { + handlers = events[ type ] = []; + handlers.delegateCount = 0; + + // Only use addEventListener/attachEvent if the special events handler returns false + if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) { + // Bind the global event handler to the element + if ( elem.addEventListener ) { + elem.addEventListener( type, eventHandle, false ); + + } else if ( elem.attachEvent ) { + elem.attachEvent( "on" + type, eventHandle ); + } + } + } + + if ( special.add ) { + special.add.call( elem, handleObj ); + + if ( !handleObj.handler.guid ) { + handleObj.handler.guid = handler.guid; + } + } + + // Add to the element's handler list, delegates in front + if ( selector ) { + handlers.splice( handlers.delegateCount++, 0, handleObj ); + } else { + handlers.push( handleObj ); + } + + // Keep track of which events have ever been used, for event optimization + jQuery.event.global[ type ] = true; + } + + // Nullify elem to prevent memory leaks in IE + elem = null; + }, + + global: {}, + + // Detach an event or set of events from an element + remove: function( elem, types, handler, selector, mappedTypes ) { + + var elemData = jQuery.hasData( elem ) && jQuery._data( elem ), + t, tns, type, origType, namespaces, origCount, + j, events, special, handle, eventType, handleObj; + + if ( !elemData || !(events = elemData.events) ) { + return; + } + + // Once for each type.namespace in types; type may be omitted + types = jQuery.trim( hoverHack( types || "" ) ).split(" "); + for ( t = 0; t < types.length; t++ ) { + tns = rtypenamespace.exec( types[t] ) || []; + type = origType = tns[1]; + namespaces = tns[2]; + + // Unbind all events (on this namespace, if provided) for the element + if ( !type ) { + for ( type in events ) { + jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); + } + continue; + } + + special = jQuery.event.special[ type ] || {}; + type = ( selector? special.delegateType : special.bindType ) || type; + eventType = events[ type ] || []; + origCount = eventType.length; + namespaces = namespaces ? new RegExp("(^|\\.)" + namespaces.split(".").sort().join("\\.(?:.*\\.)?") + "(\\.|$)") : null; + + // Remove matching events + for ( j = 0; j < eventType.length; j++ ) { + handleObj = eventType[ j ]; + + if ( ( mappedTypes || origType === handleObj.origType ) && + ( !handler || handler.guid === handleObj.guid ) && + ( !namespaces || namespaces.test( handleObj.namespace ) ) && + ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) { + eventType.splice( j--, 1 ); + + if ( handleObj.selector ) { + eventType.delegateCount--; + } + if ( special.remove ) { + special.remove.call( elem, handleObj ); + } + } + } + + // Remove generic event handler if we removed something and no more handlers exist + // (avoids potential for endless recursion during removal of special event handlers) + if ( eventType.length === 0 && origCount !== eventType.length ) { + if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) { + jQuery.removeEvent( elem, type, elemData.handle ); + } + + delete events[ type ]; + } + } + + // Remove the expando if it's no longer used + if ( jQuery.isEmptyObject( events ) ) { + handle = elemData.handle; + if ( handle ) { + handle.elem = null; + } + + // removeData also checks for emptiness and clears the expando if empty + // so use it instead of delete + jQuery.removeData( elem, [ "events", "handle" ], true ); + } + }, + + // Events that are safe to short-circuit if no handlers are attached. + // Native DOM events should not be added, they may have inline handlers. + customEvent: { + "getData": true, + "setData": true, + "changeData": true + }, + + trigger: function( event, data, elem, onlyHandlers ) { + // Don't do events on text and comment nodes + if ( elem && (elem.nodeType === 3 || elem.nodeType === 8) ) { + return; + } + + // Event object or event type + var type = event.type || event, + namespaces = [], + cache, exclusive, i, cur, old, ontype, special, handle, eventPath, bubbleType; + + // focus/blur morphs to focusin/out; ensure we're not firing them right now + if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { + return; + } + + if ( type.indexOf( "!" ) >= 0 ) { + // Exclusive events trigger only for the exact event (no namespaces) + type = type.slice(0, -1); + exclusive = true; + } + + if ( type.indexOf( "." ) >= 0 ) { + // Namespaced trigger; create a regexp to match event type in handle() + namespaces = type.split("."); + type = namespaces.shift(); + namespaces.sort(); + } + + if ( (!elem || jQuery.event.customEvent[ type ]) && !jQuery.event.global[ type ] ) { + // No jQuery handlers for this event type, and it can't have inline handlers + return; + } + + // Caller can pass in an Event, Object, or just an event type string + event = typeof event === "object" ? + // jQuery.Event object + event[ jQuery.expando ] ? event : + // Object literal + new jQuery.Event( type, event ) : + // Just the event type (string) + new jQuery.Event( type ); + + event.type = type; + event.isTrigger = true; + event.exclusive = exclusive; + event.namespace = namespaces.join( "." ); + event.namespace_re = event.namespace? new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.)?") + "(\\.|$)") : null; + ontype = type.indexOf( ":" ) < 0 ? "on" + type : ""; + + // Handle a global trigger + if ( !elem ) { + + // TODO: Stop taunting the data cache; remove global events and always attach to document + cache = jQuery.cache; + for ( i in cache ) { + if ( cache[ i ].events && cache[ i ].events[ type ] ) { + jQuery.event.trigger( event, data, cache[ i ].handle.elem, true ); + } + } + return; + } + + // Clean up the event in case it is being reused + event.result = undefined; + if ( !event.target ) { + event.target = elem; + } + + // Clone any incoming data and prepend the event, creating the handler arg list + data = data != null ? jQuery.makeArray( data ) : []; + data.unshift( event ); + + // Allow special events to draw outside the lines + special = jQuery.event.special[ type ] || {}; + if ( special.trigger && special.trigger.apply( elem, data ) === false ) { + return; + } + + // Determine event propagation path in advance, per W3C events spec (#9951) + // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) + eventPath = [[ elem, special.bindType || type ]]; + if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) { + + bubbleType = special.delegateType || type; + cur = rfocusMorph.test( bubbleType + type ) ? elem : elem.parentNode; + old = null; + for ( ; cur; cur = cur.parentNode ) { + eventPath.push([ cur, bubbleType ]); + old = cur; + } + + // Only add window if we got to document (e.g., not plain obj or detached DOM) + if ( old && old === elem.ownerDocument ) { + eventPath.push([ old.defaultView || old.parentWindow || window, bubbleType ]); + } + } + + // Fire handlers on the event path + for ( i = 0; i < eventPath.length && !event.isPropagationStopped(); i++ ) { + + cur = eventPath[i][0]; + event.type = eventPath[i][1]; + + handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] && jQuery._data( cur, "handle" ); + if ( handle ) { + handle.apply( cur, data ); + } + // Note that this is a bare JS function and not a jQuery handler + handle = ontype && cur[ ontype ]; + if ( handle && jQuery.acceptData( cur ) && handle.apply( cur, data ) === false ) { + event.preventDefault(); + } + } + event.type = type; + + // If nobody prevented the default action, do it now + if ( !onlyHandlers && !event.isDefaultPrevented() ) { + + if ( (!special._default || special._default.apply( elem.ownerDocument, data ) === false) && + !(type === "click" && jQuery.nodeName( elem, "a" )) && jQuery.acceptData( elem ) ) { + + // Call a native DOM method on the target with the same name name as the event. + // Can't use an .isFunction() check here because IE6/7 fails that test. + // Don't do default actions on window, that's where global variables be (#6170) + // IE<9 dies on focus/blur to hidden element (#1486) + if ( ontype && elem[ type ] && ((type !== "focus" && type !== "blur") || event.target.offsetWidth !== 0) && !jQuery.isWindow( elem ) ) { + + // Don't re-trigger an onFOO event when we call its FOO() method + old = elem[ ontype ]; + + if ( old ) { + elem[ ontype ] = null; + } + + // Prevent re-triggering of the same event, since we already bubbled it above + jQuery.event.triggered = type; + elem[ type ](); + jQuery.event.triggered = undefined; + + if ( old ) { + elem[ ontype ] = old; + } + } + } + } + + return event.result; + }, + + dispatch: function( event ) { + + // Make a writable jQuery.Event from the native event object + event = jQuery.event.fix( event || window.event ); + + var handlers = ( (jQuery._data( this, "events" ) || {} )[ event.type ] || []), + delegateCount = handlers.delegateCount, + args = [].slice.call( arguments, 0 ), + run_all = !event.exclusive && !event.namespace, + special = jQuery.event.special[ event.type ] || {}, + handlerQueue = [], + i, j, cur, jqcur, ret, selMatch, matched, matches, handleObj, sel, related; + + // Use the fix-ed jQuery.Event rather than the (read-only) native event + args[0] = event; + event.delegateTarget = this; + + // Call the preDispatch hook for the mapped type, and let it bail if desired + if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { + return; + } + + // Determine handlers that should run if there are delegated events + // Avoid non-left-click bubbling in Firefox (#3861) + if ( delegateCount && !(event.button && event.type === "click") ) { + + // Pregenerate a single jQuery object for reuse with .is() + jqcur = jQuery(this); + jqcur.context = this.ownerDocument || this; + + for ( cur = event.target; cur != this; cur = cur.parentNode || this ) { + + // Don't process events on disabled elements (#6911, #8165) + if ( cur.disabled !== true ) { + selMatch = {}; + matches = []; + jqcur[0] = cur; + for ( i = 0; i < delegateCount; i++ ) { + handleObj = handlers[ i ]; + sel = handleObj.selector; + + if ( selMatch[ sel ] === undefined ) { + selMatch[ sel ] = ( + handleObj.quick ? quickIs( cur, handleObj.quick ) : jqcur.is( sel ) + ); + } + if ( selMatch[ sel ] ) { + matches.push( handleObj ); + } + } + if ( matches.length ) { + handlerQueue.push({ elem: cur, matches: matches }); + } + } + } + } + + // Add the remaining (directly-bound) handlers + if ( handlers.length > delegateCount ) { + handlerQueue.push({ elem: this, matches: handlers.slice( delegateCount ) }); + } + + // Run delegates first; they may want to stop propagation beneath us + for ( i = 0; i < handlerQueue.length && !event.isPropagationStopped(); i++ ) { + matched = handlerQueue[ i ]; + event.currentTarget = matched.elem; + + for ( j = 0; j < matched.matches.length && !event.isImmediatePropagationStopped(); j++ ) { + handleObj = matched.matches[ j ]; + + // Triggered event must either 1) be non-exclusive and have no namespace, or + // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace). + if ( run_all || (!event.namespace && !handleObj.namespace) || event.namespace_re && event.namespace_re.test( handleObj.namespace ) ) { + + event.data = handleObj.data; + event.handleObj = handleObj; + + ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler ) + .apply( matched.elem, args ); + + if ( ret !== undefined ) { + event.result = ret; + if ( ret === false ) { + event.preventDefault(); + event.stopPropagation(); + } + } + } + } + } + + // Call the postDispatch hook for the mapped type + if ( special.postDispatch ) { + special.postDispatch.call( this, event ); + } + + return event.result; + }, + + // Includes some event props shared by KeyEvent and MouseEvent + // *** attrChange attrName relatedNode srcElement are not normalized, non-W3C, deprecated, will be removed in 1.8 *** + props: "attrChange attrName relatedNode srcElement altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "), + + fixHooks: {}, + + keyHooks: { + props: "char charCode key keyCode".split(" "), + filter: function( event, original ) { + + // Add which for key events + if ( event.which == null ) { + event.which = original.charCode != null ? original.charCode : original.keyCode; + } + + return event; + } + }, + + mouseHooks: { + props: "button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "), + filter: function( event, original ) { + var eventDoc, doc, body, + button = original.button, + fromElement = original.fromElement; + + // Calculate pageX/Y if missing and clientX/Y available + if ( event.pageX == null && original.clientX != null ) { + eventDoc = event.target.ownerDocument || document; + doc = eventDoc.documentElement; + body = eventDoc.body; + + event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 ); + event.pageY = original.clientY + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - ( doc && doc.clientTop || body && body.clientTop || 0 ); + } + + // Add relatedTarget, if necessary + if ( !event.relatedTarget && fromElement ) { + event.relatedTarget = fromElement === event.target ? original.toElement : fromElement; + } + + // Add which for click: 1 === left; 2 === middle; 3 === right + // Note: button is not normalized, so don't use it + if ( !event.which && button !== undefined ) { + event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) ); + } + + return event; + } + }, + + fix: function( event ) { + if ( event[ jQuery.expando ] ) { + return event; + } + + // Create a writable copy of the event object and normalize some properties + var i, prop, + originalEvent = event, + fixHook = jQuery.event.fixHooks[ event.type ] || {}, + copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props; + + event = jQuery.Event( originalEvent ); + + for ( i = copy.length; i; ) { + prop = copy[ --i ]; + event[ prop ] = originalEvent[ prop ]; + } + + // Fix target property, if necessary (#1925, IE 6/7/8 & Safari2) + if ( !event.target ) { + event.target = originalEvent.srcElement || document; + } + + // Target should not be a text node (#504, Safari) + if ( event.target.nodeType === 3 ) { + event.target = event.target.parentNode; + } + + // For mouse/key events; add metaKey if it's not there (#3368, IE6/7/8) + if ( event.metaKey === undefined ) { + event.metaKey = event.ctrlKey; + } + + return fixHook.filter? fixHook.filter( event, originalEvent ) : event; + }, + + special: { + ready: { + // Make sure the ready event is setup + setup: jQuery.bindReady + }, + + load: { + // Prevent triggered image.load events from bubbling to window.load + noBubble: true + }, + + focus: { + delegateType: "focusin" + }, + blur: { + delegateType: "focusout" + }, + + beforeunload: { + setup: function( data, namespaces, eventHandle ) { + // We only want to do this special case on windows + if ( jQuery.isWindow( this ) ) { + this.onbeforeunload = eventHandle; + } + }, + + teardown: function( namespaces, eventHandle ) { + if ( this.onbeforeunload === eventHandle ) { + this.onbeforeunload = null; + } + } + } + }, + + simulate: function( type, elem, event, bubble ) { + // Piggyback on a donor event to simulate a different one. + // Fake originalEvent to avoid donor's stopPropagation, but if the + // simulated event prevents default then we do the same on the donor. + var e = jQuery.extend( + new jQuery.Event(), + event, + { type: type, + isSimulated: true, + originalEvent: {} + } + ); + if ( bubble ) { + jQuery.event.trigger( e, null, elem ); + } else { + jQuery.event.dispatch.call( elem, e ); + } + if ( e.isDefaultPrevented() ) { + event.preventDefault(); + } + } +}; + +// Some plugins are using, but it's undocumented/deprecated and will be removed. +// The 1.7 special event interface should provide all the hooks needed now. +jQuery.event.handle = jQuery.event.dispatch; + +jQuery.removeEvent = document.removeEventListener ? + function( elem, type, handle ) { + if ( elem.removeEventListener ) { + elem.removeEventListener( type, handle, false ); + } + } : + function( elem, type, handle ) { + if ( elem.detachEvent ) { + elem.detachEvent( "on" + type, handle ); + } + }; + +jQuery.Event = function( src, props ) { + // Allow instantiation without the 'new' keyword + if ( !(this instanceof jQuery.Event) ) { + return new jQuery.Event( src, props ); + } + + // Event object + if ( src && src.type ) { + this.originalEvent = src; + this.type = src.type; + + // Events bubbling up the document may have been marked as prevented + // by a handler lower down the tree; reflect the correct value. + this.isDefaultPrevented = ( src.defaultPrevented || src.returnValue === false || + src.getPreventDefault && src.getPreventDefault() ) ? returnTrue : returnFalse; + + // Event type + } else { + this.type = src; + } + + // Put explicitly provided properties onto the event object + if ( props ) { + jQuery.extend( this, props ); + } + + // Create a timestamp if incoming event doesn't have one + this.timeStamp = src && src.timeStamp || jQuery.now(); + + // Mark it as fixed + this[ jQuery.expando ] = true; +}; + +function returnFalse() { + return false; +} +function returnTrue() { + return true; +} + +// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding +// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html +jQuery.Event.prototype = { + preventDefault: function() { + this.isDefaultPrevented = returnTrue; + + var e = this.originalEvent; + if ( !e ) { + return; + } + + // if preventDefault exists run it on the original event + if ( e.preventDefault ) { + e.preventDefault(); + + // otherwise set the returnValue property of the original event to false (IE) + } else { + e.returnValue = false; + } + }, + stopPropagation: function() { + this.isPropagationStopped = returnTrue; + + var e = this.originalEvent; + if ( !e ) { + return; + } + // if stopPropagation exists run it on the original event + if ( e.stopPropagation ) { + e.stopPropagation(); + } + // otherwise set the cancelBubble property of the original event to true (IE) + e.cancelBubble = true; + }, + stopImmediatePropagation: function() { + this.isImmediatePropagationStopped = returnTrue; + this.stopPropagation(); + }, + isDefaultPrevented: returnFalse, + isPropagationStopped: returnFalse, + isImmediatePropagationStopped: returnFalse +}; + +// Create mouseenter/leave events using mouseover/out and event-time checks +jQuery.each({ + mouseenter: "mouseover", + mouseleave: "mouseout" +}, function( orig, fix ) { + jQuery.event.special[ orig ] = { + delegateType: fix, + bindType: fix, + + handle: function( event ) { + var target = this, + related = event.relatedTarget, + handleObj = event.handleObj, + selector = handleObj.selector, + ret; + + // For mousenter/leave call the handler if related is outside the target. + // NB: No relatedTarget if the mouse left/entered the browser window + if ( !related || (related !== target && !jQuery.contains( target, related )) ) { + event.type = handleObj.origType; + ret = handleObj.handler.apply( this, arguments ); + event.type = fix; + } + return ret; + } + }; +}); + +// IE submit delegation +if ( !jQuery.support.submitBubbles ) { + + jQuery.event.special.submit = { + setup: function() { + // Only need this for delegated form submit events + if ( jQuery.nodeName( this, "form" ) ) { + return false; + } + + // Lazy-add a submit handler when a descendant form may potentially be submitted + jQuery.event.add( this, "click._submit keypress._submit", function( e ) { + // Node name check avoids a VML-related crash in IE (#9807) + var elem = e.target, + form = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ? elem.form : undefined; + if ( form && !form._submit_attached ) { + jQuery.event.add( form, "submit._submit", function( event ) { + event._submit_bubble = true; + }); + form._submit_attached = true; + } + }); + // return undefined since we don't need an event listener + }, + + postDispatch: function( event ) { + // If form was submitted by the user, bubble the event up the tree + if ( event._submit_bubble ) { + delete event._submit_bubble; + if ( this.parentNode && !event.isTrigger ) { + jQuery.event.simulate( "submit", this.parentNode, event, true ); + } + } + }, + + teardown: function() { + // Only need this for delegated form submit events + if ( jQuery.nodeName( this, "form" ) ) { + return false; + } + + // Remove delegated handlers; cleanData eventually reaps submit handlers attached above + jQuery.event.remove( this, "._submit" ); + } + }; +} + +// IE change delegation and checkbox/radio fix +if ( !jQuery.support.changeBubbles ) { + + jQuery.event.special.change = { + + setup: function() { + + if ( rformElems.test( this.nodeName ) ) { + // IE doesn't fire change on a check/radio until blur; trigger it on click + // after a propertychange. Eat the blur-change in special.change.handle. + // This still fires onchange a second time for check/radio after blur. + if ( this.type === "checkbox" || this.type === "radio" ) { + jQuery.event.add( this, "propertychange._change", function( event ) { + if ( event.originalEvent.propertyName === "checked" ) { + this._just_changed = true; + } + }); + jQuery.event.add( this, "click._change", function( event ) { + if ( this._just_changed && !event.isTrigger ) { + this._just_changed = false; + jQuery.event.simulate( "change", this, event, true ); + } + }); + } + return false; + } + // Delegated event; lazy-add a change handler on descendant inputs + jQuery.event.add( this, "beforeactivate._change", function( e ) { + var elem = e.target; + + if ( rformElems.test( elem.nodeName ) && !elem._change_attached ) { + jQuery.event.add( elem, "change._change", function( event ) { + if ( this.parentNode && !event.isSimulated && !event.isTrigger ) { + jQuery.event.simulate( "change", this.parentNode, event, true ); + } + }); + elem._change_attached = true; + } + }); + }, + + handle: function( event ) { + var elem = event.target; + + // Swallow native change events from checkbox/radio, we already triggered them above + if ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== "radio" && elem.type !== "checkbox") ) { + return event.handleObj.handler.apply( this, arguments ); + } + }, + + teardown: function() { + jQuery.event.remove( this, "._change" ); + + return rformElems.test( this.nodeName ); + } + }; +} + +// Create "bubbling" focus and blur events +if ( !jQuery.support.focusinBubbles ) { + jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) { + + // Attach a single capturing handler while someone wants focusin/focusout + var attaches = 0, + handler = function( event ) { + jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true ); + }; + + jQuery.event.special[ fix ] = { + setup: function() { + if ( attaches++ === 0 ) { + document.addEventListener( orig, handler, true ); + } + }, + teardown: function() { + if ( --attaches === 0 ) { + document.removeEventListener( orig, handler, true ); + } + } + }; + }); +} + +jQuery.fn.extend({ + + on: function( types, selector, data, fn, /*INTERNAL*/ one ) { + var origFn, type; + + // Types can be a map of types/handlers + if ( typeof types === "object" ) { + // ( types-Object, selector, data ) + if ( typeof selector !== "string" ) { // && selector != null + // ( types-Object, data ) + data = data || selector; + selector = undefined; + } + for ( type in types ) { + this.on( type, selector, data, types[ type ], one ); + } + return this; + } + + if ( data == null && fn == null ) { + // ( types, fn ) + fn = selector; + data = selector = undefined; + } else if ( fn == null ) { + if ( typeof selector === "string" ) { + // ( types, selector, fn ) + fn = data; + data = undefined; + } else { + // ( types, data, fn ) + fn = data; + data = selector; + selector = undefined; + } + } + if ( fn === false ) { + fn = returnFalse; + } else if ( !fn ) { + return this; + } + + if ( one === 1 ) { + origFn = fn; + fn = function( event ) { + // Can use an empty set, since event contains the info + jQuery().off( event ); + return origFn.apply( this, arguments ); + }; + // Use same guid so caller can remove using origFn + fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); + } + return this.each( function() { + jQuery.event.add( this, types, fn, data, selector ); + }); + }, + one: function( types, selector, data, fn ) { + return this.on( types, selector, data, fn, 1 ); + }, + off: function( types, selector, fn ) { + if ( types && types.preventDefault && types.handleObj ) { + // ( event ) dispatched jQuery.Event + var handleObj = types.handleObj; + jQuery( types.delegateTarget ).off( + handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType, + handleObj.selector, + handleObj.handler + ); + return this; + } + if ( typeof types === "object" ) { + // ( types-object [, selector] ) + for ( var type in types ) { + this.off( type, selector, types[ type ] ); + } + return this; + } + if ( selector === false || typeof selector === "function" ) { + // ( types [, fn] ) + fn = selector; + selector = undefined; + } + if ( fn === false ) { + fn = returnFalse; + } + return this.each(function() { + jQuery.event.remove( this, types, fn, selector ); + }); + }, + + bind: function( types, data, fn ) { + return this.on( types, null, data, fn ); + }, + unbind: function( types, fn ) { + return this.off( types, null, fn ); + }, + + live: function( types, data, fn ) { + jQuery( this.context ).on( types, this.selector, data, fn ); + return this; + }, + die: function( types, fn ) { + jQuery( this.context ).off( types, this.selector || "**", fn ); + return this; + }, + + delegate: function( selector, types, data, fn ) { + return this.on( types, selector, data, fn ); + }, + undelegate: function( selector, types, fn ) { + // ( namespace ) or ( selector, types [, fn] ) + return arguments.length == 1? this.off( selector, "**" ) : this.off( types, selector, fn ); + }, + + trigger: function( type, data ) { + return this.each(function() { + jQuery.event.trigger( type, data, this ); + }); + }, + triggerHandler: function( type, data ) { + if ( this[0] ) { + return jQuery.event.trigger( type, data, this[0], true ); + } + }, + + toggle: function( fn ) { + // Save reference to arguments for access in closure + var args = arguments, + guid = fn.guid || jQuery.guid++, + i = 0, + toggler = function( event ) { + // Figure out which function to execute + var lastToggle = ( jQuery._data( this, "lastToggle" + fn.guid ) || 0 ) % i; + jQuery._data( this, "lastToggle" + fn.guid, lastToggle + 1 ); + + // Make sure that clicks stop + event.preventDefault(); + + // and execute the function + return args[ lastToggle ].apply( this, arguments ) || false; + }; + + // link all the functions, so any of them can unbind this click handler + toggler.guid = guid; + while ( i < args.length ) { + args[ i++ ].guid = guid; + } + + return this.click( toggler ); + }, + + hover: function( fnOver, fnOut ) { + return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver ); + } +}); + +jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " + + "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " + + "change select submit keydown keypress keyup error contextmenu").split(" "), function( i, name ) { + + // Handle event binding + jQuery.fn[ name ] = function( data, fn ) { + if ( fn == null ) { + fn = data; + data = null; + } + + return arguments.length > 0 ? + this.on( name, null, data, fn ) : + this.trigger( name ); + }; + + if ( jQuery.attrFn ) { + jQuery.attrFn[ name ] = true; + } + + if ( rkeyEvent.test( name ) ) { + jQuery.event.fixHooks[ name ] = jQuery.event.keyHooks; + } + + if ( rmouseEvent.test( name ) ) { + jQuery.event.fixHooks[ name ] = jQuery.event.mouseHooks; + } +}); + + + +/*! + * Sizzle CSS Selector Engine + * Copyright 2011, The Dojo Foundation + * Released under the MIT, BSD, and GPL Licenses. + * More information: http://sizzlejs.com/ + */ +(function(){ + +var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g, + expando = "sizcache" + (Math.random() + '').replace('.', ''), + done = 0, + toString = Object.prototype.toString, + hasDuplicate = false, + baseHasDuplicate = true, + rBackslash = /\\/g, + rReturn = /\r\n/g, + rNonWord = /\W/; + +// Here we check if the JavaScript engine is using some sort of +// optimization where it does not always call our comparision +// function. If that is the case, discard the hasDuplicate value. +// Thus far that includes Google Chrome. +[0, 0].sort(function() { + baseHasDuplicate = false; + return 0; +}); + +var Sizzle = function( selector, context, results, seed ) { + results = results || []; + context = context || document; + + var origContext = context; + + if ( context.nodeType !== 1 && context.nodeType !== 9 ) { + return []; + } + + if ( !selector || typeof selector !== "string" ) { + return results; + } + + var m, set, checkSet, extra, ret, cur, pop, i, + prune = true, + contextXML = Sizzle.isXML( context ), + parts = [], + soFar = selector; + + // Reset the position of the chunker regexp (start from head) + do { + chunker.exec( "" ); + m = chunker.exec( soFar ); + + if ( m ) { + soFar = m[3]; + + parts.push( m[1] ); + + if ( m[2] ) { + extra = m[3]; + break; + } + } + } while ( m ); + + if ( parts.length > 1 && origPOS.exec( selector ) ) { + + if ( parts.length === 2 && Expr.relative[ parts[0] ] ) { + set = posProcess( parts[0] + parts[1], context, seed ); + + } else { + set = Expr.relative[ parts[0] ] ? + [ context ] : + Sizzle( parts.shift(), context ); + + while ( parts.length ) { + selector = parts.shift(); + + if ( Expr.relative[ selector ] ) { + selector += parts.shift(); + } + + set = posProcess( selector, set, seed ); + } + } + + } else { + // Take a shortcut and set the context if the root selector is an ID + // (but not if it'll be faster if the inner selector is an ID) + if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML && + Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) { + + ret = Sizzle.find( parts.shift(), context, contextXML ); + context = ret.expr ? + Sizzle.filter( ret.expr, ret.set )[0] : + ret.set[0]; + } + + if ( context ) { + ret = seed ? + { expr: parts.pop(), set: makeArray(seed) } : + Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML ); + + set = ret.expr ? + Sizzle.filter( ret.expr, ret.set ) : + ret.set; + + if ( parts.length > 0 ) { + checkSet = makeArray( set ); + + } else { + prune = false; + } + + while ( parts.length ) { + cur = parts.pop(); + pop = cur; + + if ( !Expr.relative[ cur ] ) { + cur = ""; + } else { + pop = parts.pop(); + } + + if ( pop == null ) { + pop = context; + } + + Expr.relative[ cur ]( checkSet, pop, contextXML ); + } + + } else { + checkSet = parts = []; + } + } + + if ( !checkSet ) { + checkSet = set; + } + + if ( !checkSet ) { + Sizzle.error( cur || selector ); + } + + if ( toString.call(checkSet) === "[object Array]" ) { + if ( !prune ) { + results.push.apply( results, checkSet ); + + } else if ( context && context.nodeType === 1 ) { + for ( i = 0; checkSet[i] != null; i++ ) { + if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && Sizzle.contains(context, checkSet[i])) ) { + results.push( set[i] ); + } + } + + } else { + for ( i = 0; checkSet[i] != null; i++ ) { + if ( checkSet[i] && checkSet[i].nodeType === 1 ) { + results.push( set[i] ); + } + } + } + + } else { + makeArray( checkSet, results ); + } + + if ( extra ) { + Sizzle( extra, origContext, results, seed ); + Sizzle.uniqueSort( results ); + } + + return results; +}; + +Sizzle.uniqueSort = function( results ) { + if ( sortOrder ) { + hasDuplicate = baseHasDuplicate; + results.sort( sortOrder ); + + if ( hasDuplicate ) { + for ( var i = 1; i < results.length; i++ ) { + if ( results[i] === results[ i - 1 ] ) { + results.splice( i--, 1 ); + } + } + } + } + + return results; +}; + +Sizzle.matches = function( expr, set ) { + return Sizzle( expr, null, null, set ); +}; + +Sizzle.matchesSelector = function( node, expr ) { + return Sizzle( expr, null, null, [node] ).length > 0; +}; + +Sizzle.find = function( expr, context, isXML ) { + var set, i, len, match, type, left; + + if ( !expr ) { + return []; + } + + for ( i = 0, len = Expr.order.length; i < len; i++ ) { + type = Expr.order[i]; + + if ( (match = Expr.leftMatch[ type ].exec( expr )) ) { + left = match[1]; + match.splice( 1, 1 ); + + if ( left.substr( left.length - 1 ) !== "\\" ) { + match[1] = (match[1] || "").replace( rBackslash, "" ); + set = Expr.find[ type ]( match, context, isXML ); + + if ( set != null ) { + expr = expr.replace( Expr.match[ type ], "" ); + break; + } + } + } + } + + if ( !set ) { + set = typeof context.getElementsByTagName !== "undefined" ? + context.getElementsByTagName( "*" ) : + []; + } + + return { set: set, expr: expr }; +}; + +Sizzle.filter = function( expr, set, inplace, not ) { + var match, anyFound, + type, found, item, filter, left, + i, pass, + old = expr, + result = [], + curLoop = set, + isXMLFilter = set && set[0] && Sizzle.isXML( set[0] ); + + while ( expr && set.length ) { + for ( type in Expr.filter ) { + if ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) { + filter = Expr.filter[ type ]; + left = match[1]; + + anyFound = false; + + match.splice(1,1); + + if ( left.substr( left.length - 1 ) === "\\" ) { + continue; + } + + if ( curLoop === result ) { + result = []; + } + + if ( Expr.preFilter[ type ] ) { + match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter ); + + if ( !match ) { + anyFound = found = true; + + } else if ( match === true ) { + continue; + } + } + + if ( match ) { + for ( i = 0; (item = curLoop[i]) != null; i++ ) { + if ( item ) { + found = filter( item, match, i, curLoop ); + pass = not ^ found; + + if ( inplace && found != null ) { + if ( pass ) { + anyFound = true; + + } else { + curLoop[i] = false; + } + + } else if ( pass ) { + result.push( item ); + anyFound = true; + } + } + } + } + + if ( found !== undefined ) { + if ( !inplace ) { + curLoop = result; + } + + expr = expr.replace( Expr.match[ type ], "" ); + + if ( !anyFound ) { + return []; + } + + break; + } + } + } + + // Improper expression + if ( expr === old ) { + if ( anyFound == null ) { + Sizzle.error( expr ); + + } else { + break; + } + } + + old = expr; + } + + return curLoop; +}; + +Sizzle.error = function( msg ) { + throw new Error( "Syntax error, unrecognized expression: " + msg ); +}; + +/** + * Utility function for retreiving the text value of an array of DOM nodes + * @param {Array|Element} elem + */ +var getText = Sizzle.getText = function( elem ) { + var i, node, + nodeType = elem.nodeType, + ret = ""; + + if ( nodeType ) { + if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { + // Use textContent || innerText for elements + if ( typeof elem.textContent === 'string' ) { + return elem.textContent; + } else if ( typeof elem.innerText === 'string' ) { + // Replace IE's carriage returns + return elem.innerText.replace( rReturn, '' ); + } else { + // Traverse it's children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling) { + ret += getText( elem ); + } + } + } else if ( nodeType === 3 || nodeType === 4 ) { + return elem.nodeValue; + } + } else { + + // If no nodeType, this is expected to be an array + for ( i = 0; (node = elem[i]); i++ ) { + // Do not traverse comment nodes + if ( node.nodeType !== 8 ) { + ret += getText( node ); + } + } + } + return ret; +}; + +var Expr = Sizzle.selectors = { + order: [ "ID", "NAME", "TAG" ], + + match: { + ID: /#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/, + CLASS: /\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/, + NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/, + ATTR: /\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/, + TAG: /^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/, + CHILD: /:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/, + POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/, + PSEUDO: /:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/ + }, + + leftMatch: {}, + + attrMap: { + "class": "className", + "for": "htmlFor" + }, + + attrHandle: { + href: function( elem ) { + return elem.getAttribute( "href" ); + }, + type: function( elem ) { + return elem.getAttribute( "type" ); + } + }, + + relative: { + "+": function(checkSet, part){ + var isPartStr = typeof part === "string", + isTag = isPartStr && !rNonWord.test( part ), + isPartStrNotTag = isPartStr && !isTag; + + if ( isTag ) { + part = part.toLowerCase(); + } + + for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) { + if ( (elem = checkSet[i]) ) { + while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {} + + checkSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ? + elem || false : + elem === part; + } + } + + if ( isPartStrNotTag ) { + Sizzle.filter( part, checkSet, true ); + } + }, + + ">": function( checkSet, part ) { + var elem, + isPartStr = typeof part === "string", + i = 0, + l = checkSet.length; + + if ( isPartStr && !rNonWord.test( part ) ) { + part = part.toLowerCase(); + + for ( ; i < l; i++ ) { + elem = checkSet[i]; + + if ( elem ) { + var parent = elem.parentNode; + checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false; + } + } + + } else { + for ( ; i < l; i++ ) { + elem = checkSet[i]; + + if ( elem ) { + checkSet[i] = isPartStr ? + elem.parentNode : + elem.parentNode === part; + } + } + + if ( isPartStr ) { + Sizzle.filter( part, checkSet, true ); + } + } + }, + + "": function(checkSet, part, isXML){ + var nodeCheck, + doneName = done++, + checkFn = dirCheck; + + if ( typeof part === "string" && !rNonWord.test( part ) ) { + part = part.toLowerCase(); + nodeCheck = part; + checkFn = dirNodeCheck; + } + + checkFn( "parentNode", part, doneName, checkSet, nodeCheck, isXML ); + }, + + "~": function( checkSet, part, isXML ) { + var nodeCheck, + doneName = done++, + checkFn = dirCheck; + + if ( typeof part === "string" && !rNonWord.test( part ) ) { + part = part.toLowerCase(); + nodeCheck = part; + checkFn = dirNodeCheck; + } + + checkFn( "previousSibling", part, doneName, checkSet, nodeCheck, isXML ); + } + }, + + find: { + ID: function( match, context, isXML ) { + if ( typeof context.getElementById !== "undefined" && !isXML ) { + var m = context.getElementById(match[1]); + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + return m && m.parentNode ? [m] : []; + } + }, + + NAME: function( match, context ) { + if ( typeof context.getElementsByName !== "undefined" ) { + var ret = [], + results = context.getElementsByName( match[1] ); + + for ( var i = 0, l = results.length; i < l; i++ ) { + if ( results[i].getAttribute("name") === match[1] ) { + ret.push( results[i] ); + } + } + + return ret.length === 0 ? null : ret; + } + }, + + TAG: function( match, context ) { + if ( typeof context.getElementsByTagName !== "undefined" ) { + return context.getElementsByTagName( match[1] ); + } + } + }, + preFilter: { + CLASS: function( match, curLoop, inplace, result, not, isXML ) { + match = " " + match[1].replace( rBackslash, "" ) + " "; + + if ( isXML ) { + return match; + } + + for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) { + if ( elem ) { + if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n\r]/g, " ").indexOf(match) >= 0) ) { + if ( !inplace ) { + result.push( elem ); + } + + } else if ( inplace ) { + curLoop[i] = false; + } + } + } + + return false; + }, + + ID: function( match ) { + return match[1].replace( rBackslash, "" ); + }, + + TAG: function( match, curLoop ) { + return match[1].replace( rBackslash, "" ).toLowerCase(); + }, + + CHILD: function( match ) { + if ( match[1] === "nth" ) { + if ( !match[2] ) { + Sizzle.error( match[0] ); + } + + match[2] = match[2].replace(/^\+|\s*/g, ''); + + // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6' + var test = /(-?)(\d*)(?:n([+\-]?\d*))?/.exec( + match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" || + !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]); + + // calculate the numbers (first)n+(last) including if they are negative + match[2] = (test[1] + (test[2] || 1)) - 0; + match[3] = test[3] - 0; + } + else if ( match[2] ) { + Sizzle.error( match[0] ); + } + + // TODO: Move to normal caching system + match[0] = done++; + + return match; + }, + + ATTR: function( match, curLoop, inplace, result, not, isXML ) { + var name = match[1] = match[1].replace( rBackslash, "" ); + + if ( !isXML && Expr.attrMap[name] ) { + match[1] = Expr.attrMap[name]; + } + + // Handle if an un-quoted value was used + match[4] = ( match[4] || match[5] || "" ).replace( rBackslash, "" ); + + if ( match[2] === "~=" ) { + match[4] = " " + match[4] + " "; + } + + return match; + }, + + PSEUDO: function( match, curLoop, inplace, result, not ) { + if ( match[1] === "not" ) { + // If we're dealing with a complex expression, or a simple one + if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) { + match[3] = Sizzle(match[3], null, null, curLoop); + + } else { + var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not); + + if ( !inplace ) { + result.push.apply( result, ret ); + } + + return false; + } + + } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) { + return true; + } + + return match; + }, + + POS: function( match ) { + match.unshift( true ); + + return match; + } + }, + + filters: { + enabled: function( elem ) { + return elem.disabled === false && elem.type !== "hidden"; + }, + + disabled: function( elem ) { + return elem.disabled === true; + }, + + checked: function( elem ) { + return elem.checked === true; + }, + + selected: function( elem ) { + // Accessing this property makes selected-by-default + // options in Safari work properly + if ( elem.parentNode ) { + elem.parentNode.selectedIndex; + } + + return elem.selected === true; + }, + + parent: function( elem ) { + return !!elem.firstChild; + }, + + empty: function( elem ) { + return !elem.firstChild; + }, + + has: function( elem, i, match ) { + return !!Sizzle( match[3], elem ).length; + }, + + header: function( elem ) { + return (/h\d/i).test( elem.nodeName ); + }, + + text: function( elem ) { + var attr = elem.getAttribute( "type" ), type = elem.type; + // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc) + // use getAttribute instead to test this case + return elem.nodeName.toLowerCase() === "input" && "text" === type && ( attr === type || attr === null ); + }, + + radio: function( elem ) { + return elem.nodeName.toLowerCase() === "input" && "radio" === elem.type; + }, + + checkbox: function( elem ) { + return elem.nodeName.toLowerCase() === "input" && "checkbox" === elem.type; + }, + + file: function( elem ) { + return elem.nodeName.toLowerCase() === "input" && "file" === elem.type; + }, + + password: function( elem ) { + return elem.nodeName.toLowerCase() === "input" && "password" === elem.type; + }, + + submit: function( elem ) { + var name = elem.nodeName.toLowerCase(); + return (name === "input" || name === "button") && "submit" === elem.type; + }, + + image: function( elem ) { + return elem.nodeName.toLowerCase() === "input" && "image" === elem.type; + }, + + reset: function( elem ) { + var name = elem.nodeName.toLowerCase(); + return (name === "input" || name === "button") && "reset" === elem.type; + }, + + button: function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && "button" === elem.type || name === "button"; + }, + + input: function( elem ) { + return (/input|select|textarea|button/i).test( elem.nodeName ); + }, + + focus: function( elem ) { + return elem === elem.ownerDocument.activeElement; + } + }, + setFilters: { + first: function( elem, i ) { + return i === 0; + }, + + last: function( elem, i, match, array ) { + return i === array.length - 1; + }, + + even: function( elem, i ) { + return i % 2 === 0; + }, + + odd: function( elem, i ) { + return i % 2 === 1; + }, + + lt: function( elem, i, match ) { + return i < match[3] - 0; + }, + + gt: function( elem, i, match ) { + return i > match[3] - 0; + }, + + nth: function( elem, i, match ) { + return match[3] - 0 === i; + }, + + eq: function( elem, i, match ) { + return match[3] - 0 === i; + } + }, + filter: { + PSEUDO: function( elem, match, i, array ) { + var name = match[1], + filter = Expr.filters[ name ]; + + if ( filter ) { + return filter( elem, i, match, array ); + + } else if ( name === "contains" ) { + return (elem.textContent || elem.innerText || getText([ elem ]) || "").indexOf(match[3]) >= 0; + + } else if ( name === "not" ) { + var not = match[3]; + + for ( var j = 0, l = not.length; j < l; j++ ) { + if ( not[j] === elem ) { + return false; + } + } + + return true; + + } else { + Sizzle.error( name ); + } + }, + + CHILD: function( elem, match ) { + var first, last, + doneName, parent, cache, + count, diff, + type = match[1], + node = elem; + + switch ( type ) { + case "only": + case "first": + while ( (node = node.previousSibling) ) { + if ( node.nodeType === 1 ) { + return false; + } + } + + if ( type === "first" ) { + return true; + } + + node = elem; + + /* falls through */ + case "last": + while ( (node = node.nextSibling) ) { + if ( node.nodeType === 1 ) { + return false; + } + } + + return true; + + case "nth": + first = match[2]; + last = match[3]; + + if ( first === 1 && last === 0 ) { + return true; + } + + doneName = match[0]; + parent = elem.parentNode; + + if ( parent && (parent[ expando ] !== doneName || !elem.nodeIndex) ) { + count = 0; + + for ( node = parent.firstChild; node; node = node.nextSibling ) { + if ( node.nodeType === 1 ) { + node.nodeIndex = ++count; + } + } + + parent[ expando ] = doneName; + } + + diff = elem.nodeIndex - last; + + if ( first === 0 ) { + return diff === 0; + + } else { + return ( diff % first === 0 && diff / first >= 0 ); + } + } + }, + + ID: function( elem, match ) { + return elem.nodeType === 1 && elem.getAttribute("id") === match; + }, + + TAG: function( elem, match ) { + return (match === "*" && elem.nodeType === 1) || !!elem.nodeName && elem.nodeName.toLowerCase() === match; + }, + + CLASS: function( elem, match ) { + return (" " + (elem.className || elem.getAttribute("class")) + " ") + .indexOf( match ) > -1; + }, + + ATTR: function( elem, match ) { + var name = match[1], + result = Sizzle.attr ? + Sizzle.attr( elem, name ) : + Expr.attrHandle[ name ] ? + Expr.attrHandle[ name ]( elem ) : + elem[ name ] != null ? + elem[ name ] : + elem.getAttribute( name ), + value = result + "", + type = match[2], + check = match[4]; + + return result == null ? + type === "!=" : + !type && Sizzle.attr ? + result != null : + type === "=" ? + value === check : + type === "*=" ? + value.indexOf(check) >= 0 : + type === "~=" ? + (" " + value + " ").indexOf(check) >= 0 : + !check ? + value && result !== false : + type === "!=" ? + value !== check : + type === "^=" ? + value.indexOf(check) === 0 : + type === "$=" ? + value.substr(value.length - check.length) === check : + type === "|=" ? + value === check || value.substr(0, check.length + 1) === check + "-" : + false; + }, + + POS: function( elem, match, i, array ) { + var name = match[2], + filter = Expr.setFilters[ name ]; + + if ( filter ) { + return filter( elem, i, match, array ); + } + } + } +}; + +var origPOS = Expr.match.POS, + fescape = function(all, num){ + return "\\" + (num - 0 + 1); + }; + +for ( var type in Expr.match ) { + Expr.match[ type ] = new RegExp( Expr.match[ type ].source + (/(?![^\[]*\])(?![^\(]*\))/.source) ); + Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source.replace(/\\(\d+)/g, fescape) ); +} +// Expose origPOS +// "global" as in regardless of relation to brackets/parens +Expr.match.globalPOS = origPOS; + +var makeArray = function( array, results ) { + array = Array.prototype.slice.call( array, 0 ); + + if ( results ) { + results.push.apply( results, array ); + return results; + } + + return array; +}; + +// Perform a simple check to determine if the browser is capable of +// converting a NodeList to an array using builtin methods. +// Also verifies that the returned array holds DOM nodes +// (which is not the case in the Blackberry browser) +try { + Array.prototype.slice.call( document.documentElement.childNodes, 0 )[0].nodeType; + +// Provide a fallback method if it does not work +} catch( e ) { + makeArray = function( array, results ) { + var i = 0, + ret = results || []; + + if ( toString.call(array) === "[object Array]" ) { + Array.prototype.push.apply( ret, array ); + + } else { + if ( typeof array.length === "number" ) { + for ( var l = array.length; i < l; i++ ) { + ret.push( array[i] ); + } + + } else { + for ( ; array[i]; i++ ) { + ret.push( array[i] ); + } + } + } + + return ret; + }; +} + +var sortOrder, siblingCheck; + +if ( document.documentElement.compareDocumentPosition ) { + sortOrder = function( a, b ) { + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) { + return a.compareDocumentPosition ? -1 : 1; + } + + return a.compareDocumentPosition(b) & 4 ? -1 : 1; + }; + +} else { + sortOrder = function( a, b ) { + // The nodes are identical, we can exit early + if ( a === b ) { + hasDuplicate = true; + return 0; + + // Fallback to using sourceIndex (in IE) if it's available on both nodes + } else if ( a.sourceIndex && b.sourceIndex ) { + return a.sourceIndex - b.sourceIndex; + } + + var al, bl, + ap = [], + bp = [], + aup = a.parentNode, + bup = b.parentNode, + cur = aup; + + // If the nodes are siblings (or identical) we can do a quick check + if ( aup === bup ) { + return siblingCheck( a, b ); + + // If no parents were found then the nodes are disconnected + } else if ( !aup ) { + return -1; + + } else if ( !bup ) { + return 1; + } + + // Otherwise they're somewhere else in the tree so we need + // to build up a full list of the parentNodes for comparison + while ( cur ) { + ap.unshift( cur ); + cur = cur.parentNode; + } + + cur = bup; + + while ( cur ) { + bp.unshift( cur ); + cur = cur.parentNode; + } + + al = ap.length; + bl = bp.length; + + // Start walking down the tree looking for a discrepancy + for ( var i = 0; i < al && i < bl; i++ ) { + if ( ap[i] !== bp[i] ) { + return siblingCheck( ap[i], bp[i] ); + } + } + + // We ended someplace up the tree so do a sibling check + return i === al ? + siblingCheck( a, bp[i], -1 ) : + siblingCheck( ap[i], b, 1 ); + }; + + siblingCheck = function( a, b, ret ) { + if ( a === b ) { + return ret; + } + + var cur = a.nextSibling; + + while ( cur ) { + if ( cur === b ) { + return -1; + } + + cur = cur.nextSibling; + } + + return 1; + }; +} + +// Check to see if the browser returns elements by name when +// querying by getElementById (and provide a workaround) +(function(){ + // We're going to inject a fake input element with a specified name + var form = document.createElement("div"), + id = "script" + (new Date()).getTime(), + root = document.documentElement; + + form.innerHTML = ""; + + // Inject it into the root element, check its status, and remove it quickly + root.insertBefore( form, root.firstChild ); + + // The workaround has to do additional checks after a getElementById + // Which slows things down for other browsers (hence the branching) + if ( document.getElementById( id ) ) { + Expr.find.ID = function( match, context, isXML ) { + if ( typeof context.getElementById !== "undefined" && !isXML ) { + var m = context.getElementById(match[1]); + + return m ? + m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ? + [m] : + undefined : + []; + } + }; + + Expr.filter.ID = function( elem, match ) { + var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id"); + + return elem.nodeType === 1 && node && node.nodeValue === match; + }; + } + + root.removeChild( form ); + + // release memory in IE + root = form = null; +})(); + +(function(){ + // Check to see if the browser returns only elements + // when doing getElementsByTagName("*") + + // Create a fake element + var div = document.createElement("div"); + div.appendChild( document.createComment("") ); + + // Make sure no comments are found + if ( div.getElementsByTagName("*").length > 0 ) { + Expr.find.TAG = function( match, context ) { + var results = context.getElementsByTagName( match[1] ); + + // Filter out possible comments + if ( match[1] === "*" ) { + var tmp = []; + + for ( var i = 0; results[i]; i++ ) { + if ( results[i].nodeType === 1 ) { + tmp.push( results[i] ); + } + } + + results = tmp; + } + + return results; + }; + } + + // Check to see if an attribute returns normalized href attributes + div.innerHTML = ""; + + if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" && + div.firstChild.getAttribute("href") !== "#" ) { + + Expr.attrHandle.href = function( elem ) { + return elem.getAttribute( "href", 2 ); + }; + } + + // release memory in IE + div = null; +})(); + +if ( document.querySelectorAll ) { + (function(){ + var oldSizzle = Sizzle, + div = document.createElement("div"), + id = "__sizzle__"; + + div.innerHTML = "

    "; + + // Safari can't handle uppercase or unicode characters when + // in quirks mode. + if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) { + return; + } + + Sizzle = function( query, context, extra, seed ) { + context = context || document; + + // Only use querySelectorAll on non-XML documents + // (ID selectors don't work in non-HTML documents) + if ( !seed && !Sizzle.isXML(context) ) { + // See if we find a selector to speed up + var match = /^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec( query ); + + if ( match && (context.nodeType === 1 || context.nodeType === 9) ) { + // Speed-up: Sizzle("TAG") + if ( match[1] ) { + return makeArray( context.getElementsByTagName( query ), extra ); + + // Speed-up: Sizzle(".CLASS") + } else if ( match[2] && Expr.find.CLASS && context.getElementsByClassName ) { + return makeArray( context.getElementsByClassName( match[2] ), extra ); + } + } + + if ( context.nodeType === 9 ) { + // Speed-up: Sizzle("body") + // The body element only exists once, optimize finding it + if ( query === "body" && context.body ) { + return makeArray( [ context.body ], extra ); + + // Speed-up: Sizzle("#ID") + } else if ( match && match[3] ) { + var elem = context.getElementById( match[3] ); + + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + if ( elem && elem.parentNode ) { + // Handle the case where IE and Opera return items + // by name instead of ID + if ( elem.id === match[3] ) { + return makeArray( [ elem ], extra ); + } + + } else { + return makeArray( [], extra ); + } + } + + try { + return makeArray( context.querySelectorAll(query), extra ); + } catch(qsaError) {} + + // qSA works strangely on Element-rooted queries + // We can work around this by specifying an extra ID on the root + // and working up from there (Thanks to Andrew Dupont for the technique) + // IE 8 doesn't work on object elements + } else if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) { + var oldContext = context, + old = context.getAttribute( "id" ), + nid = old || id, + hasParent = context.parentNode, + relativeHierarchySelector = /^\s*[+~]/.test( query ); + + if ( !old ) { + context.setAttribute( "id", nid ); + } else { + nid = nid.replace( /'/g, "\\$&" ); + } + if ( relativeHierarchySelector && hasParent ) { + context = context.parentNode; + } + + try { + if ( !relativeHierarchySelector || hasParent ) { + return makeArray( context.querySelectorAll( "[id='" + nid + "'] " + query ), extra ); + } + + } catch(pseudoError) { + } finally { + if ( !old ) { + oldContext.removeAttribute( "id" ); + } + } + } + } + + return oldSizzle(query, context, extra, seed); + }; + + for ( var prop in oldSizzle ) { + Sizzle[ prop ] = oldSizzle[ prop ]; + } + + // release memory in IE + div = null; + })(); +} + +(function(){ + var html = document.documentElement, + matches = html.matchesSelector || html.mozMatchesSelector || html.webkitMatchesSelector || html.msMatchesSelector; + + if ( matches ) { + // Check to see if it's possible to do matchesSelector + // on a disconnected node (IE 9 fails this) + var disconnectedMatch = !matches.call( document.createElement( "div" ), "div" ), + pseudoWorks = false; + + try { + // This should fail with an exception + // Gecko does not error, returns false instead + matches.call( document.documentElement, "[test!='']:sizzle" ); + + } catch( pseudoError ) { + pseudoWorks = true; + } + + Sizzle.matchesSelector = function( node, expr ) { + // Make sure that attribute selectors are quoted + expr = expr.replace(/\=\s*([^'"\]]*)\s*\]/g, "='$1']"); + + if ( !Sizzle.isXML( node ) ) { + try { + if ( pseudoWorks || !Expr.match.PSEUDO.test( expr ) && !/!=/.test( expr ) ) { + var ret = matches.call( node, expr ); + + // IE 9's matchesSelector returns false on disconnected nodes + if ( ret || !disconnectedMatch || + // As well, disconnected nodes are said to be in a document + // fragment in IE 9, so check for that + node.document && node.document.nodeType !== 11 ) { + return ret; + } + } + } catch(e) {} + } + + return Sizzle(expr, null, null, [node]).length > 0; + }; + } +})(); + +(function(){ + var div = document.createElement("div"); + + div.innerHTML = "
    "; + + // Opera can't find a second classname (in 9.6) + // Also, make sure that getElementsByClassName actually exists + if ( !div.getElementsByClassName || div.getElementsByClassName("e").length === 0 ) { + return; + } + + // Safari caches class attributes, doesn't catch changes (in 3.2) + div.lastChild.className = "e"; + + if ( div.getElementsByClassName("e").length === 1 ) { + return; + } + + Expr.order.splice(1, 0, "CLASS"); + Expr.find.CLASS = function( match, context, isXML ) { + if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) { + return context.getElementsByClassName(match[1]); + } + }; + + // release memory in IE + div = null; +})(); + +function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { + for ( var i = 0, l = checkSet.length; i < l; i++ ) { + var elem = checkSet[i]; + + if ( elem ) { + var match = false; + + elem = elem[dir]; + + while ( elem ) { + if ( elem[ expando ] === doneName ) { + match = checkSet[elem.sizset]; + break; + } + + if ( elem.nodeType === 1 && !isXML ){ + elem[ expando ] = doneName; + elem.sizset = i; + } + + if ( elem.nodeName.toLowerCase() === cur ) { + match = elem; + break; + } + + elem = elem[dir]; + } + + checkSet[i] = match; + } + } +} + +function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { + for ( var i = 0, l = checkSet.length; i < l; i++ ) { + var elem = checkSet[i]; + + if ( elem ) { + var match = false; + + elem = elem[dir]; + + while ( elem ) { + if ( elem[ expando ] === doneName ) { + match = checkSet[elem.sizset]; + break; + } + + if ( elem.nodeType === 1 ) { + if ( !isXML ) { + elem[ expando ] = doneName; + elem.sizset = i; + } + + if ( typeof cur !== "string" ) { + if ( elem === cur ) { + match = true; + break; + } + + } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) { + match = elem; + break; + } + } + + elem = elem[dir]; + } + + checkSet[i] = match; + } + } +} + +if ( document.documentElement.contains ) { + Sizzle.contains = function( a, b ) { + return a !== b && (a.contains ? a.contains(b) : true); + }; + +} else if ( document.documentElement.compareDocumentPosition ) { + Sizzle.contains = function( a, b ) { + return !!(a.compareDocumentPosition(b) & 16); + }; + +} else { + Sizzle.contains = function() { + return false; + }; +} + +Sizzle.isXML = function( elem ) { + // documentElement is verified for cases where it doesn't yet exist + // (such as loading iframes in IE - #4833) + var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement; + + return documentElement ? documentElement.nodeName !== "HTML" : false; +}; + +var posProcess = function( selector, context, seed ) { + var match, + tmpSet = [], + later = "", + root = context.nodeType ? [context] : context; + + // Position selectors must be done after the filter + // And so must :not(positional) so we move all PSEUDOs to the end + while ( (match = Expr.match.PSEUDO.exec( selector )) ) { + later += match[0]; + selector = selector.replace( Expr.match.PSEUDO, "" ); + } + + selector = Expr.relative[selector] ? selector + "*" : selector; + + for ( var i = 0, l = root.length; i < l; i++ ) { + Sizzle( selector, root[i], tmpSet, seed ); + } + + return Sizzle.filter( later, tmpSet ); +}; + +// EXPOSE +// Override sizzle attribute retrieval +Sizzle.attr = jQuery.attr; +Sizzle.selectors.attrMap = {}; +jQuery.find = Sizzle; +jQuery.expr = Sizzle.selectors; +jQuery.expr[":"] = jQuery.expr.filters; +jQuery.unique = Sizzle.uniqueSort; +jQuery.text = Sizzle.getText; +jQuery.isXMLDoc = Sizzle.isXML; +jQuery.contains = Sizzle.contains; + + +})(); + + +var runtil = /Until$/, + rparentsprev = /^(?:parents|prevUntil|prevAll)/, + // Note: This RegExp should be improved, or likely pulled from Sizzle + rmultiselector = /,/, + isSimple = /^.[^:#\[\.,]*$/, + slice = Array.prototype.slice, + POS = jQuery.expr.match.globalPOS, + // methods guaranteed to produce a unique set when starting from a unique set + guaranteedUnique = { + children: true, + contents: true, + next: true, + prev: true + }; + +jQuery.fn.extend({ + find: function( selector ) { + var self = this, + i, l; + + if ( typeof selector !== "string" ) { + return jQuery( selector ).filter(function() { + for ( i = 0, l = self.length; i < l; i++ ) { + if ( jQuery.contains( self[ i ], this ) ) { + return true; + } + } + }); + } + + var ret = this.pushStack( "", "find", selector ), + length, n, r; + + for ( i = 0, l = this.length; i < l; i++ ) { + length = ret.length; + jQuery.find( selector, this[i], ret ); + + if ( i > 0 ) { + // Make sure that the results are unique + for ( n = length; n < ret.length; n++ ) { + for ( r = 0; r < length; r++ ) { + if ( ret[r] === ret[n] ) { + ret.splice(n--, 1); + break; + } + } + } + } + } + + return ret; + }, + + has: function( target ) { + var targets = jQuery( target ); + return this.filter(function() { + for ( var i = 0, l = targets.length; i < l; i++ ) { + if ( jQuery.contains( this, targets[i] ) ) { + return true; + } + } + }); + }, + + not: function( selector ) { + return this.pushStack( winnow(this, selector, false), "not", selector); + }, + + filter: function( selector ) { + return this.pushStack( winnow(this, selector, true), "filter", selector ); + }, + + is: function( selector ) { + return !!selector && ( + typeof selector === "string" ? + // If this is a positional selector, check membership in the returned set + // so $("p:first").is("p:last") won't return true for a doc with two "p". + POS.test( selector ) ? + jQuery( selector, this.context ).index( this[0] ) >= 0 : + jQuery.filter( selector, this ).length > 0 : + this.filter( selector ).length > 0 ); + }, + + closest: function( selectors, context ) { + var ret = [], i, l, cur = this[0]; + + // Array (deprecated as of jQuery 1.7) + if ( jQuery.isArray( selectors ) ) { + var level = 1; + + while ( cur && cur.ownerDocument && cur !== context ) { + for ( i = 0; i < selectors.length; i++ ) { + + if ( jQuery( cur ).is( selectors[ i ] ) ) { + ret.push({ selector: selectors[ i ], elem: cur, level: level }); + } + } + + cur = cur.parentNode; + level++; + } + + return ret; + } + + // String + var pos = POS.test( selectors ) || typeof selectors !== "string" ? + jQuery( selectors, context || this.context ) : + 0; + + for ( i = 0, l = this.length; i < l; i++ ) { + cur = this[i]; + + while ( cur ) { + if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) { + ret.push( cur ); + break; + + } else { + cur = cur.parentNode; + if ( !cur || !cur.ownerDocument || cur === context || cur.nodeType === 11 ) { + break; + } + } + } + } + + ret = ret.length > 1 ? jQuery.unique( ret ) : ret; + + return this.pushStack( ret, "closest", selectors ); + }, + + // Determine the position of an element within + // the matched set of elements + index: function( elem ) { + + // No argument, return index in parent + if ( !elem ) { + return ( this[0] && this[0].parentNode ) ? this.prevAll().length : -1; + } + + // index in selector + if ( typeof elem === "string" ) { + return jQuery.inArray( this[0], jQuery( elem ) ); + } + + // Locate the position of the desired element + return jQuery.inArray( + // If it receives a jQuery object, the first element is used + elem.jquery ? elem[0] : elem, this ); + }, + + add: function( selector, context ) { + var set = typeof selector === "string" ? + jQuery( selector, context ) : + jQuery.makeArray( selector && selector.nodeType ? [ selector ] : selector ), + all = jQuery.merge( this.get(), set ); + + return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ? + all : + jQuery.unique( all ) ); + }, + + andSelf: function() { + return this.add( this.prevObject ); + } +}); + +// A painfully simple check to see if an element is disconnected +// from a document (should be improved, where feasible). +function isDisconnected( node ) { + return !node || !node.parentNode || node.parentNode.nodeType === 11; +} + +jQuery.each({ + parent: function( elem ) { + var parent = elem.parentNode; + return parent && parent.nodeType !== 11 ? parent : null; + }, + parents: function( elem ) { + return jQuery.dir( elem, "parentNode" ); + }, + parentsUntil: function( elem, i, until ) { + return jQuery.dir( elem, "parentNode", until ); + }, + next: function( elem ) { + return jQuery.nth( elem, 2, "nextSibling" ); + }, + prev: function( elem ) { + return jQuery.nth( elem, 2, "previousSibling" ); + }, + nextAll: function( elem ) { + return jQuery.dir( elem, "nextSibling" ); + }, + prevAll: function( elem ) { + return jQuery.dir( elem, "previousSibling" ); + }, + nextUntil: function( elem, i, until ) { + return jQuery.dir( elem, "nextSibling", until ); + }, + prevUntil: function( elem, i, until ) { + return jQuery.dir( elem, "previousSibling", until ); + }, + siblings: function( elem ) { + return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem ); + }, + children: function( elem ) { + return jQuery.sibling( elem.firstChild ); + }, + contents: function( elem ) { + return jQuery.nodeName( elem, "iframe" ) ? + elem.contentDocument || elem.contentWindow.document : + jQuery.makeArray( elem.childNodes ); + } +}, function( name, fn ) { + jQuery.fn[ name ] = function( until, selector ) { + var ret = jQuery.map( this, fn, until ); + + if ( !runtil.test( name ) ) { + selector = until; + } + + if ( selector && typeof selector === "string" ) { + ret = jQuery.filter( selector, ret ); + } + + ret = this.length > 1 && !guaranteedUnique[ name ] ? jQuery.unique( ret ) : ret; + + if ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( name ) ) { + ret = ret.reverse(); + } + + return this.pushStack( ret, name, slice.call( arguments ).join(",") ); + }; +}); + +jQuery.extend({ + filter: function( expr, elems, not ) { + if ( not ) { + expr = ":not(" + expr + ")"; + } + + return elems.length === 1 ? + jQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] : + jQuery.find.matches(expr, elems); + }, + + dir: function( elem, dir, until ) { + var matched = [], + cur = elem[ dir ]; + + while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) { + if ( cur.nodeType === 1 ) { + matched.push( cur ); + } + cur = cur[dir]; + } + return matched; + }, + + nth: function( cur, result, dir, elem ) { + result = result || 1; + var num = 0; + + for ( ; cur; cur = cur[dir] ) { + if ( cur.nodeType === 1 && ++num === result ) { + break; + } + } + + return cur; + }, + + sibling: function( n, elem ) { + var r = []; + + for ( ; n; n = n.nextSibling ) { + if ( n.nodeType === 1 && n !== elem ) { + r.push( n ); + } + } + + return r; + } +}); + +// Implement the identical functionality for filter and not +function winnow( elements, qualifier, keep ) { + + // Can't pass null or undefined to indexOf in Firefox 4 + // Set to 0 to skip string check + qualifier = qualifier || 0; + + if ( jQuery.isFunction( qualifier ) ) { + return jQuery.grep(elements, function( elem, i ) { + var retVal = !!qualifier.call( elem, i, elem ); + return retVal === keep; + }); + + } else if ( qualifier.nodeType ) { + return jQuery.grep(elements, function( elem, i ) { + return ( elem === qualifier ) === keep; + }); + + } else if ( typeof qualifier === "string" ) { + var filtered = jQuery.grep(elements, function( elem ) { + return elem.nodeType === 1; + }); + + if ( isSimple.test( qualifier ) ) { + return jQuery.filter(qualifier, filtered, !keep); + } else { + qualifier = jQuery.filter( qualifier, filtered ); + } + } + + return jQuery.grep(elements, function( elem, i ) { + return ( jQuery.inArray( elem, qualifier ) >= 0 ) === keep; + }); +} + + + + +function createSafeFragment( document ) { + var list = nodeNames.split( "|" ), + safeFrag = document.createDocumentFragment(); + + if ( safeFrag.createElement ) { + while ( list.length ) { + safeFrag.createElement( + list.pop() + ); + } + } + return safeFrag; +} + +var nodeNames = "abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|" + + "header|hgroup|mark|meter|nav|output|progress|section|summary|time|video", + rinlinejQuery = / jQuery\d+="(?:\d+|null)"/g, + rleadingWhitespace = /^\s+/, + rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig, + rtagName = /<([\w:]+)/, + rtbody = /]", "i"), + // checked="checked" or checked + rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i, + rscriptType = /\/(java|ecma)script/i, + rcleanScript = /^\s*", "" ], + legend: [ 1, "
    ", "
    " ], + thead: [ 1, "", "
    " ], + tr: [ 2, "", "
    " ], + td: [ 3, "", "
    " ], + col: [ 2, "", "
    " ], + area: [ 1, "", "" ], + _default: [ 0, "", "" ] + }, + safeFragment = createSafeFragment( document ); + +wrapMap.optgroup = wrapMap.option; +wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; +wrapMap.th = wrapMap.td; + +// IE can't serialize and + + + + + + + + + +
    +
    +
    +
    + +
    +

    8. Contacts & Notices¶

    +
    +

    8.1. Contacts¶

    +
    +
    ADLINK Technology Corporation
    +
    400 TradeCenter
    +
    Suite 5900
    +
    Woburn, MA
    +
    01801
    +
    USA
    +
    Tel: +1 781 569 5819
    +
    +
    +
    ADLINK Technology Limited
    +
    The Edge
    +
    5th Avenue
    +
    Team Valley
    +
    Gateshead
    +
    NE11 0XA
    +
    UK
    +
    Tel: +44 (0)191 497 9900
    +
    +
    +
    ADLINK Technology SARL
    +
    28 rue Jean Rostand
    +
    91400 Orsay
    +
    France
    +
    Tel: +33 (1) 69 015354
    +
    +

    Web: http://ist.adlinktech.com/

    +

    Contact: http://ist.adlinktech.com

    +

    E-mail: ist_info@adlinktech.com

    +

    LinkedIn: https://www.linkedin.com/company/79111/

    +

    Twitter: https://twitter.com/ADLINKTech_usa

    +

    Facebook: https://www.facebook.com/ADLINKTECH

    +
    +
    +

    8.2. Notices¶

    +

    Copyright © 2018 ADLINK Technology Limited. All rights reserved.

    +

    This document may be reproduced in whole but not in part. The information contained in this +document is subject to change without notice and is made available in good faith without +liability on the part of ADLINK Technology Limited. All trademarks acknowledged.

    +
    +
    + + +
    +
    +
    +
    +
    + +

    Table Of Contents

    + + +

    Previous topic

    +

    7. Ping Pong Example

    +

    This Page

    + + + +
    +
    +
    +
    + + + + \ No newline at end of file diff --git a/docs/html/DDSMATLABGuide/example-ping-pong.html b/docs/html/DDSMATLABGuide/example-ping-pong.html new file mode 100644 index 000000000..fdeacb6b2 --- /dev/null +++ b/docs/html/DDSMATLABGuide/example-ping-pong.html @@ -0,0 +1,195 @@ + + + + + + + + 7. Ping Pong Example — The Vortex OpenSplice MATLAB Guide + + + + + + + + + + + + + + + +
    +
    +
    +
    + +
    +

    7. Ping Pong Example¶

    +

    A simple ping pong example is provided to demonstrate the basic capabilities of the MATLAB DDS integration.

    +

    The ping pong example can be found in the following directory:

    +
    +
    OSPL_HOME/tools/matlab/examples/matlab/pingpong
    +

    The ping pong example creates two participants.

    +
      +
    1. A pinger that writes to the PING partition and reads from the PONG partition.
    2. +
    3. A ponger that writes to the PONG partition and reads from the PING partition.
    4. +
    +

    A matlab script is provided that writes and reads sample data in the pinger and ponger participants.

    +
    +

    7.1. Example Files¶

    +

    Files with the .m extension are MATLAB script files.

    +

    An explanation of what each example file does is provided below.

    +

    pingpong.idl

    +
      +
    • Defines the PingPongType in idl
    • +
    • Used to generate the MATLAB file PingPongType.m via:
    • +
    +

    idlpp -l matlab pingpong.idl

    +

    PingPongType.m

    +
      +
    • Defines a PingPongType; generated from idlpp
    • +
    • The PingPongType represents a DDS topic type.
    • +
    • PingPongType specifies two properties: id, count.
    • +
    +

    DDS_PingerVolatileQoS.xml

    +
      +
    • XML file that specifies the DDS QoS (quality of service) settings for pinger.
    • +
    +

    DDS_PongerVolatileQoS.xml

    +
      +
    • XML file that specifies the DDS QoS (quality of service) settings for ponger.
    • +
    +

    setup_pinger.m

    +
      +
    • Creates the pinger participant on the default DDS domain, with specified QoS profile.
    • +
    • Creates the topic PingPongType.
    • +
    • Creates the publisher using the domain participant on the PING partition specified in the specified QoS profile.
    • +
    • Creates the writer using the publisher and the specified QoS profile.
    • +
    • Creates the subscriber using the domain participant on the PONG partition specified in the QoS profile.
    • +
    • Creates the reader using the subscriber and the specified QoS profile.
    • +
    +

    setup_ponger.m

    +
      +
    • Creates the ponger participant on default domain with specified QoS profile.
    • +
    • Creates the topic PingPongType.
    • +
    • Creates the publisher using the domain participant on the PONG partition specified in the QoS profile.
    • +
    • Creates the writer using the publisher and the specified QoS profile.
    • +
    • Creates the subscriber using the domain participant on the PING partition specified in the QoS profile.
    • +
    • Creates the reader using the subscriber and the specified QoS profile.
    • +
    +

    pinger_ponger.m

    +
      +
    • MATLAB script that writes and reads sample data in the pinger and ponger participants.
    • +
    • This script calls the setup_pinger.m and setup_ponger.m scripts.
    • +
    • This is the main script to run the ping pong example.
    • +
    • This script is run from the MATLAB Command Window.
    • +
    +
    +
    +

    7.2. Steps to run example¶

    +
      +
    1. +
      In the MATLAB command window, run pinger_ponger.m.
      +
        +
      • Type “pinger_ponger”.
      • +
      • Hit enter.
      • +
      +
      +
      +
    2. +
    +
    +
    + + +
    +
    +
    +
    +
    + +

    Table Of Contents

    + + +

    Previous topic

    +

    6. QoS Provider

    +

    Next topic

    +

    8. Contacts & Notices

    +

    This Page

    + + + +
    +
    +
    +
    + + + + \ No newline at end of file diff --git a/docs/html/DDSMATLABGuide/genindex.html b/docs/html/DDSMATLABGuide/genindex.html new file mode 100644 index 000000000..efaa21a74 --- /dev/null +++ b/docs/html/DDSMATLABGuide/genindex.html @@ -0,0 +1,94 @@ + + + + + + + + + Index — The Vortex OpenSplice MATLAB Guide + + + + + + + + + + + + + +
    +
    +
    +
    + + +

    Index

    + +
    + +
    + + +
    +
    +
    +
    +
    + + + + + + +
    +
    +
    +
    + + + + \ No newline at end of file diff --git a/docs/html/DDSMATLABGuide/index.html b/docs/html/DDSMATLABGuide/index.html new file mode 100644 index 000000000..188072fce --- /dev/null +++ b/docs/html/DDSMATLABGuide/index.html @@ -0,0 +1,172 @@ + + + + + + + + DDS MATLAB Guide — The Vortex OpenSplice MATLAB Guide + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/html/DDSMATLABGuide/installation.html b/docs/html/DDSMATLABGuide/installation.html new file mode 100644 index 000000000..c436668b8 --- /dev/null +++ b/docs/html/DDSMATLABGuide/installation.html @@ -0,0 +1,200 @@ + + + + + + + + 2. Installation — The Vortex OpenSplice MATLAB Guide + + + + + + + + + + + + + + + +
    +
    +
    +
    + +
    +

    2. Installation¶

    +

    This section describes the procedure to install the Vortex DDS MATLAB Integration on a Linux or Windows platform.

    +
    +

    2.1. System Requirements¶

    +
      +
    • Operating System: Windows or Linux
    • +
    • MATLAB installed
    • +
    • Java 1.7 or greater
    • +
    +
    +
    +

    2.2. OpenSplice (OSPL) and DDS MATLAB Installation¶

    +

    Steps:

    +
      +
    1. Install OSPL. The DDS MATLAB Integration is included in this installer.
    2. +
    3. Setup OSPL license. Copy the license.lic file into the appropriate license directory.
    4. +
    +
    +
    /INSTALLDIR/Vortex_v2/license
    +
      +
    1. DDS MATLAB files are contained in a tools/matlab folder
    2. +
    +
    +
    Example: +/INSTALLDIR/Vortex_v2/Device/VortexOpenSplice/6.8.1/HDE/x86_64.linux/tools/matlab
    +
    +
    +

    2.3. MATLAB and DDS Setup¶

    +

    Steps:

    +
      +
    1. Open command shell and run script to setup environment variables.

      +
      +

      Linux

      +
        +
      • Open a Linux terminal.

        +
      • +
      • Navigate to directory containing release.com file.

        +

        /INSTALLDIR/Vortex_v2/Device/VortexOpenSplice/6.8.1/HDE/x86_64.linux

        +
      • +
      • Run release.com. (Type in “. release.com†at command line.)

        +
      • +
      +

      Windows

      +
        +
      • Open a command prompt.

        +
      • +
      • Navigate to directory containing release.bat file.

        +

        INSTALLDIR/Vortex_v2/Device/VortexOpenSplice/6.8.1/HDE/x86_64.win64

        +
      • +
      • Run release.bat. (Type in “release.bat†at command line.)

        +
      • +
      +
      +
    2. +
    3. Start MATLAB using the SAME command shell used in Step 1.

      +
      +

      NOTE: If MATLAB is NOT started from a command shell with the correct OSPL environment variables set, exceptions will occur when attempting to use DDS MATLAB classes.

      +
      +
    4. +
    5. In MATLAB, navigate to file “Vortex_DDS_MATLAB_API.mltbx†by typing:

      +
      cd(fullfile(getenv('OSPL_HOME'),'tools','matlab'))
      +
      +
      +
    6. +
    7. Double click on the file “Vortex_DDS_MATLAB_API.mltbxâ€. This will bring up a dialog entitled Vortex_DDS_MATLAB_API. +Select Install.

      +
    8. +
    +
    +DDS +
    +
    +
    +

    2.4. Examples¶

    +

    Example models have been provided in the examples folder.

    +

    Example: +/INSTALLDIR/Vortex_v2/Device/VortexOpenSplice/6.8.1/HDE/x86_64.linux/tools/matlab/examples/matlab

    +
    +
    + + +
    +
    +
    +
    +
    + +

    Table Of Contents

    + + +

    Previous topic

    +

    1. Introduction

    +

    Next topic

    +

    3. MATLAB API for Vortex DDS Classes

    +

    This Page

    + + + +
    +
    +
    +
    + + + + \ No newline at end of file diff --git a/docs/html/DDSMATLABGuide/introduction.html b/docs/html/DDSMATLABGuide/introduction.html new file mode 100644 index 000000000..b3790ccd4 --- /dev/null +++ b/docs/html/DDSMATLABGuide/introduction.html @@ -0,0 +1,146 @@ + + + + + + + + 1. Introduction — The Vortex OpenSplice MATLAB Guide + + + + + + + + + + + + + + + +
    +
    +
    +
    + +
    +

    1. Introduction¶

    +

    The DDS MATLAB Integration provides users with DDS MATLAB classes to model DDS communication using MATLAB and pure DDS applications.

    +

    Please refer to the DDS and MATLAB documentation for detailed information.

    +
    +

    1.1. DDS¶

    +

    What is DDS?

    +

    “The Data Distribution Service (DDSâ„¢) is a middleware protocol and API standard for data-centric connectivity from the Object Management Group® (OMG®). It integrates the components of a system together, providing low-latency data connectivity, extreme reliability, and a scalable architecture that business and mission-critical Internet of Things (IoT) applications need.â€

    +

    “The main goal of DDS is to share the right data at the right place at the right time, even between time-decoupled publishers and consumers. DDS implements global data space by carefully replicating relevant portions of the logically shared dataspace.†DDS specification

    +
    +DDS +
    +

    Further Documentation

    +

    http://portals.omg.org/dds/

    +

    http://ist.adlinktech.com/

    +
    +
    +

    1.2. MATLAB¶

    +

    What is MATLAB?

    +

    “The Language of Technical Computing

    +

    Millions of engineers and scientists worldwide use MATLAB® to analyze and design the systems and products transforming our world. MATLAB is in automobile active safety systems, interplanetary spacecraft, health monitoring devices, smart power grids, and LTE cellular networks. It is used for machine learning, signal processing, image processing, computer vision, communications, computational finance, control design, robotics, and much more.

    +

    Math. Graphics. Programming.

    +

    The MATLAB platform is optimized for solving engineering and scientific problems. The matrix-based MATLAB language is the world’s most natural way to express computational mathematics. Built-in graphics make it easy to visualize and gain insights from data. A vast library of prebuilt toolboxes lets you get started right away with algorithms essential to your domain. The desktop environment invites experimentation, exploration, and discovery. These MATLAB tools and capabilities are all rigorously tested and designed to work together.

    +

    Scale. Integrate. Deploy.

    +

    MATLAB helps you take your ideas beyond the desktop. You can run your analyses on larger data sets and scale up to clusters and clouds. MATLAB code can be integrated with other languages, enabling you to deploy algorithms and applications within web, enterprise, and production systems.”

    +

    https://www.mathworks.com/products/matlab.html

    +
    +
    + + +
    +
    +
    +
    +
    + +

    Table Of Contents

    + + +

    Previous topic

    +

    DDS MATLAB Guide

    +

    Next topic

    +

    2. Installation

    +

    This Page

    + + + +
    +
    +
    +
    + + + + \ No newline at end of file diff --git a/docs/html/DDSMATLABGuide/objects.inv b/docs/html/DDSMATLABGuide/objects.inv new file mode 100644 index 000000000..b4c85219e --- /dev/null +++ b/docs/html/DDSMATLABGuide/objects.inv @@ -0,0 +1,5 @@ +# Sphinx inventory version 2 +# Project: Vortex OpenSplice MATLAB Guide +# Version: 6.x +# The remainder of this file is compressed using zlib. +xÚm’AO!…ïüŠI4ÞÆÄ«·µ5¦IkÖ¬ñjp¡[V Zÿ½niö²7ï{™vF!OàƒxÔüKjÀ²z£¾M:3e|àZ󠬩í—Bn#3klä!šS¬tÄïA ]mÖ[Ü5ïÛæ‰bˆÃ™ÃÄaâÈ/W‘1V,Ì4ýa)ä±vVµÌÓåU8ØcXlMKï—ÚËÌe[%&µã%wý¡N#-÷Ñ‘¡åƒŒK.¶Õ/-y®ÌKž5Ö[x<ܱAõÒ×¥Np¹añ®fü•$öm=LÎþ(!]+Ÿ¥ByQÁ³÷ÍvÐæ ›”`²ñ#O|œâÆ«¨,b²a²QÞùŠ…jSN›ržI)o&„‡^sï¯'^¯;\Q¡z°`òƒ5íöÖÁ‡u!þ9‘„L²/¹í \ No newline at end of file diff --git a/docs/html/DDSMATLABGuide/qos_provider.html b/docs/html/DDSMATLABGuide/qos_provider.html new file mode 100644 index 000000000..02929979f --- /dev/null +++ b/docs/html/DDSMATLABGuide/qos_provider.html @@ -0,0 +1,190 @@ + + + + + + + + 6. QoS Provider — The Vortex OpenSplice MATLAB Guide + + + + + + + + + + + + + + + +
    +
    +
    +
    + +
    +

    6. QoS Provider¶

    +

    The following section explains how the QoS is set for a DDS entity using the QoS Provider.

    +
    +

    6.1. QoS Provider File¶

    +

    Quality of Service for DDS entities is set using XML files based on the XML schema file QoSProfile.xsd. +These XML files contain one or more QoS profiles for DDS entities. An example with a default QoS profile +for all entity types can be found at DDS_DefaultQoS.xml.

    +

    Note: Sample QoS Profile XML files can be found in the examples directories.

    +
    +
    +

    6.2. QoS Profile¶

    +

    A QoS profile consists of a name and optionally a base_name attribute. The base_name attribute allows a +QoS or a profile to inherit values from another QoS or profile in the same file. The file contains QoS +elements for one or more DDS entities. A skeleton file without any QoS values is displayed below to show +the structure of the file.

    +
    <dds xmlns="http://www.omg.org/dds/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="file:DDS_QoSProfile.xsd">
    +    <qos_profile name="DDS QoS Profile Name">
    +        <datareader_qos></datareader_qos>
    +        <datawriter_qos></datawriter_qos>
    +        <domainparticipant_qos></domainparticipant_qos>
    +        <subscriber_qos></subscriber_qos>
    +        <publisher_qos></publisher_qos>
    +        <topic_qos></topic_qos>
    +    </qos_profile>
    +</dds>
    +
    +
    +

    Example: Specify Publisher Partition

    +

    The example below specifies the publisher’s partitions as A and B.

    +
    <publisher_qos>
    +    <partition>
    +        <name>
    +            <element>A</element>
    +            <element>B</element>
    +        </name>
    +    </partition>
    +</publisher_qos>
    +
    +
    +
    +
    +

    6.3. Setting QoS Profile in MATLAB¶

    +

    To set the QoS profile for a DDS entity in MATLAB the user must specify the File URI and the QoS profile name. +If the file is not specified, the DDS entity will be created with the default QoS values.

    +
    % QOS File
    +PINGER_QOS_FILE = '/home/dds/matlab_examples/pingpong/DDS_PingerVolatileQoS.xml';
    +PINGER_QOS_PROFILE = 'DDS VolatileQosProfile';
    +
    +% create the pinger participant on default domain with specified qos profile
    +dp = Vortex.DomainParticipant(['file://', PINGER_QOS_FILE], PINGER_QOS_PROFILE);
    +
    +
    +

    The file for the above would minimally contain the following <domainparticipant_qos> tag.

    +
    <?xml version="1.0" encoding="UTF-8"?>
    +<dds xmlns="http://www.omg.org/dds/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="file:DDS_QoSProfile.xsd">
    +    <qos_profile name="DDS VolatileQosProfile">
    +        <domainparticipant_qos>
    +            <user_data>
    +                <value></value>
    +            </user_data>
    +            <entity_factory>
    +                <autoenable_created_entities>true</autoenable_created_entities>
    +            </entity_factory>
    +         </domainparticipant_qos>
    +    </qos_profile>
    +</dds>
    +
    +
    +
    +
    + + +
    +
    +
    +
    +
    + +

    Table Of Contents

    + + +

    Previous topic

    +

    5. MATLAB without IDL

    +

    Next topic

    +

    7. Ping Pong Example

    +

    This Page

    + + + +
    +
    +
    +
    + + + + \ No newline at end of file diff --git a/docs/html/DDSMATLABGuide/search.html b/docs/html/DDSMATLABGuide/search.html new file mode 100644 index 000000000..c0ab662b7 --- /dev/null +++ b/docs/html/DDSMATLABGuide/search.html @@ -0,0 +1,101 @@ + + + + + + + + Search — The Vortex OpenSplice MATLAB Guide + + + + + + + + + + + + + + + + + + + +
    +
    +
    +
    + +

    Search

    +
    + +

    + Please activate JavaScript to enable the search + functionality. +

    +
    +

    + From here you can search these documents. Enter your search + words into the box below and click "search". Note that the search + function will automatically search for all of the words. Pages + containing fewer words won't appear in the result list. +

    +
    + + + +
    + +
    + +
    + +
    +
    +
    +
    +
    + +
    +
    +
    +
    + + + + \ No newline at end of file diff --git a/docs/html/DDSMATLABGuide/searchindex.js b/docs/html/DDSMATLABGuide/searchindex.js new file mode 100644 index 000000000..a0462b774 --- /dev/null +++ b/docs/html/DDSMATLABGuide/searchindex.js @@ -0,0 +1 @@ +Search.setIndex({envversion:42,terms:{all:[4,7,2,5,3],code:[4,7,6],edg:3,definit:7,consum:4,four:5,prefix:7,concept:[7,6],follow:[8,7,2,5,6],skeleton:2,profil:[0,7,8],program:[4,7],aris:7,ist_info:3,global:4,string:[5,6],dds_bad_paramet:7,vortex_dds_matlab_api:1,waitsettimeout:7,facebook:3,cellular:4,xmlschema:2,implicitli:7,relev:4,vast:4,dim:6,level:7,list:[7,5],spacecraft:4,correct:1,"try":7,adjust:7,math:4,team:3,straight:6,dimens:5,x86_64:1,properti:[8,5,6],tel:3,autoenable_created_ent:2,natur:4,zero:5,design:4,pass:7,further:4,idlpp:7,click:1,even:4,what:[4,8],sub:7,neg:7,section:[1,2],abl:7,"while":7,cell:6,delet:7,version:2,qos_profil:2,method:[7,5],datareader_qo:2,datast:7,gener:7,let:4,"0xa":3,interpret:5,wait:7,search:0,somealternatedef:7,larger:4,technolog:3,extrem:4,implement:[4,6],dds_pongervolatileqo:8,via:[7,8],primit:6,modul:6,prefer:6,avenu:3,withal:7,"boolean":[5,6],instal:0,installdir:1,select:1,from:7,describ:[7,1,6],would:[7,2,5],commun:[4,7],doubl:[1,5,6],two:8,live:7,busi:4,call:[5,8],tradecent:3,recommend:[7,5],pubordp:7,type:[7,6],more:[4,7,2,6],mltbx:1,uint8:[5,6],visual:4,compani:3,must:[7,2,5,6],uint64:[5,6],graphic:4,scalabl:4,local:7,setup:0,work:4,can:[4,7,2,5,8],learn:4,ddserror:7,control:[4,7],prompt:1,process:[4,7],share:4,accept:5,pinger_qos_fil:2,critic:4,tag:2,fprintf:7,explor:4,disadvantag:5,unsign:5,occur:[7,1],end:[7,5],goal:4,pure:4,anoth:2,write:[7,8],how:2,withanyst:7,abstracttyp:5,simpl:[5,8],ne11:3,product:4,int16:[5,6],recogn:5,ospl:0,vortex_v2:1,oslp_uri:7,them:7,befor:7,membership:7,plane:7,mai:[7,6,3],data:[4,7,8,6],demonstr:8,"short":[5,6],essenti:4,bind:[5,6],explicit:7,robot:4,element:[2,6],inform:[4,3],"switch":[7,6],environ:[4,7,1],allow:[2,5],enter:8,order:7,help:4,insight:4,mission:4,scientist:4,comma:5,entitl:1,still:5,entiti:[7,2],typedef:6,group:4,monitor:4,dds_ret_cod:7,platform:[4,1],window:[1,8],matlab_exampl:2,mail:3,main:[4,8],non:7,good:3,"return":[7,5],greater:1,thei:6,automobil:4,initi:5,bound:5,now:7,introduct:0,name:[7,2],separ:5,timeout:7,each:[7,8],fulli:7,dds_qosprofil:2,compil:[7,6],domain:[4,7,2,8],map:6,idea:4,procedur:1,entity_factori:2,"static":5,connect:4,our:4,beyond:4,dispos:7,out:5,variabl:[7,1,5],safeti:4,network:4,space:4,ret:7,content:6,unsupport:6,health:4,internet:4,uint32:[5,6],red:7,common:7,franc:3,qualifi:7,experiment:4,navig:1,million:4,situat:6,given:7,pub:7,standard:4,reason:[7,6],base:[4,7,2],releas:1,org:[4,2],interplanetari:4,thrown:7,ist:[4,3],filter:7,thing:4,length:6,place:[4,7],lte:4,"5th":3,first:7,oper:[7,1],pleas:4,directli:5,enterpris:4,arrai:[7,6],qualiti:[7,2,8],number:5,restrict:[7,5],done:6,open:1,differ:7,setup_pong:8,script:[1,8],interact:7,system:0,messag:7,setup_ping:8,attach:7,dds_retcode_ok:7,circletop:5,too:6,circl:[7,5],mathwork:4,waitset:7,fullfil:1,"final":5,schema:2,shell:1,arraytop:5,option:[7,2],especi:7,tool:[4,1,8],copi:1,domainid:7,dataspac:4,specifi:[7,2,8],part:3,termin:1,withnotread:7,attempt:1,wchar:6,technic:4,prebuilt:4,provid:[4,0,7,1,8],second:7,structur:[2,6],publisher_qo:2,express:[4,7],entri:7,comput:4,ani:[7,2,6],correspond:7,packag:[7,6],xmln:2,have:[7,1,6],tabl:6,need:[4,7,6],seen:7,pinger_qos_profil:2,engin:4,built:4,equival:[5,6],lic:1,note:[7,1,2],also:7,without:7,take:[4,7],which:[7,5,6],writ:7,singl:[7,5,6],distribut:[4,7],ulong:6,c99:7,object:[4,7,5],most:[4,7,5],rigor:4,artifact:6,deploi:4,analyz:4,model:[4,7,1],homogen:6,uri:[7,2],destruct:7,doe:[7,8],adlink:3,show:[7,2,5,6],carefulli:4,syntax:6,bring:1,identifi:[7,5],xml:[2,8],current:7,onli:7,explicitli:7,copyright:3,explain:2,activ:4,state:7,latenc:4,withnew:7,folder:[1,6],analys:4,hit:8,shapetyp:[7,5],get:4,financ:4,classdef:5,nativ:6,cannot:[7,5],report:7,toolbox:4,requir:[0,7,6],bat:1,enabl:4,"float":[5,6],integr:[4,7,1,8,6],partit:[7,2,8],contain:[7,1,2,3],where:6,vision:4,set:[4,0,7,1,8],volatileqosprofil:2,datatyp:6,see:7,centric:4,result:7,respons:7,reserv:3,ddsreturncod:7,subject:3,statu:7,base_nam:2,heterogen:6,particip:[7,2,8],discoveri:4,written:7,between:4,awai:4,previous:7,approach:5,shapesdemo:7,attribut:2,qosfileuri:7,omg:[4,2],kei:[7,5],rostand:3,extens:8,solv:4,both:6,pinger_pong:8,howev:6,ushort:6,instanc:[7,2],logic:[4,5,6],whole:3,comment:6,color:[7,5],dispatch:7,linux:1,pingpongtyp:8,summar:6,liabil:3,java:1,sarl:3,union:6,qosprofil:[7,2],been:[7,1],mark:7,compon:4,much:4,valu:[7,2,6],basic:8,quickli:5,imag:4,dds_defaultqo:2,togeth:4,workspac:7,homogenen:6,"catch":7,"case":[7,6],replic:4,multi:6,pinger:[2,8],servic:[4,7,2,8],invit:4,defin:[7,8,5,6],hde:1,match:7,abov:2,error:7,gateshead:3,applic:[4,7],worldwid:4,user_data:2,linkedin:3,cluster:4,topic_qo:2,ddsstatu:7,minim:2,receiv:7,make:[4,7,5,6],same:[7,1,2,5],domainparticipant_qo:2,html:4,decod:7,failur:7,document:[4,3],difficult:6,http:[4,2,3],optim:4,nest:6,iot:4,upon:7,capabl:[4,8],rais:7,portal:4,user:[4,2],decoupl:4,typic:7,appropri:[1,5],com:[4,1,3],inherit:[2,5,6],exampl:[7,5],command:[1,8],thi:[1,3,5,6,7,8],jean:3,woburn:3,explan:8,protocol:4,less:5,ponger:8,shape:7,languag:[4,5],getkei:5,web:[4,3],struct:[7,5,6],easi:4,except:[1,5],desktop:4,uint16:[5,6],subsequ:7,smart:4,int32:[5,6],subscriber_qo:2,ospl_hom:[1,8],read:[7,8],adlinktech:[4,3],wstring:6,datawriter_qo:2,grid:4,world:4,licens:1,success:7,specif:[4,7],corpor:3,signal:4,manual:7,integ:7,shapes:5,either:7,xsd:2,xsi:2,page:0,underli:7,www:[4,2,3],right:[4,3],vortexopensplic:1,acknowledg:3,twitter:3,creation:[7,5],some:6,sampl:[8,7,2,6],home:2,librari:[4,7],scale:4,rethrow:7,octet:[5,6],datawrit:7,mathemat:4,exit:7,middlewar:4,condit:7,reproduc:3,refer:[4,7],machin:4,core:7,power:4,win64:1,"enum":[5,6],rue:3,found:[2,8],"throw":7,dcp:7,chapter:6,faith:3,usa:3,int64:[5,6],manag:4,idl:7,includ:[7,1],dialog:1,adlinktech_usa:3,opensplic:[0,3,5,6,7,8],trademark:3,within:[4,7],encod:2,orsai:3,unregist:7,dds_retcode_inconsistent_polici:7,empti:7,subordp:7,chang:[7,3],your:[4,7],wai:[4,5],pingpong:[2,8],support:7,vallei:3,question:7,transform:4,"long":[5,6],custom:7,avail:[7,5,3],start:[4,7,1,5,6],low:4,suit:3,forward:6,"function":5,schemaloc:2,getenv:1,cloud:4,link:7,gain:4,line:1,inlin:6,"true":2,int8:[5,6],count:8,made:3,utf:2,consist:2,possibl:[7,5],"default":[7,2,8],access:7,displai:2,below:[2,8],otherwis:7,problem:4,creat:7,mask:7,repres:[7,5,8],"char":[7,5,6],exist:7,file:[7,6],check:6,when:[7,1,5],detail:[4,7,6],field:[5,6],other:[4,7,5],test:4,you:[4,7,5],architectur:4,sequenc:[7,5,6],devic:[4,1],matrix:4,algorithm:4,scientif:4,directori:[1,2,8],reliabl:[4,5],dataread:7,dds_pingervolatileqo:[2,8],portion:4,time:[4,7]},objtypes:{},objnames:{},filenames:["index","installation","qos_provider","contacts","introduction","IDLless-MATLAB","IDL-MATLAB","DDS-Classes","example-ping-pong"],titles:["DDS MATLAB Guide","2. Installation","6. QoS Provider","8. Contacts & Notices","1. Introduction","5. MATLAB without IDL","4. MATLAB Generation from IDL","3. MATLAB API for Vortex DDS Classes","7. Ping Pong Example"],objects:{},titleterms:{set:2,opensplic:1,queri:7,arrai:5,domainparticip:7,topic:[7,5],api:7,file:[2,8],tabl:0,instal:1,pong:8,guid:0,idlpp:6,from:6,creat:5,pattern:7,support:6,writer:7,ping:8,system:1,publish:7,profil:2,unsupport:5,matlab:[0,1,2,4,5,6,7],reader:7,type:5,map:5,run:[8,6],without:5,vortex:7,gener:6,subscrib:7,usag:7,notic:3,step:8,indic:0,"class":[7,5],requir:1,introduct:4,provid:2,setup:1,exampl:[1,8],idl:[5,6],contact:3,limit:6,ddsexcept:7,ospl:1}}) \ No newline at end of file diff --git a/docs/html/DDSSimulinkGuide/_images/addBus.png b/docs/html/DDSSimulinkGuide/_images/addBus.png new file mode 100644 index 000000000..d1f1f9e2f Binary files /dev/null and b/docs/html/DDSSimulinkGuide/_images/addBus.png differ diff --git a/docs/html/DDSSimulinkGuide/_images/addBusElement.png b/docs/html/DDSSimulinkGuide/_images/addBusElement.png new file mode 100644 index 000000000..c9cd9bfe2 Binary files /dev/null and b/docs/html/DDSSimulinkGuide/_images/addBusElement.png differ diff --git a/docs/html/DDSSimulinkGuide/_images/addShapeType.png b/docs/html/DDSSimulinkGuide/_images/addShapeType.png new file mode 100644 index 000000000..42dda505b Binary files /dev/null and b/docs/html/DDSSimulinkGuide/_images/addShapeType.png differ diff --git a/docs/html/DDSSimulinkGuide/_images/busExport.png b/docs/html/DDSSimulinkGuide/_images/busExport.png new file mode 100644 index 000000000..7125e686f Binary files /dev/null and b/docs/html/DDSSimulinkGuide/_images/busExport.png differ diff --git a/docs/html/DDSSimulinkGuide/_images/buscreator_constants.png b/docs/html/DDSSimulinkGuide/_images/buscreator_constants.png new file mode 100644 index 000000000..a6ffe4bc9 Binary files /dev/null and b/docs/html/DDSSimulinkGuide/_images/buscreator_constants.png differ diff --git a/docs/html/DDSSimulinkGuide/_images/colorBusElement.png b/docs/html/DDSSimulinkGuide/_images/colorBusElement.png new file mode 100644 index 000000000..dffeea454 Binary files /dev/null and b/docs/html/DDSSimulinkGuide/_images/colorBusElement.png differ diff --git a/docs/html/DDSSimulinkGuide/_images/colorConstant2.png b/docs/html/DDSSimulinkGuide/_images/colorConstant2.png new file mode 100644 index 000000000..68fa308d2 Binary files /dev/null and b/docs/html/DDSSimulinkGuide/_images/colorConstant2.png differ diff --git a/docs/html/DDSSimulinkGuide/_images/constant_x.png b/docs/html/DDSSimulinkGuide/_images/constant_x.png new file mode 100644 index 000000000..4a0e85c27 Binary files /dev/null and b/docs/html/DDSSimulinkGuide/_images/constant_x.png differ diff --git a/docs/html/DDSSimulinkGuide/_images/ddsLibrary.png b/docs/html/DDSSimulinkGuide/_images/ddsLibrary.png new file mode 100644 index 000000000..b4b086257 Binary files /dev/null and b/docs/html/DDSSimulinkGuide/_images/ddsLibrary.png differ diff --git a/docs/html/DDSSimulinkGuide/_images/dds_overview.png b/docs/html/DDSSimulinkGuide/_images/dds_overview.png new file mode 100644 index 000000000..c7490ddb4 Binary files /dev/null and b/docs/html/DDSSimulinkGuide/_images/dds_overview.png differ diff --git a/docs/html/DDSSimulinkGuide/_images/default_qos_params.png b/docs/html/DDSSimulinkGuide/_images/default_qos_params.png new file mode 100644 index 000000000..02b9bfe60 Binary files /dev/null and b/docs/html/DDSSimulinkGuide/_images/default_qos_params.png differ diff --git a/docs/html/DDSSimulinkGuide/_images/domain_block.png b/docs/html/DDSSimulinkGuide/_images/domain_block.png new file mode 100644 index 000000000..812c58541 Binary files /dev/null and b/docs/html/DDSSimulinkGuide/_images/domain_block.png differ diff --git a/docs/html/DDSSimulinkGuide/_images/domain_block_parameters.png b/docs/html/DDSSimulinkGuide/_images/domain_block_parameters.png new file mode 100644 index 000000000..666779a11 Binary files /dev/null and b/docs/html/DDSSimulinkGuide/_images/domain_block_parameters.png differ diff --git a/docs/html/DDSSimulinkGuide/_images/linuxCodeGenNoANSI_OPTS.png b/docs/html/DDSSimulinkGuide/_images/linuxCodeGenNoANSI_OPTS.png new file mode 100644 index 000000000..cc1465e51 Binary files /dev/null and b/docs/html/DDSSimulinkGuide/_images/linuxCodeGenNoANSI_OPTS.png differ diff --git a/docs/html/DDSSimulinkGuide/_images/linuxIDLPP_SLDD_ChangedNames.png b/docs/html/DDSSimulinkGuide/_images/linuxIDLPP_SLDD_ChangedNames.png new file mode 100644 index 000000000..e4df8d5b8 Binary files /dev/null and b/docs/html/DDSSimulinkGuide/_images/linuxIDLPP_SLDD_ChangedNames.png differ diff --git a/docs/html/DDSSimulinkGuide/_images/linuxInstall1.png b/docs/html/DDSSimulinkGuide/_images/linuxInstall1.png new file mode 100644 index 000000000..2a85c4209 Binary files /dev/null and b/docs/html/DDSSimulinkGuide/_images/linuxInstall1.png differ diff --git a/docs/html/DDSSimulinkGuide/_images/linuxInstall2.png b/docs/html/DDSSimulinkGuide/_images/linuxInstall2.png new file mode 100644 index 000000000..cd75ee2fa Binary files /dev/null and b/docs/html/DDSSimulinkGuide/_images/linuxInstall2.png differ diff --git a/docs/html/DDSSimulinkGuide/_images/modBlock.png b/docs/html/DDSSimulinkGuide/_images/modBlock.png new file mode 100644 index 000000000..ba6d9f5b4 Binary files /dev/null and b/docs/html/DDSSimulinkGuide/_images/modBlock.png differ diff --git a/docs/html/DDSSimulinkGuide/_images/modBlock2.png b/docs/html/DDSSimulinkGuide/_images/modBlock2.png new file mode 100644 index 000000000..6e059e5f4 Binary files /dev/null and b/docs/html/DDSSimulinkGuide/_images/modBlock2.png differ diff --git a/docs/html/DDSSimulinkGuide/_images/modelExplorer.png b/docs/html/DDSSimulinkGuide/_images/modelExplorer.png new file mode 100644 index 000000000..ea80d9414 Binary files /dev/null and b/docs/html/DDSSimulinkGuide/_images/modelExplorer.png differ diff --git a/docs/html/DDSSimulinkGuide/_images/openBusEditor.png b/docs/html/DDSSimulinkGuide/_images/openBusEditor.png new file mode 100644 index 000000000..9a2b6cc67 Binary files /dev/null and b/docs/html/DDSSimulinkGuide/_images/openBusEditor.png differ diff --git a/docs/html/DDSSimulinkGuide/_images/openLibraryBrowser.png b/docs/html/DDSSimulinkGuide/_images/openLibraryBrowser.png new file mode 100644 index 000000000..2c53c6b93 Binary files /dev/null and b/docs/html/DDSSimulinkGuide/_images/openLibraryBrowser.png differ diff --git a/docs/html/DDSSimulinkGuide/_images/persistent_qos_params.png b/docs/html/DDSSimulinkGuide/_images/persistent_qos_params.png new file mode 100644 index 000000000..21cd7d768 Binary files /dev/null and b/docs/html/DDSSimulinkGuide/_images/persistent_qos_params.png differ diff --git a/docs/html/DDSSimulinkGuide/_images/publisher_block.png b/docs/html/DDSSimulinkGuide/_images/publisher_block.png new file mode 100644 index 000000000..fc3b2bd17 Binary files /dev/null and b/docs/html/DDSSimulinkGuide/_images/publisher_block.png differ diff --git a/docs/html/DDSSimulinkGuide/_images/publisher_block_parameters.png b/docs/html/DDSSimulinkGuide/_images/publisher_block_parameters.png new file mode 100644 index 000000000..1bc354e7a Binary files /dev/null and b/docs/html/DDSSimulinkGuide/_images/publisher_block_parameters.png differ diff --git a/docs/html/DDSSimulinkGuide/_images/read_blocks.png b/docs/html/DDSSimulinkGuide/_images/read_blocks.png new file mode 100644 index 000000000..3f91df58d Binary files /dev/null and b/docs/html/DDSSimulinkGuide/_images/read_blocks.png differ diff --git a/docs/html/DDSSimulinkGuide/_images/read_busSelectorOutputs.png b/docs/html/DDSSimulinkGuide/_images/read_busSelectorOutputs.png new file mode 100644 index 000000000..f0e959dfb Binary files /dev/null and b/docs/html/DDSSimulinkGuide/_images/read_busSelectorOutputs.png differ diff --git a/docs/html/DDSSimulinkGuide/_images/read_busSelector_display.png b/docs/html/DDSSimulinkGuide/_images/read_busSelector_display.png new file mode 100644 index 000000000..d38213b1b Binary files /dev/null and b/docs/html/DDSSimulinkGuide/_images/read_busSelector_display.png differ diff --git a/docs/html/DDSSimulinkGuide/_images/read_connect.png b/docs/html/DDSSimulinkGuide/_images/read_connect.png new file mode 100644 index 000000000..d92d7d264 Binary files /dev/null and b/docs/html/DDSSimulinkGuide/_images/read_connect.png differ diff --git a/docs/html/DDSSimulinkGuide/_images/read_model_settings.png b/docs/html/DDSSimulinkGuide/_images/read_model_settings.png new file mode 100644 index 000000000..d82dd6d8b Binary files /dev/null and b/docs/html/DDSSimulinkGuide/_images/read_model_settings.png differ diff --git a/docs/html/DDSSimulinkGuide/_images/read_topic_topic.png b/docs/html/DDSSimulinkGuide/_images/read_topic_topic.png new file mode 100644 index 000000000..dbe6a9298 Binary files /dev/null and b/docs/html/DDSSimulinkGuide/_images/read_topic_topic.png differ diff --git a/docs/html/DDSSimulinkGuide/_images/reader_block.png b/docs/html/DDSSimulinkGuide/_images/reader_block.png new file mode 100644 index 000000000..a41c7f24d Binary files /dev/null and b/docs/html/DDSSimulinkGuide/_images/reader_block.png differ diff --git a/docs/html/DDSSimulinkGuide/_images/reader_block_parameters.png b/docs/html/DDSSimulinkGuide/_images/reader_block_parameters.png new file mode 100644 index 000000000..27bec302a Binary files /dev/null and b/docs/html/DDSSimulinkGuide/_images/reader_block_parameters.png differ diff --git a/docs/html/DDSSimulinkGuide/_images/reader_filters_tab.png b/docs/html/DDSSimulinkGuide/_images/reader_filters_tab.png new file mode 100644 index 000000000..de09fdacb Binary files /dev/null and b/docs/html/DDSSimulinkGuide/_images/reader_filters_tab.png differ diff --git a/docs/html/DDSSimulinkGuide/_images/results.png b/docs/html/DDSSimulinkGuide/_images/results.png new file mode 100644 index 000000000..a14ff5d73 Binary files /dev/null and b/docs/html/DDSSimulinkGuide/_images/results.png differ diff --git a/docs/html/DDSSimulinkGuide/_images/run.png b/docs/html/DDSSimulinkGuide/_images/run.png new file mode 100644 index 000000000..27760626a Binary files /dev/null and b/docs/html/DDSSimulinkGuide/_images/run.png differ diff --git a/docs/html/DDSSimulinkGuide/_images/shapesizeBusElement.png b/docs/html/DDSSimulinkGuide/_images/shapesizeBusElement.png new file mode 100644 index 000000000..cbabbf03b Binary files /dev/null and b/docs/html/DDSSimulinkGuide/_images/shapesizeBusElement.png differ diff --git a/docs/html/DDSSimulinkGuide/_images/shapesizeConstantBLock.png b/docs/html/DDSSimulinkGuide/_images/shapesizeConstantBLock.png new file mode 100644 index 000000000..31d9068df Binary files /dev/null and b/docs/html/DDSSimulinkGuide/_images/shapesizeConstantBLock.png differ diff --git a/docs/html/DDSSimulinkGuide/_images/simulinkStartPage.png b/docs/html/DDSSimulinkGuide/_images/simulinkStartPage.png new file mode 100644 index 000000000..1d1f3000b Binary files /dev/null and b/docs/html/DDSSimulinkGuide/_images/simulinkStartPage.png differ diff --git a/docs/html/DDSSimulinkGuide/_images/sineWaveBlockParamters.png b/docs/html/DDSSimulinkGuide/_images/sineWaveBlockParamters.png new file mode 100644 index 000000000..220200f34 Binary files /dev/null and b/docs/html/DDSSimulinkGuide/_images/sineWaveBlockParamters.png differ diff --git a/docs/html/DDSSimulinkGuide/_images/sinewave.png b/docs/html/DDSSimulinkGuide/_images/sinewave.png new file mode 100644 index 000000000..14497d2e7 Binary files /dev/null and b/docs/html/DDSSimulinkGuide/_images/sinewave.png differ diff --git a/docs/html/DDSSimulinkGuide/_images/startSimulink.png b/docs/html/DDSSimulinkGuide/_images/startSimulink.png new file mode 100644 index 000000000..dddfac90c Binary files /dev/null and b/docs/html/DDSSimulinkGuide/_images/startSimulink.png differ diff --git a/docs/html/DDSSimulinkGuide/_images/sub_annotations_qos.png b/docs/html/DDSSimulinkGuide/_images/sub_annotations_qos.png new file mode 100644 index 000000000..0ee32f463 Binary files /dev/null and b/docs/html/DDSSimulinkGuide/_images/sub_annotations_qos.png differ diff --git a/docs/html/DDSSimulinkGuide/_images/subscriber_block.png b/docs/html/DDSSimulinkGuide/_images/subscriber_block.png new file mode 100644 index 000000000..5a5a2dd15 Binary files /dev/null and b/docs/html/DDSSimulinkGuide/_images/subscriber_block.png differ diff --git a/docs/html/DDSSimulinkGuide/_images/subscriber_block_parameters.png b/docs/html/DDSSimulinkGuide/_images/subscriber_block_parameters.png new file mode 100644 index 000000000..37b33a45e Binary files /dev/null and b/docs/html/DDSSimulinkGuide/_images/subscriber_block_parameters.png differ diff --git a/docs/html/DDSSimulinkGuide/_images/topic_block.png b/docs/html/DDSSimulinkGuide/_images/topic_block.png new file mode 100644 index 000000000..e5170e28b Binary files /dev/null and b/docs/html/DDSSimulinkGuide/_images/topic_block.png differ diff --git a/docs/html/DDSSimulinkGuide/_images/topic_block_parameters.png b/docs/html/DDSSimulinkGuide/_images/topic_block_parameters.png new file mode 100644 index 000000000..48398ab10 Binary files /dev/null and b/docs/html/DDSSimulinkGuide/_images/topic_block_parameters.png differ diff --git a/docs/html/DDSSimulinkGuide/_images/upDownBusElement.png b/docs/html/DDSSimulinkGuide/_images/upDownBusElement.png new file mode 100644 index 000000000..80ac9f72b Binary files /dev/null and b/docs/html/DDSSimulinkGuide/_images/upDownBusElement.png differ diff --git a/docs/html/DDSSimulinkGuide/_images/write_buscreator_params.png b/docs/html/DDSSimulinkGuide/_images/write_buscreator_params.png new file mode 100644 index 000000000..ab342d2ae Binary files /dev/null and b/docs/html/DDSSimulinkGuide/_images/write_buscreator_params.png differ diff --git a/docs/html/DDSSimulinkGuide/_images/write_connect_domain.png b/docs/html/DDSSimulinkGuide/_images/write_connect_domain.png new file mode 100644 index 000000000..334c3ff01 Binary files /dev/null and b/docs/html/DDSSimulinkGuide/_images/write_connect_domain.png differ diff --git a/docs/html/DDSSimulinkGuide/_images/write_domain_parameters.png b/docs/html/DDSSimulinkGuide/_images/write_domain_parameters.png new file mode 100644 index 000000000..2d0ba6864 Binary files /dev/null and b/docs/html/DDSSimulinkGuide/_images/write_domain_parameters.png differ diff --git a/docs/html/DDSSimulinkGuide/_images/write_mathFunctionBlockParams.png b/docs/html/DDSSimulinkGuide/_images/write_mathFunctionBlockParams.png new file mode 100644 index 000000000..2cdb32c6e Binary files /dev/null and b/docs/html/DDSSimulinkGuide/_images/write_mathFunctionBlockParams.png differ diff --git a/docs/html/DDSSimulinkGuide/_images/write_model_setup.png b/docs/html/DDSSimulinkGuide/_images/write_model_setup.png new file mode 100644 index 000000000..939797064 Binary files /dev/null and b/docs/html/DDSSimulinkGuide/_images/write_model_setup.png differ diff --git a/docs/html/DDSSimulinkGuide/_images/write_topic_parameters.png b/docs/html/DDSSimulinkGuide/_images/write_topic_parameters.png new file mode 100644 index 000000000..22bf10b91 Binary files /dev/null and b/docs/html/DDSSimulinkGuide/_images/write_topic_parameters.png differ diff --git a/docs/html/DDSSimulinkGuide/_images/writer_block.png b/docs/html/DDSSimulinkGuide/_images/writer_block.png new file mode 100644 index 000000000..4074aa42b Binary files /dev/null and b/docs/html/DDSSimulinkGuide/_images/writer_block.png differ diff --git a/docs/html/DDSSimulinkGuide/_images/writer_block_parameters.png b/docs/html/DDSSimulinkGuide/_images/writer_block_parameters.png new file mode 100644 index 000000000..aeaa16081 Binary files /dev/null and b/docs/html/DDSSimulinkGuide/_images/writer_block_parameters.png differ diff --git a/docs/html/DDSSimulinkGuide/_images/writer_write_parameters.png b/docs/html/DDSSimulinkGuide/_images/writer_write_parameters.png new file mode 100644 index 000000000..7b8caaa42 Binary files /dev/null and b/docs/html/DDSSimulinkGuide/_images/writer_write_parameters.png differ diff --git a/docs/html/DDSSimulinkGuide/_images/xBusElement.png b/docs/html/DDSSimulinkGuide/_images/xBusElement.png new file mode 100644 index 000000000..90d300b6f Binary files /dev/null and b/docs/html/DDSSimulinkGuide/_images/xBusElement.png differ diff --git a/docs/html/DDSSimulinkGuide/_images/xyGraph2.png b/docs/html/DDSSimulinkGuide/_images/xyGraph2.png new file mode 100644 index 000000000..953e58ecc Binary files /dev/null and b/docs/html/DDSSimulinkGuide/_images/xyGraph2.png differ diff --git a/docs/html/DDSSimulinkGuide/_images/yBusElement.png b/docs/html/DDSSimulinkGuide/_images/yBusElement.png new file mode 100644 index 000000000..fa2fa98fb Binary files /dev/null and b/docs/html/DDSSimulinkGuide/_images/yBusElement.png differ diff --git a/docs/html/DDSSimulinkGuide/_sources/blocks.txt b/docs/html/DDSSimulinkGuide/_sources/blocks.txt new file mode 100644 index 000000000..2ef6a6c7d --- /dev/null +++ b/docs/html/DDSSimulinkGuide/_sources/blocks.txt @@ -0,0 +1,89 @@ +.. _`Vortex DDS Blocks`: + + +################# +Vortex DDS Blocks +################# + + +The DDS Simulink Integration provides a block library with custom blocks to model reading and writing data with DDS. + +The Vortex DDS Simulink block library provides blocks which correspond to DDS entities. (Each DDS block is covered in its own section in this user guide.) + +The following DDS block types are provided: + + - Topic + - Domain + - Publisher + - Subscriber + - Writer + - Reader + +Optional DDS Blocks and Ports +***************************** + +Some of the DDS blocks are optional. (Domain, Publisher and Subscriber) + +When the optional blocks are not added to model diagrams, defaults are used. This allows for simpler model diagrams. +If the model requires block parameter customization, the optional blocks can be added to a model to use non-default settings. + +Many of the ports for the DDS blocks are also optional. They can be toggled on or off in the **Block Parameters** dialog, in the **Ports** tab. + +QoS Profiles +************ + +In DDS - “The Data-Distribution Service (DDS) relies on the usage of QoS. A QoS (Quality of Service) is a set of characteristics that controls some aspect of the behavior of the DDS Service." + +Each DDS block has an associated QoS profile. By default, the OSPL default profile is used. An XML file that specifies QoS profiles can be used to set the QoS of a DDS block. + +The QoS profile of a block is set in the **QoS** tab of the **Block Parameters** dialog. (This dialog is opened by double clicking on a selected block.) + + +Please see section :ref:`QoS Provider` for more information. + +.. raw:: latex + + \newpage + +Simulink Block Sample Time +************************** + +**"What is sample time?"** + +**"The sample time of a block is a parameter that indicates when, during simulation, the block produces outputs and if appropriate, updates its internal state." +-Simulink documentation** + + + +The DDS blocks have different sample times set. The only DDS block that allows for the user specification of a sample time is the **Reader** block. +A reader's sample time can be set in the **Block Parameters** **Data** tab. + +A sample time of 0 means that the block step will only execute once. + +A sample time of -1 means that the block will inherit its sample time from its inputs or from the parent model. + + ++---------------------+--------------------------------------+ +|DDS Block Type |Sample Time | ++=====================+======================================+ +|Topic | -1 (inherits) uneditable | ++---------------------+--------------------------------------+ +|Domain | -1 (inherits) uneditable | ++---------------------+--------------------------------------+ +|Publisher | -1 (inherits) uneditable | ++---------------------+--------------------------------------+ +|Subscriber | -1 (inherits) uneditable | ++---------------------+--------------------------------------+ +|Writer | -1 (inherits) uneditable | ++---------------------+--------------------------------------+ +|Reader | - default -1 (inherits) editable | +| | - Inherits from inputs or model | +| | - Valid values: -1 and Numeric > 0 | ++---------------------+--------------------------------------+ + + + + + + + diff --git a/docs/html/DDSSimulinkGuide/_sources/bus-dds.txt b/docs/html/DDSSimulinkGuide/_sources/bus-dds.txt new file mode 100644 index 000000000..e9de907fa --- /dev/null +++ b/docs/html/DDSSimulinkGuide/_sources/bus-dds.txt @@ -0,0 +1,258 @@ +.. _`Simulink Bus to DDS Topic Mapping`: + + +################################# +Simulink Bus to DDS Topic Mapping +################################# + +Simulink data is represented in buses whose types are not compatible with DDS topic data types. + +When using the Simulink Vortex DDS library, the user must create Simulink buses that will be mapped to DDS topic types. + +The Vortex DDS **Reader**, **Writer** and **Topic** blocks have block parameters that require a Simulink bus type. On data writes, the Simulink bus types are converted to DDS topic types and on data reads, the DDS topic types are converted to Simulink bus types. + +The user can generate/create the Simulink bus definitions by either generating them from an IDL file, or by using the Simulink bus editor. + + +Generate Simulink bus definitions from an IDL file +************************************************** + +DDS Topic Types can be described in an IDL file. The public Vortex.idlImportSl function can be called to generate Simulink bus definitions from an IDL file. + +**idlImportSl(IDLFILENAME,DICTIONARYFILE)** + + Given an IDLFILENAME, invokes the idlpp tool to generate a MATLAB script. + This script is then used to create Simulink.Bus objects and import them into the specified data dictionary DICTIONARYFILE. + The values are inserted into the 'Design Data' section of the data dictionary. + If the target data dictionary already contains definitions for the bus or enum names, they are overwritten. + If idlpp returns non-zero, the function returns immediately with the error code. + + Input Arguments: + + IDLFILENAME A character array with the value of the IDL file name to process. + + DICTIONARYFILE A character array with the value of the data dictionary file name. + + +**Steps:** + +1. In the IDL file, ensure that any topic structures have the OSPL specific annotation *pragma keylist* defined. + + If you want a given IDL structure to serve as the topic type, the structure requires an OSPL specific annotation. + The #pragma keylist * declaration should be defined after the structure declaration. + + IMPORTANT NOTE: The IDL file has to have a blank line after the pragma keylist declaration. (BUG) + + More information can be found at: IDLPreProcGuide_ + +2. In MATLAB, navigate to the directory that contains the IDL file. Set this directory to be the MATLAB **Current Folder**. + +3. Call the idlImportSl function in the MATLAB command window. + + Example: + >> Vortex.idlImportSl('ShapeType.idl', 'shape.sldd') + + +Overriding default values for Vortex.idlImportSl +************************************************ + +The ``Vortex.idlImportSl`` function makes a number assumptions when generating a Simulink data dictionary +from your IDL file. These are documented in the following table: + ++-------------------------+---------------------------------+ +| **IDL Element** | **Default Simulink Equivalent** | ++=========================+=================================+ +| struct name | Unqualified bus name | ++-------------------------+---------------------------------+ +| enum name | Unqualified enum name | ++-------------------------+---------------------------------+ +| sequence<*T*, *N*> name | *seqN_T* | ++-------------------------+---------------------------------+ +| sequence<*T*> name | *seq_T* | ++-------------------------+---------------------------------+ +| unbounded string | maximum 256 characters | ++-------------------------+---------------------------------+ +| unbounded sequence | maximum 16 elements | ++-------------------------+---------------------------------+ + +The following subsections illustrate how to override each of these defaults. + +Overriding struct and enum names +++++++++++++++++++++++++++++++++ + +IDL allows you to describe a hierarchical set of namespaces for structs and enums by defining modules. +Simulink, however, has a flat namespace for all busses and enumerations. +This can present problems when the same unqualified struct name is used to two or more different modules. + +Consider the following idl:: + + module A { + enum Status { + INFO, + WARNING, + ERROR + }; + struct Message { + long id; + Status status; + }; + #pragma keylist Message id + }; + + module B { + enum Status { + SUCCESS, + FAILURE + }; + struct Message { + long id; + Status status; + }; + #pragma keylist Message id + }; + +In it, both ``Status`` and ``Message`` are used in the context of both module A and module B. When you run ``Vortex.idlImportSl`` against it, +you will receive the following messages:: + + Error: IDL element B::Status translates to the Simulink artifact named Status, + which already corresponds to another IDL element A::Status. + Edit the idl_defaults.properties file to assign unique Simulink names to each IDL element. + + Error: IDL element B::Message translates to the Simulink artifact named Message, + which already corresponds to another IDL element A::Message. + Edit the idl_defaults.properties file to assign unique Simulink names to each IDL element. + +To help you solve the problem, the IDL import function generates a *properties file* with the same name as the original IDL file, but with a *properties* extension. +Here is the generated properties file:: + + # + # + # To change the generated Simulink element, change one or more values in this file, and then + # re-run the IDL import. + + A::Message#name = Message + A::Status#name = Status + B::Message#name = Message + B::Status#name = Status + +The properties file shows the names the IDL import attempted to used. Each line is of the format:: + + #name = + +You can modify any value after the equals sign (=), to create a unique name. Once you have finished +editing the properties file, re-run the IDL import to update actual Simulink entities. + +Suppose we make the following changes to the properties file:: + + A::Message#name = MessageA + A::Status#name = StatusA + B::Message#name = Message + B::Status#name = Status + +On re-running ``Vortex.idlImportSl``, the generated Simulink data dictionary would have contents as seen in the figure below. + +.. figure:: images/linuxIDLPP_SLDD_ChangedNames.png + :alt: DDS + + *View of generated Simulink Data Dictionary, showing renamed busses and enumerations*. + +Changing unbound string maximum sizes ++++++++++++++++++++++++++++++++++++++ + +Although IDL unbound strings can be of any length, in Simulink they are mapped to fixed length arrays of int8. +The default length the ``Vortex.idlImportSl`` assigns to such arrays is 256 characters. +You can change this default value, per string, using the generated properties file. + +Suppose we modify A::Message to contain a string field:: + + module A { + enum Status { + INFO, + WARNING, + ERROR + }; + struct Message { + long id; + Status status; + string body; + }; + #pragma keylist Message id + }; + +On running the IDL import, the properties file would be updated to show a new line:: + + A::Message.body#stringMax = 256 + +Changes the value to something new (say 128), and rerun the IDL import to update the generated Simulink bus. + +Changing sequence attributes +++++++++++++++++++++++++++++ + +IDL import generates a simulink bus for each IDL sequence discovered. For an unbound sequence, the default +name for such sequences is *seq_T*, where *T* is the type of elements in the sequence. +For bounded sequences, the default sequence name is *seqN_T*, where *N* is the declared upper bound of the sequence. + +The following IDL enhances our example IDL to use a sequence of string field for the body attribute:: + + module A { + enum Status { + INFO, + WARNING, + ERROR + }; + struct Message { + long id; + Status status; + sequence body; + }; + #pragma keylist Message id + }; + +On running IDL import, the generated property file now contains the following lines:: + + A::Message.seq_string#name = seq_string + A::Message.seq_string#seqMax = 16 + A::Message.seq_string#stringMax = 256 + +You can edit the value of ``A::Message.seq_string#name`` to change the name of the generated Simulink bus representing the sequences. +You can change the maximum number of elements stored in the Simulink representation of the sequence by editing ``A::Message.seq_string#seqMax``. +Finally, because the type of elements in this sequence are unbounded strings, you can also change the maximum size of each string in the sequence (``A::Message.seq_string#stringMax``). + +Add Simulink bus definitions using bus editor +********************************************* + +Users can also model the Simulink buses using the Simulink bus editor. + +Please see :ref:`Tutorial` for an example with detailed steps. + + +Bus definition limitations +************************** + +The DDS Simulink integration has some limitations. Provided below is a table of unsupported types. +Some of these bus definition limitations will be removed in later release(s). + +Please refer to :ref:`Appendix A` for more detailed implementation details. + + +-------------------------------+ + |Unsupported Simulink Types | + +===============================+ + | long long | + +-------------------------------+ + | unsigned long long | + +-------------------------------+ + | wchar | + +-------------------------------+ + | wstring | + +-------------------------------+ + | any | + +-------------------------------+ + | long double | + +-------------------------------+ + | union | + +-------------------------------+ + | inheritance | + +-------------------------------+ + +See also IDL PreProcessor Guide chapter Keys. + diff --git a/docs/html/DDSSimulinkGuide/_sources/bus_to_dds_mapping.txt b/docs/html/DDSSimulinkGuide/_sources/bus_to_dds_mapping.txt new file mode 100644 index 000000000..ed35afc62 --- /dev/null +++ b/docs/html/DDSSimulinkGuide/_sources/bus_to_dds_mapping.txt @@ -0,0 +1,172 @@ +.. _`Appendix A`: + +########## +Appendix A +########## + +Appendix A provides a description of the Simulink Bus to DDS Mapping implementation. + +Simulink Bus to DDS Mapping +*************************** + +Simulink data is represented in buses whose types are not compatable with DDS types. +Therfore sending Simulink data to DDS requires a conversion from Simulink types to DDS types. +Conversly sending DDS data to Simulink requires a conversion from DDS types to Simulink types. +This document describes the mapping between these types, the type descriptors generated for Topic +registration and any annotations needed to describe keys, namespaces, ... for two different workflows. + + + +Workflow 1: Using idlpp to Generate Simulink Bus and Type Descriptor +==================================================================== + +DDS Topic Types are described in IDL. To be compatible with DDS, these types must be +represented in Sumlink as Bus Types. On writes, these Simulink Bus types are converted +to DDS types and on read DDS types are converted to Simulink Bus types. + +IDL can be defined in an IDL file and the corresponding Simulink Bus Types can be created +by ``Vortex.idlImportSl`` at the MATLAB command line. This will create the necessary Simulink Bus +Types and Elements in a Simulink dictionary. It also creates the XML type descriptor for +the Simulink Bus types that is used to create the Topic. The type descriptor is a Simulink variable +of the form TypeDescriptor. The type descriptor is necessary for the block set to work correctly, +but you will not directly address this when creating Simulink blocks. + + +**DDS IDL to Simulink Bus Mapping** + +The table below describes the generated Simulink artifacts when ``Vortex.idlImportSl`` is invoked from MATLAB. + + +.. table:: + + +--------------------------+----------------------------+----------------+--------------------------------+ + |**DDS IDL** |**Simulink Type** |**Annotation** |**Comments** | + +==========================+============================+================+================================+ + |struct B |Simulink.Bus B | | Creates Simulink Bus | + +--------------------------+----------------------------+----------------+--------------------------------+ + |enum E | Simulink Enum E | | Creates Simulink Enum type | + +--------------------------+----------------------------+----------------+--------------------------------+ + |module A | |@Scope(A) |Added to each enum or struct | + | | | |contained in the module. | + +--------------------------+----------------------------+----------------+--------------------------------+ + |#pragma keylist | |@Key |Every topic bus has @Key in its | + | | | |description. | + +--------------------------+----------------------------+----------------+--------------------------------+ + |boolean |boolean | | | + +--------------------------+----------------------------+----------------+--------------------------------+ + |char |int8 | | | + +--------------------------+----------------------------+----------------+--------------------------------+ + |octet |uint8 | | | + +--------------------------+----------------------------+----------------+--------------------------------+ + |short |int16 | | | + +--------------------------+----------------------------+----------------+--------------------------------+ + |unsigned short |uint16 | | | + +--------------------------+----------------------------+----------------+--------------------------------+ + |long |int32 | | | + +--------------------------+----------------------------+----------------+--------------------------------+ + |unsigned long |uint32 | | | + +--------------------------+----------------------------+----------------+--------------------------------+ + |long long |double | |No int64 in Simulink. Copied | + | | | |into the memory allocated for | + | | | |a double. | + +--------------------------+----------------------------+----------------+--------------------------------+ + |unsigned long long |double | |No int64 in Simulink. Copied | + | | | |into the memory allocated for | + | | | |a double. | + +--------------------------+----------------------------+----------------+--------------------------------+ + |float |single | | | + +--------------------------+----------------------------+----------------+--------------------------------+ + |double |double | | | + +--------------------------+----------------------------+----------------+--------------------------------+ + |string |int8 |@String | Default dimension is 256 | + +--------------------------+----------------------------+----------------+--------------------------------+ + |string | int8 |@BString | | + | | Dimension N | | | + +--------------------------+----------------------------+----------------+--------------------------------+ + |T field[N] | Mapped type for T. | |Multidimensional arrays are | + | | Dimension N | |supported. | + +--------------------------+----------------------------+----------------+--------------------------------+ + |sequence | Bus: seqN_T. | |E.g. sequence becomes | + | | Dimension: N | |"Bus: seq3_int32" | + +--------------------------+----------------------------+----------------+--------------------------------+ + |sequence | Bus: seq_T | |E.g. sequence becomes | + | | Dimension: 16 | |"Bus: seq_int32" with default | + | | | |dimension of 16 | + +--------------------------+----------------------------+----------------+--------------------------------+ + |typedef | | |expanded in place | + +--------------------------+----------------------------+----------------+--------------------------------+ + | **Unsupported DDS data types** | + +--------------------------+----------------------------+----------------+--------------------------------+ + |wchar |*not supported* | | | + +--------------------------+----------------------------+----------------+--------------------------------+ + |wstring |*not supported* | | | + +--------------------------+----------------------------+----------------+--------------------------------+ + |any |*not supported* | | | + +--------------------------+----------------------------+----------------+--------------------------------+ + |long double |*not supported* | | | + +--------------------------+----------------------------+----------------+--------------------------------+ + |union |*not supported* | | | + +--------------------------+----------------------------+----------------+--------------------------------+ + |inheritance |*not supported* | | | + +--------------------------+----------------------------+----------------+--------------------------------+ + + + +Workflow 2: Manually Modeling DDS data in the Simulink Bus Editor +================================================================= + +DDS IDL is not necessary to interact with DDS applicatoins. +You can also model the Simulink buses directly. +In this case, the block set will infer the DDS data types from the Simulink types. + +Defining Simulink busses without first defining the IDL is not recommended; it has the following limitations: + +* fewer IDL concepts are supported. In particular, sequences are unsupported. +* it will be difficult for your Simulink application to interact with applications written in other languages, as those languages will required IDL to define the topic data. + + +**IDL-less mapping of Simulink bus IDL concepts** + +The table below describes how a Simulink bus that was not created from an IDL file +is mapped to IDL concepts. + +.. table:: + + +-------------------------------+------------------+---------------------------------+ + |**Simulink Type** |**IDL equivalent**|**Description** | + +===============================+==================+=================================+ + |Simulink.Bus B |struct B |Defines DDS topic type B | + +-------------------------------+------------------+---------------------------------+ + | bus annotation: @Scope(A::B) |module |Creates DDS namespace for struct | + +-------------------------------+------------------+---------------------------------+ + |bus annotation: @Key(f1,f2) |#pragma keylist |Defines topic key field(s) | + +-------------------------------+------------------+---------------------------------+ + |boolean |boolean |IDL array if Dimensions > 1 | + +-------------------------------+------------------+---------------------------------+ + |int8 |char |IDL array if Dimensions > 1 | + +-------------------------------+------------------+---------------------------------+ + |uint8 |octet |IDL array if Dimensions > 1 | + +-------------------------------+------------------+---------------------------------+ + |int16 |short |IDL array if Dimensions > 1 | + +-------------------------------+------------------+---------------------------------+ + |uint16 |unsigned short |IDL array if Dimensions > 1 | + +-------------------------------+------------------+---------------------------------+ + |int32 |long |IDL array if Dimensions > 1 | + +-------------------------------+------------------+---------------------------------+ + |uint32 |unsigned long |IDL array if Dimensions > 1 | + +-------------------------------+------------------+---------------------------------+ + |single |float |IDL array if Dimensions > 1 | + +-------------------------------+------------------+---------------------------------+ + |double |double |IDL array if Dimensions > 1 | + +-------------------------------+------------------+---------------------------------+ + | | int8, annotated @String |string | | max length of read strings is | + | | uint8, annotated @String | | | determined by field dimension | + +-------------------------------+------------------+---------------------------------+ + | | int8, annotated @BString |string | | + | | uint8, annotated @BString | | | + | | Dimension N | | | + +-------------------------------+------------------+---------------------------------+ + |Simulink enumeration, E |enum E |IDL array if Dimensions > 1 | + +-------------------------------+------------------+---------------------------------+ + + diff --git a/docs/html/DDSSimulinkGuide/_sources/contacts.txt b/docs/html/DDSSimulinkGuide/_sources/contacts.txt new file mode 100644 index 000000000..d32f6016f --- /dev/null +++ b/docs/html/DDSSimulinkGuide/_sources/contacts.txt @@ -0,0 +1 @@ +.. include:: ../../common/contacts.rst diff --git a/docs/html/DDSSimulinkGuide/_sources/domain.txt b/docs/html/DDSSimulinkGuide/_sources/domain.txt new file mode 100644 index 000000000..6babb0959 --- /dev/null +++ b/docs/html/DDSSimulinkGuide/_sources/domain.txt @@ -0,0 +1,44 @@ +.. _`Domain Block`: + + + +############ +Domain Block +############ + +The Domain block represents a DDS domain participant entity. + +In DDS - "A domain participant represents the local membership of the application in a domain. A domain is a distributed concept that links all the applications able to communicate with each other. It represents a communication plane: only the publishers and subscribers attached to the same domain may interact." + +This block is optional on a DDS Simulink model diagram. If it is not present on a model diagram, a default participant will be created by either a topic, writer or reader block. + +.. figure:: images/domain_block.png + :alt: DDS Domain Block + + +=========== ========= ======= =========================== ==================== + Port Type Optional Name Description Output consumed by +=========== ========= ======= =========================== ==================== +Output no pp DDS Domain Participant Publisher, + entity instance Subscriber, Topic +=========== ========= ======= =========================== ==================== + + +Domain Block Parameters +*********************** + +.. figure:: images/domain_block_parameters.png + :alt: Domain Block Parameters + +Domain Tab +========== +The domain id is read only. The domain id is the OSPL default domain id specified in the OSPL configuration file. + +QoS Tab +======= +The **QoS** tab is used to set the QoS profile. By default, the OSPL default profile is used. + +In DDS - The Data-Distribution Service (DDS) relies on the usage of QoS. A QoS (Quality of Service) is a set of characteristics that controls some aspect of the behavior of the DDS Service. + +Each DDS block has an associated QoS profile. By default, the OSPL default profile is used. An XML file that specifies QoS profiles can be used to set the QoS of a DDS block. + diff --git a/docs/html/DDSSimulinkGuide/_sources/index.txt b/docs/html/DDSSimulinkGuide/_sources/index.txt new file mode 100644 index 000000000..162a5ba59 --- /dev/null +++ b/docs/html/DDSSimulinkGuide/_sources/index.txt @@ -0,0 +1,36 @@ +.. The Vortex OpenSplice Simulink Guide + +.. Doc Issue 01, 28 February 2017 + +################## +DDS Simulink Guide +################## + +.. toctree:: + :maxdepth: 6 + :numbered: + + introduction + installation + blocks + bus-dds + qos_provider + topic + domain + publisher + subscriber + writer + reader + tutorial + simulink_coder + troubleshooting + + bus_to_dds_mapping + + contacts + + +Indices and tables +================== + +* :ref:`search` diff --git a/docs/html/DDSSimulinkGuide/_sources/installation.txt b/docs/html/DDSSimulinkGuide/_sources/installation.txt new file mode 100644 index 000000000..3e9104d12 --- /dev/null +++ b/docs/html/DDSSimulinkGuide/_sources/installation.txt @@ -0,0 +1,133 @@ +.. _`Installation`: + +############ +Installation +############ + +This section describes the procedure to install the Vortex DDS Simulink Integration on a Linux or Windows platform. + +System Requirements +******************* + +- Operating System: Windows or Linux +- MATLAB Simulink installed +- Java 1.7 or greater + +OpenSplice (OSPL) and DDS Simulink Installation +*********************************************** + +Steps: + +1. Install OSPL. The DDS Simulink Integration is included in this installer. + + +2. Setup OSPL license. Copy the license.lic file into the appropriate license directory. + + */INSTALLDIR/ADLINK/Vortex_v2/license* + +3. MATLAB and Simulink files are contained in a tools/matlab folder + + Example: + */INSTALLDIR/ADLINK/Vortex_v2/Device/VortexOpenSplice/6.8.x/HDE/x86_64.linux/tools/matlab* + + +OpenSplice (OSPL) Configuration +******************************* + +By default OSPL uses single process configuration. + +If however, shared memory configuration is used, additional OSPL configuration steps need to be taken to work with MATLAB Simulink. + +Linux +===== + +OSPL-9882 Linux: MATLAB/Simulink hangs when connecting to shared memory domain + +**Description** +On Linux, a MATLAB script or Simulink model connecting to a Vortex OpenSplice domain via shared memory will hang. + +**Resolution** +MATLAB, like Java applications requires that the environment variable LD_PRELOAD be set to reference the active Java installations libjsig.so library. +The MATLAB user interface uses Java, and thus requires the same signal handling strategy as Java applications connecting to Vortex OpenSplice. +The precise syntax for setting the LD_PRELOAD environment variable will depend on the shell being used. + +For Oracle JVMs, LD_PRELOAD should contain this value: + $JAVA_HOME/jre/lib/amd64/libjsig.so + +Windows +======= + +OSPL-10018 MATLAB: Shared Memory Database Address on Windows needs to be changed from default + +**Description** +On a Windows 64-bit system, an OpenSplice system configured with Shared Memory, MATLAB cannot connect to the OpenSplice domain if the Shared Memory Database Address is set to its default value of 0x40000000. The error log (ospl-error.log) will show entries such as: +Report : Can not Map View Of file: Attempt to access invalid address. +Internals : OS Abstraction/code/os_sharedmem.c/1764/0/1487951812.565129500 + +**Resolution** +Use the configuration editor to change the default data base address. Use the 'Domain' tab, and select the 'Database' element in the tree. If necessary, right click the Database element to add an 'Address' element. Change the address. In general, a larger number is less likely to be problematic. On a test machine, appending two zeros to the default address allowed for successful connections. + + +Simulink Setup +************** + +Steps: + +1. Open command shell and run script to setup environment variables. + + **Linux** + + - Open a Linux terminal. + + - Navigate to directory containing release.com file. + + */INSTALLDIR/ADLINK/Vortex_v2/Device/VortexOpenSplice/6.8.x/HDE/x86_64.linux* + + - Run release.com. (Type in “. release.com†at command line.) + + + **Windows** + + - Open a command prompt. + + - Navigate to directory containing release.bat file. + + *INSTALLDIR/ADLINK/Vortex_v2/Device/VortexOpenSplice/6.8.x/HDE/x86_64.win64* + + - Run release.bat. (Type in “release.bat†at command line.) + + +2. Start MATLAB using the **SAME** command shell used in Step 1. + + *NOTE: If MATLAB is NOT started from a command shell with the correct OSPL environment variables set, exceptions will occur when attempting to use DDS Simulink blocks.* + +3. In MATLAB, navigate to file “Vortex_DDS_Block_Set.mltbx†by typing:: + + cd(fullfile(getenv('OSPL_HOME'),'tools','matlab')) + +.. raw:: latex + + \newpage + +4. Double click on the file “Vortex_DDS_Block_Set.mltbxâ€. This will bring up a dialog entitled **Install Vortex_DDS_Block_Set**. Select **Install**. + +.. figure:: images/linuxInstall2.png + :alt: DDS + + +**Setup is complete!** + + + +Examples +******** + +Example models have been provided in the examples folder. + +*../tools/matlab/examples/simulink* + + + + + + diff --git a/docs/html/DDSSimulinkGuide/_sources/introduction.txt b/docs/html/DDSSimulinkGuide/_sources/introduction.txt new file mode 100644 index 000000000..f2694b631 --- /dev/null +++ b/docs/html/DDSSimulinkGuide/_sources/introduction.txt @@ -0,0 +1,35 @@ +.. _`Introduction`: + + +############ +Introduction +############ + +The DDS Simulink Integration provides users with DDS custom blocks to model DDS communication between Simulink models and pure DDS applications. + +DDS +*** + +**What is DDS?** + +“The Data Distribution Service (DDSâ„¢) is a middleware protocol and API standard for data-centric connectivity from the Object Management Group® (OMG®). It integrates the components of a system together, providing low-latency data connectivity, extreme reliability, and a scalable architecture that business and mission-critical Internet of Things (IoT) applications need.†+ +“The main goal of DDS is to share the right data at the right place at the right time, even between time-decoupled publishers and consumers. DDS implements global data space by carefully replicating relevant portions of the logically shared dataspace.†DDS specification + +.. figure:: images/dds_overview.png + :alt: DDS + +**Further Documentation** + +http://portals.omg.org/dds/ + +http://ist.adlinktech.com/ + +Simulink +******** + +**What is Simulink?** + +“Simulink® is a block diagram environment for multidomain simulation and Model-Based Design. It supports system-level design, simulation, automatic code generation, and continuous test and verification of embedded systems. Simulink provides a graphical editor, customizable block libraries, and solvers for modeling and simulating dynamic systems. It is integrated with MATLAB®, enabling you to incorporate MATLAB algorithms into models and export simulation results to MATLAB for further analysis.†Simulink Help + + diff --git a/docs/html/DDSSimulinkGuide/_sources/publisher.txt b/docs/html/DDSSimulinkGuide/_sources/publisher.txt new file mode 100644 index 000000000..343f27bf7 --- /dev/null +++ b/docs/html/DDSSimulinkGuide/_sources/publisher.txt @@ -0,0 +1,47 @@ +.. _`Publisher Block`: + + + +############### +Publisher Block +############### + +The Publisher block represents a DDS publisher entity. + +In DDS, a publisher is "an object responsible for data distribution. It may publish data of different data types." + +This block is optional on a DDS Simulink model diagram. If it is not present on a model diagram, each writer will create a default publisher. + +.. figure:: images/publisher_block.png + :alt: DDS Publisher Block + + + +=========== ========= ======= =========================== ==================== + Port Type Optional Name Description Output consumed by +=========== ========= ======= =========================== ==================== +Input yes pp DDS Domain Participant + entity instance +Output no ppub DDS Publisher entity Writer + instance +=========== ========= ======= =========================== ==================== + + +Publisher Block Parameters +************************** + +.. figure:: images/publisher_block_parameters.png + :alt: Publisher Block Parameters + +Ports Tab +========= +The **Ports** tab allows the user to toggle on or off optional ports. + +QoS Tab +======= +The **QoS** tab is used to set the QoS profile. By default, the OSPL default profile is used. + +In DDS - The Data-Distribution Service (DDS) relies on the usage of QoS. A QoS (Quality of Service) is a set of characteristics that controls some aspect of the behavior of the DDS Service. + +Each DDS block has an associated QoS profile. By default, the OSPL default profile is used. An XML file that specifies QoS profiles can be used to set the QoS of a DDS block. + diff --git a/docs/html/DDSSimulinkGuide/_sources/qos_provider.txt b/docs/html/DDSSimulinkGuide/_sources/qos_provider.txt new file mode 100644 index 000000000..191e69174 --- /dev/null +++ b/docs/html/DDSSimulinkGuide/_sources/qos_provider.txt @@ -0,0 +1,101 @@ +.. _`QoS Provider`: + + +############ +QoS Provider +############ + +Each Vortex DDS block has a QoS that can be set using the **Block Parameters**. + +The following section explains how the QoS is set for a DDS entity using the QoS Provider. + + +QoS Provider File +***************** + +Quality of Service for DDS entities is set using XML files based on the XML schema file DDS_QoSProfile.xsd. +These XML files contain one or more QoS profiles for DDS entities. An example with a default QoS profile +for all entity types can be found at DDS_DefaultQoS.xml_. + +**Note:** Sample QoS Profile XML files can be found in the examples directories. + +QoS Profile +*********** + +A QoS profile consists of a name. The file contains QoS +elements for one or more DDS entities. A skeleton file without any QoS values is displayed below to show +the structure of the file. + + +.. code-block:: xml + + + + + + + + + + + + +**Example: Specify Publisher Partition** + +The example below specifies the publisher's partitions as A and B. + +.. code-block:: xml + + + + + A + B + + + + + +Setting QoS Profile in Simulink +******************************* +QoS profiles are set using the Simulink block's parameters dialog under the QoS tab. If the +QoS File parameter is set to None the default QoS settings will be used. The Reset button sets +the parameters to the default values. + +.. figure:: images/default_qos_params.png + :alt: Default QoS Provider Parameters + +A QoS Provider file can be selected by browsing to the XML file. Once the file is chosen the +file name is displayed and the user is presented with a drop down list of all QoS Providers in +the file. + +.. figure:: images/persistent_qos_params.png + :alt: DDS User Selected QoS Provider Parameters + + +**Note:** Seeing the QoS Profile in the drop down list only guarantees the QoS Profile exists in the file. +It does not mean the qos tag exists for the entity. The user is responsible for verifying the entity qos +tag exists in the file. + +.. raw:: latex + + \newpage + +Simulink block annotations are visible by default to display the QoS File Name and the QoS Profile settings. + +.. figure:: images/sub_annotations_qos.png + :alt: QoS File and Profile annotations + +Known Limitations +***************** + +See `QoS Provider Known Limitations <../qos_provider.html#KnownLimitations>`_ for a list of limitations +on QoS Provider support. + +.. external links +.. _QoSProfile.xsd: http://www.omg.org/spec/dds4ccm/20110201/DDS_QoSProfile.xsd +.. _DDS_DefaultQoS.xml: http://www.omg.org/spec/dds4ccm/20110201/DDS_DefaultQoS.xml + + + diff --git a/docs/html/DDSSimulinkGuide/_sources/reader.txt b/docs/html/DDSSimulinkGuide/_sources/reader.txt new file mode 100644 index 000000000..aff83602c --- /dev/null +++ b/docs/html/DDSSimulinkGuide/_sources/reader.txt @@ -0,0 +1,124 @@ +.. _`Reader Block`: + + + +############ +Reader Block +############ + +The Reader block represents a DDS data reader entity. + +In DDS - "To access the received data, the application must use a typed DataReader attached to the subscriber." + + +.. figure:: images/reader_block.png + :alt: DDS Reader Block + + + +=========== ========= ============= =========================== ==================== + Port Type Optional Name Description Output consumed by +=========== ========= ============= =========================== ==================== +Input yes psub DDS Subscriber + entity instance +Input no topic DDS Topic entity instance +Output yes status 0 for successful reader + creation +Output no data BUS user +Output yes info BUS user +Output yes samples read Number of samples read user +=========== ========= ============= =========================== ==================== + +.. raw:: latex + + \newpage + +Reader Block Parameters +*********************** + + +.. figure:: images/reader_block_parameters.png + :alt: Reader Block Parameters + +Data Tab +======== +The **Data** tab is used to set: + +- Bus Type + + The output data type (BUS) for the **data** output port + +- Mode: take or read + + Specify whether the reader block is accessing the samples using DDS take or DDS read. + +- Sample Time + + "The sample time of a block is a parameter that indicates when, during simulation, the block produces outputs and if appropriate, updates its internal state." -Simulink documentation + + Default is -1, meaning it will inherit the Simulink sample time from inputs or the model. + Valid values: -1 and Numeric > 0 + +- Bus Width + + The bus width is the maximum number of samples that can be read or take(n) per block step. + Valid values for the bus width are: integers >= 1. + +.. raw:: latex + + \newpage + +- Wait for + + Checking the Historical Data field in the Wait for section specifies that the Reader will wait for historical data to arrive. The Timeout field is for setting time period (in seconds) determining how long the Reader should wait for the historical data. + If the timeout is reached, then any remaining historical data may be interleaved with new data. + + The Data Available field is for specifying whether the Reader should read only if the data is available. The following Timeouts field determines how long the Reader should wait for the availability of data. + If the timeout is reached, then the block returns no data and the simulation continues. + +Ports Tab +========= +The **Ports** tab allows the user to toggle on or off optional ports. + +QoS Tab +======= +The **QoS** tab is used to set the QoS profile. By default, the OSPL default profile is used. + +In DDS - The Data-Distribution Service (DDS) relies on the usage of QoS. A QoS (Quality of Service) is a set of characteristics that controls some aspect of the behavior of the DDS Service. + +Each DDS block has an associated QoS profile. By default, the OSPL default profile is used. An XML file that specifies QoS profiles can be used to set the QoS of a DDS block. + +.. raw:: latex + + \newpage + +Filters Tab +=========== + +The filters tab allows for the filtering of incoming samples. +The filtering can happen based on a query and/or on a sample read condition(s). + +**Query** + +Expression: The expression is a SQL condition. + +Parameters: N parameters in the format {'a', 'b'} +Each parameter element must be a char array (string). + +*Note: Query expressions are only validated at runtime.* + + +**Read Condition** + +The read conditions specified will filter the samples that are read or take(n). + +Example: For a reader, the Sample State has **Read** selected and **Not Read** deselected. + +Only samples with a Sample State **Read** will be processed with read or take. +Any samples with the **Not Read** sample state will not be read or take(n). + +*Note: At least one read condition must be selected for each category of Sample State, View State, or Instance State. +If not, an error will be thrown when a diagram simulation is run.* + +.. figure:: images/reader_filters_tab.png + :alt: Reader Block Parameters : Filters diff --git a/docs/html/DDSSimulinkGuide/_sources/simulink_coder.txt b/docs/html/DDSSimulinkGuide/_sources/simulink_coder.txt new file mode 100644 index 000000000..68feb66fe --- /dev/null +++ b/docs/html/DDSSimulinkGuide/_sources/simulink_coder.txt @@ -0,0 +1,100 @@ +.. _`Generating C code with Simulink Coder`: + +##################################### +Generating C code with Simulink Coder +##################################### + +The Vortex DDS Blockset for Simulink supports Simulink Coder generation of C code, if you have a Simulink Coder license from MathWorks. + +Prerequisites for C generation +****************************** + +In order to generate and compile C code containing DDS blocks, you must: + +* Have Simulink Coder and MATLAB Coder installed and licensed from MathWorks. +* You have an appropriate C compile installed, as described by the MATLAB documentation. +* Vortex OpenSplice must be installed, and the appropriate ``release.com`` (Linux) or ``release.bat`` (Windows) script must have been executed in a command window. +* MATLAB must have been started from the same command window. You can check this by running the MATLAB command ``getenv('OSPL_HOME')``. It should return a non-empty value. +* Your Simulink mode should execute correctly in simulation mode. + +Preparing for C generation +************************** + +Once your model has been validated via simulation mode, you are ready to generate and compile code. +Because of an issue with the OpenSplice C99 language headers, you must manualy change the code generation options for your model. +Follow these steps: + +- From the model's menu, choose **Code > C/C++ Code > Code Generation Options**. +- Click on the **Code Generation** tab in the left-hand pane. +- In the **Build Configurations** drop-down, choose **Specify**. +- In the table that appears below this, edit the **Options** value in the **C Compiler** row to remove the text **$(ANSI_OPTS)**. +- Click **OK** or **Apply** to save your changes, then close the Code Generation Options dialog. + +See the image, below, for an example of the code generation dialog. + +.. figure:: images/linuxCodeGenNoANSI_OPTS.png + :alt: Removing $(ANSI_OPTS) from C Compiler options + + C/C++ Code Generation Options. Remove the text $(ANSI_OPTS) for C Compiler to avoid compile errors. + +Generating code +*************** + +At least from the Vortex DDS Blockset point of view, you are ready to generate code. Follow these steps: + +- From the model's menu, choose **Code > C/C++ Code > Build Model**. +- Simulink will get busy. You may see the following warnings in the Diagnostic View. These are OK, but are explained below. + +**Domain Participant Warning** + +A warning may appear about the domain participant block:: + + Source 'SimpleDomain/Domain/Participant_Entity ' specifies that its sample time (-1) + is back-inherited. You should explicitly specify the sample time of sources. You can + disable this diagnostic by setting the 'Source block specifies -1 sample time' + diagnostic to 'none' in the Sample Time group on the Diagnostics pane of the + Configuration Parameters dialog box. + + Component:Simulink | Category:Blockwarning + +As the message states, this is because the block specifies a sample time of -1. The block only creates meaningful output on initialization (it connects to DDS), +so any inherited sample time is sufficient. Specifying a sample time of -1 allows the block to be place into a function-call subblock. + +**Full header search warning** + +The following warning about reverting to full header searches may appear:: + + The following error occurred while attempting to run the preprocessor to find the + minimum needed set of include files: + + While parsing the source file '/source/debug_utils.c' the following error + occurred + + /source/debug_utils.c:14: cannot open source file "os_stdlib.h" + | #include "os_stdlib.h" + | ^ + + Reverting to full header search. + +This may occur as you are trying to package code from compilation on another platform. The referenced header file is part of the OpenSplice distrubution. +When you compile on another platform, you will need to have that platform's OpenSplice distribution installed, and ``release`` variables set. The warning may be ignored. + +**Copy File information messages** + +If you are creating a source distrubution, you may see information messages such as the following:: + + cp: cannot stat ‘/libdcpsc99’: No such file or directory + +The build is attempting to copy OpenSplice shared libraries (which are refered to via environment variables). These should not be copied by the build. Instead, when you +compile the source on a target platform, these libraries will be found in the local OpenSplice installation. + +Running built models +******************** + +When you run a compiled Simulink executable, you will need: + +* An appropriate OpenSplice runtime installation on the machine executing the model +* The correct OpenSplice environment variables, which are set by the ``release`` script in the installation root directory. + + + diff --git a/docs/html/DDSSimulinkGuide/_sources/subscriber.txt b/docs/html/DDSSimulinkGuide/_sources/subscriber.txt new file mode 100644 index 000000000..8ce520f64 --- /dev/null +++ b/docs/html/DDSSimulinkGuide/_sources/subscriber.txt @@ -0,0 +1,47 @@ +.. _`Subscriber Block`: + + + +################ +Subscriber Block +################ + +The Subscriber block represents a DDS subscriber entity. + +In DDS, a subscriber is "an object responsible for receiving published data and making it available to the receiving application. It may receive and dispatch data of different specified types." + +This block is optional on a DDS Simulink model diagram. If it is not present on a model diagram, each reader will create its own default subscriber. + + +.. figure:: images/subscriber_block.png + :alt: DDS Subscriber Block + + +=========== ========= ======= =========================== ==================== + Port Type Optional Name Description Output consumed by +=========== ========= ======= =========================== ==================== +Input yes pp DDS Domain Participant + entity instance +Output no psub DDS Subscriber entity Reader + instance +=========== ========= ======= =========================== ==================== + + +Subscriber Block Parameters +*************************** + +.. figure:: images/subscriber_block_parameters.png + :alt: Subscriber Block Parameters + +Ports Tab +========= +The **Ports** tab allows the user to toggle on or off optional ports. + +QoS Tab +======= +The **QoS** tab is used to set the QoS profile. By default, the OSPL default profile is used. + +In DDS - The Data-Distribution Service (DDS) relies on the usage of QoS. A QoS (Quality of Service) is a set of characteristics that controls some aspect of the behavior of the DDS Service. + +Each DDS block has an associated QoS profile. By default, the OSPL default profile is used. An XML file that specifies QoS profiles can be used to set the QoS of a DDS block. + diff --git a/docs/html/DDSSimulinkGuide/_sources/topic.txt b/docs/html/DDSSimulinkGuide/_sources/topic.txt new file mode 100644 index 000000000..b25d5af6f --- /dev/null +++ b/docs/html/DDSSimulinkGuide/_sources/topic.txt @@ -0,0 +1,51 @@ +.. _`Topic Block`: + + + +########### +Topic Block +########### + +The topic block represents a DDS topic type. The DDS topic corresponds to a single data type. In DDS, data is distributed by publishing and subscribing topic data samples. + +For a DDS Topic type definition, a corresponding BUS should be defined in the MATLAB workspace. The name of the BUS and the fields and field types should correspond to the DDS topic IDL definition. + +In Simulink, a BUS definition can be used as an input or output signal of the Simulink building blocks. + + +.. figure:: images/topic_block.png + :alt: DDS Topic Block + + + +=========== ========= ======= =========================== ==================== + Port Type Optional Name Description Output consumed by +=========== ========= ======= =========================== ==================== +Input yes pp DDS Domain Participant + entity instance +Output no topic DDS Topic entity instance Writer, Reader +=========== ========= ======= =========================== ==================== + + +Topic Block Parameters +********************** + +.. figure:: images/topic_block_parameters.png + :alt: Topic Block Parameters + +Topic Tab +========= +The output port named **topic**, needs to be configured by the user. No defaults are provided. To configure the **topic** output port, edit the required parameters in the **Block Parameters / Topic** tab. The following topic parameters must be specified: **Bus Type** and **Topic Name**. + +Ports Tab +========= +The **Ports** tab allows the user to toggle on or off optional ports. + +QoS Tab +======= +The **QoS** tab is used to set the QoS profile. By default, the OSPL default profile is used. + +In DDS - The Data-Distribution Service (DDS) relies on the usage of QoS. A QoS (Quality of Service) is a set of characteristics that controls some aspect of the behavior of the DDS Service. + +Each DDS block has an associated QoS profile. By default, the OSPL default profile is used. An XML file that specifies QoS profiles can be used to set the QoS of a DDS block. + diff --git a/docs/html/DDSSimulinkGuide/_sources/troubleshooting.txt b/docs/html/DDSSimulinkGuide/_sources/troubleshooting.txt new file mode 100644 index 000000000..696e9849a --- /dev/null +++ b/docs/html/DDSSimulinkGuide/_sources/troubleshooting.txt @@ -0,0 +1,33 @@ +.. _`Troubleshooting`: + + +############### +Troubleshooting +############### + +**When double clicking on a DDS block to view the block parameters, an error dialog is shown with the message: Error evaluating 'MaskDialog' callback of SubSystem block (mask).** + +*Cause: The OSPL environment variables have not been setup correctly.* + +*Solution: Open a command shell and run the script to setup OSPL environment variables.* + + Linux + + - Open a Linux terminal. + + - Navigate to directory containing release.com file. + + */INSTALLDIR/ADLINK/Vortex_v2/Device/VortexOpenSplice/6.8.x/HDE/x86_64.linux* + + - Run release.com. (Type in “. release.com†at command line.) + + + Windows + + - Open a command prompt. + + - Navigate to directory containing release.bat file. + + *INSTALLDIR/ADLINK/Vortex_v2/Device/VortexOpenSplice/6.8.x/HDE/x86_64.win64* + + - Run release.bat. (Type in “release.bat†at command line.) diff --git a/docs/html/DDSSimulinkGuide/_sources/tutorial.txt b/docs/html/DDSSimulinkGuide/_sources/tutorial.txt new file mode 100644 index 000000000..dfc0dc734 --- /dev/null +++ b/docs/html/DDSSimulinkGuide/_sources/tutorial.txt @@ -0,0 +1,692 @@ +.. _`Tutorial`: + + +######## +Tutorial +######## + +To demonstrate the capabilities of the DDS Simulink Integration, this tutorial will create two Simulink models. One model will write DDS samples, and the second model will read the DDS samples. + +Both models will be run simultaneously, and use a DDS system for communication. + +A Simulink bus named ShapeType is created as part of this tutorial. The bus can be created by either using the Simulink bus editor, or by generation from an IDL file. +Both options are covered in this tutorial. + + +Create ShapeType Bus Using Simulink Bus Editor +********************************************** + +Buses define the data which will be published and read. Both the read and write Simulink models will make use of a bus to read and write sample data. + +For this tutorial, we will create a BUS named **ShapeType**. + +Open the bus editor from the MATLAB command window +================================================== + +.. figure:: images/openBusEditor.png + :alt: Open Bus Editor + +Add a new BUS named ShapeType +============================= + +Select Add Bus button +--------------------- + +.. figure:: images/addBus.png + :alt: Add Bus + +Set Bus name and Key +------------------------- + +- Set the new bus name to: **ShapeType**. +- Set Description to: @Key(color). This sets the Topic key. +- Select **Apply** button to save. + +.. figure:: images/addShapeType.png + :alt: Bus Name + +Note: If the Key is not set, the topic block's Key annotation in the model will be shown empty and it will result in a keyless topic. Keyless topics have only one instance. + + +Add BusElements +=============== + +The **ShapeType** bus will have 4 bus elements: color, x, y and shapesize. + +A BusElement can be added to the ShapeType bus by selecting the **Add/Insert BusElement** button. + +.. figure:: images/addBusElement.png + :alt: Add/Insert BusElement + +A BusElement can be moved up or down using the **Move Element Up** and **Move Element Down** buttons. + +.. figure:: images/upDownBusElement.png + :alt: Move Element + +.. raw:: latex + + \newpage + +Add color +--------- + +- Select **Add/Insert BusElement** button +- Set name to: color +- Set DataType to: uint8 +- Set Dimensions to: 10 +- Set Description to: @String +- Select **Apply** to save + +.. figure:: images/colorBusElement.png + :alt: BusElement color + +Note: This creates a DDS 'string' type. Bus elements of type 'int8' or 'uint8' with an annotation of @String in the Description field define a DDS string. Dimension set to 10 means Simulink is going to read only the first ten bytes of the string. You can also use the '\@BString' annotation to define a DDS bounded string. The dimension of the field is treated as the maximum string size. + +.. raw:: latex + + \newpage + +Add x +----- + +- Select **Add/Insert BusElement** button +- Set name to: x +- Set DataType to: int32 +- Select **Apply** to save + +.. figure:: images/xBusElement.png + :alt: BusElement x + +Add y +----- + +- Select **Add/Insert BusElement** button +- Set name to: y +- Set DataType to: int32 +- Select **Apply** to save + +.. figure:: images/yBusElement.png + :alt: BusElement y + +.. raw:: latex + + \newpage + +Add shapesize +------------- + +- Select **Add/Insert BusElement** button +- Set name to: shapesize +- Set DataType to: int32 +- Select **Apply** to save + +.. figure:: images/shapesizeBusElement.png + :alt: BusElement shapesize + + +Export BUS objects +================== + +When bus objects are added to the MATLAB workspace, they will be lost on MATLAB close or workspace clear. To persist the bus objects, they can be exported. + +A quick way to export the **ShapeType** bus using the bus editor, is to right click on the bus and select **Export ShapeType to File…** + +.. figure:: images/busExport.png + :alt: export bus + +The **ShapeType** bus is complete. + + +Create ShapeType Using IDL +**************************** + +The public Vortex.idlImportSl function can be called to generate Simulink bus definitions from an IDL file. +The generated bus definitions are inserted into the 'Design Data' section of a data dictionary. + +From the Simulink documentation - + *"A data dictionary is a persistent repository of data that are relevant to your model. You can also use the base workspace to store design data that are used by your model during simulation."* + +The data dictionary can then be referenced from your models. + + +Create IDL File +=============== + +Create an IDL file to define your ShapeType topic structure. For this tutorial we will name the file *ShapeType.idl*. + +.. code-block:: idl + + struct ShapeType { + string color; //@Key + long x; + long y; + long shapesize; + }; + #pragma keylist ShapeType color + +IMPORTANT NOTE: The IDL file has to have a blank line after the pragma keylist declaration. (known bug) + + +Generate Simulink bus definitions from an IDL file +================================================== + +Steps: + +1. In MATLAB, navigate to the directory that contains the *ShapeType.idl* file. Set this directory to be the MATLAB **Current Folder**. + +2. Call the idlImportSl function in the MATLAB command window. + + >> Vortex.idlImportSl('ShapeType.idl', 'shape.sldd') + + where: + + 'ShapeType.idl' is the name of the IDL file + + 'shape.sldd' is the name of the target data dictionary for the generated bus definitions + +.. raw:: latex + + \newpage + +Model Explorer +============== + +To make use of the bus definitions generated into the data dictionary, Simulink models can specify design data using the **Model Explorer**. + +.. figure:: images/modelExplorer.png + :alt: Model Explorer Design Data + + +Shapes Write Model +****************** + +This section outlines how to create a new DDS Simulink model that will write sample data for the topic type **ShapeType**. + +Although not necessary, this model will use the optional Domain and Publisher blocks. + +Create a new Simulink model +=========================== + +Start Simulink +-------------- + +.. figure:: images/startSimulink.png + :alt: Start Simulink + +.. raw:: latex + + \newpage + +Add a new blank model +--------------------- + +.. figure:: images/simulinkStartPage.png + :alt: Start Add new blank model + +Save As... +---------- + +- Save the model as *“shapes_write_model.slxâ€*. + +.. raw:: latex + + \newpage + +Model Settings +-------------- + +- Open Model Configuration Parameters dialog, by selecting menu **Simulation / Model Configuration Parameters**. + +- Set the simulation stop time to 1000.0 seconds. (Note: “Simulation time is not the same as clock time. For example, running a simulation for 10 seconds usually does not take 10 seconds. Total simulation time depends on factors such as model complexity, solver step sizes, and computer speed.†Simulink Help documentation) + +- Set the Solver Type to Fixed-step. + +.. figure:: images/write_model_setup.png + :alt: Model Settings + +Add Simulink DDS Blocks +======================= + +Open the Simulink Library Browser +--------------------------------- + +- Open the Simulink Library Browser + +- Browse to and select **Vortex DDS** to view DDS custom blocks + + +.. figure:: images/openLibraryBrowser.png + :alt: Open Simulink Library Browser + +.. figure:: images/ddsLibrary.png + :alt: Vortex DDS Blocks + +.. raw:: latex + + \newpage + +Add a Domain block +------------------ + +- Drag a Domain participant block from the Simulink Library Browser onto the Simulink model diagram. + +Set domain block properties +--------------------------- + +- To set a block’s parameters, double click on the block to bring up the **Block Parameters** dialog. +- The domain id is read only and set to DDS_DOMAIN_DEFAULT. This default is specified in the OSPL configuration file. +- The **QoS** tab defaults to the OSPL defaults. +- For this tutorial example, we are going to use the defaults, therefore no block parameters need to be specified. + +.. figure:: images/write_domain_parameters.png + :alt: Domain Block Parameters + + +Add blocks (Topic, Publisher, and Writer) +----------------------------------------------------- + +Using the Simulink Library Browser drag the following block types onto your diagram: + - 1 Topic + - 1 Publisher + - 1 Writer + +.. raw:: latex + + \newpage + +Connect Domain to Topic and Publisher +------------------------------------- + +- Connect the Domain **pp** output to Topic **pp** input. +- Connect the Domain **pp** output to Publisher **pp** input. + +.. figure:: images/write_connect_domain.png + :alt: Connecting participant ports + +.. raw:: latex + + \newpage + +Set Topic Block Parameters +-------------------------- + +- Double click on the Topic to bring up the **Block Parameters** dialog. +- In the **Topic** tab: + - Set **Bus Type** to: ShapeType + - Set **Topic Name** to: Circle +- The **Ports** tab allows for the setting of optional ports. For this model, we will not change the defaults. +- Select the **QoS** tab. +- Set the QoS file to: Shapes_Demo_QoS.xml. + /INSTALLDIR/ADLINK/Vortex_v2/Device/VortexOpenSplice/6.8.x/HDE/x86_64.linux/tools/matlab/ + /examples/simulink/dds_reader_writer_model/Shapes_Demo_QoS.xml + + +.. figure:: images/write_topic_parameters.png + :alt: Set Topic Block Parameters + + +.. raw:: latex + + \newpage + +Connect Topic, Publisher and Writer Blocks & Set Writer Block Parameters +------------------------------------------------------------------------ + +- Connect the Topic **topic** output to the Writer **topic** input. +- Connect the Publisher **ppub** output to the Writer **ppub** input. + +- Double click on the Writer block to edit the **Block Parameters**. Set the **Input Data Type** to the bus: ShapeType. +- Select the Writer **QoS** tab. +- Set the QoS file to: Shapes_Demo_QoS.xml. + + - /INSTALLDIR/ADLINK/Vortex_v2/Device/VortexOpenSplice/6.8.x/HDE/x86_64.linux/tools/matlab/ + /examples/simulink/dds_reader_writer_model/Shapes_Demo_QoS.xml + + +.. figure:: images/writer_write_parameters.png + :alt: Connect Blocks + + +.. raw:: latex + + \newpage + +Add a Bus Creator to Set Sample Data +------------------------------------ + +To generate sample data, we will add a **Simulink / Signal Routing / BusCreator** block to our diagram. + +.. figure:: images/write_buscreator_params.png + :alt: Set Bus Creator Block Parameters + +Add Bus Creator Inputs +---------------------- + +For demonstration purposes, we will input to the **BusCreator** signals using **Constant**, **Clock** and **Sine Wave** blocks. + +Note: To change the positioning of block ports, you can use the **Rotate & Flip** block menu item, accessible by right clicking on a block. + + - Drag 2 **Simulink / Sources / Constant** blocks onto the diagram + - Connect one **Constant** block to color input signal + - Connect one **Constant** block to shapesize input signal + +.. figure:: images/buscreator_constants.png + :alt: Bus Creator Constants + +.. raw:: latex + + \newpage + +- Set the **Block Parameters** for color signal **Constant** block +- Set **Constant value** to: uint8(pad('GREEN',10,'right', char( 0 ) )) +- Select **OK** + +.. figure:: images/colorConstant2.png + :alt: color Constant + +.. raw:: latex + + \newpage + +- Set the **Block Parameters** for shapesize signal **Constant** block +- Set **Constant value** to: 25 +- Set **Output data type** to: int32 + +.. figure:: images/shapesizeConstantBLock.png + :alt: shapesize Constant + +- Drag a **Simulink / Sources / Sine Wave** block onto diagram +- Connect **Sine Wave** block to y input signal +- Drag a **Simulink / Signal Attributes / Data Type Conversion** block onto **Sine Wave** connector. +- Set **Output data type** to: int32 + +.. figure:: images/sinewave.png + :alt: Sine Wave y + +.. raw:: latex + + \newpage + +- Set **Block Parameters** for **Sine Wave** block. +- Set **Amplitude** to: 150 +- Set **Bias** to: 175 +- Set **Sample time** to: 0.5 + +.. figure:: images/sineWaveBlockParamters.png + :alt: Sine Wave Block Parameters + +- For the **x** input signal, drag 3 new blocks onto diagram: + - **Simulink / Sources / Constant** + - **Simulink / Sources / Clock** + - **Simulink / Math Operations / Math Function** + +- Set **Block Parameters** for **Math Function** block. +- Set **Function** to: mod +- Set **Output signal type** to: real + +.. figure:: images/write_mathFunctionBlockParams.png + :alt: Math Function Block Parameters + +.. raw:: latex + + \newpage + +- Set **Block Parameters** for **Constant** block. +- Set **Constant value** to: 350 + +.. figure:: images/constant_x.png + :alt: Constant Block Parameters + +- Connect the **Clock** and **Constant** blocks to the mod **Math Function** +- Connect the mod **Math Function** to the **BusCreator** x input signal + +.. figure:: images/modBlock.png + :alt: Connect mod block + + +.. raw:: latex + + \newpage + +- Drag a **Simulink / Signal Attributes / Data Type Conversion** block onto **Math Function** connector. +- Set **Output data type** to: int32 + +.. figure:: images/modBlock2.png + :alt: Connect mod block + + +**Save your model. Your model is now complete!** + + + + + +Shapes Read Model +***************** + +Create a new Simulink model +=========================== + +This section outlines how to create a new DDS Simulink model that will read and display sample data for the topic type **ShapeType**. + +In this model example, we will be making use of many of the defaults, so the optional blocks will not be included in this model. + +.. raw:: latex + + \newpage + +Start Simulink +-------------- + +.. figure:: images/startSimulink.png + :alt: Start Simulink + + +Add a new blank model +--------------------- + +.. figure:: images/simulinkStartPage.png + :alt: Start Add new blank model + +Save As... +---------- + +- Save the model as *“shapes_read_model.slxâ€*. + +.. raw:: latex + + \newpage + +Model Settings +-------------- + +- Open Model Configuration Parameters dialog, by selecting menu **Simulation / Model Configuration Parameters**. + +- Set the simulation stop time to **inf**. (Note: “Specify inf to run a simulation or generated program until you explicitly pause or stop it.†Simulink Help documentation) + +- Set the Solver Type to **Fixed-step**. + +.. figure:: images/read_model_settings.png + :alt: Setup Read Model + +.. raw:: latex + + \newpage + +Add Simulink DDS Blocks +======================= + +Open the Simulink Library Browser +--------------------------------- + +.. figure:: images/ddsLibrary.png + :alt: Vortex DDS Library + +Add all required blocks (Topic and Reader) +------------------------------------------ + +Using the Simulink Library Browser drag the following block types onto your diagram: + - 1 Topic + - 1 Reader + +Note: For this example model, we will be using the block defaults for the Domain and Subscriber, therefore they will not be included on the model. + +To set a block’s parameters, double click on the block to bring up the **Block Parameters** dialog. + +.. figure:: images/read_blocks.png + :alt: Add Blocks + + +Toggle off optional ports +------------------------- + +- Double click on the Topic to bring up the **Block Parameters** dialog. +- In the Topic **Ports** tab deselect the Participant port. + +- Double click on the Reader to bring up the **Block Parameters** dialog. +- In the Reader **Ports** tab deselect the Subscriber, Reader, Status, Info and Samples Read ports. + +.. raw:: latex + + \newpage + +Set Topic Block Parameters +-------------------------- + +- Double click on the Topic to bring up the **Block Parameters** dialog, select **Topic** tab. +- Set the **Bus Type**: ShapeType bus + Note: If the ShapeType bus is not displayed, select Refresh data types from dropdown list. +- Set the **Topic Name** to: Circle. + +.. figure:: images/read_topic_topic.png + :alt: Topic Block Parameters + +- Select the **QoS** tab. +- Set the QoS file to : Shapes_Demo_QoS.xml. + INSTALLDIR/ADLINK/Vortex_v2/Device/VortexOpenSplice/6.8.x/HDE/x86_64.linux/tools/matlab/ + examples/simulink/dds_reader_writer_model/Shapes_Demo_QoS.xml + +Set Reader Block Parameters +--------------------------- + +- Double click on the Reader block to edit the **Block Parameters**. Set the **Input Data Type** to the bus: ShapeType. +- Select the **QoS** tab. +- Set the QoS file to : Shapes_Demo_QoS.xml. + INSTALLDIR/ADLINK/Vortex_v2/Device/VortexOpenSplice/6.8.x/HDE/x86_64.linux/tools/matlab/ + examples/simulink/dds_reader_writer_model/Shapes_Demo_QoS.xml + +.. raw:: latex + + \newpage + +Connect Topic and Reader +------------------------ + +- Connect the Topic block **topic** output to the Reader block **topic** input. + +.. figure:: images/read_connect.png + :alt: Connect Topic and Reader + + +Add a Bus Selector to read and display sample data +-------------------------------------------------- + +To read and display sample data, we will add a **Simulink / Signal Routing / Bus Selector** block to our diagram. + +Set Bus Selector Block Parameters +--------------------------------- + +Specify the output signals we would like to display in our simulation. For this example, we will display all the ShapeType BUS signals in the running simulation. + +- Connect the Reader **data** output to the **Bus Selector**. +- Double click on the **Bus Selector** block to edit the **Block Parameters**. +- Add all the signals in the bus to the **Selected signals**. + +.. figure:: images/read_busSelectorOutputs.png + :alt: Bus Selector Block Parameters + +.. raw:: latex + + \newpage + +Add Bus Selector outputs +------------------------ + +For demonstration purposes, we will output the bus signals using 2 Simulink **Display** blocks and an **XY Graph**. + +Note: To change the positioning of block ports, you can use the **Rotate & Flip** block menu item, accessible by right clicking on a block. + +- Drag 2 **Simulink / Sinks / Display** blocks onto the diagram. +- Connect the **Display** blocks to the **Bus Selector** output signals. + - Connect the Bus Selector color output signal to a Display block. + - Connect the Bus Selector shapesize output signal to a Display block. + +Note: Default Display block settings used. + +.. figure:: images/read_busSelector_display.png + :alt: Bus Selector Outputs + +.. raw:: latex + + \newpage + +- Drag **Simulink / Sinks / XY Graph** block onto diagram +- Connect the **BusSelector** x and y outputs to the **XY Graph** block. +- Set the Block Parameters on the **XY Graph**: + X-min: 0 + X-max: 400 + Y-min: 0 + Y-max: 400 + +.. figure:: images/xyGraph2.png + :alt: Bus Selector XY Graph + + +**Save your model!!! The model is now complete!** + + +.. raw:: latex + + \newpage + +Running Simulations +******************* + +We now have two Simulink models. We will run both models and see that data samples are being written by one model and read be the second model. + +Setup Write Model +================= + +1. Open shapes_write_model.slx. +2. Select menu item **Simulation / Update Diagram** to diagnose any possible model problems. +3. Fix any issues. + +Setup Read Model +================ + +1. Open shapes_read_model.slx. +2. Select menu item **Simulation / Update Diagram** to diagnose any possible model problems. +3. Fix any issues. + +Run Simulations +=============== + +1. Position models side by side. +2. Start the read model simulation. +3. Start the write model simulation. +4. Expected: The write model will write samples, that are received by the read model and displayed in that model’s **XY Graph** and **Display** blocks. +5. The write model will run to completion. The read model needs to be stopped manually. + +.. figure:: images/run.png + :alt: Run Simulations + +.. raw:: latex + + \newpage + +**Run Results** + +.. figure:: images/results.png + :alt: Run results + + diff --git a/docs/html/DDSSimulinkGuide/_sources/writer.txt b/docs/html/DDSSimulinkGuide/_sources/writer.txt new file mode 100644 index 000000000..173391afd --- /dev/null +++ b/docs/html/DDSSimulinkGuide/_sources/writer.txt @@ -0,0 +1,69 @@ +.. _`Writer Block`: + + + +############ +Writer Block +############ + +The Writer block represents a DDS data writer entity. + +In DDS - "The DataWriter is the object the application must use to communicate to a publisher the existence and value of data-objects of a given type." + +.. figure:: images/writer_block.png + :alt: DDS Writer Block + + +=========== ========= =============== =========================== ==================== + Port Type Optional Name Description Output consumed by +=========== ========= =============== =========================== ==================== +Input yes ppub DDS Publisher + entity instance +Input no topic DDS Topic entity instance +Input no data BUS +Input yes action 0 write, + 1 dispose, + 2 write dispose, + 3 no operation +Output yes status 0 for successful writer + creation +Output yes samples written Number of samples written User +=========== ========= =============== =========================== ==================== + +.. raw:: latex + + \newpage + +Writer Block Parameters +*********************** + + +.. figure:: images/writer_block_parameters.png + :alt: Writer Block Parameters + +Data Tab +======== +The **Data** tab is used to set the input data type (BUS) for the **data** input port and the **bus width**. + +The bus width is the maximum number of samples that can be written per block step. +The user must configure the source blocks that feed the Writer's data port so that it produces an array of the right size. + +Valid values for the bus width are: integers >= 1. + +The Reader Available field in the Wait for section is used for specifying if the Writer should wait for the Reader to become available. +The associated Timeout field is to specify how long (in seconds) the Writer should wait for the Reader to become available. + +The Write after timeout field can only be enabled when the Reader Available field is checked. It specifies if the Writer should write after the Wait for Reader Available timeout. + +Ports Tab +========= +The **Ports** tab allows the user to toggle on or off optional ports. + +QoS Tab +======= +The **QoS** tab is used to set the QoS profile. By default, the OSPL default profile is used. + +In DDS - The Data-Distribution Service (DDS) relies on the usage of QoS. A QoS (Quality of Service) is a set of characteristics that controls some aspect of the behavior of the DDS Service. + +Each DDS block has an associated QoS profile. By default, the OSPL default profile is used. An XML file that specifies QoS profiles can be used to set the QoS of a DDS block. + diff --git a/docs/html/DDSSimulinkGuide/_static/Vortex_logo_2014.png b/docs/html/DDSSimulinkGuide/_static/Vortex_logo_2014.png new file mode 100644 index 000000000..e7de4f525 Binary files /dev/null and b/docs/html/DDSSimulinkGuide/_static/Vortex_logo_2014.png differ diff --git a/docs/html/DDSSimulinkGuide/_static/ajax-loader.gif b/docs/html/DDSSimulinkGuide/_static/ajax-loader.gif new file mode 100644 index 000000000..61faf8cab Binary files /dev/null and b/docs/html/DDSSimulinkGuide/_static/ajax-loader.gif differ diff --git a/docs/html/DDSSimulinkGuide/_static/basic.css b/docs/html/DDSSimulinkGuide/_static/basic.css new file mode 100644 index 000000000..967e36ce0 --- /dev/null +++ b/docs/html/DDSSimulinkGuide/_static/basic.css @@ -0,0 +1,537 @@ +/* + * basic.css + * ~~~~~~~~~ + * + * Sphinx stylesheet -- basic theme. + * + * :copyright: Copyright 2007-2014 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +/* -- main layout ----------------------------------------------------------- */ + +div.clearer { + clear: both; +} + +/* -- relbar ---------------------------------------------------------------- */ + +div.related { + width: 100%; + font-size: 90%; +} + +div.related h3 { + display: none; +} + +div.related ul { + margin: 0; + padding: 0 0 0 10px; + list-style: none; +} + +div.related li { + display: inline; +} + +div.related li.right { + float: right; + margin-right: 5px; +} + +/* -- sidebar --------------------------------------------------------------- */ + +div.sphinxsidebarwrapper { + padding: 10px 5px 0 10px; +} + +div.sphinxsidebar { + float: left; + width: 230px; + margin-left: -100%; + font-size: 90%; +} + +div.sphinxsidebar ul { + list-style: none; +} + +div.sphinxsidebar ul ul, +div.sphinxsidebar ul.want-points { + margin-left: 20px; + list-style: square; +} + +div.sphinxsidebar ul ul { + margin-top: 0; + margin-bottom: 0; +} + +div.sphinxsidebar form { + margin-top: 10px; +} + +div.sphinxsidebar input { + border: 1px solid #98dbcc; + font-family: sans-serif; + font-size: 1em; +} + +div.sphinxsidebar #searchbox input[type="text"] { + width: 170px; +} + +div.sphinxsidebar #searchbox input[type="submit"] { + width: 30px; +} + +img { + border: 0; + max-width: 100%; +} + +/* -- search page ----------------------------------------------------------- */ + +ul.search { + margin: 10px 0 0 20px; + padding: 0; +} + +ul.search li { + padding: 5px 0 5px 20px; + background-image: url(file.png); + background-repeat: no-repeat; + background-position: 0 7px; +} + +ul.search li a { + font-weight: bold; +} + +ul.search li div.context { + color: #888; + margin: 2px 0 0 30px; + text-align: left; +} + +ul.keywordmatches li.goodmatch a { + font-weight: bold; +} + +/* -- index page ------------------------------------------------------------ */ + +table.contentstable { + width: 90%; +} + +table.contentstable p.biglink { + line-height: 150%; +} + +a.biglink { + font-size: 1.3em; +} + +span.linkdescr { + font-style: italic; + padding-top: 5px; + font-size: 90%; +} + +/* -- general index --------------------------------------------------------- */ + +table.indextable { + width: 100%; +} + +table.indextable td { + text-align: left; + vertical-align: top; +} + +table.indextable dl, table.indextable dd { + margin-top: 0; + margin-bottom: 0; +} + +table.indextable tr.pcap { + height: 10px; +} + +table.indextable tr.cap { + margin-top: 10px; + background-color: #f2f2f2; +} + +img.toggler { + margin-right: 3px; + margin-top: 3px; + cursor: pointer; +} + +div.modindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +div.genindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +/* -- general body styles --------------------------------------------------- */ + +a.headerlink { + visibility: hidden; +} + +h1:hover > a.headerlink, +h2:hover > a.headerlink, +h3:hover > a.headerlink, +h4:hover > a.headerlink, +h5:hover > a.headerlink, +h6:hover > a.headerlink, +dt:hover > a.headerlink { + visibility: visible; +} + +div.body p.caption { + text-align: inherit; +} + +div.body td { + text-align: left; +} + +.field-list ul { + padding-left: 1em; +} + +.first { + margin-top: 0 !important; +} + +p.rubric { + margin-top: 30px; + font-weight: bold; +} + +img.align-left, .figure.align-left, object.align-left { + clear: left; + float: left; + margin-right: 1em; +} + +img.align-right, .figure.align-right, object.align-right { + clear: right; + float: right; + margin-left: 1em; +} + +img.align-center, .figure.align-center, object.align-center { + display: block; + margin-left: auto; + margin-right: auto; +} + +.align-left { + text-align: left; +} + +.align-center { + text-align: center; +} + +.align-right { + text-align: right; +} + +/* -- sidebars -------------------------------------------------------------- */ + +div.sidebar { + margin: 0 0 0.5em 1em; + border: 1px solid #ddb; + padding: 7px 7px 0 7px; + background-color: #ffe; + width: 40%; + float: right; +} + +p.sidebar-title { + font-weight: bold; +} + +/* -- topics ---------------------------------------------------------------- */ + +div.topic { + border: 1px solid #ccc; + padding: 7px 7px 0 7px; + margin: 10px 0 10px 0; +} + +p.topic-title { + font-size: 1.1em; + font-weight: bold; + margin-top: 10px; +} + +/* -- admonitions ----------------------------------------------------------- */ + +div.admonition { + margin-top: 10px; + margin-bottom: 10px; + padding: 7px; +} + +div.admonition dt { + font-weight: bold; +} + +div.admonition dl { + margin-bottom: 0; +} + +p.admonition-title { + margin: 0px 10px 5px 0px; + font-weight: bold; +} + +div.body p.centered { + text-align: center; + margin-top: 25px; +} + +/* -- tables ---------------------------------------------------------------- */ + +table.docutils { + border: 0; + border-collapse: collapse; +} + +table.docutils td, table.docutils th { + padding: 1px 8px 1px 5px; + border-top: 0; + border-left: 0; + border-right: 0; + border-bottom: 1px solid #aaa; +} + +table.field-list td, table.field-list th { + border: 0 !important; +} + +table.footnote td, table.footnote th { + border: 0 !important; +} + +th { + text-align: left; + padding-right: 5px; +} + +table.citation { + border-left: solid 1px gray; + margin-left: 1px; +} + +table.citation td { + border-bottom: none; +} + +/* -- other body styles ----------------------------------------------------- */ + +ol.arabic { + list-style: decimal; +} + +ol.loweralpha { + list-style: lower-alpha; +} + +ol.upperalpha { + list-style: upper-alpha; +} + +ol.lowerroman { + list-style: lower-roman; +} + +ol.upperroman { + list-style: upper-roman; +} + +dl { + margin-bottom: 15px; +} + +dd p { + margin-top: 0px; +} + +dd ul, dd table { + margin-bottom: 10px; +} + +dd { + margin-top: 3px; + margin-bottom: 10px; + margin-left: 30px; +} + +dt:target, .highlighted { + background-color: #fbe54e; +} + +dl.glossary dt { + font-weight: bold; + font-size: 1.1em; +} + +.field-list ul { + margin: 0; + padding-left: 1em; +} + +.field-list p { + margin: 0; +} + +.optional { + font-size: 1.3em; +} + +.versionmodified { + font-style: italic; +} + +.system-message { + background-color: #fda; + padding: 5px; + border: 3px solid red; +} + +.footnote:target { + background-color: #ffa; +} + +.line-block { + display: block; + margin-top: 1em; + margin-bottom: 1em; +} + +.line-block .line-block { + margin-top: 0; + margin-bottom: 0; + margin-left: 1.5em; +} + +.guilabel, .menuselection { + font-family: sans-serif; +} + +.accelerator { + text-decoration: underline; +} + +.classifier { + font-style: oblique; +} + +abbr, acronym { + border-bottom: dotted 1px; + cursor: help; +} + +/* -- code displays --------------------------------------------------------- */ + +pre { + overflow: auto; + overflow-y: hidden; /* fixes display issues on Chrome browsers */ +} + +td.linenos pre { + padding: 5px 0px; + border: 0; + background-color: transparent; + color: #aaa; +} + +table.highlighttable { + margin-left: 0.5em; +} + +table.highlighttable td { + padding: 0 0.5em 0 0.5em; +} + +tt.descname { + background-color: transparent; + font-weight: bold; + font-size: 1.2em; +} + +tt.descclassname { + background-color: transparent; +} + +tt.xref, a tt { + background-color: transparent; + font-weight: bold; +} + +h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt { + background-color: transparent; +} + +.viewcode-link { + float: right; +} + +.viewcode-back { + float: right; + font-family: sans-serif; +} + +div.viewcode-block:target { + margin: -1px -10px; + padding: 0 10px; +} + +/* -- math display ---------------------------------------------------------- */ + +img.math { + vertical-align: middle; +} + +div.body div.math p { + text-align: center; +} + +span.eqno { + float: right; +} + +/* -- printout stylesheet --------------------------------------------------- */ + +@media print { + div.document, + div.documentwrapper, + div.bodywrapper { + margin: 0 !important; + width: 100%; + } + + div.sphinxsidebar, + div.related, + div.footer, + #top-link { + display: none; + } +} \ No newline at end of file diff --git a/docs/html/DDSSimulinkGuide/_static/comment-bright.png b/docs/html/DDSSimulinkGuide/_static/comment-bright.png new file mode 100644 index 000000000..551517b8c Binary files /dev/null and b/docs/html/DDSSimulinkGuide/_static/comment-bright.png differ diff --git a/docs/html/DDSSimulinkGuide/_static/comment-close.png b/docs/html/DDSSimulinkGuide/_static/comment-close.png new file mode 100644 index 000000000..09b54be46 Binary files /dev/null and b/docs/html/DDSSimulinkGuide/_static/comment-close.png differ diff --git a/docs/html/DDSSimulinkGuide/_static/comment.png b/docs/html/DDSSimulinkGuide/_static/comment.png new file mode 100644 index 000000000..92feb52b8 Binary files /dev/null and b/docs/html/DDSSimulinkGuide/_static/comment.png differ diff --git a/docs/html/DDSSimulinkGuide/_static/doctools.js b/docs/html/DDSSimulinkGuide/_static/doctools.js new file mode 100644 index 000000000..c5455c905 --- /dev/null +++ b/docs/html/DDSSimulinkGuide/_static/doctools.js @@ -0,0 +1,238 @@ +/* + * doctools.js + * ~~~~~~~~~~~ + * + * Sphinx JavaScript utilities for all documentation. + * + * :copyright: Copyright 2007-2014 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +/** + * select a different prefix for underscore + */ +$u = _.noConflict(); + +/** + * make the code below compatible with browsers without + * an installed firebug like debugger +if (!window.console || !console.firebug) { + var names = ["log", "debug", "info", "warn", "error", "assert", "dir", + "dirxml", "group", "groupEnd", "time", "timeEnd", "count", "trace", + "profile", "profileEnd"]; + window.console = {}; + for (var i = 0; i < names.length; ++i) + window.console[names[i]] = function() {}; +} + */ + +/** + * small helper function to urldecode strings + */ +jQuery.urldecode = function(x) { + return decodeURIComponent(x).replace(/\+/g, ' '); +}; + +/** + * small helper function to urlencode strings + */ +jQuery.urlencode = encodeURIComponent; + +/** + * This function returns the parsed url parameters of the + * current request. Multiple values per key are supported, + * it will always return arrays of strings for the value parts. + */ +jQuery.getQueryParameters = function(s) { + if (typeof s == 'undefined') + s = document.location.search; + var parts = s.substr(s.indexOf('?') + 1).split('&'); + var result = {}; + for (var i = 0; i < parts.length; i++) { + var tmp = parts[i].split('=', 2); + var key = jQuery.urldecode(tmp[0]); + var value = jQuery.urldecode(tmp[1]); + if (key in result) + result[key].push(value); + else + result[key] = [value]; + } + return result; +}; + +/** + * highlight a given string on a jquery object by wrapping it in + * span elements with the given class name. + */ +jQuery.fn.highlightText = function(text, className) { + function highlight(node) { + if (node.nodeType == 3) { + var val = node.nodeValue; + var pos = val.toLowerCase().indexOf(text); + if (pos >= 0 && !jQuery(node.parentNode).hasClass(className)) { + var span = document.createElement("span"); + span.className = className; + span.appendChild(document.createTextNode(val.substr(pos, text.length))); + node.parentNode.insertBefore(span, node.parentNode.insertBefore( + document.createTextNode(val.substr(pos + text.length)), + node.nextSibling)); + node.nodeValue = val.substr(0, pos); + } + } + else if (!jQuery(node).is("button, select, textarea")) { + jQuery.each(node.childNodes, function() { + highlight(this); + }); + } + } + return this.each(function() { + highlight(this); + }); +}; + +/** + * Small JavaScript module for the documentation. + */ +var Documentation = { + + init : function() { + this.fixFirefoxAnchorBug(); + this.highlightSearchWords(); + this.initIndexTable(); + }, + + /** + * i18n support + */ + TRANSLATIONS : {}, + PLURAL_EXPR : function(n) { return n == 1 ? 0 : 1; }, + LOCALE : 'unknown', + + // gettext and ngettext don't access this so that the functions + // can safely bound to a different name (_ = Documentation.gettext) + gettext : function(string) { + var translated = Documentation.TRANSLATIONS[string]; + if (typeof translated == 'undefined') + return string; + return (typeof translated == 'string') ? translated : translated[0]; + }, + + ngettext : function(singular, plural, n) { + var translated = Documentation.TRANSLATIONS[singular]; + if (typeof translated == 'undefined') + return (n == 1) ? singular : plural; + return translated[Documentation.PLURALEXPR(n)]; + }, + + addTranslations : function(catalog) { + for (var key in catalog.messages) + this.TRANSLATIONS[key] = catalog.messages[key]; + this.PLURAL_EXPR = new Function('n', 'return +(' + catalog.plural_expr + ')'); + this.LOCALE = catalog.locale; + }, + + /** + * add context elements like header anchor links + */ + addContextElements : function() { + $('div[id] > :header:first').each(function() { + $('\u00B6'). + attr('href', '#' + this.id). + attr('title', _('Permalink to this headline')). + appendTo(this); + }); + $('dt[id]').each(function() { + $('\u00B6'). + attr('href', '#' + this.id). + attr('title', _('Permalink to this definition')). + appendTo(this); + }); + }, + + /** + * workaround a firefox stupidity + */ + fixFirefoxAnchorBug : function() { + if (document.location.hash && $.browser.mozilla) + window.setTimeout(function() { + document.location.href += ''; + }, 10); + }, + + /** + * highlight the search words provided in the url in the text + */ + highlightSearchWords : function() { + var params = $.getQueryParameters(); + var terms = (params.highlight) ? params.highlight[0].split(/\s+/) : []; + if (terms.length) { + var body = $('div.body'); + if (!body.length) { + body = $('body'); + } + window.setTimeout(function() { + $.each(terms, function() { + body.highlightText(this.toLowerCase(), 'highlighted'); + }); + }, 10); + $('') + .appendTo($('#searchbox')); + } + }, + + /** + * init the domain index toggle buttons + */ + initIndexTable : function() { + var togglers = $('img.toggler').click(function() { + var src = $(this).attr('src'); + var idnum = $(this).attr('id').substr(7); + $('tr.cg-' + idnum).toggle(); + if (src.substr(-9) == 'minus.png') + $(this).attr('src', src.substr(0, src.length-9) + 'plus.png'); + else + $(this).attr('src', src.substr(0, src.length-8) + 'minus.png'); + }).css('display', ''); + if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) { + togglers.click(); + } + }, + + /** + * helper function to hide the search marks again + */ + hideSearchWords : function() { + $('#searchbox .highlight-link').fadeOut(300); + $('span.highlighted').removeClass('highlighted'); + }, + + /** + * make the url absolute + */ + makeURL : function(relativeURL) { + return DOCUMENTATION_OPTIONS.URL_ROOT + '/' + relativeURL; + }, + + /** + * get the current relative url + */ + getCurrentURL : function() { + var path = document.location.pathname; + var parts = path.split(/\//); + $.each(DOCUMENTATION_OPTIONS.URL_ROOT.split(/\//), function() { + if (this == '..') + parts.pop(); + }); + var url = parts.join('/'); + return path.substring(url.lastIndexOf('/') + 1, path.length - 1); + } +}; + +// quick alias for translations +_ = Documentation.gettext; + +$(document).ready(function() { + Documentation.init(); +}); diff --git a/docs/html/DDSSimulinkGuide/_static/down-pressed.png b/docs/html/DDSSimulinkGuide/_static/down-pressed.png new file mode 100644 index 000000000..6f7ad7827 Binary files /dev/null and b/docs/html/DDSSimulinkGuide/_static/down-pressed.png differ diff --git a/docs/html/DDSSimulinkGuide/_static/down.png b/docs/html/DDSSimulinkGuide/_static/down.png new file mode 100644 index 000000000..3003a8877 Binary files /dev/null and b/docs/html/DDSSimulinkGuide/_static/down.png differ diff --git a/docs/html/DDSSimulinkGuide/_static/file.png b/docs/html/DDSSimulinkGuide/_static/file.png new file mode 100644 index 000000000..d18082e39 Binary files /dev/null and b/docs/html/DDSSimulinkGuide/_static/file.png differ diff --git a/docs/html/DDSSimulinkGuide/_static/jquery.js b/docs/html/DDSSimulinkGuide/_static/jquery.js new file mode 100644 index 000000000..e2efc335e --- /dev/null +++ b/docs/html/DDSSimulinkGuide/_static/jquery.js @@ -0,0 +1,9404 @@ +/*! + * jQuery JavaScript Library v1.7.2 + * http://jquery.com/ + * + * Copyright 2011, John Resig + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * Includes Sizzle.js + * http://sizzlejs.com/ + * Copyright 2011, The Dojo Foundation + * Released under the MIT, BSD, and GPL Licenses. + * + * Date: Fri Jul 5 14:07:58 UTC 2013 + */ +(function( window, undefined ) { + +// Use the correct document accordingly with window argument (sandbox) +var document = window.document, + navigator = window.navigator, + location = window.location; +var jQuery = (function() { + +// Define a local copy of jQuery +var jQuery = function( selector, context ) { + // The jQuery object is actually just the init constructor 'enhanced' + return new jQuery.fn.init( selector, context, rootjQuery ); + }, + + // Map over jQuery in case of overwrite + _jQuery = window.jQuery, + + // Map over the $ in case of overwrite + _$ = window.$, + + // A central reference to the root jQuery(document) + rootjQuery, + + // A simple way to check for HTML strings or ID strings + // Prioritize #id over to avoid XSS via location.hash (#9521) + quickExpr = /^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/, + + // Check if a string has a non-whitespace character in it + rnotwhite = /\S/, + + // Used for trimming whitespace + trimLeft = /^\s+/, + trimRight = /\s+$/, + + // Match a standalone tag + rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>)?$/, + + // JSON RegExp + rvalidchars = /^[\],:{}\s]*$/, + rvalidescape = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, + rvalidtokens = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, + rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g, + + // Useragent RegExp + rwebkit = /(webkit)[ \/]([\w.]+)/, + ropera = /(opera)(?:.*version)?[ \/]([\w.]+)/, + rmsie = /(msie) ([\w.]+)/, + rmozilla = /(mozilla)(?:.*? rv:([\w.]+))?/, + + // Matches dashed string for camelizing + rdashAlpha = /-([a-z]|[0-9])/ig, + rmsPrefix = /^-ms-/, + + // Used by jQuery.camelCase as callback to replace() + fcamelCase = function( all, letter ) { + return ( letter + "" ).toUpperCase(); + }, + + // Keep a UserAgent string for use with jQuery.browser + userAgent = navigator.userAgent, + + // For matching the engine and version of the browser + browserMatch, + + // The deferred used on DOM ready + readyList, + + // The ready event handler + DOMContentLoaded, + + // Save a reference to some core methods + toString = Object.prototype.toString, + hasOwn = Object.prototype.hasOwnProperty, + push = Array.prototype.push, + slice = Array.prototype.slice, + trim = String.prototype.trim, + indexOf = Array.prototype.indexOf, + + // [[Class]] -> type pairs + class2type = {}; + +jQuery.fn = jQuery.prototype = { + constructor: jQuery, + init: function( selector, context, rootjQuery ) { + var match, elem, ret, doc; + + // Handle $(""), $(null), or $(undefined) + if ( !selector ) { + return this; + } + + // Handle $(DOMElement) + if ( selector.nodeType ) { + this.context = this[0] = selector; + this.length = 1; + return this; + } + + // The body element only exists once, optimize finding it + if ( selector === "body" && !context && document.body ) { + this.context = document; + this[0] = document.body; + this.selector = selector; + this.length = 1; + return this; + } + + // Handle HTML strings + if ( typeof selector === "string" ) { + // Are we dealing with HTML string or an ID? + if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) { + // Assume that strings that start and end with <> are HTML and skip the regex check + match = [ null, selector, null ]; + + } else { + match = quickExpr.exec( selector ); + } + + // Verify a match, and that no context was specified for #id + if ( match && (match[1] || !context) ) { + + // HANDLE: $(html) -> $(array) + if ( match[1] ) { + context = context instanceof jQuery ? context[0] : context; + doc = ( context ? context.ownerDocument || context : document ); + + // If a single string is passed in and it's a single tag + // just do a createElement and skip the rest + ret = rsingleTag.exec( selector ); + + if ( ret ) { + if ( jQuery.isPlainObject( context ) ) { + selector = [ document.createElement( ret[1] ) ]; + jQuery.fn.attr.call( selector, context, true ); + + } else { + selector = [ doc.createElement( ret[1] ) ]; + } + + } else { + ret = jQuery.buildFragment( [ match[1] ], [ doc ] ); + selector = ( ret.cacheable ? jQuery.clone(ret.fragment) : ret.fragment ).childNodes; + } + + return jQuery.merge( this, selector ); + + // HANDLE: $("#id") + } else { + elem = document.getElementById( match[2] ); + + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + if ( elem && elem.parentNode ) { + // Handle the case where IE and Opera return items + // by name instead of ID + if ( elem.id !== match[2] ) { + return rootjQuery.find( selector ); + } + + // Otherwise, we inject the element directly into the jQuery object + this.length = 1; + this[0] = elem; + } + + this.context = document; + this.selector = selector; + return this; + } + + // HANDLE: $(expr, $(...)) + } else if ( !context || context.jquery ) { + return ( context || rootjQuery ).find( selector ); + + // HANDLE: $(expr, context) + // (which is just equivalent to: $(context).find(expr) + } else { + return this.constructor( context ).find( selector ); + } + + // HANDLE: $(function) + // Shortcut for document ready + } else if ( jQuery.isFunction( selector ) ) { + return rootjQuery.ready( selector ); + } + + if ( selector.selector !== undefined ) { + this.selector = selector.selector; + this.context = selector.context; + } + + return jQuery.makeArray( selector, this ); + }, + + // Start with an empty selector + selector: "", + + // The current version of jQuery being used + jquery: "1.7.2", + + // The default length of a jQuery object is 0 + length: 0, + + // The number of elements contained in the matched element set + size: function() { + return this.length; + }, + + toArray: function() { + return slice.call( this, 0 ); + }, + + // Get the Nth element in the matched element set OR + // Get the whole matched element set as a clean array + get: function( num ) { + return num == null ? + + // Return a 'clean' array + this.toArray() : + + // Return just the object + ( num < 0 ? this[ this.length + num ] : this[ num ] ); + }, + + // Take an array of elements and push it onto the stack + // (returning the new matched element set) + pushStack: function( elems, name, selector ) { + // Build a new jQuery matched element set + var ret = this.constructor(); + + if ( jQuery.isArray( elems ) ) { + push.apply( ret, elems ); + + } else { + jQuery.merge( ret, elems ); + } + + // Add the old object onto the stack (as a reference) + ret.prevObject = this; + + ret.context = this.context; + + if ( name === "find" ) { + ret.selector = this.selector + ( this.selector ? " " : "" ) + selector; + } else if ( name ) { + ret.selector = this.selector + "." + name + "(" + selector + ")"; + } + + // Return the newly-formed element set + return ret; + }, + + // Execute a callback for every element in the matched set. + // (You can seed the arguments with an array of args, but this is + // only used internally.) + each: function( callback, args ) { + return jQuery.each( this, callback, args ); + }, + + ready: function( fn ) { + // Attach the listeners + jQuery.bindReady(); + + // Add the callback + readyList.add( fn ); + + return this; + }, + + eq: function( i ) { + i = +i; + return i === -1 ? + this.slice( i ) : + this.slice( i, i + 1 ); + }, + + first: function() { + return this.eq( 0 ); + }, + + last: function() { + return this.eq( -1 ); + }, + + slice: function() { + return this.pushStack( slice.apply( this, arguments ), + "slice", slice.call(arguments).join(",") ); + }, + + map: function( callback ) { + return this.pushStack( jQuery.map(this, function( elem, i ) { + return callback.call( elem, i, elem ); + })); + }, + + end: function() { + return this.prevObject || this.constructor(null); + }, + + // For internal use only. + // Behaves like an Array's method, not like a jQuery method. + push: push, + sort: [].sort, + splice: [].splice +}; + +// Give the init function the jQuery prototype for later instantiation +jQuery.fn.init.prototype = jQuery.fn; + +jQuery.extend = jQuery.fn.extend = function() { + var options, name, src, copy, copyIsArray, clone, + target = arguments[0] || {}, + i = 1, + length = arguments.length, + deep = false; + + // Handle a deep copy situation + if ( typeof target === "boolean" ) { + deep = target; + target = arguments[1] || {}; + // skip the boolean and the target + i = 2; + } + + // Handle case when target is a string or something (possible in deep copy) + if ( typeof target !== "object" && !jQuery.isFunction(target) ) { + target = {}; + } + + // extend jQuery itself if only one argument is passed + if ( length === i ) { + target = this; + --i; + } + + for ( ; i < length; i++ ) { + // Only deal with non-null/undefined values + if ( (options = arguments[ i ]) != null ) { + // Extend the base object + for ( name in options ) { + src = target[ name ]; + copy = options[ name ]; + + // Prevent never-ending loop + if ( target === copy ) { + continue; + } + + // Recurse if we're merging plain objects or arrays + if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) { + if ( copyIsArray ) { + copyIsArray = false; + clone = src && jQuery.isArray(src) ? src : []; + + } else { + clone = src && jQuery.isPlainObject(src) ? src : {}; + } + + // Never move original objects, clone them + target[ name ] = jQuery.extend( deep, clone, copy ); + + // Don't bring in undefined values + } else if ( copy !== undefined ) { + target[ name ] = copy; + } + } + } + } + + // Return the modified object + return target; +}; + +jQuery.extend({ + noConflict: function( deep ) { + if ( window.$ === jQuery ) { + window.$ = _$; + } + + if ( deep && window.jQuery === jQuery ) { + window.jQuery = _jQuery; + } + + return jQuery; + }, + + // Is the DOM ready to be used? Set to true once it occurs. + isReady: false, + + // A counter to track how many items to wait for before + // the ready event fires. See #6781 + readyWait: 1, + + // Hold (or release) the ready event + holdReady: function( hold ) { + if ( hold ) { + jQuery.readyWait++; + } else { + jQuery.ready( true ); + } + }, + + // Handle when the DOM is ready + ready: function( wait ) { + // Either a released hold or an DOMready/load event and not yet ready + if ( (wait === true && !--jQuery.readyWait) || (wait !== true && !jQuery.isReady) ) { + // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). + if ( !document.body ) { + return setTimeout( jQuery.ready, 1 ); + } + + // Remember that the DOM is ready + jQuery.isReady = true; + + // If a normal DOM Ready event fired, decrement, and wait if need be + if ( wait !== true && --jQuery.readyWait > 0 ) { + return; + } + + // If there are functions bound, to execute + readyList.fireWith( document, [ jQuery ] ); + + // Trigger any bound ready events + if ( jQuery.fn.trigger ) { + jQuery( document ).trigger( "ready" ).off( "ready" ); + } + } + }, + + bindReady: function() { + if ( readyList ) { + return; + } + + readyList = jQuery.Callbacks( "once memory" ); + + // Catch cases where $(document).ready() is called after the + // browser event has already occurred. + if ( document.readyState === "complete" ) { + // Handle it asynchronously to allow scripts the opportunity to delay ready + return setTimeout( jQuery.ready, 1 ); + } + + // Mozilla, Opera and webkit nightlies currently support this event + if ( document.addEventListener ) { + // Use the handy event callback + document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false ); + + // A fallback to window.onload, that will always work + window.addEventListener( "load", jQuery.ready, false ); + + // If IE event model is used + } else if ( document.attachEvent ) { + // ensure firing before onload, + // maybe late but safe also for iframes + document.attachEvent( "onreadystatechange", DOMContentLoaded ); + + // A fallback to window.onload, that will always work + window.attachEvent( "onload", jQuery.ready ); + + // If IE and not a frame + // continually check to see if the document is ready + var toplevel = false; + + try { + toplevel = window.frameElement == null; + } catch(e) {} + + if ( document.documentElement.doScroll && toplevel ) { + doScrollCheck(); + } + } + }, + + // See test/unit/core.js for details concerning isFunction. + // Since version 1.3, DOM methods and functions like alert + // aren't supported. They return false on IE (#2968). + isFunction: function( obj ) { + return jQuery.type(obj) === "function"; + }, + + isArray: Array.isArray || function( obj ) { + return jQuery.type(obj) === "array"; + }, + + isWindow: function( obj ) { + return obj != null && obj == obj.window; + }, + + isNumeric: function( obj ) { + return !isNaN( parseFloat(obj) ) && isFinite( obj ); + }, + + type: function( obj ) { + return obj == null ? + String( obj ) : + class2type[ toString.call(obj) ] || "object"; + }, + + isPlainObject: function( obj ) { + // Must be an Object. + // Because of IE, we also have to check the presence of the constructor property. + // Make sure that DOM nodes and window objects don't pass through, as well + if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) { + return false; + } + + try { + // Not own constructor property must be Object + if ( obj.constructor && + !hasOwn.call(obj, "constructor") && + !hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) { + return false; + } + } catch ( e ) { + // IE8,9 Will throw exceptions on certain host objects #9897 + return false; + } + + // Own properties are enumerated firstly, so to speed up, + // if last one is own, then all properties are own. + + var key; + for ( key in obj ) {} + + return key === undefined || hasOwn.call( obj, key ); + }, + + isEmptyObject: function( obj ) { + for ( var name in obj ) { + return false; + } + return true; + }, + + error: function( msg ) { + throw new Error( msg ); + }, + + parseJSON: function( data ) { + if ( typeof data !== "string" || !data ) { + return null; + } + + // Make sure leading/trailing whitespace is removed (IE can't handle it) + data = jQuery.trim( data ); + + // Attempt to parse using the native JSON parser first + if ( window.JSON && window.JSON.parse ) { + return window.JSON.parse( data ); + } + + // Make sure the incoming data is actual JSON + // Logic borrowed from http://json.org/json2.js + if ( rvalidchars.test( data.replace( rvalidescape, "@" ) + .replace( rvalidtokens, "]" ) + .replace( rvalidbraces, "")) ) { + + return ( new Function( "return " + data ) )(); + + } + jQuery.error( "Invalid JSON: " + data ); + }, + + // Cross-browser xml parsing + parseXML: function( data ) { + if ( typeof data !== "string" || !data ) { + return null; + } + var xml, tmp; + try { + if ( window.DOMParser ) { // Standard + tmp = new DOMParser(); + xml = tmp.parseFromString( data , "text/xml" ); + } else { // IE + xml = new ActiveXObject( "Microsoft.XMLDOM" ); + xml.async = "false"; + xml.loadXML( data ); + } + } catch( e ) { + xml = undefined; + } + if ( !xml || !xml.documentElement || xml.getElementsByTagName( "parsererror" ).length ) { + jQuery.error( "Invalid XML: " + data ); + } + return xml; + }, + + noop: function() {}, + + // Evaluates a script in a global context + // Workarounds based on findings by Jim Driscoll + // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context + globalEval: function( data ) { + if ( data && rnotwhite.test( data ) ) { + // We use execScript on Internet Explorer + // We use an anonymous function so that context is window + // rather than jQuery in Firefox + ( window.execScript || function( data ) { + window[ "eval" ].call( window, data ); + } )( data ); + } + }, + + // Convert dashed to camelCase; used by the css and data modules + // Microsoft forgot to hump their vendor prefix (#9572) + camelCase: function( string ) { + return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); + }, + + nodeName: function( elem, name ) { + return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase(); + }, + + // args is for internal usage only + each: function( object, callback, args ) { + var name, i = 0, + length = object.length, + isObj = length === undefined || jQuery.isFunction( object ); + + if ( args ) { + if ( isObj ) { + for ( name in object ) { + if ( callback.apply( object[ name ], args ) === false ) { + break; + } + } + } else { + for ( ; i < length; ) { + if ( callback.apply( object[ i++ ], args ) === false ) { + break; + } + } + } + + // A special, fast, case for the most common use of each + } else { + if ( isObj ) { + for ( name in object ) { + if ( callback.call( object[ name ], name, object[ name ] ) === false ) { + break; + } + } + } else { + for ( ; i < length; ) { + if ( callback.call( object[ i ], i, object[ i++ ] ) === false ) { + break; + } + } + } + } + + return object; + }, + + // Use native String.trim function wherever possible + trim: trim ? + function( text ) { + return text == null ? + "" : + trim.call( text ); + } : + + // Otherwise use our own trimming functionality + function( text ) { + return text == null ? + "" : + text.toString().replace( trimLeft, "" ).replace( trimRight, "" ); + }, + + // results is for internal usage only + makeArray: function( array, results ) { + var ret = results || []; + + if ( array != null ) { + // The window, strings (and functions) also have 'length' + // Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930 + var type = jQuery.type( array ); + + if ( array.length == null || type === "string" || type === "function" || type === "regexp" || jQuery.isWindow( array ) ) { + push.call( ret, array ); + } else { + jQuery.merge( ret, array ); + } + } + + return ret; + }, + + inArray: function( elem, array, i ) { + var len; + + if ( array ) { + if ( indexOf ) { + return indexOf.call( array, elem, i ); + } + + len = array.length; + i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0; + + for ( ; i < len; i++ ) { + // Skip accessing in sparse arrays + if ( i in array && array[ i ] === elem ) { + return i; + } + } + } + + return -1; + }, + + merge: function( first, second ) { + var i = first.length, + j = 0; + + if ( typeof second.length === "number" ) { + for ( var l = second.length; j < l; j++ ) { + first[ i++ ] = second[ j ]; + } + + } else { + while ( second[j] !== undefined ) { + first[ i++ ] = second[ j++ ]; + } + } + + first.length = i; + + return first; + }, + + grep: function( elems, callback, inv ) { + var ret = [], retVal; + inv = !!inv; + + // Go through the array, only saving the items + // that pass the validator function + for ( var i = 0, length = elems.length; i < length; i++ ) { + retVal = !!callback( elems[ i ], i ); + if ( inv !== retVal ) { + ret.push( elems[ i ] ); + } + } + + return ret; + }, + + // arg is for internal usage only + map: function( elems, callback, arg ) { + var value, key, ret = [], + i = 0, + length = elems.length, + // jquery objects are treated as arrays + isArray = elems instanceof jQuery || length !== undefined && typeof length === "number" && ( ( length > 0 && elems[ 0 ] && elems[ length -1 ] ) || length === 0 || jQuery.isArray( elems ) ) ; + + // Go through the array, translating each of the items to their + if ( isArray ) { + for ( ; i < length; i++ ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret[ ret.length ] = value; + } + } + + // Go through every key on the object, + } else { + for ( key in elems ) { + value = callback( elems[ key ], key, arg ); + + if ( value != null ) { + ret[ ret.length ] = value; + } + } + } + + // Flatten any nested arrays + return ret.concat.apply( [], ret ); + }, + + // A global GUID counter for objects + guid: 1, + + // Bind a function to a context, optionally partially applying any + // arguments. + proxy: function( fn, context ) { + if ( typeof context === "string" ) { + var tmp = fn[ context ]; + context = fn; + fn = tmp; + } + + // Quick check to determine if target is callable, in the spec + // this throws a TypeError, but we will just return undefined. + if ( !jQuery.isFunction( fn ) ) { + return undefined; + } + + // Simulated bind + var args = slice.call( arguments, 2 ), + proxy = function() { + return fn.apply( context, args.concat( slice.call( arguments ) ) ); + }; + + // Set the guid of unique handler to the same of original handler, so it can be removed + proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++; + + return proxy; + }, + + // Mutifunctional method to get and set values to a collection + // The value/s can optionally be executed if it's a function + access: function( elems, fn, key, value, chainable, emptyGet, pass ) { + var exec, + bulk = key == null, + i = 0, + length = elems.length; + + // Sets many values + if ( key && typeof key === "object" ) { + for ( i in key ) { + jQuery.access( elems, fn, i, key[i], 1, emptyGet, value ); + } + chainable = 1; + + // Sets one value + } else if ( value !== undefined ) { + // Optionally, function values get executed if exec is true + exec = pass === undefined && jQuery.isFunction( value ); + + if ( bulk ) { + // Bulk operations only iterate when executing function values + if ( exec ) { + exec = fn; + fn = function( elem, key, value ) { + return exec.call( jQuery( elem ), value ); + }; + + // Otherwise they run against the entire set + } else { + fn.call( elems, value ); + fn = null; + } + } + + if ( fn ) { + for (; i < length; i++ ) { + fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass ); + } + } + + chainable = 1; + } + + return chainable ? + elems : + + // Gets + bulk ? + fn.call( elems ) : + length ? fn( elems[0], key ) : emptyGet; + }, + + now: function() { + return ( new Date() ).getTime(); + }, + + // Use of jQuery.browser is frowned upon. + // More details: http://docs.jquery.com/Utilities/jQuery.browser + uaMatch: function( ua ) { + ua = ua.toLowerCase(); + + var match = rwebkit.exec( ua ) || + ropera.exec( ua ) || + rmsie.exec( ua ) || + ua.indexOf("compatible") < 0 && rmozilla.exec( ua ) || + []; + + return { browser: match[1] || "", version: match[2] || "0" }; + }, + + sub: function() { + function jQuerySub( selector, context ) { + return new jQuerySub.fn.init( selector, context ); + } + jQuery.extend( true, jQuerySub, this ); + jQuerySub.superclass = this; + jQuerySub.fn = jQuerySub.prototype = this(); + jQuerySub.fn.constructor = jQuerySub; + jQuerySub.sub = this.sub; + jQuerySub.fn.init = function init( selector, context ) { + if ( context && context instanceof jQuery && !(context instanceof jQuerySub) ) { + context = jQuerySub( context ); + } + + return jQuery.fn.init.call( this, selector, context, rootjQuerySub ); + }; + jQuerySub.fn.init.prototype = jQuerySub.fn; + var rootjQuerySub = jQuerySub(document); + return jQuerySub; + }, + + browser: {} +}); + +// Populate the class2type map +jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) { + class2type[ "[object " + name + "]" ] = name.toLowerCase(); +}); + +browserMatch = jQuery.uaMatch( userAgent ); +if ( browserMatch.browser ) { + jQuery.browser[ browserMatch.browser ] = true; + jQuery.browser.version = browserMatch.version; +} + +// Deprecated, use jQuery.browser.webkit instead +if ( jQuery.browser.webkit ) { + jQuery.browser.safari = true; +} + +// IE doesn't match non-breaking spaces with \s +if ( rnotwhite.test( "\xA0" ) ) { + trimLeft = /^[\s\xA0]+/; + trimRight = /[\s\xA0]+$/; +} + +// All jQuery objects should point back to these +rootjQuery = jQuery(document); + +// Cleanup functions for the document ready method +if ( document.addEventListener ) { + DOMContentLoaded = function() { + document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false ); + jQuery.ready(); + }; + +} else if ( document.attachEvent ) { + DOMContentLoaded = function() { + // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). + if ( document.readyState === "complete" ) { + document.detachEvent( "onreadystatechange", DOMContentLoaded ); + jQuery.ready(); + } + }; +} + +// The DOM ready check for Internet Explorer +function doScrollCheck() { + if ( jQuery.isReady ) { + return; + } + + try { + // If IE is used, use the trick by Diego Perini + // http://javascript.nwbox.com/IEContentLoaded/ + document.documentElement.doScroll("left"); + } catch(e) { + setTimeout( doScrollCheck, 1 ); + return; + } + + // and execute any waiting functions + jQuery.ready(); +} + +return jQuery; + +})(); + + +// String to Object flags format cache +var flagsCache = {}; + +// Convert String-formatted flags into Object-formatted ones and store in cache +function createFlags( flags ) { + var object = flagsCache[ flags ] = {}, + i, length; + flags = flags.split( /\s+/ ); + for ( i = 0, length = flags.length; i < length; i++ ) { + object[ flags[i] ] = true; + } + return object; +} + +/* + * Create a callback list using the following parameters: + * + * flags: an optional list of space-separated flags that will change how + * the callback list behaves + * + * By default a callback list will act like an event callback list and can be + * "fired" multiple times. + * + * Possible flags: + * + * once: will ensure the callback list can only be fired once (like a Deferred) + * + * memory: will keep track of previous values and will call any callback added + * after the list has been fired right away with the latest "memorized" + * values (like a Deferred) + * + * unique: will ensure a callback can only be added once (no duplicate in the list) + * + * stopOnFalse: interrupt callings when a callback returns false + * + */ +jQuery.Callbacks = function( flags ) { + + // Convert flags from String-formatted to Object-formatted + // (we check in cache first) + flags = flags ? ( flagsCache[ flags ] || createFlags( flags ) ) : {}; + + var // Actual callback list + list = [], + // Stack of fire calls for repeatable lists + stack = [], + // Last fire value (for non-forgettable lists) + memory, + // Flag to know if list was already fired + fired, + // Flag to know if list is currently firing + firing, + // First callback to fire (used internally by add and fireWith) + firingStart, + // End of the loop when firing + firingLength, + // Index of currently firing callback (modified by remove if needed) + firingIndex, + // Add one or several callbacks to the list + add = function( args ) { + var i, + length, + elem, + type, + actual; + for ( i = 0, length = args.length; i < length; i++ ) { + elem = args[ i ]; + type = jQuery.type( elem ); + if ( type === "array" ) { + // Inspect recursively + add( elem ); + } else if ( type === "function" ) { + // Add if not in unique mode and callback is not in + if ( !flags.unique || !self.has( elem ) ) { + list.push( elem ); + } + } + } + }, + // Fire callbacks + fire = function( context, args ) { + args = args || []; + memory = !flags.memory || [ context, args ]; + fired = true; + firing = true; + firingIndex = firingStart || 0; + firingStart = 0; + firingLength = list.length; + for ( ; list && firingIndex < firingLength; firingIndex++ ) { + if ( list[ firingIndex ].apply( context, args ) === false && flags.stopOnFalse ) { + memory = true; // Mark as halted + break; + } + } + firing = false; + if ( list ) { + if ( !flags.once ) { + if ( stack && stack.length ) { + memory = stack.shift(); + self.fireWith( memory[ 0 ], memory[ 1 ] ); + } + } else if ( memory === true ) { + self.disable(); + } else { + list = []; + } + } + }, + // Actual Callbacks object + self = { + // Add a callback or a collection of callbacks to the list + add: function() { + if ( list ) { + var length = list.length; + add( arguments ); + // Do we need to add the callbacks to the + // current firing batch? + if ( firing ) { + firingLength = list.length; + // With memory, if we're not firing then + // we should call right away, unless previous + // firing was halted (stopOnFalse) + } else if ( memory && memory !== true ) { + firingStart = length; + fire( memory[ 0 ], memory[ 1 ] ); + } + } + return this; + }, + // Remove a callback from the list + remove: function() { + if ( list ) { + var args = arguments, + argIndex = 0, + argLength = args.length; + for ( ; argIndex < argLength ; argIndex++ ) { + for ( var i = 0; i < list.length; i++ ) { + if ( args[ argIndex ] === list[ i ] ) { + // Handle firingIndex and firingLength + if ( firing ) { + if ( i <= firingLength ) { + firingLength--; + if ( i <= firingIndex ) { + firingIndex--; + } + } + } + // Remove the element + list.splice( i--, 1 ); + // If we have some unicity property then + // we only need to do this once + if ( flags.unique ) { + break; + } + } + } + } + } + return this; + }, + // Control if a given callback is in the list + has: function( fn ) { + if ( list ) { + var i = 0, + length = list.length; + for ( ; i < length; i++ ) { + if ( fn === list[ i ] ) { + return true; + } + } + } + return false; + }, + // Remove all callbacks from the list + empty: function() { + list = []; + return this; + }, + // Have the list do nothing anymore + disable: function() { + list = stack = memory = undefined; + return this; + }, + // Is it disabled? + disabled: function() { + return !list; + }, + // Lock the list in its current state + lock: function() { + stack = undefined; + if ( !memory || memory === true ) { + self.disable(); + } + return this; + }, + // Is it locked? + locked: function() { + return !stack; + }, + // Call all callbacks with the given context and arguments + fireWith: function( context, args ) { + if ( stack ) { + if ( firing ) { + if ( !flags.once ) { + stack.push( [ context, args ] ); + } + } else if ( !( flags.once && memory ) ) { + fire( context, args ); + } + } + return this; + }, + // Call all the callbacks with the given arguments + fire: function() { + self.fireWith( this, arguments ); + return this; + }, + // To know if the callbacks have already been called at least once + fired: function() { + return !!fired; + } + }; + + return self; +}; + + + + +var // Static reference to slice + sliceDeferred = [].slice; + +jQuery.extend({ + + Deferred: function( func ) { + var doneList = jQuery.Callbacks( "once memory" ), + failList = jQuery.Callbacks( "once memory" ), + progressList = jQuery.Callbacks( "memory" ), + state = "pending", + lists = { + resolve: doneList, + reject: failList, + notify: progressList + }, + promise = { + done: doneList.add, + fail: failList.add, + progress: progressList.add, + + state: function() { + return state; + }, + + // Deprecated + isResolved: doneList.fired, + isRejected: failList.fired, + + then: function( doneCallbacks, failCallbacks, progressCallbacks ) { + deferred.done( doneCallbacks ).fail( failCallbacks ).progress( progressCallbacks ); + return this; + }, + always: function() { + deferred.done.apply( deferred, arguments ).fail.apply( deferred, arguments ); + return this; + }, + pipe: function( fnDone, fnFail, fnProgress ) { + return jQuery.Deferred(function( newDefer ) { + jQuery.each( { + done: [ fnDone, "resolve" ], + fail: [ fnFail, "reject" ], + progress: [ fnProgress, "notify" ] + }, function( handler, data ) { + var fn = data[ 0 ], + action = data[ 1 ], + returned; + if ( jQuery.isFunction( fn ) ) { + deferred[ handler ](function() { + returned = fn.apply( this, arguments ); + if ( returned && jQuery.isFunction( returned.promise ) ) { + returned.promise().then( newDefer.resolve, newDefer.reject, newDefer.notify ); + } else { + newDefer[ action + "With" ]( this === deferred ? newDefer : this, [ returned ] ); + } + }); + } else { + deferred[ handler ]( newDefer[ action ] ); + } + }); + }).promise(); + }, + // Get a promise for this deferred + // If obj is provided, the promise aspect is added to the object + promise: function( obj ) { + if ( obj == null ) { + obj = promise; + } else { + for ( var key in promise ) { + obj[ key ] = promise[ key ]; + } + } + return obj; + } + }, + deferred = promise.promise({}), + key; + + for ( key in lists ) { + deferred[ key ] = lists[ key ].fire; + deferred[ key + "With" ] = lists[ key ].fireWith; + } + + // Handle state + deferred.done( function() { + state = "resolved"; + }, failList.disable, progressList.lock ).fail( function() { + state = "rejected"; + }, doneList.disable, progressList.lock ); + + // Call given func if any + if ( func ) { + func.call( deferred, deferred ); + } + + // All done! + return deferred; + }, + + // Deferred helper + when: function( firstParam ) { + var args = sliceDeferred.call( arguments, 0 ), + i = 0, + length = args.length, + pValues = new Array( length ), + count = length, + pCount = length, + deferred = length <= 1 && firstParam && jQuery.isFunction( firstParam.promise ) ? + firstParam : + jQuery.Deferred(), + promise = deferred.promise(); + function resolveFunc( i ) { + return function( value ) { + args[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value; + if ( !( --count ) ) { + deferred.resolveWith( deferred, args ); + } + }; + } + function progressFunc( i ) { + return function( value ) { + pValues[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value; + deferred.notifyWith( promise, pValues ); + }; + } + if ( length > 1 ) { + for ( ; i < length; i++ ) { + if ( args[ i ] && args[ i ].promise && jQuery.isFunction( args[ i ].promise ) ) { + args[ i ].promise().then( resolveFunc(i), deferred.reject, progressFunc(i) ); + } else { + --count; + } + } + if ( !count ) { + deferred.resolveWith( deferred, args ); + } + } else if ( deferred !== firstParam ) { + deferred.resolveWith( deferred, length ? [ firstParam ] : [] ); + } + return promise; + } +}); + + + + +jQuery.support = (function() { + + var support, + all, + a, + select, + opt, + input, + fragment, + tds, + events, + eventName, + i, + isSupported, + div = document.createElement( "div" ), + documentElement = document.documentElement; + + // Preliminary tests + div.setAttribute("className", "t"); + div.innerHTML = "
    a"; + + all = div.getElementsByTagName( "*" ); + a = div.getElementsByTagName( "a" )[ 0 ]; + + // Can't get basic test support + if ( !all || !all.length || !a ) { + return {}; + } + + // First batch of supports tests + select = document.createElement( "select" ); + opt = select.appendChild( document.createElement("option") ); + input = div.getElementsByTagName( "input" )[ 0 ]; + + support = { + // IE strips leading whitespace when .innerHTML is used + leadingWhitespace: ( div.firstChild.nodeType === 3 ), + + // Make sure that tbody elements aren't automatically inserted + // IE will insert them into empty tables + tbody: !div.getElementsByTagName("tbody").length, + + // Make sure that link elements get serialized correctly by innerHTML + // This requires a wrapper element in IE + htmlSerialize: !!div.getElementsByTagName("link").length, + + // Get the style information from getAttribute + // (IE uses .cssText instead) + style: /top/.test( a.getAttribute("style") ), + + // Make sure that URLs aren't manipulated + // (IE normalizes it by default) + hrefNormalized: ( a.getAttribute("href") === "/a" ), + + // Make sure that element opacity exists + // (IE uses filter instead) + // Use a regex to work around a WebKit issue. See #5145 + opacity: /^0.55/.test( a.style.opacity ), + + // Verify style float existence + // (IE uses styleFloat instead of cssFloat) + cssFloat: !!a.style.cssFloat, + + // Make sure that if no value is specified for a checkbox + // that it defaults to "on". + // (WebKit defaults to "" instead) + checkOn: ( input.value === "on" ), + + // Make sure that a selected-by-default option has a working selected property. + // (WebKit defaults to false instead of true, IE too, if it's in an optgroup) + optSelected: opt.selected, + + // Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7) + getSetAttribute: div.className !== "t", + + // Tests for enctype support on a form(#6743) + enctype: !!document.createElement("form").enctype, + + // Makes sure cloning an html5 element does not cause problems + // Where outerHTML is undefined, this still works + html5Clone: document.createElement("nav").cloneNode( true ).outerHTML !== "<:nav>", + + // Will be defined later + submitBubbles: true, + changeBubbles: true, + focusinBubbles: false, + deleteExpando: true, + noCloneEvent: true, + inlineBlockNeedsLayout: false, + shrinkWrapBlocks: false, + reliableMarginRight: true, + pixelMargin: true + }; + + // jQuery.boxModel DEPRECATED in 1.3, use jQuery.support.boxModel instead + jQuery.boxModel = support.boxModel = (document.compatMode === "CSS1Compat"); + + // Make sure checked status is properly cloned + input.checked = true; + support.noCloneChecked = input.cloneNode( true ).checked; + + // Make sure that the options inside disabled selects aren't marked as disabled + // (WebKit marks them as disabled) + select.disabled = true; + support.optDisabled = !opt.disabled; + + // Test to see if it's possible to delete an expando from an element + // Fails in Internet Explorer + try { + delete div.test; + } catch( e ) { + support.deleteExpando = false; + } + + if ( !div.addEventListener && div.attachEvent && div.fireEvent ) { + div.attachEvent( "onclick", function() { + // Cloning a node shouldn't copy over any + // bound event handlers (IE does this) + support.noCloneEvent = false; + }); + div.cloneNode( true ).fireEvent( "onclick" ); + } + + // Check if a radio maintains its value + // after being appended to the DOM + input = document.createElement("input"); + input.value = "t"; + input.setAttribute("type", "radio"); + support.radioValue = input.value === "t"; + + input.setAttribute("checked", "checked"); + + // #11217 - WebKit loses check when the name is after the checked attribute + input.setAttribute( "name", "t" ); + + div.appendChild( input ); + fragment = document.createDocumentFragment(); + fragment.appendChild( div.lastChild ); + + // WebKit doesn't clone checked state correctly in fragments + support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked; + + // Check if a disconnected checkbox will retain its checked + // value of true after appended to the DOM (IE6/7) + support.appendChecked = input.checked; + + fragment.removeChild( input ); + fragment.appendChild( div ); + + // Technique from Juriy Zaytsev + // http://perfectionkills.com/detecting-event-support-without-browser-sniffing/ + // We only care about the case where non-standard event systems + // are used, namely in IE. Short-circuiting here helps us to + // avoid an eval call (in setAttribute) which can cause CSP + // to go haywire. See: https://developer.mozilla.org/en/Security/CSP + if ( div.attachEvent ) { + for ( i in { + submit: 1, + change: 1, + focusin: 1 + }) { + eventName = "on" + i; + isSupported = ( eventName in div ); + if ( !isSupported ) { + div.setAttribute( eventName, "return;" ); + isSupported = ( typeof div[ eventName ] === "function" ); + } + support[ i + "Bubbles" ] = isSupported; + } + } + + fragment.removeChild( div ); + + // Null elements to avoid leaks in IE + fragment = select = opt = div = input = null; + + // Run tests that need a body at doc ready + jQuery(function() { + var container, outer, inner, table, td, offsetSupport, + marginDiv, conMarginTop, style, html, positionTopLeftWidthHeight, + paddingMarginBorderVisibility, paddingMarginBorder, + body = document.getElementsByTagName("body")[0]; + + if ( !body ) { + // Return for frameset docs that don't have a body + return; + } + + conMarginTop = 1; + paddingMarginBorder = "padding:0;margin:0;border:"; + positionTopLeftWidthHeight = "position:absolute;top:0;left:0;width:1px;height:1px;"; + paddingMarginBorderVisibility = paddingMarginBorder + "0;visibility:hidden;"; + style = "style='" + positionTopLeftWidthHeight + paddingMarginBorder + "5px solid #000;"; + html = "
    " + + "" + + "
    "; + + container = document.createElement("div"); + container.style.cssText = paddingMarginBorderVisibility + "width:0;height:0;position:static;top:0;margin-top:" + conMarginTop + "px"; + body.insertBefore( container, body.firstChild ); + + // Construct the test element + div = document.createElement("div"); + container.appendChild( div ); + + // Check if table cells still have offsetWidth/Height when they are set + // to display:none and there are still other visible table cells in a + // table row; if so, offsetWidth/Height are not reliable for use when + // determining if an element has been hidden directly using + // display:none (it is still safe to use offsets if a parent element is + // hidden; don safety goggles and see bug #4512 for more information). + // (only IE 8 fails this test) + div.innerHTML = "
    t
    "; + tds = div.getElementsByTagName( "td" ); + isSupported = ( tds[ 0 ].offsetHeight === 0 ); + + tds[ 0 ].style.display = ""; + tds[ 1 ].style.display = "none"; + + // Check if empty table cells still have offsetWidth/Height + // (IE <= 8 fail this test) + support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 ); + + // Check if div with explicit width and no margin-right incorrectly + // gets computed margin-right based on width of container. For more + // info see bug #3333 + // Fails in WebKit before Feb 2011 nightlies + // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right + if ( window.getComputedStyle ) { + div.innerHTML = ""; + marginDiv = document.createElement( "div" ); + marginDiv.style.width = "0"; + marginDiv.style.marginRight = "0"; + div.style.width = "2px"; + div.appendChild( marginDiv ); + support.reliableMarginRight = + ( parseInt( ( window.getComputedStyle( marginDiv, null ) || { marginRight: 0 } ).marginRight, 10 ) || 0 ) === 0; + } + + if ( typeof div.style.zoom !== "undefined" ) { + // Check if natively block-level elements act like inline-block + // elements when setting their display to 'inline' and giving + // them layout + // (IE < 8 does this) + div.innerHTML = ""; + div.style.width = div.style.padding = "1px"; + div.style.border = 0; + div.style.overflow = "hidden"; + div.style.display = "inline"; + div.style.zoom = 1; + support.inlineBlockNeedsLayout = ( div.offsetWidth === 3 ); + + // Check if elements with layout shrink-wrap their children + // (IE 6 does this) + div.style.display = "block"; + div.style.overflow = "visible"; + div.innerHTML = "
    "; + support.shrinkWrapBlocks = ( div.offsetWidth !== 3 ); + } + + div.style.cssText = positionTopLeftWidthHeight + paddingMarginBorderVisibility; + div.innerHTML = html; + + outer = div.firstChild; + inner = outer.firstChild; + td = outer.nextSibling.firstChild.firstChild; + + offsetSupport = { + doesNotAddBorder: ( inner.offsetTop !== 5 ), + doesAddBorderForTableAndCells: ( td.offsetTop === 5 ) + }; + + inner.style.position = "fixed"; + inner.style.top = "20px"; + + // safari subtracts parent border width here which is 5px + offsetSupport.fixedPosition = ( inner.offsetTop === 20 || inner.offsetTop === 15 ); + inner.style.position = inner.style.top = ""; + + outer.style.overflow = "hidden"; + outer.style.position = "relative"; + + offsetSupport.subtractsBorderForOverflowNotVisible = ( inner.offsetTop === -5 ); + offsetSupport.doesNotIncludeMarginInBodyOffset = ( body.offsetTop !== conMarginTop ); + + if ( window.getComputedStyle ) { + div.style.marginTop = "1%"; + support.pixelMargin = ( window.getComputedStyle( div, null ) || { marginTop: 0 } ).marginTop !== "1%"; + } + + if ( typeof container.style.zoom !== "undefined" ) { + container.style.zoom = 1; + } + + body.removeChild( container ); + marginDiv = div = container = null; + + jQuery.extend( support, offsetSupport ); + }); + + return support; +})(); + + + + +var rbrace = /^(?:\{.*\}|\[.*\])$/, + rmultiDash = /([A-Z])/g; + +jQuery.extend({ + cache: {}, + + // Please use with caution + uuid: 0, + + // Unique for each copy of jQuery on the page + // Non-digits removed to match rinlinejQuery + expando: "jQuery" + ( jQuery.fn.jquery + Math.random() ).replace( /\D/g, "" ), + + // The following elements throw uncatchable exceptions if you + // attempt to add expando properties to them. + noData: { + "embed": true, + // Ban all objects except for Flash (which handle expandos) + "object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000", + "applet": true + }, + + hasData: function( elem ) { + elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ]; + return !!elem && !isEmptyDataObject( elem ); + }, + + data: function( elem, name, data, pvt /* Internal Use Only */ ) { + if ( !jQuery.acceptData( elem ) ) { + return; + } + + var privateCache, thisCache, ret, + internalKey = jQuery.expando, + getByName = typeof name === "string", + + // We have to handle DOM nodes and JS objects differently because IE6-7 + // can't GC object references properly across the DOM-JS boundary + isNode = elem.nodeType, + + // Only DOM nodes need the global jQuery cache; JS object data is + // attached directly to the object so GC can occur automatically + cache = isNode ? jQuery.cache : elem, + + // Only defining an ID for JS objects if its cache already exists allows + // the code to shortcut on the same path as a DOM node with no cache + id = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey, + isEvents = name === "events"; + + // Avoid doing any more work than we need to when trying to get data on an + // object that has no data at all + if ( (!id || !cache[id] || (!isEvents && !pvt && !cache[id].data)) && getByName && data === undefined ) { + return; + } + + if ( !id ) { + // Only DOM nodes need a new unique ID for each element since their data + // ends up in the global cache + if ( isNode ) { + elem[ internalKey ] = id = ++jQuery.uuid; + } else { + id = internalKey; + } + } + + if ( !cache[ id ] ) { + cache[ id ] = {}; + + // Avoids exposing jQuery metadata on plain JS objects when the object + // is serialized using JSON.stringify + if ( !isNode ) { + cache[ id ].toJSON = jQuery.noop; + } + } + + // An object can be passed to jQuery.data instead of a key/value pair; this gets + // shallow copied over onto the existing cache + if ( typeof name === "object" || typeof name === "function" ) { + if ( pvt ) { + cache[ id ] = jQuery.extend( cache[ id ], name ); + } else { + cache[ id ].data = jQuery.extend( cache[ id ].data, name ); + } + } + + privateCache = thisCache = cache[ id ]; + + // jQuery data() is stored in a separate object inside the object's internal data + // cache in order to avoid key collisions between internal data and user-defined + // data. + if ( !pvt ) { + if ( !thisCache.data ) { + thisCache.data = {}; + } + + thisCache = thisCache.data; + } + + if ( data !== undefined ) { + thisCache[ jQuery.camelCase( name ) ] = data; + } + + // Users should not attempt to inspect the internal events object using jQuery.data, + // it is undocumented and subject to change. But does anyone listen? No. + if ( isEvents && !thisCache[ name ] ) { + return privateCache.events; + } + + // Check for both converted-to-camel and non-converted data property names + // If a data property was specified + if ( getByName ) { + + // First Try to find as-is property data + ret = thisCache[ name ]; + + // Test for null|undefined property data + if ( ret == null ) { + + // Try to find the camelCased property + ret = thisCache[ jQuery.camelCase( name ) ]; + } + } else { + ret = thisCache; + } + + return ret; + }, + + removeData: function( elem, name, pvt /* Internal Use Only */ ) { + if ( !jQuery.acceptData( elem ) ) { + return; + } + + var thisCache, i, l, + + // Reference to internal data cache key + internalKey = jQuery.expando, + + isNode = elem.nodeType, + + // See jQuery.data for more information + cache = isNode ? jQuery.cache : elem, + + // See jQuery.data for more information + id = isNode ? elem[ internalKey ] : internalKey; + + // If there is already no cache entry for this object, there is no + // purpose in continuing + if ( !cache[ id ] ) { + return; + } + + if ( name ) { + + thisCache = pvt ? cache[ id ] : cache[ id ].data; + + if ( thisCache ) { + + // Support array or space separated string names for data keys + if ( !jQuery.isArray( name ) ) { + + // try the string as a key before any manipulation + if ( name in thisCache ) { + name = [ name ]; + } else { + + // split the camel cased version by spaces unless a key with the spaces exists + name = jQuery.camelCase( name ); + if ( name in thisCache ) { + name = [ name ]; + } else { + name = name.split( " " ); + } + } + } + + for ( i = 0, l = name.length; i < l; i++ ) { + delete thisCache[ name[i] ]; + } + + // If there is no data left in the cache, we want to continue + // and let the cache object itself get destroyed + if ( !( pvt ? isEmptyDataObject : jQuery.isEmptyObject )( thisCache ) ) { + return; + } + } + } + + // See jQuery.data for more information + if ( !pvt ) { + delete cache[ id ].data; + + // Don't destroy the parent cache unless the internal data object + // had been the only thing left in it + if ( !isEmptyDataObject(cache[ id ]) ) { + return; + } + } + + // Browsers that fail expando deletion also refuse to delete expandos on + // the window, but it will allow it on all other JS objects; other browsers + // don't care + // Ensure that `cache` is not a window object #10080 + if ( jQuery.support.deleteExpando || !cache.setInterval ) { + delete cache[ id ]; + } else { + cache[ id ] = null; + } + + // We destroyed the cache and need to eliminate the expando on the node to avoid + // false lookups in the cache for entries that no longer exist + if ( isNode ) { + // IE does not allow us to delete expando properties from nodes, + // nor does it have a removeAttribute function on Document nodes; + // we must handle all of these cases + if ( jQuery.support.deleteExpando ) { + delete elem[ internalKey ]; + } else if ( elem.removeAttribute ) { + elem.removeAttribute( internalKey ); + } else { + elem[ internalKey ] = null; + } + } + }, + + // For internal use only. + _data: function( elem, name, data ) { + return jQuery.data( elem, name, data, true ); + }, + + // A method for determining if a DOM node can handle the data expando + acceptData: function( elem ) { + if ( elem.nodeName ) { + var match = jQuery.noData[ elem.nodeName.toLowerCase() ]; + + if ( match ) { + return !(match === true || elem.getAttribute("classid") !== match); + } + } + + return true; + } +}); + +jQuery.fn.extend({ + data: function( key, value ) { + var parts, part, attr, name, l, + elem = this[0], + i = 0, + data = null; + + // Gets all values + if ( key === undefined ) { + if ( this.length ) { + data = jQuery.data( elem ); + + if ( elem.nodeType === 1 && !jQuery._data( elem, "parsedAttrs" ) ) { + attr = elem.attributes; + for ( l = attr.length; i < l; i++ ) { + name = attr[i].name; + + if ( name.indexOf( "data-" ) === 0 ) { + name = jQuery.camelCase( name.substring(5) ); + + dataAttr( elem, name, data[ name ] ); + } + } + jQuery._data( elem, "parsedAttrs", true ); + } + } + + return data; + } + + // Sets multiple values + if ( typeof key === "object" ) { + return this.each(function() { + jQuery.data( this, key ); + }); + } + + parts = key.split( ".", 2 ); + parts[1] = parts[1] ? "." + parts[1] : ""; + part = parts[1] + "!"; + + return jQuery.access( this, function( value ) { + + if ( value === undefined ) { + data = this.triggerHandler( "getData" + part, [ parts[0] ] ); + + // Try to fetch any internally stored data first + if ( data === undefined && elem ) { + data = jQuery.data( elem, key ); + data = dataAttr( elem, key, data ); + } + + return data === undefined && parts[1] ? + this.data( parts[0] ) : + data; + } + + parts[1] = value; + this.each(function() { + var self = jQuery( this ); + + self.triggerHandler( "setData" + part, parts ); + jQuery.data( this, key, value ); + self.triggerHandler( "changeData" + part, parts ); + }); + }, null, value, arguments.length > 1, null, false ); + }, + + removeData: function( key ) { + return this.each(function() { + jQuery.removeData( this, key ); + }); + } +}); + +function dataAttr( elem, key, data ) { + // If nothing was found internally, try to fetch any + // data from the HTML5 data-* attribute + if ( data === undefined && elem.nodeType === 1 ) { + + var name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase(); + + data = elem.getAttribute( name ); + + if ( typeof data === "string" ) { + try { + data = data === "true" ? true : + data === "false" ? false : + data === "null" ? null : + jQuery.isNumeric( data ) ? +data : + rbrace.test( data ) ? jQuery.parseJSON( data ) : + data; + } catch( e ) {} + + // Make sure we set the data so it isn't changed later + jQuery.data( elem, key, data ); + + } else { + data = undefined; + } + } + + return data; +} + +// checks a cache object for emptiness +function isEmptyDataObject( obj ) { + for ( var name in obj ) { + + // if the public data object is empty, the private is still empty + if ( name === "data" && jQuery.isEmptyObject( obj[name] ) ) { + continue; + } + if ( name !== "toJSON" ) { + return false; + } + } + + return true; +} + + + + +function handleQueueMarkDefer( elem, type, src ) { + var deferDataKey = type + "defer", + queueDataKey = type + "queue", + markDataKey = type + "mark", + defer = jQuery._data( elem, deferDataKey ); + if ( defer && + ( src === "queue" || !jQuery._data(elem, queueDataKey) ) && + ( src === "mark" || !jQuery._data(elem, markDataKey) ) ) { + // Give room for hard-coded callbacks to fire first + // and eventually mark/queue something else on the element + setTimeout( function() { + if ( !jQuery._data( elem, queueDataKey ) && + !jQuery._data( elem, markDataKey ) ) { + jQuery.removeData( elem, deferDataKey, true ); + defer.fire(); + } + }, 0 ); + } +} + +jQuery.extend({ + + _mark: function( elem, type ) { + if ( elem ) { + type = ( type || "fx" ) + "mark"; + jQuery._data( elem, type, (jQuery._data( elem, type ) || 0) + 1 ); + } + }, + + _unmark: function( force, elem, type ) { + if ( force !== true ) { + type = elem; + elem = force; + force = false; + } + if ( elem ) { + type = type || "fx"; + var key = type + "mark", + count = force ? 0 : ( (jQuery._data( elem, key ) || 1) - 1 ); + if ( count ) { + jQuery._data( elem, key, count ); + } else { + jQuery.removeData( elem, key, true ); + handleQueueMarkDefer( elem, type, "mark" ); + } + } + }, + + queue: function( elem, type, data ) { + var q; + if ( elem ) { + type = ( type || "fx" ) + "queue"; + q = jQuery._data( elem, type ); + + // Speed up dequeue by getting out quickly if this is just a lookup + if ( data ) { + if ( !q || jQuery.isArray(data) ) { + q = jQuery._data( elem, type, jQuery.makeArray(data) ); + } else { + q.push( data ); + } + } + return q || []; + } + }, + + dequeue: function( elem, type ) { + type = type || "fx"; + + var queue = jQuery.queue( elem, type ), + fn = queue.shift(), + hooks = {}; + + // If the fx queue is dequeued, always remove the progress sentinel + if ( fn === "inprogress" ) { + fn = queue.shift(); + } + + if ( fn ) { + // Add a progress sentinel to prevent the fx queue from being + // automatically dequeued + if ( type === "fx" ) { + queue.unshift( "inprogress" ); + } + + jQuery._data( elem, type + ".run", hooks ); + fn.call( elem, function() { + jQuery.dequeue( elem, type ); + }, hooks ); + } + + if ( !queue.length ) { + jQuery.removeData( elem, type + "queue " + type + ".run", true ); + handleQueueMarkDefer( elem, type, "queue" ); + } + } +}); + +jQuery.fn.extend({ + queue: function( type, data ) { + var setter = 2; + + if ( typeof type !== "string" ) { + data = type; + type = "fx"; + setter--; + } + + if ( arguments.length < setter ) { + return jQuery.queue( this[0], type ); + } + + return data === undefined ? + this : + this.each(function() { + var queue = jQuery.queue( this, type, data ); + + if ( type === "fx" && queue[0] !== "inprogress" ) { + jQuery.dequeue( this, type ); + } + }); + }, + dequeue: function( type ) { + return this.each(function() { + jQuery.dequeue( this, type ); + }); + }, + // Based off of the plugin by Clint Helfers, with permission. + // http://blindsignals.com/index.php/2009/07/jquery-delay/ + delay: function( time, type ) { + time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time; + type = type || "fx"; + + return this.queue( type, function( next, hooks ) { + var timeout = setTimeout( next, time ); + hooks.stop = function() { + clearTimeout( timeout ); + }; + }); + }, + clearQueue: function( type ) { + return this.queue( type || "fx", [] ); + }, + // Get a promise resolved when queues of a certain type + // are emptied (fx is the type by default) + promise: function( type, object ) { + if ( typeof type !== "string" ) { + object = type; + type = undefined; + } + type = type || "fx"; + var defer = jQuery.Deferred(), + elements = this, + i = elements.length, + count = 1, + deferDataKey = type + "defer", + queueDataKey = type + "queue", + markDataKey = type + "mark", + tmp; + function resolve() { + if ( !( --count ) ) { + defer.resolveWith( elements, [ elements ] ); + } + } + while( i-- ) { + if (( tmp = jQuery.data( elements[ i ], deferDataKey, undefined, true ) || + ( jQuery.data( elements[ i ], queueDataKey, undefined, true ) || + jQuery.data( elements[ i ], markDataKey, undefined, true ) ) && + jQuery.data( elements[ i ], deferDataKey, jQuery.Callbacks( "once memory" ), true ) )) { + count++; + tmp.add( resolve ); + } + } + resolve(); + return defer.promise( object ); + } +}); + + + + +var rclass = /[\n\t\r]/g, + rspace = /\s+/, + rreturn = /\r/g, + rtype = /^(?:button|input)$/i, + rfocusable = /^(?:button|input|object|select|textarea)$/i, + rclickable = /^a(?:rea)?$/i, + rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i, + getSetAttribute = jQuery.support.getSetAttribute, + nodeHook, boolHook, fixSpecified; + +jQuery.fn.extend({ + attr: function( name, value ) { + return jQuery.access( this, jQuery.attr, name, value, arguments.length > 1 ); + }, + + removeAttr: function( name ) { + return this.each(function() { + jQuery.removeAttr( this, name ); + }); + }, + + prop: function( name, value ) { + return jQuery.access( this, jQuery.prop, name, value, arguments.length > 1 ); + }, + + removeProp: function( name ) { + name = jQuery.propFix[ name ] || name; + return this.each(function() { + // try/catch handles cases where IE balks (such as removing a property on window) + try { + this[ name ] = undefined; + delete this[ name ]; + } catch( e ) {} + }); + }, + + addClass: function( value ) { + var classNames, i, l, elem, + setClass, c, cl; + + if ( jQuery.isFunction( value ) ) { + return this.each(function( j ) { + jQuery( this ).addClass( value.call(this, j, this.className) ); + }); + } + + if ( value && typeof value === "string" ) { + classNames = value.split( rspace ); + + for ( i = 0, l = this.length; i < l; i++ ) { + elem = this[ i ]; + + if ( elem.nodeType === 1 ) { + if ( !elem.className && classNames.length === 1 ) { + elem.className = value; + + } else { + setClass = " " + elem.className + " "; + + for ( c = 0, cl = classNames.length; c < cl; c++ ) { + if ( !~setClass.indexOf( " " + classNames[ c ] + " " ) ) { + setClass += classNames[ c ] + " "; + } + } + elem.className = jQuery.trim( setClass ); + } + } + } + } + + return this; + }, + + removeClass: function( value ) { + var classNames, i, l, elem, className, c, cl; + + if ( jQuery.isFunction( value ) ) { + return this.each(function( j ) { + jQuery( this ).removeClass( value.call(this, j, this.className) ); + }); + } + + if ( (value && typeof value === "string") || value === undefined ) { + classNames = ( value || "" ).split( rspace ); + + for ( i = 0, l = this.length; i < l; i++ ) { + elem = this[ i ]; + + if ( elem.nodeType === 1 && elem.className ) { + if ( value ) { + className = (" " + elem.className + " ").replace( rclass, " " ); + for ( c = 0, cl = classNames.length; c < cl; c++ ) { + className = className.replace(" " + classNames[ c ] + " ", " "); + } + elem.className = jQuery.trim( className ); + + } else { + elem.className = ""; + } + } + } + } + + return this; + }, + + toggleClass: function( value, stateVal ) { + var type = typeof value, + isBool = typeof stateVal === "boolean"; + + if ( jQuery.isFunction( value ) ) { + return this.each(function( i ) { + jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal ); + }); + } + + return this.each(function() { + if ( type === "string" ) { + // toggle individual class names + var className, + i = 0, + self = jQuery( this ), + state = stateVal, + classNames = value.split( rspace ); + + while ( (className = classNames[ i++ ]) ) { + // check each className given, space seperated list + state = isBool ? state : !self.hasClass( className ); + self[ state ? "addClass" : "removeClass" ]( className ); + } + + } else if ( type === "undefined" || type === "boolean" ) { + if ( this.className ) { + // store className if set + jQuery._data( this, "__className__", this.className ); + } + + // toggle whole className + this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || ""; + } + }); + }, + + hasClass: function( selector ) { + var className = " " + selector + " ", + i = 0, + l = this.length; + for ( ; i < l; i++ ) { + if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) { + return true; + } + } + + return false; + }, + + val: function( value ) { + var hooks, ret, isFunction, + elem = this[0]; + + if ( !arguments.length ) { + if ( elem ) { + hooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ]; + + if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) { + return ret; + } + + ret = elem.value; + + return typeof ret === "string" ? + // handle most common string cases + ret.replace(rreturn, "") : + // handle cases where value is null/undef or number + ret == null ? "" : ret; + } + + return; + } + + isFunction = jQuery.isFunction( value ); + + return this.each(function( i ) { + var self = jQuery(this), val; + + if ( this.nodeType !== 1 ) { + return; + } + + if ( isFunction ) { + val = value.call( this, i, self.val() ); + } else { + val = value; + } + + // Treat null/undefined as ""; convert numbers to string + if ( val == null ) { + val = ""; + } else if ( typeof val === "number" ) { + val += ""; + } else if ( jQuery.isArray( val ) ) { + val = jQuery.map(val, function ( value ) { + return value == null ? "" : value + ""; + }); + } + + hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ]; + + // If set returns undefined, fall back to normal setting + if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) { + this.value = val; + } + }); + } +}); + +jQuery.extend({ + valHooks: { + option: { + get: function( elem ) { + // attributes.value is undefined in Blackberry 4.7 but + // uses .value. See #6932 + var val = elem.attributes.value; + return !val || val.specified ? elem.value : elem.text; + } + }, + select: { + get: function( elem ) { + var value, i, max, option, + index = elem.selectedIndex, + values = [], + options = elem.options, + one = elem.type === "select-one"; + + // Nothing was selected + if ( index < 0 ) { + return null; + } + + // Loop through all the selected options + i = one ? index : 0; + max = one ? index + 1 : options.length; + for ( ; i < max; i++ ) { + option = options[ i ]; + + // Don't return options that are disabled or in a disabled optgroup + if ( option.selected && (jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null) && + (!option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" )) ) { + + // Get the specific value for the option + value = jQuery( option ).val(); + + // We don't need an array for one selects + if ( one ) { + return value; + } + + // Multi-Selects return an array + values.push( value ); + } + } + + // Fixes Bug #2551 -- select.val() broken in IE after form.reset() + if ( one && !values.length && options.length ) { + return jQuery( options[ index ] ).val(); + } + + return values; + }, + + set: function( elem, value ) { + var values = jQuery.makeArray( value ); + + jQuery(elem).find("option").each(function() { + this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0; + }); + + if ( !values.length ) { + elem.selectedIndex = -1; + } + return values; + } + } + }, + + attrFn: { + val: true, + css: true, + html: true, + text: true, + data: true, + width: true, + height: true, + offset: true + }, + + attr: function( elem, name, value, pass ) { + var ret, hooks, notxml, + nType = elem.nodeType; + + // don't get/set attributes on text, comment and attribute nodes + if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + if ( pass && name in jQuery.attrFn ) { + return jQuery( elem )[ name ]( value ); + } + + // Fallback to prop when attributes are not supported + if ( typeof elem.getAttribute === "undefined" ) { + return jQuery.prop( elem, name, value ); + } + + notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); + + // All attributes are lowercase + // Grab necessary hook if one is defined + if ( notxml ) { + name = name.toLowerCase(); + hooks = jQuery.attrHooks[ name ] || ( rboolean.test( name ) ? boolHook : nodeHook ); + } + + if ( value !== undefined ) { + + if ( value === null ) { + jQuery.removeAttr( elem, name ); + return; + + } else if ( hooks && "set" in hooks && notxml && (ret = hooks.set( elem, value, name )) !== undefined ) { + return ret; + + } else { + elem.setAttribute( name, "" + value ); + return value; + } + + } else if ( hooks && "get" in hooks && notxml && (ret = hooks.get( elem, name )) !== null ) { + return ret; + + } else { + + ret = elem.getAttribute( name ); + + // Non-existent attributes return null, we normalize to undefined + return ret === null ? + undefined : + ret; + } + }, + + removeAttr: function( elem, value ) { + var propName, attrNames, name, l, isBool, + i = 0; + + if ( value && elem.nodeType === 1 ) { + attrNames = value.toLowerCase().split( rspace ); + l = attrNames.length; + + for ( ; i < l; i++ ) { + name = attrNames[ i ]; + + if ( name ) { + propName = jQuery.propFix[ name ] || name; + isBool = rboolean.test( name ); + + // See #9699 for explanation of this approach (setting first, then removal) + // Do not do this for boolean attributes (see #10870) + if ( !isBool ) { + jQuery.attr( elem, name, "" ); + } + elem.removeAttribute( getSetAttribute ? name : propName ); + + // Set corresponding property to false for boolean attributes + if ( isBool && propName in elem ) { + elem[ propName ] = false; + } + } + } + } + }, + + attrHooks: { + type: { + set: function( elem, value ) { + // We can't allow the type property to be changed (since it causes problems in IE) + if ( rtype.test( elem.nodeName ) && elem.parentNode ) { + jQuery.error( "type property can't be changed" ); + } else if ( !jQuery.support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) { + // Setting the type on a radio button after the value resets the value in IE6-9 + // Reset value to it's default in case type is set after value + // This is for element creation + var val = elem.value; + elem.setAttribute( "type", value ); + if ( val ) { + elem.value = val; + } + return value; + } + } + }, + // Use the value property for back compat + // Use the nodeHook for button elements in IE6/7 (#1954) + value: { + get: function( elem, name ) { + if ( nodeHook && jQuery.nodeName( elem, "button" ) ) { + return nodeHook.get( elem, name ); + } + return name in elem ? + elem.value : + null; + }, + set: function( elem, value, name ) { + if ( nodeHook && jQuery.nodeName( elem, "button" ) ) { + return nodeHook.set( elem, value, name ); + } + // Does not return so that setAttribute is also used + elem.value = value; + } + } + }, + + propFix: { + tabindex: "tabIndex", + readonly: "readOnly", + "for": "htmlFor", + "class": "className", + maxlength: "maxLength", + cellspacing: "cellSpacing", + cellpadding: "cellPadding", + rowspan: "rowSpan", + colspan: "colSpan", + usemap: "useMap", + frameborder: "frameBorder", + contenteditable: "contentEditable" + }, + + prop: function( elem, name, value ) { + var ret, hooks, notxml, + nType = elem.nodeType; + + // don't get/set properties on text, comment and attribute nodes + if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); + + if ( notxml ) { + // Fix name and attach hooks + name = jQuery.propFix[ name ] || name; + hooks = jQuery.propHooks[ name ]; + } + + if ( value !== undefined ) { + if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) { + return ret; + + } else { + return ( elem[ name ] = value ); + } + + } else { + if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) { + return ret; + + } else { + return elem[ name ]; + } + } + }, + + propHooks: { + tabIndex: { + get: function( elem ) { + // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set + // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ + var attributeNode = elem.getAttributeNode("tabindex"); + + return attributeNode && attributeNode.specified ? + parseInt( attributeNode.value, 10 ) : + rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ? + 0 : + undefined; + } + } + } +}); + +// Add the tabIndex propHook to attrHooks for back-compat (different case is intentional) +jQuery.attrHooks.tabindex = jQuery.propHooks.tabIndex; + +// Hook for boolean attributes +boolHook = { + get: function( elem, name ) { + // Align boolean attributes with corresponding properties + // Fall back to attribute presence where some booleans are not supported + var attrNode, + property = jQuery.prop( elem, name ); + return property === true || typeof property !== "boolean" && ( attrNode = elem.getAttributeNode(name) ) && attrNode.nodeValue !== false ? + name.toLowerCase() : + undefined; + }, + set: function( elem, value, name ) { + var propName; + if ( value === false ) { + // Remove boolean attributes when set to false + jQuery.removeAttr( elem, name ); + } else { + // value is true since we know at this point it's type boolean and not false + // Set boolean attributes to the same name and set the DOM property + propName = jQuery.propFix[ name ] || name; + if ( propName in elem ) { + // Only set the IDL specifically if it already exists on the element + elem[ propName ] = true; + } + + elem.setAttribute( name, name.toLowerCase() ); + } + return name; + } +}; + +// IE6/7 do not support getting/setting some attributes with get/setAttribute +if ( !getSetAttribute ) { + + fixSpecified = { + name: true, + id: true, + coords: true + }; + + // Use this for any attribute in IE6/7 + // This fixes almost every IE6/7 issue + nodeHook = jQuery.valHooks.button = { + get: function( elem, name ) { + var ret; + ret = elem.getAttributeNode( name ); + return ret && ( fixSpecified[ name ] ? ret.nodeValue !== "" : ret.specified ) ? + ret.nodeValue : + undefined; + }, + set: function( elem, value, name ) { + // Set the existing or create a new attribute node + var ret = elem.getAttributeNode( name ); + if ( !ret ) { + ret = document.createAttribute( name ); + elem.setAttributeNode( ret ); + } + return ( ret.nodeValue = value + "" ); + } + }; + + // Apply the nodeHook to tabindex + jQuery.attrHooks.tabindex.set = nodeHook.set; + + // Set width and height to auto instead of 0 on empty string( Bug #8150 ) + // This is for removals + jQuery.each([ "width", "height" ], function( i, name ) { + jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], { + set: function( elem, value ) { + if ( value === "" ) { + elem.setAttribute( name, "auto" ); + return value; + } + } + }); + }); + + // Set contenteditable to false on removals(#10429) + // Setting to empty string throws an error as an invalid value + jQuery.attrHooks.contenteditable = { + get: nodeHook.get, + set: function( elem, value, name ) { + if ( value === "" ) { + value = "false"; + } + nodeHook.set( elem, value, name ); + } + }; +} + + +// Some attributes require a special call on IE +if ( !jQuery.support.hrefNormalized ) { + jQuery.each([ "href", "src", "width", "height" ], function( i, name ) { + jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], { + get: function( elem ) { + var ret = elem.getAttribute( name, 2 ); + return ret === null ? undefined : ret; + } + }); + }); +} + +if ( !jQuery.support.style ) { + jQuery.attrHooks.style = { + get: function( elem ) { + // Return undefined in the case of empty string + // Normalize to lowercase since IE uppercases css property names + return elem.style.cssText.toLowerCase() || undefined; + }, + set: function( elem, value ) { + return ( elem.style.cssText = "" + value ); + } + }; +} + +// Safari mis-reports the default selected property of an option +// Accessing the parent's selectedIndex property fixes it +if ( !jQuery.support.optSelected ) { + jQuery.propHooks.selected = jQuery.extend( jQuery.propHooks.selected, { + get: function( elem ) { + var parent = elem.parentNode; + + if ( parent ) { + parent.selectedIndex; + + // Make sure that it also works with optgroups, see #5701 + if ( parent.parentNode ) { + parent.parentNode.selectedIndex; + } + } + return null; + } + }); +} + +// IE6/7 call enctype encoding +if ( !jQuery.support.enctype ) { + jQuery.propFix.enctype = "encoding"; +} + +// Radios and checkboxes getter/setter +if ( !jQuery.support.checkOn ) { + jQuery.each([ "radio", "checkbox" ], function() { + jQuery.valHooks[ this ] = { + get: function( elem ) { + // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified + return elem.getAttribute("value") === null ? "on" : elem.value; + } + }; + }); +} +jQuery.each([ "radio", "checkbox" ], function() { + jQuery.valHooks[ this ] = jQuery.extend( jQuery.valHooks[ this ], { + set: function( elem, value ) { + if ( jQuery.isArray( value ) ) { + return ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 ); + } + } + }); +}); + + + + +var rformElems = /^(?:textarea|input|select)$/i, + rtypenamespace = /^([^\.]*)?(?:\.(.+))?$/, + rhoverHack = /(?:^|\s)hover(\.\S+)?\b/, + rkeyEvent = /^key/, + rmouseEvent = /^(?:mouse|contextmenu)|click/, + rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, + rquickIs = /^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/, + quickParse = function( selector ) { + var quick = rquickIs.exec( selector ); + if ( quick ) { + // 0 1 2 3 + // [ _, tag, id, class ] + quick[1] = ( quick[1] || "" ).toLowerCase(); + quick[3] = quick[3] && new RegExp( "(?:^|\\s)" + quick[3] + "(?:\\s|$)" ); + } + return quick; + }, + quickIs = function( elem, m ) { + var attrs = elem.attributes || {}; + return ( + (!m[1] || elem.nodeName.toLowerCase() === m[1]) && + (!m[2] || (attrs.id || {}).value === m[2]) && + (!m[3] || m[3].test( (attrs[ "class" ] || {}).value )) + ); + }, + hoverHack = function( events ) { + return jQuery.event.special.hover ? events : events.replace( rhoverHack, "mouseenter$1 mouseleave$1" ); + }; + +/* + * Helper functions for managing events -- not part of the public interface. + * Props to Dean Edwards' addEvent library for many of the ideas. + */ +jQuery.event = { + + add: function( elem, types, handler, data, selector ) { + + var elemData, eventHandle, events, + t, tns, type, namespaces, handleObj, + handleObjIn, quick, handlers, special; + + // Don't attach events to noData or text/comment nodes (allow plain objects tho) + if ( elem.nodeType === 3 || elem.nodeType === 8 || !types || !handler || !(elemData = jQuery._data( elem )) ) { + return; + } + + // Caller can pass in an object of custom data in lieu of the handler + if ( handler.handler ) { + handleObjIn = handler; + handler = handleObjIn.handler; + selector = handleObjIn.selector; + } + + // Make sure that the handler has a unique ID, used to find/remove it later + if ( !handler.guid ) { + handler.guid = jQuery.guid++; + } + + // Init the element's event structure and main handler, if this is the first + events = elemData.events; + if ( !events ) { + elemData.events = events = {}; + } + eventHandle = elemData.handle; + if ( !eventHandle ) { + elemData.handle = eventHandle = function( e ) { + // Discard the second event of a jQuery.event.trigger() and + // when an event is called after a page has unloaded + return typeof jQuery !== "undefined" && (!e || jQuery.event.triggered !== e.type) ? + jQuery.event.dispatch.apply( eventHandle.elem, arguments ) : + undefined; + }; + // Add elem as a property of the handle fn to prevent a memory leak with IE non-native events + eventHandle.elem = elem; + } + + // Handle multiple events separated by a space + // jQuery(...).bind("mouseover mouseout", fn); + types = jQuery.trim( hoverHack(types) ).split( " " ); + for ( t = 0; t < types.length; t++ ) { + + tns = rtypenamespace.exec( types[t] ) || []; + type = tns[1]; + namespaces = ( tns[2] || "" ).split( "." ).sort(); + + // If event changes its type, use the special event handlers for the changed type + special = jQuery.event.special[ type ] || {}; + + // If selector defined, determine special event api type, otherwise given type + type = ( selector ? special.delegateType : special.bindType ) || type; + + // Update special based on newly reset type + special = jQuery.event.special[ type ] || {}; + + // handleObj is passed to all event handlers + handleObj = jQuery.extend({ + type: type, + origType: tns[1], + data: data, + handler: handler, + guid: handler.guid, + selector: selector, + quick: selector && quickParse( selector ), + namespace: namespaces.join(".") + }, handleObjIn ); + + // Init the event handler queue if we're the first + handlers = events[ type ]; + if ( !handlers ) { + handlers = events[ type ] = []; + handlers.delegateCount = 0; + + // Only use addEventListener/attachEvent if the special events handler returns false + if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) { + // Bind the global event handler to the element + if ( elem.addEventListener ) { + elem.addEventListener( type, eventHandle, false ); + + } else if ( elem.attachEvent ) { + elem.attachEvent( "on" + type, eventHandle ); + } + } + } + + if ( special.add ) { + special.add.call( elem, handleObj ); + + if ( !handleObj.handler.guid ) { + handleObj.handler.guid = handler.guid; + } + } + + // Add to the element's handler list, delegates in front + if ( selector ) { + handlers.splice( handlers.delegateCount++, 0, handleObj ); + } else { + handlers.push( handleObj ); + } + + // Keep track of which events have ever been used, for event optimization + jQuery.event.global[ type ] = true; + } + + // Nullify elem to prevent memory leaks in IE + elem = null; + }, + + global: {}, + + // Detach an event or set of events from an element + remove: function( elem, types, handler, selector, mappedTypes ) { + + var elemData = jQuery.hasData( elem ) && jQuery._data( elem ), + t, tns, type, origType, namespaces, origCount, + j, events, special, handle, eventType, handleObj; + + if ( !elemData || !(events = elemData.events) ) { + return; + } + + // Once for each type.namespace in types; type may be omitted + types = jQuery.trim( hoverHack( types || "" ) ).split(" "); + for ( t = 0; t < types.length; t++ ) { + tns = rtypenamespace.exec( types[t] ) || []; + type = origType = tns[1]; + namespaces = tns[2]; + + // Unbind all events (on this namespace, if provided) for the element + if ( !type ) { + for ( type in events ) { + jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); + } + continue; + } + + special = jQuery.event.special[ type ] || {}; + type = ( selector? special.delegateType : special.bindType ) || type; + eventType = events[ type ] || []; + origCount = eventType.length; + namespaces = namespaces ? new RegExp("(^|\\.)" + namespaces.split(".").sort().join("\\.(?:.*\\.)?") + "(\\.|$)") : null; + + // Remove matching events + for ( j = 0; j < eventType.length; j++ ) { + handleObj = eventType[ j ]; + + if ( ( mappedTypes || origType === handleObj.origType ) && + ( !handler || handler.guid === handleObj.guid ) && + ( !namespaces || namespaces.test( handleObj.namespace ) ) && + ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) { + eventType.splice( j--, 1 ); + + if ( handleObj.selector ) { + eventType.delegateCount--; + } + if ( special.remove ) { + special.remove.call( elem, handleObj ); + } + } + } + + // Remove generic event handler if we removed something and no more handlers exist + // (avoids potential for endless recursion during removal of special event handlers) + if ( eventType.length === 0 && origCount !== eventType.length ) { + if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) { + jQuery.removeEvent( elem, type, elemData.handle ); + } + + delete events[ type ]; + } + } + + // Remove the expando if it's no longer used + if ( jQuery.isEmptyObject( events ) ) { + handle = elemData.handle; + if ( handle ) { + handle.elem = null; + } + + // removeData also checks for emptiness and clears the expando if empty + // so use it instead of delete + jQuery.removeData( elem, [ "events", "handle" ], true ); + } + }, + + // Events that are safe to short-circuit if no handlers are attached. + // Native DOM events should not be added, they may have inline handlers. + customEvent: { + "getData": true, + "setData": true, + "changeData": true + }, + + trigger: function( event, data, elem, onlyHandlers ) { + // Don't do events on text and comment nodes + if ( elem && (elem.nodeType === 3 || elem.nodeType === 8) ) { + return; + } + + // Event object or event type + var type = event.type || event, + namespaces = [], + cache, exclusive, i, cur, old, ontype, special, handle, eventPath, bubbleType; + + // focus/blur morphs to focusin/out; ensure we're not firing them right now + if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { + return; + } + + if ( type.indexOf( "!" ) >= 0 ) { + // Exclusive events trigger only for the exact event (no namespaces) + type = type.slice(0, -1); + exclusive = true; + } + + if ( type.indexOf( "." ) >= 0 ) { + // Namespaced trigger; create a regexp to match event type in handle() + namespaces = type.split("."); + type = namespaces.shift(); + namespaces.sort(); + } + + if ( (!elem || jQuery.event.customEvent[ type ]) && !jQuery.event.global[ type ] ) { + // No jQuery handlers for this event type, and it can't have inline handlers + return; + } + + // Caller can pass in an Event, Object, or just an event type string + event = typeof event === "object" ? + // jQuery.Event object + event[ jQuery.expando ] ? event : + // Object literal + new jQuery.Event( type, event ) : + // Just the event type (string) + new jQuery.Event( type ); + + event.type = type; + event.isTrigger = true; + event.exclusive = exclusive; + event.namespace = namespaces.join( "." ); + event.namespace_re = event.namespace? new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.)?") + "(\\.|$)") : null; + ontype = type.indexOf( ":" ) < 0 ? "on" + type : ""; + + // Handle a global trigger + if ( !elem ) { + + // TODO: Stop taunting the data cache; remove global events and always attach to document + cache = jQuery.cache; + for ( i in cache ) { + if ( cache[ i ].events && cache[ i ].events[ type ] ) { + jQuery.event.trigger( event, data, cache[ i ].handle.elem, true ); + } + } + return; + } + + // Clean up the event in case it is being reused + event.result = undefined; + if ( !event.target ) { + event.target = elem; + } + + // Clone any incoming data and prepend the event, creating the handler arg list + data = data != null ? jQuery.makeArray( data ) : []; + data.unshift( event ); + + // Allow special events to draw outside the lines + special = jQuery.event.special[ type ] || {}; + if ( special.trigger && special.trigger.apply( elem, data ) === false ) { + return; + } + + // Determine event propagation path in advance, per W3C events spec (#9951) + // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) + eventPath = [[ elem, special.bindType || type ]]; + if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) { + + bubbleType = special.delegateType || type; + cur = rfocusMorph.test( bubbleType + type ) ? elem : elem.parentNode; + old = null; + for ( ; cur; cur = cur.parentNode ) { + eventPath.push([ cur, bubbleType ]); + old = cur; + } + + // Only add window if we got to document (e.g., not plain obj or detached DOM) + if ( old && old === elem.ownerDocument ) { + eventPath.push([ old.defaultView || old.parentWindow || window, bubbleType ]); + } + } + + // Fire handlers on the event path + for ( i = 0; i < eventPath.length && !event.isPropagationStopped(); i++ ) { + + cur = eventPath[i][0]; + event.type = eventPath[i][1]; + + handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] && jQuery._data( cur, "handle" ); + if ( handle ) { + handle.apply( cur, data ); + } + // Note that this is a bare JS function and not a jQuery handler + handle = ontype && cur[ ontype ]; + if ( handle && jQuery.acceptData( cur ) && handle.apply( cur, data ) === false ) { + event.preventDefault(); + } + } + event.type = type; + + // If nobody prevented the default action, do it now + if ( !onlyHandlers && !event.isDefaultPrevented() ) { + + if ( (!special._default || special._default.apply( elem.ownerDocument, data ) === false) && + !(type === "click" && jQuery.nodeName( elem, "a" )) && jQuery.acceptData( elem ) ) { + + // Call a native DOM method on the target with the same name name as the event. + // Can't use an .isFunction() check here because IE6/7 fails that test. + // Don't do default actions on window, that's where global variables be (#6170) + // IE<9 dies on focus/blur to hidden element (#1486) + if ( ontype && elem[ type ] && ((type !== "focus" && type !== "blur") || event.target.offsetWidth !== 0) && !jQuery.isWindow( elem ) ) { + + // Don't re-trigger an onFOO event when we call its FOO() method + old = elem[ ontype ]; + + if ( old ) { + elem[ ontype ] = null; + } + + // Prevent re-triggering of the same event, since we already bubbled it above + jQuery.event.triggered = type; + elem[ type ](); + jQuery.event.triggered = undefined; + + if ( old ) { + elem[ ontype ] = old; + } + } + } + } + + return event.result; + }, + + dispatch: function( event ) { + + // Make a writable jQuery.Event from the native event object + event = jQuery.event.fix( event || window.event ); + + var handlers = ( (jQuery._data( this, "events" ) || {} )[ event.type ] || []), + delegateCount = handlers.delegateCount, + args = [].slice.call( arguments, 0 ), + run_all = !event.exclusive && !event.namespace, + special = jQuery.event.special[ event.type ] || {}, + handlerQueue = [], + i, j, cur, jqcur, ret, selMatch, matched, matches, handleObj, sel, related; + + // Use the fix-ed jQuery.Event rather than the (read-only) native event + args[0] = event; + event.delegateTarget = this; + + // Call the preDispatch hook for the mapped type, and let it bail if desired + if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { + return; + } + + // Determine handlers that should run if there are delegated events + // Avoid non-left-click bubbling in Firefox (#3861) + if ( delegateCount && !(event.button && event.type === "click") ) { + + // Pregenerate a single jQuery object for reuse with .is() + jqcur = jQuery(this); + jqcur.context = this.ownerDocument || this; + + for ( cur = event.target; cur != this; cur = cur.parentNode || this ) { + + // Don't process events on disabled elements (#6911, #8165) + if ( cur.disabled !== true ) { + selMatch = {}; + matches = []; + jqcur[0] = cur; + for ( i = 0; i < delegateCount; i++ ) { + handleObj = handlers[ i ]; + sel = handleObj.selector; + + if ( selMatch[ sel ] === undefined ) { + selMatch[ sel ] = ( + handleObj.quick ? quickIs( cur, handleObj.quick ) : jqcur.is( sel ) + ); + } + if ( selMatch[ sel ] ) { + matches.push( handleObj ); + } + } + if ( matches.length ) { + handlerQueue.push({ elem: cur, matches: matches }); + } + } + } + } + + // Add the remaining (directly-bound) handlers + if ( handlers.length > delegateCount ) { + handlerQueue.push({ elem: this, matches: handlers.slice( delegateCount ) }); + } + + // Run delegates first; they may want to stop propagation beneath us + for ( i = 0; i < handlerQueue.length && !event.isPropagationStopped(); i++ ) { + matched = handlerQueue[ i ]; + event.currentTarget = matched.elem; + + for ( j = 0; j < matched.matches.length && !event.isImmediatePropagationStopped(); j++ ) { + handleObj = matched.matches[ j ]; + + // Triggered event must either 1) be non-exclusive and have no namespace, or + // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace). + if ( run_all || (!event.namespace && !handleObj.namespace) || event.namespace_re && event.namespace_re.test( handleObj.namespace ) ) { + + event.data = handleObj.data; + event.handleObj = handleObj; + + ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler ) + .apply( matched.elem, args ); + + if ( ret !== undefined ) { + event.result = ret; + if ( ret === false ) { + event.preventDefault(); + event.stopPropagation(); + } + } + } + } + } + + // Call the postDispatch hook for the mapped type + if ( special.postDispatch ) { + special.postDispatch.call( this, event ); + } + + return event.result; + }, + + // Includes some event props shared by KeyEvent and MouseEvent + // *** attrChange attrName relatedNode srcElement are not normalized, non-W3C, deprecated, will be removed in 1.8 *** + props: "attrChange attrName relatedNode srcElement altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "), + + fixHooks: {}, + + keyHooks: { + props: "char charCode key keyCode".split(" "), + filter: function( event, original ) { + + // Add which for key events + if ( event.which == null ) { + event.which = original.charCode != null ? original.charCode : original.keyCode; + } + + return event; + } + }, + + mouseHooks: { + props: "button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "), + filter: function( event, original ) { + var eventDoc, doc, body, + button = original.button, + fromElement = original.fromElement; + + // Calculate pageX/Y if missing and clientX/Y available + if ( event.pageX == null && original.clientX != null ) { + eventDoc = event.target.ownerDocument || document; + doc = eventDoc.documentElement; + body = eventDoc.body; + + event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 ); + event.pageY = original.clientY + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - ( doc && doc.clientTop || body && body.clientTop || 0 ); + } + + // Add relatedTarget, if necessary + if ( !event.relatedTarget && fromElement ) { + event.relatedTarget = fromElement === event.target ? original.toElement : fromElement; + } + + // Add which for click: 1 === left; 2 === middle; 3 === right + // Note: button is not normalized, so don't use it + if ( !event.which && button !== undefined ) { + event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) ); + } + + return event; + } + }, + + fix: function( event ) { + if ( event[ jQuery.expando ] ) { + return event; + } + + // Create a writable copy of the event object and normalize some properties + var i, prop, + originalEvent = event, + fixHook = jQuery.event.fixHooks[ event.type ] || {}, + copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props; + + event = jQuery.Event( originalEvent ); + + for ( i = copy.length; i; ) { + prop = copy[ --i ]; + event[ prop ] = originalEvent[ prop ]; + } + + // Fix target property, if necessary (#1925, IE 6/7/8 & Safari2) + if ( !event.target ) { + event.target = originalEvent.srcElement || document; + } + + // Target should not be a text node (#504, Safari) + if ( event.target.nodeType === 3 ) { + event.target = event.target.parentNode; + } + + // For mouse/key events; add metaKey if it's not there (#3368, IE6/7/8) + if ( event.metaKey === undefined ) { + event.metaKey = event.ctrlKey; + } + + return fixHook.filter? fixHook.filter( event, originalEvent ) : event; + }, + + special: { + ready: { + // Make sure the ready event is setup + setup: jQuery.bindReady + }, + + load: { + // Prevent triggered image.load events from bubbling to window.load + noBubble: true + }, + + focus: { + delegateType: "focusin" + }, + blur: { + delegateType: "focusout" + }, + + beforeunload: { + setup: function( data, namespaces, eventHandle ) { + // We only want to do this special case on windows + if ( jQuery.isWindow( this ) ) { + this.onbeforeunload = eventHandle; + } + }, + + teardown: function( namespaces, eventHandle ) { + if ( this.onbeforeunload === eventHandle ) { + this.onbeforeunload = null; + } + } + } + }, + + simulate: function( type, elem, event, bubble ) { + // Piggyback on a donor event to simulate a different one. + // Fake originalEvent to avoid donor's stopPropagation, but if the + // simulated event prevents default then we do the same on the donor. + var e = jQuery.extend( + new jQuery.Event(), + event, + { type: type, + isSimulated: true, + originalEvent: {} + } + ); + if ( bubble ) { + jQuery.event.trigger( e, null, elem ); + } else { + jQuery.event.dispatch.call( elem, e ); + } + if ( e.isDefaultPrevented() ) { + event.preventDefault(); + } + } +}; + +// Some plugins are using, but it's undocumented/deprecated and will be removed. +// The 1.7 special event interface should provide all the hooks needed now. +jQuery.event.handle = jQuery.event.dispatch; + +jQuery.removeEvent = document.removeEventListener ? + function( elem, type, handle ) { + if ( elem.removeEventListener ) { + elem.removeEventListener( type, handle, false ); + } + } : + function( elem, type, handle ) { + if ( elem.detachEvent ) { + elem.detachEvent( "on" + type, handle ); + } + }; + +jQuery.Event = function( src, props ) { + // Allow instantiation without the 'new' keyword + if ( !(this instanceof jQuery.Event) ) { + return new jQuery.Event( src, props ); + } + + // Event object + if ( src && src.type ) { + this.originalEvent = src; + this.type = src.type; + + // Events bubbling up the document may have been marked as prevented + // by a handler lower down the tree; reflect the correct value. + this.isDefaultPrevented = ( src.defaultPrevented || src.returnValue === false || + src.getPreventDefault && src.getPreventDefault() ) ? returnTrue : returnFalse; + + // Event type + } else { + this.type = src; + } + + // Put explicitly provided properties onto the event object + if ( props ) { + jQuery.extend( this, props ); + } + + // Create a timestamp if incoming event doesn't have one + this.timeStamp = src && src.timeStamp || jQuery.now(); + + // Mark it as fixed + this[ jQuery.expando ] = true; +}; + +function returnFalse() { + return false; +} +function returnTrue() { + return true; +} + +// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding +// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html +jQuery.Event.prototype = { + preventDefault: function() { + this.isDefaultPrevented = returnTrue; + + var e = this.originalEvent; + if ( !e ) { + return; + } + + // if preventDefault exists run it on the original event + if ( e.preventDefault ) { + e.preventDefault(); + + // otherwise set the returnValue property of the original event to false (IE) + } else { + e.returnValue = false; + } + }, + stopPropagation: function() { + this.isPropagationStopped = returnTrue; + + var e = this.originalEvent; + if ( !e ) { + return; + } + // if stopPropagation exists run it on the original event + if ( e.stopPropagation ) { + e.stopPropagation(); + } + // otherwise set the cancelBubble property of the original event to true (IE) + e.cancelBubble = true; + }, + stopImmediatePropagation: function() { + this.isImmediatePropagationStopped = returnTrue; + this.stopPropagation(); + }, + isDefaultPrevented: returnFalse, + isPropagationStopped: returnFalse, + isImmediatePropagationStopped: returnFalse +}; + +// Create mouseenter/leave events using mouseover/out and event-time checks +jQuery.each({ + mouseenter: "mouseover", + mouseleave: "mouseout" +}, function( orig, fix ) { + jQuery.event.special[ orig ] = { + delegateType: fix, + bindType: fix, + + handle: function( event ) { + var target = this, + related = event.relatedTarget, + handleObj = event.handleObj, + selector = handleObj.selector, + ret; + + // For mousenter/leave call the handler if related is outside the target. + // NB: No relatedTarget if the mouse left/entered the browser window + if ( !related || (related !== target && !jQuery.contains( target, related )) ) { + event.type = handleObj.origType; + ret = handleObj.handler.apply( this, arguments ); + event.type = fix; + } + return ret; + } + }; +}); + +// IE submit delegation +if ( !jQuery.support.submitBubbles ) { + + jQuery.event.special.submit = { + setup: function() { + // Only need this for delegated form submit events + if ( jQuery.nodeName( this, "form" ) ) { + return false; + } + + // Lazy-add a submit handler when a descendant form may potentially be submitted + jQuery.event.add( this, "click._submit keypress._submit", function( e ) { + // Node name check avoids a VML-related crash in IE (#9807) + var elem = e.target, + form = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ? elem.form : undefined; + if ( form && !form._submit_attached ) { + jQuery.event.add( form, "submit._submit", function( event ) { + event._submit_bubble = true; + }); + form._submit_attached = true; + } + }); + // return undefined since we don't need an event listener + }, + + postDispatch: function( event ) { + // If form was submitted by the user, bubble the event up the tree + if ( event._submit_bubble ) { + delete event._submit_bubble; + if ( this.parentNode && !event.isTrigger ) { + jQuery.event.simulate( "submit", this.parentNode, event, true ); + } + } + }, + + teardown: function() { + // Only need this for delegated form submit events + if ( jQuery.nodeName( this, "form" ) ) { + return false; + } + + // Remove delegated handlers; cleanData eventually reaps submit handlers attached above + jQuery.event.remove( this, "._submit" ); + } + }; +} + +// IE change delegation and checkbox/radio fix +if ( !jQuery.support.changeBubbles ) { + + jQuery.event.special.change = { + + setup: function() { + + if ( rformElems.test( this.nodeName ) ) { + // IE doesn't fire change on a check/radio until blur; trigger it on click + // after a propertychange. Eat the blur-change in special.change.handle. + // This still fires onchange a second time for check/radio after blur. + if ( this.type === "checkbox" || this.type === "radio" ) { + jQuery.event.add( this, "propertychange._change", function( event ) { + if ( event.originalEvent.propertyName === "checked" ) { + this._just_changed = true; + } + }); + jQuery.event.add( this, "click._change", function( event ) { + if ( this._just_changed && !event.isTrigger ) { + this._just_changed = false; + jQuery.event.simulate( "change", this, event, true ); + } + }); + } + return false; + } + // Delegated event; lazy-add a change handler on descendant inputs + jQuery.event.add( this, "beforeactivate._change", function( e ) { + var elem = e.target; + + if ( rformElems.test( elem.nodeName ) && !elem._change_attached ) { + jQuery.event.add( elem, "change._change", function( event ) { + if ( this.parentNode && !event.isSimulated && !event.isTrigger ) { + jQuery.event.simulate( "change", this.parentNode, event, true ); + } + }); + elem._change_attached = true; + } + }); + }, + + handle: function( event ) { + var elem = event.target; + + // Swallow native change events from checkbox/radio, we already triggered them above + if ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== "radio" && elem.type !== "checkbox") ) { + return event.handleObj.handler.apply( this, arguments ); + } + }, + + teardown: function() { + jQuery.event.remove( this, "._change" ); + + return rformElems.test( this.nodeName ); + } + }; +} + +// Create "bubbling" focus and blur events +if ( !jQuery.support.focusinBubbles ) { + jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) { + + // Attach a single capturing handler while someone wants focusin/focusout + var attaches = 0, + handler = function( event ) { + jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true ); + }; + + jQuery.event.special[ fix ] = { + setup: function() { + if ( attaches++ === 0 ) { + document.addEventListener( orig, handler, true ); + } + }, + teardown: function() { + if ( --attaches === 0 ) { + document.removeEventListener( orig, handler, true ); + } + } + }; + }); +} + +jQuery.fn.extend({ + + on: function( types, selector, data, fn, /*INTERNAL*/ one ) { + var origFn, type; + + // Types can be a map of types/handlers + if ( typeof types === "object" ) { + // ( types-Object, selector, data ) + if ( typeof selector !== "string" ) { // && selector != null + // ( types-Object, data ) + data = data || selector; + selector = undefined; + } + for ( type in types ) { + this.on( type, selector, data, types[ type ], one ); + } + return this; + } + + if ( data == null && fn == null ) { + // ( types, fn ) + fn = selector; + data = selector = undefined; + } else if ( fn == null ) { + if ( typeof selector === "string" ) { + // ( types, selector, fn ) + fn = data; + data = undefined; + } else { + // ( types, data, fn ) + fn = data; + data = selector; + selector = undefined; + } + } + if ( fn === false ) { + fn = returnFalse; + } else if ( !fn ) { + return this; + } + + if ( one === 1 ) { + origFn = fn; + fn = function( event ) { + // Can use an empty set, since event contains the info + jQuery().off( event ); + return origFn.apply( this, arguments ); + }; + // Use same guid so caller can remove using origFn + fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); + } + return this.each( function() { + jQuery.event.add( this, types, fn, data, selector ); + }); + }, + one: function( types, selector, data, fn ) { + return this.on( types, selector, data, fn, 1 ); + }, + off: function( types, selector, fn ) { + if ( types && types.preventDefault && types.handleObj ) { + // ( event ) dispatched jQuery.Event + var handleObj = types.handleObj; + jQuery( types.delegateTarget ).off( + handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType, + handleObj.selector, + handleObj.handler + ); + return this; + } + if ( typeof types === "object" ) { + // ( types-object [, selector] ) + for ( var type in types ) { + this.off( type, selector, types[ type ] ); + } + return this; + } + if ( selector === false || typeof selector === "function" ) { + // ( types [, fn] ) + fn = selector; + selector = undefined; + } + if ( fn === false ) { + fn = returnFalse; + } + return this.each(function() { + jQuery.event.remove( this, types, fn, selector ); + }); + }, + + bind: function( types, data, fn ) { + return this.on( types, null, data, fn ); + }, + unbind: function( types, fn ) { + return this.off( types, null, fn ); + }, + + live: function( types, data, fn ) { + jQuery( this.context ).on( types, this.selector, data, fn ); + return this; + }, + die: function( types, fn ) { + jQuery( this.context ).off( types, this.selector || "**", fn ); + return this; + }, + + delegate: function( selector, types, data, fn ) { + return this.on( types, selector, data, fn ); + }, + undelegate: function( selector, types, fn ) { + // ( namespace ) or ( selector, types [, fn] ) + return arguments.length == 1? this.off( selector, "**" ) : this.off( types, selector, fn ); + }, + + trigger: function( type, data ) { + return this.each(function() { + jQuery.event.trigger( type, data, this ); + }); + }, + triggerHandler: function( type, data ) { + if ( this[0] ) { + return jQuery.event.trigger( type, data, this[0], true ); + } + }, + + toggle: function( fn ) { + // Save reference to arguments for access in closure + var args = arguments, + guid = fn.guid || jQuery.guid++, + i = 0, + toggler = function( event ) { + // Figure out which function to execute + var lastToggle = ( jQuery._data( this, "lastToggle" + fn.guid ) || 0 ) % i; + jQuery._data( this, "lastToggle" + fn.guid, lastToggle + 1 ); + + // Make sure that clicks stop + event.preventDefault(); + + // and execute the function + return args[ lastToggle ].apply( this, arguments ) || false; + }; + + // link all the functions, so any of them can unbind this click handler + toggler.guid = guid; + while ( i < args.length ) { + args[ i++ ].guid = guid; + } + + return this.click( toggler ); + }, + + hover: function( fnOver, fnOut ) { + return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver ); + } +}); + +jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " + + "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " + + "change select submit keydown keypress keyup error contextmenu").split(" "), function( i, name ) { + + // Handle event binding + jQuery.fn[ name ] = function( data, fn ) { + if ( fn == null ) { + fn = data; + data = null; + } + + return arguments.length > 0 ? + this.on( name, null, data, fn ) : + this.trigger( name ); + }; + + if ( jQuery.attrFn ) { + jQuery.attrFn[ name ] = true; + } + + if ( rkeyEvent.test( name ) ) { + jQuery.event.fixHooks[ name ] = jQuery.event.keyHooks; + } + + if ( rmouseEvent.test( name ) ) { + jQuery.event.fixHooks[ name ] = jQuery.event.mouseHooks; + } +}); + + + +/*! + * Sizzle CSS Selector Engine + * Copyright 2011, The Dojo Foundation + * Released under the MIT, BSD, and GPL Licenses. + * More information: http://sizzlejs.com/ + */ +(function(){ + +var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g, + expando = "sizcache" + (Math.random() + '').replace('.', ''), + done = 0, + toString = Object.prototype.toString, + hasDuplicate = false, + baseHasDuplicate = true, + rBackslash = /\\/g, + rReturn = /\r\n/g, + rNonWord = /\W/; + +// Here we check if the JavaScript engine is using some sort of +// optimization where it does not always call our comparision +// function. If that is the case, discard the hasDuplicate value. +// Thus far that includes Google Chrome. +[0, 0].sort(function() { + baseHasDuplicate = false; + return 0; +}); + +var Sizzle = function( selector, context, results, seed ) { + results = results || []; + context = context || document; + + var origContext = context; + + if ( context.nodeType !== 1 && context.nodeType !== 9 ) { + return []; + } + + if ( !selector || typeof selector !== "string" ) { + return results; + } + + var m, set, checkSet, extra, ret, cur, pop, i, + prune = true, + contextXML = Sizzle.isXML( context ), + parts = [], + soFar = selector; + + // Reset the position of the chunker regexp (start from head) + do { + chunker.exec( "" ); + m = chunker.exec( soFar ); + + if ( m ) { + soFar = m[3]; + + parts.push( m[1] ); + + if ( m[2] ) { + extra = m[3]; + break; + } + } + } while ( m ); + + if ( parts.length > 1 && origPOS.exec( selector ) ) { + + if ( parts.length === 2 && Expr.relative[ parts[0] ] ) { + set = posProcess( parts[0] + parts[1], context, seed ); + + } else { + set = Expr.relative[ parts[0] ] ? + [ context ] : + Sizzle( parts.shift(), context ); + + while ( parts.length ) { + selector = parts.shift(); + + if ( Expr.relative[ selector ] ) { + selector += parts.shift(); + } + + set = posProcess( selector, set, seed ); + } + } + + } else { + // Take a shortcut and set the context if the root selector is an ID + // (but not if it'll be faster if the inner selector is an ID) + if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML && + Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) { + + ret = Sizzle.find( parts.shift(), context, contextXML ); + context = ret.expr ? + Sizzle.filter( ret.expr, ret.set )[0] : + ret.set[0]; + } + + if ( context ) { + ret = seed ? + { expr: parts.pop(), set: makeArray(seed) } : + Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML ); + + set = ret.expr ? + Sizzle.filter( ret.expr, ret.set ) : + ret.set; + + if ( parts.length > 0 ) { + checkSet = makeArray( set ); + + } else { + prune = false; + } + + while ( parts.length ) { + cur = parts.pop(); + pop = cur; + + if ( !Expr.relative[ cur ] ) { + cur = ""; + } else { + pop = parts.pop(); + } + + if ( pop == null ) { + pop = context; + } + + Expr.relative[ cur ]( checkSet, pop, contextXML ); + } + + } else { + checkSet = parts = []; + } + } + + if ( !checkSet ) { + checkSet = set; + } + + if ( !checkSet ) { + Sizzle.error( cur || selector ); + } + + if ( toString.call(checkSet) === "[object Array]" ) { + if ( !prune ) { + results.push.apply( results, checkSet ); + + } else if ( context && context.nodeType === 1 ) { + for ( i = 0; checkSet[i] != null; i++ ) { + if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && Sizzle.contains(context, checkSet[i])) ) { + results.push( set[i] ); + } + } + + } else { + for ( i = 0; checkSet[i] != null; i++ ) { + if ( checkSet[i] && checkSet[i].nodeType === 1 ) { + results.push( set[i] ); + } + } + } + + } else { + makeArray( checkSet, results ); + } + + if ( extra ) { + Sizzle( extra, origContext, results, seed ); + Sizzle.uniqueSort( results ); + } + + return results; +}; + +Sizzle.uniqueSort = function( results ) { + if ( sortOrder ) { + hasDuplicate = baseHasDuplicate; + results.sort( sortOrder ); + + if ( hasDuplicate ) { + for ( var i = 1; i < results.length; i++ ) { + if ( results[i] === results[ i - 1 ] ) { + results.splice( i--, 1 ); + } + } + } + } + + return results; +}; + +Sizzle.matches = function( expr, set ) { + return Sizzle( expr, null, null, set ); +}; + +Sizzle.matchesSelector = function( node, expr ) { + return Sizzle( expr, null, null, [node] ).length > 0; +}; + +Sizzle.find = function( expr, context, isXML ) { + var set, i, len, match, type, left; + + if ( !expr ) { + return []; + } + + for ( i = 0, len = Expr.order.length; i < len; i++ ) { + type = Expr.order[i]; + + if ( (match = Expr.leftMatch[ type ].exec( expr )) ) { + left = match[1]; + match.splice( 1, 1 ); + + if ( left.substr( left.length - 1 ) !== "\\" ) { + match[1] = (match[1] || "").replace( rBackslash, "" ); + set = Expr.find[ type ]( match, context, isXML ); + + if ( set != null ) { + expr = expr.replace( Expr.match[ type ], "" ); + break; + } + } + } + } + + if ( !set ) { + set = typeof context.getElementsByTagName !== "undefined" ? + context.getElementsByTagName( "*" ) : + []; + } + + return { set: set, expr: expr }; +}; + +Sizzle.filter = function( expr, set, inplace, not ) { + var match, anyFound, + type, found, item, filter, left, + i, pass, + old = expr, + result = [], + curLoop = set, + isXMLFilter = set && set[0] && Sizzle.isXML( set[0] ); + + while ( expr && set.length ) { + for ( type in Expr.filter ) { + if ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) { + filter = Expr.filter[ type ]; + left = match[1]; + + anyFound = false; + + match.splice(1,1); + + if ( left.substr( left.length - 1 ) === "\\" ) { + continue; + } + + if ( curLoop === result ) { + result = []; + } + + if ( Expr.preFilter[ type ] ) { + match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter ); + + if ( !match ) { + anyFound = found = true; + + } else if ( match === true ) { + continue; + } + } + + if ( match ) { + for ( i = 0; (item = curLoop[i]) != null; i++ ) { + if ( item ) { + found = filter( item, match, i, curLoop ); + pass = not ^ found; + + if ( inplace && found != null ) { + if ( pass ) { + anyFound = true; + + } else { + curLoop[i] = false; + } + + } else if ( pass ) { + result.push( item ); + anyFound = true; + } + } + } + } + + if ( found !== undefined ) { + if ( !inplace ) { + curLoop = result; + } + + expr = expr.replace( Expr.match[ type ], "" ); + + if ( !anyFound ) { + return []; + } + + break; + } + } + } + + // Improper expression + if ( expr === old ) { + if ( anyFound == null ) { + Sizzle.error( expr ); + + } else { + break; + } + } + + old = expr; + } + + return curLoop; +}; + +Sizzle.error = function( msg ) { + throw new Error( "Syntax error, unrecognized expression: " + msg ); +}; + +/** + * Utility function for retreiving the text value of an array of DOM nodes + * @param {Array|Element} elem + */ +var getText = Sizzle.getText = function( elem ) { + var i, node, + nodeType = elem.nodeType, + ret = ""; + + if ( nodeType ) { + if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { + // Use textContent || innerText for elements + if ( typeof elem.textContent === 'string' ) { + return elem.textContent; + } else if ( typeof elem.innerText === 'string' ) { + // Replace IE's carriage returns + return elem.innerText.replace( rReturn, '' ); + } else { + // Traverse it's children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling) { + ret += getText( elem ); + } + } + } else if ( nodeType === 3 || nodeType === 4 ) { + return elem.nodeValue; + } + } else { + + // If no nodeType, this is expected to be an array + for ( i = 0; (node = elem[i]); i++ ) { + // Do not traverse comment nodes + if ( node.nodeType !== 8 ) { + ret += getText( node ); + } + } + } + return ret; +}; + +var Expr = Sizzle.selectors = { + order: [ "ID", "NAME", "TAG" ], + + match: { + ID: /#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/, + CLASS: /\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/, + NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/, + ATTR: /\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/, + TAG: /^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/, + CHILD: /:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/, + POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/, + PSEUDO: /:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/ + }, + + leftMatch: {}, + + attrMap: { + "class": "className", + "for": "htmlFor" + }, + + attrHandle: { + href: function( elem ) { + return elem.getAttribute( "href" ); + }, + type: function( elem ) { + return elem.getAttribute( "type" ); + } + }, + + relative: { + "+": function(checkSet, part){ + var isPartStr = typeof part === "string", + isTag = isPartStr && !rNonWord.test( part ), + isPartStrNotTag = isPartStr && !isTag; + + if ( isTag ) { + part = part.toLowerCase(); + } + + for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) { + if ( (elem = checkSet[i]) ) { + while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {} + + checkSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ? + elem || false : + elem === part; + } + } + + if ( isPartStrNotTag ) { + Sizzle.filter( part, checkSet, true ); + } + }, + + ">": function( checkSet, part ) { + var elem, + isPartStr = typeof part === "string", + i = 0, + l = checkSet.length; + + if ( isPartStr && !rNonWord.test( part ) ) { + part = part.toLowerCase(); + + for ( ; i < l; i++ ) { + elem = checkSet[i]; + + if ( elem ) { + var parent = elem.parentNode; + checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false; + } + } + + } else { + for ( ; i < l; i++ ) { + elem = checkSet[i]; + + if ( elem ) { + checkSet[i] = isPartStr ? + elem.parentNode : + elem.parentNode === part; + } + } + + if ( isPartStr ) { + Sizzle.filter( part, checkSet, true ); + } + } + }, + + "": function(checkSet, part, isXML){ + var nodeCheck, + doneName = done++, + checkFn = dirCheck; + + if ( typeof part === "string" && !rNonWord.test( part ) ) { + part = part.toLowerCase(); + nodeCheck = part; + checkFn = dirNodeCheck; + } + + checkFn( "parentNode", part, doneName, checkSet, nodeCheck, isXML ); + }, + + "~": function( checkSet, part, isXML ) { + var nodeCheck, + doneName = done++, + checkFn = dirCheck; + + if ( typeof part === "string" && !rNonWord.test( part ) ) { + part = part.toLowerCase(); + nodeCheck = part; + checkFn = dirNodeCheck; + } + + checkFn( "previousSibling", part, doneName, checkSet, nodeCheck, isXML ); + } + }, + + find: { + ID: function( match, context, isXML ) { + if ( typeof context.getElementById !== "undefined" && !isXML ) { + var m = context.getElementById(match[1]); + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + return m && m.parentNode ? [m] : []; + } + }, + + NAME: function( match, context ) { + if ( typeof context.getElementsByName !== "undefined" ) { + var ret = [], + results = context.getElementsByName( match[1] ); + + for ( var i = 0, l = results.length; i < l; i++ ) { + if ( results[i].getAttribute("name") === match[1] ) { + ret.push( results[i] ); + } + } + + return ret.length === 0 ? null : ret; + } + }, + + TAG: function( match, context ) { + if ( typeof context.getElementsByTagName !== "undefined" ) { + return context.getElementsByTagName( match[1] ); + } + } + }, + preFilter: { + CLASS: function( match, curLoop, inplace, result, not, isXML ) { + match = " " + match[1].replace( rBackslash, "" ) + " "; + + if ( isXML ) { + return match; + } + + for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) { + if ( elem ) { + if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n\r]/g, " ").indexOf(match) >= 0) ) { + if ( !inplace ) { + result.push( elem ); + } + + } else if ( inplace ) { + curLoop[i] = false; + } + } + } + + return false; + }, + + ID: function( match ) { + return match[1].replace( rBackslash, "" ); + }, + + TAG: function( match, curLoop ) { + return match[1].replace( rBackslash, "" ).toLowerCase(); + }, + + CHILD: function( match ) { + if ( match[1] === "nth" ) { + if ( !match[2] ) { + Sizzle.error( match[0] ); + } + + match[2] = match[2].replace(/^\+|\s*/g, ''); + + // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6' + var test = /(-?)(\d*)(?:n([+\-]?\d*))?/.exec( + match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" || + !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]); + + // calculate the numbers (first)n+(last) including if they are negative + match[2] = (test[1] + (test[2] || 1)) - 0; + match[3] = test[3] - 0; + } + else if ( match[2] ) { + Sizzle.error( match[0] ); + } + + // TODO: Move to normal caching system + match[0] = done++; + + return match; + }, + + ATTR: function( match, curLoop, inplace, result, not, isXML ) { + var name = match[1] = match[1].replace( rBackslash, "" ); + + if ( !isXML && Expr.attrMap[name] ) { + match[1] = Expr.attrMap[name]; + } + + // Handle if an un-quoted value was used + match[4] = ( match[4] || match[5] || "" ).replace( rBackslash, "" ); + + if ( match[2] === "~=" ) { + match[4] = " " + match[4] + " "; + } + + return match; + }, + + PSEUDO: function( match, curLoop, inplace, result, not ) { + if ( match[1] === "not" ) { + // If we're dealing with a complex expression, or a simple one + if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) { + match[3] = Sizzle(match[3], null, null, curLoop); + + } else { + var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not); + + if ( !inplace ) { + result.push.apply( result, ret ); + } + + return false; + } + + } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) { + return true; + } + + return match; + }, + + POS: function( match ) { + match.unshift( true ); + + return match; + } + }, + + filters: { + enabled: function( elem ) { + return elem.disabled === false && elem.type !== "hidden"; + }, + + disabled: function( elem ) { + return elem.disabled === true; + }, + + checked: function( elem ) { + return elem.checked === true; + }, + + selected: function( elem ) { + // Accessing this property makes selected-by-default + // options in Safari work properly + if ( elem.parentNode ) { + elem.parentNode.selectedIndex; + } + + return elem.selected === true; + }, + + parent: function( elem ) { + return !!elem.firstChild; + }, + + empty: function( elem ) { + return !elem.firstChild; + }, + + has: function( elem, i, match ) { + return !!Sizzle( match[3], elem ).length; + }, + + header: function( elem ) { + return (/h\d/i).test( elem.nodeName ); + }, + + text: function( elem ) { + var attr = elem.getAttribute( "type" ), type = elem.type; + // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc) + // use getAttribute instead to test this case + return elem.nodeName.toLowerCase() === "input" && "text" === type && ( attr === type || attr === null ); + }, + + radio: function( elem ) { + return elem.nodeName.toLowerCase() === "input" && "radio" === elem.type; + }, + + checkbox: function( elem ) { + return elem.nodeName.toLowerCase() === "input" && "checkbox" === elem.type; + }, + + file: function( elem ) { + return elem.nodeName.toLowerCase() === "input" && "file" === elem.type; + }, + + password: function( elem ) { + return elem.nodeName.toLowerCase() === "input" && "password" === elem.type; + }, + + submit: function( elem ) { + var name = elem.nodeName.toLowerCase(); + return (name === "input" || name === "button") && "submit" === elem.type; + }, + + image: function( elem ) { + return elem.nodeName.toLowerCase() === "input" && "image" === elem.type; + }, + + reset: function( elem ) { + var name = elem.nodeName.toLowerCase(); + return (name === "input" || name === "button") && "reset" === elem.type; + }, + + button: function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && "button" === elem.type || name === "button"; + }, + + input: function( elem ) { + return (/input|select|textarea|button/i).test( elem.nodeName ); + }, + + focus: function( elem ) { + return elem === elem.ownerDocument.activeElement; + } + }, + setFilters: { + first: function( elem, i ) { + return i === 0; + }, + + last: function( elem, i, match, array ) { + return i === array.length - 1; + }, + + even: function( elem, i ) { + return i % 2 === 0; + }, + + odd: function( elem, i ) { + return i % 2 === 1; + }, + + lt: function( elem, i, match ) { + return i < match[3] - 0; + }, + + gt: function( elem, i, match ) { + return i > match[3] - 0; + }, + + nth: function( elem, i, match ) { + return match[3] - 0 === i; + }, + + eq: function( elem, i, match ) { + return match[3] - 0 === i; + } + }, + filter: { + PSEUDO: function( elem, match, i, array ) { + var name = match[1], + filter = Expr.filters[ name ]; + + if ( filter ) { + return filter( elem, i, match, array ); + + } else if ( name === "contains" ) { + return (elem.textContent || elem.innerText || getText([ elem ]) || "").indexOf(match[3]) >= 0; + + } else if ( name === "not" ) { + var not = match[3]; + + for ( var j = 0, l = not.length; j < l; j++ ) { + if ( not[j] === elem ) { + return false; + } + } + + return true; + + } else { + Sizzle.error( name ); + } + }, + + CHILD: function( elem, match ) { + var first, last, + doneName, parent, cache, + count, diff, + type = match[1], + node = elem; + + switch ( type ) { + case "only": + case "first": + while ( (node = node.previousSibling) ) { + if ( node.nodeType === 1 ) { + return false; + } + } + + if ( type === "first" ) { + return true; + } + + node = elem; + + /* falls through */ + case "last": + while ( (node = node.nextSibling) ) { + if ( node.nodeType === 1 ) { + return false; + } + } + + return true; + + case "nth": + first = match[2]; + last = match[3]; + + if ( first === 1 && last === 0 ) { + return true; + } + + doneName = match[0]; + parent = elem.parentNode; + + if ( parent && (parent[ expando ] !== doneName || !elem.nodeIndex) ) { + count = 0; + + for ( node = parent.firstChild; node; node = node.nextSibling ) { + if ( node.nodeType === 1 ) { + node.nodeIndex = ++count; + } + } + + parent[ expando ] = doneName; + } + + diff = elem.nodeIndex - last; + + if ( first === 0 ) { + return diff === 0; + + } else { + return ( diff % first === 0 && diff / first >= 0 ); + } + } + }, + + ID: function( elem, match ) { + return elem.nodeType === 1 && elem.getAttribute("id") === match; + }, + + TAG: function( elem, match ) { + return (match === "*" && elem.nodeType === 1) || !!elem.nodeName && elem.nodeName.toLowerCase() === match; + }, + + CLASS: function( elem, match ) { + return (" " + (elem.className || elem.getAttribute("class")) + " ") + .indexOf( match ) > -1; + }, + + ATTR: function( elem, match ) { + var name = match[1], + result = Sizzle.attr ? + Sizzle.attr( elem, name ) : + Expr.attrHandle[ name ] ? + Expr.attrHandle[ name ]( elem ) : + elem[ name ] != null ? + elem[ name ] : + elem.getAttribute( name ), + value = result + "", + type = match[2], + check = match[4]; + + return result == null ? + type === "!=" : + !type && Sizzle.attr ? + result != null : + type === "=" ? + value === check : + type === "*=" ? + value.indexOf(check) >= 0 : + type === "~=" ? + (" " + value + " ").indexOf(check) >= 0 : + !check ? + value && result !== false : + type === "!=" ? + value !== check : + type === "^=" ? + value.indexOf(check) === 0 : + type === "$=" ? + value.substr(value.length - check.length) === check : + type === "|=" ? + value === check || value.substr(0, check.length + 1) === check + "-" : + false; + }, + + POS: function( elem, match, i, array ) { + var name = match[2], + filter = Expr.setFilters[ name ]; + + if ( filter ) { + return filter( elem, i, match, array ); + } + } + } +}; + +var origPOS = Expr.match.POS, + fescape = function(all, num){ + return "\\" + (num - 0 + 1); + }; + +for ( var type in Expr.match ) { + Expr.match[ type ] = new RegExp( Expr.match[ type ].source + (/(?![^\[]*\])(?![^\(]*\))/.source) ); + Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source.replace(/\\(\d+)/g, fescape) ); +} +// Expose origPOS +// "global" as in regardless of relation to brackets/parens +Expr.match.globalPOS = origPOS; + +var makeArray = function( array, results ) { + array = Array.prototype.slice.call( array, 0 ); + + if ( results ) { + results.push.apply( results, array ); + return results; + } + + return array; +}; + +// Perform a simple check to determine if the browser is capable of +// converting a NodeList to an array using builtin methods. +// Also verifies that the returned array holds DOM nodes +// (which is not the case in the Blackberry browser) +try { + Array.prototype.slice.call( document.documentElement.childNodes, 0 )[0].nodeType; + +// Provide a fallback method if it does not work +} catch( e ) { + makeArray = function( array, results ) { + var i = 0, + ret = results || []; + + if ( toString.call(array) === "[object Array]" ) { + Array.prototype.push.apply( ret, array ); + + } else { + if ( typeof array.length === "number" ) { + for ( var l = array.length; i < l; i++ ) { + ret.push( array[i] ); + } + + } else { + for ( ; array[i]; i++ ) { + ret.push( array[i] ); + } + } + } + + return ret; + }; +} + +var sortOrder, siblingCheck; + +if ( document.documentElement.compareDocumentPosition ) { + sortOrder = function( a, b ) { + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) { + return a.compareDocumentPosition ? -1 : 1; + } + + return a.compareDocumentPosition(b) & 4 ? -1 : 1; + }; + +} else { + sortOrder = function( a, b ) { + // The nodes are identical, we can exit early + if ( a === b ) { + hasDuplicate = true; + return 0; + + // Fallback to using sourceIndex (in IE) if it's available on both nodes + } else if ( a.sourceIndex && b.sourceIndex ) { + return a.sourceIndex - b.sourceIndex; + } + + var al, bl, + ap = [], + bp = [], + aup = a.parentNode, + bup = b.parentNode, + cur = aup; + + // If the nodes are siblings (or identical) we can do a quick check + if ( aup === bup ) { + return siblingCheck( a, b ); + + // If no parents were found then the nodes are disconnected + } else if ( !aup ) { + return -1; + + } else if ( !bup ) { + return 1; + } + + // Otherwise they're somewhere else in the tree so we need + // to build up a full list of the parentNodes for comparison + while ( cur ) { + ap.unshift( cur ); + cur = cur.parentNode; + } + + cur = bup; + + while ( cur ) { + bp.unshift( cur ); + cur = cur.parentNode; + } + + al = ap.length; + bl = bp.length; + + // Start walking down the tree looking for a discrepancy + for ( var i = 0; i < al && i < bl; i++ ) { + if ( ap[i] !== bp[i] ) { + return siblingCheck( ap[i], bp[i] ); + } + } + + // We ended someplace up the tree so do a sibling check + return i === al ? + siblingCheck( a, bp[i], -1 ) : + siblingCheck( ap[i], b, 1 ); + }; + + siblingCheck = function( a, b, ret ) { + if ( a === b ) { + return ret; + } + + var cur = a.nextSibling; + + while ( cur ) { + if ( cur === b ) { + return -1; + } + + cur = cur.nextSibling; + } + + return 1; + }; +} + +// Check to see if the browser returns elements by name when +// querying by getElementById (and provide a workaround) +(function(){ + // We're going to inject a fake input element with a specified name + var form = document.createElement("div"), + id = "script" + (new Date()).getTime(), + root = document.documentElement; + + form.innerHTML = ""; + + // Inject it into the root element, check its status, and remove it quickly + root.insertBefore( form, root.firstChild ); + + // The workaround has to do additional checks after a getElementById + // Which slows things down for other browsers (hence the branching) + if ( document.getElementById( id ) ) { + Expr.find.ID = function( match, context, isXML ) { + if ( typeof context.getElementById !== "undefined" && !isXML ) { + var m = context.getElementById(match[1]); + + return m ? + m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ? + [m] : + undefined : + []; + } + }; + + Expr.filter.ID = function( elem, match ) { + var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id"); + + return elem.nodeType === 1 && node && node.nodeValue === match; + }; + } + + root.removeChild( form ); + + // release memory in IE + root = form = null; +})(); + +(function(){ + // Check to see if the browser returns only elements + // when doing getElementsByTagName("*") + + // Create a fake element + var div = document.createElement("div"); + div.appendChild( document.createComment("") ); + + // Make sure no comments are found + if ( div.getElementsByTagName("*").length > 0 ) { + Expr.find.TAG = function( match, context ) { + var results = context.getElementsByTagName( match[1] ); + + // Filter out possible comments + if ( match[1] === "*" ) { + var tmp = []; + + for ( var i = 0; results[i]; i++ ) { + if ( results[i].nodeType === 1 ) { + tmp.push( results[i] ); + } + } + + results = tmp; + } + + return results; + }; + } + + // Check to see if an attribute returns normalized href attributes + div.innerHTML = ""; + + if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" && + div.firstChild.getAttribute("href") !== "#" ) { + + Expr.attrHandle.href = function( elem ) { + return elem.getAttribute( "href", 2 ); + }; + } + + // release memory in IE + div = null; +})(); + +if ( document.querySelectorAll ) { + (function(){ + var oldSizzle = Sizzle, + div = document.createElement("div"), + id = "__sizzle__"; + + div.innerHTML = "

    "; + + // Safari can't handle uppercase or unicode characters when + // in quirks mode. + if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) { + return; + } + + Sizzle = function( query, context, extra, seed ) { + context = context || document; + + // Only use querySelectorAll on non-XML documents + // (ID selectors don't work in non-HTML documents) + if ( !seed && !Sizzle.isXML(context) ) { + // See if we find a selector to speed up + var match = /^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec( query ); + + if ( match && (context.nodeType === 1 || context.nodeType === 9) ) { + // Speed-up: Sizzle("TAG") + if ( match[1] ) { + return makeArray( context.getElementsByTagName( query ), extra ); + + // Speed-up: Sizzle(".CLASS") + } else if ( match[2] && Expr.find.CLASS && context.getElementsByClassName ) { + return makeArray( context.getElementsByClassName( match[2] ), extra ); + } + } + + if ( context.nodeType === 9 ) { + // Speed-up: Sizzle("body") + // The body element only exists once, optimize finding it + if ( query === "body" && context.body ) { + return makeArray( [ context.body ], extra ); + + // Speed-up: Sizzle("#ID") + } else if ( match && match[3] ) { + var elem = context.getElementById( match[3] ); + + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + if ( elem && elem.parentNode ) { + // Handle the case where IE and Opera return items + // by name instead of ID + if ( elem.id === match[3] ) { + return makeArray( [ elem ], extra ); + } + + } else { + return makeArray( [], extra ); + } + } + + try { + return makeArray( context.querySelectorAll(query), extra ); + } catch(qsaError) {} + + // qSA works strangely on Element-rooted queries + // We can work around this by specifying an extra ID on the root + // and working up from there (Thanks to Andrew Dupont for the technique) + // IE 8 doesn't work on object elements + } else if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) { + var oldContext = context, + old = context.getAttribute( "id" ), + nid = old || id, + hasParent = context.parentNode, + relativeHierarchySelector = /^\s*[+~]/.test( query ); + + if ( !old ) { + context.setAttribute( "id", nid ); + } else { + nid = nid.replace( /'/g, "\\$&" ); + } + if ( relativeHierarchySelector && hasParent ) { + context = context.parentNode; + } + + try { + if ( !relativeHierarchySelector || hasParent ) { + return makeArray( context.querySelectorAll( "[id='" + nid + "'] " + query ), extra ); + } + + } catch(pseudoError) { + } finally { + if ( !old ) { + oldContext.removeAttribute( "id" ); + } + } + } + } + + return oldSizzle(query, context, extra, seed); + }; + + for ( var prop in oldSizzle ) { + Sizzle[ prop ] = oldSizzle[ prop ]; + } + + // release memory in IE + div = null; + })(); +} + +(function(){ + var html = document.documentElement, + matches = html.matchesSelector || html.mozMatchesSelector || html.webkitMatchesSelector || html.msMatchesSelector; + + if ( matches ) { + // Check to see if it's possible to do matchesSelector + // on a disconnected node (IE 9 fails this) + var disconnectedMatch = !matches.call( document.createElement( "div" ), "div" ), + pseudoWorks = false; + + try { + // This should fail with an exception + // Gecko does not error, returns false instead + matches.call( document.documentElement, "[test!='']:sizzle" ); + + } catch( pseudoError ) { + pseudoWorks = true; + } + + Sizzle.matchesSelector = function( node, expr ) { + // Make sure that attribute selectors are quoted + expr = expr.replace(/\=\s*([^'"\]]*)\s*\]/g, "='$1']"); + + if ( !Sizzle.isXML( node ) ) { + try { + if ( pseudoWorks || !Expr.match.PSEUDO.test( expr ) && !/!=/.test( expr ) ) { + var ret = matches.call( node, expr ); + + // IE 9's matchesSelector returns false on disconnected nodes + if ( ret || !disconnectedMatch || + // As well, disconnected nodes are said to be in a document + // fragment in IE 9, so check for that + node.document && node.document.nodeType !== 11 ) { + return ret; + } + } + } catch(e) {} + } + + return Sizzle(expr, null, null, [node]).length > 0; + }; + } +})(); + +(function(){ + var div = document.createElement("div"); + + div.innerHTML = "
    "; + + // Opera can't find a second classname (in 9.6) + // Also, make sure that getElementsByClassName actually exists + if ( !div.getElementsByClassName || div.getElementsByClassName("e").length === 0 ) { + return; + } + + // Safari caches class attributes, doesn't catch changes (in 3.2) + div.lastChild.className = "e"; + + if ( div.getElementsByClassName("e").length === 1 ) { + return; + } + + Expr.order.splice(1, 0, "CLASS"); + Expr.find.CLASS = function( match, context, isXML ) { + if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) { + return context.getElementsByClassName(match[1]); + } + }; + + // release memory in IE + div = null; +})(); + +function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { + for ( var i = 0, l = checkSet.length; i < l; i++ ) { + var elem = checkSet[i]; + + if ( elem ) { + var match = false; + + elem = elem[dir]; + + while ( elem ) { + if ( elem[ expando ] === doneName ) { + match = checkSet[elem.sizset]; + break; + } + + if ( elem.nodeType === 1 && !isXML ){ + elem[ expando ] = doneName; + elem.sizset = i; + } + + if ( elem.nodeName.toLowerCase() === cur ) { + match = elem; + break; + } + + elem = elem[dir]; + } + + checkSet[i] = match; + } + } +} + +function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { + for ( var i = 0, l = checkSet.length; i < l; i++ ) { + var elem = checkSet[i]; + + if ( elem ) { + var match = false; + + elem = elem[dir]; + + while ( elem ) { + if ( elem[ expando ] === doneName ) { + match = checkSet[elem.sizset]; + break; + } + + if ( elem.nodeType === 1 ) { + if ( !isXML ) { + elem[ expando ] = doneName; + elem.sizset = i; + } + + if ( typeof cur !== "string" ) { + if ( elem === cur ) { + match = true; + break; + } + + } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) { + match = elem; + break; + } + } + + elem = elem[dir]; + } + + checkSet[i] = match; + } + } +} + +if ( document.documentElement.contains ) { + Sizzle.contains = function( a, b ) { + return a !== b && (a.contains ? a.contains(b) : true); + }; + +} else if ( document.documentElement.compareDocumentPosition ) { + Sizzle.contains = function( a, b ) { + return !!(a.compareDocumentPosition(b) & 16); + }; + +} else { + Sizzle.contains = function() { + return false; + }; +} + +Sizzle.isXML = function( elem ) { + // documentElement is verified for cases where it doesn't yet exist + // (such as loading iframes in IE - #4833) + var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement; + + return documentElement ? documentElement.nodeName !== "HTML" : false; +}; + +var posProcess = function( selector, context, seed ) { + var match, + tmpSet = [], + later = "", + root = context.nodeType ? [context] : context; + + // Position selectors must be done after the filter + // And so must :not(positional) so we move all PSEUDOs to the end + while ( (match = Expr.match.PSEUDO.exec( selector )) ) { + later += match[0]; + selector = selector.replace( Expr.match.PSEUDO, "" ); + } + + selector = Expr.relative[selector] ? selector + "*" : selector; + + for ( var i = 0, l = root.length; i < l; i++ ) { + Sizzle( selector, root[i], tmpSet, seed ); + } + + return Sizzle.filter( later, tmpSet ); +}; + +// EXPOSE +// Override sizzle attribute retrieval +Sizzle.attr = jQuery.attr; +Sizzle.selectors.attrMap = {}; +jQuery.find = Sizzle; +jQuery.expr = Sizzle.selectors; +jQuery.expr[":"] = jQuery.expr.filters; +jQuery.unique = Sizzle.uniqueSort; +jQuery.text = Sizzle.getText; +jQuery.isXMLDoc = Sizzle.isXML; +jQuery.contains = Sizzle.contains; + + +})(); + + +var runtil = /Until$/, + rparentsprev = /^(?:parents|prevUntil|prevAll)/, + // Note: This RegExp should be improved, or likely pulled from Sizzle + rmultiselector = /,/, + isSimple = /^.[^:#\[\.,]*$/, + slice = Array.prototype.slice, + POS = jQuery.expr.match.globalPOS, + // methods guaranteed to produce a unique set when starting from a unique set + guaranteedUnique = { + children: true, + contents: true, + next: true, + prev: true + }; + +jQuery.fn.extend({ + find: function( selector ) { + var self = this, + i, l; + + if ( typeof selector !== "string" ) { + return jQuery( selector ).filter(function() { + for ( i = 0, l = self.length; i < l; i++ ) { + if ( jQuery.contains( self[ i ], this ) ) { + return true; + } + } + }); + } + + var ret = this.pushStack( "", "find", selector ), + length, n, r; + + for ( i = 0, l = this.length; i < l; i++ ) { + length = ret.length; + jQuery.find( selector, this[i], ret ); + + if ( i > 0 ) { + // Make sure that the results are unique + for ( n = length; n < ret.length; n++ ) { + for ( r = 0; r < length; r++ ) { + if ( ret[r] === ret[n] ) { + ret.splice(n--, 1); + break; + } + } + } + } + } + + return ret; + }, + + has: function( target ) { + var targets = jQuery( target ); + return this.filter(function() { + for ( var i = 0, l = targets.length; i < l; i++ ) { + if ( jQuery.contains( this, targets[i] ) ) { + return true; + } + } + }); + }, + + not: function( selector ) { + return this.pushStack( winnow(this, selector, false), "not", selector); + }, + + filter: function( selector ) { + return this.pushStack( winnow(this, selector, true), "filter", selector ); + }, + + is: function( selector ) { + return !!selector && ( + typeof selector === "string" ? + // If this is a positional selector, check membership in the returned set + // so $("p:first").is("p:last") won't return true for a doc with two "p". + POS.test( selector ) ? + jQuery( selector, this.context ).index( this[0] ) >= 0 : + jQuery.filter( selector, this ).length > 0 : + this.filter( selector ).length > 0 ); + }, + + closest: function( selectors, context ) { + var ret = [], i, l, cur = this[0]; + + // Array (deprecated as of jQuery 1.7) + if ( jQuery.isArray( selectors ) ) { + var level = 1; + + while ( cur && cur.ownerDocument && cur !== context ) { + for ( i = 0; i < selectors.length; i++ ) { + + if ( jQuery( cur ).is( selectors[ i ] ) ) { + ret.push({ selector: selectors[ i ], elem: cur, level: level }); + } + } + + cur = cur.parentNode; + level++; + } + + return ret; + } + + // String + var pos = POS.test( selectors ) || typeof selectors !== "string" ? + jQuery( selectors, context || this.context ) : + 0; + + for ( i = 0, l = this.length; i < l; i++ ) { + cur = this[i]; + + while ( cur ) { + if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) { + ret.push( cur ); + break; + + } else { + cur = cur.parentNode; + if ( !cur || !cur.ownerDocument || cur === context || cur.nodeType === 11 ) { + break; + } + } + } + } + + ret = ret.length > 1 ? jQuery.unique( ret ) : ret; + + return this.pushStack( ret, "closest", selectors ); + }, + + // Determine the position of an element within + // the matched set of elements + index: function( elem ) { + + // No argument, return index in parent + if ( !elem ) { + return ( this[0] && this[0].parentNode ) ? this.prevAll().length : -1; + } + + // index in selector + if ( typeof elem === "string" ) { + return jQuery.inArray( this[0], jQuery( elem ) ); + } + + // Locate the position of the desired element + return jQuery.inArray( + // If it receives a jQuery object, the first element is used + elem.jquery ? elem[0] : elem, this ); + }, + + add: function( selector, context ) { + var set = typeof selector === "string" ? + jQuery( selector, context ) : + jQuery.makeArray( selector && selector.nodeType ? [ selector ] : selector ), + all = jQuery.merge( this.get(), set ); + + return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ? + all : + jQuery.unique( all ) ); + }, + + andSelf: function() { + return this.add( this.prevObject ); + } +}); + +// A painfully simple check to see if an element is disconnected +// from a document (should be improved, where feasible). +function isDisconnected( node ) { + return !node || !node.parentNode || node.parentNode.nodeType === 11; +} + +jQuery.each({ + parent: function( elem ) { + var parent = elem.parentNode; + return parent && parent.nodeType !== 11 ? parent : null; + }, + parents: function( elem ) { + return jQuery.dir( elem, "parentNode" ); + }, + parentsUntil: function( elem, i, until ) { + return jQuery.dir( elem, "parentNode", until ); + }, + next: function( elem ) { + return jQuery.nth( elem, 2, "nextSibling" ); + }, + prev: function( elem ) { + return jQuery.nth( elem, 2, "previousSibling" ); + }, + nextAll: function( elem ) { + return jQuery.dir( elem, "nextSibling" ); + }, + prevAll: function( elem ) { + return jQuery.dir( elem, "previousSibling" ); + }, + nextUntil: function( elem, i, until ) { + return jQuery.dir( elem, "nextSibling", until ); + }, + prevUntil: function( elem, i, until ) { + return jQuery.dir( elem, "previousSibling", until ); + }, + siblings: function( elem ) { + return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem ); + }, + children: function( elem ) { + return jQuery.sibling( elem.firstChild ); + }, + contents: function( elem ) { + return jQuery.nodeName( elem, "iframe" ) ? + elem.contentDocument || elem.contentWindow.document : + jQuery.makeArray( elem.childNodes ); + } +}, function( name, fn ) { + jQuery.fn[ name ] = function( until, selector ) { + var ret = jQuery.map( this, fn, until ); + + if ( !runtil.test( name ) ) { + selector = until; + } + + if ( selector && typeof selector === "string" ) { + ret = jQuery.filter( selector, ret ); + } + + ret = this.length > 1 && !guaranteedUnique[ name ] ? jQuery.unique( ret ) : ret; + + if ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( name ) ) { + ret = ret.reverse(); + } + + return this.pushStack( ret, name, slice.call( arguments ).join(",") ); + }; +}); + +jQuery.extend({ + filter: function( expr, elems, not ) { + if ( not ) { + expr = ":not(" + expr + ")"; + } + + return elems.length === 1 ? + jQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] : + jQuery.find.matches(expr, elems); + }, + + dir: function( elem, dir, until ) { + var matched = [], + cur = elem[ dir ]; + + while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) { + if ( cur.nodeType === 1 ) { + matched.push( cur ); + } + cur = cur[dir]; + } + return matched; + }, + + nth: function( cur, result, dir, elem ) { + result = result || 1; + var num = 0; + + for ( ; cur; cur = cur[dir] ) { + if ( cur.nodeType === 1 && ++num === result ) { + break; + } + } + + return cur; + }, + + sibling: function( n, elem ) { + var r = []; + + for ( ; n; n = n.nextSibling ) { + if ( n.nodeType === 1 && n !== elem ) { + r.push( n ); + } + } + + return r; + } +}); + +// Implement the identical functionality for filter and not +function winnow( elements, qualifier, keep ) { + + // Can't pass null or undefined to indexOf in Firefox 4 + // Set to 0 to skip string check + qualifier = qualifier || 0; + + if ( jQuery.isFunction( qualifier ) ) { + return jQuery.grep(elements, function( elem, i ) { + var retVal = !!qualifier.call( elem, i, elem ); + return retVal === keep; + }); + + } else if ( qualifier.nodeType ) { + return jQuery.grep(elements, function( elem, i ) { + return ( elem === qualifier ) === keep; + }); + + } else if ( typeof qualifier === "string" ) { + var filtered = jQuery.grep(elements, function( elem ) { + return elem.nodeType === 1; + }); + + if ( isSimple.test( qualifier ) ) { + return jQuery.filter(qualifier, filtered, !keep); + } else { + qualifier = jQuery.filter( qualifier, filtered ); + } + } + + return jQuery.grep(elements, function( elem, i ) { + return ( jQuery.inArray( elem, qualifier ) >= 0 ) === keep; + }); +} + + + + +function createSafeFragment( document ) { + var list = nodeNames.split( "|" ), + safeFrag = document.createDocumentFragment(); + + if ( safeFrag.createElement ) { + while ( list.length ) { + safeFrag.createElement( + list.pop() + ); + } + } + return safeFrag; +} + +var nodeNames = "abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|" + + "header|hgroup|mark|meter|nav|output|progress|section|summary|time|video", + rinlinejQuery = / jQuery\d+="(?:\d+|null)"/g, + rleadingWhitespace = /^\s+/, + rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig, + rtagName = /<([\w:]+)/, + rtbody = /]", "i"), + // checked="checked" or checked + rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i, + rscriptType = /\/(java|ecma)script/i, + rcleanScript = /^\s*", "" ], + legend: [ 1, "
    ", "
    " ], + thead: [ 1, "", "
    " ], + tr: [ 2, "", "
    " ], + td: [ 3, "", "
    " ], + col: [ 2, "", "
    " ], + area: [ 1, "", "" ], + _default: [ 0, "", "" ] + }, + safeFragment = createSafeFragment( document ); + +wrapMap.optgroup = wrapMap.option; +wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; +wrapMap.th = wrapMap.td; + +// IE can't serialize and + + + + + + + + + + +
    +
    +
    +
    + +
    +

    3. Vortex DDS Blocks¶

    +

    The DDS Simulink Integration provides a block library with custom blocks to model reading and writing data with DDS.

    +

    The Vortex DDS Simulink block library provides blocks which correspond to DDS entities. (Each DDS block is covered in its own section in this user guide.)

    +

    The following DDS block types are provided:

    +
    +
      +
    • Topic
    • +
    • Domain
    • +
    • Publisher
    • +
    • Subscriber
    • +
    • Writer
    • +
    • Reader
    • +
    +
    +
    +

    3.1. Optional DDS Blocks and Ports¶

    +

    Some of the DDS blocks are optional. (Domain, Publisher and Subscriber)

    +

    When the optional blocks are not added to model diagrams, defaults are used. This allows for simpler model diagrams. +If the model requires block parameter customization, the optional blocks can be added to a model to use non-default settings.

    +

    Many of the ports for the DDS blocks are also optional. They can be toggled on or off in the Block Parameters dialog, in the Ports tab.

    +
    +
    +

    3.2. QoS Profiles¶

    +

    In DDS - “The Data-Distribution Service (DDS) relies on the usage of QoS. A QoS (Quality of Service) is a set of characteristics that controls some aspect of the behavior of the DDS Service.”

    +

    Each DDS block has an associated QoS profile. By default, the OSPL default profile is used. An XML file that specifies QoS profiles can be used to set the QoS of a DDS block.

    +

    The QoS profile of a block is set in the QoS tab of the Block Parameters dialog. (This dialog is opened by double clicking on a selected block.)

    +

    Please see section QoS Provider for more information.

    +
    + +
    + + +
    +
    +
    +
    +
    + +

    Table Of Contents

    + + +

    Previous topic

    +

    2. Installation

    +

    Next topic

    +

    4. Simulink Bus to DDS Topic Mapping

    +

    This Page

    + + + +
    +
    +
    +
    + + + + \ No newline at end of file diff --git a/docs/html/DDSSimulinkGuide/bus-dds.html b/docs/html/DDSSimulinkGuide/bus-dds.html new file mode 100644 index 000000000..9c44900f2 --- /dev/null +++ b/docs/html/DDSSimulinkGuide/bus-dds.html @@ -0,0 +1,379 @@ + + + + + + + + 4. Simulink Bus to DDS Topic Mapping — The Vortex OpenSplice Simulink Guide + + + + + + + + + + + + + + + +
    +
    +
    +
    + + + + +
    +
    +
    + +
    +
    + + + + \ No newline at end of file diff --git a/docs/html/DDSSimulinkGuide/bus_to_dds_mapping.html b/docs/html/DDSSimulinkGuide/bus_to_dds_mapping.html new file mode 100644 index 000000000..74c18ee35 --- /dev/null +++ b/docs/html/DDSSimulinkGuide/bus_to_dds_mapping.html @@ -0,0 +1,417 @@ + + + + + + + + 15. Appendix A — The Vortex OpenSplice Simulink Guide + + + + + + + + + + + + + + + +
    +
    +
    +
    + +
    +

    15. Appendix A¶

    +

    Appendix A provides a description of the Simulink Bus to DDS Mapping implementation.

    + +
    + + +
    +
    +
    +
    +
    + +

    Table Of Contents

    + + +

    Previous topic

    +

    14. Troubleshooting

    +

    Next topic

    +

    16. Contacts & Notices

    +

    This Page

    + + + +
    +
    +
    +
    + + + + \ No newline at end of file diff --git a/docs/html/DDSSimulinkGuide/contacts.html b/docs/html/DDSSimulinkGuide/contacts.html new file mode 100644 index 000000000..a287327ee --- /dev/null +++ b/docs/html/DDSSimulinkGuide/contacts.html @@ -0,0 +1,153 @@ + + + + + + + + 16. Contacts & Notices — The Vortex OpenSplice Simulink Guide + + + + + + + + + + + + + + +
    +
    +
    +
    + +
    +

    16. Contacts & Notices¶

    +
    +

    16.1. Contacts¶

    +
    +
    ADLINK Technology Corporation
    +
    400 TradeCenter
    +
    Suite 5900
    +
    Woburn, MA
    +
    01801
    +
    USA
    +
    Tel: +1 781 569 5819
    +
    +
    +
    ADLINK Technology Limited
    +
    The Edge
    +
    5th Avenue
    +
    Team Valley
    +
    Gateshead
    +
    NE11 0XA
    +
    UK
    +
    Tel: +44 (0)191 497 9900
    +
    +
    +
    ADLINK Technology SARL
    +
    28 rue Jean Rostand
    +
    91400 Orsay
    +
    France
    +
    Tel: +33 (1) 69 015354
    +
    +

    Web: http://ist.adlinktech.com/

    +

    Contact: http://ist.adlinktech.com

    +

    E-mail: ist_info@adlinktech.com

    +

    LinkedIn: https://www.linkedin.com/company/79111/

    +

    Twitter: https://twitter.com/ADLINKTech_usa

    +

    Facebook: https://www.facebook.com/ADLINKTECH

    +
    +
    +

    16.2. Notices¶

    +

    Copyright © 2018 ADLINK Technology Limited. All rights reserved.

    +

    This document may be reproduced in whole but not in part. The information contained in this +document is subject to change without notice and is made available in good faith without +liability on the part of ADLINK Technology Limited. All trademarks acknowledged.

    +
    +
    + + +
    +
    +
    +
    +
    + +

    Table Of Contents

    + + +

    Previous topic

    +

    15. Appendix A

    +

    This Page

    + + + +
    +
    +
    +
    + + + + \ No newline at end of file diff --git a/docs/html/DDSSimulinkGuide/domain.html b/docs/html/DDSSimulinkGuide/domain.html new file mode 100644 index 000000000..6d9488691 --- /dev/null +++ b/docs/html/DDSSimulinkGuide/domain.html @@ -0,0 +1,173 @@ + + + + + + + + 7. Domain Block — The Vortex OpenSplice Simulink Guide + + + + + + + + + + + + + + + +
    +
    +
    +
    + +
    +

    7. Domain Block¶

    +

    The Domain block represents a DDS domain participant entity.

    +

    In DDS - “A domain participant represents the local membership of the application in a domain. A domain is a distributed concept that links all the applications able to communicate with each other. It represents a communication plane: only the publishers and subscribers attached to the same domain may interact.”

    +

    This block is optional on a DDS Simulink model diagram. If it is not present on a model diagram, a default participant will be created by either a topic, writer or reader block.

    +
    +DDS Domain Block +
    + +++++++ + + + + + + + + + + + + + + + + +
    Port TypeOptionalNameDescriptionOutput consumed by
    OutputnoppDDS Domain Participant +entity instancePublisher, +Subscriber, Topic
    +
    +

    7.1. Domain Block Parameters¶

    +
    +Domain Block Parameters +
    +
    +

    7.1.1. Domain Tab¶

    +

    The domain id is read only. The domain id is the OSPL default domain id specified in the OSPL configuration file.

    +
    +
    +

    7.1.2. QoS Tab¶

    +

    The QoS tab is used to set the QoS profile. By default, the OSPL default profile is used.

    +

    In DDS - The Data-Distribution Service (DDS) relies on the usage of QoS. A QoS (Quality of Service) is a set of characteristics that controls some aspect of the behavior of the DDS Service.

    +

    Each DDS block has an associated QoS profile. By default, the OSPL default profile is used. An XML file that specifies QoS profiles can be used to set the QoS of a DDS block.

    +
    +
    +
    + + +
    +
    +
    +
    +
    + +

    Table Of Contents

    + + +

    Previous topic

    +

    6. Topic Block

    +

    Next topic

    +

    8. Publisher Block

    +

    This Page

    + + + +
    +
    +
    +
    + + + + \ No newline at end of file diff --git a/docs/html/DDSSimulinkGuide/genindex.html b/docs/html/DDSSimulinkGuide/genindex.html new file mode 100644 index 000000000..7599ed7a4 --- /dev/null +++ b/docs/html/DDSSimulinkGuide/genindex.html @@ -0,0 +1,94 @@ + + + + + + + + + Index — The Vortex OpenSplice Simulink Guide + + + + + + + + + + + + + +
    +
    +
    +
    + + +

    Index

    + +
    + +
    + + +
    +
    +
    +
    +
    + + + + + + +
    +
    +
    +
    + + + + \ No newline at end of file diff --git a/docs/html/DDSSimulinkGuide/index.html b/docs/html/DDSSimulinkGuide/index.html new file mode 100644 index 000000000..e35998985 --- /dev/null +++ b/docs/html/DDSSimulinkGuide/index.html @@ -0,0 +1,311 @@ + + + + + + + + DDS Simulink Guide — The Vortex OpenSplice Simulink Guide + + + + + + + + + + + + + + +
    +
    +
    +
    + + + + +
    +
    +
    +
    +
    + +

    Table Of Contents

    + + +

    Next topic

    +

    1. Introduction

    +

    This Page

    + + + +
    +
    +
    +
    + + + + \ No newline at end of file diff --git a/docs/html/DDSSimulinkGuide/installation.html b/docs/html/DDSSimulinkGuide/installation.html new file mode 100644 index 000000000..66373593f --- /dev/null +++ b/docs/html/DDSSimulinkGuide/installation.html @@ -0,0 +1,234 @@ + + + + + + + + 2. Installation — The Vortex OpenSplice Simulink Guide + + + + + + + + + + + + + + + +
    +
    +
    +
    + +
    +

    2. Installation¶

    +

    This section describes the procedure to install the Vortex DDS Simulink Integration on a Linux or Windows platform.

    +
    +

    2.1. System Requirements¶

    +
      +
    • Operating System: Windows or Linux
    • +
    • MATLAB Simulink installed
    • +
    • Java 1.7 or greater
    • +
    +
    + +
    +

    2.3. OpenSplice (OSPL) Configuration¶

    +

    By default OSPL uses single process configuration.

    +

    If however, shared memory configuration is used, additional OSPL configuration steps need to be taken to work with MATLAB Simulink.

    +
    +

    2.3.1. Linux¶

    +

    OSPL-9882 Linux: MATLAB/Simulink hangs when connecting to shared memory domain

    +

    Description +On Linux, a MATLAB script or Simulink model connecting to a Vortex OpenSplice domain via shared memory will hang.

    +

    Resolution +MATLAB, like Java applications requires that the environment variable LD_PRELOAD be set to reference the active Java installations libjsig.so library. +The MATLAB user interface uses Java, and thus requires the same signal handling strategy as Java applications connecting to Vortex OpenSplice. +The precise syntax for setting the LD_PRELOAD environment variable will depend on the shell being used.

    +
    +
    For Oracle JVMs, LD_PRELOAD should contain this value:
    +
    $JAVA_HOME/jre/lib/amd64/libjsig.so
    +
    +
    +
    +

    2.3.2. Windows¶

    +

    OSPL-10018 MATLAB: Shared Memory Database Address on Windows needs to be changed from default

    +

    Description +On a Windows 64-bit system, an OpenSplice system configured with Shared Memory, MATLAB cannot connect to the OpenSplice domain if the Shared Memory Database Address is set to its default value of 0x40000000. The error log (ospl-error.log) will show entries such as: +Report : Can not Map View Of file: Attempt to access invalid address. +Internals : OS Abstraction/code/os_sharedmem.c/1764/0/1487951812.565129500

    +

    Resolution +Use the configuration editor to change the default data base address. Use the ‘Domain’ tab, and select the ‘Database’ element in the tree. If necessary, right click the Database element to add an ‘Address’ element. Change the address. In general, a larger number is less likely to be problematic. On a test machine, appending two zeros to the default address allowed for successful connections.

    +
    +
    + +
    +

    2.5. Examples¶

    +

    Example models have been provided in the examples folder.

    +

    ../tools/matlab/examples/simulink

    +
    +
    + + +
    +
    +
    +
    +
    + +

    Table Of Contents

    + + +

    Previous topic

    +

    1. Introduction

    +

    Next topic

    +

    3. Vortex DDS Blocks

    +

    This Page

    + + + +
    +
    +
    +
    + + + + \ No newline at end of file diff --git a/docs/html/DDSSimulinkGuide/introduction.html b/docs/html/DDSSimulinkGuide/introduction.html new file mode 100644 index 000000000..a541a7fda --- /dev/null +++ b/docs/html/DDSSimulinkGuide/introduction.html @@ -0,0 +1,139 @@ + + + + + + + + 1. Introduction — The Vortex OpenSplice Simulink Guide + + + + + + + + + + + + + + + +
    +
    +
    +
    + +
    +

    1. Introduction¶

    +

    The DDS Simulink Integration provides users with DDS custom blocks to model DDS communication between Simulink models and pure DDS applications.

    +
    +

    1.1. DDS¶

    +

    What is DDS?

    +

    “The Data Distribution Service (DDSâ„¢) is a middleware protocol and API standard for data-centric connectivity from the Object Management Group® (OMG®). It integrates the components of a system together, providing low-latency data connectivity, extreme reliability, and a scalable architecture that business and mission-critical Internet of Things (IoT) applications need.â€

    +

    “The main goal of DDS is to share the right data at the right place at the right time, even between time-decoupled publishers and consumers. DDS implements global data space by carefully replicating relevant portions of the logically shared dataspace.†DDS specification

    +
    +DDS +
    +

    Further Documentation

    +

    http://portals.omg.org/dds/

    +

    http://ist.adlinktech.com/

    +
    + +
    + + +
    +
    +
    +
    +
    + +

    Table Of Contents

    + + +

    Previous topic

    +

    DDS Simulink Guide

    +

    Next topic

    +

    2. Installation

    +

    This Page

    + + + +
    +
    +
    +
    + + + + \ No newline at end of file diff --git a/docs/html/DDSSimulinkGuide/objects.inv b/docs/html/DDSSimulinkGuide/objects.inv new file mode 100644 index 000000000..3dea99c25 Binary files /dev/null and b/docs/html/DDSSimulinkGuide/objects.inv differ diff --git a/docs/html/DDSSimulinkGuide/publisher.html b/docs/html/DDSSimulinkGuide/publisher.html new file mode 100644 index 000000000..20be0eafd --- /dev/null +++ b/docs/html/DDSSimulinkGuide/publisher.html @@ -0,0 +1,179 @@ + + + + + + + + 8. Publisher Block — The Vortex OpenSplice Simulink Guide + + + + + + + + + + + + + + + +
    +
    +
    +
    + +
    +

    8. Publisher Block¶

    +

    The Publisher block represents a DDS publisher entity.

    +

    In DDS, a publisher is “an object responsible for data distribution. It may publish data of different data types.”

    +

    This block is optional on a DDS Simulink model diagram. If it is not present on a model diagram, each writer will create a default publisher.

    +
    +DDS Publisher Block +
    + +++++++ + + + + + + + + + + + + + + + + + + + + + + +
    Port TypeOptionalNameDescriptionOutput consumed by
    InputyesppDDS Domain Participant +entity instance 
    OutputnoppubDDS Publisher entity +instanceWriter
    +
    +

    8.1. Publisher Block Parameters¶

    +
    +Publisher Block Parameters +
    +
    +

    8.1.1. Ports Tab¶

    +

    The Ports tab allows the user to toggle on or off optional ports.

    +
    +
    +

    8.1.2. QoS Tab¶

    +

    The QoS tab is used to set the QoS profile. By default, the OSPL default profile is used.

    +

    In DDS - The Data-Distribution Service (DDS) relies on the usage of QoS. A QoS (Quality of Service) is a set of characteristics that controls some aspect of the behavior of the DDS Service.

    +

    Each DDS block has an associated QoS profile. By default, the OSPL default profile is used. An XML file that specifies QoS profiles can be used to set the QoS of a DDS block.

    +
    +
    +
    + + +
    +
    +
    +
    +
    + +

    Table Of Contents

    + + +

    Previous topic

    +

    7. Domain Block

    +

    Next topic

    +

    9. Subscriber Block

    +

    This Page

    + + + +
    +
    +
    +
    + + + + \ No newline at end of file diff --git a/docs/html/DDSSimulinkGuide/qos_provider.html b/docs/html/DDSSimulinkGuide/qos_provider.html new file mode 100644 index 000000000..a3a7949c4 --- /dev/null +++ b/docs/html/DDSSimulinkGuide/qos_provider.html @@ -0,0 +1,190 @@ + + + + + + + + 5. QoS Provider — The Vortex OpenSplice Simulink Guide + + + + + + + + + + + + + + + +
    +
    +
    +
    + +
    +

    5. QoS Provider¶

    +

    Each Vortex DDS block has a QoS that can be set using the Block Parameters.

    +

    The following section explains how the QoS is set for a DDS entity using the QoS Provider.

    +
    +

    5.1. QoS Provider File¶

    +

    Quality of Service for DDS entities is set using XML files based on the XML schema file DDS_QoSProfile.xsd. +These XML files contain one or more QoS profiles for DDS entities. An example with a default QoS profile +for all entity types can be found at DDS_DefaultQoS.xml.

    +

    Note: Sample QoS Profile XML files can be found in the examples directories.

    +
    +
    +

    5.2. QoS Profile¶

    +

    A QoS profile consists of a name. The file contains QoS +elements for one or more DDS entities. A skeleton file without any QoS values is displayed below to show +the structure of the file.

    +
    <dds xmlns="http://www.omg.org/dds/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    +            xsi:schemaLocation="file:DDS_QoSProfile.xsd">
    +    <qos_profile name="DDS QoS Profile Name">
    +        <datareader_qos></datareader_qos>
    +        <datawriter_qos></datawriter_qos>
    +        <domainparticipant_qos></domainparticipant_qos>
    +        <subscriber_qos></subscriber_qos>
    +        <publisher_qos></publisher_qos>
    +        <topic_qos></topic_qos>
    +    </qos_profile>
    +</dds>
    +
    +
    +

    Example: Specify Publisher Partition

    +

    The example below specifies the publisher’s partitions as A and B.

    +
    <publisher_qos>
    +    <partition>
    +        <name>
    +            <element>A</element>
    +            <element>B</element>
    +        </name>
    +    </partition>
    +</publisher_qos>
    +
    +
    +
    + +
    +

    5.4. Known Limitations¶

    +

    See QoS Provider Known Limitations for a list of limitations +on QoS Provider support.

    +
    +
    + + +
    +
    +
    +
    +
    + +

    Table Of Contents

    + + +

    Previous topic

    +

    4. Simulink Bus to DDS Topic Mapping

    +

    Next topic

    +

    6. Topic Block

    +

    This Page

    + + + +
    +
    +
    +
    + + + + \ No newline at end of file diff --git a/docs/html/DDSSimulinkGuide/reader.html b/docs/html/DDSSimulinkGuide/reader.html new file mode 100644 index 000000000..a20471da8 --- /dev/null +++ b/docs/html/DDSSimulinkGuide/reader.html @@ -0,0 +1,263 @@ + + + + + + + + 11. Reader Block — The Vortex OpenSplice Simulink Guide + + + + + + + + + + + + + + + +
    +
    +
    +
    + +
    +

    11. Reader Block¶

    +

    The Reader block represents a DDS data reader entity.

    +

    In DDS - “To access the received data, the application must use a typed DataReader attached to the subscriber.”

    +
    +DDS Reader Block +
    + +++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Port TypeOptionalNameDescriptionOutput consumed by
    InputyespsubDDS Subscriber +entity instance 
    InputnotopicDDS Topic entity instance 
    Outputyesstatus0 for successful reader +creation 
    OutputnodataBUSuser
    OutputyesinfoBUSuser
    Outputyessamples readNumber of samples readuser
    +
    +

    11.1. Reader Block Parameters¶

    +
    +Reader Block Parameters +
    +
    +

    11.1.1. Data Tab¶

    +

    The Data tab is used to set:

    +
      +
    • Bus Type

      +
      +

      The output data type (BUS) for the data output port

      +
      +
    • +
    • Mode: take or read

      +
      +

      Specify whether the reader block is accessing the samples using DDS take or DDS read.

      +
      +
    • +
    • Sample Time

      +
      +

      “The sample time of a block is a parameter that indicates when, during simulation, the block produces outputs and if appropriate, updates its internal state.” -Simulink documentation

      +

      Default is -1, meaning it will inherit the Simulink sample time from inputs or the model. +Valid values: -1 and Numeric > 0

      +
      +
    • +
    • Bus Width

      +
      +

      The bus width is the maximum number of samples that can be read or take(n) per block step. +Valid values for the bus width are: integers >= 1.

      +
      +
    • +
    +
      +
    • Wait for

      +
      +

      Checking the Historical Data field in the Wait for section specifies that the Reader will wait for historical data to arrive. The Timeout field is for setting time period (in seconds) determining how long the Reader should wait for the historical data. +If the timeout is reached, then any remaining historical data may be interleaved with new data.

      +

      The Data Available field is for specifying whether the Reader should read only if the data is available. The following Timeouts field determines how long the Reader should wait for the availability of data. +If the timeout is reached, then the block returns no data and the simulation continues.

      +
      +
    • +
    +
    +
    +

    11.1.2. Ports Tab¶

    +

    The Ports tab allows the user to toggle on or off optional ports.

    +
    +
    +

    11.1.3. QoS Tab¶

    +

    The QoS tab is used to set the QoS profile. By default, the OSPL default profile is used.

    +

    In DDS - The Data-Distribution Service (DDS) relies on the usage of QoS. A QoS (Quality of Service) is a set of characteristics that controls some aspect of the behavior of the DDS Service.

    +

    Each DDS block has an associated QoS profile. By default, the OSPL default profile is used. An XML file that specifies QoS profiles can be used to set the QoS of a DDS block.

    +
    +
    +

    11.1.4. Filters Tab¶

    +

    The filters tab allows for the filtering of incoming samples. +The filtering can happen based on a query and/or on a sample read condition(s).

    +

    Query

    +

    Expression: The expression is a SQL condition.

    +

    Parameters: N parameters in the format {‘a’, ‘b’} +Each parameter element must be a char array (string).

    +

    Note: Query expressions are only validated at runtime.

    +

    Read Condition

    +

    The read conditions specified will filter the samples that are read or take(n).

    +

    Example: For a reader, the Sample State has Read selected and Not Read deselected.

    +

    Only samples with a Sample State Read will be processed with read or take. +Any samples with the Not Read sample state will not be read or take(n).

    +

    Note: At least one read condition must be selected for each category of Sample State, View State, or Instance State. +If not, an error will be thrown when a diagram simulation is run.

    +
    +Reader Block Parameters : Filters +
    +
    +
    +
    + + +
    +
    +
    +
    +
    + +

    Table Of Contents

    + + +

    Previous topic

    +

    10. Writer Block

    +

    Next topic

    +

    12. Tutorial

    +

    This Page

    + + + +
    +
    +
    +
    + + + + \ No newline at end of file diff --git a/docs/html/DDSSimulinkGuide/search.html b/docs/html/DDSSimulinkGuide/search.html new file mode 100644 index 000000000..d789b4e54 --- /dev/null +++ b/docs/html/DDSSimulinkGuide/search.html @@ -0,0 +1,101 @@ + + + + + + + + Search — The Vortex OpenSplice Simulink Guide + + + + + + + + + + + + + + + + + + + +
    +
    +
    +
    + +

    Search

    +
    + +

    + Please activate JavaScript to enable the search + functionality. +

    +
    +

    + From here you can search these documents. Enter your search + words into the box below and click "search". Note that the search + function will automatically search for all of the words. Pages + containing fewer words won't appear in the result list. +

    +
    + + + +
    + +
    + +
    + +
    +
    +
    +
    +
    + +
    +
    +
    +
    + + + + \ No newline at end of file diff --git a/docs/html/DDSSimulinkGuide/searchindex.js b/docs/html/DDSSimulinkGuide/searchindex.js new file mode 100644 index 000000000..78d107699 --- /dev/null +++ b/docs/html/DDSSimulinkGuide/searchindex.js @@ -0,0 +1 @@ +Search.setIndex({envversion:42,terms:{represent:9,all:[0,1,3,9,5],code:[6,0,15,9],edg:5,illustr:9,queri:14,consum:[8,1,6,7,11,12,14],although:[9,16],concept:[1,10],follow:[2,3,4,10,9,12,14,16],skeleton:3,hierarch:9,whose:[9,10],depend:[15,16],graph:16,specif:[6,2,9],send:10,program:16,matlab:[0,15,4,6,9,10,12],jvm:15,under:3,keylist:[9,16,10],ist_info:5,global:6,everi:10,internet:6,wave:16,facebook:5,failur:9,solver:[6,16],brows:[3,16],relev:[6,16],level:6,button:[0,3],list:[3,16],fewer:10,correct:[15,4],"try":4,item:16,unsupport:[9,10],team:5,quick:16,categori:[4,14],prepar:0,pleas:[2,9],upper:9,outlin:16,tel:5,ten:16,seq_str:9,sign:9,zero:[15,9],design:[6,9,16],further:6,idlpp:9,click:[16,15,2,13,4],append:15,compat:[9,10],what:[6,2],appear:4,blockwarn:4,clock:16,section:[15,3,7,9,14,2,16],abl:1,hde:[15,13,16],current:[9,16],qos_profil:3,win64:[15,13],"new":[0,9,14],row:4,"public":[9,16],datareader_qo:3,centric:6,dropdown:16,here:9,bodi:9,sink:16,address:[15,10],path:4,"0xa":5,becom:[7,10],modifi:9,valu:2,wait:[7,14],box:4,convert:[9,10],produc:[7,2,14],convers:[10,16],larger:15,technolog:5,precis:15,buss:[9,10],action:7,extrem:6,implement:[6,9,10],typedescriptor:10,jre:15,writer:[0,1,2,8,9,12],repositori:16,appli:[16,4],modul:[9,10],avenu:5,"boolean":10,uniqu:9,busel:0,instal:0,total:16,installdir:[15,13,16],select:[15,0,2,3,14],from:2,describ:[15,9,4,10],would:[9,16],memori:[15,10],doubl:[15,9,10,13,2,16],two:[15,9,16,10],connector:16,idl_default:9,latenc:6,call:[16,9,4],tradecent:5,recommend:10,taken:15,scope:10,wstring:[9,10],type:[2,9],until:16,toggl:[0,2,8,11,12,14],more:[2,3,9],ld_preload:15,flat:9,mltbx:15,uint8:[10,16],enhanc:9,warn:[9,4],appendix:9,particular:10,known:0,compani:5,must:[4,7,9,10,12,14],buscreat:16,none:[3,4],graphic:6,scalabl:6,setup:0,work:[15,10],annot:[10,3,16,9],remain:14,minimum:4,can:[8,1,2,3,4,7,9,10,11,12,14,15,16],purpos:16,root:4,problemat:15,control:[8,1,2,7,11,12,14],distrubut:4,prompt:[15,13],want:9,process:[15,9,14],registr:10,share:[6,15,4],therfor:10,indic:2,topic:2,critic:6,tag:3,explor:0,unsign:[9,10],occur:[15,4],goal:6,anoth:[9,4],seqmax:9,environ:[6,15,13,4],write:[0,2,9,10],how:[3,7,10,9,14,16],consist:3,pure:6,instead:4,updat:[2,9,16,14],ne11:5,int16:10,ospl:[0,1,2,9],vortex_v2:[15,13,16],max:[10,16],after:[7,9,16],invok:[9,10],manuali:4,membership:1,plane:1,mai:[8,1,4,5,11,14],associ:[8,1,2,7,11,12,14],demonstr:16,idlfilenam:9,alloc:10,"short":10,attempt:[15,9,4],correspond:[12,2,9,10],element:[15,3,10,9,14,16],issu:[16,4],inform:[2,9,4,5],int64:10,allow:[8,2,4,7,9,11,12,14,15,16],order:4,origin:9,help:[6,9,16],diagnos:16,xmlschema:3,becaus:[9,4],pane:4,entitl:15,dynam:6,entiti:[8,1,2,3,7,9,11,12,14],typedef:10,group:[6,4],chosen:3,fix:[9,16],ansi_opt:4,platform:[15,4],window:[0,9],whole:5,creat:[0,1,4,8,10,9,11],persist:16,mail:5,main:6,non:[2,9,4],good:5,"return":[9,4,14],greater:15,thei:[2,9,16],handl:15,cover:[2,16],initi:[9,4],bound:[9,16],verifi:3,now:[9,16],introduct:0,edit:[12,2,9,4,16],troubleshoot:0,drop:[3,4],revert:4,refresh:16,psub:[11,14],mode:[4,14],timeout:[7,14],each:[8,1,2,3,7,9,10,11,12,14],found:[3,4,9],difficult:10,side:16,dds_qosprofil:3,mean:[2,3,16,14],compil:4,domain:2,interleav:14,seq_t:[9,10],continu:[6,14],procedur:15,connect:[6,0,15,4],our:[9,16],happen:14,dispos:7,variabl:[15,10,4,13],shown:[13,16],referenc:[16,4],space:6,publish:[6,0,1,2],content:9,reader:[0,1,2,9],uint32:10,math:16,franc:5,qualifi:9,navig:[15,9,16,13],verif:6,differ:[11,8,2,9,10],standard:6,base:[6,15,3,16,14],dictionari:[9,16,10],releas:[15,9,4,13],org:[6,3],"byte":16,hand:4,thrown:14,diagram:[8,1,2,6,11,14,16],suffici:4,success:[7,15,9,14],ist:[6,5],filter:0,thing:6,length:[9,10],place:[6,10,4],descript:[8,1,15,7,10,11,12,14,16],onto:16,assign:9,messagea:9,first:[10,16],oper:[7,15,16],dimens:[10,16],directli:10,x86_64:[15,13,16],onc:[2,3,4,9],arrai:[14,7,9,10],qualiti:[8,1,2,3,7,11,12,14],number:[7,15,9,14],alreadi:9,least:[4,14],blank:[0,9],open:[15,0,2,13,4],avail:[11,7,14,5],given:[7,9],breviti:9,script:[15,9,4,13],data:[2,9],interact:[1,10],system:0,messag:[9,4,13],attach:[1,14],circl:16,mathwork:4,fullfil:15,"final":9,store:[9,16],schema:3,shell:[15,13],namespac:[9,10],tool:[15,9,16],copi:[15,10,4],dataspac:6,specifi:[8,1,2,3,4,7,9,11,12,14,16],selector:0,part:[16,4,5],pars:4,pragma:[9,16,10],termin:[15,13],wchar:[9,10],serv:9,target:[16,9,4],instanc:[8,1,3,7,11,12,14,16],provid:[0,2,6,9,10,15],remov:[9,4],tree:15,second:[7,16,14],structur:[3,16,9],charact:9,arriv:14,posit:16,other:[1,10],browser:0,"function":[16,9,4],sai:9,comput:16,argument:9,packag:4,xmln:3,have:[15,4,9,13,2,16],tabl:[9,10],need:[15,4,6,10,12,16],seen:9,caus:13,unqualifi:9,built:0,equival:[9,10],lic:15,rout:16,note:[14,15,3,16,9],also:[2,9,16,10],exampl:[0,9],take:[16,14],which:[16,2,9,4],green:16,dds_reader_writer_model:16,text:4,singl:[12,15,10],even:6,maskdialog:13,distribut:[8,1,2,4,6,7,11,12,14],c99:4,object:[6,0,11,9,8],oracl:15,discov:9,artifact:[9,10],model:[2,9],renam:9,clear:16,later:9,dictionaryfil:9,doe:[3,16],declar:[9,16],runtim:[4,14],determin:[10,14],left:4,adlink:[15,13,16,5],simpledomain:4,seqn_t:[9,10],show:[15,3,9],carefulli:6,enumer:[9,10],syntax:15,bring:[15,16],ppub:[8,7,16],callback:13,find:4,rotat:16,xml:[8,1,2,3,7,10,11,12,14,16],access:[15,16,14],onli:[1,2,3,4,7,14,16],explicitli:[16,4],copyright:5,menu:[16,4],explain:[3,4],configur:[0,1],activ:15,state:[2,4,14],dds_domain_default:16,should:[15,4,7,9,12,14],busi:[6,4],suppos:9,factor:16,folder:[15,9,16],local:[1,4],conversli:10,buse:[9,16,10],overwritten:9,info:[9,16,14],move:16,shapetyp:[0,9],get:4,express:14,stop:16,mission:6,newpag:[15,3,7,14,2,16],cannot:[15,4],java_hom:15,report:15,requir:[0,2,9,10],bat:[15,13,4],enabl:[6,7],"default":2,integr:[6,15,2,9,16],partit:3,contain:[15,3,4,5,10,9,13,16],where:[9,16],view:[15,4,9,13,14,16],keyless:16,set:[0,1,2,8,9,10,15],aspect:[8,1,2,7,11,12,14],creator:0,displai:[0,3],datatyp:16,see:[16,2,3,4,9],full:4,result:[6,16],respons:[11,8,3],reserv:5,close:[16,4],publisher_qo:3,subject:5,statu:[7,9,16,14],kei:[0,9,10],correctli:[10,4,13],databas:15,someth:9,particip:[8,1,4,11,12,16],written:[7,10,16],between:[6,10],"import":[9,16],bstring:[10,16],paramet:[2,9],assumpt:9,omg:[6,3],parent:2,numer:[2,14],rostand:5,extens:9,sumlink:10,preprocessor:[9,4],solv:9,problem:[9,16],addit:15,both:[9,16],howev:[15,9],equal:9,against:9,tutori:[0,9],context:9,logic:6,mani:[2,16],com:[6,15,13,4,5],comment:[9,10],figur:9,color:0,period:14,dispatch:11,header:4,linux:0,guid:[2,9],liabil:5,sine:16,java:15,start:[0,15,4],sarl:5,union:[9,10],trademark:5,been:[15,13,4],compon:[6,4],treat:16,subscrib:[0,1,2,14],immedi:9,dure:[2,16,14],strategi:15,imag:4,seq3_int32:10,search:[0,4],ani:[3,4,10,9,14,16],dds_defaultqo:3,sldd:[9,16],togeth:6,workspac:[12,16],present:[11,8,1,3,9],"case":10,replic:6,therefor:16,slx:16,servic:[8,1,2,3,6,7,11,12,14],properti:[0,9],histor:14,defin:[12,9,16,10],"while":4,behavior:[8,1,2,7,11,12,14],error:[14,15,9,4,13],subsect:9,gateshead:5,customiz:6,applic:[1,15,6,7,10,11,14],readi:4,"5th":5,them:9,linkedin:5,topic_qo:3,incom:14,feed:7,int8:[9,16,10],receiv:[11,9,16,14],make:[11,9,16],format:[9,14],same:[16,1,15,9,4],domainparticipant_qo:3,complex:16,pad:16,document:[2,4,5,6,10,9,14,16],infer:10,complet:[15,16],vortex_dds_block_set:15,finish:9,http:[6,3,5],iot:6,hang:15,solut:13,capabl:16,portal:6,user:[8,2,3,6,7,9,11,12,14,15],decoupl:6,expand:10,appropri:[15,2,4,14],off:[0,2,8,11,12,14],lib:15,entri:15,thu:15,min:16,inherit:[14,2,9,4,10],without:[10,3,5],command:[0,15,4,9,10,13],thi:[8,1,2,4,5,9,10,11,15,16],choos:4,jean:5,woburn:5,usual:16,protocol:6,paus:16,execut:[2,4],less:[15,10],shape:[0,9],via:[15,4],subblock:4,shapes_write_model:16,stringmax:9,simultan:16,speed:16,seq_int32:10,languag:[10,4],web:5,amd64:15,point:4,except:15,uint16:10,input:[0,2,8,9,11,12,14],save:[0,4],build:[12,4],real:16,int32:[10,16],subscriber_qo:3,ospl_hom:[15,4],read:[0,1,2,9,10,14],adlinktech:[6,5],bia:16,datawriter_qo:3,bit:15,characterist:[8,1,2,7,11,12,14],licens:[15,4],mod:16,insert:[9,16],like:[15,16],lost:16,corpor:5,signal:[12,15,16],integ:[7,14],shapes:0,api:6,necessari:[15,10,16],either:[1,9,16],xsd:3,output:[0,1,2,4,8,11,12,14],xsi:3,page:0,www:[3,5],right:[6,7,15,16,5],vortexopensplic:[15,13,16],acknowledg:5,twitter:5,visibl:3,some:[8,1,2,7,9,11,12,14],back:4,intern:[15,2,14],"export":[6,0],debug_util:4,guarante:3,librari:[0,2,4,6,9,15],applicatoin:10,avoid:4,octet:10,os_sharedmem:15,per:[7,9,14],datawrit:7,statusa:9,middlewar:6,condit:14,reproduc:5,refer:[15,9,4],multidomain:6,unedit:2,run:[0,15,9,14],reach:14,usag:[8,1,2,7,11,12,14],rue:5,step:[15,4,7,9,14,2,16],prerequisit:0,simpler:2,chapter:9,faith:5,about:4,actual:9,usa:5,incorpor:6,commun:[6,1,7,16],meaning:4,simul:[6,0,2,4,14],includ:[15,16,4],dialog:[15,3,4,13,2,16],adlinktech_usa:5,disabl:4,blockset:4,subsystem:13,busselector:16,own:[11,2],consid:9,opensplic:[0,1,2,5,9,10],devic:[15,13,16],"float":10,orsai:5,automat:6,down:[16,3,4],empti:[16,4],ensur:9,your:[16,9,4,10],manag:6,log:15,wai:16,libdcpsc99:4,support:[6,3,4,10],vallei:5,"long":[14,7,9,16,10],custom:[6,2,16],os_stdlib:4,width:[7,14],reli:[8,1,2,7,11,12,14],interfac:15,low:6,suit:5,machin:[15,4],participant_ent:4,analysi:6,creation:[7,14],schemaloc:3,form:10,getenv:[15,4],link:1,translat:9,shapes_demo_qo:16,line:[15,13,9,16,10],bug:[9,16],reset:3,made:5,tab:2,possibl:16,whether:14,flip:16,below:[10,3,4,9],idlpreprocguide_:9,those:10,rerun:9,embed:6,expect:16,shapes_read_model:16,constant:16,evalu:13,mask:13,"abstract":15,repres:[8,1,7,9,10,11,12,14],"char":[10,16,14],diagnost:4,exist:[7,3],file:2,inf:16,check:[7,4,14],coder:0,sourc:[7,16,4],when:[2,4,7,9,10,13,14,15,16],detail:9,invalid:15,field:[7,9,10,12,14,16],valid:[7,2,4,14],"0x40000000":15,test:[6,15],you:[6,16,9,4,10],architectur:6,stat:4,resolut:15,deselect:[16,14],multidimension:10,drag:16,amplitud:16,sql:14,algorithm:6,directori:[15,3,4,9,13,16],reliabl:6,dataread:14,portion:6,ignor:4,libjsig:15},objtypes:{},objnames:{},filenames:["index","domain","blocks","qos_provider","simulink_coder","contacts","introduction","writer","publisher","bus-dds","bus_to_dds_mapping","subscriber","topic","troubleshooting","reader","installation","tutorial"],titles:["DDS Simulink Guide","7. Domain Block","3. Vortex DDS Blocks","5. QoS Provider","13. Generating C code with Simulink Coder","16. Contacts & Notices","1. Introduction","10. Writer Block","8. Publisher Block","4. Simulink Bus to DDS Topic Mapping","15. Appendix A","9. Subscriber Block","6. Topic Block","14. Troubleshooting","11. Reader Block","2. Installation","12. Tutorial"],objects:{},titleterms:{all:16,code:4,shape:16,paramet:[8,1,7,11,12,14,16],struct:9,configur:15,add:[9,16],matlab:16,input:16,save:16,string:9,shapetyp:16,read:16,requir:[15,16],introduct:6,name:[9,16],troubleshoot:13,manual:10,shapes:16,provid:3,vortex:[2,9],output:16,button:16,domain:[1,16],set:[3,16],creator:16,blank:16,displai:16,sampl:[2,16],connect:16,idlpp:10,port:[8,2,7,11,12,14,16],librari:16,unbound:9,definit:[9,16],publish:[8,16],profil:[2,3],reader:[16,14],"new":16,attribut:9,run:[16,4],kei:16,workflow:10,gener:[16,9,4,10],"enum":9,prerequisit:4,valu:9,simul:16,filter:14,idl:[9,16],tutori:16,ospl:15,chang:9,block:[8,1,2,7,11,12,14,16],writer:[7,16],opensplic:15,color:16,linux:15,busel:16,instal:15,guid:0,open:16,select:16,size:9,from:[9,16],system:15,start:16,window:[15,16],editor:[9,16,10],subscrib:11,type:10,toggl:16,option:[2,16],notic:5,selector:16,appendix:10,known:3,tab:[8,1,7,11,12,14],"default":9,setup:[15,16],properti:16,maximum:9,descriptor:10,limit:[3,9],"export":16,browser:16,overrid:9,file:[3,16,9],creat:16,indic:0,topic:[12,9,16],explor:16,tabl:0,simulink:[0,2,3,4,6,9,10,15,16],built:4,idlimportsl:9,write:16,exampl:15,prepar:4,map:[9,10],sequenc:9,object:16,coder:4,data:[7,10,16,14],off:16,contact:5,command:16,time:2,model:[16,10,4]}}) \ No newline at end of file diff --git a/docs/html/DDSSimulinkGuide/simulink_coder.html b/docs/html/DDSSimulinkGuide/simulink_coder.html new file mode 100644 index 000000000..1f77d6b5c --- /dev/null +++ b/docs/html/DDSSimulinkGuide/simulink_coder.html @@ -0,0 +1,206 @@ + + + + + + + + 13. Generating C code with Simulink Coder — The Vortex OpenSplice Simulink Guide + + + + + + + + + + + + + + + +
    +
    +
    +
    + + + + +
    +
    +
    +
    +
    + +

    Table Of Contents

    + + +

    Previous topic

    +

    12. Tutorial

    +

    Next topic

    +

    14. Troubleshooting

    +

    This Page

    + + + +
    +
    +
    +
    + + + + \ No newline at end of file diff --git a/docs/html/DDSSimulinkGuide/subscriber.html b/docs/html/DDSSimulinkGuide/subscriber.html new file mode 100644 index 000000000..d25f18653 --- /dev/null +++ b/docs/html/DDSSimulinkGuide/subscriber.html @@ -0,0 +1,179 @@ + + + + + + + + 9. Subscriber Block — The Vortex OpenSplice Simulink Guide + + + + + + + + + + + + + + + +
    +
    +
    +
    + +
    +

    9. Subscriber Block¶

    +

    The Subscriber block represents a DDS subscriber entity.

    +

    In DDS, a subscriber is “an object responsible for receiving published data and making it available to the receiving application. It may receive and dispatch data of different specified types.”

    +

    This block is optional on a DDS Simulink model diagram. If it is not present on a model diagram, each reader will create its own default subscriber.

    +
    +DDS Subscriber Block +
    + +++++++ + + + + + + + + + + + + + + + + + + + + + + +
    Port TypeOptionalNameDescriptionOutput consumed by
    InputyesppDDS Domain Participant +entity instance 
    OutputnopsubDDS Subscriber entity +instanceReader
    +
    +

    9.1. Subscriber Block Parameters¶

    +
    +Subscriber Block Parameters +
    +
    +

    9.1.1. Ports Tab¶

    +

    The Ports tab allows the user to toggle on or off optional ports.

    +
    +
    +

    9.1.2. QoS Tab¶

    +

    The QoS tab is used to set the QoS profile. By default, the OSPL default profile is used.

    +

    In DDS - The Data-Distribution Service (DDS) relies on the usage of QoS. A QoS (Quality of Service) is a set of characteristics that controls some aspect of the behavior of the DDS Service.

    +

    Each DDS block has an associated QoS profile. By default, the OSPL default profile is used. An XML file that specifies QoS profiles can be used to set the QoS of a DDS block.

    +
    +
    +
    + + +
    +
    +
    +
    +
    + +

    Table Of Contents

    + + +

    Previous topic

    +

    8. Publisher Block

    +

    Next topic

    +

    10. Writer Block

    +

    This Page

    + + + +
    +
    +
    +
    + + + + \ No newline at end of file diff --git a/docs/html/DDSSimulinkGuide/topic.html b/docs/html/DDSSimulinkGuide/topic.html new file mode 100644 index 000000000..7e214a604 --- /dev/null +++ b/docs/html/DDSSimulinkGuide/topic.html @@ -0,0 +1,183 @@ + + + + + + + + 6. Topic Block — The Vortex OpenSplice Simulink Guide + + + + + + + + + + + + + + + +
    +
    +
    +
    + +
    +

    6. Topic Block¶

    +

    The topic block represents a DDS topic type. The DDS topic corresponds to a single data type. In DDS, data is distributed by publishing and subscribing topic data samples.

    +

    For a DDS Topic type definition, a corresponding BUS should be defined in the MATLAB workspace. The name of the BUS and the fields and field types should correspond to the DDS topic IDL definition.

    +

    In Simulink, a BUS definition can be used as an input or output signal of the Simulink building blocks.

    +
    +DDS Topic Block +
    + +++++++ + + + + + + + + + + + + + + + + + + + + + + +
    Port TypeOptionalNameDescriptionOutput consumed by
    InputyesppDDS Domain Participant +entity instance 
    OutputnotopicDDS Topic entity instanceWriter, Reader
    +
    +

    6.1. Topic Block Parameters¶

    +
    +Topic Block Parameters +
    +
    +

    6.1.1. Topic Tab¶

    +

    The output port named topic, needs to be configured by the user. No defaults are provided. To configure the topic output port, edit the required parameters in the Block Parameters / Topic tab. The following topic parameters must be specified: Bus Type and Topic Name.

    +
    +
    +

    6.1.2. Ports Tab¶

    +

    The Ports tab allows the user to toggle on or off optional ports.

    +
    +
    +

    6.1.3. QoS Tab¶

    +

    The QoS tab is used to set the QoS profile. By default, the OSPL default profile is used.

    +

    In DDS - The Data-Distribution Service (DDS) relies on the usage of QoS. A QoS (Quality of Service) is a set of characteristics that controls some aspect of the behavior of the DDS Service.

    +

    Each DDS block has an associated QoS profile. By default, the OSPL default profile is used. An XML file that specifies QoS profiles can be used to set the QoS of a DDS block.

    +
    +
    +
    + + +
    +
    +
    +
    +
    + +

    Table Of Contents

    + + +

    Previous topic

    +

    5. QoS Provider

    +

    Next topic

    +

    7. Domain Block

    +

    This Page

    + + + +
    +
    +
    +
    + + + + \ No newline at end of file diff --git a/docs/html/DDSSimulinkGuide/troubleshooting.html b/docs/html/DDSSimulinkGuide/troubleshooting.html new file mode 100644 index 000000000..f273b9059 --- /dev/null +++ b/docs/html/DDSSimulinkGuide/troubleshooting.html @@ -0,0 +1,137 @@ + + + + + + + + 14. Troubleshooting — The Vortex OpenSplice Simulink Guide + + + + + + + + + + + + + + + +
    +
    +
    +
    + +
    +

    14. Troubleshooting¶

    +

    When double clicking on a DDS block to view the block parameters, an error dialog is shown with the message: Error evaluating ‘MaskDialog’ callback of SubSystem block (mask).

    +

    Cause: The OSPL environment variables have not been setup correctly.

    +

    Solution: Open a command shell and run the script to setup OSPL environment variables.

    +
    +

    Linux

    +
      +
    • Open a Linux terminal.

      +
    • +
    • Navigate to directory containing release.com file.

      +

      /INSTALLDIR/ADLINK/Vortex_v2/Device/VortexOpenSplice/6.8.x/HDE/x86_64.linux

      +
    • +
    • Run release.com. (Type in “. release.com†at command line.)

      +
    • +
    +

    Windows

    +
      +
    • Open a command prompt.

      +
    • +
    • Navigate to directory containing release.bat file.

      +

      INSTALLDIR/ADLINK/Vortex_v2/Device/VortexOpenSplice/6.8.x/HDE/x86_64.win64

      +
    • +
    • Run release.bat. (Type in “release.bat†at command line.)

      +
    • +
    +
    +
    + + +
    +
    +
    +
    +
    + +

    Previous topic

    +

    13. Generating C code with Simulink Coder

    +

    Next topic

    +

    15. Appendix A

    +

    This Page

    + + + +
    +
    +
    +
    + + + + \ No newline at end of file diff --git a/docs/html/DDSSimulinkGuide/tutorial.html b/docs/html/DDSSimulinkGuide/tutorial.html new file mode 100644 index 000000000..daf39d88c --- /dev/null +++ b/docs/html/DDSSimulinkGuide/tutorial.html @@ -0,0 +1,827 @@ + + + + + + + + 12. Tutorial — The Vortex OpenSplice Simulink Guide + + + + + + + + + + + + + + + +
    +
    +
    +
    + +
    +

    12. Tutorial¶

    +

    To demonstrate the capabilities of the DDS Simulink Integration, this tutorial will create two Simulink models. One model will write DDS samples, and the second model will read the DDS samples.

    +

    Both models will be run simultaneously, and use a DDS system for communication.

    +

    A Simulink bus named ShapeType is created as part of this tutorial. The bus can be created by either using the Simulink bus editor, or by generation from an IDL file. +Both options are covered in this tutorial.

    + +
    +

    12.2. Create ShapeType Using IDL¶

    +

    The public Vortex.idlImportSl function can be called to generate Simulink bus definitions from an IDL file. +The generated bus definitions are inserted into the ‘Design Data’ section of a data dictionary.

    +
    +
    From the Simulink documentation -
    +
    “A data dictionary is a persistent repository of data that are relevant to your model. You can also use the base workspace to store design data that are used by your model during simulation.”
    +
    +

    The data dictionary can then be referenced from your models.

    +
    +

    12.2.1. Create IDL File¶

    +

    Create an IDL file to define your ShapeType topic structure. For this tutorial we will name the file ShapeType.idl.

    +
     struct ShapeType {
    +   string color; //@Key
    +   long x;
    +   long y;
    +   long shapesize;
    + };
    +#pragma keylist ShapeType color
    +
    +
    +

    IMPORTANT NOTE: The IDL file has to have a blank line after the pragma keylist declaration. (known bug)

    +
    + +
    +

    12.2.3. Model Explorer¶

    +

    To make use of the bus definitions generated into the data dictionary, Simulink models can specify design data using the Model Explorer.

    +
    +Model Explorer Design Data +
    +
    +
    +
    +

    12.3. Shapes Write Model¶

    +

    This section outlines how to create a new DDS Simulink model that will write sample data for the topic type ShapeType.

    +

    Although not necessary, this model will use the optional Domain and Publisher blocks.

    + + +
    +
    +

    12.4. Shapes Read Model¶

    +
    +

    12.4.1. Create a new Simulink model¶

    +

    This section outlines how to create a new DDS Simulink model that will read and display sample data for the topic type ShapeType.

    +

    In this model example, we will be making use of many of the defaults, so the optional blocks will not be included in this model.

    +
    +

    12.4.1.1. Start Simulink¶

    +
    +Start Simulink +
    +
    +
    +

    12.4.1.2. Add a new blank model¶

    +
    +Start Add new blank model +
    +
    +
    +

    12.4.1.3. Save As...¶

    +
      +
    • Save the model as “shapes_read_model.slxâ€.
    • +
    +
    +
    +

    12.4.1.4. Model Settings¶

    +
      +
    • Open Model Configuration Parameters dialog, by selecting menu Simulation / Model Configuration Parameters.
    • +
    • Set the simulation stop time to inf. (Note: “Specify inf to run a simulation or generated program until you explicitly pause or stop it.†Simulink Help documentation)
    • +
    • Set the Solver Type to Fixed-step.
    • +
    +
    +Setup Read Model +
    +
    +
    +
    +

    12.4.2. Add Simulink DDS Blocks¶

    +
    +

    12.4.2.1. Open the Simulink Library Browser¶

    +
    +Vortex DDS Library +
    +
    +
    +

    12.4.2.2. Add all required blocks (Topic and Reader)¶

    +
    +
    Using the Simulink Library Browser drag the following block types onto your diagram:
    +
      +
    • 1 Topic
    • +
    • 1 Reader
    • +
    +
    +
    +

    Note: For this example model, we will be using the block defaults for the Domain and Subscriber, therefore they will not be included on the model.

    +

    To set a block’s parameters, double click on the block to bring up the Block Parameters dialog.

    +
    +Add Blocks +
    +
    +
    +

    12.4.2.3. Toggle off optional ports¶

    +
      +
    • Double click on the Topic to bring up the Block Parameters dialog.
    • +
    • In the Topic Ports tab deselect the Participant port.
    • +
    • Double click on the Reader to bring up the Block Parameters dialog.
    • +
    • In the Reader Ports tab deselect the Subscriber, Reader, Status, Info and Samples Read ports.
    • +
    +
    +
    +

    12.4.2.4. Set Topic Block Parameters¶

    +
      +
    • Double click on the Topic to bring up the Block Parameters dialog, select Topic tab.

      +
    • +
    • +
      Set the Bus Type: ShapeType bus
      +

      Note: If the ShapeType bus is not displayed, select Refresh data types from dropdown list.

      +
      +
      +
    • +
    • Set the Topic Name to: Circle.

      +
    • +
    +
    +Topic Block Parameters +
    +
      +
    • Select the QoS tab.

      +
    • +
    • +
      Set the QoS file to : Shapes_Demo_QoS.xml.
      +
      +
      INSTALLDIR/ADLINK/Vortex_v2/Device/VortexOpenSplice/6.8.x/HDE/x86_64.linux/tools/matlab/
      +

      examples/simulink/dds_reader_writer_model/Shapes_Demo_QoS.xml

      +
      +
      +
      +
      +
    • +
    +
    +
    +

    12.4.2.5. Set Reader Block Parameters¶

    +
      +
    • Double click on the Reader block to edit the Block Parameters. Set the Input Data Type to the bus: ShapeType.

      +
    • +
    • Select the QoS tab.

      +
    • +
    • +
      Set the QoS file to : Shapes_Demo_QoS.xml.
      +
      +
      INSTALLDIR/ADLINK/Vortex_v2/Device/VortexOpenSplice/6.8.x/HDE/x86_64.linux/tools/matlab/
      +

      examples/simulink/dds_reader_writer_model/Shapes_Demo_QoS.xml

      +
      +
      +
      +
      +
    • +
    +
    +
    +

    12.4.2.6. Connect Topic and Reader¶

    +
      +
    • Connect the Topic block topic output to the Reader block topic input.
    • +
    +
    +Connect Topic and Reader +
    +
    +
    +

    12.4.2.7. Add a Bus Selector to read and display sample data¶

    +

    To read and display sample data, we will add a Simulink / Signal Routing / Bus Selector block to our diagram.

    +
    +
    +

    12.4.2.8. Set Bus Selector Block Parameters¶

    +

    Specify the output signals we would like to display in our simulation. For this example, we will display all the ShapeType BUS signals in the running simulation.

    +
      +
    • Connect the Reader data output to the Bus Selector.
    • +
    • Double click on the Bus Selector block to edit the Block Parameters.
    • +
    • Add all the signals in the bus to the Selected signals.
    • +
    +
    +Bus Selector Block Parameters +
    +
    +
    +

    12.4.2.9. Add Bus Selector outputs¶

    +

    For demonstration purposes, we will output the bus signals using 2 Simulink Display blocks and an XY Graph.

    +

    Note: To change the positioning of block ports, you can use the Rotate & Flip block menu item, accessible by right clicking on a block.

    +
      +
    • Drag 2 Simulink / Sinks / Display blocks onto the diagram.

      +
    • +
    • +
      Connect the Display blocks to the Bus Selector output signals.
      +
        +
      • Connect the Bus Selector color output signal to a Display block.
      • +
      • Connect the Bus Selector shapesize output signal to a Display block.
      • +
      +
      +
      +
    • +
    +

    Note: Default Display block settings used.

    +
    +Bus Selector Outputs +
    +
      +
    • Drag Simulink / Sinks / XY Graph block onto diagram

      +
    • +
    • Connect the BusSelector x and y outputs to the XY Graph block.

      +
    • +
    • +
      Set the Block Parameters on the XY Graph:
      +

      X-min: 0 +X-max: 400 +Y-min: 0 +Y-max: 400

      +
      +
      +
    • +
    +
    +Bus Selector XY Graph +
    +

    Save your model!!! The model is now complete!

    +
    +
    +
    +
    +

    12.5. Running Simulations¶

    +

    We now have two Simulink models. We will run both models and see that data samples are being written by one model and read be the second model.

    +
    +

    12.5.1. Setup Write Model¶

    +
      +
    1. Open shapes_write_model.slx.
    2. +
    3. Select menu item Simulation / Update Diagram to diagnose any possible model problems.
    4. +
    5. Fix any issues.
    6. +
    +
    +
    +

    12.5.2. Setup Read Model¶

    +
      +
    1. Open shapes_read_model.slx.
    2. +
    3. Select menu item Simulation / Update Diagram to diagnose any possible model problems.
    4. +
    5. Fix any issues.
    6. +
    +
    +
    +

    12.5.3. Run Simulations¶

    +
      +
    1. Position models side by side.
    2. +
    3. Start the read model simulation.
    4. +
    5. Start the write model simulation.
    6. +
    7. Expected: The write model will write samples, that are received by the read model and displayed in that model’s XY Graph and Display blocks.
    8. +
    9. The write model will run to completion. The read model needs to be stopped manually.
    10. +
    +
    +Run Simulations +
    +

    Run Results

    +
    +Run results +
    +
    +
    +
    + + +
    +
    +
    +
    +
    + +

    Table Of Contents

    + + +

    Previous topic

    +

    11. Reader Block

    +

    Next topic

    +

    13. Generating C code with Simulink Coder

    +

    This Page

    + + + +
    +
    +
    +
    + + + + \ No newline at end of file diff --git a/docs/html/DDSSimulinkGuide/writer.html b/docs/html/DDSSimulinkGuide/writer.html new file mode 100644 index 000000000..d29e71a78 --- /dev/null +++ b/docs/html/DDSSimulinkGuide/writer.html @@ -0,0 +1,216 @@ + + + + + + + + 10. Writer Block — The Vortex OpenSplice Simulink Guide + + + + + + + + + + + + + + + +
    +
    +
    +
    + +
    +

    10. Writer Block¶

    +

    The Writer block represents a DDS data writer entity.

    +

    In DDS - “The DataWriter is the object the application must use to communicate to a publisher the existence and value of data-objects of a given type.”

    +
    +DDS Writer Block +
    + +++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Port TypeOptionalNameDescriptionOutput consumed by
    InputyesppubDDS Publisher +entity instance 
    InputnotopicDDS Topic entity instance 
    InputnodataBUS 
    Inputyesaction0 write, +1 dispose, +2 write dispose, +3 no operation 
    Outputyesstatus0 for successful writer +creation 
    Outputyessamples writtenNumber of samples writtenUser
    +
    +

    10.1. Writer Block Parameters¶

    +
    +Writer Block Parameters +
    +
    +

    10.1.1. Data Tab¶

    +

    The Data tab is used to set the input data type (BUS) for the data input port and the bus width.

    +

    The bus width is the maximum number of samples that can be written per block step. +The user must configure the source blocks that feed the Writer’s data port so that it produces an array of the right size.

    +

    Valid values for the bus width are: integers >= 1.

    +

    The Reader Available field in the Wait for section is used for specifying if the Writer should wait for the Reader to become available. +The associated Timeout field is to specify how long (in seconds) the Writer should wait for the Reader to become available.

    +

    The Write after timeout field can only be enabled when the Reader Available field is checked. It specifies if the Writer should write after the Wait for Reader Available timeout.

    +
    +
    +

    10.1.2. Ports Tab¶

    +

    The Ports tab allows the user to toggle on or off optional ports.

    +
    +
    +

    10.1.3. QoS Tab¶

    +

    The QoS tab is used to set the QoS profile. By default, the OSPL default profile is used.

    +

    In DDS - The Data-Distribution Service (DDS) relies on the usage of QoS. A QoS (Quality of Service) is a set of characteristics that controls some aspect of the behavior of the DDS Service.

    +

    Each DDS block has an associated QoS profile. By default, the OSPL default profile is used. An XML file that specifies QoS profiles can be used to set the QoS of a DDS block.

    +
    +
    +
    + + +
    +
    +
    +
    +
    + +

    Table Of Contents

    + + +

    Previous topic

    +

    9. Subscriber Block

    +

    Next topic

    +

    11. Reader Block

    +

    This Page

    + + + +
    +
    +
    +
    + + + + \ No newline at end of file diff --git a/docs/html/DDSTutorial/_sources/appendix-A.txt b/docs/html/DDSTutorial/_sources/appendix-A.txt index adfe0ead6..7b963bcac 100644 --- a/docs/html/DDSTutorial/_sources/appendix-A.txt +++ b/docs/html/DDSTutorial/_sources/appendix-A.txt @@ -27,16 +27,16 @@ Getting a DDS Implementation At the time of writing, the only open source DDS implementation that supports the new ISO C++ API is *Vortex OpenSplice*, which -is freely available at http://www.opensplice.org. +is freely available at http://ist.adlinktech.com/dds-community. Commercial versions of Vortex OpenSplice and Vortex Lite are also available -which support the ISO C++ API from http://prismtech.com/vortex. +which support the ISO C++ API from http://vortex.adlinktech.com. C++11 Considerations ==================== Although some of the examples in this Tutorial take advantage of C++11, -the new C++ API can also be used with C++03 compilers. That said, if +the new C++ API can also be used with C++03 compilers. That said, if you have the opportunity to use a C++11 compiler, then there are some additional aspects of the language that can be enabled. diff --git a/docs/html/DDSTutorial/_sources/contacts.txt b/docs/html/DDSTutorial/_sources/contacts.txt index 7f7869976..e5c52db85 100644 --- a/docs/html/DDSTutorial/_sources/contacts.txt +++ b/docs/html/DDSTutorial/_sources/contacts.txt @@ -1,48 +1,57 @@ -.. _`Contacts & Notices`: - -################## -Contacts & Notices -################## - -******** -Contacts -******** - -| **PrismTech Corporation** -| 400 TradeCenter -| Suite 5900 -| Woburn, MA -| 01801 -| USA -| Tel: +1 781 569 5819 - -| **PrismTech Limited** -| PrismTech House -| 5th Avenue Business Park -| Gateshead -| NE11 0NG -| UK -| Tel: +44 (0)191 497 9900 - -| **PrismTech France** -| 28 rue Jean Rostand -| 91400 Orsay -| France -| Tel: +33 (1) 69 015354 - - -Web: http://www.prismtech.com - -E-mail: \info@prismtech.com - -******* -Notices -******* - -*This work is made available under a Creative Commons -Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license* -https://creativecommons.org/licenses/by-sa/4.0/legalcode - -The information contained in this document is subject to change without notice and is made available in good faith without liability on the part of PrismTech Limited or PrismTech Corporation. -All trademarks acknowledged. - +.. _`Contacts & Notices`: + +################## +Contacts & Notices +################## + +******** +Contacts +******** + +| **ADLINK Technology Corporation** +| 400 TradeCenter +| Suite 5900 +| Woburn, MA +| 01801 +| USA +| Tel: +1 781 569 5819 + +| **ADLINK Technology Limited** +| The Edge +| 5th Avenue +| Team Valley +| Gateshead +| NE11 0XA +| UK +| Tel: +44 (0)191 497 9900 + +| **ADLINK Technology SARL** +| 28 rue Jean Rostand +| 91400 Orsay +| France +| Tel: +33 (1) 69 015354 + + +Web: http://ist.adlinktech.com/ + +Contact: http://ist.adlinktech.com/ + +E-mail: \ist_info@adlinktech.com + +LinkedIn: https://www.linkedin.com/company/79111/ + +Twitter: https://twitter.com/ADLINKTech_usa + +Facebook: https://www.facebook.com/ADLINKTECH + +******* +Notices +******* + +*This work is made available under a Creative Commons +Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license* +https://creativecommons.org/licenses/by-sa/4.0/legalcode + +*This document may be reproduced in whole but not in part. The information contained in this +document is subject to change without notice and is made available in good faith without +liability on the part of ADLINK Technology Limited. All trademarks acknowledged.* diff --git a/docs/html/DDSTutorial/_sources/index.txt b/docs/html/DDSTutorial/_sources/index.txt index e187e2b7c..5dba8ef84 100644 --- a/docs/html/DDSTutorial/_sources/index.txt +++ b/docs/html/DDSTutorial/_sources/index.txt @@ -9,7 +9,7 @@ The Data Distribution Service Tutorial .. toctree:: :maxdepth: 4 :numbered: - + foundations topics-etc readandwrite @@ -18,8 +18,8 @@ The Data Distribution Service Tutorial acronyms biblio - contacts - + contacts + Indices and tables ================== diff --git a/docs/html/DDSTutorial/_sources/preface.txt b/docs/html/DDSTutorial/_sources/preface.txt index 469377c95..5b8e7e669 100644 --- a/docs/html/DDSTutorial/_sources/preface.txt +++ b/docs/html/DDSTutorial/_sources/preface.txt @@ -10,13 +10,13 @@ Preface About the DDS Tutorial ********************** -The *DDS Tutorial* is included with the OpenSplice DDS +The *DDS Tutorial* is included with the Vortex OpenSplice Documentation Set. This Guide is the starting point for anyone using, -developing or running applications with OpenSplice DDS. +developing or running applications with Vortex OpenSplice. *This DDS Tutorial contains:* -+ a general introduction to the ++ a general introduction to the Data Distibution Service (DDS) + descriptions of how to develop applications which @@ -24,7 +24,7 @@ developing or running applications with OpenSplice DDS. + *etc.* -*Intended Audience* +*Intended Audience* The *DDS Tutorial* is intended to be used by anyone who wishes to make use of a DDS product. @@ -35,24 +35,24 @@ wishes to make use of a DDS product. Conventions *********** -The icons shown below are used in PrismTech product documentation -to help readers to quickly identify information relevant to their -specific use of OpenSplice DDS. +The icons shown below are used in ADLINK product documentation +to help readers to quickly identify information relevant to their +specific use of Vortex OpenSplice. - ========= ================================================================== - *Icon* *Meaning* - ========= ================================================================== - |caution| Item of special significance or where caution needs to be taken. - |info| Item contains helpful hint or special information. - |windows| Information applies to Windows (*e.g.* XP, 2003, Windows 7) only. - |unix| Information applies to Unix-based systems (*e.g.* Solaris) only. - |linux| Information applies to Linux-based systems (*e.g.* Ubuntu) only. - |c| C language specific. - |cpp| C++ language specific. - |csharp| C# language specific. - |java| Java language specific. - ========= ================================================================== + ========= ================================================================== + *Icon* *Meaning* + ========= ================================================================== + |caution| Item of special significance or where caution needs to be taken. + |info| Item contains helpful hint or special information. + |windows| Information applies to Windows (*e.g.* XP, 2003, Windows 7) only. + |unix| Information applies to Unix-based systems (*e.g.* Solaris) only. + |linux| Information applies to Linux-based systems (*e.g.* Ubuntu) only. + |c| C language specific. + |cpp| C++ language specific. + |csharp| C# language specific. + |java| Java language specific. + ========= ================================================================== @@ -76,4 +76,3 @@ specific use of OpenSplice DDS. .. |java| image:: ./images/icon-java.* :height: 6mm - \ No newline at end of file diff --git a/docs/html/DDSTutorial/_sources/topics-etc.txt b/docs/html/DDSTutorial/_sources/topics-etc.txt index b053d762a..6a5ce4f05 100644 --- a/docs/html/DDSTutorial/_sources/topics-etc.txt +++ b/docs/html/DDSTutorial/_sources/topics-etc.txt @@ -6,7 +6,7 @@ Topics, Domains and Partitions The previous chapter introduced the basic concepts of DDS and walked -through the steps required to write a simple Pub/Sub application. +through the steps required to write a simple Pub/Sub application. This chapter will look at DDS in more depth, starting with data management. @@ -28,7 +28,7 @@ Operating System (OS), so it defines its type system along with a space- and time-efficient binary encoding for its types. Different syntaxes can be used to express DDS topic types, such as :ref:`IDL `, :ref:`XML `. -Some vendors, such as PrismTech, also support +Some vendors, such as ADLINK, also support Google Protocol Buffers. This Tutorial will focus on the subset of IDL that can be used to @@ -77,11 +77,11 @@ essentially what you would expect, with just one exception: the ``int`` type is not there! This should not be a problem since the IDL integral types ``short``, ``long`` and ``long long`` are equivalent to the C99 ``int16_t``, ``int32_t`` and ``int64_t``. -And what is more: in contrast to the ``int`` type, which can have a different -footprint on different platforms, each of these types has specified exactly what -its footprint is. +And what is more: in contrast to the ``int`` type, which can have a different +footprint on different platforms, each of these types has specified exactly what +its footprint is. + - .. _`IDL Template Types`: | **IDL Template Types** @@ -99,22 +99,22 @@ its footprint is. | | | sequence mtseq; | | | | sequence$ mtseq10;| +--------------------------------+----------------------------------+ - - - -In the table `IDL Template Types`_, the ``string`` can be -parameterized only with respect to their maximum length, while -the ``sequence`` type can be parameterized with respect to both its -maximum length and its contained type. -The ``sequence`` type abstracts a homogeneous random access container, pretty -much like the ``std::vector`` in C++ or ``java.util.Vector`` in Java. - -Finally, it is important to point out that when the maximum length is -not provided the type is assumed to have an unbounded length, meaning -that the middleware will allocate as much memory as necessary to store -the values that the application provides. - -The table `IDL Constructed Types`_ shows that DDS supports three different + + + +In the table `IDL Template Types`_, the ``string`` can be +parameterized only with respect to their maximum length, while +the ``sequence`` type can be parameterized with respect to both its +maximum length and its contained type. +The ``sequence`` type abstracts a homogeneous random access container, pretty +much like the ``std::vector`` in C++ or ``java.util.Vector`` in Java. + +Finally, it is important to point out that when the maximum length is +not provided the type is assumed to have an unbounded length, meaning +that the middleware will allocate as much memory as necessary to store +the values that the application provides. + +The table `IDL Constructed Types`_ shows that DDS supports three different kinds of IDL constructed types: ``enum``, ``struct``, and ``union``. @@ -145,13 +145,13 @@ kinds of IDL constructed types: ``enum``, ``struct``, and ``union``. -It should be clear from this that a Topic type is a ``struct`` that can +It should be clear from this that a Topic type is a ``struct`` that can contain (as fields) nested structures, unions, enumerations, and template types, as well as primitive types. In addition, it is possible to define multi-dimensional arrays of any DDS-supported or user-defined type. To tie things together, there are language-specific mappings from the -IDL types described above to mainstream programming languages such as +IDL types described above to mainstream programming languages such as C++, Java, and C#. @@ -165,10 +165,10 @@ Each Topic comes with an associated key-set. This key-set might be empty or it can include an arbitrary number of attributes defined by the Topic Type. There are no limitations on the number, kind, or level of nesting, of attributes used to establish the key. There are some limitations to -its kind though: a key should either be a primitive type (see table -`Primitive Types`_), an enumeration or a string. A key cannot be constructed -type (although it may consist of one or more members of an embedded constructed -type), an array or a sequence of any type. +its kind though: a key should either be a primitive type (see table +`Primitive Types`_), an enumeration or a string. A key cannot be constructed +type (although it may consist of one or more members of an embedded constructed +type), an array or a sequence of any type. .. _`Keyed and Keyless Topics`: @@ -187,8 +187,8 @@ monitoring system), it is possible to define a keyless variant of the ``TempSensorType`` defined in the :ref:`Foundations ` chapter. -`Keyed and Keyless Topics`_ shows the ``TempSensorType`` with the -``id`` attribute defined as its key, along with the ``KeylessTempSensorType`` +`Keyed and Keyless Topics`_ shows the ``TempSensorType`` with the +``id`` attribute defined as its key, along with the ``KeylessTempSensorType`` showing off an empty key-set as defined in its ``#pragma keylist`` directive. If two topics associated with the types declared in @@ -258,7 +258,7 @@ associated with the singleton instance, as shown in If we write the same samples for the ``TempSensorTopic``, the end-result is quite different. The two samples written in the code fragment below -have two different ``id`` values, respectively ``1`` and ``2``; +have two different ``id`` values, respectively ``1`` and ``2``; they are referring to two different instances. .. literalinclude:: ./code/isocpp2/ch2/tspub.cpp @@ -281,7 +281,7 @@ one queue for each instance. In summary, Topics should be thought of as classes in an object-oriented -language, and each unique key-value identifies an instance. +language, and each unique key-value identifies an instance. The life-cycle of topic instances is managed by DDS and to each topic instance are allocated memory resources; think of it as a queue on the reader side. Keys identify specific data streams @@ -294,14 +294,14 @@ track the lifecycle of the sensor by tracking the lifecycle of its associated instance. It is possible to detect when a new sensor is added into the system, because it introduces a new instance; it is possible to detect when a sensor has failed, because DDS can report -when there are no more writers for a specific instance. -It is even possible to detect when a sensor has crashed and then recovered +when there are no more writers for a specific instance. +It is even possible to detect when a sensor has crashed and then recovered thanks to information about state transitions that is provided by DDS. Finally, before moving on from DDS instances, it is emphasized that -DDS subscriptions concern *Topics*. Thus *a subscriber receives* +DDS subscriptions concern *Topics*. Thus *a subscriber receives* **all** *of the instances produced for that topic*. In some cases -this is not desirable and some scoping actions are necessary. +this is not desirable and some scoping actions are necessary. Scoping is discussed in the next section. @@ -343,11 +343,11 @@ The mechanism provided by DDS for joining a partition is very flexible as a publisher or a subscriber can join by providing its full name, such as ``SensorDataPartition``, or it can join all the partitions that match a regular expression, such as ``Sens*`` or ``*Data*``. Supported regular -expressions are the same as those accepted by the POSIX ``fnmatch`` +expressions are the same as those accepted by the POSIX ``fnmatch`` function (see :ref:`POSIX fmatch `). To recap: *partitions provide a way of* **scoping** *information*. -This scoping mechanism can be used to organize topics into different +This scoping mechanism can be used to organize topics into different coherent sets. Partitions can also be used to segregate topic instances. *Instance @@ -371,9 +371,9 @@ partitions for all of the rooms at the first floor in building 1. In a nutshell, *partitions* can be used to *scope* information, and *naming conventions* (such as those used for the example temperature control -applications) can be used to *emulate hierarchical organization of data* -starting from flat partitions. Using the same technique it is possible to -slice and access data across different dimensions or views, depending on the +applications) can be used to *emulate hierarchical organization of data* +starting from flat partitions. Using the same technique it is possible to +slice and access data across different dimensions or views, depending on the needs of the application. .. _`Content Filtering`: @@ -383,7 +383,7 @@ Content Filtering ***************** Domains and Partitions are useful mechanisms for the *structural* -organization of data, but what if it is neccessary to control the data +organization of data, but what if it is neccessary to control the data received based on its *content*? Content Filtering enables the creation of topics that constrain the values that their instances might take. @@ -476,11 +476,11 @@ This chapter has covered the most important aspects of data management in DDS: topics-types and topic instances, and the various mechanisms provided by DDS for scoping information. -Information can be structurally organized by means of domains and +Information can be structurally organized by means of domains and partitions, and special views can be created using content-filtered -topics and query conditions. +topics and query conditions. -It is recommended again that the reader compiles and runs the examples +It is recommended again that the reader compiles and runs the examples and experiments with the programs developed so far. - + diff --git a/docs/html/DDSTutorial/acronyms.html b/docs/html/DDSTutorial/acronyms.html index 6dff60999..d8738a912 100644 --- a/docs/html/DDSTutorial/acronyms.html +++ b/docs/html/DDSTutorial/acronyms.html @@ -214,7 +214,7 @@

    Navigation

    \ No newline at end of file diff --git a/docs/html/DDSTutorial/appendix-A.html b/docs/html/DDSTutorial/appendix-A.html index 9d6c83d89..b43797775 100644 --- a/docs/html/DDSTutorial/appendix-A.html +++ b/docs/html/DDSTutorial/appendix-A.html @@ -64,9 +64,9 @@

    5.1.1. Examples Source Code¶

    At the time of writing, the only open source DDS implementation that supports the new ISO C++ API is Vortex OpenSplice, which -is freely available at http://www.opensplice.org.

    +is freely available at http://ist.adlinktech.com/dds-community.

    Commercial versions of Vortex OpenSplice and Vortex Lite are also available -which support the ISO C++ API from http://prismtech.com/vortex.

    +which support the ISO C++ API from http://vortex.adlinktech.com.

    5.1.3. C++11 Considerations¶

    @@ -144,7 +144,7 @@

    Navigation

    \ No newline at end of file diff --git a/docs/html/DDSTutorial/biblio.html b/docs/html/DDSTutorial/biblio.html index 736830f7d..d57007763 100644 --- a/docs/html/DDSTutorial/biblio.html +++ b/docs/html/DDSTutorial/biblio.html @@ -257,7 +257,7 @@

    Navigation

    \ No newline at end of file diff --git a/docs/html/DDSTutorial/contacts.html b/docs/html/DDSTutorial/contacts.html index ec00d8370..65c29a044 100644 --- a/docs/html/DDSTutorial/contacts.html +++ b/docs/html/DDSTutorial/contacts.html @@ -50,7 +50,7 @@

    Navigation

    8.1. Contacts¶

    -
    PrismTech Corporation
    +
    ADLINK Technology Corporation
    400 TradeCenter
    Suite 5900
    Woburn, MA
    @@ -59,31 +59,37 @@

    8.1. ContactsTel: +1 781 569 5819

    -
    PrismTech Limited
    -
    PrismTech House
    -
    5th Avenue Business Park
    +
    ADLINK Technology Limited
    +
    The Edge
    +
    5th Avenue
    +
    Team Valley
    Gateshead
    -
    NE11 0NG
    +
    NE11 0XA
    UK
    Tel: +44 (0)191 497 9900
    -
    PrismTech France
    +
    ADLINK Technology SARL
    28 rue Jean Rostand
    91400 Orsay
    France
    Tel: +33 (1) 69 015354
    -

    Web: http://www.prismtech.com

    -

    E-mail: info@prismtech.com

    +

    Web: http://ist.adlinktech.com/

    +

    Contact: http://ist.adlinktech.com/

    +

    E-mail: ist_info@adlinktech.com

    +

    LinkedIn: https://www.linkedin.com/company/79111/

    +

    Twitter: https://twitter.com/ADLINKTech_usa

    +

    Facebook: https://www.facebook.com/ADLINKTECH

    8.2. Notices¶

    This work is made available under a Creative Commons Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license https://creativecommons.org/licenses/by-sa/4.0/legalcode

    -

    The information contained in this document is subject to change without notice and is made available in good faith without liability on the part of PrismTech Limited or PrismTech Corporation. -All trademarks acknowledged.

    +

    This document may be reproduced in whole but not in part. The information contained in this +document is subject to change without notice and is made available in good faith without +liability on the part of ADLINK Technology Limited. All trademarks acknowledged.

    @@ -143,7 +149,7 @@

    Navigation

    \ No newline at end of file diff --git a/docs/html/DDSTutorial/foundations.html b/docs/html/DDSTutorial/foundations.html index df51164ae..1e2c5c8c6 100644 --- a/docs/html/DDSTutorial/foundations.html +++ b/docs/html/DDSTutorial/foundations.html @@ -454,7 +454,7 @@

    Navigation

    \ No newline at end of file diff --git a/docs/html/DDSTutorial/foundations_2.html b/docs/html/DDSTutorial/foundations_2.html index c42aa38a0..c23363253 100644 --- a/docs/html/DDSTutorial/foundations_2.html +++ b/docs/html/DDSTutorial/foundations_2.html @@ -429,7 +429,7 @@

    Navigation

    \ No newline at end of file diff --git a/docs/html/DDSTutorial/genindex.html b/docs/html/DDSTutorial/genindex.html index 63905fbdf..5d1865050 100644 --- a/docs/html/DDSTutorial/genindex.html +++ b/docs/html/DDSTutorial/genindex.html @@ -88,7 +88,7 @@

    Navigation

    \ No newline at end of file diff --git a/docs/html/DDSTutorial/index.html b/docs/html/DDSTutorial/index.html index 5c1e2b59f..e277c12f1 100644 --- a/docs/html/DDSTutorial/index.html +++ b/docs/html/DDSTutorial/index.html @@ -201,7 +201,7 @@

    Navigation

    \ No newline at end of file diff --git a/docs/html/DDSTutorial/preface.html b/docs/html/DDSTutorial/preface.html index f92c1dd2a..e44d4b6cb 100644 --- a/docs/html/DDSTutorial/preface.html +++ b/docs/html/DDSTutorial/preface.html @@ -45,9 +45,9 @@

    Navigation

    Preface¶

    About the DDS Tutorial¶

    -

    The DDS Tutorial is included with the OpenSplice DDS +

    The DDS Tutorial is included with the Vortex OpenSplice Documentation Set. This Guide is the starting point for anyone using, -developing or running applications with OpenSplice DDS.

    +developing or running applications with Vortex OpenSplice.

    This DDS Tutorial contains:

    • a general introduction to the @@ -62,9 +62,9 @@

      About the DDS Tutorial

      Conventions¶

      -

      The icons shown below are used in PrismTech product documentation +

      The icons shown below are used in ADLINK product documentation to help readers to quickly identify information relevant to their -specific use of OpenSplice DDS.

      +specific use of Vortex OpenSplice.

      @@ -160,7 +160,7 @@

      Navigation

      \ No newline at end of file diff --git a/docs/html/DDSTutorial/qos.html b/docs/html/DDSTutorial/qos.html index 7ccd4f718..9ee4b9563 100644 --- a/docs/html/DDSTutorial/qos.html +++ b/docs/html/DDSTutorial/qos.html @@ -384,7 +384,7 @@

      Navigation

      \ No newline at end of file diff --git a/docs/html/DDSTutorial/readandwrite.html b/docs/html/DDSTutorial/readandwrite.html index ed49b870e..1ea739735 100644 --- a/docs/html/DDSTutorial/readandwrite.html +++ b/docs/html/DDSTutorial/readandwrite.html @@ -762,7 +762,7 @@

      Navigation

      \ No newline at end of file diff --git a/docs/html/DDSTutorial/search.html b/docs/html/DDSTutorial/search.html index 14595b750..af9857691 100644 --- a/docs/html/DDSTutorial/search.html +++ b/docs/html/DDSTutorial/search.html @@ -95,7 +95,7 @@

      Navigation

      \ No newline at end of file diff --git a/docs/html/DDSTutorial/searchindex.js b/docs/html/DDSTutorial/searchindex.js index e4252b41a..08469697a 100644 --- a/docs/html/DDSTutorial/searchindex.js +++ b/docs/html/DDSTutorial/searchindex.js @@ -1 +1 @@ -Search.setIndex({envversion:42,terms:{represent:[8,2,6],disr:6,concept:[4,8,1,2,9],forget:4,whatev:4,illustr:[4,8,1,2,9],queri:[4,8,1,2,6],global:6,all:[1,2,3,4,8,9,10],four:4,signific:7,unblock:4,sleep:[8,2],default_publisher_qo:9,langaug:6,edu:5,follow:[4,9],this_thread:[4,8,2],compact:4,whose:[8,1,2,9],depend:[4,8,1,2],system:[1,2,4,7,6,5,8,9],xml:[1,9,6],readabl:4,articl:4,for_each:[4,8,2],program:[4,1],present:[4,9,10],under:[4,3],sens:4,keylist:[8,1,2],worth:[4,1],introduc:[8,1,2],consum:[8,1,2,9],everi:[4,8,2],string:[4,8,1,2,9],straightforward:[8,2,9],far:[4,1,9],execut:4,"void":4,reader:[1,2,4,6,7,8,9],multi:1,unfamiliar:[8,2],focus:4,util:[4,1],interoper:[8,2,6,5],volum:[8,2,5],whether:[4,8,1,2],failur:[8,2],veri:[4,8,1,2],word:4,implicitli:4,bottleneck:[8,2],lookup_inst:4,relev:[4,9,7],condition:[8,2],mistri:6,magic:[8,2],administr:4,level:[1,9],wegner:5,sensor:[8,1,2],gui:5,scalabl:[8,2,9],list:[4,8,1,2,9],dataread:[4,8,1,2],fewer:[8,2],"try":[4,8,2],item:[9,7],interfac:[8,2,6],default_datawriter_qo:4,qosprovid:9,larg:[2,1,9,6,5,8],particularli:9,cmu:5,bracha:5,blackout:5,dimens:1,vehicl:6,impli:4,bill:5,tel:3,weslei:5,temperaturescal:[8,1,2],natur:[4,1],topic_qo:9,direct:[8,1,2],focu:[4,1],second:[4,8,2],fiber:9,pass:[8,1,2],download:5,further:1,even:[4,8,1,2,9],klt:1,corba:[8,2,6],sub:[4,8,1,2,6],defin:[4,8,1,2,9],sun:5,section:[1,5],abl:[4,1],"while":[4,8,1,2],samplest:4,access:[0,2,9,8],version:[4,10],"new":[4,1,10],net:9,ever:[4,1],method:[4,8,2],contrast:1,scada:[8,2],impact:[8,1,2],prismtech:[7,1,10,3],full:[4,1,9],abov:[4,1,9],editor:5,gener:[4,8,2,9,7],sophist:[8,2],here:[4,8,2],behaviour:[4,9],back_insert:4,northeast:5,let:4,splice:5,address:[8,2],"const":[4,8,2],along:[4,8,1,2,9],becom:[4,8,2],modifi:1,sinc:[4,8,1,2,9],valu:[4,8,1,2,9],wait:[0,2,8],cardelli:5,remark:[8,2],survei:5,not_alive_dispos:4,militari:6,technolog:[4,8,1,2,6],loos:[8,2],precis:[8,2],jame:5,amount:[1,9],base:[0,9,7],social:[8,2],action:[8,1,2],triad:[8,2],chang:[4,8,2,9,3],narrow:9,readsampl:4,commonli:9,portabl:[8,2],control:[4,8,1,2,9],semant:[4,9],writer:[2,1,9,4,6,8],depart:6,heart:[8,2],appli:[8,1,2,9,7],transit:[4,8,1,2],avenu:3,why:4,unix:[4,8,2,7],api:[2,4,5,8,9,10],famili:[8,2],instal:[8,1,2,10],establish:[8,1,2],unit:[8,1,2],highli:[8,2,9],angelo:5,from:[1,2,4,8,9,10],describ:[4,1,9],usa:3,commun:[1,2,4,5,8,9],on_data_avail:4,regist:[4,8,2],two:[4,8,1,2],todai:[8,2],next:1,implic:4,predict:[8,2],live:1,handler:4,call:[4,8,2],tradecent:3,recommend:[4,8,1,2],taken:[4,7],scope:[0,9],type:[0,9,4,5,8,2],until:9,more:[4,8,1,2,9],flat:1,mellon:5,desir:[8,1,2,9],relat:[8,2,9],line:[8,2],tempcontrol_dcp:4,enhanc:[8,2],flag:4,exce:9,accept:1,examin:4,aris:4,known:4,central:[8,2],hold:[4,9],airplan:4,must:9,high:[4,8,2,9],join:[8,1,2,9],room:[8,1,2,9],lambda:4,hous:3,milva:6,gabriel:5,work:[4,8,2,3],uniqu:[4,8,1,2],register_inst:4,histori:9,latency_budget:9,remain:4,default_id:4,can:[1,2,4,8,9,10],learn:[8,2],fnmatch:[1,5],meet:9,fetch:9,aliv:[4,9],novic:[8,2],claim:[4,9],klsensortop:1,stream:[8,1,2,9],give:[4,8,2,9],process:[8,2,9,5],destruct:4,challeng:5,celsiu:[4,8,1,2],share:[8,2,9],templat:[8,1,2],topic:5,pictur:9,critic:[8,2,9],minimum:9,caution:7,want:[4,1],unsign:[4,1],occur:4,mainstream:1,alwai:4,infrastructur:4,kldw:1,end:[4,8,1,2,9],klein:5,secur:[8,2,9],programmat:[8,2],anoth:[4,8,2],kltstopic:1,perhap:4,sharealik:3,write:10,how:[4,8,2,9,7],hot:[8,2],lifecycl:[4,1],anyon:7,gosl:5,answer:[4,8,2],iso:[8,10,5],flow:[4,8,2],simpl:[4,1],updat:[4,9],ne11:3,product:7,likewis:[4,8,1,2],ramakrishnan:5,overridden:4,less:[4,1,9],after:[4,8,2,9],variant:1,befor:[4,1],support:[1,2,4,8,9,10],mai:[4,8,1,2],multipl:9,data:[6,5],parallel:1,physic:1,alloc:[4,1],github:10,essenti:[8,1,2,9],practic:4,tutori:[8,2,10],bind:4,parameter:1,counter:4,explicit:0,fine:9,element:[8,2,9],caus:4,inform:[0,2,3,4,6,7,8,9,10],"switch":1,maintain:[4,1,9],environ:9,temp:[4,8,1,2],allow:[4,8,1,2,9],enter:4,exclus:9,mechan:[4,8,1,2,9],transport_prior:9,first:[4,8,1,2],order:[4,8,1,2,9],rue:3,mtseq10:1,help:[9,7],goodenough:5,over:[8,2,9],move:1,microsystem:5,mission:[8,2,9],idl:[8,9,1,2,6],trade:[8,1,2],"abstract":[8,1,2,9,5],whilst:[8,2,9],own:[8,2,9],through:[4,8,1,2,9],reconstruct:9,equip:[8,2],still:[4,9],dynam:[8,2,9,5],paramet:[4,1],busi:[8,2,3],style:[4,8,2],group:[2,1,9,6,5,8],monitor:[8,1,2],destination_ord:9,polici:[4,8,1,2,9],invalid:4,strang:4,better:[8,2],platform:[4,1],mqtt:6,html:5,opposit:4,requir:[4,8,1,2,9],legalcod:3,mail:3,main:[4,1],might:[4,8,1,2],them:[4,8,1,2],good:[4,3],crash:[4,8,1,2],greater:[4,1],thei:[4,8,1,2,9],fragment:1,financi:[8,1,2],overal:9,mention:4,therebi:9,recap:1,potenti:4,now:[8,1,2],discuss:[4,1],introduct:7,choic:[4,9],strongli:[8,2],maxsampl:4,name:[4,8,1,2,9],auto:[4,8,2],anyth:[4,8,2],edit:5,perspect:1,separ:4,easili:[8,2],achiev:9,luca:5,compris:[8,2],each:[4,8,1,2],fulli:[8,2,9],notif:[4,8,2],higher:5,side:[4,1],group_data:9,mean:[1,2,4,7,8,9],subsystem:9,domain:6,map:1,"short":[4,8,1,2],replac:4,exactli:1,continu:[8,2,9],functor:4,realli:[8,2],writerdatalifecycl:4,meta:[0,9],connect:[4,8,2,9],opportun:10,our:[4,1],happen:[4,8,1,2],dispos:[4,8,1,2],event:[4,8,2],special:[4,1,7],out:[4,0,2,8],manuallydisposeunregisteredinst:4,shown:[1,2,4,7,8,9],unbound:1,network:[1,9],"3rd":5,space:6,open:[10,5],defenc:6,publish:[2,1,9,4,6,8],profil:[8,2,9],vector:[4,1],tempsensortop:[4,1],hill:5,rel:9,internet:[8,2,6],dwi3:4,occurr:[4,8,2],defens:[8,2,6],common:[2,9,3,4,6,8],franc:3,any_view_st:4,iostream:4,partit:[4,0,9],insid:0,advanc:[8,2,6],upon:[4,9],time_based_filt:9,northrop:5,differ:[4,8,1,2,9],pub:[2,1,9,4,6,8],standard:6,thi:[1,2,3,4,7,8,9,10],reason:4,cftopic:1,statusmask:4,tempt:4,releas:4,org:[4,5,10,3],hand:[4,1],registr:4,unpredict:[8,2],cxx:5,care:[8,2],std:[4,8,1,2],joiner:[4,9],wai:[4,8,1,2,9],puzzl:[8,2],prescrib:[8,2],c3d:1,could:[4,8,1,2],omit:4,synchron:4,segreg:[1,9],keep:[4,8,1,2],recov:1,thing:[4,8,1,2,6],length:1,coffeescript:[8,2],place:9,due:[4,9],outsid:[1,9],listingb:4,lifetim:9,licens:3,publisherqo:9,oper:[2,1,9,4,6,8],softwar:5,major:[8,2],ubiquit:[8,2],isbn:5,notifi:[0,9],distibut:7,onc:[4,9],arrai:[4,8,1,2],independ:[8,1,2,9],qualiti:[0,2,6,8],number:[1,2,4,5,8,9],yourself:4,restrict:8,extern:9,alreadi:[4,8,2],defaultqosprofil:9,construct:[4,8,1,2],effortless:[8,2],oppos:[4,1],technetwork:5,miss:9,mix:[8,2],size:1,window:7,given:[4,1,9],"long":[4,8,1,2],breviti:4,durability_servic:9,messag:[4,8,2,6,5],citi:[8,2],associ:[2,1,9,4,6,8],"5th":3,perfectli:4,sometim:4,least:4,fahrenheit:[8,1,2],attach:4,definit:[4,8,9,2,6],demonstr:[4,8,2],termin:[4,8,2],waitset:[0,2,8],conveni:4,filter:[4,0,2,8],store:[4,1,9],too:[8,2],relationship:[4,8,2],behind:[8,2],hum:[4,8,1,2],not_new:4,park:3,specifi:[8,1,2,9],sampleinfo:4,provid:[1,2,4,8,9,10],part:[4,8,2,9,3],pragma:[8,1,2],"function":[4,8,1,2,9],viewstat:4,tempsensortyp:[4,8,1,2,9],nobodi:4,than:[4,8,1,2,9],readbisampl:4,wide:9,kind:[4,8,1,2],scheme:1,longstaff:5,whenev:4,remot:4,remov:[4,1],rate:9,structur:[4,8,1,2,6],"final":[4,8,1,2],matter:4,info:[4,3],posix:[1,5],coord3d:1,were:4,posit:1,deadlin:9,listen:[0,2,8],markup:6,pre:[8,2],lowest:4,sai:[4,8,2],bootstrap:9,comput:[9,5],coord:1,credenti:9,ani:[4,8,1,2,9],latter:4,"return":[4,8,1,2],manner:[4,9],coher:[1,9],deliv:9,need:[1,2,4,7,8,9],seen:[4,1,9],seem:4,resource_limit:9,creativecommon:3,issu:4,qoss:[8,1,2],engin:5,built:9,equival:[4,1],destroi:4,moreov:[8,2],violat:[8,2],consortium:[8,2],wipe:4,note:4,also:[1,2,4,8,9,10],take:[0,10,2,8],which:[1,2,4,7,8,9,10],transmit:9,combin:4,wonder:[8,2],singl:[4,8,2],ttempsensor:[8,1,2],simplifi:1,begin:[4,8,2],sure:4,unless:1,distribut:[6,5],deploy:[8,2,9],buffer:1,c99:1,previou:[4,1],oracl:5,deleg:1,discov:[8,2],did:[4,9],most:[4,8,1,2,9],plai:4,said:10,jsr:5,deploi:[8,2],subset:[8,1,2],model:[0,2,6,8],appear:[4,8,1,2],tradit:[8,2],doi:5,placement:1,binari:1,doc:5,clear:[8,1,2],later:[4,8,1,2],cover:[4,1],dod:6,doe:[4,8,2,9],homogen:1,declar:[4,1],timeli:0,runtim:[8,1,2],determin:4,databas:5,constrain:1,usual:[8,2],sensordatapartit:1,think:1,humid:[8,1,2],show:[4,8,1,2,9],datawriterqo:[4,9],random:1,data_read:4,syntax:[4,1],concurr:9,radio:9,cdr:6,protocol:[1,6,5],fear:[8,2],coord4d:1,trivial:4,find:[4,8,2],involv:4,depth:1,onli:[1,2,4,7,8,9,10],explicitli:[4,8,1,2,9],dp2:[8,2],pretti:[4,1,9],explain:[4,8,2,9],configur:[0,2,8],activ:4,state:0,should:[4,1],latenc:[4,8,2,9],queu:[4,6],srccond:4,iec:[8,5],local:[4,9],flexibl:1,steel:5,loss:4,wnpxrz:5,variou:[4,8,1,2,9],familiar:[8,2],express:[4,1,9],soon:4,cannot:1,domainparticip:[4,8,2,9],showcas:4,increas:9,budget:9,subscript:[1,9],restart:[4,9],reveal:[8,2],experi:[4,8,1,2],enabl:[4,1,9,10],organ:[4,1],amqp:6,cyclic:4,powergrid:5,"public":4,pubqo:9,topic_data:9,cach:[4,9],integr:[8,1,2],mediat:1,contain:[0,7,3],tempsensor:[1,9],essenc:4,where:[4,8,1,2,7],view:[4,1],gehrk:5,keyless:0,set:[0,2,8,7],xtype:5,adopt:[8,2],"float":[8,1,2],dwqo:[4,9],datatyp:4,see:[4,8,1,2],centric:9,int16_t:1,result:[4,8,1,2],fail:[8,1,2],reserv:4,publisher_qo:9,becaus:1,analog:4,concern:[4,1,9],infinit:9,awar:[4,9],statu:[4,8,2],detect:1,kei:[4,0,2,8],profession:5,heterogen:9,pattern:[4,1],someth:4,particip:6,unregistr:4,discoveri:[8,2],enough:[8,2],volatil:9,"0ng":3,c2d:1,between:[4,8,1,2,9],"import":[4,8,1,2,9],awai:4,entiti:[8,1,2,9],approach:[4,9],across:[8,1,2],"15th":1,attribut:[4,8,1,2,3],altern:[4,9],accord:9,omg:[6,5],kltempsensortop:1,extend:9,induc:4,javascript:[8,2],subject:3,versu:1,rostand:3,transient_loc:9,steroid:[8,2],grid:[8,2],complementari:[8,2],disconnect:[8,2],come:[4,1],endl:[4,8,2],regular:1,addit:[4,1,9,10],both:[4,1],last:[4,9],extens:[6,5],dissemin:9,howev:4,hint:7,equal:[4,1],against:9,tempor:[8,2,9],etc:[8,1,2,7],audienc:7,instanc:[0,2,9,8],context:4,logic:[4,1],freeli:10,com:[5,10,3],schmidt:5,simpli:[4,8,2],solari:7,figur:9,instanti:[8,2],character:[1,9],loan:4,ubuntu:7,period:9,dispatch:4,walk:1,arbitrarili:[8,2],header:1,johann:5,featur:[4,8,2,7],shutdown:9,joi:5,written:[4,8,1,9],throughout:[8,2,10],assum:[4,1],new_view:4,user_data:9,liabil:3,java:[1,2,4,7,6,5,8],corsaro:5,coupl:[8,2],addition:[8,2],trademark:3,three:[4,1],empti:1,compon:[8,2,9],whom:9,much:1,interest:[4,8,1,2,9],subscrib:[2,1,9,4,6,8],coord2d:1,immedi:[4,8,2],devis:1,dure:9,quickli:7,unregist:4,addison:5,life:[0,2,8],fmatch:[1,5],emphas:1,presenc:[8,2],persist:9,search:0,argument:1,coordin:[4,8,2],schema:9,zero:4,understand:[4,5],togeth:1,rang:[4,1],educ:5,spin:[8,2],upcom:[8,2],those:[4,8,1,2],"case":[4,1],replic:9,tempcontrol:[8,2],ident:4,look:[4,8,1,2],transportprior:9,contentfilteredtop:1,servic:[6,5],properti:[4,8,1,2,9],histor:9,air:[8,2],pace:9,invok:4,overrid:4,unifi:6,smart:[8,2],behavior:4,samples2:4,report:1,anonym:[8,2],ultra:[6,5],observ:[8,2],loop:[4,8,2],propag:[8,2],gateshead:3,have:[1,2,4,8,9,10],advantag:[4,10],readi:[8,2,9],readm:10,non:[0,2,9,8],default_topic_qo:9,destin:9,itself:4,cond:4,incom:4,mod:6,mani:[8,1,2],quit:[4,1],sever:[8,1,2],queue:1,feiler:5,develop:[4,8,1,2,7],minim:[4,1,9],perform:[4,8,1,2,9],make:[1,2,4,7,8,9],belong:[4,8,1,2],exchang:9,same:[4,8,1,2,9],member:1,handl:4,complex:[8,2],decod:[8,2],timestamp:[4,9],lite:10,raghu:5,document:[7,3],infer:4,complet:[4,8,2],status:4,safe:4,http:[5,10,3],optic:9,optim:[4,1,9],kelvin:[8,1,2],nest:[8,1,2],pick:4,mytyp:1,alert:1,mtseq:1,capabl:9,moment:9,rais:4,user:[4,8,1,2,9],ownership:9,ownership_strength:9,footprint:1,decoupl:[8,2,9],typic:[8,2,9],tune:9,techniqu:1,appropri:[4,8,2],off:[4,1],"253c6e83e1f7ec47b378721a81977c8e8":5,scenario:9,not_read_sample_st:4,whole:[8,2,9],thu:[4,8,1,2,9],well:[4,8,1,2,9],spent:4,thought:1,tie:1,without:[4,3],uint32_t:4,choos:8,programm:[4,8,2],everyth:[8,2],woburn:3,dimension:1,left:4,stringent:9,identifi:[4,8,1,2,7],cout:[4,8,2],just:1,hierarch:1,obtain:4,rest:4,bandwidth:9,via:[4,1,9],virtual:[4,1],aspect:[4,1,9,10],simd:5,regardless:[4,1],speed:9,yet:[4,8,2],languag:[1,2,4,7,6,5,8,10],wether:4,web:3,gather:4,struct:[8,1,2],expos:4,readcondit:4,interfer:9,copi:4,point:[4,8,1,2,7],priorit:9,except:1,param:[4,1],sullivan:5,other:[4,8,1,2],primit:[8,1,2],role:[4,9],dispose_inst:4,subsequ:[4,9],int32_t:1,match:[4,8,1,2,9],build:[8,1,2,9],real:[8,2,5],applic:[1,2,4,7,8,9],vendor:[8,1,2],psm:5,preserv:9,big:4,regard:[4,8,1,2],arriv:9,datawriter_qo:9,temperatur:[4,8,1,2],traffic:[8,2,9],know:4,elabor:9,guid:7,world:[8,2],bit:[1,5],wallnau:5,issn:5,loanedsampl:4,resid:4,like:[4,8,1,2],specif:[1,2,4,7,5,8,9],arbitrari:[8,1,2],oseq:1,corpor:3,exploit:[9,7],integ:[8,2],c1d:1,neccessari:1,vortex:10,"boolean":1,necessari:[4,1,10],either:[4,1],region:4,mcgraw:5,srcreader:4,inter:9,prior:4,manag:[0,2,9,6,5,8],emerg:[8,2],underli:4,jean:3,www:[5,10,3],right:[4,9],often:[4,9],urgenc:9,what:[4,8,1,2],acknowledg:3,interv:9,linux:7,some:[1,2,4,8,9,10],back:4,certain:[4,1],thread:4,intern:3,enumer:[8,1,2],sampl:[0,2,9,8],act:4,respect:[4,1],sen:1,guarante:[8,2],server:[8,2,9],constitut:9,singleton:[4,1],transport:6,alive_instance_st:4,poll:[4,8,2],cooper:9,pinpoint:4,lead:4,scala:[8,2],supervisori:[8,2],leak:4,avoid:[4,8,2],though:1,octet:[1,9],thank:1,overlap:4,summar:4,datawrit:[4,8,1,2,9],track:1,evolv:[8,2],leav:[4,8,2,9],middlewar:[4,1],sequenc:[8,1,2,9],keylesstempsensortyp:1,condit:[4,1],content:[0,2,9,8],tempsensorlisten:4,refer:[8,1,2],machin:[8,2],core:[4,8,2,9],plu:1,object:[1,2,4,6,5,8],run:[1,2,4,7,8,9,10],power:[4,8,2,9],emul:1,late:[4,9],"enum":[8,1,2],usag:[4,1,9],broker:6,noisi:9,who:[8,2,7],step:[8,1,2],topicqo:9,although:[4,8,1,2,10],found:[4,8,2],post:1,wire:[8,2,6,5],chapter:[4,8,1,2,9],faith:3,about:[8,2],rare:4,would:[4,8,1,2],datast:4,linger:5,noopdatareaderlisten:4,processor:[8,2],memori:[1,9],slightli:[8,2],acm:5,page:[0,5],kazman:5,union:[8,1,2],degre:1,coord1d:1,includ:[1,2,4,7,8,9],done:[4,8,1,2],commerci:10,commit:4,industri:[8,2,6],actuat:[8,2],produc:[8,1,2,9],block:[0,2,8],glanc:[8,2],routin:[8,2],doubl:1,effici:[4,8,1,2],opensplic:[0,1,2,3,4,5,6,7,8,9,10],devic:9,logdatapartit:1,within:[1,9],encod:[8,1,2],orsai:3,automat:[0,2,9,8],compos:[8,2],down:9,creativ:3,polyglot:[8,2],been:[4,8,1,2],ensur:[4,8,2,9],pollak:5,storag:[4,9],your:[4,8,1,2],durabl:9,per:1,c4d:1,inclus:[4,1],fast:[8,2],span:9,carnegi:5,few:4,oseq1k:1,captur:[8,2],question:[4,8,2],iter:0,sei:5,custom:4,avail:[0,10,2,8,3],start:[8,1,2,9,7],reli:[8,1,2,9],trigger:4,uml:6,low:[8,2,9],instancest:4,suit:3,forward:4,icon:7,select:[0,2,9,8],deliveri:0,new_data:4,creation:[8,1,2],form:[8,2],offer:9,great:9,basic:[4,1],amongst:1,idea:4,java5:[8,5],diffus:9,link:[1,9],ospl:5,compil:[4,8,1,2,10],highest:9,"true":[8,2],not_read:4,faster:9,sleep_for:[4,8,2],made:[1,2,3,4,8,9],consist:1,understood:[8,2],"default":[4,8,2,9],wish:7,best:4,maximum:[1,9],lifespan:9,tell:4,asynchron:[4,8,2],insert:4,below:[8,1,2,9,7],instancehandl:4,limit:[8,1,2,9,3],problem:1,remaind:9,similar:[4,1],reliabl:9,expect:[4,1],bibsonomi:5,creat:[4,8,1,2,9],"int":[4,1],request:[4,9,6],data_avail:4,repres:[8,1,2,9],"char":[4,1],proper:[8,2],ddsi:[8,2,6,5],multiplex:1,not_alive_no_writ:4,file:[8,2,9],int64_t:1,unregister_inst:4,improv:9,check:1,again:[4,1],peter:5,googl:[1,5],floor:[8,1,2,9],best_effort:9,hpp:4,when:[4,8,1,2,9],detail:[4,8,2],iot:[8,2,6],orient:[4,1],field:1,possibl:[4,8,1,2,9],valid:[4,8,2,9],lookup:4,futur:[4,5],varieti:4,bibtex:5,you:[1,2,4,8,9,10],telemetri:[8,1,2,6],architectur:[8,2,6],node:4,commandpartit:1,claus:1,intend:[4,8,2,7],registri:[8,2,6],bisampl:4,actual:1,polymorph:5,"class":[4,8,1,2],time:[1,2,4,5,8,9,10],june:5,scale:[1,2,4,6,5,8,9],intent:4,embed:[1,9],consid:[4,1,9],sql:[1,6],previous:4,fsampl:4,formal:[8,2],gilad:5,legal:[4,1],experienc:[8,2],receiv:[4,8,1,2],longer:4,furthermor:1,chrono:[4,8,2],cycl:[0,2,8],descript:7,discrimin:4,mimic:1,"transient":9,gracefulli:4,had:4,institut:5,cpp:10,slice:1,invari:9,cfttempsensor:1},objtypes:{},objnames:{},filenames:["index","topics-etc","foundations_2","contacts","readandwrite","biblio","acronyms","preface","foundations","qos","appendix-A"],titles:["The Data Distribution Service Tutorial","2. Topics, Domains and Partitions","Foundations","8. Contacts & Notices","3. Reading and Writing Data","7. Bibliography","6. Acronyms & Abbreviations","Preface","1. Foundations","4. Quality of Service","5. Appendix A"],objects:{},titleterms:{keyless:4,domain:[8,1,2],code:10,consider:10,global:[8,2],foundat:[8,2],life:4,indic:0,topic:[4,8,1,2],set:9,sampl:[4,1],tabl:0,onlin:10,select:4,notifi:4,avail:9,insid:1,convent:7,space:[8,2],write:[4,8,2],configur:9,particip:[8,2],abbrevi:6,content:[4,1],acronym:6,state:4,contact:3,bibliographi:5,take:4,scope:1,waitset:4,out:1,type:1,listen:4,deliveri:9,non:4,sourc:10,omg:[8,2],distribut:[0,2,8],kei:1,get:10,read:[4,8,2],qualiti:9,exampl:10,notic:3,standard:[8,2],cycl:4,appendix:10,nutshel:[8,2],automat:4,base:4,resourc:[9,10],data:[4,0,2,9,8],implement:10,wait:4,prefac:7,about:7,instanc:[4,1],timeli:9,servic:[0,2,9,8],access:4,explicit:4,iter:4,tutori:[0,7],filter:1,inform:1,meta:4,partit:1,contain:4,model:9,manag:4,block:4,summari:[4,8,1,2,9]}}) \ No newline at end of file +Search.setIndex({envversion:42,terms:{represent:[8,2,6],disr:6,concept:[4,8,1,2,9],edg:3,whatev:4,illustr:[4,8,1,2,9],queri:[4,8,1,2,6],global:6,all:[1,2,3,4,8,9,10],four:4,signific:7,unblock:4,sleep:[8,2],default_publisher_qo:9,langaug:6,edu:5,follow:[4,9],this_thread:[4,8,2],forget:4,compact:4,whose:[8,1,2,9],depend:[4,8,1,2],system:[1,2,4,7,6,5,8,9],xml:[1,9,6],mechan:[4,8,1,2,9],readabl:4,articl:4,for_each:[4,8,2],program:[4,1],present:[4,9,10],under:[4,3],sens:4,keylist:[8,1,2],ist_info:3,worth:[4,1],introduc:[8,1,2],consum:[8,1,2,9],everi:[4,8,2],string:[4,8,1,2,9],straightforward:[8,2,9],far:[4,1,9],execut:4,"void":4,reader:[1,2,4,6,7,8,9],multi:1,unfamiliar:[8,2],focus:4,util:[4,1],interoper:[8,2,6,5],volum:[8,2,5],whether:[4,8,1,2],failur:[8,2],veri:[4,8,1,2],word:4,implicitli:4,bottleneck:[8,2],lookup_inst:4,relev:[4,9,7],condition:[8,2],mistri:6,magic:[8,2],administr:4,level:[1,9],wegner:5,sensor:[8,1,2],gui:5,idl:[8,9,1,2,6],list:[4,8,1,2,9],dataread:[4,8,1,2],fewer:[8,2],"try":[4,8,2],item:[9,7],interfac:[8,2,6],default_datawriter_qo:4,qosprovid:9,larg:[2,1,9,6,5,8],team:3,particularli:9,cmu:5,bracha:5,blackout:5,dimens:1,vehicl:6,impli:4,bill:5,tel:3,weslei:5,temperaturescal:[8,1,2],natur:[4,1],topic_qo:9,direct:[8,1,2],focu:[4,1],second:[4,8,2],fiber:9,pass:[8,1,2],download:5,further:1,sleep_for:[4,8,2],bootstrap:9,even:[4,8,1,2,9],klt:1,corba:[8,2,6],sub:[4,8,1,2,6],defin:[4,8,1,2,9],sun:5,section:[1,5],abl:[4,1],"while":[4,8,1,2],samplest:4,access:[0,2,9,8],version:[4,10],"new":[4,1,10],net:9,ever:[4,1],method:[4,8,2],contrast:1,scada:[8,2],impact:[8,1,2],prismtech:10,full:[4,1,9],abov:[4,1,9],editor:5,gener:[4,8,2,9,7],sophist:[8,2],here:[4,8,2],behaviour:[4,9],back_insert:4,northeast:5,let:4,splice:5,address:[8,2],"const":[4,8,2],"0xa":3,becom:[4,8,2],modifi:1,sinc:[4,8,1,2,9],valu:[4,8,1,2,9],wait:[0,2,8],cardelli:5,remark:[8,2],survei:5,not_alive_dispos:4,militari:6,technolog:[1,2,3,4,6,8],loos:[8,2],precis:[8,2],jame:5,amount:[1,9],base:[0,9,7],social:[8,2],action:[8,1,2],triad:[8,2],chang:[4,8,2,9,3],narrow:9,readsampl:4,commonli:9,portabl:[8,2],control:[4,8,1,2,9],semant:[4,9],writer:[2,1,9,4,6,8],depart:6,heart:[8,2],appli:[8,1,2,9,7],transit:[4,8,1,2],avenu:3,why:4,unix:[4,8,2,7],api:[2,4,5,8,9,10],famili:[8,2],instal:[8,1,2,10],establish:[8,1,2],unit:[8,1,2],highli:[8,2,9],angelo:5,from:[1,2,4,8,9,10],describ:[4,1,9],usa:3,commun:[1,2,4,5,8,9,10],on_data_avail:4,regist:[4,8,2],two:[4,8,1,2],todai:[8,2],next:1,implic:4,predict:[8,2],live:1,handler:4,call:[4,8,2],tradecent:3,recommend:[4,8,1,2],taken:[4,7],scope:[0,9],type:[0,9,4,5,8,2],until:9,more:[4,8,1,2,9],flat:1,mellon:5,desir:[8,1,2,9],relat:[8,2,9],line:[8,2],tempcontrol_dcp:4,enhanc:[8,2],flag:4,exce:9,accept:1,examin:4,aris:4,known:4,central:[8,2],compani:3,hold:[4,9],airplan:4,must:9,high:[4,8,2,9],join:[8,1,2,9],room:[8,1,2,9],lambda:4,scalabl:[8,2,9],milva:6,gabriel:5,work:[4,8,2,3],uniqu:[4,8,1,2],register_inst:4,histori:9,latency_budget:9,remain:4,default_id:4,can:[1,2,4,8,9,10],learn:[8,2],fnmatch:[1,5],meet:9,fetch:9,aliv:[4,9],novic:[8,2],claim:[4,9],klsensortop:1,stream:[8,1,2,9],give:[4,8,2,9],process:[8,2,9,5],destruct:4,challeng:5,celsiu:[4,8,1,2],share:[8,2,9],templat:[8,1,2],topic:5,pictur:9,critic:[8,2,9],minimum:9,caution:7,want:[4,1],keep:[4,8,1,2],unsign:[4,1],occur:4,mainstream:1,alwai:4,infrastructur:4,kldw:1,end:[4,8,1,2,9],klein:5,secur:[8,2,9],programmat:[8,2],anoth:[4,8,2],kltstopic:1,perhap:4,sharealik:3,write:10,how:[4,8,2,9,7],hot:[8,2],lifecycl:[4,1],anyon:7,actual:1,answer:[4,8,2],iso:[8,10,5],flow:[4,8,2],simpl:[4,1],updat:[4,9],ne11:3,product:7,likewis:[4,8,1,2],ramakrishnan:5,overridden:4,less:[4,1,9],after:[4,8,2,9],variant:1,befor:[4,1],support:[1,2,4,8,9,10],adlinktech_usa:3,mai:[4,8,1,2,3],multipl:9,data:[6,5],parallel:1,physic:1,alloc:[4,1],github:10,essenti:[8,1,2,9],practic:4,tutori:[8,2,10],bind:4,parameter:1,issn:5,explicit:0,invari:9,fine:9,element:[8,2,9],caus:4,inform:[0,2,3,4,6,7,8,9,10],"switch":1,maintain:[4,1,9],environ:9,temp:[4,8,1,2],allow:[4,8,1,2,9],enter:4,exclus:9,facebook:3,transport_prior:9,first:[4,8,1,2],order:[4,8,1,2,9],rue:3,mtseq10:1,help:[9,7],goodenough:5,over:[8,2,9],move:1,microsystem:5,mission:[8,2,9],trade:[8,1,2],"abstract":[8,1,2,9,5],whilst:[8,2,9],own:[8,2,9],through:[4,8,1,2,9],reconstruct:9,equip:[8,2],still:[4,9],dynam:[8,2,9,5],paramet:[4,1],busi:[8,2],style:[4,8,2],group:[2,1,9,6,5,8],monitor:[8,1,2],destination_ord:9,polici:[4,8,1,2,9],invalid:4,strang:4,better:[8,2],platform:[4,1],mqtt:6,html:5,opposit:4,requir:[4,8,1,2,9],legalcod:3,mail:3,main:[4,1],might:[4,8,1,2],them:[4,8,1,2],good:[4,3],crash:[4,8,1,2],greater:[4,1],thei:[4,8,1,2,9],fragment:1,financi:[8,1,2],overal:9,mention:4,therebi:9,recap:1,potenti:4,now:[8,1,2],discuss:[4,1],introduct:7,choic:[4,9],strongli:[8,2],maxsampl:4,name:[4,8,1,2,9],auto:[4,8,2],anyth:[4,8,2],edit:5,perspect:1,separ:4,easili:[8,2],achiev:9,luca:5,compris:[8,2],each:[4,8,1,2],fulli:[8,2,9],notif:[4,8,2],higher:5,side:[4,1],group_data:9,mean:[1,2,4,7,8,9],subsystem:9,domain:6,map:1,"short":[4,8,1,2],replac:4,exactli:1,continu:[8,2,9],functor:4,realli:[8,2],writerdatalifecycl:4,meta:[0,9],connect:[4,8,2,9],opportun:10,our:[4,1],happen:[4,8,1,2],dispos:[4,8,1,2],event:[4,8,2],special:[4,1,7],out:[4,0,2,8],manuallydisposeunregisteredinst:4,shown:[1,2,4,7,8,9],unbound:1,network:[1,9],"3rd":5,space:6,open:[10,5],defenc:6,publish:[2,1,9,4,6,8],content:[0,2,9,8],vector:[4,1],tempsensortop:[4,1],hill:5,rel:9,internet:[8,2,6],dwi3:4,occurr:[4,8,2],defens:[8,2,6],common:[2,9,3,4,6,8],franc:3,any_view_st:4,iostream:4,partit:[4,0,9],insid:0,advanc:[8,2,6],upon:[4,9],time_based_filt:9,northrop:5,differ:[4,8,1,2,9],pub:[2,1,9,4,6,8],standard:6,thi:[1,2,3,4,7,8,9,10],reason:4,cftopic:1,statusmask:4,tempt:4,releas:4,org:[4,5,3],hand:[4,1],registr:4,unpredict:[8,2],cxx:5,care:[8,2],std:[4,8,1,2],joiner:[4,9],wai:[4,8,1,2,9],puzzl:[8,2],prescrib:[8,2],c3d:1,could:[4,8,1,2],omit:4,synchron:4,segreg:[1,9],ist:[10,3],recov:1,thing:[4,8,1,2,6],length:1,coffeescript:[8,2],place:9,due:[4,9],outsid:[1,9],listingb:4,lifetim:9,licens:3,publisherqo:9,oper:[2,1,9,4,6,8],softwar:5,major:[8,2],ubiquit:[8,2],isbn:5,notifi:[0,9],distibut:7,onc:[4,9],arrai:[4,8,1,2],independ:[8,1,2,9],qualiti:[0,2,6,8],number:[1,2,4,5,8,9],yourself:4,restrict:8,extern:9,alreadi:[4,8,2],defaultqosprofil:9,construct:[4,8,1,2],effortless:[8,2],oppos:[4,1],technetwork:5,miss:9,mix:[8,2],size:1,window:7,given:[4,1,9],"long":[4,8,1,2],breviti:4,durability_servic:9,messag:[4,8,2,6,5],citi:[8,2],associ:[2,1,9,4,6,8],"5th":3,perfectli:4,sometim:4,least:4,fahrenheit:[8,1,2],attach:4,definit:[4,8,9,2,6],demonstr:[4,8,2],termin:[4,8,2],waitset:[0,2,8],conveni:4,filter:[4,0,2,8],store:[4,1,9],too:[8,2],relationship:[4,8,2],behind:[8,2],hum:[4,8,1,2],not_new:4,specifi:[8,1,2,9],sampleinfo:4,provid:[1,2,4,8,9,10],part:[4,8,2,9,3],pragma:[8,1,2],"function":[4,8,1,2,9],viewstat:4,tempsensortyp:[4,8,1,2,9],nobodi:4,than:[4,8,1,2,9],readbisampl:4,wide:9,kind:[4,8,1,2],scheme:1,longstaff:5,whenev:4,remot:4,remov:[4,1],rate:9,structur:[4,8,1,2,6],"final":[4,8,1,2],matter:4,posix:[1,5],coord3d:1,were:4,posit:1,deadlin:9,listen:[0,2,8],markup:6,pre:[8,2],lowest:4,sai:[4,8,2],counter:4,comput:[9,5],new_data:4,credenti:9,ani:[4,8,1,2,9],latter:4,"return":[4,8,1,2],manner:[4,9],coher:[1,9],deliv:9,need:[1,2,4,7,8,9],seen:[4,1,9],seem:4,resource_limit:9,creativecommon:3,issu:4,qoss:[8,1,2],engin:5,built:9,equival:[4,1],destroi:4,moreov:[8,2],violat:[8,2],consortium:[8,2],wipe:4,note:4,also:[1,2,4,8,9,10],take:[0,10,2,8],which:[1,2,4,7,8,9,10],transmit:9,combin:4,wonder:[8,2],singl:[4,8,2],ttempsensor:[8,1,2],simplifi:1,begin:[4,8,2],sure:4,unless:1,distribut:[6,5],deploy:[8,2,9],buffer:1,c99:1,previou:[4,1],oracl:5,deleg:1,discov:[8,2],did:[4,9],most:[4,8,1,2,9],plai:4,said:10,jsr:5,deploi:[8,2],subset:[8,1,2],model:[0,2,6,8],appear:[4,8,1,2],tradit:[8,2],doi:5,placement:1,binari:1,doc:5,clear:[8,1,2],later:[4,8,1,2],cover:[4,1],dod:6,doe:[4,8,2,9],declar:[4,1],timeli:0,runtim:[8,1,2],determin:4,databas:5,constrain:1,usual:[8,2],sensordatapartit:1,think:1,humid:[8,1,2],show:[4,8,1,2,9],datawriterqo:[4,9],random:1,data_read:4,syntax:[4,1],concurr:9,radio:9,cdr:6,protocol:[1,6,5],fear:[8,2],coord4d:1,trivial:4,find:[4,8,2],involv:4,depth:1,onli:[1,2,4,7,8,9,10],explicitli:[4,8,1,2,9],dp2:[8,2],pretti:[4,1,9],explain:[4,8,2,9],configur:[0,2,8],activ:4,state:0,should:[4,1],latenc:[4,8,2,9],queu:[4,6],srccond:4,iec:[8,5],local:[4,9],flexibl:1,steel:5,loss:4,wnpxrz:5,variou:[4,8,1,2,9],familiar:[8,2],express:[4,1,9],vallei:3,soon:4,cannot:1,domainparticip:[4,8,2,9],showcas:4,increas:9,budget:9,subscript:[1,9],restart:[4,9],reveal:[8,2],experi:[4,8,1,2],enabl:[4,1,9,10],organ:[4,1],amqp:6,cyclic:4,coord:1,"public":4,pubqo:9,topic_data:9,cach:[4,9],integr:[8,1,2],mediat:1,contain:[0,7,3],tempsensor:[1,9],essenc:4,where:[4,8,1,2,7],view:[4,1],gehrk:5,keyless:0,set:[0,2,8,7],xtype:5,adopt:[8,2],"float":[8,1,2],dwqo:[4,9],datatyp:4,see:[4,8,1,2],centric:9,int16_t:1,result:[4,8,1,2],fail:[8,1,2],reserv:4,publisher_qo:9,becaus:1,analog:4,concern:[4,1,9],infinit:9,awar:[4,9],statu:[4,8,2],detect:1,kei:[4,0,2,8],profession:5,heterogen:9,pattern:[4,1],someth:4,particip:6,unregistr:4,discoveri:[8,2],enough:[8,2],volatil:9,c2d:1,between:[4,8,1,2,9],"import":[4,8,1,2,9],awai:4,entiti:[8,1,2,9],approach:[4,9],across:[8,1,2],"15th":1,attribut:[4,8,1,2,3],altern:[4,9],accord:9,omg:[6,5],kltempsensortop:1,extend:9,induc:4,javascript:[8,2],subject:3,versu:1,rostand:3,transient_loc:9,steroid:[8,2],grid:[8,2],complementari:[8,2],disconnect:[8,2],come:[4,1],endl:[4,8,2],regular:1,addit:[4,1,9,10],both:[4,1],last:[4,9],extens:[6,5],dissemin:9,howev:4,hint:7,equal:[4,1],against:9,tempor:[8,2,9],etc:[8,1,2,7],audienc:7,instanc:[0,2,9,8],context:4,logic:[4,1],freeli:10,whole:[8,2,9,3],schmidt:5,simpli:[4,8,2],solari:7,figur:9,instanti:[8,2],character:[1,9],loan:4,ubuntu:7,period:9,dispatch:4,walk:1,arbitrarili:[8,2],header:1,exploit:[9,7],featur:[4,8,2,7],shutdown:9,joi:5,written:[4,8,1,9],throughout:[8,2,10],assum:[4,1],along:[4,8,1,2,9],user_data:9,liabil:3,java:[1,2,4,7,6,5,8],corsaro:5,sarl:3,addition:[8,2],coupl:[8,2],trademark:3,three:[4,1],empti:1,compon:[8,2,9],whom:9,much:1,interest:[4,8,1,2,9],subscrib:[2,1,9,4,6,8],coord2d:1,immedi:[4,8,2],devis:1,dure:9,quickli:7,unregist:4,addison:5,life:[0,2,8],fmatch:[1,5],emphas:1,presenc:[8,2],persist:9,search:0,argument:1,coordin:[4,8,2],schema:9,zero:4,understand:[4,5],togeth:1,rang:[4,1],educ:5,spin:[8,2],upcom:[8,2],those:[4,8,1,2],"case":[4,1],replic:9,tempcontrol:[8,2],ident:4,look:[4,8,1,2],transportprior:9,contentfilteredtop:1,servic:[6,5],properti:[4,8,1,2,9],histor:9,air:[8,2],pace:9,invok:4,overrid:4,unifi:6,smart:[8,2],behavior:4,samples2:4,report:1,anonym:[8,2],ultra:[6,5],observ:[8,2],loop:[4,8,2],propag:[8,2],gateshead:3,have:[1,2,4,8,9,10],advantag:[4,10],readi:[8,2,9],readm:10,non:[0,2,9,8],default_topic_qo:9,destin:9,itself:4,cond:4,linkedin:3,incom:4,mod:6,mani:[8,1,2],quit:[4,1],sever:[8,1,2],queue:1,feiler:5,develop:[4,8,1,2,7],minim:[4,1,9],perform:[4,8,1,2,9],make:[1,2,4,7,8,9],belong:[4,8,1,2],exchang:9,same:[4,8,1,2,9],member:1,handl:4,complex:[8,2],decod:[8,2],timestamp:[4,9],lite:10,raghu:5,document:[7,3],infer:4,complet:[4,8,2],status:4,safe:4,http:[5,10,3],optic:9,optim:[4,1,9],kelvin:[8,1,2],nest:[8,1,2],pick:4,mytyp:1,alert:1,mtseq:1,capabl:9,moment:9,rais:4,user:[4,8,1,2,9],ownership:9,ownership_strength:9,footprint:1,decoupl:[8,2,9],typic:[8,2,9],tune:9,techniqu:1,appropri:[4,8,2],off:[4,1],"253c6e83e1f7ec47b378721a81977c8e8":5,scenario:9,not_read_sample_st:4,com:[5,10,3],thu:[4,8,1,2,9],well:[4,8,1,2,9],spent:4,thought:1,tie:1,without:[4,3],uint32_t:4,choos:8,programm:[4,8,2],everyth:[8,2],woburn:3,dimension:1,left:4,stringent:9,identifi:[4,8,1,2,7],cout:[4,8,2],just:1,hierarch:1,obtain:4,rest:4,bandwidth:9,via:[4,1,9],virtual:[4,1],aspect:[4,1,9,10],simd:5,regardless:[4,1],speed:9,yet:[4,8,2],languag:[1,2,4,7,6,5,8,10],wether:4,web:3,gather:4,struct:[8,1,2],expos:4,readcondit:4,interfer:9,copi:4,point:[4,8,1,2,7],priorit:9,except:1,param:[4,1],sullivan:5,other:[4,8,1,2],primit:[8,1,2],role:[4,9],dispose_inst:4,subsequ:[4,9],int32_t:1,match:[4,8,1,2,9],build:[8,1,2,9],real:[8,2,5],applic:[1,2,4,7,8,9],vendor:[8,1,2],psm:5,preserv:9,big:4,regard:[4,8,1,2],adlinktech:[10,3],arriv:9,datawriter_qo:9,temperatur:[4,8,1,2],traffic:[8,2,9],know:4,elabor:9,guid:7,world:[8,2],bit:[1,5],wallnau:5,formal:[8,2],loanedsampl:4,resid:4,like:[4,8,1,2],specif:[1,2,4,7,5,8,9],arbitrari:[8,1,2],oseq:1,corpor:3,johann:5,integ:[8,2],c1d:1,neccessari:1,vortex:[10,7],"boolean":1,necessari:[4,1,10],either:[4,1],region:4,mcgraw:5,srcreader:4,inter:9,prior:4,manag:[0,2,9,6,5,8],emerg:[8,2],underli:4,jean:3,www:[5,3],right:[4,9],often:[4,9],urgenc:9,what:[4,8,1,2],acknowledg:3,twitter:3,linux:7,some:[1,2,4,8,9,10],back:4,certain:[4,1],thread:4,intern:3,enumer:[8,1,2],sampl:[0,2,9,8],act:4,respect:[4,1],sen:1,guarante:[8,2],server:[8,2,9],constitut:9,transport:6,alive_instance_st:4,poll:[4,8,2],cooper:9,pinpoint:4,lead:4,scala:[8,2],supervisori:[8,2],leak:4,avoid:[4,8,2],though:1,octet:[1,9],thank:1,overlap:4,summar:4,datawrit:[4,8,1,2,9],track:1,evolv:[8,2],leav:[4,8,2,9],middlewar:[4,1],sequenc:[8,1,2,9],keylesstempsensortyp:1,condit:[4,1],gosl:5,reproduc:3,tempsensorlisten:4,refer:[8,1,2],machin:[8,2],core:[4,8,2,9],plu:1,object:[1,2,4,6,5,8],run:[1,2,4,7,8,9,10],power:[4,8,2,9],emul:1,late:[4,9],"enum":[8,1,2],usag:[4,1,9],broker:6,noisi:9,who:[8,2,7],step:[8,1,2],topicqo:9,although:[4,8,1,2,10],found:[4,8,2],post:1,wire:[8,2,6,5],chapter:[4,8,1,2,9],faith:3,about:[8,2],rare:4,would:[4,8,1,2],datast:4,linger:5,noopdatareaderlisten:4,processor:[8,2],memori:[1,9],slightli:[8,2],acm:5,page:[0,5],kazman:5,union:[8,1,2],degre:1,coord1d:1,includ:[1,2,4,7,8,9],done:[4,8,1,2],commerci:10,commit:4,industri:[8,2,6],actuat:[8,2],produc:[8,1,2,9],block:[0,2,8],glanc:[8,2],routin:[8,2],doubl:1,effici:[4,8,1,2],opensplic:[0,1,2,3,4,5,6,7,8,9,10],devic:9,logdatapartit:1,within:[1,9],encod:[8,1,2],orsai:3,automat:[0,2,9,8],compos:[8,2],down:9,creativ:3,polyglot:[8,2],been:[4,8,1,2],ensur:[4,8,2,9],pollak:5,storag:[4,9],your:[4,8,1,2],durabl:9,per:1,c4d:1,inclus:[4,1],fast:[8,2],span:9,carnegi:5,few:4,oseq1k:1,captur:[8,2],question:[4,8,2],iter:0,sei:5,custom:4,avail:[0,10,2,8,3],start:[8,1,2,9,7],reli:[8,1,2,9],trigger:4,uml:6,low:[8,2,9],instancest:4,suit:3,forward:4,icon:7,interv:9,select:[0,2,9,8],deliveri:0,homogen:1,creation:[8,1,2],form:[8,2],offer:9,great:9,basic:[4,1],amongst:1,idea:4,java5:[8,5],diffus:9,link:[1,9],adlink:[7,1,3],ospl:5,new_view:4,compil:[4,8,1,2,10],highest:9,"true":[8,2],not_read:4,faster:9,info:4,made:[1,2,3,4,8,9],consist:1,understood:[8,2],"default":[4,8,2,9],wish:7,best:4,maximum:[1,9],lifespan:9,tell:4,asynchron:[4,8,2],insert:4,below:[8,1,2,9,7],instancehandl:4,limit:[8,1,2,9,3],problem:1,remaind:9,similar:[4,1],reliabl:9,expect:[4,1],bibsonomi:5,creat:[4,8,1,2,9],"int":[4,1],request:[4,9,6],data_avail:4,repres:[8,1,2,9],"char":[4,1],proper:[8,2],ddsi:[8,2,6,5],multiplex:1,not_alive_no_writ:4,file:[8,2,9],int64_t:1,unregister_inst:4,improv:9,check:1,again:[4,1],peter:5,googl:[1,5],floor:[8,1,2,9],best_effort:9,hpp:4,when:[4,8,1,2,9],detail:[4,8,2],iot:[8,2,6],orient:[4,1],field:1,possibl:[4,8,1,2,9],valid:[4,8,2,9],lookup:4,futur:[4,5],varieti:4,bibtex:5,you:[1,2,4,8,9,10],telemetri:[8,1,2,6],architectur:[8,2,6],node:4,commandpartit:1,claus:1,intend:[4,8,2,7],registri:[8,2,6],bisampl:4,polymorph:5,"class":[4,8,1,2],time:[1,2,4,5,8,9,10],june:5,powergrid:5,scale:[1,2,4,6,5,8,9],intent:4,embed:[1,9],consid:[4,1,9],sql:[1,6],previous:4,fsampl:4,singleton:[4,1],gilad:5,legal:[4,1],experienc:[8,2],receiv:[4,8,1,2],longer:4,furthermor:1,chrono:[4,8,2],cycl:[0,2,8],descript:7,discrimin:4,mimic:1,"transient":9,gracefulli:4,had:4,institut:5,cpp:10,slice:1,profil:[8,2,9],cfttempsensor:1},objtypes:{},objnames:{},filenames:["index","topics-etc","foundations_2","contacts","readandwrite","biblio","acronyms","preface","foundations","qos","appendix-A"],titles:["The Data Distribution Service Tutorial","2. Topics, Domains and Partitions","Foundations","8. Contacts & Notices","3. Reading and Writing Data","7. Bibliography","6. Acronyms & Abbreviations","Preface","1. Foundations","4. Quality of Service","5. Appendix A"],objects:{},titleterms:{keyless:4,domain:[8,1,2],code:10,consider:10,global:[8,2],foundat:[8,2],life:4,indic:0,topic:[4,8,1,2],set:9,sampl:[4,1],tabl:0,onlin:10,select:4,notifi:4,avail:9,insid:1,convent:7,space:[8,2],write:[4,8,2],configur:9,particip:[8,2],abbrevi:6,content:[4,1],acronym:6,state:4,contact:3,bibliographi:5,take:4,scope:1,waitset:4,out:1,type:1,listen:4,deliveri:9,non:4,sourc:10,omg:[8,2],distribut:[0,2,8],kei:1,get:10,read:[4,8,2],qualiti:9,exampl:10,notic:3,standard:[8,2],cycl:4,appendix:10,nutshel:[8,2],automat:4,base:4,resourc:[9,10],data:[4,0,2,9,8],implement:10,wait:4,prefac:7,about:7,instanc:[4,1],timeli:9,servic:[0,2,9,8],access:4,explicit:4,iter:4,tutori:[0,7],filter:1,inform:1,meta:4,partit:1,contain:4,model:9,manag:4,block:4,summari:[4,8,1,2,9]}}) \ No newline at end of file diff --git a/docs/html/DDSTutorial/topics-etc.html b/docs/html/DDSTutorial/topics-etc.html index 873cec2e7..50cc37da4 100644 --- a/docs/html/DDSTutorial/topics-etc.html +++ b/docs/html/DDSTutorial/topics-etc.html @@ -67,7 +67,7 @@

      2.1.1. Topic TypesIDL, XML. -Some vendors, such as PrismTech, also support +Some vendors, such as ADLINK, also support Google Protocol Buffers.

      This Tutorial will focus on the subset of IDL that can be used to define a topic type. A topic type is made with an IDL struct plus a key. @@ -610,7 +610,7 @@

      Navigation

      \ No newline at end of file diff --git a/docs/html/DeploymentGuide/_sources/contacts.txt b/docs/html/DeploymentGuide/_sources/contacts.txt index 0f2f36ea3..d32f6016f 100644 --- a/docs/html/DeploymentGuide/_sources/contacts.txt +++ b/docs/html/DeploymentGuide/_sources/contacts.txt @@ -1,47 +1 @@ -.. _`Contacts & Notices`: - -################## -Contacts & Notices -################## - -******** -Contacts -******** - -| **PrismTech Corporation** -| 400 TradeCenter -| Suite 5900 -| Woburn, MA -| 01801 -| USA -| Tel: +1 781 569 5819 - -| **PrismTech Limited** -| PrismTech House -| 5th Avenue Business Park -| Gateshead -| NE11 0NG -| UK -| Tel: +44 (0)191 497 9900 - -| **PrismTech France** -| 28 rue Jean Rostand -| 91400 Orsay -| France -| Tel: +33 (1) 69 015354 - - -Web: http://www.prismtech.com - -E-mail: \info@prismtech.com - -******* -Notices -******* - -**Copyright** © 2016 PrismTech Limited. All rights reserved. - -*This document may be reproduced in whole but not in part. -The information contained in this document is subject to change without notice and is made available in good faith without liability on the part of PrismTech Limited or PrismTech Corporation. -All trademarks acknowledged.* - +.. include:: ../../common/contacts.rst diff --git a/docs/html/DeploymentGuide/_sources/ddsi2-networking-service.txt b/docs/html/DeploymentGuide/_sources/ddsi2-networking-service.txt index 877ccdcb6..8f39774f9 100644 --- a/docs/html/DeploymentGuide/_sources/ddsi2-networking-service.txt +++ b/docs/html/DeploymentGuide/_sources/ddsi2-networking-service.txt @@ -37,7 +37,7 @@ giving extra features for: options can be controlled. The remainder of this section gives background on these two services and describes -how the various mechanisms and their configuration parameters interact. +how the various mechanisms and their configuration parameters interact. Please refer to the :ref:`Configuration ` section fully-detailed descriptions of: @@ -50,15 +50,15 @@ section fully-detailed descriptions of: DDSI Concepts ************* -The DDSI 2.1 standard is very intimately related to the DDS 1.2 standard, with a -clear correspondence between the entities in DDSI and those in DCPS. However, -this correspondence is not one-to-one. +Both DDSI 2.1 and 2.2 standards are very intimately related to the DDS 1.2 and 1.4 +standards, with a clear correspondence between the entities in DDSI and those in DCPS. +However, this correspondence is not one-to-one. In this section we give a high-level description of the concepts of the DDSI -specification, with hardly any reference to the specifics of the OpenSplice +specification, with hardly any reference to the specifics of the Vortex OpenSplice implementation, DDSI2, which are addressed in subsequent sections. This division was chosen to aid readers interested in interoperability to understand -where the specification ends and the OpenSplice implementation begins. +where the specification ends and the Vortex OpenSplice implementation begins. .. _`Mapping of DCPS domains to DDSI domains`: @@ -70,7 +70,7 @@ In DCPS, a domain is uniquely identified by a non-negative integer, the domain i DDSI maps this domain id to UDP/IP port numbers to be used for communicating with the peer nodes — these port numbers are particularly important for the discovery protocol — and this mapping of domain ids to UDP/IP port numbers -ensures that accidental cross-domain communication is impossible with the +ensures that accidental cross-domain communication is impossible with the default mapping. DDSI does not communicate the DCPS port number in the discovery protocol; it @@ -155,23 +155,23 @@ DDSI-specific transient-local behaviour ======================================= The above describes the essentials of the mechanism used for samples of the -*‘volatile’* durability kind, but the DCPS specification also provides -*‘transient-local’*, *‘transient’* and *‘persistent’* data. Of these, the -DDSI specification currently only covers *transient-local*, and this is +*‘volatile’* durability kind, but the DCPS specification also provides +*‘transient-local’*, *‘transient’* and *‘persistent’* data. Of these, the +DDSI specification currently only covers *transient-local*, and this is the only form of durable data available when interoperating across vendors. In DDSI, transient-local data is implemented using the WHC that is normally used for reliable communication. For transient-local data, samples are retained even when all readers have acknowledged them. With the default history setting of -``KEEP_LAST`` with ``history_depth = 1``, this means that late-joining readers +``KEEP_LAST`` with ``history_depth = 1``, this means that late-joining readers can still obtain the latest sample for each existing instance. Naturally, once the DCPS writer is deleted (or disappears for whatever reason), the DDSI writer disappears as well, and with it, its history. For this reason, transient -data is generally much to be preferred over transient-local data. In OpenSplice the +data is generally much to be preferred over transient-local data. In Vortex OpenSplice the durability service implements all three durability kinds without requiring any -special support from the networking services, ensuring that the full set of -durability features is always available between OpenSplice nodes. +special support from the networking services, ensuring that the full set of +durability features is always available between Vortex OpenSplice nodes. .. _`Discovery of participants & endpoints`: @@ -183,7 +183,7 @@ DDSI participants discover each other by means of the *‘Simple Participant Discovery Protocol’*, or *‘SPDP*’ for short. This protocol is based on periodically sending a message containing the specifics of the participant to a set of known addresses. By default, this is a standardised multicast address (``239.255.0.1``; -the port number is derived from the domain id) that all DDSI implementations +the port number is derived from the domain id) that all DDSI implementations listen to. Particularly important in the SPDP message are the unicast and multicast addresses @@ -215,34 +215,34 @@ now received the complete set. |info| Note that the discovery process necessarily creates a burst of traffic each time - a participant is added to the system: *all* existing participants respond to the + a participant is added to the system: *all* existing participants respond to the SPDP message, following which all start exchanging SEDP data. -.. _`OpenSplice DDSI2 specifics`: +.. _`Vortex OpenSplice DDSI2 specifics`: -OpenSplice DDSI2 specifics -************************** +Vortex OpenSplice DDSI2 specifics +********************************* -.. _`Translating between OpenSplice and DDSI`: +.. _`Translating between Vortex OpenSplice and DDSI`: -Translating between OpenSplice and DDSI -======================================= +Translating between Vortex OpenSplice and DDSI +============================================== Given that DDSI is the DDS interoperability specification, that the mapping -between DCPS entities and DDSI entities is straightforward, and that OpenSplice is +between DCPS entities and DDSI entities is straightforward, and that Vortex OpenSplice is a full implementation of the DDS specification, one might expect that relationship -between OpenSplice and its DDSI implementation, DDSI2, is trivial. Unfortunately, +between Vortex OpenSplice and its DDSI implementation, DDSI2, is trivial. Unfortunately, this is not the case, and it does show in a number of areas. A high-level overview -such as this paragraph is not the place for the details of these cases, but they +such as this paragraph is not the place for the details of these cases, but they will be described in due course. The root cause of these complexities is a difference in design philosophy between -OpenSplice and the more recent DDSI. +Vortex OpenSplice and the more recent DDSI. DDSI is very strictly a *peer-to-peer* protocol at the level of individual endpoints, requiring lots of discovery traffic, and (at least when implemented naively) very bad -scalability. It is exactly these three problems that OpenSplice was designed to avoid, +scalability. It is exactly these three problems that Vortex OpenSplice was designed to avoid, and it does so successfully with its native *RTNetworking* service. Because of this design for scalability and the consequent use of service processes @@ -251,7 +251,7 @@ various ways in which DDSI2 has to translate between the two worlds. For example queuing and buffering and, consequently, blocking behaviour are subtly different; DDSI2 needs to also perform local discovery of DCPS endpoints to gather enough information for faithfully representing the system in terms of DDSI, it needs to -translate between completely different namespaces (native OpenSplice identifiers +translate between completely different namespaces (native Vortex OpenSplice identifiers are very different from the GUIDs used by DDSI), and it needs to work around receiving asynchronous notifications for events one would expect to be synchronous in DDSI. @@ -266,20 +266,20 @@ Federated versus Standalone deployment ====================================== As has been described elsewhere (see the :ref:`Overview ` in this -*Guide* and also the *Getting Started Guide*), OpenSplice has multiple -deployment models selectable in the configuration file (some of these require +*Guide* and also the *Getting Started Guide*), Vortex OpenSplice has multiple +deployment models selectable in the configuration file (some of these require a license). For DDSI2, there is no difference between the various models: it simply serves whatever DCPS participants are in the same ‘instance’, whether that instance be a federation of processes on a single node, all attached to a shared memory segment -managed by a set of OpenSplice service processes on that node, or a standalone one -in which a single process incorporates the OpenSplice services as libraries. +managed by a set of Vortex OpenSplice service processes on that node, or a standalone one +in which a single process incorporates the Vortex OpenSplice services as libraries. This *Guide* ignores the various deployment modes, using the terminology associated with the federated deployment mode because that mode is the driving force behind several of the user-visible design decisions in DDSI2. In consequence, -for a standalone deployment, the term *‘node’* as used in this *Guide* refers +for a standalone deployment, the term *‘node’* as used in this *Guide* refers to a single process. @@ -305,10 +305,10 @@ is to instruct DDSI2 to completely ignore them using the DCPS topic/partition to network partition mapping available in the enhanced version, DDSI2E. A separate issue is that of the DCPS built-in topics when interoperating with other -implementations. In OpenSplice the built-in topics are first-class topics, *i.e.* the -only difference between application topics and the built-in topics in OpenSplice is +implementations. In Vortex OpenSplice the built-in topics are first-class topics, *i.e.* the +only difference between application topics and the built-in topics in Vortex OpenSplice is that the built-in topics are pre-defined and that they are published and used by the -OpenSplice services. This in turn allows the RTNetworking service to avoid +Vortex OpenSplice services. This in turn allows the RTNetworking service to avoid discovery of individual domain participants and endpoints, enabling its excellent scalability. @@ -320,7 +320,7 @@ this also means that the DCPS built-in topics become a special case. Taken together, DDSI2 is in the unfortunate situation of having to straddle two very different approaches. While local reconstruction of the DCPS built-in topics by DDSI2 is clearly possible, it would negatively impact the handling of transient data. -Since handling transient data is one of the true strengths of OpenSplice, DDSI2 +Since handling transient data is one of the true strengths of Vortex OpenSplice, DDSI2 currently does not perform this reconstruction, with the unfortunate implication that loss of liveliness will not be handled fully when interoperating with another DDSI implementation. @@ -370,11 +370,11 @@ Instead of implementing the protocol as suggested by the standard, DDSI2 shares discovery activities amongst the participants, allowing one to add participants on a node with only a minimal impact on the system. It is even possible to have only a single DDSI participant on each node, which then becomes the virtual owner of all -the endpoints serviced by that instance of DDSI2. (See +the endpoints serviced by that instance of DDSI2. (See `Combining multiple participants`_ and refer to the :ref:`Configuration ` section for a detailed description of -``//OpenSplice/DDSI2Service/Internal/SquashParticipants``.) In this latter mode, -there is no discovery penalty at all for having many participants, but evidently, +``//OpenSplice/DDSI2Service/Internal/SquashParticipants``.) In this latter mode, +there is no discovery penalty at all for having many participants, but evidently, any participant-based liveliness monitoring will be affected. Because other implementations of the DDSI specification may be written on the @@ -384,10 +384,10 @@ participant independently, but it will generate the network traffic *as if* it d Please refer to the :ref:`Configuration ` section for detailed descriptions of: -+ ``//OOpenSplice/DDSI2Service/Internal/BuiltinEndpointSet`` ++ ``//OpenSplice/DDSI2Service/Internal/BuiltinEndpointSet`` + ``//OpenSplice/DDSI2Service/Internal/ConservativeBuiltinReaderStartup`` -However, please note that at the time of writing, we are not aware of any +However, please note that at the time of writing, we are not aware of any DDSI implementation requiring the use of these settings.) By sharing the discovery information across all participants in a single node, each @@ -410,7 +410,7 @@ When an application deletes a reliable DCPS data writer, there is no guarantee t all its readers have already acknowledged the correct receipt of all samples. In such a case, DDSI2 lets the writer (and the owning participant if necessary) linger in the system for some time, controlled by the ``Internal/WriterLingerDuration`` option. -The writer is deleted when all samples have been acknowledged by all readers or +The writer is deleted when all samples have been acknowledged by all readers or the linger duration has elapsed, whichever comes first. The writer linger duration setting is currently not applied when DDSI2 is requested @@ -475,7 +475,7 @@ Writer history QoS and throttling The DDSI specification heavily relies on the notion of a writer history cache (WHC) within which a sequence number uniquely identifies each sample. The original -OpenSplice design has a different division of responsibilities between various +Vortex OpenSplice design has a different division of responsibilities between various components than what is assumed by the DDSI specification and this includes the WHC. Despite the different division, the resulting behaviour is the same. @@ -493,18 +493,18 @@ The index on sequence number is required for retransmitting old data, and is therefore needed for all reliable writers. The index on key values is always needed for transient-local data, and can optionally be used for other writers using a history setting of ``KEEP_LAST`` with depth ``1``. (The ``Internal/AggressiveKeepLast1Whc`` -setting controls this behaviour.) The advantage of an index on key value in such -a case is that superseded samples can be dropped aggressively, instead of having -to deliver them to all readers; the disadvantage is that it is somewhat more +setting controls this behaviour.) The advantage of an index on key value in such +a case is that superseded samples can be dropped aggressively, instead of having +to deliver them to all readers; the disadvantage is that it is somewhat more resource-intensive. Writer throttling is based on the WHC size using a simple bang-bang controller. Once the WHC contains ``Internal/Watermarks/WhcHigh`` bytes in -unacknowledged samples, it stalls the writer until the number of bytes in +unacknowledged samples, it stalls the writer until the number of bytes in unacknowledged samples drops below ``Internal/Watermarks/WhcLow``. While ideally only the one writer would be stalled, the interface between the -OpenSplice kernel and DDSI2 is such that other outgoing traffic may be stalled as +Vortex OpenSplice kernel and DDSI2 is such that other outgoing traffic may be stalled as well. See `Unresponsive readers & head-of-stream blocking`_. Please refer to the :ref:`Configuration ` section for @@ -523,12 +523,12 @@ Unresponsive readers & head-of-stream blocking For reliable communications, DDSI2 must retain sent samples in the WHC until they have been acknowledged. Especially in case of a ``KEEP_ALL`` history kind, but also in the default case when the WHC is not aggressively dropping old samples of -instances (``Internal/AggressiveKeepLast1Whc``), a reader that fails to acknowledge +instances (``Internal/AggressiveKeepLast1Whc``), a reader that fails to acknowledge the samples timely will cause the WHC to run into resource limits. The correct treatment suggested by the DDS specification is to simply take the writer history QoS setting, apply this to the DDSI2 WHC, and block the writer up to -its ‘max_blocking_time’ QoS setting. However, the scalable architecture of +its ‘max_blocking_time’ QoS setting. However, the scalable architecture of Vortex OpenSplice renders this simple approach infeasible because of the division of labour between the application processes and the various services. Of course, even if it were a possible approach, the problem would still not be gone entirely, as one @@ -539,8 +539,8 @@ writer is a critical one. Because of this, once DDSI2 hits a resource limit on a WHC, it blocks the sequence of outgoing samples for up to ``Internal/ResponsivenessTimeout``. If this timeout is set larger than roughly the domain expiry time -(``//OpenSplice/Domain/Lease/ExpiryTime``), it may cause entire nodes to lose -liveliness. The enhanced version, DDSI2E, has the ability to use multiple queues +(``//OpenSplice/Domain/Lease/ExpiryTime``), it may cause entire nodes to lose +liveliness. The enhanced version, DDSI2E, has the ability to use multiple queues and can avoid this problem; please refer to `Channel configuration`_. Any readers that fail to acknowledge samples in time will be marked ‘unresponsive’ @@ -584,14 +584,14 @@ Handling of multiple partitions and wildcards Publishing in multiple partitions --------------------------------- -A variety of design choices allow OpenSplice in combination with its +A variety of design choices allow Vortex OpenSplice in combination with its RTNetworking service to be fully dynamically discovered, yet without requiring an expensive discovery protocol. A side effect of these choices is that a DCPS writer publishing a single sample in multiple partitions simultaneously will be translated by the current version of DDSI2 as a writer publishing multiple identical samples in all these partitions, but with unique sequence numbers. -When DDSI2 is used to communicate between OpenSplice nodes, this is not an +When DDSI2 is used to communicate between Vortex OpenSplice nodes, this is not an application-visible issue, but it is visible when interoperating with other implementations. Fortunately, publishing in multiple partitions is rarely a wise choice in a system design. @@ -612,7 +612,7 @@ partition wildcards for publishing data can easily lead to the replication of da mentioned in the previous subsection (`Publishing in multiple partitions`_). Secondly, because DDSI2 implements transient-local data internally in a different -way from the way the OpenSplice durability service does, it is strongly +way from the way the Vortex OpenSplice durability service does, it is strongly recommended that the combination of transient-local data and publishing using partition wildcards be avoided completely. @@ -627,8 +627,8 @@ Network and discovery configuration Networking interfaces ===================== -DDSI2 uses a single network interface, the *‘preferred’* interface, for transmitting -its multicast packets and advertises only the address corresponding to this interface +DDSI2 uses a single network interface, the *‘preferred’* interface, for transmitting +its multicast packets and advertises only the address corresponding to this interface in the DDSI discovery protocol. To determine the default network interface, DDSI2 ranks the eligible interfaces by @@ -637,7 +637,7 @@ are of the highest quality, it will select the first enumerated one. Eligible in are those that are up and have the right kind of address family (IPv4 or IPv6). Priority is then determined as follows: -+ interfaces with a non-link-local address are preferred over those with ++ interfaces with a non-link-local address are preferred over those with a link-local one; + multicast-capable is preferred, or if none is available + non-multicast capable but neither point-to-point, or if none is available @@ -700,19 +700,19 @@ DDSI2 allows configuring to what extent multicast is to be used: It is advised to allow multicasting to be used. However, if there are restrictions on the use of multicasting, or if the network reliability is dramatically different for multicast than for unicast, it may be attractive to disable multicast for normal -communications. In this case, setting ``General/AllowMulticast`` to ``false`` will -force DDSI2 to use unicast communications for everything except the periodic +communications. In this case, setting ``General/AllowMulticast`` to ``false`` will +force DDSI2 to use unicast communications for everything except the periodic distribution of the participant discovery messages. -If at all possible, it is strongly advised to leave multicast-based participant -discovery enabled, because that avoids having to specify a list of nodes to -contact, and it furthermore reduces the network load considerably. However, -if need be, one can disable the participant discovery from sending multicasts +If at all possible, it is strongly advised to leave multicast-based participant +discovery enabled, because that avoids having to specify a list of nodes to +contact, and it furthermore reduces the network load considerably. However, +if need be, one can disable the participant discovery from sending multicasts by setting ``Internal/SuppressSpdpMulticast`` to ``true``. -To disable incoming multicasts, or to control from which interfaces multicasts are +To disable incoming multicasts, or to control from which interfaces multicasts are to be accepted, one can use the ``General/MulticastRecvInterfaceAddresses`` setting. -This allows listening on no interface, the preferred, all or a specific set +This allows listening on no interface, the preferred, all or a specific set of interfaces. Please refer to the :ref:`Configuration ` section for @@ -734,7 +734,7 @@ Discovery addresses ................... The DDSI discovery protocols, SPDP for the domain participants and SEDP for -their endpoints, usually operate well without any explicit configuration. +their endpoints, usually operate well without any explicit configuration. Indeed, the SEDP protocol never requires any configuration. DDSI2 by default uses the domain id as specified in ``//OpenSplice/Domain/Id`` @@ -767,7 +767,7 @@ making this rather wasteful behaviour. DDSI2 allows explicitly adding a port number to the IP address, formatted as IP:PORT, to avoid this waste, but this requires manually calculating the port number. In practice it also requires fixing the participant index using -``Discovery/ParticipantIndex`` (see the description of ‘PI’ in +``Discovery/ParticipantIndex`` (see the description of ‘PI’ in `Controlling port numbers`_) to ensure that the configured port number indeed corresponds to the remote DDSI2 (or other DDSI implementation), and therefore is really practicable only in a federated deployment. @@ -790,8 +790,8 @@ Asymmetrical discovery On reception of an SPDP packet, DDSI2 adds the addresses advertised in that SPDP packet to this set, allowing asymmetrical discovery. In an extreme example, if SPDP -multicasting is disabled entirely, host A has the address of host B in its peer list -and host B has an empty peer list, then B will eventually discover A because of an +multicasting is disabled entirely, host A has the address of host B in its peer list +and host B has an empty peer list, then B will eventually discover A because of an SPDP message sent by A, at which point it adds A’s address to its own set and starts sending its own SPDP message to A, allowing A to discover B. This takes a bit longer than normal multicast based discovery, though. @@ -814,7 +814,7 @@ Endpoint discovery .................. Although the SEDP protocol never requires any configuration, the network -partitioning of OpenSplice DDSI2E does interact with it: so-called ‘ignored +partitioning of Vortex OpenSplice DDSI2E does interact with it: so-called ‘ignored partitions’ can be used to instruct DDSI2 to completely ignore certain DCPS topic and partition combinations, which will prevent DDSI2 from forwarding data for these topic/partition combinations to and from the network. @@ -830,20 +830,20 @@ DDSI2. Combining multiple participants =============================== -In an OpenSplice standalone deployment the various configured services, such as +In a Vortex OpenSplice standalone deployment the various configured services, such as spliced and DDSI2, still retain their identity by creating their own DCPS domain participants. DDSI2 faithfully mirrors all these participants in DDSI, and it will appear at the DDSI level as if there is a large system with many participants, whereas in reality there are only a few application participants. -The ``Internal/SquashParticipants`` option can be used to simulate the existence -of only one participant, the DDSI2 service itself, which owns all endpoints on -that node. This reduces the background messages because far fewer liveliness +The ``Internal/SquashParticipants`` option can be used to simulate the existence +of only one participant, the DDSI2 service itself, which owns all endpoints on +that node. This reduces the background messages because far fewer liveliness assertions need to be sent. Clearly, the liveliness monitoring features that are related to domain participants will be affected if multiple DCPS domain participants are combined into a single -DDSI domain participant. The OpenSplice services all use a liveliness QoS setting +DDSI domain participant. The Vortex OpenSplice services all use a liveliness QoS setting of AUTOMATIC, which works fine. In a federated deployment, the effect of this option is to have only a single DDSI @@ -851,10 +851,10 @@ domain participant per node. This is of course much more scalable, but in no way resembles the actual structure of the system if there are in fact multiple application processes running on that node. -However, in OpenSplice the built-in topics are not derived from the DDSI -discovery, and hence in an OpenSplice-only network the use of the -``Internal/SquashParticipants`` setting will not result in any loss of information -in the DCPS API or in the OpenSplice tools such as the Tester. +However, in Vortex OpenSplice the built-in topics are not derived from the DDSI +discovery, and hence in a Vortex OpenSplice-only network the use of the +``Internal/SquashParticipants`` setting will not result in any loss of information +in the DCPS API or in the Vortex OpenSplice tools such as the Tester. When interoperability with another vendor is not needed, enabling the ``SquashParticipants`` option is often a good choice. @@ -877,7 +877,7 @@ of serving multiple participants by a single DDSI instance: + 2 ‘well-known’ multicast ports: ``B`` and ``B+1`` + 2 unicast ports at which only this instance of DDSI2 is listening: ``B+PG*PI+10`` and ``B+PG*PI+11`` -+ 1 unicast port per domain participant it serves, chosen by the kernel ++ 1 unicast port per domain participant it serves, chosen by the kernel from the anonymous ports, *i.e.* >= 32768 where: @@ -889,8 +889,8 @@ where: The default values, taken from the DDSI specification, are in parentheses. There are actually even more parameters, here simply turned into constants as there is -absolutely no point in ever changing these values; however, they *are* configurable -and the interested reader is referred to the DDSI 2.1 specification, section 9.6.1. +absolutely no point in ever changing these values; however, they *are* configurable +and the interested reader is referred to the DDSI 2.1 or 2.2 specification, section 9.6.1. PI is the most interesting, as it relates to having multiple instances of DDSI2 in the same domain on a single node. In a federated deployment, this never happens @@ -913,7 +913,7 @@ non-negative integer. This setting matters: alternative is hardly useful. Clearly, to fully control port numbers, setting ``Discovery/ParticipantIndex`` (= PI) -to a hard-coded value is the only possibility. In a federated deployment this is an +to a hard-coded value is the only possibility. In a federated deployment this is an option that has very few downsides, and generally ``0`` will be a good choice. By fixing PI, the port numbers needed for unicast discovery are fixed as well. This @@ -949,15 +949,15 @@ detailed descriptions of: + ``//OpenSplice/DDSI2Service/Compatibility/ManySocketsMode`` -.. _`Coexistence with OpenSplice RTNetworking`: +.. _`Coexistence with Vortex OpenSplice RTNetworking`: -Coexistence with OpenSplice RTNetworking +Coexistence with Vortex OpenSplice RTNetworking ======================================== -DDSI2 has a special mode, configured using ``General/CoexistWithNativeNetworking``, -to allow it to operate in conjunction with OpenSplice RTNetworking: in this mode -DDSI2 only handles packets sent by other vendors’ implementations, allowing all -intra-OpenSplice traffic to be handled by the RTNetworking service while still +DDSI2 has a special mode, configured using ``General/CoexistWithNativeNetworking``, +to allow it to operate in conjunction with Vortex OpenSplice RTNetworking: in this mode +DDSI2 only handles packets sent by other vendors’ implementations, allowing all +intra-Vortex OpenSplice traffic to be handled by the RTNetworking service while still providing interoperability with other vendors. Please refer to the :ref:`Configuration ` section for @@ -977,7 +977,7 @@ Data path architecture ====================== The data path in DDSI2 consists of a transmitting and a receiving side. The main -path in the transmit side accepts data to be transmitted from the OpenSplice kernel +path in the transmit side accepts data to be transmitted from the Vortex OpenSplice kernel *via* a network queue and administrates and formats the data for transmission over the network. @@ -987,9 +987,9 @@ to writers, in addition to handling the retransmission of old data on request. T requests can originate in packet loss, but also in requests for historical data from transient-local readers. -The diagram `Data flow using two channels`_ gives an overview of the main data -flow and the threads in a configuration using two channels. Configuring multiple -channels is an enhanced feature that is available only in DDSI2E, but the +The diagram `Data flow using two channels`_ gives an overview of the main data +flow and the threads in a configuration using two channels. Configuring multiple +channels is an enhanced feature that is available only in DDSI2E, but the principle is the same in both variants. .. _`Data flow using two channels`: @@ -1020,7 +1020,7 @@ restricted to what in DDSI2E is the default channel if none are configured expli For details on configuring channels, see `Channel configuration`_. Each channel has its own transmit thread, draining a queue with samples to be -transmitted from the OpenSplice kernel. The maximum size of the queue can be +transmitted from the Vortex OpenSplice kernel. The maximum size of the queue can be configured per channel, and the default for the individual channels is configured using the ``Sizing/NetworkQueueSize`` setting. In DDSI2, this setting simply controls the queue size, as the default channel of DDSI2E has the default queue size. A larger @@ -1030,7 +1030,7 @@ bursts. Once a networking service has taken a sample from the queue, it takes responsibility for it. Consequently, if it is to be sent reliably and there are insufficient resources to -store it in the WHC, it must wait for resources to become available. +store it in the WHC, it must wait for resources to become available. See `Unresponsive readers & head-of-stream blocking`_. The DDSI control messages (Heartbeat, AckNack, *etc.*) are sent by a thread @@ -1059,9 +1059,9 @@ retransmissions too often, in an interoperable system the writers should be robu against it. In DDSI2, upon receiving a Heartbeat that indicates samples are missing, a reader -will schedule a retransmission request to be sent after ``Internal/NackDelay``, -or combine it with an already scheduled request if possible. Any samples received -in between receipt of the Heartbeat and the sending of the AckNack will not need +will schedule a retransmission request to be sent after ``Internal/NackDelay``, +or combine it with an already scheduled request if possible. Any samples received +in between receipt of the Heartbeat and the sending of the AckNack will not need to be retransmitted. Secondly, a writer attempts to combine retransmit requests in two different ways. @@ -1069,10 +1069,10 @@ The first is to change messages from unicast to multicast when another retransmi request arrives while the retransmit has not yet taken place. This is particularly effective when bandwidth limiting causes a backlog of samples to be retransmitted. The behaviour of the second can be configured using the ``Internal/RetransmitMerging`` -setting. Based on this setting, a retransmit request for a sample is either honoured -unconditionally, or it may be suppressed (or ‘merged’) if it comes in shortly after -a multicasted retransmission of that very sample, on the assumption that the second -reader will likely receive the retransmit, too. The ``Internal/RetransmitMergingPeriod`` +setting. Based on this setting, a retransmit request for a sample is either honoured +unconditionally, or it may be suppressed (or ‘merged’) if it comes in shortly after +a multicasted retransmission of that very sample, on the assumption that the second +reader will likely receive the retransmit, too. The ``Internal/RetransmitMergingPeriod`` controls the length of this time window. Please refer to the :ref:`Configuration ` section for @@ -1103,10 +1103,10 @@ settings governing the size of these queues, and the limits are applied per timed-event thread (*i.e.* the global one, and typically one for each configured channel with limited bandwidth when using DDSI2E). The first is ``Internal/MaxQueuedRexmitMessages``, which limits the number of retransmit -messages, the second ``Internal/MaxQueuedRexmitBytes`` which limits the number of +messages, the second ``Internal/MaxQueuedRexmitBytes`` which limits the number of bytes. The latter is automatically set based on the combination -of the allowed transmit bandwidth and the ``Internal/NackDelay`` setting, as an -approximation of the likely time until the next potential retransmit request +of the allowed transmit bandwidth and the ``Internal/NackDelay`` setting, as an +approximation of the likely time until the next potential retransmit request from the reader. Please refer to the :ref:`Configuration ` section for @@ -1129,16 +1129,16 @@ network packets. The DDSI specification states that one must not unnecessarily fragment at the DDSI level, but DDSI2 simply provides a fully configurable behaviour. -If the serialised form of a sample is at least ``Internal/FragmentSize``, -it will be fragmented using the DDSI fragmentation. All but the last fragment +If the serialised form of a sample is at least ``Internal/FragmentSize``, +it will be fragmented using the DDSI fragmentation. All but the last fragment will be exactly this size; the last one may be smaller. Control messages, non-fragmented samples, and sample fragments are all subject to packing into datagrams before sending it out on the network, based on various attributes such as the destination address, to reduce the number of network packets. This packing allows datagram payloads of up to ``Internal/MaxMessageSize``, -overshooting this size if the set maximum is too small to contain what must be -sent as a single unit. Note that in this case, there is a real problem anyway, +overshooting this size if the set maximum is too small to contain what must be +sent as a single unit. Note that in this case, there is a real problem anyway, and it no longer matters where the data is rejected, if it is rejected at all. UDP/IP header sizes are not taken into account in this maximum message size. @@ -1169,7 +1169,7 @@ Receive processing Receiving of data is split into multiple threads, as also depicted in the overall DDSI2 data path diagram `Data flow using two channels`_: -+ A single receive thread responsible for retrieving network packets and running ++ A single receive thread responsible for retrieving network packets and running the protocol state machine; + A delivery thread dedicated to processing DDSI built-in data: participant discovery, endpoint discovery and liveliness assertions; @@ -1182,7 +1182,7 @@ Heartbeat messages and queueing of samples that must be retransmitted, and for defragmenting and ordering incoming samples. For a specific proxy writer—the local manifestation of a remote DDSI data writer— -with a number of data readers, the organisation is as shown in +with a number of data readers, the organisation is as shown in the diagram `Proxy writer with multiple data readers`_. .. _`Proxy writer with multiple data readers`: @@ -1202,13 +1202,13 @@ and for unreliable data to ``Internal/DefragUnreliableMaxSamples``. Samples (defragmented if necessary) received out of sequence are buffered, primarily per proxy writer, but, secondarily, per reader catching up on historical (transient-local) data. The size of the first is limited to -``Internal/PrimaryReorderMaxSamples``, the size of the second to +``Internal/PrimaryReorderMaxSamples``, the size of the second to ``Internal/SecondaryReorderMaxSamples``. In between the receive thread and the delivery threads sit queues, of which the maximum size is controlled by the ``Internal/DeliveryQueueMaxSamples`` -setting. Generally there is no need for these queues to be very large, their -primary function is to smooth out the processing when batches of samples become +setting. Generally there is no need for these queues to be very large, their +primary function is to smooth out the processing when batches of samples become available at once, for example following a retransmission. When any of these receive buffers hit their size limit, DDSI2 will drop incoming @@ -1257,16 +1257,16 @@ Direction-independent settings Maximum sample size ------------------- -DDSI2 provides a setting, ``Internal/MaxSampleSize``, to control the maximum size -of samples that the service is willing to process. The size is the size of -the (CDR) serialised payload, and the limit holds both for built-in data and for -application data. The (CDR) serialised payload is never larger than the in-memory +DDSI2 provides a setting, ``Internal/MaxSampleSize``, to control the maximum size +of samples that the service is willing to process. The size is the size of +the (CDR) serialised payload, and the limit holds both for built-in data and for +application data. The (CDR) serialised payload is never larger than the in-memory representation of the data. On the transmitting side, samples larger than ``MaxSampleSize`` are dropped with a -warning in the OpenSplice info log. DDSI2 behaves as if the sample never existed. -The current structure of the interface between the OpenSplice kernel and the -OpenSplice networking services unfortunately prevents DDSI2 from properly +warning in the Vortex OpenSplice info log. DDSI2 behaves as if the sample never existed. +The current structure of the interface between the Vortex OpenSplice kernel and the +Vortex OpenSplice networking services unfortunately prevents DDSI2 from properly reporting this back to the application that wrote the sample, so the only guaranteed way of detecting the dropping of the sample is by checking the info log. @@ -1289,9 +1289,9 @@ whether or not dropping a particular sample has been recorded in the log already Under normal operational circumstances, DDSI2 will report a single event for each sample dropped, but it may on occasion report multiple events for the same sample. -Finally, it is technically allowed to set ``MaxSampleSize`` to very small sizes, -even to the point that the discovery data can’t be communicated anymore. -The dropping of the discovery data will be duly reported, but the usefulness +Finally, it is technically allowed to set ``MaxSampleSize`` to very small sizes, +even to the point that the discovery data can’t be communicated anymore. +The dropping of the discovery data will be duly reported, but the usefulness of such a configuration seems doubtful. Please refer to the :ref:`Configuration ` section for @@ -1332,7 +1332,7 @@ Channel configuration overview ------------------------------ DDSI2E allows defining *channels*, which are independent data paths within the -DDSI service. OpenSplice chooses a channel based by matching the transport +DDSI service. Vortex OpenSplice chooses a channel based by matching the transport priority QoS setting of the data writer with the threshold specified for the various channels. Because each channel has a set of dedicated threads to perform the processing and the thread priorities can all be configured, it is straightforward to @@ -1353,7 +1353,7 @@ receive thread only performs minimal work on each incoming packet, and never has to wait for the processing of user data. The existence of the receive thread is the only major difference between DDSI2E -channels and those of the OpenSplice RTNetworking service: in the RTNetworking +channels and those of the Vortex OpenSplice RTNetworking service: in the RTNetworking service, each thread is truly independent. This change is the consequence of DDSI2E interoperating with implementations that are not aware of channels and with DDSI2E nodes that have differently configured channels, unlike the @@ -1378,7 +1378,7 @@ priority that is higher than the writer’s transport priority. If there is no s *i.e.* the writer has a transport priority higher than the highest channel threshold, the channel with the highest threshold is used. -Each channel has its own network queue into which the OpenSplice kernel writes +Each channel has its own network queue into which the Vortex OpenSplice kernel writes samples to be transmitted and that DDSI2E reads. The size of this queue can be set for each channel independently by using ``Channels/Channel/QueueSize``, with the default taken from the global ``Sizing/NetworkQueueSize``. @@ -1411,8 +1411,8 @@ event thread handles the generation of auxiliary data for that channel. But if n is given, the global event thread instead handles all auxiliary data for the channel. The global event thread has an auxiliary credit of its own, configured using -``Internal/AuxiliaryBandwidthLimit``. This credit applies to all discovery-related -traffic, as well as to all auxiliary data generated by channels without their own +``Internal/AuxiliaryBandwidthLimit``. This credit applies to all discovery-related +traffic, as well as to all auxiliary data generated by channels without their own event thread. Generally, it is best to simply specify both the data and the auxiliary bandwidth for @@ -1456,7 +1456,7 @@ and always processed by the special delivery thread for DDSI built-in data (‘dq.builtin’). By explicitly creating a timed-event thread, one effectively separates application data from all discovery data. One way of creating such a thread is by setting properties for it (see `Thread configuration`_), -another is by setting a bandwidth limit on the auxiliary data of the channel +another is by setting a bandwidth limit on the auxiliary data of the channel (see `Transmit side`_). Please refer to the :ref:`Configuration ` section for @@ -1508,7 +1508,7 @@ Matching rules Matching of a DCPS partition/topic combination proceeds in the order in which the partition mappings are specified in the configuration. The first matching mapping is -the one that will be used. The ``*`` and ``?`` wildcards are available for +the one that will be used. The ``*`` and ``?`` wildcards are available for the DCPS partition/topic combination in the partition mapping. As mentioned earlier (see `Local discovery and built-in topics`_), @@ -1565,7 +1565,7 @@ be found, or if the associated key or cipher differs, the receiver will ignore t encrypted data. It is therefore not necessary to share keys with nodes that have no need for the encrypted data. -The encryption is performed *per-packet*; there is no chaining from one packet to +The encryption is performed *per-packet*; there is no chaining from one packet to the next. @@ -1596,7 +1596,7 @@ The properties that can be controlled are: + scheduling priority. The threads are named and the attribute ``Threads/Thread[@name]`` -is used to set the properties by thread name. Any subset of threads can be +is used to set the properties by thread name. Any subset of threads can be given special properties; anything not specified explicitly is left at the default value. @@ -1608,41 +1608,41 @@ The following threads exist: + *gc*: garbage collector, which sleeps until garbage collection is requested for an - entity, at which point it starts monitoring the state of DDSI2, pushing the - entity through whatever state transitions are needed once it is safe to do + entity, at which point it starts monitoring the state of DDSI2, pushing the + entity through whatever state transitions are needed once it is safe to do so, ending with the freeing of the memory. + *main*: the main thread of DDSI2, which performs start-up and teardown and - monitors the creation and deletion of entities in the local node using + monitors the creation and deletion of entities in the local node using the built-in topics. + *recv*: accepts incoming network packets from all sockets/ports, performs all - protocol processing, queues (nearly) all protocol messages sent in response - for handling by the timed-event thread, queues for delivery or, in special + protocol processing, queues (nearly) all protocol messages sent in response + for handling by the timed-event thread, queues for delivery or, in special cases, delivers it directly to the data readers. + *dq.builtins*: processes all discovery data coming in from the network. + *lease*: performs internal liveliness monitoring of DDSI2 and renews the - OpenSplice kernel lease if the status is satisfactory. + Vortex OpenSplice kernel lease if the status is satisfactory. + *tev*: timed-event handling, used for all kinds of things, such as: periodic - transmission of participant discovery and liveliness messages, transmission - of control messages for reliable writers and readers (except those that have - their own timed-event thread), retransmitting of reliable data on request - (except those that have their own timed-event thread), and handling of + transmission of participant discovery and liveliness messages, transmission + of control messages for reliable writers and readers (except those that have + their own timed-event thread), retransmitting of reliable data on request + (except those that have their own timed-event thread), and handling of start-up mode to normal mode transition. and, for each defined channel: + *xmit.channel-name*: - takes data from the OpenSplice kernel’s queue for this channel, serialises + takes data from the Vortex OpenSplice kernel’s queue for this channel, serialises it and forwards it to the network. + *dq.channel-name*: deserialisation and asynchronous delivery of all user data. + *tev.channel-name*: - channel-specific ‘timed-event’ handling: transmission of control messages - for reliable writers and readers and retransmission of data on request. + channel-specific ‘timed-event’ handling: transmission of control messages + for reliable writers and readers and retransmission of data on request. Channel-specific threads exist only if the configuration includes an element for it or if an auxiliary bandwidth limit is set for the channel. @@ -1657,14 +1657,14 @@ Reporting and tracing DDSI2 can produce highly detailed traces of all traffic and internal activities. It enables individual categories of information, as well as having a simple verbosity level that enables fixed sets of categories and of which the definition -corresponds to that of the other OpenSplice services. +corresponds to that of the other Vortex OpenSplice services. The categorisation of tracing output is incomplete and hence most of the verbosity levels and categories are not of much use in the current release. This is an ongoing process and here we describe the target situation rather than the current situation. All *‘fatal’* and *‘error’* messages are written both to the DDSI2 log and to the -``ospl-error.log`` file; similarly all ‘warning’ messages are written to the DDSI2 +``ospl-error.log`` file; similarly all ‘warning’ messages are written to the DDSI2 log and the ``ospl-info.log`` file. The Tracing element has the following sub elements: @@ -1702,20 +1702,20 @@ In addition, the keyword *trace* enables all but *radmin*. + *OutputFile*: the file to write the DDSI2 log to + *AppendToFile*: - boolean, set to ``true`` to append to the log instead of replacing + boolean, set to ``true`` to append to the log instead of replacing the file. Currently, the useful verbosity settings are *config* and *finest*. -*Config* writes the full configuration to the DDSI2 log file as well as -any warnings or errors, which can be a good way to verify everything is +*Config* writes the full configuration to the DDSI2 log file as well as +any warnings or errors, which can be a good way to verify everything is configured and behaving as expected. -*Finest* provides a detailed trace of everything that occurs and is an -indispensable source of information when analysing problems; however, +*Finest* provides a detailed trace of everything that occurs and is an +indispensable source of information when analysing problems; however, it also requires a significant amount of time and results in huge log files. -Whether these logging levels are set using the verbosity level or by enabling +Whether these logging levels are set using the verbosity level or by enabling the corresponding categories is immaterial. .. _`Compatibility and conformance`: @@ -1729,42 +1729,42 @@ Conformance modes ================= The DDSI2 service operates in one of three modes: *pedantic*, *strict* and *lax*; -the mode is configured using the ``Compatibility/StandardsConformance`` setting. +the mode is configured using the ``Compatibility/StandardsConformance`` setting. The default is *lax*. (Please refer to the :ref:`Configuration ` section for -a detailed description of +a detailed description of ``//OpenSplice/DDSI2Service/Compatibility/StandardsConformance``.) -In *pedantic* mode, it strives very hard to strictly conform to the DDSI 2.1 -standard. It even uses a vendor-specific extension for an essential element -missing in the specification, used for specifying the GUID of a DCPS data reader -or data writer in the discovery protocol; and it adheres to the specified -encoding of the reliability QoS. This mode is of interest for compliancy -testing but not for practical use, even though there is no application-level -observable difference between an all-OpenSplice system using the DDSI2 +In *pedantic* mode, it strives very hard to strictly conform to the DDSI 2.1 +and 2.2 standards. It even uses a vendor-specific extension for an essential element +missing in the specification, used for specifying the GUID of a DCPS data reader +or data writer in the discovery protocol; and it adheres to the specified +encoding of the reliability QoS. This mode is of interest for compliancy +testing but not for practical use, even though there is no application-level +observable difference between an all-Vortex OpenSplice system using the DDSI2 service in pedantic mode and one operating in any of the other modes. -The second mode, *strict*, instead attempts to follow the *intent* of the -specification while staying close to the letter of it. The points in which -it deviates from the standard are in all probability editing errors that -will be rectified in the next update. When operated in this mode, one -would expect it to be fully interoperable with other vendors’ implementations, -but this is not the case. The deviations in other vendors’ implementations -are not required to implement DDSI 2.1, as is proven by the OpenSplice DDSI2 -service, and they cannot rightly be considered ‘true’ implementations of -the DDSI 2.1 standard. - -The default mode, *lax*, attempts to work around (most of) the deviations +The second mode, *strict*, instead attempts to follow the *intent* of the +specification while staying close to the letter of it. The points in which +it deviates from the standard are in all probability editing errors that +will be rectified in the next update. When operated in this mode, one +would expect it to be fully interoperable with other vendors’ implementations, +but this is not the case. The deviations in other vendors’ implementations +are not required to implement DDSI 2.1 (or 2.2), as is proven by the Vortex OpenSplice DDSI2 +service, and they cannot rightly be considered ‘true’ implementations of +the DDSI 2.1 (or 2.2) standard. + +The default mode, *lax*, attempts to work around (most of) the deviations of other implementations, and provides interoperability with (at least) RTI DDS and InterCOM/Gallium DDS. (For compatibility with TwinOaks CoreDX DDS, -additional settings are needed. See -:ref:`the next section ` -for more information.) -In lax mode, the OpenSplice DDSI2 service not only accepts some invalid -messages, but will even transmit them. The consequences for interoperability +additional settings are needed. See +:ref:`the next section ` +for more information.) +In lax mode, the Vortex OpenSplice DDSI2 service not only accepts some invalid +messages, but will even transmit them. The consequences for interoperability of not doing this are simply too severe. -It should be noted that if one configures two OpenSplice nodes with DDSI2 in +It should be noted that if one configures two Vortex OpenSplice nodes with DDSI2 in different compliancy modes, the one in the stricter mode will complain about messages sent by the one in the less strict mode. Pedantic mode will complain about invalid encodings used in strict mode, strict mode will complain about illegal @@ -1779,7 +1779,7 @@ Compatibility issues with RTI In *lax* mode, there should be no major issues with most topic types when working across a network, but within a single host there is a known problem with the way RTI DDS uses, or attempts to use, its shared memory transport to communicate with -OpenSplice, which clearly advertises only UDP/IP addresses at which it is +Vortex OpenSplice, which clearly advertises only UDP/IP addresses at which it is reachable. The result is an inability to reliably establish bidirectional communication between the two. @@ -1796,8 +1796,8 @@ maximum length larger than 11 bytes. See the DDSI specification for details. In *strict* mode, there is interoperation with RTI DDS, but at the cost of incredibly high CPU and network load, caused by a Heartbeats and AckNacks going -back-and-forth between a reliable RTI DDS data writer and a reliable OpenSplice -DCPS data reader. The problem is that once the OpenSplice reader informs the RTI +back-and-forth between a reliable RTI DDS data writer and a reliable Vortex OpenSplice +DCPS data reader. The problem is that once the Vortex OpenSplice reader informs the RTI writer that it has received all data (using a valid AckNack message), the RTI writer immediately publishes a message listing the range of available sequence numbers and requesting an acknowledgement, which becomes an endless loop. diff --git a/docs/html/DeploymentGuide/_sources/durability-service.txt b/docs/html/DeploymentGuide/_sources/durability-service.txt index 9e9d2f8d3..cd4cb1499 100644 --- a/docs/html/DeploymentGuide/_sources/durability-service.txt +++ b/docs/html/DeploymentGuide/_sources/durability-service.txt @@ -10,7 +10,7 @@ purpose of the service. After that all its concepts and mechanisms are described The exact fulfilment of the durability responsibilities is determined by the configuration of the Durability Service. -There are detailed descriptions of all of the available configuration +There are detailed descriptions of all of the available configuration parameters and their purpose in the :ref:`Configuration ` section. @@ -41,7 +41,7 @@ the DDS middleware and comes in four flavours: running on at least one of the nodes. *PERSISTENT* Data needs to outlive system downtime. This implies that it - must be kept somewhere on permanent storage in order to be able to make + must be kept somewhere on permanent storage in order to be able to make it available again for subscribers after the middleware is restarted. In Vortex OpenSplice, the realisation of the non-volatile properties is the @@ -113,8 +113,8 @@ collection are always handled as an atomic data-set by the durability service. I other words, the data is guaranteed to be stored and reinserted as a whole. This atomicity also implies that a name-space is a system-wide concept, meaning -that different durability services need to agree on its definition, *i.e.* which -partitions belong to one name-space. This doesn’t mean that each durability service +that different durability services need to agree on its definition, *i.e.* which +partitions belong to one name-space. This doesn’t mean that each durability service needs to know all name-spaces, as long as the name-spaces one does know don’t conflict with one of the others in the domain. Name-spaces that are completely disjoint can co-exist (their intersection is an empty set); name-spaces conflict when they @@ -160,7 +160,7 @@ This section describes the policies that can be configured per name-space giving user full control over the fault-tolerance versus performance aspect on a per name-space level. -Please refer to the :ref:`Configuration ` section for +Please refer to the :ref:`Configuration ` section for a detailed description of: + ``//OpenSplice/DurabilityService/NameSpaces/Policy`` @@ -230,7 +230,7 @@ associated with the data, for instance by storing persistent data only in memory it were transient. Reasons for this are performance impact (CPU load, disk I/O) or simply because no permanent storage (in the form of some hard-disk) is available on a node. Be aware that it is not possible to ‘strengthen’ the durability of the data -(Persistent > Transient > Volatile). +(Persistent > Transient > Volatile). The durability service has the following options for maintaining a set of historical data: @@ -259,10 +259,10 @@ Delayed alignment policy The durability service has a mechanism in place to make sure that when multiple services with a persistent dataset exist, only one set (typically the one with the -newest state) will be injected in the system (see `Persistent data injection`_). -This mechanism will, during the startup of the durability service, negotiate with -other services which one has the best set (see `Master selection`_). -After negotiation the ‘best’ persistent set (which can be empty) is restored +newest state) will be injected in the system (see `Persistent data injection`_). +This mechanism will, during the startup of the durability service, negotiate with +other services which one has the best set (see `Master selection`_). +After negotiation the ‘best’ persistent set (which can be empty) is restored and aligned to all durability services. Once persistent data has been re-published in the domain by a durability service for @@ -271,11 +271,11 @@ re-publish their own set for that name-space from disk any longer. Applications already have started their processing based on the already-published set, and re-publishing another set of data may confuse the business logic inside applications. Other durability services will therefore back-up their own set of data and align and -store the set that is already available in the domain. +store the set that is already available in the domain. -It is important to realise that an empty set of data is also considered a set. +It is important to realise that an empty set of data is also considered a set. This means that once a durability service in the domain decides that there is no data -(and has triggered applications that the set is complete), other late-joining +(and has triggered applications that the set is complete), other late-joining durability services will not re-publish any persistent data that they potentially have available. @@ -310,12 +310,12 @@ nodes may have been publishing information for the same topic in the same partition without this information reaching the other party. Therefore their perception of the set of data will be different. -In many cases, after this has occurred the exchange of information is no longer +In many cases, after this has occurred the exchange of information is no longer allowed, because there is no guarantee that data between the connected systems doesn’t -conflict. For example, consider a fault-tolerant (distributed) global id service: -this service will provide globally-unique ids, but this will be guaranteed +conflict. For example, consider a fault-tolerant (distributed) global id service: +this service will provide globally-unique ids, but this will be guaranteed *if and only if* there is no disruption of communication between all services. In such -a case a disruption must be considered permanent and a reconnection must be avoided +a case a disruption must be considered permanent and a reconnection must be avoided at any cost. Some new environments demand supporting the possibility to (re)connect two @@ -397,7 +397,7 @@ Prevent aligning equal data sets As explained in previous sections, temporary disconnections can cause durability services to get out-of-sync, meaning that their data sets may diverge. To recover -from such situations merge policies have been defined (see `Merge policy`_) +from such situations merge policies have been defined (see `Merge policy`_) where a user can specify how to combine divergent data sets when they become reconnected. Many of these situations involve the transfer of data sets from one durability service to the other. This may generate a considerable @@ -561,19 +561,19 @@ a detailed description of: Interaction with applications ============================= -The durability service is responsible for providing historical data to +The durability service is responsible for providing historical data to late-joining subscribers. Applications can use the DCPS API call ``wait_for_historical_data`` on a DataReader -to synchronise on the availability of the complete set of historical data. -Depending on whether the historical data is already available locally, data can be -delivered immediately after the DataReader has been created or must be aligned from -another durability service in the domain first. Once all historical data is delivered -to the newly-created DataReader, the durability service will trigger the DataReader -unblocking the ``wait_for_historical_data`` performed by the application. If the -application does not need to block until the complete set of historical data is -available before it starts processing, there is no need to call -``wait_for_historical_data``. It should be noted that in such a case historical +to synchronise on the availability of the complete set of historical data. +Depending on whether the historical data is already available locally, data can be +delivered immediately after the DataReader has been created or must be aligned from +another durability service in the domain first. Once all historical data is delivered +to the newly-created DataReader, the durability service will trigger the DataReader +unblocking the ``wait_for_historical_data`` performed by the application. If the +application does not need to block until the complete set of historical data is +available before it starts processing, there is no need to call +``wait_for_historical_data``. It should be noted that in such a case historical data still is delivered by the durability service when it becomes available. @@ -722,24 +722,51 @@ for every name-space, which is the next phase in its lifecycle. Master selection ================ -To ensure a single source for re-publishing of persistent data and to allow parallel -alignment, each durability service will select a master for every name-space. - -The rules for determining a master are: - -1. If some other durability service in the domain already selected - a master, pick the same one. - -2. If no master has been selected, pick the one with the newest - initial set of persistent data. - -3. If multiple durability services exist with the newest set of - initial persistent data, pick the one with the highest id - (this id is a domain-wide unique number that is - generated at start-up of each OpenSplice federation). - -If an existing master is no longer available, due to a disconnection, crash or -regular termination, a new master is selected based on the same rules. +For each Namespace and Role combination there shall be at most one Master Durability +Service. The Master Durability Service coordinates single source re-publishing of +persistent data and to allow parallel alignment after system start-up, +and to coordinate recovery of a split brain syndrome after connecting nodes having +selected a different Master indicating that more than one state of the data may exist. + +Therefore after system start-up as well as after any topology change (i.e. late joining +nodes or leaving master node) a master selection process will take place for each +affected Namespace/Role combination. + +To control the master selection process a masterPriority attribute can be used. + +Each Durability Service will have a configured masterPriority attribute per namespace +which is an integer value between 0 and 255 and which specifies the eagerness of the +Durability Service to become Master for that namespace. +The values 0 and 255 have a special meaning. +Value 0 is used to indicate that the Durability Service will never become Master. +The value 255 is used to indicate that the Durability Service will not use priorities +but instead uses the legacy selection algorithm. +If not configured the default is 255. + +During the master selection process each Durability service will exchange for each +namespace the masterPriority and quality. The namespace quality is the timestamp of the +latest update of the persistent data set stored on disk and only plays a role in master +selection initially when no master has been chosen before and persistent data has not +been injected yet. + +Each Durability Service will determine the Master based upon the highest non zero +masterPriority and in case of multiple masters further select based on namespace +quality (but only if persistent data has not been injected before) and again in case of +multiple masters select the highest system id. The local system id is an arbitrary +value which unique identifies a durability service. +After selection each Durability Service will communicate their determined master and on +agreement effectuate the selection, on disagreement which may occur if some Durability +Services had a temporary different view of the system this process of master selection +will restart until all Durability Services have the same view of the system and have +made the same selection. +If no durability services exists having a masterPriority greater than zero then no +master will be selected. + +Summarizing, the precedence rules for master selection are (from high to low): + +1. The namespace masterPriority +2. The namespace quality, if no data has been injected before. +3. The Durability Service system id, which is unique for each durability service. Please refer to the :ref:`Configuration ` section for a detailed description of: @@ -753,88 +780,88 @@ Persistent data injection ========================= As persistent data needs to outlive system downtime, this data needs to be -re-published in DDS once a domain is started. +re-published in DDS once a domain is started. -If only one node is started, the durability service on that node can simply -re-publish the persistent data from its disk. However, if multiple nodes are -started at the same time, things become more difficult. Each one of them may -have a different set available on permanent storage due to the fact that +If only one node is started, the durability service on that node can simply +re-publish the persistent data from its disk. However, if multiple nodes are +started at the same time, things become more difficult. Each one of them may +have a different set available on permanent storage due to the fact that durability services have been stopped at a different moment in time. Therefore only one of them should be allowed to re-publish its data, to prevent -inconsistencies and duplication of data. +inconsistencies and duplication of data. -The steps below describe how a durability service currently determines whether or +The steps below describe how a durability service currently determines whether or not to inject its data during start-up: -1. *Determine validity of own persistent data* — - During this step the durability service determines whether its persistent - store has initially been completely filled with all persistent data in the - domain in the last run. If the service was shut down in the last run - during initial alignment of the persistent data, the set of data will be - incomplete and the service will restore its back-up of a full set of (older) +1. *Determine validity of own persistent data* — + During this step the durability service determines whether its persistent + store has initially been completely filled with all persistent data in the + domain in the last run. If the service was shut down in the last run + during initial alignment of the persistent data, the set of data will be + incomplete and the service will restore its back-up of a full set of (older) data if that is available from a run before that. This is done because it - is considered better to re-publish an older but complete set of data instead + is considered better to re-publish an older but complete set of data instead of a part of a newer set. -2. *Determine quality of own persistent data* — - If persistence has been configured, the durability service will inspect the - quality of its persistent data on start-up. The quality is determined on a - *per-name-space* level by looking at the time-stamps of the persistent data - on disk. The latest time-stamp of the data on disk is used as the quality - of the name-space. This information is useful when multiple nodes are started - at the same time. Since there can only be one source per name-space that is - allowed to actually inject the data from disk into DDS, this mechanism allows - the durability services to select the source that has the latest data, because - this is generally considered the best data. If this is not true then an - intervention is required. The data on the node must be replaced by the - correct data either by a supervisory (human or system management application) +2. *Determine quality of own persistent data* — + If persistence has been configured, the durability service will inspect the + quality of its persistent data on start-up. The quality is determined on a + *per-name-space* level by looking at the time-stamps of the persistent data + on disk. The latest time-stamp of the data on disk is used as the quality + of the name-space. This information is useful when multiple nodes are started + at the same time. Since there can only be one source per name-space that is + allowed to actually inject the data from disk into DDS, this mechanism allows + the durability services to select the source that has the latest data, because + this is generally considered the best data. If this is not true then an + intervention is required. The data on the node must be replaced by the + correct data either by a supervisory (human or system management application) replacing the data files or starting the nodes in the desired sequence so that data is replaced by alignment. -3. *Determine topology* — - During this step, the durability service determines whether there are other +3. *Determine topology* — + During this step, the durability service determines whether there are other durability services in the domain and what their state is. - If this service is the only one, it will select itself as the ‘best’ source + If this service is the only one, it will select itself as the ‘best’ source for the persistent data. -4. *Determine master* — +4. *Determine master* — During this step the durability service will determine who - will inject persistent data or who has injected persistent data already. - The one that will or already has injected persistent data is called the - *‘master’*. This process is done on a per name-space level + will inject persistent data or who has injected persistent data already. + The one that will or already has injected persistent data is called the + *‘master’*. This process is done on a per name-space level (see previous section). - a) *Find existing master* – - In case the durability service joins an already-running domain, - the master has already been determined and this one has already - injected the persistent data from its disk or is doing it right now. - In this case, the durability service will set its current set of - persistent data aside and will align data from the already existing - master node. If there is no master yet, persistent data has not + a) *Find existing master* – + In case the durability service joins an already-running domain, + the master has already been determined and this one has already + injected the persistent data from its disk or is doing it right now. + In this case, the durability service will set its current set of + persistent data aside and will align data from the already existing + master node. If there is no master yet, persistent data has not been injected yet. - b) *Determine new master* – - If the master has not been determined yet, the durability service - determines the master for itself based on who has the best quality + b) *Determine new master* – + If the master has not been determined yet, the durability service + determines the master for itself based on who has the best quality of persistent data. In case there is more than one service with the ‘best’ quality, the one with the highest system id (unique number) is - selected. Furthermore, a durability service that is marked as not - being an aligner for a name-space cannot become master for + selected. Furthermore, a durability service that is marked as not + being an aligner for a name-space cannot become master for that name-space. -5. *Inject persistent data* — - During this final step the durability service injects its persistent data - from disk into the running domain. This is *only* done when the service has +5. *Inject persistent data* — + During this final step the durability service injects its persistent data + from disk into the running domain. This is *only* done when the service has determined that it is the master. In any other situation the durability - service backs up its current persistent store and fills a new store with - the data it aligns from the master durability service in the domain, or + service backs up its current persistent store and fills a new store with + the data it aligns from the master durability service in the domain, or postpones alignment until a master becomes available in the domain. |caution| - It is strongly discouraged to re-inject persistent data from a persistent - store in a running system after persistent data has been published. - Behaviour of re-injecting persistent stores in a running system is not + It is strongly discouraged to re-inject persistent data from a persistent + store in a running system after persistent data has been published. + Behaviour of re-injecting persistent stores in a running system is not specified and may be changed over time. @@ -859,8 +886,8 @@ Align historical data Once all topic and partition information for all configured name-spaces are known, the initial alignment of historical data takes place. Depending on the configuration -of the service, data is obtained either immediately after discovering it or only once -local interest in the data arises. The process of aligning historical data continues +of the service, data is obtained either immediately after discovering it or only once +local interest in the data arises. The process of aligning historical data continues during the entire lifecycle of the durability service. @@ -869,8 +896,8 @@ during the entire lifecycle of the durability service. Provide historical data ======================= -Once (a part of) the historical data is available in the durability service, it is -able to provide historical data to local DataReaders as well as other durability +Once (a part of) the historical data is available in the durability service, it is +able to provide historical data to local DataReaders as well as other durability services. Providing of historical data to local DataReaders is performed automatically as soon @@ -898,6 +925,239 @@ the configured merge-policies will determine what actions are performed to recov from this situation. The process of merging historical data will be performed every time two separately running systems get (re-)connected. +.. _`Threads description`: + +Threads description +******************* + +This section contains a short description of each durability thread. When applicable, +relevant configuration parameters are mentioned. + +ospl_durability +=============== +This is the main durability service thread. It starts most of the other threads, e.g. +the listener threads that are used to receive the durability protocol messages, +and it initiates initial alignment when necessary. This thread is responsible for +periodically updating the service-lease so that the splice-daemon is aware the service +is still alive. It also periodically (every 10 seconds) checks the state of all other +service threads to detect if deadlock has occurred. If deadlock has occurred the service +will indicate which thread didn't make progress and action can be taken (e.g. the service +refrains from updating its service-lease, causing the splice daemon to execute a failure +action). Most of the time this thread is asleep. + +conflictResolver +================ +This thread is responsible for resolving conflicts. If a conflict has been detected and +stored in the conflictQueue, the conflictResolver thread takes the conflict, checks +whether the conflict still exists, and if so, starts the procedure to resolve the conflict +(i.e., start to determine a new master, send out sample requests, etc). + +statusThread +============ +This thread is responsible for the sending status messages to other durability services. +These messages are periodically sent between durability services to inform each other +about their state (.e.,g INITIALIZING or TERMINATING). + +Configuration parameters: + ++ ``//OpenSplice/DurabilityService/Watchdog/Scheduling`` + +d_adminActionQueue +================== +The durability service maintains a queue to schedule timed action. The d_adminActionQueue +periodically checks (every 100 ms) if an action is scheduled. +Example actions are: electing a new master, detection of new local groups and deleting +historical data. + +Configuration parameters: + ++ ``//OpenSplice/DurabilityService/Network/Heartbeat/Scheduling`` + +AdminEventDispatcher +==================== +Communication between the splice-daemon and durability service is managed by events. The +AdminEventDispatcher thread listens and acts upon these events. For example, the creation +of a new topic is noticed by the splice-daemon, which generates an event for the +durability service, which schedules an action on to request historical data for the topic. + +groupCreationThread +=================== +The groupCreationThread is responsible for the creation of groups that exist in other +federations. When a durability service receives a newGroup message from another +federation, it must create the group locally in order to acquire data for it. +Creation of a group may fail in case a topic is not yet known. The thread will retry with +a 10ms interval. + +sampleRequestHandler +==================== +This thread is responsible for the handling of sampleRequests. When a durability +service receives a d_sampleRequest message (see the sampleRequestListener thread) it +will not immediately answer the request, but wait some time until the time to combine +requests has been expired (see +//OpenSplice/DurabilityService/Network/Alignment/RequestCombinePeriod). When this time +has expired the sampleRequestHandler will answer the request by collecting the requested +data and sending the data as d_sampleChain messages to the requestor. + +Configuration parameters: + ++ ``//OpenSplice/DurabilityService/Network/Alignment/AlignerScheduling`` + +resendQueue +=========== +This thread is responsible for injection of message in the group after it has been rejected +before. When a durability service has received historical data from another fellow, +historical data is injected in the group (see d_sampleChain). Injection of historical data +can be rejected, e.g., when a resource limits are being used. When this happens, a new attempt +to inject the data is scheduled overusing the resendQueue thread. This thread will try to +deliver the data 1s later. + +Configuration parameters: + ++ ``//OpenSplice/DurabilityService/Network/Alignment/AligneeScheduling`` + +masterMonitor +============= +The masterMonitor is the thread that handles the selection of a new master. This thread is +invoked when the conflict resolver detects that a master conflict has occurred. The +masterMonitor is responsible for collecting master proposals from other fellows and sending +out proposals to other fellows. + +groupLocalListenerActionQueue +============================= +This thread is used to handle historical data requests from specific readers, and to handle +delayed alignment (see //OpenSplice/DurabilityService/NameSpaces/Policy[@delayedAlignment]) + +d_groupsRequest +=============== +The d_groupsRequest thread is responsible for processing incoming d_groupsRequest messages +from other fellows. When a durability service receives a message from a fellow, the durability +service will send information about its groups to the requestor by means of d_newGroup messages. +This thread collects group information, packs it in d_newGroup messages and send them to the +requestor. This thread will only do something when a d_groupsRequest has been received from a +fellow. Most of the time it will sleep. + +d_nameSpaces +============ +This thread is responsible for processing incoming d_nameSpaces messages from other fellows. +Durability services send each other their namespaces state so that they can detect potential +conflicts. The d_nameSpaces thread processes and administrates every incoming d_nameSpace. When +a conflict is detected, the conflict is scheduled which may cause the conflictResolver thread +to kick in. + +d_nameSpacesRequest +=================== +The d_nameSpacesRequest thread is responsible for processing incoming d_nameSpacesRequest +messages from other fellows. A durability service can request the namespaces form a fellow by +sending a d_nameSpacesRequest message to the fellow. Whenever a durability service receives a +d_nameSpacesRequest messages it will respond by sending its set of namespaces to the fellow. +The thread handles incoming d_nameSpacesRequest messages. As a side effect new fellows can be +discovered if a nameSpacesRequest is received from an unknown fellow. + +d_status +======== +The d_status thread is responsible for processing incoming d_status messages from other fellows. +Durability services periodically send each other status information (see the statusThread). +NOTE: in earlier versions missing d_status messages could lead to the conclusion that a fellows +has been removed. In recent versions this mechanism has been replaced so that the durability +service slaves itself to the liveness of remote federations based on heartbeats +(see thread dcpsHeartbeatListener). Effectivily, the d_status message is not used anymore to +verify liveliness of remote federations, it is only used to transfer the durability state of +a remote federation. + +d_newGroup +========== +The d_newGroup thread is responsible for handling incoming d_newGroup messages from other fellows. +Durability services inform each other about groups in the namespaces. They do that by sending +d_newGroup messages to each other (see also thread d_groupsRequest). The d_newGroup thread is +responsible for handling incoming groups. + +d_sampleChain +============= +The d_sampleChain thread handles incoming d_sampleChain messages from other fellows. When a +durability service answers an d_sampleRequest, it must collect the requested data and send it +to the requestor. The collected data is packed in d_sampleChain messages. The d_sampleChain thread +handles incoming d_sampleChain messages and applies the configured merge policy for the data. +For example, in case of a MERGE it injects all the received data in the local group and delivers +the data to the available readers. + +Configuration parameters: + ++ ``//OpenSplice/DurabilityService/Network/Alignment/AligneeScheduling`` + +d_sampleRequest +=============== +The d_sampleRequest thread is responsible for handling incoming d_sampleRequest messages from +other fellows. A durability service can request historical data from a fellow by sending a +d_sampleRequest message. The d_sampleRequest thread is used to process d_sampleRequest messages. +Because d_sampleRequest messages are not handled immediately, they are stored in a list and handled +later on (see thread sampleRequestHandler). + +d_deleteData +============ +The d_deleteData thread is responsible for handling incoming d_deleteData messages from other fellows. +An application can call delete_historical_data(). This causes all historical data up till now to be +deleted. To propagate deletion of historical data to all available durability services in the system, +durability services send each other a d_deleteData message. The d_deleteData thread handles incoming +d_deleteData messages and takes care that the relevant data is deleted. This thread will only be active +after delete_historical_data() is called. + +dcpsHeartbeatListener +===================== +The dcpsHeartbeatListener is responsible for the liveliness detection of remote federations. This +thread listens to DCPSHeartbeat messages that are sent by federation. It is used to detect new +federations or federations that disconnect. This thread will only do something when there is a change +in federation topology. Most of the time it will be asleep. + +d_capability +============ +The thread is responsible for processing d_cability messages from other fellows. As soon as a durability +service detects a fellow it will send its list of capabilities to the fellow. The fellow can use this +list to find what functionality is supported by the durability service. Similarly, the durability +service can receive capabilities from the fellow. This thread is used to process the capabilities sent by +a fellow. This thread will only do something when a fellow is detected. | | + +remoteReader +============ +The remoteReader thread is responsible for the detection of remote readers on other federations. The DDSI +service performs discovery and reader-writing matching. This is an asynchronous mechanism. When a +durability service (say A) receives a request from a fellow durability service (say B) and DDSI is used +as networking service, then A cannot be sure that DDSI has already detected the reader on B that should +receive the answer to the request. To ensure that durability services will only answer if all relevant +remote readers have been detected, the remoteReader thread keeps track of the readers that have been +discovered by ddsi. Only when all relevant readers have been discovered durability services are allowed +to answer requests. This prevents DDSI from dropping messages destined for readers that have not been +discovered yet. + +persistentDataListener +====================== +The persistentDataListenerThread is responsible for persisting durable data. When a durability service +retrieves persistent data, the data is stored in a queue. The persistentDataListener thread retrieves the +data from the queue and stores it in the persistent store. For large data sets persisting the data can take +quite some time, depending mostly on the performance of the disk. + +Note this thread is only created when persistency is enabled +(//OpenSplice/DurabilityService/Persistent/StoreDirectory has a value set): + +Configuration parameters: + ++ ``//OpenSplice/DurabilityService/Persistent/Scheduling`` + +historicalDataRequestHandler +============================ +This thread is responsible for handling incoming historicalDataRequest messages from durability clients. In +case an application does not have the resources to run a durability service but still wants to acquire +historical data it can configure a client. The client sends HistoricalDataRequest messages to the durability +service. These messages are handled by the historicalDataRequestHandler thread. + +Note this thread is only created when client durability is enabled +(//OpenSplice/DurabilityService/ClientDurability element exists) + +durabilityStateListener +======================= +This thread is responsible for handling incoming durabilityStateRequest messages from durability clients. + +Note this thread is only created when client durability is enabled +(//OpenSplice/DurabilityService/ClientDurability element exists) .. EoF diff --git a/docs/html/DeploymentGuide/_sources/guide.txt b/docs/html/DeploymentGuide/_sources/guide.txt index 6e540b437..794cf1702 100644 --- a/docs/html/DeploymentGuide/_sources/guide.txt +++ b/docs/html/DeploymentGuide/_sources/guide.txt @@ -124,13 +124,13 @@ Adding these new elements and attributes would result in the following XML: OpenSplice ********** - OpenSplice DDS is highly configurable, even allowing the architecture of the - DDS middleware to be chosen by the user at deployment time. OpenSplice DDS can + Vortex OpenSplice is highly configurable, even allowing the architecture of the + DDS middleware to be chosen by the user at deployment time. Vortex OpenSplice can be configured to run using a **shared memory** architecture, where both the DDS related administration (including the optional pluggable services) and DDS - applications interface directly with shared memory. Alternatively, OpenSplice - DDS also supports a **single process** architecture, where one or more DDS - applications, together with the OpenSplice administration and services, can all be + applications interface directly with shared memory. Alternatively, Vortex OpenSplice + also supports a **single process** architecture, where one or more DDS + applications, together with the Vortex OpenSplice administration and services, can all be grouped into a single operating system process. Both deployment modes support a configurable and extensible set of services, providing functionality such as: @@ -141,23 +141,24 @@ OpenSplice persistent settings remote control and monitoring SOAP service - providing remote web-based - access using the SOAP protocol from the OpenSplice Tuner tool + access using the SOAP protocol from the Vortex OpenSplice Tuner tool dbms service - providing a connection between the real-time and the enterprise domain by bridging data from DDS to DBMS and vice versa - Because of the pluggable architecture, the OpenSplice middleware + Because of the pluggable architecture, the Vortex OpenSplice middleware can be easily configured on the fly by specifying which services to be used as well as specifying their optimal configuration for the application domain (networking parameters, durability levels, etc.). Typically, there are many nodes within a system. - The OpenSplice middleware including its services can be configured + The Vortex OpenSplice middleware including its services can be configured by means of easy maintainable XML-file(s). - Full path: //OpenSplice - Occurrences min-max: 1-1 - Child elements: Description +- Optional attributes: version Domain ****** @@ -171,7 +172,7 @@ Domain of all started services, take corrective actions if needed and stop the services when it is terminated. - When a shutdown of the OpenSplice Domain service is requested, it will react by announcing the shutdown using the + When a shutdown of the Vortex OpenSplice Domain service is requested, it will react by announcing the shutdown using the DDS administration. Applications will not be able to use DDS functionality anymore and services are requested to terminate elegantly. Once this has succeeded, the Domain service will destroy the administration and finally terminate itself. @@ -200,8 +201,8 @@ Id Note - for maximum interoperability it is recommended that you only select a domain Id from the range 0 < n < 230. The domain Id value is used by the DDSI2 service to derive values for the required network communiction endpoints and service reconfiguration is required to use domain id values outside of this range. - Please see section 9.6.1 of the Real-time Publish-Subscribe Wire Protocol DDS Interoperability Wire Protocol specification (DDSI), v2.1, formal/2009-01-05 at - http://www.omg.org/spec/DDSI/2.1/ for further information. + Please see section 9.6.1 of the Real-time Publish-Subscribe Wire Protocol DDS Interoperability Wire Protocol specification (DDSI), v2.1, formal/2009-01-05 + or v2.2, formal/2014-09-01, at http://www.omg.org/spec/DDSI for further information. - Full path: //OpenSplice/Domain/Id - Format: integer @@ -245,7 +246,7 @@ ExpiryTime This element specifies the interval(in seconds) in which services have to announce their liveliness. - Every OpenSplice service including the Domain service itself has to announce its liveliness regularly. + Every Vortex OpenSplice service including the Domain service itself has to announce its liveliness regularly. This allows corrective actions to be taken when one of the services becomes non-responsive. This element specifies the required interval. Decreasing the interval decreases the time in which non-responsiveness of a service is detected, but leads to more processing. Increasing it has @@ -348,7 +349,7 @@ ServiceTerminatePeriod This may prevent graceful termination and thus leave applications that are still attached to the DDS domain in an undefined state. Consequently the '0' value should only be used when there is - some form of process management on top of OpenSplice DDS. + some form of process management on top of Vortex OpenSplice. - Full path: //OpenSplice/Domain/ServiceTerminatePeriod - Format: float @@ -360,12 +361,12 @@ ServiceTerminatePeriod SingleProcess ============= - The SingleProcess element specifies whether the OpenSplice Domain and other - OpenSplice services and applications are intended to be all deployed within the - same process, known in OpenSplice as a single process. + The SingleProcess element specifies whether the Vortex OpenSplice Domain and other + Vortex OpenSplice services and applications are intended to be all deployed within the + same process, known in Vortex OpenSplice as a single process. Please note that the choice to use the single process deployment also implies - the use of heap memory for the OpenSplice database management instead of shared + the use of heap memory for the Vortex OpenSplice database management instead of shared memory that would be used otherwise. If no database size or size 0 is configured the heap memory is limited by the Operating System, so the Database element under Domain does not take effect when SingleProcess has a value of True. @@ -373,13 +374,13 @@ SingleProcess heap with that size and the domain service will use it's own memory manager to manage that memory - There are two ways in which to deploy an OpenSplice DDS application as a + There are two ways in which to deploy an Vortex OpenSplice application as a single process: **Single Process Application** : The user starts an application as a new process. In this case, the DDS create_participant operation will - implicitly start the OpenSplice Domain Service as a thread in the existing - application process. The OpenSplice Domain Service will then also implicitly + implicitly start the Vortex OpenSplice Domain Service as a thread in the existing + application process. The Vortex OpenSplice Domain Service will then also implicitly start all services specified in the configuration as threads within the same process. **Single Process Application Cluster** : This provides the option to @@ -423,7 +424,7 @@ CPUAffinity InProcessExceptionHandling ========================== - The InProcessExceptionHandling element determines whether a process that uses OpenSplice will + The InProcessExceptionHandling element determines whether a process that uses Vortex OpenSplice will handle exceptions by itself and try to clean up shared resources or not. If the process itself refrains from cleaning up its resources, the splice-daemon will attempt to clean up the application shared resources asynchronously. If the splice-daemon during clean-up determines that shared @@ -1102,7 +1103,7 @@ Size Threshold --------- - This element specifies the threshold size used by OpenSplice DDS. Whenever there is less + This element specifies the threshold size used by Vortex OpenSplice. Whenever there is less free shared memory then indicated by the threshold then no new allocations will be allowed within shared memory. Services are allowed to continue allocating shared memory until less then 50% of the threshold value is available. It is strongly discouraged to configure a threshold @@ -1132,15 +1133,21 @@ Address default values per platform: - - 0x20000000 (Linux2.6 on x86) - - 00x140000000 (Linux2.6 on x86_64) - - 00x40000000 (Windows on x86) - - 00x40000000 (Windows on x86_64) - - 00xA0000000 (Solaris on SPARC) - - 00xA0000000 (AIX5.3 on POWER5+) - - 00x0 (VxWorks 5.5.1 on PowerPC604) - - 00x60000000 (VxWorks 6.x on PowerPC604) - - 00x20000000 (Integrity on mvme5100) + - 00x20000000 (Linux) + - 00x140000000 (Linux 64-bit) + - 00x40000000 (Windows) + - 00x140000000 (Windows 64-bit) + - 00xA0000000 (Solaris) + - 00xA0000000 (AIX5.3) + - 00x0 (VxWorks 5.5.1) + - 00x60000000 (VxWorks 6.x) + - 00x20000000 (Integrity) + - 00x20000000 (LynxOS) + - 00x140000000 (LynxOS 64-bit) + - 00x0 (PikeOS) + - 00x60000000 (QXN) + - 00x0 (RTEMS) + - 00x00220000 (Windows CE) - Full path: //OpenSplice/Domain/Database/Address - Format: string @@ -1218,7 +1225,7 @@ name This attribute specifies the name by which the corresponding service is identified in the rest of the configuration file. - In the OpenSplice DDS configuration file, services and their settings + In the Vortex OpenSplice configuration file, services and their settings are identified by a name. When the Domain Service starts a particular service, its corresponding name is passed. The service in question uses this name in order to find its own configuration settings in the rest of @@ -1249,15 +1256,15 @@ Command This element specifies the command to be executed in order to start the service. In shared memory mode, Command element specifies the name of the actual service - executable (possibly including its path, but always including its extension, e.g. - .exe on the Windows platform). When no path is included, the Domain Service - will search the PATH environment variable for the corresponding executable. Once - located, it will be started as a separate process. + executable or a script to launch this service (possibly including its path, but always + including its extension, e.g. .exe on the Windows platform). When no path is + included, the Domain Service will search the PATH environment variable for the + corresponding executable. Once located, it will be started as a separate process. In single process mode, Command is the name of the entry point function to be invoked and the name of the shared library to be dynamically loaded into the process. The signature of the entry point function is the same as argc/argv usually - seen with main. The OpenSplice services are implemented in such a way that the + seen with main. The Vortex OpenSplice services are implemented in such a way that the entry point name matches that of the shared library, so (for example) specifying durability is all that is required. @@ -1443,7 +1450,7 @@ FailureAction - **skip**: Ignore the non-responsiveness and continue. - **kill**: End the service process by force. - **restart**: End the service process by force and restart it. - - **systemhalt**: End all OpenSplice services including the Domain service (for the current DDS Domain on this computing node). + - **systemhalt**: End all Vortex OpenSplice services including the Domain service (for the current DDS Domain on this computing node). - Full path: //OpenSplice/Domain/Service/FailureAction - Format: enumeration @@ -1451,6 +1458,24 @@ FailureAction - Valid values: kill, restart, skip, systemhalt - Occurrences min-max: 0-1 +GIDKey +====== +- Full path: //OpenSplice/Domain/GIDKey +- Occurrences min-max: 0-* +- Required attributes: groups + +groups +------ + + This attribute specifies the namespace by which the corresponding groups + will use the writer instance gid as key so that data from different writers + don merge as historical data for late joiners. + +- Full path: //OpenSplice/Domain/GIDKey[@groups] +- Format: string +- Default value: n/a +- Required: true + Application =========== @@ -1458,7 +1483,7 @@ Application DDS applications by dynamically loading application shared libraries and starting threads within the existing process. A user can add a multiple Application elements to the configuration when they want - to 'cluster' multiple DDS applications within an OpenSplice DDS single process. + to 'cluster' multiple DDS applications within an Vortex OpenSplice single process. The entry point and shared library for each Application can be specified by using the Command and Library elements that are described below.>/p> **Note that Applications only take effect when the single process configuration is enabled by way of the SingleProcess element.** @@ -1500,7 +1525,7 @@ Command shared library to be dynamically loaded into the process. The signature of the entry point function is the same as argc/argv usually seen with main. - For example, if Command is "HelloWorld", OpenSpliceDDS will attempt to load + For example, if Command is "HelloWorld", Vortex OpenSplice will attempt to load "libHelloWorld.so" on Unix (or "HelloWorld.dll" on Windows) into the existing process and then invoke the "HelloWorld" entry point to start that DDS application. @@ -1524,7 +1549,7 @@ Arguments This optional attribute allows the user to specify arguments to be passed to the DDS application's entry point when it is invoked. - For example, if Command is "HelloWorld" and Arguments is "arg1 arg2", OpenSplice will + For example, if Command is "HelloWorld" and Arguments is "arg1 arg2", Vortex OpenSplice will invoke the HelloWorld function with the argc = 3 and argv = {"HelloWorld", "arg1", "arg2"} - Full path: //OpenSplice/Domain/Application/Arguments @@ -1552,6 +1577,7 @@ BuiltinTopics - Full path: //OpenSplice/Domain/BuiltinTopics - Occurrences min-max: 0-1 - Required attributes: enabled +- Optional attributes: logfile enabled ------- @@ -1566,6 +1592,18 @@ enabled - Default value: true - Required: true +logfile +------- + + This attribute specifies the log file for entity lifecycle messages. + When a logfile is specified the service will open the logfile and + write a corresponding log line for each update of discovered entities. + +- Full path: //OpenSplice/Domain/BuiltinTopics[@logfile] +- Format: string +- Default value: builtin.log +- Required: false + PriorityInheritance =================== @@ -1591,7 +1629,7 @@ enabled Report ====== - The Report element controls some aspects of the OpenSplice domain logging + The Report element controls some aspects of the Vortex OpenSplice domain logging functionality. - Full path: //OpenSplice/Domain/Report @@ -1640,7 +1678,7 @@ Statistics ========== This element specifies the policies regarding statistics. Various statistics - can be generated by OpenSplice DDS to help you analyze and tune application + can be generated by Vortex OpenSplice to help you analyze and tune application behaviour during application development. Since this introduces extra overhead, it is generally turned off in a runtime system. @@ -1751,7 +1789,7 @@ symbol_name The result value is used to return the status of the call. If it is 0 then the operation was successful. If it is not 0 then there was an error and details of the error and the - result value are reported to the OpenSplice DDS default report service. + result value are reported to the Vortex OpenSplice default report service. The context parameter is an out reference that can be set to plugin-specific data that will subsequently be passed to any of the other plugin functions. The value of the parameter is meaningless to the service @@ -1793,7 +1831,7 @@ symbol_name resolved, an error message will be generated and the service will not attempt to resolve other symbol_names for the report plugin. The function is invoked slightly differently for applications using the DDS API and - OpenSplice services. OpenSplice services invoke the function once for every report. + Vortex OpenSplice services. Vortex OpenSplice services invoke the function once for every report. For applications using the DDS API the function is invoked once per API call, in which case the XML is extended by one or more DETAIL elements. The implementation of this function must have the following signature: @@ -1801,7 +1839,7 @@ symbol_name The result value is used to return the status of the call. If it is 0 then the operation was successful. If it is not 0 then there was an error and details of the error and the - result value are reported to the OpenSplice DDS default report service. + result value are reported to the Vortex OpenSplice default report service. The context parameter is a reference to the plugin-specific data retrieved from the initialize operation. The report parameter is an XML string representation of the report data. @@ -1921,7 +1959,7 @@ symbol_name The result value is used to return the status of the call. If it is 0 then the operation was successful. If it is not 0 then there was an error and details of the error and the - result value are reported to the OpenSplice DDS default report service. + result value are reported to the Vortex OpenSplice default report service. - Full path: //OpenSplice/Domain/ReportPlugin/TypedReport[@symbol_name] - Format: string @@ -1952,7 +1990,7 @@ symbol_name int symbol_name (void \*context) The result value is used to return the status of the call. If it is 0 then the operation was successful. If it is not 0 then there was an error and details of the error and the - result value are reported to the OpenSplice DDS default report service. + result value are reported to the Vortex OpenSplice default report service. The context parameter is a reference to the plugin-specific data retrieved from the initialize operation. @@ -1979,8 +2017,8 @@ ServicesOnly ------------ This attribute specifies whether the log plug-in is to be effective only for processes - that are exclusively OpenSplice services. If this value is true then the plug-in will - not be used for user applications and/or OpenSplice services collocated with user + that are exclusively Vortex OpenSplice services. If this value is true then the plug-in will + not be used for user applications and/or Vortex OpenSplice services collocated with user applications in single process mode. - Full path: //OpenSplice/Domain/ReportPlugin/ServicesOnly @@ -2230,7 +2268,7 @@ UserClock ========= The UserClock Service allows you to plug in a custom clock library, allowing - OpenSplice to read the time from an external clock source. It expects a root + Vortex OpenSplice to read the time from an external clock source. It expects a root element named *OpenSplice/Domain/UserClock*. Within this root element, the userclock will look for several child-elements. Each of these is listed and explained. @@ -2459,7 +2497,7 @@ cache y2038Ready ========== - The y2038Ready element determines that OpenSplice will send timestamps to other nodes + The y2038Ready element determines that Vortex OpenSplice will send timestamps to other nodes in a 64-bit format which is capable to contain time stamps beyond the year 2038. Setting this option to true will force the middleware to communicate with time stamps able to go @@ -2487,11 +2525,90 @@ See ' time stamps and year 2038 limit' for more background information. - Default value: false - Occurrences min-max: 0-1 +Filters +======= + + Domain Filters are expressions that are applied on the local Domain Service meaning that it affects all local readers + including services, i.e. filtered out data will not exist on the node. + By using filters the amount of data that is being send or received can be reduced. + + + Different filters can be specified for different partition-topic + combinations using the <Filter>-elements. + + + Note: that when a filter is set on a partition topic combination the Durability Service can no longer be master for + the namespace that contains the given partition-topic combination as it is incomplete by definition. + +- Full path: //OpenSplice/Domain/Filters +- Occurrences min-max: 0-1 + +Filter +------ + + This element specifies the filter that is used. The <PartitionTopic>-child + elements specify the partition-topic combinations to which the + filter expression is applied. + + + If no filter is defined for a particular partition-topic then all data will be + send for this partition-topic combination. + If multiple filters are defined then the first one that matches will be applied. + +- Full path: //OpenSplice/Domain/Filters/Filter +- Occurrences min-max: 0-* +- Child elements: PartitionTopic +- Required attributes: content + +content +^^^^^^^ + + This attribute specifies the expression that is used for filtering. + The expression is a string that is used as-is without any parameters. + The filter expression is essentially the where-clauses of an sql expression. + When data is requested for matching partition-topics only the data + that matches the filter expression will be aligned. The + content attribute defaults to the empty string, which means that + no filter is applied at all. + + + The following escape sequence can be used in expressions: &lt; + (less than), &gt; (greater than), &quot; (double quote) + &apos; (apostrophe) and &amp; (ampersand). + + + Examples of expressions are: + + - x=1 or x=2 + - (id&lt;10) and (name="test") + + + If an invalid filter expression is provided an error will be logged + in ospl-error.log. + +- Full path: //OpenSplice/Domain/Filters/Filter[@content] +- Format: string +- Default value: n/a +- Required: true + +PartitionTopic +^^^^^^^^^^^^^^ + + This element specifies the partition-topics to which + the filter expression is applied. A partition-topic + expression may contain the wildcards '\*' to match any number of + characters and '?' to match one single character. + +- Full path: //OpenSplice/Domain/Filters/Filter/PartitionTopic +- Format: string +- Default value: *.* +- Occurrences min-max: 0-* + DurabilityService ***************** The responsibilities of the durability service are to realize the durable properties of - data in an OpenSplice system. The Durability Service looks for its configuration + data in an Vortex OpenSplice system. The Durability Service looks for its configuration within the 'OpenSplice/DurabilityService' element. The configuration parameters that the Durability Service will look for within this element are listed and explained in the following subsections. @@ -2550,7 +2667,7 @@ EntityNames This element specifies the names of the various entities used by the client-durability feature of this DurabilityService. The names specified - here will be displayed in the OpenSplice DDS Tuner when viewing the + here will be displayed in the Vortex OpenSplice Tuner when viewing the DurabilityService. - Full path: //OpenSplice/DurabilityService/ClientDurability/EntityNames @@ -2733,7 +2850,7 @@ Heartbeat --------- During startup and at runtime, the network topology can change - dynamically. This happens when OpenSplice services are started/stopped + dynamically. This happens when Vortex OpenSplice services are started/stopped or when a network cable is plugged in/out. The Durability services need to keep data consistency in that environment. To detect newly joining services as well as detecting nodes that are leaving, the @@ -2948,9 +3065,15 @@ TimeAlignment the domain can be considered aligned or not. This setting needs to be consistent for all durability services in the domain. In case there is no time alignment, the durability - service needs to align more data since to compensate possible + service needs to align more data to compensate for possible timing gaps between different nodes in the domain. + When using DDSI2(e) networking service it is strongly recommended + to set this value to 'false'. The asynchronous nature of the DDSI2 + discovery protocol in combination with TimeAlignment could lead to a + gap in transient/persistent data when Durability alignment and DDSI2 + discovery coincide, which is normal behavior. + - Full path: //OpenSplice/DurabilityService/Network/Alignment/TimeAlignment - Format: boolean - Default value: true @@ -3088,7 +3211,7 @@ RequestCombinePeriod but will decrease the processing and network load in case multiple Durability services need to resolve the same data around the same time. Increasing the value - is useful in case OpenSplice is started at the same time + is useful in case Vortex OpenSplice is started at the same time with more than two computing nodes. - Full path: //OpenSplice/DurabilityService/Network/Alignment/RequestCombinePeriod @@ -3261,6 +3384,38 @@ ServiceName - Default value: networking - Occurrences min-max: 1-* +MasterElection +============== + + For every namespace and role a single node is elected master, the one to + provide historical data. This optional element can be used to fine-fune the + characteristics of the master election algorithm. + + This element is optional, and when used only applies to master election for + namespaces with non-legacy masterPriority (see + //OpenSplice/DurabilityService/NameSpaces/Policy[@masterPriority]). + +- Full path: //OpenSplice/DurabilityService/MasterElection +- Occurrences min-max: 0-1 +- Child elements: WaitTime + +WaitTime +-------- + + Before the durability service elects a master it can waits some time to + detect other nodes in the system. Waiting might increase the possibility + to elect a better candidate, but slows down the master election process. + Electing a master too early may lead to additional alignment actions when + a better candidate appears later, because a handover of mastership is needed. + When the chance that a better master candicate appears within the WaitTime + is small it is advised to set this value to 0.0 (the default). + +- Full path: //OpenSplice/DurabilityService/MasterElection/WaitTime +- Dimension: seconds +- Default value: 0.0 +- Valid values: 0.0 / 10.0 +- Occurrences min-max: 0-1 + Persistent ========== @@ -3274,7 +3429,7 @@ Persistent the persistent properties of the data. Note these elements are only available as part of the DDS - persistence profile of OpenSplice. + persistence profile of Vortex OpenSplice. - Full path: //OpenSplice/DurabilityService/Persistent - Occurrences min-max: 0-1 @@ -3330,20 +3485,16 @@ StoreMode This element specifies the plug-in that is used to store the persistent data on disk. With "XML" mode, the service will store - persistent data in XML files. With "MMF", the service will store - persistent data in a Memory Mapped File that exactly represents - the memory that is being used by the persistent store. - With "KV" mode the service will store persistent data in a key-value - store using either sqlite of leveldb to store the data on disk. - !!! The "MMF" store is deprecated from version 6.3 and was only implemented on linux !!!, - + persistent data in XML files. With "KV" mode the service will store + persistent data in a key-value store using either sqlite of leveldb + to store the data on disk. !!! For "KV" stores, SQLite is supported on linux, Windows, and Solaris; LevelDB is only supported on linux. - Full path: //OpenSplice/DurabilityService/Persistent/StoreMode - Format: enumeration - Default value: XML -- Valid values: XML, MMF, KV +- Valid values: XML, KV - Occurrences min-max: 0-1 SmpCount @@ -3384,12 +3535,25 @@ type ^^^^ This attribute specifies the third-party product that is used to implement the KV store. - Products currently supported are SQLite and LevelDB + Products currently supported are SQLite and LevelDB. + The following types can be selected: + + - sqlite3 -use sqlite3 as the key value store. Data in the store is stored efficiently + as binary blobs. This is the default. + - sqlite - same as sqlite3. This option is present for backward compatibility. + - sqlitemt - use sqlite3 as the key value store implementation, but + stores the information as readable data. This mode allows a user to inspect the + contents of the store, but the store performance will be lower compared to sqlite3 + because each piece of data must be translated to readable format. This option is + typically used for testing purposes to inspect the contents of the store. + + (Note: the abbreviation 'mt' stands for 'multi-table'). + - leveldb - use leveldb as the key value store - Full path: //OpenSplice/DurabilityService/Persistent/KeyValueStore[@type] - Format: enumeration - Default value: sqlite3 -- Valid values: sqlite3, sqlite, leveldb +- Valid values: sqlite3, sqlite, sqlitemt, leveldb - Required: true StorageParameters @@ -3484,7 +3648,7 @@ algorithm This attribute specifies the compression algorithm that is used to store the persistent data in the key-value store. - The lzf and snappy compression algorithms are built into the OpenSplice + The lzf and snappy compression algorithms are built into the Vortex OpenSplice installation. To use the zlib algorithm a shared library needs to be available on the system, and it must be locatable by way of the current working directory, or via LD_LIBRARY_PATH (on Unix systems) or PATH (on Windows systems). @@ -3506,61 +3670,6 @@ enabled - Default value: true - Required: false -MemoryMappedFileStore ---------------------- - - This element specifies the memory mapped file store mode parameters. This - element is only valid when the Persistent/StoreMode element is set to "MMF". - The size and the starting address of the memory file must be supplied - The "MMF" store is deprecated from version 6.3. and was only implemented in Linux - -- Full path: //OpenSplice/DurabilityService/Persistent/MemoryMappedFileStore -- Occurrences min-max: 0-1 -- Child elements: Size, Address - -Size -^^^^ - - This element specifies the size of the memory mapped file used to - store persistent data. Change this value according to the size of - your persistent data. The file should be big enough to store: - - - all persistent data in your specified namespaces - - PLUS a potential backup for all persistent data in namespaces whose content may be replaced by persistent data from another master. - - - As a rule of thumb, you could state that the persistent store should - be twice the size of your combined persistent data in your specified - namespaces. Please note that the operating system should be configured - to support the requested size. - - If this value is not specified, the size of the persistent store will be - set to twice the size of the shared memory segment. - -- Full path: //OpenSplice/DurabilityService/Persistent/MemoryMappedFileStore/Size -- Default value: 10485760 -- Valid values: 1048576 / - -- Occurrences min-max: 0-1 - -Address -^^^^^^^ - - This element specifies the start address where the - file is mapped into the virtual memory. - The possible values are platform dependent. - - Change this value if the default address is already in - use, for example by another Domain Service or another - product. - - If this value is not specified, the file will be mapped - just after the shared memory segment. - -- Full path: //OpenSplice/DurabilityService/Persistent/MemoryMappedFileStore/Address -- Format: string -- Default value: 0x80000000 -- Occurrences min-max: 0-1 - StoreOptimizeInterval --------------------- @@ -3749,7 +3858,7 @@ Policy - Full path: //OpenSplice/DurabilityService/NameSpaces/Policy - Occurrences min-max: 0-* - Required attributes: nameSpace, durability, aligner, alignee -- Optional attributes: delayedAlignment, equalityCheck +- Optional attributes: delayedAlignment, equalityCheck, masterPriority Merge ^^^^^ @@ -3944,97 +4053,37 @@ equalityCheck - Default value: False - Required: false -Filters -------- - - Filters are expressions that are applied when historical - data is requested from another durability service. By using - filters the amount of alignment data between durability - services can be reduced. - - - Different filters can be specified for different partition-topic - combinations using the <Filter>-elements. - - - **NOTE** A side effect can occur when filters are - used in combination with the ability to align data. - In case a node that has retrieved a subset of historical data - using filters becomes the aligner to other nodes at some - point in time, then only this subset will be aligned to the other - nodes. - -- Full path: //OpenSplice/DurabilityService/NameSpaces/Filters -- Occurrences min-max: 0-1 - -Filter -^^^^^^ - - This element specifies the filter expression that is used when - historical data is requested. The <PartitionTopic>-child - elements specify the partition-topic combinations to which the - filter expression is applied. - - - If no filter is defined for a particular partition-topic then all data will be - aligned for this partition-topic combination. - If multiple filters are defined then the first one that matches will be applied. - -- Full path: //OpenSplice/DurabilityService/NameSpaces/Filters/Filter -- Occurrences min-max: 0-* -- Child elements: PartitionTopic -- Required attributes: content - -content -~~~~~~~ - - This attribute specifies the expression that is used for filtering. - The expression is a string that is used as-is without any parameters. - The filter expression is essentially the where-clauses of an sql expression. - When data is requested for matching partition-topics only the data - that matches the filter expression will be aligned. The - content attribute defaults to the empty string, which means that - no filter is applied at all. - - - The following escape sequence can be used in expressions: &lt; - (less than), &gt; (greater than), &quot; (double quote) - &apos; (apostrophe) and &amp; (ampersand). - - - Examples of expressions are: - - - x=1 or x=2 - - (id&lt;10) and (name="test") - - - If an invalid filter expression is provided an error will be logged - in ospl-error.log. - -- Full path: //OpenSplice/DurabilityService/NameSpaces/Filters/Filter[@content] -- Format: string -- Default value: n/a -- Required: true - -PartitionTopic -~~~~~~~~~~~~~~ - - This element specifies the partition-topics to which - the filter expression is applied. A partition-topic - expression may contain the wildcards '\*' to match any number of - characters and '?' to match one single character. +masterPriority +^^^^^^^^^^^^^^ -- Full path: //OpenSplice/DurabilityService/NameSpaces/Filters/Filter/PartitionTopic -- Format: string -- Default value: *.* -- Occurrences min-max: 0-* + This attribute sets the master selection priority of the namespace. + The default value is 255, this allows to modify a single durability service in + an existing system to become both preferred master as well as non-preferred master + without having to change the configuration of all durability services. + The Durability Service will never become master for a namespace when the + masterPriority is set to zero. + When set to 255 the durability Service will not use priorities at all, and falls back + to the legacy master selection algorithm. + If the masterPriority is set other than 0 and 255 the Durability Service will become master if + it has the highest masterPriority of all discovered Durability Services for the namespace. + If multiple Durability Services exist having equally highest masterPriority + a further selection will be made based on the highest namespace quality of each + Durability Service (but only if persistent data has not been injected before). + Then if there are still multiple equally suitable Durability Services the + Durability Service with the highest system id will be selected. + +- Full path: //OpenSplice/DurabilityService/NameSpaces/Policy[@masterPriority] +- Format: integer +- Default value: 255 +- Valid values: 0 / 255 +- Required: false EntityNames =========== This element specifies the names of the various entities used by the DurabilityService. The names specified here will be displayed in the - OpenSplice DDS Tuner when viewing the DurabilityService. + Vortex OpenSplice Tuner when viewing the DurabilityService. - Full path: //OpenSplice/DurabilityService/EntityNames - Occurrences min-max: 0-1 @@ -4256,7 +4305,7 @@ NetworkInterfaceAddress Every Secure Networking service is bound to only one network interface card (NIC). The card can be uniquely identified by its corresponding IP address or by its symbolic name (e.g. eth0). If the - value "first available" is entered here, the OpenSplice + value "first available" is entered here, the Vortex OpenSplice middleware will try to look up an interface that has the required capabilities. @@ -4335,7 +4384,7 @@ EnableMulticastLoopback EnableMulticastLoopback specifies whether the secure networking service will allow IP multicast packets within the node to be visible to all secure networking participants in the node, including itself. It must be TRUE for intra-node multicast communications, - but if a node runs only a single OpenSplice secure networking service and does not host + but if a node runs only a single Vortex OpenSplice secure networking service and does not host any other networking-capable programs, it may be set to FALSE for improved performance. - Full path: //OpenSplice/SNetworkService/General/EnableMulticastLoopback @@ -4393,7 +4442,7 @@ allowed Partitioning ============ - The OpenSplice Secure Networking service is capable of leveraging + The Vortex OpenSplice Secure Networking service is capable of leveraging the network's multicast and routing capabilities. If some a-priori knowledge about the participating nodes and their topic and partition interest is available, then the @@ -4522,7 +4571,7 @@ commas (,) semicolons (;) or spaces ( ). Samples for this partition will be sent all addresses that are specified in this list of addresses. To specify the default broadcast address, use the expression "broadcast". Addresses can be entered as 'dotted decimal' IPv4 or 'colon-separated hexadecimal' IPv6 notation or as the -symbolic hostname, in which case OpenSplice will try to resolve the corresponding +symbolic hostname, in which case Vortex OpenSplice will try to resolve the corresponding IP address. - Full path: //OpenSplice/SNetworkService/Partitioning/NetworkPartitions/NetworkPartition[@Address] @@ -4579,11 +4628,11 @@ SecurityProfile security feature has been enabled but no profile is declared, the NULL profile will be used by default. The ordering of network partition declarations in the OSPL configuration file must - be the same for all nodes within the OpenSplice domain. If certain nodes shall not + be the same for all nodes within the Vortex OpenSplice domain. If certain nodes shall not use one of the network partitions, the network partition in question must be declared as connected="false". In this case the declared security profile would not be evaluated or initialized, and the associated secret cipher keys need not to be defined - for the OpenSplice node in question. + for the Vortex OpenSplice node in question. - Full path: //OpenSplice/SNetworkService/Partitioning/NetworkPartitions/NetworkPartition[@SecurityProfile] - Format: string @@ -4715,7 +4764,7 @@ enabled NULL cipher does not provide for any level of integrity or confidentiality, but message items will be sent unencrypted. In case of enabled="false" the security feature will not be activated, and the - node acts like any other OpenSplice node not being security aware. Security profiles + node acts like any other Vortex OpenSplice node not being security aware. Security profiles defined in the configuration file will not take effect, but will cause the system to log warnings. @@ -4753,9 +4802,9 @@ Cipher have a specific length, 128 bits, 192 bits, 256 bits or none at all. The following case-insensitive values are supported by the current implementation: - - aes128, implements AES cipher with 128 bit cipher-key (16 Bytes, 32 hexadecimal characters). This cipher will occupy 34 bytes of each UDP packet being sent. + - aes128, implements the AES cipher with 128 bit cipher-key (16 Bytes, 32 hexadecimal characters). This cipher will occupy 34 bytes of each UDP packet being sent. - aes192, implements the AES cipher with 192 bit cipher-key (24 Bytes, 48 hexadecimal characters). This cipher will occupy 34 bytes of each UDP packet being sent. - - aes256, implements the AES cipher with 256 bit cipher-key (32 Bytes, 64 hexadecimal characters. This cipher will occupy 34 bytes of each UDP packet being sent. + - aes256, implements the AES cipher with 256 bit cipher-key (32 Bytes, 64 hexadecimal characters). This cipher will occupy 34 bytes of each UDP packet being sent. - blowfish, implements the Blowfish cipher with 128 bit cipher-key (16 Bytes, 32 hexadecimal characters). This cipher will occupy 26 bytes of each UDP packet being sent. - null, implements the NULL cipher. The only cipher that does not require a cipher-key. This cipher will occupy 4 bytes of each UDP packet being sent. @@ -4783,14 +4832,14 @@ CipherKey will be marked as invalid. Moreover, each network partition referring to the invalid Security Profile will not be operational and thus traffic will be blocked to prevent information leaks. - As all OpenSplice applications require read access to the XML configuration file, + As all Vortex OpenSplice applications require read access to the XML configuration file, for security reasons it is recommended to store the secret key in an external file in the file system, referenced by the URI in the configuration file. The file must be protected against read and write access from other users on the host. Verify that access rights are not given to any other user or group on the host. Alternatively, storing the secret key in-place in the XML configuration file will give - read/write access to all DDS applications joining the same OpenSplice node. + read/write access to all DDS applications joining the same Vortex OpenSplice node. Because of this, the 'in-place' method is strongly discouraged. - Full path: //OpenSplice/SNetworkService/Security/SecurityProfile[@CipherKey] @@ -4853,7 +4902,7 @@ enabled type ~~~~ - The type attribute defines the access control model type. Currently, OpenSplice only + The type attribute defines the access control model type. Currently, Vortex OpenSplice only supports mandatory access control, accordingly the only valid value for this attribute is "MAC". @@ -4910,7 +4959,7 @@ Key It is recommended that the absolute path is used. A relative path will be interpreted relative to the directory from which the - OpenSplice daemon is started. + Vortex OpenSplice daemon is started. - Full path: //OpenSplice/SNetworkService/Security/Authentication/X509Authentication/Credentials/Key - Format: string @@ -4923,7 +4972,7 @@ Cert It is recommended that the absolute path is used. A relative path will be interpreted relative to the directory from which the - OpenSplice daemon is started. + Vortex OpenSplice daemon is started. - Full path: //OpenSplice/SNetworkService/Security/Authentication/X509Authentication/Credentials/Cert - Format: string @@ -4936,7 +4985,7 @@ TrustedCertificates It is recommended that the absolute path is used. A relative path will be interpreted relative to the directory from which the - OpenSplice daemon is started. + Vortex OpenSplice daemon is started. - Full path: //OpenSplice/SNetworkService/Security/Authentication/X509Authentication/TrustedCertificates - Format: string @@ -5157,12 +5206,12 @@ Sending - Full path: //OpenSplice/SNetworkService/Channels/Channel/Sending - Occurrences min-max: 0-1 -- Child elements: CrcCheck, QueueSize, MaxBurstSize, ThrottleLimit, ThrottleThreshold, MaxRetries, RecoveryFactor, DiffServField, DontRoute, TimeToLive +- Child elements: CrcCheck, QueueSize, MaxBurstSize, ThrottleLimit, ThrottleThreshold, MaxRetries, RecoveryFactor, DiffServField, DontRoute, DontFragment, TimeToLive CrcCheck ~~~~~~~~ - In order to protect OpenSplice network packets from malicious attack the CrcCheck(cyclic redundancy check) configuration item has been added. + In order to protect Vortex OpenSplice network packets from malicious attack the CrcCheck(cyclic redundancy check) configuration item has been added. CRCs are specifically designed to protect against common types of errors on communication channels. When enabled the integrity of delivered network packets from one DDS process to another is assured. There is a small performance cost using this feature due to the addtional overhead of carrying out the crc calculation. @@ -5303,7 +5352,7 @@ DiffServField For Windows version 7 or higher a new API (qWAVE) has been introduced For these platforms the specified diffserv value is mapped to one of the support traffic types. The mapping is as follows: 1-8 background traffic; 9-40 excellent traffic; 41-55 audio/video traffic; 56 voice traffic; 57-63 control traffic. - When OpenSplice is run without Administrative priveleges then only the diffserv value of 0, 8, 40 or 56 is allowed. + When Vortex OpenSplice is run without Administrative priveleges then only the diffserv value of 0, 8, 40 or 56 is allowed. - Full path: //OpenSplice/SNetworkService/Channels/Channel/Sending/DiffServField - Format: integer @@ -5322,6 +5371,19 @@ The IP DONTROUTE - Valid values: True, False - Occurrences min-max: 0-1 +DontFragment +~~~~~~~~~~~~ + + Controls whether the "don't fragment" bit (DF) is set on outgoing UDP IPv4 packets. + Note that not all operating systems support setting this bit. When the operating + system does not support setting the DF bit this option is ignored. + +- Full path: //OpenSplice/SNetworkService/Channels/Channel/Sending/DontFragment +- Format: boolean +- Default value: False +- Valid values: True, False +- Occurrences min-max: 0-1 + TimeToLive ~~~~~~~~~~ For each UDP packet sent out, the IP Time To Live @@ -5395,7 +5457,7 @@ Receiving CrcCheck ~~~~~~~~ - In order to protect OpenSplice network packets from malicious attack the CrcCheck(cyclic redundancy check) configuration item has been added. + In order to protect Vortex OpenSplice network packets from malicious attack the CrcCheck(cyclic redundancy check) configuration item has been added. CRCs are specifically designed to protect against common types of errors on communication channels. When enabled the integrity of delivered network packets from one DDS process to another is assured. There is a small performance cost using this feature due to the addtional overhead of carrying out the crc calculation. @@ -5683,12 +5745,12 @@ Sending - Full path: //OpenSplice/SNetworkService/Discovery/Sending - Occurrences min-max: 0-1 -- Child elements: CrcCheck, DiffServField, DontRoute, TimeToLive, Interval, SafetyFactor, SalvoSize +- Child elements: CrcCheck, DiffServField, DontRoute, DontFragment, TimeToLive, Interval, SafetyFactor, SalvoSize CrcCheck ^^^^^^^^ - In order to protect OpenSplice network packets from malicious attack the CrcCheck(cyclic redundancy check) configuration item has been added. + In order to protect Vortex OpenSplice network packets from malicious attack the CrcCheck(cyclic redundancy check) configuration item has been added. CRCs are specifically designed to protect against common types of errors on communication channels. When enabled the integrity of delivered network packets from one DDS process to another is assured. There is a small performance cost using this feature due to the addtional overhead of carrying out the crc calculation. @@ -5726,7 +5788,7 @@ DiffServField For Windows version 7 or higher a new API (qWAVE) has been introduced For these platforms the specified diffserv value is mapped to one of the support traffic types. The mapping is as follows: 1-8 background traffic; 9-40 excellent traffic; 41-55 audio/video traffic; 56 voice traffic; 57-63 control traffic. - When OpenSplice is run without Administrative priveleges then only the diffserv value of 0, 8, 40 or 56 is allowed. + When Vortex OpenSplice is run without Administrative priveleges then only the diffserv value of 0, 8, 40 or 56 is allowed. - Full path: //OpenSplice/SNetworkService/Discovery/Sending/DiffServField - Format: integer @@ -5745,6 +5807,19 @@ The IP DONTROUTE - Valid values: True, False - Occurrences min-max: 0-1 +DontFragment +^^^^^^^^^^^^ + + Controls whether the "don't fragment" bit (DF) is set on outgoing UDP IPv4 packets. + Note that not all operating systems support setting this bit. When the operating + system does not support setting the DF bit this option is ignored. + +- Full path: //OpenSplice/SNetworkService/Discovery/Sending/DontFragment +- Format: boolean +- Default value: False +- Valid values: True, False +- Occurrences min-max: 0-1 + TimeToLive ^^^^^^^^^^ For each UDP packet sent out, the IP Time To Live @@ -5851,7 +5926,7 @@ Receiving CrcCheck ^^^^^^^^ - In order to protect OpenSplice network packets from malicious attack the CrcCheck(cyclic redundancy check) configuration item has been added. + In order to protect Vortex OpenSplice network packets from malicious attack the CrcCheck(cyclic redundancy check) configuration item has been added. CRCs are specifically designed to protect against common types of errors on communication channels. When enabled the integrity of delivered network packets from one DDS process to another is assured. There is a small performance cost using this feature due to the addtional overhead of carrying out the crc calculation. @@ -5944,7 +6019,7 @@ Tracing - Full path: //OpenSplice/SNetworkService/Tracing - Occurrences min-max: 0-1 -- Child elements: OutputFile, Timestamps +- Child elements: OutputFile, Timestamps, Verbosity - Optional attributes: enabled enabled @@ -6153,6 +6228,26 @@ Discovery - Valid values: 0 / 6 - Occurrences min-max: 0-1 +Verbosity +--------- + +The Verbosity attribute sets the level of tracing for all Tracing Catagories. This attribute is an additional method besides the Tracing/Catagories tag to specify trace levels. The difference is that Verbosity sets the level for all catagories similar as by other services whereas the Tracing/Catagories element allows to set the trace level per catagory. The verbosity levels are mapped to Catagory levels as following: + +- *none*: level 0 (no Networking log) +- *severe*: level 1 +- *warning*: level 2 +- *info*: level 3 +- *config*: level 3 +- *fine*: level 4 +- *finer*: level 5 +- *finest*: level 6 + +- Full path: //OpenSplice/SNetworkService/Tracing/Verbosity +- Format: enumeration +- Default value: none +- Valid values: finest, finer, fine, config, info, warning, severe, none +- Occurrences min-max: 0-1 + Compression =========== @@ -6161,7 +6256,7 @@ Compression networking service includes (depending on platform) implementations of zlib, lzf and snappy. Others may be implemented by writing a dynamically-loadable library and configuring it here. See the - OpenSplice release notes for details of how to write such a + Vortex OpenSplice release notes for details of how to write such a library. It is imperative that all nodes exchanging compressed data @@ -6217,7 +6312,7 @@ NetworkService The Network Service provides a bridge between the local DDS service and a network interface. -The OpenSplice NetworkService supports both Internet Protocol +The Vortex OpenSplice NetworkService supports both Internet Protocol Versions 4 and 6 (IPv4 & IPv6) where possible. Please refer to the Release Notes (Known Issues section) to see if the IPv6 capability is present on your operating system. @@ -6245,7 +6340,7 @@ Domain section of the configuration file (Element Application). * The network configuration expects a root element named -OpenSplice/NetworkService. Within this root element, the Network Service +Vortex OpenSplice/NetworkService. Within this root element, the Network Service will look for several child-elements. Each of these is listed and explained. - Full path: //OpenSplice/NetworkService @@ -6343,7 +6438,7 @@ NetworkInterfaceAddress Every Networking service is bound to only one network interface card (NIC). The card can be uniquely identified by its corresponding IP address or by its symbolic name (e.g. eth0). If the - value "first available" is entered here, the OpenSplice + value "first available" is entered here, the Vortex OpenSplice middleware will try to look up an interface that has the required capabilities. @@ -6423,7 +6518,7 @@ EnableMulticastLoopback EnableMulticastLoopback specifies whether the networking service will allow IP multicast packets within the node to be visible to all networking participants in the node, including itself. It must be TRUE for intra-node multicast communications, - but if a node runs only a single OpenSplice networking service and does not host + but if a node runs only a single Vortex OpenSplice networking service and does not host any other networking-capable programs, it may be set to FALSE for improved performance. - Full path: //OpenSplice/NetworkService/General/EnableMulticastLoopback @@ -6481,7 +6576,7 @@ allowed Partitioning ============ - The OpenSplice Networking service is capable of leveraging + The Vortex OpenSplice Networking service is capable of leveraging the network's multicast and routing capabilities. If some a-priori knowledge about the participating nodes and their topic and partition interest is available, then the @@ -6657,11 +6752,11 @@ SecurityProfile security feature has been enabled but no profile is declared, the NULL profile will be used by default. The ordering of network partition declarations in the OSPL configuration file must - be the same for all nodes within the OpenSplice domain. If certain nodes shall not + be the same for all nodes within the Vortex OpenSplice domain. If certain nodes shall not use one of the network partitions, the network partition in question must be declared as connected="false". In this case the declared security profile would not be evaluated or initialized, and the associated secret cipher keys need not to be defined - for the OpenSplice node in question. + for the Vortex OpenSplice node in question. - Full path: //OpenSplice/NetworkService/Partitioning/NetworkPartitions/NetworkPartition[@SecurityProfile] - Format: string @@ -6978,12 +7073,12 @@ Sending - Full path: //OpenSplice/NetworkService/Channels/Channel/Sending - Occurrences min-max: 0-1 -- Child elements: CrcCheck, QueueSize, MaxBurstSize, ThrottleLimit, ThrottleThreshold, MaxRetries, RecoveryFactor, DiffServField, DontRoute, TimeToLive, ReportInterval +- Child elements: CrcCheck, QueueSize, MaxBurstSize, ThrottleLimit, ThrottleThreshold, MaxRetries, RecoveryFactor, DiffServField, DontRoute, DontFragment, TimeToLive, ReportInterval CrcCheck ~~~~~~~~ - In order to protect OpenSplice network packets from malicious attack the CrcCheck(cyclic redundancy check) configuration item has been added. + In order to protect Vortex OpenSplice network packets from malicious attack the CrcCheck(cyclic redundancy check) configuration item has been added. CRCs are specifically designed to protect against common types of errors on communication channels. When enabled the integrity of delivered network packets from one DDS process to another is assured. There is a small performance cost using this feature due to the addtional overhead of carrying out the crc calculation. @@ -7104,7 +7199,7 @@ DiffServField For Windows version 7 or higher a new API (qWAVE) has been introduced For these platforms the specified diffserv value is mapped to one of the support traffic types. The mapping is as follows: 1-8 background traffic; 9-40 excellent traffic; 41-55 audio/video traffic; 56 voice traffic; 57-63 control traffic. - When OpenSplice is run without Administrative priveleges then only the diffserv value of 0, 8, 40 or 56 is allowed. + When Vortex OpenSplice is run without Administrative priveleges then only the diffserv value of 0, 8, 40 or 56 is allowed. - Full path: //OpenSplice/NetworkService/Channels/Channel/Sending/DiffServField - Format: integer @@ -7123,6 +7218,19 @@ The IP DONTROUTE - Valid values: True, False - Occurrences min-max: 0-1 +DontFragment +~~~~~~~~~~~~ + + Controls whether the "don't fragment" bit (DF) is set on outgoing UDP IPv4 packets. + Note that not all operating systems support setting this bit. When the operating + system does not support setting the DF bit this option is ignored. + +- Full path: //OpenSplice/NetworkService/Channels/Channel/Sending/DontFragment +- Format: boolean +- Default value: False +- Valid values: True, False +- Occurrences min-max: 0-1 + TimeToLive ~~~~~~~~~~ For each UDP packet sent out, the IP Time To Live @@ -7196,7 +7304,7 @@ Receiving CrcCheck ~~~~~~~~ - In order to protect OpenSplice network packets from malicious attack the CrcCheck(cyclic redundancy check) configuration item has been added. + In order to protect Vortex OpenSplice network packets from malicious attack the CrcCheck(cyclic redundancy check) configuration item has been added. CRCs are specifically designed to protect against common types of errors on communication channels. When enabled the integrity of delivered network packets from one DDS process to another is assured. There is a small performance cost using this feature due to the addtional overhead of carrying out the crc calculation. @@ -7495,12 +7603,12 @@ Sending - Full path: //OpenSplice/NetworkService/Discovery/Sending - Occurrences min-max: 0-1 -- Child elements: CrcCheck, DiffServField, DontRoute, TimeToLive, Interval, SafetyFactor, SalvoSize +- Child elements: CrcCheck, DiffServField, DontRoute, DontFragment, TimeToLive, Interval, SafetyFactor, SalvoSize CrcCheck ^^^^^^^^ - In order to protect OpenSplice network packets from malicious attack the CrcCheck(cyclic redundancy check) configuration item has been added. + In order to protect Vortex OpenSplice network packets from malicious attack the CrcCheck(cyclic redundancy check) configuration item has been added. CRCs are specifically designed to protect against common types of errors on communication channels. When enabled the integrity of delivered network packets from one DDS process to another is assured. There is a small performance cost using this feature due to the addtional overhead of carrying out the crc calculation. @@ -7538,7 +7646,7 @@ DiffServField For Windows version 7 or higher a new API (qWAVE) has been introduced For these platforms the specified diffserv value is mapped to one of the support traffic types. The mapping is as follows: 1-8 background traffic; 9-40 excellent traffic; 41-55 audio/video traffic; 56 voice traffic; 57-63 control traffic. - When OpenSplice is run without Administrative priveleges then only the diffserv value of 0, 8, 40 or 56 is allowed. + When Vortex OpenSplice is run without Administrative priveleges then only the diffserv value of 0, 8, 40 or 56 is allowed. - Full path: //OpenSplice/NetworkService/Discovery/Sending/DiffServField - Format: integer @@ -7557,6 +7665,19 @@ The IP DONTROUTE - Valid values: True, False - Occurrences min-max: 0-1 +DontFragment +^^^^^^^^^^^^ + + Controls whether the "don't fragment" bit (DF) is set on outgoing UDP IPv4 packets. + Note that not all operating systems support setting this bit. When the operating + system does not support setting the DF bit this option is ignored. + +- Full path: //OpenSplice/NetworkService/Discovery/Sending/DontFragment +- Format: boolean +- Default value: False +- Valid values: True, False +- Occurrences min-max: 0-1 + TimeToLive ^^^^^^^^^^ For each UDP packet sent out, the IP Time To Live @@ -7674,7 +7795,7 @@ Receiving CrcCheck ^^^^^^^^ - In order to protect OpenSplice network packets from malicious attack the CrcCheck(cyclic redundancy check) configuration item has been added. + In order to protect Vortex OpenSplice network packets from malicious attack the CrcCheck(cyclic redundancy check) configuration item has been added. CRCs are specifically designed to protect against common types of errors on communication channels. When enabled the integrity of delivered network packets from one DDS process to another is assured. There is a small performance cost using this feature due to the addtional overhead of carrying out the crc calculation. @@ -7768,7 +7889,7 @@ Tracing - Full path: //OpenSplice/NetworkService/Tracing - Occurrences min-max: 0-1 -- Child elements: OutputFile, Timestamps +- Child elements: OutputFile, Timestamps, Verbosity - Optional attributes: enabled enabled @@ -7977,6 +8098,26 @@ Discovery - Valid values: 0 / 6 - Occurrences min-max: 0-1 +Verbosity +--------- + +The Verbosity attribute sets the level of tracing for all Tracing Catagories. This attribute is an additional method besides the Tracing/Catagories tag to specify trace levels. The difference is that Verbosity sets the level for all catagories similar as by other services whereas the Tracing/Catagories element allows to set the trace level per catagory. The verbosity levels are mapped to Catagory levels as following: + +- *none*: level 0 (no Networking log) +- *severe*: level 1 +- *warning*: level 2 +- *info*: level 3 +- *config*: level 3 +- *fine*: level 4 +- *finer*: level 5 +- *finest*: level 6 + +- Full path: //OpenSplice/NetworkService/Tracing/Verbosity +- Format: enumeration +- Default value: none +- Valid values: finest, finer, fine, config, info, warning, severe, none +- Occurrences min-max: 0-1 + Compression =========== @@ -7985,7 +8126,7 @@ Compression networking service includes (depending on platform) implementations of zlib, lzf and snappy. Others may be implemented by writing a dynamically-loadable library and configuring it here. See the - OpenSplice release notes for details of how to write such a + Vortex OpenSplice release notes for details of how to write such a library. It is imperative that all nodes exchanging compressed data @@ -8334,7 +8475,7 @@ When an application is run without Administrative priveleges then only the diffs QueueSize ^^^^^^^^^ -This element specifies the number of messages the network queue for this channel can contain. The OpenSplice kernel writes data to be transmitted to the network queue, and DDSI2E takes them from this queue. If this queue is full when an application tries to write a sample, the sample will be dropped or the writer suspended, depending on the QoS settings of the writer. OpenSplice and its services are optimised for a well-balanced system design, where the queue never becomes full. +This element specifies the number of messages the network queue for this channel can contain. The Vortex OpenSplice kernel writes data to be transmitted to the network queue, and DDSI2E takes them from this queue. If this queue is full when an application tries to write a sample, the sample will be dropped or the writer suspended, depending on the QoS settings of the writer. Vortex OpenSplice and its services are optimised for a well-balanced system design, where the queue never becomes full. - Full path: //OpenSplice/DDSI2EService/Channels/Channel/QueueSize - Format: integer @@ -8455,18 +8596,30 @@ The Discovery element allows specifying various parameters related to the discov - Full path: //OpenSplice/DDSI2EService/Discovery - Occurrences min-max: 0-1 -- Child elements: AdvertiseBuiltinTopicWriters, DefaultMulticastAddress, DomainId, GenerateBuiltinTopics, LocalDiscoveryPartition, MaxAutoParticipantIndex, ParticipantIndex, SPDPInterval, SPDPMulticastAddress +- Child elements: AdvertiseBuiltinTopicWriters, DSGracePeriod, DefaultMulticastAddress, DomainId, GenerateBuiltinTopics, LocalDiscoveryPartition, MaxAutoParticipantIndex, ParticipantIndex, SPDPInterval, SPDPMulticastAddress AdvertiseBuiltinTopicWriters ---------------------------- -This element controls whether or not DDSI2E advertises writers for the built-in topics from its discovery for backwards compatibility with older OpenSplice versions. +This element controls whether or not DDSI2E advertises writers for the built-in topics from its discovery for backwards compatibility with older Vortex OpenSplice versions. - Full path: //OpenSplice/DDSI2EService/Discovery/AdvertiseBuiltinTopicWriters - Format: boolean - Default value: true - Occurrences min-max: 0-1 +DSGracePeriod +------------- + +This setting controls for how long endpoints discovered via a Cloud discovery service will survive after the discovery service disappeared, allowing reconnect without loss of data when the discovery service restarts (or another instance takes over). + +Valid values are finite durations with an explicit unit or the keyword 'inf' for infinity. Recognised units: ns, us, ms, s, min, hr, day. + +- Full path: //OpenSplice/DDSI2EService/Discovery/DSGracePeriod +- Format: string +- Default value: 30 s +- Occurrences min-max: 0-1 + DefaultMulticastAddress ----------------------- @@ -8504,7 +8657,7 @@ This element controls which partition is monitored by DDSI2E for built-in topics - Full path: //OpenSplice/DDSI2EService/Discovery/LocalDiscoveryPartition - Format: string -- Default value: __BUILT_IN_PARTITION__ +- Default value: __BUILT-IN PARTITION\__ - Occurrences min-max: 0-1 MaxAutoParticipantIndex @@ -8538,6 +8691,8 @@ Peers This element statically configures addresses for discovery. +Valid values are finite durations with an explicit unit or the keyword 'inf' for infinity. Recognised units: ns, us, ms, s, min, hr, day. + - Full path: //OpenSplice/DDSI2EService/Discovery/Peers - Occurrences min-max: 0-1 @@ -8590,7 +8745,7 @@ This element specifies an IP address to which discovery packets must be sent, in Ports ----- -The Ports element allows specifying various parameters related to the port numbers used for discovery. These all have default values specified by the DDSI 2.1 specification and rarely need to be changed. +The Ports element allows specifying various parameters related to the port numbers used for discovery. These all have default values specified by the DDSI 2.1 (and 2.2) specification and rarely need to be changed. - Full path: //OpenSplice/DDSI2EService/Discovery/Ports - Occurrences min-max: 0-1 @@ -8599,7 +8754,7 @@ The Ports element allows specifying various parameters related to the port numbe Base ^^^^ -This element specifies the base port number (refer to the DDSI 2.1 specification, section 9.6.1, constant PB). +This element specifies the base port number (refer to the DDSI 2.1 or 2.2 specification, section 9.6.1, constant PB). - Full path: //OpenSplice/DDSI2EService/Discovery/Ports/Base - Format: integer @@ -8610,7 +8765,7 @@ This element specifies the base port number (refer to the DDSI 2.1 specification DomainGain ^^^^^^^^^^ -This element specifies the domain gain, relating domain ids to sets of port numbers (refer to the DDSI 2.1 specification, section 9.6.1, constant DG). +This element specifies the domain gain, relating domain ids to sets of port numbers (refer to the DDSI 2.1 or 2.2 specification, section 9.6.1, constant DG). - Full path: //OpenSplice/DDSI2EService/Discovery/Ports/DomainGain - Format: integer @@ -8620,7 +8775,7 @@ This element specifies the domain gain, relating domain ids to sets of port numb MulticastDataOffset ^^^^^^^^^^^^^^^^^^^ -This element specifies the port number for multicast meta traffic (refer to the DDSI 2.1 specification, section 9.6.1, constant d2). +This element specifies the port number for multicast meta traffic (refer to the DDSI 2.1 or 2.2 specification, section 9.6.1, constant d2). - Full path: //OpenSplice/DDSI2EService/Discovery/Ports/MulticastDataOffset - Format: integer @@ -8630,7 +8785,7 @@ This element specifies the port number for multicast meta traffic (refer to the MulticastMetaOffset ^^^^^^^^^^^^^^^^^^^ -This element specifies the port number for multicast meta traffic (refer to the DDSI 2.1 specification, section 9.6.1, constant d0). +This element specifies the port number for multicast meta traffic (refer to the DDSI 2.1 or 2.2 specification, section 9.6.1, constant d0). - Full path: //OpenSplice/DDSI2EService/Discovery/Ports/MulticastMetaOffset - Format: integer @@ -8640,7 +8795,7 @@ This element specifies the port number for multicast meta traffic (refer to the ParticipantGain ^^^^^^^^^^^^^^^ -This element specifies the participant gain, relating p0, articipant index to sets of port numbers (refer to the DDSI 2.1 specification, section 9.6.1, constant PG). +This element specifies the participant gain, relating p0, articipant index to sets of port numbers (refer to the DDSI 2.1 or 2.2 specification, section 9.6.1, constant PG). - Full path: //OpenSplice/DDSI2EService/Discovery/Ports/ParticipantGain - Format: integer @@ -8650,7 +8805,7 @@ This element specifies the participant gain, relating p0, articipant index to se UnicastDataOffset ^^^^^^^^^^^^^^^^^ -This element specifies the port number for unicast meta traffic (refer to the DDSI 2.1 specification, section 9.6.1, constant d3). +This element specifies the port number for unicast meta traffic (refer to the DDSI 2.1 or 2.2 specification, section 9.6.1, constant d3). - Full path: //OpenSplice/DDSI2EService/Discovery/Ports/UnicastDataOffset - Format: integer @@ -8660,7 +8815,7 @@ This element specifies the port number for unicast meta traffic (refer to the DD UnicastMetaOffset ^^^^^^^^^^^^^^^^^ -This element specifies the port number for unicast meta traffic (refer to the DDSI 2.1 specification, section 9.6.1, constant d1). +This element specifies the port number for unicast meta traffic (refer to the DDSI 2.1 or 2.2 specification, section 9.6.1, constant d1). - Full path: //OpenSplice/DDSI2EService/Discovery/Ports/UnicastMetaOffset - Format: integer @@ -8722,7 +8877,7 @@ When set to "false" all multicasting is disabled. The default, "true" enables fu CoexistWithNativeNetworking --------------------------- -This element specifies whether the DDSI2E service operates in conjunction with the OpenSplice RT Networking service. When "false", the DDSI2E service will take care of all communications, including those between OpenSplice nodes; when "true", the DDSI2E service only communicates with DDS implementations other than OpenSplice. In this case the RT Networking service should be configured as well. +This element specifies whether the DDSI2E service operates in conjunction with the Vortex OpenSplice RT Networking service. When "false", the DDSI2E service will take care of all communications, including those between Vortex OpenSplice nodes; when "true", the DDSI2E service only communicates with DDS implementations other than Vortex OpenSplice. In this case the RT Networking service should be configured as well. - Full path: //OpenSplice/DDSI2EService/General/CoexistWithNativeNetworking - Format: boolean @@ -8880,7 +9035,7 @@ The Internal elements deal with a variety of settings that evolving and that are - Full path: //OpenSplice/DDSI2EService/Internal - Occurrences min-max: 0-1 -- Child elements: AccelerateRexmitBlockSize, AggressiveKeepLastWhc, AggressiveKeepLastWhc, AssumeMulticastCapable, AuxiliaryBandwidthLimit, BuiltinEndpointSet, ConservativeBuiltinReaderStartup, DDSI2DirectMaxThreads, DefragReliableMaxSamples, DefragUnreliableMaxSamples, DeliveryQueueMaxSamples, ForwardAllMessages, ForwardRemoteData, GenerateKeyhash, LateAckMode, LeaseDuration, LegacyFragmentation, LogStackTraces, MaxParticipants, MaxQueuedRexmitBytes, MaxQueuedRexmitMessages, MaxSampleSize, MeasureHbToAckLatency, MinimumSocketReceiveBufferSize, MinimumSocketSendBufferSize, MirrorRemoteEntities, MonitorPort, NackDelay, PreEmptiveAckDelay, PrimaryReorderMaxSamples, PrioritizeRetransmit, RediscoveryBlacklistDuration, ResponsivenessTimeout, RetransmitMerging, RetransmitMergingPeriod, RetryOnRejectBestEffort, RetryOnRejectDuration, SPDPResponseMaxDelay, ScheduleTimeRounding, SecondaryReorderMaxSamples, SquashParticipants, SuppressSPDPMulticast, SynchronousDeliveryLatencyBound, SynchronousDeliveryPriorityThreshold, UnicastResponseToSPDPMessages, UseMulticastIfMreqn, WriterLingerDuration +- Child elements: AccelerateRexmitBlockSize, AggressiveKeepLastWhc, AggressiveKeepLastWhc, AssumeMulticastCapable, AutoReschedNackDelay, AuxiliaryBandwidthLimit, BuiltinEndpointSet, ConservativeBuiltinReaderStartup, DDSI2DirectMaxThreads, DefragReliableMaxSamples, DefragUnreliableMaxSamples, DeliveryQueueMaxSamples, ForwardAllMessages, ForwardRemoteData, GenerateKeyhash, HeartbeatInterval, LateAckMode, LeaseDuration, LegacyFragmentation, LogStackTraces, MaxParticipants, MaxQueuedRexmitBytes, MaxQueuedRexmitMessages, MaxSampleSize, MeasureHbToAckLatency, MinimumSocketReceiveBufferSize, MinimumSocketSendBufferSize, MirrorRemoteEntities, MonitorPort, NackDelay, PreEmptiveAckDelay, PrimaryReorderMaxSamples, PrioritizeRetransmit, RediscoveryBlacklistDuration, ResponsivenessTimeout, RetransmitMerging, RetransmitMergingPeriod, RetryOnRejectBestEffort, RetryOnRejectDuration, SPDPResponseMaxDelay, ScheduleTimeRounding, SecondaryReorderMaxSamples, SquashParticipants, SuppressSPDPMulticast, SynchronousDeliveryLatencyBound, SynchronousDeliveryPriorityThreshold, UnicastResponseToSPDPMessages, UseMulticastIfMreqn, WriterLingerDuration AccelerateRexmitBlockSize ------------------------- @@ -8895,7 +9050,7 @@ AccelerateRexmitBlockSize AggressiveKeepLastWhc --------------------- -**Internal** This element controls whether to drop a reliable sample from a DDSI2E WHC before all readers have acknowledged it as soon as a later sample becomes available. It only affects DCPS data writers with a history QoS setting of KEEP_LAST with depth 1. The default setting, *false*, mimics the behaviour of the OpenSplice RT networking and is necessary to make the behaviour of wait_for_acknowledgements() consistent across the networking services. +**Internal** This element controls whether to drop a reliable sample from a DDSI2E WHC before all readers have acknowledged it as soon as a later sample becomes available. It only affects DCPS data writers with a history QoS setting of KEEP_LAST with depth 1. The default setting, *false*, mimics the behaviour of the Vortex OpenSplice RT networking and is necessary to make the behaviour of wait_for_acknowledgements() consistent across the networking services. - Full path: //OpenSplice/DDSI2EService/Internal/AggressiveKeepLastWhc - Format: boolean @@ -8905,7 +9060,7 @@ AggressiveKeepLastWhc AggressiveKeepLastWhc --------------------- -**Internal** This element controls whether to drop a reliable sample from a DDSI2E WHC before all readers have acknowledged it as soon as a later sample becomes available. It only affects DCPS data writers with a history QoS setting of KEEP_LAST with depth 1. The default setting, *false*, mimics the behaviour of the OpenSplice RT networking and is necessary to make the behaviour of wait_for_acknowledgements() consistent across the networking services. +**Internal** This element controls whether to drop a reliable sample from a DDSI2E WHC before all readers have acknowledged it as soon as a later sample becomes available. It only affects DCPS data writers with a history QoS setting of KEEP_LAST with depth 1. The default setting, *false*, mimics the behaviour of the Vortex OpenSplice RT networking and is necessary to make the behaviour of wait_for_acknowledgements() consistent across the networking services. - Full path: //OpenSplice/DDSI2EService/Internal/AggressiveKeepLastWhc - Format: boolean @@ -8921,6 +9076,18 @@ AssumeMulticastCapable - Format: string - Occurrences min-max: 0-1 +AutoReschedNackDelay +-------------------- + +**Internal** This setting controls the interval with which a reader will continue NACK'ing missing samples in the absence of a response from the writer, as a protection mechanism against writers incorrectly stopping the sending of HEARTBEAT messages. + +Valid values are finite durations with an explicit unit or the keyword 'inf' for infinity. Recognised units: ns, us, ms, s, min, hr, day. + +- Full path: //OpenSplice/DDSI2EService/Internal/AutoReschedNackDelay +- Format: string +- Default value: 1 s +- Occurrences min-max: 0-1 + AuxiliaryBandwidthLimit ----------------------- @@ -8969,8 +9136,8 @@ ControlTopic - Full path: //OpenSplice/DDSI2EService/Internal/ControlTopic - Occurrences min-max: 0-1 -- Child elements: DeafMute -- Optional attributes: enable +- Child elements: Deaf, Mute +- Optional attributes: enable, initialreset enable ^^^^^^ @@ -8982,12 +9149,34 @@ enable - Default value: false - Required: false -DeafMute -^^^^^^^^ +initialreset +^^^^^^^^^^^^ + +**Internal** This attribute sets the time until the deaf and mute settings are automatically reset to false + +Valid values are finite durations with an explicit unit or the keyword 'inf' for infinity. Recognised units: ns, us, ms, s, min, hr, day. + +- Full path: //OpenSplice/DDSI2EService/Internal/ControlTopic[@initialreset] +- Format: string +- Default value: inf +- Required: false + +Deaf +^^^^ + +**Internal** This element controls whether DDSI2E defaults to deaf mode or to normal mode. This controls both the initial behaviour and what behaviour it auto-reverts to. + +- Full path: //OpenSplice/DDSI2EService/Internal/ControlTopic/Deaf +- Format: boolean +- Default value: false +- Occurrences min-max: 0-1 -**Internal** This element controls whether DDSI2E defaults to deaf-mute mode or to normal mode. This controls both the initial behaviour and what behaviour it auto-reverts to. +Mute +^^^^ + +**Internal** This element controls whether DDSI2E defaults to mute mode or to normal mode. This controls both the initial behaviour and what behaviour it auto-reverts to. -- Full path: //OpenSplice/DDSI2EService/Internal/ControlTopic/DeafMute +- Full path: //OpenSplice/DDSI2EService/Internal/ControlTopic/Mute - Format: boolean - Default value: false - Occurrences min-max: 0-1 @@ -9063,6 +9252,55 @@ GenerateKeyhash - Default value: true - Occurrences min-max: 0-1 +HeartbeatInterval +----------------- + +**Internal** This element sets the base interval for the asynchronous, periodic writer heartbeats when unacknowledged data is present in its writer history cache. The actual interval is dynamically adjusted, the attributes of this element allow further configuration. + +Valid values are finite durations with an explicit unit or the keyword 'inf' for infinity. Recognised units: ns, us, ms, s, min, hr, day. + +- Full path: //OpenSplice/DDSI2EService/Internal/HeartbeatInterval +- Format: string +- Default value: 100 ms +- Occurrences min-max: 0-1 +- Optional attributes: max, min, minsched + +max +^^^ + +**Internal** This attribute sets the maximum interval for periodic heartbeats. + +Valid values are finite durations with an explicit unit or the keyword 'inf' for infinity. Recognised units: ns, us, ms, s, min, hr, day. + +- Full path: //OpenSplice/DDSI2EService/Internal/HeartbeatInterval[@max] +- Format: string +- Default value: 8 s +- Required: false + +min +^^^ + +**Internal** This attribute sets the minimum interval that must have passed since the most recent heartbeat from a writer, before another asynchronous (not directly related to writing) will be sent. + +Valid values are finite durations with an explicit unit or the keyword 'inf' for infinity. Recognised units: ns, us, ms, s, min, hr, day. + +- Full path: //OpenSplice/DDSI2EService/Internal/HeartbeatInterval[@min] +- Format: string +- Default value: 5 ms +- Required: false + +minsched +^^^^^^^^ + +**Internal** This attribute sets the minimum interval for periodic heartbeats. Other events may still cause heartbeats to go out. + +Valid values are finite durations with an explicit unit or the keyword 'inf' for infinity. Recognised units: ns, us, ms, s, min, hr, day. + +- Full path: //OpenSplice/DDSI2EService/Internal/HeartbeatInterval[@minsched] +- Format: string +- Default value: 20 ms +- Required: false + LateAckMode ----------- @@ -10409,18 +10647,30 @@ The Discovery element allows specifying various parameters related to the discov - Full path: //OpenSplice/DDSI2Service/Discovery - Occurrences min-max: 0-1 -- Child elements: AdvertiseBuiltinTopicWriters, DefaultMulticastAddress, DomainId, GenerateBuiltinTopics, LocalDiscoveryPartition, MaxAutoParticipantIndex, ParticipantIndex, SPDPInterval, SPDPMulticastAddress +- Child elements: AdvertiseBuiltinTopicWriters, DSGracePeriod, DefaultMulticastAddress, DomainId, GenerateBuiltinTopics, LocalDiscoveryPartition, MaxAutoParticipantIndex, ParticipantIndex, SPDPInterval, SPDPMulticastAddress AdvertiseBuiltinTopicWriters ---------------------------- -This element controls whether or not DDSI2 advertises writers for the built-in topics from its discovery for backwards compatibility with older OpenSplice versions. +This element controls whether or not DDSI2 advertises writers for the built-in topics from its discovery for backwards compatibility with older Vortex OpenSplice versions. - Full path: //OpenSplice/DDSI2Service/Discovery/AdvertiseBuiltinTopicWriters - Format: boolean - Default value: true - Occurrences min-max: 0-1 +DSGracePeriod +------------- + +This setting controls for how long endpoints discovered via a Cloud discovery service will survive after the discovery service disappeared, allowing reconnect without loss of data when the discovery service restarts (or another instance takes over). + +Valid values are finite durations with an explicit unit or the keyword 'inf' for infinity. Recognised units: ns, us, ms, s, min, hr, day. + +- Full path: //OpenSplice/DDSI2Service/Discovery/DSGracePeriod +- Format: string +- Default value: 30 s +- Occurrences min-max: 0-1 + DefaultMulticastAddress ----------------------- @@ -10458,7 +10708,7 @@ This element controls which partition is monitored by DDSI2 for built-in topics - Full path: //OpenSplice/DDSI2Service/Discovery/LocalDiscoveryPartition - Format: string -- Default value: __BUILT_IN_PARTITION__ +- Default value: __BUILT-IN PARTITION\__ - Occurrences min-max: 0-1 MaxAutoParticipantIndex @@ -10492,6 +10742,8 @@ Peers This element statically configures addresses for discovery. +Valid values are finite durations with an explicit unit or the keyword 'inf' for infinity. Recognised units: ns, us, ms, s, min, hr, day. + - Full path: //OpenSplice/DDSI2Service/Discovery/Peers - Occurrences min-max: 0-1 @@ -10544,7 +10796,7 @@ This element specifies an IP address to which discovery packets must be sent, in Ports ----- -The Ports element allows specifying various parameters related to the port numbers used for discovery. These all have default values specified by the DDSI 2.1 specification and rarely need to be changed. +The Ports element allows specifying various parameters related to the port numbers used for discovery. These all have default values specified by the DDSI 2.1 (and 2.2) specification and rarely need to be changed. - Full path: //OpenSplice/DDSI2Service/Discovery/Ports - Occurrences min-max: 0-1 @@ -10553,7 +10805,7 @@ The Ports element allows specifying various parameters related to the port numbe Base ^^^^ -This element specifies the base port number (refer to the DDSI 2.1 specification, section 9.6.1, constant PB). +This element specifies the base port number (refer to the DDSI 2.1 or 2.2 specification, section 9.6.1, constant PB). - Full path: //OpenSplice/DDSI2Service/Discovery/Ports/Base - Format: integer @@ -10564,7 +10816,7 @@ This element specifies the base port number (refer to the DDSI 2.1 specification DomainGain ^^^^^^^^^^ -This element specifies the domain gain, relating domain ids to sets of port numbers (refer to the DDSI 2.1 specification, section 9.6.1, constant DG). +This element specifies the domain gain, relating domain ids to sets of port numbers (refer to the DDSI 2.1 or 2.2 specification, section 9.6.1, constant DG). - Full path: //OpenSplice/DDSI2Service/Discovery/Ports/DomainGain - Format: integer @@ -10574,7 +10826,7 @@ This element specifies the domain gain, relating domain ids to sets of port numb MulticastDataOffset ^^^^^^^^^^^^^^^^^^^ -This element specifies the port number for multicast meta traffic (refer to the DDSI 2.1 specification, section 9.6.1, constant d2). +This element specifies the port number for multicast meta traffic (refer to the DDSI 2.1 or 2.2 specification, section 9.6.1, constant d2). - Full path: //OpenSplice/DDSI2Service/Discovery/Ports/MulticastDataOffset - Format: integer @@ -10584,7 +10836,7 @@ This element specifies the port number for multicast meta traffic (refer to the MulticastMetaOffset ^^^^^^^^^^^^^^^^^^^ -This element specifies the port number for multicast meta traffic (refer to the DDSI 2.1 specification, section 9.6.1, constant d0). +This element specifies the port number for multicast meta traffic (refer to the DDSI 2.1 or 2.2 specification, section 9.6.1, constant d0). - Full path: //OpenSplice/DDSI2Service/Discovery/Ports/MulticastMetaOffset - Format: integer @@ -10594,7 +10846,7 @@ This element specifies the port number for multicast meta traffic (refer to the ParticipantGain ^^^^^^^^^^^^^^^ -This element specifies the participant gain, relating p0, articipant index to sets of port numbers (refer to the DDSI 2.1 specification, section 9.6.1, constant PG). +This element specifies the participant gain, relating p0, articipant index to sets of port numbers (refer to the DDSI 2.1 or 2.2 specification, section 9.6.1, constant PG). - Full path: //OpenSplice/DDSI2Service/Discovery/Ports/ParticipantGain - Format: integer @@ -10604,7 +10856,7 @@ This element specifies the participant gain, relating p0, articipant index to se UnicastDataOffset ^^^^^^^^^^^^^^^^^ -This element specifies the port number for unicast meta traffic (refer to the DDSI 2.1 specification, section 9.6.1, constant d3). +This element specifies the port number for unicast meta traffic (refer to the DDSI 2.1 or 2.2 specification, section 9.6.1, constant d3). - Full path: //OpenSplice/DDSI2Service/Discovery/Ports/UnicastDataOffset - Format: integer @@ -10614,7 +10866,7 @@ This element specifies the port number for unicast meta traffic (refer to the DD UnicastMetaOffset ^^^^^^^^^^^^^^^^^ -This element specifies the port number for unicast meta traffic (refer to the DDSI 2.1 specification, section 9.6.1, constant d1). +This element specifies the port number for unicast meta traffic (refer to the DDSI 2.1 or 2.2 specification, section 9.6.1, constant d1). - Full path: //OpenSplice/DDSI2Service/Discovery/Ports/UnicastMetaOffset - Format: integer @@ -10676,7 +10928,7 @@ When set to "false" all multicasting is disabled. The default, "true" enables fu CoexistWithNativeNetworking --------------------------- -This element specifies whether the DDSI2 service operates in conjunction with the OpenSplice RT Networking service. When "false", the DDSI2 service will take care of all communications, including those between OpenSplice nodes; when "true", the DDSI2 service only communicates with DDS implementations other than OpenSplice. In this case the RT Networking service should be configured as well. +This element specifies whether the DDSI2 service operates in conjunction with the Vortex OpenSplice RT Networking service. When "false", the DDSI2 service will take care of all communications, including those between Vortex OpenSplice nodes; when "true", the DDSI2 service only communicates with DDS implementations other than Vortex OpenSplice. In this case the RT Networking service should be configured as well. - Full path: //OpenSplice/DDSI2Service/General/CoexistWithNativeNetworking - Format: boolean @@ -10834,7 +11086,7 @@ The Internal elements deal with a variety of settings that evolving and that are - Full path: //OpenSplice/DDSI2Service/Internal - Occurrences min-max: 0-1 -- Child elements: AccelerateRexmitBlockSize, AggressiveKeepLastWhc, AssumeMulticastCapable, BuiltinEndpointSet, ConservativeBuiltinReaderStartup, DDSI2DirectMaxThreads, DefragReliableMaxSamples, DefragUnreliableMaxSamples, DeliveryQueueMaxSamples, ForwardAllMessages, ForwardRemoteData, GenerateKeyhash, LateAckMode, LeaseDuration, LegacyFragmentation, LogStackTraces, MaxParticipants, MaxQueuedRexmitBytes, MaxQueuedRexmitMessages, MaxSampleSize, MeasureHbToAckLatency, MinimumSocketReceiveBufferSize, MinimumSocketSendBufferSize, MirrorRemoteEntities, MonitorPort, NackDelay, PreEmptiveAckDelay, PrimaryReorderMaxSamples, PrioritizeRetransmit, RediscoveryBlacklistDuration, ResponsivenessTimeout, RetransmitMerging, RetransmitMergingPeriod, RetryOnRejectBestEffort, RetryOnRejectDuration, SPDPResponseMaxDelay, ScheduleTimeRounding, SecondaryReorderMaxSamples, SquashParticipants, SuppressSPDPMulticast, SynchronousDeliveryLatencyBound, SynchronousDeliveryPriorityThreshold, UnicastResponseToSPDPMessages, UseMulticastIfMreqn, WriterLingerDuration +- Child elements: AccelerateRexmitBlockSize, AggressiveKeepLastWhc, AssumeMulticastCapable, AutoReschedNackDelay, BuiltinEndpointSet, ConservativeBuiltinReaderStartup, DDSI2DirectMaxThreads, DefragReliableMaxSamples, DefragUnreliableMaxSamples, DeliveryQueueMaxSamples, ForwardAllMessages, ForwardRemoteData, GenerateKeyhash, HeartbeatInterval, LateAckMode, LeaseDuration, LegacyFragmentation, LogStackTraces, MaxParticipants, MaxQueuedRexmitBytes, MaxQueuedRexmitMessages, MaxSampleSize, MeasureHbToAckLatency, MinimumSocketReceiveBufferSize, MinimumSocketSendBufferSize, MirrorRemoteEntities, MonitorPort, NackDelay, PreEmptiveAckDelay, PrimaryReorderMaxSamples, PrioritizeRetransmit, RediscoveryBlacklistDuration, ResponsivenessTimeout, RetransmitMerging, RetransmitMergingPeriod, RetryOnRejectBestEffort, RetryOnRejectDuration, SPDPResponseMaxDelay, ScheduleTimeRounding, SecondaryReorderMaxSamples, SquashParticipants, SuppressSPDPMulticast, SynchronousDeliveryLatencyBound, SynchronousDeliveryPriorityThreshold, UnicastResponseToSPDPMessages, UseMulticastIfMreqn, WriterLingerDuration AccelerateRexmitBlockSize ------------------------- @@ -10849,7 +11101,7 @@ AccelerateRexmitBlockSize AggressiveKeepLastWhc --------------------- -**Internal** This element controls whether to drop a reliable sample from a DDSI2 WHC before all readers have acknowledged it as soon as a later sample becomes available. It only affects DCPS data writers with a history QoS setting of KEEP_LAST with depth 1. The default setting, *false*, mimics the behaviour of the OpenSplice RT networking and is necessary to make the behaviour of wait_for_acknowledgements() consistent across the networking services. +**Internal** This element controls whether to drop a reliable sample from a DDSI2 WHC before all readers have acknowledged it as soon as a later sample becomes available. It only affects DCPS data writers with a history QoS setting of KEEP_LAST with depth 1. The default setting, *false*, mimics the behaviour of the Vortex OpenSplice RT networking and is necessary to make the behaviour of wait_for_acknowledgements() consistent across the networking services. - Full path: //OpenSplice/DDSI2Service/Internal/AggressiveKeepLastWhc - Format: boolean @@ -10865,6 +11117,18 @@ AssumeMulticastCapable - Format: string - Occurrences min-max: 0-1 +AutoReschedNackDelay +-------------------- + +**Internal** This setting controls the interval with which a reader will continue NACK'ing missing samples in the absence of a response from the writer, as a protection mechanism against writers incorrectly stopping the sending of HEARTBEAT messages. + +Valid values are finite durations with an explicit unit or the keyword 'inf' for infinity. Recognised units: ns, us, ms, s, min, hr, day. + +- Full path: //OpenSplice/DDSI2Service/Internal/AutoReschedNackDelay +- Format: string +- Default value: 1 s +- Occurrences min-max: 0-1 + BuiltinEndpointSet ------------------ @@ -10901,7 +11165,7 @@ ControlTopic - Full path: //OpenSplice/DDSI2Service/Internal/ControlTopic - Occurrences min-max: 0-1 -- Child elements: DeafMute +- Child elements: Deaf, Mute - Optional attributes: enable enable @@ -10914,12 +11178,22 @@ enable - Default value: false - Required: false -DeafMute -^^^^^^^^ +Deaf +^^^^ -**Internal** This element controls whether DDSI2 defaults to deaf-mute mode or to normal mode. This controls both the initial behaviour and what behaviour it auto-reverts to. +**Internal** This element controls whether DDSI2 defaults to deaf mode or to normal mode. This controls both the initial behaviour and what behaviour it auto-reverts to. -- Full path: //OpenSplice/DDSI2Service/Internal/ControlTopic/DeafMute +- Full path: //OpenSplice/DDSI2Service/Internal/ControlTopic/Deaf +- Format: boolean +- Default value: false +- Occurrences min-max: 0-1 + +Mute +^^^^ + +**Internal** This element controls whether DDSI2 defaults to mute mode or to normal mode. This controls both the initial behaviour and what behaviour it auto-reverts to. + +- Full path: //OpenSplice/DDSI2Service/Internal/ControlTopic/Mute - Format: boolean - Default value: false - Occurrences min-max: 0-1 @@ -10995,6 +11269,55 @@ GenerateKeyhash - Default value: true - Occurrences min-max: 0-1 +HeartbeatInterval +----------------- + +**Internal** This element sets the base interval for the asynchronous, periodic writer heartbeats when unacknowledged data is present in its writer history cache. The actual interval is dynamically adjusted, the attributes of this element allow further configuration. + +Valid values are finite durations with an explicit unit or the keyword 'inf' for infinity. Recognised units: ns, us, ms, s, min, hr, day. + +- Full path: //OpenSplice/DDSI2Service/Internal/HeartbeatInterval +- Format: string +- Default value: 100 ms +- Occurrences min-max: 0-1 +- Optional attributes: max, min, minsched + +max +^^^ + +**Internal** This attribute sets the maximum interval for periodic heartbeats. + +Valid values are finite durations with an explicit unit or the keyword 'inf' for infinity. Recognised units: ns, us, ms, s, min, hr, day. + +- Full path: //OpenSplice/DDSI2Service/Internal/HeartbeatInterval[@max] +- Format: string +- Default value: 8 s +- Required: false + +min +^^^ + +**Internal** This attribute sets the minimum interval that must have passed since the most recent heartbeat from a writer, before another asynchronous (not directly related to writing) will be sent. + +Valid values are finite durations with an explicit unit or the keyword 'inf' for infinity. Recognised units: ns, us, ms, s, min, hr, day. + +- Full path: //OpenSplice/DDSI2Service/Internal/HeartbeatInterval[@min] +- Format: string +- Default value: 5 ms +- Required: false + +minsched +^^^^^^^^ + +**Internal** This attribute sets the minimum interval for periodic heartbeats. Other events may still cause heartbeats to go out. + +Valid values are finite durations with an explicit unit or the keyword 'inf' for infinity. Recognised units: ns, us, ms, s, min, hr, day. + +- Full path: //OpenSplice/DDSI2Service/Internal/HeartbeatInterval[@minsched] +- Format: string +- Default value: 20 ms +- Required: false + LateAckMode ----------- @@ -13326,7 +13649,7 @@ Storage This element specifies a storage to use for recording and/or replaying data. Currently the supported storage backends are XML and CDR. Note that storages can also be created, or their properties modified, by Record and Replay configuration-commands. - These commands use the same syntax to specify configuration data as the OpenSplice configuration file, + These commands use the same syntax to specify configuration data as the Vortex OpenSplice configuration file, so the description given here also applies to commands. - Full path: //OpenSplice/RnRService/Storage @@ -13450,7 +13773,7 @@ reset ^^^^^ This attribute allows to reset the current values of statistics belonging to the storage. Note that this only makes sense in a configuration-command for an existing storage, since new storages created - from the OpenSplice configuration file always start out with empty statistics. + from the Vortex OpenSplice configuration file always start out with empty statistics. - Full path: //OpenSplice/RnRService/Storage/Statistics[@reset] - Format: boolean diff --git a/docs/html/DeploymentGuide/_sources/index.txt b/docs/html/DeploymentGuide/_sources/index.txt index e127b43fe..0fb60c779 100644 --- a/docs/html/DeploymentGuide/_sources/index.txt +++ b/docs/html/DeploymentGuide/_sources/index.txt @@ -7,10 +7,10 @@ The Vortex OpenSplice Deployment Guide .. toctree:: :maxdepth: 8 :numbered: - + preface overview - + service-feature-list domain-service durability-service @@ -19,15 +19,17 @@ The Vortex OpenSplice Deployment Guide networkingbridge-service tuner-service dbmsconnect-service - + tools - + guide referencesystems - contacts - + logrotate + + contacts + Indices and tables ================== diff --git a/docs/html/DeploymentGuide/_sources/logrotate.txt b/docs/html/DeploymentGuide/_sources/logrotate.txt new file mode 100644 index 000000000..017a78f24 --- /dev/null +++ b/docs/html/DeploymentGuide/_sources/logrotate.txt @@ -0,0 +1,74 @@ +.. _`Logrotate`: + + +######### +Logrotate +######### + +*The OpenSplice middleware can produce several trace and log files +depending on the applied configuration settings. Log files and in +particular trace files can become very large over time and run into +resource limitations. It is advised to use the logrotate function +to manage resource consumption of log and trace files. The logrotate +function is standard available on linux distributions and for windows +an opensource version is available on sourceforge (LogRotateWin).** + +.. _`Description`: + +Description +*********** + +logrotate is designed to ease administration of systems that generate +large numbers of log files. It allows automatic rotation, compression, +removal, and mailing of log files. Each log file may be handled daily, +weekly, monthly, or when it grows too large. +Normally, logrotate is run as a daily cron job. It will not modify a +log multiple times in one day unless the criterion for that log is +based on the log's size and logrotate is being run multiple times each +day, or unless the -f or --forceoption is used. For example, logrotate +can also be run by a supervisory process at any time to process log +files specified in the config_file. +For a more detailed description of logrotate see the linux man pages. + +.. _`Configuration file`: + +Configuration file +****************** + +logrotate reads everything about the log files it should be handling +from the series of configuration files specified on the command line. +Each configuration file can set global options (local definitions +override global ones, and later definitions override earlier ones) +and specify log files to rotate. + +.. _`Example configuration`: + +Example configuration +********************* + +For OpenSplice the following example config_file arguments are advised for logrotate: + +.. code-block:: bash + + # sample logrotate configuration file + + # The copytruncate option specifies that logfiles are first copied and + # then truncate. This option is required for OpenSplice instead of using + # the create option to avoid closing the file descriptors used by + # OpenSplice. + # + copytruncate + + # The compress option is used to compress the logfile copies. + compress + + # The following options specify that the log files in the current directory + # will be rotates when the file size exceeds 100k and that at most the 5 + # most recent rotated files are maintained. + "./\*.log" { + rotate 5 + size 100k + } + +.. EoF + diff --git a/docs/html/DeploymentGuide/_sources/overview.txt b/docs/html/DeploymentGuide/_sources/overview.txt index 351522fc7..91ed5119a 100644 --- a/docs/html/DeploymentGuide/_sources/overview.txt +++ b/docs/html/DeploymentGuide/_sources/overview.txt @@ -4,47 +4,47 @@ Overview ######## -*This chapter explains the Vortex OpenSplice middleware from -a configuration perspective. It shows the different components -running on a single node and briefly explains the role of each -entity. Furthermore, it defines a reference system that will +*This chapter explains the Vortex OpenSplice middleware from +a configuration perspective. It shows the different components +running on a single node and briefly explains the role of each +entity. Furthermore, it defines a reference system that will be used throughout the rest of the document as an example.* -.. _`Vortex OpenSplice DDS architecture`: +.. _`Vortex OpenSplice architecture`: Vortex OpenSplice Architecture ****************************** -Vortex OpenSplice is highly configurable, even allowing the architectural +Vortex OpenSplice is highly configurable, even allowing the architectural structure of the DDS middleware to be chosen by the user at deployment time. -Vortex OpenSplice can be configured to run using a so-called ‘federated’ -*shared memory* architecture, where both the DDS related administration -(including the optional pluggable services) and DDS applications interface +Vortex OpenSplice can be configured to run using a so-called ‘federated’ +*shared memory* architecture, where both the DDS related administration +(including the optional pluggable services) and DDS applications interface directly with shared memory. -Alternatively, Vortex OpenSplice also supports a so-called ‘standalone’ -*single process* architecture, where one or more DDS applications, -together with the OpenSplice administration and services, can all be -grouped into a single operating system process. +Alternatively, Vortex OpenSplice also supports a so-called ‘standalone’ +*single process* architecture, where one or more DDS applications, +together with the OpenSplice administration and services, can all be +grouped into a single operating system process. -Both deployment modes support a configurable and extensible set +Both deployment modes support a configurable and extensible set of services, providing functionality such as: + *networking* - providing QoS-driven real-time networking based on multiple reliable multicast ‘channels’ -+ *durability* - providing fault-tolerant storage for both real-time state ++ *durability* - providing fault-tolerant storage for both real-time state data as well as persistent settings + *remote control and monitoring SOAP service* - providing remote web-based access using the SOAP protocol from various Vortex OpenSplice tools -+ *dbms service* - providing a connection between the real-time and the ++ *dbms service* - providing a connection between the real-time and the enterprise domain by bridging data from DDS to DBMS and *vice versa* -The Vortex OpenSplice middleware can be easily configured, on the fly, using -its pluggable service architecture: the services that are needed can be -specified together with their configuration for the particular application +The Vortex OpenSplice middleware can be easily configured, on the fly, using +its pluggable service architecture: the services that are needed can be +specified together with their configuration for the particular application domain, including networking parameters, and durability levels for example). There are advantages to both the single process and shared memory deployment @@ -121,7 +121,7 @@ The diagram `The Vortex OpenSplice Shared Memory Architecture`_ shows an overview of the shared memory architecture of Vortex OpenSplice on *one* computing node. Typically, there are *many* nodes within a system. -.. _`The Vortex OpenSplice Shared Memory Architecture`: +.. _`The Vortex OpenSplice Shared Memory Architecture`: .. centered:: **The Vortex OpenSplice Shared Memory Architecture** @@ -129,7 +129,7 @@ shows an overview of the shared memory architecture of Vortex OpenSplice on :height: 70mm :align: center :alt: The Vortex OpenSplice Shared Memory Architecture - + .. _`Comparison of Deployment Architectures`: @@ -157,14 +157,14 @@ basically about going for out-of-the-box simplicity or for maximum performance: :height: 35mm :align: center :alt: Federated Application Cluster - + **Non-federated, `single process’ Applications** - - Each application links the required DDS services as libraries + - Each application links the required DDS services as libraries into a standalone ‘single process’ - Resources are managed by each individual application - - Added value: Ease-of-use (‘zero-configuration’, middleware + - Added value: Ease-of-use (‘zero-configuration’, middleware lifecycle is simply coupled to that of the application process) @@ -222,7 +222,7 @@ single-process architecture start with ``ospl_sp_`` whereas federated-deployment configurations start with ``ospl_shmem_``. -.. _`Vortex OpenSplice DDS Usage`: +.. _`Vortex OpenSplice Usage`: Vortex OpenSplice Usage @@ -233,14 +233,14 @@ and libraries can be found in order to be able to start the Domain Service. |unix| |linux| - On UNIX-like platforms this can be realized by starting a shell and - sourcing the ``release.com`` file located in the root directory of + On UNIX-like platforms this can be realized by starting a shell and + sourcing the ``release.com`` file located in the root directory of the Vortex OpenSplice installation: -:: +:: % . ./release.com - + |windows| @@ -249,7 +249,7 @@ and libraries can be found in order to be able to start the Domain Service. -.. _`Starting Vortex OpenSplice DDS for a Single Process Deployment`: +.. _`Starting Vortex OpenSplice for a Single Process Deployment`: Starting Vortex OpenSplice for a Single Process Deployment ========================================================== @@ -261,7 +261,7 @@ associated services at the point when the DDS ``create_participant`` operation i invoked by the standalone application process. -.. _`Starting Vortex OpenSplice DDS for a Shared Memory Deployment`: +.. _`Starting Vortex OpenSplice for a Shared Memory Deployment`: Starting Vortex OpenSplice for a Shared Memory Deployment ========================================================= @@ -271,10 +271,10 @@ Domain Service prior to running a DDS application. The ``ospl`` command-tool is provided to manage Vortex OpenSplice for shared memory deployments. To start Vortex OpenSplice in this way, enter: -:: +:: % . ./release.com - + This will start the Domain Service using the default configuration. |caution| @@ -287,7 +287,7 @@ This will start the Domain Service using the default configuration. |caution| **NOTE**: The **VxWorks** version of Vortex OpenSplice does not include the ``ospl`` - program. Please refer to the *Getting Started Guide* for details of how to use + program. Please refer to the *Getting Started Guide* for details of how to use VxWorks projects and Real Time Processes to deploy Vortex OpenSplice applications. @@ -319,7 +319,7 @@ specifying ````). The names of these log files can also be changed by se Vortex OpenSplice also accepts the environment properties ``OSPL_VERBOSITY`` and ``OSPL_LOGAPPEND``. These provide an alternate method of specifying values for -Attribute ``append`` and Attribute ``verbosity`` of the ``Domain/Report`` +Attribute ``append`` and Attribute ``verbosity`` of the ``Domain/Report`` configuration element (see the :ref:`Configuration ` section for details). @@ -363,12 +363,12 @@ for detailed information about ``mmstat``. |caution| - Please note that ``mmstat`` is only suitable for diagnostic purposes, + Please note that ``mmstat`` is only suitable for diagnostic purposes, and its use is only applicable in shared memory mode. -.. _`Stopping Vortex OpenSplice DDS`: +.. _`Stopping Vortex OpenSplice`: Stopping Vortex OpenSplice ========================== @@ -381,8 +381,8 @@ Stopping a Single Process deployment When deployed as a single process, the application can either be terminated naturally when the end of the main function is reached, or stopped prematurely by -means of a signal interrupt, for example ``Ctrl-C``. In either case, the -Vortex OpenSplice middleware running within the process will be stopped and the +means of a signal interrupt, for example ``Ctrl-C``. In either case, the +Vortex OpenSplice middleware running within the process will be stopped and the process will terminate. @@ -394,7 +394,7 @@ Stopping a Shared Memory deployment In shared memory deployment mode, the Vortex OpenSplice Domain Service can be stopped by issuing the following command on the command-line. -:: +:: % ospl stop @@ -410,7 +410,7 @@ Stopping OSPL by using signals ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Alternatively the Vortex OpenSplice domain service can also be stopped by sending a -signal to the ``ospl`` process, assuming the process was started using the ``-f`` +signal to the ``ospl`` process, assuming the process was started using the ``-f`` option. |unix| @@ -418,7 +418,7 @@ option. For example, on Unix you could use the following command to send a termination signal to the ``ospl`` tool, where ```` identifies the ``ospl`` tool pid: -:: +:: % kill –SIGTERM @@ -510,7 +510,7 @@ application is terminated by other means (*e.g.* by terminating with ``Ctrl+C``) or even if the application crashes in the user code. |caution| - + The cleanup mechanisms are *not* executed when an application is terminated with a ``KILL`` signal. For this reason a user must not terminate an application with a ``kill -9`` command (or, on Windows, must not use TaskManager’s *End Process* @@ -521,7 +521,7 @@ or even if the application crashes in the user code. node. -.. _`Deploying Vortex OpenSplice DDS on VxWorks 6.x`: +.. _`Deploying Vortex OpenSplice on VxWorks 6.x`: Deploying Vortex OpenSplice on VxWorks 6.x ========================================== @@ -532,7 +532,7 @@ VxWorks projects and Real Time Processes to deploy Vortex OpenSplice applications. -.. _`Deploying Vortex OpenSplice DDS on Integrity`: +.. _`Deploying Vortex OpenSplice on Integrity`: Deploying Vortex OpenSplice on Integrity ======================================== @@ -545,7 +545,7 @@ Vortex OpenSplice deployment on Integrity. -.. _`Installing/Uninstalling the Vortex OpenSplice DDS C# Assembly to the Global Assembly Cache`: +.. _`Installing/Uninstalling the Vortex OpenSplice C# Assembly to the Global Assembly Cache`: Installing/Uninstalling the Vortex OpenSplice C# Assembly to the Global Assembly Cache ====================================================================================== @@ -576,7 +576,7 @@ to the following: :: % C:\Program Files\Microsoft Visual Studio 9.0\VC>gacutil.exe /i - "C:\Program Files \PrismTech\VortexOpenSplice\V6.6.0\HDE\x86.win32\ + "C:\Program Files \ADLINK\VortexOpenSplice\V6.6.0\HDE\x86.win32\ bin\dcpssacsAssembly.dll" % % Microsoft (R) .NET Global Assembly Cache Utility. Version @@ -628,7 +628,7 @@ If you are successful you will see a message similar to the following: |caution| +---------------------------------------------------------------------------+ - | If you do not specify a version to the uninstall option, then all | + | If you do not specify a version to the uninstall option, then all | | installed Vortex OpenSplice C# Assemblies in the GAC called | | ``dcpssacsAssembly`` will be removed from the GAC, so take care with | | this option as it can adversely affect any deployed applications that | @@ -640,7 +640,7 @@ If you are successful you will see a message similar to the following: -.. _`Vortex OpenSplice DDS Configuration`: +.. _`Vortex OpenSplice Configuration`: Vortex OpenSplice Configuration ******************************* @@ -688,7 +688,7 @@ environment variables. When specifying configuration parameter values in a configuration file, environment variables can be referenced using the notation ``${VARIABLE}``. -When parsing the XML configuration, the Domain Service will replace the symbol +When parsing the XML configuration, the Domain Service will replace the symbol with the variable value found in the environment. @@ -704,7 +704,7 @@ be overridden to refer to a customer configuration. For single process mode operation this variable is required; see also `Single Process architecture`_ in this *Guide*, and -the detailed description of the Element ``//OpenSplice/Domain/SingleProcess`` +the detailed description of the Element ``//OpenSplice/Domain/SingleProcess`` in the :ref:`Configuration ` section. @@ -727,9 +727,9 @@ Configuration of Single Process deployment A single process deployment is enabled when the ``OSPL_URI`` environment variable refers to an XML configuration containing the ```` attribute within -the Domain section (``//OpenSplice/Domain/SingleProcess``). +the Domain section (``//OpenSplice/Domain/SingleProcess``). See the :ref:`Configuration ` section for full details. -In such a deployment, each Vortex OpenSplice service including the Domain Service +In such a deployment, each Vortex OpenSplice service including the Domain Service will be started as threads within the existing application process. In this case there is no need to start the Vortex OpenSplice administration manually @@ -750,7 +750,7 @@ In order to have Vortex OpenSplice start with a custom configuration file, use: % ospl start -where ```` denotes the URI of the Domain Service configuration file. +where ```` denotes the URI of the Domain Service configuration file. In order to stop a specific Vortex OpenSplice instance, the same mechanism holds. Use: @@ -778,7 +778,7 @@ To stop all active Vortex OpenSplice Domains, use: Note that the ```` parameter to the above commands is not required if the -``OSPL_URI`` environment variable refers to the configuration that is intended +``OSPL_URI`` environment variable refers to the configuration that is intended to be started or stopped. @@ -800,7 +800,7 @@ need to manipulate these files directly. if ``TEMP`` is not set) environment variable. These locations can be over-ridden, if required, by setting the ``OSPL_TEMP`` variable to a location on disk by specifying a path. - Please note, however, that this **must** be consistent for **all** + Please note, however, that this **must** be consistent for **all** environments on a particular node. @@ -833,7 +833,7 @@ Vortex OpenSplice daemon (and any services) for that domain and the application This requires some thought when configuring multiple Vortex OpenSplice domains on a single node. Care must be taken to ensure that the XML configuration files contain unique and non-overlapping addresses for the shared memory mapping (please also -see the description of the XML element ``//OpenSplice/Domain/Database/Address`` in +see the description of the XML element ``//OpenSplice/Domain/Database/Address`` in the :ref:`Configuration ` section). When designing and coding applications, care must also be taken with regard to @@ -879,7 +879,7 @@ history of an instance based on either the source time stamp or the reception time stamp. This is controlled by means of the ``DestinationOrderQosPolicy``. The ``HistoryQosPolicy`` controls how many historic samples are stored in a -reader. By default, a DataReader has a ``KEEP_LAST`` history with a depth +reader. By default, a DataReader has a ``KEEP_LAST`` history with a depth of ``1``. This means that only the ‘last’ (based on the ordering defined by the ``DestinationOrderQosPolicy``) sample for each instance is maintained by the middleware. When a sample is received by the subscriber, it determines whether and @@ -888,10 +888,10 @@ where to insert the sample in the history of an instance based on either the sou the instance. ``BY_SOURCE_ time stamp`` - If samples are ordered by source time stamp - and time is set back 1 hour on the subscriber node, nothing changes. If it - is set back one hour on the publisher node, samples written after the time - has changed have ‘older’ source time stamps and will therefore not overwrite + If samples are ordered by source time stamp + and time is set back 1 hour on the subscriber node, nothing changes. If it + is set back one hour on the publisher node, samples written after the time + has changed have ‘older’ source time stamps and will therefore not overwrite the samples in the history from before the time changed. ``BY_RECEPTION_ time stamp`` @@ -945,16 +945,16 @@ if supported by the OS. *Real-time clock* This is the main clock used for time stamps on data and - data-related actions. This time is typically kept close to the actual + data-related actions. This time is typically kept close to the actual time by the OS by means of NTP or the like. This clock can also be provided - by the customer through the *`UserClock’* functionality - (``//OpenSplice/Domain/UserClockService`` is fully described in + by the customer through the *`UserClock’* functionality + (``//OpenSplice/Domain/UserClockService`` is fully described in the :ref:`Configuration ` section). -*Monotonic clock* +*Monotonic clock* This is a clock that never jumps back and which provides a measure for the time a machine has been running since boot. When the time - is adjusted, this clock will not jump forward or backward. This clock + is adjusted, this clock will not jump forward or backward. This clock doesn’t include the time spent when a machine was suspended. *Elapsed time clock* @@ -976,11 +976,11 @@ For now this change is only done for CORBA C++ and CORBA Java and all internal D All other language bindings still use the 32-bit representation. Version 6.7 is fully compatible with older versions and will communicate by default in the 32-bit time representation with other nodes. If the domain/y2038Ready option is set, the node will use the new 64-bit second representation which -makes it incompatible with older nodes prior to version 6.7. (``//OpenSplice/Domain/y2038Ready`` is fully described +makes it incompatible with older nodes prior to version 6.7. (``//OpenSplice/Domain/y2038Ready`` is fully described in the :ref:`Configuration ` section) -.. _`CORBA C++`: +.. _`CORBA C++`: CORBA C++ ========= @@ -990,14 +990,14 @@ To rebuild this library to get support for the new 64-bit DDS_Time_t representat document which explains how to do this. -.. _`CORBA Java`: +.. _`CORBA Java`: CORBA Java ========== By default the CORBA Java library (dcpscj.jar) that comes with OpenSplice is built with support for the 32-bit DDS_Time_t representation. A new library dcpscj_y2038_ready.jar is added which supports the new 64-bit DDS_Time_t representation. This library can be used when -time stamps beyond year 2038 are needed. +time stamps beyond year 2038 are needed. .. _`Migration`: @@ -1006,19 +1006,19 @@ Migration ========= *client-durability* - Users that use client-durability cannot use times beyond 2038. This is because the client + Users that use client-durability cannot use times beyond 2038. This is because the client durability protocol uses DDS_Time_t in 32-bit. Also, Lite and Cafe do not support 64-bit yet. *DDS_Time_t in user data model* Users that currently use DDS_Time_t in their user-defined data structures cannot migrate a running system. If they want to migrate, the complete system must be shut down and delete all storages containing the old - 32-bit dds_time topics stored by the durability service. Rebuild the data models with the new 64-bit - dds_time topics and restart the system. Running a mixed environment with old and new dds_time structures + 32-bit dds_time topics stored by the durability service. Rebuild the data models with the new 64-bit + dds_time topics and restart the system. Running a mixed environment with old and new dds_time structures will result in topic mismatches. *Record and Replay (RnR) service* Users that use the Record and Replay service cannot use time beyond 2038. This is because the RnR service uses 32-bit times in the provided api. *No client durability and no DDS_Time_t usage* - Customers that do not use DDS_Time_t in their user-defined data structures AND do not use + Customers that do not use DDS_Time_t in their user-defined data structures AND do not use client durability can migrate in two steps: * First update all nodes to minimal version 6.7 to be compatible with the 64-bit time stamps, but don't set the domain/y2038Ready option @@ -1032,16 +1032,16 @@ Platform support ================ * Linux 64-bit: On 64-bit platforms linux already supports 64-bit time. No action required. -* Linux 32-bit: On 32-bit platforms linux support for 64-bit time stamps is still in development. - To provide y2038 safe time in GLIBC it is proposed - that the user code defines _TIME_BITS=64 to get 64bit time support. When GLIBC sees _TIME_BITS=64 or when - the system is 64bit it will set __USE_TIME_BITS64 to indicate that it will use 64bit time. +* Linux 32-bit: On 32-bit platforms linux support for 64-bit time stamps is still in development. + To provide y2038 safe time in GLIBC it is proposed + that the user code defines _TIME_BITS=64 to get 64bit time support. When GLIBC sees _TIME_BITS=64 or when + the system is 64bit it will set __USE_TIME_BITS64 to indicate that it will use 64bit time. Note that this is not yet supported. See: https://sourceware.org/glibc/wiki/Y2038ProofnessDesign?rev=83 -* Windows: 64-bit time stamps are supported +* Windows: 64-bit time stamps are supported -**NOTE**: Network Time Protocol: (This is outside the scope of OpenSplice) When NTP is used then there may be a problem -that the time stamp will rollover in 2036. This may not be an issue when version 4 of the NTP protocol is -used which provides specification of an era number and era offset. +**NOTE**: Network Time Protocol: (This is outside the scope of OpenSplice) When NTP is used then there may be a problem +that the time stamp will rollover in 2036. This may not be an issue when version 4 of the NTP protocol is +used which provides specification of an era number and era offset. .. _`DDS_Time structure change`: @@ -1087,7 +1087,7 @@ The original DDS_Time representation with a 32-bit second field: .. |java| image:: ./images/icon-java.* :height: 6mm - + .. EoF diff --git a/docs/html/DeploymentGuide/_sources/preface.txt b/docs/html/DeploymentGuide/_sources/preface.txt index 35ad4a8eb..ae096e47e 100644 --- a/docs/html/DeploymentGuide/_sources/preface.txt +++ b/docs/html/DeploymentGuide/_sources/preface.txt @@ -31,13 +31,13 @@ Organisation The :ref:`Overview ` gives a general description of the Vortex OpenSplice architecture. -This is followed by :ref:`Service Descriptions `, which -explain how Vortex OpenSplice provides integration of real-time DDS and the +This is followed by :ref:`Service Descriptions `, which +explain how Vortex OpenSplice provides integration of real-time DDS and the non-/near-real-time enterprise DBMS domains. The :ref:`Tools ` section introduces the OpenSplice system management tools. -Full details of the configuration elements and attributes of all +Full details of the configuration elements and attributes of all Vortex OpenSplice services are given in the :ref:`Configuration ` section. @@ -45,24 +45,24 @@ section. Conventions *********** -The icons shown below are used in PrismTech product documentation -to help readers to quickly identify information relevant to their +The icons shown below are used in ADLINK product documentation +to help readers to quickly identify information relevant to their specific use of Vortex OpenSplice. - ========= ================================================================== - *Icon* *Meaning* - ========= ================================================================== - |caution| Item of special significance or where caution needs to be taken. - |info| Item contains helpful hint or special information. - |windows| Information applies to Windows (*e.g.* XP, 2003, Windows 7) only. - |unix| Information applies to Unix-based systems (*e.g.* Solaris) only. - |linux| Information applies to Linux-based systems (*e.g.* Ubuntu) only. - |c| C language specific. - |cpp| C++ language specific. - |csharp| C# language specific. - |java| Java language specific. - ========= ================================================================== + ========= ================================================================== + *Icon* *Meaning* + ========= ================================================================== + |caution| Item of special significance or where caution needs to be taken. + |info| Item contains helpful hint or special information. + |windows| Information applies to Windows (*e.g.* XP, 2003, Windows 7) only. + |unix| Information applies to Unix-based systems (*e.g.* Solaris) only. + |linux| Information applies to Linux-based systems (*e.g.* Ubuntu) only. + |c| C language specific. + |cpp| C++ language specific. + |csharp| C# language specific. + |java| Java language specific. + ========= ================================================================== @@ -86,4 +86,4 @@ specific use of Vortex OpenSplice. .. |java| image:: ./images/icon-java.* :height: 6mm - + diff --git a/docs/html/DeploymentGuide/_sources/service-feature-list.txt b/docs/html/DeploymentGuide/_sources/service-feature-list.txt index bdac83dc3..fec45e7b5 100644 --- a/docs/html/DeploymentGuide/_sources/service-feature-list.txt +++ b/docs/html/DeploymentGuide/_sources/service-feature-list.txt @@ -40,7 +40,7 @@ Vortex OpenSplice middleware and its services can be configured using easy-to-maintain XML files. Full details of how to use XML files to configure -the elements and attributes of all OpenSplice DDS +the elements and attributes of all Vortex OpenSplice services are given in the :ref:`Configuration ` section. .. EoF diff --git a/docs/html/DeploymentGuide/contacts.html b/docs/html/DeploymentGuide/contacts.html index 93b3e9e6a..1e2063099 100644 --- a/docs/html/DeploymentGuide/contacts.html +++ b/docs/html/DeploymentGuide/contacts.html @@ -6,7 +6,7 @@ - 14. Contacts & Notices — The OpenSplice Deployment Guide + 15. Contacts & Notices — The OpenSplice Deployment Guide @@ -24,7 +24,7 @@ - + \ No newline at end of file diff --git a/docs/html/DeploymentGuide/dbmsconnect-service.html b/docs/html/DeploymentGuide/dbmsconnect-service.html index 0992ae777..570d54d64 100644 --- a/docs/html/DeploymentGuide/dbmsconnect-service.html +++ b/docs/html/DeploymentGuide/dbmsconnect-service.html @@ -504,7 +504,7 @@

      Navigation

      \ No newline at end of file diff --git a/docs/html/DeploymentGuide/ddsi2-networking-service.html b/docs/html/DeploymentGuide/ddsi2-networking-service.html index bc0c11bcc..dc5478cf9 100644 --- a/docs/html/DeploymentGuide/ddsi2-networking-service.html +++ b/docs/html/DeploymentGuide/ddsi2-networking-service.html @@ -92,14 +92,14 @@

      Navigation

      7.1. DDSI Concepts¶

      -

      The DDSI 2.1 standard is very intimately related to the DDS 1.2 standard, with a -clear correspondence between the entities in DDSI and those in DCPS. However, -this correspondence is not one-to-one.

      +

      Both DDSI 2.1 and 2.2 standards are very intimately related to the DDS 1.2 and 1.4 +standards, with a clear correspondence between the entities in DDSI and those in DCPS. +However, this correspondence is not one-to-one.

      In this section we give a high-level description of the concepts of the DDSI -specification, with hardly any reference to the specifics of the OpenSplice +specification, with hardly any reference to the specifics of the Vortex OpenSplice implementation, DDSI2, which are addressed in subsequent sections. This division was chosen to aid readers interested in interoperability to understand -where the specification ends and the OpenSplice implementation begins.

      +where the specification ends and the Vortex OpenSplice implementation begins.

      7.1.1. Mapping of DCPS domains to DDSI domains¶

      In DCPS, a domain is uniquely identified by a non-negative integer, the domain id. @@ -183,10 +183,10 @@

      Navigation

      can still obtain the latest sample for each existing instance.

      Naturally, once the DCPS writer is deleted (or disappears for whatever reason), the DDSI writer disappears as well, and with it, its history. For this reason, transient -data is generally much to be preferred over transient-local data. In OpenSplice the +data is generally much to be preferred over transient-local data. In Vortex OpenSplice the durability service implements all three durability kinds without requiring any special support from the networking services, ensuring that the full set of -durability features is always available between OpenSplice nodes.

      +durability features is always available between Vortex OpenSplice nodes.

      7.1.5. Discovery of participants & endpoints¶

      @@ -225,22 +225,22 @@

      Navigation

      SPDP message, following which all start exchanging SEDP data.
      -
      -

      7.2. OpenSplice DDSI2 specifics¶

      -
      -

      7.2.1. Translating between OpenSplice and DDSI¶

      +
      +

      7.2. Vortex OpenSplice DDSI2 specifics¶

      +
      +

      7.2.1. Translating between Vortex OpenSplice and DDSI¶

      Given that DDSI is the DDS interoperability specification, that the mapping -between DCPS entities and DDSI entities is straightforward, and that OpenSplice is +between DCPS entities and DDSI entities is straightforward, and that Vortex OpenSplice is a full implementation of the DDS specification, one might expect that relationship -between OpenSplice and its DDSI implementation, DDSI2, is trivial. Unfortunately, +between Vortex OpenSplice and its DDSI implementation, DDSI2, is trivial. Unfortunately, this is not the case, and it does show in a number of areas. A high-level overview such as this paragraph is not the place for the details of these cases, but they will be described in due course.

      The root cause of these complexities is a difference in design philosophy between -OpenSplice and the more recent DDSI.

      +Vortex OpenSplice and the more recent DDSI.

      DDSI is very strictly a peer-to-peer protocol at the level of individual endpoints, requiring lots of discovery traffic, and (at least when implemented naively) very bad -scalability. It is exactly these three problems that OpenSplice was designed to avoid, +scalability. It is exactly these three problems that Vortex OpenSplice was designed to avoid, and it does so successfully with its native RTNetworking service.

      Because of this design for scalability and the consequent use of service processes rather than forcing everything into self-contained application processes, there are @@ -248,7 +248,7 @@

      Navigation

      queuing and buffering and, consequently, blocking behaviour are subtly different; DDSI2 needs to also perform local discovery of DCPS endpoints to gather enough information for faithfully representing the system in terms of DDSI, it needs to -translate between completely different namespaces (native OpenSplice identifiers +translate between completely different namespaces (native Vortex OpenSplice identifiers are very different from the GUIDs used by DDSI), and it needs to work around receiving asynchronous notifications for events one would expect to be synchronous in DDSI.

      @@ -258,14 +258,14 @@

      Navigation

      7.2.2. Federated versus Standalone deployment¶

      As has been described elsewhere (see the Overview in this -Guide and also the Getting Started Guide), OpenSplice has multiple +Guide and also the Getting Started Guide), Vortex OpenSplice has multiple deployment models selectable in the configuration file (some of these require a license).

      For DDSI2, there is no difference between the various models: it simply serves whatever DCPS participants are in the same ‘instance’, whether that instance be a federation of processes on a single node, all attached to a shared memory segment -managed by a set of OpenSplice service processes on that node, or a standalone one -in which a single process incorporates the OpenSplice services as libraries.

      +managed by a set of Vortex OpenSplice service processes on that node, or a standalone one +in which a single process incorporates the Vortex OpenSplice services as libraries.

      This Guide ignores the various deployment modes, using the terminology associated with the federated deployment mode because that mode is the driving force behind several of the user-visible design decisions in DDSI2. In consequence, @@ -286,10 +286,10 @@

      Navigation

      is to instruct DDSI2 to completely ignore them using the DCPS topic/partition to network partition mapping available in the enhanced version, DDSI2E.

      A separate issue is that of the DCPS built-in topics when interoperating with other -implementations. In OpenSplice the built-in topics are first-class topics, i.e. the -only difference between application topics and the built-in topics in OpenSplice is +implementations. In Vortex OpenSplice the built-in topics are first-class topics, i.e. the +only difference between application topics and the built-in topics in Vortex OpenSplice is that the built-in topics are pre-defined and that they are published and used by the -OpenSplice services. This in turn allows the RTNetworking service to avoid +Vortex OpenSplice services. This in turn allows the RTNetworking service to avoid discovery of individual domain participants and endpoints, enabling its excellent scalability.

      Conversely, DDSI defines a different and slightly extended representation for the @@ -299,7 +299,7 @@

      Navigation

      Taken together, DDSI2 is in the unfortunate situation of having to straddle two very different approaches. While local reconstruction of the DCPS built-in topics by DDSI2 is clearly possible, it would negatively impact the handling of transient data. -Since handling transient data is one of the true strengths of OpenSplice, DDSI2 +Since handling transient data is one of the true strengths of Vortex OpenSplice, DDSI2 currently does not perform this reconstruction, with the unfortunate implication that loss of liveliness will not be handled fully when interoperating with another DDSI implementation.

      @@ -350,7 +350,7 @@

      Navigation

      participant independently, but it will generate the network traffic as if it does.

      Please refer to the Configuration section for detailed descriptions of:

        -
      • //OOpenSplice/DDSI2Service/Internal/BuiltinEndpointSet
      • +
      • //OpenSplice/DDSI2Service/Internal/BuiltinEndpointSet
      • //OpenSplice/DDSI2Service/Internal/ConservativeBuiltinReaderStartup

      However, please note that at the time of writing, we are not aware of any @@ -422,7 +422,7 @@

      Navigation

      7.2.4. Writer history QoS and throttling¶

      The DDSI specification heavily relies on the notion of a writer history cache (WHC) within which a sequence number uniquely identifies each sample. The original -OpenSplice design has a different division of responsibilities between various +Vortex OpenSplice design has a different division of responsibilities between various components than what is assumed by the DDSI specification and this includes the WHC. Despite the different division, the resulting behaviour is the same.

      DDSI2 bridges this divide by constructing its own WHC when needed. This WHC @@ -446,7 +446,7 @@

      Navigation

      unacknowledged samples, it stalls the writer until the number of bytes in unacknowledged samples drops below Internal/Watermarks/WhcLow.

      While ideally only the one writer would be stalled, the interface between the -OpenSplice kernel and DDSI2 is such that other outgoing traffic may be stalled as +Vortex OpenSplice kernel and DDSI2 is such that other outgoing traffic may be stalled as well. See Unresponsive readers & head-of-stream blocking.

      Please refer to the Configuration section for detailed descriptions of:

      @@ -465,7 +465,7 @@

      Navigation

      the samples timely will cause the WHC to run into resource limits.

      The correct treatment suggested by the DDS specification is to simply take the writer history QoS setting, apply this to the DDSI2 WHC, and block the writer up to -its ‘max_blocking_time’ QoS setting. However, the scalable architecture of +its ‘max_blocking_time’ QoS setting. However, the scalable architecture of Vortex OpenSplice renders this simple approach infeasible because of the division of labour between the application processes and the various services. Of course, even if it were a possible approach, the problem would still not be gone entirely, as one @@ -510,13 +510,13 @@

      Navigation

      7.2.6. Handling of multiple partitions and wildcards¶

      7.2.6.1. Publishing in multiple partitions¶

      -

      A variety of design choices allow OpenSplice in combination with its +

      A variety of design choices allow Vortex OpenSplice in combination with its RTNetworking service to be fully dynamically discovered, yet without requiring an expensive discovery protocol. A side effect of these choices is that a DCPS writer publishing a single sample in multiple partitions simultaneously will be translated by the current version of DDSI2 as a writer publishing multiple identical samples in all these partitions, but with unique sequence numbers.

      -

      When DDSI2 is used to communicate between OpenSplice nodes, this is not an +

      When DDSI2 is used to communicate between Vortex OpenSplice nodes, this is not an application-visible issue, but it is visible when interoperating with other implementations. Fortunately, publishing in multiple partitions is rarely a wise choice in a system design.

      @@ -531,7 +531,7 @@

      Navigation

      partition wildcards for publishing data can easily lead to the replication of data as mentioned in the previous subsection (Publishing in multiple partitions).

      Secondly, because DDSI2 implements transient-local data internally in a different -way from the way the OpenSplice durability service does, it is strongly +way from the way the Vortex OpenSplice durability service does, it is strongly recommended that the combination of transient-local data and publishing using partition wildcards be avoided completely.

      @@ -690,7 +690,7 @@

      Navigation

      7.3.1.2.4. Endpoint discovery¶

      Although the SEDP protocol never requires any configuration, the network -partitioning of OpenSplice DDSI2E does interact with it: so-called ‘ignored +partitioning of Vortex OpenSplice DDSI2E does interact with it: so-called ‘ignored partitions’ can be used to instruct DDSI2 to completely ignore certain DCPS topic and partition combinations, which will prevent DDSI2 from forwarding data for these topic/partition combinations to and from the network.

      @@ -703,7 +703,7 @@

      Navigation

      7.3.2. Combining multiple participants¶

      -

      In an OpenSplice standalone deployment the various configured services, such as +

      In a Vortex OpenSplice standalone deployment the various configured services, such as spliced and DDSI2, still retain their identity by creating their own DCPS domain participants. DDSI2 faithfully mirrors all these participants in DDSI, and it will appear at the DDSI level as if there is a large system with many participants, @@ -714,16 +714,16 @@

      Navigation

      assertions need to be sent.

      Clearly, the liveliness monitoring features that are related to domain participants will be affected if multiple DCPS domain participants are combined into a single -DDSI domain participant. The OpenSplice services all use a liveliness QoS setting +DDSI domain participant. The Vortex OpenSplice services all use a liveliness QoS setting of AUTOMATIC, which works fine.

      In a federated deployment, the effect of this option is to have only a single DDSI domain participant per node. This is of course much more scalable, but in no way resembles the actual structure of the system if there are in fact multiple application processes running on that node.

      -

      However, in OpenSplice the built-in topics are not derived from the DDSI -discovery, and hence in an OpenSplice-only network the use of the +

      However, in Vortex OpenSplice the built-in topics are not derived from the DDSI +discovery, and hence in a Vortex OpenSplice-only network the use of the Internal/SquashParticipants setting will not result in any loss of information -in the DCPS API or in the OpenSplice tools such as the Tester.

      +in the DCPS API or in the Vortex OpenSplice tools such as the Tester.

      When interoperability with another vendor is not needed, enabling the SquashParticipants option is often a good choice.

      Please refer to the Configuration section for @@ -754,7 +754,7 @@

      Navigation

      The default values, taken from the DDSI specification, are in parentheses. There are actually even more parameters, here simply turned into constants as there is absolutely no point in ever changing these values; however, they are configurable -and the interested reader is referred to the DDSI 2.1 specification, section 9.6.1.

      +and the interested reader is referred to the DDSI 2.1 or 2.2 specification, section 9.6.1.

      PI is the most interesting, as it relates to having multiple instances of DDSI2 in the same domain on a single node. In a federated deployment, this never happens (exceptional cases excluded). Its configured value is either ‘auto’, ‘none’ or a @@ -807,12 +807,12 @@

      Navigation

    • //OpenSplice/DDSI2Service/Compatibility/ManySocketsMode
    • -
      -

      7.3.4. Coexistence with OpenSplice RTNetworking¶

      +
      +

      7.3.4. Coexistence with Vortex OpenSplice RTNetworking¶

      DDSI2 has a special mode, configured using General/CoexistWithNativeNetworking, -to allow it to operate in conjunction with OpenSplice RTNetworking: in this mode +to allow it to operate in conjunction with Vortex OpenSplice RTNetworking: in this mode DDSI2 only handles packets sent by other vendors’ implementations, allowing all -intra-OpenSplice traffic to be handled by the RTNetworking service while still +intra-Vortex OpenSplice traffic to be handled by the RTNetworking service while still providing interoperability with other vendors.

      Please refer to the Configuration section for a detailed description of:

      @@ -826,7 +826,7 @@

      Navigation

      7.4.1. Data path architecture¶

      The data path in DDSI2 consists of a transmitting and a receiving side. The main -path in the transmit side accepts data to be transmitted from the OpenSplice kernel +path in the transmit side accepts data to be transmitted from the Vortex OpenSplice kernel via a network queue and administrates and formats the data for transmission over the network.

      The secondary path handles asynchronous events such as the periodic generation of @@ -852,7 +852,7 @@

      Navigation

      restricted to what in DDSI2E is the default channel if none are configured explicitly. For details on configuring channels, see Channel configuration.

      Each channel has its own transmit thread, draining a queue with samples to be -transmitted from the OpenSplice kernel. The maximum size of the queue can be +transmitted from the Vortex OpenSplice kernel. The maximum size of the queue can be configured per channel, and the default for the individual channels is configured using the Sizing/NetworkQueueSize setting. In DDSI2, this setting simply controls the queue size, as the default channel of DDSI2E has the default queue size. A larger @@ -1046,9 +1046,9 @@

      Navigation

      application data. The (CDR) serialised payload is never larger than the in-memory representation of the data.

      On the transmitting side, samples larger than MaxSampleSize are dropped with a -warning in the OpenSplice info log. DDSI2 behaves as if the sample never existed. -The current structure of the interface between the OpenSplice kernel and the -OpenSplice networking services unfortunately prevents DDSI2 from properly +warning in the Vortex OpenSplice info log. DDSI2 behaves as if the sample never existed. +The current structure of the interface between the Vortex OpenSplice kernel and the +Vortex OpenSplice networking services unfortunately prevents DDSI2 from properly reporting this back to the application that wrote the sample, so the only guaranteed way of detecting the dropping of the sample is by checking the info log.

      Similarly, on the receiving side, samples large than MaxSampleSize are dropped, @@ -1099,7 +1099,7 @@

      Navigation

      7.5.2.1. Channel configuration overview¶

      DDSI2E allows defining channels, which are independent data paths within the -DDSI service. OpenSplice chooses a channel based by matching the transport +DDSI service. Vortex OpenSplice chooses a channel based by matching the transport priority QoS setting of the data writer with the threshold specified for the various channels. Because each channel has a set of dedicated threads to perform the processing and the thread priorities can all be configured, it is straightforward to @@ -1117,7 +1117,7 @@

      Navigation

      receive thread only performs minimal work on each incoming packet, and never has to wait for the processing of user data.

      The existence of the receive thread is the only major difference between DDSI2E -channels and those of the OpenSplice RTNetworking service: in the RTNetworking +channels and those of the Vortex OpenSplice RTNetworking service: in the RTNetworking service, each thread is truly independent. This change is the consequence of DDSI2E interoperating with implementations that are not aware of channels and with DDSI2E nodes that have differently configured channels, unlike the @@ -1136,7 +1136,7 @@

      Navigation

      priority that is higher than the writer’s transport priority. If there is no such channel, i.e. the writer has a transport priority higher than the highest channel threshold, the channel with the highest threshold is used.

      -

      Each channel has its own network queue into which the OpenSplice kernel writes +

      Each channel has its own network queue into which the Vortex OpenSplice kernel writes samples to be transmitted and that DDSI2E reads. The size of this queue can be set for each channel independently by using Channels/Channel/QueueSize, with the default taken from the global Sizing/NetworkQueueSize.

      @@ -1326,7 +1326,7 @@

      Navigation

      processes all discovery data coming in from the network.
    • lease: performs internal liveliness monitoring of DDSI2 and renews the -OpenSplice kernel lease if the status is satisfactory.
    • +Vortex OpenSplice kernel lease if the status is satisfactory.
    • tev: timed-event handling, used for all kinds of things, such as: periodic transmission of participant discovery and liveliness messages, transmission @@ -1338,7 +1338,7 @@

      Navigation

      and, for each defined channel:

      • xmit.channel-name: -takes data from the OpenSplice kernel’s queue for this channel, serialises +takes data from the Vortex OpenSplice kernel’s queue for this channel, serialises it and forwards it to the network.
      • dq.channel-name: deserialisation and asynchronous delivery of all user data.
      • @@ -1356,7 +1356,7 @@

        Navigation

        DDSI2 can produce highly detailed traces of all traffic and internal activities. It enables individual categories of information, as well as having a simple verbosity level that enables fixed sets of categories and of which the definition -corresponds to that of the other OpenSplice services.

        +corresponds to that of the other Vortex OpenSplice services.

        The categorisation of tracing output is incomplete and hence most of the verbosity levels and categories are not of much use in the current release. This is an ongoing process and here we describe the target situation rather than the current situation.

        @@ -1423,12 +1423,12 @@

        Navigation

        a detailed description of //OpenSplice/DDSI2Service/Compatibility/StandardsConformance.)

        In pedantic mode, it strives very hard to strictly conform to the DDSI 2.1 -standard. It even uses a vendor-specific extension for an essential element +and 2.2 standards. It even uses a vendor-specific extension for an essential element missing in the specification, used for specifying the GUID of a DCPS data reader or data writer in the discovery protocol; and it adheres to the specified encoding of the reliability QoS. This mode is of interest for compliancy testing but not for practical use, even though there is no application-level -observable difference between an all-OpenSplice system using the DDSI2 +observable difference between an all-Vortex OpenSplice system using the DDSI2 service in pedantic mode and one operating in any of the other modes.

        The second mode, strict, instead attempts to follow the intent of the specification while staying close to the letter of it. The points in which @@ -1436,19 +1436,19 @@

        Navigation

        will be rectified in the next update. When operated in this mode, one would expect it to be fully interoperable with other vendors’ implementations, but this is not the case. The deviations in other vendors’ implementations -are not required to implement DDSI 2.1, as is proven by the OpenSplice DDSI2 +are not required to implement DDSI 2.1 (or 2.2), as is proven by the Vortex OpenSplice DDSI2 service, and they cannot rightly be considered ‘true’ implementations of -the DDSI 2.1 standard.

        +the DDSI 2.1 (or 2.2) standard.

        The default mode, lax, attempts to work around (most of) the deviations of other implementations, and provides interoperability with (at least) RTI DDS and InterCOM/Gallium DDS. (For compatibility with TwinOaks CoreDX DDS, additional settings are needed. See the next section for more information.) -In lax mode, the OpenSplice DDSI2 service not only accepts some invalid +In lax mode, the Vortex OpenSplice DDSI2 service not only accepts some invalid messages, but will even transmit them. The consequences for interoperability of not doing this are simply too severe. -It should be noted that if one configures two OpenSplice nodes with DDSI2 in +It should be noted that if one configures two Vortex OpenSplice nodes with DDSI2 in different compliancy modes, the one in the stricter mode will complain about messages sent by the one in the less strict mode. Pedantic mode will complain about invalid encodings used in strict mode, strict mode will complain about illegal @@ -1459,7 +1459,7 @@

        Navigation

        In lax mode, there should be no major issues with most topic types when working across a network, but within a single host there is a known problem with the way RTI DDS uses, or attempts to use, its shared memory transport to communicate with -OpenSplice, which clearly advertises only UDP/IP addresses at which it is +Vortex OpenSplice, which clearly advertises only UDP/IP addresses at which it is reachable. The result is an inability to reliably establish bidirectional communication between the two.

        Disposing data may also cause problems, as RTI DDS leaves out the serialised key @@ -1473,8 +1473,8 @@

        Navigation

        maximum length larger than 11 bytes. See the DDSI specification for details.

        In strict mode, there is interoperation with RTI DDS, but at the cost of incredibly high CPU and network load, caused by a Heartbeats and AckNacks going -back-and-forth between a reliable RTI DDS data writer and a reliable OpenSplice -DCPS data reader. The problem is that once the OpenSplice reader informs the RTI +back-and-forth between a reliable RTI DDS data writer and a reliable Vortex OpenSplice +DCPS data reader. The problem is that once the Vortex OpenSplice reader informs the RTI writer that it has received all data (using a valid AckNack message), the RTI writer immediately publishes a message listing the range of available sequence numbers and requesting an acknowledgement, which becomes an endless loop.

        @@ -1542,8 +1542,8 @@

        Table Of Contents

      • 7.1.5. Discovery of participants & endpoints
    • -
    • 7.2. OpenSplice DDSI2 specifics
    • \ No newline at end of file diff --git a/docs/html/DeploymentGuide/domain-service.html b/docs/html/DeploymentGuide/domain-service.html index 6f0b89ca3..51c09c1f1 100644 --- a/docs/html/DeploymentGuide/domain-service.html +++ b/docs/html/DeploymentGuide/domain-service.html @@ -138,7 +138,7 @@

      Navigation

      \ No newline at end of file diff --git a/docs/html/DeploymentGuide/durability-service.html b/docs/html/DeploymentGuide/durability-service.html index 66596628b..856829196 100644 --- a/docs/html/DeploymentGuide/durability-service.html +++ b/docs/html/DeploymentGuide/durability-service.html @@ -643,21 +643,46 @@

      Navigation

      5.4.3. Master selection¶

      -

      To ensure a single source for re-publishing of persistent data and to allow parallel -alignment, each durability service will select a master for every name-space.

      -

      The rules for determining a master are:

      +

      For each Namespace and Role combination there shall be at most one Master Durability +Service. The Master Durability Service coordinates single source re-publishing of +persistent data and to allow parallel alignment after system start-up, +and to coordinate recovery of a split brain syndrome after connecting nodes having +selected a different Master indicating that more than one state of the data may exist.

      +

      Therefore after system start-up as well as after any topology change (i.e. late joining +nodes or leaving master node) a master selection process will take place for each +affected Namespace/Role combination.

      +

      To control the master selection process a masterPriority attribute can be used.

      +

      Each Durability Service will have a configured masterPriority attribute per namespace +which is an integer value between 0 and 255 and which specifies the eagerness of the +Durability Service to become Master for that namespace. +The values 0 and 255 have a special meaning. +Value 0 is used to indicate that the Durability Service will never become Master. +The value 255 is used to indicate that the Durability Service will not use priorities +but instead uses the legacy selection algorithm. +If not configured the default is 255.

      +

      During the master selection process each Durability service will exchange for each +namespace the masterPriority and quality. The namespace quality is the timestamp of the +latest update of the persistent data set stored on disk and only plays a role in master +selection initially when no master has been chosen before and persistent data has not +been injected yet.

      +

      Each Durability Service will determine the Master based upon the highest non zero +masterPriority and in case of multiple masters further select based on namespace +quality (but only if persistent data has not been injected before) and again in case of +multiple masters select the highest system id. The local system id is an arbitrary +value which unique identifies a durability service. +After selection each Durability Service will communicate their determined master and on +agreement effectuate the selection, on disagreement which may occur if some Durability +Services had a temporary different view of the system this process of master selection +will restart until all Durability Services have the same view of the system and have +made the same selection. +If no durability services exists having a masterPriority greater than zero then no +master will be selected.

      +

      Summarizing, the precedence rules for master selection are (from high to low):

        -
      1. If some other durability service in the domain already selected -a master, pick the same one.
      2. -
      3. If no master has been selected, pick the one with the newest -initial set of persistent data.
      4. -
      5. If multiple durability services exist with the newest set of -initial persistent data, pick the one with the highest id -(this id is a domain-wide unique number that is -generated at start-up of each OpenSplice federation).
      6. +
      7. The namespace masterPriority
      8. +
      9. The namespace quality, if no data has been injected before.
      10. +
      11. The Durability Service system id, which is unique for each durability service.
      -

      If an existing master is no longer available, due to a disconnection, crash or -regular termination, a new master is selected based on the same rules.

      Please refer to the Configuration section for a detailed description of:

        @@ -789,6 +814,234 @@

        Navigation

        time two separately running systems get (re-)connected.

      +
      +

      5.5. Threads description¶

      +

      This section contains a short description of each durability thread. When applicable, +relevant configuration parameters are mentioned.

      +
      +

      5.5.1. ospl_durability¶

      +

      This is the main durability service thread. It starts most of the other threads, e.g. +the listener threads that are used to receive the durability protocol messages, +and it initiates initial alignment when necessary. This thread is responsible for +periodically updating the service-lease so that the splice-daemon is aware the service +is still alive. It also periodically (every 10 seconds) checks the state of all other +service threads to detect if deadlock has occurred. If deadlock has occurred the service +will indicate which thread didn’t make progress and action can be taken (e.g. the service +refrains from updating its service-lease, causing the splice daemon to execute a failure +action). Most of the time this thread is asleep.

      +
      +
      +

      5.5.2. conflictResolver¶

      +

      This thread is responsible for resolving conflicts. If a conflict has been detected and +stored in the conflictQueue, the conflictResolver thread takes the conflict, checks +whether the conflict still exists, and if so, starts the procedure to resolve the conflict +(i.e., start to determine a new master, send out sample requests, etc).

      +
      +
      +

      5.5.3. statusThread¶

      +

      This thread is responsible for the sending status messages to other durability services. +These messages are periodically sent between durability services to inform each other +about their state (.e.,g INITIALIZING or TERMINATING).

      +

      Configuration parameters:

      +
        +
      • //OpenSplice/DurabilityService/Watchdog/Scheduling
      • +
      +
      +
      +

      5.5.4. d_adminActionQueue¶

      +

      The durability service maintains a queue to schedule timed action. The d_adminActionQueue +periodically checks (every 100 ms) if an action is scheduled. +Example actions are: electing a new master, detection of new local groups and deleting +historical data.

      +

      Configuration parameters:

      +
        +
      • //OpenSplice/DurabilityService/Network/Heartbeat/Scheduling
      • +
      +
      +
      +

      5.5.5. AdminEventDispatcher¶

      +

      Communication between the splice-daemon and durability service is managed by events. The +AdminEventDispatcher thread listens and acts upon these events. For example, the creation +of a new topic is noticed by the splice-daemon, which generates an event for the +durability service, which schedules an action on to request historical data for the topic.

      +
      +
      +

      5.5.6. groupCreationThread¶

      +

      The groupCreationThread is responsible for the creation of groups that exist in other +federations. When a durability service receives a newGroup message from another +federation, it must create the group locally in order to acquire data for it. +Creation of a group may fail in case a topic is not yet known. The thread will retry with +a 10ms interval.

      +
      +
      +

      5.5.7. sampleRequestHandler¶

      +

      This thread is responsible for the handling of sampleRequests. When a durability +service receives a d_sampleRequest message (see the sampleRequestListener thread) it +will not immediately answer the request, but wait some time until the time to combine +requests has been expired (see +//OpenSplice/DurabilityService/Network/Alignment/RequestCombinePeriod). When this time +has expired the sampleRequestHandler will answer the request by collecting the requested +data and sending the data as d_sampleChain messages to the requestor.

      +

      Configuration parameters:

      +
        +
      • //OpenSplice/DurabilityService/Network/Alignment/AlignerScheduling
      • +
      +
      +
      +

      5.5.8. resendQueue¶

      +

      This thread is responsible for injection of message in the group after it has been rejected +before. When a durability service has received historical data from another fellow, +historical data is injected in the group (see d_sampleChain). Injection of historical data +can be rejected, e.g., when a resource limits are being used. When this happens, a new attempt +to inject the data is scheduled overusing the resendQueue thread. This thread will try to +deliver the data 1s later.

      +

      Configuration parameters:

      +
        +
      • //OpenSplice/DurabilityService/Network/Alignment/AligneeScheduling
      • +
      +
      +
      +

      5.5.9. masterMonitor¶

      +

      The masterMonitor is the thread that handles the selection of a new master. This thread is +invoked when the conflict resolver detects that a master conflict has occurred. The +masterMonitor is responsible for collecting master proposals from other fellows and sending +out proposals to other fellows.

      +
      +
      +

      5.5.10. groupLocalListenerActionQueue¶

      +

      This thread is used to handle historical data requests from specific readers, and to handle +delayed alignment (see //OpenSplice/DurabilityService/NameSpaces/Policy[@delayedAlignment])

      +
      +
      +

      5.5.11. d_groupsRequest¶

      +

      The d_groupsRequest thread is responsible for processing incoming d_groupsRequest messages +from other fellows. When a durability service receives a message from a fellow, the durability +service will send information about its groups to the requestor by means of d_newGroup messages. +This thread collects group information, packs it in d_newGroup messages and send them to the +requestor. This thread will only do something when a d_groupsRequest has been received from a +fellow. Most of the time it will sleep.

      +
      +
      +

      5.5.12. d_nameSpaces¶

      +

      This thread is responsible for processing incoming d_nameSpaces messages from other fellows. +Durability services send each other their namespaces state so that they can detect potential +conflicts. The d_nameSpaces thread processes and administrates every incoming d_nameSpace. When +a conflict is detected, the conflict is scheduled which may cause the conflictResolver thread +to kick in.

      +
      +
      +

      5.5.13. d_nameSpacesRequest¶

      +

      The d_nameSpacesRequest thread is responsible for processing incoming d_nameSpacesRequest +messages from other fellows. A durability service can request the namespaces form a fellow by +sending a d_nameSpacesRequest message to the fellow. Whenever a durability service receives a +d_nameSpacesRequest messages it will respond by sending its set of namespaces to the fellow. +The thread handles incoming d_nameSpacesRequest messages. As a side effect new fellows can be +discovered if a nameSpacesRequest is received from an unknown fellow.

      +
      +
      +

      5.5.14. d_status¶

      +

      The d_status thread is responsible for processing incoming d_status messages from other fellows. +Durability services periodically send each other status information (see the statusThread). +NOTE: in earlier versions missing d_status messages could lead to the conclusion that a fellows +has been removed. In recent versions this mechanism has been replaced so that the durability +service slaves itself to the liveness of remote federations based on heartbeats +(see thread dcpsHeartbeatListener). Effectivily, the d_status message is not used anymore to +verify liveliness of remote federations, it is only used to transfer the durability state of +a remote federation.

      +
      +
      +

      5.5.15. d_newGroup¶

      +

      The d_newGroup thread is responsible for handling incoming d_newGroup messages from other fellows. +Durability services inform each other about groups in the namespaces. They do that by sending +d_newGroup messages to each other (see also thread d_groupsRequest). The d_newGroup thread is +responsible for handling incoming groups.

      +
      +
      +

      5.5.16. d_sampleChain¶

      +

      The d_sampleChain thread handles incoming d_sampleChain messages from other fellows. When a +durability service answers an d_sampleRequest, it must collect the requested data and send it +to the requestor. The collected data is packed in d_sampleChain messages. The d_sampleChain thread +handles incoming d_sampleChain messages and applies the configured merge policy for the data. +For example, in case of a MERGE it injects all the received data in the local group and delivers +the data to the available readers.

      +

      Configuration parameters:

      +
        +
      • //OpenSplice/DurabilityService/Network/Alignment/AligneeScheduling
      • +
      +
      +
      +

      5.5.17. d_sampleRequest¶

      +

      The d_sampleRequest thread is responsible for handling incoming d_sampleRequest messages from +other fellows. A durability service can request historical data from a fellow by sending a +d_sampleRequest message. The d_sampleRequest thread is used to process d_sampleRequest messages. +Because d_sampleRequest messages are not handled immediately, they are stored in a list and handled +later on (see thread sampleRequestHandler).

      +
      +
      +

      5.5.18. d_deleteData¶

      +

      The d_deleteData thread is responsible for handling incoming d_deleteData messages from other fellows. +An application can call delete_historical_data(). This causes all historical data up till now to be +deleted. To propagate deletion of historical data to all available durability services in the system, +durability services send each other a d_deleteData message. The d_deleteData thread handles incoming +d_deleteData messages and takes care that the relevant data is deleted. This thread will only be active +after delete_historical_data() is called.

      +
      +
      +

      5.5.19. dcpsHeartbeatListener¶

      +

      The dcpsHeartbeatListener is responsible for the liveliness detection of remote federations. This +thread listens to DCPSHeartbeat messages that are sent by federation. It is used to detect new +federations or federations that disconnect. This thread will only do something when there is a change +in federation topology. Most of the time it will be asleep.

      +
      +
      +

      5.5.20. d_capability¶

      +

      The thread is responsible for processing d_cability messages from other fellows. As soon as a durability +service detects a fellow it will send its list of capabilities to the fellow. The fellow can use this +list to find what functionality is supported by the durability service. Similarly, the durability +service can receive capabilities from the fellow. This thread is used to process the capabilities sent by +a fellow. This thread will only do something when a fellow is detected. | |

      +
      +
      +

      5.5.21. remoteReader¶

      +

      The remoteReader thread is responsible for the detection of remote readers on other federations. The DDSI +service performs discovery and reader-writing matching. This is an asynchronous mechanism. When a +durability service (say A) receives a request from a fellow durability service (say B) and DDSI is used +as networking service, then A cannot be sure that DDSI has already detected the reader on B that should +receive the answer to the request. To ensure that durability services will only answer if all relevant +remote readers have been detected, the remoteReader thread keeps track of the readers that have been +discovered by ddsi. Only when all relevant readers have been discovered durability services are allowed +to answer requests. This prevents DDSI from dropping messages destined for readers that have not been +discovered yet.

      +
      +
      +

      5.5.22. persistentDataListener¶

      +

      The persistentDataListenerThread is responsible for persisting durable data. When a durability service +retrieves persistent data, the data is stored in a queue. The persistentDataListener thread retrieves the +data from the queue and stores it in the persistent store. For large data sets persisting the data can take +quite some time, depending mostly on the performance of the disk.

      +

      Note this thread is only created when persistency is enabled +(//OpenSplice/DurabilityService/Persistent/StoreDirectory has a value set):

      +

      Configuration parameters:

      +
        +
      • //OpenSplice/DurabilityService/Persistent/Scheduling
      • +
      +
      +
      +

      5.5.23. historicalDataRequestHandler¶

      +

      This thread is responsible for handling incoming historicalDataRequest messages from durability clients. In +case an application does not have the resources to run a durability service but still wants to acquire +historical data it can configure a client. The client sends HistoricalDataRequest messages to the durability +service. These messages are handled by the historicalDataRequestHandler thread.

      +

      Note this thread is only created when client durability is enabled +(//OpenSplice/DurabilityService/ClientDurability element exists)

      +
      +
      +

      5.5.24. durabilityStateListener¶

      +

      This thread is responsible for handling incoming durabilityStateRequest messages from durability clients.

      +

      Note this thread is only created when client durability is enabled +(//OpenSplice/DurabilityService/ClientDurability element exists)

      +
      +
      @@ -838,6 +1091,33 @@

      Table Of Contents

    • 5.4.8. Merge historical data
    • +
    • 5.5. Threads description +
    • @@ -886,7 +1166,7 @@

      Navigation

      \ No newline at end of file diff --git a/docs/html/DeploymentGuide/genindex.html b/docs/html/DeploymentGuide/genindex.html index c0e613df6..2276d9ce6 100644 --- a/docs/html/DeploymentGuide/genindex.html +++ b/docs/html/DeploymentGuide/genindex.html @@ -88,7 +88,7 @@

      Navigation

      \ No newline at end of file diff --git a/docs/html/DeploymentGuide/guide.html b/docs/html/DeploymentGuide/guide.html index c6283e54a..f0401c185 100644 --- a/docs/html/DeploymentGuide/guide.html +++ b/docs/html/DeploymentGuide/guide.html @@ -170,13 +170,13 @@

      Navigation

      12.1. OpenSplice¶

      -

      OpenSplice DDS is highly configurable, even allowing the architecture of the -DDS middleware to be chosen by the user at deployment time. OpenSplice DDS can +

      Vortex OpenSplice is highly configurable, even allowing the architecture of the +DDS middleware to be chosen by the user at deployment time. Vortex OpenSplice can be configured to run using a shared memory architecture, where both the DDS related administration (including the optional pluggable services) and DDS -applications interface directly with shared memory. Alternatively, OpenSplice -DDS also supports a single process architecture, where one or more DDS -applications, together with the OpenSplice administration and services, can all be +applications interface directly with shared memory. Alternatively, Vortex OpenSplice +also supports a single process architecture, where one or more DDS +applications, together with the Vortex OpenSplice administration and services, can all be grouped into a single operating system process. Both deployment modes support a configurable and extensible set of services, providing functionality such as:

      @@ -185,22 +185,23 @@

      12.1. OpenSplice
    • Full path: //OpenSplice
    • Occurrences min-max: 1-1
    • Child elements: Description
    • +
    • Optional attributes: version
    • +Please see section 9.6.1 of the Real-time Publish-Subscribe Wire Protocol DDS Interoperability Wire Protocol specification (DDSI), v2.1, formal/2009-01-05 +or v2.2, formal/2014-09-01, at http://www.omg.org/spec/DDSI for further information.
      • Full path: //OpenSplice/Domain/Id
      • Format: integer
      • @@ -289,7 +290,7 @@

        12.2.4. Lease¶

        This element specifies the interval(in seconds) in which services have to announce their liveliness.

        -

        Every OpenSplice service including the Domain service itself has to announce its liveliness regularly. +

        Every Vortex OpenSplice service including the Domain service itself has to announce its liveliness regularly. This allows corrective actions to be taken when one of the services becomes non-responsive. This element specifies the required interval. Decreasing the interval decreases the time in which non-responsiveness of a service is detected, but leads to more processing. Increasing it has @@ -401,7 +402,7 @@

        12.2.6. ServiceTerminatePeriod
      • Full path: //OpenSplice/Domain/ServiceTerminatePeriod
      • Format: float
      • @@ -415,23 +416,23 @@

        12.2.6. ServiceTerminatePeriod¶

        -
        The SingleProcess element specifies whether the OpenSplice Domain and other
        -
        OpenSplice services and applications are intended to be all deployed within the -same process, known in OpenSplice as a single process.
        +
        The SingleProcess element specifies whether the Vortex OpenSplice Domain and other
        +
        Vortex OpenSplice services and applications are intended to be all deployed within the +same process, known in Vortex OpenSplice as a single process.
        Please note that the choice to use the single process deployment also implies
        -
        the use of heap memory for the OpenSplice database management instead of shared +
        the use of heap memory for the Vortex OpenSplice database management instead of shared memory that would be used otherwise. If no database size or size 0 is configured the heap memory is limited by the Operating System, so the Database element under Domain does not take effect when SingleProcess has a value of True. If the database size is configured with a value, a database will be allocated on heap with that size and the domain service will use it’s own memory manager to manage that memory
        -
        There are two ways in which to deploy an OpenSplice DDS application as a
        +
        There are two ways in which to deploy an Vortex OpenSplice application as a
        single process:
        Single Process Application : The user starts an application as a
        new process. In this case, the DDS create_participant operation will -implicitly start the OpenSplice Domain Service as a thread in the existing -application process. The OpenSplice Domain Service will then also implicitly +implicitly start the Vortex OpenSplice Domain Service as a thread in the existing +application process. The Vortex OpenSplice Domain Service will then also implicitly start all services specified in the configuration as threads within the same process.
        Single Process Application Cluster : This provides the option to
        @@ -480,7 +481,7 @@

        12.2.9. CPUAffinity¶

        -
        The InProcessExceptionHandling element determines whether a process that uses OpenSplice will
        +
        The InProcessExceptionHandling element determines whether a process that uses Vortex OpenSplice will
        handle exceptions by itself and try to clean up shared resources or not. If the process itself refrains from cleaning up its resources, the splice-daemon will attempt to clean up the application shared resources asynchronously. If the splice-daemon during clean-up determines that shared @@ -1218,7 +1219,7 @@

        12.2.12.1. Size

        12.2.12.2. Threshold¶

        -
        This element specifies the threshold size used by OpenSplice DDS. Whenever there is less +
        This element specifies the threshold size used by Vortex OpenSplice. Whenever there is less free shared memory then indicated by the threshold then no new allocations will be allowed within shared memory. Services are allowed to continue allocating shared memory until less then 50% of the threshold value is available. It is strongly discouraged to configure a threshold @@ -1246,15 +1247,21 @@

        12.2.12.3. Address -
      • 0x20000000 (Linux2.6 on x86)
      • -
      • 00x140000000 (Linux2.6 on x86_64)
      • -
      • 00x40000000 (Windows on x86)
      • -
      • 00x40000000 (Windows on x86_64)
      • -
      • 00xA0000000 (Solaris on SPARC)
      • -
      • 00xA0000000 (AIX5.3 on POWER5+)
      • -
      • 00x0 (VxWorks 5.5.1 on PowerPC604)
      • -
      • 00x60000000 (VxWorks 6.x on PowerPC604)
      • -
      • 00x20000000 (Integrity on mvme5100)
      • +
      • 00x20000000 (Linux)
      • +
      • 00x140000000 (Linux 64-bit)
      • +
      • 00x40000000 (Windows)
      • +
      • 00x140000000 (Windows 64-bit)
      • +
      • 00xA0000000 (Solaris)
      • +
      • 00xA0000000 (AIX5.3)
      • +
      • 00x0 (VxWorks 5.5.1)
      • +
      • 00x60000000 (VxWorks 6.x)
      • +
      • 00x20000000 (Integrity)
      • +
      • 00x20000000 (LynxOS)
      • +
      • 00x140000000 (LynxOS 64-bit)
      • +
      • 00x0 (PikeOS)
      • +
      • 00x60000000 (QXN)
      • +
      • 00x0 (RTEMS)
      • +
      • 00x00220000 (Windows CE)
        @@ -1337,7 +1344,7 @@

        12.2.14.1. name +

        12.2.15. GIDKey¶

        +
          +
        • Full path: //OpenSplice/Domain/GIDKey
        • +
        • Occurrences min-max: 0-*
        • +
        • Required attributes: groups
        • +
        +
        +

        12.2.15.1. groups¶

        +
        +
        This attribute specifies the namespace by which the corresponding groups +will use the writer instance gid as key so that data from different writers +don merge as historical data for late joiners.
        +
          +
        • Full path: //OpenSplice/Domain/GIDKey[@groups]
        • +
        • Format: string
        • +
        • Default value: n/a
        • +
        • Required: true
        • +
        +
        +

      -

      12.2.15. Application¶

      +

      12.2.16. Application¶

      When in the single process deployment mode, the Domain service can deploy DDS applications by dynamically loading application shared libraries and starting threads within the existing process. A user can add a multiple Application elements to the configuration when they want -to ‘cluster’ multiple DDS applications within an OpenSplice DDS single process. +to ‘cluster’ multiple DDS applications within an Vortex OpenSplice single process. The entry point and shared library for each Application can be specified by using the Command and Library elements that are described below.>/p> Note that Applications only take effect when the single process configuration is enabled by way of the SingleProcess element.
      @@ -1604,7 +1632,7 @@

      12.2.15. Application -

      12.2.15.1. name¶

      +

      12.2.16.1. name¶

      This attribute assigns a configuration label to the application, but it is of no further use; it can have any valid string value
      @@ -1616,7 +1644,7 @@

      12.2.15.1. name -

      12.2.15.2. enabled¶

      +

      12.2.16.2. enabled¶

      This attribute indicates whether the application is actually started or not.

      Toggling an applicatione between enabled and disabled is a quick alternative for @@ -1630,12 +1658,12 @@

      12.2.15.2. enabled -

      12.2.15.3. Command¶

      +

      12.2.16.3. Command¶

      Command is the name of both the entry point function to invoked and the name of the shared library to be dynamically loaded into the process. The signature of the entry point function is the same as argc/argv usually seen with main.

      -

      For example, if Command is “HelloWorld”, OpenSpliceDDS will attempt to load +

      For example, if Command is “HelloWorld”, Vortex OpenSplice will attempt to load “libHelloWorld.so” on Unix (or “HelloWorld.dll” on Windows) into the existing process and then invoke the “HelloWorld” entry point to start that DDS application.

      If the name of the shared library does not have the same name as the entry point the @@ -1653,11 +1681,11 @@

      12.2.15.3. Command -

      12.2.15.4. Arguments¶

      +

      12.2.16.4. Arguments¶

      This optional attribute allows the user to specify arguments to be passed to the DDS application’s entry point when it is invoked.

      -

      For example, if Command is “HelloWorld” and Arguments is “arg1 arg2”, OpenSplice will +

      For example, if Command is “HelloWorld” and Arguments is “arg1 arg2”, Vortex OpenSplice will invoke the HelloWorld function with the argc = 3 and argv = {“HelloWorld”, “arg1”, “arg2”}

      -
      2.2.4.2.2. Stopping Applications in Shared Memory Mode¶
      +
      2.2.4.2.2. Stopping Applications in Shared Memory Mode¶

      Applications that are connected to and use Vortex OpenSplice in shared memory mode must not be terminated with a KILL signal. This will ensure that Vortex OpenSplice DDS shared memory always remains in a valid, functional state.

      @@ -497,14 +497,14 @@

      Navigation

      -

      2.2.5. Deploying Vortex OpenSplice on VxWorks 6.x¶

      +

      2.2.5. Deploying Vortex OpenSplice on VxWorks 6.x¶

      The VxWorks version of Vortex OpenSplice does not include the ospl program. Please refer to the Getting Started Guide for details of how to use VxWorks projects and Real Time Processes to deploy Vortex OpenSplice applications.

      -

      2.2.6. Deploying Vortex OpenSplice on Integrity¶

      +

      2.2.6. Deploying Vortex OpenSplice on Integrity¶

      The Integrity version of Vortex OpenSplice does not include the ospl program. Instead there is a project generator, ospl_projgen, which generates projects containing the required address spaces which will auto-start when loaded. Please @@ -512,14 +512,14 @@

      Navigation

      Vortex OpenSplice deployment on Integrity.

      -

      2.2.7. Installing/Uninstalling the Vortex OpenSplice C# Assembly to the Global Assembly Cache¶

      +

      2.2.7. Installing/Uninstalling the Vortex OpenSplice C# Assembly to the Global Assembly Cache¶

      The installer for the commercial distribution of Vortex OpenSplice includes the option to install the C# Assembly to the Global Assembly Cache during the installation process. If you chose to omit this step, or you are an open source user, then you should follow the instructions in the next few paragraphs, which describe how to manually install and uninstall the assembly to the Global Assembly Cache.

      -

      2.2.7.1. Installing the C# Assembly to the Global Assembly Cache¶

      +

      2.2.7.1. Installing the C# Assembly to the Global Assembly Cache¶

      To install an assembly to the Global Assembly Cache, you need to use the gacutil.exe tool. Start a Visual Studio command prompt and type:

      % gacutil /i <Vortex OpenSplice installation path>\bin\dcpssacsAssembly.dll
      @@ -529,7 +529,7 @@ 

      Navigation

      Vortex OpenSplice distribution. If you are successful you will see a message similar to the following:

      % C:\Program Files\Microsoft Visual Studio 9.0\VC>gacutil.exe /i
      -"C:\Program Files \PrismTech\VortexOpenSplice\V6.6.0\HDE\x86.win32\
      +"C:\Program Files \ADLINK\VortexOpenSplice\V6.6.0\HDE\x86.win32\
       bin\dcpssacsAssembly.dll"
       %
       % Microsoft (R) .NET Global Assembly Cache Utility. Version
      @@ -543,7 +543,7 @@ 

      Navigation

      -

      2.2.7.2. Uninstalling the C# Assembly from the Global Assembly Cache¶

      +

      2.2.7.2. Uninstalling the C# Assembly from the Global Assembly Cache¶

      To uninstall an assembly from the Global Assembly Cache, you need to use the gacutil.exe tool. Start a Visual Studio command prompt and type:

      % gacutil /u dcpssacsAssembly,Version=<version_number_goes_here>
      @@ -594,7 +594,7 @@ 

      Navigation

      -

      2.3. Vortex OpenSplice Configuration¶

      +

      2.3. Vortex OpenSplice Configuration¶

      Each application domain has its own characteristics; Vortex OpenSplice therefore allows configuring a wide range of parameters that influence its behaviour to be able to achieve optimal performance in every situation. This section describes generally @@ -602,7 +602,7 @@

      Navigation

      This requires the creation of a custom configuration file and an instruction to the middleware to use this custom configuration file.

      -

      2.3.1. Configuration Files¶

      +

      2.3.1. Configuration Files¶

      Vortex OpenSplice expects the configuration to be defined in the XML format. The expected syntax and semantics of the configuration parameters will be discussed further on in this document. Within the context of Vortex OpenSplice, a reference to a @@ -620,7 +620,7 @@

      Navigation

      in the configuration.

      -

      2.3.2. Environment Variables¶

      +

      2.3.2. Environment Variables¶

      The Vortex OpenSplice middleware will read several environment variables for different purposes. These variables are mentioned in this document at several places. To some extent, the user can customize the Vortex OpenSplice middleware by adapting the @@ -630,7 +630,7 @@

      Navigation

      When parsing the XML configuration, the Domain Service will replace the symbol with the variable value found in the environment.

      -

      2.3.2.1. The OSPL_URI environment variable¶

      +

      2.3.2.1. The OSPL_URI environment variable¶

      The environment variable OSPL_URI is a convenient mechanism to pass the configuration file to the Domain Service and DDS applications. The variable will refer to the default configuration that comes with Vortex OpenSplice but of course can @@ -651,7 +651,7 @@

      Navigation

      -

      2.3.3. Configuration of Single Process deployment¶

      +

      2.3.3. Configuration of Single Process deployment¶

      A single process deployment is enabled when the OSPL_URI environment variable refers to an XML configuration containing the <SingleProcess> attribute within the Domain section (//OpenSplice/Domain/SingleProcess). @@ -665,7 +665,7 @@

      Navigation

      pass any Vortex OpenSplice configuration parameters to the application.

      -

      2.3.4. Configuration of Shared Memory deployment¶

      +

      2.3.4. Configuration of Shared Memory deployment¶

      In order to have Vortex OpenSplice start with a custom configuration file, use:

      % ospl start <URI>
       
      @@ -693,7 +693,7 @@

      Navigation

      to be started or stopped.

      -

      2.3.5. Temporary Files¶

      +

      2.3.5. Temporary Files¶

      Please note that for a shared memory deployment, Vortex OpenSplice uses temporary files that are used to describe the shared memory that has been created. The exact nature of these files varies according to the operating system; however, the user does not @@ -710,7 +710,7 @@

      Navigation

      -

      2.4. Applications which operate in multiple domains¶

      +

      2.4. Applications which operate in multiple domains¶

      Vortex OpenSplice can be configured to allow a DDS application to operate in multiple domains.

      caution

      @@ -738,7 +738,7 @@

      Navigation

      application code, then appropriate steps must be taken at deployment in order to ensure that applications operate in the domain they were intended to.

      -

      2.4.1. Interaction with a Networking Service¶

      +

      2.4.1. Interaction with a Networking Service¶

      Where multiple domains are running on a single node, each domain must run its own instance of a networking service if that domain is to participate in remote communication.

      @@ -750,13 +750,13 @@

      Navigation

      -

      2.5. Time-jumps¶

      +

      2.5. Time-jumps¶

      Observed time discontinuities can affect data ordering and processing of middleware actions. Time-jumps can be caused by adjusting the clock forward or backward. When resuming from being suspended, time will seem to have jumped forward as if the clock was advanced.

      -

      2.5.1. Effect on data¶

      +

      2.5.1. Effect on data¶

      When a sample is published, a time stamp is determined at the source which is attached to the sample before it is sent. The subscriber stores the time stamp at which the sample is received in the sample as well. In DDS samples are ordered within the @@ -788,7 +788,7 @@

      Navigation

      -

      2.5.2. Effect on processing¶

      +

      2.5.2. Effect on processing¶

      Processing of relative time actions, actions for which a time contract exists with local entities (e.g., inter-process leases, wait for attachment of a service) or time contracts involving remote parties (e.g., heartbeats, deadline) may not behave as @@ -803,7 +803,7 @@

      Navigation

      these to prevent the adverse effects of observed time-jumps on its processing.

      -

      2.5.3. Background information¶

      +

      2.5.3. Background information¶

      The basic clock used for time stamps of data published in DDS is the real-time clock. This time is expressed as the time since the Unix epoch (00:00:00 on Thursday the 1st of January 1970, UTC). All systems support some form of a real-time clock. For @@ -851,19 +851,19 @@

      2.6. Time stamps and year 2038 limit//OpenSplice/Domain/y2038Ready is fully described in the Configuration section)

      -

      2.6.1. CORBA C++¶

      +

      2.6.1. CORBA C++¶

      By default the CORBA C++ library (dcpsccpp) that comes with OpenSplice is built with support for the 32-bit DDS_Time_t representation. To rebuild this library to get support for the new 64-bit DDS_Time_t representation please look at the OSPL_HOME/custom_lib/ccpp/README document which explains how to do this.

      -

      2.6.2. CORBA Java¶

      +

      2.6.2. CORBA Java¶

      By default the CORBA Java library (dcpscj.jar) that comes with OpenSplice is built with support for the 32-bit DDS_Time_t representation. A new library dcpscj_y2038_ready.jar is added which supports the new 64-bit DDS_Time_t representation. This library can be used when time stamps beyond year 2038 are needed.

      -

      2.6.3. Migration¶

      +

      2.6.3. Migration¶

      client-durability
      Users that use client-durability cannot use times beyond 2038. This is because the client @@ -892,7 +892,7 @@

      2.6. Time stamps and year 2038 limit -

      2.6.4. Platform support¶

      +

      2.6.4. Platform support¶

      • Linux 64-bit: On 64-bit platforms linux already supports 64-bit time. No action required.
      • Linux 32-bit: On 32-bit platforms linux support for 64-bit time stamps is still in development. @@ -907,7 +907,7 @@

        2.6. Time stamps and year 2038 limit -

        2.6.5. DDS_Time structure change¶

        +

        2.6.5. DDS_Time structure change¶

        The new DDS_Time representation which contains a 64-bit second field:

        module DDS {
             struct Time_t {
        @@ -1051,7 +1051,7 @@ 

        Navigation

      \ No newline at end of file diff --git a/docs/html/DeploymentGuide/preface.html b/docs/html/DeploymentGuide/preface.html index 2b9d0e979..361ad81b9 100644 --- a/docs/html/DeploymentGuide/preface.html +++ b/docs/html/DeploymentGuide/preface.html @@ -78,7 +78,7 @@

      1.3. Organisation

      1.4. Conventions¶

      -

      The icons shown below are used in PrismTech product documentation +

      The icons shown below are used in ADLINK product documentation to help readers to quickly identify information relevant to their specific use of Vortex OpenSplice.

      @@ -190,7 +190,7 @@

      Navigation

    \ No newline at end of file diff --git a/docs/html/DeploymentGuide/referencesystems.html b/docs/html/DeploymentGuide/referencesystems.html index dc9404731..35f14dfcd 100644 --- a/docs/html/DeploymentGuide/referencesystems.html +++ b/docs/html/DeploymentGuide/referencesystems.html @@ -24,7 +24,7 @@ - + @@ -35,7 +35,7 @@

    Navigation

    index
  • - next |
  • Previous topic
  • 12. Configuration

    Next topic

    -

    14. Contacts & Notices

    +

    14. Logrotate

    This Page

    index
  • - next |
  • Navigation
  • \ No newline at end of file diff --git a/docs/html/DeploymentGuide/search.html b/docs/html/DeploymentGuide/search.html index 4279feac7..a70f761db 100644 --- a/docs/html/DeploymentGuide/search.html +++ b/docs/html/DeploymentGuide/search.html @@ -95,7 +95,7 @@

    Navigation

    \ No newline at end of file diff --git a/docs/html/DeploymentGuide/searchindex.js b/docs/html/DeploymentGuide/searchindex.js index b8bc002f0..49ffd3234 100644 --- a/docs/html/DeploymentGuide/searchindex.js +++ b/docs/html/DeploymentGuide/searchindex.js @@ -1 +1 @@ -Search.setIndex({envversion:42,terms:{entropi:14,"_time_bit":3,communict:14,child:[3,14],four:[13,1,7],secondli:8,prefix:[13,14],sleep:[14,8],nw_compressor:7,consider:[11,1,8],whose:14,accur:3,"const":[14,7],emptiv:14,deviat:8,swap:14,under:[14,1,8],sigfp:3,worth:8,digit:[14,7],lack:[6,8],everi:[3,14,13,1,11],risk:8,"void":[14,7],voic:14,govern:[14,8],affect:[3,14,8],vast:14,disturb:14,unblock:1,taskmanag:3,verif:14,mvme5100:14,initialis:[3,5,14,7],x86_64:14,zlib:[0,14],"10m":14,naiv:8,seper:14,budget:[14,11],consequ:[11,14,8],second:[3,14,13,1,8],releaseinfo:3,aggreg:14,even:[1,3,6,8,13,14],aim:8,hide:14,muex:14,neg:[13,14,8],asid:1,"new":[1,3,5,8,13,14],net:3,ever:8,topolog:[0,1,14],ongo:[14,8],elimin:[6,8],manipul:3,abov:[3,13,7,8],never:[3,13,14,8],startupmodedur:8,here:[14,4,6,7,8],studio:3,achannel:14,interpret:[14,8],anymor:[3,5,14,8],credit:8,synchronis:[3,1],coredx:[14,8],avenu:2,unix:[3,14,12],gateshead:2,"0x80000000":14,total:[14,13,1,8],middlewar:[3,14,11,1,9],highli:[11,3,6,7,8,14],describ:[1,11,3,4,6,7,8,9,14],would:[14,8,1,6],leaki:[14,8],call:[1,11,3,7,8,14],tradecent:2,recommend:[3,14,1,8],until:[14,13,1,8],ccpp:3,os_heap:7,relax:8,relat:[1,11,3,4,6,8,14],warn:[14,8],exce:14,compatbl:14,loss:[14,1,8],keep_al:8,hold:[3,14,1,7,8],overrul:[13,14],must:[1,3,7,8,13,14],join:[3,14,1,8],restor:[1,14],elegantli:[3,5,14],work:[1,3,6,8,13,14],spec:14,conceptu:13,wors:8,introduc:[12,14,4,1,8],root:[3,14,8],overrid:[3,14,6,8],give:[1,11,4,8,12,13,14],dbmsconnectservic:6,indic:[14,1,8],caution:[14,12],unavail:[3,14],want:[3,6,14],manysocketsmod:8,attract:8,plist:14,end:[1,11,3,4,8,14],hoc:1,thing:[1,8],partitionexpress:14,how:[0,14,1,8],confin:14,answer:[14,1,6],verifi:[14,6,8],negoti:1,config:[3,13,14,7,8],updat:[1,11,3,6,8,13,14],lan:7,sedp:8,x509:14,earlier:[11,14,8],diagram:[3,8],befor:[1,11,3,4,8,14],ff02:[14,8],lax:[14,8],parallel:8,attempt:[14,7,8],by_reception_:3,overtaken:11,bootstrap:13,exclud:[6,8],recompil:3,maintain:[1,3,9,8,6,14],environ:[0,14,1,8],incorpor:[14,8],enter:[3,14,8],exclus:14,worst:[1,7,14],order:[1,11,3,4,6,7,8,13,14],origin:[3,14,7,8],composit:6,over:[1,11,3,8,13,14],fall:[6,14],orang:13,becaus:[1,11,3,6,8,13,14],addit:[14,8,13,1,6],privileg:14,keyboard:[3,13],flexibl:14,vari:3,smallint:6,distibut:14,fit:[11,13,8],unforeseen:14,fix:[3,14,8],better:[1,14],persist:[6,8],easier:8,them:[3,14,13,1,8],thei:[3,14,11,1,8],proce:8,safe:[3,14,8],overestim:14,bang:8,topicnam:6,maxsamples:8,interrupt:3,destlen:7,choic:[3,14,1,8],odbc:6,arrow:6,each:[1,11,3,9,7,8,6,13,14],debug:[13,14],mean:[1,11,3,4,6,8,10,12,14],worstcas:13,resum:[3,14],overflow:14,locking_mod:14,collector:[14,8],unbound:[6,8],newli:[1,14],smp:14,content:[6,8],rewrit:14,adapt:[3,14],forth:8,barrier:6,ntp:3,situat:[1,11,3,6,8,14],infin:14,free:[14,1,7,8],ineffici:14,egabyt:14,md5:14,dds_time:0,reconfigur:[14,8],sigkil:3,workaround:14,filter:6,renew:[14,8],isn:3,onto:[6,7,14],"3gl":6,rang:[1,8],"__built_in_partition__":14,render:8,"10k":14,wast:8,rank:8,system:[0,1,3,4,5,6,7,8,12,14],restrict:[13,14,8],instruct:[1,3,8,12,13,14],alreadi:[1,3,6,8,13,14],messag:[0,14,7,8],agre:1,primari:[14,6,8],top:[13,14,7],sometim:[4,1,14],downsid:[14,8],wal_autocheckpoint:14,too:[3,14,11,6,8],similarli:[13,8],power5:14,outag:14,listen:8,defragment:8,namespac:[8,1,6],tool:[0,3,6,8,12,14],compressor:[0,14],task:[3,1,14],somewhat:[14,8],wchar:6,technic:[14,8],symptom:14,target:[14,6,8],keyword:[14,8],provid:[6,8],older:[3,1,14],tree:13,zero:[0,14,7,3],project:[3,14],matter:[14,8],transient_loc:[1,14],provis:1,close:[3,14,8],ran:14,modern:[3,14],mind:13,spectrum:6,parenthes:8,unicast:[14,8],manner:[3,14],increment:8,os_fre:7,seen:[3,4,14],seem:[3,14,8],incompat:[3,14,1,8],minu:14,strength:[14,8],latter:[14,8],especi:[14,11,13,1,8],currenli:14,transmit:6,simplifi:7,though:[14,1,8],usernam:6,object:[0,14],regular:[4,13,1],letter:8,phase:[1,14],acknack:[14,8],jean:2,prematur:3,tradit:6,broadcast:[4,1,14],simplic:3,paradigm:6,don:[3,1,14],maimum:14,alarm:3,flow:[4,14,8],dog:1,doe:[1,3,6,7,8,13,14],declar:14,wildcard:6,unchang:[1,14],notion:[3,14,8],dot:14,rediscoveri:14,sigsegv:3,abl:[1,3,5,6,8,14],probe:8,syntax:[3,14],directli:[3,4,6,8,13,14],subtli:8,identifi:[1,11,3,6,8,12,14],involv:[3,14,1,8],absolut:8,layout:14,acquir:14,menu:13,explain:[1,3,9,8,12,14],nw_compplugin:7,busi:[1,2],likewis:13,stop:[0,1,14],compli:8,reconstruct:8,symmetr:[6,8],multicastrecvnetworkinterfaceaddress:8,bat:3,bar:13,"public":[4,14,8],twice:14,bad:8,respond:[14,1,8],mysql:6,hasn:8,datatyp:13,mandatori:14,result:[1,11,3,7,8,14],respons:[0,1,5,6,7,8,14],fail:[14,8,1,7,6],aes192:14,optimum:9,best:[14,4,1,8],subject:[8,14,2],awar:[14,8,1,6],heterogen:6,databas:[5,6],wait_for_acknowledg:14,sigint:3,outstand:1,awai:8,approach:[14,1,8],attribut:[1,3,9,7,8,6,12,13,14],inabl:[14,8],accord:[3,13,14,8],omg:[14,8],extend:[4,14,8],durabilitypartit:14,extens:[3,14,8],lazi:[1,14],dbmstodd:6,extent:[3,14,8],toler:[3,14,1,8],advertis:[4,14,8],tcpip:14,protect:14,accident:8,fault:[3,14,8,1,6],howev:[1,3,6,7,8,14],initialdiscoveryperiod:1,against:[14,1,8],logic:[1,14],uni:14,com:[3,14,2],ld_library_path:14,serversid:14,pre:[3,13,14,8],assur:14,can:[1,11,3,4,5,6,7,8,9,13,14],ospltun:[3,13],guid:8,assum:[3,14,8],duplic:[1,14],liabil:2,strong:1,union:6,three:[14,8],been:[1,3,5,6,8,13,14],advert:14,accumul:14,trigger:[14,8,1,6],interest:[14,8,13,1,6],basic:[3,14,13,1,6],ddsi2eservic:8,quickli:12,suppress:[14,8],anywher:[13,14],lift:6,pf_memsiz:14,"catch":[3,14,8],deserialis:8,emploi:4,ident:[13,6,8],launcher:14,shrink:14,properti:[3,14,1,8],commerci:[3,14],builtintop:8,calcul:[14,1,8],occas:8,aid:8,spawn:14,rediscov:14,player:11,vendor:8,smoothest:14,whclow:8,sever:[11,3,9,8,13,14],recover:[13,14],perform:[1,3,6,7,8,14],suggest:8,make:[3,14,8,1,6],transpar:[6,14],preserv:14,complex:[8,1,6],split:[14,1,8],complet:[3,14,12,1,8],evid:8,nic:14,hang:3,hand:[11,1,8],rais:13,kib:14,tune:[3,14,12,9,11],kept:[3,1,14],undesir:[3,8],thu:[14,6,8],inherit:[6,14],"0x100000":14,shortli:8,thi:[1,2,3,4,5,6,7,8,11,10,12,13,14],everyth:[14,8],woburn:2,left:[13,14,8],"1hr":14,queuesiz:8,protocol:[1,11,3,8,10,13,14],just:[14,8,1,6],sigusr1:3,domainparticip:14,bandwidth:[14,1,8],human:[1,14],participantmessagedata:14,yet:[3,14,8,1,6],languag:[3,13,12],previous:14,easi:[3,14,6,9],defrag:[14,8],had:14,els:[3,7,8],save:[13,1,14],transit:[14,1,8],opt:[3,8],applic:[5,6,8],fortun:8,ospl_hom:[3,14],supervisori:1,intercom:8,mylocaltop:4,ospltest:13,background:[0,14,8],rnr:[3,14],shadow:14,linux:[3,14,7,12],measur:[3,13,1,14],daemon:1,specif:6,arbitrari:14,contradict:1,manual:[3,11,13,8],keyhash:14,tcp_nodelai:14,specifii:14,unnecessari:1,underli:[14,6,8],www:[14,2],right:[1,2,3,6,8,13,14],old:[3,14,8],deal:14,interv:8,deaf:14,maxim:[5,1,14],dead:14,intern:[1,8],ospl_comp_lzf_init:[14,7],responsivenesstimeout:8,indirect:8,successfulli:[3,13,14,8],"0x40000000":14,transmiss:[14,8],os_int32:14,cooper:14,bottom:[13,14],service_cleanup_delai:14,datawrit:[14,13,1,6],buffer:[14,7,8],unit:[13,14,8],overcom:6,condit:[14,11,1,8],core:3,plu:14,uncompress:[14,7],systemhalt:14,chapter:[3,13],slightli:[14,8],unfortun:8,hearbeat:14,commit:14,y2038:3,marshal:8,unequivoc:14,match:6,"0xa00000":14,"float":[3,6,14],encod:[14,8],bound:[14,1,6],down:[3,14,1,11],stall:8,storag:[1,6],eth0:14,durabilitysubscrib:14,accordingli:14,jdbc:6,suffici:[3,14],nodal:[3,14],support:[0,1,5,6,8,14],why:[1,8],avail:[0,1,2,5,6,8,14],reli:[3,14,4,1,8],editor:0,fraction:14,overhead:[14,1,8],constantli:1,lowest:[14,8],medium:0,form:[3,14,1,8],offer:14,forc:[1,8],qwave:14,ospl_comp_snappy_init:[14,7],renam:14,"true":[1,3,4,6,8,14],flavour:1,maximum:6,mtu:14,dcpscj_y2038_readi:3,emit:14,flatten:6,linux2:14,featur:6,semicolon:14,ospl_logappend:3,conservativebuiltinreaderstartup:8,proven:8,diagnost:0,exist:[1,3,4,5,6,7,8,14],defragunreliablemaxsampl:8,trip:14,assembl:[0,14],inde:8,ospl_comp_zlib_exit:7,when:[1,11,3,4,5,6,7,8,13,14],aes128:14,ospl_errorfil:3,role:6,test:8,syndrom:[1,14],unlimit:14,realiti:8,node:[0,1,3,6,7,8,14],notif:8,intend:[0,8,14,3],benefici:[1,8],intens:8,intent:[3,11,8],consid:[14,1,8],sql:[6,14],forcibl:3,defragreliablemaxsampl:8,faster:[3,14],furthermor:[3,1,8],packets:14,version_number_goes_her:3,ignor:[1,11,3,6,8,14],time:6,push:[14,8],backward:[3,14],radmin:[14,8],chain:[13,8],skip:14,consum:[13,8],signific:[14,12,1,8],inaddr_ani:14,row:6,hierarch:[13,1],decid:[14,11,1,8],retransmitmergingperiod:8,decim:14,readabl:14,rmipp:13,decis:8,downtim:[1,14],sourc:[1,3,6,7,8,14],string:[14,6,8],realibl:14,feasibl:14,word:[1,14],exact:[1,3,5,7,8,10,14],hour:3,administr:[3,11,5,14,8],level:[0,14,1,8],did:8,gui:13,iter:[13,14],item:[14,12,13,6,8],maxint:14,dcpsccpp:3,quick:[14,11],primaryreordermaxsampl:8,round:14,prevent:[6,8],nwbridg:[4,14],compens:14,sign:14,cost:[14,1,8],idlpp:13,port:6,corba:0,appear:[14,8],"64bit":3,unsort:14,current:[1,11,3,5,6,8,13,14],outliv:[1,14],ampersand:14,era:3,portnumb:14,deriv:[14,8],honour:8,water:14,explicitli:[3,14,13,6,8],modif:[13,6,14],splice:[3,14,13,1,8],along:14,wait:[3,14,13,1,8],invis:8,not_alive_dispos:[1,14],tolerantli:6,checksum:14,queue:[11,4,14,8],throughput:[14,7,11],behav:[3,14,8],overriden:14,extrem:[3,14,8],reclaim:[14,8],orient:6,semant:[3,1],regardless:[3,14,8],userclockservic:3,extra:[11,14,8],tweak:[1,8],modul:[3,6,14],prefer:[13,14,8],peer:8,"1st":3,instal:[0,14],dispers:6,prove:1,univers:1,percept:1,suppressspdpmulticast:8,criteria:13,scope:[6,8],tightli:[3,11],plug:[14,7,8],maxfn:7,minim:[3,11,14,8],afford:14,claus:14,finit:14,refrain:14,"00x40000000":14,visual:3,accept:[3,13,14,7,8],examin:13,effort:[14,7,8],fly:[3,14],local:6,prepar:14,cap:8,uniqu:[3,14,8,1,6],imper:14,whatev:[14,1,8],"0x800000":14,purpos:[5,8],claim:8,underestim:14,opensplice_tuner_usermanu:13,predict:[14,11],gallium:8,srcsize:7,clockget:14,topic:6,heard:8,critic:[14,6,8],application1:14,disadvantag:8,auxiliarybandwidthlimit:8,occur:[3,14,13,1,8],maxmessages:8,alwai:[3,14,11,1,8],differenti:[14,1,8],multipl:6,unsign:[3,6,7,14],ping:14,write:[0,14,6,8],till:14,anyon:[12,8],pure:[6,8],product:[14,12],sp2:14,mac:14,mai:[1,2,3,6,7,8,13,14],data:6,grow:[3,1,8],"0x10000":14,ssm:14,practic:[14,8],conscious:11,divid:[14,8,1,6],explicit:[14,13,6,8],produc:[13,14,7,8],transport_priorr:14,inform:[6,2],"switch":[0,14],preced:[14,8],talk:6,tty:3,anticip:[1,14],brain:[1,14],ttl:14,still:[3,14,13,1,8],pointer:[14,7],"0ng":2,conjunct:[14,8],disconnect:[14,11,1,8],monitor:[0,14,1,8],platform:[0,14,7],window:[3,12,14,7,8],mail:2,main:[3,14,8],recoveri:[3,14,11],non:[1,3,4,6,8,12,13,14],halt:14,contriv:14,supersed:8,initi:[8,1,6],orsai:2,multicastrecvinterfaceaddress:8,cs_dll_version:3,therebi:14,now:[1,3,6,7,8,13,14],discuss:3,nor:[14,1,8],term:[3,14,8],name:[6,8],perspect:[3,14],drop:[14,8],revert:14,separ:[1,5,6,8,13,14],januari:3,compil:13,domain:6,replai:[3,9,14],replac:[3,14,1,8],individu:[3,13,14,7,8],receipt:[14,8],continu:[3,14,1,8],ensur:[3,14,1,8],significantli:8,year:[0,14],recogn:[14,7],happen:[14,1,8],dispos:[14,8,1,6],subnet:14,shown:[12,4,6,8],replication_us:6,profil:[3,14,8],internet:14,correct:[3,14,11,1,8],appendtofil:8,sample_count:13,state:[3,14,1,7,8],migrat:0,contain:[11,3,2,6,7,8,12,13,14],argv:14,theori:1,org:[3,14],"byte":[13,14,8],argc:14,card:14,care:[3,14],reusabl:13,wai:[1,3,6,7,8,13,14],prescrib:1,frequenc:14,synchron:8,modest:14,refus:14,recov:[1,14],turn:[3,14,13,1,8],place:[3,14,8,1,6],standbi:3,principl:[1,8],imposs:[3,14,8],frequent:1,first:[1,11,3,8,13,14],oper:[5,1,8],prioritis:8,suspend:[3,14],redhat:7,durabilityqospolici:1,carri:14,onc:[1,3,5,8,13,14],arrai:6,fast:[4,14,8],srclen:7,open:[3,13,14],predefin:14,given:[1,5,9,7,8,6,12,14],sigquit:3,convent:0,teardown:8,necessarili:[14,8],sigpip:3,tell:14,waitset:14,conveni:[3,14,7],gib:14,cope:3,copi:[3,14,8],specifi:[1,3,6,8,13,14],blacklist:14,pragma:14,than:[1,11,3,7,8,14],serv:[14,7,8],wide:[3,14,1,8],third:[14,13,6,8],ospl_verbos:3,networkqueues:8,posix:3,balanc:[14,1,8],were:[3,14,1,8],posit:14,mmstat:[0,3],dsstodbm:14,enabledcategori:14,analysi:[14,1,6],sai:14,diffserv:14,ani:[1,11,3,6,7,8,10,13,14],dash:6,deliv:[3,14,8,1,6],deliveryqueuemaxsampl:8,processnam:14,techniqu:8,destroi:[3,5,14],moreov:14,note:[1,11,3,9,7,8,13,14],altogeth:8,ideal:[14,8],take:[1,3,4,7,8,14],advis:[14,8],noth:[3,11,13,14,8],oopensplic:8,begin:8,sure:[1,14],normal:[14,13,1,8],multipli:14,snetwork:14,fragent:14,pair:[14,6,8],icon:12,synonym:14,later:[1,14],drive:[14,1,8],disableusertosset:14,replication_mod:6,runtim:[3,14],gracefulli:[3,13],heap:[3,5,14],show:[3,9,13,6,8],serialis:[14,8],unprocess:14,concurr:14,threshold:8,xml:[3,14,13,1,9],onli:[1,11,3,4,5,6,7,8,12,13,14],slow:[11,14,8],compdsiz:7,activ:[1,11,3,6,8,14],behind:[14,8],black:[4,14],analyz:14,dword:14,analys:[1,8],sourcewar:3,sighup:3,nearli:[14,8],variou:[3,14,13,1,8],get:[1,3,8,12,13,14],secondari:[14,8],"2mb":14,cannot:[3,14,13,1,8],requir:[1,11,3,9,7,8,6,12,13,14],truli:8,dramat:[14,8],where:[1,11,3,6,8,12,14],wiki:3,kernel:[3,4,14,8],n10:13,reconnect:1,burst:[14,8],transmitt:14,deadlin:3,rmi:13,concern:[11,14,8],infinit:[14,8],intim:8,detect:[14,11,1,8],enumer:[14,6,8],label:14,enough:[14,7,8],volatil:[14,1,8],between:6,"import":[3,14,11,1,8],across:[3,4,14,8],aggressivekeeplast1whc:8,assumpt:8,parent:14,screen:13,cycl:14,sparc:14,rare:[14,8],uncondition:8,come:[3,14,11,1,8],reaction:11,opensplice_testeruserguid:13,region:3,contract:3,audienc:0,inconsist:[3,1,14],improv:[14,1,8],among:14,undocu:14,"0x200000":14,color:13,period:[14,11,1,8],runawai:14,exploit:[3,6],colon:14,constant:[14,8],poll:14,ultim:[14,8],"00x20000000":14,coupl:[3,13],rebuild:3,hardli:8,besteffort:4,mark:[14,13,1,8],"__use_time_bits64":3,bypass:14,thousand:14,wake:[14,11],"1mb":14,those:[14,13,1,8],blowfish:14,interoper:6,pedant:[14,8],cast:[1,14],invok:[3,5,14],outcom:1,margin:14,advantag:[3,1,8],ctrl:[3,13],henc:[14,8],ddsi2servic:8,typesupport:13,destin:[3,14,7,8],cluster:[3,14],time_t:3,subscrib:[8,1,6],develop:[3,1,14],author:14,ospl_projgen:3,same:[1,11,3,6,7,8,14],check:[14,11,13,1,8],binari:6,epoch:3,html:14,lite:[3,14],document:[3,14,12,1,2],mbyte:14,nest:14,confidenti:14,gacutil:3,decompress:14,driven:[3,1,14],capabl:[3,14,11,1,8],ospl_comp_zlib_uncompress:7,mani:[1,11,3,8,13,14],extern:[13,14],postpon:[1,14],tradition:6,retransmiss:[14,8],appropri:[3,13,14],choos:[14,8],compfn:7,without:[1,11,2,5,8,13,14],model:[3,14,13,6,8],roughli:8,dcpscj:3,execut:[3,14,11],excel:[3,14,8],rest:[3,14,11],kill:[3,14],aspect:[14,11,1,8],speed:[14,7,11],death:14,struct:[3,6,14],hint:12,except:[3,11,13,14,8],littl:14,identif:[6,7],priori:14,treatment:8,versa:[3,14,4,6,8],disrupt:[8,1,6],earli:[14,7,8],around:[14,13,1,7,8],max_open_fil:14,read:[3,14,12,1,8],categoris:[14,8],world:[8,1,6],topicexpress:14,realtim:14,integ:[14,6,7,8],server:6,benefit:[3,14,8],"0x20000000":14,either:[1,3,5,8,13,14],cascad:[6,14],output:[3,14,1,8],inter:[3,14],rollov:3,manag:[0,14,5,1,8],fulfil:[1,5,6,7,10,14],cabl:[14,8],ospl_comp_zlib_compress:7,unrecover:13,loopback:[14,8],keystor:14,definit:[1,3,6,7,8,14],achiev:[3,14,1,6],legal:14,evolv:14,exit:[3,13,7],corespond:14,apostroph:14,complic:8,refer:[0,1,3,7,8,12,14],os_tim:14,timeout:[14,8],power:[3,14],garbag:[14,8],inspect:[1,14],broken:3,topicqo:14,found:[3,13,14,8],"throw":8,comparison:[0,1],ack:14,stand:14,ospl:[0,14,8],act:[1,14],backup:14,processor:13,effici:[3,14,11,1,6],liveli:[14,11,1,8],opensplic:[6,2],terminolog:8,unregist:[14,8],processorarchitectur:3,your:[3,13,1,14],per:[1,11,3,6,8,13,14],complianc:[14,8],area:[3,14,8],aren:3,nackdelai:8,overwrit:[3,14],start:6,compliant:[14,6,8],interfac:6,maxqueuedrexmitmessag:8,lot:[1,8],ipv6:8,strictli:[14,8],hard:[14,1,8],ospl_logpath:3,conclud:[3,1,14],regard:[3,14],amongst:[14,1,8],categor:13,longer:[14,11,1,8],notat:[3,14],possibl:[1,11,3,6,7,8,13,14],"default":[8,1,6],bucket:[14,8],unusu:[14,8],embed:[14,6,7,8],deadlock:14,expect:[3,14,8,1,6],gone:8,loadabl:14,creat:[1,3,5,6,8,14],certain:[14,8],fellow:1,strongli:[3,14,1,8],catchup:[1,14],decreas:[13,14],file:[0,1,4,7,8,14],cultur:3,intra:[3,14,8],fill:[14,1,7,8],incorrect:[14,8],again:[14,1,8],googl:14,discrimin:6,tinyint:6,prepend:14,field:[3,13,14],valid:[1,3,7,8,13,14],rdbm:6,hibern:3,you:[3,14,13,1,8],intermedi:13,sequenc:[14,8,1,6],symbol:[3,14],signficantli:14,briefli:3,track:[3,11,14,8],equalitycheck:1,z_ok:7,pool:14,reduc:[14,1,8],assert:[14,8],globalprofil:14,directori:[3,14],descript:[5,1,8],pseudo:14,mimic:14,potenti:[3,14,1,8],escap:14,degrad:14,cpu:[14,11,1,7,8],by_source_:3,represent:[3,13,14,8],all:[1,2,3,4,5,6,7,8,9,11,12,13,14],forget:14,ospl_temp:3,illustr:[1,7],forbidden:14,opensplice_rmi_gettingstart:13,standardis:[14,8],improperli:14,disc:14,abil:[14,1,8],follow:[1,3,4,9,8,6,12,13,14],disk:[3,1,14],children:14,garbagag:14,dsn:6,reportinterv:14,white:[4,13],init:[14,7],program:[3,14],os_int64:14,neglig:8,thursdai:3,global:[0,14,1,8],straightforward:8,fals:[14,4,8,1,6],unacknowledg:[14,8],util:[3,6],durabiltii:14,mechan:8,failur:[3,14,8],veri:[3,14,13,1,8],delayedalign:1,enablecategori:8,list:[3,4,6,7,8,13,14],helloworld:14,adjust:[3,14],stderr:[3,14],small:[11,13,14,8],joiner:[1,14],dimens:14,enterpris:[3,14,6,7,12],tel:2,ten:[13,14],sync:1,journal_mod:14,rate:[14,8],pressur:14,design:[3,11,14,8],pass:[3,13,14,7],further:[3,14],opensplicedd:14,tev:[14,8],what:[1,3,4,6,8,14],sub:[13,8],cleartext:8,clock:[3,14],section:[1,11,3,4,5,9,7,8,10,12,13,14],ffff:[14,8],hde:3,delet:[3,14,8,1,6],version:[3,13,14,7,8],intersect:1,consecut:14,method:[3,14,7],millisecond:[13,14],prismtech:[3,12,2],full:[1,11,3,4,9,8,12,14],themselv:[14,1,11],solari:[14,7,12],excess:14,depend:[3,14,11,1,8],standard:[1,11,3,6,8,14],modifi:[13,6,14],valu:[11,3,7,8,13,14],search:[0,14],sender:14,verify_checksum:14,prior:[3,14],amount:[13,14,5,1,8],pick:[1,8],action:[3,1,14],magnitud:3,via:[1,11,3,6,8,14],api_info:14,primit:6,databandwidthlimit:8,paranoid_check:14,libhelloworld:14,deprec:14,famili:8,suddenli:1,establish:[14,8],opensplice_preprocessor_usermanu:13,select:[6,8],aggress:[14,8],hexadecim:14,clockstart:14,stdout:[3,14],regist:14,two:[1,11,3,6,7,8,14],taken:[3,12,13,14,8],asecurityprofil:14,toggl:14,more:[1,3,6,7,8,13,14],reachabl:[10,14,8],desir:[14,1,8],tester:[13,8],hundr:13,flag:[13,14],particular:[1,3,5,9,8,13,14],known:[3,14,13,1,8],cach:8,dictat:5,none:[14,1,8],valuabl:[13,1],hous:2,opensplicev6:14,remain:[3,14,13,1,8],hkey_local_machin:14,ficiti:14,learn:8,prompt:[3,13],scan:14,challeng:6,registr:14,share:6,templat:14,minimum:14,unreli:[14,8],phrase:14,replusr:6,huge:8,cours:[3,14,1,8],secur:8,rather:[3,14,8],anoth:[0,14,1,8],divis:8,reject:[14,8],simpl:[3,6,8],unabl:3,resourc:[1,3,6,7,8,13,14],referenc:[3,14],variant:8,reflect:11,associ:[3,14,1,8],sigttin:3,circumst:[13,14,8],"short":[3,4,6,7,8,14],networkchannel:11,postfix:14,confus:1,caus:[3,14,8,1,6],so_dontrout:14,help:[3,12,13,14,8],mission:6,trade:8,held:[3,14],through:[3,14,13,1,8],pane:13,hierarchi:8,paramet:[0,14,5,1,8],write_buffer_s:14,brows:13,late:[3,14,1,8],rapidli:13,reschedul:14,exchang:[14,8,1,6],requestcombineperiod:1,might:[14,11,13,1,8],finer:[14,8],good:[11,3,2,8,13,14],"return":[13,14,7],circularli:14,thereof:8,secondarili:8,thisisnotapartit:4,complain:8,bigger:13,publickeytoken:3,eventu:8,ospl_shmem_:3,unlik:[11,8],aligne:1,easili:[3,14,8],iff:14,reactiv:14,compris:[13,14],max_lat:8,fulli:[3,6,7,8,13,14],intervent:1,errata:14,truncat:[14,11],exitfn:7,monoton:3,idea:6,procedur:8,realli:8,connect:[6,8],beyond:[3,14],event:[13,14,8],timeli:8,safeti:14,publish:6,payload:[14,8],unsupport:14,health:14,msil:3,print:[13,14],occurr:14,advanc:[3,6],publish_initial_data:6,like:[1,3,6,8,13,14],reason:[3,14,13,1,8],base:[8,1,6],ask:[1,8],mmf:14,recv:[14,8],asm:14,basi:[14,1,8],prefac:0,omit:[3,14],perhap:8,perman:[1,14],heartbeat:[1,8],lifetim:14,assign:[1,14],major:[14,8],notifi:14,obviou:8,upper:14,nack:14,placehold:14,footprint:[3,13],smaller:[11,14,8],done:[1,3,5,8,13,14],least:[14,11,1,8],blank:[14,7],stabl:[13,14],miss:[14,8],differ:[0,1,11,3,4,6,7,8,14],networkservic:8,exponenti:1,"5th":2,networkingbridg:[0,14],construct:8,rbuf_siz:14,storm:8,illeg:[3,8],scheme:14,store:[3,14,8,1,6],adher:[14,8],option:[1,3,7,8,13,14],relationship:[8,1,6],park:2,ospl_sp_:3,uncompds:7,drain:[14,8],bidirect:8,consult:14,bridgedpartit:4,grace:[3,14],albeit:14,kind:[1,11,4,8,13,14],cyclic:[6,14],remot:[1,3,6,7,8,10,14],remov:[3,14,8],executbal:14,bridg:[3,4,6,7,8,14],block_siz:14,consumpt:14,toward:6,comput:[3,1,7,14],strengthen:1,archtirectur:3,iparam:7,acknacknumbitsemptyset:8,c_base:14,expir:[14,1,8],partitit:14,dedic:8,"null":14,spdpinterv:8,equival:14,self:[3,14,8],also:[1,11,3,4,5,7,8,13,14],labour:8,silent:14,useipv6:8,previou:[14,13,1,8],reach:[3,14,13,1,8],react:[3,5,14],most:[1,3,6,7,8,14],plai:[8,1,6],synchronousdeliveryprioritythreshold:8,clear:[14,8],cover:[14,6,8],part:[1,2,4,6,8,14],abnorm:[14,8],clean:[14,8],pars:[3,13],usual:[3,14,1,8],microsoft:[3,6],think:1,ospl_infofil:3,carefulli:14,transport_prior:8,session:14,particularli:[1,8],cdr:[14,8],uniform:3,fine:[14,8],find:[14,1,8],impact:[14,1,8],colloc:14,firewal:14,copyright:[3,2],solut:14,history_depth:8,queu:[14,8],factor:[14,11],hit:8,express:[3,14,4,1,6],resent:[14,11],nativ:[0,8],mainten:1,sill:14,restart:[3,1,14],resend:[11,14,8],whenev:[11,14,7,8],crc:14,common:[3,4,14,8],wrote:[14,8],certif:14,set:6,dump:[14,8],startup:[1,7,14],pstore:14,see:[3,14,9,1,8],osplconf:0,reserv:[3,14,2],analog:6,someth:14,sigttout:3,smallest:14,mutex:14,subscript:[3,4],experi:[3,11],altern:[3,14,7,8],signatur:14,syntact:1,numer:[3,14],induc:[11,14,8],sigil:3,rostand:2,succeed:[3,5,14],distinguish:[14,13,1,7,6],pcap:14,"4gl":6,popul:13,both:[1,3,4,6,7,8,14],last:[3,14,1,8],explicitlypublishqossettodefault:8,alon:14,tempor:1,custom_lib:3,context:[3,14,13,6,11],forgotten:14,pdf:13,whole:[14,1,2],load:[3,14,11,1,8],spdpmulticastaddress:8,simpli:[3,1,8],point:[3,14,4,1,8],instanti:14,schedul:[1,8],returncod:3,arbitrarili:8,header:[14,8],networkingbridgeexampl:4,dds_userclock_t:14,shutdown:[3,5,14,7],suppli:[3,14,8],throughout:[3,14,11,1,8],backend:14,chanenl:14,faithfulli:8,java:0,stamp:[0,1,14],loggin:14,devic:14,due:[14,11,1,8],empti:[14,1,8],sinc:[1,11,3,8,13,14],secret:14,strategi:14,box:[3,11],wish:[14,12],fire:[3,14],convert:14,unnecessarili:8,gap:14,secondaryreordermaxsampl:8,partli:[1,14],vortex:[1,14],demand:[11,1,7,6],gac:3,look:[3,14,13,1,8],contentfilteredtop:14,batch:[6,8],durat:[3,14,8],ramif:14,"while":[1,3,5,6,8,14],adh:14,behavior:[3,6,14],error:[1,3,7,8,13,14],anonym:8,loos:14,loop:[3,8],pack:[11,14,8],subsect:[3,14,13,1,8],real:[0,1,3,4,6,8,12,14],aix5:14,readi:[14,8],technolog:6,readm:3,itself:[1,3,5,6,8,13,14],satisfactori:[11,8],deamon:14,leveldb:14,grant:14,nanosec:3,belong:[14,1,8],nanosecond:14,shorter:14,sqlite3:14,conflict:[1,14],higher:[14,11,1,8],rel:[3,13,14,8],x86:[3,14],optim:[3,14,1,7,11],wherea:[3,14,1,8],moment:[14,1,11],temporari:[0,14,1,8],user:[1,3,5,6,8,13,14],robust:8,wstring:6,typic:[1,3,6,8,13,14],recent:[14,8],lower:[14,8],sha1:14,discourag:[1,14],ospl_sp_ddsi:14,spent:3,expens:[14,8],propos:3,"0x240000":14,salvo:14,paragraph:[3,8],shape:8,mergepolici:14,elect:[1,14],mandat:14,snappi:[14,7],unsecur:14,shortcut:13,input:[3,13],subsequ:[3,14,8],build:[3,14,1,7,8],bin:3,writerlingerdur:8,varchar:6,format:[3,14,7,8],big:[13,1,14],intuit:[6,8],insert:[3,6,14],bit:[3,14,8],characterist:[3,14],formal:[14,8],lost:[11,14,8],signal:0,resolv:[3,13,14],elaps:[3,8],manifest:8,collect:[14,11,13,1,8],cmsoap:14,encount:14,sketch:8,often:[14,1,8],urgenc:3,acknowledg:[11,8,14,2],visibl:[13,14,8],some:[1,3,4,6,7,8,13,14],back:[3,14,1,8],urgent:8,unspecifi:[7,8],sampl:6,mirror:[14,8],sizeof:7,surpris:8,distribut:[1,11,3,6,8,10,13,14],scale:[1,11,3,7,8,14],opensplice_tnodemonitorguid:13,glibc:3,shall:14,synchronousdeliverylatencybound:8,sigusr2:3,pem:14,retri:14,larg:[14,11,1,7,8],recognis:[14,8],fragments:8,reproduc:2,machin:[3,11,14,8],run:[1,11,3,6,8,13,14],my_top:14,rue:2,step:[3,1,7],meantim:8,from:[0,1,4,5,6,7,8,14],impos:[1,14],faith:2,constraint:[0,14],memori:[0,14,5,1,8],idl:[13,6,14],microsecond:8,"00x0":14,"1gb":14,reduct:[14,8],repair:14,primarili:[14,8],within:[1,11,3,5,6,7,8,14],addtion:14,uf_mems:14,"00xa0000000":14,chang:[0,1,2,6,8,14],announc:[3,5,1,14],durabl:8,occupi:14,inclus:14,coexistwithnativenetwork:8,fledg:14,question:[14,7],live:[1,14],"long":[1,11,3,6,7,8,13,14],custom:[3,6,14],includ:[1,8],suit:[11,4,2],forward:[1,11,3,4,6,7,8,13,14],properli:[3,14,4,6,8],dbmsddstopic:6,navig:14,pwd:6,atoi:7,link:[3,14,7,8],newer:1,atom:1,duli:8,line:[1,3,6,8,13,14],info:[3,14,8,1,2],utc:3,consist:[1,3,6,8,13,14],caller:14,dds_time_t:3,priveleg:14,builtinendpointset:8,highlight:14,similar:[3,14,13,1,8],hash:[14,1,8],dds_wait_for_historical_data:14,utilis:3,chan:14,doesn:[1,3,6,8,13,14],repres:[3,5,6,8,13,14],"char":[6,7,14],incomplet:[14,1,8],uncompfn:7,guarante:[1,8],cafe:3,spontan:14,sigtstop:3,sequenti:14,invalid:[3,14,8],application:14,articip:14,librari:8,nat:14,sigcont:3,maxqueuedrexmitbyt:8,exp:14,expirytim:8,mismatch:[3,1,14],param:7,adminqueu:14,algorithm:8,vice:[3,14,4,6,8],dataread:[3,13,1,14],infuenc:14,tradeoff:14,depth:[3,14,8],far:[13,14,8],fresh:[14,8],domaingain:8,pluggabl:[1,3,4,5,6,14],code:[3,13,14,7,8],destinationorderqospolici:3,edg:6,scratch:13,durabilitypublish:14,whchigh:8,privat:3,reinsert:1,sensit:13,reallocat:14,elsewher:8,send:[8,1,6],granular:14,outgo:[14,8],opposit:14,aris:[1,14],fatal:[14,8],sent:[1,11,3,6,7,8,13,14],passiv:1,random:[14,8],whichev:8,disclos:4,outputfil:8,"00x60000000":14,keep_last:[3,14,8],volum:[0,6,14],untouch:14,implicitli:[3,14,5,1,6],relev:[13,14,12],tri:14,fewer:8,"try":[3,14,8],create_particip:[3,5,14],maxsiz:7,freed:14,pleas:[3,14,1,7,8],malici:14,impli:[1,14],pretend:8,visualis:14,dds_type:6,natur:[3,6,8],"0x0":14,jump:0,video:14,odd:14,click:13,append:[6,8],compat:6,index:[14,6,8],compar:[3,1,14],resembl:8,access:[3,6,14],absoff:14,experiment:14,deduc:14,wireshark:14,penalti:[14,1,8],chose:3,despit:8,let:[14,6,8],ubuntu:12,becom:[3,14,8,1,6],accessor:13,great:14,convers:8,overwritten:8,conceiv:14,larger:[14,7,8],reus:14,nameless:14,chanc:[14,1,8],nearest:14,appli:[1,11,7,8,12,14],approxim:[14,8],xmit:[14,8],api:[3,14,1,7,8],apo:14,reallow:14,tailor:13,metaphor:14,usa:2,commun:6,doubl:[6,14],seamless:6,next:[3,14,1,7,8],implic:8,few:[3,11,8],doubt:8,usr:6,igabty:14,stage:8,remaind:8,sort:[13,14],impress:11,unplug:8,insensit:14,ospl_comp_zlib_init:[14,7],actual:[1,11,3,7,8,14],account:8,retriev:[14,1,8],scalabl:[3,14,1,7,8],cumbersom:14,tag:[14,8],obvious:[11,14,8],meet:[14,11,9,8],unread:14,ospl_comp_zlib_maxs:7,aliv:14,control:6,sqlite:14,malform:14,process:6,high:[0,14,6,7,8],unopen:14,tab:13,daemom:14,weaken:[1,14],delai:8,aes256:14,sit:8,soon:[14,1,11],"5b9310ab51310fa9":3,need:[1,11,3,4,9,8,6,12,13,14],infeas:8,instead:[1,3,7,8,13,14],ne11:2,overridden:[3,6,8],watch:[13,1],domainservic:14,networkinginterfaceaddress:14,redund:[14,8],philosophi:8,physic:[3,1,7,14],alloc:[3,5,14,13],essenti:[14,6,8],counter:[14,1,8],correspond:[14,11,13,1,8],element:[3,9,7,6,12,8,13,14],unaccept:13,allow:[8,1,6],elig:8,creation:[3,14,6,8],mute:14,ospl_uri:[0,14],move:[3,14],whilst:8,comma:[14,8],currentcontrolset:14,chosen:[3,14,8,1,6],criterion:[13,8],therefor:[1,11,3,7,8,13,14],recept:[3,8],crash:[3,14,1,11],greater:14,nullprofil:14,auto:[3,14,8],overal:[14,8],dai:14,"0x280000":14,dat:14,mention:[3,13,8],clockstop:14,facilit:[3,14,1,6],strive:8,somewher:1,anyth:[14,1,8],edit:[13,14,8],mode:6,truth:1,subset:[14,8],chunk:[13,11],meta:[0,14],"static":[0,14],sigalrm:3,special:[14,12,6,8],out:[1,11,3,6,8,13,14],variabl:[0,14],influenc:[3,14,11],rev:3,categori:8,typenam:13,suitabl:[3,14,11],disappear:[11,14,8],hardwar:14,red:13,franc:2,shut:[3,14,1,11],insid:[14,1,8],watermark:8,kilobyt:11,standalon:6,releas:[3,13,14,7,8],allowmulticast:8,likelihood:[1,8],afterward:14,promptli:8,dbmspartit:6,unwant:14,could:[3,14,1,11],put:6,timer:3,keep:[1,11,3,8,13,14],length:[14,6,8],organis:[0,8],outsid:[3,14,8],retain:[14,8],networkinterfaceaddress:8,softwar:14,finest:[14,1,8],suffix:14,durabilityservic:1,overshoot:8,qualiti:[14,11,8,1,6],nodemon:13,date:14,owner:[14,8],ilobyt:14,facil:[3,10,14,8],prioriti:[1,8],strict:[14,6,8],licens:8,perfectli:1,capac:14,wrapper:8,attach:[1,11,3,8,13,14],attack:14,termin:[1,3,5,8,13,14],"final":[5,1,8],low:[0,8,14,3],udp:[14,8],shell:3,defeault:14,rsa:14,accompani:13,enqueu:8,exactli:[14,8,1,6],prune:14,structur:[0,6,7,8],charact:[13,6,14],sens:14,histor:8,sec:3,stricter:[14,8],unencrypt:14,thereaft:3,clearli:8,corrupt:14,have:[1,11,3,4,6,8,13,14],tabl:[6,8],disjoint:1,optimis:[14,11],depict:8,squashparticip:8,diverg:1,rout:[14,8],mib:14,mix:[3,14,8],builtin:[4,14,8],demultiplex:8,dbmstopic:6,which:[0,1,4,5,6,7,8,14],standardsconform:8,soap:[3,13,14,10],singl:[0,1,5,6,7,8,14],unless:[14,7],whc:[14,8],mimick:14,who:[1,12],discov:8,useful:14,dcpssubscript:4,cipher:8,dbmstabl:6,deploi:[0,14,8],segment:[3,5,14,8],"class":[1,8],powerpc604:14,unmangl:8,gather:8,request:[14,5,1,8],uri:[3,13,14],face:8,pipe:3,durabilitykind:14,determin:[5,8],fact:[14,1,8],text:[13,14],verbos:[1,8],indispens:8,trivial:8,anywai:[14,1,8],textual:13,locat:[3,10,14,7,8],jar:3,should:[1,11,3,4,6,7,8,14],prolong:14,won:14,max_blocking_tim:8,"1abc":14,discontinu:3,meant:[14,8],ocur:7,reuasbl:13,autom:13,regularli:14,increas:[14,11,13,1,8],endless:8,os_malloc:7,enabl:[8,1,6],integr:[0,14,6,8],partit:6,compress2:7,tuner:[0,14],alignmentkind:14,view:[3,13,14,8],conform:6,legaci:6,z_default_compress:7,knowledg:[14,9,1,8],abort:3,elast:14,"0hz":14,stack:[14,8],closer:14,asynchron:[14,1,8],statu:[3,13,14,8],wire:[3,14,8],throttletreshold:14,correctli:[13,14,8],pattern:14,boundari:[6,14],unregistr:14,dll:[3,14],written:[1,3,7,8,13,14],dynam:[6,8],progress:[3,14,8],neither:[14,1,8],complement:6,kei:[6,8],sigchld:3,entir:[14,1,8],group:1,swift:11,thumb:14,defaultnamespac:[4,14],revers:6,plugin:[0,14],equal:6,etc:[3,14,13,1,8],instanc:[1,3,6,7,8,14],instert:14,sigterm:3,retransmitmerg:8,comment:14,threadnam:14,ignoredpartit:8,arriv:[11,14,8],solv:14,vxwork:[0,14],respect:[14,11,1,7,8],quit:[3,1,14],addition:1,trademark:2,insuffici:8,compon:[3,8],besid:[1,8],treat:[14,8],immedi:[14,11,1,8],partial:13,dcpspublic:4,presenc:[14,8],bulk:14,togeth:[3,14,8],dcpssacsassembl:3,present:[1,11,3,7,8,14],cmagent:14,multi:[3,1],align:6,defin:[3,14,8,1,6],wild:14,rightli:8,deliveri:[14,8],observ:[3,14,8],layer:8,domainid:8,fragement:14,bigint:6,incom:[14,1,8],revis:14,so_reuseaddr:14,reviv:14,parti:[3,14,1,6],satisfi:[13,14,11],cross:8,on_request:[1,14],member:[6,14],schizophren:14,largest:[14,7],wakeup:14,difficult:1,http:[3,14,2],hostnam:14,denot:3,upon:[3,14,6,8],effect:[0,14,8,1,6],logfil:14,decoupl:3,expand:14,ddstodbm:6,off:[14,1,8],well:[1,11,3,6,8,10,14],historyqospolici:3,thought:[3,14],exampl:[0,1,6,7,8,14],filesystem:14,undefin:[3,14],audio:14,latest:[14,1,8],sporad:[1,14],newest:1,less:[14,7,8],"boolean":[14,8,1,6],obtain:[1,8],defaultrol:14,timeshar:14,heavili:[14,1,8],simultan:[3,14,11,1,8],web:[3,14,2],y2038proofnessdesign:3,tight:14,priorit:14,script:[3,13],add:[13,14,8],cleanup:[3,14],lzf:[14,7],participantgain:8,smart:3,simul:[8,1,6],dest:7,arguabl:14,ridden:3,wait_for_historical_data:[1,14],realiz:[3,14],five:7,know:[1,14],press:13,realis:[4,1],password:14,participantindex:8,resid:[14,8],backbon:[13,6],success:[3,14],incred:8,"00x140000000":14,corpor:[3,2],"4mb":14,necessari:[3,14,1,7,8],lose:[11,14,8],page:[0,14],unreach:8,exceed:14,didn:14,vortexopensplic:3,specfi:14,interact:8,"export":14,flush:14,proper:[14,1,8],home:14,transport:[11,14,8],tmp:[3,14],win32:3,trust:14,leaf:14,lead:[14,8,1,6],leak:14,avoid:[14,1,8],octet:6,overlap:[3,1,14],leas:[1,8],estim:[13,14],leav:[14,1,7,8],ipv4:[14,8],fill_cach:14,noisi:14,host:[3,14,6,8],obei:6,although:[14,8],offset:3,strlen:7,sigabrt:3,after:[1,3,8,12,13,14],expiri:8,about:[0,1,3,6,8,14],readwrit:14,socket:[13,14,8],column:[13,6],datagram:[14,8],discard:14,certainti:[14,8],disabl:[14,9,8],own:[1,11,3,5,9,8,13,14],automat:[14,1,8],dataset:[1,14],assess:1,rectifi:8,mere:[14,7],leverag:[6,14],transfer:[3,8,1,6],much:[11,14,8],arg1:14,biggest:13,arg2:14,"function":[1,11,3,5,6,7,8,14],unexpect:14,advers:[3,14],sigstop:3,neutral:3,gain:[14,8],uninstal:0,eas:3,highest:[14,1,8],count:[13,14],succe:14,made:[8,13,14,2],wise:8,temp:3,whether:[3,14,13,1,8],shrunk:14,smooth:[14,8],displai:[13,14],troubl:14,straightawai:14,record:[3,14,9,8],below:[1,4,6,8,12,13,14],limit:[0,2,5,6,8,14],otherwis:[14,8],problem:[3,11,14,8],veneer:7,evalu:14,"int":[14,7],mask:14,dure:[3,14,11,1,8],pid:3,meaningless:14,replica:14,implement:[1,11,3,7,8,14],inf:14,ing:14,probabl:[14,8],tick:[13,14],quot:14,immateri:8,nonetheless:8,guidanc:8,boot:[3,14],detail:[1,3,12,5,9,7,8,10,13,14],virtual:[3,14,8],other:[5,6,8],lookup:8,futur:14,branch:1,varieti:[13,14,8],"100m":14,straddl:8,log:[3,14,8,1,6],stai:[14,8],amp:14,portion:[14,8],auxiliari:[14,8],understand:[6,8]},objtypes:{},objnames:{},filenames:["index","durability-service","contacts","overview","networkingbridge-service","domain-service","dbmsconnect-service","networking-service","ddsi2-networking-service","service-feature-list","tuner-service","referencesystems","preface","tools","guide"],titles:["The Vortex OpenSplice Deployment Guide","5. The Durability Service","14. Contacts & Notices","2. Overview","8. The NetworkingBridge Service","4. The Domain Service","10. The DbmsConnect Service","6. The Networking Service","7. The DDSI2 and DDSI2E Networking Services","3. Service Descriptions","9. The Tuner Service","13. Example Reference Systems","1. Preface","11. Tools","12. Configuration"],objects:{},titleterms:{concept:[8,1,6],queri:14,global:3,systemid:14,force_key_equ:14,whchigh:14,storemod:14,priorityinherit:14,content:14,retransmitmergingperiod:14,xmitlossi:14,allowreus:14,send:14,transport_prior:14,outputfil:14,assumemulticastcap:14,mechan:1,delayedalign:14,fragments:14,enablecategori:14,level:7,maxbursts:14,measurehbtoacklat:14,primaryreordermaxsampl:14,probelist:14,certificateverif:14,prevent:1,leasemanag:14,direct:8,jump:3,zero:11,trustedcertif:14,minimis:8,port:[14,8],append:14,mirrorremoteent:14,compat:[14,1,8],corba:3,compressionbuffers:14,endpointsinsystem:14,topolog:11,maxreliabbacklog:14,partitionaccess:14,update_frequ:14,userclockstop:14,packetretentionperiod:14,gener:[6,14],startupmodedur:14,behaviour:8,partition_express:14,address:[14,8],path:8,alignerschedul:14,failureact:14,serviceterminateperiod:14,standalon:8,cert:14,base:14,chang:3,configur:[11,3,4,6,7,8,13,14],whcadapt:14,databandwidthlimit:14,throttlethreshold:14,filenam:14,domainid:14,instal:3,select:1,monitorport:14,from:3,commun:8,retentionperiod:14,latenc:[11,8],usr:14,lock:14,scope:[1,14],type:[6,14],rnrservic:14,dds_time:3,notic:2,enhanc:8,verifycli:14,"transient":8,indic:0,legacyfragment:14,cach:[3,14],high:11,endpoint:8,linger:8,histori:8,latency_budget:14,purpos:1,control:8,rtnetwork:8,stream:8,process:[3,8],typedreport:14,share:[3,8],dbmsconnectservic:14,agent:14,topic:[14,8],ddsi2directmaxthread:14,aligneeschedul:14,manysocketsmod:14,auxiliarybandwidthlimit:14,resourcelimit:14,multipl:[3,8],secur:[14,7],enablemulticastloopback:14,threadpool:14,how:7,lifecycl:1,low:11,respondtortiinitzeroackwithinvalidheartbeat:14,map:[14,6,8],max:14,catalog:14,particip:8,data:[3,1,8],parallel:1,diffservfield:14,ssl:14,bind:14,credenti:14,exclud:14,issu:8,inform:[3,8],"switch":7,environ:3,block:8,allow:14,anoth:7,volum:11,ospl_uri:3,reconnect:14,deathdetectioncount:14,portnr:14,dynam:1,paramet:7,write:7,group:14,monitor:3,delai:1,polici:[1,14],logstacktrac:14,nodelai:14,rr_storageattrxml:14,platform:3,persist:[1,14],requestcombineperiod:14,leasedur:14,durablepolici:14,maxfiles:14,smpcount:14,fragment:8,timestamp:14,initi:14,maxparticip:14,globalpartit:14,maxsamples:14,minimumsocketsendbuffers:14,spdpmulticastaddress:14,priority_kind:14,align:[1,14],introduct:[13,8],maxsampl:14,name:[1,14],rediscoveryblacklistdur:14,odbc:14,aligne:14,maxautoparticipantindex:14,mode:[3,13,8],side:8,domain:[3,5,14,8],packetcapturefil:14,access_mod:14,meta:13,"static":11,connect:[1,14],year:3,twinoak:8,suppressdefaultlog:14,network:[3,14,7,8],space:1,externalnetworkaddress:14,publish:[14,8],replication_us:14,multicastdataoffset:14,durabl:[1,14],reader:8,file_nam:14,appendtofil:14,proxi:8,watermark:14,migrat:3,publish_initial_data:14,deafmut:14,y2038readi:14,defragbuffers:14,legacycompress:14,allowmulticast:14,assumertihaspmdendpoint:14,prefac:12,thread:[14,8],spdp:8,synchron:14,filter:14,enforc:14,organis:12,heartbeat:14,selfsignedcertif:14,networkinterfaceaddress:14,oper:[3,14],rang:14,networkingbridg:4,durabilityservic:14,independ:8,number:8,generatebuiltintop:14,preemptiveackdelai:14,messag:3,size:[11,14,8],prioriti:14,avail:7,differ:13,networkservic:14,convent:12,interact:[3,1],lateackmod:14,system:11,construct:14,master:1,unicastmetaoffset:14,squashparticip:14,"final":14,schema:14,namespac:14,tool:13,usemulticastifmreqn:14,compressor:7,snetworkservic:14,userentropi:14,warnat:14,provid:1,structur:3,networkqueues:14,reliabilityrecoveryperiod:14,externalnetworkmask:14,listen:14,crccheck:14,argument:14,acknacknumbitsemptyset:14,tabl:[0,14],deliveryqueuemaxsampl:14,accesscontrol:14,spdpinterv:14,built:[7,8],min:14,contact:2,exampl:[4,11],queuesiz:14,which:3,standardsconform:14,combin:8,event_table_polici:14,channel:[14,8],userclockqueri:14,useipv6:14,recoveryfactor:14,deploy:[12,0,8,3],object:13,compress:[14,7],discov:1,trigger_polici:14,networkingbridgeservic:14,deploi:3,"class":14,synchronousdeliveryprioritythreshold:14,topic_express:14,garbagecollector:14,destruct:14,unicastdataoffset:14,replication_mod:14,determin:1,partitiontop:14,dbm:6,mainloop:14,verbos:14,rti:8,shmmonitor:14,forwardremotedata:14,threshold:14,keyvaluestor:14,absolut:14,writer:8,minimumsocketreceivebuffers:14,suppressspdpmulticast:14,salvos:14,local:8,keystorefil:14,dcpspartitiontop:14,compressionthreshold:14,maxmessages:14,between:8,stop:3,nativ:7,report:[14,8],retryonrejectdur:14,securityprofil:14,multicastrecvnetworkinterfaceaddress:14,userclockstart:14,enabl:14,statist:[3,13,14],partit:[14,8],safetyfactor:14,tuner:[3,10],conform:8,set:[1,7,8],packet:8,heapsiz:14,osplconf:13,respons:11,dbmsconnect:6,threadmax:14,databas:14,defaultmulticastaddress:14,networkpartit:14,ddsi:8,discoveri:[11,14,8],plugininitfunct:14,localdiscoverypartit:14,clientdur:14,builtinendpointset:14,entiti:8,timetowaitforalign:14,maxinst:14,kei:14,transportprior:14,dbmstodd:14,mmstat:13,entitynam:14,maxsamplesperinst:14,tunerservic:14,advertisebuiltintopicwrit:14,plugin:7,initialdiscoveryperiod:14,equal:1,audienc:12,storesessiontim:14,defragunreliablemaxsampl:14,stacksiz:14,aggressivekeeplastwhc:14,dsn:14,ignoredpartit:14,overview:[3,8],maxwaitcount:14,symbol_nam:14,vxwork:3,acceleraterexmitblocks:14,guid:[0,12],java:3,rr_storageattrcdr:14,maxclient:14,stamp:3,smpoptim:14,storeoptimizeinterv:14,subscrib:14,ddsi2eservic:14,partitionmap:14,waitforattach:14,resolut:14,secondaryreordermaxsampl:14,inprocessexceptionhandl:14,"case":6,replic:6,interoper:8,servic:[1,3,4,5,6,7,8,9,10,13,14],zlib:7,histor:1,builtintop:14,dontrout:14,resendmanag:14,retryonrejectbesteffort:14,forwardallmessag:14,kernelmanag:14,ddsi2servic:14,whclow:14,multicastmetaoffset:14,receiv:[14,8],whchighinit:14,handl:8,singleprocess:14,multicast:8,startupmodecoverstransi:14,ddsi2e:8,spdpresponsemaxdelai:14,slave:1,effect:3,temporari:3,ddstodbm:14,scenario:6,entri:14,client:14,command:14,retransmitmerg:14,categori:14,explan:6,generatekeyhash:14,allowedport:14,storageparamet:14,obtain:14,tcp:14,pluginlibrari:14,versu:8,explicitlypublishqossettodefault:14,update_factor:14,schedul:14,participantgain:14,match:8,servicenam:14,real:11,applic:[3,1,14],writerlingerdur:14,maxretri:14,storesleeptim:14,maxthreadspercli:14,daemon:14,transmit:8,traffic:8,background:[3,4],participantindex:14,userclockmodul:14,deadlockdetect:14,specif:8,memorypools:14,signal:3,server:14,synchronousdeliverylatencybound:14,x509authent:14,unicastresponsetospdpmessag:14,manag:[3,13],backlog:[14,8],retransmit:8,interv:14,intern:14,sampl:8,authent:14,librari:[14,7],arrivalofdataassertsppandepliveli:14,throttlelimit:14,trace:[14,1,8],vortex:[0,3],accesscontrolmodul:14,leas:14,topicaccess:14,inject:1,generalwatchdog:14,entropyfil:14,refer:[13,11],receivebufferchunks:14,throttl:[14,8],cpuaffin:14,usag:[3,6],interfac:8,pluginparamet:14,peer:14,storedirectori:14,dcp:8,scheduletimeround:14,comparison:3,about:12,constraint:7,coexist:8,memori:[3,13],prioritizeretransmit:14,cipher:14,includ:14,ospl:[3,13],writetimeout:14,unrespons:8,timealign:14,reportplugin:14,opensplic:[0,1,3,8,13,14],publish_interv:14,watchdog:14,storag:14,controltop:14,merg:[14,1,8],coexistwithnativenetwork:14,support:3,nackdelai:14,receivebuffers:14,editor:13,start:[3,8],singl:[3,11],keypassphras:14,maxqueuedrexmitmessag:14,ipv6:14,head:8,medium:11,forc:14,pwd:14,translat:8,uninstal:3,readtimeout:14,reset:14,"default":14,memorymappedfilestor:14,maximum:8,limit:3,adminqueues:14,responsivenesstimeout:14,featur:8,conservativebuiltinreaderstartup:14,alignment_prior:14,diagnost:3,file:3,integr:3,assembl:3,encrypt:8,other:[1,7],role:[1,14],multicasttimetol:14,test:14,asymmetr:8,architectur:[3,8],node:11,variabl:3,maxqueuedrexmitbyt:14,intend:12,wildcard:8,leaseperiod:14,expirytim:14,ddsi2:8,userclock:14,feder:8,defragreliablemaxsampl:14,algorithm:14,localendpoint:14,reliabl:[14,8],cipherkei:14,descript:[9,14],rule:8,timetol:14,time:[3,11,8],equalitycheck:14,servicesonli:14,domaingain:14}}) \ No newline at end of file +Search.setIndex({envversion:42,terms:{entropi:15,"_time_bit":3,communict:15,child:[3,15],four:[14,1,7],secondli:8,prefix:[14,15],sleep:[15,1,8],nw_compressor:7,consider:[12,1,8],accur:3,"const":[15,7],emptiv:15,deviat:8,swap:15,under:[15,1,8],sigfp:3,worth:8,digit:[15,7],lack:[6,8],everi:[3,15,14,1,12],risk:8,"void":[15,7],voic:15,govern:[15,8],affect:[3,15,1,8],vast:15,disturb:15,unblock:1,taskmanag:3,verif:15,parenthes:8,initialis:[3,5,15,7],"10k":15,zlib:[0,15],"10m":[1,15],naiv:8,seper:15,budget:[15,12],consequ:[12,15,8],second:[3,15,14,1,8],releaseinfo:3,aggreg:15,even:[1,3,6,8,14,15],aim:8,hide:15,muex:15,neg:[14,15,8],asid:1,"new":[1,3,5,8,14,15],net:3,ever:8,topolog:[0,1,15],ongo:[15,8],elimin:[6,8],manipul:3,abov:[3,14,7,8],never:[3,15,14,1,8],startupmodedur:8,here:[15,4,6,7,8],studio:3,achannel:15,interpret:[15,8],anymor:[3,15,5,1,8],credit:8,synchronis:[3,1],coredx:[15,8],avenu:2,unix:[3,15,13],gateshead:2,total:[15,14,1,8],middlewar:[1,12,3,9,10,15],highli:[12,3,6,7,8,15],describ:[1,12,3,4,6,7,8,9,15],would:[15,8,1,6],leaki:[15,8],call:[1,12,3,7,8,15],tradecent:2,recommend:[3,15,1,8],until:[15,14,1,8],ccpp:3,os_heap:7,relax:8,relat:[1,12,3,4,6,8,15],warn:[15,8],exce:[10,15],compatbl:15,loss:[15,1,8],keep_al:8,hold:[3,15,1,7,8],overrul:[14,15],must:[1,3,7,8,14,15],join:[3,15,1,8],restor:[1,15],elegantli:[3,5,15],work:[1,3,6,8,14,15],spec:15,conceptu:14,wors:8,introduc:[13,15,4,1,8],root:[3,15,8],overrid:[15,3,10,6,8],give:[1,12,4,8,13,14,15],dbmsconnectservic:6,indic:[15,1,8],caution:[15,13],unavail:[3,15],want:[3,15,1,6],manysocketsmod:8,attract:8,plist:15,end:[1,12,3,4,8,15],hoc:1,thing:[1,8],partitionexpress:15,how:[0,15,1,8],confin:15,answer:[15,1,6],verifi:[15,8,1,6],negoti:1,config:[3,14,15,7,8],updat:[1,12,3,6,8,14,15],lan:7,sedp:8,x509:15,earlier:[15,10,12,1,8],diagram:[3,8],befor:[1,12,3,4,8,15],ff02:[15,8],lax:[15,8],parallel:8,attempt:[15,1,7,8],by_reception_:3,overtaken:12,bootstrap:14,exclud:[6,8],recompil:3,maintain:[1,3,9,8,10,6,15],environ:[0,15,1,8],incorpor:[15,8],enter:[3,15,8],exclus:15,worst:[1,7,15],order:[1,12,3,4,6,7,8,14,15],origin:[3,15,7,8],composit:6,over:[1,12,3,8,10,14,15],fall:[6,15],orang:14,becaus:[1,12,3,6,8,14,15],finest:[15,1,8],privileg:15,keyboard:[3,14],flexibl:15,vari:3,smallint:6,distibut:15,fit:[12,14,8],unforeseen:15,fix:[3,15,8],better:[1,15],persist:[6,8],easier:8,them:[3,15,14,1,8],thei:[3,15,12,1,8],proce:8,safe:[3,15,8],overestim:15,bang:8,topicnam:6,maxsamples:8,interrupt:3,destlen:7,choic:[3,15,1,8],odbc:6,arrow:6,each:[1,12,3,9,7,8,10,6,14,15],debug:[14,15],mean:[1,12,3,4,6,8,11,13,15],worstcas:14,resum:[3,15],overflow:15,locking_mod:15,collector:[15,8],rtem:15,unbound:[6,8],newli:[1,15],smp:15,content:[6,8],rewrit:15,adapt:[3,15],forth:8,barrier:6,ntp:3,situat:[1,12,3,6,8,15],infin:15,free:[15,1,7,8],ineffici:15,egabyt:15,md5:15,dds_time:0,reconfigur:[15,8],sigkil:3,workaround:15,ist:2,filter:6,renew:[15,8],isn:3,onto:[6,7,15],"3gl":6,rang:[1,8],render:8,wast:8,rank:8,system:[0,1,3,4,5,6,7,8,10,13,15],restrict:[14,15,8],unlik:[12,8],alreadi:[1,3,6,8,14,15],messag:[0,15,1,7,8],agre:1,primari:[15,6,8],top:[14,15,7],sometim:[4,1,15],downsid:[15,8],exponenti:1,wal_autocheckpoint:15,too:[12,3,6,8,10,15],similarli:[14,1,8],outag:15,listen:[1,8],defragment:8,namespac:[8,1,6],tool:[0,3,6,8,13,15],compressor:[0,15],task:[3,1,15],somewhat:[15,8],wchar:6,technic:[15,8],symptom:15,target:[15,6,8],keyword:[15,8],provid:[6,8],older:[3,1,15],tree:14,zero:[0,15,1,7,3],project:[3,15],matter:[15,8],transient_loc:[1,15],provis:1,close:[3,10,15,8],ran:15,modern:[3,15],mind:14,spectrum:6,"__built":15,unicast:[15,8],manner:[3,15],increment:8,os_fre:7,seen:[3,4,15],seem:[3,15,8],incompat:[3,15,1,8],minu:15,strength:[15,8],latter:[15,8],especi:[15,12,14,1,8],currenli:15,"0x100000":15,transmit:6,simplifi:7,though:[15,1,8],usernam:6,object:[0,15],regular:[4,14,1],letter:8,phase:[1,15],acknack:[15,8],jean:2,prematur:3,tradit:6,broadcast:[4,1,15],simplic:3,paradigm:6,don:[3,1,15],maimum:15,alarm:3,flow:[4,15,8],dog:1,doe:[1,3,6,7,8,14,15],declar:15,wildcard:6,unchang:[1,15],notion:[3,15,8],dot:15,rediscoveri:15,pragma:15,sigsegv:3,abl:[1,3,5,6,8,15],probe:8,syntax:[3,15],directli:[3,4,6,8,14,15],subtli:8,identifi:[1,12,3,6,8,13,15],involv:[3,15,1,8],absolut:8,layout:15,acquir:[1,15],menu:14,explain:[1,3,9,8,13,15],nw_compplugin:7,busi:1,likewis:14,stop:[0,1,15],compli:8,reconstruct:8,symmetr:[6,8],multicastrecvnetworkinterfaceaddress:8,bat:3,bar:14,"public":[4,15,8],bad:8,respond:[15,1,8],mysql:6,datatyp:14,mandatori:15,result:[1,12,3,7,8,15],respons:[0,1,5,6,7,8,15],fail:[15,8,1,7,6],aes192:15,optimum:9,best:[15,4,1,8],subject:[8,15,2],awar:[15,8,1,6],heterogen:6,databas:[5,6],wait_for_acknowledg:15,sigint:3,outstand:1,awai:8,approach:[15,1,8],attribut:[1,3,9,7,8,6,13,14,15],inabl:[15,8],accord:[3,14,15,8],omg:[15,8],extend:[4,15,8],durabilitypartit:15,extens:[3,15,8],lazi:[1,15],dbmstodd:6,extent:[3,15,8],toler:[3,15,1,8],advertis:[4,15,8],tcpip:15,protect:15,accident:8,fault:[3,15,8,1,6],howev:[1,3,6,7,8,15],initialdiscoveryperiod:1,against:[15,1,8],logic:[1,15],uni:15,com:[3,15,2],ld_library_path:15,serversid:15,pre:[3,14,15,8],assur:15,can:[1,12,3,4,5,6,7,8,9,10,14,15],ospltun:[3,14],guid:8,assum:[3,15,8],summar:1,duplic:[1,15],liabil:2,strong:1,union:6,three:[15,8],been:[1,3,5,6,8,14,15],advert:15,accumul:15,trigger:[15,8,1,6],interest:[15,8,14,1,6],basic:[3,15,14,1,6],ddsi2eservic:8,quickli:13,suppress:[15,8],anywher:[14,15],lift:6,pf_memsiz:15,"catch":[3,15,8],deserialis:8,emploi:4,ident:[14,6,8],launcher:15,shrink:15,properti:[3,15,1,8],commerci:[3,15],builtintop:8,calcul:[15,1,8],occas:8,aid:8,spawn:15,rediscov:15,player:12,vendor:8,smoothest:15,whclow:8,sever:[12,3,9,8,10,14,15],deliveryqueuemaxsampl:8,incorrectli:15,perform:[1,3,6,7,8,15],suggest:8,make:[3,15,8,1,6],transpar:[6,15],preserv:15,complex:[8,1,6],split:[15,1,8],complet:[3,15,13,1,8],evid:8,nic:15,hang:3,hand:[12,1,8],rais:14,kib:15,tune:[3,15,13,9,12],kept:[3,1,15],undesir:[3,8],thu:[15,6,8],persistentdatalistenerthread:1,inherit:[6,15],client:1,shortli:8,thi:[1,2,3,4,5,6,7,8,10,11,12,13,14,15],everyth:[10,15,8],woburn:2,left:[14,15,8],"1hr":15,queuesiz:8,protocol:[1,12,3,8,11,14,15],just:[15,8,1,6],sigusr1:3,domainparticip:15,bandwidth:[15,1,8],human:[1,15],participantmessagedata:15,yet:[3,15,8,1,6],languag:[3,14,13],previous:15,easi:[3,15,6,9],defrag:[15,8],had:[1,15],requestor:1,els:[3,7,8],save:[14,1,15],transit:[15,1,8],opt:[3,8],applic:[5,6,8],fortun:8,ospl_hom:[3,15],supervisori:[10,1],intercom:8,mylocaltop:4,ospltest:14,background:[0,15,8],rnr:[3,15],shadow:15,linux:[3,10,15,7,13],measur:[3,14,1,15],daemon:1,specif:6,arbitrari:[1,15],contradict:1,manual:[3,12,14,8],keyhash:15,tcp_nodelai:15,specifii:15,unnecessari:1,underli:[15,6,8],www:[15,2],right:[1,2,3,6,8,14,15],old:[3,15,8],deal:15,samplerequest:1,qxn:15,interv:[1,8],maxim:[5,1,15],dead:15,intern:[1,8],ospl_comp_lzf_init:[15,7],responsivenesstimeout:8,indirect:8,successfulli:[3,14,15,8],"0x40000000":15,transmiss:[15,8],os_int32:15,cooper:15,bottom:[14,15],service_cleanup_delai:15,datawrit:[15,14,1,6],buffer:[15,7,8],logrotatewin:10,unit:[14,15,8],overcom:6,condit:[15,12,1,8],core:3,uncompress:[15,7],systemhalt:15,chapter:[3,14],slightli:[15,8],unfortun:8,hearbeat:15,commit:15,y2038:3,marshal:8,unequivoc:15,match:6,"0xa00000":15,"float":[3,6,15],encod:[15,8],bound:[15,1,6],down:[3,15,1,12],stall:8,storag:[1,6],eth0:15,durabilitysubscrib:15,accordingli:15,jdbc:6,suffici:[3,15],overus:1,nodal:[3,15],support:[0,1,5,6,8,15],why:[1,8],avail:[0,1,2,5,6,8,10,15],reli:[3,15,4,1,8],gid:15,editor:0,fraction:15,overhead:[15,1,8],constantli:1,lowest:[15,8],medium:0,form:[3,15,1,8],offer:15,forc:[1,8],qwave:15,adlink:[3,13,2],ospl_comp_snappy_init:[15,7],renam:15,"true":[1,3,4,6,8,15],flavour:1,maximum:6,mtu:15,absenc:15,dcpscj_y2038_readi:3,emit:15,flatten:6,featur:6,semicolon:15,ospl_logappend:3,conservativebuiltinreaderstartup:8,proven:8,diagnost:0,exist:[1,3,4,5,6,7,8,15],defragunreliablemaxsampl:8,trip:15,assembl:[0,15],inde:8,ospl_comp_zlib_exit:7,when:[1,12,3,4,5,6,7,8,10,14,15],aes128:15,ospl_errorfil:3,role:6,test:8,conflictqueu:1,syndrom:[1,15],unlimit:15,realiti:8,node:[0,1,3,6,7,8,15],notif:8,intend:[0,8,15,3],benefici:[1,8],intens:8,intent:[3,12,8],consid:[15,1,8],sql:[6,15],forcibl:3,defragreliablemaxsampl:8,durabilitystaterequest:1,furthermor:[3,1,8],pseudo:15,version_number_goes_her:3,ignor:[1,12,3,6,8,15],time:6,push:[15,8],backward:[3,15],daili:10,radmin:[15,8],chain:[14,8],skip:15,consum:[14,8],signific:[15,13,1,8],inaddr_ani:15,row:6,millisecond:[14,15],decid:[15,12,1,8],retransmitmergingperiod:8,decim:15,readabl:15,rmipp:14,decis:8,downtim:[1,15],sourc:[1,3,6,7,8,15],string:[15,6,8],realibl:15,feasibl:15,word:[1,15],exact:[1,3,5,7,8,11,15],hour:3,administr:[1,12,3,5,8,10,15],level:[0,15,1,8],did:8,gui:14,iter:[14,15],item:[15,13,14,6,8],maxint:15,dcpsccpp:3,team:2,quick:[15,12],primaryreordermaxsampl:8,round:15,prevent:[6,8],nwbridg:[4,15],compens:15,sign:15,cost:[15,1,8],idlpp:14,port:6,corba:0,appear:[15,8],"64bit":3,unsort:15,current:[1,12,3,5,6,8,10,14,15],outliv:[1,15],ampersand:15,era:3,portnumb:15,deriv:[15,8],honour:8,water:15,explicitli:[3,15,14,6,8],modif:[14,6,15],splice:[3,15,14,1,8],along:15,namespacesrequest:1,wait:[3,15,14,1,8],invis:8,not_alive_dispos:[1,15],tolerantli:6,checksum:15,queue:[15,12,4,1,8],throughput:[15,7,12],behav:[3,15,8],overriden:15,extrem:[3,15,8],reclaim:[15,8],semant:[3,1],regardless:[3,15,8],userclockservic:3,extra:[12,15,8],tweak:[1,8],modul:[3,6,15],prefer:[14,15,8],peer:8,"1st":3,instal:[0,15],dispers:6,prove:1,univers:1,percept:1,suppressspdpmulticast:8,criteria:14,scope:[6,8],tightli:[3,12],plug:[15,7,8],maxfn:7,minim:[3,12,15,8],afford:15,claus:15,finit:15,refrain:[1,15],"00x40000000":15,visual:3,accept:[3,14,15,7,8],examin:14,effort:[15,7,8],fly:[3,15],local:6,prepar:15,cap:8,uniqu:[3,15,8,1,6],imper:15,descriptor:10,whatev:[15,1,8],"0x800000":15,purpos:[5,8],claim:8,underestim:15,opensplice_tuner_usermanu:14,predict:[15,12],gallium:8,srcsize:7,clockget:15,topic:6,heard:8,critic:[15,6,8],application1:15,disadvantag:8,auxiliarybandwidthlimit:8,occur:[3,15,14,1,8],maxmessages:8,alwai:[3,15,12,1,8],differenti:[15,1,8],multipl:6,unsign:[3,6,7,15],ping:15,write:[0,15,8,1,6],till:[1,15],criterion:[10,14,8],pure:[6,8],product:[15,13],sp2:15,mac:15,mai:[1,2,3,6,7,8,10,14,15],data:6,grow:[3,10,1,8],"0x10000":15,man:10,ssm:15,practic:[15,8],conscious:12,divid:[15,8,1,6],explicit:[15,14,6,8],produc:[10,14,15,7,8],transport_priorr:15,inform:[6,2],"switch":[0,15],preced:[15,1,8],talk:6,partition__:15,tty:3,config_fil:10,anticip:[1,15],brain:[1,15],ttl:15,still:[3,15,14,1,8],pointer:[15,7],dynam:[6,8],conjunct:[15,8],disconnect:[15,12,1,8],monitor:[0,15,1,8],platform:[0,15,7],window:[3,7,8,10,13,15],mail:[10,2],main:[3,15,1,8],recoveri:[3,15,1,12],non:[1,3,4,6,8,13,14,15],halt:15,garbagag:15,contriv:15,supersed:8,initi:[8,1,6],orsai:2,multicastrecvinterfaceaddress:8,cs_dll_version:3,therebi:15,now:[1,3,6,7,8,14,15],discuss:3,nor:[15,1,8],jump:0,term:[3,15,8],name:[6,8],perspect:[3,15],drop:[15,1,8],revert:15,separ:[1,5,6,8,14,15],januari:3,compil:14,domain:6,replai:[3,9,15],replac:[3,15,1,8],individu:[3,14,15,7,8],receipt:[15,8],continu:[3,15,1,8],ensur:[3,15,1,8],significantli:8,year:[0,15],recogn:[15,7],happen:[15,1,8],dispos:[15,8,1,6],subnet:15,shown:[13,4,6,8],"100k":10,replication_us:6,profil:[3,15,8],internet:15,correct:[3,15,12,1,8],appendtofil:8,sample_count:14,state:[3,15,1,7,8],migrat:0,contain:[1,2,3,12,6,7,8,13,14,15],historicaldatarequest:1,argv:15,theori:1,org:[3,15],"byte":[14,15,8],argc:15,card:15,care:[3,1,15],reusabl:14,wai:[1,3,6,7,8,14,15],prescrib:1,frequenc:15,synchron:8,modest:15,refus:15,recov:[1,15],turn:[3,15,14,1,8],place:[3,15,8,1,6],standbi:3,principl:[1,8],imposs:[3,15,8],frequent:1,first:[1,12,3,8,10,14,15],oper:[5,1,8],prioritis:8,suspend:[3,15],redhat:7,kernel:[3,4,15,8],carri:15,onc:[1,3,5,8,14,15],arrai:6,fast:[4,15,8],srclen:7,open:[3,14,15],predefin:15,given:[1,5,9,7,8,6,13,15],sigquit:3,convent:0,teardown:8,necessarili:[15,8],sigpip:3,tell:15,waitset:15,conveni:[3,15,7],gib:15,cope:3,copi:[3,10,15,8],specifi:[1,3,6,8,10,14,15],blacklist:15,mostli:1,than:[1,12,3,7,8,15],serv:[15,7,8],wide:[3,15,1,8],third:[15,14,6,8],ospl_verbos:3,networkqueues:8,posix:3,balanc:[15,1,8],were:[3,15,1,8],posit:15,deadlin:3,mmstat:[0,3],dsstodbm:15,seri:10,enabledcategori:15,analysi:[15,1,6],sai:[1,15],diffserv:15,ani:[1,12,3,6,7,8,10,11,14,15],dash:6,deliv:[3,15,8,1,6],recover:[14,15],processnam:15,techniqu:8,destroi:[3,5,15],moreov:15,note:[1,12,3,9,7,8,14,15],altogeth:8,ideal:[15,8],take:[1,3,4,7,8,15],advis:[10,15,8],noth:[3,12,14,15,8],begin:8,sure:[1,15],normal:[15,10,14,1,8],multipli:15,snetwork:15,fragent:15,pair:[15,6,8],icon:13,synonym:15,later:[10,1,15],drive:[15,1,8],disableusertosset:15,replication_mod:6,runtim:[3,15],gracefulli:[3,14],heap:[3,5,15],show:[3,9,14,6,8],serialis:[15,8],unprocess:15,concurr:15,threshold:8,help:[3,13,14,15,8],xml:[3,15,14,1,9],onli:[1,12,3,4,5,6,7,8,13,14,15],slow:[12,15,8],compdsiz:7,activ:[1,12,3,6,8,15],behind:[15,8],black:[4,15],analyz:15,dword:15,analys:[1,8],sourcewar:3,sighup:3,nearli:[15,8],variou:[3,15,14,1,8],get:[1,3,8,13,14,15],secondari:[15,8],"2mb":15,cannot:[3,15,14,1,8],requir:[1,12,3,9,7,8,10,6,13,14,15],truli:8,catagori:15,dramat:[15,8],where:[1,12,3,6,8,13,15],wiki:3,durabilityqospolici:1,n10:14,reconnect:1,burst:[15,8],lynxo:15,transmitt:15,asleep:1,rmi:14,concern:[12,15,8],infinit:[15,8],intim:8,detect:[15,12,1,8],enumer:[15,6,8],label:15,delete_historical_data:1,enough:[15,7,8],volatil:[15,1,8],between:6,"import":[3,15,12,1,8],across:[3,4,15,8],aggressivekeeplast1whc:8,assumpt:8,parent:15,screen:14,cycl:15,rare:[15,8],uncondition:8,come:[3,15,12,1,8],reaction:12,opensplice_testeruserguid:14,region:3,contract:3,audienc:0,inconsist:[3,1,15],improv:[15,1,8],among:15,undocu:15,"0x200000":15,color:14,period:[15,12,1,8],runawai:15,exploit:[3,6],colon:15,constant:[15,8],poll:15,ultim:[15,8],"00x20000000":15,coupl:[3,14],rebuild:3,hardli:8,besteffort:4,mark:[15,14,1,8],"__use_time_bits64":3,bypass:15,thousand:15,wake:[15,12],"1mb":15,those:[15,14,1,8],blowfish:15,interoper:6,pedant:[15,8],cast:[1,15],invok:[3,5,1,15],outcom:1,margin:15,advantag:[3,1,8],ctrl:[3,14],henc:[15,8],ddsi2servic:8,typesupport:14,destin:[3,15,1,7,8],cluster:[3,15],time_t:3,subscrib:[8,1,6],develop:[3,1,15],author:15,ospl_projgen:3,same:[1,12,3,6,7,8,15],check:[15,12,14,1,8],binari:[6,15],epoch:3,html:15,lite:[3,15],eventu:8,mbyte:15,nest:15,confidenti:15,gacutil:3,decompress:15,driven:[3,1,15],capabl:[3,15,12,1,8],ospl_comp_zlib_uncompress:7,mani:[1,12,3,8,14,15],extern:[14,15],postpon:[1,15],tradition:6,retransmiss:[15,8],appropri:[3,14,15],choos:[15,8],compfn:7,effectu:1,model:[3,15,14,6,8],roughli:8,dcpscj:3,execut:[3,15,1,12],excel:[3,15,8],rest:[3,15,12],weekli:10,kill:[3,15],aspect:[15,12,1,8],speed:[15,7,12],death:15,struct:[3,6,15],hint:13,except:[3,12,14,15,8],littl:15,identif:[6,7],priori:15,treatment:8,versa:[3,15,4,6,8],disrupt:[8,1,6],earli:[15,7,8],around:[15,14,1,7,8],max_open_fil:15,read:[1,3,8,10,13,15],adlinktech:2,categoris:[15,8],world:[8,1,6],topicexpress:15,realtim:15,integ:[15,8,1,7,6],server:6,benefit:[3,15,8],either:[1,3,5,8,14,15],cascad:[6,15],output:[3,15,1,8],inter:[3,15],rollov:3,manag:[0,1,5,8,10,15],fulfil:[1,5,6,7,11,15],cabl:[15,8],ospl_comp_zlib_compress:7,unrecover:14,loopback:[15,8],keystor:15,definit:[1,3,6,7,8,10,15],achiev:[3,15,1,6],legal:15,evolv:15,exit:[3,14,7],corespond:15,apostroph:15,complic:8,refer:[0,1,3,7,8,13,15],os_tim:15,timeout:[15,8],power:[3,15],garbag:[15,8],inspect:[1,15],broken:3,topicqo:15,fulli:[3,6,7,8,14,15],"throw":8,comparison:[0,1],ack:15,stand:15,ospl:[0,15,8],act:[1,15],adlinktech_usa:2,processor:14,effici:[3,15,12,1,6],liveli:[15,12,1,8],opensplic:[6,2],terminolog:8,unregist:[15,8],processorarchitectur:3,watchdog:1,your:[3,14,1,15],per:[1,12,3,6,8,14,15],complianc:[15,8],area:[3,15,8],aren:3,nackdelai:8,overwrit:[3,15],start:6,compliant:[15,6,8],interfac:6,low:[0,15,8,1,3],lot:[1,8],ipv6:8,strictli:[15,8],hard:[15,1,8],ospl_logpath:3,conclud:[3,1,15],regard:[3,15],amongst:[15,1,8],categor:14,conclus:1,faster:[3,15],notat:[3,15],possibl:[1,12,3,6,7,8,14,15],"default":[8,1,6],bucket:[15,8],unusu:[15,8],embed:[15,6,7,8],deadlock:[1,15],expect:[3,15,8,1,6],gone:8,loadabl:15,creat:[1,3,5,6,8,10,15],certain:[15,8],fellow:1,strongli:[3,15,1,8],catchup:[1,15],decreas:[14,15],file:[0,15,1,8],cultur:3,intra:[3,15,8],fill:[15,1,7,8],incorrect:[15,8],again:[15,1,8],googl:15,discrimin:6,tinyint:6,orient:6,field:[3,14,15],valid:[1,3,7,8,14,15],rdbm:6,hibern:3,you:[3,15,14,1,8],intermedi:14,sequenc:[15,8,1,6],symbol:[3,15],signficantli:15,briefli:3,track:[3,15,12,1,8],equalitycheck:1,z_ok:7,pool:15,reduc:[15,1,8],assert:[15,8],globalprofil:15,directori:[3,10,15],descript:[5,8],mimic:15,potenti:[3,15,1,8],escap:15,degrad:15,cpu:[15,12,1,7,8],by_source_:3,represent:[3,14,15,8],all:[1,2,3,4,5,6,7,8,9,12,13,14,15],forget:15,ospl_temp:3,illustr:[1,7],forbidden:15,opensplice_rmi_gettingstart:14,standardis:[15,8],improperli:15,disc:15,abil:[15,1,8],follow:[1,3,4,9,8,10,6,13,14,15],disk:[3,1,15],children:15,forceopt:10,dsn:6,reportinterv:15,white:[4,14],init:[15,7],program:[3,15],os_int64:15,neglig:8,thursdai:3,global:[15,0,10,1,8],straightforward:8,fals:[15,4,8,1,6],unacknowledg:[15,8],util:[3,6],durabiltii:15,candid:15,mechan:8,failur:[3,15,1,8],veri:[1,3,8,10,14,15],delayedalign:1,enablecategori:8,list:[1,3,4,6,7,8,14,15],helloworld:15,adjust:[3,15],stderr:[3,15],small:[12,14,15,8],joiner:[1,15],dimens:15,enterpris:[3,15,6,7,13],tel:2,ten:[14,15],sync:1,journal_mod:15,rate:[15,8],pressur:15,design:[3,10,12,15,8],pass:[3,14,15,7],further:[3,1,15],tev:[15,8],what:[1,3,4,6,8,15],sub:[14,8],cleartext:8,clock:[3,15],section:[1,12,3,4,5,9,7,8,11,13,14,15],ffff:[15,8],hde:3,delet:[3,15,8,1,6],abbrevi:15,version:[1,3,7,8,10,14,15],intersect:1,consecut:15,method:[3,15,7],hierarch:[14,1],hasn:8,full:[1,12,3,4,9,8,13,15],themselv:[15,1,12],solari:[15,7,13],excess:15,depend:[1,12,3,8,10,15],standard:[1,12,3,6,8,10,15],modifi:[10,14,6,15],valu:[1,12,3,7,8,14,15],search:[0,15],sender:15,verify_checksum:15,prior:[3,15],amount:[14,15,5,1,8],pick:8,action:[3,1,15],magnitud:3,via:[1,12,3,6,8,15],masterprior:1,api_info:15,primit:6,databandwidthlimit:8,paranoid_check:15,libhelloworld:15,put:6,famili:8,suddenli:1,establish:[15,8],opensplice_preprocessor_usermanu:14,select:[6,8],aggress:[15,8],hexadecim:15,clockstart:15,stdout:[3,15],regist:15,two:[1,12,3,6,7,8,15],taken:[1,3,8,13,14,15],asecurityprofil:15,toggl:15,more:[1,3,6,7,8,10,14,15],reachabl:[11,15,8],desir:[15,1,8],tester:[14,8],hundr:14,flag:[14,15],particular:[1,3,5,9,8,10,14,15],known:[3,15,14,1,8],compani:2,cach:8,dictat:5,none:[15,1,8],ist_info:2,valuabl:[14,1],opensplicev6:15,remain:[3,15,14,1,8],hkey_local_machin:15,ficiti:15,learn:8,prompt:[3,14],scan:15,challeng:6,registr:15,share:6,templat:15,minimum:15,unreli:[15,8],phrase:15,replusr:6,huge:8,cours:[3,15,1,8],secur:8,rather:[3,15,8],anoth:[0,15,1,8],divis:8,reject:[15,1,8],simpl:[3,6,8],unabl:3,resourc:[1,3,6,7,8,10,14,15],referenc:[3,15],variant:8,reflect:12,associ:[3,15,1,8],sigttin:3,circumst:[14,15,8],"short":[1,3,4,6,7,8,15],networkchannel:12,postfix:15,confus:1,caus:[3,15,8,1,6],so_dontrout:15,facebook:2,logrot:0,rotat:10,mission:6,trade:8,held:[3,15],through:[3,15,14,1,8],pane:14,hierarchi:8,paramet:[0,15,5,1,8],write_buffer_s:15,brows:14,late:[3,15,1,8],rapidli:14,reschedul:15,exchang:[15,8,1,6],requestcombineperiod:1,might:[15,12,14,1,8],finer:[15,8],good:[12,3,2,8,14,15],"return":[14,15,7],timestamp:1,circularli:15,thereof:8,secondarili:8,thisisnotapartit:4,complain:8,bigger:14,publickeytoken:3,document:[3,15,13,1,2],ospl_shmem_:3,instruct:[1,3,8,13,14,15],aligne:1,easili:[3,15,8],iff:15,reactiv:15,compris:[14,15],max_lat:8,found:[3,14,15,8],intervent:1,errata:15,truncat:[10,15,12],exitfn:7,monoton:3,idea:6,procedur:[1,8],realli:8,connect:[6,8],beyond:[3,15],event:[15,14,1,8],timeli:8,safeti:15,publish:6,payload:[15,8],unsupport:15,health:15,msil:3,print:[14,15],occurr:15,daemom:15,advanc:[3,6],publish_initial_data:6,like:[1,3,6,8,14,15],reason:[3,15,14,1,8],base:[8,1,6],ask:[1,8],mmf:15,recv:[15,8],asm:15,basi:[15,1,8],prefac:0,launch:15,omit:[3,15],perhap:8,perman:[1,15],heartbeat:[1,8],lifetim:15,assign:[1,15],major:[15,8],notifi:15,obviou:8,upper:15,nack:15,placehold:15,footprint:[3,14],smaller:[12,15,8],done:[1,3,5,8,14,15],least:[15,12,1,8],blank:[15,7],stabl:[14,15],miss:[15,1,8],differ:[0,1,12,3,4,6,7,8,15],networkservic:8,script:[3,14,15],"5th":2,networkingbridg:[0,15],construct:8,rbuf_siz:15,storm:8,illeg:[3,8],scheme:15,disagr:1,store:[3,15,8,1,6],adher:[15,8],option:[1,3,7,8,10,14,15],relationship:[8,1,6],ospl_sp_:3,uncompds:7,drain:[15,8],bidirect:8,consult:15,bridgedpartit:4,grace:[3,15],albeit:15,kind:[1,12,4,8,14,15],cyclic:[6,15],remot:[1,3,6,7,8,11,15],remov:[15,3,10,1,8],executbal:15,bridg:[3,4,6,7,8,15],block_siz:15,consumpt:[10,15],toward:6,comput:[3,1,7,15],strengthen:1,archtirectur:3,iparam:7,acknacknumbitsemptyset:8,c_base:15,expir:[15,1,8],partitit:15,dedic:8,"null":15,spdpinterv:8,equival:15,self:[3,15,8],also:[1,12,3,4,5,7,8,10,14,15],without:[1,12,2,5,8,14,15],silent:15,useipv6:8,previou:[15,14,1,8],reach:[3,15,14,1,8],react:[3,5,15],most:[1,3,6,7,8,10,15],plai:[8,1,6],synchronousdeliveryprioritythreshold:8,clear:[15,8],cover:[15,6,8],part:[1,2,4,6,8,15],abnorm:[15,8],clean:[15,8],pars:[3,14],usual:[3,15,1,8],microsoft:[3,6],dcpsheartbeat:1,think:1,ospl_infofil:3,carefulli:15,transport_prior:8,session:15,particularli:[1,8],cdr:[15,8],uniform:3,fine:[15,8],find:[15,1,8],impact:[15,1,8],colloc:15,firewal:15,copyright:[3,2],solut:15,history_depth:8,queu:[15,8],factor:[15,12],hit:8,express:[3,15,4,1,6],resent:[15,12],nativ:[0,8],mainten:1,sill:15,restart:[3,1,15],resend:[12,15,8],whenev:[15,12,1,7,8],crc:15,common:[3,4,15,8],wrote:[15,8],certif:15,set:6,dump:[15,8],startup:[1,7,15],pstore:15,see:[1,3,9,8,10,15],osplconf:0,reserv:[3,15,2],analog:6,someth:[1,15],sigttout:3,smallest:15,mutex:15,subscript:[3,4],experi:[3,12],altern:[3,15,7,8],signatur:15,syntact:1,numer:[3,15],induc:[12,15,8],sigil:3,rostand:2,succeed:[3,5,15],distinguish:[15,14,1,7,6],pcap:15,"4gl":6,popul:14,both:[1,3,4,6,7,8,15],newgroup:1,last:[3,15,1,8],explicitlypublishqossettodefault:8,alon:15,tempor:1,custom_lib:3,context:[3,15,14,6,12],forgotten:15,pdf:14,whole:[15,1,2],load:[3,15,12,1,8],spdpmulticastaddress:8,simpli:[3,1,8],point:[3,15,4,1,8],instanti:15,schedul:[1,8],returncod:3,arbitrarili:8,header:[15,8],networkingbridgeexampl:4,dds_userclock_t:15,shutdown:[3,5,15,7],suppli:[3,15,8],throughout:[3,15,12,1,8],"0xa":2,backend:15,chanenl:15,faithfulli:8,java:0,stamp:[0,1,15],loggin:15,devic:15,due:[15,12,1,8],empti:[15,1,8],sinc:[1,12,3,8,14,15],secret:15,monthli:10,blob:15,box:[3,12],wish:[15,13],fire:[3,15],convert:15,unnecessarili:8,gap:15,secondaryreordermaxsampl:8,coordin:1,partli:[1,15],demand:[12,1,7,6],gac:3,look:[3,15,14,1,8],contentfilteredtop:15,batch:[6,8],durat:[3,15,8],ramif:15,"while":[1,3,5,6,8,15],kick:1,behavior:[3,6,15],error:[1,3,7,8,14,15],anonym:8,loos:15,loop:[3,8],pack:[15,12,1,8],subsect:[3,15,14,1,8],propag:1,aix5:15,readi:[15,8],technolog:[6,2],readm:3,itself:[1,3,5,6,8,14,15],satisfactori:[12,8],deamon:15,leveldb:15,grant:15,nanosec:3,belong:[15,1,8],nanosecond:15,shorter:15,sqlite3:15,conflict:[1,15],higher:[15,12,1,8],rel:[3,14,15,8],x86:3,optim:[3,15,1,7,12],wherea:[3,15,1,8],moment:[15,1,12],temporari:[0,15,1,8],user:[1,3,5,6,8,14,15],robust:8,wstring:6,typic:[1,3,6,8,14,15],recent:[15,10,1,8],lower:[15,8],sha1:15,discourag:[1,15],ospl_sp_ddsi:15,spent:3,expens:[15,8],propos:[3,1],"0x240000":15,salvo:15,paragraph:[3,8],shape:8,mergepolici:15,elect:[1,15],mandat:15,snappi:[15,7],unsecur:15,shortcut:14,eager:1,labour:8,input:[3,14],subsequ:[3,15,8],build:[3,15,1,7,8],bin:3,writerlingerdur:8,varchar:6,format:[3,15,7,8],big:[14,1],intuit:[6,8],insert:[3,6,15],bit:[3,15,8],characterist:[3,15],formal:[15,8],lost:[12,15,8],signal:0,resolv:[3,14,1,15],elaps:[3,8],manifest:8,collect:[15,12,14,1,8],cmsoap:15,encount:15,sketch:8,often:[15,1,8],urgenc:3,acknowledg:[12,8,15,2],visibl:[14,15,8],some:[1,3,4,6,7,8,14,15],back:[3,15,1,8],urgent:8,unspecifi:[7,8],sampl:6,mirror:[15,8],sizeof:7,surpris:8,distribut:[1,12,3,6,8,10,11,14,15],scale:[1,12,3,7,8,15],opensplice_tnodemonitorguid:14,glibc:3,shall:[1,15],synchronousdeliverylatencybound:8,sigusr2:3,pem:15,retri:[1,15],larg:[1,12,7,8,10,15],recognis:[15,8],fragments:8,reproduc:2,machin:[3,12,15,8],run:[1,12,3,6,8,10,14,15],my_top:15,agreement:1,rue:2,step:[3,1,7],meantim:8,from:[0,1,4,5,6,7,8,10,15],impos:[1,15],faith:2,constraint:[0,15],memori:[0,15,5,1,8],idl:[14,6,15],microsecond:8,"00x0":15,"1gb":15,reduct:[15,8],repair:15,doubl:[6,15],real:[0,1,3,4,6,8,13,15],primarili:[15,8],within:[1,12,3,5,6,7,8,15],addtion:15,uf_mems:15,"00xa0000000":15,chang:[0,1,2,6,8,15],announc:[3,5,1,15],durabl:8,occupi:15,inclus:15,coexistwithnativenetwork:8,fledg:15,question:[15,7],effectivili:1,"long":[1,12,3,6,7,8,14,15],custom:[3,6,15],includ:[1,8],suit:[12,4,2],forward:[1,12,3,4,6,7,8,14,15],properli:[3,15,4,6,8],dbmsddstopic:6,navig:15,pwd:6,atoi:7,link:[3,15,7,8],newer:1,atom:1,duli:8,line:[1,3,6,8,10,14,15],info:[3,15,1,8],utc:3,consist:[1,3,6,8,14,15],caller:15,dds_time_t:3,priveleg:15,builtinendpointset:8,highlight:15,similar:[3,15,14,1,8],hash:[15,1,8],dds_wait_for_historical_data:15,utilis:3,chan:15,doesn:[1,3,6,8,14,15],repres:[3,5,6,8,14,15],"char":[6,7,15],incomplet:[15,1,8],uncompfn:7,guarante:[1,8],cafe:3,spontan:15,sigtstop:3,sequenti:15,invalid:[3,15,8],application:15,articip:15,librari:8,nat:15,sigcont:3,maxqueuedrexmitbyt:8,exp:15,expirytim:8,mismatch:[3,1,15],param:7,adminqueu:15,algorithm:[1,8],vice:[3,15,4,6,8],dataread:[3,14,1,15],infuenc:15,tradeoff:15,depth:[3,15,8],far:[14,15,8],fresh:[15,8],domaingain:8,pluggabl:[1,3,4,5,6,15],code:[3,14,15,7,8],destinationorderqospolici:3,edg:[6,2],scratch:14,durabilitypublish:15,whchigh:8,samplerequestlisten:1,privat:3,reinsert:1,sensit:14,reallocat:15,elsewher:8,send:[8,1,6],granular:15,outgo:[15,8],opposit:15,aris:[1,15],fatal:[15,8],sent:[1,12,3,6,7,8,14,15],passiv:1,random:[15,8],whichev:8,disclos:4,outputfil:8,mastership:15,"00x60000000":15,keep_last:[3,15,8],volum:[0,6,15],untouch:15,implicitli:[3,15,5,1,6],relev:[15,14,1,13],tri:15,fewer:8,"try":[3,15,1,8],create_particip:[3,5,15],maxsiz:7,freed:15,pleas:[3,15,1,7,8],malici:15,impli:[1,15],pretend:8,visualis:15,dds_type:6,copytrunc:10,natur:[3,15,6,8],"0x0":15,cron:10,video:15,odd:15,click:14,append:[6,8],compat:6,index:[15,6,8],compar:[3,1,15],resembl:8,access:[3,6,15],absoff:15,experiment:15,deduc:15,wireshark:15,penalti:[15,1,8],chose:3,despit:8,let:[15,6,8],ubuntu:13,alignerschedul:1,becom:[1,3,6,8,10,15],accessor:14,great:15,convers:8,overwritten:8,conceiv:15,larger:[15,7,8],reus:15,nameless:15,chanc:[15,1,8],nearest:15,appli:[1,12,7,8,10,13,15],approxim:[15,8],xmit:[15,8],api:[3,15,1,7,8],apo:15,reallow:15,cloud:15,tailor:14,metaphor:15,usa:2,commun:6,live:[1,15],seamless:6,next:[3,15,1,7,8],implic:8,few:[3,12,8],doubt:8,usr:6,igabty:15,stage:8,remaind:8,sort:[14,15],impress:12,unplug:8,insensit:15,ospl_comp_zlib_init:[15,7],actual:[1,12,3,7,8,15],account:8,retriev:[15,1,8],scalabl:[3,15,1,7,8],cumbersom:15,tag:[15,8],obvious:[12,15,8],meet:[15,12,9,8],unread:15,ospl_comp_zlib_maxs:7,aliv:[1,15],control:6,sqlite:15,malform:15,process:6,high:[0,1,6,7,8,15],aligneeschedul:1,tab:14,opensourc:10,weaken:[1,15],delai:8,aes256:15,sit:8,soon:[15,1,12],"5b9310ab51310fa9":3,need:[1,12,3,4,9,8,6,13,14,15],infeas:8,instead:[1,3,7,8,10,14,15],ne11:2,overridden:[3,6,8],watch:[14,1],domainservic:15,networkinginterfaceaddress:15,redund:[15,8],philosophi:8,physic:[3,1,7,15],alloc:[3,5,15,14],essenti:[15,6,8],d_cabil:1,counter:[15,1,8],packets:15,element:[1,3,9,7,8,6,13,14,15],unaccept:14,allow:[8,1,6],elig:8,creation:[3,15,8,1,6],ospl_uri:[0,15],move:[3,15],whilst:8,comma:[15,8],currentcontrolset:15,chosen:[3,15,8,1,6],anyon:[13,8],therefor:[1,12,3,7,8,14,15],recept:[3,8],crash:[3,15,12],greater:[1,15],nullprofil:15,auto:[3,15,8],overal:[15,8],dai:[10,15],"0x280000":15,dat:15,mention:[3,14,1,8],clockstop:15,facilit:[3,15,1,6],surviv:15,strive:8,somewher:1,anyth:[15,1,8],edit:[14,15,8],mode:6,truth:1,subset:[15,8],chunk:[14,12],meta:[0,15],"static":[0,15],sigalrm:3,special:[13,15,8,1,6],out:[1,12,3,6,8,14,15],variabl:[0,15],influenc:[3,15,12],rev:3,categori:8,typenam:14,suitabl:[3,15,12],disappear:[12,15,8],hardwar:15,red:14,franc:2,shut:[3,15,1,12],insid:[15,1,8],watermark:8,kilobyt:12,standalon:6,releas:[3,14,15,7,8],allowmulticast:8,likelihood:[1,8],afterward:15,promptli:8,dbmspartit:6,unwant:15,could:[3,15,1,12],timer:3,keep:[1,12,3,8,14,15],length:[15,6,8],organis:[0,8],outsid:[3,15,8],retain:[15,8],networkinterfaceaddress:8,adh:15,softwar:15,vallei:2,suffix:15,durabilityservic:1,overshoot:8,qualiti:[15,12,8,1,6],nodemon:14,date:15,strategi:15,owner:[15,8],ilobyt:15,facil:[3,11,15,8],prioriti:[1,8],strict:[15,6,8],unknown:1,licens:8,perfectli:1,capac:15,wrapper:8,attach:[1,12,3,8,14,15],attack:15,termin:[1,3,5,8,14,15],"final":[5,1,8],maxqueuedrexmitmessag:8,udp:[15,8],shell:3,defeault:15,rsa:15,accompani:14,enqueu:8,exactli:[15,8,1,6],prune:15,structur:[0,6,7,8],charact:[14,6,15],sens:15,histor:8,sec:3,stricter:[15,8],unencrypt:15,thereaft:3,deprec:15,clearli:8,correspond:[15,12,14,1,8],corrupt:15,have:[1,12,3,4,6,8,14,15],tabl:[6,8],disjoint:1,optimis:[15,12],sqlitemt:15,depict:8,squashparticip:8,diverg:1,rout:[15,8],mib:15,mix:[3,15,8],builtin:[4,15,8],demultiplex:8,dbmstopic:6,which:[0,1,4,5,6,7,8,15],standardsconform:8,soap:[3,14,15,11],singl:[0,1,5,6,7,8,15],unless:[10,15,7],whc:[15,8],mimick:15,who:[1,13],discov:8,useful:15,dcpssubscript:4,cipher:8,dbmstabl:6,deploi:[0,15,8],segment:[3,5,15,8],"class":[1,8],unmangl:8,gather:8,request:[15,5,1,8],uri:[3,14,15],face:8,pipe:3,durabilitykind:15,determin:[5,8],sourceforg:10,fact:[15,1,8],text:[14,15],verbos:[1,8],indispens:8,longer:[15,12,1,8],trivial:8,anywai:[15,1,8],textual:14,locat:[3,11,15,7,8],jar:3,should:[1,12,3,4,6,7,8,10,15],prolong:15,won:15,max_blocking_tim:8,"1abc":15,discontinu:3,meant:[15,8],ocur:7,reuasbl:14,autom:14,regularli:15,increas:[15,12,14,1,8],endless:8,os_malloc:7,enabl:[8,1,6],integr:[0,15,6,8],partit:6,compress2:7,tuner:[0,15],alignmentkind:15,view:[3,15,14,1,8],conform:6,legaci:[15,1,6],z_default_compress:7,knowledg:[15,9,1,8],abort:3,elast:15,"0hz":15,"00x00220000":15,stack:[15,8],closer:15,asynchron:[15,1,8],statu:[3,15,14,1,8],wire:[3,15,8],throttletreshold:15,correctli:[14,15,8],pattern:15,boundari:[6,15],unregistr:15,dll:[3,15],written:[1,3,7,8,14,15],clientdur:1,progress:[3,15,1,8],neither:[15,1,8],complement:6,kei:[6,8],sigchld:3,job:10,entir:[15,1,8],group:1,swift:12,addit:[15,8,14,1,6],defaultnamespac:[4,15],revers:6,plugin:[0,15],equal:6,etc:[3,15,14,1,8],instanc:[1,3,6,7,8,15],instert:15,sigterm:3,retransmitmerg:8,comment:15,threadnam:15,ignoredpartit:8,arriv:[12,15,8],solv:15,vxwork:[0,15],respect:[15,12,1,7,8],quit:[3,1,15],sarl:2,addition:1,trademark:2,insuffici:8,compon:[3,8],"int":[15,7],besid:[15,1,8],treat:[15,8],immedi:[15,12,1,8],partial:14,dcpspublic:4,presenc:[15,8],coincid:15,bulk:15,togeth:[3,15,8],dcpssacsassembl:3,present:[1,12,3,7,8,15],cmagent:15,multi:[3,1,15],align:6,defin:[3,15,8,1,6],wild:15,rightli:8,deliveri:[15,8],observ:[3,15,8],layer:8,domainid:8,fragement:15,linkedin:2,bigint:6,incom:[15,1,8],revis:15,so_reuseaddr:15,reviv:15,parti:[3,15,1,6],satisfi:[14,15,12],cross:8,on_request:[1,15],member:[6,15],schizophren:15,largest:[15,7],wakeup:15,difficult:1,http:[3,15,2],hostnam:15,denot:3,upon:[3,15,8,1,6],effect:[0,15,8,1,6],decoupl:3,expand:15,ddstodbm:6,off:[15,1,8],well:[1,12,3,6,8,11,15],historyqospolici:3,thought:[3,15],exampl:[0,15,8,1,6],filesystem:15,undefin:[3,15],audio:15,latest:[15,1,8],sporad:[1,15],newest:1,less:[15,7,8],"boolean":[15,8,1,6],obtain:[1,8],defaultrol:15,timeshar:15,heavili:[15,1,8],handov:15,simultan:[3,15,12,1,8],web:[3,15,2],y2038proofnessdesign:3,tight:15,priorit:15,add:[14,15,8],cleanup:[3,15],lzf:[15,7],participantgain:8,smart:3,simul:[8,1,6],dest:7,piec:15,arguabl:15,ridden:3,wait_for_historical_data:[1,15],realiz:[3,15],five:7,know:[1,15],press:14,realis:[4,1],password:15,candic:15,participantindex:8,resid:[15,8],backbon:[14,6],success:[3,15],incred:8,"00x140000000":15,corpor:[3,2],"4mb":15,necessari:[3,15,1,7,8],lose:[12,15,8],page:[0,10,15],unreach:8,exceed:15,didn:[1,15],vortexopensplic:3,prepend:15,specfi:15,twitter:2,interact:8,"export":15,flush:15,proper:[15,1,8],home:15,transport:[12,15,8],tmp:[3,15],win32:3,trust:15,leaf:15,lead:[15,8,1,6],leak:15,avoid:[15,10,1,8],octet:6,overlap:[3,1,15],leas:[1,8],estim:[14,15],leav:[15,1,7,8],ipv4:[15,8],fill_cach:15,noisi:15,host:[3,15,6,8],obei:6,although:[15,8],offset:3,strlen:7,sigabrt:3,after:[1,3,8,13,14,15],expiri:8,about:[0,1,3,6,8,10,15],readwrit:15,socket:[14,15,8],column:[14,6],datagram:[15,8],discard:15,certainti:[15,8],disabl:[15,9,8],own:[1,12,3,5,9,8,14,15],unopen:15,automat:[15,10,1,8],dataset:[1,15],assess:1,rectifi:8,mere:[15,7],leverag:[6,15],transfer:[3,8,1,6],much:[12,15,8],arg1:15,biggest:14,arg2:15,"function":[1,12,3,5,6,7,8,10,15],unexpect:15,advers:[3,15],sigstop:3,neutral:3,gain:[15,8],uninstal:0,eas:[3,10],highest:[15,1,8],count:[14,15],succe:15,made:[15,8,14,1,2],wise:8,temp:3,whether:[3,15,14,1,8],shrunk:15,smooth:[15,8],displai:[14,15],troubl:15,straightawai:15,record:[3,15,9,8],below:[1,4,6,8,13,14,15],limit:[0,1,2,5,6,8,10,15],otherwis:[15,8],problem:[3,12,15,8],veneer:7,pikeo:15,evalu:15,storedirectori:1,mask:15,dure:[3,15,12,1,8],pid:3,meaningless:15,replica:15,implement:[1,12,3,7,8,15],inf:15,ing:15,probabl:[15,8],tick:[14,15],quot:15,immateri:8,nonetheless:8,guidanc:8,boot:[3,15],detail:[1,3,13,5,9,7,8,10,11,14,15],virtual:[3,15,8],other:[5,6,8],lookup:8,futur:15,branch:1,varieti:[14,15,8],"100m":15,straddl:8,log:[1,3,6,8,10,15],stai:[15,8],fune:15,amp:15,portion:[15,8],auxiliari:[15,8],understand:[6,8]},objtypes:{},objnames:{},filenames:["index","durability-service","contacts","overview","networkingbridge-service","domain-service","dbmsconnect-service","networking-service","ddsi2-networking-service","service-feature-list","logrotate","tuner-service","referencesystems","preface","tools","guide"],titles:["The Vortex OpenSplice Deployment Guide","5. The Durability Service","15. Contacts & Notices","2. Overview","8. The NetworkingBridge Service","4. The Domain Service","10. The DbmsConnect Service","6. The Networking Service","7. The DDSI2 and DDSI2E Networking Services","3. Service Descriptions","14. Logrotate","9. The Tuner Service","13. Example Reference Systems","1. Preface","11. Tools","12. Configuration"],objects:{},titleterms:{concept:[8,1,6],queri:15,global:3,systemid:15,force_key_equ:15,whchigh:15,storemod:15,priorityinherit:15,content:15,retransmitmergingperiod:15,xmitlossi:15,allowreus:15,send:15,transport_prior:15,outputfil:15,assumemulticastcap:15,mechan:1,d_groupsrequest:1,d_adminactionqueu:1,delayedalign:15,fragments:15,enablecategori:15,resendqueu:1,level:7,maxbursts:15,measurehbtoacklat:15,primaryreordermaxsampl:15,probelist:15,certificateverif:15,prevent:1,leasemanag:15,direct:8,jump:3,zero:12,trustedcertif:15,minimis:8,port:[15,8],append:15,mirrorremoteent:15,compat:[15,1,8],corba:3,compressionbuffers:15,endpointsinsystem:15,topolog:12,maxreliabbacklog:15,partitionaccess:15,userclockstop:15,packetretentionperiod:15,gener:[6,15],dontfrag:15,behaviour:8,test:15,partition_express:15,address:[15,8],path:8,alignerschedul:15,failureact:15,serviceterminateperiod:15,y2038readi:15,cert:15,multicast:8,chang:3,configur:[12,3,4,6,7,8,10,14,15],whcadapt:15,masterprior:15,databandwidthlimit:15,throttlethreshold:15,filenam:15,domainid:15,instal:3,select:1,monitorport:15,from:3,commun:8,retentionperiod:15,latenc:[12,8],usr:15,lock:15,scope:[1,15],conflictresolv:1,type:[6,15],rnrservic:15,dds_time:3,notic:2,enhanc:8,verifycli:15,"transient":8,indic:0,legacyfragment:15,cach:[3,15],high:12,endpoint:8,d_capabl:1,linger:8,histori:8,latency_budget:15,mastermonitor:1,purpos:1,control:8,rtnetwork:8,stream:8,process:[3,8],typedreport:15,share:[3,8],dbmsconnectservic:15,agent:15,topic:[15,8],ddsi2directmaxthread:15,aligneeschedul:15,manysocketsmod:15,auxiliarybandwidthlimit:15,resourcelimit:15,multipl:[3,8],secur:[15,7],enablemulticastloopback:15,threadpool:15,how:7,durabilitystatelisten:1,low:12,respondtortiinitzeroackwithinvalidheartbeat:15,map:[15,6,8],max:15,admineventdispatch:1,catalog:15,data:[3,1,8],parallel:1,diffservfield:15,ssl:15,bind:15,credenti:15,exclud:15,issu:8,inform:[3,8],"switch":7,environ:3,d_newgroup:1,persistentdatalisten:1,anoth:7,volum:12,logrot:10,mute:15,ospl_uri:3,reconnect:15,deathdetectioncount:15,masterelect:15,portnr:15,dynam:1,paramet:7,write:7,group:15,monitor:3,delai:1,polici:[1,15],logstacktrac:15,nodelai:15,rr_storageattrxml:15,platform:3,persist:[1,15],requestcombineperiod:15,leasedur:15,durablepolici:15,maxfiles:15,userclockstart:15,fragment:8,timestamp:15,initi:15,maxparticip:15,globalpartit:15,maxsamples:15,minimumsocketsendbuffers:15,spdpmulticastaddress:15,priority_kind:15,align:[1,15],introduct:[14,8],maxsampl:15,name:[1,15],rediscoveryblacklistdur:15,d_samplerequest:1,odbc:15,aligne:15,ddsi2e:8,preemptiveackdelai:15,mode:[3,14,8],side:8,domain:[3,5,15,8],samplerequesthandl:1,packetcapturefil:15,access_mod:15,meta:14,"static":12,connect:[1,15],year:3,twinoak:8,suppressdefaultlog:15,network:[3,15,7,8],space:1,externalnetworkaddress:15,publish:[15,8],replication_us:15,multicastdataoffset:15,durabl:[1,15],reader:8,file_nam:15,appendtofil:15,proxi:8,watermark:15,migrat:3,publish_initial_data:15,standalon:8,base:15,legacycompress:15,allowmulticast:15,assumertihaspmdendpoint:15,prefac:13,thread:[15,1,8],spdp:8,synchron:15,filter:15,enforc:15,organis:13,heartbeat:15,selfsignedcertif:15,networkinterfaceaddress:15,oper:[3,15],rang:15,networkingbridg:4,durabilityservic:15,independ:8,number:8,generatebuiltintop:15,heartbeatinterv:15,messag:3,size:[12,15,8],prioriti:15,avail:7,differ:14,networkservic:15,convent:13,interact:[3,1],lateackmod:15,system:12,construct:15,master:1,unicastmetaoffset:15,squashparticip:15,"final":15,schema:15,namespac:15,tool:14,usemulticastifmreqn:15,compressor:7,snetworkservic:15,userentropi:15,warnat:15,provid:1,structur:3,networkqueues:15,reliabilityrecoveryperiod:15,externalnetworkmask:15,listen:15,autoreschednackdelai:15,crccheck:15,argument:15,acknacknumbitsemptyset:15,tabl:[0,15],deliveryqueuemaxsampl:15,accesscontrol:15,spdpinterv:15,built:[7,8],min:15,contact:2,exampl:[10,4,12],queuesiz:15,which:3,standardsconform:15,combin:8,event_table_polici:15,channel:[15,8],userclockqueri:15,dsgraceperiod:15,useipv6:15,recoveryfactor:15,deploy:[13,0,8,3],object:14,compress:[15,7],discov:1,trigger_polici:15,cipher:15,deploi:3,grouplocallisteneractionqueu:1,"class":15,synchronousdeliveryprioritythreshold:15,topic_express:15,garbagecollector:15,destruct:15,unicastdataoffset:15,replication_mod:15,determin:1,partitiontop:15,wildcard:8,dbm:6,mainloop:15,verbos:15,rti:8,shmmonitor:15,forwardremotedata:15,threshold:15,keyvaluestor:15,absolut:15,writer:8,minimumsocketreceivebuffers:15,suppressspdpmulticast:15,salvos:15,local:8,keystorefil:15,dcpspartitiontop:15,compressionthreshold:15,maxmessages:15,between:8,stop:3,nativ:7,report:[15,8],retryonrejectdur:15,securityprofil:15,multicastrecvnetworkinterfaceaddress:15,smpcount:15,enabl:15,statist:[3,14,15],partit:[15,8],safetyfactor:15,tuner:[3,11],initialreset:15,conform:8,set:[1,7,8],packet:8,heapsiz:15,osplconf:14,respons:12,dbmsconnect:6,threadmax:15,databas:15,defaultmulticastaddress:15,networkpartit:15,particip:8,discoveri:[12,15,8],plugininitfunct:15,localdiscoverypartit:15,d_deletedata:1,clientdur:15,builtinendpointset:15,entiti:8,timetowaitforalign:15,maxinst:15,kei:15,startupmodedur:15,transportprior:15,dbmstodd:15,mmstat:14,entitynam:15,maxsamplesperinst:15,tunerservic:15,advertisebuiltintopicwrit:15,plugin:7,initialdiscoveryperiod:15,equal:1,audienc:13,storesessiontim:15,defragunreliablemaxsampl:15,stacksiz:15,aggressivekeeplastwhc:15,dsn:15,ignoredpartit:15,overview:[3,8],maxwaitcount:15,symbol_nam:15,vxwork:3,acceleraterexmitblocks:15,guid:[0,13],java:3,rr_storageattrcdr:15,maxclient:15,stamp:3,smpoptim:15,storeoptimizeinterv:15,subscrib:15,ddsi2eservic:15,partitionmap:15,waitforattach:15,resolut:15,secondaryreordermaxsampl:15,inprocessexceptionhandl:15,"case":6,replic:6,interoper:8,servic:[1,3,4,5,6,7,8,9,11,14,15],zlib:7,histor:1,builtintop:15,dontrout:15,resendmanag:15,retryonrejectbesteffort:15,forwardallmessag:15,kernelmanag:15,ddsi2servic:15,whclow:15,multicastmetaoffset:15,receiv:[15,8],whchighinit:15,handl:8,singleprocess:15,startupmodecoverstransi:15,maxautoparticipantindex:15,spdpresponsemaxdelai:15,slave:1,historicaldatarequesthandl:1,effect:3,temporari:3,logfil:15,ddstodbm:15,scenario:6,entri:15,client:15,command:15,retransmitmerg:15,d_statu:1,categori:15,explan:6,generatekeyhash:15,allowedport:15,storageparamet:15,obtain:15,tcp:15,minsch:15,d_namespacesrequest:1,statusthread:1,pluginlibrari:15,versu:8,explicitlypublishqossettodefault:15,update_factor:15,schedul:15,participantgain:15,match:8,servicenam:15,real:12,applic:[3,1,15],writerlingerdur:15,maxretri:15,d_namespac:1,storesleeptim:15,maxthreadspercli:15,daemon:15,transmit:8,traffic:8,background:[3,4],participantindex:15,userclockmodul:15,deadlockdetect:15,specif:8,memorypools:15,signal:3,server:15,vortex:[0,8,3],gidkei:15,x509authent:15,unicastresponsetospdpmessag:15,manag:[3,14],backlog:[15,8],retransmit:8,interv:15,deaf:15,intern:15,sampl:8,authent:15,librari:[15,7],throttlelimit:15,trace:[15,1,8],synchronousdeliverylatencybound:15,accesscontrolmodul:15,leas:15,topicaccess:15,inject:1,generalwatchdog:15,entropyfil:15,refer:[14,12],receivebufferchunks:15,throttl:[15,8],scheduletimeround:15,cpuaffin:15,usag:[3,6],interfac:8,remoteread:1,pluginparamet:15,peer:15,storedirectori:15,dcp:8,update_frequ:15,comparison:3,about:13,constraint:7,coexist:8,memori:[3,14],prioritizeretransmit:15,lifecycl:1,includ:15,ospl:[3,14],writetimeout:15,unrespons:8,timealign:15,reportplugin:15,opensplic:[0,1,3,8,14,15],publish_interv:15,watchdog:15,storag:15,controltop:15,merg:[15,1,8],coexistwithnativenetwork:15,support:3,nackdelai:15,receivebuffers:15,editor:14,start:[3,8],singl:[3,12],keypassphras:15,maxqueuedrexmitmessag:15,dcpsheartbeatlisten:1,ipv6:15,head:8,medium:12,groupcreationthread:1,forc:15,pwd:15,translat:8,uninstal:3,readtimeout:15,reset:15,ospl_dur:1,"default":15,maximum:8,limit:3,adminqueues:15,responsivenesstimeout:15,block:8,featur:8,conservativebuiltinreaderstartup:15,alignment_prior:15,diagnost:3,ddsi:8,file:[3,10],integr:3,assembl:3,encrypt:8,d_samplechain:1,allow:15,other:[1,7],role:[1,15],multicasttimetol:15,waittim:15,asymmetr:8,architectur:[3,8],node:12,variabl:3,maxqueuedrexmitbyt:15,intend:13,arrivalofdataassertsppandepliveli:15,leaseperiod:15,expirytim:15,ddsi2:8,userclock:15,defragbuffers:15,networkingbridgeservic:15,feder:8,defragreliablemaxsampl:15,algorithm:15,localendpoint:15,reliabl:[15,8],cipherkei:15,descript:[15,10,1,9],rule:8,timetol:15,time:[3,12,8],equalitycheck:15,servicesonli:15,domaingain:15}}) \ No newline at end of file diff --git a/docs/html/DeploymentGuide/service-feature-list.html b/docs/html/DeploymentGuide/service-feature-list.html index 34bbeea68..ed86609cf 100644 --- a/docs/html/DeploymentGuide/service-feature-list.html +++ b/docs/html/DeploymentGuide/service-feature-list.html @@ -74,7 +74,7 @@

    Navigation

    Vortex OpenSplice middleware and its services can be configured using easy-to-maintain XML files.

    Full details of how to use XML files to configure -the elements and attributes of all OpenSplice DDS +the elements and attributes of all Vortex OpenSplice services are given in the Configuration section.

    @@ -131,7 +131,7 @@

    Navigation

    \ No newline at end of file diff --git a/docs/html/DeploymentGuide/tools.html b/docs/html/DeploymentGuide/tools.html index ffc4515d5..970f0bfa4 100644 --- a/docs/html/DeploymentGuide/tools.html +++ b/docs/html/DeploymentGuide/tools.html @@ -442,7 +442,7 @@

    Navigation

    \ No newline at end of file diff --git a/docs/html/DeploymentGuide/tuner-service.html b/docs/html/DeploymentGuide/tuner-service.html index a8301e9ae..721a0bbfd 100644 --- a/docs/html/DeploymentGuide/tuner-service.html +++ b/docs/html/DeploymentGuide/tuner-service.html @@ -114,7 +114,7 @@

    Navigation

    \ No newline at end of file diff --git a/docs/html/EvaluationGuide/_images/LauncherTools.png b/docs/html/EvaluationGuide/_images/LauncherTools.png index 01c11a0ef..746dec8f6 100644 Binary files a/docs/html/EvaluationGuide/_images/LauncherTools.png and b/docs/html/EvaluationGuide/_images/LauncherTools.png differ diff --git a/docs/html/EvaluationGuide/_sources/architectural.txt b/docs/html/EvaluationGuide/_sources/architectural.txt index 75c6de1d2..a705f6572 100644 --- a/docs/html/EvaluationGuide/_sources/architectural.txt +++ b/docs/html/EvaluationGuide/_sources/architectural.txt @@ -1,10 +1,10 @@ -.. _`OpenSplice Architectural Modes`: +.. _`Vortex OpenSplice Architectural Modes`: -############################## -OpenSplice Architectural Modes -############################## +##################################### +Vortex OpenSplice Architectural Modes +##################################### -OpenSplice Enterprise provides two main architectural modes. These +Vortex OpenSplice provides two main architectural modes. These are the **Single Process** deployment mode, which provides a **Standalone** architecture, and, unique to OpenSplice, the **Shared Memory** deployment mode which provides a **Federated** architecture. @@ -21,7 +21,7 @@ Features of this mode are: + Uses in-process heap memory for the DDS database. -+ OpenSplice Enterprise services run as threads within the ++ Vortex OpenSplice services run as threads within the application process. + When there are multiple DDS application processes on a single @@ -60,7 +60,7 @@ Features of this mode are: more efficient than having to actually move the data *via* a networking service, allowing for improved performance and scalability. -+ OpenSplice Enterprise services are able to arbitrate over all of the ++ Vortex OpenSplice services are able to arbitrate over all of the DDS data on the node, and so can make smart decisions with respect to data delivery so that priority QoS values (for example) are respected; this is not possible when there are multiple standalone @@ -116,7 +116,7 @@ attribute but does contain a '' attribute.** |caution| Note that by default the ``OSPL_URI`` environment variable refers to a *Single Process* configuration, so to see the extra performance and -scalability benefits of OpenSplice DDS's Shared Memory +scalability benefits of Vortex OpenSplice's Shared Memory architecture it is necessary to switch from the default. diff --git a/docs/html/EvaluationGuide/_sources/basics.txt b/docs/html/EvaluationGuide/_sources/basics.txt index 57c583c52..0397b7d5f 100644 --- a/docs/html/EvaluationGuide/_sources/basics.txt +++ b/docs/html/EvaluationGuide/_sources/basics.txt @@ -1,25 +1,25 @@ -.. _`OpenSplice Enterprise Basics`: +.. _`Vortex OpenSplice Basics`: ############################ -OpenSplice Enterprise Basics +Vortex OpenSplice Basics ############################ -OpenSplice Enterprise is configured using an XML configuration file. +Vortex OpenSplice is configured using an XML configuration file. In this file, the user specifies the architectural model and the -OpenSplice Enterprise services that are to run when the DDS +Vortex OpenSplice services that are to run when the DDS infrastructure is started. The ``OSPL_URI`` environment variable refers to the specific XML configuration file that is used for the current deployment. The default value refers to the ``ospl.xml`` file located in the ``etc/config`` -directory of the OpenSplice Enterprise installation. The installation +directory of the Vortex OpenSplice installation. The installation directory itself can be referred to by the ``OSPL_HOME`` environment -variable. Please see :ref:`The OpenSplice Enterprise Environment` for -details of how to set up the OpenSplice Enterprise environment. +variable. Please see :ref:`The Vortex OpenSplice Environment` for +details of how to set up the Vortex OpenSplice environment. A number of other sample configuration files that can be used when -benchmarking OpenSplice Enterprise are also provided in +benchmarking Vortex OpenSplice are also provided in the ``etc/config`` directory. The ``OSPL_URI`` variable is of the form: @@ -35,7 +35,7 @@ of the ``OSPL_URI`` variable; for now, let us see what aspects of the OpenSplice deployment are controlled by this file. |info| - The OpenSplice Enterprise Launcher tool assists with the + The Vortex OpenSplice Launcher tool assists with the selection of the ``OSPL_URI`` variable. There is a *Configurations* menu that lists the sample configuration files that are available. @@ -48,7 +48,7 @@ OpenSplice deployment are controlled by this file. **The Launcher tool** -The OpenSplice Enterprise Launcher tool is also able to run the +The Vortex OpenSplice Launcher tool is also able to run the examples and performance tests that are described later in this document. diff --git a/docs/html/EvaluationGuide/_sources/biblio.txt b/docs/html/EvaluationGuide/_sources/biblio.txt index 5185f1c1a..c37b2d903 100644 --- a/docs/html/EvaluationGuide/_sources/biblio.txt +++ b/docs/html/EvaluationGuide/_sources/biblio.txt @@ -8,29 +8,43 @@ Bibliography HTML and PDF than 'official' reST/Sphinx citations In same order as original -.. _`OMG DDS 1.2`: +.. _`OMG DDS 1.2`: -**OMG DDS 1.2** - | Object Management Group, +**OMG DDS 1.2** + | Object Management Group, | *'Data Distribution Service for Real-Time Systems Version 1.2'*, | Available specification formal/07-01-01 +.. _`OMG DDS 1.4`: + +**OMG DDS 1.4** + | Object Management Group, + | *'Data Distribution Service for Real-Time Systems Version 1.4'*, + | Available specification formal/15-04-10 + .. _`OMG DDSI 2.1`: -**OMG DDSI 2.1** - | Object Management Group, +**OMG DDSI 2.1** + | Object Management Group, | *'The Real-Time Publish-Subscribe Wire Protocol DDS* | *Interoperability Wire Protocol Specification Version 2.1'*, | Document Number: formal/2009-01-05 +.. _`OMG DDSI 2.1`: + +**OMG DDSI 2.2** + | Object Management Group, + | *'The Real-Time Publish-Subscribe Wire Protocol DDS* + | *Interoperability Wire Protocol Specification Version 2.2'*, + | Document Number: formal/2014-09-01 .. _`OMG DDS XTYPES 1.0`: -**OMG DDS XTYPES 1.0** +**OMG DDS XTYPES 1.0** | Object Management Group, | *'Extensible and Dynamic Topic Types for DDS Version 1.0'*, | Document Number: formal/2012-11-10 - - + + .. END diff --git a/docs/html/EvaluationGuide/_sources/contacts.txt b/docs/html/EvaluationGuide/_sources/contacts.txt index b437fd808..d32f6016f 100644 --- a/docs/html/EvaluationGuide/_sources/contacts.txt +++ b/docs/html/EvaluationGuide/_sources/contacts.txt @@ -1,49 +1 @@ -.. _`Contacts & Notices`: - -################## -Contacts & Notices -################## - -******** -Contacts -******** - -| **PrismTech Corporation** -| 400 TradeCenter -| Suite 5900 -| Woburn, MA -| 01801 -| USA -| Tel: +1 781 569 5819 - -| **PrismTech Limited** -| PrismTech House -| 5th Avenue Business Park -| Gateshead -| NE11 0NG -| UK -| Tel: +44 (0)191 497 9900 - -| **PrismTech France** -| 28 rue Jean Rostand -| 91400 Orsay -| France -| Tel: +33 (1) 69 015354 - - -Web: http://www.prismtech.com - -E-mail: \info@prismtech.com - -******* -Notices -******* - -**Copyright** © 2016 PrismTech Limited. - -The information contained in this document is subject to change without notice and is -made available in good faith without liability on the part of PrismTech Limited or -PrismTech Corporation. - -All trademarks acknowledged. - +.. include:: ../../common/contacts.rst diff --git a/docs/html/EvaluationGuide/_sources/decisions.txt b/docs/html/EvaluationGuide/_sources/decisions.txt index d98cb4b55..a72c121d5 100644 --- a/docs/html/EvaluationGuide/_sources/decisions.txt +++ b/docs/html/EvaluationGuide/_sources/decisions.txt @@ -7,7 +7,7 @@ Benchmarking OpenSplice: Decision Trees DDS provides many functional benefits that set it apart from other middleware technologies, but users often still have specific performance requirements for latency, throughput, CPU and network -utilization. OpenSplice Enterprise provides the functional benefits +utilization. Vortex OpenSplice provides the functional benefits of the technology whilst remaining committed to excellent performance. diff --git a/docs/html/EvaluationGuide/_sources/index.txt b/docs/html/EvaluationGuide/_sources/index.txt index ed21213c3..9d7d6476b 100644 --- a/docs/html/EvaluationGuide/_sources/index.txt +++ b/docs/html/EvaluationGuide/_sources/index.txt @@ -9,7 +9,7 @@ OpenSplice Evaluation & Benchmarking Guide .. toctree:: :maxdepth: 2 :numbered: - + preface introduction basics @@ -20,8 +20,8 @@ OpenSplice Evaluation & Benchmarking Guide tests biblio - contacts - + contacts + Indices and tables ================== diff --git a/docs/html/EvaluationGuide/_sources/introduction.txt b/docs/html/EvaluationGuide/_sources/introduction.txt index f9e36c42c..57c8f1b40 100644 --- a/docs/html/EvaluationGuide/_sources/introduction.txt +++ b/docs/html/EvaluationGuide/_sources/introduction.txt @@ -4,26 +4,26 @@ Introduction ############ -One of the key differentiators of OpenSplice Enterprise is that it +One of the key differentiators of Vortex OpenSplice is that it provides a user with the ability to choose exactly how to deploy Data Distribution Service (DDS) applications, *i.e.* there are different DDS system architecture deployment modes and also different networking service protocols. This allows a user to maximize both *intra*-nodal and *inter*-nodal performance based on requirements specific to their -own use case. When evaluating OpenSplice Enterprise it is very +own use case. When evaluating Vortex OpenSplice it is very important to understand all of these features and benefits to ensure that the most appropriate combination is evaluated against your specific performance criteria. Once the performance figures have been observed the choice is usually clear. Every customer use case and set of requirements is different, so let -us briefly guide you through how to best deploy OpenSplice Enterprise +us briefly guide you through how to best deploy Vortex OpenSplice so that it meets and exceeds your expectations. Here we explain how -easy it is to get started with OpenSplice Enterprise and observe the -excellent performance and scalability it provides. OpenSplice -Enterprise is even shipped with dedicated performance tests that the -user can build and run easily. +easy it is to get started with Vortex OpenSplice and observe the +excellent performance and scalability it provides. Vortex OpenSplice +is even shipped with dedicated performance tests that the user can +build and run easily. *Note that this* Guide *serves only as an introduction and does not -replace the full OpenSplice Enterprise reference and user guides*. +replace the full Vortex OpenSplice reference and user guides*. diff --git a/docs/html/EvaluationGuide/_sources/networking.txt b/docs/html/EvaluationGuide/_sources/networking.txt index d99e9b1de..f662800a5 100644 --- a/docs/html/EvaluationGuide/_sources/networking.txt +++ b/docs/html/EvaluationGuide/_sources/networking.txt @@ -1,29 +1,29 @@ -.. _`OpenSplice Networking Options`: +.. _`Vortex OpenSplice Networking Options`: -############################# -OpenSplice Networking Options -############################# +#################################### +Vortex OpenSplice Networking Options +#################################### -OpenSplice Enterprise provides several networking options for the +Vortex OpenSplice provides several networking options for the delivery of DDS data between nodes. The networking service selection is largely transparent to the user; the difference is observed in the CPU consumption, networking load, and ultimately how fast and efficiently the data is delivered between nodes. The most applicable service is dependent on the requirements of the use case. -**OpenSplice DDSI** is the industry standard protocol providing vendor +**Vortex OpenSplice DDSI** is the industry standard protocol providing vendor interoperability that operates using a typed 'pull' style model. -**OpenSplice RTNetworking** is an alternative to the DDSI wire protocol. +**Vortex OpenSplice RTNetworking** is an alternative to the DDSI wire protocol. RTNetworking uses a type-less 'push' style model in contrast to DDSI and is often the more performant, scalable option. RTNetworking also offers prioritization of network traffic via -‘channels’, partitioning to separate data flows and +'channels', partitioning to separate data flows and optional compression for low-bandwidth environments. -**OpenSplice SecureRTNetworking** provides these features together +**Vortex OpenSplice SecureRTNetworking** provides these features together with encryption and access control. -**OpenSplice DDSI2E** is the 'enhanced' version of the +**Vortex OpenSplice DDSI2E** is the 'enhanced' version of the interoperable service. DDSI2E offers the benefits of the DDSI protocol (such as its automatic unicast delivery in the case of there being a single subscribing endpoint), together with some of the @@ -62,7 +62,7 @@ memory with any of the networking service protocols. |caution| Note that by default, the ``OSPL_URI`` environment variable refers to a *DDSI* configuration, so to see the extra performance and scalability - benefits of OpenSplice DDS's RTNetworking or DDSI2E it is + benefits of Vortex OpenSplice's RTNetworking or DDSI2E it is necessary to switch from the default. diff --git a/docs/html/EvaluationGuide/_sources/preface.txt b/docs/html/EvaluationGuide/_sources/preface.txt index 694b6b859..191ac8c74 100644 --- a/docs/html/EvaluationGuide/_sources/preface.txt +++ b/docs/html/EvaluationGuide/_sources/preface.txt @@ -10,8 +10,8 @@ Preface About the Evaluation & Benchmarking Guide ***************************************** -The *Evaluation & Benchmarking Guide* is the starting point -for anyone who wants to evaluate OpenSplice DDS. +The *Evaluation & Benchmarking Guide* is the starting point +for anyone who wants to evaluate Vortex OpenSplice. *This Evaluation Guide contains:* @@ -27,24 +27,24 @@ for anyone who wants to evaluate OpenSplice DDS. Conventions *********** -The icons shown below are used in PrismTech product documentation -to help readers to quickly identify information relevant to their +The icons shown below are used in ADLINK product documentation +to help readers to quickly identify information relevant to their specific use of OpenSplice. - ========= ================================================================== - *Icon* *Meaning* - ========= ================================================================== - |caution| Item of special significance or where caution needs to be taken. - |info| Item contains helpful hint or special information. - |windows| Information applies to Windows (*e.g.* XP, 2003, Windows 7) only. - |unix| Information applies to Unix-based systems (*e.g.* Solaris) only. - |linux| Information applies to Linux-based systems (*e.g.* Ubuntu) only. - |c| C language specific. - |cpp| C++ language specific. - |csharp| C# language specific. - |java| Java language specific. - ========= ================================================================== + ========= ================================================================== + *Icon* *Meaning* + ========= ================================================================== + |caution| Item of special significance or where caution needs to be taken. + |info| Item contains helpful hint or special information. + |windows| Information applies to Windows (*e.g.* XP, 2003, Windows 7) only. + |unix| Information applies to Unix-based systems (*e.g.* Solaris) only. + |linux| Information applies to Linux-based systems (*e.g.* Ubuntu) only. + |c| C language specific. + |cpp| C++ language specific. + |csharp| C# language specific. + |java| Java language specific. + ========= ================================================================== @@ -68,4 +68,3 @@ specific use of OpenSplice. .. |java| image:: ./images/icon-java.* :height: 6mm - \ No newline at end of file diff --git a/docs/html/EvaluationGuide/_sources/running.txt b/docs/html/EvaluationGuide/_sources/running.txt index dbfa2247b..436d6495c 100644 --- a/docs/html/EvaluationGuide/_sources/running.txt +++ b/docs/html/EvaluationGuide/_sources/running.txt @@ -1,48 +1,48 @@ -.. _`How to run OpenSplice Enterprise`: +. _`How to run Vortex OpenSplice`: ################################ -How to run OpenSplice Enterprise +How to run Vortex OpenSplice ################################ -.. _`The OpenSplice Enterprise Environment`: +.. _`The Vortex OpenSplice Environment`: ************************************* -The OpenSplice Enterprise Environment +The Vortex OpenSplice Environment ************************************* -A release file is provided with the OpenSplice Enterprise +A release file is provided with the Vortex OpenSplice installation which contains the environment variables that are required. -Create an OpenSplice Enterprise environment as follows. +Create an Vortex OpenSplice environment as follows. **First:** |linux| Open a shell and source the ``release.com`` file from - the OpenSplice Enterprise installation directory. + the Vortex OpenSplice installation directory. |windows| Open a *Windows Command prompt* and run the ``release.bat`` - file in the OpenSplice Enterprise installation directory. + file in the Vortex OpenSplice installation directory. |windows| - Alternatively, use the *OpenSplice DDS Command Prompt* + Alternatively, use the *Vortex OpenSplice Command Prompt* that can be accessed from the Windows *Start* menu (this will implicitly run ``release.bat``). |info| - Note that the OpenSplice Enterprise Launcher tool also provides a - ``Console`` option which sets up the OpenSplice Enterprise environment. + Note that the Vortex OpenSplice Launcher tool also provides a + ``Console`` option which sets up the Vortex OpenSplice environment. **Next:** -Set the ``OSPL_URI`` variable to refer to the OpenSplice Enterprise +Set the ``OSPL_URI`` variable to refer to the Vortex OpenSplice configuration that is required (see the section :ref:`How to select the Architectural Mode`). diff --git a/docs/html/EvaluationGuide/_sources/tests.txt b/docs/html/EvaluationGuide/_sources/tests.txt index 72abf0807..79cb110ed 100644 --- a/docs/html/EvaluationGuide/_sources/tests.txt +++ b/docs/html/EvaluationGuide/_sources/tests.txt @@ -4,20 +4,20 @@ Performance Tests and Examples ############################## -To make the evaluation process as easy as possible, OpenSplice -Enterprise is shipped with dedicated performance tests that can be -used to measure latency and throughput. The tests are simple and -clear, allowing the user to obtain performance results easily. +To make the evaluation process as easy as possible, Vortex OpenSplice +is shipped with dedicated performance tests that can be used to measure +latency and throughput. The tests are simple and clear, allowing the +user to obtain performance results easily. The easiest way to build and run the performance tests is to use the -OpenSplice Enterprise *Launcher* tool. In the *Examples* menu select the +Vortex OpenSplice *Launcher* tool. In the *Examples* menu select the specific example and the appropriate language and configuration. Click the *Compile Example* button and then *Run Example*. This will run the DDS applications, and if running with a shared memory configuration it will also manage the starting and stopping of -OpenSplice Enterprise. +Vortex OpenSplice. -OpenSplice Enterprise also provides dedicated performance testing +Vortex OpenSplice also provides dedicated performance testing scripts which: + Test multiple API bindings @@ -43,7 +43,7 @@ Application A to Application B and back again, so importantly it includes metrics for both data delivery and reception. The easiest way to build and run the performance tests is to use the -OpenSplice Enterprise *Launcher* tool as explained above. +Vortex OpenSplice *Launcher* tool as explained above. Alternatively, to manually build and run the round-trip performance test, for example for the ISO C++ API: @@ -52,7 +52,7 @@ test, for example for the ISO C++ API: .. code-block:: bash - # In an OpenSplice Enterprise environment: + # In an Vortex OpenSplice environment: cd $OSPL_HOME/examples/dcps/RoundTrip/isocpp make @@ -61,7 +61,7 @@ test, for example for the ISO C++ API: ./pong # If using shared memory do "ospl stop" - # In another OpenSplice Enterprise environment: + # In another Vortex OpenSplice environment: cd $OSPL_HOME/examples/dcps/RoundTrip/isocpp # If using shared memory do "ospl start" ./ping 20 100 @@ -74,16 +74,16 @@ test, for example for the ISO C++ API: .. code-block:: bat - # Load the OpenSplice DDS examples project solution + # Load the Vortex OpenSplice examples project solution # into Visual Studio and build the required projects - # In an OpenSplice Enterprise environment: + # In an Vortex OpenSplice environment: cd %OSPL_HOME%\examples\dcps\RoundTrip\isocpp # If using shared memory do "ospl start" pong.exe # If using shared memory do "ospl stop" - # In another OpenSplice Enterprise environment: + # In another Vortex OpenSplice environment: cd %OSPL_HOME%\examples\dcps\RoundTrip\isocpp # If using shared memory do "ospl start" ping.exe 20 100 @@ -124,7 +124,7 @@ it describes the ability of the DDS implementation to effectively deliver DDS data without data loss. As with the round-trip test, the easiest way to build and run the -throughput performance test is to use the OpenSplice Enterprise +throughput performance test is to use the Vortex OpenSplice *Launcher* tool. Alternatively, to manually build and run the throughput performance @@ -134,7 +134,7 @@ test, for example for the ISO C++ API: .. code-block:: bash - # In an OpenSplice Enterprise environment: + # In an Vortex OpenSplice environment: cd $OSPL_HOME/examples/dcps/Throughput/isocpp make cd $OSPL_HOME/examples/dcps/Throughput/isocpp @@ -142,7 +142,7 @@ test, for example for the ISO C++ API: ./publisher # If using shared memory do "ospl stop" - # In another In an OpenSplice Enterprise environment: + # In another In an Vortex OpenSplice environment: cd $OSPL_HOME/examples/dcps/Throughput/isocpp # If using shared memory do "ospl start" ./subscriber @@ -154,16 +154,16 @@ test, for example for the ISO C++ API: .. code-block:: bat - # Load the OpenSplice DDS examples project solution + # Load the Vortex OpenSplice examples project solution # into Visual Studio and build the required projects - # In an OpenSplice Enterprise environment: + # In an Vortex OpenSplice environment: cd %OSPL_HOME%\examples\dcps\Throughput\isocpp # If using shared memory do "ospl start" publisher.exe # If using shared memory do "ospl stop" - # In another OpenSplice Enterprise environment: + # In another Vortex OpenSplice environment: cd %OSPL_HOME%\examples\dcps\Throughput\isocpp # If using shared memory do "ospl start" subscriber.exe @@ -201,7 +201,7 @@ Achieving Maximum Throughput Where there is a requirement to support continuous flows or 'streams' of data with minimal overhead consider the use -of OpenSplice Streams. The ability to deliver potentially millions of +of Vortex OpenSplice Streams. The ability to deliver potentially millions of samples per second is realized by the Streams feature transparently batching (packing and queuing) the periodic samples. diff --git a/docs/html/EvaluationGuide/architectural.html b/docs/html/EvaluationGuide/architectural.html index 80f22133c..b15602efd 100644 --- a/docs/html/EvaluationGuide/architectural.html +++ b/docs/html/EvaluationGuide/architectural.html @@ -6,7 +6,7 @@ - 4. OpenSplice Architectural Modes — OpenSplice Evaluation and Benchmarking Guide + 4. Vortex OpenSplice Architectural Modes — OpenSplice Evaluation and Benchmarking Guide @@ -24,8 +24,8 @@ - - + +
    index
  • - next |
  • - previous |
  • OpenSplice Evaluation and Benchmarking Guide »
  • \ No newline at end of file diff --git a/docs/html/EvaluationGuide/basics.html b/docs/html/EvaluationGuide/basics.html index e057f4ea4..8a74a1777 100644 --- a/docs/html/EvaluationGuide/basics.html +++ b/docs/html/EvaluationGuide/basics.html @@ -6,7 +6,7 @@ - 3. OpenSplice Enterprise Basics — OpenSplice Evaluation and Benchmarking Guide + 3. Vortex OpenSplice Basics — OpenSplice Evaluation and Benchmarking Guide @@ -24,7 +24,7 @@ - + @@ -35,7 +35,7 @@

    Navigation

    index
  • - next |
  • Navigation
  • -
    -

    3. OpenSplice Enterprise Basics¶

    -

    OpenSplice Enterprise is configured using an XML configuration file. +

    +

    3. Vortex OpenSplice Basics¶

    +

    Vortex OpenSplice is configured using an XML configuration file. In this file, the user specifies the architectural model and the -OpenSplice Enterprise services that are to run when the DDS +Vortex OpenSplice services that are to run when the DDS infrastructure is started.

    The OSPL_URI environment variable refers to the specific XML configuration file that is used for the current deployment. The default value refers to the ospl.xml file located in the etc/config -directory of the OpenSplice Enterprise installation. The installation +directory of the Vortex OpenSplice installation. The installation directory itself can be referred to by the OSPL_HOME environment -variable. Please see The OpenSplice Enterprise Environment for -details of how to set up the OpenSplice Enterprise environment.

    +variable. Please see The Vortex OpenSplice Environment for +details of how to set up the Vortex OpenSplice environment.

    A number of other sample configuration files that can be used when -benchmarking OpenSplice Enterprise are also provided in +benchmarking Vortex OpenSplice are also provided in the etc/config directory.

    The OSPL_URI variable is of the form:

    @@ -77,7 +77,7 @@

    Navigation

    OpenSplice deployment are controlled by this file.

    info
    -
    The OpenSplice Enterprise Launcher tool assists with the +
    The Vortex OpenSplice Launcher tool assists with the selection of the OSPL_URI variable. There is a Configurations menu that lists the sample configuration files that are available.
    @@ -85,7 +85,7 @@

    Navigation

    The Launcher tool

    The Launcher tool

    -

    The OpenSplice Enterprise Launcher tool is also able to run the +

    The Vortex OpenSplice Launcher tool is also able to run the examples and performance tests that are described later in this document.

    @@ -104,7 +104,7 @@

    Previous topic

    title="previous chapter">2. Introduction

    Next topic

    4. OpenSplice Architectural Modes

    + title="next chapter">4. Vortex OpenSplice Architectural Modes

    This Page

    index
  • - next |
  • Navigation
  • \ No newline at end of file diff --git a/docs/html/EvaluationGuide/biblio.html b/docs/html/EvaluationGuide/biblio.html index 6ae94e9eb..0bdb2ef09 100644 --- a/docs/html/EvaluationGuide/biblio.html +++ b/docs/html/EvaluationGuide/biblio.html @@ -60,6 +60,15 @@

    Navigation

    +
    +
    OMG DDS 1.4
    +
    +
    Object Management Group,
    +
    ‘Data Distribution Service for Real-Time Systems Version 1.4’,
    +
    Available specification formal/15-04-10
    +
    +
    +
    OMG DDSI 2.1
    @@ -70,6 +79,16 @@

    Navigation

    +
    +
    OMG DDSI 2.2
    +
    +
    Object Management Group,
    +
    ‘The Real-Time Publish-Subscribe Wire Protocol DDS
    +
    Interoperability Wire Protocol Specification Version 2.2’,
    +
    Document Number: formal/2014-09-01
    +
    +
    +
    OMG DDS XTYPES 1.0
    @@ -134,7 +153,7 @@

    Navigation

    \ No newline at end of file diff --git a/docs/html/EvaluationGuide/contacts.html b/docs/html/EvaluationGuide/contacts.html index 16f175661..c6ae43c65 100644 --- a/docs/html/EvaluationGuide/contacts.html +++ b/docs/html/EvaluationGuide/contacts.html @@ -50,7 +50,7 @@

    Navigation

    10.1. Contacts¶

    -
    PrismTech Corporation
    +
    ADLINK Technology Corporation
    400 TradeCenter
    Suite 5900
    Woburn, MA
    @@ -59,31 +59,35 @@

    10.1. ContactsTel: +1 781 569 5819

    -
    PrismTech Limited
    -
    PrismTech House
    -
    5th Avenue Business Park
    +
    ADLINK Technology Limited
    +
    The Edge
    +
    5th Avenue
    +
    Team Valley
    Gateshead
    -
    NE11 0NG
    +
    NE11 0XA
    UK
    Tel: +44 (0)191 497 9900
    -
    PrismTech France
    +
    ADLINK Technology SARL
    28 rue Jean Rostand
    91400 Orsay
    France
    Tel: +33 (1) 69 015354
    -

    Web: http://www.prismtech.com

    -

    E-mail: info@prismtech.com

    +

    Web: http://ist.adlinktech.com/

    +

    Contact: http://ist.adlinktech.com

    +

    E-mail: ist_info@adlinktech.com

    +

    LinkedIn: https://www.linkedin.com/company/79111/

    +

    Twitter: https://twitter.com/ADLINKTech_usa

    +

    Facebook: https://www.facebook.com/ADLINKTECH

    10.2. Notices¶

    -

    Copyright © 2016 PrismTech Limited.

    -

    The information contained in this document is subject to change without notice and is -made available in good faith without liability on the part of PrismTech Limited or -PrismTech Corporation.

    -

    All trademarks acknowledged.

    +

    Copyright © 2018 ADLINK Technology Limited. All rights reserved.

    +

    This document may be reproduced in whole but not in part. The information contained in this +document is subject to change without notice and is made available in good faith without +liability on the part of ADLINK Technology Limited. All trademarks acknowledged.

    @@ -143,7 +147,7 @@

    Navigation

    \ No newline at end of file diff --git a/docs/html/EvaluationGuide/decisions.html b/docs/html/EvaluationGuide/decisions.html index dc74910ba..ea88ab117 100644 --- a/docs/html/EvaluationGuide/decisions.html +++ b/docs/html/EvaluationGuide/decisions.html @@ -24,8 +24,8 @@ - - + +

    index
  • - next |
  • - previous |
  • OpenSplice Evaluation and Benchmarking Guide »
  • \ No newline at end of file diff --git a/docs/html/EvaluationGuide/genindex.html b/docs/html/EvaluationGuide/genindex.html index 1df5be00a..50443a9b6 100644 --- a/docs/html/EvaluationGuide/genindex.html +++ b/docs/html/EvaluationGuide/genindex.html @@ -88,7 +88,7 @@

    Navigation

    \ No newline at end of file diff --git a/docs/html/EvaluationGuide/index.html b/docs/html/EvaluationGuide/index.html index 31f7ecb30..faf4e537a 100644 --- a/docs/html/EvaluationGuide/index.html +++ b/docs/html/EvaluationGuide/index.html @@ -55,20 +55,20 @@

    OpenSplice Evaluation & Benchmarking Guide2. Introduction -
  • 3. OpenSplice Enterprise Basics
  • -
  • 4. OpenSplice Architectural Modes
  • \ No newline at end of file diff --git a/docs/html/EvaluationGuide/introduction.html b/docs/html/EvaluationGuide/introduction.html index 0fa62e092..10a574e3a 100644 --- a/docs/html/EvaluationGuide/introduction.html +++ b/docs/html/EvaluationGuide/introduction.html @@ -24,7 +24,7 @@ - + @@ -35,7 +35,7 @@

    Navigation

    index
  • - next |
  • Navigation
  • 2. Introduction¶

    -

    One of the key differentiators of OpenSplice Enterprise is that it +

    One of the key differentiators of Vortex OpenSplice is that it provides a user with the ability to choose exactly how to deploy Data Distribution Service (DDS) applications, i.e. there are different DDS system architecture deployment modes and also different networking service protocols. This allows a user to maximize both intra-nodal and inter-nodal performance based on requirements specific to their -own use case. When evaluating OpenSplice Enterprise it is very +own use case. When evaluating Vortex OpenSplice it is very important to understand all of these features and benefits to ensure that the most appropriate combination is evaluated against your specific performance criteria. Once the performance figures have been observed the choice is usually clear.

    Every customer use case and set of requirements is different, so let -us briefly guide you through how to best deploy OpenSplice Enterprise +us briefly guide you through how to best deploy Vortex OpenSplice so that it meets and exceeds your expectations. Here we explain how -easy it is to get started with OpenSplice Enterprise and observe the -excellent performance and scalability it provides. OpenSplice -Enterprise is even shipped with dedicated performance tests that the -user can build and run easily.

    +easy it is to get started with Vortex OpenSplice and observe the +excellent performance and scalability it provides. Vortex OpenSplice +is even shipped with dedicated performance tests that the user can +build and run easily.

    Note that this Guide serves only as an introduction and does not -replace the full OpenSplice Enterprise reference and user guides.

    +replace the full Vortex OpenSplice reference and user guides.

    @@ -87,7 +87,7 @@

    Previous topic

    title="previous chapter">1. Preface

    Next topic

    3. OpenSplice Enterprise Basics

    + title="next chapter">3. Vortex OpenSplice Basics

    This Page

    index
  • - next |
  • Navigation
  • \ No newline at end of file diff --git a/docs/html/EvaluationGuide/networking.html b/docs/html/EvaluationGuide/networking.html index e3f16361e..ddca16d5d 100644 --- a/docs/html/EvaluationGuide/networking.html +++ b/docs/html/EvaluationGuide/networking.html @@ -6,7 +6,7 @@ - 5. OpenSplice Networking Options — OpenSplice Evaluation and Benchmarking Guide + 5. Vortex OpenSplice Networking Options — OpenSplice Evaluation and Benchmarking Guide @@ -25,7 +25,7 @@ - + \ No newline at end of file diff --git a/docs/html/GPBTutorial/genindex.html b/docs/html/GPBTutorial/genindex.html index a7012597c..18ee8fa83 100644 --- a/docs/html/GPBTutorial/genindex.html +++ b/docs/html/GPBTutorial/genindex.html @@ -88,7 +88,7 @@

    Navigation

    \ No newline at end of file diff --git a/docs/html/GPBTutorial/index.html b/docs/html/GPBTutorial/index.html index 9044a5bef..d5768a9c9 100644 --- a/docs/html/GPBTutorial/index.html +++ b/docs/html/GPBTutorial/index.html @@ -154,7 +154,7 @@

    Navigation

    \ No newline at end of file diff --git a/docs/html/GPBTutorial/introduction.html b/docs/html/GPBTutorial/introduction.html index a1bde98fd..cdfee4349 100644 --- a/docs/html/GPBTutorial/introduction.html +++ b/docs/html/GPBTutorial/introduction.html @@ -427,7 +427,7 @@

    Navigation

    \ No newline at end of file diff --git a/docs/html/GPBTutorial/preface.html b/docs/html/GPBTutorial/preface.html index 519f86dc9..39af8feb6 100644 --- a/docs/html/GPBTutorial/preface.html +++ b/docs/html/GPBTutorial/preface.html @@ -53,12 +53,12 @@

    Navigation

    1. Preface¶

    1.1. About the Vortex OpenSplice Google Protocol Buffers Tutorial¶

    -

    This OpenSplice GPB Tutorial is included with the OpenSplice DDS +

    This Vortex OpenSplice GPB Tutorial is included with the Vortex OpenSplice Documentation Set.

    It describes how to use the Vortex OpenSplice ISO C++ API and Java 5 API in combination with Google Protocol Buffers (GPB) data models.

    This Tutorial assumes that the user is already familiar with the -DDS API as well as the OpenSplice product.

    +DDS API as well as the Vortex OpenSplice product.

    Intended Audience

    This Guide is intended for anyone who wants to use Google Protocol Buffers for DDS in developing and running @@ -67,7 +67,7 @@

    1.1. About the Vortex OpenSplice Google Protocol Buffers Tutorial @@ -182,7 +182,7 @@

    Navigation

    \ No newline at end of file diff --git a/docs/html/GPBTutorial/proto-message.html b/docs/html/GPBTutorial/proto-message.html index 3ce48b3cc..5181aa436 100644 --- a/docs/html/GPBTutorial/proto-message.html +++ b/docs/html/GPBTutorial/proto-message.html @@ -333,7 +333,7 @@

    Navigation

    \ No newline at end of file diff --git a/docs/html/GPBTutorial/search.html b/docs/html/GPBTutorial/search.html index cd1e92903..135f3285a 100644 --- a/docs/html/GPBTutorial/search.html +++ b/docs/html/GPBTutorial/search.html @@ -95,7 +95,7 @@

    Navigation

    \ No newline at end of file diff --git a/docs/html/GPBTutorial/searchindex.js b/docs/html/GPBTutorial/searchindex.js index 54ae78d17..d996aabb5 100644 --- a/docs/html/GPBTutorial/searchindex.js +++ b/docs/html/GPBTutorial/searchindex.js @@ -1 +1 @@ -Search.setIndex({envversion:42,terms:{all:[7,5,4,1],concept:2,getinstancest:7,queri:[2,5],global:2,splicer:4,worksfor_nam:3,four:[2,7],signific:6,osplserviceenviron:7,fixed32:2,follow:[2,7],locat:[2,3,7],setemail:7,publicationmatchedstatu:7,"const":7,program:[2,4],datawriterqo:7,keylist:3,waittimeout:7,sourc:2,everi:5,string:[2,3,7,5,4],fals:[2,7,4],"void":7,faq:6,getaddress:7,util:7,person_phonetype_hom:7,facebook:4,affect:5,relev:6,createdatawrit:7,doesn:4,level:5,list:2,iter:7,correct:3,"try":7,item:6,pathtoprotoself:3,small:2,attachcondit:7,readcondhandl:7,datareaderqo:7,prevent:3,smaller:2,tel:1,getspi:7,uniqu:[2,5],outputpath:3,second:[3,7],ubiquit:2,personhandl:7,download:2,further:6,modifif:7,compat:5,what:7,hide:3,sub:7,neg:2,abl:5,invok:3,samplest:7,access:3,delet:3,version:2,"new":3,method:5,prismtech:[7,1],centric:2,deriv:7,addressdatawrit:2,privat:7,behaviour:2,studio:2,pub:7,solari:6,address:[2,3,7,5,4],path:3,dynam:[2,5],becom:[2,7],modifi:2,phone_s:7,valu:[2,5,4],wait:7,invis:7,search:0,not_alive_dispos:7,technolog:2,newwaitset:7,updatecount:7,cerr:7,behav:5,implement:[2,7],mix:4,via:3,createdatast:7,extra:[5,4],jar:3,modul:3,prefer:2,avenu:1,unix:6,"boolean":[2,7],visibl:2,instal:3,txt:2,mobil:[7,5,4],middlewar:2,set_address:7,from:[2,3,7],describ:[2,5,6],usa:1,messageopt:2,ddscpp_out:3,doubl:2,seamless:2,next:[2,7],few:2,mutable_phon:7,handler:7,call:[2,3],tradecent:1,taken:6,scope:[2,5],type:[0,4,3],tell:5,more:[2,5],plug:2,current_count:7,src:3,relat:2,phone:[7,5,4],visual:2,waitforcondit:7,particular:5,compani:7,unpack:2,sleep:7,must:[2,3,5],uint64:2,none:[7,4],retriev:3,err:7,hous:1,alia:4,work:[2,7,5,4],annot:[2,0],histori:[2,5],descriptor:[3,4],default_id:7,can:[2,3,5,4,6],aliv:7,overrid:2,tab:7,tar:2,give:[2,3,5,6],share:2,topic:7,caution:6,want:6,incom:7,serial:[2,3],unsign:[2,7],dcpsprotobuf:3,alwai:[2,5,4],end:7,rather:2,anoth:2,readcond:7,addphon:7,person_phonetype_mobil:7,set_typ:7,ageinyear:5,anyon:6,env:7,iso:[2,0,6,3],simpl:3,updat:[2,7],ne11:1,product:[2,6],protobuf:[2,0,3],after:[2,3],usabl:3,example_entrypoint:7,mai:[5,1],getnumb:7,datawrit:[3,7],const_iter:7,github:2,getdefaultdatawriterqo:7,third:3,setproperti:7,bind:2,proto:[0,4,3],explicit:2,correspond:7,assign:2,inform:[2,6,5,4,1],expectedupd:7,combin:[2,4,6],allow:[2,7,5],mechan:2,first:[2,3],order:[2,4],addresstypessupport:2,oper:7,help:6,withreli:7,over:4,printperson:7,janedo:7,still:5,"0ng":1,paramet:5,write:[2,7],typedef:3,getinst:7,group:2,createparticip:7,how:[2,5,6],polici:7,sfixed32:2,platform:2,window:[2,6],mail:1,main:7,them:2,good:1,hasphon:7,pbdd:7,thei:5,handl:[7,5],encod:2,overal:5,java_outer_classnam:2,msginstanc:7,"break":[2,7],worksfor_address:3,createdataread:7,introduct:0,term:7,name:[2,3,4],dcpssaj5:3,revert:4,separ:[2,5],easili:2,timeout:7,each:[2,3,5],found:[7,5,6],mean:[5,6],domain:[2,7,5],state_filt:7,getphonelist:7,individu:5,functor:7,ensur:2,"static":7,our:[7,5,4],dispos:7,special:6,out:7,variabl:[2,3],shown:[2,6],your:[2,3],content:2,rel:2,reader:[7,6],print:[7,4],uint32:2,integr:2,franc:1,iostream:7,insid:5,phonenumb:[7,5,4],migrat:2,differ:[2,5,4],argv:7,ineffici:2,println:7,nilhandl:7,base:[2,4,6],releas:[2,3],org:[2,3,7],"byte":2,argc:7,prefac:0,dcps_isocpp_protobuf_subscrib:7,thread:7,synchron:7,filter:[2,4],length:2,organis:7,think:2,currenttimemilli:7,origin:4,softwar:7,oni:2,directli:5,libprotobuf:2,getdefaultdatareaderqo:7,onc:[2,3],independ:2,number:[2,7,5,4],instruct:2,alreadi:6,done:2,getclassload:7,given:[2,3,5],convent:0,printstacktrac:7,getpolicyfactori:7,unknown:7,top:5,system:[0,4],messag:[2,0,4,3],tradition:2,citi:7,deploy:6,which:[2,3,7,5,6],termin:7,waitset:7,john:[7,4],"final":7,friend:[7,5,4],worksfor:7,option:[2,3,4],namespac:7,not_new:7,park:1,dataspac:2,specifi:[2,3],part:[2,7,1],pars:2,pragma:3,viewstat:7,sign:2,than:2,std:7,createpublish:7,provid:[2,3,6],structur:[2,7],store:[2,3],opaqu:2,sfixed64:2,seri:2,pre:3,setag:7,createtop:7,close:7,protobuf_hom:[2,3],withpolici:7,ani:[2,7,5],packag:[2,7,5,4],examplesleepmillisecond:7,have:2,deliv:[3,7],need:[2,3,5,4,6],requisit:3,"null":7,pathtoopenspliceprotocompil:3,ospl_protobuf_include_idl:3,built:5,lib:2,recompil:4,"switch":7,getsamplest:7,also:[2,3,5,6],gotham:7,build:[2,7],milli:7,environ:[2,3,4],getupdatecount:7,begin:7,distribut:2,clash:2,shall:5,buffer:3,set_email:7,mutable_worksfor:7,regular:2,eight:2,deploi:2,pair:2,"class":[2,3,7],icon:6,register_inst:7,sint64:2,doc:5,drqo:7,doe:[7,4],declar:5,printalldata:7,notion:2,dot:2,gdp:3,jane123:4,show:2,text:2,facebooknam:4,data_read:7,concurr:7,buildparti:7,dcps_isocpp_protobuf_publish:7,find:3,java_out:3,xml:2,current:[3,7],onli:[2,3,4,6],explicitli:2,layout:[2,5],copyright:[7,1],setnam:7,writer:7,solut:2,written:[3,7,5],should:5,busi:1,knowledg:[2,6],bool:[2,7,4],local:3,offici:2,flexibl:2,gettyp:7,get:4,familiar:6,stop:7,autom:2,cannot:2,protobufpublish:7,report:6,getpublicationmatchedstatu:7,requir:[2,7,5,4],bat:3,getemail:7,enabl:2,"public":7,common:7,contain:[2,3,6,5,1],where:[2,3,5,6],cpp_out:3,view:7,fieldnam:5,set:[2,3,6],previou:[3,5],xtype:2,"float":2,dwqo:7,see:7,full:7,person_phonenumb:7,result:[2,7,5],arg:7,reserv:7,subject:1,awar:[2,4],statu:7,detect:7,getworksfor:7,kei:[2,4],correctli:5,particip:7,label:5,state:7,won:2,publication_matched_statu:7,wayn:7,janedoebuild:7,between:2,"import":[2,7,5,4],approach:2,email:[7,5,4],attribut:[2,5],altern:2,omg:[3,4],extend:[2,3,5],web:1,hasnext:7,screen:7,rostand:1,sample_st:7,entir:3,set_ag:7,serviceenviron:7,timeunit:7,setaddress:7,endl:7,popul:3,last:3,somedomain:[7,4],license:7,samplecount:7,howev:4,hint:6,against:[2,4],chosen:3,audienc:6,instanc:[2,3,7,5],context:5,logic:2,com:[2,7,5,4,1],among:2,protoc:[2,3],stream:2,point:2,newbuild:7,ubuntu:6,dispatch:7,withanyinstancest:7,linux:[2,6],guid:6,assum:[3,6],new_view:7,liabil:1,addition:[2,3],trademark:1,been:[2,3],accessor:[2,3],secret:4,trigger:7,interpret:2,addit:6,not_alive_no_writ:7,quickli:6,convert:3,understand:4,togeth:3,fixed64:2,"catch":7,those:[2,5],"case":[2,0],contentfilteredtop:[2,5],servic:5,properti:4,durat:7,defin:[2,3,5],"while":[3,7],ospl_protobuf_data:[2,3],abov:[3,7],error:7,gateshead:1,stdout:7,setworksfor:7,"5th":1,has_phon:7,itself:6,cond:7,int32:[2,7,5,4],skype:4,"return":7,phonetyp:[7,5,4],ascii:2,attach:7,greater:2,develop:[5,6],grant:2,make:[2,5,4],format:2,classpath:3,same:[5,4],member:[2,4],interruptedexcept:7,document:[6,7,5,1],complet:2,finish:3,http:[2,5,1],withanysamplest:7,struct:3,createsubscrib:7,capabl:[2,5],to_year:7,temporari:3,user:[2,6],applic:[0,2,3,4,5,6],chang:[2,5,4,1],add_phon:7,descriptorproto:2,domainparticipantfactori:7,older:5,whole:1,builder:7,well:[2,6],object:2,person:[0,4,3],runtimeexcept:7,without:[2,1],command:3,thi:[1,2,3,5,6,7],undefin:[5,4],everyth:2,woburn:1,setphon:7,sint32:2,explan:5,identifi:[2,5,6],cout:7,view_stat:7,policyfactori:7,domainparticip:7,languag:[2,3,6],previous:2,note:2,octet:3,getag:7,easi:2,readcondit:7,fieldopt:2,except:7,param:7,add:4,other:[2,3],versa:3,appli:[2,6],els:7,dispose_inst:7,addressdataread:2,match:7,take:7,withanyviewst:7,vendor:3,protoc_gen_ddsjava:2,transpar:7,read:[2,7,4],protobufsubscrib:7,example_util:7,preconditionnotmeterror:7,getphon:7,bit:2,associ:7,licens:7,person_phonetype_work:7,loanedsampl:7,like:[2,4],corpor:[7,1],integ:5,getcurrentcount:7,vortex:[2,0,3],necessari:[2,4],either:5,manag:2,underli:7,jean:1,www:1,right:7,often:[2,4],captur:2,acknowledg:1,suppli:3,some:[5,4],instancehandl:7,sampl:7,proper:2,home:[7,5,4],successfulli:7,gpb_payload_t:3,ospl_hom:[3,7],manor:7,lead:5,normal:[3,4],definit:[2,3,5],protocol:3,protobuf_lib_hom:2,protofiletocompil:3,select:7,condit:7,reproduc:1,getnam:7,machin:3,core:7,set_nam:7,who:[2,6],run:[3,7,6],quit:2,"enum":[7,5,4],rue:1,step:2,pathtoprotofil:3,"throw":7,simpler:2,querycondit:[2,5],faith:1,about:0,zip:2,datast:7,int64:2,acm:7,page:0,instance_st:7,isocpp2:[3,7],block:7,own:[2,3,5],effici:2,absolut:2,opensplic:[2,0,3],within:7,waitforsubscrib:7,orsai:1,automat:[2,5],isocpp:7,empti:5,exampletimevaltomicrosecond:7,mark:[2,5],getmessag:7,implementation_class_name_properti:7,wai:5,support:[2,3,5],"long":[2,3,7,4],avail:[2,7,5,1],start:2,interfac:2,includ:[2,3,7,6],instancest:7,java_packag:2,jane:[7,4],timeoutexcept:7,etc:6,form:3,ddsjava_out:3,java5:[2,3,7],printphon:7,setnumb:7,examplegettim:7,settyp:7,getdata:7,"true":[3,7,5,4],bug:6,not_read:7,info:[7,1],absent:4,made:[2,1],utf:2,createinst:7,possibl:[2,4],"default":[2,7,5,4],until:7,record:2,below:[2,5,6],limit:[7,1],otherwis:7,embed:7,similar:2,reliabl:7,"int":[2,7],proto_path:3,"char":7,set_numb:7,exist:4,createreadcondit:7,fill:5,getkeyvalu:7,orgbuild:7,hpp:7,when:[2,4],detail:[5,6],invalid:7,field:[2,3,7,5,4],valid:7,role:7,futur:2,rememb:4,varieti:2,you:3,codegeneratorrequest:2,repeat:[7,5,4],intend:6,sequenc:[2,3,5],consid:2,faster:2,vice:3,directori:[2,3],getviewst:7,suit:1,dataread:[3,7],time:[7,4]},objtypes:{},objnames:{},filenames:["index","contacts","introduction","compiling-datamodel","evolving-data-models","proto-message","preface","using-generated-api"],titles:["DDS Java and C++ API Google Protocol Buffers Tutorial","7. Contacts & Notices","2. Introduction","4. Compiling the datamodel with the GPB compiler","6. Evolving data models","3. Proto message for a DDS system","1. Preface","5. Using the generated API in applications"],objects:{},titleterms:{compil:3,code:3,old:4,creat:3,map:2,indic:0,descriptor:2,api:[0,7],tempori:3,file:[3,5],tabl:0,protocol:[2,0,6],option:5,java:[0,7,3],opensplic:6,convent:6,proto:[2,5],system:[2,5],gpb:[2,3],contact:1,member:5,evolv:4,subscrib:[7,4],"new":4,introduct:2,instal:2,applic:7,messag:5,omg:[2,5],protobuf:7,kei:5,buffer:[2,0,6],gener:[3,7],usag:2,notic:1,instead:2,data:[2,3,7,4],googl:[2,0,6],"case":5,prefac:6,about:6,name:5,specif:3,plugin:3,type:[2,5],idl:[2,3],annot:5,exampl:[3,5],filter:5,person:5,vortex:6,tutori:[0,6],iso:7,model:[2,3,7,4],datamodel:3,publish:[7,4]}}) \ No newline at end of file +Search.setIndex({envversion:42,terms:{all:[7,5,4,1],concept:2,edg:1,queri:[2,5],global:2,splicer:4,worksfor_nam:3,four:[2,7],signific:6,osplserviceenviron:7,fixed32:2,follow:[2,7],getinstancest:7,setemail:7,publicationmatchedstatu:7,"const":7,program:[2,4],under:7,keylist:3,ist_info:1,waittimeout:7,sourc:2,everi:5,dcpsprotobuf:3,fals:[2,7,4],"void":7,faq:6,getaddress:7,util:7,person_phonetype_hom:7,facebook:[4,1],govern:7,affect:5,relev:6,createdatawrit:7,doesn:4,level:5,list:2,iter:7,correct:3,"try":7,item:6,team:1,small:2,attachcondit:7,readcondhandl:7,datareaderqo:7,still:5,prevent:3,impli:7,smaller:2,tel:1,buildparti:7,getspi:7,uniqu:[2,5],outputpath:3,second:[3,7],ubiquit:2,personhandl:7,download:2,further:6,modifif:7,compat:5,what:7,hide:3,sub:7,neg:2,abl:5,invok:3,samplest:7,access:3,delet:3,version:[2,7],"new":3,method:5,centric:2,deriv:7,addressdatawrit:2,privat:7,behaviour:2,studio:2,pub:7,solari:6,address:[2,3,7,5,4],path:3,"0xa":1,becom:[2,7],modifi:2,phone_s:7,valu:[2,5,4],wait:7,invis:7,search:0,not_alive_dispos:7,pbdd:7,technolog:[2,7,1],newwaitset:7,updatecount:7,cerr:7,behav:5,implement:[2,7],mix:4,via:3,createdatast:7,extra:[5,4],jar:3,modul:3,prefer:2,avenu:1,unix:6,"boolean":[2,7],visibl:2,instal:3,txt:2,mobil:[7,5,4],middlewar:2,set_address:7,from:[2,3,7],describ:[2,5,6],usa:1,messageopt:2,doubl:2,seamless:2,next:[2,7],few:2,mutable_phon:7,handler:7,call:[2,3],tradecent:1,taken:6,scope:[2,5],type:[0,4,3],tell:5,more:[2,5],plug:2,current_count:7,src:3,relat:2,phone:[7,5,4],visual:2,waitforcondit:7,particular:5,compani:[7,1],unpack:2,sleep:7,must:[2,3,5],uint64:2,none:[7,4],retriev:3,err:7,alia:4,work:[2,7,5,4],annot:[2,0],histori:[2,5],descriptor:[3,4],default_id:7,can:[2,3,5,4,6],aliv:7,overrid:2,tab:7,tar:2,give:[2,3,5,6],share:2,topic:7,caution:6,want:6,incom:7,serial:[2,3],unsign:[2,7],string:[2,3,7,5,4],alwai:[2,5,4],end:7,rather:2,anoth:2,readcond:7,addphon:7,person_phonetype_mobil:7,set_typ:7,ageinyear:5,anyon:6,env:7,iso:[2,0,6,3],simpl:3,updat:[2,7],ne11:1,product:[2,6],protobuf:[2,0,3],after:[2,3],usabl:3,example_entrypoint:7,mai:[7,5,1],getnumb:7,law:7,const_iter:7,github:2,getdefaultdatawriterqo:7,third:3,setproperti:7,bind:2,proto:[0,4,3],explicit:2,correspond:7,assign:2,inform:[2,6,5,4,1],expectedupd:7,combin:[2,4,6],allow:[2,7,5],mechan:2,first:[2,3],order:[2,4],addresstypessupport:2,oper:7,help:6,withreli:7,over:4,printperson:7,janedo:7,flexibl:2,dynam:[2,5],paramet:5,write:[2,7],typedef:3,getinst:7,group:2,createparticip:7,how:[2,5,6],polici:7,sfixed32:2,platform:2,window:[2,6],mail:1,main:7,them:2,good:1,hasphon:7,greater:2,thei:5,handl:[7,5],encod:2,overal:5,java_outer_classnam:2,msginstanc:7,"break":[2,7],worksfor_address:3,createdataread:7,introduct:0,warranti:7,protobufsubscrib:7,name:[2,3,4],dcpssaj5:3,revert:4,separ:[2,5],easili:2,timeout:7,each:[2,3,5],found:[7,5,6],mean:[5,6],domain:[2,7,5],state_filt:7,getphonelist:7,individu:5,functor:7,ensur:2,"static":7,our:[7,5,4],dispos:7,special:6,out:7,variabl:[2,3],shown:[2,6],your:[2,3],content:2,rel:2,reader:[7,6],print:[7,4],uint32:2,integr:2,franc:1,iostream:7,insid:5,phonenumb:[7,5,4],migrat:2,locat:[2,3,7],differ:[2,5,4],argv:7,ineffici:2,println:7,nilhandl:7,base:[2,4,6],releas:[2,3],org:[2,3,7],"byte":2,argc:7,basi:7,prefac:0,dcps_isocpp_protobuf_subscrib:7,thread:7,synchron:7,ist:1,filter:[2,4],length:2,organis:7,think:2,currenttimemilli:7,origin:4,softwar:7,oni:2,directli:5,libprotobuf:2,getdefaultdatareaderqo:7,onc:[2,3],independ:2,number:[2,7,5,4],instruct:2,alreadi:6,done:2,getclassload:7,agre:7,given:[2,3,5],convent:0,printstacktrac:7,getpolicyfactori:7,unknown:7,top:5,system:[0,4],messag:[2,0,4,3],tradition:2,citi:7,deploy:6,termin:7,waitset:7,john:[7,4],"final":7,friend:[7,5,4],worksfor:7,option:[2,3,4],namespac:7,not_new:7,set_email:7,dataspac:2,specifi:[2,3],part:[2,7,1],pars:2,pragma:3,viewstat:7,sign:2,than:2,pathtoprotoself:3,std:7,createpublish:7,kind:7,provid:[2,3,6],structur:[2,7],store:[2,3],opaqu:2,sfixed64:2,seri:2,pre:3,setag:7,createtop:7,protobuf_hom:[2,3],withpolici:7,ani:[2,7,5],packag:[2,7,5,4],examplesleepmillisecond:7,have:2,deliv:[3,7],need:[2,3,5,4,6],requisit:3,"null":7,pathtoopenspliceprotocompil:3,ospl_protobuf_include_idl:3,built:5,lib:2,recompil:4,"switch":7,getsamplest:7,also:[2,3,5,6],gotham:7,build:[2,7],milli:7,environ:[2,3,4],getupdatecount:7,begin:7,copi:7,unless:7,distribut:[2,7],clash:2,shall:5,buffer:3,mutable_worksfor:7,regular:2,eight:2,deploi:2,pair:2,"class":[2,3,7],icon:6,register_inst:7,sint64:2,doc:5,drqo:7,doe:[7,4],declar:5,printalldata:7,notion:2,dot:2,adlink:[7,1],gdp:3,jane123:4,show:2,text:2,facebooknam:4,data_read:7,concurr:7,permiss:7,dcps_isocpp_protobuf_publish:7,find:3,java_out:3,xml:2,current:[3,7],onli:[2,3,4,6],explicitli:2,layout:[2,5],copyright:[7,1],setnam:7,writer:7,solut:2,written:[3,7,5],should:5,knowledg:[2,6],bool:[2,7,4],local:3,offici:2,gettyp:7,get:4,familiar:6,express:7,stop:7,autom:2,cannot:2,protobufpublish:7,report:6,getpublicationmatchedstatu:7,requir:[2,7,5,4],bat:3,getemail:7,enabl:2,"public":7,common:7,contain:[2,3,6,5,1],where:[2,3,5,6],cpp_out:3,view:7,fieldnam:5,set:[2,3,6],previou:[3,5],xtype:2,"float":2,dwqo:7,see:7,datast:7,person_phonenumb:7,result:[2,7,5],arg:7,reserv:[7,1],close:7,subject:1,awar:[2,4],statu:7,detect:7,getworksfor:7,kei:[2,4],correctli:5,particip:7,label:5,state:7,won:2,publication_matched_statu:7,wayn:7,janedoebuild:7,between:2,"import":[2,7,5,4],approach:2,email:[7,5,4],attribut:[2,5],altern:2,omg:[3,4],extend:[2,3,5],web:1,hasnext:7,screen:7,condit:7,rostand:1,sample_st:7,entir:3,set_ag:7,serviceenviron:7,timeunit:7,setaddress:7,endl:7,popul:3,last:3,easi:2,samplecount:7,howev:4,hint:6,against:[2,4],chosen:3,audienc:6,instanc:[2,3,7,5],context:5,logic:2,com:[2,7,5,4,1],among:2,protoc:[2,3],stream:2,point:2,newbuild:7,ubuntu:6,dispatch:7,withanyinstancest:7,datawrit:[3,7],linux:[2,6],guid:6,assum:[3,6],new_view:7,liabil:1,sarl:1,addition:[2,3],trademark:1,been:[2,3],accessor:[2,3],secret:4,trigger:7,interpret:2,addit:6,not_alive_no_writ:7,quickli:6,convert:3,apach:7,understand:4,togeth:3,fixed64:2,"catch":7,those:[2,5],"case":[2,0],contentfilteredtop:[2,5],servic:5,properti:4,durat:7,defin:[2,3,5],"while":[3,7],ospl_protobuf_data:[2,3],abov:[3,7],error:7,gateshead:1,stdout:7,setworksfor:7,"5th":1,linkedin:1,has_phon:7,itself:6,cond:7,int32:[2,7,5,4],skype:4,"return":7,phonetyp:[7,5,4],ascii:2,attach:7,ddscpp_out:3,develop:[5,6],grant:2,make:[2,5,4],format:2,classpath:3,same:[5,4],member:[2,4],interruptedexcept:7,document:[6,7,5,1],complet:2,finish:3,http:[2,7,5,1],withanysamplest:7,struct:3,adlinktech:1,capabl:[2,5],to_year:7,temporari:3,user:[2,6],applic:[0,2,3,4,5,6],chang:[2,5,4,1],add_phon:7,descriptorproto:2,domainparticipantfactori:7,older:5,whole:1,builder:7,well:[2,6],object:2,person:[0,4,3],runtimeexcept:7,without:[2,7,1],command:3,thi:[1,2,3,5,6,7],undefin:[5,4],everyth:2,woburn:1,setphon:7,sint32:2,explan:5,identifi:[2,5,6],cout:7,view_stat:7,policyfactori:7,obtain:7,domainparticip:7,languag:[2,3,7,6],previous:2,note:2,octet:3,getag:7,somedomain:[7,4],readcondit:7,fieldopt:2,except:7,param:7,add:4,other:[2,3],versa:3,appli:[2,6],els:7,dispose_inst:7,addressdataread:2,match:7,take:7,withanyviewst:7,vendor:3,which:[2,3,7,5,6],transpar:7,read:[2,7,4],createsubscrib:7,example_util:7,preconditionnotmeterror:7,getphon:7,bit:2,associ:7,licens:7,person_phonetype_work:7,loanedsampl:7,like:[2,4],corpor:[7,1],integ:5,getcurrentcount:7,vortex:[2,0,3],necessari:[2,4],either:[7,5],manag:2,underli:7,jean:1,www:[7,1],right:[7,1],often:[2,4],captur:2,acknowledg:1,twitter:1,suppli:3,some:[5,4],instancehandl:7,sampl:7,proper:2,home:[7,5,4],successfulli:7,affili:7,gpb_payload_t:3,ospl_hom:3,manor:7,lead:5,normal:[3,4],definit:[2,3,5],protocol:3,protobuf_lib_hom:2,protofiletocompil:3,select:7,datawriterqo:7,reproduc:1,getnam:7,machin:3,core:7,set_nam:7,who:[2,6],run:[3,7,6],quit:2,"enum":[7,5,4],rue:1,step:2,pathtoprotofil:3,"throw":7,simpler:2,querycondit:[2,5],faith:1,about:0,zip:2,int64:2,acm:7,page:0,instance_st:7,isocpp2:[3,7],adlinktech_usa:1,block:7,own:[2,3,5],effici:2,absolut:2,opensplic:[2,0,3],within:7,waitforsubscrib:7,orsai:1,automat:[2,5],isocpp:7,empti:5,exampletimevaltomicrosecond:7,mark:[2,5],getmessag:7,implementation_class_name_properti:7,complianc:7,wai:5,support:[2,3,5],vallei:1,"long":[2,3,7,4],avail:[2,7,5,1],start:2,interfac:2,includ:[2,3,7,6],instancest:7,java_packag:2,jane:[7,4],timeoutexcept:7,etc:6,form:3,ddsjava_out:3,java5:[2,3,7],printphon:7,setnumb:7,examplegettim:7,settyp:7,getdata:7,"true":[3,7,5,4],bug:6,not_read:7,info:7,absent:4,made:[2,1],utf:2,createinst:7,possibl:[2,4],"default":[2,7,5,4],protoc_gen_ddsjava:2,until:7,record:2,below:[2,5,6],limit:[7,1],otherwis:7,embed:7,similar:2,reliabl:7,"int":[2,7],proto_path:3,"char":7,set_numb:7,exist:4,createreadcondit:7,fill:5,getkeyvalu:7,orgbuild:7,hpp:7,when:[2,4],detail:[5,6],invalid:7,field:[2,3,7,5,4],valid:7,role:7,futur:2,rememb:4,varieti:2,you:[3,7],codegeneratorrequest:2,repeat:[7,5,4],intend:6,sequenc:[2,3,5],consid:2,faster:2,vice:3,directori:[2,3],getviewst:7,suit:1,dataread:[3,7],time:[7,4],licensor:7},objtypes:{},objnames:{},filenames:["index","contacts","introduction","compiling-datamodel","evolving-data-models","proto-message","preface","using-generated-api"],titles:["DDS Java and C++ API Google Protocol Buffers Tutorial","7. Contacts & Notices","2. Introduction","4. Compiling the datamodel with the GPB compiler","6. Evolving data models","3. Proto message for a DDS system","1. Preface","5. Using the generated API in applications"],objects:{},titleterms:{compil:3,code:3,old:4,creat:3,map:2,indic:0,descriptor:2,api:[0,7],tempori:3,file:[3,5],tabl:0,protocol:[2,0,6],option:5,java:[0,7,3],opensplic:6,convent:6,proto:[2,5],system:[2,5],gpb:[2,3],contact:1,member:5,evolv:4,subscrib:[7,4],"new":4,introduct:2,instal:2,applic:7,messag:5,omg:[2,5],protobuf:7,kei:5,buffer:[2,0,6],gener:[3,7],usag:2,notic:1,instead:2,data:[2,3,7,4],googl:[2,0,6],"case":5,prefac:6,about:6,name:5,specif:3,plugin:3,type:[2,5],idl:[2,3],annot:5,exampl:[3,5],filter:5,person:5,vortex:6,tutori:[0,6],iso:7,model:[2,3,7,4],datamodel:3,publish:[7,4]}}) \ No newline at end of file diff --git a/docs/html/GPBTutorial/using-generated-api.html b/docs/html/GPBTutorial/using-generated-api.html index 172fbef8b..42561c787 100644 --- a/docs/html/GPBTutorial/using-generated-api.html +++ b/docs/html/GPBTutorial/using-generated-api.html @@ -398,19 +398,20 @@

    5.3. ISO-C++examples/protobuf/isocpp2.

    /*
    - *                         OpenSplice DDS
    + *                         Vortex OpenSplice
      *
    - *   This software and documentation are Copyright 2006 to TO_YEAR PrismTech
    - *   Limited, its affiliated companies and licensors. All rights reserved.
    + *   This software and documentation are Copyright 2006 to TO_YEAR ADLINK
    + *   Technology Limited, its affiliated companies and licensors. All rights
    + *   reserved.
      *
    - *   Licensed under the Apache License, Version 2.0 (the "License");
    + *   Licensed under the Apache License, Version 2.0 (the "License");
      *   you may not use this file except in compliance with the License.
      *   You may obtain a copy of the License at
      *
      *       http://www.apache.org/licenses/LICENSE-2.0
      *
      *   Unless required by applicable law or agreed to in writing, software
    - *   distributed under the License is distributed on an "AS IS" BASIS,
    + *   distributed under the License is distributed on an "AS IS" BASIS,
      *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      *   See the License for the specific language governing permissions and
      *   limitations under the License.
    @@ -746,7 +747,7 @@ 

    Navigation

    \ No newline at end of file diff --git a/docs/html/GettingStartedGuide/_images/Launcher-starting.png b/docs/html/GettingStartedGuide/_images/Launcher-starting.png index 037e76f45..8132e8f0d 100644 Binary files a/docs/html/GettingStartedGuide/_images/Launcher-starting.png and b/docs/html/GettingStartedGuide/_images/Launcher-starting.png differ diff --git a/docs/html/GettingStartedGuide/_images/Launcher-utility.png b/docs/html/GettingStartedGuide/_images/Launcher-utility.png index e0864c396..4fb77644c 100644 Binary files a/docs/html/GettingStartedGuide/_images/Launcher-utility.png and b/docs/html/GettingStartedGuide/_images/Launcher-utility.png differ diff --git a/docs/html/GettingStartedGuide/_sources/about-ospl.txt b/docs/html/GettingStartedGuide/_sources/about-ospl.txt index b80aa4919..5c61ec360 100644 --- a/docs/html/GettingStartedGuide/_sources/about-ospl.txt +++ b/docs/html/GettingStartedGuide/_sources/about-ospl.txt @@ -1,4 +1,4 @@ -.. _`About OpenSplice`: +.. _`About Vortex OpenSplice`: ####################### About Vortex Opensplice @@ -71,9 +71,9 @@ time--even in the *largest-scale mission- and business-critical systems*. typical 'stream' data -Please go to http://www.prismtech.com to obtain evaluation copies of -Vortex OpenSplice, and http://www.opensplice.org for free downloads of the -community version. +Please go to http://ist.adlinktech.com/ to obtain evaluation copies of +Vortex OpenSplice, and http://ist.adlinktech.com/dds-community for free downloads of the +DDS Community Edition. ****************************** @@ -93,7 +93,7 @@ networking (providing QoS driven real-time networking based on multiple reliable multicast \`channels'), durability (providing fault tolerant storage for both real-time \`state' data as well as persistent \`settings'), and remote control & monitoring \`soap service' (providing -remote web based access using the SOAP protocol from the OpenSplice DDS +remote web based access using the SOAP protocol from the Vortex OpenSplice Tuner tools). @@ -106,7 +106,7 @@ administration still provides each subscriber with his own private \`view' on this data. This allows a subscriber's data cache to be perceived as an individual \`database' that can be content-filtered, queried, etc. (using the content-subscription profile as supported by -OpenSplice DDS). This shared-memory architecture results in an extremely +Vortex OpenSplice). This shared-memory architecture results in an extremely small footprint, excellent scalability and optimal performance when compared to implementations where each reader/writer are \`communication endpoints' each with its own storage (in other words, historical data @@ -116,7 +116,7 @@ moved, even within the same physical node. Configuration ============= - + Vortex OpenSplice is highly configurable, even allowing the architectural structure of the DDS middleware to be chosen by the user at deployment time. Vortex OpenSplice can be configured to run using a *shared memory* @@ -124,7 +124,7 @@ architecture, where both the DDS related administration (including the optional pluggable services) and DDS applications interface directly with shared memory. Alternatively, Vortex OpenSplice also supports a *single process* library architecture, where one or more DDS -applications, together with the OpenSplice administration and services, +applications, together with the Vortex OpenSplice administration and services, can all be grouped into a single operating system process. Both deployment modes support a configurable and extensible set of services, providing functionality such as: @@ -137,7 +137,7 @@ providing functionality such as: data as well as persistent settings + *remote control and monitoring SOAP service* - providing remote web-based - access using the SOAP protocol from the OpenSplice Tuner tool + access using the SOAP protocol from the Vortex OpenSplice Tuner tool + *dbms service* - providing a connection between the real-time and the enterprise domain by bridging data from DDS to DBMS and *vice versa* @@ -157,7 +157,7 @@ depends on the user's exact requirements and DDS scenario. Single Process Library Architecture *********************************** -This deployment allows the DDS applications and OpenSplice +This deployment allows the DDS applications and Vortex OpenSplice administration to be contained together within one single operating system process. This single process deployment option is most useful in environments where shared memory is unavailable or undesirable. As @@ -190,16 +190,16 @@ The Single Process deployment is the default architecture provided within Vortex OpenSplice and allows for easy deployment with minimal configuration required for a running DDS system. -The figure `The OpenSplice Single Process Architecture`_ +The figure `The Vortex OpenSplice Single Process Architecture`_ shows an overview of the single process architecture of Vortex OpenSplice. -.. _`The OpenSplice Single Process Architecture`: +.. _`The Vortex OpenSplice Single Process Architecture`: .. figure:: /images/SingleProcessArchitecture.png :height: 70mm - :alt: The OpenSplice Single Process Architecture + :alt: The Vortex OpenSplice Single Process Architecture - **The OpenSplice Single Process Architecture** + **The Vortex OpenSplice Single Process Architecture** ************************** @@ -209,10 +209,10 @@ Shared Memory architecture In the shared memory architecture data is physically present only once on any machine but smart administration still provides each subscriber with his own private view on this data. Both the DDS applications and -OpenSplice administration interface directly with the shared memory -which is created by the OpenSplice daemon on start up. This architecture +Vortex OpenSplice administration interface directly with the shared memory +which is created by the Vortex OpenSplice daemon on start up. This architecture enables a subscriber's data cache to be seen as an individual database -and the content can be filtered, queried, etc. by using the OpenSplice +and the content can be filtered, queried, etc. by using the Vortex OpenSplice content subscription profile. Typically for advanced DDS users, the shared memory architecture is a @@ -223,32 +223,32 @@ each with its own storage (*i.e.* historical data both at reader and writer) and where the data itself still has to be moved, even within the same platform. -The figure `The OpenSplice Shared Memory Architecture`_ -shows an overview of the shared memory architecture of +The figure `The Vortex OpenSplice Shared Memory Architecture`_ +shows an overview of the shared memory architecture of Vortex OpenSplice on *one* computing node. Typically, there are *many* nodes within a system. -.. _`The OpenSplice Shared Memory Architecture`: +.. _`The Vortex OpenSplice Shared Memory Architecture`: .. figure:: /images/SharedMemoryArchitecture.png :height: 70mm - :alt: The OpenSplice Shared Memory Architecture - - **The OpenSplice Shared Memory Architecture** + :alt: The Vortex OpenSplice Shared Memory Architecture + + **The Vortex OpenSplice Shared Memory Architecture** -************************************ +*************************************** Vortex OpenSplice Features and Benefits -************************************ +*************************************** The table below shows the following aspects of Vortex OpenSplice, where: - *Features* are significant characteristics of OpenSplice + *Features* are significant characteristics of Vortex OpenSplice *Advantages* shows why a feature is important - *Benefits* describes how users of OpenSplice can exploit the advantages + *Benefits* describes how users of Vortex OpenSplice can exploit the advantages +----------------+-------------------+--------------------------+-------+ @@ -366,7 +366,7 @@ aspects of Vortex OpenSplice, where: Conclusion ********** -PrismTech's Vortex OpenSplice product complemented by its tool support +ADLINK's Vortex OpenSplice product complemented by its tool support together encompass the industry's most profound expertise on the OMG's DDS standard and products. diff --git a/docs/html/GettingStartedGuide/_sources/contacts.txt b/docs/html/GettingStartedGuide/_sources/contacts.txt index 53613a9d7..d32f6016f 100644 --- a/docs/html/GettingStartedGuide/_sources/contacts.txt +++ b/docs/html/GettingStartedGuide/_sources/contacts.txt @@ -1,49 +1 @@ -.. _`Contacts & Notices`: - -################## -Contacts & Notices -################## - -******** -Contacts -******** - -| **PrismTech Corporation** -| 400 TradeCenter -| Suite 5900 -| Woburn, MA -| 01801 -| USA -| Tel: +1 781 569 5819 - -| **PrismTech Limited** -| PrismTech House -| 5th Avenue Business Park -| Gateshead -| NE11 0NG -| UK -| Tel: +44 (0)191 497 9900 - -| **PrismTech France** -| 28 rue Jean Rostand -| 91400 Orsay -| France -| Tel: +33 (1) 69 015354 - - -Web: http://www.prismtech.com - -E-mail: \info@prismtech.com - -******* -Notices -******* - -**Copyright** © 2016 PrismTech Limited. All rights reserved. - -*This document may be reproduced in whole but not in part. -The information contained in this document is subject to change without notice and is made available in good faith without liability on the part of PrismTech Limited or PrismTech Corporation. -All trademarks acknowledged.* - -Doc Issue 01, 24 March 2015 - +.. include:: ../../common/contacts.rst diff --git a/docs/html/GettingStartedGuide/_sources/documentation.txt b/docs/html/GettingStartedGuide/_sources/documentation.txt index cb14e47b4..329a7665c 100644 --- a/docs/html/GettingStartedGuide/_sources/documentation.txt +++ b/docs/html/GettingStartedGuide/_sources/documentation.txt @@ -27,9 +27,10 @@ Vortex OpenSplice Documentation Set | | who need to be aware of the latest changes which may | | | affect the Service's performance and usage. | | | A link to the Release Notes is in ``index.html`` | -| | located in the directory where OpenSplice is installed. | +| | located in the directory where Vortex OpenSplice is | +| | installed. | +--------------+---------------------------------------------------------+ -| Getting | General information about OpenSplice, including | +| Getting | General information about Vortex OpenSplice, including | | Started | installation instructions, initial configuration | | Guide | requirements and instructions for running the | | | Opensplice examples on supported platforms. | @@ -37,27 +38,27 @@ Vortex OpenSplice Documentation Set | | For managers, administrators, and developers | | | to gain an initial understanding of the product, | | | as well as for product installers for | -| | installing and administering OpenSplice. | +| | installing and administering Vortex OpenSplice. | | | | | | *Essential reading for users new to DDS.* | +--------------+---------------------------------------------------------+ | Evaluation | A short guide to help new users evaluate Vortex | | Guide | OpenSplice. | +--------------+---------------------------------------------------------+ -| Tutorial | A short course on developing applications with | +| Tutorial | A short course on developing applications with Vortex | | Guide | OpenSplice. Includes example code in C, C++ and Java. | +--------------+---------------------------------------------------------+ | Deployment | *A complete reference on how to configure and | -| Guide | tune the OpenSplice service.* | +| Guide | tune the Vortex OpenSplice service.* | +--------------+---------------------------------------------------------+ | Tuner | Describes how to use the Tuner tool for monitoring | | Guide | and controlling Opensplice. | | | | | | For programmers, testers, system designers and | -| | system integrators using OpenSplice. | +| | system integrators using Vortex OpenSplice. | +--------------+---------------------------------------------------------+ -| IDL Pre-\ | Describes how to use the Opensplice IDL pre-processor | -| processor | for C, C++ and Java. | +| IDL Pre-\ | Describes how to use the Vortex Opensplice IDL | +| processor | pre-processor for C, C++ and Java. | | Guide | | +--------------+---------------------------------------------------------+ | OpenSplice | Provides a complete reference on how to configure the | @@ -92,22 +93,22 @@ Vortex OpenSplice Documentation Set | | | +--------------+---------------------------------------------------------+ | RMI over DDS | Explains how to take advantage of the client/server | -| Getting | interaction paradigm provided by OpenSplice RMI | +| Getting | interaction paradigm provided by Vortex OpenSplice RMI | | Started | layered over the publish/subscribe paradigm of | | Guide | Vortex OpenSplice. | +--------------+---------------------------------------------------------+ | Streams User | Explains the Streams API where continuous flows or | -| Guide | ‘streams’ of data have to be transported with minimal | +| Guide | streams of data have to be transported with minimal | | | overhead and therefore maximal achievable throughput. | +--------------+---------------------------------------------------------+ | GPB User | Explains how to use Google Protocol Buffers with the | | Guide | new ISO C++ and Java 5 APIs. | +--------------+---------------------------------------------------------+ -| Record and | Explains how to configure and use the Record and Replay | +| Record and | Explains how to configure and use the Record and Replay | | Replay | Service. | | Service Guide| | +--------------+---------------------------------------------------------+ -| Security User| Explains how to configure security when using the | +| Security User| Explains how to configure security when using the | | Configuration| Real Time Native Networking Protocol. | | Guide | | +--------------+---------------------------------------------------------+ @@ -119,14 +120,14 @@ Vortex OpenSplice Documentation Set | | and used. | | | | | | Documentation for the examples can be found in the | -| | OpenSplice Release Notes. | +| | Vortex OpenSplice Release Notes. | +--------------+---------------------------------------------------------+ | White Papers | Technical papers providing information about | | and Data | Vortex Opensplice. | | Sheets | | | | These technical papers are in PDF format and they | -| | can be obtained from the PrismTech web site at | -| | http://www.prismtech.com | +| | can be obtained from the ADLINK web site at | +| | http://ist.adlinktech.com/ | +--------------+---------------------------------------------------------+ @@ -137,32 +138,32 @@ Information Sources Product Information =================== -Links to useful technical information for PrismTech's products, +Links to useful technical information for ADLINK's products, including the Vortex OpenSplice and associated components, are listed below. |caution| These links are provided for the reader's convenience and may become - out-of-date if changes are made on the PrismTech Web site after + out-of-date if changes are made on the ADLINK Web site after publication of this guide. Nonetheless, these links should still be - reachable from the main PrismTech Web page located at - http://www.prismtech.com. + reachable from the main ADLINK Web page located at + http://ist.adlinktech.com/. Knowledge Base ============== -The PrismTech Knowledge Base is a collection of documents and resources -intended to assist our customers in getting the most out of the +The ADLINK Knowledge Base is a collection of documents and resources +intended to assist our customers in getting the most out of the Vortex OpenSplice products. The Knowledge Base has the most up-to-date information about bug fixes, product issues and technical support for difficulties that you may experience. The Knowledge Base can be found at: - http://www.prismtech.com/knowledge-base + http://ist.adlinktech.com/knowledge-base @@ -171,25 +172,25 @@ Additional Technical Information Information provided by independent publishers, newsgroups, web sites, and organisations, such as the Object Management Group, can be found on -the Prismtech Web site: +the ADLINK Web site: - http://www.prismtech.com + http://ist.adlinktech.com/ ******* Support ******* -PrismTech provides a range of product support, consultancy and +ADLINK provides a range of product support, consultancy and educational programmes to help you from product evaluation and -development, through to deployment of applications using OpenSplice DDS. +development, through to deployment of applications using Vortex OpenSplice. The support programmes are designed to meet customers' particular needs and range from a basic Standard programme to the Gold programme, which provides comprehensive, 24 x 7 support. -Detailed information about PrismTech's product support services, general -support contacts and enquiries are described on the PrismTech Support -page reached via the PrismTech Home page at http://www.prismtech.com. +Detailed information about ADLINK's product support services, general +support contacts and enquiries are described on the ADLINK Support +page reached via the ADLINK Home page at http://ist.adlinktech.com/. diff --git a/docs/html/GettingStartedGuide/_sources/elinos.txt b/docs/html/GettingStartedGuide/_sources/elinos.txt index c8b6f334e..7c70eb55a 100644 --- a/docs/html/GettingStartedGuide/_sources/elinos.txt +++ b/docs/html/GettingStartedGuide/_sources/elinos.txt @@ -5,7 +5,7 @@ ELinOS ###### -*This chapter provides notes about deploying OpenSplice DDS on ELinOS.* +*This chapter provides notes about deploying Vortex OpenSplice on ELinOS.* **************** diff --git a/docs/html/GettingStartedGuide/_sources/index.txt b/docs/html/GettingStartedGuide/_sources/index.txt index 59e507f61..4444929d0 100644 --- a/docs/html/GettingStartedGuide/_sources/index.txt +++ b/docs/html/GettingStartedGuide/_sources/index.txt @@ -8,7 +8,7 @@ OpenSplice Getting Started Guide .. toctree:: :maxdepth: 2 :numbered: - + preface about-ospl product-info @@ -27,7 +27,7 @@ OpenSplice Getting Started Guide unixarm elinos contacts - + Indices and tables ================== diff --git a/docs/html/GettingStartedGuide/_sources/install-configure.txt b/docs/html/GettingStartedGuide/_sources/install-configure.txt index adb47d444..c9d899edd 100644 --- a/docs/html/GettingStartedGuide/_sources/install-configure.txt +++ b/docs/html/GettingStartedGuide/_sources/install-configure.txt @@ -5,7 +5,7 @@ Installation and Configuration ############################## *Follow the instructions in this chapter to install and configure -Vortex OpenSplice and its tools. Information on running the OpenSplice +Vortex OpenSplice and its tools. Information on running the Vortex OpenSplice examples are provided at the end of the chapter under* `Examples`_. @@ -14,14 +14,12 @@ Vortex OpenSplice Development and Run-Time ****************************************** Vortex OpenSplice is provided in two installers. The **HDE** (Host -Development Environment) is the standard and it requires approximately -60 Mb of disk space after installation; the **RTS** (Run Time System) -requires approximately 35 Mb of disk space. +Development Environment) is the standard and the **RTS** (Run Time System). The HDE contains all of the services, libraries, header files and tools -needed to develop applications using OpenSplice, and the RTS is a subset +needed to develop applications using Vortex OpenSplice, and the RTS is a subset of the HDE which contains all of the services, libraries and tools -needed to deploy applications using OpenSplice. +needed to deploy applications using Vortex OpenSplice. .. _`Installation for UNIX and Windows Platforms`: @@ -31,7 +29,7 @@ Installation for UNIX and Windows Platforms This section describes the normal procedure to install Vortex OpenSplice on a UNIX or Windows platform. The exception is the procedure to install -Vortex OpenSplice on a UNIX ARM platform which is described in section :ref:`UNIX ARM platform` +Vortex OpenSplice on a UNIX ARM platform which is described in section :ref:`UNIX ARM platform` **Step 1** @@ -44,7 +42,7 @@ Vortex OpenSplice on a UNIX ARM platform which is described in section :ref:`UNI where, some being optional, - ** - PrismTech's code for the platform + ** - ADLINK's code for the platform ** - the Vortex OpenSplice version number, for example ``V6.0`` @@ -76,7 +74,7 @@ Vortex OpenSplice on a UNIX ARM platform which is described in section :ref:`UNI *Configure the Vortex OpenSplice environment variables.* (This is only necessary on UNIX, as the Windows environment - is configured by the OpenSplice installer.) + is configured by the Vortex OpenSplice installer.) Go to the *//* directory, where ** is ``HDE`` or ``RTS`` and ** is, for example, ``x86.linux2.6``. @@ -90,7 +88,7 @@ Vortex OpenSplice on a UNIX ARM platform which is described in section :ref:`UNI Usually not required, but install your desired ORB when the C++ language mapping is used with CORBA cohabitation. Ensure your chosen ORB and compiler is appropriate - for the CCPP library being used (either OpenSplice's default library or + for the CCPP library being used (either Vortex OpenSplice's default library or other custom-built library). Refer to the *Release Notes* for ORB and compiler information pertaining to Vortex OpenSplice' default CCPP library. @@ -111,8 +109,8 @@ Configuration Vortex OpenSplice is configured using an XML configuration file, as shown under `Example XML Configuration Settings`_ . -It is advisable to use the ``osplconf`` tool (UNIX) -or *OpenSplice DDS Configurator Tool* (Windows *Start Menu* ) to +It is advisable to use the ``osplconf`` tool (UNIX) +or *Vortex OpenSplice Configurator Tool* (Windows *Start Menu* ) to edit your xml files. The configurator tool provides explanations of each attribute and also validates the input. @@ -122,7 +120,7 @@ available in this directory, to assist in other scenarios). The default value of the environment variable ``OSPL_URI`` is set to this configuration file. -The configuration file defines and configures the following OpenSplice +The configuration file defines and configures the following Vortex OpenSplice services: *spliced* @@ -139,11 +137,11 @@ services: in a domain. *tuner* - This service provides a SOAP interface for the OpenSplice Tuner to connect + This service provides a SOAP interface for the Vortex OpenSplice Tuner to connect to the node remotely from any other reachable node. The default deployment specified by the XML configuration file is for a -*Single Process* deployment. This means that the OpenSplice Domain +*Single Process* deployment. This means that the Vortex OpenSplice Domain Service, database administration and associated services are all started within the DDS application process. This is implicitly done when the user's application invokes the DDS *create\_participant* operation. @@ -152,7 +150,7 @@ The deployment mode and other configurable properties can be changed by using a different ``OSPL_URI`` file. Several sample configuration files are provided at the same location. -|info| +|info| If using a shared memory configuration, a ** attribute is specified in the XML configuration. The default Database Size that is mapped on @@ -161,8 +159,8 @@ are provided at the same location. |caution| *Note:* The maximum user-creatable shared-memory segment is limited - on certain machines, including Solaris, so it must either be - adjusted or OpenSplice must be started as root. + on certain machines, including Solaris, so it must either be + adjusted or Vortex OpenSplice must be started as root. A complete configuration file that enables durability as well as Real Time Native Networking is shown below. (The relevant lines are not enabled in @@ -179,7 +177,7 @@ created). In the example below this directory is ``/tmp/Pdata``. For the networking service, the network interface-address that is to be used is specified by the ** element. The -default value is set to ``first available`` , meaning that OpenSplice will +default value is set to ``first available`` , meaning that Vortex OpenSplice will determine the first available interface that is broadcast or multicast enabled. However, an alternative address may be specified as well (specify as ``a.b.c.d``). @@ -351,13 +349,13 @@ and run it on Unix/Linux and Windows systems. For VxWorks and Integrity, please refer to :ref:`VxWorks 5.5.1`, :ref:`VxWorks 6.x RTP`, and :ref:`Integrity` in this *Guide*. -Using the OpenSplice Tools -========================== +Using the Vortex OpenSplice Tools +================================= |caution| *Note:* The following instructions apply only to the *shared memory* deployment of Vortex OpenSplice. When deploying in single process - configuration, there is no need to manually start the OpenSplice + configuration, there is no need to manually start the Vortex OpenSplice infrastructure prior to running a DDS application process, as the administration will be created within the application process. Please refer to the Vortex OpenSplice *Deployment Guide* for a discussion of these @@ -369,12 +367,12 @@ Windows *Start Menu* , as well as the Tuner and Configurator. **Step 1** - *Manually start the OpenSplice infrastructure* + *Manually start the Vortex OpenSplice infrastructure* 1. Enter ``ospl start`` on the command line [#f1]_. - This starts the OpenSplice services. + This starts the Vortex OpenSplice services. - These log files may be created in the current directory when OpenSplice + These log files may be created in the current directory when Vortex OpenSplice is started: *ospl-info.log* - contains information and warning reports @@ -390,9 +388,9 @@ Windows *Start Menu* , as well as the Tuner and Configurator. **Step 2** - *Start the OpenSplice Tuner Tool* + *Start the Vortex OpenSplice Tuner Tool* - 1. Read the *OpenSplice Tuner Guide* (``TunerGuide.pdf``) + 1. Read the *Vortex OpenSplice Tuner Guide* (``TunerGuide.pdf``) before running the Tuner Tool. 2. Start the tool by entering ``ospltun`` on the command line. @@ -402,30 +400,30 @@ Windows *Start Menu* , as well as the Tuner and Configurator. environment variable (the default URI is: ``file://$OSPL_HOME/etc/config/ospl.xml``). - The OpenSplice system can now be monitored. + The Vortex OpenSplice system can now be monitored. **Step 3** - *Experiment with the OpenSplice tools and applications* + *Experiment with the Vortex OpenSplice tools and applications* - Use the OpenSplice Tuner to monitor all DDS entities and + Use the Vortex OpenSplice Tuner to monitor all DDS entities and their (dynamic) relationships. **Step 4** - *Manually stop the OpenSplice infrastructure* + *Manually stop the Vortex OpenSplice infrastructure* - 1. Choose *File > Disconnect* from the OpenSplice Tuner menu. + 1. Choose *File > Disconnect* from the Vortex OpenSplice Tuner menu. 2. Enter ``ospl stop`` on the command line; this stops all - OpenSplice services. + Vortex OpenSplice services. + + - -  .. rubric:: Footnotes -  -.. [#f1] ``ospl`` is the command executable for OpenSplice DDS. + +.. [#f1] ``ospl`` is the command executable for Vortex OpenSplice. @@ -449,4 +447,4 @@ Windows *Start Menu* , as well as the Tuner and Configurator. .. |java| image:: ./images/icon-java.* :height: 6mm - + diff --git a/docs/html/GettingStartedGuide/_sources/integrity.txt b/docs/html/GettingStartedGuide/_sources/integrity.txt index e77e0d61a..e1a10e62d 100644 --- a/docs/html/GettingStartedGuide/_sources/integrity.txt +++ b/docs/html/GettingStartedGuide/_sources/integrity.txt @@ -249,7 +249,7 @@ hand in order for the project to build correctly. The following section describes the second method. -Changing the generated OpenSplice DDS project using *Multi* +Changing the generated Vortex OpenSplice project using *Multi* =========================================================== You can make changes to any of the settings you specified with @@ -266,7 +266,7 @@ Select the *All Options* tab and expand the *Advanced* section. **Step 3** -Select *Advanced OpenSplice DDS XML To Int Convertor Options*. In the +Select *Advanced Vortex OpenSplice XML To Int Convertor Options*. In the right-hand pane you will see the options that you have set with the ``ospl_projgen`` tool with their values, similar to `Integrity: changing project options in Multi`_ below. @@ -295,7 +295,7 @@ please see section `The ospl_xml2int command`_.) Note that if you do remove filesystem support from the kernel image you should also remove all references to the ``ivfs`` library, and make appropriate changes to the ``ospl_log.c`` file as well. See section - `Amending OpenSplice DDS Configuration with Multi`_ for information + `Amending Vortex OpenSplice Configuration with Multi`_ for information about ``ospl_log.c``. Similarly you can change any other option and the changes are applied @@ -309,7 +309,7 @@ When the changes are complete, rebuild the project by right-clicking on The ospl_xml2int Tool ===================== -The ``ospl_xml2int`` tool is used to inspect your OpenSplice DDS +The ``ospl_xml2int`` tool is used to inspect your Vortex OpenSplice configuration file (``ospl.xml``) and generate an appropriate Integrate file (``ospl.int``). For more information on Integrate files please consult the Integrity manual. @@ -374,7 +374,7 @@ the arguments are described in detail below. ``-o `` Name of the generated Integrate file. -Applications linking with OpenSplice DDS must comply with the following +Applications linking with Vortex OpenSplice must comply with the following requirements: + The ``First`` and ``Length`` parameters must match those of ``spliced`` @@ -446,8 +446,8 @@ files to match your setup. These files can be found under Once you have made all of the required changes to ``ospl.int``, you must -rebuild the whole project. Your changes will be picked up by OpenSplice -DDS automatically. +rebuild the whole project. Your changes will be picked up by Vortex OpenSplice +automatically. ************************************************** Critical Warning about *Object 10* and *Object 11* @@ -463,32 +463,32 @@ Critical Warning about *Object 10* and *Object 11* ``Object 11`` are defined (except those for ``ResourceStore`` as noted below). The value replacing ``10`` must be the same for every address space, and likewise for the value replacing ``11``. You **must** change - **all** references in order for OpenSplice DDS to work correctly. + **all** references in order for Vortex OpenSplice to work correctly. *The only exception is the* ``ResourceStore`` *address space.* - ``Object 10`` *and* ``Object 11`` *are unique to the OpenSplice DDS* + ``Object 10`` *and* ``Object 11`` *are unique to the Vortex OpenSplice* *ResourceStore and they* **MUST NOT** *be altered.* - *If you do change them, OpenSplice DDS* **WILL NOT WORK!** + *If you do change them, Vortex OpenSplice* **WILL NOT WORK!** |caution| |caution| -************************************************** -Amending OpenSplice DDS Configuration with *Multi* -************************************************** +***************************************************** +Amending Vortex OpenSplice Configuration with *Multi* +***************************************************** -You can make changes to the OpenSplice DDS configuration from Multi by +You can make changes to the Vortex OpenSplice configuration from Multi by editing the files under the project ``src/projgen.gpj/opensplice_configuration.gpj/libospl_cfg.gpj``. See -`Integrity: changing OpenSplice DDS configuration in Multi`_ below: +`Integrity: changing Vortex OpenSplice configuration in Multi`_ below: -.. _`Integrity: changing OpenSplice DDS configuration in Multi`: +.. _`Integrity: changing Vortex OpenSplice configuration in Multi`: .. figure:: /images/Integrity-DDSconfigMulti.png :height: 70mm - :alt: Integrity: changing OpenSplice DDS configuration in Multi + :alt: Integrity: changing Vortex OpenSplice configuration in Multi - **Integrity: changing OpenSplice DDS configuration in Multi** + **Integrity: changing Vortex OpenSplice configuration in Multi** |caution| @@ -496,13 +496,13 @@ editing the files under the project ``ospl_log.c``. The others must **NOT** be altered! ``ospl.xml`` - This is your OpenSplice DDS configuration file. (See - :ref:`Configuration` for more information about the options an OpenSplice DDS + This is your Vortex OpenSplice configuration file. (See + :ref:`Configuration` for more information about the options an Vortex OpenSplice configuration file may have.) ``ospl_log.c`` This file determines where the log entries (errors, - warnings and informational messages) from OpenSplice DDS go. The way the + warnings and informational messages) from Vortex OpenSplice go. The way the default file is generated by ``ospl_projgen`` depends on whether you have specified filesystem support or not. (See comments within the file for more information.) diff --git a/docs/html/GettingStartedGuide/_sources/licensing.txt b/docs/html/GettingStartedGuide/_sources/licensing.txt index ee727a4c9..8a0a22839 100644 --- a/docs/html/GettingStartedGuide/_sources/licensing.txt +++ b/docs/html/GettingStartedGuide/_sources/licensing.txt @@ -1,8 +1,8 @@ -.. _`Licensing OpenSplice`: +.. _`Licensing Vortex OpenSplice`: -#################### -Licensing OpenSplice -#################### +########################### +Licensing Vortex OpenSplice +########################### *Vortex OpenSplice uses Reprise License Manager (RLM) to manage licenses. This section describes how to install a license file for Vortex OpenSplice @@ -14,7 +14,7 @@ General ******* The licensing software is automatically installed on the host machine as -part of the OpenSplice distribution. The software consists of two parts: +part of the Vortex OpenSplice distribution. The software consists of two parts: + *Vortex OpenSplice binary files* | which are installed in ``//./bin``, @@ -22,14 +22,14 @@ part of the OpenSplice distribution. The software consists of two parts: | where Vortex OpenSplice is installed. + *License files* - | which determine the terms of the license. - | These will be supplied by PrismTech. + | which determine the terms of the license. + | These will be supplied by ADLINK. |info| - **Licenses:** PrismTech supplies an Vortex OpenSplice license file, + **Licenses:** ADLINK supplies an Vortex OpenSplice license file, ``license.lic``. This file is *not* included in the software - distribution, but is sent separately by PrismTech. + distribution, but is sent separately by ADLINK. *********************************** @@ -43,7 +43,7 @@ Vortex OpenSplice is also physically licensed on enterprise platforms for deployment. |caution| - Some OpenSplice components are licensed individually and you will need + Some Vortex OpenSplice components are licensed individually and you will need the correct feature to be unlocked for you to use them. @@ -53,7 +53,7 @@ Installing the License File Copy the license file to ``/etc/license.lic`` on the machine that will run the license manager. -```` is the directory where OpenSplice is +```` is the directory where Vortex OpenSplice is installed. This is the recommended location for the license file but you can put @@ -61,14 +61,14 @@ the file in any location that can be accessed by the license manager ``rlm``. If another location is used or the environment has not been setup, then -an environment variable, either ``RLM_LICENSE`` or ``prismtech_LICENSE``, +an environment variable, either ``RLM_LICENSE`` or ``ADLINK_LICENSE``, must be set to the full path and filename of the license file (either variable can be set; there is no need to set both). For example: - ``prismtech_LICENSE=/my/lic/dir/license.lic`` + ``ADLINK_LICENSE=/my/lic/dir/license.lic`` If licenses are distributed between multiple license files, the -``RLM_LICENSE`` or ``prismtech_LICENSE`` variable can be set to point to +``RLM_LICENSE`` or ``ADLINK_LICENSE`` variable can be set to point to the directory which contains the license files. @@ -78,13 +78,13 @@ Running the License Manager Daemon It is only necessary to run the License Manager Daemon for floating or counted licenses. In this case, the license manager must be running -before OpenSplice DDS can be used. The license manager software is +before Vortex OpenSplice can be used. The license manager software is responsible for allocating licenses to developers and ensuring that the allowed number of concurrent licenses is not exceeded. For node-locked licenses, as is the case with all evaluation licenses, then it is not necessary to run the License Manager Daemon but the -``RLM_LICENSE`` or ``prismtech_LICENSE`` variable must be set to the +``RLM_LICENSE`` or ``ADLINK_LICENSE`` variable must be set to the correct license file location. To run the license manager, use the following command: @@ -97,12 +97,12 @@ where ```` is the full path and filename of the license file. If licenses are distributed between multiple files, ```` should be the path to the directory that contains the license files. -The ``rlm`` command will start the PrismTech vendor daemon ``prismtech``, -which controls the licensing of the OpenSplice DDS software. +The ``rlm`` command will start the ADLINK vendor daemon ``prismtech``, +which controls the licensing of the Vortex OpenSplice software. -To obtain a license for OpenSplice DDS from a License Manager Daemon -that is running on a different machine, set either the ``RLM_LICENSE`` -or ``prismtech_LICENSE`` environment variable to point to the License +To obtain a license for Vortex OpenSplice from a License Manager Daemon +that is running on a different machine, set either the ``RLM_LICENSE`` +or ``ADLINK_LICENSE`` environment variable to point to the License Manager Daemon, using the following syntax: .. code-block:: bash @@ -146,11 +146,11 @@ following example: 07/05 12:05 (prismtech) license.lic 07/05 12:05 (prismtech) -.. +.. The ```` value should be taken from the first line of the output. The ```` value should be taken from the last line. From this -example, the value for ``RLM_LICENSE`` or ``prismtech_LICENSE`` would be: +example, the value for ``RLM_LICENSE`` or ``ADLINK_LICENSE`` would be: ``35562@rhel4e`` @@ -162,8 +162,8 @@ Utilities A utility program, ``rlmutil``, is available for license server management and administration. One feature of this utility is its ability to gracefully shut down the license manager. To shut down the -license manager, preventing the checkout of licenses for the OpenSplice -DDS software, run either of the following commands: +license manager, preventing the checkout of licenses for the Vortex OpenSplice +software, run either of the following commands: .. code-block:: bash @@ -194,7 +194,7 @@ This returns an ID code for the server, which will look similar to: ``Hostid of this machine: 0025643ad2a7`` -This ID code must be supplied to PrismTech so that your license key can +This ID code must be supplied to ADLINK so that your license key can be generated. diff --git a/docs/html/GettingStartedGuide/_sources/preface.txt b/docs/html/GettingStartedGuide/_sources/preface.txt index 069bc8fcb..05d0ea29d 100644 --- a/docs/html/GettingStartedGuide/_sources/preface.txt +++ b/docs/html/GettingStartedGuide/_sources/preface.txt @@ -10,7 +10,7 @@ About the Getting Started Guide The *Getting Started Guide* is included with the Vortex OpenSplice Documentation Set. This Guide is the starting point for anyone using, -developing or running applications with OpenSplice DDS. +developing or running applications with Vortex OpenSplice. *This Getting Started Guide contains:* @@ -23,7 +23,7 @@ developing or running applications with OpenSplice DDS. information is provided in the *User* and *Deployment* Guides) - details of where additional information can be found, such as the - OpenSplice FAQs, Knowledge Base, bug reports, *etc.* + Vortex OpenSplice FAQs, Knowledge Base, bug reports, *etc.* *Intended Audience* @@ -77,4 +77,3 @@ specific use of Vortex OpenSplice. .. |java| image:: ./images/icon-java.* :height: 6mm - \ No newline at end of file diff --git a/docs/html/GettingStartedGuide/_sources/product-info.txt b/docs/html/GettingStartedGuide/_sources/product-info.txt index 34f707bc4..d7a24d49b 100644 --- a/docs/html/GettingStartedGuide/_sources/product-info.txt +++ b/docs/html/GettingStartedGuide/_sources/product-info.txt @@ -25,21 +25,21 @@ Services node and the rest of the nodes on \`the network'. + **Tuner Service** (``cmsoap``) - Responsible for providing remote SOAP-based access to a deployed + Responsible for providing remote SOAP-based access to a deployed DDS system by providing a control-and-monitoring (C&M) API + **Networking Bridge Service** - Responsible for bridging DDS traffic between multiple + Responsible for bridging DDS traffic between multiple networks (each with a related Networking Service) - + + **Recording and Replay Service** Responsible for recording and replaying of real-time DDS - data, controlled a topic-based API (as also used by the + data, controlled a topic-based API (as also used by the Vortex RnR Manager tool) - + + **DBMS Connect Service** Responsible for bi-directional bridging between DDS and a - relational database (RDBMS) system + relational database (RDBMS) system Tools ===== @@ -48,13 +48,13 @@ Tools Generates topic types, type-specific readers and writers. + **OpenSplice Tuner** - Allows local and/or remote 'white-box' inspection and tuning + Allows local and/or remote 'white-box' inspection and tuning of a deployed Vortex OpenSplice federation and/or appliciation. + **OpenSplice Tester** Allows for script-based 'black-box' regression-testing of locally or remotely deployed Vortex OpenSplice Systems. - + + **OpenSplice Configurator** Simplifies the process for configuring the services. @@ -79,7 +79,7 @@ Key Features + It offers total lifecycle support from prototyping through to remote maintenance. + Vortex OpenSplice supports both Single Process (library) and Shared Memory (federated) - deployment architectures, targeting either ease of use or advanced scalability + deployment architectures, targeting either ease of use or advanced scalability and determinism scenarios. @@ -123,21 +123,21 @@ this can be found in the *Release Notes*. These compilers are the officially-supported set, but we have experience of customers who will use the delivered libraries with slight variants -of the compiler. In most cases this works, but PrismTech has provided +of the compiler. In most cases this works, but ADLINK has provided the source code so that customers can rebuild the C++ APIs for their compiler of choice. |caution| - **NOTE:** PrismTech only provides support on the officially-supported + **NOTE:** ADLINK only provides support on the officially-supported platforms due to difficult-to-fix issues with compiler-generated code, but some customers will fund us to qualify OpenSplice on their platform. If you wish to use a variant of an official platform, then as long as the issue can be recreated on the official platform it will be covered under an Vortex OpenSplice support contract. If you wish to request support - on a specific platform then please contact PrismTech - (http://www.prismtech.com/contact-us) + on a specific platform then please contact ADLINK + (http://ist.adlinktech.com/) + - ******************** Interaction patterns ******************** @@ -154,13 +154,13 @@ Support for evolutionary data models ************************************ Apart from the OMG IDL based data-modeling, Vortex OpenSplice also supports modeling of -evolutionary types using the popular Google Protocol Buffers (GPB) technology (and the +evolutionary types using the popular Google Protocol Buffers (GPB) technology (and the related .proto files). - + ********************* -Building your own C++ +Building your own C++ ********************* Building your own ISO C++ API @@ -220,4 +220,4 @@ about using Vortex OpenSplice on specific platforms. .. |java| image:: ./images/icon-java.* :height: 6mm - + diff --git a/docs/html/GettingStartedGuide/_sources/unixarm.txt b/docs/html/GettingStartedGuide/_sources/unixarm.txt index bc3313c69..589eb0186 100644 --- a/docs/html/GettingStartedGuide/_sources/unixarm.txt +++ b/docs/html/GettingStartedGuide/_sources/unixarm.txt @@ -38,7 +38,7 @@ When the installer is provided as an tar file follow the procedure described bel where, some being optional, - ** - PrismTech's code for the platform + ** - ADLINK's code for the platform ** - the Vortex OpenSplice version number, for example ``V6.0`` @@ -57,7 +57,7 @@ When the installer is provided as an tar file follow the procedure described bel ** - the target architecture for host/target builds. **Step 2** - + *Configure the Vortex OpenSplice environment.* Go to the *//* directory, where ** is ``HDE`` of ``RTS`` diff --git a/docs/html/GettingStartedGuide/_sources/vxworks-551.txt b/docs/html/GettingStartedGuide/_sources/vxworks-551.txt index ffb4363c0..2da3c00be 100644 --- a/docs/html/GettingStartedGuide/_sources/vxworks-551.txt +++ b/docs/html/GettingStartedGuide/_sources/vxworks-551.txt @@ -35,12 +35,12 @@ additional information describing how VxWorks kernels can be built. + Operating system components - POSIX components - + * POSIX timers * POSIX threads - File System and Disk Utilities - + * File System and Disk Utilities @@ -53,11 +53,11 @@ deploying from the Tornado front end: + Development tool components - WDB agent components - + * WDB agent services - WDB target server file system - + * symbol table components @@ -66,7 +66,7 @@ deploying from the Tornado front end: - synchronize host and target symbol tables - target shell components - + * target shell @@ -169,7 +169,7 @@ pre-loaded by the user. Running the Examples ******************** -If you included the additional modules listed above +If you included the additional modules listed above (see `Building a VxWorks Kernel`_) in the kernel, deployment is done *via* the target server setup from the Tornado shell connection. @@ -320,8 +320,8 @@ The osplconf2c command The OpenSplice Examples (Alternative scenario, with multiple DKMs) ****************************************************************** -|caution| - Loading separate DKMs is not recommended by PrismTech. +|caution| + Loading separate DKMs is not recommended by ADLINK. @@ -369,7 +369,7 @@ point can then be invoked to start OpenSplice. |caution| Please note that in order to deploy the cmsoap service for use with the - OpenSplice DDS Tuner, it must be configured in ``ospl.xml`` and the + Vortex OpenSplice Tuner, it must be configured in ``ospl.xml`` and the libraries named ``libcmxml.so`` and ``libddsrrstorage.so`` must be pre-loaded: diff --git a/docs/html/GettingStartedGuide/_sources/vxworks-6-kernel.txt b/docs/html/GettingStartedGuide/_sources/vxworks-6-kernel.txt index ba161c534..2ccd2142b 100644 --- a/docs/html/GettingStartedGuide/_sources/vxworks-6-kernel.txt +++ b/docs/html/GettingStartedGuide/_sources/vxworks-6-kernel.txt @@ -33,10 +33,10 @@ which must match the Vortex OpenSplice build you are working with. |caution| The *SMP* option must *only* be checked for SMP builds of OpenSplice. - + On the *Configuration Profile* dialog choose ``PROFILE_DEVELOPMENT`` from the drop-down list. - + Once the kernel configuration project has been generated, the additional required functionality can be enabled: @@ -71,7 +71,7 @@ OpenSplice Examples .. note: xref to install-configure.rst -PrismTech provides the *pingpong* example both for C and C++ that are described +ADLINK provides the *pingpong* example both for C and C++ that are described in the :ref:`Examples` section. These example are provided in the form of Workbench projects which can be easily built and then deployed on to the target hardware in a similar process to that described above. @@ -204,8 +204,8 @@ Open a target shell connection to each board and in the C mode shell run: ld 1,0,"/tgtsvr/sacpp_pingpong_kernel.out" ospl_spliced - -**Step 5** + +**Step 5** Open another target shell connection to one board and run: @@ -310,7 +310,7 @@ Open a target shell connection and in the C mode shell run: ld 1,0,"/tgtsvr/sacpp_pingpong_kernel.out" ospl_spliced - + Open another target shell connection and run: pong "PongRead PongWrite" @@ -353,7 +353,7 @@ Running the Examples (Alternative scenario, with multiple DKMs – ‘AppOnly’ ********************************************************************************* |caution| - Loading separate DKMs is not recommended by PrismTech. + Loading separate DKMs is not recommended by ADLINK. |info| |cpp| *NOTE:* There are no C++ examples provided for the AppOnly style and there is no @@ -555,7 +555,7 @@ The osplconf2c command .. code-block:: bash osplconf2c -h - + osplconf2c [-u ] [-e ]... [-o ] @@ -564,13 +564,13 @@ The osplconf2c command ``-h, -?`` List available command line arguments and give brief reminders of their functions. - + ``-u `` Identifies the configuration file to use (default: ``${OSPL_URI}``). - + ``-o `` Name of the generated file. - + ``-e `` Environment setting for configuration of OpenSplice e.g. ``-e "OSPL_LOGPATH=/xxx/yyy"`` diff --git a/docs/html/GettingStartedGuide/_sources/vxworks-6-rtp.txt b/docs/html/GettingStartedGuide/_sources/vxworks-6-rtp.txt index e3b6a0003..30f9cfe9e 100644 --- a/docs/html/GettingStartedGuide/_sources/vxworks-6-rtp.txt +++ b/docs/html/GettingStartedGuide/_sources/vxworks-6-rtp.txt @@ -24,17 +24,17 @@ Installation The following instructions describe installing Vortex OpenSplice for VxWorks 6.x on the Windows host environment. -Start the installation process by double-clicking the Vortex OpenSplice +Start the installation process by double-clicking the Vortex OpenSplice Host Development Environment (HDE) installer file. Follow the on-screen instructions and complete the installation. When asked to configure the installation with a license file, choose *No*. The installer will create an Vortex OpenSplice entry in *Start > Programs* which contains -links to the OpenSplice tools, documentation, and an Uninstall option. +links to the Vortex OpenSplice tools, documentation, and an Uninstall option. |caution| Please note that WindRiver's Workbench GUI must be run in an environment - where the OpenSplice variables have already been set. If you chose to - set the OpenSplice variables globally during the installation stage, + where the Vortex OpenSplice variables have already been set. If you chose to + set the Vortex OpenSplice variables globally during the installation stage, then Workbench can be run directly. Otherwise, Workbench must be run from the Vortex OpenSplice command prompt. Start the command prompt by clicking *Start > Programs > Vortex OpenSplice menu entry > Vortex OpenSplice @@ -84,7 +84,7 @@ Vortex OpenSplice domain service ``spliced`` and a number of optional services described within the Vortex OpenSplice configuration file (``ospl.xml``). On VxWorks 6.x, a Real Time Process for each of these services is deployed on to the target hardware. The sample ``ospl.xml`` configuration file -provided with the VxWorks 6.x edition of OpenSplice has particular +provided with the VxWorks 6.x edition of Vortex OpenSplice has particular settings so that these RTPs can operate effectively. The instructions below describe how to deploy these RTPs using the @@ -118,7 +118,7 @@ connection and choosing *Run > Run RTP on Target...*. **Step 5** Create a new configuration for the *spliced* deployment that points to -the ``spliced.vxe`` executable from the OpenSplice installation. The +the ``spliced.vxe`` executable from the Vortex OpenSplice installation. The following parameters should be set in the dialog: +------------------------+----------------------------------------+ @@ -143,7 +143,7 @@ For simplicity it has been assumed that ``spliced.vxe`` and the other executables (located in the ``bin`` directory of the installation) and ``ospl.xml`` (located in the ``etc/config`` directory of the installation) have been copied to the directory made available as ``/tgtsvr`` described -above. It is possible, if required, to copy the entire OpenSplice +above. It is possible, if required, to copy the entire Vortex OpenSplice installation directory to the ``/tgtsvr`` location so that all files are available, but please be aware that log and information files will be written to the same ``/tgtsvr`` location when the ``spliced.vxe`` is @@ -165,7 +165,7 @@ The configuration can be deployed by clicking *Run*, where an RTP for each service described in the configuration file should be created. These can be seen in Workbench in the Real Time Processes list for the target connection. An example is shown below in -`Workbench showing deployed OpenSplice RTPs`_. +`Workbench showing deployed Vortex OpenSplice RTPs`_. (The list may need to be refreshed with the *F5* key.) Deployment problems are listed in ``ospl-error.txt`` and ``ospl-info.txt``, @@ -173,22 +173,22 @@ which are created in the ``/tgtsvr`` directory if the configuration described above is used. -.. _`Workbench showing deployed OpenSplice RTPs`: +.. _`Workbench showing deployed Vortex OpenSplice RTPs`: .. figure:: /images/VxWorks-deployedRTPs.png :height: 70mm - :alt: Workbench showing deployed OpenSplice RTPs + :alt: Workbench showing deployed Vortex OpenSplice RTPs - **Workbench showing deployed OpenSplice RTPs** + **Workbench showing deployed Vortex OpenSplice RTPs** -******************* -OpenSplice Examples -******************* +************************** +Vortex OpenSplice Examples +************************** .. note: xref to install-configure.rst -PrismTech provides a number of examples both for C and C++ that are +ADLINK provides a number of examples both for C and C++ that are described in the :ref:`Examples` section. These example are provided in the form of Workbench projects which can be easily built and then deployed on to the target hardware in a similar process to that described above. @@ -204,7 +204,7 @@ The example projects can be imported into Workbench by clicking *File > Import... > General > Existing Projects into Workspace*. In the *Import Projects* dialog, browse to the ``examples`` directory of -the OpenSplice installation. Select the required projects for importing +the Vortex OpenSplice installation. Select the required projects for importing from the list that Workbench has detected. Ensure that the *Copy projects into workspace* box is un-checked. @@ -221,7 +221,7 @@ Projects in a workspace can be built individually or as a group. *Project > Build All*. -Deploying OpenSplice Examples +Deploying Vortex OpenSplice Examples ============================= The PingPong and the Tutorial examples are run in identical ways with @@ -234,7 +234,7 @@ Deploying PingPong The PingPong example consists of the ``ping.vxe`` and ``pong.vxe`` executables. If these executables have been copied to the directory made -available as ``/tgtsvr`` as described in `Deploying OpenSplice DDS`_, +available as ``/tgtsvr`` as described in `Deploying Vortex OpenSplice`_, RTP configurations should have the following parameters: +-----------------------------------+----------------------------------------+ @@ -251,8 +251,8 @@ RTP configurations should have the following parameters: +-----------------------------------+----------------------------------------+ | Stack Size | ``0x10000`` | +-----------------------------------+----------------------------------------+ - - + + +-----------------------------------+----------------------------------------+ | RTP configuration for ping | +===================================+========================================+ @@ -280,7 +280,7 @@ Deploying the Chat Tutorial The Chat Tutorial consists of the ``chatter.vxe``, ``messageboard.vxe`` and ``userload.vxe`` executables. If these executables have been copied to the directory made available as ``/tgtsvr`` as described in -`Deploying OpenSplice DDS`_, RTP configurations should have the following +`Deploying Vortex OpenSplice`_, RTP configurations should have the following parameters: +-----------------------------------+----------------------------------------+ @@ -297,8 +297,8 @@ parameters: +-----------------------------------+----------------------------------------+ | Stack Size | ``0x10000`` | +-----------------------------------+----------------------------------------+ - - + + +-----------------------------------+----------------------------------------+ | RTP configuration for messageboard | +===================================+========================================+ @@ -313,8 +313,8 @@ parameters: +-----------------------------------+----------------------------------------+ | Stack Size | ``0x10000`` | +-----------------------------------+----------------------------------------+ - - + + +-----------------------------------+----------------------------------------+ | RTP configuration for chatter | +===================================+========================================+ @@ -329,8 +329,8 @@ parameters: +-----------------------------------+----------------------------------------+ | Stack Size | ``0x10000`` | +-----------------------------------+----------------------------------------+ - - + + When deployment is successful, the console will show output from each RTP. In particular the message board will show the messages sent by the ``chatter`` process. The console view can be switched to show the output diff --git a/docs/html/GettingStartedGuide/_sources/windowsce.txt b/docs/html/GettingStartedGuide/_sources/windowsce.txt index e5d337ca3..52a96330d 100644 --- a/docs/html/GettingStartedGuide/_sources/windowsce.txt +++ b/docs/html/GettingStartedGuide/_sources/windowsce.txt @@ -75,7 +75,7 @@ Alternatives to CAB file Microsoft's Windows CE Remote Registry Editor can be used instead of a ``CAB`` file to set the necessary registry values. Alternatively, -PrismTech also provides a convenient method of editing the registry +ADLINK also provides a convenient method of editing the registry variables by way of the ``ospl`` utility using the ``getenv`` and ``putenv`` parameters (described below). @@ -83,9 +83,9 @@ Please refer to Microsoft's Windows CE documentation for detailed information about ``CAB`` files and the Remote Registry Editor. -****************************** +********************************* The Vortex OpenSplice Environment -****************************** +********************************* Vortex OpenSplice requires the contents of the *bin* , *lib* and *etc* directories from within the Vortex OpenSplice installation to be available @@ -114,7 +114,7 @@ executables. For example: copied into the ```\Windows`` directory on the Windows CE device prior to deployment.) -When running OpenSplice executables on the command prompt, it is useful +When running Vortex OpenSplice executables on the command prompt, it is useful to redirect any output to text files by using the ``>`` operator. If the ``PATH`` and ``OSPL_URI`` variables have not already been set *via* @@ -143,7 +143,7 @@ The secure networking service uses OpenSSL for cryptography support. To use this feature, the library ``libeay32.dll`` is required; it must be copied to the ``\Windows`` directory on the Windows CE device. -OpenSplice is tested against OpenSSL version 0.9.8i. This may be built +Vortex OpenSplice is tested against OpenSSL version 0.9.8i. This may be built as described below. Building OpenSSL for Windows CE 6.0 @@ -170,7 +170,7 @@ The following are needed to make an OpenSSL build for Windows CE 6.0: + An installed WinCE 6.0 SDK to be targeted In this description the target SDK is ``'WinCE-GS3Target'`` - + + Perl You will need to install Active Perl, from http://www.activestate.com/ActivePerl. @@ -212,11 +212,11 @@ any location you want. .. code-block:: make set OSVERSION=WCE600 - + set TARGETCPU=ARMV4I - + set PLATFORM=VC-CE - + set PATH=C:\Program Files\Microsoft Visual Studio 8\VC\ce\bin\x86_arm; C:\Program Files\Microsoft Visual Studio 8\Common7\IDE;%PATH% @@ -226,7 +226,7 @@ any location you want. set LIB=C:\Program Files\Windows CE Tools\wce600\WinCE-GS3Target\lib\ ARMV4I;C:\Program Files\\Microsoft Visual Studio 8\VC\ce\lib\armv4 -.. +.. If you target a different SDK, replace the text *WinCE-GS3Target* in the lines above with your own SDK. @@ -302,7 +302,7 @@ Build OpenSSL set WCECOMPAT=C:\wcecompat -.. +.. If you target a different SDK, replace the text ``WinCE-GS3Target`` in the lines above with your own SDK. Also, change the *wcecompat* @@ -351,13 +351,13 @@ If you get the following error message: Remove ``/WX`` in the makefile (``ce.mak``). -************************ -Deploying OpenSplice DDS -************************ +*************************** +Deploying Vortex OpenSplice +*************************** ``ospl start`` - This command will start the OpenSplice DDS ``splicedaemon`` and OpenSplice - DDS services specified within the configuration referred to by the + This command will start the Vortex OpenSplice ``splicedaemon`` and Vortex + OpenSplice services specified within the configuration referred to by the ``OSPL_URI`` variable: ``ospl start > osplstart.txt`` @@ -369,14 +369,14 @@ Deploying OpenSplice DDS | ``HDE/armv4i.wince/etc/config/ospl.xml" > osplstart.txt`` ``ospl list`` - This command will list all the OpenSplice DDS configurations that are + This command will list all the Vortex OpenSplice configurations that are currently running on the node. ``ospl list > ospllist.txt`` ``ospl stop`` - This command will stop the OpenSplice DDS ``splicedaemon`` and OpenSplice - DDS services specified within the configuration referred to by the + This command will stop the Vortex OpenSplice ``splicedaemon`` and Vortex + OpenSplice services specified within the configuration referred to by the ``OSPL_URI`` variable: ``ospl stop > osplstop.txt`` @@ -415,14 +415,14 @@ where ** is displayed in the output for the particular instance of ``mmstat``. -******************* -OpenSplice Examples -******************* +************************** +Vortex OpenSplice Examples +************************** .. note: xref to install-configure.rst Please refer to the :ref:`Examples` section for descriptions of the -OpenSplice DDS examples. +Vortex OpenSplice examples. Building the examples @@ -436,7 +436,7 @@ Once the projects are open in Microsoft Visual Studio, click *Build/Rebuild Solution* at the appropriate level to build the required examples. -Copy the produced executable files to the OpenSplice DDS ``bin`` directory +Copy the produced executable files to the Vortex OpenSplice ``bin`` directory (*i.e.* ``\NAND Flash\OpenSpliceDDS\\HDE\armv4i.wince\bin``) on the Windows CE device. For the PingPong example the executable files are @@ -448,7 +448,7 @@ for a new project perform the following steps: **Step 1** - Run the OpenSplice command prompt from the *OpenSplice* entry under the + Run the Vortex OpenSplice command prompt from the *OpenSplice* entry under the Windows *Start* button: *Start > Programs > OpenSpliceDDS armv4i.wince HDE @@ -461,7 +461,7 @@ for a new project perform the following steps: the *Visual Studio 2005 Command Prompt* entry located at *Start > Programs > Microsoft Visual Studio 2005 > Visual Studio Tools > Visual Studio 2005 Command Prompt* , and paste the *Shortcut Target* entry into - the OpenSplice command prompt. For example this could be + the Vortex OpenSplice command prompt. For example this could be ``%comspec% /k ""C:\Program Files\Microsoft Visual Studio 8\VC\vcvarsall.bat"" x86`` @@ -485,7 +485,7 @@ Start Vortex OpenSplice as described above. The Ping and Pong executables can then be started as follows: ``start pong PongRead PongWrite > pong.txt`` - + ``start ping 100 100 m PongRead PongWrite > ping.txt`` The ``ping.txt`` file produced should contain the expected Ping Pong diff --git a/docs/html/GettingStartedGuide/about-ospl.html b/docs/html/GettingStartedGuide/about-ospl.html index 82168da0a..cfeba0ede 100644 --- a/docs/html/GettingStartedGuide/about-ospl.html +++ b/docs/html/GettingStartedGuide/about-ospl.html @@ -50,7 +50,7 @@

    Navigation

    @@ -340,7 +178,7 @@

    Navigation

    -

    2. About Vortex Opensplice¶

    +

    2. About Vortex Opensplice¶

    2.1. Why Vortex OpenSplice¶

    @@ -98,9 +98,9 @@

    2.1.3. Vortex OpenSplice Summaryhttp://www.prismtech.com to obtain evaluation copies of -Vortex OpenSplice, and http://www.opensplice.org for free downloads of the -community version.

    +

    Please go to http://ist.adlinktech.com/ to obtain evaluation copies of +Vortex OpenSplice, and http://ist.adlinktech.com/dds-community for free downloads of the +DDS Community Edition.

    @@ -116,7 +116,7 @@

    2.2.1. Overall @@ -127,7 +127,7 @@

    2.2.2. Scalability

    2.3. Single Process Library Architecture¶

    -

    This deployment allows the DDS applications and OpenSplice +

    This deployment allows the DDS applications and Vortex OpenSplice administration to be contained together within one single operating system process. This single process deployment option is most useful in environments where shared memory is unavailable or undesirable. As @@ -199,11 +199,11 @@

    2.3. Single Process Library ArchitectureThe OpenSplice Single Process Architecture +

    The figure The Vortex OpenSplice Single Process Architecture shows an overview of the single process architecture of Vortex OpenSplice.

    -
    -The OpenSplice Single Process Architecture -

    The OpenSplice Single Process Architecture

    +
    +The Vortex OpenSplice Single Process Architecture +

    The Vortex OpenSplice Single Process Architecture

    @@ -211,10 +211,10 @@

    2.4. Shared Memory architectureThe OpenSplice Shared Memory Architecture +

    The figure The Vortex OpenSplice Shared Memory Architecture shows an overview of the shared memory architecture of Vortex OpenSplice on one computing node. Typically, there are many nodes within a system.

    -
    -The OpenSplice Shared Memory Architecture -

    The OpenSplice Shared Memory Architecture

    +
    +The Vortex OpenSplice Shared Memory Architecture +

    The Vortex OpenSplice Shared Memory Architecture

    @@ -237,9 +237,9 @@

    2.5. Vortex OpenSplice Features and Benefits @@ -436,7 +436,7 @@

    2.5. Vortex OpenSplice Features and Benefits

    2.6. Conclusion¶

    -

    PrismTech’s Vortex OpenSplice product complemented by its tool support +

    ADLINK’s Vortex OpenSplice product complemented by its tool support together encompass the industry’s most profound expertise on the OMG’s DDS standard and products.

    The result is unrivalled functional DDS coverage and performance in @@ -525,7 +525,7 @@

    Navigation

    \ No newline at end of file diff --git a/docs/html/GettingStartedGuide/contacts.html b/docs/html/GettingStartedGuide/contacts.html index eb6c458cf..d8f08fd0e 100644 --- a/docs/html/GettingStartedGuide/contacts.html +++ b/docs/html/GettingStartedGuide/contacts.html @@ -50,7 +50,7 @@

    Navigation

    18.1. Contacts¶

    -
    PrismTech Corporation
    +
    ADLINK Technology Corporation
    400 TradeCenter
    Suite 5900
    Woburn, MA
    @@ -59,31 +59,35 @@

    18.1. ContactsTel: +1 781 569 5819

    -
    PrismTech Limited
    -
    PrismTech House
    -
    5th Avenue Business Park
    +
    ADLINK Technology Limited
    +
    The Edge
    +
    5th Avenue
    +
    Team Valley
    Gateshead
    -
    NE11 0NG
    +
    NE11 0XA
    UK
    Tel: +44 (0)191 497 9900
    -
    PrismTech France
    +
    ADLINK Technology SARL
    28 rue Jean Rostand
    91400 Orsay
    France
    Tel: +33 (1) 69 015354
    -

    Web: http://www.prismtech.com

    -

    E-mail: info@prismtech.com

    +

    Web: http://ist.adlinktech.com/

    +

    Contact: http://ist.adlinktech.com

    +

    E-mail: ist_info@adlinktech.com

    +

    LinkedIn: https://www.linkedin.com/company/79111/

    +

    Twitter: https://twitter.com/ADLINKTech_usa

    +

    Facebook: https://www.facebook.com/ADLINKTECH

    18.2. Notices¶

    -

    Copyright © 2016 PrismTech Limited. All rights reserved.

    -

    This document may be reproduced in whole but not in part. -The information contained in this document is subject to change without notice and is made available in good faith without liability on the part of PrismTech Limited or PrismTech Corporation. -All trademarks acknowledged.

    -

    Doc Issue 01, 24 March 2015

    +

    Copyright © 2018 ADLINK Technology Limited. All rights reserved.

    +

    This document may be reproduced in whole but not in part. The information contained in this +document is subject to change without notice and is made available in good faith without +liability on the part of ADLINK Technology Limited. All trademarks acknowledged.

    @@ -143,7 +147,7 @@

    Navigation

    \ No newline at end of file diff --git a/docs/html/GettingStartedGuide/documentation.html b/docs/html/GettingStartedGuide/documentation.html index 79772a5e0..c04a95cfa 100644 --- a/docs/html/GettingStartedGuide/documentation.html +++ b/docs/html/GettingStartedGuide/documentation.html @@ -59,216 +59,54 @@

    Navigation

    documents and their likely users.

    4.1. Vortex OpenSplice Documentation Set¶

    - ---- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    DocumentDescription and Use
    Release -Notes

    Lists the latest updates, bug fixes, and last-minute -information.

    -

    For product installers, administrators, and developers, -who need to be aware of the latest changes which may -affect the Service’s performance and usage. -A link to the Release Notes is in index.html -located in the directory where OpenSplice is installed.

    -
    Getting -Started -Guide

    General information about OpenSplice, including -installation instructions, initial configuration -requirements and instructions for running the -Opensplice examples on supported platforms.

    -

    For managers, administrators, and developers -to gain an initial understanding of the product, -as well as for product installers for -installing and administering OpenSplice.

    -

    Essential reading for users new to DDS.

    -
    Evaluation -GuideA short guide to help new users evaluate Vortex -OpenSplice.
    Tutorial -GuideA short course on developing applications with -OpenSplice. Includes example code in C, C++ and Java.
    Deployment -GuideA complete reference on how to configure and -tune the OpenSplice service.
    Tuner -Guide

    Describes how to use the Tuner tool for monitoring -and controlling Opensplice.

    -

    For programmers, testers, system designers and -system integrators using OpenSplice.

    -
    IDL Pre-processor -GuideDescribes how to use the Opensplice IDL pre-processor -for C, C++ and Java.
    OpenSplice -Automated -Testing and -Debugging -Tool -User GuideProvides a complete reference on how to configure the -‘Tester’ tool and how to use it to test scenarios -generated with Vortex OpenSplice

    C Reference -Guide

    -

    C++ -Reference -Guide

    -

    Java -Reference -Guide

    -

    Each of these reference guides describes the Vortex -OpenSplice Application Progammers Interface (API) for -C, Classic C++ and Classic Java.

    -

    This is a detailed reference for developers to help -them to understand the particulars of each feature -of the Vortex OpenSplce API.

    -

    C# -Reference -Guide

    -

    ISO C++ -Reference -Guide

    -

    Java 5 -Reference -Guide

    -
    Describes the Vortex OpenSplice APIs for C#, the new -ISO C++ and Java 5 -Supplied as HTML rather than PDF with the -product Release Notes.
    RMI over DDS -Getting -Started -GuideExplains how to take advantage of the client/server -interaction paradigm provided by OpenSplice RMI -layered over the publish/subscribe paradigm of -Vortex OpenSplice.
    Streams User -GuideExplains the Streams API where continuous flows or -?streams? of data have to be transported with minimal -overhead and therefore maximal achievable throughput.
    GPB User -GuideExplains how to use Google Protocol Buffers with the -new ISO C++ and Java 5 APIs.
    Record and -Replay -Service GuideExplains how to configure and use the Record and Replay -Service.
    Security User -Configuration -GuideExplains how to configure security when using the -Real Time Native Networking Protocol.
    Node MonitorExplains how to the Node Monitor Tool to watch over -the Vortex OpenSplice middleware.
    Examples

    Examples, complete with source code, demonstrating -how applications usiong Opensplice can be written -and used.

    -

    Documentation for the examples can be found in the -OpenSplice Release Notes.

    -
    White Papers -and Data -Sheets

    Technical papers providing information about -Vortex Opensplice.

    -

    These technical papers are in PDF format and they -can be obtained from the PrismTech web site at -http://www.prismtech.com

    -

    4.2. Information Sources¶

    4.2.1. Product Information¶

    -

    Links to useful technical information for PrismTech’s products, +

    Links to useful technical information for ADLINK’s products, including the Vortex OpenSplice and associated components, are listed below.

    caution
    These links are provided for the reader’s convenience and may become -out-of-date if changes are made on the PrismTech Web site after +out-of-date if changes are made on the ADLINK Web site after publication of this guide. Nonetheless, these links should still be -reachable from the main PrismTech Web page located at -http://www.prismtech.com.
    +reachable from the main ADLINK Web page located at +http://ist.adlinktech.com/.

    4.2.2. Knowledge Base¶

    -

    The PrismTech Knowledge Base is a collection of documents and resources -intended to assist our customers in getting the most out of the +

    The ADLINK Knowledge Base is a collection of documents and resources +intended to assist our customers in getting the most out of the Vortex OpenSplice products. The Knowledge Base has the most up-to-date information about bug fixes, product issues and technical support for difficulties that you may experience.

    The Knowledge Base can be found at:

    -
    +

    4.2.3. Additional Technical Information¶

    Information provided by independent publishers, newsgroups, web sites, and organisations, such as the Object Management Group, can be found on -the Prismtech Web site:

    +the ADLINK Web site:

    -
    +

    4.3. Support¶

    -

    PrismTech provides a range of product support, consultancy and +

    ADLINK provides a range of product support, consultancy and educational programmes to help you from product evaluation and -development, through to deployment of applications using OpenSplice DDS. +development, through to deployment of applications using Vortex OpenSplice. The support programmes are designed to meet customers’ particular needs and range from a basic Standard programme to the Gold programme, which provides comprehensive, 24 x 7 support.

    -

    Detailed information about PrismTech’s product support services, general -support contacts and enquiries are described on the PrismTech Support -page reached via the PrismTech Home page at http://www.prismtech.com.

    +

    Detailed information about ADLINK’s product support services, general +support contacts and enquiries are described on the ADLINK Support +page reached via the ADLINK Home page at http://ist.adlinktech.com/.

    \ No newline at end of file diff --git a/docs/html/GettingStartedGuide/elinos.html b/docs/html/GettingStartedGuide/elinos.html index af67d277d..4a2fd820d 100644 --- a/docs/html/GettingStartedGuide/elinos.html +++ b/docs/html/GettingStartedGuide/elinos.html @@ -51,7 +51,7 @@

    Navigation

    17. ELinOS¶

    -

    This chapter provides notes about deploying OpenSplice DDS on ELinOS.

    +

    This chapter provides notes about deploying Vortex OpenSplice on ELinOS.

    17.1. Deployment notes¶

    OpenSplice may be deployed in an ELinOS system.

    @@ -151,7 +151,7 @@

    Navigation

    \ No newline at end of file diff --git a/docs/html/GettingStartedGuide/genindex.html b/docs/html/GettingStartedGuide/genindex.html index 1e3daabcc..43991bcb2 100644 --- a/docs/html/GettingStartedGuide/genindex.html +++ b/docs/html/GettingStartedGuide/genindex.html @@ -88,7 +88,7 @@

    Navigation

    \ No newline at end of file diff --git a/docs/html/GettingStartedGuide/index.html b/docs/html/GettingStartedGuide/index.html index 6ddd38876..18b088d49 100644 --- a/docs/html/GettingStartedGuide/index.html +++ b/docs/html/GettingStartedGuide/index.html @@ -87,7 +87,7 @@

    OpenSplice Getting Started Guide6. Using Vortex OpenSplice with Vortex Cloud and Vortex Fog -
  • 7. Licensing OpenSplice
  • 5.5. Examples
  • @@ -475,7 +473,7 @@

    Navigation

    \ No newline at end of file diff --git a/docs/html/GettingStartedGuide/integrity.html b/docs/html/GettingStartedGuide/integrity.html index 552895913..ee0015382 100644 --- a/docs/html/GettingStartedGuide/integrity.html +++ b/docs/html/GettingStartedGuide/integrity.html @@ -237,8 +237,8 @@

    13.4. Changing the ospl_projgen Arguments -

    13.4.1. Changing the generated OpenSplice DDS project using Multi¶

    +
    +

    13.4.1. Changing the generated Vortex OpenSplice project using Multi¶

    You can make changes to any of the settings you specified with ospl_projgen by following these steps:

    Step 1

    @@ -247,7 +247,7 @@

    13.4.1. Changing the generated OpenSplice DDS project using MultiStep 2

    Select the All Options tab and expand the Advanced section.

    Step 3

    -

    Select Advanced OpenSplice DDS XML To Int Convertor Options. In the +

    Select Advanced Vortex OpenSplice XML To Int Convertor Options. In the right-hand pane you will see the options that you have set with the ospl_projgen tool with their values, similar to Integrity: changing project options in Multi below.

    @@ -269,7 +269,7 @@

    13.4.1. Changing the generated OpenSplice DDS project using MultiNote that if you do remove filesystem support from the kernel image you should also remove all references to the ivfs library, and make appropriate changes to the ospl_log.c file as well. See section -Amending OpenSplice DDS Configuration with Multi for information +Amending Vortex OpenSplice Configuration with Multi for information about ospl_log.c.

    Similarly you can change any other option and the changes are applied @@ -279,7 +279,7 @@

    13.4.1. Changing the generated OpenSplice DDS project using Multi

    13.4.2. The ospl_xml2int Tool¶

    -

    The ospl_xml2int tool is used to inspect your OpenSplice DDS +

    The ospl_xml2int tool is used to inspect your Vortex OpenSplice configuration file (ospl.xml) and generate an appropriate Integrate file (ospl.int). For more information on Integrate files please consult the Integrity manual.

    @@ -336,7 +336,7 @@

    13.4.3. The ospl_xml2int command-o <file>
    Name of the generated Integrate file.
    -

    Applications linking with OpenSplice DDS must comply with the following +

    Applications linking with Vortex OpenSplice must comply with the following requirements:

    Once you have made all of the required changes to ospl.int, you must -rebuild the whole project. Your changes will be picked up by OpenSplice -DDS automatically.

    +rebuild the whole project. Your changes will be picked up by Vortex OpenSplice +automatically.

    -
    -

    13.6. Amending OpenSplice DDS Configuration with Multi¶

    -

    You can make changes to the OpenSplice DDS configuration from Multi by +

    +

    13.6. Amending Vortex OpenSplice Configuration with Multi¶

    +

    You can make changes to the Vortex OpenSplice configuration from Multi by editing the files under the project src/projgen.gpj/opensplice_configuration.gpj/libospl_cfg.gpj. See -Integrity: changing OpenSplice DDS configuration in Multi below:

    -
    -Integrity: changing OpenSplice DDS configuration in Multi -

    Integrity: changing OpenSplice DDS configuration in Multi

    +Integrity: changing Vortex OpenSplice configuration in Multi below:

    +
    +Integrity: changing Vortex OpenSplice configuration in Multi +

    Integrity: changing Vortex OpenSplice configuration in Multi

    caution
    There are five files here but you may only change ospl.xml and ospl_log.c. The others must NOT be altered!
    ospl.xml
    -
    This is your OpenSplice DDS configuration file. (See -Configuration for more information about the options an OpenSplice DDS +
    This is your Vortex OpenSplice configuration file. (See +Configuration for more information about the options an Vortex OpenSplice configuration file may have.)
    ospl_log.c
    This file determines where the log entries (errors, -warnings and informational messages) from OpenSplice DDS go. The way the +warnings and informational messages) from Vortex OpenSplice go. The way the default file is generated by ospl_projgen depends on whether you have specified filesystem support or not. (See comments within the file for more information.)
    @@ -467,13 +467,13 @@

    Table Of Contents

  • 13.3. PingPong Example
  • 13.4. Changing the ospl_projgen Arguments
  • 13.5. Critical Warning about Object 10 and Object 11
  • -
  • 13.6. Amending OpenSplice DDS Configuration with Multi
  • +
  • 13.6. Amending Vortex OpenSplice Configuration with Multi
  • @@ -522,7 +522,7 @@

    Navigation

    \ No newline at end of file diff --git a/docs/html/GettingStartedGuide/launcher.html b/docs/html/GettingStartedGuide/launcher.html index 5d0640f81..1971294d4 100644 --- a/docs/html/GettingStartedGuide/launcher.html +++ b/docs/html/GettingStartedGuide/launcher.html @@ -25,7 +25,7 @@ - + \ No newline at end of file diff --git a/docs/html/GettingStartedGuide/licensing.html b/docs/html/GettingStartedGuide/licensing.html index f49c463ff..04c102ca6 100644 --- a/docs/html/GettingStartedGuide/licensing.html +++ b/docs/html/GettingStartedGuide/licensing.html @@ -6,7 +6,7 @@ - 7. Licensing OpenSplice — OpenSplice Getting Started Guide + 7. Licensing Vortex OpenSplice — OpenSplice Getting Started Guide @@ -49,15 +49,15 @@

    Navigation

    -
    -

    7. Licensing OpenSplice¶

    +
    +

    7. Licensing Vortex OpenSplice¶

    Vortex OpenSplice uses Reprise License Manager (RLM) to manage licenses. This section describes how to install a license file for Vortex OpenSplice and how to use the license manager.

    7.1. General¶

    The licensing software is automatically installed on the host machine as -part of the OpenSplice distribution. The software consists of two parts:

    +part of the Vortex OpenSplice distribution. The software consists of two parts:

    @@ -81,9 +81,9 @@

    7.1. General
    info
    -
    Licenses: PrismTech supplies an Vortex OpenSplice license file, +
    Licenses: ADLINK supplies an Vortex OpenSplice license file, license.lic. This file is not included in the software -distribution, but is sent separately by PrismTech.
    +distribution, but is sent separately by ADLINK.

    @@ -95,7 +95,7 @@

    7.2. Development and Deployment Licenses
    caution
    -
    Some OpenSplice components are licensed individually and you will need +
    Some Vortex OpenSplice components are licensed individually and you will need the correct feature to be unlocked for you to use them.

    @@ -103,31 +103,31 @@

    7.2. Development and Deployment Licenses¶

    Copy the license file to <OpenSplice_Install_Dir>/etc/license.lic on the machine that will run the license manager. -<OpenSplice_Install_Dir> is the directory where OpenSplice is +<OpenSplice_Install_Dir> is the directory where Vortex OpenSplice is installed.

    This is the recommended location for the license file but you can put the file in any location that can be accessed by the license manager rlm.

    If another location is used or the environment has not been setup, then -an environment variable, either RLM_LICENSE or prismtech_LICENSE, +an environment variable, either RLM_LICENSE or ADLINK_LICENSE, must be set to the full path and filename of the license file (either variable can be set; there is no need to set both). For example:

    -
    prismtech_LICENSE=/my/lic/dir/license.lic
    +
    ADLINK_LICENSE=/my/lic/dir/license.lic

    If licenses are distributed between multiple license files, the -RLM_LICENSE or prismtech_LICENSE variable can be set to point to +RLM_LICENSE or ADLINK_LICENSE variable can be set to point to the directory which contains the license files.

    7.4. Running the License Manager Daemon¶

    It is only necessary to run the License Manager Daemon for floating or counted licenses. In this case, the license manager must be running -before OpenSplice DDS can be used. The license manager software is +before Vortex OpenSplice can be used. The license manager software is responsible for allocating licenses to developers and ensuring that the allowed number of concurrent licenses is not exceeded.

    For node-locked licenses, as is the case with all evaluation licenses, then it is not necessary to run the License Manager Daemon but the -RLM_LICENSE or prismtech_LICENSE variable must be set to the +RLM_LICENSE or ADLINK_LICENSE variable must be set to the correct license file location.

    To run the license manager, use the following command:

    rlm -c <location>
    @@ -136,11 +136,11 @@ 

    7.4. Running the License Manager Daemon<location> is the full path and filename of the license file. If licenses are distributed between multiple files, <location> should be the path to the directory that contains the license files.

    -

    The rlm command will start the PrismTech vendor daemon prismtech, -which controls the licensing of the OpenSplice DDS software.

    -

    To obtain a license for OpenSplice DDS from a License Manager Daemon +

    The rlm command will start the ADLINK vendor daemon prismtech, +which controls the licensing of the Vortex OpenSplice software.

    +

    To obtain a license for Vortex OpenSplice from a License Manager Daemon that is running on a different machine, set either the RLM_LICENSE -or prismtech_LICENSE environment variable to point to the License +or ADLINK_LICENSE environment variable to point to the License Manager Daemon, using the following syntax:

    @@ -190,8 +190,8 @@

    7.5. Utilitiesrlmutil, is available for license server management and administration. One feature of this utility is its ability to gracefully shut down the license manager. To shut down the -license manager, preventing the checkout of licenses for the OpenSplice -DDS software, run either of the following commands:

    +license manager, preventing the checkout of licenses for the Vortex OpenSplice +software, run either of the following commands:

    @@ -228,7 +228,7 @@

    7.5. UtilitiesTable Of Contents

    \ No newline at end of file diff --git a/docs/html/GettingStartedGuide/objects.inv b/docs/html/GettingStartedGuide/objects.inv index bee616a71..952525bc1 100644 Binary files a/docs/html/GettingStartedGuide/objects.inv and b/docs/html/GettingStartedGuide/objects.inv differ diff --git a/docs/html/GettingStartedGuide/pikeos-posix.html b/docs/html/GettingStartedGuide/pikeos-posix.html index a21a5e7fe..6910374b2 100644 --- a/docs/html/GettingStartedGuide/pikeos-posix.html +++ b/docs/html/GettingStartedGuide/pikeos-posix.html @@ -233,7 +233,7 @@

    Navigation

    \ No newline at end of file diff --git a/docs/html/GettingStartedGuide/platforms.html b/docs/html/GettingStartedGuide/platforms.html index a5de0b15e..6d94134ab 100644 --- a/docs/html/GettingStartedGuide/platforms.html +++ b/docs/html/GettingStartedGuide/platforms.html @@ -118,7 +118,7 @@

    Navigation

    \ No newline at end of file diff --git a/docs/html/GettingStartedGuide/preface.html b/docs/html/GettingStartedGuide/preface.html index 324206dda..0422c75cb 100644 --- a/docs/html/GettingStartedGuide/preface.html +++ b/docs/html/GettingStartedGuide/preface.html @@ -55,7 +55,7 @@

    Navigation

    1.1. About the Getting Started Guide¶

    The Getting Started Guide is included with the Vortex OpenSplice Documentation Set. This Guide is the starting point for anyone using, -developing or running applications with OpenSplice DDS.

    +developing or running applications with Vortex OpenSplice.

    This Getting Started Guide contains:

    \ No newline at end of file diff --git a/docs/html/GettingStartedGuide/product-info.html b/docs/html/GettingStartedGuide/product-info.html index 89495381a..36485385a 100644 --- a/docs/html/GettingStartedGuide/product-info.html +++ b/docs/html/GettingStartedGuide/product-info.html @@ -142,19 +142,19 @@

    3.2. Language and Compiler Bindings
    caution
    -
    NOTE: PrismTech only provides support on the officially-supported +
    NOTE: ADLINK only provides support on the officially-supported platforms due to difficult-to-fix issues with compiler-generated code, but some customers will fund us to qualify OpenSplice on their platform. If you wish to use a variant of an official platform, then as long as the issue can be recreated on the official platform it will be covered under an Vortex OpenSplice support contract. If you wish to request support -on a specific platform then please contact PrismTech -(http://www.prismtech.com/contact-us)
    +on a specific platform then please contact ADLINK +(http://ist.adlinktech.com/)

    @@ -279,7 +279,7 @@

    Navigation

    \ No newline at end of file diff --git a/docs/html/GettingStartedGuide/search.html b/docs/html/GettingStartedGuide/search.html index c8daf6ca1..f220e25d5 100644 --- a/docs/html/GettingStartedGuide/search.html +++ b/docs/html/GettingStartedGuide/search.html @@ -95,7 +95,7 @@

    Navigation

    \ No newline at end of file diff --git a/docs/html/GettingStartedGuide/searchindex.js b/docs/html/GettingStartedGuide/searchindex.js index 77dbff1ae..ad86363a5 100644 --- a/docs/html/GettingStartedGuide/searchindex.js +++ b/docs/html/GettingStartedGuide/searchindex.js @@ -1 +1 @@ -Search.setIndex({envversion:42,terms:{lwipconfig:5,common7:2,osplcon2c:11,under:[14,17,8,2,3],everi:[0,17],affect:6,pentium4gnu:18,armv4i:2,direct:[8,3],histor:0,consequ:5,second:[17,8],even:[0,11],"new":[0,18,2,5,6,11,14],net:2,metadata:0,moduleshow:11,centric:0,richest:0,here:[11,17,8,2],studio:2,path:[5,11,12,3],xml2int:17,wb_sacpp_pingpong_kernel_app_onli:18,libddsrrstorag:[18,11],pongread:[14,11,2,18],avenu:7,unix:1,total:[0,8],middlewar:[0,6],highli:[0,8],describ:[0,18,2,3,6,8,11,12,14,16,17],would:[5,11,12,18],overhead:6,tradecent:7,recommend:[1,15,12,5,3],type:[18,2,3,8,14,16],ccpp:[8,3],relat:[0,1,8],warn:[1,3],overrun:2,must:[18,2,3,4,5,11,12,14,17],word:0,smartdevic:2,work:[18,17,8,2],tnn:0,root:[14,3],overrid:1,give:[18,11,17,3],dds_connect:17,caution:13,unavail:0,want:[18,11,17,2],end:[0,18,11,3],how:[0,1,3,6,12,17],env:[18,11],enquiri:6,verifi:4,config:[4,14,11,2,3],updat:[6,17,2],lan:9,tunerguid:3,after:[18,6,11,3],befor:[18,3,4,5,12,17],demonstr:6,rhel4:12,attempt:[18,11],third:2,exclud:11,receiv:2,environ:[0,1,3,4,5,18,8,11,12,14,16,17],enter:[4,5,11,18,3],exclus:17,winc:2,order:[0,18,2,3,11,17],oper:[0,2,3,11,14,16],over:6,becaus:[5,11,17,2,18],privileg:4,flexibl:[0,17],unpreced:0,fit:3,fix:[6,8],better:0,persist:[0,3],comprehens:6,easier:0,them:[0,18,3,6,8,12,13,17],thei:[18,6,17,3],proce:[5,18],ospllist:2,x86_l2:12,choic:[0,17,8],sac_pingpong_kernel_app_onli:[18,11],each:[0,18,3,5,6,8,11,12,14],debug:[18,16,6,3],mean:[13,12,8,3],monolith:[18,11],extract:2,unbound:0,network:[0,1,3,5,6,18,8,11,9,15,17],reg_sz:2,newli:18,smp:18,content:[0,2,3,4,14,17],adapt:17,reader:[0,6,8,13],navig:17,situat:0,free:0,standard:[0,18,3,6,11,9],configuraion:[18,11],isv:12,filter:0,iso:6,regress:8,onto:[14,17,2,18],semaphor:17,rang:[6,8],independ:6,instruct:[14,6,3],alreadi:[14,11,17,2],top:8,similarli:17,john:2,osplstop:2,consol:[14,2],libddscor:[18,11],namespac:3,tool:[0,1,6],target:[3,5,8,11,16,17],provid:[0,18,2,3,4,5,6,8,11,13,14,15,16,17],opensplice_configur:17,minut:6,ram:[5,17],increment:0,seen:[0,14,5],deamon:[18,11],recreat:8,lp4:5,simplifi:[0,8],messageboard:[14,2],shall:3,object:[0,1,6],bsp:17,preset:8,phase:17,sub:[0,17,8],tradit:2,simplic:[14,2],paradigm:6,don:17,osvers:2,doc:7,flow:[6,3],doe:[4,9,2,3],declar:[5,17],ospl_spliced_unique_main:11,syntax:12,identifi:[18,17,2,13],menu:[4,14,5,3],explain:[14,6,18,2,3],apach:0,busi:[0,7],likewis:17,watch:6,compli:17,cryptographi:2,report:[13,3],bat:[4,2],method:[17,2],mandatori:17,result:[0,18,11,17],respons:[12,8,3],optimum:0,best:3,subject:7,expertis:0,awar:[14,6],databas:[0,18,8,3],discoveri:[0,9],figur:0,approach:[18,11,17],attribut:3,omg:[0,8],extend:3,extens:[0,16,3],preprocessor:8,toler:[0,8],protect:[4,2],fault:[0,8],lstand:5,initialdiscoveryperiod:3,endaddressspac:17,com:[0,2,3,4,5,6,7,8,12,16],opensplicevers:2,assur:0,ospltun:[5,3],splice_databas:17,guid:6,assum:[14,11,2,5],ether:12,liabil:7,been:[0,18,2,4,11,12,14,16,17],basic:6,quickli:13,userload:[14,2],xxx:[18,11],wdb:11,telnet:17,ani:[0,18,2,3,4,11,12,17,9],ident:14,gnu:[14,18],launcher:1,servic:[0,1,3,5,6,15,17],properti:[14,9,2,3],commerci:0,aim:0,sln:2,aid:17,pcpentium4:18,tabl:[0,6],toolkit:12,conf:5,vendor:[0,12],sever:[9,3],perform:[0,6,17,2,3],make:[18,2,5,11,14,17],format:[6,17,12],tgtsvr:[14,11,18],complex:0,ddsi2e:9,complet:[0,1,3,6,8,17],hand:17,tune:[6,8],undesir:0,scenario:[0,1,6,8,3],inherit:0,client:6,thi:[0,3,7,5,6,8,10,11,12,13,15,16,17],programm:6,jean:7,woburn:7,mapto:17,protocol:[0,6,8],just:3,ospl_sp_no_network:3,touchston:17,yet:[0,11],languag:[0,1,13,17,3],easi:[0,4],board:[14,11,17,18],els:17,save:4,opt:5,applic:[0,18,3,4,6,11,9,13,17],ospl_hom:[4,5,16,11,3],openfus:8,intercon:0,background:1,rnr:8,apart:8,measur:2,daemon:[0,1],specif:[0,1,3],manual:[6,17,2,3],remind:[18,11,17],www:[0,2,7,6,8,12],right:[0,18,2,7,12,14,17],ospl_sp_ddsi_statist:3,maxim:6,intern:0,successfulli:18,txt:[14,2],bottom:17,datawrit:3,buffer:[6,8,2],fog:1,armv4:2,"_arm":2,core:11,sacpp_pingpong_kernel:18,peer:9,plug:0,simul:[17,2],commit:2,produc:[18,11,17,8,2],ppc:5,openspliceddsv6:3,"float":12,profession:0,orsai:7,opensplice_product2:12,down:[14,12,2,18],coverag:[0,8],storag:[0,3],wan:9,accordingli:17,wai:[0,2,3,8,14,17],support:0,avail:[0,18,2,3,4,5,7,8,11,12,14,17,9],editor:2,saj5:8,call:[18,2,3,4,11,17],form:[0,14,18],offer:[0,8,3],osplputenv:2,libospl_cfg:17,java5:8,ospllaunch:4,heap:0,"true":[18,17,9,3],maximum:3,wrwb:14,reachabl:[6,3],linux2:[16,3],adopt:0,classic:6,proven:[0,8],diagnost:[0,1],exist:[4,14,17,18,3],trip:0,ospl_cmsoap:11,excel:0,test:[0,6,8,2],node:[0,18,2,3,6,8,12,17],intend:[0,6,13],brief:[18,2,5,6,11,14,16,17],ivfs_serv:17,sql:2,faster:0,pathnam:5,time:[0,1,6],chain:[14,18],oss:0,global:14,signific:[0,13],decid:[18,11],depend:[0,18,3,5,14,16,17],million:0,flash:[17,2],cach:0,armv7l:16,aspx:2,sourc:0,string:[0,11],osplstart:2,exact:0,rlm_licens:12,administr:[0,6,12,3],level:[0,2,3],gui:[14,18],item:[14,13,5],quick:3,setup:[11,17,12,3],dir:12,prevent:12,slower:[18,11],cost:0,idlpp:[5,8],port:[9,17,12,3],corba:[8,3],repli:8,current:[14,18,2,3],targetcpu:2,d9002:2,vs2008:2,gener:[0,1,6,3],custom_lib:8,splice:[1,17,8,3],address:[5,17,9,3],along:[18,11],box:[14,8,18],ld_bind_now:14,queue:3,multicast:[0,3,5,9,15,17],throughput:[0,6,3],extrem:0,convertor:17,ipc:15,regardless:3,modul:[18,11],instal:[1,6],mobil:2,market:0,msy:2,perl:2,i_install_dir:17,checkout:12,tightli:0,chapter:[18,2,3,5,11,14,15,16,17],enhanc:0,visual:2,prototyp:8,fly:0,uniqu:[11,17],can:[0,18,2,3,4,5,6,8,11,12,13,14,17],cab:1,purpos:[0,12,2],stream:[0,6,8],agent:11,topic:8,critic:[0,1],alwai:18,multipl:[0,1,8,12,17,9],ping:[14,11,17,2,18],write:[4,14,17],anyon:13,map:[18,3],product:0,usabl:0,mai:[18,3,2,7,5,6,11,9,14,15,16,17],mak:2,data:[0,1,6,17,3],"0x10000":14,practic:5,ospl_unique_main:11,explicit:11,inform:[0,7],"switch":[14,17],combin:16,os_putenv:[18,11],windsh:[18,11],cold:2,still:[0,18,6,11],dynam:[0,18,2,3,11,17],entiti:[0,3],conjunct:17,group:[0,14,6,9,18],monitor:[0,6,8,3],opensplc:6,olauncherpref:4,polici:0,instantli:17,platform:[0,1,6],window:1,mail:7,main:[6,11],non:[0,4,8,3],initi:[13,6,17,3],globalpartit:3,own:[0,1,3],now:[17,3],discuss:3,term:12,name:[18,2,3,5,11,12,14,17,9],drop:[14,18],crypto:2,separ:[18,11,17,12,3],compil:[4,1,5,3],domain:[0,18,3,8,9,14],replai:[6,8],replac:[17,2],individu:[0,14,12,18],continu:6,unlock:12,happen:3,shown:[2,3,12,13,14,17],space:[11,17,3],profil:[0,14,8,18],correct:[4,12,2,3],rlm:12,ospl_shmdump_unique_main:11,tmpf:15,argv:11,org:[0,12,2],argc:11,orb:[8,3],openspliceddsinstal:2,synchron:[18,11],ospl_shmem_secure_nativert:3,place:[0,18,11,2],ospl_shmem_no_network:3,first:[16,17,12,3],origin:17,directli:[0,14,8],kernel:[1,15,17,10],onc:[0,18,2,3,14,17],arrai:5,open:[0,4,11,2,18],size:[14,18,3],given:[11,17,2],sheet:6,convent:1,white:[6,8],conveni:[6,17,2],rlmdown:12,copi:[0,18,2,5,8,12,14],specifi:[0,18,2,3,4,5,11,14,17],broadcast:[5,15,17,3],"short":6,than:[0,18,3,6,10,15,17],wide:0,user_hom:4,posix:1,were:[4,18,17],mmstat:1,pre:[0,6],saj:8,sac:8,argument:1,deliv:[0,8,3],engin:0,squar:17,wb_sac_pingpong_kernel:18,note:6,forc:17,take:[5,6,11,18],advis:3,channel:[0,3],begin:17,sure:[17,2],normal:[16,3],tornado:1,ethernet:17,initial_and_align:3,icon:13,later:[18,11],runtim:[0,1],gracefulli:12,shot:14,cygpath:5,show:[0,14,11,17,3],concurr:12,permiss:4,xml:[18,2,3,5,11,14,17],onli:[0,18,3,5,8,11,12,13,17,9],activ:[14,2],state:0,black:8,offici:8,overwritten:17,variou:[17,13],get:6,soon:2,cannot:4,requir:[0,1,3,5,6,11,12,15,17,9],hostid:12,ospl_config:5,yield:17,where:[0,2,3,4,6,12,13,14,16,17,9],sooner01:2,rmi:[6,8],detect:[14,18],f77225b:2,ddsi:[0,5,15,3],volatil:[8,3],between:[0,17,12,8,3],"import":0,comp:[16,3],screen:[14,17],cycl:2,sparc:[16,3],include_posix_pthread_schedul:14,folder_cplus_stdlib:18,vmit:5,pertain:3,contract:8,audienc:13,tutori:[6,17,3],addressspac:17,improv:[18,11],dkm:1,improp:1,overview:0,exploit:0,lwipopt:5,coupl:0,marc:2,rebuild:[5,17,8,2,18],besteffort:3,gs3target:2,workspac:[14,18],pikeos_hom:5,those:[18,11,17,2],"case":[0,5,8,11,12,17],interoper:0,amend:1,mount:[14,11],do_m:2,hde:[2,3,5,11,14,16,17],ivf:17,advantag:[0,6],ctrl:4,ddsi2servic:9,cluster:0,pthread:15,develop:[0,1,6],etc:[0,18,2,3,4,5,11,12,13,14],ospl_projgen:1,same:[0,18,3,9,14,17],check:[18,2,4,8,11,14],binari:12,html:[6,3],"0x03000000":5,document:7,screenshot:17,assist:[6,3],driver:5,driven:0,capabl:[0,15,3],mani:[0,11,3],footprint:0,appropri:[0,18,2,3,4,14,17],without:[18,7,3,8,11,9,17],model:[0,1,17],execut:[0,2,3,4,5,14,16,17],your_app_name_databas:17,when:[0,18,2,3,5,6,11,12,14,16,17,9],rest:8,aspect:[0,3],hint:13,except:[18,11,17,3],blog:2,versa:0,real:[0,1,6,8,3],jacorb:8,around:8,read:[14,6,17,3],traffic:8,world:0,server:[18,2,6,11,12,14],"0x20000000":17,either:[16,17,12,8,3],output:[18,2,11,12,14,17],manag:[0,1,6],"function":[0,18,2,11,14,15,17],exit:[17,2],refer:[18,2,3,6,8,11,14,17],wb_sac_pingpong_kernel_app_onli:18,power:[0,3],inspect:[11,17,8],otherobjectnam:17,src:17,stand:3,ospl:[18,2,3,5,11,14,17],isocpp2:8,industri:0,processor:[0,6],effici:0,activest:2,yyi:[18,11],your:[1,17,12,5,3],log:[18,3,4,11,14,17],putenv:2,area:18,overwrit:17,start:[0,6],interfac:[0,3,6,8,15,17],low:0,ospl_logpath:[18,11,3],bundl:4,untar:16,notat:3,ospl_dur:11,nmake:2,possibl:[14,11,17,18],"default":[0,18,2,3,5,8,11,17],embed:[0,11,8],connect:[0,18,3,8,11,14,17],loadabl:17,creat:[0,18,2,3,5,11,14,17],certain:[2,3],dds_connectionlock:17,file:1,encompass:0,incorrect:4,again:2,googl:[6,8],hybrid:0,field:[0,8],ospl_networking_unique_main:11,valid:3,rdbm:8,ignor:2,you:[18,2,3,4,5,6,8,11,12,14,17],ospluri:2,genuin:0,registri:1,sequenc:0,symbol:[16,3],briefli:[14,18],reduc:0,directori:[18,2,3,4,5,6,8,11,12,14,16,17],descript:[18,2,5,6,11,14,16,17],pto:2,represent:8,all:[0,1,3,7,4,6,8,12,17],pluggabl:0,abil:[12,8],follow:[0,18,2,3,4,5,6,8,11,12,14,15,16,17],disk:[11,3],program:[14,12,2],rlmhostid:12,far:0,os_procinstallhook:18,faq:13,util:[0,1],mounttabl:17,mechan:[2,3],list:[18,2,6,8,11,13,14,17],adjust:[18,3],small:0,mutipl:18,enterpris:[0,12],lsbuf:5,tel:7,past:2,design:[0,6],pass:[11,17],opensplicedd:[5,2,3],excit:0,"48mb":5,devenv:2,section:[18,2,3,12,14,16,17],abl:8,nand:2,version:[0,2,3,4,11,12,16],"public":6,prismtech:[0,18,3,2,7,6,8,11,12,14,16],full:[15,8,2,12],memoryregion:17,variat:8,libdcpssac:[18,11],solari:[13,11,3],strong:0,modifi:4,legend:0,valu:[4,1,17,12,3],search:1,prior:[4,2,3],amount:5,pick:17,magnitud:0,via:[0,6,17,2,11],filenam:[5,12],establish:14,select:[0,14,17,18,3],ospl_shmem_ddsi2:3,regist:2,two:[9,11,17,12,3],opensplice_product1:12,autonom:0,taken:[12,13],more:[0,18,3,11,14,17],kernel_kernel:17,desir:[18,11,17,3],tester:[6,8],sac_pingpong_kernel:[18,11],prismtech_licens:12,particular:[0,2,3,6,9,14,17],known:[0,11],ospl_network:11,endpoint:0,hous:7,dev:[16,2,3],histori:2,hkey_local_machin:2,rescon:17,prompt:[4,14,11,2,3],rtnetwork:[8,3],challeng:0,templat:5,openssl:12,minimum:5,pong:[14,11,17,2,18],cours:[18,6,11],interconnect:0,secur:[0,1,6,3],rather:[0,6],anoth:[18,11,12],ospl_mmstat:11,resourc:6,variant:8,invok:[18,11,3],reflect:17,associ:[6,3],circumst:5,github:2,roundtrip:3,proto:8,help:[6,8,2,13],mission:[0,8],trade:0,rlmutil:12,paper:6,through:[6,17,8,3],pane:17,paramet:[0,18,2,3,5,14,17],style:[1,11,5],comspec:2,brows:[14,2,18],harmless:18,requestcombineperiod:3,might:[2,3],alter:17,good:7,"return":[12,2],libeay32:2,pingpong:[1,3],troubleshoot:1,unlik:9,refresh:14,easili:[0,14,18],achiev:[6,3],compris:5,found:[2,6,8,13,14,17],idea:3,procedur:[16,17,3],linkag:17,expect:[5,2],publish:[0,6,8],footnot:3,csdn:2,difficulti:6,qualifi:8,advanc:[0,17,8,3],ospl_sp_nativert:3,pub:[0,8],base:0,put:12,bash:[5,16],basi:12,prefac:1,thread:[14,11,18,5],launch:[5,2],omit:17,libdcpssacpp:18,taht:4,round:0,perhap:17,applici:8,"5th":7,notifi:17,feel:3,number:[2,3,12,14,16,17],done:[0,18,11,3],gpb:[6,8],blank:[14,18],miss:4,differ:[5,17,12,8,3],networkservic:3,gpj:17,script:[4,5,8],vxe:14,interact:[1,6],least:[5,3],store:[18,3],option:[0,18,2,3,5,11,14,16,17],relationship:3,park:7,sizebyt:5,pars:11,consult:[6,17],int509:17,remot:[0,14,8,2,3],remov:[18,11,17,2],bridg:[0,8],comput:0,packag:[14,18,3],built:[0,18,2,3,5,11,14,17],equival:11,lic:12,self:[0,18],also:[0,18,2,3,4,5,8,11,12,17,9],build:[1,17,3],distribut:[0,18,3,5,8,12,17],exec:14,filesystem:[5,15,11,17,18],reach:6,compl:18,most:[0,6,8,3],cygwin:5,cover:8,ext:3,part:[14,12,7],clean:[4,2],latest:[6,8,2],microsoft:2,rte:0,gold:6,cdk:5,session:5,rtp:[0,1,10,3],libdcpsgapi:[18,11],creatabl:3,usiong:6,copyright:[12,7],writer:[0,8,3],solut:[0,2],projgen:17,nativ:[5,15,6,3],mainten:8,fastest:0,common:2,set:0,startup:1,see:[18,11,17,2,3],osplconf:3,close:4,arm:[1,3],particip:9,ospl_splic:[18,11],subscript:0,experi:[0,6,8,3],altern:[0,1,3],complement:0,rostand:7,profile_develop:[14,18],popul:4,both:[0,18,3,8,12,14,16,17,9],openssl98:2,alon:3,"0025643ad2a7":12,pdf:[6,3],whole:[17,2,7],load:17,simpli:17,point:[0,18,2,4,5,11,12,13,14,17],schedul:14,header:3,shutdown:2,suppli:[0,18,6,11,12,17],identif:12,java:[0,5,6,8,13],resourcestor:17,devic:[5,2],due:8,empti:[18,11,17],waitforattach:3,imag:[14,11,17,18],ecosystem:0,fund:8,understand:6,demand:0,educ:6,chatter:[14,17,2],look:[17,12],batch:8,match:[18,17,9],abov:[14,11,17,2,18],error:[14,17,2,3],loos:0,loop:0,apponli:[1,11],malloc:11,gateshead:7,readi:[17,3],readm:[14,8,18],flashabl:17,itself:[0,17],minim:[0,6],higher:0,x86:[14,16,2,3],optim:[0,2],user:[0,18,3,4,6,8,11,9,13,17],stack:[14,17,5],lower:0,task:[18,11,17],lib:[18,11,2],ospl_sp_ddsi:3,entri:[18,2,5,11,14,17],muxa:5,elev:4,explan:3,c4748:2,"_apponli":11,lwip_hom:5,administ:6,bposix:5,shortcut:2,update_factor:3,input:3,subsequ:[17,9],include_posix_pthread:[14,18],bin:[18,2,5,11,12,14,17],march:7,transpar:8,characterist:0,resolv:11,collect:6,cmsoap:[5,11,8,18],popular:8,cohabit:[8,3],acknowledg:7,creation:17,some:[0,18,3,5,8,11,12,16,17],back:0,sampl:[0,14,8,3],ospl_cmsoap_unique_main:11,scale:[0,8],glibc:[16,3],per:[12,9],larg:[0,8],u1077:2,reproduc:7,machin:[0,14,17,12,3],previou:4,run:[0,1,15,6],rue:7,step:[18,2,3,5,14,16,17],cryptsoft:12,prerequisit:1,oea:5,faith:7,constraint:9,idl:[0,6,8],dialog:[14,18],block:11,sacpp:8,within:[0,18,2,3,8,11,14,15,17],bsd:5,ensur:[0,18,3,4,11,12,14],chang:[1,6,7,3],durabl:[0,18,11,8,3],megabyt:3,"long":8,custom:[0,6,3],includ:[0,18,2,3,6,8,11,12,13,17],suit:[17,7],vxworks5:11,link:[0,1,6,17,5],line:[18,2,3,4,11,12,16,17],sdk:2,info:[0,18,2,7,3,11,14],consist:[14,12,3],cedll:2,highlight:17,similar:[0,18,5,12,14,17],user1:14,repres:5,"char":11,chat:17,guarante:[0,17],bracket:17,servicenam:3,codeo:5,expirytim:3,vice:0,shmem:15,install_dir:[16,3],code:[0,2,3,4,5,6,8,12,16,17],queri:0,renown:0,privat:[0,9],wizard:3,young:12,fatal:2,sent:[14,12,3],implicitli:3,relev:[13,3],platformsdk:2,button:[4,14,2],"_pss":2,"try":3,create_particip:3,pleas:[0,18,2,3,8,11,14,17],"0x2":2,stdc:15,download:[0,18,11,17,2],click:[14,17,2,18],compat:2,index:6,compar:0,access:[0,18,2,4,8,12,14],chose:14,llwip4:5,ubuntu:13,becom:6,sinc:0,great:3,technolog:[0,8],osplgetenv:2,solaris8:[16,3],typic:0,appli:[13,17,2,3],approxim:3,api:[6,3],cloud:1,from:[0,3,4,5,6,8,12,16,17,9],usa:7,commun:[0,9,8,3],doubl:14,seamless:0,next:[18,2],doubt:17,usr:[11,17],remaind:10,"transient":3,ospl_durability_unique_main:11,c2220:2,perceiv:0,wce600:2,meet:6,control:[0,18,6,8,12,17],tar:16,lock:[0,12],ospl_shmem_ddsi:3,high:0,tag:11,tab:17,tao:8,subdirectori:4,instead:[18,11,2,3],ne11:7,overridden:[4,18,11],stop:[1,17,3],physic:[0,12],alloc:[18,12],essenti:6,bind:1,correspond:3,element:[17,3],issu:[6,8,7],allow:[0,18,3,5,8,11,12,9],ospl_uri:[18,2,3,5,11,14,17],move:0,evolutionari:1,portnr:3,unrival:0,superior:0,chosen:[0,3],ospl_sp_ddsi_nativert_cohabit:3,newsgroup:6,infrastructur:[0,3],decad:[0,8],therefor:[5,6,2],handl:[5,8],ospl_shmem_nativert:3,devel:5,front:[18,11],pongwrit:[14,11,2,18],profound:0,edit:[0,2,3,4,5,14,17],mode:[0,1,3,5,8,10],subset:3,"static":[5,11,17,18],our:[6,17],patch:2,special:13,out:[18,6,11],variabl:[18,2,3,4,5,11,12,14,16,17],suitabl:0,hardwar:[14,2,18],statist:[2,3],franc:7,shut:[12,2],coldbootinit:2,standalon:17,releas:[3,4,5,6,8,16],shortest:0,could:[18,11,2],ask:14,timer:11,keep:3,length:17,organis:6,networkinterfaceaddress:[17,3],softwar:[12,2],durabilityservic:3,qualiti:0,date:6,facil:5,prioriti:14,unknown:2,licens:[0,1],system:[0,18,2,3,5,6,8,11,13,14,15,16,17],messag:[14,17,2,3],termin:[4,2],"final":[18,11],udp:9,shell:[18,3,4,5,11,16],shelf:0,rsa:2,exactli:[18,11],structur:0,sec:0,deliveri:0,opensplice_install_dir:12,have:[0,18,2,4,5,6,8,11,14,17],reserv:[12,7],need:[0,18,2,3,5,6,11,12,13,14,17,9],libddso:[18,11],optimis:8,rout:[9,3],mix:0,which:[0,18,2,3,4,5,6,11,12,13,14,16,17],soap:[0,8,3],deploy:[0,6],who:[6,8,13],discov:9,deploi:[0,1,3,5,8,11,9,15,16,17],segment:[0,3],request:[8,3],uri:[5,11,17,18,3],"32m":15,durabilitykind:3,determin:[0,3,8,9,17,12],dbm:[0,8],text:2,progamm:6,anywai:3,redirect:2,locat:[0,18,2,3,5,6,11,12,14,9],should:[18,2,5,6,11,12,14,15,17],local:[11,8,2],connectionlocklink:17,autom:6,increas:5,osplconf2c:[1,5],enabl:[0,18,3,5,11,9,14,15,17],integr:[0,1,6,3],partit:[5,15,3],contain:[0,18,2,3,4,5,7,8,10,11,12,13,14,17],tuner:[0,18,3,5,6,8,11],alignmentkind:3,view:[0,14],legaci:0,vcvarsal:2,repris:12,correctli:[17,3],pattern:1,cpn805:14,dll:2,written:[14,6,11],"0ng":7,kei:[0,1,12],"1bl3":12,entir:14,disconnect:3,eclips:14,instant:0,liblwip4:5,equal:0,tsf:14,instanc:[4,2],equat:[18,11],splicedaemon:2,comment:17,maxwaitcount:3,vxwork:[10,1,3],respect:5,quit:2,trademark:7,compon:[1,6,12],treat:2,togeth:[0,8],last:[6,12],present:[0,5,2],multi:1,osplarg:11,align:3,defin:[17,3],ultra:0,howev:[5,11,18,3],layer:[0,6],domainid:9,ospl_shmdump:11,site:6,wb_sacpp_pingpong_kernel:18,archiv:[2,3],against:[5,2],parti:2,cross:5,largest:0,difficult:8,competit:0,http:[0,2,7,6,8,12],upon:[0,17],effect:14,global_t:17,decoupl:0,expand:17,mauricek:2,off:[0,17],well:[0,18,3,6,11,17],ospl_log:17,exampl:[0,1,6],command:[1,3],choos:[14,18,3],usual:[5,11,3],datashar:0,less:15,atlmfc:2,obtain:[0,6,12,2],tcp:[12,9],pikeos3:5,web:[0,6,12,7],makefil:[5,11,2],add:[5,2,3],smart:0,x86_arm:2,realiz:3,five:17,flashopensplicedd:2,realis:0,resid:0,like:[5,6,2],success:[0,14,11,17],corpor:7,necessari:[0,2,3,5,11,12],page:[1,6],exceed:12,vortexopensplic:[16,3],windriv:[14,11,18],linux:[4,10,16,13,3],"export":17,home:[4,6],transport:[0,6,9],tmp:3,win32:14,pcx86:17,feder:[8,3],lead:0,avoid:5,leas:3,leav:[14,18],endobject:17,slight:8,usag:[18,6,17,8,11],host:[0,1,17,12,3],although:14,storedirectori:3,dcp:[0,18,3,8,11,17],stage:[14,2],actual:[2,3],lifecycl:[0,8],fals:3,disabl:2,ospl_mmstat_unique_main:11,include_standalone_sym_tbl:[14,18],singleprocess:18,automat:[14,11,17,12,18],isocpp:8,libcmxml:[18,11],transfer:17,"var":[18,11],eai:12,subscrib:[0,6],getenv:2,wrmakefil:18,gain:6,uninstal:14,eas:[0,8],highest:0,bug:[6,13],count:12,made:[14,6,17,7,3],whether:[18,11,17],wish:[17,8,13],smooth:0,displai:[14,2],asynchron:0,record:[18,6,8],below:[0,2,3,6,11,13,14,16,17],limit:7,lvm:5,otherwis:[14,16,18,2,3],problem:14,pikeo:[1,15],evalu:[0,6,12],"int":[11,17],dure:[14,17],novemb:2,implement:[0,8,2],eric:12,inc:12,mutual:17,nonetheless:6,boot:2,detail:[1,6,17,13],other:[0,1],ddsi2:[9,8],activesync:2,activeperl:2,quicker:[18,11],reliabl:[0,3],pdata:3},objtypes:{},objnames:{},filenames:["about-ospl","index","windowsce","install-configure","launcher","pikeos-posix","documentation","contacts","product-info","using-with-cloud","platforms","vxworks-551","licensing","preface","vxworks-6-rtp","elinos","unixarm","integrity","vxworks-6-kernel"],titles:["2. About Vortex Opensplice","OpenSplice Getting Started Guide","14. Windows CE","5. Installation and Configuration","8. Launcher","15. PikeOS POSIX","4. Documentation and Support","18. Contacts & Notices","3. Product Details","6. Using Vortex OpenSplice with Vortex Cloud and Vortex Fog","9. Platform-specific Information","10. VxWorks 5.5.1","7. Licensing OpenSplice","1. Preface","11. VxWorks 6.x RTP","17. ELinOS","16. UNIX ARM platform","13. Integrity","12. VxWorks 6.x Kernel Mode"],objects:{},titleterms:{all:[18,11],evolutionari:8,rtp:14,file:[12,2,3],languag:8,style:18,configur:[0,18,11,17,3],platform:[10,16,18,8,3],window:[5,2,3],apponli:18,sourc:6,get:[1,13],overal:0,stop:4,pingpong:[14,11,17,2,18],util:[4,12],background:11,osplconf2c:[18,11],requir:[14,18],daemon:12,specif:10,troubleshoot:[4,2],launcher:4,benefit:0,mode:18,architectur:0,manag:12,summari:0,compil:8,kernel:[14,11,18],workbench:[14,18],set:[6,2],knowledg:6,startup:4,arm:16,librari:0,what:0,servic:[18,11,8],network:2,pattern:8,vortex:[0,18,2,3,6,9,14],fog:9,"import":[14,18],integr:17,altern:[18,11,2],run:[18,11,12,3],kei:8,gener:[17,12],standalon:[11,8],host:5,base:6,splice:11,path:18,valu:2,addit:6,prefac:13,about:[0,18,11,17,13],wcecompat:2,openssl:2,tutori:[14,2],iso:8,chang:17,dkm:[18,11],licens:12,improp:4,load:[18,11],overrid:[18,11],own:8,prerequisit:2,opensplic:[0,1,2,3,6,18,11,12,14,17,9],unix:[16,3],api:8,shmdump:17,instal:[14,16,12,3],guid:[1,13],your:8,cloud:9,differ:18,from:11,convent:13,memori:0,support:[6,8],two:18,custom:5,compon:8,start:[4,1,11,13],recommend:[18,11],ospl_xml2int:17,tool:[18,2,3,8,11,17],relat:11,notic:7,warn:17,link:[18,11],technic:6,conclus:0,multi:17,target:18,scalabl:0,amend:17,winsh:11,exampl:[18,2,3,5,11,14,17],project:[14,11,17,18],posix:5,cab:2,mmstat:[17,2],pre:[18,11],real:14,featur:[0,8],pikeo:5,process:[0,14],share:0,argument:17,indic:1,diagnost:[17,2],critic:17,chat:14,tabl:1,limit:[5,15],optimis:[18,11],vxwork:[14,11,18],develop:[12,3],secur:2,ospl_projgen:17,detail:8,note:[5,15,11,18],how:[5,11],other:3,interact:8,build:[18,2,5,8,11,14],command:[18,11,17],document:6,singl:0,complet:[18,11],elino:15,product:[6,8],registri:2,deploy:[5,15,12],tornado:11,symbol:[18,11],object:17,deploi:[14,2,18],multipl:[18,11],data:8,why:0,lwip:5,special:18,scenario:[18,11],bind:8,inform:[10,6],contact:7,environ:2,runtim:[18,11],thi:18,time:[14,11,18,3],model:8}}) \ No newline at end of file +Search.setIndex({envversion:42,terms:{pto:2,represent:8,all:[0,1,3,7,4,6,8,12,17],code:[0,2,3,4,5,8,12,16,17],edg:7,chain:[14,18],maximum:3,queri:0,oss:0,global:14,gateshead:7,pluggabl:0,lwipconfig:5,signific:[0,13],renown:0,higher:0,abil:[12,8],follow:[0,18,2,3,4,5,6,8,11,12,14,15,16,17],disk:11,content:[0,2,3,4,14,17],privat:[0,9],specif:[0,1,3],depend:[0,18,3,5,14,16,17],million:0,xml:[18,2,3,5,11,14,17],common7:2,wizard:3,young:12,ospl_network:11,common:2,osplcon2c:11,program:[14,12,2],unpreced:0,present:[0,5,2],under:[14,17,8,2,3],exit:[17,2],set:0,ist_info:7,aspx:2,sent:[14,12,3],suitabl:0,repris:12,file:1,sourc:0,everi:[0,17],string:[0,11],far:0,os_procinstallhook:18,faq:13,util:[0,1],mounttabl:17,interoper:0,facebook:7,boot:2,implicitli:3,osplstart:2,exact:0,relev:[13,3],look:[17,12],saj:8,rlm_licens:12,administr:[0,12,3],level:[0,2,3],button:[4,14,2],"_pss":2,list:[18,2,6,8,11,13,14,17],previou:4,"try":3,launcher:1,adjust:[18,3],create_particip:3,pentium4gnu:18,team:7,small:0,round:0,dir:12,armv4i:2,pleas:[0,18,2,3,8,11,14,17],enterpris:[0,12],lsbuf:5,tel:7,franc:7,"0x2":2,eas:[0,8],direct:[8,3],stdc:15,histor:0,past:2,consequ:5,second:[17,8],cost:0,design:[0,6],ospl_sp_ddsi_nativert_cohabit:3,pass:[11,17],download:[0,18,11,17,2],run:[0,1,15],opensplicedd:[5,2,3],port:[9,17,12,3],even:[0,11],subsequ:[17,9],corba:[8,3],servic:[0,1,3,5,6,15,17],sub:[0,17,8],compar:0,devenv:2,repli:8,section:[18,2,3,12,14,16,17],abl:8,brief:[18,2,5,6,11,14,16,17],access:[0,18,2,4,8,12,14],host:[0,1,17,12,3],version:[2,3,4,11,12,16],targetcpu:2,basic:6,"new":[0,18,2,5,11,14],net:2,"public":6,metadata:0,moduleshow:11,prismtech:[12,2],centric:0,chose:14,llwip4:5,variat:8,gener:[0,1,6,3],chang:[1,6,7,3],richest:0,here:[11,17,8,2],custom_lib:8,studio:2,free:0,splice:[1,17,8,3],meet:6,splice_databas:17,"0xa":7,strong:0,modifi:4,sinc:0,valu:[4,1,17,12,3],box:[14,8,18],xml2int:17,search:1,purpos:[0,12,2],copyright:[12,7],technolog:[0,8,7],osplgetenv:2,loos:0,queue:3,prior:[4,2,3],amount:5,multicast:[0,3,5,9,15,17],throughput:[0,3],pick:17,real:[0,1,8,3],extrem:0,implement:[0,8,2],convertor:17,magnitud:0,liblwip4:5,ipc:15,via:[0,6,17,2,11],regardless:3,prerequisit:1,apach:0,modul:[18,11],otherwis:[14,16,18,2,3],layer:0,pongread:[14,11,2,18],avenu:7,ask:14,unix:1,api:[6,3],instal:[1,6],total:[0,8],establish:14,lan:9,select:[0,14,17,18,3],highli:[0,8],asynchron:0,done:[0,18,11,3],from:[0,3,4,5,6,8,12,16,17,9],describ:[0,18,2,3,6,8,11,12,14,16,17],msy:2,commun:[0,9,8,3],etc:[0,18,2,3,4,5,11,12,13,14],regist:2,seamless:0,opensplice_product1:12,next:[18,2],readi:[17,3],doubt:17,call:[18,2,3,4,11,17],tradecent:7,autonom:0,recommend:[1,15,12,5,3],i_install_dir:17,otherobjectnam:17,type:[18,2,3,8,14,16],tightli:0,more:[0,18,3,11,14,17],reachabl:[6,3],plug:0,desir:[18,11,17,3],faith:7,"0x03000000":5,relat:[0,1,8],enhanc:0,warn:[1,3],visual:2,"transient":3,prototyp:8,particular:[0,2,3,6,9,14,17],known:[0,11],compani:7,cach:0,overrun:2,must:[18,2,3,4,5,11,12,14,17],fly:0,ospl_durability_unique_main:11,endpoint:0,word:0,conf:5,perceiv:0,setup:[11,17,12,3],work:[18,17,8,2],uniqu:[11,17],dev:[16,2,3],histori:2,hkey_local_machin:2,can:[0,18,2,3,4,5,6,8,11,12,13,14,17],cab:1,tnn:0,root:[14,3],sarl:7,appropri:[0,18,2,3,4,14,17],control:[0,18,17,12,8],omit:17,prompt:[4,14,11,2,3],rtnetwork:[8,3],stream:[0,8],give:[18,11,17,3],lock:[0,12],challeng:0,pthread:15,ospl_shmem_ddsi:3,templat:5,isv:12,topic:8,critic:[0,1],dds_connect:17,caution:13,unavail:0,want:[18,11,17,2],pong:[14,11,17,2,18],tao:8,interconnect:0,alwai:18,cours:[18,11],multipl:[0,1,8,12,17,9],instant:0,secur:[0,1,3],rather:0,anoth:[18,11,12],fog:1,ping:[14,11,17,2,18],perhap:17,write:[4,14,17],how:[0,1,17,12,3],anyon:13,env:[18,11],subdirectori:4,enquiri:6,instead:[18,11,2,3],config:[4,14,11,2,3],ospl_mmstat:11,updat:[17,2],ne11:7,product:0,resourc:6,ospl:[18,2,3,5,11,14,17],overridden:[4,18,11],ospl_shmem_ddsi2:3,less:15,tunerguid:3,after:[18,6,11,3],minimum:5,hde:[2,3,5,11,14,16,17],usabl:0,constraint:9,reflect:17,befor:[18,3,4,5,12,17],adlinktech_usa:7,mai:[18,3,2,7,5,6,11,9,14,15,16,17],end:[0,18,11,3],mak:2,datawrit:3,data:[0,1,17,3],"0x10000":14,advantag:0,alloc:[18,12],github:2,attempt:[18,11],practic:5,third:2,roundtrip:3,bind:1,minim:0,explicit:11,correspond:3,element:[17,3],issu:[6,8],inform:[0,7],"switch":[14,17],cannot:4,environ:[0,1,3,4,5,18,8,11,12,14,16,17],allow:[0,18,3,5,8,11,12,9],enter:[4,5,11,18,3],exclus:17,mechan:[2,3],xxx:[18,11],flashabl:17,order:[0,18,2,3,11,17],includ:[0,18,2,3,6,8,11,12,13,17],oper:[0,2,3,11,14,16],batch:8,least:[5,3],creation:17,help:[6,8,2,13],advis:3,semaphor:17,demand:0,ospl_uri:[18,2,3,5,11,14,17],offici:8,move:0,soon:2,trade:0,rlmutil:12,increas:5,evolutionari:1,through:[6,17,8,3],pane:17,effici:0,cold:2,portnr:3,dynam:[0,18,2,3,11,17],paramet:[0,18,2,3,5,14,17],unrival:0,superior:0,style:[1,11,5],group:[0,14,6,9,18],monitor:[0,8,3],fit:3,olauncherpref:4,chosen:[0,3],brows:[14,2,18],fix:[6,8],complex:0,instantli:17,better:0,platform:[0,1],window:1,newsgroup:6,infrastructur:[0,3],persist:[0,3],comprehens:6,mail:7,decad:[0,8],main:[6,11],might:[2,3],easier:0,them:[0,18,3,8,12,13,17],good:7,"return":[12,2],thei:[18,17,3],libeay32:2,handl:[5,8],profession:0,ospl_shmem_nativert:3,ospllist:2,devel:5,flash:[17,2],x86_l2:12,verifi:4,front:[18,11],platformsdk:2,now:[17,3],discuss:3,pongwrit:[14,11,2,18],ospl_projgen:1,choic:[0,17,8],term:12,taht:4,name:[18,2,3,5,11,12,14,17,9],profound:0,edit:[0,2,3,4,5,14,17],troubleshoot:1,drop:[14,18],instruct:[14,3],refresh:14,separ:[18,11,17,12,3],easili:[0,14,18],achiev:3,adlink_licens:12,mode:[0,1,3,5,8,10],compris:5,each:[0,18,3,5,8,11,12,14],debug:[18,16,3],found:[2,6,8,13,14,17],difficult:8,gui:[14,18],mean:[13,12,8,3],compil:[4,1,5,3],domain:[0,18,3,8,9,14],replai:8,monolith:[18,11],detect:[14,18],map:[18,3],mutipl:18,replac:[17,2],individu:[0,14,12,18],idea:3,procedur:[16,17,3],linkag:17,been:[0,18,2,4,11,12,14,16,17],"static":[5,11,17,18],connect:[0,18,3,8,11,14,17],our:[6,17],happen:3,patch:2,extract:2,special:13,out:[18,6,11],variabl:[18,2,3,4,5,11,12,14,16,17],shown:[2,3,12,13,14,17],unbound:0,network:[0,1,3,5,18,8,11,9,15,17],space:[11,17],reg_sz:2,open:[0,4,11,2,18],newli:18,publish:[0,6,8],smp:18,profil:[0,14,8,18],novemb:2,adapt:17,reader:[0,6,8,13],hardwar:[14,2,18],correct:[4,12,2,3],integr:[0,1,3],rlm:12,difficulti:6,shut:[12,2],ospl_shmdump_unique_main:11,navig:17,advanc:[0,17,8,3],upon:[0,17],tmpf:15,situat:0,differ:[5,17,12,8,3],pub:[0,8],standard:[0,18,3,6,11,9],coldbootinit:2,standalon:17,base:0,configuraion:[18,11],put:12,org:[12,2],toolkit:12,argc:11,orb:[8,3],shortest:0,basi:12,sampl:[0,14,8,3],prefac:1,your:[1,17,12,5,3],convent:1,thread:[14,11,18,5],launch:[5,2],argument:1,where:[0,2,3,4,12,13,14,16,17,9],could:[18,11,2],openspliceddsinstal:2,synchron:[18,11],ospl_shmem_secure_nativert:3,timer:11,keep:3,filter:0,length:17,properti:[14,9,2,3],organis:6,ospl_shmem_no_network:3,sln:2,regress:8,applici:8,onto:[14,17,2,18],"5th":7,networkinterfaceaddress:[17,3],first:[16,17,12,3],origin:17,softwar:[12,2],rang:[6,8],notifi:17,directli:[0,14,8],prevent:12,feel:3,onc:[0,18,2,3,14,17],arrai:5,independ:6,qualiti:0,number:[2,3,12,14,16,17],date:6,unlik:9,alreadi:[14,11,17,2],csdn:2,messag:[14,17,2,3],blank:[14,18],slower:[18,11],miss:4,size:[14,18,3],prioriti:14,given:[11,17,2],networkservic:3,gpj:17,script:[4,5,8],vxe:14,unknown:2,top:8,system:[0,18,2,3,5,8,11,13,14,15,16,17],gpb:8,binari:12,rlmhostid:12,physic:[0,12],similarli:17,termin:[4,2],white:8,conveni:[6,17,2],"final":[18,11],store:[18,3],low:0,udp:9,shell:[18,3,4,5,11,16],consol:[14,2],option:[0,18,2,3,5,11,14,16,17],relationship:3,namespac:3,shelf:0,tool:[0,1],messageboard:[14,2],domainid:9,rhel4:12,specifi:[0,18,2,3,4,5,11,14,17],task:[18,11,17],broadcast:[5,15,17,3],sizebyt:5,pars:11,consult:[6,17],qualifi:8,int509:17,than:[0,18,3,10,15,17],undesir:0,wide:0,john:2,user_hom:4,target:[3,5,8,11,16,17],remot:[0,14,8,2,3],remov:[18,11,17,2],ospl_sp_ddsi:3,structur:0,ospl_unique_main:11,optimum:0,bridg:[0,8],posix:1,were:[4,18,17],mandatori:17,mmstat:1,other:[0,1],initi:[13,17,3],html:3,pre:0,eai:12,comput:0,tsf:14,sac:8,pertain:3,ram:[5,17],ani:[0,18,2,3,4,11,12,17,9],privileg:4,packag:[14,18,3],opensplice_install_dir:12,have:[0,18,2,4,5,8,11,14,17],tabl:[0,6],need:[0,18,2,3,5,6,11,12,13,14,17,9],rlmdown:12,deamon:[18,11],exclud:11,libddso:[18,11],well:[0,18,11,17,3],optimis:8,libddscor:[18,11],bash:[5,16],engin:0,built:[0,18,2,3,5,11,14,17],equival:11,lic:12,wb_sac_pingpong_kernel:18,idlpp:[5,8],self:[0,18],lp4:5,mount:[14,11],click:[14,17,2,18],also:[0,18,2,3,4,5,8,11,12,17,9],high:0,exampl:[0,1],comment:17,take:[5,11,18],which:[0,18,2,3,4,5,6,11,12,13,14,16,17],combin:16,subject:7,soap:[0,8,3],channel:[0,3],compat:2,begin:17,copi:[0,18,2,5,8,12,14],distribut:[0,18,3,5,8,12,17],deploy:[0,6],buffer:[8,2],licens:[0,1],reach:6,compl:18,rsa:2,os_putenv:[18,11],preset:8,item:[14,13,5],cygwin:5,ethernet:17,phase:17,libospl_cfg:17,segment:[0,3],initial_and_align:3,heap:0,"48mb":5,tradit:2,simplic:[14,2],durabilityservic:3,don:17,correctli:[17,3],osvers:2,filesystem:[5,15,11,17,18],syntax:12,adopt:0,cover:8,uri:[5,11,17,18,3],"32m":15,fals:3,durabilitykind:3,ext:3,declar:[5,17],place:[0,18,11,2],clean:[4,2],databas:[0,18,8,3],five:17,servicenam:3,usual:[5,11,3],microsoft:2,gracefulli:12,rte:0,ospl_spliced_unique_main:11,install_dir:[16,3],dbm:[0,8],cygpath:5,gold:6,show:[0,14,11,17,3],discov:9,particip:9,osplstop:2,cdk:5,"0x20000000":17,concurr:12,rtp:[0,1,10,3],permiss:4,libdcpsgapi:[18,11],identifi:[18,17,2,13],discoveri:[0,9],anywai:3,creatabl:3,d9002:2,current:[14,18,2,3],onli:[0,18,3,5,8,11,12,13,17,9],exactli:[18,11],locat:[0,18,2,3,5,6,11,12,14,9],execut:[0,2,3,4,5,14,16,17],facil:5,menu:[4,14,5,3],explain:[14,18,2,3],writer:[0,8,3],solut:[0,2],state:0,diagnost:[0,1],should:[18,2,5,6,11,12,14,15,17],busi:0,black:8,pathnam:5,footnot:3,local:[11,8,2],overwritten:17,info:[0,18,2,3,11,14],projgen:17,connectionlocklink:17,variou:[17,13],get:6,ppc:5,likewis:17,stop:[1,17,3],compli:17,mission:[0,8],nativ:[5,15,3],mainten:8,vxwork:[10,1,3],fastest:0,cryptographi:2,report:[13,3],osplconf2c:[1,5],requir:[0,1,3,5,11,12,15,17,9],scale:[0,8],bat:[4,2],hostid:12,enabl:[0,18,3,5,11,9,14,15,17],ospl_config:5,excel:0,touchston:17,yield:17,method:[17,2],provid:[0,18,2,3,4,5,6,8,11,13,14,15,16,17],besteffort:3,statist:[2,3],partit:[5,15,3],contain:[0,18,2,3,4,5,7,8,10,11,12,13,14,17],tuner:[0,18,3,5,8,11],alignmentkind:3,view:[0,14],sooner01:2,legaci:0,vcvarsal:2,detail:[1,6,17,13],"float":12,still:[0,18,6,11],startup:1,cedll:2,see:[18,11,17,2,3],full:[15,8,2,12],osplconf:3,result:[0,18,11,17],respons:[12,8,3],reserv:[12,7],close:4,rmi:8,becaus:[5,11,17,2,18],arm:[1,3],best:3,vs2008:2,expertis:0,awar:14,flexibl:[0,17],kei:[0,1,12],f77225b:2,redirect:2,down:[14,12,2,18],pattern:1,user:[0,18,3,4,6,8,11,9,13,17],hybrid:0,cpn805:14,dll:2,written:[14,11],volatil:[8,3],ospl_splic:[18,11],between:[0,17,12,8,3],"import":0,subscript:0,experi:[0,6,8,3],approach:[18,11,17],libdcpssac:[18,11],ospllaunch:4,attribut:3,altern:[0,1,3],pdata:3,shall:3,omg:[0,8],extend:3,web:[0,6,12,7],comp:[16,3],screen:[14,17],flow:3,rostand:7,cycl:2,sparc:[16,3],add:[5,2,3],preprocessor:8,include_posix_pthread_schedul:14,toler:[0,8],folder_cplus_stdlib:18,eclips:14,embed:[0,11,8],profile_develop:[14,18],popul:4,both:[0,18,3,8,12,14,16,17,9],protect:[4,2],openssl98:2,extens:[0,16,3],fault:[0,8],howev:[5,11,18,3],initialdiscoveryperiod:3,alon:3,equal:0,contract:8,"0025643ad2a7":12,polici:0,audienc:13,instanc:[4,2],decid:[18,11],agent:11,splicedaemon:2,pdf:3,dkm:1,com:[0,2,3,4,5,6,7,8,12,16],improp:1,opensplicevers:2,assur:0,simpli:17,solari:[13,11,3],session:5,figur:0,within:[0,18,2,3,8,11,14,15,17],schedul:14,maxwaitcount:3,address:[5,17,9,3],form:[0,14,18],ospltun:[5,3],header:3,exploit:0,shutdown:2,path:[5,11,12,3],respect:5,guid:6,assum:[14,11,2,5],along:[18,11],datashar:0,quit:2,becom:6,lwipopt:5,creat:[0,18,2,3,5,11,14,17],coupl:0,harmless:18,would:[5,11,12,18],rebuild:[5,17,8,2,18],trademark:7,due:8,empti:[18,11,17],legend:0,compon:[1,6,12],"int":[11,17],treat:2,subscrib:0,ecosystem:0,dure:[14,17],waitforattach:3,quickli:13,field:[0,8],circumst:5,userload:[14,2],imag:[14,11,17,18],gs3target:2,wb_sacpp_pingpong_kernel_app_onli:18,telnet:17,wish:[17,8,13],overwrit:17,fund:8,togeth:[0,8],workspac:[14,18],requestcombineperiod:3,c2220:2,educ:6,chatter:[14,17,2],those:[18,11,17,2],"case":[0,5,8,11,12,17],doe:[4,9,2,3],multi:1,ident:14,osplarg:11,gnu:[14,18],amend:1,align:3,do_m:2,c4748:2,commerci:0,alter:17,aim:0,defin:[17,3],invok:[18,11,3],overrid:1,smart:0,abov:[14,11,17,2,18],error:[14,17,2,3],aid:17,ultra:0,lstand:5,loop:0,argv:11,bin:[18,2,5,11,12,14,17],ivf:17,pcpentium4:18,realis:0,increment:0,tar:16,ospl_shmdump:11,kernel:[1,15,17,10],ld_bind_now:14,deliv:[0,8,3],readm:[14,8,18],non:[0,4,8,3],wb_sacpp_pingpong_kernel:18,activ:[14,2],cluster:0,middlewar:0,archiv:[2,3],endaddressspac:17,linkedin:7,seen:[0,14,5],vendor:[0,12],mani:[0,11,3],sever:[9,3],memoryregion:17,disabl:2,develop:[0,1,6],proto:8,perform:[0,17,2,3],parti:2,make:[18,2,5,11,14,17],format:[17,12],excit:0,cross:5,same:[0,18,3,9,14,17],eric:12,fatal:2,tgtsvr:[14,11,18],tutori:[17,3],interact:1,largest:0,libddsrrstorag:[18,11],document:7,ddsi2e:9,complet:[0,1,17,8,3],"1bl3":12,competit:0,http:[0,2,7,6,8,12],addressspac:17,screenshot:17,optim:[0,2],cloud:1,vmit:5,assist:[6,3],ospl_sp_nativert:3,effect:14,disconnect:3,hand:17,driven:0,nand:2,global_t:17,pingpong:[1,3],improv:[18,11],footprint:0,decoupl:0,stack:[14,17,5],tune:8,squar:17,lower:0,mauricek:2,off:[0,17],lib:[18,11,2],scenario:[0,1,8,3],globalpartit:3,whole:[17,2,7],page:[1,6],itself:[0,17],inherit:0,muxa:5,ospl_log:17,without:[18,7,3,8,11,9,17],command:[1,3],elev:4,choos:[14,18,3],entiti:[0,3],programm:6,jean:7,woburn:7,mapto:17,rout:[9,3],ubuntu:13,latest:[8,2],explan:3,load:17,sec:0,protocol:[0,8],entri:[18,2,5,11,14,17],just:3,your_app_name_databas:17,atlmfc:2,obtain:[0,12,2],tcp:[12,9],ospl_sp_no_network:3,kernel_kernel:17,against:[5,2],"_apponli":11,lwip_hom:5,aspect:[0,3],world:0,rest:8,yet:[0,11],languag:[0,1,13,17,3],ist:[0,6,8,7],site:6,bposix:5,easi:[0,4],mix:0,point:[0,18,2,4,5,11,12,13,14,17],makefil:[5,11,2],except:[18,11,17,3],shortcut:2,blog:2,update_factor:3,valid:3,larg:[0,8],board:[14,11,17,18],versa:0,overview:0,quick:3,input:3,save:4,include_posix_pthread:[14,18],match:[18,17,9],build:[1,17,3],opt:5,applic:[0,18,3,4,6,11,9,13,17],jacorb:8,ctrl:4,around:8,recreat:8,transpar:8,read:[14,17,3],openfus:8,x86_arm:2,adlinktech:[0,6,8,7],realiz:3,traffic:8,background:1,flashopensplicedd:2,rnr:8,part:[14,12,7],characterist:0,associ:[6,3],apart:8,linux:[4,10,16,13,3],measur:2,daemon:[0,1],resid:0,like:[5,6,2],success:[0,14,11,17],filenam:[5,12],corpor:7,manual:[6,17,2,3],resolv:11,server:[14,11,12,2,18],collect:6,own:[0,1,3],cmsoap:[5,11,8,18],necessari:[0,2,3,5,11,12],either:[16,17,12,8,3],popular:8,output:[18,2,11,12,14,17],ospluri:2,variant:8,manag:[0,1,6],two:[9,11,17,12,3],cohabit:[8,3],"function":[0,18,2,11,14,15,17],wdb:11,www:[12,2,7],right:[0,18,2,7,12,14,17],vortexopensplic:[16,3],who:[8,13],windriv:[14,11,18],simplifi:[0,8],ospl_sp_ddsi_statist:3,acknowledg:7,twitter:7,suppli:[0,18,11,17,12],some:[0,18,3,5,8,11,12,16,17],back:0,sac_pingpong_kernel_app_onli:[18,11],certain:[2,3],intern:0,sure:[17,2],"export":17,wce600:2,guarante:[0,17],successfulli:18,transport:[0,9],registri:1,tmp:3,win32:14,pcx86:17,txt:[14,2],ospl_hom:[4,5,16,11,3],feder:[8,3],lead:0,remind:[18,11,17],mobil:2,glibc:[16,3],exec:14,per:[12,9],ether:12,osplputenv:2,tornado:1,cryptsoft:12,armv7l:16,leav:[14,18],market:0,endobject:17,capabl:[0,15,3],u1077:2,"_arm":2,reproduc:7,symbol:[16,3],refer:[18,2,3,8,11,14,17],expand:17,core:11,object:[0,1,6],wb_sac_pingpong_kernel_app_onli:18,power:[0,3],slight:8,bsp:17,inspect:[11,17,8],usag:[18,6,17,8,11],els:17,rue:7,step:[18,2,3,5,14,16,17],sacpp_pingpong_kernel:18,although:14,peer:9,java:[0,5,8,13],oea:5,pikeos_hom:5,appli:[13,17,2,3],dcp:[0,18,3,8,11,17],stage:[14,2],chapter:[18,2,3,5,11,14,15,16,17],src:17,tester:8,openssl:12,actual:[2,3],usa:7,most:[0,6,8,3],proce:[5,18],conjunct:17,marc:2,ivfs_serv:17,malloc:11,simul:[17,2],idl:[0,8],lifecycl:[0,8],stand:3,dialog:[14,18],isocpp2:8,apponli:[1,11],commit:2,industri:0,solaris8:[16,3],putenv:2,produc:[18,11,17,8,2],block:11,ospl_mmstat_unique_main:11,subset:3,include_standalone_sym_tbl:[14,18],openspliceddsv6:3,sacpp:8,activest:2,devic:[5,2],deploi:[0,1,3,5,8,11,9,15,16,17],tag:11,opensplice_configur:17,automat:[14,11,17,12,18],opensplice_product2:12,isocpp:8,bsd:5,uninstal:14,coverag:[0,8],identif:12,ensur:[0,18,3,4,11,12,14],therefor:[5,2],perl:2,storag:[0,3],leas:3,durabl:[0,18,11,8,3],crypto:2,wan:9,accordingli:17,processor:0,log:[18,3,4,11,14,17],wai:[0,2,3,8,14,17],area:18,libcmxml:[18,11],transfer:17,support:0,vallei:7,megabyt:3,"long":8,custom:[0,6,3],avail:[0,18,2,3,4,5,7,8,11,12,14,17,9],start:0,interfac:[0,15,17,8,3],editor:2,exceed:12,saj5:8,"var":[18,11],typic:0,icon:13,machin:[0,14,17,12,3],vxworks5:11,entir:14,usr:[11,17],deliveri:0,winc:2,driver:5,libdcpssacpp:18,complement:0,offer:[0,8,3],forc:17,great:3,bundl:4,untar:16,getenv:2,java5:8,taken:[12,13],thi:[0,3,7,5,6,8,10,11,12,13,15,16,17],wrmakefil:18,link:[0,1,6,17,5],adlink:[0,18,3,2,7,6,8,11,12,14,16],orsai:7,line:[18,2,3,4,11,12,16,17],highest:0,"true":[18,17,9,3],bug:[6,13],sdk:2,count:12,notat:3,ospl_dur:11,made:[14,6,17,7,3],nmake:2,consist:[14,12,3],possibl:[14,11,17,18],whether:[18,11,17],checkout:12,tab:17,smooth:0,displai:[14,2],wrwb:14,record:[18,8],below:[0,2,3,6,11,13,14,16,17],rescon:17,limit:7,ccpp:[8,3],unlock:12,lvm:5,highlight:17,problem:14,remaind:10,similar:[0,18,5,12,14,17],reliabl:[0,3],expect:[5,2],model:[0,1,17],linux2:[16,3],later:[18,11],loadabl:17,pikeo:[1,15],evalu:[0,6,12],user1:14,storedirectori:3,request:[8,3],windsh:[18,11],proven:[0,8],repres:5,"char":11,dds_connectionlock:17,armv4:2,ddsi:[0,5,15,3],exist:[4,14,17,18,3],chat:17,home:[4,6],encompass:0,resourcestor:17,smartdevic:2,check:[18,2,4,8,11,14],intercon:0,inc:12,incorrect:4,again:2,mutual:17,equat:[18,11],googl:8,nonetheless:6,hint:13,shot:14,ospl_cmsoap:11,when:[0,18,2,3,5,11,12,14,16,17,9],pikeos3:5,intend:[0,6,13],x86:[14,16,2,3],"default":[0,18,2,3,5,8,11,17],ospl_networking_unique_main:11,bracket:17,rdbm:8,normal:[16,3],test:[0,8,2],ignor:2,you:[18,2,3,4,5,6,8,11,12,14,17],runtim:[0,1],node:[0,18,2,3,8,12,17],trip:0,sac_pingpong_kernel:[18,11],genuin:0,determin:[0,3,8,9,17,12],yyi:[18,11],ospl_cmsoap_unique_main:11,expirytim:3,sequenc:0,last:12,ddsi2:[9,8],activesync:2,briefli:[14,18],releas:[4,5,16,8,3],sql:2,doubl:14,activeperl:2,codeo:5,reduc:0,receiv:2,quicker:[18,11],faster:0,vice:0,directori:[18,2,3,4,5,8,11,12,14,16,17],suit:[17,7],bottom:17,descript:[18,2,5,6,11,14,16,17],comspec:2,singleprocess:18,ospl_logpath:[18,11,3],liabil:7,text:2,shmem:15,time:[0,1],ddsi2servic:9,avoid:5},objtypes:{},objnames:{},filenames:["about-ospl","index","windowsce","install-configure","launcher","pikeos-posix","documentation","contacts","product-info","using-with-cloud","platforms","vxworks-551","licensing","preface","vxworks-6-rtp","elinos","unixarm","integrity","vxworks-6-kernel"],titles:["2. About Vortex Opensplice","OpenSplice Getting Started Guide","14. Windows CE","5. Installation and Configuration","8. Launcher","15. PikeOS POSIX","4. Documentation and Support","18. Contacts & Notices","3. Product Details","6. Using Vortex OpenSplice with Vortex Cloud and Vortex Fog","9. Platform-specific Information","10. VxWorks 5.5.1","7. Licensing Vortex OpenSplice","1. Preface","11. VxWorks 6.x RTP","17. ELinOS","16. UNIX ARM platform","13. Integrity","12. VxWorks 6.x Kernel Mode"],objects:{},titleterms:{all:[18,11],evolutionari:8,rtp:14,file:[12,2,3],languag:8,style:18,configur:[0,18,11,17,3],platform:[10,16,18,8,3],window:[5,2,3],apponli:18,sourc:6,get:[1,13],overal:0,stop:4,pingpong:[14,11,17,2,18],util:[4,12],background:11,osplconf2c:[18,11],requir:[14,18],daemon:12,specif:10,troubleshoot:[4,2],launcher:4,benefit:0,mode:18,architectur:0,manag:12,summari:0,compil:8,kernel:[14,11,18],workbench:[14,18],set:[6,2],knowledg:6,startup:4,arm:16,librari:0,what:0,servic:[18,11,8],network:2,pattern:8,vortex:[0,18,2,3,6,12,14,17,9],fog:9,"import":[14,18],integr:17,altern:[18,11,2],run:[18,11,12,3],kei:8,gener:[17,12],standalon:[11,8],host:5,base:6,splice:11,path:18,valu:2,addit:6,prefac:13,about:[0,18,11,17,13],wcecompat:2,openssl:2,tutori:[14,2],iso:8,chang:17,dkm:[18,11],licens:12,improp:4,load:[18,11],overrid:[18,11],own:8,prerequisit:2,opensplic:[0,1,2,3,6,18,11,12,14,17,9],unix:[16,3],api:8,shmdump:17,instal:[14,16,12,3],guid:[1,13],your:8,cloud:9,differ:18,from:11,convent:13,memori:0,support:[6,8],two:18,custom:5,compon:8,start:[4,1,11,13],recommend:[18,11],ospl_xml2int:17,tool:[18,2,3,8,11,17],relat:11,notic:7,warn:17,link:[18,11],technic:6,conclus:0,multi:17,target:18,scalabl:0,amend:17,winsh:11,exampl:[18,2,3,5,11,14,17],project:[14,11,17,18],posix:5,cab:2,mmstat:[17,2],pre:[18,11],real:14,featur:[0,8],pikeo:5,process:[0,14],share:0,argument:17,indic:1,diagnost:[17,2],critic:17,chat:14,tabl:1,limit:[5,15],optimis:[18,11],vxwork:[14,11,18],develop:[12,3],secur:2,ospl_projgen:17,detail:8,note:[5,15,11,18],how:[5,11],other:3,interact:8,build:[18,2,5,8,11,14],command:[18,11,17],document:6,singl:0,complet:[18,11],elino:15,product:[6,8],registri:2,deploy:[5,15,12],tornado:11,symbol:[18,11],object:17,deploi:[14,2,18],multipl:[18,11],data:8,why:0,lwip:5,special:18,scenario:[18,11],bind:8,inform:[10,6],contact:7,environ:2,runtim:[18,11],thi:18,time:[14,11,18,3],model:8}}) \ No newline at end of file diff --git a/docs/html/GettingStartedGuide/unixarm.html b/docs/html/GettingStartedGuide/unixarm.html index 2d25b0b29..48b6ef3c0 100644 --- a/docs/html/GettingStartedGuide/unixarm.html +++ b/docs/html/GettingStartedGuide/unixarm.html @@ -73,7 +73,7 @@

    16.1. Installation for UNIX ARM platformtar xf P<code>-VortexOpenSplice<version>-<E>-<platform>.<os>-<comp>-<type>-<target>-installer.tar

    where, some being optional,

    -

    <code> - PrismTech’s code for the platform +

    <code> - ADLINK’s code for the platform <version> - the Vortex OpenSplice version number, for example V6.0

    <E> - the environment, either HDE or RTS

    @@ -160,7 +160,7 @@

    Navigation

    \ No newline at end of file diff --git a/docs/html/GettingStartedGuide/using-with-cloud.html b/docs/html/GettingStartedGuide/using-with-cloud.html index 2e22d39fa..6ad321e63 100644 --- a/docs/html/GettingStartedGuide/using-with-cloud.html +++ b/docs/html/GettingStartedGuide/using-with-cloud.html @@ -24,7 +24,7 @@ - + @@ -35,7 +35,7 @@

    Navigation

    index
  • - next |
  • Previous topic
  • title="previous chapter">5. Installation and Configuration

    Next topic

    7. Licensing OpenSplice

    + title="next chapter">7. Licensing Vortex OpenSplice

    This Page

    \ No newline at end of file diff --git a/docs/html/GettingStartedGuide/vxworks-551.html b/docs/html/GettingStartedGuide/vxworks-551.html index 815b4d34e..d36b9a45c 100644 --- a/docs/html/GettingStartedGuide/vxworks-551.html +++ b/docs/html/GettingStartedGuide/vxworks-551.html @@ -295,7 +295,7 @@

    10.9. The osplconf2c command¶

    caution
    -
    Loading separate DKMs is not recommended by PrismTech.
    +
    Loading separate DKMs is not recommended by ADLINK.

    Note about the example projects

    Please ensure that any services called by a configuration XML contain an @@ -328,7 +328,7 @@

    10.10.2. How to start spliced and related services
    caution
    Please note that in order to deploy the cmsoap service for use with the -OpenSplice DDS Tuner, it must be configured in ospl.xml and the +Vortex OpenSplice Tuner, it must be configured in ospl.xml and the libraries named libcmxml.so and libddsrrstorage.so must be pre-loaded:
    @@ -506,7 +506,7 @@

    Navigation

    \ No newline at end of file diff --git a/docs/html/GettingStartedGuide/vxworks-6-kernel.html b/docs/html/GettingStartedGuide/vxworks-6-kernel.html index d32401a9d..feca58acb 100644 --- a/docs/html/GettingStartedGuide/vxworks-6-kernel.html +++ b/docs/html/GettingStartedGuide/vxworks-6-kernel.html @@ -106,7 +106,7 @@

    12.2.1. Special notes for this platform

    12.3. OpenSplice Examples¶

    -

    PrismTech provides the pingpong example both for C and C++ that are described +

    ADLINK provides the pingpong example both for C and C++ that are described in the Examples section. These example are provided in the form of Workbench projects which can be easily built and then deployed on to the target hardware in a similar process to that described above.

    @@ -312,7 +312,7 @@

    12.4.4. Note about the example projects¶

    caution
    -
    Loading separate DKMs is not recommended by PrismTech.
    +
    Loading separate DKMs is not recommended by ADLINK.
    info cpp
    NOTE: There are no C++ examples provided for the AppOnly style and there is no libdcpssacpp.out DKM because VxWorks only supports C++ modules that are @@ -591,7 +591,7 @@

    Navigation

    \ No newline at end of file diff --git a/docs/html/GettingStartedGuide/vxworks-6-rtp.html b/docs/html/GettingStartedGuide/vxworks-6-rtp.html index a1277eb10..e0efb39db 100644 --- a/docs/html/GettingStartedGuide/vxworks-6-rtp.html +++ b/docs/html/GettingStartedGuide/vxworks-6-rtp.html @@ -68,12 +68,12 @@

    11.2. Installation
    caution

    Please note that WindRiver’s Workbench GUI must be run in an environment -where the OpenSplice variables have already been set. If you chose to -set the OpenSplice variables globally during the installation stage, +where the Vortex OpenSplice variables have already been set. If you chose to +set the Vortex OpenSplice variables globally during the installation stage, then Workbench can be run directly. Otherwise, Workbench must be run from the Vortex OpenSplice command prompt. Start the command prompt by clicking Start > Programs > Vortex OpenSplice menu entry > Vortex OpenSplice @@ -113,7 +113,7 @@

    11.4. Deploying Vortex OpenSpliceospl.xml). On VxWorks 6.x, a Real Time Process for each of these services is deployed on to the target hardware. The sample ospl.xml configuration file -provided with the VxWorks 6.x edition of OpenSplice has particular +provided with the VxWorks 6.x edition of Vortex OpenSplice has particular settings so that these RTPs can operate effectively.

    The instructions below describe how to deploy these RTPs using the Workbench GUI and the Target Server File System (TSFS), although the @@ -136,7 +136,7 @@

    11.4. Deploying Vortex OpenSplicespliced.vxe executable from the OpenSplice installation. The +the spliced.vxe executable from the Vortex OpenSplice installation. The following parameters should be set in the dialog:

    @@ -174,7 +174,7 @@

    11.4. Deploying Vortex OpenSplicebin directory of the installation) and ospl.xml (located in the etc/config directory of the installation) have been copied to the directory made available as /tgtsvr described -above. It is possible, if required, to copy the entire OpenSplice +above. It is possible, if required, to copy the entire Vortex OpenSplice installation directory to the /tgtsvr location so that all files are available, but please be aware that log and information files will be written to the same /tgtsvr location when the spliced.vxe is @@ -190,19 +190,19 @@

    11.4. Deploying Vortex OpenSpliceWorkbench showing deployed OpenSplice RTPs. +Workbench showing deployed Vortex OpenSplice RTPs. (The list may need to be refreshed with the F5 key.)

    Deployment problems are listed in ospl-error.txt and ospl-info.txt, which are created in the /tgtsvr directory if the configuration described above is used.

    -
    -Workbench showing deployed OpenSplice RTPs -

    Workbench showing deployed OpenSplice RTPs

    +
    +Workbench showing deployed Vortex OpenSplice RTPs +

    Workbench showing deployed Vortex OpenSplice RTPs

    -
    -

    11.5. OpenSplice Examples¶

    -

    PrismTech provides a number of examples both for C and C++ that are +

    +

    11.5. Vortex OpenSplice Examples¶

    +

    ADLINK provides a number of examples both for C and C++ that are described in the Examples section. These example are provided in the form of Workbench projects which can be easily built and then deployed on to the target hardware in a similar process to that described above.

    @@ -213,7 +213,7 @@

    11.5.1. Importing Example Projects into WorkbenchThe example projects can be imported into Workbench by clicking File > Import... > General > Existing Projects into Workspace.

    In the Import Projects dialog, browse to the examples directory of -the OpenSplice installation. Select the required projects for importing +the Vortex OpenSplice installation. Select the required projects for importing from the list that Workbench has detected.

    Ensure that the Copy projects into workspace box is un-checked.

    @@ -227,8 +227,8 @@

    11.5.2. Building Example Projects with Workbench -

    11.5.3. Deploying OpenSplice Examples¶

    +
    +

    11.5.3. Deploying Vortex OpenSplice Examples¶

    The PingPong and the Tutorial examples are run in identical ways with the same parameters for both C and C++. These should be deployed onto the VxWorks target with the arguments described in the README files @@ -237,7 +237,7 @@

    11.5.3. Deploying OpenSplice Examples¶

    The PingPong example consists of the ping.vxe and pong.vxe executables. If these executables have been copied to the directory made -available as /tgtsvr as described in `Deploying OpenSplice DDS`_, +available as /tgtsvr as described in Deploying Vortex OpenSplice, RTP configurations should have the following parameters:

    @@ -311,7 +311,7 @@

    11.5.3.2. Deploying the Chat Tutorialchatter.vxe, messageboard.vxe and userload.vxe executables. If these executables have been copied to the directory made available as /tgtsvr as described in -`Deploying OpenSplice DDS`_, RTP configurations should have the following +Deploying Vortex OpenSplice, RTP configurations should have the following parameters:

    @@ -431,10 +431,10 @@

    Table Of Contents

  • 11.2. Installation
  • 11.3. VxWorks Kernel Requirements
  • 11.4. Deploying Vortex OpenSplice
  • -
  • 11.5. OpenSplice Examples
      +
    • 11.5. Vortex OpenSplice Examples
    • -
    • 14.5. Deploying OpenSplice DDS
    • +
    • 14.5. Deploying Vortex OpenSplice
    • 14.6. Using the mmstat Diagnostic Tool on Windows CE
    • -
    • 14.7. OpenSplice Examples
        +
      • 14.7. Vortex OpenSplice Examples \ No newline at end of file diff --git a/docs/html/IDLPreProcGuide/_sources/commandline.txt b/docs/html/IDLPreProcGuide/_sources/commandline.txt index 7ccc219b0..e32169602 100644 --- a/docs/html/IDLPreProcGuide/_sources/commandline.txt +++ b/docs/html/IDLPreProcGuide/_sources/commandline.txt @@ -16,7 +16,7 @@ command line options: [ -I ] [ -D [=] ] < -S | -C > - < -l (c | c++ | cpp | java | cs | isocpp | isoc++ | c99) > + < -l (c | c++ | cpp | java | cs | isocpp | isoc++ | c99 | simulink) > [ -F ] [ -j [old]:] [ -o | | | ] @@ -72,7 +72,7 @@ All of these options are described in full detail below. Specifies ORB integrated mode, which allows application programs to be built and run integrated with an ORB. -**-l (c | c++ | cpp | java | cs | isocpp | isoc++ | isocpp2 | isoc++2 | c99)** +**-l (c | c++ | cpp | java | cs | isocpp | isoc++ | isocpp2 | isoc++2 | c99 | simulink)** Selects the target language. Note that the Vortex OpenSplice IDL Pre-processor does not support every combination of modes and languages. This option is mandatory; when no @@ -135,6 +135,11 @@ All of these options are described in full detail below. size one larger than specified in the idl definition to allow for the terminating 0 character. + |simulink| + - For Simulink a MATLAB .m file is created representing the simulink + bus for the input IDL file. Typically this option is used when + invoking a script from MATLAB to import the IDL into Simulink. + See also :ref:`OpenSplice Modes and Languages ` for a complete list of supported modes and languages. diff --git a/docs/html/IDLPreProcGuide/_sources/contacts.txt b/docs/html/IDLPreProcGuide/_sources/contacts.txt index fc6442d3a..d32f6016f 100644 --- a/docs/html/IDLPreProcGuide/_sources/contacts.txt +++ b/docs/html/IDLPreProcGuide/_sources/contacts.txt @@ -1,53 +1 @@ -.. _`Contacts & Notices`: - -.. VERY LITTLE EVER CHANGES IN HERE !! - Just keep an eye on the copyright notice. - -################## -Contacts & Notices -################## - -******** -Contacts -******** - -| **PrismTech Corporation** -| 400 TradeCenter -| Suite 5900 -| Woburn, MA -| 01801 -| USA -| Tel: +1 781 569 5819 - -| **PrismTech Limited** -| PrismTech House -| 5th Avenue Business Park -| Gateshead -| NE11 0NG -| UK -| Tel: +44 (0)191 497 9900 - -| **PrismTech France** -| 28 rue Jean Rostand -| 91400 Orsay -| France -| Tel: +33 (1) 69 015354 - - -Web: http://www.prismtech.com - -E-mail: \info@prismtech.com - -******* -Notices -******* - -**Copyright** © 2016 PrismTech Limited. All rights reserved. - -*This document may be reproduced in whole but not in part. -The information contained in this document is subject to change -without notice and is made available in good faith without -liability on the part of PrismTech Limited or PrismTech Corporation. -All trademarks acknowledged.* - -.. END +.. include:: ../../common/contacts.rst diff --git a/docs/html/IDLPreProcGuide/_sources/index.txt b/docs/html/IDLPreProcGuide/_sources/index.txt index 5fb15a92a..0162eca9a 100644 --- a/docs/html/IDLPreProcGuide/_sources/index.txt +++ b/docs/html/IDLPreProcGuide/_sources/index.txt @@ -9,10 +9,10 @@ The IDL PreProcessor Guide .. toctree:: :maxdepth: 6 :numbered: - + preface overview - + prerequisites commandline ddsmodes @@ -21,11 +21,11 @@ The IDL PreProcessor Guide modeslanguages topictypes ddsdatatypes - + bibliography - - contacts - + + contacts + Indices and tables ================== diff --git a/docs/html/IDLPreProcGuide/_sources/modeslanguages.txt b/docs/html/IDLPreProcGuide/_sources/modeslanguages.txt index c5081bf57..5626a5ea8 100644 --- a/docs/html/IDLPreProcGuide/_sources/modeslanguages.txt +++ b/docs/html/IDLPreProcGuide/_sources/modeslanguages.txt @@ -15,10 +15,10 @@ The Vortex OpenSplice IDL Pre-processor generates IDL code for the specialized *TypeSupport*, *DataReader* and *DataWriter*, as well as C++ implementations and support code. The ORB pre-processor generates from the generated IDL interfaces the C++ specialized interfaces for that specific ORB. These interfaces -are included by the application C++ code as well as the OpenSplice DDS generated +are included by the application C++ code as well as the Vortex OpenSplice generated specialized C++ implementation code. The application C++ code as well as the specialized C++ implementation code (with the support functions) is compiled into -object code and linked together with the applicable OpenSplice libraries and the +object code and linked together with the applicable Vortex OpenSplice libraries and the ORB libraries. |info| @@ -38,19 +38,19 @@ ORB libraries. The role of the Vortex OpenSplice IDL Pre-processor functionality is expanded in -`Integrated C++ ORB OpenSplice IDL Pre-processor Details`_. +`Integrated C++ ORB Vortex OpenSplice IDL Pre-processor Details`_. It shows in more detail which files are generated, given an input file (in this example ``foo.idl``). -.. _`Integrated C++ ORB OpenSplice IDL Pre-processor Details`: +.. _`Integrated C++ ORB Vortex OpenSplice IDL Pre-processor Details`: -.. centered:: **Integrated C++ ORB OpenSplice IDL Pre-processor Details** +.. centered:: **Integrated C++ ORB Vortex OpenSplice IDL Pre-processor Details** .. image:: /images/IntegratedCppORB_detail.png :width: 150mm :align: center - :alt: Integrated C++ ORB OpenSplice IDL Pre-processor Details + :alt: Integrated C++ ORB Vortex OpenSplice IDL Pre-processor Details The file ``foo.h`` is the only file that needs to be included by the application. It includes all files needed by the application to interact with the DCPS interface. @@ -61,9 +61,9 @@ C++ interface files. The ``fooDcps_impl.*`` files contain the specialized *TypeSupport*, *DataReader* and *DataWriter* implementation classes needed to communicate the type *via* -OpenSplice DDS. +Vortex OpenSplice. -The ``fooSplDcps.*`` files contain support functions required by OpenSplice DDS +The ``fooSplDcps.*`` files contain support functions required by Vortex OpenSplice in order to be able to handle the specific data types. @@ -83,7 +83,7 @@ The diagram `C Standalone`_ is an overview of the artifacts and processing stages related to the C standalone context. For C++ the different stages are equal to the C standalone context. Because there is no ORB involved, all pre-processing is performed by the -OpenSplice DDS IDL Pre-processor. The generated specialized implementations +Vortex OpenSplice IDL Pre-processor. The generated specialized implementations and the application’s C++ code must be compiled into object code, plus all objects must be linked with the appropriate Vortex OpenSplice libraries. @@ -111,7 +111,7 @@ scope is not used but ``C99`` types are used in place of C Standalone ************ -The *C standalone* mode provides an OpenSplice DDS context which does not need +The *C standalone* mode provides an Vortex OpenSplice context which does not need an ORB. Vortex OpenSplice resolves all implied IDL to C language mapping functions and requirements. The only difference when using the standalone mode is that DDS is used as the naming scope for definitions and functions. @@ -135,19 +135,19 @@ plus all objects must be linked with the appropriate Vortex OpenSplice libraries The role of the Vortex OpenSplice IDL Pre-processor functionality is expanded in -the diagram `C Standalone OpenSplice IDL Pre-processor Details`_, +the diagram `C Standalone Vortex OpenSplice IDL Pre-processor Details`_, providing more detail about the files generated when provided with an input file (``foo.idl`` this example). -.. _`C Standalone OpenSplice IDL Pre-processor Details`: +.. _`C Standalone Vortex OpenSplice IDL Pre-processor Details`: -.. centered:: **C Standalone OpenSplice IDL Pre-processor Details** +.. centered:: **C Standalone Vortex OpenSplice IDL Pre-processor Details** .. image:: /images/CStandalone_detail.png :width: 150mm :align: center - :alt: C Standalone OpenSplice IDL Pre-processor Details + :alt: C Standalone Vortex OpenSplice IDL Pre-processor Details The file ``foo.h`` is the only file that needs to be included by the application. It itself includes all necessary files needed by the application in order to @@ -158,9 +158,9 @@ accordance with the :ref:`OMG's IDL-to-C language mapping specification `. The ``fooSacDcps.*`` files contain the specialized *TypeSupport*, *DataReader* -and *DataWriter* classes needed to communicate the type *via* OpenSplice DDS. +and *DataWriter* classes needed to communicate the type *via* Vortex OpenSplice. -The ``fooSplDcps.*`` files contain support functions required by OpenSplice DDS in +The ``fooSplDcps.*`` files contain support functions required by Vortex OpenSplice in order to be able to handle the specific data types. C99 Standalone @@ -178,7 +178,7 @@ with a upperboundone larger than specified in the idl to allow for the terminati 0 character. Further an additional file ``fooDcps.c`` is generated which contains the information -to register the type information with OpenSplice DDS. +to register the type information with Vortex OpenSplice. Java Standalone *************** @@ -230,11 +230,11 @@ ORB. The Vortex OpenSplice IDL Pre-processor generates IDL code for the specialized *TypeSupport*, *DataReader* and *DataWriter*, as well as Java implementations and support code. The ORB pre-processor generates the Java ``‘Foo’`` classes, which must be done manually. These classes are -included with the application Java code as well as the OpenSplice DDS +included with the application Java code as well as the Vortex OpenSplice generated specialized Java implementation code. The application Java code as well as the specialized Java implementation code (with the support functions) is compiled into class files and can be used -together with the applicable OpenSplice libraries and the ORB libraries. +together with the applicable Vortex OpenSplice libraries and the ORB libraries. The artifacts and processing stages related to the Java CORBA cohabitation context are similar to those of the standalone mode, with one exception: diff --git a/docs/html/IDLPreProcGuide/_sources/preface.txt b/docs/html/IDLPreProcGuide/_sources/preface.txt index 82bc0c583..a710203f9 100644 --- a/docs/html/IDLPreProcGuide/_sources/preface.txt +++ b/docs/html/IDLPreProcGuide/_sources/preface.txt @@ -11,7 +11,7 @@ About the IDL PreProcessor Guide The *IDL Pre-processor Guide* describes what the Vortex OpenSplice IDL Pre-processor is, and how to use it. -The Vortex OpenSplice IDL Pre-processor is included with +The Vortex OpenSplice IDL Pre-processor is included with the Vortex OpenSplice product. @@ -25,62 +25,62 @@ applications which use Vortex OpenSplice. Organisation ************ -The :ref:`Overview ` gives a general description of +The :ref:`Overview ` gives a general description of and brief introduction to the IDL Pre-processor. -:ref:`Prerequisites ` describes the prerequisites needed +:ref:`Prerequisites ` describes the prerequisites needed to run the pre-processor. -:ref:`IDL Pre-processor Command Line Options ` -gives detailed descriptions of the options that are available for +:ref:`IDL Pre-processor Command Line Options ` +gives detailed descriptions of the options that are available for running the pre-processor. :ref:`OpenSplice Modes and Languages ` -provides a summary of OpenSplice’s supported modes and languages, as well as +provides a summary of OpenSplice’s supported modes and languages, as well as an overview of the applicable Vortex OpenSplice libraries. -:ref:`IDL Pre-processor Grammar ` +:ref:`IDL Pre-processor Grammar ` shows the IDL grammar that is supported by the Vortex OpenSplice IDL Pre-processor. -:ref:`Keys ` -describes the mechanism for the use of keys with particular data types. +:ref:`Keys ` +describes the mechanism for the use of keys with particular data types. -:ref:`Modes, Languages and Processing steps ` -describes the steps required for creating programs for each of the modes and +:ref:`Modes, Languages and Processing steps ` +describes the steps required for creating programs for each of the modes and languages supported by the Pre-processor. -:ref:`Extensible and Dynamic Topic Types for DDS annotation support ` +:ref:`Extensible and Dynamic Topic Types for DDS annotation support ` describes how the IDL Pre-processor handles the annotation language extension. -:ref:`Built-in DDS data types ` -describes the built-in DDS data types and provides language-specific +:ref:`Built-in DDS data types ` +describes the built-in DDS data types and provides language-specific guidelines on how to use them. Finally, there is :ref:`a bibliography ` which lists -all of the publications referred to in this *Guide*. +all of the publications referred to in this *Guide*. Conventions *********** -The icons shown below are used in PrismTech product documentation -to help readers to quickly identify information relevant to their +The icons shown below are used in ADLINK product documentation +to help readers to quickly identify information relevant to their specific use of Vortex OpenSplice. - ========= ================================================================== - *Icon* *Meaning* - ========= ================================================================== - |caution| Item of special significance or where caution needs to be taken. - |info| Item contains helpful hint or special information. - |windows| Information applies to Windows (*e.g.* XP, 2003, Windows 7) only. - |unix| Information applies to Unix-based systems (*e.g.* Solaris) only. - |linux| Information applies to Linux-based systems (*e.g.* Ubuntu) only. - |c| C language specific. - |cpp| C++ language specific. - |csharp| C# language specific. - |java| Java language specific. - ========= ================================================================== + ========= ================================================================== + *Icon* *Meaning* + ========= ================================================================== + |caution| Item of special significance or where caution needs to be taken. + |info| Item contains helpful hint or special information. + |windows| Information applies to Windows (*e.g.* XP, 2003, Windows 7) only. + |unix| Information applies to Unix-based systems (*e.g.* Solaris) only. + |linux| Information applies to Linux-based systems (*e.g.* Ubuntu) only. + |c| C language specific. + |cpp| C++ language specific. + |csharp| C# language specific. + |java| Java language specific. + ========= ================================================================== @@ -104,4 +104,3 @@ specific use of Vortex OpenSplice. .. |java| image:: ./images/icon-java.* :height: 6mm - \ No newline at end of file diff --git a/docs/html/IDLPreProcGuide/bibliography.html b/docs/html/IDLPreProcGuide/bibliography.html index f0cb9ab98..a18b7abdb 100644 --- a/docs/html/IDLPreProcGuide/bibliography.html +++ b/docs/html/IDLPreProcGuide/bibliography.html @@ -177,7 +177,7 @@

        Navigation

      \ No newline at end of file diff --git a/docs/html/IDLPreProcGuide/commandline.html b/docs/html/IDLPreProcGuide/commandline.html index 82bef5f48..1979661b5 100644 --- a/docs/html/IDLPreProcGuide/commandline.html +++ b/docs/html/IDLPreProcGuide/commandline.html @@ -59,7 +59,7 @@

      Navigation

      [ -I <path> ] [ -D <macro>[=<definition>] ] < -S | -C > -< -l (c | c++ | cpp | java | cs | isocpp | isoc++ | c99) > +< -l (c | c++ | cpp | java | cs | isocpp | isoc++ | c99 | simulink) > [ -F ] [ -j [old]:<new>] [ -o <dds-types> | <custom-psm> | <no-equality> | <deprecated-c++11-mapping>] @@ -108,7 +108,7 @@

      Navigation

      -C
      Specifies ORB integrated mode, which allows application programs to be built and run integrated with an ORB.
      -
      -l (c | c++ | cpp | java | cs | isocpp | isoc++ | isocpp2 | isoc++2 | c99)
      +
      -l (c | c++ | cpp | java | cs | isocpp | isoc++ | isocpp2 | isoc++2 | c99 | simulink)

      Selects the target language. Note that the Vortex OpenSplice IDL Pre-processor does not support every combination of modes and languages. This option is mandatory; when no @@ -176,6 +176,11 @@

      Navigation

      c99 types and that bound strings are mapped to char arrays with a size one larger than specified in the idl definition to allow for the terminating 0 character.

      +

      |simulink|

      +
    • +
    • For Simulink a MATLAB .m file is created representing the simulink +bus for the input IDL file. Typically this option is used when +invoking a script from MATLAB to import the IDL into Simulink.

    See also @@ -313,7 +318,7 @@

    Navigation

    \ No newline at end of file diff --git a/docs/html/IDLPreProcGuide/contacts.html b/docs/html/IDLPreProcGuide/contacts.html index 19f303e7a..30481295c 100644 --- a/docs/html/IDLPreProcGuide/contacts.html +++ b/docs/html/IDLPreProcGuide/contacts.html @@ -45,12 +45,12 @@

    Navigation

    -
    -

    12. Contacts & Notices¶

    +

    12.2. Notices¶

    -

    Copyright © 2016 PrismTech Limited. All rights reserved.

    -

    This document may be reproduced in whole but not in part. -The information contained in this document is subject to change -without notice and is made available in good faith without -liability on the part of PrismTech Limited or PrismTech Corporation. -All trademarks acknowledged.

    +

    Copyright © 2018 ADLINK Technology Limited. All rights reserved.

    +

    This document may be reproduced in whole but not in part. The information contained in this +document is subject to change without notice and is made available in good faith without +liability on the part of ADLINK Technology Limited. All trademarks acknowledged.

    @@ -144,7 +147,7 @@

    Navigation

    \ No newline at end of file diff --git a/docs/html/IDLPreProcGuide/ddsdatatypes.html b/docs/html/IDLPreProcGuide/ddsdatatypes.html index 4045ac6ae..eca488f64 100644 --- a/docs/html/IDLPreProcGuide/ddsdatatypes.html +++ b/docs/html/IDLPreProcGuide/ddsdatatypes.html @@ -139,7 +139,7 @@

    Navigation

    \ No newline at end of file diff --git a/docs/html/IDLPreProcGuide/ddsmodes.html b/docs/html/IDLPreProcGuide/ddsmodes.html index 432e86f82..49aa67dd1 100644 --- a/docs/html/IDLPreProcGuide/ddsmodes.html +++ b/docs/html/IDLPreProcGuide/ddsmodes.html @@ -211,7 +211,7 @@

    Navigation

    \ No newline at end of file diff --git a/docs/html/IDLPreProcGuide/genindex.html b/docs/html/IDLPreProcGuide/genindex.html index 414c9e62d..346219a0b 100644 --- a/docs/html/IDLPreProcGuide/genindex.html +++ b/docs/html/IDLPreProcGuide/genindex.html @@ -88,7 +88,7 @@

    Navigation

    \ No newline at end of file diff --git a/docs/html/IDLPreProcGuide/grammar.html b/docs/html/IDLPreProcGuide/grammar.html index 973a7d46a..151dfb310 100644 --- a/docs/html/IDLPreProcGuide/grammar.html +++ b/docs/html/IDLPreProcGuide/grammar.html @@ -907,7 +907,7 @@

    Navigation

    \ No newline at end of file diff --git a/docs/html/IDLPreProcGuide/index.html b/docs/html/IDLPreProcGuide/index.html index 41402f40a..1e5811f8e 100644 --- a/docs/html/IDLPreProcGuide/index.html +++ b/docs/html/IDLPreProcGuide/index.html @@ -157,7 +157,7 @@

    Navigation

    \ No newline at end of file diff --git a/docs/html/IDLPreProcGuide/keys.html b/docs/html/IDLPreProcGuide/keys.html index eb64189bc..caeb59610 100644 --- a/docs/html/IDLPreProcGuide/keys.html +++ b/docs/html/IDLPreProcGuide/keys.html @@ -305,7 +305,7 @@

    Navigation

    \ No newline at end of file diff --git a/docs/html/IDLPreProcGuide/modeslanguages.html b/docs/html/IDLPreProcGuide/modeslanguages.html index 8961bb4e4..298b8bb03 100644 --- a/docs/html/IDLPreProcGuide/modeslanguages.html +++ b/docs/html/IDLPreProcGuide/modeslanguages.html @@ -59,10 +59,10 @@

    8.1. Integrated C++ ORBTypeSupport, DataReader and DataWriter, as well as C++ implementations and support code. The ORB pre-processor generates from the generated IDL interfaces the C++ specialized interfaces for that specific ORB. These interfaces -are included by the application C++ code as well as the OpenSplice DDS generated +are included by the application C++ code as well as the Vortex OpenSplice generated specialized C++ implementation code. The application C++ code as well as the specialized C++ implementation code (with the support functions) is compiled into -object code and linked together with the applicable OpenSplice libraries and the +object code and linked together with the applicable Vortex OpenSplice libraries and the ORB libraries.

    info
    @@ -73,11 +73,11 @@

    8.1. Integrated C++ ORB Integrated C++ ORB

    Integrated C++ ORB

    The role of the Vortex OpenSplice IDL Pre-processor functionality is expanded in -Integrated C++ ORB OpenSplice IDL Pre-processor Details. +Integrated C++ ORB Vortex OpenSplice IDL Pre-processor Details. It shows in more detail which files are generated, given an input file (in this example foo.idl).

    -

    -Integrated C++ ORB OpenSplice IDL Pre-processor Details

    Integrated C++ ORB OpenSplice IDL Pre-processor Details +

    +Integrated C++ ORB Vortex OpenSplice IDL Pre-processor Details

    Integrated C++ ORB Vortex OpenSplice IDL Pre-processor Details

    The file foo.h is the only file that needs to be included by the application. It includes all files needed by the application to interact with the DCPS interface.

    The file fooDcps.idl is an IDL definition of the specialized TypeSupport, @@ -85,8 +85,8 @@

    8.1. Integrated C++ ORB

    The fooDcps_impl.* files contain the specialized TypeSupport, DataReader and DataWriter implementation classes needed to communicate the type via -OpenSplice DDS.

    -

    The fooSplDcps.* files contain support functions required by OpenSplice DDS +Vortex OpenSplice.

    +

    The fooSplDcps.* files contain support functions required by Vortex OpenSplice in order to be able to handle the specific data types.

    @@ -102,7 +102,7 @@

    8.2. C++ Standalone

    8.5. C Standalone¶

    -

    The C standalone mode provides an OpenSplice DDS context which does not need +

    The C standalone mode provides an Vortex OpenSplice context which does not need an ORB. Vortex OpenSplice resolves all implied IDL to C language mapping functions and requirements. The only difference when using the standalone mode is that DDS is used as the naming scope for definitions and functions.

    @@ -139,11 +139,11 @@

    8.5. C Standalone C Standalone

    C Standalone

    The role of the Vortex OpenSplice IDL Pre-processor functionality is expanded in -the diagram C Standalone OpenSplice IDL Pre-processor Details, +the diagram C Standalone Vortex OpenSplice IDL Pre-processor Details, providing more detail about the files generated when provided with an input file (foo.idl this example).

    -

    -C Standalone OpenSplice IDL Pre-processor Details

    C Standalone OpenSplice IDL Pre-processor Details +

    +C Standalone Vortex OpenSplice IDL Pre-processor Details

    C Standalone Vortex OpenSplice IDL Pre-processor Details

    The file foo.h is the only file that needs to be included by the application. It itself includes all necessary files needed by the application in order to interact with the DCPS interface.

    @@ -151,8 +151,8 @@

    8.5. C StandaloneOMG’s IDL-to-C language mapping specification.

    The fooSacDcps.* files contain the specialized TypeSupport, DataReader -and DataWriter classes needed to communicate the type via OpenSplice DDS.

    -

    The fooSplDcps.* files contain support functions required by OpenSplice DDS in +and DataWriter classes needed to communicate the type via Vortex OpenSplice.

    +

    The fooSplDcps.* files contain support functions required by Vortex OpenSplice in order to be able to handle the specific data types.

    \ No newline at end of file diff --git a/docs/html/IDLPreProcGuide/objects.inv b/docs/html/IDLPreProcGuide/objects.inv index 7b713cf71..db9e785dd 100644 Binary files a/docs/html/IDLPreProcGuide/objects.inv and b/docs/html/IDLPreProcGuide/objects.inv differ diff --git a/docs/html/IDLPreProcGuide/overview.html b/docs/html/IDLPreProcGuide/overview.html index 945af73c2..07edc7fa3 100644 --- a/docs/html/IDLPreProcGuide/overview.html +++ b/docs/html/IDLPreProcGuide/overview.html @@ -161,7 +161,7 @@

    Navigation

    \ No newline at end of file diff --git a/docs/html/IDLPreProcGuide/preface.html b/docs/html/IDLPreProcGuide/preface.html index 23165371f..aa91422c2 100644 --- a/docs/html/IDLPreProcGuide/preface.html +++ b/docs/html/IDLPreProcGuide/preface.html @@ -92,7 +92,7 @@

    1.3. Organisation

    1.4. Conventions¶

    -

    The icons shown below are used in PrismTech product documentation +

    The icons shown below are used in ADLINK product documentation to help readers to quickly identify information relevant to their specific use of Vortex OpenSplice.

    @@ -204,7 +204,7 @@

    Navigation

    \ No newline at end of file diff --git a/docs/html/IDLPreProcGuide/prerequisites.html b/docs/html/IDLPreProcGuide/prerequisites.html index 6b96460d6..9d3cadd8b 100644 --- a/docs/html/IDLPreProcGuide/prerequisites.html +++ b/docs/html/IDLPreProcGuide/prerequisites.html @@ -122,7 +122,7 @@

    Navigation

    \ No newline at end of file diff --git a/docs/html/IDLPreProcGuide/search.html b/docs/html/IDLPreProcGuide/search.html index e40e07546..219b04366 100644 --- a/docs/html/IDLPreProcGuide/search.html +++ b/docs/html/IDLPreProcGuide/search.html @@ -95,7 +95,7 @@

    Navigation

    \ No newline at end of file diff --git a/docs/html/IDLPreProcGuide/searchindex.js b/docs/html/IDLPreProcGuide/searchindex.js index 63af1ac15..0a8fe9f5d 100644 --- a/docs/html/IDLPreProcGuide/searchindex.js +++ b/docs/html/IDLPreProcGuide/searchindex.js @@ -1 +1 @@ -Search.setIndex({envversion:42,terms:{xtype:11,represent:[5,6,7,2],all:[1,2,4,5,6,7,8,10],code:[5,6,7,8],partial:7,interface_typ:1,queri:5,consum:1,ptc:11,prefix:[7,12],follow:[11,3,5,7,1,12],privat:1,integer_typ:1,"const":1,type_dcl:1,program:[2,3,6,7,10,8],present:5,sens:7,keylist:5,sent:5,and_expr:1,liter:1,everi:[5,7],string:[0,7,1],fals:1,"void":1,util:5,mechan:[5,10],affect:5,relev:[5,1,10],condition:3,common:[11,1],dcpssacpp:2,level:[5,6],list:[5,6,7,2,10],fixed_pt_const_typ:1,fewer:5,factori:1,item:10,primary_expr:1,dcpsccpp:2,small:[5,8],ann_appl_param:1,mytypeannot:12,pleas:[7,12],prevent:1,impli:[6,7,2,8],tel:4,ten:5,direct:[7,1],sign:12,past:7,pass:7,further:8,idlpp:[9,7,1,3],event_abs_dcl:1,home_dcl:1,corba:[11,6,7,8,1,12],abc:5,sub:7,compar:5,section:[7,12,8],abl:[5,12,8],brief:10,member_list:1,current:7,boolean_typ:1,version:[11,8],awar:[5,3],"new":[7,1,12],"public":[1,10],involv:[7,3,8],prismtech:[10,4],full:7,deriv:7,gener:[1,5,6,7,10,8,12],here:5,custom_lib:7,let:5,header_fil:7,solari:10,param_type_spec:1,depend:7,becom:7,sinc:7,valu:[7,1,12],search:0,larger:[7,8],behav:5,action:3,implement:[7,12,8],constr_forward_decl:1,portabl:8,overrid:7,via:[7,3,8],init_param_decl:1,prerequisit:[0,10],primit:[7,8],modul:[5,1,3],build_my_dl:7,avenu:4,filenam:7,unix:[9,7,2,10],api:[5,6,7,8],instal:9,middlewar:5,"__declspec":7,from:[2,5,6,7,9,8],describ:[9,7,12,10],usa:4,memori:5,doubl:[5,1,12],regist:8,two:[6,2,12],suit:4,call:[5,3],tradecent:4,dataread:[5,6,8],taken:[3,10],scope:[5,8],type:[7,11],ccpp:[7,2],more:[7,12,8],desir:5,valuetyp:1,relat:[6,2,8],type_declar:1,setrais:1,trail:7,flag:7,accept:[6,1,12],particular:10,actual:5,cach:7,must:[5,9,1,3,8],high:6,account:1,word:5,hous:4,annot:[0,1,10],cat:5,can:[2,3,5,6,7,9,8,12],floating_pt_liter:1,purpos:8,root:9,could:7,constr_type_spec:1,proof:12,control:[7,3],dcpsac:2,my_annotation_member_2:12,scan:6,process:[5,0,7,1,3],share:[6,7,2,12],templat:[6,7,2],topic:[5,0,11,10],base_type_spec:1,keyfield:5,caution:10,my_annotation_member_1:12,want:7,tao:[7,8],unsign:[5,1],ann_fwd_dcl:1,alwai:5,multipl:1,component_export:1,valuebas:1,write:[5,12],how:10,bitbound:12,ebnf:1,perspect:5,map:[1,2,5,6,7,8,11],product:[5,10],orsai:4,invok:[9,3],diagram:[6,8],befor:9,compli:[6,7,1],attent:3,mai:[5,7,1,4],underscor:1,data:[7,11],op_type_spec:1,finder_dcl:1,alloc:5,"short":[5,1],event_dcl:1,correspond:[7,8],value_dcl:1,element:[5,1],inform:[5,7,10,8,4],"switch":1,duration_t:3,combin:[5,7],allow:[5,6,7,12,8],add_expr:1,order:[12,3,8],help:10,routin:7,over:5,consumes_dcl:1,report:7,comma:5,same:[5,7],csharp:7,fusion_1_4_1:2,still:[5,8],pointer:5,dynam:[0,11,10],typedef:[5,1],group:11,sacpp:[7,2],fix:[5,1],dds_api:7,platform:[9,7,2],window:[7,2,10],com:[9,7,4],requir:[7,8,10],mail:4,therefor:[5,3],ann_bodi:1,them:[12,10],good:4,thei:[5,12],handl:[6,8,10],gadget:12,fooc:7,switch_typ:1,mention:5,facilit:5,instead:[2,5,6,7,8,12],nor:5,introduct:0,name:[2,5,6,7,8,12],anyth:12,readonly_attr_spec:1,separ:[5,7],token:12,exampl:[3,5,6,7,8,12],mode:7,each:[5,2,10],fulli:9,complet:[7,1],truncat:1,mean:[5,7,3,10],compil:[3,8],domain:7,wide_string_liter:1,ne11:4,raises_expr:1,"static":7,expect:7,character_liter:1,unsigned_short_int:1,event:1,special:[3,5,6,7,10,8,12],out:1,variabl:7,shown:[7,8,12,10],space:[5,6,7,2],publish:[5,1],stub:7,suitabl:5,rel:5,reader:10,array_declar:1,component_dcl:1,correct:5,preceed:5,franc:4,migrat:7,mustunderstand:12,situat:5,given:8,standard:7,primarykei:1,standalon:[0,7,2],base:[9,7,8,1,10],releas:9,org:7,orb:[0,7,2,3],prefac:0,value_abs_dcl:1,angl:7,init_dcl:1,omit:7,myannot:12,length:5,organis:0,outsid:7,dcpsisocpp2:2,"5th":4,interface_bodi:1,first:[5,7,1],oper:[5,7,8],simple_type_spec:1,suffix:[7,12],forward_dcl:1,arrai:[0,7],struct_typ:1,number:[5,6,12],dll_macro_nam:7,alreadi:12,done:8,component_head:1,imported_scop:1,size:[5,7],differ:[7,8],signed_short_int:1,convent:0,interact:8,system:[6,11,3,10],definit:[1,3,5,6,7,8,12],termin:[5,7,8],"final":[11,10],store:5,shell:9,home_inheritance_spec:1,ann_attr:1,namespac:8,copi:7,exception_list:1,specifi:[1,5,6,7,8,12],dds_openfusion_1_6_1:7,part:[5,4],pars:[6,12],pragma:5,consult:7,wchar:1,ann_appl:1,const_dcl:1,than:[5,7,3,8],target:[5,6,7],keyword:[7,1],provid:[1,2,3,5,6,8,10],remov:5,ann_appl_post:1,structur:5,charact:[0,7,1],type_prefix_dcl:1,mandatori:7,example_struct:3,saj:[7,2],sac:[7,2],well:[2,5,6,10,8,12],argument:7,fusion_1_5_1:2,packag:7,switch_type_nam:1,have:[5,12,3],tabl:2,need:[5,6,7,8,10],seen:6,collis:1,attr_dcl:1,annotation_nam:1,"char":[5,7,1,8],squar:7,lib:2,switch_bodi:1,or_expr:1,violat:5,note:[6,7,1,12],mix:5,maintain:5,build:[7,3,8],which:[1,3,5,6,7,8,10],attr_spec:1,map_typ:1,even:[5,12],unless:7,distribut:11,"enum":[5,1],normal:[5,7],park:4,c99:[0,7,2],object:[11,1,8],what:10,paid:3,most:5,abcd:5,regular:5,artifact:[6,2,8],addtion:7,"class":[6,7,8],appear:[1,12],give:10,ann_appl_dcl:1,adopt:11,request:11,doe:[5,7,1,12,8],declar:1,place:8,enclos:6,component_bodi:1,inout:1,dllexport:7,set:[5,9,7],show:[5,6,8,10],text:[7,11],typeprefix:1,syntax:[5,12],value_inheritance_spec:1,init_param_attribut:1,environ:[9,7],penalti:5,access:7,onli:[2,5,6,7,10,8,12],exactli:5,locat:[9,7],emits_dcl:1,copyright:4,interface_dcl:1,activ:7,should:[5,8],busi:4,cpp:[7,12],iec:[7,11,8],local:[1,12],explicitli:[5,7],signed_longlong_int:1,becaus:[5,8],nativ:1,increas:5,union_typ:1,enum_typ:1,ospl_tmpl_path:7,complex_declar:1,enabl:[5,7,3,8],integr:[0,7,2],contain:[4,5,6,7,8,10],where:[5,6,7,2,10],summari:10,fieldnam:5,altern:[7,12],legaci:5,factory_dcl:1,isoc:[0,7,2],see:[5,7,2,8],integer_liter:1,result:5,reserv:[7,4],concern:5,case_label:1,wire:5,extend:12,correctli:9,simple_declar:1,shift_expr:1,struct:[5,1,12,3],unary_oper:1,dll:[7,2],written:5,"0ng":4,between:[6,7,2,12],"import":[7,1],inclus:3,attribut:[1,12],my_integ:12,signatur:7,accord:[6,2,8],omg:[11,2,6,8,1,12],kei:0,numer:1,parameter_dcl:1,subject:4,readonly_attr_declar:1,rostand:4,extens:[0,11,10],time_ttim:3,xor_expr:1,addit:[7,8],signed_int:1,op_attribut:1,provides_dcl:1,string_liter:1,howev:[5,7,3,8],hint:10,equal:[7,8],against:8,interface_nam:1,etc:[1,3],audienc:0,context:[6,1,2,8],logic:5,improv:7,event_forward_dcl:1,whole:[5,4],bitset:12,pre:[7,2,3],simpli:[5,7],within:[5,6,7,2],overview:[0,8],address:5,period:7,except:[7,1,8],arbitrarili:1,header:[5,7],home_bodi:1,path:[7,2,3],respect:2,assum:6,liabil:4,java:[0,7,11,2,3],union:[5,1],trademark:4,due:5,been:12,compon:1,much:8,treat:5,subscrib:5,get_excep_expr:1,quickli:10,wide_char_typ:1,dcpsisocpp:2,unsigned_int:1,wide_character_liter:1,ani:[5,7,1,12,3],const_typ:1,togeth:8,input:[6,7,8],ospl_idl_compil:3,those:[5,8],"case":[5,6,7,1,2],home_export:1,multi:7,look:7,foospldcp:8,servic:11,defin:[0,7,1,3],"while":[6,2],match:7,shall:12,error:7,event_head:1,manner:5,gateshead:4,file:[6,7,3,8],value_forward_dcl:1,readm:7,typesupport:[5,6,8],itself:[12,8],value_box_dcl:1,ascii:1,struct_head:1,time_t:[6,3],develop:10,perform:[5,7,8],alphabet:1,make:7,psm:[7,11],except_dcl:1,param_dcl:1,member:[5,1,12],template_type_spec:1,compat:8,ifndef:3,document:[10,11,4],scoped_nam:1,set_excep_expr:1,http:4,nest:12,upon:8,effect:5,capabl:12,rais:1,user:[7,12],extern:7,value_el:1,op_dcl:1,typic:5,expand:8,built:7,param_attribut:1,equival:12,scenario:5,onewai:1,macro:[7,3],thu:5,string_typ:1,interface_head:1,parenthes:12,fixed_pt_typ:1,interface_inheritance_spec:1,without:[5,7,8,3,4],thi:[2,3,4,5,6,7,8,10,12],endif:[7,3],jean:4,woburn:4,dimension:5,ubuntu:10,dcpscj:2,ann_head:1,foodcp:8,identifi:[5,7,1,10],foosacdcp:8,less:5,fixed_array_s:1,ldl:[6,2],supported_interface_spec:1,select:[6,7,12],ifdef:[7,1],const_exp:1,yet:12,languag:[7,11],web:4,signific:[1,10],also:[1,2,3,5,6,7,8,12],foodcps_impl:8,identif:5,add:5,other:[5,6,7,12,3],bibliographi:[2,10],guidelin:10,els:7,formal:11,dds_dcp:3,finder:1,take:1,real:11,applic:[2,3,5,6,7,8,10,12],jacorb:8,ospl_hom:[9,3],read:5,openfus:8,pascalcas:7,wstring:1,magnifi:8,apart:[6,2],like:[1,2,5,7,8,12],specif:[1,2,5,6,7,8,10,11,12],deprec:7,corpor:4,manual:8,resolv:8,any_typ:1,positive_int_const:1,vortex:[1,2,3,5,6,7,8,9,10,12],"boolean":[5,1],necessari:8,either:5,output:[7,1],architectur:11,manag:[11,1],cohabit:[7,12,8],www:4,right:4,old:7,acknowledg:4,dllimport:7,linux:10,some:[5,8],intern:5,enumer:1,"export":[7,1],home:1,librari:[8,2,10],mult_expr:1,both:12,lead:[5,7],though:12,octet:[5,1],datawrit:[5,6,8],substitut:7,type_spec:1,larg:5,iso:[7,11,8],slash:12,value_base_typ:1,condit:3,foo:[7,8],reproduc:4,context_expr:1,plu:8,run:[9,7,10],bold:1,slight:5,upperboundon:8,usag:[5,7],broker:11,rue:4,signed_long_int:1,step:0,state_memb:1,promot:5,although:5,fixed_pt_liter:1,appli:[12,10],dcp:[6,2,8],stage:8,faith:4,about:[0,7,8],jar:2,would:5,element_spec:1,octet_typ:1,commun:8,plai:6,page:[0,7],floating_pt_typ:1,addition:[6,8],idl:[7,2,3],attr_raises_expr:1,isocpp2:[7,2,12],type_id_dcl:1,disabl:7,wide_string_typ:1,subset:5,own:8,opensplic:[7,11,3,4],unary_expr:1,"float":[5,1],bound:[0,7],automat:7,appropri:8,isocpp:[7,2,12],value_nam:1,home_head:1,ensur:5,chang:[8,4],eventtyp:1,storag:5,your:8,sequence_typ:1,accordingli:5,processor:[7,2,3],wai:[5,6,2],getrais:1,support:[0,7,1,2,3],transform:5,"long":[5,1,12],custom:[7,1],avail:[6,7,10,8,4],char_typ:1,interfac:[1,5,6,7,8,12],includ:[1,3,7,10,8,12],replac:7,ann_dcl:1,icon:10,object_typ:1,"function":[6,7,8],verbatim:12,offer:7,publishes_dcl:1,primary_key_spec:1,link:[7,8],translat:7,inlin:5,"true":1,info:4,notat:12,made:4,possibl:5,"default":[5,7,1],maximum:5,below:[5,7,2,10],limit:[5,4],uses_dcl:1,highlight:1,similar:[1,8],emit:1,dds_open:2,model:[5,7],featur:[5,7],unsigned_long_int:1,creat:[7,10],certain:5,"abstract":1,repres:12,dcpssac:2,exist:12,component_forward_dcl:1,ann_inheritance_spec:1,dcpssaj:2,face:7,fill:5,assembl:2,again:5,readonli:1,sourc:8,simular:8,index:5,hpp:7,when:[5,7,12,3,8],detail:[7,8,12,10],prepend:[7,1],field:5,bracket:7,role:[6,8],futur:12,you:[5,7],runtim:[12,3],poor:5,dcpsc99:2,intend:0,value_head:1,sequenc:[7,1],introduc:5,ansi:1,stac:5,consid:5,boolean_liter:1,component_inheritance_spec:1,ospl_orb_path:7,reduc:5,typeid:1,attr_declar:1,longer:5,directori:[9,7],descript:[8,10],rule:5,discrimin:5,ignor:[5,7,1],fact:5,time:[5,11],far:5,escap:[7,1],unsigned_longlong_int:1,switch_type_spec:1},objtypes:{},objnames:{},filenames:["index","grammar","ddsmodes","ddsdatatypes","contacts","keys","overview","commandline","modeslanguages","prerequisites","preface","bibliography","topictypes"],titles:["The IDL PreProcessor Guide","6. IDL Pre-processor Grammar","5. OpenSplice Modes and Languages","10. Built-in DDS data types","12. Contacts & Notices","7. Keys","2. Overview","4. Command Line Options","8. Modes, Languages and Processing steps","3. Prerequisites","1. Preface","11. References","9. Extensible and Dynamic Topic Types for DDS annotation support"],objects:{},titleterms:{pre:1,opensplic:2,process:8,overview:6,arrai:5,bound:5,indic:0,mode:[2,8],topic:12,tabl:0,guid:[0,10],dynam:12,option:7,java:8,built:3,convent:10,data:3,support:[5,12],idl:[0,1,10],languag:[2,8],command:7,type:[5,12,3],refer:11,isoc:8,intend:10,string:5,kei:5,c99:8,notic:4,standalon:8,step:8,preprocessor:[0,10],prerequisit:9,line:7,orb:8,introduct:6,prefac:10,about:10,grammar:1,extens:12,annot:12,charact:5,defin:5,audienc:10,contact:4,organis:10,integr:8,processor:1}}) \ No newline at end of file +Search.setIndex({envversion:42,terms:{xtype:11,represent:[5,6,7,2],all:[1,2,4,5,6,7,8,10],code:[5,6,7,8],partial:7,edg:4,interface_typ:1,queri:5,consum:1,ptc:11,prefix:[7,12],follow:[11,3,5,7,1,12],privat:1,integer_typ:1,"const":1,type_dcl:1,program:[2,3,6,7,10,8],matlab:7,adlink:[10,4],sens:7,keylist:5,ist_info:4,sent:5,and_expr:1,liter:1,everi:[5,7],string:[0,7,1],fals:1,"void":1,util:5,facebook:4,affect:5,relev:[5,1,10],condition:3,common:[11,1],dcpssacpp:2,level:[5,6],list:[5,6,7,2,10],fixed_pt_const_typ:1,fewer:5,factori:1,item:10,primary_expr:1,dcpsccpp:2,team:4,small:[5,8],preceed:5,mytypeannot:12,pleas:[7,12],prevent:1,impli:[6,7,2,8],tel:4,ten:5,direct:[7,1],sign:12,past:7,pass:7,further:8,idlpp:[9,7,1,3],event_abs_dcl:1,home_dcl:1,corba:[11,6,7,8,1,12],abc:5,sub:7,compar:5,section:[7,12,8],abl:[5,12,8],brief:10,member_list:1,current:7,boolean_typ:1,version:[11,8],awar:[5,3],"new":[7,1,12],"public":[1,10],involv:[7,3,8],full:7,deriv:7,gener:[1,5,6,7,10,8,12],here:5,custom_lib:7,let:5,header_fil:7,solari:10,param_type_spec:1,depend:7,"0xa":4,becom:7,sinc:7,valu:[7,1,12],search:0,larger:[7,8],technolog:4,behav:5,action:3,typic:[5,7],constr_forward_decl:1,portabl:8,overrid:7,via:[7,3,8],init_param_decl:1,prerequisit:[0,10],primit:[7,8],modul:[5,1,3],build_my_dl:7,avenu:4,filenam:7,unix:[9,7,2,10],api:[5,6,7,8],instal:9,middlewar:5,"__declspec":7,from:[2,5,6,7,9,8],describ:[9,7,12,10],usa:4,memori:5,doubl:[5,1,12],regist:8,two:[6,2,12],suit:4,call:[5,3],tradecent:4,dataread:[5,6,8],taken:[3,10],scope:[5,8],type:[7,11],ccpp:[7,2],more:[7,12,8],desir:5,valuetyp:1,relat:[6,2,8],type_declar:1,setrais:1,trail:7,flag:7,accept:[6,1,12],particular:10,actual:5,compani:4,cach:7,must:[5,9,1,3,8],high:6,account:1,word:5,annot:[0,1,10],cat:5,can:[2,3,5,6,7,9,8,12],floating_pt_liter:1,purpos:8,root:9,could:7,constr_type_spec:1,proof:12,control:[7,3],dcpsac:2,my_annotation_member_2:12,scan:6,process:[5,0,7,1,3],share:[6,7,2,12],templat:[6,7,2],topic:[5,0,11,10],base_type_spec:1,keyfield:5,caution:10,my_annotation_member_1:12,want:7,tao:[7,8],unsign:[5,1],implement:[7,12,8],alwai:5,simulink:7,multipl:1,component_export:1,valuebas:1,write:[5,12],how:10,bitbound:12,ebnf:1,perspect:5,map:[1,2,5,6,7,8,11],product:[5,10],orsai:4,invok:[9,7,3],diagram:[6,8],befor:9,compli:[6,7,1],attent:3,mai:[5,7,1,4],underscor:1,data:[7,11],op_type_spec:1,alloc:5,"short":[5,1],event_dcl:1,correspond:[7,8],value_dcl:1,element:[5,1],inform:[5,7,10,8,4],"switch":1,duration_t:3,combin:[5,7],allow:[5,6,7,12,8],add_expr:1,order:[12,3,8],help:10,routin:7,over:5,consumes_dcl:1,report:7,comma:5,same:[5,7],csharp:7,fusion_1_4_1:2,still:[5,8],pointer:5,dynam:[0,11,10],typedef:[5,1],group:11,sacpp:[7,2],fix:[5,1],dds_api:7,platform:[9,7,2],window:[7,2,10],com:[9,7,4],requir:[7,8,10],mail:4,therefor:[5,3],ann_bodi:1,them:[12,10],good:4,thei:[5,12],handl:[6,8,10],gadget:12,fooc:7,switch_typ:1,mention:5,facilit:5,instead:[2,5,6,7,8,12],nor:5,introduct:0,name:[2,5,6,7,8,12],anyth:12,readonly_attr_spec:1,separ:[5,7],token:12,exampl:[3,5,6,7,8,12],mode:7,each:[5,2,10],fulli:9,complet:[7,1],truncat:1,mean:[5,7,3,10],compil:[3,8],domain:7,wide_string_liter:1,ne11:4,raises_expr:1,"static":7,expect:7,character_liter:1,unsigned_short_int:1,event:1,special:[3,5,6,7,10,8,12],out:1,variabl:7,shown:[7,8,12,10],space:[5,6,7,2],publish:[5,1],stub:7,suitabl:5,rel:5,reader:10,array_declar:1,component_dcl:1,correct:5,ann_appl_param:1,franc:4,migrat:7,mustunderstand:12,situat:5,given:8,standard:7,primarykei:1,standalon:[0,7,2],base:[9,7,8,1,10],releas:9,org:7,orb:[0,7,2,3],prefac:0,value_abs_dcl:1,dllimport:7,angl:7,init_dcl:1,omit:7,ist:4,myannot:12,length:5,organis:0,outsid:7,dcpsisocpp2:2,"5th":4,interface_bodi:1,first:[5,7,1],oper:[5,7,8],simple_type_spec:1,suffix:[7,12],forward_dcl:1,arrai:[0,7],struct_typ:1,number:[5,6,12],dll_macro_nam:7,alreadi:12,done:8,component_head:1,imported_scop:1,size:[5,7],differ:[7,8],signed_short_int:1,convent:0,script:7,interact:8,system:[6,11,3,10],definit:[1,3,5,6,7,8,12],termin:[5,7,8],"final":[11,10],store:5,shell:9,home_inheritance_spec:1,ann_attr:1,namespac:8,copi:7,exception_list:1,specifi:[1,5,6,7,8,12],dds_openfusion_1_6_1:7,part:[5,4],pars:[6,12],pragma:5,consult:7,wchar:1,exactli:5,const_dcl:1,than:[5,7,3,8],mechan:[5,10],target:[5,6,7],keyword:[7,1],provid:[1,2,3,5,6,8,10],remov:5,ann_appl_post:1,structur:5,charact:[0,7,1],type_prefix_dcl:1,mandatori:7,pre:[7,2,3],saj:[7,2],sac:[7,2],well:[2,5,6,10,8,12],argument:7,fusion_1_5_1:2,packag:7,switch_type_nam:1,have:[5,12,3],tabl:2,need:[5,6,7,8,10],seen:6,collis:1,attr_dcl:1,annotation_nam:1,"char":[5,7,1,8],squar:7,lib:2,switch_bodi:1,or_expr:1,violat:5,note:[6,7,1,12],mix:5,maintain:5,build:[7,3,8],which:[1,3,5,6,7,8,10],attr_spec:1,map_typ:1,even:[5,12],unless:7,distribut:11,"enum":[5,1],normal:[5,7],value_base_typ:1,c99:[0,7,2],object:[11,1,8],what:10,paid:3,most:5,abcd:5,regular:5,artifact:[6,2,8],addtion:7,"class":[6,7,8],appear:[1,12],give:10,ann_appl_dcl:1,adopt:11,request:11,doe:[5,7,1,12,8],declar:1,place:8,enclos:6,component_bodi:1,inout:1,unsigned_longlong_int:1,set:[5,9,7],show:[5,6,8,10],text:[7,11],typeprefix:1,syntax:[5,12],value_inheritance_spec:1,init_param_attribut:1,environ:[9,7],penalti:5,access:7,onli:[2,5,6,7,10,8,12],ann_appl:1,locat:[9,7],emits_dcl:1,copyright:4,interface_dcl:1,activ:7,should:[5,8],cpp:[7,12],iec:[7,11,8],local:[1,12],explicitli:[5,7],signed_longlong_int:1,becaus:[5,8],nativ:1,increas:5,union_typ:1,enum_typ:1,ospl_tmpl_path:7,complex_declar:1,enabl:[5,7,3,8],integr:[0,7,2],contain:[4,5,6,7,8,10],where:[5,6,7,2,10],summari:10,fieldnam:5,altern:[7,12],legaci:5,factory_dcl:1,isoc:[0,7,2],see:[5,7,2,8],integer_liter:1,result:5,reserv:[7,4],concern:5,case_label:1,wire:5,finder_dcl:1,correctli:9,simple_declar:1,shift_expr:1,struct:[5,1,12,3],unary_oper:1,dll:[7,2],written:5,between:[6,7,2,12],"import":[7,1],ann_fwd_dcl:1,inclus:3,attribut:[1,12],my_integ:12,signatur:7,accord:[6,2,8],omg:[11,2,6,8,1,12],kei:0,numer:1,parameter_dcl:1,subject:4,readonly_attr_declar:1,rostand:4,extens:[0,11,10],time_ttim:3,xor_expr:1,addit:[7,8],signed_int:1,op_attribut:1,provides_dcl:1,string_liter:1,howev:[5,7,3,8],hint:10,equal:[7,8],against:8,interface_nam:1,etc:[1,3],audienc:0,present:5,context:[6,1,2,8],logic:5,improv:7,event_forward_dcl:1,whole:[5,4],bitset:12,example_struct:3,simpli:[5,7],within:[5,6,7,2],overview:[0,8],address:5,period:7,except:[7,1,8],arbitrarili:1,header:[5,7],home_bodi:1,path:[7,2,3],respect:2,assum:6,liabil:4,java:[0,7,11,2,3],sarl:4,union:[5,1],trademark:4,due:5,been:12,compon:1,much:8,treat:5,subscrib:5,get_excep_expr:1,quickli:10,wide_char_typ:1,dcpsisocpp:2,unsigned_int:1,wide_character_liter:1,ani:[5,7,1,12,3],const_typ:1,togeth:8,input:[6,7,8],ospl_idl_compil:3,those:[5,8],"case":[5,6,7,1,2],home_export:1,multi:7,look:7,foospldcp:8,servic:11,defin:[0,7,1,3],"while":[6,2],match:7,shall:12,error:7,event_head:1,manner:5,gateshead:4,file:[6,7,3,8],value_forward_dcl:1,readm:7,typesupport:[5,6,8],itself:[12,8],value_box_dcl:1,linkedin:4,ascii:1,struct_head:1,time_t:[6,3],develop:10,perform:[5,7,8],alphabet:1,make:7,psm:[7,11],except_dcl:1,param_dcl:1,member:[5,1,12],template_type_spec:1,compat:8,ifndef:3,document:[10,11,4],scoped_nam:1,set_excep_expr:1,http:4,nest:12,upon:8,effect:5,capabl:12,rais:1,user:[7,12],extern:7,value_el:1,op_dcl:1,chang:[8,4],expand:8,built:7,param_attribut:1,equival:12,scenario:5,onewai:1,macro:[7,3],thu:5,string_typ:1,interface_head:1,parenthes:12,fixed_pt_typ:1,interface_inheritance_spec:1,without:[5,7,8,3,4],thi:[2,3,4,5,6,7,8,10,12],endif:[7,3],jean:4,woburn:4,dimension:5,ubuntu:10,dcpscj:2,ann_head:1,foodcp:8,identifi:[5,7,1,10],foosacdcp:8,less:5,fixed_array_s:1,ldl:[6,2],supported_interface_spec:1,select:[6,7,12],ifdef:[7,1],const_exp:1,yet:12,languag:[7,11],web:4,signific:[1,10],also:[1,2,3,5,6,7,8,12],foodcps_impl:8,identif:5,add:5,other:[5,6,7,12,3],bibliographi:[2,10],guidelin:10,els:7,formal:11,dds_dcp:3,finder:1,take:1,real:11,applic:[2,3,5,6,7,8,10,12],jacorb:8,ospl_hom:[9,3],read:5,openfus:8,adlinktech:4,pascalcas:7,wstring:1,magnifi:8,apart:[6,2],like:[1,2,5,7,8,12],specif:[1,2,5,6,7,8,10,11,12],deprec:7,corpor:4,manual:8,resolv:8,any_typ:1,positive_int_const:1,vortex:[1,2,3,5,6,7,8,9,10,12],"boolean":[5,1],necessari:8,either:5,output:[7,1],architectur:11,manag:[11,1],cohabit:[7,12,8],www:4,right:4,old:7,acknowledg:4,twitter:4,linux:10,some:[5,8],intern:5,enumer:1,"export":[7,1],home:1,librari:[8,2,10],mult_expr:1,both:12,lead:[5,7],though:12,octet:[5,1],datawrit:[5,6,8],substitut:7,type_spec:1,larg:5,iso:[7,11,8],slash:12,condit:3,foo:[7,8],reproduc:4,context_expr:1,plu:8,run:[9,7,10],bold:1,slight:5,upperboundon:8,usag:[5,7],broker:11,rue:4,signed_long_int:1,step:0,state_memb:1,promot:5,although:5,fixed_pt_liter:1,appli:[12,10],dcp:[6,2,8],stage:8,faith:4,about:[0,7,8],jar:2,would:5,element_spec:1,octet_typ:1,commun:8,plai:6,page:[0,7],floating_pt_typ:1,addition:[6,8],idl:[7,2,3],attr_raises_expr:1,isocpp2:[7,2,12],adlinktech_usa:4,type_id_dcl:1,disabl:7,wide_string_typ:1,subset:5,own:8,opensplic:[7,11,3,4],unary_expr:1,"float":[5,1],bound:[0,7],automat:7,appropri:8,isocpp:[7,2,12],value_nam:1,home_head:1,ensur:5,eventtyp:1,storag:5,your:8,sequence_typ:1,accordingli:5,processor:[7,2,3],wai:[5,6,2],getrais:1,support:[0,7,1,2,3],vallei:4,transform:5,"long":[5,1,12],custom:[7,1],avail:[6,7,10,8,4],char_typ:1,interfac:[1,5,6,7,8,12],includ:[1,3,7,10,8,12],replac:7,ann_dcl:1,icon:10,object_typ:1,"function":[6,7,8],verbatim:12,offer:7,publishes_dcl:1,primary_key_spec:1,link:[7,8],translat:7,inlin:5,"true":1,extend:12,notat:12,made:4,possibl:5,"default":[5,7,1],maximum:5,below:[5,7,2,10],limit:[5,4],uses_dcl:1,highlight:1,similar:[1,8],emit:1,dds_open:2,model:[5,7],featur:[5,7],unsigned_long_int:1,creat:[7,10],certain:5,"abstract":1,repres:[7,12],dcpssac:2,exist:12,component_forward_dcl:1,ann_inheritance_spec:1,dcpssaj:2,face:7,fill:5,assembl:2,again:5,readonli:1,sourc:8,simular:8,index:5,hpp:7,when:[5,7,12,3,8],detail:[7,8,12,10],prepend:[7,1],field:5,bracket:7,role:[6,8],futur:12,you:[5,7],runtim:[12,3],poor:5,dcpsc99:2,intend:0,value_head:1,sequenc:[7,1],introduc:5,ansi:1,stac:5,consid:5,boolean_liter:1,component_inheritance_spec:1,ospl_orb_path:7,reduc:5,typeid:1,attr_declar:1,longer:5,directori:[9,7],descript:[8,10],rule:5,discrimin:5,ignor:[5,7,1],fact:5,time:[5,11],far:5,escap:[7,1],dllexport:7,switch_type_spec:1},objtypes:{},objnames:{},filenames:["index","grammar","ddsmodes","ddsdatatypes","contacts","keys","overview","commandline","modeslanguages","prerequisites","preface","bibliography","topictypes"],titles:["The IDL PreProcessor Guide","6. IDL Pre-processor Grammar","5. OpenSplice Modes and Languages","10. Built-in DDS data types","12. Contacts & Notices","7. Keys","2. Overview","4. Command Line Options","8. Modes, Languages and Processing steps","3. Prerequisites","1. Preface","11. References","9. Extensible and Dynamic Topic Types for DDS annotation support"],objects:{},titleterms:{pre:1,opensplic:2,process:8,overview:6,arrai:5,bound:5,indic:0,mode:[2,8],topic:12,tabl:0,guid:[0,10],dynam:12,option:7,java:8,built:3,convent:10,data:3,support:[5,12],idl:[0,1,10],languag:[2,8],command:7,type:[5,12,3],refer:11,isoc:8,intend:10,string:5,kei:5,c99:8,notic:4,standalon:8,step:8,preprocessor:[0,10],prerequisit:9,line:7,orb:8,introduct:6,prefac:10,about:10,grammar:1,extens:12,annot:12,charact:5,defin:5,audienc:10,contact:4,organis:10,integr:8,processor:1}}) \ No newline at end of file diff --git a/docs/html/IDLPreProcGuide/topictypes.html b/docs/html/IDLPreProcGuide/topictypes.html index dddb931fd..d5504d7da 100644 --- a/docs/html/IDLPreProcGuide/topictypes.html +++ b/docs/html/IDLPreProcGuide/topictypes.html @@ -180,7 +180,7 @@

    Navigation

    \ No newline at end of file diff --git a/docs/html/ModelingGuide/_images/003_DesignPerspec_EgProj.png b/docs/html/ModelingGuide/_images/003_DesignPerspec_EgProj.png index 9867d4e5a..7a0268791 100644 Binary files a/docs/html/ModelingGuide/_images/003_DesignPerspec_EgProj.png and b/docs/html/ModelingGuide/_images/003_DesignPerspec_EgProj.png differ diff --git a/docs/html/ModelingGuide/_images/004_NewProjectDialog.png b/docs/html/ModelingGuide/_images/004_NewProjectDialog.png index 82c0764ad..14706667a 100644 Binary files a/docs/html/ModelingGuide/_images/004_NewProjectDialog.png and b/docs/html/ModelingGuide/_images/004_NewProjectDialog.png differ diff --git a/docs/html/ModelingGuide/_images/006_QoSsetEditor_overview.png b/docs/html/ModelingGuide/_images/006_QoSsetEditor_overview.png index 3a7bff862..3c154cf3e 100644 Binary files a/docs/html/ModelingGuide/_images/006_QoSsetEditor_overview.png and b/docs/html/ModelingGuide/_images/006_QoSsetEditor_overview.png differ diff --git a/docs/html/ModelingGuide/_images/016_ExportApplicationDialog.png b/docs/html/ModelingGuide/_images/016_ExportApplicationDialog.png index 528d3ea88..2f37ac4ad 100644 Binary files a/docs/html/ModelingGuide/_images/016_ExportApplicationDialog.png and b/docs/html/ModelingGuide/_images/016_ExportApplicationDialog.png differ diff --git a/docs/html/ModelingGuide/_sources/appendixa.txt b/docs/html/ModelingGuide/_sources/appendixa.txt index 9be515422..aaa0e3448 100644 --- a/docs/html/ModelingGuide/_sources/appendixa.txt +++ b/docs/html/ModelingGuide/_sources/appendixa.txt @@ -38,7 +38,7 @@ Chatter Application ChatterApplication.java /******************************************************************************* - * Copyright (c) 2012 to 2016 PrismTech Ltd. All rights Reserved. + * Copyright (c) 2012 to 2018 ADLINK Technology Limited. All rights Reserved. * LOGICAL_NAME: ChatterApplication.java * FUNCTION: Vortex OpenSplice Modeler Tutorial example code. * MODULE: Tutorial for the Java programming language. @@ -205,8 +205,8 @@ MessageBoard Application /************************************************************************ * - * Copyright (c) 2012 to 2016 - * PrismTech Ltd. + * Copyright (c) 2012 to 2018 + * ADLINK Technology Limited * All rights Reserved. * * LOGICAL_NAME: MessageBoardApplication.java @@ -396,7 +396,7 @@ ChatMessageDataReaderListenerImpl.java ChatMessageDataReaderListenerImpl.java /************************************************************************ - * Copyright (c) 2012 to 2016 PrismTech Ltd. All rights Reserved. + * Copyright (c) 2012 to 2018 ADLINK Technology Limited. All rights Reserved. * LOGICAL_NAME: ChatMessageDataReaderListenerImpl.java * FUNCTION: Vortex OpenSplice Modeler Tutorial example code * MODULE: Tutorial for the Java programming language @@ -625,8 +625,8 @@ NamedMessageDataReaderListenerImpl.java /************************************************************************ * - * Copyright (c) 2012 to 2016 - * PrismTech Ltd. + * Copyright (c) 2012 to 2018 + * ADLINK Technology Limited * All rights Reserved. * * LOGICAL_NAME: NamedMessageDataReaderListenerImpl.java @@ -719,8 +719,8 @@ UserLoad Application /******************************************************************************* - * Copyright (c) 2012 to 2016 - * PrismTech Ltd. + * Copyright (c) 2012 to 2018 + * ADLINK Technology Limited * All rights Reserved. * * LOGICAL_NAME: UserLoadApplication.java @@ -972,8 +972,8 @@ Error Handler /************************************************************************ * - * Copyright (c) 2012 to 2016 - * PrismTech Ltd. + * Copyright (c) 2012 to 2018 + * ADLINK Technology Limited * All rights Reserved. * * LOGICAL_NAME: ErrorHandler.java diff --git a/docs/html/ModelingGuide/_sources/appendixb.txt b/docs/html/ModelingGuide/_sources/appendixb.txt index 464c3786d..179d4f098 100644 --- a/docs/html/ModelingGuide/_sources/appendixb.txt +++ b/docs/html/ModelingGuide/_sources/appendixb.txt @@ -75,8 +75,8 @@ ChatterApplication.cpp, Linux Version /************************************************************************ * - * Copyright (c) 2012 to 2016 - * PrismTech Ltd. + * Copyright (c) 2012 to 2018 + * ADLINK Technology Limited * All rights Reserved. * * LOGICAL_NAME: ChatterApplication.cpp @@ -233,8 +233,8 @@ ChatterApplication.cpp, Windows Version /************************************************************************ * - * Copyright (c) 2012 to 2016 - * PrismTech Ltd. + * Copyright (c) 2012 to 2018 + * ADLINK Technology Limited * All rights Reserved. * * LOGICAL_NAME: ChatterApplication.cpp @@ -391,8 +391,8 @@ MessageBoardApplication.cpp, Linux Version /************************************************************************ * - * Copyright (c) 2012 to 2016 - * PrismTech Ltd. + * Copyright (c) 2012 to 2018 + * ADLINK Technology Limited * All rights Reserved. * * LOGICAL_NAME: MessageBoardApplication.cpp @@ -539,8 +539,8 @@ MessageBoardApplication.cpp, Windows Version /************************************************************************ * - * Copyright (c) 2012 to 2016 - * PrismTech Ltd. + * Copyright (c) 2012 to 2018 + * ADLINK Technology Limited * All rights Reserved. * * LOGICAL_NAME: MessageBoardApplication.cpp @@ -679,8 +679,8 @@ ChatMessageDataReaderListenerImpl.h, Linux version /************************************************************************ * - * Copyright (c) 2012 to 2016 - * PrismTech Ltd. + * Copyright (c) 2012 to 2018 + * ADLINK Technology Limited * All rights Reserved. * * LOGICAL_NAME: ChatMessageDataReaderListenerImpl.h @@ -785,8 +785,8 @@ ChatMessageDataReaderListenerImpl.h, Windows version /************************************************************************ * - * Copyright (c) 2012 to 2016 - * PrismTech Ltd. + * Copyright (c) 2012 to 2018 + * ADLINK Technology Limited * All rights Reserved. * * LOGICAL_NAME: ChatMessageDataReaderListenerImpl.h @@ -888,8 +888,8 @@ ChatMessageDataReaderListenerImpl.cpp /************************************************************************ * - * Copyright (c) 2012 to 2016 - * PrismTech Ltd. + * Copyright (c) 2012 to 2018 + * ADLINK Technology Limited * All rights Reserved. * * LOGICAL_NAME: ChatMessageDataReaderListenerImpl.cpp @@ -1067,8 +1067,8 @@ NamedMessageDataReaderListenerImpl.h, Linux Version /************************************************************************ * - * Copyright (c) 2012 to 2016 - * PrismTech Ltd. + * Copyright (c) 2012 to 2018 + * ADLINK Technology Limited * All rights Reserved. * * LOGICAL_NAME: NamedMessageDataReaderListenerImpl.h @@ -1154,8 +1154,8 @@ NamedMessageDataReaderListenerImpl.h, Windows Version /************************************************************************ * - * Copyright (c) 2012 to 2016 - * PrismTech Ltd. + * Copyright (c) 2012 to 2018 + * ADLINK Technology Limited * All rights Reserved. * * LOGICAL_NAME: NamedMessageDataReaderListenerImpl.h @@ -1240,8 +1240,8 @@ NamedMessageDataReaderListenerImpl.cpp /************************************************************************ * - * Copyright (c) 2012 to 2016 - * PrismTech Ltd. + * Copyright (c) 2012 to 2018 + * ADLINK Technology Limited * All rights Reserved. * * LOGICAL_NAME: NamedMessageDataReaderListenerImpl.cpp @@ -1319,8 +1319,8 @@ UserLoadApplication.cpp, Linux Version /************************************************************************ * - * Copyright (c) 2012 to 2016 - * PrismTech Ltd. + * Copyright (c) 2012 to 2018 + * ADLINK Technology Limited * All rights Reserved. * * LOGICAL_NAME: UserLoadApplication.cpp @@ -1535,8 +1535,8 @@ UserLoadApplication.cpp, Windows Version /************************************************************************ * - * Copyright (c) 2012 to 2016 - * PrismTech Ltd. + * Copyright (c) 2012 to 2018 + * ADLINK Technology Limited * All rights Reserved. * * LOGICAL_NAME: UserLoadApplication.cpp @@ -1755,8 +1755,8 @@ CheckStatus.h /************************************************************************ * - * Copyright (c) 2012 to 2016 - * PrismTech Ltd. + * Copyright (c) 2012 to 2018 + * ADLINK Technology Limited * All rights Reserved. * * LOGICAL_NAME: CheckStatus.h @@ -1804,8 +1804,8 @@ CheckStatus.cpp /************************************************************************ * - * Copyright (c) 2012 to 2016 - * PrismTech Ltd. + * Copyright (c) 2012 to 2018 + * ADLINK Technology Limited * All rights Reserved. * * LOGICAL_NAME: CheckStatus.cpp diff --git a/docs/html/ModelingGuide/_sources/codegeneration.txt b/docs/html/ModelingGuide/_sources/codegeneration.txt index 44f17ecc5..b5c4325b3 100644 --- a/docs/html/ModelingGuide/_sources/codegeneration.txt +++ b/docs/html/ModelingGuide/_sources/codegeneration.txt @@ -15,9 +15,9 @@ an easy-to-use, Eclipse-based graphical interface.* |caution| +------------------------------------------------------------------+ - | The OpenSplice HDE (version 6.1 or above) must be installed and | - | configured in order to generate code for OpenSplice from Vortex | - | OpenSplice Modeler. | + | The Vortex OpenSplice HDE (version 6.1 or above) must be | + | installed and configured in order to generate code for Vortex | + | OpenSplice from Vortex OpenSplice Modeler. | | | | Vortex Lite (version 1.2 or above) must be installed and | | configured in order to generate code targeting Vortex Lite from | @@ -31,7 +31,7 @@ aim and is able to generate: + code for DDS data types, including - - IDL specifications for Vortex OpenSplice DDS Data Types + - IDL specifications for Vortex OpenSplice Data Types - Native language interfaces for Vortex OpenSplice Data Types (*via* the Vortex OpenSplice IDL Pre-Processor) @@ -1674,4 +1674,3 @@ This class defines the following methods: .. |java| image:: ./images/icon-java.* :height: 6mm - \ No newline at end of file diff --git a/docs/html/ModelingGuide/_sources/contacts.txt b/docs/html/ModelingGuide/_sources/contacts.txt index fc6442d3a..d32f6016f 100644 --- a/docs/html/ModelingGuide/_sources/contacts.txt +++ b/docs/html/ModelingGuide/_sources/contacts.txt @@ -1,53 +1 @@ -.. _`Contacts & Notices`: - -.. VERY LITTLE EVER CHANGES IN HERE !! - Just keep an eye on the copyright notice. - -################## -Contacts & Notices -################## - -******** -Contacts -******** - -| **PrismTech Corporation** -| 400 TradeCenter -| Suite 5900 -| Woburn, MA -| 01801 -| USA -| Tel: +1 781 569 5819 - -| **PrismTech Limited** -| PrismTech House -| 5th Avenue Business Park -| Gateshead -| NE11 0NG -| UK -| Tel: +44 (0)191 497 9900 - -| **PrismTech France** -| 28 rue Jean Rostand -| 91400 Orsay -| France -| Tel: +33 (1) 69 015354 - - -Web: http://www.prismtech.com - -E-mail: \info@prismtech.com - -******* -Notices -******* - -**Copyright** © 2016 PrismTech Limited. All rights reserved. - -*This document may be reproduced in whole but not in part. -The information contained in this document is subject to change -without notice and is made available in good faith without -liability on the part of PrismTech Limited or PrismTech Corporation. -All trademarks acknowledged.* - -.. END +.. include:: ../../common/contacts.rst diff --git a/docs/html/ModelingGuide/_sources/index.txt b/docs/html/ModelingGuide/_sources/index.txt index c9058abe5..4b2d0865b 100644 --- a/docs/html/ModelingGuide/_sources/index.txt +++ b/docs/html/ModelingGuide/_sources/index.txt @@ -9,7 +9,7 @@ Modeling Guide .. toctree:: :maxdepth: 8 :numbered: - + preface introduction installation @@ -19,12 +19,12 @@ Modeling Guide launchconfig compileandrun tutorial - + appendixa appendixb - - contacts - + + contacts + Indices and tables ================== diff --git a/docs/html/ModelingGuide/_sources/installation.txt b/docs/html/ModelingGuide/_sources/installation.txt index 54d78d7d7..6a008bbd1 100644 --- a/docs/html/ModelingGuide/_sources/installation.txt +++ b/docs/html/ModelingGuide/_sources/installation.txt @@ -14,7 +14,7 @@ Modeler. **Step 1:** Prerequisites - Ensure that Java Version 6 (*required*) and the OpenSplice Host + Ensure that Java Version 6 (*required*) and the Vortex OpenSplice Host Development Environment [#]_ (*recommended*), plus any other supporting software (such as native compilers, for example), are installed and working. @@ -24,7 +24,7 @@ Modeler. *Release Notes* included with your Modeler product distribution. The Release Notes can be viewed by opening ``index.html`` located in - the root (or base) directory of your OpenSplice installation and + the root (or base) directory of your Vortex OpenSplice installation and following the *Release Notes* link. **Step 2:** Run the Vortex OpenSplice Modeler installer @@ -63,11 +63,11 @@ Modeler. **Step 3:** Install the license file - A license file must be obtained from PrismTech, then copied to + A license file must be obtained from ADLINK, then copied to the ``eclipse`` or ``eclipse/etc`` subdirectories where the Vortex OpenSplice Modeler has been installed, or copied to - the ``PrismTech/Vortex_v2/license`` directory, or have the - ``prismtech_LICENSE`` environment variable defined with the file + the ``ADLINK/Vortex_v2/license`` directory, or have the + ``ADLINK_LICENSE`` environment variable defined with the file path to the license file. @@ -75,21 +75,21 @@ Modeler. |unix| |linux| - ``/home/myHomeDir/PrismTech/Vortex_v2/Tools/VortexModeler/2.5.12/eclipse/etc`` + ``/home/myHomeDir/ADLINK/Vortex_v2/Tools/VortexModeler/2.5.12/eclipse/etc`` |windows| - ``\PrismTech\Vortex_v2\Tools\VortexModeler\2.5.12\eclipse`` + ``\ADLINK\Vortex_v2\Tools\VortexModeler\2.5.12\eclipse`` For more information about licensing, please refer to the *Getting Started Guide*. -Setting OpenSplice Preferences -****************************** +Setting Vortex OpenSplice Preferences +************************************* After installing the Vortex OpenSplice Modeler it is necessary -to specify the location of the OpenSplice DDS installation to be +to specify the location of the Vortex OpenSplice installation to be used. **Step 1:** Start the Vortex OpenSplice Modeler. @@ -98,12 +98,12 @@ used. **Step 3:** Select *OpenSplice*. -**Step 4:** Add the location of the OpenSplice DDS installation +**Step 4:** Add the location of the Vortex OpenSplice installation to ``OSPL_HOME``. In the ``OSPL_HOME`` path field enter (for example) - ``/home/apps/PrismTech/Vortex_v2/Device/VortexOpenSplice/6.6.0p1/HDE/x86_64.linux`` + ``/home/apps/ADLINK/Vortex_v2/Device/VortexOpenSplice/6.6.0p1/HDE/x86_64.linux`` The *Browse* button can be used to navigate through your file system to point to the installation. @@ -115,34 +115,34 @@ to ``OSPL_HOME``. Set the ``LITE_HOME`` path field, *e.g.* - ``/home/apps/PrismTech/Device/VortexLite/2.0.0`` + ``/home/apps/ADLINK/Device/VortexLite/2.0.0`` As before, you can set the ``LITE_URI`` path to a Vortex Lite configuration file if required. - .. _`The OpenSplice Preferences`: + .. _`The Vortex OpenSplice Preferences`: - .. centered:: **The OpenSplice Preferences** + .. centered:: **The Vortex OpenSplice Preferences** .. image:: /images/001_OpenSplicePreferences.png :width: 120mm :align: center - :alt: The OpenSplice Preferences + :alt: The Vortex OpenSplice Preferences The license location can also be specified using the *Licensing - Preferences* page, which is below the *OpenSplice Preferences* + Preferences* page, which is below the *Vortex OpenSplice Preferences* page described above. -.. _`OpenSplice licensing`: +.. _`Vortex OpenSplice licensing`: -.. centered:: **OpenSplice licensing** +.. centered:: **Vortex OpenSplice licensing** .. image:: /images/002_OpenSpliceLicensing.png :width: 120mm :align: center - :alt: OpenSplice licensing + :alt: Vortex OpenSplice licensing .. the illo above *ought* to be indented 2 spaces to align properly with the previous one in the PDF, but it actually @@ -174,7 +174,7 @@ OpenSplice Modeler installation. On **Unix-based platforms** (including Linux), the default path will be: - ``/home/myHomeDir/PrismTech/Vortex_v2/Tools/VortexModeler//uninstall`` + ``/home/myHomeDir/ADLINK/Vortex_v2/Tools/VortexModeler//uninstall`` where ```` is the release version number. @@ -182,7 +182,7 @@ OpenSplice Modeler installation. On **Windows-based platforms**, the default path will be: - ``\PrismTech\Vortex_v2\Tools\VortexModeler\\uninstall`` + ``\ADLINK\Vortex_v2\Tools\VortexModeler\\uninstall`` where ```` is the release version number. @@ -254,4 +254,3 @@ OpenSplice Modeler installation. .. |java| image:: ./images/icon-java.* :height: 6mm - \ No newline at end of file diff --git a/docs/html/ModelingGuide/_sources/introduction.txt b/docs/html/ModelingGuide/_sources/introduction.txt index 95f657e7a..8a1c5bd45 100644 --- a/docs/html/ModelingGuide/_sources/introduction.txt +++ b/docs/html/ModelingGuide/_sources/introduction.txt @@ -8,7 +8,7 @@ Introduction *The* Vortex OpenSplice Modeler *is an integrated Eclipse-based tool chain based on Data Distribution Service (DDS) domain-specific model driven techniques. It provides the -essential productivity tools of PrismTech’s third generation +essential productivity tools of ADLINK's third generation OMG-DDS suite.* Vortex OpenSplice is a suite of software products comprised of a diff --git a/docs/html/ModelingGuide/_sources/launchconfig.txt b/docs/html/ModelingGuide/_sources/launchconfig.txt index fa4126a4b..2467b8bfe 100644 --- a/docs/html/ModelingGuide/_sources/launchconfig.txt +++ b/docs/html/ModelingGuide/_sources/launchconfig.txt @@ -84,7 +84,7 @@ Creating the ``start`` Configuration *Location* text box. For example, on Windows this could be - ``"C:\Program Files (x86)\PrismTech\Vortex_v2\Device\VortexOpenSplice\6.6.0p1\HDE\x86.win32\bin\ospl.exe"``. + ``"C:\Program Files (x86)\ADLINK\Vortex_v2\Device\VortexOpenSplice\6.6.0p1\HDE\x86.win32\bin\ospl.exe"``. **Step 5** diff --git a/docs/html/ModelingGuide/_sources/preface.txt b/docs/html/ModelingGuide/_sources/preface.txt index ecf66c995..200225ad1 100644 --- a/docs/html/ModelingGuide/_sources/preface.txt +++ b/docs/html/ModelingGuide/_sources/preface.txt @@ -67,9 +67,9 @@ in the :ref:`Tutorial `. Conventions *********** -The icons shown below are used in PrismTech product documentation +The icons shown below are used in the Vortex product documentation to help readers to quickly identify information relevant to their -specific use of Vortex OpenSplice DDS. +specific use of Vortex OpenSplice. ========= ================================================================== @@ -108,4 +108,4 @@ specific use of Vortex OpenSplice DDS. .. |java| image:: ./images/icon-java.* :height: 6mm - \ No newline at end of file + diff --git a/docs/html/ModelingGuide/_sources/tutorial.txt b/docs/html/ModelingGuide/_sources/tutorial.txt index ce9aab254..502757658 100644 --- a/docs/html/ModelingGuide/_sources/tutorial.txt +++ b/docs/html/ModelingGuide/_sources/tutorial.txt @@ -366,8 +366,8 @@ following code extract. /***************************************************************** * - * Copyright (c) 2006 to 2016 - * PrismTech Ltd. + * Copyright (c) 2006 to 2018 + * ADLINK Technology Limited * All rights Reserved. * * LOGICAL_NAME: Chat.idl @@ -1408,4 +1408,4 @@ The output of each application should be as shown below: .. |java| image:: ./images/icon-java.* :height: 6mm - \ No newline at end of file + diff --git a/docs/html/ModelingGuide/appendixa.html b/docs/html/ModelingGuide/appendixa.html index 6fc42faed..22f482c8d 100644 --- a/docs/html/ModelingGuide/appendixa.html +++ b/docs/html/ModelingGuide/appendixa.html @@ -70,7 +70,7 @@

    10.1.1. Chatter Application
    ChatterApplication.java
     
     /*******************************************************************************
    - * Copyright (c) 2012 to 2016 PrismTech Ltd. All rights Reserved.
    + * Copyright (c) 2012 to 2018 ADLINK Technology Limited. All rights Reserved.
      * LOGICAL_NAME: ChatterApplication.java
      * FUNCTION:     Vortex OpenSplice Modeler Tutorial example code.
      * MODULE:       Tutorial for the Java programming language.
    @@ -234,8 +234,8 @@ 

    10.1.2. MessageBoard Application/************************************************************************ * - * Copyright (c) 2012 to 2016 - * PrismTech Ltd. + * Copyright (c) 2012 to 2018 + * ADLINK Technology Limited * All rights Reserved. * * LOGICAL_NAME: MessageBoardApplication.java @@ -423,7 +423,7 @@

    10.1.2.1. ChatMessageDataReaderListenerImpl.java \ No newline at end of file diff --git a/docs/html/ModelingGuide/appendixb.html b/docs/html/ModelingGuide/appendixb.html index d1e832033..79d7d8b7e 100644 --- a/docs/html/ModelingGuide/appendixb.html +++ b/docs/html/ModelingGuide/appendixb.html @@ -94,8 +94,8 @@

    11.1.1.1. ChatterApplication.cpp, Linux Version/************************************************************************ * - * Copyright (c) 2012 to 2016 - * PrismTech Ltd. + * Copyright (c) 2012 to 2018 + * ADLINK Technology Limited * All rights Reserved. * * LOGICAL_NAME: ChatterApplication.cpp @@ -248,8 +248,8 @@

    11.1.1.2. ChatterApplication.cpp, Windows Version/************************************************************************ * - * Copyright (c) 2012 to 2016 - * PrismTech Ltd. + * Copyright (c) 2012 to 2018 + * ADLINK Technology Limited * All rights Reserved. * * LOGICAL_NAME: ChatterApplication.cpp @@ -404,8 +404,8 @@

    11.1.2.1. MessageBoardApplication.cpp, Linux Version/************************************************************************ * - * Copyright (c) 2012 to 2016 - * PrismTech Ltd. + * Copyright (c) 2012 to 2018 + * ADLINK Technology Limited * All rights Reserved. * * LOGICAL_NAME: MessageBoardApplication.cpp @@ -550,8 +550,8 @@

    11.1.2.2. MessageBoardApplication.cpp, Windows Version/************************************************************************ * - * Copyright (c) 2012 to 2016 - * PrismTech Ltd. + * Copyright (c) 2012 to 2018 + * ADLINK Technology Limited * All rights Reserved. * * LOGICAL_NAME: MessageBoardApplication.cpp @@ -688,8 +688,8 @@

    11.1.2.3. ChatMessageDataReaderListenerImpl.h, Linux version/************************************************************************ * - * Copyright (c) 2012 to 2016 - * PrismTech Ltd. + * Copyright (c) 2012 to 2018 + * ADLINK Technology Limited * All rights Reserved. * * LOGICAL_NAME: ChatMessageDataReaderListenerImpl.h @@ -792,8 +792,8 @@

    11.1.2.4. ChatMessageDataReaderListenerImpl.h, Windows version/************************************************************************ * - * Copyright (c) 2012 to 2016 - * PrismTech Ltd. + * Copyright (c) 2012 to 2018 + * ADLINK Technology Limited * All rights Reserved. * * LOGICAL_NAME: ChatMessageDataReaderListenerImpl.h @@ -892,8 +892,8 @@

    11.1.2.5. ChatMessageDataReaderListenerImpl.cpp/************************************************************************ * - * Copyright (c) 2012 to 2016 - * PrismTech Ltd. + * Copyright (c) 2012 to 2018 + * ADLINK Technology Limited * All rights Reserved. * * LOGICAL_NAME: ChatMessageDataReaderListenerImpl.cpp @@ -1069,8 +1069,8 @@

    11.1.2.6. NamedMessageDataReaderListenerImpl.h, Linux Version/************************************************************************ * - * Copyright (c) 2012 to 2016 - * PrismTech Ltd. + * Copyright (c) 2012 to 2018 + * ADLINK Technology Limited * All rights Reserved. * * LOGICAL_NAME: NamedMessageDataReaderListenerImpl.h @@ -1154,8 +1154,8 @@

    11.1.2.7. NamedMessageDataReaderListenerImpl.h, Windows Version/************************************************************************ * - * Copyright (c) 2012 to 2016 - * PrismTech Ltd. + * Copyright (c) 2012 to 2018 + * ADLINK Technology Limited * All rights Reserved. * * LOGICAL_NAME: NamedMessageDataReaderListenerImpl.h @@ -1238,8 +1238,8 @@

    11.1.2.8. NamedMessageDataReaderListenerImpl.cpp/************************************************************************ * - * Copyright (c) 2012 to 2016 - * PrismTech Ltd. + * Copyright (c) 2012 to 2018 + * ADLINK Technology Limited * All rights Reserved. * * LOGICAL_NAME: NamedMessageDataReaderListenerImpl.cpp @@ -1314,8 +1314,8 @@

    11.1.3.1. UserLoadApplication.cpp, Linux Version/************************************************************************ * - * Copyright (c) 2012 to 2016 - * PrismTech Ltd. + * Copyright (c) 2012 to 2018 + * ADLINK Technology Limited * All rights Reserved. * * LOGICAL_NAME: UserLoadApplication.cpp @@ -1527,8 +1527,8 @@

    11.1.3.2. UserLoadApplication.cpp, Windows Version/************************************************************************ * - * Copyright (c) 2012 to 2016 - * PrismTech Ltd. + * Copyright (c) 2012 to 2018 + * ADLINK Technology Limited * All rights Reserved. * * LOGICAL_NAME: UserLoadApplication.cpp @@ -1743,8 +1743,8 @@

    11.1.3.3. CheckStatus.h/************************************************************************ * - * Copyright (c) 2012 to 2016 - * PrismTech Ltd. + * Copyright (c) 2012 to 2018 + * ADLINK Technology Limited * All rights Reserved. * * LOGICAL_NAME: CheckStatus.h @@ -1788,8 +1788,8 @@

    11.1.3.4. CheckStatus.cpp/************************************************************************ * - * Copyright (c) 2012 to 2016 - * PrismTech Ltd. + * Copyright (c) 2012 to 2018 + * ADLINK Technology Limited * All rights Reserved. * * LOGICAL_NAME: CheckStatus.cpp @@ -1949,7 +1949,7 @@

    Navigation

    \ No newline at end of file diff --git a/docs/html/ModelingGuide/codegeneration.html b/docs/html/ModelingGuide/codegeneration.html index 64bf210ba..b3dc1153c 100644 --- a/docs/html/ModelingGuide/codegeneration.html +++ b/docs/html/ModelingGuide/codegeneration.html @@ -64,9 +64,9 @@

    Navigation

  • -]", "i"), + // checked="checked" or checked + rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i, + rscriptType = /\/(java|ecma)script/i, + rcleanScript = /^\s*", "" ], + legend: [ 1, "
    ", "
    " ], + thead: [ 1, "

    The OpenSplice HDE (version 6.1 or above) must be installed and -configured in order to generate code for OpenSplice from Vortex -OpenSplice Modeler.

    +

    The Vortex OpenSplice HDE (version 6.1 or above) must be +installed and configured in order to generate code for Vortex +OpenSplice from Vortex OpenSplice Modeler.

    Vortex Lite (version 1.2 or above) must be installed and configured in order to generate code targeting Vortex Lite from Vortex OpenSplice Modeler.

    @@ -81,7 +81,7 @@

    Navigation

    aim and is able to generate:

    • code for DDS data types, including
        -
      • IDL specifications for Vortex OpenSplice DDS Data Types
      • +
      • IDL specifications for Vortex OpenSplice Data Types
      • Native language interfaces for Vortex OpenSplice Data Types (via the Vortex OpenSplice IDL Pre-Processor)
      • Typed interface code
      • @@ -1454,7 +1454,7 @@

        Navigation

      \ No newline at end of file diff --git a/docs/html/ModelingGuide/compileandrun.html b/docs/html/ModelingGuide/compileandrun.html index b70a75ec6..f4ee06238 100644 --- a/docs/html/ModelingGuide/compileandrun.html +++ b/docs/html/ModelingGuide/compileandrun.html @@ -187,7 +187,7 @@

      Navigation

    \ No newline at end of file diff --git a/docs/html/ModelingGuide/contacts.html b/docs/html/ModelingGuide/contacts.html index 7093a8a1a..d95364ad3 100644 --- a/docs/html/ModelingGuide/contacts.html +++ b/docs/html/ModelingGuide/contacts.html @@ -45,12 +45,12 @@

    Navigation

    -
    -

    12. Contacts & Notices¶

    +

    12.2. Notices¶

    -

    Copyright © 2016 PrismTech Limited. All rights reserved.

    -

    This document may be reproduced in whole but not in part. -The information contained in this document is subject to change -without notice and is made available in good faith without -liability on the part of PrismTech Limited or PrismTech Corporation. -All trademarks acknowledged.

    +

    Copyright © 2018 ADLINK Technology Limited. All rights reserved.

    +

    This document may be reproduced in whole but not in part. The information contained in this +document is subject to change without notice and is made available in good faith without +liability on the part of ADLINK Technology Limited. All trademarks acknowledged.

    @@ -144,7 +147,7 @@

    Navigation

    \ No newline at end of file diff --git a/docs/html/ModelingGuide/described.html b/docs/html/ModelingGuide/described.html index 9076ab652..9d988828c 100644 --- a/docs/html/ModelingGuide/described.html +++ b/docs/html/ModelingGuide/described.html @@ -1195,7 +1195,7 @@

    Navigation

    \ No newline at end of file diff --git a/docs/html/ModelingGuide/genindex.html b/docs/html/ModelingGuide/genindex.html index 6bf580f22..d138060c7 100644 --- a/docs/html/ModelingGuide/genindex.html +++ b/docs/html/ModelingGuide/genindex.html @@ -88,7 +88,7 @@

    Navigation

    \ No newline at end of file diff --git a/docs/html/ModelingGuide/index.html b/docs/html/ModelingGuide/index.html index e1cb050cc..5a7f1d239 100644 --- a/docs/html/ModelingGuide/index.html +++ b/docs/html/ModelingGuide/index.html @@ -59,7 +59,7 @@

    Modeling Guide2. Introduction
  • 3. Installation
  • @@ -351,7 +351,7 @@

    Navigation

    \ No newline at end of file diff --git a/docs/html/ModelingGuide/installation.html b/docs/html/ModelingGuide/installation.html index c47a0ee4e..701305207 100644 --- a/docs/html/ModelingGuide/installation.html +++ b/docs/html/ModelingGuide/installation.html @@ -57,7 +57,7 @@

    3.1. General Installation Instructions[1] (recommended), plus any other supporting software (such as native compilers, for example), are installed and working.

    @@ -65,7 +65,7 @@

    3.1. General Installation Instructionsindex.html located in -the root (or base) directory of your OpenSplice installation and +the root (or base) directory of your Vortex OpenSplice installation and following the Release Notes link.

    Step 2: Run the Vortex OpenSplice Modeler installer

    @@ -96,37 +96,37 @@

    3.1. General Installation Instructionseclipse or eclipse/etc subdirectories where the Vortex OpenSplice Modeler has been installed, or copied to -the PrismTech/Vortex_v2/license directory, or have the -prismtech_LICENSE environment variable defined with the file +the ADLINK/Vortex_v2/license directory, or have the +ADLINK_LICENSE environment variable defined with the file path to the license file.

    For example:

    unix linux

    -
    /home/myHomeDir/PrismTech/Vortex_v2/Tools/VortexModeler/2.5.12/eclipse/etc
    +
    /home/myHomeDir/ADLINK/Vortex_v2/Tools/VortexModeler/2.5.12/eclipse/etc

    windows

    -
    \PrismTech\Vortex_v2\Tools\VortexModeler\2.5.12\eclipse
    +
    \ADLINK\Vortex_v2\Tools\VortexModeler\2.5.12\eclipse

    For more information about licensing, please refer to the Getting Started Guide.

    -
    -

    3.2. Setting OpenSplice Preferences¶

    +
    +

    3.2. Setting Vortex OpenSplice Preferences¶

    After installing the Vortex OpenSplice Modeler it is necessary -to specify the location of the OpenSplice DDS installation to be +to specify the location of the Vortex OpenSplice installation to be used.

    Step 1: Start the Vortex OpenSplice Modeler.

    Step 2: Choose Window > Preferences.

    Step 3: Select OpenSplice.

    -

    Step 4: Add the location of the OpenSplice DDS installation +

    Step 4: Add the location of the Vortex OpenSplice installation to OSPL_HOME.

    In the OSPL_HOME path field enter (for example)

    -
    /home/apps/PrismTech/Vortex_v2/Device/VortexOpenSplice/6.6.0p1/HDE/x86_64.linux
    +
    /home/apps/ADLINK/Vortex_v2/Device/VortexOpenSplice/6.6.0p1/HDE/x86_64.linux

    The Browse button can be used to navigate through your file system to point to the installation.

    You can also set the OSPL_URI path if this is different from the @@ -136,17 +136,17 @@

    3.2. Setting OpenSplice PreferencesLITE_HOME path field, e.g.

    -
    /home/apps/PrismTech/Device/VortexLite/2.0.0
    +
    /home/apps/ADLINK/Device/VortexLite/2.0.0

    As before, you can set the LITE_URI path to a Vortex Lite configuration file if required.

    -

    -The OpenSplice Preferences

    The OpenSplice Preferences +

    +The Vortex OpenSplice Preferences

    The Vortex OpenSplice Preferences

    The license location can also be specified using the Licensing -Preferences page, which is below the OpenSplice Preferences +Preferences page, which is below the Vortex OpenSplice Preferences page described above.

    -

    -OpenSplice licensing

    OpenSplice licensing +

    +Vortex OpenSplice licensing

    Vortex OpenSplice licensing

    3.3. Uninstallation Instructions¶

    @@ -167,12 +167,12 @@

    3.3. Uninstallation Instructions/home/myHomeDir/PrismTech/Vortex_v2/Tools/VortexModeler/<version>/uninstall

    +
    /home/myHomeDir/ADLINK/Vortex_v2/Tools/VortexModeler/<version>/uninstall

    where <version> is the release version number.

    windows

    On Windows-based platforms, the default path will be:

    -
    \PrismTech\Vortex_v2\Tools\VortexModeler\<version>\uninstall
    +
    \ADLINK\Vortex_v2\Tools\VortexModeler\<version>\uninstall

    where <version> is the release version number.

    Step 2: Run the Vortex OpenSplice Modeler uninstaller.

    @@ -235,7 +235,7 @@

    Table Of Contents

    \ No newline at end of file diff --git a/docs/html/ModelingGuide/introduction.html b/docs/html/ModelingGuide/introduction.html index 2d8e790dd..3cf72aaaf 100644 --- a/docs/html/ModelingGuide/introduction.html +++ b/docs/html/ModelingGuide/introduction.html @@ -54,7 +54,7 @@

    Navigation

    The Vortex OpenSplice Modeler is an integrated Eclipse-based tool chain based on Data Distribution Service (DDS) domain-specific model driven techniques. It provides the -essential productivity tools of PrismTech’s third generation +essential productivity tools of ADLINK’s third generation OMG-DDS suite.

    Vortex OpenSplice is a suite of software products comprised of a high-performance, low-overhead run-time environment, development @@ -178,7 +178,7 @@

    Navigation

    \ No newline at end of file diff --git a/docs/html/ModelingGuide/launchconfig.html b/docs/html/ModelingGuide/launchconfig.html index 1a561e0f2..4e370177c 100644 --- a/docs/html/ModelingGuide/launchconfig.html +++ b/docs/html/ModelingGuide/launchconfig.html @@ -130,7 +130,7 @@

    7.1.1. Creating the startOSPL executable should appear in the Location text box.

    For example, on Windows this could be -"C:\Program Files (x86)\PrismTech\Vortex_v2\Device\VortexOpenSplice\6.6.0p1\HDE\x86.win32\bin\ospl.exe".

    +"C:\Program Files (x86)\ADLINK\Vortex_v2\Device\VortexOpenSplice\6.6.0p1\HDE\x86.win32\bin\ospl.exe".

    Step 5

    @@ -290,7 +290,7 @@

    Navigation

    \ No newline at end of file diff --git a/docs/html/ModelingGuide/modeling.html b/docs/html/ModelingGuide/modeling.html index 59febdaa3..b6bed6be8 100644 --- a/docs/html/ModelingGuide/modeling.html +++ b/docs/html/ModelingGuide/modeling.html @@ -785,7 +785,7 @@

    Navigation

    \ No newline at end of file diff --git a/docs/html/ModelingGuide/objects.inv b/docs/html/ModelingGuide/objects.inv index 88d115086..3e648616a 100644 Binary files a/docs/html/ModelingGuide/objects.inv and b/docs/html/ModelingGuide/objects.inv differ diff --git a/docs/html/ModelingGuide/preface.html b/docs/html/ModelingGuide/preface.html index 1df36e98b..18504c214 100644 --- a/docs/html/ModelingGuide/preface.html +++ b/docs/html/ModelingGuide/preface.html @@ -95,9 +95,9 @@

    1.3. Organisation

    1.4. Conventions¶

    -

    The icons shown below are used in PrismTech product documentation +

    The icons shown below are used in the Vortex product documentation to help readers to quickly identify information relevant to their -specific use of Vortex OpenSplice DDS.

    +specific use of Vortex OpenSplice.

    @@ -207,7 +207,7 @@

    Navigation

    \ No newline at end of file diff --git a/docs/html/ModelingGuide/search.html b/docs/html/ModelingGuide/search.html index 1e58f86e2..a2a3d6d14 100644 --- a/docs/html/ModelingGuide/search.html +++ b/docs/html/ModelingGuide/search.html @@ -95,7 +95,7 @@

    Navigation

    \ No newline at end of file diff --git a/docs/html/ModelingGuide/searchindex.js b/docs/html/ModelingGuide/searchindex.js index 59a679376..eef678f5d 100644 --- a/docs/html/ModelingGuide/searchindex.js +++ b/docs/html/ModelingGuide/searchindex.js @@ -1 +1 @@ -Search.setIndex({envversion:42,terms:{dds_retcode_illegal_oper:10,sleep:[12,10],whose:[9,2],"const":[10,1,11],dds_retcode_error:[12,10],under:[1,2,5,7,9,11],keylist:11,not_alive_instance_st:[12,10],"void":[12,10,1],affect:9,m_previousid:10,correct:[4,11],mygc:1,println:12,nameservicedatawriterwrapp:12,x86_64:8,clarifi:2,direct:1,second:[12,10,1,2,11],iostream:10,valid_data:[12,10],blue:11,hide:[2,11],"_wait":12,"new":[1,8,2,5,12,7,9,10,11],widget:2,here:11,studio:1,undo:2,path:[8,2,11],pthread_t:10,avenu:3,unix:[8,11,6],middlewar:[4,2],describ:[7,1],would:[9,1,11],on_data_avail:[12,10,1],call:[1,2,11],tradecent:3,recommend:[8,9,2,5],type:[0,1,2,4,12,8,10],until:[9,10,2,11,12],myappdp:[1,11],relat:[4,9,1,2,11],warn:2,keep_al:11,hold:[12,10,2,11],livchangedstatushold:12,infoseq:[12,10],must:[1,8,2,5,7,9,11],join:[12,10,11],room:[12,10],work:[8,2,11],root:[8,2],overrid:[12,1],give:[1,6],indic:1,alive_count:[12,10],nr_error_cod:12,want:2,chatterappl:12,unsign:10,end:11,domainparticipant_nam:1,how:[1,2,5,6,7,9,11],ancestor:2,collaps:2,vortex_v2:[8,5],after:[8,1,2,11],createmutex:10,diagram:1,befor:[8,1,2,11],demonstr:[11,6],attempt:1,third:4,namedmessagedatawriterwrapp:[12,10],receiv:[1,2,12,9,10,11],environ:[4,8,2,7,5],enter:[1,8,2,5,9,11],order:[12,10,1],oper:[8,2,5,9,12,10,11],composit:4,feedback:11,loadadmin:[12,10],over:[12,10],becaus:[12,8],keyboard:2,flexibl:4,getpublisherwrapp:[10,11],fit:2,mydp:1,inadvert:2,publisher_nam:1,hidden:2,length_unlimit:[12,10],them:[8,1,2,11],thei:[9,1,2,11,12],rectangl:11,"break":[12,10],not_read_sample_st:[12,10,11],guardconditionwrapp:12,choic:1,getmyqcwrapp:1,accommod:10,timeout:[9,2],each:[1,2,4,12,9,10,11],complet:[9,2,11],userloadw:[12,10],mean:[4,2,11,6],getinstancestatemask:1,sampleinfoseq:10,extract:[12,10,11],network:[4,11],newli:[9,2,11],content:[1,2,12,9,10,11],navig:[9,8,11],situat:9,free:[9,11,12],standard:[4,11],statusmask:1,filter:[9,1,2,11,12],onto:11,independ:[9,2,11],restrict:2,instruct:[0,2],alreadi:[9,10,2,12],messag:[12,10,11],top:[8,2,11,5],stack:10,too:[12,2],similarli:9,listen:[12,10],consol:11,namespac:[10,1,11],tool:[4,0,2,8,5],target:[4,9,1,11,7],provid:[0,1,2,5,4,6,9],tree:[1,2,11,5],getmygcwrapp:1,getdatawrit:[12,10,1,11],seen:2,datareader_ptr:[10,1],minu:2,thorough:11,sleeper:[12,10],transmit:[2,11],getstatusmask:[10,1],even:11,dds_retcode_no_data:[12,10],usernam:[12,10,11],object:[1,2,4,12,9,10,11],preset:7,letter:11,getpublish:[1,11],paradigm:9,readcondition_ptr:10,nameserviceinfoseq:[12,10],doe:[1,2,11,5],dummi:1,declar:[1,11],setqueryparamet:[12,10,1],namedmessageseq:10,getmyreaderwrapp:1,syntax:9,wrapperexcept:[12,10,1],m_statusmask:1,publicationmatchstatu:1,menu:[1,2,5,7,9,11],explain:[1,6],configur:[4,0,1,8,7],retcode_no_data:[12,10],busi:[0,1,3],dds_retcode_immutable_polici:[12,10],getviewstatemask:1,m_namedmsgread:10,stop:[0,10,1,12],getnamedmessagedatawriterwrapp:10,bar:[7,9,2,11,5],"public":[9,10,1,12],cleanli:1,qosset:[1,2],getreason:12,result:[12,1],respons:[2,11],fail:[12,10,1,11],best:4,subject:3,awar:[4,9,1],databas:9,figur:11,simplest:11,approach:11,attribut:[9,10,2,12],accord:[7,9,1,2],omg:[4,9,1,2,11],extend:[12,1,2],extens:2,toler:[4,11],namedmessagedatareader_ptr:10,fault:[4,11],howev:[1,2,5,7,9,11],against:7,logic:[0,1,2],com:[1,3],"2nd":4,guid:2,assum:[9,5],duplic:[1,2,5],liabil:3,three:[1,2,11],been:[1,8,2,9,12,10,11],trigger:[9,10,1,2,12],interest:[9,1,2],subscrib:10,quickli:[2,6],duration_infinit:[12,10],argument:[12,10,1,5],getnamedmessagedatareaderwrapp:10,child:[2,11],"catch":[12,10],emploi:11,ident:11,servic:[4,9,2,11],air:4,aim:1,calcul:2,multitop:9,pthread_mutex_destroi:10,instancehandle_t:10,sever:1,perform:[4,1,2,11],suggest:11,make:[7,2],complex:4,namefind:[12,10],userhandl:[12,10],hand:[2,11,5],rais:[4,1],domanparticip:9,kept:11,inherit:[1,2,11],pthread_mutex_t:10,wherebi:1,thi:[1,8,5,4,3,9,7,2,10,11,12],endif:[10,1],getnameservicedatawriterwrapp:10,programm:1,jean:3,woburn:3,left:[12,10,2,11,5],set_expression_paramet:10,identifi:[12,10,2,11,6],just:[9,1,2],languag:[1,2,6,9,12,10,11],easi:[4,1],previousid:[12,10],had:[12,11],board:11,els:[12,10],ospl_hom:8,on_offered_incompatible_qo:1,vortexopensplicemodel:8,lite_hom:8,daemon:[7,11,5],specif:[0,1,2,5,4,7,12,10],nameservicedatareaderwrapp:[12,10],manual:[1,2,5,7,9,11],zoom:11,underli:1,www:[2,3],right:[1,2,5,3,12,7,9,10,11],intern:1,interf:11,alive_instance_st:[12,10,11],bottom:[2,11,5],getsubscriberwrapp:10,subclass:1,datawrit:[0,1,2,4,12,10],track:11,condit:[12,10],plu:[8,2,11],messageboardapplicationwrapperimplement:10,getstatuscondit:[12,1],getwaitset:[12,10,1],ccpp_dds_dcp:[10,1],promot:2,peer:11,post:11,plug:2,obj:1,simul:11,produc:[1,2],getnamedmessagefilteredtopicwrapp:10,orsai:3,dds_retcode_inconsistent_polici:[12,10],chatmessagedatawriterwrapp:12,wrap:1,accordingli:2,wai:[9,5,11,6],support:[1,8,4,9,2,11],avail:[4,7,2,3],editor:1,overhead:4,statuscondit:12,form:2,offer:4,heap:10,pthread_mutex_unlock:10,"true":[12,10,2,11],reset:2,conditionseq:10,datareaderlisten:1,caution:6,"0p1":[8,5],featur:[4,2,11,6],alongsid:2,data_avail:11,terminationreceiv:[12,10],proven:4,exist:[8,10,1,2,9],check:[12,10,1,2,11],assembl:[9,2,6],exported_messageboardapplicationdcp:10,when:[9,1,2,11,5],set_query_paramet:[12,10],"_chatmessagedatareaderlistenerimpl_h_":10,tid:10,privateparticipantwrapp:[12,10],node:11,notif:[9,1,2],intend:[0,2],chatmessagedatawriter_ptr:10,consid:2,sql:[9,2],longer:1,getcondit:[10,1],ignor:[12,10,11],time:[1,2,4,12,9,11],queryparamet:1,getdataread:[12,10,1],chain:[4,2],skip:8,consum:12,focus:11,signific:6,namedmessagedatareaderlistenervar:10,reader_nam:1,hierarch:[4,2],depend:[9,2],thandl:10,readabl:2,ownid:[12,10],namedmessagedatawriter_ptr:10,string:[12,10,1,11],uml:2,word:[9,1,2,11,5],on_requested_deadline_miss:1,brows:[9,1,8,11,5],on_liveliness_lost:1,chatdiagram:11,level:[1,2],chatmessageseqhold:12,item:[5,9,1,2,6],mysubscrib:1,round:4,prevent:2,talker:[12,10,11],corba:11,lazili:1,current:[1,8,4,12,2,9,10,11],userloadappl:12,scada:4,deriv:9,gener:[12,10],satisfi:[9,2],splice:[2,11],along:[2,11],toolbar:9,wait:[9,10,2,12],box:[9,1,2,11,5],shift:2,errorhandl:[12,11],namedmessagefilteredtopicwrapp:[12,10],regardless:9,m_namedmessagewrit:10,extra:2,modul:[0,1,2,9,12,10],prefer:[7,0],visibl:[2,11],marker:2,instal:[0,1],market:4,"__checkstatus_h__":10,memori:[11,5],connector:9,msg:[12,10],scope:[4,1],reorder:2,myread:1,appendic:6,peopl:11,waitset_nam:1,visual:[4,1],graphic:[4,1,2],focu:2,descriptor:2,handle_nil:[12,10],can:[1,8,2,5,7,9,11],on_subscription_match:1,getmyrcwrapp:1,purpos:[4,1,2,11],topic:[0,1,2,4,12,10],application1:1,occur:[12,10,1],alwai:[9,1,2,11],multipl:9,myapplic:1,write:[1,2,12,9,10,11],map:9,product:[4,8,2,6],membership:2,set_query_argu:[12,10],date:[12,10,11],mak:1,data:[12,10],geterrornam:[12,10],practic:4,explicit:10,inform:[0,1,2,3,4,5,12,8,10],"switch":2,guardcondit:[12,10],combin:11,create_querycondit:[12,10],still:[8,2],pointer:[10,1],"0ng":3,entiti:[0,1,2,4,12,10],conjunct:9,disconnect:1,monitor:[4,2],polici:1,platform:[1,8,2,5,7,9,10,11],getsamplestatemask:1,mail:3,main:[7,12,10,1,2],non:11,initi:[12,10,1,11],now:[9,1,11],nor:11,introduct:0,down:[1,2,11],term:11,name:[1,2,5,9,12,10,11],drop:[1,2,11],zoomabl:2,separ:[9,2,11],januari:[12,10],updat:11,domain:[4,9,2,11,5],messageboardapplicationwrapp:[12,10],individu:[4,9,2,11],continu:[1,8,11],dispos:[12,10],shown:[8,5,2,11,6],space:[1,11],getqueryconditionwrapp:10,profil:4,factori:2,integr:[4,2],contain:[1,2,3,6,7,9,10,11,12],prevcount:[12,10],argv:10,org:2,argc:10,m_nameserviceread:10,synchron:[9,2,12],turn:[1,2,11],place:[1,2,11],frequent:1,first:[8,1,2,11],origin:[9,1],directli:[1,2,11],onc:[1,2],arrai:[12,10],interruptedexcept:12,fast:[12,10],open:[8,2,5,9,12,10,11],size:[2,11],given:[8,2,6,9,12,10,11],breviti:[9,11],convent:[0,1],necessarili:2,waitset:[12,10],conveni:[5,2,6],getnameservicedatareaderwrapp:10,copi:8,retcodenam:[12,10],specifi:[12,8,10,2,9],getguardconditionwrapp:10,pragma:11,than:[9,2,11],serv:1,wide:4,vcproj:1,pre:[12,10,1,11],ani:[1,8,2,9,12,10,11],sampleinfoseqhold:12,engin:[4,2],techniqu:[4,2],note:[1,8,9,7,2,11],take:[12,10,1],advis:2,noth:1,statuscondt:[1,2],begin:11,ulong:10,normal:[8,2],buffer:10,namedmessagedatareaderlisten:[12,10,11],icon:[9,5,2,11,6],later:[12,10],drive:11,runtim:1,parseint:12,querycondition_ptr:10,show:[2,11],on_offered_deadline_miss:1,permiss:8,estop:12,corner:[2,11],"_module1_application1_listener1_h_":1,xml:4,onli:[1,2,5,6,12,9,11],explicitli:12,chatapp:11,activ:[12,10,11],state:[9,1,2,11],pthread_mutex_init:10,requestedincompatibleqosstatu:1,dword:10,numberstr:10,variou:[4,2],get:[1,8,11,5],tailor:4,take_w_condit:[12,10],requir:[1,8,2,4,5,12,7,9,10,11],reveal:[2,11],lite_uri:8,dramat:4,infoseq2:[12,10],namedmsgseq:[12,10],where:[1,8,5,4,6,2,9,11],data_available_statu:1,deadlin:2,reserv:[12,10,11,3],concern:2,infinit:10,dds_retcode_not_en:[12,10],userloadapplicationwrapp:12,label:9,enough:1,between:[1,2,4,9,10,11],"import":[12,1],across:11,parent:[9,2],screen:[8,2,11],typedef:11,cycl:12,dds_retcode_timeout:[12,10],come:7,dds_retcode_bad_paramet:[12,10],chatter1:11,audienc:0,tutori:[12,0,10,2,6],improv:2,chatmessag:[12,10,11],unistd:10,pop:[9,2,11],getdomainparticip:1,getchatmessagedatareaderwrapp:10,leftus:[12,10],rebuilt:11,"abstract":[1,11],get_liveliness_changed_statu:[12,10],ostringstream:10,wake:[9,2],workspac:[8,1,2,11],those:[9,2],"case":1,wrapperimplement:1,tostr:12,string_dup:10,hde:[1,8,11,5],cannot:[1,2],datawriter_nam:1,advantag:6,ctrl:11,destin:[9,11],readcondt:2,myapp:1,pthread:10,develop:[4,8,1,2,11],copy_from_topic_qo:2,same:[9,1,2,11],trip:4,html:8,exprparam:10,lite:[7,1,8],document:[3,6],status:[9,1,2],topicdescript:[0,2],namefinderexpr:12,finish:[1,2,12,9,10,11],getviewstatemak:1,nest:1,driven:[4,2],extern:5,appropri:[9,1,2,11],nameservic:[12,10,11],without:[8,9,2,11,3],model:[7,12,10,1],execut:[8,5,12,7,9,10,11],module1:1,readconditionwrapp:12,struct:[9,1,11],hint:6,returncod:[12,10],param:12,identif:11,offeredincompatibleqosstatu:1,any_instance_st:[12,10,11],real:[4,9,2,11],read:[9,10,2,11,12],test:0,traffic:4,nameserviceread:12,queryexpress:1,retcode_ok:[12,10],integ:12,benefit:6,either:[1,2,5,12,7,9,10],output:0,manag:[4,10,1,2],myparticip:1,constitut:[2,11],new_view_st:11,definit:[2,4,12,9,10,11],getguardcondit:[12,1],exit:[12,10,11],refer:[1,8,2,5,9,11],on_sample_reject:1,arrow:11,sampleloststatu:1,garbag:1,termination_messag:[12,10],fulli:[1,2],vcxproj:1,"throw":1,querycondit:[12,10],src:[1,11],central:11,side:[2,11,5],degre:11,stand:2,ospl:0,act:1,processor:1,effici:11,liveli:[12,10],opensplic:[7,12,10,1,3],unregist:[12,10],mark:[7,2],your:[1,8,5,7,2,11],messageboardappl:12,getreadconditionwrapp:10,log:11,area:[4,9,2,11],overwrit:[1,2],start:[0,1,2,12,8,10],compliant:[1,2,11,6],interfac:[8,1,2,11,9],low:[4,2],strictli:11,strict:2,getparticipantwrapp:[10,11],regard:[4,9],amongst:11,delayedescap:10,categor:2,possibl:9,"default":1,dds_retcode_out_of_resourc:[12,10],connect:[4,0,1,2],set_trigger_valu:[12,10],creat:[7,12,10,1],certain:[8,2,9],strongli:2,file:[1,8,2,5,12,7,9,10,11],dcpssaj:11,again:[12,10,2,11],setexpressionparamet:[12,10],inconsistenttopicstatu:1,field:[1,8,5,9,12,10,11],cleanup:[12,10],pathnam:[9,11,5],you:[1,8,12,7,2,10,11],waitset_ptr:10,architectur:[2,11],finali:6,symbol:[9,2,11],nameservicedatawrit:[12,10,11],chatmessagedatareaderwaitset:12,reduc:[4,2],nslist:[12,10],directori:[8,1,2,11],mask:[9,1,2,11],escap:[12,10],cpu:12,unset:12,represent:2,all:[1,8,5,4,3,9,7,2,10,11,12],istringstream:10,illustr:[9,2,11],partitionnam:1,concept:4,follow:[1,8,2,4,6,12,9,10,11],children:1,chatmessagedatareaderlisten:[12,10,11],program:[12,9,10,11,5],introduc:2,global:2,fals:[12,10,1],util:[7,11],mechan:2,mysc:1,list:[12,10,1,2,11],participantwrapp:[12,10],entity_nam:[1,11],small:11,chatmessageseq:10,tei:10,tel:3,getuserloadwaitsetwrapp:10,userloadwaitset:11,pass:1,further:9,what:[10,1,2,6],sub:[8,11],sun:4,section:[1,2,5,6,7,9,11],abl:[8,1,2,9],invok:[7,1],delet:[10,1],nexrt:11,method:[7,9,1,2,11],prismtech:[1,8,5,4,3,6,12,10,11],full:[9,5],domainparticp:11,newmessag:[12,10],chatmessage_top:11,qospolici:2,behaviour:[1,11],solari:6,rudimentari:11,modifi:[9,2],valu:[7,12,1],search:0,amount:12,getprivateparticipantwrapp:10,pick:2,action:2,myrc:1,via:1,depart:[12,10,11],primit:9,filenam:[1,8],establish:11,select:[1,8,2,5,7,9,11],samplerejectedstatu:1,regist:[12,10,1],two:[9,10,11,6],autonom:11,taken:6,more:[1,8,2,5,9,12,10,11],desir:[9,1,2,11,5],namedmessag:[12,10,11],flag:[12,10],prismtech_licens:8,particular:[9,2,11],known:[12,10],jdk:4,hous:3,outlin:[2,11,6],histori:[12,10,11],remain:11,"0ul":10,prompt:8,share:[11,5],accept:[4,1,11],namedmessagefilteredtop:11,explor:[8,1,2,11,9],rather:[2,11],anoth:[9,2],settermin:[12,10],simpl:[2,11],resourc:[2,6,9,12,10,11],compulsori:2,reflect:[9,1],exisit:1,associ:[9,1,2,11],"short":11,postfix:1,confus:11,caus:2,callback:1,help:[2,6],waitforsingleobject:10,held:1,through:[8,1,2,11,9],hierarchi:1,paramet:[12,1],style:2,condition_nam:1,alter:[2,11],good:3,"return":[12,10,1,2],on_liveliness_chang:1,framework:4,getmyscwrapp:1,on_data_on_read:1,getmywaitsetwrapp:1,num_msg:[12,10],detach:[12,10,1],userid:[12,10,11],unlik:9,easili:2,achiev:[1,11],compris:4,found:[12,10],addpublish:1,chatmessagedatareaderwrapp:[12,10],publisher1wrapp:1,expect:7,http:[2,3],event:1,namedmessagedatareaderwrapp:[12,10],publish:10,footnot:[8,1,2,11,9],publisherwrapp:[12,10],print:[12,10,11],returncode_t:10,occurr:2,difficulti:9,m_namefinderparam:10,like:[9,1,2],reason:2,base:[1,8,2,4,6,9,11],put:10,thrown:1,prefac:0,thread:[9,10,2,12],launch:0,participant1:1,perman:2,assign:[9,1,2,11],checkstatu:12,guardcondition_ptr:10,number:[1,8,2,9,12,10,11],done:[2,11],construct:11,livelinesschangedstatushold:12,miss:2,myapplicationwrapp:1,differ:[8,10,2,9],printstacktrac:12,interact:11,least:[12,10],dds_retcode_ok:[12,10],statement:1,scheme:9,option:[1,2,12,7,9,10,11],relationship:[2,11],getmywriterwrapp:1,park:3,part:[9,2,11,3],std:10,kind:11,whenev:9,remov:[12,10,1],architect:2,str:10,arrang:2,grei:9,comput:2,packag:[4,12,1,2,11],expir:[9,2],dedic:9,"null":[12,10,1],built:11,equival:2,myappdpwrapp:11,violat:2,also:[1,8,2,4,6,7,9,10,11],build:[7,8,2,11],distribut:[4,8,2,11,9],previou:11,most:[1,2],appear:[1,2,5,9,12,10,11],register_inst:[12,10],clear:[2,11],cover:11,clean:[8,11],find:[9,10,1,2,12],copyright:[12,10,11,3],setnam:1,on_publication_match:1,palett:[4,9,2,11],express:[9,1,2,11,12],nativ:[7,9,1,8],restart:8,chatmsgseq:[12,10],common:2,userloadapplicationwrapperimplement:10,set:[7,12,10,1],see:[7,9,2,11,5],sec:10,on_requested_incompatible_qo:1,arg:[12,10],close:[1,2,5,12,10,11],m_newmessag:10,particip:[9,10,1,11],invalid_handle_valu:10,subscript:[9,2],altern:[9,1,2],rostand:3,distinguish:[4,2],removepublish:1,popul:2,both:[4,9,1,2,11],last:9,delimit:11,alon:2,context:[4,9,2,11],whole:[1,2,3],load:[2,11],nametyp:11,simpli:[7,9,1,2],m_istermin:10,point:[8,11],instanti:[1,11],status_mask:1,except:[12,10,1,8,11],header:[10,1,11],shutdown:1,read_w_condit:[12,10],livchangstatu:10,devic:[8,5],empti:[9,1,2],accessor:1,myadddp:1,nameserv:[12,10],look:[12,10],solid:11,contentfilteredtop:[0,1,2],"while":[12,10,1,2],match:2,abov:[8,1,2,11,5],gateshead:3,readi:1,centr:2,herein:9,itself:[1,11],demot:2,"_local_is_a":1,shorten:4,conflict:[1,2],higher:2,x86:5,any_view_st:[12,10,11],wherea:1,alert:2,chatterapplicationwrapperimplement:[10,11],user:[1,8,2,6,9,12,10,11],m_chatmsgread:10,robust:4,implement:[0,1,2,9,12,10],lower:[2,11],task:[2,11],entri:[9,11],guardlist:[12,10],explan:2,cout:10,shape:2,cut:11,readcondit:[12,10],shortcut:11,mywrit:1,notifi:9,subsequ:[9,1,11],m_messageboardappl:10,bin:[8,5],vendor:4,transpar:11,formal:9,resolv:2,collect:[1,2],princip:1,"boolean":[9,1,2,12],encount:1,simplifi:[1,11],acknowledg:3,creation:[12,10,1,11],some:[12,10],back:[1,11],sampl:[1,2,12,9,10,11],max_nam:11,namedmessagewrit:12,return_loan:[12,10],releasemutex:10,namedmsgread:12,larg:[2,11],slash:11,reproduc:3,machin:8,run:[12,10,1],rue:3,step:[0,1,2,5,4,9,8],prerequisit:8,faith:3,idl:[4,0,1,2],dialog:[9,1,2,11,5],block:[9,2],myqc:1,on_sample_lost:1,within:[9,1,2,11,5],chatmessagedatareader_ptr:10,ensur:[4,8,2,11,9],chang:[12,10,1,3],durabl:[4,11],msglist:[12,10],offereddeadlinemissedstatu:1,"long":[12,10,11],custom:2,adjac:[9,2,11],includ:[1,8,5,4,6,12,2,9,10,11],suit:[4,3,2,6],forward:11,link:[8,2,11],vortexlit:8,line:[8,11],m_mutex:10,info:[12,10,3],consist:[9,2,11],similar:[9,11],dds_retcode_precondition_not_met:[12,10],constant:1,repres:[9,1,2,11],"char":[10,1],chat:[0,10,12],stringseq:10,vortexmodel:8,unregister_inst:[12,10],m_usernam:10,myapplicationwrapperimplement:1,invalid:[12,10],librari:11,namedmsg:[12,10],drag:[9,2,11],lang:11,getreadcondit:[12,1],algorithm:2,confirm:11,dataread:[0,1,2,4,12,10],depth:11,"transient":11,scroll:2,queri:[12,10,11],pthread_mutex_lock:10,chatterapplicationwrapp:[12,11],privat:[12,10,1],sensit:2,wizard:[9,2,11],send:[12,10,11],leav:[12,10,8,11],userloadwaitsetwrapp:12,sent:[12,10,11],mous:[2,11],untouch:8,implicitli:[12,10],relev:[1,2,11,6],dds_retcode_unsupport:[12,10],button:[1,8,2,5,9,11],"try":[12,10],create_particip:1,pleas:[1,8,11,5],datareaderlistener_var:10,uniqu:[2,11],click:[1,8,2,5,7,9,11],compat:2,index:[12,10,8,11],closehandl:10,compar:2,pthread_creat:10,access:[1,2,11],perimet:11,winapi:10,bodi:11,ubuntu:6,becom:[9,2],sinc:[9,10,2,12],convert:9,larger:11,cerr:10,typic:8,appli:[1,2,5,6,12,10],app:8,api:1,mypublish:1,from:[1,8,2,4,5,12,7,9,10,11],usa:3,commun:[9,1,2,11],doubl:[8,2,11],seamless:8,next:[9,2,11,6],stage:4,namedmessagedatawrit:[12,10,11],about:[0,9,2,8,5],publisher1wrapperimplement:1,folder:[8,1,2,11,9],retriev:[1,11],scalabl:[4,11],control:[1,2,5,4,6,9,11],"_namedmessagedatareaderlistenerimpl_h_":10,process:[8,2,11],lock:8,high:4,tab:[7,2,11,5],writer_nam:1,six:2,chatternam:[12,10],subdirectori:8,instead:[12,10,5],ne11:3,overridden:1,dds_retcode_already_delet:[12,10],alloc:[12,10],essenti:4,bind:9,correspond:[12,10,1],element:2,allow:[9,1,2,11],getsubscrib:1,ospl_uri:8,move:[2,11],whilst:1,own:[9,1,2,11],superior:4,chosen:[1,2],therefor:[1,11],chatmessagedatareaderlistenervar:10,subscriptionmatchedstatu:1,handl:[12,10],auto:[1,11],overal:4,handi:7,facilit:4,chatmsgread:12,anyth:11,edit:[7,1],nameserviceseq:[12,10],subset:[9,2],meta:4,"static":[12,10,1,11],our:10,out:[9,2,11,12],variabl:[7,8,5],string_mgr:10,defenc:4,ret:10,franc:3,shut:[1,11],chatmessagedataread:[12,10,11],insid:[9,11],createthread:10,nameservicedataread:[12,10,11],statusconditionwrapp:12,delete_readcondit:[12,10],releas:[1,8,4,12,2,9,10,11],getquerycondit:[12,1],complianc:4,livelinessloststatu:1,unwant:2,could:5,lpvoid:10,keep:11,length:[12,10],organis:[0,2],outsid:2,ltd:[12,10,11],retain:11,softwar:[4,8,2],m_namefind:10,suffix:1,qualiti:[4,2],mai:[9,2,3],owner:[12,10,2,11],facil:[7,2],prioriti:2,newus:[12,10],unknown:12,licens:8,system:[8,5,4,2,6,12,9,10,11],wrapper:[1,11],listener1:1,attach:[9,10,1,2,12],namefinderparam:12,termin:[12,10,11],"final":[12,1,2,11],nameservicedatawriter_ptr:10,getchatmessagedatawriterwrapp:10,exactli:[1,2],nameservicedatareader_ptr:10,structur:[2,11],light:11,getmysubscriberwrapp:1,viewer:2,clearli:4,have:[1,8,12,7,2,9,10,11],tabl:2,need:[1,2,6,7,9,11],nameserviceseqhold:12,create_readcondit:[12,10],liveliness_changed_st:11,preced:2,which:[1,8,5,2,6,7,9,11],singl:[4,9,1,2,11],unless:2,deploy:[4,7,2,11,5],who:11,deploi:4,"class":[1,2,12,9,10,11],subscriber_nam:1,request:[9,2],determin:[9,2],conditionseqhold:12,text:[9,1,2,11,5],mywaitset:1,namedmessageseqhold:12,chatmessagedatawrit:[12,10,11],locat:[1,8,2,5,9,11],jar:11,should:[1,8,2,5,9,12,11],combo:2,local:[7,2,11],familiar:2,increas:4,subscriptionmatchstatu:1,enabl:[1,8,2,5,7,9,11],upper:[2,11],she:11,ascertain:2,tuner:[4,11],view:[1,8,2,5,9,11],conform:4,workbench:7,publisher1:[1,11],project_nam:1,statu:[1,2,12,9,10,11],correctli:[2,11],pattern:4,datawriterswrapp:1,written:[9,10,2,11,12],setdefaultstatusmask:1,thumbnail:2,kei:[9,10,2,11,12],group:4,endl:10,addit:[1,2,5,7,9,11],plugin:8,equal:12,etc:[8,2],instanc:[1,2,12,9,10,11],comment:1,arriv:[9,2],chmod:8,walk:[12,10],"_var":1,respect:[9,2,11],addition:[7,1],queryconditionwrapp:12,trademark:3,compos:2,compon:1,besid:11,assert:[12,10],togeth:2,present:1,multi:[2,11],rectangular:11,cursor:11,defin:[1,8,4,9,2,10,11],"5th":3,incom:2,member:[9,1],subscriberwrapp:[12,10],ifndef:[10,1],mypublisherwrapp:11,on_inconsistent_top:1,expans:[2,11],repositryid:1,upon:1,effect:[12,10],canva:[9,2,11],expand:[9,1,2,11],off:11,nameservice_top:11,builder:7,well:[4,9,2,11],getmydpwrapp:1,command:[8,5],choos:[1,8,2,5,7,9,11],namedmessagedataread:[12,10,11],less:1,domainparticipantlisten:1,obtain:[8,10,1,2,12],chatmsginfoseq:[12,10],web:3,any_sample_st:[12,10,11],makefil:1,add:[8,1,2,11,9],valid:[12,10],statuscondition_ptr:10,smart:10,checkhandl:[12,10],realiz:4,know:1,press:2,getmypublisherwrapp:1,tick:7,recurs:2,insert:1,myhomedir:8,lost:[12,10],corpor:3,sstream:10,vortex:[7,12,10,1],necessari:8,lose:8,resiz:11,vortexopensplic:[8,5],suppli:4,home:[8,11],transport:11,win32:5,trust:4,leak:10,avoid:1,outgo:2,esc:2,speak:11,getnam:1,"enum":1,host:[8,11,5],although:[1,11],dcp:[9,1,8,11],panel:[1,2],c_str:10,actual:[4,9,2],requesteddeadlinemissedstatu:1,column:9,lifecycl:[4,1],disabl:[9,1,11],set_listen:10,artefact:1,livelinesschangedstatu:[10,1],automat:[7,9,1,2,11],guard:[12,10],privateparticip:[10,11],merg:[12,10,1,2],much:12,replac:[11,5],"function":[1,2,12,9,10,11],namedmessage_top:11,getstatusconditionwrapp:10,basic:[2,11,6],gain:1,uninstal:0,eas:4,buf:10,made:[9,2,11,3],whether:[9,10,1,12],wish:[1,11],displai:[1,2,12,7,9,10,11],asynchron:[9,2],below:[1,8,2,6,9,11],logical_nam:[12,10,11],limit:3,otherwis:[7,1],problem:[9,2],"int":[12,10,1],dure:8,mutual:2,guidanc:4,detail:[1,2,5,6,9,11],virtual:[10,1],other:[1,8,4,12,2,9,10,11],bool:10,futur:[4,1,2],rememb:11,repeat:[11,5],june:11,singleus:[12,10],reliabl:11,rule:2,istermin:[12,10]},objtypes:{},objnames:{},filenames:["index","codegeneration","described","contacts","introduction","launchconfig","preface","compileandrun","installation","modeling","appendixb","tutorial","appendixa"],titles:["Modeling Guide","6. Code Generation","4. Modeler Described","12. Contacts & Notices","2. Introduction","7. Creating Launch Configurations","1. Preface","8. Compiling and Running","3. Installation","5. Modeling","11. Appendix B","9. Tutorial","10. Appendix A"],objects:{},titleterms:{code:[12,10,1,11],chatmessagedatareaderlistenerimpl:[12,10],domainparticip:[9,1],entiti:9,polici:[2,11],writer:1,window:10,busi:11,save:1,applic:[9,10,1,11,12],sourc:[12,10,11],handl:1,stop:5,condit:[9,1],introduct:4,specif:9,edit:2,gui:2,provid:11,vortex:2,partit:[9,1,11],output:11,page:2,compil:[7,11],workbench:2,set:[8,2,11],"export":1,result:2,special:2,publish:[9,1],datawrit:9,delet:2,version:10,userloadappl:10,reader:1,"import":2,run:[7,11,5],gener:[1,8,11],step:11,eclips:[1,2],valu:[2,11],querycondit:[9,1],prefac:6,about:6,launch:5,idl:9,tutori:11,organis:6,ospl:5,logic:11,chang:2,configur:5,checkstatu:10,opensplic:[8,2],overview:[2,11],modul:11,prefer:8,instruct:8,linux:10,instal:8,guid:[0,6],messageboardappl:10,java:[7,12,1,11],describ:2,convent:6,compon:[9,2],start:5,handler:12,editor:2,subscrib:[9,1],waitset:[9,1],type:9,statuscondit:[9,1],listen:[9,1],userload:[12,10],tool:9,messageboard:[12,10],notic:3,appendix:[12,10],uninstal:8,chatter:[12,10],"default":2,contentfilteredtop:9,remov:2,properti:2,project:[1,2,11],error:[12,1],design:2,connect:9,creat:[2,11,5],descript:2,chatterappl:10,indic:0,topic:[9,11],namedmessagedatareaderlistenerimpl:[12,10],chat:11,tabl:0,topicdescript:9,audienc:6,contact:3,readcondit:[9,1],guardcondit:1,chatroom:[12,10,11],test:11,perspect:2,intend:6,diagram:2,data:1,implement:11,renam:2,dataread:9,inform:[9,11],exampl:[12,10,11],cpp:10,model:[0,9,2,11,6],order:2}}) \ No newline at end of file +Search.setIndex({envversion:42,terms:{dds_retcode_illegal_oper:10,sleep:[12,10],whose:[9,2],"const":[10,1,11],dds_retcode_error:[12,10],under:[1,2,5,7,9,11],livchangedstatushold:12,not_alive_instance_st:[12,10],"void":[12,10,1],affect:9,m_previousid:10,correct:[4,11],mygc:1,println:12,nameservicedatawriterwrapp:12,x86_64:8,clarifi:2,direct:1,second:[12,10,1,2,11],iostream:10,valid_data:[12,10],blue:11,hide:[2,11],"_wait":12,"new":[1,8,2,5,12,7,9,10,11],widget:2,here:11,studio:1,undo:2,path:[8,2,11],pthread_t:10,avenu:3,unix:[8,11,6],middlewar:[4,2],describ:[7,1],would:[9,1,11],on_data_avail:[12,10,1],call:[1,2,11],tradecent:3,recommend:[8,9,2,5],type:[0,1,2,4,12,8,10],until:[9,10,2,11,12],myappdp:[1,11],relat:[4,9,1,2,11],warn:2,keep_al:11,hold:[12,10,2,11],keylist:11,infoseq:[12,10],must:[1,8,2,5,7,9,11],join:[12,10,11],room:[12,10],work:[8,2,11],root:[8,2],overrid:[12,1],give:[1,6],indic:1,alive_count:[12,10],nr_error_cod:12,want:2,chatterappl:12,unsign:10,end:11,domainparticipant_nam:1,how:[1,2,5,6,7,9,11],ancestor:2,collaps:2,vortex_v2:[8,5],after:[8,1,2,11],createmutex:10,diagram:1,befor:[8,1,2,11],demonstr:[11,6],attempt:1,third:4,namedmessagedatawriterwrapp:[12,10],receiv:[1,2,12,9,10,11],environ:[4,8,2,7,5],enter:[1,8,2,5,9,11],order:[12,10,1],oper:[8,2,5,9,12,10,11],composit:4,feedback:11,loadadmin:[12,10],over:[12,10],becaus:[12,8],keyboard:2,flexibl:4,getpublisherwrapp:[10,11],fit:2,mydp:1,inadvert:2,publisher_nam:1,hidden:2,length_unlimit:[12,10],them:[8,1,2,11],thei:[9,1,2,11,12],rectangl:11,"break":[12,10],not_read_sample_st:[12,10,11],guardconditionwrapp:12,choic:1,getmyqcwrapp:1,accommod:10,timeout:[9,2],each:[1,2,4,12,9,10,11],complet:[9,2,11],userloadw:[12,10],mean:[4,2,11,6],getinstancestatemask:1,sampleinfoseq:10,extract:[12,10,11],network:[4,11],newli:[9,2,11],content:[1,2,12,9,10,11],navig:[9,8,11],situat:9,free:[9,11,12],standard:[4,11],statusmask:1,ist:3,filter:[9,1,2,11,12],onto:11,independ:[9,2,11],restrict:2,instruct:[0,2],alreadi:[9,10,2,12],messag:[12,10,11],top:[8,2,11,5],stack:10,too:[12,2],similarli:9,listen:[12,10],consol:11,namespac:[10,1,11],tool:[4,0,2,8,5],target:[4,9,1,11,7],provid:[0,1,2,5,4,6,9],tree:[1,2,11,5],getmygcwrapp:1,getdatawrit:[12,10,1,11],seen:2,datareader_ptr:[10,1],minu:2,thorough:11,sleeper:[12,10],transmit:[2,11],getstatusmask:[10,1],even:11,dds_retcode_no_data:[12,10],usernam:[12,10,11],object:[1,2,4,12,9,10,11],preset:7,letter:11,getpublish:[1,11],paradigm:9,readcondition_ptr:10,nameserviceinfoseq:[12,10],doe:[1,2,11,5],dummi:1,declar:[1,11],setqueryparamet:[12,10,1],namedmessageseq:10,getmyreaderwrapp:1,syntax:9,wrapperexcept:[12,10,1],m_statusmask:1,publicationmatchstatu:1,menu:[1,2,5,7,9,11],explain:[1,6],configur:[4,0,1,8,7],retcode_no_data:[12,10],busi:[0,1],dds_retcode_immutable_polici:[12,10],getviewstatemask:1,m_namedmsgread:10,stop:[0,10,1,12],getnamedmessagedatawriterwrapp:10,bar:[7,9,2,11,5],"public":[9,10,1,12],cleanli:1,qosset:[1,2],getreason:12,result:[12,1],respons:[2,11],fail:[12,10,1,11],best:4,subject:3,awar:[4,9,1],databas:9,figur:11,simplest:11,approach:11,attribut:[9,10,2,12],accord:[7,9,1,2],omg:[4,9,1,2,11],extend:[12,1,2],extens:2,toler:[4,11],namedmessagedatareader_ptr:10,fault:[4,11],howev:[1,2,5,7,9,11],against:7,logic:[0,1,2],com:[1,3],"2nd":4,guid:2,assum:[9,5],duplic:[1,2,5],liabil:3,three:[1,2,11],been:[1,8,2,9,12,10,11],trigger:[9,10,1,2,12],interest:[9,1,2],subscrib:10,quickli:[2,6],duration_infinit:[12,10],argument:[12,10,1,5],getnamedmessagedatareaderwrapp:10,child:[2,11],"catch":[12,10],emploi:11,ident:11,servic:[4,9,2,11],air:4,aim:1,calcul:2,multitop:9,pthread_mutex_destroi:10,instancehandle_t:10,sever:1,perform:[4,1,2,11],suggest:11,make:[7,2],complex:4,namefind:[12,10],userhandl:[12,10],hand:[2,11,5],rais:[4,1],domanparticip:9,kept:11,inherit:[1,2,11],pthread_mutex_t:10,wherebi:1,thi:[1,8,5,4,3,9,7,2,10,11,12],endif:[10,1],getnameservicedatawriterwrapp:10,programm:1,jean:3,woburn:3,left:[12,10,2,11,5],set_expression_paramet:10,identifi:[12,10,2,11,6],just:[9,1,2],languag:[1,2,6,9,12,10,11],easi:[4,1],previousid:[12,10],had:[12,11],board:11,els:[12,10],ospl_hom:8,on_offered_incompatible_qo:1,vortexopensplicemodel:8,lite_hom:8,daemon:[7,11,5],specif:[0,1,2,5,4,7,12,10],nameservicedatareaderwrapp:[12,10],manual:[1,2,5,7,9,11],zoom:11,underli:1,www:[2,3],right:[1,2,5,3,12,7,9,10,11],intern:1,interf:11,alive_instance_st:[12,10,11],bottom:[2,11,5],getsubscriberwrapp:10,subclass:1,datawrit:[0,1,2,4,12,10],track:11,condit:[12,10],plu:[8,2,11],messageboardapplicationwrapperimplement:10,getstatuscondit:[12,1],getwaitset:[12,10,1],ccpp_dds_dcp:[10,1],promot:2,peer:11,post:11,plug:2,obj:1,simul:11,produc:[1,2],getnamedmessagefilteredtopicwrapp:10,orsai:3,dds_retcode_inconsistent_polici:[12,10],chatmessagedatawriterwrapp:12,wrap:1,accordingli:2,wai:[9,5,11,6],support:[1,8,4,9,2,11],avail:[4,7,2,3],editor:1,overhead:4,statuscondit:12,form:2,offer:4,adlink:[8,5,4,3,12,10,11],heap:10,pthread_mutex_unlock:10,"true":[12,10,2,11],reset:2,conditionseq:10,datareaderlisten:1,caution:6,"0p1":[8,5],featur:[4,2,11,6],alongsid:2,data_avail:11,terminationreceiv:[12,10],proven:4,exist:[8,10,1,2,9],check:[12,10,1,2,11],assembl:[9,2,6],exported_messageboardapplicationdcp:10,when:[9,1,2,11,5],set_query_paramet:[12,10],"_chatmessagedatareaderlistenerimpl_h_":10,tid:10,privateparticipantwrapp:[12,10],node:11,notif:[9,1,2],intend:[0,2],chatmessagedatawriter_ptr:10,consid:2,sql:[9,2],longer:1,getcondit:[10,1],ignor:[12,10,11],time:[1,2,4,12,9,11],queryparamet:1,getdataread:[12,10,1],chain:[4,2],skip:8,consum:12,focus:11,signific:6,namedmessagedatareaderlistenervar:10,reader_nam:1,hierarch:[4,2],depend:[9,2],thandl:10,readabl:2,ownid:[12,10],namedmessagedatawriter_ptr:10,string:[12,10,1,11],uml:2,word:[9,1,2,11,5],on_requested_deadline_miss:1,brows:[9,1,8,11,5],on_liveliness_lost:1,chatdiagram:11,level:[1,2],chatmessageseqhold:12,item:[5,9,1,2,6],mysubscrib:1,round:4,prevent:2,talker:[12,10,11],corba:11,lazili:1,current:[1,8,4,12,2,9,10,11],userloadappl:12,scada:4,deriv:9,gener:[12,10],satisfi:[9,2],splice:[2,11],along:[2,11],toolbar:9,wait:[9,10,2,12],box:[9,1,2,11,5],shift:2,errorhandl:[12,11],namedmessagefilteredtopicwrapp:[12,10],regardless:9,m_namedmessagewrit:10,extra:2,modul:[0,1,2,9,12,10],prefer:[7,0],visibl:[2,11],marker:2,instal:[0,1],market:4,"__checkstatus_h__":10,memori:[11,5],connector:9,msg:[12,10],scope:[4,1],reorder:2,myread:1,appendic:6,peopl:11,waitset_nam:1,visual:[4,1],graphic:[4,1,2],focu:2,descriptor:2,handle_nil:[12,10],can:[1,8,2,5,7,9,11],on_subscription_match:1,getmyrcwrapp:1,purpos:[4,1,2,11],topic:[0,1,2,4,12,10],application1:1,occur:[12,10,1],alwai:[9,1,2,11],multipl:9,myapplic:1,write:[1,2,12,9,10,11],map:9,product:[4,8,2,6],membership:2,set_query_argu:[12,10],date:[12,10,11],mak:1,data:[12,10],geterrornam:[12,10],practic:4,explicit:10,inform:[0,1,2,3,4,5,12,8,10],"switch":2,guardcondit:[12,10],combin:11,create_querycondit:[12,10],still:[8,2],pointer:[10,1],entiti:[0,1,2,4,12,10],conjunct:9,disconnect:1,monitor:[4,2],polici:1,platform:[1,8,2,5,7,9,10,11],getsamplestatemask:1,mail:3,main:[7,12,10,1,2],non:11,initi:[12,10,1,11],now:[9,1,11],nor:11,introduct:0,down:[1,2,11],term:11,name:[1,2,5,9,12,10,11],drop:[1,2,11],zoomabl:2,separ:[9,2,11],januari:[12,10],updat:11,domain:[4,9,2,11,5],messageboardapplicationwrapp:[12,10],individu:[4,9,2,11],continu:[1,8,11],dispos:[12,10],shown:[8,5,2,11,6],space:[1,11],getqueryconditionwrapp:10,profil:4,factori:2,integr:[4,2],contain:[1,2,3,6,7,9,10,11,12],prevcount:[12,10],argv:10,org:2,argc:10,m_nameserviceread:10,synchron:[9,2,12],turn:[1,2,11],place:[1,2,11],frequent:1,first:[8,1,2,11],origin:[9,1],directli:[1,2,11],onc:[1,2],arrai:[12,10],adlink_licens:8,interruptedexcept:12,fast:[12,10],open:[8,2,5,9,12,10,11],size:[2,11],given:[8,2,6,9,12,10,11],breviti:[9,11],convent:[0,1],necessarili:2,waitset:[12,10],conveni:[5,2,6],getnameservicedatareaderwrapp:10,copi:8,retcodenam:[12,10],specifi:[12,8,10,2,9],getguardconditionwrapp:10,pragma:11,than:[9,2,11],serv:1,wide:4,vcproj:1,pre:[12,10,1,11],ani:[1,8,2,9,12,10,11],sampleinfoseqhold:12,engin:[4,2],techniqu:[4,2],note:[1,8,9,7,2,11],take:[12,10,1],advis:2,noth:1,statuscondt:[1,2],begin:11,ulong:10,normal:[8,2],buffer:10,namedmessagedatareaderlisten:[12,10,11],icon:[9,5,2,11,6],later:[12,10],drive:11,runtim:1,parseint:12,querycondition_ptr:10,show:[2,11],on_offered_deadline_miss:1,permiss:8,estop:12,corner:[2,11],"_module1_application1_listener1_h_":1,xml:4,onli:[1,2,5,6,12,9,11],explicitli:12,chatapp:11,activ:[12,10,11],state:[9,1,2,11],pthread_mutex_init:10,requestedincompatibleqosstatu:1,dword:10,numberstr:10,variou:[4,2],get:[1,8,11,5],tailor:4,take_w_condit:[12,10],requir:[1,8,2,4,5,12,7,9,10,11],reveal:[2,11],lite_uri:8,dramat:4,infoseq2:[12,10],namedmsgseq:[12,10],where:[1,8,5,4,6,2,9,11],data_available_statu:1,deadlin:2,reserv:[12,10,11,3],concern:2,infinit:10,dds_retcode_not_en:[12,10],userloadapplicationwrapp:12,label:9,enough:1,between:[1,2,4,9,10,11],"import":[12,1],across:11,parent:[9,2],screen:[8,2,11],typedef:11,cycl:12,dds_retcode_timeout:[12,10],come:7,dds_retcode_bad_paramet:[12,10],chatter1:11,audienc:0,tutori:[12,0,10,2,6],improv:2,chatmessag:[12,10,11],unistd:10,pop:[9,2,11],getdomainparticip:1,getchatmessagedatareaderwrapp:10,leftus:[12,10],rebuilt:11,"abstract":[1,11],get_liveliness_changed_statu:[12,10],ostringstream:10,wake:[9,2],workspac:[8,1,2,11],those:[9,2],"case":1,wrapperimplement:1,tostr:12,string_dup:10,hde:[1,8,11,5],cannot:[1,2],datawriter_nam:1,advantag:6,ctrl:11,destin:[9,11],readcondt:2,myapp:1,pthread:10,develop:[4,8,1,2,11],copy_from_topic_qo:2,same:[9,1,2,11],trip:4,html:8,exprparam:10,lite:[7,1,8],document:[3,6],status:[9,1,2],topicdescript:[0,2],namefinderexpr:12,finish:[1,2,12,9,10,11],getviewstatemak:1,nest:1,driven:[4,2],extern:5,appropri:[9,1,2,11],nameservic:[12,10,11],without:[8,9,2,11,3],model:[7,12,10,1],execut:[8,5,12,7,9,10,11],module1:1,readconditionwrapp:12,struct:[9,1,11],hint:6,returncod:[12,10],param:12,identif:11,offeredincompatibleqosstatu:1,any_instance_st:[12,10,11],real:[4,9,2,11],read:[9,10,2,11,12],adlinktech:3,test:0,traffic:4,nameserviceread:12,queryexpress:1,retcode_ok:[12,10],integ:12,benefit:6,either:[1,2,5,12,7,9,10],output:0,manag:[4,10,1,2],myparticip:1,constitut:[2,11],new_view_st:11,definit:[2,4,12,9,10,11],getguardcondit:[12,1],exit:[12,10,11],refer:[1,8,2,5,9,11],on_sample_reject:1,arrow:11,sampleloststatu:1,garbag:1,termination_messag:[12,10],fulli:[1,2],vcxproj:1,"throw":1,querycondit:[12,10],src:[1,11],central:11,side:[2,11,5],degre:11,stand:2,ospl:0,act:1,adlinktech_usa:3,processor:1,effici:11,liveli:[12,10],opensplic:[7,12,10,1,3],unregist:[12,10],mark:[7,2],your:[1,8,5,7,2,11],messageboardappl:12,getreadconditionwrapp:10,log:11,area:[4,9,2,11],vallei:3,overwrit:[1,2],start:[0,1,2,12,8,10],compliant:[1,2,11,6],interfac:[8,1,2,11,9],low:[4,2],strictli:11,strict:2,getparticipantwrapp:[10,11],regard:[4,9],amongst:11,delayedescap:10,categor:2,possibl:9,"default":1,dds_retcode_out_of_resourc:[12,10],connect:[4,0,1,2],set_trigger_valu:[12,10],creat:[7,12,10,1],certain:[8,2,9],strongli:2,file:[1,8,2,5,12,7,9,10,11],dcpssaj:11,again:[12,10,2,11],setexpressionparamet:[12,10],inconsistenttopicstatu:1,field:[1,8,5,9,12,10,11],cleanup:[12,10],pathnam:[9,11,5],you:[1,8,12,7,2,10,11],waitset_ptr:10,architectur:[2,11],finali:6,symbol:[9,2,11],nameservicedatawrit:[12,10,11],chatmessagedatareaderwaitset:12,reduc:[4,2],nslist:[12,10],directori:[8,1,2,11],mask:[9,1,2,11],escap:[12,10],cpu:12,unset:12,represent:2,all:[1,8,5,4,3,9,7,2,10,11,12],istringstream:10,illustr:[9,2,11],partitionnam:1,concept:4,follow:[1,8,2,4,6,12,9,10,11],children:1,chatmessagedatareaderlisten:[12,10,11],program:[12,9,10,11,5],introduc:2,global:2,fals:[12,10,1],util:[7,11],mechan:2,mysc:1,list:[12,10,1,2,11],participantwrapp:[12,10],entity_nam:[1,11],small:11,chatmessageseq:10,tei:10,tel:3,getuserloadwaitsetwrapp:10,userloadwaitset:11,pass:1,further:9,what:[10,1,2,6],sub:[8,11],sun:4,section:[1,2,5,6,7,9,11],abl:[8,1,2,9],invok:[7,1],delet:[10,1],nexrt:11,method:[7,9,1,2,11],prismtech:1,full:[9,5],domainparticp:11,newmessag:[12,10],chatmessage_top:11,qospolici:2,behaviour:[1,11],solari:6,rudimentari:11,modifi:[9,2],valu:[7,12,1],search:0,amount:12,getprivateparticipantwrapp:10,pick:2,action:2,myrc:1,via:1,depart:[12,10,11],primit:9,filenam:[1,8],establish:11,select:[1,8,2,5,7,9,11],samplerejectedstatu:1,regist:[12,10,1],two:[9,10,11,6],autonom:11,taken:6,more:[1,8,2,5,9,12,10,11],desir:[9,1,2,11,5],namedmessag:[12,10,11],flag:[12,10],particular:[9,2,11],known:[12,10],compani:3,jdk:4,outlin:[2,11,6],histori:[12,10,11],remain:11,"0ul":10,prompt:8,share:[11,5],accept:[4,1,11],namedmessagefilteredtop:11,explor:[8,1,2,11,9],rather:[2,11],anoth:[9,2],settermin:[12,10],simpl:[2,11],resourc:[2,6,9,12,10,11],compulsori:2,reflect:[9,1],exisit:1,associ:[9,1,2,11],"short":11,postfix:1,confus:11,caus:2,callback:1,help:[2,6],waitforsingleobject:10,held:1,through:[8,1,2,11,9],hierarchi:1,paramet:[12,1],style:2,condition_nam:1,alter:[2,11],good:3,"return":[12,10,1,2],on_liveliness_chang:1,framework:4,getmyscwrapp:1,on_data_on_read:1,getmywaitsetwrapp:1,num_msg:[12,10],detach:[12,10,1],userid:[12,10,11],unlik:9,easili:2,achiev:[1,11],compris:4,found:[12,10],addpublish:1,chatmessagedatareaderwrapp:[12,10],publisher1wrapp:1,expect:7,on_inconsistent_top:1,event:1,namedmessagedatareaderwrapp:[12,10],publish:10,footnot:[8,1,2,11,9],publisherwrapp:[12,10],print:[12,10,11],returncode_t:10,occurr:2,difficulti:9,m_namefinderparam:10,team:3,like:[9,1,2],reason:2,base:[1,8,2,4,6,9,11],put:10,thrown:1,prefac:0,thread:[9,10,2,12],launch:0,participant1:1,perman:2,assign:[9,1,2,11],checkstatu:12,guardcondition_ptr:10,number:[1,8,2,9,12,10,11],done:[2,11],construct:11,livelinesschangedstatushold:12,miss:2,myapplicationwrapp:1,differ:[8,10,2,9],printstacktrac:12,interact:11,least:[12,10],dds_retcode_ok:[12,10],statement:1,scheme:9,option:[1,2,12,7,9,10,11],relationship:[2,11],getmywriterwrapp:1,part:[9,2,11,3],std:10,kind:11,whenev:9,remov:[12,10,1],architect:2,str:10,arrang:2,grei:9,comput:2,packag:[4,12,1,2,11],expir:[9,2],dedic:9,"null":[12,10,1],built:11,equival:2,myappdpwrapp:11,violat:2,also:[1,8,2,4,6,7,9,10,11],build:[7,8,2,11],distribut:[4,8,2,11,9],previou:11,most:[1,2],appear:[1,2,5,9,12,10,11],register_inst:[12,10],clear:[2,11],cover:11,clean:[8,11],find:[9,10,1,2,12],copyright:[12,10,11,3],setnam:1,on_publication_match:1,palett:[4,9,2,11],express:[9,1,2,11,12],nativ:[7,9,1,8],restart:8,chatmsgseq:[12,10],common:2,userloadapplicationwrapperimplement:10,set:[7,12,10,1],see:[7,9,2,11,5],sec:10,on_requested_incompatible_qo:1,arg:[12,10],close:[1,2,5,12,10,11],m_newmessag:10,particip:[9,10,1,11],invalid_handle_valu:10,subscript:[9,2],altern:[9,1,2],rostand:3,distinguish:[4,2],removepublish:1,popul:2,both:[4,9,1,2,11],last:9,delimit:11,alon:2,context:[4,9,2,11],whole:[1,2,3],load:[2,11],nametyp:11,simpli:[7,9,1,2],m_istermin:10,point:[8,11],instanti:[1,11],status_mask:1,except:[12,10,1,8,11],header:[10,1,11],shutdown:1,read_w_condit:[12,10],livchangstatu:10,devic:[8,5],empti:[9,1,2],accessor:1,myadddp:1,nameserv:[12,10],look:[12,10],solid:11,contentfilteredtop:[0,1,2],"while":[12,10,1,2],match:2,abov:[8,1,2,11,5],gateshead:3,readi:1,centr:2,herein:9,itself:[1,11],demot:2,"_local_is_a":1,shorten:4,conflict:[1,2],higher:2,x86:5,any_view_st:[12,10,11],wherea:1,alert:2,chatterapplicationwrapperimplement:[10,11],user:[1,8,2,6,9,12,10,11],m_chatmsgread:10,robust:4,implement:[0,1,2,9,12,10],lower:[2,11],task:[2,11],entri:[9,11],guardlist:[12,10],explan:2,cout:10,shape:2,cut:11,readcondit:[12,10],shortcut:11,mywrit:1,notifi:9,subsequ:[9,1,11],m_messageboardappl:10,bin:[8,5],vendor:4,transpar:11,formal:9,resolv:2,collect:[1,2],princip:1,"boolean":[9,1,2,12],encount:1,simplifi:[1,11],acknowledg:3,creation:[12,10,1,11],some:[12,10],back:[1,11],sampl:[1,2,12,9,10,11],max_nam:11,namedmessagewrit:12,return_loan:[12,10],releasemutex:10,namedmsgread:12,larg:[2,11],slash:11,reproduc:3,machin:8,run:[12,10,1],rue:3,step:[0,1,2,5,4,9,8],prerequisit:8,faith:3,idl:[4,0,1,2],dialog:[9,1,2,11,5],block:[9,2],myqc:1,on_sample_lost:1,within:[9,1,2,11,5],chatmessagedatareader_ptr:10,ensur:[4,8,2,11,9],chang:[12,10,1,3],durabl:[4,11],msglist:[12,10],offereddeadlinemissedstatu:1,"long":[12,10,11],custom:2,adjac:[9,2,11],includ:[1,8,5,4,6,12,2,9,10,11],suit:[4,3,2,6],forward:11,link:[8,2,11],vortexlit:8,line:[8,11],m_mutex:10,info:[12,10],consist:[9,2,11],similar:[9,11],dds_retcode_precondition_not_met:[12,10],constant:1,repres:[9,1,2,11],"char":[10,1],chat:[0,10,12],stringseq:10,vortexmodel:8,unregister_inst:[12,10],m_usernam:10,myapplicationwrapperimplement:1,invalid:[12,10],librari:11,namedmsg:[12,10],drag:[9,2,11],lang:11,getreadcondit:[12,1],algorithm:2,confirm:11,dataread:[0,1,2,4,12,10],depth:11,"transient":11,scroll:2,edg:3,queri:[12,10,11],pthread_mutex_lock:10,chatterapplicationwrapp:[12,11],privat:[12,10,1],sensit:2,wizard:[9,2,11],send:[12,10,11],esc:2,userloadwaitsetwrapp:12,ist_info:3,sent:[12,10,11],mous:[2,11],facebook:3,untouch:8,implicitli:[12,10],relev:[1,2,11,6],dds_retcode_unsupport:[12,10],button:[1,8,2,5,9,11],"try":[12,10],create_particip:1,pleas:[1,8,11,5],datareaderlistener_var:10,uniqu:[2,11],click:[1,8,2,5,7,9,11],compat:2,index:[12,10,8,11],closehandl:10,compar:2,pthread_creat:10,access:[1,2,11],perimet:11,winapi:10,bodi:11,ubuntu:6,"0xa":3,becom:[9,2],sinc:[9,10,2,12],convert:9,larger:11,technolog:[12,10,11,3],cerr:10,typic:8,appli:[1,2,5,6,12,10],app:8,api:1,mypublish:1,from:[1,8,2,4,5,12,7,9,10,11],usa:3,commun:[9,1,2,11],doubl:[8,2,11],seamless:8,next:[9,2,11,6],panel:[1,2],namedmessagedatawrit:[12,10,11],about:[0,9,2,8,5],publisher1wrapperimplement:1,folder:[8,1,2,11,9],retriev:[1,11],scalabl:[4,11],control:[1,2,5,4,6,9,11],"_namedmessagedatareaderlistenerimpl_h_":10,process:[8,2,11],lock:8,high:4,tab:[7,2,11,5],writer_nam:1,six:2,chatternam:[12,10],subdirectori:8,instead:[12,10,5],ne11:3,overridden:1,dds_retcode_already_delet:[12,10],alloc:[12,10],essenti:4,bind:9,correspond:[12,10,1],element:2,allow:[9,1,2,11],getsubscrib:1,ospl_uri:8,move:[2,11],whilst:1,own:[9,1,2,11],superior:4,chosen:[1,2],therefor:[1,11],chatmessagedatareaderlistenervar:10,subscriptionmatchedstatu:1,handl:[12,10],auto:[1,11],overal:4,handi:7,facilit:4,chatmsgread:12,anyth:11,edit:[7,1],nameserviceseq:[12,10],subset:[9,2],meta:4,"static":[12,10,1,11],our:10,out:[9,2,11,12],variabl:[7,8,5],string_mgr:10,defenc:4,ret:10,franc:3,shut:[1,11],chatmessagedataread:[12,10,11],insid:[9,11],createthread:10,nameservicedataread:[12,10,11],statusconditionwrapp:12,delete_readcondit:[12,10],releas:[1,8,4,12,2,9,10,11],getquerycondit:[12,1],complianc:4,livelinessloststatu:1,unwant:2,could:5,lpvoid:10,keep:11,length:[12,10],organis:[0,2],outsid:2,retain:11,softwar:[4,8,2],m_namefind:10,suffix:1,qualiti:[4,2],mai:[9,2,3],owner:[12,10,2,11],facil:[7,2],prioriti:2,newus:[12,10],unknown:12,licens:8,system:[8,5,4,2,6,12,9,10,11],wrapper:[1,11],listener1:1,attach:[9,10,1,2,12],namefinderparam:12,termin:[12,10,11],"final":[12,1,2,11],nameservicedatawriter_ptr:10,getchatmessagedatawriterwrapp:10,exactli:[1,2],nameservicedatareader_ptr:10,structur:[2,11],light:11,getmysubscriberwrapp:1,viewer:2,clearli:4,have:[1,8,12,7,2,9,10,11],tabl:2,need:[1,2,6,7,9,11],nameserviceseqhold:12,create_readcondit:[12,10],liveliness_changed_st:11,preced:2,which:[1,8,5,2,6,7,9,11],singl:[4,9,1,2,11],unless:2,deploy:[4,7,2,11,5],who:11,deploi:4,"class":[1,2,12,9,10,11],subscriber_nam:1,request:[9,2],determin:[9,2],conditionseqhold:12,text:[9,1,2,11,5],mywaitset:1,namedmessageseqhold:12,chatmessagedatawrit:[12,10,11],locat:[1,8,2,5,9,11],jar:11,should:[1,8,2,5,9,12,11],combo:2,local:[7,2,11],familiar:2,increas:4,subscriptionmatchstatu:1,enabl:[1,8,2,5,7,9,11],upper:[2,11],she:11,ascertain:2,tuner:[4,11],view:[1,8,2,5,9,11],conform:4,workbench:7,publisher1:[1,11],project_nam:1,statu:[1,2,12,9,10,11],correctli:[2,11],pattern:4,datawriterswrapp:1,written:[9,10,2,11,12],setdefaultstatusmask:1,thumbnail:2,kei:[9,10,2,11,12],group:4,endl:10,addit:[1,2,5,7,9,11],plugin:8,equal:12,etc:[8,2],instanc:[1,2,12,9,10,11],comment:1,arriv:[9,2],chmod:8,walk:[12,10],"_var":1,respect:[9,2,11],sarl:3,addition:[7,1],queryconditionwrapp:12,trademark:3,compos:2,compon:1,besid:11,assert:[12,10],togeth:2,present:1,multi:[2,11],rectangular:11,cursor:11,defin:[1,8,4,9,2,10,11],"5th":3,linkedin:3,incom:2,member:[9,1],subscriberwrapp:[12,10],ifndef:[10,1],mypublisherwrapp:11,http:[2,3],expans:[2,11],repositryid:1,upon:1,effect:[12,10],canva:[9,2,11],expand:[9,1,2,11],off:11,nameservice_top:11,builder:7,well:[4,9,2,11],getmydpwrapp:1,command:[8,5],choos:[1,8,2,5,7,9,11],namedmessagedataread:[12,10,11],less:1,domainparticipantlisten:1,obtain:[8,10,1,2,12],chatmsginfoseq:[12,10],web:3,any_sample_st:[12,10,11],makefil:1,add:[8,1,2,11,9],valid:[12,10],statuscondition_ptr:10,smart:10,checkhandl:[12,10],realiz:4,know:1,press:2,getmypublisherwrapp:1,tick:7,recurs:2,insert:1,myhomedir:8,lost:[12,10],corpor:3,sstream:10,vortex:[7,12,10,1],necessari:8,lose:8,resiz:11,vortexopensplic:[8,5],twitter:3,suppli:4,home:[8,11],transport:11,win32:5,trust:4,leak:10,avoid:1,outgo:2,leav:[12,10,8,11],speak:11,getnam:1,"enum":1,host:[8,11,5],although:[1,11],dcp:[9,1,8,11],stage:4,c_str:10,actual:[4,9,2],requesteddeadlinemissedstatu:1,column:9,lifecycl:[4,1],disabl:[9,1,11],set_listen:10,artefact:1,livelinesschangedstatu:[10,1],automat:[7,9,1,2,11],guard:[12,10],privateparticip:[10,11],merg:[12,10,1,2],much:12,replac:[11,5],"function":[1,2,12,9,10,11],namedmessage_top:11,getstatusconditionwrapp:10,basic:[2,11,6],gain:1,uninstal:0,eas:4,buf:10,made:[9,2,11,3],whether:[9,10,1,12],wish:[1,11],displai:[1,2,12,7,9,10,11],asynchron:[9,2],below:[1,8,2,6,9,11],logical_nam:[12,10,11],limit:[12,10,11,3],otherwis:[7,1],problem:[9,2],"int":[12,10,1],dure:8,mutual:2,guidanc:4,detail:[1,2,5,6,9,11],virtual:[10,1],other:[1,8,4,12,2,9,10,11],bool:10,futur:[4,1,2],rememb:11,repeat:[11,5],june:11,singleus:[12,10],reliabl:11,rule:2,istermin:[12,10]},objtypes:{},objnames:{},filenames:["index","codegeneration","described","contacts","introduction","launchconfig","preface","compileandrun","installation","modeling","appendixb","tutorial","appendixa"],titles:["Modeling Guide","6. Code Generation","4. Modeler Described","12. Contacts & Notices","2. Introduction","7. Creating Launch Configurations","1. Preface","8. Compiling and Running","3. Installation","5. Modeling","11. Appendix B","9. Tutorial","10. Appendix A"],objects:{},titleterms:{code:[12,10,1,11],chatmessagedatareaderlistenerimpl:[12,10],domainparticip:[9,1],entiti:9,polici:[2,11],writer:1,window:10,busi:11,save:1,applic:[9,10,1,11,12],sourc:[12,10,11],handl:1,stop:5,condit:[9,1],introduct:4,specif:9,edit:2,gui:2,provid:11,vortex:[8,2],partit:[9,1,11],output:11,page:2,compil:[7,11],workbench:2,set:[8,2,11],"export":1,result:2,special:2,publish:[9,1],datawrit:9,delet:2,version:10,userloadappl:10,reader:1,"import":2,run:[7,11,5],gener:[1,8,11],step:11,eclips:[1,2],valu:[2,11],querycondit:[9,1],prefac:6,about:6,launch:5,idl:9,tutori:11,organis:6,ospl:5,logic:11,chang:2,configur:5,checkstatu:10,opensplic:[8,2],overview:[2,11],modul:11,prefer:8,instruct:8,linux:10,instal:8,guid:[0,6],messageboardappl:10,java:[7,12,1,11],describ:2,convent:6,compon:[9,2],start:5,handler:12,editor:2,subscrib:[9,1],waitset:[9,1],type:9,statuscondit:[9,1],listen:[9,1],userload:[12,10],tool:9,messageboard:[12,10],notic:3,appendix:[12,10],uninstal:8,chatter:[12,10],"default":2,contentfilteredtop:9,remov:2,properti:2,project:[1,2,11],error:[12,1],design:2,connect:9,creat:[2,11,5],descript:2,chatterappl:10,indic:0,topic:[9,11],namedmessagedatareaderlistenerimpl:[12,10],chat:11,tabl:0,topicdescript:9,audienc:6,contact:3,readcondit:[9,1],guardcondit:1,chatroom:[12,10,11],test:11,perspect:2,intend:6,diagram:2,data:1,implement:11,renam:2,dataread:9,inform:[9,11],exampl:[12,10,11],cpp:10,model:[0,9,2,11,6],order:2}}) \ No newline at end of file diff --git a/docs/html/ModelingGuide/tutorial.html b/docs/html/ModelingGuide/tutorial.html index 3329fb281..93723b89c 100644 --- a/docs/html/ModelingGuide/tutorial.html +++ b/docs/html/ModelingGuide/tutorial.html @@ -357,8 +357,8 @@

    9.2.2. Step 2: Provide an Information Model
    /*****************************************************************
      *
    - * Copyright (c) 2006 to 2016
    - * PrismTech Ltd.
    + * Copyright (c) 2006 to 2018
    + * ADLINK Technology Limited
      * All rights Reserved.
      *
      * LOGICAL_NAME:    Chat.idl
    @@ -1253,7 +1253,7 @@ 

    Navigation

    \ No newline at end of file diff --git a/docs/html/NodeJSDCPSAPIGuide/_images/dds_overview.png b/docs/html/NodeJSDCPSAPIGuide/_images/dds_overview.png new file mode 100644 index 000000000..c7490ddb4 Binary files /dev/null and b/docs/html/NodeJSDCPSAPIGuide/_images/dds_overview.png differ diff --git a/docs/html/NodeJSDCPSAPIGuide/_sources/contacts.txt b/docs/html/NodeJSDCPSAPIGuide/_sources/contacts.txt new file mode 100644 index 000000000..d32f6016f --- /dev/null +++ b/docs/html/NodeJSDCPSAPIGuide/_sources/contacts.txt @@ -0,0 +1 @@ +.. include:: ../../common/contacts.rst diff --git a/docs/html/NodeJSDCPSAPIGuide/_sources/dds_entities.txt b/docs/html/NodeJSDCPSAPIGuide/_sources/dds_entities.txt new file mode 100644 index 000000000..d1c636416 --- /dev/null +++ b/docs/html/NodeJSDCPSAPIGuide/_sources/dds_entities.txt @@ -0,0 +1,622 @@ +.. _`Node.js API for Vortex DDS`: + +########################## +Node.js API for Vortex DDS +########################## + +The Node.js DCPS API provides users with Node.js classes to model DDS communication using JavaScript and pure +DDS applications. + +The Node.js DCPS API consists of one module. + +* vortexdds + +This section provides an overview of the main DDS concepts and Node.js API examples for these DDS concepts. + +.. note:: + + - The Node.js DCPS API documentation can be found in the following directory: + + *$OSPL_HOME/docs/nodejs/html* + + +API Usage Patterns +****************** + +The typical usage pattern for the Node.js DCPS API for Vortex DDS is the following: + +* Model your DDS topics using IDL and generate Node.js topic classes from IDL. +* AND/OR generate Node.js topic classes for topics that already exist in the DDS system. +* Start writing your Node.js program using the Node.js API for Vortex DDS. + +The core classes are ``Participant``, ``Topic``, ``Reader`` and ``Writer``. +``Publisher`` and ``Subscriber`` classes can be used to adjust the Quality of Service (QoS) defaults. + +For details on setting QoS values with the API, see :ref:`QoS Provider`. + +The following list shows the sequence in which you would use the Vortex classes: + +* Create a ``Participant`` instance. +* Create one or more ``Topic`` instances. +* If you require publisher or subscriber level non-default QoS settings, create ``Publisher`` and/or ``Subscriber`` instances. (The most common reason for changing publisher/subscriber QoS is to define non-default partitions.) +* Create ``Reader`` and/or ``Writer`` classes using the ``Topic`` instances that you created. +* If you required data filtering, create ``QueryCondition`` objects. +* Create the core of program, writing and/or reading data and processing it. + + +Participant +*********** + +The Node.js ``Participant`` class represents a DDS domain participant entity. + +In DDS - “A domain participant represents the local membership of the application in a domain. A domain is a distributed concept that links all the applications able to communicate with each other. It represents a communication plane: only the publishers and subscribers attached to the same domain may interact.†+ +Parameters: + +* {number} domainId 0 <= domainId <= 230 (Default: DDSConstants.DDS_DOMAIN_DEFAULT) +* {QoS} qos (Default: undefined) +* {object} listener (Default: undefined) + +The optional parameters have defaults if not specified. If the qos is undefined, the OSPL default QoS is used. + + +**Examples** + +Create a Vortex DDS domain participant. Returns participant or throws a ``DDSError`` if the participant cannot be created. + +Create a domain participant in the default DDS domain (the one specified by the OSPL_URI environment variable). + +.. code-block:: javascript + + const dds = require('vortexdds'); + + // create domain participant + const participant = new dds.Participant(); + +Create a participant on the default domain with a QoS profile. Consider the code snippet below taken from example: GetSetQoSExample/GetSetQoSExample.js file. + +.. code-block:: javascript + + const QOS_PATH = 'DDS_Get_Set_QoS.xml'; + const QOS_PROFILE = 'DDS GetSetQosProfile'; + const DOMAIN_ID = dds.DDS_DOMAIN_DEFAULT; + + async function main(){ + + // create a qos provider using qos xml file + let qp = new dds.QoSProvider(QOS_PATH, QOS_PROFILE); + + // get participant qos from qos provider + let pqos = qp.getParticipantQos(); + let participant = new dds.Participant(DOMAIN_ID, pqos); + + } + +.. _Topic: + +Topic +***** + +The Node.js ``Topic`` class represents a DDS topic type. The DDS topic corresponds to a single data type. In DDS, data is distributed by publishing and subscribing topic data samples. + +Javascript ``Topic`` instances can be created using an IDL file. + +**Step 1 - Generate TypeSupport objects from IDL file** + +The function ``getTopicTypeSupportsForIDL(idlPath)`` is provided to generate a ``TypeSupport`` instance for every topic defined in an IDL file. This function returns a promise, therefore should be called from an async function. + +**Step 2 - Create Topic instance using TypeSupport** + +The ``createTopicFor`` method in the ``Participant`` class can then be used to create a topic instance. + +.. code-block:: javascript + + /** + * Create a Topic on this participant given a TypeSupport object. + * @param {string} topicName + * @param {TypeSupport} typeSupport + * @param {QoS} QoS (default undefined) + * @param {object} listener (default undefined) + * @returns {Topic} topic instance + */ + createTopicFor( + topicName, + typeSupport, + qos = null, + listener = null + ) { + + + + +**Example** + +Create a Vortex DDS topic named 'HelloWorldData_Msg' based on the DDS Topic type ``Msg`` from the ``HelloWorldData.idl`` file. This topic is created using the getTopicTypeSupportsForIDL function, and the ``Participant`` createTopicFor method. + +Consider the code snippet below taken from example: HelloWorld/HelloWorldTopic.js file. + +.. code-block:: javascript + + const dds = require('vortexdds'); + const path = require('path'); + + module.exports.create = async function(participant) { + + const topicName = 'HelloWorldData_Msg'; + const idlName = 'HelloWorldData.idl'; + const idlPath = path.resolve(idlName); + + //wait for dds.getTopicTypeSupportsForIDL to return a Map of typeSupports + let typeSupports = await dds.getTopicTypeSupportsForIDL(idlPath); + + //HelloWorldData.idl contains 1 topic + let typeSupport = typeSupports.get('HelloWorldData::Msg'); + + //create topic qos + let tqos = dds.QoS.topicDefault(); + tqos.durability = dds.DurabilityKind.Transient; + tqos.reliability = dds.ReliabilityKind.Reliable; + + //create topic + return participant.createTopicFor(topicName, typeSupport, tqos); + + }; + + +Publisher +********* + +The Node.js ``Publisher`` class represents a DDS publisher entity. + +In DDS, a publisher is “an object responsible for data distribution. It may publish data of different data types.†+ +Use of the ``Publisher`` class is optional. +In its place, you can use a ``Participant`` instance. +Reasons for explicitly creating a ``Publisher`` instance are: + +* to specify non-default QoS settings, including specifying the DDS *partition* upon which samples are written. +* to control the timing of publisher creation and deletion. + +**Examples** + +Create a DDS Publisher entity. Returns publisher or throws a ``DDSError`` if the publisher cannot be created. + +Create a publisher with participant. + +.. code-block:: javascript + + const dds = require('vortexdds'); + + //create participant + const participant = new dds.Participant(); + + //create publisher + const pub = participant.createPublisher(); + +Create a publisher with a participant and QoS profile. Consider the code snippet below taken from example: GetSetQoSExample/GetSetQoSExample.js file. + +.. code-block:: javascript + + const QOS_PATH = 'DDS_Get_Set_QoS.xml'; + const QOS_PROFILE = 'DDS GetSetQosProfile'; + const DOMAIN_ID = dds.DDS_DOMAIN_DEFAULT; + + async function main(){ + + // create a qos provider using qos xml file + let qp = new dds.QoSProvider(QOS_PATH, QOS_PROFILE); + + // get participant qos from qos provider + let pqos = qp.getParticipantQos(); + let participant = new dds.Participant(DOMAIN_ID, pqos); + + // get publisher qos from qos provider and create a publisher + let pubqos = qp.getPublisherQos(); + let publisher = new dds.Publisher(participant, pubqos); + } + +Writer +****** + +The Node.js ``Writer`` class represents a DDS data writer entity. + +In DDS - “The writer is the object the application must use to communicate to a publisher the existence and value of data-objects of a given type.†+ +A ``Writer`` class is required in order to write data to a DDS domain. +It is attached to a DDS publisher or a DDS domain participant. + +A ``Writer`` class instance references an existing ``Topic`` instance. + +**Examples** + +Create a Vortex DDS domain writer and write data. Returns writer or throws a ``DDSError`` if the writer cannot be created. The example below uses the 'HelloWorldData_Msg' topic from the 'HelloWorldTopic.js' file as shown in :ref:`Topic` example. Consider the code snippet below taken from example: HelloWorld/HelloWorldPublisher.js file. + +.. code-block:: javascript + + const dds = require('vortexdds'); + const HelloWorldTopic = require('./HelloWorldTopic'); + + main(); + + async function main(){ + + //create domain participant + let participant = new dds.Participant(); + + //wait for topic to be created + let topic = await HelloWorldTopic.create(participant); + + //create a publisher with publisher QoS + let pqos = dds.QoS.publisherDefault(); + pqos.partition = 'HelloWorld example'; + let pub = participant.createPublisher(pqos, null); + + //create a writer with writer QoS + let wqos = dds.QoS.writerDefault(); + wqos.durability = dds.DurabilityKind.Transient; + wqos.reliability = dds.ReliabilityKind.Reliable; + let writer = pub.createWriter(topic, wqos, null); + + //write one sample + let msg = {userID: 1, message: 'Hello World'}; + + console.log('=== HelloWorldPublisher'); + console.log('=== [Publisher] writing a message containing :'); + console.log(' userID : ' + msg.userID); + console.log(' Message : ' + msg.message); + + writer.write(msg); + + } + + +Subscriber +********** + +The Node.js ``Subscriber`` class represents a DDS subscriber entity. + +In DDS, a subscriber is “an object responsible for receiving published data and making it available to the receiving application. It may receive and dispatch data of different specified types.†+ +Use of the ``Subscriber`` class is optional. +In its place, you can use a ``Participant`` instance. +Reasons for explicitly creating a ``Subscriber`` instance are: + +* to specify non-default QoS settings, including specifying the DDS *partition* upon which samples are written. +* to control the timing of subscriber creation and deletion. + +**Examples** + + +Create a Vortex DDS domain subscriber. Returns subscriber or throw a ``DDSError`` if the subscriber cannot be created. + + +Create a subscriber with participant. + +.. code-block:: javascript + + const dds = require('vortexdds'); + + //create participant + consr participant = new dds.Participant(); + + //create Subscriber + const sub = participant.createSubscriber(); + +Create a subscriber with participant and QoS profile, where the DDS_DefaultQoS_All.xml file is located in the project directory. + +.. code-block:: javascript + + const QOS_PATH = 'DDS_Get_Set_QoS.xml'; + const QOS_PROFILE = 'DDS GetSetQosProfile'; + const DOMAIN_ID = dds.DDS_DOMAIN_DEFAULT; + + async function main(){ + + // create a qos provider using qos xml file + let qp = new dds.QoSProvider(QOS_PATH, QOS_PROFILE); + + // get participant qos from qos provider + let pqos = qp.getParticipantQos(); + let participant = new dds.Participant(DOMAIN_ID, pqos); + + /* + Get subscriber qos from qos provider and create a subscriber + In the qos xml file provided with this example, there are + two subscriber qos. The subscriber qos with + id 'subscriber1' is chosen below + + NOTE: If there are more than one qos entries in the xml file + for a dds entity, then the entity qos id must be specified. + Otherwise an error will be thrown while trying to get the + respective entity qos from the qos provider + */ + let subqos = qp.getSubscriberQos('subscriber1'); + let subscriber = new dds.Subscriber(participant, subqos); + } + + +Reader +****** + +The Node.js ``Reader`` class represents a DDS data reader entity. + +In DDS - “To access the received data, the application must use a typed reader attached to the subscriber.†+ +A ``Reader`` class is required in order to write data to a DDS domain. +It is attached to a DDS subscriber or a DDS participant. + +A ``Reader`` class instance references an existing ``Topic`` instance. + +**Examples** + +Create a Vortex DDS domain reader with a subscriber and read/take data. Returns reader or throw a ``DDSError`` instance if the reader cannot be created. Consider the code snippet below taken from example: HelloWorld/HelloWorldSubscriber.js file. + +.. code-block:: javascript + + const dds = require('vortexdds'); + const HelloWorldTopic = require('./HelloWorldTopic'); + + main(); + + async function main(){ + + //create domain participant + let participant = new dds.Participant(); + + //wait for topic to be created + let topic = await HelloWorldTopic.create(participant); + + //create subscriber with subscriber QoS + let sqos = dds.QoS.subscriberDefault(); + sqos.partition = 'HelloWorld example'; + let sub = participant.createSubscriber(sqos, null); + + //create reader with reader QoS + let rqos = dds.QoS.readerDefault(); + rqos.durability = dds.DurabilityKind.Transient; + rqos.reliability = dds.ReliabilityKind.Reliable; + let reader = sub.createReader(topic, rqos, null); + + console.log('=== [Subscriber] Ready ...'); + + attemptTake(participant, reader, 0); + + participant.delete(); + } + + /* Attempt to take from the reader every 200 ms. + * If a successful take occurs, we are done. + * If a successful take does not occur after 100 attempts, + * return. + */ + function attemptTake(participant, reader, numberAttempts){ + + setTimeout(function() { + let takeArray = reader.take(1); + if (takeArray.length > 0 && (takeArray[0].info.valid_data === 1)) { + console.log('=== [Subscriber] message received :'); + console.log(' userID : ' + takeArray[0].sample.userID); + console.log(' Message : ' + takeArray[0].sample.message); + } else { + if (numberAttempts < 100){ + return attemptTake(participant, reader, numberAttempts + 1); + } + } + participant.delete(); + return; + }, 200); + } + +Take data with read condition from a data reader. + +.. code-block:: javascript + + const numberOfSamples = 10; + const cond = new dds.ReadCondition(reader, dds.StateMask.any); + let readArray = reader.takeCond(numberOfSamples, cond); + +Read data with read condition from a data reader. + +.. code-block:: javascript + + const numberOfSamples = 10; + const cond = new dds.ReadCondition(reader, dds.StateMask.any); + let readArray = reader.readCond(numberOfSamples, cond); + +WaitSet +******* + +The Node.js ``WaitSet`` class represents a DDS wait set. + +A WaitSet object allows an application to wait until one or more of the attached Condition objects evaluates to true or until the timeout expires. + +**Example** + +Create a ``WaitSet`` with a read condition to wait until publication is matched. Consider the code snippet below taken from example: PingPong/ping.js file. + +.. code-block:: javascript + + const dds = require('vortexdds'); + const PingPongTopic = require('./PingPongTopic'); + + // we iterate for 20 samples + const numSamples = 20; + main(); + + async function main() { + // create our entities + let participant = new dds.Participant(); + let topic = await PingPongTopic.create(participant); + + // create publisher on partition 'Ping' and writer on the publisher + // on pong, we have a subscriber on the same partition and topic + let pqos = dds.QoS.publisherDefault(); + pqos.partition = 'Ping'; + let publisher = participant.createPublisher(pqos, null); + let writer = publisher.createWriter(topic); + + // create a subscriber on partition 'Pong' and a reader on the subscriber + let sqos = dds.QoS.subscriberDefault(); + sqos.partition = 'Pong'; + let subscriber = participant.createSubscriber(sqos); + let reader = subscriber.createReader(topic); + + // create waitset which waits until pong subscriber on partition + // 'Ping' is found + let pubMatchedWaitset = new dds.Waitset(); + let statCond = new dds.StatusCondition(writer); + statCond.enable(dds.StatusMask.publication_matched); + pubMatchedWaitset.attach(statCond, writer); + + // waitset for new data + let newDataWaitset = new dds.Waitset(); + let newDataCond = new dds.ReadCondition(reader, + dds.StateMask.sample.not_read); + newDataWaitset.attach(newDataCond, reader); + + // block until pong has been found + console.log('Waiting for pong subscriber to be found...'); + pubMatchedWaitset.wait(dds.DDSConstants.DDS_INFINITY, function(err, res) { + if (err) throw err; + console.log('Found pong subscriber.'); + // Ping writes the first message + let msg = {userID: 0, message: 'from ping'}; + console.log('sending ' + JSON.stringify(msg)); + writer.write(msg); + onDataAvailable(participant, newDataWaitset, reader, writer, 0); + }); + } + + /* onDataAvailable waits for new data. When we have new data, it + * reads it, prints it, and sends back a message with the userID + * field incremented by one and 'from ping' in the message field. + * It then calls onDataAvailable again. + * We quit when iterLower === numSamples (20 iterations in this example). + */ + function onDataAvailable( + participant, + ws, + reader, + writer, + iterLower + ) { + if (iterLower === numSamples) { + console.log('Done'); + participant.delete(); + return; + } + // when we get a message from pong, read it, then send it back + // with userID+1 and message 'from ping' + ws.wait(dds.DDSConstants.DDS_INFINITY, function(err, res) { + if (err) throw err; + let takeArray = reader.take(1); + if (takeArray.length > 0 && (takeArray[0].info.valid_data === 1)) { + let sample = takeArray[0].sample; + console.log('received: ' + JSON.stringify(sample)); + let msg = {userID: sample.userID + 1, message: 'from ping'}; + console.log('sending ' + JSON.stringify(msg)); + writer.write(msg); + } + onDataAvailable(participant, ws, reader, writer, iterLower + 1); + }); + } + + +QueryCondition +************** + +The Node.js ``QueryCondition`` class represents a DDS query entity. + +A query is a data reader, restricted to accessing data that matches specific status conditions and/or a filter expression. + +A ``QueryCondition`` class instance references an existing ``Reader`` instance. + +**Example** + +Create a ``QueryCondition`` with a state mask and a filter expression for a reader and take data. Consider the code snippet below taken from example: jsshapes/read.js file. + +.. code-block:: javascript + + const dds = require('vortexdds'); + const ShapeTopicHelper = require('./ShapeTopicHelper'); + const util = require('util'); + + // we are reading 100 samples of a blue circle + const shapeName = 'Circle'; + const numSamples = 100; + const mask = dds.StateMask.sample.not_read; + const sqlExpression = 'color=%0'; + const params = ['BLUE']; + + main(); + + async function main() { + const participant = new dds.Participant(); + + // set up our topic + const circleTopic = await ShapeTopicHelper.create(participant, 'Circle'); + + // our reader has volatile qos + let readerqosprovider = new dds.QoSProvider( + './DDS_VolatileQoS_All.xml', + 'DDS VolatileQosProfile' + ); + + // set up circle reader + const circleReader = participant.createReader(circleTopic, + readerqosprovider.getReaderQos()); + + // set up waitset + const newDataWs = new dds.Waitset(); + const queryCond = new dds.QueryCondition( + circleReader, + mask, + sqlExpression, + params, + 1 + ); + // attach the query condition + newDataWs.attach(queryCond, circleReader); + + console.log('Waiting for demo_ishapes to publish a blue circle...'); + onDataAvailable(participant, newDataWs, circleReader, queryCond, 0); + }; + + /* onDataAvailable waits until we have new data (with the query condition). + * when we do, we read it, print the data (shape data), and then call + * onDataAvailable with iterLower incremented by one, to wait for more data. + * This repeats until iterLower === numSamples (100 samples in this case). + * When iterLower === numSamples, we delete the participant and quit. + */ + function onDataAvailable( + participant, + ws, + reader, + queryCond, + iterLower + ) { + if (iterLower === numSamples) { + console.log('Done.'); + participant.delete(); + return; + } + ws.wait(dds.DDSConstants.DDS_INFINITY, function(err, res) { + if (err) throw err; + let sampleArray = reader.takeCond(1, queryCond); + if (sampleArray.length > 0 && (sampleArray[0].info.valid_data === 1)) { + let sample = sampleArray[0].sample; + console.log( + util.format( + '%s %s of size %d at (%d,%d)', + sample.color, + shapeName, + sample.shapesize, + sample.x, + sample.y + ) + ); + } + onDataAvailable(participant, ws, reader, queryCond, iterLower + 1); + }); + } + diff --git a/docs/html/NodeJSDCPSAPIGuide/_sources/examples.txt b/docs/html/NodeJSDCPSAPIGuide/_sources/examples.txt new file mode 100644 index 000000000..2c0a34eb3 --- /dev/null +++ b/docs/html/NodeJSDCPSAPIGuide/_sources/examples.txt @@ -0,0 +1,142 @@ +.. _`Examples`: + +######## +Examples +######## + +Examples are provided to demonstrate the Node.js DCPS features. + +The examples can be found in the following directory: + + *$OSPL_HOME/tools/nodejs/examples* + +WHERE: + + Linux + + OSPL_HOME = *INSTALLDIR/ADLINK/Vortex_v2/Device/VortexOpenSplice/6.9.x/HDE/x86_64.linux* + + Windows + + OSPL_HOME = *INSTALLDIR\\ADLINK\\Vortex_v2\\Device\\VortexOpenSplice\\6.9.x\\HDE\\x86_64.win64* + +Example Files +************* + +Each subfolder consists of a Node.js example project. + +.. _`ExamplesTable`: + +Examples +======== + +.. tabularcolumns:: | p{3.3cm} | p{11cm} | ++-------------------+-----------------------------------------------------+ +| **Example** | **Description** | ++===================+=====================================================+ +| HelloWorld | Demonstrates how to read and write a simple | +| | topic in DDS | +| | | ++-------------------+-----------------------------------------------------+ +| jsshapes | Demonstrates how to read and write to a | +| | DDS application | +| | | ++-------------------+-----------------------------------------------------+ +| IoTData | Demonstrates reading and writing an IoTData topic | +| | | +| | | ++-------------------+-----------------------------------------------------+ +| PingPong | Demonstrates reading, writing, and waitsets | +| | | +| | | ++-------------------+-----------------------------------------------------+ +| QoSExample | Demonstrates QoS settings | +| | | +| | | ++-------------------+-----------------------------------------------------+ +| GetSetQoSExample | Demonstrates getting and setting QoS using | +| | QoS Provider and DCPS api | +| | | ++-------------------+-----------------------------------------------------+ + + +.. raw:: latex + + \newpage + +File Types +========== + +The examples directory contains files of different types. + + +============= ========================================================================================= +**File Type** **Description** +============= ========================================================================================= +js A program file or script written in JavaScript +package.json Lists the packages that a project depends on +xml An XML file that contains one or more Quality of Service (QoS) profiles for DDS entities +idl An interface description language file used to define topic(s) +============= ========================================================================================= + + + +Running Examples +**************** + +To run a Node.js example: + +1. Setup OSPL environment variables + + **Linux** + + - For each example javascript file to be run, open a Linux terminal + + - Navigate to directory containing release.com file (OSPL_HOME) + + */INSTALLDIR/ADLINK/Vortex_v2/Device/VortexOpenSplice/6.9.x/HDE/x86_64.linux* + + - Run release.com (“. release.comâ€) + + + **Windows** + + - For each example javascript file to be run, open a command prompt + + - Navigate to directory containing release.bat file (OSPL_HOME) + + *\\INSTALLDIR\\ADLINK\\Vortex_v2\\Device\\VortexOpenSplice\\6.9.x\\HDE\\x86_64.win64* + + - Run release.bat (“release.batâ€), if OSPL environment variables are not set system wide + +2. Change directory to the example folder + + Example: + + *$OSPL_HOME/tools/nodejs/examples/HelloWorld* + + +3. Run npm install to install the Node.js DCPS API (vortexdds-x.y.z.tgz) and all other dependencies + + npm install + +.. note:: + + If you are running the examples from another directory outside the OSPL install, then you will need to manually install the Node.js DCPS API first and then run npm install for the example dependencies as follows: + + npm install $OSPL_HOME/tools/nodejs/vortexdds-x.y.z.tgz + + npm install + +4. Run .js file(s) in a terminal/command shell + + Example: + + node HelloWorldSubscriber.js + + + + + + + diff --git a/docs/html/NodeJSDCPSAPIGuide/_sources/index.txt b/docs/html/NodeJSDCPSAPIGuide/_sources/index.txt new file mode 100644 index 000000000..0e2a13788 --- /dev/null +++ b/docs/html/NodeJSDCPSAPIGuide/_sources/index.txt @@ -0,0 +1,27 @@ +.. Node.js DCSP API Guide + +.. Doc Issue 01, 04 April 2018 + +###################### +Node.js DCPS API Guide +###################### + +.. toctree:: + :maxdepth: 6 + :numbered: + + preface + introduction + installation + examples + dds_entities + qos_provider + topic + + contacts + + +Indices and tables +================== + +* :ref:`search` diff --git a/docs/html/NodeJSDCPSAPIGuide/_sources/installation.txt b/docs/html/NodeJSDCPSAPIGuide/_sources/installation.txt new file mode 100644 index 000000000..a3a1d3a53 --- /dev/null +++ b/docs/html/NodeJSDCPSAPIGuide/_sources/installation.txt @@ -0,0 +1,143 @@ +.. _`Installation`: + +############ +Installation +############ + +This section describes the procedure to install the Node.js DCPS API on a Linux or Windows platform. + +Dependencies +************ + +The Node.js DCPS API has several dependencies that must be installed. + +Linux 64-bit +============ + + - Node.js LTS 8.11.1 or later (preferably Node.js LTS 8.x version) + - npm (node package manager) version 5.6.0 or later (typically included with a Node.js install) + - Python 2.7 (v3.x.x is not supported) + - make + - C/C++ compiler toolchain like GCC + + +Windows 64-bit +============== + + - Node.js LTS 8.11.1 or later (preferably Node.js LTS 8.x version) + - npm (node package manager) version 5.6.0 or later (typically included with a Node.js install) + - Python 2.7 (v3.x.x is not supported) + - Visual C++ build tools (VS 2015 or VS 2017) + +Python and Visual C++ build tools install +----------------------------------------- + + + - Install all the required tools and configurations using Microsoft's windows-build-tools by running the following from a command prompt as an administrator: + + npm install - -global - -production windows-build-tools + + (or) + + - Install tools and configuration manually + + - Visual C++ build tools (VS 2015 or VS 2017) + - Python 2.7 (v3.x.x is not supported) + +More detailed information on installing Python and Visual C++ build tools on Windows can be found at: https://github.com/Microsoft/nodejs-guidelines/blob/master/windows-environment.md#compiling-native-addon-modules + + +OpenSplice (OSPL) and Node.js DCPS API Installation +*************************************************** + +Steps: + +1. Install OSPL. Choose an HDE type installer which is a Host Development Environment. This contains all of the services, libraries, header files and tools needed to develop + applications using OpenSplice. The Node.js DCPS API is included in the following installers: + + + .. _`Installers Table`: + .. tabularcolumns:: | p{5cm} | p{5cm} | + +-------------------+----------------------+ + | **Platform** | **Platform Code** | + +===================+======================+ + | Ubuntu1404 64 bit | P704 | + | | | + +-------------------+----------------------+ + | Ubuntu1604 64 bit | P768 | + | | | + +-------------------+----------------------+ + | Windows10 64 bit | P738 | + | | | + +-------------------+----------------------+ + + Example installer: + + P704-VortexOpenSplice-6.9.x-HDE-x86.linux-gcc4.1.2-glibc2.5-installer.run + +2. Setup OSPL license. Copy the license.lic file into the appropriate license directory + + */INSTALLDIR/Vortex_v2/license* + +3. Node.js DCPS API files are contained in a tools/nodejs folder + + Example: + *$OSPL_HOME/tools/nodejs* + +Installing Node.js DCPS API in a Node.js application +**************************************************** + +1. Start a command shell. Setup OSPL environment variables by running release.com or release.bat which can be found in + + **Linux** + + */INSTALLDIR/ADLINK/Vortex_v2/Device/VortexOpenSplice/6.9.x/HDE/x86_64.linux/* + + **Windows** + + *\\INSTALLDIR\\ADLINK\\Vortex_v2\\Device\\VortexOpenSplice\\6.9.x\\HDE\\x86_64.windows\\* + +2. Create a node project folder, if not created + + mkdir + + cd + + npm init + +3. Change directory to node project folder + +4. Install the Node.js DCPS API to your project by executing: + + **Linux** + + npm install $OSPL_HOME/tools/nodejs/vortexdds-x.y.z.tgz + + **Windows** + + npm install %OSPL_HOME%\\tools\\nodejs\\vortexdds-x.y.z.tgz + +Examples and Documentation +************************** + +1. Examples directory: + + *$OSPL_HOME/tools/nodejs/examples* + + +2. Node.js DCPS API documentation directory: + + *$OSPL_HOME/docs/nodejs/html* + + +3. Node.js DCPS User Guide (HTML and PDF) directory: + + *$OSPL_HOME/docs* + + + + + + + + diff --git a/docs/html/NodeJSDCPSAPIGuide/_sources/introduction.txt b/docs/html/NodeJSDCPSAPIGuide/_sources/introduction.txt new file mode 100644 index 000000000..f9b44446f --- /dev/null +++ b/docs/html/NodeJSDCPSAPIGuide/_sources/introduction.txt @@ -0,0 +1,38 @@ +.. _`Introduction`: + + +############ +Introduction +############ + +The Node.js DCPS API provides users with Node.js classes to model DDS communication using JavaScript and pure DDS applications. + +The Node.js DCPS API is a native JavaScript binding that supports DDS functionality. The language binding consists of Node.js classes and wrapper implementations of the C99 API (C API for DDS). It makes use of ECMAScript 2015 (ES6) JavaScript language features and leverages ease of use by providing a higher level of abstraction. + +Please see :ref:`Limitations` for limitations of Node.js DDS API support. + +.. raw:: latex + + \newpage + +DDS +*** + +**What is DDS?** + +“The Data Distribution Service (DDSâ„¢) is a middleware protocol and API standard for data-centric connectivity from the Object Management Group® (OMG®). It integrates the components of a system together, providing low-latency data connectivity, extreme reliability, and a scalable architecture that business and mission-critical Internet of Things (IoT) applications need.†+ +“The main goal of DDS is to share the right data at the right place at the right time, even between time-decoupled publishers and consumers. DDS implements global data space by carefully replicating relevant portions of the logically shared dataspace.†DDS specification + +.. figure:: images/dds_overview.png + :alt: DDS + +**Further Documentation** + +http://portals.omg.org/dds/ + +http://ist.adlinktech.com/ + + + + diff --git a/docs/html/NodeJSDCPSAPIGuide/_sources/preface.txt b/docs/html/NodeJSDCPSAPIGuide/_sources/preface.txt new file mode 100644 index 000000000..0e8e8140b --- /dev/null +++ b/docs/html/NodeJSDCPSAPIGuide/_sources/preface.txt @@ -0,0 +1,31 @@ +.. _`Preface`: + +####### +Preface +####### + +About the Node.js DCPS API Guide +******************************** + +The Node.js DCPS API Guide is a starting point for anyone using, developing or running Node.js applications with Vortex OpenSplice. + +This guide contains: + + - Node.js DCSP API setup instructions + - location of Node.js DCPS API dds module documentation + - overview of general DDS concepts and Node.js API for Vortex DDS + - a listing of examples, and how to run them + - detailed information on how to specify DDS entity Quality of Service (QoS) + - how to register DDS topics + +This reference guide is based on the OMG’s Data Distribution Service Specification. + +Please note that this guide is not intended to provide a detailed explanation of the aforementioned OMG specifications or the Vortex OpenSplice product. It provides an introduction to the essential concepts and enables users to begin using the Node.js DCPS API as quickly as possible. + +Intended Audience +***************** + +The Node.js Reference Guide is intended to be used by JavaScript programmers who are +using Vortex OpenSplice to develop Node.js applications. + + diff --git a/docs/html/NodeJSDCPSAPIGuide/_sources/qos_provider.txt b/docs/html/NodeJSDCPSAPIGuide/_sources/qos_provider.txt new file mode 100644 index 000000000..f3306a686 --- /dev/null +++ b/docs/html/NodeJSDCPSAPIGuide/_sources/qos_provider.txt @@ -0,0 +1,516 @@ +.. _`QoS Provider`: + + +######################## +Quality of Service (QoS) +######################## + +The following section explains how to set the Quality of Service (QoS) for a DDS entity. + +Users have two options available to set the QoS for an entity or entities. They can define the QoS settings using an XML file, or they can use the Node.js DCPS APIs. Both of these options are explained. + +If a QoS setting for an entity is not set using an xml file or the Node.js DCPS APIs, the defaults will be used. This allows a user the ability to override only those settings that require non-default values. + +The code snippets referenced are taken from the runnable examples. + +.. note:: + + - The :ref:`Examples` section provides the examples directory location, example descriptions and running instructions. + + +Setting QoS Using QoS Provider XML File +*************************************** + +QoS for DDS entities can be set using XML files based on the XML schema file QoSProfile.xsd_. +These XML files contain one or more QoS profiles for DDS entities. OSPL includes an XSD (XML schema), that is located in $OSPL_HOME/etc/DDS_QoSProfile.xml. This can be used with XML schema core editors to help create valid XML files. + +Sample QoS Profile XML files can be found in the examples directory. Typically you will place the qos files in a subdirectory of your Node.js application. + +.. _QoSProfile: + +QoS Profile +=========== + +A QoS profile consists of a name and optionally a base_name attribute. The base_name attribute allows a +QoS or a profile to inherit values from another QoS or profile in the same file. The file contains QoS +elements for one or more DDS entities. + +A skeleton file without any QoS values is displayed below to show the structure of the file. + +.. code-block:: xml + + + + + + + + + + + + + +**Example: Persistent QoS XML file** + +The example below specifies the persistent QoS XML file which is used by the QoSProvider. + +.. code-block:: xml + + + + + + + + + + true + + + + + INSTANCE_PRESENTATION_QOS + true + true + + + partition1 + + + + + + true + + + + + INSTANCE_PRESENTATION_QOS + false + false + + + + + + + + + true + + + + + INSTANCE_PRESENTATION_QOS + true + true + + + partition1 + + + + + + true + + + + + PERSISTENT_DURABILITY_QOS + + + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + + 0 + 0 + + + + AUTOMATIC_LIVELINESS_QOS + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + RELIABLE_RELIABILITY_QOS + + 0 + 100000000 + + + + BY_RECEPTION_TIMESTAMP_DESTINATIONORDER_QOS + + + KEEP_LAST_HISTORY_QOS + 100 + + + LENGTH_UNLIMITED + LENGTH_UNLIMITED + LENGTH_UNLIMITED + + + 0 + + + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + + + + SHARED_OWNERSHIP_QOS + + + 0 + + + true + + + + + PERSISTENT_DURABILITY_QOS + + + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + + 0 + 0 + + + + AUTOMATIC_LIVELINESS_QOS + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + BEST_EFFORT_RELIABILITY_QOS + + 0 + 100000000 + + + + BY_RECEPTION_TIMESTAMP_DESTINATIONORDER_QOS + + + KEEP_ALL_HISTORY_QOS + + + LENGTH_UNLIMITED + LENGTH_UNLIMITED + LENGTH_UNLIMITED + + + + + + SHARED_OWNERSHIP_QOS + + + + 0 + 0 + + + + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + + + + + + PERSISTENT_DURABILITY_QOS + + + + 3600 + 0 + + KEEP_LAST_HISTORY_QOS + 100 + 8192 + 4196 + 8192 + + + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + + 0 + 0 + + + + AUTOMATIC_LIVELINESS_QOS + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + BEST_EFFORT_RELIABILITY_QOS + + 0 + 100000000 + + + + BY_RECEPTION_TIMESTAMP_DESTINATIONORDER_QOS + + + KEEP_LAST_HISTORY_QOS + 1 + + + LENGTH_UNLIMITED + LENGTH_UNLIMITED + LENGTH_UNLIMITED + + + 0 + + + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + SHARED_OWNERSHIP_QOS + + + + + +Applying QoS Profile +==================== + +To set the QoS profile for a DDS entity using the Node.js DCPS API and an XML file, the user specifies the qos file URI or file path and the QoS profile name as parameters. + +**Example** + +Create a QoS provider and get the respective entity QoS. The example below uses the QoS XML file referred in :ref:`QoSProfile`. For a detailed example refer to 'GetSetQoSExample.js' file referred in :ref:`GetSetQoSExample` example. + +.. code-block:: javascript + + const dds = require('vortexdds'); + const HelloWorldTopic = require('./HelloWorldTopic.js'); + + /** + * Path of the qos xml file + * The DDS_PersistentQoS.xml file is used for this example + * It is located in the same directory of this example + * */ + const QOS_PATH = 'DDS_PersistentQoS.xml'; + const QOS_PROFILE = 'DDS PersistentQosProfile'; + const DOMAIN_ID = dds.DDS_DOMAIN_DEFAULT; + + main(); + + async function main(){ + + /** + * Set QoS using QoS XML file + */ + + // create a qos provider using qos xml file + let qp = new dds.QoSProvider(QOS_PATH, QOS_PROFILE); + + // get participant qos from qos provider and create a participant + let pqos = qp.getParticipantQos(); + let participant = new dds.Participant(DOMAIN_ID, pqos); + + // get publisher qos from qos provider and create a publisher + let pubqos = qp.getPublisherQos(); + let publisher = new dds.Publisher(participant, pubqos); + + let subqos = qp.getSubscriberQos('subscriber1'); + let subscriber = new dds.Subscriber(participant, subqos); + + // get topic qos from qos provider and create a topic + let tqos = qp.getTopicQos(); + let topic = await HelloWorldTopic.create(participant, tqos); + + // get reader qos from qos provider and create a reader + let rqos = qp.getReaderQos(); + let reader = new dds.Reader(subscriber, topic, rqos); + + // get writer qos from qos provider and create a writer + let wqos = qp.getWriterQos(); + let writer = new dds.Writer(publisher, topic, wqos); + + // delete the participant + participant.delete(); + } + +Setting QoS Using Node.js DCPS API Classes +****************************************** + +QoS settings can also be set by using the Node.js classes alone. (No XML files required.) + +**Example** + +Below is a code snippet similar to the 'GetSetQoSExample/GetSetQoSExample.js' file. It demonstrates how to specify the QoS settings for a topic, writer and reader using the Node.js DCPS APIs. + +.. code-block:: javascript + + const dds = require('vortexdds'); + const HelloWorldTopic = require('./HelloWorldTopic.js'); + + main(); + + async function main(){ + + let participant = new dds.Participant(); + + // get the default topic qos + let tqos = dds.QoS.topicDefault(); + + // modify the topic qos policies + + // All of the policy variables can be set + tqos.durabilityService = { + serviceCleanupDelay: 5000, + historyKind: dds.HistoryKind.KeepLast, + historyDepth: 10, + maxSamples: 10, + maxInstances: 5, + maxSamplesPerInstance: -1, + }; + + // Or a subset of the policy variables can be set + tqos.durabilityService = { + historyKind: dds.HistoryKind.KeepLast, + }; + + tqos.reliability = dds.ReliabilityKind.reliable; + tqos.durability = dds.DurabilityKind.Volatile; + tqos.topicdata = 'Hello world topic'; + tqos.userdata = 'connected to hello world'; + tqos.groupdata = 'hello world group'; + tqos.history = { + kind: dds.HistoryKind.KeepLast, + depth: 10, + }; + tqos.resourceLimits = { + maxSamples: 10, + maxInstances: 5, + }; + tqos.lifespan = 5000; + tqos.deadline = 3000; + tqos.latencyBudget = 4000; + tqos.ownership = dds.OwnershipKind.Exclusive; + tqos.liveliness = { + kind: dds.LivelinessKind.ManualByTopic, + leaseDuration: 10, + }; + tqos.reliability = { + kind: dds.ReliabilityKind.Reliable, + maxBlockingTime: 100, + }; + tqos.transportPriority = 5; + tqos.destinationOrder = dds.DestinationOrderKind.BySourceTimestamp; + + // create topic with qos + let topic = await HelloWorldTopic.create(participant, tqos); + + // get topic qos policies + console.log('\n', '** Topic QoS **'); + console.log('Reliability: ', tqos.reliability); + console.log('Durability: ', tqos.durability); + console.log('Topic data: ', tqos.topicdata); + console.log('User data: ', tqos.userdata); + console.log('Group data: ', tqos.groupdata); + console.log('History: ', tqos.history); + console.log('Resource Limits: ', tqos.resourceLimits); + console.log('Lifespan: ', tqos.lifespan); + console.log('Deadline: ', tqos.deadline); + console.log('Latency Budget: ', tqos.latencyBudget); + console.log('Ownership: ', tqos.ownership); + console.log('Liveliness: ', tqos.liveliness); + console.log('Transport Priority: ', tqos.transportPriority); + console.log('Destination Order: ', tqos.destinationOrder); + console.log('Durability Service: ', tqos.durabilityService); + + // get the default writer qos + let wqos = dds.QoS.writerDefault(); + + // modify the writer qos policies + wqos.writerDataLifecycle = false; + + // create a writer with qos + let writer = new dds.Writer(publisher, topic, wqos); + + // get writer qos policies + console.log('\n', '** Writer QoS **'); + console.log('Writer data lifecyle: ', wqos.writerDataLifecycle); + + // get the default reader qos + let rqos = dds.QoS.readerDefault(); + + // modify the reader qos policies + rqos.partition = 'partition1'; + rqos.timebasedFilter = 60000; + rqos.readerDataLifecycle = { + autopurgeNoWriterSamples: 100, + autopurgeDisposedSamplesDelay: 500, + }; + + // create a reader with qos + let reader = new dds.Reader(subscriber, topic, rqos); + + // get reader qos policies + console.log('\n', '** Reader QoS **'); + console.log('Partition: ', rqos.partition); + console.log('Time based filter: ', rqos.timebasedFilter); + console.log('Reader data lifecycle: ', rqos.readerDataLifecycle); + + // delete the participant + participant.delete(); + + // NOTE: Actual reading and writing data is not demonstrated in this example + } + + + +.. external links +.. _QoSProfile.xsd: http://www.omg.org/spec/dds4ccm/20110201/DDS_QoSProfile.xsd +.. _DDS_DefaultQoS.xml: http://www.omg.org/spec/dds4ccm/20110201/DDS_DefaultQoS.xml diff --git a/docs/html/NodeJSDCPSAPIGuide/_sources/topic.txt b/docs/html/NodeJSDCPSAPIGuide/_sources/topic.txt new file mode 100644 index 000000000..e23cc866e --- /dev/null +++ b/docs/html/NodeJSDCPSAPIGuide/_sources/topic.txt @@ -0,0 +1,153 @@ +.. _`Topic Generation and Discovery`: + +############################## +Topic Generation and Discovery +############################## + +A DDS Topic represents the unit for information that can be produced or consumed by a DDS application. Topics are defined by a name, a type, and a set of QoS policies. + +The Node.js DCPS API provides several ways of generating Node.js classes to represent DDS topics. + + - over the wire discovery + - dynamic generation of Node.js classes using parameters IDL file and topic name + +.. note:: + + - The :ref:`Examples` section provides the examples directory location, example descriptions and running instructions. + + +Over the Wire Discovery +************************ + +Node.js topic classes can be generated for existing DDS topics in the DDS system. These topics are "discovered over the wire". + +The Node.js classes are generated when the topic is requested by name. + +A code snippet is provided from findTopicExample.js. This example finds a topic registered by another process, and writes a sample to that topic. + +**Example** + +.. code-block:: javascript + + ... + const dds = require('vortexdds'); + + console.log('Connecting to DDS domain...'); + const participant = new dds.Participant(); + + console.log('Finding topic...'); + let topic = participant.findTopic('HelloWorldData_Msg'); + + console.log('Creating writer and sample data to write...'); + let writer = participant.createWriter(topic); + let sample = { userID: 4, message: 7 }; + + console.log('Writing sample data...'); + let status = writer.write(sample); + ... + + +Dynamic Generation of Node.js Topic Classes Using IDL and Name +************************************************************** + +The Node.js DCPS API supports generation of Node.js topic classes from IDL. This section describes the details of the IDL-Node.js binding. + +Dynamic Generation +================== + +The Node.js DCPS API provides an asynchronous function that returns a Map of ``TypeSupport`` objects. + +A ``TypeSupport`` object includes the topic typename, keys and descriptor. + +The structure type representation of a topic is created by the TypeSupport object. However, the usage +of the structure type is internal to the Node.js DCPS API. + +In order to create a topic, a topic name and a ``TypeSupport`` are passed into the ``Participant`` createTopicFor function. (qos and listener parameters are optional) + +The code snippet below is taken from the 'IoTTopicHelper.js' file referred in :ref:`IoTData` example. + +.. code-block:: javascript + + const dds = require('vortexdds'); + const path = require('path'); + + //asynchronous function to create the topic + module.exports.create = async function(participant) { + + const topicName = 'IoTData'; + const idlName = 'dds_IoTData.idl'; + const idlPath = path.resolve(idlName); + + //wait for dds.getTopicTypeSupportsForIDL to return a map of typeSupports + let typeSupports = await dds.getTopicTypeSupportsForIDL(idlPath); + + //idl contains 1 topic. + let typeSupport = typeSupports.get('DDS::IoT::IoTData'); + + return participant.createTopicFor(topicName, typeSupport); + }; + +Generated Artifacts +=================== + +The following table defines the Node.js artifacts generated from IDL concepts: + +=========== ====================================== +IDL Concept Node.js Concept +=========== ====================================== +module N/A +enum enum from npm 'enum' package +enum value enum value +struct object +field object property +union object (IoTValue from dds_IoTData.idl + is the only supported union) +=========== ====================================== + +**Datatype mappings** + +The following table shows the Node.js equivalents to IDL primitive types: + +=========== ============== +IDL Type Node.js Type +=========== ============== +boolean Boolean +char Number +octet Number +short Number +ushort Number +long Number +ulong Number +long long Number +ulong long Number +float Number +double Number +string String +wchar Unsupported +wstring Unsupported +any Unsupported +long double Unsupported +=========== ============== + + +**Implementing Arrays and Sequences in Node.js** + +Both IDL arrays and IDL sequences are mapped to JavaScript arrays. + + +.. _Limitations: + +Limitations of Node.js Support +****************************** + +The Node.js binding has the following limitations: + + - Listeners are not supported + + - Only the IoTValue union from dds_IoTData.idl is supported in the beta + + - JavaScript does not currently include standard support for 64-bit integer values. 64-bit integers with more than 53 bits of data are represented by String values to avoid loss of precision. If the value will fit inside a JavaScript Number without losing precision, a Number can be used, otherwise use a String. (Refer to :ref:`IoTData` example which demonstrates the usage and ranges for the unsigned and signed 64 bit integers within nodejs.) + + + + diff --git a/docs/html/NodeJSDCPSAPIGuide/_static/Vortex_logo_2014.png b/docs/html/NodeJSDCPSAPIGuide/_static/Vortex_logo_2014.png new file mode 100644 index 000000000..e7de4f525 Binary files /dev/null and b/docs/html/NodeJSDCPSAPIGuide/_static/Vortex_logo_2014.png differ diff --git a/docs/html/NodeJSDCPSAPIGuide/_static/ajax-loader.gif b/docs/html/NodeJSDCPSAPIGuide/_static/ajax-loader.gif new file mode 100644 index 000000000..61faf8cab Binary files /dev/null and b/docs/html/NodeJSDCPSAPIGuide/_static/ajax-loader.gif differ diff --git a/docs/html/NodeJSDCPSAPIGuide/_static/basic.css b/docs/html/NodeJSDCPSAPIGuide/_static/basic.css new file mode 100644 index 000000000..967e36ce0 --- /dev/null +++ b/docs/html/NodeJSDCPSAPIGuide/_static/basic.css @@ -0,0 +1,537 @@ +/* + * basic.css + * ~~~~~~~~~ + * + * Sphinx stylesheet -- basic theme. + * + * :copyright: Copyright 2007-2014 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +/* -- main layout ----------------------------------------------------------- */ + +div.clearer { + clear: both; +} + +/* -- relbar ---------------------------------------------------------------- */ + +div.related { + width: 100%; + font-size: 90%; +} + +div.related h3 { + display: none; +} + +div.related ul { + margin: 0; + padding: 0 0 0 10px; + list-style: none; +} + +div.related li { + display: inline; +} + +div.related li.right { + float: right; + margin-right: 5px; +} + +/* -- sidebar --------------------------------------------------------------- */ + +div.sphinxsidebarwrapper { + padding: 10px 5px 0 10px; +} + +div.sphinxsidebar { + float: left; + width: 230px; + margin-left: -100%; + font-size: 90%; +} + +div.sphinxsidebar ul { + list-style: none; +} + +div.sphinxsidebar ul ul, +div.sphinxsidebar ul.want-points { + margin-left: 20px; + list-style: square; +} + +div.sphinxsidebar ul ul { + margin-top: 0; + margin-bottom: 0; +} + +div.sphinxsidebar form { + margin-top: 10px; +} + +div.sphinxsidebar input { + border: 1px solid #98dbcc; + font-family: sans-serif; + font-size: 1em; +} + +div.sphinxsidebar #searchbox input[type="text"] { + width: 170px; +} + +div.sphinxsidebar #searchbox input[type="submit"] { + width: 30px; +} + +img { + border: 0; + max-width: 100%; +} + +/* -- search page ----------------------------------------------------------- */ + +ul.search { + margin: 10px 0 0 20px; + padding: 0; +} + +ul.search li { + padding: 5px 0 5px 20px; + background-image: url(file.png); + background-repeat: no-repeat; + background-position: 0 7px; +} + +ul.search li a { + font-weight: bold; +} + +ul.search li div.context { + color: #888; + margin: 2px 0 0 30px; + text-align: left; +} + +ul.keywordmatches li.goodmatch a { + font-weight: bold; +} + +/* -- index page ------------------------------------------------------------ */ + +table.contentstable { + width: 90%; +} + +table.contentstable p.biglink { + line-height: 150%; +} + +a.biglink { + font-size: 1.3em; +} + +span.linkdescr { + font-style: italic; + padding-top: 5px; + font-size: 90%; +} + +/* -- general index --------------------------------------------------------- */ + +table.indextable { + width: 100%; +} + +table.indextable td { + text-align: left; + vertical-align: top; +} + +table.indextable dl, table.indextable dd { + margin-top: 0; + margin-bottom: 0; +} + +table.indextable tr.pcap { + height: 10px; +} + +table.indextable tr.cap { + margin-top: 10px; + background-color: #f2f2f2; +} + +img.toggler { + margin-right: 3px; + margin-top: 3px; + cursor: pointer; +} + +div.modindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +div.genindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +/* -- general body styles --------------------------------------------------- */ + +a.headerlink { + visibility: hidden; +} + +h1:hover > a.headerlink, +h2:hover > a.headerlink, +h3:hover > a.headerlink, +h4:hover > a.headerlink, +h5:hover > a.headerlink, +h6:hover > a.headerlink, +dt:hover > a.headerlink { + visibility: visible; +} + +div.body p.caption { + text-align: inherit; +} + +div.body td { + text-align: left; +} + +.field-list ul { + padding-left: 1em; +} + +.first { + margin-top: 0 !important; +} + +p.rubric { + margin-top: 30px; + font-weight: bold; +} + +img.align-left, .figure.align-left, object.align-left { + clear: left; + float: left; + margin-right: 1em; +} + +img.align-right, .figure.align-right, object.align-right { + clear: right; + float: right; + margin-left: 1em; +} + +img.align-center, .figure.align-center, object.align-center { + display: block; + margin-left: auto; + margin-right: auto; +} + +.align-left { + text-align: left; +} + +.align-center { + text-align: center; +} + +.align-right { + text-align: right; +} + +/* -- sidebars -------------------------------------------------------------- */ + +div.sidebar { + margin: 0 0 0.5em 1em; + border: 1px solid #ddb; + padding: 7px 7px 0 7px; + background-color: #ffe; + width: 40%; + float: right; +} + +p.sidebar-title { + font-weight: bold; +} + +/* -- topics ---------------------------------------------------------------- */ + +div.topic { + border: 1px solid #ccc; + padding: 7px 7px 0 7px; + margin: 10px 0 10px 0; +} + +p.topic-title { + font-size: 1.1em; + font-weight: bold; + margin-top: 10px; +} + +/* -- admonitions ----------------------------------------------------------- */ + +div.admonition { + margin-top: 10px; + margin-bottom: 10px; + padding: 7px; +} + +div.admonition dt { + font-weight: bold; +} + +div.admonition dl { + margin-bottom: 0; +} + +p.admonition-title { + margin: 0px 10px 5px 0px; + font-weight: bold; +} + +div.body p.centered { + text-align: center; + margin-top: 25px; +} + +/* -- tables ---------------------------------------------------------------- */ + +table.docutils { + border: 0; + border-collapse: collapse; +} + +table.docutils td, table.docutils th { + padding: 1px 8px 1px 5px; + border-top: 0; + border-left: 0; + border-right: 0; + border-bottom: 1px solid #aaa; +} + +table.field-list td, table.field-list th { + border: 0 !important; +} + +table.footnote td, table.footnote th { + border: 0 !important; +} + +th { + text-align: left; + padding-right: 5px; +} + +table.citation { + border-left: solid 1px gray; + margin-left: 1px; +} + +table.citation td { + border-bottom: none; +} + +/* -- other body styles ----------------------------------------------------- */ + +ol.arabic { + list-style: decimal; +} + +ol.loweralpha { + list-style: lower-alpha; +} + +ol.upperalpha { + list-style: upper-alpha; +} + +ol.lowerroman { + list-style: lower-roman; +} + +ol.upperroman { + list-style: upper-roman; +} + +dl { + margin-bottom: 15px; +} + +dd p { + margin-top: 0px; +} + +dd ul, dd table { + margin-bottom: 10px; +} + +dd { + margin-top: 3px; + margin-bottom: 10px; + margin-left: 30px; +} + +dt:target, .highlighted { + background-color: #fbe54e; +} + +dl.glossary dt { + font-weight: bold; + font-size: 1.1em; +} + +.field-list ul { + margin: 0; + padding-left: 1em; +} + +.field-list p { + margin: 0; +} + +.optional { + font-size: 1.3em; +} + +.versionmodified { + font-style: italic; +} + +.system-message { + background-color: #fda; + padding: 5px; + border: 3px solid red; +} + +.footnote:target { + background-color: #ffa; +} + +.line-block { + display: block; + margin-top: 1em; + margin-bottom: 1em; +} + +.line-block .line-block { + margin-top: 0; + margin-bottom: 0; + margin-left: 1.5em; +} + +.guilabel, .menuselection { + font-family: sans-serif; +} + +.accelerator { + text-decoration: underline; +} + +.classifier { + font-style: oblique; +} + +abbr, acronym { + border-bottom: dotted 1px; + cursor: help; +} + +/* -- code displays --------------------------------------------------------- */ + +pre { + overflow: auto; + overflow-y: hidden; /* fixes display issues on Chrome browsers */ +} + +td.linenos pre { + padding: 5px 0px; + border: 0; + background-color: transparent; + color: #aaa; +} + +table.highlighttable { + margin-left: 0.5em; +} + +table.highlighttable td { + padding: 0 0.5em 0 0.5em; +} + +tt.descname { + background-color: transparent; + font-weight: bold; + font-size: 1.2em; +} + +tt.descclassname { + background-color: transparent; +} + +tt.xref, a tt { + background-color: transparent; + font-weight: bold; +} + +h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt { + background-color: transparent; +} + +.viewcode-link { + float: right; +} + +.viewcode-back { + float: right; + font-family: sans-serif; +} + +div.viewcode-block:target { + margin: -1px -10px; + padding: 0 10px; +} + +/* -- math display ---------------------------------------------------------- */ + +img.math { + vertical-align: middle; +} + +div.body div.math p { + text-align: center; +} + +span.eqno { + float: right; +} + +/* -- printout stylesheet --------------------------------------------------- */ + +@media print { + div.document, + div.documentwrapper, + div.bodywrapper { + margin: 0 !important; + width: 100%; + } + + div.sphinxsidebar, + div.related, + div.footer, + #top-link { + display: none; + } +} \ No newline at end of file diff --git a/docs/html/NodeJSDCPSAPIGuide/_static/comment-bright.png b/docs/html/NodeJSDCPSAPIGuide/_static/comment-bright.png new file mode 100644 index 000000000..551517b8c Binary files /dev/null and b/docs/html/NodeJSDCPSAPIGuide/_static/comment-bright.png differ diff --git a/docs/html/NodeJSDCPSAPIGuide/_static/comment-close.png b/docs/html/NodeJSDCPSAPIGuide/_static/comment-close.png new file mode 100644 index 000000000..09b54be46 Binary files /dev/null and b/docs/html/NodeJSDCPSAPIGuide/_static/comment-close.png differ diff --git a/docs/html/NodeJSDCPSAPIGuide/_static/comment.png b/docs/html/NodeJSDCPSAPIGuide/_static/comment.png new file mode 100644 index 000000000..92feb52b8 Binary files /dev/null and b/docs/html/NodeJSDCPSAPIGuide/_static/comment.png differ diff --git a/docs/html/NodeJSDCPSAPIGuide/_static/doctools.js b/docs/html/NodeJSDCPSAPIGuide/_static/doctools.js new file mode 100644 index 000000000..c5455c905 --- /dev/null +++ b/docs/html/NodeJSDCPSAPIGuide/_static/doctools.js @@ -0,0 +1,238 @@ +/* + * doctools.js + * ~~~~~~~~~~~ + * + * Sphinx JavaScript utilities for all documentation. + * + * :copyright: Copyright 2007-2014 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +/** + * select a different prefix for underscore + */ +$u = _.noConflict(); + +/** + * make the code below compatible with browsers without + * an installed firebug like debugger +if (!window.console || !console.firebug) { + var names = ["log", "debug", "info", "warn", "error", "assert", "dir", + "dirxml", "group", "groupEnd", "time", "timeEnd", "count", "trace", + "profile", "profileEnd"]; + window.console = {}; + for (var i = 0; i < names.length; ++i) + window.console[names[i]] = function() {}; +} + */ + +/** + * small helper function to urldecode strings + */ +jQuery.urldecode = function(x) { + return decodeURIComponent(x).replace(/\+/g, ' '); +}; + +/** + * small helper function to urlencode strings + */ +jQuery.urlencode = encodeURIComponent; + +/** + * This function returns the parsed url parameters of the + * current request. Multiple values per key are supported, + * it will always return arrays of strings for the value parts. + */ +jQuery.getQueryParameters = function(s) { + if (typeof s == 'undefined') + s = document.location.search; + var parts = s.substr(s.indexOf('?') + 1).split('&'); + var result = {}; + for (var i = 0; i < parts.length; i++) { + var tmp = parts[i].split('=', 2); + var key = jQuery.urldecode(tmp[0]); + var value = jQuery.urldecode(tmp[1]); + if (key in result) + result[key].push(value); + else + result[key] = [value]; + } + return result; +}; + +/** + * highlight a given string on a jquery object by wrapping it in + * span elements with the given class name. + */ +jQuery.fn.highlightText = function(text, className) { + function highlight(node) { + if (node.nodeType == 3) { + var val = node.nodeValue; + var pos = val.toLowerCase().indexOf(text); + if (pos >= 0 && !jQuery(node.parentNode).hasClass(className)) { + var span = document.createElement("span"); + span.className = className; + span.appendChild(document.createTextNode(val.substr(pos, text.length))); + node.parentNode.insertBefore(span, node.parentNode.insertBefore( + document.createTextNode(val.substr(pos + text.length)), + node.nextSibling)); + node.nodeValue = val.substr(0, pos); + } + } + else if (!jQuery(node).is("button, select, textarea")) { + jQuery.each(node.childNodes, function() { + highlight(this); + }); + } + } + return this.each(function() { + highlight(this); + }); +}; + +/** + * Small JavaScript module for the documentation. + */ +var Documentation = { + + init : function() { + this.fixFirefoxAnchorBug(); + this.highlightSearchWords(); + this.initIndexTable(); + }, + + /** + * i18n support + */ + TRANSLATIONS : {}, + PLURAL_EXPR : function(n) { return n == 1 ? 0 : 1; }, + LOCALE : 'unknown', + + // gettext and ngettext don't access this so that the functions + // can safely bound to a different name (_ = Documentation.gettext) + gettext : function(string) { + var translated = Documentation.TRANSLATIONS[string]; + if (typeof translated == 'undefined') + return string; + return (typeof translated == 'string') ? translated : translated[0]; + }, + + ngettext : function(singular, plural, n) { + var translated = Documentation.TRANSLATIONS[singular]; + if (typeof translated == 'undefined') + return (n == 1) ? singular : plural; + return translated[Documentation.PLURALEXPR(n)]; + }, + + addTranslations : function(catalog) { + for (var key in catalog.messages) + this.TRANSLATIONS[key] = catalog.messages[key]; + this.PLURAL_EXPR = new Function('n', 'return +(' + catalog.plural_expr + ')'); + this.LOCALE = catalog.locale; + }, + + /** + * add context elements like header anchor links + */ + addContextElements : function() { + $('div[id] > :header:first').each(function() { + $('
    \u00B6'). + attr('href', '#' + this.id). + attr('title', _('Permalink to this headline')). + appendTo(this); + }); + $('dt[id]').each(function() { + $('\u00B6'). + attr('href', '#' + this.id). + attr('title', _('Permalink to this definition')). + appendTo(this); + }); + }, + + /** + * workaround a firefox stupidity + */ + fixFirefoxAnchorBug : function() { + if (document.location.hash && $.browser.mozilla) + window.setTimeout(function() { + document.location.href += ''; + }, 10); + }, + + /** + * highlight the search words provided in the url in the text + */ + highlightSearchWords : function() { + var params = $.getQueryParameters(); + var terms = (params.highlight) ? params.highlight[0].split(/\s+/) : []; + if (terms.length) { + var body = $('div.body'); + if (!body.length) { + body = $('body'); + } + window.setTimeout(function() { + $.each(terms, function() { + body.highlightText(this.toLowerCase(), 'highlighted'); + }); + }, 10); + $('') + .appendTo($('#searchbox')); + } + }, + + /** + * init the domain index toggle buttons + */ + initIndexTable : function() { + var togglers = $('img.toggler').click(function() { + var src = $(this).attr('src'); + var idnum = $(this).attr('id').substr(7); + $('tr.cg-' + idnum).toggle(); + if (src.substr(-9) == 'minus.png') + $(this).attr('src', src.substr(0, src.length-9) + 'plus.png'); + else + $(this).attr('src', src.substr(0, src.length-8) + 'minus.png'); + }).css('display', ''); + if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) { + togglers.click(); + } + }, + + /** + * helper function to hide the search marks again + */ + hideSearchWords : function() { + $('#searchbox .highlight-link').fadeOut(300); + $('span.highlighted').removeClass('highlighted'); + }, + + /** + * make the url absolute + */ + makeURL : function(relativeURL) { + return DOCUMENTATION_OPTIONS.URL_ROOT + '/' + relativeURL; + }, + + /** + * get the current relative url + */ + getCurrentURL : function() { + var path = document.location.pathname; + var parts = path.split(/\//); + $.each(DOCUMENTATION_OPTIONS.URL_ROOT.split(/\//), function() { + if (this == '..') + parts.pop(); + }); + var url = parts.join('/'); + return path.substring(url.lastIndexOf('/') + 1, path.length - 1); + } +}; + +// quick alias for translations +_ = Documentation.gettext; + +$(document).ready(function() { + Documentation.init(); +}); diff --git a/docs/html/NodeJSDCPSAPIGuide/_static/down-pressed.png b/docs/html/NodeJSDCPSAPIGuide/_static/down-pressed.png new file mode 100644 index 000000000..6f7ad7827 Binary files /dev/null and b/docs/html/NodeJSDCPSAPIGuide/_static/down-pressed.png differ diff --git a/docs/html/NodeJSDCPSAPIGuide/_static/down.png b/docs/html/NodeJSDCPSAPIGuide/_static/down.png new file mode 100644 index 000000000..3003a8877 Binary files /dev/null and b/docs/html/NodeJSDCPSAPIGuide/_static/down.png differ diff --git a/docs/html/NodeJSDCPSAPIGuide/_static/file.png b/docs/html/NodeJSDCPSAPIGuide/_static/file.png new file mode 100644 index 000000000..d18082e39 Binary files /dev/null and b/docs/html/NodeJSDCPSAPIGuide/_static/file.png differ diff --git a/docs/html/NodeJSDCPSAPIGuide/_static/jquery.js b/docs/html/NodeJSDCPSAPIGuide/_static/jquery.js new file mode 100644 index 000000000..e2efc335e --- /dev/null +++ b/docs/html/NodeJSDCPSAPIGuide/_static/jquery.js @@ -0,0 +1,9404 @@ +/*! + * jQuery JavaScript Library v1.7.2 + * http://jquery.com/ + * + * Copyright 2011, John Resig + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * Includes Sizzle.js + * http://sizzlejs.com/ + * Copyright 2011, The Dojo Foundation + * Released under the MIT, BSD, and GPL Licenses. + * + * Date: Fri Jul 5 14:07:58 UTC 2013 + */ +(function( window, undefined ) { + +// Use the correct document accordingly with window argument (sandbox) +var document = window.document, + navigator = window.navigator, + location = window.location; +var jQuery = (function() { + +// Define a local copy of jQuery +var jQuery = function( selector, context ) { + // The jQuery object is actually just the init constructor 'enhanced' + return new jQuery.fn.init( selector, context, rootjQuery ); + }, + + // Map over jQuery in case of overwrite + _jQuery = window.jQuery, + + // Map over the $ in case of overwrite + _$ = window.$, + + // A central reference to the root jQuery(document) + rootjQuery, + + // A simple way to check for HTML strings or ID strings + // Prioritize #id over to avoid XSS via location.hash (#9521) + quickExpr = /^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/, + + // Check if a string has a non-whitespace character in it + rnotwhite = /\S/, + + // Used for trimming whitespace + trimLeft = /^\s+/, + trimRight = /\s+$/, + + // Match a standalone tag + rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>)?$/, + + // JSON RegExp + rvalidchars = /^[\],:{}\s]*$/, + rvalidescape = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, + rvalidtokens = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, + rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g, + + // Useragent RegExp + rwebkit = /(webkit)[ \/]([\w.]+)/, + ropera = /(opera)(?:.*version)?[ \/]([\w.]+)/, + rmsie = /(msie) ([\w.]+)/, + rmozilla = /(mozilla)(?:.*? rv:([\w.]+))?/, + + // Matches dashed string for camelizing + rdashAlpha = /-([a-z]|[0-9])/ig, + rmsPrefix = /^-ms-/, + + // Used by jQuery.camelCase as callback to replace() + fcamelCase = function( all, letter ) { + return ( letter + "" ).toUpperCase(); + }, + + // Keep a UserAgent string for use with jQuery.browser + userAgent = navigator.userAgent, + + // For matching the engine and version of the browser + browserMatch, + + // The deferred used on DOM ready + readyList, + + // The ready event handler + DOMContentLoaded, + + // Save a reference to some core methods + toString = Object.prototype.toString, + hasOwn = Object.prototype.hasOwnProperty, + push = Array.prototype.push, + slice = Array.prototype.slice, + trim = String.prototype.trim, + indexOf = Array.prototype.indexOf, + + // [[Class]] -> type pairs + class2type = {}; + +jQuery.fn = jQuery.prototype = { + constructor: jQuery, + init: function( selector, context, rootjQuery ) { + var match, elem, ret, doc; + + // Handle $(""), $(null), or $(undefined) + if ( !selector ) { + return this; + } + + // Handle $(DOMElement) + if ( selector.nodeType ) { + this.context = this[0] = selector; + this.length = 1; + return this; + } + + // The body element only exists once, optimize finding it + if ( selector === "body" && !context && document.body ) { + this.context = document; + this[0] = document.body; + this.selector = selector; + this.length = 1; + return this; + } + + // Handle HTML strings + if ( typeof selector === "string" ) { + // Are we dealing with HTML string or an ID? + if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) { + // Assume that strings that start and end with <> are HTML and skip the regex check + match = [ null, selector, null ]; + + } else { + match = quickExpr.exec( selector ); + } + + // Verify a match, and that no context was specified for #id + if ( match && (match[1] || !context) ) { + + // HANDLE: $(html) -> $(array) + if ( match[1] ) { + context = context instanceof jQuery ? context[0] : context; + doc = ( context ? context.ownerDocument || context : document ); + + // If a single string is passed in and it's a single tag + // just do a createElement and skip the rest + ret = rsingleTag.exec( selector ); + + if ( ret ) { + if ( jQuery.isPlainObject( context ) ) { + selector = [ document.createElement( ret[1] ) ]; + jQuery.fn.attr.call( selector, context, true ); + + } else { + selector = [ doc.createElement( ret[1] ) ]; + } + + } else { + ret = jQuery.buildFragment( [ match[1] ], [ doc ] ); + selector = ( ret.cacheable ? jQuery.clone(ret.fragment) : ret.fragment ).childNodes; + } + + return jQuery.merge( this, selector ); + + // HANDLE: $("#id") + } else { + elem = document.getElementById( match[2] ); + + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + if ( elem && elem.parentNode ) { + // Handle the case where IE and Opera return items + // by name instead of ID + if ( elem.id !== match[2] ) { + return rootjQuery.find( selector ); + } + + // Otherwise, we inject the element directly into the jQuery object + this.length = 1; + this[0] = elem; + } + + this.context = document; + this.selector = selector; + return this; + } + + // HANDLE: $(expr, $(...)) + } else if ( !context || context.jquery ) { + return ( context || rootjQuery ).find( selector ); + + // HANDLE: $(expr, context) + // (which is just equivalent to: $(context).find(expr) + } else { + return this.constructor( context ).find( selector ); + } + + // HANDLE: $(function) + // Shortcut for document ready + } else if ( jQuery.isFunction( selector ) ) { + return rootjQuery.ready( selector ); + } + + if ( selector.selector !== undefined ) { + this.selector = selector.selector; + this.context = selector.context; + } + + return jQuery.makeArray( selector, this ); + }, + + // Start with an empty selector + selector: "", + + // The current version of jQuery being used + jquery: "1.7.2", + + // The default length of a jQuery object is 0 + length: 0, + + // The number of elements contained in the matched element set + size: function() { + return this.length; + }, + + toArray: function() { + return slice.call( this, 0 ); + }, + + // Get the Nth element in the matched element set OR + // Get the whole matched element set as a clean array + get: function( num ) { + return num == null ? + + // Return a 'clean' array + this.toArray() : + + // Return just the object + ( num < 0 ? this[ this.length + num ] : this[ num ] ); + }, + + // Take an array of elements and push it onto the stack + // (returning the new matched element set) + pushStack: function( elems, name, selector ) { + // Build a new jQuery matched element set + var ret = this.constructor(); + + if ( jQuery.isArray( elems ) ) { + push.apply( ret, elems ); + + } else { + jQuery.merge( ret, elems ); + } + + // Add the old object onto the stack (as a reference) + ret.prevObject = this; + + ret.context = this.context; + + if ( name === "find" ) { + ret.selector = this.selector + ( this.selector ? " " : "" ) + selector; + } else if ( name ) { + ret.selector = this.selector + "." + name + "(" + selector + ")"; + } + + // Return the newly-formed element set + return ret; + }, + + // Execute a callback for every element in the matched set. + // (You can seed the arguments with an array of args, but this is + // only used internally.) + each: function( callback, args ) { + return jQuery.each( this, callback, args ); + }, + + ready: function( fn ) { + // Attach the listeners + jQuery.bindReady(); + + // Add the callback + readyList.add( fn ); + + return this; + }, + + eq: function( i ) { + i = +i; + return i === -1 ? + this.slice( i ) : + this.slice( i, i + 1 ); + }, + + first: function() { + return this.eq( 0 ); + }, + + last: function() { + return this.eq( -1 ); + }, + + slice: function() { + return this.pushStack( slice.apply( this, arguments ), + "slice", slice.call(arguments).join(",") ); + }, + + map: function( callback ) { + return this.pushStack( jQuery.map(this, function( elem, i ) { + return callback.call( elem, i, elem ); + })); + }, + + end: function() { + return this.prevObject || this.constructor(null); + }, + + // For internal use only. + // Behaves like an Array's method, not like a jQuery method. + push: push, + sort: [].sort, + splice: [].splice +}; + +// Give the init function the jQuery prototype for later instantiation +jQuery.fn.init.prototype = jQuery.fn; + +jQuery.extend = jQuery.fn.extend = function() { + var options, name, src, copy, copyIsArray, clone, + target = arguments[0] || {}, + i = 1, + length = arguments.length, + deep = false; + + // Handle a deep copy situation + if ( typeof target === "boolean" ) { + deep = target; + target = arguments[1] || {}; + // skip the boolean and the target + i = 2; + } + + // Handle case when target is a string or something (possible in deep copy) + if ( typeof target !== "object" && !jQuery.isFunction(target) ) { + target = {}; + } + + // extend jQuery itself if only one argument is passed + if ( length === i ) { + target = this; + --i; + } + + for ( ; i < length; i++ ) { + // Only deal with non-null/undefined values + if ( (options = arguments[ i ]) != null ) { + // Extend the base object + for ( name in options ) { + src = target[ name ]; + copy = options[ name ]; + + // Prevent never-ending loop + if ( target === copy ) { + continue; + } + + // Recurse if we're merging plain objects or arrays + if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) { + if ( copyIsArray ) { + copyIsArray = false; + clone = src && jQuery.isArray(src) ? src : []; + + } else { + clone = src && jQuery.isPlainObject(src) ? src : {}; + } + + // Never move original objects, clone them + target[ name ] = jQuery.extend( deep, clone, copy ); + + // Don't bring in undefined values + } else if ( copy !== undefined ) { + target[ name ] = copy; + } + } + } + } + + // Return the modified object + return target; +}; + +jQuery.extend({ + noConflict: function( deep ) { + if ( window.$ === jQuery ) { + window.$ = _$; + } + + if ( deep && window.jQuery === jQuery ) { + window.jQuery = _jQuery; + } + + return jQuery; + }, + + // Is the DOM ready to be used? Set to true once it occurs. + isReady: false, + + // A counter to track how many items to wait for before + // the ready event fires. See #6781 + readyWait: 1, + + // Hold (or release) the ready event + holdReady: function( hold ) { + if ( hold ) { + jQuery.readyWait++; + } else { + jQuery.ready( true ); + } + }, + + // Handle when the DOM is ready + ready: function( wait ) { + // Either a released hold or an DOMready/load event and not yet ready + if ( (wait === true && !--jQuery.readyWait) || (wait !== true && !jQuery.isReady) ) { + // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). + if ( !document.body ) { + return setTimeout( jQuery.ready, 1 ); + } + + // Remember that the DOM is ready + jQuery.isReady = true; + + // If a normal DOM Ready event fired, decrement, and wait if need be + if ( wait !== true && --jQuery.readyWait > 0 ) { + return; + } + + // If there are functions bound, to execute + readyList.fireWith( document, [ jQuery ] ); + + // Trigger any bound ready events + if ( jQuery.fn.trigger ) { + jQuery( document ).trigger( "ready" ).off( "ready" ); + } + } + }, + + bindReady: function() { + if ( readyList ) { + return; + } + + readyList = jQuery.Callbacks( "once memory" ); + + // Catch cases where $(document).ready() is called after the + // browser event has already occurred. + if ( document.readyState === "complete" ) { + // Handle it asynchronously to allow scripts the opportunity to delay ready + return setTimeout( jQuery.ready, 1 ); + } + + // Mozilla, Opera and webkit nightlies currently support this event + if ( document.addEventListener ) { + // Use the handy event callback + document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false ); + + // A fallback to window.onload, that will always work + window.addEventListener( "load", jQuery.ready, false ); + + // If IE event model is used + } else if ( document.attachEvent ) { + // ensure firing before onload, + // maybe late but safe also for iframes + document.attachEvent( "onreadystatechange", DOMContentLoaded ); + + // A fallback to window.onload, that will always work + window.attachEvent( "onload", jQuery.ready ); + + // If IE and not a frame + // continually check to see if the document is ready + var toplevel = false; + + try { + toplevel = window.frameElement == null; + } catch(e) {} + + if ( document.documentElement.doScroll && toplevel ) { + doScrollCheck(); + } + } + }, + + // See test/unit/core.js for details concerning isFunction. + // Since version 1.3, DOM methods and functions like alert + // aren't supported. They return false on IE (#2968). + isFunction: function( obj ) { + return jQuery.type(obj) === "function"; + }, + + isArray: Array.isArray || function( obj ) { + return jQuery.type(obj) === "array"; + }, + + isWindow: function( obj ) { + return obj != null && obj == obj.window; + }, + + isNumeric: function( obj ) { + return !isNaN( parseFloat(obj) ) && isFinite( obj ); + }, + + type: function( obj ) { + return obj == null ? + String( obj ) : + class2type[ toString.call(obj) ] || "object"; + }, + + isPlainObject: function( obj ) { + // Must be an Object. + // Because of IE, we also have to check the presence of the constructor property. + // Make sure that DOM nodes and window objects don't pass through, as well + if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) { + return false; + } + + try { + // Not own constructor property must be Object + if ( obj.constructor && + !hasOwn.call(obj, "constructor") && + !hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) { + return false; + } + } catch ( e ) { + // IE8,9 Will throw exceptions on certain host objects #9897 + return false; + } + + // Own properties are enumerated firstly, so to speed up, + // if last one is own, then all properties are own. + + var key; + for ( key in obj ) {} + + return key === undefined || hasOwn.call( obj, key ); + }, + + isEmptyObject: function( obj ) { + for ( var name in obj ) { + return false; + } + return true; + }, + + error: function( msg ) { + throw new Error( msg ); + }, + + parseJSON: function( data ) { + if ( typeof data !== "string" || !data ) { + return null; + } + + // Make sure leading/trailing whitespace is removed (IE can't handle it) + data = jQuery.trim( data ); + + // Attempt to parse using the native JSON parser first + if ( window.JSON && window.JSON.parse ) { + return window.JSON.parse( data ); + } + + // Make sure the incoming data is actual JSON + // Logic borrowed from http://json.org/json2.js + if ( rvalidchars.test( data.replace( rvalidescape, "@" ) + .replace( rvalidtokens, "]" ) + .replace( rvalidbraces, "")) ) { + + return ( new Function( "return " + data ) )(); + + } + jQuery.error( "Invalid JSON: " + data ); + }, + + // Cross-browser xml parsing + parseXML: function( data ) { + if ( typeof data !== "string" || !data ) { + return null; + } + var xml, tmp; + try { + if ( window.DOMParser ) { // Standard + tmp = new DOMParser(); + xml = tmp.parseFromString( data , "text/xml" ); + } else { // IE + xml = new ActiveXObject( "Microsoft.XMLDOM" ); + xml.async = "false"; + xml.loadXML( data ); + } + } catch( e ) { + xml = undefined; + } + if ( !xml || !xml.documentElement || xml.getElementsByTagName( "parsererror" ).length ) { + jQuery.error( "Invalid XML: " + data ); + } + return xml; + }, + + noop: function() {}, + + // Evaluates a script in a global context + // Workarounds based on findings by Jim Driscoll + // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context + globalEval: function( data ) { + if ( data && rnotwhite.test( data ) ) { + // We use execScript on Internet Explorer + // We use an anonymous function so that context is window + // rather than jQuery in Firefox + ( window.execScript || function( data ) { + window[ "eval" ].call( window, data ); + } )( data ); + } + }, + + // Convert dashed to camelCase; used by the css and data modules + // Microsoft forgot to hump their vendor prefix (#9572) + camelCase: function( string ) { + return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); + }, + + nodeName: function( elem, name ) { + return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase(); + }, + + // args is for internal usage only + each: function( object, callback, args ) { + var name, i = 0, + length = object.length, + isObj = length === undefined || jQuery.isFunction( object ); + + if ( args ) { + if ( isObj ) { + for ( name in object ) { + if ( callback.apply( object[ name ], args ) === false ) { + break; + } + } + } else { + for ( ; i < length; ) { + if ( callback.apply( object[ i++ ], args ) === false ) { + break; + } + } + } + + // A special, fast, case for the most common use of each + } else { + if ( isObj ) { + for ( name in object ) { + if ( callback.call( object[ name ], name, object[ name ] ) === false ) { + break; + } + } + } else { + for ( ; i < length; ) { + if ( callback.call( object[ i ], i, object[ i++ ] ) === false ) { + break; + } + } + } + } + + return object; + }, + + // Use native String.trim function wherever possible + trim: trim ? + function( text ) { + return text == null ? + "" : + trim.call( text ); + } : + + // Otherwise use our own trimming functionality + function( text ) { + return text == null ? + "" : + text.toString().replace( trimLeft, "" ).replace( trimRight, "" ); + }, + + // results is for internal usage only + makeArray: function( array, results ) { + var ret = results || []; + + if ( array != null ) { + // The window, strings (and functions) also have 'length' + // Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930 + var type = jQuery.type( array ); + + if ( array.length == null || type === "string" || type === "function" || type === "regexp" || jQuery.isWindow( array ) ) { + push.call( ret, array ); + } else { + jQuery.merge( ret, array ); + } + } + + return ret; + }, + + inArray: function( elem, array, i ) { + var len; + + if ( array ) { + if ( indexOf ) { + return indexOf.call( array, elem, i ); + } + + len = array.length; + i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0; + + for ( ; i < len; i++ ) { + // Skip accessing in sparse arrays + if ( i in array && array[ i ] === elem ) { + return i; + } + } + } + + return -1; + }, + + merge: function( first, second ) { + var i = first.length, + j = 0; + + if ( typeof second.length === "number" ) { + for ( var l = second.length; j < l; j++ ) { + first[ i++ ] = second[ j ]; + } + + } else { + while ( second[j] !== undefined ) { + first[ i++ ] = second[ j++ ]; + } + } + + first.length = i; + + return first; + }, + + grep: function( elems, callback, inv ) { + var ret = [], retVal; + inv = !!inv; + + // Go through the array, only saving the items + // that pass the validator function + for ( var i = 0, length = elems.length; i < length; i++ ) { + retVal = !!callback( elems[ i ], i ); + if ( inv !== retVal ) { + ret.push( elems[ i ] ); + } + } + + return ret; + }, + + // arg is for internal usage only + map: function( elems, callback, arg ) { + var value, key, ret = [], + i = 0, + length = elems.length, + // jquery objects are treated as arrays + isArray = elems instanceof jQuery || length !== undefined && typeof length === "number" && ( ( length > 0 && elems[ 0 ] && elems[ length -1 ] ) || length === 0 || jQuery.isArray( elems ) ) ; + + // Go through the array, translating each of the items to their + if ( isArray ) { + for ( ; i < length; i++ ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret[ ret.length ] = value; + } + } + + // Go through every key on the object, + } else { + for ( key in elems ) { + value = callback( elems[ key ], key, arg ); + + if ( value != null ) { + ret[ ret.length ] = value; + } + } + } + + // Flatten any nested arrays + return ret.concat.apply( [], ret ); + }, + + // A global GUID counter for objects + guid: 1, + + // Bind a function to a context, optionally partially applying any + // arguments. + proxy: function( fn, context ) { + if ( typeof context === "string" ) { + var tmp = fn[ context ]; + context = fn; + fn = tmp; + } + + // Quick check to determine if target is callable, in the spec + // this throws a TypeError, but we will just return undefined. + if ( !jQuery.isFunction( fn ) ) { + return undefined; + } + + // Simulated bind + var args = slice.call( arguments, 2 ), + proxy = function() { + return fn.apply( context, args.concat( slice.call( arguments ) ) ); + }; + + // Set the guid of unique handler to the same of original handler, so it can be removed + proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++; + + return proxy; + }, + + // Mutifunctional method to get and set values to a collection + // The value/s can optionally be executed if it's a function + access: function( elems, fn, key, value, chainable, emptyGet, pass ) { + var exec, + bulk = key == null, + i = 0, + length = elems.length; + + // Sets many values + if ( key && typeof key === "object" ) { + for ( i in key ) { + jQuery.access( elems, fn, i, key[i], 1, emptyGet, value ); + } + chainable = 1; + + // Sets one value + } else if ( value !== undefined ) { + // Optionally, function values get executed if exec is true + exec = pass === undefined && jQuery.isFunction( value ); + + if ( bulk ) { + // Bulk operations only iterate when executing function values + if ( exec ) { + exec = fn; + fn = function( elem, key, value ) { + return exec.call( jQuery( elem ), value ); + }; + + // Otherwise they run against the entire set + } else { + fn.call( elems, value ); + fn = null; + } + } + + if ( fn ) { + for (; i < length; i++ ) { + fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass ); + } + } + + chainable = 1; + } + + return chainable ? + elems : + + // Gets + bulk ? + fn.call( elems ) : + length ? fn( elems[0], key ) : emptyGet; + }, + + now: function() { + return ( new Date() ).getTime(); + }, + + // Use of jQuery.browser is frowned upon. + // More details: http://docs.jquery.com/Utilities/jQuery.browser + uaMatch: function( ua ) { + ua = ua.toLowerCase(); + + var match = rwebkit.exec( ua ) || + ropera.exec( ua ) || + rmsie.exec( ua ) || + ua.indexOf("compatible") < 0 && rmozilla.exec( ua ) || + []; + + return { browser: match[1] || "", version: match[2] || "0" }; + }, + + sub: function() { + function jQuerySub( selector, context ) { + return new jQuerySub.fn.init( selector, context ); + } + jQuery.extend( true, jQuerySub, this ); + jQuerySub.superclass = this; + jQuerySub.fn = jQuerySub.prototype = this(); + jQuerySub.fn.constructor = jQuerySub; + jQuerySub.sub = this.sub; + jQuerySub.fn.init = function init( selector, context ) { + if ( context && context instanceof jQuery && !(context instanceof jQuerySub) ) { + context = jQuerySub( context ); + } + + return jQuery.fn.init.call( this, selector, context, rootjQuerySub ); + }; + jQuerySub.fn.init.prototype = jQuerySub.fn; + var rootjQuerySub = jQuerySub(document); + return jQuerySub; + }, + + browser: {} +}); + +// Populate the class2type map +jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) { + class2type[ "[object " + name + "]" ] = name.toLowerCase(); +}); + +browserMatch = jQuery.uaMatch( userAgent ); +if ( browserMatch.browser ) { + jQuery.browser[ browserMatch.browser ] = true; + jQuery.browser.version = browserMatch.version; +} + +// Deprecated, use jQuery.browser.webkit instead +if ( jQuery.browser.webkit ) { + jQuery.browser.safari = true; +} + +// IE doesn't match non-breaking spaces with \s +if ( rnotwhite.test( "\xA0" ) ) { + trimLeft = /^[\s\xA0]+/; + trimRight = /[\s\xA0]+$/; +} + +// All jQuery objects should point back to these +rootjQuery = jQuery(document); + +// Cleanup functions for the document ready method +if ( document.addEventListener ) { + DOMContentLoaded = function() { + document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false ); + jQuery.ready(); + }; + +} else if ( document.attachEvent ) { + DOMContentLoaded = function() { + // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). + if ( document.readyState === "complete" ) { + document.detachEvent( "onreadystatechange", DOMContentLoaded ); + jQuery.ready(); + } + }; +} + +// The DOM ready check for Internet Explorer +function doScrollCheck() { + if ( jQuery.isReady ) { + return; + } + + try { + // If IE is used, use the trick by Diego Perini + // http://javascript.nwbox.com/IEContentLoaded/ + document.documentElement.doScroll("left"); + } catch(e) { + setTimeout( doScrollCheck, 1 ); + return; + } + + // and execute any waiting functions + jQuery.ready(); +} + +return jQuery; + +})(); + + +// String to Object flags format cache +var flagsCache = {}; + +// Convert String-formatted flags into Object-formatted ones and store in cache +function createFlags( flags ) { + var object = flagsCache[ flags ] = {}, + i, length; + flags = flags.split( /\s+/ ); + for ( i = 0, length = flags.length; i < length; i++ ) { + object[ flags[i] ] = true; + } + return object; +} + +/* + * Create a callback list using the following parameters: + * + * flags: an optional list of space-separated flags that will change how + * the callback list behaves + * + * By default a callback list will act like an event callback list and can be + * "fired" multiple times. + * + * Possible flags: + * + * once: will ensure the callback list can only be fired once (like a Deferred) + * + * memory: will keep track of previous values and will call any callback added + * after the list has been fired right away with the latest "memorized" + * values (like a Deferred) + * + * unique: will ensure a callback can only be added once (no duplicate in the list) + * + * stopOnFalse: interrupt callings when a callback returns false + * + */ +jQuery.Callbacks = function( flags ) { + + // Convert flags from String-formatted to Object-formatted + // (we check in cache first) + flags = flags ? ( flagsCache[ flags ] || createFlags( flags ) ) : {}; + + var // Actual callback list + list = [], + // Stack of fire calls for repeatable lists + stack = [], + // Last fire value (for non-forgettable lists) + memory, + // Flag to know if list was already fired + fired, + // Flag to know if list is currently firing + firing, + // First callback to fire (used internally by add and fireWith) + firingStart, + // End of the loop when firing + firingLength, + // Index of currently firing callback (modified by remove if needed) + firingIndex, + // Add one or several callbacks to the list + add = function( args ) { + var i, + length, + elem, + type, + actual; + for ( i = 0, length = args.length; i < length; i++ ) { + elem = args[ i ]; + type = jQuery.type( elem ); + if ( type === "array" ) { + // Inspect recursively + add( elem ); + } else if ( type === "function" ) { + // Add if not in unique mode and callback is not in + if ( !flags.unique || !self.has( elem ) ) { + list.push( elem ); + } + } + } + }, + // Fire callbacks + fire = function( context, args ) { + args = args || []; + memory = !flags.memory || [ context, args ]; + fired = true; + firing = true; + firingIndex = firingStart || 0; + firingStart = 0; + firingLength = list.length; + for ( ; list && firingIndex < firingLength; firingIndex++ ) { + if ( list[ firingIndex ].apply( context, args ) === false && flags.stopOnFalse ) { + memory = true; // Mark as halted + break; + } + } + firing = false; + if ( list ) { + if ( !flags.once ) { + if ( stack && stack.length ) { + memory = stack.shift(); + self.fireWith( memory[ 0 ], memory[ 1 ] ); + } + } else if ( memory === true ) { + self.disable(); + } else { + list = []; + } + } + }, + // Actual Callbacks object + self = { + // Add a callback or a collection of callbacks to the list + add: function() { + if ( list ) { + var length = list.length; + add( arguments ); + // Do we need to add the callbacks to the + // current firing batch? + if ( firing ) { + firingLength = list.length; + // With memory, if we're not firing then + // we should call right away, unless previous + // firing was halted (stopOnFalse) + } else if ( memory && memory !== true ) { + firingStart = length; + fire( memory[ 0 ], memory[ 1 ] ); + } + } + return this; + }, + // Remove a callback from the list + remove: function() { + if ( list ) { + var args = arguments, + argIndex = 0, + argLength = args.length; + for ( ; argIndex < argLength ; argIndex++ ) { + for ( var i = 0; i < list.length; i++ ) { + if ( args[ argIndex ] === list[ i ] ) { + // Handle firingIndex and firingLength + if ( firing ) { + if ( i <= firingLength ) { + firingLength--; + if ( i <= firingIndex ) { + firingIndex--; + } + } + } + // Remove the element + list.splice( i--, 1 ); + // If we have some unicity property then + // we only need to do this once + if ( flags.unique ) { + break; + } + } + } + } + } + return this; + }, + // Control if a given callback is in the list + has: function( fn ) { + if ( list ) { + var i = 0, + length = list.length; + for ( ; i < length; i++ ) { + if ( fn === list[ i ] ) { + return true; + } + } + } + return false; + }, + // Remove all callbacks from the list + empty: function() { + list = []; + return this; + }, + // Have the list do nothing anymore + disable: function() { + list = stack = memory = undefined; + return this; + }, + // Is it disabled? + disabled: function() { + return !list; + }, + // Lock the list in its current state + lock: function() { + stack = undefined; + if ( !memory || memory === true ) { + self.disable(); + } + return this; + }, + // Is it locked? + locked: function() { + return !stack; + }, + // Call all callbacks with the given context and arguments + fireWith: function( context, args ) { + if ( stack ) { + if ( firing ) { + if ( !flags.once ) { + stack.push( [ context, args ] ); + } + } else if ( !( flags.once && memory ) ) { + fire( context, args ); + } + } + return this; + }, + // Call all the callbacks with the given arguments + fire: function() { + self.fireWith( this, arguments ); + return this; + }, + // To know if the callbacks have already been called at least once + fired: function() { + return !!fired; + } + }; + + return self; +}; + + + + +var // Static reference to slice + sliceDeferred = [].slice; + +jQuery.extend({ + + Deferred: function( func ) { + var doneList = jQuery.Callbacks( "once memory" ), + failList = jQuery.Callbacks( "once memory" ), + progressList = jQuery.Callbacks( "memory" ), + state = "pending", + lists = { + resolve: doneList, + reject: failList, + notify: progressList + }, + promise = { + done: doneList.add, + fail: failList.add, + progress: progressList.add, + + state: function() { + return state; + }, + + // Deprecated + isResolved: doneList.fired, + isRejected: failList.fired, + + then: function( doneCallbacks, failCallbacks, progressCallbacks ) { + deferred.done( doneCallbacks ).fail( failCallbacks ).progress( progressCallbacks ); + return this; + }, + always: function() { + deferred.done.apply( deferred, arguments ).fail.apply( deferred, arguments ); + return this; + }, + pipe: function( fnDone, fnFail, fnProgress ) { + return jQuery.Deferred(function( newDefer ) { + jQuery.each( { + done: [ fnDone, "resolve" ], + fail: [ fnFail, "reject" ], + progress: [ fnProgress, "notify" ] + }, function( handler, data ) { + var fn = data[ 0 ], + action = data[ 1 ], + returned; + if ( jQuery.isFunction( fn ) ) { + deferred[ handler ](function() { + returned = fn.apply( this, arguments ); + if ( returned && jQuery.isFunction( returned.promise ) ) { + returned.promise().then( newDefer.resolve, newDefer.reject, newDefer.notify ); + } else { + newDefer[ action + "With" ]( this === deferred ? newDefer : this, [ returned ] ); + } + }); + } else { + deferred[ handler ]( newDefer[ action ] ); + } + }); + }).promise(); + }, + // Get a promise for this deferred + // If obj is provided, the promise aspect is added to the object + promise: function( obj ) { + if ( obj == null ) { + obj = promise; + } else { + for ( var key in promise ) { + obj[ key ] = promise[ key ]; + } + } + return obj; + } + }, + deferred = promise.promise({}), + key; + + for ( key in lists ) { + deferred[ key ] = lists[ key ].fire; + deferred[ key + "With" ] = lists[ key ].fireWith; + } + + // Handle state + deferred.done( function() { + state = "resolved"; + }, failList.disable, progressList.lock ).fail( function() { + state = "rejected"; + }, doneList.disable, progressList.lock ); + + // Call given func if any + if ( func ) { + func.call( deferred, deferred ); + } + + // All done! + return deferred; + }, + + // Deferred helper + when: function( firstParam ) { + var args = sliceDeferred.call( arguments, 0 ), + i = 0, + length = args.length, + pValues = new Array( length ), + count = length, + pCount = length, + deferred = length <= 1 && firstParam && jQuery.isFunction( firstParam.promise ) ? + firstParam : + jQuery.Deferred(), + promise = deferred.promise(); + function resolveFunc( i ) { + return function( value ) { + args[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value; + if ( !( --count ) ) { + deferred.resolveWith( deferred, args ); + } + }; + } + function progressFunc( i ) { + return function( value ) { + pValues[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value; + deferred.notifyWith( promise, pValues ); + }; + } + if ( length > 1 ) { + for ( ; i < length; i++ ) { + if ( args[ i ] && args[ i ].promise && jQuery.isFunction( args[ i ].promise ) ) { + args[ i ].promise().then( resolveFunc(i), deferred.reject, progressFunc(i) ); + } else { + --count; + } + } + if ( !count ) { + deferred.resolveWith( deferred, args ); + } + } else if ( deferred !== firstParam ) { + deferred.resolveWith( deferred, length ? [ firstParam ] : [] ); + } + return promise; + } +}); + + + + +jQuery.support = (function() { + + var support, + all, + a, + select, + opt, + input, + fragment, + tds, + events, + eventName, + i, + isSupported, + div = document.createElement( "div" ), + documentElement = document.documentElement; + + // Preliminary tests + div.setAttribute("className", "t"); + div.innerHTML = "

    a"; + + all = div.getElementsByTagName( "*" ); + a = div.getElementsByTagName( "a" )[ 0 ]; + + // Can't get basic test support + if ( !all || !all.length || !a ) { + return {}; + } + + // First batch of supports tests + select = document.createElement( "select" ); + opt = select.appendChild( document.createElement("option") ); + input = div.getElementsByTagName( "input" )[ 0 ]; + + support = { + // IE strips leading whitespace when .innerHTML is used + leadingWhitespace: ( div.firstChild.nodeType === 3 ), + + // Make sure that tbody elements aren't automatically inserted + // IE will insert them into empty tables + tbody: !div.getElementsByTagName("tbody").length, + + // Make sure that link elements get serialized correctly by innerHTML + // This requires a wrapper element in IE + htmlSerialize: !!div.getElementsByTagName("link").length, + + // Get the style information from getAttribute + // (IE uses .cssText instead) + style: /top/.test( a.getAttribute("style") ), + + // Make sure that URLs aren't manipulated + // (IE normalizes it by default) + hrefNormalized: ( a.getAttribute("href") === "/a" ), + + // Make sure that element opacity exists + // (IE uses filter instead) + // Use a regex to work around a WebKit issue. See #5145 + opacity: /^0.55/.test( a.style.opacity ), + + // Verify style float existence + // (IE uses styleFloat instead of cssFloat) + cssFloat: !!a.style.cssFloat, + + // Make sure that if no value is specified for a checkbox + // that it defaults to "on". + // (WebKit defaults to "" instead) + checkOn: ( input.value === "on" ), + + // Make sure that a selected-by-default option has a working selected property. + // (WebKit defaults to false instead of true, IE too, if it's in an optgroup) + optSelected: opt.selected, + + // Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7) + getSetAttribute: div.className !== "t", + + // Tests for enctype support on a form(#6743) + enctype: !!document.createElement("form").enctype, + + // Makes sure cloning an html5 element does not cause problems + // Where outerHTML is undefined, this still works + html5Clone: document.createElement("nav").cloneNode( true ).outerHTML !== "<:nav>", + + // Will be defined later + submitBubbles: true, + changeBubbles: true, + focusinBubbles: false, + deleteExpando: true, + noCloneEvent: true, + inlineBlockNeedsLayout: false, + shrinkWrapBlocks: false, + reliableMarginRight: true, + pixelMargin: true + }; + + // jQuery.boxModel DEPRECATED in 1.3, use jQuery.support.boxModel instead + jQuery.boxModel = support.boxModel = (document.compatMode === "CSS1Compat"); + + // Make sure checked status is properly cloned + input.checked = true; + support.noCloneChecked = input.cloneNode( true ).checked; + + // Make sure that the options inside disabled selects aren't marked as disabled + // (WebKit marks them as disabled) + select.disabled = true; + support.optDisabled = !opt.disabled; + + // Test to see if it's possible to delete an expando from an element + // Fails in Internet Explorer + try { + delete div.test; + } catch( e ) { + support.deleteExpando = false; + } + + if ( !div.addEventListener && div.attachEvent && div.fireEvent ) { + div.attachEvent( "onclick", function() { + // Cloning a node shouldn't copy over any + // bound event handlers (IE does this) + support.noCloneEvent = false; + }); + div.cloneNode( true ).fireEvent( "onclick" ); + } + + // Check if a radio maintains its value + // after being appended to the DOM + input = document.createElement("input"); + input.value = "t"; + input.setAttribute("type", "radio"); + support.radioValue = input.value === "t"; + + input.setAttribute("checked", "checked"); + + // #11217 - WebKit loses check when the name is after the checked attribute + input.setAttribute( "name", "t" ); + + div.appendChild( input ); + fragment = document.createDocumentFragment(); + fragment.appendChild( div.lastChild ); + + // WebKit doesn't clone checked state correctly in fragments + support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked; + + // Check if a disconnected checkbox will retain its checked + // value of true after appended to the DOM (IE6/7) + support.appendChecked = input.checked; + + fragment.removeChild( input ); + fragment.appendChild( div ); + + // Technique from Juriy Zaytsev + // http://perfectionkills.com/detecting-event-support-without-browser-sniffing/ + // We only care about the case where non-standard event systems + // are used, namely in IE. Short-circuiting here helps us to + // avoid an eval call (in setAttribute) which can cause CSP + // to go haywire. See: https://developer.mozilla.org/en/Security/CSP + if ( div.attachEvent ) { + for ( i in { + submit: 1, + change: 1, + focusin: 1 + }) { + eventName = "on" + i; + isSupported = ( eventName in div ); + if ( !isSupported ) { + div.setAttribute( eventName, "return;" ); + isSupported = ( typeof div[ eventName ] === "function" ); + } + support[ i + "Bubbles" ] = isSupported; + } + } + + fragment.removeChild( div ); + + // Null elements to avoid leaks in IE + fragment = select = opt = div = input = null; + + // Run tests that need a body at doc ready + jQuery(function() { + var container, outer, inner, table, td, offsetSupport, + marginDiv, conMarginTop, style, html, positionTopLeftWidthHeight, + paddingMarginBorderVisibility, paddingMarginBorder, + body = document.getElementsByTagName("body")[0]; + + if ( !body ) { + // Return for frameset docs that don't have a body + return; + } + + conMarginTop = 1; + paddingMarginBorder = "padding:0;margin:0;border:"; + positionTopLeftWidthHeight = "position:absolute;top:0;left:0;width:1px;height:1px;"; + paddingMarginBorderVisibility = paddingMarginBorder + "0;visibility:hidden;"; + style = "style='" + positionTopLeftWidthHeight + paddingMarginBorder + "5px solid #000;"; + html = "
    " + + "" + + "
    "; + + container = document.createElement("div"); + container.style.cssText = paddingMarginBorderVisibility + "width:0;height:0;position:static;top:0;margin-top:" + conMarginTop + "px"; + body.insertBefore( container, body.firstChild ); + + // Construct the test element + div = document.createElement("div"); + container.appendChild( div ); + + // Check if table cells still have offsetWidth/Height when they are set + // to display:none and there are still other visible table cells in a + // table row; if so, offsetWidth/Height are not reliable for use when + // determining if an element has been hidden directly using + // display:none (it is still safe to use offsets if a parent element is + // hidden; don safety goggles and see bug #4512 for more information). + // (only IE 8 fails this test) + div.innerHTML = "
    t
    "; + tds = div.getElementsByTagName( "td" ); + isSupported = ( tds[ 0 ].offsetHeight === 0 ); + + tds[ 0 ].style.display = ""; + tds[ 1 ].style.display = "none"; + + // Check if empty table cells still have offsetWidth/Height + // (IE <= 8 fail this test) + support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 ); + + // Check if div with explicit width and no margin-right incorrectly + // gets computed margin-right based on width of container. For more + // info see bug #3333 + // Fails in WebKit before Feb 2011 nightlies + // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right + if ( window.getComputedStyle ) { + div.innerHTML = ""; + marginDiv = document.createElement( "div" ); + marginDiv.style.width = "0"; + marginDiv.style.marginRight = "0"; + div.style.width = "2px"; + div.appendChild( marginDiv ); + support.reliableMarginRight = + ( parseInt( ( window.getComputedStyle( marginDiv, null ) || { marginRight: 0 } ).marginRight, 10 ) || 0 ) === 0; + } + + if ( typeof div.style.zoom !== "undefined" ) { + // Check if natively block-level elements act like inline-block + // elements when setting their display to 'inline' and giving + // them layout + // (IE < 8 does this) + div.innerHTML = ""; + div.style.width = div.style.padding = "1px"; + div.style.border = 0; + div.style.overflow = "hidden"; + div.style.display = "inline"; + div.style.zoom = 1; + support.inlineBlockNeedsLayout = ( div.offsetWidth === 3 ); + + // Check if elements with layout shrink-wrap their children + // (IE 6 does this) + div.style.display = "block"; + div.style.overflow = "visible"; + div.innerHTML = "
    "; + support.shrinkWrapBlocks = ( div.offsetWidth !== 3 ); + } + + div.style.cssText = positionTopLeftWidthHeight + paddingMarginBorderVisibility; + div.innerHTML = html; + + outer = div.firstChild; + inner = outer.firstChild; + td = outer.nextSibling.firstChild.firstChild; + + offsetSupport = { + doesNotAddBorder: ( inner.offsetTop !== 5 ), + doesAddBorderForTableAndCells: ( td.offsetTop === 5 ) + }; + + inner.style.position = "fixed"; + inner.style.top = "20px"; + + // safari subtracts parent border width here which is 5px + offsetSupport.fixedPosition = ( inner.offsetTop === 20 || inner.offsetTop === 15 ); + inner.style.position = inner.style.top = ""; + + outer.style.overflow = "hidden"; + outer.style.position = "relative"; + + offsetSupport.subtractsBorderForOverflowNotVisible = ( inner.offsetTop === -5 ); + offsetSupport.doesNotIncludeMarginInBodyOffset = ( body.offsetTop !== conMarginTop ); + + if ( window.getComputedStyle ) { + div.style.marginTop = "1%"; + support.pixelMargin = ( window.getComputedStyle( div, null ) || { marginTop: 0 } ).marginTop !== "1%"; + } + + if ( typeof container.style.zoom !== "undefined" ) { + container.style.zoom = 1; + } + + body.removeChild( container ); + marginDiv = div = container = null; + + jQuery.extend( support, offsetSupport ); + }); + + return support; +})(); + + + + +var rbrace = /^(?:\{.*\}|\[.*\])$/, + rmultiDash = /([A-Z])/g; + +jQuery.extend({ + cache: {}, + + // Please use with caution + uuid: 0, + + // Unique for each copy of jQuery on the page + // Non-digits removed to match rinlinejQuery + expando: "jQuery" + ( jQuery.fn.jquery + Math.random() ).replace( /\D/g, "" ), + + // The following elements throw uncatchable exceptions if you + // attempt to add expando properties to them. + noData: { + "embed": true, + // Ban all objects except for Flash (which handle expandos) + "object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000", + "applet": true + }, + + hasData: function( elem ) { + elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ]; + return !!elem && !isEmptyDataObject( elem ); + }, + + data: function( elem, name, data, pvt /* Internal Use Only */ ) { + if ( !jQuery.acceptData( elem ) ) { + return; + } + + var privateCache, thisCache, ret, + internalKey = jQuery.expando, + getByName = typeof name === "string", + + // We have to handle DOM nodes and JS objects differently because IE6-7 + // can't GC object references properly across the DOM-JS boundary + isNode = elem.nodeType, + + // Only DOM nodes need the global jQuery cache; JS object data is + // attached directly to the object so GC can occur automatically + cache = isNode ? jQuery.cache : elem, + + // Only defining an ID for JS objects if its cache already exists allows + // the code to shortcut on the same path as a DOM node with no cache + id = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey, + isEvents = name === "events"; + + // Avoid doing any more work than we need to when trying to get data on an + // object that has no data at all + if ( (!id || !cache[id] || (!isEvents && !pvt && !cache[id].data)) && getByName && data === undefined ) { + return; + } + + if ( !id ) { + // Only DOM nodes need a new unique ID for each element since their data + // ends up in the global cache + if ( isNode ) { + elem[ internalKey ] = id = ++jQuery.uuid; + } else { + id = internalKey; + } + } + + if ( !cache[ id ] ) { + cache[ id ] = {}; + + // Avoids exposing jQuery metadata on plain JS objects when the object + // is serialized using JSON.stringify + if ( !isNode ) { + cache[ id ].toJSON = jQuery.noop; + } + } + + // An object can be passed to jQuery.data instead of a key/value pair; this gets + // shallow copied over onto the existing cache + if ( typeof name === "object" || typeof name === "function" ) { + if ( pvt ) { + cache[ id ] = jQuery.extend( cache[ id ], name ); + } else { + cache[ id ].data = jQuery.extend( cache[ id ].data, name ); + } + } + + privateCache = thisCache = cache[ id ]; + + // jQuery data() is stored in a separate object inside the object's internal data + // cache in order to avoid key collisions between internal data and user-defined + // data. + if ( !pvt ) { + if ( !thisCache.data ) { + thisCache.data = {}; + } + + thisCache = thisCache.data; + } + + if ( data !== undefined ) { + thisCache[ jQuery.camelCase( name ) ] = data; + } + + // Users should not attempt to inspect the internal events object using jQuery.data, + // it is undocumented and subject to change. But does anyone listen? No. + if ( isEvents && !thisCache[ name ] ) { + return privateCache.events; + } + + // Check for both converted-to-camel and non-converted data property names + // If a data property was specified + if ( getByName ) { + + // First Try to find as-is property data + ret = thisCache[ name ]; + + // Test for null|undefined property data + if ( ret == null ) { + + // Try to find the camelCased property + ret = thisCache[ jQuery.camelCase( name ) ]; + } + } else { + ret = thisCache; + } + + return ret; + }, + + removeData: function( elem, name, pvt /* Internal Use Only */ ) { + if ( !jQuery.acceptData( elem ) ) { + return; + } + + var thisCache, i, l, + + // Reference to internal data cache key + internalKey = jQuery.expando, + + isNode = elem.nodeType, + + // See jQuery.data for more information + cache = isNode ? jQuery.cache : elem, + + // See jQuery.data for more information + id = isNode ? elem[ internalKey ] : internalKey; + + // If there is already no cache entry for this object, there is no + // purpose in continuing + if ( !cache[ id ] ) { + return; + } + + if ( name ) { + + thisCache = pvt ? cache[ id ] : cache[ id ].data; + + if ( thisCache ) { + + // Support array or space separated string names for data keys + if ( !jQuery.isArray( name ) ) { + + // try the string as a key before any manipulation + if ( name in thisCache ) { + name = [ name ]; + } else { + + // split the camel cased version by spaces unless a key with the spaces exists + name = jQuery.camelCase( name ); + if ( name in thisCache ) { + name = [ name ]; + } else { + name = name.split( " " ); + } + } + } + + for ( i = 0, l = name.length; i < l; i++ ) { + delete thisCache[ name[i] ]; + } + + // If there is no data left in the cache, we want to continue + // and let the cache object itself get destroyed + if ( !( pvt ? isEmptyDataObject : jQuery.isEmptyObject )( thisCache ) ) { + return; + } + } + } + + // See jQuery.data for more information + if ( !pvt ) { + delete cache[ id ].data; + + // Don't destroy the parent cache unless the internal data object + // had been the only thing left in it + if ( !isEmptyDataObject(cache[ id ]) ) { + return; + } + } + + // Browsers that fail expando deletion also refuse to delete expandos on + // the window, but it will allow it on all other JS objects; other browsers + // don't care + // Ensure that `cache` is not a window object #10080 + if ( jQuery.support.deleteExpando || !cache.setInterval ) { + delete cache[ id ]; + } else { + cache[ id ] = null; + } + + // We destroyed the cache and need to eliminate the expando on the node to avoid + // false lookups in the cache for entries that no longer exist + if ( isNode ) { + // IE does not allow us to delete expando properties from nodes, + // nor does it have a removeAttribute function on Document nodes; + // we must handle all of these cases + if ( jQuery.support.deleteExpando ) { + delete elem[ internalKey ]; + } else if ( elem.removeAttribute ) { + elem.removeAttribute( internalKey ); + } else { + elem[ internalKey ] = null; + } + } + }, + + // For internal use only. + _data: function( elem, name, data ) { + return jQuery.data( elem, name, data, true ); + }, + + // A method for determining if a DOM node can handle the data expando + acceptData: function( elem ) { + if ( elem.nodeName ) { + var match = jQuery.noData[ elem.nodeName.toLowerCase() ]; + + if ( match ) { + return !(match === true || elem.getAttribute("classid") !== match); + } + } + + return true; + } +}); + +jQuery.fn.extend({ + data: function( key, value ) { + var parts, part, attr, name, l, + elem = this[0], + i = 0, + data = null; + + // Gets all values + if ( key === undefined ) { + if ( this.length ) { + data = jQuery.data( elem ); + + if ( elem.nodeType === 1 && !jQuery._data( elem, "parsedAttrs" ) ) { + attr = elem.attributes; + for ( l = attr.length; i < l; i++ ) { + name = attr[i].name; + + if ( name.indexOf( "data-" ) === 0 ) { + name = jQuery.camelCase( name.substring(5) ); + + dataAttr( elem, name, data[ name ] ); + } + } + jQuery._data( elem, "parsedAttrs", true ); + } + } + + return data; + } + + // Sets multiple values + if ( typeof key === "object" ) { + return this.each(function() { + jQuery.data( this, key ); + }); + } + + parts = key.split( ".", 2 ); + parts[1] = parts[1] ? "." + parts[1] : ""; + part = parts[1] + "!"; + + return jQuery.access( this, function( value ) { + + if ( value === undefined ) { + data = this.triggerHandler( "getData" + part, [ parts[0] ] ); + + // Try to fetch any internally stored data first + if ( data === undefined && elem ) { + data = jQuery.data( elem, key ); + data = dataAttr( elem, key, data ); + } + + return data === undefined && parts[1] ? + this.data( parts[0] ) : + data; + } + + parts[1] = value; + this.each(function() { + var self = jQuery( this ); + + self.triggerHandler( "setData" + part, parts ); + jQuery.data( this, key, value ); + self.triggerHandler( "changeData" + part, parts ); + }); + }, null, value, arguments.length > 1, null, false ); + }, + + removeData: function( key ) { + return this.each(function() { + jQuery.removeData( this, key ); + }); + } +}); + +function dataAttr( elem, key, data ) { + // If nothing was found internally, try to fetch any + // data from the HTML5 data-* attribute + if ( data === undefined && elem.nodeType === 1 ) { + + var name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase(); + + data = elem.getAttribute( name ); + + if ( typeof data === "string" ) { + try { + data = data === "true" ? true : + data === "false" ? false : + data === "null" ? null : + jQuery.isNumeric( data ) ? +data : + rbrace.test( data ) ? jQuery.parseJSON( data ) : + data; + } catch( e ) {} + + // Make sure we set the data so it isn't changed later + jQuery.data( elem, key, data ); + + } else { + data = undefined; + } + } + + return data; +} + +// checks a cache object for emptiness +function isEmptyDataObject( obj ) { + for ( var name in obj ) { + + // if the public data object is empty, the private is still empty + if ( name === "data" && jQuery.isEmptyObject( obj[name] ) ) { + continue; + } + if ( name !== "toJSON" ) { + return false; + } + } + + return true; +} + + + + +function handleQueueMarkDefer( elem, type, src ) { + var deferDataKey = type + "defer", + queueDataKey = type + "queue", + markDataKey = type + "mark", + defer = jQuery._data( elem, deferDataKey ); + if ( defer && + ( src === "queue" || !jQuery._data(elem, queueDataKey) ) && + ( src === "mark" || !jQuery._data(elem, markDataKey) ) ) { + // Give room for hard-coded callbacks to fire first + // and eventually mark/queue something else on the element + setTimeout( function() { + if ( !jQuery._data( elem, queueDataKey ) && + !jQuery._data( elem, markDataKey ) ) { + jQuery.removeData( elem, deferDataKey, true ); + defer.fire(); + } + }, 0 ); + } +} + +jQuery.extend({ + + _mark: function( elem, type ) { + if ( elem ) { + type = ( type || "fx" ) + "mark"; + jQuery._data( elem, type, (jQuery._data( elem, type ) || 0) + 1 ); + } + }, + + _unmark: function( force, elem, type ) { + if ( force !== true ) { + type = elem; + elem = force; + force = false; + } + if ( elem ) { + type = type || "fx"; + var key = type + "mark", + count = force ? 0 : ( (jQuery._data( elem, key ) || 1) - 1 ); + if ( count ) { + jQuery._data( elem, key, count ); + } else { + jQuery.removeData( elem, key, true ); + handleQueueMarkDefer( elem, type, "mark" ); + } + } + }, + + queue: function( elem, type, data ) { + var q; + if ( elem ) { + type = ( type || "fx" ) + "queue"; + q = jQuery._data( elem, type ); + + // Speed up dequeue by getting out quickly if this is just a lookup + if ( data ) { + if ( !q || jQuery.isArray(data) ) { + q = jQuery._data( elem, type, jQuery.makeArray(data) ); + } else { + q.push( data ); + } + } + return q || []; + } + }, + + dequeue: function( elem, type ) { + type = type || "fx"; + + var queue = jQuery.queue( elem, type ), + fn = queue.shift(), + hooks = {}; + + // If the fx queue is dequeued, always remove the progress sentinel + if ( fn === "inprogress" ) { + fn = queue.shift(); + } + + if ( fn ) { + // Add a progress sentinel to prevent the fx queue from being + // automatically dequeued + if ( type === "fx" ) { + queue.unshift( "inprogress" ); + } + + jQuery._data( elem, type + ".run", hooks ); + fn.call( elem, function() { + jQuery.dequeue( elem, type ); + }, hooks ); + } + + if ( !queue.length ) { + jQuery.removeData( elem, type + "queue " + type + ".run", true ); + handleQueueMarkDefer( elem, type, "queue" ); + } + } +}); + +jQuery.fn.extend({ + queue: function( type, data ) { + var setter = 2; + + if ( typeof type !== "string" ) { + data = type; + type = "fx"; + setter--; + } + + if ( arguments.length < setter ) { + return jQuery.queue( this[0], type ); + } + + return data === undefined ? + this : + this.each(function() { + var queue = jQuery.queue( this, type, data ); + + if ( type === "fx" && queue[0] !== "inprogress" ) { + jQuery.dequeue( this, type ); + } + }); + }, + dequeue: function( type ) { + return this.each(function() { + jQuery.dequeue( this, type ); + }); + }, + // Based off of the plugin by Clint Helfers, with permission. + // http://blindsignals.com/index.php/2009/07/jquery-delay/ + delay: function( time, type ) { + time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time; + type = type || "fx"; + + return this.queue( type, function( next, hooks ) { + var timeout = setTimeout( next, time ); + hooks.stop = function() { + clearTimeout( timeout ); + }; + }); + }, + clearQueue: function( type ) { + return this.queue( type || "fx", [] ); + }, + // Get a promise resolved when queues of a certain type + // are emptied (fx is the type by default) + promise: function( type, object ) { + if ( typeof type !== "string" ) { + object = type; + type = undefined; + } + type = type || "fx"; + var defer = jQuery.Deferred(), + elements = this, + i = elements.length, + count = 1, + deferDataKey = type + "defer", + queueDataKey = type + "queue", + markDataKey = type + "mark", + tmp; + function resolve() { + if ( !( --count ) ) { + defer.resolveWith( elements, [ elements ] ); + } + } + while( i-- ) { + if (( tmp = jQuery.data( elements[ i ], deferDataKey, undefined, true ) || + ( jQuery.data( elements[ i ], queueDataKey, undefined, true ) || + jQuery.data( elements[ i ], markDataKey, undefined, true ) ) && + jQuery.data( elements[ i ], deferDataKey, jQuery.Callbacks( "once memory" ), true ) )) { + count++; + tmp.add( resolve ); + } + } + resolve(); + return defer.promise( object ); + } +}); + + + + +var rclass = /[\n\t\r]/g, + rspace = /\s+/, + rreturn = /\r/g, + rtype = /^(?:button|input)$/i, + rfocusable = /^(?:button|input|object|select|textarea)$/i, + rclickable = /^a(?:rea)?$/i, + rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i, + getSetAttribute = jQuery.support.getSetAttribute, + nodeHook, boolHook, fixSpecified; + +jQuery.fn.extend({ + attr: function( name, value ) { + return jQuery.access( this, jQuery.attr, name, value, arguments.length > 1 ); + }, + + removeAttr: function( name ) { + return this.each(function() { + jQuery.removeAttr( this, name ); + }); + }, + + prop: function( name, value ) { + return jQuery.access( this, jQuery.prop, name, value, arguments.length > 1 ); + }, + + removeProp: function( name ) { + name = jQuery.propFix[ name ] || name; + return this.each(function() { + // try/catch handles cases where IE balks (such as removing a property on window) + try { + this[ name ] = undefined; + delete this[ name ]; + } catch( e ) {} + }); + }, + + addClass: function( value ) { + var classNames, i, l, elem, + setClass, c, cl; + + if ( jQuery.isFunction( value ) ) { + return this.each(function( j ) { + jQuery( this ).addClass( value.call(this, j, this.className) ); + }); + } + + if ( value && typeof value === "string" ) { + classNames = value.split( rspace ); + + for ( i = 0, l = this.length; i < l; i++ ) { + elem = this[ i ]; + + if ( elem.nodeType === 1 ) { + if ( !elem.className && classNames.length === 1 ) { + elem.className = value; + + } else { + setClass = " " + elem.className + " "; + + for ( c = 0, cl = classNames.length; c < cl; c++ ) { + if ( !~setClass.indexOf( " " + classNames[ c ] + " " ) ) { + setClass += classNames[ c ] + " "; + } + } + elem.className = jQuery.trim( setClass ); + } + } + } + } + + return this; + }, + + removeClass: function( value ) { + var classNames, i, l, elem, className, c, cl; + + if ( jQuery.isFunction( value ) ) { + return this.each(function( j ) { + jQuery( this ).removeClass( value.call(this, j, this.className) ); + }); + } + + if ( (value && typeof value === "string") || value === undefined ) { + classNames = ( value || "" ).split( rspace ); + + for ( i = 0, l = this.length; i < l; i++ ) { + elem = this[ i ]; + + if ( elem.nodeType === 1 && elem.className ) { + if ( value ) { + className = (" " + elem.className + " ").replace( rclass, " " ); + for ( c = 0, cl = classNames.length; c < cl; c++ ) { + className = className.replace(" " + classNames[ c ] + " ", " "); + } + elem.className = jQuery.trim( className ); + + } else { + elem.className = ""; + } + } + } + } + + return this; + }, + + toggleClass: function( value, stateVal ) { + var type = typeof value, + isBool = typeof stateVal === "boolean"; + + if ( jQuery.isFunction( value ) ) { + return this.each(function( i ) { + jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal ); + }); + } + + return this.each(function() { + if ( type === "string" ) { + // toggle individual class names + var className, + i = 0, + self = jQuery( this ), + state = stateVal, + classNames = value.split( rspace ); + + while ( (className = classNames[ i++ ]) ) { + // check each className given, space seperated list + state = isBool ? state : !self.hasClass( className ); + self[ state ? "addClass" : "removeClass" ]( className ); + } + + } else if ( type === "undefined" || type === "boolean" ) { + if ( this.className ) { + // store className if set + jQuery._data( this, "__className__", this.className ); + } + + // toggle whole className + this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || ""; + } + }); + }, + + hasClass: function( selector ) { + var className = " " + selector + " ", + i = 0, + l = this.length; + for ( ; i < l; i++ ) { + if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) { + return true; + } + } + + return false; + }, + + val: function( value ) { + var hooks, ret, isFunction, + elem = this[0]; + + if ( !arguments.length ) { + if ( elem ) { + hooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ]; + + if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) { + return ret; + } + + ret = elem.value; + + return typeof ret === "string" ? + // handle most common string cases + ret.replace(rreturn, "") : + // handle cases where value is null/undef or number + ret == null ? "" : ret; + } + + return; + } + + isFunction = jQuery.isFunction( value ); + + return this.each(function( i ) { + var self = jQuery(this), val; + + if ( this.nodeType !== 1 ) { + return; + } + + if ( isFunction ) { + val = value.call( this, i, self.val() ); + } else { + val = value; + } + + // Treat null/undefined as ""; convert numbers to string + if ( val == null ) { + val = ""; + } else if ( typeof val === "number" ) { + val += ""; + } else if ( jQuery.isArray( val ) ) { + val = jQuery.map(val, function ( value ) { + return value == null ? "" : value + ""; + }); + } + + hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ]; + + // If set returns undefined, fall back to normal setting + if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) { + this.value = val; + } + }); + } +}); + +jQuery.extend({ + valHooks: { + option: { + get: function( elem ) { + // attributes.value is undefined in Blackberry 4.7 but + // uses .value. See #6932 + var val = elem.attributes.value; + return !val || val.specified ? elem.value : elem.text; + } + }, + select: { + get: function( elem ) { + var value, i, max, option, + index = elem.selectedIndex, + values = [], + options = elem.options, + one = elem.type === "select-one"; + + // Nothing was selected + if ( index < 0 ) { + return null; + } + + // Loop through all the selected options + i = one ? index : 0; + max = one ? index + 1 : options.length; + for ( ; i < max; i++ ) { + option = options[ i ]; + + // Don't return options that are disabled or in a disabled optgroup + if ( option.selected && (jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null) && + (!option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" )) ) { + + // Get the specific value for the option + value = jQuery( option ).val(); + + // We don't need an array for one selects + if ( one ) { + return value; + } + + // Multi-Selects return an array + values.push( value ); + } + } + + // Fixes Bug #2551 -- select.val() broken in IE after form.reset() + if ( one && !values.length && options.length ) { + return jQuery( options[ index ] ).val(); + } + + return values; + }, + + set: function( elem, value ) { + var values = jQuery.makeArray( value ); + + jQuery(elem).find("option").each(function() { + this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0; + }); + + if ( !values.length ) { + elem.selectedIndex = -1; + } + return values; + } + } + }, + + attrFn: { + val: true, + css: true, + html: true, + text: true, + data: true, + width: true, + height: true, + offset: true + }, + + attr: function( elem, name, value, pass ) { + var ret, hooks, notxml, + nType = elem.nodeType; + + // don't get/set attributes on text, comment and attribute nodes + if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + if ( pass && name in jQuery.attrFn ) { + return jQuery( elem )[ name ]( value ); + } + + // Fallback to prop when attributes are not supported + if ( typeof elem.getAttribute === "undefined" ) { + return jQuery.prop( elem, name, value ); + } + + notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); + + // All attributes are lowercase + // Grab necessary hook if one is defined + if ( notxml ) { + name = name.toLowerCase(); + hooks = jQuery.attrHooks[ name ] || ( rboolean.test( name ) ? boolHook : nodeHook ); + } + + if ( value !== undefined ) { + + if ( value === null ) { + jQuery.removeAttr( elem, name ); + return; + + } else if ( hooks && "set" in hooks && notxml && (ret = hooks.set( elem, value, name )) !== undefined ) { + return ret; + + } else { + elem.setAttribute( name, "" + value ); + return value; + } + + } else if ( hooks && "get" in hooks && notxml && (ret = hooks.get( elem, name )) !== null ) { + return ret; + + } else { + + ret = elem.getAttribute( name ); + + // Non-existent attributes return null, we normalize to undefined + return ret === null ? + undefined : + ret; + } + }, + + removeAttr: function( elem, value ) { + var propName, attrNames, name, l, isBool, + i = 0; + + if ( value && elem.nodeType === 1 ) { + attrNames = value.toLowerCase().split( rspace ); + l = attrNames.length; + + for ( ; i < l; i++ ) { + name = attrNames[ i ]; + + if ( name ) { + propName = jQuery.propFix[ name ] || name; + isBool = rboolean.test( name ); + + // See #9699 for explanation of this approach (setting first, then removal) + // Do not do this for boolean attributes (see #10870) + if ( !isBool ) { + jQuery.attr( elem, name, "" ); + } + elem.removeAttribute( getSetAttribute ? name : propName ); + + // Set corresponding property to false for boolean attributes + if ( isBool && propName in elem ) { + elem[ propName ] = false; + } + } + } + } + }, + + attrHooks: { + type: { + set: function( elem, value ) { + // We can't allow the type property to be changed (since it causes problems in IE) + if ( rtype.test( elem.nodeName ) && elem.parentNode ) { + jQuery.error( "type property can't be changed" ); + } else if ( !jQuery.support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) { + // Setting the type on a radio button after the value resets the value in IE6-9 + // Reset value to it's default in case type is set after value + // This is for element creation + var val = elem.value; + elem.setAttribute( "type", value ); + if ( val ) { + elem.value = val; + } + return value; + } + } + }, + // Use the value property for back compat + // Use the nodeHook for button elements in IE6/7 (#1954) + value: { + get: function( elem, name ) { + if ( nodeHook && jQuery.nodeName( elem, "button" ) ) { + return nodeHook.get( elem, name ); + } + return name in elem ? + elem.value : + null; + }, + set: function( elem, value, name ) { + if ( nodeHook && jQuery.nodeName( elem, "button" ) ) { + return nodeHook.set( elem, value, name ); + } + // Does not return so that setAttribute is also used + elem.value = value; + } + } + }, + + propFix: { + tabindex: "tabIndex", + readonly: "readOnly", + "for": "htmlFor", + "class": "className", + maxlength: "maxLength", + cellspacing: "cellSpacing", + cellpadding: "cellPadding", + rowspan: "rowSpan", + colspan: "colSpan", + usemap: "useMap", + frameborder: "frameBorder", + contenteditable: "contentEditable" + }, + + prop: function( elem, name, value ) { + var ret, hooks, notxml, + nType = elem.nodeType; + + // don't get/set properties on text, comment and attribute nodes + if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); + + if ( notxml ) { + // Fix name and attach hooks + name = jQuery.propFix[ name ] || name; + hooks = jQuery.propHooks[ name ]; + } + + if ( value !== undefined ) { + if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) { + return ret; + + } else { + return ( elem[ name ] = value ); + } + + } else { + if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) { + return ret; + + } else { + return elem[ name ]; + } + } + }, + + propHooks: { + tabIndex: { + get: function( elem ) { + // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set + // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ + var attributeNode = elem.getAttributeNode("tabindex"); + + return attributeNode && attributeNode.specified ? + parseInt( attributeNode.value, 10 ) : + rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ? + 0 : + undefined; + } + } + } +}); + +// Add the tabIndex propHook to attrHooks for back-compat (different case is intentional) +jQuery.attrHooks.tabindex = jQuery.propHooks.tabIndex; + +// Hook for boolean attributes +boolHook = { + get: function( elem, name ) { + // Align boolean attributes with corresponding properties + // Fall back to attribute presence where some booleans are not supported + var attrNode, + property = jQuery.prop( elem, name ); + return property === true || typeof property !== "boolean" && ( attrNode = elem.getAttributeNode(name) ) && attrNode.nodeValue !== false ? + name.toLowerCase() : + undefined; + }, + set: function( elem, value, name ) { + var propName; + if ( value === false ) { + // Remove boolean attributes when set to false + jQuery.removeAttr( elem, name ); + } else { + // value is true since we know at this point it's type boolean and not false + // Set boolean attributes to the same name and set the DOM property + propName = jQuery.propFix[ name ] || name; + if ( propName in elem ) { + // Only set the IDL specifically if it already exists on the element + elem[ propName ] = true; + } + + elem.setAttribute( name, name.toLowerCase() ); + } + return name; + } +}; + +// IE6/7 do not support getting/setting some attributes with get/setAttribute +if ( !getSetAttribute ) { + + fixSpecified = { + name: true, + id: true, + coords: true + }; + + // Use this for any attribute in IE6/7 + // This fixes almost every IE6/7 issue + nodeHook = jQuery.valHooks.button = { + get: function( elem, name ) { + var ret; + ret = elem.getAttributeNode( name ); + return ret && ( fixSpecified[ name ] ? ret.nodeValue !== "" : ret.specified ) ? + ret.nodeValue : + undefined; + }, + set: function( elem, value, name ) { + // Set the existing or create a new attribute node + var ret = elem.getAttributeNode( name ); + if ( !ret ) { + ret = document.createAttribute( name ); + elem.setAttributeNode( ret ); + } + return ( ret.nodeValue = value + "" ); + } + }; + + // Apply the nodeHook to tabindex + jQuery.attrHooks.tabindex.set = nodeHook.set; + + // Set width and height to auto instead of 0 on empty string( Bug #8150 ) + // This is for removals + jQuery.each([ "width", "height" ], function( i, name ) { + jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], { + set: function( elem, value ) { + if ( value === "" ) { + elem.setAttribute( name, "auto" ); + return value; + } + } + }); + }); + + // Set contenteditable to false on removals(#10429) + // Setting to empty string throws an error as an invalid value + jQuery.attrHooks.contenteditable = { + get: nodeHook.get, + set: function( elem, value, name ) { + if ( value === "" ) { + value = "false"; + } + nodeHook.set( elem, value, name ); + } + }; +} + + +// Some attributes require a special call on IE +if ( !jQuery.support.hrefNormalized ) { + jQuery.each([ "href", "src", "width", "height" ], function( i, name ) { + jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], { + get: function( elem ) { + var ret = elem.getAttribute( name, 2 ); + return ret === null ? undefined : ret; + } + }); + }); +} + +if ( !jQuery.support.style ) { + jQuery.attrHooks.style = { + get: function( elem ) { + // Return undefined in the case of empty string + // Normalize to lowercase since IE uppercases css property names + return elem.style.cssText.toLowerCase() || undefined; + }, + set: function( elem, value ) { + return ( elem.style.cssText = "" + value ); + } + }; +} + +// Safari mis-reports the default selected property of an option +// Accessing the parent's selectedIndex property fixes it +if ( !jQuery.support.optSelected ) { + jQuery.propHooks.selected = jQuery.extend( jQuery.propHooks.selected, { + get: function( elem ) { + var parent = elem.parentNode; + + if ( parent ) { + parent.selectedIndex; + + // Make sure that it also works with optgroups, see #5701 + if ( parent.parentNode ) { + parent.parentNode.selectedIndex; + } + } + return null; + } + }); +} + +// IE6/7 call enctype encoding +if ( !jQuery.support.enctype ) { + jQuery.propFix.enctype = "encoding"; +} + +// Radios and checkboxes getter/setter +if ( !jQuery.support.checkOn ) { + jQuery.each([ "radio", "checkbox" ], function() { + jQuery.valHooks[ this ] = { + get: function( elem ) { + // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified + return elem.getAttribute("value") === null ? "on" : elem.value; + } + }; + }); +} +jQuery.each([ "radio", "checkbox" ], function() { + jQuery.valHooks[ this ] = jQuery.extend( jQuery.valHooks[ this ], { + set: function( elem, value ) { + if ( jQuery.isArray( value ) ) { + return ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 ); + } + } + }); +}); + + + + +var rformElems = /^(?:textarea|input|select)$/i, + rtypenamespace = /^([^\.]*)?(?:\.(.+))?$/, + rhoverHack = /(?:^|\s)hover(\.\S+)?\b/, + rkeyEvent = /^key/, + rmouseEvent = /^(?:mouse|contextmenu)|click/, + rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, + rquickIs = /^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/, + quickParse = function( selector ) { + var quick = rquickIs.exec( selector ); + if ( quick ) { + // 0 1 2 3 + // [ _, tag, id, class ] + quick[1] = ( quick[1] || "" ).toLowerCase(); + quick[3] = quick[3] && new RegExp( "(?:^|\\s)" + quick[3] + "(?:\\s|$)" ); + } + return quick; + }, + quickIs = function( elem, m ) { + var attrs = elem.attributes || {}; + return ( + (!m[1] || elem.nodeName.toLowerCase() === m[1]) && + (!m[2] || (attrs.id || {}).value === m[2]) && + (!m[3] || m[3].test( (attrs[ "class" ] || {}).value )) + ); + }, + hoverHack = function( events ) { + return jQuery.event.special.hover ? events : events.replace( rhoverHack, "mouseenter$1 mouseleave$1" ); + }; + +/* + * Helper functions for managing events -- not part of the public interface. + * Props to Dean Edwards' addEvent library for many of the ideas. + */ +jQuery.event = { + + add: function( elem, types, handler, data, selector ) { + + var elemData, eventHandle, events, + t, tns, type, namespaces, handleObj, + handleObjIn, quick, handlers, special; + + // Don't attach events to noData or text/comment nodes (allow plain objects tho) + if ( elem.nodeType === 3 || elem.nodeType === 8 || !types || !handler || !(elemData = jQuery._data( elem )) ) { + return; + } + + // Caller can pass in an object of custom data in lieu of the handler + if ( handler.handler ) { + handleObjIn = handler; + handler = handleObjIn.handler; + selector = handleObjIn.selector; + } + + // Make sure that the handler has a unique ID, used to find/remove it later + if ( !handler.guid ) { + handler.guid = jQuery.guid++; + } + + // Init the element's event structure and main handler, if this is the first + events = elemData.events; + if ( !events ) { + elemData.events = events = {}; + } + eventHandle = elemData.handle; + if ( !eventHandle ) { + elemData.handle = eventHandle = function( e ) { + // Discard the second event of a jQuery.event.trigger() and + // when an event is called after a page has unloaded + return typeof jQuery !== "undefined" && (!e || jQuery.event.triggered !== e.type) ? + jQuery.event.dispatch.apply( eventHandle.elem, arguments ) : + undefined; + }; + // Add elem as a property of the handle fn to prevent a memory leak with IE non-native events + eventHandle.elem = elem; + } + + // Handle multiple events separated by a space + // jQuery(...).bind("mouseover mouseout", fn); + types = jQuery.trim( hoverHack(types) ).split( " " ); + for ( t = 0; t < types.length; t++ ) { + + tns = rtypenamespace.exec( types[t] ) || []; + type = tns[1]; + namespaces = ( tns[2] || "" ).split( "." ).sort(); + + // If event changes its type, use the special event handlers for the changed type + special = jQuery.event.special[ type ] || {}; + + // If selector defined, determine special event api type, otherwise given type + type = ( selector ? special.delegateType : special.bindType ) || type; + + // Update special based on newly reset type + special = jQuery.event.special[ type ] || {}; + + // handleObj is passed to all event handlers + handleObj = jQuery.extend({ + type: type, + origType: tns[1], + data: data, + handler: handler, + guid: handler.guid, + selector: selector, + quick: selector && quickParse( selector ), + namespace: namespaces.join(".") + }, handleObjIn ); + + // Init the event handler queue if we're the first + handlers = events[ type ]; + if ( !handlers ) { + handlers = events[ type ] = []; + handlers.delegateCount = 0; + + // Only use addEventListener/attachEvent if the special events handler returns false + if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) { + // Bind the global event handler to the element + if ( elem.addEventListener ) { + elem.addEventListener( type, eventHandle, false ); + + } else if ( elem.attachEvent ) { + elem.attachEvent( "on" + type, eventHandle ); + } + } + } + + if ( special.add ) { + special.add.call( elem, handleObj ); + + if ( !handleObj.handler.guid ) { + handleObj.handler.guid = handler.guid; + } + } + + // Add to the element's handler list, delegates in front + if ( selector ) { + handlers.splice( handlers.delegateCount++, 0, handleObj ); + } else { + handlers.push( handleObj ); + } + + // Keep track of which events have ever been used, for event optimization + jQuery.event.global[ type ] = true; + } + + // Nullify elem to prevent memory leaks in IE + elem = null; + }, + + global: {}, + + // Detach an event or set of events from an element + remove: function( elem, types, handler, selector, mappedTypes ) { + + var elemData = jQuery.hasData( elem ) && jQuery._data( elem ), + t, tns, type, origType, namespaces, origCount, + j, events, special, handle, eventType, handleObj; + + if ( !elemData || !(events = elemData.events) ) { + return; + } + + // Once for each type.namespace in types; type may be omitted + types = jQuery.trim( hoverHack( types || "" ) ).split(" "); + for ( t = 0; t < types.length; t++ ) { + tns = rtypenamespace.exec( types[t] ) || []; + type = origType = tns[1]; + namespaces = tns[2]; + + // Unbind all events (on this namespace, if provided) for the element + if ( !type ) { + for ( type in events ) { + jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); + } + continue; + } + + special = jQuery.event.special[ type ] || {}; + type = ( selector? special.delegateType : special.bindType ) || type; + eventType = events[ type ] || []; + origCount = eventType.length; + namespaces = namespaces ? new RegExp("(^|\\.)" + namespaces.split(".").sort().join("\\.(?:.*\\.)?") + "(\\.|$)") : null; + + // Remove matching events + for ( j = 0; j < eventType.length; j++ ) { + handleObj = eventType[ j ]; + + if ( ( mappedTypes || origType === handleObj.origType ) && + ( !handler || handler.guid === handleObj.guid ) && + ( !namespaces || namespaces.test( handleObj.namespace ) ) && + ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) { + eventType.splice( j--, 1 ); + + if ( handleObj.selector ) { + eventType.delegateCount--; + } + if ( special.remove ) { + special.remove.call( elem, handleObj ); + } + } + } + + // Remove generic event handler if we removed something and no more handlers exist + // (avoids potential for endless recursion during removal of special event handlers) + if ( eventType.length === 0 && origCount !== eventType.length ) { + if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) { + jQuery.removeEvent( elem, type, elemData.handle ); + } + + delete events[ type ]; + } + } + + // Remove the expando if it's no longer used + if ( jQuery.isEmptyObject( events ) ) { + handle = elemData.handle; + if ( handle ) { + handle.elem = null; + } + + // removeData also checks for emptiness and clears the expando if empty + // so use it instead of delete + jQuery.removeData( elem, [ "events", "handle" ], true ); + } + }, + + // Events that are safe to short-circuit if no handlers are attached. + // Native DOM events should not be added, they may have inline handlers. + customEvent: { + "getData": true, + "setData": true, + "changeData": true + }, + + trigger: function( event, data, elem, onlyHandlers ) { + // Don't do events on text and comment nodes + if ( elem && (elem.nodeType === 3 || elem.nodeType === 8) ) { + return; + } + + // Event object or event type + var type = event.type || event, + namespaces = [], + cache, exclusive, i, cur, old, ontype, special, handle, eventPath, bubbleType; + + // focus/blur morphs to focusin/out; ensure we're not firing them right now + if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { + return; + } + + if ( type.indexOf( "!" ) >= 0 ) { + // Exclusive events trigger only for the exact event (no namespaces) + type = type.slice(0, -1); + exclusive = true; + } + + if ( type.indexOf( "." ) >= 0 ) { + // Namespaced trigger; create a regexp to match event type in handle() + namespaces = type.split("."); + type = namespaces.shift(); + namespaces.sort(); + } + + if ( (!elem || jQuery.event.customEvent[ type ]) && !jQuery.event.global[ type ] ) { + // No jQuery handlers for this event type, and it can't have inline handlers + return; + } + + // Caller can pass in an Event, Object, or just an event type string + event = typeof event === "object" ? + // jQuery.Event object + event[ jQuery.expando ] ? event : + // Object literal + new jQuery.Event( type, event ) : + // Just the event type (string) + new jQuery.Event( type ); + + event.type = type; + event.isTrigger = true; + event.exclusive = exclusive; + event.namespace = namespaces.join( "." ); + event.namespace_re = event.namespace? new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.)?") + "(\\.|$)") : null; + ontype = type.indexOf( ":" ) < 0 ? "on" + type : ""; + + // Handle a global trigger + if ( !elem ) { + + // TODO: Stop taunting the data cache; remove global events and always attach to document + cache = jQuery.cache; + for ( i in cache ) { + if ( cache[ i ].events && cache[ i ].events[ type ] ) { + jQuery.event.trigger( event, data, cache[ i ].handle.elem, true ); + } + } + return; + } + + // Clean up the event in case it is being reused + event.result = undefined; + if ( !event.target ) { + event.target = elem; + } + + // Clone any incoming data and prepend the event, creating the handler arg list + data = data != null ? jQuery.makeArray( data ) : []; + data.unshift( event ); + + // Allow special events to draw outside the lines + special = jQuery.event.special[ type ] || {}; + if ( special.trigger && special.trigger.apply( elem, data ) === false ) { + return; + } + + // Determine event propagation path in advance, per W3C events spec (#9951) + // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) + eventPath = [[ elem, special.bindType || type ]]; + if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) { + + bubbleType = special.delegateType || type; + cur = rfocusMorph.test( bubbleType + type ) ? elem : elem.parentNode; + old = null; + for ( ; cur; cur = cur.parentNode ) { + eventPath.push([ cur, bubbleType ]); + old = cur; + } + + // Only add window if we got to document (e.g., not plain obj or detached DOM) + if ( old && old === elem.ownerDocument ) { + eventPath.push([ old.defaultView || old.parentWindow || window, bubbleType ]); + } + } + + // Fire handlers on the event path + for ( i = 0; i < eventPath.length && !event.isPropagationStopped(); i++ ) { + + cur = eventPath[i][0]; + event.type = eventPath[i][1]; + + handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] && jQuery._data( cur, "handle" ); + if ( handle ) { + handle.apply( cur, data ); + } + // Note that this is a bare JS function and not a jQuery handler + handle = ontype && cur[ ontype ]; + if ( handle && jQuery.acceptData( cur ) && handle.apply( cur, data ) === false ) { + event.preventDefault(); + } + } + event.type = type; + + // If nobody prevented the default action, do it now + if ( !onlyHandlers && !event.isDefaultPrevented() ) { + + if ( (!special._default || special._default.apply( elem.ownerDocument, data ) === false) && + !(type === "click" && jQuery.nodeName( elem, "a" )) && jQuery.acceptData( elem ) ) { + + // Call a native DOM method on the target with the same name name as the event. + // Can't use an .isFunction() check here because IE6/7 fails that test. + // Don't do default actions on window, that's where global variables be (#6170) + // IE<9 dies on focus/blur to hidden element (#1486) + if ( ontype && elem[ type ] && ((type !== "focus" && type !== "blur") || event.target.offsetWidth !== 0) && !jQuery.isWindow( elem ) ) { + + // Don't re-trigger an onFOO event when we call its FOO() method + old = elem[ ontype ]; + + if ( old ) { + elem[ ontype ] = null; + } + + // Prevent re-triggering of the same event, since we already bubbled it above + jQuery.event.triggered = type; + elem[ type ](); + jQuery.event.triggered = undefined; + + if ( old ) { + elem[ ontype ] = old; + } + } + } + } + + return event.result; + }, + + dispatch: function( event ) { + + // Make a writable jQuery.Event from the native event object + event = jQuery.event.fix( event || window.event ); + + var handlers = ( (jQuery._data( this, "events" ) || {} )[ event.type ] || []), + delegateCount = handlers.delegateCount, + args = [].slice.call( arguments, 0 ), + run_all = !event.exclusive && !event.namespace, + special = jQuery.event.special[ event.type ] || {}, + handlerQueue = [], + i, j, cur, jqcur, ret, selMatch, matched, matches, handleObj, sel, related; + + // Use the fix-ed jQuery.Event rather than the (read-only) native event + args[0] = event; + event.delegateTarget = this; + + // Call the preDispatch hook for the mapped type, and let it bail if desired + if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { + return; + } + + // Determine handlers that should run if there are delegated events + // Avoid non-left-click bubbling in Firefox (#3861) + if ( delegateCount && !(event.button && event.type === "click") ) { + + // Pregenerate a single jQuery object for reuse with .is() + jqcur = jQuery(this); + jqcur.context = this.ownerDocument || this; + + for ( cur = event.target; cur != this; cur = cur.parentNode || this ) { + + // Don't process events on disabled elements (#6911, #8165) + if ( cur.disabled !== true ) { + selMatch = {}; + matches = []; + jqcur[0] = cur; + for ( i = 0; i < delegateCount; i++ ) { + handleObj = handlers[ i ]; + sel = handleObj.selector; + + if ( selMatch[ sel ] === undefined ) { + selMatch[ sel ] = ( + handleObj.quick ? quickIs( cur, handleObj.quick ) : jqcur.is( sel ) + ); + } + if ( selMatch[ sel ] ) { + matches.push( handleObj ); + } + } + if ( matches.length ) { + handlerQueue.push({ elem: cur, matches: matches }); + } + } + } + } + + // Add the remaining (directly-bound) handlers + if ( handlers.length > delegateCount ) { + handlerQueue.push({ elem: this, matches: handlers.slice( delegateCount ) }); + } + + // Run delegates first; they may want to stop propagation beneath us + for ( i = 0; i < handlerQueue.length && !event.isPropagationStopped(); i++ ) { + matched = handlerQueue[ i ]; + event.currentTarget = matched.elem; + + for ( j = 0; j < matched.matches.length && !event.isImmediatePropagationStopped(); j++ ) { + handleObj = matched.matches[ j ]; + + // Triggered event must either 1) be non-exclusive and have no namespace, or + // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace). + if ( run_all || (!event.namespace && !handleObj.namespace) || event.namespace_re && event.namespace_re.test( handleObj.namespace ) ) { + + event.data = handleObj.data; + event.handleObj = handleObj; + + ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler ) + .apply( matched.elem, args ); + + if ( ret !== undefined ) { + event.result = ret; + if ( ret === false ) { + event.preventDefault(); + event.stopPropagation(); + } + } + } + } + } + + // Call the postDispatch hook for the mapped type + if ( special.postDispatch ) { + special.postDispatch.call( this, event ); + } + + return event.result; + }, + + // Includes some event props shared by KeyEvent and MouseEvent + // *** attrChange attrName relatedNode srcElement are not normalized, non-W3C, deprecated, will be removed in 1.8 *** + props: "attrChange attrName relatedNode srcElement altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "), + + fixHooks: {}, + + keyHooks: { + props: "char charCode key keyCode".split(" "), + filter: function( event, original ) { + + // Add which for key events + if ( event.which == null ) { + event.which = original.charCode != null ? original.charCode : original.keyCode; + } + + return event; + } + }, + + mouseHooks: { + props: "button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "), + filter: function( event, original ) { + var eventDoc, doc, body, + button = original.button, + fromElement = original.fromElement; + + // Calculate pageX/Y if missing and clientX/Y available + if ( event.pageX == null && original.clientX != null ) { + eventDoc = event.target.ownerDocument || document; + doc = eventDoc.documentElement; + body = eventDoc.body; + + event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 ); + event.pageY = original.clientY + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - ( doc && doc.clientTop || body && body.clientTop || 0 ); + } + + // Add relatedTarget, if necessary + if ( !event.relatedTarget && fromElement ) { + event.relatedTarget = fromElement === event.target ? original.toElement : fromElement; + } + + // Add which for click: 1 === left; 2 === middle; 3 === right + // Note: button is not normalized, so don't use it + if ( !event.which && button !== undefined ) { + event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) ); + } + + return event; + } + }, + + fix: function( event ) { + if ( event[ jQuery.expando ] ) { + return event; + } + + // Create a writable copy of the event object and normalize some properties + var i, prop, + originalEvent = event, + fixHook = jQuery.event.fixHooks[ event.type ] || {}, + copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props; + + event = jQuery.Event( originalEvent ); + + for ( i = copy.length; i; ) { + prop = copy[ --i ]; + event[ prop ] = originalEvent[ prop ]; + } + + // Fix target property, if necessary (#1925, IE 6/7/8 & Safari2) + if ( !event.target ) { + event.target = originalEvent.srcElement || document; + } + + // Target should not be a text node (#504, Safari) + if ( event.target.nodeType === 3 ) { + event.target = event.target.parentNode; + } + + // For mouse/key events; add metaKey if it's not there (#3368, IE6/7/8) + if ( event.metaKey === undefined ) { + event.metaKey = event.ctrlKey; + } + + return fixHook.filter? fixHook.filter( event, originalEvent ) : event; + }, + + special: { + ready: { + // Make sure the ready event is setup + setup: jQuery.bindReady + }, + + load: { + // Prevent triggered image.load events from bubbling to window.load + noBubble: true + }, + + focus: { + delegateType: "focusin" + }, + blur: { + delegateType: "focusout" + }, + + beforeunload: { + setup: function( data, namespaces, eventHandle ) { + // We only want to do this special case on windows + if ( jQuery.isWindow( this ) ) { + this.onbeforeunload = eventHandle; + } + }, + + teardown: function( namespaces, eventHandle ) { + if ( this.onbeforeunload === eventHandle ) { + this.onbeforeunload = null; + } + } + } + }, + + simulate: function( type, elem, event, bubble ) { + // Piggyback on a donor event to simulate a different one. + // Fake originalEvent to avoid donor's stopPropagation, but if the + // simulated event prevents default then we do the same on the donor. + var e = jQuery.extend( + new jQuery.Event(), + event, + { type: type, + isSimulated: true, + originalEvent: {} + } + ); + if ( bubble ) { + jQuery.event.trigger( e, null, elem ); + } else { + jQuery.event.dispatch.call( elem, e ); + } + if ( e.isDefaultPrevented() ) { + event.preventDefault(); + } + } +}; + +// Some plugins are using, but it's undocumented/deprecated and will be removed. +// The 1.7 special event interface should provide all the hooks needed now. +jQuery.event.handle = jQuery.event.dispatch; + +jQuery.removeEvent = document.removeEventListener ? + function( elem, type, handle ) { + if ( elem.removeEventListener ) { + elem.removeEventListener( type, handle, false ); + } + } : + function( elem, type, handle ) { + if ( elem.detachEvent ) { + elem.detachEvent( "on" + type, handle ); + } + }; + +jQuery.Event = function( src, props ) { + // Allow instantiation without the 'new' keyword + if ( !(this instanceof jQuery.Event) ) { + return new jQuery.Event( src, props ); + } + + // Event object + if ( src && src.type ) { + this.originalEvent = src; + this.type = src.type; + + // Events bubbling up the document may have been marked as prevented + // by a handler lower down the tree; reflect the correct value. + this.isDefaultPrevented = ( src.defaultPrevented || src.returnValue === false || + src.getPreventDefault && src.getPreventDefault() ) ? returnTrue : returnFalse; + + // Event type + } else { + this.type = src; + } + + // Put explicitly provided properties onto the event object + if ( props ) { + jQuery.extend( this, props ); + } + + // Create a timestamp if incoming event doesn't have one + this.timeStamp = src && src.timeStamp || jQuery.now(); + + // Mark it as fixed + this[ jQuery.expando ] = true; +}; + +function returnFalse() { + return false; +} +function returnTrue() { + return true; +} + +// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding +// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html +jQuery.Event.prototype = { + preventDefault: function() { + this.isDefaultPrevented = returnTrue; + + var e = this.originalEvent; + if ( !e ) { + return; + } + + // if preventDefault exists run it on the original event + if ( e.preventDefault ) { + e.preventDefault(); + + // otherwise set the returnValue property of the original event to false (IE) + } else { + e.returnValue = false; + } + }, + stopPropagation: function() { + this.isPropagationStopped = returnTrue; + + var e = this.originalEvent; + if ( !e ) { + return; + } + // if stopPropagation exists run it on the original event + if ( e.stopPropagation ) { + e.stopPropagation(); + } + // otherwise set the cancelBubble property of the original event to true (IE) + e.cancelBubble = true; + }, + stopImmediatePropagation: function() { + this.isImmediatePropagationStopped = returnTrue; + this.stopPropagation(); + }, + isDefaultPrevented: returnFalse, + isPropagationStopped: returnFalse, + isImmediatePropagationStopped: returnFalse +}; + +// Create mouseenter/leave events using mouseover/out and event-time checks +jQuery.each({ + mouseenter: "mouseover", + mouseleave: "mouseout" +}, function( orig, fix ) { + jQuery.event.special[ orig ] = { + delegateType: fix, + bindType: fix, + + handle: function( event ) { + var target = this, + related = event.relatedTarget, + handleObj = event.handleObj, + selector = handleObj.selector, + ret; + + // For mousenter/leave call the handler if related is outside the target. + // NB: No relatedTarget if the mouse left/entered the browser window + if ( !related || (related !== target && !jQuery.contains( target, related )) ) { + event.type = handleObj.origType; + ret = handleObj.handler.apply( this, arguments ); + event.type = fix; + } + return ret; + } + }; +}); + +// IE submit delegation +if ( !jQuery.support.submitBubbles ) { + + jQuery.event.special.submit = { + setup: function() { + // Only need this for delegated form submit events + if ( jQuery.nodeName( this, "form" ) ) { + return false; + } + + // Lazy-add a submit handler when a descendant form may potentially be submitted + jQuery.event.add( this, "click._submit keypress._submit", function( e ) { + // Node name check avoids a VML-related crash in IE (#9807) + var elem = e.target, + form = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ? elem.form : undefined; + if ( form && !form._submit_attached ) { + jQuery.event.add( form, "submit._submit", function( event ) { + event._submit_bubble = true; + }); + form._submit_attached = true; + } + }); + // return undefined since we don't need an event listener + }, + + postDispatch: function( event ) { + // If form was submitted by the user, bubble the event up the tree + if ( event._submit_bubble ) { + delete event._submit_bubble; + if ( this.parentNode && !event.isTrigger ) { + jQuery.event.simulate( "submit", this.parentNode, event, true ); + } + } + }, + + teardown: function() { + // Only need this for delegated form submit events + if ( jQuery.nodeName( this, "form" ) ) { + return false; + } + + // Remove delegated handlers; cleanData eventually reaps submit handlers attached above + jQuery.event.remove( this, "._submit" ); + } + }; +} + +// IE change delegation and checkbox/radio fix +if ( !jQuery.support.changeBubbles ) { + + jQuery.event.special.change = { + + setup: function() { + + if ( rformElems.test( this.nodeName ) ) { + // IE doesn't fire change on a check/radio until blur; trigger it on click + // after a propertychange. Eat the blur-change in special.change.handle. + // This still fires onchange a second time for check/radio after blur. + if ( this.type === "checkbox" || this.type === "radio" ) { + jQuery.event.add( this, "propertychange._change", function( event ) { + if ( event.originalEvent.propertyName === "checked" ) { + this._just_changed = true; + } + }); + jQuery.event.add( this, "click._change", function( event ) { + if ( this._just_changed && !event.isTrigger ) { + this._just_changed = false; + jQuery.event.simulate( "change", this, event, true ); + } + }); + } + return false; + } + // Delegated event; lazy-add a change handler on descendant inputs + jQuery.event.add( this, "beforeactivate._change", function( e ) { + var elem = e.target; + + if ( rformElems.test( elem.nodeName ) && !elem._change_attached ) { + jQuery.event.add( elem, "change._change", function( event ) { + if ( this.parentNode && !event.isSimulated && !event.isTrigger ) { + jQuery.event.simulate( "change", this.parentNode, event, true ); + } + }); + elem._change_attached = true; + } + }); + }, + + handle: function( event ) { + var elem = event.target; + + // Swallow native change events from checkbox/radio, we already triggered them above + if ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== "radio" && elem.type !== "checkbox") ) { + return event.handleObj.handler.apply( this, arguments ); + } + }, + + teardown: function() { + jQuery.event.remove( this, "._change" ); + + return rformElems.test( this.nodeName ); + } + }; +} + +// Create "bubbling" focus and blur events +if ( !jQuery.support.focusinBubbles ) { + jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) { + + // Attach a single capturing handler while someone wants focusin/focusout + var attaches = 0, + handler = function( event ) { + jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true ); + }; + + jQuery.event.special[ fix ] = { + setup: function() { + if ( attaches++ === 0 ) { + document.addEventListener( orig, handler, true ); + } + }, + teardown: function() { + if ( --attaches === 0 ) { + document.removeEventListener( orig, handler, true ); + } + } + }; + }); +} + +jQuery.fn.extend({ + + on: function( types, selector, data, fn, /*INTERNAL*/ one ) { + var origFn, type; + + // Types can be a map of types/handlers + if ( typeof types === "object" ) { + // ( types-Object, selector, data ) + if ( typeof selector !== "string" ) { // && selector != null + // ( types-Object, data ) + data = data || selector; + selector = undefined; + } + for ( type in types ) { + this.on( type, selector, data, types[ type ], one ); + } + return this; + } + + if ( data == null && fn == null ) { + // ( types, fn ) + fn = selector; + data = selector = undefined; + } else if ( fn == null ) { + if ( typeof selector === "string" ) { + // ( types, selector, fn ) + fn = data; + data = undefined; + } else { + // ( types, data, fn ) + fn = data; + data = selector; + selector = undefined; + } + } + if ( fn === false ) { + fn = returnFalse; + } else if ( !fn ) { + return this; + } + + if ( one === 1 ) { + origFn = fn; + fn = function( event ) { + // Can use an empty set, since event contains the info + jQuery().off( event ); + return origFn.apply( this, arguments ); + }; + // Use same guid so caller can remove using origFn + fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); + } + return this.each( function() { + jQuery.event.add( this, types, fn, data, selector ); + }); + }, + one: function( types, selector, data, fn ) { + return this.on( types, selector, data, fn, 1 ); + }, + off: function( types, selector, fn ) { + if ( types && types.preventDefault && types.handleObj ) { + // ( event ) dispatched jQuery.Event + var handleObj = types.handleObj; + jQuery( types.delegateTarget ).off( + handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType, + handleObj.selector, + handleObj.handler + ); + return this; + } + if ( typeof types === "object" ) { + // ( types-object [, selector] ) + for ( var type in types ) { + this.off( type, selector, types[ type ] ); + } + return this; + } + if ( selector === false || typeof selector === "function" ) { + // ( types [, fn] ) + fn = selector; + selector = undefined; + } + if ( fn === false ) { + fn = returnFalse; + } + return this.each(function() { + jQuery.event.remove( this, types, fn, selector ); + }); + }, + + bind: function( types, data, fn ) { + return this.on( types, null, data, fn ); + }, + unbind: function( types, fn ) { + return this.off( types, null, fn ); + }, + + live: function( types, data, fn ) { + jQuery( this.context ).on( types, this.selector, data, fn ); + return this; + }, + die: function( types, fn ) { + jQuery( this.context ).off( types, this.selector || "**", fn ); + return this; + }, + + delegate: function( selector, types, data, fn ) { + return this.on( types, selector, data, fn ); + }, + undelegate: function( selector, types, fn ) { + // ( namespace ) or ( selector, types [, fn] ) + return arguments.length == 1? this.off( selector, "**" ) : this.off( types, selector, fn ); + }, + + trigger: function( type, data ) { + return this.each(function() { + jQuery.event.trigger( type, data, this ); + }); + }, + triggerHandler: function( type, data ) { + if ( this[0] ) { + return jQuery.event.trigger( type, data, this[0], true ); + } + }, + + toggle: function( fn ) { + // Save reference to arguments for access in closure + var args = arguments, + guid = fn.guid || jQuery.guid++, + i = 0, + toggler = function( event ) { + // Figure out which function to execute + var lastToggle = ( jQuery._data( this, "lastToggle" + fn.guid ) || 0 ) % i; + jQuery._data( this, "lastToggle" + fn.guid, lastToggle + 1 ); + + // Make sure that clicks stop + event.preventDefault(); + + // and execute the function + return args[ lastToggle ].apply( this, arguments ) || false; + }; + + // link all the functions, so any of them can unbind this click handler + toggler.guid = guid; + while ( i < args.length ) { + args[ i++ ].guid = guid; + } + + return this.click( toggler ); + }, + + hover: function( fnOver, fnOut ) { + return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver ); + } +}); + +jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " + + "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " + + "change select submit keydown keypress keyup error contextmenu").split(" "), function( i, name ) { + + // Handle event binding + jQuery.fn[ name ] = function( data, fn ) { + if ( fn == null ) { + fn = data; + data = null; + } + + return arguments.length > 0 ? + this.on( name, null, data, fn ) : + this.trigger( name ); + }; + + if ( jQuery.attrFn ) { + jQuery.attrFn[ name ] = true; + } + + if ( rkeyEvent.test( name ) ) { + jQuery.event.fixHooks[ name ] = jQuery.event.keyHooks; + } + + if ( rmouseEvent.test( name ) ) { + jQuery.event.fixHooks[ name ] = jQuery.event.mouseHooks; + } +}); + + + +/*! + * Sizzle CSS Selector Engine + * Copyright 2011, The Dojo Foundation + * Released under the MIT, BSD, and GPL Licenses. + * More information: http://sizzlejs.com/ + */ +(function(){ + +var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g, + expando = "sizcache" + (Math.random() + '').replace('.', ''), + done = 0, + toString = Object.prototype.toString, + hasDuplicate = false, + baseHasDuplicate = true, + rBackslash = /\\/g, + rReturn = /\r\n/g, + rNonWord = /\W/; + +// Here we check if the JavaScript engine is using some sort of +// optimization where it does not always call our comparision +// function. If that is the case, discard the hasDuplicate value. +// Thus far that includes Google Chrome. +[0, 0].sort(function() { + baseHasDuplicate = false; + return 0; +}); + +var Sizzle = function( selector, context, results, seed ) { + results = results || []; + context = context || document; + + var origContext = context; + + if ( context.nodeType !== 1 && context.nodeType !== 9 ) { + return []; + } + + if ( !selector || typeof selector !== "string" ) { + return results; + } + + var m, set, checkSet, extra, ret, cur, pop, i, + prune = true, + contextXML = Sizzle.isXML( context ), + parts = [], + soFar = selector; + + // Reset the position of the chunker regexp (start from head) + do { + chunker.exec( "" ); + m = chunker.exec( soFar ); + + if ( m ) { + soFar = m[3]; + + parts.push( m[1] ); + + if ( m[2] ) { + extra = m[3]; + break; + } + } + } while ( m ); + + if ( parts.length > 1 && origPOS.exec( selector ) ) { + + if ( parts.length === 2 && Expr.relative[ parts[0] ] ) { + set = posProcess( parts[0] + parts[1], context, seed ); + + } else { + set = Expr.relative[ parts[0] ] ? + [ context ] : + Sizzle( parts.shift(), context ); + + while ( parts.length ) { + selector = parts.shift(); + + if ( Expr.relative[ selector ] ) { + selector += parts.shift(); + } + + set = posProcess( selector, set, seed ); + } + } + + } else { + // Take a shortcut and set the context if the root selector is an ID + // (but not if it'll be faster if the inner selector is an ID) + if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML && + Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) { + + ret = Sizzle.find( parts.shift(), context, contextXML ); + context = ret.expr ? + Sizzle.filter( ret.expr, ret.set )[0] : + ret.set[0]; + } + + if ( context ) { + ret = seed ? + { expr: parts.pop(), set: makeArray(seed) } : + Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML ); + + set = ret.expr ? + Sizzle.filter( ret.expr, ret.set ) : + ret.set; + + if ( parts.length > 0 ) { + checkSet = makeArray( set ); + + } else { + prune = false; + } + + while ( parts.length ) { + cur = parts.pop(); + pop = cur; + + if ( !Expr.relative[ cur ] ) { + cur = ""; + } else { + pop = parts.pop(); + } + + if ( pop == null ) { + pop = context; + } + + Expr.relative[ cur ]( checkSet, pop, contextXML ); + } + + } else { + checkSet = parts = []; + } + } + + if ( !checkSet ) { + checkSet = set; + } + + if ( !checkSet ) { + Sizzle.error( cur || selector ); + } + + if ( toString.call(checkSet) === "[object Array]" ) { + if ( !prune ) { + results.push.apply( results, checkSet ); + + } else if ( context && context.nodeType === 1 ) { + for ( i = 0; checkSet[i] != null; i++ ) { + if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && Sizzle.contains(context, checkSet[i])) ) { + results.push( set[i] ); + } + } + + } else { + for ( i = 0; checkSet[i] != null; i++ ) { + if ( checkSet[i] && checkSet[i].nodeType === 1 ) { + results.push( set[i] ); + } + } + } + + } else { + makeArray( checkSet, results ); + } + + if ( extra ) { + Sizzle( extra, origContext, results, seed ); + Sizzle.uniqueSort( results ); + } + + return results; +}; + +Sizzle.uniqueSort = function( results ) { + if ( sortOrder ) { + hasDuplicate = baseHasDuplicate; + results.sort( sortOrder ); + + if ( hasDuplicate ) { + for ( var i = 1; i < results.length; i++ ) { + if ( results[i] === results[ i - 1 ] ) { + results.splice( i--, 1 ); + } + } + } + } + + return results; +}; + +Sizzle.matches = function( expr, set ) { + return Sizzle( expr, null, null, set ); +}; + +Sizzle.matchesSelector = function( node, expr ) { + return Sizzle( expr, null, null, [node] ).length > 0; +}; + +Sizzle.find = function( expr, context, isXML ) { + var set, i, len, match, type, left; + + if ( !expr ) { + return []; + } + + for ( i = 0, len = Expr.order.length; i < len; i++ ) { + type = Expr.order[i]; + + if ( (match = Expr.leftMatch[ type ].exec( expr )) ) { + left = match[1]; + match.splice( 1, 1 ); + + if ( left.substr( left.length - 1 ) !== "\\" ) { + match[1] = (match[1] || "").replace( rBackslash, "" ); + set = Expr.find[ type ]( match, context, isXML ); + + if ( set != null ) { + expr = expr.replace( Expr.match[ type ], "" ); + break; + } + } + } + } + + if ( !set ) { + set = typeof context.getElementsByTagName !== "undefined" ? + context.getElementsByTagName( "*" ) : + []; + } + + return { set: set, expr: expr }; +}; + +Sizzle.filter = function( expr, set, inplace, not ) { + var match, anyFound, + type, found, item, filter, left, + i, pass, + old = expr, + result = [], + curLoop = set, + isXMLFilter = set && set[0] && Sizzle.isXML( set[0] ); + + while ( expr && set.length ) { + for ( type in Expr.filter ) { + if ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) { + filter = Expr.filter[ type ]; + left = match[1]; + + anyFound = false; + + match.splice(1,1); + + if ( left.substr( left.length - 1 ) === "\\" ) { + continue; + } + + if ( curLoop === result ) { + result = []; + } + + if ( Expr.preFilter[ type ] ) { + match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter ); + + if ( !match ) { + anyFound = found = true; + + } else if ( match === true ) { + continue; + } + } + + if ( match ) { + for ( i = 0; (item = curLoop[i]) != null; i++ ) { + if ( item ) { + found = filter( item, match, i, curLoop ); + pass = not ^ found; + + if ( inplace && found != null ) { + if ( pass ) { + anyFound = true; + + } else { + curLoop[i] = false; + } + + } else if ( pass ) { + result.push( item ); + anyFound = true; + } + } + } + } + + if ( found !== undefined ) { + if ( !inplace ) { + curLoop = result; + } + + expr = expr.replace( Expr.match[ type ], "" ); + + if ( !anyFound ) { + return []; + } + + break; + } + } + } + + // Improper expression + if ( expr === old ) { + if ( anyFound == null ) { + Sizzle.error( expr ); + + } else { + break; + } + } + + old = expr; + } + + return curLoop; +}; + +Sizzle.error = function( msg ) { + throw new Error( "Syntax error, unrecognized expression: " + msg ); +}; + +/** + * Utility function for retreiving the text value of an array of DOM nodes + * @param {Array|Element} elem + */ +var getText = Sizzle.getText = function( elem ) { + var i, node, + nodeType = elem.nodeType, + ret = ""; + + if ( nodeType ) { + if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { + // Use textContent || innerText for elements + if ( typeof elem.textContent === 'string' ) { + return elem.textContent; + } else if ( typeof elem.innerText === 'string' ) { + // Replace IE's carriage returns + return elem.innerText.replace( rReturn, '' ); + } else { + // Traverse it's children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling) { + ret += getText( elem ); + } + } + } else if ( nodeType === 3 || nodeType === 4 ) { + return elem.nodeValue; + } + } else { + + // If no nodeType, this is expected to be an array + for ( i = 0; (node = elem[i]); i++ ) { + // Do not traverse comment nodes + if ( node.nodeType !== 8 ) { + ret += getText( node ); + } + } + } + return ret; +}; + +var Expr = Sizzle.selectors = { + order: [ "ID", "NAME", "TAG" ], + + match: { + ID: /#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/, + CLASS: /\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/, + NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/, + ATTR: /\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/, + TAG: /^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/, + CHILD: /:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/, + POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/, + PSEUDO: /:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/ + }, + + leftMatch: {}, + + attrMap: { + "class": "className", + "for": "htmlFor" + }, + + attrHandle: { + href: function( elem ) { + return elem.getAttribute( "href" ); + }, + type: function( elem ) { + return elem.getAttribute( "type" ); + } + }, + + relative: { + "+": function(checkSet, part){ + var isPartStr = typeof part === "string", + isTag = isPartStr && !rNonWord.test( part ), + isPartStrNotTag = isPartStr && !isTag; + + if ( isTag ) { + part = part.toLowerCase(); + } + + for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) { + if ( (elem = checkSet[i]) ) { + while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {} + + checkSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ? + elem || false : + elem === part; + } + } + + if ( isPartStrNotTag ) { + Sizzle.filter( part, checkSet, true ); + } + }, + + ">": function( checkSet, part ) { + var elem, + isPartStr = typeof part === "string", + i = 0, + l = checkSet.length; + + if ( isPartStr && !rNonWord.test( part ) ) { + part = part.toLowerCase(); + + for ( ; i < l; i++ ) { + elem = checkSet[i]; + + if ( elem ) { + var parent = elem.parentNode; + checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false; + } + } + + } else { + for ( ; i < l; i++ ) { + elem = checkSet[i]; + + if ( elem ) { + checkSet[i] = isPartStr ? + elem.parentNode : + elem.parentNode === part; + } + } + + if ( isPartStr ) { + Sizzle.filter( part, checkSet, true ); + } + } + }, + + "": function(checkSet, part, isXML){ + var nodeCheck, + doneName = done++, + checkFn = dirCheck; + + if ( typeof part === "string" && !rNonWord.test( part ) ) { + part = part.toLowerCase(); + nodeCheck = part; + checkFn = dirNodeCheck; + } + + checkFn( "parentNode", part, doneName, checkSet, nodeCheck, isXML ); + }, + + "~": function( checkSet, part, isXML ) { + var nodeCheck, + doneName = done++, + checkFn = dirCheck; + + if ( typeof part === "string" && !rNonWord.test( part ) ) { + part = part.toLowerCase(); + nodeCheck = part; + checkFn = dirNodeCheck; + } + + checkFn( "previousSibling", part, doneName, checkSet, nodeCheck, isXML ); + } + }, + + find: { + ID: function( match, context, isXML ) { + if ( typeof context.getElementById !== "undefined" && !isXML ) { + var m = context.getElementById(match[1]); + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + return m && m.parentNode ? [m] : []; + } + }, + + NAME: function( match, context ) { + if ( typeof context.getElementsByName !== "undefined" ) { + var ret = [], + results = context.getElementsByName( match[1] ); + + for ( var i = 0, l = results.length; i < l; i++ ) { + if ( results[i].getAttribute("name") === match[1] ) { + ret.push( results[i] ); + } + } + + return ret.length === 0 ? null : ret; + } + }, + + TAG: function( match, context ) { + if ( typeof context.getElementsByTagName !== "undefined" ) { + return context.getElementsByTagName( match[1] ); + } + } + }, + preFilter: { + CLASS: function( match, curLoop, inplace, result, not, isXML ) { + match = " " + match[1].replace( rBackslash, "" ) + " "; + + if ( isXML ) { + return match; + } + + for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) { + if ( elem ) { + if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n\r]/g, " ").indexOf(match) >= 0) ) { + if ( !inplace ) { + result.push( elem ); + } + + } else if ( inplace ) { + curLoop[i] = false; + } + } + } + + return false; + }, + + ID: function( match ) { + return match[1].replace( rBackslash, "" ); + }, + + TAG: function( match, curLoop ) { + return match[1].replace( rBackslash, "" ).toLowerCase(); + }, + + CHILD: function( match ) { + if ( match[1] === "nth" ) { + if ( !match[2] ) { + Sizzle.error( match[0] ); + } + + match[2] = match[2].replace(/^\+|\s*/g, ''); + + // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6' + var test = /(-?)(\d*)(?:n([+\-]?\d*))?/.exec( + match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" || + !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]); + + // calculate the numbers (first)n+(last) including if they are negative + match[2] = (test[1] + (test[2] || 1)) - 0; + match[3] = test[3] - 0; + } + else if ( match[2] ) { + Sizzle.error( match[0] ); + } + + // TODO: Move to normal caching system + match[0] = done++; + + return match; + }, + + ATTR: function( match, curLoop, inplace, result, not, isXML ) { + var name = match[1] = match[1].replace( rBackslash, "" ); + + if ( !isXML && Expr.attrMap[name] ) { + match[1] = Expr.attrMap[name]; + } + + // Handle if an un-quoted value was used + match[4] = ( match[4] || match[5] || "" ).replace( rBackslash, "" ); + + if ( match[2] === "~=" ) { + match[4] = " " + match[4] + " "; + } + + return match; + }, + + PSEUDO: function( match, curLoop, inplace, result, not ) { + if ( match[1] === "not" ) { + // If we're dealing with a complex expression, or a simple one + if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) { + match[3] = Sizzle(match[3], null, null, curLoop); + + } else { + var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not); + + if ( !inplace ) { + result.push.apply( result, ret ); + } + + return false; + } + + } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) { + return true; + } + + return match; + }, + + POS: function( match ) { + match.unshift( true ); + + return match; + } + }, + + filters: { + enabled: function( elem ) { + return elem.disabled === false && elem.type !== "hidden"; + }, + + disabled: function( elem ) { + return elem.disabled === true; + }, + + checked: function( elem ) { + return elem.checked === true; + }, + + selected: function( elem ) { + // Accessing this property makes selected-by-default + // options in Safari work properly + if ( elem.parentNode ) { + elem.parentNode.selectedIndex; + } + + return elem.selected === true; + }, + + parent: function( elem ) { + return !!elem.firstChild; + }, + + empty: function( elem ) { + return !elem.firstChild; + }, + + has: function( elem, i, match ) { + return !!Sizzle( match[3], elem ).length; + }, + + header: function( elem ) { + return (/h\d/i).test( elem.nodeName ); + }, + + text: function( elem ) { + var attr = elem.getAttribute( "type" ), type = elem.type; + // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc) + // use getAttribute instead to test this case + return elem.nodeName.toLowerCase() === "input" && "text" === type && ( attr === type || attr === null ); + }, + + radio: function( elem ) { + return elem.nodeName.toLowerCase() === "input" && "radio" === elem.type; + }, + + checkbox: function( elem ) { + return elem.nodeName.toLowerCase() === "input" && "checkbox" === elem.type; + }, + + file: function( elem ) { + return elem.nodeName.toLowerCase() === "input" && "file" === elem.type; + }, + + password: function( elem ) { + return elem.nodeName.toLowerCase() === "input" && "password" === elem.type; + }, + + submit: function( elem ) { + var name = elem.nodeName.toLowerCase(); + return (name === "input" || name === "button") && "submit" === elem.type; + }, + + image: function( elem ) { + return elem.nodeName.toLowerCase() === "input" && "image" === elem.type; + }, + + reset: function( elem ) { + var name = elem.nodeName.toLowerCase(); + return (name === "input" || name === "button") && "reset" === elem.type; + }, + + button: function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && "button" === elem.type || name === "button"; + }, + + input: function( elem ) { + return (/input|select|textarea|button/i).test( elem.nodeName ); + }, + + focus: function( elem ) { + return elem === elem.ownerDocument.activeElement; + } + }, + setFilters: { + first: function( elem, i ) { + return i === 0; + }, + + last: function( elem, i, match, array ) { + return i === array.length - 1; + }, + + even: function( elem, i ) { + return i % 2 === 0; + }, + + odd: function( elem, i ) { + return i % 2 === 1; + }, + + lt: function( elem, i, match ) { + return i < match[3] - 0; + }, + + gt: function( elem, i, match ) { + return i > match[3] - 0; + }, + + nth: function( elem, i, match ) { + return match[3] - 0 === i; + }, + + eq: function( elem, i, match ) { + return match[3] - 0 === i; + } + }, + filter: { + PSEUDO: function( elem, match, i, array ) { + var name = match[1], + filter = Expr.filters[ name ]; + + if ( filter ) { + return filter( elem, i, match, array ); + + } else if ( name === "contains" ) { + return (elem.textContent || elem.innerText || getText([ elem ]) || "").indexOf(match[3]) >= 0; + + } else if ( name === "not" ) { + var not = match[3]; + + for ( var j = 0, l = not.length; j < l; j++ ) { + if ( not[j] === elem ) { + return false; + } + } + + return true; + + } else { + Sizzle.error( name ); + } + }, + + CHILD: function( elem, match ) { + var first, last, + doneName, parent, cache, + count, diff, + type = match[1], + node = elem; + + switch ( type ) { + case "only": + case "first": + while ( (node = node.previousSibling) ) { + if ( node.nodeType === 1 ) { + return false; + } + } + + if ( type === "first" ) { + return true; + } + + node = elem; + + /* falls through */ + case "last": + while ( (node = node.nextSibling) ) { + if ( node.nodeType === 1 ) { + return false; + } + } + + return true; + + case "nth": + first = match[2]; + last = match[3]; + + if ( first === 1 && last === 0 ) { + return true; + } + + doneName = match[0]; + parent = elem.parentNode; + + if ( parent && (parent[ expando ] !== doneName || !elem.nodeIndex) ) { + count = 0; + + for ( node = parent.firstChild; node; node = node.nextSibling ) { + if ( node.nodeType === 1 ) { + node.nodeIndex = ++count; + } + } + + parent[ expando ] = doneName; + } + + diff = elem.nodeIndex - last; + + if ( first === 0 ) { + return diff === 0; + + } else { + return ( diff % first === 0 && diff / first >= 0 ); + } + } + }, + + ID: function( elem, match ) { + return elem.nodeType === 1 && elem.getAttribute("id") === match; + }, + + TAG: function( elem, match ) { + return (match === "*" && elem.nodeType === 1) || !!elem.nodeName && elem.nodeName.toLowerCase() === match; + }, + + CLASS: function( elem, match ) { + return (" " + (elem.className || elem.getAttribute("class")) + " ") + .indexOf( match ) > -1; + }, + + ATTR: function( elem, match ) { + var name = match[1], + result = Sizzle.attr ? + Sizzle.attr( elem, name ) : + Expr.attrHandle[ name ] ? + Expr.attrHandle[ name ]( elem ) : + elem[ name ] != null ? + elem[ name ] : + elem.getAttribute( name ), + value = result + "", + type = match[2], + check = match[4]; + + return result == null ? + type === "!=" : + !type && Sizzle.attr ? + result != null : + type === "=" ? + value === check : + type === "*=" ? + value.indexOf(check) >= 0 : + type === "~=" ? + (" " + value + " ").indexOf(check) >= 0 : + !check ? + value && result !== false : + type === "!=" ? + value !== check : + type === "^=" ? + value.indexOf(check) === 0 : + type === "$=" ? + value.substr(value.length - check.length) === check : + type === "|=" ? + value === check || value.substr(0, check.length + 1) === check + "-" : + false; + }, + + POS: function( elem, match, i, array ) { + var name = match[2], + filter = Expr.setFilters[ name ]; + + if ( filter ) { + return filter( elem, i, match, array ); + } + } + } +}; + +var origPOS = Expr.match.POS, + fescape = function(all, num){ + return "\\" + (num - 0 + 1); + }; + +for ( var type in Expr.match ) { + Expr.match[ type ] = new RegExp( Expr.match[ type ].source + (/(?![^\[]*\])(?![^\(]*\))/.source) ); + Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source.replace(/\\(\d+)/g, fescape) ); +} +// Expose origPOS +// "global" as in regardless of relation to brackets/parens +Expr.match.globalPOS = origPOS; + +var makeArray = function( array, results ) { + array = Array.prototype.slice.call( array, 0 ); + + if ( results ) { + results.push.apply( results, array ); + return results; + } + + return array; +}; + +// Perform a simple check to determine if the browser is capable of +// converting a NodeList to an array using builtin methods. +// Also verifies that the returned array holds DOM nodes +// (which is not the case in the Blackberry browser) +try { + Array.prototype.slice.call( document.documentElement.childNodes, 0 )[0].nodeType; + +// Provide a fallback method if it does not work +} catch( e ) { + makeArray = function( array, results ) { + var i = 0, + ret = results || []; + + if ( toString.call(array) === "[object Array]" ) { + Array.prototype.push.apply( ret, array ); + + } else { + if ( typeof array.length === "number" ) { + for ( var l = array.length; i < l; i++ ) { + ret.push( array[i] ); + } + + } else { + for ( ; array[i]; i++ ) { + ret.push( array[i] ); + } + } + } + + return ret; + }; +} + +var sortOrder, siblingCheck; + +if ( document.documentElement.compareDocumentPosition ) { + sortOrder = function( a, b ) { + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) { + return a.compareDocumentPosition ? -1 : 1; + } + + return a.compareDocumentPosition(b) & 4 ? -1 : 1; + }; + +} else { + sortOrder = function( a, b ) { + // The nodes are identical, we can exit early + if ( a === b ) { + hasDuplicate = true; + return 0; + + // Fallback to using sourceIndex (in IE) if it's available on both nodes + } else if ( a.sourceIndex && b.sourceIndex ) { + return a.sourceIndex - b.sourceIndex; + } + + var al, bl, + ap = [], + bp = [], + aup = a.parentNode, + bup = b.parentNode, + cur = aup; + + // If the nodes are siblings (or identical) we can do a quick check + if ( aup === bup ) { + return siblingCheck( a, b ); + + // If no parents were found then the nodes are disconnected + } else if ( !aup ) { + return -1; + + } else if ( !bup ) { + return 1; + } + + // Otherwise they're somewhere else in the tree so we need + // to build up a full list of the parentNodes for comparison + while ( cur ) { + ap.unshift( cur ); + cur = cur.parentNode; + } + + cur = bup; + + while ( cur ) { + bp.unshift( cur ); + cur = cur.parentNode; + } + + al = ap.length; + bl = bp.length; + + // Start walking down the tree looking for a discrepancy + for ( var i = 0; i < al && i < bl; i++ ) { + if ( ap[i] !== bp[i] ) { + return siblingCheck( ap[i], bp[i] ); + } + } + + // We ended someplace up the tree so do a sibling check + return i === al ? + siblingCheck( a, bp[i], -1 ) : + siblingCheck( ap[i], b, 1 ); + }; + + siblingCheck = function( a, b, ret ) { + if ( a === b ) { + return ret; + } + + var cur = a.nextSibling; + + while ( cur ) { + if ( cur === b ) { + return -1; + } + + cur = cur.nextSibling; + } + + return 1; + }; +} + +// Check to see if the browser returns elements by name when +// querying by getElementById (and provide a workaround) +(function(){ + // We're going to inject a fake input element with a specified name + var form = document.createElement("div"), + id = "script" + (new Date()).getTime(), + root = document.documentElement; + + form.innerHTML = ""; + + // Inject it into the root element, check its status, and remove it quickly + root.insertBefore( form, root.firstChild ); + + // The workaround has to do additional checks after a getElementById + // Which slows things down for other browsers (hence the branching) + if ( document.getElementById( id ) ) { + Expr.find.ID = function( match, context, isXML ) { + if ( typeof context.getElementById !== "undefined" && !isXML ) { + var m = context.getElementById(match[1]); + + return m ? + m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ? + [m] : + undefined : + []; + } + }; + + Expr.filter.ID = function( elem, match ) { + var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id"); + + return elem.nodeType === 1 && node && node.nodeValue === match; + }; + } + + root.removeChild( form ); + + // release memory in IE + root = form = null; +})(); + +(function(){ + // Check to see if the browser returns only elements + // when doing getElementsByTagName("*") + + // Create a fake element + var div = document.createElement("div"); + div.appendChild( document.createComment("") ); + + // Make sure no comments are found + if ( div.getElementsByTagName("*").length > 0 ) { + Expr.find.TAG = function( match, context ) { + var results = context.getElementsByTagName( match[1] ); + + // Filter out possible comments + if ( match[1] === "*" ) { + var tmp = []; + + for ( var i = 0; results[i]; i++ ) { + if ( results[i].nodeType === 1 ) { + tmp.push( results[i] ); + } + } + + results = tmp; + } + + return results; + }; + } + + // Check to see if an attribute returns normalized href attributes + div.innerHTML = ""; + + if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" && + div.firstChild.getAttribute("href") !== "#" ) { + + Expr.attrHandle.href = function( elem ) { + return elem.getAttribute( "href", 2 ); + }; + } + + // release memory in IE + div = null; +})(); + +if ( document.querySelectorAll ) { + (function(){ + var oldSizzle = Sizzle, + div = document.createElement("div"), + id = "__sizzle__"; + + div.innerHTML = "

    "; + + // Safari can't handle uppercase or unicode characters when + // in quirks mode. + if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) { + return; + } + + Sizzle = function( query, context, extra, seed ) { + context = context || document; + + // Only use querySelectorAll on non-XML documents + // (ID selectors don't work in non-HTML documents) + if ( !seed && !Sizzle.isXML(context) ) { + // See if we find a selector to speed up + var match = /^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec( query ); + + if ( match && (context.nodeType === 1 || context.nodeType === 9) ) { + // Speed-up: Sizzle("TAG") + if ( match[1] ) { + return makeArray( context.getElementsByTagName( query ), extra ); + + // Speed-up: Sizzle(".CLASS") + } else if ( match[2] && Expr.find.CLASS && context.getElementsByClassName ) { + return makeArray( context.getElementsByClassName( match[2] ), extra ); + } + } + + if ( context.nodeType === 9 ) { + // Speed-up: Sizzle("body") + // The body element only exists once, optimize finding it + if ( query === "body" && context.body ) { + return makeArray( [ context.body ], extra ); + + // Speed-up: Sizzle("#ID") + } else if ( match && match[3] ) { + var elem = context.getElementById( match[3] ); + + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + if ( elem && elem.parentNode ) { + // Handle the case where IE and Opera return items + // by name instead of ID + if ( elem.id === match[3] ) { + return makeArray( [ elem ], extra ); + } + + } else { + return makeArray( [], extra ); + } + } + + try { + return makeArray( context.querySelectorAll(query), extra ); + } catch(qsaError) {} + + // qSA works strangely on Element-rooted queries + // We can work around this by specifying an extra ID on the root + // and working up from there (Thanks to Andrew Dupont for the technique) + // IE 8 doesn't work on object elements + } else if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) { + var oldContext = context, + old = context.getAttribute( "id" ), + nid = old || id, + hasParent = context.parentNode, + relativeHierarchySelector = /^\s*[+~]/.test( query ); + + if ( !old ) { + context.setAttribute( "id", nid ); + } else { + nid = nid.replace( /'/g, "\\$&" ); + } + if ( relativeHierarchySelector && hasParent ) { + context = context.parentNode; + } + + try { + if ( !relativeHierarchySelector || hasParent ) { + return makeArray( context.querySelectorAll( "[id='" + nid + "'] " + query ), extra ); + } + + } catch(pseudoError) { + } finally { + if ( !old ) { + oldContext.removeAttribute( "id" ); + } + } + } + } + + return oldSizzle(query, context, extra, seed); + }; + + for ( var prop in oldSizzle ) { + Sizzle[ prop ] = oldSizzle[ prop ]; + } + + // release memory in IE + div = null; + })(); +} + +(function(){ + var html = document.documentElement, + matches = html.matchesSelector || html.mozMatchesSelector || html.webkitMatchesSelector || html.msMatchesSelector; + + if ( matches ) { + // Check to see if it's possible to do matchesSelector + // on a disconnected node (IE 9 fails this) + var disconnectedMatch = !matches.call( document.createElement( "div" ), "div" ), + pseudoWorks = false; + + try { + // This should fail with an exception + // Gecko does not error, returns false instead + matches.call( document.documentElement, "[test!='']:sizzle" ); + + } catch( pseudoError ) { + pseudoWorks = true; + } + + Sizzle.matchesSelector = function( node, expr ) { + // Make sure that attribute selectors are quoted + expr = expr.replace(/\=\s*([^'"\]]*)\s*\]/g, "='$1']"); + + if ( !Sizzle.isXML( node ) ) { + try { + if ( pseudoWorks || !Expr.match.PSEUDO.test( expr ) && !/!=/.test( expr ) ) { + var ret = matches.call( node, expr ); + + // IE 9's matchesSelector returns false on disconnected nodes + if ( ret || !disconnectedMatch || + // As well, disconnected nodes are said to be in a document + // fragment in IE 9, so check for that + node.document && node.document.nodeType !== 11 ) { + return ret; + } + } + } catch(e) {} + } + + return Sizzle(expr, null, null, [node]).length > 0; + }; + } +})(); + +(function(){ + var div = document.createElement("div"); + + div.innerHTML = "
    "; + + // Opera can't find a second classname (in 9.6) + // Also, make sure that getElementsByClassName actually exists + if ( !div.getElementsByClassName || div.getElementsByClassName("e").length === 0 ) { + return; + } + + // Safari caches class attributes, doesn't catch changes (in 3.2) + div.lastChild.className = "e"; + + if ( div.getElementsByClassName("e").length === 1 ) { + return; + } + + Expr.order.splice(1, 0, "CLASS"); + Expr.find.CLASS = function( match, context, isXML ) { + if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) { + return context.getElementsByClassName(match[1]); + } + }; + + // release memory in IE + div = null; +})(); + +function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { + for ( var i = 0, l = checkSet.length; i < l; i++ ) { + var elem = checkSet[i]; + + if ( elem ) { + var match = false; + + elem = elem[dir]; + + while ( elem ) { + if ( elem[ expando ] === doneName ) { + match = checkSet[elem.sizset]; + break; + } + + if ( elem.nodeType === 1 && !isXML ){ + elem[ expando ] = doneName; + elem.sizset = i; + } + + if ( elem.nodeName.toLowerCase() === cur ) { + match = elem; + break; + } + + elem = elem[dir]; + } + + checkSet[i] = match; + } + } +} + +function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { + for ( var i = 0, l = checkSet.length; i < l; i++ ) { + var elem = checkSet[i]; + + if ( elem ) { + var match = false; + + elem = elem[dir]; + + while ( elem ) { + if ( elem[ expando ] === doneName ) { + match = checkSet[elem.sizset]; + break; + } + + if ( elem.nodeType === 1 ) { + if ( !isXML ) { + elem[ expando ] = doneName; + elem.sizset = i; + } + + if ( typeof cur !== "string" ) { + if ( elem === cur ) { + match = true; + break; + } + + } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) { + match = elem; + break; + } + } + + elem = elem[dir]; + } + + checkSet[i] = match; + } + } +} + +if ( document.documentElement.contains ) { + Sizzle.contains = function( a, b ) { + return a !== b && (a.contains ? a.contains(b) : true); + }; + +} else if ( document.documentElement.compareDocumentPosition ) { + Sizzle.contains = function( a, b ) { + return !!(a.compareDocumentPosition(b) & 16); + }; + +} else { + Sizzle.contains = function() { + return false; + }; +} + +Sizzle.isXML = function( elem ) { + // documentElement is verified for cases where it doesn't yet exist + // (such as loading iframes in IE - #4833) + var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement; + + return documentElement ? documentElement.nodeName !== "HTML" : false; +}; + +var posProcess = function( selector, context, seed ) { + var match, + tmpSet = [], + later = "", + root = context.nodeType ? [context] : context; + + // Position selectors must be done after the filter + // And so must :not(positional) so we move all PSEUDOs to the end + while ( (match = Expr.match.PSEUDO.exec( selector )) ) { + later += match[0]; + selector = selector.replace( Expr.match.PSEUDO, "" ); + } + + selector = Expr.relative[selector] ? selector + "*" : selector; + + for ( var i = 0, l = root.length; i < l; i++ ) { + Sizzle( selector, root[i], tmpSet, seed ); + } + + return Sizzle.filter( later, tmpSet ); +}; + +// EXPOSE +// Override sizzle attribute retrieval +Sizzle.attr = jQuery.attr; +Sizzle.selectors.attrMap = {}; +jQuery.find = Sizzle; +jQuery.expr = Sizzle.selectors; +jQuery.expr[":"] = jQuery.expr.filters; +jQuery.unique = Sizzle.uniqueSort; +jQuery.text = Sizzle.getText; +jQuery.isXMLDoc = Sizzle.isXML; +jQuery.contains = Sizzle.contains; + + +})(); + + +var runtil = /Until$/, + rparentsprev = /^(?:parents|prevUntil|prevAll)/, + // Note: This RegExp should be improved, or likely pulled from Sizzle + rmultiselector = /,/, + isSimple = /^.[^:#\[\.,]*$/, + slice = Array.prototype.slice, + POS = jQuery.expr.match.globalPOS, + // methods guaranteed to produce a unique set when starting from a unique set + guaranteedUnique = { + children: true, + contents: true, + next: true, + prev: true + }; + +jQuery.fn.extend({ + find: function( selector ) { + var self = this, + i, l; + + if ( typeof selector !== "string" ) { + return jQuery( selector ).filter(function() { + for ( i = 0, l = self.length; i < l; i++ ) { + if ( jQuery.contains( self[ i ], this ) ) { + return true; + } + } + }); + } + + var ret = this.pushStack( "", "find", selector ), + length, n, r; + + for ( i = 0, l = this.length; i < l; i++ ) { + length = ret.length; + jQuery.find( selector, this[i], ret ); + + if ( i > 0 ) { + // Make sure that the results are unique + for ( n = length; n < ret.length; n++ ) { + for ( r = 0; r < length; r++ ) { + if ( ret[r] === ret[n] ) { + ret.splice(n--, 1); + break; + } + } + } + } + } + + return ret; + }, + + has: function( target ) { + var targets = jQuery( target ); + return this.filter(function() { + for ( var i = 0, l = targets.length; i < l; i++ ) { + if ( jQuery.contains( this, targets[i] ) ) { + return true; + } + } + }); + }, + + not: function( selector ) { + return this.pushStack( winnow(this, selector, false), "not", selector); + }, + + filter: function( selector ) { + return this.pushStack( winnow(this, selector, true), "filter", selector ); + }, + + is: function( selector ) { + return !!selector && ( + typeof selector === "string" ? + // If this is a positional selector, check membership in the returned set + // so $("p:first").is("p:last") won't return true for a doc with two "p". + POS.test( selector ) ? + jQuery( selector, this.context ).index( this[0] ) >= 0 : + jQuery.filter( selector, this ).length > 0 : + this.filter( selector ).length > 0 ); + }, + + closest: function( selectors, context ) { + var ret = [], i, l, cur = this[0]; + + // Array (deprecated as of jQuery 1.7) + if ( jQuery.isArray( selectors ) ) { + var level = 1; + + while ( cur && cur.ownerDocument && cur !== context ) { + for ( i = 0; i < selectors.length; i++ ) { + + if ( jQuery( cur ).is( selectors[ i ] ) ) { + ret.push({ selector: selectors[ i ], elem: cur, level: level }); + } + } + + cur = cur.parentNode; + level++; + } + + return ret; + } + + // String + var pos = POS.test( selectors ) || typeof selectors !== "string" ? + jQuery( selectors, context || this.context ) : + 0; + + for ( i = 0, l = this.length; i < l; i++ ) { + cur = this[i]; + + while ( cur ) { + if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) { + ret.push( cur ); + break; + + } else { + cur = cur.parentNode; + if ( !cur || !cur.ownerDocument || cur === context || cur.nodeType === 11 ) { + break; + } + } + } + } + + ret = ret.length > 1 ? jQuery.unique( ret ) : ret; + + return this.pushStack( ret, "closest", selectors ); + }, + + // Determine the position of an element within + // the matched set of elements + index: function( elem ) { + + // No argument, return index in parent + if ( !elem ) { + return ( this[0] && this[0].parentNode ) ? this.prevAll().length : -1; + } + + // index in selector + if ( typeof elem === "string" ) { + return jQuery.inArray( this[0], jQuery( elem ) ); + } + + // Locate the position of the desired element + return jQuery.inArray( + // If it receives a jQuery object, the first element is used + elem.jquery ? elem[0] : elem, this ); + }, + + add: function( selector, context ) { + var set = typeof selector === "string" ? + jQuery( selector, context ) : + jQuery.makeArray( selector && selector.nodeType ? [ selector ] : selector ), + all = jQuery.merge( this.get(), set ); + + return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ? + all : + jQuery.unique( all ) ); + }, + + andSelf: function() { + return this.add( this.prevObject ); + } +}); + +// A painfully simple check to see if an element is disconnected +// from a document (should be improved, where feasible). +function isDisconnected( node ) { + return !node || !node.parentNode || node.parentNode.nodeType === 11; +} + +jQuery.each({ + parent: function( elem ) { + var parent = elem.parentNode; + return parent && parent.nodeType !== 11 ? parent : null; + }, + parents: function( elem ) { + return jQuery.dir( elem, "parentNode" ); + }, + parentsUntil: function( elem, i, until ) { + return jQuery.dir( elem, "parentNode", until ); + }, + next: function( elem ) { + return jQuery.nth( elem, 2, "nextSibling" ); + }, + prev: function( elem ) { + return jQuery.nth( elem, 2, "previousSibling" ); + }, + nextAll: function( elem ) { + return jQuery.dir( elem, "nextSibling" ); + }, + prevAll: function( elem ) { + return jQuery.dir( elem, "previousSibling" ); + }, + nextUntil: function( elem, i, until ) { + return jQuery.dir( elem, "nextSibling", until ); + }, + prevUntil: function( elem, i, until ) { + return jQuery.dir( elem, "previousSibling", until ); + }, + siblings: function( elem ) { + return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem ); + }, + children: function( elem ) { + return jQuery.sibling( elem.firstChild ); + }, + contents: function( elem ) { + return jQuery.nodeName( elem, "iframe" ) ? + elem.contentDocument || elem.contentWindow.document : + jQuery.makeArray( elem.childNodes ); + } +}, function( name, fn ) { + jQuery.fn[ name ] = function( until, selector ) { + var ret = jQuery.map( this, fn, until ); + + if ( !runtil.test( name ) ) { + selector = until; + } + + if ( selector && typeof selector === "string" ) { + ret = jQuery.filter( selector, ret ); + } + + ret = this.length > 1 && !guaranteedUnique[ name ] ? jQuery.unique( ret ) : ret; + + if ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( name ) ) { + ret = ret.reverse(); + } + + return this.pushStack( ret, name, slice.call( arguments ).join(",") ); + }; +}); + +jQuery.extend({ + filter: function( expr, elems, not ) { + if ( not ) { + expr = ":not(" + expr + ")"; + } + + return elems.length === 1 ? + jQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] : + jQuery.find.matches(expr, elems); + }, + + dir: function( elem, dir, until ) { + var matched = [], + cur = elem[ dir ]; + + while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) { + if ( cur.nodeType === 1 ) { + matched.push( cur ); + } + cur = cur[dir]; + } + return matched; + }, + + nth: function( cur, result, dir, elem ) { + result = result || 1; + var num = 0; + + for ( ; cur; cur = cur[dir] ) { + if ( cur.nodeType === 1 && ++num === result ) { + break; + } + } + + return cur; + }, + + sibling: function( n, elem ) { + var r = []; + + for ( ; n; n = n.nextSibling ) { + if ( n.nodeType === 1 && n !== elem ) { + r.push( n ); + } + } + + return r; + } +}); + +// Implement the identical functionality for filter and not +function winnow( elements, qualifier, keep ) { + + // Can't pass null or undefined to indexOf in Firefox 4 + // Set to 0 to skip string check + qualifier = qualifier || 0; + + if ( jQuery.isFunction( qualifier ) ) { + return jQuery.grep(elements, function( elem, i ) { + var retVal = !!qualifier.call( elem, i, elem ); + return retVal === keep; + }); + + } else if ( qualifier.nodeType ) { + return jQuery.grep(elements, function( elem, i ) { + return ( elem === qualifier ) === keep; + }); + + } else if ( typeof qualifier === "string" ) { + var filtered = jQuery.grep(elements, function( elem ) { + return elem.nodeType === 1; + }); + + if ( isSimple.test( qualifier ) ) { + return jQuery.filter(qualifier, filtered, !keep); + } else { + qualifier = jQuery.filter( qualifier, filtered ); + } + } + + return jQuery.grep(elements, function( elem, i ) { + return ( jQuery.inArray( elem, qualifier ) >= 0 ) === keep; + }); +} + + + + +function createSafeFragment( document ) { + var list = nodeNames.split( "|" ), + safeFrag = document.createDocumentFragment(); + + if ( safeFrag.createElement ) { + while ( list.length ) { + safeFrag.createElement( + list.pop() + ); + } + } + return safeFrag; +} + +var nodeNames = "abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|" + + "header|hgroup|mark|meter|nav|output|progress|section|summary|time|video", + rinlinejQuery = / jQuery\d+="(?:\d+|null)"/g, + rleadingWhitespace = /^\s+/, + rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig, + rtagName = /<([\w:]+)/, + rtbody = /

    ", "
    " ], + tr: [ 2, "", "
    " ], + td: [ 3, "", "
    " ], + col: [ 2, "", "
    " ], + area: [ 1, "", "" ], + _default: [ 0, "", "" ] + }, + safeFragment = createSafeFragment( document ); + +wrapMap.optgroup = wrapMap.option; +wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; +wrapMap.th = wrapMap.td; + +// IE can't serialize and + + + + + + + +
    + +
    +
    +
    +
    + +
    +

    8. Contacts & Notices¶

    +
    +

    8.1. Contacts¶

    +
    +
    ADLINK Technology Corporation
    +
    400 TradeCenter
    +
    Suite 5900
    +
    Woburn, MA
    +
    01801
    +
    USA
    +
    Tel: +1 781 569 5819
    +
    +
    +
    ADLINK Technology Limited
    +
    The Edge
    +
    5th Avenue
    +
    Team Valley
    +
    Gateshead
    +
    NE11 0XA
    +
    UK
    +
    Tel: +44 (0)191 497 9900
    +
    +
    +
    ADLINK Technology SARL
    +
    28 rue Jean Rostand
    +
    91400 Orsay
    +
    France
    +
    Tel: +33 (1) 69 015354
    +
    +

    Web: http://ist.adlinktech.com/

    +

    Contact: http://ist.adlinktech.com

    +

    E-mail: ist_info@adlinktech.com

    +

    LinkedIn: https://www.linkedin.com/company/79111/

    +

    Twitter: https://twitter.com/ADLINKTech_usa

    +

    Facebook: https://www.facebook.com/ADLINKTECH

    +
    +
    +

    8.2. Notices¶

    +

    Copyright © 2018 ADLINK Technology Limited. All rights reserved.

    +

    This document may be reproduced in whole but not in part. The information contained in this +document is subject to change without notice and is made available in good faith without +liability on the part of ADLINK Technology Limited. All trademarks acknowledged.

    +
    +
    + + +
    +
    +
    +
    +
    + +

    Table Of Contents

    + + +

    Previous topic

    +

    7. Topic Generation and Discovery

    +

    This Page

    + + + +
    +
    +
    +
    + + + + \ No newline at end of file diff --git a/docs/html/NodeJSDCPSAPIGuide/dds_entities.html b/docs/html/NodeJSDCPSAPIGuide/dds_entities.html new file mode 100644 index 000000000..cd04773d2 --- /dev/null +++ b/docs/html/NodeJSDCPSAPIGuide/dds_entities.html @@ -0,0 +1,665 @@ + + + + + + + + 5. Node.js API for Vortex DDS — Node.js DCPS API Guide + + + + + + + + + + + + + + + +
    +
    +
    +
    + +
    +

    5. Node.js API for Vortex DDS¶

    +

    The Node.js DCPS API provides users with Node.js classes to model DDS communication using JavaScript and pure +DDS applications.

    +

    The Node.js DCPS API consists of one module.

    +
      +
    • vortexdds
    • +
    +

    This section provides an overview of the main DDS concepts and Node.js API examples for these DDS concepts.

    +
    +

    Note

    +
      +
    • The Node.js DCPS API documentation can be found in the following directory:

      +
      +

      $OSPL_HOME/docs/nodejs/html

      +
      +
    • +
    +
    +
    +

    5.1. API Usage Patterns¶

    +

    The typical usage pattern for the Node.js DCPS API for Vortex DDS is the following:

    +
      +
    • Model your DDS topics using IDL and generate Node.js topic classes from IDL.
    • +
    • AND/OR generate Node.js topic classes for topics that already exist in the DDS system.
    • +
    • Start writing your Node.js program using the Node.js API for Vortex DDS.
    • +
    +

    The core classes are Participant, Topic, Reader and Writer. +Publisher and Subscriber classes can be used to adjust the Quality of Service (QoS) defaults.

    +

    For details on setting QoS values with the API, see Quality of Service (QoS).

    +

    The following list shows the sequence in which you would use the Vortex classes:

    +
      +
    • Create a Participant instance.
    • +
    • Create one or more Topic instances.
    • +
    • If you require publisher or subscriber level non-default QoS settings, create Publisher and/or Subscriber instances. (The most common reason for changing publisher/subscriber QoS is to define non-default partitions.)
    • +
    • Create Reader and/or Writer classes using the Topic instances that you created.
    • +
    • If you required data filtering, create QueryCondition objects.
    • +
    • Create the core of program, writing and/or reading data and processing it.
    • +
    +
    +
    +

    5.2. Participant¶

    +

    The Node.js Participant class represents a DDS domain participant entity.

    +

    In DDS - “A domain participant represents the local membership of the application in a domain. A domain is a distributed concept that links all the applications able to communicate with each other. It represents a communication plane: only the publishers and subscribers attached to the same domain may interact.â€

    +

    Parameters:

    +
      +
    • {number} domainId 0 <= domainId <= 230 (Default: DDSConstants.DDS_DOMAIN_DEFAULT)
    • +
    • {QoS} qos (Default: undefined)
    • +
    • {object} listener (Default: undefined)
    • +
    +

    The optional parameters have defaults if not specified. If the qos is undefined, the OSPL default QoS is used.

    +

    Examples

    +

    Create a Vortex DDS domain participant. Returns participant or throws a DDSError if the participant cannot be created.

    +

    Create a domain participant in the default DDS domain (the one specified by the OSPL_URI environment variable).

    +
    const dds = require('vortexdds');
    +
    +// create domain participant
    +const participant = new dds.Participant();
    +
    +
    +

    Create a participant on the default domain with a QoS profile. Consider the code snippet below taken from example: GetSetQoSExample/GetSetQoSExample.js file.

    +
    const QOS_PATH = 'DDS_Get_Set_QoS.xml';
    +const QOS_PROFILE = 'DDS GetSetQosProfile';
    +const DOMAIN_ID = dds.DDS_DOMAIN_DEFAULT;
    +
    +async function main(){
    +
    +  // create a qos provider using qos xml file
    +  let qp = new dds.QoSProvider(QOS_PATH, QOS_PROFILE);
    +
    +  // get participant qos from qos provider
    +  let pqos = qp.getParticipantQos();
    +  let participant = new dds.Participant(DOMAIN_ID, pqos);
    +
    +}
    +
    +
    +
    +
    +

    5.3. Topic¶

    +

    The Node.js Topic class represents a DDS topic type. The DDS topic corresponds to a single data type. In DDS, data is distributed by publishing and subscribing topic data samples.

    +

    Javascript Topic instances can be created using an IDL file.

    +

    Step 1 - Generate TypeSupport objects from IDL file

    +

    The function getTopicTypeSupportsForIDL(idlPath) is provided to generate a TypeSupport instance for every topic defined in an IDL file. This function returns a promise, therefore should be called from an async function.

    +

    Step 2 - Create Topic instance using TypeSupport

    +

    The createTopicFor method in the Participant class can then be used to create a topic instance.

    +
    /**
    +* Create a Topic on this participant given a TypeSupport object.
    +* @param {string} topicName
    +* @param {TypeSupport} typeSupport
    +* @param {QoS} QoS (default undefined)
    +* @param {object} listener (default undefined)
    +* @returns {Topic} topic instance
    +*/
    +createTopicFor(
    +        topicName,
    +        typeSupport,
    +        qos = null,
    +        listener = null
    +) {
    +
    +
    +

    Example

    +

    Create a Vortex DDS topic named ‘HelloWorldData_Msg’ based on the DDS Topic type Msg from the HelloWorldData.idl file. This topic is created using the getTopicTypeSupportsForIDL function, and the Participant createTopicFor method.

    +

    Consider the code snippet below taken from example: HelloWorld/HelloWorldTopic.js file.

    +
    const dds = require('vortexdds');
    +const path = require('path');
    +
    +module.exports.create = async function(participant) {
    +
    +  const topicName = 'HelloWorldData_Msg';
    +  const idlName = 'HelloWorldData.idl';
    +  const idlPath = path.resolve(idlName);
    +
    +  //wait for dds.getTopicTypeSupportsForIDL to return a Map of typeSupports
    +  let typeSupports = await dds.getTopicTypeSupportsForIDL(idlPath);
    +
    +  //HelloWorldData.idl contains 1 topic
    +  let typeSupport = typeSupports.get('HelloWorldData::Msg');
    +
    +  //create topic qos
    +  let tqos = dds.QoS.topicDefault();
    +  tqos.durability = dds.DurabilityKind.Transient;
    +  tqos.reliability = dds.ReliabilityKind.Reliable;
    +
    +  //create topic
    +  return participant.createTopicFor(topicName, typeSupport, tqos);
    +
    +};
    +
    +
    +
    +
    +

    5.4. Publisher¶

    +

    The Node.js Publisher class represents a DDS publisher entity.

    +

    In DDS, a publisher is “an object responsible for data distribution. It may publish data of different data types.â€

    +

    Use of the Publisher class is optional. +In its place, you can use a Participant instance. +Reasons for explicitly creating a Publisher instance are:

    +
      +
    • to specify non-default QoS settings, including specifying the DDS partition upon which samples are written.
    • +
    • to control the timing of publisher creation and deletion.
    • +
    +

    Examples

    +

    Create a DDS Publisher entity. Returns publisher or throws a DDSError if the publisher cannot be created.

    +

    Create a publisher with participant.

    +
    const dds = require('vortexdds');
    +
    +//create participant
    +const participant = new dds.Participant();
    +
    +//create publisher
    +const pub = participant.createPublisher();
    +
    +
    +

    Create a publisher with a participant and QoS profile. Consider the code snippet below taken from example: GetSetQoSExample/GetSetQoSExample.js file.

    +
    const QOS_PATH = 'DDS_Get_Set_QoS.xml';
    +const QOS_PROFILE = 'DDS GetSetQosProfile';
    +const DOMAIN_ID = dds.DDS_DOMAIN_DEFAULT;
    +
    +async function main(){
    +
    +  // create a qos provider using qos xml file
    +  let qp = new dds.QoSProvider(QOS_PATH, QOS_PROFILE);
    +
    +  // get participant qos from qos provider
    +  let pqos = qp.getParticipantQos();
    +  let participant = new dds.Participant(DOMAIN_ID, pqos);
    +
    +  // get publisher qos from qos provider and create a publisher
    +  let pubqos = qp.getPublisherQos();
    +  let publisher = new dds.Publisher(participant, pubqos);
    +}
    +
    +
    +
    +
    +

    5.5. Writer¶

    +

    The Node.js Writer class represents a DDS data writer entity.

    +

    In DDS - “The writer is the object the application must use to communicate to a publisher the existence and value of data-objects of a given type.â€

    +

    A Writer class is required in order to write data to a DDS domain. +It is attached to a DDS publisher or a DDS domain participant.

    +

    A Writer class instance references an existing Topic instance.

    +

    Examples

    +

    Create a Vortex DDS domain writer and write data. Returns writer or throws a DDSError if the writer cannot be created. The example below uses the ‘HelloWorldData_Msg’ topic from the ‘HelloWorldTopic.js’ file as shown in Topic example. Consider the code snippet below taken from example: HelloWorld/HelloWorldPublisher.js file.

    +
    const dds = require('vortexdds');
    +const HelloWorldTopic = require('./HelloWorldTopic');
    +
    +main();
    +
    +async function main(){
    +
    +    //create domain participant
    +    let participant = new dds.Participant();
    +
    +    //wait for topic to be created
    +    let topic = await HelloWorldTopic.create(participant);
    +
    +    //create a publisher with publisher QoS
    +    let pqos = dds.QoS.publisherDefault();
    +    pqos.partition = 'HelloWorld example';
    +    let pub = participant.createPublisher(pqos, null);
    +
    +    //create a writer with writer QoS
    +    let wqos = dds.QoS.writerDefault();
    +    wqos.durability = dds.DurabilityKind.Transient;
    +    wqos.reliability = dds.ReliabilityKind.Reliable;
    +    let writer = pub.createWriter(topic, wqos, null);
    +
    +    //write one sample
    +    let msg = {userID: 1, message: 'Hello World'};
    +
    +    console.log('=== HelloWorldPublisher');
    +    console.log('=== [Publisher] writing a message containing :');
    +    console.log('    userID  : ' + msg.userID);
    +    console.log('    Message : ' + msg.message);
    +
    +    writer.write(msg);
    +
    +}
    +
    +
    +
    +
    +

    5.6. Subscriber¶

    +

    The Node.js Subscriber class represents a DDS subscriber entity.

    +

    In DDS, a subscriber is “an object responsible for receiving published data and making it available to the receiving application. It may receive and dispatch data of different specified types.â€

    +

    Use of the Subscriber class is optional. +In its place, you can use a Participant instance. +Reasons for explicitly creating a Subscriber instance are:

    +
      +
    • to specify non-default QoS settings, including specifying the DDS partition upon which samples are written.
    • +
    • to control the timing of subscriber creation and deletion.
    • +
    +

    Examples

    +

    Create a Vortex DDS domain subscriber. Returns subscriber or throw a DDSError if the subscriber cannot be created.

    +

    Create a subscriber with participant.

    +
    const dds = require('vortexdds');
    +
    +//create participant
    +consr participant = new dds.Participant();
    +
    +//create Subscriber
    +const sub = participant.createSubscriber();
    +
    +
    +

    Create a subscriber with participant and QoS profile, where the DDS_DefaultQoS_All.xml file is located in the project directory.

    +
    const QOS_PATH = 'DDS_Get_Set_QoS.xml';
    +const QOS_PROFILE = 'DDS GetSetQosProfile';
    +const DOMAIN_ID = dds.DDS_DOMAIN_DEFAULT;
    +
    +async function main(){
    +
    +  // create a qos provider using qos xml file
    +  let qp = new dds.QoSProvider(QOS_PATH, QOS_PROFILE);
    +
    +  // get participant qos from qos provider
    +  let pqos = qp.getParticipantQos();
    +  let participant = new dds.Participant(DOMAIN_ID, pqos);
    +
    +  /*
    +     Get subscriber qos from qos provider and create a subscriber
    +     In the qos xml file provided with this example, there are
    +     two subscriber qos. The subscriber qos with
    +     id 'subscriber1' is chosen below
    +
    +     NOTE: If there are more than one qos entries in the xml file
    +     for a dds entity, then the entity qos id must be specified.
    +     Otherwise an error will be thrown while trying to get the
    +     respective entity qos from the qos provider
    +   */
    +  let subqos = qp.getSubscriberQos('subscriber1');
    +  let subscriber = new dds.Subscriber(participant, subqos);
    +  }
    +
    +
    +
    +
    +

    5.7. Reader¶

    +

    The Node.js Reader class represents a DDS data reader entity.

    +

    In DDS - “To access the received data, the application must use a typed reader attached to the subscriber.â€

    +

    A Reader class is required in order to write data to a DDS domain. +It is attached to a DDS subscriber or a DDS participant.

    +

    A Reader class instance references an existing Topic instance.

    +

    Examples

    +

    Create a Vortex DDS domain reader with a subscriber and read/take data. Returns reader or throw a DDSError instance if the reader cannot be created. Consider the code snippet below taken from example: HelloWorld/HelloWorldSubscriber.js file.

    +
    const dds = require('vortexdds');
    +const HelloWorldTopic = require('./HelloWorldTopic');
    +
    +main();
    +
    +async function main(){
    +
    +    //create domain participant
    +    let participant = new dds.Participant();
    +
    +    //wait for topic to be created
    +    let topic = await HelloWorldTopic.create(participant);
    +
    +    //create subscriber with subscriber QoS
    +    let sqos = dds.QoS.subscriberDefault();
    +    sqos.partition = 'HelloWorld example';
    +    let sub = participant.createSubscriber(sqos, null);
    +
    +    //create reader with reader QoS
    +    let rqos = dds.QoS.readerDefault();
    +    rqos.durability = dds.DurabilityKind.Transient;
    +    rqos.reliability = dds.ReliabilityKind.Reliable;
    +    let reader = sub.createReader(topic, rqos, null);
    +
    +    console.log('=== [Subscriber] Ready ...');
    +
    +    attemptTake(participant, reader, 0);
    +
    +    participant.delete();
    +   }
    +
    +   /* Attempt to take from the reader every 200 ms.
    +    * If a successful take occurs, we are done.
    +    * If a successful take does not occur after 100 attempts,
    +    * return.
    +    */
    +   function attemptTake(participant, reader, numberAttempts){
    +
    +    setTimeout(function() {
    +            let takeArray = reader.take(1);
    +            if (takeArray.length > 0 && (takeArray[0].info.valid_data === 1)) {
    +            console.log('=== [Subscriber] message received :');
    +            console.log('    userID  : ' + takeArray[0].sample.userID);
    +            console.log('    Message : ' + takeArray[0].sample.message);
    +            } else {
    +            if (numberAttempts < 100){
    +            return attemptTake(participant, reader, numberAttempts + 1);
    +            }
    +            }
    +            participant.delete();
    +            return;
    +    }, 200);
    +   }
    +
    +
    +

    Take data with read condition from a data reader.

    +
    const numberOfSamples = 10;
    +const cond = new dds.ReadCondition(reader, dds.StateMask.any);
    +let readArray = reader.takeCond(numberOfSamples, cond);
    +
    +
    +

    Read data with read condition from a data reader.

    +
    const numberOfSamples = 10;
    +const cond = new dds.ReadCondition(reader, dds.StateMask.any);
    +let readArray = reader.readCond(numberOfSamples, cond);
    +
    +
    +
    +
    +

    5.8. WaitSet¶

    +

    The Node.js WaitSet class represents a DDS wait set.

    +

    A WaitSet object allows an application to wait until one or more of the attached Condition objects evaluates to true or until the timeout expires.

    +

    Example

    +

    Create a WaitSet with a read condition to wait until publication is matched. Consider the code snippet below taken from example: PingPong/ping.js file.

    +
    const dds = require('vortexdds');
    +const PingPongTopic = require('./PingPongTopic');
    +
    +// we iterate for 20 samples
    +const numSamples = 20;
    +main();
    +
    +async function main() {
    +  // create our entities
    +  let participant = new dds.Participant();
    +  let topic = await PingPongTopic.create(participant);
    +
    +  // create publisher on partition 'Ping' and writer on the publisher
    +  // on pong, we have a subscriber on the same partition and topic
    +  let pqos = dds.QoS.publisherDefault();
    +  pqos.partition = 'Ping';
    +  let publisher = participant.createPublisher(pqos, null);
    +  let writer = publisher.createWriter(topic);
    +
    +  // create a subscriber on partition 'Pong' and a reader on the subscriber
    +  let sqos = dds.QoS.subscriberDefault();
    +  sqos.partition = 'Pong';
    +  let subscriber = participant.createSubscriber(sqos);
    +  let reader = subscriber.createReader(topic);
    +
    +  // create waitset which waits until pong subscriber on partition
    +  // 'Ping' is found
    +  let pubMatchedWaitset = new dds.Waitset();
    +  let statCond = new dds.StatusCondition(writer);
    +  statCond.enable(dds.StatusMask.publication_matched);
    +  pubMatchedWaitset.attach(statCond, writer);
    +
    +  // waitset for new data
    +  let newDataWaitset = new dds.Waitset();
    +  let newDataCond = new dds.ReadCondition(reader,
    +    dds.StateMask.sample.not_read);
    +  newDataWaitset.attach(newDataCond, reader);
    +
    +  // block until pong has been found
    +  console.log('Waiting for pong subscriber to be found...');
    +  pubMatchedWaitset.wait(dds.DDSConstants.DDS_INFINITY, function(err, res) {
    +    if (err) throw err;
    +    console.log('Found pong subscriber.');
    +    // Ping writes the first message
    +    let msg = {userID: 0, message: 'from ping'};
    +    console.log('sending ' + JSON.stringify(msg));
    +    writer.write(msg);
    +    onDataAvailable(participant, newDataWaitset, reader, writer, 0);
    +  });
    +}
    +
    +/* onDataAvailable waits for new data. When we have new data, it
    + * reads it, prints it, and sends back a message with the userID
    + * field incremented by one and 'from ping' in the message field.
    + * It then calls onDataAvailable again.
    + * We quit when iterLower === numSamples (20 iterations in this example).
    + */
    +function onDataAvailable(
    +  participant,
    +  ws,
    +  reader,
    +  writer,
    +  iterLower
    +) {
    +  if (iterLower === numSamples) {
    +    console.log('Done');
    +    participant.delete();
    +    return;
    +  }
    +  // when we get a message from pong, read it, then send it back
    +  // with userID+1 and message 'from ping'
    +  ws.wait(dds.DDSConstants.DDS_INFINITY, function(err, res) {
    +    if (err) throw err;
    +    let takeArray = reader.take(1);
    +    if (takeArray.length > 0 && (takeArray[0].info.valid_data === 1)) {
    +      let sample = takeArray[0].sample;
    +      console.log('received: ' + JSON.stringify(sample));
    +      let msg = {userID: sample.userID + 1, message: 'from ping'};
    +      console.log('sending ' + JSON.stringify(msg));
    +      writer.write(msg);
    +    }
    +    onDataAvailable(participant, ws, reader, writer, iterLower + 1);
    +  });
    +}
    +
    +
    +
    +
    +

    5.9. QueryCondition¶

    +

    The Node.js QueryCondition class represents a DDS query entity.

    +

    A query is a data reader, restricted to accessing data that matches specific status conditions and/or a filter expression.

    +

    A QueryCondition class instance references an existing Reader instance.

    +

    Example

    +

    Create a QueryCondition with a state mask and a filter expression for a reader and take data. Consider the code snippet below taken from example: jsshapes/read.js file.

    +
    const dds = require('vortexdds');
    +const ShapeTopicHelper = require('./ShapeTopicHelper');
    +const util = require('util');
    +
    +// we are reading 100 samples of a blue circle
    +const shapeName = 'Circle';
    +const numSamples = 100;
    +const mask = dds.StateMask.sample.not_read;
    +const sqlExpression = 'color=%0';
    +const params = ['BLUE'];
    +
    +main();
    +
    +async function main() {
    +  const participant = new dds.Participant();
    +
    +  // set up our topic
    +  const circleTopic = await ShapeTopicHelper.create(participant, 'Circle');
    +
    +  // our reader has volatile qos
    +  let readerqosprovider = new dds.QoSProvider(
    +    './DDS_VolatileQoS_All.xml',
    +    'DDS VolatileQosProfile'
    +  );
    +
    +  // set up circle reader
    +  const circleReader = participant.createReader(circleTopic,
    +    readerqosprovider.getReaderQos());
    +
    +  // set up waitset
    +  const newDataWs = new dds.Waitset();
    +  const queryCond = new dds.QueryCondition(
    +    circleReader,
    +    mask,
    +    sqlExpression,
    +    params,
    +    1
    +  );
    +  // attach the query condition
    +  newDataWs.attach(queryCond, circleReader);
    +
    +  console.log('Waiting for demo_ishapes to publish a blue circle...');
    +  onDataAvailable(participant, newDataWs, circleReader, queryCond, 0);
    +};
    +
    +/* onDataAvailable waits until we have new data (with the query condition).
    + * when we do, we read it, print the data (shape data), and then call
    + * onDataAvailable with iterLower incremented by one, to wait for more data.
    + * This repeats until iterLower === numSamples (100 samples in this case).
    + * When iterLower === numSamples, we delete the participant and quit.
    + */
    +function onDataAvailable(
    +  participant,
    +  ws,
    +  reader,
    +  queryCond,
    +  iterLower
    +) {
    +  if (iterLower === numSamples) {
    +    console.log('Done.');
    +    participant.delete();
    +    return;
    +  }
    +  ws.wait(dds.DDSConstants.DDS_INFINITY, function(err, res) {
    +    if (err) throw err;
    +    let sampleArray = reader.takeCond(1, queryCond);
    +    if (sampleArray.length > 0 && (sampleArray[0].info.valid_data === 1)) {
    +      let sample = sampleArray[0].sample;
    +      console.log(
    +        util.format(
    +          '%s %s of size %d at (%d,%d)',
    +          sample.color,
    +          shapeName,
    +          sample.shapesize,
    +          sample.x,
    +          sample.y
    +        )
    +      );
    +    }
    +    onDataAvailable(participant, ws, reader, queryCond, iterLower + 1);
    +  });
    +}
    +
    +
    +
    +
    + + +
    +
    +
    +
    +
    + +

    Table Of Contents

    + + +

    Previous topic

    +

    4. Examples

    +

    Next topic

    +

    6. Quality of Service (QoS)

    +

    This Page

    + + + +
    +
    +
    +
    + + + + \ No newline at end of file diff --git a/docs/html/NodeJSDCPSAPIGuide/examples.html b/docs/html/NodeJSDCPSAPIGuide/examples.html new file mode 100644 index 000000000..b4143bfef --- /dev/null +++ b/docs/html/NodeJSDCPSAPIGuide/examples.html @@ -0,0 +1,267 @@ + + + + + + + + 4. Examples — Node.js DCPS API Guide + + + + + + + + + + + + + + + +
    +
    +
    +
    + +
    +

    4. Examples¶

    +

    Examples are provided to demonstrate the Node.js DCPS features.

    +

    The examples can be found in the following directory:

    +
    +
    $OSPL_HOME/tools/nodejs/examples
    +

    WHERE:

    +
    +

    Linux

    +
    +
    OSPL_HOME = INSTALLDIR/ADLINK/Vortex_v2/Device/VortexOpenSplice/6.9.x/HDE/x86_64.linux
    +

    Windows

    +
    +
    OSPL_HOME = INSTALLDIR\ADLINK\Vortex_v2\Device\VortexOpenSplice\6.9.x\HDE\x86_64.win64
    +
    +
    +

    4.1. Example Files¶

    +

    Each subfolder consists of a Node.js example project.

    +
    +

    4.1.1. Examples¶

    + ++++ + + + + + + + + + + + + + + + + + + + + + + + + + +
    ExampleDescription
    HelloWorldDemonstrates how to read and write a simple +topic in DDS
    jsshapesDemonstrates how to read and write to a +DDS application
    IoTDataDemonstrates reading and writing an IoTData topic
    PingPongDemonstrates reading, writing, and waitsets
    QoSExampleDemonstrates QoS settings
    GetSetQoSExampleDemonstrates getting and setting QoS using +QoS Provider and DCPS api
    +
    +
    +

    4.1.2. File Types¶

    +

    The examples directory contains files of different types.

    + ++++ + + + + + + + + + + + + + + + + + + + +
    File TypeDescription
    jsA program file or script written in JavaScript
    package.jsonLists the packages that a project depends on
    xmlAn XML file that contains one or more Quality of Service (QoS) profiles for DDS entities
    idlAn interface description language file used to define topic(s)
    +
    +
    +
    +

    4.2. Running Examples¶

    +

    To run a Node.js example:

    +
      +
    1. Setup OSPL environment variables

      +
      +

      Linux

      +
        +
      • For each example javascript file to be run, open a Linux terminal

        +
      • +
      • Navigate to directory containing release.com file (OSPL_HOME)

        +

        /INSTALLDIR/ADLINK/Vortex_v2/Device/VortexOpenSplice/6.9.x/HDE/x86_64.linux

        +
      • +
      • Run release.com (“. release.comâ€)

        +
      • +
      +

      Windows

      +
        +
      • For each example javascript file to be run, open a command prompt

        +
      • +
      • Navigate to directory containing release.bat file (OSPL_HOME)

        +

        \INSTALLDIR\ADLINK\Vortex_v2\Device\VortexOpenSplice\6.9.x\HDE\x86_64.win64

        +
      • +
      • Run release.bat (“release.batâ€), if OSPL environment variables are not set system wide

        +
      • +
      +
      +
    2. +
    3. Change directory to the example folder

      +
      +

      Example:

      +
      +

      $OSPL_HOME/tools/nodejs/examples/HelloWorld

      +
      +
      +
    4. +
    5. Run npm install to install the Node.js DCPS API (vortexdds-x.y.z.tgz) and all other dependencies

      +
      +

      npm install

      +
      +
    6. +
    +
    +

    Note

    +

    If you are running the examples from another directory outside the OSPL install, then you will need to manually install the Node.js DCPS API first and then run npm install for the example dependencies as follows:

    +

    npm install $OSPL_HOME/tools/nodejs/vortexdds-x.y.z.tgz

    +

    npm install

    +
    +
      +
    1. Run .js file(s) in a terminal/command shell

      +
      +

      Example:

      +
      +

      node HelloWorldSubscriber.js

      +
      +
      +
    2. +
    +
    +
    + + +
    +
    +
    +
    +
    + +

    Table Of Contents

    + + +

    Previous topic

    +

    3. Installation

    +

    Next topic

    +

    5. Node.js API for Vortex DDS

    +

    This Page

    + + + +
    +
    +
    +
    + + + + \ No newline at end of file diff --git a/docs/html/NodeJSDCPSAPIGuide/genindex.html b/docs/html/NodeJSDCPSAPIGuide/genindex.html new file mode 100644 index 000000000..8c1ed6ce2 --- /dev/null +++ b/docs/html/NodeJSDCPSAPIGuide/genindex.html @@ -0,0 +1,94 @@ + + + + + + + + + Index — Node.js DCPS API Guide + + + + + + + + + + + + + +
    +
    +
    +
    + + +

    Index

    + +
    + +
    + + +
    +
    +
    +
    +
    + + + + + + +
    +
    +
    +
    + + + + \ No newline at end of file diff --git a/docs/html/NodeJSDCPSAPIGuide/index.html b/docs/html/NodeJSDCPSAPIGuide/index.html new file mode 100644 index 000000000..362d0e2d8 --- /dev/null +++ b/docs/html/NodeJSDCPSAPIGuide/index.html @@ -0,0 +1,188 @@ + + + + + + + + Node.js DCPS API Guide — Node.js DCPS API Guide + + + + + + + + + + + + + + +
    + +
    +
    + +

    Table Of Contents

    + + +

    Next topic

    +

    1. Preface

    +

    This Page

    + + + +
    +
    +
    +
    + + + + \ No newline at end of file diff --git a/docs/html/NodeJSDCPSAPIGuide/installation.html b/docs/html/NodeJSDCPSAPIGuide/installation.html new file mode 100644 index 000000000..2b306f519 --- /dev/null +++ b/docs/html/NodeJSDCPSAPIGuide/installation.html @@ -0,0 +1,269 @@ + + + + + + + + 3. Installation — Node.js DCPS API Guide + + + + + + + + + + + + + + + +
    +
    +
    +
    + +
    +

    3. Installation¶

    +

    This section describes the procedure to install the Node.js DCPS API on a Linux or Windows platform.

    +
    +

    3.1. Dependencies¶

    +

    The Node.js DCPS API has several dependencies that must be installed.

    +
    +

    3.1.1. Linux 64-bit¶

    +
    +
      +
    • Node.js LTS 8.11.1 or later (preferably Node.js LTS 8.x version)
    • +
    • npm (node package manager) version 5.6.0 or later (typically included with a Node.js install)
    • +
    • Python 2.7 (v3.x.x is not supported)
    • +
    • make
    • +
    • C/C++ compiler toolchain like GCC
    • +
    +
    +
    +
    +

    3.1.2. Windows 64-bit¶

    +
    +
      +
    • Node.js LTS 8.11.1 or later (preferably Node.js LTS 8.x version)
    • +
    • npm (node package manager) version 5.6.0 or later (typically included with a Node.js install)
    • +
    • Python 2.7 (v3.x.x is not supported)
    • +
    • Visual C++ build tools (VS 2015 or VS 2017)
    • +
    +
    +
    +

    3.1.2.1. Python and Visual C++ build tools install¶

    +
    +
      +
    • Install all the required tools and configurations using Microsoft’s windows-build-tools by running the following from a command prompt as an administrator:

      +

      npm install - -global - -production windows-build-tools

      +
      +

      (or)

      +
      +
    • +
    • Install tools and configuration manually

      +
      +
        +
      • Visual C++ build tools (VS 2015 or VS 2017)
      • +
      • Python 2.7 (v3.x.x is not supported)
      • +
      +
      +
    • +
    +
    +

    More detailed information on installing Python and Visual C++ build tools on Windows can be found at: https://github.com/Microsoft/nodejs-guidelines/blob/master/windows-environment.md#compiling-native-addon-modules

    +
    +
    +
    +
    +

    3.2. OpenSplice (OSPL) and Node.js DCPS API Installation¶

    +

    Steps:

    +
      +
    1. Install OSPL. Choose an HDE type installer which is a Host Development Environment. This contains all of the services, libraries, header files and tools needed to develop +applications using OpenSplice. The Node.js DCPS API is included in the following installers:

      + ++++ + + + + + + + + + + + + + + + + +
      PlatformPlatform Code
      Ubuntu1404 64 bitP704
      Ubuntu1604 64 bitP768
      Windows10 64 bitP738
      +

      Example installer:

      +
      +

      P704-VortexOpenSplice-6.9.x-HDE-x86.linux-gcc4.1.2-glibc2.5-installer.run

      +
      +
    2. +
    3. Setup OSPL license. Copy the license.lic file into the appropriate license directory

      +
    4. +
    +
    +
    /INSTALLDIR/Vortex_v2/license
    +
      +
    1. Node.js DCPS API files are contained in a tools/nodejs folder
    2. +
    +
    +
    Example: +$OSPL_HOME/tools/nodejs
    +
    +
    +

    3.3. Installing Node.js DCPS API in a Node.js application¶

    +
      +
    1. Start a command shell. Setup OSPL environment variables by running release.com or release.bat which can be found in

      +

      Linux

      +

      /INSTALLDIR/ADLINK/Vortex_v2/Device/VortexOpenSplice/6.9.x/HDE/x86_64.linux/

      +

      Windows

      +

      \INSTALLDIR\ADLINK\Vortex_v2\Device\VortexOpenSplice\6.9.x\HDE\x86_64.windows\

      +
    2. +
    3. Create a node project folder, if not created

      +

      mkdir <project_name>

      +

      cd <project_name>

      +

      npm init

      +
    4. +
    5. Change directory to node project folder

      +
    6. +
    7. Install the Node.js DCPS API to your project by executing:

      +

      Linux

      +

      npm install $OSPL_HOME/tools/nodejs/vortexdds-x.y.z.tgz

      +

      Windows

      +

      npm install %OSPL_HOME%\tools\nodejs\vortexdds-x.y.z.tgz

      +
    8. +
    +
    +
    +

    3.4. Examples and Documentation¶

    +
      +
    1. Examples directory:

      +
      +

      $OSPL_HOME/tools/nodejs/examples

      +
      +
    2. +
    3. Node.js DCPS API documentation directory:

      +
      +

      $OSPL_HOME/docs/nodejs/html

      +
      +
    4. +
    5. Node.js DCPS User Guide (HTML and PDF) directory:

      +
      +

      $OSPL_HOME/docs

      +
      +
    6. +
    +
    +
    + + +
    +
    +
    +
    + +
    +
    +
    + + + + \ No newline at end of file diff --git a/docs/html/NodeJSDCPSAPIGuide/introduction.html b/docs/html/NodeJSDCPSAPIGuide/introduction.html new file mode 100644 index 000000000..68b36ab82 --- /dev/null +++ b/docs/html/NodeJSDCPSAPIGuide/introduction.html @@ -0,0 +1,135 @@ + + + + + + + + 2. Introduction — Node.js DCPS API Guide + + + + + + + + + + + + + + + +
    +
    +
    +
    + +
    +

    2. Introduction¶

    +

    The Node.js DCPS API provides users with Node.js classes to model DDS communication using JavaScript and pure DDS applications.

    +

    The Node.js DCPS API is a native JavaScript binding that supports DDS functionality. The language binding consists of Node.js classes and wrapper implementations of the C99 API (C API for DDS). It makes use of ECMAScript 2015 (ES6) JavaScript language features and leverages ease of use by providing a higher level of abstraction.

    +

    Please see Limitations of Node.js Support for limitations of Node.js DDS API support.

    +
    +

    2.1. DDS¶

    +

    What is DDS?

    +

    “The Data Distribution Service (DDSâ„¢) is a middleware protocol and API standard for data-centric connectivity from the Object Management Group® (OMG®). It integrates the components of a system together, providing low-latency data connectivity, extreme reliability, and a scalable architecture that business and mission-critical Internet of Things (IoT) applications need.â€

    +

    “The main goal of DDS is to share the right data at the right place at the right time, even between time-decoupled publishers and consumers. DDS implements global data space by carefully replicating relevant portions of the logically shared dataspace.†DDS specification

    +
    +DDS +
    +

    Further Documentation

    +

    http://portals.omg.org/dds/

    +

    http://ist.adlinktech.com/

    +
    +
    + + +
    +
    +
    +
    +
    + +

    Table Of Contents

    + + +

    Previous topic

    +

    1. Preface

    +

    Next topic

    +

    3. Installation

    +

    This Page

    + + + +
    +
    +
    +
    + + + + \ No newline at end of file diff --git a/docs/html/NodeJSDCPSAPIGuide/objects.inv b/docs/html/NodeJSDCPSAPIGuide/objects.inv new file mode 100644 index 000000000..dbe9f0e5a --- /dev/null +++ b/docs/html/NodeJSDCPSAPIGuide/objects.inv @@ -0,0 +1,7 @@ +# Sphinx inventory version 2 +# Project: Node.js DCPS API Guide +# Version: Beta 6.x +# The remainder of this file is compressed using zlib. +xÚSÁN!¼ó/Ñ=ÐÄ«7ci¢Í6k¼6o[¶@7íßË.KéÖšzƒ÷fÞÀ0lk¬©¤Bp^<)ö +è#l[†F+ÚÉÚ×ê榄"‚‰’µôÌK£Ý˜èM#yb¼Ÿ Ls#p²qPîšÆXOV¨¥¸OHÕ8fÝšHí¦V:Ùë°'½Oc¬n‰ÚK/3þ³ƒ…Û{NÇ/Ý>wòísèÁsÖH¨Œ…6¼Z×Ä;&Ý8˜40idÒŽ™ò¹˜õC¿âÐé´$ÜhϸwpÚxÉñL'õ£FÚÑ„}Éôy,Ýý§±!¹’{-Ó¡BØÅŽ)é]PK´mІûùÒX¬?{Ø¡˜ä‹¸ž5DmÌ*Ó„tÜ´h~•~I3Í´>ð6ž:Míô9Ð:¸Áß$ãiÄSòá¢qá \ No newline at end of file diff --git a/docs/html/NodeJSDCPSAPIGuide/preface.html b/docs/html/NodeJSDCPSAPIGuide/preface.html new file mode 100644 index 000000000..42818e720 --- /dev/null +++ b/docs/html/NodeJSDCPSAPIGuide/preface.html @@ -0,0 +1,143 @@ + + + + + + + + 1. Preface — Node.js DCPS API Guide + + + + + + + + + + + + + + + +
    +
    +
    +
    + +
    +

    1. Preface¶

    +
    +

    1.1. About the Node.js DCPS API Guide¶

    +

    The Node.js DCPS API Guide is a starting point for anyone using, developing or running Node.js applications with Vortex OpenSplice.

    +

    This guide contains:

    +
    +
      +
    • Node.js DCSP API setup instructions
    • +
    • location of Node.js DCPS API dds module documentation
    • +
    • overview of general DDS concepts and Node.js API for Vortex DDS
    • +
    • a listing of examples, and how to run them
    • +
    • detailed information on how to specify DDS entity Quality of Service (QoS)
    • +
    • how to register DDS topics
    • +
    +
    +

    This reference guide is based on the OMG’s Data Distribution Service Specification.

    +

    Please note that this guide is not intended to provide a detailed explanation of the aforementioned OMG specifications or the Vortex OpenSplice product. It provides an introduction to the essential concepts and enables users to begin using the Node.js DCPS API as quickly as possible.

    +
    +
    +

    1.2. Intended Audience¶

    +

    The Node.js Reference Guide is intended to be used by JavaScript programmers who are +using Vortex OpenSplice to develop Node.js applications.

    +
    +
    + + +
    +
    +
    +
    +
    + +

    Table Of Contents

    + + +

    Previous topic

    +

    Node.js DCPS API Guide

    +

    Next topic

    +

    2. Introduction

    +

    This Page

    + + + +
    +
    +
    +
    + + + + \ No newline at end of file diff --git a/docs/html/NodeJSDCPSAPIGuide/qos_provider.html b/docs/html/NodeJSDCPSAPIGuide/qos_provider.html new file mode 100644 index 000000000..f88749efe --- /dev/null +++ b/docs/html/NodeJSDCPSAPIGuide/qos_provider.html @@ -0,0 +1,607 @@ + + + + + + + + 6. Quality of Service (QoS) — Node.js DCPS API Guide + + + + + + + + + + + + + + + +
    +
    +
    +
    + +
    +

    6. Quality of Service (QoS)¶

    +

    The following section explains how to set the Quality of Service (QoS) for a DDS entity.

    +

    Users have two options available to set the QoS for an entity or entities. They can define the QoS settings using an XML file, or they can use the Node.js DCPS APIs. Both of these options are explained.

    +

    If a QoS setting for an entity is not set using an xml file or the Node.js DCPS APIs, the defaults will be used. This allows a user the ability to override only those settings that require non-default values.

    +

    The code snippets referenced are taken from the runnable examples.

    +
    +

    Note

    +
      +
    • The Examples section provides the examples directory location, example descriptions and running instructions.
    • +
    +
    +
    +

    6.1. Setting QoS Using QoS Provider XML File¶

    +

    QoS for DDS entities can be set using XML files based on the XML schema file QoSProfile.xsd. +These XML files contain one or more QoS profiles for DDS entities. OSPL includes an XSD (XML schema), that is located in $OSPL_HOME/etc/DDS_QoSProfile.xml. This can be used with XML schema core editors to help create valid XML files.

    +

    Sample QoS Profile XML files can be found in the examples directory. Typically you will place the qos files in a subdirectory of your Node.js application.

    +
    +

    6.1.1. QoS Profile¶

    +

    A QoS profile consists of a name and optionally a base_name attribute. The base_name attribute allows a +QoS or a profile to inherit values from another QoS or profile in the same file. The file contains QoS +elements for one or more DDS entities.

    +

    A skeleton file without any QoS values is displayed below to show the structure of the file.

    +
    <dds xmlns="http://www.omg.org/dds/"
    + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    + xsi:schemaLocation="file:DDS_QoSProfile.xsd">
    +    <qos_profile name="DDS QoS Profile Name">
    +        <datareader_qos></datareader_qos>
    +        <datawriter_qos></datawriter_qos>
    +        <domainparticipant_qos></domainparticipant_qos>
    +        <subscriber_qos></subscriber_qos>
    +        <publisher_qos></publisher_qos>
    +        <topic_qos></topic_qos>
    +    </qos_profile>
    +</dds>
    +
    +
    +

    Example: Persistent QoS XML file

    +

    The example below specifies the persistent QoS XML file which is used by the QoSProvider.

    +
    <?xml version="1.0" encoding="UTF-8"?>
    +<dds xmlns="http://www.omg.org/dds/"
    +xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    +xsi:schemaLocation="file:DDS_QoSProfile.xsd">
    +<qos_profile name="DDS PersistentQosProfile">
    +     <domainparticipant_qos>
    +          <user_data>
    +               <value></value>
    +          </user_data>
    +          <entity_factory>
    +               <autoenable_created_entities>true</autoenable_created_entities>
    +          </entity_factory>
    +     </domainparticipant_qos>
    +     <subscriber_qos name="subscriber1">
    +          <presentation>
    +               <access_scope>INSTANCE_PRESENTATION_QOS</access_scope>
    +               <coherent_access>true</coherent_access>
    +               <ordered_access>true</ordered_access>
    +          </presentation>
    +          <partition>
    +               <name>partition1</name>
    +          </partition>
    +          <group_data>
    +               <value></value>
    +          </group_data>
    +          <entity_factory>
    +               <autoenable_created_entities>true</autoenable_created_entities>
    +          </entity_factory>
    +     </subscriber_qos>
    +     <subscriber_qos name="subscriber2">
    +          <presentation>
    +               <access_scope>INSTANCE_PRESENTATION_QOS</access_scope>
    +               <coherent_access>false</coherent_access>
    +               <ordered_access>false</ordered_access>
    +          </presentation>
    +          <partition>
    +               <name></name>
    +          </partition>
    +          <group_data>
    +               <value></value>
    +          </group_data>
    +          <entity_factory>
    +               <autoenable_created_entities>true</autoenable_created_entities>
    +          </entity_factory>
    +     </subscriber_qos>
    +     <publisher_qos>
    +          <presentation>
    +               <access_scope>INSTANCE_PRESENTATION_QOS</access_scope>
    +               <coherent_access>true</coherent_access>
    +               <ordered_access>true</ordered_access>
    +          </presentation>
    +          <partition>
    +               <name>partition1</name>
    +          </partition>
    +          <group_data>
    +               <value></value>
    +          </group_data>
    +          <entity_factory>
    +               <autoenable_created_entities>true</autoenable_created_entities>
    +          </entity_factory>
    +     </publisher_qos>
    +     <datawriter_qos>
    +          <durability>
    +               <kind>PERSISTENT_DURABILITY_QOS</kind>
    +          </durability>
    +          <deadline>
    +               <period>
    +                    <sec>DURATION_INFINITE_SEC</sec>
    +                    <nanosec>DURATION_INFINITE_NSEC</nanosec>
    +               </period>
    +          </deadline>
    +          <latency_budget>
    +               <duration>
    +                    <sec>0</sec>
    +                    <nanosec>0</nanosec>
    +               </duration>
    +          </latency_budget>
    +          <liveliness>
    +               <kind>AUTOMATIC_LIVELINESS_QOS</kind>
    +               <lease_duration>
    +                    <sec>DURATION_INFINITE_SEC</sec>
    +                    <nanosec>DURATION_INFINITE_NSEC</nanosec>
    +               </lease_duration>
    +          </liveliness>
    +          <reliability>
    +               <kind>RELIABLE_RELIABILITY_QOS</kind>
    +               <max_blocking_time>
    +                    <sec>0</sec>
    +                    <nanosec>100000000</nanosec>
    +               </max_blocking_time>
    +         </reliability>
    +         <destination_order>
    +              <kind>BY_RECEPTION_TIMESTAMP_DESTINATIONORDER_QOS</kind>
    +          </destination_order>
    +          <history>
    +               <kind>KEEP_LAST_HISTORY_QOS</kind>
    +               <depth>100</depth>
    +          </history>
    +          <resource_limits>
    +               <max_samples>LENGTH_UNLIMITED</max_samples>
    +               <max_instances>LENGTH_UNLIMITED</max_instances>
    +               <max_samples_per_instance>LENGTH_UNLIMITED</max_samples_per_instance>
    +          </resource_limits>
    +          <transport_priority>
    +               <value>0</value>
    +          </transport_priority>
    +          <lifespan>
    +               <duration>
    +                    <sec>DURATION_INFINITE_SEC</sec>
    +                    <nanosec>DURATION_INFINITE_NSEC</nanosec>
    +               </duration>
    +          </lifespan>
    +          <user_data>
    +               <value></value>
    +         </user_data>
    +         <ownership>
    +              <kind>SHARED_OWNERSHIP_QOS</kind>
    +          </ownership>
    +          <ownership_strength>
    +               <value>0</value>
    +          </ownership_strength>
    +          <writer_data_lifecycle>
    +               <autodispose_unregistered_instances>true</autodispose_unregistered_instances>
    +          </writer_data_lifecycle>
    +     </datawriter_qos>
    +     <datareader_qos>
    +          <durability>
    +              <kind>PERSISTENT_DURABILITY_QOS</kind>
    +          </durability>
    +          <deadline>
    +               <period>
    +                    <sec>DURATION_INFINITE_SEC</sec>
    +                    <nanosec>DURATION_INFINITE_NSEC</nanosec>
    +               </period>
    +          </deadline>
    +          <latency_budget>
    +               <duration>
    +                    <sec>0</sec>
    +                    <nanosec>0</nanosec>
    +               </duration>
    +          </latency_budget>
    +          <liveliness>
    +               <kind>AUTOMATIC_LIVELINESS_QOS</kind>
    +               <lease_duration>
    +                    <sec>DURATION_INFINITE_SEC</sec>
    +                    <nanosec>DURATION_INFINITE_NSEC</nanosec>
    +               </lease_duration>
    +          </liveliness>
    +          <reliability>
    +               <kind>BEST_EFFORT_RELIABILITY_QOS</kind>
    +               <max_blocking_time>
    +                    <sec>0</sec>
    +                    <nanosec>100000000</nanosec>
    +               </max_blocking_time>
    +          </reliability>
    +          <destination_order>
    +                <kind>BY_RECEPTION_TIMESTAMP_DESTINATIONORDER_QOS</kind>
    +          </destination_order>
    +          <history>
    +               <kind>KEEP_ALL_HISTORY_QOS</kind>
    +          </history>
    +          <resource_limits>
    +               <max_samples>LENGTH_UNLIMITED</max_samples>
    +               <max_instances>LENGTH_UNLIMITED</max_instances>
    +               <max_samples_per_instance>LENGTH_UNLIMITED</max_samples_per_instance>
    +          </resource_limits>
    +          <user_data>
    +               <value></value>
    +          </user_data>
    +          <ownership>
    +               <kind>SHARED_OWNERSHIP_QOS</kind>
    +          </ownership>
    +          <time_based_filter>
    +               <minimum_separation>
    +                    <sec>0</sec>
    +                    <nanosec>0</nanosec>
    +               </minimum_separation>
    +          </time_based_filter>
    +          <reader_data_lifecycle>
    +               <autopurge_nowriter_samples_delay>
    +                    <sec>DURATION_INFINITE_SEC</sec>
    +                    <nanosec>DURATION_INFINITE_NSEC</nanosec>
    +               </autopurge_nowriter_samples_delay>
    +               <autopurge_disposed_samples_delay>
    +                    <sec>DURATION_INFINITE_SEC</sec>
    +                    <nanosec>DURATION_INFINITE_NSEC</nanosec>
    +               </autopurge_disposed_samples_delay>
    +          </reader_data_lifecycle>
    +     </datareader_qos>
    +     <topic_qos>
    +          <topic_data>
    +               <value></value>
    +          </topic_data>
    +          <durability>
    +               <kind>PERSISTENT_DURABILITY_QOS</kind>
    +          </durability>
    +          <durability_service>
    +               <service_cleanup_delay>
    +                    <sec>3600</sec>
    +                    <nanosec>0</nanosec>
    +               </service_cleanup_delay>
    +               <history_kind>KEEP_LAST_HISTORY_QOS</history_kind>
    +               <history_depth>100</history_depth>
    +               <max_samples>8192</max_samples>
    +               <max_instances>4196</max_instances>
    +               <max_samples_per_instance>8192</max_samples_per_instance>
    +          </durability_service>
    +          <deadline>
    +               <period>
    +                    <sec>DURATION_INFINITE_SEC</sec>
    +                    <nanosec>DURATION_INFINITE_NSEC</nanosec>
    +               </period>
    +          </deadline>
    +          <latency_budget>
    +               <duration>
    +                    <sec>0</sec>
    +                    <nanosec>0</nanosec>
    +               </duration>
    +          </latency_budget>
    +          <liveliness>
    +               <kind>AUTOMATIC_LIVELINESS_QOS</kind>
    +               <lease_duration>
    +                    <sec>DURATION_INFINITE_SEC</sec>
    +                    <nanosec>DURATION_INFINITE_NSEC</nanosec>
    +               </lease_duration>
    +          </liveliness>
    +          <reliability>
    +               <kind>BEST_EFFORT_RELIABILITY_QOS</kind>
    +               <max_blocking_time>
    +                    <sec>0</sec>
    +                    <nanosec>100000000</nanosec>
    +                    </max_blocking_time>
    +          </reliability>
    +          <destination_order>
    +               <kind>BY_RECEPTION_TIMESTAMP_DESTINATIONORDER_QOS</kind>
    +          </destination_order>
    +          <history>
    +               <kind>KEEP_LAST_HISTORY_QOS</kind>
    +               <depth>1</depth>
    +          </history>
    +              <resource_limits>
    +               <max_samples>LENGTH_UNLIMITED</max_samples>
    +               <max_instances>LENGTH_UNLIMITED</max_instances>
    +               <max_samples_per_instance>LENGTH_UNLIMITED</max_samples_per_instance>
    +          </resource_limits>
    +          <transport_priority>
    +               <value>0</value>
    +          </transport_priority>
    +          <lifespan>
    +               <duration>
    +                    <sec>DURATION_INFINITE_SEC</sec>
    +                    <nanosec>DURATION_INFINITE_NSEC</nanosec>
    +              </duration>
    +          </lifespan>
    +          <ownership>
    +               <kind>SHARED_OWNERSHIP_QOS</kind>
    +          </ownership>
    +     </topic_qos>
    +</qos_profile>
    +</dds>
    +
    +
    +
    +
    +

    6.1.2. Applying QoS Profile¶

    +

    To set the QoS profile for a DDS entity using the Node.js DCPS API and an XML file, the user specifies the qos file URI or file path and the QoS profile name as parameters.

    +

    Example

    +

    Create a QoS provider and get the respective entity QoS. The example below uses the QoS XML file referred in QoS Profile. For a detailed example refer to ‘GetSetQoSExample.js’ file referred in GetSetQoSExample example.

    +
    const dds = require('vortexdds');
    +const HelloWorldTopic = require('./HelloWorldTopic.js');
    +
    +/**
    + * Path of the qos xml file
    + * The DDS_PersistentQoS.xml file is used for this example
    + * It is located in the same directory of this example
    +* */
    +const QOS_PATH = 'DDS_PersistentQoS.xml';
    +const QOS_PROFILE = 'DDS PersistentQosProfile';
    +const DOMAIN_ID = dds.DDS_DOMAIN_DEFAULT;
    +
    +main();
    +
    +async function main(){
    +
    +  /**
    +   * Set QoS using QoS XML file
    +   */
    +
    +  // create a qos provider using qos xml file
    +  let qp = new dds.QoSProvider(QOS_PATH, QOS_PROFILE);
    +
    +  // get participant qos from qos provider and create a participant
    +  let pqos = qp.getParticipantQos();
    +  let participant = new dds.Participant(DOMAIN_ID, pqos);
    +
    +  // get publisher qos from qos provider and create a publisher
    +  let pubqos = qp.getPublisherQos();
    +  let publisher = new dds.Publisher(participant, pubqos);
    +
    +  let subqos = qp.getSubscriberQos('subscriber1');
    +  let subscriber = new dds.Subscriber(participant, subqos);
    +
    +  // get topic qos from qos provider and create a topic
    +  let tqos = qp.getTopicQos();
    +  let topic = await HelloWorldTopic.create(participant, tqos);
    +
    +  // get reader qos from qos provider and create a reader
    +  let rqos = qp.getReaderQos();
    +  let reader = new dds.Reader(subscriber, topic, rqos);
    +
    +  // get writer qos from qos provider and create a writer
    +  let wqos = qp.getWriterQos();
    +  let writer = new dds.Writer(publisher, topic, wqos);
    +
    +  // delete the participant
    +  participant.delete();
    +}
    +
    +
    +
    +
    +
    +

    6.2. Setting QoS Using Node.js DCPS API Classes¶

    +

    QoS settings can also be set by using the Node.js classes alone. (No XML files required.)

    +

    Example

    +

    Below is a code snippet similar to the ‘GetSetQoSExample/GetSetQoSExample.js’ file. It demonstrates how to specify the QoS settings for a topic, writer and reader using the Node.js DCPS APIs.

    +
    const dds = require('vortexdds');
    +const HelloWorldTopic = require('./HelloWorldTopic.js');
    +
    +main();
    +
    +async function main(){
    +
    +  let participant = new dds.Participant();
    +
    +  // get the default topic qos
    +  let tqos = dds.QoS.topicDefault();
    +
    +  // modify the topic qos policies
    +
    +  // All of the policy variables can be set
    +  tqos.durabilityService = {
    +    serviceCleanupDelay: 5000,
    +    historyKind: dds.HistoryKind.KeepLast,
    +    historyDepth: 10,
    +    maxSamples: 10,
    +    maxInstances: 5,
    +    maxSamplesPerInstance: -1,
    +  };
    +
    +  // Or a subset of the policy variables can be set
    +  tqos.durabilityService = {
    +    historyKind: dds.HistoryKind.KeepLast,
    +  };
    +
    +  tqos.reliability = dds.ReliabilityKind.reliable;
    +  tqos.durability = dds.DurabilityKind.Volatile;
    +  tqos.topicdata = 'Hello world topic';
    +  tqos.userdata = 'connected to hello world';
    +  tqos.groupdata = 'hello world group';
    +  tqos.history = {
    +    kind: dds.HistoryKind.KeepLast,
    +    depth: 10,
    +  };
    +  tqos.resourceLimits = {
    +    maxSamples: 10,
    +    maxInstances: 5,
    +  };
    +  tqos.lifespan = 5000;
    +  tqos.deadline = 3000;
    +  tqos.latencyBudget = 4000;
    +  tqos.ownership = dds.OwnershipKind.Exclusive;
    +  tqos.liveliness = {
    +    kind: dds.LivelinessKind.ManualByTopic,
    +    leaseDuration: 10,
    +  };
    +  tqos.reliability = {
    +    kind: dds.ReliabilityKind.Reliable,
    +    maxBlockingTime: 100,
    +  };
    +  tqos.transportPriority = 5;
    +  tqos.destinationOrder = dds.DestinationOrderKind.BySourceTimestamp;
    +
    +  // create topic with qos
    +  let topic = await HelloWorldTopic.create(participant, tqos);
    +
    +  // get topic qos policies
    +  console.log('\n', '** Topic QoS **');
    +  console.log('Reliability: ', tqos.reliability);
    +  console.log('Durability: ', tqos.durability);
    +  console.log('Topic data: ', tqos.topicdata);
    +  console.log('User data: ', tqos.userdata);
    +  console.log('Group data: ', tqos.groupdata);
    +  console.log('History: ', tqos.history);
    +  console.log('Resource Limits: ', tqos.resourceLimits);
    +  console.log('Lifespan: ', tqos.lifespan);
    +  console.log('Deadline: ', tqos.deadline);
    +  console.log('Latency Budget: ', tqos.latencyBudget);
    +  console.log('Ownership: ', tqos.ownership);
    +  console.log('Liveliness: ', tqos.liveliness);
    +  console.log('Transport Priority: ', tqos.transportPriority);
    +  console.log('Destination Order: ', tqos.destinationOrder);
    +  console.log('Durability Service: ', tqos.durabilityService);
    +
    +  // get the default writer qos
    +  let wqos = dds.QoS.writerDefault();
    +
    +  // modify the writer qos policies
    +  wqos.writerDataLifecycle = false;
    +
    +  // create a writer with qos
    +  let writer = new dds.Writer(publisher, topic, wqos);
    +
    +  // get writer qos policies
    +  console.log('\n', '** Writer QoS **');
    +  console.log('Writer data lifecyle: ', wqos.writerDataLifecycle);
    +
    +  // get the default reader qos
    +  let rqos = dds.QoS.readerDefault();
    +
    +  // modify the reader qos policies
    +  rqos.partition = 'partition1';
    +  rqos.timebasedFilter = 60000;
    +  rqos.readerDataLifecycle = {
    +    autopurgeNoWriterSamples: 100,
    +    autopurgeDisposedSamplesDelay: 500,
    +  };
    +
    +  // create a reader with qos
    +  let reader = new dds.Reader(subscriber, topic, rqos);
    +
    +  // get reader qos policies
    +  console.log('\n', '** Reader QoS **');
    +  console.log('Partition: ', rqos.partition);
    +  console.log('Time based filter: ', rqos.timebasedFilter);
    +  console.log('Reader data lifecycle: ', rqos.readerDataLifecycle);
    +
    +  // delete the participant
    +  participant.delete();
    +
    +  // NOTE: Actual reading and writing data  is not demonstrated in this example
    +}
    +
    +
    +
    +
    + + +
    +
    +
    +
    +
    + +

    Table Of Contents

    + + +

    Previous topic

    +

    5. Node.js API for Vortex DDS

    +

    Next topic

    +

    7. Topic Generation and Discovery

    +

    This Page

    + + + +
    +
    +
    +
    + + + + \ No newline at end of file diff --git a/docs/html/NodeJSDCPSAPIGuide/search.html b/docs/html/NodeJSDCPSAPIGuide/search.html new file mode 100644 index 000000000..4b9f36935 --- /dev/null +++ b/docs/html/NodeJSDCPSAPIGuide/search.html @@ -0,0 +1,101 @@ + + + + + + + + Search — Node.js DCPS API Guide + + + + + + + + + + + + + + + + + + + +
    +
    +
    +
    + +

    Search

    +
    + +

    + Please activate JavaScript to enable the search + functionality. +

    +
    +

    + From here you can search these documents. Enter your search + words into the box below and click "search". Note that the search + function will automatically search for all of the words. Pages + containing fewer words won't appear in the result list. +

    +
    + + + +
    + +
    + +
    + +
    +
    +
    +
    +
    + +
    +
    +
    +
    + + + + \ No newline at end of file diff --git a/docs/html/NodeJSDCPSAPIGuide/searchindex.js b/docs/html/NodeJSDCPSAPIGuide/searchindex.js new file mode 100644 index 000000000..cb1c0437a --- /dev/null +++ b/docs/html/NodeJSDCPSAPIGuide/searchindex.js @@ -0,0 +1 @@ +Search.setIndex({envversion:42,terms:{represent:6,all:[7,5,1,2,3],concept:[6,5,8],edg:3,queri:5,global:[4,1],windows10:1,code:[6,5,1,2],abil:2,follow:[6,5,1,2,7],partition1:2,skeleton:2,consr:5,nodej:[6,5,1,7],"const":[6,5,2],send:5,init:1,program:[5,7],those:2,ist_info:3,writerdefault:[5,2],getsetqosexampl:[5,2,7],consum:[4,6],everi:5,string:[6,5],fals:2,util:5,facebook:3,xmlschema:2,destinationorderkind:2,relev:4,administr:1,level:[4,5],list:[5,7,8],make:[4,5,1],iter:5,"try":5,adjust:5,qosprovid:[5,2],team:3,max_samples_per_inst:2,pleas:[4,8],x86_64:[1,7],tel:3,autoenable_created_ent:2,sign:6,createpublish:5,keep_all_history_qo:2,pass:6,further:4,history_kind:2,valid_data:5,blue:5,what:4,sub:5,getparticipantqo:[5,2],section:[6,5,1,2],abl:5,"while":5,access:5,delet:[5,2],version:[1,2],dds_volatileqos_al:5,qos_profil:[5,2],"new":[6,5,2],autopurgenowritersampl:2,datareader_qo:2,centric:4,idlpath:[6,5],createwrit:[6,5],gener:[0,5,8],let:[6,5,2],path:[6,5,2],"0xa":3,modifi:2,valu:[6,5,2],wait:[6,5],search:0,historydepth:2,maxblockingtim:2,current:6,technolog:3,step:[5,1],precis:6,ordered_access:2,extrem:4,implement:[4,6],overrid:2,appli:0,modul:[6,5,1,8],prefer:1,avenu:3,domainid:5,instal:[0,7],installdir:[1,7],service_cleanup_delai:2,middlewar:4,from:[1,2,4,5,6,7],describ:[6,1],usa:3,commun:[4,5],"float":6,getwriterqo:2,doubl:6,regist:[6,8],two:[5,2],suit:3,shapetopichelp:5,call:5,tradecent:3,taken:[6,5,2],type:5,until:5,more:[6,5,1,2,7],faith:3,visual:0,"transient":5,typesupport:[6,5],toolchain:1,compani:3,given:5,samplearrai:5,addon:1,gettopictypesupportsforidl:[6,5],err:5,scalabl:4,setup:[1,7,8],histori:2,latency_budget:2,descriptor:6,can:[6,5,1,2,7],cond:5,history_depth:2,ddserror:5,control:5,prompt:[1,7],dds_infin:5,process:[6,5],share:4,critic:4,pong:5,unsign:6,occur:5,historykind:2,resourcelimit:2,gcc:1,goal:4,anoth:[6,2,7],ping:5,blob:1,write:[6,5,2,7],how:[8,2,7],shared_ownership_qo:2,anyon:8,low:4,pure:[4,5],subdirectori:2,simpl:7,querycond:5,npm:[6,1,7],ne11:3,product:[1,8],resourc:2,vortex_v2:[1,7],numsampl:5,await:[6,5,2],them:8,pqo:[5,2],takearrai:5,membership:5,plane:5,mai:[5,3],data:[4,6,5,2,8],demonstr:[6,2,7],circleread:5,"short":6,essenti:8,bind:[4,6],correspond:5,element:2,inform:[6,8,1,3],environ:[5,1,7],block:5,allow:[5,2],exclus:2,order:[6,5,2],keeplast:2,tqo:[5,2],help:2,ospl_uri:5,over:0,mission:4,subscriber1:[5,2],subscriber2:2,dynam:0,entiti:[8,5,2,7],snippet:[6,5,2],group:[4,2],maxsamplesperinst:2,fit:6,destination_ord:2,chosen:5,runnabl:2,platform:1,window:[0,7],whole:3,persist:2,mail:3,leasedur:2,latencybudget:2,qos_path:[5,2],length_unlimit:2,non:[5,2],good:3,"return":[6,5],thei:2,python:0,qualiti:[0,5,7,8],pingpong:[5,7],topicnam:[6,5],promis:5,introduct:0,reliabilitykind:[5,2],maxsampl:2,name:[0,5,2],userid:[6,5],bysourcetimestamp:2,timeout:5,each:[5,7],found:[5,1,2,7],dds_qosprofil:2,compil:1,domain:[6,5],map:[6,5],ospl_hom:[5,1,2,7],procedur:1,entity_factori:2,helloworld:[5,7],our:5,pubmatchedwaitset:5,variabl:[5,1,2,7],shown:5,referenc:2,space:4,helloworlddata:5,your:[5,1,2],profil:[0,5,7],unsupport:6,com:[4,1,7,3],internet:4,print:5,leverag:4,p704:1,franc:3,after:5,navig:7,time_based_filt:2,dds_iotdata:6,pub:5,standard:[4,6],reason:5,base:[5,2,8],statusmask:5,releas:[1,7],org:[4,2],thrown:5,prefac:0,script:7,success:5,ist:[4,3],filter:[5,2],thing:4,length:5,place:[4,5,2],newdatawaitset:5,outsid:7,numberofsampl:5,"5th":3,first:[5,7],rang:6,attempttak:5,polici:[6,2],durabilityservic:2,arrai:6,lease_dur:2,autopurgedisposedsamplesdelai:2,number:[6,5],wqo:[5,2],instruct:[6,2,8],alreadi:5,done:5,wrapper:4,writerdatalifecycl:2,open:7,size:5,prioriti:2,latenc:[4,2],differ:[5,7],durability_servic:2,attach:5,interact:5,mkdir:1,system:[4,6,5,7],messag:[6,5],duration_infinite_nsec:2,master:1,circl:5,termin:7,schema:2,shell:[1,7],consol:[6,5,2],option:[6,5,2],readerdefault:[5,2],tool:[0,7],copi:1,dataspac:4,specifi:[5,2,8],github:1,topicdefault:[5,2],jsshape:[5,7],attempt:5,wchar:6,than:[6,5],wide:7,kind:2,pubqo:[5,2],structur:[6,2],publisher_qo:2,project:[5,1,7],includ:[6,5,1,2],deadlin:2,listen:[6,5],livelinesskind:2,topicdata:2,ani:[6,5,2],packag:[6,1,7],aforement:8,xmln:2,by_reception_timestamp_destinationorder_qo:2,expir:5,increment:5,need:[4,1,7],"null":5,domain_id:[5,2],resource_limit:2,subqo:[5,2],equival:6,lic:1,note:[5,2,8],readcondit:5,without:[6,2,3],take:5,which:[6,5,1,2],createtopicfor:[6,5],singl:5,ecmascript:4,even:4,begin:8,distribut:[4,5,8],ulong:6,c99:4,object:[4,6,5],discov:6,most:5,beta:6,typenam:6,glibc2:1,"class":[4,0,5],ubuntu1604:1,settimeout:5,getreaderqo:[5,2],doc:[5,1],later:1,request:6,uri:2,doe:[6,5],durabilitykind:[5,2],part:3,microsoft:1,show:[6,5,2],carefulli:4,transport_prior:2,inherit:2,coherent_access:2,find:6,persistentqosprofil:2,xml:[0,5,7],userdata:2,onli:[6,5,2],explicitli:5,locat:[6,5,2,8],copyright:3,dds_get_set_qo:5,explain:2,configur:1,written:[5,7],dds_domain_default:[5,2],should:5,"public":5,best_effort_reliability_qo:2,busi:4,max_blocking_tim:2,folder:[1,7],local:5,get:[6,5,2,7],express:5,newpag:[4,7],nativ:[4,1],cannot:5,takecond:5,requir:[6,5,1,2],portion:4,bat:[1,7],enabl:[5,8],method:5,provid:[4,0,5,7,8],topic_data:2,common:5,partit:[5,2],contain:[1,2,3,5,6,7,8],where:[5,7],set:[0,5,7],project_nam:1,volatileqosprofil:5,findtopicexampl:6,see:[4,5],sec:2,respons:5,reserv:3,subject:3,statu:[6,5],wire:0,base_nam:2,publisherdefault:5,discoveri:0,state:5,volatil:[5,2],between:4,paramet:[6,5,2],attribut:2,omg:[4,2,8],maxinst:2,kei:6,javascript:[4,6,5,7,8],helloworlddata_msg:[6,5],transportprior:2,otherwis:[6,5],subfold:7,rostand:3,howev:6,ushort:6,alon:2,p738:1,etc:2,audienc:0,instanc:[5,2],logic:4,pdf:1,readerdatalifecycl:2,point:8,color:5,overview:[5,8],period:2,dispatch:5,header:1,param:5,linux:[0,7],respect:[5,2],liabil:3,numberattempt:5,evalu:5,sarl:3,union:6,qosprofil:2,been:5,compon:4,json:[5,7],helloworldsubscrib:[5,7],quickli:8,persistent_durability_qo:2,shapenam:5,both:[6,2],subscriberdefault:5,togeth:4,getsetqosprofil:5,present:2,"case":5,replic:4,main:[4,5,2],idlnam:[6,5],servic:[0,1,4,5,7,8],properti:6,budget:2,durat:2,duration_infinite_sec:2,defin:[6,5,2,7],hde:[1,7],autodispose_unregistered_inst:2,error:5,gateshead:3,have:[5,2],readi:5,therefor:5,user_data:2,linkedin:3,destin:2,topic_qo:2,subscriber_qo:2,sever:[6,1],minimum_separ:2,develop:[1,8],receiv:5,publication_match:5,nanosec:2,format:5,same:[5,2],domainparticipant_qo:2,html:[5,1],document:[0,5,3],higher:4,http:[4,1,2,3],x86:1,iot:[4,6],upon:5,adlinktech:[4,3],portal:4,user:[4,5,1,2,8],ownership:2,ownership_strength:2,decoupl:4,typic:[5,1,2],demo_ishap:5,sqlexpress:5,appropri:1,choos:1,entri:5,timebasedfilt:2,exampl:5,command:[1,7],iotvalu:6,thi:[1,2,3,5,6,8],destinationord:2,undefin:5,programm:8,jean:3,woburn:3,guidelin:1,explan:8,protocol:4,execut:1,ddsconstant:5,ondataavail:5,groupdata:2,shape:5,readarrai:5,languag:[4,7],iottopichelp:6,web:3,struct:6,also:2,getpublisherqo:[5,2],tgz:[1,7],other:[5,7],autopurge_nowriter_samples_delai:2,primit:6,els:5,match:5,build:0,applic:[0,5,7],ownershipkind:2,iotdata:[6,7],read:[5,2,7],createsubscrib:5,wstring:6,datawriter_qo:2,readcond:5,world:[5,2],bit:0,licens:1,loss:6,statcond:5,qosexampl:7,helloworldpublish:5,like:1,specif:[4,5,8],corpor:3,statemask:5,manual:[1,7],resolv:[6,5],integ:6,shapes:5,createread:5,"boolean":6,xsd:2,lose:6,async:[6,5,2],xsi:2,page:0,depend:[0,7],getsubscriberqo:[5,2],www:[2,3],right:[4,3],vortexopensplic:[1,7],pingpongtop:5,twitter:3,creation:5,back:5,intern:6,"export":[6,5],librari:1,avoid:6,servicecleanupdelai:2,octet:6,p768:1,keep_last_history_qo:2,unit:6,condit:5,reproduc:3,refer:[6,5,2,8],core:[5,2],who:8,vortexdd:[6,5,1,2,7],quit:5,win64:7,"enum":6,ubuntu1404:1,rue:3,newdataw:5,host:1,"throw":5,dcp:[5,7],es6:4,about:0,actual:2,would:5,insid:6,must:[5,1],idl:[0,5,7],lifecycl:2,group_data:2,ospl:[0,5,7],adlinktech_usa:3,produc:6,restrict:5,dds_defaultqos_al:5,subset:2,liveli:2,opensplic:0,findtop:6,trademark:3,datatyp:6,within:6,encod:2,orsai:3,gcc4:1,lifecyl:2,rqo:[5,2],chang:[5,1,7,3],access_scop:2,durabl:[5,2],manag:[4,1],writer_data_lifecycl:2,log:[6,5,2],wai:6,support:[4,0,1],vallei:3,"long":6,avail:[5,2,3],start:[5,1,8],interfac:7,editor:2,acknowledg:3,autopurge_disposed_samples_delai:2,statuscondit:5,"function":[4,6,5,2],gettopicqo:2,schemaloc:2,newdatacond:5,msg:5,link:5,adlink:[1,7,3],eas:4,"true":[5,2],not_read:5,info:5,made:3,utf:2,consist:[4,5,2,7],possibl:8,"default":[5,2],displai:2,lifespan:2,asynchron:6,below:[6,5,2],limit:[4,0,2,3],sampl:[6,5,2],iterlow:5,similar:2,connect:[4,6,2],model:[4,5],featur:[4,7],artifact:0,reliable_reliability_qo:2,creat:[6,5,1,2],stringifi:5,helloworldtop:[5,2],mask:5,"abstract":4,repres:[6,5],"char":6,exist:[6,5],file:5,manualbytop:2,integr:4,again:5,dcsp:8,reader_data_lifecycl:2,instance_presentation_qo:2,when:[6,5],detail:[6,5,1,2,8],field:[6,5],valid:2,transport:2,you:[5,2,7],automatic_liveliness_qo:2,architectur:4,repeat:5,intend:0,sequenc:[6,5],time:[4,5,2],sqo:5,consid:5,devic:[1,7],readerqosprovid:5,max_sampl:2,dds_persistentqo:2,directori:[6,5,1,2,7],reliabl:[4,5,2],descript:[6,2,7],depth:2,max_inst:2,circletop:5,hello:[5,2]},objtypes:{},objnames:{},filenames:["index","installation","qos_provider","contacts","introduction","dds_entities","topic","examples","preface"],titles:["Node.js DCPS API Guide","3. Installation","6. Quality of Service (QoS)","8. Contacts & Notices","2. Introduction","5. Node.js API for Vortex DDS","7. Topic Generation and Discovery","4. Examples","1. Preface"],objects:{},titleterms:{set:2,opensplic:1,appli:2,over:6,linux:1,qualiti:2,indic:0,topic:[6,5],api:[0,5,1,2,8],file:[2,7],tabl:0,instal:1,guid:[0,8],dynam:6,xml:2,wire:6,depend:1,pattern:5,support:6,writer:5,particip:5,idl:6,publish:5,discoveri:6,profil:2,window:1,intend:8,build:1,reader:5,waitset:5,document:1,type:7,tool:1,node:[0,1,2,5,6,8],applic:1,run:7,python:1,vortex:5,gener:6,subscrib:5,usag:5,notic:3,visual:1,artifact:6,bit:1,"class":[6,2],dcp:[0,1,2,8],introduct:4,querycondit:5,prefac:8,about:8,name:6,provid:2,servic:2,exampl:[1,7],audienc:8,contact:3,limit:6,ospl:1}}) \ No newline at end of file diff --git a/docs/html/NodeJSDCPSAPIGuide/topic.html b/docs/html/NodeJSDCPSAPIGuide/topic.html new file mode 100644 index 000000000..fd85c5bc4 --- /dev/null +++ b/docs/html/NodeJSDCPSAPIGuide/topic.html @@ -0,0 +1,310 @@ + + + + + + + + 7. Topic Generation and Discovery — Node.js DCPS API Guide + + + + + + + + + + + + + + + +
    +
    +
    +
    + +
    +

    7. Topic Generation and Discovery¶

    +

    A DDS Topic represents the unit for information that can be produced or consumed by a DDS application. Topics are defined by a name, a type, and a set of QoS policies.

    +

    The Node.js DCPS API provides several ways of generating Node.js classes to represent DDS topics.

    +
    +
      +
    • over the wire discovery
    • +
    • dynamic generation of Node.js classes using parameters IDL file and topic name
    • +
    +
    +
    +

    Note

    +
      +
    • The Examples section provides the examples directory location, example descriptions and running instructions.
    • +
    +
    +
    +

    7.1. Over the Wire Discovery¶

    +

    Node.js topic classes can be generated for existing DDS topics in the DDS system. These topics are “discovered over the wire”.

    +

    The Node.js classes are generated when the topic is requested by name.

    +

    A code snippet is provided from findTopicExample.js. This example finds a topic registered by another process, and writes a sample to that topic.

    +

    Example

    +
    ...
    +const dds = require('vortexdds');
    +
    +console.log('Connecting to DDS domain...');
    +const participant = new dds.Participant();
    +
    +console.log('Finding topic...');
    +let topic = participant.findTopic('HelloWorldData_Msg');
    +
    +console.log('Creating writer and sample data to write...');
    +let writer = participant.createWriter(topic);
    +let sample = { userID: 4, message: 7 };
    +
    +console.log('Writing sample data...');
    +let status = writer.write(sample);
    +...
    +
    +
    +
    +
    +

    7.2. Dynamic Generation of Node.js Topic Classes Using IDL and Name¶

    +

    The Node.js DCPS API supports generation of Node.js topic classes from IDL. This section describes the details of the IDL-Node.js binding.

    +
    +

    7.2.1. Dynamic Generation¶

    +

    The Node.js DCPS API provides an asynchronous function that returns a Map of TypeSupport objects.

    +

    A TypeSupport object includes the topic typename, keys and descriptor.

    +

    The structure type representation of a topic is created by the TypeSupport object. However, the usage +of the structure type is internal to the Node.js DCPS API.

    +

    In order to create a topic, a topic name and a TypeSupport are passed into the Participant createTopicFor function. (qos and listener parameters are optional)

    +

    The code snippet below is taken from the ‘IoTTopicHelper.js’ file referred in IoTData example.

    +
    const dds = require('vortexdds');
    +const path = require('path');
    +
    +//asynchronous function to create the topic
    +module.exports.create = async function(participant) {
    +
    +  const topicName = 'IoTData';
    +  const idlName = 'dds_IoTData.idl';
    +  const idlPath = path.resolve(idlName);
    +
    +  //wait for dds.getTopicTypeSupportsForIDL to return a map of typeSupports
    +  let typeSupports = await dds.getTopicTypeSupportsForIDL(idlPath);
    +
    +  //idl contains 1 topic.
    +  let typeSupport = typeSupports.get('DDS::IoT::IoTData');
    +
    +  return participant.createTopicFor(topicName, typeSupport);
    +};
    +
    +
    +
    +
    +

    7.2.2. Generated Artifacts¶

    +

    The following table defines the Node.js artifacts generated from IDL concepts:

    + ++++ + + + + + + + + + + + + + + + + + + + + + + + + + +
    IDL ConceptNode.js Concept
    moduleN/A
    enumenum from npm ‘enum’ package
    enum valueenum value
    structobject
    fieldobject property
    unionobject (IoTValue from dds_IoTData.idl +is the only supported union)
    +

    Datatype mappings

    +

    The following table shows the Node.js equivalents to IDL primitive types:

    + ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    IDL TypeNode.js Type
    booleanBoolean
    charNumber
    octetNumber
    shortNumber
    ushortNumber
    longNumber
    ulongNumber
    long longNumber
    ulong longNumber
    floatNumber
    doubleNumber
    stringString
    wcharUnsupported
    wstringUnsupported
    anyUnsupported
    long doubleUnsupported
    +

    Implementing Arrays and Sequences in Node.js

    +

    Both IDL arrays and IDL sequences are mapped to JavaScript arrays.

    +
    +
    +
    +

    7.3. Limitations of Node.js Support¶

    +

    The Node.js binding has the following limitations:

    +
    +
      +
    • Listeners are not supported
    • +
    • Only the IoTValue union from dds_IoTData.idl is supported in the beta
    • +
    • JavaScript does not currently include standard support for 64-bit integer values. 64-bit integers with more than 53 bits of data are represented by String values to avoid loss of precision. If the value will fit inside a JavaScript Number without losing precision, a Number can be used, otherwise use a String. (Refer to IoTData example which demonstrates the usage and ranges for the unsigned and signed 64 bit integers within nodejs.)
    • +
    +
    +
    +
    + + +
    +
    +
    +
    +
    + +

    Table Of Contents

    + + +

    Previous topic

    +

    6. Quality of Service (QoS)

    +

    Next topic

    +

    8. Contacts & Notices

    +

    This Page

    + + + +
    +
    +
    +
    + + + + \ No newline at end of file diff --git a/docs/html/NodeMonitorGuide/_sources/contacts.txt b/docs/html/NodeMonitorGuide/_sources/contacts.txt index b437fd808..d32f6016f 100644 --- a/docs/html/NodeMonitorGuide/_sources/contacts.txt +++ b/docs/html/NodeMonitorGuide/_sources/contacts.txt @@ -1,49 +1 @@ -.. _`Contacts & Notices`: - -################## -Contacts & Notices -################## - -******** -Contacts -******** - -| **PrismTech Corporation** -| 400 TradeCenter -| Suite 5900 -| Woburn, MA -| 01801 -| USA -| Tel: +1 781 569 5819 - -| **PrismTech Limited** -| PrismTech House -| 5th Avenue Business Park -| Gateshead -| NE11 0NG -| UK -| Tel: +44 (0)191 497 9900 - -| **PrismTech France** -| 28 rue Jean Rostand -| 91400 Orsay -| France -| Tel: +33 (1) 69 015354 - - -Web: http://www.prismtech.com - -E-mail: \info@prismtech.com - -******* -Notices -******* - -**Copyright** © 2016 PrismTech Limited. - -The information contained in this document is subject to change without notice and is -made available in good faith without liability on the part of PrismTech Limited or -PrismTech Corporation. - -All trademarks acknowledged. - +.. include:: ../../common/contacts.rst diff --git a/docs/html/NodeMonitorGuide/_sources/index.txt b/docs/html/NodeMonitorGuide/_sources/index.txt index 07aaf6f48..e1777a25c 100644 --- a/docs/html/NodeMonitorGuide/_sources/index.txt +++ b/docs/html/NodeMonitorGuide/_sources/index.txt @@ -9,7 +9,7 @@ OpenSplice NodeMonitor User Guide .. toctree:: :maxdepth: 2 :numbered: - + preface introduction startstop @@ -17,8 +17,8 @@ OpenSplice NodeMonitor User Guide dataavailable biblio - contacts - + contacts + Indices and tables ================== diff --git a/docs/html/NodeMonitorGuide/_sources/preface.txt b/docs/html/NodeMonitorGuide/_sources/preface.txt index 71d6892d5..c0b496068 100644 --- a/docs/html/NodeMonitorGuide/_sources/preface.txt +++ b/docs/html/NodeMonitorGuide/_sources/preface.txt @@ -32,7 +32,7 @@ statistics about the performance of a system. Conventions *********** -The icons shown below are used in PrismTech product documentation +The icons shown below are used in the Vortex product documentation to help readers to quickly identify information relevant to their specific use of OpenSplice. @@ -73,4 +73,4 @@ specific use of OpenSplice. .. |java| image:: ./images/icon-java.* :height: 6mm - \ No newline at end of file + diff --git a/docs/html/NodeMonitorGuide/biblio.html b/docs/html/NodeMonitorGuide/biblio.html index f8182d55d..1004d99c6 100644 --- a/docs/html/NodeMonitorGuide/biblio.html +++ b/docs/html/NodeMonitorGuide/biblio.html @@ -112,7 +112,7 @@

    Navigation

    \ No newline at end of file diff --git a/docs/html/NodeMonitorGuide/configuring.html b/docs/html/NodeMonitorGuide/configuring.html index 58534dbdb..813bda355 100644 --- a/docs/html/NodeMonitorGuide/configuring.html +++ b/docs/html/NodeMonitorGuide/configuring.html @@ -227,7 +227,7 @@

    Navigation

    \ No newline at end of file diff --git a/docs/html/NodeMonitorGuide/contacts.html b/docs/html/NodeMonitorGuide/contacts.html index 93072e7c4..bd14acfd2 100644 --- a/docs/html/NodeMonitorGuide/contacts.html +++ b/docs/html/NodeMonitorGuide/contacts.html @@ -50,7 +50,7 @@

    Navigation

    7.1. Contacts¶

    -
    PrismTech Corporation
    +
    ADLINK Technology Corporation
    400 TradeCenter
    Suite 5900
    Woburn, MA
    @@ -59,31 +59,35 @@

    7.1. ContactsTel: +1 781 569 5819

    -
    PrismTech Limited
    -
    PrismTech House
    -
    5th Avenue Business Park
    +
    ADLINK Technology Limited
    +
    The Edge
    +
    5th Avenue
    +
    Team Valley
    Gateshead
    -
    NE11 0NG
    +
    NE11 0XA
    UK
    Tel: +44 (0)191 497 9900
    -
    PrismTech France
    +
    ADLINK Technology SARL
    28 rue Jean Rostand
    91400 Orsay
    France
    Tel: +33 (1) 69 015354
    -

    Web: http://www.prismtech.com

    -

    E-mail: info@prismtech.com

    +

    Web: http://ist.adlinktech.com/

    +

    Contact: http://ist.adlinktech.com

    +

    E-mail: ist_info@adlinktech.com

    +

    LinkedIn: https://www.linkedin.com/company/79111/

    +

    Twitter: https://twitter.com/ADLINKTech_usa

    +

    Facebook: https://www.facebook.com/ADLINKTECH

    7.2. Notices¶

    -

    Copyright © 2016 PrismTech Limited.

    -

    The information contained in this document is subject to change without notice and is -made available in good faith without liability on the part of PrismTech Limited or -PrismTech Corporation.

    -

    All trademarks acknowledged.

    +

    Copyright © 2018 ADLINK Technology Limited. All rights reserved.

    +

    This document may be reproduced in whole but not in part. The information contained in this +document is subject to change without notice and is made available in good faith without +liability on the part of ADLINK Technology Limited. All trademarks acknowledged.

    @@ -143,7 +147,7 @@

    Navigation

    \ No newline at end of file diff --git a/docs/html/NodeMonitorGuide/dataavailable.html b/docs/html/NodeMonitorGuide/dataavailable.html index 8cc50f769..bd12bc916 100644 --- a/docs/html/NodeMonitorGuide/dataavailable.html +++ b/docs/html/NodeMonitorGuide/dataavailable.html @@ -237,7 +237,7 @@

    Navigation

    \ No newline at end of file diff --git a/docs/html/NodeMonitorGuide/genindex.html b/docs/html/NodeMonitorGuide/genindex.html index 522bf6776..bec3ca02c 100644 --- a/docs/html/NodeMonitorGuide/genindex.html +++ b/docs/html/NodeMonitorGuide/genindex.html @@ -88,7 +88,7 @@

    Navigation

    \ No newline at end of file diff --git a/docs/html/NodeMonitorGuide/index.html b/docs/html/NodeMonitorGuide/index.html index d9364fff7..838391d0d 100644 --- a/docs/html/NodeMonitorGuide/index.html +++ b/docs/html/NodeMonitorGuide/index.html @@ -152,7 +152,7 @@

    Navigation

    \ No newline at end of file diff --git a/docs/html/NodeMonitorGuide/introduction.html b/docs/html/NodeMonitorGuide/introduction.html index c1f1eab67..01aa30f7c 100644 --- a/docs/html/NodeMonitorGuide/introduction.html +++ b/docs/html/NodeMonitorGuide/introduction.html @@ -137,7 +137,7 @@

    Navigation

    \ No newline at end of file diff --git a/docs/html/NodeMonitorGuide/preface.html b/docs/html/NodeMonitorGuide/preface.html index bed6620ae..4724cafd6 100644 --- a/docs/html/NodeMonitorGuide/preface.html +++ b/docs/html/NodeMonitorGuide/preface.html @@ -67,7 +67,7 @@

    1.1. About the Vortex OpenSplice Node Monitor User Guide

    1.2. Conventions¶

    -

    The icons shown below are used in PrismTech product documentation +

    The icons shown below are used in the Vortex product documentation to help readers to quickly identify information relevant to their specific use of OpenSplice.

    @@ -177,7 +177,7 @@

    Navigation

    \ No newline at end of file diff --git a/docs/html/NodeMonitorGuide/search.html b/docs/html/NodeMonitorGuide/search.html index 40b8b96d2..47fbc2ed5 100644 --- a/docs/html/NodeMonitorGuide/search.html +++ b/docs/html/NodeMonitorGuide/search.html @@ -95,7 +95,7 @@

    Navigation

    \ No newline at end of file diff --git a/docs/html/NodeMonitorGuide/searchindex.js b/docs/html/NodeMonitorGuide/searchindex.js index 2aea8ae16..531f3bc5b 100644 --- a/docs/html/NodeMonitorGuide/searchindex.js +++ b/docs/html/NodeMonitorGuide/searchindex.js @@ -1 +1 @@ -Search.setIndex({envversion:42,terms:{oper:1,all:[1,2],hyper:4,identifi:7,help:7,memstat:1,operatingsysteminfo:1,ospl_uri:5,insight:1,obtain:3,signific:7,sleep:5,same:1,follow:[3,6],"0ng":2,jean:2,millisecond:[5,1],web:2,onli:7,processinfo:1,netinterfaceinfo:1,hint:7,cpu:1,platform:0,window:[3,0,7],busi:2,swap:5,mail:2,must:6,good:2,vendor:5,ospl_hom:5,node_info:1,stop:[0,7],bat:6,number:5,gatewai:5,bit:[3,5],relev:7,introduct:0,nodeinfoservic:1,resid:5,name:[5,1],specif:[1,7],corpor:2,drop:5,list:[3,7],instruct:7,server:3,item:7,vortex:[3,0,1],statist:1,partit:1,contain:[7,2],categori:1,where:[3,1,7],page:[0,5],mean:7,pleas:6,kernel:[3,5],domain:[5,1],tel:2,franc:2,acknowledg:2,interv:1,architectur:5,packet:5,see:3,possibl:[3,1],http:[4,2],histori:1,time:5,special:7,subject:2,variabl:[5,1],shown:7,network:1,correctli:6,loopback:5,netinfo:1,publish:[3,1],your:1,access:7,when:1,state:5,version:5,languag:[3,7],reader:7,get:6,core:5,prismtech:[7,2],run:5,endian:5,free:5,backbon:[3,1],rostand:2,control:1,base:7,zombi:5,solari:7,ubuntu:[5,7],releas:6,java:[3,7],"byte":5,rue:2,valu:[5,1],faith:2,about:0,historydepth:1,actual:5,copyright:2,thread:5,fault:5,current:5,keep:1,etc:5,idl:5,carrier:5,ospl:5,cpustat:1,implement:3,sigar:[3,4],com:[4,6,2],disabl:1,load:5,cpuinfo:1,major:5,own:1,opensplic:1,appli:7,address:5,nodemon:6,usa:2,avenu:2,unix:7,api:[3,4],linux:[3,0,5,7],instal:[3,6],total:5,open:6,primari:5,size:5,prioriti:5,liabil:2,from:[3,6],convent:0,memori:1,"5th":2,support:0,trademark:2,system:1,avail:2,start:[0,5,1,7],interfac:1,tradecent:2,suit:2,taken:7,scope:1,type:[5,7],frame:5,minor:5,quickli:7,shell:6,option:7,prefac:0,imag:5,park:2,search:0,broadcast:5,netmask:5,part:[3,2],line:6,categor:7,cach:5,overrun:5,processcpustat:1,info:2,made:2,hous:2,provid:7,work:5,mtu:5,defin:1,below:[3,7],limit:2,can:[3,7],www:2,error:5,overrid:1,gateshead:2,prompt:6,creat:1,process:1,metric:1,ram:5,share:5,destin:5,sourc:6,caution:7,want:7,need:7,collis:5,both:3,perform:7,frequenc:[5,1],percent:5,detail:[3,6],virtual:5,how:6,epoch:5,other:1,anyon:7,which:[3,1],environ:[5,6],you:1,document:[7,2],complet:3,ne11:2,product:7,orsai:2,x86:3,who:7,netinterfacestat:1,befor:6,mac:5,user:5,distribut:5,secondari:5,data:1,chang:[1,2],averag:5,icon:7,github:4,processmemorystat:1,directori:[5,1],descript:7,historyqospolici:1,without:2,inform:[1,2],depth:1,exampl:5,command:6,thi:[7,1,2],enter:6,push:1,ethernet:5,model:5,woburn:2,microsoft:3},objtypes:{},objnames:{},filenames:["index","configuring","contacts","introduction","biblio","dataavailable","startstop","preface"],titles:["OpenSplice NodeMonitor User Guide","4. Configuring Node Monitor","7. Contacts & Notices","2. Introduction","6. References","5. Data Available through Node Monitor","3. Starting and Stopping Node Monitor","1. Preface"],objects:{},titleterms:{oper:5,set:1,file:1,opensplic:[0,7],process:5,linux:6,indic:0,inform:5,through:5,conf:1,tabl:0,guid:[0,7],paramet:1,monitor:[5,6,1,7],convent:7,memori:5,support:3,configur:1,system:5,avail:5,platform:3,window:6,interfac:5,start:6,refer:4,node:[5,6,1,7],applic:1,stop:6,notic:2,user:[0,7],data:5,introduct:3,prefac:7,about:7,"default":1,nodemonitor:0,network:5,vortex:7,contact:2,statist:5,cpu:5}}) \ No newline at end of file +Search.setIndex({envversion:42,terms:{oper:1,all:[1,2],hyper:4,identifi:7,edg:2,memstat:1,operatingsysteminfo:1,ospl_uri:5,insight:1,obtain:3,signific:7,sleep:5,same:1,follow:[3,6],compani:2,languag:[3,7],help:7,millisecond:[5,1],web:2,onli:7,processinfo:1,copyright:2,hint:7,cpu:1,twitter:2,platform:0,window:[3,0,7],swap:5,mail:2,ist_info:2,good:2,vendor:5,ospl_hom:5,node_info:1,stop:[0,7],adlinktech:2,number:5,facebook:2,"0xa":2,bit:[3,5],relev:7,introduct:0,bat:6,sarl:2,resid:5,name:[5,1],specif:[1,7],corpor:2,drop:5,list:[3,7],unix:7,server:3,item:7,netinfo:1,statist:1,partit:1,team:2,categori:1,where:[3,1,7],page:[0,5],mean:7,pleas:6,kernel:[3,5],domain:[5,1],right:2,tel:2,franc:2,acknowledg:2,interv:1,architectur:5,packet:5,see:3,reserv:2,histori:1,time:5,special:7,subject:2,variabl:[5,1],shown:7,network:1,correctli:6,loopback:5,http:[4,2],vortex:[3,0,1],publish:[3,1],your:1,access:7,when:1,state:5,version:5,reader:7,get:6,reproduc:2,core:5,run:5,contain:[7,2],free:5,backbon:[3,1],rostand:2,control:1,base:7,zombi:5,solari:7,ubuntu:[5,7],releas:6,java:[3,7],"byte":5,rue:2,valu:[5,1],faith:2,about:0,historydepth:1,actual:5,netinterfaceinfo:1,thread:5,fault:5,current:5,technolog:2,mac:5,keep:1,etc:5,idl:5,carrier:5,ospl:5,cpustat:1,adlinktech_usa:2,implement:3,sigar:[3,4],com:[4,6,2],disabl:1,load:5,cpuinfo:1,major:5,own:1,nodeinfoservic:1,opensplic:1,appli:7,address:5,nodemon:6,usa:2,avenu:2,instruct:7,api:[3,4],linux:[3,0,5,7],instal:[3,6],total:5,open:6,primari:5,size:5,prioriti:5,liabil:2,from:[3,6],convent:0,memori:1,support:0,vallei:2,trademark:2,system:1,avail:2,start:[0,5,1,7],interfac:1,tradecent:2,suit:2,taken:7,scope:1,type:[5,7],frame:5,minor:5,quickli:7,shell:6,option:7,prefac:0,imag:5,search:0,broadcast:5,netmask:5,part:[3,2],adlink:2,line:6,categor:7,cach:5,overrun:5,processcpustat:1,made:2,possibl:[3,1],provid:7,work:5,ram:5,mtu:5,defin:1,below:[3,7],limit:2,can:[3,7],www:2,error:5,gatewai:5,overrid:1,gateshead:2,prompt:6,creat:1,process:1,metric:1,"5th":2,share:5,linkedin:2,destin:5,jean:2,sourc:6,caution:7,want:7,need:7,ist:2,both:3,perform:7,frequenc:[5,1],percent:5,detail:[3,6],virtual:5,how:6,epoch:5,other:1,anyon:7,which:[3,1],environ:[5,6],you:1,document:[7,2],complet:3,ne11:2,product:7,endian:5,orsai:2,x86:3,who:7,netinterfacestat:1,befor:6,must:6,user:5,distribut:5,mai:2,secondari:5,data:1,chang:[1,2],averag:5,icon:7,github:4,processmemorystat:1,directori:[5,1],whole:2,collis:5,descript:7,historyqospolici:1,without:2,inform:[1,2],depth:1,exampl:5,command:6,thi:[7,1,2],enter:6,push:1,ethernet:5,model:5,woburn:2,microsoft:3},objtypes:{},objnames:{},filenames:["index","configuring","contacts","introduction","biblio","dataavailable","startstop","preface"],titles:["OpenSplice NodeMonitor User Guide","4. Configuring Node Monitor","7. Contacts & Notices","2. Introduction","6. References","5. Data Available through Node Monitor","3. Starting and Stopping Node Monitor","1. Preface"],objects:{},titleterms:{oper:5,set:1,file:1,opensplic:[0,7],process:5,linux:6,indic:0,inform:5,through:5,conf:1,tabl:0,guid:[0,7],paramet:1,monitor:[5,6,1,7],convent:7,memori:5,support:3,configur:1,system:5,avail:5,platform:3,window:6,interfac:5,start:6,refer:4,node:[5,6,1,7],applic:1,stop:6,notic:2,user:[0,7],data:5,introduct:3,prefac:7,about:7,"default":1,nodemonitor:0,network:5,vortex:7,contact:2,statist:5,cpu:5}}) \ No newline at end of file diff --git a/docs/html/NodeMonitorGuide/startstop.html b/docs/html/NodeMonitorGuide/startstop.html index 197899330..22473e507 100644 --- a/docs/html/NodeMonitorGuide/startstop.html +++ b/docs/html/NodeMonitorGuide/startstop.html @@ -137,7 +137,7 @@

    Navigation

    \ No newline at end of file diff --git a/docs/html/PythonDCPSAPIGuide/_images/dds_overview.png b/docs/html/PythonDCPSAPIGuide/_images/dds_overview.png new file mode 100644 index 000000000..c7490ddb4 Binary files /dev/null and b/docs/html/PythonDCPSAPIGuide/_images/dds_overview.png differ diff --git a/docs/html/PythonDCPSAPIGuide/_images/pythonDir.png b/docs/html/PythonDCPSAPIGuide/_images/pythonDir.png new file mode 100644 index 000000000..15ed91df0 Binary files /dev/null and b/docs/html/PythonDCPSAPIGuide/_images/pythonDir.png differ diff --git a/docs/html/PythonDCPSAPIGuide/_sources/contacts.txt b/docs/html/PythonDCPSAPIGuide/_sources/contacts.txt new file mode 100644 index 000000000..d32f6016f --- /dev/null +++ b/docs/html/PythonDCPSAPIGuide/_sources/contacts.txt @@ -0,0 +1 @@ +.. include:: ../../common/contacts.rst diff --git a/docs/html/PythonDCPSAPIGuide/_sources/dds_entities.txt b/docs/html/PythonDCPSAPIGuide/_sources/dds_entities.txt new file mode 100644 index 000000000..972ed9a1d --- /dev/null +++ b/docs/html/PythonDCPSAPIGuide/_sources/dds_entities.txt @@ -0,0 +1,436 @@ +.. _`Python API for Vortex DDS`: + +######################### +Python API for Vortex DDS +######################### + +The Python DCPS API provides users with Python classes to model DDS communication using Python and pure +DDS applications. + +The Python DCPS API consists of 2 modules. + +* dds module +* ddsutil module + +This section provides an overview of the main DDS concepts and Python API examples for these DDS concepts. + +.. note:: + + - The Python DCPS API can be found in the following directory: + + *$OSPL_HOME/tools/python/docs/html* + +API Usage Patterns +****************** + +The typical usage pattern for the Python DCPS API for Vortex DDS is the following: + +* optional - Model your DDS topics using IDL. Alternatively, the python scripts can use topics that already exist in the DDS system. +* optional - Statically generate Python topic classes using ``idlpp -l python``. If using IDL, the user also has the option to dynamically generate Python topic classes in python scripts. See :ref:`Python Generation from IDL`. +* Start writing your Python program using the Python API for Vortex DDS. + +The core classes you must use are ``dds.Topic``, ``dds.DomainParticipant`` and either ``dds.DataReader`` or ``dds.DataWriter``. +Other classes may be required, especially if you need to adjust the Quality of Service (QoS) defaults. +For details on setting QoS values with the API, see :ref:`QoS Provider`. + +The following list shows the sequence in which you would use the Vortex classes: + +* Create a ``dds.DomainParticipant`` instance. +* Create one or more ``dds.Topic`` instances for the IDL topics your program will read or write. +* If you require publisher or subscriber level non-default QoS settings, create ``dds.Publisher`` and/or ``dds.Subscriber`` instances. (The most common reason for changing publisher/subscriber QoS is to define non-default partitions.) +* Create ``dds.DataReader`` and/or ``dds.DataWriter`` classes using the ``dds.Topic`` instances that you created. +* If you required data filtering, create ``dds.QueryCondition`` objects. +* Create the core of program, creating instances of your topic classes and writing them; or, reading data and processing it. + +dds.Topic +********* + +The Python Topic class represents a DDS topic type. The DDS topic corresponds to a single data type. In DDS, data is distributed by publishing and subscribing topic data samples. + +For a DDS Topic type definition, a corresponding Python class must be defined. +These topic classes are either a class created statically using ``idlpp``, dynamically using an idl file or dynamically for an existing topic discovered in the system. (see :ref:`Topic Generation and Discovery`) + +**API Examples** + +Create a Vortex DDS topic named 'Msg1' based on the DDS Topic type ``Msg``. + +.. code-block:: python + + TOPIC_NAME = 'Msg1' + TOPIC_TYPE = 'HelloWorldData::Msg' + IDL_FILE = 'idl/HelloWorldData.idl' + + # Create domain participant + dp = DomainParticipant() + + # Generate python classes from IDL file + gen_info = ddsutil.get_dds_classes_from_idl(IDL_FILE, TOPIC_TYPE) + + # Type support class + qos = Qos([DurabilityQosPolicy(DDSDurabilityKind.TRANSIENT), + ReliabilityQosPolicy(DDSReliabilityKind.RELIABLE)]) + topic = gen_info.register_topic(dp, TOPIC_NAME, qos) + +dds.DomainParticipant +********************* + +The Python``dds.DomainParticipant`` class represents a DDS domain participant entity. + +In DDS - “A domain participant represents the local membership of the application in a domain. A domain is a distributed concept that links all the applications able to communicate with each other. It represents a communication plane: only the publishers and subscribers attached to the same domain may interact.†+ +The dds.DomainParticipant has two optional parameters on creation. If these parameters are not provided, defaults are used. + +Parameters: + +* qos (Qos) – Participant QoS. Default: None +* listener (Listener) – Participant listener Default: None + + +**API Examples** + +Create a Vortex DDS domain participant. Returns participant or throws a ``dds.DDSException`` if the participant cannot be created. + +Create a domain participant in the default DDS domain (the one specified by the OSLP_URI environment variable). + +.. code-block:: python + + # Create domain participant + dp = DomainParticipant() + +Create a participant on default domain with QoS profile. + +.. code-block:: python + + qp = QosProvider('file://DDS_DefaultQoS_All.xml', 'DDS DefaultQosProfile') + + # Create participant + dp = DomainParticipant(qos = qp.get_participant_qos()) + +Create a participant on domain with QoS profile and listener. TODO + +.. code-block:: python + + qp = QosProvider('file://DDS_DefaultQoS_All.xml', 'DDS DefaultQosProfile') + + # Create participant + dp = DomainParticipant(qos = qp.get_participant_qos()) + +dds.Publisher +************* + +The Python ``dds.Publisher`` class represents a DDS publisher entity. + +In DDS, a publisher is “an object responsible for data distribution. It may publish data of different data types.†+ +Use of the ``dds.Publisher`` class is optional. +In it's place, you can use a ``dds.DomainParticipant`` instance. +Reasons for explicitly creating a ``dds.Publisher`` instance are: + +* to specify non-default QoS settings, including specifying the DDS *partition* upon which samples are written. +* to control the timing of publisher creation and deletion. + +**API Examples** + +Create a DDS Publisher entity. Returns publisher or throws a ``dds.DDSException`` if the publisher cannot be created. + +Create a publisher with participant. + +.. code-block:: python + + # Create participant + dp = DomainParticipant() + + # Create publisher + pub = dp.create_publisher() + +Create a publisher with participant and QoS profile. + +.. code-block:: python + + qp = QosProvider('file://DDS_DefaultQoS_All.xml', 'DDS DefaultQosProfile') + + # Create participant + dp = DomainParticipant(qos = qp.get_participant_qos()) + + # Create publisher + pub = dp.create_publisher(qos = qp.get_publisher_qos()) + +dds.DataWriter +************** + +The Python ``dds.Writer`` class represents a DDS data writer entity. + +In DDS - “The DataWriter is the object the application must use to communicate to a publisher the existence and value of data-objects of a given type.†+ +A ``dds.DataWriter`` class is required in order to write data to a DDS domain. +It is attached to a DDS publisher or a DDS domain participant. + +A ``dds.DataWriter`` class instance references an existing ``dds.Topic`` instance. + +**API Examples** + +Create a Vortex DDS domain writer. Returns writer or throws a ``dds.DDSException`` if the writer cannot be created. + +Create a writer within a domain participant, and with default QoS. + +.. code-block:: python + + # Create domain participant + dp = DomainParticipant() + + # Generate python classes from IDL file + gen_info = ddsutil.get_dds_classes_from_idl('idl/HelloWorldData.idl', 'HelloWorldData::Msg') + + # Type support class + qos = Qos([DurabilityQosPolicy(DDSDurabilityKind.TRANSIENT), ReliabilityQosPolicy(DDSReliabilityKind.RELIABLE)]) + topic = gen_info.register_topic(dp, 'Msg1', qos) + + # Create a writer + writer = dp.create_datawriter(topic) + +Create a writer within a publisher, and with default QoS. + +.. code-block:: python + + # Create domain participant + dp = DomainParticipant() + + # Create publisher + pub = dp.create_publisher() + + # Generate python classes from IDL file + gen_info = ddsutil.get_dds_classes_from_idl('idl/HelloWorldData.idl', 'HelloWorldData::Msg') + + # Type support class + qos = Qos([DurabilityQosPolicy(DDSDurabilityKind.TRANSIENT), ReliabilityQosPolicy(DDSReliabilityKind.RELIABLE)]) + topic = gen_info.register_topic(dp, 'Msg1', qos) + + # Create a writer + writer = pub.create_datawriter(topic) + +Create a writer with publisher or participant, topic and QoS profile. + + .. code-block:: python + + # Create domain participant + dp = DomainParticipant() + + # Create publisher + pub = dp.create_publisher() + + # Generate python classes from IDL file + gen_info = ddsutil.get_dds_classes_from_idl('idl/HelloWorldData.idl', 'HelloWorldData::Msg') + + # Type support class + qos = Qos([DurabilityQosPolicy(DDSDurabilityKind.TRANSIENT), ReliabilityQosPolicy(DDSReliabilityKind.RELIABLE)]) + topic = gen_info.register_topic(dp, 'Msg1', qos) + + # Create a writer + qp = QosProvider('file://DDS_DefaultQoS_All.xml', 'DDS DefaultQosProfile') + writer = pub.create_datawriter(topic) + writer = pub.create_datawriter(topic, qp.get_writer_qos()) + +Write a Msg topic class instance to a writer. + +.. code-block:: python + + # Topic data class + idMessage = 1 + message1 = 'Hello World' + s = gen_info.topic_data_class(userID = idMessage, message = message1) + + # Write data + writer.write(s) + +Dispose a DDS topic instance. + +.. code-block:: python + + # dispose instance + writer.dispose_instance(s) + +Unregister a DDS topic instance. TODO no equivalent in Python API + + % writer: a Vortex.Writer instance + % ShapeType: a 'topic class' created manually or via IDLPP + data = ShapeType(); % create an object instance + % set data key values... + data.color = 'RED'; + + ddsStatus = writer.unregister(data); + +dds.Subscriber +************** + +The Python ``dds.Subscriber`` class represents a DDS subscriber entity. + +In DDS, a subscriber is “an object responsible for receiving published data and making it available to the receiving application. It may receive and dispatch data of different specified types.†+ +Use of the ``dds.Subscriber`` class is optional. +In it's place, you can use a ``dds.DomainParticipant`` instance. +Reasons for explicitly creating a ``dds.Subscriber`` instance are: + +* to specify non-default QoS settings, including specifying the DDS *partition* upon which samples are written. +* to control the timing of subscriber creation and deletion. + +**API Examples** + + +Create a Vortex DDS domain subscriber. Returns subscriber or throw a ``dds.DDSException`` if the subscriber cannot be created. + + +Create a subscriber with participant. + +.. code-block:: python + + # Create participant + dp = DomainParticipant() + + # Create Subscriber + sub = dp.create_subscriber() + +Create a subscriber with participant and QoS profile. + +.. code-block:: python + + qp = QosProvider('file://DDS_DefaultQoS_All.xml', 'DDS DefaultQosProfile') + + # Create participant + dp = DomainParticipant(qos = qp.get_participant_qos()) + + # Create Subscriber + sub = dp.create_subscriber(qos = qp.get_subscriber_qos()) + + +dds.DataReader +************** + +The Python ``Vortex.Reader`` class represents a DDS data reader entity. + +In DDS - “To access the received data, the application must use a typed DataReader attached to the subscriber.†+ +A ``dds.DataReader`` class is required in order to write data to a DDS domain. +It is attached to a DDS subscriber or a DDS domain participant. + +A ``dds.DataReader`` class instance references an existing ``dds.Topic`` instance. + +**API Examples** + +Create a Vortex DDS domain reader. Returns reader or throw a ``dds.DDSException`` instance if the reader cannot be created. + +Create a reader for a topic within a participant, and with default QoS. + +.. code-block:: python + + # Create domain participant + dp = DomainParticipant() + + # Generate python classes from IDL file + gen_info = ddsutil.get_dds_classes_from_idl('idl/HelloWorldData.idl', 'HelloWorldData::Msg') + + # Type support class + qos = Qos([DurabilityQosPolicy(DDSDurabilityKind.TRANSIENT), ReliabilityQosPolicy(DDSReliabilityKind.RELIABLE)]) + topic = gen_info.register_topic(dp, 'Msg1', qos) + + # Create a reader + reader = dp.create_datareader(topic) + +Create a reader for a topic within a subscriber, and with default QoS. + +.. code-block:: python + + # Create domain participant + dp = DomainParticipant() + + # Create subscriber + sub = dp.create_subscriber() + + # Generate python classes from IDL file + gen_info = ddsutil.get_dds_classes_from_idl(IDL_FILE, TOPIC_TYPE) + + # Type support class + qos = Qos([DurabilityQosPolicy(DDSDurabilityKind.TRANSIENT), ReliabilityQosPolicy(DDSReliabilityKind.RELIABLE)]) + topic = gen_info.register_topic(dp, TOPIC_NAME, qos) + + # Create a reader + reader = sub.create_datareader(topic) + +Create a reader for a topic within a subscriber or participant, with with a QoS profile. + +.. code-block:: python + + # Create domain participant + dp = DomainParticipant() + + # Create subscriber + sub = dp.create_subscriber() + + # Generate python classes from IDL file + gen_info = ddsutil.get_dds_classes_from_idl(IDL_FILE, TOPIC_TYPE) + + # Type support class + qos = Qos([DurabilityQosPolicy(DDSDurabilityKind.TRANSIENT), ReliabilityQosPolicy(DDSReliabilityKind.RELIABLE)]) + topic = gen_info.register_topic(dp, TOPIC_NAME, qos) + + # Create a reader + qp = QosProvider('file://DDS_DefaultQoS_All.xml', 'DDS DefaultQosProfile') + reader = sub.create_datareader(topic, qp.get_reader_qos()) + +Take data from a data reader. + +.. code-block:: python + + l = reader.take(10) + +Read data from a data reader. + +.. code-block:: python + + l = reader.read(10) + +Specify a wait timeout, in seconds, before read or take will return without receiving data TODO change description the code is wrong + +.. code-block:: python + + # Create waitset + waitset = WaitSet() + qc = QueryCondition(reader, DDSMaskUtil.all_samples(), 'long1 > 1') + + waitset.attach(qc) + + # Wait for data + conditions = waitset.wait() + + # Print data + l = reader.take(10) + +dds.QueryCondition +****************** + +The Python ``dds.QueryCondition`` class represents a DDS query entity. + +A query is a data reader, restricted to accessing data that matches specific status conditions and/or a filter expression. + +A ``dds.Query`` class instance references an existing ``dds.DataReader`` instance. + +**API Examples** + +Create a ``dds.QueryCondition`` with a state mask and a filter expression for a reader and take data. + +.. code-block:: python + + # Create waitset + waitset = WaitSet() + qc = QueryCondition(reader, DDSMaskUtil.all_samples(), 'long1 > 1') + + waitset.attach(qc) + + # Wait for data + conditions = waitset.wait() + + # Print data + l = reader.take(10) + for sd, si in l: + sd.print_vars() + + diff --git a/docs/html/PythonDCPSAPIGuide/_sources/examples.txt b/docs/html/PythonDCPSAPIGuide/_sources/examples.txt new file mode 100644 index 000000000..c0eed334a --- /dev/null +++ b/docs/html/PythonDCPSAPIGuide/_sources/examples.txt @@ -0,0 +1,87 @@ +.. _`Examples`: + +######## +Examples +######## + +Several examples are provided to demonstrate the Python DCPS features. + +The examples can be found in the following directory: + + - *$OSPL_HOME/tools/python/examples* + +Example Files +************* + +File Types +========== + +The examples directory contains files of different types. The runnable python script files reference the xml and idl files. + + +============= ========================================================================================= +**File Type** **Description** +============= ========================================================================================= +py A program file or script written in Python +xml An XML file that contains one or more Quality of Service (QoS) profiles for DDS entities. +idl An interface description language file used to define topic(s). +============= ========================================================================================= + + + + +Examples +======== + +.. _`Examples Table`: +.. tabularcolumns:: | p{3.3cm} | p{11cm} | ++-------------------+-----------------------------------------------------+ +| **Example** | **Description** | ++===================+=====================================================+ +| qos_example.py | An example that demonstrates how to specify QoS | +| | settings using Python DCPS APIs. Also shows | +| | usage of a waitset. | +| | | ++-------------------+-----------------------------------------------------+ +| example1.py | Dynamic generation of Python Topic classes | +| | using IDL file and name. Uses a topic with a | +| | sequence. | +| | | ++-------------------+-----------------------------------------------------+ +| example2.py | Dynamic generation of Python Topic classes | +| | using Enumeration and nested modules. | +| | | +| | | ++-------------------+-----------------------------------------------------+ +| example4.py | Demonstrate finding DDS topics over-the-wire. | +| | Find topics registered by other processes, and | +| | read and write samples to those topics. | +| | | ++-------------------+-----------------------------------------------------+ + + + +Running Examples +**************** + +To run an example python script: + +1. Setup OSPL environment variables. + + **Linux** + + - source release.com + + **Windows** + - release.bat + + +2. Run an example python script + + - > python3 example1.py + + + + + + diff --git a/docs/html/PythonDCPSAPIGuide/_sources/index.txt b/docs/html/PythonDCPSAPIGuide/_sources/index.txt new file mode 100644 index 000000000..ee2c9ad4f --- /dev/null +++ b/docs/html/PythonDCPSAPIGuide/_sources/index.txt @@ -0,0 +1,28 @@ +.. Python DCSP API Guide + +.. Doc Issue 01, 30 November 2017 + +##################### +Python DCPS API Guide +##################### + +.. toctree:: + :maxdepth: 6 + :numbered: + + preface + introduction + installation + examples + dds_entities + qos_provider + topic + python_idl_mapping + + contacts + + +Indices and tables +================== + +* :ref:`search` diff --git a/docs/html/PythonDCPSAPIGuide/_sources/installation.txt b/docs/html/PythonDCPSAPIGuide/_sources/installation.txt new file mode 100644 index 000000000..99ed780e8 --- /dev/null +++ b/docs/html/PythonDCPSAPIGuide/_sources/installation.txt @@ -0,0 +1,120 @@ +.. _`Installation`: + +############ +Installation +############ + +This section describes the procedure to install the Python DCPS API on a Linux or Windows platform. + +System Requirements +******************* + +Operating System: Linux or Windows + +Dependencies +************ + + **Linux** + - Python3 version 3.4.0 or later + - pip3 (package "python3-pip" on most linux package managers) + - GCC 4.8 or later + + **Windows** + - Python version 3.5.0 + - pip (usually already included in Python for Windows) + - Visual Studio 14 (2015) C compiler or later + + **Python modules** + - Cython version 0.27 or later (install using "pip3 install Cython") + + +OpenSplice (OSPL) and Python DCPS API Installation +*************************************************** + +Steps: + +1. Install OSPL. The Python DCPS API is included in this installer. + +2. Setup OSPL license. Copy the license.lic file into the appropriate license directory. + + */INSTALLDIR/Vortex_v2/license* + +3. Python DCPS API files are contained in a tools/python folder + + Example: + *$OSPL_HOME/tools/python* + +.. figure:: images/pythonDir.png + :alt: Python Directory + +.. _PythonDCPSAPI: + +Python DCPS API Setup +********************* + +Install Python DCPS API package from python wheel +================================================= + +In certain Vortex OpenSplice installs, the python api is bundled as a python wheel file in +the $OSPL_HOME/tools/python directory. This way it avoids needing a native compiler and Cython +prerequisites before installation. + +Simply install using pip. For example, executing the command will install the wheel package, +which is targeted for python 3.4 64-bit Linux: + + $pip3 install dds-6.9.0-cp34-cp34m-linux_x86_64.whl + +Or similarly, for python 3.5 64-bit Windows: + + >pip install dds-6.9.0-cp35-cp35m-win_amd64.whl + +If the binary wheel package is not present or is not compatible with your python version, +then it is preferable to install the api from source. + +Install Python DCPS API package from source +=========================================== + +If the dependencies are satisfied, and the Vortex OpenSplice environment is set +(OSPL_HOME and associated environment variables), then installation is just one command +to execute in the $OSPL_HOME/python/src directory: + + $python3 setup.py install + +.. note:: + + - In either case, installing from wheel or from source may require administrator or superuser privileges if python was installed for all users. + + - To check modules are installed correctly try importing the installed modules. + + >>> import dds + >>> import ddsutil + + +Examples and Documentation +************************** + +1. Examples + + The examples can be found in the following directory: + + - *$OSPL_HOME/tools/python/examples* + +2. Python DCPS API Documentation + + The Python DCPS API can be found in the following directory: + + - *$OSPL_HOME/tools/python/docs/html* + +3. Python DCPS User Guide (HTML and PDF) + + The user guide can be found in the following directories: + + - *$OSPL_HOME/docs/html* + + - *$OSPL_HOME/docs/pdf* + + + + + + diff --git a/docs/html/PythonDCPSAPIGuide/_sources/introduction.txt b/docs/html/PythonDCPSAPIGuide/_sources/introduction.txt new file mode 100644 index 000000000..ebd798f7d --- /dev/null +++ b/docs/html/PythonDCPSAPIGuide/_sources/introduction.txt @@ -0,0 +1,32 @@ +.. _`Introduction`: + + +############ +Introduction +############ + +The Python DCPS API provides users with Python classes to model DDS communication using Python and pure DDS applications. + +The Python DCPS API is a native Python binding that supports full DDS functionality. The language binding consists of a Python interface and a C wrapper implementation of the C99 API (C API for DDS). It makes use of Python language features and leverages ease of use by providing a higher level of abstraction. + +DDS +*** + +**What is DDS?** + +“The Data Distribution Service (DDS™) is a middleware protocol and API standard for data-centric connectivity from the Object Management Group® (OMG®). It integrates the components of a system together, providing low-latency data connectivity, extreme reliability, and a scalable architecture that business and mission-critical Internet of Things (IoT) applications need.†+ +“The main goal of DDS is to share the right data at the right place at the right time, even between time-decoupled publishers and consumers. DDS implements global data space by carefully replicating relevant portions of the logically shared dataspace.†DDS specification + +.. figure:: images/dds_overview.png + :alt: DDS + +**Further Documentation** + +http://portals.omg.org/dds/ + +http://ist.adlinktech.com/ + + + + diff --git a/docs/html/PythonDCPSAPIGuide/_sources/preface.txt b/docs/html/PythonDCPSAPIGuide/_sources/preface.txt new file mode 100644 index 000000000..1a8a9f522 --- /dev/null +++ b/docs/html/PythonDCPSAPIGuide/_sources/preface.txt @@ -0,0 +1,31 @@ +.. _`Preface`: + +####### +Preface +####### + +About the Python DCPS API Guide +******************************* + +The Python DCPS API Guide is a starting point for anyone using, developing or running Python applications with Vortex OpenSplice. + +This guide contains: + + - Python DCSP API installation instructions + - location of Python DCPS API dds module documentation + - overview of general DDS concepts and Python API for Vortex DDS + - a listing of examples, and how to run them + - detailed information on how to specify DDS entity Quality of Service (QoS) + - how to discover and register DDS topics + +This reference guide is based on the OMG’s Data Distribution Service Specification and Python Language Mapping Specification. + +Please note that this guide is not intended to provide a detailed explanation of the aforementioned OMG specifications or the Vortex OpenSplice product. It provides an introduction to the essential concepts and enables users to begin using the Python DCPS API as quickly as possible. + +Intended Audience +***************** + +The Python Reference Guide is intended to be used by Python programmers who are +using Vortex OpenSplice to develop applications. + + diff --git a/docs/html/PythonDCPSAPIGuide/_sources/python_idl_mapping.txt b/docs/html/PythonDCPSAPIGuide/_sources/python_idl_mapping.txt new file mode 100644 index 000000000..2ed0be78e --- /dev/null +++ b/docs/html/PythonDCPSAPIGuide/_sources/python_idl_mapping.txt @@ -0,0 +1,134 @@ +.. _`Python Generation from IDL`: + +########################## +Python Generation from IDL +########################## + +The Python DCPS API supports generation of Python topic classes from IDL. This chapter describes the details of the IDL-Python binding. + +Running IDLPP +************* + +.. _StaticGeneration: + +Static Generation +================= + +The Python topic classes can be generated statically using an IDL file. + +Compiling IDL into python code is done using the ``-l python`` switch on idlpp:: + + idlpp -l python idl-file-to-compile.idl + +.. note:: + + - A Python package with the same name as the idl file (without the .idl extension) is always created. + + - It defines types not included in an IDL module. IDL modules become Python packages within this base package. + +.. _DynamicGeneration: + +Dynamic Generation +================== + +The Python topic classes can be generated dynamically using an IDL file, and the topic name. An api, ``ddsutil.get_dds_classes_from_idl``, is provided to generate the topic classes at runtime from within a Python script. + +**HelloWorldDataPublisher.py** + +.. code-block:: python + + ... + TOPIC_NAME = 'Msg1' + TOPIC_TYPE = 'HelloWorldData::Msg' + IDL_FILE = 'idl/HelloWorldData.idl' + + # Create domain participant + dp = DomainParticipant() + + # Create publisher + pub = dp.create_publisher() + + # Generate python topic classes from IDL file + gen_info = ddsutil.get_dds_classes_from_idl(IDL_FILE, TOPIC_TYPE) + + # Type support class + qos = Qos([DurabilityQosPolicy(DDSDurabilityKind.TRANSIENT), + ReliabilityQosPolicy(DDSReliabilityKind.RELIABLE)]) + + # Register topic + topic = gen_info.register_topic(dp, TOPIC_NAME, qos) + + # Create a writer + writer = pub.create_datawriter(topic) + + # Topic data class + idMessage = 1 + message1 = 'Hello World' + s = gen_info.topic_data_class(userID = idMessage, message = message1) + + # Write data + writer.write(s) + + #output to console + print('=== [Publisher] writing a message containing : ') + print('userID :', idMessage) + print('message :', message1) + ... + +Generated Artifacts +=================== + +The following table defines the Python artifacts generated from IDL concepts: + +=========== ============== =============================================== +IDL Concept Python Concept Comment +=========== ============== =============================================== +module package Folder with module name, plus __init__.py that + defines types defined within the module. +enum class Defined in __init__.py files. +enum value enum value Defined in __init__.py files. +struct class Defined in __init__.py files. +field class property Defined in __init__.py files. +union union Defined in __init__.py files. (Only statically + generated supported) +=========== ============== =============================================== + +**Datatype mappings** + +The following table shows the Python equivalents to IDL primitive types: + +=========== ============== +IDL Type Python Type +=========== ============== +boolean bool +char str, length==1 +octet int +short int +ushort int +long int +ulong int +long long int +ulong long int +float float +double float +string str +wchar Unsupported +wstring Unsupported +any Unsupported +long double Unsupported +=========== ============== + +**Implementing Arrays and Sequences in Python** + +Both IDL arrays and IDL sequences are mapped to Python lists. + +The constructors for generated classes always fully allocate any array fields. Sequences are always initialized to the empty list. + +Limitations of Python Support +***************************** + +The IDL-to-Python binding has the following limitations: + +* IDL unions are Supported by statically generated Python, but not by dynamic or over-the-wire. +* The following IDL data types are not supported: wchar, wstring, any and long double . + diff --git a/docs/html/PythonDCPSAPIGuide/_sources/qos_provider.txt b/docs/html/PythonDCPSAPIGuide/_sources/qos_provider.txt new file mode 100644 index 000000000..db4ecaa0e --- /dev/null +++ b/docs/html/PythonDCPSAPIGuide/_sources/qos_provider.txt @@ -0,0 +1,142 @@ +.. _`QoS Provider`: + + +######################## +Quality of Service (QoS) +######################## + +The following section explains how to set the Quality of Service (QoS) for a DDS entity. + +Users have two options available to set the QoS for an entity or entities. They can define the QoS settings using an XML file, or they can use the Python DCPS APIs. Both of these options are explained. + +If a QoS setting for an entity is not set using an xml file or the Python DCPS APIs, the defaults will be used. This allows a user the ability to override only those settings that require non-default values. + +The code snippets referenced are taken from the runnable examples. + +.. note:: + + - The :ref:`Examples` section provides the examples directory location, example descriptions and running instructions. + + +Setting QoS Using QoS Provider XML File +*************************************** + +QoS for DDS entities can be set using XML files based on the XML schema file QoSProfile.xsd_. +These XML files contain one or more QoS profiles for DDS entities. + +Sample QoS Profile XML files can be found in the examples directory. + +QoS Profile +=========== + +A QoS profile consists of a name and optionally a base_name attribute. The base_name attribute allows a +QoS or a profile to inherit values from another QoS or profile in the same file. The file contains QoS +elements for one or more DDS entities. A skeleton file without any QoS values is displayed below to show +the structure of the file. + +.. code-block:: xml + + + + + + + + + + + + +**Example: Specify Publisher Partition** + +The example below specifies the publisher's partitions as A and B. + +.. code-block:: xml + + + + + A + B + + + + +Applying QoS Profile +==================== + +To set the QoS profile for a DDS entity using the Python DCPS API and an XML file, the user specifies the File URI and the QoS profile name as parameters. + +**example1.py** + +.. code-block:: python + + ... + qp = QosProvider('file://DDS_DefaultQoS_All.xml', 'DDS DefaultQosProfile') + + # Create participant + dp = DomainParticipant(qos = qp.get_participant_qos()) + + # Create publisher + pub = dp.create_publisher(qos = qp.get_publisher_qos()) + + # Create Subscriber + sub = dp.create_subscriber(qos = qp.get_subscriber_qos()) + ... + + +Setting QoS Using Python DCPS API Classes +***************************************** + +QoS settings can also be set by using the python classes alone. (No XML files required.) + +Below is a code snippet that demonstrates how to specify the QoS settings for a writer using the python DCPS apis. In this example, all the QoS settings for the writer are set and all of the default QoS settings are overridden. If a QoS setting for an entity is not set, the default is used. + +**qos_example.py** + +.. code-block:: python + + ... + writer_qos = Qos([DurabilityQosPolicy(DDSDurabilityKind.TRANSIENT), + DeadlineQosPolicy(DDSDuration(500)), + LatencyBudgetQosPolicy(DDSDuration(3000)), + LivelinessQosPolicy(DDSLivelinessKind.MANUAL_BY_PARTICIPANT), + ReliabilityQosPolicy(DDSReliabilityKind.RELIABLE, DDSDuration.infinity()), + DestinationOrderQosPolicy(DDSDestinationOrderKind.BY_SOURCE_TIMESTAMP), + HistoryQosPolicy(DDSHistoryKind.KEEP_ALL), + ResourceLimitsQosPolicy(10,10,10), + TransportPriorityQosPolicy(700), + LifespanQosPolicy(DDSDuration(10, 500)), + OwnershipQosPolicy(DDSOwnershipKind.EXCLUSIVE), + OwnershipStrengthQosPolicy(100), + WriterDataLifecycleQosPolicy(False) + ]) + ... + + +In the next example, a topic QoS is created that overrides only a subset of the QoS settings. + +**HelloWorldDataSubscriber.py** + +.. code-block:: python + + ... + # Create domain participant + dp = DomainParticipant() + + # Create subscriber + sub = dp.create_subscriber() + + # Generate python classes from IDL file + gen_info = ddsutil.get_dds_classes_from_idl(IDL_FILE, TOPIC_TYPE) + + # Create a topic QoS that overrides defaults for durability and reliability + qos = Qos([DurabilityQosPolicy(DDSDurabilityKind.TRANSIENT), + ReliabilityQosPolicy(DDSReliabilityKind.RELIABLE)]) + topic = gen_info.register_topic(dp, TOPIC_NAME, qos) + ... + + +.. external links +.. _QoSProfile.xsd: http://www.omg.org/spec/dds4ccm/20110201/DDS_QoSProfile.xsd +.. _DDS_DefaultQoS.xml: http://www.omg.org/spec/dds4ccm/20110201/DDS_DefaultQoS.xml diff --git a/docs/html/PythonDCPSAPIGuide/_sources/topic.txt b/docs/html/PythonDCPSAPIGuide/_sources/topic.txt new file mode 100644 index 000000000..89a553c57 --- /dev/null +++ b/docs/html/PythonDCPSAPIGuide/_sources/topic.txt @@ -0,0 +1,75 @@ +.. _`Topic Generation and Discovery`: + +############################## +Topic Generation and Discovery +############################## + +A DDS Topic represents the unit for information that can be produced or consumed by a DDS application. Topics are defined by a name, a type, and a set of QoS policies. + +The Python DCPS API provides several ways of generating Python classes to represent DDS topics. + + - over the wire discovery + - dynamic generation of Python Topic classes using parameters IDL file and topic name + - static generation of Python Topic classes using IDL + +.. note:: + + - The :ref:`Examples` section provides the examples directory location, example descriptions and running instructions. + + +Over the Wire Discovery +************************ + +Python topic classes can be generated for existing DDS topics in the DDS system. These topics are "discovered over the wire". + +The Python classes are generated when the topic is requested by name. + +A code snippet is provided from example4.py. This example finds a topic registered by another process, and reads and writes samples to that topic. + +**example4.py** + +.. code-block:: python + + ... + print('Connecting to DDS domain...') + dp = dds.DomainParticipant() + + print('Finding OsplTestTopic...') + found_topic = dp.find_topic('OsplTestTopic') + + print('Registering OsplTestTopic locally') + local_topic = ddsutil.register_found_topic_as_local(found_topic) + + print('Getting Python classes for the found topic...') + gen_info = ddsutil.get_dds_classes_for_found_topic(found_topic) + OsplTestTopic = gen_info.get_class(found_topic.type_name) + Tstate = gen_info.get_class('ospllog::Tstate') + + print('Creating sample data to write...') + data = OsplTestTopic(id=11,index=22, x=1.2, y=2.3, z= 3.4, t=9.8, + state=Tstate.init, description='Hello from Python') + + print('Creating readers and writers...') + pub = dp.create_publisher() + wr = pub.create_datawriter(local_topic, found_topic.qos) + sub = dp.create_subscriber() + rd = sub.create_datareader(local_topic, found_topic.qos) + + print('Writing sample data...') + wr.write(data) + print('Wrote: %s' % (str(data))) + ... + +Static Generation of Python Topic Classes Using IDL +*************************************************** + +The Python topic classes can be generated statically using an IDL file. Please see :ref:`StaticGeneration` for more information. + +Dynamic Generation of Python Topic Classes Using IDL and Name +************************************************************* + +The Python topic classes can be generated dynamically using an IDL file, and the topic name. Please see :ref:`DynamicGeneration` for more information. + + + + diff --git a/docs/html/PythonDCPSAPIGuide/_static/Vortex_logo_2014.png b/docs/html/PythonDCPSAPIGuide/_static/Vortex_logo_2014.png new file mode 100644 index 000000000..e7de4f525 Binary files /dev/null and b/docs/html/PythonDCPSAPIGuide/_static/Vortex_logo_2014.png differ diff --git a/docs/html/PythonDCPSAPIGuide/_static/ajax-loader.gif b/docs/html/PythonDCPSAPIGuide/_static/ajax-loader.gif new file mode 100644 index 000000000..61faf8cab Binary files /dev/null and b/docs/html/PythonDCPSAPIGuide/_static/ajax-loader.gif differ diff --git a/docs/html/PythonDCPSAPIGuide/_static/basic.css b/docs/html/PythonDCPSAPIGuide/_static/basic.css new file mode 100644 index 000000000..967e36ce0 --- /dev/null +++ b/docs/html/PythonDCPSAPIGuide/_static/basic.css @@ -0,0 +1,537 @@ +/* + * basic.css + * ~~~~~~~~~ + * + * Sphinx stylesheet -- basic theme. + * + * :copyright: Copyright 2007-2014 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +/* -- main layout ----------------------------------------------------------- */ + +div.clearer { + clear: both; +} + +/* -- relbar ---------------------------------------------------------------- */ + +div.related { + width: 100%; + font-size: 90%; +} + +div.related h3 { + display: none; +} + +div.related ul { + margin: 0; + padding: 0 0 0 10px; + list-style: none; +} + +div.related li { + display: inline; +} + +div.related li.right { + float: right; + margin-right: 5px; +} + +/* -- sidebar --------------------------------------------------------------- */ + +div.sphinxsidebarwrapper { + padding: 10px 5px 0 10px; +} + +div.sphinxsidebar { + float: left; + width: 230px; + margin-left: -100%; + font-size: 90%; +} + +div.sphinxsidebar ul { + list-style: none; +} + +div.sphinxsidebar ul ul, +div.sphinxsidebar ul.want-points { + margin-left: 20px; + list-style: square; +} + +div.sphinxsidebar ul ul { + margin-top: 0; + margin-bottom: 0; +} + +div.sphinxsidebar form { + margin-top: 10px; +} + +div.sphinxsidebar input { + border: 1px solid #98dbcc; + font-family: sans-serif; + font-size: 1em; +} + +div.sphinxsidebar #searchbox input[type="text"] { + width: 170px; +} + +div.sphinxsidebar #searchbox input[type="submit"] { + width: 30px; +} + +img { + border: 0; + max-width: 100%; +} + +/* -- search page ----------------------------------------------------------- */ + +ul.search { + margin: 10px 0 0 20px; + padding: 0; +} + +ul.search li { + padding: 5px 0 5px 20px; + background-image: url(file.png); + background-repeat: no-repeat; + background-position: 0 7px; +} + +ul.search li a { + font-weight: bold; +} + +ul.search li div.context { + color: #888; + margin: 2px 0 0 30px; + text-align: left; +} + +ul.keywordmatches li.goodmatch a { + font-weight: bold; +} + +/* -- index page ------------------------------------------------------------ */ + +table.contentstable { + width: 90%; +} + +table.contentstable p.biglink { + line-height: 150%; +} + +a.biglink { + font-size: 1.3em; +} + +span.linkdescr { + font-style: italic; + padding-top: 5px; + font-size: 90%; +} + +/* -- general index --------------------------------------------------------- */ + +table.indextable { + width: 100%; +} + +table.indextable td { + text-align: left; + vertical-align: top; +} + +table.indextable dl, table.indextable dd { + margin-top: 0; + margin-bottom: 0; +} + +table.indextable tr.pcap { + height: 10px; +} + +table.indextable tr.cap { + margin-top: 10px; + background-color: #f2f2f2; +} + +img.toggler { + margin-right: 3px; + margin-top: 3px; + cursor: pointer; +} + +div.modindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +div.genindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +/* -- general body styles --------------------------------------------------- */ + +a.headerlink { + visibility: hidden; +} + +h1:hover > a.headerlink, +h2:hover > a.headerlink, +h3:hover > a.headerlink, +h4:hover > a.headerlink, +h5:hover > a.headerlink, +h6:hover > a.headerlink, +dt:hover > a.headerlink { + visibility: visible; +} + +div.body p.caption { + text-align: inherit; +} + +div.body td { + text-align: left; +} + +.field-list ul { + padding-left: 1em; +} + +.first { + margin-top: 0 !important; +} + +p.rubric { + margin-top: 30px; + font-weight: bold; +} + +img.align-left, .figure.align-left, object.align-left { + clear: left; + float: left; + margin-right: 1em; +} + +img.align-right, .figure.align-right, object.align-right { + clear: right; + float: right; + margin-left: 1em; +} + +img.align-center, .figure.align-center, object.align-center { + display: block; + margin-left: auto; + margin-right: auto; +} + +.align-left { + text-align: left; +} + +.align-center { + text-align: center; +} + +.align-right { + text-align: right; +} + +/* -- sidebars -------------------------------------------------------------- */ + +div.sidebar { + margin: 0 0 0.5em 1em; + border: 1px solid #ddb; + padding: 7px 7px 0 7px; + background-color: #ffe; + width: 40%; + float: right; +} + +p.sidebar-title { + font-weight: bold; +} + +/* -- topics ---------------------------------------------------------------- */ + +div.topic { + border: 1px solid #ccc; + padding: 7px 7px 0 7px; + margin: 10px 0 10px 0; +} + +p.topic-title { + font-size: 1.1em; + font-weight: bold; + margin-top: 10px; +} + +/* -- admonitions ----------------------------------------------------------- */ + +div.admonition { + margin-top: 10px; + margin-bottom: 10px; + padding: 7px; +} + +div.admonition dt { + font-weight: bold; +} + +div.admonition dl { + margin-bottom: 0; +} + +p.admonition-title { + margin: 0px 10px 5px 0px; + font-weight: bold; +} + +div.body p.centered { + text-align: center; + margin-top: 25px; +} + +/* -- tables ---------------------------------------------------------------- */ + +table.docutils { + border: 0; + border-collapse: collapse; +} + +table.docutils td, table.docutils th { + padding: 1px 8px 1px 5px; + border-top: 0; + border-left: 0; + border-right: 0; + border-bottom: 1px solid #aaa; +} + +table.field-list td, table.field-list th { + border: 0 !important; +} + +table.footnote td, table.footnote th { + border: 0 !important; +} + +th { + text-align: left; + padding-right: 5px; +} + +table.citation { + border-left: solid 1px gray; + margin-left: 1px; +} + +table.citation td { + border-bottom: none; +} + +/* -- other body styles ----------------------------------------------------- */ + +ol.arabic { + list-style: decimal; +} + +ol.loweralpha { + list-style: lower-alpha; +} + +ol.upperalpha { + list-style: upper-alpha; +} + +ol.lowerroman { + list-style: lower-roman; +} + +ol.upperroman { + list-style: upper-roman; +} + +dl { + margin-bottom: 15px; +} + +dd p { + margin-top: 0px; +} + +dd ul, dd table { + margin-bottom: 10px; +} + +dd { + margin-top: 3px; + margin-bottom: 10px; + margin-left: 30px; +} + +dt:target, .highlighted { + background-color: #fbe54e; +} + +dl.glossary dt { + font-weight: bold; + font-size: 1.1em; +} + +.field-list ul { + margin: 0; + padding-left: 1em; +} + +.field-list p { + margin: 0; +} + +.optional { + font-size: 1.3em; +} + +.versionmodified { + font-style: italic; +} + +.system-message { + background-color: #fda; + padding: 5px; + border: 3px solid red; +} + +.footnote:target { + background-color: #ffa; +} + +.line-block { + display: block; + margin-top: 1em; + margin-bottom: 1em; +} + +.line-block .line-block { + margin-top: 0; + margin-bottom: 0; + margin-left: 1.5em; +} + +.guilabel, .menuselection { + font-family: sans-serif; +} + +.accelerator { + text-decoration: underline; +} + +.classifier { + font-style: oblique; +} + +abbr, acronym { + border-bottom: dotted 1px; + cursor: help; +} + +/* -- code displays --------------------------------------------------------- */ + +pre { + overflow: auto; + overflow-y: hidden; /* fixes display issues on Chrome browsers */ +} + +td.linenos pre { + padding: 5px 0px; + border: 0; + background-color: transparent; + color: #aaa; +} + +table.highlighttable { + margin-left: 0.5em; +} + +table.highlighttable td { + padding: 0 0.5em 0 0.5em; +} + +tt.descname { + background-color: transparent; + font-weight: bold; + font-size: 1.2em; +} + +tt.descclassname { + background-color: transparent; +} + +tt.xref, a tt { + background-color: transparent; + font-weight: bold; +} + +h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt { + background-color: transparent; +} + +.viewcode-link { + float: right; +} + +.viewcode-back { + float: right; + font-family: sans-serif; +} + +div.viewcode-block:target { + margin: -1px -10px; + padding: 0 10px; +} + +/* -- math display ---------------------------------------------------------- */ + +img.math { + vertical-align: middle; +} + +div.body div.math p { + text-align: center; +} + +span.eqno { + float: right; +} + +/* -- printout stylesheet --------------------------------------------------- */ + +@media print { + div.document, + div.documentwrapper, + div.bodywrapper { + margin: 0 !important; + width: 100%; + } + + div.sphinxsidebar, + div.related, + div.footer, + #top-link { + display: none; + } +} \ No newline at end of file diff --git a/docs/html/PythonDCPSAPIGuide/_static/comment-bright.png b/docs/html/PythonDCPSAPIGuide/_static/comment-bright.png new file mode 100644 index 000000000..551517b8c Binary files /dev/null and b/docs/html/PythonDCPSAPIGuide/_static/comment-bright.png differ diff --git a/docs/html/PythonDCPSAPIGuide/_static/comment-close.png b/docs/html/PythonDCPSAPIGuide/_static/comment-close.png new file mode 100644 index 000000000..09b54be46 Binary files /dev/null and b/docs/html/PythonDCPSAPIGuide/_static/comment-close.png differ diff --git a/docs/html/PythonDCPSAPIGuide/_static/comment.png b/docs/html/PythonDCPSAPIGuide/_static/comment.png new file mode 100644 index 000000000..92feb52b8 Binary files /dev/null and b/docs/html/PythonDCPSAPIGuide/_static/comment.png differ diff --git a/docs/html/PythonDCPSAPIGuide/_static/doctools.js b/docs/html/PythonDCPSAPIGuide/_static/doctools.js new file mode 100644 index 000000000..c5455c905 --- /dev/null +++ b/docs/html/PythonDCPSAPIGuide/_static/doctools.js @@ -0,0 +1,238 @@ +/* + * doctools.js + * ~~~~~~~~~~~ + * + * Sphinx JavaScript utilities for all documentation. + * + * :copyright: Copyright 2007-2014 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +/** + * select a different prefix for underscore + */ +$u = _.noConflict(); + +/** + * make the code below compatible with browsers without + * an installed firebug like debugger +if (!window.console || !console.firebug) { + var names = ["log", "debug", "info", "warn", "error", "assert", "dir", + "dirxml", "group", "groupEnd", "time", "timeEnd", "count", "trace", + "profile", "profileEnd"]; + window.console = {}; + for (var i = 0; i < names.length; ++i) + window.console[names[i]] = function() {}; +} + */ + +/** + * small helper function to urldecode strings + */ +jQuery.urldecode = function(x) { + return decodeURIComponent(x).replace(/\+/g, ' '); +}; + +/** + * small helper function to urlencode strings + */ +jQuery.urlencode = encodeURIComponent; + +/** + * This function returns the parsed url parameters of the + * current request. Multiple values per key are supported, + * it will always return arrays of strings for the value parts. + */ +jQuery.getQueryParameters = function(s) { + if (typeof s == 'undefined') + s = document.location.search; + var parts = s.substr(s.indexOf('?') + 1).split('&'); + var result = {}; + for (var i = 0; i < parts.length; i++) { + var tmp = parts[i].split('=', 2); + var key = jQuery.urldecode(tmp[0]); + var value = jQuery.urldecode(tmp[1]); + if (key in result) + result[key].push(value); + else + result[key] = [value]; + } + return result; +}; + +/** + * highlight a given string on a jquery object by wrapping it in + * span elements with the given class name. + */ +jQuery.fn.highlightText = function(text, className) { + function highlight(node) { + if (node.nodeType == 3) { + var val = node.nodeValue; + var pos = val.toLowerCase().indexOf(text); + if (pos >= 0 && !jQuery(node.parentNode).hasClass(className)) { + var span = document.createElement("span"); + span.className = className; + span.appendChild(document.createTextNode(val.substr(pos, text.length))); + node.parentNode.insertBefore(span, node.parentNode.insertBefore( + document.createTextNode(val.substr(pos + text.length)), + node.nextSibling)); + node.nodeValue = val.substr(0, pos); + } + } + else if (!jQuery(node).is("button, select, textarea")) { + jQuery.each(node.childNodes, function() { + highlight(this); + }); + } + } + return this.each(function() { + highlight(this); + }); +}; + +/** + * Small JavaScript module for the documentation. + */ +var Documentation = { + + init : function() { + this.fixFirefoxAnchorBug(); + this.highlightSearchWords(); + this.initIndexTable(); + }, + + /** + * i18n support + */ + TRANSLATIONS : {}, + PLURAL_EXPR : function(n) { return n == 1 ? 0 : 1; }, + LOCALE : 'unknown', + + // gettext and ngettext don't access this so that the functions + // can safely bound to a different name (_ = Documentation.gettext) + gettext : function(string) { + var translated = Documentation.TRANSLATIONS[string]; + if (typeof translated == 'undefined') + return string; + return (typeof translated == 'string') ? translated : translated[0]; + }, + + ngettext : function(singular, plural, n) { + var translated = Documentation.TRANSLATIONS[singular]; + if (typeof translated == 'undefined') + return (n == 1) ? singular : plural; + return translated[Documentation.PLURALEXPR(n)]; + }, + + addTranslations : function(catalog) { + for (var key in catalog.messages) + this.TRANSLATIONS[key] = catalog.messages[key]; + this.PLURAL_EXPR = new Function('n', 'return +(' + catalog.plural_expr + ')'); + this.LOCALE = catalog.locale; + }, + + /** + * add context elements like header anchor links + */ + addContextElements : function() { + $('div[id] > :header:first').each(function() { + $('\u00B6'). + attr('href', '#' + this.id). + attr('title', _('Permalink to this headline')). + appendTo(this); + }); + $('dt[id]').each(function() { + $('\u00B6'). + attr('href', '#' + this.id). + attr('title', _('Permalink to this definition')). + appendTo(this); + }); + }, + + /** + * workaround a firefox stupidity + */ + fixFirefoxAnchorBug : function() { + if (document.location.hash && $.browser.mozilla) + window.setTimeout(function() { + document.location.href += ''; + }, 10); + }, + + /** + * highlight the search words provided in the url in the text + */ + highlightSearchWords : function() { + var params = $.getQueryParameters(); + var terms = (params.highlight) ? params.highlight[0].split(/\s+/) : []; + if (terms.length) { + var body = $('div.body'); + if (!body.length) { + body = $('body'); + } + window.setTimeout(function() { + $.each(terms, function() { + body.highlightText(this.toLowerCase(), 'highlighted'); + }); + }, 10); + $('') + .appendTo($('#searchbox')); + } + }, + + /** + * init the domain index toggle buttons + */ + initIndexTable : function() { + var togglers = $('img.toggler').click(function() { + var src = $(this).attr('src'); + var idnum = $(this).attr('id').substr(7); + $('tr.cg-' + idnum).toggle(); + if (src.substr(-9) == 'minus.png') + $(this).attr('src', src.substr(0, src.length-9) + 'plus.png'); + else + $(this).attr('src', src.substr(0, src.length-8) + 'minus.png'); + }).css('display', ''); + if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) { + togglers.click(); + } + }, + + /** + * helper function to hide the search marks again + */ + hideSearchWords : function() { + $('#searchbox .highlight-link').fadeOut(300); + $('span.highlighted').removeClass('highlighted'); + }, + + /** + * make the url absolute + */ + makeURL : function(relativeURL) { + return DOCUMENTATION_OPTIONS.URL_ROOT + '/' + relativeURL; + }, + + /** + * get the current relative url + */ + getCurrentURL : function() { + var path = document.location.pathname; + var parts = path.split(/\//); + $.each(DOCUMENTATION_OPTIONS.URL_ROOT.split(/\//), function() { + if (this == '..') + parts.pop(); + }); + var url = parts.join('/'); + return path.substring(url.lastIndexOf('/') + 1, path.length - 1); + } +}; + +// quick alias for translations +_ = Documentation.gettext; + +$(document).ready(function() { + Documentation.init(); +}); diff --git a/docs/html/PythonDCPSAPIGuide/_static/down-pressed.png b/docs/html/PythonDCPSAPIGuide/_static/down-pressed.png new file mode 100644 index 000000000..6f7ad7827 Binary files /dev/null and b/docs/html/PythonDCPSAPIGuide/_static/down-pressed.png differ diff --git a/docs/html/PythonDCPSAPIGuide/_static/down.png b/docs/html/PythonDCPSAPIGuide/_static/down.png new file mode 100644 index 000000000..3003a8877 Binary files /dev/null and b/docs/html/PythonDCPSAPIGuide/_static/down.png differ diff --git a/docs/html/PythonDCPSAPIGuide/_static/file.png b/docs/html/PythonDCPSAPIGuide/_static/file.png new file mode 100644 index 000000000..d18082e39 Binary files /dev/null and b/docs/html/PythonDCPSAPIGuide/_static/file.png differ diff --git a/docs/html/PythonDCPSAPIGuide/_static/jquery.js b/docs/html/PythonDCPSAPIGuide/_static/jquery.js new file mode 100644 index 000000000..e2efc335e --- /dev/null +++ b/docs/html/PythonDCPSAPIGuide/_static/jquery.js @@ -0,0 +1,9404 @@ +/*! + * jQuery JavaScript Library v1.7.2 + * http://jquery.com/ + * + * Copyright 2011, John Resig + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * Includes Sizzle.js + * http://sizzlejs.com/ + * Copyright 2011, The Dojo Foundation + * Released under the MIT, BSD, and GPL Licenses. + * + * Date: Fri Jul 5 14:07:58 UTC 2013 + */ +(function( window, undefined ) { + +// Use the correct document accordingly with window argument (sandbox) +var document = window.document, + navigator = window.navigator, + location = window.location; +var jQuery = (function() { + +// Define a local copy of jQuery +var jQuery = function( selector, context ) { + // The jQuery object is actually just the init constructor 'enhanced' + return new jQuery.fn.init( selector, context, rootjQuery ); + }, + + // Map over jQuery in case of overwrite + _jQuery = window.jQuery, + + // Map over the $ in case of overwrite + _$ = window.$, + + // A central reference to the root jQuery(document) + rootjQuery, + + // A simple way to check for HTML strings or ID strings + // Prioritize #id over to avoid XSS via location.hash (#9521) + quickExpr = /^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/, + + // Check if a string has a non-whitespace character in it + rnotwhite = /\S/, + + // Used for trimming whitespace + trimLeft = /^\s+/, + trimRight = /\s+$/, + + // Match a standalone tag + rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>)?$/, + + // JSON RegExp + rvalidchars = /^[\],:{}\s]*$/, + rvalidescape = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, + rvalidtokens = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, + rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g, + + // Useragent RegExp + rwebkit = /(webkit)[ \/]([\w.]+)/, + ropera = /(opera)(?:.*version)?[ \/]([\w.]+)/, + rmsie = /(msie) ([\w.]+)/, + rmozilla = /(mozilla)(?:.*? rv:([\w.]+))?/, + + // Matches dashed string for camelizing + rdashAlpha = /-([a-z]|[0-9])/ig, + rmsPrefix = /^-ms-/, + + // Used by jQuery.camelCase as callback to replace() + fcamelCase = function( all, letter ) { + return ( letter + "" ).toUpperCase(); + }, + + // Keep a UserAgent string for use with jQuery.browser + userAgent = navigator.userAgent, + + // For matching the engine and version of the browser + browserMatch, + + // The deferred used on DOM ready + readyList, + + // The ready event handler + DOMContentLoaded, + + // Save a reference to some core methods + toString = Object.prototype.toString, + hasOwn = Object.prototype.hasOwnProperty, + push = Array.prototype.push, + slice = Array.prototype.slice, + trim = String.prototype.trim, + indexOf = Array.prototype.indexOf, + + // [[Class]] -> type pairs + class2type = {}; + +jQuery.fn = jQuery.prototype = { + constructor: jQuery, + init: function( selector, context, rootjQuery ) { + var match, elem, ret, doc; + + // Handle $(""), $(null), or $(undefined) + if ( !selector ) { + return this; + } + + // Handle $(DOMElement) + if ( selector.nodeType ) { + this.context = this[0] = selector; + this.length = 1; + return this; + } + + // The body element only exists once, optimize finding it + if ( selector === "body" && !context && document.body ) { + this.context = document; + this[0] = document.body; + this.selector = selector; + this.length = 1; + return this; + } + + // Handle HTML strings + if ( typeof selector === "string" ) { + // Are we dealing with HTML string or an ID? + if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) { + // Assume that strings that start and end with <> are HTML and skip the regex check + match = [ null, selector, null ]; + + } else { + match = quickExpr.exec( selector ); + } + + // Verify a match, and that no context was specified for #id + if ( match && (match[1] || !context) ) { + + // HANDLE: $(html) -> $(array) + if ( match[1] ) { + context = context instanceof jQuery ? context[0] : context; + doc = ( context ? context.ownerDocument || context : document ); + + // If a single string is passed in and it's a single tag + // just do a createElement and skip the rest + ret = rsingleTag.exec( selector ); + + if ( ret ) { + if ( jQuery.isPlainObject( context ) ) { + selector = [ document.createElement( ret[1] ) ]; + jQuery.fn.attr.call( selector, context, true ); + + } else { + selector = [ doc.createElement( ret[1] ) ]; + } + + } else { + ret = jQuery.buildFragment( [ match[1] ], [ doc ] ); + selector = ( ret.cacheable ? jQuery.clone(ret.fragment) : ret.fragment ).childNodes; + } + + return jQuery.merge( this, selector ); + + // HANDLE: $("#id") + } else { + elem = document.getElementById( match[2] ); + + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + if ( elem && elem.parentNode ) { + // Handle the case where IE and Opera return items + // by name instead of ID + if ( elem.id !== match[2] ) { + return rootjQuery.find( selector ); + } + + // Otherwise, we inject the element directly into the jQuery object + this.length = 1; + this[0] = elem; + } + + this.context = document; + this.selector = selector; + return this; + } + + // HANDLE: $(expr, $(...)) + } else if ( !context || context.jquery ) { + return ( context || rootjQuery ).find( selector ); + + // HANDLE: $(expr, context) + // (which is just equivalent to: $(context).find(expr) + } else { + return this.constructor( context ).find( selector ); + } + + // HANDLE: $(function) + // Shortcut for document ready + } else if ( jQuery.isFunction( selector ) ) { + return rootjQuery.ready( selector ); + } + + if ( selector.selector !== undefined ) { + this.selector = selector.selector; + this.context = selector.context; + } + + return jQuery.makeArray( selector, this ); + }, + + // Start with an empty selector + selector: "", + + // The current version of jQuery being used + jquery: "1.7.2", + + // The default length of a jQuery object is 0 + length: 0, + + // The number of elements contained in the matched element set + size: function() { + return this.length; + }, + + toArray: function() { + return slice.call( this, 0 ); + }, + + // Get the Nth element in the matched element set OR + // Get the whole matched element set as a clean array + get: function( num ) { + return num == null ? + + // Return a 'clean' array + this.toArray() : + + // Return just the object + ( num < 0 ? this[ this.length + num ] : this[ num ] ); + }, + + // Take an array of elements and push it onto the stack + // (returning the new matched element set) + pushStack: function( elems, name, selector ) { + // Build a new jQuery matched element set + var ret = this.constructor(); + + if ( jQuery.isArray( elems ) ) { + push.apply( ret, elems ); + + } else { + jQuery.merge( ret, elems ); + } + + // Add the old object onto the stack (as a reference) + ret.prevObject = this; + + ret.context = this.context; + + if ( name === "find" ) { + ret.selector = this.selector + ( this.selector ? " " : "" ) + selector; + } else if ( name ) { + ret.selector = this.selector + "." + name + "(" + selector + ")"; + } + + // Return the newly-formed element set + return ret; + }, + + // Execute a callback for every element in the matched set. + // (You can seed the arguments with an array of args, but this is + // only used internally.) + each: function( callback, args ) { + return jQuery.each( this, callback, args ); + }, + + ready: function( fn ) { + // Attach the listeners + jQuery.bindReady(); + + // Add the callback + readyList.add( fn ); + + return this; + }, + + eq: function( i ) { + i = +i; + return i === -1 ? + this.slice( i ) : + this.slice( i, i + 1 ); + }, + + first: function() { + return this.eq( 0 ); + }, + + last: function() { + return this.eq( -1 ); + }, + + slice: function() { + return this.pushStack( slice.apply( this, arguments ), + "slice", slice.call(arguments).join(",") ); + }, + + map: function( callback ) { + return this.pushStack( jQuery.map(this, function( elem, i ) { + return callback.call( elem, i, elem ); + })); + }, + + end: function() { + return this.prevObject || this.constructor(null); + }, + + // For internal use only. + // Behaves like an Array's method, not like a jQuery method. + push: push, + sort: [].sort, + splice: [].splice +}; + +// Give the init function the jQuery prototype for later instantiation +jQuery.fn.init.prototype = jQuery.fn; + +jQuery.extend = jQuery.fn.extend = function() { + var options, name, src, copy, copyIsArray, clone, + target = arguments[0] || {}, + i = 1, + length = arguments.length, + deep = false; + + // Handle a deep copy situation + if ( typeof target === "boolean" ) { + deep = target; + target = arguments[1] || {}; + // skip the boolean and the target + i = 2; + } + + // Handle case when target is a string or something (possible in deep copy) + if ( typeof target !== "object" && !jQuery.isFunction(target) ) { + target = {}; + } + + // extend jQuery itself if only one argument is passed + if ( length === i ) { + target = this; + --i; + } + + for ( ; i < length; i++ ) { + // Only deal with non-null/undefined values + if ( (options = arguments[ i ]) != null ) { + // Extend the base object + for ( name in options ) { + src = target[ name ]; + copy = options[ name ]; + + // Prevent never-ending loop + if ( target === copy ) { + continue; + } + + // Recurse if we're merging plain objects or arrays + if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) { + if ( copyIsArray ) { + copyIsArray = false; + clone = src && jQuery.isArray(src) ? src : []; + + } else { + clone = src && jQuery.isPlainObject(src) ? src : {}; + } + + // Never move original objects, clone them + target[ name ] = jQuery.extend( deep, clone, copy ); + + // Don't bring in undefined values + } else if ( copy !== undefined ) { + target[ name ] = copy; + } + } + } + } + + // Return the modified object + return target; +}; + +jQuery.extend({ + noConflict: function( deep ) { + if ( window.$ === jQuery ) { + window.$ = _$; + } + + if ( deep && window.jQuery === jQuery ) { + window.jQuery = _jQuery; + } + + return jQuery; + }, + + // Is the DOM ready to be used? Set to true once it occurs. + isReady: false, + + // A counter to track how many items to wait for before + // the ready event fires. See #6781 + readyWait: 1, + + // Hold (or release) the ready event + holdReady: function( hold ) { + if ( hold ) { + jQuery.readyWait++; + } else { + jQuery.ready( true ); + } + }, + + // Handle when the DOM is ready + ready: function( wait ) { + // Either a released hold or an DOMready/load event and not yet ready + if ( (wait === true && !--jQuery.readyWait) || (wait !== true && !jQuery.isReady) ) { + // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). + if ( !document.body ) { + return setTimeout( jQuery.ready, 1 ); + } + + // Remember that the DOM is ready + jQuery.isReady = true; + + // If a normal DOM Ready event fired, decrement, and wait if need be + if ( wait !== true && --jQuery.readyWait > 0 ) { + return; + } + + // If there are functions bound, to execute + readyList.fireWith( document, [ jQuery ] ); + + // Trigger any bound ready events + if ( jQuery.fn.trigger ) { + jQuery( document ).trigger( "ready" ).off( "ready" ); + } + } + }, + + bindReady: function() { + if ( readyList ) { + return; + } + + readyList = jQuery.Callbacks( "once memory" ); + + // Catch cases where $(document).ready() is called after the + // browser event has already occurred. + if ( document.readyState === "complete" ) { + // Handle it asynchronously to allow scripts the opportunity to delay ready + return setTimeout( jQuery.ready, 1 ); + } + + // Mozilla, Opera and webkit nightlies currently support this event + if ( document.addEventListener ) { + // Use the handy event callback + document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false ); + + // A fallback to window.onload, that will always work + window.addEventListener( "load", jQuery.ready, false ); + + // If IE event model is used + } else if ( document.attachEvent ) { + // ensure firing before onload, + // maybe late but safe also for iframes + document.attachEvent( "onreadystatechange", DOMContentLoaded ); + + // A fallback to window.onload, that will always work + window.attachEvent( "onload", jQuery.ready ); + + // If IE and not a frame + // continually check to see if the document is ready + var toplevel = false; + + try { + toplevel = window.frameElement == null; + } catch(e) {} + + if ( document.documentElement.doScroll && toplevel ) { + doScrollCheck(); + } + } + }, + + // See test/unit/core.js for details concerning isFunction. + // Since version 1.3, DOM methods and functions like alert + // aren't supported. They return false on IE (#2968). + isFunction: function( obj ) { + return jQuery.type(obj) === "function"; + }, + + isArray: Array.isArray || function( obj ) { + return jQuery.type(obj) === "array"; + }, + + isWindow: function( obj ) { + return obj != null && obj == obj.window; + }, + + isNumeric: function( obj ) { + return !isNaN( parseFloat(obj) ) && isFinite( obj ); + }, + + type: function( obj ) { + return obj == null ? + String( obj ) : + class2type[ toString.call(obj) ] || "object"; + }, + + isPlainObject: function( obj ) { + // Must be an Object. + // Because of IE, we also have to check the presence of the constructor property. + // Make sure that DOM nodes and window objects don't pass through, as well + if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) { + return false; + } + + try { + // Not own constructor property must be Object + if ( obj.constructor && + !hasOwn.call(obj, "constructor") && + !hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) { + return false; + } + } catch ( e ) { + // IE8,9 Will throw exceptions on certain host objects #9897 + return false; + } + + // Own properties are enumerated firstly, so to speed up, + // if last one is own, then all properties are own. + + var key; + for ( key in obj ) {} + + return key === undefined || hasOwn.call( obj, key ); + }, + + isEmptyObject: function( obj ) { + for ( var name in obj ) { + return false; + } + return true; + }, + + error: function( msg ) { + throw new Error( msg ); + }, + + parseJSON: function( data ) { + if ( typeof data !== "string" || !data ) { + return null; + } + + // Make sure leading/trailing whitespace is removed (IE can't handle it) + data = jQuery.trim( data ); + + // Attempt to parse using the native JSON parser first + if ( window.JSON && window.JSON.parse ) { + return window.JSON.parse( data ); + } + + // Make sure the incoming data is actual JSON + // Logic borrowed from http://json.org/json2.js + if ( rvalidchars.test( data.replace( rvalidescape, "@" ) + .replace( rvalidtokens, "]" ) + .replace( rvalidbraces, "")) ) { + + return ( new Function( "return " + data ) )(); + + } + jQuery.error( "Invalid JSON: " + data ); + }, + + // Cross-browser xml parsing + parseXML: function( data ) { + if ( typeof data !== "string" || !data ) { + return null; + } + var xml, tmp; + try { + if ( window.DOMParser ) { // Standard + tmp = new DOMParser(); + xml = tmp.parseFromString( data , "text/xml" ); + } else { // IE + xml = new ActiveXObject( "Microsoft.XMLDOM" ); + xml.async = "false"; + xml.loadXML( data ); + } + } catch( e ) { + xml = undefined; + } + if ( !xml || !xml.documentElement || xml.getElementsByTagName( "parsererror" ).length ) { + jQuery.error( "Invalid XML: " + data ); + } + return xml; + }, + + noop: function() {}, + + // Evaluates a script in a global context + // Workarounds based on findings by Jim Driscoll + // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context + globalEval: function( data ) { + if ( data && rnotwhite.test( data ) ) { + // We use execScript on Internet Explorer + // We use an anonymous function so that context is window + // rather than jQuery in Firefox + ( window.execScript || function( data ) { + window[ "eval" ].call( window, data ); + } )( data ); + } + }, + + // Convert dashed to camelCase; used by the css and data modules + // Microsoft forgot to hump their vendor prefix (#9572) + camelCase: function( string ) { + return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); + }, + + nodeName: function( elem, name ) { + return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase(); + }, + + // args is for internal usage only + each: function( object, callback, args ) { + var name, i = 0, + length = object.length, + isObj = length === undefined || jQuery.isFunction( object ); + + if ( args ) { + if ( isObj ) { + for ( name in object ) { + if ( callback.apply( object[ name ], args ) === false ) { + break; + } + } + } else { + for ( ; i < length; ) { + if ( callback.apply( object[ i++ ], args ) === false ) { + break; + } + } + } + + // A special, fast, case for the most common use of each + } else { + if ( isObj ) { + for ( name in object ) { + if ( callback.call( object[ name ], name, object[ name ] ) === false ) { + break; + } + } + } else { + for ( ; i < length; ) { + if ( callback.call( object[ i ], i, object[ i++ ] ) === false ) { + break; + } + } + } + } + + return object; + }, + + // Use native String.trim function wherever possible + trim: trim ? + function( text ) { + return text == null ? + "" : + trim.call( text ); + } : + + // Otherwise use our own trimming functionality + function( text ) { + return text == null ? + "" : + text.toString().replace( trimLeft, "" ).replace( trimRight, "" ); + }, + + // results is for internal usage only + makeArray: function( array, results ) { + var ret = results || []; + + if ( array != null ) { + // The window, strings (and functions) also have 'length' + // Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930 + var type = jQuery.type( array ); + + if ( array.length == null || type === "string" || type === "function" || type === "regexp" || jQuery.isWindow( array ) ) { + push.call( ret, array ); + } else { + jQuery.merge( ret, array ); + } + } + + return ret; + }, + + inArray: function( elem, array, i ) { + var len; + + if ( array ) { + if ( indexOf ) { + return indexOf.call( array, elem, i ); + } + + len = array.length; + i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0; + + for ( ; i < len; i++ ) { + // Skip accessing in sparse arrays + if ( i in array && array[ i ] === elem ) { + return i; + } + } + } + + return -1; + }, + + merge: function( first, second ) { + var i = first.length, + j = 0; + + if ( typeof second.length === "number" ) { + for ( var l = second.length; j < l; j++ ) { + first[ i++ ] = second[ j ]; + } + + } else { + while ( second[j] !== undefined ) { + first[ i++ ] = second[ j++ ]; + } + } + + first.length = i; + + return first; + }, + + grep: function( elems, callback, inv ) { + var ret = [], retVal; + inv = !!inv; + + // Go through the array, only saving the items + // that pass the validator function + for ( var i = 0, length = elems.length; i < length; i++ ) { + retVal = !!callback( elems[ i ], i ); + if ( inv !== retVal ) { + ret.push( elems[ i ] ); + } + } + + return ret; + }, + + // arg is for internal usage only + map: function( elems, callback, arg ) { + var value, key, ret = [], + i = 0, + length = elems.length, + // jquery objects are treated as arrays + isArray = elems instanceof jQuery || length !== undefined && typeof length === "number" && ( ( length > 0 && elems[ 0 ] && elems[ length -1 ] ) || length === 0 || jQuery.isArray( elems ) ) ; + + // Go through the array, translating each of the items to their + if ( isArray ) { + for ( ; i < length; i++ ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret[ ret.length ] = value; + } + } + + // Go through every key on the object, + } else { + for ( key in elems ) { + value = callback( elems[ key ], key, arg ); + + if ( value != null ) { + ret[ ret.length ] = value; + } + } + } + + // Flatten any nested arrays + return ret.concat.apply( [], ret ); + }, + + // A global GUID counter for objects + guid: 1, + + // Bind a function to a context, optionally partially applying any + // arguments. + proxy: function( fn, context ) { + if ( typeof context === "string" ) { + var tmp = fn[ context ]; + context = fn; + fn = tmp; + } + + // Quick check to determine if target is callable, in the spec + // this throws a TypeError, but we will just return undefined. + if ( !jQuery.isFunction( fn ) ) { + return undefined; + } + + // Simulated bind + var args = slice.call( arguments, 2 ), + proxy = function() { + return fn.apply( context, args.concat( slice.call( arguments ) ) ); + }; + + // Set the guid of unique handler to the same of original handler, so it can be removed + proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++; + + return proxy; + }, + + // Mutifunctional method to get and set values to a collection + // The value/s can optionally be executed if it's a function + access: function( elems, fn, key, value, chainable, emptyGet, pass ) { + var exec, + bulk = key == null, + i = 0, + length = elems.length; + + // Sets many values + if ( key && typeof key === "object" ) { + for ( i in key ) { + jQuery.access( elems, fn, i, key[i], 1, emptyGet, value ); + } + chainable = 1; + + // Sets one value + } else if ( value !== undefined ) { + // Optionally, function values get executed if exec is true + exec = pass === undefined && jQuery.isFunction( value ); + + if ( bulk ) { + // Bulk operations only iterate when executing function values + if ( exec ) { + exec = fn; + fn = function( elem, key, value ) { + return exec.call( jQuery( elem ), value ); + }; + + // Otherwise they run against the entire set + } else { + fn.call( elems, value ); + fn = null; + } + } + + if ( fn ) { + for (; i < length; i++ ) { + fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass ); + } + } + + chainable = 1; + } + + return chainable ? + elems : + + // Gets + bulk ? + fn.call( elems ) : + length ? fn( elems[0], key ) : emptyGet; + }, + + now: function() { + return ( new Date() ).getTime(); + }, + + // Use of jQuery.browser is frowned upon. + // More details: http://docs.jquery.com/Utilities/jQuery.browser + uaMatch: function( ua ) { + ua = ua.toLowerCase(); + + var match = rwebkit.exec( ua ) || + ropera.exec( ua ) || + rmsie.exec( ua ) || + ua.indexOf("compatible") < 0 && rmozilla.exec( ua ) || + []; + + return { browser: match[1] || "", version: match[2] || "0" }; + }, + + sub: function() { + function jQuerySub( selector, context ) { + return new jQuerySub.fn.init( selector, context ); + } + jQuery.extend( true, jQuerySub, this ); + jQuerySub.superclass = this; + jQuerySub.fn = jQuerySub.prototype = this(); + jQuerySub.fn.constructor = jQuerySub; + jQuerySub.sub = this.sub; + jQuerySub.fn.init = function init( selector, context ) { + if ( context && context instanceof jQuery && !(context instanceof jQuerySub) ) { + context = jQuerySub( context ); + } + + return jQuery.fn.init.call( this, selector, context, rootjQuerySub ); + }; + jQuerySub.fn.init.prototype = jQuerySub.fn; + var rootjQuerySub = jQuerySub(document); + return jQuerySub; + }, + + browser: {} +}); + +// Populate the class2type map +jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) { + class2type[ "[object " + name + "]" ] = name.toLowerCase(); +}); + +browserMatch = jQuery.uaMatch( userAgent ); +if ( browserMatch.browser ) { + jQuery.browser[ browserMatch.browser ] = true; + jQuery.browser.version = browserMatch.version; +} + +// Deprecated, use jQuery.browser.webkit instead +if ( jQuery.browser.webkit ) { + jQuery.browser.safari = true; +} + +// IE doesn't match non-breaking spaces with \s +if ( rnotwhite.test( "\xA0" ) ) { + trimLeft = /^[\s\xA0]+/; + trimRight = /[\s\xA0]+$/; +} + +// All jQuery objects should point back to these +rootjQuery = jQuery(document); + +// Cleanup functions for the document ready method +if ( document.addEventListener ) { + DOMContentLoaded = function() { + document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false ); + jQuery.ready(); + }; + +} else if ( document.attachEvent ) { + DOMContentLoaded = function() { + // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). + if ( document.readyState === "complete" ) { + document.detachEvent( "onreadystatechange", DOMContentLoaded ); + jQuery.ready(); + } + }; +} + +// The DOM ready check for Internet Explorer +function doScrollCheck() { + if ( jQuery.isReady ) { + return; + } + + try { + // If IE is used, use the trick by Diego Perini + // http://javascript.nwbox.com/IEContentLoaded/ + document.documentElement.doScroll("left"); + } catch(e) { + setTimeout( doScrollCheck, 1 ); + return; + } + + // and execute any waiting functions + jQuery.ready(); +} + +return jQuery; + +})(); + + +// String to Object flags format cache +var flagsCache = {}; + +// Convert String-formatted flags into Object-formatted ones and store in cache +function createFlags( flags ) { + var object = flagsCache[ flags ] = {}, + i, length; + flags = flags.split( /\s+/ ); + for ( i = 0, length = flags.length; i < length; i++ ) { + object[ flags[i] ] = true; + } + return object; +} + +/* + * Create a callback list using the following parameters: + * + * flags: an optional list of space-separated flags that will change how + * the callback list behaves + * + * By default a callback list will act like an event callback list and can be + * "fired" multiple times. + * + * Possible flags: + * + * once: will ensure the callback list can only be fired once (like a Deferred) + * + * memory: will keep track of previous values and will call any callback added + * after the list has been fired right away with the latest "memorized" + * values (like a Deferred) + * + * unique: will ensure a callback can only be added once (no duplicate in the list) + * + * stopOnFalse: interrupt callings when a callback returns false + * + */ +jQuery.Callbacks = function( flags ) { + + // Convert flags from String-formatted to Object-formatted + // (we check in cache first) + flags = flags ? ( flagsCache[ flags ] || createFlags( flags ) ) : {}; + + var // Actual callback list + list = [], + // Stack of fire calls for repeatable lists + stack = [], + // Last fire value (for non-forgettable lists) + memory, + // Flag to know if list was already fired + fired, + // Flag to know if list is currently firing + firing, + // First callback to fire (used internally by add and fireWith) + firingStart, + // End of the loop when firing + firingLength, + // Index of currently firing callback (modified by remove if needed) + firingIndex, + // Add one or several callbacks to the list + add = function( args ) { + var i, + length, + elem, + type, + actual; + for ( i = 0, length = args.length; i < length; i++ ) { + elem = args[ i ]; + type = jQuery.type( elem ); + if ( type === "array" ) { + // Inspect recursively + add( elem ); + } else if ( type === "function" ) { + // Add if not in unique mode and callback is not in + if ( !flags.unique || !self.has( elem ) ) { + list.push( elem ); + } + } + } + }, + // Fire callbacks + fire = function( context, args ) { + args = args || []; + memory = !flags.memory || [ context, args ]; + fired = true; + firing = true; + firingIndex = firingStart || 0; + firingStart = 0; + firingLength = list.length; + for ( ; list && firingIndex < firingLength; firingIndex++ ) { + if ( list[ firingIndex ].apply( context, args ) === false && flags.stopOnFalse ) { + memory = true; // Mark as halted + break; + } + } + firing = false; + if ( list ) { + if ( !flags.once ) { + if ( stack && stack.length ) { + memory = stack.shift(); + self.fireWith( memory[ 0 ], memory[ 1 ] ); + } + } else if ( memory === true ) { + self.disable(); + } else { + list = []; + } + } + }, + // Actual Callbacks object + self = { + // Add a callback or a collection of callbacks to the list + add: function() { + if ( list ) { + var length = list.length; + add( arguments ); + // Do we need to add the callbacks to the + // current firing batch? + if ( firing ) { + firingLength = list.length; + // With memory, if we're not firing then + // we should call right away, unless previous + // firing was halted (stopOnFalse) + } else if ( memory && memory !== true ) { + firingStart = length; + fire( memory[ 0 ], memory[ 1 ] ); + } + } + return this; + }, + // Remove a callback from the list + remove: function() { + if ( list ) { + var args = arguments, + argIndex = 0, + argLength = args.length; + for ( ; argIndex < argLength ; argIndex++ ) { + for ( var i = 0; i < list.length; i++ ) { + if ( args[ argIndex ] === list[ i ] ) { + // Handle firingIndex and firingLength + if ( firing ) { + if ( i <= firingLength ) { + firingLength--; + if ( i <= firingIndex ) { + firingIndex--; + } + } + } + // Remove the element + list.splice( i--, 1 ); + // If we have some unicity property then + // we only need to do this once + if ( flags.unique ) { + break; + } + } + } + } + } + return this; + }, + // Control if a given callback is in the list + has: function( fn ) { + if ( list ) { + var i = 0, + length = list.length; + for ( ; i < length; i++ ) { + if ( fn === list[ i ] ) { + return true; + } + } + } + return false; + }, + // Remove all callbacks from the list + empty: function() { + list = []; + return this; + }, + // Have the list do nothing anymore + disable: function() { + list = stack = memory = undefined; + return this; + }, + // Is it disabled? + disabled: function() { + return !list; + }, + // Lock the list in its current state + lock: function() { + stack = undefined; + if ( !memory || memory === true ) { + self.disable(); + } + return this; + }, + // Is it locked? + locked: function() { + return !stack; + }, + // Call all callbacks with the given context and arguments + fireWith: function( context, args ) { + if ( stack ) { + if ( firing ) { + if ( !flags.once ) { + stack.push( [ context, args ] ); + } + } else if ( !( flags.once && memory ) ) { + fire( context, args ); + } + } + return this; + }, + // Call all the callbacks with the given arguments + fire: function() { + self.fireWith( this, arguments ); + return this; + }, + // To know if the callbacks have already been called at least once + fired: function() { + return !!fired; + } + }; + + return self; +}; + + + + +var // Static reference to slice + sliceDeferred = [].slice; + +jQuery.extend({ + + Deferred: function( func ) { + var doneList = jQuery.Callbacks( "once memory" ), + failList = jQuery.Callbacks( "once memory" ), + progressList = jQuery.Callbacks( "memory" ), + state = "pending", + lists = { + resolve: doneList, + reject: failList, + notify: progressList + }, + promise = { + done: doneList.add, + fail: failList.add, + progress: progressList.add, + + state: function() { + return state; + }, + + // Deprecated + isResolved: doneList.fired, + isRejected: failList.fired, + + then: function( doneCallbacks, failCallbacks, progressCallbacks ) { + deferred.done( doneCallbacks ).fail( failCallbacks ).progress( progressCallbacks ); + return this; + }, + always: function() { + deferred.done.apply( deferred, arguments ).fail.apply( deferred, arguments ); + return this; + }, + pipe: function( fnDone, fnFail, fnProgress ) { + return jQuery.Deferred(function( newDefer ) { + jQuery.each( { + done: [ fnDone, "resolve" ], + fail: [ fnFail, "reject" ], + progress: [ fnProgress, "notify" ] + }, function( handler, data ) { + var fn = data[ 0 ], + action = data[ 1 ], + returned; + if ( jQuery.isFunction( fn ) ) { + deferred[ handler ](function() { + returned = fn.apply( this, arguments ); + if ( returned && jQuery.isFunction( returned.promise ) ) { + returned.promise().then( newDefer.resolve, newDefer.reject, newDefer.notify ); + } else { + newDefer[ action + "With" ]( this === deferred ? newDefer : this, [ returned ] ); + } + }); + } else { + deferred[ handler ]( newDefer[ action ] ); + } + }); + }).promise(); + }, + // Get a promise for this deferred + // If obj is provided, the promise aspect is added to the object + promise: function( obj ) { + if ( obj == null ) { + obj = promise; + } else { + for ( var key in promise ) { + obj[ key ] = promise[ key ]; + } + } + return obj; + } + }, + deferred = promise.promise({}), + key; + + for ( key in lists ) { + deferred[ key ] = lists[ key ].fire; + deferred[ key + "With" ] = lists[ key ].fireWith; + } + + // Handle state + deferred.done( function() { + state = "resolved"; + }, failList.disable, progressList.lock ).fail( function() { + state = "rejected"; + }, doneList.disable, progressList.lock ); + + // Call given func if any + if ( func ) { + func.call( deferred, deferred ); + } + + // All done! + return deferred; + }, + + // Deferred helper + when: function( firstParam ) { + var args = sliceDeferred.call( arguments, 0 ), + i = 0, + length = args.length, + pValues = new Array( length ), + count = length, + pCount = length, + deferred = length <= 1 && firstParam && jQuery.isFunction( firstParam.promise ) ? + firstParam : + jQuery.Deferred(), + promise = deferred.promise(); + function resolveFunc( i ) { + return function( value ) { + args[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value; + if ( !( --count ) ) { + deferred.resolveWith( deferred, args ); + } + }; + } + function progressFunc( i ) { + return function( value ) { + pValues[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value; + deferred.notifyWith( promise, pValues ); + }; + } + if ( length > 1 ) { + for ( ; i < length; i++ ) { + if ( args[ i ] && args[ i ].promise && jQuery.isFunction( args[ i ].promise ) ) { + args[ i ].promise().then( resolveFunc(i), deferred.reject, progressFunc(i) ); + } else { + --count; + } + } + if ( !count ) { + deferred.resolveWith( deferred, args ); + } + } else if ( deferred !== firstParam ) { + deferred.resolveWith( deferred, length ? [ firstParam ] : [] ); + } + return promise; + } +}); + + + + +jQuery.support = (function() { + + var support, + all, + a, + select, + opt, + input, + fragment, + tds, + events, + eventName, + i, + isSupported, + div = document.createElement( "div" ), + documentElement = document.documentElement; + + // Preliminary tests + div.setAttribute("className", "t"); + div.innerHTML = "
    a"; + + all = div.getElementsByTagName( "*" ); + a = div.getElementsByTagName( "a" )[ 0 ]; + + // Can't get basic test support + if ( !all || !all.length || !a ) { + return {}; + } + + // First batch of supports tests + select = document.createElement( "select" ); + opt = select.appendChild( document.createElement("option") ); + input = div.getElementsByTagName( "input" )[ 0 ]; + + support = { + // IE strips leading whitespace when .innerHTML is used + leadingWhitespace: ( div.firstChild.nodeType === 3 ), + + // Make sure that tbody elements aren't automatically inserted + // IE will insert them into empty tables + tbody: !div.getElementsByTagName("tbody").length, + + // Make sure that link elements get serialized correctly by innerHTML + // This requires a wrapper element in IE + htmlSerialize: !!div.getElementsByTagName("link").length, + + // Get the style information from getAttribute + // (IE uses .cssText instead) + style: /top/.test( a.getAttribute("style") ), + + // Make sure that URLs aren't manipulated + // (IE normalizes it by default) + hrefNormalized: ( a.getAttribute("href") === "/a" ), + + // Make sure that element opacity exists + // (IE uses filter instead) + // Use a regex to work around a WebKit issue. See #5145 + opacity: /^0.55/.test( a.style.opacity ), + + // Verify style float existence + // (IE uses styleFloat instead of cssFloat) + cssFloat: !!a.style.cssFloat, + + // Make sure that if no value is specified for a checkbox + // that it defaults to "on". + // (WebKit defaults to "" instead) + checkOn: ( input.value === "on" ), + + // Make sure that a selected-by-default option has a working selected property. + // (WebKit defaults to false instead of true, IE too, if it's in an optgroup) + optSelected: opt.selected, + + // Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7) + getSetAttribute: div.className !== "t", + + // Tests for enctype support on a form(#6743) + enctype: !!document.createElement("form").enctype, + + // Makes sure cloning an html5 element does not cause problems + // Where outerHTML is undefined, this still works + html5Clone: document.createElement("nav").cloneNode( true ).outerHTML !== "<:nav>", + + // Will be defined later + submitBubbles: true, + changeBubbles: true, + focusinBubbles: false, + deleteExpando: true, + noCloneEvent: true, + inlineBlockNeedsLayout: false, + shrinkWrapBlocks: false, + reliableMarginRight: true, + pixelMargin: true + }; + + // jQuery.boxModel DEPRECATED in 1.3, use jQuery.support.boxModel instead + jQuery.boxModel = support.boxModel = (document.compatMode === "CSS1Compat"); + + // Make sure checked status is properly cloned + input.checked = true; + support.noCloneChecked = input.cloneNode( true ).checked; + + // Make sure that the options inside disabled selects aren't marked as disabled + // (WebKit marks them as disabled) + select.disabled = true; + support.optDisabled = !opt.disabled; + + // Test to see if it's possible to delete an expando from an element + // Fails in Internet Explorer + try { + delete div.test; + } catch( e ) { + support.deleteExpando = false; + } + + if ( !div.addEventListener && div.attachEvent && div.fireEvent ) { + div.attachEvent( "onclick", function() { + // Cloning a node shouldn't copy over any + // bound event handlers (IE does this) + support.noCloneEvent = false; + }); + div.cloneNode( true ).fireEvent( "onclick" ); + } + + // Check if a radio maintains its value + // after being appended to the DOM + input = document.createElement("input"); + input.value = "t"; + input.setAttribute("type", "radio"); + support.radioValue = input.value === "t"; + + input.setAttribute("checked", "checked"); + + // #11217 - WebKit loses check when the name is after the checked attribute + input.setAttribute( "name", "t" ); + + div.appendChild( input ); + fragment = document.createDocumentFragment(); + fragment.appendChild( div.lastChild ); + + // WebKit doesn't clone checked state correctly in fragments + support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked; + + // Check if a disconnected checkbox will retain its checked + // value of true after appended to the DOM (IE6/7) + support.appendChecked = input.checked; + + fragment.removeChild( input ); + fragment.appendChild( div ); + + // Technique from Juriy Zaytsev + // http://perfectionkills.com/detecting-event-support-without-browser-sniffing/ + // We only care about the case where non-standard event systems + // are used, namely in IE. Short-circuiting here helps us to + // avoid an eval call (in setAttribute) which can cause CSP + // to go haywire. See: https://developer.mozilla.org/en/Security/CSP + if ( div.attachEvent ) { + for ( i in { + submit: 1, + change: 1, + focusin: 1 + }) { + eventName = "on" + i; + isSupported = ( eventName in div ); + if ( !isSupported ) { + div.setAttribute( eventName, "return;" ); + isSupported = ( typeof div[ eventName ] === "function" ); + } + support[ i + "Bubbles" ] = isSupported; + } + } + + fragment.removeChild( div ); + + // Null elements to avoid leaks in IE + fragment = select = opt = div = input = null; + + // Run tests that need a body at doc ready + jQuery(function() { + var container, outer, inner, table, td, offsetSupport, + marginDiv, conMarginTop, style, html, positionTopLeftWidthHeight, + paddingMarginBorderVisibility, paddingMarginBorder, + body = document.getElementsByTagName("body")[0]; + + if ( !body ) { + // Return for frameset docs that don't have a body + return; + } + + conMarginTop = 1; + paddingMarginBorder = "padding:0;margin:0;border:"; + positionTopLeftWidthHeight = "position:absolute;top:0;left:0;width:1px;height:1px;"; + paddingMarginBorderVisibility = paddingMarginBorder + "0;visibility:hidden;"; + style = "style='" + positionTopLeftWidthHeight + paddingMarginBorder + "5px solid #000;"; + html = "
    " + + "" + + "
    "; + + container = document.createElement("div"); + container.style.cssText = paddingMarginBorderVisibility + "width:0;height:0;position:static;top:0;margin-top:" + conMarginTop + "px"; + body.insertBefore( container, body.firstChild ); + + // Construct the test element + div = document.createElement("div"); + container.appendChild( div ); + + // Check if table cells still have offsetWidth/Height when they are set + // to display:none and there are still other visible table cells in a + // table row; if so, offsetWidth/Height are not reliable for use when + // determining if an element has been hidden directly using + // display:none (it is still safe to use offsets if a parent element is + // hidden; don safety goggles and see bug #4512 for more information). + // (only IE 8 fails this test) + div.innerHTML = "
    t
    "; + tds = div.getElementsByTagName( "td" ); + isSupported = ( tds[ 0 ].offsetHeight === 0 ); + + tds[ 0 ].style.display = ""; + tds[ 1 ].style.display = "none"; + + // Check if empty table cells still have offsetWidth/Height + // (IE <= 8 fail this test) + support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 ); + + // Check if div with explicit width and no margin-right incorrectly + // gets computed margin-right based on width of container. For more + // info see bug #3333 + // Fails in WebKit before Feb 2011 nightlies + // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right + if ( window.getComputedStyle ) { + div.innerHTML = ""; + marginDiv = document.createElement( "div" ); + marginDiv.style.width = "0"; + marginDiv.style.marginRight = "0"; + div.style.width = "2px"; + div.appendChild( marginDiv ); + support.reliableMarginRight = + ( parseInt( ( window.getComputedStyle( marginDiv, null ) || { marginRight: 0 } ).marginRight, 10 ) || 0 ) === 0; + } + + if ( typeof div.style.zoom !== "undefined" ) { + // Check if natively block-level elements act like inline-block + // elements when setting their display to 'inline' and giving + // them layout + // (IE < 8 does this) + div.innerHTML = ""; + div.style.width = div.style.padding = "1px"; + div.style.border = 0; + div.style.overflow = "hidden"; + div.style.display = "inline"; + div.style.zoom = 1; + support.inlineBlockNeedsLayout = ( div.offsetWidth === 3 ); + + // Check if elements with layout shrink-wrap their children + // (IE 6 does this) + div.style.display = "block"; + div.style.overflow = "visible"; + div.innerHTML = "
    "; + support.shrinkWrapBlocks = ( div.offsetWidth !== 3 ); + } + + div.style.cssText = positionTopLeftWidthHeight + paddingMarginBorderVisibility; + div.innerHTML = html; + + outer = div.firstChild; + inner = outer.firstChild; + td = outer.nextSibling.firstChild.firstChild; + + offsetSupport = { + doesNotAddBorder: ( inner.offsetTop !== 5 ), + doesAddBorderForTableAndCells: ( td.offsetTop === 5 ) + }; + + inner.style.position = "fixed"; + inner.style.top = "20px"; + + // safari subtracts parent border width here which is 5px + offsetSupport.fixedPosition = ( inner.offsetTop === 20 || inner.offsetTop === 15 ); + inner.style.position = inner.style.top = ""; + + outer.style.overflow = "hidden"; + outer.style.position = "relative"; + + offsetSupport.subtractsBorderForOverflowNotVisible = ( inner.offsetTop === -5 ); + offsetSupport.doesNotIncludeMarginInBodyOffset = ( body.offsetTop !== conMarginTop ); + + if ( window.getComputedStyle ) { + div.style.marginTop = "1%"; + support.pixelMargin = ( window.getComputedStyle( div, null ) || { marginTop: 0 } ).marginTop !== "1%"; + } + + if ( typeof container.style.zoom !== "undefined" ) { + container.style.zoom = 1; + } + + body.removeChild( container ); + marginDiv = div = container = null; + + jQuery.extend( support, offsetSupport ); + }); + + return support; +})(); + + + + +var rbrace = /^(?:\{.*\}|\[.*\])$/, + rmultiDash = /([A-Z])/g; + +jQuery.extend({ + cache: {}, + + // Please use with caution + uuid: 0, + + // Unique for each copy of jQuery on the page + // Non-digits removed to match rinlinejQuery + expando: "jQuery" + ( jQuery.fn.jquery + Math.random() ).replace( /\D/g, "" ), + + // The following elements throw uncatchable exceptions if you + // attempt to add expando properties to them. + noData: { + "embed": true, + // Ban all objects except for Flash (which handle expandos) + "object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000", + "applet": true + }, + + hasData: function( elem ) { + elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ]; + return !!elem && !isEmptyDataObject( elem ); + }, + + data: function( elem, name, data, pvt /* Internal Use Only */ ) { + if ( !jQuery.acceptData( elem ) ) { + return; + } + + var privateCache, thisCache, ret, + internalKey = jQuery.expando, + getByName = typeof name === "string", + + // We have to handle DOM nodes and JS objects differently because IE6-7 + // can't GC object references properly across the DOM-JS boundary + isNode = elem.nodeType, + + // Only DOM nodes need the global jQuery cache; JS object data is + // attached directly to the object so GC can occur automatically + cache = isNode ? jQuery.cache : elem, + + // Only defining an ID for JS objects if its cache already exists allows + // the code to shortcut on the same path as a DOM node with no cache + id = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey, + isEvents = name === "events"; + + // Avoid doing any more work than we need to when trying to get data on an + // object that has no data at all + if ( (!id || !cache[id] || (!isEvents && !pvt && !cache[id].data)) && getByName && data === undefined ) { + return; + } + + if ( !id ) { + // Only DOM nodes need a new unique ID for each element since their data + // ends up in the global cache + if ( isNode ) { + elem[ internalKey ] = id = ++jQuery.uuid; + } else { + id = internalKey; + } + } + + if ( !cache[ id ] ) { + cache[ id ] = {}; + + // Avoids exposing jQuery metadata on plain JS objects when the object + // is serialized using JSON.stringify + if ( !isNode ) { + cache[ id ].toJSON = jQuery.noop; + } + } + + // An object can be passed to jQuery.data instead of a key/value pair; this gets + // shallow copied over onto the existing cache + if ( typeof name === "object" || typeof name === "function" ) { + if ( pvt ) { + cache[ id ] = jQuery.extend( cache[ id ], name ); + } else { + cache[ id ].data = jQuery.extend( cache[ id ].data, name ); + } + } + + privateCache = thisCache = cache[ id ]; + + // jQuery data() is stored in a separate object inside the object's internal data + // cache in order to avoid key collisions between internal data and user-defined + // data. + if ( !pvt ) { + if ( !thisCache.data ) { + thisCache.data = {}; + } + + thisCache = thisCache.data; + } + + if ( data !== undefined ) { + thisCache[ jQuery.camelCase( name ) ] = data; + } + + // Users should not attempt to inspect the internal events object using jQuery.data, + // it is undocumented and subject to change. But does anyone listen? No. + if ( isEvents && !thisCache[ name ] ) { + return privateCache.events; + } + + // Check for both converted-to-camel and non-converted data property names + // If a data property was specified + if ( getByName ) { + + // First Try to find as-is property data + ret = thisCache[ name ]; + + // Test for null|undefined property data + if ( ret == null ) { + + // Try to find the camelCased property + ret = thisCache[ jQuery.camelCase( name ) ]; + } + } else { + ret = thisCache; + } + + return ret; + }, + + removeData: function( elem, name, pvt /* Internal Use Only */ ) { + if ( !jQuery.acceptData( elem ) ) { + return; + } + + var thisCache, i, l, + + // Reference to internal data cache key + internalKey = jQuery.expando, + + isNode = elem.nodeType, + + // See jQuery.data for more information + cache = isNode ? jQuery.cache : elem, + + // See jQuery.data for more information + id = isNode ? elem[ internalKey ] : internalKey; + + // If there is already no cache entry for this object, there is no + // purpose in continuing + if ( !cache[ id ] ) { + return; + } + + if ( name ) { + + thisCache = pvt ? cache[ id ] : cache[ id ].data; + + if ( thisCache ) { + + // Support array or space separated string names for data keys + if ( !jQuery.isArray( name ) ) { + + // try the string as a key before any manipulation + if ( name in thisCache ) { + name = [ name ]; + } else { + + // split the camel cased version by spaces unless a key with the spaces exists + name = jQuery.camelCase( name ); + if ( name in thisCache ) { + name = [ name ]; + } else { + name = name.split( " " ); + } + } + } + + for ( i = 0, l = name.length; i < l; i++ ) { + delete thisCache[ name[i] ]; + } + + // If there is no data left in the cache, we want to continue + // and let the cache object itself get destroyed + if ( !( pvt ? isEmptyDataObject : jQuery.isEmptyObject )( thisCache ) ) { + return; + } + } + } + + // See jQuery.data for more information + if ( !pvt ) { + delete cache[ id ].data; + + // Don't destroy the parent cache unless the internal data object + // had been the only thing left in it + if ( !isEmptyDataObject(cache[ id ]) ) { + return; + } + } + + // Browsers that fail expando deletion also refuse to delete expandos on + // the window, but it will allow it on all other JS objects; other browsers + // don't care + // Ensure that `cache` is not a window object #10080 + if ( jQuery.support.deleteExpando || !cache.setInterval ) { + delete cache[ id ]; + } else { + cache[ id ] = null; + } + + // We destroyed the cache and need to eliminate the expando on the node to avoid + // false lookups in the cache for entries that no longer exist + if ( isNode ) { + // IE does not allow us to delete expando properties from nodes, + // nor does it have a removeAttribute function on Document nodes; + // we must handle all of these cases + if ( jQuery.support.deleteExpando ) { + delete elem[ internalKey ]; + } else if ( elem.removeAttribute ) { + elem.removeAttribute( internalKey ); + } else { + elem[ internalKey ] = null; + } + } + }, + + // For internal use only. + _data: function( elem, name, data ) { + return jQuery.data( elem, name, data, true ); + }, + + // A method for determining if a DOM node can handle the data expando + acceptData: function( elem ) { + if ( elem.nodeName ) { + var match = jQuery.noData[ elem.nodeName.toLowerCase() ]; + + if ( match ) { + return !(match === true || elem.getAttribute("classid") !== match); + } + } + + return true; + } +}); + +jQuery.fn.extend({ + data: function( key, value ) { + var parts, part, attr, name, l, + elem = this[0], + i = 0, + data = null; + + // Gets all values + if ( key === undefined ) { + if ( this.length ) { + data = jQuery.data( elem ); + + if ( elem.nodeType === 1 && !jQuery._data( elem, "parsedAttrs" ) ) { + attr = elem.attributes; + for ( l = attr.length; i < l; i++ ) { + name = attr[i].name; + + if ( name.indexOf( "data-" ) === 0 ) { + name = jQuery.camelCase( name.substring(5) ); + + dataAttr( elem, name, data[ name ] ); + } + } + jQuery._data( elem, "parsedAttrs", true ); + } + } + + return data; + } + + // Sets multiple values + if ( typeof key === "object" ) { + return this.each(function() { + jQuery.data( this, key ); + }); + } + + parts = key.split( ".", 2 ); + parts[1] = parts[1] ? "." + parts[1] : ""; + part = parts[1] + "!"; + + return jQuery.access( this, function( value ) { + + if ( value === undefined ) { + data = this.triggerHandler( "getData" + part, [ parts[0] ] ); + + // Try to fetch any internally stored data first + if ( data === undefined && elem ) { + data = jQuery.data( elem, key ); + data = dataAttr( elem, key, data ); + } + + return data === undefined && parts[1] ? + this.data( parts[0] ) : + data; + } + + parts[1] = value; + this.each(function() { + var self = jQuery( this ); + + self.triggerHandler( "setData" + part, parts ); + jQuery.data( this, key, value ); + self.triggerHandler( "changeData" + part, parts ); + }); + }, null, value, arguments.length > 1, null, false ); + }, + + removeData: function( key ) { + return this.each(function() { + jQuery.removeData( this, key ); + }); + } +}); + +function dataAttr( elem, key, data ) { + // If nothing was found internally, try to fetch any + // data from the HTML5 data-* attribute + if ( data === undefined && elem.nodeType === 1 ) { + + var name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase(); + + data = elem.getAttribute( name ); + + if ( typeof data === "string" ) { + try { + data = data === "true" ? true : + data === "false" ? false : + data === "null" ? null : + jQuery.isNumeric( data ) ? +data : + rbrace.test( data ) ? jQuery.parseJSON( data ) : + data; + } catch( e ) {} + + // Make sure we set the data so it isn't changed later + jQuery.data( elem, key, data ); + + } else { + data = undefined; + } + } + + return data; +} + +// checks a cache object for emptiness +function isEmptyDataObject( obj ) { + for ( var name in obj ) { + + // if the public data object is empty, the private is still empty + if ( name === "data" && jQuery.isEmptyObject( obj[name] ) ) { + continue; + } + if ( name !== "toJSON" ) { + return false; + } + } + + return true; +} + + + + +function handleQueueMarkDefer( elem, type, src ) { + var deferDataKey = type + "defer", + queueDataKey = type + "queue", + markDataKey = type + "mark", + defer = jQuery._data( elem, deferDataKey ); + if ( defer && + ( src === "queue" || !jQuery._data(elem, queueDataKey) ) && + ( src === "mark" || !jQuery._data(elem, markDataKey) ) ) { + // Give room for hard-coded callbacks to fire first + // and eventually mark/queue something else on the element + setTimeout( function() { + if ( !jQuery._data( elem, queueDataKey ) && + !jQuery._data( elem, markDataKey ) ) { + jQuery.removeData( elem, deferDataKey, true ); + defer.fire(); + } + }, 0 ); + } +} + +jQuery.extend({ + + _mark: function( elem, type ) { + if ( elem ) { + type = ( type || "fx" ) + "mark"; + jQuery._data( elem, type, (jQuery._data( elem, type ) || 0) + 1 ); + } + }, + + _unmark: function( force, elem, type ) { + if ( force !== true ) { + type = elem; + elem = force; + force = false; + } + if ( elem ) { + type = type || "fx"; + var key = type + "mark", + count = force ? 0 : ( (jQuery._data( elem, key ) || 1) - 1 ); + if ( count ) { + jQuery._data( elem, key, count ); + } else { + jQuery.removeData( elem, key, true ); + handleQueueMarkDefer( elem, type, "mark" ); + } + } + }, + + queue: function( elem, type, data ) { + var q; + if ( elem ) { + type = ( type || "fx" ) + "queue"; + q = jQuery._data( elem, type ); + + // Speed up dequeue by getting out quickly if this is just a lookup + if ( data ) { + if ( !q || jQuery.isArray(data) ) { + q = jQuery._data( elem, type, jQuery.makeArray(data) ); + } else { + q.push( data ); + } + } + return q || []; + } + }, + + dequeue: function( elem, type ) { + type = type || "fx"; + + var queue = jQuery.queue( elem, type ), + fn = queue.shift(), + hooks = {}; + + // If the fx queue is dequeued, always remove the progress sentinel + if ( fn === "inprogress" ) { + fn = queue.shift(); + } + + if ( fn ) { + // Add a progress sentinel to prevent the fx queue from being + // automatically dequeued + if ( type === "fx" ) { + queue.unshift( "inprogress" ); + } + + jQuery._data( elem, type + ".run", hooks ); + fn.call( elem, function() { + jQuery.dequeue( elem, type ); + }, hooks ); + } + + if ( !queue.length ) { + jQuery.removeData( elem, type + "queue " + type + ".run", true ); + handleQueueMarkDefer( elem, type, "queue" ); + } + } +}); + +jQuery.fn.extend({ + queue: function( type, data ) { + var setter = 2; + + if ( typeof type !== "string" ) { + data = type; + type = "fx"; + setter--; + } + + if ( arguments.length < setter ) { + return jQuery.queue( this[0], type ); + } + + return data === undefined ? + this : + this.each(function() { + var queue = jQuery.queue( this, type, data ); + + if ( type === "fx" && queue[0] !== "inprogress" ) { + jQuery.dequeue( this, type ); + } + }); + }, + dequeue: function( type ) { + return this.each(function() { + jQuery.dequeue( this, type ); + }); + }, + // Based off of the plugin by Clint Helfers, with permission. + // http://blindsignals.com/index.php/2009/07/jquery-delay/ + delay: function( time, type ) { + time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time; + type = type || "fx"; + + return this.queue( type, function( next, hooks ) { + var timeout = setTimeout( next, time ); + hooks.stop = function() { + clearTimeout( timeout ); + }; + }); + }, + clearQueue: function( type ) { + return this.queue( type || "fx", [] ); + }, + // Get a promise resolved when queues of a certain type + // are emptied (fx is the type by default) + promise: function( type, object ) { + if ( typeof type !== "string" ) { + object = type; + type = undefined; + } + type = type || "fx"; + var defer = jQuery.Deferred(), + elements = this, + i = elements.length, + count = 1, + deferDataKey = type + "defer", + queueDataKey = type + "queue", + markDataKey = type + "mark", + tmp; + function resolve() { + if ( !( --count ) ) { + defer.resolveWith( elements, [ elements ] ); + } + } + while( i-- ) { + if (( tmp = jQuery.data( elements[ i ], deferDataKey, undefined, true ) || + ( jQuery.data( elements[ i ], queueDataKey, undefined, true ) || + jQuery.data( elements[ i ], markDataKey, undefined, true ) ) && + jQuery.data( elements[ i ], deferDataKey, jQuery.Callbacks( "once memory" ), true ) )) { + count++; + tmp.add( resolve ); + } + } + resolve(); + return defer.promise( object ); + } +}); + + + + +var rclass = /[\n\t\r]/g, + rspace = /\s+/, + rreturn = /\r/g, + rtype = /^(?:button|input)$/i, + rfocusable = /^(?:button|input|object|select|textarea)$/i, + rclickable = /^a(?:rea)?$/i, + rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i, + getSetAttribute = jQuery.support.getSetAttribute, + nodeHook, boolHook, fixSpecified; + +jQuery.fn.extend({ + attr: function( name, value ) { + return jQuery.access( this, jQuery.attr, name, value, arguments.length > 1 ); + }, + + removeAttr: function( name ) { + return this.each(function() { + jQuery.removeAttr( this, name ); + }); + }, + + prop: function( name, value ) { + return jQuery.access( this, jQuery.prop, name, value, arguments.length > 1 ); + }, + + removeProp: function( name ) { + name = jQuery.propFix[ name ] || name; + return this.each(function() { + // try/catch handles cases where IE balks (such as removing a property on window) + try { + this[ name ] = undefined; + delete this[ name ]; + } catch( e ) {} + }); + }, + + addClass: function( value ) { + var classNames, i, l, elem, + setClass, c, cl; + + if ( jQuery.isFunction( value ) ) { + return this.each(function( j ) { + jQuery( this ).addClass( value.call(this, j, this.className) ); + }); + } + + if ( value && typeof value === "string" ) { + classNames = value.split( rspace ); + + for ( i = 0, l = this.length; i < l; i++ ) { + elem = this[ i ]; + + if ( elem.nodeType === 1 ) { + if ( !elem.className && classNames.length === 1 ) { + elem.className = value; + + } else { + setClass = " " + elem.className + " "; + + for ( c = 0, cl = classNames.length; c < cl; c++ ) { + if ( !~setClass.indexOf( " " + classNames[ c ] + " " ) ) { + setClass += classNames[ c ] + " "; + } + } + elem.className = jQuery.trim( setClass ); + } + } + } + } + + return this; + }, + + removeClass: function( value ) { + var classNames, i, l, elem, className, c, cl; + + if ( jQuery.isFunction( value ) ) { + return this.each(function( j ) { + jQuery( this ).removeClass( value.call(this, j, this.className) ); + }); + } + + if ( (value && typeof value === "string") || value === undefined ) { + classNames = ( value || "" ).split( rspace ); + + for ( i = 0, l = this.length; i < l; i++ ) { + elem = this[ i ]; + + if ( elem.nodeType === 1 && elem.className ) { + if ( value ) { + className = (" " + elem.className + " ").replace( rclass, " " ); + for ( c = 0, cl = classNames.length; c < cl; c++ ) { + className = className.replace(" " + classNames[ c ] + " ", " "); + } + elem.className = jQuery.trim( className ); + + } else { + elem.className = ""; + } + } + } + } + + return this; + }, + + toggleClass: function( value, stateVal ) { + var type = typeof value, + isBool = typeof stateVal === "boolean"; + + if ( jQuery.isFunction( value ) ) { + return this.each(function( i ) { + jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal ); + }); + } + + return this.each(function() { + if ( type === "string" ) { + // toggle individual class names + var className, + i = 0, + self = jQuery( this ), + state = stateVal, + classNames = value.split( rspace ); + + while ( (className = classNames[ i++ ]) ) { + // check each className given, space seperated list + state = isBool ? state : !self.hasClass( className ); + self[ state ? "addClass" : "removeClass" ]( className ); + } + + } else if ( type === "undefined" || type === "boolean" ) { + if ( this.className ) { + // store className if set + jQuery._data( this, "__className__", this.className ); + } + + // toggle whole className + this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || ""; + } + }); + }, + + hasClass: function( selector ) { + var className = " " + selector + " ", + i = 0, + l = this.length; + for ( ; i < l; i++ ) { + if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) { + return true; + } + } + + return false; + }, + + val: function( value ) { + var hooks, ret, isFunction, + elem = this[0]; + + if ( !arguments.length ) { + if ( elem ) { + hooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ]; + + if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) { + return ret; + } + + ret = elem.value; + + return typeof ret === "string" ? + // handle most common string cases + ret.replace(rreturn, "") : + // handle cases where value is null/undef or number + ret == null ? "" : ret; + } + + return; + } + + isFunction = jQuery.isFunction( value ); + + return this.each(function( i ) { + var self = jQuery(this), val; + + if ( this.nodeType !== 1 ) { + return; + } + + if ( isFunction ) { + val = value.call( this, i, self.val() ); + } else { + val = value; + } + + // Treat null/undefined as ""; convert numbers to string + if ( val == null ) { + val = ""; + } else if ( typeof val === "number" ) { + val += ""; + } else if ( jQuery.isArray( val ) ) { + val = jQuery.map(val, function ( value ) { + return value == null ? "" : value + ""; + }); + } + + hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ]; + + // If set returns undefined, fall back to normal setting + if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) { + this.value = val; + } + }); + } +}); + +jQuery.extend({ + valHooks: { + option: { + get: function( elem ) { + // attributes.value is undefined in Blackberry 4.7 but + // uses .value. See #6932 + var val = elem.attributes.value; + return !val || val.specified ? elem.value : elem.text; + } + }, + select: { + get: function( elem ) { + var value, i, max, option, + index = elem.selectedIndex, + values = [], + options = elem.options, + one = elem.type === "select-one"; + + // Nothing was selected + if ( index < 0 ) { + return null; + } + + // Loop through all the selected options + i = one ? index : 0; + max = one ? index + 1 : options.length; + for ( ; i < max; i++ ) { + option = options[ i ]; + + // Don't return options that are disabled or in a disabled optgroup + if ( option.selected && (jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null) && + (!option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" )) ) { + + // Get the specific value for the option + value = jQuery( option ).val(); + + // We don't need an array for one selects + if ( one ) { + return value; + } + + // Multi-Selects return an array + values.push( value ); + } + } + + // Fixes Bug #2551 -- select.val() broken in IE after form.reset() + if ( one && !values.length && options.length ) { + return jQuery( options[ index ] ).val(); + } + + return values; + }, + + set: function( elem, value ) { + var values = jQuery.makeArray( value ); + + jQuery(elem).find("option").each(function() { + this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0; + }); + + if ( !values.length ) { + elem.selectedIndex = -1; + } + return values; + } + } + }, + + attrFn: { + val: true, + css: true, + html: true, + text: true, + data: true, + width: true, + height: true, + offset: true + }, + + attr: function( elem, name, value, pass ) { + var ret, hooks, notxml, + nType = elem.nodeType; + + // don't get/set attributes on text, comment and attribute nodes + if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + if ( pass && name in jQuery.attrFn ) { + return jQuery( elem )[ name ]( value ); + } + + // Fallback to prop when attributes are not supported + if ( typeof elem.getAttribute === "undefined" ) { + return jQuery.prop( elem, name, value ); + } + + notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); + + // All attributes are lowercase + // Grab necessary hook if one is defined + if ( notxml ) { + name = name.toLowerCase(); + hooks = jQuery.attrHooks[ name ] || ( rboolean.test( name ) ? boolHook : nodeHook ); + } + + if ( value !== undefined ) { + + if ( value === null ) { + jQuery.removeAttr( elem, name ); + return; + + } else if ( hooks && "set" in hooks && notxml && (ret = hooks.set( elem, value, name )) !== undefined ) { + return ret; + + } else { + elem.setAttribute( name, "" + value ); + return value; + } + + } else if ( hooks && "get" in hooks && notxml && (ret = hooks.get( elem, name )) !== null ) { + return ret; + + } else { + + ret = elem.getAttribute( name ); + + // Non-existent attributes return null, we normalize to undefined + return ret === null ? + undefined : + ret; + } + }, + + removeAttr: function( elem, value ) { + var propName, attrNames, name, l, isBool, + i = 0; + + if ( value && elem.nodeType === 1 ) { + attrNames = value.toLowerCase().split( rspace ); + l = attrNames.length; + + for ( ; i < l; i++ ) { + name = attrNames[ i ]; + + if ( name ) { + propName = jQuery.propFix[ name ] || name; + isBool = rboolean.test( name ); + + // See #9699 for explanation of this approach (setting first, then removal) + // Do not do this for boolean attributes (see #10870) + if ( !isBool ) { + jQuery.attr( elem, name, "" ); + } + elem.removeAttribute( getSetAttribute ? name : propName ); + + // Set corresponding property to false for boolean attributes + if ( isBool && propName in elem ) { + elem[ propName ] = false; + } + } + } + } + }, + + attrHooks: { + type: { + set: function( elem, value ) { + // We can't allow the type property to be changed (since it causes problems in IE) + if ( rtype.test( elem.nodeName ) && elem.parentNode ) { + jQuery.error( "type property can't be changed" ); + } else if ( !jQuery.support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) { + // Setting the type on a radio button after the value resets the value in IE6-9 + // Reset value to it's default in case type is set after value + // This is for element creation + var val = elem.value; + elem.setAttribute( "type", value ); + if ( val ) { + elem.value = val; + } + return value; + } + } + }, + // Use the value property for back compat + // Use the nodeHook for button elements in IE6/7 (#1954) + value: { + get: function( elem, name ) { + if ( nodeHook && jQuery.nodeName( elem, "button" ) ) { + return nodeHook.get( elem, name ); + } + return name in elem ? + elem.value : + null; + }, + set: function( elem, value, name ) { + if ( nodeHook && jQuery.nodeName( elem, "button" ) ) { + return nodeHook.set( elem, value, name ); + } + // Does not return so that setAttribute is also used + elem.value = value; + } + } + }, + + propFix: { + tabindex: "tabIndex", + readonly: "readOnly", + "for": "htmlFor", + "class": "className", + maxlength: "maxLength", + cellspacing: "cellSpacing", + cellpadding: "cellPadding", + rowspan: "rowSpan", + colspan: "colSpan", + usemap: "useMap", + frameborder: "frameBorder", + contenteditable: "contentEditable" + }, + + prop: function( elem, name, value ) { + var ret, hooks, notxml, + nType = elem.nodeType; + + // don't get/set properties on text, comment and attribute nodes + if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); + + if ( notxml ) { + // Fix name and attach hooks + name = jQuery.propFix[ name ] || name; + hooks = jQuery.propHooks[ name ]; + } + + if ( value !== undefined ) { + if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) { + return ret; + + } else { + return ( elem[ name ] = value ); + } + + } else { + if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) { + return ret; + + } else { + return elem[ name ]; + } + } + }, + + propHooks: { + tabIndex: { + get: function( elem ) { + // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set + // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ + var attributeNode = elem.getAttributeNode("tabindex"); + + return attributeNode && attributeNode.specified ? + parseInt( attributeNode.value, 10 ) : + rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ? + 0 : + undefined; + } + } + } +}); + +// Add the tabIndex propHook to attrHooks for back-compat (different case is intentional) +jQuery.attrHooks.tabindex = jQuery.propHooks.tabIndex; + +// Hook for boolean attributes +boolHook = { + get: function( elem, name ) { + // Align boolean attributes with corresponding properties + // Fall back to attribute presence where some booleans are not supported + var attrNode, + property = jQuery.prop( elem, name ); + return property === true || typeof property !== "boolean" && ( attrNode = elem.getAttributeNode(name) ) && attrNode.nodeValue !== false ? + name.toLowerCase() : + undefined; + }, + set: function( elem, value, name ) { + var propName; + if ( value === false ) { + // Remove boolean attributes when set to false + jQuery.removeAttr( elem, name ); + } else { + // value is true since we know at this point it's type boolean and not false + // Set boolean attributes to the same name and set the DOM property + propName = jQuery.propFix[ name ] || name; + if ( propName in elem ) { + // Only set the IDL specifically if it already exists on the element + elem[ propName ] = true; + } + + elem.setAttribute( name, name.toLowerCase() ); + } + return name; + } +}; + +// IE6/7 do not support getting/setting some attributes with get/setAttribute +if ( !getSetAttribute ) { + + fixSpecified = { + name: true, + id: true, + coords: true + }; + + // Use this for any attribute in IE6/7 + // This fixes almost every IE6/7 issue + nodeHook = jQuery.valHooks.button = { + get: function( elem, name ) { + var ret; + ret = elem.getAttributeNode( name ); + return ret && ( fixSpecified[ name ] ? ret.nodeValue !== "" : ret.specified ) ? + ret.nodeValue : + undefined; + }, + set: function( elem, value, name ) { + // Set the existing or create a new attribute node + var ret = elem.getAttributeNode( name ); + if ( !ret ) { + ret = document.createAttribute( name ); + elem.setAttributeNode( ret ); + } + return ( ret.nodeValue = value + "" ); + } + }; + + // Apply the nodeHook to tabindex + jQuery.attrHooks.tabindex.set = nodeHook.set; + + // Set width and height to auto instead of 0 on empty string( Bug #8150 ) + // This is for removals + jQuery.each([ "width", "height" ], function( i, name ) { + jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], { + set: function( elem, value ) { + if ( value === "" ) { + elem.setAttribute( name, "auto" ); + return value; + } + } + }); + }); + + // Set contenteditable to false on removals(#10429) + // Setting to empty string throws an error as an invalid value + jQuery.attrHooks.contenteditable = { + get: nodeHook.get, + set: function( elem, value, name ) { + if ( value === "" ) { + value = "false"; + } + nodeHook.set( elem, value, name ); + } + }; +} + + +// Some attributes require a special call on IE +if ( !jQuery.support.hrefNormalized ) { + jQuery.each([ "href", "src", "width", "height" ], function( i, name ) { + jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], { + get: function( elem ) { + var ret = elem.getAttribute( name, 2 ); + return ret === null ? undefined : ret; + } + }); + }); +} + +if ( !jQuery.support.style ) { + jQuery.attrHooks.style = { + get: function( elem ) { + // Return undefined in the case of empty string + // Normalize to lowercase since IE uppercases css property names + return elem.style.cssText.toLowerCase() || undefined; + }, + set: function( elem, value ) { + return ( elem.style.cssText = "" + value ); + } + }; +} + +// Safari mis-reports the default selected property of an option +// Accessing the parent's selectedIndex property fixes it +if ( !jQuery.support.optSelected ) { + jQuery.propHooks.selected = jQuery.extend( jQuery.propHooks.selected, { + get: function( elem ) { + var parent = elem.parentNode; + + if ( parent ) { + parent.selectedIndex; + + // Make sure that it also works with optgroups, see #5701 + if ( parent.parentNode ) { + parent.parentNode.selectedIndex; + } + } + return null; + } + }); +} + +// IE6/7 call enctype encoding +if ( !jQuery.support.enctype ) { + jQuery.propFix.enctype = "encoding"; +} + +// Radios and checkboxes getter/setter +if ( !jQuery.support.checkOn ) { + jQuery.each([ "radio", "checkbox" ], function() { + jQuery.valHooks[ this ] = { + get: function( elem ) { + // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified + return elem.getAttribute("value") === null ? "on" : elem.value; + } + }; + }); +} +jQuery.each([ "radio", "checkbox" ], function() { + jQuery.valHooks[ this ] = jQuery.extend( jQuery.valHooks[ this ], { + set: function( elem, value ) { + if ( jQuery.isArray( value ) ) { + return ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 ); + } + } + }); +}); + + + + +var rformElems = /^(?:textarea|input|select)$/i, + rtypenamespace = /^([^\.]*)?(?:\.(.+))?$/, + rhoverHack = /(?:^|\s)hover(\.\S+)?\b/, + rkeyEvent = /^key/, + rmouseEvent = /^(?:mouse|contextmenu)|click/, + rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, + rquickIs = /^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/, + quickParse = function( selector ) { + var quick = rquickIs.exec( selector ); + if ( quick ) { + // 0 1 2 3 + // [ _, tag, id, class ] + quick[1] = ( quick[1] || "" ).toLowerCase(); + quick[3] = quick[3] && new RegExp( "(?:^|\\s)" + quick[3] + "(?:\\s|$)" ); + } + return quick; + }, + quickIs = function( elem, m ) { + var attrs = elem.attributes || {}; + return ( + (!m[1] || elem.nodeName.toLowerCase() === m[1]) && + (!m[2] || (attrs.id || {}).value === m[2]) && + (!m[3] || m[3].test( (attrs[ "class" ] || {}).value )) + ); + }, + hoverHack = function( events ) { + return jQuery.event.special.hover ? events : events.replace( rhoverHack, "mouseenter$1 mouseleave$1" ); + }; + +/* + * Helper functions for managing events -- not part of the public interface. + * Props to Dean Edwards' addEvent library for many of the ideas. + */ +jQuery.event = { + + add: function( elem, types, handler, data, selector ) { + + var elemData, eventHandle, events, + t, tns, type, namespaces, handleObj, + handleObjIn, quick, handlers, special; + + // Don't attach events to noData or text/comment nodes (allow plain objects tho) + if ( elem.nodeType === 3 || elem.nodeType === 8 || !types || !handler || !(elemData = jQuery._data( elem )) ) { + return; + } + + // Caller can pass in an object of custom data in lieu of the handler + if ( handler.handler ) { + handleObjIn = handler; + handler = handleObjIn.handler; + selector = handleObjIn.selector; + } + + // Make sure that the handler has a unique ID, used to find/remove it later + if ( !handler.guid ) { + handler.guid = jQuery.guid++; + } + + // Init the element's event structure and main handler, if this is the first + events = elemData.events; + if ( !events ) { + elemData.events = events = {}; + } + eventHandle = elemData.handle; + if ( !eventHandle ) { + elemData.handle = eventHandle = function( e ) { + // Discard the second event of a jQuery.event.trigger() and + // when an event is called after a page has unloaded + return typeof jQuery !== "undefined" && (!e || jQuery.event.triggered !== e.type) ? + jQuery.event.dispatch.apply( eventHandle.elem, arguments ) : + undefined; + }; + // Add elem as a property of the handle fn to prevent a memory leak with IE non-native events + eventHandle.elem = elem; + } + + // Handle multiple events separated by a space + // jQuery(...).bind("mouseover mouseout", fn); + types = jQuery.trim( hoverHack(types) ).split( " " ); + for ( t = 0; t < types.length; t++ ) { + + tns = rtypenamespace.exec( types[t] ) || []; + type = tns[1]; + namespaces = ( tns[2] || "" ).split( "." ).sort(); + + // If event changes its type, use the special event handlers for the changed type + special = jQuery.event.special[ type ] || {}; + + // If selector defined, determine special event api type, otherwise given type + type = ( selector ? special.delegateType : special.bindType ) || type; + + // Update special based on newly reset type + special = jQuery.event.special[ type ] || {}; + + // handleObj is passed to all event handlers + handleObj = jQuery.extend({ + type: type, + origType: tns[1], + data: data, + handler: handler, + guid: handler.guid, + selector: selector, + quick: selector && quickParse( selector ), + namespace: namespaces.join(".") + }, handleObjIn ); + + // Init the event handler queue if we're the first + handlers = events[ type ]; + if ( !handlers ) { + handlers = events[ type ] = []; + handlers.delegateCount = 0; + + // Only use addEventListener/attachEvent if the special events handler returns false + if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) { + // Bind the global event handler to the element + if ( elem.addEventListener ) { + elem.addEventListener( type, eventHandle, false ); + + } else if ( elem.attachEvent ) { + elem.attachEvent( "on" + type, eventHandle ); + } + } + } + + if ( special.add ) { + special.add.call( elem, handleObj ); + + if ( !handleObj.handler.guid ) { + handleObj.handler.guid = handler.guid; + } + } + + // Add to the element's handler list, delegates in front + if ( selector ) { + handlers.splice( handlers.delegateCount++, 0, handleObj ); + } else { + handlers.push( handleObj ); + } + + // Keep track of which events have ever been used, for event optimization + jQuery.event.global[ type ] = true; + } + + // Nullify elem to prevent memory leaks in IE + elem = null; + }, + + global: {}, + + // Detach an event or set of events from an element + remove: function( elem, types, handler, selector, mappedTypes ) { + + var elemData = jQuery.hasData( elem ) && jQuery._data( elem ), + t, tns, type, origType, namespaces, origCount, + j, events, special, handle, eventType, handleObj; + + if ( !elemData || !(events = elemData.events) ) { + return; + } + + // Once for each type.namespace in types; type may be omitted + types = jQuery.trim( hoverHack( types || "" ) ).split(" "); + for ( t = 0; t < types.length; t++ ) { + tns = rtypenamespace.exec( types[t] ) || []; + type = origType = tns[1]; + namespaces = tns[2]; + + // Unbind all events (on this namespace, if provided) for the element + if ( !type ) { + for ( type in events ) { + jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); + } + continue; + } + + special = jQuery.event.special[ type ] || {}; + type = ( selector? special.delegateType : special.bindType ) || type; + eventType = events[ type ] || []; + origCount = eventType.length; + namespaces = namespaces ? new RegExp("(^|\\.)" + namespaces.split(".").sort().join("\\.(?:.*\\.)?") + "(\\.|$)") : null; + + // Remove matching events + for ( j = 0; j < eventType.length; j++ ) { + handleObj = eventType[ j ]; + + if ( ( mappedTypes || origType === handleObj.origType ) && + ( !handler || handler.guid === handleObj.guid ) && + ( !namespaces || namespaces.test( handleObj.namespace ) ) && + ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) { + eventType.splice( j--, 1 ); + + if ( handleObj.selector ) { + eventType.delegateCount--; + } + if ( special.remove ) { + special.remove.call( elem, handleObj ); + } + } + } + + // Remove generic event handler if we removed something and no more handlers exist + // (avoids potential for endless recursion during removal of special event handlers) + if ( eventType.length === 0 && origCount !== eventType.length ) { + if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) { + jQuery.removeEvent( elem, type, elemData.handle ); + } + + delete events[ type ]; + } + } + + // Remove the expando if it's no longer used + if ( jQuery.isEmptyObject( events ) ) { + handle = elemData.handle; + if ( handle ) { + handle.elem = null; + } + + // removeData also checks for emptiness and clears the expando if empty + // so use it instead of delete + jQuery.removeData( elem, [ "events", "handle" ], true ); + } + }, + + // Events that are safe to short-circuit if no handlers are attached. + // Native DOM events should not be added, they may have inline handlers. + customEvent: { + "getData": true, + "setData": true, + "changeData": true + }, + + trigger: function( event, data, elem, onlyHandlers ) { + // Don't do events on text and comment nodes + if ( elem && (elem.nodeType === 3 || elem.nodeType === 8) ) { + return; + } + + // Event object or event type + var type = event.type || event, + namespaces = [], + cache, exclusive, i, cur, old, ontype, special, handle, eventPath, bubbleType; + + // focus/blur morphs to focusin/out; ensure we're not firing them right now + if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { + return; + } + + if ( type.indexOf( "!" ) >= 0 ) { + // Exclusive events trigger only for the exact event (no namespaces) + type = type.slice(0, -1); + exclusive = true; + } + + if ( type.indexOf( "." ) >= 0 ) { + // Namespaced trigger; create a regexp to match event type in handle() + namespaces = type.split("."); + type = namespaces.shift(); + namespaces.sort(); + } + + if ( (!elem || jQuery.event.customEvent[ type ]) && !jQuery.event.global[ type ] ) { + // No jQuery handlers for this event type, and it can't have inline handlers + return; + } + + // Caller can pass in an Event, Object, or just an event type string + event = typeof event === "object" ? + // jQuery.Event object + event[ jQuery.expando ] ? event : + // Object literal + new jQuery.Event( type, event ) : + // Just the event type (string) + new jQuery.Event( type ); + + event.type = type; + event.isTrigger = true; + event.exclusive = exclusive; + event.namespace = namespaces.join( "." ); + event.namespace_re = event.namespace? new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.)?") + "(\\.|$)") : null; + ontype = type.indexOf( ":" ) < 0 ? "on" + type : ""; + + // Handle a global trigger + if ( !elem ) { + + // TODO: Stop taunting the data cache; remove global events and always attach to document + cache = jQuery.cache; + for ( i in cache ) { + if ( cache[ i ].events && cache[ i ].events[ type ] ) { + jQuery.event.trigger( event, data, cache[ i ].handle.elem, true ); + } + } + return; + } + + // Clean up the event in case it is being reused + event.result = undefined; + if ( !event.target ) { + event.target = elem; + } + + // Clone any incoming data and prepend the event, creating the handler arg list + data = data != null ? jQuery.makeArray( data ) : []; + data.unshift( event ); + + // Allow special events to draw outside the lines + special = jQuery.event.special[ type ] || {}; + if ( special.trigger && special.trigger.apply( elem, data ) === false ) { + return; + } + + // Determine event propagation path in advance, per W3C events spec (#9951) + // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) + eventPath = [[ elem, special.bindType || type ]]; + if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) { + + bubbleType = special.delegateType || type; + cur = rfocusMorph.test( bubbleType + type ) ? elem : elem.parentNode; + old = null; + for ( ; cur; cur = cur.parentNode ) { + eventPath.push([ cur, bubbleType ]); + old = cur; + } + + // Only add window if we got to document (e.g., not plain obj or detached DOM) + if ( old && old === elem.ownerDocument ) { + eventPath.push([ old.defaultView || old.parentWindow || window, bubbleType ]); + } + } + + // Fire handlers on the event path + for ( i = 0; i < eventPath.length && !event.isPropagationStopped(); i++ ) { + + cur = eventPath[i][0]; + event.type = eventPath[i][1]; + + handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] && jQuery._data( cur, "handle" ); + if ( handle ) { + handle.apply( cur, data ); + } + // Note that this is a bare JS function and not a jQuery handler + handle = ontype && cur[ ontype ]; + if ( handle && jQuery.acceptData( cur ) && handle.apply( cur, data ) === false ) { + event.preventDefault(); + } + } + event.type = type; + + // If nobody prevented the default action, do it now + if ( !onlyHandlers && !event.isDefaultPrevented() ) { + + if ( (!special._default || special._default.apply( elem.ownerDocument, data ) === false) && + !(type === "click" && jQuery.nodeName( elem, "a" )) && jQuery.acceptData( elem ) ) { + + // Call a native DOM method on the target with the same name name as the event. + // Can't use an .isFunction() check here because IE6/7 fails that test. + // Don't do default actions on window, that's where global variables be (#6170) + // IE<9 dies on focus/blur to hidden element (#1486) + if ( ontype && elem[ type ] && ((type !== "focus" && type !== "blur") || event.target.offsetWidth !== 0) && !jQuery.isWindow( elem ) ) { + + // Don't re-trigger an onFOO event when we call its FOO() method + old = elem[ ontype ]; + + if ( old ) { + elem[ ontype ] = null; + } + + // Prevent re-triggering of the same event, since we already bubbled it above + jQuery.event.triggered = type; + elem[ type ](); + jQuery.event.triggered = undefined; + + if ( old ) { + elem[ ontype ] = old; + } + } + } + } + + return event.result; + }, + + dispatch: function( event ) { + + // Make a writable jQuery.Event from the native event object + event = jQuery.event.fix( event || window.event ); + + var handlers = ( (jQuery._data( this, "events" ) || {} )[ event.type ] || []), + delegateCount = handlers.delegateCount, + args = [].slice.call( arguments, 0 ), + run_all = !event.exclusive && !event.namespace, + special = jQuery.event.special[ event.type ] || {}, + handlerQueue = [], + i, j, cur, jqcur, ret, selMatch, matched, matches, handleObj, sel, related; + + // Use the fix-ed jQuery.Event rather than the (read-only) native event + args[0] = event; + event.delegateTarget = this; + + // Call the preDispatch hook for the mapped type, and let it bail if desired + if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { + return; + } + + // Determine handlers that should run if there are delegated events + // Avoid non-left-click bubbling in Firefox (#3861) + if ( delegateCount && !(event.button && event.type === "click") ) { + + // Pregenerate a single jQuery object for reuse with .is() + jqcur = jQuery(this); + jqcur.context = this.ownerDocument || this; + + for ( cur = event.target; cur != this; cur = cur.parentNode || this ) { + + // Don't process events on disabled elements (#6911, #8165) + if ( cur.disabled !== true ) { + selMatch = {}; + matches = []; + jqcur[0] = cur; + for ( i = 0; i < delegateCount; i++ ) { + handleObj = handlers[ i ]; + sel = handleObj.selector; + + if ( selMatch[ sel ] === undefined ) { + selMatch[ sel ] = ( + handleObj.quick ? quickIs( cur, handleObj.quick ) : jqcur.is( sel ) + ); + } + if ( selMatch[ sel ] ) { + matches.push( handleObj ); + } + } + if ( matches.length ) { + handlerQueue.push({ elem: cur, matches: matches }); + } + } + } + } + + // Add the remaining (directly-bound) handlers + if ( handlers.length > delegateCount ) { + handlerQueue.push({ elem: this, matches: handlers.slice( delegateCount ) }); + } + + // Run delegates first; they may want to stop propagation beneath us + for ( i = 0; i < handlerQueue.length && !event.isPropagationStopped(); i++ ) { + matched = handlerQueue[ i ]; + event.currentTarget = matched.elem; + + for ( j = 0; j < matched.matches.length && !event.isImmediatePropagationStopped(); j++ ) { + handleObj = matched.matches[ j ]; + + // Triggered event must either 1) be non-exclusive and have no namespace, or + // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace). + if ( run_all || (!event.namespace && !handleObj.namespace) || event.namespace_re && event.namespace_re.test( handleObj.namespace ) ) { + + event.data = handleObj.data; + event.handleObj = handleObj; + + ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler ) + .apply( matched.elem, args ); + + if ( ret !== undefined ) { + event.result = ret; + if ( ret === false ) { + event.preventDefault(); + event.stopPropagation(); + } + } + } + } + } + + // Call the postDispatch hook for the mapped type + if ( special.postDispatch ) { + special.postDispatch.call( this, event ); + } + + return event.result; + }, + + // Includes some event props shared by KeyEvent and MouseEvent + // *** attrChange attrName relatedNode srcElement are not normalized, non-W3C, deprecated, will be removed in 1.8 *** + props: "attrChange attrName relatedNode srcElement altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "), + + fixHooks: {}, + + keyHooks: { + props: "char charCode key keyCode".split(" "), + filter: function( event, original ) { + + // Add which for key events + if ( event.which == null ) { + event.which = original.charCode != null ? original.charCode : original.keyCode; + } + + return event; + } + }, + + mouseHooks: { + props: "button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "), + filter: function( event, original ) { + var eventDoc, doc, body, + button = original.button, + fromElement = original.fromElement; + + // Calculate pageX/Y if missing and clientX/Y available + if ( event.pageX == null && original.clientX != null ) { + eventDoc = event.target.ownerDocument || document; + doc = eventDoc.documentElement; + body = eventDoc.body; + + event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 ); + event.pageY = original.clientY + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - ( doc && doc.clientTop || body && body.clientTop || 0 ); + } + + // Add relatedTarget, if necessary + if ( !event.relatedTarget && fromElement ) { + event.relatedTarget = fromElement === event.target ? original.toElement : fromElement; + } + + // Add which for click: 1 === left; 2 === middle; 3 === right + // Note: button is not normalized, so don't use it + if ( !event.which && button !== undefined ) { + event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) ); + } + + return event; + } + }, + + fix: function( event ) { + if ( event[ jQuery.expando ] ) { + return event; + } + + // Create a writable copy of the event object and normalize some properties + var i, prop, + originalEvent = event, + fixHook = jQuery.event.fixHooks[ event.type ] || {}, + copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props; + + event = jQuery.Event( originalEvent ); + + for ( i = copy.length; i; ) { + prop = copy[ --i ]; + event[ prop ] = originalEvent[ prop ]; + } + + // Fix target property, if necessary (#1925, IE 6/7/8 & Safari2) + if ( !event.target ) { + event.target = originalEvent.srcElement || document; + } + + // Target should not be a text node (#504, Safari) + if ( event.target.nodeType === 3 ) { + event.target = event.target.parentNode; + } + + // For mouse/key events; add metaKey if it's not there (#3368, IE6/7/8) + if ( event.metaKey === undefined ) { + event.metaKey = event.ctrlKey; + } + + return fixHook.filter? fixHook.filter( event, originalEvent ) : event; + }, + + special: { + ready: { + // Make sure the ready event is setup + setup: jQuery.bindReady + }, + + load: { + // Prevent triggered image.load events from bubbling to window.load + noBubble: true + }, + + focus: { + delegateType: "focusin" + }, + blur: { + delegateType: "focusout" + }, + + beforeunload: { + setup: function( data, namespaces, eventHandle ) { + // We only want to do this special case on windows + if ( jQuery.isWindow( this ) ) { + this.onbeforeunload = eventHandle; + } + }, + + teardown: function( namespaces, eventHandle ) { + if ( this.onbeforeunload === eventHandle ) { + this.onbeforeunload = null; + } + } + } + }, + + simulate: function( type, elem, event, bubble ) { + // Piggyback on a donor event to simulate a different one. + // Fake originalEvent to avoid donor's stopPropagation, but if the + // simulated event prevents default then we do the same on the donor. + var e = jQuery.extend( + new jQuery.Event(), + event, + { type: type, + isSimulated: true, + originalEvent: {} + } + ); + if ( bubble ) { + jQuery.event.trigger( e, null, elem ); + } else { + jQuery.event.dispatch.call( elem, e ); + } + if ( e.isDefaultPrevented() ) { + event.preventDefault(); + } + } +}; + +// Some plugins are using, but it's undocumented/deprecated and will be removed. +// The 1.7 special event interface should provide all the hooks needed now. +jQuery.event.handle = jQuery.event.dispatch; + +jQuery.removeEvent = document.removeEventListener ? + function( elem, type, handle ) { + if ( elem.removeEventListener ) { + elem.removeEventListener( type, handle, false ); + } + } : + function( elem, type, handle ) { + if ( elem.detachEvent ) { + elem.detachEvent( "on" + type, handle ); + } + }; + +jQuery.Event = function( src, props ) { + // Allow instantiation without the 'new' keyword + if ( !(this instanceof jQuery.Event) ) { + return new jQuery.Event( src, props ); + } + + // Event object + if ( src && src.type ) { + this.originalEvent = src; + this.type = src.type; + + // Events bubbling up the document may have been marked as prevented + // by a handler lower down the tree; reflect the correct value. + this.isDefaultPrevented = ( src.defaultPrevented || src.returnValue === false || + src.getPreventDefault && src.getPreventDefault() ) ? returnTrue : returnFalse; + + // Event type + } else { + this.type = src; + } + + // Put explicitly provided properties onto the event object + if ( props ) { + jQuery.extend( this, props ); + } + + // Create a timestamp if incoming event doesn't have one + this.timeStamp = src && src.timeStamp || jQuery.now(); + + // Mark it as fixed + this[ jQuery.expando ] = true; +}; + +function returnFalse() { + return false; +} +function returnTrue() { + return true; +} + +// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding +// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html +jQuery.Event.prototype = { + preventDefault: function() { + this.isDefaultPrevented = returnTrue; + + var e = this.originalEvent; + if ( !e ) { + return; + } + + // if preventDefault exists run it on the original event + if ( e.preventDefault ) { + e.preventDefault(); + + // otherwise set the returnValue property of the original event to false (IE) + } else { + e.returnValue = false; + } + }, + stopPropagation: function() { + this.isPropagationStopped = returnTrue; + + var e = this.originalEvent; + if ( !e ) { + return; + } + // if stopPropagation exists run it on the original event + if ( e.stopPropagation ) { + e.stopPropagation(); + } + // otherwise set the cancelBubble property of the original event to true (IE) + e.cancelBubble = true; + }, + stopImmediatePropagation: function() { + this.isImmediatePropagationStopped = returnTrue; + this.stopPropagation(); + }, + isDefaultPrevented: returnFalse, + isPropagationStopped: returnFalse, + isImmediatePropagationStopped: returnFalse +}; + +// Create mouseenter/leave events using mouseover/out and event-time checks +jQuery.each({ + mouseenter: "mouseover", + mouseleave: "mouseout" +}, function( orig, fix ) { + jQuery.event.special[ orig ] = { + delegateType: fix, + bindType: fix, + + handle: function( event ) { + var target = this, + related = event.relatedTarget, + handleObj = event.handleObj, + selector = handleObj.selector, + ret; + + // For mousenter/leave call the handler if related is outside the target. + // NB: No relatedTarget if the mouse left/entered the browser window + if ( !related || (related !== target && !jQuery.contains( target, related )) ) { + event.type = handleObj.origType; + ret = handleObj.handler.apply( this, arguments ); + event.type = fix; + } + return ret; + } + }; +}); + +// IE submit delegation +if ( !jQuery.support.submitBubbles ) { + + jQuery.event.special.submit = { + setup: function() { + // Only need this for delegated form submit events + if ( jQuery.nodeName( this, "form" ) ) { + return false; + } + + // Lazy-add a submit handler when a descendant form may potentially be submitted + jQuery.event.add( this, "click._submit keypress._submit", function( e ) { + // Node name check avoids a VML-related crash in IE (#9807) + var elem = e.target, + form = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ? elem.form : undefined; + if ( form && !form._submit_attached ) { + jQuery.event.add( form, "submit._submit", function( event ) { + event._submit_bubble = true; + }); + form._submit_attached = true; + } + }); + // return undefined since we don't need an event listener + }, + + postDispatch: function( event ) { + // If form was submitted by the user, bubble the event up the tree + if ( event._submit_bubble ) { + delete event._submit_bubble; + if ( this.parentNode && !event.isTrigger ) { + jQuery.event.simulate( "submit", this.parentNode, event, true ); + } + } + }, + + teardown: function() { + // Only need this for delegated form submit events + if ( jQuery.nodeName( this, "form" ) ) { + return false; + } + + // Remove delegated handlers; cleanData eventually reaps submit handlers attached above + jQuery.event.remove( this, "._submit" ); + } + }; +} + +// IE change delegation and checkbox/radio fix +if ( !jQuery.support.changeBubbles ) { + + jQuery.event.special.change = { + + setup: function() { + + if ( rformElems.test( this.nodeName ) ) { + // IE doesn't fire change on a check/radio until blur; trigger it on click + // after a propertychange. Eat the blur-change in special.change.handle. + // This still fires onchange a second time for check/radio after blur. + if ( this.type === "checkbox" || this.type === "radio" ) { + jQuery.event.add( this, "propertychange._change", function( event ) { + if ( event.originalEvent.propertyName === "checked" ) { + this._just_changed = true; + } + }); + jQuery.event.add( this, "click._change", function( event ) { + if ( this._just_changed && !event.isTrigger ) { + this._just_changed = false; + jQuery.event.simulate( "change", this, event, true ); + } + }); + } + return false; + } + // Delegated event; lazy-add a change handler on descendant inputs + jQuery.event.add( this, "beforeactivate._change", function( e ) { + var elem = e.target; + + if ( rformElems.test( elem.nodeName ) && !elem._change_attached ) { + jQuery.event.add( elem, "change._change", function( event ) { + if ( this.parentNode && !event.isSimulated && !event.isTrigger ) { + jQuery.event.simulate( "change", this.parentNode, event, true ); + } + }); + elem._change_attached = true; + } + }); + }, + + handle: function( event ) { + var elem = event.target; + + // Swallow native change events from checkbox/radio, we already triggered them above + if ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== "radio" && elem.type !== "checkbox") ) { + return event.handleObj.handler.apply( this, arguments ); + } + }, + + teardown: function() { + jQuery.event.remove( this, "._change" ); + + return rformElems.test( this.nodeName ); + } + }; +} + +// Create "bubbling" focus and blur events +if ( !jQuery.support.focusinBubbles ) { + jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) { + + // Attach a single capturing handler while someone wants focusin/focusout + var attaches = 0, + handler = function( event ) { + jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true ); + }; + + jQuery.event.special[ fix ] = { + setup: function() { + if ( attaches++ === 0 ) { + document.addEventListener( orig, handler, true ); + } + }, + teardown: function() { + if ( --attaches === 0 ) { + document.removeEventListener( orig, handler, true ); + } + } + }; + }); +} + +jQuery.fn.extend({ + + on: function( types, selector, data, fn, /*INTERNAL*/ one ) { + var origFn, type; + + // Types can be a map of types/handlers + if ( typeof types === "object" ) { + // ( types-Object, selector, data ) + if ( typeof selector !== "string" ) { // && selector != null + // ( types-Object, data ) + data = data || selector; + selector = undefined; + } + for ( type in types ) { + this.on( type, selector, data, types[ type ], one ); + } + return this; + } + + if ( data == null && fn == null ) { + // ( types, fn ) + fn = selector; + data = selector = undefined; + } else if ( fn == null ) { + if ( typeof selector === "string" ) { + // ( types, selector, fn ) + fn = data; + data = undefined; + } else { + // ( types, data, fn ) + fn = data; + data = selector; + selector = undefined; + } + } + if ( fn === false ) { + fn = returnFalse; + } else if ( !fn ) { + return this; + } + + if ( one === 1 ) { + origFn = fn; + fn = function( event ) { + // Can use an empty set, since event contains the info + jQuery().off( event ); + return origFn.apply( this, arguments ); + }; + // Use same guid so caller can remove using origFn + fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); + } + return this.each( function() { + jQuery.event.add( this, types, fn, data, selector ); + }); + }, + one: function( types, selector, data, fn ) { + return this.on( types, selector, data, fn, 1 ); + }, + off: function( types, selector, fn ) { + if ( types && types.preventDefault && types.handleObj ) { + // ( event ) dispatched jQuery.Event + var handleObj = types.handleObj; + jQuery( types.delegateTarget ).off( + handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType, + handleObj.selector, + handleObj.handler + ); + return this; + } + if ( typeof types === "object" ) { + // ( types-object [, selector] ) + for ( var type in types ) { + this.off( type, selector, types[ type ] ); + } + return this; + } + if ( selector === false || typeof selector === "function" ) { + // ( types [, fn] ) + fn = selector; + selector = undefined; + } + if ( fn === false ) { + fn = returnFalse; + } + return this.each(function() { + jQuery.event.remove( this, types, fn, selector ); + }); + }, + + bind: function( types, data, fn ) { + return this.on( types, null, data, fn ); + }, + unbind: function( types, fn ) { + return this.off( types, null, fn ); + }, + + live: function( types, data, fn ) { + jQuery( this.context ).on( types, this.selector, data, fn ); + return this; + }, + die: function( types, fn ) { + jQuery( this.context ).off( types, this.selector || "**", fn ); + return this; + }, + + delegate: function( selector, types, data, fn ) { + return this.on( types, selector, data, fn ); + }, + undelegate: function( selector, types, fn ) { + // ( namespace ) or ( selector, types [, fn] ) + return arguments.length == 1? this.off( selector, "**" ) : this.off( types, selector, fn ); + }, + + trigger: function( type, data ) { + return this.each(function() { + jQuery.event.trigger( type, data, this ); + }); + }, + triggerHandler: function( type, data ) { + if ( this[0] ) { + return jQuery.event.trigger( type, data, this[0], true ); + } + }, + + toggle: function( fn ) { + // Save reference to arguments for access in closure + var args = arguments, + guid = fn.guid || jQuery.guid++, + i = 0, + toggler = function( event ) { + // Figure out which function to execute + var lastToggle = ( jQuery._data( this, "lastToggle" + fn.guid ) || 0 ) % i; + jQuery._data( this, "lastToggle" + fn.guid, lastToggle + 1 ); + + // Make sure that clicks stop + event.preventDefault(); + + // and execute the function + return args[ lastToggle ].apply( this, arguments ) || false; + }; + + // link all the functions, so any of them can unbind this click handler + toggler.guid = guid; + while ( i < args.length ) { + args[ i++ ].guid = guid; + } + + return this.click( toggler ); + }, + + hover: function( fnOver, fnOut ) { + return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver ); + } +}); + +jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " + + "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " + + "change select submit keydown keypress keyup error contextmenu").split(" "), function( i, name ) { + + // Handle event binding + jQuery.fn[ name ] = function( data, fn ) { + if ( fn == null ) { + fn = data; + data = null; + } + + return arguments.length > 0 ? + this.on( name, null, data, fn ) : + this.trigger( name ); + }; + + if ( jQuery.attrFn ) { + jQuery.attrFn[ name ] = true; + } + + if ( rkeyEvent.test( name ) ) { + jQuery.event.fixHooks[ name ] = jQuery.event.keyHooks; + } + + if ( rmouseEvent.test( name ) ) { + jQuery.event.fixHooks[ name ] = jQuery.event.mouseHooks; + } +}); + + + +/*! + * Sizzle CSS Selector Engine + * Copyright 2011, The Dojo Foundation + * Released under the MIT, BSD, and GPL Licenses. + * More information: http://sizzlejs.com/ + */ +(function(){ + +var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g, + expando = "sizcache" + (Math.random() + '').replace('.', ''), + done = 0, + toString = Object.prototype.toString, + hasDuplicate = false, + baseHasDuplicate = true, + rBackslash = /\\/g, + rReturn = /\r\n/g, + rNonWord = /\W/; + +// Here we check if the JavaScript engine is using some sort of +// optimization where it does not always call our comparision +// function. If that is the case, discard the hasDuplicate value. +// Thus far that includes Google Chrome. +[0, 0].sort(function() { + baseHasDuplicate = false; + return 0; +}); + +var Sizzle = function( selector, context, results, seed ) { + results = results || []; + context = context || document; + + var origContext = context; + + if ( context.nodeType !== 1 && context.nodeType !== 9 ) { + return []; + } + + if ( !selector || typeof selector !== "string" ) { + return results; + } + + var m, set, checkSet, extra, ret, cur, pop, i, + prune = true, + contextXML = Sizzle.isXML( context ), + parts = [], + soFar = selector; + + // Reset the position of the chunker regexp (start from head) + do { + chunker.exec( "" ); + m = chunker.exec( soFar ); + + if ( m ) { + soFar = m[3]; + + parts.push( m[1] ); + + if ( m[2] ) { + extra = m[3]; + break; + } + } + } while ( m ); + + if ( parts.length > 1 && origPOS.exec( selector ) ) { + + if ( parts.length === 2 && Expr.relative[ parts[0] ] ) { + set = posProcess( parts[0] + parts[1], context, seed ); + + } else { + set = Expr.relative[ parts[0] ] ? + [ context ] : + Sizzle( parts.shift(), context ); + + while ( parts.length ) { + selector = parts.shift(); + + if ( Expr.relative[ selector ] ) { + selector += parts.shift(); + } + + set = posProcess( selector, set, seed ); + } + } + + } else { + // Take a shortcut and set the context if the root selector is an ID + // (but not if it'll be faster if the inner selector is an ID) + if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML && + Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) { + + ret = Sizzle.find( parts.shift(), context, contextXML ); + context = ret.expr ? + Sizzle.filter( ret.expr, ret.set )[0] : + ret.set[0]; + } + + if ( context ) { + ret = seed ? + { expr: parts.pop(), set: makeArray(seed) } : + Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML ); + + set = ret.expr ? + Sizzle.filter( ret.expr, ret.set ) : + ret.set; + + if ( parts.length > 0 ) { + checkSet = makeArray( set ); + + } else { + prune = false; + } + + while ( parts.length ) { + cur = parts.pop(); + pop = cur; + + if ( !Expr.relative[ cur ] ) { + cur = ""; + } else { + pop = parts.pop(); + } + + if ( pop == null ) { + pop = context; + } + + Expr.relative[ cur ]( checkSet, pop, contextXML ); + } + + } else { + checkSet = parts = []; + } + } + + if ( !checkSet ) { + checkSet = set; + } + + if ( !checkSet ) { + Sizzle.error( cur || selector ); + } + + if ( toString.call(checkSet) === "[object Array]" ) { + if ( !prune ) { + results.push.apply( results, checkSet ); + + } else if ( context && context.nodeType === 1 ) { + for ( i = 0; checkSet[i] != null; i++ ) { + if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && Sizzle.contains(context, checkSet[i])) ) { + results.push( set[i] ); + } + } + + } else { + for ( i = 0; checkSet[i] != null; i++ ) { + if ( checkSet[i] && checkSet[i].nodeType === 1 ) { + results.push( set[i] ); + } + } + } + + } else { + makeArray( checkSet, results ); + } + + if ( extra ) { + Sizzle( extra, origContext, results, seed ); + Sizzle.uniqueSort( results ); + } + + return results; +}; + +Sizzle.uniqueSort = function( results ) { + if ( sortOrder ) { + hasDuplicate = baseHasDuplicate; + results.sort( sortOrder ); + + if ( hasDuplicate ) { + for ( var i = 1; i < results.length; i++ ) { + if ( results[i] === results[ i - 1 ] ) { + results.splice( i--, 1 ); + } + } + } + } + + return results; +}; + +Sizzle.matches = function( expr, set ) { + return Sizzle( expr, null, null, set ); +}; + +Sizzle.matchesSelector = function( node, expr ) { + return Sizzle( expr, null, null, [node] ).length > 0; +}; + +Sizzle.find = function( expr, context, isXML ) { + var set, i, len, match, type, left; + + if ( !expr ) { + return []; + } + + for ( i = 0, len = Expr.order.length; i < len; i++ ) { + type = Expr.order[i]; + + if ( (match = Expr.leftMatch[ type ].exec( expr )) ) { + left = match[1]; + match.splice( 1, 1 ); + + if ( left.substr( left.length - 1 ) !== "\\" ) { + match[1] = (match[1] || "").replace( rBackslash, "" ); + set = Expr.find[ type ]( match, context, isXML ); + + if ( set != null ) { + expr = expr.replace( Expr.match[ type ], "" ); + break; + } + } + } + } + + if ( !set ) { + set = typeof context.getElementsByTagName !== "undefined" ? + context.getElementsByTagName( "*" ) : + []; + } + + return { set: set, expr: expr }; +}; + +Sizzle.filter = function( expr, set, inplace, not ) { + var match, anyFound, + type, found, item, filter, left, + i, pass, + old = expr, + result = [], + curLoop = set, + isXMLFilter = set && set[0] && Sizzle.isXML( set[0] ); + + while ( expr && set.length ) { + for ( type in Expr.filter ) { + if ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) { + filter = Expr.filter[ type ]; + left = match[1]; + + anyFound = false; + + match.splice(1,1); + + if ( left.substr( left.length - 1 ) === "\\" ) { + continue; + } + + if ( curLoop === result ) { + result = []; + } + + if ( Expr.preFilter[ type ] ) { + match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter ); + + if ( !match ) { + anyFound = found = true; + + } else if ( match === true ) { + continue; + } + } + + if ( match ) { + for ( i = 0; (item = curLoop[i]) != null; i++ ) { + if ( item ) { + found = filter( item, match, i, curLoop ); + pass = not ^ found; + + if ( inplace && found != null ) { + if ( pass ) { + anyFound = true; + + } else { + curLoop[i] = false; + } + + } else if ( pass ) { + result.push( item ); + anyFound = true; + } + } + } + } + + if ( found !== undefined ) { + if ( !inplace ) { + curLoop = result; + } + + expr = expr.replace( Expr.match[ type ], "" ); + + if ( !anyFound ) { + return []; + } + + break; + } + } + } + + // Improper expression + if ( expr === old ) { + if ( anyFound == null ) { + Sizzle.error( expr ); + + } else { + break; + } + } + + old = expr; + } + + return curLoop; +}; + +Sizzle.error = function( msg ) { + throw new Error( "Syntax error, unrecognized expression: " + msg ); +}; + +/** + * Utility function for retreiving the text value of an array of DOM nodes + * @param {Array|Element} elem + */ +var getText = Sizzle.getText = function( elem ) { + var i, node, + nodeType = elem.nodeType, + ret = ""; + + if ( nodeType ) { + if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { + // Use textContent || innerText for elements + if ( typeof elem.textContent === 'string' ) { + return elem.textContent; + } else if ( typeof elem.innerText === 'string' ) { + // Replace IE's carriage returns + return elem.innerText.replace( rReturn, '' ); + } else { + // Traverse it's children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling) { + ret += getText( elem ); + } + } + } else if ( nodeType === 3 || nodeType === 4 ) { + return elem.nodeValue; + } + } else { + + // If no nodeType, this is expected to be an array + for ( i = 0; (node = elem[i]); i++ ) { + // Do not traverse comment nodes + if ( node.nodeType !== 8 ) { + ret += getText( node ); + } + } + } + return ret; +}; + +var Expr = Sizzle.selectors = { + order: [ "ID", "NAME", "TAG" ], + + match: { + ID: /#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/, + CLASS: /\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/, + NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/, + ATTR: /\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/, + TAG: /^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/, + CHILD: /:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/, + POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/, + PSEUDO: /:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/ + }, + + leftMatch: {}, + + attrMap: { + "class": "className", + "for": "htmlFor" + }, + + attrHandle: { + href: function( elem ) { + return elem.getAttribute( "href" ); + }, + type: function( elem ) { + return elem.getAttribute( "type" ); + } + }, + + relative: { + "+": function(checkSet, part){ + var isPartStr = typeof part === "string", + isTag = isPartStr && !rNonWord.test( part ), + isPartStrNotTag = isPartStr && !isTag; + + if ( isTag ) { + part = part.toLowerCase(); + } + + for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) { + if ( (elem = checkSet[i]) ) { + while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {} + + checkSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ? + elem || false : + elem === part; + } + } + + if ( isPartStrNotTag ) { + Sizzle.filter( part, checkSet, true ); + } + }, + + ">": function( checkSet, part ) { + var elem, + isPartStr = typeof part === "string", + i = 0, + l = checkSet.length; + + if ( isPartStr && !rNonWord.test( part ) ) { + part = part.toLowerCase(); + + for ( ; i < l; i++ ) { + elem = checkSet[i]; + + if ( elem ) { + var parent = elem.parentNode; + checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false; + } + } + + } else { + for ( ; i < l; i++ ) { + elem = checkSet[i]; + + if ( elem ) { + checkSet[i] = isPartStr ? + elem.parentNode : + elem.parentNode === part; + } + } + + if ( isPartStr ) { + Sizzle.filter( part, checkSet, true ); + } + } + }, + + "": function(checkSet, part, isXML){ + var nodeCheck, + doneName = done++, + checkFn = dirCheck; + + if ( typeof part === "string" && !rNonWord.test( part ) ) { + part = part.toLowerCase(); + nodeCheck = part; + checkFn = dirNodeCheck; + } + + checkFn( "parentNode", part, doneName, checkSet, nodeCheck, isXML ); + }, + + "~": function( checkSet, part, isXML ) { + var nodeCheck, + doneName = done++, + checkFn = dirCheck; + + if ( typeof part === "string" && !rNonWord.test( part ) ) { + part = part.toLowerCase(); + nodeCheck = part; + checkFn = dirNodeCheck; + } + + checkFn( "previousSibling", part, doneName, checkSet, nodeCheck, isXML ); + } + }, + + find: { + ID: function( match, context, isXML ) { + if ( typeof context.getElementById !== "undefined" && !isXML ) { + var m = context.getElementById(match[1]); + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + return m && m.parentNode ? [m] : []; + } + }, + + NAME: function( match, context ) { + if ( typeof context.getElementsByName !== "undefined" ) { + var ret = [], + results = context.getElementsByName( match[1] ); + + for ( var i = 0, l = results.length; i < l; i++ ) { + if ( results[i].getAttribute("name") === match[1] ) { + ret.push( results[i] ); + } + } + + return ret.length === 0 ? null : ret; + } + }, + + TAG: function( match, context ) { + if ( typeof context.getElementsByTagName !== "undefined" ) { + return context.getElementsByTagName( match[1] ); + } + } + }, + preFilter: { + CLASS: function( match, curLoop, inplace, result, not, isXML ) { + match = " " + match[1].replace( rBackslash, "" ) + " "; + + if ( isXML ) { + return match; + } + + for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) { + if ( elem ) { + if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n\r]/g, " ").indexOf(match) >= 0) ) { + if ( !inplace ) { + result.push( elem ); + } + + } else if ( inplace ) { + curLoop[i] = false; + } + } + } + + return false; + }, + + ID: function( match ) { + return match[1].replace( rBackslash, "" ); + }, + + TAG: function( match, curLoop ) { + return match[1].replace( rBackslash, "" ).toLowerCase(); + }, + + CHILD: function( match ) { + if ( match[1] === "nth" ) { + if ( !match[2] ) { + Sizzle.error( match[0] ); + } + + match[2] = match[2].replace(/^\+|\s*/g, ''); + + // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6' + var test = /(-?)(\d*)(?:n([+\-]?\d*))?/.exec( + match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" || + !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]); + + // calculate the numbers (first)n+(last) including if they are negative + match[2] = (test[1] + (test[2] || 1)) - 0; + match[3] = test[3] - 0; + } + else if ( match[2] ) { + Sizzle.error( match[0] ); + } + + // TODO: Move to normal caching system + match[0] = done++; + + return match; + }, + + ATTR: function( match, curLoop, inplace, result, not, isXML ) { + var name = match[1] = match[1].replace( rBackslash, "" ); + + if ( !isXML && Expr.attrMap[name] ) { + match[1] = Expr.attrMap[name]; + } + + // Handle if an un-quoted value was used + match[4] = ( match[4] || match[5] || "" ).replace( rBackslash, "" ); + + if ( match[2] === "~=" ) { + match[4] = " " + match[4] + " "; + } + + return match; + }, + + PSEUDO: function( match, curLoop, inplace, result, not ) { + if ( match[1] === "not" ) { + // If we're dealing with a complex expression, or a simple one + if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) { + match[3] = Sizzle(match[3], null, null, curLoop); + + } else { + var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not); + + if ( !inplace ) { + result.push.apply( result, ret ); + } + + return false; + } + + } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) { + return true; + } + + return match; + }, + + POS: function( match ) { + match.unshift( true ); + + return match; + } + }, + + filters: { + enabled: function( elem ) { + return elem.disabled === false && elem.type !== "hidden"; + }, + + disabled: function( elem ) { + return elem.disabled === true; + }, + + checked: function( elem ) { + return elem.checked === true; + }, + + selected: function( elem ) { + // Accessing this property makes selected-by-default + // options in Safari work properly + if ( elem.parentNode ) { + elem.parentNode.selectedIndex; + } + + return elem.selected === true; + }, + + parent: function( elem ) { + return !!elem.firstChild; + }, + + empty: function( elem ) { + return !elem.firstChild; + }, + + has: function( elem, i, match ) { + return !!Sizzle( match[3], elem ).length; + }, + + header: function( elem ) { + return (/h\d/i).test( elem.nodeName ); + }, + + text: function( elem ) { + var attr = elem.getAttribute( "type" ), type = elem.type; + // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc) + // use getAttribute instead to test this case + return elem.nodeName.toLowerCase() === "input" && "text" === type && ( attr === type || attr === null ); + }, + + radio: function( elem ) { + return elem.nodeName.toLowerCase() === "input" && "radio" === elem.type; + }, + + checkbox: function( elem ) { + return elem.nodeName.toLowerCase() === "input" && "checkbox" === elem.type; + }, + + file: function( elem ) { + return elem.nodeName.toLowerCase() === "input" && "file" === elem.type; + }, + + password: function( elem ) { + return elem.nodeName.toLowerCase() === "input" && "password" === elem.type; + }, + + submit: function( elem ) { + var name = elem.nodeName.toLowerCase(); + return (name === "input" || name === "button") && "submit" === elem.type; + }, + + image: function( elem ) { + return elem.nodeName.toLowerCase() === "input" && "image" === elem.type; + }, + + reset: function( elem ) { + var name = elem.nodeName.toLowerCase(); + return (name === "input" || name === "button") && "reset" === elem.type; + }, + + button: function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && "button" === elem.type || name === "button"; + }, + + input: function( elem ) { + return (/input|select|textarea|button/i).test( elem.nodeName ); + }, + + focus: function( elem ) { + return elem === elem.ownerDocument.activeElement; + } + }, + setFilters: { + first: function( elem, i ) { + return i === 0; + }, + + last: function( elem, i, match, array ) { + return i === array.length - 1; + }, + + even: function( elem, i ) { + return i % 2 === 0; + }, + + odd: function( elem, i ) { + return i % 2 === 1; + }, + + lt: function( elem, i, match ) { + return i < match[3] - 0; + }, + + gt: function( elem, i, match ) { + return i > match[3] - 0; + }, + + nth: function( elem, i, match ) { + return match[3] - 0 === i; + }, + + eq: function( elem, i, match ) { + return match[3] - 0 === i; + } + }, + filter: { + PSEUDO: function( elem, match, i, array ) { + var name = match[1], + filter = Expr.filters[ name ]; + + if ( filter ) { + return filter( elem, i, match, array ); + + } else if ( name === "contains" ) { + return (elem.textContent || elem.innerText || getText([ elem ]) || "").indexOf(match[3]) >= 0; + + } else if ( name === "not" ) { + var not = match[3]; + + for ( var j = 0, l = not.length; j < l; j++ ) { + if ( not[j] === elem ) { + return false; + } + } + + return true; + + } else { + Sizzle.error( name ); + } + }, + + CHILD: function( elem, match ) { + var first, last, + doneName, parent, cache, + count, diff, + type = match[1], + node = elem; + + switch ( type ) { + case "only": + case "first": + while ( (node = node.previousSibling) ) { + if ( node.nodeType === 1 ) { + return false; + } + } + + if ( type === "first" ) { + return true; + } + + node = elem; + + /* falls through */ + case "last": + while ( (node = node.nextSibling) ) { + if ( node.nodeType === 1 ) { + return false; + } + } + + return true; + + case "nth": + first = match[2]; + last = match[3]; + + if ( first === 1 && last === 0 ) { + return true; + } + + doneName = match[0]; + parent = elem.parentNode; + + if ( parent && (parent[ expando ] !== doneName || !elem.nodeIndex) ) { + count = 0; + + for ( node = parent.firstChild; node; node = node.nextSibling ) { + if ( node.nodeType === 1 ) { + node.nodeIndex = ++count; + } + } + + parent[ expando ] = doneName; + } + + diff = elem.nodeIndex - last; + + if ( first === 0 ) { + return diff === 0; + + } else { + return ( diff % first === 0 && diff / first >= 0 ); + } + } + }, + + ID: function( elem, match ) { + return elem.nodeType === 1 && elem.getAttribute("id") === match; + }, + + TAG: function( elem, match ) { + return (match === "*" && elem.nodeType === 1) || !!elem.nodeName && elem.nodeName.toLowerCase() === match; + }, + + CLASS: function( elem, match ) { + return (" " + (elem.className || elem.getAttribute("class")) + " ") + .indexOf( match ) > -1; + }, + + ATTR: function( elem, match ) { + var name = match[1], + result = Sizzle.attr ? + Sizzle.attr( elem, name ) : + Expr.attrHandle[ name ] ? + Expr.attrHandle[ name ]( elem ) : + elem[ name ] != null ? + elem[ name ] : + elem.getAttribute( name ), + value = result + "", + type = match[2], + check = match[4]; + + return result == null ? + type === "!=" : + !type && Sizzle.attr ? + result != null : + type === "=" ? + value === check : + type === "*=" ? + value.indexOf(check) >= 0 : + type === "~=" ? + (" " + value + " ").indexOf(check) >= 0 : + !check ? + value && result !== false : + type === "!=" ? + value !== check : + type === "^=" ? + value.indexOf(check) === 0 : + type === "$=" ? + value.substr(value.length - check.length) === check : + type === "|=" ? + value === check || value.substr(0, check.length + 1) === check + "-" : + false; + }, + + POS: function( elem, match, i, array ) { + var name = match[2], + filter = Expr.setFilters[ name ]; + + if ( filter ) { + return filter( elem, i, match, array ); + } + } + } +}; + +var origPOS = Expr.match.POS, + fescape = function(all, num){ + return "\\" + (num - 0 + 1); + }; + +for ( var type in Expr.match ) { + Expr.match[ type ] = new RegExp( Expr.match[ type ].source + (/(?![^\[]*\])(?![^\(]*\))/.source) ); + Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source.replace(/\\(\d+)/g, fescape) ); +} +// Expose origPOS +// "global" as in regardless of relation to brackets/parens +Expr.match.globalPOS = origPOS; + +var makeArray = function( array, results ) { + array = Array.prototype.slice.call( array, 0 ); + + if ( results ) { + results.push.apply( results, array ); + return results; + } + + return array; +}; + +// Perform a simple check to determine if the browser is capable of +// converting a NodeList to an array using builtin methods. +// Also verifies that the returned array holds DOM nodes +// (which is not the case in the Blackberry browser) +try { + Array.prototype.slice.call( document.documentElement.childNodes, 0 )[0].nodeType; + +// Provide a fallback method if it does not work +} catch( e ) { + makeArray = function( array, results ) { + var i = 0, + ret = results || []; + + if ( toString.call(array) === "[object Array]" ) { + Array.prototype.push.apply( ret, array ); + + } else { + if ( typeof array.length === "number" ) { + for ( var l = array.length; i < l; i++ ) { + ret.push( array[i] ); + } + + } else { + for ( ; array[i]; i++ ) { + ret.push( array[i] ); + } + } + } + + return ret; + }; +} + +var sortOrder, siblingCheck; + +if ( document.documentElement.compareDocumentPosition ) { + sortOrder = function( a, b ) { + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) { + return a.compareDocumentPosition ? -1 : 1; + } + + return a.compareDocumentPosition(b) & 4 ? -1 : 1; + }; + +} else { + sortOrder = function( a, b ) { + // The nodes are identical, we can exit early + if ( a === b ) { + hasDuplicate = true; + return 0; + + // Fallback to using sourceIndex (in IE) if it's available on both nodes + } else if ( a.sourceIndex && b.sourceIndex ) { + return a.sourceIndex - b.sourceIndex; + } + + var al, bl, + ap = [], + bp = [], + aup = a.parentNode, + bup = b.parentNode, + cur = aup; + + // If the nodes are siblings (or identical) we can do a quick check + if ( aup === bup ) { + return siblingCheck( a, b ); + + // If no parents were found then the nodes are disconnected + } else if ( !aup ) { + return -1; + + } else if ( !bup ) { + return 1; + } + + // Otherwise they're somewhere else in the tree so we need + // to build up a full list of the parentNodes for comparison + while ( cur ) { + ap.unshift( cur ); + cur = cur.parentNode; + } + + cur = bup; + + while ( cur ) { + bp.unshift( cur ); + cur = cur.parentNode; + } + + al = ap.length; + bl = bp.length; + + // Start walking down the tree looking for a discrepancy + for ( var i = 0; i < al && i < bl; i++ ) { + if ( ap[i] !== bp[i] ) { + return siblingCheck( ap[i], bp[i] ); + } + } + + // We ended someplace up the tree so do a sibling check + return i === al ? + siblingCheck( a, bp[i], -1 ) : + siblingCheck( ap[i], b, 1 ); + }; + + siblingCheck = function( a, b, ret ) { + if ( a === b ) { + return ret; + } + + var cur = a.nextSibling; + + while ( cur ) { + if ( cur === b ) { + return -1; + } + + cur = cur.nextSibling; + } + + return 1; + }; +} + +// Check to see if the browser returns elements by name when +// querying by getElementById (and provide a workaround) +(function(){ + // We're going to inject a fake input element with a specified name + var form = document.createElement("div"), + id = "script" + (new Date()).getTime(), + root = document.documentElement; + + form.innerHTML = ""; + + // Inject it into the root element, check its status, and remove it quickly + root.insertBefore( form, root.firstChild ); + + // The workaround has to do additional checks after a getElementById + // Which slows things down for other browsers (hence the branching) + if ( document.getElementById( id ) ) { + Expr.find.ID = function( match, context, isXML ) { + if ( typeof context.getElementById !== "undefined" && !isXML ) { + var m = context.getElementById(match[1]); + + return m ? + m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ? + [m] : + undefined : + []; + } + }; + + Expr.filter.ID = function( elem, match ) { + var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id"); + + return elem.nodeType === 1 && node && node.nodeValue === match; + }; + } + + root.removeChild( form ); + + // release memory in IE + root = form = null; +})(); + +(function(){ + // Check to see if the browser returns only elements + // when doing getElementsByTagName("*") + + // Create a fake element + var div = document.createElement("div"); + div.appendChild( document.createComment("") ); + + // Make sure no comments are found + if ( div.getElementsByTagName("*").length > 0 ) { + Expr.find.TAG = function( match, context ) { + var results = context.getElementsByTagName( match[1] ); + + // Filter out possible comments + if ( match[1] === "*" ) { + var tmp = []; + + for ( var i = 0; results[i]; i++ ) { + if ( results[i].nodeType === 1 ) { + tmp.push( results[i] ); + } + } + + results = tmp; + } + + return results; + }; + } + + // Check to see if an attribute returns normalized href attributes + div.innerHTML = ""; + + if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" && + div.firstChild.getAttribute("href") !== "#" ) { + + Expr.attrHandle.href = function( elem ) { + return elem.getAttribute( "href", 2 ); + }; + } + + // release memory in IE + div = null; +})(); + +if ( document.querySelectorAll ) { + (function(){ + var oldSizzle = Sizzle, + div = document.createElement("div"), + id = "__sizzle__"; + + div.innerHTML = "

    "; + + // Safari can't handle uppercase or unicode characters when + // in quirks mode. + if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) { + return; + } + + Sizzle = function( query, context, extra, seed ) { + context = context || document; + + // Only use querySelectorAll on non-XML documents + // (ID selectors don't work in non-HTML documents) + if ( !seed && !Sizzle.isXML(context) ) { + // See if we find a selector to speed up + var match = /^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec( query ); + + if ( match && (context.nodeType === 1 || context.nodeType === 9) ) { + // Speed-up: Sizzle("TAG") + if ( match[1] ) { + return makeArray( context.getElementsByTagName( query ), extra ); + + // Speed-up: Sizzle(".CLASS") + } else if ( match[2] && Expr.find.CLASS && context.getElementsByClassName ) { + return makeArray( context.getElementsByClassName( match[2] ), extra ); + } + } + + if ( context.nodeType === 9 ) { + // Speed-up: Sizzle("body") + // The body element only exists once, optimize finding it + if ( query === "body" && context.body ) { + return makeArray( [ context.body ], extra ); + + // Speed-up: Sizzle("#ID") + } else if ( match && match[3] ) { + var elem = context.getElementById( match[3] ); + + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + if ( elem && elem.parentNode ) { + // Handle the case where IE and Opera return items + // by name instead of ID + if ( elem.id === match[3] ) { + return makeArray( [ elem ], extra ); + } + + } else { + return makeArray( [], extra ); + } + } + + try { + return makeArray( context.querySelectorAll(query), extra ); + } catch(qsaError) {} + + // qSA works strangely on Element-rooted queries + // We can work around this by specifying an extra ID on the root + // and working up from there (Thanks to Andrew Dupont for the technique) + // IE 8 doesn't work on object elements + } else if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) { + var oldContext = context, + old = context.getAttribute( "id" ), + nid = old || id, + hasParent = context.parentNode, + relativeHierarchySelector = /^\s*[+~]/.test( query ); + + if ( !old ) { + context.setAttribute( "id", nid ); + } else { + nid = nid.replace( /'/g, "\\$&" ); + } + if ( relativeHierarchySelector && hasParent ) { + context = context.parentNode; + } + + try { + if ( !relativeHierarchySelector || hasParent ) { + return makeArray( context.querySelectorAll( "[id='" + nid + "'] " + query ), extra ); + } + + } catch(pseudoError) { + } finally { + if ( !old ) { + oldContext.removeAttribute( "id" ); + } + } + } + } + + return oldSizzle(query, context, extra, seed); + }; + + for ( var prop in oldSizzle ) { + Sizzle[ prop ] = oldSizzle[ prop ]; + } + + // release memory in IE + div = null; + })(); +} + +(function(){ + var html = document.documentElement, + matches = html.matchesSelector || html.mozMatchesSelector || html.webkitMatchesSelector || html.msMatchesSelector; + + if ( matches ) { + // Check to see if it's possible to do matchesSelector + // on a disconnected node (IE 9 fails this) + var disconnectedMatch = !matches.call( document.createElement( "div" ), "div" ), + pseudoWorks = false; + + try { + // This should fail with an exception + // Gecko does not error, returns false instead + matches.call( document.documentElement, "[test!='']:sizzle" ); + + } catch( pseudoError ) { + pseudoWorks = true; + } + + Sizzle.matchesSelector = function( node, expr ) { + // Make sure that attribute selectors are quoted + expr = expr.replace(/\=\s*([^'"\]]*)\s*\]/g, "='$1']"); + + if ( !Sizzle.isXML( node ) ) { + try { + if ( pseudoWorks || !Expr.match.PSEUDO.test( expr ) && !/!=/.test( expr ) ) { + var ret = matches.call( node, expr ); + + // IE 9's matchesSelector returns false on disconnected nodes + if ( ret || !disconnectedMatch || + // As well, disconnected nodes are said to be in a document + // fragment in IE 9, so check for that + node.document && node.document.nodeType !== 11 ) { + return ret; + } + } + } catch(e) {} + } + + return Sizzle(expr, null, null, [node]).length > 0; + }; + } +})(); + +(function(){ + var div = document.createElement("div"); + + div.innerHTML = "
    "; + + // Opera can't find a second classname (in 9.6) + // Also, make sure that getElementsByClassName actually exists + if ( !div.getElementsByClassName || div.getElementsByClassName("e").length === 0 ) { + return; + } + + // Safari caches class attributes, doesn't catch changes (in 3.2) + div.lastChild.className = "e"; + + if ( div.getElementsByClassName("e").length === 1 ) { + return; + } + + Expr.order.splice(1, 0, "CLASS"); + Expr.find.CLASS = function( match, context, isXML ) { + if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) { + return context.getElementsByClassName(match[1]); + } + }; + + // release memory in IE + div = null; +})(); + +function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { + for ( var i = 0, l = checkSet.length; i < l; i++ ) { + var elem = checkSet[i]; + + if ( elem ) { + var match = false; + + elem = elem[dir]; + + while ( elem ) { + if ( elem[ expando ] === doneName ) { + match = checkSet[elem.sizset]; + break; + } + + if ( elem.nodeType === 1 && !isXML ){ + elem[ expando ] = doneName; + elem.sizset = i; + } + + if ( elem.nodeName.toLowerCase() === cur ) { + match = elem; + break; + } + + elem = elem[dir]; + } + + checkSet[i] = match; + } + } +} + +function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { + for ( var i = 0, l = checkSet.length; i < l; i++ ) { + var elem = checkSet[i]; + + if ( elem ) { + var match = false; + + elem = elem[dir]; + + while ( elem ) { + if ( elem[ expando ] === doneName ) { + match = checkSet[elem.sizset]; + break; + } + + if ( elem.nodeType === 1 ) { + if ( !isXML ) { + elem[ expando ] = doneName; + elem.sizset = i; + } + + if ( typeof cur !== "string" ) { + if ( elem === cur ) { + match = true; + break; + } + + } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) { + match = elem; + break; + } + } + + elem = elem[dir]; + } + + checkSet[i] = match; + } + } +} + +if ( document.documentElement.contains ) { + Sizzle.contains = function( a, b ) { + return a !== b && (a.contains ? a.contains(b) : true); + }; + +} else if ( document.documentElement.compareDocumentPosition ) { + Sizzle.contains = function( a, b ) { + return !!(a.compareDocumentPosition(b) & 16); + }; + +} else { + Sizzle.contains = function() { + return false; + }; +} + +Sizzle.isXML = function( elem ) { + // documentElement is verified for cases where it doesn't yet exist + // (such as loading iframes in IE - #4833) + var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement; + + return documentElement ? documentElement.nodeName !== "HTML" : false; +}; + +var posProcess = function( selector, context, seed ) { + var match, + tmpSet = [], + later = "", + root = context.nodeType ? [context] : context; + + // Position selectors must be done after the filter + // And so must :not(positional) so we move all PSEUDOs to the end + while ( (match = Expr.match.PSEUDO.exec( selector )) ) { + later += match[0]; + selector = selector.replace( Expr.match.PSEUDO, "" ); + } + + selector = Expr.relative[selector] ? selector + "*" : selector; + + for ( var i = 0, l = root.length; i < l; i++ ) { + Sizzle( selector, root[i], tmpSet, seed ); + } + + return Sizzle.filter( later, tmpSet ); +}; + +// EXPOSE +// Override sizzle attribute retrieval +Sizzle.attr = jQuery.attr; +Sizzle.selectors.attrMap = {}; +jQuery.find = Sizzle; +jQuery.expr = Sizzle.selectors; +jQuery.expr[":"] = jQuery.expr.filters; +jQuery.unique = Sizzle.uniqueSort; +jQuery.text = Sizzle.getText; +jQuery.isXMLDoc = Sizzle.isXML; +jQuery.contains = Sizzle.contains; + + +})(); + + +var runtil = /Until$/, + rparentsprev = /^(?:parents|prevUntil|prevAll)/, + // Note: This RegExp should be improved, or likely pulled from Sizzle + rmultiselector = /,/, + isSimple = /^.[^:#\[\.,]*$/, + slice = Array.prototype.slice, + POS = jQuery.expr.match.globalPOS, + // methods guaranteed to produce a unique set when starting from a unique set + guaranteedUnique = { + children: true, + contents: true, + next: true, + prev: true + }; + +jQuery.fn.extend({ + find: function( selector ) { + var self = this, + i, l; + + if ( typeof selector !== "string" ) { + return jQuery( selector ).filter(function() { + for ( i = 0, l = self.length; i < l; i++ ) { + if ( jQuery.contains( self[ i ], this ) ) { + return true; + } + } + }); + } + + var ret = this.pushStack( "", "find", selector ), + length, n, r; + + for ( i = 0, l = this.length; i < l; i++ ) { + length = ret.length; + jQuery.find( selector, this[i], ret ); + + if ( i > 0 ) { + // Make sure that the results are unique + for ( n = length; n < ret.length; n++ ) { + for ( r = 0; r < length; r++ ) { + if ( ret[r] === ret[n] ) { + ret.splice(n--, 1); + break; + } + } + } + } + } + + return ret; + }, + + has: function( target ) { + var targets = jQuery( target ); + return this.filter(function() { + for ( var i = 0, l = targets.length; i < l; i++ ) { + if ( jQuery.contains( this, targets[i] ) ) { + return true; + } + } + }); + }, + + not: function( selector ) { + return this.pushStack( winnow(this, selector, false), "not", selector); + }, + + filter: function( selector ) { + return this.pushStack( winnow(this, selector, true), "filter", selector ); + }, + + is: function( selector ) { + return !!selector && ( + typeof selector === "string" ? + // If this is a positional selector, check membership in the returned set + // so $("p:first").is("p:last") won't return true for a doc with two "p". + POS.test( selector ) ? + jQuery( selector, this.context ).index( this[0] ) >= 0 : + jQuery.filter( selector, this ).length > 0 : + this.filter( selector ).length > 0 ); + }, + + closest: function( selectors, context ) { + var ret = [], i, l, cur = this[0]; + + // Array (deprecated as of jQuery 1.7) + if ( jQuery.isArray( selectors ) ) { + var level = 1; + + while ( cur && cur.ownerDocument && cur !== context ) { + for ( i = 0; i < selectors.length; i++ ) { + + if ( jQuery( cur ).is( selectors[ i ] ) ) { + ret.push({ selector: selectors[ i ], elem: cur, level: level }); + } + } + + cur = cur.parentNode; + level++; + } + + return ret; + } + + // String + var pos = POS.test( selectors ) || typeof selectors !== "string" ? + jQuery( selectors, context || this.context ) : + 0; + + for ( i = 0, l = this.length; i < l; i++ ) { + cur = this[i]; + + while ( cur ) { + if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) { + ret.push( cur ); + break; + + } else { + cur = cur.parentNode; + if ( !cur || !cur.ownerDocument || cur === context || cur.nodeType === 11 ) { + break; + } + } + } + } + + ret = ret.length > 1 ? jQuery.unique( ret ) : ret; + + return this.pushStack( ret, "closest", selectors ); + }, + + // Determine the position of an element within + // the matched set of elements + index: function( elem ) { + + // No argument, return index in parent + if ( !elem ) { + return ( this[0] && this[0].parentNode ) ? this.prevAll().length : -1; + } + + // index in selector + if ( typeof elem === "string" ) { + return jQuery.inArray( this[0], jQuery( elem ) ); + } + + // Locate the position of the desired element + return jQuery.inArray( + // If it receives a jQuery object, the first element is used + elem.jquery ? elem[0] : elem, this ); + }, + + add: function( selector, context ) { + var set = typeof selector === "string" ? + jQuery( selector, context ) : + jQuery.makeArray( selector && selector.nodeType ? [ selector ] : selector ), + all = jQuery.merge( this.get(), set ); + + return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ? + all : + jQuery.unique( all ) ); + }, + + andSelf: function() { + return this.add( this.prevObject ); + } +}); + +// A painfully simple check to see if an element is disconnected +// from a document (should be improved, where feasible). +function isDisconnected( node ) { + return !node || !node.parentNode || node.parentNode.nodeType === 11; +} + +jQuery.each({ + parent: function( elem ) { + var parent = elem.parentNode; + return parent && parent.nodeType !== 11 ? parent : null; + }, + parents: function( elem ) { + return jQuery.dir( elem, "parentNode" ); + }, + parentsUntil: function( elem, i, until ) { + return jQuery.dir( elem, "parentNode", until ); + }, + next: function( elem ) { + return jQuery.nth( elem, 2, "nextSibling" ); + }, + prev: function( elem ) { + return jQuery.nth( elem, 2, "previousSibling" ); + }, + nextAll: function( elem ) { + return jQuery.dir( elem, "nextSibling" ); + }, + prevAll: function( elem ) { + return jQuery.dir( elem, "previousSibling" ); + }, + nextUntil: function( elem, i, until ) { + return jQuery.dir( elem, "nextSibling", until ); + }, + prevUntil: function( elem, i, until ) { + return jQuery.dir( elem, "previousSibling", until ); + }, + siblings: function( elem ) { + return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem ); + }, + children: function( elem ) { + return jQuery.sibling( elem.firstChild ); + }, + contents: function( elem ) { + return jQuery.nodeName( elem, "iframe" ) ? + elem.contentDocument || elem.contentWindow.document : + jQuery.makeArray( elem.childNodes ); + } +}, function( name, fn ) { + jQuery.fn[ name ] = function( until, selector ) { + var ret = jQuery.map( this, fn, until ); + + if ( !runtil.test( name ) ) { + selector = until; + } + + if ( selector && typeof selector === "string" ) { + ret = jQuery.filter( selector, ret ); + } + + ret = this.length > 1 && !guaranteedUnique[ name ] ? jQuery.unique( ret ) : ret; + + if ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( name ) ) { + ret = ret.reverse(); + } + + return this.pushStack( ret, name, slice.call( arguments ).join(",") ); + }; +}); + +jQuery.extend({ + filter: function( expr, elems, not ) { + if ( not ) { + expr = ":not(" + expr + ")"; + } + + return elems.length === 1 ? + jQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] : + jQuery.find.matches(expr, elems); + }, + + dir: function( elem, dir, until ) { + var matched = [], + cur = elem[ dir ]; + + while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) { + if ( cur.nodeType === 1 ) { + matched.push( cur ); + } + cur = cur[dir]; + } + return matched; + }, + + nth: function( cur, result, dir, elem ) { + result = result || 1; + var num = 0; + + for ( ; cur; cur = cur[dir] ) { + if ( cur.nodeType === 1 && ++num === result ) { + break; + } + } + + return cur; + }, + + sibling: function( n, elem ) { + var r = []; + + for ( ; n; n = n.nextSibling ) { + if ( n.nodeType === 1 && n !== elem ) { + r.push( n ); + } + } + + return r; + } +}); + +// Implement the identical functionality for filter and not +function winnow( elements, qualifier, keep ) { + + // Can't pass null or undefined to indexOf in Firefox 4 + // Set to 0 to skip string check + qualifier = qualifier || 0; + + if ( jQuery.isFunction( qualifier ) ) { + return jQuery.grep(elements, function( elem, i ) { + var retVal = !!qualifier.call( elem, i, elem ); + return retVal === keep; + }); + + } else if ( qualifier.nodeType ) { + return jQuery.grep(elements, function( elem, i ) { + return ( elem === qualifier ) === keep; + }); + + } else if ( typeof qualifier === "string" ) { + var filtered = jQuery.grep(elements, function( elem ) { + return elem.nodeType === 1; + }); + + if ( isSimple.test( qualifier ) ) { + return jQuery.filter(qualifier, filtered, !keep); + } else { + qualifier = jQuery.filter( qualifier, filtered ); + } + } + + return jQuery.grep(elements, function( elem, i ) { + return ( jQuery.inArray( elem, qualifier ) >= 0 ) === keep; + }); +} + + + + +function createSafeFragment( document ) { + var list = nodeNames.split( "|" ), + safeFrag = document.createDocumentFragment(); + + if ( safeFrag.createElement ) { + while ( list.length ) { + safeFrag.createElement( + list.pop() + ); + } + } + return safeFrag; +} + +var nodeNames = "abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|" + + "header|hgroup|mark|meter|nav|output|progress|section|summary|time|video", + rinlinejQuery = / jQuery\d+="(?:\d+|null)"/g, + rleadingWhitespace = /^\s+/, + rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig, + rtagName = /<([\w:]+)/, + rtbody = /]", "i"), + // checked="checked" or checked + rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i, + rscriptType = /\/(java|ecma)script/i, + rcleanScript = /^\s*", "" ], + legend: [ 1, "
    ", "
    " ], + thead: [ 1, "", "
    " ], + tr: [ 2, "", "
    " ], + td: [ 3, "", "
    " ], + col: [ 2, "", "
    " ], + area: [ 1, "", "" ], + _default: [ 0, "", "" ] + }, + safeFragment = createSafeFragment( document ); + +wrapMap.optgroup = wrapMap.option; +wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; +wrapMap.th = wrapMap.td; + +// IE can't serialize and + + + + + + + + + +
    +
    +
    +
    + +
    +

    9. Contacts & Notices¶

    +
    +

    9.1. Contacts¶

    +
    +
    ADLINK Technology Corporation
    +
    400 TradeCenter
    +
    Suite 5900
    +
    Woburn, MA
    +
    01801
    +
    USA
    +
    Tel: +1 781 569 5819
    +
    +
    +
    ADLINK Technology Limited
    +
    The Edge
    +
    5th Avenue
    +
    Team Valley
    +
    Gateshead
    +
    NE11 0XA
    +
    UK
    +
    Tel: +44 (0)191 497 9900
    +
    +
    +
    ADLINK Technology SARL
    +
    28 rue Jean Rostand
    +
    91400 Orsay
    +
    France
    +
    Tel: +33 (1) 69 015354
    +
    +

    Web: http://ist.adlinktech.com/

    +

    Contact: http://ist.adlinktech.com

    +

    E-mail: ist_info@adlinktech.com

    +

    LinkedIn: https://www.linkedin.com/company/79111/

    +

    Twitter: https://twitter.com/ADLINKTech_usa

    +

    Facebook: https://www.facebook.com/ADLINKTECH

    +
    +
    +

    9.2. Notices¶

    +

    Copyright © 2018 ADLINK Technology Limited. All rights reserved.

    +

    This document may be reproduced in whole but not in part. The information contained in this +document is subject to change without notice and is made available in good faith without +liability on the part of ADLINK Technology Limited. All trademarks acknowledged.

    +
    +
    + + +
    +
    +
    +
    +
    + +

    Table Of Contents

    + + +

    Previous topic

    +

    8. Python Generation from IDL

    +

    This Page

    + + + +
    +
    +
    +
    + + + + \ No newline at end of file diff --git a/docs/html/PythonDCPSAPIGuide/dds_entities.html b/docs/html/PythonDCPSAPIGuide/dds_entities.html new file mode 100644 index 000000000..a6cafc81e --- /dev/null +++ b/docs/html/PythonDCPSAPIGuide/dds_entities.html @@ -0,0 +1,482 @@ + + + + + + + + 5. Python API for Vortex DDS — Python DCPS API Guide + + + + + + + + + + + + + + + +
    +
    +
    +
    + +
    +

    5. Python API for Vortex DDS¶

    +

    The Python DCPS API provides users with Python classes to model DDS communication using Python and pure +DDS applications.

    +

    The Python DCPS API consists of 2 modules.

    +
      +
    • dds module
    • +
    • ddsutil module
    • +
    +

    This section provides an overview of the main DDS concepts and Python API examples for these DDS concepts.

    +
    +

    Note

    +
      +
    • The Python DCPS API can be found in the following directory:

      +
      +

      $OSPL_HOME/tools/python/docs/html

      +
      +
    • +
    +
    +
    +

    5.1. API Usage Patterns¶

    +

    The typical usage pattern for the Python DCPS API for Vortex DDS is the following:

    +
      +
    • optional - Model your DDS topics using IDL. Alternatively, the python scripts can use topics that already exist in the DDS system.
    • +
    • optional - Statically generate Python topic classes using idlpp -l python. If using IDL, the user also has the option to dynamically generate Python topic classes in python scripts. See Python Generation from IDL.
    • +
    • Start writing your Python program using the Python API for Vortex DDS.
    • +
    +

    The core classes you must use are dds.Topic, dds.DomainParticipant and either dds.DataReader or dds.DataWriter. +Other classes may be required, especially if you need to adjust the Quality of Service (QoS) defaults. +For details on setting QoS values with the API, see Quality of Service (QoS).

    +

    The following list shows the sequence in which you would use the Vortex classes:

    +
      +
    • Create a dds.DomainParticipant instance.
    • +
    • Create one or more dds.Topic instances for the IDL topics your program will read or write.
    • +
    • If you require publisher or subscriber level non-default QoS settings, create dds.Publisher and/or dds.Subscriber instances. (The most common reason for changing publisher/subscriber QoS is to define non-default partitions.)
    • +
    • Create dds.DataReader and/or dds.DataWriter classes using the dds.Topic instances that you created.
    • +
    • If you required data filtering, create dds.QueryCondition objects.
    • +
    • Create the core of program, creating instances of your topic classes and writing them; or, reading data and processing it.
    • +
    +
    +
    +

    5.2. dds.Topic¶

    +

    The Python Topic class represents a DDS topic type. The DDS topic corresponds to a single data type. In DDS, data is distributed by publishing and subscribing topic data samples.

    +

    For a DDS Topic type definition, a corresponding Python class must be defined. +These topic classes are either a class created statically using idlpp, dynamically using an idl file or dynamically for an existing topic discovered in the system. (see Topic Generation and Discovery)

    +

    API Examples

    +

    Create a Vortex DDS topic named ‘Msg1’ based on the DDS Topic type Msg.

    +
    TOPIC_NAME = 'Msg1'
    +TOPIC_TYPE = 'HelloWorldData::Msg'
    +IDL_FILE = 'idl/HelloWorldData.idl'
    +
    +# Create domain participant
    +dp = DomainParticipant()
    +
    +# Generate python classes from IDL file
    +gen_info = ddsutil.get_dds_classes_from_idl(IDL_FILE, TOPIC_TYPE)
    +
    +# Type support class
    +qos = Qos([DurabilityQosPolicy(DDSDurabilityKind.TRANSIENT),
    +    ReliabilityQosPolicy(DDSReliabilityKind.RELIABLE)])
    +topic = gen_info.register_topic(dp, TOPIC_NAME, qos)
    +
    +
    +
    +
    +

    5.3. dds.DomainParticipant¶

    +

    The Python``dds.DomainParticipant`` class represents a DDS domain participant entity.

    +

    In DDS - “A domain participant represents the local membership of the application in a domain. A domain is a distributed concept that links all the applications able to communicate with each other. It represents a communication plane: only the publishers and subscribers attached to the same domain may interact.â€

    +

    The dds.DomainParticipant has two optional parameters on creation. If these parameters are not provided, defaults are used.

    +

    Parameters:

    +
      +
    • qos (Qos) – Participant QoS. Default: None
    • +
    • listener (Listener) – Participant listener Default: None
    • +
    +

    API Examples

    +

    Create a Vortex DDS domain participant. Returns participant or throws a dds.DDSException if the participant cannot be created.

    +

    Create a domain participant in the default DDS domain (the one specified by the OSLP_URI environment variable).

    +
    # Create domain participant
    +dp = DomainParticipant()
    +
    +
    +

    Create a participant on default domain with QoS profile.

    +
    qp = QosProvider('file://DDS_DefaultQoS_All.xml', 'DDS DefaultQosProfile')
    +
    +# Create participant
    +dp = DomainParticipant(qos = qp.get_participant_qos())
    +
    +
    +

    Create a participant on domain with QoS profile and listener. TODO

    +
    qp = QosProvider('file://DDS_DefaultQoS_All.xml', 'DDS DefaultQosProfile')
    +
    +# Create participant
    +dp = DomainParticipant(qos = qp.get_participant_qos())
    +
    +
    +
    +
    +

    5.4. dds.Publisher¶

    +

    The Python dds.Publisher class represents a DDS publisher entity.

    +

    In DDS, a publisher is “an object responsible for data distribution. It may publish data of different data types.â€

    +

    Use of the dds.Publisher class is optional. +In it’s place, you can use a dds.DomainParticipant instance. +Reasons for explicitly creating a dds.Publisher instance are:

    +
      +
    • to specify non-default QoS settings, including specifying the DDS partition upon which samples are written.
    • +
    • to control the timing of publisher creation and deletion.
    • +
    +

    API Examples

    +

    Create a DDS Publisher entity. Returns publisher or throws a dds.DDSException if the publisher cannot be created.

    +

    Create a publisher with participant.

    +
    # Create participant
    +dp = DomainParticipant()
    +
    +# Create publisher
    +pub = dp.create_publisher()
    +
    +
    +

    Create a publisher with participant and QoS profile.

    +
    qp = QosProvider('file://DDS_DefaultQoS_All.xml', 'DDS DefaultQosProfile')
    +
    +# Create participant
    +dp = DomainParticipant(qos = qp.get_participant_qos())
    +
    +# Create publisher
    +pub = dp.create_publisher(qos = qp.get_publisher_qos())
    +
    +
    +
    +
    +

    5.5. dds.DataWriter¶

    +

    The Python dds.Writer class represents a DDS data writer entity.

    +

    In DDS - “The DataWriter is the object the application must use to communicate to a publisher the existence and value of data-objects of a given type.â€

    +

    A dds.DataWriter class is required in order to write data to a DDS domain. +It is attached to a DDS publisher or a DDS domain participant.

    +

    A dds.DataWriter class instance references an existing dds.Topic instance.

    +

    API Examples

    +

    Create a Vortex DDS domain writer. Returns writer or throws a dds.DDSException if the writer cannot be created.

    +

    Create a writer within a domain participant, and with default QoS.

    +
    # Create domain participant
    +dp = DomainParticipant()
    +
    +# Generate python classes from IDL file
    +gen_info = ddsutil.get_dds_classes_from_idl('idl/HelloWorldData.idl', 'HelloWorldData::Msg')
    +
    +# Type support class
    +qos = Qos([DurabilityQosPolicy(DDSDurabilityKind.TRANSIENT), ReliabilityQosPolicy(DDSReliabilityKind.RELIABLE)])
    +topic = gen_info.register_topic(dp, 'Msg1', qos)
    +
    +# Create a writer
    +writer = dp.create_datawriter(topic)
    +
    +
    +

    Create a writer within a publisher, and with default QoS.

    +
    # Create domain participant
    +dp = DomainParticipant()
    +
    +# Create publisher
    +pub = dp.create_publisher()
    +
    +# Generate python classes from IDL file
    +gen_info = ddsutil.get_dds_classes_from_idl('idl/HelloWorldData.idl', 'HelloWorldData::Msg')
    +
    +# Type support class
    +qos = Qos([DurabilityQosPolicy(DDSDurabilityKind.TRANSIENT), ReliabilityQosPolicy(DDSReliabilityKind.RELIABLE)])
    +topic = gen_info.register_topic(dp, 'Msg1', qos)
    +
    +# Create a writer
    +writer = pub.create_datawriter(topic)
    +
    +
    +

    Create a writer with publisher or participant, topic and QoS profile.

    +
    +
    # Create domain participant
    +dp = DomainParticipant()
    +
    +# Create publisher
    +pub = dp.create_publisher()
    +
    +# Generate python classes from IDL file
    +gen_info = ddsutil.get_dds_classes_from_idl('idl/HelloWorldData.idl', 'HelloWorldData::Msg')
    +
    +# Type support class
    +qos = Qos([DurabilityQosPolicy(DDSDurabilityKind.TRANSIENT), ReliabilityQosPolicy(DDSReliabilityKind.RELIABLE)])
    +topic = gen_info.register_topic(dp, 'Msg1', qos)
    +
    +# Create a writer
    +qp = QosProvider('file://DDS_DefaultQoS_All.xml', 'DDS DefaultQosProfile')
    +writer = pub.create_datawriter(topic)
    +writer = pub.create_datawriter(topic, qp.get_writer_qos())
    +
    +
    +
    +

    Write a Msg topic class instance to a writer.

    +
    # Topic data class
    +idMessage = 1
    +message1 = 'Hello World'
    +s = gen_info.topic_data_class(userID = idMessage, message = message1)
    +
    +# Write data
    +writer.write(s)
    +
    +
    +

    Dispose a DDS topic instance.

    +
    # dispose instance
    +writer.dispose_instance(s)
    +
    +
    +

    Unregister a DDS topic instance. TODO no equivalent in Python API

    +
    +

    % writer: a Vortex.Writer instance +% ShapeType: a ‘topic class’ created manually or via IDLPP +data = ShapeType(); % create an object instance +% set data key values... +data.color = ‘RED’;

    +

    ddsStatus = writer.unregister(data);

    +
    +
    +
    +

    5.6. dds.Subscriber¶

    +

    The Python dds.Subscriber class represents a DDS subscriber entity.

    +

    In DDS, a subscriber is “an object responsible for receiving published data and making it available to the receiving application. It may receive and dispatch data of different specified types.â€

    +

    Use of the dds.Subscriber class is optional. +In it’s place, you can use a dds.DomainParticipant instance. +Reasons for explicitly creating a dds.Subscriber instance are:

    +
      +
    • to specify non-default QoS settings, including specifying the DDS partition upon which samples are written.
    • +
    • to control the timing of subscriber creation and deletion.
    • +
    +

    API Examples

    +

    Create a Vortex DDS domain subscriber. Returns subscriber or throw a dds.DDSException if the subscriber cannot be created.

    +

    Create a subscriber with participant.

    +
    # Create participant
    +dp = DomainParticipant()
    +
    +# Create Subscriber
    +sub = dp.create_subscriber()
    +
    +
    +

    Create a subscriber with participant and QoS profile.

    +
    qp = QosProvider('file://DDS_DefaultQoS_All.xml', 'DDS DefaultQosProfile')
    +
    +# Create participant
    +dp = DomainParticipant(qos = qp.get_participant_qos())
    +
    +# Create Subscriber
    +sub = dp.create_subscriber(qos = qp.get_subscriber_qos())
    +
    +
    +
    +
    +

    5.7. dds.DataReader¶

    +

    The Python Vortex.Reader class represents a DDS data reader entity.

    +

    In DDS - “To access the received data, the application must use a typed DataReader attached to the subscriber.â€

    +

    A dds.DataReader class is required in order to write data to a DDS domain. +It is attached to a DDS subscriber or a DDS domain participant.

    +

    A dds.DataReader class instance references an existing dds.Topic instance.

    +

    API Examples

    +

    Create a Vortex DDS domain reader. Returns reader or throw a dds.DDSException instance if the reader cannot be created.

    +

    Create a reader for a topic within a participant, and with default QoS.

    +
    # Create domain participant
    +dp = DomainParticipant()
    +
    +# Generate python classes from IDL file
    +gen_info = ddsutil.get_dds_classes_from_idl('idl/HelloWorldData.idl', 'HelloWorldData::Msg')
    +
    +# Type support class
    +qos = Qos([DurabilityQosPolicy(DDSDurabilityKind.TRANSIENT), ReliabilityQosPolicy(DDSReliabilityKind.RELIABLE)])
    +topic = gen_info.register_topic(dp, 'Msg1', qos)
    +
    +# Create a reader
    +reader = dp.create_datareader(topic)
    +
    +
    +

    Create a reader for a topic within a subscriber, and with default QoS.

    +
    # Create domain participant
    +dp = DomainParticipant()
    +
    +# Create subscriber
    +sub = dp.create_subscriber()
    +
    +# Generate python classes from IDL file
    +gen_info = ddsutil.get_dds_classes_from_idl(IDL_FILE, TOPIC_TYPE)
    +
    +# Type support class
    +qos = Qos([DurabilityQosPolicy(DDSDurabilityKind.TRANSIENT), ReliabilityQosPolicy(DDSReliabilityKind.RELIABLE)])
    +topic = gen_info.register_topic(dp, TOPIC_NAME, qos)
    +
    +# Create a reader
    +reader = sub.create_datareader(topic)
    +
    +
    +

    Create a reader for a topic within a subscriber or participant, with with a QoS profile.

    +
    # Create domain participant
    +dp = DomainParticipant()
    +
    +# Create subscriber
    +sub = dp.create_subscriber()
    +
    +# Generate python classes from IDL file
    +gen_info = ddsutil.get_dds_classes_from_idl(IDL_FILE, TOPIC_TYPE)
    +
    +# Type support class
    +qos = Qos([DurabilityQosPolicy(DDSDurabilityKind.TRANSIENT), ReliabilityQosPolicy(DDSReliabilityKind.RELIABLE)])
    +topic = gen_info.register_topic(dp, TOPIC_NAME, qos)
    +
    +# Create a reader
    +qp = QosProvider('file://DDS_DefaultQoS_All.xml', 'DDS DefaultQosProfile')
    +reader = sub.create_datareader(topic, qp.get_reader_qos())
    +
    +
    +

    Take data from a data reader.

    +
    l = reader.take(10)
    +
    +
    +

    Read data from a data reader.

    +
    l = reader.read(10)
    +
    +
    +

    Specify a wait timeout, in seconds, before read or take will return without receiving data TODO change description the code is wrong

    +
    # Create waitset
    +waitset = WaitSet()
    +qc = QueryCondition(reader, DDSMaskUtil.all_samples(), 'long1 > 1')
    +
    +waitset.attach(qc)
    +
    +# Wait for data
    +conditions = waitset.wait()
    +
    +# Print data
    +l = reader.take(10)
    +
    +
    +
    +
    +

    5.8. dds.QueryCondition¶

    +

    The Python dds.QueryCondition class represents a DDS query entity.

    +

    A query is a data reader, restricted to accessing data that matches specific status conditions and/or a filter expression.

    +

    A dds.Query class instance references an existing dds.DataReader instance.

    +

    API Examples

    +

    Create a dds.QueryCondition with a state mask and a filter expression for a reader and take data.

    +
    # Create waitset
    +waitset = WaitSet()
    +qc = QueryCondition(reader, DDSMaskUtil.all_samples(), 'long1 > 1')
    +
    +waitset.attach(qc)
    +
    +# Wait for data
    +conditions = waitset.wait()
    +
    +# Print data
    +l = reader.take(10)
    +for sd, si in l:
    +    sd.print_vars()
    +
    +
    +
    +
    + + +
    +
    +
    +
    +
    + +

    Table Of Contents

    + + +

    Previous topic

    +

    4. Examples

    +

    Next topic

    +

    6. Quality of Service (QoS)

    +

    This Page

    + + + +
    +
    +
    +
    + + + + \ No newline at end of file diff --git a/docs/html/PythonDCPSAPIGuide/examples.html b/docs/html/PythonDCPSAPIGuide/examples.html new file mode 100644 index 000000000..1b72c4da0 --- /dev/null +++ b/docs/html/PythonDCPSAPIGuide/examples.html @@ -0,0 +1,224 @@ + + + + + + + + 4. Examples — Python DCPS API Guide + + + + + + + + + + + + + + + +
    +
    +
    +
    + +
    +

    4. Examples¶

    +

    Several examples are provided to demonstrate the Python DCPS features.

    +

    The examples can be found in the following directory:

    +
    +
      +
    • $OSPL_HOME/tools/python/examples
    • +
    +
    +
    +

    4.1. Example Files¶

    +
    +

    4.1.1. File Types¶

    +

    The examples directory contains files of different types. The runnable python script files reference the xml and idl files.

    + ++++ + + + + + + + + + + + + + + + + +
    File TypeDescription
    pyA program file or script written in Python
    xmlAn XML file that contains one or more Quality of Service (QoS) profiles for DDS entities.
    idlAn interface description language file used to define topic(s).
    +
    +
    +

    4.1.2. Examples¶

    + ++++ + + + + + + + + + + + + + + + + + + + +
    ExampleDescription
    qos_example.pyAn example that demonstrates how to specify QoS +settings using Python DCPS APIs. Also shows +usage of a waitset.
    example1.pyDynamic generation of Python Topic classes +using IDL file and name. Uses a topic with a +sequence.
    example2.pyDynamic generation of Python Topic classes +using Enumeration and nested modules.
    example4.pyDemonstrate finding DDS topics over-the-wire. +Find topics registered by other processes, and +read and write samples to those topics.
    +
    +
    +
    +

    4.2. Running Examples¶

    +

    To run an example python script:

    +
      +
    1. Setup OSPL environment variables.

      +

      Linux

      +
      +
        +
      • source release.com
      • +
      +
      +
      +
      Windows
      +
        +
      • release.bat
      • +
      +
      +
      +
    2. +
    3. Run an example python script

      +
      +
        +
      • > python3 example1.py
      • +
      +
      +
    4. +
    +
    +
    + + +
    +
    +
    +
    +
    + +

    Table Of Contents

    + + +

    Previous topic

    +

    3. Installation

    +

    Next topic

    +

    5. Python API for Vortex DDS

    +

    This Page

    + + + +
    +
    +
    +
    + + + + \ No newline at end of file diff --git a/docs/html/PythonDCPSAPIGuide/genindex.html b/docs/html/PythonDCPSAPIGuide/genindex.html new file mode 100644 index 000000000..733029f9e --- /dev/null +++ b/docs/html/PythonDCPSAPIGuide/genindex.html @@ -0,0 +1,94 @@ + + + + + + + + + Index — Python DCPS API Guide + + + + + + + + + + + + + +
    +
    +
    +
    + + +

    Index

    + +
    + +
    + + +
    +
    +
    +
    +
    + + + + + + +
    +
    +
    +
    + + + + \ No newline at end of file diff --git a/docs/html/PythonDCPSAPIGuide/index.html b/docs/html/PythonDCPSAPIGuide/index.html new file mode 100644 index 000000000..7165c8345 --- /dev/null +++ b/docs/html/PythonDCPSAPIGuide/index.html @@ -0,0 +1,191 @@ + + + + + + + + Python DCPS API Guide — Python DCPS API Guide + + + + + + + + + + + + + + +
    + +
    +
    + +

    Table Of Contents

    + + +

    Next topic

    +

    1. Preface

    +

    This Page

    + + + +
    +
    +
    +
    + + + + \ No newline at end of file diff --git a/docs/html/PythonDCPSAPIGuide/installation.html b/docs/html/PythonDCPSAPIGuide/installation.html new file mode 100644 index 000000000..546f30755 --- /dev/null +++ b/docs/html/PythonDCPSAPIGuide/installation.html @@ -0,0 +1,253 @@ + + + + + + + + 3. Installation — Python DCPS API Guide + + + + + + + + + + + + + + + +
    +
    +
    +
    + +
    +

    3. Installation¶

    +

    This section describes the procedure to install the Python DCPS API on a Linux or Windows platform.

    +
    +

    3.1. System Requirements¶

    +

    Operating System: Linux or Windows

    +
    +
    +

    3.2. Dependencies¶

    +
    +
    +
    Linux
    +
      +
    • Python3 version 3.4.0 or later
    • +
    • pip3 (package “python3-pip” on most linux package managers)
    • +
    • GCC 4.8 or later
    • +
    +
    +
    Windows
    +
      +
    • Python version 3.5.0
    • +
    • pip (usually already included in Python for Windows)
    • +
    • Visual Studio 14 (2015) C compiler or later
    • +
    +
    +
    Python modules
    +
      +
    • Cython version 0.27 or later (install using “pip3 install Cython”)
    • +
    +
    +
    +
    +
    +
    +

    3.3. OpenSplice (OSPL) and Python DCPS API Installation¶

    +

    Steps:

    +
      +
    1. Install OSPL. The Python DCPS API is included in this installer.
    2. +
    3. Setup OSPL license. Copy the license.lic file into the appropriate license directory.
    4. +
    +
    +
    /INSTALLDIR/Vortex_v2/license
    +
      +
    1. Python DCPS API files are contained in a tools/python folder
    2. +
    +
    +
    Example: +$OSPL_HOME/tools/python
    +
    +Python Directory +
    +
    +
    +

    3.4. Python DCPS API Setup¶

    +
    +

    3.4.1. Install Python DCPS API package from python wheel¶

    +

    In certain Vortex OpenSplice installs, the python api is bundled as a python wheel file in +the $OSPL_HOME/tools/python directory. This way it avoids needing a native compiler and Cython +prerequisites before installation.

    +

    Simply install using pip. For example, executing the command will install the wheel package, +which is targeted for python 3.4 64-bit Linux:

    +
    +
    $pip3 install dds-6.9.0-cp34-cp34m-linux_x86_64.whl
    +

    Or similarly, for python 3.5 64-bit Windows:

    +
    +
    >pip install dds-6.9.0-cp35-cp35m-win_amd64.whl
    +

    If the binary wheel package is not present or is not compatible with your python version, +then it is preferable to install the api from source.

    +
    +
    +

    3.4.2. Install Python DCPS API package from source¶

    +

    If the dependencies are satisfied, and the Vortex OpenSplice environment is set +(OSPL_HOME and associated environment variables), then installation is just one command +to execute in the $OSPL_HOME/python/src directory:

    +
    +
    $python3 setup.py install
    +
    +

    Note

    +
      +
    • In either case, installing from wheel or from source may require administrator or superuser privileges if python was installed for all users.

      +
    • +
    • To check modules are installed correctly try importing the installed modules.

      +
      >>> import dds
      +>>> import ddsutil
      +
      +
      +
    • +
    +
    +
    +
    +
    +

    3.5. Examples and Documentation¶

    +
      +
    1. Examples

      +
      +

      The examples can be found in the following directory:

      +
      +
        +
      • $OSPL_HOME/tools/python/examples
      • +
      +
      +
      +
    2. +
    3. Python DCPS API Documentation

      +
      +

      The Python DCPS API can be found in the following directory:

      +
      +
        +
      • $OSPL_HOME/tools/python/docs/html
      • +
      +
      +
      +
    4. +
    5. Python DCPS User Guide (HTML and PDF)

      +
      +

      The user guide can be found in the following directories:

      +
      +
        +
      • $OSPL_HOME/docs/html
      • +
      • $OSPL_HOME/docs/pdf
      • +
      +
      +
      +
    6. +
    +
    +
    + + +
    +
    +
    + +
    +
    + + + + \ No newline at end of file diff --git a/docs/html/PythonDCPSAPIGuide/introduction.html b/docs/html/PythonDCPSAPIGuide/introduction.html new file mode 100644 index 000000000..bf5c0dba4 --- /dev/null +++ b/docs/html/PythonDCPSAPIGuide/introduction.html @@ -0,0 +1,134 @@ + + + + + + + + 2. Introduction — Python DCPS API Guide + + + + + + + + + + + + + + + +
    +
    +
    +
    + +
    +

    2. Introduction¶

    +

    The Python DCPS API provides users with Python classes to model DDS communication using Python and pure DDS applications.

    +

    The Python DCPS API is a native Python binding that supports full DDS functionality. The language binding consists of a Python interface and a C wrapper implementation of the C99 API (C API for DDS). It makes use of Python language features and leverages ease of use by providing a higher level of abstraction.

    +
    +

    2.1. DDS¶

    +

    What is DDS?

    +

    “The Data Distribution Service (DDSâ„¢) is a middleware protocol and API standard for data-centric connectivity from the Object Management Group® (OMG®). It integrates the components of a system together, providing low-latency data connectivity, extreme reliability, and a scalable architecture that business and mission-critical Internet of Things (IoT) applications need.â€

    +

    “The main goal of DDS is to share the right data at the right place at the right time, even between time-decoupled publishers and consumers. DDS implements global data space by carefully replicating relevant portions of the logically shared dataspace.†DDS specification

    +
    +DDS +
    +

    Further Documentation

    +

    http://portals.omg.org/dds/

    +

    http://ist.adlinktech.com/

    +
    +
    + + +
    +
    +
    +
    +
    + +

    Table Of Contents

    + + +

    Previous topic

    +

    1. Preface

    +

    Next topic

    +

    3. Installation

    +

    This Page

    + + + +
    +
    +
    +
    + + + + \ No newline at end of file diff --git a/docs/html/PythonDCPSAPIGuide/objects.inv b/docs/html/PythonDCPSAPIGuide/objects.inv new file mode 100644 index 000000000..90b055a1f --- /dev/null +++ b/docs/html/PythonDCPSAPIGuide/objects.inv @@ -0,0 +1,7 @@ +# Sphinx inventory version 2 +# Project: Python DCPS API Guide +# Version: 6.x +# The remainder of this file is compressed using zlib. +xÚSÁJÄ0½ç+.¢‡^½‰•eA¥RñºÄ$Û ¤ILgû÷N;mQñ–¼™÷fæMRo½6¼}ãä›q\\ózD¯öи3¾éÏ,v°¾™$Áâq—BívK2åmß62Fëk’!\L|ÑóEÏ/Iz}"½)˜õ-Hç]Ô™G¨Â +;0ÖýÍl±90Ž÷ôÁ™Κ· \ No newline at end of file diff --git a/docs/html/PythonDCPSAPIGuide/preface.html b/docs/html/PythonDCPSAPIGuide/preface.html new file mode 100644 index 000000000..6b68fa0ba --- /dev/null +++ b/docs/html/PythonDCPSAPIGuide/preface.html @@ -0,0 +1,143 @@ + + + + + + + + 1. Preface — Python DCPS API Guide + + + + + + + + + + + + + + + +
    +
    +
    +
    + +
    +

    1. Preface¶

    +
    +

    1.1. About the Python DCPS API Guide¶

    +

    The Python DCPS API Guide is a starting point for anyone using, developing or running Python applications with Vortex OpenSplice.

    +

    This guide contains:

    +
    +
      +
    • Python DCSP API installation instructions
    • +
    • location of Python DCPS API dds module documentation
    • +
    • overview of general DDS concepts and Python API for Vortex DDS
    • +
    • a listing of examples, and how to run them
    • +
    • detailed information on how to specify DDS entity Quality of Service (QoS)
    • +
    • how to discover and register DDS topics
    • +
    +
    +

    This reference guide is based on the OMG’s Data Distribution Service Specification and Python Language Mapping Specification.

    +

    Please note that this guide is not intended to provide a detailed explanation of the aforementioned OMG specifications or the Vortex OpenSplice product. It provides an introduction to the essential concepts and enables users to begin using the Python DCPS API as quickly as possible.

    +
    +
    +

    1.2. Intended Audience¶

    +

    The Python Reference Guide is intended to be used by Python programmers who are +using Vortex OpenSplice to develop applications.

    +
    +
    + + +
    +
    +
    +
    +
    + +

    Table Of Contents

    + + +

    Previous topic

    +

    Python DCPS API Guide

    +

    Next topic

    +

    2. Introduction

    +

    This Page

    + + + +
    +
    +
    +
    + + + + \ No newline at end of file diff --git a/docs/html/PythonDCPSAPIGuide/python_idl_mapping.html b/docs/html/PythonDCPSAPIGuide/python_idl_mapping.html new file mode 100644 index 000000000..92da2dbd8 --- /dev/null +++ b/docs/html/PythonDCPSAPIGuide/python_idl_mapping.html @@ -0,0 +1,308 @@ + + + + + + + + 8. Python Generation from IDL — Python DCPS API Guide + + + + + + + + + + + + + + + +
    +
    +
    +
    + +
    +

    8. Python Generation from IDL¶

    +

    The Python DCPS API supports generation of Python topic classes from IDL. This chapter describes the details of the IDL-Python binding.

    +
    +

    8.1. Running IDLPP¶

    +
    +

    8.1.1. Static Generation¶

    +

    The Python topic classes can be generated statically using an IDL file.

    +

    Compiling IDL into python code is done using the -l python switch on idlpp:

    +
    idlpp -l python idl-file-to-compile.idl
    +
    +
    +
    +

    Note

    +
      +
    • A Python package with the same name as the idl file (without the .idl extension) is always created.
    • +
    • It defines types not included in an IDL module. IDL modules become Python packages within this base package.
    • +
    +
    +
    +
    +

    8.1.2. Dynamic Generation¶

    +

    The Python topic classes can be generated dynamically using an IDL file, and the topic name. An api, ddsutil.get_dds_classes_from_idl, is provided to generate the topic classes at runtime from within a Python script.

    +

    HelloWorldDataPublisher.py

    +
    ...
    +TOPIC_NAME = 'Msg1'
    +TOPIC_TYPE = 'HelloWorldData::Msg'
    +IDL_FILE = 'idl/HelloWorldData.idl'
    +
    +# Create domain participant
    +dp = DomainParticipant()
    +
    +# Create publisher
    +pub = dp.create_publisher()
    +
    +# Generate python topic classes from IDL file
    +gen_info = ddsutil.get_dds_classes_from_idl(IDL_FILE, TOPIC_TYPE)
    +
    +# Type support class
    +qos = Qos([DurabilityQosPolicy(DDSDurabilityKind.TRANSIENT),
    +       ReliabilityQosPolicy(DDSReliabilityKind.RELIABLE)])
    +
    +# Register topic
    +topic = gen_info.register_topic(dp, TOPIC_NAME, qos)
    +
    +# Create a writer
    +writer = pub.create_datawriter(topic)
    +
    +# Topic data class
    +idMessage = 1
    +message1 = 'Hello World'
    +s = gen_info.topic_data_class(userID = idMessage, message = message1)
    +
    +# Write data
    +writer.write(s)
    +
    +#output to console
    +print('=== [Publisher] writing a message containing : ')
    +print('userID  :',  idMessage)
    +print('message :', message1)
    +...
    +
    +
    +
    +
    +

    8.1.3. Generated Artifacts¶

    +

    The following table defines the Python artifacts generated from IDL concepts:

    + +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    IDL ConceptPython ConceptComment
    modulepackageFolder with module name, plus __init__.py that +defines types defined within the module.
    enumclassDefined in __init__.py files.
    enum valueenum valueDefined in __init__.py files.
    structclassDefined in __init__.py files.
    fieldclass propertyDefined in __init__.py files.
    unionunionDefined in __init__.py files. (Only statically +generated supported)
    +

    Datatype mappings

    +

    The following table shows the Python equivalents to IDL primitive types:

    + ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    IDL TypePython Type
    booleanbool
    charstr, length==1
    octetint
    shortint
    ushortint
    longint
    ulongint
    long longint
    ulong longint
    floatfloat
    doublefloat
    stringstr
    wcharUnsupported
    wstringUnsupported
    anyUnsupported
    long doubleUnsupported
    +

    Implementing Arrays and Sequences in Python

    +

    Both IDL arrays and IDL sequences are mapped to Python lists.

    +

    The constructors for generated classes always fully allocate any array fields. Sequences are always initialized to the empty list.

    +
    +
    +
    +

    8.2. Limitations of Python Support¶

    +

    The IDL-to-Python binding has the following limitations:

    +
      +
    • IDL unions are Supported by statically generated Python, but not by dynamic or over-the-wire.
    • +
    • The following IDL data types are not supported: wchar, wstring, any and long double .
    • +
    +
    +
    + + +
    +
    +
    +
    +
    + +

    Table Of Contents

    + + +

    Previous topic

    +

    7. Topic Generation and Discovery

    +

    Next topic

    +

    9. Contacts & Notices

    +

    This Page

    + + + +
    +
    +
    +
    + + + + \ No newline at end of file diff --git a/docs/html/PythonDCPSAPIGuide/qos_provider.html b/docs/html/PythonDCPSAPIGuide/qos_provider.html new file mode 100644 index 000000000..507110dbe --- /dev/null +++ b/docs/html/PythonDCPSAPIGuide/qos_provider.html @@ -0,0 +1,234 @@ + + + + + + + + 6. Quality of Service (QoS) — Python DCPS API Guide + + + + + + + + + + + + + + + +
    +
    +
    +
    + +
    +

    6. Quality of Service (QoS)¶

    +

    The following section explains how to set the Quality of Service (QoS) for a DDS entity.

    +

    Users have two options available to set the QoS for an entity or entities. They can define the QoS settings using an XML file, or they can use the Python DCPS APIs. Both of these options are explained.

    +

    If a QoS setting for an entity is not set using an xml file or the Python DCPS APIs, the defaults will be used. This allows a user the ability to override only those settings that require non-default values.

    +

    The code snippets referenced are taken from the runnable examples.

    +
    +

    Note

    +
      +
    • The Examples section provides the examples directory location, example descriptions and running instructions.
    • +
    +
    +
    +

    6.1. Setting QoS Using QoS Provider XML File¶

    +

    QoS for DDS entities can be set using XML files based on the XML schema file QoSProfile.xsd. +These XML files contain one or more QoS profiles for DDS entities.

    +

    Sample QoS Profile XML files can be found in the examples directory.

    +
    +

    6.1.1. QoS Profile¶

    +

    A QoS profile consists of a name and optionally a base_name attribute. The base_name attribute allows a +QoS or a profile to inherit values from another QoS or profile in the same file. The file contains QoS +elements for one or more DDS entities. A skeleton file without any QoS values is displayed below to show +the structure of the file.

    +
    <dds xmlns="http://www.omg.org/dds/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="file:DDS_QoSProfile.xsd">
    +    <qos_profile name="DDS QoS Profile Name">
    +        <datareader_qos></datareader_qos>
    +        <datawriter_qos></datawriter_qos>
    +        <domainparticipant_qos></domainparticipant_qos>
    +        <subscriber_qos></subscriber_qos>
    +        <publisher_qos></publisher_qos>
    +        <topic_qos></topic_qos>
    +    </qos_profile>
    +</dds>
    +
    +
    +

    Example: Specify Publisher Partition

    +

    The example below specifies the publisher’s partitions as A and B.

    +
    <publisher_qos>
    +    <partition>
    +        <name>
    +            <element>A</element>
    +            <element>B</element>
    +        </name>
    +    </partition>
    +</publisher_qos>
    +
    +
    +
    +
    +

    6.1.2. Applying QoS Profile¶

    +

    To set the QoS profile for a DDS entity using the Python DCPS API and an XML file, the user specifies the File URI and the QoS profile name as parameters.

    +

    example1.py

    +
    ...
    +qp = QosProvider('file://DDS_DefaultQoS_All.xml', 'DDS DefaultQosProfile')
    +
    +# Create participant
    +dp = DomainParticipant(qos = qp.get_participant_qos())
    +
    +# Create publisher
    +pub = dp.create_publisher(qos = qp.get_publisher_qos())
    +
    +# Create Subscriber
    +sub = dp.create_subscriber(qos = qp.get_subscriber_qos())
    +...
    +
    +
    +
    +
    +
    +

    6.2. Setting QoS Using Python DCPS API Classes¶

    +

    QoS settings can also be set by using the python classes alone. (No XML files required.)

    +

    Below is a code snippet that demonstrates how to specify the QoS settings for a writer using the python DCPS apis. In this example, all the QoS settings for the writer are set and all of the default QoS settings are overridden. If a QoS setting for an entity is not set, the default is used.

    +

    qos_example.py

    +
    ...
    +writer_qos = Qos([DurabilityQosPolicy(DDSDurabilityKind.TRANSIENT),
    +               DeadlineQosPolicy(DDSDuration(500)),
    +               LatencyBudgetQosPolicy(DDSDuration(3000)),
    +               LivelinessQosPolicy(DDSLivelinessKind.MANUAL_BY_PARTICIPANT),
    +               ReliabilityQosPolicy(DDSReliabilityKind.RELIABLE, DDSDuration.infinity()),
    +               DestinationOrderQosPolicy(DDSDestinationOrderKind.BY_SOURCE_TIMESTAMP),
    +               HistoryQosPolicy(DDSHistoryKind.KEEP_ALL),
    +               ResourceLimitsQosPolicy(10,10,10),
    +               TransportPriorityQosPolicy(700),
    +               LifespanQosPolicy(DDSDuration(10, 500)),
    +               OwnershipQosPolicy(DDSOwnershipKind.EXCLUSIVE),
    +               OwnershipStrengthQosPolicy(100),
    +               WriterDataLifecycleQosPolicy(False)
    +               ])
    +...
    +
    +
    +

    In the next example, a topic QoS is created that overrides only a subset of the QoS settings.

    +

    HelloWorldDataSubscriber.py

    +
    ...
    +# Create domain participant
    +dp = DomainParticipant()
    +
    +# Create subscriber
    +sub = dp.create_subscriber()
    +
    +# Generate python classes from IDL file
    +gen_info = ddsutil.get_dds_classes_from_idl(IDL_FILE, TOPIC_TYPE)
    +
    +# Create a topic QoS that overrides defaults for durability and reliability
    +qos = Qos([DurabilityQosPolicy(DDSDurabilityKind.TRANSIENT),
    +       ReliabilityQosPolicy(DDSReliabilityKind.RELIABLE)])
    +topic = gen_info.register_topic(dp, TOPIC_NAME, qos)
    +...
    +
    +
    +
    +
    + + +
    +
    +
    +
    +
    + +

    Table Of Contents

    + + +

    Previous topic

    +

    5. Python API for Vortex DDS

    +

    Next topic

    +

    7. Topic Generation and Discovery

    +

    This Page

    + + + +
    +
    +
    +
    + + + + \ No newline at end of file diff --git a/docs/html/PythonDCPSAPIGuide/search.html b/docs/html/PythonDCPSAPIGuide/search.html new file mode 100644 index 000000000..33b9c77db --- /dev/null +++ b/docs/html/PythonDCPSAPIGuide/search.html @@ -0,0 +1,101 @@ + + + + + + + + Search — Python DCPS API Guide + + + + + + + + + + + + + + + + + + + +
    +
    +
    +
    + +

    Search

    +
    + +

    + Please activate JavaScript to enable the search + functionality. +

    +
    +

    + From here you can search these documents. Enter your search + words into the box below and click "search". Note that the search + function will automatically search for all of the words. Pages + containing fewer words won't appear in the result list. +

    +
    + + + +
    + +
    + +
    + +
    +
    +
    +
    +
    + +
    +
    +
    +
    + + + + \ No newline at end of file diff --git a/docs/html/PythonDCPSAPIGuide/searchindex.js b/docs/html/PythonDCPSAPIGuide/searchindex.js new file mode 100644 index 000000000..3341a5c3a --- /dev/null +++ b/docs/html/PythonDCPSAPIGuide/searchindex.js @@ -0,0 +1 @@ +Search.setIndex({envversion:42,terms:{all:[6,2,3,4],concept:[1,6,9],destinationorderqospolici:3,edg:4,queri:6,consum:[5,7],writer_qo:3,code:[7,1,6,3],abil:3,follow:[6,1,2,3,8],keep_al:3,skeleton:3,cython:2,depend:0,init:7,program:[6,8],those:[3,8],ist_info:4,sourc:[0,8],msg1:[1,6],string:1,fals:3,internet:5,ddsdestinationorderkind:3,facebook:4,xmlschema:3,relev:5,administr:2,level:[5,6],list:[1,6,9],dcsp:9,"try":2,adjust:6,qosprovid:[6,3],team:4,pleas:[7,9],tel:4,linux_x86_64:2,get_dds_classes_for_found_top:7,second:6,further:5,idlpp:[0,6],topic_nam:[1,6,3],compat:2,index:7,what:5,sub:[7,6,3],section:[7,6,2,3],abl:6,access:6,delet:6,version:2,qos_profil:3,local_top:7,datareader_qo:3,full:5,gener:[0,6,8,9],create_datawrit:[7,1,6],studio:2,"0xa":4,becom:1,valu:[1,6,3],wait:6,search:0,topic_typ:[1,6,3],technolog:4,step:2,within:[1,6],create_subscrib:[7,6,3],extrem:5,typic:6,cp35m:2,overrid:3,via:6,appli:0,modul:[6,1,2,8,9],prefer:2,avenu:4,"boolean":1,instal:0,installdir:2,middlewar:5,from:[0,6],describ:[1,2],usa:4,commun:[5,6],doubl:1,regist:[7,1,8,9],two:[6,3],next:3,busi:5,tradecent:4,transportpriorityqospolici:3,msg:[1,6],type:6,more:[7,6,3,8],faith:4,visual:2,"transient":[1,6,3],compani:4,given:6,must:6,none:6,ospllog:7,idl_fil:[1,6,3],scalabl:5,setup:[0,8],can:[1,2,3,6,7,8],defaultqosprofil:[6,3],control:6,ddsdurat:3,process:[7,6,8],share:5,critic:5,definit:6,helloworlddatasubscrib:3,ddsmaskutil:6,alwai:1,gcc:2,goal:5,anoth:[7,3],snippet:[7,3],how:[9,3,8],anyon:9,"__init__":1,pure:[5,6],get_publisher_qo:[6,3],map:[1,9],product:9,overridden:3,oslp_uri:6,superus:2,befor:[6,2],membership:6,plane:6,mai:[6,2,4],associ:2,demonstr:[3,8],alloc:1,"short":1,essenti:9,bind:[5,1],correspond:6,element:3,inform:[7,9,4],"switch":1,environ:[6,2,8],allow:3,exclus:3,order:6,over:[0,1,8],mission:5,privileg:2,dynam:[0,6,8],entiti:[9,6,3,8],latencybudgetqospolici:3,write:[7,1,6,8],group:5,writerdatalifecycleqospolici:3,runnabl:[3,8],platform:2,window:[2,8],mail:4,main:[5,6],get_writer_qo:6,non:[6,3],good:4,"return":6,thei:3,python:4,initi:1,"enum":1,introduct:0,name:[0,1,6,3,8],userid:[1,6],timeout:6,each:6,found:[7,6,2,3,8],dds_qosprofil:3,compil:[1,2],domain:[7,1,6,3],ne11:4,procedur:2,"static":[0,6],connect:[5,7],dispos:6,variabl:[6,2,8],vortex_v2:2,space:5,message1:[1,6],profil:[0,6,8],unsupport:1,sever:[7,8],reader:[7,6],print:[7,1,6],red:6,integr:5,franc:4,lifespanqospolici:3,infin:3,pub:[7,1,6,3],standard:5,reason:6,base:[1,6,3,9],releas:8,org:[5,3],get_participant_qo:[6,3],prefac:0,ownershipstrengthqospolici:3,wrong:6,ist:[5,4],filter:6,thing:5,length:1,place:[5,6],ddsexcept:6,licens:2,oper:2,get_class:7,arrai:1,qualiti:[0,6,8,9],restrict:6,instruct:[7,3,9],alreadi:[6,2],done:1,wrapper:5,differ:[6,8],idmessag:[1,6],script:[1,6,8],data:[5,7,1,6,9],interact:6,system:[0,6],messag:[1,6],attach:6,similarli:2,create_dataread:[7,6],waitset:[6,8],schema:3,xmln:3,consol:1,option:[6,3],especi:6,tool:[6,2,8],copi:2,dataspac:5,specifi:[9,6,3,8],part:4,ddsutil:[7,6,1,2,3],wchar:1,target:2,provid:[0,1,5,6,8,9],structur:3,publisher_qo:3,str:[7,1],helloworlddatapublish:1,listen:6,qos_exampl:[3,8],packag:0,aforement:9,have:3,need:[5,6,2],equival:[1,6],lic:2,ddsdurabilitykind:[1,6,3],note:9,also:[6,3,8],without:[1,6,3,4],take:6,which:[6,2],singl:6,even:5,begin:9,distribut:[5,6,9],ulong:1,whl:2,long1:6,object:[5,6],discov:[7,6,9],most:[6,2],dds_defaultqos_al:[6,3],"class":[5,0,1,6,8],correctli:2,doc:[6,2],later:2,request:7,uri:3,runtim:1,show:[1,6,3,8],carefulli:5,particip:[1,6,3],register_found_topic_as_loc:7,find:[7,8],xml:[0,6,8],onli:[1,6,3],explicitli:6,locat:[7,3,9],execut:2,copyright:4,gen_info:[7,1,6,3],explain:3,writer:[7,1,6,3],written:[6,8],latenc:5,folder:[1,2],local:[7,6],shapetyp:6,get:7,express:6,nativ:[5,2],cannot:6,requir:[0,6],bat:8,enabl:9,helloworlddata:[1,6],common:6,partit:[6,3],contain:[1,2,3,4,8,9],register_top:[1,6,3],wrote:7,durabilityqospolici:[1,6,3],set:[0,6,2,8],reliabilityqospolici:[1,6,3],datatyp:1,see:[7,6],centric:5,respons:6,livelinessqospolici:3,reserv:4,subject:4,statu:6,wire:[0,1,8],base_nam:3,enumer:8,discoveri:[0,6],state:[7,6],between:5,"import":2,paramet:[7,6,3],attribut:3,altern:6,omg:[5,3,9],kei:6,rostand:4,extens:1,satisfi:2,ushort:1,alon:3,polici:7,audienc:0,instanc:[6,3],logic:5,pdf:2,com:[5,8,4],comment:1,simpli:2,point:9,color:6,overview:[6,9],dispatch:6,linux:[2,8],cp34:2,cp35:2,liabil:4,sarl:4,union:1,trademark:4,empti:1,compon:5,quickli:9,both:[1,3],ani:[1,3],togeth:5,print_var:6,present:2,"case":2,replic:5,servic:[5,0,6,8,9],properti:1,defin:[7,1,6,3,8],exist:[7,6],ddshistorykind:3,gateshead:4,"5th":4,them:[6,9],linkedin:4,topic_qo:3,ddsstatu:6,develop:9,receiv:6,make:[5,6],same:[1,6,3],binari:2,domainparticipant_qo:3,html:[6,2],document:[0,4],higher:5,wheel:0,http:[5,3,4],referenc:3,nest:8,iot:5,upon:6,portal:5,user:[5,6,2,3,9],create_publish:[7,1,6,3],decoupl:5,tstate:7,appropri:2,pip3:2,whole:4,historyqospolici:3,inherit:3,exampl:6,command:2,thi:[1,2,3,4,6,7,9],programm:9,jean:4,woburn:4,usual:2,explan:9,deadlineqospolici:3,protocol:5,just:2,languag:[5,8,9],web:4,struct:1,mask:6,ddslivelinesskind:3,primit:1,ospltesttop:7,dispose_inst:6,cp34m:2,match:6,applic:[5,7,6,9],subscriber_qo:3,ospl_hom:[6,2,8],read:[7,6,8],adlinktech:[5,4],wstring:1,datawriter_qo:3,win_amd64:2,world:[1,6],bit:2,find_top:7,python3:[2,8],specif:[5,6,9],found_top:7,manual:6,either:[6,2],xsd:3,corpor:4,output:1,xsi:3,manag:[5,2],www:[3,4],right:[5,4],acknowledg:4,twitter:4,creation:6,global:5,sampl:[7,6,3,8],get_reader_qo:6,resourcelimitsqospolici:3,avoid:2,octet:1,unit:7,condit:6,reproduc:4,c99:5,refer:[6,8,9],core:6,plu:1,who:9,topic_data_class:[1,6],by_source_timestamp:3,rue:4,example4:[7,8],example2:8,prerequisit:2,example1:[3,8],"throw":6,dcp:[6,8],chapter:1,src:2,about:0,would:6,page:0,idl:[0,6,8],includ:[6,1,2],ospl:[0,8],constructor:1,adlinktech_usa:4,produc:7,subset:3,opensplic:[0,6,8,4],qosprofil:3,"float":1,orsai:4,unregist:6,chang:[6,4],your:[6,2],durabl:3,leverag:5,get_dds_classes_from_idl:[1,6,3],wai:[7,2],support:[5,0,6],vallei:4,all_sampl:6,"long":1,avail:[6,3,4],start:[6,9],interfac:[5,8],low:5,suit:4,"function":5,schemaloc:3,bundl:2,taken:3,link:6,adlink:4,eas:5,made:4,consist:[5,6,3],possibl:9,"default":[6,3],displai:3,below:3,limit:[0,4],ownershipqospolici:3,model:[5,6],featur:[5,8],artifact:0,get_subscriber_qo:[6,3],creat:[7,1,6,3],"int":1,certain:2,"abstract":5,repres:[7,6],"char":1,implement:[5,1],file:6,pip:2,check:2,todo:6,when:7,detail:[1,6,9],field:1,other:[6,8],bool:1,you:6,architectur:5,intend:0,fulli:1,sequenc:[1,6,8],manual_by_particip:3,ddsownershipkind:3,type_nam:7,directori:[7,6,2,3,8],reliabl:[5,1,6,3],descript:[7,6,3,8],portion:5,ddsreliabilitykind:[1,6,3],time:[5,6],hello:[7,1,6]},objtypes:{},objnames:{},filenames:["index","python_idl_mapping","installation","qos_provider","contacts","introduction","dds_entities","topic","examples","preface"],titles:["Python DCPS API Guide","8. Python Generation from IDL","3. Installation","6. Quality of Service (QoS)","9. Contacts & Notices","2. Introduction","5. Python API for Vortex DDS","7. Topic Generation and Discovery","4. Examples","1. Preface"],objects:{},titleterms:{set:3,opensplic:2,appli:3,over:7,qualiti:3,indic:0,topic:[7,6],packag:2,api:[0,6,2,3,9],"static":[7,1],file:[3,8],tabl:0,instal:2,guid:[0,9],idlpp:1,dynam:[7,1],xml:3,datawrit:6,wire:7,depend:2,pattern:6,support:1,system:2,publish:6,discoveri:7,profil:3,intend:9,dcp:[0,2,3,9],subscrib:6,document:2,type:8,wheel:2,sourc:2,run:[1,8],python:[0,1,2,3,6,7,9],vortex:6,gener:[7,1],usag:6,artifact:1,notic:4,from:[1,2],domainparticip:6,"class":[7,3],requir:2,introduct:5,querycondit:6,prefac:9,about:9,name:7,provid:3,setup:2,idl:[7,1],dataread:6,exampl:[2,8],audienc:9,contact:4,limit:1,ospl:2,servic:3}}) \ No newline at end of file diff --git a/docs/html/PythonDCPSAPIGuide/topic.html b/docs/html/PythonDCPSAPIGuide/topic.html new file mode 100644 index 000000000..dc7a63fa2 --- /dev/null +++ b/docs/html/PythonDCPSAPIGuide/topic.html @@ -0,0 +1,183 @@ + + + + + + + + 7. Topic Generation and Discovery — Python DCPS API Guide + + + + + + + + + + + + + + + +
    +
    +
    +
    + +
    +

    7. Topic Generation and Discovery¶

    +

    A DDS Topic represents the unit for information that can be produced or consumed by a DDS application. Topics are defined by a name, a type, and a set of QoS policies.

    +

    The Python DCPS API provides several ways of generating Python classes to represent DDS topics.

    +
    +
      +
    • over the wire discovery
    • +
    • dynamic generation of Python Topic classes using parameters IDL file and topic name
    • +
    • static generation of Python Topic classes using IDL
    • +
    +
    +
    +

    Note

    +
      +
    • The Examples section provides the examples directory location, example descriptions and running instructions.
    • +
    +
    +
    +

    7.1. Over the Wire Discovery¶

    +

    Python topic classes can be generated for existing DDS topics in the DDS system. These topics are “discovered over the wire”.

    +

    The Python classes are generated when the topic is requested by name.

    +

    A code snippet is provided from example4.py. This example finds a topic registered by another process, and reads and writes samples to that topic.

    +

    example4.py

    +
    ...
    +print('Connecting to DDS domain...')
    +dp = dds.DomainParticipant()
    +
    +print('Finding OsplTestTopic...')
    +found_topic = dp.find_topic('OsplTestTopic')
    +
    +print('Registering OsplTestTopic locally')
    +local_topic = ddsutil.register_found_topic_as_local(found_topic)
    +
    +print('Getting Python classes for the found topic...')
    +gen_info = ddsutil.get_dds_classes_for_found_topic(found_topic)
    +OsplTestTopic = gen_info.get_class(found_topic.type_name)
    +Tstate = gen_info.get_class('ospllog::Tstate')
    +
    +print('Creating sample data to write...')
    +data = OsplTestTopic(id=11,index=22, x=1.2, y=2.3, z= 3.4, t=9.8,
    +    state=Tstate.init, description='Hello from Python')
    +
    +print('Creating readers and writers...')
    +pub = dp.create_publisher()
    +wr = pub.create_datawriter(local_topic, found_topic.qos)
    +sub = dp.create_subscriber()
    +rd = sub.create_datareader(local_topic, found_topic.qos)
    +
    +print('Writing sample data...')
    +wr.write(data)
    +print('Wrote: %s' % (str(data)))
    +...
    +
    +
    +
    +
    +

    7.2. Static Generation of Python Topic Classes Using IDL¶

    +

    The Python topic classes can be generated statically using an IDL file. Please see Static Generation for more information.

    +
    +
    +

    7.3. Dynamic Generation of Python Topic Classes Using IDL and Name¶

    +

    The Python topic classes can be generated dynamically using an IDL file, and the topic name. Please see Dynamic Generation for more information.

    +
    +
    + + +
    +
    +
    +
    +
    + +

    Table Of Contents

    + + +

    Previous topic

    +

    6. Quality of Service (QoS)

    +

    Next topic

    +

    8. Python Generation from IDL

    +

    This Page

    + + + +
    +
    +
    +
    + + + + \ No newline at end of file diff --git a/docs/html/RMIGettingStarted/_sources/contacts.txt b/docs/html/RMIGettingStarted/_sources/contacts.txt index c13319efa..d32f6016f 100644 --- a/docs/html/RMIGettingStarted/_sources/contacts.txt +++ b/docs/html/RMIGettingStarted/_sources/contacts.txt @@ -1,49 +1 @@ -.. _`Contacts & Notices`: - -################## -Contacts & Notices -################## - -******** -Contacts -******** - -| **PrismTech Corporation** -| 400 TradeCenter -| Suite 5900 -| Woburn, MA -| 01801 -| USA -| Tel: +1 781 569 5819 - -| **PrismTech Limited** -| PrismTech House -| 5th Avenue Business Park -| Gateshead -| NE11 0NG -| UK -| Tel: +44 (0)191 497 9900 - -| **PrismTech France** -| 28 rue Jean Rostand -| 91400 Orsay -| France -| Tel: +33 (1) 69 015354 - - -Web: http://www.prismtech.com - -E-mail: \info@prismtech.com - -******* -Notices -******* - -**Copyright** © 2016 PrismTech Limited. All rights reserved. - -*This document may be reproduced in whole but not in part. -The information contained in this document is subject to change -without notice and is made available in good faith without -liability on the part of PrismTech Limited or PrismTech Corporation. -All trademarks acknowledged.* - +.. include:: ../../common/contacts.rst diff --git a/docs/html/RMIGettingStarted/_sources/index.txt b/docs/html/RMIGettingStarted/_sources/index.txt index bb7da9e17..e9672fcf6 100644 --- a/docs/html/RMIGettingStarted/_sources/index.txt +++ b/docs/html/RMIGettingStarted/_sources/index.txt @@ -21,7 +21,7 @@ Vortex OpenSplice RMI User Guide qos-policies contacts - + Indices and tables ================== diff --git a/docs/html/RMIGettingStarted/_sources/language-map.txt b/docs/html/RMIGettingStarted/_sources/language-map.txt index 16f007206..62d884992 100644 --- a/docs/html/RMIGettingStarted/_sources/language-map.txt +++ b/docs/html/RMIGettingStarted/_sources/language-map.txt @@ -143,6 +143,14 @@ IDL sequences are mapped as specified by the DDS standard. string DDS::String =================== ============== +|caution| |cpp| + Please be aware that the RMI middleware assumes ownership of any + ``DDS::String`` that is provided to it (either by an in/inout argument + or return value). This also means that it'll free the given string. This + can cause issues when the application keeps using the provided string after + the RMI call or if RMI is called with a const string literal. It is advised + to apply ``DDS::string_dup(str)`` when using strings in conjunction with + RMI. This is also applicable to sequences of strings. diff --git a/docs/html/RMIGettingStarted/_sources/runtime-config.txt b/docs/html/RMIGettingStarted/_sources/runtime-config.txt index 3ba485cf7..6076ea731 100644 --- a/docs/html/RMIGettingStarted/_sources/runtime-config.txt +++ b/docs/html/RMIGettingStarted/_sources/runtime-config.txt @@ -30,7 +30,7 @@ RMIServiceDiscoveryTimeout option This is a client-side option that specifies the maximum duration (in seconds) that a client application can wait to find services. -It influences the execution time of the DDS_Service.getServerProxy +It influences the execution time of the DDS_Service.getServerProxy operation that is used to find a given service. The default value is set to 10 seconds. The need to set this value may come from some specific deployment environements with bad communication conditions. @@ -41,7 +41,7 @@ RMIServerThreadingModel option ``--RMIServerThreadingModel=ST | MT | TPS [,]`` -This is a server-side option that specifies the threading policy of +This is a server-side option that specifies the threading policy of the server runtime including the threading policy name and the thread pool size. **ST** selects *Single Threaded* policy. @@ -79,8 +79,8 @@ RMIDurability option .. [[!! DEVELOPMENT NOTE: Check status of this feature on each release !! !!]] - -|cpp| + +|cpp| ``--RMIDurability = yes | no`` @@ -90,16 +90,16 @@ underlying DDS middleware support the non-default durability Qos policies By default, this option value is ``yes``. -RMI servers uses non-volatile topics for services advertising to allow -late-joining clients to discover them. This option is useful for adapting -services registration and discovery mechanisms when the durability support +RMI servers uses non-volatile topics for services advertising to allow +late-joining clients to discover them. This option is useful for adapting +services registration and discovery mechanisms when the durability support is missing in the underlying DDS middleware. |caution| - Note that this feature must be *either* enabled *or* disabled for *all* of - the RMI applications in a given DDS domain. It means that durability-*en*abled - (option value is ``yes``) RMI applications cannot be deployed with - durability-*dis*abled (option value is ``no``) RMI applications in + Note that this feature must be *either* enabled *or* disabled for *all* of + the RMI applications in a given DDS domain. It means that durability-*en*abled + (option value is ``yes``) RMI applications cannot be deployed with + durability-*dis*abled (option value is ``no``) RMI applications in the same DDS domain. @@ -109,8 +109,8 @@ RMIClientSchedulingModel option |caution| **Note**: The ``RMIClientSchedulingModel`` option is currently *only* implemented for *Java*. - - + + .. [[!! DEVELOPMENT NOTE: Check status of this feature on each release !! !!]] @@ -124,6 +124,30 @@ by OpenSplice RMI at the client side, including the AsyncWaiter thread, which is one that waits for asynchronous replies. +******************************* +RMILegacyTopicNames option +******************************* +|caution| + **Note**: The ``RMILegacyTopicNames`` option applies *only* to *C++*. + +|cpp| + +``--RMILegacyTopicNames = yes | no`` + +This client- and server-side option allows to switch topic names between a legacy-mode +and a Java-compatible mode. + +In legacy-mode, topics are named ``DDS_ServiceDefinition`` and +``DDS_ServiceIdentification``. In this mode, a C++ RMI client or server is compatible +with previous releases of C++ RMI. Since Java RMI uses different topic names, a C++ +RMI client cannot communicate with a Java RMI server (or vice-versa). This is the +default behaviour. + +When legacy-mode is disabled, topics are named ``DDS_RMIDefinition`` and +``DDS_RMIIdentification``. This enables compatibility with Java RMI which has always +used these topic names, but unfortunately doesn't allow communication with older +versions of C++ RMI that don't support this option. + .. |caution| image:: ./images/icon-caution.* :height: 6mm .. |info| image:: ./images/icon-info.* @@ -143,4 +167,4 @@ one that waits for asynchronous replies. .. |java| image:: ./images/icon-java.* :height: 6mm - + diff --git a/docs/html/RMIGettingStarted/build-rmi-apps.html b/docs/html/RMIGettingStarted/build-rmi-apps.html index df8e8d7f9..36667153b 100644 --- a/docs/html/RMIGettingStarted/build-rmi-apps.html +++ b/docs/html/RMIGettingStarted/build-rmi-apps.html @@ -996,7 +996,7 @@

    Navigation

    \ No newline at end of file diff --git a/docs/html/RMIGettingStarted/contacts.html b/docs/html/RMIGettingStarted/contacts.html index df8fb4df5..411c0ae7d 100644 --- a/docs/html/RMIGettingStarted/contacts.html +++ b/docs/html/RMIGettingStarted/contacts.html @@ -50,7 +50,7 @@

    Navigation

    9.1. Contacts¶

    -
    PrismTech Corporation
    +
    ADLINK Technology Corporation
    400 TradeCenter
    Suite 5900
    Woburn, MA
    @@ -59,32 +59,35 @@

    9.1. ContactsTel: +1 781 569 5819

    -
    PrismTech Limited
    -
    PrismTech House
    -
    5th Avenue Business Park
    +
    ADLINK Technology Limited
    +
    The Edge
    +
    5th Avenue
    +
    Team Valley
    Gateshead
    -
    NE11 0NG
    +
    NE11 0XA
    UK
    Tel: +44 (0)191 497 9900
    -
    PrismTech France
    +
    ADLINK Technology SARL
    28 rue Jean Rostand
    91400 Orsay
    France
    Tel: +33 (1) 69 015354
    -

    Web: http://www.prismtech.com

    -

    E-mail: info@prismtech.com

    +

    Web: http://ist.adlinktech.com/

    +

    Contact: http://ist.adlinktech.com

    +

    E-mail: ist_info@adlinktech.com

    +

    LinkedIn: https://www.linkedin.com/company/79111/

    +

    Twitter: https://twitter.com/ADLINKTech_usa

    +

    Facebook: https://www.facebook.com/ADLINKTECH

    9.2. Notices¶

    -

    Copyright © 2016 PrismTech Limited. All rights reserved.

    -

    This document may be reproduced in whole but not in part. -The information contained in this document is subject to change -without notice and is made available in good faith without -liability on the part of PrismTech Limited or PrismTech Corporation. -All trademarks acknowledged.

    +

    Copyright © 2018 ADLINK Technology Limited. All rights reserved.

    +

    This document may be reproduced in whole but not in part. The information contained in this +document is subject to change without notice and is made available in good faith without +liability on the part of ADLINK Technology Limited. All trademarks acknowledged.

    @@ -144,7 +147,7 @@

    Navigation

    \ No newline at end of file diff --git a/docs/html/RMIGettingStarted/genindex.html b/docs/html/RMIGettingStarted/genindex.html index 550aff7c2..610efa86b 100644 --- a/docs/html/RMIGettingStarted/genindex.html +++ b/docs/html/RMIGettingStarted/genindex.html @@ -88,7 +88,7 @@

    Navigation

    \ No newline at end of file diff --git a/docs/html/RMIGettingStarted/index.html b/docs/html/RMIGettingStarted/index.html index 8aed45cc1..029a6a2e3 100644 --- a/docs/html/RMIGettingStarted/index.html +++ b/docs/html/RMIGettingStarted/index.html @@ -88,6 +88,7 @@

    Vortex OpenSplice RMI User Guide7.4. RMIServerSchedulingModel option
  • 7.5. RMIDurability option
  • 7.6. RMIClientSchedulingModel option
  • +
  • 7.7. RMILegacyTopicNames option
  • 8. QoS policies XML schema
  • @@ -161,7 +162,7 @@

    Navigation

    \ No newline at end of file diff --git a/docs/html/RMIGettingStarted/introduction.html b/docs/html/RMIGettingStarted/introduction.html index ecbad07e1..fb30ad832 100644 --- a/docs/html/RMIGettingStarted/introduction.html +++ b/docs/html/RMIGettingStarted/introduction.html @@ -165,7 +165,7 @@

    Navigation

    \ No newline at end of file diff --git a/docs/html/RMIGettingStarted/language-map.html b/docs/html/RMIGettingStarted/language-map.html index 7b3b8be85..09599b90c 100644 --- a/docs/html/RMIGettingStarted/language-map.html +++ b/docs/html/RMIGettingStarted/language-map.html @@ -159,6 +159,16 @@

    5.3. Mapping for basic types +
    caution cpp
    +
    Please be aware that the RMI middleware assumes ownership of any +DDS::String that is provided to it (either by an in/inout argument +or return value). This also means that it’ll free the given string. This +can cause issues when the application keeps using the provided string after +the RMI call or if RMI is called with a const string literal. It is advised +to apply DDS::string_dup(str) when using strings in conjunction with +RMI. This is also applicable to sequences of strings.
    +

    @@ -225,7 +235,7 @@

    Navigation

    \ No newline at end of file diff --git a/docs/html/RMIGettingStarted/preface.html b/docs/html/RMIGettingStarted/preface.html index 205ea97c2..762ff33f1 100644 --- a/docs/html/RMIGettingStarted/preface.html +++ b/docs/html/RMIGettingStarted/preface.html @@ -186,7 +186,7 @@

    Navigation

    \ No newline at end of file diff --git a/docs/html/RMIGettingStarted/qos-policies.html b/docs/html/RMIGettingStarted/qos-policies.html index 73ba0cf25..1d038d5e1 100644 --- a/docs/html/RMIGettingStarted/qos-policies.html +++ b/docs/html/RMIGettingStarted/qos-policies.html @@ -378,7 +378,7 @@

    Navigation

    \ No newline at end of file diff --git a/docs/html/RMIGettingStarted/rmi-over-dds.html b/docs/html/RMIGettingStarted/rmi-over-dds.html index 70e3e5aab..44a8258b9 100644 --- a/docs/html/RMIGettingStarted/rmi-over-dds.html +++ b/docs/html/RMIGettingStarted/rmi-over-dds.html @@ -177,7 +177,7 @@

    Navigation

    \ No newline at end of file diff --git a/docs/html/RMIGettingStarted/runtime-config.html b/docs/html/RMIGettingStarted/runtime-config.html index 87f2ffef6..9622f43fb 100644 --- a/docs/html/RMIGettingStarted/runtime-config.html +++ b/docs/html/RMIGettingStarted/runtime-config.html @@ -130,6 +130,26 @@

    7.6. RMIClientSchedulingModel option +

    7.7. RMILegacyTopicNames option¶

    +
    +
    caution
    +
    Note: The RMILegacyTopicNames option applies only to C++.
    +
    +

    cpp

    +

    --RMILegacyTopicNames = yes | no

    +

    This client- and server-side option allows to switch topic names between a legacy-mode +and a Java-compatible mode.

    +

    In legacy-mode, topics are named DDS_ServiceDefinition and +DDS_ServiceIdentification. In this mode, a C++ RMI client or server is compatible +with previous releases of C++ RMI. Since Java RMI uses different topic names, a C++ +RMI client cannot communicate with a Java RMI server (or vice-versa). This is the +default behaviour.

    +

    When legacy-mode is disabled, topics are named DDS_RMIDefinition and +DDS_RMIIdentification. This enables compatibility with Java RMI which has always +used these topic names, but unfortunately doesn’t allow communication with older +versions of C++ RMI that don’t support this option.

    + @@ -150,6 +170,7 @@

    Table Of Contents

  • 7.4. RMIServerSchedulingModel option
  • 7.5. RMIDurability option
  • 7.6. RMIClientSchedulingModel option
  • +
  • 7.7. RMILegacyTopicNames option
  • @@ -198,7 +219,7 @@

    Navigation

    \ No newline at end of file diff --git a/docs/html/RMIGettingStarted/search.html b/docs/html/RMIGettingStarted/search.html index 54e679ffa..383f8d7cc 100644 --- a/docs/html/RMIGettingStarted/search.html +++ b/docs/html/RMIGettingStarted/search.html @@ -95,7 +95,7 @@

    Navigation

    \ No newline at end of file diff --git a/docs/html/RMIGettingStarted/searchindex.js b/docs/html/RMIGettingStarted/searchindex.js index bffae48dc..432fd2c3e 100644 --- a/docs/html/RMIGettingStarted/searchindex.js +++ b/docs/html/RMIGettingStarted/searchindex.js @@ -1 +1 @@ -Search.setIndex({envversion:42,terms:{all:[1,2,3,4,5,7,8],code:[1,4],destinationorderqospolici:[7,1],skeleton:1,definit:[3,1,4],particular:1,focus:4,greet_request:1,prefix:1,concept:3,by_source_timestamp_destinationorder_qo:[7,1],abil:[3,1],schedulingpolici:1,follow:[9,1,4],forget:9,whose:1,decid:1,depend:1,strongli:1,xml:[0,1,6],qos_fil:1,client_impl:5,present:1,jvm:1,keylist:[7,5],best_effort_reliability_qo:7,sent:9,helloservice_interfac:1,sourc:[1,4],string:[7,5,1,4],"void":[5,1,4],getserverproxi:[8,1],mechan:[3,8],whether:[8,1],failur:[1,9],veri:3,relev:[6,1,4],level:3,signific:6,helloworld:[5,1],"try":1,item:6,println:1,refer:[6,1,4],initialis:1,librari:[1,9],targetnamespac:7,pleas:[1,4],prevent:9,impli:[5,1,6],tel:2,natur:3,direct:1,second:[8,1,4],design:1,keep_all_history_qo:7,pass:[8,1,4],even:[3,1],corba:[3,1,9],hide:9,insid:1,repli:[1,4,3,5,8,9],section:[8,1],abl:[8,4],invok:[3,9,1,4],current:[8,1],getdds_serviceinterfac:1,history_depth:7,"new":[5,1],ever:9,method:[3,9,1,4],whatev:1,involv:6,prismtech:2,full:1,scedul:1,asynch_greet:1,getserverschedulingpolici:1,usag:1,gener:[3,9,6,1,4],here:1,behaviour:1,solari:6,ubuntu:6,path:1,strong:3,valu:[7,5,8,1,9],wait:[5,8,1,9],schedulingprior:1,search:0,technolog:3,step:[1,6],prior:1,within:1,pick:5,destinationorderkind:[7,1],subsect:1,semant:1,via:[3,1],regardless:1,appli:[1,6],modul:[5,1,9],avenu:2,unix:6,"boolean":[1,4],select:[8,1],from:[3,9,8,1,4],describ:[8,1,6],usa:2,commun:[3,8,9],doubl:4,regist:1,two:[6,5,1,4],next:1,handler:[5,1,4],call:[1,9],tradecent:2,transportpriorityqospolici:7,recommend:1,taken:6,scope:5,threadingpolicykind:1,type:[0,1],until:[1,9],more:[3,9,1,4],valuetyp:1,relat:[3,1],enhanc:[3,1],accept:1,cruntim:1,known:3,hold:9,rmipp:[9,1,4],must:[8,1],high:9,join:8,hous:2,interfaces_fil:1,work:1,uniqu:[3,1],other:1,can:[3,6,8,1,4],purpos:9,helloservic:[5,1,4],control:[3,1],defer:1,give:[3,6],process:[3,1],registr:[3,8,1],bad_param:1,topic:[0,1,3,6,7,8,9],caution:6,unsign:4,rmiclientthreadingmodel:[0,1],mix:[3,1],cours:[1,9],multipl:1,programmat:1,anoth:3,write:[1,9],how:[1,6],shared_ownership_qo:7,reject:1,iso:1,simpl:[3,1,9],transient_local_durability_qo:7,longlong:4,ne11:2,product:3,resourc:1,usabl:1,service_not_found:1,diagram:4,befor:1,cruntime_ref:1,mai:[8,1,2],shared_ptr:1,setserverschedulingpolici:1,parallel:1,demonstr:5,alloc:1,"short":[5,1,4],attempt:1,rmidur:0,bind:0,correspond:[9,1,4],greet:1,assign:1,issu:3,callback:[9,1,4],combin:3,allow:[8,1],order:1,publish:6,help:6,over:[3,0,1,6],xmlschema:[7,1],becaus:1,privileg:1,pointer:1,dynam:3,paramet:[9,5,1,4],latencybudgetqospolici:[7,1],snippet:1,thank:3,dds_serviceinterface_ref:1,fix:9,async_:[1,4],late:8,platform:1,window:6,complex:1,infrastructur:1,onc:[1,9],mail:2,main:1,serverthreadingpolici:1,non:[9,8,1,4],good:[1,2],"return":[9,5,1,4],thei:[3,1,9],handl:[9,5,1,4],safe:1,initi:1,mention:1,keymemb:7,unregist:1,introduct:0,reliabilitykind:[7,1],term:1,name:[1,4,3,5,7,8,9],framework:[3,1,9],achiev:3,timeout:1,each:[9,5,1,4],found:1,complet:[1,9],side:[8,1,9],mean:[8,1,6],map:[3,0,1],procedur:1,"static":1,expect:1,client_inst:5,orient:[3,9],special:[1,6],out:[5,1,4],dds_servic:[8,1],shown:[9,1,6],safeti:1,network:3,space:[3,1],influenc:8,ret:1,adapt:8,rel:1,reader:6,ref:7,franc:2,qualifi:7,proxi:[1,4],lifespanqospolici:7,differ:[9,1,4],argv:1,standard:4,base:[7,6,1,4],async_greet:1,releas:1,org:[7,1],"byte":4,argc:1,care:[1,9],prefac:0,capabl:[1,9],myinterfaceinterfac:1,could:[1,9],keep:1,length:1,place:1,onto:[1,9],top:3,first:[6,1,4],oper:[0,1],suffix:5,directli:8,busi:[1,2],exchang:[3,1],arrai:1,qualiti:[3,1,9],number:1,restrict:[7,1],instruct:1,done:1,miss:8,size:[8,1],given:[8,1],convent:0,data:[3,5,1],interact:[3,1,6],system:[3,1,6],messag:9,greet_req:1,scheme:3,"final":[3,1,9],exclusive_ownership_qo:7,request_head:5,xmln:[7,1],option:[0,1,6],relationship:9,namespac:1,park:2,setserverthreadingpolici:1,specifi:[8,1,4],part:[2,1,4],pragma:5,set_prior:1,than:3,std:1,kind:[3,1],conveni:1,target:[3,1],remot:[3,9,6,4],remov:1,requir:[7,1,6],structur:5,were:1,transient_loc:8,minut:1,schema:[0,1,6],livelinesskind:7,pre:[1,9],"_request":5,arg:1,ani:[3,1],fail:1,by_reception_timestamp_destinationorder_qo:7,expir:[3,1],have:[3,9,1,4],deliv:[1,9],need:[3,8,1,6],element:7,nanosec:[7,1],qoss:3,depict:4,inform:[3,6,2,1,4],latter:[1,4],note:[8,1],also:[1,4],exampl:1,take:[6,1,4],indic:1,environ:[8,1,9],ulonglong:4,instanci:1,maxoccur:7,regard:1,distribut:[3,1],ulong:4,deploy:[3,8,1],object:[9,1,4],discov:8,connot:3,deploi:8,helloworld_helloservice_greet_reply_handl:1,"class":[9,1,4],icon:6,tradit:9,woburn:2,connectionless:3,getdefaultruntim:1,later:1,request:[3,5,1,9],drive:5,doe:[1,9],durabilitykind:[7,1],declar:[3,6,5,1,4],helloserv:1,pattern:3,notion:1,inout:[5,1,4],show:[6,1,4],concurr:1,dll:1,fine:3,find:[3,8],transport:1,cout:1,impact:3,onli:[6,8,1,4],locat:[3,1],copyright:2,greet_repli:[1,4],explain:6,configur:[3,0,1,6],activ:1,enough:1,should:[1,4],version:[7,1],templat:1,schedule_default:1,local:[9,5,1,4],entrant:1,"_topic":1,move:3,variou:3,get:[1,4],express:3,nativ:3,cannot:[8,1,9],lifespan:9,initial_inst:7,him:9,historykind:7,enabl:[3,5,8,1,9],borrow:1,"public":[3,1,4],provid:[3,9,6,1,4],bad:8,getserverthreadingpolici:1,organis:6,contain:[6,2,1,4],through:[3,9],where:[9,5,1,6],setup:9,respond:1,durabilityqospolici:[7,1],set:[9,8,1,4],reliabilityqospolici:[7,1],knowledg:1,asyncwait:8,see:1,centric:3,sec:[7,1],result:1,respons:1,livelinessqospolici:7,reserv:2,subject:2,extend:1,vari:1,someth:3,enumer:7,discoveri:[3,8],figur:[9,4],won:1,volatil:8,"0ng":2,transient_durability_qo:7,"import":1,entiti:1,attribut:7,accord:3,omg:[7,1,4],kei:0,rostand:2,empt:1,complementari:3,toler:3,max_samples_per_inst:7,come:[8,1,4],endl:1,addit:[3,1],both:[1,9],protect:1,fault:3,howev:1,ushort:4,audienc:6,instanc:[1,9],improv:9,com:2,comment:1,among:1,instanti:1,dispatch:1,header:1,exploit:1,featur:0,shutdown:1,suppli:1,respect:[5,8,1],rmiclientschedulingmodel:0,guid:1,advertis:8,liabil:2,java:[0,1,2,3,4,5,6,7,8,9],union:1,trademark:2,three:1,been:[3,9],compon:0,basic:[0,1],immedi:1,quickli:6,op1_repli:5,persistent_durability_qo:[7,1],rather:9,fire:9,persist:3,"catch":1,schedule_timeshar:1,those:3,"case":1,"char":[1,4],multi:[8,1],ident:3,durat:[7,8,1,9],defin:[9,1,4],"while":3,op1_request:5,abov:[8,1],error:1,rmiserverschedulingmodel:0,spawn:1,real:[3,9],layer:[1,6],gateshead:2,advantag:6,"5th":2,henc:[1,4],them:[8,1],itself:1,topic_qo:[7,1],incom:1,automatic_liveliness_qo:7,"null":1,develop:[9,1,6],helloservice_top:1,perform:[3,1,9],make:1,format:1,same:[3,5,8,1,4],drawback:1,document:2,higher:[3,1],finish:1,http:[7,1,2],wherea:1,fairli:1,rais:1,user:1,nonnegativeinteg:7,typic:[3,1],tune:[1,9],rmiserverthreadingmodel:0,task:1,onewai:[9,1,4],macro:1,thu:1,well:[9,1,4],historyqospolici:7,without:[3,1,2],s_polici:1,thi:[1,2,4,5,6,8,9],choos:1,jean:2,paradigm:[3,6],deadlineqospolici:7,identifi:[3,1,6],op1:5,execut:[3,8,1],dds_serviceinterfac:1,t_polici:1,dds_rmi:[5,1],timeshar:1,fact:1,languag:[0,1],previous:4,web:2,struct:[5,1],easi:3,hint:[1,6],helloserviceinterfaceproxi:[1,4],mygreetreplyhandl:1,priorit:3,except:1,"_repli":5,interfacenam:5,subsequ:1,smart:1,ami:9,ownershipkind:7,which:[8,1],transpar:3,read:9,intuit:9,burden:3,associ:[3,5],rmiservicediscoverytimeout:0,success:[1,9],realtim:1,manual:3,positiveinteg:7,vortex:[1,2],api:[3,1,9],singl:[8,1],xsd:[7,1],corpor:2,output:1,xsi:1,setprior:1,page:0,req_info:5,underli:[3,8,1,9],www:[7,1,2],right:2,often:3,acknowledg:2,linux:6,some:[8,1,4],back:9,helloservice_impl:1,global:3,intern:1,sampl:1,proper:1,guarante:1,mainli:1,avoid:1,normal:1,octet:4,benefit:0,keep_last_history_qo:7,whole:2,exit:1,middlewar:[3,8,1,9],condit:8,reproduc:2,either:[8,1],schedule_realtim:1,core:9,greetrepli:1,run:1,power:9,efer:1,helloserviceinterfac:[1,4],rue:2,host:1,obei:4,complextyp:7,dcp:[3,7,1,9],timebasedfilterqospolici:7,chapter:[6,5,8,1,4],faith:2,most:4,initial_sampl:7,idltyp:[7,1],idl:[6,9,5,1,4],includ:[3,8,1,9],disabl:[8,1],block:[1,9],durabilityserviceqospolici:7,opensplic:[1,2],idlfil:[7,1],"float":4,encod:[7,1],orsai:2,my_domain_id:1,down:1,manual_by_topic_liveliness_qo:7,ensur:1,chang:[1,2],durabl:8,per:[8,1],processor:[1,9],wai:1,support:[8,1],transform:5,"long":[5,1,4],avail:[9,6,1,2],interfac:[0,1],inner:4,suit:2,greet_reply_handl:[1,4],"function":[1,4],schemaloc:1,form:4,subscrib:6,register_interfac:1,client_id:5,line:[8,1,6],highest:1,"true":1,info:2,concaten:[1,4],made:[5,1,2],utf:7,possibl:1,"default":[7,8,1],maximum:8,helloservice_interfaceproxi:1,below:[6,1,4],ddsrmi:1,limit:[1,2],"export":[3,1],ownershipqospolici:7,similar:[1,9],impl:1,topicdataqospolici:7,gather:5,reliable_reliability_qo:[7,1],creat:[5,8,1],"int":[1,4],"abstract":[3,4],command:[3,8,1,6],repres:[1,4],simpletyp:7,exist:1,file:[6,1,4],shut:1,volatile_durability_qo:7,stimulu:3,dll_macro_nam:1,hpp:1,when:[9,8,1,6],detail:8,virtual:1,valid:9,bool:1,resourcelimitsqospolici:7,you:1,base64binari:7,elementformdefault:7,intend:[1,6],sequenc:[7,1,4],manual_by_participant_liveliness_qo:7,meaning:1,threadpools:1,unbound:7,minoccur:7,pool:[8,1],max_sampl:7,reduc:1,receiv:[1,9],longer:1,algorithm:1,directori:1,reliabl:1,rule:[0,9,6,1,4],depth:7,max_inst:7,time:[3,8,1,9],cpp:1,getruntim:1},objtypes:{},objnames:{},filenames:["index","build-rmi-apps","contacts","introduction","language-map","topics-maps","preface","qos-policies","runtime-config","rmi-over-dds"],titles:["Vortex OpenSplice RMI User Guide","4. Building an RMI Application","9. Contacts & Notices","2. Introduction","5. Language mapping for Vortex OpenSplice RMI","6. RMI Interface to DDS topics mapping rules","1. Preface","8. QoS policies XML schema","7. RMI Runtime Configuration Options","3. Vortex OpenSplice RMI over DDS"],objects:{},titleterms:{compil:1,oper:4,domain:1,featur:3,synchron:1,opensplic:[0,9,4],applic:1,schedul:1,over:9,indic:0,rmiservicediscoverytimeout:8,tabl:0,rmiclientschedulingmodel:8,guid:[0,6],languag:[9,4],prioriti:1,xml:7,rmi:[0,1,4,5,6,8,9],convent:6,polici:[7,1],configur:8,vortex:[0,9,4],client:1,compon:9,start:1,program:1,interfac:[5,4],build:1,option:8,basic:4,type:4,invoc:1,mode:1,map:[5,4],rmiclientthreadingmodel:8,kei:9,rmiserverthreadingmodel:8,stop:1,notic:2,multithread:1,schema:7,user:[0,6],implement:1,introduct:3,topic:5,about:[1,6],specif:1,thread:1,rmidur:8,bind:9,servic:1,descript:1,rule:5,server:1,asynchron:1,benefit:3,contact:2,runtim:[8,1],model:1,prefac:6,rmiserverschedulingmodel:8}}) \ No newline at end of file +Search.setIndex({envversion:42,terms:{all:[1,2,3,4,5,7,8],code:[1,4],destinationorderqospolici:[7,1],skeleton:1,definit:[3,1,4],particular:1,focus:4,greet_request:1,prefix:1,concept:3,by_source_timestamp_destinationorder_qo:[7,1],abil:[3,1],schedulingpolici:1,follow:[9,1,4],edg:2,whose:1,decid:1,depend:1,strongli:1,xml:[0,1,6],qos_fil:1,client_impl:5,present:1,jvm:1,keylist:[7,5],ist_info:2,sent:9,helloservice_interfac:1,sourc:[1,4],string:[7,5,1,4],"void":[5,1,4],getserverproxi:[8,1],facebook:2,whether:[8,1],failur:[1,9],veri:3,relev:[6,1,4],level:3,signific:6,helloworld:[5,1],"try":1,item:6,team:2,println:1,refer:[6,1,4],initialis:1,librari:[1,9],targetnamespac:7,pleas:[1,4],prevent:9,impli:[5,1,6],tel:2,natur:3,direct:1,second:[8,1,4],greetrepli:1,design:1,keep_all_history_qo:7,pass:[8,1,4],durat:[7,8,1,9],even:[3,1],corba:[3,1,9],hide:9,insid:1,repli:[1,4,3,5,8,9],section:[8,1],abl:[8,4],invok:[3,9,1,4],current:[8,1],getdds_serviceinterfac:1,history_depth:7,"new":[5,1],ever:9,method:[3,9,1,4],whatev:1,involv:6,full:1,scedul:1,asynch_greet:1,getserverschedulingpolici:1,usag:1,gener:[3,9,6,1,4],here:1,behaviour:[8,1],argv:1,solari:6,ubuntu:6,"const":4,"0xa":2,strong:3,sinc:8,valu:[1,4,5,7,8,9],wait:[5,8,1,9],schedulingprior:1,search:0,technolog:[3,2],step:[1,6],prior:1,within:1,pick:5,destinationorderkind:[7,1],mix:[3,1],subsect:1,semant:1,via:[3,1],regardless:1,appli:[6,8,1,4],modul:[5,1,9],avenu:2,unix:6,"boolean":[1,4],select:[8,1],from:[3,9,8,1,4],describ:[8,1,6],usa:2,commun:[3,8,9],doubl:4,regist:1,two:[6,5,1,4],next:1,handler:[5,1,4],call:[9,1,4],tradecent:2,transportpriorityqospolici:7,recommend:1,taken:6,scope:5,threadingpolicykind:1,type:[0,1],until:[1,9],more:[3,9,1,4],valuetyp:1,relat:[3,1],enhanc:[3,1],accept:1,cruntim:1,known:3,compani:2,hold:9,rmipp:[9,1,4],must:[8,1],high:9,join:8,interfaces_fil:1,work:1,uniqu:[3,1],other:1,can:[3,6,8,1,4],purpos:9,helloservic:[5,1,4],control:[3,1],defer:1,give:[3,6],process:[3,1],registr:[3,8,1],bad_param:1,topic:[0,1,3,6,7,8,9],liter:4,caution:6,keep:[1,4],unsign:4,rmiclientthreadingmodel:[0,1],alwai:8,cours:[1,9],multipl:1,programmat:1,anoth:3,write:[1,9],how:[1,6],shared_ownership_qo:7,reject:1,iso:1,simpl:[3,1,9],longlong:4,ne11:2,product:3,resourc:1,after:4,usabl:1,service_not_found:1,diagram:4,befor:1,cruntime_ref:1,mai:[8,1,2],shared_ptr:1,setserverschedulingpolici:1,parallel:1,demonstr:5,alloc:1,"short":[5,1,4],attempt:1,rmidur:0,bind:0,correspond:[9,1,4],greet:1,assign:1,issu:[3,4],callback:[9,1,4],"switch":8,combin:3,allow:[8,1],mechan:[3,8],dds_servicedefinit:8,order:1,publish:6,help:6,over:[3,0,1,6],xmlschema:[7,1],becaus:1,privileg:1,pointer:1,dynam:3,paramet:[9,5,1,4],latencybudgetqospolici:[7,1],snippet:1,conjunct:4,thank:3,dds_serviceinterface_ref:1,fix:9,async_:[1,4],late:8,platform:1,window:6,complex:1,infrastructur:1,onc:[1,9],mail:2,main:1,serverthreadingpolici:1,non:[9,8,1,4],good:[1,2],"return":[9,5,1,4],thei:[3,1,9],handl:[9,5,1,4],safe:1,initi:1,mention:1,keymemb:7,unregist:1,introduct:0,reliabilitykind:[7,1],term:1,name:[1,4,3,5,7,8,9],framework:[3,1,9],achiev:3,timeout:1,each:[9,5,1,4],found:1,complet:[1,9],side:[8,1,9],mean:[6,8,1,4],map:[3,0,1],procedur:1,"static":1,expect:1,client_inst:5,orient:[3,9],special:[1,6],out:[5,1,4],dds_servic:[8,1],shown:[9,1,6],unbound:7,network:3,space:[3,1],influenc:8,transient_local_durability_qo:7,adapt:8,rel:1,reader:6,ref:7,franc:2,qualifi:7,proxi:[1,4],lifespanqospolici:7,given:[8,1,4],free:4,standard:4,base:[7,6,1,4],async_greet:1,releas:[8,1],org:[7,1],"byte":4,argc:1,care:[1,9],prefac:0,capabl:[1,9],myinterfaceinterfac:1,could:[1,9],ist:2,length:1,place:1,onto:[1,9],top:3,first:[6,1,4],oper:[0,1],suffix:5,directli:8,busi:1,exchang:[3,1],arrai:1,qualiti:[3,1,9],number:1,restrict:[7,1],instruct:1,set:[9,8,1,4],done:1,miss:8,size:[8,1],differ:[9,8,1,4],convent:0,data:[3,5,1],interact:[3,1,6],system:[3,1,6],messag:9,greet_req:1,which:[8,1],scheme:3,"final":[3,1,9],schema:[0,1,6],request_head:5,xmln:[7,1],option:[0,1,6],relationship:9,namespac:1,setserverthreadingpolici:1,specifi:[8,1,4],part:[2,1,4],pragma:5,set_prior:1,than:3,std:1,kind:[3,1],conveni:1,target:[3,1],remot:[3,9,6,4],remov:1,onewai:[9,1,4],requir:[7,1,6],structur:5,str:4,were:1,transient_loc:8,minut:1,exclusive_ownership_qo:7,livelinesskind:7,pre:[1,9],"_request":5,arg:1,ani:[3,1,4],fail:1,by_reception_timestamp_destinationorder_qo:7,expir:[3,1],have:[3,9,1,4],deliv:[1,9],need:[3,8,1,6],element:7,nanosec:[7,1],caus:4,qoss:3,depict:4,dds_serviceidentif:8,inform:[3,6,2,1,4],latter:[1,4],note:[8,1],also:[1,4],exampl:1,take:[6,1,4],indic:1,environ:[8,1,9],ulonglong:4,instanci:1,maxoccur:7,compat:8,regard:1,distribut:[3,1],ulong:4,deploy:[3,8,1],object:[9,1,4],discov:8,connot:3,deploi:8,helloworld_helloservice_greet_reply_handl:1,"class":[9,1,4],icon:6,tradit:9,woburn:2,don:8,connectionless:3,getdefaultruntim:1,later:1,request:[3,5,1,9],drive:5,doe:[1,9],durabilitykind:[7,1],declar:[3,6,5,1,4],helloserv:1,pattern:3,notion:1,inout:[5,1,4],show:[6,1,4],concurr:1,dll:1,fine:3,find:[3,8],transport:1,cout:1,impact:3,onli:[6,8,1,4],locat:[3,1],copyright:2,greet_repli:[1,4],explain:6,configur:[3,0,1,6],activ:1,enough:1,should:[1,4],best_effort_reliability_qo:7,version:[7,8,1],templat:1,schedule_default:1,local:[9,5,1,4],"_topic":1,move:3,variou:3,get:[1,4],express:3,nativ:3,cannot:[8,1,9],lifespan:9,initial_inst:7,him:9,historykind:7,enabl:[3,5,8,1,9],rmilegacytopicnam:0,borrow:1,"public":[3,1,4],provid:[3,9,6,1,4],bad:8,getserverthreadingpolici:1,organis:6,contain:[6,2,1,4],through:[3,9],where:[9,5,1,6],setup:9,respond:1,durabilityqospolici:[7,1],legaci:8,reliabilityqospolici:[7,1],knowledg:1,asyncwait:8,see:1,centric:3,sec:[7,1],result:1,respons:1,livelinessqospolici:7,reserv:2,subject:2,awar:4,extend:1,vari:1,someth:3,enumer:7,discoveri:[3,8],figur:[9,4],won:1,volatil:8,entrant:1,between:8,transient_durability_qo:7,"import":1,entiti:1,attribut:7,accord:3,omg:[7,1,4],kei:0,rostand:2,empt:1,complementari:3,toler:3,max_samples_per_inst:7,come:[8,1,4],endl:1,addit:[3,1],both:[1,9],protect:1,fault:3,howev:1,ushort:4,audienc:6,instanc:[1,9],improv:9,com:2,comment:1,among:1,instanti:1,dispatch:1,header:1,exploit:1,featur:0,shutdown:1,path:1,respect:[5,8,1],rmiclientschedulingmodel:0,guid:1,assum:4,advertis:8,liabil:2,java:[0,1,2,3,4,5,6,7,8,9],sarl:2,union:1,trademark:2,three:1,been:[3,9],compon:0,basic:[0,1],immedi:1,quickli:6,op1_repli:5,persistent_durability_qo:[7,1],rather:9,fire:9,persist:3,argument:4,"catch":1,schedule_timeshar:1,those:3,"case":1,"char":[1,4],multi:[8,1],ident:3,string_dup:4,defin:[9,1,4],"while":3,op1_request:5,abov:[8,1],error:1,rmiserverschedulingmodel:0,spawn:1,real:[3,9],layer:[1,6],gateshead:2,advantag:6,"5th":2,henc:[1,4],them:[8,1],linkedin:2,itself:1,topic_qo:[7,1],incom:1,automatic_liveliness_qo:7,"null":1,develop:[9,1,6],helloservice_top:1,perform:[3,1,9],make:1,format:1,same:[3,5,8,1,4],drawback:1,document:2,higher:[3,1],finish:1,http:[7,1,2],wherea:1,adlinktech:2,fairli:1,rais:1,user:1,ownership:4,nonnegativeinteg:7,typic:[3,1],tune:[1,9],rmiserverthreadingmodel:0,task:1,older:8,macro:1,thu:1,well:[9,1,4],historyqospolici:7,without:[3,1,2],s_polici:1,thi:[1,2,4,5,6,8,9],choos:1,jean:2,paradigm:[3,6],deadlineqospolici:7,identifi:[3,1,6],op1:5,execut:[3,8,1],dds_rmiidentif:8,dds_serviceinterfac:1,t_polici:1,dds_rmi:[5,1],timeshar:1,fact:1,languag:[0,1],previous:4,web:2,struct:[5,1],easi:3,hint:[1,6],helloserviceinterfaceproxi:[1,4],mygreetreplyhandl:1,priorit:3,except:1,"_repli":5,versa:8,interfacenam:5,subsequ:1,smart:1,ami:9,ownershipkind:7,advis:4,transpar:3,read:9,intuit:9,burden:3,associ:[3,5],linux:6,rmiservicediscoverytimeout:0,success:[1,9],realtim:1,manual:3,positiveinteg:7,vortex:[1,2],api:[3,1,9],singl:[8,1],xsd:[7,1],corpor:2,output:1,xsi:1,setprior:1,page:0,req_info:5,underli:[3,8,1,9],www:[7,1,2],right:2,often:3,acknowledg:2,twitter:2,suppli:1,some:[8,1,4],back:9,helloservice_impl:1,global:3,intern:1,sampl:1,proper:1,guarante:1,mainli:1,avoid:1,normal:1,octet:4,benefit:0,per:[8,1],whole:2,exit:1,middlewar:[3,9,8,1,4],condit:8,reproduc:2,either:[8,1,4],schedule_realtim:1,core:9,previou:8,run:1,power:9,efer:1,helloserviceinterfac:[1,4],rue:2,host:1,obei:4,complextyp:7,dcp:[3,7,1,9],timebasedfilterqospolici:7,chapter:[6,5,8,1,4],faith:2,most:4,initial_sampl:7,idltyp:[7,1],unfortun:8,idl:[6,9,5,1,4],includ:[3,8,1,9],adlinktech_usa:2,disabl:[8,1],block:[1,9],durabilityserviceqospolici:7,opensplic:[1,2],idlfil:[7,1],"float":4,encod:[7,1],orsai:2,my_domain_id:1,down:1,manual_by_topic_liveliness_qo:7,ensur:1,chang:[1,2],forget:9,durabl:8,processor:[1,9],wai:1,support:[8,1],vallei:2,transform:5,"long":[5,1,4],avail:[9,6,1,2],interfac:[0,1],inner:4,suit:2,greet_reply_handl:[1,4],register_interfac:1,ret:1,"function":[1,4],schemaloc:1,form:4,subscrib:6,dds_rmidefinit:8,adlink:2,client_id:5,line:[8,1,6],highest:1,"true":1,concaten:[1,4],made:[5,1,2],utf:7,possibl:1,"default":[7,8,1],maximum:8,helloservice_interfaceproxi:1,below:[6,1,4],ddsrmi:1,limit:[1,2],"export":[3,1],ownershipqospolici:7,similar:[1,9],impl:1,topicdataqospolici:7,gather:5,reliable_reliability_qo:[7,1],creat:[5,8,1],"int":[1,4],"abstract":[3,4],command:[3,8,1,6],doesn:8,repres:[1,4],simpletyp:7,exist:1,file:[6,1,4],shut:1,keep_last_history_qo:7,volatile_durability_qo:7,stimulu:3,dll_macro_nam:1,hpp:1,when:[9,6,8,1,4],detail:8,virtual:1,valid:9,bool:1,resourcelimitsqospolici:7,you:1,base64binari:7,elementformdefault:7,intend:[1,6],sequenc:[7,1,4],manual_by_participant_liveliness_qo:7,meaning:1,threadpools:1,safeti:1,minoccur:7,pool:[8,1],max_sampl:7,reduc:1,receiv:[1,9],longer:1,algorithm:1,vice:8,directori:1,reliabl:1,rule:[0,9,6,1,4],depth:7,max_inst:7,time:[3,8,1,9],cpp:1,getruntim:1},objtypes:{},objnames:{},filenames:["index","build-rmi-apps","contacts","introduction","language-map","topics-maps","preface","qos-policies","runtime-config","rmi-over-dds"],titles:["Vortex OpenSplice RMI User Guide","4. Building an RMI Application","9. Contacts & Notices","2. Introduction","5. Language mapping for Vortex OpenSplice RMI","6. RMI Interface to DDS topics mapping rules","1. Preface","8. QoS policies XML schema","7. RMI Runtime Configuration Options","3. Vortex OpenSplice RMI over DDS"],objects:{},titleterms:{compil:1,oper:4,domain:1,featur:3,synchron:1,opensplic:[0,9,4],applic:1,schedul:1,over:9,indic:0,rmiservicediscoverytimeout:8,tabl:0,rmiclientschedulingmodel:8,guid:[0,6],languag:[9,4],prioriti:1,xml:7,rmi:[0,1,4,5,6,8,9],convent:6,polici:[7,1],configur:8,vortex:[0,9,4],client:1,compon:9,start:1,program:1,interfac:[5,4],build:1,option:8,basic:4,type:4,invoc:1,mode:1,map:[5,4],rmiclientthreadingmodel:8,kei:9,rmiserverthreadingmodel:8,stop:1,notic:2,multithread:1,schema:7,user:[0,6],implement:1,introduct:3,topic:5,about:[1,6],specif:1,thread:1,rmidur:8,bind:9,servic:1,rmilegacytopicnam:8,descript:1,rule:5,server:1,asynchron:1,benefit:3,contact:2,runtim:[8,1],model:1,prefac:6,rmiserverschedulingmodel:8}}) \ No newline at end of file diff --git a/docs/html/RMIGettingStarted/topics-maps.html b/docs/html/RMIGettingStarted/topics-maps.html index a934bb850..eb44aedf7 100644 --- a/docs/html/RMIGettingStarted/topics-maps.html +++ b/docs/html/RMIGettingStarted/topics-maps.html @@ -159,7 +159,7 @@

    Navigation

    \ No newline at end of file diff --git a/docs/html/RnRAPIReference/_sources/contacts.txt b/docs/html/RnRAPIReference/_sources/contacts.txt index fc6442d3a..d32f6016f 100644 --- a/docs/html/RnRAPIReference/_sources/contacts.txt +++ b/docs/html/RnRAPIReference/_sources/contacts.txt @@ -1,53 +1 @@ -.. _`Contacts & Notices`: - -.. VERY LITTLE EVER CHANGES IN HERE !! - Just keep an eye on the copyright notice. - -################## -Contacts & Notices -################## - -******** -Contacts -******** - -| **PrismTech Corporation** -| 400 TradeCenter -| Suite 5900 -| Woburn, MA -| 01801 -| USA -| Tel: +1 781 569 5819 - -| **PrismTech Limited** -| PrismTech House -| 5th Avenue Business Park -| Gateshead -| NE11 0NG -| UK -| Tel: +44 (0)191 497 9900 - -| **PrismTech France** -| 28 rue Jean Rostand -| 91400 Orsay -| France -| Tel: +33 (1) 69 015354 - - -Web: http://www.prismtech.com - -E-mail: \info@prismtech.com - -******* -Notices -******* - -**Copyright** © 2016 PrismTech Limited. All rights reserved. - -*This document may be reproduced in whole but not in part. -The information contained in this document is subject to change -without notice and is made available in good faith without -liability on the part of PrismTech Limited or PrismTech Corporation. -All trademarks acknowledged.* - -.. END +.. include:: ../../common/contacts.rst diff --git a/docs/html/RnRAPIReference/_sources/index.txt b/docs/html/RnRAPIReference/_sources/index.txt index 4ee35f4f7..95798a315 100644 --- a/docs/html/RnRAPIReference/_sources/index.txt +++ b/docs/html/RnRAPIReference/_sources/index.txt @@ -9,19 +9,19 @@ The Vortex Record and Replay API Reference .. toctree:: :maxdepth: 6 :numbered: - + preface introduction scenarios topic-api-overview issues impact - + appendixa bibliography - - contacts - + + contacts + Indices and tables ================== diff --git a/docs/html/RnRAPIReference/_sources/preface.txt b/docs/html/RnRAPIReference/_sources/preface.txt index ae53e792d..912b2400d 100644 --- a/docs/html/RnRAPIReference/_sources/preface.txt +++ b/docs/html/RnRAPIReference/_sources/preface.txt @@ -8,8 +8,8 @@ Preface About The Record and Replay API Reference ****************************************** -The *Record and Replay (RnR) API Reference* provides a complete description of the functions -available *via* the API of the OpenSplice Record and Replay Service +The *Record and Replay (RnR) API Reference* provides a complete description of the functions +available *via* the API of the OpenSplice Record and Replay Service (RnR Service). This API Reference is intended to be used after the Vortex OpenSplice software @@ -19,58 +19,58 @@ according to the instructions in the Vortex OpenSplice *Getting Started Guide*. Intended Audience ***************** -The API Reference is intended to be used by all Record and Replay -Service users, including programmers, testers, system designers and +The API Reference is intended to be used by all Record and Replay +Service users, including programmers, testers, system designers and system integrators. Organisation ************ -The :ref:`Introduction ` gives an overview of the purpose +The :ref:`Introduction ` gives an overview of the purpose and design of the Record and Replay Service. -The :ref:`Scenarios ` section explains the key concept of the +The :ref:`Scenarios ` section explains the key concept of the ‘scenario’ used in the RnR Service. -:ref:`All of the functions of the RnR Service ` +:ref:`All of the functions of the RnR Service ` are then described in full detail. -There is a (very short) list of :ref:`known issues ` which +There is a (very short) list of :ref:`known issues ` which describes current limitations of the RnR Service. -The next section describes how the RnR Service is designed to -minimize its :ref:`intrusiveness ` on +The next section describes how the RnR Service is designed to +minimize its :ref:`intrusiveness ` on existing systems. -The :ref:`RnR Topic API IDL specification ` contains +The :ref:`RnR Topic API IDL specification ` contains the complete IDL definition of the RnR Service API. Finally, there is a :ref:`bibliography ` which lists -all of the publications referred to in this *Guide*. +all of the publications referred to in this *Guide*. Conventions *********** -The icons shown below are used in PrismTech product documentation -to help readers to quickly identify information relevant to their +The icons shown below are used in ADLINK product documentation +to help readers to quickly identify information relevant to their specific use of Vortex OpenSplice. - ========= ================================================================== - *Icon* *Meaning* - ========= ================================================================== - |caution| Item of special significance or where caution needs to be taken. - |info| Item contains helpful hint or special information. - |windows| Information applies to Windows (*e.g.* XP, 2003, Windows 7) only. - |unix| Information applies to Unix-based systems (*e.g.* Solaris) only. - |linux| Information applies to Linux-based systems (*e.g.* Ubuntu) only. - |c| C language specific. - |cpp| C++ language specific. - |csharp| C# language specific. - |java| Java language specific. - ========= ================================================================== + ========= ================================================================== + *Icon* *Meaning* + ========= ================================================================== + |caution| Item of special significance or where caution needs to be taken. + |info| Item contains helpful hint or special information. + |windows| Information applies to Windows (*e.g.* XP, 2003, Windows 7) only. + |unix| Information applies to Unix-based systems (*e.g.* Solaris) only. + |linux| Information applies to Linux-based systems (*e.g.* Ubuntu) only. + |c| C language specific. + |cpp| C++ language specific. + |csharp| C# language specific. + |java| Java language specific. + ========= ================================================================== @@ -94,4 +94,3 @@ specific use of Vortex OpenSplice. .. |java| image:: ./images/icon-java.* :height: 6mm - \ No newline at end of file diff --git a/docs/html/RnRAPIReference/appendixa.html b/docs/html/RnRAPIReference/appendixa.html index 136022abf..4ba6d9ea2 100644 --- a/docs/html/RnRAPIReference/appendixa.html +++ b/docs/html/RnRAPIReference/appendixa.html @@ -546,7 +546,7 @@

    Navigation

    \ No newline at end of file diff --git a/docs/html/RnRAPIReference/appendixab.html b/docs/html/RnRAPIReference/appendixab.html index b6f8af3ab..86137b908 100644 --- a/docs/html/RnRAPIReference/appendixab.html +++ b/docs/html/RnRAPIReference/appendixab.html @@ -444,7 +444,7 @@

    Navigation

    \ No newline at end of file diff --git a/docs/html/RnRAPIReference/bibliography.html b/docs/html/RnRAPIReference/bibliography.html index 1e8c31b23..6910a3043 100644 --- a/docs/html/RnRAPIReference/bibliography.html +++ b/docs/html/RnRAPIReference/bibliography.html @@ -177,7 +177,7 @@

    Navigation

    \ No newline at end of file diff --git a/docs/html/RnRAPIReference/contacts.html b/docs/html/RnRAPIReference/contacts.html index 045d7e652..7a3b134c9 100644 --- a/docs/html/RnRAPIReference/contacts.html +++ b/docs/html/RnRAPIReference/contacts.html @@ -45,12 +45,12 @@

    Navigation

    -
    -

    9. Contacts & Notices¶

    +

    9.2. Notices¶

    -

    Copyright © 2016 PrismTech Limited. All rights reserved.

    -

    This document may be reproduced in whole but not in part. -The information contained in this document is subject to change -without notice and is made available in good faith without -liability on the part of PrismTech Limited or PrismTech Corporation. -All trademarks acknowledged.

    +

    Copyright © 2018 ADLINK Technology Limited. All rights reserved.

    +

    This document may be reproduced in whole but not in part. The information contained in this +document is subject to change without notice and is made available in good faith without +liability on the part of ADLINK Technology Limited. All trademarks acknowledged.

    @@ -144,7 +147,7 @@

    Navigation

    \ No newline at end of file diff --git a/docs/html/RnRAPIReference/genindex.html b/docs/html/RnRAPIReference/genindex.html index 7e6986284..c590ec623 100644 --- a/docs/html/RnRAPIReference/genindex.html +++ b/docs/html/RnRAPIReference/genindex.html @@ -88,7 +88,7 @@

    Navigation

    \ No newline at end of file diff --git a/docs/html/RnRAPIReference/impact.html b/docs/html/RnRAPIReference/impact.html index 317324679..c45b60184 100644 --- a/docs/html/RnRAPIReference/impact.html +++ b/docs/html/RnRAPIReference/impact.html @@ -165,7 +165,7 @@

    Navigation

    \ No newline at end of file diff --git a/docs/html/RnRAPIReference/index.html b/docs/html/RnRAPIReference/index.html index ee84f8693..077970551 100644 --- a/docs/html/RnRAPIReference/index.html +++ b/docs/html/RnRAPIReference/index.html @@ -177,7 +177,7 @@

    Navigation

    \ No newline at end of file diff --git a/docs/html/RnRAPIReference/introduction.html b/docs/html/RnRAPIReference/introduction.html index 6abfb9a61..9ea7b79ce 100644 --- a/docs/html/RnRAPIReference/introduction.html +++ b/docs/html/RnRAPIReference/introduction.html @@ -144,7 +144,7 @@

    Navigation

    \ No newline at end of file diff --git a/docs/html/RnRAPIReference/issues.html b/docs/html/RnRAPIReference/issues.html index e8bc00f6c..602c7df9f 100644 --- a/docs/html/RnRAPIReference/issues.html +++ b/docs/html/RnRAPIReference/issues.html @@ -130,7 +130,7 @@

    Navigation

    \ No newline at end of file diff --git a/docs/html/RnRAPIReference/objects.inv b/docs/html/RnRAPIReference/objects.inv index f8852196c..b9390216b 100644 Binary files a/docs/html/RnRAPIReference/objects.inv and b/docs/html/RnRAPIReference/objects.inv differ diff --git a/docs/html/RnRAPIReference/preface.html b/docs/html/RnRAPIReference/preface.html index 48fa1f9a3..98ae9edad 100644 --- a/docs/html/RnRAPIReference/preface.html +++ b/docs/html/RnRAPIReference/preface.html @@ -86,7 +86,7 @@

    1.3. Organisation

    1.4. Conventions¶

    -

    The icons shown below are used in PrismTech product documentation +

    The icons shown below are used in ADLINK product documentation to help readers to quickly identify information relevant to their specific use of Vortex OpenSplice.

    @@ -198,7 +198,7 @@

    Navigation

    \ No newline at end of file diff --git a/docs/html/RnRAPIReference/scenarios.html b/docs/html/RnRAPIReference/scenarios.html index 11f5bbc50..ee6e97329 100644 --- a/docs/html/RnRAPIReference/scenarios.html +++ b/docs/html/RnRAPIReference/scenarios.html @@ -209,7 +209,7 @@

    Navigation

    \ No newline at end of file diff --git a/docs/html/RnRAPIReference/search.html b/docs/html/RnRAPIReference/search.html index 89632c791..3ee27560f 100644 --- a/docs/html/RnRAPIReference/search.html +++ b/docs/html/RnRAPIReference/search.html @@ -95,7 +95,7 @@

    Navigation

    \ No newline at end of file diff --git a/docs/html/RnRAPIReference/searchindex.js b/docs/html/RnRAPIReference/searchindex.js index 9fee44030..82eff77be 100644 --- a/docs/html/RnRAPIReference/searchindex.js +++ b/docs/html/RnRAPIReference/searchindex.js @@ -1 +1 @@ -Search.setIndex({envversion:42,terms:{represent:8,all:[0,8,3,5,6,7,10],concept:6,partial:8,skip:8,ptc:2,blacklistexpr:[7,10],signific:6,code:8,sleep:8,per:[7,10,8],abil:1,follow:[7,8,2,9,10],valuekind_tim:[7,10],depend:8,remove_replai:5,friendli:8,send:8,deviat:8,text:2,keylist:[7,10],add_replai:5,messag:8,introduc:[5,7,10],removereplaycommand:[7,10],everi:[7,10],string:[7,10,8],fals:[7,10,8],util:[0,8],keep_last:8,remove_replay_command:[7,1,10],veri:6,affect:8,implicitli:9,exact:8,relev:[0,1,6],condition:8,common:[8,2],tri:8,abstim:[7,10],resempl:7,reproduc:3,necessit:5,hous:3,list:[8,6],bvalu:[7,10],item:6,reltim:[7,10],small:0,initialis:8,pleas:[5,8,9],prevent:[5,8],impli:0,smaller:[4,7,10],tel:3,timerang:[7,1,10],natur:5,batch:8,rate:[7,10,8],design:6,pass:[7,10],storagestatu:[7,10,8],append:8,compat:[5,8],corba:2,compar:[7,10],resembl:[7,10],section:[0,8,6,7,10,9],abl:[7,10,8],current:[7,10,8,9,6],version:[1,2],"new":[5,8],"public":[7,10,8,6],xml:[4,8],prismtech:[6,3],centric:0,depth:8,absolut:[7,10],gener:[7,10,8],behaviour:[7,10,8],met:8,solari:6,address:[5,7,8,10],recordrateaverag:[7,10],coincid:5,remove_record_command:[7,1,10],modifi:[4,8],sinc:[5,7,10],interpret:[7,10,8],search:1,add_record_command:[7,1,10],start_scenario_command:[7,10,8],amount:0,multicast:0,keyvalu:[7,1,10],action:5,implement:8,rr_servicestatu:8,scenarionam:[5,7,8,10],writer:8,regardless:8,extra:0,appli:[7,10,8,6],transit:[7,10],avenu:3,filenam:8,unix:6,"boolean":[7,10,8],rnrid:[5,7,8,10],visibl:0,instal:6,total:[7,10],select:[4,8],from:[0,8,4,5,7,10],describ:[0,5,8,6],usa:3,memori:0,two:[5,7,8,10],next:[5,8,6],process:[0,5,8,10,7],busi:[8,3],call:[0,5,8],tradecent:3,recommend:5,taken:6,type:[5,1,2,10,7],until:[5,8],more:8,minim:6,faith:3,relat:[0,8],impress:8,setreplayspeed_command:[7,1,10],enhanc:[7,10],"transient":[5,8],numberofsamplesreplai:[7,10],accept:8,particular:9,known:1,keep_al:8,hold:[7,10],addreplai:[7,10],must:[5,7,10],fly:[4,8],rr_scenario_v2:[5,8],join:8,scenario_suspend:[7,10],uniqu:8,histori:8,rr_storagestatu:8,can:[0,4,8,9,5],purpos:[0,8,6],aliv:[7,10],control:[0,1,4,5,7,10],claim:8,unanticip:0,give:[8,6],svalu:[7,10,8],share:[0,5,8],indic:[7,10],high:4,tag:8,caution:6,storage_open:[7,10],yet:[7,10,8,9],occur:[7,10,8],delai:[4,7,8,10],alwai:[5,8],end:[7,10,8],divid:[7,10],travel:0,write:8,how:6,confin:0,instead:8,simpl:5,unabl:[7,10],map:2,product:[5,9,6],resourc:[7,10,8],after:[5,8,6],diagram:8,befor:[5,7,8,9,10],scenario_run:[7,10],mai:[5,8,3],multipl:[4,8],data:[0,2,4,5,10,7,8,9],averag:8,circumst:5,"short":6,practic:5,deadline_period:8,topicstatist:[7,10],exclud:[7,10],issu:1,inform:[4,6,8,9,3],"switch":[7,10],duration_t:[7,10],environ:5,allow:[0,5,8],enter:8,exclus:8,order:[5,8],rue:3,partition__:9,oper:[4,5,8],belong:[7,10,8,9],help:[5,6],timeexpr:[7,10,8],over:0,rang:[4,7,8,10],removerecord:[7,10],through:[4,5],numberofbytesrecord:[7,10],still:5,vari:8,dynam:[4,5,2,8],paramet:8,conjunct:4,group:[4,5,2],monitor:[4,7,8,10],polici:8,fix:[7,10],rr_storageattrxml:8,whether:5,window:6,requir:[0,5,8],bypass:9,persist:[5,8],mystorag:8,mail:3,therefor:8,might:5,builtinscenario:1,wouldn:5,non:[0,8],good:3,truncate_command:[7,1,10],greater:[7,10],thei:[0,8],timestamp:[7,10,8],safe:5,initi:[5,8],bound:0,dat:8,automat:4,half:8,detach:8,replayrateaverag:[7,10],choic:5,name:[5,7,8,10],anyth:5,config:[5,1,10,7],revers:5,unlik:8,separ:8,easili:5,each:[5,8],servicest:[7,10],found:8,updat:8,truncat:[7,10,8],mean:[8,6],subset:[0,8],domain:[7,10],replai:[0,7,10],ne11:3,resum:[7,10,8],individu:5,continu:[7,10,8],config_command:[7,10,8],meta:[7,10],"static":[0,4],addreplaycommand:[7,10],special:[5,8,6],out:[7,10,8],shown:6,recordratemaximum:[7,10],network:[0,6],space:4,setreplayspeedcommand:[7,10],publish:[0,8,4,5,7,10],content:[5,7,8,10],rel:[5,7,10],reader:[5,8,6],rnr_v2:[5,7,8,10],occurr:8,statist:[4,1,10,7],franc:3,shut:[7,10,8],insid:0,advanc:5,migrat:5,manipul:8,infin:[7,10,8],quick:8,reason:8,base:[0,8,6],intric:5,releas:[8,9],succesfulli:8,"byte":[7,10,8],prefac:1,defauilt:8,omit:8,filter:[4,5,8,10,7],perhap:5,organis:1,isn:[5,8],storage_readi:[7,10],confus:8,"5th":3,first:[7,10,8,9],origin:[5,7,8,10],softwar:6,major:5,suspend:[7,10,8],directli:8,onc:8,independ:8,number:[7,10,8],system:[0,4,2,6],hook:5,instruct:[8,6],alreadi:8,done:[7,10],overwrit:8,open:[7,10,8],prioriti:8,differ:1,"long":[5,7,8,10],convent:1,script:5,interact:[0,4,5],sometim:8,gpb:5,attach:[5,8],service_termin:[7,10],termin:[7,10,8],scheme:5,"final":[2,6],store:[4,5,8],option:[0,8],especi:5,tool:[0,8],suit:3,park:3,alloc:8,specifi:[7,10,8],provid:[5,8,6],part:[0,5,8,3],pragma:[7,10],exactli:8,than:[7,10,8],serv:5,wide:0,kind:[7,10,8],conveni:8,recordandreplai:[0,8],target:[5,8],remot:0,remov:[5,7,8,10],lvalu:[7,10],second:8,charact:8,were:[5,7,8,10],sec:[7,10,8],toward:0,typic:0,pre:8,analysi:4,lifecycleexpr:[7,10],stop_scenario_command:[7,10,8],ani:[0,5,8,9],correspond:[5,8],valuekind_long:[7,10],setreplayspe:[7,10],commandkind:[7,10],close:[7,10,8],need:[8,6],dedic:0,element:8,nanosec:[7,10,8],caus:8,recordrateminimum:[7,10],strength:8,built:[0,9],skiptofirstsampl:[7,10,8],rout:4,note:[0,5,8,9],mix:5,unawar:8,maintain:8,take:8,which:[0,8,4,5,6,7,10],combin:8,iso:2,singl:[5,8],even:8,distribut:[5,2],"enum":[7,10],normal:8,buffer:5,object:[8,2],reach:8,suspend_scenario_command:[7,10,8],most:8,regular:4,segment:0,jean:3,icon:6,clear:8,adopt:2,request:2,doe:[5,9],valuekind_float:[7,10],runtim:8,wildcard:[4,8],latest:8,keyval:[7,10,8],show:8,transport_prior:8,alphanumer:8,session:8,permiss:8,identifi:[7,10,8,6],involv:8,addrecordcommand:[7,10],onli:[0,4,6,8,5],submit:8,locat:0,execut:[4,7,8,10],copyright:3,explain:6,configur:[0,4,8,6],activ:[7,10,8],state:[0,7,8,10],should:[7,10,8,9],latenc:8,factor:[7,10],iec:2,local:[0,8],info:3,storagenam:[7,10,8],unus:8,variou:[4,7,8,10],get:[8,9,6],express:[4,7,8,9,10],stop:[5,7,8,10],becaus:5,regularli:5,storage_clos:[7,10],cannot:[5,8],increas:8,dataexpr:[7,10],restart:5,tvalu:[7,10],xmlstorag:8,organ:5,twice:8,integr:6,partit:[0,8,4,5,7,10],contain:[0,8,3,5,6,7,10],tuner:0,where:[0,7,8,10,6],durabilityqospolici:8,myservic:8,set:[4,1,10,7],xtype:2,"float":[7,10,8],reliabilityqospolici:8,startup:[5,8],see:[5,8,9],full:[8,6],mandatori:8,cond_lifecycl:[7,10],respons:8,reserv:[7,10,3],lifespan_period:8,subject:3,awar:8,statu:[0,1,10,7,4],interestexpr:[7,10,8],struct:[7,10],discoveri:4,written:8,volatil:[5,8],"0ng":3,between:[5,8],"import":[5,8],subscript:8,inclus:[7,10],approach:5,attribut:[7,10,8],accord:6,omg:2,kei:[7,10,8,6],induc:0,flow:0,rostand:3,extens:[5,8,2,10,7],latency_period:8,addit:[0,5,8,9],scenario_stop:[7,10],both:5,last:8,cycl:8,howev:8,hint:6,against:8,audienc:1,instanc:[0,5,8,10,7],logic:4,scenariostatu:[7,10,8],com:3,removerecordcommand:[7,10],compromis:5,fvalu:[7,10],simpli:8,point:[7,10,8],wall:[7,10],overview:[1,6],inher:[0,4],period:[7,10,8],except:8,myscenario:8,colon:8,shutdown:8,suppli:[8,9],respect:[0,4],guid:6,assum:5,summar:[0,9],liabil:3,java:[2,6],creat:[4,1],union:[7,10,8],storage_error:[7,10],valuekind:[7,10],been:[5,7,8,10,6],compon:8,time_invalid_nsec:[7,10,8],trigger:0,valu:[7,10,8],interest:[4,7,8,9,10],subscrib:[0,4,8,5],immedi:[5,8],addrecord:[7,10],life:8,cond_data:[7,10],mine:4,decim:8,understand:[5,8],togeth:8,add_replay_command:[7,1,10],those:[5,8],"case":[0,5,8,10,7],ident:[5,8],servic:[0,1,2,4,5,6,7,10,9],properti:[7,10,8],budget:8,durat:8,defin:[5,7,8,10],"while":[5,8],behavior:8,error:[7,10,8],scenariost:[7,10],gateshead:3,storageattr:[7,10,8],helper:[7,10,8],readi:8,outofresourc:8,deliv:[5,8],middlewar:[4,5,8],itself:8,time_t:[7,10,8],"null":8,develop:5,copy_from_topic_qo:8,receiv:[7,10],make:8,format:8,same:[5,8],member:[7,10,8],preserv:[5,8],throughput:4,document:[6,2,3],complet:[8,6],deadlin:8,http:3,nest:5,upon:[7,10,8],effect:8,capabl:[4,5],user:6,ownership:8,ownership_strength:8,footprint:4,decoupl:4,chang:[8,3,4,5,7,10],recent:8,servicestatu:[7,10,8],scenario:[4,1,10,7,6],macro:8,thu:[0,8],well:4,"__built":9,without:[8,3],exampl:8,command:[0,1,4,7,10,9],thi:[0,8,3,5,6,7,10,9],choos:8,programm:6,model:[5,7,10],woburn:3,ubuntu:6,usual:8,protocol:5,paus:8,just:[4,8],cond_abs_tim:[7,10],obtain:0,via:6,excludedattributeexpr:[7,10],aspect:[0,8],comput:0,speed:[4,7,8,10],filterexpr:[7,10],languag:[2,6],previous:8,web:3,cut:8,miscellan:1,easi:4,also:[5,8],builtin:[7,10],shortcut:8,add:[7,10,8,9],valid:[7,10,8],bibliographi:6,versa:0,cdr:4,introduct:1,dds_dcp:[7,10],modul:[5,7,10],match:[5,7,8,10],real:2,applic:[0,5,8],milli:8,transpar:[0,4],read:[5,8],arriv:5,rr_scenario:[5,8],traffic:0,rr_storagestatist:8,dcpstopic:9,characterist:[0,8],formal:2,insert:[7,10,8],storagestatist:[7,10,8],rr_scenariostatu:8,like:[0,5],success:8,corpor:3,manual:8,resolv:8,vortex:0,either:8,have:[5,8,9],architectur:[4,2],manag:[5,8,2],psm:2,storage_outofresourc:[7,10],www:3,right:3,old:5,acknowledg:3,extcommand:[7,10],linux:6,some:8,unrecover:[7,10],sampl:[0,4,8,10,7],mirror:8,guarante:5,successfulli:[7,10,8],transport:8,numberofsamplesrecord:[7,10],feder:0,cond_rel_tim:[7,10],definit:[0,5,6],benefit:4,overlap:8,whole:3,inject:5,condit:[4,7,8,10],notabl:8,reflect:8,previou:[5,7,8,10],run:[0,5,8],service_initialis:[7,10],inspect:0,usag:5,broker:2,viabl:5,post:4,chapter:5,removereplai:[7,10],about:1,actual:0,would:[0,5],page:1,stamp:8,lifecycl:[7,10],valuekind_boolean:[7,10],discard:8,produc:8,block:[7,10],pluggabl:4,own:8,durabilityserviceqospolici:8,opensplic:[0,1,2,3,4,5,6,7,8,9,10],replayrateminimum:[7,10],within:8,useoriginaltimestamp:[7,10,8],orsai:3,publish_interv:8,upgrad:5,down:[7,10,8],numberofbytesreplai:[7,10],empti:[7,10,8],trademark:3,ensur:9,opportun:8,storag:[4,1,10,9,7],durabl:1,merg:5,occupi:0,accordingli:8,log:8,wai:0,few:0,support:[5,7,8,10],enabl:[0,8],transform:[5,7,8,10],fast:[7,10,8],why:8,avail:[4,5,6,8,3],start:[5,7,8,10,6],compliant:8,includ:[8,5,6,7,10,9],replac:[5,8],forward:[0,7,10],strictli:5,interv:8,"function":6,human:8,offer:4,regard:8,"true":[7,10,8],reset:8,notat:8,made:[7,10,3],consist:8,possibl:[5,7,8,10],"default":8,service_oper:[7,10],maximum:8,lifespan:8,record:[0,7,10],below:6,limit:[8,3,6,7,10,9],highlight:5,quickli:6,similar:8,featur:[0,1],evalu:8,certain:8,dure:[4,5,8],doesn:8,deem:8,exist:[0,5,8,6],file:[4,7,8,10],probabl:5,again:[5,8],generic_command:[7,10],use_topic_qo:8,googl:5,valuekind_str:[7,10],tester:6,when:[0,5,8,10,7],detail:[5,8,6],invalid:8,field:8,other:[0,5,8],futur:[7,10,8],you:4,historyqospolici:8,conditionkind:[7,10],realiti:8,node:[0,5],intend:1,determin:8,sequenc:[7,10,8],asterisk:8,time_invalid_sec:[7,10,8],intent:0,consid:[0,7,8,10],stai:0,longer:5,furthermor:8,vice:0,anywher:0,reliabl:8,storagest:[7,10],descript:[8,6],discrimin:[7,10],mimic:8,ignor:8,time:[2,4,5,8,7,10],replayratemaximum:[7,10],backward:5},objtypes:{},objnames:{},filenames:["impact","index","bibliography","contacts","introduction","scenarios","preface","appendixab","topic-api-overview","issues","appendixa"],titles:["6. Impact on DDS Domain","The Vortex Record and Replay API Reference","8. References","9. Contacts & Notices","2. Introduction","3. Scenarios","1. Preface","Appendix A","4. Topic API Overview","5. Known Issues","7. Appendix A"],objects:{},titleterms:{control:8,domain:0,replai:[1,8,6],set:8,timerang:8,creat:9,overview:8,indic:1,topic:[5,7,8,9,10],api:[7,1,8,10,6],abil:9,tabl:1,intend:6,storag:8,durabl:5,impact:0,differ:5,miscellan:8,convent:6,add_record_command:8,audienc:6,relev:8,version:5,keyvalu:8,type:8,refer:[1,2,6],builtinscenario:5,truncate_command:8,statist:8,about:6,notic:3,intrus:0,appendix:[7,10],vortex:1,remove_replay_command:8,known:9,rnr:[7,10],add_replay_command:8,featur:4,introduct:4,prefac:6,setreplayspeed_command:8,specif:[7,10],scenario:[5,8],statu:8,config:8,servic:8,issu:9,record:[1,8,6],idl:[7,10],contact:3,command:[5,8],organis:6,remove_record_command:8}}) \ No newline at end of file +Search.setIndex({envversion:42,terms:{represent:8,all:[0,8,3,5,6,7,10],concept:6,partial:8,edg:3,skip:8,ptc:2,blacklistexpr:[7,10],signific:6,code:8,sleep:8,per:[7,10,8],abil:1,follow:[7,8,2,9,10],valuekind_tim:[7,10],keep_al:8,depend:8,remove_replai:5,friendli:8,send:8,deviat:8,text:2,keylist:[7,10],ist_info:3,introduc:[5,7,10],removereplaycommand:[7,10],everi:[7,10],string:[7,10,8],fals:[7,10,8],util:[0,8],keep_last:8,facebook:3,remove_replay_command:[7,1,10],veri:6,affect:8,implicitli:9,exact:8,relev:[0,1,6],condition:8,common:[8,2],tri:8,abstim:[7,10],resempl:7,reproduc:3,necessit:5,list:[8,6],bvalu:[7,10],item:6,reltim:[7,10],team:3,small:0,initialis:8,pleas:[5,8,9],prevent:[5,8],impli:0,smaller:[4,7,10],tel:3,timerang:[7,1,10],natur:5,batch:8,rate:[7,10,8],design:6,pass:[7,10],storagestatu:[7,10,8],append:8,compat:[5,8],corba:2,compar:[7,10],resembl:[7,10],section:[0,8,6,7,10,9],abl:[7,10,8],current:[7,10,8,9,6],version:[1,2],"new":[5,8],"public":[7,10,8,6],xml:[4,8],centric:0,depth:8,absolut:[7,10],gener:[7,10,8],behaviour:[7,10,8],met:8,solari:6,address:[5,7,8,10],recordrateaverag:[7,10],"0xa":3,remove_record_command:[7,1,10],modifi:[4,8],sinc:[5,7,10],interpret:[7,10,8],search:1,technolog:3,add_record_command:[7,1,10],start_scenario_command:[7,10,8],amount:0,multicast:0,keyvalu:[7,1,10],action:5,implement:8,rr_servicestatu:8,scenarionam:[5,7,8,10],writer:8,regardless:8,extra:0,appli:[7,10,8,6],transit:[7,10],avenu:3,filenam:8,unix:6,"boolean":[7,10,8],rnrid:[5,7,8,10],visibl:0,instal:6,total:[7,10],select:[4,8],from:[0,8,4,5,7,10],describ:[0,5,8,6],usa:3,memori:0,gpb:5,two:[5,7,8,10],next:[5,8,6],process:[0,5,8,10,7],latenc:8,call:[0,5,8],tradecent:3,recommend:5,taken:6,type:[5,1,2,10,7],until:[5,8],more:8,minim:6,removereplai:[7,10],relat:[0,8],impress:8,setreplayspeed_command:[7,1,10],enhanc:[7,10],"transient":[5,8],numberofsamplesreplai:[7,10],accept:8,particular:9,known:1,compani:3,hold:[7,10],addreplai:[7,10],must:[5,7,10],fly:[4,8],rr_scenario_v2:[5,8],add_replai:5,join:8,scenario_suspend:[7,10],uniqu:8,histori:8,rr_storagestatu:8,can:[0,4,8,9,5],purpos:[0,8,6],aliv:[7,10],control:[0,1,4,5,7,10],claim:8,unanticip:0,give:[8,6],svalu:[7,10,8],share:[0,5,8],indic:[7,10],high:4,tag:8,caution:6,storage_open:[7,10],yet:[7,10,8,9],occur:[7,10,8],delai:[4,7,8,10],alwai:[5,8],end:[7,10,8],divid:[7,10],travel:0,write:8,how:6,confin:0,instead:8,simpl:5,unabl:[7,10],map:2,product:[5,9,6],resourc:[7,10,8],after:[5,8,6],diagram:8,befor:[5,7,8,9,10],scenario_run:[7,10],adlinktech_usa:3,mai:[5,8,3],multipl:[4,8],data:[0,2,4,5,10,7,8,9],averag:8,circumst:5,"short":6,practic:5,deadline_period:8,topicstatist:[7,10],exclud:[7,10],issu:1,inform:[4,6,8,9,3],"switch":[7,10],duration_t:[7,10],environ:5,allow:[0,5,8],enter:8,exclus:8,order:[5,8],rue:3,partition__:9,oper:[4,5,8],belong:[7,10,8,9],help:[5,6],timeexpr:[7,10,8],over:0,rang:[4,7,8,10],removerecord:[7,10],through:[4,5],numberofbytesrecord:[7,10],still:5,vari:8,dynam:[4,5,2,8],paramet:8,conjunct:4,group:[4,5,2],monitor:[4,7,8,10],polici:8,fix:[7,10],rr_storageattrxml:8,whether:5,window:6,requir:[0,5,8],bypass:9,persist:[5,8],mystorag:8,mail:3,therefor:8,might:5,builtinscenario:1,wouldn:5,non:[0,8],good:3,truncate_command:[7,1,10],greater:[7,10],thei:[0,8],timestamp:[7,10,8],safe:5,initi:[5,8],bound:0,dat:8,automat:4,half:8,detach:8,replayrateaverag:[7,10],choic:5,name:[5,7,8,10],anyth:5,config:[5,1,10,7],revers:5,instruct:[8,6],separ:8,easili:5,each:[5,8],servicest:[7,10],found:8,updat:8,truncat:[7,10,8],mean:[8,6],subset:[0,8],domain:[7,10],replai:[0,7,10],ne11:3,resum:[7,10,8],individu:5,continu:[7,10,8],config_command:[7,10,8],meta:[7,10],"static":[0,4],addreplaycommand:[7,10],special:[5,8,6],out:[7,10,8],shown:6,recordratemaximum:[7,10],network:[0,6],space:4,setreplayspeedcommand:[7,10],publish:[0,8,4,5,7,10],content:[5,7,8,10],com:3,rel:[5,7,10],reader:[5,8,6],rnr_v2:[5,7,8,10],occurr:8,statist:[4,1,10,7],franc:3,shut:[7,10,8],insid:0,advanc:5,migrat:5,manipul:8,infin:[7,10,8],quick:8,reason:8,base:[0,8,6],intric:5,releas:[8,9],succesfulli:8,"byte":[7,10,8],prefac:1,defauilt:8,omit:8,ist:3,filter:[4,5,8,10,7],perhap:5,organis:1,isn:[5,8],storage_readi:[7,10],confus:8,"5th":3,first:[7,10,8,9],origin:[5,7,8,10],softwar:6,major:5,suspend:[7,10,8],directli:8,onc:8,independ:8,number:[7,10,8],system:[0,4,2,6],hook:5,unlik:8,alreadi:8,done:[7,10],overwrit:8,open:[7,10,8],prioriti:8,differ:1,"long":[5,7,8,10],convent:1,script:5,interact:[0,4,5],sometim:8,messag:8,attach:[5,8],service_termin:[7,10],termin:[7,10,8],scheme:5,"final":[2,6],store:[4,5,8],option:[0,8],especi:5,tool:[0,8],suit:3,alloc:8,specifi:[7,10,8],provid:[5,8,6],part:[0,5,8,3],pragma:[7,10],exactli:8,than:[7,10,8],serv:5,wide:0,kind:[7,10,8],conveni:8,recordandreplai:[0,8],target:[5,8],remot:0,remov:[5,7,8,10],lvalu:[7,10],second:8,charact:8,were:[5,7,8,10],sec:[7,10,8],toward:0,typic:0,pre:8,analysi:4,lifecycleexpr:[7,10],stop_scenario_command:[7,10,8],ani:[0,5,8,9],correspond:[5,8],valuekind_long:[7,10],setreplayspe:[7,10],commandkind:[7,10],close:[7,10,8],need:[8,6],dedic:0,element:8,nanosec:[7,10,8],caus:8,recordrateminimum:[7,10],strength:8,built:[0,9],skiptofirstsampl:[7,10,8],rout:4,note:[0,5,8,9],mix:5,unawar:8,maintain:8,take:8,which:[0,8,4,5,6,7,10],combin:8,iso:2,singl:[5,8],even:8,distribut:[5,2],"enum":[7,10],normal:8,buffer:5,object:[8,2],reach:8,suspend_scenario_command:[7,10,8],most:8,regular:4,segment:0,jean:3,icon:6,consist:8,clear:8,adopt:2,request:2,doe:[5,9],valuekind_float:[7,10],runtim:8,wildcard:[4,8],latest:8,keyval:[7,10,8],show:8,transport_prior:8,alphanumer:8,session:8,permiss:8,identifi:[7,10,8,6],involv:8,addrecordcommand:[7,10],onli:[0,4,6,8,5],submit:8,locat:0,execut:[4,7,8,10],copyright:3,explain:6,configur:[0,4,8,6],activ:[7,10,8],state:[0,7,8,10],should:[7,10,8,9],busi:8,factor:[7,10],iec:2,local:[0,8],storagenam:[7,10,8],unus:8,variou:[4,7,8,10],get:[8,9,6],express:[4,7,8,9,10],stop:[5,7,8,10],vallei:3,becaus:5,regularli:5,storage_clos:[7,10],cannot:[5,8],increas:8,dataexpr:[7,10],restart:5,tvalu:[7,10],xmlstorag:8,organ:5,twice:8,integr:6,partit:[0,8,4,5,7,10],contain:[0,8,3,5,6,7,10],tuner:0,where:[0,7,8,10,6],durabilityqospolici:8,myservic:8,set:[4,1,10,7],xtype:2,"float":[7,10,8],reliabilityqospolici:8,startup:[5,8],see:[5,8,9],full:[8,6],mandatori:8,cond_lifecycl:[7,10],respons:8,reserv:[7,10,3],lifespan_period:8,subject:3,awar:8,statu:[0,1,10,7,4],interestexpr:[7,10,8],struct:[7,10],discoveri:4,written:8,volatil:[5,8],between:[5,8],"import":[5,8],subscript:8,inclus:[7,10],approach:5,attribut:[7,10,8],accord:6,omg:2,kei:[7,10,8,6],induc:0,flow:0,rostand:3,extens:[5,8,2,10,7],latency_period:8,addit:[0,5,8,9],scenario_stop:[7,10],both:5,last:8,cycl:8,howev:8,hint:6,against:8,audienc:1,instanc:[0,5,8,10,7],logic:4,scenariostatu:[7,10,8],whole:3,removerecordcommand:[7,10],compromis:5,fvalu:[7,10],simpli:8,point:[7,10,8],wall:[7,10],overview:[1,6],inher:[0,4],period:[7,10,8],except:8,myscenario:8,colon:8,shutdown:8,suppli:[8,9],respect:[0,4],guid:6,assum:5,coincid:5,liabil:3,java:[2,6],creat:[4,1],sarl:3,union:[7,10,8],storage_error:[7,10],valuekind:[7,10],been:[5,7,8,10,6],compon:8,time_invalid_nsec:[7,10,8],trigger:0,valu:[7,10,8],interest:[4,7,8,9,10],subscrib:[0,4,8,5],immedi:[5,8],addrecord:[7,10],life:8,cond_data:[7,10],mine:4,decim:8,understand:[5,8],togeth:8,add_replay_command:[7,1,10],those:[5,8],"case":[0,5,8,10,7],ident:[5,8],servic:[0,1,2,4,5,6,7,10,9],properti:[7,10,8],budget:8,durat:8,defin:[5,7,8,10],"while":[5,8],behavior:8,error:[7,10,8],scenariost:[7,10],gateshead:3,storageattr:[7,10,8],helper:[7,10,8],readi:8,outofresourc:8,deliv:[5,8],linkedin:3,middlewar:[4,5,8],itself:8,time_t:[7,10,8],"null":8,develop:5,copy_from_topic_qo:8,receiv:[7,10],make:8,format:8,same:[5,8],member:[7,10,8],preserv:[5,8],throughput:4,document:[6,2,3],complet:[8,6],deadlin:8,http:3,nest:5,upon:[7,10,8],effect:8,capabl:[4,5],user:6,ownership:8,ownership_strength:8,footprint:4,decoupl:4,chang:[8,3,4,5,7,10],recent:8,servicestatu:[7,10,8],scenario:[4,1,10,7,6],macro:8,thu:[0,8],well:4,"__built":9,without:[8,3],exampl:8,command:[0,1,4,7,10,9],thi:[0,8,3,5,6,7,10,9],choos:8,programm:6,model:[5,7,10],woburn:3,ubuntu:6,usual:8,protocol:5,paus:8,just:[4,8],cond_abs_tim:[7,10],obtain:0,via:6,excludedattributeexpr:[7,10],aspect:[0,8],comput:0,speed:[4,7,8,10],filterexpr:[7,10],languag:[2,6],previous:8,web:3,cut:8,miscellan:1,easi:4,also:[5,8],builtin:[7,10],shortcut:8,add:[7,10,8,9],valid:[7,10,8],bibliographi:6,versa:0,cdr:4,introduct:1,dds_dcp:[7,10],modul:[5,7,10],match:[5,7,8,10],real:2,applic:[0,5,8],milli:8,transpar:[0,4],read:[5,8],adlinktech:3,arriv:5,rr_scenario:[5,8],traffic:0,rr_storagestatist:8,dcpstopic:9,characterist:[0,8],formal:2,insert:[7,10,8],storagestatist:[7,10,8],rr_scenariostatu:8,like:[0,5],success:8,corpor:3,manual:8,resolv:8,vortex:0,either:8,have:[5,8,9],architectur:[4,2],manag:[5,8,2],psm:2,storage_outofresourc:[7,10],www:3,right:3,old:5,acknowledg:3,interv:8,linux:6,some:8,unrecover:[7,10],sampl:[0,4,8,10,7],mirror:8,guarante:5,successfulli:[7,10,8],transport:8,numberofsamplesrecord:[7,10],feder:0,cond_rel_tim:[7,10],definit:[0,5,6],benefit:4,overlap:8,summar:[0,9],inject:5,condit:[4,7,8,10],notabl:8,reflect:8,previou:[5,7,8,10],run:[0,5,8],service_initialis:[7,10],inspect:0,usag:5,broker:2,viabl:5,post:4,chapter:5,faith:3,about:1,actual:0,would:[0,5],page:1,stamp:8,lifecycl:[7,10],valuekind_boolean:[7,10],discard:8,produc:8,block:[7,10],pluggabl:4,own:8,durabilityserviceqospolici:8,opensplic:[0,1,2,3,4,5,6,7,8,9,10],replayrateminimum:[7,10],within:8,useoriginaltimestamp:[7,10,8],orsai:3,publish_interv:8,upgrad:5,down:[7,10,8],numberofbytesreplai:[7,10],empti:[7,10,8],trademark:3,ensur:9,opportun:8,storag:[4,1,10,9,7],durabl:1,merg:5,occupi:0,accordingli:8,log:8,wai:0,few:0,support:[5,7,8,10],enabl:[0,8],transform:[5,7,8,10],fast:[7,10,8],why:8,avail:[4,5,6,8,3],start:[5,7,8,10,6],compliant:8,includ:[8,5,6,7,10,9],replac:[5,8],forward:[0,7,10],strictli:5,twitter:3,"function":6,human:8,offer:4,regard:8,adlink:[6,3],"true":[7,10,8],reset:8,notat:8,made:[7,10,3],extcommand:[7,10],possibl:[5,7,8,10],"default":8,service_oper:[7,10],maximum:8,lifespan:8,record:[0,7,10],below:6,limit:[8,3,6,7,10,9],highlight:5,quickli:6,similar:8,featur:[0,1],evalu:8,certain:8,dure:[4,5,8],doesn:8,deem:8,exist:[0,5,8,6],file:[4,7,8,10],probabl:5,again:[5,8],generic_command:[7,10],use_topic_qo:8,googl:5,valuekind_str:[7,10],tester:6,when:[0,5,8,10,7],detail:[5,8,6],invalid:8,field:8,other:[0,5,8],futur:[7,10,8],you:4,historyqospolici:8,conditionkind:[7,10],realiti:8,node:[0,5],intend:1,determin:8,sequenc:[7,10,8],asterisk:8,time_invalid_sec:[7,10,8],intent:0,consid:[0,7,8,10],stai:0,longer:5,furthermor:8,vice:0,anywher:0,reliabl:8,storagest:[7,10],descript:[8,6],discrimin:[7,10],mimic:8,ignor:8,time:[2,4,5,8,7,10],replayratemaximum:[7,10],backward:5},objtypes:{},objnames:{},filenames:["impact","index","bibliography","contacts","introduction","scenarios","preface","appendixab","topic-api-overview","issues","appendixa"],titles:["6. Impact on DDS Domain","The Vortex Record and Replay API Reference","8. References","9. Contacts & Notices","2. Introduction","3. Scenarios","1. Preface","Appendix A","4. Topic API Overview","5. Known Issues","7. Appendix A"],objects:{},titleterms:{control:8,domain:0,replai:[1,8,6],set:8,timerang:8,creat:9,overview:8,indic:1,topic:[5,7,8,9,10],api:[7,1,8,10,6],abil:9,tabl:1,intend:6,storag:8,durabl:5,impact:0,differ:5,miscellan:8,convent:6,add_record_command:8,audienc:6,relev:8,version:5,keyvalu:8,type:8,refer:[1,2,6],builtinscenario:5,truncate_command:8,statist:8,about:6,notic:3,intrus:0,appendix:[7,10],vortex:1,remove_replay_command:8,known:9,rnr:[7,10],add_replay_command:8,featur:4,introduct:4,prefac:6,setreplayspeed_command:8,specif:[7,10],scenario:[5,8],statu:8,config:8,servic:8,issu:9,record:[1,8,6],idl:[7,10],contact:3,command:[5,8],organis:6,remove_record_command:8}}) \ No newline at end of file diff --git a/docs/html/RnRAPIReference/topic-api-overview.html b/docs/html/RnRAPIReference/topic-api-overview.html index d5ed7b395..93e475a46 100644 --- a/docs/html/RnRAPIReference/topic-api-overview.html +++ b/docs/html/RnRAPIReference/topic-api-overview.html @@ -828,7 +828,7 @@

    Navigation

    \ No newline at end of file diff --git a/docs/html/RnRManagerGuide/_images/011_Domain_Wizard.png b/docs/html/RnRManagerGuide/_images/011_Domain_Wizard.png index d37e34fe1..11e9cf5a5 100644 Binary files a/docs/html/RnRManagerGuide/_images/011_Domain_Wizard.png and b/docs/html/RnRManagerGuide/_images/011_Domain_Wizard.png differ diff --git a/docs/html/RnRManagerGuide/_images/058_ImportStorage.png b/docs/html/RnRManagerGuide/_images/058_ImportStorage.png index 552adceec..000b30dde 100644 Binary files a/docs/html/RnRManagerGuide/_images/058_ImportStorage.png and b/docs/html/RnRManagerGuide/_images/058_ImportStorage.png differ diff --git a/docs/html/RnRManagerGuide/_sources/contacts.txt b/docs/html/RnRManagerGuide/_sources/contacts.txt index fc6442d3a..d32f6016f 100644 --- a/docs/html/RnRManagerGuide/_sources/contacts.txt +++ b/docs/html/RnRManagerGuide/_sources/contacts.txt @@ -1,53 +1 @@ -.. _`Contacts & Notices`: - -.. VERY LITTLE EVER CHANGES IN HERE !! - Just keep an eye on the copyright notice. - -################## -Contacts & Notices -################## - -******** -Contacts -******** - -| **PrismTech Corporation** -| 400 TradeCenter -| Suite 5900 -| Woburn, MA -| 01801 -| USA -| Tel: +1 781 569 5819 - -| **PrismTech Limited** -| PrismTech House -| 5th Avenue Business Park -| Gateshead -| NE11 0NG -| UK -| Tel: +44 (0)191 497 9900 - -| **PrismTech France** -| 28 rue Jean Rostand -| 91400 Orsay -| France -| Tel: +33 (1) 69 015354 - - -Web: http://www.prismtech.com - -E-mail: \info@prismtech.com - -******* -Notices -******* - -**Copyright** © 2016 PrismTech Limited. All rights reserved. - -*This document may be reproduced in whole but not in part. -The information contained in this document is subject to change -without notice and is made available in good faith without -liability on the part of PrismTech Limited or PrismTech Corporation. -All trademarks acknowledged.* - -.. END +.. include:: ../../common/contacts.rst diff --git a/docs/html/RnRManagerGuide/_sources/index.txt b/docs/html/RnRManagerGuide/_sources/index.txt index dfa6ace20..f34c14b04 100644 --- a/docs/html/RnRManagerGuide/_sources/index.txt +++ b/docs/html/RnRManagerGuide/_sources/index.txt @@ -7,14 +7,14 @@ The Vortex Record and Replay Manager User Guide .. toctree:: :maxdepth: 6 :numbered: - + preface introduction installation using01 - - contacts - + + contacts + Indices and tables ================== diff --git a/docs/html/RnRManagerGuide/_sources/installation.txt b/docs/html/RnRManagerGuide/_sources/installation.txt index ee4fd66cf..ae87cf510 100644 --- a/docs/html/RnRManagerGuide/_sources/installation.txt +++ b/docs/html/RnRManagerGuide/_sources/installation.txt @@ -71,7 +71,7 @@ Installing the license file Please refer to the Vortex OpenSplice *Getting Started Guide* for full details of how Vortex OpenSplice is licensed. -PrismTech supplies a license file for the RnR Manager product. This file +ADLINK supplies a license file for the RnR Manager product. This file is *not* included in the software distribution. During the installation, you have the option of specifying the license @@ -125,4 +125,4 @@ Click the button *Restart Workbench* after importing the license file. .. |java| image:: ./images/icon-java.* :height: 6mm - \ No newline at end of file + diff --git a/docs/html/RnRManagerGuide/_sources/introduction.txt b/docs/html/RnRManagerGuide/_sources/introduction.txt index c2a8a10de..791b9a1df 100644 --- a/docs/html/RnRManagerGuide/_sources/introduction.txt +++ b/docs/html/RnRManagerGuide/_sources/introduction.txt @@ -12,12 +12,12 @@ Introduction Overview ******** -This section provides a brief introduction to the OpenSplice DDS +This section provides a brief introduction to the Vortex OpenSplice RnR Service and the RnR Manager tool. |caution| Version 6.4 of RnR Manager is compatible with Vortex OpenSplice - version 6.4. It is not compatible with earlier versions of OpenSplice. + version 6.4. It is not compatible with earlier versions of Vortex OpenSplice. Vortex OpenSplice Record and Replay Service @@ -83,7 +83,7 @@ for an existing system are: b) In the case of a dedicated RnR node, this partition can be configured to be a so-called ‘local partition’, thus bounding all control/status traffic to the RnR node (see Section 2.5.2.6 in the - OpenSplice *Deployment Guide*). + Vortex OpenSplice *Deployment Guide*). 3. Replaying (subsets) of recorded data ‘by definition’ has an impact on an existing system: @@ -106,7 +106,7 @@ data in a multicast-enabled network is non-intrusive. Note: *The few shared topic-definitions (definitions ONLY, not actual samples of these topics when these are ‘confined’ to the RnR node) that would be visible system-wide when inspecting the built-in topics of - the system (for instance with a tool like the OpenSplice Tuner) are + the system (for instance with a tool like the Vortex OpenSplice Tuner) are considered not instrusive as they only imply a small amount of static data space occupied by the related built-in topic samples.)* @@ -117,7 +117,7 @@ Please refer to the Vortex OpenSplice *Deployment Guide* (``OpenSplice_Deployment.pdf``) for more detailed information on how to configure Vortex OpenSplice. -The OpenSplice configuration editor (``osplconf``) provides facilities to +The Vortex OpenSplice configuration editor (``osplconf``) provides facilities to create, modify and save configuration files. This tool is described in Section 3.2 in the Vortex OpenSplice *Deployment Guide*. @@ -152,7 +152,7 @@ inspect and change recorded data. RnR Manager uses the internal Control and Monitoring API for access to the Vortex OpenSplice Middleware. Connections to local nodes *via* JNI and remote nodes (*via* SOAP) are supported. The manager tool does not need to have -OpenSplice DDS installed locally. A connection can be made remotely to a +Vortex OpenSplice installed locally. A connection can be made remotely to a node that is running Vortex OpenSplice. RnR Manager Features @@ -384,4 +384,4 @@ A range is defined with a start and an end timestamp. .. |java| image:: ./images/icon-java.* :height: 6mm - \ No newline at end of file + diff --git a/docs/html/RnRManagerGuide/_sources/preface.txt b/docs/html/RnRManagerGuide/_sources/preface.txt index 8cf390b3b..72e0656bb 100644 --- a/docs/html/RnRManagerGuide/_sources/preface.txt +++ b/docs/html/RnRManagerGuide/_sources/preface.txt @@ -45,7 +45,7 @@ of RnR Manager. Conventions *********** -The icons shown below are used in PrismTech product documentation +The icons shown below are used in Vortex product documentation to help readers to quickly identify information relevant to their specific use of Vortex OpenSplice. @@ -86,4 +86,4 @@ specific use of Vortex OpenSplice. .. |java| image:: ./images/icon-java.* :height: 6mm - \ No newline at end of file + diff --git a/docs/html/RnRManagerGuide/contacts.html b/docs/html/RnRManagerGuide/contacts.html index 0833c8303..bb068a098 100644 --- a/docs/html/RnRManagerGuide/contacts.html +++ b/docs/html/RnRManagerGuide/contacts.html @@ -14,7 +14,7 @@ + + + + + + + + + + + + + + + + + +
    +
    +
    +
    + +
    +

    dds module¶

    +

    DDS Python DCPS API class

    +
    +
    +class dds.Condition¶
    +

    Bases: object

    +

    Abstract condition class

    +
    +
    +triggered()¶
    +
    + +
    + +
    +
    +class dds.DDSDestinationOrderKind¶
    +

    Bases: enum.Enum

    +
    +
    +BY_RECEPTION_TIMESTAMP = 0¶
    +
    + +
    +
    +BY_SOURCE_TIMESTAMP = 1¶
    +
    + +
    + +
    +
    +class dds.DDSDurabilityKind¶
    +

    Bases: enum.Enum

    +
    +
    +PERSISTENT = 3¶
    +
    + +
    +
    +TRANSIENT = 2¶
    +
    + +
    +
    +TRANSIENT_LOCAL = 1¶
    +
    + +
    +
    +VOLATILE = 0¶
    +
    + +
    + +
    +
    +class dds.DDSDuration¶
    +

    Bases: dds.DDSTime

    +

    DDS Duration

    + +++ + + + +
    Parameters:
      +
    • sec (long) – seconds (default: 0)
    • +
    • nanosec (long) – nanoseconds (default: 0)
    • +
    +
    +
    +
    +infinity¶
    +

    Return DDSDuration for infinity

    +
    + +
    + +
    +
    +exception dds.DDSException¶
    +

    Bases: Exception

    +

    DDS exception

    +
    +
    +__init__()¶
    +
    + +
    + +
    +
    +class dds.DDSHistoryKind¶
    +

    Bases: enum.Enum

    +
    +
    +KEEP_ALL = 1¶
    +
    + +
    +
    +KEEP_LAST = 0¶
    +
    + +
    + +
    +
    +class dds.DDSLivelinessKind¶
    +

    Bases: enum.Enum

    +
    +
    +AUTOMATIC = 0¶
    +
    + +
    +
    +MANUAL_BY_PARTICIPANT = 1¶
    +
    + +
    +
    +MANUAL_BY_TOPIC = 2¶
    +
    + +
    + +
    +
    +class dds.DDSMaskUtil¶
    +

    Bases: object

    +

    Mask utility. +Some commonly used mask combination +See DDSStateKind for list of available status

    +
    +
    +all_samples¶
    +

    [DDSStateKind.ANY_STATE]

    + +++ + + + + + +
    Return type:list
    Returns:list of DDSStateKind enumeration literals
    +
    + +
    +
    +new_instance_samples¶
    +

    [DDSStateKind.NOT_READ_SAMPLE_STATE, DDSStateKind.ALIVE_INSTANCE_STATE, DDSStateKind.NEW_VIEW_STATE]

    + +++ + + + + + +
    Return type:list
    Returns:list of DDSStateKind enumeration literals
    +
    + +
    +
    +new_samples¶
    +

    [DDSStateKind.NOT_READ_SAMPLE_STATE, DDSStateKind.ALIVE_INSTANCE_STATE, DDSStateKind.ANY_VIEW_STATE]

    + +++ + + + + + +
    Return type:list
    Returns:list of DDSStateKind enumeration literals
    +
    + +
    +
    +not_alive_instance_samples¶
    +

    [DDSStateKind.ANY_SAMPLE_STATE, DDSStateKind.ANY_VIEW_STATE, DDSStateKind.NOT_ALIVE_NO_WRITERS_INSTANCE_STATE, DDSStateKind.NOT_ALIVE_DISPOSED_INSTANCE_STATE]

    + +++ + + + + + +
    Return type:list
    Returns:list of DDSStateKind enumeration literals
    +
    + +
    +
    +read_samples¶
    +

    [DDSStateKind.READ_SAMPLE_STATE, DDSStateKind.ALIVE_INSTANCE_STATE, DDSStateKind.ANY_VIEW_STATE]

    + +++ + + + + + +
    Return type:list
    Returns:list of DDSStateKind enumeration literals
    +
    + +
    + +
    +
    +class dds.DDSOwnershipKind¶
    +

    Bases: enum.Enum

    +
    +
    +EXCLUSIVE = 1¶
    +
    + +
    +
    +SHARED = 0¶
    +
    + +
    + +
    +
    +class dds.DDSPresentationAccessScopeKind¶
    +

    Bases: enum.Enum

    +
    +
    +GROUP = 2¶
    +
    + +
    +
    +INSTANCE = 0¶
    +
    + +
    +
    +TOPIC = 1¶
    +
    + +
    + +
    +
    +class dds.DDSReliabilityKind¶
    +

    Bases: enum.Enum

    +
    +
    +BEST_EFFORT = 0¶
    +
    + +
    +
    +RELIABLE = 1¶
    +
    + +
    + +
    +
    +class dds.DDSStateKind¶
    +

    Bases: enum.Enum

    +
    +
    +ALIVE_INSTANCE_STATE = 16¶
    +
    + +
    +
    +ANY_INSTANCE_STATE = 112¶
    +
    + +
    +
    +ANY_SAMPLE_STATE = 3¶
    +
    + +
    +
    +ANY_STATE = 127¶
    +
    + +
    +
    +ANY_VIEW_STATE = 12¶
    +
    + +
    +
    +NEW_VIEW_STATE = 4¶
    +
    + +
    +
    +NOT_ALIVE_DISPOSED_INSTANCE_STATE = 32¶
    +
    + +
    +
    +NOT_ALIVE_NO_WRITERS_INSTANCE_STATE = 64¶
    +
    + +
    +
    +NOT_NEW_VIEW_STATE = 8¶
    +
    + +
    +
    +NOT_READ_SAMPLE_STATE = 2¶
    +
    + +
    +
    +READ_SAMPLE_STATE = 1¶
    +
    + +
    + +
    +
    +class dds.DDSStatusKind¶
    +

    Bases: enum.Enum

    +
    +
    +DATA_AVAILABLE = 1024¶
    +
    + +
    +
    +DATA_ON_READERS = 512¶
    +
    + +
    +
    +INCONSISTENT_TOPIC = 1¶
    +
    + +
    +
    +LIVELINESS_CHANGED = 4096¶
    +
    + +
    +
    +LIVELINESS_LOST = 2048¶
    +
    + +
    +
    +OFFERED_DEADLINE_MISSED = 2¶
    +
    + +
    +
    +OFFERED_INCOMPATIBLE_QOS = 32¶
    +
    + +
    +
    +PUBLICATION_MATCHED = 8192¶
    +
    + +
    +
    +REQUESTED_DEADLINE_MISSED = 4¶
    +
    + +
    +
    +REQUESTED_INCOMPATIBLE_QOS = 64¶
    +
    + +
    +
    +SAMPLE_LOST = 128¶
    +
    + +
    +
    +SAMPLE_REJECTED = 256¶
    +
    + +
    +
    +SUBSCRIPTION_MATCHED = 16384¶
    +
    + +
    + +
    +
    +class dds.DDSTime¶
    +

    Bases: object

    +

    DDS Time

    + +++ + + + +
    Parameters:
      +
    • sec (long) – seconds (default: 1)
    • +
    • nanosec (long) – nanoseconds (default: 0)
    • +
    +
    +
    +
    +__init__()¶
    +
    + +
    + +
    +
    +class dds.DataReader¶
    +

    Bases: dds.Entity

    +

    DataReader class

    +
    +
    +read(n=1, masks=DDSMaskUtil.all_samples())¶
    +

    Read samples

    + +++ + + + + + + + +
    Parameters:
      +
    • n (int) – number of samples to read
    • +
    • masks (list) – list of DDS statuses
    • +
    +
    Return type:

    list

    +
    Returns:

    list of sample data and sample info tuple

    +
    +
    + +
    +
    +take(n=1, masks=DDSMaskUtil.all_samples())¶
    +

    Take samples

    + +++ + + + + + + + +
    Parameters:
      +
    • n (int) – number of samples to take
    • +
    • masks (list) – list of DDS statuses
    • +
    +
    Return type:

    list

    +
    Returns:

    list of sample data and sample info tuple

    +
    +
    + +
    +
    +wait_for_historical_data(timeout = None)¶
    +

    Wait for data reader to receive historical data, up to timeout duration

    + +++ + + + + + + + +
    Parameters:timeout (DDSDuration) – timeout in seconds(default: infinity)
    Return type:boolean
    Returns:False if timeout exipred; True otherwise
    +
    + +
    + +
    +
    +class dds.DataWriter¶
    +

    Bases: dds.Entity

    +

    DataWriter class

    +
    +
    +dispose_instance(data)¶
    +

    Dispose instance

    + +++ + + + +
    Parameters:data (object) – Topic data class instance
    +
    + +
    +
    +dispose_instance_ts(data, ts)¶
    +

    Dispose instance with timestamp

    + +++ + + + +
    Parameters:
      +
    • data (object) – Topic data class instance
    • +
    • ts (long) – timestamp
    • +
    +
    +
    + +
    +
    +write(data)¶
    +

    Write data

    + +++ + + + +
    Parameters:data (object) – Topic data class instance
    +
    + +
    + +
    +
    +class dds.DeadlineQosPolicy¶
    +

    Bases: dds.QosPolicy

    +

    Deadline QoS Policy

    + +++ + + + +
    Parameters:deadline (DDSDuration) – Value for deadline (default: infinity)
    +
    +
    +__init__()¶
    +
    + +
    +
    +deadline¶
    +
    + +
    + +
    +
    +class dds.DestinationOrderQosPolicy¶
    +

    Bases: dds.QosPolicy

    +

    Destination order QoS Policy

    + +++ + + + +
    Parameters:kind (DDSDestinationOrderKind) – Destination order kind
    +
    +
    +__init__()¶
    +
    + +
    + +
    +
    +class dds.DomainParticipant¶
    +

    Bases: dds.Entity

    +

    Domain participant class

    + +++ + + + +
    Parameters:
      +
    • qos (Qos) – Participant QoS. Default: None
    • +
    • listener (Listener) – Participant listener Default: None
    • +
    +
    +
    +
    +create_datareader(Topic topic, Qos qos = None, listener = None)¶
    +

    Create a publisher

    + +++ + + + + + +
    Parameters:
      +
    • topic (Topic) – Topic
    • +
    • qos (QoS) – QoS
    • +
    • listener (Listener) – Listener
    • +
    +
    Return type:

    DataReader

    +
    +
    + +
    +
    +create_datawriter(Topic topic, Qos qos = None, listener = None)¶
    +

    Create a publisher

    + +++ + + + + + +
    Parameters:
      +
    • topic (Topic) – Topic
    • +
    • qos (QoS) – QoS
    • +
    • listener (Listener) – Listener
    • +
    +
    Return type:

    DataWriter

    +
    +
    + +
    +
    +create_publisher(Qos qos = None, listener = None)¶
    +

    Create a publisher

    + +++ + + + + + +
    Parameters:
      +
    • qos (QoS) – QoS
    • +
    • listener (Listener) – Listener
    • +
    +
    Return type:

    Publisher

    +
    +
    + +
    +
    +create_subscriber(Qos qos = None, listener = None)¶
    +

    Create a subscriber

    + +++ + + + + + +
    Parameters:
      +
    • qos (QoS) – QoS
    • +
    • listener (Listener) – Listener
    • +
    +
    Return type:

    Subscriber

    +
    +
    + +
    + +
    +
    +class dds.DurabilityQosPolicy¶
    +

    Bases: dds.QosPolicy

    +

    Durability QoS Policy

    + +++ + + + +
    Parameters:k (DDSDurabilityKind) – Durability kind
    +
    +
    +__init__(k=DDSDurabilityKind.VOLATILE)¶
    +
    + +
    + +
    +
    +class dds.DurabilityServiceQosPolicy¶
    +

    Bases: dds.QosPolicy

    +

    Durability service QoS Policy

    + +++ + + + +
    Parameters:
      +
    • service_cleanup_delay (DDSDuration) – set service_cleanup_delay (default: 0)
    • +
    • history_kind (DDSHistoryKind) – set history kind (default: KEEP_LAST)
    • +
    • history_depth (long) – set history_depth (default: 1)
    • +
    • max_samples (long) – set max_samples (default: unlimited)
    • +
    • max_instances (long) – set max_instances (default: unlimited)
    • +
    • max_samples_per_instance (long) – set max_samples_per_instance (default: unlimited)
    • +
    +
    +
    +
    +__init__()¶
    +
    + +
    +
    +history_depth¶
    +
    + +
    +
    +history_kind¶
    +
    + +
    +
    +max_instances¶
    +
    + +
    +
    +max_samples¶
    +
    + +
    +
    +max_samples_per_instance¶
    +
    + +
    +
    +service_cleanup_delay¶
    +
    + +
    + +
    +
    +class dds.Entity¶
    +

    Bases: object

    +

    Abstract base entity class

    +
    +
    +get_statuscondition()¶
    +
    + +
    +
    +listener¶
    +

    Listener

    +
    + +
    +
    +parent¶
    +

    Parent entity

    +
    + +
    + +
    +
    +class dds.GroupdataQosPolicy¶
    +

    Bases: dds.UserdataQosPolicy

    +

    Group data QoS Policy

    + +++ + + + +
    Parameters:value (string) – value
    +
    +
    +__init__()¶
    +
    + +
    + +
    +
    +class dds.GuardCondition¶
    +

    Bases: dds.Condition

    +

    Guard condition

    +
    +
    +reset()¶
    +

    Reset guard condition

    +
    + +
    +
    +trigger()¶
    +

    Trigger guard condition

    +
    + +
    + +
    +
    +class dds.HistoryQosPolicy¶
    +

    Bases: dds.QosPolicy

    +

    History QoS Policy

    + +++ + + + +
    Parameters:
      +
    • k (DDSHistoryKind) – History kind
    • +
    • depth (int) – History depth (default: 1)
    • +
    +
    +
    +
    +__init__(kind=DDSHistoryKind.KEEP_LAST, depth=1)¶
    +
    + +
    +
    +depth¶
    +
    + +
    + +
    +
    +class dds.LatencyBudgetQosPolicy¶
    +

    Bases: dds.QosPolicy

    +

    Latency budget QoS Policy

    + +++ + + + +
    Parameters:duration (DDSDuration) – Value for duration (default: 0)
    +
    +
    +__init__()¶
    +
    + +
    +
    +duration¶
    +
    + +
    + +
    +
    +class dds.LifespanQosPolicy¶
    +

    Bases: dds.QosPolicy

    +

    Lifespan QoS Policy

    + +++ + + + +
    Parameters:lifespan (DDSDuration) – Value for lifespan (default: infinity)
    +
    +
    +__init__()¶
    +
    + +
    +
    +lifespan¶
    +
    + +
    + +
    +
    +class dds.Listener¶
    +

    Bases: object

    +

    Abstract Listener class. +Beta: only on_data_available is implemented.

    +
    +
    +__init__()¶
    +
    + +
    +
    +on_data_available(entity)¶
    +
    + +
    +
    +on_data_readers(entity)¶
    +
    + +
    +
    +on_inconsistent_topic(entity, status)¶
    +
    + +
    +
    +on_liveliness_changed(entity, status)¶
    +
    + +
    +
    +on_liveliness_lost(entity, status)¶
    +
    + +
    +
    +on_offered_deadline_missed(entity, status)¶
    +
    + +
    +
    +on_offered_incompatible_qos(entity, status)¶
    +
    + +
    +
    +on_publication_matched(entity, status)¶
    +
    + +
    +
    +on_requested_deadline_missed(entity, status)¶
    +
    + +
    +
    +on_requested_incompatible_qos(entity, status)¶
    +
    + +
    +
    +on_sample_lost(entity, status)¶
    +
    + +
    +
    +on_sample_rejected(entity, status)¶
    +
    + +
    +
    +on_subscription_matched(entity, status)¶
    +
    + +
    + +
    +
    +class dds.LivelinessQosPolicy¶
    +

    Bases: dds.QosPolicy

    +

    Liveliness QoS Policy

    + +++ + + + +
    Parameters: +
    +
    +
    +__init__()¶
    +
    + +
    +
    +lease_duration¶
    +
    + +
    + +
    +
    +class dds.OwnershipQosPolicy¶
    +

    Bases: dds.QosPolicy

    +

    Ownership QoS Policy

    + +++ + + + +
    Parameters:kind (DDSOwnershipKind) – Ownership kind
    +
    +
    +__init__()¶
    +
    + +
    + +
    +
    +class dds.OwnershipStrengthQosPolicy¶
    +

    Bases: dds.QosPolicy

    +

    Ownership strenth QoS Policy

    + +++ + + + +
    Parameters:value (int) – value for strength (default: 0)
    +
    +
    +__init__()¶
    +
    + +
    +
    +value¶
    +
    + +
    + +
    +
    +class dds.PartitionQosPolicy¶
    +

    Bases: dds.QosPolicy

    +

    Partition QoS Policy

    + +++ + + + +
    Parameters:ps (list) – list of partition names
    +
    +
    +__init__()¶
    +
    + +
    +
    +ps¶
    +
    + +
    + +
    +
    +class dds.PresentationQosPolicy¶
    +

    Bases: dds.QosPolicy

    +

    Presentation QoS Policy

    + +++ + + + +
    Parameters:
      +
    • kind (DDSPresentationAccessScopeKind) – Presentation kind (default: INSTANCE)
    • +
    • coherent_access (bool) – Set coherent access (default: False)
    • +
    • ordered_access (bool) – Set ordered access (default: False)
    • +
    +
    +
    +
    +__init__(kind=DDSHistoryKind.KEEP_LAST, depth=1)¶
    +
    + +
    +
    +coherent_access¶
    +
    + +
    +
    +ordered_access¶
    +
    + +
    + +
    +
    +class dds.Publisher¶
    +

    Bases: dds.Entity

    +

    Publisher class

    +
    +
    +create_datawriter(Topic topic, Qos qos = None, listener = None)¶
    +

    Create a data writer +:type topic: Topic +:param topic: Topic

    + +++ + + + + + +
    Parameters:
      +
    • qos (Qos) – Qos
    • +
    • listener (Listener) – Listener
    • +
    +
    Return type:

    DataWriter

    +
    +
    + +
    + +
    +
    +class dds.Qos¶
    +

    Bases: object

    +

    QoS class

    + +++ + + + +
    Parameters:policies (list) – list of QoS policies
    +
    +
    +set_policies(policies)¶
    +

    Set policies +:type policies: list +:param policies: list of QoS policies

    +
    + +
    + +
    +
    +class dds.QosPolicy¶
    +

    Bases: object

    +

    Abstract QoS policy class. +Users should not instantiate this class.

    +
    +
    +__init__(i)¶
    +
    + +
    +
    +id¶
    +

    An internal QoS Policy id

    +
    + +
    +
    +kind¶
    +

    QoS Policy kind

    +
    + +
    + +
    +
    +class dds.QosProfile¶
    +

    Bases: object

    +

    QoS Provider class

    + +++ + + + +
    Parameters:
      +
    • uri (string) – uri to xml file
    • +
    • profile (string) – profile name
    • +
    +
    +
    +
    +get_participant_qos()¶
    +

    Create participant QoS

    + +++ + + + +
    Return type:Qos
    +
    + +
    +
    +get_publisher_qos()¶
    +

    Create publisher QoS

    + +++ + + + +
    Return type:Qos
    +
    + +
    +
    +get_reader_qos()¶
    +

    Create reader QoS

    + +++ + + + +
    Return type:Qos
    +
    + +
    +
    +get_subscriber_qos()¶
    +

    Create subscriber QoS

    + +++ + + + +
    Return type:Qos
    +
    + +
    +
    +get_topic_qos()¶
    +

    Create topic QoS

    + +++ + + + +
    Return type:Qos
    +
    + +
    +
    +get_writer_qos()¶
    +

    Create writer QoS

    + +++ + + + +
    Return type:Qos
    +
    + +
    + +
    +
    +class dds.QueryCondition¶
    +

    Bases: dds.Condition

    +

    Query condition

    + +++ + + + +
    Parameters:
      +
    • reader (DataReader) – Source DataReader
    • +
    • masks (list) – list of masks (default: DDSMaskUtil.all_samples()
    • +
    • expression (string) – Expression
    • +
    • parameters (list) – list of parameters in string
    • +
    +
    +
    + +
    +
    +class dds.ReadCondition¶
    +

    Bases: dds.Condition

    +

    Read condition

    + +++ + + + +
    Parameters:
      +
    • reader (DataReader) – Source DataReader
    • +
    • masks (list) – list of masks (default: DDSMaskUtil.all_samples()
    • +
    +
    +
    + +
    +
    +class dds.ReaderDataLifecycleQosPolicy¶
    +

    Bases: dds.QosPolicy

    +

    Reader data lifecycle QoS Policy

    + +++ + + + +
    Parameters:
      +
    • autopurge_nowriter_samples (DDSDuration) – set autopurge_nowriter_samples (default: infinity)
    • +
    • autopurge_disposed_samples_delay (DDSDuration) – set autopurge_nowriter_samples (default: infinity)
    • +
    +
    +
    +
    +__init__()¶
    +
    + +
    +
    +autopurge_disposed_samples_delay¶
    +
    + +
    +
    +autopurge_nowriter_samples¶
    +
    + +
    + +
    +
    +class dds.ReliabilityQosPolicy¶
    +

    Bases: dds.QosPolicy

    +

    Reliability QoS Policy

    + +++ + + + +
    Parameters: +
    +
    +
    +__init__()¶
    +
    + +
    +
    +max_blocking_time¶
    +
    + +
    + +
    +
    +class dds.ResourceLimitsQosPolicy¶
    +

    Bases: dds.QosPolicy

    +

    Resource limit QoS Policy

    + +++ + + + +
    Parameters:
      +
    • max_samples (int) – maximum samples (default: -1)
    • +
    • max_instances (int) – maximum instances (default: -1)
    • +
    • max_samples_per_instance (int) – maximum samples per instance (default: -1)
    • +
    +
    +
    +
    +__init__()¶
    +
    + +
    +
    +max_instances¶
    +
    + +
    +
    +max_samples¶
    +
    + +
    +
    +max_samples_per_instance¶
    +
    + +
    + +
    +
    +class dds.SampleInfo¶
    +

    Bases: object

    +

    Base sample info class

    +
    +
    +__init__()¶
    +
    + +
    + +
    +
    +class dds.StatusCondition¶
    +

    Bases: dds.Condition

    +

    Status condition

    + +++ + + + +
    Parameters:entity (Entity) – Source entity
    +
    +
    +enable_status()¶
    +
    + +
    +
    +entity¶
    +
    + +
    +
    +get_enabled_status()¶
    +
    + +
    + +
    +
    +class dds.Subscriber¶
    +

    Bases: dds.Entity

    +

    Subscriber class

    +
    +
    +create_datareader(Topic topic, Qos qos = None, listener = None)¶
    +

    Create a data reader +:type topic: Topic +:param topic: Topic

    + +++ + + + + + +
    Parameters:
      +
    • qos (Qos) – Qos
    • +
    • listener (Listener) – Listener
    • +
    +
    Return type:

    DataReader

    +
    +
    + +
    + +
    +
    +class dds.TimeBasedFilterQosPolicy¶
    +

    Bases: dds.QosPolicy

    +

    Time based filter QoS Policy

    + +++ + + + +
    Parameters:minimum_separation (DDSDuration) – Value for minimum separation (default: 0)
    +
    +
    +__init__()¶
    +
    + +
    +
    +minimum_separation¶
    +
    + +
    + +
    +
    +class dds.Topic¶
    +

    Bases: dds.Entity

    +

    Topic class

    + +++ + + + +
    Parameters:
      +
    • dp (DomainParticipant) – Domain participant
    • +
    • name (string) – Topic name
    • +
    • qos (Qos) – Topic QoS (default: None)
    • +
    • listener (Listener) – Topic listener (default: None)
    • +
    +
    +
    + +
    +
    +class dds.TopicdataQosPolicy¶
    +

    Bases: dds.UserdataQosPolicy

    +

    Topic data QoS Policy

    + +++ + + + +
    Parameters:value (string) – value
    +
    +
    +__init__()¶
    +
    + +
    + +
    +
    +class dds.TransportPriorityQosPolicy¶
    +

    Bases: dds.QosPolicy

    +

    Transport priority QoS Policy

    + +++ + + + +
    Parameters:value (int) – value for transport priority
    +
    +
    +__init__()¶
    +
    + +
    +
    +value¶
    +
    + +
    + +
    +
    +class dds.TypeSupport¶
    +

    Bases: object

    +

    It is used to generate a dds_topic_descriptor from the +provided typename, keys and XML type specification. +The size attribute is need to allocate memory when +the topic data is deserialized. +For the serialization and deserialization the struct +module is used

    +
    +
    +__init__¶
    +

    Initialize self. See help(type(self)) for accurate signature.

    +
    + +
    +
    +deserialize(b)¶
    +

    Deserialize data

    +
    + +
    +
    +handle¶
    +

    C handle

    +
    + +
    +
    +serialize(o)¶
    +

    Serialize data

    +
    + +
    +
    +size¶
    +

    Data size

    +
    + +
    + +
    +
    +class dds.UserdataQosPolicy¶
    +

    Bases: dds.QosPolicy

    +

    Userdata QoS Policy

    + +++ + + + +
    Parameters:value (string) – value
    +
    +
    +__init__()¶
    +
    + +
    +
    +value¶
    +
    + +
    + +
    +
    +class dds.WaitSet¶
    +

    Bases: object

    +

    WaitSet class

    +
    +
    +attach(Condition cond)¶
    +

    Attach condition +:type cond: Condition +:param cond: condition to attach

    +
    + +
    +
    +detach(Condition cond)¶
    +

    Detach condition

    + +++ + + + +
    Parameters:cond (Condition) – condition to detach
    +
    + +
    +
    +get_conditions()¶
    +

    Return conditions

    +
    + +
    +
    +wait(timeout = DDSDuration.infinity())¶
    +

    Wait for any of the conditions attached to the waitset to be triggered

    + +++ + + + + + + + +
    Parameters:timeout (DDSDuration) – timeout in seconds(default: infinity)
    Return type:list
    Returns:list of Condition objects that were triggered. list is empty if timeout expired
    +
    + +
    + +
    +
    +class dds.WriterDataLifecycleQosPolicy¶
    +

    Bases: dds.QosPolicy

    +

    Writer data lifecycle QoS Policy

    + +++ + + + +
    Parameters:autodispose_unregistered_instances (bool) – set autodispose_unregistered_instances (default: true)
    +
    +
    +__init__()¶
    +
    + +
    +
    +autodispose_unregistered_instances¶
    +
    + +
    + +
    + + +
    +
    +
    + +
    +
    + + + + + + + \ No newline at end of file diff --git a/src/api/dcps/python/docs/html/ddsutil.html b/src/api/dcps/python/docs/html/ddsutil.html new file mode 100644 index 000000000..05689399a --- /dev/null +++ b/src/api/dcps/python/docs/html/ddsutil.html @@ -0,0 +1,226 @@ + + + + + + + ddsutil module — Python DCPS API 6.8.3 documentation + + + + + + + + + + + + + + + + + + + +
    +
    +
    +
    + +
    +

    ddsutil module¶

    +

    DDS descriptor utility module

    +

    Main purpose of this module is to provide methods to convert +DDS descriptor to Python classes dynamically.

    +

    Users can use IDL file as an input to generate classes

    +
    +
    +class ddsutil.GeneratedClassInfo(data_cls, type_support_cls, nested_types)¶
    +

    Bases: object

    +

    Place holder for generated classes

    + +++ + + + +
    Variables:
      +
    • topic_data_class – Topic data class
    • +
    • type_support_class – Type support class
    • +
    +
    +
    +
    +__init__(data_cls, type_support_cls, nested_types)¶
    +
    + +
    +
    +get_class(type_info)¶
    +

    Return classes created dynamically

    + +++ + + + +
    Parameters:type_info (string) – struct identifier (.e.g, “test::basic::inner_structâ€)
    +
    + +
    +
    +register_topic(dp, name, qos)¶
    +

    Register topic for generated topic data class

    + +++ + + + + + + + +
    Parameters:
      +
    • dp (DomainParticipant) – Domain participant
    • +
    • name (string) – topic name
    • +
    • qos (Qos) – topic QoS
    • +
    +
    Return type:

    Topic

    +
    Returns:

    topic

    +
    +
    + +
    + +
    +
    +ddsutil.get_dds_classes_from_idl(idl_path, type_info)¶
    +

    Create DDS topic data class and DDS type support class +from the given IDL file source.

    + +++ + + + + + + + +
    Parameters:
      +
    • idl_path (string) – path to IDL file
    • +
    • type_info (string) – struct module (e.g., test::basic::my_struct)
    • +
    +
    Return type:

    GeneratedClassInfo

    +
    Returns:

    GeneratedClassInfo

    +
    +
    +
    Examples:
    +
    gen_info = dds_class(“sample.idlâ€, “basic::test::Type1â€, “long_1â€)
    +
    +
    + +
    +
    +class ddsutil.TopicDataClass(member_names=[])¶
    +

    Bases: object

    +

    Abstract topic data class. +Generated classes inherits this base class.

    +
    +
    +__init__(member_names=[])¶
    +
    + +
    +
    +get_vars()¶
    +

    Return the dictionary of attribute and value pair for the topic data members.

    +
    + +
    +
    +print_vars()¶
    +

    Print values of all member variables.

    +
    + +
    + +
    + + +
    +
    +
    + +
    +
    + + + + + + + \ No newline at end of file diff --git a/src/api/dcps/python/docs/html/genindex.html b/src/api/dcps/python/docs/html/genindex.html new file mode 100644 index 000000000..3f1ce0d49 --- /dev/null +++ b/src/api/dcps/python/docs/html/genindex.html @@ -0,0 +1,742 @@ + + + + + + + + Index — Python DCPS API 6.8.3 documentation + + + + + + + + + + + + + + + + + + +
    +
    +
    +
    + + +

    Index

    + +
    + _ + | A + | B + | C + | D + | E + | G + | H + | I + | K + | L + | M + | N + | O + | P + | Q + | R + | S + | T + | U + | V + | W + +
    +

    _

    + + +
    + +

    A

    + + + +
    + +

    B

    + + + +
    + +

    C

    + + + +
    + +

    D

    + + + +
    + +

    E

    + + + +
    + +

    G

    + + + +
    + +

    H

    + + + +
    + +

    I

    + + + +
    + +

    K

    + + + +
    + +

    L

    + + + +
    + +

    M

    + + + +
    + +

    N

    + + + +
    + +

    O

    + + + +
    + +

    P

    + + + +
    + +

    Q

    + + + +
    + +

    R

    + + + +
    + +

    S

    + + + +
    + +

    T

    + + + +
    + +

    U

    + + +
    + +

    V

    + + + +
    + +

    W

    + + + +
    + + + +
    +
    +
    + +
    +
    + + + + + + + \ No newline at end of file diff --git a/src/api/dcps/python/docs/html/index.html b/src/api/dcps/python/docs/html/index.html new file mode 100644 index 000000000..1ef5db424 --- /dev/null +++ b/src/api/dcps/python/docs/html/index.html @@ -0,0 +1,111 @@ + + + + + + + code — Python DCPS API 6.8.3 documentation + + + + + + + + + + + + + + + + + + + +
    +
    +
    +
    + +
    +

    code¶

    + +
    + + +
    +
    +
    + +
    +
    + + + + + + + \ No newline at end of file diff --git a/src/api/dcps/python/docs/html/objects.inv b/src/api/dcps/python/docs/html/objects.inv new file mode 100644 index 000000000..a841fb2bd Binary files /dev/null and b/src/api/dcps/python/docs/html/objects.inv differ diff --git a/src/api/dcps/python/docs/html/py-modindex.html b/src/api/dcps/python/docs/html/py-modindex.html new file mode 100644 index 000000000..6ef062294 --- /dev/null +++ b/src/api/dcps/python/docs/html/py-modindex.html @@ -0,0 +1,126 @@ + + + + + + + Python Module Index — Python DCPS API 6.8.3 documentation + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    +
    + + +

    Python Module Index

    + +
    + d +
    + + + + + + + + + + +
     
    + d
    + dds +
    + ddsutil +
    + + +
    +
    +
    + +
    +
    + + + + + + + \ No newline at end of file diff --git a/src/api/dcps/python/docs/html/search.html b/src/api/dcps/python/docs/html/search.html new file mode 100644 index 000000000..c5a2e99d4 --- /dev/null +++ b/src/api/dcps/python/docs/html/search.html @@ -0,0 +1,117 @@ + + + + + + + Search — Python DCPS API 6.8.3 documentation + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    +
    + +

    Search

    +
    + +

    + Please activate JavaScript to enable the search + functionality. +

    +
    +

    + From here you can search these documents. Enter your search + words into the box below and click "search". Note that the search + function will automatically search for all of the words. Pages + containing fewer words won't appear in the result list. +

    +
    + + + +
    + +
    + +
    + +
    +
    +
    + +
    +
    + + + + + + + \ No newline at end of file diff --git a/src/api/dcps/python/docs/html/searchindex.js b/src/api/dcps/python/docs/html/searchindex.js new file mode 100644 index 000000000..84283894a --- /dev/null +++ b/src/api/dcps/python/docs/html/searchindex.js @@ -0,0 +1 @@ +Search.setIndex({docnames:["dds","ddsutil","index"],envversion:53,filenames:["dds.rst","ddsutil.rst","index.rst"],objects:{"":{dds:[0,0,0,"-"],ddsutil:[1,0,0,"-"]},"dds.Condition":{triggered:[0,2,1,""]},"dds.DDSDestinationOrderKind":{BY_RECEPTION_TIMESTAMP:[0,3,1,""],BY_SOURCE_TIMESTAMP:[0,3,1,""]},"dds.DDSDurabilityKind":{PERSISTENT:[0,3,1,""],TRANSIENT:[0,3,1,""],TRANSIENT_LOCAL:[0,3,1,""],VOLATILE:[0,3,1,""]},"dds.DDSDuration":{infinity:[0,3,1,""]},"dds.DDSException":{__init__:[0,2,1,""]},"dds.DDSHistoryKind":{KEEP_ALL:[0,3,1,""],KEEP_LAST:[0,3,1,""]},"dds.DDSLivelinessKind":{AUTOMATIC:[0,3,1,""],MANUAL_BY_PARTICIPANT:[0,3,1,""],MANUAL_BY_TOPIC:[0,3,1,""]},"dds.DDSMaskUtil":{all_samples:[0,3,1,""],new_instance_samples:[0,3,1,""],new_samples:[0,3,1,""],not_alive_instance_samples:[0,3,1,""],read_samples:[0,3,1,""]},"dds.DDSOwnershipKind":{EXCLUSIVE:[0,3,1,""],SHARED:[0,3,1,""]},"dds.DDSPresentationAccessScopeKind":{GROUP:[0,3,1,""],INSTANCE:[0,3,1,""],TOPIC:[0,3,1,""]},"dds.DDSReliabilityKind":{BEST_EFFORT:[0,3,1,""],RELIABLE:[0,3,1,""]},"dds.DDSStateKind":{ALIVE_INSTANCE_STATE:[0,3,1,""],ANY_INSTANCE_STATE:[0,3,1,""],ANY_SAMPLE_STATE:[0,3,1,""],ANY_STATE:[0,3,1,""],ANY_VIEW_STATE:[0,3,1,""],NEW_VIEW_STATE:[0,3,1,""],NOT_ALIVE_DISPOSED_INSTANCE_STATE:[0,3,1,""],NOT_ALIVE_NO_WRITERS_INSTANCE_STATE:[0,3,1,""],NOT_NEW_VIEW_STATE:[0,3,1,""],NOT_READ_SAMPLE_STATE:[0,3,1,""],READ_SAMPLE_STATE:[0,3,1,""]},"dds.DDSStatusKind":{DATA_AVAILABLE:[0,3,1,""],DATA_ON_READERS:[0,3,1,""],INCONSISTENT_TOPIC:[0,3,1,""],LIVELINESS_CHANGED:[0,3,1,""],LIVELINESS_LOST:[0,3,1,""],OFFERED_DEADLINE_MISSED:[0,3,1,""],OFFERED_INCOMPATIBLE_QOS:[0,3,1,""],PUBLICATION_MATCHED:[0,3,1,""],REQUESTED_DEADLINE_MISSED:[0,3,1,""],REQUESTED_INCOMPATIBLE_QOS:[0,3,1,""],SAMPLE_LOST:[0,3,1,""],SAMPLE_REJECTED:[0,3,1,""],SUBSCRIPTION_MATCHED:[0,3,1,""]},"dds.DDSTime":{__init__:[0,2,1,""]},"dds.DataReader":{read:[0,2,1,""],take:[0,2,1,""],wait_for_historical_data:[0,2,1,""]},"dds.DataWriter":{dispose_instance:[0,2,1,""],dispose_instance_ts:[0,2,1,""],write:[0,2,1,""]},"dds.DeadlineQosPolicy":{__init__:[0,2,1,""],deadline:[0,3,1,""]},"dds.DestinationOrderQosPolicy":{__init__:[0,2,1,""]},"dds.DomainParticipant":{create_datareader:[0,2,1,""],create_datawriter:[0,2,1,""],create_publisher:[0,2,1,""],create_subscriber:[0,2,1,""]},"dds.DurabilityQosPolicy":{__init__:[0,2,1,""]},"dds.DurabilityServiceQosPolicy":{__init__:[0,2,1,""],history_depth:[0,3,1,""],history_kind:[0,3,1,""],max_instances:[0,3,1,""],max_samples:[0,3,1,""],max_samples_per_instance:[0,3,1,""],service_cleanup_delay:[0,3,1,""]},"dds.Entity":{get_statuscondition:[0,2,1,""],listener:[0,3,1,""],parent:[0,3,1,""]},"dds.GroupdataQosPolicy":{__init__:[0,2,1,""]},"dds.GuardCondition":{reset:[0,2,1,""],trigger:[0,2,1,""]},"dds.HistoryQosPolicy":{__init__:[0,2,1,""],depth:[0,3,1,""]},"dds.LatencyBudgetQosPolicy":{__init__:[0,2,1,""],duration:[0,3,1,""]},"dds.LifespanQosPolicy":{__init__:[0,2,1,""],lifespan:[0,3,1,""]},"dds.Listener":{__init__:[0,2,1,""],on_data_available:[0,2,1,""],on_data_readers:[0,2,1,""],on_inconsistent_topic:[0,2,1,""],on_liveliness_changed:[0,2,1,""],on_liveliness_lost:[0,2,1,""],on_offered_deadline_missed:[0,2,1,""],on_offered_incompatible_qos:[0,2,1,""],on_publication_matched:[0,2,1,""],on_requested_deadline_missed:[0,2,1,""],on_requested_incompatible_qos:[0,2,1,""],on_sample_lost:[0,2,1,""],on_sample_rejected:[0,2,1,""],on_subscription_matched:[0,2,1,""]},"dds.LivelinessQosPolicy":{__init__:[0,2,1,""],lease_duration:[0,3,1,""]},"dds.OwnershipQosPolicy":{__init__:[0,2,1,""]},"dds.OwnershipStrengthQosPolicy":{__init__:[0,2,1,""],value:[0,3,1,""]},"dds.PartitionQosPolicy":{__init__:[0,2,1,""],ps:[0,3,1,""]},"dds.PresentationQosPolicy":{__init__:[0,2,1,""],coherent_access:[0,3,1,""],ordered_access:[0,3,1,""]},"dds.Publisher":{create_datawriter:[0,2,1,""]},"dds.Qos":{set_policies:[0,2,1,""]},"dds.QosPolicy":{__init__:[0,2,1,""],id:[0,3,1,""],kind:[0,3,1,""]},"dds.QosProfile":{get_participant_qos:[0,2,1,""],get_publisher_qos:[0,2,1,""],get_reader_qos:[0,2,1,""],get_subscriber_qos:[0,2,1,""],get_topic_qos:[0,2,1,""],get_writer_qos:[0,2,1,""]},"dds.ReaderDataLifecycleQosPolicy":{__init__:[0,2,1,""],autopurge_disposed_samples_delay:[0,3,1,""],autopurge_nowriter_samples:[0,3,1,""]},"dds.ReliabilityQosPolicy":{__init__:[0,2,1,""],max_blocking_time:[0,3,1,""]},"dds.ResourceLimitsQosPolicy":{__init__:[0,2,1,""],max_instances:[0,3,1,""],max_samples:[0,3,1,""],max_samples_per_instance:[0,3,1,""]},"dds.SampleInfo":{__init__:[0,2,1,""]},"dds.StatusCondition":{enable_status:[0,2,1,""],entity:[0,3,1,""],get_enabled_status:[0,2,1,""]},"dds.Subscriber":{create_datareader:[0,2,1,""]},"dds.TimeBasedFilterQosPolicy":{__init__:[0,2,1,""],minimum_separation:[0,3,1,""]},"dds.TopicdataQosPolicy":{__init__:[0,2,1,""]},"dds.TransportPriorityQosPolicy":{__init__:[0,2,1,""],value:[0,3,1,""]},"dds.TypeSupport":{__init__:[0,3,1,""],deserialize:[0,2,1,""],handle:[0,3,1,""],serialize:[0,2,1,""],size:[0,3,1,""]},"dds.UserdataQosPolicy":{__init__:[0,2,1,""],value:[0,3,1,""]},"dds.WaitSet":{attach:[0,2,1,""],detach:[0,2,1,""],get_conditions:[0,2,1,""],wait:[0,2,1,""]},"dds.WriterDataLifecycleQosPolicy":{__init__:[0,2,1,""],autodispose_unregistered_instances:[0,3,1,""]},"ddsutil.GeneratedClassInfo":{__init__:[1,2,1,""],get_class:[1,2,1,""],register_topic:[1,2,1,""]},"ddsutil.TopicDataClass":{__init__:[1,2,1,""],get_vars:[1,2,1,""],print_vars:[1,2,1,""]},dds:{Condition:[0,1,1,""],DDSDestinationOrderKind:[0,1,1,""],DDSDurabilityKind:[0,1,1,""],DDSDuration:[0,1,1,""],DDSException:[0,4,1,""],DDSHistoryKind:[0,1,1,""],DDSLivelinessKind:[0,1,1,""],DDSMaskUtil:[0,1,1,""],DDSOwnershipKind:[0,1,1,""],DDSPresentationAccessScopeKind:[0,1,1,""],DDSReliabilityKind:[0,1,1,""],DDSStateKind:[0,1,1,""],DDSStatusKind:[0,1,1,""],DDSTime:[0,1,1,""],DataReader:[0,1,1,""],DataWriter:[0,1,1,""],DeadlineQosPolicy:[0,1,1,""],DestinationOrderQosPolicy:[0,1,1,""],DomainParticipant:[0,1,1,""],DurabilityQosPolicy:[0,1,1,""],DurabilityServiceQosPolicy:[0,1,1,""],Entity:[0,1,1,""],GroupdataQosPolicy:[0,1,1,""],GuardCondition:[0,1,1,""],HistoryQosPolicy:[0,1,1,""],LatencyBudgetQosPolicy:[0,1,1,""],LifespanQosPolicy:[0,1,1,""],Listener:[0,1,1,""],LivelinessQosPolicy:[0,1,1,""],OwnershipQosPolicy:[0,1,1,""],OwnershipStrengthQosPolicy:[0,1,1,""],PartitionQosPolicy:[0,1,1,""],PresentationQosPolicy:[0,1,1,""],Publisher:[0,1,1,""],Qos:[0,1,1,""],QosPolicy:[0,1,1,""],QosProfile:[0,1,1,""],QueryCondition:[0,1,1,""],ReadCondition:[0,1,1,""],ReaderDataLifecycleQosPolicy:[0,1,1,""],ReliabilityQosPolicy:[0,1,1,""],ResourceLimitsQosPolicy:[0,1,1,""],SampleInfo:[0,1,1,""],StatusCondition:[0,1,1,""],Subscriber:[0,1,1,""],TimeBasedFilterQosPolicy:[0,1,1,""],Topic:[0,1,1,""],TopicdataQosPolicy:[0,1,1,""],TransportPriorityQosPolicy:[0,1,1,""],TypeSupport:[0,1,1,""],UserdataQosPolicy:[0,1,1,""],WaitSet:[0,1,1,""],WriterDataLifecycleQosPolicy:[0,1,1,""]},ddsutil:{GeneratedClassInfo:[1,1,1,""],TopicDataClass:[1,1,1,""],get_dds_classes_from_idl:[1,5,1,""]}},objnames:{"0":["py","module","Python module"],"1":["py","class","Python class"],"2":["py","method","Python method"],"3":["py","attribute","Python attribute"],"4":["py","exception","Python exception"],"5":["py","function","Python function"]},objtypes:{"0":"py:module","1":"py:class","2":"py:method","3":"py:attribute","4":"py:exception","5":"py:function"},terms:{"abstract":[0,1],"boolean":0,"class":[0,1],"default":0,"enum":0,"int":0,"long":0,"return":[0,1],"transient":0,"true":0,DDS:[0,1],For:0,QoS:[0,1],Qos:[0,1],The:0,__init__:[0,1],access:0,accur:0,alive_instance_st:0,all:1,all_sampl:0,alloc:0,ani:0,any_instance_st:0,any_sample_st:0,any_st:0,any_view_st:0,api:0,attach:0,attribut:[0,1],autodispose_unregistered_inst:0,automat:0,autopurge_disposed_samples_delai:0,autopurge_nowriter_sampl:0,avail:0,base:[0,1],basic:1,best_effort:0,beta:0,block:0,bool:0,budget:0,by_reception_timestamp:0,by_source_timestamp:0,can:1,coher:0,coherent_access:0,combin:0,commonli:0,cond:0,condit:0,convert:1,creat:[0,1],create_dataread:0,create_datawrit:0,create_publish:0,create_subscrib:0,data:[0,1],data_avail:0,data_cl:1,data_on_read:0,dataread:0,datawrit:0,dcp:0,dds:2,dds_class:1,dds_topic_descriptor:0,ddsdestinationorderkind:0,ddsdurabilitykind:0,ddsdurat:0,ddsexcept:0,ddshistorykind:0,ddslivelinesskind:0,ddsmaskutil:0,ddsownershipkind:0,ddspresentationaccessscopekind:0,ddsreliabilitykind:0,ddsstatekind:0,ddsstatuskind:0,ddstime:0,ddsutil:2,deadlin:0,deadlineqospolici:0,depth:0,descriptor:1,deseri:0,destin:0,destinationorderqospolici:0,detach:0,dictionari:1,dispos:0,dispose_inst:0,dispose_instance_t:0,domain:[0,1],domainparticip:[0,1],durabilityqospolici:0,durabilityserviceqospolici:0,durabl:0,durat:0,dynam:1,empti:0,enable_statu:0,entiti:0,enumer:0,exampl:1,except:0,exclus:0,exipr:0,expir:0,express:0,fals:0,file:[0,1],filter:0,from:[0,1],gen_info:1,gener:[0,1],generatedclassinfo:1,get_class:1,get_condit:0,get_dds_classes_from_idl:1,get_enabled_statu:0,get_participant_qo:0,get_publisher_qo:0,get_reader_qo:0,get_statuscondit:0,get_subscriber_qo:0,get_topic_qo:0,get_var:1,get_writer_qo:0,given:1,group:0,groupdataqospolici:0,guard:0,guardcondit:0,handl:0,help:0,histor:0,histori:0,history_depth:0,history_kind:0,historyqospolici:0,holder:1,identifi:1,idl:1,idl_path:1,implement:0,inconsistent_top:0,infin:0,info:0,inherit:1,initi:0,inner_struct:1,input:1,instanc:0,instanti:0,intern:0,keep_al:0,keep_last:0,kei:0,kind:0,latenc:0,latencybudgetqospolici:0,leas:0,lease_dur:0,lifecycl:0,lifespan:0,lifespanqospolici:0,limit:0,list:0,listen:0,liter:0,liveli:0,liveliness_chang:0,liveliness_lost:0,livelinessqospolici:0,long_1:1,main:1,manual_by_particip:0,manual_by_top:0,mask:0,max:0,max_blocking_tim:0,max_inst:0,max_sampl:0,max_samples_per_inst:0,maximum:0,member:1,member_nam:1,memori:0,method:1,millisecond:0,minimum:0,minimum_separ:0,modul:2,my_struct:1,name:[0,1],nanosec:0,nanosecond:0,need:0,nested_typ:1,new_instance_sampl:0,new_sampl:0,new_view_st:0,none:0,not_alive_disposed_instance_st:0,not_alive_instance_sampl:0,not_alive_no_writers_instance_st:0,not_new_view_st:0,not_read_sample_st:0,number:0,object:[0,1],offered_deadline_miss:0,offered_incompatible_qo:0,on_data_avail:0,on_data_read:0,on_inconsistent_top:0,on_liveliness_chang:0,on_liveliness_lost:0,on_offered_deadline_miss:0,on_offered_incompatible_qo:0,on_publication_match:0,on_requested_deadline_miss:0,on_requested_incompatible_qo:0,on_sample_lost:0,on_sample_reject:0,on_subscription_match:0,onli:0,order:0,ordered_access:0,otherwis:0,ownership:0,ownershipqospolici:0,ownershipstrengthqospolici:0,pair:1,param:0,paramet:[0,1],parent:0,particip:[0,1],partit:0,partitionqospolici:0,path:1,per:0,persist:0,place:1,polici:0,present:0,presentationqospolici:0,print:1,print_var:1,prioriti:0,profil:0,provid:[0,1],publication_match:0,publish:0,purpos:1,python:[0,1],qos:[0,1],qospolici:0,qosprofil:0,queri:0,querycondit:0,read:0,read_sampl:0,read_sample_st:0,readcondit:0,reader:0,readerdatalifecycleqospolici:0,receiv:0,regist:1,register_top:1,reliabilityqospolici:0,reliabl:0,requested_deadline_miss:0,requested_incompatible_qo:0,reset:0,resourc:0,resourcelimitsqospolici:0,sampl:[0,1],sample_lost:0,sample_reject:0,sampleinfo:0,sec:0,second:0,see:0,self:0,separ:0,serial:0,servic:0,service_cleanup_delai:0,set:0,set_polici:0,share:0,should:0,signatur:0,size:0,some:0,sourc:[0,1],specif:0,statu:0,status:0,statuscondit:0,strength:0,strenth:0,string:[0,1],struct:[0,1],subscrib:0,subscription_match:0,support:1,take:0,test:1,thi:[0,1],time:0,timebasedfilterqospolici:0,timeout:0,timestamp:0,topic:[0,1],topic_data_class:1,topicdataclass:1,topicdataqospolici:0,transient_loc:0,transport:0,transportpriorityqospolici:0,trigger:0,tupl:0,type1:1,type:[0,1],type_info:1,type_support_cl:1,type_support_class:1,typenam:0,typesupport:0,unlimit:0,uri:0,use:1,used:0,user:[0,1],userdata:0,userdataqospolici:0,util:[0,1],valu:[0,1],variabl:1,volatil:0,wait:0,wait_for_historical_data:0,waitset:0,were:0,when:0,write:0,writer:0,writerdatalifecycleqospolici:0,xml:0},titles:["dds module","ddsutil module","code"],titleterms:{code:2,dds:0,ddsutil:1,modul:[0,1]}}) \ No newline at end of file diff --git a/src/api/dcps/python/docs/rst/conf.py b/src/api/dcps/python/docs/rst/conf.py new file mode 100644 index 000000000..f985ab312 --- /dev/null +++ b/src/api/dcps/python/docs/rst/conf.py @@ -0,0 +1,179 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# +# Python DCPS API documentation build configuration file, created by +# sphinx-quickstart on Thu Sep 7 13:29:15 2017. +# +# This file is execfile()d with the current directory set to its +# containing dir. +# +# Note that not all possible configuration values are present in this +# autogenerated file. +# +# All configuration values have a default; values that are commented out +# serve to show the default. + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +# +import os +import sys +sys.path.insert(0, os.path.abspath('/home/prismtech/git/ospli/src/api/dcps/python/code')) + + +# -- General configuration ------------------------------------------------ + +# If your documentation needs a minimal Sphinx version, state it here. +# +# needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = ['sphinx.ext.autodoc'] +autodoc_member_order = 'bysource' +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The suffix(es) of source filenames. +# You can specify multiple suffix as a list of string: +# +# source_suffix = ['.rst', '.md'] +source_suffix = '.rst' + +# The master toctree document. +master_doc = 'index' + +# General information about the project. +project = 'Python DCPS API' +copyright = '2017, ADLINK Technology Limited' +author = 'ADLINK' + + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# +# The short X.Y version. +version = '6.8.3' +# The full version, including alpha/beta/rc tags. +release = '6.8.3' + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +# +# This is also used if you do content translation via gettext catalogs. +# Usually you set "language" from the command line for these cases. +language = None + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This patterns also effect to html_static_path and html_extra_path +exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + +# If true, `todo` and `todoList` produce output, else they produce nothing. +todo_include_todos = False + + +# -- Options for HTML output ---------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +html_theme = 'alabaster' + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +# +# html_theme_options = {} + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] + +# Custom sidebar templates, must be a dictionary that maps document names +# to template names. +# +# This is required for the alabaster theme +# refs: http://alabaster.readthedocs.io/en/latest/installation.html#sidebars +html_sidebars = { + '**': [ + 'about.html', + 'navigation.html', + 'relations.html', # needs 'show_related': True theme option to display + 'searchbox.html', + 'donate.html', + ] +} + + +# -- Options for HTMLHelp output ------------------------------------------ + +# Output file base name for HTML help builder. +htmlhelp_basename = 'PythonDCPSAPIdoc' + + +# -- Options for LaTeX output --------------------------------------------- + +latex_elements = { + # The paper size ('letterpaper' or 'a4paper'). + # + # 'papersize': 'letterpaper', + + # The font size ('10pt', '11pt' or '12pt'). + # + # 'pointsize': '10pt', + + # Additional stuff for the LaTeX preamble. + # + # 'preamble': '', + + # Latex figure (float) alignment + # + # 'figure_align': 'htbp', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, +# author, documentclass [howto, manual, or own class]). +latex_documents = [ + (master_doc, 'PythonDCPSAPI.tex', 'Python DCPS API Documentation', + 'ADLINK', 'manual'), +] + + +# -- Options for manual page output --------------------------------------- + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + (master_doc, 'pythondcpsapi', 'Python DCPS API Documentation', + [author], 1) +] + + +# -- Options for Texinfo output ------------------------------------------- + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + (master_doc, 'PythonDCPSAPI', 'Python DCPS API Documentation', + author, 'PythonDCPSAPI', 'One line description of project.', + 'Miscellaneous'), +] + + +def skip(app, what, name, obj, skip, options): + if name == "__init__": + return False + return skip + +def setup(app): + app.connect("autodoc-skip-member", skip) diff --git a/src/api/dcps/python/docs/rst/dds.rst b/src/api/dcps/python/docs/rst/dds.rst new file mode 100644 index 000000000..b68547bbf --- /dev/null +++ b/src/api/dcps/python/docs/rst/dds.rst @@ -0,0 +1,7 @@ +dds module +========== + +.. automodule:: dds + :members: + :undoc-members: + :show-inheritance: diff --git a/src/api/dcps/python/docs/rst/ddsutil.rst b/src/api/dcps/python/docs/rst/ddsutil.rst new file mode 100644 index 000000000..7fc8f13bd --- /dev/null +++ b/src/api/dcps/python/docs/rst/ddsutil.rst @@ -0,0 +1,8 @@ +ddsutil module +============== + +.. automodule:: ddsutil + :members: + :undoc-members: + :show-inheritance: + :member-order: bysource diff --git a/src/api/dcps/python/docs/rst/index.rst b/src/api/dcps/python/docs/rst/index.rst new file mode 100644 index 000000000..b1921c6e5 --- /dev/null +++ b/src/api/dcps/python/docs/rst/index.rst @@ -0,0 +1,8 @@ +code +==== + +.. toctree:: + :maxdepth: 2 + + dds + ddsutil diff --git a/src/api/dcps/python/examples/DDS_DefaultQoS_All.xml b/src/api/dcps/python/examples/DDS_DefaultQoS_All.xml new file mode 100644 index 000000000..6745b326e --- /dev/null +++ b/src/api/dcps/python/examples/DDS_DefaultQoS_All.xml @@ -0,0 +1,243 @@ + + + + + + VOLATILE_DURABILITY_QOS + + + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + + 0 + 0 + + + + AUTOMATIC_LIVELINESS_QOS + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + BEST_EFFORT_RELIABILITY_QOS + + 0 + 100000000 + + + + BY_RECEPTION_TIMESTAMP_DESTINATIONORDER_QOS + + + KEEP_LAST_HISTORY_QOS + 1 + + + LENGTH_UNLIMITED + LENGTH_UNLIMITED + LENGTH_UNLIMITED + + + + + + SHARED_OWNERSHIP_QOS + + + + 0 + 0 + + + + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + + + VOLATILE_DURABILITY_QOS + + + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + + 0 + 0 + + + + AUTOMATIC_LIVELINESS_QOS + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + RELIABLE_RELIABILITY_QOS + + 0 + 100000000 + + + + BY_RECEPTION_TIMESTAMP_DESTINATIONORDER_QOS + + + KEEP_LAST_HISTORY_QOS + 1 + + + LENGTH_UNLIMITED + LENGTH_UNLIMITED + LENGTH_UNLIMITED + + + 0 + + + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + + + + SHARED_OWNERSHIP_QOS + + + 0 + + + true + + + + + + + + true + + + + + INSTANCE_PRESENTATION_QOS + false + false + + + + + + + + + true + + + + + INSTANCE_PRESENTATION_QOS + false + false + + + + + + + + + true + + + + + + + + VOLATILE_DURABILITY_QOS + + + + 0 + 0 + + KEEP_LAST_HISTORY_QOS + 1 + LENGTH_UNLIMITED + LENGTH_UNLIMITED + LENGTH_UNLIMITED + + + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + + 0 + 0 + + + + AUTOMATIC_LIVELINESS_QOS + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + BEST_EFFORT_RELIABILITY_QOS + + 0 + 100000000 + + + + BY_RECEPTION_TIMESTAMP_DESTINATIONORDER_QOS + + + KEEP_LAST_HISTORY_QOS + 1 + + + LENGTH_UNLIMITED + LENGTH_UNLIMITED + LENGTH_UNLIMITED + + + 0 + + + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + SHARED_OWNERSHIP_QOS + + + + diff --git a/src/api/dcps/python/examples/DDS_VolatileQoS_All.xml b/src/api/dcps/python/examples/DDS_VolatileQoS_All.xml new file mode 100644 index 000000000..040b2949b --- /dev/null +++ b/src/api/dcps/python/examples/DDS_VolatileQoS_All.xml @@ -0,0 +1,243 @@ + + + + + + VOLATILE_DURABILITY_QOS + + + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + + 0 + 0 + + + + AUTOMATIC_LIVELINESS_QOS + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + BEST_EFFORT_RELIABILITY_QOS + + 0 + 100000000 + + + + BY_RECEPTION_TIMESTAMP_DESTINATIONORDER_QOS + + + KEEP_LAST_HISTORY_QOS + 100 + + + LENGTH_UNLIMITED + LENGTH_UNLIMITED + LENGTH_UNLIMITED + + + + + + SHARED_OWNERSHIP_QOS + + + + 0 + 0 + + + + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + + + VOLATILE_DURABILITY_QOS + + + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + + 0 + 0 + + + + AUTOMATIC_LIVELINESS_QOS + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + RELIABLE_RELIABILITY_QOS + + 0 + 100000000 + + + + BY_RECEPTION_TIMESTAMP_DESTINATIONORDER_QOS + + + KEEP_LAST_HISTORY_QOS + 100 + + + LENGTH_UNLIMITED + LENGTH_UNLIMITED + LENGTH_UNLIMITED + + + 0 + + + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + + + + SHARED_OWNERSHIP_QOS + + + 0 + + + true + + + + + + + + true + + + + + INSTANCE_PRESENTATION_QOS + false + false + + + + + + + + + true + + + + + INSTANCE_PRESENTATION_QOS + false + false + + + + + + + + + true + + + + + + + + VOLATILE_DURABILITY_QOS + + + + 3600 + 0 + + KEEP_LAST_HISTORY_QOS + 100 + 8192 + 4196 + 8192 + + + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + + 0 + 0 + + + + AUTOMATIC_LIVELINESS_QOS + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + BEST_EFFORT_RELIABILITY_QOS + + 0 + 100000000 + + + + BY_RECEPTION_TIMESTAMP_DESTINATIONORDER_QOS + + + KEEP_LAST_HISTORY_QOS + 100 + + + LENGTH_UNLIMITED + LENGTH_UNLIMITED + LENGTH_UNLIMITED + + + 0 + + + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + SHARED_OWNERSHIP_QOS + + + + diff --git a/src/api/dcps/python/examples/PythonExample4.sd b/src/api/dcps/python/examples/PythonExample4.sd new file mode 100644 index 000000000..3cffe7387 --- /dev/null +++ b/src/api/dcps/python/examples/PythonExample4.sd @@ -0,0 +1,11 @@ +scenario PythonExample4 + +log("Starting Tester Script..."); + +repeat OsplTestTopic 1.0 0 (id => 21, index => 221, x => 3.4, y => 4.5, z => 5.6, t => 6.7, state => boost, description => "Hello from Tester!"); + +wait (15); + +log("Finished Tester Scripted."); + +end scenario \ No newline at end of file diff --git a/src/api/dcps/python/examples/README.txt b/src/api/dcps/python/examples/README.txt new file mode 100644 index 000000000..dfca66061 --- /dev/null +++ b/src/api/dcps/python/examples/README.txt @@ -0,0 +1,7 @@ +Python API examples +=================== + +To run example script: + + 1. Source OSPL environment variables. (e.g., source release.com) + 2. run "python3 example1.py" diff --git a/src/api/dcps/python/examples/example1.idl b/src/api/dcps/python/examples/example1.idl new file mode 100644 index 000000000..397ab59ee --- /dev/null +++ b/src/api/dcps/python/examples/example1.idl @@ -0,0 +1,20 @@ +module basic{ + + module module_SequenceOfStruct{ + + struct Inner{ + short short1; + double double1; + }; + + typedef Inner inner_struct; + + struct SequenceOfStruct_struct{ + long long1; + Sequence seq1; + }; + + #pragma keylist SequenceOfStruct_struct long1 + }; +}; + diff --git a/src/api/dcps/python/examples/example1.py b/src/api/dcps/python/examples/example1.py new file mode 100644 index 000000000..63e74650d --- /dev/null +++ b/src/api/dcps/python/examples/example1.py @@ -0,0 +1,97 @@ +# +# Vortex OpenSplice +# +# This software and documentation are Copyright 2006 to TO_YEAR ADLINK +# Technology Limited, its affiliated companies and licensors. All rights +# reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from dds import * +import time +import ddsutil + +# Data available listener +class DataAvailableListener(Listener): + def __init__(self): + Listener.__init__(self) + + def on_data_available(self, entity): + print('on_data_available called') + l = entity.read(10) + for (sd, si) in l: + sd.print_vars() + +if __name__ == "__main__": + + + qp = QosProfile('file://DDS_DefaultQoS_All.xml', 'DDS DefaultQosProfile') + + # Create participant + dp = DomainParticipant(qos = qp.get_participant_qos()) + + # Create publisher + pub = dp.create_publisher(qos = qp.get_publisher_qos()) + + # Create Subscriber + sub = dp.create_subscriber(qos = qp.get_subscriber_qos()) + + + # Generate python classes from IDL file + gen_info = ddsutil.get_dds_classes_from_idl('example1.idl', + 'basic::module_SequenceOfStruct::SequenceOfStruct_struct') + + # Type support class + topic = gen_info.register_topic(dp, "Example1", qp.get_topic_qos()) + + # Create a writer + writer = pub.create_datawriter(topic, qp.get_writer_qos()) + readerQos = qp.get_reader_qos() + reader = sub.create_datareader(topic, readerQos) + + Inner = gen_info.get_class("basic::module_SequenceOfStruct::Inner") + inner1 = Inner(short1 = 999, double1=222) + inner2 = Inner(short1 = 777, double1=333) + + # Topic data class + s = gen_info.topic_data_class(long1=2, seq1 = [inner1, inner2]) + + # Write data + writer.write(s) + + + time.sleep(1) + + # Create waitset + waitset = WaitSet() + qc = QueryCondition(reader, DDSMaskUtil.all_samples(), 'long1 > 1') + + waitset.attach(qc) + + # Wait for data + conditions = waitset.wait() + + + # Print data + l = reader.take(10) + for sd, si in l: + sd.print_vars() + + # dispose instance + writer.dispose_instance(s) + + + + + + diff --git a/src/api/dcps/python/examples/example2.idl b/src/api/dcps/python/examples/example2.idl new file mode 100644 index 000000000..ec8630a49 --- /dev/null +++ b/src/api/dcps/python/examples/example2.idl @@ -0,0 +1,27 @@ +module basic{ + + module enumZ { + + enum Color { Red, Green, Blue }; + + }; + + module module_Enum2{ + + enum Color { Red, Green, Blue }; + typedef Color AColor; + typedef enumZ::Color ZColor; + + struct Enum2_struct{ + long long1; + AColor color1; + ZColor color2; + ZColor array[2]; + }; + + #pragma keylist Enum2_struct long1 + }; + + +}; + diff --git a/src/api/dcps/python/examples/example2.py b/src/api/dcps/python/examples/example2.py new file mode 100644 index 000000000..b6c6eb79f --- /dev/null +++ b/src/api/dcps/python/examples/example2.py @@ -0,0 +1,89 @@ +# +# Vortex OpenSplice +# +# This software and documentation are Copyright 2006 to TO_YEAR ADLINK +# Technology Limited, its affiliated companies and licensors. All rights +# reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from dds import * +import time +import ddsutil + + +# Data available listener +class DataAvailableListener(Listener): + def __init__(self): + Listener.__init__(self) + + def on_data_available(self, entity): + print('on_data_available called') + l = entity.read(10) + for (sd, si) in l: + print(si.source_timestamp, end=", ") + sd.print_vars() + + +if __name__ == "__main__": + + qp = QosProfile('file://DDS_VolatileQoS_All.xml', 'DDS VolatileQosProfile') + + # Create participant + dp = DomainParticipant(qos=qp.get_participant_qos()) + + # Create publisher + pub = dp.create_publisher(qos=qp.get_publisher_qos()) + + # Create Subscriber + sub = dp.create_subscriber(qos=qp.get_subscriber_qos()) + + + # Generate python classes from IDL file + gen_info = ddsutil.get_dds_classes_from_idl('example2.idl', 'basic::module_Enum2::Enum2_struct') + + # Register topic + topic = gen_info.register_topic(dp, "Example2", qp.get_topic_qos()) + + # Create a writer + writer = pub.create_datawriter(topic, qp.get_writer_qos()) + readerQos = qp.get_reader_qos() + reader = sub.create_datareader(topic, readerQos, DataAvailableListener()) + reader2 = sub.create_datareader(topic, readerQos) + + # Topic data class + ColorA = gen_info.get_class("basic::module_Enum2::Color") + ColorZ = gen_info.get_class("basic::enumZ::Color") + + s = gen_info.topic_data_class(long1 = 4, color1 = ColorA.Green, color2=ColorZ.Blue, array=[ColorZ.Red, ColorZ.Blue]) + + + # Write data + writer.write(s) + + time.sleep(1) + + # Create waitset + waitset = WaitSet() + condition = ReadCondition(reader2, DDSMaskUtil.all_samples()) + + waitset.attach(condition) + + # Wait for data + conditions = waitset.wait() + + # Print data + l = reader2.take(10) + for sd, si in l: + sd.print_vars() + diff --git a/src/api/dcps/python/examples/example3.idl b/src/api/dcps/python/examples/example3.idl new file mode 100644 index 000000000..97d5fbc95 --- /dev/null +++ b/src/api/dcps/python/examples/example3.idl @@ -0,0 +1,28 @@ +const long length = 3; + +module test{ + typedef long my_long; +}; + +module basic{ + + typedef long basic_long; + + module module_NestedStruct{ + + struct Inner{ + basic::basic_long long1; + double double1; + }; + + typedef Inner inner_struct; + + struct NestedStruct_struct{ + test::my_long long1; + inner_struct inner1; + }; + + #pragma keylist NestedStruct_struct long1 + }; +}; + diff --git a/src/api/dcps/python/examples/example4.py b/src/api/dcps/python/examples/example4.py new file mode 100644 index 000000000..7897f4d20 --- /dev/null +++ b/src/api/dcps/python/examples/example4.py @@ -0,0 +1,81 @@ +# +# Vortex OpenSplice +# +# This software and documentation are Copyright 2006 to TO_YEAR ADLINK +# Technology Limited, its affiliated companies and licensors. All rights +# reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +''' +Demonstrate finding DDS topics 'over-the-wire'. That is, find topics registered +in other processes, and read and write samples to those topics + +@author: ADLINK +''' + +import subprocess +import time +import ddsutil +import dds + +def demo_over_the_wire_topics(): + print('Starting OpenSplice Tester, which registers a topic we don''t have locally...') + # This runs OpenSplice Tester headlessly, and runs a Tester 'scenario' to periodically + # write data to the OsplTestTopic topic. + subprocess.call(['ospltest', '-headless', '-e', '-s', 'PythonExample4.sd']) + print(' Waiting 15s for it to start...') + time.sleep(15) + print(' Finished waiting, continuing...') + + print('Connecting to DDS domain...') + dp = dds.DomainParticipant() + + print('Finding OsplTestTopic...') + found_topic = dp.find_topic('OsplTestTopic') + + print('Registering OsplTestTopic locally') + local_topic = ddsutil.register_found_topic_as_local(found_topic) + + print('Getting Python classes for the found topic...') + gen_info = ddsutil.get_dds_classes_for_found_topic(found_topic) + OsplTestTopic = gen_info.get_class(found_topic.type_name) + Tstate = gen_info.get_class('ospllog::Tstate') + + print('Creating sample data to write...') + data = OsplTestTopic(id=11,index=22, x=1.2, y=2.3, z= 3.4, t=9.8, state=Tstate.init, description='Hello from Python') + + print('Creating readers and writers...') + pub = dp.create_publisher() + wr = pub.create_datawriter(local_topic, found_topic.qos) + sub = dp.create_subscriber() + rd = sub.create_datareader(local_topic, found_topic.qos) + + print('Writing sample data...') + wr.write(data) + print('Wrote: %s' % (str(data))) + + print('Waiting a bit so Tester has time to see our data...') + time.sleep(3) + + + print('Reading data...') + l = rd.take(10) + for (sd, si) in l: + if si.valid_data: + print('Read: %s' % (str(sd))) + + print('All Done!!!') + +if __name__ == '__main__': + demo_over_the_wire_topics() \ No newline at end of file diff --git a/src/api/dcps/python/examples/qos_example.py b/src/api/dcps/python/examples/qos_example.py new file mode 100644 index 000000000..daf7ee990 --- /dev/null +++ b/src/api/dcps/python/examples/qos_example.py @@ -0,0 +1,113 @@ +# +# Vortex OpenSplice +# +# This software and documentation are Copyright 2006 to TO_YEAR ADLINK +# Technology Limited, its affiliated companies and licensors. All rights +# reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from dds import * +from ddsutil import * +import time + + +if __name__ == "__main__": + + + publisher_qos = Qos([PresentationQosPolicy(DDSPresentationAccessScopeKind.TOPIC, True, True), + PartitionQosPolicy(['A', 'B'])]) + subscriber_qos = Qos([PresentationQosPolicy(DDSPresentationAccessScopeKind.TOPIC, True, True), + PartitionQosPolicy(['A', 'B'])]) + # Create participant + dp = DomainParticipant() + + # Create publisher + pub = dp.create_publisher(publisher_qos) + + # Create Subscriber + sub = dp.create_subscriber(subscriber_qos) + + # Generate python classes from IDL file + gen_info = get_dds_classes_from_idl('example3.idl', 'basic::module_NestedStruct::NestedStruct_struct') + + topic_qos = Qos([DurabilityQosPolicy(DDSDurabilityKind.TRANSIENT), + DurabilityServiceQosPolicy(DDSDuration(2, 500), DDSHistoryKind.KEEP_ALL, 2, 100, 100, 100), + DeadlineQosPolicy(DDSDuration(500)), + LatencyBudgetQosPolicy(DDSDuration(3000)), + LivelinessQosPolicy(DDSLivelinessKind.MANUAL_BY_PARTICIPANT), + ReliabilityQosPolicy(DDSReliabilityKind.RELIABLE, DDSDuration.infinity()), + DestinationOrderQosPolicy(DDSDestinationOrderKind.BY_SOURCE_TIMESTAMP), + HistoryQosPolicy(DDSHistoryKind.KEEP_ALL), + ResourceLimitsQosPolicy(10,10,10), + TransportPriorityQosPolicy(700), + LifespanQosPolicy(DDSDuration(10, 500)), + OwnershipQosPolicy(DDSOwnershipKind.EXCLUSIVE) + ]) + + topic = gen_info.register_topic(dp, "NestedStruct3", topic_qos) + + writer_qos = Qos([DurabilityQosPolicy(DDSDurabilityKind.TRANSIENT), + DeadlineQosPolicy(DDSDuration(500)), + LatencyBudgetQosPolicy(DDSDuration(3000)), + LivelinessQosPolicy(DDSLivelinessKind.MANUAL_BY_PARTICIPANT), + ReliabilityQosPolicy(DDSReliabilityKind.RELIABLE, DDSDuration.infinity()), + DestinationOrderQosPolicy(DDSDestinationOrderKind.BY_SOURCE_TIMESTAMP), + HistoryQosPolicy(DDSHistoryKind.KEEP_ALL), + ResourceLimitsQosPolicy(10,10,10), + TransportPriorityQosPolicy(700), + LifespanQosPolicy(DDSDuration(10, 500)), + OwnershipQosPolicy(DDSOwnershipKind.EXCLUSIVE), + OwnershipStrengthQosPolicy(100), + WriterDataLifecycleQosPolicy(False) + ]) + + reader_qos = Qos([DurabilityQosPolicy(DDSDurabilityKind.TRANSIENT), + DeadlineQosPolicy(DDSDuration(500)), + LatencyBudgetQosPolicy(DDSDuration(3000)), + LivelinessQosPolicy(DDSLivelinessKind.MANUAL_BY_PARTICIPANT), + ReliabilityQosPolicy(DDSReliabilityKind.RELIABLE, DDSDuration.infinity()), + DestinationOrderQosPolicy(DDSDestinationOrderKind.BY_SOURCE_TIMESTAMP), + HistoryQosPolicy(DDSHistoryKind.KEEP_ALL), + ResourceLimitsQosPolicy(10,10,10), + OwnershipQosPolicy(DDSOwnershipKind.EXCLUSIVE), + TimeBasedFilterQosPolicy(DDSDuration(2, 500)), + ReaderDataLifecycleQosPolicy(DDSDuration(3), DDSDuration(5)) + ]) + + writer = pub.create_datawriter(topic, writer_qos) + reader = sub.create_datareader(topic, reader_qos) + + Inner = gen_info.get_class("basic::module_NestedStruct::Inner") + inner = Inner(long1 = 1, double1 = 1.0) + s = gen_info.topic_data_class(long1 = 1, inner1 = inner) + + # Write data + writer.write(s) + + time.sleep(2) + + # Create waitset + waitset = WaitSet() + condition = StatusCondition(reader) + + waitset.attach(condition) + + # Wait for data + conditions = waitset.wait() + + # Print data + l = reader.take(10) + for sd, si in l: + sd.print_vars() + diff --git a/src/api/dcps/python/makefile b/src/api/dcps/python/makefile new file mode 100644 index 000000000..7b3fcdfda --- /dev/null +++ b/src/api/dcps/python/makefile @@ -0,0 +1,9 @@ +include $(OSPL_HOME)/setup/makefiles/makefile.mak + +all link: bld/$(SPLICE_TARGET)/makefile + @$(MAKE) -C bld/$(SPLICE_TARGET) $@ + + +clean: + @rm -rf bld/$(SPLICE_TARGET) + diff --git a/src/api/dcps/python/makefile.mak b/src/api/dcps/python/makefile.mak new file mode 100644 index 000000000..97ce3a296 --- /dev/null +++ b/src/api/dcps/python/makefile.mak @@ -0,0 +1,37 @@ +# +# included by bld/$(SPLICE_TARGET)/makefile + +# Don't use inherited C compile rules from target.mak +C_FILES= + +include $(OSPL_HOME)/setup/makefiles/target.mak + +# This list of files is what will be included in the source assembly, as well as +# what is needed for the wheel packaging. +SOURCE_FILES = dds.pxd dds.pyx ddsutil.py setup.py README.txt + +# The source assembly is unconditionally picked up by the HDE install for all platforms +SOURCE_ASSEMBLY_DIR = src +SOURCE_ASSEMBLY = $(addprefix $(SOURCE_ASSEMBLY_DIR)/, $(SOURCE_FILES)) + +# Only invoke python3 binary wheel packaging if prerequisites are met from configure +# This is picked up by HDE and RTS installs for select platforms +BINARY_PACKAGE = dist/*.whl +ifeq "$(INCLUDE_API_DCPS_PYTHON)" "yes" + TARGET = $(BINARY_PACKAGE) +else + TARGET = $(SOURCE_ASSEMBLY) +endif + +all link: $(TARGET) + +$(SOURCE_ASSEMBLY): $(addprefix $(CODE_DIR)/, $(SOURCE_FILES)) + @mkdir -p $(SOURCE_ASSEMBLY_DIR) + cp $^ $(SOURCE_ASSEMBLY_DIR) + +# For every python install defined in PYTHON3_EXECS, create a wheel for each +$(BINARY_PACKAGE): $(SOURCE_ASSEMBLY) + @cp -r $(SOURCE_ASSEMBLY_DIR)/* . + @for pyexec in $$(echo "$$PYTHON3_EXECS" | tr ":" "\n"); do \ + $$pyexec setup.py build_ext --inplace bdist_wheel; \ + done diff --git a/src/api/dcps/python/test/.gitignore b/src/api/dcps/python/test/.gitignore new file mode 100644 index 000000000..bee8a64b7 --- /dev/null +++ b/src/api/dcps/python/test/.gitignore @@ -0,0 +1 @@ +__pycache__ diff --git a/src/api/dcps/python/test/TestArrayOfSimpleSequence.py b/src/api/dcps/python/test/TestArrayOfSimpleSequence.py new file mode 100644 index 000000000..ffedcda8d --- /dev/null +++ b/src/api/dcps/python/test/TestArrayOfSimpleSequence.py @@ -0,0 +1,61 @@ +# +# Vortex OpenSplice +# +# This software and documentation are Copyright 2006 to TO_YEAR ADLINK +# Technology Limited, its affiliated companies and licensors. All rights +# reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +''' +Created on Dec 8, 2017 + +@author: prismtech +''' +import unittest +import struct +import countTest + +if countTest.count_test == False: + import ArrayOfSimpleSequence.basic.module_ArrayOfSimpleSequence + +class TestArrayOfSimpleSequence(unittest.TestCase): + + + def testCopyInCopyOut(self): + data = ArrayOfSimpleSequence.basic.module_ArrayOfSimpleSequence.ArrayOfSimpleSequence_struct( + long1 = 12, + array1 = [[101, 102], [201, 202, 203]] + ) + print('data: ' + str(data)) + + print('data._get_packing_fmt(): ', data._get_packing_fmt()) + print('data._get_packing_args(): ', data._get_packing_args()) + buffer = data._serialize() + print('buffer: ', buffer) + + values = struct.unpack(data._get_packing_fmt(), buffer) + data1 = ArrayOfSimpleSequence.basic.module_ArrayOfSimpleSequence.ArrayOfSimpleSequence_struct() + data1._deserialize(list(values)) + + self.assertEqual(data.long1, data1.long1) + self.assertEqual(len(data.array1), len(data1.array1)) + for i in range(len(data.array1)): + self.assertEqual(len(data.array1[i]), len(data1.array1[i])) + for j in range(len(data.array1[i])): + self.assertEqual(data.array1[i][j], data1.array1[i][j], 'array1[%d][%d]'%(i,j)) + + +if __name__ == "__main__": + #import sys;sys.argv = ['', 'TestArrayOfSimpleSequence.testCopyInCopyOut'] + unittest.main() \ No newline at end of file diff --git a/src/api/dcps/python/test/TestArrayOfStructSequence.py b/src/api/dcps/python/test/TestArrayOfStructSequence.py new file mode 100644 index 000000000..68c7e9ea4 --- /dev/null +++ b/src/api/dcps/python/test/TestArrayOfStructSequence.py @@ -0,0 +1,66 @@ +# +# Vortex OpenSplice +# +# This software and documentation are Copyright 2006 to TO_YEAR ADLINK +# Technology Limited, its affiliated companies and licensors. All rights +# reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +''' +Created on Dec 8, 2017 + +@author: prismtech +''' +import unittest +import struct +import countTest + +if countTest.count_test == False: + import ArrayOfStructSequence.basic.module_ArrayOfStructSequence + from ArrayOfStructSequence.basic.module_ArrayOfStructSequence import Inner + +class TestArrayOfStructSequence(unittest.TestCase): + + + def testCopyInCopyOut(self): + data = ArrayOfStructSequence.basic.module_ArrayOfStructSequence.ArrayOfStructSequence_struct( + long1 = 13, + array1 = [ + [Inner(short1=11, double1=1.1), Inner(short1=12,double1=1.2)], + [Inner(short1=21, double1=2.1), Inner(short1=22, double1=2.2), Inner(short1=23, double1=2.3)] + ] + ) + print('data: ' + str(data)) + + print('data._get_packing_fmt(): ', data._get_packing_fmt()) + print('data._get_packing_args(): ', data._get_packing_args()) + buffer = data._serialize() + print('buffer: ', buffer) + + values = struct.unpack(data._get_packing_fmt(), buffer) + data1 = ArrayOfStructSequence.basic.module_ArrayOfStructSequence.ArrayOfStructSequence_struct() + data1._deserialize(list(values)) + + self.assertEqual(data.long1, data1.long1) + self.assertEqual(len(data.array1), len(data1.array1)) + for i in range(len(data.array1)): + self.assertEqual(len(data.array1[i]), len(data1.array1[i])) + for j in range(len(data.array1[i])): + self.assertEqual(data.array1[i][j].short1, data1.array1[i][j].short1, 'array1[%d][%d].short1'%(i,j)) + self.assertEqual(data.array1[i][j].double1, data1.array1[i][j].double1, 'array1[%d][%d].double1'%(i,j)) + + +if __name__ == "__main__": + #import sys;sys.argv = ['', 'TestArrayOfStructSequence.testCopyInCopyOut'] + unittest.main() \ No newline at end of file diff --git a/src/api/dcps/python/test/TestBasicStruct.py b/src/api/dcps/python/test/TestBasicStruct.py new file mode 100644 index 000000000..69e262e88 --- /dev/null +++ b/src/api/dcps/python/test/TestBasicStruct.py @@ -0,0 +1,55 @@ +# +# Vortex OpenSplice +# +# This software and documentation are Copyright 2006 to TO_YEAR ADLINK +# Technology Limited, its affiliated companies and licensors. All rights +# reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +''' +Created on Dec 8, 2017 + +@author: prismtech +''' +import unittest +import struct +import countTest + +if countTest.count_test == False: + from BasicStruct.declaration_order import S11 + +class TestBasicStruct(unittest.TestCase): + + + def testCopyInCopyOut(self): + data = S11(a=11,b=12,xa=21,xb=22,ya=31,yb=32,za=41,zb=42) + print('data: ' + str(data)) + + print('data._get_packing_fmt(): ', data._get_packing_fmt()) + print('data._get_packing_args(): ', data._get_packing_args()) + buffer = data._serialize() + print('buffer: ', buffer) + + values = struct.unpack(data._get_packing_fmt(), buffer) + data1 = S11() + data1._deserialize(list(values)) + + for a in data._member_attributes: + self.assertEqual(getattr(data,a),getattr(data1,a),a) + + + +if __name__ == "__main__": + #import sys;sys.argv = ['', 'TestBasicStruct.testCopyInCopyOut'] + unittest.main() \ No newline at end of file diff --git a/src/api/dcps/python/test/TestCharTypes.py b/src/api/dcps/python/test/TestCharTypes.py new file mode 100644 index 000000000..d9828d404 --- /dev/null +++ b/src/api/dcps/python/test/TestCharTypes.py @@ -0,0 +1,64 @@ +# +# Vortex OpenSplice +# +# This software and documentation are Copyright 2006 to TO_YEAR ADLINK +# Technology Limited, its affiliated companies and licensors. All rights +# reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +''' +Created on Dec 17, 2017 + +@author: prismtech +''' +import unittest +import struct +import countTest + +if countTest.count_test == False: + from CharTypes.basic.module_CharTypes import CharTypes_struct + +class TestCharTypes(unittest.TestCase): + + + def testCopyInCopyOut(self): + data = CharTypes_struct( + long1 = 32, + char1='A', + char_array=list('aBcDeFgHiJ'), + char_seq1=list('ABCDEFGHIJKLMNOPQRSTUVWXYZ'), + char_seq2=list('qrstuvwxyz'), + octet1=0x01, + octet_array=[0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x10], + octet_seq1=[0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x20], + octet_seq2=[0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x30], + ) + + print('data: ' + str(data)) + + print('data._get_packing_fmt(): ', data._get_packing_fmt()) + buffer = data._serialize() + print('buffer: ', buffer) + + values = struct.unpack(data._get_packing_fmt(), buffer) + data1 = CharTypes_struct() + data1._deserialize(list(values)) + + for attr in CharTypes_struct._member_attributes: + self.assertEqual(getattr(data,attr),getattr(data1,attr),attr) + + +if __name__ == "__main__": + #import sys;sys.argv = ['', 'TestCharTypes.testCopyInCopyOut'] + unittest.main() \ No newline at end of file diff --git a/src/api/dcps/python/test/TestIoTBuiltIn.py b/src/api/dcps/python/test/TestIoTBuiltIn.py new file mode 100644 index 000000000..81765e1cb --- /dev/null +++ b/src/api/dcps/python/test/TestIoTBuiltIn.py @@ -0,0 +1,109 @@ +# +# Vortex OpenSplice +# +# This software and documentation are Copyright 2006 to TO_YEAR ADLINK +# Technology Limited, its affiliated companies and licensors. All rights +# reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +''' +Created on Dec 18, 2017 + +@author: prismtech +''' +import unittest +import struct +import countTest + +if countTest.count_test == False: + from dds_IoTData.DDS.IoT import IoTData, IoTNVP, IoTType, IoTValue + +class TestIoTBuiltIn(unittest.TestCase): + + + def testCopyInCopyOut(self): + data = IoTData( + typeName = 'Foo', + instanceId = 'Bar', + values=[ + IoTNVP(name='Tui8', value=IoTValue(ui8=127)), + IoTNVP(name='Tui16', value=IoTValue(ui16=0x0102)), + IoTNVP(name='Tui32', value=IoTValue(ui32=0x01020304)), + IoTNVP(name='Tui64', value=IoTValue(ui64=0x0102030405060708)), + IoTNVP(name='Ti8', value=IoTValue(i8='F')), + IoTNVP(name='Ti16', value=IoTValue(i16=0x1102)), + IoTNVP(name='Ti32', value=IoTValue(i32=0x11020304)), + IoTNVP(name='Ti64', value=IoTValue(i64=0x1102030405060708)), + IoTNVP(name='Tf32', value=IoTValue(f32=16.0)), + IoTNVP(name='Tf64', value=IoTValue(f64=1024.0)), + IoTNVP(name='Tb', value=IoTValue(b=True)), + IoTNVP(name='Tstr', value=IoTValue(str='Hi There')), + IoTNVP(name='Tch', value=IoTValue(ch='X')), + + IoTNVP(name='Tui8Seq', value=IoTValue(ui8Seq=[127,128,129])), + IoTNVP(name='Tui16Seq', value=IoTValue(ui16Seq=[0x0102,0x0304])), + IoTNVP(name='Tui32Seq', value=IoTValue(ui32Seq=[0x01020304,0x05060708])), + IoTNVP(name='Tui64Seq', value=IoTValue(ui64Seq=[0x0102030405060708,0x0807060504030201])), + IoTNVP(name='Ti8Seq', value=IoTValue(i8Seq=['F','G','H','I'])), + IoTNVP(name='Ti16Seq', value=IoTValue(i16Seq=[0x0102,-0x0102])), + IoTNVP(name='Ti32Seq', value=IoTValue(i32Seq=[0x11020304,-0x01020304])), + IoTNVP(name='Ti64Seq', value=IoTValue(i64Seq=[0x1102030405060708,-0x0102030405060708])), + IoTNVP(name='Tf32Seq', value=IoTValue(f32Seq=[16.0,32.0,64.0,128.0])), + IoTNVP(name='Tf64Seq', value=IoTValue(f64Seq=[1024.0,1048.,4096.0])), + IoTNVP(name='TbSeq', value=IoTValue(bSeq=[True,False,True])), + IoTNVP(name='TstrSeq', value=IoTValue(strSeq=['Hi There','James','Bond'])), + IoTNVP(name='TchSeq', value=IoTValue(chSeq=['X','Y','Z'])), + ] + ) + for t in (IoTData, IoTNVP, IoTValue): + print('{0}._get_packing_fmt(): {1}, size={2}'.format( t.__name__, t._get_packing_fmt(), struct.calcsize(t._get_packing_fmt()))) + + print('data._get_packing_args(): {1}', data._get_packing_args()) + buffer = data._serialize() + print('buffer: ', buffer) + + values = struct.unpack(data._get_packing_fmt(), buffer) + data1 = IoTData() + data1._deserialize(list(values)) + + self.assertEqual(data.typeName, data1.typeName) + self.assertEqual(len(data.instanceId), len(data1.instanceId)) + for i in range(len(data.values)): + self.assertEqual(str(data.values[i]), str(data1.values[i]), 'str(values[%d])'%(i)) + + def testCopyInCopyOutEmpty(self): + data = IoTData( + typeName = 'Foo', + instanceId = 'BarE' + ) + for t in (IoTData, IoTNVP, IoTValue): + print('{0}._get_packing_fmt(): {1}, size={2}'.format( t.__name__, t._get_packing_fmt(), struct.calcsize(t._get_packing_fmt()))) + + print('data._get_packing_args(): {1}', data._get_packing_args()) + buffer = data._serialize() + print('buffer: ', buffer) + + values = struct.unpack(data._get_packing_fmt(), buffer) + data1 = IoTData() + data1._deserialize(list(values)) + + self.assertEqual(data.typeName, data1.typeName) + self.assertEqual(len(data.instanceId), len(data1.instanceId)) + for i in range(len(data.values)): + self.assertEqual(str(data.values[i]), str(data1.values[i]), 'str(values[%d])'%(i)) + + +if __name__ == "__main__": + #import sys;sys.argv = ['', 'TestIoTBuiltIn.testCopyInCopyOut'] + unittest.main() \ No newline at end of file diff --git a/src/api/dcps/python/test/TestMultiArrayBasicType.py b/src/api/dcps/python/test/TestMultiArrayBasicType.py new file mode 100644 index 000000000..386ec1fa9 --- /dev/null +++ b/src/api/dcps/python/test/TestMultiArrayBasicType.py @@ -0,0 +1,61 @@ +# +# Vortex OpenSplice +# +# This software and documentation are Copyright 2006 to TO_YEAR ADLINK +# Technology Limited, its affiliated companies and licensors. All rights +# reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +''' +Created on Dec 7, 2017 + +@author: prismtech +''' +import unittest +import struct +import countTest + +if countTest.count_test == False: + import MultiArrayBasicType.basic.module_MultiArrayBasicType + +class TestMultiArrayBasicType(unittest.TestCase): + + + def testCopyInCopyOut(self): + d = [[[(i+1) * 100 + (j+1) * 10 + (k+1)*1 for k in range (2)] for j in range(3)] for i in range(2)] + data = MultiArrayBasicType.basic.module_MultiArrayBasicType.MultiArrayBasicType_struct( + long1 = 12, + array1 = d + ) + print('data: ' + str(data)) + + print('data._get_packing_fmt(): ', data._get_packing_fmt()) + print('data._get_packing_args(): ', data._get_packing_args()) + buffer = data._serialize() + print('buffer: ', buffer) + + values = struct.unpack(data._get_packing_fmt(), buffer) + data1 = MultiArrayBasicType.basic.module_MultiArrayBasicType.MultiArrayBasicType_struct() + data1._deserialize(list(values)) + + self.assertEqual(data.long1, data1.long1) + for i in range(len(data.array1)): + for j in range(len(data.array1[i])): + for k in range(len(data.array1[i][j])): + self.assertEqual(data.array1[i][j][k], data1.array1[i][j][k], 'array1[%d][%d][%d]' % (i, j, k)) + + +if __name__ == "__main__": + #import sys;sys.argv = ['', 'Test.testCopyInCopyOut'] + unittest.main() \ No newline at end of file diff --git a/src/api/dcps/python/test/TestSequence.py b/src/api/dcps/python/test/TestSequence.py new file mode 100644 index 000000000..09a4bb971 --- /dev/null +++ b/src/api/dcps/python/test/TestSequence.py @@ -0,0 +1,77 @@ +# +# Vortex OpenSplice +# +# This software and documentation are Copyright 2006 to TO_YEAR ADLINK +# Technology Limited, its affiliated companies and licensors. All rights +# reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +''' +Created on Dec 8, 2017 + +@author: prismtech +''' +import unittest +import struct +import countTest + +if countTest.count_test == False: + import Sequence.basic.module_Sequence + +class TestSequence(unittest.TestCase): + + + def testCopyInCopyOut(self): + data = Sequence.basic.module_Sequence.Sequence_struct( + long1=12, + seq1=[21, 32, 43] + ) + print('data: ' + str(data)) + + print('data._get_packing_fmt(): ', data._get_packing_fmt()) + print('data._get_packing_args(): ', data._get_packing_args()) + buffer = data._serialize() + print('buffer: ', buffer) + + values = struct.unpack(data._get_packing_fmt(), buffer) + data1 = Sequence.basic.module_Sequence.Sequence_struct() + data1._deserialize(list(values)) + + self.assertEqual(data.long1, data1.long1) + self.assertEqual(data.seq1[0],data1.seq1[0]) + self.assertEqual(data.seq1[1],data1.seq1[1]) + self.assertEqual(data.seq1[2],data1.seq1[2]) + + def testCopyInCopyOutEmpty(self): + data = Sequence.basic.module_Sequence.Sequence_struct( + long1=12, + seq1=[] + ) + print('data: ' + str(data)) + + print('data._get_packing_fmt(): ', data._get_packing_fmt()) + print('data._get_packing_args(): ', data._get_packing_args()) + buffer = data._serialize() + print('buffer: ', buffer) + + values = struct.unpack(data._get_packing_fmt(), buffer) + data1 = Sequence.basic.module_Sequence.Sequence_struct() + data1._deserialize(list(values)) + + self.assertEqual(data.long1, data1.long1) + + +if __name__ == "__main__": + #import sys;sys.argv = ['', 'TestSequence.testCopyInCopyOut'] + unittest.main() \ No newline at end of file diff --git a/src/api/dcps/python/test/TestSequenceOfSimpleArray.py b/src/api/dcps/python/test/TestSequenceOfSimpleArray.py new file mode 100644 index 000000000..7e3a42310 --- /dev/null +++ b/src/api/dcps/python/test/TestSequenceOfSimpleArray.py @@ -0,0 +1,58 @@ +# +# Vortex OpenSplice +# +# This software and documentation are Copyright 2006 to TO_YEAR ADLINK +# Technology Limited, its affiliated companies and licensors. All rights +# reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +''' +Created on Dec 8, 2017 + +@author: prismtech +''' +import unittest +import struct +import countTest + +if countTest.count_test == False: + from SequenceOfSimpleArray.basic.module_SequenceOfSimpleArray import SequenceOfSimpleArray_struct + +class TestSequenceOfSimpleArray(unittest.TestCase): + + + def testCopyInCopyOut(self): + data = SequenceOfSimpleArray_struct( + long1 = 13, + sequence1 = [[11, 12], [21,22], [31,32]]) + print('data: ' + str(data)) + + print('data._get_packing_fmt(): ', data._get_packing_fmt()) + print('data._get_packing_args(): ', data._get_packing_args()) + buffer = data._serialize() + print('buffer: ', buffer) + + values = struct.unpack(data._get_packing_fmt(), buffer) + data1 = SequenceOfSimpleArray_struct() + data1._deserialize(list(values)) + + self.assertEqual(data.long1, data1.long1) + self.assertEqual(len(data.sequence1), len(data1.sequence1)) + for i in range(len(data.sequence1)): + self.assertEqual(data.sequence1[i], data1.sequence1[i], 'sequence[%d]'%(i)) + + +if __name__ == "__main__": + #import sys;sys.argv = ['', 'TestSequenceOfSimpleArray.testCopyInCopyOut'] + unittest.main() \ No newline at end of file diff --git a/src/api/dcps/python/test/TestSequenceOfStruct.py b/src/api/dcps/python/test/TestSequenceOfStruct.py new file mode 100644 index 000000000..4bf932128 --- /dev/null +++ b/src/api/dcps/python/test/TestSequenceOfStruct.py @@ -0,0 +1,62 @@ +# +# Vortex OpenSplice +# +# This software and documentation are Copyright 2006 to TO_YEAR ADLINK +# Technology Limited, its affiliated companies and licensors. All rights +# reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +''' +Created on Dec 8, 2017 + +@author: prismtech +''' +import unittest +import struct +import countTest + +if countTest.count_test == False: + from SequenceOfStruct.basic.module_SequenceOfStruct import SequenceOfStruct_struct, Inner + +class Test(unittest.TestCase): + + + def testCopyInCopyOut(self): + data = SequenceOfStruct_struct( + long1 = 13, + seq1 = [Inner(short1=11,double1=1.1), + Inner(short1=12,double1=1.2), + Inner(short1=13,double1=1.3)]) + print('data: ' + str(data)) + + print('data._get_packing_fmt(): ', data._get_packing_fmt()) + print('data._get_packing_args(): ', data._get_packing_args()) + buffer = data._serialize() + print('buffer: ', buffer) + + values = struct.unpack(data._get_packing_fmt(), buffer) + data1 = SequenceOfStruct_struct() + data1._deserialize(list(values)) + + self.assertEqual(data.long1, data1.long1) + self.assertEqual(len(data.seq1), len(data1.seq1)) + for i in range(len(data.seq1)): + self.assertEqual(data.seq1[i].short1, data1.seq1[i].short1, 'seq1[%d].short1'%(i)) + self.assertEqual(data.seq1[i].double1, data1.seq1[i].double1, 'seq1[%d].double1'%(i)) + + + +if __name__ == "__main__": + #import sys;sys.argv = ['', 'Test.testCopyInCopyOut'] + unittest.main() \ No newline at end of file diff --git a/src/api/dcps/python/test/TestSequenceOfStructArray.py b/src/api/dcps/python/test/TestSequenceOfStructArray.py new file mode 100644 index 000000000..12ce55d56 --- /dev/null +++ b/src/api/dcps/python/test/TestSequenceOfStructArray.py @@ -0,0 +1,65 @@ +# +# Vortex OpenSplice +# +# This software and documentation are Copyright 2006 to TO_YEAR ADLINK +# Technology Limited, its affiliated companies and licensors. All rights +# reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +''' +Created on Dec 8, 2017 + +@author: prismtech +''' +import unittest +import struct +import countTest + +if countTest.count_test == False: + from SequenceOfStructArray.basic.module_SequenceOfStructArray import SequenceOfStructArray_struct, Inner + +class TestSequenceOfStructArray(unittest.TestCase): + + + def testCopyInCopyOut(self): + data = SequenceOfStructArray_struct( + long1 = 13, + seq1= [ + [Inner(short1=11,double1=1.1),Inner(short1=12,double1=1.2)], + [Inner(short1=21,double1=2.1),Inner(short1=22,double1=2.2)], + [Inner(short1=31,double1=3.1),Inner(short1=32,double1=3.2)], + ]) + print('data: ' + str(data)) + + print('data._get_packing_fmt(): ', data._get_packing_fmt()) + print('data._get_packing_args(): ', data._get_packing_args()) + buffer = data._serialize() + print('buffer: ', buffer) + + values = struct.unpack(data._get_packing_fmt(), buffer) + data1 = SequenceOfStructArray_struct() + data1._deserialize(list(values)) + + self.assertEqual(data.long1, data1.long1) + self.assertEqual(len(data.seq1), len(data1.seq1)) + for i in range(len(data.seq1)): + self.assertEqual(len(data.seq1[i]), len(data1.seq1[i]), 'len(seq1[%d])'%(i)) + for j in range(len(data.seq1[i])): + self.assertEqual(data.seq1[i][j].short1, data1.seq1[i][j].short1, 'seq1[%d][%d].short1'%(i,j)) + self.assertEqual(data.seq1[i][j].double1, data1.seq1[i][j].double1, 'seq1[%d][%d].double1'%(i,j)) + + +if __name__ == "__main__": + #import sys;sys.argv = ['', 'TestSequenceOfStructArray.testCopyInCopyOut'] + unittest.main() \ No newline at end of file diff --git a/src/api/dcps/python/test/TestStringTypes.py b/src/api/dcps/python/test/TestStringTypes.py new file mode 100644 index 000000000..d0ea415b7 --- /dev/null +++ b/src/api/dcps/python/test/TestStringTypes.py @@ -0,0 +1,60 @@ +# +# Vortex OpenSplice +# +# This software and documentation are Copyright 2006 to TO_YEAR ADLINK +# Technology Limited, its affiliated companies and licensors. All rights +# reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +''' +Created on Dec 17, 2017 + +@author: prismtech +''' +import unittest +import struct +import countTest + +if countTest.count_test == False: + from StringTypes.basic.module_StringTypes import StringTypes_struct + +class TestStringTypes(unittest.TestCase): + + + def testCopyInCopyOut(self): + data = StringTypes_struct( + long1 = 32, + string1='Hello World!', + string2='Five5', + string_array=['Alpha','Bravo','Delta'], + string_seq1=['Fee','Fi','Foe','Fum'], + string_seq2=['Echo','Delta', 'Espsi', 'Foxtr']) + + print('data: ' + str(data)) + + print('data._get_packing_fmt(): ', data._get_packing_fmt()) + buffer = data._serialize() + print('buffer: ', buffer) + + values = struct.unpack(data._get_packing_fmt(), buffer) + data1 = StringTypes_struct() + data1._deserialize(list(values)) + + for attr in ('string1','string2','string_array','string_seq1','string_seq2'): + self.assertEqual(getattr(data,attr),getattr(data1,attr),attr) + + +if __name__ == "__main__": + #import sys;sys.argv = ['', 'TestStringTypes.testCopyInCopyOut'] + unittest.main() \ No newline at end of file diff --git a/src/api/dcps/python/test/TestUnion.py b/src/api/dcps/python/test/TestUnion.py new file mode 100644 index 000000000..3a07ec20f --- /dev/null +++ b/src/api/dcps/python/test/TestUnion.py @@ -0,0 +1,158 @@ +# +# Vortex OpenSplice +# +# This software and documentation are Copyright 2006 to TO_YEAR ADLINK +# Technology Limited, its affiliated companies and licensors. All rights +# reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +''' +Created on Dec 16, 2017 + +@author: prismtech +''' +import unittest +import struct +import countTest + +if countTest.count_test == False: + from Union.basic.module_Union import ano21, Color, uone, utwo, uthree, ufour, ufive, Union_struct + +class Test(unittest.TestCase): + + + def testDefaultConstructor(self): + u1 = uone() + self.assertEqual(u1.discriminator, Color.Red) + self.assertEqual(u1.s, 0) + + u2 = utwo() + self.assertEqual(u2.discriminator, Color.Red) + self.assertEqual(u2.s, 0) + + u3 = uthree() + self.assertEqual(u3.discriminator, '\x00') + self.assertIsNone(u3._v) + + u4 = ufour() + self.assertEqual(u4.discriminator, 0) + self.assertIsNone(u4._v) + + u5 = ufive() + self.assertEqual(u5.discriminator, False) + self.assertEqual(u5.sF, 0) + + def testDVConstructor(self): + u1 = uone(Color.Green, 32) + self.assertEqual(u1.discriminator, Color.Green) + self.assertEqual(u1.l,32) + + u2 = utwo(Color.Green, 33) + self.assertEqual(u2.discriminator, Color.Green) + self.assertEqual(u2.l, 33) + + u3 = uthree('a',34) + self.assertEqual(u3.discriminator, 'a') + self.assertEqual(u3.sa, 34) + + u4 = ufour(2, 35) + self.assertEqual(u4.discriminator, 2) + self.assertEqual(u4.s2, 35) + + u5 = ufive(True, 36) + self.assertEqual(u5.discriminator, True) + self.assertEqual(u5.sT, 36) + + def testKWConstructor(self): + u1 = uone(ll=41) + self.assertEqual(u1.discriminator, Color.Yellow) + self.assertEqual(u1.ll, 41) + + u2 = utwo(l=42) + self.assertEqual(u2.discriminator, Color.Green) + self.assertEqual(u2.l,42) + + u3 = uthree(sa=43) + self.assertEqual(u3.discriminator, 'a') + self.assertEqual(u3.sa, 43) + + u4 = ufour(s1=44) + self.assertEqual(u4.discriminator, 1) + self.assertEqual(u4.s1, 44) + + u5 = ufive(sT=45) + self.assertEqual(u5.discriminator, True) + self.assertEqual(u5.sT, 45) + + def testSetDefault(self): + u2 = utwo() + self.assertIsNotNone(u2._v) + u2.set_default() + self.assertIsNone(u2._v) + + u3 = uthree(sa=53) + self.assertIsNotNone(u3._v) + u3.set_default() + self.assertIsNone(u3._v) + + u4 = ufour(s1=52) + self.assertIsNotNone(u4._v) + u4.set_default() + self.assertIsNone(u4._v) + + def testSerializeDeserialize(self): + for u in [uone(l=32), uone(s=16), uone(ll=64), uone()]: + u_o = uone() + u_o._deserialize(list(struct.unpack(uone._get_packing_fmt(),u._serialize()))) + self.assertEqual(str(u),str(u_o)) + + for u in [utwo(s=15), utwo(l=333), utwo(Color.Blue,None), utwo()]: + u_o = utwo() + u_o._deserialize(list(struct.unpack(utwo._get_packing_fmt(),u._serialize()))) + self.assertEqual(str(u),str(u_o)) + + for u in [uthree(sa=35), uthree(sb=333), uthree('x'), uthree()]: + u_o = uthree() + u_o._deserialize(list(struct.unpack(uthree._get_packing_fmt(),u._serialize()))) + self.assertEqual(str(u),str(u_o)) + + for u in [ufour(s1=155), ufour(s2=312), ufour(3,None), ufour()]: + u_o = ufour() + u_o._deserialize(list(struct.unpack(ufour._get_packing_fmt(),u._serialize()))) + self.assertEqual(str(u),str(u_o)) + + for u in [ufive(sT=1066), ufive(sF=1944), ufive()]: + u_o = ufive() + u_o._deserialize(list(struct.unpack(ufive._get_packing_fmt(),u._serialize()))) + self.assertEqual(str(u),str(u_o)) + + ano1 = ano21() + ano1.discriminator = 97 + ano1.x1[0][0] = 11 + ano1.x1[1][1] = 22 + ano1.x1[11][11] = 1212 + + ano2 = ano21() + ano2.discriminator = 98 + ano2.x2[0][1][2][5] = Color.Blue + ano2.x2[1][1][1][1] = Color.Orange + for s in [Union_struct(long1=111,union1=ano1), Union_struct(long1=222,union1=ano2)]: + s_o = Union_struct() + s_o._deserialize(list(struct.unpack(Union_struct._get_packing_fmt(),s._serialize()))) + self.assertEqual(str(s),str(s_o)) + + +if __name__ == "__main__": + #import sys;sys.argv = ['', 'Test.testDefaultConstructor'] + unittest.main() \ No newline at end of file diff --git a/src/api/dcps/python/test/Testsample2.py b/src/api/dcps/python/test/Testsample2.py new file mode 100644 index 000000000..c4d8d3b4f --- /dev/null +++ b/src/api/dcps/python/test/Testsample2.py @@ -0,0 +1,70 @@ +# +# Vortex OpenSplice +# +# This software and documentation are Copyright 2006 to TO_YEAR ADLINK +# Technology Limited, its affiliated companies and licensors. All rights +# reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +''' +Created on Dec 8, 2017 + +@author: prismtech +''' +import unittest +import struct +import countTest + +if countTest.count_test == False: + from sample2.basic import Inner + from sample2.basic.test import Type1 + +class Testsample2(unittest.TestCase): + + + def testCopyInCopyOut(self): + data = Type1( + long1 = '\x13', + inner1 = [ + Inner(long1=11,double1=1.1,array1=[11,12,13],str1='One'), + Inner(long1=21,double1=2.1,array1=[21,22,23],str1='Two'), + Inner(long1=31,double1=3.1,array1=[31,32,33],str1='Three'), + ], + mylong1 = 23 + ) + print('data: ' + str(data)) + + print('data._get_packing_fmt(): ', data._get_packing_fmt()) + print('data._get_packing_args(): ', data._get_packing_args()) + buffer = data._serialize() + print('buffer: ', buffer) + + values = struct.unpack(data._get_packing_fmt(), buffer) + data1 = Type1() + data1._deserialize(list(values)) + + self.assertEqual(data.long1, data1.long1) + self.assertEqual(data.mylong1, data.mylong1) + self.assertEqual(len(data.inner1),len(data1.inner1)) + for i in range(len(data.inner1)): + self.assertEqual(data.inner1[i].long1,data1.inner1[i].long1,'inner1[%d].long1'%i) + self.assertEqual(data.inner1[i].double1,data1.inner1[i].double1,'inner1[%d].double1'%i) + self.assertEqual(len(data.inner1[i].array1),len(data1.inner1[i].array1),'len(inner1[%d].array1)'%i) + for j in range(len(data.inner1[i].array1)): + self.assertEqual(data.inner1[i].array1[j],data1.inner1[i].array1[j],'inner1[%d].array1[%d]'%(i,j)) + + +if __name__ == "__main__": + #import sys;sys.argv = ['', 'Testsample2.testCopyInCopyOut'] + unittest.main() \ No newline at end of file diff --git a/src/api/dcps/python/test/__init__.py b/src/api/dcps/python/test/__init__.py new file mode 100644 index 000000000..e67ecd52a --- /dev/null +++ b/src/api/dcps/python/test/__init__.py @@ -0,0 +1,19 @@ +# +# Vortex OpenSplice +# +# This software and documentation are Copyright 2006 to TO_YEAR ADLINK +# Technology Limited, its affiliated companies and licensors. All rights +# reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# diff --git a/src/api/dcps/python/test/countTest.py b/src/api/dcps/python/test/countTest.py new file mode 100644 index 000000000..5521e9c2a --- /dev/null +++ b/src/api/dcps/python/test/countTest.py @@ -0,0 +1,31 @@ +# +# Vortex OpenSplice +# +# This software and documentation are Copyright 2006 to TO_YEAR ADLINK +# Technology Limited, its affiliated companies and licensors. All rights +# reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# The 'count_test' variable determines if generated modules from the idl file +# will be imported or not. +# The import will happen only if the 'count_test' variable is set to false. +# The 'count_test' variable is set to true only in the generateTestcaseList.py +# file because for generating testcase list there is no need of importing +# the idl generated modules and it happens before the generation of the modules +# from the idl file. +# For all the other cases the count_test variable is set to false, resulting in +# import of the generated modules from the idl files. + +count_test = False diff --git a/src/api/dcps/python/test/generateTestcaseList.py b/src/api/dcps/python/test/generateTestcaseList.py new file mode 100644 index 000000000..8a8aeec94 --- /dev/null +++ b/src/api/dcps/python/test/generateTestcaseList.py @@ -0,0 +1,57 @@ +# +# Vortex OpenSplice +# +# This software and documentation are Copyright 2006 to TO_YEAR ADLINK +# Technology Limited, its affiliated companies and licensors. All rights +# reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import unittest +import os +import re +import countTest + +def package_contents(): + files = os.listdir() + # Use a set because some may be both source and compiled. + return set([os.path.splitext(module)[0] + for module in files + if re.match(r'[tT]est.*\.py', module)]) + +def print_all_testcases(testcaseList): + try: + root = os.getenv('OSPL_OUTER_HOME_NORMALIZED') + file = os.path.join(root,"testsuite","dbt","api","dcps","python","bin","testcases") + etcf = open(file, 'w') + for testcase in testcaseList: + etcf.write ("python_{}\n".format(testcase.replace(".","_"))) + finally: + etcf.close() + + +def all_pyUnit_tests(): + testcaseList = [] + testmodules = package_contents() + for t in testmodules: + # load all the test cases from the module. + for test in unittest.defaultTestLoader.loadTestsFromName(t): + for testcase in test: + testcaseList.append(testcase.id()) + + print_all_testcases(testcaseList) + +if __name__ == '__main__': + countTest.count_test = True + all_pyUnit_tests() + countTest.count_test = False diff --git a/src/api/dcps/python/test/idl/Array.idl b/src/api/dcps/python/test/idl/Array.idl new file mode 100644 index 000000000..dce66be98 --- /dev/null +++ b/src/api/dcps/python/test/idl/Array.idl @@ -0,0 +1,13 @@ +module basic{ + + module module_Array{ + + struct Array_struct{ + long long1; + double array1[3]; + }; + + #pragma keylist Array_struct long1 + }; +}; + diff --git a/src/api/dcps/python/test/idl/ArrayOfSimpleSequence.idl b/src/api/dcps/python/test/idl/ArrayOfSimpleSequence.idl new file mode 100644 index 000000000..3a3ffef14 --- /dev/null +++ b/src/api/dcps/python/test/idl/ArrayOfSimpleSequence.idl @@ -0,0 +1,15 @@ +module basic{ + + typedef sequence longSeq; + + module module_ArrayOfSimpleSequence{ + + struct ArrayOfSimpleSequence_struct{ + long long1; + longSeq array1[2]; + }; + + #pragma keylist ArrayOfSimpleSequence_struct long1 + }; +}; + diff --git a/src/api/dcps/python/test/idl/ArrayOfStruct.idl b/src/api/dcps/python/test/idl/ArrayOfStruct.idl new file mode 100644 index 000000000..8720be4d5 --- /dev/null +++ b/src/api/dcps/python/test/idl/ArrayOfStruct.idl @@ -0,0 +1,24 @@ +const long length = 2; +typedef long my_long; + +module basic{ + + module module_ArrayOfStruct{ + + struct Inner{ + short long1; + double double1; + }; + + typedef Inner inner_struct; + + struct ArrayOfStruct_struct{ + long long1; + inner_struct array1[length]; + my_long mylong1; + }; + + #pragma keylist ArrayOfStruct_struct long1 + }; +}; + diff --git a/src/api/dcps/python/test/idl/ArrayOfStructSequence.idl b/src/api/dcps/python/test/idl/ArrayOfStructSequence.idl new file mode 100644 index 000000000..ce1cd7dcf --- /dev/null +++ b/src/api/dcps/python/test/idl/ArrayOfStructSequence.idl @@ -0,0 +1,21 @@ +module basic{ + + module module_ArrayOfStructSequence{ + + struct Inner{ + short short1; + double double1; + }; + + typedef Inner inner_struct; + typedef sequence innerSeq; + + struct ArrayOfStructSequence_struct{ + long long1; + innerSeq array1[2]; + }; + + #pragma keylist ArrayOfStructSequence_struct long1 + }; +}; + diff --git a/src/api/dcps/python/test/idl/BasicStruct.idl b/src/api/dcps/python/test/idl/BasicStruct.idl new file mode 100644 index 000000000..b3631d98e --- /dev/null +++ b/src/api/dcps/python/test/idl/BasicStruct.idl @@ -0,0 +1,40 @@ +// +// From comment on 4/Dec/2015 +// + +module mod_X { + typedef short A; + typedef short B; +}; + +module mod_Y { + typedef short B; + typedef short A; + typedef short C; +}; + +module mod_Z { + typedef short B; + typedef short A; +}; + + +module declaration_order { + + typedef short A; + typedef short B; + + struct S11 { + mod_X::B xb; + mod_Z::A za; + mod_Y::A ya; + B b; + mod_X::A xa; + mod_Y::B yb; + mod_Z::B zb; + mod_Y::C yc; + A a; + }; +#pragma keylist S11 xb + +}; diff --git a/src/api/dcps/python/test/idl/CharTypes.idl b/src/api/dcps/python/test/idl/CharTypes.idl new file mode 100644 index 000000000..0a6ec5038 --- /dev/null +++ b/src/api/dcps/python/test/idl/CharTypes.idl @@ -0,0 +1,19 @@ +module basic { + module module_CharTypes { + typedef string<5> string5; + + struct CharTypes_struct { + long long1; + char char1; + char char_array[10]; + sequence char_seq1; + sequence char_seq2; + + octet octet1; + octet octet_array[10]; + sequence octet_seq1; + sequence octet_seq2; + }; + #pragma keylist CharTypes_struct long1 + }; +}; diff --git a/src/api/dcps/python/test/idl/Constants.idl b/src/api/dcps/python/test/idl/Constants.idl new file mode 100644 index 000000000..713a926e9 --- /dev/null +++ b/src/api/dcps/python/test/idl/Constants.idl @@ -0,0 +1,38 @@ +const long TWO = 1 + 11 - 10; + +enum Color { + RED, + GREEN, + BLUE +}; + +const char Cchar = 'a'; +const octet Coctet = 255; +const short Cshort = 1000; +const unsigned short Cushort = 2000; +const long Clong = 3000; +const unsigned long CULong = 4000; // this is trouble +const long long Clonglong = 5000; +const unsigned long long Culonglong = 6000; +const float Cfloat = 3.14; +const double Cdouble = 9.8e55; +const boolean Cbool = True; +const string Cstring = "Hello"; +const Color Cenum = GREEN; + +module basic { + const long SIX = 6; + module module_Constants { + const long FIVE = 5; + + const long ADDED = Clong + Cshort + CULong; + + struct Constants_struct { + long long1; + long five_array[FIVE]; + long six_array[SIX]; + long two_array[TWO]; + }; + #pragma keylist Constants_struct long1 + }; +}; diff --git a/src/api/dcps/python/test/idl/Enum2.idl b/src/api/dcps/python/test/idl/Enum2.idl new file mode 100644 index 000000000..ec8630a49 --- /dev/null +++ b/src/api/dcps/python/test/idl/Enum2.idl @@ -0,0 +1,27 @@ +module basic{ + + module enumZ { + + enum Color { Red, Green, Blue }; + + }; + + module module_Enum2{ + + enum Color { Red, Green, Blue }; + typedef Color AColor; + typedef enumZ::Color ZColor; + + struct Enum2_struct{ + long long1; + AColor color1; + ZColor color2; + ZColor array[2]; + }; + + #pragma keylist Enum2_struct long1 + }; + + +}; + diff --git a/src/api/dcps/python/test/idl/IdlIncludingInner_idl.idl b/src/api/dcps/python/test/idl/IdlIncludingInner_idl.idl new file mode 100644 index 000000000..0f481bdeb --- /dev/null +++ b/src/api/dcps/python/test/idl/IdlIncludingInner_idl.idl @@ -0,0 +1,10 @@ +#include "Inner_idl.idl" + +module Outer_mod { + struct Outer { + long key; + inner_mod::Inner inner1; + }; + #pragma keylist Outer key +}; + \ No newline at end of file diff --git a/src/api/dcps/python/test/idl/Inner_idl.idl b/src/api/dcps/python/test/idl/Inner_idl.idl new file mode 100644 index 000000000..9363df0d3 --- /dev/null +++ b/src/api/dcps/python/test/idl/Inner_idl.idl @@ -0,0 +1,6 @@ +module inner_mod { + struct Inner { + short short1; + double double1; + }; +}; diff --git a/src/api/dcps/python/test/idl/LelyExample2.idl b/src/api/dcps/python/test/idl/LelyExample2.idl new file mode 100644 index 000000000..76558b9c9 --- /dev/null +++ b/src/api/dcps/python/test/idl/LelyExample2.idl @@ -0,0 +1,33 @@ + +enum rootEnum { + A, + B +}; + +module basic{ + + enum basicEnum { + A, + B + }; + + module module_SequenceOfStruct{ + + struct Inner{ + short short1; + double double1; + + }; + + typedef Inner inner_struct; + + struct SequenceOfStruct_struct{ + long long1; + Sequence seq1; + rootEnum enum_test; + }; + + #pragma keylist SequenceOfStruct_struct + }; +}; + diff --git a/src/api/dcps/python/test/idl/Lely_example1.idl b/src/api/dcps/python/test/idl/Lely_example1.idl new file mode 100644 index 000000000..8d7c643f5 --- /dev/null +++ b/src/api/dcps/python/test/idl/Lely_example1.idl @@ -0,0 +1,48 @@ +module FarmGraph { + + enum FarmGraphEntityType{ + PROCESSING_AREA, + TCS_AREA, + MULTI_COW_AREA, + HIGH_PRIORITY_AREA, + AUTOMATIC_HOLDING_AREA, + SELECTION_GATE, + SEGREGATION_GATE, + BLOCKING_GATE + }; + + struct FarmGraphEntity{ + string identifier; + unsigned long robot_id; + FarmGraphEntityType type; + }; + + struct FarmGraphEdge{ + string entity_1_identifier; + string entity_2_identifier; + boolean bidirectional; + string position; + }; + + struct RoutingDataResult{ + sequence entities; + sequence edges; + }; + #pragma keylist RoutingDataResult + +}; + +/** No module, key */ + +enum LeftRightStates{ + LEFT, + RIGHT +}; + +struct SegregationGate{ + string output_identifier; + LeftRightStates state; +}; +#pragma keylist SegregationGate output_identifier + + diff --git a/src/api/dcps/python/test/idl/MultiArrayBasicType.idl b/src/api/dcps/python/test/idl/MultiArrayBasicType.idl new file mode 100644 index 000000000..2d6171dcd --- /dev/null +++ b/src/api/dcps/python/test/idl/MultiArrayBasicType.idl @@ -0,0 +1,11 @@ +module basic{ + module module_MultiArrayBasicType{ + + struct MultiArrayBasicType_struct{ + long long1; + long array1[2][3][2]; + }; + + #pragma keylist MultiArrayBasicType_struct long1 + }; +}; diff --git a/src/api/dcps/python/test/idl/NestedStruct.idl b/src/api/dcps/python/test/idl/NestedStruct.idl new file mode 100644 index 000000000..97d5fbc95 --- /dev/null +++ b/src/api/dcps/python/test/idl/NestedStruct.idl @@ -0,0 +1,28 @@ +const long length = 3; + +module test{ + typedef long my_long; +}; + +module basic{ + + typedef long basic_long; + + module module_NestedStruct{ + + struct Inner{ + basic::basic_long long1; + double double1; + }; + + typedef Inner inner_struct; + + struct NestedStruct_struct{ + test::my_long long1; + inner_struct inner1; + }; + + #pragma keylist NestedStruct_struct long1 + }; +}; + diff --git a/src/api/dcps/python/test/idl/Sequence.idl b/src/api/dcps/python/test/idl/Sequence.idl new file mode 100644 index 000000000..56ba041d6 --- /dev/null +++ b/src/api/dcps/python/test/idl/Sequence.idl @@ -0,0 +1,13 @@ +module basic{ + + module module_Sequence{ + + struct Sequence_struct{ + long long1; + Sequence seq1; + }; + + #pragma keylist Sequence_struct long1 + }; +}; + diff --git a/src/api/dcps/python/test/idl/SequenceOfSimpleArray.idl b/src/api/dcps/python/test/idl/SequenceOfSimpleArray.idl new file mode 100644 index 000000000..820fb340c --- /dev/null +++ b/src/api/dcps/python/test/idl/SequenceOfSimpleArray.idl @@ -0,0 +1,15 @@ +module basic{ + + module module_SequenceOfSimpleArray{ + + typedef long arr[2]; + + struct SequenceOfSimpleArray_struct{ + long long1; + Sequence sequence1; + }; + + #pragma keylist SequenceOfSimpleArray_struct long1 + }; +}; + diff --git a/src/api/dcps/python/test/idl/SequenceOfStruct.idl b/src/api/dcps/python/test/idl/SequenceOfStruct.idl new file mode 100644 index 000000000..397ab59ee --- /dev/null +++ b/src/api/dcps/python/test/idl/SequenceOfStruct.idl @@ -0,0 +1,20 @@ +module basic{ + + module module_SequenceOfStruct{ + + struct Inner{ + short short1; + double double1; + }; + + typedef Inner inner_struct; + + struct SequenceOfStruct_struct{ + long long1; + Sequence seq1; + }; + + #pragma keylist SequenceOfStruct_struct long1 + }; +}; + diff --git a/src/api/dcps/python/test/idl/SequenceOfStructArray.idl b/src/api/dcps/python/test/idl/SequenceOfStructArray.idl new file mode 100644 index 000000000..0fbe2703f --- /dev/null +++ b/src/api/dcps/python/test/idl/SequenceOfStructArray.idl @@ -0,0 +1,21 @@ +module basic{ + + module module_SequenceOfStructArray{ + + struct Inner{ + short short1; + double double1; + }; + + typedef Inner inner_struct; + typedef inner_struct arr[2]; + + struct SequenceOfStructArray_struct{ + long long1; + Sequence seq1; + }; + + #pragma keylist SequenceOfStructArray_struct long1 + }; +}; + diff --git a/src/api/dcps/python/test/idl/Shapes.idl b/src/api/dcps/python/test/idl/Shapes.idl new file mode 100644 index 000000000..c0aa14517 --- /dev/null +++ b/src/api/dcps/python/test/idl/Shapes.idl @@ -0,0 +1,21 @@ +struct Inner { + long foo; +}; + +struct ShapeType { + string color; + long x; + long y; + long z; + Inner t; +}; +#pragma keylist ShapeType color + +struct ShapeType2 { + string color; + long x; + long y; + long z; + Inner t; +}; +#pragma keylist ShapeType2 color diff --git a/src/api/dcps/python/test/idl/SimpleTypes.idl b/src/api/dcps/python/test/idl/SimpleTypes.idl new file mode 100644 index 000000000..4ba2f2d55 --- /dev/null +++ b/src/api/dcps/python/test/idl/SimpleTypes.idl @@ -0,0 +1,21 @@ +module basic{ + module module_SimpleTypes{ + struct SimpleTypes_struct{ + long long1; + unsigned long ulong1; + long long longlong1; + unsigned long long ulonglong1; + float float1; + short short1; + unsigned short ushort1; + char char1; + octet octet1; + double double1; + //long double longdouble1; + boolean bool1; + string string1; + }; + + #pragma keylist SimpleTypes_struct long1 + }; +}; diff --git a/src/api/dcps/python/test/idl/StringTypes.idl b/src/api/dcps/python/test/idl/StringTypes.idl new file mode 100644 index 000000000..7d9550efd --- /dev/null +++ b/src/api/dcps/python/test/idl/StringTypes.idl @@ -0,0 +1,14 @@ +module basic { + module module_StringTypes { + typedef string<5> string5; + struct StringTypes_struct { + long long1; + string string1; + string<5> string2; + string string_array[3]; + sequence string_seq1; + sequence string_seq2; + }; + #pragma keylist StringTypes_struct long1 + }; +}; diff --git a/src/api/dcps/python/test/idl/TestIDL.idl b/src/api/dcps/python/test/idl/TestIDL.idl new file mode 100644 index 000000000..677fd16af --- /dev/null +++ b/src/api/dcps/python/test/idl/TestIDL.idl @@ -0,0 +1,66 @@ +module basic{ + module module_TestIDL { + typedef sequence longSeq; + typedef sequence longLongSeq; + typedef sequence longLongLongSeq; + typedef long arr[3]; + typedef longSeq arrayseq[3]; + + struct InnerInnerStruct { + long num; + long array[2]; + long arr2D[2][2]; + }; + + struct InnerCollectionStruct { + long num; + long size; + long array[2]; + sequence seqnce; + long arr2D[2][2]; + sequence seq2D; + InnerInnerStruct innerInnerStruct; + }; + + struct MultiCollectionType { + long key; + long num; + char ch; + long array[2]; + sequence seqnce; + long arr2D[2][3]; + sequence seqarr; + arrayseq arrseq; + + sequence seq2D; + sequence seq4D; + InnerCollectionStruct innerStruct; + InnerCollectionStruct innerStructArray[2]; + sequence innerStructSeq; + }; + #pragma keylist MultiCollectionType key + + struct SeqseqType { + long key; + sequence seq2D; + sequence seq4D; + }; + #pragma keylist SeqseqType key + + typedef sequence structSeq; + + struct StructSeqseqType { + long key; + sequence structSeq2D; + }; + #pragma keylist StructSeqseqType key + + struct StructCharCollectionType { + char key; + sequence charseq; + sequence charbseq; + char chararr[6]; + }; + #pragma keylist StructCharCollectionType key + }; +}; \ No newline at end of file diff --git a/src/api/dcps/python/test/idl/TestIDL2.idl b/src/api/dcps/python/test/idl/TestIDL2.idl new file mode 100644 index 000000000..d3390bfab --- /dev/null +++ b/src/api/dcps/python/test/idl/TestIDL2.idl @@ -0,0 +1,2326 @@ +// Fichier IDL pour l'application SYS_TRADUCTEUR_ETH_DDS_TRT +// Extraction modele de donnees generique version V2.0_20150211 + +module VDM +{ + + // Maximal size of zones + const unsigned short c_NbZoneMax=10; + + // Maximm size of a tiny character string + const unsigned short c_ShortString=10; + + // Maximum size of a great character string + const unsigned short c_LongString=50; + + const unsigned short c_SvCommandLineString=500; + + // Redéfinition d'un chaine de c_ShortString (10) caractères + typedef string stringShort; + + // Redéfinition d'un chaine de c_LongString (50) caractères + typedef string string50; + + // Redéfinition d'un chaine de 1000 caractères + typedef string<1000> string1000; + + // Redéfinition d'une chaine de c_SvCommandLineString (500) carctères dédiée aux services + typedef string stringSvCmdLine; + + module COM + { + + // Operator identifier + typedef unsigned short ECOM_OperatorIdentifier_t; + + typedef unsigned short ECOM_AutoManuMode_t; + + typedef unsigned short ECOM_WeaponType_t; + + typedef unsigned short ECOM_OpeningState_t; + + typedef unsigned short ECOM_LockingState_t; + + typedef unsigned short ECOM_CTASCErrorCode_t; + + typedef unsigned short ECOM_AmmunitionType_t; + + typedef unsigned short ECOM_ActivatedState_t; + + typedef unsigned short ECOM_BargraphType_t; + + typedef unsigned short ECOM_FiringWindow_t; + + // Sight identifier + typedef unsigned short ECOM_SightType_t; + + typedef unsigned short ECOM_ResponseButton_t; + + // Alert state + typedef unsigned short ECOM_AlertState_t; + + typedef unsigned short ECOM_SubComponents_t; + + typedef unsigned short ECOM_SystemComponents_t; + + // User profile + typedef unsigned short ECOM_UserProfile_t; + + typedef unsigned short ECOM_CarrierType_t; + + // Equipment state + typedef unsigned short ECOM_EquipmentState_t; + + typedef unsigned short ECOM_MFDPosition_t; + + // Video channel + typedef unsigned short ECOM_VideoChannel_t; + + // Video field + typedef unsigned short ECOM_VideoField_t; + + typedef unsigned short ECOM_Equipment_t; + + typedef unsigned short ECOM_HWPresence_t; + + typedef unsigned short ECOM_PowerActivState_t; + + typedef unsigned short ECOM_OperatorRequest_t; + + typedef boolean ECOM_AuthorizationBool_t; + + typedef unsigned short ECOM_Language_t; + + // Function state + typedef unsigned short ECOM_FunctionState_t; + + // Direction to rally + typedef unsigned short ECOM_SlewingDirection_t; + + typedef unsigned short ECOM_ZoneVeh_t; + + typedef unsigned short ECOM_Status_t; + + // Position de la fenêtre + struct TCOM_AppPosition + { + // X + unsigned long m_nX; + // Y + unsigned long m_nY; + }; + + // Taille de la fenêtre + struct TCOM_AppSize + { + // Largeur + unsigned long m_nWidth; + // Hauteur + unsigned long m_nHeight; + }; + }; + + module IMV + { + + typedef unsigned long long TIMV_ApplicationIdentifier_t; + }; + + module SYS + { + + typedef unsigned short ESYS_TimeMode_t; + + typedef unsigned short ESYS_WindowState_t; + + typedef unsigned short ESYS_DiscretionMode_t; + + typedef unsigned short ESYS_DiscretionSource_t; + + typedef unsigned short ESYS_EmergencyStopType_t; + + typedef unsigned short ESYS_HarmoPhases_t; + + typedef unsigned short ESYS_HarmoType_t; + + typedef unsigned short ESYS_Action_t; + + typedef unsigned short ESYS_Kit_t; + + typedef unsigned short ESYS_KitSelection_t; + + typedef unsigned short ESYS_ListToUpdate_t; + + typedef unsigned short ESYS_MFDModeAck_t; + + typedef unsigned short ESYS_MFDModeCmd_t; + + // Device concerned + typedef unsigned short ESYS_SlewingDevice_t; + + typedef unsigned short ESYS_TimeOrigin_t; + + typedef unsigned short ESYS_CrosshairXPos_t; + + typedef unsigned short ESYS_CrosshairYPos_t; + + // Déplace du réticule + struct TSYS_CrosshairPosition + { + // Déplacement en X + ESYS_CrosshairXPos_t m_unDeltaXPos; + // Déplacement en Y + ESYS_CrosshairYPos_t m_unDeltaYPos; + }; + + // Etat de la fenêtre de l'applicatif + struct SYS_ApplicationWindowState + { + // Nom de l'applicatif + IMV::TIMV_ApplicationIdentifier_t m_unApplicationID; + // Identifiant de l'opérateur (Chef Tireur Pilote etc.) + COM::ECOM_OperatorIdentifier_t m_unOperatorID; + // Position de la fenêtre (X Y) + COM::TCOM_AppPosition m_tApplicationPosition; + // Taille de la fenêtre (hauteur largeur) + COM::TCOM_AppSize m_tApplicationSize; + // Etat de la fenêtre de l'applicatif + ESYS_WindowState_t m_unWindowState; + // Le niveau du contexte IHM + stringSvCmdLine m_sContextLevel; + }; + #pragma keylist SYS_ApplicationWindowState m_unApplicationID + + // Demande blackoutt + struct SYS_BlackoutReq + { + // Identifiant de l'opérateur (Chef Tireur Pilote etc.) + COM::ECOM_OperatorIdentifier_t m_unOperatorID; + // Modes de discretion possibles (nominale réduite cachée) + ESYS_DiscretionMode_t m_unDiscretionModeReq; + // Origine de la demande (Mfd) + unsigned short m_unRequestorID; + // Activation ou non de l'occultation automatique sur ouverture de trappe + boolean m_bHideAuto; + }; + #pragma keylist SYS_BlackoutReq m_unOperatorID m_unDiscretionModeReq + + // Etat du blackoutt + struct SYS_BlackoutState + { + // Mode de discretion + ESYS_DiscretionMode_t m_unDiscretionMode; + // Source des modes de discretion (opérateur ouvrants) + ESYS_DiscretionSource_t m_unDiscretionSource; + }; + #pragma keylist SYS_BlackoutState m_unDiscretionMode + + // Etat d'activation des arrêts d'urgence + struct SYS_EmergencyStopState + { + // Identifiant de l'opérateur (Chef Tireur Pilote etc.) + COM::ECOM_OperatorIdentifier_t m_unOperatorID; + // Emergency stop type + ESYS_EmergencyStopType_t m_unEmergencyStop; + // Etat d'activation de l'arrêt d'urgence + COM::ECOM_ActivatedState_t m_unActivation; + }; + #pragma keylist SYS_EmergencyStopState m_unOperatorID m_unEmergencyStop + + // Déplacement du réticule de simbleautage + struct SYS_HarmoCrossMoveReq + { + // Identifiant de l'opérateur (Chef Tireur Pilote etc.) + COM::ECOM_OperatorIdentifier_t m_unOperatorID; + // Origine de la demande (Mfd) + unsigned short m_unRequestorID; + // Déplacement du réticule en X ou Y + TSYS_CrosshairPosition m_tDeltaPos; + }; + #pragma keylist SYS_HarmoCrossMoveReq m_unOperatorID + + // Requete sur la fonction simbleautage + struct SYS_HarmoFunctionReq + { + // Identifiant de l'opérateur (Chef Tireur Pilote etc.) + COM::ECOM_OperatorIdentifier_t m_unOperatorID; + // Origine de la demande (Mfd) + unsigned short m_unRequestorID; + // Phase courante du simbleautage + ESYS_HarmoPhases_t m_unCurrentPhase; + // Demandes opérateur (autorisation sortie) + COM::ECOM_OperatorRequest_t m_unRequest; + }; + #pragma keylist SYS_HarmoFunctionReq m_unOperatorID + + // Etat de la requete sur la fonction simbleautage + struct SYS_HarmoFunctionState + { + // Identifiant de l'opérateur (Chef Tireur Pilote etc.) + COM::ECOM_OperatorIdentifier_t m_unOperatorID; + // Etat système de la demande opérateur + COM::ECOM_AuthorizationBool_t m_unRequest; + }; + #pragma keylist SYS_HarmoFunctionState m_unOperatorID + + // Acquitement de la commande de phase de simbleautage + struct SYS_HarmoPhaseAck + { + // Identifiant de l'opérateur (Chef Tireur Pilote etc.) + COM::ECOM_OperatorIdentifier_t m_unOperatorID; + // Origine de la demande (Mfd) + unsigned short m_unRequestorID; + // Phase de simbleautage commandée par le LCCS + ESYS_HarmoPhases_t m_unPhase; + }; + #pragma keylist SYS_HarmoPhaseAck m_unOperatorID + + // Réception d'une commande de phase de simbleautage + struct SYS_HarmoPhaseCmd + { + // Identifiant de l'opérateur (Chef Tireur Pilote etc.) + COM::ECOM_OperatorIdentifier_t m_unOperatorID; + // Phase de simbleautage commandée par le LCCS + ESYS_HarmoPhases_t m_unPhase; + }; + #pragma keylist SYS_HarmoPhaseCmd m_unOperatorID + + // Sélection du type de simbleautage + struct SYS_HarmoSelectReq + { + // Identifiant de l'opérateur (Chef Tireur Pilote etc.) + COM::ECOM_OperatorIdentifier_t m_unOperatorID; + // Origine de la demande (Mfd) + unsigned short m_unRequestorID; + // Type de simbleautage + ESYS_HarmoType_t m_unType; + // Valeur de la distance du simbleautage terrain + unsigned short m_unDistance; + // Identificateur de viseur + COM::ECOM_SightType_t m_unSight; + // Identifiant de voie + COM::ECOM_VideoChannel_t m_unChannel; + // Identifiant de champ + COM::ECOM_VideoField_t m_unField; + }; + #pragma keylist SYS_HarmoSelectReq m_unOperatorID + + // Etat du type de simbleautage + struct SYS_HarmoSelectState + { + // Identifiant de l'opérateur (Chef Tireur Pilote etc.) + COM::ECOM_OperatorIdentifier_t m_unOperatorID; + // Type de simbleautage + ESYS_HarmoType_t m_unType; + // Valeur de la distance de simbleautage terrain forfaitaire + unsigned short m_unDefaultDistance; + // Valeur de la distance du simbleautage terrain + unsigned short m_unDistance; + // Identificateur de viseur + COM::ECOM_SightType_t m_unSight; + // Identifiant de voie + COM::ECOM_VideoChannel_t m_unChannel; + // Identifiant de champ + COM::ECOM_VideoField_t m_unField; + // Permet d'indiquer si la voir est une voie de référence ou non + boolean m_bRefChannelFlag; + }; + #pragma keylist SYS_HarmoSelectState m_unOperatorID + + // Selection des commande + struct SYS_HarmoSightActionReq + { + // Type de simbleautage + ESYS_HarmoType_t m_unType; + // Identificateur de viseur + COM::ECOM_SightType_t m_unSight; + // Identifiant de l'opérateur (Chef Tireur Pilote etc.) + COM::ECOM_OperatorIdentifier_t m_unOperatorID; + // Origine de la demande (Mfd) + unsigned short m_unRequestorID; + // Phase de simbleautage commandée par le LCCS + ESYS_HarmoPhases_t m_unCurrentPhase; + // Actions + ESYS_Action_t m_unAction; + }; + #pragma keylist SYS_HarmoSightActionReq m_unType m_unSight m_unOperatorID + + // Etat des commande + struct SYS_HarmoSightActionState + { + // Type de simbleautage + ESYS_HarmoType_t m_unType; + // Identificateur de viseur + COM::ECOM_SightType_t m_unSight; + // Identifiant de l'opérateur (Chef Tireur Pilote etc.) + COM::ECOM_OperatorIdentifier_t m_unOperatorID; + // Actions + ESYS_Action_t m_unAction; + }; + #pragma keylist SYS_HarmoSightActionState m_unType m_unSight m_unOperatorID + + // Etat de la position de la ligne de visée et offset du réticule + struct SYS_HarmoSightPosState + { + // Type de simbleautage + ESYS_HarmoType_t m_unType; + // Identificateur de viseur + COM::ECOM_SightType_t m_unSight; + // Identifiant de l'opérateur (Chef Tireur Pilote etc.) + COM::ECOM_OperatorIdentifier_t m_unOperatorID; + // Origine de la demande (Mfd) + unsigned short m_unRequestorID; + // Position en gisement du réticule + float m_fCrossOffsetAzimuth; + // Position en site du réticule + float m_fCrossOffsetElevation; + }; + #pragma keylist SYS_HarmoSightPosState m_unType m_unSight + + // Demande de sélection des kits + struct SYS_KitReq + { + // Identifiant de l'opérateur (Chef Tireur Pilote etc.) + COM::ECOM_OperatorIdentifier_t m_unOperatorID; + // Nom présence et état des kits + ESYS_Kit_t m_unKit; + // Origine de la demande (Mfd) + unsigned short m_unRequestorID; + // Selectino des kits active ou désactive + ESYS_KitSelection_t m_unKitAction; + }; + #pragma keylist SYS_KitReq m_unOperatorID m_unKit + + // Recense les kits et leurs états + struct SYS_KitState + { + // Clé par défaut + ESYS_Kit_t m_unKit; + // Nom présence et état des kits + COM::ECOM_HWPresence_t m_unPresence; + // Etat de l'activation de l'équipement + COM::ECOM_ActivatedState_t m_unActivation; + }; + #pragma keylist SYS_KitState m_unKit + + // Demande de mise à jour des fichiers + struct SYS_ListUpdateCmd + { + // Liste des fichiers à mettre à jour + ESYS_ListToUpdate_t m_unList; + }; + #pragma keylist SYS_ListUpdateCmd m_unList + + // Compte-rendu de mode de l'abonné MPC / MPT / MSC + struct SYS_MFDModeAck + { + // Identifiant de l'opérateur (Chef Tireur Pilote etc.) + COM::ECOM_OperatorIdentifier_t m_unOperatorID; + // La position du MFD + COM::ECOM_MFDPosition_t m_unMFDType; + // Acquittement de la commande de mode + ESYS_MFDModeAck_t m_unMode; + }; + #pragma keylist SYS_MFDModeAck m_unOperatorID m_unMFDType + + // Commande de mode de l'abonné MPC / MPT / MSC + struct SYS_MFDModeCmd + { + // Identifiant de l'opérateur (Chef Tireur Pilote etc.) + COM::ECOM_OperatorIdentifier_t m_unOperatorID; + // La position du MFD + COM::ECOM_MFDPosition_t m_unMFDType; + // Acquittement de la commande de mode + ESYS_MFDModeCmd_t m_unMode; + }; + #pragma keylist SYS_MFDModeCmd m_unOperatorID m_unMFDType + + // Langue utilisée + struct SYS_PresentationLanguage + { + // Identifiant du poste opérateur + COM::ECOM_OperatorIdentifier_t m_unOperatorID; + // Présentation de la charte IHM en fonction du découpage géographique + unsigned short m_unPresentation; + // Langue sélectionnée + COM::ECOM_Language_t m_unLanguage; + }; + #pragma keylist SYS_PresentationLanguage m_unOperatorID + + // Activation de la compensation de dérive de la stabilisation de la tourelle de 40mm par le chef / tireur + struct SYS_SightDerivCompActivReq + { + // Identificateur de viseur + COM::ECOM_SightType_t m_unSight; + // Identifiant de l'opérateur (Chef Tireur Pilote etc.) + COM::ECOM_OperatorIdentifier_t m_unOperatorID; + // Origine de la demande (Mfd) + unsigned short m_unRequestorID; + // Compensation de dérive commandée (vrai) / Non commandée + boolean m_bActivation; + }; + #pragma keylist SYS_SightDerivCompActivReq m_unSight m_unOperatorID + + // CR compensation de dérive de la tourelle de 40mm en cours + struct SYS_SightDerivCompActivState + { + // Identificateur de viseur + COM::ECOM_SightType_t m_unSight; + // Etat de la compensation de dérive + COM::ECOM_ActivatedState_t m_unProgress; + }; + #pragma keylist SYS_SightDerivCompActivState m_unSight + + // Prise en charge du viseur par l'opérateur + struct SYS_SightSelectReq + { + // Identificateur de viseur + COM::ECOM_SightType_t m_unSight; + // Identifiant de l'opérateur (Chef Tireur Pilote etc.) + COM::ECOM_OperatorIdentifier_t m_unOperatorID; + // Origine de la demande (Mfd) + unsigned short m_unRequestorID; + // Prise en charge (vrai) / Pas de prise en charge (faux) + boolean m_bPec; + }; + #pragma keylist SYS_SightSelectReq m_unSight m_unOperatorID + + // Demande d'activation de la stabilisation tourelle + struct SYS_SightStabActivReq + { + // Identificateur de viseur + COM::ECOM_SightType_t m_unSight; + // Identifiant de l'opérateur (Chef Tireur Pilote etc.) + COM::ECOM_OperatorIdentifier_t m_unOperatorID; + // Origine de la demande (Mfd) + unsigned short m_unRequestorID; + // Activation de la stabilisation activée (vrai) / Non activée (faux) + boolean m_bActivation; + }; + #pragma keylist SYS_SightStabActivReq m_unSight m_unOperatorID + + // Etat d'activation de la stabilisation tourelle + struct SYS_SightStabActivState + { + // Identificateur de viseur + COM::ECOM_SightType_t m_unSight; + // Etat d'activation de lla stabilisation tourelle + COM::ECOM_ActivatedState_t m_unActivation; + }; + #pragma keylist SYS_SightStabActivState m_unSight + + // Compte rendu d'état de la stabilisation tourelle + struct SYS_SightStabState + { + // Identificateur de viseur + COM::ECOM_SightType_t m_unSight; + // Etat de la stabilisation du viseur + COM::ECOM_FunctionState_t m_unState; + }; + #pragma keylist SYS_SightStabState m_unSight + + // Demande de ralliement par le chef / tireur + struct SYS_SlewingReq + { + // Dispositif concerné / moyen piloté + ESYS_SlewingDevice_t m_unDevice; + // Identificateur d'opérateur + COM::ECOM_OperatorIdentifier_t m_unOperatorID; + // Demande activée (vrai) / désactivé (faux) + boolean m_bActivation; + // Nom de l'applicatif demandeur + IMV::TIMV_ApplicationIdentifier_t m_unApplicationID; + // Type de direction à rallier + COM::ECOM_SlewingDirection_t m_unDirection; + // Clef de l'instance du topic décrivant la direction à rallier (topic selon valeur de m_unDirection) / Dans le cas des episcopes m_unDirectionInfoKey indique le numéro d'épiscope comme direction à rallier + unsigned short m_unDirectionInfoKey; + // Opérateur dont la voie affiché est à rallier dans le cas où m_unDirectionInfoKey = eunESYS_SlewDir_Operator + COM::ECOM_OperatorIdentifier_t m_unDirectionOperatorID; + // Champ utilisé dans le cas ou m_unDirection = viseur. Sinon m_unSight = Undefined + COM::ECOM_SightType_t m_unSight; + }; + #pragma keylist SYS_SlewingReq m_unDevice m_unOperatorID + + // Date / Heure applicative + struct SYS_SystemApplicativeTime + { + // Clé par défaut + unsigned short m_unKey; + // Date/Heure en secondes + long long m_lSeconds; + long m_lNanoseconds; + // Origine de l'heure système + ESYS_TimeOrigin_t m_unOrigin; + }; + #pragma keylist SYS_SystemApplicativeTime m_unKey + + // Date/Heure système automatique rempnté par les sources + struct SYS_SystemAutoTimeState + { + // Clé par défaut + unsigned short m_unKey; + // Date/Heure en secondes independante du Fuseau + long long m_lSeconds; + // Choix de la source DH automatique + boolean m_bAutomaticChoice; + // Origine de l'heure système + ESYS_TimeOrigin_t m_unOrigin; + }; + #pragma keylist SYS_SystemAutoTimeState m_unKey + + // Fuseau date/Heure système + struct SYS_SystemTimeZoneState + { + // Clé par défaut + unsigned short m_unKey; + // Signe de l'offset + short m_nOffsetSign; + // Valeur de l'heure d'offset + unsigned short m_unOffsetHour; + // Valeur des minutes d'offset + unsigned short m_unOffsetMinute; + // Lettre code du fuseau + char m_cTZCode; + }; + #pragma keylist SYS_SystemTimeZoneState m_unKey + }; + + module ALT + { + + typedef unsigned short EALT_AlertLevel_t; + + // Alert type + typedef unsigned short EALT_AlertType_t; + + // Acquittement de l'alerte par l'opérateur + struct ALT_AlertAlarmAck + { + // Identifiant de l'opérateur (Chef Tireur Pilote etc.) + COM::ECOM_OperatorIdentifier_t m_unOperatorID; + // Identifiant de l'alarme / alerte + unsigned short m_unAlertID; + // Reponse dans le cas d'une alarme / alerte sous forme d'une question + COM::ECOM_ResponseButton_t m_unResponse; + }; + #pragma keylist ALT_AlertAlarmAck m_unOperatorID m_unAlertID + + // Etat de l'alarme / alerte + struct ALT_AlertAlarmState + { + // Identifiant de l'alarme / alerte + unsigned short m_unAlertID; + // Datation de l'occurrence de l'alarme / alerte (en secondes) + long m_lDatation; + // Etat de l'alerte + COM::ECOM_AlertState_t m_unAlertState; + }; + #pragma keylist ALT_AlertAlarmState m_unAlertID + + // Informations sur l'alerte + struct ALT_AlertInformations + { + // Identifiant de l'opérateur (Chef Tireur Pilote etc.) + COM::ECOM_OperatorIdentifier_t m_unOperatorID; + // Identifiant de l'alerte + unsigned short m_unAlertID; + // Niveau de l'alerte + EALT_AlertLevel_t m_unType; + // Type de l'alerte + EALT_AlertType_t m_unAlertMaxType; + // Précise s'il s'agit d'un début ou fin d'alerte + COM::ECOM_AlertState_t m_unStartEnd; + // Libellé de l'alerte / Alarme + string50 m_sTexte1; + // Conduite à tenir + string1000 m_sTexte2; + // Sous composants et sous fonctions impactés + COM::ECOM_SubComponents_t m_unSubComponentID; + // Composants des fonctions état système impactés + COM::ECOM_SystemComponents_t m_unComponentID; + }; + #pragma keylist ALT_AlertInformations m_unOperatorID m_unAlertID + }; + + module NAV + { + + // Sens de direction du porteur + struct TNAV_GeoAngularDirection + { + // cap + float m_fHeading; + // azimut + float m_fGeoAzimut; + // elevation + float m_fGeoElevation; + }; + + // Etat de l'orientation du porteur + struct NAV_CarrierOrientationState + { + // Identifiant du porteur : porteur principal porteur secondaire (robot) … + COM::ECOM_CarrierType_t m_unCarrierType; + // Sens de direction du porteur + TNAV_GeoAngularDirection m_tOrientation; + }; + #pragma keylist NAV_CarrierOrientationState m_unCarrierType + }; + + module AGR + { + + typedef unsigned short EAGR_AHSIdentifier_t; + + // Activation demande of a AHS function + typedef unsigned short EAGR_AHSFunction_t; + + // AHS state + typedef unsigned short EAGR_AHSLoadState_t; + + typedef unsigned short EAGR_AHSZoneIdentifier_t; + + // State of the AHS (CTWS) + typedef unsigned short EAGR_AHSState_t; + + typedef unsigned short EAGR_AirburstFiringMode_t; + + typedef unsigned short EAGR_AirburstFiringPoint_t; + + typedef unsigned short EAGR_AtmoHumidity_t; + + typedef unsigned short AGR_TemplateType_t; + + // Identificateur de zone + struct TAGR_AHSZone + { + // Identificateur de zone + EAGR_AHSZoneIdentifier_t m_unZoneID; + // Nombre de munitions dans la zone du carrosuel + unsigned short m_unNbAmmunition; + // Nombre d'alvéoles + unsigned short m_unNbAlveolus; + // Type de munitions de l'arme principale + COM::ECOM_AmmunitionType_t m_unAmmunition; + }; + + // Données de configuration des zones + struct TAGR_AHSZoneTab + { + // Nombre de zones configurées dans le magasin + unsigned short m_unCurrentSize; + // Données de configuration des zones + TAGR_AHSZone m_atZoneConfig[c_NbZoneMax]; + }; + + // Configurations des paramètres aérologiques + struct AGR_AeroParamReq + { + // Identifiant de l'opérateur (Chef Tireur Pilote etc.) + COM::ECOM_OperatorIdentifier_t m_unOperatorID; + // Origine de la demande (Mfd) + unsigned short m_unRequestorID; + // Mode d'acquisition de la vitesse du vent + COM::ECOM_AutoManuMode_t m_unWindMode; + // Valeur de la vitesse du vent + float m_fWindSpeedValue; + // Valeur de la direction du vent + float m_fWindDirectionValue; + }; + #pragma keylist AGR_AeroParamReq m_unOperatorID + + // Etat des paramètres aérologiques + struct AGR_AeroParamState + { + // Clé par défaut + unsigned short m_unKey; + // Mode d'acquisition de la vitesse du vent + COM::ECOM_AutoManuMode_t m_unWindMode; + // Valeur de la vitesse du vent + float m_fWindSpeedValue; + // Mode d'acquisition de la direction du vent + COM::ECOM_AutoManuMode_t m_unWindDirectionMode; + // Valeur de la direction du vent + float m_fWindDirectionValue; + }; + #pragma keylist AGR_AeroParamState m_unKey + + // Menu de configuration AHS + struct AGR_AHSConfigReq + { + // Type d'arme + COM::ECOM_WeaponType_t m_unWeapon; + // Identifiant de caroussel + EAGR_AHSIdentifier_t m_unAHSID; + // Identifiant de l'opérateur (Chef Tireur Pilote etc.) + COM::ECOM_OperatorIdentifier_t m_unOperatorID; + // Origine de la demande (Mfd) + unsigned short m_unRequestorID; + // Données de configuration des zones + TAGR_AHSZoneTab m_aZoneConfig; + }; + #pragma keylist AGR_AHSConfigReq m_unWeapon m_unAHSID m_unOperatorID + + // Actualisation du menu de coufiguration des carrousels + struct AGR_AHSConfigState + { + // Type d'arme + COM::ECOM_WeaponType_t m_unWeapon; + // Identifiant de caroussel + EAGR_AHSIdentifier_t m_unAHSID; + // Données de configuration des zones + TAGR_AHSZoneTab m_aZoneConfig; + }; + #pragma keylist AGR_AHSConfigState m_unWeapon m_unAHSID + + // Etat du calculateur du système d'arme du carrousel + struct AGR_AHSCTASCState + { + // Type d'arme + COM::ECOM_WeaponType_t m_unWeapon; + // Identifiant de caroussel + EAGR_AHSIdentifier_t m_unAHSID; + // Etat du tiroir de l'AHS + COM::ECOM_OpeningState_t m_unDrawerState; + // Etat de verrouillage du tiroir + COM::ECOM_LockingState_t m_unDrawerLockState; + // Code d'erreur du CTASC + COM::ECOM_CTASCErrorCode_t m_unErrorCode; + // Numéro d'alvéole présente à la position n°1 de l'AHS + unsigned short m_unFirstAveolusNumber; + // Nombre d'alvéoles restant à traiter + unsigned short m_unNbRemainingAlveolus; + }; + #pragma keylist AGR_AHSCTASCState m_unWeapon m_unAHSID + + // Commande de la zone du carrousel X prédisposé pour le tir par le chef / tireur + struct AGR_AHSFiringReq + { + // Type d'arme + COM::ECOM_WeaponType_t m_unWeapon; + // Identifiant de caroussel + EAGR_AHSIdentifier_t m_unAHSID; + // Type de munition sélectionnée par l'opérateur + COM::ECOM_AmmunitionType_t m_unAmmunition; + // Identifiant de l'opérateur (Chef Tireur Pilote etc.) + COM::ECOM_OperatorIdentifier_t m_unOperatorID; + // Origine de la demande (Mfd) + unsigned short m_unRequestorID; + // Longueur de rafale selectionnée par l'opérateur + unsigned short m_unBurstLong; + }; + #pragma keylist AGR_AHSFiringReq m_unWeapon m_unAHSID + + // Etat de tir des carrousels + struct AGR_AHSFiringState + { + // Type d'arme + COM::ECOM_WeaponType_t m_unWeapon; + // Identifiant de carrousel + EAGR_AHSIdentifier_t m_unAHSID; + // Type de munition sélectionnée par le système + COM::ECOM_AmmunitionType_t m_unAmmunition; + // Longueur de rafale selectionnée par le système + unsigned short m_unBurstLong; + // Longueur de rafale selectionnée faisable (vrai) / non faisable (faux) + boolean m_bBurstFeasible; + }; + #pragma keylist AGR_AHSFiringState m_unWeapon m_unAHSID + + // Signal de demande de configuration des magasins en type et nombre de munitions + struct AGR_AHSFunctionReq + { + // Type d'arme + COM::ECOM_WeaponType_t m_unWeapon; + // Identifiant de caroussel + EAGR_AHSIdentifier_t m_unAHSID; + // Identifiant de l'opérateur (Chef Tireur Pilote etc.) + COM::ECOM_OperatorIdentifier_t m_unOperatorID; + // Origine de la demande (MFD) + unsigned short m_unRequestorID; + // Demande d'activation d'une fonction carrousel + EAGR_AHSFunction_t m_unFunction; + }; + #pragma keylist AGR_AHSFunctionReq m_unWeapon m_unAHSID m_unOperatorID + + // Compte rendu de configuration des magasins en type et nombre de munitions + struct AGR_AHSFunctionState + { + // Type d'arme + COM::ECOM_WeaponType_t m_unWeapon; + // Identifiant de caroussel + EAGR_AHSIdentifier_t m_unAHSID; + // Demande d'activation d'une fonction carrousel + EAGR_AHSFunction_t m_unFunction; + }; + #pragma keylist AGR_AHSFunctionState m_unWeapon m_unAHSID + + // Etat de configuration des carrousels + struct AGR_AHSLoadConfigState + { + // Type d'arme + COM::ECOM_WeaponType_t m_unWeapon; + // Identifiant de caroussel + EAGR_AHSIdentifier_t m_unAHSID; + // Données de chargement/déchargement des zones + TAGR_AHSZoneTab m_aZoneConfigList; + // Etat du carroussel + EAGR_AHSLoadState_t m_unAHSState; + }; + #pragma keylist AGR_AHSLoadConfigState m_unWeapon m_unAHSID + + // Demande de chargement de munitions dans le carrousel + struct AGR_AHSLoadingReq + { + // Type d'arme + COM::ECOM_WeaponType_t m_unWeapon; + // Identifiant de caroussel + EAGR_AHSIdentifier_t m_unAHSID; + // Identifiant de l'opérateur (Chef Tireur Pilote etc.) + COM::ECOM_OperatorIdentifier_t m_unOperatorID; + // Origine de la demande (Mfd) + unsigned short m_unRequestorID; + // Zone à prédisposer au tir + EAGR_AHSZoneIdentifier_t m_unZoneID; + // Type de munition + COM::ECOM_AmmunitionType_t m_unAmmunition; + }; + #pragma keylist AGR_AHSLoadingReq m_unWeapon m_unAHSID m_unOperatorID + + // Etat de la demande de chargement de munitions dans le carrousel + struct AGR_AHSLoadingState + { + // Type d'arme + COM::ECOM_WeaponType_t m_unWeapon; + // Identifiant de caroussel + EAGR_AHSIdentifier_t m_unAHSID; + // Zone à prédisposer au tir + EAGR_AHSZoneIdentifier_t m_unZoneID; + // Type de munition + COM::ECOM_AmmunitionType_t m_unAmmunition; + }; + #pragma keylist AGR_AHSLoadingState m_unWeapon m_unAHSID + + // Demande de passage à l'alvéole suivante + struct AGR_AHSNextAlveolusReq + { + // Type d'arme + COM::ECOM_WeaponType_t m_unWeapon; + // Identifiant de caroussel + EAGR_AHSIdentifier_t m_unAHSID; + // Identifiant de l'opérateur (Chef Tireur Pilote etc.) + COM::ECOM_OperatorIdentifier_t m_unOperatorID; + // Origine de la demande (Mfd) + unsigned short m_unRequestorID; + }; + #pragma keylist AGR_AHSNextAlveolusReq m_unWeapon m_unAHSID m_unOperatorID + + // Etat de passage à l'alvéole suivante + struct AGR_AHSNextAlveolusState + { + // Type d'arme + COM::ECOM_WeaponType_t m_unWeapon; + // Identifiant de caroussel + EAGR_AHSIdentifier_t m_unAHSID; + }; + #pragma keylist AGR_AHSNextAlveolusState m_unWeapon m_unAHSID + + // Demande d'infos sur le paramétrage du carrousel + struct AGR_AHSParamReq + { + // Type d'arme + COM::ECOM_WeaponType_t m_unWeapon; + // Identifiant de caroussel + EAGR_AHSIdentifier_t m_unAHSID; + // Identifiant de l'opérateur (Chef Tireur Pilote etc.) + COM::ECOM_OperatorIdentifier_t m_unOperatorID; + // Origine de la demande (Mfd) + unsigned short m_unRequestorID; + }; + #pragma keylist AGR_AHSParamReq m_unWeapon m_unAHSID m_unOperatorID + + // Etat du paramétrage du carrousel + struct AGR_AHSParamState + { + // Type d'arme + COM::ECOM_WeaponType_t m_unWeapon; + // Identifiant de caroussel + EAGR_AHSIdentifier_t m_unAHSID; + // Nombre max de zones dans le carrousel + unsigned short m_unNbMaxZone; + // Nombre max d'alvéoles dans le carrousel + unsigned short m_unNbMaxAlveolus; + }; + #pragma keylist AGR_AHSParamState m_unWeapon m_unAHSID + + // Etat des carrrousels + struct AGR_AHSState + { + // Type d'arme + COM::ECOM_WeaponType_t m_unWeapon; + // Identifiant de caroussel + EAGR_AHSIdentifier_t m_unAHSID; + // Etat du carrousel + EAGR_AHSState_t m_unAHSState; + }; + #pragma keylist AGR_AHSState m_unWeapon m_unAHSID + + // Demande de zone correspondante au carrousel + struct AGR_AHSZoneReq + { + // Type d'arme + COM::ECOM_WeaponType_t m_unWeapon; + // Identifiant de caroussel + EAGR_AHSIdentifier_t m_unAHSID; + // Identifiant de l'opérateur (Chef Tireur Pilote etc.) + COM::ECOM_OperatorIdentifier_t m_unOperatorID; + // Origine de la demande (Mfd) + unsigned short m_unRequestorID; + // Zone à prédisposer au tir + EAGR_AHSZoneIdentifier_t m_unZoneID; + }; + #pragma keylist AGR_AHSZoneReq m_unWeapon m_unAHSID m_unOperatorID + + // Etat de la zone correspondante au carrousel + struct AGR_AHSZoneState + { + // Type d'arme + COM::ECOM_WeaponType_t m_unWeapon; + // Identifiant de caroussel + EAGR_AHSIdentifier_t m_unAHSID; + // Zone à prédisposer au tir + EAGR_AHSZoneIdentifier_t m_unZoneID; + // Etat de l'accès à la zone + COM::ECOM_ActivatedState_t m_unActivation; + }; + #pragma keylist AGR_AHSZoneState m_unWeapon m_unAHSID + + // Requête de configuration airbusrt + struct AGR_AirburstConfigReq + { + // Identifiant de l'opérateur (Chef Tireur Pilote etc.) + COM::ECOM_OperatorIdentifier_t m_unOperatorID; + // Origine de la demande (Mfd) + unsigned short m_unRequestorID; + // Mode de tir airburst sélectionné + EAGR_AirburstFiringMode_t m_unAirburstFiringModeSel; + // Dépointage du tir airburst par rapport au point visé + EAGR_AirburstFiringPoint_t m_unAirburstFiringPoint; + }; + #pragma keylist AGR_AirburstConfigReq m_unOperatorID + + // Etat de la configuration airburst + struct AGR_AirburstConfigState + { + // Clé par défaut + unsigned short m_unKey; + // Mode de tir airburst validé + EAGR_AirburstFiringMode_t m_unAirburstFiringMode; + // Mode de tir airburst slectionné + EAGR_AirburstFiringMode_t m_unAirburstFiringModeSel; + // Dépointage du tir airburst par rapport au point visé + EAGR_AirburstFiringPoint_t m_unAirburstFiringPoint; + }; + #pragma keylist AGR_AirburstConfigState m_unKey + + // Offset de portée de tir + struct AGR_AirburstOffsetReq + { + // Identifiant de l'opérateur (Chef Tireur Pilote etc.) + COM::ECOM_OperatorIdentifier_t m_unOperatorID; + // Origine de la demande (Mfd) + unsigned short m_unRequestorID; + // Offset de tir airburst + short m_nAirburstOffset; + }; + #pragma keylist AGR_AirburstOffsetReq m_unOperatorID + + // Offset de portée de tir + struct AGR_AirburstOffsetState + { + // Clé par défaut + unsigned short m_unKey; + // Offset de portée de tir Airburst (domaine de valeur +/- 30m) + short m_nAirburstOffset; + }; + #pragma keylist AGR_AirburstOffsetState m_unKey + + // Validation télémétrie + struct AGR_AirburstTelemReq + { + // Identifiant de l'opérateur (Chef Tireur Pilote etc.) + COM::ECOM_OperatorIdentifier_t m_unOperatorID; + // Origine de la demande (Mfd) + unsigned short m_unRequestorID; + // Validation télémétrie + boolean m_bAirburstValidTelem; + }; + #pragma keylist AGR_AirburstTelemReq m_unOperatorID + + // Validation télémétrie + struct AGR_AirburstTelemState + { + // Clé par défaut + unsigned short m_unKey; + // Télémétrie airburst validée (vrai) / non validée (faux) + boolean m_bAirburstValidTelem; + }; + #pragma keylist AGR_AirburstTelemState m_unKey + + // Configuration des paramètres de tir + struct AGR_AmmunitionParamReq + { + // Identifiant de l'opérateur (Chef Tireur Pilote etc.) + COM::ECOM_OperatorIdentifier_t m_unOperatorID; + // Origine de la demande (Mfd) + unsigned short m_unRequestorID; + // Mode d'asquisition de la température de poudre + COM::ECOM_AutoManuMode_t m_unPowderTempMode; + // Valeur de la température de poudre + float m_fPowderTempValue; + // Mode d'acquisition de l'écart V0 + COM::ECOM_AutoManuMode_t m_unV0DeltaMode; + // Valeur de l'écart V0 + float m_fV0DeltaValue; + }; + #pragma keylist AGR_AmmunitionParamReq m_unOperatorID + + // Etat des paramètres de tir + struct AGR_AmmunitionParamState + { + // Clé par défaut + unsigned short m_unKey; + // Mode d'asquisition de la température de poudre + COM::ECOM_AutoManuMode_t m_unPowderTempMode; + // Valeur de la température de poudre + float m_fPowderTempValue; + // Mode d'acquisition de l'écart V0 + COM::ECOM_AutoManuMode_t m_unV0DeltaMode; + // Valeur de l'écart V0 + float m_fV0DeltaValue; + }; + #pragma keylist AGR_AmmunitionParamState m_unKey + + // Configuration des paramètres atmosphériques + struct AGR_AtmoParamReq + { + // Identifiant de l'opérateur (Chef Tireur Pilote etc.) + COM::ECOM_OperatorIdentifier_t m_unOperatorID; + // Origine de la demande (Mfd) + unsigned short m_unRequestorID; + // Mode d'acquisition de l'humidité atmosphérique + SYS::ESYS_TimeMode_t m_unAtmoHumidityMode; + // Valeur de l'humidité atmosphérique + EAGR_AtmoHumidity_t m_unAtmoHumidityValue; + // Mode d'acquisition de la pression atmosphérique + SYS::ESYS_TimeMode_t m_unAtmoPressureMode; + // Valeur de la pression atmosphérique + float m_fAtmoPressureValue; + // Mode d'acquisition de la température d'air extérieur + SYS::ESYS_TimeMode_t m_unAirExtTempMode; + // Valeur de la température d'air extérieure + float m_fAirExtTempValue; + }; + #pragma keylist AGR_AtmoParamReq m_unOperatorID + + // Etat des paramètres atmosphériques + struct AGR_AtmoParamState + { + // Clé par défaut + unsigned short m_unKey; + // Mode d'acquisition de l'humidité atmosphérique + SYS::ESYS_TimeMode_t m_unAtmoHumidityMode; + // Valeur de l'humidité atmosphérique + EAGR_AtmoHumidity_t m_unAtmoHumidityValue; + // Mode d'acquisition de la pression atmosphérique + SYS::ESYS_TimeMode_t m_unAtmoPressureMode; + // Valeur de la pression atmosphérique + float m_fAtmoPressureValue; + // Mode d'acquisition de la température d'air extérieur + SYS::ESYS_TimeMode_t m_unAirExtTempMode; + // Valeur de la température d'air extérieure + float m_fAirExtTempValue; + }; + #pragma keylist AGR_AtmoParamState m_unKey + + // Bargraphe d'acquisition de cible + struct AGR_BargraphState + { + // Type d'arme + COM::ECOM_WeaponType_t m_unWeapon; + // Histogramme temps de ralliement + COM::ECOM_BargraphType_t m_unBargraph; + }; + #pragma keylist AGR_BargraphState m_unWeapon + + // Requête d'activation fin de bande + struct AGR_CartridgeBeltEndOfBandReq + { + // Type d'arme + COM::ECOM_WeaponType_t m_unWeapon; + // Identifiant de l'opérateur (Chef Tireur Pilote etc.) + COM::ECOM_OperatorIdentifier_t m_unOperatorID; + // Origine de la demande (Mfd) + unsigned short m_unRequestorID; + // Demande d'activation (vrai) / désactivation (faux) de fin de bande + boolean m_bEndOfBandActivated; + }; + #pragma keylist AGR_CartridgeBeltEndOfBandReq m_unWeapon m_unOperatorID + + // CR d'activation de la gestion de fin de bande du tourelleau 7.62 + struct AGR_CartridgeBeltEndOfBandState + { + // Type d'arme + COM::ECOM_WeaponType_t m_unWeapon; + // Etat d'activation de la demande de fin de bande + COM::ECOM_ActivatedState_t m_unActivation; + }; + #pragma keylist AGR_CartridgeBeltEndOfBandState m_unWeapon + + // Demande de chargement de la ceinture de cartouche + struct AGR_CartridgeBeltLoadingReq + { + // Identifiant de l'opérateur (Chef Tireur Pilote etc.) + COM::ECOM_OperatorIdentifier_t m_unOperatorID; + // Type d'arme + COM::ECOM_WeaponType_t m_unWeapon; + // Origine de la demande (Mfd) + unsigned short m_unRequestorID; + // Demande d'activation (vrai) / de désactivation (faux) de l'opération de chargement de la bande par l'opérateur + boolean m_bActivation; + }; + #pragma keylist AGR_CartridgeBeltLoadingReq m_unOperatorID m_unWeapon + + // Etat de la mise à jour du nombre de coups + struct AGR_CartridgeBeltLoadingState + { + // Type d'arme + COM::ECOM_WeaponType_t m_unWeapon; + // Etat système de la demande d'activation + COM::ECOM_ActivatedState_t m_unActivation; + }; + #pragma keylist AGR_CartridgeBeltLoadingState m_unWeapon + + // Information sur les limites de gabarits + struct AGR_FiringTemplateState + { + // Identifiant de l'opérateur (Chef Tireur Pilote etc.) + COM::ECOM_OperatorIdentifier_t m_unOperatorID; + // Type de limite de gabarit + AGR_TemplateType_t m_unType; + // Hauteur en pixel du gabarit + unsigned short m_unPosition; + }; + #pragma keylist AGR_FiringTemplateState m_unOperatorID + + // Etat des munitions + struct AGR_FiringWeaponAmmunitionState + { + // Weapon type + COM::ECOM_WeaponType_t m_unWeapon; + // Type de munition + COM::ECOM_AmmunitionType_t m_unAmmunition; + // Remaning shots + unsigned short m_unNbRemaningShots; + // à utilisé par l'arme 7.62 + boolean m_bEndOfBandReached; + // Incident de gestion de fin de bande pour l'arme secondaire + boolean m_bEndOfBandFault; + }; + #pragma keylist AGR_FiringWeaponAmmunitionState m_unWeapon m_unAmmunition + + // Etat des armes + struct AGR_FiringWeaponState + { + // Weapon type + COM::ECOM_WeaponType_t m_unWeapon; + // Fenêtre de tir (Tir prêt engagé réalisé) + COM::ECOM_FiringWindow_t m_unFiringWindow; + // appliqué à la 7.62 / Arme non enrayée (faux) ou enrayée (vrai) + boolean m_bWeaponBloked; + // Tir dégradé + boolean m_bDegradedFiring; + }; + #pragma keylist AGR_FiringWeaponState m_unWeapon + + // Configuration des paramètres géographiques + struct AGR_GeoParamReq + { + // Identifiant de l'opérateur (Chef Tireur Pilote etc.) + COM::ECOM_OperatorIdentifier_t m_unOperatorID; + // Origine de la demande (Mfd) + unsigned short m_unRequestorID; + // Mode d'acquisition de latitude + SYS::ESYS_TimeMode_t m_unLatitudeMode; + // Valeur manuelle de la latitude + float m_fLatitudeValue; + }; + #pragma keylist AGR_GeoParamReq m_unOperatorID + + // Etat des paramètres géographiques + struct AGR_GeoParamState + { + // Clé par défaut + unsigned short m_unKey; + // Mode d'acquisition de latitude + SYS::ESYS_TimeMode_t m_unLatitudeMode; + // Valeur de la latitude + float m_fLatitudeValue; + }; + #pragma keylist AGR_GeoParamState m_unKey + + // Demande d'activation de la fonction PAC pour l'arme 40mm au poste chef / tireur + struct AGR_PACActivationReq + { + // Identificateur de viseur de tir + COM::ECOM_SightType_t m_unSight; + // Identifiant de l'opérateur (Chef Tireur Pilote etc.) + COM::ECOM_OperatorIdentifier_t m_unOperatorID; + // Origine de la demande (Mfd) + unsigned short m_unRequestorID; + // Demande PAC Activée (Vrai) / PAC Désactivée (Faux) + boolean m_bActivation; + }; + #pragma keylist AGR_PACActivationReq m_unSight m_unOperatorID + + // Etat d'activation de la fonction PAC pour l'arme 40mm au poste chef / tireur + struct AGR_PACActivationState + { + // Identifiant de l'opérateur (Chef Tireur Pilote etc.) + COM::ECOM_OperatorIdentifier_t m_unOperatorID; + // Identificateur de viseur + COM::ECOM_SightType_t m_unSight; + // Etat d'activation de la fonction PAC + COM::ECOM_ActivatedState_t m_unActivation; + }; + #pragma keylist AGR_PACActivationState m_unOperatorID m_unSight + + // Etat du verrouillage de la PAC + struct AGR_PACLockedState + { + // Identificateur de viseur + COM::ECOM_SightType_t m_unSight; + // Type d'arme + COM::ECOM_WeaponType_t m_unWeapon; + // Etat du verrouillage + COM::ECOM_LockingState_t m_unState; + }; + #pragma keylist AGR_PACLockedState m_unSight + + // Information de l'arme principale sélectionnée + struct AGR_SelectedMainWeapon + { + // Clé par défaut + unsigned short m_unKey; + // Arme principale sélectionnée + COM::ECOM_WeaponType_t m_unWeapon; + }; + #pragma keylist AGR_SelectedMainWeapon m_unKey + + // Etat d'activation de la sélection de l'arme + struct AGR_SelectedWeaponState + { + // Identifiant de l'opérateur (Chef Tireur Pilote etc.) + COM::ECOM_OperatorIdentifier_t m_unOperatorID; + // Identificateur d'arme + COM::ECOM_WeaponType_t m_unWeapon; + // Etat système de l'activation + COM::ECOM_ActivatedState_t m_unActivation; + }; + #pragma keylist AGR_SelectedWeaponState m_unOperatorID m_unWeapon + + // Etat des autorisations de tir et pointage + struct AGR_WeaponAuthorizationState + { + // Identificateur d'arme + COM::ECOM_WeaponType_t m_unWeapon; + // Pointage interdit (faux) / autorisé (vrai) + boolean m_bAimingAuthorizationState; + // Tir interdit (faux) / autorisé (vrai) + boolean m_bFiringAuthorizationState; + }; + #pragma keylist AGR_WeaponAuthorizationState m_unWeapon + + // Requête de modification du nombre de coups + struct AGR_WeaponNbShotModifyReq + { + // Identifiant de l'opérateur (Chef Tireur Pilote etc.) + COM::ECOM_OperatorIdentifier_t m_unOperatorID; + // Type d'arme + COM::ECOM_WeaponType_t m_unWeapon; + // Origine de la demande (Mfd) + unsigned short m_unRequestorID; + // Nombre de munitions système + unsigned short m_unNbAmmunition; + }; + #pragma keylist AGR_WeaponNbShotModifyReq m_unOperatorID m_unWeapon + + // Etat de la modification du nombre de coups + struct AGR_WeaponNbShotModifyState + { + // Type d'arme + COM::ECOM_WeaponType_t m_unWeapon; + // Nombre de munitions système + unsigned short m_unNbAmmunition; + }; + #pragma keylist AGR_WeaponNbShotModifyState m_unWeapon + }; + + module OBS + { + + typedef unsigned short EOBS_EchoType_t; + + typedef unsigned short EOBS_DistanceMeasureMode_t; + + // Video Equipment started / stopped by IHM + typedef unsigned short EOBS_VideoEquiActiv_t; + + typedef unsigned short EOBS_VideoConfMode_t; + + typedef unsigned short EOBS_VideoFocusState_t; + + typedef unsigned short EOBS_VideoGainState_t; + + typedef unsigned short EOBS_VideoCalibState_t; + + // Video equipment + typedef unsigned short EOBS_VideoSensor_t; + + // Video mode + typedef unsigned short EOBS_VideoMode_t; + + // Demande de nettoyage des viseurs par les operateurs + struct OBS_CleaningReq + { + // Identificateur de viseur de tir + COM::ECOM_SightType_t m_unSight; + // Identifiant de l'opérateur (Chef Tireur Pilote etc.) + COM::ECOM_OperatorIdentifier_t m_unOperatorID; + // Origine de la demande (Mfd) + unsigned short m_unRequestorID; + // Nettoyage des viseur activé (vrai) / Non activé (faux) + boolean m_bActivation; + }; + #pragma keylist OBS_CleaningReq m_unSight m_unOperatorID + + // Etat du nettoyage des viseurs + struct OBS_CleaningState + { + // Identificateur de viseur de tir + COM::ECOM_SightType_t m_unSight; + // Etat d'activation de ldu nettoyage des viseurs + COM::ECOM_ActivatedState_t m_unActivation; + }; + #pragma keylist OBS_CleaningState m_unSight + + // Demande de changement des reticules + struct OBS_CrosshairReq + { + // Identifiant de l'opérateur (Chef Tireur Pilote etc.) + COM::ECOM_OperatorIdentifier_t m_unOperatorID; + // Etat système de la couleur sélectionnée + unsigned short m_unColor; + // Origine de la demande + unsigned short m_unRequestorID; + }; + #pragma keylist OBS_CrosshairReq m_unOperatorID + + // Etat des reticules + struct OBS_CrosshairState + { + // Identifiant de l'opérateur (Chef Tireur Pilote etc.) + COM::ECOM_OperatorIdentifier_t m_unOperatorID; + // Etat système de la couleur sélectionnée + unsigned short m_unColor; + }; + #pragma keylist OBS_CrosshairState m_unOperatorID + + // Demande de degivrage + struct OBS_DefrostReq + { + // Identificateur de viseur de tir + COM::ECOM_SightType_t m_unSight; + // Identifiant de l'opérateur (Chef Tireur Pilote etc.) + COM::ECOM_OperatorIdentifier_t m_unOperatorID; + // Origine de la demande (Mfd) + unsigned short m_unRequestorID; + // Activation du dégivrage activée (vrai) / Non activée (faux) + boolean m_bActivation; + }; + #pragma keylist OBS_DefrostReq m_unSight m_unOperatorID + + // Etat degivrage + struct OBS_DefrostState + { + // Identificateur de viseur de tir + COM::ECOM_SightType_t m_unSight; + // Etat système de la demande d'activation + COM::ECOM_ActivatedState_t m_unActivation; + }; + #pragma keylist OBS_DefrostState m_unSight + + // Demande de détection des viseurs + struct OBS_DetectionReq + { + // Identificateur de viseur de tir + COM::ECOM_SightType_t m_unSight; + // Identifiant de l'opérateur (Chef Tireur Pilote etc.) + COM::ECOM_OperatorIdentifier_t m_unOperatorID; + // Origine de la demande (Mfd) + unsigned short m_unRequestorID; + // Detection activée (vrai) / Non activée (faux) + boolean m_bActivation; + }; + #pragma keylist OBS_DetectionReq m_unSight m_unOperatorID + + // Etat de la détection des viseurs + struct OBS_DetectionState + { + // Identificateur de viseur de tir + COM::ECOM_SightType_t m_unSight; + // Etat d'activation de la détection des viseurs + COM::ECOM_ActivatedState_t m_unActivation; + }; + #pragma keylist OBS_DetectionState m_unSight + + // Commande d'affichage de l'échelle des échos + struct OBS_EchoDisplayCmd + { + // Type d'arme + COM::ECOM_WeaponType_t m_unWeapon; + // Commande d'affichage de l'échelle des échos et de l'offset de distance activé (vrai) + boolean m_bEchoDisplayActivated; + }; + #pragma keylist OBS_EchoDisplayCmd m_unWeapon + + // Etat des echos dans le cas d'une séquence de tir Airburst + struct OBS_EchoState + { + // Type d'arme + COM::ECOM_WeaponType_t m_unWeapon; + // Type d'écho + EOBS_EchoType_t m_unEchoType; + // Numéro de l'écho télémétré + unsigned short m_unEchoNumber; + // Mode de mesure la distance + EOBS_DistanceMeasureMode_t m_unMode; + // Distance cible système + float m_fDistance; + // L'echo considéré être l'echo validé (vrai) / L'echo n'est pas considéré comme être l'echo validé (faux) + boolean m_bValid; + // Echo télémétré considéré être l'écho de la cible (vrai) / ou pas (faux) + boolean m_bTarget; + }; + #pragma keylist OBS_EchoState m_unWeapon m_unEchoType m_unEchoNumber + + // Demande d'activation de la sélection de distance manuelle + struct OBS_ManualDistanceReq + { + // Identificateur de viseur de tir + COM::ECOM_SightType_t m_unSight; + // Identifiant de l'opérateur (Chef Tireur Pilote etc.) + COM::ECOM_OperatorIdentifier_t m_unOperatorID; + // Origine de la demande (MFD) + unsigned short m_unRequestorID; + // valeur de la distance manuelle + unsigned short m_unValue; + }; + #pragma keylist OBS_ManualDistanceReq m_unSight m_unOperatorID + + // Etat d'activation de la sélection de distance manuelle + struct OBS_ManualDistanceState + { + // Identificateur de viseur de tir + COM::ECOM_SightType_t m_unSight; + // valeur de la distance manuelle + unsigned short m_unValue; + }; + #pragma keylist OBS_ManualDistanceState m_unSight + + // Viseur principal sélectionné + struct OBS_SelectedMainSight + { + // Clé par défaut + unsigned short m_unKey; + // Identificateur de viseur + COM::ECOM_SightType_t m_unSight; + }; + #pragma keylist OBS_SelectedMainSight m_unKey + + // Etat de la sélection du viseur + struct OBS_SelectedSightState + { + // Identifiant de l'opérateur (Chef Tireur Pilote etc.) + COM::ECOM_OperatorIdentifier_t m_unOperatorID; + // Identificateur de viseur + COM::ECOM_SightType_t m_unSight; + // Etat système de la sélection du viseur + COM::ECOM_ActivatedState_t m_unActivation; + }; + #pragma keylist OBS_SelectedSightState m_unOperatorID m_unSight + + // Valeur de la position site / gisement du viseur + struct OBS_SightPositionState + { + // Identificateur de viseur + COM::ECOM_SightType_t m_unSight; + // Identifiant de viseur dans le groupe "type" + unsigned short m_unKey; + // Gisement + float m_fAzimuth; + // Site + float m_fElevation; + // limite gauche d'observation + float m_fAzimuthLeftLimit; + // limite droite d'observation + float m_fAzimuthRightLimit; + // distance et portée + float m_fLineOfSight; + }; + #pragma keylist OBS_SightPositionState m_unSight m_unKey + + // Echelle stadimétrique + struct OBS_StadimetricScaleReq + { + // Identificateur de viseur de tir + COM::ECOM_SightType_t m_unSight; + // Identifiant de l'opérateur (Chef Tireur Pilote etc.) + COM::ECOM_OperatorIdentifier_t m_unOperatorID; + // Origine de la demande (Mfd) + unsigned short m_unRequestorID; + // Echelle stadimétrique activée (vrai) / Non activée (faux) + boolean m_bActivation; + }; + #pragma keylist OBS_StadimetricScaleReq m_unSight m_unOperatorID + + // Echelle stadimétrique + struct OBS_StadimetricScaleState + { + // Identificateur de viseur de tir + COM::ECOM_SightType_t m_unSight; + // Etat d'activation de l'échelle stadimétrique + COM::ECOM_ActivatedState_t m_unActivation; + }; + #pragma keylist OBS_StadimetricScaleState m_unSight + + // Distance de la cible du système et alerte multi echo distance cible + struct OBS_TargetDistanceState + { + // Origine de la distance + EOBS_DistanceMeasureMode_t m_unOrigin; + // Type d'arme + COM::ECOM_WeaponType_t m_unWeapon; + // Distance cible système + float m_fDistance; + // Offset de portée de tir dans le cas d'un tir airvurst (40mm) + short m_nOffset; + // Alerte mullti echo activé (vrai) / Désactivé (faux) + boolean m_bMultiEcho; + }; + #pragma keylist OBS_TargetDistanceState m_unOrigin m_unWeapon + + // Activation télémétre par le chef / tireur + struct OBS_TelemActivReq + { + // Identificateur de viseur + COM::ECOM_SightType_t m_unSight; + // Identifiant de l'opérateur (Chef Tireur Pilote etc.) + COM::ECOM_OperatorIdentifier_t m_unOperatorID; + // Origine de la demande (Mfd) + unsigned short m_unRequestorID; + // Demande d'activation du télémètre (vrai) / de désactivation (faux) + boolean m_bActivation; + }; + #pragma keylist OBS_TelemActivReq m_unSight m_unOperatorID + + // Etat d'activation télémétre + struct OBS_TelemActivState + { + // Identificateur de viseur + COM::ECOM_SightType_t m_unSight; + // Etat d'activation du télémètre + COM::ECOM_ActivatedState_t m_unActivation; + }; + #pragma keylist OBS_TelemActivState m_unSight + + // Demande de mise sous tension ddes equipements videos + struct OBS_VideoActivReq + { + // Equipement vidéo démarré/arrêté par l'IHM + EOBS_VideoEquiActiv_t m_unVideo; + // Identifiant de l'opérateur (Chef Tireur Pilote etc.) + COM::ECOM_OperatorIdentifier_t m_unOperatorID; + // Origine de la demande (Mfd) + unsigned short m_unRequestorID; + // Equipement vidéo activé / Désactivé + boolean m_bActivation; + }; + #pragma keylist OBS_VideoActivReq m_unVideo m_unOperatorID + + // Etat de l'activation des équipements videos + struct OBS_VideoActivState + { + // Equipement vidéo démarré/arrêté + EOBS_VideoEquiActiv_t m_unVideo; + // Etat d'activation de la demande d'activation + COM::ECOM_ActivatedState_t m_unActivation; + // Etat équipement vidéo + COM::ECOM_EquipmentState_t m_unState; + }; + #pragma keylist OBS_VideoActivState m_unVideo + + // Demande de configuration vidéo + struct OBS_VideoConfigReq + { + // Identifiant de l'opérateur (Chef Tireur Pilote etc.) + COM::ECOM_OperatorIdentifier_t m_unOperatorID; + // Identificateur de viseur + COM::ECOM_SightType_t m_unSight; + // Origine de la demande (Mfd) + unsigned short m_unRequestorID; + // Demande d'inversion de polarité (Normale (faux) / Inversée (vrai)) + boolean m_bPolarityInversion; + // Demande d'activation de la calibration thermique activée (vrai) / désactivée (faux) + boolean m_bCalibCth; + // Demande de réglage de la focalisation de la voie visualisée + EOBS_VideoConfMode_t m_unFocus; + // Valeur manuelle du réglage de la focalisation + unsigned short m_unFocusValue; + // Demande de réglage du gain (aucun (faux)/automatique (vrai)) + EOBS_VideoConfMode_t m_unGain; + // Valeur manuelle du réglage du gain + unsigned short m_unGainValue; + }; + #pragma keylist OBS_VideoConfigReq m_unOperatorID m_unSight + + // Réglage de la vidéo pour la voie affichée sur le poste chef ou tireur + struct OBS_VideoConfigState + { + // Identifiant de l'opérateur (Chef Tireur Pilote etc.) + COM::ECOM_OperatorIdentifier_t m_unOperatorID; + // Identificateur de viseur + COM::ECOM_SightType_t m_unSight; + // Etat du réglage de la focalisation + EOBS_VideoFocusState_t m_unFocus; + // Valeur manuelle du réglage de la focalisation + unsigned short m_unFocusValue; + // Etat du réglage du gain + EOBS_VideoGainState_t m_unGain; + // Valeur manuelle du réglage du gain + unsigned short m_unGainValue; + // Etat de la demande d'inversion de polarité (faux =normale vrai = inversée) + boolean m_bPolarityInversion; + // Etat de la demande de calibration + EOBS_VideoCalibState_t m_unCalibCth; + }; + #pragma keylist OBS_VideoConfigState m_unOperatorID m_unSight + + // Commande de mode vidéo du MPC / MPT + struct OBS_VideoDisplayCmd + { + // Identifiant de l'opérateur (Chef Tireur Pilote etc.) + COM::ECOM_OperatorIdentifier_t m_unOperatorID; + // La position du MFD + COM::ECOM_MFDPosition_t m_unMFDType; + // Equipement fournissant la vidéo + EOBS_VideoSensor_t m_unEquipment; + // Voie de la video a afficher + COM::ECOM_VideoChannel_t m_unChannel; + // Champ de la video a afficher + COM::ECOM_VideoField_t m_unField; + // Mode de la video a afficher + EOBS_VideoMode_t m_unMode; + // Position de la vidéo (X Y) + COM::TCOM_AppPosition m_tVideoPosition; + // Taille de la video (hauteur largeur) + COM::TCOM_AppSize m_tVideoSize; + }; + #pragma keylist OBS_VideoDisplayCmd m_unOperatorID m_unMFDType + + // Demande de sélection video + struct OBS_VideoSelectReq + { + // Identifiant de l'opérateur (Chef Tireur Pilote etc.) + COM::ECOM_OperatorIdentifier_t m_unOperatorID; + // Origine de la demande (Mfd) + unsigned short m_unRequestorID; + // Video à selectionner + EOBS_VideoSensor_t m_unVideoSensor; + }; + #pragma keylist OBS_VideoSelectReq m_unOperatorID m_unRequestorID + + // Demande d'activation du mode loupe + struct OBS_VideoZoomReq + { + // Identifiant de l'opérateur (Chef Tireur Pilote etc.) + COM::ECOM_OperatorIdentifier_t m_unOperatorID; + // Equipement fournissant la video + EOBS_VideoSensor_t m_unVideoSensor; + // Origine de la demande (Mfd) + unsigned short m_unRequestorID; + // Activation (vrai) / Desactivation (faux) de la loupe x2 + boolean m_bActivation; + // valeur du zoom + float m_fZoom; + }; + #pragma keylist OBS_VideoZoomReq m_unOperatorID m_unVideoSensor + + // Etat du niveau loupe reçu du système + struct OBS_VideoZoomState + { + // Equipement fournissant la video + EOBS_VideoSensor_t m_unVideoSensor; + // Etat d'activation de l'équipement + COM::ECOM_ActivatedState_t m_unActivationProgress; + // valeur du zoom appliqué + float m_fZoom; + }; + #pragma keylist OBS_VideoZoomState m_unVideoSensor + + // Demande d'essuyage + struct OBS_WipingReq + { + // Identificateur de viseur de tir + COM::ECOM_SightType_t m_unSight; + // Identifiant de l'opérateur (Chef Tireur Pilote etc.) + COM::ECOM_OperatorIdentifier_t m_unOperatorID; + // Origine de la demande (Mfd) + unsigned short m_unRequestorID; + // Essuyage du viseur activé (vrai) / Non activé (faux) + boolean m_bActivation; + }; + #pragma keylist OBS_WipingReq m_unSight m_unOperatorID + + // Etat d'essuyage des viseusrs + struct OBS_WipingState + { + // Identificateur de viseur de tir + COM::ECOM_SightType_t m_unSight; + // Etat d'activation de l'essuyage du viseur + COM::ECOM_ActivatedState_t m_unActivation; + }; + #pragma keylist OBS_WipingState m_unSight + }; + + module TST + { + + typedef unsigned short ETST_TypeAlarmIndicator_t; + + typedef unsigned long ETST_FaultCode_t; + + typedef unsigned short ETST_OperationalState_t; + + typedef unsigned short ETST_SystemFunction_t; + + struct TST_AlarmIndicator + { + // Origine de la demande (Mfd) + unsigned short m_unRequestorID; + // Identifiant de l'opérateur (Chef Tireur Pilote etc.) + COM::ECOM_OperatorIdentifier_t m_unOperatorID; + // Sous composants et sous fonctions + COM::ECOM_SubComponents_t m_unSubComponentID; + // Composants des fonctions état système + COM::ECOM_SystemComponents_t m_unComponentID; + // Précise s'il s'agit d'une alarme ou d'une indication de panne + ETST_TypeAlarmIndicator_t m_unType; + }; + #pragma keylist TST_AlarmIndicator m_unRequestorID m_unOperatorID + + // Information sur l'apparition ou la disparition d'un défaut + struct TST_CANFaultCode + { + // Code défaut + ETST_FaultCode_t m_ulFaultCode; + // Code de défaillance SPN + unsigned long m_ulSPNFailureCode; + // Code de défaillance FMI + unsigned long m_ulFMIFailureCode; + // Nombre d'occurrence dans la session courante + unsigned short m_unOccurence; + // Etat de l'alerte + COM::ECOM_AlertState_t m_unAlertState; + }; + #pragma keylist TST_CANFaultCode m_ulFaultCode + + // Etat des équipements des fonctions de l'état technique système + struct TST_ComponentState + { + // Composants des fonctions état système + COM::ECOM_SystemComponents_t m_unComponentID; + // Etat système de la demande d'activation + COM::ECOM_ActivatedState_t m_unActivation; + }; + #pragma keylist TST_ComponentState m_unComponentID + + // Acquittement d'état des MFDs + struct TST_MFDStateAck + { + // Identifiant de l'opérateur (Chef Tireur Pilote etc.) + COM::ECOM_OperatorIdentifier_t m_unOperatorID; + // La position du MFD + COM::ECOM_MFDPosition_t m_unMFDType; + // Si MFD global (valeur = 0) sinon identifiant d'une sous fonction ( le LCCS fait le lien directement entre le numéro et la sous fonction correspondante) + unsigned short m_unStateType; + // Etat operationel du MFD ou de la sous fonction pour testabilité + ETST_OperationalState_t m_unOpeState; + }; + #pragma keylist TST_MFDStateAck m_unOperatorID m_unMFDType m_unStateType + + // Remise à Zero des potentiels mission par l'opérateur + struct TST_PotentialRAZ + { + // Clé par défaut + unsigned short m_unKey; + // Remise à zéro de la partie Mission des potentiels consommés. + boolean m_bRAZ; + }; + #pragma keylist TST_PotentialRAZ m_unKey + + // Informations sur les potentiels restants + struct TST_RemainingPotential + { + // Identifiant du potentiel restant + unsigned short m_unPotentialID; + // Valeur du potentiel restant + unsigned short m_unPotentialValue; + }; + #pragma keylist TST_RemainingPotential m_unPotentialID + + // Etat des sous équipements + struct TST_SubComponentState + { + // Sous composants et sous fonctions + COM::ECOM_SubComponents_t m_unSubComponentID; + // Composants des fonctions état système + COM::ECOM_SystemComponents_t m_unComponentID; + // Etat système de la demande d'activation + COM::ECOM_ActivatedState_t m_unActivation; + }; + #pragma keylist TST_SubComponentState m_unSubComponentID + + // Etat fonctionnel système + struct TST_SystemFunctionalState + { + // Fonction système + ETST_SystemFunction_t m_unFunction; + // Etat fonctionnel + COM::ECOM_FunctionState_t m_unState; + }; + #pragma keylist TST_SystemFunctionalState m_unFunction + }; + + module VISU + { + + typedef unsigned short EVISU_Pictogram_t; + + typedef unsigned short EVISU_PictoState_t; + + // Etat des pictogrammes + struct VISU_PictogramState + { + // Pictogramme concerné par la mise à jour + EVISU_Pictogram_t m_unPictogram; + // Etat du pictogramme + EVISU_PictoState_t m_unState; + // Couleur du pictogramme + unsigned short m_unColor; + }; + #pragma keylist VISU_PictogramState m_unPictogram + + // Etat des séquences de ralliement commandées par le chef / pilote / tireur + struct VISU_RallyingSequenceState + { + // Identifiant de l'opérateur (Chef Tireur Pilote etc.) + COM::ECOM_OperatorIdentifier_t m_unOperatorID; + // Etat du ralliement + COM::ECOM_ActivatedState_t m_unRallying; + // Histogramme temps de ralliement + COM::ECOM_BargraphType_t m_unBargraph; + // Destination à rallier + COM::ECOM_SlewingDirection_t m_unDestination; + }; + #pragma keylist VISU_RallyingSequenceState m_unOperatorID + + // Permet d'afficher un texte sur la molette en ins-tanciant le numéro de l'application publisher de ce topic + struct VISU_StripTextReturn + { + // Permet d'afficher un texte sur la molette en instanciant le numéro de l'application publisher de ce topic + unsigned short m_unAppInstanceID; + // Séquence de string pour texte à afficher sur molette + string50 m_sLabel; + }; + #pragma keylist VISU_StripTextReturn m_unAppInstanceID + + // Profil utilisateur sélectionné + struct VISU_UserProfilSelected + { + // Identifiant de l'opérateur (Chef Tireur Pilote etc.) + COM::ECOM_OperatorIdentifier_t m_unOperatorID; + // Profil utilisateur + COM::ECOM_UserProfile_t m_unUserProfile; + }; + #pragma keylist VISU_UserProfilSelected m_unOperatorID + }; + + module VIVA + { + + typedef unsigned short EVIVA_AirCondType_t; + + typedef unsigned short EVIVA_AirCondCmdMode_t; + + typedef unsigned short EVIVA_AirCondActivMode_t; + + typedef unsigned short EVIVA_NBCVentilationMode_t; + + typedef unsigned short EVIVA_OpeningID_t; + + typedef unsigned short EVIVA_OpeningNature_t; + + // Informations sur les ouvrants + struct TVIVA_OpeningInformation + { + // Vrai si état ouvrant ouvert + boolean m_bOpeningState; + // Vrai si état ouvrant verrouillé + boolean m_bLockedState; + // Position du verrouillage + float m_fLockedPosition; + // Vrai si état ouvrant arrêté + boolean m_bMovementState; + }; + + // Commande du type de climatisation + struct VIVA_AirConditioningTypeReq + { + // Type de climatisation concernée + EVIVA_AirCondType_t m_unAirCondType; + // Mode choici pour l'air conditionné (manuel auto arrêt test) + EVIVA_AirCondCmdMode_t m_unCmdMode; + // Identifiant de l'opérateur (Chef Tireur Pilote etc.) + COM::ECOM_OperatorIdentifier_t m_unOperatorID; + // Origine de la demande (Mfd) + unsigned short m_unRequestorID; + // Activation mode de la climatisation selon le mode manuel + EVIVA_AirCondActivMode_t m_unActivMode; + }; + #pragma keylist VIVA_AirConditioningTypeReq m_unAirCondType + + // Surpression habitacle + struct VIVA_CrewCompartmentOverpressure + { + // Clé par défaut du topic + unsigned short m_unKey; + // Valeur de la surpression de l'habitacle + float m_fOverpressure; + }; + #pragma keylist VIVA_CrewCompartmentOverpressure m_unKey + + // Température de l'habitacle + struct VIVA_CrewCompartmentTemperature + { + // Zone véhicule (interieur extérieur) + COM::ECOM_ZoneVeh_t m_unZone; + // Identifiant du porteur : porteur principal porteur secondaire (robot) … + COM::ECOM_CarrierType_t m_unCarrierType; + // Valeur de la température demandée + float m_fTemp; + }; + #pragma keylist VIVA_CrewCompartmentTemperature m_unZone m_unCarrierType + + // Etat filtre NBC et état des modes ventilation NBC + struct VIVA_NBCFilterVentilationState + { + // Clé par défaut du topic + unsigned short m_unKey; + // Présence état filtre monté sur le véhicule + boolean m_bFilterPresence; + // Retour d'état du mode de ventilation NBC + EVIVA_NBCVentilationMode_t m_unMode; + }; + #pragma keylist VIVA_NBCFilterVentilationState m_unKey + + // Etat d'un des capteurs de l'ouvrant + struct VIVA_OpeningSensorState + { + // Identifiant de l'ouvrant + EVIVA_OpeningID_t m_unOpeningID; + // Identifiant du capteur de l'ouvrant + unsigned short m_unSensorID; + // Etat équipement + COM::ECOM_Status_t m_unState; + }; + #pragma keylist VIVA_OpeningSensorState m_unOpeningID m_unSensorID + + // Etat de l'ouvrant + struct VIVA_OpeningState + { + // Identifiant de l'ouvrant + EVIVA_OpeningID_t m_unOpeningID; + // Nature de l'ouvrant + EVIVA_OpeningNature_t m_unOpeningNature; + // Informations sur l'ouvrant + TVIVA_OpeningInformation m_tOpeningInfo; + }; + #pragma keylist VIVA_OpeningState m_unOpeningID m_unOpeningNature + + // Etat de la température + struct VIVA_TemperatureState + { + // Zone véhicule (interieur extérieur) + COM::ECOM_ZoneVeh_t m_unZone; + // Identifiant du porteur : porteur principal porteur secondaire (robot) … + COM::ECOM_CarrierType_t m_unCarrierType; + // Valeur de la température + float m_fTemp; + }; + #pragma keylist VIVA_TemperatureState m_unZone m_unCarrierType + + // Etat de la climatisation et de la ventilation + struct VIVA_VentilationAirCondState + { + // Type de climatisation concernée + EVIVA_AirCondType_t m_unAirCondType; + // Mode choici pour l'air conditionné (manuel auto arrêt test) + EVIVA_AirCondCmdMode_t m_unCmdMode; + // Retour d'état du bloc de climatisation selon le mode manuel + COM::ECOM_EquipmentState_t m_unState; + // Retour d'état de la ventillation + float m_fVentilationOutput; + }; + #pragma keylist VIVA_VentilationAirCondState m_unAirCondType + + // Commande de débit de ventilation + struct VIVA_VentilationOutputReq + { + // Commande de débit de ventilation + unsigned short m_unKey; + // Identifiant de l'opérateur (Chef Tireur Pilote etc.) + COM::ECOM_OperatorIdentifier_t m_unOperatorID; + // Origine de la demande (Mfd) + unsigned short m_unRequestorID; + // Commande de débit de ventilation + float m_fVentilationOutput; + }; + #pragma keylist VIVA_VentilationOutputReq m_unKey + }; + + module PWR + { + + typedef unsigned short EPWR_BatteryGroup_t; + + typedef unsigned short EPWR_BatteryNum_t; + + typedef unsigned short EPWR_Equipment_t; + + // Temps d'utilisation restant des batteries + struct PWR_BatteryAverageRemainingTime + { + // Clé par défaut du topic + unsigned short m_unKey; + // Valeur calculée du temps restant avant la décharge des batteries + unsigned short m_unAverageRemainingTime; + }; + #pragma keylist PWR_BatteryAverageRemainingTime m_unKey + + // Niveau de charge moyen des batteries + struct PWR_BatteryAverageStateOfCharge + { + // Clé par défaut du topic + unsigned short m_unKey; + // Etat moyen de charge des batteries + float m_fAverageStateOfCharge; + }; + #pragma keylist PWR_BatteryAverageStateOfCharge m_unKey + + // Tension moyenne aux bornes des batteries + struct PWR_BatteryAverageVoltage + { + // Clé par défaut du topic + unsigned short m_unKey; + // Valeur moyenne de la tension des batteries + float m_fAverageVoltage; + }; + #pragma keylist PWR_BatteryAverageVoltage m_unKey + + // Temps restant avant la décharge complète de la batterie + struct PWR_BatteryRemainingTime + { + // Identifiant du BMS + EPWR_BatteryGroup_t m_unGroup; + // Identifiant de la batterie + EPWR_BatteryNum_t m_unNum; + // Valeur du temps restant avant la décharge complète de la batterie + unsigned short m_unRemainingTime; + }; + #pragma keylist PWR_BatteryRemainingTime m_unGroup m_unNum + + // Etat de charge de la batterie + struct PWR_BatteryStateOfCharge + { + // Identifiant du porteur : porteur principal porteur secondaire (robot) … + COM::ECOM_CarrierType_t m_unType; + // Identifiant du BMS + EPWR_BatteryGroup_t m_unGroup; + // Identifiant de la batterie + EPWR_BatteryNum_t m_unNum; + // Etat de charge de la batterie en % + float m_fStateOfCharge; + }; + #pragma keylist PWR_BatteryStateOfCharge m_unType m_unGroup m_unNum + + // Température batterie mesurée par le BMS + struct PWR_BatteryTemperature + { + // Identifiant du BMS + EPWR_BatteryGroup_t m_unGroup; + // Identifiant de la batterie + EPWR_BatteryNum_t m_unNum; + // Valeur de la température batterie mesurée par le BMS + float m_fTemperature; + }; + #pragma keylist PWR_BatteryTemperature m_unGroup m_unNum + + // Tension batterie mesurée par le BMS + struct PWR_BatteryVoltage + { + // Identifiant du BMS + EPWR_BatteryGroup_t m_unGroup; + // Identifiant de la batterie + EPWR_BatteryNum_t m_unNum; + // Valeur de la tension batterie mesurée par le BMS + float m_fVolatge; + }; + #pragma keylist PWR_BatteryVoltage m_unGroup m_unNum + + // Demande d'activation des équipements + struct PWR_EquipmentActivationReq + { + // Identifiant de l'opérateur (Chef Tireur Pilote etc.) + COM::ECOM_OperatorIdentifier_t m_unOperatorID; + // Identifiant de l'équipement + COM::ECOM_Equipment_t m_unEquipement; + // Origine de la demande (Mfd) + unsigned short m_unRequestorID; + // Activation (vrai) / Desactivation (faux) de l'alimentation électrique + boolean m_bActivation; + }; + #pragma keylist PWR_EquipmentActivationReq m_unOperatorID m_unEquipement + + // Etat d'activation des équipements + struct PWR_EquipmentActivationState + { + // Identifiant de l'équipement + COM::ECOM_Equipment_t m_unEquipement; + // Etat de l'activation de l'équipement + COM::ECOM_ActivatedState_t m_unActivation; + // Durée de l'autonomie restante + unsigned long m_ulDuration; + }; + #pragma keylist PWR_EquipmentActivationState m_unEquipement + + // Présence ou non du BMS et génératrice + struct PWR_EquipmentsPresence + { + // Equipements de puissance + EPWR_Equipment_t m_unEquipment; + // Etat equipement (present ou pas) + COM::ECOM_HWPresence_t m_unPresence; + }; + #pragma keylist PWR_EquipmentsPresence m_unEquipment + + // Pourcentage de charge de la génératrice + struct PWR_GeneratorLoadCapacity + { + // Clé par défaut du topic + unsigned short m_unKey; + // Capacité de charge de la génératrice + unsigned short m_unCapacity; + }; + #pragma keylist PWR_GeneratorLoadCapacity m_unKey + + // Demande dd'activation de l'alimentation électrique + struct PWR_PowerSupplyReq + { + // Identifiant de l'opérateur (Chef Tireur Pilote etc.) + COM::ECOM_OperatorIdentifier_t m_unOperatorID; + // Equipements des fonctions état système + unsigned short m_unLineID; + // Origine de la demande (Mfd) + unsigned short m_unRequestorID; + // Vrai si activation de l'alimentation électrique sinon Faux + boolean m_bActivation; + }; + #pragma keylist PWR_PowerSupplyReq m_unOperatorID m_unLineID + + // Etat des equipemensts + struct PWR_PowerSupplyState + { + // Identifiant de la ligne + unsigned short m_unLineID; + // Etat système de la demande d'activation + COM::ECOM_PowerActivState_t m_unActivation; + }; + #pragma keylist PWR_PowerSupplyState m_unLineID + }; + + module HUMS + { + + // Operator action origin + typedef unsigned short EHUMS_OriginUserAction_t; + + // Operator action type + typedef unsigned short EHUMS_UserActionType_t; + + // Actions de l'opérateur + struct HUMS_UserActions + { + // Nom de l'applicatif + unsigned short m_unAppInstanceID; + // Identifiant de l'opérateur (Chef Tireur Pilote etc.) + COM::ECOM_OperatorIdentifier_t m_unOperatorID; + // Profil utilisateur + COM::ECOM_UserProfile_t m_unUserProfile; + // Origine de l'action opérateur + EHUMS_OriginUserAction_t m_unOriginUserAction; + // Type de l'action opérateur + EHUMS_UserActionType_t m_unTypeUserAction; + // Nom de l'attribut/variable concerné par l'action opérateur + stringShort m_sAttributeName; + // Valeur de l'attribut/variable concerné par l'action opérateur + stringShort m_sAttributeValue; + }; + #pragma keylist HUMS_UserActions m_unAppInstanceID m_unOperatorID + }; + + module HMI + { + + typedef unsigned short EHMI_JoystickAction_t; + + typedef unsigned short EHMI_PushButtonState_t; + + // Etat du VDC et du Joystick(molette bouton) + struct HMI_Joystick + { + // Identifiant de l'opérateur (Chef Tireur Pilote etc.) + COM::ECOM_OperatorIdentifier_t m_unOperatorID; + // Indentfiant du joystick (en cas de l'utilisation de plusieurs VDC) + unsigned short m_unJoystickID; + // nombre de graduation de la molette tournante + unsigned short m_unJoystickRotaryEncoder; + // Action Joystick + EHMI_JoystickAction_t m_unJoystickAction; + // Etat du bouton + EHMI_PushButtonState_t m_unButtonState; + }; + #pragma keylist HMI_Joystick m_unOperatorID m_unJoystickID + }; + +}; diff --git a/src/api/dcps/python/test/idl/Thales.idl b/src/api/dcps/python/test/idl/Thales.idl new file mode 100644 index 000000000..e3fba0295 --- /dev/null +++ b/src/api/dcps/python/test/idl/Thales.idl @@ -0,0 +1,17 @@ +module test { + struct T_ID + { + long A_ID; + long A_subID; + }; + + typedef sequence T_IDList; + + struct C_TopicStruct + { + T_ID A_ID; + T_IDList A_ForeignIDList; + long value; + }; + #pragma keylist C_TopicStruct A_ID.A_ID A_ID.A_subID +}; \ No newline at end of file diff --git a/src/api/dcps/python/test/idl/Union.idl b/src/api/dcps/python/test/idl/Union.idl new file mode 100644 index 000000000..e37ffbaeb --- /dev/null +++ b/src/api/dcps/python/test/idl/Union.idl @@ -0,0 +1,63 @@ +module basic{ + + module module_Union{ + + enum Color { Red, Orange, Yellow, Green, Blue, Indigo, Violet}; + + union uone switch(Color) { + case Red: + case Orange: + short s; + case Green: + long l; + default: + long long ll; + }; + + union utwo switch(Color) { + case Red: + case Orange: + short s; + case Green: + long l; + }; + + union uthree switch(char) { + case 'a': + short sa; + case 'b': + short sb; + }; + + union ufour switch(long) { + case 1: + short s1; + case 2: + short s2; + }; + + union ufive switch(boolean) { + case True: + short sT; + case False: + short sF; + }; + + union ano21 switch (short) { + case 97: long x1[20][12]; + case 98: Color x2[2][3][4][6]; + }; + + struct Union_struct{ + long long1; + ano21 union1; + }; + + #pragma keylist Union_struct long1 + }; + + +}; + + + diff --git a/src/api/dcps/python/test/idl/sample2.idl b/src/api/dcps/python/test/idl/sample2.idl new file mode 100644 index 000000000..3579d8f23 --- /dev/null +++ b/src/api/dcps/python/test/idl/sample2.idl @@ -0,0 +1,30 @@ +const long length = 3; +typedef long my_long; + +module basic{ + + struct Inner{ + short long1; + double double1; + //double double2; + //long long2; + //long long3; + long array1[length]; + string str1; + }; + + typedef Inner inner_struct; + + module test{ + + struct Type1{ + char long1; + //string str1; + Sequence inner1; + my_long mylong1; + }; + + #pragma keylist Type1 long1 + }; +}; + diff --git a/src/api/dcps/python/test/qos/DDS_DefaultQoS_All.xml b/src/api/dcps/python/test/qos/DDS_DefaultQoS_All.xml new file mode 100644 index 000000000..6745b326e --- /dev/null +++ b/src/api/dcps/python/test/qos/DDS_DefaultQoS_All.xml @@ -0,0 +1,243 @@ + + + + + + VOLATILE_DURABILITY_QOS + + + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + + 0 + 0 + + + + AUTOMATIC_LIVELINESS_QOS + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + BEST_EFFORT_RELIABILITY_QOS + + 0 + 100000000 + + + + BY_RECEPTION_TIMESTAMP_DESTINATIONORDER_QOS + + + KEEP_LAST_HISTORY_QOS + 1 + + + LENGTH_UNLIMITED + LENGTH_UNLIMITED + LENGTH_UNLIMITED + + + + + + SHARED_OWNERSHIP_QOS + + + + 0 + 0 + + + + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + + + VOLATILE_DURABILITY_QOS + + + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + + 0 + 0 + + + + AUTOMATIC_LIVELINESS_QOS + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + RELIABLE_RELIABILITY_QOS + + 0 + 100000000 + + + + BY_RECEPTION_TIMESTAMP_DESTINATIONORDER_QOS + + + KEEP_LAST_HISTORY_QOS + 1 + + + LENGTH_UNLIMITED + LENGTH_UNLIMITED + LENGTH_UNLIMITED + + + 0 + + + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + + + + SHARED_OWNERSHIP_QOS + + + 0 + + + true + + + + + + + + true + + + + + INSTANCE_PRESENTATION_QOS + false + false + + + + + + + + + true + + + + + INSTANCE_PRESENTATION_QOS + false + false + + + + + + + + + true + + + + + + + + VOLATILE_DURABILITY_QOS + + + + 0 + 0 + + KEEP_LAST_HISTORY_QOS + 1 + LENGTH_UNLIMITED + LENGTH_UNLIMITED + LENGTH_UNLIMITED + + + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + + 0 + 0 + + + + AUTOMATIC_LIVELINESS_QOS + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + BEST_EFFORT_RELIABILITY_QOS + + 0 + 100000000 + + + + BY_RECEPTION_TIMESTAMP_DESTINATIONORDER_QOS + + + KEEP_LAST_HISTORY_QOS + 1 + + + LENGTH_UNLIMITED + LENGTH_UNLIMITED + LENGTH_UNLIMITED + + + 0 + + + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + SHARED_OWNERSHIP_QOS + + + + diff --git a/src/api/dcps/python/test/qos/DDS_DefaultQoS_Reader.xml b/src/api/dcps/python/test/qos/DDS_DefaultQoS_Reader.xml new file mode 100644 index 000000000..f1f043bd0 --- /dev/null +++ b/src/api/dcps/python/test/qos/DDS_DefaultQoS_Reader.xml @@ -0,0 +1,70 @@ + + + + + + VOLATILE_DURABILITY_QOS + + + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + + 0 + 0 + + + + AUTOMATIC_LIVELINESS_QOS + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + BEST_EFFORT_RELIABILITY_QOS + + 0 + 100000000 + + + + BY_RECEPTION_TIMESTAMP_DESTINATIONORDER_QOS + + + KEEP_LAST_HISTORY_QOS + 1 + + + LENGTH_UNLIMITED + LENGTH_UNLIMITED + LENGTH_UNLIMITED + + + + + + SHARED_OWNERSHIP_QOS + + + + 0 + 0 + + + + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + + diff --git a/src/api/dcps/python/test/qos/DDS_DefaultQoS_Topic.xml b/src/api/dcps/python/test/qos/DDS_DefaultQoS_Topic.xml new file mode 100644 index 000000000..f6157a30b --- /dev/null +++ b/src/api/dcps/python/test/qos/DDS_DefaultQoS_Topic.xml @@ -0,0 +1,74 @@ + + + + + + + + + VOLATILE_DURABILITY_QOS + + + + 0 + 0 + + KEEP_LAST_HISTORY_QOS + 1 + LENGTH_UNLIMITED + LENGTH_UNLIMITED + LENGTH_UNLIMITED + + + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + + 0 + 0 + + + + AUTOMATIC_LIVELINESS_QOS + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + BEST_EFFORT_RELIABILITY_QOS + + 0 + 100000000 + + + + BY_RECEPTION_TIMESTAMP_DESTINATIONORDER_QOS + + + KEEP_LAST_HISTORY_QOS + 1 + + + LENGTH_UNLIMITED + LENGTH_UNLIMITED + LENGTH_UNLIMITED + + + 0 + + + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + SHARED_OWNERSHIP_QOS + + + + diff --git a/src/api/dcps/python/test/qos/DDS_DefaultQoS_Writer.xml b/src/api/dcps/python/test/qos/DDS_DefaultQoS_Writer.xml new file mode 100644 index 000000000..6868aa63f --- /dev/null +++ b/src/api/dcps/python/test/qos/DDS_DefaultQoS_Writer.xml @@ -0,0 +1,69 @@ + + + + + + VOLATILE_DURABILITY_QOS + + + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + + 0 + 0 + + + + AUTOMATIC_LIVELINESS_QOS + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + RELIABLE_RELIABILITY_QOS + + 0 + 100000000 + + + + BY_RECEPTION_TIMESTAMP_DESTINATIONORDER_QOS + + + KEEP_LAST_HISTORY_QOS + 1 + + + LENGTH_UNLIMITED + LENGTH_UNLIMITED + LENGTH_UNLIMITED + + + 0 + + + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + + + + SHARED_OWNERSHIP_QOS + + + 0 + + + true + + + + diff --git a/src/api/dcps/python/test/qos/DDS_InvalidQoS.xml b/src/api/dcps/python/test/qos/DDS_InvalidQoS.xml new file mode 100644 index 000000000..fb7c4abaf --- /dev/null +++ b/src/api/dcps/python/test/qos/DDS_InvalidQoS.xml @@ -0,0 +1,2 @@ + + diff --git a/src/api/dcps/python/test/qos/DDS_No_Data_QoS.xml b/src/api/dcps/python/test/qos/DDS_No_Data_QoS.xml new file mode 100644 index 000000000..2172f9e9d --- /dev/null +++ b/src/api/dcps/python/test/qos/DDS_No_Data_QoS.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + true + + + + + INSTANCE_PRESENTATION_QOS + false + false + + + + + + + + + true + + + + + INSTANCE_PRESENTATION_QOS + false + false + + + + + + + + + true + + + + + + diff --git a/src/api/dcps/python/test/qos/DDS_PersistentQoS_All.xml b/src/api/dcps/python/test/qos/DDS_PersistentQoS_All.xml new file mode 100644 index 000000000..bbaec69c8 --- /dev/null +++ b/src/api/dcps/python/test/qos/DDS_PersistentQoS_All.xml @@ -0,0 +1,242 @@ + + + + + + PERSISTENT_DURABILITY_QOS + + + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + + 0 + 0 + + + + AUTOMATIC_LIVELINESS_QOS + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + BEST_EFFORT_RELIABILITY_QOS + + 0 + 100000000 + + + + BY_RECEPTION_TIMESTAMP_DESTINATIONORDER_QOS + + + KEEP_ALL_HISTORY_QOS + + + LENGTH_UNLIMITED + LENGTH_UNLIMITED + LENGTH_UNLIMITED + + + + + + SHARED_OWNERSHIP_QOS + + + + 0 + 0 + + + + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + + + PERSISTENT_DURABILITY_QOS + + + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + + 0 + 0 + + + + AUTOMATIC_LIVELINESS_QOS + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + RELIABLE_RELIABILITY_QOS + + 0 + 100000000 + + + + BY_RECEPTION_TIMESTAMP_DESTINATIONORDER_QOS + + + KEEP_LAST_HISTORY_QOS + 100 + + + LENGTH_UNLIMITED + LENGTH_UNLIMITED + LENGTH_UNLIMITED + + + 0 + + + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + + + + SHARED_OWNERSHIP_QOS + + + 0 + + + true + + + + + + + + true + + + + + INSTANCE_PRESENTATION_QOS + false + false + + + + + + + + + true + + + + + INSTANCE_PRESENTATION_QOS + false + false + + + + + + + + + true + + + + + + + + PERSISTENT_DURABILITY_QOS + + + + 3600 + 0 + + KEEP_LAST_HISTORY_QOS + 100 + 8192 + 4196 + 8192 + + + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + + 0 + 0 + + + + AUTOMATIC_LIVELINESS_QOS + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + BEST_EFFORT_RELIABILITY_QOS + + 0 + 100000000 + + + + BY_RECEPTION_TIMESTAMP_DESTINATIONORDER_QOS + + + KEEP_LAST_HISTORY_QOS + 1 + + + LENGTH_UNLIMITED + LENGTH_UNLIMITED + LENGTH_UNLIMITED + + + 0 + + + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + SHARED_OWNERSHIP_QOS + + + + diff --git a/src/api/dcps/python/test/qos/DDS_PersistentQoS_Reader.xml b/src/api/dcps/python/test/qos/DDS_PersistentQoS_Reader.xml new file mode 100644 index 000000000..e72345d73 --- /dev/null +++ b/src/api/dcps/python/test/qos/DDS_PersistentQoS_Reader.xml @@ -0,0 +1,69 @@ + + + + + + PERSISTENT_DURABILITY_QOS + + + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + + 0 + 0 + + + + AUTOMATIC_LIVELINESS_QOS + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + BEST_EFFORT_RELIABILITY_QOS + + 0 + 100000000 + + + + BY_RECEPTION_TIMESTAMP_DESTINATIONORDER_QOS + + + KEEP_ALL_HISTORY_QOS + + + LENGTH_UNLIMITED + LENGTH_UNLIMITED + LENGTH_UNLIMITED + + + + + + SHARED_OWNERSHIP_QOS + + + + 0 + 0 + + + + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + + diff --git a/src/api/dcps/python/test/qos/DDS_PersistentQoS_Topic.xml b/src/api/dcps/python/test/qos/DDS_PersistentQoS_Topic.xml new file mode 100644 index 000000000..eb1f0581d --- /dev/null +++ b/src/api/dcps/python/test/qos/DDS_PersistentQoS_Topic.xml @@ -0,0 +1,74 @@ + + + + + + + + + PERSISTENT_DURABILITY_QOS + + + + 3600 + 0 + + KEEP_LAST_HISTORY_QOS + 100 + 8192 + 4196 + 8192 + + + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + + 0 + 0 + + + + AUTOMATIC_LIVELINESS_QOS + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + BEST_EFFORT_RELIABILITY_QOS + + 0 + 100000000 + + + + BY_RECEPTION_TIMESTAMP_DESTINATIONORDER_QOS + + + KEEP_LAST_HISTORY_QOS + 1 + + + LENGTH_UNLIMITED + LENGTH_UNLIMITED + LENGTH_UNLIMITED + + + 0 + + + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + SHARED_OWNERSHIP_QOS + + + + diff --git a/src/api/dcps/python/test/qos/DDS_PersistentQoS_Writer.xml b/src/api/dcps/python/test/qos/DDS_PersistentQoS_Writer.xml new file mode 100644 index 000000000..12cdef983 --- /dev/null +++ b/src/api/dcps/python/test/qos/DDS_PersistentQoS_Writer.xml @@ -0,0 +1,69 @@ + + + + + + PERSISTENT_DURABILITY_QOS + + + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + + 0 + 0 + + + + AUTOMATIC_LIVELINESS_QOS + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + RELIABLE_RELIABILITY_QOS + + 0 + 100000000 + + + + BY_RECEPTION_TIMESTAMP_DESTINATIONORDER_QOS + + + KEEP_LAST_HISTORY_QOS + 100 + + + LENGTH_UNLIMITED + LENGTH_UNLIMITED + LENGTH_UNLIMITED + + + 0 + + + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + + + + SHARED_OWNERSHIP_QOS + + + 0 + + + true + + + + diff --git a/src/api/dcps/python/test/qos/DDS_QoS_Mismatched.xml b/src/api/dcps/python/test/qos/DDS_QoS_Mismatched.xml new file mode 100644 index 000000000..2d8f41c78 --- /dev/null +++ b/src/api/dcps/python/test/qos/DDS_QoS_Mismatched.xml @@ -0,0 +1,242 @@ + + + + + + PERSISTENT_DURABILITY_QOS + + + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + + 0 + 0 + + + + AUTOMATIC_LIVELINESS_QOS + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + BEST_EFFORT_RELIABILITY_QOS + + 0 + 100000000 + + + + BY_RECEPTION_TIMESTAMP_DESTINATIONORDER_QOS + + + KEEP_ALL_HISTORY_QOS + + + LENGTH_UNLIMITED + LENGTH_UNLIMITED + LENGTH_UNLIMITED + + + + + + SHARED_OWNERSHIP_QOS + + + + 0 + 0 + + + + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + + + VOLATILE_DURABILITY_QOS + + + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + + 0 + 0 + + + + AUTOMATIC_LIVELINESS_QOS + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + RELIABLE_RELIABILITY_QOS + + 0 + 100000000 + + + + BY_RECEPTION_TIMESTAMP_DESTINATIONORDER_QOS + + + KEEP_LAST_HISTORY_QOS + 1 + + + LENGTH_UNLIMITED + LENGTH_UNLIMITED + LENGTH_UNLIMITED + + + 0 + + + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + + + + SHARED_OWNERSHIP_QOS + + + 0 + + + true + + + + + + + + true + + + + + INSTANCE_PRESENTATION_QOS + false + false + + + + + + + + + true + + + + + INSTANCE_PRESENTATION_QOS + false + false + + + + + + + + + true + + + + + + + + VOLATILE_DURABILITY_QOS + + + + 3600 + 0 + + KEEP_LAST_HISTORY_QOS + 100 + 8192 + 4196 + 8192 + + + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + + 0 + 0 + + + + AUTOMATIC_LIVELINESS_QOS + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + BEST_EFFORT_RELIABILITY_QOS + + 0 + 100000000 + + + + BY_RECEPTION_TIMESTAMP_DESTINATIONORDER_QOS + + + KEEP_LAST_HISTORY_QOS + 100 + + + LENGTH_UNLIMITED + LENGTH_UNLIMITED + LENGTH_UNLIMITED + + + 0 + + + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + SHARED_OWNERSHIP_QOS + + + + diff --git a/src/api/dcps/python/test/qos/DDS_QoS_WithoutReader.xml b/src/api/dcps/python/test/qos/DDS_QoS_WithoutReader.xml new file mode 100644 index 000000000..bfea21ea7 --- /dev/null +++ b/src/api/dcps/python/test/qos/DDS_QoS_WithoutReader.xml @@ -0,0 +1,178 @@ + + + + + + VOLATILE_DURABILITY_QOS + + + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + + 0 + 0 + + + + AUTOMATIC_LIVELINESS_QOS + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + RELIABLE_RELIABILITY_QOS + + 0 + 100000000 + + + + BY_RECEPTION_TIMESTAMP_DESTINATIONORDER_QOS + + + KEEP_LAST_HISTORY_QOS + 1 + + + LENGTH_UNLIMITED + LENGTH_UNLIMITED + LENGTH_UNLIMITED + + + 0 + + + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + + + + SHARED_OWNERSHIP_QOS + + + 0 + + + true + + + + + + + + true + + + + + INSTANCE_PRESENTATION_QOS + false + false + + + + + + + + + true + + + + + INSTANCE_PRESENTATION_QOS + false + false + + + + + + + + + true + + + + + + + + VOLATILE_DURABILITY_QOS + + + + 0 + 0 + + KEEP_LAST_HISTORY_QOS + 1 + LENGTH_UNLIMITED + LENGTH_UNLIMITED + LENGTH_UNLIMITED + + + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + + 0 + 0 + + + + AUTOMATIC_LIVELINESS_QOS + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + BEST_EFFORT_RELIABILITY_QOS + + 0 + 100000000 + + + + BY_RECEPTION_TIMESTAMP_DESTINATIONORDER_QOS + + + KEEP_LAST_HISTORY_QOS + 1 + + + LENGTH_UNLIMITED + LENGTH_UNLIMITED + LENGTH_UNLIMITED + + + 0 + + + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + SHARED_OWNERSHIP_QOS + + + + diff --git a/src/api/dcps/python/test/qos/DDS_QoS_WithoutTopic.xml b/src/api/dcps/python/test/qos/DDS_QoS_WithoutTopic.xml new file mode 100644 index 000000000..856acbccf --- /dev/null +++ b/src/api/dcps/python/test/qos/DDS_QoS_WithoutTopic.xml @@ -0,0 +1,174 @@ + + + + + + VOLATILE_DURABILITY_QOS + + + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + + 0 + 0 + + + + AUTOMATIC_LIVELINESS_QOS + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + BEST_EFFORT_RELIABILITY_QOS + + 0 + 100000000 + + + + BY_RECEPTION_TIMESTAMP_DESTINATIONORDER_QOS + + + KEEP_LAST_HISTORY_QOS + 1 + + + LENGTH_UNLIMITED + LENGTH_UNLIMITED + LENGTH_UNLIMITED + + + + + + SHARED_OWNERSHIP_QOS + + + + 0 + 0 + + + + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + + + VOLATILE_DURABILITY_QOS + + + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + + 0 + 0 + + + + AUTOMATIC_LIVELINESS_QOS + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + RELIABLE_RELIABILITY_QOS + + 0 + 100000000 + + + + BY_RECEPTION_TIMESTAMP_DESTINATIONORDER_QOS + + + KEEP_LAST_HISTORY_QOS + 1 + + + LENGTH_UNLIMITED + LENGTH_UNLIMITED + LENGTH_UNLIMITED + + + 0 + + + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + + + + SHARED_OWNERSHIP_QOS + + + 0 + + + true + + + + + + + + true + + + + + INSTANCE_PRESENTATION_QOS + false + false + + + + + + + + + true + + + + + INSTANCE_PRESENTATION_QOS + false + false + + + + + + + + + true + + + + diff --git a/src/api/dcps/python/test/qos/DDS_QoS_WithoutWriter.xml b/src/api/dcps/python/test/qos/DDS_QoS_WithoutWriter.xml new file mode 100644 index 000000000..33bf3187b --- /dev/null +++ b/src/api/dcps/python/test/qos/DDS_QoS_WithoutWriter.xml @@ -0,0 +1,179 @@ + + + + + + VOLATILE_DURABILITY_QOS + + + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + + 0 + 0 + + + + AUTOMATIC_LIVELINESS_QOS + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + BEST_EFFORT_RELIABILITY_QOS + + 0 + 100000000 + + + + BY_RECEPTION_TIMESTAMP_DESTINATIONORDER_QOS + + + KEEP_LAST_HISTORY_QOS + 1 + + + LENGTH_UNLIMITED + LENGTH_UNLIMITED + LENGTH_UNLIMITED + + + + + + SHARED_OWNERSHIP_QOS + + + + 0 + 0 + + + + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + + + + + + true + + + + + INSTANCE_PRESENTATION_QOS + false + false + + + + + + + + + true + + + + + INSTANCE_PRESENTATION_QOS + false + false + + + + + + + + + true + + + + + + + + VOLATILE_DURABILITY_QOS + + + + 0 + 0 + + KEEP_LAST_HISTORY_QOS + 1 + LENGTH_UNLIMITED + LENGTH_UNLIMITED + LENGTH_UNLIMITED + + + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + + 0 + 0 + + + + AUTOMATIC_LIVELINESS_QOS + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + BEST_EFFORT_RELIABILITY_QOS + + 0 + 100000000 + + + + BY_RECEPTION_TIMESTAMP_DESTINATIONORDER_QOS + + + KEEP_LAST_HISTORY_QOS + 1 + + + LENGTH_UNLIMITED + LENGTH_UNLIMITED + LENGTH_UNLIMITED + + + 0 + + + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + SHARED_OWNERSHIP_QOS + + + + diff --git a/src/api/dcps/python/test/qos/DDS_VolatileQoS_All.xml b/src/api/dcps/python/test/qos/DDS_VolatileQoS_All.xml new file mode 100644 index 000000000..040b2949b --- /dev/null +++ b/src/api/dcps/python/test/qos/DDS_VolatileQoS_All.xml @@ -0,0 +1,243 @@ + + + + + + VOLATILE_DURABILITY_QOS + + + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + + 0 + 0 + + + + AUTOMATIC_LIVELINESS_QOS + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + BEST_EFFORT_RELIABILITY_QOS + + 0 + 100000000 + + + + BY_RECEPTION_TIMESTAMP_DESTINATIONORDER_QOS + + + KEEP_LAST_HISTORY_QOS + 100 + + + LENGTH_UNLIMITED + LENGTH_UNLIMITED + LENGTH_UNLIMITED + + + + + + SHARED_OWNERSHIP_QOS + + + + 0 + 0 + + + + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + + + VOLATILE_DURABILITY_QOS + + + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + + 0 + 0 + + + + AUTOMATIC_LIVELINESS_QOS + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + RELIABLE_RELIABILITY_QOS + + 0 + 100000000 + + + + BY_RECEPTION_TIMESTAMP_DESTINATIONORDER_QOS + + + KEEP_LAST_HISTORY_QOS + 100 + + + LENGTH_UNLIMITED + LENGTH_UNLIMITED + LENGTH_UNLIMITED + + + 0 + + + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + + + + SHARED_OWNERSHIP_QOS + + + 0 + + + true + + + + + + + + true + + + + + INSTANCE_PRESENTATION_QOS + false + false + + + + + + + + + true + + + + + INSTANCE_PRESENTATION_QOS + false + false + + + + + + + + + true + + + + + + + + VOLATILE_DURABILITY_QOS + + + + 3600 + 0 + + KEEP_LAST_HISTORY_QOS + 100 + 8192 + 4196 + 8192 + + + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + + 0 + 0 + + + + AUTOMATIC_LIVELINESS_QOS + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + BEST_EFFORT_RELIABILITY_QOS + + 0 + 100000000 + + + + BY_RECEPTION_TIMESTAMP_DESTINATIONORDER_QOS + + + KEEP_LAST_HISTORY_QOS + 100 + + + LENGTH_UNLIMITED + LENGTH_UNLIMITED + LENGTH_UNLIMITED + + + 0 + + + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + SHARED_OWNERSHIP_QOS + + + + diff --git a/src/api/dcps/python/test/qos/DDS_VolatileQoS_Reader.xml b/src/api/dcps/python/test/qos/DDS_VolatileQoS_Reader.xml new file mode 100644 index 000000000..e5d7ff15a --- /dev/null +++ b/src/api/dcps/python/test/qos/DDS_VolatileQoS_Reader.xml @@ -0,0 +1,70 @@ + + + + + + VOLATILE_DURABILITY_QOS + + + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + + 0 + 0 + + + + AUTOMATIC_LIVELINESS_QOS + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + BEST_EFFORT_RELIABILITY_QOS + + 0 + 100000000 + + + + BY_RECEPTION_TIMESTAMP_DESTINATIONORDER_QOS + + + KEEP_LAST_HISTORY_QOS + 100 + + + LENGTH_UNLIMITED + LENGTH_UNLIMITED + LENGTH_UNLIMITED + + + + + + SHARED_OWNERSHIP_QOS + + + + 0 + 0 + + + + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + + diff --git a/src/api/dcps/python/test/qos/DDS_VolatileQoS_Topic.xml b/src/api/dcps/python/test/qos/DDS_VolatileQoS_Topic.xml new file mode 100644 index 000000000..f0f0e76a1 --- /dev/null +++ b/src/api/dcps/python/test/qos/DDS_VolatileQoS_Topic.xml @@ -0,0 +1,74 @@ + + + + + + + + + VOLATILE_DURABILITY_QOS + + + + 3600 + 0 + + KEEP_LAST_HISTORY_QOS + 100 + 8192 + 4196 + 8192 + + + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + + 0 + 0 + + + + AUTOMATIC_LIVELINESS_QOS + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + BEST_EFFORT_RELIABILITY_QOS + + 0 + 100000000 + + + + BY_RECEPTION_TIMESTAMP_DESTINATIONORDER_QOS + + + KEEP_LAST_HISTORY_QOS + 100 + + + LENGTH_UNLIMITED + LENGTH_UNLIMITED + LENGTH_UNLIMITED + + + 0 + + + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + SHARED_OWNERSHIP_QOS + + + + diff --git a/src/api/dcps/python/test/qos/DDS_VolatileQoS_Writer.xml b/src/api/dcps/python/test/qos/DDS_VolatileQoS_Writer.xml new file mode 100644 index 000000000..ae2d60f7e --- /dev/null +++ b/src/api/dcps/python/test/qos/DDS_VolatileQoS_Writer.xml @@ -0,0 +1,69 @@ + + + + + + VOLATILE_DURABILITY_QOS + + + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + + 0 + 0 + + + + AUTOMATIC_LIVELINESS_QOS + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + RELIABLE_RELIABILITY_QOS + + 0 + 100000000 + + + + BY_RECEPTION_TIMESTAMP_DESTINATIONORDER_QOS + + + KEEP_LAST_HISTORY_QOS + 100 + + + LENGTH_UNLIMITED + LENGTH_UNLIMITED + LENGTH_UNLIMITED + + + 0 + + + + DURATION_INFINITE_SEC + DURATION_INFINITE_NSEC + + + + + + + SHARED_OWNERSHIP_QOS + + + 0 + + + true + + + + diff --git a/src/api/dcps/python/test/resources/expectedFail.txt b/src/api/dcps/python/test/resources/expectedFail.txt new file mode 100644 index 000000000..e69de29bb diff --git a/src/api/dcps/python/test/runAllPyUnitTests.py b/src/api/dcps/python/test/runAllPyUnitTests.py new file mode 100644 index 000000000..7e35f32f5 --- /dev/null +++ b/src/api/dcps/python/test/runAllPyUnitTests.py @@ -0,0 +1,67 @@ +# +# Vortex OpenSplice +# +# This software and documentation are Copyright 2006 to TO_YEAR ADLINK +# Technology Limited, its affiliated companies and licensors. All rights +# reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import unittest +import os +import sys +import re +import subprocess + +def package_contents(): + files = os.listdir() + # Use a set because some may be both source and compiled. + print(files) + return set([os.path.splitext(module)[0] + for module in files + if re.match(r'[tT]est.*\.py', module)]) + +def compile_idl(): + idl_dir = 'idl' + idlfiles = [os.path.join(idl_dir,f) for f in os.listdir(path=idl_dir) if os.path.isfile(os.path.join(idl_dir,f)) and f.endswith('.idl')] + idlfiles.append(os.getenv('OSPL_HOME_NORMALIZED') + '/etc/idl/dds_IoTData.idl') + for f in idlfiles: + print('Compiling %s' % f) + retcode = subprocess.call(['idlpp','-l','python', f]) + print(' returned ', retcode) + +def all_tests(): + suite = unittest.TestSuite() + testmodules = package_contents() + print(testmodules) + for t in testmodules: + try: + # If the module defines a suite() function, call it to get the suite. + mod = __import__(t, globals(), locals(), ['suite']) + suitefn = getattr(mod, 'suite') + suite.addTest(suitefn()) + except (ImportError, AttributeError): + # else, just load all the test cases from the module. + suite.addTest(unittest.defaultTestLoader.loadTestsFromName(t)) + if dbt_testrun: + xmlrunner.XMLTestRunner(output='test-reports').run(suite) + else: + unittest.TextTestRunner().run(suite) + +if __name__ == '__main__': + dbt_testrun = False + if '--dbt' in sys.argv: + import xmlrunner + dbt_testrun = True + compile_idl() + all_tests() diff --git a/src/api/dcps/python/test/testArray.py b/src/api/dcps/python/test/testArray.py new file mode 100644 index 000000000..ea3f0bd72 --- /dev/null +++ b/src/api/dcps/python/test/testArray.py @@ -0,0 +1,58 @@ +# +# Vortex OpenSplice +# +# This software and documentation are Copyright 2006 to TO_YEAR ADLINK +# Technology Limited, its affiliated companies and licensors. All rights +# reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +''' +Created on Dec 7, 2017 + +@author: prismtech +''' +import unittest +import struct +import countTest + +if countTest.count_test == False: + import Array.basic.module_Array + + +class TestArray(unittest.TestCase): + + + def testCopyInCopyOut(self): + data = Array.basic.module_Array.Array_struct(long1 = 21, array1=[3.2,4.5,9.8]) + + print('data: ' + str(data)) + + print('data._get_packing_fmt(): ', data._get_packing_fmt()) + print('data._get_packing_args(): ', data._get_packing_args()) + buffer = data._serialize() + print('buffer: ', buffer) + + values = struct.unpack(data._get_packing_fmt(), buffer) + data1 = Array.basic.module_Array.Array_struct() + data1._deserialize(list(values)) + + self.assertEqual(data.long1, data1.long1) + self.assertEqual(data.array1[0], data1.array1[0]) + self.assertEqual(data.array1[1], data1.array1[1]) + self.assertEqual(data.array1[2], data1.array1[2]) + + +if __name__ == "__main__": + #import sys;sys.argv = ['', 'Test.testCopyInCopyOut'] + unittest.main() \ No newline at end of file diff --git a/src/api/dcps/python/test/testArrayOfStruct.py b/src/api/dcps/python/test/testArrayOfStruct.py new file mode 100644 index 000000000..e6b2a8aa5 --- /dev/null +++ b/src/api/dcps/python/test/testArrayOfStruct.py @@ -0,0 +1,62 @@ +# +# Vortex OpenSplice +# +# This software and documentation are Copyright 2006 to TO_YEAR ADLINK +# Technology Limited, its affiliated companies and licensors. All rights +# reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +''' +Created on Dec 7, 2017 + +@author: prismtech +''' +import unittest +import struct +import countTest + +if countTest.count_test == False: + import ArrayOfStruct.basic.module_ArrayOfStruct + +class TestArrayOfStruct(unittest.TestCase): + + + def testCopyInCopyOut(self): + data = ArrayOfStruct.basic.module_ArrayOfStruct.ArrayOfStruct_struct( + long1 = 12, + array1=[ArrayOfStruct.basic.module_ArrayOfStruct.Inner(long1=21,double1=2.5), + ArrayOfStruct.basic.module_ArrayOfStruct.Inner(long1=31,double1=3.5)], + mylong1 = 42) + print('data: ' + str(data)) + + print('data._get_packing_fmt(): ', data._get_packing_fmt()) + print('data._get_packing_args(): ', data._get_packing_args()) + buffer = data._serialize() + print('buffer: ', buffer) + + values = struct.unpack(data._get_packing_fmt(), buffer) + data1 = ArrayOfStruct.basic.module_ArrayOfStruct.ArrayOfStruct_struct() + data1._deserialize(list(values)) + + self.assertEqual(data.long1, data1.long1) + self.assertEqual(data.array1[0].long1, data1.array1[0].long1) + self.assertEqual(data.array1[0].double1, data1.array1[0].double1) + self.assertEqual(data.array1[1].long1, data1.array1[1].long1) + self.assertEqual(data.array1[1].double1, data1.array1[1].double1) + self.assertEqual(data.mylong1, data1.mylong1) + + +if __name__ == "__main__": + #import sys;sys.argv = ['', 'Test.testCopyInCopyOut'] + unittest.main() \ No newline at end of file diff --git a/src/api/dcps/python/test/testEnum2.py b/src/api/dcps/python/test/testEnum2.py new file mode 100644 index 000000000..d4ca07d41 --- /dev/null +++ b/src/api/dcps/python/test/testEnum2.py @@ -0,0 +1,66 @@ +# +# Vortex OpenSplice +# +# This software and documentation are Copyright 2006 to TO_YEAR ADLINK +# Technology Limited, its affiliated companies and licensors. All rights +# reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +''' +Created on Dec 4, 2017 + +@author: prismtech +''' +import unittest +import struct +import countTest + +if countTest.count_test == False: + import Enum2.basic.module_Enum2 + import Enum2.basic.enumZ + + +class TestEnum2(unittest.TestCase): + + + def testCopyInCopyOut(self): + data = Enum2.basic.module_Enum2.Enum2_struct( + long1=11, + color1=Enum2.basic.module_Enum2.Color.Blue, + color2=Enum2.basic.enumZ.Color.Green, + array=[Enum2.basic.enumZ.Color.Red, Enum2.basic.enumZ.Color.Green] + ) + + print('data: ' + str(data)) + + print('data._get_packing_fmt(): ', data._get_packing_fmt()) + print('data._get_packing_args(): ', data._get_packing_args()) + buffer = data._serialize() + print('buffer: ', buffer) + + values = struct.unpack(data._get_packing_fmt(), buffer) + data1 = Enum2.basic.module_Enum2.Enum2_struct() + data1._deserialize(list(values)) + + self.assertEqual(data.long1, data1.long1) + self.assertEqual(data.color1, data1.color1) + self.assertEqual(data.color2, data1.color2) + self.assertEqual(len(data.array), len(data1.array)) + self.assertEqual(data.array[0], data1.array[0]) + self.assertEqual(data.array[1], data1.array[1]) + + +if __name__ == "__main__": + #import sys;sys.argv = ['', 'Test.testName'] + unittest.main() \ No newline at end of file diff --git a/src/api/dcps/python/test/testNestedStruct.py b/src/api/dcps/python/test/testNestedStruct.py new file mode 100644 index 000000000..dae15e5e8 --- /dev/null +++ b/src/api/dcps/python/test/testNestedStruct.py @@ -0,0 +1,60 @@ +# +# Vortex OpenSplice +# +# This software and documentation are Copyright 2006 to TO_YEAR ADLINK +# Technology Limited, its affiliated companies and licensors. All rights +# reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +''' +Created on Dec 4, 2017 + +@author: prismtech +''' +import unittest +import struct +import dds +import countTest + +if countTest.count_test == False: + import NestedStruct.basic.module_NestedStruct + + + +class Test(unittest.TestCase): + + + def testCopyInCopyOut(self): + data = NestedStruct.basic.module_NestedStruct.NestedStruct_struct( + long1=11, + inner1=NestedStruct.basic.module_NestedStruct.Inner(long1=21, double1=22.2)) + + print('data: ' + str(data)) + + print('data._get_packing_fmt(): ', data._get_packing_fmt()) + buffer = data._serialize() + print('buffer: ', buffer) + + values = struct.unpack(data._get_packing_fmt(), buffer) + data1 = NestedStruct.basic.module_NestedStruct.NestedStruct_struct() + data1._deserialize(list(values)) + + self.assertEqual(data.long1, data1.long1) + self.assertEqual(data.inner1.long1, data1.inner1.long1) + self.assertEqual(data.inner1.double1, data1.inner1.double1) + + +if __name__ == "__main__": + #import sys;sys.argv = ['', 'Test.testName'] + unittest.main() \ No newline at end of file diff --git a/src/api/dcps/python/test/testSimpleTypes.py b/src/api/dcps/python/test/testSimpleTypes.py new file mode 100644 index 000000000..b343b9c31 --- /dev/null +++ b/src/api/dcps/python/test/testSimpleTypes.py @@ -0,0 +1,89 @@ +# +# Vortex OpenSplice +# +# This software and documentation are Copyright 2006 to TO_YEAR ADLINK +# Technology Limited, its affiliated companies and licensors. All rights +# reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +''' +Created on Dec 1, 2017 + +@author: prismtech +''' +import unittest +import struct +import dds +import countTest + +if countTest.count_test == False: + import SimpleTypes.basic.module_SimpleTypes + +class Test(unittest.TestCase): + + + def testName(self): + data = SimpleTypes.basic.module_SimpleTypes.SimpleTypes_struct( + string1='Hello World!', + char1='X', + bool1=True, + octet1=127, + long1=1123) + + print('data: ' + str(data)) + + print('data._get_packing_fmt(): ', data._get_packing_fmt()) + buffer = data._serialize() + print('buffer: ', buffer) + + values = struct.unpack(data._get_packing_fmt(), buffer) + data1 = SimpleTypes.basic.module_SimpleTypes.SimpleTypes_struct() + data1._deserialize(list(values)) + + self.assertEqual(data.string1, data1.string1) + self.assertEqual(data.char1, data1.char1) + self.assertEqual(data.bool1, data1.bool1) + self.assertEqual(data.octet1, data1.octet1) + self.assertEqual(data.long1, data1.long1) + + def testDDSTopic(self): + data = SimpleTypes.basic.module_SimpleTypes.SimpleTypes_struct( + string1='Hello World!', + char1='X', + bool1=True, + octet1=127, + long1=1123) + + dp = dds.DomainParticipant() + qos = None + topic = dds.Topic(dp, 'SimpleTypes', SimpleTypes.basic.module_SimpleTypes.SimpleTypes_struct.get_type_support()) + + self.assertIsNotNone(topic, 'Returned topic must not be None') + + pub = dp.create_publisher() + sub = dp.create_subscriber() + + wr = pub.create_datawriter(topic) + rd = sub.create_datareader(topic) + + wr.write(data) + + rs = rd.take(1) + self.assertEqual(len(rs),1) + + self.assertEqual(str(rs[0][0]), str(data)) + +if __name__ == "__main__": + #import sys;sys.argv = ['', 'Test.testName'] + unittest.main() \ No newline at end of file diff --git a/src/api/dcps/python/test/test_api.py b/src/api/dcps/python/test/test_api.py new file mode 100644 index 000000000..bee1f5dea --- /dev/null +++ b/src/api/dcps/python/test/test_api.py @@ -0,0 +1,105 @@ +# +# Vortex OpenSplice +# +# This software and documentation are Copyright 2006 to TO_YEAR ADLINK +# Technology Limited, its affiliated companies and licensors. All rights +# reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from ddsutil import * +from dds import * +import unittest +import time +import xmlrunner + +type_info_fmt = "basic::module_{}::{}" + +class APITests(unittest.TestCase): + + def setUp(self): + unittest.TestCase.setUp(self) + + def compare_result(self, obj1, obj2): + print("Comparing result:") + obj1.print_vars() + obj2.print_vars() + return self._do_compare_result(obj1, obj2) + + def _do_compare_result(self, obj1, obj2): + if isinstance(obj1, TopicDataClass): + cls1_vars = obj1.get_vars() + cls2_vars = obj2.get_vars() + return self._do_compare_result(list(cls1_vars.values()), list(cls2_vars.values())) + + if isinstance(obj1, list): + for i in range(len(obj1)): + if not self._do_compare_result(obj1[i], obj2[i]): + return False + else: + if not obj1 == obj2: + return False + return True + + def test_waitset(self): + + qp = QosProfile('file://qos/DDS_DefaultQoS_All.xml', 'DDS DefaultQosProfile') + + # Create participant + dp = DomainParticipant(qos=qp.get_participant_qos()) + + # Create publisher + pub = dp.create_publisher(qp.get_publisher_qos()) + + # Create Subscriber + sub = dp.create_subscriber(qp.get_subscriber_qos()) + + idl_name = 'MultiArrayBasicType' + idl_path = 'idl/' + idl_name + '.idl' + type_info = type_info_fmt.format(idl_name, idl_name + '_struct') + + gen_info = get_dds_classes_from_idl(idl_path, type_info) + Sample = gen_info.topic_data_class + SampleTypeSupport = gen_info.type_support_class + + ts = SampleTypeSupport() + topic = Topic(dp, 'MultiArrayBasicType1', ts, qp.get_topic_qos()) + writer = DataWriter(pub, topic, qp.get_writer_qos()) + reader2 = DataReader(sub, topic, qp.get_reader_qos()) + + waitset = WaitSet() + condition = StatusCondition(reader2) + + waitset.attach(condition) + + s = Sample(long1 = 4, array1=[[[1,2],[2,3],[3,4]],[[11,22],[22,33],[33,44]]]) + writer.write(s) + time.sleep(1) + + conditions = waitset.wait(DDSDuration(5)) + + l = reader2.take(1) + sd, si = l[0] + self.assertTrue(self.compare_result(s, sd)) + + + @classmethod + def setUpClass(cls): + super(APITests, cls).setUpClass() + + +if __name__ == '__main__': + unittest.main(testRunner=xmlrunner.XMLTestRunner(output='test-reports'), + # these make sure that some options that are not applicable + # remain hidden from the help menu. + failfast=False, buffer=False, catchbreak=False) diff --git a/src/api/dcps/python/test/test_builtin.py b/src/api/dcps/python/test/test_builtin.py new file mode 100644 index 000000000..f3dee57ab --- /dev/null +++ b/src/api/dcps/python/test/test_builtin.py @@ -0,0 +1,98 @@ +# +# Vortex OpenSplice +# +# This software and documentation are Copyright 2006 to TO_YEAR ADLINK +# Technology Limited, its affiliated companies and licensors. All rights +# reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from ddsutil import * +from dds import * +import unittest +import time +import xmlrunner + +TOPIC_NAMES=['DCPSParticipant', 'DCPSTopic', 'DCPSPublication', 'DCPSSubscription', + 'CMParticipant', 'CMPublisher', 'CMSubscriber', 'CMDataWriter', 'CMDataReader', 'DCPSType'] +topics=[] +dp=None + +# Data available listener +class DataAvailableListener(Listener): + def __init__(self, holder): + Listener.__init__(self) + self.holder = holder + + def on_data_available(self, entity): + try: + l = entity.read(1) + for (sd, si) in l: + if si.valid_data: + sd.print_vars() + self.holder.result = str(sd) + except Exception as ex: + self.holder.result = ex + +class ResultHolder(object): + + def __init__(self, tname): + self.result = '' + self.tname = tname + +class Test(unittest.TestCase): + + def setUp(self): + pass + + + def tearDown(self): + pass + + + def testCreateBuiltinTopics(self): + global dp + dp = DomainParticipant() + for tname in TOPIC_NAMES: + try: + ft = dp.find_topic(tname) + t = register_found_topic_as_local(ft) + gen_info = get_dds_classes_for_found_topic(ft) + topics.append(t) + except DDSException: + self.assertFalse('built-in topic registration threw exception') + + def testReadBuiltinTopics(self): + sub = dp.create_subscriber(Qos([PartitionQosPolicy(['__BUILT-IN PARTITION__'])])) + results = [] + for t in topics: + try: + result_holder = ResultHolder(t.name) + results.append(result_holder) + rd = sub.create_datareader(t, + Qos([DurabilityQosPolicy(DDSDurabilityKind.TRANSIENT)]), + DataAvailableListener(result_holder)) + except Exception: + self.assertFalse('sub.create_datareader threw exception') + + time.sleep(1) + for result in results: + self.assertFalse(isinstance(result_holder.result, Exception), 'Exception occurred while reading built in topic data') + self.assertTrue(len(result_holder.result) == 0 or result.tname == 'DCPSType', 'Read results contain no data') + # DCPSType not included due to no data available in fresh system + +if __name__ == "__main__": + unittest.main(testRunner=xmlrunner.XMLTestRunner(output='test-reports'), + # these make sure that some options that are not applicable + # remain hidden from the help menu. + failfast=False, buffer=False, catchbreak=False) \ No newline at end of file diff --git a/src/api/dcps/python/test/test_classGeneration.py b/src/api/dcps/python/test/test_classGeneration.py new file mode 100644 index 000000000..9739c0736 --- /dev/null +++ b/src/api/dcps/python/test/test_classGeneration.py @@ -0,0 +1,60 @@ +# +# Vortex OpenSplice +# +# This software and documentation are Copyright 2006 to TO_YEAR ADLINK +# Technology Limited, its affiliated companies and licensors. All rights +# reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import sys +sys.path.append('../dds') +from ddsutil import * +import unittest +import xmlrunner + +class DynamicClassGenerationTests(unittest.TestCase): + + def test_basic_types(self): + self.dynamic_create_test("SimpleTypes") + + def test_nested_struct(self): + self.dynamic_create_test("NestedStruct") + + def test_array(self): + self.dynamic_create_test("Array") + + def test_sequence(self): + self.dynamic_create_test("Sequence") + + def test_nested_struct_array(self): + self.dynamic_create_test("ArrayOfStruct") + + def test_nested_struct_sequence(self): + self.dynamic_create_test("SequenceOfStruct") + + def dynamic_create_test(self, idl_name): + + idl_path = 'idl/' + idl_name + '.idl' + type_info = "basic::module_{}::{}".format(idl_name, idl_name + '_struct') + gen_info = get_dds_classes_from_idl(idl_path, type_info) + Sample = gen_info.topic_data_class + SampleType = gen_info.type_support_class + s = Sample() + self.assertIsNotNone(Sample, "Topic data class not created") + self.assertIsNotNone(SampleType, "Topic support class not created") +if __name__ == '__main__': + unittest.main(testRunner=xmlrunner.XMLTestRunner(output='test-reports'), + # these make sure that some options that are not applicable + # remain hidden from the help menu. + failfast=False, buffer=False, catchbreak=False) \ No newline at end of file diff --git a/src/api/dcps/python/test/test_close.py b/src/api/dcps/python/test/test_close.py new file mode 100644 index 000000000..01b4e063d --- /dev/null +++ b/src/api/dcps/python/test/test_close.py @@ -0,0 +1,128 @@ +# +# Vortex OpenSplice +# +# This software and documentation are Copyright 2006 to TO_YEAR ADLINK +# Technology Limited, its affiliated companies and licensors. All rights +# reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from ddsutil import * +from dds import * +import unittest + +class CloseTests(unittest.TestCase): + + def setUp(self): + unittest.TestCase.setUp(self) + + def _check(self, entity, closed): + try: + entity._check_handle() + self.assertTrue(not closed) + except DDSException as e: + self.assertTrue(closed) + + def check_closed(self, entity): + self._check(entity, True) + + def check_not_closed(self, entity): + self._check(entity, False) + + def test_close_individual(self): + gen_info = get_dds_classes_from_idl('idl/SimpleTypes.idl', 'basic::module_SimpleTypes::SimpleTypes_struct') + dp = DomainParticipant() + pub = dp.create_publisher() + sub = dp.create_subscriber() + topic = gen_info.register_topic(dp, 'simpletopic') + writer = pub.create_datawriter(topic) + reader = sub.create_datareader(topic) + + self.check_not_closed(dp) + self.check_not_closed(pub) + self.check_not_closed(sub) + self.check_not_closed(topic) + self.check_not_closed(writer) + self.check_not_closed(reader) + + reader.close() + self.check_closed(reader) + sub.close() + self.check_closed(sub) + writer.close() + self.check_closed(writer) + pub.close() + self.check_closed(pub) + topic.close() + self.check_closed(topic) + dp.close() + self.check_closed(dp) + + def test_close_individual_w_default_pub_sub(self): + gen_info = get_dds_classes_from_idl('idl/SimpleTypes.idl', 'basic::module_SimpleTypes::SimpleTypes_struct') + dp = DomainParticipant() + topic = gen_info.register_topic(dp, 'simpletopic') + writer = dp.create_datawriter(topic) + reader = dp.create_datareader(topic) + + self.check_not_closed(dp) + self.check_not_closed(topic) + self.check_not_closed(writer) + self.check_not_closed(reader) + + reader.close() + self.check_closed(reader) + writer.close() + self.check_closed(writer) + topic.close() + self.check_closed(topic) + dp.close() + self.check_closed(dp) + + def test_close_recursive(self): + gen_info = get_dds_classes_from_idl('idl/SimpleTypes.idl', 'basic::module_SimpleTypes::SimpleTypes_struct') + dp = DomainParticipant() + pub = dp.create_publisher() + sub = dp.create_subscriber() + topic = gen_info.register_topic(dp, 'simpletopic2') + writer = pub.create_datawriter(topic) + reader = sub.create_datareader(topic) + + dp.close() + self.check_closed(dp) + self.check_closed(pub) + self.check_closed(sub) + self.check_closed(topic) + self.check_closed(writer) + self.check_closed(reader) + + def test_close_recursive_w_default_pub_sub(self): + gen_info = get_dds_classes_from_idl('idl/SimpleTypes.idl', 'basic::module_SimpleTypes::SimpleTypes_struct') + dp = DomainParticipant() + topic = gen_info.register_topic(dp, 'simpletopic2') + writer = dp.create_datawriter(topic) + reader = dp.create_datareader(topic) + + dp.close() + self.check_closed(dp) + self.check_closed(topic) + self.check_closed(writer) + self.check_closed(reader) + + @classmethod + def setUpClass(cls): + super(CloseTests, cls).setUpClass() + + +if __name__ == '__main__': + unittest.main() diff --git a/src/api/dcps/python/test/test_copy_in_out.py b/src/api/dcps/python/test/test_copy_in_out.py new file mode 100644 index 000000000..ee1cb158e --- /dev/null +++ b/src/api/dcps/python/test/test_copy_in_out.py @@ -0,0 +1,591 @@ +# +# Vortex OpenSplice +# +# This software and documentation are Copyright 2006 to TO_YEAR ADLINK +# Technology Limited, its affiliated companies and licensors. All rights +# reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from ddsutil import * +from ddsutil import _class_dict +import unittest +import time +import xmlrunner + +type_info_fmt = "basic::module_{}::{}" + +class CopyInOutTests(unittest.TestCase): + + def setUp(self): + unittest.TestCase.setUp(self) + _class_dict.clear() + + def compare_result(self, obj1, obj2): + print("Comparing result:") + obj1.print_vars() + obj2.print_vars() + return self._do_compare_result(obj1, obj2) + + def _do_compare_result(self, obj1, obj2): + if isinstance(obj1, TopicDataClass): + cls1_vars = obj1.get_vars() + cls2_vars = obj2.get_vars() + return self._do_compare_result(list(cls1_vars.values()), list(cls2_vars.values())) + + if isinstance(obj1, list): + for i in range(len(obj1)): + if not self._do_compare_result(obj1[i], obj2[i]): + return False + else: + if not obj1 == obj2: + return False + return True + + def test_multi_array_basic_type(self): + idl_name = 'MultiArrayBasicType' + idl_path = 'idl/' + idl_name + '.idl' + type_info = type_info_fmt.format(idl_name, idl_name + '_struct') + + gen_info = get_dds_classes_from_idl(idl_path, type_info) + topic = gen_info.register_topic(self.dp, idl_name, self.qos) + + writer = dds.DataWriter(self.pub, topic, self.qos) + reader2 = dds.DataReader(self.sub, topic, self.qos) + + waitset = dds.WaitSet() + condition = dds.StatusCondition(reader2) + + waitset.attach(condition) + + s = gen_info.topic_data_class(long1 = 4, array1=[[[1,2],[2,3],[3,4]],[[11,22],[22,33],[33,44]]]) + writer.write(s) + time.sleep(1) + + conditions = waitset.wait() + + l = reader2.take(1) + sd, si = l[0] + self.assertTrue(self.compare_result(s, sd)) + + def test_array_of_struct(self): + idl_name = 'ArrayOfStruct' + idl_path = 'idl/' + idl_name + '.idl' + type_info = type_info_fmt.format(idl_name, idl_name + '_struct') + + gen_info = get_dds_classes_from_idl(idl_path, type_info) + Sample = gen_info.topic_data_class + SampleTypeSupport = gen_info.type_support_class + ts = SampleTypeSupport() + topic = dds.Topic(self.dp, idl_name, ts, self.qos) + writer = dds.DataWriter(self.pub, topic, self.qos) + reader2 = dds.DataReader(self.sub, topic, self.qos) + + waitset = dds.WaitSet() + condition = dds.StatusCondition(reader2) + + waitset.attach(condition) + + Inner = gen_info.get_class("basic::module_{}::Inner".format(idl_name)) + inner1 = Inner(long1 = 999, double1=222) + inner2 = Inner(long1 = 777, double1=333) + s = Sample(long1=2, array1 = [inner1, inner2], mylong1=5) + writer.write(s) + time.sleep(1) + + conditions = waitset.wait() + + l = reader2.take(1) + sd, si = l[0] + self.assertTrue(self.compare_result(s, sd)) + + + def test_array_of_struct_sequence(self): + + idl_name = 'ArrayOfStructSequence' + idl_path = 'idl/' + idl_name + '.idl' + type_info = type_info_fmt.format(idl_name, idl_name + '_struct') + + gen_info = get_dds_classes_from_idl(idl_path, type_info) + Sample = gen_info.topic_data_class + SampleTypeSupport = gen_info.type_support_class + ts = SampleTypeSupport() + topic = dds.Topic(self.dp, idl_name, ts, self.qos) + writer = dds.DataWriter(self.pub, topic, self.qos) + reader2 = dds.DataReader(self.sub, topic, self.qos) + + waitset = dds.WaitSet() + condition = dds.StatusCondition(reader2) + + waitset.attach(condition) + + + Inner = gen_info.get_class("basic::module_{}::Inner".format(idl_name)) + inner1 = Inner(short1 = 1, double1=1) + inner2 = Inner(short1 = 2, double1=2) + inner3 = Inner(short1 = 3, double1=3) + inner4 = Inner(short1 = 4, double1=4) + inner5 = Inner(short1 = 5, double1=5) + + s = Sample(long1 = 4, array1 = [[inner1,inner2,inner3], [inner4,inner5]]) + + writer.write(s) + time.sleep(1) + + conditions = waitset.wait() + + l = reader2.take(1) + sd, si = l[0] + self.assertTrue(self.compare_result(s, sd)) + + def test_array_of_simple_sequence(self): + + idl_name = 'ArrayOfSimpleSequence' + idl_path = 'idl/' + idl_name + '.idl' + type_info = type_info_fmt.format(idl_name, idl_name + '_struct') + + gen_info = get_dds_classes_from_idl(idl_path, type_info) + Sample = gen_info.topic_data_class + SampleTypeSupport = gen_info.type_support_class + ts = SampleTypeSupport() + topic = dds.Topic(self.dp, idl_name, ts, self.qos) + writer = dds.DataWriter(self.pub, topic, self.qos) + reader2 = dds.DataReader(self.sub, topic, self.qos) + + waitset = dds.WaitSet() + condition = dds.StatusCondition(reader2) + + waitset.attach(condition) + + s = Sample(long1 = 4, array1 = [[1,2,3], [4,5]]) + + writer.write(s) + time.sleep(1) + + conditions = waitset.wait() + + l = reader2.take(1) + sd, si = l[0] + self.assertTrue(self.compare_result(s, sd)) + + def test_sequence_of_simple_array(self): + + idl_name = 'SequenceOfSimpleArray' + idl_path = 'idl/' + idl_name + '.idl' + type_info = type_info_fmt.format(idl_name, idl_name + '_struct') + + gen_info = get_dds_classes_from_idl(idl_path, type_info) + Sample = gen_info.topic_data_class + SampleTypeSupport = gen_info.type_support_class + ts = SampleTypeSupport() + topic = dds.Topic(self.dp, idl_name, ts, self.qos) + writer = dds.DataWriter(self.pub, topic, self.qos) + reader2 = dds.DataReader(self.sub, topic, self.qos) + + waitset = dds.WaitSet() + condition = dds.StatusCondition(reader2) + + waitset.attach(condition) + + s = Sample(long1 = 4, sequence1 = [[1,2], [3,4]]) + + writer.write(s) + time.sleep(1) + + conditions = waitset.wait() + + l = reader2.take(1) + sd, si = l[0] + self.assertTrue(self.compare_result(s, sd)) + + def test_sequence_of_struct_array(self): + + idl_name = 'SequenceOfStructArray' + idl_path = 'idl/' + idl_name + '.idl' + type_info = type_info_fmt.format(idl_name, idl_name + '_struct') + + gen_info = get_dds_classes_from_idl(idl_path, type_info) + Sample = gen_info.topic_data_class + SampleTypeSupport = gen_info.type_support_class + ts = SampleTypeSupport() + topic = dds.Topic(self.dp, idl_name, ts, self.qos) + writer = dds.DataWriter(self.pub, topic, self.qos) + reader2 = dds.DataReader(self.sub, topic, self.qos) + + waitset = dds.WaitSet() + condition = dds.StatusCondition(reader2) + + waitset.attach(condition) + + + Inner = gen_info.get_class("basic::module_{}::Inner".format(idl_name)) + inner1 = Inner(short1 = 1, double1=1) + inner2 = Inner(short1 = 2, double1=2) + inner3 = Inner(short1 = 3, double1=3) + inner4 = Inner(short1 = 4, double1=4) + inner5 = Inner(short1 = 5, double1=5) + inner6 = Inner(short1 = 6, double1=6) + + s = Sample(long1 = 4, seq1 = [[inner1,inner2], [inner3,inner4], [inner5, inner6]]) + + writer.write(s) + time.sleep(1) + + conditions = waitset.wait() + + l = reader2.take(1) + sd, si = l[0] + self.assertTrue(self.compare_result(s, sd)) + + def test_sequence_of_struct(self): + + idl_name = 'SequenceOfStruct' + idl_path = 'idl/' + idl_name + '.idl' + type_info = type_info_fmt.format(idl_name, idl_name + '_struct') + + gen_info = get_dds_classes_from_idl(idl_path, type_info) + Sample = gen_info.topic_data_class + SampleTypeSupport = gen_info.type_support_class + ts = SampleTypeSupport() + topic = dds.Topic(self.dp, idl_name, ts, self.qos) + writer = dds.DataWriter(self.pub, topic, self.qos) + reader2 = dds.DataReader(self.sub, topic, self.qos) + + waitset = dds.WaitSet() + condition = dds.StatusCondition(reader2) + + waitset.attach(condition) + + Inner = gen_info.get_class("basic::module_{}::Inner".format(idl_name)) + inner1 = Inner(short1 = 999, double1=222) + inner2 = Inner(short1 = 777, double1=333) + s = Sample(long1=2, seq1 = [inner1, inner2]) + writer.write(s) + time.sleep(1) + + conditions = waitset.wait() + + l = reader2.take(1) + sd, si = l[0] + self.assertTrue(self.compare_result(s, sd)) + + def test_string_types(self): + idl_name = 'StringTypes' + idl_path = 'idl/' + idl_name + '.idl' + type_info = type_info_fmt.format(idl_name, idl_name + '_struct') + + gen_info = get_dds_classes_from_idl(idl_path, type_info) + Sample = gen_info.topic_data_class + SampleTypeSupport = gen_info.type_support_class + ts = SampleTypeSupport() + topic = dds.Topic(self.dp, idl_name, ts, self.qos) + writer = dds.DataWriter(self.pub, topic, self.qos) + reader2 = dds.DataReader(self.sub, topic, self.qos) + + waitset = dds.WaitSet() + condition = dds.StatusCondition(reader2) + + waitset.attach(condition) + + s = Sample( + long1 = 4, + string1 = 'Hello World', + string2 = 'Five5', + string_array = ['This', 'that', 'the other'], + string_seq1 = ['Fee', 'Fi', 'Foe', 'Fum'], + string_seq2 = ['Seven', 'Eleve'] + ) + writer.write(s) + time.sleep(1) + + conditions = waitset.wait() + + l = reader2.take(1) + sd, si = l[0] + self.assertTrue(self.compare_result(s, sd)) + + def test_simple_types(self): + idl_name = 'SimpleTypes' + idl_path = 'idl/' + idl_name + '.idl' + type_info = type_info_fmt.format(idl_name, idl_name + '_struct') + + gen_info = get_dds_classes_from_idl(idl_path, type_info) + Sample = gen_info.topic_data_class + SampleTypeSupport = gen_info.type_support_class + ts = SampleTypeSupport() + topic = dds.Topic(self.dp, 'test_simple_types' + idl_name, ts, self.qos) + writer = dds.DataWriter(self.pub, topic, self.qos) + reader2 = dds.DataReader(self.sub, topic, self.qos) + + waitset = dds.WaitSet() + condition = dds.StatusCondition(reader2) + + waitset.attach(condition) + + s = Sample( + long1 = 0x01020304, + ulong1 = 0x04030201, + longlong1 = 0x0102030405060708, + ulonglong1 = 0x0807060504030201, + float1 = 1.00, + short1 = 0x0102, + ushort1 = 0x0201, + char1 = 'Z', + octet1 = 13, + double1 = 4.00, + bool1 = True, + string1 = 'Hello World!', + ) + writer.write(s) + time.sleep(1) + + conditions = waitset.wait() + + l = reader2.take(1) + sd, si = l[0] + self.assertTrue(self.compare_result(s, sd)) + + def test_enum(self): + + idl_name = 'Enum2' + idl_path = 'idl/' + idl_name + '.idl' + type_info = type_info_fmt.format(idl_name, idl_name + '_struct') + + gen_info = get_dds_classes_from_idl(idl_path, type_info) + Sample = gen_info.topic_data_class + SampleTypeSupport = gen_info.type_support_class + ts = SampleTypeSupport() + topic = dds.Topic(self.dp, idl_name, ts, self.qos) + writer = dds.DataWriter(self.pub, topic, self.qos) + reader2 = dds.DataReader(self.sub, topic, self.qos) + + waitset = dds.WaitSet() + condition = dds.StatusCondition(reader2) + + waitset.attach(condition) + + ColorA = gen_info.get_class("basic::module_Enum2::Color") + ColorZ = gen_info.get_class("basic::enumZ::Color") + s = Sample(long1 = 4, color1 = ColorA.Green, color2=ColorZ.Blue, array=[ColorZ.Red, ColorZ.Blue]) + writer.write(s) + time.sleep(1) + + conditions = waitset.wait() + + l = reader2.take(1) + sd, si = l[0] + self.assertTrue(self.compare_result(s, sd)) + + def test_user_idl01(self): + + idl_name = 'TestIDL2' + idl_path = '../test/idl/' + idl_name + '.idl' + type_info = "VDM::SYS::SYS_ApplicationWindowState" + + gen_info = get_dds_classes_from_idl(idl_path, type_info) + Sample = gen_info.topic_data_class + SampleTypeSupport = gen_info.type_support_class + ts = SampleTypeSupport() + topic = dds.Topic(self.dp, "SYS_ApplicationWindowState", ts, self.qos) + writer = dds.DataWriter(self.pub, topic, self.qos) + reader2 = dds.DataReader(self.sub, topic, self.qos) + + waitset = dds.WaitSet() + condition = dds.StatusCondition(reader2) + + waitset.attach(condition) + + TCOM_AppPosition = gen_info.get_class("VDM::COM::TCOM_AppPosition") + TCOM_AppSize = gen_info.get_class("VDM::COM::TCOM_AppSize") + appPosition = TCOM_AppPosition(m_nX = 1, m_nY=2) + appSize = TCOM_AppSize(m_nWidth = 3, m_nHeight = 4) + s = Sample(m_unApplicationID = 12345678, + m_unOperatorID = 123, + m_tApplicationPosition = appPosition, + m_tApplicationSize = appSize, + m_unWindowState = 112, + m_sContextLevel = "hello dello") + writer.write(s) + time.sleep(1) + + conditions = waitset.wait() + + l = reader2.take(1) + sd, si = l[0] + self.assertTrue(self.compare_result(s, sd)) + + def test_user_idl02(self): + + idl_name = 'TestIDL2' + idl_path = '../test/idl/' + idl_name + '.idl' + type_info = "VDM::HUMS::HUMS_UserActions" + + gen_info = get_dds_classes_from_idl(idl_path, type_info) + Sample = gen_info.topic_data_class + SampleTypeSupport = gen_info.type_support_class + ts = SampleTypeSupport() + topic = dds.Topic(self.dp, "HUMS_UserActions", ts, self.qos) + writer = dds.DataWriter(self.pub, topic, self.qos) + reader2 = dds.DataReader(self.sub, topic, self.qos) + + waitset = dds.WaitSet() + condition = dds.StatusCondition(reader2) + + waitset.attach(condition) + + s = Sample(m_unAppInstanceID = 110, + m_unOperatorID = 111, + m_unUserProfile = 112, + m_unOriginUserAction = 113, + m_unTypeUserAction = 114, + m_sAttributeName = "hello", + m_sAttributeValue = "dello") + writer.write(s) + time.sleep(1) + + conditions = waitset.wait() + + l = reader2.take(1) + sd, si = l[0] + self.assertTrue(self.compare_result(s, sd)) + + def test_basic_struct(self): + + idl_name = 'BasicStruct' + idl_path = '../test/idl/' + idl_name + '.idl' + type_info = "declaration_order::S11" + + gen_info = get_dds_classes_from_idl(idl_path, type_info) + Sample = gen_info.topic_data_class + SampleTypeSupport = gen_info.type_support_class + ts = SampleTypeSupport() + topic = dds.Topic(self.dp, "BasicStruct", ts, self.qos) + writer = dds.DataWriter(self.pub, topic, self.qos) + reader2 = dds.DataReader(self.sub, topic, self.qos) + + waitset = dds.WaitSet() + condition = dds.StatusCondition(reader2) + + waitset.attach(condition) + + s = Sample(xb = 1, + za = 2, + ya = 3, + b = 4, + xa = 5, + yb = 6, + zb = 7, + yc = 8, + a = 9) + writer.write(s) + time.sleep(1) + + conditions = waitset.wait() + + l = reader2.take(1) + sd, si = l[0] + self.assertTrue(self.compare_result(s, sd)) + + def test_lely_example1(self): + + idl_name = 'Lely_example1' + idl_path = '../test/idl/' + idl_name + '.idl' + type_info = "FarmGraph::RoutingDataResult" + + gen_info = get_dds_classes_from_idl(idl_path, type_info) + Sample = gen_info.topic_data_class + SampleTypeSupport = gen_info.type_support_class + ts = SampleTypeSupport() + topic = dds.Topic(self.dp, "RoutingDataResult", ts, self.qos) + writer = dds.DataWriter(self.pub, topic, self.qos) + reader2 = dds.DataReader(self.sub, topic, self.qos) + + waitset = dds.WaitSet() + condition = dds.StatusCondition(reader2) + + waitset.attach(condition) + + FarmGraphEntity = gen_info.get_class('FarmGraph::FarmGraphEntity') + FarmGraphEdge = gen_info.get_class('FarmGraph::FarmGraphEdge') + FarmGraphEntityType = gen_info.get_class('FarmGraph::FarmGraphEntityType') + + entity1 = FarmGraphEntity(identifier="entity1", robot_id=1, + type=FarmGraphEntityType.BLOCKING_GATE) + entity2 = FarmGraphEntity(identifier="entity2", robot_id=2, + type=FarmGraphEntityType.SEGREGATION_GATE) + entity3 = FarmGraphEntity(identifier="entity3", robot_id=3, + type=FarmGraphEntityType.HIGH_PRIORITY_AREA) + + edge1 = FarmGraphEdge(entity_1_identifier="entity1", entity_2_identifier="entity2", + bidirectional=False, position="Forward") + edge2 = FarmGraphEdge(entity_1_identifier="entity2", entity_2_identifier="entity3", + bidirectional=False, position="Backward") + + s = Sample(entities = [entity1, entity2, entity3], edges = [edge1, edge2]) + writer.write(s) + time.sleep(1) + + conditions = waitset.wait() + + l = reader2.take(1) + sd, si = l[0] + self.assertTrue(self.compare_result(s, sd)) + + def test_lely_example2(self): + + idl_name = 'Lely_example1' + idl_path = '../test/idl/' + idl_name + '.idl' + type_info = "SegregationGate" + + gen_info = get_dds_classes_from_idl(idl_path, type_info) + Sample = gen_info.topic_data_class + SampleTypeSupport = gen_info.type_support_class + ts = SampleTypeSupport() + topic = dds.Topic(self.dp, "SegregationGate", ts, self.qos) + writer = dds.DataWriter(self.pub, topic, self.qos) + reader2 = dds.DataReader(self.sub, topic, self.qos) + + waitset = dds.WaitSet() + condition = dds.StatusCondition(reader2) + + waitset.attach(condition) + + LeftRightStates = gen_info.get_class('LeftRightStates') + + s = Sample(output_identifier="output1", state=LeftRightStates.LEFT) + writer.write(s) + time.sleep(1) + + conditions = waitset.wait() + + l = reader2.take(1) + sd, si = l[0] + self.assertTrue(self.compare_result(s, sd)) + + @classmethod + def setUpClass(cls): + super(CopyInOutTests, cls).setUpClass() + durabilityQos = dds.DurabilityQosPolicy(dds.DDSDurabilityKind.TRANSIENT) + historyQos = dds.HistoryQosPolicy(dds.DDSHistoryKind.KEEP_LAST) + cls.qos = dds.Qos([durabilityQos, historyQos]) + cls.dp = dds.DomainParticipant() + cls.pub = pub = dds.Publisher(cls.dp) + cls.sub = dds.Subscriber(cls.dp) + + + +if __name__ == '__main__': + unittest.main(testRunner=xmlrunner.XMLTestRunner(output='test-reports'), + # these make sure that some options that are not applicable + # remain hidden from the help menu. + failfast=False, buffer=False, catchbreak=False) diff --git a/src/api/dcps/python/test/test_dynamic_defaults.py b/src/api/dcps/python/test/test_dynamic_defaults.py new file mode 100644 index 000000000..02461597b --- /dev/null +++ b/src/api/dcps/python/test/test_dynamic_defaults.py @@ -0,0 +1,152 @@ +# +# Vortex OpenSplice +# +# This software and documentation are Copyright 2006 to TO_YEAR ADLINK +# Technology Limited, its affiliated companies and licensors. All rights +# reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +''' +Created on Jan 8, 2018 + +@author: prismtech +''' +import os +import unittest +import ddsutil +import collections + +Info = collections.namedtuple('Info', ['field','def_val']) + +class TestDynamicDefaults(unittest.TestCase): + + def get_idl(self, name, *args): + dds_name = "basic::module_" + name + "::" + name + "_struct" + gci = ddsutil.get_dds_classes_from_idl(os.path.join('idl',name + '.idl'), dds_name) + names = [ name ] + names.extend(args) + dict = {} + for n in names: + dds_name = "basic::module_" + name + "::" + n + if n == name: + dds_name += '_struct' + dict[n] = gci.get_class(dds_name) + return dict + + def check_defaults(self, obj, field_info): + for info in field_info: + f = getattr(obj, info.field) + self.assertIsInstance(f, type(info.def_val), 'Field {} is not expected type'.format(info.field)) + self.assertEqual(f, info.def_val, 'Field {} not expected value'.format(info.field)) + + def testSimpleTypes(self): + types = self.get_idl('SimpleTypes') + data = types['SimpleTypes']() + self.check_defaults(data, [ + Info('long1', 0), + Info('ulong1', 0), + Info('longlong1', 0), + Info('ulonglong1', 0), + Info('float1', 0.0), + Info('short1', 0), + Info('ushort1', 0), + Info('char1', '\x00'), + Info('octet1', 0), + Info('double1', 0.0), + Info('bool1', 0), + Info('string1', ''), + ]) + + def testArray(self): + types = self.get_idl('Array') + data = types['Array']() + + self.check_defaults(data, [ + Info('long1', 0), + Info('array1', [0.0, 0.0, 0.0]), + ]) + + def testArrayOfStruct(self): + types = self.get_idl('ArrayOfStruct', 'Inner') + data = types['ArrayOfStruct']() + Inner = types['Inner'] + + self.check_defaults(data, [ + Info('long1', 0), + Info('mylong1', 0), + ]) + for i in range(2): + self.assertIsInstance(data.array1[i], Inner, 'array1[{}] is not an Inner') + self.check_defaults(data.array1[i], [ + Info('long1', 0), + Info('double1', 0.0), + ]) + + def testArrayOfStructSequence(self): + types = self.get_idl('ArrayOfStructSequence', 'Inner') + data = types['ArrayOfStructSequence']() + + self.check_defaults(data, [ + Info('long1', 0), + Info('array1', [[], []]), + ]) + + def testArrayOfSimpleSequence(self): + types = self.get_idl('ArrayOfSimpleSequence') + data = types['ArrayOfSimpleSequence']() + + self.check_defaults(data, [ + Info('long1', 0), + Info('array1', [[], []]), + ]) + + def testSequence(self): + types = self.get_idl('Sequence') + data = types['Sequence']() + + self.check_defaults(data, [ + Info('long1', 0), + Info('seq1', []), + ]) + + def testSequenceOfSimpleArray(self): + types = self.get_idl('SequenceOfSimpleArray') + data = types['SequenceOfSimpleArray']() + + self.check_defaults(data, [ + Info('long1', 0), + Info('sequence1', []), + ]) + + def testSequenceOfStruct(self): + types = self.get_idl('SequenceOfStruct') + data = types['SequenceOfStruct']() + + self.check_defaults(data, [ + Info('long1', 0), + Info('seq1', []), + ]) + + def testSequenceOfStructArray(self): + types = self.get_idl('SequenceOfStructArray') + data = types['SequenceOfStructArray']() + + self.check_defaults(data, [ + Info('long1', 0), + Info('seq1', []), + ]) + +if __name__ == "__main__": + #import sys;sys.argv = ['', 'TestDynamicDefaults.testSimpleTypes'] + unittest.main() \ No newline at end of file diff --git a/src/api/dcps/python/test/test_instance_operations.py b/src/api/dcps/python/test/test_instance_operations.py new file mode 100644 index 000000000..19ba8983d --- /dev/null +++ b/src/api/dcps/python/test/test_instance_operations.py @@ -0,0 +1,235 @@ +# +# Vortex OpenSplice +# +# This software and documentation are Copyright 2006 to TO_YEAR ADLINK +# Technology Limited, its affiliated companies and licensors. All rights +# reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +''' +Created on Jan 5, 2018 + +@author: prismtech +''' +import unittest +import os +import dds +import ddsutil + +class TestInstanceOperations(unittest.TestCase): + + idl_path = os.path.join('idl', 'Shapes.idl') + shape_type_name = 'ShapeType' + + def test_registration(self): + dp = dds.DomainParticipant() + + gci = ddsutil.get_dds_classes_from_idl(self.idl_path, self.shape_type_name) + ShapeType = gci.get_class('ShapeType') + Inner = gci.get_class('Inner') + + t = gci.register_topic(dp, 'ST_test_registration') + + wr = dp.create_datawriter(t) + #data = ShapeType(color='RED') + data = ShapeType(color='RED',x=0,y=0,z=0,t=Inner(foo=0)) + + h = wr.register_instance(data) + self.assertIsNotNone(h, 'handle is None') + self.assertIsInstance(h, int, 'handle is not int') + + wr.unregister_instance(data, h) + + def test_unregistration(self): + dp = dds.DomainParticipant() + + gci = ddsutil.get_dds_classes_from_idl(self.idl_path, self.shape_type_name) + ShapeType = gci.get_class('ShapeType') + Inner = gci.get_class('Inner') + + t = gci.register_topic(dp, 'ST_test_unregistration') + + wr = dp.create_datawriter(t) + #data = ShapeType(color='RED') + data = ShapeType(color='RED',x=0,y=0,z=0,t=Inner(foo=0)) + data2 = ShapeType(color='BLUE',x=0,y=0,z=0,t=Inner(foo=0)) + data3 = ShapeType(color='YELLOW',x=0,y=0,z=0,t=Inner(foo=0)) + data4 = ShapeType(color='PINK',x=0,y=0,z=0,t=Inner(foo=0)) + dataNever = ShapeType(color='NEVER',x=0,y=0,z=0,t=Inner(foo=0)) + + h = wr.register_instance(data) + h2 = wr.register_instance(data2) + h3 = wr.register_instance(data3) + h4 = wr.register_instance(data4) + self.assertIsNotNone(h, 'handle is None') + self.assertIsInstance(h, int, 'handle is not int') + + # test expected success paths + wr.unregister_instance(handle=h) + wr.unregister_instance(data=data2) + + # test failure paths + try: + wr.unregister_instance() + self.fail('should not succeed; unregistering inconsistent data') + except dds.DDSException: + pass + + # unregister something that's already unregistered + try: + wr.unregister_instance(handle=h) + self.fail('should not succeed; duplicate unregistration') + except dds.DDSException: + pass + + # unregister something that was never registered + try: + wr.unregister_instance(data=dataNever) + self.fail('should not succeed; instance never registered') + except dds.DDSException: + pass + + # The following are not failures, but will produce oslp-error.log entries + + # unregister something where data does not match + wr.unregister_instance(dataNever, h4) + + def test_wr_instance_lookup(self): + dp = dds.DomainParticipant() + + gci = ddsutil.get_dds_classes_from_idl(self.idl_path, self.shape_type_name) + ShapeType = gci.get_class('ShapeType') + Inner = gci.get_class('Inner') + + t = gci.register_topic(dp, 'ST_test_wr_instance_lookup') + + wr = dp.create_datawriter(t) + #data = ShapeType(color='RED') + data = ShapeType(color='RED',x=0,y=0,z=0,t=Inner(foo=0)) + dataUnreg = ShapeType(color='GREEN',x=0,y=0,z=0,t=Inner(foo=0)) + + h = wr.register_instance(data) + + hlookup = wr.lookup_instance(data) + self.assertEqual(hlookup, h) + + hUnreg = wr.lookup_instance(dataUnreg) + self.assertIsNone(hUnreg) + +# def test_wr_get_key(self): +# dp = dds.DomainParticipant() +# +# gci = ddsutil.get_dds_classes_from_idl(self.idl_path, self.shape_type_name) +# ShapeType = gci.get_class('ShapeType') +# Inner = gci.get_class('Inner') +# +# t = gci.register_topic(dp, 'ST_test_wr_get_key') +# +# wr = dp.create_datawriter(t) +# #data = ShapeType(color='RED') +# data = ShapeType(color='RED',x=1,y=2,z=3,t=Inner(foo=4)) +# dataUnreg = ShapeType(color='GREEN',x=0,y=0,z=0,t=Inner(foo=0)) +# +# h = wr.register_instance(data) +# +# dataLookup = wr.get_key(h) +# self.assertEqual(dataLookup.color, data.color) +# self.assertEqual(dataLookup.x, 0) +# self.assertEqual(dataLookup.y, 0) +# self.assertEqual(dataLookup.z, 0) +# self.assertEqual(dataLookup.t.foo, 0) +# +# try: +# wr.get_key(11231997) +# self.fail('Expected exception on invalid handle') +# except dds.DDSException: +# pass + + def test_take_instance(self): + dp = dds.DomainParticipant() + + gci = ddsutil.get_dds_classes_from_idl(self.idl_path, self.shape_type_name) + ShapeType = gci.get_class('ShapeType') + Inner = gci.get_class('Inner') + + t = gci.register_topic(dp, 'ST_test_take_instance') + + rd = dp.create_datareader(t) + wr = dp.create_datawriter(t) + + dataR = ShapeType(color='RED',x=1,y=1,z=1,t=Inner(foo=1)) + dataG = ShapeType(color='GREEN',x=1,y=1,z=1,t=Inner(foo=1)) + + keyR = ShapeType(color='RED',x=0,y=0,z=0,t=Inner(foo=0)) + + hR = rd.lookup_instance(keyR) + self.assertIsNone(hR) + + wr.write(dataR) + wr.write(dataG) + + keyR = ShapeType(color='RED',x=0,y=0,z=0,t=Inner(foo=0)) + + hR = rd.lookup_instance(keyR) + self.assertIsInstance(hR, int) + + data = rd.take_instance(hR,n=2) + self.assertEqual(1, len(data)) + found = [d.color for d, _ in data] + self.assertIn('RED',found) + + #do it again + data = rd.take_instance(hR,n=2) + self.assertEqual(0, len(data)) + + def test_read_instance(self): + dp = dds.DomainParticipant() + + gci = ddsutil.get_dds_classes_from_idl(self.idl_path, self.shape_type_name) + ShapeType = gci.get_class('ShapeType') + Inner = gci.get_class('Inner') + + t = gci.register_topic(dp, 'ST_test_read_instance') + + rd = dp.create_datareader(t) + wr = dp.create_datawriter(t) + + dataR = ShapeType(color='RED',x=1,y=1,z=1,t=Inner(foo=1)) + dataG = ShapeType(color='GREEN',x=1,y=1,z=1,t=Inner(foo=1)) + + keyR = ShapeType(color='RED',x=0,y=0,z=0,t=Inner(foo=0)) + + hR = rd.lookup_instance(keyR) + self.assertIsNone(hR) + + wr.write(dataR) + wr.write(dataG) + + hR = rd.lookup_instance(keyR) + self.assertIsInstance(hR, int) + + data = rd.read_instance(hR,n=2) + self.assertEqual(1, len(data)) + found = [d.color for d, _ in data] + self.assertIn('RED',found) + + #do it again + data = rd.read_instance(hR,n=2) + self.assertEqual(1, len(data)) + found = [d.color for d, _ in data] + self.assertIn('RED',found) + +if __name__ == "__main__": + #import sys;sys.argv = ['', 'TestInstanceOperations.test_register_instance'] + unittest.main() \ No newline at end of file diff --git a/src/api/dcps/python/test/test_listeners.py b/src/api/dcps/python/test/test_listeners.py new file mode 100644 index 000000000..031985f91 --- /dev/null +++ b/src/api/dcps/python/test/test_listeners.py @@ -0,0 +1,599 @@ +# +# Vortex OpenSplice +# +# This software and documentation are Copyright 2006 to TO_YEAR ADLINK +# Technology Limited, its affiliated companies and licensors. All rights +# reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +''' +Created on Dec 27, 2017 + +@author: prismtech +''' +import unittest +from dds import Listener, DomainParticipant, Qos, DurabilityQosPolicy, DDSDurabilityKind, DDSException,\ + DeadlineQosPolicy, DDSDuration, LivelinessQosPolicy, DDSLivelinessKind,\ + OwnershipQosPolicy, DDSOwnershipKind, ResourceLimitsQosPolicy,\ + DestinationOrderQosPolicy, DDSDestinationOrderKind, DDSTime,\ + PublicationMatchedStatus, SubscriptionMatchedStatus,\ + OfferedDeadlineMissedStatus, OfferedIncompatibleQosStatus, QosPolicyId,\ + LivelinessLostStatus, LivelinessChangedStatus, RequestedDeadlineMissedStatus,\ + RequestedIncompatibleQosStatus, SampleRejectedStatus,\ + DDSSampleRejectedStatusKind, SampleLostStatus +import ddsutil +import os +import threading +import time +from symbol import nonlocal_stmt +import collections + +Info = collections.namedtuple('Info', ['name', 'type']) + +class TestListeners(unittest.TestCase): + + idl_path = os.path.join('idl', 'Shapes.idl') + shape_type_name = 'ShapeType' + time_out = 10.0 + + def _check_status(self, status, type, field_info): + self.assertIsInstance(status, type, 'status is not {}'.format(type)) + self.assertEqual(len(field_info), len(type._fields), 'incorrect number of field_info entries') + for n, t in field_info: + self.assertTrue(hasattr(status,n), 'status does not have attr {}'.format(n)) + self.assertIsInstance(getattr(status,n), t, 'status.{} is not a {}'.format(n,t)) + + def test_on_data_available(self): + topic_name = 'ST_on_data_available' + event = threading.Event() + + dp1 = DomainParticipant() + + gci = ddsutil.get_dds_classes_from_idl(self.idl_path, self.shape_type_name) + ShapeType = gci.get_class('ShapeType') + Inner = gci.get_class('Inner') + + t1 = gci.register_topic(dp1, topic_name) + wr1 = dp1.create_datawriter(t1) + + class L(Listener): + def on_data_available(self,_): + event.set() + + dp2 = DomainParticipant() + t2 = gci.register_topic(dp2, topic_name) + rd2 = dp2.create_datareader(t2,listener=L()) + + data = ShapeType(color='RED',x=1,y=2,z=3,t=Inner(foo=4)) + wr1.write(data) + + self.assertTrue(event.wait(self.time_out),'Did not receive on_data_available') + + def test_on_inconsistent_topic(self): + ''' + from: osplo/testsuite/dbt/api/dcps/c99/utest/listener/code/listener_utests.c + + It's not that easy for OpenSplice to generate inconsistent_topic + events. However, it is build on top of SAC and it works on that + language binding. We can assume that this test succeeds when + the other listener test pass as well... + + So, we will just check that the listener's actually got installed + ''' + topic_name = 'ST_on_inconsistent_topic' + event = threading.Event() + + gci = ddsutil.get_dds_classes_from_idl(self.idl_path, self.shape_type_name) +# gci2 = ddsutil.get_dds_classes_from_idl(self.idl_path, self.shape_type_name + '2') + + class L(Listener): + def on_inconsistent_topic(self, topic, status): + print('on_inconsistent_topic triggered: topic name = {}, total_count = {}, total_change_count = {}' + .format(topic.get_name(), status.total_coutn, status.total_change_count)) + event.set() + + dp1 = DomainParticipant(listener=L()) + + self.assertIsNotNone(dp1.listener, "DomainParticipant Listener was not set") + + t1 = gci.register_topic(dp1, topic_name, listener=L()) + + self.assertIsNotNone(t1.listener, "Topic Listener was not set") + +# t2qos = Qos([DurabilityQosPolicy(DDSDurabilityKind.PERSISTENT)]) +# try: +# t2 = gci2.register_topic(dp2, topic_name, qos=None) +# self.fail("expected this topic registeration to fail") +# except DDSException as e: +# pass +# +# try: +# self.assertTrue(self.event.wait(self.time_out),'Did not receive on_inconsistent_topic') +# finally: +# pass + + def test_data_available_listeners(self): + dp_on_data_available_event = threading.Event() + dp_on_publication_matched_event = threading.Event() + dp_on_subscription_matched_event = threading.Event() + + p_on_publication_matched_event = threading.Event() + s_on_data_available_event = threading.Event() + s_on_subscription_matched_event = threading.Event() + + wr_on_publication_matched_event = threading.Event() + + rd_on_data_available_event = threading.Event() + rd_on_subscription_matched_event = threading.Event() + + opm_event = threading.Event() + osm_event = threading.Event() + oda_event = threading.Event() + + pub_match_status = None + sub_match_status = None + + class DPL(Listener): + def on_data_available(self,reader): + dp_on_data_available_event.set() + oda_event.set() + def on_publication_matched(self,writer,status): + dp_on_publication_matched_event.set() + opm_event.set() + def on_subscription_matched(self,reader,status): + dp_on_subscription_matched_event.set() + osm_event.set() + + class PL(Listener): + def on_publication_matched(self,writer, status): + p_on_publication_matched_event.set() + + class SL(Listener): + def on_data_available(self,reader): + s_on_data_available_event.set() + oda_event.set() + def on_subscription_matched(self,reader, status): + s_on_subscription_matched_event.set() + osm_event.set() + + class WL(Listener): + def on_publication_matched(self,writer, status): + nonlocal pub_match_status + pub_match_status = status + wr_on_publication_matched_event.set() + opm_event.set() + + class RL(Listener): + def on_data_available(self,reader): + rd_on_data_available_event.set() + oda_event.set() + def on_subscription_matched(self,reader, status): + nonlocal sub_match_status + sub_match_status = status + rd_on_subscription_matched_event.set() + osm_event.set() + + dp = DomainParticipant(listener=DPL()) + self.assertIsInstance(dp.listener, DPL, 'listener is not a DPL') + + topic_name = 'ST_data_available_listeners' + + gci = ddsutil.get_dds_classes_from_idl(self.idl_path, self.shape_type_name) + + t = gci.register_topic(dp, topic_name) + + pub = dp.create_publisher(listener=PL()) + self.assertIsInstance(pub.listener, PL, 'listener is not a PL') + + sub = dp.create_subscriber(listener=SL()) + self.assertIsInstance(sub.listener, SL, 'listener is not a SL') + + wr = pub.create_datawriter(t, listener=WL()) + self.assertIsInstance(wr.listener, WL, 'listener is not a WL') + + rd = sub.create_datareader(t, listener=RL()) + self.assertIsInstance(rd.listener, RL, 'listener is not a RL') + + ShapeType = gci.get_class('ShapeType') + Inner = gci.get_class('Inner') + + data = ShapeType(color='GREEN', x=22, y=33, z=44, t=Inner(foo=55)) + +# time.sleep(1.0) + + wr.write(data) + + + TriggerState = collections.namedtuple('TriggerState',[ + 'opm', + 'osm', + 'oda', + ]) + + actual_trigger_state = TriggerState( + opm_event.wait(self.time_out), + osm_event.wait(self.time_out), + oda_event.wait(self.time_out)) + print(actual_trigger_state) + + self.assertEqual( + actual_trigger_state, + TriggerState(True, True, True) + , 'Not all events triggered') + + EventState = collections.namedtuple('EventState',[ + 'dp_opm', + 'p_opm', + 'wr_opm', + 'dp_osm', + 's_osm', + 'rd_osm', + 'dp_oda', + 's_oda', + 'rd_oda', + ]) + + actual_event_state = EventState( + dp_on_publication_matched_event.is_set(), + p_on_publication_matched_event.is_set(), + wr_on_publication_matched_event.is_set(), + dp_on_subscription_matched_event.is_set(), + s_on_subscription_matched_event.is_set(), + rd_on_subscription_matched_event.is_set(), + dp_on_data_available_event.is_set(), + s_on_data_available_event.is_set(), + rd_on_data_available_event.is_set(), + ) + expected_event_state = EventState( + False, False, True, + False, False, True, + False, False, True, + ) + print(actual_event_state) + self.assertEqual(actual_event_state, expected_event_state, 'Incorrect listeners triggered') +# time.sleep(1.0) +# self.assertTrue(wr_on_publication_matched_event.wait(self.time_out), 'wr_on_publication_matched_event') +# self.assertTrue(rd_on_subscription_matched_event.wait(self.time_out), 'rd_on_subscription_matched_event') + + self._check_status(pub_match_status, PublicationMatchedStatus, [ + Info('total_count', int), + Info('total_count_change', int), + Info('current_count', int), + Info('current_count_change', int), + Info('last_subscription_handle', int), + ]) + self._check_status(sub_match_status, SubscriptionMatchedStatus, [ + Info('total_count', int), + Info('total_count_change', int), + Info('current_count', int), + Info('current_count_change', int), + Info('last_publication_handle', int), + ]) + + + def test_on_offered_deadline_missed(self): + handlerTriggered = threading.Event() + write_time = 0.0 + delay = 0.0 + saved_status = None + class L(Listener): + def on_offered_deadline_missed(self, writer, status): + nonlocal delay + nonlocal saved_status + handlerTriggered.set() + saved_status = status + delay = time.time() - write_time + + dp = DomainParticipant() + + topic_name = 'ST_on_offered_deadline_missed' + + gci = ddsutil.get_dds_classes_from_idl(self.idl_path, self.shape_type_name) + + t = gci.register_topic(dp, topic_name) + + wqos = Qos(policies=[ + DeadlineQosPolicy(DDSDuration(1,0)) + ]) + wr = dp.create_datawriter(t, wqos, L()) + rd = dp.create_datareader(t) + + ShapeType = gci.get_class('ShapeType') + Inner = gci.get_class('Inner') + + data = ShapeType(color='GREEN', x=22, y=33, z=44, t=Inner(foo=55)) + + wr.write(data) + write_time = time.time() + self.assertTrue(handlerTriggered.wait(self.time_out), 'Event not triggered') + self.assertGreaterEqual(delay, 1.0 - 0.05, 'Delay not >= 1.0s') + self._check_status(saved_status, OfferedDeadlineMissedStatus, [ + Info('total_count', int), + Info('total_count_change', int), + Info('last_instance_handle', int), + ]) + + + def test_on_offered_incompatible_qos(self): + handlerTriggered = threading.Event() + saved_status = None + class L(Listener): + def on_offered_incompatible_qos(self, writer, status): + nonlocal saved_status + saved_status = status + handlerTriggered.set() + + dp = DomainParticipant() + + topic_name = 'ST_on_offered_incompatible_qos' + + gci = ddsutil.get_dds_classes_from_idl(self.idl_path, self.shape_type_name) + + t = gci.register_topic(dp, topic_name) + + wqos = Qos(policies=[ + DurabilityQosPolicy(DDSDurabilityKind.VOLATILE) + ]) + rqos = Qos(policies=[ + DurabilityQosPolicy(DDSDurabilityKind.TRANSIENT) + ]) + wr = dp.create_datawriter(t, wqos, L()) + rd = dp.create_datareader(t,rqos) + + ShapeType = gci.get_class('ShapeType') + Inner = gci.get_class('Inner') + + data = ShapeType(color='GREEN', x=22, y=33, z=44, t=Inner(foo=55)) + + wr.write(data) + self.assertTrue(handlerTriggered.wait(self.time_out), 'Event not triggered') + self._check_status(saved_status, OfferedIncompatibleQosStatus, [ + Info('total_count', int), + Info('total_count_change', int), + Info('last_policy_id', QosPolicyId), + ]) + + def test_liveliness(self): + handlerTriggered = threading.Event() + aliveTriggered = threading.Event() + notaliveTriggered = threading.Event() + write_time = 0.0 + delay = 0.0 + saved_lost_status = None + saved_changed_status = None + class L(Listener): + def on_liveliness_lost(self, writer, status): + nonlocal delay + nonlocal saved_lost_status + saved_lost_status = status + handlerTriggered.set() + delay = time.time() - write_time + + class RL(Listener): + def on_liveliness_changed(self, reader, status): + nonlocal saved_changed_status + saved_changed_status = status + if status.alive_count == 1: + aliveTriggered.set() + else: + notaliveTriggered.set() + + qos = Qos(policies=[ + LivelinessQosPolicy(DDSLivelinessKind.MANUAL_BY_TOPIC, + DDSDuration(1,0)), + OwnershipQosPolicy(DDSOwnershipKind.EXCLUSIVE) + ]) + dp = DomainParticipant() + + topic_name = 'ST_liveliness' + + gci = ddsutil.get_dds_classes_from_idl(self.idl_path, self.shape_type_name) + + t = gci.register_topic(dp, topic_name, qos) + + wr = dp.create_datawriter(t, qos=qos, listener=L()) + rd = dp.create_datareader(t, qos=qos, listener=RL()) + + ShapeType = gci.get_class('ShapeType') + Inner = gci.get_class('Inner') + + data = ShapeType(color='GREEN', x=22, y=33, z=44, t=Inner(foo=55)) + + wr.write(data) + write_time = time.time() + self.assertTrue(handlerTriggered.wait(self.time_out), 'Event not triggered') + self.assertGreaterEqual(delay, 1.0 - 0.05, 'Delay not >= 1.0s') + self.assertTrue(aliveTriggered.wait(self.time_out), 'Alive not signaled to reader') + self.assertTrue(notaliveTriggered.wait(self.time_out), 'Not Alive not signaled to reader') + self._check_status(saved_lost_status, LivelinessLostStatus, [ + Info('total_count', int), + Info('total_count_change', int), + ]) + self._check_status(saved_changed_status, LivelinessChangedStatus, [ + Info('alive_count', int), + Info('not_alive_count', int), + Info('alive_count_change', int), + Info('not_alive_count_change', int), + Info('last_publication_handle', int), + ]) + + + def test_on_requested_deadline_missed(self): + handlerTriggered = threading.Event() + write_time = 0.0 + delay = 0.0 + saved_status = None + class L(Listener): + def on_requested_deadline_missed(self, reader, status): + nonlocal delay + nonlocal saved_status + saved_status = status + handlerTriggered.set() + delay = time.time() - write_time + + dp = DomainParticipant() + + topic_name = 'ST_on_requested_deadline_missed' + + gci = ddsutil.get_dds_classes_from_idl(self.idl_path, self.shape_type_name) + + t = gci.register_topic(dp, topic_name) + + qos = Qos(policies=[ + DeadlineQosPolicy(DDSDuration(1,0)) + ]) + wr = dp.create_datawriter(t, qos) + rd = dp.create_datareader(t, qos, L()) + + ShapeType = gci.get_class('ShapeType') + Inner = gci.get_class('Inner') + + data = ShapeType(color='GREEN', x=22, y=33, z=44, t=Inner(foo=55)) + + wr.write(data) + write_time = time.time() + self.assertTrue(handlerTriggered.wait(self.time_out), 'Event not triggered') + self.assertGreaterEqual(delay, 1.0 - 0.05, 'Delay not >= 1.0s') + self._check_status(saved_status, RequestedDeadlineMissedStatus, [ + Info('total_count', int), + Info('total_count_change', int), + Info('last_instance_handle', int), + ]) + + def test_on_requested_incompatible_qos(self): + handlerTriggered = threading.Event() + saved_status = None + class L(Listener): + def on_requested_incompatible_qos(self, reader, status): + nonlocal saved_status + saved_status = status + handlerTriggered.set() + + dp = DomainParticipant() + + topic_name = 'ST_test_on_requested_incompatible_qos' + + gci = ddsutil.get_dds_classes_from_idl(self.idl_path, self.shape_type_name) + + t = gci.register_topic(dp, topic_name) + + wqos = Qos(policies=[ + DurabilityQosPolicy(DDSDurabilityKind.VOLATILE) + ]) + rqos = Qos(policies=[ + DurabilityQosPolicy(DDSDurabilityKind.TRANSIENT) + ]) + wr = dp.create_datawriter(t, wqos) + rd = dp.create_datareader(t,rqos, L()) + + ShapeType = gci.get_class('ShapeType') + Inner = gci.get_class('Inner') + + data = ShapeType(color='GREEN', x=22, y=33, z=44, t=Inner(foo=55)) + + wr.write(data) + self.assertTrue(handlerTriggered.wait(self.time_out), 'Event not triggered') + self._check_status(saved_status, RequestedIncompatibleQosStatus, [ + Info('total_count', int), + Info('total_count_change', int), + Info('last_policy_id', QosPolicyId), + ]) + + def test_on_sample_rejected(self): + handlerTriggered = threading.Event() + saved_status = None + class L(Listener): + def on_sample_rejected(self, reader, status): + nonlocal saved_status + saved_status = status + handlerTriggered.set() + + dp = DomainParticipant() + + topic_name = 'ST_on_sample_rejected' + + gci = ddsutil.get_dds_classes_from_idl(self.idl_path, self.shape_type_name) + + t = gci.register_topic(dp, topic_name) + + qos = Qos(policies=[ + ResourceLimitsQosPolicy(max_samples=1) + ]) + + wr = dp.create_datawriter(t) + rd = dp.create_datareader(t, qos, L()) + + ShapeType = gci.get_class('ShapeType') + Inner = gci.get_class('Inner') + + data1 = ShapeType(color='GREEN', x=22, y=33, z=44, t=Inner(foo=55)) + data2 = ShapeType(color='BLUE', x=222, y=233, z=244, t=Inner(foo=255)) + + wr.write(data1) + self.assertFalse(handlerTriggered.is_set(), 'Event already triggered') + wr.write(data2) + self.assertTrue(handlerTriggered.wait(self.time_out), 'Event not triggered') + self._check_status(saved_status, SampleRejectedStatus, [ + Info('total_count', int), + Info('total_count_change', int), + Info('last_reason', DDSSampleRejectedStatusKind), + Info('last_instance_handle', int), + ]) + + def test_on_sample_lost(self): + handlerTriggered = threading.Event() + saved_status = None + + class L(Listener): + def on_sample_lost(self, reader, status): + nonlocal saved_status + saved_status = status + handlerTriggered.set() + + qos = Qos(policies=[ + DestinationOrderQosPolicy(DDSDestinationOrderKind.BY_SOURCE_TIMESTAMP) + ]) + + dp = DomainParticipant() + + topic_name = 'ST_on_sample_lost' + + gci = ddsutil.get_dds_classes_from_idl(self.idl_path, self.shape_type_name) + + t = gci.register_topic(dp, topic_name) + + wr = dp.create_datawriter(t, qos) + rd = dp.create_datareader(t, qos, L()) + + ShapeType = gci.get_class('ShapeType') + Inner = gci.get_class('Inner') + + data1 = ShapeType(color='GREEN', x=22, y=33, z=44, t=Inner(foo=55)) + + t1 = DDSTime(1000,0) + t2 = DDSTime(1001,0) + # write out-of-order samples + wr.write_ts(data1, t2) + rd.take() + wr.write_ts(data1, t1) + self.assertTrue(handlerTriggered.wait(self.time_out), 'Event not triggered') + self._check_status(saved_status, SampleLostStatus, [ + Info('total_count', int), + Info('total_count_change', int), + ]) + + +if __name__ == "__main__": + #import sys;sys.argv = ['', 'Test.testName'] + unittest.main() \ No newline at end of file diff --git a/src/api/dcps/python/test/test_ospl_11503.py b/src/api/dcps/python/test/test_ospl_11503.py new file mode 100644 index 000000000..9f6f6672c --- /dev/null +++ b/src/api/dcps/python/test/test_ospl_11503.py @@ -0,0 +1,89 @@ +# +# Vortex OpenSplice +# +# This software and documentation are Copyright 2006 to TO_YEAR ADLINK +# Technology Limited, its affiliated companies and licensors. All rights +# reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +''' +Created on Jan 8, 2018 + +@author: prismtech +''' +import unittest +from dds import Listener, DomainParticipant +import ddsutil +import os +import threading + + +class TestOSPL11503(unittest.TestCase): + + idl_path = os.path.join('idl', 'Shapes.idl') + shape_type_name = 'ShapeType' + + def setUp(self): + print('setUp') +# self.dp1 = DomainParticipant() + self.dp2 = DomainParticipant() + print('Created event') + self.event = threading.Event() + + def tearDown(self): + print('tearDown') +# self.dp1.close() + print('dp1 closed') + self.dp2.close() + print('tearDown - done') + +# @unittest.skip("This test causes OSPL/Python to hang") + def test_on_data_available(self): + topic_name = 'ST_on_data_available' + event = self.event + + gci = ddsutil.get_dds_classes_from_idl(self.idl_path, self.shape_type_name) + ShapeType = gci.get_class('ShapeType') + Inner = gci.get_class('Inner') + + print('createing writer') + t1 = gci.register_topic(self.dp2, topic_name) + wr1 = self.dp2.create_datawriter(t1) + + class L(Listener): +# def on_requested_deadline_missed(self, _, __): +# Listener.on_requested_deadline_missed(self) + def on_data_available(self,_): + print('triggering event') + event.set() + + print('creating reader with listener') + t2 = gci.register_topic(self.dp2, topic_name) + rd2 = self.dp2.create_datareader(t2,listener=L()) + + print('writing') + data = ShapeType(color='RED',x=1,y=2,z=3,t=Inner(foo=4)) + wr1.write(data) + try: + print('waiting for listener to trigger') + self.assertTrue(self.event.wait(2.0),'Did not receive on_data_available') + print('done waiting') + finally: + print('closing rd2') +# rd2.close() + print('all done') + +if __name__ == "__main__": + #import sys;sys.argv = ['', 'Test.testName'] + unittest.main() \ No newline at end of file diff --git a/src/api/dcps/python/test/test_ospl_11530.py b/src/api/dcps/python/test/test_ospl_11530.py new file mode 100644 index 000000000..ac70711b9 --- /dev/null +++ b/src/api/dcps/python/test/test_ospl_11530.py @@ -0,0 +1,255 @@ +# +# Vortex OpenSplice +# +# This software and documentation are Copyright 2006 to TO_YEAR ADLINK +# Technology Limited, its affiliated companies and licensors. All rights +# reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +''' +Created on Jan 22, 2018 + +@author: prismtech +''' +import unittest +import dds +import ddsutil +from threading import Event + +class TestOspl11530(unittest.TestCase): + + @classmethod + def setUpClass(cls): + cls.dp = dds.DomainParticipant() + + @classmethod + def tearDownClass(cls): + cls.dp.close() + + def testParticipant_textData(self): + myData = 'DP Text User Data' + builtinTopicName = 'DCPSParticipant' + sawMyData = Event() + dp_qos_txt = dds.Qos(policies=[dds.UserdataQosPolicy(myData)]) + dp2 = dds.DomainParticipant(qos=dp_qos_txt) + + class L(dds.Listener): + def on_data_available(self, reader): + nonlocal sawMyData + while True: + r = reader.take(n = 1) + if len(r) == 0: + break + elif r[0].status.valid_data: + try: + v = bytes(r[0].data.user_data.value).decode('ISO-8859-1') + if v == myData: + sawMyData.set() + break + except UnicodeError: + pass + + builtin_sub = self.dp.create_subscriber(qos=dds.Qos([dds.PartitionQosPolicy(['__BUILT-IN PARTITION__'])])) + builtin_topic_info = ddsutil.find_and_register_topic(self.dp, builtinTopicName) + + builtin_reader = builtin_sub.create_datareader(builtin_topic_info.topic, qos=builtin_topic_info.topic.qos, listener=L()) + + self.assertTrue(sawMyData.wait(10), 'Did not see expected data') + builtin_reader.close() + dp2.close() + + def testParticipant_bytesData(self): + myData = b'DP Bytes User Data' + builtinTopicName = 'DCPSParticipant' + sawMyData = Event() + dp_qos_txt = dds.Qos(policies=[dds.UserdataQosPolicy(myData)]) + dp2 = dds.DomainParticipant(qos=dp_qos_txt) + + class L(dds.Listener): + def on_data_available(self, reader): + nonlocal sawMyData + while True: + r = reader.take(n = 1) + if len(r) == 0: + break + elif r[0].status.valid_data: + try: + v = bytes(r[0].data.user_data.value) + if v == myData: + sawMyData.set() + break + except UnicodeError: + pass + + builtin_sub = self.dp.create_subscriber(qos=dds.Qos([dds.PartitionQosPolicy(['__BUILT-IN PARTITION__'])])) + builtin_topic_info = ddsutil.find_and_register_topic(self.dp, builtinTopicName) + + builtin_reader = builtin_sub.create_datareader(builtin_topic_info.topic, qos=builtin_topic_info.topic.qos, listener=L()) + + self.assertTrue(sawMyData.wait(10), 'Did not see expected data') + builtin_reader.close() + dp2.close() + + def testTopic_textData(self): + myData = 'Topic Text Topic Data' + builtinTopicName = 'DCPSTopic' + sawMyData = Event() + + class L(dds.Listener): + def on_data_available(self, reader): + nonlocal sawMyData + while True: + r = reader.take(n = 1) + if len(r) == 0: + break + elif r[0].status.valid_data: + try: + v = bytes(r[0].data.topic_data.value).decode('ISO-8859-1') + if v == myData: + sawMyData.set() + break + except UnicodeError: + pass + + builtin_sub = self.dp.create_subscriber(qos=dds.Qos([dds.PartitionQosPolicy(['__BUILT-IN PARTITION__'])])) + builtin_topic_info = ddsutil.find_and_register_topic(self.dp, builtinTopicName) + builtin_reader = builtin_sub.create_datareader(builtin_topic_info.topic, qos=builtin_topic_info.topic.qos, listener=L()) + + # Register a topic with a TopicdataQosPolicy + t_qos = dds.Qos(policies=[dds.TopicdataQosPolicy(myData)]) + info = ddsutil.get_dds_classes_from_idl('idl/Shapes.idl', "ShapeType") + info.register_topic(self.dp, "T_testTopic_textData", t_qos) + + self.assertTrue(sawMyData.wait(10), 'Did not see expected data') + builtin_reader.close() + + def testTopic_bytesData(self): + myData = b'Topic Bytes Topic Data' + builtinTopicName = 'DCPSTopic' + sawMyData = Event() + + class L(dds.Listener): + def on_data_available(self, reader): + nonlocal sawMyData + while True: + r = reader.take(n = 1) + if len(r) == 0: + break + elif r[0].status.valid_data: + try: + v = bytes(r[0].data.topic_data.value) + if v == myData: + sawMyData.set() + break + except UnicodeError: + pass + + builtin_sub = self.dp.create_subscriber(qos=dds.Qos([dds.PartitionQosPolicy(['__BUILT-IN PARTITION__'])])) + builtin_topic_info = ddsutil.find_and_register_topic(self.dp, builtinTopicName) + + builtin_reader = builtin_sub.create_datareader(builtin_topic_info.topic, qos=builtin_topic_info.topic.qos, listener=L()) + + # Register a topic with a TopicdataQosPolicy + t_qos = dds.Qos(policies=[dds.TopicdataQosPolicy(myData)]) + info = ddsutil.get_dds_classes_from_idl('idl/Shapes.idl', "ShapeType") + t = info.register_topic(self.dp, "T_testTopic_bytesData", t_qos) + self.assertIsNotNone(t, "Topic registration failed") + + self.assertTrue(sawMyData.wait(10), 'Did not see expected data') + builtin_reader.close() + + def testGroup_textData(self): + myData = 'Pub Text Group Data' + builtinTopicName = 'DCPSPublication' + sawMyData = Event() + + class L(dds.Listener): + def on_data_available(self, reader): + nonlocal sawMyData + while True: + r = reader.take(n = 1) + if len(r) == 0: + break + elif r[0].status.valid_data: + try: + v = bytes(r[0].data.group_data.value).decode('ISO-8859-1') + if v == myData: + sawMyData.set() + break + except UnicodeError: + pass + + builtin_sub = self.dp.create_subscriber(qos=dds.Qos([dds.PartitionQosPolicy(['__BUILT-IN PARTITION__'])])) + builtin_topic_info = ddsutil.find_and_register_topic(self.dp, builtinTopicName) + builtin_reader = builtin_sub.create_datareader(builtin_topic_info.topic, qos=builtin_topic_info.topic.qos, listener=L()) + + # Register a topic with a TopicdataQosPolicy + p_qos = dds.Qos(policies=[dds.GroupdataQosPolicy(myData)]) + pub = self.dp.create_publisher(p_qos); + + info = ddsutil.get_dds_classes_from_idl('idl/Shapes.idl', "ShapeType") + t = info.register_topic(self.dp, "T_testGroup_textData") + self.assertIsNotNone(t, "Topic registration failed") + + dw = pub.create_datawriter(t) + + self.assertTrue(sawMyData.wait(10), 'Did not see expected data') + builtin_reader.close() + dw.close() + pub.close() + + def testGroup_bytesData(self): + myData = b'Pub Bytes Group Data' + builtinTopicName = 'DCPSPublication' + sawMyData = Event() + + class L(dds.Listener): + def on_data_available(self, reader): + nonlocal sawMyData + while True: + r = reader.take(n = 1) + if len(r) == 0: + break + elif r[0].status.valid_data: + try: + v = bytes(r[0].data.group_data.value) + if v == myData: + sawMyData.set() + break + except UnicodeError: + pass + + builtin_sub = self.dp.create_subscriber(qos=dds.Qos([dds.PartitionQosPolicy(['__BUILT-IN PARTITION__'])])) + builtin_topic_info = ddsutil.find_and_register_topic(self.dp, builtinTopicName) + builtin_reader = builtin_sub.create_datareader(builtin_topic_info.topic, qos=builtin_topic_info.topic.qos, listener=L()) + + # Register a topic with a TopicdataQosPolicy + p_qos = dds.Qos(policies=[dds.GroupdataQosPolicy(myData)]) + pub = self.dp.create_publisher(p_qos); + + info = ddsutil.get_dds_classes_from_idl('idl/Shapes.idl', "ShapeType") + t = info.register_topic(self.dp, "T_testGroup_bytesData") + self.assertIsNotNone(t, "Topic registration failed") + + dw = pub.create_datawriter(t) + + self.assertTrue(sawMyData.wait(10), 'Did not see expected data') + builtin_reader.close() + dw.close() + pub.close() + + +if __name__ == "__main__": + #import sys;sys.argv = ['', 'TestOspl11530.testParticipant_textData'] + unittest.main() \ No newline at end of file diff --git a/src/api/dcps/python/test/test_qos.py b/src/api/dcps/python/test/test_qos.py new file mode 100644 index 000000000..3424529fd --- /dev/null +++ b/src/api/dcps/python/test/test_qos.py @@ -0,0 +1,355 @@ +# +# Vortex OpenSplice +# +# This software and documentation are Copyright 2006 to TO_YEAR ADLINK +# Technology Limited, its affiliated companies and licensors. All rights +# reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from ddsutil import * +from dds import * +import unittest +import time +import xmlrunner + +type_info_fmt = "basic::module_{}::{}" + +class QosProfileTests(unittest.TestCase): + + def setUp(self): + unittest.TestCase.setUp(self) + + def compare_result(self, obj1, obj2): + print("Comparing result:") + obj1.print_vars() + obj2.print_vars() + return self._do_compare_result(obj1, obj2) + + def _do_compare_result(self, obj1, obj2): + if isinstance(obj1, TopicDataClass): + cls1_vars = obj1.get_vars() + cls2_vars = obj2.get_vars() + return self._do_compare_result(list(cls1_vars.values()), list(cls2_vars.values())) + + if isinstance(obj1, list): + for i in range(len(obj1)): + if not self._do_compare_result(obj1[i], obj2[i]): + return False + else: + if not obj1 == obj2: + return False + return True + + def test_default_xml_qos(self): + + qp = QosProfile('file://qos/DDS_DefaultQoS_All.xml', 'DDS DefaultQosProfile') + + # Create participant + dp = DomainParticipant(qos=qp.get_participant_qos()) + + # Create publisher + pub = dp.create_publisher(qp.get_publisher_qos()) + + # Create Subscriber + sub = dp.create_subscriber(qp.get_subscriber_qos()) + + idl_name = 'MultiArrayBasicType' + idl_path = 'idl/' + idl_name + '.idl' + type_info = type_info_fmt.format(idl_name, idl_name + '_struct') + + gen_info = get_dds_classes_from_idl(idl_path, type_info) + Sample = gen_info.topic_data_class + SampleTypeSupport = gen_info.type_support_class + + ts = SampleTypeSupport() + topic = Topic(dp, 'MultiArrayBasicType1', ts, qp.get_topic_qos()) + writer = DataWriter(pub, topic, qp.get_writer_qos()) + reader2 = DataReader(sub, topic, qp.get_reader_qos()) + + waitset = WaitSet() + condition = StatusCondition(reader2) + + waitset.attach(condition) + + s = Sample(long1 = 4, array1=[[[1,2],[2,3],[3,4]],[[11,22],[22,33],[33,44]]]) + writer.write(s) + time.sleep(1) + + conditions = waitset.wait() + + l = reader2.take(1) + sd, si = l[0] + self.assertTrue(self.compare_result(s, sd)) + + + def test_volatile_xml_qos(self): + + qp = QosProfile('file://qos/DDS_VolatileQoS_All.xml', 'DDS VolatileQosProfile') + + # Create participant + dp = DomainParticipant(qos=qp.get_participant_qos()) + + # Create publisher + pub = dp.create_publisher(qp.get_publisher_qos()) + + # Create Subscriber + sub = dp.create_subscriber(qp.get_subscriber_qos()) + + idl_name = 'Lely_example1' + idl_path = '../test/idl/' + idl_name + '.idl' + type_info = "SegregationGate" + + gen_info = get_dds_classes_from_idl(idl_path, type_info) + Sample = gen_info.topic_data_class + SampleTypeSupport = gen_info.type_support_class + ts = SampleTypeSupport() + topic = Topic(dp, "SegregationGate1", ts, qp.get_topic_qos()) + writer = DataWriter(pub, topic, qp.get_writer_qos()) + reader2 = DataReader(sub, topic, qp.get_reader_qos()) + + waitset = WaitSet() + condition = StatusCondition(reader2) + + waitset.attach(condition) + + LeftRightStates = gen_info.get_class('LeftRightStates') + + s = Sample(output_identifier="output1", state=LeftRightStates.LEFT) + writer.write(s) + time.sleep(1) + + conditions = waitset.wait() + + l = reader2.take(1) + sd, si = l[0] + self.assertTrue(self.compare_result(s, sd)) + + + def test_array_of_struct(self): + qp = QosProfile('file://qos/DDS_QoS_Mismatched.xml', 'DDS DefaultQosProfile') + + # Create participant + dp = DomainParticipant(qos=qp.get_participant_qos()) + + # Create publisher + pub = dp.create_publisher(qp.get_publisher_qos()) + + # Create Subscriber + sub = dp.create_subscriber(qp.get_subscriber_qos()) + + idl_name = 'ArrayOfStruct' + idl_path = 'idl/' + idl_name + '.idl' + type_info = type_info_fmt.format(idl_name, idl_name + '_struct') + + gen_info = get_dds_classes_from_idl(idl_path, type_info) + Sample = gen_info.topic_data_class + SampleTypeSupport = gen_info.type_support_class + + ts = SampleTypeSupport() + topic = Topic(dp, 'ArrayOfStruct1', ts, qp.get_topic_qos()) + writer = DataWriter(pub, topic, qp.get_writer_qos()) + reader2 = DataReader(sub, topic, qp.get_reader_qos()) + + waitset = WaitSet() + condition = StatusCondition(reader2) + + waitset.attach(condition) + + Inner = gen_info.get_class("basic::module_{}::Inner".format(idl_name)) + inner1 = Inner(long1 = 999, double1=222) + inner2 = Inner(long1 = 777, double1=333) + s = Sample(long1=2, array1 = [inner1, inner2], mylong1=5) + writer.write(s) + time.sleep(1) + + conditions = waitset.wait() + + l = reader2.take(1) + + self.assertTrue(len(l) == 0) + + def test_qos_policy(self): + + publisher_qos = Qos([PresentationQosPolicy(DDSPresentationAccessScopeKind.TOPIC, True, True), + PartitionQosPolicy(['A', 'B'])]) + subscriber_qos = Qos([PresentationQosPolicy(DDSPresentationAccessScopeKind.TOPIC, True, True), + PartitionQosPolicy(['A', 'B'])]) + # Create participant + dp = DomainParticipant() + + # Create publisher + pub = dp.create_publisher(publisher_qos) + + # Create Subscriber + sub = dp.create_subscriber(subscriber_qos) + + # Generate python classes from IDL file + gen_info = get_dds_classes_from_idl('idl/NestedStruct.idl', 'basic::module_NestedStruct::NestedStruct_struct') + + topic_qos = Qos([DurabilityQosPolicy(DDSDurabilityKind.TRANSIENT), + DurabilityServiceQosPolicy(DDSDuration(2, 500), DDSHistoryKind.KEEP_ALL, 2, 100, 100, 100), + DeadlineQosPolicy(DDSDuration(500)), + LatencyBudgetQosPolicy(DDSDuration(3000)), + LivelinessQosPolicy(DDSLivelinessKind.MANUAL_BY_PARTICIPANT), + ReliabilityQosPolicy(DDSReliabilityKind.RELIABLE, DDSDuration.infinity()), + DestinationOrderQosPolicy(DDSDestinationOrderKind.BY_SOURCE_TIMESTAMP), + HistoryQosPolicy(DDSHistoryKind.KEEP_ALL), + ResourceLimitsQosPolicy(10,10,10), + TransportPriorityQosPolicy(700), + LifespanQosPolicy(DDSDuration(10, 500)), + OwnershipQosPolicy(DDSOwnershipKind.EXCLUSIVE), + TopicdataQosPolicy("TopicData") + ]) + + topic = gen_info.register_topic(dp, "NestedStruct3", topic_qos) + + writer_qos = Qos([DurabilityQosPolicy(DDSDurabilityKind.TRANSIENT), + DeadlineQosPolicy(DDSDuration(500)), + LatencyBudgetQosPolicy(DDSDuration(3000)), + LivelinessQosPolicy(DDSLivelinessKind.MANUAL_BY_PARTICIPANT), + ReliabilityQosPolicy(DDSReliabilityKind.RELIABLE, DDSDuration.infinity()), + DestinationOrderQosPolicy(DDSDestinationOrderKind.BY_SOURCE_TIMESTAMP), + HistoryQosPolicy(DDSHistoryKind.KEEP_ALL), + ResourceLimitsQosPolicy(10,10,10), + TransportPriorityQosPolicy(700), + LifespanQosPolicy(DDSDuration(10, 500)), + OwnershipQosPolicy(DDSOwnershipKind.EXCLUSIVE), + OwnershipStrengthQosPolicy(100), + WriterDataLifecycleQosPolicy(False), + UserdataQosPolicy("hello") + ]) + + reader_qos = Qos([DurabilityQosPolicy(DDSDurabilityKind.TRANSIENT), + DeadlineQosPolicy(DDSDuration(500)), + LatencyBudgetQosPolicy(DDSDuration(3000)), + LivelinessQosPolicy(DDSLivelinessKind.MANUAL_BY_PARTICIPANT), + ReliabilityQosPolicy(DDSReliabilityKind.RELIABLE, DDSDuration.infinity()), + DestinationOrderQosPolicy(DDSDestinationOrderKind.BY_SOURCE_TIMESTAMP), + HistoryQosPolicy(DDSHistoryKind.KEEP_ALL), + ResourceLimitsQosPolicy(10,10,10), + OwnershipQosPolicy(DDSOwnershipKind.EXCLUSIVE), + TimeBasedFilterQosPolicy(DDSDuration(2, 500)), + ReaderDataLifecycleQosPolicy(DDSDuration(3), DDSDuration(5)), + UserdataQosPolicy("dello") + ]) + + writer = pub.create_datawriter(topic, writer_qos) + reader = sub.create_datareader(topic, reader_qos) + + Inner = gen_info.get_class("basic::module_NestedStruct::Inner") + inner = Inner(long1 = 1, double1 = 1.0) + s = gen_info.topic_data_class(long1 = 1, inner1 = inner) + + waitset = WaitSet() + condition = StatusCondition(reader) + + waitset.attach(condition) + + writer.write(s) + + time.sleep(1) + + conditions = waitset.wait() + + l = reader.take(1) + sd, si = l[0] + self.assertTrue(self.compare_result(s, sd)) + + def test_qos_policy_with_default_pub_sub(self): + + # Create participant + dp = DomainParticipant() + + # Generate python classes from IDL file + gen_info = get_dds_classes_from_idl('idl/NestedStruct.idl', 'basic::module_NestedStruct::NestedStruct_struct') + + topic_qos = Qos([DurabilityQosPolicy(DDSDurabilityKind.TRANSIENT), + DurabilityServiceQosPolicy(DDSDuration(2, 500), DDSHistoryKind.KEEP_ALL, 2, 100, 100, 100), + DeadlineQosPolicy(DDSDuration(500)), + LatencyBudgetQosPolicy(DDSDuration(3000)), + LivelinessQosPolicy(DDSLivelinessKind.MANUAL_BY_PARTICIPANT), + ReliabilityQosPolicy(DDSReliabilityKind.RELIABLE, DDSDuration.infinity()), + DestinationOrderQosPolicy(DDSDestinationOrderKind.BY_SOURCE_TIMESTAMP), + HistoryQosPolicy(DDSHistoryKind.KEEP_ALL), + ResourceLimitsQosPolicy(10,10,10), + TransportPriorityQosPolicy(700), + LifespanQosPolicy(DDSDuration(10, 500)), + OwnershipQosPolicy(DDSOwnershipKind.EXCLUSIVE), + TopicdataQosPolicy("TopicData") + ]) + + topic = gen_info.register_topic(dp, "NestedStruct3", topic_qos) + + writer_qos = Qos([DurabilityQosPolicy(DDSDurabilityKind.TRANSIENT), + DeadlineQosPolicy(DDSDuration(500)), + LatencyBudgetQosPolicy(DDSDuration(3000)), + LivelinessQosPolicy(DDSLivelinessKind.MANUAL_BY_PARTICIPANT), + ReliabilityQosPolicy(DDSReliabilityKind.RELIABLE, DDSDuration.infinity()), + DestinationOrderQosPolicy(DDSDestinationOrderKind.BY_SOURCE_TIMESTAMP), + HistoryQosPolicy(DDSHistoryKind.KEEP_ALL), + ResourceLimitsQosPolicy(10,10,10), + TransportPriorityQosPolicy(700), + LifespanQosPolicy(DDSDuration(10, 500)), + OwnershipQosPolicy(DDSOwnershipKind.EXCLUSIVE), + OwnershipStrengthQosPolicy(100), + WriterDataLifecycleQosPolicy(False), + UserdataQosPolicy("hello") + ]) + + reader_qos = Qos([DurabilityQosPolicy(DDSDurabilityKind.TRANSIENT), + DeadlineQosPolicy(DDSDuration(500)), + LatencyBudgetQosPolicy(DDSDuration(3000)), + LivelinessQosPolicy(DDSLivelinessKind.MANUAL_BY_PARTICIPANT), + ReliabilityQosPolicy(DDSReliabilityKind.RELIABLE, DDSDuration.infinity()), + DestinationOrderQosPolicy(DDSDestinationOrderKind.BY_SOURCE_TIMESTAMP), + HistoryQosPolicy(DDSHistoryKind.KEEP_ALL), + ResourceLimitsQosPolicy(10,10,10), + OwnershipQosPolicy(DDSOwnershipKind.EXCLUSIVE), + TimeBasedFilterQosPolicy(DDSDuration(2, 500)), + ReaderDataLifecycleQosPolicy(DDSDuration(3), DDSDuration(5)), + UserdataQosPolicy("dello") + ]) + + writer = dp.create_datawriter(topic, writer_qos) + reader = dp.create_datareader(topic, reader_qos) + + Inner = gen_info.get_class("basic::module_NestedStruct::Inner") + inner = Inner(long1 = 1, double1 = 1.0) + s = gen_info.topic_data_class(long1 = 1, inner1 = inner) + + waitset = WaitSet() + condition = StatusCondition(reader) + + waitset.attach(condition) + + writer.write(s) + + time.sleep(1) + + conditions = waitset.wait() + + l = reader.take(1) + sd, si = l[0] + self.assertTrue(self.compare_result(s, sd)) + + @classmethod + def setUpClass(cls): + super(QosProfileTests, cls).setUpClass() + + +if __name__ == '__main__': + unittest.main(testRunner=xmlrunner.XMLTestRunner(output='test-reports'), + # these make sure that some options that are not applicable + # remain hidden from the help menu. + failfast=False, buffer=False, catchbreak=False) diff --git a/src/api/dcps/python/test/test_read_conditions.py b/src/api/dcps/python/test/test_read_conditions.py new file mode 100644 index 000000000..3b4c2291f --- /dev/null +++ b/src/api/dcps/python/test/test_read_conditions.py @@ -0,0 +1,92 @@ +# +# Vortex OpenSplice +# +# This software and documentation are Copyright 2006 to TO_YEAR ADLINK +# Technology Limited, its affiliated companies and licensors. All rights +# reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +''' +Created on Jan 4, 2018 + +@author: prismtech +''' +import os +import unittest +import dds +import ddsutil + +class TestReadConditions(unittest.TestCase): + + idl_path = os.path.join('idl', 'Shapes.idl') + shape_type_name = 'ShapeType' + + def test_take_cond(self): + dp = dds.DomainParticipant() + + gci = ddsutil.get_dds_classes_from_idl(self.idl_path, self.shape_type_name) + ShapeType = gci.get_class('ShapeType') + Inner = gci.get_class('Inner') + + t = gci.register_topic(dp, 'ST_test_take_cond') + + rd = dp.create_datareader(t) + wr = dp.create_datawriter(t) + + qc = rd.create_querycondition(expression='color = %0', parameters=['RED']) + + dataR = ShapeType(color='RED',x=1,y=1,z=1,t=Inner(foo=1)) + dataG = ShapeType(color='GREEN',x=1,y=1,z=1,t=Inner(foo=1)) + + wr.write(dataR) + wr.write(dataG) + + data = rd.take_cond(qc,2) + self.assertEqual(1, len(data)) + found = [d.color for d, _ in data] + self.assertIn('RED',found) + + def test_read_cond(self): + dp = dds.DomainParticipant() + + gci = ddsutil.get_dds_classes_from_idl(self.idl_path, self.shape_type_name) + ShapeType = gci.get_class('ShapeType') + Inner = gci.get_class('Inner') + + t = gci.register_topic(dp, 'ST_test_take_cond') + + rd = dp.create_datareader(t) + wr = dp.create_datawriter(t) + + qc = rd.create_querycondition(expression='x = 1') + + dataR = ShapeType(color='RED',x=1,y=1,z=1,t=Inner(foo=1)) + dataG = ShapeType(color='GREEN',x=1,y=1,z=1,t=Inner(foo=1)) + dataB = ShapeType(color='BLUE',x=2,y=1,z=1,t=Inner(foo=1)) + + wr.write(dataR) + wr.write(dataG) + wr.write(dataB) + + samples = rd.read_cond(qc,3) + self.assertEqual(2, len(samples)) + found = [s.data.color for s in samples] + self.assertIn('RED',found) + self.assertIn('GREEN',found) + + + +if __name__ == "__main__": + #import sys;sys.argv = ['', 'TestReadConditions.test_take_cond'] + unittest.main() \ No newline at end of file diff --git a/src/api/dcps/python/test/test_status_conditions.py b/src/api/dcps/python/test/test_status_conditions.py new file mode 100644 index 000000000..59227a15f --- /dev/null +++ b/src/api/dcps/python/test/test_status_conditions.py @@ -0,0 +1,263 @@ +# +# Vortex OpenSplice +# +# This software and documentation are Copyright 2006 to TO_YEAR ADLINK +# Technology Limited, its affiliated companies and licensors. All rights +# reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +''' +Created on Jan 3, 2018 + +@author: prismtech +''' +import os +import unittest +import dds +import ddsutil +from collections import namedtuple + +class TestStatusConditions(unittest.TestCase): + + idl_path = os.path.join('idl', 'Shapes.idl') + shape_type_name = 'ShapeType' + + def test_inconsistent_topic_status(self): + dp = dds.DomainParticipant() + t, _ = ddsutil.find_and_register_topic(dp, 'DCPSParticipant') + + status = t.inconsistent_topic_status() + self.assertIsNotNone(status, 'status is None') + self.assertTrue(hasattr(status, 'total_count')) + self.assertTrue(hasattr(status, 'total_count_change')) + self.assertIsInstance(status.total_count, int) + self.assertIsInstance(status.total_count_change, int) + + def test_publication_matched_status(self): + dp = dds.DomainParticipant() + + topic_name = 'ST_publication_matched_status' + gci = ddsutil.get_dds_classes_from_idl(self.idl_path, self.shape_type_name) + t = gci.register_topic(dp, topic_name) + + wr = dp.create_datawriter(t) + + status = wr.publication_matched_status() + Info = namedtuple('Info', ['name','type']) + attrs = [Info('total_count', int), + Info('total_count_change', int), + Info('current_count', int), + Info('current_count_change', int), + Info('last_subscription_handle', int)] + self.assertIsNotNone(status, 'status is None') + self.assertIsInstance(status, dds.PublicationMatchedStatus) + for a in attrs: + self.assertTrue(hasattr(status, a.name)) + self.assertIsInstance(getattr(status, a.name), a.type, '{} is not a {}'.format(a.name, a.type)) + + def test_liveliness_lost_status(self): + dp = dds.DomainParticipant() + + topic_name = 'ST_liveliness_lost_status' + gci = ddsutil.get_dds_classes_from_idl(self.idl_path, self.shape_type_name) + t = gci.register_topic(dp, topic_name) + + wr = dp.create_datawriter(t) + + status = wr.liveliness_lost_status() + Info = namedtuple('Info', ['name','type']) + attrs = [Info('total_count', int), + Info('total_count_change', int), + ] + self.assertIsNotNone(status, 'status is None') + self.assertIsInstance(status, dds.LivelinessLostStatus) + for a in attrs: + self.assertTrue(hasattr(status, a.name)) + self.assertIsInstance(getattr(status, a.name), a.type, '{} is not a {}'.format(a.name, a.type)) + + def test_offered_deadline_missed_status(self): + dp = dds.DomainParticipant() + + topic_name = 'ST_offered_deadline_missed' + gci = ddsutil.get_dds_classes_from_idl(self.idl_path, self.shape_type_name) + t = gci.register_topic(dp, topic_name) + + wr = dp.create_datawriter(t) + + status = wr.offered_deadline_missed_status() + Info = namedtuple('Info', ['name','type']) + attrs = [Info('total_count', int), + Info('total_count_change', int), + Info('last_instance_handle', int), + ] + self.assertIsNotNone(status, 'status is None') + self.assertIsInstance(status, dds.OfferedDeadlineMissedStatus) + for a in attrs: + self.assertTrue(hasattr(status, a.name)) + self.assertIsInstance(getattr(status, a.name), a.type, '{} is not a {}'.format(a.name, a.type)) + + def test_offered_incompatible_qos_status(self): + dp = dds.DomainParticipant() + + topic_name = 'ST_offered_incompatible_qos' + gci = ddsutil.get_dds_classes_from_idl(self.idl_path, self.shape_type_name) + t = gci.register_topic(dp, topic_name) + + wr = dp.create_datawriter(t) + + status = wr.offered_incompatible_qos_status() + Info = namedtuple('Info', ['name','type']) + attrs = [Info('total_count', int), + Info('total_count_change', int), + Info('last_policy_id', dds.QosPolicyId), + ] + self.assertIsNotNone(status, 'status is None') + self.assertIsInstance(status, dds.OfferedIncompatibleQosStatus) + for a in attrs: + self.assertTrue(hasattr(status, a.name)) + self.assertIsInstance(getattr(status, a.name), a.type, '{} is not a {}'.format(a.name, a.type)) + + def test_subscription_matched_status(self): + dp = dds.DomainParticipant() + + topic_name = 'ST_subscription_matched_status' + gci = ddsutil.get_dds_classes_from_idl(self.idl_path, self.shape_type_name) + t = gci.register_topic(dp, topic_name) + + rd = dp.create_datareader(t) + + status = rd.subscription_matched_status() + Info = namedtuple('Info', ['name','type']) + attrs = [Info('total_count', int), + Info('total_count_change', int), + Info('current_count', int), + Info('current_count_change', int), + Info('last_publication_handle', int)] + self.assertIsNotNone(status, 'status is None') + self.assertIsInstance(status, dds.SubscriptionMatchedStatus) + for a in attrs: + self.assertTrue(hasattr(status, a.name)) + self.assertIsInstance(getattr(status, a.name), a.type, '{} is not a {}'.format(a.name, a.type)) + + def test_liveliness_changed_status(self): + dp = dds.DomainParticipant() + + topic_name = 'ST_liveliness_changed_status' + gci = ddsutil.get_dds_classes_from_idl(self.idl_path, self.shape_type_name) + t = gci.register_topic(dp, topic_name) + + rd = dp.create_datareader(t) + + status = rd.liveliness_changed_status() + Info = namedtuple('Info', ['name','type']) + attrs = [Info('alive_count', int), + Info('not_alive_count', int), + Info('alive_count_change', int), + Info('not_alive_count_change', int), + Info('last_publication_handle', int)] + self.assertIsNotNone(status, 'status is None') + self.assertIsInstance(status, dds.LivelinessChangedStatus) + for a in attrs: + self.assertTrue(hasattr(status, a.name)) + self.assertIsInstance(getattr(status, a.name), a.type, '{} is not a {}'.format(a.name, a.type)) + + def test_sample_rejected_status(self): + dp = dds.DomainParticipant() + + topic_name = 'ST_sample_rejected_status' + gci = ddsutil.get_dds_classes_from_idl(self.idl_path, self.shape_type_name) + t = gci.register_topic(dp, topic_name) + + rd = dp.create_datareader(t) + + status = rd.sample_rejected_status() + Info = namedtuple('Info', ['name','type']) + attrs = [Info('total_count', int), + Info('total_count_change', int), + Info('last_reason', dds.DDSSampleRejectedStatusKind), + Info('last_instance_handle', int), + ] + self.assertIsNotNone(status, 'status is None') + self.assertIsInstance(status, dds.SampleRejectedStatus) + for a in attrs: + self.assertTrue(hasattr(status, a.name)) + self.assertIsInstance(getattr(status, a.name), a.type, '{} is not a {}'.format(a.name, a.type)) + + def test_sample_lost_status(self): + dp = dds.DomainParticipant() + + topic_name = 'ST_sample_lost_status' + gci = ddsutil.get_dds_classes_from_idl(self.idl_path, self.shape_type_name) + t = gci.register_topic(dp, topic_name) + + rd = dp.create_datareader(t) + + status = rd.sample_lost_status() + Info = namedtuple('Info', ['name','type']) + attrs = [Info('total_count', int), + Info('total_count_change', int), + ] + self.assertIsNotNone(status, 'status is None') + self.assertIsInstance(status, dds.SampleLostStatus) + for a in attrs: + self.assertTrue(hasattr(status, a.name)) + self.assertIsInstance(getattr(status, a.name), a.type, '{} is not a {}'.format(a.name, a.type)) + + #requested_deadline_missed_status + def test_requested_deadline_missed_status(self): + dp = dds.DomainParticipant() + + topic_name = 'ST_requested_deadline_missed_status' + gci = ddsutil.get_dds_classes_from_idl(self.idl_path, self.shape_type_name) + t = gci.register_topic(dp, topic_name) + + rd = dp.create_datareader(t) + + status = rd.requested_deadline_missed_status() + Info = namedtuple('Info', ['name','type']) + attrs = [Info('total_count', int), + Info('total_count_change', int), + Info('last_instance_handle', int), + ] + self.assertIsNotNone(status, 'status is None') + self.assertIsInstance(status, dds.RequestedDeadlineMissedStatus) + for a in attrs: + self.assertTrue(hasattr(status, a.name)) + self.assertIsInstance(getattr(status, a.name), a.type, '{} is not a {}'.format(a.name, a.type)) + + def test_requested_incompatible_qos_status(self): + dp = dds.DomainParticipant() + + topic_name = 'ST_requested_incompatible_qos_status' + gci = ddsutil.get_dds_classes_from_idl(self.idl_path, self.shape_type_name) + t = gci.register_topic(dp, topic_name) + + rd = dp.create_datareader(t) + + status = rd.requested_incompatible_qos_status() + Info = namedtuple('Info', ['name','type']) + attrs = [Info('total_count', int), + Info('total_count_change', int), + Info('last_policy_id', dds.QosPolicyId), + ] + self.assertIsNotNone(status, 'status is None') + self.assertIsInstance(status, dds.RequestedIncompatibleQosStatus) + for a in attrs: + self.assertTrue(hasattr(status, a.name)) + self.assertIsInstance(getattr(status, a.name), a.type, '{} is not a {}'.format(a.name, a.type)) + + +if __name__ == "__main__": + #import sys;sys.argv = ['', 'TestStatusConditions.test_inconsistent_topic_status'] + unittest.main() diff --git a/src/api/dcps/python/test/test_topic_over_the_wire.py b/src/api/dcps/python/test/test_topic_over_the_wire.py new file mode 100644 index 000000000..09f8b1d92 --- /dev/null +++ b/src/api/dcps/python/test/test_topic_over_the_wire.py @@ -0,0 +1,338 @@ +# +# Vortex OpenSplice +# +# This software and documentation are Copyright 2006 to TO_YEAR ADLINK +# Technology Limited, its affiliated companies and licensors. All rights +# reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +''' +Created on Nov 23, 2017 + +@author: prismtech +''' +import sys +from symbol import except_clause +sys.path.append('../dds') +from dds import DomainParticipant, Topic, Listener, Qos, DurabilityQosPolicy, DDSDurabilityKind, DDSException +import unittest +import time +import xmlrunner +import ddsutil +from threading import Event + +# Data available listener +class DataAvailableListener(Listener): + def __init__(self, holder, event): + Listener.__init__(self) + self.holder = holder + self.event = event + + def on_data_available(self, entity): + l = entity.read(10) + for (sd, si) in l: + if si.valid_data: + sd.print_vars() + self.holder.result = str(sd) + self.event.set() + +class ResultHolder(object): + + def __init__(self): + self._result = '' + + @property + def result(self): + return self._result + + @result.setter + def result(self, value): + self._result = value + +class Test(unittest.TestCase): + + + def setUp(self): + pass + + + def tearDown(self): + pass + + + def testAccessingTopicMetaData(self): + idl_path = 'idl/' + 'Thales' + '.idl' + type_info = 'test::C_TopicStruct' + gen_info = ddsutil.get_dds_classes_from_idl(idl_path, type_info) + + dp1 = DomainParticipant() + tq1 = Qos([DurabilityQosPolicy(DDSDurabilityKind.PERSISTENT)]) + topic_dp1 = gen_info.register_topic(dp1, 'DP1_C_TopicStruct',tq1) + + self.assertEqual('DP1_C_TopicStruct', topic_dp1.name, 'Topic name not as expected') + self.assertEqual(type_info, topic_dp1.type_name, 'Type name not as expected') + self.assertEqual('A_ID.A_ID,A_ID.A_subID', topic_dp1.keylist, 'Key list not as expected') + self.assertEqual('', + topic_dp1.metadescriptor, 'Meta descriptor not as expected') + + dp2 = DomainParticipant() + topic_dp2 = dp2.find_topic('DP1_C_TopicStruct') + self.assertIsNotNone(topic_dp2, 'Found topic is not None') + self.assertEqual('DP1_C_TopicStruct', topic_dp2.name, 'Found topic name not as expected') + self.assertEqual(type_info, topic_dp2.type_name, 'Found type name not as expected') + self.assertEqual('A_ID.A_ID,A_ID.A_subID', topic_dp2.keylist, 'Found key list not as expected') + self.assertEqual('', + topic_dp2.metadescriptor, 'Found meta descriptor not as expected') + + pub2 = dp2.create_publisher() + sub2 = dp2.create_subscriber() + try: + wr2 = pub2.create_datawriter(topic_dp2) + self.assertFalse('Expected pub2.create_datawriter to throw exception') + except DDSException: + pass + try: + rd2 = sub2.create_datareader(topic_dp2) + self.assertFalse('Expected sub2.create_datareader to throw exception') + except DDSException: + pass + + # now register the found topic locally, and test reading and writing between the participants + local_topic_dp2 = ddsutil.register_found_topic_as_local(topic_dp2) + + gen_info2 = ddsutil.get_dds_classes_for_found_topic(topic_dp2) + self.assertIsNotNone(gen_info2, 'Returned gen_info2 is None') + + tq2 = topic_dp2.qos + self.assertIsNotNone(tq2) + + # TODO: need get copy topic qos + #local_topic_dp2 = register_topic_locally(topic_dp2) +# local_topic_dp2 = gen_info2.register_topic(dp2, topic_dp2.get_name(), tq2) + + # Reader for dp2 + result_holder = ResultHolder() + event = Event() + rd2 = sub2.create_datareader(local_topic_dp2, tq2, DataAvailableListener(result_holder,event)) + + # Writer for dp1 + pub1 = dp1.create_publisher() + wr1 = pub1.create_datawriter(topic_dp1, tq1) + + # create the data + Outer = gen_info.get_class('test::C_TopicStruct') + Inner = gen_info.get_class('test::T_ID') + data1 = Outer() + data1.A_ID = Inner(A_ID=1,A_subID=12) + data1.A_ForeignIDList = [Inner(A_ID=2,A_subID=23),Inner(A_ID=3,A_subID=34)] + data1.value = 42 + + wr1.write(data1) + + # let the listener catch up... + self.assertTrue(event.wait(10.0), 'wait timed out') + + self.assertEqual(str(data1), result_holder.result, 'read and write results do not match') + + def testSimplifiedFindAPI(self): + idl_path = 'idl/' + 'Thales' + '.idl' + type_info = 'test::C_TopicStruct' + gen_info = ddsutil.get_dds_classes_from_idl(idl_path, type_info) + + dp1 = DomainParticipant() + tq1 = Qos([DurabilityQosPolicy(DDSDurabilityKind.PERSISTENT)]) + topic_dp1 = gen_info.register_topic(dp1, 'DP1_C_TopicStruct_2',tq1) + + self.assertEqual('DP1_C_TopicStruct_2', topic_dp1.name, 'Topic name not as expected') + self.assertEqual(type_info, topic_dp1.type_name, 'Type name not as expected') + self.assertEqual('A_ID.A_ID,A_ID.A_subID', topic_dp1.keylist, 'Key list not as expected') + self.assertEqual('', + topic_dp1.metadescriptor, 'Meta descriptor not as expected') + + dp2 = DomainParticipant() + + topic_dp2, gen_info2 = ddsutil.find_and_register_topic(dp2, 'DP1_C_TopicStruct_2') + self.assertIsNotNone(topic_dp2, 'Found topic is not None') + self.assertEqual('DP1_C_TopicStruct_2', topic_dp2.name, 'Found topic name not as expected') + self.assertEqual(type_info, topic_dp2.type_name, 'Found type name not as expected') + self.assertEqual('A_ID.A_ID,A_ID.A_subID', topic_dp2.keylist, 'Found key list not as expected') + self.assertEqual('', + topic_dp2.metadescriptor, 'Found meta descriptor not as expected') + + sub2 = dp2.create_subscriber() + + # now register the found topic locally, and test reading and writing between the participants + self.assertIsNotNone(gen_info2, 'Returned gen_info2 is None') + + tq2 = topic_dp2.qos + self.assertIsNotNone(tq2) + + # TODO: need get copy topic qos + #local_topic_dp2 = register_topic_locally(topic_dp2) +# local_topic_dp2 = gen_info2.register_topic(dp2, topic_dp2.get_name(), tq2) + + # Reader for dp2 + result_holder = ResultHolder() + event = Event() + rd2 = sub2.create_datareader(topic_dp2, tq2, DataAvailableListener(result_holder, event)) + + # Writer for dp1 + pub1 = dp1.create_publisher() + wr1 = pub1.create_datawriter(topic_dp1, tq1) + + # create the data + Outer = gen_info.get_class('test::C_TopicStruct') + Inner = gen_info.get_class('test::T_ID') + data1 = Outer() + data1.A_ID = Inner(A_ID=21,A_subID=212) + data1.A_ForeignIDList = [Inner(A_ID=22,A_subID=223),Inner(A_ID=23,A_subID=234)] + data1.value = 242 + + wr1.write(data1) + + # let the listener catch up... + self.assertTrue(event.wait(10.0), 'wait timed out') + + self.assertEqual(str(data1), result_holder.result, 'read and write results do not match') + + def testSimplifiedFindAPIWithNamedTuple(self): + idl_path = 'idl/' + 'Thales' + '.idl' + type_info = 'test::C_TopicStruct' + gen_info = ddsutil.get_dds_classes_from_idl(idl_path, type_info) + + dp1 = DomainParticipant() + tq1 = Qos([DurabilityQosPolicy(DDSDurabilityKind.PERSISTENT)]) + topic_dp1 = gen_info.register_topic(dp1, 'DP1_C_TopicStruct_3',tq1) + + self.assertEqual('DP1_C_TopicStruct_3', topic_dp1.name, 'Topic name not as expected') + self.assertEqual(type_info, topic_dp1.type_name, 'Type name not as expected') + self.assertEqual('A_ID.A_ID,A_ID.A_subID', topic_dp1.keylist, 'Key list not as expected') + self.assertEqual('', + topic_dp1.metadescriptor, 'Meta descriptor not as expected') + + dp2 = DomainParticipant() + + topic_info = ddsutil.find_and_register_topic(dp2, 'DP1_C_TopicStruct_3') + + self.assertIsNotNone(topic_info.topic, 'Found topic is not None') + self.assertEqual('DP1_C_TopicStruct_3', topic_info.topic.name, 'Found topic name not as expected') + self.assertEqual(type_info, topic_info.topic.type_name, 'Found type name not as expected') + self.assertEqual('A_ID.A_ID,A_ID.A_subID', topic_info.topic.keylist, 'Found key list not as expected') + self.assertEqual('', + topic_info.topic.metadescriptor, 'Found meta descriptor not as expected') + + sub2 = dp2.create_subscriber() + + # now register the found topic locally, and test reading and writing between the participants + self.assertIsNotNone(topic_info.gen_info, 'Returned topic_info.gen_info is None') + + tq2 = topic_info.topic.qos + self.assertIsNotNone(tq2) + + # TODO: need get copy topic qos + #local_topic_dp2 = register_topic_locally(topic_dp2) +# local_topic_dp2 = gen_info2.register_topic(dp2, topic_dp2.get_name(), tq2) + + # Reader for dp2 + result_holder = ResultHolder() + event = Event() + rd2 = sub2.create_datareader(topic_info.topic, tq2, DataAvailableListener(result_holder, event)) + + # Writer for dp1 + pub1 = dp1.create_publisher() + wr1 = pub1.create_datawriter(topic_dp1, tq1) + + # create the data + Outer = gen_info.get_class('test::C_TopicStruct') + Inner = gen_info.get_class('test::T_ID') + data1 = Outer() + data1.A_ID = Inner(A_ID=31,A_subID=312) + data1.A_ForeignIDList = [Inner(A_ID=32,A_subID=323),Inner(A_ID=33,A_subID=334)] + data1.value = 342 + + wr1.write(data1) + + # let the listener catch up... + self.assertTrue(event.wait(10.0), 'wait timed out') + + self.assertEqual(str(data1), result_holder.result, 'read and write results do not match') + + def testSimplifiedFindAPIWithNamedTupleAndDefaultPubSub(self): + idl_path = 'idl/' + 'Thales' + '.idl' + type_info = 'test::C_TopicStruct' + gen_info = ddsutil.get_dds_classes_from_idl(idl_path, type_info) + + dp1 = DomainParticipant() + tq1 = Qos([DurabilityQosPolicy(DDSDurabilityKind.PERSISTENT)]) + topic_dp1 = gen_info.register_topic(dp1, 'DP1_C_TopicStruct_4',tq1) + + self.assertEqual('DP1_C_TopicStruct_4', topic_dp1.name, 'Topic name not as expected') + self.assertEqual(type_info, topic_dp1.type_name, 'Type name not as expected') + self.assertEqual('A_ID.A_ID,A_ID.A_subID', topic_dp1.keylist, 'Key list not as expected') + self.assertEqual('', + topic_dp1.metadescriptor, 'Meta descriptor not as expected') + + dp2 = DomainParticipant() + + topic_info = ddsutil.find_and_register_topic(dp2, 'DP1_C_TopicStruct_4') + + self.assertIsNotNone(topic_info.topic, 'Found topic is not None') + self.assertEqual('DP1_C_TopicStruct_4', topic_info.topic.name, 'Found topic name not as expected') + self.assertEqual(type_info, topic_info.topic.type_name, 'Found type name not as expected') + self.assertEqual('A_ID.A_ID,A_ID.A_subID', topic_info.topic.keylist, 'Found key list not as expected') + self.assertEqual('', + topic_info.topic.metadescriptor, 'Found meta descriptor not as expected') + + # now register the found topic locally, and test reading and writing between the participants + self.assertIsNotNone(topic_info.gen_info, 'Returned topic_info.gen_info is None') + + tq2 = topic_info.topic.qos + self.assertIsNotNone(tq2) + + # TODO: need get copy topic qos + #local_topic_dp2 = register_topic_locally(topic_dp2) +# local_topic_dp2 = gen_info2.register_topic(dp2, topic_dp2.get_name(), tq2) + + # Reader for dp2 + result_holder = ResultHolder() + event = Event() + rd2 = dp2.create_datareader(topic_info.topic, tq2, DataAvailableListener(result_holder, event)) + + # Writer for dp1 + wr1 = dp1.create_datawriter(topic_dp1, tq1) + + # create the data + Outer = gen_info.get_class('test::C_TopicStruct') + Inner = gen_info.get_class('test::T_ID') + data1 = Outer() + data1.A_ID = Inner(A_ID=41,A_subID=412) + data1.A_ForeignIDList = [Inner(A_ID=42,A_subID=423),Inner(A_ID=43,A_subID=434)] + data1.value = 442 + + wr1.write(data1) + + # let the listener catch up... + self.assertTrue(event.wait(10.0), 'wait timed out') + + self.assertEqual(str(data1), result_holder.result, 'read and write results do not match') + + + + +if __name__ == "__main__": + #import sys;sys.argv = ['', 'Test.testAccessingTopicMetaData'] + unittest.main(testRunner=xmlrunner.XMLTestRunner(output='test-reports'), + # these make sure that some options that are not applicable + # remain hidden from the help menu. + failfast=False, buffer=False, catchbreak=False) \ No newline at end of file diff --git a/src/api/dcps/python/test/test_type_checkers.py b/src/api/dcps/python/test/test_type_checkers.py new file mode 100644 index 000000000..f5100452d --- /dev/null +++ b/src/api/dcps/python/test/test_type_checkers.py @@ -0,0 +1,258 @@ +# +# Vortex OpenSplice +# +# This software and documentation are Copyright 2006 to TO_YEAR ADLINK +# Technology Limited, its affiliated companies and licensors. All rights +# reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +''' +Created on Dec 22, 2017 + +@author: prismtech +''' +import unittest +import ddsutil +import enum + +class MyEnum(enum.Enum): + ONE = 0 + TWO = 1 + +class TestTypeCheckers(unittest.TestCase): + + + _bool_checker = ddsutil._bool_checker + def testBool(self): + self.assertRaises(TypeError, lambda: self._bool_checker(None)) + self.assertRaises(TypeError, lambda: self._bool_checker(1)) + self._bool_checker(True) + self._bool_checker(False) + + _octet_checker = ddsutil._octet_checker + _ushort_checker = ddsutil._ushort_checker + _ulong_checker = ddsutil._ulong_checker + _ulonglong_checker = ddsutil._ulonglong_checker + _short_checker = ddsutil._short_checker + _long_checker = ddsutil._long_checker + _longlong_checker = ddsutil._longlong_checker + def testOctet(self): + self.assertRaises(TypeError, lambda: self._octet_checker(None)) + self.assertRaises(TypeError, lambda: self._octet_checker(3.5)) + self.assertRaises(TypeError, lambda: self._octet_checker('a')) + self.assertRaises(TypeError, lambda: self._octet_checker(b'a')) + self.assertRaises(TypeError, lambda: self._octet_checker(-1)) + self.assertRaises(TypeError, lambda: self._octet_checker(256)) + self.assertRaises(TypeError, lambda: self._octet_checker(-1000)) + self.assertRaises(TypeError, lambda: self._octet_checker(2560)) + self._octet_checker(0) + self._octet_checker(128) + self._octet_checker(255) + + def testUShort(self): + self.assertRaises(TypeError, lambda: self._ushort_checker(None)) + self.assertRaises(TypeError, lambda: self._ushort_checker(3.5)) + self.assertRaises(TypeError, lambda: self._ushort_checker('a')) + self.assertRaises(TypeError, lambda: self._ushort_checker(b'a')) + self.assertRaises(TypeError, lambda: self._ushort_checker(-1)) + self.assertRaises(TypeError, lambda: self._ushort_checker((1<<16))) + self.assertRaises(TypeError, lambda: self._ushort_checker(-1000)) + self.assertRaises(TypeError, lambda: self._ushort_checker(350000)) + self._ushort_checker(0) + self._ushort_checker((1<<15)) + self._ushort_checker((1<<16)-1) + + def testULong(self): + self.assertRaises(TypeError, lambda: self._ulong_checker(None)) + self.assertRaises(TypeError, lambda: self._ulong_checker(3.5)) + self.assertRaises(TypeError, lambda: self._ulong_checker('a')) + self.assertRaises(TypeError, lambda: self._ulong_checker(b'a')) + self.assertRaises(TypeError, lambda: self._ulong_checker(-1)) + self.assertRaises(TypeError, lambda: self._ulong_checker((1<<32))) + self.assertRaises(TypeError, lambda: self._ulong_checker(-1000)) + self.assertRaises(TypeError, lambda: self._ulong_checker((1<<40))) + self._ulong_checker(0) + self._ulong_checker((1<<31)) + self._ulong_checker((1<<32)-1) + + def testULongLong(self): + self.assertRaises(TypeError, lambda: self._ulonglong_checker(None)) + self.assertRaises(TypeError, lambda: self._ulonglong_checker(3.5)) + self.assertRaises(TypeError, lambda: self._ulonglong_checker('a')) + self.assertRaises(TypeError, lambda: self._ulonglong_checker(b'a')) + self.assertRaises(TypeError, lambda: self._ulonglong_checker(-1)) + self.assertRaises(TypeError, lambda: self._ulonglong_checker((1<<64))) + self.assertRaises(TypeError, lambda: self._ulonglong_checker(-1000)) + self.assertRaises(TypeError, lambda: self._ulonglong_checker((1<<66))) + self._ulonglong_checker(0) + self._ulonglong_checker((1<<60)) + self._ulonglong_checker((1<<64)-1) + + def testShort(self): + self.assertRaises(TypeError, lambda: self._short_checker(None)) + self.assertRaises(TypeError, lambda: self._short_checker(3.5)) + self.assertRaises(TypeError, lambda: self._short_checker('a')) + self.assertRaises(TypeError, lambda: self._short_checker(b'a')) + self.assertRaises(TypeError, lambda: self._short_checker(-(1<<15) - 1)) # right outside the bounds + self.assertRaises(TypeError, lambda: self._short_checker((1<<15))) # right outside the bounds + self.assertRaises(TypeError, lambda: self._short_checker(-(1<<16) - 1)) # well outside the bounds + self.assertRaises(TypeError, lambda: self._short_checker((1<<16))) # well outside the bounds + self._short_checker(-(1<<15)) + self._short_checker(-5) + self._short_checker(0) + self._short_checker(5) + self._short_checker((1<<15)-1) + + def testLong(self): + self.assertRaises(TypeError, lambda: self._long_checker(None)) + self.assertRaises(TypeError, lambda: self._long_checker(3.5)) + self.assertRaises(TypeError, lambda: self._long_checker('a')) + self.assertRaises(TypeError, lambda: self._long_checker(b'a')) + self.assertRaises(TypeError, lambda: self._long_checker(-(1<<31) - 1)) # right outside the bounds + self.assertRaises(TypeError, lambda: self._long_checker((1<<31))) # right outside the bounds + self.assertRaises(TypeError, lambda: self._long_checker(-(1<<32) - 1)) # well outside the bounds + self.assertRaises(TypeError, lambda: self._long_checker((1<<32))) # well outside the bounds + self._long_checker(-(1<<31)) + self._long_checker(-5) + self._long_checker(0) + self._long_checker(5) + self._long_checker((1<<31)-1) + + def testLongLong(self): + self.assertRaises(TypeError, lambda: self._longlong_checker(None)) + self.assertRaises(TypeError, lambda: self._longlong_checker(3.5)) + self.assertRaises(TypeError, lambda: self._longlong_checker('a')) + self.assertRaises(TypeError, lambda: self._longlong_checker(b'a')) + self.assertRaises(TypeError, lambda: self._longlong_checker(-(1<<63) - 1)) # right outside the bounds + self.assertRaises(TypeError, lambda: self._longlong_checker((1<<63))) # right outside the bounds + self.assertRaises(TypeError, lambda: self._longlong_checker(-(1<<64) - 1)) # well outside the bounds + self.assertRaises(TypeError, lambda: self._longlong_checker((1<<64))) # well outside the bounds + self._longlong_checker(-(1<<63)) + self._longlong_checker(-5) + self._longlong_checker(0) + self._longlong_checker(5) + self._longlong_checker((1<<63)-1) + + _char_checker = ddsutil._char_checker + def testChar(self): + self.assertRaises(TypeError, lambda: self._char_checker(None)) + self.assertRaises(TypeError, lambda: self._char_checker(3)) + self.assertRaises(TypeError, lambda: self._char_checker(b'a')) + self.assertRaises(TypeError, lambda: self._char_checker('')) + self.assertRaises(TypeError, lambda: self._char_checker('aa')) + self.assertRaises(TypeError, lambda: self._char_checker(chr(256))) + self._char_checker(chr(0)) + self._char_checker('1') + self._char_checker(chr(255)) + + _str_checker = ddsutil._str_checker + _str2_checker = ddsutil._bounded_str_checker(2) + def testStr(self): + self.assertRaises(TypeError, lambda: self._str2_checker(None)) + self.assertRaises(TypeError, lambda: self._str2_checker(3)) + self.assertRaises(TypeError, lambda: self._str2_checker(b'a')) + self.assertRaises(TypeError, lambda: self._str2_checker('aab')) + self.assertRaises(TypeError, lambda: self._str2_checker(chr(256))) + self._str2_checker('') + self._str2_checker(chr(0)) + self._str2_checker('1') + self._str2_checker('11') + self._str2_checker(chr(255)) + + _enum_checker = ddsutil._class_checker(MyEnum) + def testClass(self): + self.assertRaises(TypeError, lambda: self._enum_checker(None)) + self.assertRaises(TypeError, lambda: self._enum_checker(1)) + self.assertRaises(TypeError, lambda: self._enum_checker('A')) + self._enum_checker(MyEnum.ONE) + self._enum_checker(MyEnum.TWO) + + _float_checker = ddsutil._float_checker + def testFloat(self): + self.assertRaises(TypeError, lambda: self._float_checker(None)) + self.assertRaises(TypeError, lambda: self._float_checker(1)) + self.assertRaises(TypeError, lambda: self._float_checker('A')) + self._float_checker(3.15) + self._float_checker(1.0) + self._float_checker(-9.183) + + _long_array_checker = ddsutil._array_checker(2, ddsutil._long_checker) + def testLongArray(self): + self.assertRaises(TypeError, lambda: self._long_array_checker(None)) + self.assertRaises(TypeError, lambda: self._long_array_checker(1)) + self.assertRaises(TypeError, lambda: self._long_array_checker(1.0)) + self.assertRaises(TypeError, lambda: self._long_array_checker('A')) + self.assertRaises(TypeError, lambda: self._long_array_checker([])) + self.assertRaises(TypeError, lambda: self._long_array_checker([1])) + self.assertRaises(TypeError, lambda: self._long_array_checker([1,2,3])) + self.assertRaises(TypeError, lambda: self._long_array_checker([1.0,2])) + self.assertRaises(TypeError, lambda: self._long_array_checker([1,2.0])) + self.assertRaises(TypeError, lambda: self._long_array_checker([1<<32,2])) + self.assertRaises(TypeError, lambda: self._long_array_checker([1,1<<32])) + self._long_array_checker([1,2]) + self._long_array_checker([-(1<<31),(1<<31)-1]) + + _long_seq_checker = ddsutil._seq_checker(2, ddsutil._long_checker) + def testLongSeq(self): + self.assertRaises(TypeError, lambda: self._long_seq_checker(None)) + self.assertRaises(TypeError, lambda: self._long_seq_checker(1)) + self.assertRaises(TypeError, lambda: self._long_seq_checker(1.0)) + self.assertRaises(TypeError, lambda: self._long_seq_checker('A')) + self.assertRaises(TypeError, lambda: self._long_seq_checker([1,2,3])) + self.assertRaises(TypeError, lambda: self._long_seq_checker([1.0,2])) + self.assertRaises(TypeError, lambda: self._long_seq_checker([1,2.0])) + self.assertRaises(TypeError, lambda: self._long_seq_checker([1<<32,2])) + self.assertRaises(TypeError, lambda: self._long_seq_checker([1,1<<32])) + self._long_seq_checker([]) + self._long_seq_checker([1]) + self._long_seq_checker([1,2]) + self._long_seq_checker([-(1<<31),(1<<31)-1]) + + _long_ubseq_checker = ddsutil._seq_checker(0, ddsutil._long_checker) + def testLongUBSeq(self): + self.assertRaises(TypeError, lambda: self._long_ubseq_checker(None)) + self.assertRaises(TypeError, lambda: self._long_ubseq_checker(1)) + self.assertRaises(TypeError, lambda: self._long_ubseq_checker(1.0)) + self.assertRaises(TypeError, lambda: self._long_ubseq_checker('A')) + self.assertRaises(TypeError, lambda: self._long_ubseq_checker([1.0,2])) + self.assertRaises(TypeError, lambda: self._long_ubseq_checker([1,2.0])) + self.assertRaises(TypeError, lambda: self._long_ubseq_checker([1<<32,2])) + self.assertRaises(TypeError, lambda: self._long_ubseq_checker([1,1<<32])) + self._long_ubseq_checker([]) + self._long_ubseq_checker([1]) + self._long_ubseq_checker([1,2]) + self._long_ubseq_checker([1,2,3,4,5]) + self._long_ubseq_checker([-(1<<31),(1<<31)-1]) + + _long_matrix_checker = ddsutil._array_checker(1,ddsutil._array_checker(2,ddsutil._long_checker)) + def testLongMatrix(self): + self.assertRaises(TypeError, lambda: self._long_matrix_checker([])) + self.assertRaises(TypeError, lambda: self._long_matrix_checker([[]])) + self.assertRaises(TypeError, lambda: self._long_matrix_checker([[1]])) + self.assertRaises(TypeError, lambda: self._long_matrix_checker([[1,2,3]])) + self.assertRaises(TypeError, lambda: self._long_matrix_checker([[1,2],[3,4]])) + self._long_matrix_checker([[1,2]]) + + _long_seqseq_checker = ddsutil._seq_checker(1,ddsutil._seq_checker(2,ddsutil._long_checker)) + def testLongSeqSeq(self): + self._long_seqseq_checker([]) + self._long_seqseq_checker([[]]) + self._long_seqseq_checker([[1]]) + self._long_seqseq_checker([[1,2]]) + self.assertRaises(TypeError, lambda: self._long_seqseq_checker([[1,2,3]])) + self.assertRaises(TypeError, lambda: self._long_seqseq_checker([[1,2],[3,4]])) + +if __name__ == "__main__": + #import sys;sys.argv = ['', 'Test.testName'] + unittest.main() \ No newline at end of file diff --git a/src/api/dcps/sac/code/sac_common.c b/src/api/dcps/sac/code/sac_common.c index 3b0d2f64e..ff6cc8090 100644 --- a/src/api/dcps/sac/code/sac_common.c +++ b/src/api/dcps/sac/code/sac_common.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,6 +24,7 @@ #include "sac_common.h" #include "sac_entity.h" #include "u_dataViewQos.h" +#include "u_instanceHandle.h" #include "v_kernel.h" #include "kernelModule.h" #include "c_stringSupport.h" @@ -1196,6 +1198,13 @@ validResourceLimitsQosPolicy ( SAC_REPORT(DDS_RETCODE_BAD_PARAMETER, "Invalid max_samples_per_instance = %d", policy->max_samples_per_instance); } + if ( (policy->max_samples != DDS_LENGTH_UNLIMITED) && + (policy->max_samples_per_instance != DDS_LENGTH_UNLIMITED) && + (policy->max_samples < policy->max_samples_per_instance) ) { + valid = FALSE; + SAC_REPORT(DDS_RETCODE_BAD_PARAMETER, "Invalid max_samples(%d) < max_samples_per_instance(%d)", + policy->max_samples, policy->max_samples_per_instance); + } return valid; } @@ -3234,3 +3243,17 @@ DDS_PublicationMatchedStatus_init ( status->last_subscription_handle = u_instanceHandleFromGID(info->instanceHandle); } +DDS_ReturnCode_t +DDS_InstanceHandle_set_userdata( + DDS_InstanceHandle_t handle, + void *userData) +{ + return DDS_ReturnCode_get(u_instanceHandleSetUserData((u_instanceHandle)handle, userData)); +} + +void * +DDS_InstanceHandle_get_userdata( + DDS_InstanceHandle_t handle) +{ + return u_instanceHandleGetUserData((u_instanceHandle)handle); +} diff --git a/src/api/dcps/sac/code/sac_common.h b/src/api/dcps/sac/code/sac_common.h index 3fee1517f..124757d63 100644 --- a/src/api/dcps/sac/code/sac_common.h +++ b/src/api/dcps/sac/code/sac_common.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/dcps/sac/code/sac_condition.c b/src/api/dcps/sac/code/sac_condition.c index 510915b4a..af72f2d6c 100644 --- a/src/api/dcps/sac/code/sac_condition.c +++ b/src/api/dcps/sac/code/sac_condition.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -93,10 +94,6 @@ DDS_Condition_init ( return DDS_RETCODE_OK; } -/* - * boolean - * get_trigger_value(); - */ DDS_boolean DDS_Condition_get_trigger_value ( DDS_Condition _this) diff --git a/src/api/dcps/sac/code/sac_condition.h b/src/api/dcps/sac/code/sac_condition.h index 122649c32..23b493334 100644 --- a/src/api/dcps/sac/code/sac_condition.h +++ b/src/api/dcps/sac/code/sac_condition.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/dcps/sac/code/sac_contentFilteredTopic.c b/src/api/dcps/sac/code/sac_contentFilteredTopic.c index 9b0bf1760..19155faa0 100644 --- a/src/api/dcps/sac/code/sac_contentFilteredTopic.c +++ b/src/api/dcps/sac/code/sac_contentFilteredTopic.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -150,8 +151,8 @@ DDS_ContentFilteredTopicNew ( return (DDS_Topic)topic; } -/* string - * get_filter_expression(); +/* string + * get_filter_expression(); */ DDS_string DDS_ContentFilteredTopic_get_filter_expression ( @@ -173,8 +174,8 @@ DDS_ContentFilteredTopic_get_filter_expression ( return expr; } -/* StringSeq - * get_expression_parameters(); +/* StringSeq + * get_expression_parameters(); */ DDS_ReturnCode_t DDS_ContentFilteredTopic_get_expression_parameters ( @@ -198,9 +199,9 @@ DDS_ContentFilteredTopic_get_expression_parameters ( return result; } -/* ReturnCode_t - * set_expression_parameters( - * in StringSeq expression_parameters); +/* ReturnCode_t + * set_expression_parameters( + * in StringSeq expression_parameters); */ DDS_ReturnCode_t DDS_ContentFilteredTopic_set_expression_parameters ( @@ -216,7 +217,8 @@ DDS_ContentFilteredTopic_set_expression_parameters ( DDS_ReturnCode_t DDS_ContentFilteredTopic_get_parameters ( DDS_ContentFilteredTopic _this, - c_value **params) + c_value **params, + DDS_unsigned_long *nrOfParams) { DDS_ReturnCode_t result; _ContentFilteredTopic topic; @@ -234,8 +236,10 @@ DDS_ContentFilteredTopic_get_parameters ( for (n=0;n_length;n++) { (*params)[n] = c_stringValue(parms->_buffer[n]); } + *nrOfParams = parms->_length; } else { *params = NULL; + *nrOfParams = 0; } DDS_ContentFilteredTopicRelease(_this); } @@ -248,8 +252,8 @@ DDS_ContentFilteredTopic_get_parameters ( return result; } -/* Topic - * get_related_topic(); +/* Topic + * get_related_topic(); */ DDS_Topic DDS_ContentFilteredTopic_get_related_topic ( diff --git a/src/api/dcps/sac/code/sac_contentFilteredTopic.h b/src/api/dcps/sac/code/sac_contentFilteredTopic.h index 05998e9c3..47b962bcb 100644 --- a/src/api/dcps/sac/code/sac_contentFilteredTopic.h +++ b/src/api/dcps/sac/code/sac_contentFilteredTopic.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -34,6 +35,7 @@ DDS_ContentFilteredTopicNew ( DDS_ReturnCode_t DDS_ContentFilteredTopic_get_parameters ( DDS_ContentFilteredTopic _this, - c_value **params); + c_value **params, + DDS_unsigned_long *nrOfParams); #endif diff --git a/src/api/dcps/sac/code/sac_dataReader.c b/src/api/dcps/sac/code/sac_dataReader.c index 423fe14cc..5ac7a1447 100644 --- a/src/api/dcps/sac/code/sac_dataReader.c +++ b/src/api/dcps/sac/code/sac_dataReader.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -247,16 +248,16 @@ DDS_DataReaderNew ( u_subscriber uSubscriber; u_dataReader uReader; u_readerQos rQos = NULL; - os_char *expr; - c_value *params; + os_char *expr = NULL; + c_value *params = NULL; + os_uint32 nrOfParams = 0; result = DDS_TopicDescription_get_typeSupport(tdesc, &typeSupport); if (typeSupport == NULL) { result = DDS_RETCODE_PRECONDITION_NOT_MET; SAC_REPORT(result, "No TypeSupport registered for TopicDescription"); } - /* - * Translate parameters to kernel representation. QoS is guaranteed to be + /* Translate parameters to kernel representation. QoS is guaranteed to be * consistent at this point. */ if (result == DDS_RETCODE_OK) { @@ -268,15 +269,13 @@ DDS_DataReaderNew ( } if (result == DDS_RETCODE_OK) { if (DDS_Object_get_kind(tdesc) == DDS_CONTENTFILTEREDTOPIC) { - result = DDS_ContentFilteredTopic_get_parameters(tdesc, ¶ms); - } else { - params = NULL; + result = DDS_ContentFilteredTopic_get_parameters(tdesc, ¶ms, &nrOfParams); } if (result == DDS_RETCODE_OK) { uSubscriber = u_subscriber(_Entity_get_user_entity(subscriber)); if (uSubscriber != NULL) { expr = DDS_TopicDescription_get_expr(tdesc); - uReader = u_dataReaderNew(uSubscriber, name, expr, params, rQos, FALSE); + uReader = u_dataReaderNew(uSubscriber, name, expr, params, nrOfParams, rQos); os_free(expr); if (uReader!= NULL) { result = DDS_Object_new(DDS_DATAREADER, _DataReader_deinit, (_Object *)&_this); @@ -342,11 +341,11 @@ DDS_DataReaderFree ( return result; } -/* ReadCondition - * create_readcondition( - * in SampleStateMask sample_states, - * in ViewStateMask view_states, - * in InstanceStateMask instance_states); +/* ReadCondition + * create_readcondition( + * in SampleStateMask sample_states, + * in ViewStateMask view_states, + * in InstanceStateMask instance_states); */ DDS_ReadCondition DDS_DataReader_create_readcondition ( @@ -373,13 +372,13 @@ DDS_DataReader_create_readcondition ( return rc; } -/* QueryCondition - * create_querycondition( - * in SampleStateMask sample_states, - * in ViewStateMask view_states, - * in InstanceStateMask instance_states, - * in string query_expression, - * in StringSeq query_parameters); +/* QueryCondition + * create_querycondition( + * in SampleStateMask sample_states, + * in ViewStateMask view_states, + * in InstanceStateMask instance_states, + * in string query_expression, + * in StringSeq query_parameters); */ DDS_QueryCondition DDS_DataReader_create_querycondition ( @@ -409,9 +408,9 @@ DDS_DataReader_create_querycondition ( return qc; } -/* ReturnCode_t - * delete_readcondition( - * in ReadCondition a_condition); +/* ReturnCode_t + * delete_readcondition( + * in ReadCondition a_condition); */ DDS_ReturnCode_t DDS_DataReader_delete_readcondition ( @@ -499,8 +498,8 @@ DDS_DataReader_contains_entity ( return arg.result; } -/* ReturnCode_t - * delete_contained_entities(); +/* ReturnCode_t + * delete_contained_entities(); */ DDS_ReturnCode_t DDS_DataReader_delete_contained_entities ( @@ -520,9 +519,9 @@ DDS_DataReader_delete_contained_entities ( return result; } -/* DataReaderView - * create_view ( - * in DataReaderViewQos * qos); +/* DataReaderView + * create_view ( + * in DataReaderViewQos * qos); */ DDS_DataReaderView DDS_DataReader_create_view ( @@ -565,9 +564,9 @@ DDS_DataReader_create_view ( return DDS_DataReaderView(view); } -/* ReturnCode_t - * delete_view( - * in DataReaderView a_view); +/* ReturnCode_t + * delete_view( + * in DataReaderView a_view); */ DDS_ReturnCode_t DDS_DataReader_delete_view ( @@ -613,9 +612,9 @@ DDS_DataReader_delete_view ( } -/* ReturnCode_t - * set_qos( - * in DataReaderQos qos); +/* ReturnCode_t + * set_qos( + * in DataReaderQos qos); */ DDS_ReturnCode_t DDS_DataReader_set_qos ( @@ -675,9 +674,9 @@ DDS_DataReader_set_qos ( return result; } -/* ReturnCode_t - * get_qos( - * inout DataReaderQos qos); +/* ReturnCode_t + * get_qos( + * inout DataReaderQos qos); */ DDS_ReturnCode_t DDS_DataReader_get_qos ( @@ -717,10 +716,10 @@ DDS_DataReader_get_qos ( return result; } -/* ReturnCode_t - * set_listener( - * in DataReaderListener a_listener, - * in StatusKindMask mask); +/* ReturnCode_t + * set_listener( + * in DataReaderListener a_listener, + * in StatusKindMask mask); */ DDS_ReturnCode_t DDS_DataReader_set_listener ( @@ -748,8 +747,8 @@ DDS_DataReader_set_listener ( return result; } -/* DataReaderListener - * get_listener(); +/* DataReaderListener + * get_listener(); */ struct DDS_DataReaderListener DDS_DataReader_get_listener ( @@ -771,10 +770,10 @@ DDS_DataReader_get_listener ( return listener; } -/* ReturnCode_t - * set_listener_mask( - * in DataReaderListener a_listener, - * in StatusKindMask mask); +/* ReturnCode_t + * set_listener_mask( + * in DataReaderListener a_listener, + * in StatusKindMask mask); */ DDS_ReturnCode_t DDS_DataReader_set_listener_mask ( @@ -790,8 +789,8 @@ DDS_DataReader_set_listener_mask ( return result; } -/* TopicDescription - * get_topicdescription(); +/* TopicDescription + * get_topicdescription(); */ DDS_TopicDescription DDS_DataReader_get_topicdescription ( @@ -811,8 +810,8 @@ DDS_DataReader_get_topicdescription ( return td; } -/* Subscriber - * get_subscriber(); +/* Subscriber + * get_subscriber(); */ DDS_Subscriber DDS_DataReader_get_subscriber ( @@ -866,8 +865,8 @@ copy_sample_rejected_status( } /* ReturnCode_t - *get_sample_rejected_status( - *inout SampleRejectedStatus status); + * get_sample_rejected_status( + * inout SampleRejectedStatus status); */ DDS_ReturnCode_t DDS_DataReader_get_sample_rejected_status ( @@ -920,8 +919,8 @@ copy_liveliness_changed_status( } /* ReturnCode_t - *get_liveliness_changed_status( - *inout LivelinessChangedStatus status); + * get_liveliness_changed_status( + * inout LivelinessChangedStatus status); */ DDS_ReturnCode_t DDS_DataReader_get_liveliness_changed_status ( @@ -983,8 +982,8 @@ copy_deadline_missed_status( } /* ReturnCode_t - *get_requested_deadline_missed_status( - *inout RequestedDeadlineMissedStatus status); + * get_requested_deadline_missed_status( + * inout RequestedDeadlineMissedStatus status); */ DDS_ReturnCode_t DDS_DataReader_get_requested_deadline_missed_status ( @@ -1067,8 +1066,8 @@ copy_incompatible_qos_status( } /* ReturnCode_t - *get_requested_incompatible_qos_status( - *inout RequestedIncompatibleQosStatus status); + * get_requested_incompatible_qos_status( + * inout RequestedIncompatibleQosStatus status); */ DDS_ReturnCode_t DDS_DataReader_get_requested_incompatible_qos_status ( @@ -1117,8 +1116,8 @@ copy_sample_lost_status( } /* ReturnCode_t - *get_sample_lost_status( - *inout SampleLostStatus status); + * get_sample_lost_status( + * inout SampleLostStatus status); */ DDS_ReturnCode_t DDS_DataReader_get_sample_lost_status ( @@ -1201,9 +1200,9 @@ DDS_DataReader_get_subscription_matched_status ( return result; } -/* ReturnCode_t - * wait_for_historical_data( - * in Duration_t max_wait); +/* ReturnCode_t + * wait_for_historical_data( + * in Duration_t max_wait); */ DDS_ReturnCode_t DDS_DataReader_wait_for_historical_data ( @@ -1350,8 +1349,9 @@ copy_matched_publication( return V_RESULT_OK; } -/* ReturnCode_t get_matched_publications( - * inout InstanceHandleSeq publication_handles); +/* ReturnCode_t + * get_matched_publications( + * inout InstanceHandleSeq publication_handles); */ DDS_ReturnCode_t DDS_DataReader_get_matched_publications ( @@ -1395,10 +1395,10 @@ ___DDS_PublicationBuiltinTopicData__copyOut( return V_RESULT_OK; } -/* ReturnCode_t - * get_matched_publication_data( - * inout PublicationBuiltinTopicData publication_data, - * in InstanceHandle_t publication_handle); +/* ReturnCode_t + * get_matched_publication_data( + * inout PublicationBuiltinTopicData publication_data, + * in InstanceHandle_t publication_handle); */ DDS_ReturnCode_t DDS_DataReader_get_matched_publication_data ( @@ -1430,9 +1430,9 @@ DDS_DataReader_get_matched_publication_data ( return result; } -/* ReturnCode_t - * set_default_datareaderview_qos( - * in DataReaderViewQos qos); +/* ReturnCode_t + * set_default_datareaderview_qos( + * in DataReaderViewQos qos); */ DDS_ReturnCode_t DDS_DataReader_set_default_datareaderview_qos ( @@ -1474,9 +1474,9 @@ DDS_DataReader_set_default_datareaderview_qos ( return result; } -/* ReturnCode_t - * get_default_datareaderview_qos( - * inout DataReaderViewQos qos); +/* ReturnCode_t + * get_default_datareaderview_qos( + * inout DataReaderViewQos qos); */ DDS_ReturnCode_t DDS_DataReader_get_default_datareaderview_qos ( diff --git a/src/api/dcps/sac/code/sac_dataReader.h b/src/api/dcps/sac/code/sac_dataReader.h index 4cc88857d..d2e950017 100644 --- a/src/api/dcps/sac/code/sac_dataReader.h +++ b/src/api/dcps/sac/code/sac_dataReader.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/dcps/sac/code/sac_dataReaderView.c b/src/api/dcps/sac/code/sac_dataReaderView.c index 83eb1f391..6cd5ced80 100644 --- a/src/api/dcps/sac/code/sac_dataReaderView.c +++ b/src/api/dcps/sac/code/sac_dataReaderView.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -245,8 +246,8 @@ DDS_DataReaderViewFree ( } -/* From Entity - * get_statuscondition +/* From Entity + * get_statuscondition */ DDS_StatusCondition DDS_DataReaderView_get_statuscondition( @@ -257,7 +258,7 @@ DDS_DataReaderView_get_statuscondition( return DDS_StatusCondition(DDS_HANDLE_NIL); } -/* From Entity +/* From Entity * DDS_DataReaderView_get_status_changes */ DDS_StatusMask @@ -278,9 +279,9 @@ DDS_DataReaderView_get_status_changes( return mask; } -/* ReturnCode_t - * set_qos( - * in DataReaderViewQos qos); +/* ReturnCode_t + * set_qos( + * in DataReaderViewQos qos); */ DDS_ReturnCode_t DDS_DataReaderView_set_qos( @@ -331,9 +332,9 @@ DDS_DataReaderView_set_qos( return result; } -/* ReturnCode_t - * get_qos( - * inout DataReaderViewQos qos); +/* ReturnCode_t + * get_qos( + * inout DataReaderViewQos qos); */ DDS_ReturnCode_t DDS_DataReaderView_get_qos ( @@ -370,8 +371,8 @@ DDS_DataReaderView_get_qos ( return result; } -/* DataReader - * get_datareader(); +/* DataReader + * get_datareader(); */ DDS_DataReader DDS_DataReaderView_get_datareader( @@ -391,11 +392,11 @@ DDS_DataReaderView_get_datareader( return reader; } -/* ReadCondition - * create_readcondition( - * in SampleStateMask sample_states, - * in ViewStateMask view_states, - * in InstanceStateMask instance_states); +/* ReadCondition + * create_readcondition( + * in SampleStateMask sample_states, + * in ViewStateMask view_states, + * in InstanceStateMask instance_states); */ DDS_ReadCondition DDS_DataReaderView_create_readcondition( @@ -422,13 +423,13 @@ DDS_DataReaderView_create_readcondition( return rc; } -/* QueryCondition - * create_querycondition( - * in SampleStateMask sample_states, - * in ViewStateMask view_states, - * in InstanceStateMask instance_states, - * in string query_expression, - * in StringSeq query_parameters); +/* QueryCondition + * create_querycondition( + * in SampleStateMask sample_states, + * in ViewStateMask view_states, + * in InstanceStateMask instance_states, + * in string query_expression, + * in StringSeq query_parameters); */ DDS_QueryCondition DDS_DataReaderView_create_querycondition( @@ -458,9 +459,9 @@ DDS_DataReaderView_create_querycondition( return qc; } -/* ReturnCode_t - * delete_readcondition( - * in ReadCondition a_condition); +/* ReturnCode_t + * delete_readcondition( + * in ReadCondition a_condition); */ DDS_ReturnCode_t DDS_DataReaderView_delete_readcondition( @@ -507,8 +508,8 @@ DDS_DataReaderView_delete_readcondition( return result; } -/* ReturnCode_t - * delete_contained_entities(); +/* ReturnCode_t + * delete_contained_entities(); */ DDS_ReturnCode_t DDS_DataReaderView_delete_contained_entities( @@ -906,7 +907,7 @@ DDS_DataReaderView_return_loan ( _DDS_sequence data_seq, DDS_SampleInfoSeq *info_seq) { - DDS_ReturnCode_t result; + DDS_ReturnCode_t result = DDS_RETCODE_OK; _DataReaderView view; SAC_REPORT_STACK(); @@ -916,20 +917,30 @@ DDS_DataReaderView_return_loan ( { result = DDS_RETCODE_BAD_PARAMETER; } else { - if (data_seq->_release == info_seq->_release) { + if (data_seq->_release != info_seq->_release) { + result = DDS_RETCODE_PRECONDITION_NOT_MET; + SAC_REPORT(result, "Data_seq->_release (%s) != info_seq->_release (%s)", + data_seq->_release?"TRUE":"FALSE", info_seq->_release?"TRUE":"FALSE"); + } + if (data_seq->_length != info_seq->_length) { + result = DDS_RETCODE_PRECONDITION_NOT_MET; + SAC_REPORT(result, "Data_seq->_length (%d) != info_seq->_length (%d)", + data_seq->_length, info_seq->_length); + } + if (data_seq->_maximum != info_seq->_maximum) { + result = DDS_RETCODE_PRECONDITION_NOT_MET; + SAC_REPORT(result, "Data_seq->_maximum (%d) != info_seq->_maximum (%d)", + data_seq->_maximum, info_seq->_maximum); + } + + if (result == DDS_RETCODE_OK) { if (!data_seq->_release) { result = DDS_DataReaderViewClaim(_this, &view); if (result == DDS_RETCODE_OK) { result = DDS_LoanRegistry_deregister(view->loanRegistry, data_seq, info_seq); DDS_DataReaderViewRelease(_this); } - } else { - result = DDS_RETCODE_OK; } - } else { - result = DDS_RETCODE_PRECONDITION_NOT_MET; - SAC_REPORT(result, "Data_seq->_release (%s) != info_seq->_release (%s)", - data_seq->_release?"TRUE":"FALSE", info_seq->_release?"TRUE":"FALSE"); } } SAC_REPORT_FLUSH(_this, result != DDS_RETCODE_OK); @@ -938,10 +949,10 @@ DDS_DataReaderView_return_loan ( /* ReturnCode_t * read_w_condition( - * inout DataSeq data_seq, - * inout SampleInfoSeq info_seq, - * in long max_samples, - * in ReadCondition a_condition); + * inout DataSeq data_seq, + * inout SampleInfoSeq info_seq, + * in long max_samples, + * in ReadCondition a_condition); */ DDS_ReturnCode_t DDS_DataReaderView_read_w_condition ( @@ -962,10 +973,10 @@ DDS_DataReaderView_read_w_condition ( /* ReturnCode_t * take_w_condition( - * inout DataSeq data_seq, - * inout SampleInfoSeq info_seq, - * in long max_samples, - * in ReadCondition a_condition); + * inout DataSeq data_seq, + * inout SampleInfoSeq info_seq, + * in long max_samples, + * in ReadCondition a_condition); */ DDS_ReturnCode_t DDS_DataReaderView_take_w_condition ( @@ -1087,7 +1098,7 @@ _DataReaderViewCopyIn ( /* InstanceHandle_t * lookup_instance( - * in Data instance); + * in Data instance); */ DDS_InstanceHandle_t DDS_DataReaderView_lookup_instance ( diff --git a/src/api/dcps/sac/code/sac_dataReaderView.h b/src/api/dcps/sac/code/sac_dataReaderView.h index 8b6f1b2fe..7cab7cd7a 100644 --- a/src/api/dcps/sac/code/sac_dataReaderView.h +++ b/src/api/dcps/sac/code/sac_dataReaderView.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/dcps/sac/code/sac_dataWriter.c b/src/api/dcps/sac/code/sac_dataWriter.c old mode 100644 new mode 100755 index ce490f711..b7d854374 --- a/src/api/dcps/sac/code/sac_dataWriter.c +++ b/src/api/dcps/sac/code/sac_dataWriter.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -32,6 +33,7 @@ #include "u_writer.h" #include "v_status.h" #include "sac_report.h" +#include "sac_genericCopyOut.h" #define DDS_DataWriterClaim(_this, writer) \ DDS_Object_claim(DDS_Object(_this), DDS_DATAWRITER, (_Object *)writer) @@ -144,7 +146,7 @@ DDS_DataWriterNew ( _this->copy_in = DDS_TypeSupportCopyIn(typeSupport); _this->copy_out = DDS_TypeSupportCopyOut(typeSupport); _this->copy_cache = DDS_TypeSupportCopyCache(typeSupport); -/* TODO copy_action = DDS_TypeSupportGetWriterCopy(typeSupport);*/ + /* TODO copy_action = DDS_TypeSupportGetWriterCopy(typeSupport);*/ *writer = (DDS_DataWriter)_this; } @@ -160,9 +162,9 @@ DDS_DataWriterFree ( return result; } -/* ReturnCode_t - * set_qos( - * in DataWriterQos qos); +/* ReturnCode_t + * set_qos( + * in DataWriterQos qos); */ DDS_ReturnCode_t DDS_DataWriter_set_qos ( @@ -227,9 +229,9 @@ DDS_DataWriter_set_qos ( return result; } -/* ReturnCode_t - * get_qos( - * inout DataWriterQos qos); +/* ReturnCode_t + * get_qos( + * inout DataWriterQos qos); */ DDS_ReturnCode_t DDS_DataWriter_get_qos ( @@ -269,10 +271,10 @@ DDS_DataWriter_get_qos ( return result; } -/* ReturnCode_t - * set_listener( - * in DataWriterListener a_listener, - * in StatusKindMask mask); +/* ReturnCode_t + * set_listener( + * in DataWriterListener a_listener, + * in StatusKindMask mask); */ DDS_ReturnCode_t DDS_DataWriter_set_listener ( @@ -300,8 +302,8 @@ DDS_DataWriter_set_listener ( return result; } -/* DataWriterListener - * get_listener(); +/* DataWriterListener + * get_listener(); */ struct DDS_DataWriterListener DDS_DataWriter_get_listener ( @@ -324,9 +326,9 @@ DDS_DataWriter_get_listener ( return *listener; } -/* ReturnCode_t - * set_listener_mask( - * in StatusKindMask mask); +/* ReturnCode_t + * set_listener_mask( + * in StatusKindMask mask); */ DDS_ReturnCode_t DDS_DataWriter_set_listener_mask ( @@ -343,8 +345,8 @@ DDS_DataWriter_set_listener_mask ( } -/* Topic - * get_topic(); +/* Topic + * get_topic(); */ DDS_Topic DDS_DataWriter_get_topic ( @@ -364,8 +366,8 @@ DDS_DataWriter_get_topic ( return topic; } -/* Publisher - * get_publisher(); +/* Publisher + * get_publisher(); */ DDS_Publisher DDS_DataWriter_get_publisher ( @@ -386,7 +388,7 @@ DDS_DataWriter_get_publisher ( } /* ReturnCode_t - * wait_for_acknowledgments( + * wait_for_acknowledgments( * in Duration_t max_wait); */ DDS_ReturnCode_t @@ -429,10 +431,10 @@ copy_liveliness_lost_status( return V_RESULT_OK; } -/* // Access the status +/* Access the status * ReturnCode_t * get_liveliness_lost_status( - * inout LivelinessLostStatus a_status); + * inout LivelinessLostStatus a_status); */ DDS_ReturnCode_t DDS_DataWriter_get_liveliness_lost_status ( @@ -493,10 +495,10 @@ copy_deadline_missed_status( return result; } -/* // Access the status +/* Access the status * ReturnCode_t * get_offered_deadline_missed_status( - * inout OfferedDeadlineMissedStatus a_status); + * inout OfferedDeadlineMissedStatus a_status); */ DDS_ReturnCode_t DDS_DataWriter_get_offered_deadline_missed_status ( @@ -576,10 +578,10 @@ copy_IncompatibleQosStatus( return result; } -/* // Access the status +/* Access the status * ReturnCode_t * get_offered_incompatible_qos_status( - * inout OfferedIncompatibleQosStatus a_status); + * inout OfferedIncompatibleQosStatus a_status); */ DDS_ReturnCode_t DDS_DataWriter_get_offered_incompatible_qos_status ( @@ -629,10 +631,10 @@ copy_publication_matched_status( return V_RESULT_OK; } -/* // Access the status +/* Access the status * ReturnCode_t * get_publication_matched_status( - * inout PublicationMatchedStatus a_status); + * inout PublicationMatchedStatus a_status); */ DDS_ReturnCode_t DDS_DataWriter_get_publication_matched_status ( @@ -663,8 +665,8 @@ DDS_DataWriter_get_publication_matched_status ( return result; } -/* ReturnCode_t - * assert_liveliness(); +/* ReturnCode_t + * assert_liveliness(); */ DDS_ReturnCode_t DDS_DataWriter_assert_liveliness ( @@ -709,9 +711,9 @@ copy_matched_subscription( return V_RESULT_OK; } -/* ReturnCode_t - * get_matched_subscriptions( - * inout InstanceHandleSeq subscription_handles); +/* ReturnCode_t + * get_matched_subscriptions( + * inout InstanceHandleSeq subscription_handles); */ DDS_ReturnCode_t DDS_DataWriter_get_matched_subscriptions ( @@ -750,10 +752,10 @@ ___DDS_SubscriptionBuiltinTopicData__copyOut( return V_RESULT_OK; } -/* ReturnCode_t - * get_matched_subscription_data( - * inout SubscriptionBuiltinTopicData subscription_data, - * in InstanceHandle_t subscription_handle); +/* ReturnCode_t + * get_matched_subscription_data( + * inout SubscriptionBuiltinTopicData subscription_data, + * in InstanceHandle_t subscription_handle); */ DDS_ReturnCode_t DDS_DataWriter_get_matched_subscription_data ( @@ -786,8 +788,7 @@ DDS_DataWriter_get_matched_subscription_data ( * Typeless Foo API operations */ -/* - * Alternative function for DDS_Time_copyIn, which can also handle +/* Alternative function for DDS_Time_copyIn, which can also handle * the proprietary DDS_TIMESTAMP_CURRENT. */ static DDS_ReturnCode_t @@ -1104,22 +1105,40 @@ DDS_DataWriter_get_key_value ( SAC_REPORT_STACK(); - if (key_holder != NULL) { - result = DDS_DataWriterCheck(_this, &w); - if (result == DDS_RETCODE_OK) { + result = DDS_RETCODE_OK; + if (key_holder == NULL) { + result = DDS_RETCODE_BAD_PARAMETER; + SAC_REPORT(result, "Sample key_holder = NULL"); + } + if (handle == DDS_HANDLE_NIL) { + result = DDS_RETCODE_BAD_PARAMETER; + SAC_REPORT(result, "InstanceHandle = DDS_HANDLE_NIL"); + } + if (result == DDS_RETCODE_OK) { + result = DDS_DataWriterClaim(_this, &w); + } + if (result == DDS_RETCODE_OK) { + PREPEND_COPYOUTCACHE(w->copy_cache, key_holder, NULL); + if (key_holder != NULL) { uResult = u_writerCopyKeysFromInstanceHandle( - _DataWriter_get_user_entity(w), - (u_instanceHandle)handle, - (u_writerCopyKeyAction)_DataWriter(_this)->copy_out, - key_holder); + _DataWriter_get_user_entity(w), + (u_instanceHandle)handle, + (u_copyOut)w->copy_out, + key_holder); result = DDS_ReturnCode_get(uResult); - if (result != DDS_RETCODE_OK) { - SAC_REPORT(result, "Could not copy keys from Instance Handle"); - } + REMOVE_COPYOUTCACHE(w->copy_cache, key_holder); + } else { + result = DDS_RETCODE_OUT_OF_RESOURCES; + SAC_REPORT(result, "DataWriter could not copy out key value"); } - } else { - result = DDS_RETCODE_BAD_PARAMETER; - SAC_REPORT(result, "Sample key_holder = NULL"); + /* The OpenSplice user-layer may detect that the instance is deleted + * In that case according to the spec return PRECONDITION_NOT_MET. + */ + if (result == DDS_RETCODE_ALREADY_DELETED) { + result = DDS_RETCODE_PRECONDITION_NOT_MET; + SAC_REPORT(result, "InstanceHandle was already deleted"); + } + DDS_DataWriterRelease(_this); } SAC_REPORT_FLUSH(_this, result != DDS_RETCODE_OK); return result; diff --git a/src/api/dcps/sac/code/sac_dataWriter.h b/src/api/dcps/sac/code/sac_dataWriter.h index 7464ee369..51b77d00a 100644 --- a/src/api/dcps/sac/code/sac_dataWriter.h +++ b/src/api/dcps/sac/code/sac_dataWriter.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/dcps/sac/code/sac_domain.c b/src/api/dcps/sac/code/sac_domain.c index 5c5425001..8fa6875a8 100644 --- a/src/api/dcps/sac/code/sac_domain.c +++ b/src/api/dcps/sac/code/sac_domain.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -92,7 +93,7 @@ DDS_DomainNew ( /* Error handling */ err_objInit: - DDS__free(_this); + (void) DDS__free(_this); err_objNew: (void) u_domainClose(uDomain); err_open: @@ -122,11 +123,11 @@ DDS_Domain_get_domain_id( return domainId; } -/* DDS_ReturnCode_t - * create_persistent_snapshot( - * in String partition_expression, - * in String topic_expression, - * in String URI); +/* DDS_ReturnCode_t + * create_persistent_snapshot( + * in String partition_expression, + * in String topic_expression, + * in String URI); */ DDS_ReturnCode_t DDS_Domain_create_persistent_snapshot ( diff --git a/src/api/dcps/sac/code/sac_domain.h b/src/api/dcps/sac/code/sac_domain.h index e9789dcca..ce662c337 100644 --- a/src/api/dcps/sac/code/sac_domain.h +++ b/src/api/dcps/sac/code/sac_domain.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/dcps/sac/code/sac_domainParticipant.c b/src/api/dcps/sac/code/sac_domainParticipant.c index 326134051..90a07b75e 100644 --- a/src/api/dcps/sac/code/sac_domainParticipant.c +++ b/src/api/dcps/sac/code/sac_domainParticipant.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -155,7 +156,7 @@ _DomainParticipant_deinit ( if (result == DDS_RETCODE_OK) { DDS_Entity_set_listener_interest (DDS_Entity(dp), 0); - /* TODO : hack, breaks encapsulation. */ + /* TODO : breaks encapsulation. */ if (_Entity (_this)->listenerDispatcher != NULL) { result = cmn_listenerDispatcher_free ( _Entity (_this)->listenerDispatcher); @@ -183,7 +184,7 @@ _DomainParticipant_deinit ( DDS_free(dp->domainName); result = _Entity_deinit(_this); if (result != DDS_RETCODE_OK) { - SAC_PANIC("Could not cleanup Entity"); + SAC_REPORT(result, "Could not cleanup Entity"); } } } else { @@ -607,7 +608,7 @@ DDS_DomainParticipant_create_subscriber ( if (sub) { result = DDS_Subscriber_set_listener(sub, a_listener, mask); if (result == DDS_RETCODE_OK) { - if (autoEnable) { + if (autoEnable && !(qos->presentation.coherent_access && qos->presentation.access_scope == DDS_GROUP_PRESENTATION_QOS)) { result = DDS_Entity_enable(sub); } } @@ -1216,11 +1217,12 @@ DDS_DomainParticipant_create_contentfilteredtopic ( dp->cfTopicList = c_iterInsert (dp->cfTopicList, topic); } else { (void)DDS__free(topic); + topic = NULL; } } else { result = DDS_RETCODE_ERROR; } - result = DDS_DomainParticipantRelease(_this); + DDS_DomainParticipantRelease(_this); } SAC_REPORT_FLUSH(_this, result != DDS_RETCODE_OK); return topic; @@ -1642,15 +1644,14 @@ DDS_DomainParticipant_ignore_participant ( { DDS_ReturnCode_t result; _DomainParticipant p; - - OS_UNUSED_ARG(handle); + u_result uresult; SAC_REPORT_STACK(); result = DDS_DomainParticipantClaim(_this, &p); if (result == DDS_RETCODE_OK) { - result = DDS_RETCODE_UNSUPPORTED; - SAC_REPORT(result, "This operation is currently unsupported"); + uresult = u_participantIgnoreParticipant(DDS_DomainParticipant_get_user_entity(p), handle); + result = DDS_ReturnCode_get(uresult); DDS_DomainParticipantRelease(_this); } SAC_REPORT_FLUSH(_this, result != DDS_RETCODE_OK); @@ -1668,15 +1669,14 @@ DDS_DomainParticipant_ignore_topic ( { DDS_ReturnCode_t result; _DomainParticipant p; - - OS_UNUSED_ARG(handle); + u_result uresult; SAC_REPORT_STACK(); result = DDS_DomainParticipantClaim(_this, &p); if (result == DDS_RETCODE_OK) { - result = DDS_RETCODE_UNSUPPORTED; - SAC_REPORT(result, "This operation is currently unsupported"); + uresult = u_participantIgnoreTopic(DDS_DomainParticipant_get_user_entity(p), handle); + result = DDS_ReturnCode_get(uresult); DDS_DomainParticipantRelease(_this); } SAC_REPORT_FLUSH(_this, result != DDS_RETCODE_OK); @@ -1694,15 +1694,14 @@ DDS_DomainParticipant_ignore_publication ( { DDS_ReturnCode_t result; _DomainParticipant p; - - OS_UNUSED_ARG(handle); + u_result uresult; SAC_REPORT_STACK(); result = DDS_DomainParticipantClaim(_this, &p); if (result == DDS_RETCODE_OK) { - result = DDS_RETCODE_UNSUPPORTED; - SAC_REPORT(result, "This operation is currently unsupported"); + uresult = u_participantIgnorePublication(DDS_DomainParticipant_get_user_entity(p), handle); + result = DDS_ReturnCode_get(uresult); DDS_DomainParticipantRelease(_this); } SAC_REPORT_FLUSH(_this, result != DDS_RETCODE_OK); @@ -1720,15 +1719,14 @@ DDS_DomainParticipant_ignore_subscription ( { DDS_ReturnCode_t result; _DomainParticipant p; - - OS_UNUSED_ARG(handle); + u_result uresult; SAC_REPORT_STACK(); result = DDS_DomainParticipantClaim(_this, &p); if (result == DDS_RETCODE_OK) { - result = DDS_RETCODE_UNSUPPORTED; - SAC_REPORT(result, "This operation is currently unsupported"); + uresult = u_participantIgnoreSubscription(DDS_DomainParticipant_get_user_entity(p), handle); + result = DDS_ReturnCode_get(uresult); DDS_DomainParticipantRelease(_this); } SAC_REPORT_FLUSH(_this, result != DDS_RETCODE_OK); @@ -2572,3 +2570,81 @@ DDS_DomainParticipant_notify_listener( return result; } +DDS_ReturnCode_t +DDS_DomainParticipant_set_property( + DDS_DomainParticipant _this, + const DDS_DomainParticipantProperty *a_property) +{ + DDS_ReturnCode_t result = DDS_RETCODE_OK; + u_result uResult; + _DomainParticipant p; + + SAC_REPORT_STACK(); + + if ((result == DDS_RETCODE_OK) && (_this == NULL)){ + result = DDS_RETCODE_BAD_PARAMETER; + SAC_REPORT(result, "Supplied participant is NULL."); + } + if ((result == DDS_RETCODE_OK) && (a_property == NULL)) { + result = DDS_RETCODE_BAD_PARAMETER; + SAC_REPORT(result, "Supplied Property is NULL."); + } + if ((result == DDS_RETCODE_OK) && (a_property->value == NULL)) { + result = DDS_RETCODE_BAD_PARAMETER; + SAC_REPORT(result, "Supplied Property.value is NULL."); + } + if ((result == DDS_RETCODE_OK) && (a_property->name == NULL)) { + result = DDS_RETCODE_BAD_PARAMETER; + SAC_REPORT(result, "Supplied Property.name is NULL."); + } + + if (result == DDS_RETCODE_OK) { + result = DDS_DomainParticipantClaim(_this, &p); + if (result == DDS_RETCODE_OK) { + uResult = u_entitySetProperty(u_entity(DDS_DomainParticipant_get_user_entity(p)), a_property->name, a_property->value); + result = DDS_ReturnCode_get(uResult); + } + DDS_DomainParticipantRelease(_this); + } + SAC_REPORT_FLUSH(_this, result != DDS_RETCODE_OK); + return result; +} + +DDS_ReturnCode_t +DDS_DomainParticipant_get_property( + DDS_DomainParticipant _this, + DDS_DomainParticipantProperty *a_property) +{ + DDS_ReturnCode_t result = DDS_RETCODE_OK; + u_result uResult; + _DomainParticipant p; + + SAC_REPORT_STACK(); + + if ((result == DDS_RETCODE_OK) && (_this == NULL)){ + result = DDS_RETCODE_BAD_PARAMETER; + SAC_REPORT(result, "Supplied participant is NULL."); + } + if ((result == DDS_RETCODE_OK) && (a_property == NULL)) { + result = DDS_RETCODE_BAD_PARAMETER; + SAC_REPORT(result, "Supplied Property is NULL."); + } + if ((result == DDS_RETCODE_OK) && (a_property->name == NULL)) { + result = DDS_RETCODE_BAD_PARAMETER; + SAC_REPORT(result, "Supplied Property.name is NULL."); + } + + if (result == DDS_RETCODE_OK){ + result = DDS_DomainParticipantClaim(_this, &p); + if (result == DDS_RETCODE_OK) { + os_char *value=NULL; + uResult = u_entityGetProperty(u_entity(DDS_DomainParticipant_get_user_entity(p)), a_property->name, &value); + a_property->value = DDS_string_dup(value); + os_free(value); + result = DDS_ReturnCode_get(uResult); + } + DDS_DomainParticipantRelease(_this); + } + SAC_REPORT_FLUSH(_this, result != DDS_RETCODE_OK); + return result; +} diff --git a/src/api/dcps/sac/code/sac_domainParticipant.h b/src/api/dcps/sac/code/sac_domainParticipant.h index 528e293d6..edd576124 100644 --- a/src/api/dcps/sac/code/sac_domainParticipant.h +++ b/src/api/dcps/sac/code/sac_domainParticipant.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/dcps/sac/code/sac_domainParticipantFactory.c b/src/api/dcps/sac/code/sac_domainParticipantFactory.c index 5aaa10276..dbe3bd8cd 100644 --- a/src/api/dcps/sac/code/sac_domainParticipantFactory.c +++ b/src/api/dcps/sac/code/sac_domainParticipantFactory.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -30,9 +31,7 @@ #include "os_atomics.h" -static C_STRUCT(_DomainParticipantFactory) *TheFactory = NULL; -static pa_uint32_t TheFactoryInitializingCount = PA_UINT32_INIT (0); -static DDS_boolean TheFactoryOperational = FALSE; +static pa_voidp_t g_factory = PA_VOIDP_INIT(NULL); #define DDS_DomainParticipantFactoryClaim(_this, factory) \ DDS_Object_claim(DDS_Object(_this), DDS_DOMAINFACTORY, (_Object *)factory) @@ -94,6 +93,24 @@ C_STRUCT(_TypeSupportBinding) { DDS_TypeSupport *typeSupport; }; +static DDS_ReturnCode_t +_DomainParticipantFactory_deinit ( + _Object _this) +{ + DDS_ReturnCode_t result = DDS_RETCODE_OK; + + C_STRUCT(_DomainParticipantFactory) *factory = (C_STRUCT(_DomainParticipantFactory) *)_this; + + c_iterFree(factory->participantList); + c_iterFree(factory->domainList); + factory->participantList = NULL; + factory->domainList = NULL; + + os_osExit(); + + return result; +} + /* * From Specification * @@ -102,45 +119,33 @@ C_STRUCT(_TypeSupportBinding) { DDS_DomainParticipantFactory DDS_DomainParticipantFactory_get_instance(void) { + C_STRUCT(_DomainParticipantFactory) *factory = NULL; DDS_ReturnCode_t result; - os_uint safecount; - os_time delay = {1,0}; - os_uint count; - - safecount = pa_inc32_nv(&TheFactoryInitializingCount); - if ((safecount == 1) && (TheFactoryOperational == FALSE)) { + factory = pa_ldvoidp(&g_factory); + if (factory == NULL) { if (u_userInitialise() == U_RESULT_OK) { SAC_REPORT_STACK(); - result = DDS_Object_new(DDS_DOMAINFACTORY, NULL, (_Object *)&TheFactory); + result = DDS_Object_new(DDS_DOMAINFACTORY, _DomainParticipantFactory_deinit, (_Object *)&factory); if (result == DDS_RETCODE_OK) { - TheFactory->participantList = NULL; - TheFactory->domainList = NULL; + factory->participantList = NULL; + factory->domainList = NULL; /* Can't fail with defaults */ - (void)DDS_DomainParticipantFactoryQos_init(&TheFactory->qos, DDS_PARTICIPANTFACTORY_QOS_DEFAULT); - (void)DDS_DomainParticipantQos_init(&TheFactory->defaultQos, DDS_PARTICIPANT_QOS_DEFAULT); - - os_procAtExit(factoryCleanup); - TheFactoryOperational = TRUE; + (void)DDS_DomainParticipantFactoryQos_init(&factory->qos, DDS_PARTICIPANTFACTORY_QOS_DEFAULT); + (void)DDS_DomainParticipantQos_init(&factory->defaultQos, DDS_PARTICIPANT_QOS_DEFAULT); } SAC_REPORT_FLUSH(NULL, result != DDS_RETCODE_OK); } - } else { /* wait for the factory to become initialized */ - count = 0; - while ((count < 5) && (TheFactoryOperational == FALSE)) { - count++; - os_nanoSleep(delay); - } - if (TheFactoryOperational == FALSE) { - result = DDS_RETCODE_ERROR; - SAC_REPORT(result, "The factory initialization failed."); + + if (pa_casvoidp(&g_factory, NULL, factory)) { + os_procAtExit(factoryCleanup); } else { - result = DDS_RETCODE_OK; + DDS_free(factory); + factory = pa_ldvoidp(&g_factory); } } - (void) pa_dec32_nv(&TheFactoryInitializingCount); - return (DDS_DomainParticipantFactory)TheFactory; + return (DDS_DomainParticipantFactory)factory; } /* DomainParticipant @@ -190,9 +195,6 @@ DDS_DomainParticipantFactory_create_participant ( result = DDS_Entity_enable(participant); } if ( result == DDS_RETCODE_OK ) { - if (factory->participantList == NULL) { - factory->participantList = c_iterNew(NULL); - } factory->participantList = c_iterInsert (factory->participantList, participant); result = factory->participantList ? DDS_RETCODE_OK : DDS_RETCODE_OUT_OF_RESOURCES; } @@ -457,9 +459,6 @@ DDS_DomainParticipantFactory_lookup_domain( result = DDS_RETCODE_PRECONDITION_NOT_MET; SAC_REPORT(result, "Could not locate a domain with domainId = %d.", id); } else { - if (factory->domainList == NULL) { - factory->domainList = c_iterNew(NULL); - } factory->domainList = c_iterInsert(factory->domainList, domain); } } @@ -511,8 +510,7 @@ DDS_DomainParticipantFactory_delete_domain ( } /* ReturnCode_t - * delete_contained_entities( - * ); + * delete_contained_entities(); */ DDS_ReturnCode_t DDS_DomainParticipantFactory_delete_contained_entities ( @@ -586,5 +584,12 @@ DDS_DomainParticipantFactory_detach_all_domains ( static void factoryCleanup(void) { + C_STRUCT(_DomainParticipantFactory) *factory = NULL; u_userDetach(U_USER_DELETE_ENTITIES); + factory = pa_ldvoidp(&g_factory); + if (factory != NULL) { + if (pa_casvoidp(&g_factory, factory, NULL)) { + DDS_free(factory); + } + } } diff --git a/src/api/dcps/sac/code/sac_domainParticipantFactory.h b/src/api/dcps/sac/code/sac_domainParticipantFactory.h index daee1860f..130129f1e 100644 --- a/src/api/dcps/sac/code/sac_domainParticipantFactory.h +++ b/src/api/dcps/sac/code/sac_domainParticipantFactory.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/dcps/sac/code/sac_entity.c b/src/api/dcps/sac/code/sac_entity.c index 5a2bf7b49..6d79e2f85 100644 --- a/src/api/dcps/sac/code/sac_entity.c +++ b/src/api/dcps/sac/code/sac_entity.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -62,7 +63,6 @@ _Entity_deinit ( if (entity->uEntity != NULL) { uResult = u_objectFree_s(u_object(entity->uEntity)); result = DDS_ReturnCode_get(uResult); - assert(result == DDS_RETCODE_OK); } else { result = DDS_RETCODE_OK; } @@ -679,11 +679,11 @@ DDS_Entity_reset_dataAvailable_status ( u_entity uEntity; u_result uResult; -/* TODO OSPL-8179: This is a bit tricky, the entity may already been deleted and in that case - * this operation will perform a dirty memory read. - * It may be better to wipe all pending events belonging to an entity when it is deleted or - * if that is too intrusive find another way to safely detect/avoid deletion. - */ + /* TODO OSPL-8179: This is a bit tricky, the entity may already been deleted and in that case + * this operation will perform a dirty memory read. + * It may be better to wipe all pending events belonging to an entity when it is deleted or + * if that is too intrusive find another way to safely detect/avoid deletion. + */ uEntity = _Entity_get_user_entity(_Entity(_this)); uResult = u_observableAction(u_observable(uEntity), resetDataAvailable, NULL); return DDS_ReturnCode_get(uResult); @@ -706,11 +706,11 @@ DDS_Entity_reset_on_data_on_readers_status ( u_entity uEntity; u_result uResult; -/* TODO OSPL-8179: This is a bit tricky, the entity may already been deleted and in that case - * this operation will perform a dirty memory read. - * It may be better to wipe all pending events belonging to an entity when it is deleted or - * if that is too intrusive find another way to safely detect/avoid deletion. - */ + /* TODO OSPL-8179: This is a bit tricky, the entity may already been deleted and in that case + * this operation will perform a dirty memory read. + * It may be better to wipe all pending events belonging to an entity when it is deleted or + * if that is too intrusive find another way to safely detect/avoid deletion. + */ uEntity = _Entity_get_user_entity(_Entity(_this)); uResult = u_observableAction(u_observable(uEntity), resetOnDataOnReaders, NULL); return DDS_ReturnCode_get(uResult); @@ -798,6 +798,39 @@ DDS_Entity_get_kind( return kind; } +const char * +DDS_EntityKind_image( + DDS_EntityKind_t kind) +{ + char * image; + + switch(kind) { + case DDS_ENTITY_KIND_DOMAINPARTICIPANT: + image = "DomainParticipant"; + break; + case DDS_ENTITY_KIND_TOPIC: + image = "Topic"; + break; + case DDS_ENTITY_KIND_PUBLISHER: + image = "Publisher"; + break; + case DDS_ENTITY_KIND_SUBSCRIBER: + image = "Subscriber"; + break; + case DDS_ENTITY_KIND_DATAWRITER: + image = "DataWriter"; + break; + case DDS_ENTITY_KIND_DATAREADER: + image = "DataReader"; + break; + default: + image = "Undefined"; + break; + } + + return image; +} + void DDS_Entity_user_data_init( DDS_EntityUserData userData, @@ -838,8 +871,13 @@ DDS_Entity_claim_user_data( if (userData) { result = DDS_EntityClaim(_this, &entity); if (result == DDS_RETCODE_OK) { - *userData = entity->userData; - pa_inc32(&entity->userData->refCount); + if (entity->userData) { + *userData = entity->userData; + pa_inc32(&entity->userData->refCount); + } + else { + result = DDS_RETCODE_ALREADY_DELETED; + } DDS_EntityRelease(_this); } } else { diff --git a/src/api/dcps/sac/code/sac_entity.h b/src/api/dcps/sac/code/sac_entity.h index 58eeb82c6..e45550058 100644 --- a/src/api/dcps/sac/code/sac_entity.h +++ b/src/api/dcps/sac/code/sac_entity.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/dcps/sac/code/sac_errorInfo.c b/src/api/dcps/sac/code/sac_errorInfo.c index 6434fccb2..df59f85b0 100644 --- a/src/api/dcps/sac/code/sac_errorInfo.c +++ b/src/api/dcps/sac/code/sac_errorInfo.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/dcps/sac/code/sac_genericCopyBuffer.c b/src/api/dcps/sac/code/sac_genericCopyBuffer.c index 66335316a..e0923509f 100644 --- a/src/api/dcps/sac/code/sac_genericCopyBuffer.c +++ b/src/api/dcps/sac/code/sac_genericCopyBuffer.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/dcps/sac/code/sac_genericCopyBuffer.h b/src/api/dcps/sac/code/sac_genericCopyBuffer.h index b2d9cf5ed..9f5066815 100644 --- a/src/api/dcps/sac/code/sac_genericCopyBuffer.h +++ b/src/api/dcps/sac/code/sac_genericCopyBuffer.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/dcps/sac/code/sac_genericCopyCache.c b/src/api/dcps/sac/code/sac_genericCopyCache.c index 1fb835434..8e724dc45 100644 --- a/src/api/dcps/sac/code/sac_genericCopyCache.c +++ b/src/api/dcps/sac/code/sac_genericCopyCache.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/dcps/sac/code/sac_genericCopyCache.h b/src/api/dcps/sac/code/sac_genericCopyCache.h index 58558a1fe..a55ae0a0f 100644 --- a/src/api/dcps/sac/code/sac_genericCopyCache.h +++ b/src/api/dcps/sac/code/sac_genericCopyCache.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/dcps/sac/code/sac_genericCopyIn.c b/src/api/dcps/sac/code/sac_genericCopyIn.c index 6cc7ac3bf..0388996d9 100644 --- a/src/api/dcps/sac/code/sac_genericCopyIn.c +++ b/src/api/dcps/sac/code/sac_genericCopyIn.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/dcps/sac/code/sac_genericCopyIn.h b/src/api/dcps/sac/code/sac_genericCopyIn.h index feac10078..2f162dd59 100644 --- a/src/api/dcps/sac/code/sac_genericCopyIn.h +++ b/src/api/dcps/sac/code/sac_genericCopyIn.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/dcps/sac/code/sac_genericCopyOut.c b/src/api/dcps/sac/code/sac_genericCopyOut.c index ca3570667..be579049c 100644 --- a/src/api/dcps/sac/code/sac_genericCopyOut.c +++ b/src/api/dcps/sac/code/sac_genericCopyOut.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/dcps/sac/code/sac_genericCopyOut.h b/src/api/dcps/sac/code/sac_genericCopyOut.h index 693e1922d..2ddd8536f 100644 --- a/src/api/dcps/sac/code/sac_genericCopyOut.h +++ b/src/api/dcps/sac/code/sac_genericCopyOut.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/dcps/sac/code/sac_guardCondition.c b/src/api/dcps/sac/code/sac_guardCondition.c index af9892c41..340cc7312 100644 --- a/src/api/dcps/sac/code/sac_guardCondition.c +++ b/src/api/dcps/sac/code/sac_guardCondition.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/dcps/sac/code/sac_listenerDispatcher.c b/src/api/dcps/sac/code/sac_listenerDispatcher.c index b0844a5e5..5ebeb8df8 100644 --- a/src/api/dcps/sac/code/sac_listenerDispatcher.c +++ b/src/api/dcps/sac/code/sac_listenerDispatcher.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/dcps/sac/code/sac_listenerDispatcher.h b/src/api/dcps/sac/code/sac_listenerDispatcher.h index b8a311e54..3fec746b5 100644 --- a/src/api/dcps/sac/code/sac_listenerDispatcher.h +++ b/src/api/dcps/sac/code/sac_listenerDispatcher.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/dcps/sac/code/sac_loanRegistry.c b/src/api/dcps/sac/code/sac_loanRegistry.c index a1136ce35..c0663cd0f 100644 --- a/src/api/dcps/sac/code/sac_loanRegistry.c +++ b/src/api/dcps/sac/code/sac_loanRegistry.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/dcps/sac/code/sac_loanRegistry.h b/src/api/dcps/sac/code/sac_loanRegistry.h index e11164c90..b35af0d89 100644 --- a/src/api/dcps/sac/code/sac_loanRegistry.h +++ b/src/api/dcps/sac/code/sac_loanRegistry.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/dcps/sac/code/sac_multiTopic.c b/src/api/dcps/sac/code/sac_multiTopic.c index 8970fd9f6..cfcd4e8ad 100644 --- a/src/api/dcps/sac/code/sac_multiTopic.c +++ b/src/api/dcps/sac/code/sac_multiTopic.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/dcps/sac/code/sac_multiTopic.h b/src/api/dcps/sac/code/sac_multiTopic.h index 7c7e93a99..9cfde335f 100644 --- a/src/api/dcps/sac/code/sac_multiTopic.h +++ b/src/api/dcps/sac/code/sac_multiTopic.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/dcps/sac/code/sac_objManag.c b/src/api/dcps/sac/code/sac_objManag.c index 0e419aa1c..a8e205c99 100644 --- a/src/api/dcps/sac/code/sac_objManag.c +++ b/src/api/dcps/sac/code/sac_objManag.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/dcps/sac/code/sac_objManag.h b/src/api/dcps/sac/code/sac_objManag.h index 7f43e3a37..a543b7150 100644 --- a/src/api/dcps/sac/code/sac_objManag.h +++ b/src/api/dcps/sac/code/sac_objManag.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/dcps/sac/code/sac_object.c b/src/api/dcps/sac/code/sac_object.c index c462bdadc..ccb7e0afd 100644 --- a/src/api/dcps/sac/code/sac_object.c +++ b/src/api/dcps/sac/code/sac_object.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/dcps/sac/code/sac_object.h b/src/api/dcps/sac/code/sac_object.h index effdea317..b05e3b1ad 100644 --- a/src/api/dcps/sac/code/sac_object.h +++ b/src/api/dcps/sac/code/sac_object.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/dcps/sac/code/sac_publisher.c b/src/api/dcps/sac/code/sac_publisher.c index 0e5e96368..d6fc60ef0 100644 --- a/src/api/dcps/sac/code/sac_publisher.c +++ b/src/api/dcps/sac/code/sac_publisher.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -902,7 +903,7 @@ DDS_Publisher_copy_from_topic_qos ( } if (topicQos != NULL) { - DDS__free(topicQos); + (void)DDS__free(topicQos); } SAC_REPORT_FLUSH(_this, result != DDS_RETCODE_OK); diff --git a/src/api/dcps/sac/code/sac_publisher.h b/src/api/dcps/sac/code/sac_publisher.h index c93a00c52..69fa02b4f 100644 --- a/src/api/dcps/sac/code/sac_publisher.h +++ b/src/api/dcps/sac/code/sac_publisher.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/dcps/sac/code/sac_qosProvider.c b/src/api/dcps/sac/code/sac_qosProvider.c index a682a1c90..8e31a1222 100644 --- a/src/api/dcps/sac/code/sac_qosProvider.c +++ b/src/api/dcps/sac/code/sac_qosProvider.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -225,7 +226,7 @@ DDS_QosProvider_get_topic_qos( } (void)DDS_TopicQos_deinit (&namedTopicQos.topic_qos); err_init_failed: - DDS_free(&namedTopicQos.name); + DDS_free(namedTopicQos.name); err_not_found: DDS_QosProviderRelease (_this); err_bad_parameter: @@ -283,7 +284,7 @@ DDS_QosProvider_get_subscriber_qos( } (void)DDS_SubscriberQos_deinit (&namedSubscriberQos.subscriber_qos); err_init_failed: - DDS_free(&namedSubscriberQos.name); + DDS_free(namedSubscriberQos.name); err_not_found: DDS_QosProviderRelease (_this); err_bad_parameter: @@ -345,7 +346,7 @@ DDS_QosProvider_get_datareader_qos( } (void)DDS_DataReaderQos_deinit (&namedDataReaderQos.datareader_qos); err_init_failed: - DDS_free(&namedDataReaderQos.name); + DDS_free(namedDataReaderQos.name); err_not_found: DDS_QosProviderRelease (_this); err_bad_parameter: @@ -403,7 +404,7 @@ DDS_QosProvider_get_publisher_qos( } (void)DDS_PublisherQos_deinit (&namedPublisherQos.publisher_qos); err_init_failed: - DDS_free(&namedPublisherQos.name); + DDS_free(namedPublisherQos.name); err_not_found: DDS_QosProviderRelease (_this); err_bad_parameter: @@ -465,7 +466,7 @@ DDS_QosProvider_get_datawriter_qos( } (void)DDS_DataWriterQos_deinit (&namedDataWriterQos.datawriter_qos); err_init_failed: - DDS_free(&namedDataWriterQos.name); + DDS_free(namedDataWriterQos.name); err_not_found: DDS_QosProviderRelease (_this); err_bad_parameter: diff --git a/src/api/dcps/sac/code/sac_queryCondition.c b/src/api/dcps/sac/code/sac_queryCondition.c index 11e60606d..cc5005dbb 100644 --- a/src/api/dcps/sac/code/sac_queryCondition.c +++ b/src/api/dcps/sac/code/sac_queryCondition.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/dcps/sac/code/sac_queryCondition.h b/src/api/dcps/sac/code/sac_queryCondition.h index 987144ee7..32f0b2334 100644 --- a/src/api/dcps/sac/code/sac_queryCondition.h +++ b/src/api/dcps/sac/code/sac_queryCondition.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/dcps/sac/code/sac_readCondition.c b/src/api/dcps/sac/code/sac_readCondition.c index 54fe791c0..d9b0e33d6 100644 --- a/src/api/dcps/sac/code/sac_readCondition.c +++ b/src/api/dcps/sac/code/sac_readCondition.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/dcps/sac/code/sac_readCondition.h b/src/api/dcps/sac/code/sac_readCondition.h index c6920a4df..57d80c4a0 100644 --- a/src/api/dcps/sac/code/sac_readCondition.h +++ b/src/api/dcps/sac/code/sac_readCondition.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/dcps/sac/code/sac_readerCommon.c b/src/api/dcps/sac/code/sac_readerCommon.c index 4acb23056..d00877528 100644 --- a/src/api/dcps/sac/code/sac_readerCommon.c +++ b/src/api/dcps/sac/code/sac_readerCommon.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/dcps/sac/code/sac_readerCommon.h b/src/api/dcps/sac/code/sac_readerCommon.h index 1860a798c..8ca2e195d 100644 --- a/src/api/dcps/sac/code/sac_readerCommon.h +++ b/src/api/dcps/sac/code/sac_readerCommon.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/dcps/sac/code/sac_report.c b/src/api/dcps/sac/code/sac_report.c index 7f5f4acd7..80351aba8 100644 --- a/src/api/dcps/sac/code/sac_report.c +++ b/src/api/dcps/sac/code/sac_report.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -31,21 +32,18 @@ sac_panic( ...) { os_char buffer[OS_REPORT_BUFLEN]; - static const os_char panic[] = "Panic: "; - const os_size_t offset = sizeof(panic) - 1; va_list args; assert (function != NULL); assert (file != NULL); assert (format != NULL); - (void)memcpy (buffer, panic, offset); + snprintf(buffer, sizeof(buffer), "Panic: %s", format); + va_start (args, format); - (void)os_vsnprintf (buffer + offset, sizeof(buffer) - offset, format, args); + os_report_va (OS_CRITICAL, function, file, line, DDS_RETCODE_ERROR, -1, OS_TRUE, buffer, args); + os_report_dump(OS_TRUE, function, file, line, -1); va_end (args); - - os_report_noargs (OS_CRITICAL, function, file, line, DDS_RETCODE_ERROR, buffer); - os_report_dumpStack (function, file, line); } void @@ -61,68 +59,60 @@ sac_report( const os_char *retcode = NULL; /* os_report truncates messages to bytes */ os_char buffer[OS_REPORT_BUFLEN]; - os_size_t offset = 0; va_list args; assert (function != NULL); assert (file != NULL); assert (format != NULL); - /* probably never happens, but you can never be to sure */ - assert (OS_REPORT_BUFLEN > 0); switch (code) { - case DDS_RETCODE_ERROR: - retcode = "Error: "; - break; - case DDS_RETCODE_UNSUPPORTED: - retcode = "Unsupported: "; - break; - case DDS_RETCODE_BAD_PARAMETER: - retcode = "Bad parameter: "; - break; - case DDS_RETCODE_PRECONDITION_NOT_MET: - retcode = "Precondition not met: "; - break; - case DDS_RETCODE_OUT_OF_RESOURCES: - retcode = "Out of resources: "; - break; - case DDS_RETCODE_NOT_ENABLED: - retcode = "Not enabled: "; - break; - case DDS_RETCODE_IMMUTABLE_POLICY: - retcode = "Immutable policy: "; - break; - case DDS_RETCODE_INCONSISTENT_POLICY: - retcode = "Inconsistent policy: "; - break; - case DDS_RETCODE_ALREADY_DELETED: - retcode = "Already deleted: "; - break; - case DDS_RETCODE_TIMEOUT: - retcode = "Timeout: "; - break; - case DDS_RETCODE_NO_DATA: - retcode = "No data: "; - break; - case DDS_RETCODE_ILLEGAL_OPERATION: - retcode = "Illegal operation: "; - break; - default: - assert (code == DDS_RETCODE_OK); - break; + case DDS_RETCODE_ERROR: + retcode = "Error"; + break; + case DDS_RETCODE_UNSUPPORTED: + retcode = "Unsupported"; + break; + case DDS_RETCODE_BAD_PARAMETER: + retcode = "Bad parameter"; + break; + case DDS_RETCODE_PRECONDITION_NOT_MET: + retcode = "Precondition not met"; + break; + case DDS_RETCODE_OUT_OF_RESOURCES: + retcode = "Out of resources"; + break; + case DDS_RETCODE_NOT_ENABLED: + retcode = "Not enabled"; + break; + case DDS_RETCODE_IMMUTABLE_POLICY: + retcode = "Immutable policy"; + break; + case DDS_RETCODE_INCONSISTENT_POLICY: + retcode = "Inconsistent policy"; + break; + case DDS_RETCODE_ALREADY_DELETED: + retcode = "Already deleted"; + break; + case DDS_RETCODE_TIMEOUT: + retcode = "Timeout"; + break; + case DDS_RETCODE_NO_DATA: + retcode = "No data"; + break; + case DDS_RETCODE_ILLEGAL_OPERATION: + retcode = "Illegal operation"; + break; + default: + assert (code == DDS_RETCODE_OK); + retcode = "Unknown error"; + break; } - if (retcode != NULL) { - assert (offset <= OS_REPORT_BUFLEN); - offset = strlen(retcode); - (void)memcpy(buffer, retcode, offset); - } + snprintf(buffer, OS_REPORT_BUFLEN, "%s: %s", retcode, format); va_start (args, format); - (void)os_vsnprintf (buffer + offset, sizeof(buffer) - offset, format, args); + os_report_va (reportType, function, file, line, code, -1, OS_TRUE, buffer, args); va_end (args); - - os_report_noargs (reportType, function, file, line, code, buffer); } void @@ -133,8 +123,8 @@ sac_report_flush( os_int32 line, const os_char *function) { - if (os_report_stack_flush_required(valid)) { + if (os_report_status(valid)) { os_int32 domainId = DDS_Object_get_domain_id(object); - os_report_stack_unwind(valid, function, file, line, domainId); + os_report_flush(valid, function, file, line, domainId); } } diff --git a/src/api/dcps/sac/code/sac_report.h b/src/api/dcps/sac/code/sac_report.h index 1ee0290b1..0a71a22f9 100644 --- a/src/api/dcps/sac/code/sac_report.h +++ b/src/api/dcps/sac/code/sac_report.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,7 +25,7 @@ #include "os_report.h" #define SAC_REPORT_STACK() \ - os_report_stack () + os_report_stack_open (NULL,0,NULL,NULL) #define SAC_PANIC(...) \ do { \ diff --git a/src/api/dcps/sac/code/sac_sequence.c b/src/api/dcps/sac/code/sac_sequence.c index ee0be895d..0e3025d82 100644 --- a/src/api/dcps/sac/code/sac_sequence.c +++ b/src/api/dcps/sac/code/sac_sequence.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/dcps/sac/code/sac_static_check_kinds.c b/src/api/dcps/sac/code/sac_static_check_kinds.c index 58103af91..f875f3e80 100644 --- a/src/api/dcps/sac/code/sac_static_check_kinds.c +++ b/src/api/dcps/sac/code/sac_static_check_kinds.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/dcps/sac/code/sac_statusCondition.c b/src/api/dcps/sac/code/sac_statusCondition.c index 6c6eab6f9..f059e9bb3 100644 --- a/src/api/dcps/sac/code/sac_statusCondition.c +++ b/src/api/dcps/sac/code/sac_statusCondition.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/dcps/sac/code/sac_statusCondition.h b/src/api/dcps/sac/code/sac_statusCondition.h index a8ead69b5..42d8ef4fe 100644 --- a/src/api/dcps/sac/code/sac_statusCondition.h +++ b/src/api/dcps/sac/code/sac_statusCondition.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/dcps/sac/code/sac_subscriber.c b/src/api/dcps/sac/code/sac_subscriber.c index a34f2e07b..44c3c988f 100644 --- a/src/api/dcps/sac/code/sac_subscriber.c +++ b/src/api/dcps/sac/code/sac_subscriber.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -108,7 +109,7 @@ DDS_SubscriberNew ( uParticipant = u_participant(_Entity_get_user_entity(participant)); _participant = _DomainParticipant(participant); if (uParticipant != NULL && _participant != NULL) { - uSubscriber = u_subscriberNew(uParticipant, name, sQos, FALSE); + uSubscriber = u_subscriberNew(uParticipant, name, sQos); if (uSubscriber != NULL) { result = DDS_Object_new(DDS_SUBSCRIBER, _Subscriber_deinit, (_Object *)&_this); if (result == DDS_RETCODE_OK) { @@ -274,7 +275,7 @@ DDS_Subscriber_create_datareader ( } if (result == DDS_RETCODE_OK) { DDS_DataReader_set_listener(reader, a_listener, mask); - if (factoryAutoEnable) { + if (factoryAutoEnable && _Entity_is_enabled(_Entity(sub))) { result = DDS_Entity_enable(reader); if (result != DDS_RETCODE_OK) { DDS_ReturnCode_t destroyed; @@ -953,7 +954,7 @@ DDS_Subscriber_copy_from_topic_qos ( } if (topicQos != NULL) { - DDS__free(topicQos); + (void)DDS__free(topicQos); } SAC_REPORT_FLUSH(_this, result != DDS_RETCODE_OK); diff --git a/src/api/dcps/sac/code/sac_subscriber.h b/src/api/dcps/sac/code/sac_subscriber.h index 074be2cb2..95c60c5dd 100644 --- a/src/api/dcps/sac/code/sac_subscriber.h +++ b/src/api/dcps/sac/code/sac_subscriber.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/dcps/sac/code/sac_topic.c b/src/api/dcps/sac/code/sac_topic.c index 2894427f6..e86c1f2be 100644 --- a/src/api/dcps/sac/code/sac_topic.c +++ b/src/api/dcps/sac/code/sac_topic.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -490,7 +491,7 @@ DDS_Topic_validate_filter( result = DDS_TopicCheck(_this, &topic); if (result == DDS_RETCODE_OK) { uTopic = u_topic(_Topic_get_user_entity(topic)); - if (u_topicContentFilterValidate2(uTopic, expr, params)) { + if (u_topicContentFilterValidate2(uTopic, expr, params, filter_parameters->_length)) { result = DDS_RETCODE_OK; } else { result = DDS_RETCODE_BAD_PARAMETER; diff --git a/src/api/dcps/sac/code/sac_topic.h b/src/api/dcps/sac/code/sac_topic.h index d20c78dff..cb5c01c53 100644 --- a/src/api/dcps/sac/code/sac_topic.h +++ b/src/api/dcps/sac/code/sac_topic.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/dcps/sac/code/sac_topicDescription.c b/src/api/dcps/sac/code/sac_topicDescription.c index 90afc8126..da5cca22f 100644 --- a/src/api/dcps/sac/code/sac_topicDescription.c +++ b/src/api/dcps/sac/code/sac_topicDescription.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/dcps/sac/code/sac_topicDescription.h b/src/api/dcps/sac/code/sac_topicDescription.h index 9491f45b9..e743e0b92 100644 --- a/src/api/dcps/sac/code/sac_topicDescription.h +++ b/src/api/dcps/sac/code/sac_topicDescription.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/dcps/sac/code/sac_typeSupport.c b/src/api/dcps/sac/code/sac_typeSupport.c index 8ed0c78fb..8a96c1188 100644 --- a/src/api/dcps/sac/code/sac_typeSupport.c +++ b/src/api/dcps/sac/code/sac_typeSupport.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -193,7 +194,8 @@ _TypeSupport_load_type( } if ( result == DDS_RETCODE_OK ) { /* If either of the copy routines is NULL, - the generic copy routines will be used for both */ + * the generic copy routines will be used for both + */ if( (ts->copy_in == NULL) || (ts->copy_out == NULL)) { c_metaObject md; @@ -205,7 +207,7 @@ _TypeSupport_load_type( if (md != NULL) { ts->copy_cache = DDS_copyCacheNew(md) ; - /* de volgende 9 regels verhuizen naar DDS_copyCacheNew() */ + /* TODO: next 9 line should move to DDS_copyCacheNew() */ if ( ts->copy_cache != NULL ) { if ( ts->alloc_size == 0 ) { ts->alloc_size = DDS_copyCacheGetUserSize(ts->copy_cache); diff --git a/src/api/dcps/sac/code/sac_typeSupport.h b/src/api/dcps/sac/code/sac_typeSupport.h index d9f971d15..4fd742e78 100644 --- a/src/api/dcps/sac/code/sac_typeSupport.h +++ b/src/api/dcps/sac/code/sac_typeSupport.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/dcps/sac/code/sac_waitSet.c b/src/api/dcps/sac/code/sac_waitSet.c index a765cff7c..9681e2627 100644 --- a/src/api/dcps/sac/code/sac_waitSet.c +++ b/src/api/dcps/sac/code/sac_waitSet.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -300,7 +301,7 @@ DDS_WaitSet_wait ( if (arg.nrOfGuards > MAX_GUARDS) { os_free(arg.guards); } - SAC_REPORT_FLUSH(_this, (result != DDS_RETCODE_OK) && (result != DDS_RETCODE_TIMEOUT)); + SAC_REPORT_FLUSH((result != DDS_RETCODE_ALREADY_DELETED) ? _this : NULL, (result != DDS_RETCODE_OK) && (result != DDS_RETCODE_TIMEOUT)); return result; } diff --git a/src/api/dcps/sac/code/sac_waitSet.h b/src/api/dcps/sac/code/sac_waitSet.h index 7f7f9be94..6621f37ed 100644 --- a/src/api/dcps/sac/code/sac_waitSet.h +++ b/src/api/dcps/sac/code/sac_waitSet.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/dcps/sac/include/dds_dcps.h b/src/api/dcps/sac/include/dds_dcps.h index 95cbe74af..668bae0ad 100644 --- a/src/api/dcps/sac/include/dds_dcps.h +++ b/src/api/dcps/sac/include/dds_dcps.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -735,10 +736,9 @@ typedef DDS_unsigned_long DDS_StatusMask; /* Opensplice Extensions */ #define DDS_ALL_DATA_DISPOSED_TOPIC_STATUS 0x80000000U -#define DDS_ANY_STATUS 0x1FFF /* Depricated, now use DDS_STATUS_MASK_ANY */ -#define DDS_STATUS_MASK_ANY_V1_2 0x1FFF -#define DDS_STATUS_MASK_ANY (DDS_STATUS_MASK_ANY_V1_2 | \ - DDS_ALL_DATA_DISPOSED_TOPIC_STATUS) +#define DDS_ANY_STATUS 0x7FFF /* Depricated, now use DDS_STATUS_MASK_ANY */ +#define DDS_STATUS_MASK_ANY_V1_2 0x7FFF +#define DDS_STATUS_MASK_ANY 0xFFFFFFFF #define DDS_STATUS_MASK_NONE 0x0 /* @@ -2408,6 +2408,24 @@ DDS_DomainParticipant_delete_historical_data ( const DDS_string partition_expression, const DDS_string topic_expression); +struct DDS_Property_s { + DDS_string name; + DDS_string value; +}; + +typedef struct DDS_Property_s DDS_DomainParticipantProperty; + +OS_API DDS_ReturnCode_t +DDS_DomainParticipant_set_property ( + DDS_DomainParticipant _this, + const DDS_DomainParticipantProperty *property); + +OS_API DDS_ReturnCode_t +DDS_DomainParticipant_get_property ( + DDS_DomainParticipant _this, + DDS_DomainParticipantProperty *property); + + /* * interface Domain */ diff --git a/src/api/dcps/sac/include/dds_dcps_private.h b/src/api/dcps/sac/include/dds_dcps_private.h index d0e381e6b..b5d0f5199 100644 --- a/src/api/dcps/sac/include/dds_dcps_private.h +++ b/src/api/dcps/sac/include/dds_dcps_private.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -43,8 +44,7 @@ */ #define DDS_RETCODE_HANDLE_EXPIRED (13) -/* - * This function prototype is an abstract specification of the +/* This function prototype is an abstract specification of the * deallocation operation required for all objects that can be * free via the DDS_free operation. * All classes need to implement their specific implementation @@ -177,6 +177,10 @@ typedef enum { DDS_ENTITY_KIND_DATAREADER } DDS_EntityKind_t; +OS_API const char * +DDS_EntityKind_image( + DDS_EntityKind_t kind); + OS_API DDS_EntityKind_t DDS_Entity_get_kind( DDS_Entity _this); @@ -273,8 +277,7 @@ DDS_Condition_get_kind( DDS_Condition _this); -/* - * Normally, DDS_WaitSet_wait returns a DDS_ConditionSeq that +/* Normally, DDS_WaitSet_wait returns a DDS_ConditionSeq that * contains triggered DDS_Conditions. * However, when the condition was attached to the WaitSet with * this function, the alternative pointer (can be NULL) will be @@ -286,5 +289,14 @@ DDS_WaitSet_attach_condition_alternative ( const DDS_Condition cond, void *alternative); +OS_API DDS_ReturnCode_t +DDS_InstanceHandle_set_userdata( + DDS_InstanceHandle_t handle, + void *userData); + +OS_API void * +DDS_InstanceHandle_get_userdata( + DDS_InstanceHandle_t handle); + #undef OS_API #endif /* DDS_DCPS_PRIVATE_H */ diff --git a/src/api/dcps/sac/include/dds_primitive_types.h b/src/api/dcps/sac/include/dds_primitive_types.h index ddc079f84..4d7d9e292 100644 --- a/src/api/dcps/sac/include/dds_primitive_types.h +++ b/src/api/dcps/sac/include/dds_primitive_types.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,6 +25,8 @@ extern "C" { #endif +#include "dds_sac_if.h" + typedef short int DDS_short; typedef int DDS_long; typedef long long int DDS_long_long; @@ -39,6 +42,32 @@ typedef unsigned char DDS_boolean; typedef DDS_char * DDS_string; typedef void * DDS_Object; +/* Definition for sequence of DDS_octet */ +#ifndef _DDS_sequence_octet_defined +#define _DDS_sequence_octet_defined +typedef struct { + DDS_unsigned_long _maximum; + DDS_unsigned_long _length; + DDS_octet *_buffer; + DDS_boolean _release; +} DDS_sequence_octet; +SAC_BUILTIN DDS_sequence_octet *DDS_sequence_octet__alloc (void); +SAC_BUILTIN DDS_octet *DDS_sequence_octet_allocbuf (DDS_unsigned_long len); +#endif /* _DDS_sequence_octet_defined */ + +/* Definition for sequence of DDS_string */ +#ifndef _DDS_sequence_string_defined +#define _DDS_sequence_string_defined +typedef struct { + DDS_unsigned_long _maximum; + DDS_unsigned_long _length; + DDS_string *_buffer; + DDS_boolean _release; +} DDS_sequence_string; +SAC_BUILTIN DDS_sequence_string *DDS_sequence_string__alloc (void); +SAC_BUILTIN DDS_string *DDS_sequence_string_allocbuf (DDS_unsigned_long len); +#endif /* _DDS_sequence_string_defined */ + #ifndef FALSE #define FALSE 0 #endif diff --git a/src/api/dcps/sac/include/dds_sac_if.h b/src/api/dcps/sac/include/dds_sac_if.h index c95de7ce8..ce1018655 100644 --- a/src/api/dcps/sac/include/dds_sac_if.h +++ b/src/api/dcps/sac/include/dds_sac_if.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/dcps/sacs/Dds.sln b/src/api/dcps/sacs/Dds.sln index cc7142bb5..a02e2dc03 100644 --- a/src/api/dcps/sacs/Dds.sln +++ b/src/api/dcps/sacs/Dds.sln @@ -2,8 +2,6 @@ Microsoft Visual Studio Solution File, Format Version 10.00 # Visual Studio 2008 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "dcpssacs", "code\DDS\dcpssacs.csproj", "{AFB382F9-84F5-4226-BD28-A02F0B15F2E1}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestBinding", "api_quick_test\code\TestBinding.csproj", "{33364B52-2443-4B73-8C14-8EEFBABE5923}" -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU diff --git a/src/api/dcps/sacs/api_quick_test/code/Data/DataTest.idl b/src/api/dcps/sacs/api_quick_test/code/Data/DataTest.idl deleted file mode 100644 index 204bc079d..000000000 --- a/src/api/dcps/sacs/api_quick_test/code/Data/DataTest.idl +++ /dev/null @@ -1,15 +0,0 @@ -module Data -{ - struct DataTest - { - long TestId; - long ProviderId; - string SensorType; - string DataType; - boolean Emergency; - string TestStr; - sequence SequenceTest; - }; -#pragma keylist DataTest TestId ProviderId - -}; diff --git a/src/api/dcps/sacs/api_quick_test/code/TestBinding.cs b/src/api/dcps/sacs/api_quick_test/code/TestBinding.cs deleted file mode 100644 index 258ba559c..000000000 --- a/src/api/dcps/sacs/api_quick_test/code/TestBinding.cs +++ /dev/null @@ -1,389 +0,0 @@ -/* - * OpenSplice DDS - * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -using System; -using DDS; -using System.Runtime.InteropServices; - -using DDS.OpenSplice.CustomMarshalers; -namespace testNamespace -{ - class TestBinding : DomainParticipantListener - { - public static void Main() - { - TestBinding binding = new TestBinding(); - binding.Run(); - } - - public void Run() - { -#if DBCallTests - DDS.Test.DatabaseTests(); -#endif - - Console.WriteLine("Press enter to enter..."); - Console.ReadLine(); - Data.DataTest detectionData = new Data.DataTest(); - detectionData.TestId = 3214; - detectionData.Emergency = true; - detectionData.TestStr = "not really"; - //detectionData.SeqInt[3] = 23; -#if TestMarshaling - - //Tactical.DetectionTypeSupport support = new Tactical.DetectionTypeSupport(); - //Tactical.Detection cachedObj = new Tactical.Detection(); - //support.Copy(cachedObj, detectionData); - - //SampleMarshaler marshaler = SampleMarshalerFactory.CreateMarshaler(detectionData); - - //using (SampleMarshalHelper helper = new SampleMarshalHelper(marshaler)) - //{ - // DDS.OpenSplice.Gapi.Test.test_detection(helper.GapiPtr); - - // Tactical.Detection detectionData2 = new Tactical.Detection(); - // SampleMarshaler marshaler2 = SampleMarshalerFactory.CreateMarshaler(detectionData2); - // marshaler2.CopyOut(helper.GapiPtr, 0); - //} - - //Duration d = new Duration(234, 2343); - //int sec; - //uint nanosec; - //DDS.OpenSplice.Gapi.Test.test_duration(d, out sec, out nanosec); - - //LivelinessChangedStatus status; - //DDS.OpenSplice.Gapi.Test.get_liveliness_changed_status(out status); - - //Time t = new Time(1, 2); - //int size = Marshal.SizeOf(t); - //IntPtr ptr = Marshal.AllocHGlobal(size); - //Marshal.StructureToPtr(t, ptr, true); -#endif - - //DDS.Test.TestDataReaderQos(); - //DDS.Test.TestTopicQos(); - - // Create a DomainParticipantFactory - DomainParticipantFactory dpf = DomainParticipantFactory.Instance; - Console.WriteLine("DomainParticipantFactory: " + dpf); - - // Tailor the DomainPartipantFactoryQos; - DomainParticipantFactoryQos dpfQos = null; - ReturnCode result = dpf.GetQos(ref dpfQos); - Console.WriteLine("DomainParticipantFactory.get_qos: {0}", result); - Console.WriteLine("DomainParticipantFactoryQos.entity_factory.autoenable_created_entities: " + dpfQos.EntityFactory.AutoenableCreatedEntities); - - dpfQos.EntityFactory.AutoenableCreatedEntities = true; - result = dpf.SetQos(dpfQos); - Console.WriteLine("DomainParticipantFactory.set_qos: {0}", result); - - // Get the QOS settings for the Factory... Check values without additional changes - DomainParticipantFactoryQos dpf2Qos = null; - result = dpf.GetQos(ref dpf2Qos); - Console.WriteLine("DomainParticipantFactory.get_qos: {0}", result); - Console.WriteLine("DomainParticipantFactoryQos.entity_factory.autoenable_created_entities: " + dpf2Qos.EntityFactory.AutoenableCreatedEntities); - - // Create the domainParticipant itself. - DomainParticipantQos dpQos = new DomainParticipantQos(); - dpQos.UserData.Value = new byte[] { (byte)1, (byte)2, (byte)3 }; - dpQos.EntityFactory.AutoenableCreatedEntities = true; - dpQos.ListenerScheduling.SchedulingClass.Kind = SchedulingClassQosPolicyKind.ScheduleDefault; - dpQos.ListenerScheduling.SchedulingPriorityKind.Kind = SchedulingPriorityQosPolicyKind.PriorityRelative; - dpQos.ListenerScheduling.SchedulingPriority = 0; - dpQos.WatchdogScheduling.SchedulingClass.Kind = SchedulingClassQosPolicyKind.ScheduleDefault; - dpQos.WatchdogScheduling.SchedulingPriorityKind.Kind = SchedulingPriorityQosPolicyKind.PriorityRelative; - dpQos.WatchdogScheduling.SchedulingPriority = 4; - - IDomainParticipant dp = dpf.CreateParticipant(DDS.DomainId.Default, dpQos); - Console.Write("DomainParticipant: "); - Console.WriteLine(dp != null ? "yes" : "no"); - - - if (dp.ContainsEntity(0)) - { - Console.WriteLine("contains_entity with nil handle incorrect"); - } - if (dp.ContainsEntity(100)) - { - Console.WriteLine("contains_entity with incorrect handle incorrect"); - } - - Time currentTime; - dp.GetCurrentTime(out currentTime); - Console.WriteLine("Current Local Time: {0}", currentTime.ToDatetime().ToLocalTime()); - - // And look up this DomainParticipant. - IDomainParticipant dp2 = dpf.LookupParticipant(DDS.DomainId.Default); - - DomainParticipantQos dp2Qos = null; - - Console.Write("lookup DomainParticipant: "); - Console.WriteLine(dp2 != null ? "Success" : "Fail"); - result = dp2.GetQos(ref dp2Qos); - Console.WriteLine("DomainParticipant.get_qos: {0}", result); - Console.WriteLine("DomainParticipantQos.entity_factory.autoenable_created_entities: " + dp2Qos.EntityFactory.AutoenableCreatedEntities); - // Create a new PublisherQos and set some values... - PublisherQos publisherQos = new PublisherQos(); - publisherQos.EntityFactory.AutoenableCreatedEntities = true; - publisherQos.Partition.Name = new string[] { "howdy" }; //, "neighbor", "partition" }; - - // true not supported in 4.1 ?? - publisherQos.Presentation.OrderedAccess = false; - - // Create the Publisher - dp.Enable(); - IPublisher publisher = dp.CreatePublisher(publisherQos); - Console.WriteLine("Create Publisher: {0}", publisher); - - DataWriterQos dwQos = null; - publisher.GetDefaultDataWriterQos(ref dwQos); - - - // Create a Detection Type Support and register it's type - Data.DataTestTypeSupport support = new Data.DataTestTypeSupport(); - - string test2 = support.TypeName; - Console.WriteLine("Register Typesupport"); - result = support.RegisterType(dp, support.TypeName); - Console.WriteLine("Register Typesupport Result: {0}", result); - - // Create a topic for the Detection type - TopicQos topicQos = null; - result = dp.GetDefaultTopicQos(ref topicQos); - - //topicQos.Ownership.Kind = OwnershipQosPolicyKind.ExclusiveOwnershipQos; - - //DDS.Test.TestTopicQos2(ref topicQos); - - // Add a listener to the topic - ITopic topic = dp.CreateTopic("Data_DataTest", support.TypeName, topicQos, - this, StatusKind.InconsistentTopic); - - topicQos.History.Depth = 5; - - ITopic topic2 = dp.CreateTopic("Data_DataTest", support.TypeName, topicQos); - - // ErrorCode errorCode; - // string msg; - // result = ErrorInfo.Update(); - // result = ErrorInfo.GetCode(out errorCode); - // result = ErrorInfo.GetMessage(out msg); - - // Create a DataWriter for the topic - Data.IDataTestDataWriter dataWriter = publisher.CreateDataWriter(topic, dwQos) as Data.IDataTestDataWriter; - - // Create a SubscriberQos object and set the partition name - SubscriberQos subscriberQos = null; - result = dp.GetDefaultSubscriberQos(ref subscriberQos); - subscriberQos.Partition.Name = new string[] { "howdy" }; - - // Create the subscriber - ISubscriber sub = dp.CreateSubscriber(subscriberQos); - // Verify that the subsciber was created... - if (sub == null) - { - Console.WriteLine("Subscriber not created"); - return; - } - - DDS.DataReaderQos readerQos = null; - sub.GetDefaultDataReaderQos(ref readerQos); - - //readerQos.SubscriptionKeys.KeyList = new string[] { "test" }; - //readerQos.Durability.Kind = DurabilityQosPolicyKind.TransientDurabilityQos; - //readerQos.Reliability.Kind = ReliabilityQosPolicyKind.ReliableReliabilityQos; - - // Create a DataReader for the Detection topic - Data.IDataTestDataReader dataReader = sub.CreateDataReader(topic, readerQos, this, StatusKind.DataAvailable) - as Data.IDataTestDataReader; - - // Create a filtered detection topic (only read detections that have an id != 4) - IContentFilteredTopic filteredTopic = dp.CreateContentFilteredTopic("Another", topic, "TestId <> %0", "234"); - //IContentFilteredTopic filteredTopic = dp.CreateContentFilteredTopic("Another", topic, "TestStr = %0", "not really"); - string[] testParams = null; - result = filteredTopic.GetExpressionParameters(ref testParams); - if (result != DDS.ReturnCode.Ok || testParams == null || testParams.Length != 1 || !testParams[0].Equals("234")) - { - Console.WriteLine("filteredTopic.GetExpressionParameters does not return the expected parameter....."); - } - else - { - Console.WriteLine("filteredTopic.GetExpressionParameters returns the expected parameter....."); - } - - result = filteredTopic.SetExpressionParameters("hello", "test"); - if (result != DDS.ReturnCode.Ok) - { - Console.WriteLine("filteredTopic.SetExpressionParameters returns not OK: result = " + result); - } -// result = filteredTopic.GetExpressionParameters(ref testParams); - - // Create a DataReader to read the filtered topic - Data.IDataTestDataReader reader2 = sub.CreateDataReader(filteredTopic) as Data.IDataTestDataReader; - - IQueryCondition queryCondition = dataReader.CreateQueryCondition( - "TestId = %0", - "234"); - - // just for testing... - GC.Collect(); - - // WaitSet - WaitSet waitSet = new WaitSet(); - - // either use status conditions...or - IStatusCondition sc = reader2.StatusCondition; - sc.SetEnabledStatuses(StatusKind.DataAvailable); - waitSet.AttachCondition(sc); - - IStatusCondition sc2 = reader2.StatusCondition; - - // read conditions... - IReadCondition readCond = reader2.CreateReadCondition(); - waitSet.AttachCondition(readCond); - - Console.WriteLine("Press enter to write data"); - Console.ReadLine(); - - detectionData.SequenceTest = new int[1];// new System.Collections.Generic.List(); - //detectionData.SequenceTest.Add(4); - detectionData.SequenceTest[0] = 4; - - // Write detection data - result = dataWriter.Write(detectionData); - - detectionData = new Data.DataTest(); - detectionData.TestId = 234; - dataWriter.Write(detectionData, InstanceHandle.Nil); - - detectionData = new Data.DataTest(); - detectionData.TestId = 235; - dataWriter.Write(detectionData); - - detectionData = new Data.DataTest(); - detectionData.TestId = 236; - dataWriter.Write(detectionData); - - detectionData = new Data.DataTest(); - detectionData.TestId = 237; - dataWriter.Write(detectionData); - - Console.WriteLine("Press enter to read data"); - Console.ReadLine(); - - // Read the data - ICondition[] cond = null; - waitSet.Wait(ref cond, Duration.Infinite); - - - SampleInfo[] infos = null; - Data.DataTest[] dataValues = null; - - result = dataReader.Read(ref dataValues, ref infos); - Console.WriteLine("dataReader: {0}", dataReader); - - if (dataValues != null) - { - Console.WriteLine("Number of samples received: {0}", dataValues.Length); - for (int index = 0; index < dataValues.Length; index++) - { - Console.WriteLine("TestId: {0}, ProviderId: {1}, Emergency: {2}, TestStr: {3}", dataValues[index].TestId, - dataValues[index].ProviderId, dataValues[index].Emergency, dataValues[index].TestStr); - Console.WriteLine("info: ValidData: {0}, InstHandle: {1}, PubHandle:{2}, SourceTS: {3}, ArrivalTS: {4}, sample: {5}, view: {6}, instance: {7}", - infos[index].ValidData, - infos[index].InstanceHandle, infos[index].PublicationHandle, - infos[index].SourceTimestamp, infos[index].ReceptionTimestamp, - infos[index].SampleState, infos[index].ViewState, infos[index].InstanceState); - } - } - - Console.WriteLine("Press enter to read data from contentfiltered topic"); - Console.ReadLine(); - - result = reader2.Read(ref dataValues, ref infos, DDS.Length.Unlimited); - if (dataValues != null) - { - Console.WriteLine("Number of samples received: {0}", dataValues.Length); - for (int index = 0; index < dataValues.Length; index++) - { - Console.WriteLine("TestId: {0}, ProviderId: {1}, Emergency: {2}, TestStr: {3}", dataValues[index].TestId, - dataValues[index].ProviderId, dataValues[index].Emergency, dataValues[index].TestStr); - Console.WriteLine("info: ValidData: {0}, InstHandle: {1}, PubHandle:{2}, SourceTS: {3}, ArrivalTS: {4}, sample: {5}, view: {6}, instance: {7}", - infos[index].ValidData, - infos[index].InstanceHandle, infos[index].PublicationHandle, - infos[index].SourceTimestamp, infos[index].ReceptionTimestamp, - infos[index].SampleState, infos[index].ViewState, infos[index].InstanceState); - } - } - - Console.WriteLine("Press enter to read data from query"); - Console.ReadLine(); - - result = dataReader.ReadWithCondition(ref dataValues, ref infos, DDS.Length.Unlimited, queryCondition); - if (dataValues != null) - { - Console.WriteLine("Number of samples received: {0}", dataValues.Length); - for (int index = 0; index < dataValues.Length; index++) - { - Console.WriteLine("TestId: {0}, ProviderId: {1}, Emergency: {2}, TestStr: {3}", dataValues[index].TestId, - dataValues[index].ProviderId, dataValues[index].Emergency, dataValues[index].TestStr); - Console.WriteLine("info: ValidData: {0}, InstHandle: {1}, PubHandle:{2}, SourceTS: {3}, ArrivalTS: {4}, sample: {5}, view: {6}, instance: {7}", - infos[index].ValidData, - infos[index].InstanceHandle, infos[index].PublicationHandle, - infos[index].SourceTimestamp, infos[index].ReceptionTimestamp, - infos[index].SampleState, infos[index].ViewState, infos[index].InstanceState); - } - } - - Console.WriteLine("Press enter to cleanup"); - Console.ReadLine(); - - Console.WriteLine("DeleteContainedEntities"); - result = dp.DeleteContainedEntities(); - - // If you don't use DeleteContainedEntities then you must delete everything that was created - //result = sub.DeleteDataReader(dataReader); - //result = publisher.DeleteDataWriter(dataWriter); - - //result = dp.DeleteTopic(topic); - //result = dp.DeletePublisher(publisher); - - //result = dp.DeleteSubscriber(sub); - - Console.WriteLine("DeleteParticipant"); - result = dpf.DeleteParticipant(dp); - - Console.WriteLine("Press enter to exit"); - Console.ReadLine(); - - } - - public override void OnDataAvailable(IDataReader entityInterface) - { - Console.WriteLine("Received OnDataAvailable"); - } - - public override void OnInconsistentTopic(ITopic entityInterface, InconsistentTopicStatus status) - { - // Test the listener... This class is an TopicListener -- we can listen for an InconsistenTopic - // by overriding the OnInconsistentTopic method of the TopicListener. - Console.WriteLine("Received Inconsistent Topic"); - } - } -} diff --git a/src/api/dcps/sacs/api_quick_test/code/TestBinding.csproj b/src/api/dcps/sacs/api_quick_test/code/TestBinding.csproj deleted file mode 100644 index 2dec00b90..000000000 --- a/src/api/dcps/sacs/api_quick_test/code/TestBinding.csproj +++ /dev/null @@ -1,70 +0,0 @@ - - - - Debug - AnyCPU - 9.0.21022 - 2.0 - {33364B52-2443-4B73-8C14-8EEFBABE5923} - Exe - Properties - TestBinding - v2.0 - 512 - - - true - full - false - bin - DEBUG;TRACE - prompt - 4 - true - TestBinding - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - TestBinding - - - - - - - - - - - - - - - - {AFB382F9-84F5-4226-BD28-A02F0B15F2E1} - dcpssacs - - - - - - - - - - - - idlpp -S -l cs -d "$(ProjectDir)Data" "$(ProjectDir)Data\DataTest.idl" - - \ No newline at end of file diff --git a/src/api/dcps/sacs/api_quick_test/code/TestBinding.sln b/src/api/dcps/sacs/api_quick_test/code/TestBinding.sln deleted file mode 100644 index 307485e5a..000000000 --- a/src/api/dcps/sacs/api_quick_test/code/TestBinding.sln +++ /dev/null @@ -1,30 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 10.00 -# Visual Studio 2008 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestBinding", "TestBinding.csproj", "{33364B52-2443-4B73-8C14-8EEFBABE5923}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "dcpssacs", "..\..\code\DDS\dcpssacs.csproj", "{AFB382F9-84F5-4226-BD28-A02F0B15F2E1}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {33364B52-2443-4B73-8C14-8EEFBABE5923}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {33364B52-2443-4B73-8C14-8EEFBABE5923}.Debug|Any CPU.Build.0 = Debug|Any CPU - {33364B52-2443-4B73-8C14-8EEFBABE5923}.Release|Any CPU.ActiveCfg = Release|Any CPU - {33364B52-2443-4B73-8C14-8EEFBABE5923}.Release|Any CPU.Build.0 = Release|Any CPU - {AFB382F9-84F5-4226-BD28-A02F0B15F2E1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {AFB382F9-84F5-4226-BD28-A02F0B15F2E1}.Debug|Any CPU.Build.0 = Debug|Any CPU - {AFB382F9-84F5-4226-BD28-A02F0B15F2E1}.Release|Any CPU.ActiveCfg = Release|Any CPU - {AFB382F9-84F5-4226-BD28-A02F0B15F2E1}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(MonoDevelopProperties) = preSolution - version = 0.1 - StartupItem = TestBinding.csproj - EndGlobalSection -EndGlobal diff --git a/src/api/dcps/sacs/api_quick_test/makefile.mak b/src/api/dcps/sacs/api_quick_test/makefile.mak deleted file mode 100755 index 135704287..000000000 --- a/src/api/dcps/sacs/api_quick_test/makefile.mak +++ /dev/null @@ -1,26 +0,0 @@ -# -# included by bld/$(SPLICE_TARGET)/makefile - -TARGET_CSEXEC = TestBinding -CS_NAMESPCS = . - -TARGET_LINK_DIR = ../../exec/$(SPLICE_TARGET) - -# Specify the location of the IDL data model, and the generation results of idlpp. -IDL_DIR := ../../code/Data -TOPIC_IDL := $(notdir $(wildcard $(IDL_DIR)/*.idl)) -IDL_CS := $(TOPIC_IDL:%.idl=%.cs) $(TOPIC_IDL:%.idl=I%Dcps.cs) $(TOPIC_IDL:%.idl=%Dcps.cs) $(TOPIC_IDL:%.idl=%SplDcps.cs) - -# Specify the CSharp API on which this application depends. -CS_API = $(OSPL_HOME)/src/api/dcps/sacs/bld/$(SPLICE_TARGET)/$(CSLIB_PREFIX)$(DDS_DCPSSACS)$(CSLIB_POSTFIX) - -# Fine tune the compiler flags. -CSLIBS += -r:$(CS_API) - -include $(OSPL_HOME)/setup/makefiles/target.mak - -# Generate the C++ interfaces from the IDL descriptions. -$(IDL_CS): $(IDL_DIR)/$(TOPIC_IDL) - idlpp -l cs -S $< - - diff --git a/src/api/dcps/sacs/code/DDS/Condition.cs b/src/api/dcps/sacs/code/DDS/Condition.cs index 0d209e791..14985a4e5 100644 --- a/src/api/dcps/sacs/code/DDS/Condition.cs +++ b/src/api/dcps/sacs/code/DDS/Condition.cs @@ -1,8 +1,9 @@ -/* - * OpenSplice DDS +/* + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,21 +30,21 @@ public abstract class Condition : SacsSuperClass, ICondition { protected List waitSetList = new List(); protected bool deinitializing = false; - + internal Condition() { // Base class handles everything. } - + internal override ReturnCode init(IntPtr userPtr, bool isWeak) { return base.init(userPtr, isWeak); } - + internal override ReturnCode wlReq_deinit() { ReturnCode result = DDS.ReturnCode.Ok; - + // Create a temporary representation of the waitSetList, since // it is not allowed to remove items from a collection during // a walk through that same collection. So we walk through @@ -66,10 +67,10 @@ internal override ReturnCode wlReq_deinit() waitSetList = null; result = base.wlReq_deinit(); } - + return result; } - + internal virtual ReturnCode AttachToWaitSet(WaitSet waitset) { ReturnCode result = DDS.ReturnCode.AlreadyDeleted; @@ -86,7 +87,7 @@ internal virtual ReturnCode AttachToWaitSet(WaitSet waitset) /* The waitset will detach itself when it is destructed. */ waitSetList.Add(waitset); } - } + } else { result = DDS.ReturnCode.Ok; @@ -94,13 +95,6 @@ internal virtual ReturnCode AttachToWaitSet(WaitSet waitset) } } -// if (result != DDS.ReturnCode.Ok) { -// OS_REPORT(OS_ERROR, -// "Condition::attach_waitset", 0, -// "attach failed with %s", -// DDS::OpenSplice::Utils::returnCodeToString(result)); -// } - return result; } @@ -125,13 +119,6 @@ internal virtual ReturnCode DetachFromWaitSet (WaitSet waitset) } } -// if (result != DDS.ReturnCode.Ok) { -// OS_REPORT(OS_ERROR, -// "Condition::detach_waitset", 0, -// "detach failed with %s", -// DDS::OpenSplice::Utils::returnCodeToString(result)); -// } - return result; } diff --git a/src/api/dcps/sacs/code/DDS/DataReaderListener.cs b/src/api/dcps/sacs/code/DDS/DataReaderListener.cs index fbc4e58d2..34ebbbc92 100644 --- a/src/api/dcps/sacs/code/DDS/DataReaderListener.cs +++ b/src/api/dcps/sacs/code/DDS/DataReaderListener.cs @@ -1,8 +1,9 @@ -/* - * OpenSplice DDS +/* + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/dcps/sacs/code/DDS/DataWriterListener.cs b/src/api/dcps/sacs/code/DDS/DataWriterListener.cs index 7b7540410..4efa754a2 100644 --- a/src/api/dcps/sacs/code/DDS/DataWriterListener.cs +++ b/src/api/dcps/sacs/code/DDS/DataWriterListener.cs @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/dcps/sacs/code/DDS/DdsDcpsEnums.cs b/src/api/dcps/sacs/code/DDS/DdsDcpsEnums.cs index 3f7e2bb72..19ec333a2 100644 --- a/src/api/dcps/sacs/code/DDS/DdsDcpsEnums.cs +++ b/src/api/dcps/sacs/code/DDS/DdsDcpsEnums.cs @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,12 +18,6 @@ * limitations under the License. */ -// Csharp backend -// PTF C# mapping for IDL -// File /Users/Jcm/Documents/Ecllipse_WS/CSharpDDS/generated/dds_dcps.cs -// Generated on 2008-11-11 13:36:00 -// from dds_dcps.idl - using System; using System.Runtime.InteropServices; @@ -215,10 +210,15 @@ public enum StatusKind : uint /// AllDataDisposed = 0x80000000, + /// + /// Any_V1_2 status. + /// + Any_V1_2 = 0x7fff, + /// /// Any status. /// - Any = 0x7fffffff, + Any = 0xffffffff } /// diff --git a/src/api/dcps/sacs/code/DDS/DdsDcpsInterfaces.cs b/src/api/dcps/sacs/code/DDS/DdsDcpsInterfaces.cs index 3c6114786..828e4e929 100644 --- a/src/api/dcps/sacs/code/DDS/DdsDcpsInterfaces.cs +++ b/src/api/dcps/sacs/code/DDS/DdsDcpsInterfaces.cs @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,11 +17,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -// Csharp backend -// PTF C# mapping for IDL -// File /Users/Jcm/Documents/Ecllipse_WS/CSharpDDS/generated/dds_dcps.cs -// Generated on 2008-11-11 13:36:00 -// from dds_dcps.idl using System; using System.Runtime.InteropServices; @@ -715,6 +711,21 @@ public interface IEntity /// The Listeners associated with an IEntity are not called until the IEntity is /// enabled. Conditions associated with an IEntity that is not enabled are "inactive", /// that is, have a TriggerValue which is false. + /// + /// In addition to the general description, the enable operation on a Subscriber has special meaning + /// in specific usecases. This applies only to Subscribers with PresentationQoS coherent-access set to + /// true with access-scope set to group. + /// + /// In this case the subscriber is always created in a disabled state, regardless of the factory's auto-enable + /// created entities setting. While the subscriber remains disabled, DataReaders can be created that will + /// participate in coherent transactions of the subscriber (See @ref DDS.ISubscriber.BeginAccess()) and + /// @ref DDS.ISubscriber.EndAccess() operations for more information). + /// + /// All DataReaders will also be created in a disabled state. Coherency with group access-scope requires data + /// to be delivered as a transaction, atomically, to all eligible readers. Therefore data should not be delivered + /// to any single DataReader immediately after it's created, as usual, but only after the application has finished + /// creating all DataReaders for a given Subscriber. At this point, the application should enable the Subscriber + /// which in turn enables all its DataReaders. /// /// Return codes are: /// @@ -2155,6 +2166,72 @@ public interface IDomainParticipant : IEntity /// ReturnCode GetDiscoveredTopicData (ref TopicBuiltinTopicData data, InstanceHandle handle); + /// + /// This operation looks up the property for a given key in the DomainParticipant. + /// + /// + /// This operation looks up the property for a given key + /// in the DomainParticipant, returning the value belonging to this key + /// If the property has not been set using setProperty, + /// the default value of the property is returned. + /// + /// The name of the property to request the value from + /// The value of the requested property. + /// Return values are: + /// + /// DDS.ReturnCode Ok - the information on the specified property has been successfully retrieved + /// DDS.ReturnCode Error - an internal error has occurred. + /// DDS.ReturnCode AlreadyDeleted - the IDomainParticipant has already been deleted + /// DDS.ReturnCode OutOfResources - the Data Distribution Service ran out of resources to complete this operation. + /// DDS.ReturnCode Unsupported - if the name specifies an undefined property or the operation is not supported in this version. + /// DDS.ReturnCode NotEnabled - the IDomainParticipant is not enabled. + /// DDS.ReturnCode BadParameter - An invalid name or value has been specified. + /// + /// + ReturnCode GetProperty(ref Property property); + + /// + /// This operation sets the property specified by a key value pair. + /// + /// + /// This operation sets the property specified by a key value pair. + /// Currently, the following property is defined: + /// + /// isolateNode + /// The isolateNode property allows applications to isolate the federation from the rest of + /// the Domain, i.e. at network level disconnect the node from the rest of the system. + /// Additionally, they also need to be able to issue a request to reconnect their federation + /// to the domain again after which the durability merge-policy that is configured needs to be + /// applied. + /// + /// To isolate a federation, the application needs to set the isolateNode property value + /// to 'true' and to (de)isolate the federation the same property needs to set to 'false'. + /// The default value of the isolateNode property is 'false'. + /// + /// All data that is published after isolateNode is set to true will not be sent to the network + /// and any data received from the network will be ignored. Be aware that data being processed + /// by the network service at time of isolating a node may still be sent to the network due + /// to asynchronous nature of network service internals. + /// + /// The value is interpreted as a boolean (i.e., it must be either 'true' or 'false'). + /// false (default): The federation is connected to the domain. + /// true: The federation is disconnected from the domain meaning that data is not published + /// on the network and data from the network is ignored. + /// + /// The name of the property + /// The value of the property + /// Return values are: + /// + /// DDS.ReturnCode Ok - the information on the specified property has been successfully set + /// DDS.ReturnCode Error - an internal error has occurred. + /// DDS.ReturnCode AlreadyDeleted - the IDomainParticipant has already been deleted + /// DDS.ReturnCode OutOfResources - the Data Distribution Service ran out of resources to complete this operation. + /// DDS.ReturnCode Unsupported - if the name specifies an undefined property or the operation is not supported in this version. + /// DDS.ReturnCode NotEnabled - the IDomainParticipant is not enabled. + /// DDS.ReturnCode BadParameter - An invalid name or value has been specified. + /// + /// + ReturnCode SetProperty(Property property); } @@ -4324,6 +4401,10 @@ public interface ISubscriber : IEntity /// /// The calls to BeginAccess() / EndAccess() may be nested. In that case, the /// application must call EndAccess() as many times as it called BeginAccess(). + /// + /// Note that a coherent Subscriber should first be enabled, otherwise this operation + /// will return an error. See @ref DDS.IEntity.Enable() for additional information. + /// /// /// Return codes are: /// @@ -4351,6 +4432,9 @@ public interface ISubscriber : IEntity /// /// This call must close a previous call to BeginAccess() otherwise the operation will /// return the error DDS.ReturnCode PreconditionNotMet. + /// + /// Please consult @ref DDS.IEntity.Enable() for additional information about coherent access + /// /// /// Return codes are: /// @@ -5842,11 +5926,11 @@ public interface IListener /// ITopicListener. This interface must be implemented by the /// application. A user-defined class must be provided by the application which must /// extend from the ITopicListener class.All operations for this interface must be implemented - /// in the user-defined class, it is up to the application whether an operation is empty or + /// in the user-defined class, it is up to the application whether an operation is empty or /// contains some functionality. - /// The ITopicListener provides a generic mechanism (actually a callback function) for the Data - /// Distribution Service to notify the application of relevant asynchronous status change events, - /// such as a missed deadline, violation of a QosPolicy setting, etc. The ITopicListener is + /// The ITopicListener provides a generic mechanism (actually a callback function) for the Data + /// Distribution Service to notify the application of relevant asynchronous status change events, + /// such as a missed deadline, violation of a QosPolicy setting, etc. The ITopicListener is /// related to changes in communication status StatusConditions. /// /// @@ -5865,9 +5949,9 @@ public interface ITopicListener : IListener /// This operation is called by the Data Distribution Service when the /// InconsistentTopicStatus changes. /// - /// The implementation may be left empty when this functionality is not needed. + /// The implementation may be left empty when this functionality is not needed. /// This operation will only be called when the relevant ITopicListener is installed and - /// enabled with the DDS.StatusKind.InconsistentTopic. The InconsistentTopicStatus will change + /// enabled with the DDS.StatusKind.InconsistentTopic. The InconsistentTopicStatus will change /// when another Topic exists with the same topic_name but different characteristics. /// /// contain a pointer to the Topic on which the conflict @@ -5882,10 +5966,10 @@ public interface ITopicListener : IListener /// IDataWriterListener. This interface must be implemented by the /// application. A user-defined class must be provided by the application which must /// extend from the DataWriterListener class. - /// All operations for this interface must be implemented in the user-defined class, + /// All operations for this interface must be implemented in the user-defined class, /// it is up to the application whether an operation is empty or contains some functionality. - /// The IDataWriterListener provides a generic mechanism (actually a callback function) - /// for the Data Distribution Service to notify the application of relevant + /// The IDataWriterListener provides a generic mechanism (actually a callback function) + /// for the Data Distribution Service to notify the application of relevant /// asynchronous status change events, such as a missed deadline, violation of /// a QosPolicy setting, etc. The IDataWriterListener is related to /// changes in communication status IStatusConditions. @@ -5899,17 +5983,17 @@ public interface ITopicListener : IListener /// { /// Console.WriteLine("OnOfferedDeadlineMissed"); /// } - /// + /// /// public void OnOfferedIncompatibleQos(DDS.IDataWriter writer, DDS.OfferedIncompatibleQosStatus status) /// { /// Console.WriteLine("OnOfferedIncompatibleQos"); /// } - /// + /// /// public void OnLivelinessLost(DDS.IDataWriter writer, DDS.LivelinessLostStatus status) /// { /// Console.WriteLine("OnLivelinessLost"); /// } - /// + /// /// public void OnPublicationMatched(DDS.IDataWriter writer, DDS.PublicationMatchedStatus status) /// { /// Console.WriteLine("OnPublicationMatched"); @@ -5921,40 +6005,40 @@ public interface IDataWriterListener : IListener { /// This operation is called by the Data Distribution Service when the /// OfferedDeadlineMissedStatus changes. - /// This operation will only be called when the relevant + /// This operation will only be called when the relevant /// IDataWriterListener is installed and enabled for the offered /// deadline missed status (DDS.StatusKind.OfferedDeadlineMissed). The offered deadline - /// missed status will change when the deadline that the IDataWriter has - /// committed through its DeadlineQosPolicy was not respected for a + /// missed status will change when the deadline that the IDataWriter has + /// committed through its DeadlineQosPolicy was not respected for a /// specific instance. - /// contain a pointer to the IDataWriter on which + /// contain a pointer to the IDataWriter on which /// the OfferedDeadlineMissedStatus has changed (this is an input to the application) /// contain the OfferedDeadlineMissedStatus object (this is - /// an input to the application). + /// an input to the application). void OnOfferedDeadlineMissed(IDataWriter entityInterface, OfferedDeadlineMissedStatus status); /// This operation called by the Data Distribution Service when the /// OfferedIncompatibleQosStatus changes. - /// This operation will only be called when the relevant IDataWriterListener - /// is installed and enabled for the DDS.StatusKind.OfferedIncompatibleQos. The incompatible + /// This operation will only be called when the relevant IDataWriterListener + /// is installed and enabled for the DDS.StatusKind.OfferedIncompatibleQos. The incompatible /// Qos status will change when a IDataReader object has been discovered by the IDataWriter - /// with the same ITopic and a requested DataReaderQos that was incompatible with the + /// with the same ITopic and a requested DataReaderQos that was incompatible with the /// one offered by the IDataWriter. - /// contain a pointer to the IDataWriter on which the + /// contain a pointer to the IDataWriter on which the /// OfferedIncompatibleQosStatus has changed (this is an input to the application). - /// contain the OfferedIncompatibleQosStatus object (this is + /// contain the OfferedIncompatibleQosStatus object (this is /// an input to the application). void OnOfferedIncompatibleQos(IDataWriter entityInterface, OfferedIncompatibleQosStatus status); - /// This operation is called by the Data Distribution Service when the + /// This operation is called by the Data Distribution Service when the /// LivelinessLostStatus changes. /// This operation will only be called when the relevant /// IDataWriterListener is installed and enabled for the liveliness lost status /// (LivelinessLostStatus). - /// The liveliness lost status will change when the liveliness that the DataWriter has + /// The liveliness lost status will change when the liveliness that the DataWriter has /// committed through its LivelinessQosPolicy was not respected. In other words, /// the IDataWriter failed to actively signal its liveliness within the offered liveliness /// period. As a result, the IDataReader objects will consider the IDataWriter as no /// longer “aliveâ€. - /// contains a pointer to the IDataWriter on which + /// contains a pointer to the IDataWriter on which /// the LivelinessLostStatus has changed (this is an input to /// the application). /// contains the LivelinessLostStatus object (this is an input @@ -5962,24 +6046,24 @@ public interface IDataWriterListener : IListener void OnLivelinessLost(IDataWriter entityInterface, LivelinessLostStatus status); /// /// This operation is called by the Data Distribution Service when a new match has - /// been discovered for the current publication, or when an existing match has + /// been discovered for the current publication, or when an existing match has /// ceased to exist. - /// Usually this means that a new IDataReader that matches the ITopic - /// and that has compatible Qos as the current IDataWriter has either been discovered, - /// or that a previously discovered IDataReader has ceased to be matched to the current - /// IDataWriter. A IDataReader may cease to match when it gets deleted, when it - /// changes its Qos to a value that is incompatible with the current IDataWriter or - /// when either the IDataWriter or the IDataReader has chosen to put its matching - /// counterpart on its ignore-list using the DDS.IDomainParticipant.IgnoreSubscription + /// Usually this means that a new IDataReader that matches the ITopic + /// and that has compatible Qos as the current IDataWriter has either been discovered, + /// or that a previously discovered IDataReader has ceased to be matched to the current + /// IDataWriter. A IDataReader may cease to match when it gets deleted, when it + /// changes its Qos to a value that is incompatible with the current IDataWriter or + /// when either the IDataWriter or the IDataReader has chosen to put its matching + /// counterpart on its ignore-list using the DDS.IDomainParticipant.IgnoreSubscription /// or DDS.IDomainParticipant.IgnorePublication operations. /// it will only be called when the relevant IDataWriterListener is installed and enabled /// for the PublicationMatchedStatus. - /// contains a pointer to the IDataWriter for which a + /// contains a pointer to the IDataWriter for which a /// match has been discovered (this is an input to the application provided by the /// Data Distribution Service). - /// contains the PublicationMatchedStatus object + /// contains the PublicationMatchedStatus object /// (this is an input to the application provided by the Data Distribution Service). - + void OnPublicationMatched(IDataWriter entityInterface, PublicationMatchedStatus status); } /// Since a Publisher is an Entity, it has the ability to have a Listener @@ -5989,7 +6073,7 @@ public interface IDataWriterListener : IListener /// extend from the IPublisherListener class. /// All operations for this interface must be implemented in the user-defined class, it is /// up to the application whether an operation is empty or contains some functionality. - /// The IPublisherListener provides a generic mechanism (actually a + /// The IPublisherListener provides a generic mechanism (actually a /// callback function) for the Data Distribution Service to notify the application of /// relevant asynchronous status change events, such as a missed deadline, violation of /// a QosPolicy setting, etc. The IPublisherListener is related to @@ -6014,9 +6098,9 @@ public interface IPublisherListener : IDataWriterListener /// IDataReaderListener. This interface must be implemented by the /// application. A user-defined class must be provided by the application which must /// extend from the IDataReaderListener class. - /// All operations for this interface must be implemented in the user-defined - /// class, it is up to the application whether an operation is empty or contains some - /// functionality. The IDataReaderListener provides a generic mechanism (actually a + /// All operations for this interface must be implemented in the user-defined + /// class, it is up to the application whether an operation is empty or contains some + /// functionality. The IDataReaderListener provides a generic mechanism (actually a /// callback function) for the Data Distribution Service to notify the application of /// relevant asynchronous status change events, such as a missed deadline, violation of /// a QosPolicy setting, etc. The IDataReaderListener is related to @@ -6026,7 +6110,7 @@ public interface IPublisherListener : IDataWriterListener /// { /// public MyExampleDataReaderListener() /// { - /// } + /// } /// public void OnRequestedDeadlineMissed(DDS.IDataReader reader, DDS.RequestedDeadlineMissedStatus status) /// { /// Console.WriteLine("OnRequestedDeadlineMissed"); @@ -6036,27 +6120,27 @@ public interface IPublisherListener : IDataWriterListener /// { /// Console.WriteLine("OnRequestedIncompatibleQos"); /// } - /// + /// /// public void OnSampleRejected(DDS.IDataReader reader, DDS.SampleRejectedStatus status) /// { /// Console.WriteLine("OnSampleRejected"); /// } - /// + /// /// public void OnLivelinessChanged(DDS.IDataReader reader, DDS.LivelinessChangedStatus status) /// { /// Console.WriteLine("OnLivelinessChanged"); /// } - /// + /// /// public void OnDataAvailable(DDS.IDataReader reader) /// { /// Console.WriteLine("OnDataAvailableCalled"); /// } - /// + /// /// public void OnSubscriptionMatched(DDS.IDataReader reader, DDS.SubscriptionMatchedStatus status) /// { /// Console.WriteLine("OnSubscriptionMatchCalled"); /// } - /// + /// /// public void OnSampleLost(DDS.IDataReader reader, DDS.SampleLostStatus status) /// { /// Console.WriteLine("OnSampleLostCalled"); @@ -6066,7 +6150,7 @@ public interface IPublisherListener : IDataWriterListener /// public interface IDataReaderListener : IListener { - + /// /// This operation called by the Data Distribution Service when the deadline /// that the IDataReader was expecting through its DeadlineQosPolicy was not @@ -6081,7 +6165,7 @@ public interface IDataReaderListener : IListener /// contain a pointer to the IDataReader for which /// the deadline was missed (this is an input to the application provided by the Data /// Distribution Service). - /// contain the RequestedDeadlineMissedStatus object (this is + /// contain the RequestedDeadlineMissedStatus object (this is /// an input to the application provided by the Data Distribution Service). void OnRequestedDeadlineMissed(IDataReader entityInterface, RequestedDeadlineMissedStatus status); @@ -6090,33 +6174,33 @@ public interface IDataReaderListener : IListener /// The implementation may be left empty when this functionality is not /// needed. This operation will only be called when the relevant IDataReaderListener /// is installed and enabled for the DDS.StatusKind.RequestedIncompatibleQos. The - /// Data Distribution Service will provide a reference to the IDataReader in the - /// parameter and the RequestedIncompatibleQosStatus object in the + /// Data Distribution Service will provide a reference to the IDataReader in the + /// parameter and the RequestedIncompatibleQosStatus object in the /// parameter , for use by the application. - /// - /// When the IDataReaderListener on the IDataReader is not enabled with the + /// + /// When the IDataReaderListener on the IDataReader is not enabled with the /// DDS.StatusKind.RequestedIncompatibleQos, the DDS.StatusKind.RequestedIncompatibleQos - /// change will propagate to the ISubscriberListener of the ISubscriber - /// (if enabled) or to the IDomainParticipantListener of the + /// change will propagate to the ISubscriberListener of the ISubscriber + /// (if enabled) or to the IDomainParticipantListener of the /// IDomainParticipant (if enabled). /// reader the IDataReader provided by the Data Distribution Service. /// the RequestedIncompatibleQosStatus object provided by the /// Data Distribution Service. void OnRequestedIncompatibleQos(IDataReader entityInterface, RequestedIncompatibleQosStatus status); - /// This operation called by the Data Distribution Service when a (received) + /// This operation called by the Data Distribution Service when a (received) /// sample has been rejected. - /// Samples may be rejected by the IDataReader when it runs out of - /// ResourceLimitsQosPolicy to store incoming samples. Usually this means that old samples need - /// to be ‘consumed’ (for example by ‘taking’ them instead of ‘reading’ them) to make + /// Samples may be rejected by the IDataReader when it runs out of + /// ResourceLimitsQosPolicy to store incoming samples. Usually this means that old samples need + /// to be ‘consumed’ (for example by ‘taking’ them instead of ‘reading’ them) to make /// room for newly incoming samples. /// The implementation may be left empty when this functionality is not needed. This /// operation will only be called when the relevant IDataReaderListener is installed /// and enabled with the DDS.StatusKind.SampleLost. /// contains a pointer to the IDataReader for which a sample - /// has been rejected (this is an input to the application provided by the + /// has been rejected (this is an input to the application provided by the /// Data Distribution Service). - /// contains the SampleRejectedStatus object (this is an + /// contains the SampleRejectedStatus object (this is an /// input to the application provided by the Data Distribution Service). void OnSampleRejected(IDataReader entityInterface, SampleRejectedStatus status); @@ -6146,13 +6230,13 @@ public interface IDataReaderListener : IListener /// available for this IDataReader. /// /// - /// The implementation may be left empty when this functionality is not + /// The implementation may be left empty when this functionality is not /// needed. This operation will only be called when the relevant IDataReaderListener /// is installed and enabled for the DDS.StatusKind.DataAvailable. /// The Data Distribution Service will provide a reference to the IDataReader in the /// parameter for use by the application. - /// The statuses DDS.StatusKind.DataOnReaders and DDS.StatusKind.DataAvailable will - /// occur together. In case these status changes occur, the Data Distribution + /// The statuses DDS.StatusKind.DataOnReaders and DDS.StatusKind.DataAvailable will + /// occur together. In case these status changes occur, the Data Distribution /// Service will look for an attached and activated ISubscriberListener or /// IDomainParticipantListener (in that order) for the enabled /// DDS.StatusKind.DataOnReaders. In case the DDS.StatusKind.DataOnReaders can not be @@ -6173,14 +6257,14 @@ public interface IDataReaderListener : IListener /// when a new match has been discovered for the current subscription, or /// when an existing match has ceased to exist. /// Usually this means that a new IDataWriter that matches - /// the ITopic and that has compatible Qos as the current IDataReader has + /// the ITopic and that has compatible Qos as the current IDataReader has /// either been discovered, or that a previously discovered IDataWriter has - /// ceased to be matched to the current IDataReader. A IDataWriter may cease to + /// ceased to be matched to the current IDataReader. A IDataWriter may cease to /// match when it gets deleted, when it changes its Qos to a value that is incompatible /// with the current IDataReader or when either the IDataReader or the IDataWriter /// has chosen to put its matching counterpart on its ignore-list using the /// DDS.IDomainParticipant.IgnoreSubscription or DDS.IDomainParticipant.IgnorePublication operations. - /// + /// /// The implementation of this IListener operation may be left empty when this /// functionality is not needed: it will only be called when the relevant /// IDataReaderListener is installed and enabled for the DDS.StatusKind.SubscriptionMatched. @@ -6201,16 +6285,16 @@ public interface IDataReaderListener : IListener /// Since a Subscriber is an Entity, it has the ability to have a Listener /// associated with it. In this case, the associated Listener should be of type - /// ISubscriberListener. This interface must be implemented by the + /// ISubscriberListener. This interface must be implemented by the /// application. A user-defined class must be provided by the application which must - /// extend from the SubscriberListener class. All operations for this interface must be + /// extend from the SubscriberListener class. All operations for this interface must be /// implemented in the user-defined class, it is up to the application whether an operation is /// empty or contains some functionality. /// The ISubscriberListener provides a generic mechanism (actually a callback function) for - /// the Data Distribution Service to notify the application of relevant asynchronous status - /// change events, such as a missed deadline, violation of a QosPolicy setting, etc. The + /// the Data Distribution Service to notify the application of relevant asynchronous status + /// change events, such as a missed deadline, violation of a QosPolicy setting, etc. The /// ISubscriberListener is related to changes in communication status StatusConditions. - /// + /// /// public class MySubscriberListener : DDS.ISubscriberListener /// { /// public MySubscriberListener() @@ -6227,18 +6311,18 @@ public interface ISubscriberListener : IDataReaderListener { /// This operation called by the Data Distribution Service when new data is /// available for this Subscriber. - /// The implementation may be left empty when this functionality is not needed. - /// This operation will only be called when the relevant ISubscriberListener + /// The implementation may be left empty when this functionality is not needed. + /// This operation will only be called when the relevant ISubscriberListener /// is installed and enabled with the DDS.StatusKind.DataOnReaders. - /// The statuses OnDataOnReaders() and OnDataAvailable() will occur together. + /// The statuses OnDataOnReaders() and OnDataAvailable() will occur together. /// In case these status changes occur, the Data Distribution Service will look for - /// an attached and activated ISubscriberListener or IDomainParticipantListener + /// an attached and activated ISubscriberListener or IDomainParticipantListener /// (in that order) for the enabled DDS.StatusKind.DataOnReaders. In case the DDS.StatusKind.DataOnReaders /// can not be handled, the Data Distribution Service will look for an attached and activated - /// IDataReaderListener, ISubscriberListener or IDomainParticipantListener for the enabled + /// IDataReaderListener, ISubscriberListener or IDomainParticipantListener for the enabled /// DDS.StatusKind.DataAvailable (in that order). Note that if OnDataOnReaders is called, then the Data Distribution /// Service will not try to call OnDataAvailable, however, the application can force a call - /// to the callback function OnDataAvailable of IDataReaderListener objects that have + /// to the callback function OnDataAvailable of IDataReaderListener objects that have /// data by means of the Subscriber.NotifyDatareaders() operation. /// contain a pointer to the ISubscriber for which data is available (this is /// an input to the application provided by the Data Distribution Service). @@ -6251,9 +6335,9 @@ public interface ISubscriberListener : IDataReaderListener /// extend from the IDomainParticipantListener class. /// All operations for this interface must be implemented in the user-defined class, it is /// up to the application whether an operation is empty or contains some functionality. - /// The IDomainParticipantListener provides a generic mechanism (actually a callback function) + /// The IDomainParticipantListener provides a generic mechanism (actually a callback function) /// for the Data Distribution Service to notify the application of relevant asynchronous status - /// change events, such as a missed deadline, violation of QosPolicy setting, etc. The + /// change events, such as a missed deadline, violation of QosPolicy setting, etc. The /// IDomainParticipantListener is related to changes in communication status StatusConditions. /// /// diff --git a/src/api/dcps/sacs/code/DDS/DdsDcpsStructs.cs b/src/api/dcps/sacs/code/DDS/DdsDcpsStructs.cs index f633c38c3..a42cad3ce 100644 --- a/src/api/dcps/sacs/code/DDS/DdsDcpsStructs.cs +++ b/src/api/dcps/sacs/code/DDS/DdsDcpsStructs.cs @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,12 +18,6 @@ * limitations under the License. */ -// Csharp backend -// PTF C# mapping for IDL -// File /Users/Jcm/Documents/Ecllipse_WS/CSharpDDS/generated/dds_dcps.cs -// Generated on 2008-11-11 13:36:00 -// from dds_dcps.idl - using System; using System.Runtime.InteropServices; @@ -36,6 +31,30 @@ namespace DDS // ---------------------------------------------------------------------- + public struct Property + { + private string _name; + private string _value; + + public Property(string name, string val) + { + _name = name; + _value = val; + } + + public string Name + { + get { return _name; } + set { _name = value; } + } + + public string Value + { + get { return _value; } + set { _value = value; } + } + } + /// /// Duration represents a time interval. /// diff --git a/src/api/dcps/sacs/code/DDS/DomainParticipantFactory.cs b/src/api/dcps/sacs/code/DDS/DomainParticipantFactory.cs index 4d04bb1a8..c183ce0b2 100644 --- a/src/api/dcps/sacs/code/DDS/DomainParticipantFactory.cs +++ b/src/api/dcps/sacs/code/DDS/DomainParticipantFactory.cs @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/dcps/sacs/code/DDS/DomainParticipantListener.cs b/src/api/dcps/sacs/code/DDS/DomainParticipantListener.cs index 58d8b5e95..2548615a4 100644 --- a/src/api/dcps/sacs/code/DDS/DomainParticipantListener.cs +++ b/src/api/dcps/sacs/code/DDS/DomainParticipantListener.cs @@ -1,8 +1,9 @@ -/* - * OpenSplice DDS +/* + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/dcps/sacs/code/DDS/ErrorInfo.cs b/src/api/dcps/sacs/code/DDS/ErrorInfo.cs index fd317cfcc..ab6adae75 100644 --- a/src/api/dcps/sacs/code/DDS/ErrorInfo.cs +++ b/src/api/dcps/sacs/code/DDS/ErrorInfo.cs @@ -1,8 +1,9 @@ -/* - * OpenSplice DDS +/* + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -44,24 +45,24 @@ internal ReturnCode init() // Parent class is only needed for its WriteLock and ReadLock calls... return DDS.ReturnCode.Ok; } - + internal override ReturnCode wlReq_deinit() { // Because there is no UserLayer ref to be stored, do NOT forward to SacsSuperClass.wlReq_deinit()!! // Parent class is only needed for its WriteLock and ReadLock calls... return DDS.ReturnCode.Ok; } - + public ReturnCode Update() { ReturnCode result; - + IntPtr osInfoPtr = DDS.OpenSplice.OS.Report.GetApiInfo(); if (osInfoPtr != IntPtr.Zero) { DDS.OpenSplice.OS.ReportInfo osInfo; Type osInfoType = typeof(DDS.OpenSplice.OS.ReportInfo); - + osInfo = (DDS.OpenSplice.OS.ReportInfo) Marshal.PtrToStructure(osInfoPtr, osInfoType); reportContext = BaseMarshaler.ReadString(osInfo.reportContext); sourceLine = BaseMarshaler.ReadString(osInfo.sourceLine); @@ -82,7 +83,7 @@ public ReturnCode Update() public ReturnCode GetCode(out ErrorCode code) { ReturnCode result; - + if (valid) { code = (ErrorCode)this.reportCode; @@ -99,7 +100,7 @@ public ReturnCode GetCode(out ErrorCode code) public ReturnCode GetCode(out ReturnCode code) { ReturnCode result; - + if (valid) { code = (DDS.ReturnCode)DDS.OpenSplice.Common.ErrorInfo.ReportCodeToCode(this.reportCode); @@ -116,7 +117,7 @@ public ReturnCode GetCode(out ReturnCode code) public ReturnCode GetMessage(out string message) { ReturnCode result; - + if (valid) { message = this.description; @@ -133,7 +134,7 @@ public ReturnCode GetMessage(out string message) public ReturnCode GetLocation(out string location) { ReturnCode result; - + if (valid) { location = this.reportContext; @@ -150,7 +151,7 @@ public ReturnCode GetLocation(out string location) public ReturnCode GetSourceLine(out string sourceLine) { ReturnCode result; - + if (valid) { sourceLine = this.sourceLine; @@ -167,7 +168,7 @@ public ReturnCode GetSourceLine(out string sourceLine) public ReturnCode GetStackTrace(out string stackTrace) { ReturnCode result; - + if (valid) { stackTrace = this.callStack; diff --git a/src/api/dcps/sacs/code/DDS/GuardCondition.cs b/src/api/dcps/sacs/code/DDS/GuardCondition.cs index e4c43e914..bfd036470 100644 --- a/src/api/dcps/sacs/code/DDS/GuardCondition.cs +++ b/src/api/dcps/sacs/code/DDS/GuardCondition.cs @@ -1,8 +1,9 @@ -/* - * OpenSplice DDS +/* + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,7 +27,7 @@ namespace DDS public class GuardCondition : Condition, IGuardCondition { private bool triggerValue = false; - + public GuardCondition() { } @@ -35,12 +36,12 @@ internal ReturnCode init() { return base.init(IntPtr.Zero, true); } - + internal override ReturnCode wlReq_deinit() { return base.wlReq_deinit(); } - + internal override ReturnCode AttachToWaitSet(WaitSet waitset) { ReturnCode result = DDS.ReturnCode.AlreadyDeleted; @@ -58,7 +59,7 @@ internal override ReturnCode AttachToWaitSet(WaitSet waitset) /* The waitset will detach itself when it is destructed. */ waitSetList.Add(waitset); } - } + } else { result = DDS.ReturnCode.Ok; @@ -66,13 +67,6 @@ internal override ReturnCode AttachToWaitSet(WaitSet waitset) } } -// if (result != DDS.ReturnCode.Ok) { -// OS_REPORT(OS_ERROR, -// "Condition::attach_waitset", 0, -// "attach failed with %s", -// DDS::OpenSplice::Utils::returnCodeToString(result)); -// } - return result; } @@ -96,13 +90,6 @@ internal override ReturnCode DetachFromWaitSet (WaitSet waitset) } } -// if (result != DDS.ReturnCode.Ok) { -// OS_REPORT(OS_ERROR, -// "Condition::detach_waitset", 0, -// "detach failed with %s", -// DDS::OpenSplice::Utils::returnCodeToString(result)); -// } - return result; } @@ -137,7 +124,7 @@ public ReturnCode SetTriggerValue(bool value) { triggerValue = value; context = rlReq_HandleSelf; - + /* A copy of the list of waitsets is made to be triggered after * the condition is released. Triggering a Waitset will lock the * Waitset whereas the Waitset may lock the condition to get the diff --git a/src/api/dcps/sacs/code/DDS/OpenSplice/Common/ErrorInfo.cs b/src/api/dcps/sacs/code/DDS/OpenSplice/Common/ErrorInfo.cs index 2d9e7f112..e7fee5695 100644 --- a/src/api/dcps/sacs/code/DDS/OpenSplice/Common/ErrorInfo.cs +++ b/src/api/dcps/sacs/code/DDS/OpenSplice/Common/ErrorInfo.cs @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,6 +17,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + using System; using System.Runtime.InteropServices; using DDS.OpenSplice.CustomMarshalers; diff --git a/src/api/dcps/sacs/code/DDS/OpenSplice/Common/ListenerDispatcher.cs b/src/api/dcps/sacs/code/DDS/OpenSplice/Common/ListenerDispatcher.cs index 38e670347..5206bbebb 100644 --- a/src/api/dcps/sacs/code/DDS/OpenSplice/Common/ListenerDispatcher.cs +++ b/src/api/dcps/sacs/code/DDS/OpenSplice/Common/ListenerDispatcher.cs @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,6 +17,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + using System; using System.Runtime.InteropServices; using DDS.OpenSplice.CustomMarshalers; diff --git a/src/api/dcps/sacs/code/DDS/OpenSplice/Common/ListenerEvent.cs b/src/api/dcps/sacs/code/DDS/OpenSplice/Common/ListenerEvent.cs index f2305ff21..5c0812048 100644 --- a/src/api/dcps/sacs/code/DDS/OpenSplice/Common/ListenerEvent.cs +++ b/src/api/dcps/sacs/code/DDS/OpenSplice/Common/ListenerEvent.cs @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/dcps/sacs/code/DDS/OpenSplice/Common/QosProvider.cs b/src/api/dcps/sacs/code/DDS/OpenSplice/Common/QosProvider.cs index 89309f338..3d5452141 100644 --- a/src/api/dcps/sacs/code/DDS/OpenSplice/Common/QosProvider.cs +++ b/src/api/dcps/sacs/code/DDS/OpenSplice/Common/QosProvider.cs @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/dcps/sacs/code/DDS/OpenSplice/Common/SampleList.cs b/src/api/dcps/sacs/code/DDS/OpenSplice/Common/SampleList.cs index 69aad781e..58e99c23e 100644 --- a/src/api/dcps/sacs/code/DDS/OpenSplice/Common/SampleList.cs +++ b/src/api/dcps/sacs/code/DDS/OpenSplice/Common/SampleList.cs @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,7 +25,7 @@ namespace DDS.OpenSplice.Common { /** \brief Callback function to copy samples into the language binding. - * + * * When there are samples within the list, then this callback will be called * by cmn_samplesList_read() or cmn_samplesList_flush(). The language binding * can use this call to copy the provided sample into its' own types. diff --git a/src/api/dcps/sacs/code/DDS/OpenSplice/Common/Status.cs b/src/api/dcps/sacs/code/DDS/OpenSplice/Common/Status.cs index 5c938f2dd..aa55522c9 100644 --- a/src/api/dcps/sacs/code/DDS/OpenSplice/Common/Status.cs +++ b/src/api/dcps/sacs/code/DDS/OpenSplice/Common/Status.cs @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/dcps/sacs/code/DDS/OpenSplice/ContentFilteredTopic.cs b/src/api/dcps/sacs/code/DDS/OpenSplice/ContentFilteredTopic.cs index 84654c275..2f7418d85 100644 --- a/src/api/dcps/sacs/code/DDS/OpenSplice/ContentFilteredTopic.cs +++ b/src/api/dcps/sacs/code/DDS/OpenSplice/ContentFilteredTopic.cs @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/dcps/sacs/code/DDS/OpenSplice/CustomMarshalers/BaseMarshaler.cs b/src/api/dcps/sacs/code/DDS/OpenSplice/CustomMarshalers/BaseMarshaler.cs index 1d096c475..bfa2338a1 100644 --- a/src/api/dcps/sacs/code/DDS/OpenSplice/CustomMarshalers/BaseMarshaler.cs +++ b/src/api/dcps/sacs/code/DDS/OpenSplice/CustomMarshalers/BaseMarshaler.cs @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -185,7 +186,7 @@ public static void WriteString(ref IntPtr to, string from) to = IntPtr.Zero; } } - + public static void ReleaseString(ref IntPtr to) { if (to != IntPtr.Zero) { @@ -197,7 +198,7 @@ public static void ReleaseString(ref IntPtr to) to = IntPtr.Zero; } } - + #endregion #region Readers @@ -253,7 +254,7 @@ public static double ReadDouble(IntPtr from, int offset) return dtl.theDouble; } - public static float ReadSingle(IntPtr from, int offset) + public static float ReadFloat(IntPtr from, int offset) { SingleToInt sti = new SingleToInt(); sti.theInt = Marshal.ReadInt32(from, offset); @@ -292,11 +293,11 @@ public static IntPtr ReadIntPtr(IntPtr from, int offset) { return Marshal.ReadIntPtr(from, offset); } - + public static string ReadString(IntPtr from) { string result; - + if (from != IntPtr.Zero) { #if COMPACT_FRAMEWORK @@ -310,7 +311,7 @@ public static string ReadString(IntPtr from) } else { result = null; } - + return result; } diff --git a/src/api/dcps/sacs/code/DDS/OpenSplice/CustomMarshalers/DataReaderMarshalers.cs b/src/api/dcps/sacs/code/DDS/OpenSplice/CustomMarshalers/DataReaderMarshalers.cs index 93fc2662e..60804b4cd 100644 --- a/src/api/dcps/sacs/code/DDS/OpenSplice/CustomMarshalers/DataReaderMarshalers.cs +++ b/src/api/dcps/sacs/code/DDS/OpenSplice/CustomMarshalers/DataReaderMarshalers.cs @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -84,4 +85,4 @@ // sampleInfoHandle.Free(); // } // } -//} \ No newline at end of file +//} diff --git a/src/api/dcps/sacs/code/DDS/OpenSplice/CustomMarshalers/DatabaseMarshaler.cs b/src/api/dcps/sacs/code/DDS/OpenSplice/CustomMarshalers/DatabaseMarshaler.cs index 94d4642d6..11efe66ea 100644 --- a/src/api/dcps/sacs/code/DDS/OpenSplice/CustomMarshalers/DatabaseMarshaler.cs +++ b/src/api/dcps/sacs/code/DDS/OpenSplice/CustomMarshalers/DatabaseMarshaler.cs @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -92,7 +93,7 @@ public DatabaseMarshaler() typeMarshalers.TryGetValue(new KeyValuePair(participant, t), out marshaler); return marshaler; } - + public static void initObjectSeq(object[] src, object[] target) { if (src != null) diff --git a/src/api/dcps/sacs/code/DDS/OpenSplice/CustomMarshalers/DatabaseSequenceMarshaler.cs b/src/api/dcps/sacs/code/DDS/OpenSplice/CustomMarshalers/DatabaseSequenceMarshaler.cs index 8ab0892c9..f2a94a724 100644 --- a/src/api/dcps/sacs/code/DDS/OpenSplice/CustomMarshalers/DatabaseSequenceMarshaler.cs +++ b/src/api/dcps/sacs/code/DDS/OpenSplice/CustomMarshalers/DatabaseSequenceMarshaler.cs @@ -1,21 +1,3 @@ -/* - * OpenSplice DDS - * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ //using System; //using System.Collections.Generic; //using System.Text; diff --git a/src/api/dcps/sacs/code/DDS/OpenSplice/CustomMarshalers/FooDatabaseMarshaler.cs b/src/api/dcps/sacs/code/DDS/OpenSplice/CustomMarshalers/FooDatabaseMarshaler.cs index d6377089c..f70499da1 100644 --- a/src/api/dcps/sacs/code/DDS/OpenSplice/CustomMarshalers/FooDatabaseMarshaler.cs +++ b/src/api/dcps/sacs/code/DDS/OpenSplice/CustomMarshalers/FooDatabaseMarshaler.cs @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/dcps/sacs/code/DDS/OpenSplice/CustomMarshalers/ListenerMarshalers.cs b/src/api/dcps/sacs/code/DDS/OpenSplice/CustomMarshalers/ListenerMarshalers.cs index 2f3899a29..2af1b99cd 100644 --- a/src/api/dcps/sacs/code/DDS/OpenSplice/CustomMarshalers/ListenerMarshalers.cs +++ b/src/api/dcps/sacs/code/DDS/OpenSplice/CustomMarshalers/ListenerMarshalers.cs @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/dcps/sacs/code/DDS/OpenSplice/CustomMarshalers/QosContainedMarshalers.cs b/src/api/dcps/sacs/code/DDS/OpenSplice/CustomMarshalers/QosContainedMarshalers.cs index a51dd5e3a..fee52cd8a 100644 --- a/src/api/dcps/sacs/code/DDS/OpenSplice/CustomMarshalers/QosContainedMarshalers.cs +++ b/src/api/dcps/sacs/code/DDS/OpenSplice/CustomMarshalers/QosContainedMarshalers.cs @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/dcps/sacs/code/DDS/OpenSplice/CustomMarshalers/QosToplevelMarshalers.cs b/src/api/dcps/sacs/code/DDS/OpenSplice/CustomMarshalers/QosToplevelMarshalers.cs index 101ad3824..941f6842b 100644 --- a/src/api/dcps/sacs/code/DDS/OpenSplice/CustomMarshalers/QosToplevelMarshalers.cs +++ b/src/api/dcps/sacs/code/DDS/OpenSplice/CustomMarshalers/QosToplevelMarshalers.cs @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/dcps/sacs/code/DDS/OpenSplice/CustomMarshalers/SampleMarshalers.cs b/src/api/dcps/sacs/code/DDS/OpenSplice/CustomMarshalers/SampleMarshalers.cs index 4828ce534..4c8135539 100644 --- a/src/api/dcps/sacs/code/DDS/OpenSplice/CustomMarshalers/SampleMarshalers.cs +++ b/src/api/dcps/sacs/code/DDS/OpenSplice/CustomMarshalers/SampleMarshalers.cs @@ -1,8 +1,9 @@ -/* - * OpenSplice DDS +/* + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/dcps/sacs/code/DDS/OpenSplice/CustomMarshalers/SequenceMarshalers.cs b/src/api/dcps/sacs/code/DDS/OpenSplice/CustomMarshalers/SequenceMarshalers.cs index 2b7db003e..4aa9ea73d 100644 --- a/src/api/dcps/sacs/code/DDS/OpenSplice/CustomMarshalers/SequenceMarshalers.cs +++ b/src/api/dcps/sacs/code/DDS/OpenSplice/CustomMarshalers/SequenceMarshalers.cs @@ -1,8 +1,9 @@ -/* - * OpenSplice DDS +/* + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/dcps/sacs/code/DDS/OpenSplice/CustomMarshalers/StatusMarshaler.cs b/src/api/dcps/sacs/code/DDS/OpenSplice/CustomMarshalers/StatusMarshaler.cs index 709fb30ed..3d83ff37f 100644 --- a/src/api/dcps/sacs/code/DDS/OpenSplice/CustomMarshalers/StatusMarshaler.cs +++ b/src/api/dcps/sacs/code/DDS/OpenSplice/CustomMarshalers/StatusMarshaler.cs @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -214,7 +215,6 @@ internal static V_RESULT CopyOut(ref v_incompatibleQosInfo from, RequestedIncomp int arrSize = 0; for (int i = 0; i < Constants.V_POLICY_ID_COUNT; i++) { -// int v = BaseMarshaler.ReadInt32(from.policyCount, i * 4); // Offset = index * sizeof(int) int v = from.policyCount[i]; if (v != 0) { @@ -226,7 +226,6 @@ internal static V_RESULT CopyOut(ref v_incompatibleQosInfo from, RequestedIncomp to.Policies = new QosPolicyCount[arrSize]; for (int i = 0; i < Constants.V_POLICY_ID_COUNT; i++) { -// int v = BaseMarshaler.ReadInt32(from.policyCount, i * 4); // Offset = index * sizeof(int) int v = from.policyCount[i]; if (v != 0) @@ -344,7 +343,6 @@ internal static V_RESULT CopyOut(ref v_incompatibleQosInfo from, OfferedIncompat int arrSize = 0; for (int i = 0; i < Constants.V_POLICY_ID_COUNT; i++) { -// int v = BaseMarshaler.ReadInt32(from.policyCount, i * 4); // Offset = index * sizeof(int) int v = from.policyCount[i]; if (v != 0) @@ -357,7 +355,6 @@ internal static V_RESULT CopyOut(ref v_incompatibleQosInfo from, OfferedIncompat to.Policies = new QosPolicyCount[arrSize]; for (int i = 0; i < Constants.V_POLICY_ID_COUNT; i++) { -// int v = BaseMarshaler.ReadInt32(from.policyCount, i * 4); // Offset = index * sizeof(int) int v = from.policyCount[i]; if (v != 0) diff --git a/src/api/dcps/sacs/code/DDS/OpenSplice/CustomMarshalers/UserMarshaler.cs b/src/api/dcps/sacs/code/DDS/OpenSplice/CustomMarshalers/UserMarshaler.cs index 0de2dcf1f..6eca30ed8 100644 --- a/src/api/dcps/sacs/code/DDS/OpenSplice/CustomMarshalers/UserMarshaler.cs +++ b/src/api/dcps/sacs/code/DDS/OpenSplice/CustomMarshalers/UserMarshaler.cs @@ -1,21 +1,3 @@ -/* - * OpenSplice DDS - * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ using System; using DDS.OpenSplice; using DDS.OpenSplice.OS; @@ -23,10 +5,10 @@ namespace DDS.OpenSplice.CustomMarshalers { - /** + /** * Common base class for all Marshalers that marshal to * and from gapi datatypes. - */ + */ internal abstract class UserMarshaler : BaseMarshaler, IDisposable where TUserType : class, new() where TSacsType : class, new() @@ -68,7 +50,7 @@ internal IntPtr UserPtr public void Dispose() { - if (cleanupRequired) + if (cleanupRequired) { if (nativeImg != null) { @@ -81,7 +63,7 @@ public void Dispose() internal DDS.ReturnCode CopyIn(TSacsType from) { DDS.ReturnCode result; - + nativeImg = new TUserType(); result = CopyIn(from, ref nativeImg); if (result == DDS.ReturnCode.Ok) @@ -90,7 +72,7 @@ internal DDS.ReturnCode CopyIn(TSacsType from) } return result; } - + internal void CopyOut(ref TSacsType to) { nativeImg = (TUserType) Marshal.PtrToStructure(userPtr, type); @@ -98,4 +80,4 @@ internal void CopyOut(ref TSacsType to) CopyOut(nativeImg, ref to); } } -} \ No newline at end of file +} diff --git a/src/api/dcps/sacs/code/DDS/OpenSplice/DataReader.cs b/src/api/dcps/sacs/code/DDS/OpenSplice/DataReader.cs index 304bf1bae..ea2f3391d 100644 --- a/src/api/dcps/sacs/code/DDS/OpenSplice/DataReader.cs +++ b/src/api/dcps/sacs/code/DDS/OpenSplice/DataReader.cs @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -36,7 +37,6 @@ public class DataReader : Entity, IDataReader public const ViewStateKind VIEW_STATE_FLAGS = (ViewStateKind.NotNew | ViewStateKind.New); public const InstanceStateKind INSTANCE_STATE_FLAGS = (InstanceStateKind.Alive | InstanceStateKind.NotAlive); -// private DataReaderListenerHelper listenerHelper; private Subscriber subscriber; private ITopicDescriptionImpl topic; private List conditionList = new List(); @@ -59,7 +59,8 @@ internal virtual ReturnCode init(Subscriber subscriber, DataReaderQos drQos, ITo { using (SequenceStringToCValueArrMarshaler paramsMarshaler = new SequenceStringToCValueArrMarshaler()) { - result = paramsMarshaler.CopyIn(aTopic.rlReq_TopicExpressionParameters); + string[] _params = aTopic.rlReq_TopicExpressionParameters; + result = paramsMarshaler.CopyIn(_params); if (result == ReturnCode.Ok) { IntPtr uReader = User.DataReader.NewBySQL( @@ -67,8 +68,8 @@ internal virtual ReturnCode init(Subscriber subscriber, DataReaderQos drQos, ITo drName, aTopic.rlReq_TopicExpression, paramsMarshaler.UserPtr, - qosMarshaler.UserPtr, - 0); + _params==null ? 0 : Convert.ToUInt32(_params.Length), + qosMarshaler.UserPtr); if (uReader != IntPtr.Zero) { result = base.init(uReader); @@ -231,7 +232,7 @@ internal static V_RESULT CopyMatchedPublicationData(IntPtr info, IntPtr arg) (__PublicationBuiltinTopicData) Marshal.PtrToStructure(info, typeof(__PublicationBuiltinTopicData)); GCHandle argGCHandle = GCHandle.FromIntPtr(arg); PublicationBuiltinTopicData to = argGCHandle.Target as PublicationBuiltinTopicData; - PublicationBuiltinTopicDataMarshaler.CopyOut(ref nativeImage, ref to); + __PublicationBuiltinTopicDataMarshaler.CopyOut(ref nativeImage, ref to); argGCHandle.Target = to; return V_RESULT.OK; } @@ -782,6 +783,10 @@ public ReturnCode WaitForHistoricalData(Duration maxWait) { result = DDS.ReturnCode.BadParameter; } + else if (!this.IsEnabled()) + { + result = DDS.ReturnCode.NotEnabled; + } else { if (this.rlReq_isAlive) diff --git a/src/api/dcps/sacs/code/DDS/OpenSplice/DataWriter.cs b/src/api/dcps/sacs/code/DDS/OpenSplice/DataWriter.cs index 12b94a89d..91deccf04 100644 --- a/src/api/dcps/sacs/code/DDS/OpenSplice/DataWriter.cs +++ b/src/api/dcps/sacs/code/DDS/OpenSplice/DataWriter.cs @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -141,7 +142,7 @@ internal static V_RESULT CopyMatchedSubscriptionData(IntPtr info, IntPtr arg) (__SubscriptionBuiltinTopicData) Marshal.PtrToStructure(info, typeof(__SubscriptionBuiltinTopicData)); GCHandle argGCHandle = GCHandle.FromIntPtr(arg); SubscriptionBuiltinTopicData to = argGCHandle.Target as SubscriptionBuiltinTopicData; - SubscriptionBuiltinTopicDataMarshaler.CopyOut(ref nativeImage, ref to); + __SubscriptionBuiltinTopicDataMarshaler.CopyOut(ref nativeImage, ref to); argGCHandle.Target = to; return V_RESULT.OK; } diff --git a/src/api/dcps/sacs/code/DDS/OpenSplice/Database/DDSDatabase.cs b/src/api/dcps/sacs/code/DDS/OpenSplice/Database/DDSDatabase.cs index db71e9b95..af5df4c15 100644 --- a/src/api/dcps/sacs/code/DDS/OpenSplice/Database/DDSDatabase.cs +++ b/src/api/dcps/sacs/code/DDS/OpenSplice/Database/DDSDatabase.cs @@ -1,8 +1,9 @@ -/* - * OpenSplice DDS +/* + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/dcps/sacs/code/DDS/OpenSplice/Docs/Typed.cs b/src/api/dcps/sacs/code/DDS/OpenSplice/Docs/Typed.cs index 12cfb6a35..3246c1ed5 100644 --- a/src/api/dcps/sacs/code/DDS/OpenSplice/Docs/Typed.cs +++ b/src/api/dcps/sacs/code/DDS/OpenSplice/Docs/Typed.cs @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/dcps/sacs/code/DDS/OpenSplice/DomainParticipant.cs b/src/api/dcps/sacs/code/DDS/OpenSplice/DomainParticipant.cs index 5d9454c43..1b15c587c 100644 --- a/src/api/dcps/sacs/code/DDS/OpenSplice/DomainParticipant.cs +++ b/src/api/dcps/sacs/code/DDS/OpenSplice/DomainParticipant.cs @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -66,8 +67,8 @@ public BuiltinTopicProperties(DDS.OpenSplice.TypeSupport ts, string tn) private const int DCPS_PARTICIPANT_INDEX = 0; private const int DCPS_TOPIC_INDEX = 1; - private ParticipantBuiltinTopicDataMarshaler ParticipantDataMarshaler; - private TopicBuiltinTopicDataMarshaler TopicDataMarshaler; + private __ParticipantBuiltinTopicDataMarshaler ParticipantDataMarshaler; + private __TopicBuiltinTopicDataMarshaler TopicDataMarshaler; private PublisherQos defaultPublisherQos = new PublisherQos(); private SubscriberQos defaultSubscriberQos = new SubscriberQos(); private TopicQos defaultTopicQos = new TopicQos(); @@ -255,7 +256,7 @@ internal ReturnCode nlReq_LoadTypeSupport(TypeSupport ts, string typeName) { V_RESULT uResult = User.Domain.LoadXmlDescriptor (uDomain, descriptor); result = uResultToReturnCode (uResult); - if (result != DDS.ReturnCode.Ok) + if (result != DDS.ReturnCode.Ok) { ReportStack.Report(result, "Given type \"" + typeName + "\" is incompatible with an already registered type using the same name."); } @@ -360,12 +361,12 @@ internal ReturnCode CreateBuiltinTopics() if (result == DDS.ReturnCode.Ok) { this.ParticipantDataMarshaler = DatabaseMarshaler.GetMarshaler( - this, osplBuiltinTopics[DCPS_PARTICIPANT_INDEX].typeSupport.TypeSpec) as ParticipantBuiltinTopicDataMarshaler; + this, osplBuiltinTopics[DCPS_PARTICIPANT_INDEX].typeSupport.TypeSpec) as __ParticipantBuiltinTopicDataMarshaler; } if (result == DDS.ReturnCode.Ok) { this.TopicDataMarshaler = DatabaseMarshaler.GetMarshaler( - this, osplBuiltinTopics[DCPS_TOPIC_INDEX].typeSupport.TypeSpec) as TopicBuiltinTopicDataMarshaler; + this, osplBuiltinTopics[DCPS_TOPIC_INDEX].typeSupport.TypeSpec) as __TopicBuiltinTopicDataMarshaler; } return result; @@ -695,7 +696,9 @@ public ISubscriber CreateSubscriber(SubscriberQos qos, ISubscriberListener liste if (result == ReturnCode.Ok) { subscriberList.Add(subscriber); - if (rlReq_AutoEnableCreatedEntities) + if (rlReq_AutoEnableCreatedEntities && + !(qos.Presentation.CoherentAccess && + qos.Presentation.AccessScope == PresentationQosPolicyAccessScopeKind.GroupPresentationQos)) { result = subscriber.Enable(); } @@ -1560,6 +1563,33 @@ public ReturnCode SetQos(DomainParticipantQos qos) return result; } + public ReturnCode GetProperty(ref Property property) + { + IntPtr Value = IntPtr.Zero; + + ReturnCode result = DDS.ReturnCode.Unsupported; + result = checkProperty(ref property); + if (result == DDS.ReturnCode.Ok) { + IntPtr uDomain = User.DomainParticipant.Domain(rlReq_UserPeer); + result = uResultToReturnCode(User.Entity.GetProperty(uDomain, property.Name, ref Value)); + if (Value != IntPtr.Zero) { + property.Value = Marshal.PtrToStringAnsi(Value); + } + } + return result; + } + + public ReturnCode SetProperty(Property property) + { + ReturnCode result = DDS.ReturnCode.Unsupported; + result = checkProperty(ref property); + if (result == DDS.ReturnCode.Ok) { + IntPtr uDomain = User.DomainParticipant.Domain(rlReq_UserPeer); + result = uResultToReturnCode(User.Entity.SetProperty(uDomain, property.Name, property.Value)); + } + return result; + } + public ReturnCode GetQos(ref DomainParticipantQos qos) { ReturnCode result = DDS.ReturnCode.AlreadyDeleted; diff --git a/src/api/dcps/sacs/code/DDS/OpenSplice/Entity.cs b/src/api/dcps/sacs/code/DDS/OpenSplice/Entity.cs index 3633df305..2f8840876 100644 --- a/src/api/dcps/sacs/code/DDS/OpenSplice/Entity.cs +++ b/src/api/dcps/sacs/code/DDS/OpenSplice/Entity.cs @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -48,6 +49,17 @@ internal Entity() { } + internal ReturnCode checkProperty(ref Property prop) + { + ReturnCode result = DDS.ReturnCode.Ok; + if (prop.Name == null) { + result = DDS.ReturnCode.BadParameter; + } else if (prop.Value == null) { + result = DDS.ReturnCode.BadParameter; + } + return result; + } + internal ReturnCode init(IntPtr userPtr) { ReturnCode result = base.init(userPtr, false); @@ -185,6 +197,16 @@ public ReturnCode Enable() return result; } + public bool IsEnabled() + { + byte state = User.Entity.Enabled(rlReq_UserPeer); + if (state != 0) { + return true; + } else { + return false; + } + } + public IStatusCondition StatusCondition { get @@ -269,7 +291,7 @@ internal void WaitListenerRemoved() { while (wait && wakeCount < 4) { - /* OSPL-6164 Made wait use a timeout in order to be able to detect + /* Made wait use a timeout in order to be able to detect * a race where sometimes the wait() doesn't return (missed event?). */ Monitor.Wait(this, 250); if (wait) diff --git a/src/api/dcps/sacs/code/DDS/OpenSplice/FooDataReader.cs b/src/api/dcps/sacs/code/DDS/OpenSplice/FooDataReader.cs index c057d3909..dc7fdb51a 100644 --- a/src/api/dcps/sacs/code/DDS/OpenSplice/FooDataReader.cs +++ b/src/api/dcps/sacs/code/DDS/OpenSplice/FooDataReader.cs @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -262,7 +263,7 @@ internal int RealMaxSamples(T[] data, int maxSamples) { result = ReaderCopy(sampleList, ref data, ref sampleInfos); } - + Common.SampleList.Free(sampleList); } ReportStack.Flush(this, (result != ReturnCode.Ok)&&(result != ReturnCode.NoData)); @@ -809,7 +810,7 @@ internal int RealMaxSamples(T[] data, int maxSamples) key = keyHandle.Target as T; keyHandle.Free(); ReportStack.Flush(this, result != ReturnCode.Ok); - + return result; } @@ -829,7 +830,7 @@ internal int RealMaxSamples(T[] data, int maxSamples) handle = uHandle; keyHandle.Free(); ReportStack.Flush(this, result != ReturnCode.Ok); - + return handle; } } diff --git a/src/api/dcps/sacs/code/DDS/OpenSplice/FooDataWriter.cs b/src/api/dcps/sacs/code/DDS/OpenSplice/FooDataWriter.cs index d9c22793c..cfdd47eb9 100644 --- a/src/api/dcps/sacs/code/DDS/OpenSplice/FooDataWriter.cs +++ b/src/api/dcps/sacs/code/DDS/OpenSplice/FooDataWriter.cs @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -42,7 +43,7 @@ public FooDataWriter(DatabaseMarshaler marshaler) { ReturnCode result = DDS.ReturnCode.BadParameter; InstanceHandle handle = DDS.InstanceHandle.Nil; - + ReportStack.Start(); if ((sourceTimestamp == Time.Current) || (QosManager.countErrors(sourceTimestamp) == 0)) { diff --git a/src/api/dcps/sacs/code/DDS/OpenSplice/Kernel/DDSKernel.cs b/src/api/dcps/sacs/code/DDS/OpenSplice/Kernel/DDSKernel.cs index e50e77d32..760921d16 100644 --- a/src/api/dcps/sacs/code/DDS/OpenSplice/Kernel/DDSKernel.cs +++ b/src/api/dcps/sacs/code/DDS/OpenSplice/Kernel/DDSKernel.cs @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,7 +25,7 @@ namespace DDS.OpenSplice.Kernel { - enum V_RESULT { + public enum V_RESULT { UNDEFINED = (3 << 8), OK, INTERRUPTED, diff --git a/src/api/dcps/sacs/code/DDS/OpenSplice/ListenerDispatcher.cs b/src/api/dcps/sacs/code/DDS/OpenSplice/ListenerDispatcher.cs index 599133123..af776aaf9 100644 --- a/src/api/dcps/sacs/code/DDS/OpenSplice/ListenerDispatcher.cs +++ b/src/api/dcps/sacs/code/DDS/OpenSplice/ListenerDispatcher.cs @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/dcps/sacs/code/DDS/OpenSplice/MultiTopic.cs b/src/api/dcps/sacs/code/DDS/OpenSplice/MultiTopic.cs index 377b26523..3b221a15c 100644 --- a/src/api/dcps/sacs/code/DDS/OpenSplice/MultiTopic.cs +++ b/src/api/dcps/sacs/code/DDS/OpenSplice/MultiTopic.cs @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,7 +25,7 @@ using DDS.OpenSplice.CustomMarshalers; namespace DDS.OpenSplice -{ +{ internal class MultiTopic : SacsSuperClass, ITopicDescriptionImpl, IMultiTopic { private DomainParticipant domainParticipant; @@ -35,13 +36,13 @@ internal class MultiTopic : SacsSuperClass, ITopicDescriptionImpl, IMultiTopic private string[] subscriptionParameters; private uint nrUsers = 0; private ITopicDescriptionImpl[] relatedTopics = new ITopicDescriptionImpl[0]; - + internal MultiTopic( string typeName, string topicName, DomainParticipant domainParticipant, TypeSupport typeSupport, - string subscriptionExpression, + string subscriptionExpression, string[] subscriptionParameters) { this.typeName = typeName; @@ -52,14 +53,13 @@ internal class MultiTopic : SacsSuperClass, ITopicDescriptionImpl, IMultiTopic this.subscriptionParameters = subscriptionParameters; MyDomainId = domainParticipant.MyDomainId; } - + internal ReturnCode init() { ReturnCode result; - + result = DDS.ReturnCode.Unsupported; // Try to obtain the list of related topics. - //relatedTopics = getRelatedTopics(); for (int i = 0; i < relatedTopics.Length && result == DDS.ReturnCode.Ok; i++) { ITopicDescriptionImpl t = relatedTopics[i]; @@ -90,14 +90,14 @@ internal ReturnCode init() { result = DDS.ReturnCode.Error; } - } + } return result; } - + internal override ReturnCode wlReq_deinit() { ReturnCode result; - + if (nrUsers > 0) { result = DDS.ReturnCode.PreconditionNotMet; @@ -113,9 +113,9 @@ internal override ReturnCode wlReq_deinit() } return result; } - + /// - /// This property returns the registered name of the data type associated with the TopicDescription + /// This property returns the registered name of the data type associated with the TopicDescription /// (inherited from TopicDescription) /// public string TypeName @@ -167,7 +167,7 @@ public string Name } /// - /// This property returns the DomainParticipant associated with the TopicDescription or + /// This property returns the DomainParticipant associated with the TopicDescription or /// a null DomainParticipant. /// (inherited from TopicDescription) /// @@ -192,7 +192,7 @@ public IDomainParticipant Participant return participant; } } - + public string SubscriptionExpression { get @@ -214,7 +214,7 @@ public string SubscriptionExpression return sexpr; } } - + public ReturnCode GetExpressionParameters(ref string[] expressionParameters) { expressionParameters = null; @@ -233,11 +233,11 @@ public ReturnCode GetExpressionParameters(ref string[] expressionParameters) return result; } - + public ReturnCode SetExpressionParameters(params string[] expressionParameters) { ReturnCode result = DDS.ReturnCode.Unsupported; - + // using (SequenceStringToArrMarshaler marshaler = new SequenceStringToArrMarshaler()) // { // result = WriteLock(); @@ -259,7 +259,7 @@ public ReturnCode SetExpressionParameters(params string[] expressionParameters) return result; } - + string ITopicDescriptionImpl.rlReq_TopicExpression { get @@ -267,7 +267,7 @@ string ITopicDescriptionImpl.rlReq_TopicExpression return subscriptionExpression; } } - + string[] ITopicDescriptionImpl.rlReq_TopicExpressionParameters { get @@ -275,7 +275,7 @@ string[] ITopicDescriptionImpl.rlReq_TopicExpressionParameters return subscriptionParameters; } } - + void ITopicDescriptionImpl.wlReq_IncrNrUsers() { nrUsers++; diff --git a/src/api/dcps/sacs/code/DDS/OpenSplice/OS/OsLayer.cs b/src/api/dcps/sacs/code/DDS/OpenSplice/OS/OsLayer.cs index af7a521f7..c6ce1d45e 100644 --- a/src/api/dcps/sacs/code/DDS/OpenSplice/OS/OsLayer.cs +++ b/src/api/dcps/sacs/code/DDS/OpenSplice/OS/OsLayer.cs @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -65,7 +66,10 @@ static internal class os string fileName, int lineNo, DDS.ReturnCode reportCode, - string description); + int domainId, + bool stack, + string description, + IntPtr args); public static void report( ReportType type, @@ -80,7 +84,10 @@ static internal class os fileName, callStack.GetFileLineNumber(), reportCode, - description); + -1, + true, + description, + IntPtr.Zero); } } } diff --git a/src/api/dcps/sacs/code/DDS/OpenSplice/OS/Report.cs b/src/api/dcps/sacs/code/DDS/OpenSplice/OS/Report.cs index 50b12eff6..e5db67d33 100644 --- a/src/api/dcps/sacs/code/DDS/OpenSplice/OS/Report.cs +++ b/src/api/dcps/sacs/code/DDS/OpenSplice/OS/Report.cs @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/dcps/sacs/code/DDS/OpenSplice/Publisher.cs b/src/api/dcps/sacs/code/DDS/OpenSplice/Publisher.cs index 6ecce7b75..6428b9ec5 100644 --- a/src/api/dcps/sacs/code/DDS/OpenSplice/Publisher.cs +++ b/src/api/dcps/sacs/code/DDS/OpenSplice/Publisher.cs @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/dcps/sacs/code/DDS/OpenSplice/QosManager.cs b/src/api/dcps/sacs/code/DDS/OpenSplice/QosManager.cs index 99ca06ca5..dee32591b 100644 --- a/src/api/dcps/sacs/code/DDS/OpenSplice/QosManager.cs +++ b/src/api/dcps/sacs/code/DDS/OpenSplice/QosManager.cs @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -252,7 +253,7 @@ internal static int countErrors(Time o) int errorCount = 0; if (o.Sec < 0 || o.NanoSec > 1000000000) { - if (o != Time.Invalid) + if (o != Time.Invalid) { errorCount++; ReportStack.Report(DDS.ReturnCode.BadParameter, "Time { " + o.Sec + ", " + o.NanoSec + "} is not properly normalized"); @@ -450,6 +451,13 @@ internal static int countErrors(ResourceLimitsQosPolicy o) { errorCount++; } + if (o.MaxSamples != Length.Unlimited && + o.MaxSamplesPerInstance != Length.Unlimited && + o.MaxSamples < o.MaxSamplesPerInstance) + { + errorCount++; + } + return errorCount; } @@ -715,7 +723,7 @@ internal static ReturnCode checkQos(DataReaderQos o) { ReportStack.Report(result, "ReaderDataLifecycle.InvalidSampleVisibility.kind 'ALL_INVALID_SAMPLES' is unsupported."); - result = DDS.ReturnCode.Unsupported; // See OSPL-433 + result = DDS.ReturnCode.Unsupported; // See CYCL-15 } } } else { diff --git a/src/api/dcps/sacs/code/DDS/OpenSplice/QueryCondition.cs b/src/api/dcps/sacs/code/DDS/OpenSplice/QueryCondition.cs index 476b3cab9..577c20731 100644 --- a/src/api/dcps/sacs/code/DDS/OpenSplice/QueryCondition.cs +++ b/src/api/dcps/sacs/code/DDS/OpenSplice/QueryCondition.cs @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -37,13 +38,13 @@ internal class QueryCondition : ReadCondition, IQueryCondition { private string queryExpression; private string[] queryParameters; - + internal QueryCondition( DataReader dataReader, - SampleStateKind sampleState, - ViewStateKind viewState, - InstanceStateKind instanceState, - string queryExpression, + SampleStateKind sampleState, + ViewStateKind viewState, + InstanceStateKind instanceState, + string queryExpression, string[] queryParameters) : base(dataReader, sampleState, viewState, instanceState) { @@ -55,7 +56,7 @@ internal override ReturnCode init(IntPtr query) { return base.init(query); } - + /// /// This operation returns the query expression associated with the QueryCondition. /// @@ -82,7 +83,7 @@ public string GetQueryExpression() /// /// This operation obtains the queryParameters associated with the QueryCondition /// - /// A reference to a sequence of strings that will be + /// A reference to a sequence of strings that will be /// used to store the parameters used in the SQL expression /// Return codes are:Ok,Error,AlreadyDeleted or OutOfResources. public ReturnCode GetQueryParameters(ref string[] queryParameters) @@ -142,25 +143,25 @@ public ReturnCode SetQueryParameters(params string[] queryParameters) ReportStack.Flush(this, result != ReturnCode.Ok); return result; } - + internal override ReturnCode Read(IntPtr sampleList) { return uResultToReturnCode( User.Query.Read(rlReq_UserPeer, Common.SampleList.ReaderAction, sampleList, DDS.Duration.Zero.OsDuration)); } - + internal override ReturnCode Take(IntPtr sampleList) { return uResultToReturnCode( User.Query.Take(rlReq_UserPeer, Common.SampleList.ReaderAction, sampleList, DDS.Duration.Zero.OsDuration)); } - + internal override ReturnCode ReadNextInstance(InstanceHandle handle, IntPtr sampleList) { return uResultToReturnCode( User.Query.ReadNextInstance(rlReq_UserPeer, handle, Common.SampleList.ReaderAction, sampleList, DDS.Duration.Zero.OsDuration)); } - + internal override ReturnCode TakeNextInstance(InstanceHandle handle, IntPtr sampleList) { return uResultToReturnCode( diff --git a/src/api/dcps/sacs/code/DDS/OpenSplice/ReadCondition.cs b/src/api/dcps/sacs/code/DDS/OpenSplice/ReadCondition.cs index c969097c6..ca44ba0e8 100644 --- a/src/api/dcps/sacs/code/DDS/OpenSplice/ReadCondition.cs +++ b/src/api/dcps/sacs/code/DDS/OpenSplice/ReadCondition.cs @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/dcps/sacs/code/DDS/OpenSplice/ReportStack.cs b/src/api/dcps/sacs/code/DDS/OpenSplice/ReportStack.cs index 6527c6422..40e4ba4d1 100644 --- a/src/api/dcps/sacs/code/DDS/OpenSplice/ReportStack.cs +++ b/src/api/dcps/sacs/code/DDS/OpenSplice/ReportStack.cs @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,6 +20,7 @@ using DDS; using DDS.OpenSplice.OS; +using System; using System.Diagnostics; using System.Runtime.InteropServices; @@ -93,6 +95,11 @@ private static string getFileName(StackFrame errorFrame) return fileName; } + internal static void Start() + { + Start(null, 0, null, IntPtr.Zero); + } + internal static void Flush(SacsSuperClass obj, bool valid) { if (FlushRequired(valid) != 0) { @@ -115,6 +122,7 @@ internal static void Report(DDS.ReturnCode returnCode, string description) getFileName(callStack), callStack.GetFileLineNumber(), returnCode, + -1, true, GetReturnCodePrefix(returnCode) + description); } @@ -128,6 +136,7 @@ internal static void Deprecated(string description) getFileName(callStack), callStack.GetFileLineNumber(), DDS.ReturnCode.Ok, + -1, true, description); } @@ -141,20 +150,21 @@ internal static void Warning(string description) getFileName(callStack), callStack.GetFileLineNumber(), DDS.ReturnCode.Ok, + -1, true, description); } - [DllImport("ddskernel", EntryPoint = "os_report_stack", CallingConvention = CallingConvention.Cdecl)] - internal static extern void Start(); + [DllImport("ddskernel", EntryPoint = "os_report_stack_open", CallingConvention = CallingConvention.Cdecl)] + internal static extern void Start(string fileName, int lineNumber, string signature, IntPtr userInfo); - [DllImport("ddskernel", EntryPoint = "os_report_stack_unwind", CallingConvention = CallingConvention.Cdecl)] + [DllImport("ddskernel", EntryPoint = "os_report_flush", CallingConvention = CallingConvention.Cdecl)] internal static extern void Flush(bool valid, string reportContext, string fileName, int lineNumber, int domainId); [DllImport("ddskernel", EntryPoint = "os_report", CallingConvention = CallingConvention.Cdecl)] - internal static extern void Report(ReportType type, string reportContext, string fileName, int lineNo, DDS.ReturnCode reportCode, string description); + internal static extern void Report(ReportType type, string reportContext, string fileName, int lineNo, DDS.ReturnCode reportCode, int domainId, bool stack, string description); - [DllImport("ddskernel", EntryPoint = "os_report_stack_flush_required", CallingConvention = CallingConvention.Cdecl)] + [DllImport("ddskernel", EntryPoint = "os_report_status", CallingConvention = CallingConvention.Cdecl)] internal static extern int FlushRequired(bool valid); } } diff --git a/src/api/dcps/sacs/code/DDS/OpenSplice/SacsSuperClass.cs b/src/api/dcps/sacs/code/DDS/OpenSplice/SacsSuperClass.cs index 079cb9a9e..564bb2aa8 100644 --- a/src/api/dcps/sacs/code/DDS/OpenSplice/SacsSuperClass.cs +++ b/src/api/dcps/sacs/code/DDS/OpenSplice/SacsSuperClass.cs @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,10 +27,10 @@ namespace DDS.OpenSplice { /** - * This interface is implemented by all DDS defined classes and holds the - * adress of the equivalent gapi object. The adress is stored as - * a (platform-dependent) int because the gapi can - * be compiled for any platform using up to 64 bit adressing. + * This interface is implemented by all DDS defined classes and holds the + * adress of the equivalent gapi object. The adress is stored as + * a (platform-dependent) int because the gapi can + * be compiled for any platform using up to 64 bit adressing. */ public class SacsSuperClass : IDisposable { @@ -37,20 +38,20 @@ public class SacsSuperClass : IDisposable private bool deinitialized = false; /** - * The adress of the equivalent object in the gapi + * The adress of the equivalent object in the gapi */ private IntPtr userPeer = IntPtr.Zero; - internal IntPtr rlReq_UserPeer { get { return userPeer; } } + public IntPtr rlReq_UserPeer { get { return userPeer; } } private IntPtr handleSelf = IntPtr.Zero; internal IntPtr rlReq_HandleSelf { get { return handleSelf; } } - /* This constructor is only used by all DDS classes that have a + /* This constructor is only used by all DDS classes that have a * default constructor (i.e. TypeSupport, WaitSet, GuardCondition). * It is due to the fact that the Gapi..alloc() needs to * be called in order to get a gapi handle, but this cannot be done - * in the constructor in this stage. + * in the constructor in this stage. * The caller must call SetPeer and pass the gapi handle as soon as * he has obtained it. */ @@ -58,7 +59,7 @@ internal SacsSuperClass() { } - /* + /* * Use C# destructor syntax for finalization code. * Note that this finalizer is only invoked when not yet suppressed by * an invocation of GC.SuppressFinalize(). @@ -78,10 +79,10 @@ internal SacsSuperClass() } /* This operation assumes it is invoked by the init() operations - * of each of its children. Since an object is not yet accessable + * of each of its children. Since an object is not yet accessable * before finalization of its init(), no lock is required to set * the address of the UserLayer object which it represents. - * Weak Objects are objects that do not leave a pinned backref to + * Weak Objects are objects that do not leave a pinned backref to * their C# wrappers in the UserLayer administration, since that * would prevent an object from becoming garbage collected when * there is no explicit API call to do so. Examples of objects @@ -103,7 +104,7 @@ internal virtual ReturnCode init(IntPtr userPtr, bool isWeak) { backRefType = GCHandleType.Normal; } - + // Get the GCHandle for the current C# object and cache the IntPtr of the GCHandle // in the UserData field of its gapi pointer. GCHandle tmpGCHandle = GCHandle.Alloc(this, backRefType); @@ -111,10 +112,10 @@ internal virtual ReturnCode init(IntPtr userPtr, bool isWeak) // Store the handle in the object itself. userPeer = userPtr; - + return DDS.ReturnCode.Ok; } - + /** * deinit() takes care of all deinitilization by invoking a virtual wlReq_deinit() call * that will be overridden by each child and that will be recursively traversed upward. @@ -122,22 +123,22 @@ internal virtual ReturnCode init(IntPtr userPtr, bool isWeak) internal ReturnCode deinit() { ReturnCode result = DDS.ReturnCode.AlreadyDeleted; - - lock(this) + + lock(this) { if (this.rlReq_isAlive) { result = wlReq_deinit(); } } - + return result; } internal virtual ReturnCode wlReq_deinit() { ReturnCode result = DDS.ReturnCode.Ok; - - // Weak references are slaved to their wrappers lifecycle. + + // Weak references are slaved to their wrappers lifecycle. // So if the wrapper is disposed, so should the corresponding // UserLayer handle. deinitialized = true; @@ -153,18 +154,18 @@ internal virtual ReturnCode wlReq_deinit() // Make sure that Dispose() is not invoked a 2nd time by the destructor/finalizer. GC.SuppressFinalize(this); - + return result; } - - /* Using the Dispose/Finalize pattern from: + + /* Using the Dispose/Finalize pattern from: * http://msdn.microsoft.com/en-us/library/b1yfkh5e(vs.71).aspx */ public void Dispose() { deinit(); } - + private int _MyDomainId = -1; public int MyDomainId { @@ -178,17 +179,17 @@ internal bool rlReq_isAlive get { bool result = true; - + if (deinitialized) { result = false; ReportStack.Report( - DDS.ReturnCode.AlreadyDeleted, + DDS.ReturnCode.AlreadyDeleted, "Trying to invoke an operation on an already deleted OpenSplice object."); } return result; } } - + internal static SacsSuperClass fromUserData(IntPtr userPtr) { SacsSuperClass entity = null; @@ -210,7 +211,7 @@ internal static SacsSuperClass fromUserData(IntPtr userPtr) return entity; } - + internal static DDS.ReturnCode uResultToReturnCode(V_RESULT uResult) { DDS.ReturnCode result; diff --git a/src/api/dcps/sacs/code/DDS/OpenSplice/Subscriber.cs b/src/api/dcps/sacs/code/DDS/OpenSplice/Subscriber.cs index 472bb6bfc..79d574a06 100644 --- a/src/api/dcps/sacs/code/DDS/OpenSplice/Subscriber.cs +++ b/src/api/dcps/sacs/code/DDS/OpenSplice/Subscriber.cs @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -63,7 +64,7 @@ internal ReturnCode init(DomainParticipant participant, string name, SubscriberQ result = marshaler.CopyIn(qos); if (result == ReturnCode.Ok) { - IntPtr uSubscriber = User.Subscriber.New(participant.rlReq_UserPeer, name, marshaler.UserPtr, 0); + IntPtr uSubscriber = User.Subscriber.New(participant.rlReq_UserPeer, name, marshaler.UserPtr); if (uSubscriber != IntPtr.Zero) { result = base.init(uSubscriber); @@ -321,7 +322,7 @@ public IDataReader CreateDataReader(ITopicDescription topic, DataReaderQos qos) if (result == DDS.ReturnCode.Ok) { readerList.Add(dataReader); - if (rlReq_AutoEnableCreatedEntities) + if (rlReq_AutoEnableCreatedEntities && this.IsEnabled()) { result = dataReader.Enable(); } diff --git a/src/api/dcps/sacs/code/DDS/OpenSplice/Topic.cs b/src/api/dcps/sacs/code/DDS/OpenSplice/Topic.cs index 42fee8ad6..e16e913b5 100644 --- a/src/api/dcps/sacs/code/DDS/OpenSplice/Topic.cs +++ b/src/api/dcps/sacs/code/DDS/OpenSplice/Topic.cs @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -32,7 +33,6 @@ namespace DDS.OpenSplice { internal class Topic : Entity, ITopic, ITopicDescriptionImpl { -// private readonly TopicListenerHelper listenerHelper; private DomainParticipant domainParticipant; private TypeSupport typeSupport; private string topicName; @@ -194,7 +194,7 @@ internal ReturnCode ValidateFilter(string filterExpression, string[] filterParam if (qExpr != IntPtr.Zero) { - if (User.Topic.ContentFilterValidate2(rlReq_UserPeer, qExpr, qParams) != 0) + if (User.Topic.ContentFilterValidate2(rlReq_UserPeer, qExpr, qParams, Convert.ToUInt32(length)) != 0) { result = DDS.ReturnCode.Ok; } diff --git a/src/api/dcps/sacs/code/DDS/OpenSplice/TopicDescription.cs b/src/api/dcps/sacs/code/DDS/OpenSplice/TopicDescription.cs index 5011701c2..aabf19124 100644 --- a/src/api/dcps/sacs/code/DDS/OpenSplice/TopicDescription.cs +++ b/src/api/dcps/sacs/code/DDS/OpenSplice/TopicDescription.cs @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,16 +30,16 @@ string rlReq_TopicExpression { get; } - + string[] rlReq_TopicExpressionParameters { get; } - + // Mostly invoked when lock is already ackquired. void wlReq_IncrNrUsers(); - // Mostly invoked when lock is not yet ackquired. + // Mostly invoked when lock is not yet ackquired. ReturnCode DecrNrUsers(); TypeSupport rlReq_TypeSupport diff --git a/src/api/dcps/sacs/code/DDS/OpenSplice/TypeSupport.cs b/src/api/dcps/sacs/code/DDS/OpenSplice/TypeSupport.cs index c1ed096d2..47791ca8d 100644 --- a/src/api/dcps/sacs/code/DDS/OpenSplice/TypeSupport.cs +++ b/src/api/dcps/sacs/code/DDS/OpenSplice/TypeSupport.cs @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -32,7 +33,7 @@ public abstract class TypeSupport : ITypeSupport private string internalTypeName; private string keyList; private Type dataType; - + public Type TypeSpec { get @@ -48,7 +49,7 @@ public string TypeName return typeName; } } - + public string InternalTypeName { get @@ -57,8 +58,8 @@ public string InternalTypeName } } - public string TypeDescriptor - { + public string TypeDescriptor + { get { return typeDescriptor; @@ -73,7 +74,7 @@ public string KeyList return keyList; } } - + /* * Constructor for a TypeSupport that uses the specified (custom) Marshaler. @@ -84,9 +85,9 @@ public TypeSupport(Type dataType, string[] descriptorArr, string typeName, strin this.typeName = typeName; this.internalTypeName = (internalTypeName.Length > 0) ? internalTypeName : typeName; this.keyList = keyList; - + System.Text.StringBuilder descriptor = new System.Text.StringBuilder(); - foreach (string s in descriptorArr) + foreach (string s in descriptorArr) { descriptor.Append(s); } @@ -117,7 +118,7 @@ public TypeSupport(Type dataType, string[] descriptorArr, string typeName, strin } else { dp = participant as DomainParticipant; if (dp == null) { - ReportStack.Report (result, "domain is invalid, not of type " + + ReportStack.Report (result, "domain is invalid, not of type " + "DDS::OpenSplice::DomainParticipant"); } else { if (typeName == null) { diff --git a/src/api/dcps/sacs/code/DDS/OpenSplice/User/DataReader.cs b/src/api/dcps/sacs/code/DDS/OpenSplice/User/DataReader.cs index 36468a193..7fff27461 100644 --- a/src/api/dcps/sacs/code/DDS/OpenSplice/User/DataReader.cs +++ b/src/api/dcps/sacs/code/DDS/OpenSplice/User/DataReader.cs @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -34,8 +35,8 @@ internal class DataReader * const os_char *name, * const q_expr OQLexpr, * const c_value params[], - * const u_readerQos qos, - * u_bool enable); + * os_uint32 nrOfParams, + * const u_readerQos qos); */ [DllImport("ddskernel", EntryPoint = "u_dataReaderNew", CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr New( @@ -43,8 +44,8 @@ internal class DataReader string name, IntPtr OQLexpr, IntPtr _params, - IntPtr qos, - byte enable); + uint nrOfParams, + IntPtr qos); /* * u_dataReader @@ -62,8 +63,8 @@ internal class DataReader string name, string expr, IntPtr _params, - IntPtr qos, - byte enable); + uint nrOfParams, + IntPtr qos); /* * u_result diff --git a/src/api/dcps/sacs/code/DDS/OpenSplice/User/Domain.cs b/src/api/dcps/sacs/code/DDS/OpenSplice/User/Domain.cs index f9ee939a5..ef01b1c49 100644 --- a/src/api/dcps/sacs/code/DDS/OpenSplice/User/Domain.cs +++ b/src/api/dcps/sacs/code/DDS/OpenSplice/User/Domain.cs @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -51,5 +52,7 @@ internal static class Domain string partitionExpression, string topicExpression, string uri); + } + } diff --git a/src/api/dcps/sacs/code/DDS/OpenSplice/User/DomainParticipant.cs b/src/api/dcps/sacs/code/DDS/OpenSplice/User/DomainParticipant.cs index 83c7314ce..a9afb9884 100644 --- a/src/api/dcps/sacs/code/DDS/OpenSplice/User/DomainParticipant.cs +++ b/src/api/dcps/sacs/code/DDS/OpenSplice/User/DomainParticipant.cs @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/dcps/sacs/code/DDS/OpenSplice/User/Entity.cs b/src/api/dcps/sacs/code/DDS/OpenSplice/User/Entity.cs index 5b71b06e9..096dabf1c 100644 --- a/src/api/dcps/sacs/code/DDS/OpenSplice/User/Entity.cs +++ b/src/api/dcps/sacs/code/DDS/OpenSplice/User/Entity.cs @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -161,5 +162,17 @@ static internal class Entity public static extern byte DisableCallbacks( IntPtr _this); + [DllImport("ddskernel", EntryPoint = "u_entityGetProperty", CallingConvention = CallingConvention.Cdecl)] + public static extern V_RESULT GetProperty( + IntPtr _this, + string name, + ref IntPtr value); + + [DllImport("ddskernel", EntryPoint = "u_entitySetProperty", CallingConvention = CallingConvention.Cdecl)] + public static extern V_RESULT SetProperty( + IntPtr _this, + string name, + string value); + } } diff --git a/src/api/dcps/sacs/code/DDS/OpenSplice/User/InstanceHandle.cs b/src/api/dcps/sacs/code/DDS/OpenSplice/User/InstanceHandle.cs index 4842d26df..464097161 100644 --- a/src/api/dcps/sacs/code/DDS/OpenSplice/User/InstanceHandle.cs +++ b/src/api/dcps/sacs/code/DDS/OpenSplice/User/InstanceHandle.cs @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/dcps/sacs/code/DDS/OpenSplice/User/Listener.cs b/src/api/dcps/sacs/code/DDS/OpenSplice/User/Listener.cs index b6ebf18a8..fc3e66bd7 100644 --- a/src/api/dcps/sacs/code/DDS/OpenSplice/User/Listener.cs +++ b/src/api/dcps/sacs/code/DDS/OpenSplice/User/Listener.cs @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/dcps/sacs/code/DDS/OpenSplice/User/Object.cs b/src/api/dcps/sacs/code/DDS/OpenSplice/User/Object.cs index a7af14876..d23c93fab 100644 --- a/src/api/dcps/sacs/code/DDS/OpenSplice/User/Object.cs +++ b/src/api/dcps/sacs/code/DDS/OpenSplice/User/Object.cs @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/dcps/sacs/code/DDS/OpenSplice/User/Observable.cs b/src/api/dcps/sacs/code/DDS/OpenSplice/User/Observable.cs index e43a7c1a0..42f549430 100644 --- a/src/api/dcps/sacs/code/DDS/OpenSplice/User/Observable.cs +++ b/src/api/dcps/sacs/code/DDS/OpenSplice/User/Observable.cs @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,7 +27,7 @@ namespace DDS.OpenSplice.User [UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate void observableActionFn(IntPtr p, IntPtr arg); - class Observable + public class Observable { /* * void * diff --git a/src/api/dcps/sacs/code/DDS/OpenSplice/User/Publisher.cs b/src/api/dcps/sacs/code/DDS/OpenSplice/User/Publisher.cs index 4dd680f8c..88d7a5251 100644 --- a/src/api/dcps/sacs/code/DDS/OpenSplice/User/Publisher.cs +++ b/src/api/dcps/sacs/code/DDS/OpenSplice/User/Publisher.cs @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/dcps/sacs/code/DDS/OpenSplice/User/QosManagement.cs b/src/api/dcps/sacs/code/DDS/OpenSplice/User/QosManagement.cs index 6b18a2942..62c14fdca 100644 --- a/src/api/dcps/sacs/code/DDS/OpenSplice/User/QosManagement.cs +++ b/src/api/dcps/sacs/code/DDS/OpenSplice/User/QosManagement.cs @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/dcps/sacs/code/DDS/OpenSplice/User/Query.cs b/src/api/dcps/sacs/code/DDS/OpenSplice/User/Query.cs index 682462cf9..7a77e4585 100644 --- a/src/api/dcps/sacs/code/DDS/OpenSplice/User/Query.cs +++ b/src/api/dcps/sacs/code/DDS/OpenSplice/User/Query.cs @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/dcps/sacs/code/DDS/OpenSplice/User/Reader.cs b/src/api/dcps/sacs/code/DDS/OpenSplice/User/Reader.cs index 00700492a..99c965f91 100644 --- a/src/api/dcps/sacs/code/DDS/OpenSplice/User/Reader.cs +++ b/src/api/dcps/sacs/code/DDS/OpenSplice/User/Reader.cs @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/dcps/sacs/code/DDS/OpenSplice/User/StatusCondition.cs b/src/api/dcps/sacs/code/DDS/OpenSplice/User/StatusCondition.cs index 81d590b05..1211a0fcb 100644 --- a/src/api/dcps/sacs/code/DDS/OpenSplice/User/StatusCondition.cs +++ b/src/api/dcps/sacs/code/DDS/OpenSplice/User/StatusCondition.cs @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/dcps/sacs/code/DDS/OpenSplice/User/Subscriber.cs b/src/api/dcps/sacs/code/DDS/OpenSplice/User/Subscriber.cs index b03d27ba9..841f3bd69 100644 --- a/src/api/dcps/sacs/code/DDS/OpenSplice/User/Subscriber.cs +++ b/src/api/dcps/sacs/code/DDS/OpenSplice/User/Subscriber.cs @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -30,15 +31,13 @@ static internal class Subscriber * u_subscriberNew( * const u_participant _scope, * const os_char *name, - * const u_subscriberQos qos, - * u_bool enable); + * const u_subscriberQos qos); */ [DllImport("ddskernel", EntryPoint = "u_subscriberNew", CallingConvention = CallingConvention.Cdecl)] public static extern IntPtr New( IntPtr _scope, string name, - IntPtr qos, - byte enable); + IntPtr qos); /* * u_result diff --git a/src/api/dcps/sacs/code/DDS/OpenSplice/User/Topic.cs b/src/api/dcps/sacs/code/DDS/OpenSplice/User/Topic.cs index 1135c9d6d..0f44e0d56 100644 --- a/src/api/dcps/sacs/code/DDS/OpenSplice/User/Topic.cs +++ b/src/api/dcps/sacs/code/DDS/OpenSplice/User/Topic.cs @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -146,26 +147,30 @@ static internal class Topic * u_topicContentFilterValidate ( * const u_topic _this, * const q_expr expr, - * const c_value params[]); + * const c_value params[], + * os_uint32 nrOfParams); */ [DllImport("ddskernel", EntryPoint = "u_topicContentFilterValidate", CallingConvention = CallingConvention.Cdecl)] public static extern V_RESULT ContentFilterValidate( IntPtr _this, IntPtr expr, - IntPtr _params); + IntPtr _params, + uint nrOfParams); /* * u_bool * u_topicContentFilterValidate ( * const u_topic _this, * const q_expr expr, - * const c_value params[]); + * const c_value params[], + * os_uint32 nrOfParams); */ [DllImport("ddskernel", EntryPoint = "u_topicContentFilterValidate2", CallingConvention = CallingConvention.Cdecl)] public static extern byte ContentFilterValidate2( IntPtr _this, IntPtr expr, - IntPtr _params); + IntPtr _params, + uint nrOfParams); /* * os_char * diff --git a/src/api/dcps/sacs/code/DDS/OpenSplice/User/UserLayer.cs b/src/api/dcps/sacs/code/DDS/OpenSplice/User/UserLayer.cs index f551d5aa8..0d54a9f71 100644 --- a/src/api/dcps/sacs/code/DDS/OpenSplice/User/UserLayer.cs +++ b/src/api/dcps/sacs/code/DDS/OpenSplice/User/UserLayer.cs @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/dcps/sacs/code/DDS/OpenSplice/User/WaitSet.cs b/src/api/dcps/sacs/code/DDS/OpenSplice/User/WaitSet.cs index 78c313159..fb0621b47 100644 --- a/src/api/dcps/sacs/code/DDS/OpenSplice/User/WaitSet.cs +++ b/src/api/dcps/sacs/code/DDS/OpenSplice/User/WaitSet.cs @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/dcps/sacs/code/DDS/OpenSplice/User/Writer.cs b/src/api/dcps/sacs/code/DDS/OpenSplice/User/Writer.cs index 7aa228e22..6921ac60a 100644 --- a/src/api/dcps/sacs/code/DDS/OpenSplice/User/Writer.cs +++ b/src/api/dcps/sacs/code/DDS/OpenSplice/User/Writer.cs @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/dcps/sacs/code/DDS/PublisherListener.cs b/src/api/dcps/sacs/code/DDS/PublisherListener.cs index d753b9e04..26ccb550c 100644 --- a/src/api/dcps/sacs/code/DDS/PublisherListener.cs +++ b/src/api/dcps/sacs/code/DDS/PublisherListener.cs @@ -1,8 +1,9 @@ -/* - * OpenSplice DDS +/* + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/dcps/sacs/code/DDS/QosProvider.cs b/src/api/dcps/sacs/code/DDS/QosProvider.cs index 71719ad93..fff2c2d70 100644 --- a/src/api/dcps/sacs/code/DDS/QosProvider.cs +++ b/src/api/dcps/sacs/code/DDS/QosProvider.cs @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -147,27 +148,27 @@ private ReturnCode qpResultToReturnCode (QP_RESULT qpResult) /* let's assign defaults and see what happens */ loadQosInputAttr( - new NamedDomainParticipantQosMarshaler(), + new __NamedDomainParticipantQosMarshaler(), typeof(NamedDomainParticipantQos), ref attr.participantQos); loadQosInputAttr( - new NamedTopicQosMarshaler(), + new __NamedTopicQosMarshaler(), typeof(NamedTopicQos), ref attr.topicQos); loadQosInputAttr( - new NamedPublisherQosMarshaler(), + new __NamedPublisherQosMarshaler(), typeof(NamedPublisherQos), ref attr.publisherQos); loadQosInputAttr( - new NamedSubscriberQosMarshaler(), + new __NamedSubscriberQosMarshaler(), typeof(NamedSubscriberQos), ref attr.subscriberQos); loadQosInputAttr( - new NamedDataWriterQosMarshaler(), + new __NamedDataWriterQosMarshaler(), typeof(NamedDataWriterQos), ref attr.dataWriterQos); loadQosInputAttr( - new NamedDataReaderQosMarshaler(), + new __NamedDataReaderQosMarshaler(), typeof(NamedDataReaderQos), ref attr.dataReaderQos); diff --git a/src/api/dcps/sacs/code/DDS/StatusCondition.cs b/src/api/dcps/sacs/code/DDS/StatusCondition.cs index eeaefd952..5a5fd86a8 100644 --- a/src/api/dcps/sacs/code/DDS/StatusCondition.cs +++ b/src/api/dcps/sacs/code/DDS/StatusCondition.cs @@ -1,8 +1,9 @@ -/* - * OpenSplice DDS +/* + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/dcps/sacs/code/DDS/SubscriberListener.cs b/src/api/dcps/sacs/code/DDS/SubscriberListener.cs index 6d4eb5a21..28a442e1d 100644 --- a/src/api/dcps/sacs/code/DDS/SubscriberListener.cs +++ b/src/api/dcps/sacs/code/DDS/SubscriberListener.cs @@ -1,8 +1,9 @@ -/* - * OpenSplice DDS +/* + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/dcps/sacs/code/DDS/TopicListener.cs b/src/api/dcps/sacs/code/DDS/TopicListener.cs index 207a78c56..a4f85037a 100644 --- a/src/api/dcps/sacs/code/DDS/TopicListener.cs +++ b/src/api/dcps/sacs/code/DDS/TopicListener.cs @@ -1,8 +1,9 @@ -/* - * OpenSplice DDS +/* + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/dcps/sacs/code/DDS/WaitSet.cs b/src/api/dcps/sacs/code/DDS/WaitSet.cs index ae5db5e84..34339b03b 100644 --- a/src/api/dcps/sacs/code/DDS/WaitSet.cs +++ b/src/api/dcps/sacs/code/DDS/WaitSet.cs @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/dcps/sacs/docs/EXAMPLES.md b/src/api/dcps/sacs/docs/EXAMPLES.md index 7bd896248..4e38f6a06 100644 --- a/src/api/dcps/sacs/docs/EXAMPLES.md +++ b/src/api/dcps/sacs/docs/EXAMPLES.md @@ -129,7 +129,7 @@ A script `release.bat` is provided. It exports a value of `OSPL_URI` to indicate the file `%%OSPL_HOME%\etc\config\ospl.xml` and also makes the OpenSplice executables and dynamic-link libraries available on the `PATH`. -A shortcut within the OpenSplice HDE folder on the Start Menu: **OpenSplice DDS +A shortcut within the OpenSplice HDE folder on the Start Menu: **Vortex OpenSplice command prompt** creates a `cmd.exe` console session with this environment ready set. diff --git a/src/api/dcps/sacs/docs/README.md b/src/api/dcps/sacs/docs/README.md index cb77a77b1..4f8907d7e 100755 --- a/src/api/dcps/sacs/docs/README.md +++ b/src/api/dcps/sacs/docs/README.md @@ -23,7 +23,7 @@ about the DDS specification and usage, which is a good starting point if you don much about DDS yet. If you are new to C# we would recommend that you start by looking at the example -code provided in your OpenSplice installation directory as well as the documentation +code provided in your Vortex OpenSplice installation directory as well as the documentation in the sections below. A summary of each example, along with build instructions can be found on the @@ -37,7 +37,7 @@ The API is currently compiled on the Windows platform using Microsoft's C# compi the Mono framework has also been used by the opensource community, but that is not yet part of the commercially supported releases. However, it should be possible to run the Windows DLL on Mono, since Mono is binary compatible with Windows. The resulting deliverable is a library file called dcpssacsAssembly.dll, which you can find in the -%OSPL_HOME%/bin directory alongside all the other OpenSplice DDS product libraries. +%OSPL_HOME%/bin directory alongside all the other Vortex OpenSplice product libraries. Since the DLL is a managed assembly, it is not found by Windows using the normal PATH environment variable. In order for the .NET framework to find a library, this library must either be copied to the same directory diff --git a/src/api/dcps/sacs/makefile.mak b/src/api/dcps/sacs/makefile.mak index 0369365db..3646353f1 100644 --- a/src/api/dcps/sacs/makefile.mak +++ b/src/api/dcps/sacs/makefile.mak @@ -12,7 +12,7 @@ TARGET_ASSEMBLY = $(CSLIB_PREFIX)$(DDS_DCPSSACS)$(CSLIB_POSTFIX) # Input IDL files. IDL_DIR := $(OSPL_HOME)/etc/idl vpath %.idl $(IDL_DIR) -TOPIC_IDL := dds_dcps_builtintopics.idl dds_builtinTopics.idl dds_namedQosTypes.idl +TOPIC_IDL := dds_dcps_builtintopics.idl dds_builtinTopics.idl dds_namedQosTypes.idl dds_IoTData.idl # idlpp compiler settings. IDLPP = $(WINCMD) idlpp @@ -30,8 +30,6 @@ ODL_FILES = $(OSPL_HOME)/src/kernel/code/v_kernel.odl include $(OSPL_HOME)/setup/makefiles/target.mak -CSLIBS += -r:System.dll - all link: $(TARGET_ASSEMBLY) # Generate the C# interfaces from the IDL descriptions. @@ -40,4 +38,4 @@ all link: $(TARGET_ASSEMBLY) # Generate the assembly as well. $(TARGET_ASSEMBLY): $(CS_FILES) - $(CSC) $(CSFLAGS) -out:$(TARGET_ASSEMBLY) $(CSTARGET_LIB) $(CSLIBS) $(CS_FILES) + $(CSC) $(CSFLAGS) -out:$(TARGET_ASSEMBLY) $(CSTARGET_LIB) $(CS_SYSLIB) $(CSLIBS) $(CS_FILES) diff --git a/src/api/face/cpp/code/Vortex/FACE/AnyConnection.cpp b/src/api/face/cpp/code/Vortex/FACE/AnyConnection.cpp index 1ef0c37fe..cb175daeb 100644 --- a/src/api/face/cpp/code/Vortex/FACE/AnyConnection.cpp +++ b/src/api/face/cpp/code/Vortex/FACE/AnyConnection.cpp @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/face/cpp/code/Vortex/FACE/Config.cpp b/src/api/face/cpp/code/Vortex/FACE/Config.cpp index 162121ac3..f8b853bb5 100644 --- a/src/api/face/cpp/code/Vortex/FACE/Config.cpp +++ b/src/api/face/cpp/code/Vortex/FACE/Config.cpp @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/face/cpp/code/Vortex/FACE/ConnectionConfig.cpp b/src/api/face/cpp/code/Vortex/FACE/ConnectionConfig.cpp index e648a1694..053062607 100644 --- a/src/api/face/cpp/code/Vortex/FACE/ConnectionConfig.cpp +++ b/src/api/face/cpp/code/Vortex/FACE/ConnectionConfig.cpp @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/face/cpp/code/Vortex/FACE/ConnectionFactory.cpp b/src/api/face/cpp/code/Vortex/FACE/ConnectionFactory.cpp index 3ad0b74fa..7e3c8fb8c 100644 --- a/src/api/face/cpp/code/Vortex/FACE/ConnectionFactory.cpp +++ b/src/api/face/cpp/code/Vortex/FACE/ConnectionFactory.cpp @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/face/cpp/code/Vortex/FACE/FaceInstance.cpp b/src/api/face/cpp/code/Vortex/FACE/FaceInstance.cpp index 535922ef5..77f71dd36 100644 --- a/src/api/face/cpp/code/Vortex/FACE/FaceInstance.cpp +++ b/src/api/face/cpp/code/Vortex/FACE/FaceInstance.cpp @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/face/cpp/code/Vortex/FACE/Mutex.cpp b/src/api/face/cpp/code/Vortex/FACE/Mutex.cpp index 471cf12c2..dc1ae5725 100644 --- a/src/api/face/cpp/code/Vortex/FACE/Mutex.cpp +++ b/src/api/face/cpp/code/Vortex/FACE/Mutex.cpp @@ -1,8 +1,9 @@ /* -* OpenSplice DDS +* Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,13 +18,8 @@ * limitations under the License. * */ - - -/** - * @file - */ - #include "Vortex/FACE/Mutex.hpp" +#include "Vortex/FACE/ReportSupport.hpp" Vortex::FACE::Mutex::Mutex() @@ -31,8 +27,8 @@ Vortex::FACE::Mutex::Mutex() os_result osr; osr = os_mutexInit(&this->mtx, NULL); if (osr != os_resultSuccess) { + FACE_REPORT_ERROR(::FACE::NOT_AVAILABLE, "Failed to initialize mutex"); assert(false); - /* TODO: (OSPL-8901) Add trace. */ } } @@ -76,6 +72,7 @@ Vortex::FACE::MutexScoped::~MutexScoped() mtx.unlock(); } catch (...) { /* Don't know what to do anymore (it should have never failed)... */ + FACE_REPORT_ERROR(::FACE::NOT_AVAILABLE, "Unexpected error in ~MutexScoped()"); assert(false); } } diff --git a/src/api/face/cpp/code/Vortex/FACE/ReportSupport.cpp b/src/api/face/cpp/code/Vortex/FACE/ReportSupport.cpp index c97505c07..494cb8c56 100644 --- a/src/api/face/cpp/code/Vortex/FACE/ReportSupport.cpp +++ b/src/api/face/cpp/code/Vortex/FACE/ReportSupport.cpp @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -126,7 +127,7 @@ Vortex::FACE::report_stack_close( assert (file != NULL); assert (signature != NULL); - if (os_report_stack_flush_required((os_boolean)flush)) { + if (os_report_status((os_boolean)flush)) { const char *_file = file; int32_t _line = line; const char *_signature = signature; @@ -150,7 +151,7 @@ Vortex::FACE::report_stack_close( } } } - os_report_stack_unwind((os_boolean)flush, function, _file, _line, domainId); + os_report_flush((os_boolean)flush, function, _file, _line, domainId); } } @@ -169,20 +170,15 @@ Vortex::FACE::report( char buffer[OS_REPORT_BUFLEN]; const char *function; std::string retcode; - os_size_t offset = 0; va_list args; assert (file != NULL); assert (signature != NULL); assert (format != NULL); - /* Prepare error description. */ retcode = returnCodeToString(code); - offset = snprintf(buffer, OS_REPORT_BUFLEN, "%s: ", retcode.c_str()); - va_start(args, format); - (void)os_vsnprintf(buffer + offset, sizeof(buffer) - offset, format, args); - va_end(args); + snprintf(buffer, OS_REPORT_BUFLEN, "%s: %s", retcode.c_str(), format); /* Prettify function name. */ std::string s(signature); @@ -193,5 +189,7 @@ Vortex::FACE::report( } /* Add this report to the logs. */ - os_report_noargs(reportType, function, file, line, (os_int32)code, buffer); + va_start(args, format); + os_report_va(reportType, function, file, line, (os_int32)code, -1, OS_TRUE, (os_char *)buffer, args); + va_end(args); } diff --git a/src/api/face/cpp/code/Vortex_FACE.cpp b/src/api/face/cpp/code/Vortex_FACE.cpp index 659c7edc3..ceeaa9653 100644 --- a/src/api/face/cpp/code/Vortex_FACE.cpp +++ b/src/api/face/cpp/code/Vortex_FACE.cpp @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,7 +18,6 @@ * limitations under the License. * */ - #include "Vortex_FACE.hpp" #include "Vortex/FACE/FaceInstance.hpp" #include "Vortex/FACE/ReportSupport.hpp" diff --git a/src/api/face/cpp/doc/EXAMPLES.md b/src/api/face/cpp/doc/EXAMPLES.md index 327662e88..25426fb66 100644 --- a/src/api/face/cpp/doc/EXAMPLES.md +++ b/src/api/face/cpp/doc/EXAMPLES.md @@ -100,7 +100,7 @@ A script `release.bat` is provided. It exports a value of `OSPL_URI` to indicate the file `%%OSPL_HOME%\etc\config\ospl.xml` and also makes the OpenSplice executables and dynamic-link libraries available on the `PATH`. -A shortcut within the OpenSplice HDE folder on the Start Menu: **OpenSplice DDS +A shortcut within the OpenSplice HDE folder on the Start Menu: **Vortex OpenSplice command prompt** creates a `cmd.exe` console session with this environment ready set. diff --git a/src/api/face/cpp/doc/Vortex_FACE.hpp b/src/api/face/cpp/doc/Vortex_FACE.hpp index f8f0e3500..9a2354a82 100644 --- a/src/api/face/cpp/doc/Vortex_FACE.hpp +++ b/src/api/face/cpp/doc/Vortex_FACE.hpp @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/face/cpp/include/FACE/FACE_TS_common.h b/src/api/face/cpp/include/FACE/FACE_TS_common.h index cdf674570..b05b83541 100644 --- a/src/api/face/cpp/include/FACE/FACE_TS_common.h +++ b/src/api/face/cpp/include/FACE/FACE_TS_common.h @@ -1,3 +1,23 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ #ifndef _FACE_TS_COMMON_H_ #define _FACE_TS_COMMON_H_ diff --git a/src/api/face/cpp/include/FACE/FACE_callback.h b/src/api/face/cpp/include/FACE/FACE_callback.h index 70c260527..bcd7ff26b 100644 --- a/src/api/face/cpp/include/FACE/FACE_callback.h +++ b/src/api/face/cpp/include/FACE/FACE_callback.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/face/cpp/include/FACE/FACE_common.h b/src/api/face/cpp/include/FACE/FACE_common.h index 50623ee1d..0367fa982 100644 --- a/src/api/face/cpp/include/FACE/FACE_common.h +++ b/src/api/face/cpp/include/FACE/FACE_common.h @@ -1,3 +1,23 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ #ifndef _FACE_COMMON_H_ #define _FACE_COMMON_H_ diff --git a/src/api/face/cpp/include/Vortex/FACE/AnyConnection.hpp b/src/api/face/cpp/include/Vortex/FACE/AnyConnection.hpp index 3c3a4cfa1..751ceafd9 100644 --- a/src/api/face/cpp/include/Vortex/FACE/AnyConnection.hpp +++ b/src/api/face/cpp/include/Vortex/FACE/AnyConnection.hpp @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,7 +18,6 @@ * limitations under the License. * */ - #ifndef VORTEX_FACE_ANY_CONNECTION_HPP_ #define VORTEX_FACE_ANY_CONNECTION_HPP_ diff --git a/src/api/face/cpp/include/Vortex/FACE/Config.hpp b/src/api/face/cpp/include/Vortex/FACE/Config.hpp index c325544d1..90a9e2a8b 100644 --- a/src/api/face/cpp/include/Vortex/FACE/Config.hpp +++ b/src/api/face/cpp/include/Vortex/FACE/Config.hpp @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/face/cpp/include/Vortex/FACE/Connection.hpp b/src/api/face/cpp/include/Vortex/FACE/Connection.hpp index 9e186b39a..a80f94d3b 100644 --- a/src/api/face/cpp/include/Vortex/FACE/Connection.hpp +++ b/src/api/face/cpp/include/Vortex/FACE/Connection.hpp @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,7 +18,6 @@ * limitations under the License. * */ - #ifndef VORTEX_FACE_CONNECTION_HPP_ #define VORTEX_FACE_CONNECTION_HPP_ diff --git a/src/api/face/cpp/include/Vortex/FACE/ConnectionConfig.hpp b/src/api/face/cpp/include/Vortex/FACE/ConnectionConfig.hpp index f71ef7f10..ebe0cde77 100644 --- a/src/api/face/cpp/include/Vortex/FACE/ConnectionConfig.hpp +++ b/src/api/face/cpp/include/Vortex/FACE/ConnectionConfig.hpp @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,11 +21,9 @@ #ifndef VORTEX_FACE_CONNECTION_CONFIGURATION_HPP_ #define VORTEX_FACE_CONNECTION_CONFIGURATION_HPP_ - #include "Vortex_FACE.hpp" #include "Vortex/FACE/Macros.hpp" - namespace Vortex { namespace FACE { diff --git a/src/api/face/cpp/include/Vortex/FACE/ConnectionFactory.hpp b/src/api/face/cpp/include/Vortex/FACE/ConnectionFactory.hpp index b702a0e92..fea79a4a2 100644 --- a/src/api/face/cpp/include/Vortex/FACE/ConnectionFactory.hpp +++ b/src/api/face/cpp/include/Vortex/FACE/ConnectionFactory.hpp @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,11 +21,9 @@ #ifndef VORTEX_FACE_CONNECTION_FACTORY_HPP_ #define VORTEX_FACE_CONNECTION_FACTORY_HPP_ - #include "Vortex_FACE.hpp" #include "Vortex/FACE/AnyConnection.hpp" - namespace Vortex { namespace FACE { diff --git a/src/api/face/cpp/include/Vortex/FACE/DataListener.hpp b/src/api/face/cpp/include/Vortex/FACE/DataListener.hpp index 85b47c1bc..ddf0cc3c8 100644 --- a/src/api/face/cpp/include/Vortex/FACE/DataListener.hpp +++ b/src/api/face/cpp/include/Vortex/FACE/DataListener.hpp @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,7 +18,6 @@ * limitations under the License. * */ - #ifndef VORTEX_FACE_DATALISTENER_HPP_ #define VORTEX_FACE_DATALISTENER_HPP_ diff --git a/src/api/face/cpp/include/Vortex/FACE/FaceInstance.hpp b/src/api/face/cpp/include/Vortex/FACE/FaceInstance.hpp index a46568423..d4c4faf70 100644 --- a/src/api/face/cpp/include/Vortex/FACE/FaceInstance.hpp +++ b/src/api/face/cpp/include/Vortex/FACE/FaceInstance.hpp @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,7 +18,6 @@ * limitations under the License. * */ - #ifndef VORTEX_FACE_FACE_INSTANCE_HPP_ #define VORTEX_FACE_FACE_INSTANCE_HPP_ diff --git a/src/api/face/cpp/include/Vortex/FACE/Macros.hpp b/src/api/face/cpp/include/Vortex/FACE/Macros.hpp index a2d5381fd..2a6727d64 100644 --- a/src/api/face/cpp/include/Vortex/FACE/Macros.hpp +++ b/src/api/face/cpp/include/Vortex/FACE/Macros.hpp @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/face/cpp/include/Vortex/FACE/Mutex.hpp b/src/api/face/cpp/include/Vortex/FACE/Mutex.hpp index f353b52d5..5d016e7ff 100644 --- a/src/api/face/cpp/include/Vortex/FACE/Mutex.hpp +++ b/src/api/face/cpp/include/Vortex/FACE/Mutex.hpp @@ -1,8 +1,9 @@ /* -* OpenSplice DDS +* Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,12 +18,6 @@ * limitations under the License. * */ - - -/** - * @file - */ - #ifndef VORTEX_FACE_MUTEX_HPP_ #define VORTEX_FACE_MUTEX_HPP_ diff --git a/src/api/face/cpp/include/Vortex/FACE/ReportSupport.hpp b/src/api/face/cpp/include/Vortex/FACE/ReportSupport.hpp index d300e98da..a009f4ed9 100644 --- a/src/api/face/cpp/include/Vortex/FACE/ReportSupport.hpp +++ b/src/api/face/cpp/include/Vortex/FACE/ReportSupport.hpp @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,7 +18,6 @@ * limitations under the License. * */ - #ifndef VORTEX_FACE_REPORT_SUPPORT_HPP_ #define VORTEX_FACE_REPORT_SUPPORT_HPP_ diff --git a/src/api/face/cpp/include/Vortex_FACE.hpp b/src/api/face/cpp/include/Vortex_FACE.hpp index 082c8bdc9..2c465a930 100644 --- a/src/api/face/cpp/include/Vortex_FACE.hpp +++ b/src/api/face/cpp/include/Vortex_FACE.hpp @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,7 +18,6 @@ * limitations under the License. * */ - #ifndef VORTEX_FACE_HPP_ #define VORTEX_FACE_HPP_ @@ -32,8 +32,9 @@ namespace FACE { namespace TS { /** - * The Initialize function call allows for the Portable Components Segment (PCS) and Platform-Specific Services Segment (PSSS) - * component to trigger the initialization of the Transport Services Segment (TSS) component. + * The Initialize function call allows for the Portable Components Segment (PCS) + * and Platform-Specific Services Segment (PSSS) component to trigger the + * initialization of the Transport Services Segment (TSS) component. * * Possible return codes: *
      @@ -42,7 +43,8 @@ namespace TS { *
    • NO_ACTION - There is already an initialized configuration. *
    * @param configuration - * The configuration defined as an xml file which hold the connection configuration. + * The configuration defined as an xml file which hold the connection + * configuration. * This is an input parameter * @param return_code * The return_code @@ -52,9 +54,10 @@ void VORTEX_FACE_API Initialize( /* out */ FACE::RETURN_CODE_TYPE &return_code); /** - * The Transport Services Segment (TSS) provides an interface to create a connection. - * The parameters for the individual connections are determined through the TSS configuration - * capability which is set by the Initialize function call. + * The Transport Services Segment (TSS) provides an interface to create a + * connection. The parameters for the individual connections are determined + * through the TSS configuration capability which is set by the Initialize + * function call. * * Possible return codes: *
      @@ -76,16 +79,20 @@ void VORTEX_FACE_API Initialize( *
    * * @param connection_name - * The connection_name which needs to match one of the configured connection names in the configuration + * The connection_name which needs to match one of the configured + * connection names in the configuration. * This is an input parameter. * @param pattern - * The pattern set in the connection configuration which for DDS only can be PUB_SUB. + * The pattern set in the connection configuration which for DDS only + * can be PUB_SUB. * This is an input parameter. * @param connection_id - * The connection_id which is generated by DDS and set on successful creation. + * The connection_id which is generated by DDS and set on successful + * creation. * This is an output parameter. * @param connection_direction - * The connection_direction of the connection that is created. This can be SOURCE or DESTINATION. + * The connection_direction of the connection that is created. This can + * be SOURCE or DESTINATION. * This is an output parameter. * @param max_message_size * The max_message_size for DDS this parameter is not relevant. @@ -107,7 +114,8 @@ void VORTEX_FACE_API Create_Connection( /* out */ FACE::RETURN_CODE_TYPE &return_code); /** - * The Destroy_Connection function frees up any resources allocated to the connection. + * The Destroy_Connection function frees up any resources allocated to the + * connection. * * Possible return codes: *
      @@ -136,7 +144,8 @@ void VORTEX_FACE_API Destroy_Connection( /* out */ FACE::RETURN_CODE_TYPE &return_code); /** - * The purpose of Get_Connection_Parameters is to get the information regarding the requested connection. + * The purpose of Get_Connection_Parameters is to get the information regarding + * the requested connection. * * @param connection_name * The connection_name which belongs to the given connection_id. @@ -153,7 +162,8 @@ void VORTEX_FACE_API Destroy_Connection( *
    • CONNECTION_DIRECTION - SOURCE or DESTINATION *
    • WAITING_PROCESSES_OR_MESSAGES - Not implemented *
    • REFRESH_PERIOD - The configured refresh period. - *
    • LAST_MSG_VALIDITY - Whether or not the refresh period of last taken message has expired or not (DESTINATION) + *
    • LAST_MSG_VALIDITY - Whether or not the refresh period of last + * taken message has expired or not (DESTINATION) *
    * This is an output parameter. * @param return_code @@ -167,8 +177,8 @@ void VORTEX_FACE_API Get_Connection_Parameters( /* out */ FACE::RETURN_CODE_TYPE &return_code); /** - * The purpose of Unregister_Callback is to provide a mechanism to unregister the callback - * associated with a connection_id. + * The purpose of Unregister_Callback is to provide a mechanism to unregister + * the callback associated with a connection_id. * * @param connection_id * The connection_id of the connection where the callback was registered. diff --git a/src/api/face/java/code/org/vortex/FACE/ConfigurationException.java b/src/api/face/java/code/org/vortex/FACE/ConfigurationException.java index b8f0102fb..fdf8b4bf0 100644 --- a/src/api/face/java/code/org/vortex/FACE/ConfigurationException.java +++ b/src/api/face/java/code/org/vortex/FACE/ConfigurationException.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/face/java/code/org/vortex/FACE/Connection.java b/src/api/face/java/code/org/vortex/FACE/Connection.java index e3a711bb2..4cb2e847d 100644 --- a/src/api/face/java/code/org/vortex/FACE/Connection.java +++ b/src/api/face/java/code/org/vortex/FACE/Connection.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/face/java/code/org/vortex/FACE/ConnectionDescription.java b/src/api/face/java/code/org/vortex/FACE/ConnectionDescription.java index edb10b24c..2439f4e71 100644 --- a/src/api/face/java/code/org/vortex/FACE/ConnectionDescription.java +++ b/src/api/face/java/code/org/vortex/FACE/ConnectionDescription.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/face/java/code/org/vortex/FACE/DestinationConnection.java b/src/api/face/java/code/org/vortex/FACE/DestinationConnection.java index 1cf708f86..64be22680 100644 --- a/src/api/face/java/code/org/vortex/FACE/DestinationConnection.java +++ b/src/api/face/java/code/org/vortex/FACE/DestinationConnection.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/face/java/code/org/vortex/FACE/Holder.java b/src/api/face/java/code/org/vortex/FACE/Holder.java index 80c8f3bb8..f12abe749 100644 --- a/src/api/face/java/code/org/vortex/FACE/Holder.java +++ b/src/api/face/java/code/org/vortex/FACE/Holder.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/face/java/code/org/vortex/FACE/Logger.java b/src/api/face/java/code/org/vortex/FACE/Logger.java index f0990d972..6633d30ec 100644 --- a/src/api/face/java/code/org/vortex/FACE/Logger.java +++ b/src/api/face/java/code/org/vortex/FACE/Logger.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/face/java/code/org/vortex/FACE/Read_Callback.java b/src/api/face/java/code/org/vortex/FACE/Read_Callback.java index 117c1f373..6f94e26bb 100644 --- a/src/api/face/java/code/org/vortex/FACE/Read_Callback.java +++ b/src/api/face/java/code/org/vortex/FACE/Read_Callback.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/face/java/code/org/vortex/FACE/Read_CallbackHolder.java b/src/api/face/java/code/org/vortex/FACE/Read_CallbackHolder.java index 43bb55f51..3a0a93bba 100644 --- a/src/api/face/java/code/org/vortex/FACE/Read_CallbackHolder.java +++ b/src/api/face/java/code/org/vortex/FACE/Read_CallbackHolder.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/face/java/code/org/vortex/FACE/Read_CallbackOperations.java b/src/api/face/java/code/org/vortex/FACE/Read_CallbackOperations.java index 2f41c0569..2059b2514 100644 --- a/src/api/face/java/code/org/vortex/FACE/Read_CallbackOperations.java +++ b/src/api/face/java/code/org/vortex/FACE/Read_CallbackOperations.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/face/java/code/org/vortex/FACE/SourceConnection.java b/src/api/face/java/code/org/vortex/FACE/SourceConnection.java index ddabd709b..5942f3e50 100644 --- a/src/api/face/java/code/org/vortex/FACE/SourceConnection.java +++ b/src/api/face/java/code/org/vortex/FACE/SourceConnection.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/face/java/code/org/vortex/FACE/TS.java b/src/api/face/java/code/org/vortex/FACE/TS.java index 84f4ab236..98c262a02 100644 --- a/src/api/face/java/code/org/vortex/FACE/TS.java +++ b/src/api/face/java/code/org/vortex/FACE/TS.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -37,8 +38,9 @@ public TransportServices getImpl() { } /** - * The Initialize function call allows for the Portable Components Segment (PCS) and Platform-Specific Services Segment (PSSS) - * component to trigger the initialization of the Transport Services Segment (TSS) component. + * The Initialize function call allows for the Portable Components Segment + * (PCS) and Platform-Specific Services Segment (PSSS) component to trigger + * the initialization of the Transport Services Segment (TSS) component. * * Possible return codes: *
      @@ -47,7 +49,8 @@ public TransportServices getImpl() { *
    • NO_ACTION - There is already an initialized configuration. *
    * @param configuration - * The configuration defined as an xml file which hold the connection configuration. + * The configuration defined as an xml file which hold the connection + * configuration. * This is an input parameter * @param return_code * The return_code @@ -70,9 +73,10 @@ public static void Initialize(String configuration, } /** - * The Transport Services Segment (TSS) provides an interface to create a connection. - * The parameters for the individual connections are determined through the TSS configuration - * capability which is set by the Initialize function call. + * The Transport Services Segment (TSS) provides an interface to create a + * connection. + * The parameters for the individual connections are determined through the + * TSS configuration capability which is set by the Initialize function call. * * Possible return codes: *
      @@ -94,16 +98,20 @@ public static void Initialize(String configuration, *
    * * @param connection_name - * The connection_name which needs to match one of the configured connection names in the configuration + * The connection_name which needs to match one of the configured + * connection names in the configuration. * This is an input parameter. * @param pattern - * The pattern set in the connection configuration which for DDS only can be PUB_SUB. + * The pattern set in the connection configuration which for DDS only + * can be PUB_SUB. * This is an input parameter. * @param connection_id - * The connection_id which is generated by DDS and set on successful creation. + * The connection_id which is generated by DDS and set on successful + * creation. * This is an output parameter. * @param connection_direction - * The connection_direction of the connection that is created. This can be SOURCE or DESTINATION. + * The connection_direction of the connection that is created. This + * can be SOURCE or DESTINATION. * This is an output parameter. * @param max_message_size * The max_message_size for DDS this parameter is not relevant. @@ -132,7 +140,8 @@ public static void Create_Connection(String connection_name, /** - * The Destroy_Connection function frees up any resources allocated to the connection. + * The Destroy_Connection function frees up any resources allocated to the + * connection. * * Possible return codes: *
      @@ -166,11 +175,12 @@ public static void Destroy_Connection(long connection_id, } /** - * The purpose of Unregister_Callback is to provide a mechanism to unregister the callback - * associated with a connection_id. + * The purpose of Unregister_Callback is to provide a mechanism to unregister + * the callback associated with a connection_id. * * @param connection_id - * The connection_id of the connection where the callback was registered. + * The connection_id of the connection where the callback was + * registered. * This is an input parameter. * @param return_code * The return_code @@ -187,13 +197,15 @@ public static void Unregister_Callback(long connection_id, } /** - * The purpose of Get_Connection_Parameters is to get the information regarding the requested connection. + * The purpose of Get_Connection_Parameters is to get the information + * regarding the requested connection. * * @param connection_name * The connection_name which belongs to the given connection_id. * This is an output parameter. * @param connection_id - * The connection_id for which this status needs to return information + * The connection_id for which this status needs to return + * information. * This is an input parameter. * @param connection_status * The connection_status which consists of the following settings: @@ -204,7 +216,8 @@ public static void Unregister_Callback(long connection_id, *
    • CONNECTION_DIRECTION - SOURCE or DESTINATION *
    • WAITING_PROCESSES_OR_MESSAGES - Not implemented *
    • REFRESH_PERIOD - The configured refresh period. - *
    • LAST_MSG_VALIDITY - Whether or not the refresh period of last taken message has expired or not (DESTINATION) + *
    • LAST_MSG_VALIDITY - Whether or not the refresh period of last + * taken message has expired or not (DESTINATION) *
    * This is an output parameter. * @param return_code diff --git a/src/api/face/java/code/org/vortex/FACE/TSFactory.java b/src/api/face/java/code/org/vortex/FACE/TSFactory.java index aef7353f3..d252f8676 100644 --- a/src/api/face/java/code/org/vortex/FACE/TSFactory.java +++ b/src/api/face/java/code/org/vortex/FACE/TSFactory.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/face/java/code/org/vortex/FACE/TransportServices.java b/src/api/face/java/code/org/vortex/FACE/TransportServices.java index a5a9f3de9..c278bf0b6 100644 --- a/src/api/face/java/code/org/vortex/FACE/TransportServices.java +++ b/src/api/face/java/code/org/vortex/FACE/TransportServices.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -213,7 +214,8 @@ public void Destroy_Connection(long connection_id, /** * The Receive_Message Function is used to receive data from another source. - * For Java this needs to be called on the generated type interface without using the TS Interface. + * For Java this needs to be called on the generated type interface without + * using the TS Interface. * * Possible return codes: *
      @@ -231,17 +233,19 @@ public void Destroy_Connection(long connection_id, *
    * * @param connection_id - * The connection_id which is used to get the connection where to receive messages on. + * The connection_id which is used to get the connection where to + * receive messages on. * This is an input parameter. * @param timeout - * The timeout in nanoseconds, this is used to determine how long DDS should wait for new messages - * to arrive before returning the result. + * The timeout in nanoseconds, this is used to determine how long DDS + * should wait for new messages to arrive before returning the result. * This is an input parameter. * @param transaction_id - * The transaction_id, each time a message is read an unique transaction_id is generated for it. + * The transaction_id, each time a message is read an unique + * transaction_id is generated for it. * This is an output parameter. * @param message - * The message that is read by DDS + * The message that is read by DDS. * This is an output parameter. * @param message_type_id * The message_type_id for DDS this parameter is not relevant. @@ -301,7 +305,8 @@ public void Receive_Message(long connection_id, long timeout, /** * The Send_Message Function is used to send data to another source. - * For Java this needs to be called on the generated type interface without using the TS Interface. + * For Java this needs to be called on the generated type interface without + * using the TS Interface. * * Possible return codes: *
      @@ -324,17 +329,21 @@ public void Receive_Message(long connection_id, long timeout, *
    * * @param connection_id - * The connection_id which is used to get the connection where to send messages to. + * The connection_id which is used to get the connection where to + * send messages to. * This is an input parameter. * @param timeout - * The timeout in nanoseconds, this is used to determine how long DDS at maximum can wait to send the message. - * This timeout cannot be greater than max_blocking_time of the supplied DataWriter QoS. + * The timeout in nanoseconds, this is used to determine how long DDS + * at maximum can wait to send the message. + * This timeout cannot be greater than max_blocking_time of the + * supplied DataWriter QoS. * This is an input parameter. * @param transaction_id - * The transaction_id, each time a message is send an unique transaction_id is generated for it. + * The transaction_id, each time a message is send an unique + * transaction_id is generated for it. * This is an output parameter. * @param message - * The message that is read by DDS + * The message that is read by DDS. * This is an output parameter. * @param message_type_id * The message_type_id for DDS this parameter is not relevant. @@ -397,8 +406,9 @@ public void Send_Message(long connection_id, long timeout, } /** - * The purpose of Register_Callback is to provide a mechanism to read data without polling. - * For Java this needs to be called on the generated type interface without using the TS Interface. + * The purpose of Register_Callback is to provide a mechanism to read data + * without polling. For Java this needs to be called on the generated type + * interface without using the TS Interface. * There can only be one callback registration per connection_id. * * Possible return codes: @@ -415,17 +425,20 @@ public void Send_Message(long connection_id, long timeout, * * * @param connection_id - * The connection_id of the connection that needs to be used for the callback. + * The connection_id of the connection that needs to be used for the + * callback. * This is an input parameter. * @param waitset * The waitset for DDS this parameter is not relevant. * This is an input parameter. * @param data_callback - * The data_callback class in which an action can be set on how to react when receiving data. + * The data_callback class in which an action can be set on how to + * react when receiving data. * This is an output parameter. * @param max_message_size - * The max_message_size for DDS this parameter is not relevant however the max_message_size supplied - * needs to be less then the max_message_size of the configured connection. + * The max_message_size for DDS this parameter is not relevant + * however the max_message_size supplied needs to be less then the + * max_message_size of the configured connection. * This is an input parameter. * @param return_code the return_code * This is an output parameter. diff --git a/src/api/face/java/code/org/vortex/FACE/Util.java b/src/api/face/java/code/org/vortex/FACE/Util.java index e0a35aab0..2ef016d3c 100644 --- a/src/api/face/java/code/org/vortex/FACE/Util.java +++ b/src/api/face/java/code/org/vortex/FACE/Util.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/face/java/doc/DataTypeTS.java b/src/api/face/java/doc/DataTypeTS.java index 05d87fa8f..5b30f0c17 100644 --- a/src/api/face/java/doc/DataTypeTS.java +++ b/src/api/face/java/doc/DataTypeTS.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,7 +26,8 @@ public class DataTypeTS extends TS { /** * The Receive_Message Function is used to receive data from another source. - * This needs to be called on the generated type interface without using the TS Interface. + * This needs to be called on the generated type interface without using + * the TS Interface. * * Possible return codes: *
      @@ -43,17 +45,19 @@ public class DataTypeTS extends TS { *
    • NO_ACTION - Indicates a transient situation where the operation did *
    * @param connection_id - * The connection_id which is used to get the connection where to receive messages on. + * The connection_id which is used to get the connection where to + * receive messages on. * This is an input parameter. * @param timeout - * The timeout in nanoseconds, this is used to determine how long DDS should wait for new messages - * to arrive before returning the result. + * The timeout in nanoseconds, this is used to determine how long DDS + * should wait for new messages to arrive before returning the result. * This is an input parameter. * @param transaction_id - * The transaction_id, each time a message is read an unique transaction_id is generated for it. + * The transaction_id, each time a message is read an unique + * transaction_id is generated for it. * This is an output parameter. * @param message - * The message that is read by DDS + * The message that is read by DDS. * This is an output parameter. * @param message_type_id * The message_type_id for DDS this parameter is not relevant. @@ -62,7 +66,7 @@ public class DataTypeTS extends TS { * The message_type_id for DDS this parameter is not relevant. * This is an output parameter. * @param return_code - * The return_code + * The return_code. * This is an output parameter. */ public static void Receive_Message(long connection_id, long timeout, @@ -73,7 +77,8 @@ public static void Receive_Message(long connection_id, long timeout, /** * The Send_Message Function is used to send data to another source. - * This needs to be called on the generated type interface without using the TS Interface. + * This needs to be called on the generated type interface without using + * the TS Interface. * * Possible return codes: *
      @@ -96,17 +101,21 @@ public static void Receive_Message(long connection_id, long timeout, *
    * * @param connection_id - * The connection_id which is used to get the connection where to send messages to. + * The connection_id which is used to get the connection where to + * send messages to. * This is an input parameter. * @param timeout - * The timeout in nanoseconds, this is used to determine how long DDS at maximum can wait to send the message. - * This timeout cannot be greater than max_blocking_time of the supplied DataWriter QoS. + * The timeout in nanoseconds, this is used to determine how long DDS + * at maximum can wait to send the message. + * This timeout cannot be greater than max_blocking_time of the + * supplied DataWriter QoS. * This is an input parameter. * @param transaction_id - * The transaction_id, each time a message is send an unique transaction_id is generated for it. + * The transaction_id, each time a message is send an unique + * transaction_id is generated for it. * This is an output parameter. * @param message - * The message that is read by DDS + * The message that is read by DDS. * This is an output parameter. * @param message_type_id * The message_type_id for DDS this parameter is not relevant. @@ -115,7 +124,7 @@ public static void Receive_Message(long connection_id, long timeout, * The message_type_id for DDS this parameter is not relevant. * This is an output parameter. * @param return_code - * The return_code + * The return_code. * This is an output parameter. */ public static void Send_Message(long connection_id, long timeout, @@ -127,8 +136,9 @@ public static void Send_Message(long connection_id, long timeout, } /** - * The purpose of Register_Callback is to provide a mechanism to read data without polling. - * This needs to be called on the generated type interface without using the TS Interface. + * The purpose of Register_Callback is to provide a mechanism to read data + * without polling. This needs to be called on the generated type interface + * without using the TS Interface. * There can only be one callback registration per connection_id. * * Possible return codes: @@ -163,19 +173,24 @@ public static void Send_Message(long connection_id, long timeout, *

    * * @param connection_id - * The connection_id of the connection that needs to be used for the callback. + * The connection_id of the connection that needs to be used for the + * callback. * This is an input parameter. * @param waitset * The waitset for DDS this parameter is not relevant. * This is an input parameter. * @param data_callback - * The data_callback class in which an action can be set on how to react when receiving data. - * This data_callback is the external operation (interface, which must be implemented by the application see example) - * that is called by the FACE API when new data is available for this connection. + * The data_callback class in which an action can be set on how to + * react when receiving data. + * This data_callback is the external operation (interface, which + * must be implemented by the application see example) + * that is called by the FACE API when new data is available for + * this connection. * This is an input parameter. * @param max_message_size - * The max_message_size for DDS this parameter is not relevant however the max_message_size supplied - * needs to be less then the max_message_size of the configured connection. + * The max_message_size for DDS this parameter is not relevant however + * the max_message_size supplied needs to be less then the + * max_message_size of the configured connection. * This is an input parameter. * @param return_code the return_code * This is an output parameter. @@ -183,6 +198,5 @@ public static void Send_Message(long connection_id, long timeout, public static void Register_Callback(long connection_id, boolean[] waitset, DataTypeRead_CallbackHolder data_callback, int max_message_size, FACE.RETURN_CODE_TYPEHolder return_code) { - } } diff --git a/src/api/face/java/doc/EXAMPLES.md b/src/api/face/java/doc/EXAMPLES.md index 26b911ca2..73ea5762f 100644 --- a/src/api/face/java/doc/EXAMPLES.md +++ b/src/api/face/java/doc/EXAMPLES.md @@ -6,7 +6,7 @@ Examples FACE Examples {#face_examples_dcpslist} ============= -The examples source code can be found in the examples folder of your OpenSplice installation. +The examples source code can be found in the examples folder of your Vortex OpenSplice installation. The descriptions below summarize what each example demonstrates. Towards the bottom of the page you will find instructions on how to build and run the examples. @@ -21,7 +21,7 @@ Building the examples {#face_build_exa ========================================= In the following sections `$OSPL_HOME` identifies the installation directory of -OpenSplice. *Note* it is not however required that this be exported as a variable +Vortex OpenSplice. *Note* it is not however required that this be exported as a variable in the shell environment. In order to build and or run applications that use face the library `ddsface.jar` need to be in the classPath. @@ -33,11 +33,11 @@ POSIX: ### General posix build/run environment setup {#posixgeneral} In the following examples `$OSPL_HOME` identifies the installation directory of -OpenSplice. *Note* it is not however required that this be exported as a variable +Vortex OpenSplice. *Note* it is not however required that this be exported as a variable in the shell environment. A script `release.com` is provided. It exports a value of `OSPL_URI` to indicate -the file `$OSPL_HOME/etc/config/ospl.xml` and also makes the OpenSplice libraries +the file `$OSPL_HOME/etc/config/ospl.xml` and also makes the Vortex OpenSplice libraries available on the library load path. ### Building a single example @@ -65,14 +65,14 @@ Windows: ### General windows build/run environment setup {#windowsgeneral} In the following examples `%%OSPL_HOME%` identifies the installation directory of -OpenSplice. *Note* it is not however required that this be set as a variable +Vortex OpenSplice. *Note* it is not however required that this be set as a variable in the console environment. A script `release.bat` is provided. It exports a value of `OSPL_URI` to indicate -the file `%%OSPL_HOME%\etc\config\ospl.xml` and also makes the OpenSplice +the file `%%OSPL_HOME%\etc\config\ospl.xml` and also makes the Vortex OpenSplice executables and dynamic-link libraries available on the `PATH`. -A shortcut within the OpenSplice HDE folder on the Start Menu: **OpenSplice DDS +A shortcut within the Vortex OpenSplice HDE folder on the Start Menu: **Vortex OpenSplice command prompt** creates a `cmd.exe` console session with this environment ready set. @@ -80,7 +80,7 @@ set. Change directory to the example source directory and `make`. E.g.: - open the OpenSplice DDS command prompt + open the Vortex OpenSplice command prompt "<<< OpenSplice HDE Release V6.6.4 For x86_64.win64, Date 2016-08-01 >>>" cd examples\face\HelloWorld\java BUILD_java.bat @@ -90,7 +90,7 @@ Change directory to the example source directory and `make`. E.g.: The top-level makefile `Makefile.All_Java` can be used to build all the examples. - open the OpenSplice DDS command prompt + open the Vortex OpenSplice command prompt "<<< OpenSplice HDE Release V6.6.4 For x86_64.win64, Date 2016-08-01 >>>" cd examples BUILD_All_Java.bat @@ -134,7 +134,7 @@ Windows: To run an example in _single process_ mode: - open the OpenSplice DDS command prompt + open the Vortex OpenSplice command prompt "<<< OpenSplice HDE Release V6.6.4 For x86_64.win64, Date 2016-08-01 >>>" cd examples\face\HelloWorld\java start /b java -classpath "%OSPL_HOME%\jar\ddsface.jar";classes HelloWorldDataSubscriber @@ -143,7 +143,7 @@ To run an example in _single process_ mode: To run an example in _shared memory_ mode you might do: - open the OpenSplice DDS command prompt + open the Vortex OpenSplice command prompt "<<< OpenSplice HDE Release V6.6.4 For x86_64.win64, Date 2016-08-01 >>>" set OSPL_URI=file://%OSPL_HOME%\etc\config\ospl_shmem_ddsi.xml cd examples\face\HelloWorld\java diff --git a/src/api/streams/ccpp/code/ccpp_StreamDataReader_impl.cpp b/src/api/streams/ccpp/code/ccpp_StreamDataReader_impl.cpp index ae4ebde56..10dcd3924 100644 --- a/src/api/streams/ccpp/code/ccpp_StreamDataReader_impl.cpp +++ b/src/api/streams/ccpp/code/ccpp_StreamDataReader_impl.cpp @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/streams/ccpp/code/ccpp_StreamDataWriter_impl.cpp b/src/api/streams/ccpp/code/ccpp_StreamDataWriter_impl.cpp index 9ea891947..9b4e459b7 100644 --- a/src/api/streams/ccpp/code/ccpp_StreamDataWriter_impl.cpp +++ b/src/api/streams/ccpp/code/ccpp_StreamDataWriter_impl.cpp @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/streams/ccpp/code/ccpp_StreamsUtils.cpp b/src/api/streams/ccpp/code/ccpp_StreamsUtils.cpp index 5cc88ca89..83c06c1ca 100644 --- a/src/api/streams/ccpp/code/ccpp_StreamsUtils.cpp +++ b/src/api/streams/ccpp/code/ccpp_StreamsUtils.cpp @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/streams/ccpp/include/ccpp_StreamDataReader_impl.h b/src/api/streams/ccpp/include/ccpp_StreamDataReader_impl.h index 408e5379b..12adf467e 100644 --- a/src/api/streams/ccpp/include/ccpp_StreamDataReader_impl.h +++ b/src/api/streams/ccpp/include/ccpp_StreamDataReader_impl.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/streams/ccpp/include/ccpp_StreamDataWriter_impl.h b/src/api/streams/ccpp/include/ccpp_StreamDataWriter_impl.h index 1c17c99ff..a9b82dca3 100644 --- a/src/api/streams/ccpp/include/ccpp_StreamDataWriter_impl.h +++ b/src/api/streams/ccpp/include/ccpp_StreamDataWriter_impl.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/streams/ccpp/include/ccpp_StreamsUtils.h b/src/api/streams/ccpp/include/ccpp_StreamsUtils.h index 280c87ad3..166f1172a 100644 --- a/src/api/streams/ccpp/include/ccpp_StreamsUtils.h +++ b/src/api/streams/ccpp/include/ccpp_StreamsUtils.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/streams/ccpp/include/ccpp_streamsT_impl.h b/src/api/streams/ccpp/include/ccpp_streamsT_impl.h index 75d9840fb..a932a4b7b 100644 --- a/src/api/streams/ccpp/include/ccpp_streamsT_impl.h +++ b/src/api/streams/ccpp/include/ccpp_streamsT_impl.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -420,13 +421,12 @@ namespace DDS { result = ws->detach_condition(qc.in()); assert(result == DDS::RETCODE_OK || result == DDS::RETCODE_ALREADY_DELETED); + result = ws->detach_condition(gc.in()); + assert(result == DDS::RETCODE_OK); if (tmp) { result = tmp->delete_readcondition(qc.in()); assert(result == DDS::RETCODE_OK); } - result = ws->detach_condition(gc.in()); - (void)result; - assert(result == DDS::RETCODE_OK); /* Satisfy compiler when building release. */ OS_UNUSED_ARG(result); } diff --git a/src/api/streams/ccpp/include/ccpp_streams_if.h b/src/api/streams/ccpp/include/ccpp_streams_if.h index 27989742a..2758eb73c 100644 --- a/src/api/streams/ccpp/include/ccpp_streams_if.h +++ b/src/api/streams/ccpp/include/ccpp_streams_if.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/streams/ccpp/include/streams_dcpsSplDcps.h b/src/api/streams/ccpp/include/streams_dcpsSplDcps.h index 6ae5c2388..67d1db4bb 100644 --- a/src/api/streams/ccpp/include/streams_dcpsSplDcps.h +++ b/src/api/streams/ccpp/include/streams_dcpsSplDcps.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/streams/ccpp/orb/DDS_ACE_TAO_1_4_1/streams_ccpp.h b/src/api/streams/ccpp/orb/DDS_ACE_TAO_1_4_1/streams_ccpp.h index 2f2433e9d..beb70f0ba 100644 --- a/src/api/streams/ccpp/orb/DDS_ACE_TAO_1_4_1/streams_ccpp.h +++ b/src/api/streams/ccpp/orb/DDS_ACE_TAO_1_4_1/streams_ccpp.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/streams/ccpp/orb/DDS_ACE_TAO_5_6_6/streams_ccpp.h b/src/api/streams/ccpp/orb/DDS_ACE_TAO_5_6_6/streams_ccpp.h index 2f2433e9d..beb70f0ba 100644 --- a/src/api/streams/ccpp/orb/DDS_ACE_TAO_5_6_6/streams_ccpp.h +++ b/src/api/streams/ccpp/orb/DDS_ACE_TAO_5_6_6/streams_ccpp.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/streams/ccpp/orb/DDS_Eorb_3_0/streams_ccpp.h b/src/api/streams/ccpp/orb/DDS_Eorb_3_0/streams_ccpp.h index 04aafad77..4d64d0608 100644 --- a/src/api/streams/ccpp/orb/DDS_Eorb_3_0/streams_ccpp.h +++ b/src/api/streams/ccpp/orb/DDS_Eorb_3_0/streams_ccpp.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/streams/ccpp/orb/DDS_Mico_2_3_11/streams_ccpp.h b/src/api/streams/ccpp/orb/DDS_Mico_2_3_11/streams_ccpp.h index 04aafad77..4d64d0608 100644 --- a/src/api/streams/ccpp/orb/DDS_Mico_2_3_11/streams_ccpp.h +++ b/src/api/streams/ccpp/orb/DDS_Mico_2_3_11/streams_ccpp.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/streams/ccpp/orb/DDS_OpenFusion_1_4_1/streams_ccpp.h b/src/api/streams/ccpp/orb/DDS_OpenFusion_1_4_1/streams_ccpp.h index 2f2433e9d..beb70f0ba 100644 --- a/src/api/streams/ccpp/orb/DDS_OpenFusion_1_4_1/streams_ccpp.h +++ b/src/api/streams/ccpp/orb/DDS_OpenFusion_1_4_1/streams_ccpp.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/streams/ccpp/orb/DDS_OpenFusion_1_5_1/streams_ccpp.h b/src/api/streams/ccpp/orb/DDS_OpenFusion_1_5_1/streams_ccpp.h index 2f2433e9d..beb70f0ba 100644 --- a/src/api/streams/ccpp/orb/DDS_OpenFusion_1_5_1/streams_ccpp.h +++ b/src/api/streams/ccpp/orb/DDS_OpenFusion_1_5_1/streams_ccpp.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/streams/ccpp/orb/DDS_OpenFusion_1_6_1/streams_ccpp.h b/src/api/streams/ccpp/orb/DDS_OpenFusion_1_6_1/streams_ccpp.h index 2f2433e9d..beb70f0ba 100644 --- a/src/api/streams/ccpp/orb/DDS_OpenFusion_1_6_1/streams_ccpp.h +++ b/src/api/streams/ccpp/orb/DDS_OpenFusion_1_6_1/streams_ccpp.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/streams/ccpp/orb/DDS_OpenFusion_2/streams_ccpp.h b/src/api/streams/ccpp/orb/DDS_OpenFusion_2/streams_ccpp.h index 2f2433e9d..beb70f0ba 100644 --- a/src/api/streams/ccpp/orb/DDS_OpenFusion_2/streams_ccpp.h +++ b/src/api/streams/ccpp/orb/DDS_OpenFusion_2/streams_ccpp.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/streams/isocpp/code/dds/streams/core/policy/CorePolicy.cpp b/src/api/streams/isocpp/code/dds/streams/core/policy/CorePolicy.cpp index 78179641e..99c6fbe0c 100644 --- a/src/api/streams/isocpp/code/dds/streams/core/policy/CorePolicy.cpp +++ b/src/api/streams/isocpp/code/dds/streams/core/policy/CorePolicy.cpp @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/streams/isocpp/code/org/opensplice/streams/core/policy/DefaultQos.cpp b/src/api/streams/isocpp/code/org/opensplice/streams/core/policy/DefaultQos.cpp index 99f6491ee..3c8b4a79e 100644 --- a/src/api/streams/isocpp/code/org/opensplice/streams/core/policy/DefaultQos.cpp +++ b/src/api/streams/isocpp/code/org/opensplice/streams/core/policy/DefaultQos.cpp @@ -1,10 +1,11 @@ #ifndef ORG_OPENSPLICE_STREAMS_CORE_POLICY_DEFAULTQOS_CPP_ #define ORG_OPENSPLICE_STREAMS_CORE_POLICY_DEFAULTQOS_CPP_ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/streams/isocpp/code/org/opensplice/streams/pub/qos/StreamDataWriterQosImpl.cpp b/src/api/streams/isocpp/code/org/opensplice/streams/pub/qos/StreamDataWriterQosImpl.cpp index 063fe0a7c..b0b834ac4 100644 --- a/src/api/streams/isocpp/code/org/opensplice/streams/pub/qos/StreamDataWriterQosImpl.cpp +++ b/src/api/streams/isocpp/code/org/opensplice/streams/pub/qos/StreamDataWriterQosImpl.cpp @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/streams/isocpp/code/org/opensplice/streams/sub/qos/StreamDataReaderQosImpl.cpp b/src/api/streams/isocpp/code/org/opensplice/streams/sub/qos/StreamDataReaderQosImpl.cpp index 0b5a722b3..c44e1f384 100644 --- a/src/api/streams/isocpp/code/org/opensplice/streams/sub/qos/StreamDataReaderQosImpl.cpp +++ b/src/api/streams/isocpp/code/org/opensplice/streams/sub/qos/StreamDataReaderQosImpl.cpp @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/streams/isocpp/include/dds/streams/core/policy/CorePolicy.hpp b/src/api/streams/isocpp/include/dds/streams/core/policy/CorePolicy.hpp index e9beaea2d..7c84d87a2 100644 --- a/src/api/streams/isocpp/include/dds/streams/core/policy/CorePolicy.hpp +++ b/src/api/streams/isocpp/include/dds/streams/core/policy/CorePolicy.hpp @@ -2,10 +2,11 @@ #define OSPL_DDS_STREAMS_CORE_POLICY_COREPOLICY_HPP_ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/streams/isocpp/include/dds/streams/core/policy/TCorePolicy.hpp b/src/api/streams/isocpp/include/dds/streams/core/policy/TCorePolicy.hpp index 871ebf8d4..4272a615f 100644 --- a/src/api/streams/isocpp/include/dds/streams/core/policy/TCorePolicy.hpp +++ b/src/api/streams/isocpp/include/dds/streams/core/policy/TCorePolicy.hpp @@ -2,10 +2,11 @@ #define OSPL_DDS_STREAMS_CORE_POLICY_TCOREPOLICY_HPP_ /* -* OpenSplice DDS +* Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/streams/isocpp/include/dds/streams/core/policy/detail/CorePolicy.hpp b/src/api/streams/isocpp/include/dds/streams/core/policy/detail/CorePolicy.hpp index 7c0c0742d..1dee5b056 100644 --- a/src/api/streams/isocpp/include/dds/streams/core/policy/detail/CorePolicy.hpp +++ b/src/api/streams/isocpp/include/dds/streams/core/policy/detail/CorePolicy.hpp @@ -2,10 +2,11 @@ #define OSPL_DDS_STREAMS_CORE_POLICY_DETAIL_COREPOLICY_HPP_ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/streams/isocpp/include/dds/streams/core/streamscore.hpp b/src/api/streams/isocpp/include/dds/streams/core/streamscore.hpp index ec1d253fc..570cdd95e 100644 --- a/src/api/streams/isocpp/include/dds/streams/core/streamscore.hpp +++ b/src/api/streams/isocpp/include/dds/streams/core/streamscore.hpp @@ -1,10 +1,11 @@ #ifndef STREAMSCORE_HPP #define STREAMSCORE_HPP /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/streams/isocpp/include/dds/streams/pub/StreamDataWriter.hpp b/src/api/streams/isocpp/include/dds/streams/pub/StreamDataWriter.hpp index 29ca59889..d7b58368d 100644 --- a/src/api/streams/isocpp/include/dds/streams/pub/StreamDataWriter.hpp +++ b/src/api/streams/isocpp/include/dds/streams/pub/StreamDataWriter.hpp @@ -1,10 +1,11 @@ #ifndef DDS_STREAMS_PUB_STREAMDATAWRITER_HPP_ #define DDS_STREAMS_PUB_STREAMDATAWRITER_HPP_ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/streams/isocpp/include/dds/streams/pub/detail/StreamDataWriter.hpp b/src/api/streams/isocpp/include/dds/streams/pub/detail/StreamDataWriter.hpp index bcd7394b8..9e7bc2ecf 100644 --- a/src/api/streams/isocpp/include/dds/streams/pub/detail/StreamDataWriter.hpp +++ b/src/api/streams/isocpp/include/dds/streams/pub/detail/StreamDataWriter.hpp @@ -1,10 +1,11 @@ #ifndef DDS_STREAMS_PUB_DETAIL_STREAMDATAWRITER_HPP_ #define DDS_STREAMS_PUB_DETAIL_STREAMDATAWRITER_HPP_ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/streams/isocpp/include/dds/streams/pub/qos/StreamDataWriterQos.hpp b/src/api/streams/isocpp/include/dds/streams/pub/qos/StreamDataWriterQos.hpp index ff4fbc5a9..486706a6d 100644 --- a/src/api/streams/isocpp/include/dds/streams/pub/qos/StreamDataWriterQos.hpp +++ b/src/api/streams/isocpp/include/dds/streams/pub/qos/StreamDataWriterQos.hpp @@ -2,10 +2,11 @@ #define DDS_STREAMS_PUB_QOS_STREAM_DATA_WRITER_QOS_HPP_ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/streams/isocpp/include/dds/streams/pub/qos/detail/StreamDataWriterQos.hpp b/src/api/streams/isocpp/include/dds/streams/pub/qos/detail/StreamDataWriterQos.hpp index 8660680e7..304739b92 100644 --- a/src/api/streams/isocpp/include/dds/streams/pub/qos/detail/StreamDataWriterQos.hpp +++ b/src/api/streams/isocpp/include/dds/streams/pub/qos/detail/StreamDataWriterQos.hpp @@ -1,10 +1,11 @@ #ifndef DDS_STREAMS_PUB_QOS_DETAIL_STREAM_DATA_WRITER_QOS_HPP_ #define DDS_STREAMS_PUB_QOS_DETAIL_STREAM_DATA_WRITER_QOS_HPP_ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/streams/isocpp/include/dds/streams/pub/streamspub.hpp b/src/api/streams/isocpp/include/dds/streams/pub/streamspub.hpp index ae8c75311..c38f02d43 100644 --- a/src/api/streams/isocpp/include/dds/streams/pub/streamspub.hpp +++ b/src/api/streams/isocpp/include/dds/streams/pub/streamspub.hpp @@ -1,10 +1,11 @@ #ifndef STREAMSPUB_HPP #define STREAMSPUB_HPP /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/streams/isocpp/include/dds/streams/streams.hpp b/src/api/streams/isocpp/include/dds/streams/streams.hpp index 9bb82c7aa..3fbda69cc 100644 --- a/src/api/streams/isocpp/include/dds/streams/streams.hpp +++ b/src/api/streams/isocpp/include/dds/streams/streams.hpp @@ -1,10 +1,11 @@ #ifndef STREAMS_HPP #define STREAMS_HPP /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/streams/isocpp/include/dds/streams/sub/StreamDataReader.hpp b/src/api/streams/isocpp/include/dds/streams/sub/StreamDataReader.hpp index 0802fc222..867299bf7 100644 --- a/src/api/streams/isocpp/include/dds/streams/sub/StreamDataReader.hpp +++ b/src/api/streams/isocpp/include/dds/streams/sub/StreamDataReader.hpp @@ -1,10 +1,11 @@ #ifndef DDS_STREAMS_SUB_DATAREADER_HPP_ #define DDS_STREAMS_SUB_DATAREADER_HPP_ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/streams/isocpp/include/dds/streams/sub/StreamLoanedSamples.hpp b/src/api/streams/isocpp/include/dds/streams/sub/StreamLoanedSamples.hpp index b1c36a4ea..4376d0e00 100644 --- a/src/api/streams/isocpp/include/dds/streams/sub/StreamLoanedSamples.hpp +++ b/src/api/streams/isocpp/include/dds/streams/sub/StreamLoanedSamples.hpp @@ -1,10 +1,11 @@ #ifndef DDS_STREAM_SUB_STREAMLOANEDSAMPLES_HPP_ #define DDS_STREAM_SUB_STREAMLOANEDSAMPLES_HPP_ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/streams/isocpp/include/dds/streams/sub/StreamSample.hpp b/src/api/streams/isocpp/include/dds/streams/sub/StreamSample.hpp index 9e83a634a..a53916b28 100644 --- a/src/api/streams/isocpp/include/dds/streams/sub/StreamSample.hpp +++ b/src/api/streams/isocpp/include/dds/streams/sub/StreamSample.hpp @@ -1,10 +1,11 @@ #ifndef DDS_STREAMS_SUB_STREAMSAMPLE_HPP_ #define DDS_STREAMS_SUB_STREAMSAMPLE_HPP_ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/streams/isocpp/include/dds/streams/sub/StreamSharedSamples.hpp b/src/api/streams/isocpp/include/dds/streams/sub/StreamSharedSamples.hpp index 97a4a9276..fbe8cb0d8 100644 --- a/src/api/streams/isocpp/include/dds/streams/sub/StreamSharedSamples.hpp +++ b/src/api/streams/isocpp/include/dds/streams/sub/StreamSharedSamples.hpp @@ -1,10 +1,11 @@ #ifndef DDS_STREAMS_SUB_STREAMSHAREDSAMPLES_HPP_ #define DDS_STREAMS_SUB_STREAMSHAREDSAMPLES_HPP_ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/streams/isocpp/include/dds/streams/sub/TStreamDataReader.hpp b/src/api/streams/isocpp/include/dds/streams/sub/TStreamDataReader.hpp index 214e5c53a..c0b7f1c19 100644 --- a/src/api/streams/isocpp/include/dds/streams/sub/TStreamDataReader.hpp +++ b/src/api/streams/isocpp/include/dds/streams/sub/TStreamDataReader.hpp @@ -1,10 +1,11 @@ #ifndef DDS_STREAMS_SUB_TDATAREADER_HPP_ #define DDS_STREAMS_SUB_TDATAREADER_HPP_ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/streams/isocpp/include/dds/streams/sub/TStreamSample.hpp b/src/api/streams/isocpp/include/dds/streams/sub/TStreamSample.hpp index c5015866c..8213b064a 100644 --- a/src/api/streams/isocpp/include/dds/streams/sub/TStreamSample.hpp +++ b/src/api/streams/isocpp/include/dds/streams/sub/TStreamSample.hpp @@ -1,10 +1,11 @@ #ifndef DDS_STREAMS_SUB_TSTREAMSAMPLE_HPP_ #define DDS_STREAMS_SUB_TSTREAMSAMPLE_HPP_ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/streams/isocpp/include/dds/streams/sub/detail/StreamDataReader.hpp b/src/api/streams/isocpp/include/dds/streams/sub/detail/StreamDataReader.hpp index 24caa199e..0b4c4ed0c 100644 --- a/src/api/streams/isocpp/include/dds/streams/sub/detail/StreamDataReader.hpp +++ b/src/api/streams/isocpp/include/dds/streams/sub/detail/StreamDataReader.hpp @@ -1,10 +1,11 @@ #ifndef DDS_STREAMS_SUB_DETAIL_STREAMDATAREADER_HPP_ #define DDS_STREAMS_SUB_DETAIL_STREAMDATAREADER_HPP_ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/streams/isocpp/include/dds/streams/sub/detail/StreamLoanedSamples.hpp b/src/api/streams/isocpp/include/dds/streams/sub/detail/StreamLoanedSamples.hpp index dc6f8e58e..4b7377206 100644 --- a/src/api/streams/isocpp/include/dds/streams/sub/detail/StreamLoanedSamples.hpp +++ b/src/api/streams/isocpp/include/dds/streams/sub/detail/StreamLoanedSamples.hpp @@ -1,10 +1,11 @@ #ifndef DDS_STREAMS_SUB_DETAIL_STREAMLOANEDSAMPLES_HPP_ #define DDS_STREAMS_SUB_DETAIL_STREAMLOANEDSAMPLES_HPP_ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/streams/isocpp/include/dds/streams/sub/detail/StreamSample.hpp b/src/api/streams/isocpp/include/dds/streams/sub/detail/StreamSample.hpp index 59df6e66b..a6647ef8a 100644 --- a/src/api/streams/isocpp/include/dds/streams/sub/detail/StreamSample.hpp +++ b/src/api/streams/isocpp/include/dds/streams/sub/detail/StreamSample.hpp @@ -1,10 +1,11 @@ #ifndef DDS_STREAMS_SUB_DETAIL_STREAMSAMPLE_HPP_ #define DDS_STREAMS_SUB_DETAIL_STREAMSAMPLE_HPP_ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/streams/isocpp/include/dds/streams/sub/detail/StreamSharedSamples.hpp b/src/api/streams/isocpp/include/dds/streams/sub/detail/StreamSharedSamples.hpp index 3f704d8ec..0d7c1547b 100644 --- a/src/api/streams/isocpp/include/dds/streams/sub/detail/StreamSharedSamples.hpp +++ b/src/api/streams/isocpp/include/dds/streams/sub/detail/StreamSharedSamples.hpp @@ -1,10 +1,11 @@ #ifndef DDS_STREAMS_SUB_DETAIL_STREAMSHAREDSAMPLES_HPP_ #define DDS_STREAMS_SUB_DETAIL_STREAMSHAREDSAMPLES_HPP_ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/streams/isocpp/include/dds/streams/sub/qos/StreamDataReaderQos.hpp b/src/api/streams/isocpp/include/dds/streams/sub/qos/StreamDataReaderQos.hpp index 2e834dfb0..5b235036a 100644 --- a/src/api/streams/isocpp/include/dds/streams/sub/qos/StreamDataReaderQos.hpp +++ b/src/api/streams/isocpp/include/dds/streams/sub/qos/StreamDataReaderQos.hpp @@ -2,10 +2,11 @@ #define DDS_STREAMS_SUB_QOS_STREAM_DATA_READER_QOS_HPP_ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/streams/isocpp/include/dds/streams/sub/qos/detail/StreamDataReaderQos.hpp b/src/api/streams/isocpp/include/dds/streams/sub/qos/detail/StreamDataReaderQos.hpp index 627310383..2560a2293 100644 --- a/src/api/streams/isocpp/include/dds/streams/sub/qos/detail/StreamDataReaderQos.hpp +++ b/src/api/streams/isocpp/include/dds/streams/sub/qos/detail/StreamDataReaderQos.hpp @@ -1,10 +1,11 @@ #ifndef DDS_STREAMS_SUB_QOS_DETAIL_STREAM_DATA_READER_QOS_HPP_ #define DDS_STREAMS_SUB_QOS_DETAIL_STREAM_DATA_READER_QOS_HPP_ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/streams/isocpp/include/dds/streams/sub/streamssub.hpp b/src/api/streams/isocpp/include/dds/streams/sub/streamssub.hpp index 51ee4dd42..d897d96f4 100644 --- a/src/api/streams/isocpp/include/dds/streams/sub/streamssub.hpp +++ b/src/api/streams/isocpp/include/dds/streams/sub/streamssub.hpp @@ -1,10 +1,11 @@ #ifndef STREAMSSUB_HPP #define STREAMSSUB_HPP /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/streams/isocpp/include/org/EXAMPLES.md b/src/api/streams/isocpp/include/org/EXAMPLES.md index d52498a48..d913adcd6 100644 --- a/src/api/streams/isocpp/include/org/EXAMPLES.md +++ b/src/api/streams/isocpp/include/org/EXAMPLES.md @@ -108,7 +108,7 @@ A script `release.bat` is provided. It exports a value of `OSPL_URI` to indicate the file `%%OSPL_HOME%\etc\config\ospl.xml` and also makes the OpenSplice executables and dynamic-link libraries available on the `PATH`. -A shortcut within the OpenSplice HDE folder on the Start Menu: **OpenSplice DDS +A shortcut within the OpenSplice HDE folder on the Start Menu: **Vortex OpenSplice command prompt** creates a `cmd.exe` console session with this environment ready set. diff --git a/src/api/streams/isocpp/include/org/opensplice/streams/core/module_docs.hpp b/src/api/streams/isocpp/include/org/opensplice/streams/core/module_docs.hpp index 116d8fb8e..2dea817ec 100644 --- a/src/api/streams/isocpp/include/org/opensplice/streams/core/module_docs.hpp +++ b/src/api/streams/isocpp/include/org/opensplice/streams/core/module_docs.hpp @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/streams/isocpp/include/org/opensplice/streams/core/policy/CorePolicy.hpp b/src/api/streams/isocpp/include/org/opensplice/streams/core/policy/CorePolicy.hpp index c7e233cf3..997d8a3bd 100644 --- a/src/api/streams/isocpp/include/org/opensplice/streams/core/policy/CorePolicy.hpp +++ b/src/api/streams/isocpp/include/org/opensplice/streams/core/policy/CorePolicy.hpp @@ -2,10 +2,11 @@ #define ORG_OPENSPLICE_STREAMS_CORE_POLICY_CORE_POLICY_IMPL_HPP_ /* -* OpenSplice DDS +* Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/streams/isocpp/include/org/opensplice/streams/core/policy/DefaultQos.hpp b/src/api/streams/isocpp/include/org/opensplice/streams/core/policy/DefaultQos.hpp index d83f829a6..6702e288a 100644 --- a/src/api/streams/isocpp/include/org/opensplice/streams/core/policy/DefaultQos.hpp +++ b/src/api/streams/isocpp/include/org/opensplice/streams/core/policy/DefaultQos.hpp @@ -1,10 +1,11 @@ #ifndef ORG_OPENSPLICE_STREAMS_CORE_POLICY_DEFAULTQOS_HPP_ #define ORG_OPENSPLICE_STREAMS_CORE_POLICY_DEFAULTQOS_HPP_ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/streams/isocpp/include/org/opensplice/streams/pub/qos/StreamDataWriterQosImpl.hpp b/src/api/streams/isocpp/include/org/opensplice/streams/pub/qos/StreamDataWriterQosImpl.hpp index 4c695ecbb..c25d31c6a 100644 --- a/src/api/streams/isocpp/include/org/opensplice/streams/pub/qos/StreamDataWriterQosImpl.hpp +++ b/src/api/streams/isocpp/include/org/opensplice/streams/pub/qos/StreamDataWriterQosImpl.hpp @@ -1,10 +1,11 @@ #ifndef ORG_OPENSPLICE_STREAMS_PUB_QOS_STREAM_DATA_WRITER_QOS_HPP_ #define ORG_OPENSPLICE_STREAMS_PUB_QOS_STREAM_DATA_WRITER_QOS_HPP_ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/streams/isocpp/include/org/opensplice/streams/sub/qos/StreamDataReaderQosImpl.hpp b/src/api/streams/isocpp/include/org/opensplice/streams/sub/qos/StreamDataReaderQosImpl.hpp index 77924dd80..f4e348f1c 100644 --- a/src/api/streams/isocpp/include/org/opensplice/streams/sub/qos/StreamDataReaderQosImpl.hpp +++ b/src/api/streams/isocpp/include/org/opensplice/streams/sub/qos/StreamDataReaderQosImpl.hpp @@ -1,10 +1,11 @@ #ifndef ORG_OPENSPLICE_STREAMS_SUB_QOS_STREAM_DATA_READER_QOS_HPP_ #define ORG_OPENSPLICE_STREAMS_SUB_QOS_STREAM_DATA_READER_QOS_HPP_ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/streams/isocpp/include/org/opensplice/streams/topic/TopicTraits.hpp b/src/api/streams/isocpp/include/org/opensplice/streams/topic/TopicTraits.hpp index ac893aba3..9b5f90753 100644 --- a/src/api/streams/isocpp/include/org/opensplice/streams/topic/TopicTraits.hpp +++ b/src/api/streams/isocpp/include/org/opensplice/streams/topic/TopicTraits.hpp @@ -1,10 +1,11 @@ #ifndef ORG_OPENSPLICE_STREAMS_TOPIC_TOPICTRAITS_HPP_ #define ORG_OPENSPLICE_STREAMS_TOPIC_TOPICTRAITS_HPP_ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/streams/isocpp/include/spec/dds/streams/core/policy/CorePolicy.hpp b/src/api/streams/isocpp/include/spec/dds/streams/core/policy/CorePolicy.hpp index 7fc8deee6..650ba3782 100644 --- a/src/api/streams/isocpp/include/spec/dds/streams/core/policy/CorePolicy.hpp +++ b/src/api/streams/isocpp/include/spec/dds/streams/core/policy/CorePolicy.hpp @@ -2,10 +2,11 @@ #define SPEC_DDS_STREAMS_CORE_POLICY_CORE_POLICY_HPP_ /* -* OpenSplice DDS +* Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/streams/isocpp/include/spec/dds/streams/core/policy/TCorePolicy.hpp b/src/api/streams/isocpp/include/spec/dds/streams/core/policy/TCorePolicy.hpp index dee3d8f4c..cdab5af20 100644 --- a/src/api/streams/isocpp/include/spec/dds/streams/core/policy/TCorePolicy.hpp +++ b/src/api/streams/isocpp/include/spec/dds/streams/core/policy/TCorePolicy.hpp @@ -2,10 +2,11 @@ #define SPEC_DDS_STREAMS_CORE_POLICY_TCORE_POLICY_HPP_ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/streams/isocpp/include/spec/dds/streams/core/policy/detail/CorePolicy.hpp b/src/api/streams/isocpp/include/spec/dds/streams/core/policy/detail/CorePolicy.hpp index 1c1072282..9009bea12 100644 --- a/src/api/streams/isocpp/include/spec/dds/streams/core/policy/detail/CorePolicy.hpp +++ b/src/api/streams/isocpp/include/spec/dds/streams/core/policy/detail/CorePolicy.hpp @@ -2,10 +2,11 @@ #define SPEC_DDS_STREAMS_CORE_POLICY_DETAIL_CORE_POLICY_HPP_ /* -* OpenSplice DDS +* Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/streams/isocpp/include/spec/dds/streams/core/streamscore.hpp b/src/api/streams/isocpp/include/spec/dds/streams/core/streamscore.hpp index af33ec678..6d86c358a 100644 --- a/src/api/streams/isocpp/include/spec/dds/streams/core/streamscore.hpp +++ b/src/api/streams/isocpp/include/spec/dds/streams/core/streamscore.hpp @@ -1,10 +1,11 @@ #ifndef SPEC_STREAMSCORE_HPP #define SPEC_STREAMSCORE_HPP /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/streams/isocpp/include/spec/dds/streams/pub/StreamDataWriter.hpp b/src/api/streams/isocpp/include/spec/dds/streams/pub/StreamDataWriter.hpp index 10e23d3da..890cb1256 100644 --- a/src/api/streams/isocpp/include/spec/dds/streams/pub/StreamDataWriter.hpp +++ b/src/api/streams/isocpp/include/spec/dds/streams/pub/StreamDataWriter.hpp @@ -1,10 +1,11 @@ #ifndef SPEC_DDS_STREAMS_PUB_STREAM_DATA_WRITER_HPP_ #define SPEC_DDS_STREAMS_PUB_STREAM_DATA_WRITER_HPP_ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/streams/isocpp/include/spec/dds/streams/pub/detail/StreamDataWriter.hpp b/src/api/streams/isocpp/include/spec/dds/streams/pub/detail/StreamDataWriter.hpp index 06ccb7bfa..050300cb0 100644 --- a/src/api/streams/isocpp/include/spec/dds/streams/pub/detail/StreamDataWriter.hpp +++ b/src/api/streams/isocpp/include/spec/dds/streams/pub/detail/StreamDataWriter.hpp @@ -1,10 +1,11 @@ #ifndef SPEC_DDS_STREAMS_PUB_DETAIL_STREAM_DATA_WRITER_HPP_ #define SPEC_DDS_STREAMS_PUB_DETAIL_STREAM_DATA_WRITER_HPP_ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/streams/isocpp/include/spec/dds/streams/pub/qos/StreamDataWriterQos.hpp b/src/api/streams/isocpp/include/spec/dds/streams/pub/qos/StreamDataWriterQos.hpp index f104255d8..3ab925a7a 100644 --- a/src/api/streams/isocpp/include/spec/dds/streams/pub/qos/StreamDataWriterQos.hpp +++ b/src/api/streams/isocpp/include/spec/dds/streams/pub/qos/StreamDataWriterQos.hpp @@ -2,10 +2,11 @@ #define SPEC_DDS_STREAMS_QOS_STREAM_DATA_WRITER_QOS_HPP_ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/streams/isocpp/include/spec/dds/streams/pub/qos/detail/StreamDataWriterQos.hpp b/src/api/streams/isocpp/include/spec/dds/streams/pub/qos/detail/StreamDataWriterQos.hpp index 64d580ba2..f8869f633 100644 --- a/src/api/streams/isocpp/include/spec/dds/streams/pub/qos/detail/StreamDataWriterQos.hpp +++ b/src/api/streams/isocpp/include/spec/dds/streams/pub/qos/detail/StreamDataWriterQos.hpp @@ -2,10 +2,11 @@ #define SPEC_DDS_STREAMS_QOS_DETAIL_STREAM_DATA_WRITER_QOS_HPP_ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/streams/isocpp/include/spec/dds/streams/pub/streamspub.hpp b/src/api/streams/isocpp/include/spec/dds/streams/pub/streamspub.hpp index 9b2fa3718..2ce77226d 100644 --- a/src/api/streams/isocpp/include/spec/dds/streams/pub/streamspub.hpp +++ b/src/api/streams/isocpp/include/spec/dds/streams/pub/streamspub.hpp @@ -1,10 +1,11 @@ #ifndef SPEC_STREAMSPUB_HPP #define SPEC_STREAMSPUB_HPP /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/streams/isocpp/include/spec/dds/streams/sub/StreamDataReader.hpp b/src/api/streams/isocpp/include/spec/dds/streams/sub/StreamDataReader.hpp index f4d9674d4..9643b2072 100644 --- a/src/api/streams/isocpp/include/spec/dds/streams/sub/StreamDataReader.hpp +++ b/src/api/streams/isocpp/include/spec/dds/streams/sub/StreamDataReader.hpp @@ -1,10 +1,11 @@ #ifndef SPEC_DDS_STREAMS_SUB_STREAMDATAREADER_HPP_ #define SPEC_DDS_STREAMS_SUB_STREAMDATAREADER_HPP_ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/streams/isocpp/include/spec/dds/streams/sub/StreamLoanedSamples.hpp b/src/api/streams/isocpp/include/spec/dds/streams/sub/StreamLoanedSamples.hpp index 1d193b09a..b6bc253e6 100644 --- a/src/api/streams/isocpp/include/spec/dds/streams/sub/StreamLoanedSamples.hpp +++ b/src/api/streams/isocpp/include/spec/dds/streams/sub/StreamLoanedSamples.hpp @@ -1,10 +1,11 @@ #ifndef SPEC_DDS_STREAMS_SUB_STREAMLOANEDSAMPLES_HPP_ #define SPEC_DDS_STREAMS_SUB_STREAMLOANEDSAMPLES_HPP_ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/streams/isocpp/include/spec/dds/streams/sub/StreamSample.hpp b/src/api/streams/isocpp/include/spec/dds/streams/sub/StreamSample.hpp index f83e0f1a8..ee4bcbaa1 100644 --- a/src/api/streams/isocpp/include/spec/dds/streams/sub/StreamSample.hpp +++ b/src/api/streams/isocpp/include/spec/dds/streams/sub/StreamSample.hpp @@ -1,10 +1,11 @@ #ifndef SPEC_DDS_STREAMS_SUB_STREAMSAMPLE_HPP_ #define SPEC_DDS_STREAMS_SUB_STREAMSAMPLE_HPP_ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/streams/isocpp/include/spec/dds/streams/sub/StreamSharedSamples.hpp b/src/api/streams/isocpp/include/spec/dds/streams/sub/StreamSharedSamples.hpp index 0023c9239..7e8529421 100644 --- a/src/api/streams/isocpp/include/spec/dds/streams/sub/StreamSharedSamples.hpp +++ b/src/api/streams/isocpp/include/spec/dds/streams/sub/StreamSharedSamples.hpp @@ -1,10 +1,11 @@ #ifndef SPEC_DDS_STREAMS_SUB_STREAMS_SHARED_SAMPLES_HPP_ #define SPEC_DDS_STREAMS_SUB_STREAMS_SHARED_SAMPLES_HPP_ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/streams/isocpp/include/spec/dds/streams/sub/TStreamDataReader.hpp b/src/api/streams/isocpp/include/spec/dds/streams/sub/TStreamDataReader.hpp index ec1446802..c9a1ca134 100644 --- a/src/api/streams/isocpp/include/spec/dds/streams/sub/TStreamDataReader.hpp +++ b/src/api/streams/isocpp/include/spec/dds/streams/sub/TStreamDataReader.hpp @@ -1,10 +1,11 @@ #ifndef SPEC_DDS_STREAMS_SUB_TSTREAMDATAREADER_HPP_ #define SPEC_DDS_STREAMS_SUB_TSTREAMDATAREADER_HPP_ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/streams/isocpp/include/spec/dds/streams/sub/TStreamSample.hpp b/src/api/streams/isocpp/include/spec/dds/streams/sub/TStreamSample.hpp index 8777d9090..d79bc97da 100644 --- a/src/api/streams/isocpp/include/spec/dds/streams/sub/TStreamSample.hpp +++ b/src/api/streams/isocpp/include/spec/dds/streams/sub/TStreamSample.hpp @@ -1,10 +1,11 @@ #ifndef SPEC_DDS_STREAMS_SUB_TSTREAMSAMPLE_HPP_ #define SPEC_DDS_STREAMS_SUB_TSTREAMSAMPLE_HPP_ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/streams/isocpp/include/spec/dds/streams/sub/detail/StreamDataReader.hpp b/src/api/streams/isocpp/include/spec/dds/streams/sub/detail/StreamDataReader.hpp index 4f5425894..ccd09d2c3 100644 --- a/src/api/streams/isocpp/include/spec/dds/streams/sub/detail/StreamDataReader.hpp +++ b/src/api/streams/isocpp/include/spec/dds/streams/sub/detail/StreamDataReader.hpp @@ -1,10 +1,11 @@ #ifndef SPEC_DDS_STREAMS_SUB_DETAIL_STREAMDATAREADER_HPP_ #define SPEC_DDS_STREAMS_SUB_DETAIL_STREAMDATAREADER_HPP_ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/streams/isocpp/include/spec/dds/streams/sub/detail/StreamLoanedSamples.hpp b/src/api/streams/isocpp/include/spec/dds/streams/sub/detail/StreamLoanedSamples.hpp index e19c7e045..1b5f75d3b 100644 --- a/src/api/streams/isocpp/include/spec/dds/streams/sub/detail/StreamLoanedSamples.hpp +++ b/src/api/streams/isocpp/include/spec/dds/streams/sub/detail/StreamLoanedSamples.hpp @@ -1,10 +1,11 @@ #ifndef SPEC_DDS_STREAMS_SUB_DETAIL_STREAMLOANEDSAMPLES_HPP_ #define SPEC_DDS_STREAMS_SUB_DETAIL_STREAMLOANEDSAMPLES_HPP_ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/streams/isocpp/include/spec/dds/streams/sub/detail/StreamSample.hpp b/src/api/streams/isocpp/include/spec/dds/streams/sub/detail/StreamSample.hpp index 76e6576b6..8cf9d15e1 100644 --- a/src/api/streams/isocpp/include/spec/dds/streams/sub/detail/StreamSample.hpp +++ b/src/api/streams/isocpp/include/spec/dds/streams/sub/detail/StreamSample.hpp @@ -1,10 +1,11 @@ #ifndef SPEC_DDS_STREAMS_SUB_STREAMSAMPLE_HPP_ #define SPEC_DDS_STREAMS_SUB_STREAMSAMPLE_HPP_ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/streams/isocpp/include/spec/dds/streams/sub/detail/StreamSharedSamples.hpp b/src/api/streams/isocpp/include/spec/dds/streams/sub/detail/StreamSharedSamples.hpp index f78e86827..36fb5660e 100644 --- a/src/api/streams/isocpp/include/spec/dds/streams/sub/detail/StreamSharedSamples.hpp +++ b/src/api/streams/isocpp/include/spec/dds/streams/sub/detail/StreamSharedSamples.hpp @@ -1,10 +1,11 @@ #ifndef SPEC_DDS_SUB_DETAIL_STREAM_SHARED_SAMPLES_HPP_ #define SPEC_DDS_SUB_DETAIL_STREAM_SHARED_SAMPLES_HPP_ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/streams/isocpp/include/spec/dds/streams/sub/qos/StreamDataReaderQos.hpp b/src/api/streams/isocpp/include/spec/dds/streams/sub/qos/StreamDataReaderQos.hpp index 5a56ae2dd..068ba24fd 100644 --- a/src/api/streams/isocpp/include/spec/dds/streams/sub/qos/StreamDataReaderQos.hpp +++ b/src/api/streams/isocpp/include/spec/dds/streams/sub/qos/StreamDataReaderQos.hpp @@ -2,10 +2,11 @@ #define SPEC_DDS_STREAMS_QOS_STREAM_DATA_READER_QOS_HPP_ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/streams/isocpp/include/spec/dds/streams/sub/qos/detail/StreamDataReaderQos.hpp b/src/api/streams/isocpp/include/spec/dds/streams/sub/qos/detail/StreamDataReaderQos.hpp index 87f13b17f..31ffa595c 100644 --- a/src/api/streams/isocpp/include/spec/dds/streams/sub/qos/detail/StreamDataReaderQos.hpp +++ b/src/api/streams/isocpp/include/spec/dds/streams/sub/qos/detail/StreamDataReaderQos.hpp @@ -2,10 +2,11 @@ #define SPEC_DDS_STREAMS_QOS_DETAIL_STREAM_DATA_READER_QOS_HPP_ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/streams/isocpp/include/spec/dds/streams/sub/streamssub.hpp b/src/api/streams/isocpp/include/spec/dds/streams/sub/streamssub.hpp index 2c92380c5..c1cf79678 100644 --- a/src/api/streams/isocpp/include/spec/dds/streams/sub/streamssub.hpp +++ b/src/api/streams/isocpp/include/spec/dds/streams/sub/streamssub.hpp @@ -1,10 +1,11 @@ #ifndef SPEC_STREAMSSUB_HPP #define SPEC_STREAMSSUB_HPP /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/api/streams/sacpp/include/streams_ccpp.h b/src/api/streams/sacpp/include/streams_ccpp.h index 04aafad77..4d64d0608 100644 --- a/src/api/streams/sacpp/include/streams_ccpp.h +++ b/src/api/streams/sacpp/include/streams_ccpp.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/configuration/config/code/cf__nodeList.h b/src/configuration/config/code/cf__nodeList.h index 82c0ccc2d..3a57d3e83 100644 --- a/src/configuration/config/code/cf__nodeList.h +++ b/src/configuration/config/code/cf__nodeList.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/configuration/config/code/cf_attribute.c b/src/configuration/config/code/cf_attribute.c index c90fbcb24..6d9145d10 100644 --- a/src/configuration/config/code/cf_attribute.c +++ b/src/configuration/config/code/cf_attribute.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/configuration/config/code/cf_data.c b/src/configuration/config/code/cf_data.c index 4c2bf67b8..d145c0753 100644 --- a/src/configuration/config/code/cf_data.c +++ b/src/configuration/config/code/cf_data.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/configuration/config/code/cf_element.c b/src/configuration/config/code/cf_element.c index 37e427d1a..0eac478e1 100644 --- a/src/configuration/config/code/cf_element.c +++ b/src/configuration/config/code/cf_element.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/configuration/config/code/cf_node.c b/src/configuration/config/code/cf_node.c index 19f0767b5..a6f50a226 100644 --- a/src/configuration/config/code/cf_node.c +++ b/src/configuration/config/code/cf_node.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/configuration/config/code/cf_nodeList.c b/src/configuration/config/code/cf_nodeList.c index 0547a16a5..32b46d313 100644 --- a/src/configuration/config/code/cf_nodeList.c +++ b/src/configuration/config/code/cf_nodeList.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/configuration/config/include/cf_attribute.h b/src/configuration/config/include/cf_attribute.h index 0bbc6d875..9636b073f 100644 --- a/src/configuration/config/include/cf_attribute.h +++ b/src/configuration/config/include/cf_attribute.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/configuration/config/include/cf_config.h b/src/configuration/config/include/cf_config.h index 5ea258413..78eb8b589 100644 --- a/src/configuration/config/include/cf_config.h +++ b/src/configuration/config/include/cf_config.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/configuration/config/include/cf_data.h b/src/configuration/config/include/cf_data.h index a93a46189..ed75fabe9 100644 --- a/src/configuration/config/include/cf_data.h +++ b/src/configuration/config/include/cf_data.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/configuration/config/include/cf_element.h b/src/configuration/config/include/cf_element.h index 7113e5be3..8b82a8864 100644 --- a/src/configuration/config/include/cf_element.h +++ b/src/configuration/config/include/cf_element.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/configuration/config/include/cf_node.h b/src/configuration/config/include/cf_node.h index 0d734e982..7294a7aeb 100644 --- a/src/configuration/config/include/cf_node.h +++ b/src/configuration/config/include/cf_node.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/configuration/parser/code/cfg_parser.c b/src/configuration/parser/code/cfg_parser.c index 7a4fc9600..c0d7f8fae 100644 --- a/src/configuration/parser/code/cfg_parser.c +++ b/src/configuration/parser/code/cfg_parser.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/configuration/parser/include/cfg_parser.h b/src/configuration/parser/include/cfg_parser.h index 1855e16be..4f29fde59 100644 --- a/src/configuration/parser/include/cfg_parser.h +++ b/src/configuration/parser/include/cfg_parser.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/configuration/validator/code/cfg_metaConfig.c b/src/configuration/validator/code/cfg_metaConfig.c index cd075d281..9f46efd94 100644 --- a/src/configuration/validator/code/cfg_metaConfig.c +++ b/src/configuration/validator/code/cfg_metaConfig.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -797,8 +798,8 @@ cfg_sizeElementCheckValue( { os_boolean valid; os_uint64 value; - valid = stringToSizeValue(str, &value); + if (valid) { if ((value < _this->min) || (value > _this->max)) { valid = OS_FALSE; @@ -1603,9 +1604,7 @@ cfg_elementCheckValue( { os_boolean valid = OS_TRUE; - if (str == NULL) { - return OS_FALSE; - } + assert(str); switch (_this->elementKind) { case CFG_ELEMENT_KIND_BOOLEAN: @@ -1647,9 +1646,7 @@ cfg_attributeCheckValue( { os_boolean valid = OS_TRUE; - if (str == NULL) { - return OS_FALSE; - } + assert(str); switch (_this->attributeKind) { case CFG_ATTRIBUTE_KIND_BOOLEAN: @@ -1945,26 +1942,28 @@ stringToSizeValue( os_boolean valid = OS_TRUE; char *endptr; os_size_t len; + os_double temp = 0.0; - *value = os_strtoull (image, &endptr, 0); + /* double needed to also accept cases like 0.5G */ + temp = os_strtod (image, &endptr); len = strlen(endptr); if (len > 0) { switch (*endptr) { case 'K': - (*value) *= 1024ULL; + temp *= 1024ULL; break; case 'M': - (*value) *= 1024ULL * 1024UL; + temp *= 1024ULL * 1024UL; break; case 'G': - (*value) *= 1024ULL * 1024UL * 1024UL; + temp *= 1024ULL * 1024UL * 1024UL; break; default: valid = OS_FALSE; break; } } - + (*value) = (os_uint64)temp; return valid; } diff --git a/src/configuration/validator/code/cfg_metaConfig.h b/src/configuration/validator/code/cfg_metaConfig.h index 02496677f..b0ada381a 100644 --- a/src/configuration/validator/code/cfg_metaConfig.h +++ b/src/configuration/validator/code/cfg_metaConfig.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -91,7 +92,7 @@ cfg_nodeGetName( cfg_node cfg_nodeGetParent( - cfg_node _this) __nonnull_all__; + cfg_node _this); os_uint32 cfg_nodeGetOccurrences( diff --git a/src/configuration/validator/code/cfg_metaConfigParser.c b/src/configuration/validator/code/cfg_metaConfigParser.c index aede86541..c83d3780d 100644 --- a/src/configuration/validator/code/cfg_metaConfigParser.c +++ b/src/configuration/validator/code/cfg_metaConfigParser.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -364,7 +365,7 @@ cfg_parseMetaConfig( cfg_element *root, cfg_element *serviceMapping) { - C_STRUCT(MetaConfigParser) parser = {0}; + C_STRUCT(MetaConfigParser) parser = {NULL, NULL, OS_FALSE, NULL,0}; struct ut_xmlpCallbacks cb; struct ut_xmlpState *st; cfgprs_status status; diff --git a/src/configuration/validator/code/cfg_metaConfigParser.h b/src/configuration/validator/code/cfg_metaConfigParser.h index e30488882..f660a60bc 100644 --- a/src/configuration/validator/code/cfg_metaConfigParser.h +++ b/src/configuration/validator/code/cfg_metaConfigParser.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/configuration/validator/code/cfg_validator.c b/src/configuration/validator/code/cfg_validator.c index 38f6f378f..2dcc84be9 100644 --- a/src/configuration/validator/code/cfg_validator.c +++ b/src/configuration/validator/code/cfg_validator.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -28,7 +29,7 @@ #include "cfg_metaConfigParser.h" #include "cfg_validator.h" -#define CONFIG_SYNTAX_FILE_NAME "metaconfig.xml" +#define CONFIG_SYNTAX_FILE_NAME "ospl_metaconfig.xml" #define CONFIG_SYNTAX_FILE_NAME_PREFIX "splice_metaconfig_" #define CONFIG_SYNTAX_FILE_NAME_POSTFIX ".1.xml" #define CONFIG_VALIDATION_DISABLED "OSPL_CONFIG_VALIDATION_DISABLED" @@ -433,17 +434,32 @@ findServiceMappingByCommand( cfg_serviceMapping item; c_iter list; c_iterIter iter; + char *ptr, *normalizedCmd; assert(services); + /* For matching, the basename of command without suffix is required */ + normalizedCmd = os_fileNormalize(command); + ptr = os_rindex(normalizedCmd, '.'); + if (ptr) { + *ptr = '\0'; + } + + ptr = os_rindex(normalizedCmd, OS_FILESEPCHAR); + if (ptr) { + ptr++; + } else { + ptr = normalizedCmd; + } + list = cfg_elementGetChildren(services); if (list) { iter = c_iterIterGet(list); item = c_iterNext(&iter); while (item && !mapping) { const char *cmd = cfg_serviceMappingGetCommand(item); - if (cmd && command) { - if (strcmp(cmd, command) == 0) { + if (cmd && ptr) { + if (strcmp(cmd, ptr) == 0) { mapping = item; } else { item = c_iterNext(&iter); @@ -452,6 +468,8 @@ findServiceMappingByCommand( } } + os_free(normalizedCmd); + return mapping; } @@ -509,6 +527,62 @@ getBooleanAttributeValue( return result; } +static cfg_serviceMapping +validateServiceCommand( + cf_element configRoot, + const char *name, + const char *command, + cfg_checkContext context) +{ + cfg_serviceMapping mapping = NULL; + c_iter list; + c_iterIter iter; + c_bool cont = TRUE; + char *fullname; + + cfg_serviceMapping result = NULL; + + assert(configRoot); + assert(name); + + fullname = os_locate(command, OS_ROK | OS_XOK); + if (!fullname) { + cont = FALSE; + } + os_free(fullname); + + list = cfg_elementGetChildren(context->services); + if (list) { + iter = c_iterIterGet(list); + while (cont && (mapping = cfg_serviceMapping(c_iterNext(&iter))) != NULL) { + c_iter nodeList = findChildrenByName(configRoot, cfg_nodeGetName(cfg_node(mapping))); + cf_node node = c_iterTakeFirst(nodeList); + while (node && cont) { + if (cf_nodeKind(node) == CF_ELEMENT) { + char *foundName = getAttributeValue(cf_element(node), "name"); + if (foundName) { + if (!strcmp(name, foundName)) { + cont = FALSE; + result = mapping; + OS_REPORT_WID(OS_INFO, "configuration validator", 0, context->domainId, + "Element %s command '%s' is non-default for service %s but executable, accepting it as valid command", + name, command, command, foundName); + + } + os_free(foundName); + } + } + node = c_iterTakeFirst(nodeList); + } + c_iterFree(nodeList); + } + } + + + return result; + +} + /* Get the list of configured services. * The meta configuration contains the list of serviceMappings @@ -597,6 +671,9 @@ getListedServices( command = getElementData(cf_element(node)); if (command) { mapping = findServiceMappingByCommand(context->services, command); + if (!mapping) { + mapping = validateServiceCommand(configRoot, name, command, context); + } if (mapping) { entry = serviceEntryNew(mapping, name, enabled); list = c_iterAppend(list, entry); @@ -731,8 +808,14 @@ validateConfigurationDisabled(void) return disabled; } +/* This function returns the absolute path of the meta config file in the development tree. + * This alternative location is only applicable for internal use in the development environment. + * In normal installed environments the meta config file is located at $OSPL_HOME/etc or + * in the current directory in case a user wants to override the meta configuration file. + * The development location is $OSPL_HOME/src/tools.cm/config/code + */ static char * -getSyntaxFilenameAlternative(void) +alternativeMetaConfigFileName(void) { const char *osplhome; const char *dirs[] = {"src", "tools", "cm", "config", "code"}; @@ -770,9 +853,8 @@ getSyntaxFilenameAlternative(void) return filename; } - static char * -getSyntaxFilename(void) +defaultMetaConfigFileName(void) { const char *osplhome; const char *dir = "etc"; @@ -800,7 +882,7 @@ cfg_validateConfiguration( cf_element configRoot) { cfgprs_status status = CFGPRS_OK; - C_STRUCT(cfg_checkContext) context = {0}; + C_STRUCT(cfg_checkContext) context = {NULL, NULL, NULL, OS_FALSE, 0}; char *syntaxFileName; cfg_element syntaxRoot = NULL; cfg_element serviceMapping = NULL; @@ -814,20 +896,45 @@ cfg_validateConfiguration( context.domainId = -1; } - syntaxFileName = getSyntaxFilename(); - if (syntaxFileName) { - fp = fopen(syntaxFileName, "r"); + /* First check for a local config file in current directory */ + syntaxFileName = os_strdup(CONFIG_SYNTAX_FILE_NAME); + fp = fopen(syntaxFileName, "r"); + + /* If no local config file then use the default OSPL_HOME/etc/ospl_metaconfig.xml config file. */ + if (!fp) { + os_free(syntaxFileName); + syntaxFileName = defaultMetaConfigFileName(); + if (syntaxFileName) { + fp = fopen(syntaxFileName, "r"); + } + /* If also no default config file then look for alternative. + * This alternative location is only applicable for internal use in the development environment. + */ if (!fp) { - char *altFilename = getSyntaxFilenameAlternative(); - fp = fopen(altFilename, "r"); - if (!fp) { - OS_REPORT_WID(OS_ERROR, "configuration validator", 0, context.domainId, - "Failed to open configuration syntax file: %s", syntaxFileName); + char *alternativeFileName; + alternativeFileName = alternativeMetaConfigFileName(); + if (alternativeFileName) { + fp = fopen(alternativeFileName, "r"); + os_free(alternativeFileName); + } + } + if (!fp) { + const char *osplhome = os_getenv("OSPL_HOME"); + if (osplhome) { + OS_REPORT_NOW(OS_ERROR, "configuration validator", 0, context.domainId, + "Failed to open meta configuration file \"%s\".\n" + " The file was not found in the current directory nor\n" + " at the default location: %s%setc", + CONFIG_SYNTAX_FILE_NAME, osplhome, os_fileSep()); + } else { + OS_REPORT_NOW(OS_ERROR, "configuration validator", 0, context.domainId, + "Failed to open meta configuration file \"%s\".\n" + " The file was not found in the current directory nor\n" + " could the file be found at the default location because\n" + " the environment variable OSPL_HOME was not set", + CONFIG_SYNTAX_FILE_NAME); } - os_free(altFilename); } - } else { - OS_REPORT(OS_ERROR, "configuration validator", 0, "OSPL_HOME is not set"); } if (fp) { @@ -844,7 +951,7 @@ cfg_validateConfiguration( } else { OS_REPORT_WID(OS_ERROR, "configuration validator", 0, context.domainId, - "Failed to parse configuration syntax file: %s", syntaxFileName); + "Meta configuration parse error(s) in file: %s", syntaxFileName); } cfg_nodeFree(cfg_node(syntaxRoot)); cfg_nodeFree(cfg_node(serviceMapping)); diff --git a/src/configuration/validator/include/cfg_validator.h b/src/configuration/validator/include/cfg_validator.h index 5eda5469f..6dd88bed6 100644 --- a/src/configuration/validator/include/cfg_validator.h +++ b/src/configuration/validator/include/cfg_validator.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/cpp/code/accum.c b/src/cpp/code/accum.c index e8bd2ee0f..24bcb8a8e 100644 --- a/src/cpp/code/accum.c +++ b/src/cpp/code/accum.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/cpp/code/accum.h b/src/cpp/code/accum.h index d2e55c7e3..349a287b2 100644 --- a/src/cpp/code/accum.h +++ b/src/cpp/code/accum.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/cpp/code/at.c b/src/cpp/code/at.c index 97c159af5..45550f67d 100644 --- a/src/cpp/code/at.c +++ b/src/cpp/code/at.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/cpp/code/autodef.c b/src/cpp/code/autodef.c index de50c6425..22c34a959 100644 --- a/src/cpp/code/autodef.c +++ b/src/cpp/code/autodef.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/cpp/code/copyof.c b/src/cpp/code/copyof.c index f670cda93..07988a45c 100644 --- a/src/cpp/code/copyof.c +++ b/src/cpp/code/copyof.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/cpp/code/cpp_io.h b/src/cpp/code/cpp_io.h index 85ff2f7b2..eceb99523 100644 --- a/src/cpp/code/cpp_io.h +++ b/src/cpp/code/cpp_io.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/cpp/code/cpp_malloc.h b/src/cpp/code/cpp_malloc.h index c1f682e61..b69c69d22 100644 --- a/src/cpp/code/cpp_malloc.h +++ b/src/cpp/code/cpp_malloc.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/cpp/code/debug.c b/src/cpp/code/debug.c index ac46ea985..bb0596d7c 100644 --- a/src/cpp/code/debug.c +++ b/src/cpp/code/debug.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/cpp/code/define.c b/src/cpp/code/define.c index 7b9d372b3..d9092d5c9 100644 --- a/src/cpp/code/define.c +++ b/src/cpp/code/define.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/cpp/code/dump.c b/src/cpp/code/dump.c index c6c0539fe..a1e7db2bc 100644 --- a/src/cpp/code/dump.c +++ b/src/cpp/code/dump.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/cpp/code/error.c b/src/cpp/code/error.c index 576055e86..b423438ff 100644 --- a/src/cpp/code/error.c +++ b/src/cpp/code/error.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/cpp/code/eval.c b/src/cpp/code/eval.c index 9041ff71a..b97b67251 100644 --- a/src/cpp/code/eval.c +++ b/src/cpp/code/eval.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/cpp/code/expand.c b/src/cpp/code/expand.c index d0a76bae5..b8fd6867d 100644 --- a/src/cpp/code/expand.c +++ b/src/cpp/code/expand.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/cpp/code/expr.c b/src/cpp/code/expr.c index ec3d71f43..f8e24336a 100644 --- a/src/cpp/code/expr.c +++ b/src/cpp/code/expr.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/cpp/code/expr.h b/src/cpp/code/expr.h index cf51f1245..5464c2117 100644 --- a/src/cpp/code/expr.h +++ b/src/cpp/code/expr.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/cpp/code/if.c b/src/cpp/code/if.c index 71e1b760d..c096b686e 100644 --- a/src/cpp/code/if.c +++ b/src/cpp/code/if.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/cpp/code/if.h b/src/cpp/code/if.h index d77ed40b2..8d22421a7 100644 --- a/src/cpp/code/if.h +++ b/src/cpp/code/if.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/cpp/code/include.c b/src/cpp/code/include.c index 36c0fbe19..c739dc6f2 100644 --- a/src/cpp/code/include.c +++ b/src/cpp/code/include.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/cpp/code/include.h b/src/cpp/code/include.h index 5fbd9bd5d..9399116ce 100644 --- a/src/cpp/code/include.h +++ b/src/cpp/code/include.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/cpp/code/io.c b/src/cpp/code/io.c index 5f3a3f1a1..faa738004 100644 --- a/src/cpp/code/io.c +++ b/src/cpp/code/io.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -201,7 +202,7 @@ int Get() else { flush_final_nl(); - return ( -1); + return -1; } } mark_got_from_file(c); diff --git a/src/cpp/code/is.c b/src/cpp/code/is.c index d2f16a871..440ccf1e3 100644 --- a/src/cpp/code/is.c +++ b/src/cpp/code/is.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/cpp/code/is.h b/src/cpp/code/is.h index 67a6aaee6..0847aa793 100644 --- a/src/cpp/code/is.h +++ b/src/cpp/code/is.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/cpp/code/line.c b/src/cpp/code/line.c index ceb4b4e30..bef3efca0 100644 --- a/src/cpp/code/line.c +++ b/src/cpp/code/line.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/cpp/code/pragma.c b/src/cpp/code/pragma.c index f763b4d25..21a93bb60 100644 --- a/src/cpp/code/pragma.c +++ b/src/cpp/code/pragma.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,11 +23,11 @@ extern void do_pragma (void) { - char c; + int c; if (in_false_if()) { - while ((c = Get()) != '\n') + for (c = Get(); (c != '\n') && (c != -1); c = Get()) ; } else @@ -39,9 +40,9 @@ extern void do_pragma (void) outputc('m'); outputc('a'); outputc(' '); - while ((c = Get()) != '\n') + for (c = Get(); (c != '\n') && (c != -1); c = Get()) { - outputc(c); + outputc((char)c); } } } diff --git a/src/cpp/code/predefs.c b/src/cpp/code/predefs.c index 369184b13..b04a760e3 100644 --- a/src/cpp/code/predefs.c +++ b/src/cpp/code/predefs.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/cpp/code/preprocess.c b/src/cpp/code/preprocess.c index c69f09d5c..8d0832997 100644 --- a/src/cpp/code/preprocess.c +++ b/src/cpp/code/preprocess.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/cpp/code/preprocess.h b/src/cpp/code/preprocess.h index eac068b30..83f6a02ba 100644 --- a/src/cpp/code/preprocess.h +++ b/src/cpp/code/preprocess.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/cpp/code/set.c b/src/cpp/code/set.c index e261ce131..cd99d7ac6 100644 --- a/src/cpp/code/set.c +++ b/src/cpp/code/set.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/cpp/code/sharp.c b/src/cpp/code/sharp.c index 947699687..c15df4112 100644 --- a/src/cpp/code/sharp.c +++ b/src/cpp/code/sharp.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/cpp/code/stdincs.h b/src/cpp/code/stdincs.h index 31c3cfe0c..4c93fb21e 100644 --- a/src/cpp/code/stdincs.h +++ b/src/cpp/code/stdincs.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/cpp/code/symtbl.c b/src/cpp/code/symtbl.c index f4b601b44..7aeb09403 100644 --- a/src/cpp/code/symtbl.c +++ b/src/cpp/code/symtbl.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/cpp/code/symtbl.h b/src/cpp/code/symtbl.h index ae60d56e9..e634489b6 100644 --- a/src/cpp/code/symtbl.h +++ b/src/cpp/code/symtbl.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/cpp/code/unctrl.c b/src/cpp/code/unctrl.c index 615c16e22..64a62bc67 100644 --- a/src/cpp/code/unctrl.c +++ b/src/cpp/code/unctrl.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/cpp/code/unctrl.h b/src/cpp/code/unctrl.h index 1581f8b58..3b1dfe552 100644 --- a/src/cpp/code/unctrl.h +++ b/src/cpp/code/unctrl.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/cpp/code/undef.c b/src/cpp/code/undef.c index 92a89ad40..0690bfe4e 100644 --- a/src/cpp/code/undef.c +++ b/src/cpp/code/undef.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/cpp/code/while.c b/src/cpp/code/while.c index 675a6913a..30a5d6bef 100644 --- a/src/cpp/code/while.c +++ b/src/cpp/code/while.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/cpp/include/dds_cpp.h b/src/cpp/include/dds_cpp.h index 51e00b34a..75fec9b52 100644 --- a/src/cpp/include/dds_cpp.h +++ b/src/cpp/include/dds_cpp.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/database/database/code/c__base.h b/src/database/database/code/c__base.h index b751c8d71..2f0ca03bb 100644 --- a/src/database/database/code/c__base.h +++ b/src/database/database/code/c__base.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/database/database/code/c__collection.h b/src/database/database/code/c__collection.h index 32055939c..51f3d199d 100644 --- a/src/database/database/code/c__collection.h +++ b/src/database/database/code/c__collection.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/database/database/code/c__field.h b/src/database/database/code/c__field.h index 42d978bde..b546ad703 100644 --- a/src/database/database/code/c__field.h +++ b/src/database/database/code/c__field.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/database/database/code/c__metabase.h b/src/database/database/code/c__metabase.h index b8e09be72..78122b64f 100644 --- a/src/database/database/code/c__metabase.h +++ b/src/database/database/code/c__metabase.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/database/database/code/c__mmbase.h b/src/database/database/code/c__mmbase.h index 98659e489..c294a950f 100644 --- a/src/database/database/code/c__mmbase.h +++ b/src/database/database/code/c__mmbase.h @@ -1,10 +1,11 @@ /* (progn (c-set-style "k&r") (setq c-basic-offset 4)) */ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/database/database/code/c__querybase.h b/src/database/database/code/c__querybase.h index 4dcefc4c0..f4c0922cb 100644 --- a/src/database/database/code/c__querybase.h +++ b/src/database/database/code/c__querybase.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -115,19 +116,6 @@ C_STRUCT(c_qPred) { c_qPred next; }; -#if 0 -c_array -c_keyNew ( - c_type t, - c_iter fieldNames); - -c_array -c_keyDcl ( - c_type t, - c_long size, - ...); -#endif - OS_API c_qResult c_qPredNew ( c_type type, diff --git a/src/database/database/code/c__refcheck.h b/src/database/database/code/c__refcheck.h index e7b1088c6..709b28b28 100644 --- a/src/database/database/code/c__refcheck.h +++ b/src/database/database/code/c__refcheck.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/database/database/code/c__scope.h b/src/database/database/code/c__scope.h index b254a3763..d99044cd1 100644 --- a/src/database/database/code/c__scope.h +++ b/src/database/database/code/c__scope.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/database/database/code/c_base.c b/src/database/database/code/c_base.c index 2d276ad90..8e1a5780a 100644 --- a/src/database/database/code/c_base.c +++ b/src/database/database/code/c_base.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -34,7 +35,6 @@ #include "c__collection.h" #include "c__field.h" #include "c__metabase.h" -#include "q__parser.h" #include "c_module.h" /* If set the meta descriptions c_union, c_interface and c_structure will @@ -44,11 +44,15 @@ #define TYPE_REFC_COUNTS_OBJECTS 0 #define CONFIDENCE (0x504F5448) -#define REFCOUNT_MASK 0xffffffu -#define REFCOUNT_FLAG_ATOMIC 0x1000000u -#define REFCOUNT_FLAG_TRACE 0x2000000u -#define REFCOUNT_FLAG_TRACETYPE 0x4000000u +#define REFCOUNT_MASK 0x1ffffffu +#define REFCOUNT_FLAG_CLAMP 0x1000000u +#define REFCOUNT_FLAG_ATOMIC 0x2000000u +#define REFCOUNT_FLAG_TRACE 0x4000000u +#define REFCOUNT_FLAG_TRACETYPE 0x8000000u #define REFCOUNT_FLAG_GARBAGE 0x10000000u +#if (REFCOUNT_FLAG_CLAMP << 1) != REFCOUNT_MASK + 1 +#error "REFCOUNT_FLAG_CLAMP must be the top bit of REFCOUNT_MASK" +#endif #define c_oid(o) ((c_object)(C_ADDRESS(o) + HEADERSIZE)) #define c_header(o) ((c_header)(C_ADDRESS(o) - HEADERSIZE)) @@ -169,7 +173,8 @@ c_stringMalloc( * 'empty' string, so in this case return a reference to the intern. This * saves precious resources in case of big amounts of empty strings, since * each empty string does not only contain the '\0' terminator but also - * 36-40 bytes of header information. */ + * 36-40 bytes of header information. + */ assert(base->emptyString[0] == '\0'); return c_keep(base->emptyString); } @@ -190,7 +195,8 @@ c_stringMalloc_s( * 'empty' string, so in this case return a reference to the intern. This * saves precious resources in case of big amounts of empty strings, since * each empty string does not only contain the '\0' terminator but also - * 36-40 bytes of header information. */ + * 36-40 bytes of header information. + */ assert(base->emptyString[0] == '\0'); return c_keep(base->emptyString); } @@ -255,7 +261,8 @@ c_wstringMalloc( * 'empty' string, so in this case return a reference to the intern. This * saves precious resources in case of big amounts of empty strings, since * each empty string does not only contain the '\0' terminator but also - * 36-40 bytes of header information. */ + * 36-40 bytes of header information. + */ assert(base->emptyWstring[0] == 0); return c_keep(base->emptyWstring); } @@ -277,7 +284,8 @@ c_wstringMalloc_s( * 'empty' string, so in this case return a reference to the intern. This * saves precious resources in case of big amounts of empty strings, since * each empty string does not only contain the '\0' terminator but also - * 36-40 bytes of header information. */ + * 36-40 bytes of header information. + */ assert(base->emptyWstring[0] == 0); return c_keep(base->emptyWstring); } @@ -303,7 +311,8 @@ c_stringNew( len = strlen(str) + 1; if((s = c_stringMalloc(base, len)) != NULL && len > 1){ /* str is nul-terminated (since we could determine len), so memcpy str - * including the nul-terminator. */ + * including the nul-terminator. + */ memcpy(s, str, len); } @@ -329,7 +338,8 @@ c_stringNew_s( len = strlen(str) + 1; if((s = c_stringMalloc_s(base, len)) != NULL && len > 1){ /* str is nul-terminated (since we could determine len), so memcpy str - * including the nul-terminator. */ + * including the nul-terminator. + */ memcpy(s, str, len); } @@ -397,7 +407,8 @@ initInterface( c_object o) { /* The vast majority of classes that get defined during initialisation have the scope already - allocated by c_metaDefine, but not all of them. */ + * allocated by c_metaDefine, but not all of them. + */ if(c_interface(o)->scope == NULL) { c_interface(o)->scope = (c_scope)c_scopeNew(c__getBase(o)); } @@ -510,7 +521,8 @@ c_baseSetMaintainObjectCount ( c_bool enable) { /* Not bothering with locking here, so it is undefined when - exactly other threads take note (but they will eventually) */ + * exactly other threads take note (but they will eventually) + */ base->maintainObjectCount = enable; } @@ -520,7 +532,8 @@ c_baseSetY2038Ready ( c_bool enable) { /* Not bothering with locking here, so it is undefined when - exactly other threads take note (but they will eventually) */ + * exactly other threads take note (but they will eventually) + */ base->y2038Ready = enable; } @@ -536,7 +549,8 @@ c_baseGetScopeAttr( c_base base) { /* Use shared mutexes only when this base - * is within shared memory. */ + * is within shared memory. + */ if (c_mmMode(base->mm) == MM_SHARED) { return OS_SCOPE_SHARED; } else { @@ -576,17 +590,18 @@ c_baseInit ( c_metaObject(base)->name = NULL; /* c_module init */ - c_mutexInit(base, &((c_module)base)->mtx); + (void)c_mutexInit(base, &((c_module)base)->mtx); /* scope is initialized when scope-type is bootstrapped */ /* c_base init */ base->confidence = CONFIDENCE; ut_avlInit (&c_base_bindings_td, &base->bindings); - c_mutexInit(base, &base->bindLock); - c_mutexInit(base, &base->serLock); + (void)c_mutexInit(base, &base->bindLock); + (void)c_mutexInit(base, &base->serLock); /* metaType[M_COUNT], string_type and emptyString are initialized when types - * are available. */ + * are available. + */ /* c_base init */ c_queryCacheInit (&base->baseCache.queryCache); @@ -600,8 +615,9 @@ c_baseInit ( #endif #endif -/** Declare class type. - this is required because all meta meta objects are defined as class. **/ + /* Declare class type. + * this is required because all meta meta objects are defined as class. + */ size = MEMSIZE(C_SIZEOF(c_class)); header = (c_header)c_mmMalloc(base->mm,size); if (!header) { @@ -636,8 +652,9 @@ c_baseInit ( C_META_TYPEINIT_(o,c_collectionType); base->metaType[M_COLLECTION] = c_type(o); -/** Declare scope class type. - this is required because all meta meta objects are managed in the base scope. **/ + /* Declare scope class type. + * this is required because all meta meta objects are managed in the base scope. + */ scopeType = c_type(c_new(base->metaType[M_COLLECTION])); c_baseObject(scopeType)->kind = M_COLLECTION; @@ -645,8 +662,9 @@ c_baseInit ( c_collectionType(scopeType)->maxSize = 0; C_META_TYPEINIT_(scopeType,c_scope); -/** Declare base class type and initialize the base scope. - this is required because all meta meta objects are bound to the base scope. **/ + /* Declare base class type and initialize the base scope. + * this is required because all meta meta objects are bound to the base scope. + */ o = c_metaObject(c_new(base->metaType[M_CLASS])); c_baseObject(o)->kind = M_CLASS; @@ -654,14 +672,15 @@ c_baseInit ( base->metaType[M_BASE] = c_type(o); /* Overwrite as header->type points to type of metatype class - * i.o. NULL */ + * i.o. NULL + */ c_header(base)->type = c_keep(o); /* c_module->scope init */ c_module(base)->scope = c_scope(c_new(scopeType)); c_scopeInit(c_module(base)->scope); - /** Declare c_string type, this is required to be able to bind objects to names. **/ + /* Declare c_string type, this is required to be able to bind objects to names. */ o = c_metaObject(c_new(base->metaType[M_COLLECTION])); c_baseObject(o)->kind = M_COLLECTION; c_collectionType(o)->kind = OSPL_C_STRING; @@ -692,16 +711,18 @@ c_baseInit ( assert(found == c_metaObject(scopeType)); c_free(found); -/** Now allocate, bind and pre-initialize all meta meta objects. - pre-initialize will only set size and kind making the meta meta objects - ready to be used for meta creation. - At this point reflection will be unavailable until the meta meta objects - are fully initialized. **/ + /* Now allocate, bind and pre-initialize all meta meta objects. + * pre-initialize will only set size and kind making the meta meta objects + * ready to be used for meta creation. + * At this point reflection will be unavailable until the meta meta objects + * are fully initialized. + */ /* Initialize the interned empty string. Strings can now be allocated, so * even though in the baseInit no empty strings are used, initialisation * is needed here to guarantee the assertions of c_stringNew and - * c_stringMalloc. */ + * c_stringMalloc. + */ base->emptyString = c__stringMalloc(base, 1, FALSE); base->emptyString[0] = '\0'; @@ -716,12 +737,12 @@ c_baseInit ( base->baseCache.typeCache.c_property_t = _META_(base,c_property); base->baseCache.typeCache.c_type_t = _META_(base,c_type); - /** At last set the subType of c_scope type. **/ + /* At last set the subType of c_scope type. */ c_collectionType(scopeType)->subType = ResolveType(base,c_metaObject); c_free(scopeType); /* we can now free our local ref as we don't use it anymore */ scopeType = NULL; - /** Declare meta types **/ + /* Declare meta types */ base->metaType[M_LITERAL] = _META_(base,c_literal); base->metaType[M_CONSTOPERAND] = _META_(base,c_constOperand); base->metaType[M_EXPRESSION] = _META_(base,c_expression); @@ -769,11 +790,12 @@ c_baseInit ( #undef _META_ -/** Now allocation of meta objects is operational. - For initialization of the meta meta object we need to allocate the meta objects - for all internal types. **/ + /* Now allocation of meta objects is operational. + * For initialization of the meta meta object we need to allocate the meta objects + * for all internal types. + */ - /** Definition of the meta objects specifying all internal primitive types. **/ + /* Definition of the meta objects specifying all internal primitive types. */ #define INITPRIM(s,n,k) \ o = c_metaDeclare(c_metaObject(s),#n,M_PRIMITIVE); \ @@ -1025,11 +1047,12 @@ c_baseInit ( c_free(o); -/** Now all meta meta references required for initialization are available. - The following statements will initialize all meta meta objects. - After initialization reflection will be operational. **/ + /* Now all meta meta references required for initialization are available. + * The following statements will initialize all meta meta objects. + * After initialization reflection will be operational. + */ - /** Initialize abstract meta types **/ + /* Initialize abstract meta types */ #define _INITCLASS_(s,c,p) \ c_metaObject(initClass(ResolveType(s,c),ResolveType(s,p))) @@ -1084,7 +1107,7 @@ c_baseInit ( C_META_FINALIZE_(o); c_free(o); - /** Initialize meta types **/ + /* Initialize meta types */ o = _INITCLASS_(base,c_literal,c_operand); type = ResolveType(base,c_value); C_META_ATTRIBUTE_(c_literal,o,value,type); @@ -1457,7 +1480,6 @@ c_baseInit ( c_property(found)->type = c_ulong_t(base); c_free(found); c_metaBind(c_metaObject(_intern), "ID", o); - /*c_metaFinalize(o);*/ c_free(o); /* ::Optional */ @@ -1467,7 +1489,6 @@ c_baseInit ( c_property(found)->type = c_bool_t(base); c_free(found); c_metaBind(c_metaObject(_intern), "optional", o); - /*c_metaFinalize(o);*/ c_free(o); /* ::Key */ @@ -1477,7 +1498,6 @@ c_baseInit ( c_property(found)->type = c_bool_t(base); c_free(found); c_metaBind(c_metaObject(_intern), "Key", o); - /*c_metaFinalize(o);*/ c_free(o); /* ::Shared */ @@ -1487,7 +1507,6 @@ c_baseInit ( c_property(found)->type = c_bool_t(base); c_free(found); c_metaBind(c_metaObject(_intern), "Shared", o); - /*c_metaFinalize(o);*/ c_free(o); /* ::BitBound */ @@ -1497,7 +1516,6 @@ c_baseInit ( c_property(found)->type = c_ushort_t(base); c_free(found); c_metaBind(c_metaObject(_intern), "BitBound", o); - /*c_metaFinalize(o);*/ c_free(o); /* ::Value */ @@ -1507,14 +1525,12 @@ c_baseInit ( c_property(found)->type = c_ulong_t(base); c_free(found); c_metaBind(c_metaObject(_intern), "Value", o); - /*c_metaFinalize(o);*/ c_free(o); /* ::BitSet */ o = c_metaDefine(c_metaObject(_intern), M_ANNOTATION); initAnnotation(o); c_metaBind(c_metaObject(_intern), "BitSet", o); - /*c_metaFinalize(o);*/ c_free(o); /* ::Nested */ @@ -1524,7 +1540,6 @@ c_baseInit ( c_property(found)->type = c_bool_t(base); c_free(found); c_metaBind(c_metaObject(_intern), "Nested", o); - /*c_metaFinalize(o);*/ c_free(o); temp = c_metaDefine(c_metaObject(base),M_ENUMERATION); @@ -1543,7 +1558,6 @@ c_baseInit ( c_property(found)->type = c_type(temp); c_free(found); c_metaBind(c_metaObject(_intern), "Extensibility", o); - /*c_metaFinalize(o);*/ c_free(o); /* ::MustUnderstand */ @@ -1553,7 +1567,6 @@ c_baseInit ( c_property(found)->type = c_bool_t(base); c_free(found); c_metaBind(c_metaObject(_intern), "MustUnderstand", o); - /*c_metaFinalize(o);*/ c_free(o); /* ::Verbatim */ @@ -1592,7 +1605,6 @@ c_baseInit ( found = c_metaDeclare(o, "text", M_ATTRIBUTE); c_property(found)->type = c_string_t(base); c_free(found); - /*c_metaFinalize(o);*/ c_free(o); c_fieldInit(base); @@ -1650,8 +1662,6 @@ c_create ( c_baseInit(base, mm); ospl_c_bind(base,"c_baseModule"); - - q_parserInit(); } return base; } @@ -1709,8 +1719,6 @@ c_open ( return NULL; } - q_parserInit(); - return base; } @@ -2002,8 +2010,7 @@ c__newBaseArrayObjectCommon ( o = c_oid(header); - /* - * When an array is freed via c_free, it also checks whether it contains + /* When an array is freed via c_free, it also checks whether it contains * references and if they need to be freed. If the user did not fill the whole array * a c_free on garbage data could be performed, which causes undefined behaviour. * Therefore the whole array is set on 0. @@ -2104,20 +2111,137 @@ void c__assertValidDatabaseObject( c_voidp o) { + c_header header; assert(o); - assert(c_header(o)->confidence == CONFIDENCE); - assert((pa_ld32(&c_header(o)->refCount) & REFCOUNT_MASK) > 0); + header = c_header(o); + assert(header->confidence == CONFIDENCE); + assert((pa_ld32(&header->refCount) & REFCOUNT_MASK) > 0); } #endif -static c_bool _c_freeReferences(c_metaObject metaObject, c_object o); -#define c_freeReferences(m,o) ((m && o)? _c_freeReferences(m,o):TRUE) -#define freeReference(p,t) (p?_freeReference(p,t):TRUE) +/** + * Object Free functionality + * + * The c_free decreases the refcount of a database object and releases claimed memory resources + * when the refcount reaches zero, in other words the object is no longer reachable / used. + * + * The free will also free other referenced objects when an object is destroyed, this traversal + * of references is solved in an iterative algorithm and not recursively to avoid stack memory depletion. + * + * The algorithm works by: + * - first initialize a freelist intended to hold any references that are encountered that also need to be freed. + * - enter the processing loop + * - then decrease the refcount of the object. + * - if the refcount reaches zero then add all direct referenced objects to the freelist. + * - release the objects memory resources. + * - get the next object from the freelist and goto the start of the loop. + * + * Performance considerations: + * The freelist is ia stretchy fifo queue that is implemented as an array allocated on heap to avoid + * memory allocation and deallocation, however when the number of elements exceeds the array size (REFBUF_SIZE) + * then the freelist will allocate additional buffers forming a chain of buffers. + * Allocated buffers in the chain that become empty when taking object from the queue are freed on the fly. + * The size of the buffer becomes less effective the greater it gets and considering that the initial buffer + * is allocated on stack it should not be too big. + */ + +#define REFBUF_SIZE (256) + +/* The class c_refbuf implements the chainable object buffer. */ +C_CLASS(c_refbuf); +C_STRUCT(c_refbuf) { + c_object element[REFBUF_SIZE]; + c_refbuf next; +}; + +#define c_refbuf(o) ((c_refbuf)o) + +/* The class c_freelist implements the stretchy fifo queue used by the iterative free algorithm. */ +C_CLASS(c_freelist); +C_STRUCT(c_freelist) { + C_EXTENDS(c_refbuf); /* Initial object buffer that is initialized on stack. */ + c_refbuf tail_buf; /* Tail buffer of the queue, objects are read from this buffer. */ + c_refbuf head_buf; /* Head buffer of the queue, objects are inserted in this buffer. */ + os_uint32 tail_idx; /* Tail buffer index of the queue, oldest object that is next to be read. */ + os_uint32 head_idx; /* Head buffer index of the queue, place where the next object will be inserted. */ +}; + +/* This function is used to initialize a new freelist heap object. */ +static void +c_freelistInit( + c_freelist freelist) +{ + c_refbuf(freelist)->next = NULL; + freelist->tail_buf = c_refbuf(freelist); + freelist->head_buf = c_refbuf(freelist); + freelist->tail_idx = 0; + freelist->head_idx = 0; +} + +/* This function inserts an object at the head of the freelist. */ +static void +c_freelistInsert( + c_freelist freelist, + c_object object) +{ + if (object == NULL) return; + assert(c_header(object)->confidence == CONFIDENCE); + if (freelist->head_idx == REFBUF_SIZE) { + freelist->head_buf->next = os_malloc(sizeof(C_STRUCT(c_refbuf))); + freelist->head_buf = freelist->head_buf->next; + freelist->head_buf->next = NULL; + freelist->head_idx = 0; + } + freelist->head_buf->element[freelist->head_idx++] = object; +} + +/* This function will remove the oldest object from the freelist. */ +static c_object +c_freelistTake( + c_freelist freelist) +{ + c_object object = NULL; + c_refbuf freebuf; + + if (freelist->tail_idx == REFBUF_SIZE) { + /* Reached the end of a buffer so it is empty and if allocated can be freed. */ + freelist->tail_idx = 0; + freebuf = freelist->tail_buf; + freelist->tail_buf = freelist->tail_buf->next; + + if (freebuf != c_refbuf(freelist)) { + /* The empty buffer was allocated so free it now. */ + assert(freebuf == c_refbuf(freelist)->next); + os_free(freebuf); + } + c_refbuf(freelist)->next = freelist->tail_buf; + if (freelist->tail_buf == NULL) { + /* If the tail_buf is NULL then the queue is empty meaning that it can conveniently + * be reinitialized as a new freelist. + */ + c_freelistInit(freelist); + } + } + if (freelist->head_idx > freelist->tail_idx || freelist->head_buf != freelist->tail_buf ) + { + /* the freelist is not empty so take an object from the freelist. */ + object = freelist->tail_buf->element[freelist->tail_idx++]; + } else if (freelist->tail_buf != c_refbuf(freelist)) { + /* The freelist is empty but also has an allocated buffer so free it now. */ + os_free(freelist->tail_buf); + } + return object; +} + +static c_bool _c_freeReferences(c_metaObject metaObject, c_object o, c_freelist freelist); +#define c_freeReferences(m,o,l) ((m && o)? _c_freeReferences(m,o,l):TRUE) +#define freeReference(p,t,l) (p?_freeReference(p,t,l):TRUE) static c_bool _freeReference ( c_voidp *p, - c_type type) + c_type type, + c_freelist freelist) { c_type t = type; @@ -2131,21 +2255,21 @@ _freeReference ( case M_CLASS: case M_INTERFACE: case M_ANNOTATION: - c_free(c_object(*p)); + c_freelistInsert(freelist, c_object(*p)); break; case M_BASE: case M_COLLECTION: if ((c_collectionType(t)->kind == OSPL_C_ARRAY) && (c_collectionType(t)->maxSize != 0)) { - c_freeReferences(c_metaObject(t), p); + c_freeReferences(c_metaObject(t), p, freelist); } else { - c_free(c_object(*p)); + c_freelistInsert(freelist, c_object(*p)); } break; case M_EXCEPTION: case M_STRUCTURE: case M_UNION: - c_freeReferences(c_metaObject(type),p); + c_freeReferences(c_metaObject(type),p, freelist); break; case M_PRIMITIVE: switch (c_primitive(t)->kind) { @@ -2175,7 +2299,8 @@ _freeReference ( static c_bool _c_freeReferences ( c_metaObject metaObject, - c_object o) + c_object o, + c_freelist freelist) { c_type type; c_class cls; @@ -2213,7 +2338,7 @@ _c_freeReferences ( for (i=0;ireferences[i]); type = property->type; - freeReference(C_DISPLACE(o,property->offset),type); + freeReference(C_DISPLACE(o,property->offset),type, freelist); } cls = cls->extends; } @@ -2224,7 +2349,7 @@ _c_freeReferences ( for (i=0;ireferences[i]); type = property->type; - freeReference(C_DISPLACE(o,property->offset),type); + freeReference(C_DISPLACE(o,property->offset),type, freelist); } break; case M_EXCEPTION: @@ -2233,7 +2358,7 @@ _c_freeReferences ( for (i=0;ireferences[i]); type = c_specifier(member)->type; - freeReference(C_DISPLACE(o,member->offset),type); + freeReference(C_DISPLACE(o,member->offset),type, freelist); } break; case M_UNION: @@ -2268,7 +2393,7 @@ _c_freeReferences ( while ((jvalue) == C_EQ) { c_freeReferences(c_metaObject(references[i]), - C_DISPLACE(o,c_type(metaObject)->alignment)); + C_DISPLACE(o,c_type(metaObject)->alignment), freelist); type = c_specifier(references[i])->type; } j++; @@ -2293,13 +2418,13 @@ _c_freeReferences ( if (c_typeIsRef(type)) { for (i=0;isize; for (i=0;ialias),o); + c_freeReferences(c_metaObject(c_typeDef(metaObject)->alias),o, freelist); break; case M_ATTRIBUTE: case M_RELATION: ACTUALTYPE(type,c_property(metaObject)->type); - freeReference(C_DISPLACE(o,c_property(metaObject)->offset),type); + freeReference(C_DISPLACE(o,c_property(metaObject)->offset),type, freelist); break; case M_MEMBER: ACTUALTYPE(type,c_specifier(metaObject)->type); - freeReference(C_DISPLACE(o,c_member(metaObject)->offset),type); + freeReference(C_DISPLACE(o,c_member(metaObject)->offset),type, freelist); break; case M_UNIONCASE: ACTUALTYPE(type,c_specifier(metaObject)->type); - freeReference(o,type); + freeReference(o,type, freelist); break; case M_MODULE: - c_free(c_module(o)->scope); + c_freelistInsert(freelist, c_module(o)->scope); break; case M_PRIMITIVE: /* Do nothing */ @@ -2347,9 +2472,7 @@ _c_freeReferences ( } #ifndef NDEBUG -/* - * Function used in OS_REPORT in c_free - */ +/* Function used in OS_REPORT in c_free */ static const c_char * metaKindImage ( c_metaKind kind) @@ -2393,149 +2516,156 @@ c_free ( { c_header header; c_type type, headerType; + C_STRUCT(c_freelist) freelist; os_uint32 safeCount; #if CHECK_REF c_bool matchesRefRequest = FALSE; #endif + if (object == NULL) { return; } - header = c_header (object); + c_freelistInit(&freelist); + + while (object) { + header = c_header (object); #ifndef NDEBUG - assert(header->confidence == CONFIDENCE); - if ((pa_ld32(&header->refCount) & REFCOUNT_MASK) == 0) { + assert(header->confidence == CONFIDENCE); + if ((pa_ld32(&header->refCount) & REFCOUNT_MASK) == 0) { #if CHECK_REF - UT_TRACE("\n\n===========Free(%p) already freed =======\n", object); + UT_TRACE("\n\n===========Free(%p) already freed =======\n", object); #endif - OS_REPORT(OS_ERROR, - "Database",0, - "Object (%p) of type '%s', kind '%s' already deleted", - object, - c_metaName(c_metaObject(header->type)), - metaKindImage(c_baseObject(header->type)->kind)); - assert(0); - } + OS_REPORT(OS_ERROR, + "Database",0, + "Object (%p) of type '%s', kind '%s' already deleted", + object, + c_metaName(c_metaObject(header->type)), + metaKindImage(c_baseObject(header->type)->kind)); + assert(0); + } #endif /* NDEBUG */ #if CHECK_REF - /* Take a local pointer, since header->type pointer will be deleted */ - headerType = header->type; - ACTUALTYPE(type,headerType); - if (type && c_metaObject(type)->name) { - if (strlen(c_metaObject(type)->name) >= CHECK_REF_TYPE_LEN) { - if (strncmp(c_metaObject(type)->name, CHECK_REF_TYPE, strlen(CHECK_REF_TYPE)) == 0) { - matchesRefRequest = TRUE; + /* Take a local pointer, since header->type pointer will be deleted */ + headerType = header->type; + ACTUALTYPE(type,headerType); + if (type && c_metaObject(type)->name) { + if (strlen(c_metaObject(type)->name) >= CHECK_REF_TYPE_LEN) { + if (strncmp(c_metaObject(type)->name, CHECK_REF_TYPE, strlen(CHECK_REF_TYPE)) == 0) { + matchesRefRequest = TRUE; + } + } } - } - } #endif + safeCount = pa_dec32_nv(&header->refCount); - safeCount = pa_dec32_nv(&header->refCount); - if ((safeCount & REFCOUNT_MASK) != 0) - { - if (safeCount & REFCOUNT_FLAG_TRACE) { - c_type headerType = header->type, type; - void *block; - ACTUALTYPE (type, headerType); - if ((c_baseObjectKind (type) == M_COLLECTION) && ((c_collectionTypeKind (type) == OSPL_C_ARRAY) || (c_collectionTypeKind (type) == OSPL_C_SEQUENCE))) { - block = c_arrayHeader (object); - } else { - block = header; + if ((safeCount & REFCOUNT_MASK) != 0) { + if (safeCount & REFCOUNT_FLAG_TRACE) { + c_type headerType = header->type, type; + void *block; + ACTUALTYPE (type, headerType); + if ((c_baseObjectKind (type) == M_COLLECTION) && + ((c_collectionTypeKind (type) == OSPL_C_ARRAY) || + (c_collectionTypeKind (type) == OSPL_C_SEQUENCE))) + { + block = c_arrayHeader (object); + } else { + block = header; + } + c_mmTrackObject (type->base->mm, block, C_MMTRACKOBJECT_CODE_MIN + 1); } - c_mmTrackObject (type->base->mm, block, C_MMTRACKOBJECT_CODE_MIN + 1); - } - } - else - { - c_base base; + } else { + c_base base; - /* Take a local pointer, since header->type pointer will be deleted */ + /* Take a local pointer, since header->type pointer will be deleted */ #if ! CHECK_REF - headerType = header->type; - ACTUALTYPE(type,headerType); + headerType = header->type; + ACTUALTYPE(type,headerType); #endif - base = type->base; - if (!(safeCount & REFCOUNT_FLAG_ATOMIC)) { - c_freeReferences(c_metaObject(type),object); - } + base = type->base; + if (!(safeCount & REFCOUNT_FLAG_ATOMIC)) { + c_freeReferences(c_metaObject(type),object, &freelist); + } #ifndef NDEBUG #ifdef OBJECT_WALK - { - c_object *prevNext; - c_object *nextPrev; + { + c_object *prevNext; + c_object *nextPrev; - if (header->prevObject != NULL) { - prevNext = &c_header(header->prevObject)->nextObject; - } else { - prevNext = &type->base->firstObject; - } - if (header->nextObject != NULL) { - nextPrev = &c_header(header->nextObject)->prevObject; - } else { - nextPrev = &type->base->lastObject; + if (header->prevObject != NULL) { + prevNext = &c_header(header->prevObject)->nextObject; + } else { + prevNext = &type->base->firstObject; + } + if (header->nextObject != NULL) { + nextPrev = &c_header(header->nextObject)->prevObject; + } else { + nextPrev = &type->base->lastObject; + } + *prevNext = header->nextObject; + *nextPrev = header->prevObject; } - *prevNext = header->nextObject; - *nextPrev = header->prevObject; - } #endif #endif - if ((c_baseObjectKind(type) == M_COLLECTION) && - ((c_collectionTypeKind(type) == OSPL_C_ARRAY) || - (c_collectionTypeKind(type) == OSPL_C_SEQUENCE))) { - c_arrayHeader hdr; + if ((c_baseObjectKind(type) == M_COLLECTION) && + ((c_collectionTypeKind(type) == OSPL_C_ARRAY) || + (c_collectionTypeKind(type) == OSPL_C_SEQUENCE))) { + c_arrayHeader hdr; - hdr = c_arrayHeader(object); + hdr = c_arrayHeader(object); #ifdef OSPL_STRICT_MEM - { - c_long size; - size = c_arraySize(object); - memset(hdr,0xff,ARRAYMEMSIZE(size)); - } + { + c_long size; + size = c_arraySize(object); + memset(hdr,0xff,ARRAYMEMSIZE(size)); + } #endif - if (safeCount & REFCOUNT_FLAG_TRACE) { - c_mmTrackObject (base->mm, hdr, C_MMTRACKOBJECT_CODE_MIN + 3); - } - c_mmFree(base->mm, hdr); - } else { + if (safeCount & REFCOUNT_FLAG_TRACE) { + c_mmTrackObject (base->mm, hdr, C_MMTRACKOBJECT_CODE_MIN + 3); + } + c_mmFree(base->mm, hdr); + } else { #ifdef OSPL_STRICT_MEM - { - /* Only when OSPL_STRICT_MEM has been set so that we can abort on the detection of illegal usage - of a deleted mutex or conditon, without blocking the calling thread indefinitely */ - c_long size; - size = c_typeSize(type); - memset(header,0xff,MEMSIZE(size)); - } + { + /* Only when OSPL_STRICT_MEM has been set so that we can abort on the detection of illegal usage + * of a deleted mutex or conditon, without blocking the calling thread indefinitely + */ + c_long size; + size = c_typeSize(type); + memset(header,0xff,MEMSIZE(size)); + } #endif - if (safeCount & REFCOUNT_FLAG_TRACE) { - c_mmTrackObject (base->mm, header, C_MMTRACKOBJECT_CODE_MIN + 3); + if (safeCount & REFCOUNT_FLAG_TRACE) { + c_mmTrackObject (base->mm, header, C_MMTRACKOBJECT_CODE_MIN + 3); + } + c_mmFree(base->mm, header); + } + /* Do not use type, as it refers to an actual type, while + * we incremented the header->type. + */ + if (base->maintainObjectCount) { + /* Since no special actions need to be performed on going to 0, the + * return-value of the decrement isn't needed. + */ + (void) pa_dec32_nv(&headerType->objectCount); } - c_mmFree(base->mm, header); - } - /* Do not use type, as it refers to an actual type, while - * we incremented the header->type. - */ - if (base->maintainObjectCount) { - /* Since no special actions need to be performed on going to 0, the - * return-value of the decrement isn't needed. */ - (void) pa_dec32_nv(&headerType->objectCount); - } #if TYPE_REFC_COUNTS_OBJECTS - c_free(headerType); /* free the header->type */ + c_free(headerType); /* free the header->type */ #endif - } + } #if CHECK_REF - if(matchesRefRequest) - { - UT_TRACE("\n\n============ Free(%p): %d -> %d =============\n", - object, (safeCount & REFCOUNT_MASK)+1, safeCount & REFCOUNT_MASK); - - } + if (matchesRefRequest) { + UT_TRACE("\n\n============ Free(%p): %d -> %d =============\n", + object, (safeCount & REFCOUNT_MASK)+1, safeCount & REFCOUNT_MASK); + } #endif + object = c_freelistTake(&freelist); + } } c_object @@ -2568,6 +2698,15 @@ c_keep ( oldCount = pa_ld32(&header->refCount); assert((oldCount & REFCOUNT_MASK) > 0); pa_inc32(&header->refCount); /* FIXME: should add pa_inc32_ov and use it here */ + if (oldCount & REFCOUNT_FLAG_CLAMP) { + /* Protect against wrap-around of reference count by forcing + * the refcount up once half the range (24 bits) has been used + * up. The memory will then never be freed, but a memory leak + * is still better than a crash. This resets the flags, which + * is fine for the current set of flags + */ + pa_st32 (&header->refCount, (REFCOUNT_FLAG_CLAMP | (REFCOUNT_FLAG_CLAMP >> 1))); + } if (oldCount & REFCOUNT_FLAG_TRACE) { c_type headerType = header->type, type; void *block; @@ -2808,7 +2947,7 @@ c_baseObjectWalk( * The following deleteGarbage function is therefore created to deal with this leakage at * database destruction. The deleteGarbage function is called by the c_destruct operation. * This function will walk over all remaining objects and collect one reference to each object - * in a trashcan and afterwards free the allocated memory of each object referenced by the trashcan. + * in a trashcan and afterwards free the allocated memory of each object referenced by the trashcan. *******/ #define OBJECTTYPE(t,o) ACTUALTYPE(t,c_header(o)->type) @@ -2831,7 +2970,7 @@ c_metaObject o, c_voidp trashcan) { CHECKOBJECT(o); - c_iterAppend(((c_trashcan)trashcan)->references, c_keep(o)); + ((c_trashcan)trashcan)->references = c_iterAppend(((c_trashcan)trashcan)->references, c_keep(o)); } static c_bool @@ -2840,7 +2979,7 @@ c_object o, c_voidp trashcan) { CHECKOBJECT(o); - c_iterAppend(((c_trashcan)trashcan)->references, c_keep(o)); + ((c_trashcan)trashcan)->references = c_iterAppend(((c_trashcan)trashcan)->references, c_keep(o)); return TRUE; } @@ -2862,7 +3001,7 @@ collectReferenceGarbage( case M_INTERFACE: case M_ANNOTATION: CHECKOBJECT(*p); - c_iterAppend(trashcan->references, c_object(*p)); + trashcan->references = c_iterAppend(trashcan->references, c_object(*p)); break; case M_BASE: case M_COLLECTION: @@ -2872,7 +3011,7 @@ collectReferenceGarbage( walkReferences((c_metaObject)t, p, trashcan); } else { CHECKOBJECT(*p); - c_iterAppend(trashcan->references, c_object(*p)); + trashcan->references = c_iterAppend(trashcan->references, c_object(*p)); } break; case M_EXCEPTION: @@ -3004,7 +3143,7 @@ walkReferences( /* Need to check type again as it might have been fixed */ if (c_typeIsRef(type)) { CHECKOBJECT(ar[i]); - c_iterAppend(trashcan->references, ar[i]); + trashcan->references = c_iterAppend(trashcan->references, ar[i]); } else { walkReferences(c_metaObject(type),ar[i],trashcan); } @@ -3048,7 +3187,7 @@ walkReferences( break; case M_MODULE: CHECKOBJECT(c_module(o)->scope); - c_iterAppend(trashcan->references, c_module(o)->scope); + trashcan->references = c_iterAppend(trashcan->references, c_module(o)->scope); break; case M_PRIMITIVE: /* Do nothing */ @@ -3071,7 +3210,7 @@ static void freeBindings (void *binding, void *arg) c_type type; c_object o; - c_iterInsert(a->trashcan->references, b->object); + a->trashcan->references = c_iterInsert(a->trashcan->references, b->object); while ((o = c_iterTakeFirst(a->trashcan->references)) != NULL) { header = c_header(o); /* skip already freed or corrupted */ @@ -3085,19 +3224,19 @@ static void freeBindings (void *binding, void *arg) switch (c_collectionTypeKind(type)) { case OSPL_C_ARRAY: case OSPL_C_SEQUENCE: - c_iterInsert(a->trashcan->arrays, o); + a->trashcan->arrays = c_iterInsert(a->trashcan->arrays, o); break; case OSPL_C_SCOPE: - c_iterInsert(a->trashcan->scopes, o); + a->trashcan->scopes = c_iterInsert(a->trashcan->scopes, o); break; case OSPL_C_STRING: - c_iterInsert(a->trashcan->trash, o); + a->trashcan->trash = c_iterInsert(a->trashcan->trash, o); break; default: - c_iterInsert(a->trashcan->collections, o); + a->trashcan->collections = c_iterInsert(a->trashcan->collections, o); } } else { - c_iterInsert(a->trashcan->trash, o); + a->trashcan->trash = c_iterInsert(a->trashcan->trash, o); } } } @@ -3120,17 +3259,17 @@ deleteGarbage( mm = base->mm; - trashcan.trash = c_iterNew(NULL); - trashcan.arrays = c_iterNew(NULL); - trashcan.scopes = c_iterNew(NULL); - trashcan.collections = c_iterNew(NULL); - trashcan.references = c_iterNew(NULL); + trashcan.trash = NULL; + trashcan.arrays = NULL; + trashcan.scopes = NULL; + trashcan.collections = NULL; + trashcan.references = NULL; barg.trashcan = &trashcan; barg.mm = mm; ut_avlFreeArg (&c_base_bindings_td, &base->bindings, freeBindings, &barg); - OS_REPORT(OS_INFO,"Database close",0,"Removed %d objects",c_iterLength(trashcan.trash)); + OS_REPORT_NOW(OS_INFO,"Database close",0,-1,"Removed %d objects",c_iterLength(trashcan.trash)); while ((trash = c_iterTakeFirst(trashcan.scopes)) != NULL) { diff --git a/src/database/database/code/c_clone.c b/src/database/database/code/c_clone.c index 7f6465544..5f13a0d8e 100644 --- a/src/database/database/code/c_clone.c +++ b/src/database/database/code/c_clone.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -33,8 +34,7 @@ */ #define C_CLONE_TRACE(p) -/* - * parameter t the type of object o +/* parameter t the type of object o * parameter o the object of which must be determined whether it's a type * Returns TRUE if o is a type. The type of o is needed, because o could be * an inline object, and then c_getType will not work. @@ -42,8 +42,7 @@ #define isType(t, o) (c_isBaseObjectType(t) && c_objectIsType(o)) #define isModule(t, o) (c_isBaseObjectType(t) && c_baseObjectKind(o) == M_MODULE) /*todo: finish this */ -/* - * This object contains a reference to the destination database and a collection +/* This object contains a reference to the destination database and a collection * of processed objects for resolving. This collection contains all 'source * object'-'destination object' pointer pairs, so for each processed object in * the source database, there is a matching object in the destination database. @@ -59,14 +58,12 @@ struct c_clone_s { c_type type_c_type; }; -/* - * This value is used for indentation during debugging tracing. This is not +/* This value is used for indentation during debugging tracing. This is not * thread safe, as it's a shared static variable for the entire process. */ C_CLONE_TRACE(static c_long indent = 0;) -/* - * This function does the actual cloning. A more detailed explanation is given +/* This function does the actual cloning. A more detailed explanation is given * at the implementation. */ c_object @@ -76,9 +73,7 @@ _c_cloneAction( c_object srcObj, c_object dstObj); -/* - * Returns the string representation of a c_metaKind as a hardcoded string. - */ +/* Returns the string representation of a c_metaKind as a hardcoded string. */ static const c_char * metaKindImage ( c_metaKind kind) @@ -115,8 +110,7 @@ metaKindImage ( } -/* - * Compares two pointers. +/* Compares two pointers. * Returns: * - OS_EQ when pointers are equal * - OS_GT when o1 is bigger than o2 @@ -142,8 +136,7 @@ c_cloneComparePointers( return result; } -/* - * This method is used by c_clone to free the c_objects +/* This method is used by c_clone to free the c_objects * when the c_clone->processed_objects collection is freed. */ static void @@ -156,8 +149,7 @@ c_clonePointerFree( c_free(o); } -/* - * The method c_clone uses this method to check whether +/* The method c_clone uses this method to check whether * certain objects have already been cloned or are already being cloned. * It's also a faster way to resolve types (faster than c_metaResolveType), * when the to be resolved type is already cloned or is already being cloned. @@ -184,8 +176,7 @@ c_cloneResolve( *dstObj = ut_get(ut_collection(_this->processed_objects), srcObj); - /* - * If the object has not been resolved, we check whether it's a type + /* If the object has not been resolved, we check whether it's a type * or a module, because then we can try to resolve it using * c_metaResolve. */ @@ -224,8 +215,7 @@ c_cloneResolve( return result; } -/* - * This method recursively clones all (parent) modules of the +/* This method recursively clones all (parent) modules of the * module given. It returns the cloned (and c_keep'ed) module of the module given. * This is done separately from the rest of the clone process, as cloning a module * is the only exception to not cloning all of it's children. @@ -272,8 +262,7 @@ c_cloneModules( return dstModule; } -/* - * This struct is used by c_cloneCloneCollection, which is a helper function +/* This struct is used by c_cloneCloneCollection, which is a helper function * for cloning collections. The dstCollection pointer contains a reference * to the collection to be cloned, the c parameter contains a reference to the * c_clone object. @@ -284,13 +273,13 @@ typedef struct c_cloneCloneCollectionArg_s { } * c_cloneCloneCollectionArg; /* -* Used by _c_cloneAction in a collection walk to clone the objects in a collection. -* First the c_clone->processed_objects is checked whether it contains the object -* (which would mean the object has already been cloned, or is being cloned). -* If the object has not been found, then the type of the object will be resolved, -* after which the object is cloned and inserted into the collection contained by the -* arg parameter. -*/ + * Used by _c_cloneAction in a collection walk to clone the objects in a collection. + * First the c_clone->processed_objects is checked whether it contains the object + * (which would mean the object has already been cloned, or is being cloned). + * If the object has not been found, then the type of the object will be resolved, + * after which the object is cloned and inserted into the collection contained by the + * arg parameter. + */ static c_bool c_cloneCloneCollection ( c_object o, @@ -302,21 +291,16 @@ c_cloneCloneCollection ( c = arg->c; - /* - * First try to resolve the object. - */ + /* First try to resolve the object. */ if(c_cloneResolve(c, o, &clonedObj)) { if(!clonedObj){ c_type oType = c_getType(o); c_type clonedObjType = NULL; - /* - * Try to resolve the type of the object. - */ + /* Try to resolve the type of the object. */ if(c_cloneResolve(c, oType, (void*)&clonedObjType)) { - /* - * If the type of the to-be cloned object is not resolved, the type + /* If the type of the to-be cloned object is not resolved, the type * must be cloned too. */ if(!clonedObjType) @@ -324,9 +308,7 @@ c_cloneCloneCollection ( clonedObjType = _c_cloneAction(c, c_getBase(arg->dstCollection)->metaType[c_baseObjectKind(oType)], oType, NULL); } - /* - * Now we have all we need to clone the object. - */ + /* Now we have all we need to clone the object. */ assert(clonedObjType); clonedObj = _c_cloneAction(c, clonedObjType, o, NULL); c_free(clonedObjType); @@ -359,9 +341,7 @@ c_cloneCloneCollection ( return TRUE; } -/* - * Used by _c_clone in a c_scopeWalk to clone the objects in a c_scope. - */ +/* Used by _c_clone in a c_scopeWalk to clone the objects in a c_scope. */ static void c_cloneCloneScopeObject ( c_metaObject o, @@ -371,8 +351,7 @@ c_cloneCloneScopeObject ( } -/* - * Creates a new c_clone object which contains a reference to the destination +/* Creates a new c_clone object which contains a reference to the destination * database and holds the administration of processed objects. */ c_clone @@ -392,9 +371,7 @@ c_cloneNew(c_base destination) return _this; } -/* - * Cleans up the c_clone object. - */ +/* Cleans up the c_clone object. */ void c_cloneFree(c_clone _this) { @@ -409,8 +386,7 @@ c_cloneFree(c_clone _this) os_free(_this); } -/* - * This function is for cloning objects. The c_clone object _this contains the reference to +/* This function is for cloning objects. The c_clone object _this contains the reference to * the destination database where obj should be cloned into. This is a deep-copy, so * all references are cloned too. * @@ -426,8 +402,7 @@ c_cloneCloneObject( c_object o; c_type type = NULL; - /* - * Before each action a clean administration of the processed objects is created, + /* Before each action a clean administration of the processed objects is created, * and after the clone, destroyed. * This is done, because of various problems if we don't do this: * - cloning from different databases @@ -484,8 +459,7 @@ c_cloneCloneObject( return o; } -/* - * This method does the actual cloning. The c_clone _this object contains the reference +/* This method does the actual cloning. The c_clone _this object contains the reference * to the c_clone object containing the administration of processed objects (to be * able to handle cyclic references, and so objects are not cloned multiple times), * and a reference to the destination database. The c_type type is the type of @@ -531,8 +505,7 @@ _c_cloneAction( } ) - /* - * Check whether dstObj is NULL or not. If it isn't, it's an inline object + /* Check whether dstObj is NULL or not. If it isn't, it's an inline object * to which the srcObj data must be cloned. If dstObj is NULL, we need * to see if it already exists (and return it if true), or * allocate memory depending on what kind of object it is. @@ -605,8 +578,7 @@ _c_cloneAction( c_object *dstRef; c_object srcRef; c_class cls = c_class(type); - /* - * we are going to handle cls and each type it extends. This is done as + /* we are going to handle cls and each type it extends. This is done as * follows: * while(cls){ * ... do what is necessary ... @@ -691,8 +663,7 @@ _c_cloneAction( } ) - /* - * Modules are handled as a special case, because we don't want + /* Modules are handled as a special case, because we don't want * every object and type in a module cloned. This is done, because * e.g. when we clones some struct in module M in the source database, * the result should be a struct in module M in the destination database. @@ -715,8 +686,7 @@ _c_cloneAction( } else { - /* - * This object is not definedIn a module, but some other + /* This object is not definedIn a module, but some other * metaObject. First see if the definedIn metaObject is * in the destination database. */ @@ -746,8 +716,7 @@ _c_cloneAction( return NULL; /* error */ } - /* - * If the type of the definedIn metaObject cannot be + /* If the type of the definedIn metaObject cannot be * resolved, clone it. */ if(!definedInType) @@ -758,8 +727,7 @@ _c_cloneAction( NULL); } - /* - * Clone the definedIn metaObject to the destination + /* Clone the definedIn metaObject to the destination * database. */ c_metaObject(dstObj)->definedIn = _c_cloneAction(_this, @@ -838,8 +806,7 @@ _c_cloneAction( { size = c_arraySize(srcObj); } - /* - * c_typeHasRef returns true when c_typeIsRef or c_typeHasRef is true for + /* c_typeHasRef returns true when c_typeIsRef or c_typeHasRef is true for * any object it contains. I.e. if an array with inline structs (no ref) * contains a pointer (ref), c_typeHasRef also returns TRUE. * diff --git a/src/database/database/code/c_collection.c b/src/database/database/code/c_collection.c index 4e9e6961e..e2ed481bd 100644 --- a/src/database/database/code/c_collection.c +++ b/src/database/database/code/c_collection.c @@ -1,10 +1,11 @@ /* -*- mode: c; c-file-style: "k&r"; c-basic-offset: 4; -*- */ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -36,6 +37,7 @@ #include "c_stringSupport.h" #include "c_mmbase.h" #include "c__mmbase.h" +#include "os_assert.h" #include "c_list_tmpl.h" #define C__LISTIMPL_EQUALS(a,b) (a) == (b) @@ -201,7 +203,7 @@ C_CLASS(collectActionArg); static c_bool collectAction(c_object o, c_voidp arg) { collectActionArg a = (collectActionArg)arg; - c_iterInsert(a->results, c_keep(o)); + a->results = c_iterInsert(a->results, c_keep(o)); if (c_iterLength(a->results) < a->max) { return 1; } @@ -512,6 +514,16 @@ c_setInsert ( return f->object; } +c_bool +c_setContains ( + c_set _this, + c_object o) +{ + C_STRUCT(c_set) *set = (C_STRUCT(c_set) *) _this; + assert(c_collectionIsType(_this, OSPL_C_SET)); + return (ut_avlCLookup (&c_set_td, &set->tree, o) != NULL); +} + static c_object c_setReplace ( c_set _this, @@ -596,7 +608,7 @@ c_setSelect ( arg.results = c_iterNew(NULL); if (max < 1) { - max = 0x7fffffff; /* RP: MAXINT */ + max = 0x7fffffff; } arg.max = (c_ulong) max; c_setRead(_this,q,collectAction,&arg); @@ -689,6 +701,31 @@ c_setWalk( return proceed; } +c_object c_setIterNext (struct c_collectionIter *it) +{ + c_setNode n; + n = ut_avlCIterNext((ut_avlCIter_t *)&it->u.set); + return n ? n->object : NULL; +} + +c_object c_setIterFirst (c_set _this, struct c_collectionIter *it) +{ + C_STRUCT(c_set) *set = (C_STRUCT(c_set) *) _this; + c_setNode n; + assert(c_collectionIsType(_this, OSPL_C_SET)); + +/* Compile time assert to ensure the opaque it->u.set is equal to the size of + * ut_avlCIter_t. This type is opaque so that the database does not have a header + * dependency on ut_avl.h + */ +os_ct_assert(sizeof(it->u.set) == sizeof(ut_avlCIter_t)); + + it->next = c_setIterNext; + it->source = _this; + n = ut_avlCIterFirst(&c_set_td, &set->tree, (ut_avlCIter_t *)&it->u.set); + return n ? n->object : NULL; +} + /*============================================================================*/ /* BAG COLLECTION TYPE */ /*============================================================================*/ @@ -817,7 +854,7 @@ c_bagSelect ( arg.results = c_iterNew(NULL); if (max < 1) { - max = 0x7fffffff; /* RP: MAXINT */ + max = 0x7fffffff; } arg.max = (c_ulong) max; c_bagRead(_this,q,collectAction,&arg); @@ -1114,28 +1151,38 @@ c_tableRemove ( return object; } -#ifdef _NIL_ c_object c_tableFind ( c_table _this, - c_value *keyValues) + c_value *keyValues, + c_ulong nrOfKeys) +{ + return c_keep (c_tableFindWeakRef(_this, keyValues, nrOfKeys)); +} + +c_object +c_tableFindWeakRef ( + c_table _this, + c_value *keyValues, + c_ulong nrOfKeys) { C_STRUCT(c_table) *table = (C_STRUCT(c_table) *)_this; union c_tableContents *contents; c_tableNode found; c_object object; - c_ulong i, nrOfKeys; + c_ulong i, nrOfKeys_table; assert(c_collectionIsType(_this, OSPL_C_DICTIONARY)); _READ_BEGIN_(_this); - - if (table->key == NULL || (nrOfKeys = c_arraySize(table->key)) == 0) { + if (table->key == NULL || (nrOfKeys_table = c_arraySize(table->key)) == 0) { if (table->contents.object == NULL) { goto notfound; } object = table->contents.object; } else { + assert(nrOfKeys == nrOfKeys_table); + OS_UNUSED_ARG(nrOfKeys_table); contents = &table->contents; for (i = 0; i < nrOfKeys; i++) { if ((found = ut_avlLookup (&c_table_td, &contents->tree, &keyValues[i])) == NULL) { @@ -1147,12 +1194,11 @@ c_tableFind ( object = contents->object; } _READ_END_(_this); - return c_keep (object); + return object; notfound: _READ_END_ (table); return NULL; } -#endif static c_tableNode tableNext( @@ -1230,8 +1276,7 @@ c_tableReadCursor ( _READ_BEGIN_(table); if (table->key == NULL || (nrOfKeys = c_arraySize (table->key)) == 0) { - /* Special case when no key is defined; single place - * buffer */ + /* Special case when no key is defined; single place buffer */ _READ_END_(table); if (table->cursor[0] == NULL) { _CHECK_CONSISTENCY_(table,table->contents.object); @@ -1266,7 +1311,8 @@ c_tablePeekCursor ( _READ_BEGIN_(table); /* If table->key == NULL, table is a single place buffer. In that case cursor[0] - * contains the cursor for that buffer. */ + * contains the cursor for that buffer. + */ if (table->key == NULL || (nrOfKeys = c_arraySize(table->key)) == 0) { return table->cursor[0]; } @@ -1370,12 +1416,14 @@ tableReadTakeRangeWalk ( n = ut_avlIterSucc (&c_table_td, tree, &it, start); } /* Don't bother looking at the end of the range if there's no - * matching data */ + * matching data + */ if (n == NULL) { return proceed; } /* Endpoint of the iteration: if N is outside the range, abort, - * else look up the first node beyond the range */ + * else look up the first node beyond the range + */ if (end == NULL) { endn = NULL; } else if (include_end) { @@ -1404,9 +1452,10 @@ tableReadTakeActionNonMatchingKey ( c_ulong keyIndex) { /* FIXME: this can't be right: for any key but the one nested most - deeply, N doesn't actually point to an object. Hence any table - with multi-level keys can be tricked into returning the wrong - result or crashes (in practice, only if the key is a string) */ + * deeply, N doesn't actually point to an object. Hence any table + * with multi-level keys can be tricked into returning the wrong + * result or crashes (in practice, only if the key is a string) + */ if ((keyIndex > 0) && (query != NULL)) { c_qKey key = query->keyField[keyIndex-1]; if (key->expr != NULL) { @@ -1567,12 +1616,14 @@ c_tableReadCircular ( obj = c_tableReadCursor(_this); if (!obj) { /* Read till the end of the table, so wrap around to read up to - * the pivot. */ + * the pivot. + */ continue; } /* Perform the action-routine. If it return FALSE we have to stop walking - * over the table. */ + * over the table. + */ if (!action(obj, arg)) { return FALSE; } @@ -1593,7 +1644,7 @@ c_tableSelect ( arg.results = c_iterNew(NULL); if (max < 1) { - max = 0x7fffffff; /* RP: MAXINT */ + max = 0x7fffffff; } arg.max = (c_ulong) max; c_tableRead(_this,q,collectAction,&arg); @@ -1739,7 +1790,8 @@ c_tableTake ( if (table->contents.object != NULL) { c_object o = NULL; /* FIXME: this can't be right: action is called regardless - * of whether the predicate is satisfied */ + * of whether the predicate is satisfied + */ if (predMatches (p, table->contents.object)) { o = table->contents.object; table->contents.object = NULL; @@ -2474,7 +2526,7 @@ c_object c_collectionIterFirst(c_collection c, struct c_collectionIter *it) switch(c_collectionType(type)->kind) { case OSPL_C_QUERY: case OSPL_C_DICTIONARY: - case OSPL_C_SET: + case OSPL_C_SET: return c_setIterFirst(c, it); case OSPL_C_BAG: assert(0); case OSPL_C_LIST: return c_listIterFirst(c, it); case OSPL_C_ARRAY: @@ -3053,7 +3105,6 @@ c_tableNew( t->key = NULL; } t->cursor = c_arrayNew(c_voidp_t(base),nrOfKeys ? nrOfKeys : 1); - c_iterFree(fieldList); t->mm = c_baseMM(base); if (nrOfKeys == 0) { t->contents.object = NULL; @@ -3061,71 +3112,17 @@ c_tableNew( ut_avlInit (&c_table_td, &t->contents.tree); } } + c_iterFree(fieldList); return (c_collection)t; } #undef C_TABLE_ANONYMOUS_NAME -#if 0 -c_collection -c_queryNew( - c_collection c, - q_expr predicate, - c_value params[]) -{ - c_base base; - c_type subType; - c_qPred pred; - C_STRUCT(c_query) *q; - c_metaObject o; - c_string name; - c_long size; - c_qResult result; - - base = c__getBase(c); - - subType = c_collectionType(c__getType(c))->subType; - result = c_qPredNew(subType,c_keyList(c),predicate,params,&pred); - if (result == CQ_RESULT_OK) { - if (pred == NULL) { - return NULL; - } - - if (c_metaObject(subType)->name != NULL) { - size = strlen(c_metaObject(subType)->name)+8; - name = c_stringMalloc(base,size); - os_sprintf(name,"QUERY<%s>",c_metaObject(subType)->name); - } else { - name = c_stringNew(base,"QUERY<******>"); - } - - o = c_metaDefine(c_metaObject(base),M_COLLECTION); - c_metaObject(o)->name = name; - c_collectionType(o)->kind = C_QUERY; - c_collectionType(o)->subType = c_keep(subType); - c_collectionType(o)->maxSize = C_UNLIMITED; - c_metaFinalize(o); - - q = c_query(c_new(c_type(o))); - c_free(o); - if (q) { - q->source = c; - q->pred = pred; - - c_qPredOptimize(q->pred); - } - } else { - q = NULL; - } - - return (c_collection)q; -} -#else #define C_QUERY_ANONYMOUS_NAME "QUERY<******>" c_collection c_queryNew( - c_collection c, - q_expr predicate, - c_value params[]) + const c_collection c, + const q_expr predicate, + const c_value params[]) { c_base base; c_type subType; @@ -3187,7 +3184,6 @@ c_queryNew( return (c_collection)q; } #undef C_QUERY_ANONYMOUS_NAME -#endif void c_clear ( diff --git a/src/database/database/code/c_field.c b/src/database/database/code/c_field.c index 373a9748d..c5e4f6124 100644 --- a/src/database/database/code/c_field.c +++ b/src/database/database/code/c_field.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -218,13 +219,13 @@ c_fieldNew ( "failed to allocate field->path array"); c_iterWalk(nameList,(c_iterWalkAction)os_free,NULL); } - c_iterFree(nameList); } else { OS_REPORT(OS_ERROR, "c_fieldNew failed",0, "failed to process field name <%s>", fieldName); } + c_iterFree(nameList); return field; } @@ -450,27 +451,6 @@ c_fieldValue( return v; } -#if 0 - v.kind = field->kind; - switch(v.kind) { - case V_STRING: - case V_WSTRING: - case V_OBJECT: - v.is.Object = *(c_object *)p; -/* memcpy(&v.is,p,field->type->size);*/ - c_keep(v.is.Object); - break; - case V_FIXED: - case V_UNDEFINED: - case V_COUNT: - break; - default: - v.is.LongLong = *(c_longlong *)p; -/* memcpy(&v.is,p,field->type->size);*/ - break; - } - return v; -#else #define _VAL_(f,t) v.is.f = *(t *)p v.kind = field->kind; @@ -505,7 +485,6 @@ c_fieldValue( return v; #undef _VAL_ -#endif } void diff --git a/src/database/database/code/c_iterator.c b/src/database/database/code/c_iterator.c index ff0c2bc2b..b8aa62152 100644 --- a/src/database/database/code/c_iterator.c +++ b/src/database/database/code/c_iterator.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -253,7 +254,10 @@ c_bool c_iterContains(c_iter iter, void *object) c_iterIter c_iterIterGet(c_iter i) { c_iterIter result; - result.current = c__iterImplIterFirst(&i->x, &result.it); + memset(&result, 0, sizeof(result)); + if (i != NULL) { + result.current = c__iterImplIterFirst(&i->x, &result.it); + } return result; } diff --git a/src/database/database/code/c_laptime.c b/src/database/database/code/c_laptime.c index 5d80413b0..db73f6999 100644 --- a/src/database/database/code/c_laptime.c +++ b/src/database/database/code/c_laptime.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/database/database/code/c_metabase.c b/src/database/database/code/c_metabase.c index e25a9ccca..fe2fec28d 100644 --- a/src/database/database/code/c_metabase.c +++ b/src/database/database/code/c_metabase.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -542,7 +543,7 @@ c__metaDefineCommon( } assert(o); o->kind = kind; - c_mutexInit(base, &c_module(o)->mtx); + (void)c_mutexInit(base, &c_module(o)->mtx); break; case M_ANNOTATION: case M_CLASS: @@ -686,64 +687,24 @@ c_typeInit( c_type(o)->size = size; } - static void -getProperties( +getPropertiesScopeWalkAction( c_metaObject o, - c_scopeWalkActionArg iter) + c_scopeWalkActionArg arg) { - assert(iter); + c_iter *iter = (c_iter *)arg; switch(c_baseObjectKind(o)) { case M_ATTRIBUTE: case M_RELATION: case M_MEMBER: case M_UNIONCASE: - (void)c_iterInsert((c_iter)iter,o); + *iter = c_iterInsert(*iter, o); break; default: break; } } -static void -getPropertiesScopeWalkAction( - c_metaObject o, - c_scopeWalkActionArg arg /* c_iter */) -{ - getProperties(o, (c_iter)arg); -} -#if 0 -static c_long -c_compareMembers( - c_member *m1, - c_member *m2) -{ - c_type t1,t2; -#define _ALIGN_(m) (c_specifier(m)->type->alignment) -#define _KIND_(m) (c_baseObjectKind(c_specifier(m)->type)) - if (*m1 == *m2) return 0; - if (*m1 == NULL) return 1; - if (*m2 == NULL) return -1; - t1 = c_specifier(*m1)->type; - while (c_baseObjectKind(t1) == M_TYPEDEF) { - t1 = c_typeDef(t1)->alias; - } - t2 = c_specifier(*m2)->type; - while (c_baseObjectKind(t2) == M_TYPEDEF) { - t2 = c_typeDef(t2)->alias; - } - if ((c_baseObjectKind(t1) == M_COLLECTION) && - (c_baseObjectKind(t2) != M_COLLECTION)) return 1; - if ((c_baseObjectKind(t1) != M_COLLECTION) && - (c_baseObjectKind(t2) == M_COLLECTION)) return -1; - if (_ALIGN_(*m1) > _ALIGN_(*m2)) return -1; - if (_ALIGN_(*m1) < _ALIGN_(*m2)) return 1; - return strcmp(c_specifier(*m1)->name,c_specifier(*m2)->name); -#undef _KIND_ -#undef _ALIGN_ -} -#endif - static c_long c_compareProperty( const void *ptr1, @@ -1082,7 +1043,7 @@ _c_metaCompare ( if (result != E_EQUAL) { return result; } - if (c_union(o)->cases == c_union(o)->cases) { + if (c_union(object)->cases == c_union(o)->cases) { return E_EQUAL; /* used to identify both being NULL */ } length = c_arraySize(c_union(object)->cases); @@ -1140,7 +1101,7 @@ _c_metaCompare ( case M_ANNOTATION: { c_property property,p; - c_iter iter; + c_iter iter = NULL; if (c_baseObjectKind(o) == M_CLASS) { result = _c_metaCompare(c_metaObject(c_class(object)->extends), @@ -1154,8 +1115,7 @@ _c_metaCompare ( if (metaScopeCount(c_metaObject(o)) != metaScopeCount(c_metaObject(object))) { return E_UNEQUAL; } - iter = c_iterNew(NULL); - metaScopeWalk(c_metaObject(o), getPropertiesScopeWalkAction, iter); + metaScopeWalk(c_metaObject(o), getPropertiesScopeWalkAction, &iter); length = c_iterLength(iter); if (length > 0) { @@ -1191,8 +1151,7 @@ _c_metaCompare ( return E_EQUAL; } -/* - * Compares two pointers. +/* Compares two pointers. * Returns: * - OS_EQ when pointers are equal * - OS_GT when o1 is bigger than o2 @@ -1326,6 +1285,7 @@ c__metaFinalize( member->offset = alignSize(size,pa); ps = propertySize(type); if (ps == 0) { + c_iterFree(refList); return S_ILLEGALRECURSION; } size = member->offset + ps; @@ -1356,8 +1316,7 @@ c__metaFinalize( c_iter refList; c_ulong length; - /* - * A union has the following C syntax: + /* A union has the following C syntax: * struct union { * _d; * _u; @@ -1411,6 +1370,7 @@ c__metaFinalize( } ps = propertySize(type); if (ps == 0) { + c_iterFree(refList); return S_ILLEGALRECURSION; } if (ps > size) { @@ -1420,7 +1380,6 @@ c__metaFinalize( } } } - /*size += c_union(o)->switchType->size + alignSize(c_union(o)->switchType->size, alignment);*/ size += alignSize(c_union(o)->switchType->size, alignment); if (refList != NULL) { i=0; @@ -1514,7 +1473,7 @@ c__metaFinalize( case M_CLASS: { c_property property; - c_iter iter; + c_iter iter = NULL; c_type type; c_property *properties; os_size_t offset; @@ -1531,8 +1490,7 @@ c__metaFinalize( assert(alignment > 0); } } - iter = c_iterNew(NULL); - metaScopeWalk(c_metaObject(o), getPropertiesScopeWalkAction, iter); + metaScopeWalk(c_metaObject(o), getPropertiesScopeWalkAction, &iter); if (c_interface(o)->inherits != NULL) { length = c_arraySize(c_interface(o)->inherits); for (i=0; itype); if (ps == 0) { + os_free(properties); + if (refList != NULL) { + c_iterFree(refList); + } return S_ILLEGALRECURSION; } size = property->offset + ps; @@ -2793,9 +2755,7 @@ c_isBaseObjectType( } -/* - * Returns TRUE is obj is a c_baseObject. - */ +/* Returns TRUE is obj is a c_baseObject. */ c_bool c_isBaseObject(c_object obj) { diff --git a/src/database/database/code/c_metafactory.c b/src/database/database/code/c_metafactory.c index f582c10a5..348a78878 100644 --- a/src/database/database/code/c_metafactory.c +++ b/src/database/database/code/c_metafactory.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/database/database/code/c_misc.c b/src/database/database/code/c_misc.c index 71baa0fb5..0fbca125c 100644 --- a/src/database/database/code/c_misc.c +++ b/src/database/database/code/c_misc.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/database/database/code/c_mmbase.c b/src/database/database/code/c_mmbase.c index 062502385..461a576dd 100644 --- a/src/database/database/code/c_mmbase.c +++ b/src/database/database/code/c_mmbase.c @@ -1,10 +1,9 @@ -/* -*- mode: c; c-file-style: "k&r"; c-basic-offset: 4; -*- */ - /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/database/database/code/c_mmheap.c b/src/database/database/code/c_mmheap.c new file mode 100644 index 000000000..e33a68cef --- /dev/null +++ b/src/database/database/code/c_mmheap.c @@ -0,0 +1,1424 @@ +/* -*- mode: c; c-file-style: "k&r"; c-basic-offset: 4; -*- */ + +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#include +#include +#include + +#include "os_defs.h" +#include "os_stdlib.h" +#include "os_signature.h" +#include "os_time.h" +#include "os_heap.h" +#include "os_report.h" +#include "os_abstract.h" +#include "c_sync.h" + +#include "c_mmheap.h" + +#if HAVE_VALGRIND +#include "memcheck.h" +#endif + +/* A classical eager-coalescing best-fit heap with internal boundary + * tags. For 1 and 2 unit-sized free blocks, it maintains free lists; + * any larger free block is in an AVL-tree sorted on size, with each + * node a doubly-linked list of free blocks of that size. + * + * A heap may consist of multiple regions, the free blocks + * administration is unified. + */ + +#define PRINTF_PTR(p) ((int) (2 * sizeof (p))), ((os_address) (p)) + +#define XA(x, a) (((x) + (a) - 1) & (~ (os_address) ((a) - 1))) +#define ALIGNMENT XA (sizeof (struct c_mmheap_allocated), 8) +#define HDR_SIZE (A (sizeof (struct c_mmheap_allocated))) +#define A(x) XA ((x), ALIGNMENT) + +#define SPLIT_CONST (1 * ALIGNMENT) +#define FREE1_SIZE (1 * ALIGNMENT) +#define FREE2_SIZE (2 * ALIGNMENT) +#define MIN_TREE_SIZE (3 * ALIGNMENT) + +#define USED ((os_address)0x1) /* 0 for free blocks, 1 for used ones */ +#define CHECK ((os_address)0x2) /* 0 during normal operations, temporarily 1 for free blocks during a heap check */ +#define ZERO_FLAG ((os_address)0x4) /* assumed to be 0 */ +#define FLAGS ((os_address)0x7) + +#define GET_SIZE(f) ((f)->size_and_flags & ~FLAGS) +#define GET_USED(f) ((f)->size_and_flags & USED) +#define GET_CHECK(f) ((f)->size_and_flags & CHECK) +#define GET_NEXT(b) ((struct c_mmheap_tree *) ((char *) (b) + HDR_SIZE + GET_SIZE (b))) +#define IS_MARKER(b) (GET_SIZE (b) == 0) /* for check_heap () */ + +#define HEIGHTOF(tree) ((tree) == NULL ? 0 : (tree)->height) + +struct c_mmheap_tree { + os_address size_and_flags; + struct c_mmheap_tree *prev; + struct c_mmheap_tree *left; + struct c_mmheap_tree *right; + struct c_mmheap_tree *parent; + struct c_mmheap_tree *list; + int height; +}; + +struct c_mmheap_list { + os_address size_and_flags; + struct c_mmheap_tree *prev; + struct c_mmheap_list *left, *right; +}; + +struct c_mmheap_allocated { + os_address size_and_flags; + struct c_mmheap_tree *prev; +}; + +#if __GNUC__ +#define UNUSED __attribute__ ((unused)) +#else +#define UNUSED +#endif + +static void c_mmheap_breakpoint (struct c_mmheap *heap UNUSED) +{ + fprintf (stderr, "heap corruption detected by check_heap ()\n"); +} + +static int invalid_addr (struct c_mmheap *heap, void *addr) +{ + struct c_mmheap_region *hr = &heap->heap_region; + while (hr) { + if ((char *) addr >= (char *) hr->base + hr->off && + (char *) addr < (char *) hr->base + hr->size) { + return 0; + } + hr = hr->next; + } + return 1; +} + +static int check_list (struct c_mmheap *heap, struct c_mmheap_list *node, struct c_mmheap_list *parent, os_address *n, os_address *amount, int indent, int dump_heap) +{ + int r = 0; + for (; node; node = node->right) { + if (invalid_addr (heap, node)) { + fprintf (stderr, "check_list: illegal node address\n"); + return 1; + } + if (dump_heap) { + fprintf (stderr, "%u%*s %0*"PA_PRIxADDR" %c%c%c %8"PA_PRIuADDR"<-%0*"PA_PRIxADDR" l%0*"PA_PRIxADDR" r%0*"PA_PRIxADDR"\n", + heap->heap_check_serial, indent, "", PRINTF_PTR (node), + GET_USED (node) ? 'u' : 'f', GET_CHECK (node) ? 'c' : ' ', ' ', + GET_SIZE (node), + PRINTF_PTR (node->prev), PRINTF_PTR (node->left), PRINTF_PTR (node->right)); + } + + if (GET_SIZE (node) != FREE1_SIZE && GET_SIZE (node) != FREE2_SIZE) { + fprintf (stderr, "check_list: non-[12]*align byte block in simple list\n"); + r = 1; + } + if (parent) { + if (GET_SIZE (node) != GET_SIZE (parent)) { + fprintf (stderr, "check_list: list nodes have different sizes\n"); + r = 1; + } + } + if (GET_USED (node)) { + fprintf (stderr, "check_list: free node not marked as free\n"); + r = 1; + } + if (IS_MARKER (node)) { + fprintf (stderr, "check_list: marker in list\n"); + r = 1; + } + if (parent != node->left) { + fprintf (stderr, "check_list: parents don't match\n"); + r = 1; + } + if (GET_CHECK (node)) { + fprintf (stderr, "check_list: check bit set\n"); + r = 1; + } + + node->size_and_flags |= CHECK; + (*n)++; + *amount += GET_SIZE (node); + parent = node; + } + return r; +} + +static int check_node_list (struct c_mmheap *heap, struct c_mmheap_tree *node, struct c_mmheap_tree *parent, os_address *n, os_address *amount, int indent, int dump_heap) +{ + int r = 0; + for (; node; node = node->list) { + if (invalid_addr (heap, node)) { + fprintf (stderr, "check_node_list: illegal node address\n"); + return 1; + } + if (dump_heap) { + fprintf (stderr, "%u %*s+%0*"PA_PRIxADDR" %c%c%c %8"PA_PRIuADDR" <-%0*"PA_PRIxADDR" ^%0*"PA_PRIxADDR" ->%0*"PA_PRIxADDR"\n", + heap->heap_check_serial, indent, "", + PRINTF_PTR (node), GET_USED (node) ? 'u' : 'f', GET_CHECK (node) ? 'c' : ' ', ' ', + GET_SIZE (node), + PRINTF_PTR (node->prev), PRINTF_PTR (node->parent), PRINTF_PTR (node->list)); + } + + if (GET_SIZE (node) == FREE1_SIZE || GET_SIZE (node) == FREE2_SIZE) { + fprintf (stderr, "check_node_list: [12]*align byte block in tree list\n"); + r = 1; + } + if (GET_SIZE (node) != GET_SIZE (parent)) { + fprintf (stderr, "check_node_list: list nodes have different sizes\n"); + r = 1; + } + if (GET_USED (node)) { + fprintf (stderr, "check_node_list: free node not marked as free\n"); + r = 1; + } + if (IS_MARKER (node)) { + fprintf (stderr, "check_node_list: marker in node list\n"); + r = 1; + } + if (parent != node->parent) { + fprintf (stderr, "check_node_list: parents don't match\n"); + r = 1; + } + if (GET_CHECK (node)) { + fprintf (stderr, "check_node_list: check bit set\n"); + r = 1; + } + + node->size_and_flags |= CHECK; + (*n)++; + *amount += GET_SIZE (node); + parent = node; + } + return r; +} + +static int check_node (struct c_mmheap *heap, struct c_mmheap_tree *node, struct c_mmheap_tree *parent, os_address *n, os_address *nn, os_address *amount, int indent, int dump_heap) +{ + int r = 0; + + if (node == NULL) { + return 0; + } + if (invalid_addr (heap, node)) { + fprintf (stderr, "check_node: illegal node address\n"); + return 1; + } + + if (dump_heap) { + fprintf (stderr, "%u %*s%0*"PA_PRIxADDR" %c%c%c %8"PA_PRIuADDR" " "<-%0*"PA_PRIxADDR" l%0*"PA_PRIxADDR" r%0*"PA_PRIxADDR" " "^%0*"PA_PRIxADDR" ->%0*"PA_PRIxADDR" h%d\n", + heap->heap_check_serial, indent, "", PRINTF_PTR (node), + GET_USED (node) ? 'u' : 'f', GET_CHECK (node) ? 'c' : ' ', ' ', + GET_SIZE (node), + PRINTF_PTR (node->prev), PRINTF_PTR (node->left), PRINTF_PTR (node->right), + PRINTF_PTR (node->parent), PRINTF_PTR (node->list), + node->height); + } + + if (parent && + ((GET_SIZE (node) < GET_SIZE (parent) && node != parent->left) || + (GET_SIZE (node) > GET_SIZE (parent) && node != parent->right))) { + fprintf (stderr, "check_node: on wrong side of parent\n"); + r++; + } + if (node->height - 1 != (HEIGHTOF (node->left) > HEIGHTOF (node->right) ? + HEIGHTOF (node->left) : HEIGHTOF (node->right))) { + fprintf (stderr, "check_node: height of node %p wrong wrt children\n", (void *) node); + r++; + } + if (HEIGHTOF (node->left) - 1 > HEIGHTOF (node->right) || + HEIGHTOF (node->left) + 1 < HEIGHTOF (node->right)) { + fprintf (stderr, "check_node: imbalance rooted at node %p\n", (void *) node); + r++; + } + if (GET_SIZE (node) == FREE1_SIZE || GET_SIZE (node) == FREE2_SIZE) { + fprintf (stderr, "check_node: [12]*align byte block in tree\n"); + r++; + } + if (GET_USED (node)) { + fprintf (stderr, "check_node: free node not marked as free\n"); + r++; + } + if (IS_MARKER (node)) { + fprintf (stderr, "check_node: marker in tree\n"); + r++; + } + if (parent != node->parent) { + fprintf (stderr, "check_node: parents don't match\n"); + r++; + } + if (GET_CHECK (node)) { + fprintf (stderr, "check_node: check bit set\n"); + r++; + } + + node->size_and_flags |= CHECK; + (*n)++; + (*nn)++; + *amount += GET_SIZE (node); + + r += check_node_list (heap, node->list, node, n, amount, indent, dump_heap); + r += check_node (heap, node->left, node, n, nn, amount, indent + 2, dump_heap); + r += check_node (heap, node->right, node, n, nn, amount, indent + 2, dump_heap); + return r; +} + +static int check_heap (struct c_mmheap *heap, char *call, os_address p0, os_address p1, int lock, int dump_heap) +{ + int r = 0; + os_address nfree; + os_address afree; + struct c_mmheap_allocated *hdr, *phdr; + struct c_mmheap_region *hr; + + if (lock) { + os_mutexLock (&heap->lock); + } + + heap->heap_check_serial++; + + if (dump_heap && call) { + fprintf (stderr, "%u ---- %s (%"PA_PRIuADDR" 0x%"PA_PRIxADDR", %"PA_PRIuADDR" 0x%"PA_PRIxADDR") start of heap\n", + heap->heap_check_serial, call, p0, p0, p1, p1); + } + + nfree = 0; + afree = 0; + + if (dump_heap) { + fprintf (stderr, "%u ---- free %"PA_PRIdADDR" byte blocks list:\n", heap->heap_check_serial, FREE1_SIZE); + } + if (heap == NULL || (heap->free1 && invalid_addr (heap, heap->free1))) { + fprintf (stderr, "check_heap: free %"PA_PRIdADDR" byte blocks list has illegal address\n", FREE1_SIZE); + r++; + } else { + r += check_list (heap, heap->free1, 0, &nfree, &afree, 0, dump_heap); + } + + if (dump_heap) { + fprintf (stderr, "%u ---- free %"PA_PRIdADDR" byte blocks list:\n", heap->heap_check_serial, FREE2_SIZE); + } + if (heap == NULL || (heap->free2 && invalid_addr (heap, heap->free2))) { + fprintf (stderr, "check_heap: free %"PA_PRIdADDR" byte blocks list has illegal address\n", FREE2_SIZE); + r++; + } else { + r += check_list (heap, heap->free2, 0, &nfree, &afree, 0, dump_heap); + } + + if (dump_heap) { + fprintf (stderr, "%u ---- tree:\n", heap->heap_check_serial); + } + if (heap == NULL || (heap->free && invalid_addr (heap, heap->free))) { + fprintf (stderr, "check_heap: free blocks tree has illegal address\n"); + r++; + } else { + os_address tree_n, node_n; + + tree_n = (os_address) (-(os_saddress)nfree); + node_n = 0; + r += check_node (heap, heap->free, 0, &nfree, &node_n, &afree, 0, dump_heap); + tree_n += nfree; + + if (dump_heap) { + fprintf (stderr, "%u ---- free: tree: blocks: %"PA_PRIdADDR" block%s (%"PA_PRIdADDR" key%s)\n", + heap->heap_check_serial, tree_n, tree_n != 1 ? "s" : "", node_n, node_n != 1 ? "s" : ""); + fprintf (stderr, "%u ---- free: blocks adm: %"PA_PRIdADDR" blocks, heap adm: %"PA_PRIdADDR" blocks\n", + heap->heap_check_serial, nfree, heap->n_free_blocks); + fprintf (stderr, "%u ---- free: blocks adm: %"PA_PRIdADDR" bytes, heap adm: %"PA_PRIdADDR" bytes\n", + heap->heap_check_serial, afree, heap->n_free_bytes); + } + if (nfree != heap->n_free_blocks) { + fprintf (stderr, "check_heap: heap->n_free_blocks is incorrect\n"); + r++; + } + if (afree != heap->n_free_bytes) { + fprintf (stderr, "check_heap: heap->n_free_bytes is incorrect\n"); + r++; + } + } + + if (dump_heap > 1) { + fprintf (stderr, "%u ---- linear:\n", heap->heap_check_serial); + } + + for (hr = &heap->heap_region; hr; hr = hr->next) { + phdr = NULL; + hdr = (struct c_mmheap_allocated *) ((char *) hr->base + hr->off); + while ((char *) hdr < ((char *) hr->base + hr->size)) { + if (hdr < (struct c_mmheap_allocated *) ((char *) hr->base + hr->off) || + hdr >= (struct c_mmheap_allocated *) ((char *) hr->base + hr->size)) { + fprintf (stderr, "check_heap: block address illegal\n"); + if (lock) { + os_mutexUnlock (&heap->lock); + } + return 1; + } + + if (dump_heap > 1) { + fprintf (stderr, "%u %0*"PA_PRIxADDR" %c%c%c %8"PA_PRIuADDR" <-%0*"PA_PRIxADDR"\n", + heap->heap_check_serial, + PRINTF_PTR (hdr), + GET_USED (hdr) ? 'u' : 'f', + GET_CHECK (hdr) ? 'c' : ' ', + ' ', + GET_SIZE (hdr), + PRINTF_PTR (hdr->prev)); + } + + if (!GET_USED (hdr)) { + nfree--; + } + + if (!GET_USED (hdr) && !GET_CHECK (hdr)) { + fprintf (stderr, "check_heap: %p marked as free but not in tree\n", (void *) hdr); + r++; + } + if (!GET_USED (hdr) && IS_MARKER (hdr)) { + fprintf (stderr, "check_heap: %p marker has free bit set\n", (void *) hdr); + r++; + } + if ((IS_MARKER (hdr) != 0) != + (((char *) hdr == (char *) hr->base + hr->off) || + ((char *) hdr + HDR_SIZE == (char *) hr->base + hr->size))) { + if (IS_MARKER (hdr)) { + fprintf (stderr, "check_heap: %p marker not at heap boundary\n", (void *) hdr); + } else { + fprintf (stderr, "check_heap: %p non-marker at heap boundary\n", (void *) hdr); + } + r++; + } + if ((char *) hdr + HDR_SIZE + GET_SIZE (hdr) > (char *) hr->base + hr->size) { + fprintf (stderr, "check_heap: %p block ends beyond over heap boundary\n", (void *) hdr); + r++; + } + if (hdr->prev != (struct c_mmheap_tree *) phdr) { + fprintf (stderr, "check_heap: %p prev field wrong (%p expected)\n", (void *) hdr, (void *) phdr); + r++; + } + if (!GET_USED (hdr) && hdr->prev && !GET_USED (hdr->prev)) { + fprintf (stderr, "check_heap: %p free blocks (%p & %p) not merged\n", (void *) hdr, (void *) phdr, (void *) hdr); + r++; + } + if (hdr->size_and_flags & ZERO_FLAG) { + fprintf (stderr, "check_heap: %p bit 2 is set\n", (void *) hdr); + r++; + } + + hdr->size_and_flags &= ~CHECK; + + phdr = hdr; + hdr = (struct c_mmheap_allocated *) GET_NEXT (hdr); + } + } + if (nfree != 0) { + fprintf (stderr, "check_heap: free count doesn't match " "number of nodes (%"PA_PRIuADDR")\n", nfree); + r++; + } + + if (dump_heap) { + fprintf (stderr, "%u ---- end of heap\n", heap->heap_check_serial); + } + + if (lock) { + os_mutexUnlock (&heap->lock); + } + + return r; +} + +static struct c_mmheap_tree *tree_rebalance_one (struct c_mmheap *heap, struct c_mmheap_tree *node) +{ + struct c_mmheap_tree *noderight = node->right; + struct c_mmheap_tree *nodeleft = node->left; + os_int heightright = HEIGHTOF (noderight); + os_int heightleft = HEIGHTOF (nodeleft); + + if (heightright + 1 < heightleft) { + struct c_mmheap_tree *nodeleftleft, *nodeleftright; + int heightleftright; + + assert(nodeleft); + nodeleftleft = nodeleft->left; + nodeleftright = nodeleft->right; + heightleftright = HEIGHTOF (nodeleftright); + + if (HEIGHTOF (nodeleftleft) >= heightleftright) { + node->left = nodeleft->right; + nodeleft->parent = node->parent; + node->parent = nodeleft; + if (nodeleftright) { + nodeleftright->parent = node; + } + nodeleft->right = node; + nodeleft->height = 1 + (node->height = 1 + heightleftright); + if (nodeleft->parent == NULL) { + heap->free = nodeleft; + } else if (node == nodeleft->parent->left) { + nodeleft->parent->left = nodeleft; + } else { + nodeleft->parent->right = nodeleft; + } + return nodeleft->parent; + } else { + assert(nodeleftright); + nodeleftright->parent = node->parent; + + nodeleft->right = nodeleftright->left; + if (nodeleft->right) { + nodeleft->right->parent = nodeleft; + } + node->left = nodeleftright->right; + if (node->left) { + node->left->parent = node; + } + nodeleftright->left = nodeleft; + nodeleft->parent = nodeleftright; + + nodeleftright->right = node; + node->parent = nodeleftright; + + nodeleft->height = node->height = heightleftright; + nodeleftright->height = heightleft; + + if (nodeleftright->parent == NULL) { + heap->free = nodeleftright; + } else if (node == nodeleftright->parent->left) { + nodeleftright->parent->left = nodeleftright; + } else { + nodeleftright->parent->right = nodeleftright; + } + return nodeleftright->parent; + } + } else if (heightleft + 1 < heightright) { + struct c_mmheap_tree *noderightright, *noderightleft; + int heightrightleft; + + assert(noderight); + noderightright = noderight->right; + noderightleft = noderight->left; + heightrightleft = HEIGHTOF (noderightleft); + + if (HEIGHTOF (noderightright) >= heightrightleft) { + node->right = noderight->left; + noderight->parent = node->parent; + node->parent = noderight; + if (noderightleft) { + noderightleft->parent = node; + } + noderight->left = node; + noderight->height = 1 + (node->height = 1 + heightrightleft); + + if (noderight->parent == NULL) { + heap->free = noderight; + } else if (node == noderight->parent->left) { + noderight->parent->left = noderight; + } else { + noderight->parent->right = noderight; + } + return noderight->parent; + } else { + assert(noderightleft); + noderightleft->parent = node->parent; + + noderight->left = noderightleft->right; + if (noderight->left) { + noderight->left->parent = noderight; + } + node->right = noderightleft->left; + if (node->right) { + node->right->parent = node; + } + noderightleft->right = noderight; + noderight->parent = noderightleft; + + noderightleft->left = node; + node->parent = noderightleft; + + noderight->height = node->height = heightrightleft; + noderightleft->height = heightright; + + if (noderightleft->parent == NULL) { + heap->free = noderightleft; + } else if (node == noderightleft->parent->left) { + noderightleft->parent->left = noderightleft; + } else { + noderightleft->parent->right = noderightleft; + } + return noderightleft->parent; + } + } else { + int height = (heightleft < heightright ? heightright : heightleft) + 1; + if (height == node->height) { + return NULL; + } else { + node->height = height; + return node->parent; + } + } +} + +static void tree_rebalance (struct c_mmheap *heap, struct c_mmheap_tree *node) +{ + while (node) { + node = tree_rebalance_one (heap, node); + } +} + +static void tree_insert (struct c_mmheap *heap, struct c_mmheap_tree *node) +{ + os_address node_size; + struct c_mmheap_tree *tmp, *prev; + + if (heap->free == NULL) { + node->left = NULL; + node->right = NULL; + node->parent = NULL; + node->list = NULL; + node->height = 1; + heap->free = node; + return; + } + + tmp = heap->free; + prev = NULL; + node_size = node->size_and_flags; + while (tmp && node_size != tmp->size_and_flags) { + prev = tmp; + if (node_size < tmp->size_and_flags) { + tmp = tmp->left; + } else { + tmp = tmp->right; + } + } + + if (tmp) { + /* add to list */ + node->parent = tmp; + node->list = tmp->list; + tmp->list = node; + if (node->list) { + /* already a list, update (3rd node)->parent */ + node->list->parent = node; + } + } else { + /* add the node to the tree */ + node->left = NULL; + node->right = NULL; + node->list = NULL; + node->height = 1; + if (node_size < prev->size_and_flags) { + prev->left = node; + } else { + prev->right = node; + } + node->parent = prev; + tree_rebalance (heap, prev); + } +} + +static void tree_delete (struct c_mmheap *heap, struct c_mmheap_tree *node) +{ + struct c_mmheap_tree *parent = node->parent, *largest, *rebalance_start; + + if (node->left == NULL) { + struct c_mmheap_tree *right = node->right; + if (parent == NULL) { + heap->free = right; + } else if (node == parent->left) { + parent->left = right; + } else { + parent->right = right; + } + if (right) { + right->parent = node->parent; + } + if (parent) { + tree_rebalance (heap, parent); + } + return; + } + + if (node->right == NULL) { + struct c_mmheap_tree *left = node->left; + if (parent == NULL) { + heap->free = left; + } else if (node == parent->left) { + parent->left = left; + } else { + parent->right = left; + } + left->parent = node->parent; + if (parent) { + tree_rebalance (heap, parent); + } + return; + } + + /* Search the left orphaned subtree for the largest value it + * contains. This will necessarily be smaller than the deleted + * node, and all the nodes in the right subtree. + */ + largest = node->left; + if (largest->right == NULL) { + largest->parent = node->parent; + largest->right = node->right; + largest->height = node->height; + if (largest->right) + largest->right->parent = largest; + + rebalance_start = largest; + } else { + while (largest->right) { + largest = largest->right; + } + rebalance_start = largest->parent; + rebalance_start->right = largest->left; + if (largest->left) { + largest->left->parent = rebalance_start; + } + largest->right = node->right; + largest->left = node->left; + largest->parent = node->parent; + largest->height = node->height; + node->left->parent = largest; + node->right->parent = largest; + } + + if (parent == NULL) { + heap->free = largest; + } else if (node == parent->left) { + parent->left = largest; + } else { + parent->right = largest; + } + + tree_rebalance (heap, rebalance_start); +} + +static void node_insert (struct c_mmheap *heap, struct c_mmheap_tree *node) +{ + if (node->size_and_flags >= MIN_TREE_SIZE) { + tree_insert (heap, node); + } else if (node->size_and_flags >= FREE2_SIZE) { + struct c_mmheap_list *lnode = (struct c_mmheap_list *) node; + lnode->left = NULL; + lnode->right = heap->free2; + if (heap->free2) { + heap->free2->left = lnode; + } + heap->free2 = lnode; + } else { + struct c_mmheap_list *lnode = (struct c_mmheap_list *) node; + lnode->left = NULL; + lnode->right = heap->free1; + if (heap->free1) { + heap->free1->left = lnode; + } + heap->free1 = lnode; + } +} + +static void node_delete (struct c_mmheap *heap, struct c_mmheap_tree *node) +{ + if (node->size_and_flags < FREE2_SIZE) { + struct c_mmheap_list *n = (struct c_mmheap_list *) node; + if (n->right) { + n->right->left = n->left; + } if (n->left) { + n->left->right = n->right; + } else { + heap->free1 = n->right; + } + } else if (node->size_and_flags < MIN_TREE_SIZE) { + struct c_mmheap_list *n = (struct c_mmheap_list *) node; + if (n->right) { + n->right->left = n->left; + } if (n->left) { + n->left->right = n->right; + } else { + heap->free2 = n->right; + } + } + else if (node->list != NULL /* for all nodes but the last in a list */ || + (node->list == NULL && node->parent != NULL /* for the last node in a list */ && + node->parent->list == node)) { + /* removing a node that is part of the list doesn't really + * change the structure of the tree: the list will be + * shortened but the key won't be removed. + */ + if (node->parent == NULL || node->parent->list != node) { + /* removing head of list (i.e. second node in list now + * becomes the head) + */ + struct c_mmheap_tree *next = node->list; + + next->parent = node->parent; + next->left = node->left; + next->right = node->right; + next->height = node->height; + if (node->left) { + node->left->parent = node->list; + } + if (node->right) { + node->right->parent = node->list; + } + if (node->parent) { + struct c_mmheap_tree *parent = node->parent; + if (node == parent->left) { + parent->left = node->list; + } else { + parent->right = node->list; + } + } else { + heap->free = next; + } + } else { + /* removing an element somewhere in the list */ + struct c_mmheap_tree *prev = node->parent; + prev->list = node->list; + if (node->list) { + node->list->parent = node->parent; + } + } + } else { + tree_delete (heap, node); + } +} + +static struct c_mmheap_tree *block_from_list (struct c_mmheap_tree *block) +{ + /* block is a tree node, and the head of a list blocks of this + * size, remove the second to speed things up a bit more. (note + * that this doesn't alter the tree's structure as far as + * balancing is concerned.) + */ + struct c_mmheap_tree *b = block->list; + block->list = b->list; + if (b->list) { + b->list->parent = block; + } + return b; +} + +static struct c_mmheap_tree *split_block (struct c_mmheap *heap, struct c_mmheap_tree *block, os_address size) +{ + struct c_mmheap_tree *new = (struct c_mmheap_tree *) ((char *) block + HDR_SIZE + size); + new->size_and_flags = block->size_and_flags - size - HDR_SIZE; + new->prev = block; + GET_NEXT (block)->prev = new; + block->size_and_flags = size | USED; + heap->n_free_bytes -= size + HDR_SIZE; + return new; +} + +static void *tree_alloc_unsplittable (struct c_mmheap *heap, struct c_mmheap_tree *block) +{ + if (block->list == NULL) { + tree_delete (heap, block); + } else { + block = block_from_list (block); + } + heap->n_free_bytes -= block->size_and_flags; + heap->n_free_blocks--; + block->size_and_flags |= USED; + return block; +} + +static void *mmheap_malloc_lockheld (struct c_mmheap *heap, os_address size) +{ + struct c_mmheap_tree *root, *block; + struct c_mmheap_tree *pred; + void *result; + + if (size == 0) { + return NULL; + } + + size = A (size); + + if (heap->check > 2 && check_heap (heap, "pre c_mmheap_malloc", size, 0, 0, heap->dump)) { + c_mmheap_breakpoint (heap); + } + + if (size <= FREE1_SIZE && heap->free1 != NULL) { + struct c_mmheap_list *b = heap->free1; + if (b->right) b->right->left = NULL; + heap->free1 = b->right; + heap->n_free_bytes -= b->size_and_flags; + heap->n_free_blocks--; + b->size_and_flags |= USED; + result = b; + goto success; + } + + if (size <= FREE2_SIZE && heap->free2 != NULL) { + struct c_mmheap_list *b = heap->free2; + if (b->right) b->right->left = NULL; + heap->free2 = b->right; + heap->n_free_bytes -= b->size_and_flags; + heap->n_free_blocks--; + b->size_and_flags |= USED; + result = b; + goto success; + } + + root = heap->free; /* used to walk the tree. */ + block = NULL; /* best match so far. */ + pred = NULL; /* cand. largest smaller than block */ + while (root) { + if (root->size_and_flags > size) { /* larger than necessary */ + block = root, root = root->left; + } else if (root->size_and_flags < size) { /* too small */ + pred = root, root = root->right; + } else { /* exact fit: don't think, just do */ + result = tree_alloc_unsplittable (heap, root); + goto success; + } + } + + if (block == NULL) { + /* bail out on memory exhaustion. */ + goto failure; + } else if (block->size_and_flags < size + HDR_SIZE + SPLIT_CONST) { + /* unsplittable blocks are short circuited */ + result = tree_alloc_unsplittable (heap, block); + } else if (block->list != NULL) { + /* remove the block from the list, split & reinsert */ + struct c_mmheap_tree *new; + block = block_from_list (block); + new = split_block (heap, block, size); + node_insert (heap, new); + result = block; + } else if (block->size_and_flags - size - HDR_SIZE < MIN_TREE_SIZE) { + /* can't stay in the tree, so remove it, split it and insert the + * remainer in list1 or list2 depending on its size + */ + struct c_mmheap_tree *new; + tree_delete (heap, block); + new = split_block (heap, block, size); + node_insert (heap, new); + result = block; + } else { + struct c_mmheap_tree *new = + (struct c_mmheap_tree *) ((char *) block + HDR_SIZE + size); + os_address new_size = block->size_and_flags - size - HDR_SIZE; + + /* Note: this modifies size & prev in block, but it doesn't touch + * the pointers used by tree_delete() which means that postponing + * removal from the tree is actually possible. + */ + GET_NEXT (block)->prev = new; + block->size_and_flags = size | USED; + heap->n_free_bytes -= size + HDR_SIZE; + + /* This is merely an excellent approximation of the predecessor */ + if (block->left == NULL && (pred == NULL || pred->size_and_flags < new_size)) { + /* Wow! In-place substitution is possible - beware though + * that the fields must be copied in the reverse order of + * their definition to cope with a allocation of 8 or 16 + * bytes, in which case `new' overlaps part of the tree fields + * in `block' + */ + new->height = block->height; + new->list = NULL; + new->parent = block->parent; + new->right = block->right; + new->left = block->left; + new->prev = block; + new->size_and_flags = new_size; + if (new->left) { + new->left->parent = new; + } + if (new->right) { + new->right->parent = new; + } + if (new->parent == NULL) { + heap->free = new; + } else if (new->parent->left == block) { + new->parent->left = new; + } else { + new->parent->right = new; + } + } else { + /* Brute force needed... We simply don't know where new is going to end up. */ + tree_delete (heap, block); + new->size_and_flags = new_size; + new->prev = block; + tree_insert (heap, new); + } + result = block; + } + +success: + heap->n_allocated_blocks++; + if (heap->check > 1 && check_heap (heap, "post c_mmheap_malloc", size, 0, 0, heap->dump)) { + c_mmheap_breakpoint (heap); + } + return ((struct c_mmheap_allocated *) result + 1); +failure: + heap->n_failed_allocations++; + if (heap->check > 1 && check_heap (heap, "post failed c_mmheap_malloc", size, 0, 0, heap->dump)) { + c_mmheap_breakpoint (heap); + } + return NULL; +} + +static void mmheap_free_lockheld (struct c_mmheap *heap, void *ptr) +{ + struct c_mmheap_tree *next, *block; + + if (ptr == NULL) { + return; + } + + block = (struct c_mmheap_tree *) ((struct c_mmheap_allocated *) ptr - 1); + + if (heap->check > 2 && check_heap (heap, "pre c_mmheap_free", (os_address) block, 0, 0, heap->dump)) { + c_mmheap_breakpoint (heap); + } + if (heap->check > 0 && (block->size_and_flags & USED) == 0) { + fprintf (stderr, "c_mmheap_free (%p, %p): block already freed\n", (void *) heap, (void *) ptr); + } + + block->size_and_flags &= ~USED; + + next = GET_NEXT (block); + heap->n_free_bytes += block->size_and_flags; + heap->n_allocated_blocks--; + + if (! GET_USED ((struct c_mmheap_allocated *) block->prev)) { + struct c_mmheap_tree *prev = block->prev; + if (! GET_USED (next)) { + /* combine prev, block, next */ + node_delete (heap, prev); + node_delete (heap, next); + prev->size_and_flags += + HDR_SIZE + block->size_and_flags + + HDR_SIZE + next->size_and_flags; + GET_NEXT (next)->prev = prev; + + /* two headers reclaimed; block, next disappear, block wasn't + counted yet. */ + heap->n_free_bytes += 2 * HDR_SIZE; + heap->n_free_blocks--; + } else { + /* combine prev, block */ + node_delete (heap, prev); + prev->size_and_flags += HDR_SIZE + block->size_and_flags; + next->prev = prev; + + /* one header reclaimed; no free blocks added or removed. */ + heap->n_free_bytes += HDR_SIZE; + } + /* prev is now at least size (prev) + sizeof (header) + size + * (block) which amounts to (>= align) + align + (>= align) = (>= + * 2*align) bytes large, any block at least 3*align bytes large is + * stored in the tree and we can thus use tree_insert () without + * bothering to check whether to block is at least 3*align bytes + * large or not :-). + */ + tree_insert (heap, prev); + } else if (! GET_USED (next)) { + /* combine block, next */ + node_delete (heap, next); + block->size_and_flags += HDR_SIZE + next->size_and_flags; + GET_NEXT (next)->prev = block; + /* tree_insert () is used instead of node_insert () for the + * reasons mentioned above in the `prev' case. + */ + tree_insert (heap, block); + + /* one header reclaimed; no free blocks added or removed. */ + heap->n_free_bytes += HDR_SIZE; + } else { + node_insert (heap, block); + + /* block added, no blocks removed; so increment n_free. */ + heap->n_free_blocks++; + } + + if (heap->check > 1 && check_heap (heap, "post c_mmheap_free", (os_address) block, 0, 0, heap->dump)) { + c_mmheap_breakpoint (heap); + } +} + +static int mmheap_addregion_lockheld (struct c_mmheap *heap, void *block, os_address size) __nonnull_all__; + +static int mmheap_addregion_lockheld (struct c_mmheap *heap, void *block, os_address size) +{ + struct c_mmheap_allocated *node, *endm; + struct c_mmheap_region *hr; + os_address off; + + off = A ((os_address) block + sizeof (struct c_mmheap_region)) - (os_address) block; + size = (((os_address) block + size) & (os_address)(-(os_saddress)ALIGNMENT)) - (os_address) block; + + if (size < off || + size - off < (HDR_SIZE + /* begin marker */ + HDR_SIZE + 3 * HDR_SIZE + /* one tree node */ + HDR_SIZE)) { /* end marker */ + /* size is too small for a heap */ + return -1; + } + + /* Two modes: (1) block immediately follows an existing heap + * block, and (2) it does not. In case (1), we grow the heap + * block, in case (2) we add a heap block. We don't attempt to + * merge three blocks if we happen to fill a hole between two. + * + * Note that in case (1) we don't really have the size & offset + * requirements that we've already checked, but those amount to a + * few bytes and one shouldn't be attempting to grow the heap by + * such small amounts anyway. + */ + assert (heap != NULL); + for (hr = &heap->heap_region; hr; hr = hr->next) { + if ((char *) hr->base + hr->size == (char *) block) { + break; + } + } + + if (hr != NULL) { /* case (1) */ + /* Write an end marker at the end of the new region and + * rewrite the size of the old end marker so that it becomes a + * block that occupies all of the space in the new region. + * Then all we need to do is free the old end marker. + */ + node = (struct c_mmheap_allocated *) ((char *) hr->base + hr->size - HDR_SIZE); + assert (node->size_and_flags == (0 | USED)); + node->size_and_flags += size - HDR_SIZE; + hr->size += size; + } else { /* case (2) */ + /* Make block look like: HEAPBLOCK BEGM NODE ENDM, where BEGM + * and ENDM are begin and end markers, and where NODE is an + * _allocated_ block spanning the bytes between BEGM and + * ENDM. + */ + struct c_mmheap_allocated *begm; + hr = block; + hr->base = block; + hr->off = off; + hr->size = size; + hr->next = heap->heap_region.next; + heap->heap_region.next = hr; + + begm = (struct c_mmheap_allocated *) ((char *) block + off); + begm->size_and_flags = 0 | USED; + begm->prev = NULL; + + node = (struct c_mmheap_allocated *) ((char *) block + off + HDR_SIZE); + node->size_and_flags = (size - off - 3 * HDR_SIZE) | USED; + node->prev = (struct c_mmheap_tree *) begm; + } + + /* Always need an end marker */ + endm = (struct c_mmheap_allocated *) ((char *) block + size - HDR_SIZE); + endm->size_and_flags = 0 | USED; + endm->prev = (struct c_mmheap_tree *) node; + + /* Integrate new block into heap by freeing the node that + * describes the new region as-if it were a allocated memory + */ + heap->n_allocated_blocks++; + mmheap_free_lockheld (heap, (struct c_mmheap_allocated *) node + 1); + return 0; +} + +static void *mmheap_check_pointer_lockheld (struct c_mmheap *heap, void *ptr) +{ + struct c_mmheap_region *hr; + struct c_mmheap_allocated *hdr; + /* find the heap block containing the address, excluding the begin + * and end markers because they could easily be confused for + * allocated blocks + */ + for (hr = &heap->heap_region; hr; hr = hr->next) { + if ((char *) ptr >= (char *) hr->base + hr->off + HDR_SIZE && + (char *) ptr < (char *) hr->base + hr->size - HDR_SIZE) { + break; + } + } + if (hr == NULL) { + /* address is not contained in any heap block */ + return NULL; + } + /* do a linear scan of "hr", ptr is known to be between the begin + * & end markers, so we'll definitely find the block + */ + hdr = (struct c_mmheap_allocated *) ((char *) hr->base + hr->off + HDR_SIZE); + while ((char *) ptr >= (char *) GET_NEXT (hdr)) { + hdr = (struct c_mmheap_allocated *) GET_NEXT (hdr); + } + assert ((char *) ptr >= (char *) hdr); + assert ((char *) ptr < (char *) GET_NEXT (hdr)); + if ((char *) ptr < (char *) hdr + HDR_SIZE) { + /* naughty: ptr points into the block header */ + return NULL; + } else if (! GET_USED (hdr)) { + /* sloppy: ptr points into unallocated memory */ + return NULL; + } else { + return hdr + 1; + } +} + +static void mmheap_dropregion_lockheld (struct c_mmheap *heap, os_address minfree, os_address minsize, os_address align, void (*dropped_cb) (void *arg, void *addr, os_address size), void *arg) __nonnull((1,5)); + +static void mmheap_dropregion_lockheld (struct c_mmheap *heap, os_address minfree, os_address minsize, os_address align, void (*dropped_cb) (void *arg, void *addr, os_address size), void *arg) +{ + /* For each heap region, removes memory from the top of a heap. + * Minimum size removed is MINSIZE, start address will be a + * multiple of ALIGN. Will not free anything if less than minsize + * remains. Returns new top-of-heap address. + */ + struct c_mmheap_region *hr; + /* ALIGN must be a power of 2, and must be at least ALIGNMENT */ + assert ((align & (os_address)(-(os_saddress)align)) == align); + assert (align >= ALIGNMENT); + assert (heap != NULL); + /* willing to return free memory, but want to retain at least + * SPLIT_CONST + ALIGNMENT) so that we only ever have to shrink + * the last free block. + */ + if (minfree < SPLIT_CONST + ALIGNMENT) { + minfree = SPLIT_CONST + ALIGNMENT; + } + /* find the heap block containing the address, excluding the begin + * and end markers because they could easily be confused for + * allocated blocks + */ + for (hr = &heap->heap_region; hr; hr = hr->next) { + struct c_mmheap_allocated *endm; + struct c_mmheap_tree *lastblock; + os_address addr, size, remain; + /* Find header of last block before end marker. If it's in + * use there is nothing we can do + */ + endm = (struct c_mmheap_allocated *) ((char *) hr->base + hr->size - HDR_SIZE); + lastblock = endm->prev; + if (GET_USED (lastblock)) { + continue; + } + /* Align up the address of the payload (we need space for the + * header for the end marker), and see if it would result in + * freeing at least minsize + */ + if (minfree + align - 1 > (os_address) endm - (os_address) lastblock) { + /* minsize + alignment (potentially) pushes address beyond + * heap region + */ + continue; + } + addr = ((os_address) lastblock + HDR_SIZE + minfree + align - 1) & (os_address)(-(os_saddress)align); + assert (addr >= (os_address) lastblock + HDR_SIZE + minfree); + assert (addr <= (os_address) hr->base + hr->size); + size = (os_address) hr->base + hr->size - addr; + if (size < minsize) { + /* not worth the bother */ + continue; + } + remain = addr - ((os_address) lastblock + HDR_SIZE); + assert (remain >= minfree); + assert ((remain & (ALIGNMENT-1)) == 0); + /* state: ... [lb hdr] [... lb space 0 ...] ADDR [... lb space 1 ...] [endm] + * + * where lb space 0 >= minfree and lb space 1 >= minsize and + * ADDR is aligned to a multiple of align. + * + * remain is (sizeof (lb space 0)) + * size is (sizeof (lb space 1) + sizeof (endm)) + * + * Allocate lastblock, update its size, rewrite region, write + * new end marker, free lastblock + */ + node_delete (heap, lastblock); + heap->n_free_bytes -= lastblock->size_and_flags; + heap->n_free_blocks--; + lastblock->size_and_flags = (remain - HDR_SIZE) | USED; + hr->size = addr - (os_address) hr->base; + endm = (struct c_mmheap_allocated *) (addr - HDR_SIZE); + endm->prev = lastblock; + endm->size_and_flags = (0 | USED); + + heap->n_allocated_blocks++; + mmheap_free_lockheld (heap, (struct c_mmheap_allocated *) lastblock + 1); + /* inform caller */ + dropped_cb (arg, (void *) addr, size); + } + check_heap (heap, 0, 0, 0, 0, heap->dump); +} + +static os_address mmheap_largest_available_lockheld (struct c_mmheap *heap) +{ + if (heap->free != NULL) { + struct c_mmheap_tree *block = heap->free; + os_address maxsize = 0; + do { + maxsize = GET_SIZE (block); + block = block->right; + } while (block); + return maxsize; + } else if (heap->free2) { + return FREE2_SIZE; + } else if (heap->free1) { + return FREE1_SIZE; + } else { + return 0; + } +} + +int c_mmheapInit (struct c_mmheap *heap, os_address off, os_address size, unsigned flags) +{ + struct c_mmheap_tree *node; + struct c_mmheap_allocated *begm, *endm; + os_mutexAttr mattr; + + if (flags & ~(C_MMHEAP_SHARED)) { + /* undefined flags specified */ + return -1; + } + + if (off == 0) { + off = sizeof (struct c_mmheap); + } + off = A ((os_address) heap + off) - (os_address) heap; + size = (((os_address) heap + size) & (os_address)(-(os_saddress)ALIGNMENT)) - (os_address) heap; + if (size < off || + size - off < (HDR_SIZE + /* begin marker */ + HDR_SIZE + 3 * HDR_SIZE + /* one tree node */ + HDR_SIZE)) { /* end marker */ + /* size - off is too small for a heap */ + return -1; + } + + begm = (struct c_mmheap_allocated *) ((char *) heap + off); + node = (struct c_mmheap_tree *) ((char *) heap + off + HDR_SIZE); + endm = (struct c_mmheap_allocated *) ((char *) heap + size - HDR_SIZE); + + begm->size_and_flags = 0 | USED; + begm->prev = NULL; + node->size_and_flags = size - off - 3 * HDR_SIZE; + node->prev = (struct c_mmheap_tree *) begm; + node->left = NULL; + node->right = NULL; + node->parent = NULL; + node->list = NULL; + node->height = 1; + endm->size_and_flags = 0 | USED; + endm->prev = node; + + os_mutexAttrInit (&mattr); + mattr.scopeAttr = (flags & C_MMHEAP_SHARED) ? OS_SCOPE_SHARED : OS_SCOPE_PRIVATE; + if (os_mutexInit (&heap->lock, &mattr) != os_resultSuccess) { + return -1; + } + + heap->free = node; + heap->free1 = NULL; + heap->free2 = NULL; + heap->flags = flags; + heap->n_free_bytes = GET_SIZE (node); + heap->n_free_blocks = 1; + heap->n_allocated_blocks = 0; + heap->n_failed_allocations = 0; + heap->dump = 0; + heap->check = 0; + heap->heap_check_serial = 0; + heap->heap_region.base = heap; + heap->heap_region.off = off; + heap->heap_region.size = size; + heap->heap_region.next = NULL; + + if (check_heap (heap, 0, 0, 0, 1, heap->dump)) + { + os_mutexDestroy (&heap->lock); + return -1; + } + return 0; +} + +void c_mmheapFini (struct c_mmheap *heap) +{ + os_mutexDestroy (&heap->lock); +} + +void *c_mmheapMalloc (struct c_mmheap *heap, os_address size) +{ + void *ptr; + os_mutexLock (&heap->lock); + ptr = mmheap_malloc_lockheld (heap, size); + os_mutexUnlock (&heap->lock); + return ptr; +} + +void c_mmheapFree (struct c_mmheap *heap, void *b) +{ + os_mutexLock (&heap->lock); + mmheap_free_lockheld (heap, b); + os_mutexUnlock (&heap->lock); +} + +int c_mmheapAddRegion (struct c_mmheap *heap, void *block, os_address size) +{ + int r; + os_mutexLock (&heap->lock); + r = mmheap_addregion_lockheld (heap, block, size); + os_mutexUnlock (&heap->lock); + return r; +} + +void c_mmheapDropRegion (struct c_mmheap *heap, os_address minfree, os_address minsize, os_address align, void (*dropped_cb) (void *arg, void *addr, os_address size), void *arg) +{ + os_mutexLock (&heap->lock); + mmheap_dropregion_lockheld (heap, minfree, minsize, align, dropped_cb, arg); + os_mutexUnlock (&heap->lock); +} + +void c_mmheapStats (struct c_mmheap *heap, struct c_mmheapStats *st) +{ + os_mutexLock (&heap->lock); + st->nused = heap->n_allocated_blocks; + st->totfree = heap->n_free_bytes; + st->nfails = heap->n_failed_allocations; + os_mutexUnlock (&heap->lock); +} + +void *c_mmheapCheckPtr (struct c_mmheap *heap, void *ptr) +{ + void *result; + os_mutexLock (&heap->lock); + result = mmheap_check_pointer_lockheld (heap, ptr); + os_mutexUnlock (&heap->lock); + return result; +} + +os_address c_mmheapLargestAvailable (struct c_mmheap *heap) +{ + os_address res; + os_mutexLock (&heap->lock); + res = mmheap_largest_available_lockheld (heap); + os_mutexUnlock (&heap->lock); + return res; +} diff --git a/src/database/database/code/c_mmheap.h b/src/database/database/code/c_mmheap.h new file mode 100644 index 000000000..2a3109fdf --- /dev/null +++ b/src/database/database/code/c_mmheap.h @@ -0,0 +1,82 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +/* (progn (c-set-style "k&r") (setq c-basic-offset 4)) */ + +#ifndef C_MMHEAP_H +#define C_MMHEAP_H + +#if defined (__cplusplus) +extern "C" { +#endif +#ifdef OSPL_BUILD_CORE +#define OS_API OS_API_EXPORT +#else +#define OS_API OS_API_IMPORT +#endif + +#include "os_defs.h" +#include "os_mutex.h" + +#define C_MMHEAP_SHARED 1u + +struct c_mmheap_tree; +struct c_mmheap_list; + +struct c_mmheap_region { + os_address off, size; + void *base; + struct c_mmheap_region *next; +}; + +struct c_mmheap { + os_mutex lock; + struct c_mmheap_tree *free; + struct c_mmheap_list *free1; + struct c_mmheap_list *free2; + os_uint32 flags; + int dump; + int check; + os_uint32 heap_check_serial; + os_address n_free_bytes; + os_address n_free_blocks; + os_address n_allocated_blocks; + os_address n_failed_allocations; + struct c_mmheap_region heap_region; +}; + +struct c_mmheapStats { + os_address nused; + os_address nfails; + os_address totfree; +}; + +int c_mmheapInit (struct c_mmheap *heap, os_address off, os_address size, unsigned flags); +void c_mmheapFini (struct c_mmheap *heap); +int c_mmheapAddRegion (struct c_mmheap *heap, void *block, os_address size); +void c_mmheapDropRegion (struct c_mmheap *heap, os_address minfree, os_address minsize, os_address align, void (*dropped_cb) (void *arg, void *addr, os_address size), void *arg); +void *c_mmheapMalloc (struct c_mmheap *heap, os_address size); +void c_mmheapFree (struct c_mmheap *heap, void *b); +void c_mmheapStats (struct c_mmheap *heap, struct c_mmheapStats *st); +void *c_mmheapCheckPtr (struct c_mmheap *heap, void *ptr); +os_address c_mmheapLargestAvailable (struct c_mmheap *heap); + +#undef OS_API +#if defined (__cplusplus) +} +#endif +#endif /* C_MMHEAP_H */ diff --git a/src/database/database/code/c_querybase.c b/src/database/database/code/c_querybase.c index 474f2e0f4..6815c6fc9 100644 --- a/src/database/database/code/c_querybase.c +++ b/src/database/database/code/c_querybase.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -577,8 +578,9 @@ c_qRangeListAnd( switch (eq) { case C_LT: /* in this case the range is such that no value could ever satisfy it - e.g. [*..5] AND [10..*] ~~> no value satisfies both ranges - so the result is , i.e. a list which no variable can satisfy */ + * e.g. [*..5] AND [10..*] ~~> no value satisfies both ranges + * so the result is , i.e. a list which no variable can satisfy + */ r = c_new(c_qRange_t(c__getBase(r1->startExpr))); c_setRange(r,r1->start,r1->startExpr,B_EXCLUDE,r1->start,r2->startExpr,B_EXCLUDE); result = c_iterAppend(result,r); @@ -835,9 +837,9 @@ c_qVarCompare( } /* If the given type is an enumeration then the expression is examined. - If the expression is a string constant then it is the enum label and - will be transformed into the enum value. -*/ + * If the expression is a string constant then it is the enum label and + * will be transformed into the enum value. + */ static c_qResult transformEnumLabelToValue( c_type type, diff --git a/src/database/database/code/c_refcheck.c b/src/database/database/code/c_refcheck.c index 6b2909f36..3699de2f8 100644 --- a/src/database/database/code/c_refcheck.c +++ b/src/database/database/code/c_refcheck.c @@ -13,7 +13,6 @@ #include "c__field.h" #include "c__metabase.h" #include "c__refcheck.h" -#include "q__parser.h" #include "c_module.h" struct mlnode { diff --git a/src/database/database/code/c_scope.c b/src/database/database/code/c_scope.c index 4a8c9c37e..98c5f65b4 100644 --- a/src/database/database/code/c_scope.c +++ b/src/database/database/code/c_scope.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/database/database/code/c_stringSupport.c b/src/database/database/code/c_stringSupport.c index ef35956c7..c6a6dff2a 100644 --- a/src/database/database/code/c_stringSupport.c +++ b/src/database/database/code/c_stringSupport.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/database/database/code/c_sync.c b/src/database/database/code/c_sync.c index 09eb96d03..af18ea433 100644 --- a/src/database/database/code/c_sync.c +++ b/src/database/database/code/c_sync.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/database/database/code/c_time.c b/src/database/database/code/c_time.c index e9acf3a91..488146231 100644 --- a/src/database/database/code/c_time.c +++ b/src/database/database/code/c_time.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -102,7 +103,8 @@ c_timeAdd( c_time tr; /* The only valid additions are C_TIME_ABSOLUTE_TIME + C_TIME_RELATIVE_TIME - * or C_TIME_RELATIVE_TIME + C_TIME_RELATIVE_TIME. */ + * or C_TIME_RELATIVE_TIME + C_TIME_RELATIVE_TIME. + */ assert (CHECK_TIME( (C_TIME_ISABSOLUTE(t1) && C_TIME_ISRELATIVE(t2)) || (C_TIME_ISRELATIVE(t1) && C_TIME_ISABSOLUTE(t2)) || @@ -144,9 +146,9 @@ c_timeAdd( } } if (t2.seconds > 0) { - if (C_TIME_INFINITE.seconds - t2.seconds <= t1.seconds) { + if (C_TIME_INFINITE.seconds - t2.seconds <= t1.seconds) { /* is identical to - * 'C_TIME_INFINITE.seconds <= t1.seconds + t2.seconds' + * 'C_TIME_INFINITE.seconds <= t1.seconds + t2.seconds' * In other words the sum is larger than infinite, * so results must be infinite. */ @@ -154,8 +156,8 @@ c_timeAdd( } } else { if (C_TIME_MIN_INFINITE.seconds - t2.seconds >= t1.seconds) { - /* is identical to - * '-(C_TIME_MIN_INFINITE.seconds <= t1.seconds + t2.seconds)' + /* is identical to + * '-(C_TIME_MIN_INFINITE.seconds <= t1.seconds + t2.seconds)' * In other words the sum is smaller than min infinite, * so results must be min infinite. */ @@ -231,11 +233,11 @@ c_timeSub( t2.nanoseconds); assert(C_TIME_NANOS(t2.nanoseconds) < 1000000000); } - + if (t2.seconds > 0) { - if (C_TIME_MIN_INFINITE.seconds + t2.seconds >= t1.seconds) { - /* is identical to - * 'C_TIME_MIN_INFINITE.seconds >= t1.seconds - t2.seconds' + if (C_TIME_MIN_INFINITE.seconds + t2.seconds >= t1.seconds) { + /* is identical to + * 'C_TIME_MIN_INFINITE.seconds >= t1.seconds - t2.seconds' * In other words the sum is smaller than min infinite, * so results must be min infinite. */ @@ -244,7 +246,7 @@ c_timeSub( } else { if (C_TIME_INFINITE.seconds + t2.seconds <= t1.seconds) { /* is identical to - * '-(C_TIME_INFINITE.seconds >= t1.seconds - t2.seconds)' + * '-(C_TIME_INFINITE.seconds >= t1.seconds - t2.seconds)' * In other words the sum is larger than infinite, * so results must be infinite. */ @@ -291,18 +293,18 @@ c_timeValid( { valid = TRUE; } else { - if ( (t1.seconds == C_TIME_INFINITE.seconds) || + if ( (t1.seconds == C_TIME_INFINITE.seconds) || (t1.seconds == C_TIME_MIN_INFINITE.seconds)) { valid = FALSE; } else { if (C_TIME_NANOS(t1.nanoseconds) < 1000000000U) { valid = TRUE; - } else { + } else { valid = FALSE; } } } - + return valid; } @@ -311,7 +313,7 @@ c_timeNanoSleep( c_time interval) { os_time t; - + /* This call should only accept relative times. C_TIME_ISRELATIVE(...) does * include the INFINITE's as well, so !C_TIME_ISABSOLUTE(...) is used * instead. */ @@ -320,7 +322,7 @@ c_timeNanoSleep( t.tv_sec = interval.seconds; t.tv_nsec = (os_int32) C_TIME_NANOS(interval.nanoseconds); return (c_timeResult) os_nanoSleep(t); - + } /** \brief return floating point representation of c_time reprersentation. diff --git a/src/database/database/code/c_typebase.c b/src/database/database/code/c_typebase.c index 70cd3283e..0b3ae0106 100644 --- a/src/database/database/code/c_typebase.c +++ b/src/database/database/code/c_typebase.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -672,21 +673,6 @@ c_valueCompare( return C_NE; } -#if 0 -/* Some compilers have an optimizer that turns this very simple matcher - into something just as fast as the one below, but not all of them. So - better use the one in which the recursion has been partially eliminated - by hand. */ -static int patmatch (const char *pat, const char *str) -{ - switch (*pat) { - case 0: return *str == 0; - case '?': return *str == 0 ? 0 : patmatch (pat+1, str+1); - case '*': return patmatch (pat+1, str) || (*str != 0 && patmatch (pat, str+1)); - default: return *str != *pat ? 0 : patmatch (pat+1, str+1); - } -} -#else static int patmatch (const char *pat, const char *str) { while (*pat) { @@ -698,7 +684,8 @@ static int patmatch (const char *pat, const char *str) pat++; } else if (*pat == '*') { /* collapse a sequence of wildcards, requiring as many - characters in str as there are ?s in the sequence */ + * characters in str as there are ?s in the sequence + */ while (*pat == '*' || *pat == '?') { if (*pat == '?' && *str++ == 0) { return 0; @@ -722,7 +709,6 @@ static int patmatch (const char *pat, const char *str) } return *str == 0; } -#endif c_value c_valueStringMatch ( diff --git a/src/database/database/code/q__parser.h b/src/database/database/code/q__parser.h deleted file mode 100644 index 628bbaf48..000000000 --- a/src/database/database/code/q__parser.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * OpenSplice DDS - * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#ifndef EMPTY_H -#define EMPTY_H - -#if defined (__cplusplus) -extern "C" { -#endif - -void q_parserInit(void); - -#if defined (__cplusplus) -} -#endif - -#endif /* EMPTY_H */ diff --git a/src/database/database/code/q_expr.c b/src/database/database/code/q_expr.c index 3d2f731d2..f6b73ee90 100644 --- a/src/database/database/code/q_expr.c +++ b/src/database/database/code/q_expr.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,7 +22,6 @@ #include "c_iterator.h" #include "q_expr.h" #include "q_helper.h" -#include "q__parser.h" #include "c_field.h" #include "c__field.h" #include "c_collection.h" @@ -546,9 +546,10 @@ q_exprCopy( case T_FNC: if (e->info.function->tag == Q_EXPR_CALLBACK) { - /* The first parameter specifies the result type of the callback function. */ - /* The second parameter is not of type q_expr but is a function pointer. */ - /* The function pointer is the address of the callback function. */ + /* The first parameter specifies the result type of the callback function. + * The second parameter is not of type q_expr but is a function pointer. + * The function pointer is the address of the callback function. + */ /* increment ref count of internal c_type because it is being copied */ c_keep (q_getTyp(q_getPar(e,0))); @@ -652,7 +653,8 @@ q_takeField( return q_takeField(&(*e)->info.function->params->expr,name); case Q_EXPR_OR: /* This function should never be used upon an OR expression. - However if that functionality is required then this function should be redesigned. + * However if that functionality is required then this function + * should be redesigned. */ assert(FALSE); break; @@ -823,7 +825,7 @@ q_takeKey( break; case T_ID: for (i=0; i */ - c_array indexKeyList) /* c_array */ -{ - assert(expr); - assert(sourceKeyList); - assert(indexKeyList); - - if(q_getKind(expr) == T_FNC){ - if(q_isFnc(expr, Q_EXPR_PROPERTY)) - { - /* first get the string representation of the id's in this expr */ - c_field f; - c_ulong i, index, size = 0; - c_char *name; - - name = q_propertyName(expr); - if(name) - { - /* Now find the matching key in the sourceKeyList */ - index = size = c_arraySize(sourceKeyList); - - assert(size == c_arraySize(indexKeyList)); - - if(size == c_arraySize(indexKeyList)){ - - for(i=0; icolumn += (int)strlen(yytext); return t /********************************************************************** * @@ -21,6 +20,11 @@ * **********************************************************************/ +static char * +removeDoubleQuotes( + char *str, + char ch); + /* Removed tokens because these are currently unused "+" { RETURN (PLUS); } @@ -68,16 +72,23 @@ flatten { RETURN (FLATTEN); } %} -/* %option noyywrap */ +%option noyywrap +%option nounistd %option never-interactive +%option prefix="q_parser_" + +%option reentrant bison-bridge + INTEGER -[0-9]+ UINTEGER \+?[0-9]+ FLOAT [+-]?({UINTEGER}"."{UINTEGER})(e[+-]?{UINTEGER})? CHAR \'[^\']\' -STR \"([^"]*\"\")*[^"]*\" -STR2 \'([^']*\'\')*[^']*\' -STR3 \`([^']*\'\')*[^']*\' + +%x STRING1 +STR1 (([^"]*\"\")*[^"]*) +%x STRING2 +STR2 (([^']*\'\')*[^']*) IDENT [a-zA-Z][a-zA-Z0-9_]* @@ -88,7 +99,7 @@ COMMENT2 "//"[^\n]* SD ("select"{BLANK}"distict") %% -"$" { OS_UNUSED_ARG(yyunput); RETURN (DOLLAR); } +"$" { RETURN (DOLLAR); } "%" { RETURN (PERCENT); } "(" { RETURN (LRPAR); } ")" { RETURN (RRPAR); } @@ -102,8 +113,8 @@ SD ("select"{BLANK}"distict") "*" { RETURN (MUL); } "." { RETURN (DOT); } "->" { RETURN (REF); } -":" { RETURN (COLON); } -"::" { RETURN (DOUBLECOLON); } +":" { RETURN (COLON); } +"::" { RETURN (DOUBLECOLON); } "," { RETURN (COMMA); } define { RETURN (DEFINE); } as { RETURN (AS_KEYWORD); } @@ -137,62 +148,103 @@ JOIN { RETURN (JOIN); } BETWEEN { RETURN (BETWEEN); } {BLANK} { - q_parser_column+=(int)strlen(yytext); + context->column += (int)strlen(yytext); } {COMMENT2} { - q_parser_column=0; + context->column = 0; } {NEWLINE} { - q_parser_line++; - q_parser_column=0; + context->line++; + context->column = 0; } {IDENT} { + context->column += (int)strlen(yytext); /* variable length string values are allocated dynamically and must be freed by the parser calling this scanner. */ - yylval.String = (char*)malloc(strlen(yytext)+1); - q_parser_column+=(int)strlen(yytext); - os_strcpy(yylval.String,yytext); + yylval->String = os_strdup(yytext); return (identifier); } {INTEGER} { - yylval.Integer = os_atoll(yytext); - q_parser_column+=(int)strlen(yytext); + context->column += (int)strlen(yytext); + yylval->Integer = os_atoll(yytext); return (longlongLiteral); } {UINTEGER} { - yylval.UInteger = os_atoull(yytext); - q_parser_column+=(int)strlen(yytext); + context->column += (int)strlen(yytext); + yylval->UInteger = os_atoull(yytext); return (ulonglongLiteral); } {FLOAT} { - yylval.Float = (double)atof(yytext); - q_parser_column+=(int)strlen(yytext); + context->column += (int)strlen(yytext); + yylval->Float = (double)atof(yytext); return (doubleLiteral); } -{CHAR} { - yylval.Char = yytext[1]; - q_parser_column+=(int)strlen(yytext); +{CHAR} { + context->column += (int)strlen(yytext); + yylval->Char = yytext[1]; return (charLiteral); } -{STR}|{STR2}|{STR3} { - os_size_t length = strlen(yytext); - q_parser_column+=length; - /* variable length string values are allocated dynamically and - must be freed by the parser calling this scanner. - */ - yylval.String = (char*)malloc(length-1); - os_strncpy(yylval.String, (char *)&yytext[1], length-2); - yylval.String[length-2]=0; - return (stringLiteral); +\" { + context->column++; + BEGIN(STRING1); + } +{STR1} { + context->column += (int)strlen(yytext); + yylval->String = removeDoubleQuotes(yytext, '\"'); + return (stringLiteral); + } +\" { + context->column++; + BEGIN(INITIAL); + } +\'|\` { + context->column++; + BEGIN(STRING2); + } +{STR2} { + context->column += (int)strlen(yytext); + yylval->String = removeDoubleQuotes(yytext, '\''); + return (stringLiteral); + } +\' { + context->column++; + BEGIN(INITIAL); } {SD} { return (SELECT_DISTINCT); } -. { q_parser_column+=(int)strlen(yytext); } +. { context->column += (int)strlen(yytext); } "/*" BEGIN(COMMENT1); [^*\n]* "*"+[^*/\n]* -\n { ++q_parser_line; q_parser_column=0; } +\n { context->line++; context->column = 0; } "*"+"/" BEGIN(INITIAL); %% + + +static char * +removeDoubleQuotes( + char *str, + char ch) +{ + os_size_t i, j; + os_size_t len; + char *s = NULL; + + if (str) { + len = strlen(str); + + s = os_malloc(len+1); + + for (i = 0, j = 0; i < len; i++, j++) { + if ((str[i] == ch) && (str[i+1] == ch)) { + i++; + } + s[j] = str[i]; + } + s[j] = '\0'; + } + + return s; +} diff --git a/src/database/database/code/q_parser.y b/src/database/database/code/q_parser.y index d1b4df14d..2dacc1f99 100644 --- a/src/database/database/code/q_parser.y +++ b/src/database/database/code/q_parser.y @@ -6,61 +6,31 @@ #include "q_expr.h" #include "q_helper.h" -#ifdef _WIN32 -#define YY_NO_UNISTD_H -#define YYMALLOC malloc -#define YYFREE free -#endif - -/* This define is needed for Win32, but also applies to other platforms */ -#define YY_NEVER_INTERACTIVE 1 - -#define yyin q_parser_yyin -#define yyout q_parser_yyout -#define yyparse q_parser_yyparse -#define yychar q_parser_yychar -#define yyerror q_parser_yyerror -#define yylex q_parser_yylex -#define yylval q_parser_yylval -#define yyrestart q_parser_yyrestart -#define yywrap q_parser_yywrap -#define yytext q_parser_yytext -#define yynerrs q_parser_yynerrs -#define yyleng q_parser_yyleng -#define yy_scan_string q_parser_yy_scan_string -#define yy_scan_buffer q_parser_yy_scan_buffer -#define yy_init_buffer q_parser_yy_init_buffer -#define yy_flush_buffer q_parser_yy_flush_buffer -#define yy_switch_to_buffer q_parser_yy_switch_to_buffer -#define yy_delete_buffer q_parser_yy_delete_buffer -#define yy_create_buffer q_parser_yy_create_buffer -#define yy_load_buffer_state q_parser_yy_load_buffer_state -#define yy_scan_bytes q_parser_yy_scan_bytes - -#define ResolveType(s,t) c_type(c_metaResolve(c_metaObject(s),#t)) - -#define ToBeImplemented NULL - -#define c_dateNew(a,b,c,d) ToBeImplemented -#define c_timeNew(a,b,c,d) ToBeImplemented -#define c_timestampNew(a,b,c,d,e,f,g) ToBeImplemented - -q_expr expr, exprError; - -int q_parser_line = 1; -int q_parser_column = 0; -int q_parser_state = 0; - -int yylex(); -int yyerror ( char* text ); -void dollar_warning(); +#include "os_report.h" +#include "vortex_os.h" + +/* yyscan_t is an opaque pointer, a typedef is required here to break a + circular dependency introduced with bison 2.6 (normally a typedef is + generated by flex). the define is required to disable the typedef in flex + generated code */ +#define YY_TYPEDEF_YY_SCANNER_T + +typedef void *yyscan_t; + +struct q_context { + int line; + int column; + q_expr expr; +}; -/*********************************************************************** - * - * Static function prototypes - * - ***********************************************************************/ +int +yyerror( + yyscan_t yyscanner, struct q_context *context, char *text); + +void +dollar_warning( + void); %} %union { @@ -75,6 +45,24 @@ void dollar_warning(); q_tag Tag; } +%{ +/* q_parser_lex must be declared here because q_parser_lex (yylex if no prefix + would be specified) signature is augmented with an extra argument */ +int q_parser_lex( + YYSTYPE * yylval_param, yyscan_t yyscanner, struct q_context *context); + +#define YY_DECL int q_parser_lex \ + (YYSTYPE * yylval_param, yyscan_t yyscanner, struct q_context *context) +%} + +%define api.pure full +%define api.prefix q_parser_ + +%lex-param {yyscan_t scanner} +%lex-param {struct q_context *context} +%parse-param {yyscan_t scanner} +%parse-param {struct q_context *context} + %start program /* Removed tokens because these are currently unused @@ -128,7 +116,7 @@ void dollar_warning(); program: | query - { expr = F1(Q_EXPR_PROGRAM,$1); } + { context->expr = F1(Q_EXPR_PROGRAM,$1); } ; query: @@ -400,78 +388,55 @@ literal: %% -#include "q_parser.h" -#include "q__parser.h" -#include "os_report.h" -#include "vortex_os.h" +#define YY_NO_UNPUT +#define YY_NO_INPUT + +#include "q_parser.h" /* generated by flex */ -static os_mutex q_mtx; -static os_int32 initialise = 1; /* reset by q_parserInit */ int -yyerror ( - char* text ) +yyerror( + yyscan_t yyscanner, struct q_context *context, char *text) { - q_list params = NULL; + OS_UNUSED_ARG(yyscanner); - OS_REPORT(OS_ERROR,"SQL parse failed",0,"%s near %s at line: %d, column: %d", - text, yytext, q_parser_line, q_parser_column); - yyclearin; - - q_dispose(expr); - expr = NULL; - params = q_insert(params,q_newStr(text)); - params = q_insert(params,q_newStr(yytext)); - params = q_insert(params,q_newInt(q_parser_line)); - params = q_insert(params,q_newInt(q_parser_column)); - exprError = q_newFnc(Q_EXPR_ERROR,params); + OS_REPORT(OS_ERROR,"SQL parse failed",0,"%s near line: %d, column: %d", + text, context->line, context->column); return 0; } void -dollar_warning() +dollar_warning( + void) { OS_REPORT(OS_WARNING,"SQL parser",0,"The use of '$' is deprecated, use '%%' instead"); } -int -yywrap() -{ - return 1; -} - q_expr -q_parse ( +q_parse( const c_char *expression) { - q_expr e; + YY_BUFFER_STATE buffer; + yyscan_t scanner; + struct q_context context = { 1, 0, NULL }; + q_expr e = NULL; if (expression) { - os_mutexLock(&q_mtx); - q_parser_line = 1; - q_parser_column = 0; - q_parser_state = 0; - expr = NULL; - yy_scan_string((char *) expression); - yyparse(); - e = expr; - yy_delete_buffer(YY_CURRENT_BUFFER); - q_exprSetText(e, expression); - os_mutexUnlock(&q_mtx); - } else { - e = NULL; - } - return e; -} - -void -q_parserInit() -{ - if (initialise) { - initialise = 0; - if ( os_mutexInit(&q_mtx, NULL) != os_resultSuccess ) { - OS_REPORT(OS_ERROR, "SQL parser", 0, "mutex init failed"); + q_parser_lex_init(&scanner); + buffer = q_parser__scan_string(expression, scanner); + if (yyparse(scanner, &context) == 0) { + e = context.expr; + q_exprSetText(e, expression); + } else { + /* 1 on invalid input, 2 on memory exhaustion */ + q_dispose(context.expr); + context.expr = NULL; } + + q_parser__delete_buffer(buffer, scanner); + q_parser_lex_destroy(scanner); } + + return e; } diff --git a/src/database/database/include/c_base.h b/src/database/database/include/c_base.h index 3020d4302..1a5cd1de2 100644 --- a/src/database/database/include/c_base.h +++ b/src/database/database/include/c_base.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -67,6 +68,7 @@ #include "c_metabase.h" #include "c_mmbase.h" #include "os_if.h" +#include "os_defs.h" #ifdef OSPL_BUILD_CORE #define OS_API OS_API_EXPORT diff --git a/src/database/database/include/c_clone.h b/src/database/database/include/c_clone.h index f84e9d09b..12dc82d79 100644 --- a/src/database/database/include/c_clone.h +++ b/src/database/database/include/c_clone.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/database/database/include/c_collection.h b/src/database/database/include/c_collection.h index 5ccdafba2..e3f7a0879 100644 --- a/src/database/database/include/c_collection.h +++ b/src/database/database/include/c_collection.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -128,7 +129,7 @@ C_CLASS(c_collection); #define C_UNLIMITED (0) typedef c_bool (*c_action) - (c_object o, c_voidp arg); + (_Inout_ c_object o, _Inout_ c_voidp arg); typedef c_bool (*c_removeCondition) (c_object found, c_object requested, c_voidp arg); @@ -142,11 +143,16 @@ typedef c_collection c_bag; typedef c_collection c_table; typedef c_collection c_query; +struct c__setImplIter_s { + c_voidp opaque[4 + (12 * sizeof(void *))]; /* same size as ut_avlCIter_t */ +}; + struct c_collectionIter { void * (*next) (struct c_collectionIter *it); c_collection source; union { struct c__listImplIter_s list; + struct c__setImplIter_s set; } u; }; @@ -254,9 +260,9 @@ c_tableNew ( */ OS_API c_query c_queryNew ( - c_collection source, - q_expr predicate, - c_value params[]); + const c_collection source, + const q_expr predicate, + const c_value params[]); /** * \brief This operation returns the element type of the given collection type. @@ -747,7 +753,7 @@ c_queryEval ( */ OS_API c_qPred c_queryGetPred( - c_query _this); + c_query _this); /** * \brief This operation sets the predicate of the given query to the given predicate. @@ -757,8 +763,8 @@ c_queryGetPred( */ OS_API void c_querySetPred( - c_query _this, - c_qPred p); + c_query _this, + c_qPred p); /** * \brief This table operation inspects the specified object and fills a @@ -815,13 +821,17 @@ c_tableRemove ( c_removeCondition condition, c_voidp arg); -#define _NIL_ -#ifdef _NIL_ OS_API c_object c_tableFind ( c_table _this, - c_value *keyValues); -#endif + c_value *keyValues, + c_ulong nrOfKeys); + +OS_API c_object +c_tableFindWeakRef ( + c_table _this, + c_value *keyValues, + c_ulong nrOfKeys); OS_API c_bool c_tableWalk( @@ -838,6 +848,11 @@ c_setInsert( c_set _this, c_object o); +OS_API c_bool +c_setContains ( + c_set _this, + c_object o); + OS_API c_object c_setRemove ( c_set _this, diff --git a/src/database/database/include/c_field.h b/src/database/database/include/c_field.h index e2b936080..166812c88 100644 --- a/src/database/database/include/c_field.h +++ b/src/database/database/include/c_field.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/database/database/include/c_filter.h b/src/database/database/include/c_filter.h index 8d4597d0b..33fbdd844 100644 --- a/src/database/database/include/c_filter.h +++ b/src/database/database/include/c_filter.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/database/database/include/c_iterator.h b/src/database/database/include/c_iterator.h index 7172253ba..f45e67ccc 100644 --- a/src/database/database/include/c_iterator.h +++ b/src/database/database/include/c_iterator.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/database/database/include/c_laptime.h b/src/database/database/include/c_laptime.h index 2d5e80bd5..0da444f6d 100644 --- a/src/database/database/include/c_laptime.h +++ b/src/database/database/include/c_laptime.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/database/database/include/c_metabase.h b/src/database/database/include/c_metabase.h index d197d697f..d0a3ba0e8 100644 --- a/src/database/database/include/c_metabase.h +++ b/src/database/database/include/c_metabase.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -73,8 +74,9 @@ C_CLASS(c_valueType); /* Meta Specifiers */ /*============================================================================*/ -/* Note: if c_metaKind is updated a corresponding update to the baseKind array - in common/mm_metakindNames.c for mmstat is also required */ +/* NOTE: if c_metaKind is updated a corresponding update to the baseKind array + * in common/mm_metakindNames.c for mmstat is also required + */ typedef enum c_metaKind { M_UNDEFINED, M_ANNOTATION, M_ATTRIBUTE, M_CLASS, M_COLLECTION, M_CONSTANT, M_CONSTOPERAND, @@ -86,8 +88,9 @@ typedef enum c_metaKind { } c_metaKind; C_ALIGNMENT_TYPE (c_metaKind); -/* Note: if c_collKind is updated a corresponding update to the collectionKind - array in common/mm_metakindNames.c for mmstat is also required */ +/* NOTE: if c_collKind is updated a corresponding update to the collectionKind + * array in common/mm_metakindNames.c for mmstat is also required + */ typedef enum c_collKind { OSPL_C_UNDEFINED, OSPL_C_LIST, OSPL_C_ARRAY, OSPL_C_BAG, OSPL_C_SET, OSPL_C_MAP, OSPL_C_DICTIONARY, @@ -519,8 +522,7 @@ c_metaFindByName( const char *name, c_ulong metaFilter); -/* - * Walks over all the elements in the c_scope of the given metaObject. +/* Walks over all the elements in the c_scope of the given metaObject. * Action 'action' is called for each element, and as arguments to that action, * the element and 'arg' are passed on. */ @@ -530,8 +532,7 @@ c_metaWalk( c_metaWalkAction action, c_metaWalkActionArg arg); -/* - * Walks over all the elements in the c_scope of the given metaObject. +/* Walks over all the elements in the c_scope of the given metaObject. * Action 'action' is called for each element, and as arguments to that action, * the element and 'arg' are passed on. If action returns false, the walk is aborted * and false is returned. @@ -542,9 +543,7 @@ c_metaWalkBool( c_metaWalkBoolAction action, c_metaWalkActionArg arg); -/* - * Returns the number of elements in the c_scope of the given c_metaObject. - */ +/* Returns the number of elements in the c_scope of the given c_metaObject. */ OS_API c_ulong c_metaCount( c_metaObject scope); diff --git a/src/database/database/include/c_metafactory.h b/src/database/database/include/c_metafactory.h index 15b0d2aae..61c2a2ea8 100644 --- a/src/database/database/include/c_metafactory.h +++ b/src/database/database/include/c_metafactory.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/database/database/include/c_misc.h b/src/database/database/include/c_misc.h index 430ba6232..d0be5d559 100644 --- a/src/database/database/include/c_misc.h +++ b/src/database/database/include/c_misc.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -43,15 +44,14 @@ extern "C" { #define C_TYPECHECK(o,t) (o == c_checkType(o,#t)) -/** - This function verifies the object type. - The type of the object must be the same as or be derived from the specified type. - If the type is correct the function will return the given object otherwise it will - return NULL, so it can simply be added into existing code. - If a type mismatch occures an error report is generated. - If the standard assert functionality is enabled a type mismatch will result in - an abort signal. -**/ +/* This function verifies the object type. + * The type of the object must be the same as or be derived from the specified type. + * If the type is correct the function will return the given object otherwise it will + * return NULL, so it can simply be added into existing code. + * If a type mismatch occures an error report is generated. + * If the standard assert functionality is enabled a type mismatch will result in + * an abort signal. + */ OS_API c_object c_checkType (c_object o, const c_char *typeName); OS_API c_bool c_instanceOf (c_object o, const c_char *typeName); OS_API void c_copyIn (c_type type, const void *data, c_voidp *dest); diff --git a/src/database/database/include/c_mmbase.h b/src/database/database/include/c_mmbase.h index 1a084a012..5701fc394 100644 --- a/src/database/database/include/c_mmbase.h +++ b/src/database/database/include/c_mmbase.h @@ -1,10 +1,11 @@ /* (progn (c-set-style "k&r") (setq c-basic-offset 4)) */ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/database/database/include/c_module.h b/src/database/database/include/c_module.h index ba6a5ce53..2ad6b34d0 100644 --- a/src/database/database/include/c_module.h +++ b/src/database/database/include/c_module.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/database/database/include/c_querybase.h b/src/database/database/include/c_querybase.h index 8b0bec62d..15d9066f5 100644 --- a/src/database/database/include/c_querybase.h +++ b/src/database/database/include/c_querybase.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/database/database/include/c_stringSupport.h b/src/database/database/include/c_stringSupport.h index deeb9ec5a..6b60d6a51 100644 --- a/src/database/database/include/c_stringSupport.h +++ b/src/database/database/include/c_stringSupport.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -44,6 +45,7 @@ OS_API c_char *c_skipIdentifier (const c_char *str, const c_char *punctuatio OS_API c_char *c_skipUntil (const c_char *str, const c_char *symbolList); OS_API c_iter c_splitString (const c_char *str, const c_char *delimiters); OS_API c_equality c_compareString (const c_char *s1, const c_char *s2); + /** \brief string trimmer * * Returns a newly allocated string with the same contents as the original string diff --git a/src/database/database/include/c_sync.h b/src/database/database/include/c_sync.h index 38f6a3e89..72feac16e 100644 --- a/src/database/database/include/c_sync.h +++ b/src/database/database/include/c_sync.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/database/database/include/c_time.h b/src/database/database/include/c_time.h index cd83eab74..50ca5cfbd 100644 --- a/src/database/database/include/c_time.h +++ b/src/database/database/include/c_time.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -52,7 +53,8 @@ typedef os_result c_timeResult; * be broken if this were to be enabled by default in dev-builds. There are also * some conversion (e.g., from real to c_time) which don't cover all cases * correctly (the result is assumed to be relative, while it is perfectly valid - * to convert an absolute time to a real and back). */ + * to convert an absolute time to a real and back). + */ #ifdef C_TIME_CHECK /* The two most significant bits of the nanoseconds part of the time encode the * time-domain as follows: @@ -64,7 +66,8 @@ typedef os_result c_timeResult; * * The C_TIME(_MIN)_INFINITE values also have bit 30 set (C_TIME_MONOTONIC). This * isn't a problem, since both infinites are part of the C_TIME_MONOTONIC domain - * as well. */ + * as well. + */ # define CHECK_TIME(expr) expr # define C_TIME_MONOTONIC (1U << 30) diff --git a/src/database/database/include/c_typebase.h b/src/database/database/include/c_typebase.h index 9dab9bd3e..860141266 100644 --- a/src/database/database/include/c_typebase.h +++ b/src/database/database/include/c_typebase.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -61,11 +62,10 @@ extern "C" { C_CLASS(c_base); C_CLASS(c_type); -/** @def NULL - * @bug OSPL-2272 */ /* VERSION is the deprecated form of OSPL_VERSION * This is only defined when building OpenSplice itself */ #if defined (VERSION) || defined (OSPL_VERSION) +/* TODO: Check this definition of NULL. See OSPL-2272 */ #undef NULL #define NULL (0) #endif diff --git a/src/database/database/include/q_expr.h b/src/database/database/include/q_expr.h index 51682485f..20b4308ae 100644 --- a/src/database/database/include/q_expr.h +++ b/src/database/database/include/q_expr.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,7 +24,7 @@ * * This header file defines the types, functions and marcos that belong to the * database query intermediate code component. - * + * * The database query constructor uses this intermediate code to specify the query. * Database users can generate intermediate code from a SQL statment using the * q_parse function provided by this interface or provide its own custom method @@ -41,7 +42,7 @@ * * Intermediate code is allocated on the heap memory of the callee. The callee * is responsible for freeing allocated memory. - * + * */ #ifndef Q_EXPR_H @@ -390,15 +391,15 @@ q_getUInt( OS_API c_double q_getDbl( q_expr expr); - + OS_API c_char q_getChr( q_expr expr); - + OS_API c_char * q_getStr( q_expr expr); - + OS_API c_char * q_getId( q_expr expr); @@ -406,7 +407,7 @@ q_getId( OS_API c_longlong q_getVar( q_expr expr); - + OS_API c_type q_getTyp( q_expr expr); @@ -423,7 +424,7 @@ q_getLst( OS_API c_bool q_isInt( q_expr expr); - + OS_API c_bool q_isUInt( q_expr expr); @@ -431,11 +432,11 @@ q_isUInt( OS_API c_bool q_isDbl( q_expr expr); - + OS_API c_bool q_isStr( q_expr expr); - + OS_API c_bool q_isId( q_expr expr); @@ -443,11 +444,11 @@ q_isId( OS_API c_bool q_isVar( q_expr expr); - + OS_API c_bool q_isTyp( q_expr expr); - + OS_API c_bool q_isFnc( q_expr expr, @@ -486,20 +487,20 @@ OS_API q_list q_append( q_list list, q_expr expr); - + OS_API q_list q_insert( q_list list, q_expr expr); - + OS_API q_list q_next( q_list list); - + OS_API q_expr q_element( q_list list); - + OS_API q_list q_listCopy( q_list list); @@ -514,28 +515,28 @@ OS_API q_list q_getLst( q_expr expr, c_long index); - + OS_API q_expr q_getPar( q_expr expr, c_long index); - + OS_API q_expr q_takePar( q_expr expr, c_long index); - + OS_API void q_swapExpr( q_expr oldExpr, q_expr newExpr); - + OS_API q_expr q_swapPar( q_expr expr, c_long index, q_expr par); - + OS_API void q_insertPar( q_expr expr, @@ -552,16 +553,16 @@ OS_API q_expr q_newBind( c_char *id, q_expr expr); - + OS_API q_expr q_newStruct( q_list list); - + OS_API q_expr q_newIterate( q_expr variable, q_expr collection); - + OS_API q_expr q_newProject( q_list list); @@ -570,7 +571,7 @@ OS_API q_expr q_newCompr( q_tag tag, q_list list); - + OS_API q_expr q_newEqual( q_expr left, diff --git a/src/database/database/include/q_helper.h b/src/database/database/include/q_helper.h index 232015879..1a6e268bc 100644 --- a/src/database/database/include/q_helper.h +++ b/src/database/database/include/q_helper.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -31,11 +32,11 @@ extern "C" { #define OS_API OS_API_IMPORT #endif -OS_API void +OS_API void q_exprSetText( q_expr expr, const c_char* text); - -OS_API c_char* + +OS_API c_char* q_exprGetText( q_expr expr); @@ -67,16 +68,10 @@ q_exprGetViewState( q_expr expr); OS_API c_iter -deOr( +q_exprDeOr( q_expr e, c_iter list); -OS_API void -translate( - q_expr expr, - c_array sourceKeyList, /* c_array */ - c_array indexKeyList); /* c_array */ - #undef OS_API #if defined (__cplusplus) diff --git a/src/database/odlpp/code/c_genc.c b/src/database/odlpp/code/c_genc.c index 1d1d17044..09cea22f3 100644 --- a/src/database/odlpp/code/c_genc.c +++ b/src/database/odlpp/code/c_genc.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -160,7 +161,8 @@ c_genObjectSpec( } /* If this meta object is defined in another module then don't - generate a definition but instead include that module. */ + * generate a definition but instead include that module. + */ if (scope != module) { /* If this scope is not processed before then include it */ if (c_getObjectState(context,scope) == G_UNKNOWN) { @@ -211,7 +213,6 @@ c_genObjectSpec( switch(c_baseObject(o)->kind) { case M_CLASS: c_classFwdSpec(c_class(o), context); - /* c_outi(context,0,"C_CLASS(%s);\n\n",name); */ break; case M_TYPEDEF: c_typeDefSpec(c_typeDef(o),context); @@ -242,11 +243,12 @@ c_genObjectBody( } else { module = c_metaModule(context->scope); } - /* Get the module that contains the processed object. */ + /* Get the module that contains the processed object. */ scope = c_metaModule(o); /* Check if this meta object is a c_base type, if true then skip - the generation */ + * the generation + */ if (scope == NULL) { return; } @@ -257,7 +259,8 @@ c_genObjectBody( } /* If this meta object is defined in another module then don't - generate a definition but instead include that module. */ + * generate a definition but instead include that module. + */ if (scope != module) { /* If this scope is not processed before then load it */ if (c_getObjectState(context,scope) == G_UNKNOWN) { @@ -270,7 +273,8 @@ c_genObjectBody( } /* If this meta object is processed before then don't generate - a definition */ + * a definition + */ switch (c_getObjectState(context,o)) { case G_UNDECLARED: name = c_metaName(o); @@ -597,7 +601,6 @@ c_moduleBody( newContext.stream = fopen(streamName,"w"); newContext.scope = c_metaObject(o); - /* newContext.processing = context->processing; */ newContext.processing = c_iterNew(NULL); newContext.action = c_genObjectBody; @@ -978,7 +981,6 @@ c_enumerationSpec( for (i=0, value=i; ielements[i]), "_", FALSE, context); - /* label = c_metaName(c_metaObject(o->elements[i])); */ literal = c_literal(c_constant(o->elements[i])->operand); assert (literal->value.kind == V_LONG || @@ -1577,9 +1579,10 @@ operandPrint( }; break; case E_MINUS: - /* Special case: the last operand of E_MINUS sometimes - has to be surrounded by parentheses, even if the - precedence is the same */ + /* Special case: the last operand of E_MINUS sometimes + * has to be surrounded by parentheses, even if the + * precedence is the same + */ switch(c_arraySize(expression->operands)){ case 1: c_out(context, "-"); diff --git a/src/database/odlpp/code/c_genc.h b/src/database/odlpp/code/c_genc.h index bccf89bce..a6be3f234 100644 --- a/src/database/odlpp/code/c_genc.h +++ b/src/database/odlpp/code/c_genc.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/database/odlpp/code/c_gencommon.c b/src/database/odlpp/code/c_gencommon.c index 9b4870171..83dbe1251 100644 --- a/src/database/odlpp/code/c_gencommon.c +++ b/src/database/odlpp/code/c_gencommon.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/database/odlpp/code/c_gencommon.h b/src/database/odlpp/code/c_gencommon.h index 38b0dc993..9850043aa 100644 --- a/src/database/odlpp/code/c_gencommon.h +++ b/src/database/odlpp/code/c_gencommon.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/database/odlpp/code/c_gencs.c b/src/database/odlpp/code/c_gencs.c index e5e40230b..691c4a18e 100644 --- a/src/database/odlpp/code/c_gencs.c +++ b/src/database/odlpp/code/c_gencs.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -66,9 +67,6 @@ static void c_unionSpec(c_union o, c_genArg context); static void primitiveHelper(c_primitive p, c_string name, c_genArg context); static c_string enumNameHelper(c_string name); - -/*****************************************************/ - void c_gen_CS( c_module topLevel, @@ -77,7 +75,6 @@ c_gen_CS( struct c_genArg context; locale = localeconv(); - /* c_setLocale(localeconv()); */ context.scope = NULL; context.stream = NULL; @@ -179,7 +176,8 @@ c_genObjectSpec( } /* If this meta object is defined in another module then don't - generate a definition but instead include that module. */ + * generate a definition but instead include that module. + */ if (scope != module) { /* If this scope is not processed before then include it */ if (c_getObjectState(context,scope) == G_UNKNOWN) { @@ -230,11 +228,9 @@ c_genObjectSpec( switch(c_baseObject(o)->kind) { case M_CLASS: c_classFwdSpec(c_class(o), context); - /* c_outi(context,0,"C_CLASS(%s);\n\n",name); */ break; case M_TYPEDEF: c_typeDefSpec(c_typeDef(o),context); - /* c_genObjectSpec(c_metaObject(c_typeDef(o)->alias),context); */ break; default: break; diff --git a/src/database/odlpp/code/c_gencs.h b/src/database/odlpp/code/c_gencs.h index 4f07a8f0c..56bcc3ba2 100644 --- a/src/database/odlpp/code/c_gencs.h +++ b/src/database/odlpp/code/c_gencs.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/database/odlpp/code/c_odlbase.y b/src/database/odlpp/code/c_odlbase.y index acde497d7..aca21400d 100644 --- a/src/database/odlpp/code/c_odlbase.y +++ b/src/database/odlpp/code/c_odlbase.y @@ -21,7 +21,6 @@ #define yylex c_odlbase_yylex #define yylval c_odlbase_yylval #define yyrestart c_odlbase_yyrestart -/*#define yywrap c_odlbase_yywrap*/ #define yytext c_odlbase_yytext #define yynerrs c_odlbase_yynerrs #define yyleng c_odlbase_yyleng diff --git a/src/database/odlpp/code/c_odlparser.c b/src/database/odlpp/code/c_odlparser.c index 6b2a66cda..66c65281a 100644 --- a/src/database/odlpp/code/c_odlparser.c +++ b/src/database/odlpp/code/c_odlparser.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/database/odlpp/code/c_typenames.c b/src/database/odlpp/code/c_typenames.c index 6971aaaa9..4802b5f9f 100644 --- a/src/database/odlpp/code/c_typenames.c +++ b/src/database/odlpp/code/c_typenames.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/database/odlpp/code/c_typenames.h b/src/database/odlpp/code/c_typenames.h index bb4750d32..7a064814f 100644 --- a/src/database/odlpp/code/c_typenames.h +++ b/src/database/odlpp/code/c_typenames.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/database/serialization/code/sd__byteswapping.h b/src/database/serialization/code/sd__byteswapping.h index fd86bbb46..9f72f1053 100644 --- a/src/database/serialization/code/sd__byteswapping.h +++ b/src/database/serialization/code/sd__byteswapping.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/database/serialization/code/sd__confidence.h b/src/database/serialization/code/sd__confidence.h index 367424a72..7af8ac3a9 100644 --- a/src/database/serialization/code/sd__confidence.h +++ b/src/database/serialization/code/sd__confidence.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/database/serialization/code/sd__contextItem.h b/src/database/serialization/code/sd__contextItem.h index 6d29ef27b..bef27e02b 100644 --- a/src/database/serialization/code/sd__contextItem.h +++ b/src/database/serialization/code/sd__contextItem.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/database/serialization/code/sd__deepwalkMeta.h b/src/database/serialization/code/sd__deepwalkMeta.h index d2e31cc66..b24358a36 100644 --- a/src/database/serialization/code/sd__deepwalkMeta.h +++ b/src/database/serialization/code/sd__deepwalkMeta.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/database/serialization/code/sd__printXMLTypeinfo.h b/src/database/serialization/code/sd__printXMLTypeinfo.h index 78aebb0a8..754d8f52e 100644 --- a/src/database/serialization/code/sd__printXMLTypeinfo.h +++ b/src/database/serialization/code/sd__printXMLTypeinfo.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/database/serialization/code/sd__resultCodes.h b/src/database/serialization/code/sd__resultCodes.h index 981f5e329..dbd70e744 100644 --- a/src/database/serialization/code/sd__resultCodes.h +++ b/src/database/serialization/code/sd__resultCodes.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/database/serialization/code/sd__resultCodesXML.h b/src/database/serialization/code/sd__resultCodesXML.h index e02349cfd..28ac0594c 100644 --- a/src/database/serialization/code/sd__resultCodesXML.h +++ b/src/database/serialization/code/sd__resultCodesXML.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/database/serialization/code/sd__resultCodesXMLMetadata.h b/src/database/serialization/code/sd__resultCodesXMLMetadata.h index 70255fed3..65fac3903 100644 --- a/src/database/serialization/code/sd__resultCodesXMLMetadata.h +++ b/src/database/serialization/code/sd__resultCodesXMLMetadata.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/database/serialization/code/sd__serializer.h b/src/database/serialization/code/sd__serializer.h index 1d53f2cf5..736c315ee 100644 --- a/src/database/serialization/code/sd__serializer.h +++ b/src/database/serialization/code/sd__serializer.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -35,8 +36,7 @@ /** \brief Platform independent representation of the serializer format ID */ typedef c_octet sd_formatID[2]; -/** \brief Platform independent representation of the serializer format version - */ +/** \brief Platform independent representation of the serializer format version */ typedef c_octet sd_formatVersion[2]; /** \brief Platform independent representation of size of the serialized data, @@ -127,8 +127,8 @@ C_STRUCT(sd_serializer) { }; /* Private constructor, to be used only by descendants which do not - * add any members */ - + * add any members + */ sd_serializer sd_serializerNew( c_ushort formatID, @@ -145,11 +145,11 @@ sd_serializerInitialize( c_base base, c_type type, struct sd_serializerVMT VMT) __nonnull((1,4)); - + void sd_serializerResetValidationState( sd_serializer _this) __nonnull_all__; - + void sd_serializerSetValidationInfo( sd_serializer _this, diff --git a/src/database/serialization/code/sd__serializerXML.h b/src/database/serialization/code/sd__serializerXML.h index 14f13aeae..8560f20b7 100644 --- a/src/database/serialization/code/sd__serializerXML.h +++ b/src/database/serialization/code/sd__serializerXML.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -38,20 +39,20 @@ c_bool sd_XMLDeserType( c_object *objectPtr, c_char **dataPtrPtr, sd_errorInfo *errorInfo) __nonnull_all__ __attribute_warn_unused_result__; - + c_ulong sd_printCharData( c_string dst, c_string src) __nonnull_all__; - + c_bool sd_scanCharData( c_char **dst, c_char **src, sd_errorInfo *errorInfo) __nonnull_all__ __attribute_warn_unused_result__; - + c_char * sd_peekTaggedCharData( c_char *src, c_char *tagName) __nonnull_all__; - + c_char * sd_serializerXMLToString( sd_serializer serializer, sd_serializedData serData) __nonnull_all__ __attribute_warn_unused_result__; @@ -59,8 +60,8 @@ c_char * sd_serializerXMLToString( sd_serializedData sd_serializerXMLFromString( sd_serializer serializer, const c_char *str) __nonnull_all__ __attribute_warn_unused_result__; - - + + c_bool sd_XMLDeserCallbackPre( const c_char *name, c_type type, @@ -68,7 +69,7 @@ c_bool sd_XMLDeserCallbackPre( void *actionArg, sd_errorInfo *errorInfo, void *userData) __nonnull((1, 2, 4, 5)) __attribute_warn_unused_result__; - + c_bool sd_XMLDeserCallbackPost( const c_char *name, c_type type, @@ -76,7 +77,7 @@ c_bool sd_XMLDeserCallbackPost( void *actionArg, sd_errorInfo *errorInfo, void *userData) __nonnull((1, 2, 3, 4, 5)) __attribute_warn_unused_result__; - - + + #endif /* SD__SERIALIZERXML_H */ diff --git a/src/database/serialization/code/sd_cdr.c b/src/database/serialization/code/sd_cdr.c index b71a8d3cb..7741e26b8 100644 --- a/src/database/serialization/code/sd_cdr.c +++ b/src/database/serialization/code/sd_cdr.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -51,6 +52,7 @@ #define BE_NEEDS_BSWAP 0 #endif +/* Defines for debugging purposes : */ /*#define PRINTTYPE*/ /*#define PRINTSIZE*/ /*#define PRINTPROG*/ @@ -584,7 +586,8 @@ static int convclass_body (struct convtype_context *ctx, struct ser_type **rt, u assert (count_arg.n > 0); /* For our purposes, a class really is like a struct, but the - the meta data is represented very differently. */ + * the meta data is represented very differently. + */ if ((*rt = convtype_alloc (&ctx->alloc, TK_STRUCT, label, cls->_parent._parent.size, count_arg.n * sizeof ((*rt)->u.strukt.ms[0]))) == NULL) return SD_CDR_OUT_OF_MEMORY; (*rt)->u.strukt.n = count_arg.n; @@ -598,9 +601,10 @@ static int convclass_body (struct convtype_context *ctx, struct ser_type **rt, u convert_arg.error = 0; /* First field is the parent class (if any) -- so convert that one - first. Then call metaWalk to walk the attributes of the class. - The resulting "struct conversion" is unordered in offset, hence - the sorting. */ + * first. Then call metaWalk to walk the attributes of the class. + * The resulting "struct conversion" is unordered in offset, hence + * the sorting. + */ if (cls->extends) { (*rt)->u.strukt.ms[convert_arg.i].off = 0; @@ -649,8 +653,9 @@ static unsigned long long convunion_discvalue (const struct c_type_s *dtype0, co switch (c_primitiveKind ((c_type) dtype)) { /* All types are treated as unsigned by serializer when - reading from source, so should also treat label values as - unsigned even when they aren't. */ + * reading from source, so should also treat label values as + * unsigned even when they aren't. + */ case P_BOOLEAN: return lab->value.is.Boolean; case P_CHAR: return lab->value.is.Octet; case P_SHORT: return lab->value.is.UShort; @@ -724,7 +729,8 @@ static int convunion_getcases (struct convtype_context *ctx, int *hasdefault, st } /* move default to the end if it isn't, then sort on increasing - label value (when interpreted as unsigned 64-bit) */ + * label value (when interpreted as unsigned 64-bit) + */ if (defidx != idx - 1) { struct ser_unionmember tmp = ms[idx - 1]; @@ -875,7 +881,9 @@ static int convtype (struct convtype_context *ctx, struct ser_type **rt, const s } else { - /*fprintf (stderr, "convtype: CATS\n");*/ +#ifdef PRINTTYPE + fprintf (stderr, "convtype: CATS\n"); +#endif assert (ctype->maxSize > 0); if ((*rt = convtype_alloc (&ctx->alloc, TK_STRING_TO_ARRAY, label, sizeof (char *), 0)) == NULL) return SD_CDR_OUT_OF_MEMORY; @@ -900,7 +908,9 @@ static int convtype (struct convtype_context *ctx, struct ser_type **rt, const s rc = mk_array (ctx, rt, label, ctype->maxSize, subtype); else { - /*fprintf (stderr, "convtype: STAC\n");*/ +#ifdef PRINTTYPE + fprintf (stderr, "convtype: STAC\n"); +#endif assert (ctype->maxSize > 0); assert ((c_address) ctype->maxSize == type->size); if ((*rt = convtype_alloc (&ctx->alloc, TK_ARRAY_TO_STRING, label, type->size, 0)) == NULL) @@ -966,34 +976,32 @@ static int convtype (struct convtype_context *ctx, struct ser_type **rt, const s /****************** SERIALIZED SIZE *******************/ -/* -Stream alignment is represented as (a,k), where: - - stream position = k mod a - - a `elem` {1,2,4,8} - - k `elem` N && k < a - -If a < A, where A is the alignment requirement of the next type to be -appended to (or read from) the stream, then the stream must be aligned -dynamically by moving forward: - - align A pos = if pos `mod` A == 0 then 0 else A - (pos `mod` A)) - -If a >= A, then the required shift is known statically: - - if k `mod` A == 0 then 0 else A - (k `mod` A) - -For arrays and sequences, the alignment steps in the first element may -be different from those in the second and further elements: the stream -alignment (a,k) for the second and further elements is determined by -the one before the first element and the type of the elements, whereas -that for the first element is determined by what precedes the array of -sequence. - -merge (a_i,k_i) = (a',k'), where: - - a' is the maximum a' <= a_i s.t. - - forall i. (k_i mod a_i) mod a' = k' mod a' -*/ - +/* Stream alignment is represented as (a,k), where: + * - stream position = k mod a + * - a `elem` {1,2,4,8} + * - k `elem` N && k < a + * + * If a < A, where A is the alignment requirement of the next type to be + * appended to (or read from) the stream, then the stream must be aligned + * dynamically by moving forward: + * + * align A pos = if pos `mod` A == 0 then 0 else A - (pos `mod` A)) + * + * If a >= A, then the required shift is known statically: + * + * if k `mod` A == 0 then 0 else A - (k `mod` A) + * + * For arrays and sequences, the alignment steps in the first element may + * be different from those in the second and further elements: the stream + * alignment (a,k) for the second and further elements is determined by + * the one before the first element and the type of the elements, whereas + * that for the first element is determined by what precedes the array of + * sequence. + * + * merge (a_i,k_i) = (a',k'), where: + * - a' is the maximum a' <= a_i s.t. + * - forall i. (k_i mod a_i) mod a' = k' mod a' + */ struct mmsz_context { size_t minsize; size_t maxsize; @@ -1005,22 +1013,23 @@ struct mmsz_context { static struct ser_cdralign merge_cdralign (struct ser_cdralign a0, unsigned n, const struct ser_cdralign *as) { /* At all times, all ser_cdralign have 0 <= off < align, so each - time we reduce a.align, we recalculate a.off. */ + * time we reduce a.align, we recalculate a.off. + */ struct ser_cdralign a = a0; unsigned i; for (i = 0; i < n && a.align > 1; i++) { if (as[i].align < a.align) { - /* a.align <= max a0.align, s[i].align */ a.align = as[i].align; a.off = a.off % a.align; } /* a.align <= as[i].align, so a.off and as[i].off may be congruent - mod a.align (in which case all is well) or not (in which case - we know less about the alignment than a.align); the lazy way is - to just do this by trial and error, as we can halve a.align at - most 3 times to reach a={.align=1,.off=0}, or nothing known. */ + * mod a.align (in which case all is well) or not (in which case + * we know less about the alignment than a.align); the lazy way is + * to just do this by trial and error, as we can halve a.align at + * most 3 times to reach a={.align=1,.off=0}, or nothing known. + */ while (a.off != (as[i].off % a.align)) { a.align /= 2; @@ -1035,9 +1044,10 @@ static void mmsz_calc1 (struct mmsz_context *ctx, const struct ser_type *type); static void mmsz_update (struct mmsz_context *ctx, size_t addmin, size_t addmax, size_t align) { /* If required alignment higher than we our current basis, re-align - (and do so conservatively: e.g., ctx->align=={4,3} and align==8 - => need 1 or 5 bytes, not something in 0 .. 7), else if the - offset makes it misaligned, add a known amount of padding */ + * (and do so conservatively: e.g., ctx->align=={4,3} and align==8 + * => need 1 or 5 bytes, not something in 0 .. 7), else if the + * offset makes it misaligned, add a known amount of padding + */ #ifdef PRINTSIZE fprintf (stderr, "mmsz_update: %u,%u [%zu,%zu] %zu => ", ctx->align.align, ctx->align.off, addmin, addmax, align); #endif @@ -1064,8 +1074,9 @@ static void mmsz_update (struct mmsz_context *ctx, size_t addmin, size_t addmax, ctx->minsize += addmin; ctx->maxsize += addmax; /* If min and max sizes are equal, i.e., a definite size, then we - compute the exact effect on the alignment; else we simply assume - there is no alignment guarantee beyond "align" */ + * compute the exact effect on the alignment; else we simply assume + * there is no alignment guarantee beyond "align" + */ if (addmin == addmax) { ctx->align.off = (ctx->align.off + addmin) % ctx->align.align; #ifdef PRINTSIZE @@ -1107,13 +1118,14 @@ static void mmsz_context_subsume_fixed (struct mmsz_context *ctx, unsigned n, co { struct mmsz_context ctx1; /* For the 2nd and later array elements, the size is exactly the - same (if it is fixed in the first place), and the alignment at - the end is also the same, except for the possibility that the - offset can be different for N vs N+1 copies. However, the offset - necessarily repeats itself at least every ALIGN copies. E.g., - array[]{octet} starting with (8,0) results in (8,n mod 8); and - array[]{struct{short;octet}} starting with (8,0) toggles between - (8,3) and (8,7) as alignment. */ + * same (if it is fixed in the first place), and the alignment at + * the end is also the same, except for the possibility that the + * offset can be different for N vs N+1 copies. However, the offset + * necessarily repeats itself at least every ALIGN copies. E.g., + * array[]{octet} starting with (8,0) results in (8,n mod 8); and + * array[]{struct{short;octet}} starting with (8,0) toggles between + * (8,3) and (8,7) as alignment. + */ assert (n > 0); #ifdef PRINTSIZE fprintf (stderr, "mmsz_context_subsume_fixed %u\n", n); @@ -1152,7 +1164,8 @@ static void mmsz_context_subsume_variable (struct mmsz_context *ctx, unsigned nm else { /* alignment guaranteed to repeat itself after 8 copies, so - unbounded can be treated as 8 */ + * unbounded can be treated as 8 + */ nmax = 8; } mmsz_context_init (&ctx1, ctx->align); @@ -1168,8 +1181,7 @@ static void mmsz_context_subsume_variable (struct mmsz_context *ctx, unsigned nm ctx->maxsize += (nmax - 1) * ctx1.maxsize; ctx->align = merge_cdralign (ctx->align, 1, &ctx1.align); } - /* Like _fixed, but here we have to allow for the effects of 2, 3, - ... nmax copies. */ + /* Like _fixed, but here we have to allow for the effects of 2, 3,... nmax copies. */ if (nmax > 2) { nxoffs = (nmax < 8) ? nmax : 8; @@ -1232,7 +1244,8 @@ static void mmsz_calc1 (struct mmsz_context *ctx, const struct ser_type *type) else { /* addmin, addmax have to be different, but when it is - unbounded the actual value of addmax is irrelevant */ + * unbounded the actual value of addmax is irrelevant + */ mmsz_unbounded (ctx); mmsz_update (ctx, 1, 0, 1); } @@ -1256,10 +1269,11 @@ static void mmsz_calc1 (struct mmsz_context *ctx, const struct ser_type *type) mmsz_unbounded (ctx); mmsz_calc1 (ctx, &prim4); /* drop all alignment info, rather than trying to be precise: at - worst we underestimate the minimum serialized size by a few - bytes (note that precise alignment tracking is primarily - useful for recognising memcpy opportunities, but those don't - exist with recursive sequences anyway). */ + * worst we underestimate the minimum serialized size by a few + * bytes (note that precise alignment tracking is primarily + * useful for recognising memcpy opportunities, but those don't + * exist with recursive sequences anyway). + */ ctx->align.align = 1; ctx->align.off = 0; break; @@ -1277,8 +1291,9 @@ static void mmsz_calc1 (struct mmsz_context *ctx, const struct ser_type *type) else { /* class serialized as-if union switch(bool) { case true: T } - (though computed as-if sequence with a 8-bit length - rather than a 32-bit length) */ + * (though computed as-if sequence with a 8-bit length + * rather than a 32-bit length) + */ mmsz_calc1 (ctx, &prim1); mmsz_context_subsume_variable (ctx, 1, type->u.class.subtype); } @@ -1291,7 +1306,8 @@ static void mmsz_calc1 (struct mmsz_context *ctx, const struct ser_type *type) mmsz_calc1 (ctx, &dtype); mmsz_context_init (&ctxu, ctx->align); /* Set ctxu.minsize to something ridiculously large, then let - the iteration over the union clauses bring it down */ + * the iteration over the union clauses bring it down + */ ctxu.minsize = ~ (size_t) 0; for (i = 0; i < type->u.union_list.n + type->u.union_list.hasdefault; i++) { @@ -1925,9 +1941,10 @@ static int lowertype1_multiple (struct lowertype_context *ctx, const struct ser_ static int lowertype1 (struct lowertype_context *ctx, const struct ser_type *type) { /* PRE: source positioned at start of type; srcadv tracking is - entirely internal to lowering function, VM always advances source - for every primitive converted, as well as for every srcadvance - instruction */ + * entirely internal to lowering function, VM always advances source + * for every primitive converted, as well as for every srcadvance + * instruction + */ struct insnstream *st = ctx->st; struct insnstream_marker mjump = { 0 }; os_size_t srcpos_before, srcpos_after; @@ -1935,11 +1952,12 @@ static int lowertype1 (struct lowertype_context *ctx, const struct ser_type *typ int rc; /* If recursively used, we "call" the code as if it were a function, - rather than jump into it. There's no need for a function prologue - in the code (we do need an epilogue: INSN_RETURN), but we do need - to insert a INSN_CALL. Note that we never call lowertype1 for a - recursive use of the type, only for the first use (thanks to the - simple-mindedness of IDL type recursion). */ + * rather than jump into it. There's no need for a function prologue + * in the code (we do need an epilogue: INSN_RETURN), but we do need + * to insert a INSN_CALL. Note that we never call lowertype1 for a + * recursive use of the type, only for the first use (thanks to the + * simple-mindedness of IDL type recursion). + */ if (type->recuse) { if ((rc = is_append_marker_placeholder (&mjump, st, INSN_JUMP)) < 0) @@ -2034,9 +2052,10 @@ static int lowertype1 (struct lowertype_context *ctx, const struct ser_type *typ case TK_SEQUENCE: { /* Type uses 0 to encode maxn, but CDR has a hard limit of - 2**32-1 on sequence lengths because it encodes them as - 32-bit unsigned. Transforming unbounded to 2**32-1 means - we need only a single check when deserialising */ + * 2**32-1 on sequence lengths because it encodes them as + * 32-bit unsigned. Transforming unbounded to 2**32-1 means + * we need only a single check when deserialising + */ const os_uint32 maxn = (type->u.sequence.maxn == 0) ? ~(os_uint32)0 : type->u.sequence.maxn; struct insnstream_marker mpush, m; if ((rc = is_append_marker_placeholder (&mpush, st, INSN_PUSHSTAR)) < 0) @@ -2076,9 +2095,10 @@ static int lowertype1 (struct lowertype_context *ctx, const struct ser_type *typ case TK_RSEQUENCE: { /* Type uses 0 to encode maxn, but CDR has a hard limit of - 2**32-1 on sequence lengths because it encodes them as - 32-bit unsigned. Transforming unbounded to 2**32-1 means - we need only a single check when deserialising */ + * 2**32-1 on sequence lengths because it encodes them as + * 32-bit unsigned. Transforming unbounded to 2**32-1 means + * we need only a single check when deserialising + */ const os_uint32 maxn = (type->u.sequence.maxn == 0) ? ~(os_uint32)0 : type->u.sequence.maxn; /* label is in context, along with the instruction marker */ struct insnstream_marker mpush, m; @@ -2155,9 +2175,10 @@ static int lowertype1 (struct lowertype_context *ctx, const struct ser_type *typ if ((rc = is_append_srcadv (st, (unsigned) (type->u.union_list.moff - discsz))) < 0) goto union_return_rc; /* push_srcpos this late so that recursive call sees - offset 0; at the end of the union we pop the source pos - and advance it beyond the union, so there is no harm in - the successive append_srcadv's here. */ + * offset 0; at the end of the union we pop the source pos + * and advance it beyond the union, so there is no harm in + * the successive append_srcadv's here. + */ is_push_srcpos (st); if ((rc = lowertype1 (ctx, type->u.union_list.ms[i].type)) < 0) goto union_return_rc; @@ -2197,8 +2218,9 @@ static int lowertype1 (struct lowertype_context *ctx, const struct ser_type *typ break; case TK_PRIM8: /* insn_dispatch_list8 uses prim8, and therefore has to - be 8-byte aligned. That means the dispatch - instruction itself must be on an even position */ + * be 8-byte aligned. That means the dispatch + * instruction itself must be on an even position + */ if ((rc = is_align2 (st)) < 0) goto union_return_rc; if ((rc = is_append_count (st, 8, INSN_PRIM8_DISPATCH_LIST, count)) < 0) @@ -2255,11 +2277,12 @@ static int lowertype1 (struct lowertype_context *ctx, const struct ser_type *typ if (ctx->depth == 1) { /* top-level class is ignored: that is handled outside the - (de)serializer VM, so all we need to do is process the - struct representing the class's members. SRCPOS is - essentially irrelevant for the top-level struct, the - fiddling here is just to keep the code handling trailing - padding happy. */ + * (de)serializer VM, so all we need to do is process the + * struct representing the class's members. SRCPOS is + * essentially irrelevant for the top-level struct, the + * fiddling here is just to keep the code handling trailing + * padding happy. + */ is_adv_srcpos (st, sizeof (void *)); is_push_srcpos (st); if ((rc = lowertype1 (ctx, type->u.class.subtype)) < 0) @@ -2352,9 +2375,10 @@ static int lowertype (struct serprog **prog, const struct ser_type *type, c_type static void *extract_pointer_from_code (const char *cptr) { /* ptr is at least 4 byte aligned, so on 32-bits platforms and on - those with hardware-supported misaligned loads, it is best to - just load it (but we don't have an easy way of knowing whether - our platforms supports misaligned loads) */ + * those with hardware-supported misaligned loads, it is best to + * just load it (but we don't have an easy way of knowing whether + * our platforms supports misaligned loads) + */ void *ptr; memcpy (&ptr, cptr, sizeof (void *)); return ptr; @@ -2891,9 +2915,10 @@ static void serprog_exec_trace (FILE *fp, int *indent, const struct serprog *pro static const char *getstring (const char *src) { /* data is a c_string* is an os_char** is a char** (it's - gotta be 'cos it's passed to strlen -- O! the joys of - defining aliases for primitive types in C ... FIXME: - wstrings? */ + * gotta be 'cos it's passed to strlen -- O! the joys of + * defining aliases for primitive types in C ... + * FIXME: wstrings? + */ const char *s = (const char *) (*((const c_string *) src)); return s; } @@ -2901,10 +2926,11 @@ static const char *getstring (const char *src) static int serprog_exec (struct sd_cdrSerdata *sd, const struct serprog *prog, const char *data, os_uint32 size_hint) { /* os_address really means uintptr_t: unsigned int, or a pointer; - stack is unified for loop counts, source pointers and code - pointers; when both a loop and a source pointer are are pushed, - src goes first (and therefore when both are popped, src comes - last) */ + * stack is unified for loop counts, source pointers and code + * pointers; when both a loop and a source pointer are are pushed, + * src goes first (and therefore when both are popped, src comes + * last) + */ const struct insn_enc *xs = (const struct insn_enc *) prog->buf; os_address stk_storage[128]; os_address *stk = &stk_storage[0]; @@ -3115,8 +3141,9 @@ static int serprog_exec (struct sd_cdrSerdata *sd, const struct serprog *prog, c if (n < insn.count) { /* note that the src is not really needed for clearing, - but the function does advance the source pointer, - needed or not */ + * but the function does advance the source pointer, + * needed or not + */ ser_clear_multiple_0 (prog->control, sd, &dst, &dstlimit, &s, insn.count - n); } src += sizeof (char *); @@ -3318,10 +3345,11 @@ static int ser_write_swap_2 ( static int serprog_exec_swap (struct sd_cdrSerdata *sd, const struct serprog *prog, const char *data, os_uint32 size_hint) { /* os_address really means uintptr_t: unsigned int, or a pointer; - stack is unified for loop counts, source pointers and code - pointers; when both a loop and a source pointer are are pushed, - src goes first (and therefore when both are popped, src comes - last) */ + * stack is unified for loop counts, source pointers and code + * pointers; when both a loop and a source pointer are are pushed, + * src goes first (and therefore when both are popped, src comes + * last) + */ const struct insn_enc *xs = (const struct insn_enc *) prog->buf; os_address stk_storage[128]; os_address *stk = &stk_storage[0]; @@ -3531,8 +3559,9 @@ static int serprog_exec_swap (struct sd_cdrSerdata *sd, const struct serprog *pr if (n < insn.count) { /* note that the src is not really needed for clearing, - but the function does advance the source pointer, - needed or not */ + * but the function does advance the source pointer, + * needed or not + */ ser_clear_multiple_0 (prog->control, sd, &dst, &dstlimit, &s, insn.count - n); } src += sizeof (char *); @@ -3619,8 +3648,9 @@ static int serprog_exec_swap (struct sd_cdrSerdata *sd, const struct serprog *pr /******************** DESERIALIZE VM (STRAIGHT) ********************/ /* FIXME: natural alignment on input guaranteed to be 4, - so can't do address-based alignment and need to use - memcpy (on some platforms) for 8 byte objects */ + * so can't do address-based alignment and need to use + * memcpy (on some platforms) for 8 byte objects + */ #define SRC_CHECK_ALIGN(amount, align) do { \ src = blob + alignup_address ((os_address) (src - blob), (align)); \ if (src + amount > srclimit) \ @@ -3683,9 +3713,10 @@ static int serprog_exec_swap (struct sd_cdrSerdata *sd, const struct serprog *pr } while (0) #define DESERPROG_EXEC_DISPATCH_list4 DESERPROG_EXEC_DISPATCH_list #define DESERPROG_EXEC_DISPATCH_list8 DESERPROG_EXEC_DISPATCH_list -/* Note: sneakily reading just-deserialized discriminator from result, - rather than reading discriminator from source. Also note the - confusingly named "srcadv". */ +/* NOTE: sneakily reading just-deserialized discriminator from result, + * rather than reading discriminator from source. Also note the + * confusingly named "srcadv". + */ #define DESERPROG_EXEC_DISPATCH(width, mode) do { \ const struct insn_dispatch_##mode *ds = \ (const struct insn_dispatch_##mode *) (xs + 1); \ @@ -3720,8 +3751,9 @@ static int deserprog_exec (char *dst, const struct serprog *prog, os_uint32 sz, serprog_exec_trace (stderr, &indent, prog, xs - 1, loopcount); #endif /* FIXME: instruction fields are named for serialisation, so - "source advance" suddenly becomes "destination advance" when - deserializing */ + * "source advance" suddenly becomes "destination advance" when + * deserializing + */ dst += insn.srcadv; switch ((enum insn_opcode) insn.opcode) { @@ -3939,10 +3971,11 @@ static int deserprog_exec (char *dst, const struct serprog *prog, os_uint32 sz, break; case INSN_PRIM1_CONST: /* Constants are not represented in the deserialized - representation, so we can skip them -- or we can require - that they have the expected value. Given it is currently - only being used for an optional endianness marker, perhaps - it'd be wise to check */ + * representation, so we can skip them -- or we can require + * that they have the expected value. Given it is currently + * only being used for an optional endianness marker, perhaps + * it'd be wise to check + */ SRC_CHECK_ALIGN (1, 1); if (*src != insn.count) return SD_CDR_INVALID; @@ -4068,8 +4101,9 @@ static int deserprog_exec_swap (char *dst, const struct serprog *prog, os_uint32 serprog_exec_trace (stderr, &indent, prog, xs - 1, loopcount); #endif /* FIXME: instruction fields are named for serialisation, so - "source advance" suddenly becomes "destination advance" when - deserializing */ + * "source advance" suddenly becomes "destination advance" when + * deserializing + */ dst += insn.srcadv; switch ((enum insn_opcode) insn.opcode) { @@ -4287,10 +4321,11 @@ static int deserprog_exec_swap (char *dst, const struct serprog *prog, os_uint32 break; case INSN_PRIM1_CONST: /* Constants are not represented in the deserialized - representation, so we can skip them -- or we can require - that they have the expected value. Given it is currently - only being used for an optional endianness marker, perhaps - it'd be wise to check */ + * representation, so we can skip them -- or we can require + * that they have the expected value. Given it is currently + * only being used for an optional endianness marker, perhaps + * it'd be wise to check + */ SRC_CHECK_ALIGN (1, 1); if (*src != insn.count) return SD_CDR_INVALID; @@ -4439,8 +4474,9 @@ void sd_cdrInfoFree (struct sd_cdrInfo *ci) int sd_cdrNoteCatsStac (struct sd_cdrInfo *ci, unsigned n, struct c_type_s const * const *typestack) { /* typestack contains: structs, unions, arrays, sequences + - string(cats)/array(stac), i.e., the full path without - typedefs. */ + * string(cats)/array(stac), i.e., the full path without + * typedefs. + */ struct sd_catsstac *cs; cs = os_malloc (offsetof (struct sd_catsstac, typestack) + n * sizeof (*cs->typestack)); cs->next = NULL; diff --git a/src/database/serialization/code/sd_contextItem.c b/src/database/serialization/code/sd_contextItem.c index cdc2e7063..9e9e1533d 100644 --- a/src/database/serialization/code/sd_contextItem.c +++ b/src/database/serialization/code/sd_contextItem.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/database/serialization/code/sd_deepwalk.c b/src/database/serialization/code/sd_deepwalk.c index a1b6b5180..a0e46f3df 100644 --- a/src/database/serialization/code/sd_deepwalk.c +++ b/src/database/serialization/code/sd_deepwalk.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -429,7 +430,7 @@ static c_bool sd_deepwalkType(c_type type, c_object *objectPtr, sd_deepwalkFunc break; } } - + return TRUE; } diff --git a/src/database/serialization/code/sd_deepwalk.h b/src/database/serialization/code/sd_deepwalk.h index a9028ff91..2088604da 100644 --- a/src/database/serialization/code/sd_deepwalk.h +++ b/src/database/serialization/code/sd_deepwalk.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/database/serialization/code/sd_deepwalkMeta.c b/src/database/serialization/code/sd_deepwalkMeta.c index d4dc94c85..f80840459 100644 --- a/src/database/serialization/code/sd_deepwalkMeta.c +++ b/src/database/serialization/code/sd_deepwalkMeta.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -750,7 +751,8 @@ sd_deepwalkMetaClass( if ((*objectPtr) && *((c_class *)(*objectPtr))) { /* For deepwalkMeta, we are interested in the actual class. We might - * have a baseclass here so downcast to the real class */ + * have a baseclass here so downcast to the real class + */ actualClass = c_class(c_getType(*((c_type *)(*objectPtr)))); } else { actualClass = class; @@ -766,10 +768,12 @@ sd_deepwalkMetaClass( } /* Again re-evaluate the actual class because the Pre-function might - * have changed its value. This is the case for virtual classes */ + * have changed its value. This is the case for virtual classes + */ if ((*objectPtr) && *((c_class *)(*objectPtr))) { /* For deepwalkMeta, we are interested in the actual class. We might - * have a baseclass here so downcast to the real class */ + * have a baseclass here so downcast to the real class + */ actualClass = c_class(c_getType(*((c_type *)(*objectPtr)))); } else { actualClass = class; @@ -1141,7 +1145,7 @@ sd_deepwalkMetaType( ok = FALSE; break; } - + assert (ok || context->errorInfo); return ok; } diff --git a/src/database/serialization/code/sd_errorReport.c b/src/database/serialization/code/sd_errorReport.c index 29c62c304..cb197ad17 100644 --- a/src/database/serialization/code/sd_errorReport.c +++ b/src/database/serialization/code/sd_errorReport.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/database/serialization/code/sd_list.c b/src/database/serialization/code/sd_list.c index 029d7c989..98a0dc10b 100644 --- a/src/database/serialization/code/sd_list.c +++ b/src/database/serialization/code/sd_list.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -385,8 +386,7 @@ sd_listIndexOf ( return i; } -/* - * Inserts 'object' at index 'index', which causes all elements from index 'index' and higher +/* Inserts 'object' at index 'index', which causes all elements from index 'index' and higher * to move one higher in the list. */ void @@ -416,8 +416,7 @@ sd_listInsertAt( after->prev = node; } -/* - * This method inserts 'object' before 'beforeObject'. +/* This method inserts 'object' before 'beforeObject'. * * Precondition: 'beforeObject' is in the list. * Postcondition: 'object' is in the list, before 'beforeObject'. diff --git a/src/database/serialization/code/sd_misc.c b/src/database/serialization/code/sd_misc.c index b175f98da..12c35ac59 100644 --- a/src/database/serialization/code/sd_misc.c +++ b/src/database/serialization/code/sd_misc.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/database/serialization/code/sd_misc.h b/src/database/serialization/code/sd_misc.h index bcefad97a..24de49263 100644 --- a/src/database/serialization/code/sd_misc.h +++ b/src/database/serialization/code/sd_misc.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/database/serialization/code/sd_randomizer.c b/src/database/serialization/code/sd_randomizer.c index f3d2180dc..4d226bbf7 100644 --- a/src/database/serialization/code/sd_randomizer.c +++ b/src/database/serialization/code/sd_randomizer.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/database/serialization/code/sd_serializer.c b/src/database/serialization/code/sd_serializer.c index 1df5b8a64..4089dc0e1 100644 --- a/src/database/serialization/code/sd_serializer.c +++ b/src/database/serialization/code/sd_serializer.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -67,7 +68,7 @@ * translated into a big endian in the header of the * serialized data. * \param formatVersion The version number of the serialization used. This - * will be translated into big endian in the header of the + * will be translated into big endian in the header of the * serialized data. * \param dataSize The size of the data when serialized. This amount of bytes * will be allocated by the constructor. @@ -285,11 +286,11 @@ sd_serializerCheckDataFormat( { c_bool idOK, versionOK; c_bool result; - + idOK = (c_bool)((int)serializer->formatID == (int)sd_serializedDataGetFormatID(serData)); versionOK = (c_bool)((int)serializer->formatVersion == (int)sd_serializedDataGetFormatVersion(serData)); result = idOK && versionOK; - + return result; } @@ -373,7 +374,7 @@ sd_serializerInitialize( sd_validationInfoInit(&serializer->validationInfo); serializer->VMT = VMT; } - + /** \brief Protected function used by \b sd_serializer descendants for * indicating if they want to do validation during deserialization @@ -383,7 +384,7 @@ sd_serializerInitialize( * stores some internal information. This protected function offers the * possibility for descendants to indicate that they indeed want to use the * internal information for validation. - * + * * \param serializer The serializer object (self) * \param doValidation Boolean value indicating whether validation information * is to be maintained or not @@ -393,7 +394,7 @@ sd_serializerResetValidationState( sd_serializer serializer) { sd_validationInfoReset(&serializer->validationInfo); -} +} /** \brief Protected function used by \b sd_serializer descendants for setting * validation information in case of an error. @@ -403,7 +404,7 @@ sd_serializerResetValidationState( * encapsulated validation state. The error numbers used are supposed to be * unique over all serializing classes and are to be interpreted by the class * itself only. - * + * * \param serializer The serializer object (self) * \param errorNumber Numeric representation of the error encountered * \param message Readable message explaining the error encountered @@ -451,13 +452,13 @@ sd_serializerSerialize( c_object object) { sd_serializedData result = NULL; - + SD_CONFIDENCE(sd_serializerCheckBase(serializer, object)); - + if (serializer->VMT.serialize) { result = serializer->VMT.serialize(serializer, object); } - + return result; } @@ -470,7 +471,7 @@ sd_serializerSerialize( * Before deserialization, the serialized data is checked for format ID * and version. This has to correspond with the serializer format ID and * version. - * + * * Use the serializer's lastValidationResult function in order to check on * encountered errors. * @@ -487,9 +488,9 @@ sd_serializerDeserialize( sd_serializedData serData) { c_object result = NULL; - + SD_CONFIDENCE(sd_serializerCheckDataFormat(serializer, serData)); - + if (serializer->VMT.deserialize) { result = serializer->VMT.deserialize(serializer, serData); if (result == NULL && serializer->validationInfo.errorNumber == SD_SUCCESS) { @@ -497,7 +498,7 @@ sd_serializerDeserialize( sd_serializerSetValidationInfo(serializer, SD_ERRNO_ERROR, os_strdup(SD_MESSAGE_ERROR), NULL); } } - + return result; } @@ -510,7 +511,7 @@ sd_serializerDeserialize( * Before deserialization, the serialized data is checked for format ID * and version. This has to correspond with the serializer format ID and * version. - * + * * Use the serializer's lastValidationResult function in order to check on * encountered errors. * @@ -530,7 +531,7 @@ sd_serializerDeserializeInto( c_object object) { SD_CONFIDENCE(sd_serializerCheckDataFormat(serializer, serData)); - + if (serializer->VMT.deserializeInto) { c_bool result = serializer->VMT.deserializeInto(serializer, serData, object); if (!result && serializer->validationInfo.errorNumber == SD_SUCCESS) { @@ -564,13 +565,13 @@ sd_serializerToString( sd_serializedData serData) { c_char *result = NULL; - + SD_CONFIDENCE(sd_serializerCheckDataFormat(serializer, serData)); - + if (serializer->VMT.toString) { result = serializer->VMT.toString(serializer, serData); } - + return result; } @@ -591,11 +592,11 @@ sd_serializerFromString( const c_char *str) { sd_serializedData result = NULL; - + if (serializer->VMT.fromString) { result = serializer->VMT.fromString(serializer, str); } - + return result; } @@ -631,8 +632,8 @@ sd_serializerLastValidationMessage( { return serializer->validationInfo.message; } - - + + /** \brief Query a character pointer to the first error encountered during * deserialization. * diff --git a/src/database/serialization/code/sd_serializerBigE.c b/src/database/serialization/code/sd_serializerBigE.c index 3ba9a026a..6d66feac3 100644 --- a/src/database/serialization/code/sd_serializerBigE.c +++ b/src/database/serialization/code/sd_serializerBigE.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -653,7 +654,7 @@ static c_bool sd_bigEDeserCallback (c_type type, c_object *objectPtr, void *acti len = 0; break; } - + *dataPtrPtr = C_DISPLACE(*dataPtrPtr, C_ADDRESS(len)); return TRUE; } @@ -967,7 +968,7 @@ sd_serializerBigEDeserializeTypedInternal( } else { SD_CONFIDENCE(result && (C_ADDRESS(startPtr) - C_ADDRESS(serData->data)) == sd_serializedDataGetDataSize(serData)); } - + return result; } diff --git a/src/database/serialization/code/sd_serializerXML.c b/src/database/serialization/code/sd_serializerXML.c index 3a7ecf752..a03285359 100644 --- a/src/database/serialization/code/sd_serializerXML.c +++ b/src/database/serialization/code/sd_serializerXML.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -322,8 +323,7 @@ sd_printReference( c_ulong result; int snpRes; - /* Check if this is a null reference. In that case, we should still print - something */ + /* Check if this is a null reference. In that case, we should still print something */ if (sd_isValidReference(object)) { snpRes = snprintf(dataPtr, sizeof(SD_VALID_REF_IMAGE), "%s", SD_VALID_REF_IMAGE); } else { @@ -720,7 +720,8 @@ sd_XMLSerCallbackPost( /* An implementation for counting: do the serialization but overwrite - a static buffer. Count anyway and return the count. */ + *a static buffer. Count anyway and return the count. + */ static c_bool sd_XMLCountCallback(const c_char *name, c_type type, c_object *objectPtr, void *actionArg, sd_errorInfo *errorInfo, void *userData) __nonnull((2, 3, 4, 5, 6)) __attribute_warn_unused_result__; static c_bool @@ -865,8 +866,9 @@ sd_serializerXMLSerializeTyped( #define SD_CHARS_CHAR "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" #define SD_CHARS_DIGIT "1234567890" -/* Note: Some characters are serialized using octal representation. These are omitted from the following set, - * except for '\', required to recognize the octal representations (i.e. '\001') */ +/* NOTE: Some characters are serialized using octal representation. These are omitted from the following set, + * except for '\', required to recognize the octal representations (i.e. '\001') + */ #define SD_CHARS_SPECIAL "!\"#$%'()*+,-./:;=?@[\\]^_`{|}~" #define SD_CHARS_SPACES " \t\n" @@ -940,7 +942,8 @@ sd_skipPrim( * This would mean that if you have a locale (like nl_NL and fr_FR) * that uses a comma as decimal point (aka LC_NUMERIC), then you * would run into trouble because the rest of the ospl system uses - * a point as decimal point. */ + * a point as decimal point. + */ static c_long sd_scanDoubleNoSkip( c_char *dataPtr, @@ -1482,8 +1485,8 @@ sd_scanCharData( } -/** Peek for string between tags. Note that no escape sequences - * are allowed here, nor are mixes of strings and CDATA +/* Peek for string between tags. Note that no escape sequences + * are allowed here, nor are mixes of strings and CDATA */ c_char * sd_peekTaggedCharData( @@ -1766,7 +1769,8 @@ sd_XMLDeserInterface( if (isValidRef) { /* treat a non-instantiated interface the same - as a NULL pointer. This avoids memleaks. */ + * as a NULL pointer. This avoids memleaks. + */ if (!(*placeHolder)) { if ((*placeHolder = c_new_s(c_type(interf))) == NULL) { SD_VALIDATION_SET_ERROR(errorInfo, OUT_OF_MEMORY, NULL, NULL); diff --git a/src/database/serialization/code/sd_serializerXMLMetadata.c b/src/database/serialization/code/sd_serializerXMLMetadata.c index e0cca312c..c4f359a4d 100644 --- a/src/database/serialization/code/sd_serializerXMLMetadata.c +++ b/src/database/serialization/code/sd_serializerXMLMetadata.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -853,8 +854,6 @@ sd_createOrLookupType( *actualType = NULL; *typeExisted = FALSE; - /* Free the abstract type that was created before */ - /* c_free(*objectPtr); */ helperPtrPtr = &dataPtr; kindPtrPtr = &kindPtr; @@ -1039,7 +1038,8 @@ sd_XMLMetadataDeserCallbackPre( typeAction = sd_matchesAbstractTypeAddresses(special, c_typeActualType(type)); if (typeAction) { /* This is an abstract type. Lookup the concrete instance type and - * create it, if it does not exist */ + * create it, if it does not exist + */ if (!sd_createOrLookupType(objectPtr, *dataPtrPtr, &actualType, &typeExisted, errorInfo, special)) { return FALSE; } @@ -1240,7 +1240,8 @@ sd_XMLMetadataDeserHook( /* This is a special case. The type has already been set * before the deserializer has processed it. The only known * situation for this is c_string: c_stringNew sets the - * subtype. */ + * subtype. + */ special->currentContext.existingType = c_type(typeInstance); special->currentContext.doCompare = TRUE; if (!doSerHook(doRecurse, name, propOrMem, objectPtr, dataPtrPtr, errorInfo, special)) { diff --git a/src/database/serialization/code/sd_serializerXMLTypeinfo.c b/src/database/serialization/code/sd_serializerXMLTypeinfo.c index 8b6919c9c..ed0f17ab3 100644 --- a/src/database/serialization/code/sd_serializerXMLTypeinfo.c +++ b/src/database/serialization/code/sd_serializerXMLTypeinfo.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -79,52 +80,6 @@ sd_checkSerializerType( } #endif -#if 0 -typedef struct { - sd_contextItemKind kind; - c_metaKind metaKind; - const c_char *xmlName; - const c_char *typeName; - union { - int kind; - c_primKind primKind; - c_collKind collKind; - } special; -} sd_typeInfo; - -static const sd_typeInfo typeInfoMap[] = { - { SD_CONTEXT_ITEM_MODULE, M_MODULE, "Module", "c_structure", { (int) P_UNDEFINED } }, - { SD_CONTEXT_ITEM_STRUCTURE, M_STRUCTURE, "Struct", "c_structure", { (int) P_UNDEFINED } }, - { SD_CONTEXT_ITEM_MEMBER, M_MEMBER, "Member", "c_member", { (int) P_UNDEFINED } }, - { SD_CONTEXT_ITEM_TYPEDEF, M_TYPEDEF, "TypeDef", "c_typeDef", { (int) P_UNDEFINED } }, - { SD_CONTEXT_ITEM_ARRAY, M_COLLECTION, "Array", "c_collection", { (int) C_ARRAY } }, - { SD_CONTEXT_ITEM_SEQUENCE, M_COLLECTION, "Sequence", "c_collection", { (int) C_SEQUENCE } }, - { SD_CONTEXT_ITEM_ENUMERATION, M_ENUMERATION, "Enum", "c_enumeration", { (int) P_UNDEFINED } }, - { SD_CONTEXT_ITEM_UNION, M_UNION, "Union", "c_union", { (int) P_UNDEFINED } }, - { SD_CONTEXT_ITEM_UNIONCASE, M_UNIONCASE, "UNIONCASE", "c_unionCase", { (int) P_UNDEFINED } } -}; -static const c_long typeInfoMapSize = sizeof(typeInfoMap)/sizeof(sd_typeInfo); - -static const sd_typeInfo specTypeInfoMap[] = { - { SD_CONTEXT_ITEM_TYPE, M_UNDEFINED, "Type", NULL, { (int) P_UNDEFINED } }, - { SD_CONTEXT_ITEM_STRING, M_COLLECTION, "String", "c_string", { (int) C_STRING } }, - { SD_CONTEXT_ITEM_PRIMITIVE, M_PRIMITIVE, "Address", "c_address", { (int) P_ADDRESS } }, - { SD_CONTEXT_ITEM_PRIMITIVE, M_PRIMITIVE, "Boolean", "c_bool", { (int) P_BOOLEAN } }, - { SD_CONTEXT_ITEM_PRIMITIVE, M_PRIMITIVE, "Char", "c_char", { (int) P_CHAR } }, - { SD_CONTEXT_ITEM_PRIMITIVE, M_PRIMITIVE, "WChar", "c_wchar", { (int) P_WCHAR } }, - { SD_CONTEXT_ITEM_PRIMITIVE, M_PRIMITIVE, "Octet", "c_octet", { (int) P_OCTET } }, - { SD_CONTEXT_ITEM_PRIMITIVE, M_PRIMITIVE, "Short", "c_short", { (int) P_SHORT } }, - { SD_CONTEXT_ITEM_PRIMITIVE, M_PRIMITIVE, "UShort", "c_ushort", { (int) P_USHORT } }, - { SD_CONTEXT_ITEM_PRIMITIVE, M_PRIMITIVE, "Long", "c_long", { (int) P_LONG } }, - { SD_CONTEXT_ITEM_PRIMITIVE, M_PRIMITIVE, "ULong", "c_ulong", { (int) P_ULONG } }, - { SD_CONTEXT_ITEM_PRIMITIVE, M_PRIMITIVE, "LongLong", "c_longlong", { (int) P_LONGLONG } }, - { SD_CONTEXT_ITEM_PRIMITIVE, M_PRIMITIVE, "ULongLong", "c_ulonglong", { (int) P_ULONGLONG } }, - { SD_CONTEXT_ITEM_PRIMITIVE, M_PRIMITIVE, "Float", "c_float", { (int) P_FLOAT } }, - { SD_CONTEXT_ITEM_PRIMITIVE, M_PRIMITIVE, "Double", "c_double", { (int) P_DOUBLE } } -}; -static const c_long specTypeInfoMapSize = sizeof(specTypeInfoMap)/sizeof(sd_typeInfo); -#endif - /* --------------------- Serialization driving functions -------------------- */ typedef struct sd_context_s* sd_context; @@ -373,7 +328,8 @@ sd_itemDerefDependee( } /* Deref dependees. Dependees are deref'd when a dependency (the item passed to this function) is - * resolved. When a dependee reaches refcount zero, it can be processed itself. */ + * resolved. When a dependee reaches refcount zero, it can be processed itself. + */ static void sd_itemDerefDependees( sd_item item) @@ -454,7 +410,7 @@ sd_contextProcessed( { struct sd_contextFindModule_t walkData; assert(!sd_contextIsProcessed(context, item->self)); - c_iterAppend(context->items, item); + context->items = c_iterAppend(context->items, item); /* Find corresponding module */ walkData.find = c_metaObject(item->self)->definedIn; @@ -481,7 +437,7 @@ sd_contextDeclare( sd_item item) { assert(!sd_contextIsProcessed(context, item->self)); - c_iterAppend(context->declarations, item); + context->declarations = c_iterAppend(context->declarations, item); } /* Serialize a type */ @@ -628,7 +584,8 @@ sd_serializeUnionDependencies( * Parameter 'rootType' is typically the same as the 'type' parameter. * However, for inline types these two differ. The distinction * enables that dependencies are always added to the - * top-level type. */ + * top-level type. * + */ static int sd_serializeTypeDependencies( sd_context context, @@ -704,7 +661,8 @@ sd_serializeType( }else { /* Don't process inlined types in graph. These are resolved when the parent-type is printed, which is always in correct * dependency order, which is the order of members(structs) or cases(unions). Collections are also considered - * inlined, because the actual location of a collection type is implementation specific. */ + * inlined, because the actual location of a collection type is implementation specific. + */ if(!sd_utilIsInlined(type)) { /* Here, the usage of 'rootType' is prohibited since this is not an inlined type. */ @@ -713,7 +671,8 @@ sd_serializeType( /* Add forward-declaration marker for structs and unions, to allow references to self, so that * the cycles can be detected. IDL does not allow other types to be forward-declared, thus - * cannot introduce cyclic references. */ + * cannot introduce cyclic references. + */ if((c_baseObject(type)->kind == M_STRUCTURE) || (c_baseObject(type)->kind == M_UNION)) { sd_contextDeclare(context, item); } @@ -741,13 +700,15 @@ sd_serializeType( } /* If rootType is referencing an inlined type that is defined in the scope of another type, - * rootType is implicitly dependent on the rootType of the inlined type. */ + * rootType is implicitly dependent on the rootType of the inlined type. + */ if(rootType->self != (typeRoot = sd_utilRootType(type))) { sd_item typeRootItem = NULL; /* An empty typeRoot means that the type is not stored as inlined object, but conceptually it is. * This will typically occur for intern collectiontypes like c_string, who are defined - * in the root. */ + * in the root. + */ if(typeRoot) { /* Serialize rootType of type */ if(sd_serializeType(context, NULL, typeRoot, allowCycles, &typeRootItem)) { @@ -1136,7 +1097,8 @@ sd_printXmlCollection( /* Print collection size, subType and footer. Pass current rootType to * sd_printXmlType so inlined types that are used as subtype are defined within - * the inline collection. */ + * the inline collection. + */ switch(type->kind) { case OSPL_C_SEQUENCE: case OSPL_C_ARRAY: @@ -1269,7 +1231,8 @@ sd_printXmlTyperef( } /* Open module. This function finds the shortest path from the current module to the next, - * and opens and closes modules where necessary. */ + * and opens and closes modules where necessary. + */ static void sd_printXmlModuleOpen( sd_context context, @@ -1291,7 +1254,8 @@ sd_printXmlModuleOpen( /* Find common module. First build up a scope-stack for the two modules which * are ordered base -> . Then walk through these stacks to find the - * last common module. */ + * last common module. + */ sd_utilModuleStack(from, fromStack); sd_utilModuleStack(to, toStack); toPtr = sd_utilFirstCommonModule(from, to, fromStack, toStack, &i); @@ -1345,7 +1309,8 @@ sd_printXmlType( }else { /* If object is defined outside the current scope and is not a collection or primitive, serialize a typeref. * Also, if the type is already defined serialize a typeref. This prevents inline types to be defined multiple - * times if they are used multiple times within a module-scoped type. */ + * times if they are used multiple times within a module-scoped type. + */ if(!((c_baseObject(type)->kind == M_COLLECTION) || (c_baseObject(type)->kind == M_PRIMITIVE) || (!c_iterContains(context->inlineProcessed, type) && (c_metaObject(type)->definedIn == c_metaObject(current))))) { @@ -1374,7 +1339,8 @@ sd_printXmlType( break; default: /* This may not happen. Types other than the ones listed - * above cannot be printed. */ + * above cannot be printed. + */ assert(0); break; } @@ -1410,14 +1376,16 @@ sd_printXmlItem( break; default: /* This may not happen. Types other than the ones listed - * above cannot be directly printed. */ + * above cannot be directly printed. + */ OS_REPORT(OS_ERROR, "sd_printXmlItem", 0, "invalid typeKind for serializer."); assert(0); break; } /* Dereference dependees of item. This will populate module-objects with types - * that reach refcount 0. */ + * that reach refcount 0. + */ sd_itemDerefDependees(item); } @@ -1433,7 +1401,8 @@ sd_addInitialItems( item = o; /* If refcount of item is zero, it means that it has no unresolved dependencies, thus that it can - * be processed. */ + * be processed. + */ if(!item->refcount){ sd_itemAddToModule(item); } @@ -2126,27 +2095,6 @@ sd_deserXmlSequence ( return result; } -#if 0 -static sd_elementContext -sd_findScopeRoot ( - sd_elementContext context, - const c_char *name) -{ - sd_elementContext root = NULL; - - assert(name); - - while ( !root && context ) { - if ( context->name && (strcmp(context->name, name) == 0) ) { - root = context; - } else { - context = context->parent; - } - } - return root; -} -#endif - static c_metaObject sd_findScopeInContext ( sd_elementContext context, @@ -2243,9 +2191,10 @@ sd_findTypeInScope ( /* If not found, look it up in the root scope of the database. */ o = c_metaResolve(scope->info->base, name); if ( !o ) { - /* If still not found, look it up in the root of the serializer scope. */ - /* This is appropriate in case of recursive references to self, where */ - /* self is not yet inserted into the database. */ + /* If still not found, look it up in the root of the serializer scope. + * This is appropriate in case of recursive references to self, where + * self is not yet inserted into the database. + */ o = sd_findScopeInContext(scope, (c_char*)name); } } @@ -2607,7 +2556,7 @@ sd_stringToPrimValue ( break; case P_USHORT: if ( sd_stringToLong(str, &lv) ) { - value = c_longValue((c_ushort)lv); + value = c_ushortValue((c_ushort)lv); } break; case P_ULONG: diff --git a/src/database/serialization/code/sd_string.c b/src/database/serialization/code/sd_string.c index b4b1ddfb2..63fdd26e7 100644 --- a/src/database/serialization/code/sd_string.c +++ b/src/database/serialization/code/sd_string.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/database/serialization/code/sd_string.h b/src/database/serialization/code/sd_string.h index d7e856ddf..c20d9f70d 100644 --- a/src/database/serialization/code/sd_string.h +++ b/src/database/serialization/code/sd_string.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/database/serialization/code/sd_stringsXML.c b/src/database/serialization/code/sd_stringsXML.c index 87d619fb7..07548bd05 100644 --- a/src/database/serialization/code/sd_stringsXML.c +++ b/src/database/serialization/code/sd_stringsXML.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/database/serialization/code/sd_stringsXML.h b/src/database/serialization/code/sd_stringsXML.h index 7210919e7..38d8cd664 100644 --- a/src/database/serialization/code/sd_stringsXML.h +++ b/src/database/serialization/code/sd_stringsXML.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/database/serialization/code/sd_typeInfoParser.c b/src/database/serialization/code/sd_typeInfoParser.c index 9b438f1c6..dc5cd9e55 100644 --- a/src/database/serialization/code/sd_typeInfoParser.c +++ b/src/database/serialization/code/sd_typeInfoParser.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/database/serialization/code/sd_xmlNode.c b/src/database/serialization/code/sd_xmlNode.c index 18502217b..29eaa58fe 100644 --- a/src/database/serialization/code/sd_xmlNode.c +++ b/src/database/serialization/code/sd_xmlNode.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -61,9 +62,9 @@ sd_xmlElementFree ( sd_xmlElement node) { sd_xmlNode n; - + assert(node); - + if ( node->children ) { n = sd_xmlNode(sd_listTakeFirst(node->children)); while ( n ) { @@ -85,12 +86,12 @@ sd_xmlElementFree ( if ( node->data ) { sd_xmlNodeFree(node->data); } - + sd_xmlNodeDeinit(sd_xmlNode(node)); os_free(node); } - + sd_xmlAttribute sd_xmlAttributeNew ( void) @@ -106,7 +107,7 @@ sd_xmlAttributeFree ( sd_xmlAttribute node) { assert(node); - + if ( node->value ) { os_free(node->value); } @@ -115,7 +116,7 @@ sd_xmlAttributeFree ( os_free(node); } - + sd_xmlData sd_xmlDataNew ( void) @@ -131,7 +132,7 @@ sd_xmlDataFree ( sd_xmlData node) { assert(node); - + if ( node->data ) { os_free(node->data); } @@ -225,7 +226,7 @@ sd_xmlElementAdd ( } } - + sd_xmlElement sd_xmlElementGetParent ( sd_xmlElement node) @@ -303,7 +304,7 @@ sd_xmlFindNodeAction ( c_bool result = TRUE; assert(node->name); - + if ( strcmp(node->name, argument->name) == 0 ) { argument->node = node; result = FALSE; @@ -338,7 +339,7 @@ sd_xmlElementHasChildren ( result = TRUE; } } - + return result; } @@ -353,7 +354,7 @@ sd_xmlElementHasAttributes ( result = TRUE; } } - + return result; } @@ -362,7 +363,7 @@ sd_xmlElementNumAttributes ( sd_xmlElement node) { c_ulong size = 0; - + assert(node); if ( node->attributes ) { @@ -370,7 +371,7 @@ sd_xmlElementNumAttributes ( } return size; } - + c_bool sd_xmlNodeEqualName ( sd_xmlNode n1, diff --git a/src/database/serialization/code/sd_xmlNode.h b/src/database/serialization/code/sd_xmlNode.h index f00ef0ce2..2278ba15c 100644 --- a/src/database/serialization/code/sd_xmlNode.h +++ b/src/database/serialization/code/sd_xmlNode.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/database/serialization/code/sd_xmlParser.c b/src/database/serialization/code/sd_xmlParser.c index 6a6ab48e3..65cfdb228 100644 --- a/src/database/serialization/code/sd_xmlParser.c +++ b/src/database/serialization/code/sd_xmlParser.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/database/serialization/code/sd_xmlParser.h b/src/database/serialization/code/sd_xmlParser.h index 974709b1a..25fd03104 100644 --- a/src/database/serialization/code/sd_xmlParser.h +++ b/src/database/serialization/code/sd_xmlParser.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/database/serialization/include/sd_cdr.h b/src/database/serialization/include/sd_cdr.h index 8c9b51940..c44012ce7 100644 --- a/src/database/serialization/include/sd_cdr.h +++ b/src/database/serialization/include/sd_cdr.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,6 +28,11 @@ #else #define OS_API OS_API_IMPORT #endif + +#if defined (__cplusplus) +extern "C" { +#endif + /* !!!!!!!!NOTE From here no more includes are allowed!!!!!!! */ #define SD_CDR_OK 0 @@ -144,4 +150,8 @@ OS_API os_uint32 sd_cdrSerdataBlob (const void **blob, struct sd_cdrSerdata *ser #undef OS_API +#if defined (__cplusplus) +} +#endif + #endif /* SD_CDR_H */ diff --git a/src/database/serialization/include/sd_deepwalkMeta.h b/src/database/serialization/include/sd_deepwalkMeta.h index c4275875e..6e194721c 100644 --- a/src/database/serialization/include/sd_deepwalkMeta.h +++ b/src/database/serialization/include/sd_deepwalkMeta.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/database/serialization/include/sd_errorReport.h b/src/database/serialization/include/sd_errorReport.h index 52619bd20..64d3097e5 100644 --- a/src/database/serialization/include/sd_errorReport.h +++ b/src/database/serialization/include/sd_errorReport.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/database/serialization/include/sd_list.h b/src/database/serialization/include/sd_list.h index c894e279d..0e5502834 100644 --- a/src/database/serialization/include/sd_list.h +++ b/src/database/serialization/include/sd_list.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/database/serialization/include/sd_randomizer.h b/src/database/serialization/include/sd_randomizer.h index 2bce4375b..c01e17980 100644 --- a/src/database/serialization/include/sd_randomizer.h +++ b/src/database/serialization/include/sd_randomizer.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/database/serialization/include/sd_serializer.h b/src/database/serialization/include/sd_serializer.h index 715e21c52..8fc3525a9 100644 --- a/src/database/serialization/include/sd_serializer.h +++ b/src/database/serialization/include/sd_serializer.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/database/serialization/include/sd_serializerBigE.h b/src/database/serialization/include/sd_serializerBigE.h index 75c579d53..2b2317d0c 100644 --- a/src/database/serialization/include/sd_serializerBigE.h +++ b/src/database/serialization/include/sd_serializerBigE.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/database/serialization/include/sd_serializerXML.h b/src/database/serialization/include/sd_serializerXML.h index 0e866a29e..55d81f158 100644 --- a/src/database/serialization/include/sd_serializerXML.h +++ b/src/database/serialization/include/sd_serializerXML.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/database/serialization/include/sd_serializerXMLMetadata.h b/src/database/serialization/include/sd_serializerXMLMetadata.h index 10af8361d..2472523a6 100644 --- a/src/database/serialization/include/sd_serializerXMLMetadata.h +++ b/src/database/serialization/include/sd_serializerXMLMetadata.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/database/serialization/include/sd_serializerXMLTypeinfo.h b/src/database/serialization/include/sd_serializerXMLTypeinfo.h index 62a56bd03..18109ca4c 100644 --- a/src/database/serialization/include/sd_serializerXMLTypeinfo.h +++ b/src/database/serialization/include/sd_serializerXMLTypeinfo.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/database/serialization/include/sd_typeInfoParser.h b/src/database/serialization/include/sd_typeInfoParser.h index 566c2e6af..51ecd3f23 100644 --- a/src/database/serialization/include/sd_typeInfoParser.h +++ b/src/database/serialization/include/sd_typeInfoParser.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/code/v__builtin.h b/src/kernel/code/v__builtin.h index eeca14663..584868abc 100644 --- a/src/kernel/code/v__builtin.h +++ b/src/kernel/code/v__builtin.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -94,6 +95,67 @@ v_builtinCreateCMSubscriberInfo ( v_builtin _this, v_subscriber reader); +/* Returns TRUE if there is a partition match between + * the given publication and subscription info. + */ +os_boolean +v_builtinTestPartitionMatch( + const struct v_publicationInfo *pubInfo, + const struct v_subscriptionInfo *subInfo); + +/* Returns TRUE if there is a Qos match between + * the given publication and subscription info. + */ +os_boolean +v_builtinTestQosMatch( + const struct v_publicationInfo *pubInfo, + const struct v_subscriptionInfo *subInfo); + +void +v_builtinLogParticipant( + v_builtin _this, + const v_dataReaderSample sample); + +void +v_builtinLogPublication( + v_builtin _this, + const v_dataReaderSample sample); + +void +v_builtinLogSubscription( + v_builtin _this, + const v_dataReaderSample sample); + +void +v_builtinLogTopic( + v_builtin _this, + const v_dataReaderSample sample); + +void +v_builtinLogCMParticipant( + v_builtin _this, + const v_dataReaderSample sample); + +void +v_builtinLogCMDataWriter( + v_builtin _this, + const v_dataReaderSample sample); + +void +v_builtinLogCMDataReader( + v_builtin _this, + const v_dataReaderSample sample); + +void +v_builtinLogCMPublisher( + v_builtin _this, + const v_dataReaderSample sample); + +void +v_builtinLogCMSubscriber( + v_builtin _this, + const v_dataReaderSample sample); + #if defined (__cplusplus) } #endif diff --git a/src/kernel/code/v__collection.h b/src/kernel/code/v__collection.h index 330c113ec..91809943a 100644 --- a/src/kernel/code/v__collection.h +++ b/src/kernel/code/v__collection.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,9 +30,8 @@ extern "C" { void v_collectionInit ( - v_collection _this, - const c_char *name, - c_bool enable); + _Inout_ v_collection _this, + _In_opt_z_ const c_char *name); void v_collectionDeinit ( diff --git a/src/kernel/code/v__dataReader.h b/src/kernel/code/v__dataReader.h index 3558a9189..87dcf3f6d 100644 --- a/src/kernel/code/v__dataReader.h +++ b/src/kernel/code/v__dataReader.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -51,7 +52,8 @@ /* Updates the liveliness statistic for an instance. If oldState == 0, then * nothing is done. This is useful for initialization. It uses the newState - * (oldState ^ xoredState) to determine whether counters have to be updated. */ + * (oldState ^ xoredState) to determine whether counters have to be updated. + */ #define __V_DATAREADER_UPDATE_ALIVE__(reader, oldState, xoredState) \ if (oldState && __V_DATAREADER_LIVELINESS_CHANGED__(xoredState)) { \ if (__V_DATAREADER_ALIVE__(oldState)){\ @@ -62,7 +64,8 @@ } /* Updates the statistics for the instance-state flags that are enabled. Updates - * are only performed when statistics are enabled for the specified reader. */ + * are only performed when statistics are enabled for the specified reader. + */ #define UPDATE_READER_STATISTICS(index, instance, oldState) \ if (reader->statistics) { \ v_state xoredState = oldState^v_instanceState(instance); \ @@ -75,7 +78,8 @@ /* Subtracts the currently still enabled instance-state flags from the * statistics. Updates are only performed when statistics are enabled for - * the specified reader. */ + * the specified reader. + */ #define UPDATE_READER_STATISTICS_REMOVE_INSTANCE(reader, instance) \ if (reader->statistics) { \ __V_DATAREADER_UPDATE_FOR_FLAG__(L_NEW, New, reader, \ @@ -89,12 +93,6 @@ } \ } -#define v_dataReaderLock(_this) \ - v_observerLock(v_dataReader(_this)) - -#define v_dataReaderUnlock(_this) \ - v_observerUnlock(v_dataReader(_this)) - #define v_dataReaderQos(_this) \ (v_reader(v_dataReader(_this))->qos) @@ -151,28 +149,8 @@ v_dataReaderField( v_dataReader reader, const c_char *name); -c_bool -v_dataReaderSubscribe( - v_dataReader reader, - v_partition partition); - -c_bool -v_dataReaderUnSubscribe( - v_dataReader reader, - v_partition partition); - -c_bool -v_dataReaderSubscribeGroup( - v_dataReader reader, - v_group group); - -c_bool -v_dataReaderUnSubscribeGroup( - v_dataReader reader, - v_group group); - #define v_dataReaderAddEntry(_this,entry) \ - v_dataReaderEntry(v_readerAddEntry(v_reader(_this),v_entry(entry))) + v_readerAddEntry(v_reader(_this),v_entry(entry)) #define v_dataReaderNextInstance(_this,_inst) \ v_dataReaderInstance( \ @@ -185,13 +163,15 @@ v_dataReaderUnSubscribeGroup( * * This macro returns the parameter sample * - * @return sample */ + * @return sample + */ #define v_dataReaderTriggerValueKeep(sample) \ (c_keep(v_readerSample(sample)->instance), \ c_keep(sample)) /* The sample stored in the trigger-value has its (otherwise unreferenced) - * instance-pointer explicitly kept, so it has to be freed. */ + * instance-pointer explicitly kept, so it has to be freed. + */ #define v_dataReaderTriggerValueFree(triggerValue) \ { \ v_dataReaderInstance _instance; \ @@ -207,7 +187,11 @@ v_dataReaderUpdatePurgeLists( v_dataReader _this); void -v_dataReaderUpdatePurgeListsLocked( +v_dataReaderBeginAccess( + v_dataReader _this); + +void +v_dataReaderEndAccess( v_dataReader _this); typedef struct v_dataReaderConnectionChanges_s { @@ -216,11 +200,6 @@ typedef struct v_dataReaderConnectionChanges_s { c_iter removedPartitions; } v_dataReaderConnectionChanges; -void -v_dataReaderUpdateConnections( - v_dataReader _this, - v_dataReaderConnectionChanges *arg); - void v_dataReaderNotify( v_dataReader _this, @@ -237,12 +216,12 @@ v_dataReaderTriggerDataAvailable( v_dataReader _this); void -v_dataReaderNotifySampleLost( +v_dataReaderNotifySampleLost_nl( v_dataReader _this, c_ulong nrSamplesLost); void -v_dataReaderNotifySampleLostLock( +v_dataReaderNotifySampleLost( v_dataReader _this, c_ulong nrSamplesLost); @@ -320,21 +299,19 @@ v_dataReaderCheckDeadlineMissed( os_timeE now); c_ulong -v_dataReaderInstanceCount( +v_dataReaderInstanceCount_nl( v_dataReader _this); v_dataReaderInstance v_dataReaderAllocInstance( v_dataReader _this); +_Check_return_ +_Ret_maybenull_ OS_API v_topic v_dataReaderGetTopic( v_dataReader _this); -void -v_dataReaderFlushPending( - v_dataReader _this); - c_long v_dataReaderHistoryCount( v_dataReader _this); @@ -344,14 +321,6 @@ v_dataReaderHasMatchingSamples( v_dataReader _this, v_sampleMask mask); -void -v_dataReaderTrigger( - v_dataReader _this); - -void -v_dataReaderTriggerNoLock( - v_dataReader _this); - void v_dataReaderCheckMinimumSeparationList( v_dataReader _this, @@ -367,6 +336,30 @@ v_dataReaderMinimumSeparationListRemove( v_dataReader _this, v_dataReaderInstance instance); +v_result +v_dataReaderAccessTest( + v_dataReader _this); + +/* This operation informs the reader to either add or remove the publication described by + * the given publication info depending on the given ignore flag. + * If ignore is TRUE then the publication will be added to the readers ignore list and if + * ignore is FALSE then the publication will be removed from the ignore list if it exists. + * Note that removing a publication from the ignore list should only be performed if no data + * from the publication is to be expected in the future according to the DCPS specification. + */ +v_result +v_dataReaderIgnore( + v_dataReader _this, + struct v_publicationInfo *info, + os_boolean ignore); + +/* This operation will return the actual builtin subscription data for this dataReader. + * The dataReader caches this last published subscription data. + */ +v_message +v_dataReaderSubscription( + v_dataReader _this); + #undef OS_API #endif diff --git a/src/kernel/code/v__dataReaderEntry.h b/src/kernel/code/v__dataReaderEntry.h index 50bf5a7e2..f17c6deb5 100644 --- a/src/kernel/code/v__dataReaderEntry.h +++ b/src/kernel/code/v__dataReaderEntry.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -62,10 +63,6 @@ v_dataReaderEntryFlushTransactionNoLock( v_message message, c_voidp arg); -v_typeRepresentation -v__dataReaderEntryGetTypeRepresentation ( - v_dataReaderEntry _this); - v_writeResult v_dataReaderEntryDisposeAll ( v_dataReaderEntry _this, @@ -73,4 +70,21 @@ v_dataReaderEntryDisposeAll ( c_bool (*condition)(c_object instance, c_voidp condition_arg), c_voidp condition_arg); +/* This operation will add the given publication GID to the entry's ignore list. + * The entry will filter-out all messages that originate from this publication. + */ +void +v_dataReaderEntryIgnorePublication( + v_dataReaderEntry _this, + const struct v_publicationInfo *info); + +/* This operation will wipe the given publicatiom GID from the entry's ignore list. + * This can only be performed when the publication no longer exists and no data + * from this writer is to be expected anymore. + */ +void +v_dataReaderEntryDisposePublication( + v_dataReaderEntry _this, + const struct v_publicationInfo *info); + #endif /* V__DATAREADERENTRY_H */ diff --git a/src/kernel/code/v__dataReaderInstance.h b/src/kernel/code/v__dataReaderInstance.h index 99a43ee3e..a99002dc8 100644 --- a/src/kernel/code/v__dataReaderInstance.h +++ b/src/kernel/code/v__dataReaderInstance.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -119,6 +120,11 @@ v_dataReaderInstanceWrite ( v_dataReaderInstance _this, v_message message); +void +v_dataReaderInstanceTransferGroupOwnership( + v_dataReaderInstance _this, + struct v_owner *groupOwnership); + v_dataReaderResult v_dataReaderInstanceInsert( v_dataReaderInstance _this, diff --git a/src/kernel/code/v__dataReaderSample.h b/src/kernel/code/v__dataReaderSample.h index c730f3a29..b3efb27b4 100644 --- a/src/kernel/code/v__dataReaderSample.h +++ b/src/kernel/code/v__dataReaderSample.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/code/v__dataView.h b/src/kernel/code/v__dataView.h index 4338bc005..970e1f5d7 100644 --- a/src/kernel/code/v__dataView.h +++ b/src/kernel/code/v__dataView.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -33,25 +34,21 @@ extern "C" { #define v_dataViewReader(_this) \ v_dataReader(v_dataView(_this)->reader) -#define v_dataViewLock(_this) \ - v_observerLock(v_dataViewReader(_this)) - -#define v_dataViewUnlock(_this) \ - v_observerUnlock(v_dataViewReader(_this)) - /* The trigger-value stores a sample but needs access to the unreferenced * instance-pointer of the sample, which thus needs to be explicitly kept and * freed. * * This macro returns the parameter sample * - * @return sample */ + * @return sample + */ #define v_dataViewTriggerValueKeep(sample) \ (c_keep(v_readerSample(sample)->instance), \ c_keep(sample)) /* The sample stored in the trigger-value has its (otherwise unreferenced) - * instance-pointer explicitly kept, so it has to be freed. */ + * instance-pointer explicitly kept, so it has to be freed. + */ #define v_dataViewTriggerValueFree(triggerValue) \ { \ v_dataViewInstance instance; \ @@ -65,7 +62,7 @@ extern "C" { void v_dataViewDeinit( v_dataView _this); - + void v_dataViewFreeUnsafe( v_dataView _this); diff --git a/src/kernel/code/v__dataViewInstance.h b/src/kernel/code/v__dataViewInstance.h new file mode 100644 index 000000000..81908193e --- /dev/null +++ b/src/kernel/code/v__dataViewInstance.h @@ -0,0 +1,106 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#ifndef V__DATAVIEWINSTANCE_H +#define V__DATAVIEWINSTANCE_H + +/** \file kernel/code/v__dataViewInstance.h + * \brief This file defines the interface + * + */ + +#include "v_kernel.h" +#include "v_dataView.h" +#include "v__dataViewSample.h" +#include "os_if.h" +#include "v_query.h" +#include "v_dataReaderInstance.h" + +/** + * \brief The v_dataViewInstance cast method. + * + * This method casts an object to a v_dataViewInstance object. + * Before the cast is performed, if compiled with the NDEBUG flag not set, + * the type of the object is checked to be v_dataViewInstance or + * one of its subclasses. + */ +#define v_dataViewInstanceEmpty(_this) \ + (v_dataViewInstance(_this)->sampleCount == 0) + +typedef c_bool +(*v_dataViewInstanceAction)( + v_dataViewInstance _this, + c_voidp arg); + +v_dataViewInstance +v_dataViewInstanceNew( + v_dataView dataView, + v_dataViewSample sample); + +void +v_dataViewInstanceDeinit( + v_dataViewInstance _this); + +void +v_dataViewInstanceWipe( + v_dataViewInstance _this); + +void +v_dataViewInstanceWrite( + v_dataViewInstance instance, + v_dataViewSample sample, + v_dataViewSample position); + +void +v_dataViewInstanceRemove( + v_dataViewInstance _this); + +c_bool +v_dataViewInstanceReadSamples( + v_dataViewInstance _this, + c_query query, + v_state sampleMask, + v_readerSampleAction action, + c_voidp arg); + +c_bool +v_dataViewInstanceTakeSamples( + v_dataViewInstance _this, + c_query query, + v_state sampleMask, + v_readerSampleAction action, + c_voidp arg); + +c_bool +v_dataViewInstanceTest( + v_dataViewInstance _this, + c_query query, + v_state sampleMask, + v_queryAction action, + c_voidp args); + +v_actionResult +v_dataViewSampleReadTake( + v_dataViewSample sample, + v_readerSampleAction action, + c_voidp arg, + c_bool consume); + +#endif diff --git a/src/kernel/code/v__dataViewSample.h b/src/kernel/code/v__dataViewSample.h new file mode 100644 index 000000000..531ca2177 --- /dev/null +++ b/src/kernel/code/v__dataViewSample.h @@ -0,0 +1,65 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#ifndef V__DATAVIEWSAMPLE_H +#define V__DATAVIEWSAMPLE_H + +/** \file kernel/code/v__dataViewSample.h + * \brief This file defines the interface + * + */ + +#include "v_kernel.h" +#include "v_readerSample.h" +#include "os_if.h" + +#define v_dataViewSampleState(_this) \ + (v_readerSample(_this)->sampleState) + +#define v_dataViewSampleTestState(_this,mask) \ + v_stateTest(v_dataViewSampleState(_this),mask) + +#define v_dataViewSampleInstance(o) \ + ((v_dataViewInstance)(v_readerSampleInstance(v_readerSample(o)))) + +/** + * \brief The v_dataViewSampleList cast method. + * + * This method casts an object to a v_dataViewSampleList object. + * Before the cast is performed, if compiled with the NDEBUG flag not set, + * the type of the object is checked to be v_dataViewSampleList or + * one of its subclasses. + */ +#define v_dataViewSampleList(_this) (C_CAST(_this,v_dataViewSampleList)) + +v_dataViewSample +v_dataViewSampleNew ( + v_dataView dataView, + v_readerSample sample); + +void +v_dataViewSampleRemove( + v_dataViewSample _this); + +void +v_dataViewSampleListRemove( + v_dataViewSampleList _this); + +#endif diff --git a/src/kernel/code/v__deadLineInstance.h b/src/kernel/code/v__deadLineInstance.h index bc98cf6e3..0d528a305 100644 --- a/src/kernel/code/v__deadLineInstance.h +++ b/src/kernel/code/v__deadLineInstance.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/code/v__deadLineInstanceList.h b/src/kernel/code/v__deadLineInstanceList.h index 04a0cda28..3e07ff0b6 100644 --- a/src/kernel/code/v__deadLineInstanceList.h +++ b/src/kernel/code/v__deadLineInstanceList.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/code/v__deliveryGuard.h b/src/kernel/code/v__deliveryGuard.h index 567f281f8..e3e09fb2f 100644 --- a/src/kernel/code/v__deliveryGuard.h +++ b/src/kernel/code/v__deliveryGuard.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/code/v__deliveryService.h b/src/kernel/code/v__deliveryService.h index a21959952..aaa56d36c 100644 --- a/src/kernel/code/v__deliveryService.h +++ b/src/kernel/code/v__deliveryService.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -35,7 +36,6 @@ * The Delivery Service on the node of the DataWriter that has sent the message * will receive the delivery acknoledgement message and notify the DataWriter * that the sent message has been delivered. - * */ /** @@ -48,12 +48,6 @@ */ #define v_deliveryService(o) (C_CAST(o,v_deliveryService)) -#define v_deliveryServiceLock(_this) \ - v_observerLock(v_deliveryService(_this)) - -#define v_deliveryServiceUnLock(_this) \ - v_observerUnlock(v_deliveryService(_this)) - v_deliveryService v_deliveryServiceNew( v_subscriber subscriber, @@ -64,30 +58,13 @@ v_deliveryServiceFree( v_deliveryService _this); v_result -v_deliveryServiceEnable( - v_deliveryService _this); +v__deliveryServiceEnable( + _Inout_ v_deliveryService _this); void v_deliveryServiceDeinit( v_deliveryService _this); -/* the following v_deliveryServiceSubscribe and v_deliveryServiceUnSubscribe - * methods are defined by the v_reader interface and are required to - * establish connectivity to communication partitions. - */ -c_bool -v_deliveryServiceSubscribe( - v_deliveryService _this, - v_partition partition); - -c_bool -v_deliveryServiceUnSubscribe( - v_deliveryService _this, - v_partition partition); - -#define v_deliveryServiceAddEntry(_this,entry) \ - v_deliveryServiceEntry(v_readerAddEntry(v_reader(_this),v_entry(entry))) - /* The v_deliveryServiceRegister method is called by the spliced to pass received * builtin subscription messages. The Delivery Service will use this information * to update the 'connected synchronous DataReader' list of the synchronous diff --git a/src/kernel/code/v__deliveryWaitList.h b/src/kernel/code/v__deliveryWaitList.h index 0e170e67a..9470b9da9 100644 --- a/src/kernel/code/v__deliveryWaitList.h +++ b/src/kernel/code/v__deliveryWaitList.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/code/v__entity.h b/src/kernel/code/v__entity.h index e95f7c259..fed53bf49 100644 --- a/src/kernel/code/v__entity.h +++ b/src/kernel/code/v__entity.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -31,6 +32,14 @@ void v_entityFree ( v_entity _this); +c_bool +v__entityEnabled_nl ( + _In_ v_entity _this); + +c_bool +v__entityDisabled_nl ( + _In_ v_entity _this); + /** * The initialisation of an entity object. * This method initialises all attributes of the entity class and must @@ -39,11 +48,10 @@ v_entityFree ( * \param _this the reference to an entity object. * \param name the name of the entity. */ -v_result +void v_entityInit ( - v_entity _this, - const c_char *name, - c_bool enable); + _Inout_ v_entity _this, + _In_opt_z_ const c_char *name); /** * The de-initialisation of an entity object. @@ -58,7 +66,7 @@ v_entityDeinit ( c_ulong v_entityGetTriggerValue( - v_entity _this); + _In_ v_entity _this); #if defined (__cplusplus) } diff --git a/src/kernel/code/v__entry.h b/src/kernel/code/v__entry.h index 76c2f477e..c689ee062 100644 --- a/src/kernel/code/v__entry.h +++ b/src/kernel/code/v__entry.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -38,20 +39,6 @@ void v_entryFree ( v_entry _this); -/** - * Adds the group to the entry. Returns TRUE if the entry was not yet connected - * to the group and the group has thus been added. Returns FALSE otherwise. - * - * @param _this The entry to add the group to - * @param g The group to be added to the entry - * @return TRUE if the group was added, FALSE if the group was already - * in the entry - */ -c_bool -v_entryAddGroup ( - v_entry _this, - v_group g); - void v_entryRemoveGroup ( v_entry _this, @@ -62,13 +49,24 @@ v_entryGroupExists( v_entry entry, v_group group); -c_bool +v_alignState v_entryNotifyGroupStateChange( v_entry _this, - v_group g); + v_handle groupHandle, + v_alignState alignState); c_long v_entryDurableGroupCount( v_entry _this); +c_bool +v_entryWalkGroups( + v_entry _this, + c_action action, + c_voidp actionArg); + +c_iter +v_entryGetGroups( + v_entry _this); + #endif diff --git a/src/kernel/code/v__group.h b/src/kernel/code/v__group.h index ba11e7605..f3b0671eb 100644 --- a/src/kernel/code/v__group.h +++ b/src/kernel/code/v__group.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,10 +27,13 @@ extern "C" { #endif +#define v_groupGIDKey(_this) \ + (v_group(_this)->gidkey) + #define V_GROUP_NAME_TEMPLATE "Group<%s,%s>" #define v_groupKeyList(_this) \ - c_tableKeyList(v_group(_this)->instances) + v_group(_this)->keyList #define v_groupSampleCountIncrement(_this) \ v_group(_this)->resourceSampleCount++; @@ -45,11 +49,15 @@ struct v_groupFlushTransactionArg { v_transaction txn; }; +/* param 'id' is the sequence number of the group and is locally unique. + * param 'gidkey' specifies the storage spectrum is defined by topic key or instance gid key. + */ v_group v_groupNew ( v_partition partition, v_topic topic, - c_long id); + c_long id, + c_bool gidkey); void v_groupDeinit ( @@ -97,7 +105,7 @@ v_groupCreateInvalidMessage( os_timeW timestamp); void -v_groupNotifyGroupCoherentPublication( +v_groupNotifyCoherentPublication( v_group _this, v_message msg); @@ -151,10 +159,6 @@ os_boolean v_groupIsDurable( v_group _this); -v_transactionAdmin -v__groupGetTransactionAdmin( - v_group _this); - c_bool v_groupIsOnRequest( v_group _this); @@ -168,6 +172,30 @@ v_groupNotifyWriter( v_group _this, v_writer w); +v_result +v_groupSetFilter( + v_group _this, + q_expr condition, + const c_value params[], + os_uint32 nrOfParams); + +_Requires_lock_held_(g->mutex) +v_alignState +v__groupCompleteGet_nl( + _In_ v_group g); + +void +v_groupGetOpenTransactions( + v_group g, + v_entry e, + c_bool groupAdmin); + +void +v_groupInsertTransactionMessage( + v_group _this, + v_message msg, + v_groupInstance instance); + #if defined (__cplusplus) } #endif diff --git a/src/kernel/code/v__groupInstance.h b/src/kernel/code/v__groupInstance.h index 1e4cb9cce..1c2e5a9a2 100644 --- a/src/kernel/code/v__groupInstance.h +++ b/src/kernel/code/v__groupInstance.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,6 +25,7 @@ #include "v_kernel.h" #include "v_writerInstance.h" #include "v_state.h" +#include "v__policy.h" #include "v__group.h" #include "v_groupInstance.h" @@ -114,11 +116,14 @@ v_groupInstanceUnregister ( v_writeResult v_groupInstanceInsert ( + v_groupInstance _this, + v_message message); + +v_writeResult +v_groupInstanceFlushTransaction ( v_groupInstance _this, v_message message, - c_bool isTransactionFlush, - v_transaction transaction, - c_bool stream); + v_transaction transaction); void v_groupInstanceRemove ( @@ -195,4 +200,9 @@ void v_groupInstanceReleaseResource( v_groupInstance _this); +v_ownershipResult +v_groupInstanceTestOwnership( + v_groupInstance instance, + v_message message); + #endif diff --git a/src/kernel/code/v__groupQueue.h b/src/kernel/code/v__groupQueue.h index 446c10a34..d6215d137 100644 --- a/src/kernel/code/v__groupQueue.h +++ b/src/kernel/code/v__groupQueue.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,6 +22,7 @@ #ifndef V__GROUPQUEUE_H #define V__GROUPQUEUE_H +#include "v_kernel.h" #include "v_groupQueue.h" #include "kernelModuleI.h" @@ -47,6 +49,10 @@ void v_groupQueueDeinit ( v_groupQueue _this); +v_result +v_groupQueueEnable( + _Inout_ v_groupQueue _this); + #if defined (__cplusplus) } #endif diff --git a/src/kernel/code/v__groupStore.h b/src/kernel/code/v__groupStore.h new file mode 100644 index 000000000..0c271bcf4 --- /dev/null +++ b/src/kernel/code/v__groupStore.h @@ -0,0 +1,121 @@ +/* + * OpenSplice DDS + * + * This software and documentation are Copyright 2006 to TO_YEAR PrismTech + * Limited, its affiliated companies and licensors. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#ifndef V__GROUPSTORE_H +#define V__GROUPSTORE_H + +#include "v_group.h" +#include "v_groupStore.h" + +#if defined (__cplusplus) +extern "C" { +#endif + +v_groupStore +v_groupStoreNew( + const v_group group, + const c_char *keyExpr, + const c_array messageKeyList); + +void +v_groupStoreDeinit( + const v_groupStore _this); + +void +v_groupStoreDelete( + const v_groupStore _this, + const v_groupInstance instance); + +void +v_groupStoreDispose( + const v_groupStore _this, + const v_groupInstance instance); + +void +v_groupStoreWalk( + const v_groupStore _this, + const c_action action, + const c_voidp arg); + +c_iter +v_groupStoreSelect( + const v_groupStore _this, + const os_uint32 max); + +/** + * \brief Set the specified flags in the instanceStates + * of all dataReader instances associated with the specified group. + * + * \param group The group for which all instanceStates of all DataReaders must set the flags. + * \param flags The flags to set for all instanceStates of the DataReaders. + * + * \remark The function is thread-safe. During the execution of the function access + * to the group is locked. + */ +void +v_groupStoreMarkGroupInstanceStates ( + const v_groupStore _this, + c_ulong flags); + +/** + * \brief Reset the specified flags in the instanceStates + * of all dataReader instances associated with the specified group. + * + * \param group The group for which all instanceStates of all DataReaders must reset the flags. + * \param flags The flags to reset for all instanceStates of the DataReaders. + * + * \remark The function is thread-safe. During the execution of the function access + * to the group is locked. + */ +void +v_groupStoreUnmarkGroupInstanceStates ( + const v_groupStore _this, + c_ulong flags); + +c_array +v_groupStoreKeyList( + const v_groupStore _this); + +c_query +v_groupStore_create_query( + const v_groupStore _this, + const q_expr progExpr, + const c_value *params); + +v_groupInstance +v_groupStoreLookupInstance( + const v_groupStore _this, + const v_message msg); + +/** + * \brief Lookup or create an instance for the message key value. + * + * \param _this The group store which shall hold a matching instance after this operation. + * \param msg The message providing the key value of the desired instance. + */ +v_groupInstance +v_groupStoreCreateInstance( + const v_groupStore _this, + const v_message msg); + +#if defined (__cplusplus) +} +#endif + +#endif diff --git a/src/kernel/code/v__groupStream.h b/src/kernel/code/v__groupStream.h index d0653154e..b07fd0289 100644 --- a/src/kernel/code/v__groupStream.h +++ b/src/kernel/code/v__groupStream.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,6 +30,10 @@ extern "C" { #endif +v_result +v_groupStreamEnable( + _Inout_ v_groupStream _this); + void v_groupStreamConnectNewGroups ( v_groupStream _this, @@ -43,26 +48,21 @@ v_groupStreamWrite ( v_groupStream _this, v_groupAction action); -c_bool -v_groupStreamSubscribe ( - v_groupStream _this, - v_partition partition); - c_bool v_groupStreamUnSubscribe ( v_groupStream _this, v_partition partition); - + c_bool v_groupStreamSubscribeGroup ( - v_groupStream _this, + v_groupStream _this, v_group group); - + c_bool v_groupStreamUnSubscribeGroup ( - v_groupStream _this, + v_groupStream _this, v_group group); - + #if defined (__cplusplus) } #endif diff --git a/src/kernel/code/v__index.h b/src/kernel/code/v__index.h index 4d7f8b52a..566b7a2ee 100644 --- a/src/kernel/code/v__index.h +++ b/src/kernel/code/v__index.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -40,5 +41,5 @@ v_indexInit( c_type instanceType, c_array sourceKeyList, v_reader reader); - + #endif diff --git a/src/kernel/code/v__kernel.h b/src/kernel/code/v__kernel.h index 43d3f8ba9..2ace360dd 100644 --- a/src/kernel/code/v__kernel.h +++ b/src/kernel/code/v__kernel.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,6 +25,12 @@ #include "os_if.h" +#if 0 +#define TRACE_IGNORE printf("## TRACE(Ignore) : "); printf +#else +#define TRACE_IGNORE(...) +#endif + #ifdef OSPL_BUILD_CORE #define OS_API OS_API_EXPORT #else @@ -43,7 +50,7 @@ v_kernelGroupTransactionFlush( v_transactionAdmin admin); c_bool -v_kernelGroupTransactionLockAccess( +v_kernelGroupTransactionTryLockAccess( v_kernel _this); void @@ -51,32 +58,19 @@ v_kernelGroupTransactionUnlockAccess( v_kernel _this); void -v_kernelNotifyGroupCoherentPublication( +v_kernelNotifyCoherentPublication( v_kernel _this, v_message msg); -void -v_lockShares ( - v_kernel _this); - -void -v_unlockShares ( - v_kernel _this); - -v_entity -v_addShareUnsafe ( - v_kernel _this, - v_entity e); - -v_entity -v_removeShareUnsafe ( +v_subscriber +v_kernelAddSharedSubscriber ( v_kernel _this, - v_entity e); + v_subscriber subscriber); -c_iter -v_resolveShare ( +c_ulong +v_kernelRemoveSharedSubscriber ( v_kernel _this, - const c_char *name); + v_subscriber subscriber); void v_checkMaxSamplesPerInstanceWarningLevel( @@ -170,4 +164,36 @@ v_rxoDataCompatible( v_rxoData offered, v_rxoData requested); +/* connect group to all matching readers */ +void +v_kernelConnectGroup( + v_kernel _this, + v_group g); + +/* This operation will update the kernel according to a newly discovered publication and + * notify matching local subscriptions (synchronously). + * The given message holds the builtin publication data describing the discovered writer. + */ +void +v_kernelNotifyPublication( + v_kernel _this, + v_message msg); + +/* This operation will update the kernel according to a newly discovered subscription and + * notify matching local publications (synchronously). + * The given message holds the builtin subscription data describing the discovered reader. + */ +void +v_kernelNotifySubscription( + v_kernel _this, + v_message msg); + +/* This operation will lookup the publication message identified by the given gid. + * If found the message will be returned and must be freed after use. + */ +v_message +v_kernelLookupPublication( + v_kernel _this, + v_gid gid); + #endif /* V__KERNEL_H */ diff --git a/src/kernel/code/v__lease.h b/src/kernel/code/v__lease.h index e03c4246a..cf836308c 100644 --- a/src/kernel/code/v__lease.h +++ b/src/kernel/code/v__lease.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/code/v__leaseManager.h b/src/kernel/code/v__leaseManager.h index 0776e08b9..07b8484e4 100644 --- a/src/kernel/code/v__leaseManager.h +++ b/src/kernel/code/v__leaseManager.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/code/v__leaseTime.h b/src/kernel/code/v__leaseTime.h index 48ac69398..a280b6f67 100644 --- a/src/kernel/code/v__leaseTime.h +++ b/src/kernel/code/v__leaseTime.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/code/v__lifespanAdmin.h b/src/kernel/code/v__lifespanAdmin.h index 60b63dca7..5ec163eb4 100644 --- a/src/kernel/code/v__lifespanAdmin.h +++ b/src/kernel/code/v__lifespanAdmin.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/code/v__listener.h b/src/kernel/code/v__listener.h index de17b4232..0a0bbe6d7 100644 --- a/src/kernel/code/v__listener.h +++ b/src/kernel/code/v__listener.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,12 +24,6 @@ #include "v_listener.h" -#define v_listenerLock(_this) \ - v_observerLock(v_observer(_this)) - -#define v_listenerUnlock(_this) \ - v_observerUnlock(v_observer(_this)) - /** * Releases all resources claimed by the referenced listener object. * diff --git a/src/kernel/code/v__nameSpace.h b/src/kernel/code/v__nameSpace.h new file mode 100644 index 000000000..d0b16fa30 --- /dev/null +++ b/src/kernel/code/v__nameSpace.h @@ -0,0 +1,53 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#ifndef __V__NAMESPACE_H__ +#define __V__NAMESPACE_H__ + +#include "c_typebase.h" +#include "c_iterator.h" +#include "v_kernel.h" + +struct v_nameSpacePartitionTopic { + char *partition; + char *topic; +}; + +struct v_nameSpace { + char *name; + c_iter partitionTopics; + /* policy */ +}; + +c_iter /* v_nameSpace */ +v__nameSpaceCollect ( + v_kernel kernel); + +c_bool +v__nameSpaceIsIn ( + struct v_nameSpace *ns, + char *partition, + char *topic); + +void +v__nameSpaceFree ( + struct v_nameSpace *ns); + +#endif /* __V__NAMESPACE_H__ */ diff --git a/src/kernel/code/v__networkQueue.h b/src/kernel/code/v__networkQueue.h index 33ae21f54..2a75a8da4 100644 --- a/src/kernel/code/v__networkQueue.h +++ b/src/kernel/code/v__networkQueue.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/code/v__networkReader.h b/src/kernel/code/v__networkReader.h index 5d7a792ff..53d7bbe6b 100644 --- a/src/kernel/code/v__networkReader.h +++ b/src/kernel/code/v__networkReader.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,19 +28,6 @@ /* ----------------------------- v_networkReader ----------------------- */ -/* Protected methods to be used by v_reader only */ - -c_bool -v_networkReaderSubscribeGroup( - v_networkReader _this, - v_group group); - -c_bool -v_networkReaderUnSubscribeGroup( - v_networkReader _this, - v_group group); - - /* Protected methods to be used by v_networkReaderEntry only */ c_bool diff --git a/src/kernel/code/v__objectLoan.h b/src/kernel/code/v__objectLoan.h index a7854cc00..584a63dcb 100644 --- a/src/kernel/code/v__objectLoan.h +++ b/src/kernel/code/v__objectLoan.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/code/v__observable.h b/src/kernel/code/v__observable.h index b2d9b54ea..1f2683be6 100644 --- a/src/kernel/code/v__observable.h +++ b/src/kernel/code/v__observable.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,7 +26,35 @@ extern "C" { #endif +#include "v_kernel.h" +#include "v_event.h" +#include "os_if.h" #include "v_observable.h" +#include "v_observer.h" + +#define OSPL_LOCK(_this) \ + v_observableLock(v_observable(_this)) +#define OSPL_UNLOCK(_this) \ + v_observableUnlock(v_observable(_this)) + +#define OSPL_ASSERT_LOCK(_this) + +#define OSPL_ADD_OBSERVER(_this,o,mask,userdata) \ + v_observableAddObserver(v_observable(_this), v_observer(o), mask, userdata) +#define OSPL_REMOVE_OBSERVER(_this,o,mask,userdata) \ + v_observableRemoveObserver(v_observable(_this), v_observer(o), mask, userdata) + +#define OSPL_THROW_EVENT(_this,e) \ + v_observableNotify(v_observable(_this), e); + +#define v_observableHasObservers(_this) \ + (v_observable(_this)->observers != NULL) + +/* Following macros are private for v_observer and v_observable */ +#define OSPL_BLOCK_EVENTS(_this) \ + v_observableBlock(v_observable(_this)) +#define OSPL_UNBLOCK_EVENTS(_this) \ + v_observableUnblock(v_observable(_this)) void v_observableFree ( @@ -54,8 +83,62 @@ void v_observableDeinit ( v_observable _this); -#define v_observableHasObservers(_this) \ - (v_observable(_this)->observers != NULL) +/** + * Notifies all observers of the observable. + * + * \param _this the reference to an observable object. + * \param event the event describes the reason of notification and + * is passed to the observers. + */ +void +v_observableNotify( + v_observable _this, + v_event event); + +/** + * Add an observer to the observable. + * By adding an observer to the observable, the observer is notified on + * state changes of the observable. With this notification the given + * userData is also sent. + * + * \param _this the reference to an observable object. + * \param observer the reference to the observer object to add. + * \param mask this mask specifies the events of interest, these events will now trigger the observer. + * \param userData this data also sent when notify the given observer. + * \return TRUE if the observer is added, otherwise FALSE. + */ +#if 0 /* TODO temporary declared public in v_observable.h until dependency in cmx API is removed. */ +c_bool +v_observableAddObserver( + v_observable _this, + v_observer observer, + v_eventMask mask, + c_voidp userData); +#endif + +/** + * Removes an observer from the observable. + * By removing an observer from the observable, the observer is no longer + * notified on state changes of the observable. + * + * \param _this the reference to an observable object. + * \param observer the reference to the observer object to remove. + * \param mask this mask specifies the events of no interest, these events will no + * longer trigger the observer. + * \param userData the reference to the userdata belonging to the proxy of the observer object to remove. + * \return TRUE if the observer is removed, otherwise FALSE. + */ +c_bool +v_observableRemoveObserver ( + v_observable _this, + v_observer observer, + v_eventMask mask, + void** userData); + +void v_observableLock(v_observable o); +void v_observableUnlock(v_observable o); +void v_observableBlock(v_observable o); +void v_observableUnblock(v_observable o); #if defined (__cplusplus) } diff --git a/src/kernel/code/v__observer.h b/src/kernel/code/v__observer.h index c69842010..66c74aa2c 100644 --- a/src/kernel/code/v__observer.h +++ b/src/kernel/code/v__observer.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,11 +28,23 @@ extern "C" { #include "v_observer.h" -#define v__observerClearEventFlags(_this) \ - (v_observer(_this)->eventFlags = 0) +#define OSPL_TRIGGER_EVENT(_this,e, userdata) \ + v_observerNotify(v_observer(_this), e, userdata); +#define OSPL_CATCH_EVENT(_this, timeout) \ + v_observerTimedWait(v_observer(_this), timeout) +#define OSPL_CATCH_EVENT_ACTION(_this, timeout, action, arg) \ + v_observerTimedWaitAction(v_observer(_this), timeout, action, arg) +#define OSPL_CLEAR_EVENT_FLAGS(_this) \ + v_observerClearEventFlags(v_observer(_this)) -#define v_observerEventMask(_this) \ - (v_observer(_this)->eventMask) +#define OSPL_SET_EVENT_MASK(_this,mask) \ + v_observerSetEventMask(v_observer(_this),mask) +#define OSPL_ADD_EVENT_MASK(_this,mask) \ + v_observerSetEvent(v_observer(_this),mask) +#define OSPL_CLEAR_EVENT_MASK(_this,mask) \ + v_observerClearEvent(v_observer(_this),mask) +#define OSPL_GET_EVENT_MASK(_this) \ + v_observerGetEventMask(v_observer(_this)) /** * The initialisation of an observer object. @@ -43,7 +56,7 @@ extern "C" { */ void v_observerInit ( - v_observer _this); + _Inout_ v_observer _this); /** * The de-initialisation of an observer object. @@ -60,28 +73,8 @@ void v_observerFree ( v_observer _this); -/** - * Retrieves and stores event data in the observer in one transaction. - * - * Retrieves and stores event data in the observer in a thread-safe manner. - * It must be thread-safe, since the data can be used to determine whether - * the observer must be triggered or not. - * - * \param _this the reference to an observer object. - * \param eventData the event data to store in the observer. - * \return the overwritten event data in the observer. - */ -c_voidp -v_observerSetEventData( - v_observer _this, - c_voidp eventData); - -c_ulong -v__observerWait( - v_observer _this); - c_ulong -v__observerTimedWait( +v_observerTimedWait( v_observer _this, const os_duration time); @@ -90,7 +83,7 @@ v_observerGetEventFlags( v_observer _this); c_ulong -v__observerSetEvent( +v_observerSetEvent( v_observer _this, c_ulong event); diff --git a/src/kernel/code/v__orderedInstance.h b/src/kernel/code/v__orderedInstance.h index 3e911c0d1..e00b531d4 100644 --- a/src/kernel/code/v__orderedInstance.h +++ b/src/kernel/code/v__orderedInstance.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,7 +23,7 @@ #include "kernelModule.h" #include "v_dataReader.h" -#include "v_dataViewSample.h" +#include "v__dataViewSample.h" #if defined (__cplusplus) extern "C" { @@ -72,25 +73,20 @@ v_orderedInstanceReadSample ( v_orderedInstance _this, v_sampleMask mask); -#if 0 -OS_API void -v_orderedInstanceUnreadSample ( - v_orderedInstance _this, - v_dataReaderSample sample); -#endif - /* If presentation access scope is set to group, the read/take operations must - be aligned to the list of data readers returned by get_datareaders. In case - an unauthorized read/take is registered the list is invalidated and the - read/take operation should fallback to unordered mode. */ + * be aligned to the list of data readers returned by get_datareaders. In case + * an unauthorized read/take is registered the list is invalidated and the + * read/take operation should fallback to unordered mode. + */ OS_API c_bool v_orderedInstanceIsAligned ( v_orderedInstance _this); /* If a reader reads a sample that does not belong to itself, it must - invalidate the list returned by get_datareaders by invoking this function. - This will effectively mark the ordered instance unaligned and reset the - bookmark. */ + * invalidate the list returned by get_datareaders by invoking this function. + * This will effectively mark the ordered instance unaligned and reset the + * bookmark. + */ OS_API void v_orderedInstanceUnaligned ( v_orderedInstance _this); diff --git a/src/kernel/code/v__participant.h b/src/kernel/code/v__participant.h index aea46a3f5..3859df55e 100644 --- a/src/kernel/code/v__participant.h +++ b/src/kernel/code/v__participant.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -78,6 +79,39 @@ v_participantNotifyGroupCoherentPublication( v_participant _this, v_message msg); +void +v_participantConnectGroup ( + v_participant _this, + v_group g); + +/* This operation will update the participant according to a newly discovered publication and + * notify matching local subscriptions (synchronously). + * The given message holds the builtin publication data describing the discovered writer. + * This operation will lock the participant and contained subscribers and contained DataReaders. + */ +void +v_participantNotifyPublication( + v_participant _this, + v_message msg); + +/* This operation will update the participant according to a newly discovered subscription and + * notify matching local publications (synchronously). + * The given message holds the builtin subscription data describing the discovered reader. + * This operation will lock the participant and contained publishers and contained DataWriters. + */ +void +v_participantNotifySubscription( + v_participant _this, + v_message msg); + +/* This operation will return TRUE if the writer identified given publication info is ignored by + * this participant. + */ +os_boolean +v_participantCheckPublicationIgnored( + v_participant _this, + const struct v_publicationInfo *info); + #if defined (__cplusplus) } #endif diff --git a/src/kernel/code/v__participantQos.h b/src/kernel/code/v__participantQos.h index e4148ad90..78287f119 100644 --- a/src/kernel/code/v__participantQos.h +++ b/src/kernel/code/v__participantQos.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/code/v__partition.h b/src/kernel/code/v__partition.h index 52c9c4044..5469d5828 100644 --- a/src/kernel/code/v__partition.h +++ b/src/kernel/code/v__partition.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/code/v__partitionAdmin.h b/src/kernel/code/v__partitionAdmin.h index db928be9e..532b80f23 100644 --- a/src/kernel/code/v__partitionAdmin.h +++ b/src/kernel/code/v__partitionAdmin.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -38,33 +39,23 @@ void v_partitionAdminFree( v_partitionAdmin _this); -c_bool -v_partitionAdminFitsInterest( - v_partitionAdmin _this, - v_partition d); - -c_iter -v_partitionAdminAdd( +void +v_partitionAdminFill( v_partitionAdmin _this, const c_char *partitionExpr); -c_iter -v_partitionAdminRemove( +c_bool +v_partitionAdminAdd( v_partitionAdmin _this, - const c_char *partitionExpr); + v_partition d); c_bool -v_partitionAdminSet( +v_partitionAdminUpdate( v_partitionAdmin _this, v_partitionPolicyI partitionExpressions, c_iter *addedPartitions, c_iter *removedPartitions); -c_bool -v_partitionAdminExists( - v_partitionAdmin _this, - const c_char *partitionName); - c_iter v_partitionAdminLookup( v_partitionAdmin _this, diff --git a/src/kernel/code/v__policy.h b/src/kernel/code/v__policy.h index 0ab7189b3..79d38e698 100644 --- a/src/kernel/code/v__policy.h +++ b/src/kernel/code/v__policy.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -56,7 +57,7 @@ v_ownershipResult v_determineOwnershipByStrength ( struct v_owner *owner, const struct v_owner *candidate, - c_bool claim); /* Workaround for dds1784, see v_policy.c for details. */ + v_state messageState); #if defined (__cplusplus) } diff --git a/src/kernel/code/v__processInfo.h b/src/kernel/code/v__processInfo.h index 136c24247..155b4083b 100644 --- a/src/kernel/code/v__processInfo.h +++ b/src/kernel/code/v__processInfo.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/code/v__publisher.h b/src/kernel/code/v__publisher.h index 079c7b4b6..505eb1fb9 100644 --- a/src/kernel/code/v__publisher.h +++ b/src/kernel/code/v__publisher.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -43,7 +44,7 @@ v_publisherConnectNewGroup( v_group g); c_bool -v__publisherCoherentTransactionSingleNoLock( +v_publisherStartTransaction( v_publisher p, c_ulong *publisherId, c_ulong *transactionId); diff --git a/src/kernel/code/v__publisherQos.h b/src/kernel/code/v__publisherQos.h index c22740f5b..9236114b8 100644 --- a/src/kernel/code/v__publisherQos.h +++ b/src/kernel/code/v__publisherQos.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/code/v__query.h b/src/kernel/code/v__query.h index 77d39c158..a65aa85e7 100644 --- a/src/kernel/code/v__query.h +++ b/src/kernel/code/v__query.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -34,12 +35,6 @@ q_expr v_queryGetPredicate( v_query _this); -void -v_queryNotify ( - v_query _this, - v_event event, - c_voidp userData); - c_bool v_queryNotifyDataAvailable ( v_query _this, diff --git a/src/kernel/code/v__reader.h b/src/kernel/code/v__reader.h index d3fa22127..af121f91a 100644 --- a/src/kernel/code/v__reader.h +++ b/src/kernel/code/v__reader.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,29 +24,23 @@ #include "v_reader.h" #include "v_entity.h" +#include "v__subscriberQos.h" -#define v_readerEntrySetLock(_this) \ - c_mutexLock(&_this->entrySet.mutex) - -#define v_readerEntrySetUnlock(_this) \ - c_mutexUnlock(&_this->entrySet.mutex) - -#define v__readerIsGroupCoherent(reader_) \ - ((reader_->subQos->presentation.v.access_scope == V_PRESENTATION_GROUP) && \ - (reader_->subQos->presentation.v.coherent_access)) - +#define v__readerIsGroupCoherent(reader_) v_subscriberQosIsGroupCoherent((reader_)->subQos) #define v__readerIsGroupOrderedNonCoherent(reader_) \ ((reader_->subQos->presentation.v.access_scope == V_PRESENTATION_GROUP) && \ (reader_->subQos->presentation.v.coherent_access == FALSE) && \ (reader_->subQos->presentation.v.ordered_access == TRUE)) +#define v_readerAccessScope(_this) \ + v_reader(_this)->subQos->presentation.v.access_scope + void v_readerInit( - v_reader _this, - const c_char *name, - v_subscriber s, - v_readerQos qos, - c_bool enable); + _Inout_ v_reader _this, + _In_z_ const c_char *name, + _In_ v_subscriber s, + _In_ v_readerQos qos); void v_readerDeinit( @@ -55,38 +50,35 @@ void v_readerFree( v_reader _this); -v_result -v_readerSubscribe( - v_reader _this, - v_partition d); +void +v_readerAddEntry( + _Inout_ v_reader _this, + _In_ v_entry e); + +void +v_readerAddTransactionAdmin( + _Inout_ v_reader r, + _In_opt_ v_transactionGroupAdmin a); -c_bool -v_readerUnSubscribe( +void +v__readerNotifyStateChange_nl( v_reader _this, - v_partition d); + c_bool complete); -v_result -v_readerGetHistoricalData( +v_topic +v_readerGetTopic( v_reader _this); -c_bool -v_readerSubscribeGroup ( - v_reader _this, - v_group group); - -c_bool -v_readerUnSubscribeGroup ( - v_reader _this, - v_group g); +v_topic +v_readerGetTopic_nl( + v_reader _this); -v_entry -v_readerAddEntry( - v_reader _this, - v_entry e); +void +v_readerPublishBuiltinInfo( + v_reader _this); -v_entry -v_readerRemoveEntry( - v_reader _this, - v_entry e); +v_subscriber +v_readerGetSubscriber( + v_reader _this); #endif diff --git a/src/kernel/code/v__readerQos.h b/src/kernel/code/v__readerQos.h index eb76c5142..9a5beace3 100644 --- a/src/kernel/code/v__readerQos.h +++ b/src/kernel/code/v__readerQos.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,12 +28,14 @@ extern "C" { #endif +_Success_(return == V_RESULT_OK) v_result v_readerQosCompare( - v_readerQos _this, - v_readerQos tmpl, - c_bool enabled, - v_qosChangeMask *changeMask); + _In_ v_readerQos q, + _In_ v_readerQos tmpl, + _In_ c_bool enabled, + _In_ c_bool groupCoherent, + _Out_ v_qosChangeMask *changeMask); #if defined (__cplusplus) } diff --git a/src/kernel/code/v__service.h b/src/kernel/code/v__service.h index eee426eff..d9a0afe66 100644 --- a/src/kernel/code/v__service.h +++ b/src/kernel/code/v__service.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -30,4 +31,8 @@ v_serviceNotify( v_event event, c_voidp userData); +v_serviceStateKind +v_serviceGetState( + v_service _this); + #endif /* V__SERVICE_H */ diff --git a/src/kernel/code/v__serviceManager.h b/src/kernel/code/v__serviceManager.h index a41bc2366..abda9574d 100644 --- a/src/kernel/code/v__serviceManager.h +++ b/src/kernel/code/v__serviceManager.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -34,12 +35,6 @@ #endif /* !!!!!!!!NOTE From here no more includes are allowed!!!!!!! */ -void -v_serviceManagerNotify( - v_serviceManager _this, - v_event event, - c_voidp userData); - v_serviceState v_serviceManagerRegister( v_serviceManager _this, diff --git a/src/kernel/code/v__serviceState.h b/src/kernel/code/v__serviceState.h index 2506ff29c..3bc18c11a 100644 --- a/src/kernel/code/v__serviceState.h +++ b/src/kernel/code/v__serviceState.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/code/v__spliced.h b/src/kernel/code/v__spliced.h index 5af8b31b0..86ddca719 100644 --- a/src/kernel/code/v__spliced.h +++ b/src/kernel/code/v__spliced.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,15 +28,15 @@ extern "C" { #include "v_spliced.h" +_Check_return_ +_Ret_notnull_ v_spliced v_splicedNew ( - v_kernel kernel, - c_bool enable); + _In_ v_kernel kernel); void v_splicedInit ( - v_spliced _this, - c_bool enable); + _Inout_ v_spliced _this); void v_splicedDeinit ( @@ -49,21 +50,27 @@ void v_splicedCheckHeartbeats ( v_spliced _this); -c_bool -v_splicedPublicationMatchCount( - v_spliced _this, - v_object scope, - v_gid wgid, - c_ulong *count); - -typedef v_result (*publicationInfoAction)(struct v_publicationInfo *, void *arg); +/* This operation visits all discovered subscription info messages. + * The given action function is called upon each subscription message. + * the action signature : os_boolean (*action) (const v_message subscription, void *arg) + * This message shall be renamed to v_kernelWalkSubscriptions when the admin moves to the kernel. + */ +v_result +v_splicedWalkSubscriptions( + v_spliced spliced, + v_subscription_action action, + c_voidp arg); +/* This operation visits all discovered publications info messages. + * The given action function is called upon each publication message. + * the action signature : os_boolean (*action) (const v_message publication, void *arg) + * This message shall be renamed to v_kernelWalkPublications when the admin moves to the kernel. + */ v_result -v_splicedLookupPublicationInfo( - v_spliced _this, - v_gid wgid, - publicationInfoAction action, - void *arg); +v_splicedWalkPublications( + v_spliced spliced, + v_publication_action action, + c_voidp arg); #if defined (__cplusplus) } diff --git a/src/kernel/code/v__statCat.h b/src/kernel/code/v__statCat.h index b89cc26ee..7e06710d7 100644 --- a/src/kernel/code/v__statCat.h +++ b/src/kernel/code/v__statCat.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/code/v__statistics.h b/src/kernel/code/v__statistics.h index 640cc7ff1..809de1738 100644 --- a/src/kernel/code/v__statistics.h +++ b/src/kernel/code/v__statistics.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/code/v__status.h b/src/kernel/code/v__status.h index e7c952fa4..36f319ca2 100644 --- a/src/kernel/code/v__status.h +++ b/src/kernel/code/v__status.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/code/v__subscriber.h b/src/kernel/code/v__subscriber.h index d6954ab70..18fb1165f 100644 --- a/src/kernel/code/v__subscriber.h +++ b/src/kernel/code/v__subscriber.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -36,16 +37,14 @@ extern "C" { #define v_subscriberPartitionCount(_this) v_partitionAdminCount(v_subscriber(_this)->partitions) -#define v_subscriberLock(_this) \ - c_mutexLock(&_this->mutex) - -#define v_subscriberUnlock(_this) \ - c_mutexUnlock(&_this->mutex) +v_result +v__subscriberEnable( + _Inout_ v_subscriber _this); void v_subscriberWalkReaders( v_subscriber _this, - c_bool (*action)(v_reader reader, c_voidp arg), + c_action action, c_voidp arg); void @@ -58,70 +57,30 @@ v_subscriberConnectNewGroup( v_subscriber s, v_group g); -v_reader -v_subscriberRemoveShareUnsafe( - v_subscriber _this, - v_reader reader); - -v_reader -v_subscriberAddShareUnsafe( - v_subscriber _this, - v_reader r); +v_dataReader +v_subscriberAddShare( + _Inout_ v_subscriber _this, + _In_ v_dataReader reader); -v_reader -v_subscriberRemoveShareUnsafe( +c_ulong +v_subscriberRemoveShare( v_subscriber _this, - v_reader r); - -void -v_subscriberLockShares( - v_subscriber _this); - -void -v_subscriberUnlockShares( - v_subscriber _this); - -/* This operation will return the subscriber's transactionGroup admin. - * It will lazy create a new admin in case it didn't exist already. - */ -v_transactionGroupAdmin -v_subscriberLookupTransactionGroupAdmin( - v_subscriber _this); - -c_bool -v__subscriberRequireAccessLockCoherent( - v_subscriber _this); - -c_bool -v__subscriberRequireAccessLockOrdered( - v_subscriber _this); - -v_result -v_subscriberTestBeginAccess( - v_subscriber _this); + v_dataReader reader); void -v_subscriberLockAccess( - v_subscriber _this); - -c_bool -v_subscriberTryLockAccess( +v_subscriberGroupTransactionFlush( v_subscriber _this); -void -v_subscriberUnlockAccess( - v_subscriber _this); - -void -v_subscriberTriggerGroupCoherent( - v_subscriber _this, - v_reader owner); - void v_subscriberNotifyGroupCoherentPublication( v_subscriber _this, v_message msg); +void +v_subscriberNotify( + v_subscriber _this, + v_event event, + c_voidp userData); #if defined (__cplusplus) } #endif diff --git a/src/kernel/code/v__subscriberQos.h b/src/kernel/code/v__subscriberQos.h index 7aae50e7e..8ce7c7e96 100644 --- a/src/kernel/code/v__subscriberQos.h +++ b/src/kernel/code/v__subscriberQos.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -28,12 +29,17 @@ extern "C" { #include "v_qos.h" #include "v_subscriberQos.h" +_Success_(return == V_RESULT_OK) v_result v_subscriberQosCompare( - v_subscriberQos _this, - v_subscriberQos tmpl, - c_bool enable, - v_qosChangeMask *changeMask); + _In_ v_subscriberQos _this, + _In_ v_subscriberQos tmpl, + _In_ c_bool enable, + _Out_ v_qosChangeMask *changeMask); + +c_bool +v_subscriberQosIsGroupCoherent ( + _In_ _Const_ v_subscriberQos _this); #if defined (__cplusplus) } diff --git a/src/kernel/code/v__threadInfo.h b/src/kernel/code/v__threadInfo.h index e4b21096d..78eb2a5d9 100644 --- a/src/kernel/code/v__threadInfo.h +++ b/src/kernel/code/v__threadInfo.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/code/v__topic.h b/src/kernel/code/v__topic.h index a0f5849fb..9fa7184c1 100644 --- a/src/kernel/code/v__topic.h +++ b/src/kernel/code/v__topic.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -35,6 +36,9 @@ extern "C" { #endif /* !!!!!!!!NOTE From here no more includes are allowed!!!!!!! */ +OS_API v_result +v__topicEnable( + _Inout_ v_topic _this); OS_API void v_topicDeinit( @@ -44,15 +48,6 @@ OS_API c_type v_topicKeyType( v_topic _this); -/** - * for every notify method the observer lock must be locked! - */ -OS_API void -v_topicNotify ( - v_topic _this, - v_event event, - c_voidp userData); - OS_API void v_topicNotifyInconsistentTopic ( v_topic _this); diff --git a/src/kernel/code/v__topicAdapter.h b/src/kernel/code/v__topicAdapter.h index 5202740fd..2c1f7709d 100644 --- a/src/kernel/code/v__topicAdapter.h +++ b/src/kernel/code/v__topicAdapter.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/code/v__topicImpl.h b/src/kernel/code/v__topicImpl.h index 21591ba51..bbc4b2b99 100644 --- a/src/kernel/code/v__topicImpl.h +++ b/src/kernel/code/v__topicImpl.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -53,8 +54,8 @@ v_topicImplFree( v_topicImpl _this); v_result -v_topicImplEnable( - v_topicImpl topic); +v__topicImplEnable( + _Inout_ v_topicImpl topic); v_topicQos v_topicImplGetQos( diff --git a/src/kernel/code/v__topicQos.h b/src/kernel/code/v__topicQos.h index 6b868621a..1c77692e8 100644 --- a/src/kernel/code/v__topicQos.h +++ b/src/kernel/code/v__topicQos.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/code/v__transaction.h b/src/kernel/code/v__transaction.h index 4a7d5482e..438c039d4 100644 --- a/src/kernel/code/v__transaction.h +++ b/src/kernel/code/v__transaction.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -38,10 +39,10 @@ * - A v_transactionWriter class : Internal class implementing an administration record * for each discovered matching coherent DataWriter which * will hold all active transactions. - * - A v_transaction class : Internal class implementing an administration record + * - A v_transaction class : Internal class implementing an administration record * for each active transaction which will hold all * received messages. - * - A v_transactionElement class : Internal class implementing an administration record + * - A v_transactionElement class : Internal class implementing an administration record * for each received transaction message. */ @@ -55,7 +56,7 @@ extern "C" { * \brief The following MARCROs are defined to cast references to the correct type. * * If compiled with the NDEBUG flag not set, these macros will additionally perform - * runtime type checking, and in case of providing an incorrect type these macros will + * runtime type checking, and in case of providing an incorrect type these macros will * return a NULL reference. */ #define v_messageEOT(o) (C_CAST(o,v_messageEOT)) @@ -81,9 +82,9 @@ typedef void (*v_transactionAction) (v_instance instance, v_message message, c_v */ v_transactionAdmin v_transactionAdminNew( - v_object owner, - v_transactionGroupAdmin groupAdmin, - v_topic topic); + _In_ v_object owner, + _In_opt_ v_transactionGroupAdmin groupAdmin, + _In_ v_topic topic); /** * \brief This operation notifies the transactionAdmin about discovered @@ -136,7 +137,7 @@ v_transactionAdminInsertMessage( c_bool *complete); /** - * \brief This operation will perform a user action on all transactions. + * \brief This operation will perform a user action on all transactions. * * \param _this : The transaction administration this operation operates on. * \param action : The user action that is executed on each transaction. @@ -170,16 +171,20 @@ v_transactionAdminWalkWriters( * * This operation is executed when a transaction has become complete * and will insert all messages belonging to the transaction into the - * reader's history and delete the transaction from this administration. + * reader's history and delete the transaction from this administration. * * \param _this : The transaction this operation operates on. - * + * * \return : Not applicable. */ void +v_transactionFlush_nl( + v_transaction _this); + +/* similar as v_transactionFlush_nl but also takes lock of the transaction owner. */ +void v_transactionFlush( - v_transaction _this, - v_transactionAdmin owner); + v_transaction _this); /** * \brief This operation will invoke the given action routine for all @@ -230,15 +235,6 @@ v_transactionGroupAdmin v_transactionGetGroupAdmin( v_transactionAdmin _this); -void -v_transactionTriggerList( - v_transaction _this, - c_iter triggerList); - -void -v_transactionAdminTrigger( - v_transactionAdmin _this); - void v_transactionNotifySampleLost( v_transaction _this, @@ -267,8 +263,12 @@ v_transactionAdminNoMessageFromWriterExist( v_gid writerGid); void -v_transactionAdminPurgeHistory( - v_transactionAdmin _this); +v_transactionLink( + v_transaction _this); + +void +v_transactionUnlink( + v_transaction _this); #if defined (__cplusplus) } diff --git a/src/kernel/code/v__transactionGroup.h b/src/kernel/code/v__transactionGroup.h index ad25f35cb..8d7985973 100644 --- a/src/kernel/code/v__transactionGroup.h +++ b/src/kernel/code/v__transactionGroup.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -39,7 +40,7 @@ * - A v_transactionPublisher class : Internal class implementing an administration record * for each discovered matching coherent Publisher which * will hold all active transaction groups. - * - A v_transactionGroup class : Internal class implementing an administration record + * - A v_transactionGroup class : Internal class implementing an administration record * for each active transaction group which will hold all * completed DataWriter transactions. */ @@ -58,6 +59,7 @@ extern "C" { * return a NULL reference. */ #define v_transactionGroup(o) (C_CAST(o,v_transactionGroup)) +#define v_transactionGroupAdmin(o) (C_CAST(o,v_transactionGroupAdmin)) /** * \brief The v_transactionGroupAdmin constructor. @@ -65,12 +67,14 @@ extern "C" { * \param owner : this is the object that will be the owner of the administration, * this is either a v_subscriber or a v_kernel for durable data. * - * \return : NULL if this operation fails, otherwise - * a reference to a newly created v_transactionGroupAdmin. + * \return : a reference to a newly created v_transactionGroupAdmin. */ +_Check_return_ +_Ret_notnull_ +_Pre_satisfies_(v_objectKind(owner) == K_KERNEL || v_objectKind(owner) == K_SUBSCRIBER) v_transactionGroupAdmin v_transactionGroupAdminNew( - v_object owner); + _In_ v_object owner); /** * \brief This operation inserts a completed transaction belonging to a @@ -99,17 +103,12 @@ v_transactionGroupAdminRemoveReader( v_transactionGroupAdmin _this, v_reader reader); -void -v_transactionGroupAdminUpdateReader( - v_transactionGroupAdmin _this, - v_reader reader); - void v_transactionGroupAdminFlush( v_transactionGroupAdmin _this); c_bool -v_transactionGroupAdminNotifyGroupCoherentPublication( +v_transactionGroupAdminNotifyPublication( v_transactionGroupAdmin _this, v_transactionWriter writer, c_bool dispose, @@ -127,11 +126,6 @@ v_transactionGroupAdminFlushPending( v_transactionGroupAdmin _this, v_transactionAdmin admin); -void -v_transactionGroupAdminTrigger( - v_transactionGroupAdmin _this, - v_reader owner); - /** * \brief This operation checks if the transaction group admin does * not contain samples from a writer for a particular group instance. @@ -155,8 +149,12 @@ v_transactionGroupAdminNoMessageFromWriterExist( v_gid writerGid); void -v_transactionGroupAdminPurgeHistory( - v_transactionGroupAdmin _this); +v_transactionGroupLink( + v_transactionGroup _this); + +void +v_transactionGroupUnlink( + v_transactionGroup _this); #if defined (__cplusplus) } diff --git a/src/kernel/code/v__typeRepresentation.h b/src/kernel/code/v__typeRepresentation.h index 7d375db19..6f53d79dd 100644 --- a/src/kernel/code/v__typeRepresentation.h +++ b/src/kernel/code/v__typeRepresentation.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/code/v__waitset.h b/src/kernel/code/v__waitset.h index 86052c1d0..d13a751e2 100644 --- a/src/kernel/code/v__waitset.h +++ b/src/kernel/code/v__waitset.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,12 +24,6 @@ #include "v_waitset.h" -#define v_waitsetLock(_this) \ - v_observerLock(v_observer(_this)) - -#define v_waitsetUnlock(_this) \ - v_observerUnlock(v_observer(_this)) - /** * Releases all resources claimed by the referenced waitset object. * diff --git a/src/kernel/code/v__writer.h b/src/kernel/code/v__writer.h index 252e70eed..cc4f9ead1 100644 --- a/src/kernel/code/v__writer.h +++ b/src/kernel/code/v__writer.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -47,7 +48,8 @@ * nothing the statistics are updated as if the instance just became ALIVE (so * the new state has to be ALIVE). This is useful for initialization. It uses * the newState (oldState ^ xoredState) to determine whether counters have to be - * updated. */ + * updated. + */ #define __V_WRITER_UPDATE_ALIVE__(writer, oldState, xoredState) \ if (oldState != 0 && __V_WRITER_LIVELINESS_CHANGED__(xoredState)) { \ if (__V_WRITER_ALIVE__(oldState)){\ @@ -60,7 +62,8 @@ } /* Updates the statistics for the instance-state flags that are enabled. Updates - * are only performed when statistics are enabled for the specified reader. */ + * are only performed when statistics are enabled for the specified reader. + */ #define UPDATE_WRITER_STATISTICS(writer, instance, oldState) \ if (writer->statistics) { \ v_state xoredState = oldState^v_instanceState(instance); \ @@ -72,7 +75,8 @@ /* Subtracts the currently still enabled instance-state flags from the * statistics. Updates are only performed when statistics are enabled for - * the specified writer. */ + * the specified writer. + */ #define UPDATE_WRITER_STATISTICS_REMOVE_INSTANCE(writer, instance) \ if ((writer)->statistics) { \ v_state state = v_instanceState(instance); \ @@ -94,7 +98,8 @@ /* Evaluates to TRUE in all cases when resends need to be done in order within * a writer. This is the case when the access_scope of the publisher is either - * V_PRESENTATION_TOPIC or V_PRESENTATION_GROUP. */ + * V_PRESENTATION_TOPIC or V_PRESENTATION_GROUP. + */ #define v__writerNeedsInOrderResends(w) ((w)->resend._d != V_PRESENTATION_INSTANCE) #define v__writerInOrderAdminOldest(w) (assert(v__writerNeedsInOrderResends(w)), v__writerInOrderAdmin(w)->resendOldest) @@ -105,16 +110,21 @@ * * In case v__writerNeedsInOrderResends(...) evaluates to TRUE, this is * determined by means of checking the head of the in-order admin. Otherwise - * the size of the resendInstances table is inspected. */ + * the size of the resendInstances table is inspected. + */ #define v__writerHasResendsPending(w) ((c_bool)(v__writerNeedsInOrderResends(w) ? (v__writerInOrderAdminOldest(w) != NULL) : (c_tableCount(v__writerResendInstances(w)) > 0))) - typedef struct v_writerNotifyChangedQosArg_s { /* the following fields are set when the partitionpolicy has changed. */ c_iter addedPartitions; c_iter removedPartitions; } v_writerNotifyChangedQosArg; +v_result +v__writerEnable( + v_writer writer, + os_boolean builtin); + c_bool v_writerPublishGroup ( v_writer _this, @@ -200,10 +210,6 @@ v_writerGroupWalkUnlocked( v_writerGroupAction action, c_voidp arg); -c_ulong -v_writerAllocSequenceNumber ( - v_writer _this); - void v_writerResendItemRemove( v_writer writer, @@ -214,8 +220,27 @@ v_writerResendItemInsert( v_writer writer, v_writerResendItem ri); -v_typeRepresentation -v__writerGetTypeRepresentation ( +char * +v__writerGetNameSpaceNames( + v_writer writer, + c_iter partitions, + c_iter nameSpaces); + +c_bool +v__writerInSingleNameSpace( + v_writer writer, + c_iter partitions, + c_iter nameSpaces); + +v_publisher +v_writerGetPublisher( + v_writer _this); + +/* This operation will return the actual builtin publication data for this writer. + * The writer caches this last published publication data. + */ +v_message +v_writerPublication( v_writer _this); #endif /* V__WRITER_H */ diff --git a/src/kernel/code/v__writerQos.h b/src/kernel/code/v__writerQos.h index 1ba784462..5f5231a16 100644 --- a/src/kernel/code/v__writerQos.h +++ b/src/kernel/code/v__writerQos.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/code/v_avgValue.c b/src/kernel/code/v_avgValue.c index 1a0af9d2f..632b41cba 100644 --- a/src/kernel/code/v_avgValue.c +++ b/src/kernel/code/v_avgValue.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/code/v_builtin.c b/src/kernel/code/v_builtin.c index 9a2ce8915..388d2cb7f 100644 --- a/src/kernel/code/v_builtin.c +++ b/src/kernel/code/v_builtin.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -35,39 +36,27 @@ #include "v__policy.h" #include "v_topic.h" #include "v_dataReader.h" +#include "v_dataReaderInstance.h" #include "v_deliveryServiceEntry.h" #include "v_public.h" -#include "v_observer.h" +#include "v__observer.h" +#include "v__observable.h" #include "v_participant.h" #include "v_topicQos.h" #include "v_writerQos.h" #include "v_publisherQos.h" #include "v_policy.h" #include "v_groupSet.h" - -/************************************************************** - * Private functions - **************************************************************/ - -/************************************************************** - * constructor/destructor - **************************************************************/ - -/************************************************************** - * Protected functions - **************************************************************/ -/************************************************************** - * Public functions - **************************************************************/ - +#include "v_configuration.h" +#include "v_cfElement.h" void v_builtinWritersDisable( v_builtin _this) { /* set builtin writer to NULL, to prevent using those writers - while publishing builtin topic information - */ + * while publishing builtin topic information + */ unsigned i; v_writer w = NULL; @@ -79,6 +68,661 @@ v_builtinWritersDisable( } } +char * +durationImage ( + c_time duration, + char *buf, + os_size_t bufsz) +{ + char *b = NULL; + c_double d; + + assert(buf); + assert(bufsz >= OS_DURATION_TO_STRING_BUFSIZE); + + if (buf && bufsz >= OS_DURATION_TO_STRING_BUFSIZE) { + if (c_timeIsInfinite(duration)) { + strncpy(buf, "INFINITE", bufsz); + } else if (c_timeIsInvalid(duration)) { + strncpy(buf, "INVALID", bufsz); + } else { + d = c_timeToReal(duration); + sprintf(buf, "%g", d); + } + b = buf; + } + return b; +} + +static const os_char * +dateImage( + os_timeW time, + os_char *buf, + os_size_t size) +{ + os_size_t ptr; + ptr = os_ctimeW_r(&time, buf, size); + buf[ptr++] = ' '; + os_timeWImage(time, &buf[ptr], size-ptr); + return buf; +} + +#define BUFSIZE (64) +#define DurationStr(d,b) durationImage(d,b,BUFSIZE) +#define TimeStr(t,b) dateImage(t,b,BUFSIZE) + +typedef os_char timebuf[BUFSIZE]; + +#define ReliabilityKindStr(k) (k == V_RELIABILITY_BESTEFFORT ? "BestEffort" : \ + k == V_RELIABILITY_RELIABLE ? "Reliable" : "?") + +#define SynchronousStr(s) (s ? "Synchronous" : "Asynchronous") + +#define DurabilityKindStr(k) (k == V_DURABILITY_VOLATILE ? "Volatile" : \ + k == V_DURABILITY_TRANSIENT_LOCAL ? "TransientLocal" : \ + k == V_DURABILITY_TRANSIENT ? "Transient" : \ + k == V_DURABILITY_PERSISTENT ? "Persistent" : "?") + +#define PresentationKindStr(k) (k == V_PRESENTATION_INSTANCE ? "Instance" : \ + k == V_PRESENTATION_TOPIC ? "Topic" : \ + k == V_PRESENTATION_GROUP ? "Group" : "?") + +#define LivelinessKindStr(k) (k == V_LIVELINESS_AUTOMATIC ? "Automatic" : \ + k == V_LIVELINESS_PARTICIPANT ? "ByParticipant" : \ + k == V_LIVELINESS_TOPIC ? "ByTopic" : "?") + +#define OwnershipKindStr(k) (k == V_OWNERSHIP_SHARED ? "Shared" : \ + k == V_OWNERSHIP_EXCLUSIVE ? "Exclusive" : "?") + +#define HistoryKindStr(k) (k == V_HISTORY_KEEPLAST ? "KeepLast" : \ + k == V_HISTORY_KEEPALL ? "KeepAll" : "?") + +#define OrderbyKindStr(k) (k == V_ORDERBY_RECEPTIONTIME ? "ByReception" : \ + k == V_ORDERBY_SOURCETIME ? "BySource" : "?") + +#define SampleVisibilityKindStr(k) (k == V_VISIBILITY_NO_INVALID_SAMPLES ? "NoInvalidSamples" : \ + k == V_VISIBILITY_MINIMUM_INVALID_SAMPLES ? "MinimumInvalidSamples" : \ + k == V_VISIBILITY_ALL_INVALID_SAMPLES ? "AllInvalidSamples" : "?") + +#define KeyFmt "[%u,%u,%u]" +#define KeyStr(k) k.systemId, k.localId, k.serial + +#define DurabilityFmt "Durability[%s]" +#define DurabilityStr(d) DurabilityKindStr(d.kind) + +#define ReliabilityFmt "Reliability[%s,%s,%s]" +#define ReliabilityStr(r,b) ReliabilityKindStr(r.kind), DurationStr(r.max_blocking_time, b), SynchronousStr(r.synchronous) + +#define OwnershipFmt "Ownership[%s]" +#define OwnershipStr(o) OwnershipKindStr(o.kind) + +#define ProductDataFmt "ProductData[%s]" +#define ProductDataStr(p) (p.value ? p.value : "") + +#define UserDataFmt "UserData[%s]" +#define TopicDataFmt "TopicData[%s]" +#define GroupDataFmt "GroupData[%s]" +#define PartitionFmt "Partition[%s]" +#define MetaDataFmt "MetaData[%s]" +#define KeylistFmt "Keylist[%s]" + +#define KeylistStr(s) (s?s:"") +#define NameStr(n) (n?n:"") + +#define HistoryFmt "History[%s,%d]" +#define HistoryStr(h) HistoryKindStr(h.kind), h.depth + +#define OrderbyFmt "OrderBy[%s]" +#define OrderbyStr(o) OrderbyKindStr(o.kind) + +#define PresentationFmt "Presentation[%s,%s,%s]" +#define PresentationStr(p) PresentationKindStr(p.access_scope), (p.coherent_access?"Coherent":"NotCoherent"), (p.ordered_access?"Ordered":"NotOrdered") + +#define LivelinessFmt "Liveliness[%s,%s]" +#define LivelinessStr(l,b) LivelinessKindStr(l.kind), DurationStr(l.lease_duration,b) + +#define DeadlineFmt "Deadline[%s]" +#define DeadlineStr(d,b) DurationStr(d.period, b) + +#define LatencyBudgetFmt "LatencyBudget[%s]" +#define LatencyBudgetStr(l,b) DurationStr(l.duration, b) + +#define LifespanFmt "Lifespan[%s]" +#define LifespanStr(l,b) DurationStr(l.duration, b) + +#define TransportPrioFmt "TransportPrio[%d]" +#define TransportPrioStr(t) t.value + +#define LifecycleFmt "AutoDispose[%s], PurgeSuspendedDelay[%s], PurgeUnregisterDelay[%s]" +#define LifecycleStr(l,b1,b2) \ + (l.autodispose_unregistered_instances ? "True" : "False"), \ + DurationStr(l.autopurge_suspended_samples_delay,b1), \ + DurationStr(l.autounregister_instance_delay, b2) + +#define PacingFmt "MinSeperation[%s]" +#define PacingStr(p,b) DurationStr(p.minSeperation,b) + +#define ReaderLifespanFmt "Lifespan[%s,%s]" +#define ReaderLifespanStr(l,b) (l.used ? "Used" : "NotUsed"), DurationStr(l.duration,b) + +#define ResourceLimitsFmt "MaxSamples[%d], MaxInstances[%d], MaxSamplesPerInstance[%d]" +#define ResourceLimitsStr(l) l.max_samples, l.max_instances, l.max_samples_per_instance + +#define DurabilityServiceFmt "DurabilityService[%s,%s,%d,%d,%d,%d]" +#define DurabilityServiceStr(d,b) DurationStr(d.service_cleanup_delay, b), \ + HistoryKindStr(d.history_kind), \ + d.history_depth, d.max_samples, d.max_instances, d.max_samples_per_instance + +#define ReaderLifecycleFmt "Lifecycle[%s,%s,%s,%s,%s]" +#define ReaderLifecycleStr(l,b1,b2) DurationStr(l.autopurge_nowriter_samples_delay, b1), \ + DurationStr(l.autopurge_disposed_samples_delay, b2), \ + (l.autopurge_dispose_all ? "AutoPurgeDisposeAll" : "NotPurgeDisposeAll"), \ + (l.enable_invalid_samples ? "InvalidSamplesEnabled" : "InvalidSamplesDisabled"), \ + SampleVisibilityKindStr(l.invalid_sample_visibility) + +#define UserKeyFmt "UserDefKey[%s,%s]" +#define UserKeyStr(u) (u.enable ? "Enabled":"Disabled"), (u.expression ? u.expression : "") + +#define ShareFmt "Shared[%s,%s]" +#define ShareStr(s) (s.name && strcmp(s.name,"") ? s.name : ""), (s.enable ? "Enabled":"Disabled") + +#define v_dataReaderSampleInstanceStateTest(_this,_mask) \ + v_dataReaderInstanceStateTest(v_dataReaderSampleInstance(_this),_mask) + +static os_char * +PartitionStr( + struct v_builtinPartitionPolicy *partition) +{ + os_char *p = NULL; + os_size_t len, size, i; + + size = 1; + len = c_arraySize(partition->name); + for (i=0; iname[i]) + 1; + } + p = os_malloc(size); + p[0] = 0; + for (i=0; iname[i]); + if (i+1value); +} + +static os_char * +TopicDataStr( + struct v_builtinTopicDataPolicy *topicdata) +{ + return OctetStr(topicdata->value); +} + +static os_char * +GroupDataStr( + struct v_builtinGroupDataPolicy *groupdata) +{ + return OctetStr(groupdata->value); +} + +static const os_char * +SampleStateStr( + v_dataReaderSample sample) +{ + v_dataReaderInstance inst; + + inst = v_dataReaderSampleInstance(sample); + if (v_dataReaderInstanceStateTest(inst, L_NEW)) { + if (v_dataReaderInstanceStateTest(inst, L_DISPOSED)) { + return "NewDisposed"; + } else if (v_dataReaderInstanceStateTest(inst, L_NOWRITERS)) { + return "NewNotAlive"; + } else { + return "NewAlive"; + } + } else { + if (v_dataReaderInstanceStateTest(inst, L_DISPOSED)) { + return "Disposed"; + } else if (v_dataReaderInstanceStateTest(inst, L_NOWRITERS)) { + return "NotAlive"; + } else { + return "Alive"; + } + } +} + +void +v_builtinLogParticipant( + v_builtin _this, + const v_dataReaderSample sample) +{ + v_message msg; + struct v_participantInfo *info; + os_char curtime[BUFSIZE], pubtime[BUFSIZE]; + + if (_this->logfile) { + msg = v_dataReaderSampleMessage(sample); + info = (struct v_participantInfo *) (msg + 1); + fprintf(_this->logfile, + "%s : DomainParticipant"KeyFmt", WriteTime[%s]\n", + os_timeWImage(os_timeWGet(), curtime, BUFSIZE), + KeyStr(info->key), + os_timeWImage(msg->writeTime, pubtime, BUFSIZE)); + } +} + +void +v_builtinLogPublication( + v_builtin _this, + const v_dataReaderSample sample) +{ + v_message msg; + struct v_publicationInfo *info; + timebuf buf[9]; + os_char *partition = NULL; + os_char *user_data = NULL; + os_char *group_data = NULL; + os_char *topic_data = NULL; + + if (_this->logfile) { + msg = v_dataReaderSampleMessage(sample); + info = (struct v_publicationInfo *) (msg + 1); + partition = PartitionStr(&info->partition); + user_data = UserDataStr(&info->user_data); + group_data = GroupDataStr(&info->group_data); + topic_data = TopicDataStr(&info->topic_data); + fprintf(_this->logfile, + + "%s : DataWriter"KeyFmt", Participant"KeyFmt", State[%s], WriteTime[%s], Topic[%s], Type[%s], " + DurabilityFmt", "ReliabilityFmt", "PresentationFmt", "OrderbyFmt", "LivelinessFmt"," + OwnershipFmt", Strength[%d], "LifespanFmt", "DeadlineFmt", "LatencyBudgetFmt", " + LifecycleFmt", "PartitionFmt", "UserDataFmt", "GroupDataFmt", "TopicDataFmt"\n\n", + + TimeStr(os_timeWGet(), buf[0]), + KeyStr(info->key), + KeyStr(info->participant_key), + SampleStateStr(sample), + TimeStr(msg->writeTime, buf[1]), + NameStr(info->topic_name), + NameStr(info->type_name), + DurabilityStr(info->durability), + ReliabilityStr(info->reliability, buf[2]), + PresentationStr(info->presentation), + OrderbyStr(info->destination_order), + LivelinessStr(info->liveliness, buf[3]), + OwnershipStr(info->ownership), + info->ownership_strength.value, + LifespanStr(info->lifespan, buf[4]), + DeadlineStr(info->deadline, buf[5]), + LatencyBudgetStr(info->latency_budget, buf[6]), + LifecycleStr(info->lifecycle, buf[7], buf[8]), + partition, user_data, group_data, topic_data); + + os_free(partition); + os_free(user_data); + os_free(group_data); + os_free(topic_data); + } +} + +void +v_builtinLogSubscription( + v_builtin _this, + const v_dataReaderSample sample) +{ + v_message msg; + struct v_subscriptionInfo *info; + timebuf buf[9]; + os_char *partition = NULL; + os_char *user_data = NULL; + os_char *group_data = NULL; + os_char *topic_data = NULL; + + if (_this->logfile) { + msg = v_dataReaderSampleMessage(sample); + info = (struct v_subscriptionInfo *) (msg + 1); + partition = PartitionStr(&info->partition); + user_data = UserDataStr(&info->user_data); + group_data = GroupDataStr(&info->group_data); + topic_data = TopicDataStr(&info->topic_data); + fprintf(_this->logfile, + + "%s : DataReader"KeyFmt", Participant"KeyFmt", State[%s], WriteTime[%s], Topic[%s], Type[%s], " + DurabilityFmt", "ReliabilityFmt", "PresentationFmt", "OrderbyFmt", "LivelinessFmt", " + OwnershipFmt", "DeadlineFmt", "LatencyBudgetFmt", " ReaderLifespanFmt", "PacingFmt", " + PartitionFmt", "UserDataFmt", "GroupDataFmt", "TopicDataFmt"\n\n", + + TimeStr(os_timeWGet(), buf[0]), + KeyStr(info->key), + KeyStr(info->participant_key), + SampleStateStr(sample), + TimeStr(msg->writeTime, buf[1]), + NameStr(info->topic_name), + NameStr(info->type_name), + DurabilityStr(info->durability), + ReliabilityStr(info->reliability,buf[2]), + PresentationStr(info->presentation), + OrderbyStr(info->destination_order), + LivelinessStr(info->liveliness,buf[3]), + OwnershipStr(info->ownership), + DeadlineStr(info->deadline, buf[5]), + LatencyBudgetStr(info->latency_budget, buf[6]), + ReaderLifespanStr(info->lifespan, buf[7]), + PacingStr(info->time_based_filter,buf[8]), + partition, user_data, group_data, topic_data); + + os_free(partition); + os_free(user_data); + os_free(group_data); + os_free(topic_data); + } +} + +void +v_builtinLogTopic( + v_builtin _this, + const v_dataReaderSample sample) +{ + v_message msg; + struct v_topicInfo *info; + timebuf buf[8]; + os_char *topic_data = NULL; + + if (_this->logfile) { + msg = v_dataReaderSampleMessage(sample); + info = (struct v_topicInfo *) (msg + 1); + topic_data = TopicDataStr(&info->topic_data); + fprintf(_this->logfile, + + "%s : Topic"KeyFmt", State[%s], WriteTime[%s], Name[%s], Type[%s], " + DurabilityFmt", "DurabilityServiceFmt", "ReliabilityFmt", " + HistoryFmt", "OrderbyFmt", "LivelinessFmt","LifespanFmt", " + DeadlineFmt", "LatencyBudgetFmt", "OwnershipFmt", "TransportPrioFmt", " + ResourceLimitsFmt", "TopicDataFmt", "MetaDataFmt", "KeylistFmt"\n\n", + + TimeStr(os_timeWGet(), buf[0]), + KeyStr(info->key), + SampleStateStr(sample), + TimeStr(msg->writeTime, buf[1]), + NameStr(info->name), + NameStr(info->type_name), + DurabilityStr(info->durability), + DurationStr(info->durabilityService.service_cleanup_delay, buf[2]), + HistoryKindStr(info->durabilityService.history_kind), + info->durabilityService.history_depth, info->durabilityService.max_samples, + info->durabilityService.max_instances, info->durabilityService.max_samples_per_instance, + ReliabilityStr(info->reliability, buf[3]), + HistoryStr(info->history), + OrderbyStr(info->destination_order), + LivelinessStr(info->liveliness, buf[4]), + LifespanStr(info->lifespan, buf[5]), + DeadlineStr(info->deadline, buf[6]), + LatencyBudgetStr(info->latency_budget, buf[7]), + OwnershipStr(info->ownership), + TransportPrioStr(info->transport_priority), + ResourceLimitsStr(info->resource_limits), + topic_data, info->meta_data, + KeylistStr(info->key_list)); + + os_free(topic_data); + } +} + +void +v_builtinLogCMParticipant( + v_builtin _this, + const v_dataReaderSample sample) +{ + v_message msg; + struct v_participantCMInfo *info; + timebuf buf[2]; + + if (_this->logfile && !v_readerSampleTestState(sample, L_REMOVED)) { + msg = v_dataReaderSampleMessage(sample); + info = (struct v_participantCMInfo *) (msg + 1); + fprintf(_this->logfile, + "%s : CMParticipant"KeyFmt", State[%s], WriteTime[%s], "ProductDataFmt"\n\n", + TimeStr(os_timeWGet(), buf[0]), + KeyStr(info->key), + SampleStateStr(sample), + TimeStr(msg->writeTime, buf[1]), + ProductDataStr(info->product)); + } +} + +void +v_builtinLogCMDataWriter( + v_builtin _this, + const v_dataReaderSample sample) +{ + v_message msg; + struct v_dataWriterCMInfo *info; + timebuf buf[4]; + + if (_this->logfile && !v_readerSampleTestState(sample, L_REMOVED)) { + msg = v_dataReaderSampleMessage(sample); + info = (struct v_dataWriterCMInfo *) (msg + 1); + fprintf(_this->logfile, + + "%s : CMDataWriter"KeyFmt", Publisher"KeyFmt", State[%s], WriteTime[%s], Name[%s], " + ProductDataFmt", "HistoryFmt", "ResourceLimitsFmt", "LifecycleFmt"\n\n", + + TimeStr(os_timeWGet(), buf[0]), + KeyStr(info->key), + KeyStr(info->publisher_key), + SampleStateStr(sample), + TimeStr(msg->writeTime, buf[1]), + NameStr(info->name), + ProductDataStr(info->product), + HistoryStr(info->history), + ResourceLimitsStr(info->resource_limits), + LifecycleStr(info->writer_data_lifecycle, buf[2], buf[3])); + } +} + +void +v_builtinLogCMDataReader( + v_builtin _this, + const v_dataReaderSample sample) +{ + v_message msg; + struct v_dataReaderCMInfo *info; + timebuf buf[5]; + + if (_this->logfile && !v_readerSampleTestState(sample, L_REMOVED)) { + msg = v_dataReaderSampleMessage(sample); + info = (struct v_dataReaderCMInfo *) (msg + 1); + fprintf(_this->logfile, + + "%s : CMDataReader"KeyFmt", Subscriber"KeyFmt", State[%s], WriteTime[%s], Name[%s], "ProductDataFmt", " + HistoryFmt", "ResourceLimitsFmt", "ReaderLifecycleFmt", "UserKeyFmt", "ShareFmt", "ReaderLifespanFmt"\n\n", + + TimeStr(os_timeWGet(), buf[0]), + KeyStr(info->key), + KeyStr(info->subscriber_key), + SampleStateStr(sample), + TimeStr(msg->writeTime, buf[1]), + NameStr(info->name), + ProductDataStr(info->product), + HistoryStr(info->history), + ResourceLimitsStr(info->resource_limits), + ReaderLifecycleStr(info->reader_data_lifecycle, buf[2], buf[3]), + UserKeyStr(info->subscription_keys), + ShareStr(info->share), + ReaderLifespanStr(info->reader_lifespan, buf[4])); + } +} + +void +v_builtinLogCMPublisher( + v_builtin _this, + const v_dataReaderSample sample) +{ + v_message msg; + struct v_publisherCMInfo *info; + timebuf buf[2]; + os_char *partition = NULL; + + if (_this->logfile && !v_readerSampleTestState(sample, L_REMOVED)) { + msg = v_dataReaderSampleMessage(sample); + info = (struct v_publisherCMInfo *) (msg + 1); + partition = PartitionStr(&info->partition); + fprintf(_this->logfile, + + "%s : CMPublisher"KeyFmt", Participant"KeyFmt", State[%s], WriteTime[%s], Name[%s], "ProductDataFmt", " + "AutoEnable[%s], "PartitionFmt"\n\n", + + TimeStr(os_timeWGet(), buf[0]), + KeyStr(info->key), + KeyStr(info->participant_key), + SampleStateStr(sample), + TimeStr(msg->writeTime, buf[1]), + NameStr(info->name), + ProductDataStr(info->product), + (info->entity_factory.autoenable_created_entities ? "True" : "False"), + partition); + + os_free(partition); + } +} + +void +v_builtinLogCMSubscriber( + v_builtin _this, + const v_dataReaderSample sample) +{ + v_message msg; + struct v_subscriberCMInfo *info; + timebuf buf[2]; + os_char *partition = NULL; + + if (_this->logfile && !v_readerSampleTestState(sample, L_REMOVED)) { + msg = v_dataReaderSampleMessage(sample); + info = (struct v_subscriberCMInfo *) (msg + 1); + fprintf(_this->logfile, "v_subscriberCMInfo\n"); + partition = PartitionStr(&info->partition); + fprintf(_this->logfile, + + "%s : CMPublisher"KeyFmt", Participant"KeyFmt", State[%s], WriteTime[%s], Name[%s], "ProductDataFmt", " + "AutoEnable[%s], "ShareFmt", "PartitionFmt"\n\n", + + TimeStr(os_timeWGet(), buf[0]), + KeyStr(info->key), + KeyStr(info->participant_key), + SampleStateStr(sample), + TimeStr(msg->writeTime, buf[1]), + NameStr(info->name), + ProductDataStr(info->product), + (info->entity_factory.autoenable_created_entities ? "True" : "False"), + ShareStr(info->share), + partition); + + os_free(partition); + } +} + +static FILE * +v_builtinGetLogfile( + v_builtin _this) +{ + char *filename = NULL; + FILE *logfile=NULL; + os_char *dir, *str; + os_size_t len; + + c_iter iter; + c_value value; + v_cfElement root, elem; + v_kernel kernel; + v_configuration config; + + kernel = v_objectKernel(_this->participant); + if (!kernel->configuration) { + return NULL; + } + config = kernel->configuration; + root = v_configurationGetRoot(config); + iter = v_cfElementXPath(root, "Domain/BuiltinTopics"); + elem = v_cfElement(c_iterTakeFirst(iter)); + while (elem) { + value = v_cfElementAttributeValue(elem, "logfile"); + if (value.kind == V_STRING) { + if (filename) { + os_free(filename); + } + filename = os_strdup(value.is.String); + } + elem = v_cfElement(c_iterTakeFirst(iter)); + } + c_iterFree(iter); + + if (filename) { + _this->kernelQos = c_keep(kernel->qos); + if (strcmp (filename, "") == 0) { + logfile = stdout; + } else if (strcmp (filename, "") == 0) { + logfile = stderr; + } else { + dir = os_getenv("OSPL_LOGPATH"); + if (dir == NULL) { + dir = "."; + } + len = strlen(dir) + strlen(filename) + 2; /* '/' + '\0' */ + str = os_malloc (len); + if (str != NULL) { + (void)snprintf (str, len, "%s/%s", dir, filename); + os_free(filename); + filename = os_fileNormalize (str); + os_free (str); + if (filename != NULL) { + logfile = fopen (filename, "a"); + if (logfile == NULL) { + OS_REPORT_NOW(OS_ERROR, "Configuration file", V_RESULT_PRECONDITION_NOT_MET, 0, + "Failed to open Domain/BuiltinTopics/logfile: '%s' with error : %s.", + filename, strerror(errno)); + } + } else { + OS_REPORT_NOW(OS_ERROR, + "kernel::v_builtin::v_builtinNew", V_RESULT_INTERNAL_ERROR, 0, + "Failed to allocate logfile name (1)."); + } + } else { + OS_REPORT_NOW(OS_ERROR, + "kernel::v_builtin::v_builtinNew", V_RESULT_INTERNAL_ERROR, 0, + "Failed to allocate logfile name (2)."); + } + } + os_free(filename); + } + return logfile; +} + v_builtin v_builtinNew( v_kernel kernel) @@ -155,7 +799,7 @@ v_builtinNew( "Failed to allocate \"Built-in participant\" object."); goto error; } - + _this->logfile = v_builtinGetLogfile(_this); if ((pQos = v_publisherQosNew (kernel, NULL)) == NULL) { OS_REPORT(OS_ERROR, "kernel::v_builtin::v_builtinNew", V_RESULT_INTERNAL_ERROR, @@ -227,8 +871,9 @@ v_builtinNew( tQos->reliability.v.max_blocking_time = OS_DURATION_INIT(0,100000000); tQos->durabilityService.v.service_cleanup_delay = OS_DURATION_ZERO; /* make the history qos to have keep all and unlimited depth so - that samples that are marked for resend don't get squeezed out - of the writer's history */ + * that samples that are marked for resend don't get squeezed out + * of the writer's history + */ tQos->history.v.kind = V_HISTORY_KEEPALL; tQos->history.v.depth = V_LENGTH_UNLIMITED; break; @@ -253,7 +898,7 @@ v_builtinNew( ts[i].topicname, typename, ts[i].keylist); goto error; } - /* Overrule TopicAccess for builtin topics see OSPL-6437 */ + /* Overrule TopicAccess for builtin topics */ v_topicImpl(_this->topics[ts[i].id])->accessMode = V_ACCESS_MODE_READ_WRITE; if (ts[i].transient >= trans_threshold) { wQos->durability.v.kind = V_DURABILITY_TRANSIENT; @@ -265,31 +910,34 @@ v_builtinNew( wQos->reliability.v.kind = ts[i].isreliable ? V_RELIABILITY_RELIABLE : V_RELIABILITY_BESTEFFORT; wQos->transport.v.value = ts[i].transportPriority; _this->writers[ts[i].id] = v_writerNew (_this->publisher, wrname, _this->topics[ts[i].id], wQos); - if (_this->writers[ts[i].id] == NULL) { - OS_REPORT (OS_ERROR, - "kernel::v_builtin::v_builtinNew", V_RESULT_INTERNAL_ERROR, - "Operation failed because v_writerNew failed for:" - OS_REPORT_NL "Name: \"%s" - OS_REPORT_NL "Topic: \"%s", - wrname, ts[i].topicname); - goto error; - } else { - v_entityEnable(v_entity(_this->writers[ts[i].id])); - } } } c_free (wQos); c_free (tQos); c_free (pQos); + kernel->builtin = _this; + for (i = 0; i < sizeof (ts) / sizeof (ts[0]); i++) { + if (ts[i].always || _this->kernelQos->builtin.v.enabled) { + if (_this->writers[ts[i].id] == NULL) { + OS_REPORT (OS_ERROR, "kernel::v_builtin::v_builtinNew", + V_RESULT_INTERNAL_ERROR, "Operation failed because v_writerNew failed for:" + OS_REPORT_NL "Topic: \"%s", ts[i].topicname); + goto error; + } else { + (void)v__writerEnable(_this->writers[ts[i].id], OS_FALSE); + } + } + } /* We have to solve a bootstrapping problem here! The kernel - entities created above have notified their existence to the - builtin interface. Unfortunately the implementation does not - yet exists as being in the construction of it :) Therefore this - information is published below. */ + * entities created above have notified their existence to the + * builtin interface. Unfortunately the implementation does not + * yet exists as being in the construction of it :) Therefore this + * information is published below. + */ { os_timeW time = os_timeWGet(); - v_message msg, msg2; + v_message msg; if (_this->kernelQos->builtin.v.enabled) { msg = v_builtinCreateParticipantInfo (_this, _this->participant); @@ -304,7 +952,8 @@ v_builtinNew( } for (i = 0; i < V_INFO_ID_COUNT; i++) { /* Do not use v_topicAnnounce (_this->topics[i]) as - kernel->builtin is not assigned yet! */ + * kernel->builtin is not assigned yet! + */ if (_this->topics[i] != NULL) { msg = v_builtinCreateTopicInfo (_this, _this->topics[i]); v_writerWrite (_this->writers[V_TOPICINFO_ID], msg, time, NULL); @@ -314,14 +963,14 @@ v_builtinNew( if (_this->kernelQos->builtin.v.enabled) { for (i = 0; i < V_INFO_ID_COUNT; i++) { if (_this->writers[i]) { - v_observerLock (v_observer(_this->writers[i])); - msg = v_builtinCreatePublicationInfo (_this, _this->writers[i]); - msg2 = v_builtinCreateCMDataWriterInfo (_this, _this->writers[i]); - v_observerUnlock (v_observer(_this->writers[i])); - v_writerWrite (_this->writers[V_PUBLICATIONINFO_ID], msg, time, NULL); - v_writerWrite (_this->writers[V_CMDATAWRITERINFO_ID], msg2, time, NULL); - c_free (msg); - c_free (msg2); + msg = v_writerPublication(_this->writers[i]); + v_writerWrite(_this->writers[V_PUBLICATIONINFO_ID], msg, time, NULL); + c_free(msg); + OSPL_LOCK(_this->writers[i]); + msg = v_builtinCreateCMDataWriterInfo (_this, _this->writers[i]); + OSPL_UNLOCK(_this->writers[i]); + v_writerWrite(_this->writers[V_CMDATAWRITERINFO_ID], msg, time, NULL); + c_free(msg); } } } @@ -405,7 +1054,8 @@ v_builtinCreateCMParticipantInfo ( parNameLength = strlen(participantName); } /* Note: the template has the vendor ID hardcoded to the DDSI vendor ID code - allocated by the OMG. */ + * allocated by the OMG. + */ #define T "" \ "" \ "" \ @@ -832,37 +1482,6 @@ v_builtinCreateCMDataWriterInfo ( return msg; } -static c_bool -getTopic ( - c_object o, - c_voidp arg) -{ - v_topic *topic = (v_topic *)arg; - c_bool result = TRUE; - - if (c_instanceOf(o, "v_dataReaderEntry")) { - v_dataReaderEntry entry = v_dataReaderEntry(o); - if (*topic == NULL) { - *topic = c_keep(entry->topic); - } else { - /* Already a topic was found so this must be a Multi Topic reader. - * In that case abort and clear the topic. - */ - c_free(*topic); - *topic = NULL; - result = FALSE; - } - } else if (c_instanceOf(o, "v_deliveryServiceEntry")) { - v_deliveryServiceEntry entry = v_deliveryServiceEntry(o); - *topic = c_keep(entry->topic); - } else { - OS_REPORT(OS_ERROR, "kernel::v_builtin::getTopic", V_RESULT_ILL_PARAM, "Type mismatch: object type is %s, but v_dataReaderEntry or v_deliveryServiceEntry was expected", c_metaObject(c_getType(o))->name); - assert(FALSE); - } - - return result; -} - v_message v_builtinCreateSubscriptionInfo ( v_builtin _this, @@ -904,8 +1523,7 @@ v_builtinCreateSubscriptionInfo ( return NULL; } - topic = NULL; - v_readerWalkEntries(reader,getTopic,&topic); + topic = v_readerGetTopic_nl(reader); assert (topic); qos = reader->qos; topicQos = v_topicGetQos (topic); @@ -1212,3 +1830,60 @@ v_builtinInfoIdToName( return name; } + +/* Returns TRUE if there is a partition match between + * the given publication and subscription info. + */ +os_boolean +v_builtinTestPartitionMatch( + const struct v_publicationInfo *pubInfo, + const struct v_subscriptionInfo *subInfo) +{ + c_ulong i, j; + c_value val; + c_value str1, str2; + c_array name1, name2; + + val.kind = V_BOOLEAN; + val.is.Boolean = FALSE; + + if ((pubInfo != NULL) && (subInfo != NULL)) { + name1 = pubInfo->partition.name; + name2 = subInfo->partition.name; + for (i = 0; val.is.Boolean == FALSE && i < c_arraySize(name1); i++) { + str1 = c_stringValue(name1[i]); + for (j = 0; val.is.Boolean == FALSE && j < c_arraySize(name2); j++) { + str2 = c_stringValue(name2[j]); + val = c_valueStringMatch(str1, str2); + if (!val.is.Boolean) { + val = c_valueStringMatch(str2, str1); + } + } + } + } + return (os_boolean)val.is.Boolean; +} + +/* Returns TRUE if there is a Qos match between + * the given publication and subscription info. + */ +os_boolean +v_builtinTestQosMatch( + const struct v_publicationInfo *pubInfo, + const struct v_subscriptionInfo *subInfo) +{ + if ((pubInfo != NULL) && + (subInfo != NULL) && + v_reliabilityPolicyCompatible(pubInfo->reliability, subInfo->reliability) && + v_durabilityPolicyCompatible(pubInfo->durability, subInfo->durability) && + v_presentationPolicyCompatible(pubInfo->presentation, subInfo->presentation) && + v_latencyPolicyCompatible(pubInfo->latency_budget, subInfo->latency_budget) && + v_orderbyPolicyCompatible(pubInfo->destination_order, subInfo->destination_order) && + v_deadlinePolicyCompatible(pubInfo->deadline, subInfo->deadline) && + v_livelinessPolicyCompatible(pubInfo->liveliness, subInfo->liveliness) && + v_ownershipPolicyCompatible(pubInfo->ownership, subInfo->ownership)) + { + return OS_TRUE; + } + return OS_FALSE; +} diff --git a/src/kernel/code/v_cache.c b/src/kernel/code/v_cache.c index 8f5b00dd7..393b60c18 100644 --- a/src/kernel/code/v_cache.c +++ b/src/kernel/code/v_cache.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/code/v_cache.h b/src/kernel/code/v_cache.h index 5cf906d8a..ff1799698 100644 --- a/src/kernel/code/v_cache.h +++ b/src/kernel/code/v_cache.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/code/v_cfAttribute.c b/src/kernel/code/v_cfAttribute.c index 02b748d9b..eb53aae7b 100644 --- a/src/kernel/code/v_cfAttribute.c +++ b/src/kernel/code/v_cfAttribute.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,13 +25,6 @@ #include "os_report.h" -/************************************************************** - * Private functions - **************************************************************/ - -/************************************************************** - * constructor/destructor - **************************************************************/ v_cfAttribute v_cfAttributeNew ( v_configuration config, @@ -75,7 +69,7 @@ v_cfAttributeInit ( case V_SHORT: case V_LONG: case V_LONGLONG: case V_USHORT: case V_ULONG: case V_ULONGLONG: case V_FLOAT: case V_DOUBLE: - case V_CHAR: + case V_CHAR: case V_WCHAR: case V_WSTRING: case V_FIXED: case V_OBJECT: default: @@ -89,13 +83,6 @@ v_cfAttributeInit ( } } -/************************************************************** - * Protected functions - **************************************************************/ - -/************************************************************** - * Public functions - **************************************************************/ c_value v_cfAttributeValue( v_cfAttribute attribute) diff --git a/src/kernel/code/v_cfData.c b/src/kernel/code/v_cfData.c index c0c19a0e8..931d71381 100644 --- a/src/kernel/code/v_cfData.c +++ b/src/kernel/code/v_cfData.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,13 +25,6 @@ #include "v_cfNode.h" #include "v_kernel.h" -/************************************************************** - * Private functions - **************************************************************/ - -/************************************************************** - * constructor/destructor - **************************************************************/ v_cfData v_cfDataNew ( v_configuration config, @@ -96,13 +90,6 @@ v_cfDataInit ( } -/************************************************************** - * Protected functions - **************************************************************/ - -/************************************************************** - * Public functions - **************************************************************/ c_value v_cfDataValue( v_cfData data) diff --git a/src/kernel/code/v_cfElement.c b/src/kernel/code/v_cfElement.c index ab35e388d..57f9e8c76 100644 --- a/src/kernel/code/v_cfElement.c +++ b/src/kernel/code/v_cfElement.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -41,10 +42,6 @@ struct getChildrenArg { c_iter children; }; -/************************************************************** - * Private functions - **************************************************************/ - static c_bool attributesToIterator( c_object o, @@ -123,9 +120,6 @@ getChildren( return TRUE; /* always finish the walk */ } -/************************************************************** - * constructor/destructor - **************************************************************/ v_cfElement v_cfElementNew ( v_configuration config, @@ -151,7 +145,7 @@ v_cfElementInit ( c_type attrType; c_type nodeType; const c_char *keyList; - + assert(C_TYPECHECK(element, v_cfElement)); assert(tagName != NULL); @@ -165,13 +159,6 @@ v_cfElementInit ( element->children = c_setNew(nodeType); } -/************************************************************** - * Protected functions - **************************************************************/ - -/************************************************************** - * Public functions - **************************************************************/ v_cfAttribute v_cfElementAddAttribute ( v_cfElement element, @@ -259,7 +246,7 @@ v_cfElementAttributeValue( assert(attributeName != NULL); attr = v_cfElementAttribute(element, attributeName); - + if (attr != NULL) { value = v_cfAttributeValue(attr); } else { @@ -284,7 +271,7 @@ v_cfElementXPath( assert(C_TYPECHECK(element, v_cfElement)); assert(xpathExpr != NULL); - + result = c_iterNew(element); nrToProcess = 1; posInExpr = xpathExpr; @@ -303,10 +290,11 @@ v_cfElementXPath( arg.tagName = (c_char *)os_malloc(length + 1U); os_strncpy(arg.tagName, posInExpr, length); arg.tagName[length] = 0; - + /* Look for selection criteria based on attribute value * Example XPath expression: - * /aaa/bbb[@name='value']/ccc or /aaa/bbb[@name!='value']/ccc */ + * /aaa/bbb[@name='value']/ccc or /aaa/bbb[@name!='value']/ccc + */ arg.attribName = strchr(arg.tagName, '['); if (arg.attribName != NULL) { *arg.attribName = '\0'; @@ -333,10 +321,10 @@ v_cfElementXPath( *attribEnd = '\0'; assert(attribEnd[1] == ']'); } - + c_walk(v_cfElement(node)->children, getChildren, &arg); os_free(arg.tagName); - if (slash) { + if (slash) { nrToProcess += c_iterLength(arg.children); } /* now append */ diff --git a/src/kernel/code/v_cfNode.c b/src/kernel/code/v_cfNode.c index 15b6ae9df..388d0bee2 100644 --- a/src/kernel/code/v_cfNode.c +++ b/src/kernel/code/v_cfNode.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,13 +28,6 @@ #include "v_cfAttribute.h" #include "v_cfData.h" -/************************************************************** - * Private functions - **************************************************************/ - -/************************************************************** - * constructor/destructor - **************************************************************/ v_cfNode v_cfNodeNew( v_configuration config, @@ -41,9 +35,9 @@ v_cfNodeNew( { v_cfNode node; c_type type; - + assert(C_TYPECHECK(config, v_configuration)); - + switch (kind) { case V_CFELEMENT: type = c_resolve(c_getBase(config), "kernelModuleI::v_cfElement"); @@ -60,7 +54,7 @@ v_cfNodeNew( OS_ERROR, OS_FUNCTION, V_RESULT_ILL_PARAM, "Illegal kind (%d) specified", kind); - assert(FALSE); + assert(FALSE); type = NULL; break; } @@ -75,8 +69,9 @@ v_cfNodeNew( assert(FALSE); node = NULL; } - /* init is done by specific class itself, this is just a - convenience function! */ + /* init is done by specific class itself, this is just a + * convenience function! + */ return node; } @@ -97,13 +92,6 @@ v_cfNodeInit ( node->configuration = config; } -/************************************************************** - * Protected functions - **************************************************************/ - -/************************************************************** - * Public functions - **************************************************************/ const c_char * v_cfNodeGetName ( v_cfNode node) @@ -130,6 +118,6 @@ v_cfNodeConfiguration( { assert(node != NULL); assert(C_TYPECHECK(node, v_cfNode)); - + return node->configuration; } diff --git a/src/kernel/code/v_cmsoap.c b/src/kernel/code/v_cmsoap.c index 19f0d2c61..1b4919e5e 100644 --- a/src/kernel/code/v_cmsoap.c +++ b/src/kernel/code/v_cmsoap.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/code/v_cmsoapStatistics.c b/src/kernel/code/v_cmsoapStatistics.c index 7a2e265c4..a926e7330 100644 --- a/src/kernel/code/v_cmsoapStatistics.c +++ b/src/kernel/code/v_cmsoapStatistics.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/code/v_collection.c b/src/kernel/code/v_collection.c index c5c582235..8e80d251f 100644 --- a/src/kernel/code/v_collection.c +++ b/src/kernel/code/v_collection.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,30 +24,20 @@ #include "v__query.h" #include "v_public.h" -/************************************************************** - * Private functions - **************************************************************/ - -/************************************************************** - * constructor/destructor - **************************************************************/ - -/************************************************************** - * Protected functions - **************************************************************/ void v_collectionInit( - v_collection c, - const c_char *name, - c_bool enable) + _Inout_ v_collection c, + _In_opt_z_ const c_char *name) { - c_base base; + c_type type; assert(C_TYPECHECK(c,v_collection)); - v_entityInit(v_entity(c), name, enable); - base = c_getBase(c_object(c)); - c->queries = c_setNew(c_resolve(base,"kernelModuleI::v_query")); + v_entityInit(v_entity(c), name); + type = c_resolve(c_getBase(c_object(c)),"kernelModuleI::v_query"); + assert(type); + c->queries = c_setNew(type); + c_free(type); } void @@ -86,7 +77,3 @@ v_collectionDeinit( c_free(c->queries); c->queries = NULL; } - -/************************************************************** - * Public functions - **************************************************************/ diff --git a/src/kernel/code/v_configuration.c b/src/kernel/code/v_configuration.c index 5d6feffdb..44d58ef4c 100644 --- a/src/kernel/code/v_configuration.c +++ b/src/kernel/code/v_configuration.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -532,3 +533,77 @@ v_configurationGetSchedulingPolicy ( } } + +static c_bool +v_configurationScanBoolean( + c_char *value) +{ + c_bool result = FALSE; + size_t l; + + l = strspn(value, " \t\n"); + if (l <= strlen(value)) { + if (os_strncasecmp(&value[l], "TRUE", 4) == 0) { + result = TRUE; + } + } + + return result; +} + +#define V_SERVICE_ENTRY_FMT "Domain/Service[@name='%s']" +#define V_SERVICE_ATTR_NAME "name" +#define V_SERVICE_ATTR_ENABLED "enabled" + +static c_bool +v_configurationServiceIsEnabled( + v_configuration config, + const c_char *serviceName) +{ + c_bool enabled = FALSE; + v_cfAttribute attr; + c_char *path; + c_value value; + + path = os_malloc(strlen(V_SERVICE_ENTRY_FMT) + strlen(serviceName) + 1); + os_sprintf(path, V_SERVICE_ENTRY_FMT, serviceName); + attr = ResolveAttribute(config->root, path, V_SERVICE_ATTR_ENABLED); + if (attr) { + value = v_cfAttributeValue(attr); + if (value.kind == V_STRING) { + enabled = v_configurationScanBoolean(value.is.String); + } + } else { + enabled = TRUE; + } + os_free(path); + + return enabled; +} + +c_bool +v_configurationContainsService( + v_configuration config, + const char *serviceName) +{ + c_bool found = FALSE; + c_iter nodes; + v_cfNode node; + c_value value; + + nodes = v_cfElementXPath(config->root, serviceName); + node = v_cfNode(c_iterTakeFirst(nodes)); + while (!found && node) { + if (v_cfNodeKind(node) == V_CFELEMENT) { + value = v_cfElementAttributeValue(v_cfElement(node), V_SERVICE_ATTR_NAME); + if (value.kind == V_STRING) { + found = v_configurationServiceIsEnabled(config, value.is.String); + } + } + node = v_cfNode(c_iterTakeFirst(nodes)); + } + + c_iterFree(nodes); + + return found; +} diff --git a/src/kernel/code/v_dataReader.c b/src/kernel/code/v_dataReader.c index 136b78b45..a6f2a2c78 100644 --- a/src/kernel/code/v_dataReader.c +++ b/src/kernel/code/v_dataReader.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -43,7 +44,7 @@ #include "v__policy.h" #include "v__transaction.h" #include "v__orderedInstance.h" -#include "v_filter.h" +#include "v__participant.h" #include "v_dataReaderStatistics.h" #include "v_dataReaderEntry.h" #include "v_state.h" @@ -53,7 +54,6 @@ #include "v_group.h" #include "v_groupSet.h" #include "v_groupCache.h" -#include "v_participant.h" #include "v_topic.h" #include "v_partition.h" #include "v_qos.h" @@ -71,6 +71,10 @@ #include "q_helper.h" +/************************************************************** + * Instance set macros + **************************************************************/ + #define v_dataReaderAllInstanceSet(_this) \ (v_dataReader(_this)->index->objects) @@ -158,126 +162,42 @@ dataReaderLookupInstanceUnlocked( return found; } -static void -dataReaderEntrySubscribe( - void *o, - void *arg) -{ - v_partition p = v_partition(o); - v_dataReaderEntry e = v_dataReaderEntry(arg); - v_kernel kernel; - v_group g; - - assert(C_TYPECHECK(e,v_dataReaderEntry)); - assert(C_TYPECHECK(p,v_partition)); - - kernel = v_objectKernel(e); - if (kernel == NULL) { - OS_REPORT(OS_FATAL, - "kernel::v_dataReader::dataReaderEntrySubscribe", V_RESULT_INTERNAL_ERROR, - "Operation v_objectKernel(entity=0x%"PA_PRIxADDR") failed.", - (os_address)e); - } else { - g = v_groupSetCreate(kernel->groupSet,p,e->topic); - if (g == NULL) { - OS_REPORT(OS_CRITICAL, - "kernel::v_dataReader::dataReaderEntrySubscribe", V_RESULT_INTERNAL_ERROR, - "Operation v_groupSetCreate(groupSet=0x%"PA_PRIxADDR", partition=0x%"PA_PRIxADDR", topic=0x%"PA_PRIxADDR") failed.", - (os_address)kernel->groupSet, (os_address)p, (os_address)e->topic); - } else { - if(v_groupPartitionAccessMode(g) == V_ACCESS_MODE_READ_WRITE || - v_groupPartitionAccessMode(g) == V_ACCESS_MODE_READ) - { - v_groupAddEntry(g,v_entry(e)); - } - c_free(g); - } - } -} - -static void -dataReaderEntryUnSubscribe( - void *o, - void *arg) -{ - v_partition p = v_partition(o); - v_dataReaderEntry e = v_dataReaderEntry(arg); - v_kernel kernel; - v_group g; - c_value params[2]; - c_iter list; - - assert(C_TYPECHECK(e,v_dataReaderEntry)); - assert(C_TYPECHECK(p,v_partition)); - - params[0] = c_objectValue(p); - params[1] = c_objectValue(e->topic); - kernel = v_objectKernel(e); - list = v_groupSetSelect(kernel->groupSet, "partition = %0 and topic = %1", params); - while ((g = c_iterTakeFirst(list)) != NULL) { - v_groupRemoveEntry(g,v_entry(e)); - c_free(g); - } - c_iterFree(list); -} - struct onNewIndexArg { v_dataReader dataReader; q_expr _where; const c_value **params; + os_uint32 nrOfParams; }; -static void +static c_bool onNewIndex( v_index index, v_topic topic, c_voidp arg) { struct onNewIndexArg *a = (struct onNewIndexArg *)arg; - v_dataReaderEntry entry = NULL, found; - - entry = v_dataReaderEntryNew(a->dataReader, index, topic, a->_where, a->params); - if (entry != NULL) { - found = v_dataReaderAddEntry(a->dataReader,entry); - if (found == entry) { - entry->index = c_keep(index); - index->entry = entry; - } else { - OS_REPORT(OS_CRITICAL, - "kernel::v_dataReader::onNewIndex", V_RESULT_INTERNAL_ERROR, - "Operation v_dataReaderAddEntry(dataReader=0x%"PA_PRIxADDR", entry=0x%"PA_PRIxADDR") failed" - OS_REPORT_NL "Operation returned 0x%"PA_PRIxADDR" but expected 0x%"PA_PRIxADDR"", - (os_address)a->dataReader, (os_address)entry, (os_address)found, (os_address)entry); - } + v_dataReaderEntry entry; + + entry = v_dataReaderEntryNew(a->dataReader, topic, a->_where, a->params, a->nrOfParams); + if (entry) { + v_dataReaderAddEntry(a->dataReader,entry); + entry->index = c_keep(index); + index->entry = entry; c_free(entry); - c_free(found); + return TRUE; } else { - OS_REPORT(OS_CRITICAL, - "kernel::v_dataReader::onNewIndex", V_RESULT_INTERNAL_ERROR, - "Operation v_dataReaderEntryNew(dataReader=0x%"PA_PRIxADDR", topic=0x%"PA_PRIxADDR") failed.", - (os_address)a->dataReader, (os_address)topic); + return FALSE; } } -static c_bool -dataReaderEntryUpdatePurgeLists( - c_object o, - c_voidp arg) -{ - OS_UNUSED_ARG(arg); - v_dataReaderEntryUpdatePurgeLists(v_dataReaderEntry(o)); - return TRUE; /* process all other entries */ -} - -/* - * Precondition: dataReader is locked (v_dataReaderLock). - */ +/* Precondition: dataReader is locked (OSPL_LOCK). */ c_ulong -v_dataReaderInstanceCount( +v_dataReaderInstanceCount_nl( v_dataReader _this) { assert(C_TYPECHECK(_this,v_dataReader)); + OSPL_ASSERT_LOCK(_this); return c_tableCount(v_dataReaderAllInstanceSet(_this)); } @@ -287,17 +207,56 @@ v_dataReaderUpdatePurgeLists( v_dataReader _this) { assert(C_TYPECHECK(_this,v_dataReader)); + v_dataReaderEntryUpdatePurgeLists(_this->entry); +} - v_readerWalkEntries(v_reader(_this), dataReaderEntryUpdatePurgeLists, NULL); +void +v_dataReaderBeginAccess( + v_dataReader _this) +{ + assert(C_TYPECHECK(_this,v_dataReader)); + + OSPL_LOCK(_this); + _this->accessBusy = TRUE; + v_dataReaderEntryUpdatePurgeLists(_this->entry); + OSPL_UNLOCK(_this); +} + +static c_bool +flushPending( + c_object o, + c_voidp arg) +{ + v_dataReaderInstance instance = v_dataReaderInstance(o); + c_bool inNotEmptyList; + + OS_UNUSED_ARG(arg); + + inNotEmptyList = v_dataReaderInstanceInNotEmptyList(instance); + + v_dataReaderInstanceFlushPending(instance); + + if (!v_dataReaderInstanceEmpty(instance) && !inNotEmptyList) { + c_tableInsert(v_dataReaderInstanceReader(instance)->index->notEmptyList, instance); + v_dataReaderInstanceInNotEmptyList(instance) = TRUE; + } + + return TRUE; } void -v_dataReaderUpdatePurgeListsLocked( +v_dataReaderEndAccess( v_dataReader _this) { + assert(_this != NULL); assert(C_TYPECHECK(_this,v_dataReader)); - c_setWalk(v_reader(_this)->entrySet.entries, dataReaderEntryUpdatePurgeLists, NULL); + OSPL_LOCK(_this); + (void) c_tableWalk(v_dataReaderAllInstanceSet(_this), flushPending, NULL); + v_dataReaderUpdatePurgeLists(_this); + _this->accessBusy = FALSE; + + OSPL_UNLOCK(_this); } #ifdef _MSG_STAMP_ @@ -457,15 +416,15 @@ v_dataReaderNewBySQL ( const os_char *name, const os_char *expr, const c_value params[], - v_readerQos qos, - c_bool enable) + os_uint32 nrOfParams, + v_readerQos qos) { v_dataReader reader = NULL; q_expr OQLexpr; if (expr) { OQLexpr = v_parser_parse(expr); - reader = v_dataReaderNew(subscriber, name, OQLexpr, params, qos, enable); + reader = v_dataReaderNew(subscriber, name, OQLexpr, params, nrOfParams, qos); q_dispose(OQLexpr); } return reader; @@ -473,14 +432,13 @@ v_dataReaderNewBySQL ( v_dataReader v_dataReaderNew ( - v_subscriber subscriber, - const c_char *name, - q_expr OQLexpr, + _In_ v_subscriber subscriber, + _In_opt_z_ const c_char *name, + _In_opt_ q_expr OQLexpr, const c_value params[], - v_readerQos qos, - c_bool enable) + os_uint32 nrOfParams, + _In_opt_ v_readerQos qos) { - v_result result; v_kernel kernel; v_participant participant; v_dataReader _this, found; @@ -491,12 +449,14 @@ v_dataReaderNew ( c_property sampleProperty; c_long i; v_topic topic; + v_result result; if (name == NULL) { name = ""; } assert(C_TYPECHECK(subscriber,v_subscriber)); kernel = v_objectKernel(subscriber); + if (!q_isFnc(OQLexpr,Q_EXPR_PROGRAM)) { OS_REPORT(OS_ERROR, "kernel::v_dataReader::v_dataReaderNew",V_RESULT_INTERNAL_ERROR, @@ -514,6 +474,7 @@ v_dataReaderNew ( name, (os_address)OQLexpr); return NULL; } + _projection = NULL; _from = NULL; _where = NULL; @@ -543,11 +504,12 @@ v_dataReaderNew ( name, (os_address)OQLexpr); return NULL; } - topic = v_lookupTopic (kernel, q_getId(_from)); + /* ES, dds1576: Before creating the datareader we have to verify that read * access to the topic is allowed. We can accomplish this by checking the * access mode of the topic. */ + topic = v_lookupTopic (kernel, q_getId(_from)); if(!topic) { OS_REPORT(OS_ERROR, @@ -570,12 +532,13 @@ v_dataReaderNew ( } c_free(topic); topic = NULL; + if (v_readerQosCheck(qos) == V_RESULT_OK) { q = v_readerQosNew(kernel, qos); if (q == NULL) { OS_REPORT(OS_ERROR, "kernel::v_dataReader::v_dataReaderNew", V_RESULT_INTERNAL_ERROR, - "Creation of DataReader (name=\"%s\") failed. Cannot create writer QoS.", + "Creation of DataReader (name=\"%s\") failed. Cannot create reader QoS.", name); return NULL; } @@ -583,29 +546,28 @@ v_dataReaderNew ( return NULL; } - _this = v_dataReader(v_objectNew(kernel,K_DATAREADER)); - if (_this == NULL) { - OS_REPORT(OS_ERROR, - "kernel::v_dataReader::v_dataReaderNew", V_RESULT_ILL_PARAM, - "v_objectNew(kernel=0x%"PA_PRIxADDR" DataReader (name=\"%s\") not created: inconsistent qos", - (os_address)kernel, name); + if (q->share.v.enable && !subscriber->qos->share.v.enable){ + OS_REPORT(OS_ERROR, "kernel::v_dataReader::v_dataReaderNew", V_RESULT_PRECONDITION_NOT_MET, + "Datareader (name=\"%s\") not created." + OS_REPORT_NL "Can't create a shared reader in a non-shared subscriber.", + name); + c_free(q); return NULL; } + _this = v_dataReader(v_objectNew(kernel, K_DATAREADER)); + if (v_isEnabledStatistics(kernel, V_STATCAT_READER)) { _this->statistics = v_dataReaderStatisticsNew(kernel); - if (_this->statistics == NULL) { - OS_REPORT(OS_ERROR, - "kernel::v_dataReader::v_dataReaderNew", V_RESULT_INTERNAL_ERROR, - "Failed to create Statistics for DataReader (name=\"%s\").", - name); - assert(FALSE); - return NULL; - } - } else { - _this->statistics = NULL; } + v_readerInit(v_reader(_this), name, subscriber, q); + + /* Not really required to lock during creation as no other thread has acces yet. + * However to avoid warnings from static code analisys this lock is performed anyway. + */ + OSPL_LOCK(_this); + _this->shareCount = 1; _this->views = NULL; _this->resourceSampleCount = 0; @@ -614,35 +576,31 @@ v_dataReaderNew ( _this->triggerValue = NULL; _this->walkRequired = TRUE; _this->readCnt = 0; + _this->accessBusy = FALSE; /* temporary until set property is implemented */ _this->maximumSeparationTime = 0; if (qos) { _this->maximumSeparationTime = qos->pacing.v.minSeperation; } + OSPL_UNLOCK(_this); + #ifdef _MSG_STAMP_ v_dataReaderLogInit(_this); #endif - v_readerInit(v_reader(_this),name, subscriber, q, enable); - if (q->share.v.enable) { - if(!subscriber->qos->share.v.enable){ - OS_REPORT(OS_ERROR, - "kernel::v_dataReader::v_dataReaderNew", V_RESULT_INTERNAL_ERROR, - "Creating a shared dataReader in a non-shared subscriber."); - assert(FALSE); - } - v_subscriberLockShares(subscriber); - found = v_dataReader(v_subscriberAddShareUnsafe(subscriber,v_reader(_this))); + assert(subscriber->qos->share.v.enable); + found = v_subscriberAddShare(subscriber,_this); if (found != _this) { /* Existing shared DataReader so abort reader creation and * return existing DataReader. - */ - /* Make sure to set the index and deadline list to NULL, + * + * Make sure to set the index and deadline list to NULL, * because v_publicFree will cause a crash in the * v_dataReaderDeinit otherwise. */ + _this->entry = NULL; _this->index = NULL; _this->deadLineList = NULL; _this->minimumSeparationList = NULL; @@ -651,8 +609,6 @@ v_dataReaderNew ( v_publicFree(v_public(_this)); /*Now free the local reference as well.*/ c_free(_this); - found->shareCount++; - v_subscriberUnlockShares(subscriber); c_free(q); return c_keep(found); } @@ -662,95 +618,148 @@ v_dataReaderNew ( arg.dataReader = _this; arg._where = _where; arg.params = ¶ms; + arg.nrOfParams = nrOfParams; _this->index = v_indexNew(_this, _from, onNewIndex, &arg); - if (_this->index) { + if (_this->index != NULL) { + _this->entry = c_keep(_this->index->entry); instanceType = v_dataReaderInstanceType(_this); - sampleProperty = c_property(c_metaResolve(c_metaObject(instanceType), - "sample")); + sampleProperty = c_property(c_metaResolve(c_metaObject(instanceType), "sample")); c_free(instanceType); if (sampleProperty != NULL) { - _this->sampleType = c_keep (sampleProperty->type); - _this->projection = v_projectionNew(_this,_projection); - _this->orderedInstance = NULL; - - participant = v_participant(subscriber->participant); - assert(participant != NULL); - _this->deadLineList = v_deadLineInstanceListNew(c_getBase(c_object(_this)), - participant->leaseManager, - q->deadline.v.period, - V_LEASEACTION_READER_DEADLINE_MISSED, - v_public(_this)); - if (enable) { - result = v_dataReaderEnable(_this); - if (result != V_RESULT_OK) { - OS_REPORT(OS_ERROR, - "kernel::v_dataReader::v_dataReaderNew", result, - "Enable of DataReader (name=\"%s\") failed.", - name); - v_readerDeinit(v_reader(_this)); - c_free(_this); - _this = NULL; - } - } + result = V_RESULT_OK; } else { + result = V_RESULT_INTERNAL_ERROR; OS_REPORT(OS_ERROR, - "kernel::v_dataReader::v_dataReaderNew", V_RESULT_INTERNAL_ERROR, - "Creation of DataReader (name=\"%s\") failed." - OS_REPORT_NL "Operation c_metaResolve(scope=0x%"PA_PRIxADDR", \"sample\") failed.", - name, (os_address)instanceType); - v_readerDeinit(v_reader(_this)); - c_free(_this); - _this = NULL; + "kernel::v_dataReader::v_dataReaderNew", result, + "Creation of DataReader (name=\"%s\") failed: " + OS_REPORT_NL "Operation c_metaResolve(scope=0x%"PA_PRIxADDR", \"sample\") failed.", + name, (os_address)instanceType); } } else { + result = V_RESULT_INTERNAL_ERROR; OS_REPORT(OS_ERROR, - "kernel::v_dataReader::v_dataReaderNew", V_RESULT_INTERNAL_ERROR, - "Creation of DataReader (name=\"%s\") failed." - OS_REPORT_NL - "Operation v_indexNew(_this=0x%"PA_PRIxADDR", _from=0x%"PA_PRIxADDR", action=0x%"PA_PRIxADDR", arg=0x%"PA_PRIxADDR") failed.", - name, (os_address)_this, (os_address)_from, (os_address)onNewIndex, (os_address)&arg); + "kernel::v_dataReader::v_dataReaderNew", result, + "Creation of DataReader (name=\"%s\") failed: v_indexNew failed.", + name); + } + + if (result == V_RESULT_OK) { + _this->sampleType = c_keep (sampleProperty->type); + _this->projection = v_projectionNew(_this,_projection); + _this->orderedInstance = NULL; + + participant = v_participant(subscriber->participant); + assert(participant != NULL); + _this->deadLineList = v_deadLineInstanceListNew(c_getBase(c_object(_this)), + participant->leaseManager, + q->deadline.v.period, + V_LEASEACTION_READER_DEADLINE_MISSED, + v_public(_this)); + + result = v_subscriberAddReader (subscriber, v_reader (_this)); + } + + if (result != V_RESULT_OK) { v_readerDeinit(v_reader(_this)); c_free(_this); _this = NULL; } - if (q->share.v.enable) { - v_subscriberUnlockShares(subscriber); - } return _this; } +struct mp_arg_s { + const struct v_subscriptionInfo *info; + v_dataReaderEntry entry; + v_participant participant; +}; + +static os_boolean +getMatchingPublications( + const v_message publication, + void *arg) +{ + struct mp_arg_s *a = (struct mp_arg_s *)arg; + const struct v_publicationInfo *info = (struct v_publicationInfo *)(publication + 1); + + if ((strcmp(info->topic_name, a->info->topic_name) == 0) && + v_builtinTestPartitionMatch(info, a->info) && + v_builtinTestQosMatch(info, a->info)) + { + TRACE_IGNORE("DataReader::Enable: found matching publication GID: {%d, %d, %d}\n", + info->key.systemId, info->key.localId, info->key.serial); + /* Found a matching publication so now check with the particinant if it ought to be ignored! */ + if (v_participantCheckPublicationIgnored(a->participant, info) == OS_TRUE) { + v_dataReaderEntryIgnorePublication(a->entry, info); + } + } + return OS_TRUE; +} + +/* This operation is called during reader enable and initializes the readers ignore list by + * first lookup all matching (discovered) publications and the check if any are ignored according + * to the participant's ignore list. + */ +static void +initializeIgnoreList( + v_dataReader _this) +{ + v_kernel kernel; + v_message subscription; + struct mp_arg_s arg; + + kernel = v_objectKernel(_this); + subscription = v_dataReaderSubscription(_this); + if (subscription != NULL) { + arg.participant = v_subscriberParticipant(v_readerSubscriber(_this)); + if (arg.participant->ignore) { + arg.entry = _this->entry; + arg.info = (const struct v_subscriptionInfo *) (subscription + 1); + v_kernelWalkPublications(kernel, getMatchingPublications, &arg); + } + c_free(subscription); + } +} + v_result v_dataReaderEnable( - v_dataReader _this) + _Inout_ v_dataReader _this) { v_kernel kernel; - v_message builtinMsg, builtinCMMsg; + v_message builtinCMMsg; v_subscriber subscriber; v_result result = V_RESULT_OK; - if (_this) { - kernel = v_objectKernel(_this); - subscriber = v_subscriber(v_reader(_this)->subscriber); - result = v_subscriberAddReader (subscriber, v_reader (_this)); - if (result == V_RESULT_OK) { - builtinMsg = v_builtinCreateSubscriptionInfo(kernel->builtin, v_reader(_this)); - builtinCMMsg = v_builtinCreateCMDataReaderInfo(kernel->builtin, v_reader(_this)); - v_writeBuiltinTopic(kernel, V_SUBSCRIPTIONINFO_ID, builtinMsg); - v_writeBuiltinTopic(kernel, V_CMDATAREADERINFO_ID, builtinCMMsg); - c_free(builtinMsg); - c_free(builtinCMMsg); - - /* Trigger the durability client in spliced to send a historical data request - * for non-volatile readers in case the reader is not yet complete */ - if ((v_reader(_this)->qos->durability.v.kind != V_DURABILITY_VOLATILE)) { - (void) v_readerWaitForHistoricalData(v_reader(_this), OS_DURATION_ZERO); - } - } - } else { - result = V_RESULT_ILL_PARAM; + subscriber = v_subscriber(v_reader(_this)->subscriber); + kernel = v_objectKernel(_this); + + /* A datareader may be enabled if the subscriber is either enabling or enabled */ + if(v_entityDisabled(v_entity(subscriber))) { + /* DDS v1.4 $2.1.2.1.1.7: Calling enable on an Entity whose factory is + * not enabled will fail and return PRECONDITION_NOT_MET. + */ + return V_RESULT_PRECONDITION_NOT_MET; } + c_free(_this->subInfo); + _this->subInfo = v_builtinCreateSubscriptionInfo(kernel->builtin, v_reader(_this)); + builtinCMMsg = v_builtinCreateCMDataReaderInfo(kernel->builtin, v_reader(_this)); + + initializeIgnoreList(_this); + + result = v_subscriberEnableReader (subscriber, v_reader (_this)); + if (result == V_RESULT_OK) { + v_writeBuiltinTopic(kernel, V_SUBSCRIPTIONINFO_ID, _this->subInfo); + v_writeBuiltinTopic(kernel, V_CMDATAREADERINFO_ID, builtinCMMsg); + + /* Trigger the durability client in spliced to send a historical data request + * for non-volatile readers in case the reader is not yet complete + */ + if ((v_reader(_this)->qos->durability.v.kind != V_DURABILITY_VOLATILE)) { + (void) v_readerWaitForHistoricalData(v_reader(_this), OS_DURATION_ZERO, TRUE); + } + } + c_free(builtinCMMsg); return result; } @@ -770,12 +779,12 @@ v_dataReaderFree ( { v_message builtinMsg, builtinCMMsg; v_message unregisterMsg, unregisterCMMsg; - v_dataReader found; v_subscriber subscriber; v_kernel kernel; v_dataView view; c_iter views; c_bool userKey; + c_bool enabled = FALSE; assert(_this != NULL); assert(C_TYPECHECK(_this,v_dataReader)); @@ -784,19 +793,13 @@ v_dataReaderFree ( v_dataReaderLogReport(_this); #endif /* First create message, only at the end dispose. Applications expect - the disposed sample to be the last! - */ + * the disposed sample to be the last! + */ subscriber = v_subscriber(v_reader(_this)->subscriber); assert(subscriber); if (v_reader(_this)->qos->share.v.enable) { - v_subscriberLockShares(subscriber); - if(--_this->shareCount == 0){ - found = v_dataReader(v_subscriberRemoveShareUnsafe(subscriber,v_reader(_this))); - assert(found == _this); - c_free(found); - v_subscriberUnlockShares(subscriber); - } else { - v_subscriberUnlockShares(subscriber); + if (v_subscriberRemoveShare(subscriber,_this) > 0) { + /* Not the last reference, so not destroy yet */ return; } } @@ -809,8 +812,9 @@ v_dataReaderFree ( userKey = v_reader(_this)->qos->userKey.v.enable; v_readerFree(v_reader(_this)); - v_dataReaderLock(_this); + OSPL_LOCK(_this); + enabled = v__entityEnabled_nl(v_entity(_this)); v_orderedInstanceRemove(_this->orderedInstance, v_entity(_this)); if(_this->deadLineList){ @@ -842,12 +846,14 @@ v_dataReaderFree ( (void) c_tableWalk(v_dataReaderAllInstanceSet(_this), instanceFree, NULL); /* Always returns TRUE. */ } } - v_dataReaderUnlock(_this); + OSPL_UNLOCK(_this); - v_writeDisposeBuiltinTopic(kernel, V_SUBSCRIPTIONINFO_ID, builtinMsg); - v_writeDisposeBuiltinTopic(kernel, V_CMDATAREADERINFO_ID, builtinCMMsg); - v_unregisterBuiltinTopic(kernel, V_SUBSCRIPTIONINFO_ID, unregisterMsg); - v_unregisterBuiltinTopic(kernel, V_CMDATAREADERINFO_ID, unregisterCMMsg); + if (enabled) { + v_writeDisposeBuiltinTopic(kernel, V_SUBSCRIPTIONINFO_ID, builtinMsg); + v_writeDisposeBuiltinTopic(kernel, V_CMDATAREADERINFO_ID, builtinCMMsg); + v_unregisterBuiltinTopic(kernel, V_SUBSCRIPTIONINFO_ID, unregisterMsg); + v_unregisterBuiltinTopic(kernel, V_CMDATAREADERINFO_ID, unregisterCMMsg); + } c_free(builtinMsg); c_free(builtinCMMsg); c_free(unregisterMsg); @@ -910,7 +916,7 @@ v_dataReaderInsertView( assert(view != NULL); assert(C_TYPECHECK(view, v_dataView)); - v_dataReaderLock(_this); + OSPL_LOCK(_this); /* Create set if it does not exist yet */ if (_this->views == NULL) { base = c_getBase((c_object)_this); @@ -924,7 +930,7 @@ v_dataReaderInsertView( walkInstanceSamples, view); - v_dataReaderUnlock(_this); + OSPL_UNLOCK(_this); } void @@ -964,9 +970,9 @@ v_dataReaderRemoveView( assert(view != NULL); assert(C_TYPECHECK(view, v_dataView)); - v_dataReaderLock(_this); + OSPL_LOCK(_this); v_dataReaderRemoveViewUnsafe(_this, view); - v_dataReaderUnlock(_this); + OSPL_UNLOCK(_this); } C_STRUCT(readSampleArg) { @@ -1001,9 +1007,9 @@ v_dataReaderWalkInstances( c_bool proceed; if (_this != NULL) { - v_dataReaderLock(_this); + OSPL_LOCK(_this); proceed = v__dataReaderWalkInstances (_this, action, arg); - v_dataReaderUnlock(_this); + OSPL_UNLOCK(_this); } else { proceed = FALSE; OS_REPORT(OS_ERROR,"v_dataReaderWalkInstances",V_RESULT_ILL_PARAM, @@ -1165,15 +1171,12 @@ v__dataReaderOrderedReadOrTake ( } else { v_dataReaderInstanceSampleRemove(instance, sample, FALSE); } - + } if (v_actionResultTest (proceed, V_PROCEED)) { - if (v_subscriberAccessScope (v_readerSubscriber (_this)) - != V_PRESENTATION_GROUP) - { - sample = v_orderedInstanceReadSample ( - _this->orderedInstance, mask); + if (v_readerAccessScope(_this) != V_PRESENTATION_GROUP) { + sample = v_orderedInstanceReadSample(_this->orderedInstance, mask); } else { v_actionResultClear (proceed, V_PROCEED); } @@ -1194,13 +1197,12 @@ waitForData( os_duration *delay) { v_result result = V_RESULT_OK; - /* If no data read then wait for data or timeout. - */ + /* If no data read then wait for data or timeout. */ if (*delay > 0) { c_ulong flags = 0; os_timeE time = os_timeEGet(); - v__observerSetEvent(v_observer(_this), V_EVENT_DATA_AVAILABLE); - flags = v__observerTimedWait(v_observer(_this), *delay); + v_observerSetEvent(v_observer(_this), V_EVENT_DATA_AVAILABLE); + flags = OSPL_CATCH_EVENT(_this, *delay); if (flags & V_EVENT_TIMEOUT) { result = V_RESULT_TIMEOUT; } else { @@ -1232,16 +1234,20 @@ v_dataReaderRead( * between observer, entrySet and group locks with three different threads. */ - v_dataReaderLock(_this); + OSPL_LOCK(_this); + if(!v__entityEnabled_nl(v_entity(_this))) { + OSPL_UNLOCK(_this); + return V_RESULT_NOT_ENABLED; + } if (v_readerSubscriber(_this) == NULL) { - v_dataReaderUnlock(_this); + OSPL_UNLOCK(_this); return V_RESULT_ALREADY_DELETED; } - result = v_subscriberTestBeginAccess(v_readerSubscriber(_this)); + result = v_dataReaderAccessTest(_this); if (result == V_RESULT_OK) { _this->readCnt++; - if (v_subscriberAccessScope (v_readerSubscriber (_this)) != V_PRESENTATION_GROUP) { - v_dataReaderUpdatePurgeListsLocked(_this); + if (v_readerAccessScope(_this) != V_PRESENTATION_GROUP) { + v_dataReaderUpdatePurgeLists(_this); } if (v_orderedInstanceIsAligned (_this->orderedInstance)) { result = v__dataReaderOrderedReadOrTake(_this, mask, &v_dataReaderSampleRead, action, arg); @@ -1280,12 +1286,11 @@ v_dataReaderRead( } c_iterFree(argument.emptyList); if (_this->statistics) { - _this->statistics->numberOfInstances = v_dataReaderInstanceCount(_this); + _this->statistics->numberOfInstances = v_dataReaderInstanceCount_nl(_this); } } resetCommunicationStatusFlags(_this); - /* If no data read then wait for data or timeout. - */ + /* If no data read then wait for data or timeout. */ if (argument.count == 0) { result = waitForData(_this, &timeout); } @@ -1298,7 +1303,7 @@ v_dataReaderRead( _this->statistics->numberOfReads++; } } - v_dataReaderUnlock(_this); + OSPL_UNLOCK(_this); return result; } @@ -1347,12 +1352,16 @@ v_dataReaderReadInstance( } assert(C_TYPECHECK(instance, v_dataReaderInstance)); - v_dataReaderLock(_this); + OSPL_LOCK(_this); + if(!v__entityEnabled_nl(v_entity(_this))) { + OSPL_UNLOCK(_this); + return V_RESULT_NOT_ENABLED; + } if (v_readerSubscriber(_this) == NULL) { - v_dataReaderUnlock(_this); + OSPL_UNLOCK(_this); return V_RESULT_ALREADY_DELETED; } - result = v_subscriberTestBeginAccess(v_readerSubscriber(_this)); + result = v_dataReaderAccessTest(_this); if (result == V_RESULT_OK) { C_STRUCT(readSampleArg) argument; @@ -1369,7 +1378,7 @@ v_dataReaderReadInstance( while ((argument.count == 0) && (result == V_RESULT_OK)) { if (!v_dataReaderInstanceEmpty(instance)) { - v_dataReaderUpdatePurgeListsLocked(_this); + v_dataReaderUpdatePurgeLists(_this); (void)v_dataReaderInstanceReadSamples(instance,NULL,mask, (v_readerSampleAction)instanceSampleAction, &argument); @@ -1378,8 +1387,7 @@ v_dataReaderReadInstance( v_dataReaderRemoveInstance(_this,instance); } } - /* If no data read then wait for data or timeout. - */ + /* If no data read then wait for data or timeout. */ if (argument.count == 0) { result = waitForData(_this, &timeout); } @@ -1390,7 +1398,7 @@ v_dataReaderReadInstance( _this->statistics->numberOfInstanceReads++; } } - v_dataReaderUnlock(_this); + OSPL_UNLOCK(_this); return result; } @@ -1405,7 +1413,7 @@ v_dataReaderReadNextInstance( os_duration timeout) { v_result result = V_RESULT_OK; - v_dataReaderInstance cur; + v_dataReaderInstance cur, next; assert(_this != NULL); assert(C_TYPECHECK(_this, v_dataReader)); @@ -1417,12 +1425,16 @@ v_dataReaderReadNextInstance( return V_RESULT_ILL_PARAM; } assert(C_TYPECHECK(instance, v_dataReaderInstance)); - v_dataReaderLock(_this); + OSPL_LOCK(_this); + if(!v__entityEnabled_nl(v_entity(_this))) { + OSPL_UNLOCK(_this); + return V_RESULT_NOT_ENABLED; + } if (v_readerSubscriber(_this) == NULL) { - v_dataReaderUnlock(_this); + OSPL_UNLOCK(_this); return V_RESULT_ALREADY_DELETED; } - result = v_subscriberTestBeginAccess(v_readerSubscriber(_this)); + result = v_dataReaderAccessTest(_this); if (result == V_RESULT_OK) { C_STRUCT(readSampleArg) argument; @@ -1437,32 +1449,41 @@ v_dataReaderReadNextInstance( _this->readCnt++; - v_dataReaderUpdatePurgeListsLocked(_this); + v_dataReaderUpdatePurgeLists(_this); cur = v_dataReaderNextInstance(_this,instance); - while (argument.count == 0 && result == V_RESULT_OK) + result = V_RESULT_NO_DATA; + while (cur != NULL && result == V_RESULT_NO_DATA) { - while (cur && v_dataReaderInstanceEmpty(cur)) { - v_dataReaderInstance next = v_dataReaderNextInstance(_this,cur); + next = v_dataReaderNextInstance(_this,cur); + if (v_dataReaderInstanceEmpty(cur)) { v_dataReaderRemoveInstance(_this,cur); - cur = next; - } - if (cur) { + } else { (void)v_dataReaderInstanceReadSamples(cur, NULL,mask, (v_readerSampleAction)instanceSampleAction, &argument); - } - /* If no data read then wait for data or timeout. - */ - if (argument.count == 0) { - if (cur == NULL) { - result = waitForData(_this, &timeout); - if (result == V_RESULT_OK) { - cur = v_dataReaderNextInstance(_this,instance); + if (v_dataReaderInstanceEmpty(cur)) { + v_dataReaderRemoveInstance(_this,cur); + } + /* If no data read then wait for data or timeout. + */ + if (argument.count == 0) { + if (next == NULL) { + /* No data was availabile so block until data becomes available or timeout. + */ + result = waitForData(_this, &timeout); + if (result == V_RESULT_OK) { + /* After initial read without data, data has arrived before timeout. + * so start reading from start again. + */ + next = v_dataReaderNextInstance(_this,instance); + result = V_RESULT_NO_DATA; + } } } else { - cur = v_dataReaderNextInstance(_this,cur); + result = V_RESULT_OK; } } + cur = next; } /* Now trigger the action routine that the last sample is read. */ action(NULL,arg); @@ -1472,7 +1493,7 @@ v_dataReaderReadNextInstance( _this->statistics->numberOfNextInstanceReads++; } } - v_dataReaderUnlock(_this); + OSPL_UNLOCK(_this); return result; } @@ -1503,26 +1524,11 @@ instanceTakeSamples( a->reader->statistics->numberOfSamplesTaken += (c_ulong) a->count; } -#if 1 - /* This code snippet is functionally correct, but in typical - * pingpong like scenario'sit might result in the same instance - * being inserted and removed from the non-emptyList continuously. - * So postponing the decision to move the instance around can be - * seen as an optimization for these pingpong like scenario's. - * - * So this snippet of code intends to avoid leakage, but is also - * executed by other functions that operate on the v_dataReaderInstance. - * So if we don't clean-up the instance now, it will be done in - * a more lazy manner by subsequent operations on the same - * v_dataReaderInstance. - * - * Code like this can permanently be deleted as soon as active - * garbage collection is implemented (scdds1817) - */ - if (v_dataReaderInstanceEmpty(instance)) { + /* If the instance is empty and has no active writers, it may be purged */ + if (v_dataReaderInstanceEmpty(instance) && (instance->liveliness == 0)) { a->emptyList = c_iterInsert(a->emptyList,c_keep(instance)); } -#endif + return proceed; } @@ -1625,16 +1631,20 @@ v_dataReaderTake( assert(_this != NULL); assert(C_TYPECHECK(_this, v_dataReader)); - v_dataReaderLock(_this); + OSPL_LOCK(_this); + if(!v__entityEnabled_nl(v_entity(_this))) { + OSPL_UNLOCK(_this); + return V_RESULT_NOT_ENABLED; + } if (v_readerSubscriber(_this) == NULL) { - v_dataReaderUnlock(_this); + OSPL_UNLOCK(_this); return V_RESULT_ALREADY_DELETED; } - result = v_subscriberTestBeginAccess(v_readerSubscriber(_this)); + result = v_dataReaderAccessTest(_this); if (result == V_RESULT_OK) { _this->readCnt++; - if (v_subscriberAccessScope (v_readerSubscriber (_this)) != V_PRESENTATION_GROUP) { - v_dataReaderUpdatePurgeListsLocked(_this); + if (v_readerAccessScope(_this) != V_PRESENTATION_GROUP) { + v_dataReaderUpdatePurgeLists(_this); } if (v_orderedInstanceIsAligned (_this->orderedInstance)) { result = v__dataReaderOrderedReadOrTake ( @@ -1669,12 +1679,11 @@ v_dataReaderTake( } c_iterFree(argument.emptyList); if (_this->statistics) { - _this->statistics->numberOfInstances = v_dataReaderInstanceCount(_this); + _this->statistics->numberOfInstances = v_dataReaderInstanceCount_nl(_this); } } resetCommunicationStatusFlags(_this); - /* If no data read then wait for data or timeout. - */ + /* If no data read then wait for data or timeout. */ if (argument.count == 0) { result = waitForData(_this, &timeout); } @@ -1687,7 +1696,7 @@ v_dataReaderTake( _this->statistics->numberOfTakes++; } } - v_dataReaderUnlock(_this); + OSPL_UNLOCK(_this); return result; } @@ -1716,12 +1725,16 @@ v_dataReaderTakeInstance( } assert(C_TYPECHECK(instance, v_dataReaderInstance)); - v_dataReaderLock(_this); + OSPL_LOCK(_this); + if(!v__entityEnabled_nl(v_entity(_this))) { + OSPL_UNLOCK(_this); + return V_RESULT_NOT_ENABLED; + } if (v_readerSubscriber(_this) == NULL) { - v_dataReaderUnlock(_this); + OSPL_UNLOCK(_this); return V_RESULT_ALREADY_DELETED; } - result = v_subscriberTestBeginAccess(v_readerSubscriber(_this)); + result = v_dataReaderAccessTest(_this); if (result == V_RESULT_OK) { C_STRUCT(readSampleArg) argument; @@ -1738,7 +1751,7 @@ v_dataReaderTakeInstance( while ((argument.count == 0) && (result == V_RESULT_OK)) { if (!v_dataReaderInstanceEmpty(instance)) { - v_dataReaderUpdatePurgeListsLocked(_this); + v_dataReaderUpdatePurgeLists(_this); (void)v_dataReaderInstanceTakeSamples(instance,NULL,mask, (v_readerSampleAction)instanceSampleAction, &argument); @@ -1757,8 +1770,7 @@ v_dataReaderTakeInstance( v_dataReaderRemoveInstance(_this,instance); } - /* If no data read then wait for data or timeout. - */ + /* If no data read then wait for data or timeout. */ if (argument.count == 0) { result = waitForData(_this, &timeout); } @@ -1769,7 +1781,7 @@ v_dataReaderTakeInstance( _this->statistics->numberOfInstanceTakes++; } } - v_dataReaderUnlock(_this); + OSPL_UNLOCK(_this); return result; } @@ -1784,7 +1796,7 @@ v_dataReaderTakeNextInstance( os_duration timeout) { v_result result = V_RESULT_OK; - v_dataReaderInstance cur; + v_dataReaderInstance cur, next; assert(_this != NULL); assert(C_TYPECHECK(_this, v_dataReader)); @@ -1795,12 +1807,16 @@ v_dataReaderTakeNextInstance( return V_RESULT_ILL_PARAM; } assert(C_TYPECHECK(instance, v_dataReaderInstance)); - v_dataReaderLock(_this); + OSPL_LOCK(_this); + if(!v__entityEnabled_nl(v_entity(_this))) { + OSPL_UNLOCK(_this); + return V_RESULT_NOT_ENABLED; + } if (v_readerSubscriber(_this) == NULL) { - v_dataReaderUnlock(_this); + OSPL_UNLOCK(_this); return V_RESULT_ALREADY_DELETED; } - result = v_subscriberTestBeginAccess(v_readerSubscriber(_this)); + result = v_dataReaderAccessTest(_this); if (result == V_RESULT_OK) { C_STRUCT(readSampleArg) argument; @@ -1810,53 +1826,52 @@ v_dataReaderTakeNextInstance( argument.arg = arg; argument.query = NULL; argument.count = 0; - v_orderedInstanceUnaligned (_this->orderedInstance); - _this->readCnt++; - - v_dataReaderUpdatePurgeListsLocked(_this); + v_dataReaderUpdatePurgeLists(_this); cur = v_dataReaderNextInstance(_this,instance); - while (argument.count == 0 && result == V_RESULT_OK) + result = V_RESULT_NO_DATA; + while (cur != NULL && result == V_RESULT_NO_DATA) { - while (cur && v_dataReaderInstanceEmpty(cur)) { - v_dataReaderInstance next = v_dataReaderNextInstance(_this,cur); + next = v_dataReaderNextInstance(_this,cur); + if (v_dataReaderInstanceEmpty(cur)) { v_dataReaderRemoveInstance(_this,cur); - cur = next; - } - if (cur) { + } else { (void)v_dataReaderInstanceTakeSamples(cur, NULL, mask, (v_readerSampleAction)instanceSampleAction, &argument); - if (argument.count > 0) { - assert(_this->resourceSampleCount >= 0); - if (v_dataReaderInstanceEmpty(cur)) { - v_dataReaderRemoveInstance(_this,cur); - } + if (v_dataReaderInstanceEmpty(cur)) { + v_dataReaderRemoveInstance(_this,cur); } - } - /* If no data read then wait for data or timeout. - */ - if (argument.count == 0) { - if (cur == NULL) { - result = waitForData(_this, &timeout); - if (result == V_RESULT_OK) { - cur = v_dataReaderNextInstance(_this,instance); + /* If no data read then wait for data or timeout. */ + if (argument.count == 0) { + if (next == NULL) { + /* No data was availabile so block until data becomes available or timeout. */ + result = waitForData(_this, &timeout); + if (result == V_RESULT_OK) { + /* After initial read without data, data has arrived before timeout. + * so start reading from start again. + */ + next = v_dataReaderNextInstance(_this,instance); + result = V_RESULT_NO_DATA; + } } } else { - cur = v_dataReaderNextInstance(_this,cur); + result = V_RESULT_OK; } } + cur = next; } - resetCommunicationStatusFlags(_this); - + /* Now trigger the action routine that the last sample is read. */ action(NULL,arg); + resetCommunicationStatusFlags(_this); + if (_this->statistics) { _this->statistics->numberOfNextInstanceTakes++; } } - v_dataReaderUnlock(_this); + OSPL_UNLOCK(_this); return result; } @@ -1874,33 +1889,26 @@ v_dataReaderNotify( * calling Notify(_this, event, userData). * This implies that _this cannot be locked within any Notify method * to avoid deadlocks. - * For consistency _this must be locked by v_observerLock(_this) before + * For consistency _this must be locked by OSPL_LOCK(_this) before * calling this method. */ assert(_this != NULL); assert(C_TYPECHECK(_this, v_dataReader)); + assert(event != NULL); OS_UNUSED_ARG(userData); - if (event != NULL) { - #define _NOTIFICATION_MASK_ \ - V_EVENT_INCONSISTENT_TOPIC | \ V_EVENT_SAMPLE_REJECTED | \ V_EVENT_SAMPLE_LOST | \ - V_EVENT_OFFERED_DEADLINE_MISSED | \ V_EVENT_REQUESTED_DEADLINE_MISSED | \ - V_EVENT_OFFERED_INCOMPATIBLE_QOS | \ V_EVENT_REQUESTED_INCOMPATIBLE_QOS | \ - V_EVENT_PUBLICATION_MATCHED | \ V_EVENT_SUBSCRIPTION_MATCHED | \ V_EVENT_LIVELINESS_CHANGED | \ - V_EVENT_DATA_AVAILABLE | \ - V_EVENT_ALL_DATA_DISPOSED + V_EVENT_DATA_AVAILABLE - v_entity(_this)->status->state |= (event->kind & (_NOTIFICATION_MASK_)); + v_entity(_this)->status->state |= (event->kind & (_NOTIFICATION_MASK_)); #undef _NOTIFICATION_MASK_ - } } static c_bool @@ -1908,48 +1916,20 @@ queryNotifyDataAvailable( c_object query, c_voidp arg) { - v_query q = v_query(query); v_event event = (v_event)arg; - if (v_observableHasObservers(v_observable(q)) || - (v_entity(q)->listener != NULL)) - { - event->source = v_observable(query); - v_dataReaderQueryNotifyDataAvailable(v_dataReaderQuery(query),event); - } else { - v_dataReaderQuery(query)->walkRequired = TRUE; - } + event->source = v_observable(query); + v_dataReaderQueryNotifyDataAvailable(v_dataReaderQuery(query),event); return TRUE; } -void -v_dataReaderTrigger( - v_dataReader _this) -{ - if (_this) { - v_dataReaderLock(_this); - v_dataReaderNotifyDataAvailable(_this, NULL); - v_dataReaderUnlock(_this); - } -} - -void -v_dataReaderTriggerNoLock( - v_dataReader _this) -{ - if (_this) { - v_dataReaderNotifyDataAvailable(_this, NULL); - } -} - void v_dataReaderNotifyDataAvailable( v_dataReader _this, v_dataReaderSample sample) { C_STRUCT(v_event) event; - c_bool handled; assert(_this != NULL); assert(C_TYPECHECK(_this,v_dataReader)); @@ -1957,7 +1937,7 @@ v_dataReaderNotifyDataAvailable( EVENT_TRACE("v_dataReaderNotifyDataAvailable(_this = 0x%x, sample = 0x%x)\n", _this, sample); - v_entity(_this)->status->state |= V_EVENT_DATA_AVAILABLE; + v_statusNotifyDataAvailable(v_entity(_this)->status); if (_this->triggerValue) { v_dataReaderTriggerValueFree(_this->triggerValue); @@ -1981,28 +1961,28 @@ v_dataReaderNotifyDataAvailable( c_setWalk(v_collection(_this)->queries, queryNotifyDataAvailable, &event); } - /* Now notify all other observers and listeners. */ - /* Also notify myself, since the user reader might be waiting. */ + /* Now notify all other observers and listeners. + * Also notify myself, since the user reader might be waiting. + */ event.source = v_observable(_this); - handled = v_entityNotifyListener(v_entity(_this), &event); - if (!handled) { - v_observableNotify(v_observable(_this), &event); + event.handled = v_entityNotifyListener(v_entity(_this), &event); + if (!event.handled) { if (v_reader(_this)->subscriber) { v_subscriberNotifyDataAvailable(v_reader(_this)->subscriber,NULL); } } - if (event.kind & v_observer(_this)->eventMask) { - v_observerNotify(v_observer(_this), &event, NULL); + OSPL_TRIGGER_EVENT(_this, &event, NULL); + if (!event.handled) { + OSPL_THROW_EVENT(_this, &event); } } void -v_dataReaderNotifySampleLost( +v_dataReaderNotifySampleLost_nl( v_dataReader _this, c_ulong nrSamplesLost) { - c_bool handled; C_STRUCT(v_event) event; assert(_this != NULL); @@ -2017,23 +1997,23 @@ v_dataReaderNotifySampleLost( event.kind = V_EVENT_SAMPLE_LOST; event.source = v_observable(_this); event.data = NULL; - handled = v_entityNotifyListener(v_entity(_this), &event); - if (!handled) { - v_observableNotify(v_observable(_this), &event); + event.handled = v_entityNotifyListener(v_entity(_this), &event); + if (!event.handled) { + OSPL_THROW_EVENT(_this, &event); } } void -v_dataReaderNotifySampleLostLock( +v_dataReaderNotifySampleLost( v_dataReader _this, c_ulong nrSamplesLost) { assert(_this != NULL); assert(C_TYPECHECK(_this,v_dataReader)); - v_dataReaderLock(_this); - v_dataReaderNotifySampleLost(_this, nrSamplesLost); - v_dataReaderUnlock(_this); + OSPL_LOCK(_this); + v_dataReaderNotifySampleLost_nl(_this, nrSamplesLost); + OSPL_UNLOCK(_this); } void @@ -2042,7 +2022,6 @@ v_dataReaderNotifySampleRejected( v_sampleRejectedKind kind, v_gid instanceHandle) { - c_bool handled; C_STRUCT(v_event) event; assert(_this != NULL); @@ -2054,9 +2033,9 @@ v_dataReaderNotifySampleRejected( event.kind = V_EVENT_SAMPLE_REJECTED; event.source = v_observable(_this); event.data = NULL; - handled = v_entityNotifyListener(v_entity(_this), &event); - if (!handled) { - v_observableNotify(v_observable(_this), &event); + event.handled = v_entityNotifyListener(v_entity(_this), &event); + if (!event.handled) { + OSPL_THROW_EVENT(_this, &event); } } @@ -2066,14 +2045,13 @@ v_dataReaderNotifyIncompatibleQos( v_policyId id, v_gid writerGID) { - c_bool handled; C_STRUCT(v_event) event; OS_UNUSED_ARG(writerGID); assert(_this != NULL); assert(C_TYPECHECK(_this,v_dataReader)); - v_observerLock(v_observer(_this)); + OSPL_LOCK(_this); v_statusNotifyRequestedIncompatibleQos(v_entity(_this)->status, id); @@ -2081,12 +2059,11 @@ v_dataReaderNotifyIncompatibleQos( event.kind = V_EVENT_REQUESTED_INCOMPATIBLE_QOS; event.source = v_observable(_this); event.data = NULL; - handled = v_entityNotifyListener(v_entity(_this), &event); - if (!handled) { - v_observableNotify(v_observable(_this), &event); + event.handled = v_entityNotifyListener(v_entity(_this), &event); + if (!event.handled) { + OSPL_THROW_EVENT(_this, &event); } - - v_observerUnlock(v_observer(_this)); + OSPL_UNLOCK(_this); } struct updateTransactionsArg { @@ -2095,17 +2072,6 @@ struct updateTransactionsArg { struct v_publicationInfo *publicationInfo; }; -static c_bool -lookupEntries( - c_object o, - c_voidp arg) -{ - c_iter *list = (c_iter *)arg; - - *list = c_iterInsert(*list, o); - return TRUE; -} - void v_dataReaderNotifySubscriptionMatched ( v_dataReader _this, @@ -2114,79 +2080,36 @@ v_dataReaderNotifySubscriptionMatched ( struct v_publicationInfo *publicationInfo, c_bool isImplicit) { - c_bool handled; C_STRUCT(v_event) event; - v_dataReaderEntry entry = NULL; - c_iter list = NULL; v_subscriber subscriber; - c_bool complete = FALSE; + c_bool flush = FALSE; assert(_this != NULL); assert(C_TYPECHECK(_this,v_dataReader)); - v_dataReaderLock(_this); + OSPL_LOCK(_this); subscriber = v_readerSubscriber(v_reader(_this)); if (subscriber) { if (v_reader(_this)->subQos->presentation.v.coherent_access) { - (void)v_readerWalkEntries(v_reader(_this), lookupEntries, &list); - /* A DataReader currently only has one entry, assert added to detect if - * this has changed. - */ - assert(c_iterLength(list) == 1); - entry = v_dataReaderEntry(c_iterTakeFirst(list)); - if (entry) { - complete = v_transactionAdminNotifyPublication(entry->transactionAdmin, - writerGID, - dispose, - publicationInfo, - isImplicit); + if (_this->entry) { + flush = v_transactionAdminNotifyPublication(_this->entry->transactionAdmin, writerGID, + dispose, publicationInfo, isImplicit); } } v_statusNotifySubscriptionMatched(v_entity(_this)->status, writerGID, dispose); event.kind = V_EVENT_SUBSCRIPTION_MATCHED; event.source = v_observable(_this); event.data = NULL; - handled = v_entityNotifyListener(v_entity(_this), &event); - if (!handled) { - v_observableNotify(v_observable(_this), &event); + event.handled = v_entityNotifyListener(v_entity(_this), &event); + if (!event.handled) { + OSPL_THROW_EVENT(_this, &event); } - if (complete && v__readerIsGroupCoherent(v_reader(_this))) { - v_subscriberTriggerGroupCoherent(subscriber, v_reader(_this)); - } } - - v_dataReaderUnlock(_this); - c_iterFree(list); -} - -static c_bool -updateConnections( - c_object o, - c_voidp arg) -{ - v_dataReaderEntry e = v_dataReaderEntry(o); - v_dataReaderConnectionChanges *a = (v_dataReaderConnectionChanges *)arg; - - c_iterWalk(a->addedPartitions, dataReaderEntrySubscribe, e); - c_iterWalk(a->removedPartitions, dataReaderEntryUnSubscribe, e); - - return TRUE; -} - -/* only called by v_subscriberSetQos() and v_readerSetQos(). */ -void -v_dataReaderUpdateConnections( - v_dataReader _this, - v_dataReaderConnectionChanges *arg) -{ - assert(_this != NULL); - assert(C_TYPECHECK(_this,v_dataReader)); - - if ((arg != NULL) && - ((arg->addedPartitions != NULL) || (arg->removedPartitions != NULL))) { - /* partition policy has changed */ - v_readerWalkEntries(v_reader(_this), updateConnections, arg); + OSPL_UNLOCK(_this); + if (flush ) { + /* Removal of a reader could complete a transaction */ + v_subscriberGroupTransactionFlush(subscriber); } } @@ -2195,38 +2118,26 @@ void v_dataReaderNotifyChangedQos( v_dataReader _this) { - v_kernel kernel; - v_message builtinMsg, builtinCMMsg; + v_kernel kernel = NULL; + v_message builtinMsg = NULL; + v_message builtinCMMsg = NULL; assert(_this != NULL); assert(C_TYPECHECK(_this,v_dataReader)); /* publish subscription info */ - v_dataReaderLock(_this); + OSPL_LOCK(_this); - if (v_entity(_this)->enabled) { + if (v__entityEnabled_nl(v_entity(_this))) { kernel = v_objectKernel(_this); - builtinMsg = v_builtinCreateSubscriptionInfo(kernel->builtin, v_reader(_this)); + c_free(_this->subInfo); + _this->subInfo = v_builtinCreateSubscriptionInfo(kernel->builtin, v_reader(_this)); + builtinMsg = c_keep(_this->subInfo); builtinCMMsg = v_builtinCreateCMDataReaderInfo(kernel->builtin, v_reader(_this)); - } else { - kernel = NULL; - builtinMsg = NULL; - builtinCMMsg = NULL; } v_deadLineInstanceListSetDuration(_this->deadLineList, v_reader(_this)->qos->deadline.v.period); - - if ((v_reader(_this)->subQos->presentation.v.coherent_access) && - (v_reader(_this)->subQos->presentation.v.access_scope == V_PRESENTATION_GROUP)) { - v_transactionGroupAdmin groupAdmin = NULL; - v_subscriber s = v_subscriber(v_reader(_this)->subscriber); - groupAdmin = v_subscriberLookupTransactionGroupAdmin(s); - assert(groupAdmin); - - v_transactionGroupAdminUpdateReader(groupAdmin, v_reader(_this)); - } - - v_dataReaderUnlock(_this); + OSPL_UNLOCK(_this); if (builtinMsg) { v_writeBuiltinTopic(kernel, V_SUBSCRIPTIONINFO_ID, builtinMsg); @@ -2247,8 +2158,6 @@ v_dataReaderNotifyLivelinessChanged( enum v_statusLiveliness newLivState, v_message publicationInfo) { - c_bool handled; - OS_UNUSED_ARG(publicationInfo); assert(_this != NULL); assert(C_TYPECHECK(_this,v_dataReader)); @@ -2258,7 +2167,7 @@ v_dataReaderNotifyLivelinessChanged( if (oldLivState != newLivState) { c_bool genEvent = 1; - v_dataReaderLock(_this); + OSPL_LOCK(_this); /** * Transition table: * @@ -2346,13 +2255,13 @@ v_dataReaderNotifyLivelinessChanged( event.kind = V_EVENT_LIVELINESS_CHANGED; event.source = v_observable(_this); event.data = NULL; - handled = v_entityNotifyListener(v_entity(_this), &event); - if (!handled) { - v_observableNotify(v_observable(_this), &event); + event.handled = v_entityNotifyListener(v_entity(_this), &event); + if (!event.handled) { + OSPL_THROW_EVENT(_this, &event); } } - v_dataReaderUnlock(_this); + OSPL_UNLOCK(_this); } } @@ -2361,13 +2270,20 @@ v__dataReaderNotifyOwnershipStrengthChangedCallback ( c_object obj, c_voidp arg) { - assert (C_TYPECHECK (obj, v_dataReaderInstance)); - assert (arg != NULL); + v_dataReaderInstance readerInst = v_dataReaderInstance (obj); + struct v_owner *candidate = (struct v_owner *)arg; - (void)v_determineOwnershipByStrength ( - &(v_dataReaderInstance (obj)->owner), - (struct v_owner *)(arg), - (v_dataReaderInstance (obj)->liveliness > 0)); + assert (candidate != NULL); + + /* First determine whether the writer changing its strength is actually the current owner. + * If not, then no change is necessary. If it is, and the strength got lowered, then lower + * the recorded strength as well. Increasing strength will not automatically be recorded: + * that will happen upon arrival of the first sample with the increased strength. + */ + if ((v_gidCompare (readerInst->owner.gid, candidate->gid) == C_EQ) + && readerInst->owner.strength > candidate->strength) { + readerInst->owner.strength = candidate->strength; + } return TRUE; } @@ -2380,12 +2296,12 @@ v_dataReaderNotifyOwnershipStrengthChanged ( assert (C_TYPECHECK (_this, v_dataReader)); assert (ownership != NULL); - v_dataReaderLock(_this); + OSPL_LOCK(_this); (void)c_tableWalk ( v_dataReaderAllInstanceSet (_this), &v__dataReaderNotifyOwnershipStrengthChangedCallback, ownership); - v_dataReaderUnlock(_this); + OSPL_UNLOCK(_this); } c_type @@ -2462,142 +2378,14 @@ v_dataReaderField( return field; } -c_bool -v_dataReaderSubscribe( - v_dataReader _this, - v_partition p) -{ - c_iter list; - v_dataReaderEntry entry; - - assert(C_TYPECHECK(_this,v_dataReader)); - - v_dataReaderLock(_this); - list = v_readerCollectEntries(v_reader(_this)); - v_dataReaderUnlock(_this); - while ((entry = v_dataReaderEntry(c_iterTakeFirst(list)))) { - dataReaderEntrySubscribe(p, entry); - c_free(entry); - } - c_iterFree(list); - return TRUE; -} - -static c_bool -dataReaderEntrySubscribeGroup( - c_object o, - c_voidp arg) -{ - v_dataReaderEntry entry = v_dataReaderEntry(o); - v_group group = v_group(arg); - - assert(C_TYPECHECK(entry,v_entry)); - assert(C_TYPECHECK(group,v_group)); - - if (group->topic == entry->topic) { - v_groupAddEntry(group, v_entry(entry)); - } - return TRUE; -} - -c_bool -v_dataReaderSubscribeGroup( - v_dataReader _this, - v_group group) -{ - c_bool result; - - assert(C_TYPECHECK(_this, v_dataReader)); - - result = v_readerWalkEntries(v_reader(_this), - dataReaderEntrySubscribeGroup, - group); - return result; -} - -c_bool -v_dataReaderUnSubscribe( - v_dataReader _this, - v_partition p) -{ - c_iter list; - v_dataReaderEntry entry; - - assert(C_TYPECHECK(_this,v_dataReader)); - - v_dataReaderLock(_this); - list = v_readerCollectEntries(v_reader(_this)); - v_dataReaderUnlock(_this); - while ((entry = v_dataReaderEntry(c_iterTakeFirst(list)))) { - dataReaderEntryUnSubscribe(p, entry); - c_free(entry); - } - c_iterFree(list); - return TRUE; -} - -static c_bool -dataReaderEntryUnSubscribeGroup( - c_object o, - c_voidp arg) -{ - v_dataReaderEntry entry = v_dataReaderEntry(o); - v_group group = v_group(arg); - - v_groupRemoveEntry(group, v_entry(entry)); - - return TRUE; -} - -c_bool -v_dataReaderUnSubscribeGroup( - v_dataReader _this, - v_group group) -{ - assert(C_TYPECHECK(_this, v_reader)); - - return v_readerWalkEntries(v_reader(_this), - dataReaderEntryUnSubscribeGroup, - group); -} - - -static c_bool -getTopic ( - c_object o, - c_voidp arg) -{ - v_dataReaderEntry entry = v_dataReaderEntry(o); - v_topic *topic = (v_topic *)arg; - c_bool result = TRUE; - - if (*topic == NULL) { - *topic = c_keep(entry->topic); - } else { - /* Already a topic was found so this must be a Multi Topic reader. - * In that case abort and clear the topic. - * Multi Topics are not yet supported by v_builtin. - * Even Worse: The spec doesn't support builtin definition for - * Multi Topics. - */ - c_free(*topic); - *topic = NULL; - result = FALSE; - } - return result; -} - +_Check_return_ +_Ret_maybenull_ v_topic v_dataReaderGetTopic( v_dataReader _this) { - v_topic topic; assert(C_TYPECHECK(_this,v_dataReader)); - - topic = NULL; - v_readerWalkEntries(v_reader(_this), getTopic, &topic); - - return c_keep(topic); + return c_keep(_this->entry->topic); } v_dataReaderInstance @@ -2610,12 +2398,16 @@ v_dataReaderLookupInstance( assert(C_TYPECHECK(_this,v_dataReader)); assert(C_TYPECHECK(keyTemplate,v_message)); - v_dataReaderLock(_this); + OSPL_LOCK(_this); + if(!v__entityEnabled_nl(v_entity(_this))) { + OSPL_UNLOCK(_this); + return NULL; + } found = dataReaderLookupInstanceUnlocked(_this, keyTemplate); if (_this->statistics) { _this->statistics->numberOfInstanceLookups++; } - v_dataReaderUnlock(_this); + OSPL_UNLOCK(_this); return found; } @@ -2649,13 +2441,13 @@ v_dataReaderCheckDeadlineMissed( C_STRUCT(v_event) event; c_iter missed; v_dataReaderInstance instance; - c_bool handled = TRUE; event.kind = V_EVENT_REQUESTED_DEADLINE_MISSED; event.source = v_observable(_this); event.data = NULL; + event.handled = TRUE; - v_dataReaderLock(_this); + OSPL_LOCK(_this); missed = v_deadLineInstanceListCheckDeadlineMissed(_this->deadLineList, v_reader(_this)->qos->deadline.v.period, now); instance = v_dataReaderInstance(c_iterTakeFirst(missed)); while (instance != NULL) { @@ -2664,15 +2456,16 @@ v_dataReaderCheckDeadlineMissed( instance->owner.strength = 0; } v_statusNotifyRequestedDeadlineMissed(v_entity(_this)->status,v_publicHandle(v_public(instance))); - handled = v_entityNotifyListener(v_entity(_this), &event); + // TODO: event.handled is overwritten, this looks incorect, need a closer look! + event.handled = v_entityNotifyListener(v_entity(_this), &event); instance = v_dataReaderInstance(c_iterTakeFirst(missed)); } c_iterFree(missed); - v_dataReaderUnlock(_this); - if (!handled) { - v_observableNotify(v_observable(_this), &event); + if (!event.handled) { + OSPL_THROW_EVENT(_this, &event); } + OSPL_UNLOCK(_this); } v_dataReaderInstance @@ -2703,50 +2496,13 @@ v_dataReaderNotReadCount( assert(_this != NULL); assert(C_TYPECHECK(_this,v_dataReader)); - v_dataReaderLock(_this); + OSPL_LOCK(_this); count = _this->notReadCount; - v_dataReaderUnlock(_this); + OSPL_UNLOCK(_this); return count; } -static c_bool -flushPending( - c_object o, - c_voidp arg) -{ - v_dataReaderInstance instance = v_dataReaderInstance(o); - c_bool inNotEmptyList; - - OS_UNUSED_ARG(arg); - - inNotEmptyList = v_dataReaderInstanceInNotEmptyList(instance); - - v_dataReaderInstanceFlushPending(instance); - - if (!v_dataReaderInstanceEmpty(instance) && !inNotEmptyList) { - c_tableInsert(v_dataReaderInstanceReader(instance)->index->notEmptyList, instance); - v_dataReaderInstanceInNotEmptyList(instance) = TRUE; - } - - return TRUE; -} - -void -v_dataReaderFlushPending( - v_dataReader _this) -{ - assert(_this != NULL); - assert(C_TYPECHECK(_this,v_dataReader)); - - v_dataReaderLock(_this); -// (void) c_tableWalk(v_dataReaderNotEmptyInstanceSet(_this), flushPending, NULL); - (void) c_tableWalk(v_dataReaderAllInstanceSet(_this), flushPending, NULL); - v_dataReaderUpdatePurgeListsLocked(_this); - - v_dataReaderUnlock(_this); -} - static v_actionResult v__dataReaderFindMatchingSample( c_object object, @@ -2808,9 +2564,10 @@ v__dataReaderFindMatchingInstance( (v_sampleMaskTest (mask, V_MASK_NEW_VIEW)))) { /* User is either only interested in instance states or required - sample state is not read and instance is marked as new, which - indicates there are samples in the instance and that are not yet - readread. */ + * sample state is not read and instance is marked as new, which + * indicates there are samples in the instance and that are not yet + * readread. + */ walkon = FALSE; /* Reader qualifies, stop iteration. */ } else { walkon = V_STOP != v_dataReaderInstanceWalkSamples ( @@ -2830,8 +2587,7 @@ v_dataReaderHasMatchingSamples( assert (_this != NULL && C_TYPECHECK (_this, v_dataReader)); - v_dataReaderLock(_this); - + OSPL_LOCK(_this); if (v_sampleMaskTest(mask, V_MASK_NOT_READ_SAMPLE) && _this->notReadCount) { assert (_this->notReadCount > 0); /* notReadCount is signed */ @@ -2839,11 +2595,12 @@ v_dataReaderHasMatchingSamples( match = TRUE; } else { /* User is either only interested in instance states or instance - is required to be NEW, which indicates it's samples have not - been read. */ - /* If iteration ends prematurely at least one matching instance - and/or sample was identified. Iteration is terminated by - returning FALSE. */ + * is required to be NEW, which indicates it's samples have not + * been read. + * If iteration ends prematurely at least one matching instance + * and/or sample was identified. Iteration is terminated by + * returning FALSE. + */ match = FALSE == v__dataReaderWalkInstances ( _this, &v__dataReaderFindMatchingInstance, (c_voidp)&mask); } @@ -2851,8 +2608,7 @@ v_dataReaderHasMatchingSamples( match = FALSE == v__dataReaderWalkInstances ( _this, &v__dataReaderFindMatchingInstance, (c_voidp)&mask); } - - v_dataReaderUnlock(_this); + OSPL_UNLOCK(_this); return match; } @@ -2894,20 +2650,6 @@ countTransactions ( return TRUE; } -static c_bool -dataReaderEntryCountTransactions( - c_object o, - c_voidp arg) -{ - v_dataReaderEntry entry = v_dataReaderEntry(o); - - if (entry->transactionAdmin) { - v_transactionAdminWalkTransactions(entry->transactionAdmin, countTransactions, arg); - } - - return TRUE; /* process all other entries */ -} - c_ulong v_dataReaderGetNumberOpenTransactions( v_dataReader _this) @@ -2916,12 +2658,14 @@ v_dataReaderGetNumberOpenTransactions( assert (_this != NULL && C_TYPECHECK (_this, v_dataReader)); - v_dataReaderLock(_this); - - (void)c_setWalk(v_reader(_this)->entrySet.entries, dataReaderEntryCountTransactions, &count); - - v_dataReaderUnlock(_this); - + if(!v_entityEnabled(v_entity(_this))) { + return 0; + } + OSPL_LOCK(_this); + if (_this->entry->transactionAdmin) { + v_transactionAdminWalkTransactions(_this->entry->transactionAdmin, countTransactions, &count); + } + OSPL_UNLOCK(_this); return count; } @@ -2941,7 +2685,7 @@ v_dataReaderCheckMinimumSeparationList( c_list reinsertList = NULL; os_timeE lastInsertionTime = now; - v_dataReaderLock(_this); + OSPL_LOCK(_this); while ((instance = c_take(_this->minimumSeparationList))) { processed = v_dataReaderInstanceCheckMinimumSeparation(instance, now); if (!processed) { @@ -2971,12 +2715,11 @@ v_dataReaderCheckMinimumSeparationList( os_duration d = _this->maximumSeparationTime - os_timeEDiff(now, lastInsertionTime); v_leaseRenew(_this->minimumSeparationLease, d); } else { - /* There are no more instances with pending samples so set the lease expiry time to infinite. - */ + /* There are no more instances with pending samples so set the lease expiry time to infinite. */ v_leaseRenew(_this->minimumSeparationLease, OS_DURATION_INFINITE); } /* replace old list with the updated list. */ - v_dataReaderUnlock(_this); + OSPL_UNLOCK(_this); } /* This operation will add an instance that has a sample in the minimum separation window to the @@ -3035,8 +2778,7 @@ v_dataReaderMinimumSeparationListRegister( } } -/* This operation will remove an instance from the reader's minimum separation list. - */ +/* This operation will remove an instance from the reader's minimum separation list. */ void v_dataReaderMinimumSeparationListRemove( v_dataReader _this, @@ -3052,3 +2794,190 @@ v_dataReaderMinimumSeparationListRemove( } } +v_result +v_dataReaderAccessTest( + v_dataReader _this) +{ + v_result result = V_RESULT_OK; + + assert(_this != NULL); + assert(C_TYPECHECK(_this, v_dataReader)); + + if (!_this->accessBusy && + (v_reader(_this)->subQos->presentation.v.coherent_access || + v_reader(_this)->subQos->presentation.v.ordered_access) && + v_reader(_this)->subQos->presentation.v.access_scope == V_PRESENTATION_GROUP) + { + result = V_RESULT_PRECONDITION_NOT_MET; + } + return result; +} + +v_result +v_dataReaderSetQos( + v_dataReader _this, + v_readerQos qos) +{ + v_result result = V_RESULT_OK; + + assert(_this != NULL); + assert(C_TYPECHECK(_this, v_dataReader)); + + result = v_readerSetQos(v_reader(_this), qos); + OSPL_LOCK(_this); + if (result == V_RESULT_OK) { + v_deadLineInstanceListSetDuration(_this->deadLineList, qos->deadline.v.period); + } + OSPL_UNLOCK(_this); + return result; +} + +/* This operation informs the reader to either add or remove the publication described by + * the given publication info depending on the given ignore flag. + * If ignore is TRUE then the publication will be added to the readers ignore list and if + * ignore is FALSE then the publication will be removed from the ignore list if it exists. + * Note that removing a publication from the ignore list should only be performed if no data + * from the publication is to be expected in the future according to the DCPS specification. + */ +v_result +v_dataReaderIgnore( + v_dataReader _this, + struct v_publicationInfo *info, + os_boolean ignore) +{ + OSPL_LOCK(_this); + if (ignore) { + v_dataReaderEntryIgnorePublication(_this->entry, info); + } else { + v_dataReaderEntryDisposePublication(_this->entry, info); + } + OSPL_UNLOCK(_this); + return V_RESULT_OK; +} + +/* This operation will return the actual builtin subscription data for this dataReader. + * The dataReader caches this last published subscription data. + */ +v_message +v_dataReaderSubscription( + v_dataReader _this) +{ + v_message subscription; + OSPL_LOCK(_this); + if (_this->subInfo == NULL) { + _this->subInfo = v_builtinCreateSubscriptionInfo(v_objectKernel(_this)->builtin, v_reader(_this)); + } + subscription = c_keep(_this->subInfo); + OSPL_UNLOCK(_this); + return subscription; +} + +struct matchingPublicationsArg { + struct v_subscriptionInfo *subInfo; + v_publicationInfo_action action; + void *arg; +}; + +static os_boolean +actionOnMatch( + v_message publication, + void *arg) +{ + struct matchingPublicationsArg *a = (struct matchingPublicationsArg *)arg; + struct v_publicationInfo *pubInfo = (struct v_publicationInfo *)(publication + 1); + + if ((strcmp(pubInfo->topic_name, a->subInfo->topic_name) == 0) && + v_builtinTestPartitionMatch(pubInfo, a->subInfo) && + v_builtinTestQosMatch(pubInfo, a->subInfo) ) + { + a->action(pubInfo, a->arg); + } + return OS_TRUE; +} + +/* This operation will visit all discovered matching publications for this dataReader. + * The given action routine will be invoked on each publication info message. + * The signature of the action routine : v_result (*action)(const v_publicationInfo *info, void *arg) + * Issue: don't like operating on info as being an attribute of a message, + * better visit the whole message then it can also be returned as kept ref. + */ +v_result +v_dataReaderReadMatchedPublications( + v_dataReader _this, + v_publicationInfo_action action, + c_voidp arg) +{ + v_message msg; + v_result result = V_RESULT_OK; + struct matchingPublicationsArg ctx; + + msg = v_dataReaderSubscription(_this); + if (msg) { + ctx.subInfo = (struct v_subscriptionInfo *)(msg + 1); + ctx.action = action; + ctx.arg = arg; + result = v_kernelWalkPublications(v_objectKernel(_this), actionOnMatch, &ctx); + c_free(msg); + } + + return result; +} + +struct readMatchedDataArg { + struct v_subscriptionInfo *subInfo; + v_publicationInfo_action action; + void *arg; + v_gid publication; +}; + +static os_boolean +readMatchedData( + v_message publication, + void *arg) +{ + os_boolean proceed = OS_TRUE; + struct readMatchedDataArg *a = (struct readMatchedDataArg *)arg; + struct v_publicationInfo *pubInfo = (struct v_publicationInfo *)(publication + 1); + + if (pubInfo->key.systemId == a->publication.systemId && + pubInfo->key.localId == a->publication.localId) + { + if ((strcmp(pubInfo->topic_name, a->subInfo->topic_name) == 0) && + v_builtinTestPartitionMatch(pubInfo, a->subInfo) && + v_builtinTestQosMatch(pubInfo, a->subInfo) ) + { + a->action(pubInfo, a->arg); + } + proceed = OS_FALSE; + } + return proceed; +} + +/* This operation will visit the discovered matching publication for this dataReader identified by the given GID. + * The given action routine will be invoked on the GID associated publication info message. + * The signature of the action routine : v_result (*action)(const v_publicationInfo *info, void *arg) + * Issue: don't like operating on info as being an attribute of a message, + * better visit the whole message then it can also be returned as kept ref. + */ +v_result +v_dataReaderReadMatchedPublicationData( + v_dataReader _this, + v_gid publication, + v_publicationInfo_action action, + c_voidp arg) +{ + v_message msg; + v_result result = V_RESULT_OK; + struct readMatchedDataArg ctx; + + msg = v_dataReaderSubscription(_this); + if (msg) { + ctx.subInfo = (struct v_subscriptionInfo *)(msg + 1); + ctx.action = action; + ctx.arg = arg; + ctx.publication = publication; + result = v_kernelWalkPublications(v_objectKernel(_this), readMatchedData, &ctx); + c_free(msg); + } + return result; +} diff --git a/src/kernel/code/v_dataReaderEntry.c b/src/kernel/code/v_dataReaderEntry.c index 31015e460..565a9c4c3 100644 --- a/src/kernel/code/v_dataReaderEntry.c +++ b/src/kernel/code/v_dataReaderEntry.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,10 +23,10 @@ #include "v__dataReaderEntry.h" #include "v__dataReader.h" #include "v__reader.h" -#include "v_filter.h" #include "v__dataReaderInstance.h" #include "v_dataView.h" #include "v__observer.h" +#include "v__observable.h" #include "v_readerQos.h" #include "v_index.h" #include "v_public.h" @@ -38,20 +39,18 @@ #include "v__transaction.h" #include "v__participant.h" #include "v__subscriber.h" -#include "v_builtin.h" +#include "v__builtin.h" #include "v_topic.h" #include "v_message.h" #include "v_messageQos.h" #include "v__deliveryService.h" #include "v__kernel.h" #include "v_proxy.h" +#include "v_filter.h" #include "os_heap.h" #include "os_report.h" -/************************************************************** - * Private functions - **************************************************************/ typedef struct v_lifespanArg_s { v_readerSampleAction action; c_voidp arg; @@ -90,16 +89,13 @@ lifespanTakeAction( return result; } -/************************************************************** - * constructor/destructor - **************************************************************/ v_dataReaderEntry v_dataReaderEntryNew( v_dataReader dataReader, - v_index index, v_topic topic, q_expr _where, - const c_value *params[]) + const c_value *params[], + os_uint32 nrOfParams) { v_kernel kernel; v_dataReaderEntry e; @@ -111,29 +107,38 @@ v_dataReaderEntryNew( e = v_dataReaderEntry(v_objectNew(kernel,K_DATAREADERENTRY)); v_entryInit(v_entry(e), v_reader(dataReader)); e->topic = c_keep(topic); - - v_filterSplit(topic, _where, *params, &e->filterInstance, &e->filterData, index); - - /* Aministration for lifespan of messages */ - e->lifespanAdmin = v_lifespanAdminNew(kernel); - /* The time-ordered lists for autopurging and garbagecollection */ - e->purgeListNotEmpty = c_listNew(v_kernelType(kernel, K_PURGELISTITEM)); - e->purgeListDisposed = c_listNew(v_kernelType(kernel, K_PURGELISTITEM)); - if (v_reader(dataReader)->subQos->presentation.v.coherent_access) { - v_transactionGroupAdmin gAdmin = NULL; - if (v_reader(dataReader)->subQos->presentation.v.access_scope == V_PRESENTATION_GROUP) - { - gAdmin = v_subscriberLookupTransactionGroupAdmin(v_reader(dataReader)->subscriber); - assert(gAdmin); + e->ignore = NULL; + e->filter = v_filterNew(v_topicMessageType(topic), v_topicMessageKeyList(topic), _where, *params, nrOfParams); + if (e->filter) { + /* Aministration for lifespan of messages */ + e->lifespanAdmin = v_lifespanAdminNew(kernel); + /* The time-ordered lists for autopurging and garbagecollection */ + e->purgeListNotEmpty = c_listNew(v_kernelType(kernel, K_PURGELISTITEM)); + e->purgeListDisposed = c_listNew(v_kernelType(kernel, K_PURGELISTITEM)); + if (v_reader(dataReader)->subQos->presentation.v.coherent_access + && v_reader(dataReader)->subQos->presentation.v.access_scope != V_PRESENTATION_GROUP) { + e->transactionAdmin = v_transactionAdminNew(v_object(dataReader), NULL, topic); } - e->transactionAdmin = v_transactionAdminNew(v_object(dataReader), gAdmin, topic); } else { - e->transactionAdmin = NULL; + c_free(e->topic); + v_entryFree(v_entry(e)); + c_free(e); + e = NULL; } return e; } +void +v_dataReaderEntrySetTransactionAdmin( + _Inout_ v_dataReaderEntry _this, + _In_opt_ v_transactionGroupAdmin admin) +{ + assert(_this->transactionAdmin == NULL); + + _this->transactionAdmin = v_transactionAdminNew(v_object(v_entryReader(_this)), admin, _this->topic); +} + /* Callback functions for the index write action */ static v_actionResult @@ -206,8 +211,8 @@ doInstanceAutoPurge( if (!v_dataReaderInstanceEmpty(instance)) { /* Remove all samples from the instance, where - sample->disposed-/noWritersCount <= disposed-/noWritersCount - */ + * sample->disposed-/noWritersCount <= disposed-/noWritersCount + */ sampleCount = v_dataReaderInstanceSampleCount(instance); v_dataReaderInstancePurge(instance, disposedCount, noWritersCount); sampleCount -= v_dataReaderInstanceSampleCount(instance); @@ -248,7 +253,8 @@ v_dataReaderEntryUpdatePurgeLists( if (v_lifespanAdminSampleCount(entry->lifespanAdmin) > 0) { /* Walk over samples in lifespan administration in order to determine if - * they have to be discarded */ + * they have to be discarded + */ lifespanArg.action = onSampleDumpedAction; lifespanArg.arg = reader; lifespanArg.index = entry->index; @@ -273,41 +279,45 @@ v_dataReaderEntryUpdatePurgeLists( } /* This routine walks over the purgeLists and checks if any actions - * have to be done with the instances in the lists. */ + * have to be done with the instances in the lists. + */ qos = v_reader(reader)->qos; purgeList = entry->purgeListNotEmpty; if (c_listCount(purgeList) > 0) { timestamp = os_timeMSub(now, qos->lifecycle.v.autopurge_nowriter_samples_delay); - count = reader->resourceSampleCount; /* statistics */ - purgeListItem = c_removeAt(purgeList, 0); - while (purgeListItem != NULL) { - equality = os_timeMCompare(purgeListItem->insertionTime,timestamp); - if ((equality == OS_LESS) || (equality == OS_EQUAL)) { - purgeInstance = purgeListItem->instance; - - if (os_timeMCompare(purgeListItem->insertionTime, - purgeInstance->purgeInsertionTime) == OS_EQUAL){ - doInstanceAutoPurge(reader, purgeInstance, -1, purgeListItem->genCount); - } + /* timestamp can be invalid when 'now' is small (node was just started) */ + if (!OS_TIMEM_ISINVALID(timestamp)) { + count = reader->resourceSampleCount; /* statistics */ + purgeListItem = c_removeAt(purgeList, 0); + while (purgeListItem != NULL) { + equality = os_timeMCompare(purgeListItem->insertionTime, timestamp); + if ((equality == OS_LESS) || (equality == OS_EQUAL)) { + purgeInstance = purgeListItem->instance; + + if (os_timeMCompare(purgeListItem->insertionTime, + purgeInstance->purgeInsertionTime) == OS_EQUAL){ + doInstanceAutoPurge(reader, purgeInstance, -1, purgeListItem->genCount); + } - c_free(purgeListItem); - purgeListItem = c_removeAt(purgeList, 0); - } else { - /* the taken instance was not old enough yet and is - * therefore re-inserted. - */ - testItem = c_listInsert(purgeList, purgeListItem); - assert(testItem == purgeListItem); - OS_UNUSED_ARG(testItem); - c_free(purgeListItem); - purgeListItem = NULL; + c_free(purgeListItem); + purgeListItem = c_removeAt(purgeList, 0); + } else { + /* the taken instance was not old enough yet and is + * therefore re-inserted. + */ + testItem = c_listInsert(purgeList, purgeListItem); + assert(testItem == purgeListItem); + OS_UNUSED_ARG(testItem); + c_free(purgeListItem); + purgeListItem = NULL; + } } - } - /* Update statistics */ - if (reader->statistics) { - delta = count - reader->resourceSampleCount; - if (delta) { - reader->statistics->numberOfSamplesPurgedByNoWriters += (c_ulong) delta; + /* Update statistics */ + if (reader->statistics) { + delta = count - reader->resourceSampleCount; + if (delta) { + reader->statistics->numberOfSamplesPurgedByNoWriters += (c_ulong) delta; + } } } } @@ -315,42 +325,44 @@ v_dataReaderEntryUpdatePurgeLists( purgeList = entry->purgeListDisposed; if (c_listCount(purgeList) > 0) { timestamp = os_timeMSub(now, qos->lifecycle.v.autopurge_disposed_samples_delay); - count = reader->resourceSampleCount; /* statistics */ - purgeListItem = c_removeAt(purgeList, 0); - while (purgeListItem != NULL) { - equality = os_timeMCompare(purgeListItem->insertionTime,timestamp); - if ((equality == OS_LESS) || (equality == OS_EQUAL)) { - purgeInstance = purgeListItem->instance; - - if (os_timeMCompare(purgeListItem->insertionTime, - purgeInstance->purgeInsertionTime) == OS_EQUAL){ - doInstanceAutoPurge(reader, purgeInstance, purgeListItem->genCount, -1); - } + /* timestamp can be invalid when 'now' is small (node was just started) */ + if (!OS_TIMEM_ISINVALID(timestamp)) { + count = reader->resourceSampleCount; /* statistics */ + purgeListItem = c_removeAt(purgeList, 0); + while (purgeListItem != NULL) { + equality = os_timeMCompare(purgeListItem->insertionTime, timestamp); + if ((equality == OS_LESS) || (equality == OS_EQUAL)) { + purgeInstance = purgeListItem->instance; + + if (os_timeMCompare(purgeListItem->insertionTime, + purgeInstance->purgeInsertionTime) == OS_EQUAL){ + doInstanceAutoPurge(reader, purgeInstance, purgeListItem->genCount, -1); + } - c_free(purgeListItem); - purgeListItem = c_removeAt(purgeList, 0); - } else { - /* the taken instance was not old enough yet and is - * therefore re-inserted. - */ - testItem = c_listInsert(purgeList, purgeListItem); - assert(testItem == purgeListItem); - c_free(purgeListItem); - purgeListItem = NULL; + c_free(purgeListItem); + purgeListItem = c_removeAt(purgeList, 0); + } else { + /* the taken instance was not old enough yet and is + * therefore re-inserted. + */ + testItem = c_listInsert(purgeList, purgeListItem); + assert(testItem == purgeListItem); + c_free(purgeListItem); + purgeListItem = NULL; + } } - } - /* Update statistics. */ - if (reader->statistics) { - delta = count - reader->resourceSampleCount; - if (delta) { - reader->statistics->numberOfSamplesPurgedByDispose += (c_ulong) delta; + /* Update statistics. */ + if (reader->statistics) { + delta = count - reader->resourceSampleCount; + if (delta) { + reader->statistics->numberOfSamplesPurgedByDispose += (c_ulong) delta; + } } } } /* Why have statistic attributes if already available? */ - /* Update statistics. */ if (reader->statistics) { - reader->statistics->numberOfInstances = (c_ulong) v_dataReaderInstanceCount(reader); + reader->statistics->numberOfInstances = (c_ulong) v_dataReaderInstanceCount_nl(reader); reader->statistics->numberOfSamples = (c_ulong) reader->resourceSampleCount; } } @@ -393,7 +405,8 @@ doWrite( qos->lifecycle.v.autopurge_dispose_all) { /* This is a dispose_all and the instance needs to be * purged immediately. - * Dispose all is indicated by the lack of a writerGID. */ + * Dispose all is indicated by the lack of a writerGID. + */ doInstanceAutoPurge(v_dataReader(reader), found, found->disposeCount, @@ -409,8 +422,7 @@ doWrite( purgeListInsert(_this->purgeListNotEmpty, found); } } - } else if (v_dataReaderInstanceStateTest(found,L_NOWRITERS) && - !v_stateTest(v_nodeState(message), L_REGISTER)) { + } else if (found->liveliness == 0) { v_dataReaderRemoveInstance(v_dataReader(reader), v_dataReaderInstance(found)); } @@ -430,7 +442,7 @@ doWrite( result = V_WRITE_SUCCESS; break; case V_DATAREADER_SAMPLE_LOST: - v_dataReaderNotifySampleLost(reader, 1); + v_dataReaderNotifySampleLost_nl(reader, 1); result = V_WRITE_SUCCESS; break; case V_DATAREADER_OUT_OF_MEMORY: @@ -448,10 +460,9 @@ doWrite( break; } } - /* statistics */ if (reader->statistics) { c_ulong cnt; - cnt = (c_ulong) v_dataReaderInstanceCount(reader); + cnt = (c_ulong) v_dataReaderInstanceCount_nl(reader); reader->statistics->numberOfInstances = cnt; reader->statistics->maxNumberOfInstances.value = cnt; cnt = (c_ulong) reader->resourceSampleCount; @@ -472,6 +483,34 @@ doWrite( return result; } +static c_bool +pass_filter( + v_dataReaderEntry _this, + v_message message) +{ + c_bool pass = TRUE; + + if (_this->filter) { + /* a filter that is only operates on key fields will block all data of complying instances. + * so avoid creation of instance and pipeline for key values not passing a pure key filter + * except for transactions which require data for completeness verification. + */ + if (v_messageStateTest(message, L_WRITE) && v_filterHasNonKey(_this->filter)) { + /* Full messages can be filtered by any filter */ + pass = v_filterEval(_this->filter, message); + } else if (c_getType(message) != v_kernelType(v_objectKernel(_this), K_MESSAGE)) { + /* Invalid data messages can only be filtered on key value */ + pass = v_filterEvalKey(_this->filter, message); + } else { + /* Mini messages cannot be filtered but comply by default to the key filter because + * they are associated to the pipeline. + */ + pass = TRUE; + } + } + return pass; +} + v_writeResult v_dataReaderEntryWrite( v_dataReaderEntry _this, @@ -485,10 +524,8 @@ v_dataReaderEntryWrite( v_state state; v_dataReaderInstance instance=NULL, found; c_table instanceSet; - c_ulong index = 0; - c_ulong length; v_subscriber subscriber; - c_bool complete = FALSE; + c_bool flush = FALSE; assert(C_TYPECHECK(_this,v_dataReaderEntry)); assert(message != NULL); @@ -497,16 +534,15 @@ v_dataReaderEntryWrite( /* Only write if the message is not produced by an incompatible writer. */ reader = v_dataReader(v_entryReader(_this)); - v_observerLock(v_observer(reader)); + OSPL_LOCK(reader); subscriber = v_readerSubscriber(v_reader(reader)); if (!subscriber) { /* The subscriber is detached meaning that the reader is in progress of being deleted. * Abort message insertion and return success as if the reader was already deleted. */ - v_observerUnlock(v_observer(reader)); + OSPL_UNLOCK(reader); return V_WRITE_SUCCESS; /* reader is in progress of being deleted */ } - /* Purge samples */ v_dataReaderEntryUpdatePurgeLists(_this); @@ -530,16 +566,30 @@ v_dataReaderEntryWrite( /* Note: write_dispose has the side effect that the instance state * for subscriber defined keys is set. */ - v_observerUnlock(v_observer(reader)); + OSPL_UNLOCK(reader); return V_WRITE_SUCCESS; } } /* Filter-out all QoS-incompatible messages. */ if (!v_messageQos_isReaderCompatible(message->qos,v_reader(reader))) { - v_observerUnlock(v_observer(reader)); + OSPL_UNLOCK(reader); return V_WRITE_SUCCESS; } + /* Filter-out ignored messages. */ + if (_this->ignore) { + os_uint32 i, size; + size = c_arraySize(_this->ignore); + for (i=0; iwriterGID.systemId == ((v_gid *)(_this->ignore))[i].systemId && + message->writerGID.localId == ((v_gid *)(_this->ignore))[i].localId) + { + OSPL_UNLOCK(reader); + return V_WRITE_SUCCESS; + } + } + } + if (reader->statistics) { reader->statistics->numberOfSamplesArrived++; } @@ -549,7 +599,7 @@ v_dataReaderEntryWrite( /* Drop invalid messages when the datareader instance is not known */ if (c_getType(message) == v_kernelType(v_objectKernel(_this), K_MESSAGE)) { - v_observerUnlock(v_observer(reader)); + OSPL_UNLOCK(reader); return V_WRITE_SUCCESS; } @@ -559,48 +609,19 @@ v_dataReaderEntryWrite( "v_dataReaderEntry::v_dataReaderEntryWrite",V_RESULT_INTERNAL_ERROR, "Failed to allocate v_dataReaderInstance object."); /* failed to create a new instance. */ - v_observerUnlock(v_observer(reader)); + OSPL_UNLOCK(reader); return V_WRITE_OUT_OF_RESOURCES; } - if (_this->filterInstance) { - c_bool key_filter = TRUE; /* only key fields in filter */ - c_bool pass = TRUE; - length = c_arraySize(_this->filterInstance); - for (index=0; indexfilterData[index]) { - if (v_messageStateTest(message, L_WRITE)) { - DataMatch = v_filterEval(_this->filterData[index],message); - } - key_filter = FALSE; - } - if ((DataMatch == TRUE)&&(_this->filterInstance[index])) { - KeyMatch = v_filterEval(_this->filterInstance[index],instance); - } - if ((pass = (DataMatch && KeyMatch)) == TRUE) { - break; - } + if (!pass_filter(_this, message)) { + if (_this->transactionAdmin && v_stateTest(v_nodeState(message), L_WRITE) && v_message_isTransaction(message)) { + (void)v_transactionAdminInsertMessage(_this->transactionAdmin, message, NULL, FALSE, &flush); } - if (pass == FALSE) { - c_bool is_transaction = v_message_isTransaction(message); - /* a filter that is only operates on key fields will block all data of complying instances. - * so avoid creation of instance and pipeline for key values not passing a pure key filter - * except for transactions which require data for completeness verification. - */ - if (v_stateTest(state, L_WRITE) || (key_filter && !is_transaction)) { - if (is_transaction && _this->transactionAdmin) { - (void)v_transactionAdminInsertMessage(_this->transactionAdmin, message, NULL, FALSE, &complete); - if (complete && v__readerIsGroupCoherent(v_reader(reader))) { - v_subscriberTriggerGroupCoherent(subscriber, v_reader(reader)); - } - } - v_dataReaderInstanceFree(instance); - v_observerUnlock(v_observer(reader)); - return V_WRITE_SUCCESS; - } + OSPL_UNLOCK(reader); + if (flush) { + v_subscriberGroupTransactionFlush(subscriber); } + v_dataReaderInstanceFree(instance); + return V_WRITE_SUCCESS; } assert(c_refCount(instance) == 2); if (qos->userKey.v.enable) { @@ -613,20 +634,11 @@ v_dataReaderEntryWrite( if (found == instance) { /* Instance did not yet exist */ assert(c_refCount(found) == 3); -#if 0 - /* The max_instance limit is disabled because it rejects the register message from the group - * meaning that the pipeline will not be build which results in a permanent disconnect for this instance - * even if later on room for new instances becomes available. - * see OSPL-22 - */ - if (qos->resource.v.max_instances != V_LENGTH_UNLIMITED) { - reader->maxInstances = (qos->resource.v.max_instances < (c_long)c_tableCount(instanceSet)); - } -#endif if (reader->maxInstances == TRUE) { /* The maximum number of instances was already reached. * Therefore the instance was inserted unnecessarily and must - * be removed. */ + * be removed. + */ found = c_remove(instanceSet, instance,NULL,NULL); assert(found == instance); c_free(instance); @@ -634,18 +646,14 @@ v_dataReaderEntryWrite( found = NULL; onSampleRejected(reader, S_REJECTED_BY_INSTANCES_LIMIT, v_publicGid(NULL)); result = V_WRITE_REJECTED; - if (v_message_isTransaction(message) || v_messageStateTest(message, L_ENDOFTRANSACTION)) { - if (_this->transactionAdmin) { - (void)v_transactionAdminInsertMessage(_this->transactionAdmin, message, NULL, TRUE, &complete); - if (complete && v__readerIsGroupCoherent(v_reader(reader))) { - v_subscriberTriggerGroupCoherent(subscriber, v_reader(reader)); - } - } + if (_this->transactionAdmin && (v_message_isTransaction(message) || v_messageStateTest(message, L_ENDOFTRANSACTION))) { + (void)v_transactionAdminInsertMessage(_this->transactionAdmin, message, NULL, TRUE, &flush); } } else if (v_messageStateTest(message,L_UNREGISTER)) { /* There is no use case to support implicit unregister. * Therefore the instance was inserted unnecessarily and can - * be removed. */ + * be removed. + */ found = c_remove(instanceSet, instance,NULL,NULL); assert(found == instance); c_free(instance); @@ -661,7 +669,8 @@ v_dataReaderEntryWrite( * state 0 is ALIVE, but instances are created with flag * L_NOWRITERS set, this change triggers an unwanted de- * crement of the Alive-counter. This special case has to be - * handled in the statistics updating. */ + * handled in the statistics updating. + */ UPDATE_READER_STATISTICS(_this,found,0); V_MESSAGE_STAMP(message,readerLookupTime); result = doWrite(_this, found, message, context, @@ -681,49 +690,25 @@ v_dataReaderEntryWrite( *instancePtr = c_keep(found); } } else { - if (_this->filterInstance) { - c_bool key_filter = TRUE; /* only key fields in filter */ - c_bool pass = TRUE; - length = c_arraySize(_this->filterInstance); - for (index=0; indexfilterData[index]) { - if (v_messageStateTest(message, L_WRITE)) { - DataMatch = v_filterEval(_this->filterData[index],message); - } - key_filter = FALSE; - } - if ((DataMatch == TRUE)&&(_this->filterInstance[index])) { - KeyMatch = v_filterEval(_this->filterInstance[index],v_dataReaderInstance(*instancePtr)); - } - if ((pass = (DataMatch && KeyMatch)) == TRUE) { - break; - } - } - if (pass == FALSE) { - c_bool is_transaction = v_message_isTransaction(message); - /* a filter that is only operates on key fields will block all data of complying instances. - * so avoid creation of instance and pipeline for key values not passing a pure key filter - * except for transactions which require data for completeness verification. - */ - if (v_stateTest(state, L_WRITE) || (key_filter && !is_transaction)) { - if (is_transaction && _this->transactionAdmin) { - (void)v_transactionAdminInsertMessage(_this->transactionAdmin, message, NULL, FALSE, &complete); - if (complete && v__readerIsGroupCoherent(v_reader(reader))) { - v_subscriberTriggerGroupCoherent(subscriber, v_reader(reader)); - } - } - v_observerUnlock(v_observer(reader)); - return V_WRITE_SUCCESS; - } + if (pass_filter(_this, message)) { + V_MESSAGE_STAMP(message,readerLookupTime); + result = doWrite(_this, v_dataReaderInstance(*instancePtr), message, context, NULL); + } else if (v_message_isTransaction(message)) { + if (!v_stateTest(v_nodeState(message), L_WRITE)) { + /* Invalid messages that belong to a transaction are never filtered out */ + result = doWrite(_this, v_dataReaderInstance(*instancePtr), message, context, NULL); + } else if (_this->transactionAdmin) { + (void)v_transactionAdminInsertMessage(_this->transactionAdmin, message, NULL, FALSE, &flush); + result = V_WRITE_SUCCESS; } + } else { + result = V_WRITE_SUCCESS; } - V_MESSAGE_STAMP(message,readerLookupTime); - result = doWrite(_this, v_dataReaderInstance(*instancePtr), message, context, NULL); } - v_observerUnlock(v_observer(reader)); + OSPL_UNLOCK(reader); + if (flush) { + v_subscriberGroupTransactionFlush(subscriber); + } return result; } @@ -735,21 +720,18 @@ v_dataReaderEntryWriteEOT( { v_reader reader = v_entryReader(_this); v_subscriber subscriber = NULL; - c_bool complete = FALSE; + c_bool flush = FALSE; - v_observerLock(v_observer(reader)); + OSPL_LOCK(reader); subscriber = v_readerSubscriber(reader); /* Filter-out all QoS-incompatible messages. */ - if (subscriber && _this->transactionAdmin) { - if (v_messageQos_isReaderCompatible(message->qos,reader)) { - (void)v_transactionAdminInsertMessage(_this->transactionAdmin, message, NULL, FALSE, &complete); - if (complete && v__readerIsGroupCoherent(reader)) { - v_subscriberTriggerGroupCoherent(subscriber, reader); - } - } + if (subscriber && _this->transactionAdmin && v_messageQos_isReaderCompatible(message->qos,reader)) { + (void)v_transactionAdminInsertMessage(_this->transactionAdmin, message, NULL, FALSE, &flush); + } + OSPL_UNLOCK(reader); + if (flush) { + v_subscriberGroupTransactionFlush(subscriber); } - v_observerUnlock(v_observer(reader)); - return V_WRITE_SUCCESS; } @@ -812,7 +794,7 @@ v_dataReaderEntryDisposeAll ( assert(C_TYPECHECK(_this,v_dataReaderEntry)); reader = v_entryReader(_this); - v_observerLock(v_observer(reader)); + OSPL_LOCK(reader); /* Only if the subscriber is still attached, otherwise the reader is in progress of being deleted. */ if (v_readerSubscriber(v_reader(reader))) { @@ -843,7 +825,7 @@ v_dataReaderEntryDisposeAll ( } c_iterFree(ca.instances); } - v_observerUnlock(v_observer(reader)); + OSPL_UNLOCK(reader); return result; } @@ -871,24 +853,87 @@ v_dataReaderEntryUnmarkInstanceStates ( assert(C_TYPECHECK(_this,v_dataReaderEntry)); reader = v_entryReader(_this); - v_observerLock(v_observer(reader)); + OSPL_LOCK(reader); c_tableWalk(_this->index->objects, unmarkInstance, &flags); - v_observerUnlock(v_observer(reader)); + OSPL_UNLOCK(reader); } -v_typeRepresentation -v__dataReaderEntryGetTypeRepresentation ( - v_dataReaderEntry _this) +static os_boolean +inList( + c_array list, + v_gid gid) { - c_char *typeName; - v_typeRepresentation found; - - typeName = c_metaScopedName(c_metaObject(v_topicDataType(v_dataReaderEntryTopic(_this)))); - found = v_participantLookupTypeRepresentation(v_subscriberParticipant(v_readerSubscriber(v_reader(_this))), typeName); - os_free(typeName); + os_uint32 i, size; + v_gid *gidlist = (v_gid *)list; + size = c_arraySize(list); + for (i=0; itopic), info->topic_name) == 0) { + type = c_resolve(c_getBase(_this),"kernelModule::v_gid"); + TRACE_IGNORE("DataReader::Entry::ignore_publication GID: {%d,%d,%d} for topic %s\n", + info->key.systemId, info->key.localId, info->key.serial, info->topic_name); + if (_this->ignore == NULL) { + _this->ignore = c_arrayNew(type, 1); + ((v_gid *)(_this->ignore))[0] = info->key; + } else if (!inList(_this->ignore, info->key)) { + v_gid *old = (v_gid *)(_this->ignore); + size = c_arraySize(_this->ignore); + _this->ignore = c_arrayNew(type, size+1); + for (i=0; iignore))[i] = old[i]; + } + ((v_gid *)(_this->ignore))[i] = info->key; + c_free(old); + } + c_free(type); + } } +/* This operation will wipe the given publicatiom GID from the entry's ignore list. + * This can only be performed when the publication no longer exists and no data + * from this writer is to be expected anymore. + */ +void +v_dataReaderEntryDisposePublication( + v_dataReaderEntry _this, + const struct v_publicationInfo *info) +{ + c_type type; + os_uint32 i, n, size; + + if (inList(_this->ignore, info->key)) { + v_gid *old = (v_gid *)(_this->ignore); + size = c_arraySize(_this->ignore); + type = c_resolve(c_getBase(_this),"kernelModule::v_gid"); + _this->ignore = c_arrayNew(type, size-1); + c_free(type); + n = 0; + for (i=0; ikey.systemId || old[i].localId != info->key.localId) + { + ((v_gid *)(_this->ignore))[n++] = old[i]; + } + } + c_free(old); + } +} diff --git a/src/kernel/code/v_dataReaderInstance.c b/src/kernel/code/v_dataReaderInstance.c index 9f67d7200..1e19c320b 100644 --- a/src/kernel/code/v_dataReaderInstance.c +++ b/src/kernel/code/v_dataReaderInstance.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,6 +30,7 @@ #include "v__lifespanAdmin.h" #include "v__transaction.h" #include "v__observer.h" +#include "v__observable.h" #include "v_state.h" #include "v_instance.h" #include "v__deadLineInstance.h" @@ -93,6 +95,14 @@ #define CHECK_COUNT(_this) #endif +#define DECREASE_READER_NOT_READ_COUNT(reader) \ + (reader)->notReadCount--; \ + assert((reader)->notReadCount >= 0) + +#define INCREASE_READER_NOT_READ_COUNT(reader) \ + (reader)->notReadCount++; \ + assert((reader)->notReadCount <= (reader)->resourceSampleCount + (c_long)c_tableCount((reader)->index->objects) + 1) + /** * Returns the relative order of a v_message to a v_historyBookmark. * @param _this A v_historyBookmark @@ -100,9 +110,9 @@ * @return C_EQ, C_LT or C_GT if msg is respectively equal, less or greater than _this bookmark */ static c_equality -v_historyBookmarkMessageCompare( - struct v_historyBookmark *_this, - v_message msg) +compareMessageToBookmark( + v_message msg, + struct v_historyBookmark *_this) { C_STRUCT(v_message) template; @@ -110,7 +120,7 @@ v_historyBookmarkMessageCompare( template.writerGID = _this->gid; template.sequenceNumber = _this->sequenceNumber; ((v_node)&template)->nodeState = _this->isImplicit ? L_IMPLICIT : 0; - return v_messageCompare(&template, msg); + return v_messageCompare(msg, &template); } #ifndef NDEBUG @@ -222,16 +232,16 @@ invalidSampleResetEventCounters( * and raise the L_READ flag to indicate that these samples * should no longer influence the notReadCount. */ - if (!v_readerSampleTestStateOr(sample, L_VALIDDATA | L_READ | L_LAZYREAD)) + if (!v_readerSampleTestStateOr(sample, L_VALIDDATA | L_READ | L_LAZYREAD | L_INMINSEPTIME)) { - reader->notReadCount--; + DECREASE_READER_NOT_READ_COUNT(reader); v_readerSampleSetState(sample, L_READ); } sample = v_dataReaderSample(sample->newer); } } -static void +static v_dataReaderSample updateIntermediateInstanceAndSampleState( v_dataReaderInstance _this, v_message message, @@ -242,6 +252,7 @@ updateIntermediateInstanceAndSampleState( v_state prevMsgState, nextMsgState; v_dataReaderSample s; v_state msgState = v_nodeState(message); + c_bool invalid = FALSE; assert(sample->newer); /* Valid samples that are part of a transaction that is still in progress do @@ -253,7 +264,6 @@ updateIntermediateInstanceAndSampleState( v_readerSampleSetState(sample, L_VALIDDATA); _this->historySampleCount++; } - /* If the sample is a an UNREGISTER, it might need to set increase the * noWritersCount, but only if the older sample was not a dispose. * However, if the previous sample was both a DISPOSE and an UNREGISTER, @@ -265,8 +275,7 @@ updateIntermediateInstanceAndSampleState( { prevMsg = v_dataReaderSampleMessage(sample->older); prevMsgState = v_nodeState(prevMsg); - if (!v_stateTest(prevMsgState, L_DISPOSED) || - v_stateTest(prevMsgState, L_DISPOSED | L_UNREGISTER)) + if (!v_stateTest(prevMsgState, L_DISPOSED) || v_stateTest(prevMsgState, L_DISPOSED | L_UNREGISTER)) { _this->noWritersCount++; s = sample; @@ -282,6 +291,7 @@ updateIntermediateInstanceAndSampleState( } } } + invalid = TRUE; } /* If the sample is a a DISPOSE, it needs to increase the disposeCount. @@ -302,8 +312,7 @@ updateIntermediateInstanceAndSampleState( /* Intermediate sample, so there is always a newer sample. */ nextMsg = v_dataReaderSampleMessage(sample->newer); nextMsgState = v_nodeState(nextMsg); - if (v_stateTest(nextMsgState, L_UNREGISTER) && - !v_stateTest(nextMsgState, L_DISPOSED | L_UNREGISTER)) + if (v_stateTest(nextMsgState, L_UNREGISTER) && !v_stateTest(nextMsgState, L_DISPOSED | L_UNREGISTER)) { _this->noWritersCount--; s = sample; @@ -318,15 +327,21 @@ updateIntermediateInstanceAndSampleState( { v_dataReaderInstanceStateSet(_this, L_TRIGGER); } + invalid = !v_stateTest(msgState, L_WRITE); } v_deadLineInstanceListUpdate(v_dataReader(v_index(_this->index)->reader)->deadLineList, v_deadLineInstance(_this), message->allocTime); - if (v_dataReaderInstanceStateTest(_this, L_TRIGGER) || - v_stateTest(msgState, L_WRITE)) { - reader->notReadCount++; + if (invalid || v_stateTest(msgState, L_WRITE)) + { + INCREASE_READER_NOT_READ_COUNT(reader); } + if (invalid) { + v_dataReaderInstanceSampleRemove(_this, sample, TRUE); + sample = NULL; + } + return sample; } static void @@ -436,6 +451,11 @@ updateFinalInstanceAndSampleState( { v_dataReaderInstanceStateSetMask(_this, (L_DISPOSED | L_STATECHANGED)); + /* If this is a replace dispose action then mark this instance as replaced */ + if (v_stateTest(msgState, L_REPLACED)) { + v_dataReaderInstanceStateSetMask(_this, L_REPLACED); + } + /* If the sample is valid, the update constitutes a readable * state change for which observers need to be triggered. * @@ -457,7 +477,8 @@ updateFinalInstanceAndSampleState( { /* Don't set the trigger flag when this is a dispose all * and the instance needs to be purge immediately. - * Dispose all is indicated by the lack of a writerGID. */ + * Dispose all is indicated by the lack of a writerGID. + */ if (!(!v_gidIsValid(message->writerGID) && qos->lifecycle.v.autopurge_dispose_all)) { @@ -493,10 +514,7 @@ updateFinalInstanceAndSampleState( * to the observers when the reader has indicated that * it is prepared to receive invalid samples. */ - if (v_stateTest(msgState, L_WRITE) || - qos->lifecycle.v.enable_invalid_samples || - hasValidSampleAccessible(_this)) - { + if (qos->lifecycle.v.enable_invalid_samples || hasValidSampleAccessible(_this)) { v_dataReaderInstanceStateSet(_this, L_TRIGGER); } } @@ -521,7 +539,7 @@ updateFinalInstanceAndSampleState( * flag, to indicate that it does not impact the notReadCount. */ if (v_dataReaderInstanceStateTest(_this, L_TRIGGER)){ - reader->notReadCount++; + INCREASE_READER_NOT_READ_COUNT(reader); } else { v_readerSampleSetState(sample, L_READ); } @@ -530,7 +548,6 @@ updateFinalInstanceAndSampleState( * Otherwise update the instance in the deadline list. */ if (generationEnd) { - /* v_instanceRemove(v_instance(_this)); */ v_deadLineInstanceListRemoveInstance( v_dataReaderDeadLineInstanceList(reader), v_deadLineInstance(_this)); @@ -539,6 +556,29 @@ updateFinalInstanceAndSampleState( v_dataReaderDeadLineInstanceList(reader), v_deadLineInstance(_this), message->allocTime); } + /* If previous message is an invalid message then remove it as it is no longer required. */ + if (sample->older && + !v_readerSampleTestState(sample->older, L_VALIDDATA)) + { + c_bool prev_not_read = !v_readerSampleTestState(sample->older, L_READ); + v_dataReaderInstanceSampleRemove(_this, sample->older, TRUE); + if (v_readerSampleTestState(sample, L_READ) && prev_not_read) { + /* If the previous invalid sample was still NOT_READ while we pushed it out of the + * history, then its task of communicating its state change passes on to the newly + * inserted sample. That means the newly inserted sample should become NOT_READ instead. + * However, the state machine might have decided that the newly inserted message is + * considered READ, in which case we will have overrule this decision and set its + * sample state to NOT_READ instead. Such a scenario occurs for example when the + * previous sample communicated a DISPOSED state, while the newly inserted sample + * communicates an UNREGISTER state. The latter was not considered to be a a state change + * (since DISPOSED is an end state for the application reader) so the sample was set to + * READ. So in this case we will have to transfer the NOT_READ state from the previous + * sample to the newly inserted sample. + */ + v_readerSampleClearState(sample, L_READ); + INCREASE_READER_NOT_READ_COUNT(reader); + } + } } v_dataReaderResult @@ -631,8 +671,7 @@ InsertPending( } while ( s!= NULL && equality == C_LT); } - /* If max_samples_per_instance is then handle resource issue. - */ + /* If max_samples_per_instance is then handle resource issue. */ if (v_messageStateTest(message, L_WRITE) && (qos->resource.v.max_samples_per_instance != V_LENGTH_UNLIMITED) && (qos->resource.v.max_samples_per_instance <= _this->resourceSampleCount)) @@ -729,6 +768,8 @@ MakeSampleAvailable ( { v_dataReader reader; + if (!sample) return; + reader = v_dataReaderInstanceReader(_this); /* If ReaderQos has orderedAccess set to TRUE, then report the sample * to the orderedInstance. @@ -820,7 +861,8 @@ FindHistoryPosition( * sources, then messages with the same timestamp * will be sorted by their writerGID and * sequenceNumber to guarantee eventual consistency - * throughout all DataReaders in the Domain. */ + * throughout all DataReaders in the Domain. + */ if ( equality == C_EQ ) { result = V_DATAREADER_DUPLICATE_SAMPLE; } else if ( equality == C_LT) { @@ -836,7 +878,8 @@ FindHistoryPosition( if (qos->history.v.kind == V_HISTORY_KEEPLAST && depthBookmark >= qos->history.v.depth) { /* If this sample is older than all VALID samples in the current * history, and the history has already reached its full depth, - * then the sample can discarded. */ + * then the sample can discarded. + */ if(reader->statistics){ reader->statistics->numberOfSamplesDiscarded++; } @@ -922,6 +965,7 @@ InsertHistory( CHECK_COUNT(_this); result = V_DATAREADER_INSERTED; + /* Filter out messages that violate the time based filter minimum separation time, * if the message state is not disposed or unregister and the time_based_filter QoS is enabled * Messages part of a transaction are filtered if/when a transaction flush occurs. @@ -1046,9 +1090,9 @@ InsertHistory( if(v_dataReaderInstanceNewest(_this) == sample){ updateFinalInstanceAndSampleState(_this, message, sample); } else { - updateIntermediateInstanceAndSampleState(_this, message, sample); + sample = updateIntermediateInstanceAndSampleState(_this, message, sample); } - if (((v_observerEventMask(reader) & V_EVENT_PREPARE_DELETE) == 0)) { + if (((OSPL_GET_EVENT_MASK(reader) & V_EVENT_PREPARE_DELETE) == 0)) { MakeSampleAvailable(_this, sample); } } @@ -1067,9 +1111,6 @@ InsertSample( v_readerQos qos; c_equality equality; v_dataReaderResult result; - c_bool accessLock = FALSE; - c_bool insert = TRUE; - v_subscriber subscriber; reader = v_dataReaderInstanceReader(_this); qos = v_reader(reader)->qos; @@ -1079,38 +1120,25 @@ InsertSample( * in case of equal timestamps order is determined by the writerGID and * then by sequence-number.) */ + result = V_DATAREADER_INSERTED; if (qos->orderby.v.kind == V_ORDERBY_SOURCETIME) { - equality = v_historyBookmarkMessageCompare(&_this->lastConsumed, message); + equality = compareMessageToBookmark(message, &_this->lastConsumed); if (equality == C_EQ) { result = V_DATAREADER_DUPLICATE_SAMPLE; - } else if (equality == C_GT) { + } else if (equality == C_LT) { result = V_DATAREADER_SAMPLE_LOST; } } if (result == V_DATAREADER_INSERTED) { - subscriber = v_readerSubscriber(v_reader(reader)); - assert(subscriber); - - if (context != V_CONTEXT_TRANSACTIONFLUSH) { - if (v__readerIsGroupOrderedNonCoherent(v_reader(reader))) { - /* accessLock only required for group, none coherent, ordered subscribers. */ - v_subscriberLock(subscriber); - insert = accessLock = v_subscriberTryLockAccess(subscriber); - if (accessLock == FALSE) { - result = InsertPending(_this, message, context); - } - v_subscriberUnlock(subscriber); - } - } - if (insert) { + if ((context != V_CONTEXT_TRANSACTIONFLUSH) && + (v__readerIsGroupOrderedNonCoherent(v_reader(reader))) && + (reader->accessBusy)) + { + result = InsertPending(_this, message, context); + } else { result = InsertHistory(_this, message, context); } - if (accessLock) { - v_subscriberLock(subscriber); - v_subscriberUnlockAccess(subscriber); - v_subscriberUnlock(subscriber); - } } if (result != V_DATAREADER_INSERTED && context == V_CONTEXT_TRANSACTIONFLUSH && @@ -1171,9 +1199,7 @@ v_dataReaderInstanceInit ( _this->owner.exclusive = FALSE; } - /* - * copy key value from message into instance. - */ + /* copy key value from message into instance. */ messageKeyList = v_indexMessageKeyList(index); instanceKeyList = v_indexKeyList(index); assert(c_arraySize(messageKeyList) == c_arraySize(instanceKeyList)); @@ -1261,37 +1287,44 @@ v_dataReaderInstanceWrite ( v_writeResult result; v_dataReaderEntry entry; v_dataReaderInstance* thisPtr; + v_dataReader reader; assert(C_TYPECHECK(_this,v_dataReaderInstance)); assert(C_TYPECHECK(msg,v_message)); - if ((_this->owner.exclusive) && - (v_messageQos_getOwnershipStrength(msg->qos) < _this->owner.strength) && - (v_gidIsValid(_this->owner.gid)) && - (!v_gidEqual(_this->owner.gid, msg->writerGID)) /* also choose else-branch in case current owner lowered strength */ - ) { - if (v_messageStateTest(msg, L_UNREGISTER)) { - /* - * An unregister message should decrease the liveliness. - * This is normally done in the v_dataReaderInstanceInsert() function. - * But, because this message is not forwarded and will not reach that - * function, the liveliness has the be decreased here. - * - * The register message takes a different route. It will not come here and - * will always reach v_dataReaderInstanceInsert() to increase liveliness. - */ - if (_this->liveliness > 0) - { - _this->liveliness--; + result = V_WRITE_SUCCESS; + reader = v_dataReaderInstanceReader(_this); + entry = v_dataReaderEntry(v_index(_this->index)->entry); + if ((msg->qos) && _this->owner.exclusive) { + OSPL_LOCK(reader); + if ((v_messageQos_getOwnershipStrength(msg->qos) < _this->owner.strength) && + (v_gidIsValid(_this->owner.gid)) && + (!v_gidEqual(_this->owner.gid, msg->writerGID))) + { + if (v_messageStateTest(msg, L_UNREGISTER)) { + /* An unregister message should decrease the liveliness. + * This is normally done in the v_dataReaderInstanceInsert() function. + * But, because this message is not forwarded and will not reach that + * function, the liveliness has the be decreased here. + * + * The register message takes a different route. It will not come here and + * will always reach v_dataReaderInstanceInsert() to increase liveliness. + */ + if (_this->liveliness > 0) + { + _this->liveliness--; + } } + result = V_WRITE_SUCCESS_NOT_STORED; } - result = V_WRITE_SUCCESS; - } else { - entry = v_dataReaderEntry(v_index(_this->index)->entry); + OSPL_UNLOCK(reader); + } + if (result == V_WRITE_SUCCESS) { thisPtr = &_this; result = v_dataReaderEntryWrite(entry, msg, (v_instance *)thisPtr, V_CONTEXT_GROUPWRITE); + } else if (result == V_WRITE_SUCCESS_NOT_STORED) { + result = V_WRITE_SUCCESS; } - return result; } @@ -1307,6 +1340,19 @@ v_dataReaderInstanceResetOwner( } } +void +v_dataReaderInstanceTransferGroupOwnership( + v_dataReaderInstance _this, + struct v_owner *groupOwnership) +{ + /* Simulate that the group transfers its ownership by a normal + * sample with an L_WRITE flag, since both messages with the + * L_REGISTER and with the L_UNREGISTER will be ignored. + */ + v_state messageState = L_WRITE; + (void)v_determineOwnershipByStrength(&_this->owner, groupOwnership, messageState); +} + v_message v_dataReaderInstanceCreateMessage( v_dataReaderInstance _this) @@ -1380,8 +1426,8 @@ CheckAndProcessReplacePolicyMarker( */ sample = v_dataReaderInstanceNewest(_this); while ( (sample != NULL) && (latestDisposedSample == NULL) ) { - if (v_readerSampleTestState(sample, L_DISPOSED) && - v_readerSampleTestState(sample, L_REPLACED)) { + if (v_dataReaderSampleMessageStateTest(sample, L_DISPOSED) && + v_dataReaderSampleMessageStateTest(sample, L_REPLACED)) { latestDisposedSample = sample; } else { sample = sample->older; @@ -1400,8 +1446,25 @@ CheckAndProcessReplacePolicyMarker( while ( (sample != latestDisposedSample->newer) && (sample != NULL) ) { /* Remember the next sample (in case the current one gets purged.) */ nextSample = sample->newer; + /* Keep the sample as the take will free it. The take can't be moved + * as it updates the lastConsumed which is required for the message + * compare. + */ + c_keep(sample); /* Take the sample */ v_dataReaderSampleTake(sample, NULL, NULL); + if (nextSample == NULL) { + c_equality equality = compareMessageToBookmark(v_dataReaderSampleMessage(sample), + &_this->lastConsumed); + if (equality != C_GT) { + /* Only if last consumed is part of the old history before the replace then reset last consumed. */ + _this->lastConsumed.sourceTimestamp = OS_TIMEW_ZERO; + v_gidSetNil(_this->lastConsumed.gid); + _this->lastConsumed.sequenceNumber = 0; + _this->lastConsumed.isImplicit = FALSE; + } + } + c_free(sample); /* Iterate to the next sample. */ sample = nextSample; } @@ -1417,15 +1480,9 @@ v_dataReaderInstanceInsert( v_messageContext context) { v_state messageState; -#if 0 - os_compare equality; -#endif v_index index; v_dataReader reader; v_dataReaderEntry entry; -#if 0 - v_readerQos qos; -#endif v_dataReaderResult result = V_DATAREADER_UNDETERMINED; struct v_owner ownership; v_ownershipResult ownershipResult = V_OWNERSHIP_OWNER; @@ -1444,28 +1501,6 @@ v_dataReaderInstanceInsert( entry = v_dataReaderEntry(index->entry); messageState = v_nodeState(message); -#if 0 - qos = v_reader(reader)->qos; - - /* - * Filter out messages that still belong to a previous lifecycle of this - * 'recycled' v_dataReaderInstance object. The epoch time determines when - * the previous lifecycle ended, so everything older than that can be - * discarded. - */ - if (qos->orderby.v.kind == V_ORDERBY_SOURCETIME) { - equality = os_timeWCompare(message->writeTime, _this->epoch); - if (equality != OS_MORE) { - CHECK_COUNT(_this); - /* TODO: in case of a transaction message should we look for - * existing transaction and abort it or ignore it and leave it - * to garbage collection or maybe this cannot occur? - */ - return V_DATAREADER_OUTDATED; - } - } -#endif - /* Replace merge policy code: * During a replace action all existing instances are marked with the replace flag * This flag will be reset at the end of the replace action or if a replace message @@ -1479,7 +1514,8 @@ v_dataReaderInstanceInsert( /* The first message carrying the L_MARK flag that is * added to an existing instance will clear the L_MARK * from the instance to indicate that the instance has - * been touched by the CATCHUP merge policy */ + * been touched by the CATCHUP merge policy + */ if ( v_stateTest(messageState, L_MARK) && v_dataReaderInstanceStateTest(_this, L_MARK)) { v_dataReaderInstanceStateClear(_this, L_MARK); @@ -1490,39 +1526,37 @@ v_dataReaderInstanceInsert( CHECK_EMPTINESS(_this); CHECK_INSTANCE_CONSISTENCY(_this); - if (message->qos) { - /* - * Test if ownership is exclusive and whether the writer identified + if (message->qos && context != V_CONTEXT_GETHISTORY) { + /* Test if ownership is exclusive and whether the writer identified * in the message should become owner. In case of an invalid GID * ownership is always assumed. (For example in case of disposeAll.) */ ownership.exclusive = v_messageQos_isExclusive(message->qos); if (ownership.exclusive == TRUE) { - c_bool claim = !v_stateTest(messageState, L_REGISTER); ownership.strength = v_messageQos_getOwnershipStrength(message->qos); ownership.gid = message->writerGID; - ownershipResult = v_determineOwnershipByStrength(&_this->owner, &ownership, claim); + ownershipResult = v_determineOwnershipByStrength(&_this->owner, &ownership, messageState); } } else { ownership.exclusive = FALSE; } + if (v_stateTest(messageState, L_REGISTER)) { + _this->liveliness++; + } if (context != V_CONTEXT_TRANSACTIONFLUSH) { /* All kinds of messages need to update alive writers. * The alive writers must always be updated even when the writer is * not owner, it remains a writer that is alive. */ - if (v_stateTest(messageState, L_REGISTER)) { - _this->liveliness++; - } if (v_message_isTransaction(message) && entry->transactionAdmin && context != V_CONTEXT_GETHISTORY ) { /* Exclude finished transaction messages (V_CONTEXT_TRANSACTIONFLUSH) and * exclude finished historical transaction messages (V_CONTEXT_GETHISTORY). * These should not go into the transaction admin but instead go into the * readers history, i.e. made available to the reader. - */ - /* If the sample belongs to an unfinished transaction, then insert it into the + * + * If the sample belongs to an unfinished transaction, then insert it into the * transactional administration. Since this is a newly arriving sample, it still * needs to make a resource claim. */ @@ -1561,36 +1595,18 @@ v_dataReaderInstanceInsert( result = V_DATAREADER_INSERTED; } else { _this->liveliness--; - /* It is possible (f.i. by deadline QoS) that a lower strength - * writer has already taken over before this unregister message - * of a possible higher strength writer is received/triggered. - * - * If the current unregister write has a higher strength and would - * claim this instance, then the lower strength writer (that has - * taken over and actually is providing data) will be ignored again, - * until the next deadline occurs. - * This will cause a 'gap' within sample delivery to the reader. - * The duration of this gap is the duration of deadline QoS. + /* In case the UNREGISTER did not result in a NOWRITERS state, + * because the liveliness counter is still > 0, then prevent + * any sample from being inserted by indicating this sample + * has already been processed. However, if the message also has + * a DISPOSE attached, then process the DISPOSE using the normal + * route (i.e. first determine ownership). The UNREGISTER + * flag will not have any further negative impact when + * processing the DISPOSE using this normal route (since an + * UNREGISTER following a DISPOSE does not result in any + * further state change). */ - if ((ownership.exclusive == TRUE) && (ownershipResult == V_OWNERSHIP_ALREADY_OWNER)) { - /* If the writer indicates will no longer update (own) this - * instance (by sending an unregister message) then the ownership - * is released by resetting the owner gid to nil. - */ - v_gidSetNil (_this->owner.gid); - } if (_this->liveliness > 0 && !v_stateTest(messageState, L_DISPOSED)) { - /* In case the UNREGISTER did not result in a NOWRITERS state, - * because the liveliness counter is still > 0, then prevent - * any sample from being inserted by indicating this sample - * has already been processed. However, if the message also has - * a DISPOSE attached, then process the DISPOSE using the normal - * route (i.e. first determine ownership). The UNREGISTER - * flag will not have any further negative impact when - * processing the DISPOSE using this normal route (since an - * UNREGISTER following a DISPOSE does not result in any - * further state change). - */ result = V_DATAREADER_INSERTED; } } @@ -1598,7 +1614,7 @@ v_dataReaderInstanceInsert( /* When no message has been inserted yet, handle all other types of messages. */ if (result == V_DATAREADER_UNDETERMINED) { - if (v_observerEventMask(reader) & V_EVENT_PREPARE_DELETE) { + if (OSPL_GET_EVENT_MASK(reader) & V_EVENT_PREPARE_DELETE) { /* No need to insert incomming messages when the reader is in process of being deleted. */ result = V_DATAREADER_INSERTED; } else if (ownership.exclusive == TRUE && (ownershipResult == V_OWNERSHIP_INCOMPATIBLE_QOS || @@ -1606,13 +1622,11 @@ v_dataReaderInstanceInsert( { /* No need to insert incomming messages form lower strength writers. */ result = V_DATAREADER_NOT_OWNER; + } else { + /* When message state is not determined then it can be inserted. */ + result = InsertSample(_this, message, context); } } - /* When message state is not determined then it can be inserted. */ - CHECK_COUNT(_this); - if (result == V_DATAREADER_UNDETERMINED) { - result = InsertSample(_this, message, context); - } CHECK_COUNT(_this); CHECK_EMPTINESS(_this); @@ -1723,8 +1737,8 @@ v_dataReaderInstanceTest( if (v_sampleMaskPass(sampleMask, sample)) { if (query) { /* The history samples are swapped with the first sample to make - sample-evaluation on instance level work. - */ + * sample-evaluation on instance level work. + */ if (sample != newestSample) { v_dataReaderInstanceSetNewest(_this,sample); } @@ -1863,7 +1877,11 @@ v_dataReaderSampleRead( v_dataReaderInstanceStateClear(instance, L_NEW); v_dataReaderInstanceStateClear(instance, L_STATECHANGED); if (!v_readerSampleTestState(sample, L_READ)) { - v_dataReaderInstanceReader(instance)->notReadCount--; + /* Sample with L_INMINSEPTIME have not incremented the notReadCount, + * they should also not decrement it (and should not be possible here) + */ + assert(!v_readerSampleTestState(sample, L_INMINSEPTIME)); + DECREASE_READER_NOT_READ_COUNT(v_dataReaderInstanceReader(instance)); v_readerSampleSetState(sample, L_LAZYREAD); } @@ -1929,8 +1947,7 @@ v_dataReaderInstanceReadSamples( { sample = sample->newer; } - /* If a sample is found matching the criteria, then consume it. - */ + /* If a sample is found matching the criteria, then consume it. */ if (sample) { if (v_sampleMaskPass(sampleMask, sample)) { @@ -2102,9 +2119,9 @@ v_dataReaderInstanceSampleRemove( sample->older = NULL; v_dataReaderSampleWipeViews(sample); v_dataReaderSampleRemoveFromLifespanAdmin(sample); - if (!v_readerSampleTestStateOr(sample, L_READ | L_LAZYREAD)) + if (!v_readerSampleTestStateOr(sample, L_READ | L_LAZYREAD | L_INMINSEPTIME)) { - reader->notReadCount--; + DECREASE_READER_NOT_READ_COUNT(reader); } /* Unregister messages should not affect the lastConsumed time. */ @@ -2113,8 +2130,8 @@ v_dataReaderInstanceSampleRemove( * sample, then update the history bookmark to indicate that * all samples prior to the current sample have been consumed. */ - if (v_historyBookmarkMessageCompare(&_this->lastConsumed, msg) != C_GT) - { + c_equality eq = compareMessageToBookmark(msg, &_this->lastConsumed); + if (eq == C_GT) { _this->lastConsumed.sourceTimestamp = msg->writeTime; _this->lastConsumed.gid = msg->writerGID; _this->lastConsumed.sequenceNumber = msg->sequenceNumber; @@ -2127,8 +2144,7 @@ v_dataReaderInstanceSampleRemove( c_free(sample); } -/* - * This function checks whether a sample is still contained in the +/* This function checks whether a sample is still contained in the * dataReaderInstance. It is not enough to check the instance pointer * of the dataReaderSample, because the sample under investigation * might just have been taken from the dataReaderInstance but still @@ -2552,7 +2568,8 @@ v_dataReaderInstanceUnregister ( } /* If there are no other registrations, or if the Writer had an autodispose - * policy set for this instance, then insert an unregister message explicitly. */ + * policy set for this instance, then insert an unregister message explicitly. + */ if (_this->liveliness == 1 || autoDispose) { /* Create an invalid sample as holder for the dispose. */ @@ -2620,12 +2637,12 @@ InsertPendingSample( qos = v_reader(reader)->qos; if (qos->orderby.v.kind == V_ORDERBY_SOURCETIME) { - equality = v_historyBookmarkMessageCompare(&_this->lastConsumed, message); + equality = compareMessageToBookmark(message, &_this->lastConsumed); if (equality == C_EQ) { CHECK_COUNT(_this); return V_DATAREADER_DUPLICATE_SAMPLE; - } else if (equality == C_GT) { + } else if (equality == C_LT) { CHECK_COUNT(_this); return V_DATAREADER_SAMPLE_LOST; } @@ -2657,9 +2674,9 @@ InsertPendingSample( v_dataReaderSample(s->older)->newer = sample; } s->older = sample; - updateIntermediateInstanceAndSampleState(_this, message, sample); + sample = updateIntermediateInstanceAndSampleState(_this, message, sample); } - if ((v_observerEventMask(reader) & V_EVENT_PREPARE_DELETE) == 0) { + if ((OSPL_GET_EVENT_MASK(reader) & V_EVENT_PREPARE_DELETE) == 0) { MakeSampleAvailable(_this, sample); } } @@ -2700,7 +2717,8 @@ v_dataReaderInstanceMatchesSampleMask ( v_sampleMask mask) { /* This function ignores sample state flags and only checks if the instance - flags specified match. */ + * flags specified match. + */ v_sampleMask state = V_MASK_ALIVE_INSTANCE; assert (_this != NULL && C_TYPECHECK (_this, v_dataReaderInstance)); diff --git a/src/kernel/code/v_dataReaderQuery.c b/src/kernel/code/v_dataReaderQuery.c index 9b9c85185..7c873bd9d 100644 --- a/src/kernel/code/v_dataReaderQuery.c +++ b/src/kernel/code/v_dataReaderQuery.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,6 +19,7 @@ * */ #include "v__dataReader.h" +#include "v__reader.h" #include "v_state.h" #include "v_event.h" #include "v_index.h" @@ -139,6 +141,90 @@ resolveFields ( return TRUE; } +static void +translate( + q_expr expr, + c_array sourceKeyList, /* c_array */ + c_array indexKeyList) /* c_array */ +{ + assert(expr); + assert(sourceKeyList); + assert(indexKeyList); + + if(q_getKind(expr) == T_FNC){ + if(q_isFnc(expr, Q_EXPR_PROPERTY)) { + /* first get the string representation of the id's in this expr */ + c_field f; + c_ulong i, index, size = 0; + c_char *name; + + name = q_propertyName(expr); + if(name) { + /* Now find the matching key in the sourceKeyList */ + index = size = c_arraySize(sourceKeyList); + + assert(size == c_arraySize(indexKeyList)); + + if(size == c_arraySize(indexKeyList)){ + for(i=0; iinstanceQ[i] == NULL) { - v_dataReaderUnlock(r); + OSPL_UNLOCK(r); v_queryFree(v_query(query)); c_free(query); c_iterFree(list); @@ -331,19 +417,19 @@ v_dataReaderQueryNew ( printf("\n"); #endif /* The following code generates the intermediate non-key query code. - Unfortunately c_queryNew creates the query expression relative to the - given collection's element type. In this case the instance type. - This means that to perform the query evaluation on each sample within - an instance the sample must be swapped with the instance sample field and - re-swapped after the evaluation. -*/ + * Unfortunately c_queryNew creates the query expression relative to the + * given collection's element type. In this case the instance type. + * This means that to perform the query evaluation on each sample within + * an instance the sample must be swapped with the instance sample field and + * re-swapped after the evaluation. + */ progExpr = F1(Q_EXPR_PROGRAM,subExpr); query->sampleQ[i] = c_queryNew(instanceSet, progExpr, values); q_dispose(progExpr); if (query->sampleQ[i] == NULL) { - v_dataReaderUnlock(r); + OSPL_UNLOCK(r); v_queryFree(v_query(query)); c_free(query); c_iterFree(list); @@ -374,7 +460,7 @@ v_dataReaderQueryNew ( assert(found == query); OS_UNUSED_ARG(found); - v_dataReaderUnlock(r); + OSPL_UNLOCK(r); if (values) { os_free(values); } @@ -401,12 +487,12 @@ v_dataReaderQueryFree ( if (v_objectKind(src) == K_DATAREADER) { r = v_dataReader(src); drQ = v_dataReaderQuery(_this); - v_dataReaderLock(r); + OSPL_LOCK(r); if (drQ->triggerValue) { v_dataReaderTriggerValueFree(drQ->triggerValue); drQ->triggerValue = NULL; } - v_dataReaderUnlock(r); + OSPL_UNLOCK(r); v_queryFree(v_query(_this)); } else { OS_REPORT(OS_ERROR, "v_dataReaderQueryFree failed", V_RESULT_ILL_PARAM, @@ -435,16 +521,17 @@ v_dataReaderQueryDeinit ( assert(v_objectKind(src) == K_DATAREADER); if (v_objectKind(src) == K_DATAREADER) { r = v_dataReader(src); - v_dataReaderLock(r); + OSPL_LOCK(r); found = c_setRemove(v_collection(r)->queries,_this,NULL,NULL); if (found != NULL) { assert(_this == found); /* Free the query found because it has been removed - * from the queries-collection */ + * from the queries-collection + */ c_free(found); v_queryDeinit(v_query(_this)); } - v_dataReaderUnlock(r); + OSPL_UNLOCK(r); } else { OS_REPORT(OS_ERROR, "v_dataReaderQueryDeinit failed", V_RESULT_ILL_PARAM, "source is not datareader"); @@ -532,7 +619,7 @@ v_dataReaderQueryTest( if (v_objectKind(src) == K_DATAREADER) { r = v_dataReader(src); - v_dataReaderLock(r); + OSPL_LOCK(r); instanceSet = r->index->notEmptyList; if (c_tableCount(instanceSet) > 0) { @@ -620,6 +707,14 @@ v_dataReaderQueryTest( } else { + /* When the triggerValue was an invalid sample, then it could + * be that it was a invalid dispose sample that was just replaced + * by an unregister sample. Set walk reaquired to true to catch + * those situations. + */ + if(!v_readerSampleTestState(_this->triggerValue, L_VALIDDATA)) { + _this->walkRequired = TRUE; + } /* The trigger value is no longer available in the DataReader. * It can therefore be reset. */ @@ -661,7 +756,7 @@ v_dataReaderQueryTest( if ( !pass ) { _this->state = V_STATE_INITIAL; } - v_dataReaderUnlock(r); + OSPL_UNLOCK(r); } else { OS_REPORT(OS_CRITICAL, "v_dataReaderQueryTest failed", V_RESULT_ILL_PARAM, @@ -794,9 +889,7 @@ v__dataReaderQueryOrderedReadOrTake( } if (v_actionResultTest (proceed, V_PROCEED)) { - if (v_subscriberAccessScope (v_readerSubscriber(source)) - != V_PRESENTATION_GROUP) - { + if (v_readerAccessScope(source) != V_PRESENTATION_GROUP) { sample = v_orderedInstanceReadSample ( source->orderedInstance, _this->sampleMask); } else { @@ -824,8 +917,8 @@ waitForData( if (*delay > 0) { c_ulong flags = 0; os_timeE time = os_timeEGet(); - v__observerSetEvent(v_observer(_this), V_EVENT_DATA_AVAILABLE); - flags = v__observerTimedWait(v_observer(_this), *delay); + v_observerSetEvent(v_observer(_this), V_EVENT_DATA_AVAILABLE); + flags = OSPL_CATCH_EVENT(_this, *delay); if (flags & V_EVENT_TIMEOUT) { result = V_RESULT_TIMEOUT; } else { @@ -859,17 +952,17 @@ v_dataReaderQueryRead ( r = v_dataReader(src); - v_dataReaderLock(r); + OSPL_LOCK(r); if (v_readerSubscriber(r) == NULL) { - v_dataReaderUnlock(r); + OSPL_UNLOCK(r); return V_RESULT_ALREADY_DELETED; } - result = v_subscriberTestBeginAccess(v_readerSubscriber(r)); + result = v_dataReaderAccessTest(r); if (result == V_RESULT_OK) { r->readCnt++; - if (v_subscriberAccessScope (v_readerSubscriber (r)) != V_PRESENTATION_GROUP) { - v_dataReaderUpdatePurgeListsLocked(r); + if (v_readerAccessScope(r) != V_PRESENTATION_GROUP) { + v_dataReaderUpdatePurgeLists(r); } if (v_orderedInstanceIsAligned (r->orderedInstance)) { result = v__dataReaderQueryOrderedReadOrTake ( @@ -973,7 +1066,7 @@ v_dataReaderQueryRead ( } c_iterFree(argument.emptyList); if (r->statistics) { - r->statistics->numberOfInstances = v_dataReaderInstanceCount(r); + r->statistics->numberOfInstances = v_dataReaderInstanceCount_nl(r); } } } @@ -993,7 +1086,7 @@ v_dataReaderQueryRead ( _this->state = _this->state & ~V_STATE_DATA_AVAILABLE; } } - v_dataReaderUnlock(r); + OSPL_UNLOCK(r); } else { result = V_RESULT_ILL_PARAM; OS_REPORT(OS_CRITICAL, @@ -1037,17 +1130,17 @@ v_dataReaderQueryReadInstance( assert(v_objectKind(src) == K_DATAREADER); if (v_objectKind(src) == K_DATAREADER) { r = v_dataReader(src); - v_dataReaderLock(r); + OSPL_LOCK(r); if (v_readerSubscriber(r) == NULL) { - v_dataReaderUnlock(r); + OSPL_UNLOCK(r); return V_RESULT_ALREADY_DELETED; } - result = v_subscriberTestBeginAccess(v_readerSubscriber(r)); + result = v_dataReaderAccessTest(r); if (result == V_RESULT_OK) { C_STRUCT(sampleActionArg) argument; v_orderedInstanceUnaligned (r->orderedInstance); r->readCnt++; - v_dataReaderUpdatePurgeListsLocked(r); + v_dataReaderUpdatePurgeLists(r); argument.action = action; argument.arg = arg; @@ -1096,7 +1189,7 @@ v_dataReaderQueryReadInstance( _this->state = _this->state & ~V_STATE_DATA_AVAILABLE; } } - v_dataReaderUnlock(r); + OSPL_UNLOCK(r); } else { result = V_RESULT_ILL_PARAM; OS_REPORT(OS_CRITICAL, @@ -1156,18 +1249,18 @@ v_dataReaderQueryReadNextInstance( assert(v_objectKind(src) == K_DATAREADER); if (v_objectKind(src) == K_DATAREADER) { r = v_dataReader(src); - v_dataReaderLock(r); + OSPL_LOCK(r); if (v_readerSubscriber(r) == NULL) { - v_dataReaderUnlock(r); + OSPL_UNLOCK(r); return V_RESULT_ALREADY_DELETED; } - result = v_subscriberTestBeginAccess(v_readerSubscriber(r)); + result = v_dataReaderAccessTest(r); if (result == V_RESULT_OK) { C_STRUCT(sampleActionArg) argument; v_orderedInstanceUnaligned (r->orderedInstance); r->readCnt++; - v_dataReaderUpdatePurgeListsLocked(r); + v_dataReaderUpdatePurgeLists(r); a.action = action; a.arg = arg; @@ -1238,7 +1331,7 @@ v_dataReaderQueryReadNextInstance( } action(NULL, arg); /* This triggers the action routine that the last sample is read. */ } - v_dataReaderUnlock(r); + OSPL_UNLOCK(r); } else { result = V_RESULT_ILL_PARAM; OS_REPORT(OS_CRITICAL, "v_dataReaderQueryReadNextInstance failed", V_RESULT_ILL_PARAM, @@ -1333,17 +1426,17 @@ v_dataReaderQueryTake( if (v_objectKind(src) == K_DATAREADER) { r = v_dataReader(src); - v_dataReaderLock(r); + OSPL_LOCK(r); if (v_readerSubscriber(r) == NULL) { - v_dataReaderUnlock(r); + OSPL_UNLOCK(r); return V_RESULT_ALREADY_DELETED; } - result = v_subscriberTestBeginAccess(v_readerSubscriber(r)); + result = v_dataReaderAccessTest(r); if (result == V_RESULT_OK) { r->readCnt++; - if (v_subscriberAccessScope (v_readerSubscriber (r)) != V_PRESENTATION_GROUP) { - v_dataReaderUpdatePurgeListsLocked(r); + if (v_readerAccessScope(r) != V_PRESENTATION_GROUP) { + v_dataReaderUpdatePurgeLists(r); } if (v_orderedInstanceIsAligned (r->orderedInstance)) { result = v__dataReaderQueryOrderedReadOrTake ( @@ -1437,7 +1530,7 @@ v_dataReaderQueryTake( } c_iterFree(argument.emptyList); if (r->statistics) { - r->statistics->numberOfInstances = v_dataReaderInstanceCount(r); + r->statistics->numberOfInstances = v_dataReaderInstanceCount_nl(r); } } } @@ -1461,7 +1554,7 @@ v_dataReaderQueryTake( _this->state = _this->state & ~V_STATE_DATA_AVAILABLE; } } - v_dataReaderUnlock(r); + OSPL_UNLOCK(r); } else { result = V_RESULT_ILL_PARAM; OS_REPORT(OS_CRITICAL, @@ -1507,18 +1600,18 @@ v_dataReaderQueryTakeInstance( assert(v_objectKind(src) == K_DATAREADER); if (v_objectKind(src) == K_DATAREADER) { r = v_dataReader(src); - v_dataReaderLock(r); + OSPL_LOCK(r); if (v_readerSubscriber(r) == NULL) { - v_dataReaderUnlock(r); + OSPL_UNLOCK(r); return V_RESULT_ALREADY_DELETED; } - result = v_subscriberTestBeginAccess(v_readerSubscriber(r)); + result = v_dataReaderAccessTest(r); if (result == V_RESULT_OK) { C_STRUCT(sampleActionArg) argument; v_orderedInstanceUnaligned (r->orderedInstance); r->readCnt++; - v_dataReaderUpdatePurgeListsLocked(r); + v_dataReaderUpdatePurgeLists(r); argument.action = action; argument.arg = arg; @@ -1573,7 +1666,7 @@ v_dataReaderQueryTakeInstance( _this->state = _this->state & ~V_STATE_DATA_AVAILABLE; } } - v_dataReaderUnlock(r); + OSPL_UNLOCK(r); } else { result = V_RESULT_ILL_PARAM; OS_REPORT(OS_CRITICAL, @@ -1620,18 +1713,18 @@ v_dataReaderQueryTakeNextInstance( assert(v_objectKind(src) == K_DATAREADER); if (v_objectKind(src) == K_DATAREADER) { r = v_dataReader(src); - v_dataReaderLock(r); + OSPL_LOCK(r); if (v_readerSubscriber(r) == NULL) { - v_dataReaderUnlock(r); + OSPL_UNLOCK(r); return V_RESULT_ALREADY_DELETED; } - result = v_subscriberTestBeginAccess(v_readerSubscriber(r)); + result = v_dataReaderAccessTest(r); if (result == V_RESULT_OK) { C_STRUCT(sampleActionArg) argument; v_orderedInstanceUnaligned (r->orderedInstance); r->readCnt++; - v_dataReaderUpdatePurgeListsLocked(r); + v_dataReaderUpdatePurgeLists(r); a.action = action; a.arg = arg; @@ -1724,7 +1817,7 @@ v_dataReaderQueryTakeNextInstance( } action(NULL, arg); /* This triggers the action routine that the last sample is read. */ } - v_dataReaderUnlock(r); + OSPL_UNLOCK(r); } else { result = V_RESULT_ILL_PARAM; OS_REPORT(OS_CRITICAL, @@ -1757,7 +1850,7 @@ v_dataReaderQueryNotifyDataAvailable( EVENT_TRACE("v_dataReaderQueryNotifyDataAvailable(_this = 0x%x, event = 0x%x)\n", _this, e); - v_observerLock(v_observer(_this)); + OSPL_LOCK(_this); /* Only store the trigger value and notify observers if no * trigger value is set before. * The trigger value is reset when it no longer satisfies the Query. @@ -1779,8 +1872,8 @@ v_dataReaderQueryNotifyDataAvailable( _this->walkRequired = TRUE; } _this->state |= V_STATE_DATA_AVAILABLE; - v_observableNotify(v_observable(_this),e); - v_observerUnlock(v_observer(_this)); + OSPL_THROW_EVENT(_this, e); + OSPL_UNLOCK(_this); return TRUE; } @@ -1826,7 +1919,7 @@ v_dataReaderQuerySetParams( kernel = v_objectKernel(_this); r = v_dataReader(src); - v_dataReaderLock(r); + OSPL_LOCK(r); len = c_arraySize(_this->instanceQ); /* Try to assign parameter values to all sub-queries. * If one or more of the assignments fails then it indicates that @@ -1849,7 +1942,7 @@ v_dataReaderQuerySetParams( e = q_takePar(predicate,0); if (!resolveFields(r,e)) { - v_dataReaderUnlock(r); + OSPL_UNLOCK(r); q_dispose(e); q_dispose(predicate); os_free(values); @@ -1860,7 +1953,7 @@ v_dataReaderQuerySetParams( q_disjunctify(e); e = q_removeNots(e); - list = deOr(e,NULL); + list = q_exprDeOr(e,NULL); len = c_iterLength(list); type = c_resolve(c_getBase(c_object(kernel)),"c_query"); @@ -1927,7 +2020,7 @@ v_dataReaderQuerySetParams( result = TRUE; _this->walkRequired = TRUE; - v_dataReaderUnlock(r); + OSPL_UNLOCK(r); if (values) { os_free(values); } @@ -1946,14 +2039,14 @@ v_dataReaderQuerySetParams( } if (result == TRUE) { - if (v_observableHasObservers(v_observable(_this))) { - C_STRUCT(v_event) event; + C_STRUCT(v_event) event; - event.kind = V_EVENT_TRIGGER; - event.source = v_observable(_this); - event.data = NULL; - v_observableNotify(v_observable(_this), &event); - } + event.kind = V_EVENT_TRIGGER; + event.source = v_observable(_this); + event.data = NULL; + event.handled = FALSE; + + OSPL_THROW_EVENT(_this, &event); } return result; diff --git a/src/kernel/code/v_dataReaderSample.c b/src/kernel/code/v_dataReaderSample.c index fc5f3d973..37a0f2f84 100644 --- a/src/kernel/code/v_dataReaderSample.c +++ b/src/kernel/code/v_dataReaderSample.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,8 +21,9 @@ #include "v__dataReaderSample.h" #include "v_dataReaderEntry.h" #include "v__dataReaderInstance.h" -#include "v_dataViewInstance.h" -#include "v_dataViewSample.h" +#include "v__dataView.h" +#include "v__dataViewInstance.h" +#include "v__dataViewSample.h" #include "v_messageQos.h" #include "v__reader.h" #include "v_state.h" @@ -60,7 +62,6 @@ v_dataReaderSampleNew( /* The expiry time calculation is dependent on the DestinationOrderQos(readerQos->orderby.v.kind): * In case of the by_reception_timestamp kind the expiry time is determined based on insertion time(sample->insertTime). * In case of the by_source_timestamp kind the expiry time is determined based on source time (message->writeTime). - * see OSPL-871 */ msgEpoch = os_timeEGet(); diff --git a/src/kernel/code/v_dataReaderStatistics.c b/src/kernel/code/v_dataReaderStatistics.c index 082d71b2a..97f925d20 100644 --- a/src/kernel/code/v_dataReaderStatistics.c +++ b/src/kernel/code/v_dataReaderStatistics.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,7 +24,10 @@ #include "v_maxValue.h" #include "v_fullCounter.h" -v_dataReaderStatistics v_dataReaderStatisticsNew(v_kernel k) +_Ret_notnull_ +v_dataReaderStatistics +v_dataReaderStatisticsNew( + _In_ v_kernel k) { v_dataReaderStatistics rs; c_type readerStatisticsType; @@ -37,7 +41,9 @@ v_dataReaderStatistics v_dataReaderStatisticsNew(v_kernel k) return rs; } -void v_dataReaderStatisticsInit(v_dataReaderStatistics rs) +void +v_dataReaderStatisticsInit( + _Inout_ v_dataReaderStatistics rs) { assert(rs != NULL); assert(C_TYPECHECK(rs,v_dataReaderStatistics)); diff --git a/src/kernel/code/v_dataView.c b/src/kernel/code/v_dataView.c index f06b2ed57..757611e07 100644 --- a/src/kernel/code/v_dataView.c +++ b/src/kernel/code/v_dataView.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,9 +28,11 @@ #include "c_stringSupport.h" #include "v__entity.h" +#include "v__reader.h" #include "v__dataReader.h" #include "v__query.h" -#include "v_dataViewInstance.h" +#include "v__dataViewInstance.h" +#include "v__dataReaderSample.h" #include "v_readerQos.h" #include "v_dataViewQos.h" #include "v_qos.h" @@ -37,7 +40,7 @@ #include "v__topic.h" #include "v__index.h" #include "v__observer.h" -#include "v_observable.h" +#include "v__observable.h" #include "v_state.h" #include "v__collection.h" #include "v__subscriber.h" @@ -234,7 +237,10 @@ v_dataViewInit( q = v_dataViewQosNew(kernel, qos); dataView->qos = q; - v_collectionInit(v_collection(dataView), name, enable); + v_collectionInit(v_collection(dataView), name); + if(enable) { + (void)v_entityEnable(v_entity(dataView)); + } dataViewSampleType = dataViewSampleTypeNew(dataReader); assert(dataViewSampleType != NULL); @@ -243,16 +249,12 @@ v_dataViewInit( /* When the view has defined its own keys, then grab the key-definition from * the userKeyQosPolicy and the key-values from the messages that are passed. */ - if (qos->userKey.v.enable) - { - if (qos->userKey.v.expression) - { + if (qos->userKey.v.enable) { + if (qos->userKey.v.expression) { totalSize = strlen(qos->userKey.v.expression) + 1; keyExpr = os_malloc(totalSize); os_strncpy(keyExpr, qos->userKey.v.expression, totalSize); - } - else - { + } else { keyExpr = NULL; } } @@ -261,34 +263,30 @@ v_dataViewInit( * the original keys as specified on the topic, or the reader may have * overruled the topic keys by means of its own userKeyQosPolicy. */ - else if (v_reader(dataReader)->qos->userKey.v.enable) - { - if (v_reader(dataReader)->qos->userKey.v.expression) - { + else if (v_reader(dataReader)->qos->userKey.v.enable) { + if (v_reader(dataReader)->qos->userKey.v.expression) { totalSize = strlen(v_reader(dataReader)->qos->userKey.v.expression) + 1; keyExpr = os_malloc(totalSize); os_strncpy(keyExpr, v_reader(dataReader)->qos->userKey.v.expression, totalSize); - } - else - { + } else { keyExpr = NULL; } - } - else - { + } else { v_topic topic; - topic = v_dataReaderGetTopic(dataReader); - if (v_topicKeyExpr(topic) != NULL) - { - totalSize = strlen(v_topicKeyExpr(topic)) + 1; - keyExpr = os_malloc(totalSize); - os_strncpy(keyExpr, v_topicKeyExpr(topic), totalSize); - } - else - { + topic = v_readerGetTopic(v_reader(dataReader)); + + if(topic) { + if (v_topicKeyExpr(topic) != NULL) { + totalSize = strlen(v_topicKeyExpr(topic)) + 1; + keyExpr = os_malloc(totalSize); + os_strncpy(keyExpr, v_topicKeyExpr(topic), totalSize); + } else { + keyExpr = NULL; + } + c_free(topic); + } else { keyExpr = NULL; } - c_free(topic); } prefix = "sample.sample.message.userData."; if (keyExpr != NULL) { @@ -421,16 +419,21 @@ v_dataViewWrite( { v_actionResult result = 0; v_dataViewInstance instance, found; + v_dataViewSample viewSample; assert(C_TYPECHECK(_this,v_dataView)); if (!v_stateTest(v_nodeState(v_dataReaderSampleMessage(sample)),L_REGISTER)) { - instance = v_dataViewInstanceNew(_this,sample); + viewSample = v_dataViewSampleNew(_this, sample); + assert(viewSample); + instance = v_dataViewInstanceNew(_this,viewSample); found = c_tableInsert(_this->instances,instance); + v_readerSample(viewSample)->instance = found; + v_dataReaderSampleAddViewSample(sample,viewSample); if (found != instance) { - v_dataViewInstanceWipe(instance); - v_dataViewInstanceWrite(found,sample); + v_dataViewInstanceWrite(found,viewSample, NULL); } + v_dataViewNotifyDataAvailable(_this, viewSample); c_free(instance); } @@ -460,10 +463,8 @@ waitForData( if (*delay > 0) { c_ulong flags = 0; os_timeE time = os_timeEGet(); - v_observerLock(_this); - v__observerSetEvent(v_observer(_this), V_EVENT_DATA_AVAILABLE); - flags = v__observerTimedWait(v_observer(_this), *delay); - v_observerUnlock(_this); + v_observerSetEvent(v_observer(_this), V_EVENT_DATA_AVAILABLE); + flags = OSPL_CATCH_EVENT(_this, *delay); if (flags & V_EVENT_TIMEOUT) { result = V_RESULT_TIMEOUT; } else { @@ -517,12 +518,12 @@ v_dataViewRead( assert(C_TYPECHECK(_this,v_dataView)); - v_dataViewLock(_this); + OSPL_LOCK(_this); if (v_readerSubscriber(_this->reader) == NULL) { - v_dataViewUnlock(_this); + OSPL_UNLOCK(_this); return V_RESULT_ALREADY_DELETED; } - result = v_subscriberTestBeginAccess(v_readerSubscriber(_this->reader)); + result = v_dataReaderAccessTest(_this->reader); if (result == V_RESULT_OK) { argument.action = action; argument.arg = arg; @@ -545,7 +546,7 @@ v_dataViewRead( action(NULL,arg); /* This triggers the action routine that the * last sample is read. */ } - v_dataViewUnlock(_this); + OSPL_UNLOCK(_this); return result; } @@ -569,12 +570,12 @@ v_dataViewReadInstance( assert(C_TYPECHECK(instance, v_dataViewInstance)); - v_dataViewLock(_this); + OSPL_LOCK(_this); if (v_readerSubscriber(_this->reader) == NULL) { - v_dataViewUnlock(_this); + OSPL_UNLOCK(_this); return V_RESULT_ALREADY_DELETED; } - result = v_subscriberTestBeginAccess(v_readerSubscriber(_this->reader)); + result = v_dataReaderAccessTest(_this->reader); if (result == V_RESULT_OK) { argument.action = action; argument.arg = arg; @@ -597,7 +598,7 @@ v_dataViewReadInstance( action(NULL,arg); /* This triggers the action routine that the * last sample is read. */ } - v_dataViewUnlock(_this); + OSPL_UNLOCK(_this); return result; } @@ -618,16 +619,16 @@ v_dataViewReadNextInstance( assert(C_TYPECHECK(_this,v_dataView)); assert(C_TYPECHECK(instance, v_dataViewInstance)); - v_dataViewLock(_this); + OSPL_LOCK(_this); if (v_readerSubscriber(_this->reader) == NULL) { - v_dataViewUnlock(_this); + OSPL_UNLOCK(_this); return V_RESULT_ALREADY_DELETED; } if (instance != NULL && ((v_dataView)v_instanceEntity(instance)) != _this) { - v_dataViewUnlock(_this); + OSPL_UNLOCK(_this); return V_RESULT_PRECONDITION_NOT_MET; } - result = v_subscriberTestBeginAccess(v_readerSubscriber(_this->reader)); + result = v_dataReaderAccessTest(_this->reader); if (result == V_RESULT_OK) { v_dataReaderUpdatePurgeLists(v_dataReader(_this->reader)); @@ -654,7 +655,7 @@ v_dataViewReadNextInstance( action(NULL,arg); /* This triggers the action routine that the * last sample is read. */ } - v_dataViewUnlock(_this); + OSPL_UNLOCK(_this); return result; } @@ -688,12 +689,12 @@ v_dataViewTake( assert(C_TYPECHECK(_this,v_dataView)); - v_dataViewLock(_this); + OSPL_LOCK(_this); if (v_readerSubscriber(_this->reader) == NULL) { - v_dataViewUnlock(_this); + OSPL_UNLOCK(_this); return V_RESULT_ALREADY_DELETED; } - result = v_subscriberTestBeginAccess(v_readerSubscriber(_this->reader)); + result = v_dataReaderAccessTest(_this->reader); if (result == V_RESULT_OK) { v_dataReaderUpdatePurgeLists(v_dataReader(_this->reader)); @@ -723,7 +724,7 @@ v_dataViewTake( } action(NULL,arg); /* This triggers the action routine that the last sample is read. */ } - v_dataViewUnlock(_this); + OSPL_UNLOCK(_this); return result; } @@ -748,12 +749,12 @@ v_dataViewTakeInstance( assert(C_TYPECHECK(instance, v_dataViewInstance)); - v_dataViewLock(_this); + OSPL_LOCK(_this); if (v_readerSubscriber(_this->reader) == NULL) { - v_dataViewUnlock(_this); + OSPL_UNLOCK(_this); return V_RESULT_ALREADY_DELETED; } - result = v_subscriberTestBeginAccess(v_readerSubscriber(_this->reader)); + result = v_dataReaderAccessTest(_this->reader); if (result == V_RESULT_OK) { v_dataReaderUpdatePurgeLists(v_dataReader(_this->reader)); @@ -778,7 +779,7 @@ v_dataViewTakeInstance( } action(NULL,arg); /* This triggers the action routine that the last sample is read. */ } - v_dataViewUnlock(_this); + OSPL_UNLOCK(_this); return result; } @@ -798,16 +799,16 @@ v_dataViewTakeNextInstance( assert(C_TYPECHECK(_this,v_dataView)); assert(C_TYPECHECK(instance,v_dataViewInstance )); - v_dataViewLock(_this); + OSPL_LOCK(_this); if (v_readerSubscriber(_this->reader) == NULL) { - v_dataViewUnlock(_this); + OSPL_UNLOCK(_this); return V_RESULT_ALREADY_DELETED; } if (instance != NULL && ((v_dataView)v_instanceEntity(instance)) != _this) { - v_dataViewUnlock(_this); + OSPL_UNLOCK(_this); return V_RESULT_PRECONDITION_NOT_MET; } - result = v_subscriberTestBeginAccess(v_readerSubscriber(_this->reader)); + result = v_dataReaderAccessTest(_this->reader); if (result == V_RESULT_OK) { v_dataReaderUpdatePurgeLists(v_dataReader(_this->reader)); @@ -844,7 +845,7 @@ v_dataViewTakeNextInstance( action(NULL,arg); /* This triggers the action routine that the * last sample is read. */ } - v_dataViewUnlock(_this); + OSPL_UNLOCK(_this); return result; } @@ -857,9 +858,9 @@ v_dataViewGetQos( assert(C_TYPECHECK(_this,v_dataView)); - v_dataViewLock(_this); + OSPL_LOCK(_this); qos = c_keep(_this->qos); - v_dataViewUnlock(_this); + OSPL_UNLOCK(_this); return qos; } @@ -894,12 +895,12 @@ v_dataViewLookupInstance( assert(C_TYPECHECK(_this,v_dataView)); assert(C_TYPECHECK(keyTemplate,v_message)); - v_dataViewLock(_this); + OSPL_LOCK(_this); readerSampleTemplate.message = keyTemplate; viewSampleTemplate.sample = (v_readerSample)(&readerSampleTemplate); instanceTemplate.sample = (v_dataViewSample)(&viewSampleTemplate); instance = c_find(_this->instances, &instanceTemplate); - v_dataViewUnlock(_this); + OSPL_UNLOCK(_this); return instance; } @@ -915,7 +916,7 @@ v_dataViewContainsInstance ( assert(C_TYPECHECK(instance,v_dataViewInstance)); if (instance) { - v_dataViewLock(_this); + OSPL_LOCK(_this); if ( ((v_dataView)v_instanceEntity(instance)) == _this) { found = TRUE; } else { @@ -923,7 +924,7 @@ v_dataViewContainsInstance ( "Invalid dataViewInstance: no attached to DataView" "<_this = 0x%"PA_PRIxADDR" instance = 0x%"PA_PRIxADDR">", (os_address)_this, (os_address)instance); } - v_dataViewUnlock(_this); + OSPL_UNLOCK(_this); } return found; } @@ -956,13 +957,13 @@ v_dataViewNotifyDataAvailable( event.kind = V_EVENT_DATA_AVAILABLE; event.source = NULL; event.data = sample; + event.handled = FALSE; - v_observerLock(v_observer(_this)); + OSPL_LOCK(_this); c_setWalk(v_collection(_this)->queries, queryNotifyDataAvailable, &event); - v_observerUnlock(v_observer(_this)); - + OSPL_UNLOCK(_this); /* Also notify myself, since the user reader might be waiting. */ event.source = v_observable(_this); - v_observableNotify(v_observable(_this), &event); + OSPL_THROW_EVENT(_this, &event); } diff --git a/src/kernel/code/v_dataViewInstance.c b/src/kernel/code/v_dataViewInstance.c index 60903d73e..ecfe08079 100644 --- a/src/kernel/code/v_dataViewInstance.c +++ b/src/kernel/code/v_dataViewInstance.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,8 +18,8 @@ * limitations under the License. * */ -#include "v_dataViewInstance.h" -#include "v_dataViewSample.h" +#include "v__dataViewInstance.h" +#include "v__dataViewSample.h" #include "v__dataReaderSample.h" #include "v__dataView.h" #include "v_state.h" @@ -106,38 +107,28 @@ checkInstance( v_dataViewInstance v_dataViewInstanceNew( v_dataView dataView, - v_readerSample sample) + v_dataViewSample viewSample) { v_dataViewInstance instance; - v_dataViewSample viewSample; assert(dataView); - assert(sample); + assert(viewSample); assert(C_TYPECHECK(dataView,v_dataView)); - assert(C_TYPECHECK(sample,v_readerSample)); + assert(C_TYPECHECK(viewSample,v_dataViewSample)); instance = v_dataViewInstance(c_new(dataView->instanceType)); if (instance) { v_object(instance)->kernel = v_objectKernel(dataView); v_objectKind(instance) = K_DATAVIEWINSTANCE; v_instanceInit(v_instance(instance), v_entity(dataView)); - viewSample = v_dataViewSampleNew(instance,sample); - if (viewSample) { - viewSample->next = viewSample; - viewSample->prev = NULL; - v_dataViewInstanceTemplate(instance)->sample = viewSample; - v_dataReaderSampleAddViewSample(sample,viewSample); - instance->sampleCount = 1; - - v_stateSet(v_instanceState(instance),L_NEW); - v_stateClear(v_readerSample(viewSample)->sampleState,L_READ); - - assert(C_TYPECHECK(instance,v_dataViewInstance)); - v_dataViewNotifyDataAvailable(dataView, viewSample); - } else { - v_publicFree(v_public(instance)); - c_free(instance); - } + viewSample->next = viewSample; + v_dataViewInstanceTemplate(instance)->sample = viewSample; + instance->sampleCount = 1; + + v_stateSet(v_instanceState(instance),L_NEW); + v_stateClear(v_readerSample(viewSample)->sampleState,L_READ); + + assert(C_TYPECHECK(instance,v_dataViewInstance)); CHECK_INSTANCE(instance); } else { OS_REPORT(OS_FATAL, OS_FUNCTION, V_RESULT_INTERNAL_ERROR, @@ -189,8 +180,8 @@ v_dataViewInstanceWipe( CHECK_ZERO_INSTANCE(instance); } -v_dataViewSample -v__dataViewInstanceWrite( +void +v_dataViewInstanceWrite( v_dataViewInstance instance, v_dataViewSample sample, v_dataViewSample position) @@ -205,7 +196,8 @@ v__dataViewInstanceWrite( head = v_dataViewInstanceTemplate(instance)->sample; /* Keep alive view sample must be discarded, but only after the new - view sample is inserted. */ + * view sample is inserted. + */ if (instance->sampleCount == 0) { assert (position == NULL); assert(head == NULL); @@ -215,7 +207,7 @@ v__dataViewInstanceWrite( (*sampleptr) = sample; } else if (position == NULL) { - assert(head); + assert(head); /* "normal" use case, append sample to list */ sampleptr = (v_dataViewSample *)&head->next; sample->next = (*sampleptr); @@ -225,7 +217,7 @@ v__dataViewInstanceWrite( } else { assert (position->next != NULL); - assert(head); + assert(head); sample->next = position->next; if (position == head) { sampleptr = &v_dataViewInstanceTemplate(instance)->sample; @@ -239,35 +231,7 @@ v__dataViewInstanceWrite( sample->prev = position; (*sampleptr) = sample; } - instance->sampleCount++; - - return sample; -} - - - -v_writeResult -v_dataViewInstanceWrite ( - v_dataViewInstance instance, - v_readerSample sample) -{ - v_dataViewSample viewSample; - - assert(C_TYPECHECK(instance,v_dataViewInstance)); - assert(C_TYPECHECK(sample,v_readerSample)); - - CHECK_INSTANCE(instance); - - viewSample = v_dataViewSampleNew(instance,sample); - if (viewSample) { - v__dataViewInstanceWrite (instance, viewSample, NULL); - v_dataReaderSampleAddViewSample(sample,viewSample); - assert(c_refCount(viewSample) == 1); - v_dataViewNotifyDataAvailable(v_dataView(v_instanceEntity(instance)), viewSample); - } - CHECK_INSTANCE(instance); - return V_WRITE_SUCCESS; } void @@ -378,8 +342,8 @@ v_dataViewInstanceReadSamples( if (v_sampleMaskPass(sampleMask, sample)) { if (query != NULL) { /* The history samples are swapped with the first sample to make - sample-evaluation on instance level work. - */ + * sample-evaluation on instance level work. + */ if (sample != firstSample) { v_dataViewInstanceTemplate(instance)->sample = sample; } @@ -400,33 +364,6 @@ v_dataViewInstanceReadSamples( return v_actionResultTest(result, V_PROCEED); } -void -v_dataViewInstanceWalkSamples( - v_dataViewInstance instance, - v_readerSampleAction action, - c_voidp arg) -{ - v_dataViewSample sample; - v_actionResult result = V_PROCEED; - - assert(C_TYPECHECK(instance,v_dataViewInstance)); - CHECK_INSTANCE(instance); - - if (instance == NULL) { - return; - } - if (instance->sampleCount == 0) { - return; - } - sample = v_dataViewInstanceTemplate(instance)->sample; - assert (sample != NULL); - while (sample != NULL && v_actionResultTest(result, V_PROCEED)) { - result = action(v_readerSample(sample),arg); - sample = sample->prev; - } - CHECK_INSTANCE(instance); -} - typedef c_bool (*v_sampleCondition)(v_dataViewSample sample, c_voidp arg); static c_bool @@ -494,7 +431,8 @@ evalInstanceQuery( assert(query != NULL); /* The history samples are swapped with the first sample to make - sample-evaluation on instance level work. */ + * sample-evaluation on instance level work. + */ firstSample = v_dataViewInstanceTemplate(instance)->sample; if (sample != firstSample) { v_dataViewInstanceTemplate(instance)->sample = sample; @@ -519,8 +457,6 @@ v_dataViewInstanceTakeSamples( struct v_instanceQueryArg_s instanceQueryArg_s; assert(C_TYPECHECK(instance,v_dataViewInstance)); - /* No check, already done in TakeWithCondition */ - /* CHECK_INSTANCE(instance); */ if (query != NULL) { instanceQueryArg_s.query = query; @@ -531,8 +467,6 @@ v_dataViewInstanceTakeSamples( proceed = v_dataViewInstanceTakeWithCondition(instance,NULL,NULL,sampleMask,action,arg); } - /* No check, already done in TakeWithCondition */ - /* CHECK_INSTANCE(instance); */ return proceed; } diff --git a/src/kernel/code/v_dataViewQos.c b/src/kernel/code/v_dataViewQos.c index 6eb2f2009..9d3fc6724 100644 --- a/src/kernel/code/v_dataViewQos.c +++ b/src/kernel/code/v_dataViewQos.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -28,9 +29,6 @@ static const v_qosChangeMask immutableMask = V_POLICY_BIT_USERKEY; -/************************************************************** - * private functions - **************************************************************/ static c_bool v_dataViewQosValidValues( v_dataViewQos qos) @@ -50,9 +48,6 @@ v_dataViewQosValidValues( return (valuesNok) ? FALSE : TRUE; } -/************************************************************** - * constructor/destructor - **************************************************************/ v_dataViewQos v_dataViewQosNew( v_kernel kernel, @@ -87,11 +82,6 @@ v_dataViewQosFree( c_free(q); } - - -/************************************************************** - * Protected functions - **************************************************************/ v_result v_dataViewQosCompare( v_dataViewQos q, @@ -122,9 +112,6 @@ v_dataViewQosCompare( return result; } -/************************************************************** - * Public functions - **************************************************************/ v_result v_dataViewQosCheck( v_dataViewQos _this) diff --git a/src/kernel/code/v_dataViewQuery.c b/src/kernel/code/v_dataViewQuery.c index 92889c297..0950586a5 100644 --- a/src/kernel/code/v_dataViewQuery.c +++ b/src/kernel/code/v_dataViewQuery.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,7 +26,7 @@ #include "v_projection.h" #include "v_entity.h" #include "v_handle.h" -#include "v_dataViewInstance.h" +#include "v__dataViewInstance.h" #include "v__query.h" #include "v__observable.h" #include "v__observer.h" @@ -215,10 +216,10 @@ v_dataViewQueryNew ( values = NULL; } - v_dataViewLock(view); + OSPL_LOCK(view); subtype = c_subType(view->instances); if (!resolveFields(subtype,e)) { - v_dataViewUnlock(view); + OSPL_UNLOCK(view); q_dispose(e); q_dispose(predicate); c_free(subtype); @@ -242,7 +243,7 @@ v_dataViewQueryNew ( q_disjunctify(e); e = q_removeNots(e); - list = deOr(e,NULL); + list = q_exprDeOr(e,NULL); len = c_iterLength(list); type = c_resolve(c_getBase(c_object(kernel)),"c_query"); @@ -292,7 +293,7 @@ v_dataViewQueryNew ( found = ospl_c_insert(v_collection(view)->queries,query); assert(found == query); OS_UNUSED_ARG(found); - v_dataViewUnlock(view); + OSPL_UNLOCK(view); if (values) { os_free(values); } @@ -317,12 +318,12 @@ v_dataViewQueryFree ( assert(v_objectKind(src) == K_DATAVIEW); if (v_objectKind(src) == K_DATAVIEW) { v = v_dataView(src); - v_dataViewLock(v); + OSPL_LOCK(v); if (_this->triggerValue) { v_dataViewTriggerValueFree(_this->triggerValue); _this->triggerValue = NULL; } - v_dataViewUnlock(v); + OSPL_UNLOCK(v); v_queryFree(v_query(_this)); } else { OS_REPORT(OS_ERROR, "v_dataViewQueryFree failed", 0, @@ -350,14 +351,15 @@ v_dataViewQueryDeinit ( assert(v_objectKind(src) == K_DATAVIEW); if (v_objectKind(src) == K_DATAVIEW) { v = v_dataView(src); - v_dataViewLock(v); + OSPL_LOCK(v); found = c_remove(v_collection(v)->queries,_this,NULL,NULL); assert(_this == found); /* Free the query found because it has been removed from the - * queries-collection */ + * queries-collection + */ c_free(found); v_queryDeinit(v_query(_this)); - v_dataViewUnlock(v); + OSPL_UNLOCK(v); } else { OS_REPORT(OS_ERROR, "v_dataViewQueryDeinit failed", V_RESULT_ILL_PARAM, @@ -446,7 +448,7 @@ v_dataViewQueryTest( assert(v_objectKind(src) == K_DATAVIEW); if (v_objectKind(src) == K_DATAVIEW) { v = v_dataView(src); - v_dataViewLock(v); + OSPL_LOCK(v); v_dataReaderUpdatePurgeLists(v_dataReader(v->reader)); instanceSet = v->instances; @@ -560,7 +562,7 @@ v_dataViewQueryTest( if ( !pass ) { _this->state = V_STATE_INITIAL; } - v_dataViewUnlock(v); + OSPL_UNLOCK(v); } else { OS_REPORT(OS_CRITICAL, "v_dataViewQueryTest failed", V_RESULT_ILL_PARAM, @@ -619,13 +621,12 @@ waitForData( os_duration *delay) { v_result result = V_RESULT_OK; - /* If no data read then wait for data or timeout. - */ + /* If no data read then wait for data or timeout. */ if (*delay > 0) { c_ulong flags = 0; os_timeE time = os_timeEGet(); - v__observerSetEvent(v_observer(_this), V_EVENT_DATA_AVAILABLE); - flags = v__observerTimedWait(v_observer(_this), *delay); + v_observerSetEvent(v_observer(_this), V_EVENT_DATA_AVAILABLE); + flags = OSPL_CATCH_EVENT(_this, *delay); if (flags & V_EVENT_TIMEOUT) { result = V_RESULT_TIMEOUT; } else { @@ -656,7 +657,7 @@ v_dataViewQueryRead ( assert(v_objectKind(src) == K_DATAVIEW); if (v_objectKind(src) == K_DATAVIEW) { v = v_dataView(src); - v_dataViewLock(v); + OSPL_LOCK(v); argument.action = action; argument.arg = arg; argument.sampleMask = _this->sampleMask; @@ -702,10 +703,9 @@ v_dataViewQueryRead ( result = waitForData(_this, &timeout); } } - /* This triggers the action routine that the last sample is read. - */ + /* This triggers the action routine that the last sample is read. */ action(NULL,arg); - v_dataViewUnlock(v); + OSPL_UNLOCK(v); } else { result = V_RESULT_ILL_PARAM; proceed = FALSE; @@ -751,7 +751,7 @@ v_dataViewQueryReadInstance( if (v_objectKind(src) == K_DATAVIEW) { C_STRUCT(walkQueryArg) argument; v = v_dataView(src); - v_dataViewLock(v); + OSPL_LOCK(v); v_dataReaderUpdatePurgeLists(v_dataReader(v->reader)); argument.action = action; @@ -788,10 +788,9 @@ v_dataViewQueryReadInstance( result = waitForData(_this, &timeout); } } - /* This triggers the action routine that the last sample is read. - */ + /* This triggers the action routine that the last sample is read. */ action(NULL,arg); - v_dataViewUnlock(v); + OSPL_UNLOCK(v); } else { result = V_RESULT_ILL_PARAM; proceed = FALSE; @@ -855,7 +854,7 @@ v_dataViewQueryReadNextInstance( if (v_objectKind(src) == K_DATAVIEW) { C_STRUCT(walkQueryArg) argument; v = v_dataView(src); - v_dataViewLock(v); + OSPL_LOCK(v); v_dataReaderUpdatePurgeLists(v_dataReader(v->reader)); len = c_arraySize(_this->instanceQ); @@ -899,10 +898,9 @@ v_dataViewQueryReadNextInstance( result = waitForData(_this, &timeout); } } - /* This triggers the action routine that the last sample is read. - */ + /* This triggers the action routine that the last sample is read. */ action(NULL,arg); - v_dataViewUnlock(v); + OSPL_UNLOCK(v); } else { result = V_RESULT_ILL_PARAM; proceed = FALSE; @@ -972,7 +970,7 @@ v_dataViewQueryTake( if (v_objectKind(src) == K_DATAVIEW) { v = v_dataView(src); - v_dataViewLock(v); + OSPL_LOCK(v); v_dataReaderUpdatePurgeLists(v_dataReader(v->reader)); argument.dataView = v; @@ -1031,10 +1029,9 @@ v_dataViewQueryTake( result = waitForData(_this, &timeout); } } - /* This triggers the action routine that the last sample is read. - */ + /* This triggers the action routine that the last sample is read. */ action(NULL,arg); - v_dataViewUnlock(v); + OSPL_UNLOCK(v); } else { result = V_RESULT_ILL_PARAM; proceed = FALSE; @@ -1088,7 +1085,7 @@ v_dataViewQueryTakeInstance( if (v_objectKind(src) == K_DATAVIEW) { C_STRUCT(walkQueryArg) argument; v = v_dataView(src); - v_dataViewLock(v); + OSPL_LOCK(v); v_dataReaderUpdatePurgeLists(v_dataReader(v->reader)); argument.dataView = v; @@ -1136,7 +1133,7 @@ v_dataViewQueryTakeInstance( * triggers the action routine that the last sample is read. */ action(NULL,arg); - v_dataViewUnlock(v); + OSPL_UNLOCK(v); } else { result = V_RESULT_ILL_PARAM; proceed = FALSE; @@ -1186,7 +1183,7 @@ v_dataViewQueryTakeNextInstance( if (v_objectKind(src) == K_DATAVIEW) { C_STRUCT(walkQueryArg) argument; v = v_dataView(src); - v_dataViewLock(v); + OSPL_LOCK(v); v_dataReaderUpdatePurgeLists(v_dataReader(v->reader)); len = c_arraySize(_this->instanceQ); @@ -1239,7 +1236,7 @@ v_dataViewQueryTakeNextInstance( * triggers the action routine that the last sample is read. */ action(NULL,arg); - v_dataViewUnlock(v); + OSPL_UNLOCK(v); } else { result = V_RESULT_ILL_PARAM; proceed = FALSE; @@ -1273,7 +1270,7 @@ v_dataViewQueryNotifyDataAvailable( assert(e); assert(C_TYPECHECK(e->data,v_dataViewSample)); - v_observerLock(v_observer(_this)); + OSPL_LOCK(_this); if (e->data) { if (_this->triggerValue == NULL) { @@ -1282,7 +1279,7 @@ v_dataViewQueryNotifyDataAvailable( _this->walkRequired = TRUE; } _this->state |= V_STATE_DATA_AVAILABLE; - v_observableNotify(v_observable(_this),e); + OSPL_THROW_EVENT(_this, e); /* Notify for internal use only, result can be ignored */ (void)v_entityNotifyListener(v_entity(_this), e); } else { @@ -1291,7 +1288,7 @@ v_dataViewQueryNotifyDataAvailable( "No triggerValue provided"); assert(FALSE); } - v_observerUnlock(v_observer(_this)); + OSPL_UNLOCK(_this); return TRUE; } @@ -1334,7 +1331,7 @@ v_dataViewQuerySetParams( kernel = v_objectKernel(_this); v = v_dataView(src); - v_dataViewLock(v); + OSPL_LOCK(v); len = c_arraySize(_this->instanceQ); for (i=0; (isampleQ[i],values); } if (result) { - v_dataViewUnlock(v); + OSPL_UNLOCK(v); } else { predicate = v_queryGetPredicate(v_query(_this)); q_prefixFieldNames(&predicate,"sample.sample.message.userData"); @@ -1355,7 +1352,7 @@ v_dataViewQuerySetParams( e = q_takePar(predicate,0); subtype = c_subType(v->instances); if (!resolveFields(subtype,e)) { - v_dataViewUnlock(v); + OSPL_UNLOCK(v); q_dispose(e); q_dispose(predicate); c_free(subtype); @@ -1368,7 +1365,7 @@ v_dataViewQuerySetParams( q_disjunctify(e); e = q_removeNots(e); - list = deOr(e,NULL); + list = q_exprDeOr(e,NULL); len = c_iterLength(list); type = c_resolve(c_getBase(c_object(kernel)),"c_query"); @@ -1428,7 +1425,7 @@ v_dataViewQuerySetParams( } } c_iterFree(list); - v_dataViewUnlock(v); + OSPL_UNLOCK(v); #if PRINT_QUERY printf("End v_dataViewQuerySetParams\n\n"); #endif diff --git a/src/kernel/code/v_dataViewSample.c b/src/kernel/code/v_dataViewSample.c index 127e57898..2657ce643 100644 --- a/src/kernel/code/v_dataViewSample.c +++ b/src/kernel/code/v_dataViewSample.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,8 +20,8 @@ */ -#include "v_dataViewSample.h" -#include "v_dataViewInstance.h" +#include "v__dataViewSample.h" +#include "v__dataViewInstance.h" #include "v__orderedInstance.h" #include "v_dataView.h" #include "v__reader.h" @@ -42,20 +43,18 @@ void checkInstance(v_dataViewInstance instance, c_bool isNotEmpty); v_dataViewSample v_dataViewSampleNew( - v_dataViewInstance instance, + v_dataView dataView, v_readerSample masterSample) { - v_dataView dataView; v_dataViewSample sample; - assert(instance != NULL); + assert(dataView != NULL); assert(masterSample != NULL); assert(C_TYPECHECK(masterSample,v_readerSample)); - dataView = v_dataView(v_instanceEntity(instance)); sample = v_dataViewSample(c_new(dataView->sampleType)); if (sample) { - v_readerSample(sample)->instance = (c_voidp)instance; + v_readerSample(sample)->instance = NULL; v_readerSample(sample)->sampleState = L_VALIDDATA; v_dataViewSampleList(sample)->next = NULL; v_dataViewSampleList(sample)->prev = NULL; @@ -70,21 +69,6 @@ v_dataViewSampleNew( return sample; } - -void -v_dataViewSampleFree( - v_dataViewSample sample) -{ - OS_UNUSED_ARG(sample); - assert(sample != NULL); - assert(C_TYPECHECK(sample, v_dataViewSample)); - - PRINT_REFCOUNT(v_dataViewSampleFree, sample); - /* Free the slave-samples as well */ - - PRINT_REFCOUNT(v_dataViewSampleFree, sample); -} - void v_dataViewSampleRemove( v_dataViewSample sample) @@ -110,7 +94,8 @@ v_dataViewSampleRemove( if (v_objectKind (instance) == K_ORDEREDINSTANCE) { /* Set v_orderedInstance bookmark to NULL by default if "no" - examples exist. */ + * examples exist. + */ v_orderedInstance(instance)->bookmark = NULL; v_dataViewInstanceTemplate(instance)->sample = NULL; c_free(sample); @@ -129,7 +114,8 @@ v_dataViewSampleRemove( /* Upon removing the head of the list the previous pointer of the * next sample should never be set, because that would set the * previous pointer of the tail sample and thus cause undefined - * behavior. */ + * behavior. + */ v_dataViewInstanceTemplate(instance)->sample = sample->prev; } else { v_dataViewSample(sample->next)->prev = sample->prev; @@ -142,7 +128,8 @@ v_dataViewSampleRemove( v_orderedInstance (instance)->bookmark == sample) { /* Bookmark should not need to be updated on a take operation, it - might need to be updated when samples are purged for example. */ + * might need to be updated when samples are purged for example. + */ v_orderedInstance (instance)->bookmark = sample->prev; } diff --git a/src/kernel/code/v_dbmsconnect.c b/src/kernel/code/v_dbmsconnect.c new file mode 100644 index 000000000..d84754cba --- /dev/null +++ b/src/kernel/code/v_dbmsconnect.c @@ -0,0 +1,72 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#include "v_dbmsconnect.h" +#include "v_kernel.h" +#include "v_service.h" +#include "v__observable.h" +#include "os_report.h" + +v_dbmsconnect +v_dbmsconnectNew( + v_kernel kernel, + const c_char *name, + const c_char *extStateName, + v_participantQos qos, + c_bool enable) +{ + v_dbmsconnect dbmsconnect = NULL; + v_participantQos q; + + assert(C_TYPECHECK(kernel, v_kernel)); + assert(name != NULL); + + q = v_participantQosNew(kernel, (v_participantQos)qos); + if (q == NULL) { + OS_REPORT(OS_ERROR, OS_FUNCTION, V_RESULT_INTERNAL_ERROR, + "DBMSconnect service not created: inconsistent qos"); + } else { + dbmsconnect = v_dbmsconnect(v_objectNew(kernel, K_DBMSCONNECT)); + if (dbmsconnect) { + v_serviceInit(v_service(dbmsconnect), name, extStateName, V_SERVICETYPE_DBMSCONNECT, q, enable); + + if (v_service(dbmsconnect)->state == NULL) { + v_serviceFree(v_service(dbmsconnect)); + dbmsconnect = NULL; + } else { + OSPL_ADD_OBSERVER(kernel, dbmsconnect, V_EVENT_NEW_GROUP, NULL); + } + } else { + OS_REPORT(OS_ERROR, OS_FUNCTION, V_RESULT_OUT_OF_MEMORY, + "DBMSconnect service not created: out of memory"); + } + c_free(q); + } + + return dbmsconnect; +} + +void +v_dbmsconnectFree( + v_dbmsconnect _this) +{ + assert(C_TYPECHECK(_this, v_dbmsconnect)); + v_serviceFree(v_service(_this)); +} diff --git a/src/kernel/code/v_deadLineInstanceList.c b/src/kernel/code/v_deadLineInstanceList.c index 8e7f1448a..f8923efe4 100644 --- a/src/kernel/code/v_deadLineInstanceList.c +++ b/src/kernel/code/v_deadLineInstanceList.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -61,7 +62,7 @@ v_deadLineInstanceListNew( list->leaseManager = c_keep(leaseManager); list->leaseDuration = leaseDuration; list->deadlineLease = NULL; - list->actionObject = o; /* no keep, since actionObject is onwer of v_deadLineInstanceList */ + list->actionObject = o; /* no keep, since actionObject is owner of v_deadLineInstanceList */ list->actionId = actionId; list->head = NULL; list->tail = NULL; @@ -83,16 +84,14 @@ v_deadLineInstanceListFree( assert(C_TYPECHECK(list,v_deadLineInstanceList)); _CHECK_LIST_(list); - /* Stop lease manager activity. - */ + /* Stop lease manager activity. */ v_leaseManagerDeregister(list->leaseManager, list->deadlineLease); c_free(list->leaseManager); list->leaseManager = NULL; c_free(list->deadlineLease); list->deadlineLease = NULL; - /* Free contained deadLine Instances. - */ + /* Free contained deadLine Instances. */ while (list->head != NULL) { assert(list->tail != NULL); v_deadLineInstanceListRemoveInstance(list, list->head); @@ -165,9 +164,7 @@ v_deadLineInstanceListInsertInstance( _CHECK_HEAD_(list, instance); _CHECK_TAIL_(list, instance); - /* As the instance is put at the end of the list no need to update the - lease! - */ + /* As the instance is put at the end of the list no need to update the lease! */ if (list->head == NULL) { assert(list->tail == NULL); list->head = instance; @@ -227,8 +224,7 @@ v_deadLineInstanceListRemoveInstance( * the next deadline check, which is more efficient as the administration * might already have changed many times. */ - /* Update next pointer list. - */ + /* Update next pointer list. */ if (list->head == instance) { assert(instance->prev == NULL); list->head = instance->next; @@ -240,8 +236,7 @@ v_deadLineInstanceListRemoveInstance( v_deadLineInstance(instance->prev)->next = instance->next; } - /* Update prev pointer list. - */ + /* Update prev pointer list. */ if (list->tail == instance) { assert(instance->next == NULL); list->tail = instance->prev; @@ -256,8 +251,7 @@ v_deadLineInstanceListRemoveInstance( instance->next = instance; instance->prev = instance; - /* Update Lease manager registration. - */ + /* Update Lease manager registration. */ if (list->head == NULL) { assert(list->tail == NULL); if (list->deadlineLease != NULL) { @@ -288,17 +282,16 @@ v_deadLineInstanceListUpdate( assert(c_refCount(instance) > 0); /* This will also place the current instance at the end of the list. - Again no need to update the lease, we can determine the next wake-up - as soon as the next deadlinecheck is performed. - */ + * Again no need to update the lease, we can determine the next wake-up + * as soon as the next deadlinecheck is performed. + */ if (list->leaseDuration != OS_DURATION_INFINITE) { instance->lastDeadlineResetTime = timestamp; if (v_deadLineInstance_alone(instance)) { v_deadLineInstanceListInsertInstance(list, instance); } else { if (instance != list->tail) { - /* Remove from next pointer list. - */ + /* Remove from next pointer list. */ if (list->head == instance) { assert(instance->prev == NULL); list->head = instance->next; @@ -309,13 +302,11 @@ v_deadLineInstanceListUpdate( assert(instance->prev != NULL); v_deadLineInstance(instance->prev)->next = instance->next; } - /* Remove from prev pointer list. - */ + /* Remove from prev pointer list. */ assert(instance->next != NULL); v_deadLineInstance(instance->next)->prev = instance->prev; - /* Reset deadline list timestamp and reinsert instance at the tail of the list. - */ + /* Reset deadline list timestamp and reinsert instance at the tail of the list. */ assert(list->tail != NULL); assert(list->tail->next == NULL); list->tail->next = instance; @@ -345,8 +336,7 @@ v_deadLineInstanceListCheckDeadlineMissed( missed = NULL; if (list->head == NULL) { /* list is empty */ - /* - * expected was that the deadlineLease should be != NULL + /* Expected was that the deadlineLease should be != NULL * However when an entity is being deleted this lease will be deleted but the * leaseManager of the participant may already have received a deadline * missed notification and will call this operation and when the deletion has not diff --git a/src/kernel/code/v_deliveryGuard.c b/src/kernel/code/v_deliveryGuard.c index 7542f0f1b..167681a95 100644 --- a/src/kernel/code/v_deliveryGuard.c +++ b/src/kernel/code/v_deliveryGuard.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -43,7 +44,7 @@ v_deliveryGuardNew( C_STRUCT(v_deliveryGuard) template; c_type type; v_deliveryGuard _this; - v_result result; + v_result result = V_RESULT_UNDEFINED; assert(C_TYPECHECK(service,v_deliveryService)); assert(C_TYPECHECK(writer,v_writer)); @@ -58,30 +59,31 @@ v_deliveryGuardNew( c_free(type); if (_this) { - c_mutexInit(c_getBase(_this), &(_this->mutex)); - _this->writerGID = template.writerGID; - _this->owner = (c_voidp)service; /* backref used by the free */ - _this->gidType = c_resolve(c_getBase(_this),"kernelModule::v_gid"); - - type = c_resolve(c_getBase(_this),"kernelModuleI::v_deliveryWaitList"); - /* The sequence number is the key, as this is unique within each writer */ - _this->waitlists = c_tableNew(type,"sequenceNumber"); - c_free(type); - - /* The following subscription set attribute contains the - * subscriptions of nodes that have synchronous DataReaders - * that communicate with this particular DataWriter. - * This list will be maintained by the reception of builtin - * topics. The list does not need to be initialized with - * the correct data right now because the topic is transient - * so the whole state will be delivered and delivery will - * update the list. - */ - type = c_resolve(c_getBase(_this),"kernelModuleI::v_deliveryPublisher"); - _this->publications = c_tableNew(type,"readerGID.systemId,readerGID.localId,readerGID.serial"); - c_free(type); - - result = v_deliveryServiceAddGuard(service,_this); + if (c_mutexInit(c_getBase(_this), &(_this->mutex)) == SYNC_RESULT_SUCCESS) { + _this->writerGID = template.writerGID; + _this->owner = (c_voidp)service; /* backref used by the free */ + _this->gidType = c_resolve(c_getBase(_this),"kernelModule::v_gid"); + + type = c_resolve(c_getBase(_this),"kernelModuleI::v_deliveryWaitList"); + /* The sequence number is the key, as this is unique within each writer */ + _this->waitlists = c_tableNew(type,"sequenceNumber"); + c_free(type); + + /* The following subscription set attribute contains the + * subscriptions of nodes that have synchronous DataReaders + * that communicate with this particular DataWriter. + * This list will be maintained by the reception of builtin + * topics. The list does not need to be initialized with + * the correct data right now because the topic is transient + * so the whole state will be delivered and delivery will + * update the list. + */ + type = c_resolve(c_getBase(_this),"kernelModuleI::v_deliveryPublisher"); + _this->publications = c_tableNew(type,"readerGID.systemId,readerGID.localId,readerGID.serial"); + c_free(type); + + result = v_deliveryServiceAddGuard(service,_this); + } if (result != V_RESULT_OK) { c_free(_this); _this = NULL; diff --git a/src/kernel/code/v_deliveryService.c b/src/kernel/code/v_deliveryService.c index 33d161999..16f3eaa0a 100644 --- a/src/kernel/code/v_deliveryService.c +++ b/src/kernel/code/v_deliveryService.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,7 +25,8 @@ #include "v_entity.h" #include "v_public.h" #include "v_readerQos.h" -#include "v_observer.h" +#include "v__observer.h" +#include "v__observable.h" #include "v__deliveryService.h" #include "v__deliveryGuard.h" @@ -37,96 +39,18 @@ #include "os_report.h" #include "os_abstract.h" -static void -deliveryServiceSubscribe( - void *o, - void *arg) -{ - v_partition p = v_partition(o); - v_deliveryServiceEntry e = v_deliveryServiceEntry(arg); - v_kernel kernel; - v_group g; - - assert(C_TYPECHECK(e,v_deliveryServiceEntry)); - assert(C_TYPECHECK(p,v_partition)); - - kernel = v_objectKernel(e); - g = v_groupSetCreate(kernel->groupSet,p,e->topic); - - if(v_groupPartitionAccessMode(g) == V_ACCESS_MODE_READ_WRITE || - v_groupPartitionAccessMode(g) == V_ACCESS_MODE_READ) - { - v_groupAddEntry(g,v_entry(e)); - } - c_free(g); -} - -static c_bool -subscribe( - c_object entry, - c_voidp partition) -{ - v_partition p = v_partition(partition); - v_deliveryServiceEntry e = v_deliveryServiceEntry(entry); - - deliveryServiceSubscribe(p, e); - - return TRUE; -} - -static void -deliveryServiceUnSubscribe( - void *o, - void *arg) -{ - v_partition p = v_partition(o); - v_deliveryServiceEntry e = v_deliveryServiceEntry(arg); - v_kernel kernel; - v_group g; - c_value params[2]; - c_iter list; - - assert(C_TYPECHECK(e,v_deliveryServiceEntry)); - assert(C_TYPECHECK(p,v_partition)); - - params[0] = c_objectValue(p); - params[1] = c_objectValue(e->topic); - kernel = v_objectKernel(e); - list = v_groupSetSelect(kernel->groupSet, - "partition = %0 and topic = %1", - params); - while ((g = c_iterTakeFirst(list)) != NULL) { - v_groupRemoveEntry(g,v_entry(e)); - c_free(g); - } - c_iterFree(list); -} - -static c_bool -unsubscribe( - c_object entry, - c_voidp partition) -{ - v_partition p = v_partition(partition); - v_deliveryServiceEntry e = v_deliveryServiceEntry(entry); - - deliveryServiceUnSubscribe(p, e); - - return TRUE; -} - v_deliveryService v_deliveryServiceNew ( v_subscriber subscriber, const c_char *name) { v_kernel kernel; - v_deliveryService _this; + v_deliveryService _this = NULL; v_readerQos q; v_topic topic; c_base base; c_type type; - v_entry entry, found; + v_entry entry; assert(C_TYPECHECK(subscriber,v_subscriber)); base = c_getBase(subscriber); @@ -141,79 +65,94 @@ v_deliveryServiceNew ( OS_REPORT(OS_ERROR, "v_deliveryServiceNew",0, "DeliveryService not created: " "Could not locate topic with name DCPS_Delivery."); - return NULL; + goto err_precon; } - if(v_topicAccessMode(topic) == V_ACCESS_MODE_READ || - v_topicAccessMode(topic) == V_ACCESS_MODE_READ_WRITE) + if (!(v_topicAccessMode(topic) == V_ACCESS_MODE_READ || v_topicAccessMode(topic) == V_ACCESS_MODE_READ_WRITE)) { - q = v_readerQosNew(kernel, NULL); - if (q == NULL) { - OS_REPORT(OS_ERROR, "v_deliveryServiceNew", V_RESULT_INTERNAL_ERROR, - "Creation of DeliveryService <%s> failed: Cannot create reader QoS.", - name); - return NULL; - } - _this = v_deliveryService(v_objectNew(kernel,K_DELIVERYSERVICE)); - - type = c_resolve(base, "kernelModuleI::v_deliveryGuard"); - _this->guards = c_tableNew(type, "writerGID.localId"); - c_free(type); - - type = c_resolve(base, "kernelModuleI::v_subscriptionInfoTemplate"); - _this->subscriptions = c_tableNew(type, "userData.key.systemId,userData.key.localId"); - c_free(type); + OS_REPORT(OS_ERROR, "v_deliveryServiceNew", V_RESULT_ILL_PARAM, + "Creation of DeliveryService <%s> failed. Topic DCPS_Delivery." + "does not have read access rights.", name); + goto err_topic; + } + q = v_readerQosNew(kernel, NULL); + if (q == NULL) { + OS_REPORT(OS_ERROR, "v_deliveryServiceNew", V_RESULT_INTERNAL_ERROR, + "Creation of DeliveryService <%s> failed: Cannot create reader QoS.", + name); + goto err_topic; + } - c_mutexInit(c_getBase(_this), &_this->mutex); + _this = v_deliveryService(v_objectNew(kernel,K_DELIVERYSERVICE)); + if (_this == NULL) { + c_free(q); + goto err_topic; + } + q->userKey.v.enable = TRUE; + q->userKey.v.expression = NULL; + v_readerInit(v_reader(_this), name, subscriber, q); + c_free(q); + + type = c_resolve(base, "kernelModuleI::v_deliveryGuard"); + _this->guards = c_tableNew(type, "writerGID.localId"); + c_free(type); + if (_this->guards == NULL) { + OS_REPORT(OS_ERROR, "v_deliveryServiceNew", V_RESULT_INTERNAL_ERROR, + "Creation of DeliveryService <%s> failed: create delivery guard table failed.", + name); + goto err_init; + } - q->userKey.v.enable = TRUE; - q->userKey.v.expression = NULL; - v_readerInit(v_reader(_this), name, subscriber, q, TRUE); - v_entityEnable(v_entity(_this)); + type = c_resolve(base, "kernelModuleI::v_subscriptionInfoTemplate"); + _this->subscriptions = c_tableNew(type, "userData.key.systemId,userData.key.localId"); + c_free(type); + if (_this->subscriptions == NULL) { + OS_REPORT(OS_ERROR, "v_deliveryServiceNew", V_RESULT_INTERNAL_ERROR, + "Creation of DeliveryService <%s> failed: create delivery subscription table failed.", + name); + goto err_init; + } - c_free(q); + entry = v_entry(v_deliveryServiceEntryNew(_this,topic)); + v_readerAddEntry(v_reader(_this),v_entry(entry)); + c_free(entry); - entry = v_entry(v_deliveryServiceEntryNew(_this,topic)); - found = v_readerAddEntry(v_reader(_this),v_entry(entry)); - c_free(entry); - c_free(found); + (void)v_entityEnable(v_entity(_this)); - v_deliveryServiceEnable(_this); - } else - { - OS_REPORT(OS_ERROR, "v_deliveryServiceNew", V_RESULT_ILL_PARAM, - "Creation of DeliveryService <%s> failed. Topic DCPS_Delivery." - "does not have read access rights.", name); - _this = NULL; - } return _this; + +err_init: + c_free(_this); +err_topic: + c_free(topic); +err_precon: + return NULL; } v_result -v_deliveryServiceEnable( - v_deliveryService _this) +v__deliveryServiceEnable( + _Inout_ v_deliveryService _this) { v_kernel kernel; v_message builtinMsg, builtinCMMsg; v_subscriber subscriber; v_result result; - if (_this) { - result = V_RESULT_OK; - subscriber = v_subscriber(v_reader(_this)->subscriber); - - result = v_subscriberAddReader(subscriber,v_reader(_this)); - if (result == V_RESULT_OK) { - kernel = v_objectKernel(_this); - builtinMsg = v_builtinCreateSubscriptionInfo(kernel->builtin, v_reader(_this)); - builtinCMMsg = v_builtinCreateCMDataReaderInfo(kernel->builtin, v_reader(_this)); - v_writeBuiltinTopic(kernel, V_SUBSCRIPTIONINFO_ID, builtinMsg); - v_writeBuiltinTopic(kernel, V_CMDATAREADERINFO_ID, builtinCMMsg); - c_free(builtinMsg); - c_free(builtinCMMsg); - } - } else { - result = V_RESULT_ILL_PARAM; + subscriber = v_subscriber(v_reader(_this)->subscriber); + + result = v_subscriberAddReader(subscriber,v_reader(_this)); + if (result == V_RESULT_OK) { + result = v_subscriberEnableReader (subscriber, v_reader (_this)); + } + if (result == V_RESULT_OK) { + kernel = v_objectKernel(_this); + builtinMsg = v_builtinCreateSubscriptionInfo(kernel->builtin, v_reader(_this)); + builtinCMMsg = v_builtinCreateCMDataReaderInfo(kernel->builtin, v_reader(_this)); + v_writeBuiltinTopic(kernel, V_SUBSCRIPTIONINFO_ID, builtinMsg); + v_writeBuiltinTopic(kernel, V_CMDATAREADERINFO_ID, builtinCMMsg); + c_free(builtinMsg); + c_free(builtinCMMsg); } + return result; } @@ -258,31 +197,8 @@ v_deliveryServiceDeinit ( v_readerDeinit(v_reader(_this)); } -c_bool -v_deliveryServiceSubscribe( - v_deliveryService _this, - v_partition d) -{ - assert(C_TYPECHECK(_this,v_deliveryService)); - - v_readerWalkEntries(v_reader(_this), subscribe, d); - - return TRUE; -} - -c_bool -v_deliveryServiceUnSubscribe( - v_deliveryService _this, - v_partition d) -{ - assert(C_TYPECHECK(_this,v_deliveryService)); - - return v_readerWalkEntries(v_reader(_this), unsubscribe, d); -} - C_STRUCT(MatchingGuardsArg) { v_topic topic; - v_writer writer; v_deliveryGuard guard; c_iter groupList; v_gid readerGID; @@ -312,19 +228,19 @@ updateMatchingGuards( { C_STRUCT(MatchingGuardsArg) *a = (C_STRUCT(MatchingGuardsArg) *)arg; c_bool result = TRUE; + v_writer writer; - /* select writers having equal topic and compatible qos policy. - */ + /* select writers having equal topic and compatible qos policy. */ a->guard = v_deliveryGuard(o); - a->writer = v_writer(v_gidClaim(a->guard->writerGID, a->kernel)); - if (a->writer) { - if (a->writer->topic == a->topic) { + writer = v_writer(v_gidClaim(a->guard->writerGID, a->kernel)); + if (writer) { + if (writer->topic == a->topic) { /* if this writer has groups matching the reader groups * then update the guards publication list. */ c_type type; v_deliveryPublisher publication, found; - v_observerLock(v_observer(a->writer)); + OSPL_LOCK(writer); c_mutexLock(&a->guard->mutex); type = c_subType(a->guard->publications); @@ -337,7 +253,7 @@ updateMatchingGuards( found = c_replace(a->guard->publications, publication, NULL, NULL); c_free(found); a->publication = publication; - v_writerGroupWalkUnlocked(a->writer, updatePublication, arg); + v_writerGroupWalkUnlocked(writer, updatePublication, arg); } else { found = c_find(a->guard->publications, publication); c_free(publication); @@ -366,15 +282,14 @@ updateMatchingGuards( } c_mutexUnlock(&a->guard->mutex); - v_observerUnlock(v_observer(a->writer)); + OSPL_UNLOCK(writer); } v_gidRelease(a->guard->writerGID, a->kernel); } return result; } -/* - * This method updates the v_deliveryGuard->publications list with all synchronous +/* This method updates the v_deliveryGuard->publications list with all synchronous * writers the v_deliveryService is aware of, preconditions for to be added to the list are: * a) guard->writer->topic matches the sInfo->topic * b) guard->writer->partitions match the sInfo->partitions @@ -468,8 +383,7 @@ collectGuardsAction( c_object o, c_voidp arg) { - /* select writers having equal topic and compatible qos policy. - */ + /* select writers having equal topic and compatible qos policy. */ c_iterAppend((c_iter)arg, c_keep(o)); return TRUE; @@ -484,9 +398,9 @@ doGuardsAction( c_object guard; c_iter guards = c_iterNew(NULL); - c_mutexLock(&(_this->mutex)); + OSPL_LOCK(_this); (void)c_walk(_this->guards, collectGuardsAction, guards); - c_mutexUnlock(&(_this->mutex)); + OSPL_UNLOCK(_this); guard = c_iterTakeFirst(guards); @@ -524,9 +438,9 @@ v_deliveryServiceRegister( return; } - c_mutexLock(&_this->mutex); + OSPL_LOCK(_this); found = c_replace(_this->subscriptions, msg, NULL, NULL); - c_mutexUnlock(&(_this->mutex)); + OSPL_UNLOCK(_this); c_free(found); rInfo = (v_subscriptionInfoTemplate)msg; @@ -573,7 +487,6 @@ v_deliveryServiceRegister( if (arg.groupList) { arg.readerGID = rInfo->userData.key; arg.topic = topic; - arg.writer = NULL; arg.alive = TRUE; /* Need to ensure not to update the matching guards while @@ -623,9 +536,9 @@ v_deliveryServiceUnregister( return; } - c_mutexLock(&_this->mutex); + OSPL_LOCK(_this); found = c_remove(_this->subscriptions, msg, NULL, NULL); - c_mutexUnlock(&(_this->mutex)); + OSPL_UNLOCK(_this); if (found) { rInfo = (v_subscriptionInfoTemplate)found; @@ -667,7 +580,6 @@ v_deliveryServiceUnregister( if (arg.groupList) { arg.readerGID = rInfo->userData.key; arg.topic = topic; - arg.writer = NULL; arg.alive = FALSE; /* Need to ensure not to update the matching guards while @@ -768,7 +680,7 @@ v_deliveryServiceRemoveGuard( assert(guard); assert(C_TYPECHECK(guard,v_deliveryGuard)); - c_mutexLock(&(_this->mutex)); + OSPL_LOCK(_this); found = c_remove(_this->guards,guard,NULL,NULL); if (found != guard) { /* This should not happen! */ @@ -780,7 +692,7 @@ v_deliveryServiceRemoveGuard( } else { result = V_RESULT_OK; } - c_mutexUnlock(&(_this->mutex)); + OSPL_UNLOCK(_this); return result; } @@ -796,7 +708,7 @@ v_deliveryServiceAddGuard( assert(guard); assert(C_TYPECHECK(guard,v_deliveryGuard)); - c_mutexLock(&_this->mutex); + OSPL_LOCK(_this); found = c_tableInsert(_this->guards, guard); assert(found == guard); @@ -805,7 +717,7 @@ v_deliveryServiceAddGuard( /* Now update publication list from delivery service subscriptions. */ c_walk(_this->subscriptions, getMatchingPublications, guard); - c_mutexUnlock(&(_this->mutex)); + OSPL_UNLOCK(_this); return V_RESULT_OK; } @@ -820,9 +732,7 @@ v_deliveryServiceLookupGuard( assert(_this); assert(C_TYPECHECK(_this,v_deliveryService)); - c_mutexLock(&_this->mutex); found = c_find(_this->guards, template); - c_mutexUnlock(&(_this->mutex)); return found; } diff --git a/src/kernel/code/v_deliveryServiceEntry.c b/src/kernel/code/v_deliveryServiceEntry.c index 45fe90fae..31c857205 100644 --- a/src/kernel/code/v_deliveryServiceEntry.c +++ b/src/kernel/code/v_deliveryServiceEntry.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,19 +21,14 @@ #include "v_deliveryServiceEntry.h" #include "v_kernel.h" #include "v_reader.h" -#include "v_observer.h" +#include "v__observer.h" +#include "v__observable.h" #include "v_messageQos.h" #include "v__deliveryService.h" #include "v__entry.h" #include "os_report.h" -/************************************************************** - * Private functions - **************************************************************/ -/************************************************************** - * constructor/destructor - **************************************************************/ v_deliveryServiceEntry v_deliveryServiceEntryNew( v_deliveryService deliveryService, @@ -68,28 +64,19 @@ v_deliveryServiceEntryWrite( /* Only write if the message is not produced by an incompatible writer. */ reader = v_entryReader(_this); - v_observerLock(v_observer(reader)); + OSPL_LOCK(reader); /* Filter-out all QoS-incompatible messages. */ if (!v_messageQos_isReaderCompatible(message->qos,reader)) { - v_observerUnlock(v_observer(reader)); + OSPL_UNLOCK(reader); return V_WRITE_SUCCESS; } - /* If Alive then claim instance and trigger with sample event. - */ + /* If Alive then claim instance and trigger with sample event. */ ackMsg = (v_deliveryInfoTemplate)message; result = v_deliveryServiceWrite(v_deliveryService(reader),ackMsg); - v_observerUnlock(v_observer(reader)); + OSPL_UNLOCK(reader); return result; } - -/************************************************************** - * Protected functions - **************************************************************/ - -/************************************************************** - * Public functions - **************************************************************/ diff --git a/src/kernel/code/v_deliveryServiceEntry.h b/src/kernel/code/v_deliveryServiceEntry.h index 3c5ffe9e7..151907c61 100644 --- a/src/kernel/code/v_deliveryServiceEntry.h +++ b/src/kernel/code/v_deliveryServiceEntry.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -52,17 +53,17 @@ v_deliveryServiceEntry v_deliveryServiceEntryNew( v_deliveryService deliveryService, v_topic topic); - -void + +void v_deliveryServiceEntryFree( v_deliveryServiceEntry _this); - -v_writeResult + +v_writeResult v_deliveryServiceEntryWrite( - v_deliveryServiceEntry _this, - v_message o, + v_deliveryServiceEntry _this, + v_message o, v_instance *instance); - + #if defined (__cplusplus) } #endif diff --git a/src/kernel/code/v_deliveryWaitList.c b/src/kernel/code/v_deliveryWaitList.c index 00d6907e9..5d6c31b99 100644 --- a/src/kernel/code/v_deliveryWaitList.c +++ b/src/kernel/code/v_deliveryWaitList.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -41,7 +42,8 @@ v_deliveryWaitListWait ( /* TODO: Due to spurious wake-ups and the use of a *relative* timeout, * the provided timeout can be exceeded. When the hibernation work is * available, this should be eliminated by keeping track of the - * monotonic clock or absolute sleeps should be supported instead. */ + * monotonic clock or absolute sleeps should be supported instead. + */ result = v_condWait(&_this->cv, &_this->mutex, timeout); } c_mutexUnlock(&_this->mutex); @@ -73,7 +75,8 @@ v_deliveryWaitListNotify ( if (v_gidEqual(list[i], msg->userData.readerGID)) { /* Set the found readerGID to zero, the waitlist can be * unblocked when all expected systemIds are zero. In that case - * _this->waitCount will be 0. */ + * _this->waitCount will be 0. + */ v_gidSetNil(list[i]); _this->waitCount--; break; @@ -114,7 +117,8 @@ v_deliveryWaitListIgnore ( if (v_gidEqual(list[i], readerGID)) { /* Set the found readerGID to zero, the waitlist can be * unblocked when all expected systemIds are zero. In that case - * _this->waitCount will be 0. */ + * _this->waitCount will be 0. + */ v_gidSetNil(list[i]); _this->waitCount--; break; @@ -185,26 +189,33 @@ v_deliveryWaitListNew( assert(_this); assert(C_TYPECHECK(_this,v_deliveryGuard)); - /* lookup or create a writer specific admin. - */ + /* lookup or create a writer specific admin. */ type = c_subType(_this->waitlists); waitlist = c_new_s(type); c_free(type); if (waitlist) { - c_mutexInit(c_getBase(waitlist), &waitlist->mutex); - c_condInit(c_getBase(waitlist), &waitlist->cv, &waitlist->mutex); - waitlist->sequenceNumber = msg->sequenceNumber; - waitlist->guard = _this; - - /* When modifying the contents of the WaitList collection in the deliveryGuard, - * we must first acquire its lock. */ - c_mutexLock(&_this->mutex); - waitlist->readerGID = copyReaderGIDsFromPublications(_this); - waitlist->waitCount = c_arraySize(waitlist->readerGID); - found = c_tableInsert(_this->waitlists, waitlist); - assert(found == waitlist); - (void)found; - c_mutexUnlock(&_this->mutex); + if (c_mutexInit(c_getBase(waitlist), &waitlist->mutex) == SYNC_RESULT_SUCCESS) { + c_condInit(c_getBase(waitlist), &waitlist->cv, &waitlist->mutex); + waitlist->sequenceNumber = msg->sequenceNumber; + waitlist->guard = _this; + + /* When modifying the contents of the WaitList collection in the deliveryGuard, + * we must first acquire its lock. + */ + c_mutexLock(&_this->mutex); + waitlist->readerGID = copyReaderGIDsFromPublications(_this); + waitlist->waitCount = c_arraySize(waitlist->readerGID); + found = c_tableInsert(_this->waitlists, waitlist); + assert(found == waitlist); + (void)found; + c_mutexUnlock(&_this->mutex); + } else { + c_free(waitlist); + waitlist = NULL; + OS_REPORT(OS_FATAL, + "v_deliveryWaitListNew",V_RESULT_INTERNAL_ERROR, + "Failed to initialize mutex for waitlist."); + } } else { OS_REPORT(OS_FATAL, "v_deliveryWaitListNew",V_RESULT_INTERNAL_ERROR, @@ -224,11 +235,11 @@ v_deliveryWaitListFree( assert(C_TYPECHECK(_this,v_deliveryWaitList)); - /* lookup or create a writer specific admin. - */ + /* lookup or create a writer specific admin. */ if (_this) { /* When modifying the contents of the WaitList collection in the deliveryGuard, - * we must first acquire the lock of its guard. */ + * we must first acquire the lock of its guard. + */ guard = v_deliveryGuard(_this->guard); c_mutexLock(&guard->mutex); found = c_remove(guard->waitlists, _this, NULL, NULL); diff --git a/src/kernel/code/v_durability.c b/src/kernel/code/v_durability.c index 3a1b1dc23..7831cad88 100644 --- a/src/kernel/code/v_durability.c +++ b/src/kernel/code/v_durability.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,7 +22,7 @@ #include "v__statCat.h" #include "v_durabilityStatistics.h" #include "v_service.h" -#include "v__groupInstance.h" +#include "v__observable.h" #include "v_group.h" #include "v__kernel.h" #include "v_participant.h" @@ -59,6 +60,8 @@ v_durabilityNew( if (v_service(s)->state == NULL) { v_serviceFree(v_service(s)); s = NULL; + } else { + OSPL_ADD_OBSERVER(kernel, s, V_EVENT_PERSISTENT_SNAPSHOT | V_EVENT_NEW_GROUP | V_EVENT_CONNECT_WRITER, NULL); } } return s; diff --git a/src/kernel/code/v_durabilityClient.c b/src/kernel/code/v_durabilityClient.c index 030d96831..07e2e8b1e 100644 --- a/src/kernel/code/v_durabilityClient.c +++ b/src/kernel/code/v_durabilityClient.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,6 +20,7 @@ */ #include "v_durabilityClient.h" +#include "v__kernel.h" #include "v__topic.h" #include "v__topicImpl.h" #include "v__writer.h" @@ -26,14 +28,17 @@ #include "v__subscriber.h" #include "v__reader.h" #include "v__policy.h" +#include "v__entry.h" #include "v__group.h" +#include "v_groupInstance.h" #include "v_public.h" #include "v_topicQos.h" #include "v_writerQos.h" #include "v_publisherQos.h" #include "v_dataReaderInstance.h" -#include "v_observable.h" -#include "v_observer.h" +#include "v_configuration.h" +#include "v__observer.h" +#include "v__observable.h" #include "v_builtin.h" #include "v_waitset.h" #include "v_handle.h" @@ -102,6 +107,28 @@ #define COMPLETENESS_INCOMPLETE 1 #define COMPLETENESS_COMPLETE 2 +#define V_DC_RETCODE_NO_ERROR 0x0 +/* Syntax errors -- 1 - 8388607 (= 1 .. 2^23-1) */ +#define V_DC_RETCODE_INCOMPATIBLE_VERSION 0x1 +#define V_DC_RETCODE_NO_TOPIC 0x2 +#define V_DC_RETCODE_INVALID_START_TIME 0x3 +#define V_DC_RETCODE_INVALID_END_TIME 0x4 +#define V_DC_RETCODE_INVALID_TIME_RANGE 0x5 +#define V_DC_RETCODE_INVALID_SERIAZATION 0x6 +#define V_DC_RETCODE_NO_PARTITIONS 0x7 +#define V_DC_RETCODE_INVALID_MAX_SAMPLES 0x8 +#define V_DC_RETCODE_INVALID_MAX_INSTANCES 0x9 +#define V_DC_RETCODE_INVALID_MAX_SAMPLES_PER_INSTANCE 0xA +/* Syntax OK, but server is not able process -- 8388608 - (= 2^23 - 2^24-1) - */ +#define V_DC_RETCODE_SERVER_IS_NOT_ALIGNER 0x80000000 +#define V_DC_RETCODE_SERVER_IS_NOT_RESPONSIBLE 0x80000001 +#define V_DC_RETCODE_READER_NOT_KNOWN 0x80000002 +#define V_DC_RETCODE_NO_MASTER_SELECTED 0x80000003 +#define V_DC_RETCODE_GROUP_NOT_FOUND 0x80000004 +#define V_DC_RETCODE_INVALID 0xFFFFFFFF + + + #define V_DC_ALL_READERS_AVAILABLE(flags) \ ((flags & (V_DC_STATE_REQUEST_FLAG|V_DC_DATA_REQUEST_FLAG)) == \ (V_DC_STATE_REQUEST_FLAG|V_DC_DATA_REQUEST_FLAG) ) @@ -127,20 +154,27 @@ #define v__dcSampleGetSystemId(s) (v__dcMessageGetSystemId (v_dataReaderSampleTemplate(s)->message)) -const char *builtin_topics[] = { - V_TOPICINFO_NAME, - V_PARTICIPANTINFO_NAME, - V_PUBLICATIONINFO_NAME, - V_SUBSCRIPTIONINFO_NAME, - V_CMPARTICIPANTINFO_NAME, - V_CMDATAWRITERINFO_NAME, - V_CMDATAREADERINFO_NAME, - V_CMPUBLISHERINFO_NAME, - V_CMSUBSCRIBERINFO_NAME, - V_HEARTBEATINFO_NAME, - V_DELIVERYINFO_NAME, - NULL /* Must be the last element, used as delimiter */ + +struct v__builtinTopicInfo { + const char *topicName; + c_bool align; /* align when builtin topics enabled */ + c_bool always; /* align always */ +}; + +static const struct v__builtinTopicInfo builtin_topics[] = { + { V_TOPICINFO_NAME, TRUE, TRUE }, + { V_PARTICIPANTINFO_NAME, TRUE, FALSE }, + { V_PUBLICATIONINFO_NAME, TRUE, TRUE }, + { V_SUBSCRIPTIONINFO_NAME, TRUE, FALSE }, + { V_CMPARTICIPANTINFO_NAME, TRUE, FALSE }, + { V_CMDATAWRITERINFO_NAME, TRUE, FALSE }, + { V_CMDATAREADERINFO_NAME, TRUE, FALSE }, + { V_CMPUBLISHERINFO_NAME, TRUE, FALSE }, + { V_CMSUBSCRIBERINFO_NAME, TRUE, FALSE }, + { V_HEARTBEATINFO_NAME, FALSE, FALSE }, + { V_DELIVERYINFO_NAME, FALSE, FALSE } }; +static const c_ulong num_builtin_topics = sizeof(builtin_topics)/sizeof(struct v__builtinTopicInfo); typedef void (*v__dcDataAction)(v_durabilityClient _this, v_dataReaderSample sample); @@ -287,6 +321,7 @@ static void cleanup_server(void *n); static void cleanup_group(void *n); static void v_dcUpdateDurabilityState(v_durabilityClient _this, struct _DDS_RequestId_t *requestId, v_message msg, struct _DDS_DurabilityState *data, struct server_node *n); void v_durabilityClientFree (v_durabilityClient _this); +static void v__dcRequestHistoricalBuiltinData (v_durabilityClient _this); /****************************************************************************** * Private functions @@ -477,11 +512,16 @@ v_dcInsertHistoricalDataLink( assert(data->content._d == HISTORICAL_DATA_KIND_LINK); /* link */ assert(chain->link == NULL); /* not received yet */ - chain->sampleCount = data->content._u.link.sampleCount; - chain->completeness = data->content._u.link.completeness; - chain->errorCode = data->content._u.link.errorCode; - chain->link = c_keep(msg); - V_DC_TRACE("%s - link %p added to chain administration %p\n", OS_FUNCTION, (void *)msg, (void *)chain); + if (data->content._u.link.errorCode == V_DC_RETCODE_NO_ERROR) { + chain->sampleCount = data->content._u.link.sampleCount; + chain->completeness = data->content._u.link.completeness; + chain->errorCode = data->content._u.link.errorCode; + chain->link = c_keep(msg); + V_DC_TRACE("%s - link %p added to chain administration %p\n", OS_FUNCTION, (void *)msg, (void *)chain); + } else { + V_DC_TRACE("%s - link %p related to chain administration %p ignored because of error %x\n", + OS_FUNCTION, (void *)msg, (void *)chain, data->content._u.link.errorCode); + } } @@ -521,58 +561,6 @@ v_dcInsertHistoricalData( } } - -static void tracegroupGenKeystr(char *keystr, size_t keystr_size, v_groupInstance gi) -{ - v_group g = gi->group; - c_array instanceKeyList = c_tableKeyList(g->instances); - c_ulong i, nrOfKeys = c_arraySize(instanceKeyList); - size_t pos = 0; - assert (keystr_size >= 4); /* for ...\0 */ - for (i = 0; i < nrOfKeys; i++) - { - c_value v = c_fieldValue(instanceKeyList[i], gi); - char *vimg = c_valueImage(v); - int n = snprintf(keystr + pos, keystr_size - pos, "%s%s", (i == 0) ? "" : ";", vimg); - c_valueFreeRef(v); - os_free(vimg); - if (n > 0) { pos += (size_t)n; } else { break; } - } - if (i < nrOfKeys || pos >= keystr_size) { - if (pos >= keystr_size - 4) { - pos = keystr_size - 4; - } - strcpy(keystr + pos, "..."); - } - c_free(instanceKeyList); -} - - -#if 0 -static void tracegroupGenMsgKeystr(char *keystr, size_t keystr_size, v_group g, v_message msg) -{ - c_array messageKeyList = v_topicMessageKeyList(v_groupTopic(g)); - c_ulong i, nrOfKeys = c_arraySize(messageKeyList); - size_t pos = 0; - assert (keystr_size >= 4); /* for ...\0 */ - for (i = 0; i < nrOfKeys; i++) - { - c_value v = c_fieldValue(messageKeyList[i], msg); - char *vimg = c_valueImage(v); - int n = snprintf(keystr + pos, keystr_size - pos, "%s%s", (i == 0) ? "" : ";", vimg); - c_valueFreeRef(v); - os_free(vimg); - if (n > 0) { pos += (size_t)n; } else { break; } - } - if (i < nrOfKeys || pos >= keystr_size) { - if (pos >= keystr_size - 4) { - pos = keystr_size - 4; - } - strcpy(keystr + pos, "..."); - } -} -#endif - static void tracegroupInstance(v_groupInstance gi, const char *prefix) { v_groupSample s; @@ -580,14 +568,15 @@ static void tracegroupInstance(v_groupInstance gi, const char *prefix) OS_UNUSED_ARG(prefix); - tracegroupGenKeystr(keystr, sizeof (keystr), gi); + v_groupInstanceKeyToString(gi, keystr, sizeof (keystr)); V_DC_TRACE("%s - %sInstance %p state=%u epoch=%"PA_PRItime" key={%s}\n", OS_FUNCTION, prefix, (void*)gi, gi->state, OS_TIMEE_PRINT(gi->epoch), keystr); s = v_groupSample(gi->oldest); while (s != NULL) { v_message msg = v_groupSampleTemplate(s)->message; OS_UNUSED_ARG(msg); V_DC_TRACE("%s - %s Sample %p msg %p state=%u time=%"PA_PRItime" wrgid=%u:%u:%u\n", - OS_FUNCTION, prefix, (void*)s, (void*)msg, msg->_parent.nodeState, OS_TIMEW_PRINT(msg->writeTime), msg->writerGID.systemId, msg->writerGID.localId, msg->writerGID.serial); + OS_FUNCTION, prefix, (void*)s, (void*)msg, msg->_parent.nodeState, OS_TIMEW_PRINT(msg->writeTime), + msg->writerGID.systemId, msg->writerGID.localId, msg->writerGID.serial); s = s->newer; } } @@ -607,164 +596,32 @@ static void tracegroup(v_group g, const char *info) V_DC_TRACE("%s - Group %s.%s lastDisposeAllTime=%"PA_PRItime" - %s\n", OS_FUNCTION, v_partitionName(v_groupPartition(g)), v_topicName(v_groupTopic(g)), OS_TIMEW_PRINT(g->lastDisposeAllTime), info); - c_mutexLock(&g->mutex); - (void)c_walk((c_collection)g->instances, tracegroupHelper, NULL); - c_mutexUnlock(&g->mutex); + v_groupWalkInstances(g, tracegroupHelper, NULL); } - -static v_message -create_message(v_group group, struct _DDS_HistoricalData *bead, v_messageQos mqos, c_array messageKeyList, c_ulong nrOfKeys, c_value keyValues[], c_ulong nodeState) -{ - v_message message; - c_ulong i; - - assert(group); - assert(bead); - assert(mqos); - - /* Currently, beads have a writerGID (12 bytes) to identify the writer, not a GUID (16 bytes). - * Since the only server currently available is a durability service that uses beads with - * writerGID this is OK. If some time in the future a server is constructed that uses - * GUIDs to identify the writer the code below must be changed. */ - if (bead->content._u.bead.writerId[12] | bead->content._u.bead.writerId[13] | bead->content._u.bead.writerId[14] | bead->content._u.bead.writerId[15]) { - OS_REPORT(OS_ERROR, OS_FUNCTION, V_RESULT_INTERNAL_ERROR, - "The writerId of bead %p is not a valid writerGID", (void *)bead); - abort(); - } - message = v_topicMessageNew_s(v_groupTopic(group)); - if (message != NULL) { - v_nodeState(message) = nodeState; - memcpy(&message->writerGID, bead->content._u.bead.writerId, sizeof(message->writerGID)); - message->writeTime = OS_TIMEW_INIT(bead->content._u.bead.sourceTimestamp.sec, bead->content._u.bead.sourceTimestamp.nanosec); - message->qos = c_keep(mqos); - for (i=0;i 32) { - OS_REPORT(OS_ERROR, OS_FUNCTION, 0, "number of keys for topic %s (%d) exceeds limit of 32", v_topicName(v_groupTopic(group)), nrOfKeys); - writeResult = V_WRITE_PRE_NOT_MET; - goto err_nrOfKeys; - } - for (i = 0; i < nrOfKeys; i++) { - keyValues[i] = c_fieldValue(messageKeyList[i], msg); - } - /* get the instance associated with the msg key, or remember to register the instance */ - instance = v_groupLookupInstanceAndRegistration(group, keyValues, msg->writerGID, v_gidCompare, ®istration); - if (instance) { - if (registration) { - c_free(registration); - } else { - doRegister = TRUE; - } - } else { - doRegister = TRUE; - } - - /* Create registration and acquire the instance */ - if (doRegister) { - if ((registerMessage = create_message(group, bead, mqos, messageKeyList, nrOfKeys, keyValues, L_REGISTER)) == NULL) { - writeResult = V_WRITE_OUT_OF_RESOURCES; - goto err_register; - } - if (!c_baseMakeMemReservation(base, C_MM_RESERVATION_HIGH)) { - c_free(registerMessage); - writeResult = V_WRITE_OUT_OF_RESOURCES; - goto err_register_claim; - } - (void)v_groupWrite(group, registerMessage, &instance, V_NETWORKID_ANY, &resendScope); - c_baseReleaseMemReservation(base, C_MM_RESERVATION_HIGH); - if (v_gidIsNil(registerMessage->writerGID)) { - /* An unregister message must be sent to */ - if ((unregisterMessage = create_message(group, bead, mqos, messageKeyList, nrOfKeys, keyValues, L_UNREGISTER)) == NULL) { - writeResult = V_WRITE_OUT_OF_RESOURCES; - goto err_unregister; - } - doUnregister = TRUE; - } - c_free(registerMessage); - } - for (i = 0; i < nrOfKeys; i++) { - /* c_fieldValue adds a ref, so undo the ref */ - c_valueFreeRef(keyValues[i]); - } - - /* At this point we should have an instance */ - assert(instance); - - /* Send the data */ - if (writeResult == V_WRITE_SUCCESS) { - if (!c_baseMakeMemReservation(base, C_MM_RESERVATION_HIGH)) { - writeResult = V_WRITE_OUT_OF_RESOURCES; - goto err_data_claim; - } + if (c_baseMakeMemReservation(base, C_MM_RESERVATION_HIGH)) { + /* no caching, deliver to the reader */ if (entry) { - /* no caching, deliver to the reader */ - writeResult = v_groupWriteNoStreamWithEntry(group, msg, &instance, V_NETWORKID_ANY, entry); + writeResult = v_groupWriteHistoricalToReader(group, msg, entry); + } else if (v_gidIsNil(msg->writerGID)) { + writeResult = v_groupWriteHistoricalData(group, msg, NULL, V_NETWORKID_ANY); } else { - /* caching, write to group */ - writeResult = v_groupWrite(group, msg, &instance, V_NETWORKID_ANY, &resendScope); + v_resendScope resendScope = V_RESEND_NONE; + writeResult = v_groupWrite(group, msg, NULL, V_NETWORKID_ANY, &resendScope); } c_baseReleaseMemReservation(base, C_MM_RESERVATION_HIGH); } - - /* Send unregister when needed. */ - if (writeResult == V_WRITE_SUCCESS) { - if (doUnregister) { - if (!c_baseMakeMemReservation(c_getBase(group), C_MM_RESERVATION_HIGH)) { - writeResult = V_WRITE_OUT_OF_RESOURCES; - goto err_unregister_claim; - } - writeResult = v_groupWrite(group, unregisterMessage, &instance, V_NETWORKID_ANY, &resendScope); - /* Note that unregister message will never be rejected */ - c_baseReleaseMemReservation(c_getBase(group), C_MM_RESERVATION_HIGH); - c_free(unregisterMessage); - unregisterMessage = NULL; - } - } - - c_free(instance); - return writeResult; - -err_unregister_claim: - if (unregisterMessage) { - c_free(unregisterMessage); - } - -err_data_claim: -err_unregister: -err_register_claim: - c_free(registerMessage); -err_register: - c_free(instance); -err_nrOfKeys: return writeResult; } @@ -1045,9 +902,10 @@ v__dcChainBeadInject( goto err_bead_kind; } /* Inject the message to the group or reader. - * Possible return values of inject_message are V_WRITE_SUCCESS, V_WRITE_PRE_NOT_MET, V_WRITE_OUT_OF_RESOURCES, or V_WRITE_REJECTED. + * Possible return values of inject_message are: + * V_WRITE_SUCCESS, V_WRITE_PRE_NOT_MET, V_WRITE_OUT_OF_RESOURCES, or V_WRITE_REJECTED. * Only in case the message is injected successfully the bead is removed. */ - if ((writeResult = inject_message(_this, msg, mqos, bead, group, entry)) == V_WRITE_SUCCESS) { + if ((writeResult = inject_message(group, msg, entry)) == V_WRITE_SUCCESS) { ut_avlCDelete (&beads_avltreedef, &chain->beads, b); cleanup_bead(b); } @@ -1260,7 +1118,7 @@ v__dcCheckChainComplete( } else if (writeResult == V_WRITE_SUCCESS) { /* All beads successfully injected */ if (cache) { - v_groupCompleteSet(chain->vgroup, TRUE); + (void)v_groupCompleteSet(chain->vgroup, V_ALIGNSTATE_COMPLETE); } } else { /* V_WRITE_PRE_NOT_MET or V_WRITE_OUT_OF_RESOURCES */ @@ -1329,7 +1187,7 @@ v__dcCreateEntities(v_durabilityClient _this) */ _this->waitset = v_waitsetNew (_this->participant); _this->publisher = v_publisherNew (_this->participant, V_DC_PUBLISHER_NAME, pQos, FALSE); - _this->subscriber = v_subscriberNew(_this->participant, V_DC_SUBSCRIBER_NAME, sQos, FALSE); + _this->subscriber = v_subscriberNew(_this->participant, V_DC_SUBSCRIBER_NAME, sQos); if ((_this->waitset == NULL) || (_this->publisher == NULL) || (_this->subscriber == NULL) ){ @@ -1492,9 +1350,9 @@ is_builtin_group( if(strcmp(partition, V_BUILTIN_PARTITION) != 0) { return FALSE; } else { - int i; - for (i = 0; builtin_topics[i] != NULL; i++) { - if (strcmp (topic, builtin_topics[i]) == 0) { + c_ulong i; + for (i = 0; i < num_builtin_topics; i++) { + if (strcmp (topic, builtin_topics[i].topicName) == 0) { return TRUE; } } @@ -1560,25 +1418,29 @@ v__dcEventHistoricalDataRequest(v_durabilityClient _this, v_durabilityClientEven v_partition p; c_bool cache; v_subscriber subscriber; + v_topic vtopic; assert (v_objectKind(rd) == K_DATAREADER); /* Make sure that the subscriber exists, the subscriber could be removed while the reader is being destroyed */ - v_observerLock(v_observer(rd)); - subscriber = c_keep(rd->subscriber); - v_observerUnlock(v_observer(rd)); + subscriber = v_readerGetSubscriber(rd); if (subscriber != NULL) { rhandle = v_publicHandle(v_public(rd)); - topic = c_keep(v_entityName(v_dataReaderGetTopic(v_dataReader(rd)))); - c_mutexLock(&v_subscriber(subscriber)->partitions->mutex); - kps = ospl_c_select(v_subscriber(subscriber)->partitions->partitions, 0); - c_mutexUnlock(&v_subscriber(subscriber)->partitions->mutex); - while ((p = v_partition(c_iterTakeFirst(kps))) != NULL) { - /* skip builtin topics and groups that do not need to be aligned by client durability */ - if ((!is_builtin_group(v_partitionName(p), topic)) && (v_durabilityClientIsResponsibleForAlignment(_this, v_partitionName(p), topic, &cache))) { - ps = c_iterAppend(ps, c_keep(v_entity(p)->name)); - doRequest = TRUE; + vtopic = v_readerGetTopic(rd); + + if(vtopic){ + topic = c_keep(v_entityName(vtopic)); + c_mutexLock(&v_subscriber(rd->subscriber)->partitions->mutex); + kps = ospl_c_select(v_subscriber(rd->subscriber)->partitions->partitions, 0); + c_mutexUnlock(&v_subscriber(rd->subscriber)->partitions->mutex); + while ((p = v_partition(c_iterTakeFirst(kps))) != NULL) { + /* skip builtin topics and groups that do not need to be aligned by client durability */ + if ((!is_builtin_group(v_partitionName(p), topic)) && (v_durabilityClientIsResponsibleForAlignment(_this, v_partitionName(p), topic, &cache))) { + ps = c_iterAppend(ps, c_keep(v_entity(p)->name)); + doRequest = TRUE; + } + c_free(p); } - c_free(p); + c_free(vtopic); } c_iterFree(kps); c_free(subscriber); @@ -1870,7 +1732,7 @@ v__dcHandleHistoricalData(v_durabilityClient _this, v_dataReaderSample sample) { /* To print the message */ char tmpstr[30]; if (data->content._d == HISTORICAL_DATA_KIND_LINK) { - snprintf(tmpstr, sizeof(tmpstr), "L %u %u %u", data->content._u.link.sampleCount, data->content._u.link.completeness, data->content._u.link.errorCode); + snprintf(tmpstr, sizeof(tmpstr), "L %u %u %x", data->content._u.link.sampleCount, data->content._u.link.completeness, data->content._u.link.errorCode); } V_DC_TRACE("%s - Sample %p msg %p state=%u time=%"PA_PRItime" wrgid=%u:%u:%u %s\n", OS_FUNCTION, (void*)sample, (void*)msg, msg->_parent.nodeState, OS_TIMEW_PRINT(msg->writeTime), @@ -2206,7 +2068,7 @@ v__dcNewReader(v_subscriber subscriber, v_topic topic, v_readerQos qos) assert (0); } expr_q = q_parse(expr_str); - dr = v_dataReaderNew(subscriber, name, expr_q, NULL, qos, FALSE); + dr = v_dataReaderNew(subscriber, name, expr_q, NULL, 0, qos); q_dispose(expr_q); @@ -2591,13 +2453,14 @@ v__dcWaitsetAction(v_waitsetEvent e, c_voidp arg) static void v__dcWaitsetSetup(v_durabilityClient _this) { - v_observerSetEventMask(v_observer(_this->waitset), - V_EVENT_DATA_AVAILABLE | V_EVENT_TERMINATE | V_EVENT_HISTORY_REQUEST); + v_eventMask mask = V_EVENT_DATA_AVAILABLE | V_EVENT_TERMINATE | V_EVENT_HISTORY_REQUEST; - (void)v_observableAddObserver(v_observable(_this->participant), v_observer(_this->waitset), NULL); /* to trigger the participant */ - (void)v_observableAddObserver(v_observable(_this->readers[V_DC_READER_STATE_ID]), v_observer(_this->waitset), NULL); - (void)v_observableAddObserver(v_observable(_this->readers[V_DC_READER_DATA_ID]), v_observer(_this->waitset), NULL); - (void)v_observableAddObserver(v_observable(_this->readers[V_DC_READER_SUBSCRIPTIONINFO_ID]), v_observer(_this->waitset), NULL); + OSPL_SET_EVENT_MASK(_this->waitset, V_EVENTMASK_ALL); + + (void)OSPL_ADD_OBSERVER(_this->participant, _this->waitset, mask, NULL); + (void)OSPL_ADD_OBSERVER(_this->readers[V_DC_READER_STATE_ID], _this->waitset, mask, NULL); + (void)OSPL_ADD_OBSERVER(_this->readers[V_DC_READER_DATA_ID], _this->waitset, mask, NULL); + (void)OSPL_ADD_OBSERVER(_this->readers[V_DC_READER_SUBSCRIPTIONINFO_ID], _this->waitset, mask, NULL); } @@ -2683,6 +2546,8 @@ v_durabilityClientNew( _this->partitions[V_DC_PARTITION_GLOBAL_DATA_ID] = c_stringNew(base, partitionDataGlobal); _this->partitions[V_DC_PARTITION_PRIVATE_DATA_ID] = c_stringNew(base, partitionDataPrivate); + _this->alignBuiltin = FALSE; + if (!v__dcCreateEntities(_this)) { OS_REPORT (OS_ERROR, "kernel::v_durabilityClient::v_durabilityClientNew", V_RESULT_INTERNAL_ERROR, @@ -2777,7 +2642,7 @@ get_durable_policies_str( strcpy(result, "\0"); while ((policy = (struct durablePolicy *)c_iterNext(&iter)) != NULL) { char *tmp; - tmp = os_malloc(strlen(result) + 1 /* */ + 1 /* ( */ + strlen(policy->obtain) + 1 /* , */ + 5 /* TRUE, FALSE */ + 1 /* ) */); + tmp = os_malloc(strlen(result) + 1 /* */ + 1 /* ( */ + strlen(policy->obtain) + 1 /* , */ + 5 /* TRUE, FALSE */ + 1 /* ) */ + 1 /* \0 */); os_sprintf(tmp, "%s (%s,%s)", result, policy->obtain, policy->cache ? "TRUE" : "FALSE"); os_free(result); result = tmp; @@ -2795,6 +2660,7 @@ get_durable_policies_str( void v_durabilityClientMain(v_durabilityClient _this) { + v_kernel kernel; os_duration retry_time = OS_DURATION_INIT( 0, 100000000 ); /* 100 ms */ os_duration timeout; @@ -2809,6 +2675,8 @@ v_durabilityClientMain(v_durabilityClient _this) assert(_this->partitions[V_DC_PARTITION_GLOBAL_DATA_ID]); assert(_this->partitions[V_DC_PARTITION_PRIVATE_DATA_ID]); + kernel = v_objectKernel(_this); + /* Enable the readers and writers */ v__dcEnable(_this); @@ -2821,6 +2689,19 @@ v_durabilityClientMain(v_durabilityClient _this) os_free(durablePoliciesStr); + /* When the networking service or the secure networking service is configured + * client durability should also perform the alignment of the builtin topics. + * Because the builtin readers are created before the durability client is + * created the historical data request of these readers are not received by + * client durability and have to be added. + */ + if (!v_configurationContainsService(kernel->configuration, "DurabilityService") && + (v_configurationContainsService(kernel->configuration, "NetworkService") || + v_configurationContainsService(kernel->configuration, "SNetworkService"))) { + _this->alignBuiltin = TRUE; + v__dcRequestHistoricalBuiltinData(_this); + } + while (!_this->terminate) { /* Handle events in the queue. */ v__dcEventDispatcher(_this); @@ -2854,9 +2735,7 @@ v_durabilityClientTerminate(v_durabilityClient _this) term.data = NULL; o = v_observer(_this->waitset); - v_observerLock(o); - v_observerNotify(o, &term, NULL); - v_observerUnlock(o); + OSPL_TRIGGER_EVENT(o, &term, NULL); } } @@ -2922,6 +2801,22 @@ v_durabilityClientIsResponsibleForAlignment( } os_free(str); } + + if (!result) { + v_kernel kernel = v_objectKernel(_this); + if (_this->alignBuiltin) { + c_ulong i; + for (i = 0; i < num_builtin_topics; i++) { + if (strcmp(builtin_topics[i].topicName, topic) == 0) { + if (builtin_topics[i].always || (kernel->qos->builtin.v.enabled && builtin_topics[i].align)) { + result = TRUE; + } + break; + } + } + } + } + return result; } @@ -2967,7 +2862,7 @@ has_non_volatile_reader(v_groupEntry groupEntry, c_voidp arg) if (!*interest) { v_reader r; - r = v_reader(v_dataReaderEntry(groupEntry->entry)); + r = v_entryReader(groupEntry->entry); if (r) { if (r->qos) { *interest = (r->qos->durability.v.kind > V_DURABILITY_VOLATILE); @@ -3079,3 +2974,52 @@ v_dcUpdateDurabilityState( return; } +static void +v__dcRequestHistoricalBuiltinData( + v_durabilityClient _this) +{ + v_kernel kernel; + v_spliced spliced; + v_handle rhandle; + c_iter ps, alignmentPartition; + c_bool alignBuiltin; + c_ulong i; + + kernel = v_objectKernel(_this); + spliced = v_kernelGetSpliced(kernel); + alignBuiltin = kernel->qos->builtin.v.enabled; + + ps = c_iterNew(V_BUILTIN_PARTITION); + + alignmentPartition = c_iterNew(_this->partitions[V_DC_PARTITION_PRIVATE_DATA_ID]); + + for (i = 0; i < num_builtin_topics; i++) { + c_ulong j; + c_bool found = FALSE; + + if (builtin_topics[i].align && (alignBuiltin || builtin_topics[i].always)) { + for (j = 0; !found && (j < V_INFO_ID_COUNT); j++) { + v_topic vtopic; + + if (c_instanceOf(spliced->readers[j], "v_dataReader")) { + vtopic = v_dataReaderGetTopic(spliced->readers[j]); + if (vtopic && (strcmp(builtin_topics[i].topicName, v_topicName(vtopic)) == 0)) { + rhandle = v_publicHandle(v_public(spliced->readers[j])); + found = TRUE; + } + c_free(vtopic); + } + } + } + + if (found) { + v_dcSendMsgDataRequest( + _this, rhandle, ps, (char *)builtin_topics[i].topicName, + NULL, NULL, OS_TIMEW_ZERO, OS_TIMEW_INFINITE, + -1, -1, -1, alignmentPartition, OS_DURATION_ZERO); + } + } + + c_iterFree(alignmentPartition); + c_iterFree(ps); +} diff --git a/src/kernel/code/v_durabilityStatistics.c b/src/kernel/code/v_durabilityStatistics.c index 1f4765d5e..0226fe63d 100644 --- a/src/kernel/code/v_durabilityStatistics.c +++ b/src/kernel/code/v_durabilityStatistics.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/code/v_entity.c b/src/kernel/code/v_entity.c index 510370bfa..5b8949252 100644 --- a/src/kernel/code/v_entity.c +++ b/src/kernel/code/v_entity.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,9 +30,12 @@ #include "v_dataReader.h" #include "v_dataReaderEntry.h" #include "v__dataView.h" +#include "v__groupQueue.h" #include "v__reader.h" +#include "v__deliveryService.h" #include "v_partition.h" #include "v__topic.h" +#include "v__topicImpl.h" #include "v__topicAdapter.h" #include "v__topicQos.h" #include "v_query.h" @@ -58,26 +62,20 @@ #define _TRACE_EVENTS_(...) #endif -v_result +void v_entityInit( - v_entity e, - const c_char *name, - c_bool enable) + _Inout_ v_entity e, + _In_opt_z_ const c_char *name) { assert(C_TYPECHECK(e,v_entity)); - if (name == NULL) { - e->name = NULL; - } else { - e->name = c_stringNew(c_getBase(e),name); - } + e->name = c_stringNew(c_getBase(e),name); e->status = v_statusNew(e); e->listener = NULL; e->listenerInterest = 0; - e->enabled = enable; + e->state = V_ENTITYSTATE_DISABLED; e->loan = NULL; v_observerInit(v_observer(e)); - return V_RESULT_OK; } void @@ -148,6 +146,20 @@ v_entityStatus( return c_keep(e->status); } +v_state +v_entityGetStatusFlags( + v_entity e) +{ + v_state state; + assert(e != NULL); + assert(C_TYPECHECK(e,v_entity)); + + OSPL_BLOCK_EVENTS(e); + state = e->status->state; + OSPL_UNBLOCK_EVENTS(e); + return state; +} + void v_entityStatusReset( v_entity e, @@ -173,13 +185,9 @@ v_entityStatusGetMask( c_ulong v_entityGetTriggerValue( - v_entity _this) + _In_ v_entity _this) { - c_ulong triggerValue = 0; - if (_this != NULL) { - triggerValue = v_statusGetMask(_this->status); - } - return triggerValue; + return v_statusGetMask(_this->status); } v_entity @@ -230,32 +238,16 @@ v_entityGetProcessId( return processId; } -v_result -v_entityEnable ( - v_entity e) +static v_result +v__entityEnable ( + _Inout_ v_entity e) { v_result result; - assert(e != NULL); - assert(C_TYPECHECK(e,v_entity)); - - v_observerLock(v_observer(e)); - if (e->enabled) { - v_observerUnlock(v_observer(e)); - result = V_RESULT_OK; /* Idempotent */ - } else { - e->enabled = TRUE; - v_observerUnlock(v_observer(e)); - switch (v_objectKind(e)) { + switch (v_objectKind(e)) { case K_TOPIC: - /* TODO: OSPL-12. - * Topics are currently always created in an enabled state, so it makes no sense - * to try and enable them here. What is needed is that, when disabled topics are - * supported, we check whether the v_topicEnable fails, and if it does we return - * this fail to the user layer, which then needs to reroute its handle to the - * topic's precursor. - */ - result = V_RESULT_OK; + case K_TOPIC_ADAPTER: + result = v__topicEnable(v_topic(e)); break; case K_WRITER: result = v_writerEnable(v_writer(e)); @@ -263,11 +255,14 @@ v_entityEnable ( case K_DATAREADER: result = v_dataReaderEnable(v_dataReader(e)); break; + case K_GROUPQUEUE: + result = v_groupQueueEnable(v_groupQueue(e)); + break; case K_PUBLISHER: result = v_publisherEnable(v_publisher(e)); break; case K_SUBSCRIBER: - result = v_subscriberEnable(v_subscriber(e)); + result = v__subscriberEnable(v_subscriber(e)); break; case K_PARTICIPANT: case K_SERVICE: @@ -277,33 +272,122 @@ v_entityEnable ( case K_NWBRIDGE: case K_CMSOAP: case K_RNR: + case K_DBMSCONNECT: result = v_participantEnable(v_participant(e)); break; + case K_DELIVERYSERVICE: + result = v__deliveryServiceEnable(v_deliveryService(e)); + break; + case K_SERVICEMANAGER: case K_NETWORKREADER: - case K_GROUPQUEUE: case K_DATAVIEW: + case K_DOMAIN: result = V_RESULT_OK; - break; + break; + case K_KERNEL: + v_kernelEnable(v_kernel(e)); + result = V_RESULT_OK; + break; default: result = V_RESULT_CLASS_MISMATCH; OS_REPORT(OS_ERROR, "v_entityEnable", result, - "Supplied entity (%d) can not be enabled", - v_objectKind(e)); - break; - } + "Supplied entity %s can not be enabled", + v_objectKindImage(v_object(e))); + break; } return result; } +v_result +v_entityEnable ( + _Inout_ v_entity e) +{ + v_result result; + + assert(e != NULL); + assert(C_TYPECHECK(e,v_entity)); + + do { + OSPL_LOCK(e); + _TRACE_EVENTS_("Enabling entity '%s' (%s(%d)) (%d) %p\n", v_entityName(e), v_objectKindImage(v_object(e)), v_objectKind(e), e->state, e); + switch (e->state) { + case V_ENTITYSTATE_ENABLED: + OSPL_UNLOCK(e); + result = V_RESULT_OK; + break; + case V_ENTITYSTATE_ENABLING: + OSPL_UNLOCK(e); + { + /* TODO: Replace polling? */ + os_time poll = {0, 100000000}; + os_nanoSleep(poll); + } + result = V_RESULT_NOT_ENABLED; + break; + case V_ENTITYSTATE_DISABLED: + e->state = V_ENTITYSTATE_ENABLING; + OSPL_UNLOCK(e); + result = v__entityEnable(e); + OSPL_LOCK(e); + e->state = (result == V_RESULT_OK) ? V_ENTITYSTATE_ENABLED : V_ENTITYSTATE_DISABLED; + OSPL_UNLOCK(e); + break; + default: + result = V_RESULT_NOT_ENABLED; + break; + } + } while (result == V_RESULT_NOT_ENABLED); + + _TRACE_EVENTS_("Enabling entity %s (%d) %p returned %s\n", v_objectKindImage(v_object(e)), e->state, e, v_resultImage(result)); + + return result; +} + c_bool v_entityEnabled ( - v_entity _this) + _In_ v_entity _this) +{ + c_bool enabled; + + OSPL_LOCK(_this); + enabled = v__entityEnabled_nl(_this); + OSPL_UNLOCK(_this); + + return enabled; +} + +c_bool +v__entityEnabled_nl ( + _In_ v_entity _this) { assert(_this != NULL); assert(C_TYPECHECK(_this,v_entity)); - return _this->enabled; + return _this->state == V_ENTITYSTATE_ENABLED; +} + +c_bool +v_entityDisabled ( + _In_ v_entity _this) +{ + c_bool disabled; + + OSPL_LOCK(_this); + disabled = v__entityDisabled_nl(_this); + OSPL_UNLOCK(_this); + + return disabled; +} + +c_bool +v__entityDisabled_nl ( + _In_ v_entity _this) +{ + assert(_this != NULL); + assert(C_TYPECHECK(_this,v_entity)); + + return _this->state == V_ENTITYSTATE_DISABLED; } c_voidp @@ -355,23 +439,20 @@ v_entityWalkEntities( { c_bool r = TRUE; + OSPL_LOCK(e); switch(v_objectKind(e)){ case K_DATAREADER: - v_observerLock(v_observer(e)); r = c_setWalk(v_collection(e)->queries,(c_action)action,arg); if (r == TRUE) { struct entryActionArg a; a.action = (c_action)action; a.arg = arg; - v_readerWalkEntries(v_reader(e),entryAction,&a); + v_readerWalkEntries_nl(v_reader(e),entryAction,&a); } - v_observerUnlock(v_observer(e)); break; case K_QUERY: case K_DATAREADERQUERY: - v_observerLock(v_observer(e)); r = c_setWalk(v_collection(e)->queries,(c_action)action,arg); - v_observerUnlock(v_observer(e)); break; case K_PARTICIPANT: case K_SERVICE: @@ -381,33 +462,25 @@ v_entityWalkEntities( case K_NETWORKING: case K_CMSOAP: case K_RNR: - c_lockRead(&v_participant(e)->lock); + case K_DBMSCONNECT: r = c_setWalk(v_participant(e)->entities,(c_action)action,arg); - c_lockUnlock(&v_participant(e)->lock); break; case K_PUBLISHER: - c_lockRead(&v_publisher(e)->lock); r = c_setWalk(v_publisher(e)->writers,(c_action)action,arg); if (r == TRUE) { r = c_tableWalk(v_publisher(e)->partitions->partitions,(c_action)action,arg); } - c_lockUnlock(&v_publisher(e)->lock); break; case K_SUBSCRIBER: - v_subscriberLock(v_subscriber(e)); r = c_setWalk(v_subscriber(e)->readers,(c_action)action,arg); if (r == TRUE) { r = c_tableWalk(v_subscriber(e)->partitions->partitions,(c_action)action,arg); } - v_subscriberUnlock(v_subscriber(e)); break; case K_WRITER: - v_observerLock(v_observer(e)); r = action(v_entity(v_writer(e)->topic),arg); - v_observerUnlock(v_observer(e)); break; case K_KERNEL: - c_lockRead(&v_kernel(e)->lock); r = c_tableWalk(v_kernel(e)->topics,(c_action)action,arg); if (r == TRUE) { r = c_tableWalk(v_kernel(e)->partitions,(c_action)action,arg); @@ -415,11 +488,11 @@ v_entityWalkEntities( if (r == TRUE) { r = c_setWalk(v_kernel(e)->participants,(c_action)action,arg); } - c_lockUnlock(&v_kernel(e)->lock); break; default: break; } + OSPL_UNLOCK(e); return r; } @@ -518,12 +591,14 @@ v_entityWalkDependantEntities( while (entity != NULL) { if (r == TRUE) { + v_subscriber s; (void) action(entity, arg); #ifdef DDS_269 - entity2 = v_reader(entity)->subscriber; - v_subscriberLock(v_subscriber(entity2)); - r = c_tableWalk(v_subscriber(entity2)->partitions->partitions,(c_action)action,arg); - v_subscriberUnlock(v_subscriber(entity2)); + s = v_readerGetSubscriber(v_reader(entity)); + OSPL_LOCK(s); + r = c_tableWalk(s->partitions->partitions,(c_action)action,arg); + OSPL_UNLOCK(s); + c_free(s); #endif } c_free(entity); @@ -538,12 +613,14 @@ v_entityWalkDependantEntities( while(entity != NULL){ if (r == TRUE) { + v_publisher p; (void) action(entity, arg); #ifdef DDS_269 - entity2 = v_writer(entity)->publisher; - c_lockRead(&v_publisher(entity2)->lock); - r = c_tableWalk(v_publisher(entity2)->partitions->partitions,(c_action)action,arg); - c_lockUnlock(&v_publisher(entity2)->lock); + p = v_writerGetPublisher(v_writer(entity)); + OSPL_LOCK(p); + r = c_tableWalk(p->partitions->partitions,(c_action)action,arg); + OSPL_UNLOCK(p); + c_free(p); #endif } c_free(entity); @@ -563,12 +640,8 @@ v_entityWalkDependantEntities( r = action(entity, arg); #ifdef DDS_268 if(r == TRUE){ - c_lockRead(&v_publisher(entity)->lock); - iter2 = ospl_c_select(v_publisher(entity)->writers, 0); - c_lockUnlock(&v_publisher(entity)->lock); - + iter2 = v_publisherLookupWriters(v_publisher(entity), "*"); entity2 = v_entity(c_iterTakeFirst(iter2)); - while (entity2 != NULL) { topic = c_keep(v_topic(v_writer(entity2)->topic)); @@ -598,12 +671,8 @@ v_entityWalkDependantEntities( r = action(entity, arg); #ifdef DDS_268 if(r == TRUE){ - v_subscriberLock(v_subscriber(entity)); - iter2 = ospl_c_select(v_subscriber(entity)->readers, 0); - v_subscriberUnlock(v_subscriber(entity)); - + iter2 = v_subscriberLookupReadersByTopic(v_subscriber(entity), "*"); entity2 = v_entity(c_iterTakeFirst(iter2)); - while (entity2 != NULL) { if (c_iterContains(iter3, entity2) == FALSE) { v_readerWalkEntries(v_reader(entity2), @@ -657,12 +726,11 @@ v_entitySetListener( v_eventMask additional_interest; c_voidp userData; - /*C_STRUCT(v_event) event;*/ assert(_this != NULL); assert(C_TYPECHECK(_this,v_entity)); assert(C_TYPECHECK(listener,v_listener)); - v_observerLock(v_observer(_this)); + OSPL_LOCK(_this); additional_interest = interest & ~_this->listenerInterest; obsolete_interest = _this->listenerInterest & ~interest & ~V_EVENT_OBJECT_DESTROYED; @@ -688,7 +756,7 @@ v_entitySetListener( _this->listenerInterest = interest; _this->listenerData = listenerData; - v_observerUnlock(v_observer(_this)); + OSPL_UNLOCK(_this); /* Now reset status flags for new interest so that the listener will be triggered. * Note that triggers are blocked once the flag is set. @@ -798,7 +866,7 @@ v_entityNotifyListener( { _TRACE_EVENTS_("v_entityNotifyListener: -- Event(0x%x) matches %s(0x%x) interest(0x%x) so notify listener\n", event->kind, v_objectKindImage(entity), entity, entity->listenerInterest); - /* workaround to reset the topic listener when set on a participant see OSPL-3899 */ + /* workaround to reset the topic listener when set on a participant */ if (_this != v_entity(event->source) && v_objectKind(v_object(v_entity(event->source))) == K_TOPIC) { v_entityStatusReset(v_entity(event->source), event->kind); } else { @@ -837,14 +905,14 @@ v_entityDisableCallbacks ( c_bool triggered; C_STRUCT(v_event) event; - v_observerLock(v_observer(e)); + OSPL_LOCK(e); event.kind = V_EVENT_OBJECT_DESTROYED; event.source = v_observable(e); event.data = NULL; e->listenerInterest |= V_EVENT_OBJECT_DESTROYED; triggered = v_entityNotifyListener(e, &event); - v_observerUnlock(v_observer(e)); + OSPL_UNLOCK(e); return triggered; } @@ -871,6 +939,7 @@ v_entityGetXMLQos( case K_NWBRIDGE: case K_CMSOAP: case K_RNR: + case K_DBMSCONNECT: qos = v_qos(c_keep(v_participant(e)->qos)); break; case K_TOPIC: @@ -969,6 +1038,7 @@ v_entitySetXMLQos( case K_NWBRIDGE: case K_CMSOAP: case K_RNR: + case K_DBMSCONNECT: type = c_resolve(base, "kernelModuleI::v_participantQos"); qos = createQosFromXML(type, xml); if (qos) { @@ -990,15 +1060,16 @@ v_entitySetXMLQos( result = v_writerSetQos(v_writer(e), (v_writerQos)qos); } break; - case K_DATAREADER: /* intentionally no break */ - case K_NETWORKREADER: /* intentionally no break */ - case K_GROUPQUEUE: + case K_DATAREADER: type = c_resolve(base, "kernelModuleI::v_readerQos"); qos = createQosFromXML(type, xml); if (qos) { - result = v_readerSetQos(v_reader(e), (v_readerQos)qos); + result = v_dataReaderSetQos(v_dataReader(e), (v_readerQos)qos); } break; + case K_NETWORKREADER: /* intentionally no break */ + case K_GROUPQUEUE: + break; case K_PUBLISHER: type = c_resolve(base, "kernelModuleI::v_publisherQos"); qos = createQosFromXML(type, xml); @@ -1020,15 +1091,6 @@ v_entitySetXMLQos( result = v_dataViewSetQos(v_dataView(e), (v_dataViewQos)qos); } break; -#if 0 - case K_DOMAIN: - type = c_resolve(base, "kernelModuleI::v_partitionQos"); - qos = createQosFromXML(type, xml); - if (qos) { - result = v_partitionSetQos(v_partition(e), (v_partitionQos)qos); - } - break; -#endif default: result = V_RESULT_CLASS_MISMATCH; OS_REPORT(OS_ERROR, @@ -1040,4 +1102,69 @@ v_entitySetXMLQos( return result; } +v_result +v_entityGetProperty( + const v_entity _this, + const os_char * property, + os_char ** value) +{ + v_result result = V_RESULT_UNSUPPORTED; + *value = NULL; + if (!os_strcasecmp(property, "isolatenode")) { + os_uint32 isolate; + result = V_RESULT_OK; + + v_kernelGetIsolate(v_objectKernel(_this), &isolate); + switch (isolate) { + case V_ISOLATE_DEAF: + *value = os_strdup("deaf"); + break; + case V_ISOLATE_MUTE: + *value = os_strdup("mute"); + break; + case V_ISOLATE_ALL: + *value = os_strdup("true"); + break; + case V_ISOLATE_NONE: + *value = os_strdup("false"); + break; + default: + *value = NULL; + result = V_RESULT_INTERNAL_ERROR; + break; + } + } else { + OS_REPORT(OS_ERROR, + "v_entityGetProperty", result, + "Supplied property %s is invalid", property); + } + return result; +} +v_result +v_entitySetProperty( + const v_entity _this, + const os_char * property, + const os_char * value) +{ + v_result result = V_RESULT_UNSUPPORTED; + if (!os_strcasecmp(property, "isolatenode")) { + result = V_RESULT_OK; + if (!os_strcasecmp(value, "false")) { + v_kernelSetIsolate(v_objectKernel(_this), V_ISOLATE_NONE); + } else if (!os_strcasecmp(value, "true")) { + v_kernelSetIsolate(v_objectKernel(_this), V_ISOLATE_ALL); + } else if (!os_strcasecmp(value, "deaf")) { + v_kernelSetIsolate(v_objectKernel(_this), V_ISOLATE_DEAF); + } else if (!os_strcasecmp(value, "mute")) { + v_kernelSetIsolate(v_objectKernel(_this), V_ISOLATE_MUTE); + } else { + result = V_RESULT_ILL_PARAM; + } + } else { + OS_REPORT(OS_ERROR, + "v_entitySetProperty", result, + "Supplied property %s is invalid", property); + } + return result; +} diff --git a/src/kernel/code/v_entry.c b/src/kernel/code/v_entry.c index 05a390402..117b3d44b 100644 --- a/src/kernel/code/v_entry.c +++ b/src/kernel/code/v_entry.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,6 +20,7 @@ */ #include "v__entry.h" #include "v__observer.h" +#include "v__observable.h" #include "v__reader.h" #include "v__group.h" #include "v_entity.h" @@ -43,9 +45,10 @@ */ #define COMPLETE_FLAG (0x0001) #define DURABILITY_FLAG (0x0002) + #define SET_COMPLETE(userData, complete) \ { c_address data = (c_address)userData; \ - if (complete) {data |= COMPLETE_FLAG;} else {data &= (c_address)~COMPLETE_FLAG;} \ + if ((complete) == V_ALIGNSTATE_COMPLETE) {data |= COMPLETE_FLAG;} else {data &= (c_address)~COMPLETE_FLAG;} \ userData = (c_voidp)data; \ } #define SET_DURABILITY(userData, durability) \ @@ -69,7 +72,7 @@ v_entryInit( kernel = v_objectKernel(reader); _this->reader = reader; - _this->complete = FALSE; + _this->alignState = V_ALIGNSTATE_INCOMPLETE; _this->nvgCount = 0; /* non volatile group count */ _this->groups = c_tableNew(v_kernelType(kernel,K_PROXY), "source.index,source.server"); assert(_this->groups != NULL); @@ -91,6 +94,7 @@ v_entryFree( group = v_group(v_proxyClaim(proxy)); if (group) { v_groupRemoveEntry(group, _this); + v_entryRemoveGroup(_this, group); v_proxyRelease(proxy); } c_free(proxy); @@ -169,31 +173,31 @@ v_entryResend( static c_bool get_completeness(c_object o, c_voidp arg) { - c_bool *complete = (c_bool *)arg; + v_alignState *alignState = (v_alignState *)arg; if (!TEST_COMPLETE(v_proxyUserData(o))) { - *complete = FALSE; + *alignState = V_ALIGNSTATE_INCOMPLETE; } - return *complete; + return *alignState == V_ALIGNSTATE_COMPLETE; } -c_bool +void v_entryAddGroup( v_entry _this, v_group group) { v_proxy proxy; v_proxy found; - c_bool result; - c_bool complete; + v_alignState alignState; c_bool durability; c_voidp userData = NULL; + c_bool stateChanged = FALSE; assert(C_TYPECHECK(_this,v_entry)); assert(C_TYPECHECK(group,v_group)); - complete = v_groupCompleteGet(group); + alignState = v_groupCompleteGet(group); durability = v_groupIsDurable(group); - SET_COMPLETE(userData, complete); + SET_COMPLETE(userData, alignState); SET_DURABILITY(userData, durability); /* Create group proxy and store completeness (and in the future also durability) @@ -203,35 +207,38 @@ v_entryAddGroup( v_publicHandle(v_public(group)), (c_voidp)userData); + OSPL_LOCK(_this->reader); found = ospl_c_insert(_this->groups, proxy); if(found != proxy){ /* The group was already available in the groupset. This can happen if * the reader gets notified of the group it has just created. In that - * case the administration should not be updated. */ - result = FALSE; + * case the administration should not be updated. + */ } else { - if (_this->complete != complete) { - if (_this->complete) { + if (_this->alignState != alignState) { + if (_this->alignState == V_ALIGNSTATE_COMPLETE) { /* reader becomes incomplete because an incomplete group is added. */ - _this->complete = FALSE; + _this->alignState = V_ALIGNSTATE_INCOMPLETE; } else { /* reader was incomplete and group is complete so recheck total completeness. */ - _this->complete = TRUE; - (void)c_tableWalk(_this->groups, get_completeness, &_this->complete); + _this->alignState = V_ALIGNSTATE_COMPLETE; + (void)c_tableWalk(_this->groups, get_completeness, &_this->alignState); } - if (_this->complete == complete) { + assert(_this->alignState == V_ALIGNSTATE_COMPLETE || _this->alignState == V_ALIGNSTATE_INCOMPLETE); + if (_this->alignState == alignState) { /* reader completeness has changed so notify state change. */ - v_readerNotifyStateChange(_this->reader, _this->complete); + stateChanged = TRUE; } } if (durability == TRUE) { _this->nvgCount++; } - result = TRUE; + if (stateChanged) { + v__readerNotifyStateChange_nl(_this->reader, _this->alignState == V_ALIGNSTATE_COMPLETE); + } } + OSPL_UNLOCK(_this->reader); c_free(proxy); - - return result; } void @@ -256,6 +263,7 @@ v_entryRemoveGroup( params[0] = c_ulongValue(handle.index); params[1] = c_addressValue(handle.server); + OSPL_LOCK(_this->reader); query = c_queryNew(_this->groups, qExpr, params); q_dispose(qExpr); groups = ospl_c_select(query, 0); @@ -265,12 +273,12 @@ v_entryRemoveGroup( proxy2 = c_remove(_this->groups, proxy, NULL, NULL); c_free(proxy); if (proxy2) { - if (!_this->complete) { - _this->complete = TRUE; - (void)c_tableWalk(_this->groups, get_completeness, &_this->complete); - if (_this->complete) { + if (_this->alignState == V_ALIGNSTATE_INCOMPLETE) { + _this->alignState = V_ALIGNSTATE_COMPLETE; + (void)c_tableWalk(_this->groups, get_completeness, &_this->alignState); + if (_this->alignState == V_ALIGNSTATE_COMPLETE) { /* reader became complete because the only incomplete group is removed. */ - v_readerNotifyStateChange(_this->reader, TRUE); + v__readerNotifyStateChange_nl(_this->reader, _this->alignState == V_ALIGNSTATE_COMPLETE); } } if (TEST_DURABILITY(v_proxyUserData(proxy2))) { @@ -278,49 +286,57 @@ v_entryRemoveGroup( } c_free(proxy2); } + OSPL_UNLOCK(_this->reader); c_iterFree(groups); } +struct set_completeness_arg { + v_handle groupHandle; + v_alignState alignState; +}; + static c_bool set_completeness(c_object o, c_voidp arg) { v_proxy p = v_proxy(o); c_bool found = FALSE; - v_group group = v_group(arg); - c_bool complete = v_groupCompleteGet(group); + struct set_completeness_arg *a = (struct set_completeness_arg *)arg; - if (v_handleIsEqual(p->source, v_publicHandle(v_public(group)))) { - SET_COMPLETE(p->userData, complete); + if (v_handleIsEqual(p->source, a->groupHandle)) { + SET_COMPLETE(p->userData, a->alignState); found = TRUE; } return !found; } -c_bool +v_alignState v_entryNotifyGroupStateChange( v_entry _this, - v_group group) + v_handle groupHandle, + v_alignState alignState) { - c_bool complete = v_groupCompleteGet(group); + struct set_completeness_arg arg; c_bool changed = FALSE; v_reader reader = v_reader(_this->reader); - v_readerEntrySetLock(reader); - (void)c_tableWalk(_this->groups, set_completeness, group); - if (complete != _this->complete) { - if (_this->complete) { - _this->complete = FALSE; + OSPL_LOCK(reader); + + arg.groupHandle = groupHandle; + arg.alignState = alignState; + (void)c_tableWalk(_this->groups, set_completeness, &arg); + if (alignState != _this->alignState) { + if (_this->alignState == V_ALIGNSTATE_COMPLETE) { + _this->alignState = V_ALIGNSTATE_INCOMPLETE; } else { - _this->complete = TRUE; - (void)c_tableWalk(_this->groups, get_completeness, &_this->complete); + _this->alignState = V_ALIGNSTATE_COMPLETE; + (void)c_tableWalk(_this->groups, get_completeness, &_this->alignState); } - complete = _this->complete; + alignState = _this->alignState; changed = TRUE; } - v_readerEntrySetUnlock(reader); if (changed) { - v_readerNotifyStateChange(reader, complete); - if (complete) { + v__readerNotifyStateChange_nl(reader, alignState == V_ALIGNSTATE_COMPLETE); + if (alignState == V_ALIGNSTATE_COMPLETE) { /* At this point it all goups have become complete so the reader can get * the historical data (changes). * For now the data is still pushed by the group so it is already available @@ -330,10 +346,13 @@ v_entryNotifyGroupStateChange( * solving locking issues, this operation is called by the group and requires * locking of the reader and groups to get the data, need to decide if this * can be performed synchonuous or asychronuous by a reader/subscriber/participant - * or application thread. */ - } + * or application thread. + */ + } } - return complete; + OSPL_UNLOCK(reader); + + return alignState; } struct groupExistsArg { @@ -379,3 +398,54 @@ v_entryDurableGroupCount( return _this->nvgCount; } +struct groupActionHelper { + c_action action; + c_voidp arg; +}; + +static c_bool +groupAction( + c_object o, + c_voidp arg) +{ + v_proxy p = v_proxy(o); + struct groupActionHelper *helper = (struct groupActionHelper *)arg; + v_group group; + c_bool result = FALSE; + + assert(helper); + + if (v_handleClaim(p->source, (v_object*)(&group)) == V_HANDLE_OK) { + assert(helper->action); + result = helper->action(group, helper->arg); + (void)v_handleRelease(p->source); + } + return result; +} + +c_bool +v_entryWalkGroups( + v_entry _this, + c_action action, + c_voidp actionArg) +{ + struct groupActionHelper helper; + assert(_this != NULL); + assert(C_TYPECHECK(_this,v_entry)); + + helper.action = action; + helper.arg = actionArg; + + return c_tableWalk(_this->groups, groupAction, &helper); +} + +c_iter +v_entryGetGroups( + v_entry _this) +{ + assert(_this != NULL); + assert(C_TYPECHECK(_this,v_entry)); + + return ospl_c_select(_this->groups, 0); +} + diff --git a/src/kernel/code/v_filter.c b/src/kernel/code/v_filter.c index 31deefe88..cc92156ce 100644 --- a/src/kernel/code/v_filter.c +++ b/src/kernel/code/v_filter.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,55 +22,34 @@ #include "v_topic.h" #include "c_filter.h" +#include "c_metabase.h" #include "os_report.h" #include "vortex_os.h" #include "q_helper.h" #include "v_index.h" +#define HAS_KEY (1) +#define HAS_NONKEY (2) + static q_expr resolveField( c_type type, - const c_char *name, - c_bool typeIsIndex) + const c_char *name) { - c_property property; - c_field field; c_array path; c_ulong i, length; q_list list; c_char* metaName; - c_type fieldType; - /*In case the filter is created using the instance, parameter type is already a usable type - and doesn't need to be resolved using c_metaResolve, so skip that lookup. - */ - if (typeIsIndex==TRUE) - { - fieldType = c_keep(type); - } - else - { - property = c_property(c_metaResolve(c_metaObject(type),"userData")); - fieldType = c_keep(property->type); - c_free(property); - } - if (strncmp(name, "sample.message.userData",strlen("sample.message.userData")) == 0) - { - field = c_fieldNew(fieldType,name+strlen("sample.message.userData")+1); - } - else - { - field = c_fieldNew(fieldType,name); - } - c_free(fieldType); + field = c_fieldNew(type,name); if (field == NULL) { - metaName = c_metaName(c_metaObject(fieldType)); + metaName = c_metaName(c_metaObject(type)); OS_REPORT(OS_ERROR, - "kernel::v_filter::v_filterNew:",V_RESULT_ILL_PARAM, - "Field %s not found in type %s\n", - name,metaName); + "kernel::v_filter::v_filterNew:",V_RESULT_ILL_PARAM, + "Field %s not found in type %s\n", + name,metaName); c_free(metaName); return NULL; } @@ -83,19 +63,13 @@ resolveField( c_free(metaName); } c_free(field); - if (!typeIsIndex) - { - list = q_insert(list,q_newId("userData")); - } - return q_newFnc(Q_EXPR_PROPERTY,list); } static c_bool resolveFields ( c_type type, - q_expr e, - c_bool typeIsIndex) + q_expr e) { /* search fields in result, data or info type. */ @@ -110,7 +84,7 @@ resolveFields ( switch(q_getTag(e)) { case Q_EXPR_PROPERTY: name = q_propertyName(e); - p = resolveField(type,name, typeIsIndex); + p = resolveField(type,name); os_free(name); if (p != NULL) { q_swapExpr(e,p); @@ -122,7 +96,7 @@ resolveFields ( default: /* process sub-expression, fail if a field cannot be resolved */ i=0; while ((result) && ((p = q_getPar(e,i)) != NULL)) { - result = resolveFields(type,p, typeIsIndex); + result = resolveFields(type,p); i++; } break; @@ -130,7 +104,7 @@ resolveFields ( break; case T_ID: name = q_getId(e); - p = resolveField(type,name, typeIsIndex); + p = resolveField(type,name); if (p != NULL) { q_swapExpr(e,p); q_dispose(p); @@ -144,237 +118,158 @@ resolveFields ( return result; } -v_filter -v_filterNew( - v_topic t, - q_expr e, +#define PRINT_QUERY (0) + +static c_filter +createFilter( + c_type type, + q_expr subExpr, const c_value params[]) { - v_kernel kernel; - c_type type; - v_filter filter; - - assert(C_TYPECHECK(t,v_topic)); - - filter = NULL; - kernel = v_objectKernel(t); - type = v_topicMessageType(t); - - if (t) { - if (type) { - if (!resolveFields(type,e, FALSE)) { - OS_REPORT(OS_ERROR, - "kernel::v_filter::v_filterNew",V_RESULT_ILL_PARAM, - "Failed to resolve fields in filter expression." - OS_REPORT_NL "Topic = \"%s\"", - v_topicName(t)); - } else { - filter = c_new(v_kernelType(kernel, K_FILTER)); - - if (filter) { - filter->topic = c_keep(t); - filter->predicate = c_filterNew(type,e,params); - if (filter->predicate == NULL) { - c_free(filter); - filter = NULL; - } - } else { - OS_REPORT(OS_ERROR, - "kernel::v_filter::v_filterNew",V_RESULT_INTERNAL_ERROR, - "Failed to allocate a filter." - OS_REPORT_NL "Topic = \"%s\"", - v_topicName(t)); - assert(FALSE); - } - } - } else { - OS_REPORT(OS_ERROR, - "kernel::v_filter::v_filterNew",V_RESULT_ILL_PARAM, - "Failed to resolve type for Topic \"%s\".", - v_topicName(t)); - } + c_filter filter = NULL; + q_expr progExpr; +#if PRINT_QUERY + printf("subExpr[%d]: ",i); + q_print(subExpr,12); + printf("\n"); +#endif + progExpr = F1(Q_EXPR_PROGRAM,subExpr); + if (resolveFields(type, progExpr)) { + filter = c_filterNew(type,progExpr,params); } else { - OS_REPORT(OS_ERROR, - "kernel::v_filter::v_filterNew",V_RESULT_PRECONDITION_NOT_MET, - "Pre condition failed: Topic is not specified (NULL)."); + OS_REPORT(OS_ERROR, "kernel::v_filter::v_filterNew",V_RESULT_ILL_PARAM, + "Failed to resolve fields in filter expression." OS_REPORT_NL "Type = \"%s\"", + c_metaName(c_metaObject(type))); } + q_dispose(progExpr); return filter; } v_filter -v_filterNewFromIndex( - v_index i, +v_filterNew( + c_type type, + c_array keyList, q_expr e, - const c_value params[]) + const c_value params[], + os_uint32 nrOfParams) { - v_kernel kernel; - c_type type; - v_filter filter; + c_base base; + c_type filtertype; + v_filter filter = NULL; + c_bool error = FALSE; + c_iter list; + c_ulong i,len; + q_expr expr,subExpr,keyExpr; - assert(i); - assert(C_TYPECHECK(i,v_index)); + OS_UNUSED_ARG(nrOfParams); - filter = NULL; - kernel = v_objectKernel(i); + assert(type != NULL); + assert(C_TYPECHECK(type,c_type)); - type = i->objectType; - assert(type); - if (type) { - if (!resolveFields(type,e, TRUE)) { - OS_REPORT(OS_ERROR, - "kernel::v_filter::v_filterNewFromIndex",V_RESULT_ILL_PARAM, - "Failed to resolve fields in filter expression."); - } else { - filter = c_new(v_kernelType(kernel, K_FILTER)); - - if (filter) { - filter->predicate = c_filterNew(type,e,params); - if (filter->predicate == NULL) { - c_free(filter); - filter = NULL; - OS_REPORT(OS_ERROR, - "kernel::v_filter::v_filterNewFromIndex",V_RESULT_INTERNAL_ERROR, - "Failed to allocate a filter expression."); - } - } else { - OS_REPORT(OS_ERROR, - "kernel::v_filter::v_filterNewFromIndex",V_RESULT_INTERNAL_ERROR, - "Failed to allocate a filter."); - assert(FALSE); - } - } - } else { + if (q_getLastVar(e) > nrOfParams) { OS_REPORT(OS_ERROR, - "kernel::v_filter::v_filterNewFromIndex",V_RESULT_ILL_PARAM, - "Failed to resolve type for Topic."); + "kernel::v_filter::v_filterNew",V_RESULT_ILL_PARAM, + "Requested param %%%d not supplied, only %d parameters where passed", + q_getLastVar(e), nrOfParams); + return NULL; } - - return filter; -} - -c_bool -v_filterEval(v_filter f, c_object o) -{ - assert(C_TYPECHECK(f,v_filter)); - return c_qPredEval(f->predicate, o); -} - -#define PRINT_QUERY (0) - -void v_filterSplit( - v_topic topic, - q_expr where, - const c_value params[], - c_array *instanceQ, - c_array *sampleQ, - v_index index) -{ - c_iter list; - c_ulong i,len; - q_expr subExpr,keyExpr,progExpr; - c_array sourceKeyList, indexKeyList; - q_expr copyWhere = q_exprCopy(where); - q_expr filter = q_takePar(copyWhere, 0); - v_kernel kernel = v_objectKernel(topic); - q_dispose(copyWhere); + base = c_getBase(type); + filtertype = c_resolve(base,"kernelModuleI::v_filter"); + filter = c_new(filtertype); + filter->key = NULL; + filter->nonkey = NULL; + filter->flags = 0; + c_free(filtertype); - if (filter != NULL) - { - q_prefixFieldNames(&filter,"sample.message.userData"); + expr = q_exprCopy(q_getPar(e,0)); + if (expr != NULL) { + q_prefixFieldNames(&expr,"userData"); - q_disjunctify(filter); - filter = q_removeNots(filter); - list = deOr(filter,NULL); + q_disjunctify(expr); + expr = q_removeNots(expr); + list = q_exprDeOr(expr,NULL); len = c_iterLength(list); - *instanceQ = c_arrayNew(v_kernelType(kernel, K_FILTER),len); - *sampleQ = c_arrayNew(v_kernelType(kernel, K_FILTER),len); + filter->key = c_arrayNew(c_object_t(base),len); + filter->nonkey = c_arrayNew(c_object_t(base),len); for (i=0;ikey[i] = NULL; if (keyExpr != NULL) { - translate(keyExpr, sourceKeyList, indexKeyList); - assert(keyExpr); - } - - c_free(sourceKeyList); - c_free(indexKeyList); - - if (keyExpr != NULL) { -#if PRINT_QUERY - printf("keyExpr[%d]: ",i); - q_print(keyExpr,12); - printf("\n"); -#endif - progExpr = F1(Q_EXPR_PROGRAM,keyExpr); - (*instanceQ)[i] = v_filterNewFromIndex(index, - progExpr, params); - - q_dispose(progExpr); - if ((*instanceQ)[i] == NULL) { - c_free(*instanceQ); - *instanceQ = NULL; - c_free(*sampleQ); - *sampleQ = NULL; - c_iterFree(list); - OS_REPORT(OS_CRITICAL, - "v_filterSplit failed",V_RESULT_ILL_PARAM, - "error in expression"); - return; + filter->flags |= HAS_KEY; + filter->key[i] = createFilter(type, keyExpr, params); + if (filter->key[i] == NULL) { + error = TRUE; } - } else { -#if PRINT_QUERY - printf("keyExpr[%d]: \n",i); -#endif - (*instanceQ)[i] = NULL; } + filter->nonkey[i] = NULL; if (subExpr != NULL) { -#if PRINT_QUERY - printf("subExpr[%d]: ",i); - q_print(subExpr,12); - printf("\n"); -#endif - progExpr = F1(Q_EXPR_PROGRAM,subExpr); - (*sampleQ)[i] = v_filterNew(topic, - progExpr, - params); - q_dispose(progExpr); - if ((*sampleQ)[i] == NULL) { - c_free(*instanceQ); - *instanceQ = NULL; - c_free(*sampleQ); - *sampleQ = NULL; - c_iterFree(list); - OS_REPORT(OS_CRITICAL, - "v_filterSplit failed",V_RESULT_ILL_PARAM, - "error in expression"); - return; + filter->flags |= HAS_NONKEY; + filter->nonkey[i] = createFilter(type, subExpr, params); + if (filter->nonkey[i] == NULL) { + error = TRUE; } - } else { -#if PRINT_QUERY - printf("subExpr[%d]: \n",i); -#endif - (*sampleQ)[i] = NULL; } } -#if PRINT_QUERY - printf("End v_filterSplit\n\n"); -#endif c_iterFree(list); - } else { - *instanceQ = NULL; - *sampleQ = NULL; } + if (error) { + c_free(filter); + filter = NULL; + } + return filter; +} + +static c_bool +filterEval(v_filter _this, c_object o, c_bool onlykey) +{ + os_uint32 index, length; + c_bool pass = TRUE; + + assert(C_TYPECHECK(_this,v_filter)); + + length = c_arraySize(_this->key); + for (index=0; indexnonkey[index]) { + pass = c_qPredEval(_this->nonkey[index],o); + } + if ((pass == TRUE)&&(_this->key[index])) { + pass = c_qPredEval(_this->key[index],o); + } + if (pass == TRUE) { + break; + } + } + return pass; +} + +c_bool +v_filterEvalKey(v_filter _this, c_object o) +{ + return filterEval(_this, o, TRUE); +} + +c_bool +v_filterEval(v_filter _this, c_object o) +{ + return filterEval(_this, o, FALSE); +} + +c_bool +v_filterHasKey ( + v_filter _this) +{ + return ((_this->flags & HAS_KEY) != 0); +} + +c_bool +v_filterHasNonKey ( + v_filter _this) +{ + return ((_this->flags & HAS_NONKEY) != 0); } diff --git a/src/kernel/code/v_fullCounter.c b/src/kernel/code/v_fullCounter.c index b53a1fb46..cc033efb1 100644 --- a/src/kernel/code/v_fullCounter.c +++ b/src/kernel/code/v_fullCounter.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/code/v_group.c b/src/kernel/code/v_group.c index 2f0fa5829..44d59c4e9 100644 --- a/src/kernel/code/v_group.c +++ b/src/kernel/code/v_group.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,6 +19,7 @@ * */ #include "v__group.h" +#include "v__groupStore.h" #include "v__kernel.h" #include "v_policy.h" #include "v__entry.h" @@ -26,7 +28,6 @@ #include "v_message.h" #include "v_messageQos.h" #include "v__entity.h" -#include "v_proxy.h" #include "v__observable.h" #include "v_writer.h" #include "v_reader.h" @@ -43,9 +44,14 @@ #include "v__transaction.h" #include "v__transactionGroup.h" #include "v_networkReaderEntry.h" +#include "v_time.h" +#include "v_filter.h" #include "v__builtin.h" #include "v_kernel.h" +#include "q_helper.h" #include "c_time.h" +#include "v_configuration.h" +#include "v_cfElement.h" #include "os_heap.h" #include "os_report.h" @@ -68,15 +74,20 @@ groupWrite ( v_groupInstance *instancePtr, v_networkId writingNetworkId, c_bool stream, - v_entry entry, + c_bool historicalData, v_resendScope *resendScope ); static v_result groupGetHistoricalData( + v_group g, + v_entry e); + +static void +groupGetOpenTransactions( v_group g, v_entry e, - c_bool openTransactions); + c_bool groupAdmin); v_groupSample v_groupSampleNew ( @@ -113,6 +124,25 @@ v_groupSampleNew ( return sample; } +static c_array +createInstanceKeyList( + c_type instanceType, + v_topic topic) +{ + os_uint32 i, nrOfKeys; + c_array newKeyList = NULL; + os_char keyName[16]; + + nrOfKeys = c_arraySize(v_topicMessageKeyList(topic)); + newKeyList = c_arrayNew(c_field_t(c_getBase(instanceType)), nrOfKeys); + for(i = 0; i attribute and key-type - * attribute in one class. Sometimes the key-type is a reference and - * sometimes it is not, leading to different ordering in memory of the - * two attributes some situations. As the v_groupInstanceTemplate is - * used to get a hold of the typed v_groupSample, it needs to be before the - * key in memory in all cases. The algorithm below introduces an - * extra anonymous class in between v_groupInstance and the typed - * v_groupInstance to ensure memory layout is always the same for any - * typed v_groupInstance - */ - /* Declare new class that extends from v_groupInstance. */ - tmpType = c_type(c_metaDefine(c_metaObject(base),M_CLASS)); - c_class(tmpType)->extends = c_class(baseType); - - /* Declare typed v_groupSample attribute in the anonymous class. */ - o = c_metaDeclare(c_metaObject(tmpType),"newest",M_ATTRIBUTE); - c_property(o)->type = c_keep(sampleType); - c_free(o); - - /* Finalize the anonymous class. */ - c_metaObject(tmpType)->definedIn = c_keep(base); - c_metaFinalize(c_metaObject(tmpType)); - - /* Declare the typed v_groupInstance and make it extend the anonymous - * class with the typed v_groupSample. - */ - instanceType = c_type(c_metaDefine(c_metaObject(base),M_CLASS)); - c_class(instanceType)->extends = c_class(tmpType); /* transfer refCount */ - - /* If the topic has a key, add a key attribute to the typed - * v_groupInstance. + /* Determine the name of the Topic specific GroupInstance type. + * And look for existing definition. */ - foundType = v_topicKeyType(topic); - - if ( foundType != NULL) { - o = c_metaDeclare(c_metaObject(instanceType),"key",M_ATTRIBUTE); - c_property(o)->type = foundType; /* transfer refcount */ - c_free(o); - } - /* Finalize typed v_groupInstance. */ - c_metaObject(instanceType)->definedIn = c_keep(base); - c_metaFinalize(c_metaObject(instanceType)); - #define INSTANCE_NAME "v_groupInstance>" #define INSTANCE_FORMAT "v_groupInstance>" - /* Create a name and bind type to name */ - /* Ths sizeof contains \0 */ length = sizeof(INSTANCE_NAME) + strlen(v_topicName(topic)); name = os_malloc(length); - sres = snprintf(name,length,INSTANCE_FORMAT,v_topicName(topic)); - assert(sres >= 0 && (os_size_t) sres == (length-1)); - OS_UNUSED_ARG(sres); + snprintf(name,length,INSTANCE_FORMAT,v_topicName(topic)); #undef INSTANCE_NAME #undef INSTANCE_FORMAT + foundType = c_resolve(base,name); - foundType = c_type(c_metaBind(c_metaObject(base), - name, - c_metaObject(instanceType))); + if (foundType == NULL) { + /* The type doesn't exist so declare it now. + * Lookup GroupInstance base type and extend it with type specific attributes. + */ + baseType = c_resolve(base,"kernelModuleI::v_groupInstance"); + assert(baseType != NULL); + + /* Due to the fact that our database will normalize attributes in classes, + * it is not possible to define v_groupSample attribute and key-type + * attribute in one class. Sometimes the key-type is a reference and + * sometimes it is not, leading to different ordering in memory of the + * two attributes some situations. As the v_groupInstanceTemplate is + * used to get a hold of the typed v_groupSample, it needs to be before the + * key in memory in all cases. The algorithm below introduces an + * extra anonymous class in between v_groupInstance and the typed + * v_groupInstance to ensure memory layout is always the same for any + * typed v_groupInstance + */ + /* Declare new class that extends from v_groupInstance. */ + tmpType = c_type(c_metaDefine(c_metaObject(base),M_CLASS)); + c_class(tmpType)->extends = c_class(baseType); + c_free(baseType); + + /* Declare typed v_groupSample attribute in the anonymous class. */ + o = c_metaDeclare(c_metaObject(tmpType),"newest",M_ATTRIBUTE); + c_property(o)->type = c_keep(sampleType); + c_free(o); + + /* Finalize the anonymous class. */ + c_metaObject(tmpType)->definedIn = c_keep(base); + c_metaFinalize(c_metaObject(tmpType)); + + /* Extend GroupInstance base class with a Topic specific key attribute. + * Lookup the GroupInstance key depending on GIDKEY policy as either the Topic key or Instance GID. + */ + if (gidkey) { + baseType = tmpType; + /* Declare new class that extends from previous. */ + tmpType = c_type(c_metaDefine(c_metaObject(base),M_CLASS)); + c_class(tmpType)->extends = c_class(baseType); + /* Declare the system wide unique Instance GID as key to avoid information loss. */ + o = c_metaDeclare(c_metaObject(tmpType),"gid",M_ATTRIBUTE); + c_property(o)->type = c_resolve(base,"kernelModule::v_gid"); + c_free(o); + /* Finalize the anonymous class. */ + c_metaObject(tmpType)->definedIn = c_keep(base); + c_metaFinalize(c_metaObject(tmpType)); + } + + /* Declare the typed v_groupInstance and make it extend the anonymous + * class with the typed v_groupSample. + */ + instanceType = c_type(c_metaDefine(c_metaObject(base),M_CLASS)); + c_class(instanceType)->extends = c_class(tmpType); /* transfer refCount */ + + /* Declare the key attribute of the extended GroupInstance type. */ + foundType = v_topicKeyType(topic); + if (foundType) { + o = c_metaDeclare(c_metaObject(instanceType),"key",M_ATTRIBUTE); + c_property(o)->type = foundType; // transfer refcount + foundType = NULL; + c_free(o); + } + /* Finalize typed v_groupInstance. */ + c_metaObject(instanceType)->definedIn = c_keep(base); + c_metaFinalize(c_metaObject(instanceType)); + + /* Now create the extended GroupInstance type name and register the type to the Database. + * The Bind may return an existing GroupInstance type, + * in that case the existing is returned and the newly created is destroyed. + */ + foundType = c_type(c_metaBind(c_metaObject(base), name, c_metaObject(instanceType))); + c_free(instanceType); + } os_free(name); - c_free(instanceType); return foundType; } @@ -383,7 +435,8 @@ registerInstance ( (v_reader(v_entry(proxy->entry)->reader)->qos->userKey.v.enable)); /* Now register all writer instances by forwarding the writers - * register messages. Then forward all transient data */ + * register messages. Then forward all transient data + */ regArg.proxy = proxy; regArg.instance = instance; return v_groupInstanceWalkRegistrations(instance, doRegister, ®Arg); @@ -417,17 +470,6 @@ doUnregister ( return TRUE; } - -static c_bool -instanceFree ( - c_object o, - c_voidp arg) -{ - OS_UNUSED_ARG(arg); - v_groupInstanceFree(v_groupInstance(o)); - return TRUE; -} - static v_groupAction v_groupActionNew( v_groupActionKind kind, @@ -659,8 +701,7 @@ _empty_purgeList_insert( v_groupInstanceDisconnect(instance); v_groupInstanceSetEpoch(instance, insertTime); - purgeItem = c_new(v_kernelType(v_objectKernel(group), - K_GROUPPURGEITEM)); + purgeItem = c_new(v_kernelType(v_objectKernel(group), K_GROUPPURGEITEM)); if (purgeItem) { purgeItem->instance = c_keep(instance); purgeItem->insertionTime = insertTime; @@ -674,9 +715,8 @@ _empty_purgeList_insert( group->purgeListEmptyLast = purgeItem; } } else { - OS_REPORT(OS_FATAL, - "v_group::_empty_purgeList_insert",V_RESULT_INTERNAL_ERROR, - "Failed to allocate purgeItem"); + OS_REPORT(OS_FATAL, "v_group::_empty_purgeList_insert", + V_RESULT_INTERNAL_ERROR, "Failed to allocate purgeItem"); assert(FALSE); } } @@ -687,7 +727,6 @@ _empty_purge_take( os_timeE purgeBefore) { v_groupPurgeItem purgeItem; - v_groupInstance removed; v_groupInstance instance = NULL; os_compare equality; @@ -717,13 +756,7 @@ _empty_purge_take( */ equality = os_timeECompare(purgeItem->insertionTime, instance->epoch); if (equality == OS_EQUAL) { - removed = c_remove(group->instances,instance,NULL,NULL); - /* It is allowed that the instance is already taken and - * no longer exists in the group->instances set. - */ - if (removed) { - v_groupInstanceFree(removed); - } + v_groupStoreDelete(group->store, instance); purgeItem->instance = NULL; /* Return instance, so prevent purgeItem from releasing it. */ c_free(purgeItem); purgeItem = NULL; @@ -744,6 +777,12 @@ _empty_purge_take( return instance; } +struct alignstate_order_constraint { + char require_V_ALIGNSTATE_INCOMPLETE_lt_V_ALIGNSTATE_NO_INTEREST [V_ALIGNSTATE_INCOMPLETE < V_ALIGNSTATE_NO_INTEREST]; + char require_V_ALIGNSTATE_INCOMPLETE_lt_V_ALIGNSTATE_COMPLETE [V_ALIGNSTATE_INCOMPLETE < V_ALIGNSTATE_COMPLETE]; + char non_empty_dummy_last_member[1]; +}; + static void updatePurgeList( @@ -762,57 +801,56 @@ updatePurgeList( /* Purge all instances that are expired. */ /* Precondition is that the instances in the purge list are not alive - * and empty */ + * and empty + */ exp.t = currentTime; exp.group = group; v_lifespanAdminTakeExpired(group->lifespanAdmin, currentTime, onSampleExpired, &exp); - if (group->purgeListEmpty) { - delay = kernel->retentionPeriod; - purgeBefore = os_timeESub(now, delay); - /* purgeBefore can be invalid when retentionPeriod is large and - * current elapsed time is small (node was just started). */ - if (!OS_TIMEE_ISINVALID(purgeBefore)) { - while ((instance = _empty_purge_take(group, purgeBefore)) != NULL) { - v_groupInstanceFree(instance); + /* If the group is incomplete, the emptylist should not be purged, since + * durability can be a source of out-of-order data too. If a group is not + * maintained by durability, the state will be V_ALIGNSTATE_NO_INTEREST. + * In that case flushing is OK . + */ + if(group->alignState > V_ALIGNSTATE_INCOMPLETE) { + if (group->purgeListEmpty) { + delay = kernel->retentionPeriod; + purgeBefore = os_timeESub(now, delay); + /* purgeBefore can be invalid when retentionPeriod is large and + * current elapsed time is small (node was just started). + */ + if (!OS_TIMEE_ISINVALID(purgeBefore)) { + while ((instance = _empty_purge_take(group, purgeBefore)) != NULL) { + v_groupInstanceFree(instance); + } } } - } - - if (group->disposedInstances) { - delay = v_topicQosRef(group->topic)->durabilityService.v.service_cleanup_delay; - purgeBefore = os_timeESub(now, delay); - /* purgeBefore can be invalid when service_cleanup_delay is large and - * current elapsed time is small (node was just started). */ - if (!OS_TIMEE_ISINVALID(purgeBefore)) { - while ((instance = _dispose_purgeList_take(group, purgeBefore)) != NULL) { - if (v_stateTest(instance->state, L_EMPTY | L_NOWRITERS)) { - message = v_groupInstanceCreateMessage(instance); - message->writeTime = os_timeWGet(); - forwardMessageToStreams(group, - NULL, - message, - purgeBefore, - V_GROUP_ACTION_CLEANUP_DELAY_EXPIRE); - c_free(message); - _empty_purgeList_insert(instance, now); + if (group->disposedInstances) { + delay = v_topicQosRef(group->topic)->durabilityService.v.service_cleanup_delay; + purgeBefore = os_timeESub(now, delay); + /* purgeBefore can be invalid when service_cleanup_delay is large and + * current elapsed time is small (node was just started). + */ + if (!OS_TIMEE_ISINVALID(purgeBefore)) { + while ((instance = _dispose_purgeList_take(group, purgeBefore)) != NULL) { + if (v_stateTest(instance->state, L_EMPTY | L_NOWRITERS)) { + message = v_groupInstanceCreateMessage(instance); + message->writeTime = os_timeWGet(); + forwardMessageToStreams(group, + NULL, + message, + purgeBefore, + V_GROUP_ACTION_CLEANUP_DELAY_EXPIRE); + c_free(message); + _empty_purgeList_insert(instance, now); + } + v_groupInstanceFree(instance); } - v_groupInstanceFree(instance); } } } - - if (group->transactionAdmin) { - v_transactionGroupAdmin tgroupadm; - v_transactionAdminPurgeHistory(group->transactionAdmin); - - tgroupadm = v_transactionGetGroupAdmin(group->transactionAdmin); - if (tgroupadm) { - v_transactionGroupAdminPurgeHistory(tgroupadm); - } - } } #undef MAX_PURGECOUNT @@ -834,31 +872,38 @@ v_groupEntrySetAdd ( c_type type; v_groupEntry proxy; - type = c_resolve(c_getBase(e),"kernelModuleI::v_groupEntry"); - proxy = c_new(type); - c_free(type); - if (proxy) { - proxy->connectionCache = v_groupCacheNew(v_objectKernel(e),V_CACHE_CONNECTION); - if (proxy->connectionCache) { - proxy->entry = c_keep(e); - proxy->sequenceNumber = set->lastSequenceNumber; - proxy->next = set->firstEntry; - set->firstEntry = proxy; /* Transfer refCount */ - set->lastSequenceNumber++; + proxy = set->firstEntry; + while ((proxy != NULL) && (proxy->entry != e)) { + proxy = proxy->next; + } + if (proxy == NULL) { + type = c_resolve(c_getBase(e),"kernelModuleI::v_groupEntry"); + proxy = c_new(type); + c_free(type); + if (proxy) { + proxy->connectionCache = v_groupCacheNew(v_objectKernel(e),V_CACHE_CONNECTION); + if (proxy->connectionCache) { + proxy->entry = c_keep(e); + proxy->sequenceNumber = set->lastSequenceNumber; + proxy->next = set->firstEntry; + set->firstEntry = proxy; /* Transfer refCount */ + set->lastSequenceNumber++; + } else { + c_free(proxy); + proxy = NULL; + OS_REPORT(OS_ERROR, "v_groupEntrySetAdd",V_RESULT_INTERNAL_ERROR, + "Failed to allocate reader instance cache."); + } } else { - c_free(proxy); - proxy = NULL; - OS_REPORT(OS_ERROR, - "v_groupEntrySetAdd",V_RESULT_INTERNAL_ERROR, - "Failed to allocate reader instance cache."); + OS_REPORT(OS_FATAL, "v_groupEntrySetAdd",V_RESULT_INTERNAL_ERROR, + "Failed to allocate reader proxy."); + assert(FALSE); } + c_keep(proxy); } else { - OS_REPORT(OS_FATAL, - "v_groupEntrySetAdd",V_RESULT_INTERNAL_ERROR, - "Failed to allocate reader proxy."); - assert(FALSE); + proxy = NULL; } - return c_keep(proxy); + return proxy; } static v_groupEntry @@ -957,7 +1002,7 @@ createInstanceKeyExpr ( c_array keyList; assert(C_TYPECHECK(topic,v_topic)); - keyList = c_keep(v_topicMessageKeyList(topic)); + keyList = v_topicMessageKeyList(topic); nrOfKeys = c_arraySize(keyList); if (nrOfKeys>0) { totalSize = nrOfKeys * strlen("key.field0,"); @@ -980,12 +1025,90 @@ createInstanceKeyExpr ( return keyExpr; } -static void +/* This operation will iterate over all configured filters and apply all matching filters to the group. + * Note that each filter that is applied will override a previous filter. + * This effectively means that in case of multiple matching filters only the first filter that + * is specified in the configuration is applied (filters are stored in reverse order of declaration). + */ +static v_result +lookup_filter( + v_group group) +{ + c_iter iter, iter2, iter3; + v_configuration config; + v_cfElement root = NULL; + v_cfElement filter_element, group_element; + v_cfNode data; + c_value value, filter_expr; + v_result result = V_RESULT_OK; + + config = v_getConfiguration(v_objectKernel(group)); + if (config) { + root = v_configurationGetRoot(config); + } + if (root) { + iter = v_cfElementXPath(root, "Domain/Filters/Filter"); + + while(result == V_RESULT_OK && (filter_element = v_cfElement(c_iterTakeFirst(iter))) != NULL) { + filter_expr = v_cfElementAttributeValue(filter_element, "content"); + assert(filter_expr.kind == V_STRING); + iter2 = v_cfElementXPath(filter_element, "PartitionTopic"); + group_element = v_cfElement(c_iterTakeFirst(iter2)); + while (result == V_RESULT_OK && group_element) { + iter3 = v_cfElementGetChildren(group_element); + if (c_iterLength(iter3) != 0) { + data = v_cfNode(c_iterTakeFirst(iter3)); + if (v_cfNodeKind(data) == V_CFDATA) { + value = v_cfDataValue(v_cfData(data)); + if (value.kind == V_STRING) { + char *tname, *pname; + c_value p,r; + tname = v_topicName(group->topic); + pname = v_partitionName(group->partition); + /* Note that the c_value var p is a heap variable instead of a database object. + * The c_value type is intentionally misused in this manner for the sake of + * using the c_valueStringMatch function. + * Therefore not pass p to any operation that alter this variable. + */ + p.kind = V_STRING; + p.is.String = os_malloc(strlen(pname) + strlen(tname) + 2); + os_sprintf(p.is.String, "%s.%s", pname, tname); + r = c_valueStringMatch (value, p); + os_free(p.is.String); + if (r.is.Boolean) { + q_expr condition = q_parse(filter_expr.is.String); + assert(condition); + result = v_groupSetFilter(group, condition, NULL, 0); + q_dispose(condition); + if (result != V_RESULT_OK) { + OS_REPORT(OS_ERROR, + "v_groupSetFilter",V_RESULT_INTERNAL_ERROR, + "Failed to to create a the Domain filter <%s> for topic %s.", + filter_expr.is.String, tname); + result = V_RESULT_OK; + } + } + } + } + } + c_iterFree(iter3); + group_element = v_cfElement(c_iterTakeFirst(iter2)); + } /* while */ + c_iterFree(iter2); + } + c_iterFree(iter); + c_free(root); + } + return result; +} + +static v_result v_groupInit( v_group group, v_partition partition, v_topic topic, - c_long id) + c_long id, + c_bool gidkey) { char *groupName; os_size_t groupNameLen; @@ -996,7 +1119,9 @@ v_groupInit( c_base base; c_type type; v_partitionPolicyI partqos; + v_result result = V_RESULT_OK; + assert(C_TYPECHECK(group, v_group)); kernel = v_objectKernel(group); base = c_getBase(kernel); @@ -1016,73 +1141,91 @@ v_groupInit( group->lastDisposeAllTime = OS_TIMEW_ZERO; group->partition = c_keep(partition); group->topic = c_keep(topic); + group->filter = NULL; group->sequenceNumber = id; group->routingEnabled = FALSE; - group->lifespanAdmin = v_lifespanAdminNew(kernel); + result = lookup_filter(group); + if (result == V_RESULT_OK) { + group->lifespanAdmin = v_lifespanAdminNew(kernel); - group->purgeListEmpty = NULL; - group->purgeListEmptyLast = NULL; + group->purgeListEmpty = NULL; + group->purgeListEmptyLast = NULL; - v_groupEntrySetInit(&group->topicEntrySet); - v_groupEntrySetInit(&group->networkEntrySet); - v_groupEntrySetInit(&group->routedEntrySet); - v_groupEntrySetInit(&group->variantEntrySet); + v_groupEntrySetInit(&group->topicEntrySet); + v_groupEntrySetInit(&group->networkEntrySet); + v_groupEntrySetInit(&group->routedEntrySet); + v_groupEntrySetInit(&group->variantEntrySet); - type = c_resolve(base,"kernelModuleI::v_groupStream"); - group->streams = c_setNew(type); + type = c_resolve(base,"kernelModuleI::v_groupStream"); + group->streams = c_setNew(type); - type = c_resolve(base, "c_string"); - assert(type); - group->attachedServices = c_setNew(type); - group->notInterestedServices = c_setNew(type); + type = c_resolve(base, "c_string"); + assert(type); + group->attachedServices = c_setNew(type); + group->notInterestedServices = c_setNew(type); - qos = v_topicQosRef(topic); - infWait = OS_DURATION_ISINFINITE(qos->reliability.v.max_blocking_time); + qos = v_topicQosRef(topic); + infWait = OS_DURATION_ISINFINITE(qos->reliability.v.max_blocking_time); - group->sampleType = createGroupSampleType(topic); - group->instanceType = createGroupInstanceType(topic, group->sampleType); + group->gidkey = gidkey; + group->sampleType = createGroupSampleType(topic); + group->instanceType = createGroupInstanceType(topic, group->sampleType, gidkey); + group->keyList = createInstanceKeyList(group->instanceType, topic); - keyExpr = createInstanceKeyExpr(topic); - group->instances = c_tableNew(group->instanceType,keyExpr); - os_free(keyExpr); - - group->resourceSampleCount = 0; - group->infWait = infWait; - group->disposedInstances = NULL; - group->disposedInstancesLast = NULL; - if(qos->durability.v.kind == V_DURABILITY_VOLATILE) { - group->complete = TRUE; /* no alignment necessary.*/ - } else { - group->complete = FALSE; /* until aligned */ - } - c_mutexInit(c_getBase(group), &group->mutex); + /* Create the Group Instance table depending on GIDKEY policy with key is either + * the Topic key which merges data from multiple publishers or + * Instance GID as key which avoids merge conflicts of historical data. + */ + if (gidkey) { + OS_REPORT_NOW(OS_INFO, "TRANSIENT DATA", 0, 0, "GIDKey policy applicable on Group '%s.%s'", + v_partitionName(partition), v_topicName(topic)); + group->store = v_groupStoreNew(group, + "gid.systemId,gid.localId,gid.serial", + v_topicMessageKeyList(topic)); + } else { + keyExpr = createInstanceKeyExpr(topic); + group->store = v_groupStoreNew(group, keyExpr, v_topicMessageKeyList(topic)); + os_free(keyExpr); + } - group->cachedInstance = NULL; - group->cachedRegMsg = NULL; - /* ES, dds1576: For each new group, determine the access mode for the - * partition involved in this group. - */ - partqos.v = v_partitionName (partition); - group->partitionAccessMode = v_kernelPartitionAccessMode(kernel, partqos); + group->resourceSampleCount = 0; + group->infWait = infWait; + group->disposedInstances = NULL; + group->disposedInstancesLast = NULL; + if(qos->durability.v.kind == V_DURABILITY_VOLATILE || !v_kernelGetDurabilitySupport(kernel)) { + group->alignState = V_ALIGNSTATE_COMPLETE; /* no alignment necessary. */ + } else { + group->alignState = V_ALIGNSTATE_INCOMPLETE; /* until aligned */ + } - type = c_resolve(base,"kernelModuleI::v_groupwriterAdministration"); - group->writerAdministration = c_tableNew(type, "gid.systemId,gid.localId,gid.serial"); - /* The transactionAdmin is created lazy when required. */ - group->transactionAdmin = NULL; - group->onRequest = FALSE; - group->pristine = TRUE; /* becomes false as soon a writer connects. */ - c_free(type); + /* ES, dds1576: For each new group, determine the access mode for the + * partition involved in this group. + */ + partqos.v = v_partitionName (partition); + group->partitionAccessMode = v_kernelPartitionAccessMode(kernel, partqos); + + type = c_resolve(base,"kernelModuleI::v_groupwriterAdministration"); + group->writerAdministration = c_tableNew(type, "gid.systemId,gid.localId,gid.serial"); + /* The transactionAdmin is created lazy when required. */ + group->transactionAdmin = NULL; + group->onRequest = FALSE; + group->pristine = TRUE; /* becomes false as soon a writer connects. */ + c_free(type); + } + return result; } v_group v_groupNew( v_partition partition, v_topic topic, - c_long id) + c_long id, + c_bool gidkey) { v_kernel kernel; v_group group; + v_result result = V_RESULT_OK; assert(partition != NULL); assert(C_TYPECHECK(partition,v_partition)); @@ -1091,8 +1234,11 @@ v_groupNew( kernel = v_objectKernel(topic); group = v_group(v_objectNew(kernel,K_GROUP)); - v_groupInit(group, partition, topic, id); - + result = v_groupInit(group, partition, topic, id, gidkey); + if (result != V_RESULT_OK) { + c_free(group); + group = NULL; + } return group; } @@ -1113,7 +1259,7 @@ v_groupDeinit( assert(group != NULL); assert(C_TYPECHECK(group,v_group)); - c_tableWalk(group->instances,instanceFree,NULL); + v_groupStoreDeinit(group->store); } struct findServiceHelper { @@ -1156,7 +1302,7 @@ v_groupRemoveAwareness ( helper.search = serviceName; helper.serviceName = NULL; - c_mutexLock(&_this->mutex); + OSPL_LOCK(_this); (void)c_walk(_this->attachedServices, findService, &helper); if(helper.found){ @@ -1174,7 +1320,7 @@ v_groupRemoveAwareness ( helper.serviceName = NULL; } } - c_mutexUnlock(&_this->mutex); + OSPL_UNLOCK(_this); } } @@ -1195,13 +1341,13 @@ v_groupNotifyAwareness ( base = c_getBase(_this); name = c_stringNew(base, serviceName); - c_mutexLock(&_this->mutex); + OSPL_LOCK(_this); if(interested){ found = ospl_c_insert(_this->attachedServices, name); } else { found = ospl_c_insert(_this->notInterestedServices, name); } - c_mutexUnlock(&_this->mutex); + OSPL_UNLOCK(_this); if(found){ c_free(name); @@ -1227,7 +1373,7 @@ v_groupServiceGetAttachState ( helper.search = serviceName; helper.serviceName = NULL; - c_mutexLock(&_this->mutex); + OSPL_LOCK(_this); (void)c_walk(_this->attachedServices, findService, &helper); if(helper.found){ @@ -1241,62 +1387,13 @@ v_groupServiceGetAttachState ( state = V_GROUP_ATTACH_STATE_UNKNOWN; } } - c_mutexUnlock(&_this->mutex); + OSPL_UNLOCK(_this); } else { state = V_GROUP_ATTACH_STATE_UNKNOWN; } return state; } -void -v_groupAddEntry( - v_group g, - v_entry e) -{ - v_groupEntry proxy; - - assert(g != NULL); - assert(C_TYPECHECK(g,v_group)); - assert(e != NULL); - assert(C_TYPECHECK(e,v_entry)); - - c_mutexLock(&g->mutex); - - updatePurgeList(g, os_timeEGet()); - /* doubly linked connection */ - if (v_entryAddGroup(e, g)) - { - if (v_objectKind(e) == K_NETWORKREADERENTRY) { - c_free(v_groupEntrySetAdd(&g->networkEntrySet,e)); - if(v_networkReaderEntryIsRouting(v_networkReaderEntry(e))){ - c_free(v_groupEntrySetAdd(&g->routedEntrySet,e)); - } - } else if (v_reader(v_entry(e)->reader)->qos->userKey.v.enable) { - proxy = v_groupEntrySetAdd(&g->variantEntrySet,e); - if (proxy) { - c_free(proxy); - if (v_reader(v_entry(e)->reader)->qos->durability.v.kind != V_DURABILITY_VOLATILE) { - (void)groupGetHistoricalData(g,e,TRUE); - } - } - } else { - proxy = v_groupEntrySetAdd(&g->topicEntrySet,e); - if (proxy) { - c_tableWalk(g->instances,registerInstance,proxy); - c_free(proxy); - if (v_reader(v_entry(e)->reader)->qos->durability.v.kind != V_DURABILITY_VOLATILE) { - (void)groupGetHistoricalData(g,e,TRUE); - } - } else { - OS_REPORT(OS_ERROR, - "v_groupAddEntry",V_RESULT_INTERNAL_ERROR, - " Failed to register instance in topicEntrySet"); - } - } - } - c_mutexUnlock(&g->mutex); -} - void v_groupRemoveEntry( v_group g, @@ -1310,7 +1407,7 @@ v_groupRemoveEntry( assert(e != NULL); assert(C_TYPECHECK(e,v_entry)); - c_mutexLock(&g->mutex); + OSPL_LOCK(g); if (v_objectKind(e) == K_NETWORKREADERENTRY) { proxy = v_groupEntrySetRemove(&g->networkEntrySet,e); @@ -1323,31 +1420,69 @@ v_groupRemoveEntry( proxy = v_groupEntrySetRemove(&g->variantEntrySet,e); } else { proxy = v_groupEntrySetRemove(&g->topicEntrySet,e); - if ((proxy != NULL) && !(v_observerEventMask(v_entry(e)->reader) & V_EVENT_PREPARE_DELETE)) { + if ((proxy != NULL) && !(v_observerGetEventMask(v_entry(e)->reader) & V_EVENT_PREPARE_DELETE)) { timestamp = os_timeWGet(); (void)v_groupCacheWalk(proxy->connectionCache, doUnregister, ×tamp); } } v_groupEntryFree(proxy); - v_entryRemoveGroup(e, g); - c_mutexUnlock(&g->mutex); + OSPL_UNLOCK(g); } -v_entry -v_groupLookupEntry( +c_bool +v_groupAddEntry( v_group g, - v_reader r) + v_entry e) { + c_bool connected = TRUE; + v_groupEntry proxy; + c_bool groupAdmin = FALSE; + assert(g != NULL); assert(C_TYPECHECK(g,v_group)); - assert(r != NULL); - assert(C_TYPECHECK(r,v_reader)); + assert(e != NULL); + assert(C_TYPECHECK(e,v_entry)); - OS_UNUSED_ARG(g); - OS_UNUSED_ARG(r); + OSPL_LOCK(g); - assert(FALSE); /* To be implemented. */ - return NULL; + updatePurgeList(g, os_timeEGet()); + /* doubly linked connection */ + if (v_objectKind(e) == K_NETWORKREADERENTRY) { + c_free(v_groupEntrySetAdd(&g->networkEntrySet,e)); + if(v_networkReaderEntryIsRouting(v_networkReaderEntry(e))){ + c_free(v_groupEntrySetAdd(&g->routedEntrySet,e)); + } + } else if (g->partitionAccessMode == V_ACCESS_MODE_READ_WRITE || + g->partitionAccessMode == V_ACCESS_MODE_READ) + { + if (v_reader(v_entry(e)->reader)->qos->userKey.v.enable) { + proxy = v_groupEntrySetAdd(&g->variantEntrySet,e); + if (proxy) { + c_free(proxy); + if (v_reader(v_entry(e)->reader)->qos->durability.v.kind != V_DURABILITY_VOLATILE) { + (void)groupGetHistoricalData(g,e); + groupAdmin = TRUE; + } + (void)groupGetOpenTransactions(g,e,groupAdmin); + } + } else { + proxy = v_groupEntrySetAdd(&g->topicEntrySet,e); + if (proxy) { + /* For all instances in the store write all registrations to the proxy. */ + v_groupStoreWalk(g->store, registerInstance, proxy); + c_free(proxy); + if (v_reader(v_entry(e)->reader)->qos->durability.v.kind != V_DURABILITY_VOLATILE) { + (void)groupGetHistoricalData(g,e); + groupAdmin = TRUE; + } + (void)groupGetOpenTransactions(g,e,groupAdmin); + } + } + } else { + connected = FALSE; + } + OSPL_UNLOCK(g); + return connected; } c_bool @@ -1365,13 +1500,13 @@ v_groupAddStream( result = FALSE; - c_mutexLock(&group->mutex); + OSPL_LOCK(group); found = v_groupStream(c_setInsert(group->streams,stream)); if (found == stream) { result = TRUE; } - c_mutexUnlock(&group->mutex); + OSPL_UNLOCK(group); return result; } @@ -1390,13 +1525,13 @@ v_groupRemoveStream( assert(C_TYPECHECK(stream,v_groupStream)); result = FALSE; - c_mutexLock(&group->mutex); + OSPL_LOCK(group); found = v_groupStream(c_remove(group->streams,stream, NULL, NULL)); if (found == stream) { result = TRUE; } - c_mutexUnlock(&group->mutex); + OSPL_UNLOCK(group); return result; } @@ -1411,10 +1546,10 @@ v_groupSetRoutingEnabled( assert(group != NULL); assert(C_TYPECHECK(group,v_group)); - c_mutexLock(&group->mutex); + OSPL_LOCK(group); result = group->routingEnabled; group->routingEnabled = routingEnabled; - c_mutexUnlock(&group->mutex); + OSPL_UNLOCK(group); return result; } @@ -1602,8 +1737,7 @@ flushInstanceRegistrations( if(entry && propagateTheMessage) { v_message message = v_groupInstanceCreateMessage(grInst); - if (message) - { + if (message) { message->writerGID = registration->writerGID; message->qos = c_keep(registration->qos); message->writeTime = registration->writeTime; @@ -1617,11 +1751,8 @@ flushInstanceRegistrations( /* write the sample to other node(s) */ v_entryWrite(entry, message, V_NETWORKID_LOCAL, FALSE, NULL, V_CONTEXT_GETHISTORY); c_free(message); - } - else - { - OS_REPORT(OS_ERROR, - "v_group",V_RESULT_INTERNAL_ERROR, + } else { + OS_REPORT(OS_ERROR, "v_group",V_RESULT_INTERNAL_ERROR, "flushInstanceRegistrations(registration=0x%"PA_PRIxADDR", arg=0x%"PA_PRIxADDR")\n" " Failed to allocate an unregister message.", (os_address)registration, (os_address)arg); @@ -1647,20 +1778,23 @@ flushInstance ( /* For each registration that doesn't have a sample, insert an explicit registration * message. When the group contains unregister messages for instances that are still * alive, the explicit registrations will make sure that when interpreting the result of - * a flush the final registration-count will be correct. */ + * a flush the final registration-count will be correct. + */ flushInstanceRegistrations(grInst, groupFlushArg); result = v_groupInstanceWalkSamples(grInst,doFlush,arg); - if(grInst->oldest) { + if (grInst->oldest) { if(result == TRUE){ groupFlushArg->grInst = grInst; - v_groupInstanceWalkUnregisterMessages(v_groupInstance(o), - doUnregisterFlush, arg); + v_groupInstanceWalkUnregisterMessages(v_groupInstance(o), doUnregisterFlush, arg); } - }else { - /* TODO: This will effectively stop forwarding of unregister-only messages when there is no data in a group. This is a situation that should not occur! At the moment it still does - * however, for reasons unknown. This fix (if grInst->oldest) is harmless and is a quick fix for customers. When the real cause is found, this comment should be replaced with - * an assert. */ + } else { + /* TODO: This will effectively stop forwarding of unregister-only messages when there + * is no data in a group. This is a situation that should not occur! + * At the moment it still does however, for reasons unknown. + * This fix (if grInst->oldest) is harmless and is a quick fix for customers. + * When the real cause is found, this comment should be replaced with an assert. + */ } return result; } @@ -1711,8 +1845,8 @@ v_groupFlushAction( groupFlushArg.grInst = NULL; groupFlushArg.writeResult = V_WRITE_UNDEFINED; - c_mutexLock(&_this->mutex); - (void)c_tableWalk(_this->instances, flushInstance, &groupFlushArg); + OSPL_LOCK(_this); + v_groupStoreWalk(_this->store, flushInstance, &groupFlushArg); if (_this->transactionAdmin) { v_transactionGroupAdmin tgroupadm; v_transactionAdminWalkTransactions(_this->transactionAdmin, flushTransaction, &groupFlushArg); @@ -1723,7 +1857,7 @@ v_groupFlushAction( } } - c_mutexUnlock(&_this->mutex); + OSPL_UNLOCK(_this); } C_STRUCT(v_entryRegisterArg) { @@ -1758,7 +1892,6 @@ C_STRUCT(v_nwEntryWriteArg) { v_networkId networkId; c_bool groupRoutingEnabled; v_writeResult writeResult; - v_entry entry; }; C_CLASS(v_nwEntryWriteArg); @@ -1778,7 +1911,7 @@ handleSampleLost( v_writerAdmin wrAdmin = (v_writerAdmin)arg; v_reader reader = v_entryReader(proxy->entry); - /* Filter-out all QoS-incompatible messages. */ + /* Only notify all QoS-compatible readers. */ if (v_messageQos_isReaderCompatible(wrAdmin->message->qos,reader)) { v_dataReaderNotifySampleLost(v_dataReader(reader),wrAdmin->missedMessages); } @@ -1807,10 +1940,10 @@ entryRegister( writeArg->writeResult = result; } else { /* Write is successfull, however instance may not point to the - reader instance, due to the following reasons: - - message qos was incompatible with reader qos - - the reader has a filter which rejects the message. - */ + * reader instance, due to the following reasons: + * - message qos was incompatible with reader qos + * - the reader has a filter which rejects the message. + */ if (instance != NULL) { /* first check whether instance is already cached */ unknownArg.instance = instance; @@ -1846,32 +1979,26 @@ nwEntryWrite( c_voidp arg) { v_nwEntryWriteArg writeArg = (v_nwEntryWriteArg)arg; + v_writeResult result; - if ((writeArg->entry) && (writeArg->entry != proxy->entry)) { - /* The message was not addressed to this network. - */ - } else { - v_writeResult result; - - result = v_networkReaderEntryWrite( - v_networkReaderEntry(proxy->entry), - writeArg->message, - writeArg->networkId, - writeArg->groupRoutingEnabled); - - /* This method is used in a walk method and visits all network - * interfaces. The callee expects the writeResult to indecate if - * a reject has occured so the result will only be set if a message - * is rejected. - */ - if (result == V_WRITE_REJECTED) { - writeArg->writeResult = result; - } else if (result != V_WRITE_SUCCESS) { - OS_REPORT(OS_CRITICAL, - "v_writerInstance::nwEntryWrite",result, - "Internal error (%d) occured", - result); - } + result = v_networkReaderEntryWrite( + v_networkReaderEntry(proxy->entry), + writeArg->message, + writeArg->networkId, + writeArg->groupRoutingEnabled); + + /* This method is used in a walk method and visits all network + * interfaces. The callee expects the writeResult to indecate if + * a reject has occured so the result will only be set if a message + * is rejected. + */ + if (result == V_WRITE_REJECTED) { + writeArg->writeResult = result; + } else if (result != V_WRITE_SUCCESS) { + OS_REPORT(OS_CRITICAL, + "v_writerInstance::nwEntryWrite",result, + "Internal error (%d) occured", + result); } return TRUE; } @@ -1885,18 +2012,12 @@ entryWrite( v_entryWriteArg writeArg = (v_entryWriteArg)arg; v_instance instance = NULL; - if ((writeArg->entry) && (writeArg->entry != proxy->entry)) { - /* The message was not addressed to this entry. - */ - result = V_WRITE_SUCCESS; - } else { - result = v_entryWrite(proxy->entry, - writeArg->message, - writeArg->networkId, - writeArg->groupRoutingEnabled, - &instance, - V_CONTEXT_GROUPWRITE); - } + result = v_entryWrite(proxy->entry, + writeArg->message, + writeArg->networkId, + writeArg->groupRoutingEnabled, + &instance, + V_CONTEXT_GROUPWRITE); /* This method is used in a walk method and visits all network * interfaces. The callee expects the writeResult to indicate if @@ -1959,26 +2080,24 @@ instanceWrite( assert(item->registrationCount <= instance->liveliness); compatible = v_messageQos_isReaderCompatible( - writeArg->message->qos, - v_reader(v_instance(instance)->entity)); - - result = v_dataReaderInstanceWrite(instance, writeArg->message); - /* It is possible at this point that the instance has been freed by a - * reader take. So, we shouldn't access it anymore. */ - - if (result == V_WRITE_SUCCESS) { - if (v_messageStateTest(writeArg->message,L_UNREGISTER)) { - if (compatible) { + writeArg->message->qos, v_reader(v_instance(instance)->entity)); + if (compatible) { + result = v_dataReaderInstanceWrite(instance, writeArg->message); + /* It is possible at this point that the instance has been + freed by a reader take. So, don't access it anymore. + */ + if (result == V_WRITE_SUCCESS) { + if (v_messageStateTest(writeArg->message,L_UNREGISTER)) { item->registrationCount--; } - } - } else { - writeArg->writeResult = result; - /* only increase pendingResends, - * when not called from instanceResend. - */ - if (!writeArg->resend) { - item->pendingResends++; + } else { + writeArg->writeResult = result; + /* Increase pendingResends only when not called from + * instanceResend. + */ + if (!writeArg->resend) { + item->pendingResends++; + } } } } else { @@ -1996,8 +2115,7 @@ instanceWrite( static c_bool groupReadyToAcceptSample ( - v_group group - ) + v_group group) { v_kernel kernel = v_objectKernel(group); @@ -2039,8 +2157,7 @@ static v_writeResult forwardMessageToNetwork ( v_group group, v_message message, - v_networkId writingNetworkId, - v_entry entry) + v_networkId writingNetworkId) { C_STRUCT(v_nwEntryWriteArg) writeArg; writeArg.writeResult = V_WRITE_SUCCESS; @@ -2050,7 +2167,6 @@ forwardMessageToNetwork ( writeArg.message = message; writeArg.networkId = writingNetworkId; - writeArg.entry = entry; writeArg.groupRoutingEnabled = group->routingEnabled; if (writingNetworkId == V_NETWORKID_LOCAL) { @@ -2156,7 +2272,6 @@ forwardMessage ( v_groupInstance instance, v_message message, v_networkId writingNetworkId, - v_entry entry, c_bool bypassCache, v_resendScope *resendScope) { @@ -2186,7 +2301,6 @@ forwardMessage ( writeArg.networkId = writingNetworkId; writeArg.groupRoutingEnabled = group->routingEnabled; - writeArg.entry = entry; /* If the sample has no valid content, replace the typed sample * with an untyped sample to save storage space, but only @@ -2209,14 +2323,12 @@ forwardMessage ( } if (writeArg.writeResult == V_WRITE_SUCCESS) { - if(!entry && !bypassCache){ + if(!bypassCache){ instanceArg.writeResult = V_WRITE_SUCCESS; instanceArg.deadCacheItems = NULL; instanceArg.resend = FALSE; - /* No connection updates, so forward the messages via the cached - instances. - */ + /* No connection updates, so forward the messages via the cached instances. */ (void)v_groupCacheWalk(instance->targetCache, instanceWrite, &instanceArg); if (instanceArg.deadCacheItems) { item = v_groupCacheItem(c_iterTakeFirst(instanceArg.deadCacheItems)); @@ -2228,7 +2340,6 @@ forwardMessage ( } writeArg.writeResult = instanceArg.writeResult; } else { - /*special case to handle writing to one specific entry*/ (void)v_groupEntrySetWalk(&group->topicEntrySet, entryWrite, &writeArg); } @@ -2257,41 +2368,6 @@ forwardMessage ( return writeArg.writeResult; } -/* -c_long -v_groupSampleCount ( - v_group group) -{ - c_long count; - assert(C_TYPECHECK(group,v_group)); - c_mutexLock(&group->mutex); - count = v_sampleListLength(&group->sampleList); - c_mutexUnlock(&group->mutex); - return count; -} -*/ - - -static c_bool -markGroupInstance(c_object o, c_voidp arg) -{ - v_groupInstance instance = v_groupInstance(o); - c_ulong *flags = (c_ulong *)arg; - - v_stateSet(instance->state, *flags); - return TRUE; -} - -static c_bool -unmarkGroupInstance(c_object o, c_voidp arg) -{ - v_groupInstance instance = v_groupInstance(o); - c_ulong *flags = (c_ulong *)arg; - - v_stateClear(instance->state, *flags); - return TRUE; -} - /* Set the specified flags for all DataReader instance states associated * with the specified group. */ @@ -2305,14 +2381,14 @@ v_groupMarkGroupInstanceStates ( assert(C_TYPECHECK(group,v_group)); if (flags != 0) { - c_mutexLock(&group->mutex); + OSPL_LOCK(group); qos = v_topicQosRef(group->topic); if (qos->durability.v.kind != V_DURABILITY_VOLATILE) { - (void)c_tableWalk(group->instances, markGroupInstance, &flags); + v_groupStoreMarkGroupInstanceStates(group->store, flags); } - c_mutexUnlock(&group->mutex); + OSPL_UNLOCK(group); } } @@ -2329,14 +2405,14 @@ v_groupUnmarkGroupInstanceStates ( assert(C_TYPECHECK(group,v_group)); if (flags != 0) { - c_mutexLock(&group->mutex); + OSPL_LOCK(group); qos = v_topicQosRef(group->topic); if (qos->durability.v.kind != V_DURABILITY_VOLATILE) { - (void)c_tableWalk(group->instances, unmarkGroupInstance, &flags); + v_groupStoreUnmarkGroupInstanceStates(group->store, flags); } - c_mutexUnlock(&group->mutex); + OSPL_UNLOCK(group); } } @@ -2351,12 +2427,61 @@ v_groupUnmarkReaderInstanceStates ( assert(C_TYPECHECK(group,v_group)); if (flags != 0) { - c_mutexLock(&group->mutex); + OSPL_LOCK(group); v_groupEntrySetUnmarkReaderInstanceStates( &group->topicEntrySet, flags ); - c_mutexUnlock(&group->mutex); + OSPL_UNLOCK(group); + } +} + +static void forwardToStreams( + v_groupInstance instance, + v_message message) +{ + v_groupActionKind actionKind; + os_duration delay; + v_topicQos qos; + v_group group = v_group(instance->group); + os_timeE now = os_timeEGet(); + + /* if the instance state is NOWRITERS and DISPOSED then and only + * then add the instance to the purge admin. + */ + qos = v_topicQosRef(v_group(instance->group)->topic); + if (v_groupInstanceStateTest(instance, L_DISPOSED | L_NOWRITERS)) { + delay = qos->durabilityService.v.service_cleanup_delay; + if (OS_DURATION_ISZERO(delay)) { + /* cleanup_delay is zero, remove all samples and insert instance in emptyList. */ + if (!v_groupInstanceStateTest(instance,L_EMPTY)) { + v_groupInstancePurge(instance); + } + assert(v_groupInstanceStateTest(instance,L_EMPTY)); + _empty_purgeList_insert(instance, now); + actionKind = V_GROUP_ACTION_CLEANUP_DELAY_EXPIRE; + } else if (!OS_DURATION_ISINFINITE(delay)) { + /* cleanup_delay is finite, insert instance in disposed list. */ + _dispose_purgeList_insert(instance, now); + actionKind = V_GROUP_ACTION_UNREGISTER; + } else { + /* If service_cleanup_delay is infinite, do nothing. */ + actionKind = V_GROUP_ACTION_UNREGISTER; + } + } else if (v_messageStateTest(message,L_WRITE)) { + actionKind = V_GROUP_ACTION_WRITE; + } else if (v_messageStateTest(message,L_DISPOSED)) { + actionKind = V_GROUP_ACTION_DISPOSE; + } else if (v_messageStateTest(message,L_UNREGISTER)) { + actionKind = V_GROUP_ACTION_UNREGISTER; + } else if (v_messageStateTest(message,L_REGISTER)) { + actionKind = V_GROUP_ACTION_REGISTER; + } else { + actionKind = V_GROUP_ACTION_WRITE; } + /* Only forward to stream when sample is inserted in groupInstance and + * when streaming is required + */ + forwardMessageToStreams(group, instance, message, now, actionKind); } static c_bool @@ -2368,9 +2493,11 @@ disposeGroupInstance ( messageActionArg a = (messageActionArg) arg; if ((a->condition == NULL) || ((a->condition)(instance, a->arg))) { - a->result = v_groupInstanceInsert(instance, a->message, FALSE, NULL, TRUE); - /* Make sure that a dispose that is processed correctly without error is treated as success. */ - if (a->result == V_WRITE_DUPLICATE || a->result == V_WRITE_SUCCESS_NOT_STORED) { + a->result = v_groupInstanceInsert(instance, a->message); + if (a->result == V_WRITE_SUCCESS) { + forwardToStreams(instance, a->message); + } else if (a->result == V_WRITE_DUPLICATE || a->result == V_WRITE_SUCCESS_NOT_STORED) { + /* Make sure that a dispose that is processed correctly without error is treated as success. */ a->result = V_WRITE_SUCCESS; } } @@ -2393,15 +2520,19 @@ disposeMarkedInstance( registerMessage->writerGID = disposeMsg->writerGID; registerMessage->writeTime = disposeMsg->writeTime; registerMessage->qos = c_keep(disposeMsg->qos); - result = groupWrite(group, registerMessage, NULL, V_NETWORKID_ANY, TRUE, NULL, &resendScope); + result = groupWrite(group, registerMessage, NULL, V_NETWORKID_ANY, TRUE, FALSE, &resendScope); c_free(registerMessage); if (result == V_WRITE_REGISTERED || result == V_WRITE_SUCCESS) { - result = groupWrite(group, disposeMsg, &instance, V_NETWORKID_ANY, TRUE, NULL, &resendScope); + result = groupWrite(group, disposeMsg, &instance, V_NETWORKID_ANY, TRUE, FALSE, &resendScope); if (result != V_WRITE_SUCCESS) { - OS_REPORT(OS_ERROR, "v_group::disposeMarkedInstances", result, "During CATCHUP failed to dispose instance that no longer exists on master."); + OS_REPORT(OS_ERROR, "v_group::disposeMarkedInstances", result, + "During CATCHUP failed to dispose instance that no longer exists on master."); } + } else if (result == V_WRITE_SUCCESS_NOT_STORED) { + result = V_WRITE_SUCCESS; } else { - OS_REPORT(OS_ERROR, "v_group::disposeMarkedInstances", result, "During CATCHUP failed to re-register instance that no longer exists on master."); + OS_REPORT(OS_ERROR, "v_group::disposeMarkedInstances", result, + "During CATCHUP failed to re-register instance that no longer exists on master."); } } else { result = V_WRITE_OUT_OF_RESOURCES; @@ -2412,8 +2543,8 @@ disposeMarkedInstance( v_writeResult v_groupSweepMarkedInstances( - v_group group, - os_timeW timestamp) + v_group group, + os_timeW timestamp) { v_kernel kernel; v_gid nullGID; @@ -2422,16 +2553,20 @@ v_groupSweepMarkedInstances( v_groupInstance grInst; v_writeResult result = V_WRITE_SUCCESS; - c_mutexLock(&group->mutex); + OSPL_LOCK(group); kernel = v_objectKernel(group); v_gidSetNil(nullGID); disposeMsg = v_groupCreateInvalidMessage(kernel, nullGID, NULL, timestamp); if (disposeMsg) { - /* Set the nodeState of the message to DISPOSED. UNREGISTER and L_IMPLICIT. */ - v_stateSet(v_nodeState(disposeMsg), L_DISPOSED | L_UNREGISTER | L_IMPLICIT); - instances = ospl_c_select(group->instances, -1); + /* Set the nodeState of the message to DISPOSED and UNREGISTER. + * Note that this is NOT an IMPLICIT dispose, because it is not + * the result of a disconnect, but a valid deduction from the fact + * that the aligner MUST have disposed the data. + */ + v_stateSet(v_nodeState(disposeMsg), L_DISPOSED | L_UNREGISTER); + instances = v_groupStoreSelect(group->store, 0); while ((grInst = v_groupInstance(c_iterTakeFirst(instances))) != NULL && result == V_WRITE_SUCCESS) { if (v_stateTest(grInst->state, L_MARK)) { result = disposeMarkedInstance(grInst, disposeMsg); @@ -2444,7 +2579,7 @@ v_groupSweepMarkedInstances( result = V_WRITE_OUT_OF_RESOURCES; OS_REPORT(OS_ERROR, "v_group::v_groupSweepMarkedInstances", result, "Failed to allocate message."); } - c_mutexUnlock(&group->mutex); + OSPL_UNLOCK(group); return result; } @@ -2478,7 +2613,7 @@ v_groupDisposeAllMatchingInstancesLocked ( v_stateSet(v_nodeState(msgActionArg.message), L_DISPOSED | flags); msgActionArg.result = V_WRITE_SUCCESS; if (qos->durability.v.kind != V_DURABILITY_VOLATILE) { - (void)c_tableWalk(group->instances, disposeGroupInstance, &msgActionArg); + v_groupStoreWalk(group->store, disposeGroupInstance, &msgActionArg); } if ( msgActionArg.result == V_WRITE_SUCCESS ) { @@ -2506,9 +2641,9 @@ v_groupDisposeAllMatchingInstances ( c_voidp arg) { v_writeResult res; - c_mutexLock(&group->mutex); + OSPL_LOCK(group); res = v_groupDisposeAllMatchingInstancesLocked(group, timestamp, flags, condition, arg); - c_mutexUnlock(&group->mutex); + OSPL_UNLOCK(group); return res; } @@ -2519,10 +2654,10 @@ v_groupDisposeAll ( c_ulong flags) { v_writeResult res; - c_mutexLock(&group->mutex); + OSPL_LOCK(group); res = v_groupDisposeAllMatchingInstancesLocked(group, timestamp, flags, NULL, NULL); group->lastDisposeAllTime = timestamp; - c_mutexUnlock(&group->mutex); + OSPL_UNLOCK(group); return res; } @@ -2640,34 +2775,36 @@ v_resendScopeImage ( return tot; } -static v_groupInstance -lookupInstanceByMessage( +static v_message +createRegisterMessage ( v_group group, v_message msg) { - v_groupInstance instance; - c_value _keyValues[32]; - c_value *keyValues = _keyValues; - c_array messageKeyList; - c_ulong i, nrOfKeys; + v_message regMsg = NULL; - messageKeyList = v_topicMessageKeyList(v_groupTopic(group)); - nrOfKeys = c_arraySize(messageKeyList); - if (nrOfKeys > 32) { - keyValues = os_malloc(sizeof(c_value) * nrOfKeys); - } - for (i=0;iinstances, &keyValues[0]); - /* Key values have to be freed again */ - for (i=0;i 32) { - os_free(keyValues); + regMsg = v_topicMessageNew(group->topic); + if (regMsg) { + memcpy(regMsg, msg, C_SIZEOF(v_message)); + v_topicMessageCopyKeyValues(group->topic, regMsg, msg); + regMsg->qos = c_keep(msg->qos); + v_nodeState(regMsg) = (v_nodeState(msg) & L_TRANSACTION) | L_REGISTER; } - return instance; + return regMsg; +} + +static v_message +createDisposeMessage ( + v_group group) +{ + v_message msg = NULL; + v_gid nullGID; + + v_gidSetNil(nullGID); + msg = v_groupCreateInvalidMessage(v_objectKernel(group), nullGID, NULL, group->lastDisposeAllTime); + if (msg) { + v_stateSet(v_nodeState(msg), L_DISPOSED); + } + return msg; } /* As part of scarab#2907, the new inout v_resendScope parameter to groupWrite @@ -2689,132 +2826,83 @@ groupWrite ( v_groupInstance *instancePtr, v_networkId writingNetworkId, c_bool stream, - v_entry entry, + c_bool historicalData, v_resendScope *resendScope) { - v_groupInstance instance, found; + v_groupInstance instance; v_writeResult result; v_topicQos qos; c_bool rejected = FALSE; - v_message regMsg, disposeMsg = NULL; + v_message disposeMsg = NULL; v_resendScope disposeScope = V_RESEND_NONE; - c_bool bypassCache = 0; + c_bool bypassCache = historicalData; const os_timeE now = msg->allocTime; assert(C_TYPECHECK(group,v_group)); assert(C_TYPECHECK(msg,v_message)); assert(!v_messageStateTest(msg, L_ENDOFTRANSACTION)); + if (instancePtr != NULL && *instancePtr != NULL && v_groupInstanceOwner(*instancePtr) != group) { + assert(FALSE); + return V_WRITE_PRE_NOT_MET; + } + /* Check if a key filter is set and filter out key values of no interest */ + if ((group->filter) && (!v_filterEvalKey(group->filter, msg))) { + return V_WRITE_SUCCESS_NOT_STORED; + } /* cleanup resources, * do not delay this call until the data is inserted, * it will have undesired side-effects on the just inserted data. */ updatePurgeList(group, now); - qos = v_topicQosRef(group->topic); - - if ((instancePtr == NULL) || (*instancePtr == NULL)) { - instance = lookupInstanceByMessage(group, msg); - if (instance == NULL) { - if(v_messageStateTest(msg, L_UNREGISTER)){ - /* The instance doesn't exist, meaning no writer has it currently - * registered. An implicit register doesn't make sense for an - * unregister either. */ - return V_WRITE_SUCCESS; - } - instance = v_groupInstanceNew(group, msg); - found = c_tableInsert(group->instances, instance); - assert(found == instance); - OS_UNUSED_ARG(found); - } - - result = v_groupInstanceRegister(instance, msg); - if (result == V_WRITE_REGISTERED){ - /* This writer is new for this instance. */ - if (!v_messageStateTest(msg, L_REGISTER)) { - /* This message is not a register message. - * Therefore create an implicit register message and forward it to all peers. - */ - regMsg = v_topicMessageNew(group->topic); - if (regMsg) { - memcpy(regMsg, msg, C_SIZEOF(v_message)); - v_topicMessageCopyKeyValues(group->topic, regMsg, msg); - regMsg->qos = c_keep(msg->qos); - v_nodeState(regMsg) = (v_nodeState(msg) & L_TRANSACTION) | L_REGISTER; - - if(stream == TRUE) { - forwardMessageToStreams(group, NULL, regMsg, now, V_GROUP_ACTION_REGISTER); - } - result = forwardRegisterMessage(instance, regMsg); - c_free(regMsg); - } else { - OS_REPORT(OS_CRITICAL, OS_FUNCTION, V_RESULT_OUT_OF_MEMORY, - "Failed to create a register message for topic %s", v_topicName(group->topic)); - assert(FALSE); - return V_RESULT_OUT_OF_MEMORY; - } - } - } else if (result == V_WRITE_UNREGISTERED) { - bypassCache = 1; - result = V_WRITE_SUCCESS; - } - if ((instancePtr != NULL) && (*instancePtr == NULL)) { + if ((instancePtr != NULL) && (*instancePtr != NULL)) { + instance = c_keep(*instancePtr); + } else { + instance = v_groupStoreCreateInstance(group->store, msg); + if (instancePtr) { *instancePtr = c_keep(instance); } + } + + /* If msg is a pure register message then no more actions required. */ + if (!v_stateTestOr(v_nodeState(msg), L_WRITE | L_DISPOSED | L_UNREGISTER | L_TRANSACTION)) { v_groupInstanceFree(instance); - /* When the message is delivered out-of-order and belongs to an instance that - * should have been covered by a newer dispose_all_data event that has already - * been processed, then make sure the a corresponding dispose message is inserted - * behind it in the readers. This dispose message is by definition an invalid - * sample, and so does not count towards the resource limits. It should therefore - * not be rejected by reason of resource limit exhaustion. If it is rejected - * because of a still missing connection, then the previous sample is rejected - * as well. So during its re-transmission this snippet of code will be touched - * again, thereby re-inserting the dispose message as well. - */ - if ( qos->orderby.v.kind == V_ORDERBY_SOURCETIME && - os_timeWCompare( msg->writeTime, group->lastDisposeAllTime ) == OS_LESS ) - { - v_gid nullGID; + return V_WRITE_SUCCESS; + } - v_gidSetNil(nullGID); - disposeMsg = v_groupCreateInvalidMessage(v_objectKernel(group), nullGID, NULL, group->lastDisposeAllTime); - if (disposeMsg) { - v_stateSet(v_nodeState(disposeMsg), L_DISPOSED); - } else { - /* Error message already generated by v_groupCreateInvalidMessage. */ - return V_WRITE_OUT_OF_RESOURCES; - } - } - } else { - instance = *instancePtr; - if (v_groupInstanceOwner(instance) != group) { - assert(FALSE); - return V_WRITE_PRE_NOT_MET; - } - if (!v_stateTestOr(v_nodeState(msg), L_WRITE | L_DISPOSED | L_UNREGISTER | L_TRANSACTION)) { - return V_WRITE_SUCCESS; - } + result = v_groupInstanceRegister(instance, msg); + if (result == V_WRITE_UNREGISTERED) { + bypassCache = TRUE; result = V_WRITE_SUCCESS; } - (void) result; - - V_MESSAGE_STAMP(msg,groupLookupTime); - /* At this point the group instance is either created, resolved * or verified if it was provided by the callee. */ - assert(instance != NULL); + if (result == V_WRITE_REGISTERED && !v_messageStateTest(msg, L_REGISTER)){ + /* The Instance is registered but the message is not a register message. + * Therefore create an implicit register message and + * forward it to all local peers to establish the instance pipeline. + */ + v_message regMsg = createRegisterMessage(group, msg); + if (regMsg) { + result = forwardRegisterMessage(instance, regMsg); + c_free(regMsg); + } else { + v_groupInstanceFree(instance); + return V_WRITE_OUT_OF_RESOURCES; + } + } /* For Unregister messages first unregister the instance to check * if it was registered, if not then no need to continue. */ if (v_messageStateTest(msg,L_UNREGISTER)) { assert(!v_messageStateTest(msg,L_REGISTER)); - /* When entry is set the msg is not meant for the instance, when - * msg is part of an transaction don't insert it just yet. */ - if ((!entry) && - (!v_message_isTransaction(msg))) { + /* When msg is part of an transaction don't insert it just yet. + */ + if (!v_message_isTransaction(msg)) + { result = v_groupInstanceUnregister(instance,msg, NULL); if (result != V_WRITE_UNREGISTERED) { /* The message has no effect on the instance state. @@ -2822,31 +2910,44 @@ groupWrite ( * Therefore readers will not be effected. * So abort this method. */ + v_groupInstanceFree(instance); return result; } } } + if (forwardMessage(instance,msg,writingNetworkId, bypassCache, resendScope) == + V_WRITE_REJECTED) { + rejected = TRUE; + /* if forwardMessage rejects, it will have already set resendScope itself */ + } /* Now forward the message to all networks. */ - result = forwardMessageToNetwork(group, msg, writingNetworkId, entry); + result = forwardMessageToNetwork(group, msg, writingNetworkId); if (result == V_WRITE_REJECTED) { rejected = TRUE; *resendScope |= V_RESEND_REMOTE; } - /* Now forward the message to all subscribers. - * The resendScope is passed into this function so it can be set for the - * particular scope that is required. This is because forwardMessage does - * the work for sending of both V_RESEND_VARIANT and V_RESEND_TOPIC - * functionality (which may be required independently). + /* When the message is delivered out-of-order and belongs to an instance that + * should have been covered by a newer dispose_all_data event that has already + * been processed, then make sure the a corresponding dispose message is inserted + * behind it in the readers. This dispose message is by definition an invalid + * sample, and so does not count towards the resource limits. It should therefore + * not be rejected by reason of resource limit exhaustion. If it is rejected + * because of a still missing connection, then the previous sample is rejected + * as well. So during its re-transmission this snippet of code will be touched + * again, thereby re-inserting the dispose message as well. */ - result = forwardMessage(instance,msg,writingNetworkId, entry, bypassCache, resendScope); - if (result == V_WRITE_REJECTED) { - rejected = TRUE; - /* if forwardMessage rejects, it will have already set resendScope itself */ - } - if (result == V_WRITE_SUCCESS && disposeMsg != NULL) { - result = forwardMessage(instance, disposeMsg, V_NETWORKID_LOCAL, NULL, 0, &disposeScope); + V_MESSAGE_STAMP(msg,groupLookupTime); + qos = v_topicQosRef(group->topic); + if ( qos->orderby.v.kind == V_ORDERBY_SOURCETIME && + os_timeWCompare( msg->writeTime, group->lastDisposeAllTime ) == OS_LESS ) + { + disposeMsg = createDisposeMessage(group); + if (!disposeMsg) { + v_groupInstanceFree(instance); + return V_WRITE_OUT_OF_RESOURCES; + } } /* In case the message contains non volatile data then check the @@ -2857,57 +2958,70 @@ groupWrite ( * qos is non-volatile. */ if (v_message_isTransaction(msg) || - (!entry && (qos->durability.v.kind != V_DURABILITY_VOLATILE) && - (!msg->qos || v_messageQos_durabilityKind(msg->qos) != V_DURABILITY_VOLATILE))) { - result = v_groupInstanceInsert(instance, msg, FALSE, NULL, stream); - if (result == V_WRITE_REJECTED) { + ((qos->durability.v.kind != V_DURABILITY_VOLATILE) && + (!msg->qos || v_messageQos_durabilityKind(msg->qos) != V_DURABILITY_VOLATILE))) + { + result = v_groupInstanceInsert(instance, msg); + if (result == V_WRITE_SUCCESS) { + if (stream) { + forwardToStreams(instance, msg); + } + if (disposeMsg != NULL) { + /* When the message is delivered out-of-order and belongs to an instance that + * should have been covered by a newer dispose_all_data event that has already + * been processed, then make sure the a corresponding dispose message is inserted + * behind it in the group and its streams. + * This dispose message is by definition an invalid sample, and so does not count + * towards the resource limits. It should therefore not be rejected by reason of + * resource limit exhaustion. If it is rejected because of a still missing connection, + * then the previous sample is rejected as well. So during its re-transmission this + * snippet of code will be touched again, thereby re-inserting the dispose message + * as well. + */ + result = v_groupInstanceInsert(instance, disposeMsg); + if (result == V_WRITE_SUCCESS) { + forwardToStreams(instance, disposeMsg); + } + } + } else if (result == V_WRITE_REJECTED) { rejected = TRUE; *resendScope |= V_RESEND_DURABLE; } - if (result == V_WRITE_SUCCESS && disposeMsg != NULL) - { - /* When the message is delivered out-of-order and belongs to an instance that - * should have been covered by a newer dispose_all_data event that has already - * been processed, then make sure the a corresponding dispose message is inserted - * behind it in the group and its streams. - * This dispose message is by definition an invalid sample, and so does not count - * towards the resource limits. It should therefore not be rejected by reason of - * resource limit exhaustion. If it is rejected because of a still missing connection, - * then the previous sample is rejected as well. So during its re-transmission this - * snippet of code will be touched again, thereby re-inserting the dispose message - * as well. - */ - result = v_groupInstanceInsert(instance, disposeMsg, FALSE, NULL, TRUE); - /* Make sure that a dispose that is processed correctly without error is treated as success. */ - } if (result == V_WRITE_DUPLICATE || result == V_WRITE_SUCCESS_NOT_STORED) { result = V_WRITE_SUCCESS; + } else if (result == V_WRITE_REJECTED) { + *resendScope |= V_RESEND_DURABLE; } - } else { + } + if (!v_message_isTransaction(msg) && + ((qos->durability.v.kind == V_DURABILITY_VOLATILE) || + (msg->qos && v_messageQos_durabilityKind(msg->qos) == V_DURABILITY_VOLATILE))) + { /* The message is VOLATILE. Only if the message is an UNREGISTER message * we might need to add the instance to one of the 2 purgelists. As the * message is volatile we can ignore the WRITE and DISPOSE messages. */ - if ((v_messageStateTest(msg,L_UNREGISTER) && - v_groupInstanceStateTest(instance,L_NOWRITERS))) + if ((v_messageStateTest(msg,L_UNREGISTER) && v_groupInstanceStateTest(instance,L_NOWRITERS))) { - if ((qos->durability.v.kind != V_DURABILITY_VOLATILE) && - v_groupInstanceStateTest(instance,L_DISPOSED)) + if ((qos->durability.v.kind != V_DURABILITY_VOLATILE) && v_groupInstanceStateTest(instance,L_DISPOSED)) { _dispose_purgeList_insert(instance, now); - } else { - if (v_groupInstanceStateTest(instance,L_EMPTY)) { - _empty_purgeList_insert(instance, now); - } + } else if (v_groupInstanceStateTest(instance,L_EMPTY)) { + _empty_purgeList_insert(instance, now); } } } + + if (result == V_WRITE_SUCCESS && disposeMsg != NULL) { + result = forwardMessage(instance, disposeMsg, V_NETWORKID_LOCAL, 0, &disposeScope); + } + c_free(disposeMsg); + v_groupInstanceFree(instance); + if (rejected) { result = V_WRITE_REJECTED; } - c_free(disposeMsg); - return result; } @@ -2919,53 +3033,60 @@ groupWriteEOT ( v_resendScope *resendScope) { v_writeResult result = V_WRITE_SUCCESS; - v_resendScope inputScope = *resendScope; - c_bool complete = FALSE; - v_topicQos qos; - v_transactionAdmin transactionAdmin; - /* cleanup resources, * do not delay this call until the data is inserted, * it will have undesired side-effects on the just inserted data. */ updatePurgeList(group, msg->allocTime); - /* Now forward the message to all networks. */ - if (inputScope == V_RESEND_NONE || (inputScope & V_RESEND_REMOTE)) { - result = forwardMessageToNetwork(group, msg, writingNetworkId, NULL); + if (*resendScope == V_RESEND_NONE || (*resendScope & V_RESEND_REMOTE)) { + result = forwardMessageToNetwork(group, msg, writingNetworkId); if (result == V_WRITE_REJECTED) { *resendScope |= V_RESEND_REMOTE; } } + return result; +} - /* Now forward the message to all subscribers and to the groups. - * EOT's will never be rejected by readers or groups since they - * represent an event, not a new sample. That means that it will - * only need to be sent to readers and groups initially (during - * the V_RESEND_NONE scope). There is no possible reason to retransmit - * the EOT for readers and groups, like there is for the network. - */ - if (inputScope == V_RESEND_NONE) { - qos = v_topicQosRef(group->topic); - if (v_message_isTransaction(msg) || - ((qos->durability.v.kind != V_DURABILITY_VOLATILE) && - ((!msg->qos || v_messageQos_durabilityKind(msg->qos) != V_DURABILITY_VOLATILE)))) { - transactionAdmin = v__groupGetTransactionAdmin(group); - if (transactionAdmin) { - /* Now update the transaction administration in the group itself. */ - (void)v_transactionAdminInsertMessage(transactionAdmin, msg, NULL, FALSE, &complete); - if (complete) { - if (!v_kernelGroupTransactionLockAccess(v_objectKernel(group))) { - v_kernelGroupTransactionFlush(v_objectKernel(group), transactionAdmin); - v_kernelGroupTransactionUnlockAccess(v_objectKernel(group)); - } - } - c_free(transactionAdmin); - } - } +static c_bool +groupInsertTransactionMessage( + v_group _this, + v_message msg) +{ + c_bool flush = FALSE; + if (_this->transactionAdmin == NULL) { + _this->transactionAdmin = v_transactionAdminNew(v_object(_this), + v_kernelTransactionGroupAdmin(v_objectKernel(_this)), + _this->topic); } + (void)v_transactionAdminInsertMessage(_this->transactionAdmin, msg, NULL, FALSE, &flush); + return flush; +} - return result; +void +v_groupInsertTransactionMessage( + v_group _this, + v_message msg, + v_groupInstance instance) +{ + c_bool flush = FALSE; + v_instance inst = v_instance(instance); + if (_this->transactionAdmin == NULL) { + _this->transactionAdmin = v_transactionAdminNew(v_object(_this), + v_kernelTransactionGroupAdmin(v_objectKernel(_this)), + _this->topic); + } + /* For data only provide the instance when owner */ + if (!v_messageStateTest(msg,L_UNREGISTER) && !v_messageStateTest(msg,L_REGISTER)) { + v_ownershipResult ownership = v_groupInstanceTestOwnership(instance, msg); + if (ownership == V_OWNERSHIP_INCOMPATIBLE_QOS || ownership == V_OWNERSHIP_NOT_OWNER) { + inst = NULL; + } + } + (void)v_transactionAdminInsertMessage(_this->transactionAdmin, msg, inst, FALSE, &flush); + if (flush) { + v_kernelGroupTransactionFlush(v_objectKernel(_this), _this->transactionAdmin); + } } v_writeResult @@ -2977,16 +3098,158 @@ v_groupWrite ( v_resendScope *resendScope) { v_writeResult result; + c_bool flush = FALSE; - c_mutexLock(&group->mutex); - + OSPL_LOCK(group); V_MESSAGE_STAMP(msg,groupInsertTime); if (v_messageStateTest(msg, L_ENDOFTRANSACTION)) { + /* Now forward the message to all subscribers and to the groups. + * EOT's will never be rejected by readers or groups since they + * represent an event, not a new sample. That means that it will + * only need to be sent to readers and groups initially (during + * the V_RESEND_NONE scope). There is no possible reason to retransmit + * the EOT for readers and groups, like there is for the network. + */ + c_bool resend = (*resendScope != V_RESEND_NONE); result = groupWriteEOT(group, msg, writingNetworkId, resendScope); + if (!resend) { + flush = groupInsertTransactionMessage(group, msg); + } + } else { + result = groupWrite(group, msg, instancePtr, writingNetworkId, TRUE, FALSE, resendScope); + if (result == V_WRITE_SUCCESS_NOT_STORED) { + if (v_message_isTransaction(msg)) { + flush = groupInsertTransactionMessage(group, msg); + } + result = V_WRITE_SUCCESS; + } + } + OSPL_UNLOCK(group); + if (flush) { + v_kernelGroupTransactionFlush(v_objectKernel(group), NULL); + } + return result; +} + +v_writeResult +v_groupWriteHistoricalData ( + v_group group, + v_message msg, + v_groupInstance *instancePtr, + v_networkId writingNetworkId) +{ + v_writeResult result; + v_resendScope resendScope = V_RESEND_NONE; /* resendScope not yet used here beyond this function */ + c_bool flush = FALSE; + + OSPL_LOCK(group); + + V_MESSAGE_STAMP(msg,groupInsertTime); + if (v_messageStateTest(msg, L_ENDOFTRANSACTION)) { + result = groupWriteEOT(group, msg, writingNetworkId, &resendScope); + flush = groupInsertTransactionMessage(group, msg); } else { - result = groupWrite(group, msg, instancePtr, writingNetworkId, TRUE, NULL, resendScope); + result = groupWrite(group, msg, instancePtr, writingNetworkId, TRUE, TRUE, &resendScope); + if (result == V_WRITE_SUCCESS_NOT_STORED) { + if (v_message_isTransaction(msg)) { + flush = groupInsertTransactionMessage(group, msg); + } + result = V_WRITE_SUCCESS; + } + } + OSPL_UNLOCK(group); + if (flush) { + v_kernelGroupTransactionFlush(v_objectKernel(group), NULL); + } + + return result; +} + +v_writeResult +v_groupWriteNoStream ( + v_group group, + v_message msg, + v_groupInstance *instancePtr, + v_networkId writingNetworkId) +{ + v_writeResult result; + v_resendScope resendScope = V_RESEND_NONE; /* resendScope not yet used here beyond this function */ + c_bool flush = FALSE; + + OSPL_LOCK(group); + result = groupWrite(group, msg, instancePtr, writingNetworkId, FALSE, FALSE, &resendScope); + if (result == V_WRITE_SUCCESS_NOT_STORED) { + if (v_message_isTransaction(msg)) { + flush = groupInsertTransactionMessage(group, msg); + } + result = V_WRITE_SUCCESS; + } + OSPL_UNLOCK(group); + if (flush) { + v_kernelGroupTransactionFlush(v_objectKernel(group), NULL); + } + + return result; +} + +v_writeResult +v_groupWriteHistoricalToReader ( + v_group group, + v_message msg, + v_entry entry) +{ + v_writeResult result; + const os_timeE now = msg->allocTime; + + assert(C_TYPECHECK(group,v_group)); + assert(C_TYPECHECK(msg,v_message)); + + OSPL_LOCK(group); + + /* Check if a key filter is set and filter out key values of no interest */ + if ((group->filter) && (!v_filterEvalKey(group->filter, msg))) { + c_bool flush = FALSE; + if (v_message_isTransaction(msg)) { + flush = groupInsertTransactionMessage(group, msg); + } + OSPL_UNLOCK(group); + if (flush) { + v_kernelGroupTransactionFlush(v_objectKernel(group), NULL); + } + return V_WRITE_SUCCESS; + } + /* cleanup resources, + * do not delay this call until the data is inserted, + * it will have undesired side-effects on the just inserted data. + */ + updatePurgeList(group, now); + + if (!v_stateTestOr(v_nodeState(msg), L_WRITE | L_DISPOSED | L_UNREGISTER | L_TRANSACTION)) { + OSPL_UNLOCK(group); + return V_WRITE_SUCCESS; + } + + V_MESSAGE_STAMP(msg,groupLookupTime); + + result = v_dataReaderEntryWrite(v_dataReaderEntry(entry), msg, NULL, V_CONTEXT_GROUPWRITE); + + /* In case the message contains non volatile data then check the + * durability resource limits and write the data into the Transient + * (and persistent) store. + * Be aware that a dispose message written by dispose_all_data has + * no inline qos, but should still be stored in the group if the topic + * qos is non-volatile. + */ + if (v_message_isTransaction(msg)) { + v_groupInstance instance = v_groupStoreCreateInstance(group->store, msg); + v_groupInsertTransactionMessage(group, msg, instance); + if (result == V_WRITE_DUPLICATE || result == V_WRITE_SUCCESS_NOT_STORED) { + result = V_WRITE_SUCCESS; + } + v_groupInstanceFree(instance); } - c_mutexUnlock(&group->mutex); + + OSPL_UNLOCK(group); return result; } @@ -3013,7 +3276,7 @@ v__groupDataReaderEntriesWriteEOTNoLock( struct WriteEOTArg arg; #ifndef NDEBUG - assert(os_threadIdToInteger(_this->mutex.owner) == os_threadIdToInteger(os_threadIdSelf())); +//TODO: Need a replacement for: assert(os_threadIdToInteger(_this->mutex.owner) == os_threadIdToInteger(os_threadIdSelf())); #endif arg.msg = msg; arg.result = V_WRITE_SUCCESS; @@ -3037,18 +3300,15 @@ v_groupFlushTransactionNoLock( if (v_messageStateTest(message, L_ENDOFTRANSACTION)) { /* Create a v_groupAction to notify durability that the - * transaction has completed. */ + * transaction has completed. + */ forwardMessageToStreams(a->group, NULL, message, message->allocTime, V_GROUP_ACTION_TRANSACTION_COMPLETE); } else { assert(instance); qos = v_topicQosRef(a->group->topic); if (v_messageStateTest(message, L_UNREGISTER)) { - v_writeResult result; - result = v_groupInstanceUnregister(v_groupInstance(instance), message, a->txn); - if (result == V_WRITE_UNREGISTERED) { - (void)v_groupInstanceInsert(v_groupInstance(instance), message, TRUE, a->txn, TRUE); - } + /* UNREGISTER messages are flush when received, so ignore it now */ } else if (qos->durability.v.kind == V_DURABILITY_VOLATILE) { /* This is as far as a volatile sample goes */ if (v_messageStateTest(message, L_WRITE)) { @@ -3060,50 +3320,11 @@ v_groupFlushTransactionNoLock( * Since the sample already consumed resource limits in the transactional * administration, no additional resource claim is needed. */ - (void)v_groupInstanceInsert(v_groupInstance(instance), message, TRUE, a->txn, TRUE); + (void)v_groupInstanceFlushTransaction(v_groupInstance(instance), message, a->txn); } } } -v_writeResult -v_groupWriteNoStream ( - v_group group, - v_message msg, - v_groupInstance *instancePtr, - v_networkId writingNetworkId) -{ - v_writeResult result; - v_resendScope resendScope = V_RESEND_NONE; /* resendScope not yet used here beyond this function */ - - c_mutexLock(&group->mutex); - result = groupWrite(group, msg, instancePtr, writingNetworkId, FALSE, NULL, &resendScope); - c_mutexUnlock(&group->mutex); - - return result; -} - -v_writeResult -v_groupWriteNoStreamWithEntry ( - v_group group, - v_message msg, - v_groupInstance *instancePtr, - v_networkId writingNetworkId, - v_entry entry) -{ - v_writeResult result; - v_resendScope resendScope = V_RESEND_NONE; /* resendScope not yet used here beyond this function */ - - c_mutexLock(&group->mutex); - if (v_messageStateTest(msg, L_ENDOFTRANSACTION)) { - result = groupWriteEOT(group, msg, writingNetworkId, &resendScope); - } else { - result = groupWrite(group, msg, instancePtr, writingNetworkId, FALSE, entry, &resendScope); - } - c_mutexUnlock(&group->mutex); - - return result; -} - v_writeResult v_groupWriteCheckSampleLost( v_group group, @@ -3113,8 +3334,9 @@ v_groupWriteCheckSampleLost( v_resendScope *resendScope) { v_writeResult result; + c_bool flush = FALSE; - c_mutexLock(&group->mutex); + OSPL_LOCK(group); v_groupCheckForSampleLost(group, msg); @@ -3125,16 +3347,36 @@ v_groupWriteCheckSampleLost( */ if (c_baseMakeMemReservation(c_getBase(group), C_MM_RESERVATION_HIGH)) { if (v_messageStateTest(msg, L_ENDOFTRANSACTION)) { + c_bool processTransaction = (*resendScope == V_RESEND_NONE); result = groupWriteEOT(group, msg, writingNetworkId, resendScope); + if (processTransaction) { + flush = groupInsertTransactionMessage(group, msg); + } } else { - result = groupWrite(group, msg, instancePtr, writingNetworkId, TRUE, NULL, resendScope); + /* Before delivering the message to the group, check whether the message + * contains an L_UNREGISTER flag while the writer has autodispose set to TRUE. + * In that case also raise the L_DISPOSE flag, so that the dispose/unregister + * combination will be treated atomically. + */ + if (v_messageStateTest(msg, L_UNREGISTER) && v_messageQos_isAutoDispose(msg->qos)) { + v_stateSet(v_nodeState(msg), L_DISPOSED); + } + result = groupWrite(group, msg, instancePtr, writingNetworkId, TRUE, FALSE, resendScope); + if (result == V_WRITE_SUCCESS_NOT_STORED) { + if (v_message_isTransaction(msg)) { + flush = groupInsertTransactionMessage(group, msg); + } + result = V_WRITE_SUCCESS; + } } c_baseReleaseMemReservation(c_getBase(group), C_MM_RESERVATION_HIGH); } else { result = V_WRITE_OUT_OF_RESOURCES; } - - c_mutexUnlock(&group->mutex); + OSPL_UNLOCK(group); + if (flush) { + v_kernelGroupTransactionFlush(v_objectKernel(group), NULL); + } return result; } @@ -3186,10 +3428,10 @@ v_groupDeleteHistoricalData( { /* Do not delete historical data in builtin groups*/ if(isBuiltinGroup(group) == FALSE){ - c_mutexLock(&group->mutex); - c_tableWalk(group->instances, purgeInstanceTimedAction, &t); + OSPL_LOCK(group); + v_groupStoreWalk(group->store, purgeInstanceTimedAction, &t); forwardMessageToStreams(group, NULL, NULL, t, V_GROUP_ACTION_DELETE_DATA); - c_mutexUnlock(&group->mutex); + OSPL_UNLOCK(group); } return V_WRITE_SUCCESS; @@ -3248,11 +3490,11 @@ v_groupResend ( result = V_WRITE_SUCCESS; - c_mutexLock(&group->mutex); + OSPL_LOCK(group); updatePurgeList(group, os_timeEGet()); if ((instancePtr == NULL) || (*instancePtr == NULL)) { - c_mutexUnlock(&group->mutex); + OSPL_UNLOCK(group); return V_WRITE_ERROR; } else { instance = *instancePtr; @@ -3263,9 +3505,13 @@ v_groupResend ( */ if (*resendScope & V_RESEND_DURABLE) { if ((v_messageQos_durabilityKind(msg->qos) != V_DURABILITY_VOLATILE) || - (v_message_isTransaction(msg))) { - result = v_groupInstanceInsert(instance, msg, FALSE, NULL, TRUE); - if (result == V_WRITE_SUCCESS || result == V_WRITE_DUPLICATE) { + (v_message_isTransaction(msg))) + { + result = v_groupInstanceInsert(instance, msg); + if (result == V_WRITE_SUCCESS) { + forwardToStreams(instance, msg); + *resendScope = (v_resendScope) (*resendScope & ~V_RESEND_DURABLE); + } else if (result == V_WRITE_DUPLICATE) { *resendScope = (v_resendScope) (*resendScope & ~V_RESEND_DURABLE); } } else { @@ -3290,7 +3536,6 @@ v_groupResend ( arg.networkId = writingNetworkId; arg.writeResult = V_WRITE_SUCCESS; arg.groupRoutingEnabled = group->routingEnabled; - arg.entry = NULL; v_groupEntrySetWalk(&group->networkEntrySet, nwEntryWrite, &arg); @@ -3304,8 +3549,8 @@ v_groupResend ( /* If the the resend scope includes user defined key interest * then write the message to the DataReader in the variant entry set. - */ - /* Only forward the message when the WRITE bit is set! + * + * Only forward the message when the WRITE bit is set! * So only write and writedispose messages are forwarded to readers * with own storage spectrum. */ @@ -3355,7 +3600,7 @@ v_groupResend ( c_iterFree(arg.deadCacheItems); } - c_mutexUnlock(&group->mutex); + OSPL_UNLOCK(group); return result; } @@ -3370,44 +3615,73 @@ v_groupNwAttachedGet( return (g->networkEntrySet.firstEntry != NULL); } -c_bool +//TODO: Need a replacement for: _Requires_lock_held_(g->mutex) +v_alignState +v__groupCompleteGet_nl( + _In_ v_group g) +{ + assert(g != NULL); + assert(C_TYPECHECK(g,v_group)); + + return g->alignState; +} + +v_alignState v_groupCompleteGet( - v_group g) + _In_ v_group g) { + v_alignState alignState; + assert(g != NULL); assert(C_TYPECHECK(g,v_group)); - return g->complete; + OSPL_LOCK(g); + alignState = v__groupCompleteGet_nl(g); + OSPL_UNLOCK(g); + + return alignState; } -void +C_STRUCT(entryNotifyGroupStateChangeArg) { + v_handle groupHandle; + v_alignState alignState; +}; +C_CLASS(entryNotifyGroupStateChangeArg); + +static c_bool +entryNotifyGroupStateChange( + v_groupEntry proxy, + c_voidp arg) +{ + entryNotifyGroupStateChangeArg a = (entryNotifyGroupStateChangeArg)arg; + + v_entryNotifyGroupStateChange(proxy->entry, a->groupHandle, a->alignState); + return TRUE; +} + +v_alignState v_groupCompleteSet( - v_group g, - c_bool complete) + _Inout_ v_group g, + _In_ v_alignState alignState) { - c_iter entrySet = NULL; - v_groupEntry proxy; + v_alignState prev_state; + C_STRUCT(entryNotifyGroupStateChangeArg) alignArg; assert(g != NULL); assert(C_TYPECHECK(g,v_group)); - c_mutexLock(&g->mutex); - g->complete = complete; - proxy = g->topicEntrySet.firstEntry; - while (proxy) { - entrySet = c_iterAppend(entrySet, proxy); - proxy = proxy->next; - } - proxy = g->variantEntrySet.firstEntry; - while (proxy) { - entrySet = c_iterAppend(entrySet, proxy); - proxy = proxy->next; - } - c_mutexUnlock(&g->mutex); - while ((proxy = (v_groupEntry) c_iterTakeFirst(entrySet))) { - v_entryNotifyGroupStateChange(proxy->entry, g); - } - c_iterFree(entrySet); + OSPL_LOCK(g); + + assert(v_groupIsDurable(g)); + prev_state = g->alignState; + alignArg.alignState = g->alignState = alignState; + alignArg.groupHandle = v_publicHandle(v_public(g)); + (void)v_groupEntrySetWalk(&g->topicEntrySet, entryNotifyGroupStateChange, &alignArg); + (void)v_groupEntrySetWalk(&g->variantEntrySet, entryNotifyGroupStateChange, &alignArg); + + OSPL_UNLOCK(g); + + return prev_state; } struct walkEntryActionArg { @@ -3440,7 +3714,7 @@ v_groupWalkEntries( proxyAction.action = action; proxyAction.arg = arg; - c_mutexLock(&g->mutex); + OSPL_LOCK(g); result = v_groupEntrySetWalk(&g->networkEntrySet, walkEntryAction,&proxyAction); if (result == TRUE) { @@ -3451,13 +3725,12 @@ v_groupWalkEntries( result = v_groupEntrySetWalk(&g->topicEntrySet, walkEntryAction,&proxyAction); } - c_mutexUnlock(&g->mutex); + OSPL_UNLOCK(g); return result; } -/* - * Provide a target walk function and corresponding arg for walking +/* Provide a target walk function and corresponding arg for walking * through all groupInstances until a registration has been found that * matches the writerGID. */ @@ -3505,8 +3778,7 @@ removeWriterAdmin( } } -/* - * This function unregisters all instances that relate through the provided +/* This function unregisters all instances that relate through the provided * predicate to the GID supplied in the template. * The argument 'isImplicit' indicates whether the request to unregister was * implicit (i.e., on conto of the splice daemon) or an explicit unregister. @@ -3526,7 +3798,7 @@ v_groupUnregisterByGidTemplate( v_groupInstance grInst; /* Lock group. */ - c_mutexLock(&_this->mutex); + OSPL_LOCK(_this); /* Remove the writer admin for sample lost count */ removeWriterAdmin(_this, tmplGid); @@ -3547,9 +3819,9 @@ v_groupUnregisterByGidTemplate( arg.instanceList = c_iterNew(NULL); arg.registrationList = c_iterNew(NULL); arg.predicate = predicate; - c_tableWalk(_this->instances, groupCollectMatchingRegistrations, &arg); + v_groupStoreWalk(_this->store, groupCollectMatchingRegistrations, &arg); /* Unlock the group again to be able to forward the messages into the pipeline. */ - c_mutexUnlock(&_this->mutex); + OSPL_UNLOCK(_this); registration = (v_registration)c_iterTakeFirst(arg.registrationList); grInst = v_groupInstance(c_iterTakeFirst(arg.instanceList)); @@ -3585,7 +3857,8 @@ v_groupDisconnectWriter( } /* This function provides a predicate for finding GIDs that originate on the - * same node. */ + * same node. + */ static c_equality v_systemIdCompare( v_gid id1, @@ -3683,12 +3956,12 @@ v_groupStreamHistoricalData( assert(C_TYPECHECK(g,v_group)); assert(C_TYPECHECK(stream,v_groupStream)); - c_mutexLock(&g->mutex); + OSPL_LOCK(g); updatePurgeList(g, os_timeEGet()); h.group = g; h.stream = stream; - c_tableWalk(g->instances, streamHistoricalData, &h); - c_mutexUnlock(&g->mutex); + v_groupStoreWalk(g->store, streamHistoricalData, &h); + OSPL_UNLOCK(g); } struct lookupReaderIntanceArg { @@ -3741,6 +4014,9 @@ writeHistoricalSample( * through the pipeline first. */ if (lriArg->prevGroupInst != gi) { + if (lriArg->prevGroupInst && v_objectKind(lriArg->trgtEntry->reader) == K_DATAREADER) { + v_dataReaderInstanceTransferGroupOwnership(v_dataReaderInstance(*readerInst), &gi->owner); + } lriArg->readerInst = NULL; /* Reset previous readerInstance first. */ (void)v_groupCacheWalk(gi->targetCache, lookupReaderInstance, lriArg); } @@ -3789,7 +4065,6 @@ struct getHistoricalDataArg { v_result result; }; - static c_bool writeHistoricalData( c_object o, @@ -3812,61 +4087,32 @@ writeHistoricalData( return result; } - -struct writeTransactionArg { - v_dataReaderEntry entry; - v_groupInstance prevGroupInst; - v_dataReaderInstance readerInst; - c_bool includeEOT; -}; - -struct writeHistoricalTransactionArg { - v_dataReaderEntry entry; - c_bool includeEOT; -}; - static void writeTransaction( v_instance instance, v_message message, c_voidp arg) { - struct writeTransactionArg *a = (struct writeTransactionArg *)arg; - v_groupInstance gi = v_groupInstance(instance); - v_instance *readerInst = (v_instance *) &a->readerInst; - c_base base = c_getBase(instance); - v_writeResult writeResult; - - if (message && v_messageStateTest(message, L_ENDOFTRANSACTION)) { - if (a->includeEOT) { - v_dataReaderEntryWriteEOT(a->entry, message); - } - } else if (instance) { - if (a->prevGroupInst != gi) { - struct lookupReaderIntanceArg lriArg = {0}; - lriArg.trgtEntry = v_entry(a->entry); - (void)v_groupCacheWalk(gi->targetCache, lookupReaderInstance, &lriArg); - a->readerInst = lriArg.readerInst; - } + struct getHistoricalDataArg *a = (struct getHistoricalDataArg *)arg; + v_dataReaderEntry entry; - /* Keep track of the current groupInstance/readerInstance pair. */ - a->prevGroupInst = gi; + assert(arg); - if (c_baseMakeMemReservation(base, C_MM_RESERVATION_ZERO)) { - writeResult = v_entryWrite(v_entry(a->entry), message, V_NETWORKID_LOCAL, FALSE, readerInst, V_CONTEXT_GROUPWRITE); - c_baseReleaseMemReservation(base, C_MM_RESERVATION_ZERO); + /* The 'instance' attribute is part of the function signature because the function + * has to comply with the signature described by v_transactionAction in order to be + * able to pass it as a callback parameter to the v_transactionWalk function. However, + * the instance parameter has no use in the context of this particular callback. + */ + OS_UNUSED_ARG(instance); - if (writeResult != V_WRITE_SUCCESS) { - OS_REPORT(OS_CRITICAL, - "v_group::writeHistoricalSample",0, - "writeHistoricalSample(0x%"PA_PRIxADDR", 0x%"PA_PRIxADDR") failed with result %d.", - (os_address)message, (os_address)arg, writeResult); + if (message) { + entry = v_dataReaderEntry(a->entry); + if (v_messageStateTest(message, L_ENDOFTRANSACTION)) { + if (a->includeEOT) { + (void)v_dataReaderEntryWriteEOT(entry, message); } } else { - OS_REPORT(OS_CRITICAL, - "v_group::writeHistoricalSample",0, - "writeHistoricalSample(0x%"PA_PRIxADDR", 0x%"PA_PRIxADDR") failed: out of memory.", - (os_address)message, (os_address)arg); + (void)v_dataReaderEntryWrite(entry, message, NULL, V_CONTEXT_GROUPWRITE); } } } @@ -3876,17 +4122,7 @@ writeHistoricalTransaction( c_object o, c_voidp arg) { - v_transaction transaction = v_transaction(o); - struct getHistoricalDataArg *histArgs = arg; - struct writeTransactionArg writeArg; - - writeArg.entry = v_dataReaderEntry(histArgs->entry); - writeArg.prevGroupInst = NULL; - writeArg.readerInst = NULL; - writeArg.includeEOT = histArgs->includeEOT; - - v_transactionWalk(transaction, writeTransaction, &writeArg); - + v_transactionWalk(v_transaction(o), writeTransaction, arg); return TRUE; } @@ -3894,32 +4130,56 @@ writeHistoricalTransaction( static v_result groupGetHistoricalData( v_group g, - v_entry e, - c_bool openTransactions) + v_entry e) { - c_bool success; struct getHistoricalDataArg histArgs; - OS_UNUSED_ARG(success); + histArgs.entry = e; + histArgs.includeEOT = FALSE; + histArgs.result = V_RESULT_OK; + + v_groupStoreWalk(g->store, writeHistoricalData, &histArgs); + return histArgs.result; +} + +static void +groupGetOpenTransactions( + v_group g, + v_entry e, + c_bool groupAdmin) +{ + struct getHistoricalDataArg histArgs; histArgs.entry = e; histArgs.includeEOT = FALSE; histArgs.result = V_RESULT_OK; - success = c_tableWalk(g->instances, writeHistoricalData, &histArgs); - assert((success && (histArgs.result == V_RESULT_OK)) || - (!success && (histArgs.result != V_RESULT_OK))); - if (openTransactions && g->transactionAdmin) { + if (g->transactionAdmin) { v_transactionGroupAdmin tgroupadm; v_transactionAdminWalkTransactions(g->transactionAdmin, writeHistoricalTransaction, &histArgs); tgroupadm = v_transactionGetGroupAdmin(g->transactionAdmin); - if (tgroupadm) { + if (groupAdmin && tgroupadm) { histArgs.includeEOT = TRUE; v_transactionGroupAdminWalkTransactions(tgroupadm, g, writeHistoricalTransaction, &histArgs); } } - return histArgs.result; +} + +void +v_groupGetOpenTransactions( + v_group g, + v_entry e, + c_bool groupAdmin) +{ + assert(g != NULL); + assert(C_TYPECHECK(g,v_group)); + assert(e != NULL); + assert(C_TYPECHECK(e,v_entry)); + + OSPL_LOCK(g); + groupGetOpenTransactions(g,e,groupAdmin); + OSPL_UNLOCK(g); } v_result @@ -3936,13 +4196,16 @@ v_groupGetHistoricalData( assert(e != NULL); assert(C_TYPECHECK(e,v_entry)); - c_mutexLock(&g->mutex); + OSPL_LOCK(g); qos = v_topicQosRef(g->topic); if (qos->durability.v.kind != V_DURABILITY_VOLATILE) { updatePurgeList(g, os_timeEGet()); - result = groupGetHistoricalData(g, e, openTransactions); + result = groupGetHistoricalData(g, e); + if (openTransactions) { + groupGetOpenTransactions(g,e, TRUE); + } } - c_mutexUnlock(&g->mutex); + OSPL_UNLOCK(g); return result; } @@ -3957,29 +4220,25 @@ resolveField( c_ulong i, length; q_list list; c_string str; - c_type instanceType; c_char *fieldName; q_expr expr; - instanceType = c_subType(_this->instances); - field = c_fieldNew(instanceType,name); - + field = c_fieldNew(_this->instanceType,name); if (!field) { fieldName = os_alloca(strlen(name) + strlen("newest.message.userData.") + 1); os_sprintf(fieldName,"newest.%s",name); - field = c_fieldNew(instanceType,fieldName); + field = c_fieldNew(_this->instanceType,fieldName); if (!field) { os_sprintf(fieldName,"newest.message.%s",name); - field = c_fieldNew(instanceType,fieldName); + field = c_fieldNew(_this->instanceType,fieldName); if (!field) { os_sprintf(fieldName,"newest.message.userData.%s",name); - field = c_fieldNew(instanceType,fieldName); + field = c_fieldNew(_this->instanceType,fieldName); } } os_freea(fieldName); } - c_free(instanceType); if(field){ path = c_fieldPath(field); length = c_arraySize(path); @@ -4059,22 +4318,6 @@ resolveFields ( return TRUE; } -static c_iter -deOr( - q_expr e, - c_iter list) -{ - c_iter results; - - if (q_getTag(e) == Q_EXPR_OR) { - results = deOr(q_takePar(e,0),deOr(q_takePar(e,0),list)); - q_dispose(e); - } else { - results = c_iterInsert(list,e); - } - return results; -} - struct historicalCondition { c_array instanceQ; c_array sampleQ; @@ -4090,7 +4333,10 @@ struct historicalCondition { #define PREFIX "newest.message" static c_array -createKeyList(c_type instanceType, c_array keyList){ +createKeyList( + c_type instanceType, + c_array keyList) +{ c_ulong size, i; c_array newKeyList = NULL; @@ -4137,7 +4383,6 @@ calculateCondition( c_iter list; c_type type; c_array keyList; - c_table instanceSet; c_value *params = NULL; c_ulong nparams; @@ -4158,7 +4403,7 @@ calculateCondition( q_disjunctify(e); e = q_removeNots(e); - list = deOr(e,NULL); + list = q_exprDeOr(e,NULL); len = c_iterLength(list); type = c_resolve(c_getBase(c_object(v_objectKernel(g))),"c_query"); @@ -4179,7 +4424,6 @@ calculateCondition( result = FALSE; } } - instanceSet = g->instances; keyList = createKeyList(g->instanceType, v_topicMessageKeyList(g->topic)); @@ -4190,9 +4434,7 @@ calculateCondition( if (keyExpr != NULL) { progExpr = F1(Q_EXPR_PROGRAM,keyExpr); - condition->instanceQ[i] = c_queryNew(instanceSet, - progExpr, - params); + condition->instanceQ[i] = v_groupStore_create_query(g->store, progExpr, params); q_dispose(progExpr); if (condition->instanceQ[i] == NULL) { @@ -4206,9 +4448,7 @@ calculateCondition( } if (subExpr != NULL) { progExpr = F1(Q_EXPR_PROGRAM,subExpr); - condition->sampleQ[i] = c_queryNew(instanceSet, - progExpr, - params); + condition->sampleQ[i] = v_groupStore_create_query(g->store, progExpr, params); q_dispose(progExpr); if (condition->sampleQ[i] == NULL) { @@ -4354,7 +4594,8 @@ walkMatchingSamples( if (pass) { /* instance matches query*/ /* Since history is 'replayed' here, the oldest sample should be * processed first. We keep a reference to the first sample and - * set the current sample to the tail of the instance (oldest). */ + * set the current sample to the tail of the instance (oldest). + */ firstSample = v_groupInstanceHead(instance); sample = v_groupInstanceTail(instance); while ((sample != NULL) && proceed) { @@ -4412,7 +4653,7 @@ walkMatchingSamples( } if (condition->insertedSamples > samplesBefore) { - /*In case the instance matches the condition, also check whether + /* In case the instance matches the condition, also check whether * unregister messages need to be forwarded */ if (condition->handleUnregistrations) { @@ -4435,13 +4676,10 @@ v_groupGetHistoricalDataWithCondition( v_entry entry, v_historicalDataRequest request) { - c_bool success; v_result result; struct historicalCondition condition; struct lookupReaderIntanceArg actionArgs; - OS_UNUSED_ARG(success); - assert(g != NULL); assert(C_TYPECHECK(g,v_group)); assert(entry != NULL); @@ -4463,8 +4701,8 @@ v_groupGetHistoricalDataWithCondition( condition.handleUnregistrations = FALSE; if(calculateCondition(g, &condition)){ - /*Get all matching data and send it to the reader*/ - success = c_walk(g->instances, walkMatchingSamples, &condition); + /* Get all matching data and send it to the reader */ + v_groupStoreWalk(g->store, walkMatchingSamples, &condition); result = actionArgs.result; c_free(condition.instanceQ); c_free(condition.sampleQ); @@ -4510,8 +4748,20 @@ v_groupFlushActionWithCondition( if (request != NULL) { result = calculateCondition(g, &condition); } - if(result){ - (void) c_walk(g->instances, walkMatchingSamples, &condition); + if (result) { + v_groupStoreWalk(g->store, walkMatchingSamples, &condition); + /* Do not apply conditions to open transactions. This way the + * collected data can always be used to reconstruct the transactions. + */ + if (g->transactionAdmin) { + v_transactionGroupAdmin tgroupadm; + v_transactionAdminWalkTransactions(g->transactionAdmin, flushTransaction, &groupFlushArg); + + tgroupadm = v_transactionGetGroupAdmin(g->transactionAdmin); + if (tgroupadm) { + v_transactionGroupAdminWalkTransactions(tgroupadm, g, flushTransaction, &groupFlushArg); + } + } } c_free(condition.instanceQ); c_free(condition.sampleQ); @@ -4525,56 +4775,25 @@ v_groupUpdatePurgeList( assert(C_TYPECHECK(group,v_group)); if(group){ - c_mutexLock(&group->mutex); + OSPL_LOCK(group); updatePurgeList(group, os_timeEGet()); - c_mutexUnlock(&group->mutex); + OSPL_UNLOCK(group); } } -v_groupInstance -v_groupLookupInstance( - v_group group, - c_value keyValue[]) -{ - v_groupInstance result; - - if(group && keyValue){ - c_mutexLock(&group->mutex); - result = c_tableFind(group->instances, &keyValue[0]); - c_mutexUnlock(&group->mutex); - } else { - result = NULL; - } - return result; -} - -v_groupInstance -v_groupLookupInstanceAndRegistration( - v_group group, - c_value keyValue[], - v_gid gidTemplate, - v_matchIdentityAction predicate, - v_registration *registration) +void +v_groupWalkInstances( + v_group _this, + c_action action, + void *actionArg) { - v_groupInstance result; - - if(group && keyValue){ - c_mutexLock(&group->mutex); - result = c_tableFind(group->instances, &keyValue[0]); - if (result) { - if (registration) { - *registration = v_groupInstanceGetRegistration(result, gidTemplate, predicate); - } - } - c_mutexUnlock(&group->mutex); - } else { - result = NULL; - } - return result; + OSPL_LOCK(_this); + v_groupStoreWalk(_this->store, action, actionArg); + OSPL_UNLOCK(_this); } void -v_groupNotifyGroupCoherentPublication( +v_groupNotifyCoherentPublication( v_group _this, v_message msg) { @@ -4582,14 +4801,14 @@ v_groupNotifyGroupCoherentPublication( c_bool dispose; c_bool isImplicit; - c_mutexLock(&_this->mutex); + OSPL_LOCK(_this); if (_this->transactionAdmin) { info = v_builtinPublicationInfoData(msg); dispose = v_messageStateTest(msg, L_DISPOSED); isImplicit = v_messageStateTest(msg, L_IMPLICIT); (void)v_transactionAdminNotifyPublication(_this->transactionAdmin, info->key, dispose, info, isImplicit); } - c_mutexUnlock(&_this->mutex); + OSPL_UNLOCK(_this); } os_boolean @@ -4599,36 +4818,14 @@ v_groupIsDurable( return (v_topicQosRef(v_groupTopic(_this))->durability.v.kind != V_DURABILITY_VOLATILE); } -/** - * \brief This operation gets the transaction admin from the group - * and lazy creates it if it does not exist yet. - * - * \pre : The group is locked - * - * \param _this : The v_group this operation operates on - * - * \return : A kept reference to the v_transactionAdmin - */ -v_transactionAdmin -v__groupGetTransactionAdmin( - v_group _this) -{ - if (_this->transactionAdmin == NULL) { - _this->transactionAdmin = v_transactionAdminNew(v_object(_this), - v_kernelTransactionGroupAdmin(v_objectKernel(_this)), - _this->topic); - } - return c_keep(_this->transactionAdmin); -} - void v_groupSetOnRequest( v_group _this, c_bool value) { - c_mutexLock(&_this->mutex); + OSPL_LOCK(_this); _this->onRequest = value; - c_mutexUnlock(&_this->mutex); + OSPL_UNLOCK(_this); } c_bool @@ -4646,10 +4843,14 @@ v_groupNotifyWriter( v_kernel kernel; C_STRUCT(v_event) event; - c_mutexLock(&_this->mutex); + OSPL_LOCK(_this); if (_this->pristine) { kernel = v_objectKernel(_this); + event.kind = V_EVENT_CONNECT_WRITER; + event.source = v_observable(w); + event.data = _this; + event.handled = TRUE; /* Connect writer event * * This event is introduced for durability to be able to act on a writer connecting to a group, which @@ -4657,12 +4858,48 @@ v_groupNotifyWriter( * corresponding namespace with an infinite quality, which causes potential delayed alignment actions * of late-joining persistent sources to be discarded. */ - event.kind = V_EVENT_CONNECT_WRITER; - event.source = v_observable(w); - event.data = _this; - v_observableNotify(v_observable(kernel),&event); + OSPL_THROW_EVENT(kernel, &event); _this->pristine = FALSE; } - c_mutexUnlock(&_this->mutex); + OSPL_UNLOCK(_this); } +const char * +v_alignStateImage( + _In_ v_alignState s) +{ + switch (s) { + case V_ALIGNSTATE_COMPLETE: + return "COMPLETE"; + case V_ALIGNSTATE_INCOMPLETE: + return "INCOMPLETE"; + case V_ALIGNSTATE_NO_INTEREST: + return "NO_INTEREST"; + case V_ALIGNSTATE_COUNT: + break; + } + + return ""; +} + +v_result +v_groupSetFilter( + v_group _this, + q_expr condition, + const c_value params[], + os_uint32 nrOfParams) +{ + v_result result = V_RESULT_ILL_PARAM; + v_filter filter; + + assert(_this); + assert(condition); + assert(C_TYPECHECK(_this, v_group)); + filter = v_filterNew(v_topicMessageType(_this->topic), v_topicMessageKeyList(_this->topic), condition, params, nrOfParams); + if (filter) { + c_free(_this->filter); + _this->filter = filter; + result = V_RESULT_OK; + } + return result; +} diff --git a/src/kernel/code/v_groupCache.c b/src/kernel/code/v_groupCache.c index 1d6798324..c746f30a5 100644 --- a/src/kernel/code/v_groupCache.c +++ b/src/kernel/code/v_groupCache.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/code/v_groupCache.h b/src/kernel/code/v_groupCache.h index 26a337fa8..2d84431f8 100644 --- a/src/kernel/code/v_groupCache.h +++ b/src/kernel/code/v_groupCache.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/code/v_groupInstance.c b/src/kernel/code/v_groupInstance.c index f949413b1..75909e5df 100644 --- a/src/kernel/code/v_groupInstance.c +++ b/src/kernel/code/v_groupInstance.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -34,6 +35,7 @@ #include "v_messageQos.h" #include "v__policy.h" +#include "vortex_os.h" #include "os_report.h" #include "os_abstract.h" @@ -95,7 +97,8 @@ v_groupInstanceCheckCount( /* now check registrations and unregisterMessages lists. * first do cross check! messages in registrations may not - * occur in unregisterMessages. */ + * occur in unregisterMessages. + */ inconsistent = 0; reg = instance->registrations; while (reg != NULL) { @@ -111,7 +114,8 @@ v_groupInstanceCheckCount( } /* check for duplicates in both lists. * Only check if next item is a duplicate as this is the most likely - * place for a duplicate. */ + * place for a duplicate. + */ reg = instance->registrations; while (reg != NULL) { unreg = reg->next; @@ -218,40 +222,33 @@ v_groupAllocInstance( assert(_this); assert(C_TYPECHECK(_this,v_group)); - if (_this->cachedInstance == NULL) { - instance = v_groupInstance(c_new(_this->instanceType)); - if (instance) { - _ABORT_(c_refCount(instance) == 1); - kernel = v_objectKernel(_this); - v_object(instance)->kernel = kernel; - v_objectKind(instance) = K_GROUPINSTANCE; - instance->targetCache = v_groupCacheNew(kernel, V_CACHE_TARGETS); - instance->group = (c_voidp)_this; - if (instance->targetCache == NULL) { - OS_REPORT(OS_ERROR, - "v_groupAllocInstance",V_RESULT_INTERNAL_ERROR, - "Failed to allocate targetCache."); - assert(FALSE); - c_free(instance); - instance = NULL; - } - } else { - OS_REPORT(OS_FATAL, - "v_groupAllocInstance",V_RESULT_INTERNAL_ERROR, - "Failed to allocate group instance."); + instance = v_groupInstance(c_new(_this->instanceType)); + if (instance) { + _ABORT_(c_refCount(instance) == 1); + kernel = v_objectKernel(_this); + v_object(instance)->kernel = kernel; + v_objectKind(instance) = K_GROUPINSTANCE; + instance->targetCache = v_groupCacheNew(kernel, V_CACHE_TARGETS); + instance->group = (c_voidp)_this; + if (instance->targetCache == NULL) { + OS_REPORT(OS_ERROR, "v_groupAllocInstance", + V_RESULT_INTERNAL_ERROR, "Failed to allocate targetCache."); assert(FALSE); + c_free(instance); + instance = NULL; } } else { - instance = _this->cachedInstance; - _ABORT_(c_refCount(instance) == 1); - _this->cachedInstance = NULL; - assert(instance->group == (c_voidp)_this); + OS_REPORT(OS_FATAL, "v_groupAllocInstance", + V_RESULT_INTERNAL_ERROR, "Failed to allocate group instance."); + assert(FALSE); } _ABORT_(c_refCount(instance->targetCache) == 1); return instance; } +#define v_groupInstanceGID(o) ((v_groupInstanceGID)(o)) + void v_groupInstanceInit ( v_groupInstance _this, @@ -264,18 +261,20 @@ v_groupInstanceInit ( topicQos = v_topicGetQos(v_groupTopic(_this->group)); - /* - * copy the key value of the message into the newly created instance. - */ + /* copy the key value of the message into the newly created instance. */ + if (v_groupGIDKey(_this->group)) { + v_groupInstanceGID(_this)->gid = message->writerInstanceGID; + } messageKeyList = v_topicMessageKeyList(v_groupTopic(_this->group)); instanceKeyList = v_groupKeyList(_this->group); - nrOfKeys = c_arraySize(messageKeyList); - assert(nrOfKeys == c_arraySize(instanceKeyList)); - for (i=0;iepoch = OS_TIMEE_ZERO; _this->registrations = NULL; @@ -315,11 +314,6 @@ void v_groupInstanceFree( v_groupInstance instance) { - v_group group; - v_groupSample sample; - c_array instanceKeyList; - c_ulong i, nrOfKeys; - assert(C_TYPECHECK(instance,v_groupInstance)); assert((instance->count == 0) == (v_groupInstanceHead(instance) == NULL)); assert((instance->count == 0) == (v_groupInstanceTail(instance) == NULL)); @@ -334,32 +328,7 @@ v_groupInstanceFree( /* make sure it is removed from any purge list! */ instance->epoch = OS_TIMEE_ZERO; - v_groupCacheDeinit(instance->targetCache); - group = v_group(instance->group); - if (group->cachedInstance == NULL) { - /* - Explicit free the sample when this v_groupInstance is - cached. Because otherwise the reference is overwritten - when the v_groupInstance is re-used. - Note: the sample itself is also cached in its own module. - */ - sample = v_groupInstanceHead(instance); - c_free(sample); - v_groupInstanceSetHead(instance,NULL); - /* - Also free the key values for this instance, otherwise the - reference(s) is/are overwritten when the v_groupInstance - is re-used. - */ - instanceKeyList = v_groupKeyList(instance->group); - nrOfKeys = c_arraySize(instanceKeyList); - for (i = 0; i < nrOfKeys; i++) { - c_fieldFreeRef(instanceKeyList[i], instance); - } - c_free(instanceKeyList); - group->cachedInstance = c_keep(instance); - } } c_free(instance); } @@ -382,22 +351,16 @@ v_groupInstanceDisconnect( static c_equality v_registrationMessageCompare ( - v_registration _this, - v_message msg) + v_message msg, + v_registration _this) { C_STRUCT(v_message) template; - /* If the v_registration is an implicit UNREGISTER, then any message may re-register. */ - if (_this->state & L_IMPLICIT) { - assert(_this->state & L_UNREGISTER); - return C_LT; - } - template.writeTime = _this->writeTime; template.writerGID = _this->writerGID; template.sequenceNumber = _this->sequenceNumber; ((v_node)&template)->nodeState = _this->state & L_IMPLICIT; - return v_messageCompare(&template, msg); + return v_messageCompare(msg, &template); } v_writeResult @@ -436,8 +399,7 @@ v_groupInstanceRegister ( os_duration delay = OS_DURATION_INIT(5, 0); os_timeE purgeTime = os_timeESub(os_timeEGet(), delay); - /* - * Keep track of the address of the current registration to be able to + /* Keep track of the address of the current registration to be able to * redirect the content of the previous item in the registration list * when removing the current registration. */ @@ -445,20 +407,28 @@ v_groupInstanceRegister ( while (*registration != NULL && found == NULL) { if (v_gidCompare((*registration)->writerGID, message->writerGID) == C_EQ) { found = *registration; + if (v_messageStateTest(message,L_UNREGISTER)) { + /* The writers state is already unregisterd so for now ignore unregister message */ + return V_WRITE_SUCCESS; + } /* Pull registration from list by redirecting the contents of the - * previous registration pointer to the next registration. */ + * previous registration pointer to the next registration. + */ *registration = found->next; found->next = NULL; } else { /* Temporary implementation. Final solution must be more efficient. * e.g. by walking from oldest to newer and use of an active garbage collector. - * The purgeDelay should also be specified via a configuration parameter. */ + * The purgeDelay should also be specified via a configuration parameter. + */ if (os_timeECompare((*registration)->unregisterTime, purgeTime) == OS_LESS) { found = *registration; /* Pull registration from list by redirecting the contents of the - * previous registration pointer to the next registration. */ + * previous registration pointer to the next registration. + */ *registration = found->next; found->next = NULL; + v_transactionUnlink(found->transaction); c_free(found); found = NULL; } else { @@ -494,7 +464,7 @@ v_groupInstanceRegister ( /* Registrations are never IMPLICIT, not even when created by IMPLICIT samples. */ v_stateClear(found->state, L_IMPLICIT); v_stateSet(found->state, L_REGISTER); - found->transaction = NULL; /* Only unregistrations have a transaction ref */ + found->transaction = NULL; /* Only unregistrations have a transaction backref */ found->next = instance->registrations; instance->registrations = found; result = V_WRITE_REGISTERED; @@ -516,20 +486,22 @@ v_groupInstanceRegister ( * do miss a generation count increase! */ if (v_messageStateTest(message, L_REGISTER)) { - if (v_registrationMessageCompare(found, message) == C_LT) - { + c_equality eq = v_registrationMessageCompare(message, found); + if (eq != C_LT) { c_free(found->qos); found->qos = c_keep(message->qos); found->writeTime = message->writeTime; found->sequenceNumber = message->sequenceNumber; found->state = v_messageState(message); - c_free(found->transaction); + v_transactionUnlink(found->transaction); found->transaction = NULL; } } result = V_WRITE_SUCCESS; } } else if (!v_messageStateTest(message, L_UNREGISTER)){ + c_equality eq; + /* check writeTime of unregister message and given message in case the destination order policy is BY_SOURCE_TIMESTAMP. In that case If given message is older, return WRITE_SUCCESS, @@ -546,12 +518,16 @@ v_groupInstanceRegister ( bySource = (topicQos->orderby.v.kind == V_ORDERBY_SOURCETIME) ? TRUE : FALSE; c_free (topicQos); } - if ( (bySource == TRUE) && - v_registrationMessageCompare(found, message) == C_GT) { + if (bySource) { + eq = v_registrationMessageCompare(message, found); + } else { + eq = C_GT; + } + if (eq != C_GT) { /* reinsert as unregister message */ found->unregisterTime = message->allocTime; found->next = instance->unregistrations; - c_free(found->transaction); + v_transactionUnlink(found->transaction); found->transaction = NULL; instance->unregistrations = found; result = V_WRITE_UNREGISTERED; @@ -563,7 +539,7 @@ v_groupInstanceRegister ( found->state = v_messageState(message); /* Registrations are never IMPLICIT, not even when created by IMPLICIT samples. */ v_stateClear(found->state, L_IMPLICIT); - c_free(found->transaction); + v_transactionUnlink(found->transaction); found->transaction = NULL; found->next = instance->registrations; instance->registrations = found; @@ -597,8 +573,7 @@ v_groupInstanceRemoveUnregistrationIfObsolete( v_groupSample sampleFound; CHECK_REGISTRATIONS(instance); - /* - * First find the corresponding unregister message, if available. + /* First find the corresponding unregister message, if available. * Keep track of the address of the current unregistration to be able to * redirect the content of the previous item in the unregistration list * when removing the current unregistration. @@ -620,7 +595,8 @@ v_groupInstanceRemoveUnregistrationIfObsolete( if (unregistrationFound != NULL) { /* Now figure out if the instance contains any messages - * from this gid */ + * from this gid + */ sample = v_groupSample(instance->oldest); sampleFound = NULL; while (sample != NULL && sampleFound == NULL) @@ -640,9 +616,11 @@ v_groupInstanceRemoveUnregistrationIfObsolete( /* No sample found for this gid so remove the corresponding * unregistration message. Pull the registration from the list * by redirecting the contents of the previous registration pointer - * to the next registration. */ + * to the next registration. + */ *unregistration = unregistrationFound->next; unregistrationFound->next = NULL; + v_transactionUnlink(unregistrationFound->transaction); c_free(unregistrationFound); } } @@ -660,7 +638,6 @@ v_groupInstanceUnregister ( v_registration *registration; v_registration found; c_equality equality; - v_transaction txn; assert(instance != NULL); assert(C_TYPECHECK(instance,v_groupInstance)); @@ -673,8 +650,7 @@ v_groupInstanceUnregister ( v_stateClear(instance->state, L_MARK); } - /* - * Keep track of the address of the current registration to be able to + /* Keep track of the address of the current registration to be able to * redirect the content of the previous item in the registration list * when removing the current registration. */ @@ -698,16 +674,22 @@ v_groupInstanceUnregister ( registration = &((*registration)->next); } } - if (found != NULL) - { + if (found != NULL) { /* If resolved registration is older than unregister message, or if topic is ordered BY_RECEPTION, * then process the unregister. Otherwise skip this unregister since it belongs to an older * generation than the current registration. */ - if (v_registrationMessageCompare(found, message) == C_LT || - v_topicQosRef(v_groupInstanceGroup(instance)->topic)->orderby.v.kind == V_ORDERBY_RECEPTIONTIME) - - { + if (v_topicQosRef(v_groupInstanceGroup(instance)->topic)->orderby.v.kind == V_ORDERBY_RECEPTIONTIME) { + equality = C_GT; + } else { + equality = v_registrationMessageCompare(message, found); + } + if (equality != C_GT) { + /* reinsert registration */ + result = V_WRITE_SUCCESS; + found->next = instance->registrations; + instance->registrations = found; + } else { /* If message is currently owning instance, reset owner */ equality = v_gidCompare (message->writerGID, instance->owner.gid); if (equality == C_EQ) @@ -724,21 +706,14 @@ v_groupInstanceUnregister ( found->state = v_messageState(message); /* Use the txn variable to ensure that when txn == transaction the * transaction is not accidentally freed. */ - txn = found->transaction; - found->transaction = c_keep(transaction); - c_free(txn); + v_transactionLink(transaction); + v_transactionUnlink(found->transaction); + found->transaction = transaction; /* Insert the registration into the unregistration list. */ found->next = instance->unregistrations; instance->unregistrations = found; result = V_WRITE_UNREGISTERED; } - else - { - /* reinsert registration */ - result = V_WRITE_SUCCESS; - found->next = instance->registrations; - instance->registrations = found; - } } else { @@ -835,21 +810,15 @@ v_groupInstanceCreateMessage( { group = v_groupInstanceGroup(_this); message = v_topicMessageNew(v_groupTopic(group)); - if (message != NULL) - { + if (message != NULL) { messageKeyList = v_topicMessageKeyList(v_groupTopic(group)); instanceKeyList = v_groupKeyList(group); - assert(c_arraySize(messageKeyList) == c_arraySize(instanceKeyList)); nrOfKeys = c_arraySize(messageKeyList); - for (i=0;igroup); topicQos = v_topicQosRef(group->topic); + if (v_messageStateTest(message,L_REGISTER) || + (v_messageStateTest(message,L_UNREGISTER) && !v_messageStateTest(message,L_DISPOSED))) + { + /* Do not insert pure register or unregister messages */ + return V_WRITE_SUCCESS; + } if (v_stateTest(instance->state, L_EMPTY)) { - if (!isTransactionFlush) { + if (!transaction) { resourcesClaimed = v_groupInstanceClaimResource(instance, message); } if (resourcesClaimed) { @@ -1090,12 +1064,13 @@ insertSample( if (oldest == ptr) { ptr = NULL; } + v_transactionUnlink(oldest->transaction); c_free(oldest); instance->oldest = sample; } } - if (!isTransactionFlush) { + if (!transaction) { resourcesClaimed = v_groupInstanceClaimResource(instance, message); } if (resourcesClaimed) { @@ -1147,7 +1122,9 @@ insertSample( sample->instance = instance; state = v_nodeState(message); - sample->transaction = c_keep(transaction); + + sample->transaction = transaction; + v_transactionLink(sample->transaction); if (v_stateTest(state,L_DISPOSED)) { instance->count++; @@ -1175,91 +1152,37 @@ insertSample( return V_WRITE_SUCCESS; } -static v_groupActionKind -determineStreamAction( - v_groupInstance instance, - os_timeE now, - v_groupActionKind intendedAction) -{ - os_duration delay; - v_topicQos qos; - v_groupActionKind resultingAction = intendedAction; - - /* if the instance state is NOWRITERS and DISPOSED then and only - * then add the instance to the purge admin. - */ - qos = v_topicQosRef(v_group(instance->group)->topic); - if (v_groupInstanceStateTest(instance, L_DISPOSED | L_NOWRITERS)) { - delay = qos->durabilityService.v.service_cleanup_delay; - - /* If service_cleanup_delay is zero, remove all samples and - * insert instance in emptyList. - */ - if (OS_DURATION_ISZERO(delay)) { - if (!v_groupInstanceStateTest(instance,L_EMPTY)) { - v_groupInstancePurge(instance); - } - assert(v_groupInstanceStateTest(instance,L_EMPTY)); - _empty_purgeList_insert(instance, now); - resultingAction = V_GROUP_ACTION_CLEANUP_DELAY_EXPIRE; - } - /* Else if service_cleanup_delay is finite, insert instance - * in disposed list. - */ - else if (!OS_DURATION_ISINFINITE(delay)) { - _dispose_purgeList_insert(instance, now); - resultingAction = V_GROUP_ACTION_UNREGISTER; - } - /* If service_cleanup_delay is infinite, do nothing. */ - else { - resultingAction = V_GROUP_ACTION_UNREGISTER; - } - } - return resultingAction; -} - -static void processStreamActions( +v_ownershipResult +v_groupInstanceTestOwnership( v_groupInstance instance, - v_message message, - c_bool isTransactionFlush, - c_bool stream) + v_message message) { - v_groupActionKind actionKind; - v_group group = v_group(instance->group); - os_timeE now = os_timeEGet(); - - if (v_messageStateTest(message,L_WRITE)) { - actionKind = V_GROUP_ACTION_WRITE; - } else if (v_messageStateTest(message,L_DISPOSED)) { - actionKind = V_GROUP_ACTION_DISPOSE; - } else if (v_messageStateTest(message,L_UNREGISTER)) { - actionKind = V_GROUP_ACTION_UNREGISTER; - } else if (v_messageStateTest(message,L_REGISTER)) { - actionKind = V_GROUP_ACTION_REGISTER; + struct v_owner ownership; + /* Before NULL check on QoS was done here. Instead we now check the writer + * GID for validity and require QoS to be set because QoS is only allowed + * to be NULL in case of a "dispose all", in which case the writer GID must + * be NIL as well. + */ + if (v_gidIsValid (message->writerGID)) { + assert (message->qos != NULL); + ownership.exclusive = v_messageQos_isExclusive(message->qos); + ownership.strength = v_messageQos_getOwnershipStrength(message->qos); } else { - actionKind = V_GROUP_ACTION_WRITE; - } - actionKind = determineStreamAction(instance, now, actionKind); - /* Only forward to stream when sample is inserted in groupInstance and - * when streaming is required */ - if(stream == TRUE && !isTransactionFlush) { - forwardMessageToStreams(group, instance, message, now, actionKind); + assert (message->qos == NULL); + ownership.exclusive = 0; + ownership.strength = 0; } + ownership.gid = message->writerGID; + return v_determineOwnershipByStrength(&instance->owner, &ownership, v_messageState(message)); } v_writeResult v_groupInstanceInsert( v_groupInstance instance, - v_message message, - c_bool isTransactionFlush, - v_transaction transaction, - c_bool stream) + v_message message) { v_group group; - v_writeResult result; - struct v_owner ownership; - c_bool complete = FALSE; - v_transactionAdmin transactionAdmin; + v_writeResult result = V_WRITE_SUCCESS; assert(message != NULL); assert(instance != NULL); @@ -1271,124 +1194,38 @@ v_groupInstanceInsert( CHECK_REGISTRATIONS(instance); group = v_group(instance->group); - - if (v_messageStateTest(message,L_UNREGISTER) || - v_messageStateTest(message,L_REGISTER)) { - if (!isTransactionFlush && v_message_isTransaction(message)) { - transactionAdmin = v__groupGetTransactionAdmin(group); - if (transactionAdmin) { - (void)v_transactionAdminInsertMessage(transactionAdmin, message, v_instance(instance), FALSE, &complete); - if (complete) { - if (!v_kernelGroupTransactionLockAccess(v_objectKernel(group))) { - v_kernelGroupTransactionFlush(v_objectKernel(group), transactionAdmin); - v_kernelGroupTransactionUnlockAccess(v_objectKernel(group)); - } - } - c_free(transactionAdmin); - } - } - /* If this is a mixed L_DISPOSED | L_UNREGISTER message, inserted because of a disconnect, - * then not only remove the registration, but also process and store the DISPOSE sample. - */ - if (v_messageStateTest(message,L_DISPOSED)) { - result = insertSample(instance, message, FALSE, NULL); - } else { - result = V_WRITE_SUCCESS; - } - processStreamActions(instance, message, isTransactionFlush, stream); - return result; - } - - if (v_messageStateTest(message,L_MARK)) { - v_stateClear(instance->state, L_MARK); + if (v_message_isTransaction(message)) { + v_groupInsertTransactionMessage(group, message, instance); + } else { + result = insertSample(instance, message, NULL); } - if (v_messageStateTest(message,L_MARK)) { v_stateClear(instance->state, L_MARK); } + return result; +} - /* Exclusive ownership handling */ - /* Before NULL check on QoS was done here. Instead we now check the writer - GID for validity and require QoS to be set because QoS is only allowed - to be NULL in case of a "dispose all", in which case the writer GID must - be NIL as well. */ - if (v_gidIsValid (message->writerGID)) { - assert (message->qos != NULL); - ownership.exclusive = v_messageQos_isExclusive(message->qos); - ownership.strength = v_messageQos_getOwnershipStrength(message->qos); - } else { - assert (message->qos == NULL); - ownership.exclusive = 0; - ownership.strength = 0; - } - - ownership.gid = message->writerGID; - - switch (v_determineOwnershipByStrength ( - &instance->owner, &ownership, TRUE)) - { - case V_OWNERSHIP_INCOMPATIBLE_QOS: - case V_OWNERSHIP_NOT_OWNER: - if (!isTransactionFlush && v_message_isTransaction(message)) { - transactionAdmin = v__groupGetTransactionAdmin(group); - if (transactionAdmin) { - (void)v_transactionAdminInsertMessage(transactionAdmin, message, NULL, FALSE, &complete); - if (complete) { - if (!v_kernelGroupTransactionLockAccess(v_objectKernel(group))) { - v_kernelGroupTransactionFlush(v_objectKernel(group), transactionAdmin); - v_kernelGroupTransactionUnlockAccess(v_objectKernel(group)); - } - } - c_free(transactionAdmin); - } - } - return V_WRITE_SUCCESS_NOT_STORED; - break; - default: - break; - } - - if (!isTransactionFlush && v_message_isTransaction(message)) { - /* If the sample belongs to an unfinished transaction, then insert it into the - * transactional administration. Since this is a newly arriving sample, it still - * needs to make a resource claim. - */ - v_topicQos topicQos = v_topicGetQos(v_groupTopic(group)); - transactionAdmin = v__groupGetTransactionAdmin(group); - if (transactionAdmin) { - result = v_transactionAdminInsertMessage(transactionAdmin, message, v_instance(instance), FALSE, &complete); - if (complete) { - if (!v_kernelGroupTransactionLockAccess(v_objectKernel(group))) { - v_kernelGroupTransactionFlush(v_objectKernel(group), transactionAdmin); - v_kernelGroupTransactionUnlockAccess(v_objectKernel(group)); - } - } - c_free(transactionAdmin); - } else { - if (v_groupInstanceClaimResource(instance, message)) { - result = V_WRITE_SUCCESS; - } else { - result = V_WRITE_REJECTED; - }; - } - if (result != V_WRITE_REJECTED) { - processStreamActions(instance, message, isTransactionFlush, stream); - } - c_free(topicQos); - - return result; - } +v_writeResult +v_groupInstanceFlushTransaction( + v_groupInstance instance, + v_message message, + v_transaction transaction) +{ + v_writeResult result; - /* Insert the sample into the history. Since this is a newly arriving - * sample, it still needs to make a resource claim. - */ - result = insertSample(instance, message, isTransactionFlush, transaction); + assert(message != NULL); + assert(instance != NULL); + assert(C_TYPECHECK(message,v_message)); + assert(C_TYPECHECK(instance,v_groupInstance)); + assert((instance->count == 0) == (v_groupInstanceHead(instance) == NULL)); + assert((instance->count == 0) == (v_groupInstanceTail(instance) == NULL)); + CHECK_COUNT(instance); + CHECK_REGISTRATIONS(instance); - if (result == V_WRITE_SUCCESS) - { - processStreamActions(instance, message, isTransactionFlush, stream); + result = insertSample(instance, message, transaction); + if (v_messageStateTest(message,L_MARK)) { + v_stateClear(instance->state, L_MARK); } - return result; } @@ -1428,6 +1265,7 @@ v_groupInstanceRemove ( instance->count--; } CHECK_COUNT(instance); + v_transactionUnlink(sample->transaction); c_free(sample); if (instance->oldest == NULL) { v_stateSet(instance->state, L_EMPTY); @@ -1589,8 +1427,7 @@ groupInstanceCreateMessageEOT( return message; } -/* - * TODO: The code snippet below can be removed when v_groupUnregisterByGidTemplate +/* TODO: The code snippet below can be removed when v_groupUnregisterByGidTemplate * starts using the part in the #if 0 clause instead of in its #else clause as * indicated by scdds2805. */ @@ -1643,8 +1480,8 @@ v_groupInstancecleanup( } if (transaction) { v_stateSet(v_nodeState(unregMsg), L_TRANSACTION); - unregMsg->sequenceNumber = C_MAX_ULONG; } + unregMsg->sequenceNumber = C_MAX_ULONG; unregMsg->qos = c_keep(registration->qos); /* since messageQos does not contain refs */ unregMsg->writerGID = registration->writerGID; /* pretend this message comes from the original writer! */ unregMsg->writeTime = timestamp; @@ -1711,3 +1548,33 @@ v_groupInstanceUnregisterByTime ( } } +void +v_groupInstanceKeyToString( + v_groupInstance _this, + char *keystr, + size_t keystr_size) +{ + v_group group; + c_ulong i, nrOfKeys; + size_t pos = 0; + + assert (keystr_size >= 4); /* for ...\0 */ + + group = v_groupInstanceGroup(_this); + nrOfKeys = c_arraySize(group->keyList); + for (i = 0; i < nrOfKeys; i++) { + c_value v = c_fieldValue(group->keyList[i], _this); + char *vimg = c_valueImage(v); + int n = snprintf(keystr + pos, keystr_size - pos, "%s%s", (i == 0) ? "" : ";", vimg); + c_valueFreeRef(v); + os_free(vimg); + if (n > 0) { pos += (size_t)n; } else { break; } + } + if (i < nrOfKeys || pos >= keystr_size) { + if (pos >= keystr_size - 4) { + pos = keystr_size - 4; + } + strcpy(keystr + pos, "..."); + } +} + diff --git a/src/kernel/code/v_groupQueue.c b/src/kernel/code/v_groupQueue.c index 1669aad43..1cec04c66 100644 --- a/src/kernel/code/v_groupQueue.c +++ b/src/kernel/code/v_groupQueue.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,7 +26,8 @@ #include "v_groupQueueStatistics.h" #include "v_reader.h" #include "v_readerQos.h" -#include "v_observer.h" +#include "v__observer.h" +#include "v__observable.h" #include "v_status.h" #include "v_state.h" #include "v_event.h" @@ -168,12 +170,12 @@ v_groupQueueSetMarker( { assert(C_TYPECHECK(queue,v_groupQueue)); - v_observerLock(v_observer(queue)); + OSPL_LOCK(queue); queue->marker = queue->tail; queue->markerReached = FALSE; - v_observerUnlock(v_observer(queue)); + OSPL_UNLOCK(queue); } void @@ -182,12 +184,12 @@ v_groupQueueResetMarker( { assert(C_TYPECHECK(queue,v_groupQueue)); - v_observerLock(v_observer(queue)); + OSPL_LOCK(queue); queue->marker = NULL; queue->markerReached = FALSE; - v_observerUnlock(v_observer(queue)); + OSPL_UNLOCK(queue); } v_groupAction @@ -198,7 +200,7 @@ v_groupQueueRead( assert(C_TYPECHECK(_this,v_groupQueue)); - v_observerLock(v_observer(_this)); + OSPL_LOCK(_this); if (_this->head) { action = c_keep(_this->head->action); @@ -208,7 +210,7 @@ v_groupQueueRead( } else { action = NULL; } - v_observerUnlock(v_observer(_this)); + OSPL_UNLOCK(_this); return action; } @@ -224,7 +226,7 @@ v_groupQueueTake( action = NULL; - v_observerLock(v_observer(_this)); + OSPL_LOCK(_this); if(_this->head){ if (!_this->markerReached) { @@ -251,7 +253,7 @@ v_groupQueueTake( } } - v_observerUnlock(v_observer(_this)); + OSPL_UNLOCK(_this); return action; } @@ -268,7 +270,7 @@ v_groupQueueWrite( assert(C_TYPECHECK(_this,v_groupQueue)); assert(C_TYPECHECK(action,v_groupAction)); - v_observerLock(v_observer(_this)); + OSPL_LOCK(_this); result = V_WRITE_SUCCESS; @@ -324,7 +326,7 @@ v_groupQueueWrite( action->kind); break; } - v_observerUnlock(v_observer(_this)); + OSPL_UNLOCK(_this); return result; } @@ -338,11 +340,18 @@ v_groupQueueSize( assert(C_TYPECHECK(_this,v_groupQueue)); if(_this){ - v_observerLock(v_observer(_this)); + OSPL_LOCK(_this); size = _this->size; - v_observerUnlock(v_observer(_this)); + OSPL_UNLOCK(_this); } else { size = 0; } return size; } + +v_result +v_groupQueueEnable( + _Inout_ v_groupQueue _this) +{ + return v_groupStreamEnable(v_groupStream(_this)); +} diff --git a/src/kernel/code/v_groupQueueStatistics.c b/src/kernel/code/v_groupQueueStatistics.c index b3f7818c4..89b638de8 100644 --- a/src/kernel/code/v_groupQueueStatistics.c +++ b/src/kernel/code/v_groupQueueStatistics.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/code/v_groupSet.c b/src/kernel/code/v_groupSet.c index b628b39a6..a405ff2f9 100644 --- a/src/kernel/code/v_groupSet.c +++ b/src/kernel/code/v_groupSet.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,12 +18,17 @@ * limitations under the License. * */ +#include "vortex_os.h" #include "v_groupSet.h" #include "v__observable.h" #include "v_entity.h" #include "v__group.h" +#include "v__kernel.h" #include "v_event.h" #include "v_public.h" +#include "v__partition.h" +#include "v_topic.h" +#include "v_configuration.h" #include "c_collection.h" @@ -33,7 +39,6 @@ v_groupSetNew( v_groupSet groupSet; groupSet = v_groupSet(v_objectNew(kernel,K_GROUPSET)); - v_observableInit(v_observable(groupSet)); groupSet->sequenceNumber = 0; groupSet->groups = c_tableNew(v_kernelType(kernel,K_GROUP),"partition,topic"); c_lockInit(c_getBase(groupSet), &groupSet->lock); @@ -60,6 +65,40 @@ alwaysFalse( } +static c_bool +getGidKeyPolicy ( + v_topic topic, + v_partition partition) +{ + v_configuration config; + v_cfElement root; + v_cfElement element; + c_iter iter; + c_value gidkeyValue; + c_bool gidkey = FALSE; + os_size_t size; + os_char *str; + + config = v_getConfiguration(v_objectKernel(topic)); + if(config) { + root = v_configurationGetRoot(config); + /* Iterate over all TopicAccess elements */ + iter = v_cfElementXPath(root, "Domain/GIDKey"); + while((element = v_cfElement(c_iterTakeFirst(iter))) != NULL && !gidkey) { + gidkeyValue = v_cfElementAttributeValue(element, "groups"); + size = strlen(v_partitionName(partition)) + strlen(v_topicName(topic)) + 2; + str = os_malloc(size); + sprintf(str, "%s.%s", v_partitionName(partition), v_topicName(topic)); + if (gidkeyValue.kind == V_STRING) { + gidkey = v_partitionStringMatchesExpression(str, gidkeyValue.is.String); + } + os_free(str); + } + c_iterFree(iter); + } + return gidkey; +} + v_group v_groupSetCreate( v_groupSet set, @@ -67,9 +106,10 @@ v_groupSetCreate( v_topic topic) { v_group group, found; - C_STRUCT(v_event) event; v_kernel kernel; C_STRUCT(v_group) dummyGroup; + C_STRUCT(v_event) event; + c_bool gidkey; assert(set != NULL); assert(partition != NULL); @@ -78,6 +118,7 @@ v_groupSetCreate( assert(C_TYPECHECK(partition,v_partition)); assert(C_TYPECHECK(topic,v_topic)); + gidkey = getGidKeyPolicy(topic, partition); c_lockWrite(&set->lock); /* First create a dummy group used for checking existence */ memset(&dummyGroup, 0, sizeof(dummyGroup)); @@ -85,14 +126,17 @@ v_groupSetCreate( dummyGroup.topic = topic; /* Note: the following call does not execute the actual remove because - * the alwaysFalse function returns FALSE */ + * the alwaysFalse function returns FALSE + */ found = NULL; + group = NULL; /* Note: The alwaysFalse function increases the refCount of - * found, which is the out-parameter of the tableRemove. */ + * found, which is the out-parameter of the tableRemove. + */ c_tableRemove(set->groups, &dummyGroup, alwaysFalse, &found); if (!found) { - group = v_groupNew(partition, topic, set->sequenceNumber); + group = v_groupNew(partition, topic, set->sequenceNumber, gidkey); found = c_tableInsert(set->groups,group); /* Because understanding assertion holds true, we practically * transferred the refCount from group to found. Because found @@ -101,17 +145,16 @@ v_groupSetCreate( assert(found == group); set->sequenceNumber++; kernel = v_objectKernel(set); - - c_lockUnlock(&set->lock); - - /* Update the status of the observers */ - /* And trigger the waiting observers */ + } + c_lockUnlock(&set->lock); + if (group) { + v_kernelConnectGroup(kernel, group); + /* Update the status of the observers and trigger the waiting observers */ event.kind = V_EVENT_NEW_GROUP; event.source = v_observable(kernel); event.data = group; - v_observableNotify(v_observable(kernel),&event); - } else { - c_lockUnlock(&set->lock); + event.handled = TRUE; + OSPL_THROW_EVENT(kernel,&event); } return found; diff --git a/src/kernel/code/v_groupStore.c b/src/kernel/code/v_groupStore.c new file mode 100644 index 000000000..3b9d7b42d --- /dev/null +++ b/src/kernel/code/v_groupStore.c @@ -0,0 +1,758 @@ +/* + * OpenSplice DDS + * + * This software and documentation are Copyright 2006 to TO_YEAR PrismTech + * Limited, its affiliated companies and licensors. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#include "v__groupStore.h" +#include "v__groupInstance.h" +#include "v__group.h" +#include "v__kernel.h" +#include "v__topic.h" +#include "v_kernelParser.h" +#include "v_public.h" +#include "v_message.h" +#include "v_messageQos.h" +#include "q_helper.h" +#include "c_base.h" +#include "vortex_os.h" +#include "os_report.h" + +C_STRUCT(v_groupStoreQuery) { + c_array instanceQ; + c_array sampleQ; + void *userData; +}; + +v_groupStore +v_groupStoreNew( + const v_group group, + const c_char *keyExpr, + const c_array messageKeyList) +{ + v_groupStore store; + v_kernel kernel; + c_base base; + + base = c_getBase(group); + kernel = v_objectKernel(group); + + store = c_new(v_kernelType(kernel,K_GROUPSTORE)); + (void)c_mutexInit(base, &store->mutex); + store->group = group; /* (void *) backref */ + store->instances = c_tableNew(group->instanceType,keyExpr); + store->messageKeyList = c_keep(messageKeyList); + store->readid = 0; + return store; +} + +static c_bool +instanceFree ( + c_object o, + c_voidp arg) +{ + OS_UNUSED_ARG(arg); + v_groupInstanceFree(v_groupInstance(o)); + return TRUE; +} + +void +v_groupStoreDeinit( + const v_groupStore _this) +{ + assert(_this != NULL); + assert(C_TYPECHECK(_this,v_groupStore)); + + c_mutexLock(&_this->mutex); + (void)c_tableWalk(_this->instances,instanceFree,NULL); + c_mutexUnlock(&_this->mutex); +} + +static c_bool +alwaysFalse( + c_object found, + c_object requested, + c_voidp arg) +{ + v_groupInstance *instance = (v_groupInstance *)arg; + + OS_UNUSED_ARG(requested); + assert(instance != NULL); + assert(*instance == NULL); /* out param */ + + *instance = c_keep(found); + + return FALSE; +} + +static v_groupInstance +lookupInstance( + v_groupStore _this, + v_message msg) +{ + v_groupInstance instance = NULL; + c_value _keyValues[32]; + c_value *keyValues = _keyValues; + + if (_this->gidkey) { + C_STRUCT(v_groupInstanceGID) template; + template.gid = msg->writerInstanceGID; + /* Note: The alwaysFalse function increases the refCount of + * found, which is the out-parameter of the tableRemove. + */ + c_tableRemove(_this->instances, &template, alwaysFalse, &instance); + } else { + c_ulong i, nrOfKeys; + + nrOfKeys = c_arraySize(_this->messageKeyList); + if (nrOfKeys > 32) { + keyValues = os_malloc(sizeof(c_value) * nrOfKeys); + } + for (i=0;imessageKeyList[i], msg); + } + instance = c_tableFind(_this->instances, &keyValues[0], nrOfKeys); + /* Key values have to be freed again */ + for (i=0;i 32) { + os_free(keyValues); + } + } + return instance; +} + +v_groupInstance +v_groupStoreLookupInstance( + const v_groupStore _this, + const v_message msg) +{ + v_groupInstance instance = NULL; + c_mutexLock(&_this->mutex); + instance = lookupInstance(_this, msg); + c_mutexUnlock(&_this->mutex); + return instance; +} + +v_groupInstance +v_groupStoreCreateInstance( + const v_groupStore _this, + const v_message msg) +{ + v_groupInstance instance; + + c_mutexLock(&_this->mutex); + instance = lookupInstance(_this, msg); + if (instance == NULL) { + v_groupInstance found; + instance = v_groupInstanceNew(_this->group, msg); + found = c_tableInsert(_this->instances, instance); + assert(found == instance); + OS_UNUSED_ARG(found); + } + c_mutexUnlock(&_this->mutex); + + return instance; +} + +void +v_groupStoreDispose( + const v_groupStore _this, + const v_groupInstance instance) +{ + assert(_this != NULL); + assert(C_TYPECHECK(_this,v_groupStore)); + OS_UNUSED_ARG(instance); + c_mutexLock(&_this->mutex); + c_mutexUnlock(&_this->mutex); +} + +void +v_groupStoreDelete( + const v_groupStore _this, + const v_groupInstance instance) +{ + v_groupInstance removed; + + c_mutexLock(&_this->mutex); + removed = c_remove(_this->instances,instance,NULL,NULL); + c_mutexUnlock(&_this->mutex); + /* It is allowed that the instance is already taken and + * no longer exists in the group->instances set. + */ + if (removed) { + v_groupInstanceFree(removed); + } +} + +void +v_groupStoreWalk( + const v_groupStore _this, + const c_action action, + const c_voidp arg) +{ + assert(_this != NULL); + assert(C_TYPECHECK(_this,v_groupStore)); + + c_mutexLock(&_this->mutex); + (void)c_tableWalk(_this->instances,action,arg); + c_mutexUnlock(&_this->mutex); +} + +c_iter +v_groupStoreSelect( + const v_groupStore _this, + const os_uint32 max) +{ + c_iter list; + + assert(_this != NULL); + assert(C_TYPECHECK(_this,v_groupStore)); + + c_mutexLock(&_this->mutex); + list = ospl_c_select(_this->instances, (c_long)max); + c_mutexUnlock(&_this->mutex); + + return list; +} + +static c_bool +markGroupInstance(c_object o, c_voidp arg) +{ + v_groupInstance instance = v_groupInstance(o); + c_ulong *flags = (c_ulong *)arg; + + v_stateSet(instance->state, *flags); + return TRUE; +} + +/* Set the specified flags for all DataReader instance states associated + * with the specified group. + */ +void +v_groupStoreMarkGroupInstanceStates ( + const v_groupStore _this, + c_ulong flags) +{ + c_mutexLock(&_this->mutex); + (void)c_tableWalk(_this->instances,markGroupInstance,&flags); + c_mutexUnlock(&_this->mutex); +} + +static c_bool +unmarkGroupInstance(c_object o, c_voidp arg) +{ + v_groupInstance instance = v_groupInstance(o); + c_ulong *flags = (c_ulong *)arg; + + v_stateClear(instance->state, *flags); + return TRUE; +} + +/* Set the specified flags for all DataReader instance states associated + * with the specified group. + */ +void +v_groupStoreUnmarkGroupInstanceStates ( + const v_groupStore _this, + c_ulong flags) +{ + assert(C_TYPECHECK(_this,v_groupStore)); + + if (flags != 0) { + c_mutexLock(&_this->mutex); + (void)c_tableWalk(_this->instances, unmarkGroupInstance, &flags); + c_mutexUnlock(&_this->mutex); + } +} + +c_array +v_groupStoreKeyList( + const v_groupStore _this) +{ + return c_tableKeyList(_this->instances); +} + +static q_expr +resolveField( + c_type instanceType, + const c_char *name) +{ + c_field field; + c_array path; + c_ulong i, length; + q_list list; + c_string str; + c_char *fieldName; + q_expr expr; + + field = c_fieldNew(instanceType,name); + if (!field) { + fieldName = os_alloca(strlen(name) + strlen("newest.message.userData.") + 1); + os_sprintf(fieldName,"newest.%s",name); + field = c_fieldNew(instanceType,fieldName); + + if (!field) { + os_sprintf(fieldName,"newest.message.%s",name); + field = c_fieldNew(instanceType,fieldName); + if (!field) { + os_sprintf(fieldName,"newest.message.userData.%s",name); + field = c_fieldNew(instanceType,fieldName); + } + } + os_freea(fieldName); + } + if (field) { + path = c_fieldPath(field); + length = c_arraySize(path); + list = NULL; + i = length; + while (i-- > 0) { + str = c_metaName(path[i]); + list = q_insert(list,q_newId(str)); + c_free(str); + } + c_free(field); + expr = q_newFnc(Q_EXPR_PROPERTY,list); + } else { + expr = NULL; + } + return expr; +} + +static c_bool +resolveFields ( + c_type type, + q_expr e) +{ + /* search fields in result, data or info type. */ + + q_expr p; + c_long i; + c_char *name; + + switch(q_getKind(e)) { + case T_FNC: + switch(q_getTag(e)) { + case Q_EXPR_PROPERTY: + name = q_propertyName(e); + p = resolveField(type,name); + if (p == NULL) { + OS_REPORT(OS_ERROR, "v_groupStoreQueryNew failed", + V_RESULT_ILL_PARAM, "Parsing query expression failed: " + "field '%s' is undefined for type '%s'", + name, c_metaName(c_metaObject(type))); + os_free(name); + return FALSE; + } + os_free(name); + q_swapExpr(e,p); + q_dispose(p); + break; + default: /* process sub-expression */ + i=0; + while ((p = q_getPar(e,i)) != NULL) { + if (!resolveFields(type,p)) { + return FALSE; + } + i++; + } + } + break; + case T_ID: + name = q_getId(e); + p = resolveField(type,name); + if (p == NULL) { + OS_REPORT(OS_ERROR, "v_groupStoreQueryNew failed", + V_RESULT_ILL_PARAM, "Parsing query expression failed: field '%s' "\ + "is undefined for type '%s'", + name, c_metaName(c_metaObject(type))); + return FALSE; + } else { + q_swapExpr(e,p); + q_dispose(p); + } + break; + default: + break; + } + return TRUE; +} + +#define PREFIX "newest.message" +static c_array +createKeyList( + c_type instanceType, + c_array keyList) +{ + c_ulong size, i; + c_array newKeyList = NULL; + + assert(instanceType); + + if(keyList){ + size = c_arraySize(keyList); + + newKeyList = c_arrayNew(c_field_t(c_getBase(instanceType)), size); + + if(newKeyList){ + for(i = 0; iinstanceQ) { + c_free(_this->instanceQ); + } + if (_this->sampleQ) { + c_free(_this->sampleQ); + } + os_free(_this); +} + +v_groupStoreQuery +v_groupStoreQueryNew( + const v_groupStore _this, + const os_char *expression, + const c_value params[], + const os_uint32 nrOfParams) +{ + v_groupStoreQuery query; + c_bool result = TRUE; + q_expr progExpr, e, subExpr, keyExpr; + c_ulong i,len; + c_iter list; + c_type type, c_query_t; + c_array keyList; + q_expr predicate; + + assert(_this != NULL); + assert(C_TYPECHECK(_this,v_groupStore)); + + if (expression == NULL) { + return NULL; + } + predicate = v_parser_parse(expression); + if (!predicate) { + OS_REPORT(OS_ERROR, "DataReader SQL Parser", + V_RESULT_ILL_PARAM, "Parse Query expression failed. Query: \"%s\"", + expression); + return NULL; + } + + if (q_getLastVar(predicate) > nrOfParams) { + q_dispose(predicate); + OS_REPORT(OS_ERROR, "DataReader SQL Parser", + V_RESULT_ILL_PARAM, "Query parameter count mismatch. Query: \"%s\"", + expression); + return NULL; + } + + c_mutexLock(&_this->mutex); + + query = os_malloc(C_SIZEOF(v_groupStoreQuery)); + query->instanceQ = NULL; + query->sampleQ = NULL; + query->userData = NULL; + + e = q_takePar(predicate,0); + type = c_subType(_this->instances); + if (!resolveFields(type,e)) { + q_dispose(e); + result = FALSE; + } else { + /* Normalize the query to the disjunctive form. */ + q_disjunctify(e); + e = q_removeNots(e); + + list = q_exprDeOr(e,NULL); + len = c_iterLength(list); + + c_query_t = c_resolve(c_getBase(c_object(v_objectKernel(_this->group))),"c_query"); + + query->instanceQ = c_arrayNew(c_query_t,len); + query->sampleQ = c_arrayNew(c_query_t,len); + c_free(c_query_t); + + keyList = createKeyList(type, _this->messageKeyList); + + for (i=0;iinstanceQ[i] = c_queryNew(_this->instances, progExpr, params); + q_dispose(progExpr); + + if (query->instanceQ[i] == NULL) { + OS_REPORT(OS_ERROR, "calculateCondition failed", + V_RESULT_ILL_PARAM, "error in query expression"); + result = FALSE; + } + } else { + query->instanceQ[i] = NULL; + } + if (subExpr != NULL) { + progExpr = F1(Q_EXPR_PROGRAM,subExpr); + query->sampleQ[i] = c_queryNew(_this->instances, progExpr, params); + q_dispose(progExpr); + + if (query->sampleQ[i] == NULL) { + OS_REPORT(OS_ERROR, "calculateCondition failed", + V_RESULT_ILL_PARAM, "error in query expression"); + result = FALSE; + } + } else { + query->sampleQ[i] = NULL; + } + } + c_iterFree(list); + c_free(keyList); + } + c_mutexUnlock(&_this->mutex); + + q_dispose(predicate); + + if (!result){ + v_groupStoreQueryFree(query); + query = NULL; + } + return query; +} + +v_groupStoreQuery +v_groupStoreQueryNew2( + const v_groupStore _this, + const os_char *expression, + const os_char *params[], + const os_uint32 nrOfParams) +{ + c_value values[100]; /* maximum number of parameters */ + os_uint32 i; + + /* The dds specification prescribes a max parameter number of 99 */ + assert(nrOfParams<100); + for (i=0; imessage->writeTime; + if (!OS_TIMEW_ISINVALID(begin)) { + if (os_timeWCompare(begin, writeTime) == OS_MORE) { + pass = FALSE; /* produced before begin of period */ + } + } + if (pass && !OS_TIMEW_ISINVALID(end)) { + if (os_timeWCompare(end, writeTime) == OS_LESS) { + pass = FALSE; /* produced after end of period */ + } + } + return pass; +} + +static c_bool +checkTransientLocal( + v_groupSample sample) +{ + v_message vmessage; + v_groupInstance instance; + v_registration reg; + c_bool pass = TRUE; + + vmessage = v_groupSampleTemplate(sample)->message; + if ( (v_messageQos_durabilityKind(vmessage->qos) == V_DURABILITY_TRANSIENT_LOCAL) ) { + /* check if the sample is registered; if so, the writer is alive */ + instance = v_groupInstance(sample->instance); + reg = instance->registrations; + pass = FALSE; + while ( (reg != NULL) && ! pass ) { + if ( v_gidCompare(reg->writerGID,vmessage->writerInstanceGID) == C_EQ) { + pass = TRUE; + } else { + reg = reg->next; + } + } + } + return pass; +} + +static c_bool +walkMatchingSamples( + c_object obj, + c_voidp args) +{ + struct readArg *arg = (struct readArg *)args; + v_groupStoreQuery query; + c_ulong len, i; + v_groupSample firstSample, sample; + c_bool pass, proceed; + v_groupInstance instance; + + query = arg->query; + instance = (v_groupInstance)obj; + + proceed = TRUE; + + if (v_stateTest(instance->state, L_EMPTY)) { + return proceed; + } + /* only walk in case the instance queue is not empty */ + if (query) { + len = c_arraySize(query->instanceQ); + for (i=0; (iinstanceQ[i]) { + pass = c_queryEval(query->instanceQ[i],instance); + } else { + pass = TRUE; + } + if (pass) { /* instance matches query*/ + /* Since history is 'replayed' here, the oldest sample should be + * processed first. We keep a reference to the first sample and + * set the current sample to the tail of the instance (oldest). + */ + firstSample = v_groupInstanceHead(instance); + sample = v_groupInstanceTail(instance); + while ((sample != NULL) && proceed) { + /* if len > 1 then expression contains OR meaning that multiple queries + * are executed and results are joined, so samples can be selected multiples times, + * therefore check if not already inserted. + */ + if (len == 1 || sample->readid != arg->readid) { + sample->readid = arg->readid; + /* prevent aligning local-transient data without alive writers */ + pass = checkTransientLocal(sample); + if (pass) { + /* prevent aligning data outside request period */ + pass = checkConditionPeriod(sample, arg->begin, arg->end); + } + if (pass && query->sampleQ[i]) { + /* Evaluate non key query part */ + if (sample == firstSample) { + pass = c_queryEval(query->sampleQ[i], instance); + } else { + /* Swap sample with first sample during query evaluation since + * it only addresses first sample. + */ + v_groupInstanceSetHeadNoRefCount(instance,sample); + pass = c_queryEval(query->sampleQ[i], instance); + v_groupInstanceSetHeadNoRefCount(instance,firstSample); + } + } + if (pass) { + proceed = arg->action(sample, arg->actionArg); + } + } + sample = sample->newer; + } + } + } + } else { + sample = v_groupInstanceTail(instance); + while ((sample != NULL) && proceed) { + /* prevent aligning local-transient data without alive writers */ + pass = checkTransientLocal(sample); + if (pass) { + /* prevent aligning data outside request period */ + pass = checkConditionPeriod(sample, arg->begin, arg->end); + } + if (pass) { + proceed = arg->action(sample, arg->actionArg); + } + sample = sample->newer; + } + } + return proceed; +} + +v_result +v_groupStoreRead( + const v_groupStore _this, + const v_groupStoreQuery query, + const v_groupStoreAction action, + const void *actionArg) +{ + struct readArg arg; + + arg.query = query; + arg.begin = OS_TIMEW_INVALID; + arg.end = OS_TIMEW_INVALID; + arg.action = action; + arg.actionArg = actionArg; + arg.readid = _this->readid++; + arg.result = V_RESULT_OK; + + c_mutexLock(&_this->mutex); + (void)c_tableWalk(_this->instances,walkMatchingSamples,&arg); + c_mutexUnlock(&_this->mutex); + + return arg.result; +} + +c_query +v_groupStore_create_query( + const v_groupStore _this, + const q_expr expr, + const c_value *params) +{ + c_query query; + c_mutexLock(&_this->mutex); + query = c_queryNew(_this->instances, expr, params); + c_mutexUnlock(&_this->mutex); + return query; +} diff --git a/src/kernel/code/v_groupStream.c b/src/kernel/code/v_groupStream.c index 61a74c2e3..c0a0a2a8a 100644 --- a/src/kernel/code/v_groupStream.c +++ b/src/kernel/code/v_groupStream.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -32,6 +33,7 @@ #include "v_group.h" #include "v_groupSet.h" #include "v__observable.h" +#include "v_messageQos.h" #include "c_iterator.h" #include "c_collection.h" #include "os_report.h" @@ -124,13 +126,13 @@ v_groupStreamConnectNewGroups( v_group group) { struct groupConnected data; + c_bool connected = FALSE; assert(stream != NULL); assert(C_TYPECHECK(stream,v_groupStream)); - v_observerLock(v_observer(stream)); + OSPL_LOCK(stream); - /* - * This means the group is interesting for this + /* This means the group is interesting for this * groupActionStream. Now I have to check if the stream is already * connected to this group, because we wouldn't want to connect * multiple times to one single group. @@ -144,11 +146,11 @@ v_groupStreamConnectNewGroups( /* * The stream is not connected to the group yet, so connect now. */ - v_groupStreamSubscribeGroup(stream, group); + connected = v_groupStreamSubscribeGroup(stream, group); } - v_observerUnlock(v_observer(stream)); + OSPL_UNLOCK(stream); - if(data.connected == FALSE){ + if(connected == TRUE){ v_groupStreamHistoricalData(group, stream); } @@ -162,6 +164,7 @@ void v_groupStreamNotifyDataAvailable( v_groupStream stream) { + C_STRUCT(v_event) event; /* This Notify method is part of the observer-observable pattern. * It is designed to be invoked when _this object as observer receives * an event from an observable object. @@ -169,20 +172,21 @@ v_groupStreamNotifyDataAvailable( * calling Notify(_this, event, userData). * This implies that _this cannot be locked within any Notify method * to avoid deadlocks. - * For consistency _this must be locked by v_observerLock(_this) before + * For consistency _this must be locked by OSPL_LOCK(_this) before * calling this method. */ - C_STRUCT(v_event) event; - assert(stream != NULL); assert(C_TYPECHECK(stream,v_groupStream)); v_statusNotifyDataAvailable(v_entity(stream)->status); + event.kind = V_EVENT_DATA_AVAILABLE; event.source = v_observable(stream); event.data = NULL; - v_observableNotify(v_observable(stream), &event); + event.handled = TRUE; + + OSPL_THROW_EVENT(stream, &event); return; } @@ -214,11 +218,12 @@ v_groupStreamInit( kernel = v_objectKernel(subscriber); stream->groups = c_setNew(v_kernelType(kernel,K_GROUP)); - stream->expr = c_listNew(c_resolve(c_getBase(stream), "::c_string")); + stream->expr = c_listNew(c_string_t(c_getBase(stream))); c_iterWalk(expr, fillExprList, stream->expr); - v_readerInit(v_reader(stream), name, subscriber, qos, TRUE); + v_readerInit(v_reader(stream), name, subscriber, qos); (void)v_subscriberAddReader(subscriber,v_reader(stream)); + (void)v_entityEnable(v_entity(stream)); } void @@ -254,12 +259,13 @@ v_groupStreamFree( v_readerFree(v_reader(stream)); } -c_bool +static c_bool v_groupStreamSubscribe( v_groupStream stream, v_partition partition) { c_iter list; + c_iter connected = NULL; v_kernel kernel; c_value params[1]; v_group group; @@ -269,32 +275,65 @@ v_groupStreamSubscribe( kernel = v_objectKernel(v_entity(partition)); params[0] = c_objectValue(partition); list = v_groupSetSelect(kernel->groupSet,"partition = %0 ",params); - group = c_iterTakeFirst(list); - while (group != NULL) { - v_groupStreamSubscribeGroup(stream, group); - c_free(group); - group = c_iterTakeFirst(list); + if (c_iterLength(list) > 0) { + v_observerLock(v_observer(stream)); + while ((group = c_iterTakeFirst(list)) != NULL) { + if (v_groupStreamSubscribeGroup(stream, group)) { + connected = c_iterAppend(connected, c_keep(group)); + } + c_free(group); + } + v_observerUnlock(v_observer(stream)); + c_iterFree(list); + + while ((group = c_iterTakeFirst(connected)) != NULL) { + v_groupStreamHistoricalData(group, stream); + c_free(group); + } + c_iterFree(connected); } - c_iterFree(list); return TRUE; } +v_result +v_groupStreamEnable( + _Inout_ v_groupStream _this) +{ + v_subscriber subscriber; + v_result result = V_RESULT_OK; + c_iter list; + v_partition partition; + + subscriber = v_subscriber(v_reader(_this)->subscriber); + + /* A groupQueue cannot be enabled if the subscriber is disabled */ + if(v_entityDisabled(v_entity(subscriber))) { + return V_RESULT_PRECONDITION_NOT_MET; + } + list = v_subscriberLookupPartitions(subscriber, "*"); + while ((partition = c_iterTakeFirst(list)) != NULL) { + v_groupStreamSubscribe(_this, partition); + c_free(partition); + } + c_iterFree(list); + return result; +} + c_bool v_groupStreamSubscribeGroup( v_groupStream stream, v_group group) { - c_bool inserted; + c_bool inserted = FALSE; assert(C_TYPECHECK(stream, v_groupStream)); assert(C_TYPECHECK(group, v_group)); if (v_reader(stream)->qos->durability.v.kind == v_topicQosRef(group->topic)->durability.v.kind) { struct groupMatched data; - /* - * OSPL-1073: Check if the new group matches with the group-expression list. This + /* Check if the new group matches with the group-expression list. This * is a collection of partition.topic strings that allows users to connect to specific * topics rather than connecting to all topics within a partition. */ @@ -313,7 +352,7 @@ v_groupStreamSubscribeGroup( } } } - return TRUE; + return inserted; } c_bool @@ -333,8 +372,7 @@ v_groupStreamUnSubscribe( result = FALSE; while (group != NULL) { - if(strcmp(v_partitionName(partition), - v_partitionName(group->partition)) == 0){ + if (group->partition == partition) { result = v_groupStreamUnSubscribeGroup(stream, group); } c_free(group); @@ -372,6 +410,7 @@ v_groupStreamWrite( v_groupAction action) { v_writeResult result; + v_readerQos qos; assert(C_TYPECHECK(stream,v_groupStream)); assert(C_TYPECHECK(action, v_groupAction)); @@ -380,7 +419,13 @@ v_groupStreamWrite( switch(v_objectKind(stream)){ case K_GROUPQUEUE: - result = v_groupQueueWrite(v_groupQueue(stream), action); + qos = v_readerGetQos(v_reader(stream)); + if ((action->message == NULL) || + (action->message->qos == NULL) || + (v_messageQos_durabilityKind(action->message->qos) >= qos->durability.v.kind)) { + result = v_groupQueueWrite(v_groupQueue(stream), action); + } + c_free(qos); break; default: OS_REPORT(OS_CRITICAL,"v_groupStreamWrite",result, diff --git a/src/kernel/code/v_handle.c b/src/kernel/code/v_handle.c index 382c8648d..12770f0d7 100644 --- a/src/kernel/code/v_handle.c +++ b/src/kernel/code/v_handle.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -45,9 +46,7 @@ */ #define COL(index) ((index) / NROFROW) #define ROW(index) ((index) % NROFROW) -/* - * This macro specifies the non zero value as first serial value. - */ +/* This macro specifies the non zero value as first serial value. */ #define MAX_SERIAL (0x00ffffff) const v_handle V_HANDLE_NIL = {0, 0, 0}; @@ -103,7 +102,13 @@ v_handleServerNew ( "kernel::v_handle::v_handleServerNew",V_RESULT_INTERNAL_ERROR, "Failed to allocate handle info records"); } else { - c_mutexInit(c_getBase(server), &server->mutex); + if (c_mutexInit(c_getBase(server), &server->mutex) != SYNC_RESULT_SUCCESS) { + c_free(server); + server = NULL; + OS_REPORT(OS_FATAL, + "kernel::v_handle::v_handleServerNew",V_RESULT_INTERNAL_ERROR, + "Failed to initialize mutex for server"); + } } } else { c_free(server); @@ -277,7 +282,8 @@ v_handleServerRegister( info = fresh_info_from_idx(server, idx); } else if (server->freeListLength < NROFROW && COL(server->lastIndex) < NROFCOL-1) { /* Free list is getting short, but we can add another column (this also - covers the case of an empty freelist) */ + * covers the case of an empty freelist) + */ assert(ROW(server->lastIndex) == NROFROW - 1); idx = ++server->lastIndex; if ((info = fresh_info_from_new_column(server, idx)) == NULL) { @@ -301,10 +307,11 @@ v_handleServerRegister( info->object_nextFree = (c_address) c_keep(o); /* memory barrier here will ensure that any accidental - handleClaim (we haven't advertised the handle, but in case - somehow it gets fed random garbage) will fail because - status_count still has ON_FREELIST set until object_nextFree - properly points to the object. */ + * handleClaim (we haven't advertised the handle, but in case + * somehow it gets fed random garbage) will fail because + * status_count still has ON_FREELIST set until object_nextFree + * properly points to the object. + */ pa_fence (); pa_st32 (&info->status_count_index, 0); @@ -382,9 +389,10 @@ release_int ( c_ulong idx) { /* GCC atomic builtins imply barriers => whatever had been done - before release_int will be visible in time. v_handleDeregister - marks the handle as DEREGISTERING and relies on release_int to - put it on the freelist and dispose the object */ + * before release_int will be visible in time. v_handleDeregister + * marks the handle as DEREGISTERING and relies on release_int to + * put it on the freelist and dispose the object + */ assert (!(pa_ld32 (&info->status_count_index) & STATUS_ON_FREELIST)); if (pa_dec32_nv (&info->status_count_index) == STATUS_DEREGISTERING) { free_handle (server, info, idx); @@ -403,8 +411,9 @@ claim_int ( status_count = pa_ld32 (&info->status_count_index); if (status_count & (STATUS_DEREGISTERING | STATUS_ON_FREELIST)) { /* can't trust serials unless we first lock server->mutex, but - then again, who cares whether it is EXPIRED or INVALID - anyway? */ + * then again, who cares whether it is EXPIRED or INVALID + * anyway? + */ return V_HANDLE_EXPIRED; } else { c_ulong new_status_count = status_count + 1; @@ -418,8 +427,9 @@ claim_int ( return V_HANDLE_OK; } else { /* Incremented refcount, but for the wrong handle => decide - whether it is expired or illegal, then immediately release - it */ + * whether it is expired or illegal, then immediately release + * it + */ v_handleResult result = (handle.serial < info->serial && handle.serial != 0) ? V_HANDLE_EXPIRED : V_HANDLE_ILLEGAL; release_int (server, info, handle.index); return result; @@ -490,9 +500,10 @@ v_handleRelease ( } /* It must be claimed, therefore the serial can't change and must - match ... Now what if it wasn't claimed? There's no guarantee - whatsoever that an issue will be caught, but do some assertions - anyway. */ + * match ... Now what if it wasn't claimed? There's no guarantee + * whatsoever that an issue will be caught, but do some assertions + * anyway. + */ assert ((pa_ld32 (&info->status_count_index) & STATUS_COUNT_INDEX_MASK) > 0); assert (!(pa_ld32 (&info->status_count_index) & STATUS_ON_FREELIST)); assert (handle.serial == info->serial); diff --git a/src/kernel/code/v_historicalDataRequest.c b/src/kernel/code/v_historicalDataRequest.c index 6e6a9b32e..9c5251178 100644 --- a/src/kernel/code/v_historicalDataRequest.c +++ b/src/kernel/code/v_historicalDataRequest.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/code/v_index.c b/src/kernel/code/v_index.c index e195f15d5..d474f07e5 100644 --- a/src/kernel/code/v_index.c +++ b/src/kernel/code/v_index.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -354,8 +355,6 @@ v_indexInit( index->objectType = c_keep(instanceType); } -/*#define prefix "sample.message.userData."*/ - v_index v__indexNew( v_dataReader reader, @@ -423,10 +422,15 @@ v__indexNew( c_free(instanceType); if (index != NULL) { - if (action != NULL) { - action(index, topic, arg); + if (action != NULL && !action(index, topic, arg)) { + OS_REPORT(OS_ERROR, + "v_indexNew", V_RESULT_INTERNAL_ERROR, + "v_indexNewAction failed!"); + c_free(index); + index = NULL; + } else { + (void)c_iterAppend(indexList, index); } - (void)c_iterAppend(indexList, index); } } } else { diff --git a/src/kernel/code/v_index.h b/src/kernel/code/v_index.h index e1018b78a..481b9550a 100644 --- a/src/kernel/code/v_index.h +++ b/src/kernel/code/v_index.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -42,7 +43,7 @@ #define v_indexDataReader(_this) \ v_dataReader(v_index(_this)->reader) -typedef void (*v_indexNewAction)(v_index index, v_topic topic, c_voidp arg); +typedef c_bool (*v_indexNewAction)(v_index index, v_topic topic, c_voidp arg); v_index v_indexNew( diff --git a/src/kernel/code/v_instance.c b/src/kernel/code/v_instance.c index 16ef16001..567c8688d 100644 --- a/src/kernel/code/v_instance.c +++ b/src/kernel/code/v_instance.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -38,6 +39,7 @@ v_instanceInit( v_publicInit(v_public(_this)); _this->state = L_EMPTY | L_NOWRITERS; _this->entity = (c_voidp)entity; + _this->userData = NULL; } void @@ -50,3 +52,22 @@ v_instanceDeinit( v_publicDeinit(v_public(_this)); } +c_voidp +v_instanceSetUserData( + v_instance _this, + c_voidp userData) +{ + c_voidp oldData; + + oldData = _this->userData; + _this->userData = userData; + return oldData; +} + +c_voidp +v_instanceGetUserData( + v_instance _this) +{ + return _this->userData; +} + diff --git a/src/kernel/code/v_kernel.c b/src/kernel/code/v_kernel.c index ad7c30a95..b45b24a1f 100644 --- a/src/kernel/code/v_kernel.c +++ b/src/kernel/code/v_kernel.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,6 +26,7 @@ #include "v__observable.h" #include "v__entity.h" #include "v__participant.h" +#include "v__service.h" #include "v_partition.h" #include "v_publisher.h" #include "v_subscriber.h" @@ -35,10 +37,12 @@ #include "v_dataReaderEntry.h" #include "v_serviceManager.h" #include "v_groupSet.h" +#include "v__groupStore.h" #include "v__group.h" #include "v_status.h" #include "v_handle.h" #include "v_dataReader.h" +#include "v_dataView.h" #include "v__topic.h" #include "v_topicQos.h" #include "v_publisherQos.h" @@ -60,7 +64,7 @@ #include "v__policy.h" #include "v__partition.h" #include "v_instance.h" -#include "v_dataViewSample.h" +#include "v__dataViewSample.h" #include "v_typeRepresentation.h" #include "sd_serializer.h" #include "sd_serializerXMLTypeinfo.h" @@ -68,6 +72,7 @@ #include "v__processInfo.h" #include "v__threadInfo.h" #include "v_service.h" +#include "v_networking.h" #include "v_messageQos.h" #include "ut_trace.h" #include "os_atomics.h" @@ -136,11 +141,13 @@ v_new( return o; } - +_Check_return_ +_Ret_notnull_ +_Pre_satisfies_(kind >= K_KERNEL && kind < K_TYPECOUNT) v_object v_objectNew( - v_kernel kernel, - v_kind kind) + _In_ v_kernel kernel, + _In_ v_kind kind) { v_object o; @@ -153,10 +160,12 @@ v_objectNew( return o; } +_Check_return_ +_Ret_maybenull_ v_object v_objectNew_s( - v_kernel kernel, - v_kind kind) + _In_ v_kernel kernel, + _In_ v_kind kind) { v_object o; @@ -171,93 +180,136 @@ v_objectNew_s( return o; } -char * +_Ret_z_ +const char * v_objectKindImage( - v_object _this) + _In_ v_object _this) { +#define _CASE_(o) case o: return #o; break; switch (v_objectKind(_this)) { - case K_DATAREADER: - return "K_DATAREADER"; - break; - case K_WRITER: - return "K_WRITER"; - break; - case K_PUBLISHER: - return "K_PUBLISHER"; - break; - case K_SUBSCRIBER: - return "K_SUBSCRIBER"; - break; - case K_PARTICIPANT: - return "K_PARTICIPANT"; - break; - case K_SPLICED: - return "K_SPLICED"; - break; - case K_TOPIC: - return "K_TOPIC"; - break; - case K_TOPIC_ADAPTER: - return "K_TOPIC_ADAPTER"; - break; - case K_TYPEREPRESENTATION: - return "K_TYPEREPRESENTATION"; - break; - case K_STATUSCONDITION: - return "STATUSCONDITION"; - break; - case K_KERNEL: - return "K_KERNEL"; - break; - case K_WAITSET: - return "K_WAITSET"; - break; - case K_LISTENER: - return "K_LISTENER"; - break; - case K_DATAREADERQUERY: - return "K_DATAREADERQUERY"; - break; - case K_DATAVIEW: - return "K_DATAVIEW"; - break; - case K_DOMAIN: - return "K_DOMAIN"; - break; - case K_SERVICE: - return "K_SERVICE"; - break; - case K_CMSOAP: - return "K_CMSOAP"; - break; - case K_NETWORKING: - return "K_NETWORKING"; - break; - case K_DURABILITY: - return "K_DURABILITY"; - break; - case K_NWBRIDGE: - return "K_NWBRIDGE"; - break; - case K_NETWORKREADER: - return "K_NETWORKREADER"; - break; - case K_GROUPQUEUE: - return "K_GROUPQUEUE"; - break; - case K_GROUP: - return "K_GROUP"; - break; - case K_ORDEREDINSTANCE: - return "K_ORDEREDINSTANCE"; - break; - case K_ORDEREDINSTANCESAMPLE: - return "K_ORDEREDINSTANCESAMPLE"; - break; - default: - break; + _CASE_(K_KERNEL); + _CASE_(K_OBJECT); + _CASE_(K_ENTITY); + _CASE_(K_GROUPSET); + _CASE_(K_STATUSCONDITION); + _CASE_(K_OBJECTLOAN); + _CASE_(K_OBJECTBUFFER); + _CASE_(K_WAITSET); + _CASE_(K_LISTENER); + _CASE_(K_CONDITION); + _CASE_(K_QUERY); + _CASE_(K_DATAREADERQUERY); + _CASE_(K_DATAVIEW); + _CASE_(K_PROJECTION); + _CASE_(K_MAPPING); + _CASE_(K_FILTER); + _CASE_(K_DEADLINEINSTANCE); + _CASE_(K_DEADLINEINSTANCELIST); + _CASE_(K_MESSAGE); + _CASE_(K_MESSAGEEOT); + _CASE_(K_EOTLISTELEMENT); + _CASE_(K_TRANSACTIONADMIN); + _CASE_(K_TRANSACTION); + _CASE_(K_TRANSACTIONELEMENT); + _CASE_(K_TRANSACTIONGROUPADMIN); + _CASE_(K_TRANSACTIONGROUP); + _CASE_(K_TRANSACTIONPUBLISHER); + _CASE_(K_TRANSACTIONWRITER); + _CASE_(K_TRANSACTIONGROUPWRITER); + _CASE_(K_TRANSACTIONGROUPREADER); + _CASE_(K_TRANSACTIONPENDING); + _CASE_(K_WRITERINSTANCE); + _CASE_(K_WRITERSAMPLE); + _CASE_(K_WRITERCACHEITEM); + _CASE_(K_GROUPINSTANCE); + _CASE_(K_GROUPSAMPLE); + _CASE_(K_GROUPCACHEITEM); + _CASE_(K_DATAREADERINSTANCE); + _CASE_(K_READERSAMPLE); + _CASE_(K_DATAVIEWINSTANCE); + _CASE_(K_DATAVIEWQUERY); + _CASE_(K_DATAVIEWSAMPLE); + _CASE_(K_ORDEREDINSTANCE); + _CASE_(K_ORDEREDINSTANCESAMPLE); + _CASE_(K_WRITERINSTANCETEMPLATE); + _CASE_(K_TOPIC); + _CASE_(K_TOPIC_ADAPTER); + _CASE_(K_TYPEREPRESENTATION); + _CASE_(K_PUBLISHER); + _CASE_(K_SUBSCRIBER); + _CASE_(K_DOMAIN); + _CASE_(K_DOMAININTEREST); + _CASE_(K_DOMAINADMIN); + _CASE_(K_READER); + _CASE_(K_WRITER); + _CASE_(K_ENTRY); + _CASE_(K_DATAREADERENTRY); + _CASE_(K_DELIVERYSERVICEENTRY); + _CASE_(K_GROUP); + _CASE_(K_GROUPSTORE); + _CASE_(K_WRITERGROUP); + _CASE_(K_CACHE); + _CASE_(K_GROUPACTION); + _CASE_(K_GROUPSTREAM); + _CASE_(K_GROUPQUEUE); + _CASE_(K_GROUPQUEUESAMPLE); + _CASE_(K_DATAREADER); + _CASE_(K_DELIVERYSERVICE); + _CASE_(K_PARTICIPANT); + _CASE_(K_PURGELISTITEM); + _CASE_(K_GROUPPURGEITEM); + _CASE_(K_INDEX); + _CASE_(K_READERSTATUS); + _CASE_(K_WRITERSTATUS); + _CASE_(K_PUBLISHERSTATUS); + _CASE_(K_SUBSCRIBERSTATUS); + _CASE_(K_DOMAINSTATUS); + _CASE_(K_TOPICSTATUS); + _CASE_(K_PARTICIPANTSTATUS); + _CASE_(K_KERNELSTATUS); + _CASE_(K_WRITERSTATISTICS); + _CASE_(K_QUERYSTATISTICS); + _CASE_(K_DATAREADERSTATISTICS); + _CASE_(K_PROXY); + _CASE_(K_WAITSETEVENT); + _CASE_(K_LISTENEREVENT); + _CASE_(K_WAITSETEVENTHISTORYDELETE); + _CASE_(K_WAITSETEVENTHISTORYREQUEST); + _CASE_(K_WAITSETEVENTPERSISTENTSNAPSHOT); + _CASE_(K_WAITSETEVENTCONNECTWRITER); + _CASE_(K_SERVICEMANAGER); + _CASE_(K_SERVICE); + _CASE_(K_SERVICESTATE); + _CASE_(K_NETWORKING); + _CASE_(K_DURABILITY); + _CASE_(K_CMSOAP); + _CASE_(K_RNR); + _CASE_(K_NWBRIDGE); + _CASE_(K_DBMSCONNECT); + _CASE_(K_LEASEMANAGER); + _CASE_(K_LEASE); + _CASE_(K_LEASEACTION); + _CASE_(K_SPLICED); + _CASE_(K_CONFIGURATION); + _CASE_(K_REGISTRATION); + _CASE_(K_NETWORKREADER); + _CASE_(K_NETWORKREADERENTRY); + _CASE_(K_NETWORKMESSAGE); + _CASE_(K_NETWORKMAPENTRY); + _CASE_(K_HISTORICALDELETEREQUEST); + _CASE_(K_HISTORICALDATAREQUEST); + _CASE_(K_PERSISTENTSNAPSHOTREQUEST); + _CASE_(K_PENDINGDISPOSEELEMENT); + _CASE_(K_WRITEREOTSAMPLE); + _CASE_(K_GID); + _CASE_(K_TID); + _CASE_(K_RXODATA); + _CASE_(K_DURABILITYCLIENT); + _CASE_(K_DURABILITYCLIENTEVENT); + _CASE_(K_DURABILITYCLIENTSERVER); + default: return "UNDEFINED"; break; } - return "UNDEFINED"; +#undef _CASE_ } c_iter @@ -276,10 +328,25 @@ v_kernelGetAttachedProcesses( _Ret_notnull_ _Must_inspect_result_ v_processInfo -v_kernelGetOwnProcessInfo( +v_kernelGetOwnProcessInfoWeakRef ( _Inout_ v_kernel _this) { - return v_kernelGetProcessInfo(_this, os_procIdSelf()); + c_value keyValue; + v_processInfo own; + + /* os_procId is modeled in the kernel odl as c_longlong */ + keyValue = c_longlongValue(os_procIdSelf()); + + c_lockRead(&_this->lock); + own = c_tableFindWeakRef(_this->attachedProcesses, &keyValue, 1); + c_lockUnlock(&_this->lock); + + /* The process info for this process has to be available. It is needed to + * in the kernel for a process to get access to the kernel and is retrieved + * from the kernel too. + */ + assert(own); + return own; } _Ret_maybenull_ @@ -296,7 +363,7 @@ v_kernelGetProcessInfo( keyValue = c_longlongValue(pid); c_lockRead(&_this->lock); - info = c_tableFind(_this->attachedProcesses, &keyValue); + info = c_tableFind(_this->attachedProcesses, &keyValue, 1); c_lockUnlock(&_this->lock); return info; @@ -324,16 +391,29 @@ v_kernel v_kernelAttach( c_base base, const c_char *name, + os_duration timeout, v_processInfo* procInfo) { - v_kernel kernel; + v_kernel kernel = NULL; v_processInfo procInfoSelf; + os_timeM expiryTime; + os_duration sleepTime = OS_DURATION_INIT(0,0); assert(base); assert(name); assert(procInfo); - if ((kernel = c_lookup(base, name)) == NULL){ + if (timeout > 0) { + sleepTime = OS_DURATION_INIT(0, 100 * 1000 * 1000); /*100ms*/ + if(os_durationCompare(timeout, sleepTime) == OS_LESS){ + sleepTime = timeout; + } + } + expiryTime = os_timeMAdd(os_timeMGet(), timeout); + while ((kernel = c_lookup(base, name)) == NULL && os_timeMCompare(expiryTime, os_timeMGet()) == OS_MORE) { + ospl_os_sleep(sleepTime); + } + if (kernel == NULL) { OS_REPORT(OS_ERROR, "v_kernelAttach", V_RESULT_ILL_PARAM, "Failed to lookup kernel with name '%s'", name); goto err_lookup; } @@ -346,15 +426,31 @@ v_kernelAttach( goto err_processInfoNew; } + while (((kernel->spliced == NULL) || v_serviceGetState((v_service)kernel->spliced) == STATE_INITIALISING) && + os_timeMCompare(expiryTime, os_timeMGet()) == OS_MORE) + { + ospl_os_sleep(sleepTime); + } + if (kernel->spliced == NULL || v_serviceGetState(v_service(kernel->spliced)) != STATE_OPERATIONAL) { + if (os_timeMCompare(expiryTime, os_timeMGet()) == OS_MORE) { + OS_REPORT(OS_ERROR, "v_kernelAttach",V_RESULT_ALREADY_DELETED, + "Attach process to Domain failed because Spliced is not running (anymore)."); + } else { + OS_REPORT(OS_ERROR, "v_kernelAttach",V_RESULT_TIMEOUT, + "Attach process to Domain failed because Spliced did not become operational within the specified timeout."); + } + goto err_spliced_operational; + } c_lockWrite(&kernel->lock); *procInfo = ospl_c_insert(kernel->attachedProcesses, procInfoSelf); c_lockUnlock(&kernel->lock); - c_free(procInfoSelf); return kernel; /* Error handling */ +err_spliced_operational: + c_free(procInfoSelf); err_processInfoNew: err_kernelType: c_free(kernel); @@ -381,7 +477,8 @@ collectParticipants( } /* this is needed so that the group attachedServices and notInterestedServices list count - * will be in sync with the v_kernelNetworkCount see OSPL-2219*/ + * will be in sync with the v_kernelNetworkCount + */ static c_bool removeServiceFromGroup( c_object o, @@ -413,7 +510,8 @@ v_kernelMyProtectCount( * be increased anymore and the value is checked to be equal to * zero (which is the terminal state for the counter). Only then * is it a safe conclusion that there are no threads in SHM any- - * more. */ + * more. + */ protectCount = pa_ld32 (&procInfo->protectCount) - pa_ld32 (&procInfo->blockedCount); if (protectCount != 0) { @@ -464,12 +562,14 @@ v_kernelDetach( * be increased anymore and the value is checked to be equal to * zero (which is the terminal state for the counter). Only then * is it a safe conclusion that there are no threads in SHM any- - * more. */ + * more. + */ protectCount = pa_ld32 (&procInfo->protectCount) - pa_ld32 (&procInfo->blockedCount); } else { /* If the process is detaching a process that isn't running any- * more, the waiting threads don't have to be counted, since - * these were sleeping (and thus not modifying SHM). */ + * these were sleeping (and thus not modifying SHM). + */ protectCount = pa_ld32 (&procInfo->protectCount) - (pa_ld32 (&procInfo->waitCount) + pa_ld32 (&procInfo->blockedCount)); } @@ -486,7 +586,8 @@ v_kernelDetach( pa_ld32 (&procInfo->blockedCount)); /* When the process did not cleanup it's resources then let the * shared memory monitor remove the process info of the terminated - * process. */ + * process. + */ if(procId != procIntSelf) { removed = v__kernelRemoveProcessInfo(k, procInfo); assert(removed == procInfo); @@ -513,6 +614,7 @@ v_kernelDetach( case K_NWBRIDGE: case K_CMSOAP: case K_RNR: + case K_DBMSCONNECT: name = c_keep((c_object)v_serviceGetName(v_service(p))); if (name == NULL) { name = c_keep(v_entityName(v_entity(p))); @@ -521,7 +623,8 @@ v_kernelDetach( v_groupSetWalk(k->groupSet, removeServiceFromGroup, name); } /* If the service has no name, it can't be in the group - * administration of attached/interested services either. */ + * administration of attached/interested services either. + */ (void)v_serviceChangeState(v_service(p),STATE_DIED); v_publicFree(v_public(p)); /* Deregister handle. */ @@ -554,7 +657,8 @@ v_kernelDetach( * that the disappeared process was waiting, we explicitly leak * our local reference. * NOTE: found->waitCount also includes threads that were just - * sleeping, so we may leak more often than strictly needed. */ + * sleeping, so we may leak more often than strictly needed. + */ if(procId == procIntSelf || pa_ld32 (&procInfo->waitCount) == 0){ c_free(p); } @@ -593,8 +697,7 @@ v_kernelUserCount( return count; } -/* - * v_kernelNetworkCount is used to request the number of network services +/* v_kernelNetworkCount is used to request the number of network services * that the kernel's configuration expects. Currently this value is * determined once during kernel initialisation, but could be extended to * support the concept of dynamically started/stopped/restarted services, @@ -822,9 +925,7 @@ v_kernelWaitForDurabilityAvailability( durabilityServices = getDurabilityServiceNames(_this); serviceName = (c_string)c_iterTakeFirst(durabilityServices); - /* If no durability services have been configured, return pre-condition - * not met. - */ + /* If no durability services have been configured, return pre-condition not met. */ if(!serviceName){ result = V_RESULT_PRECONDITION_NOT_MET; } else { @@ -840,7 +941,7 @@ v_kernelWaitForDurabilityAvailability( case STATE_INITIALISING: /* Wait some time if still within timeout. */ if(os_timeMCompare(expiryTime, os_timeMGet()) == OS_MORE){ - os_sleep(sleepTime); + ospl_os_sleep(sleepTime); } else { result = V_RESULT_TIMEOUT; } @@ -930,6 +1031,7 @@ static void init_kernel_type_cache (v_kernel kernel) { K_WRITER, "v_writer" }, { K_WRITERGROUP, "v_writerGroup" }, { K_GROUP, "v_group" }, + { K_GROUPSTORE, "v_groupStore" }, { K_GROUPINSTANCE, "v_groupInstance" }, { K_GROUPSAMPLE, "v_groupSample" }, { K_GROUPCACHEITEM, "v_groupCacheItem" }, @@ -967,6 +1069,7 @@ static void init_kernel_type_cache (v_kernel kernel) { K_NWBRIDGE, "v_nwbridge" }, { K_CMSOAP, "v_cmsoap" }, { K_RNR, "v_rnr" }, + { K_DBMSCONNECT, "v_dbmsconnect" }, { K_LEASEMANAGER, "v_leaseManager" }, { K_GROUPSET, "v_groupSet" }, { K_PROXY, "v_proxy" }, @@ -1008,12 +1111,16 @@ static void init_kernel_type_cache (v_kernel kernel) } +#define MILLION 1000000 +_Check_return_ +_Ret_maybenull_ +_Success_(return != NULL) v_kernel v_kernelNew( - c_base base, - const c_char *name, - v_kernelQos qos, - v_processInfo* procInfo) + _In_ c_base base, + _In_z_ const c_char *name, + _In_ v_kernelQos qos, + _Outptr_ v_processInfo* procInfo) { v_kernel kernel; os_duration retPeriod; @@ -1072,9 +1179,9 @@ v_kernelNew( c_free(*procInfo); /* procInfo should be returned to the caller without a refcount */ kernel->pendingDisposeList = c_listNew(v_kernelType(kernel, K_PENDINGDISPOSEELEMENT )); - c_mutexInit(c_getBase(kernel), &kernel->pendingDisposeListMutex); + (void)c_mutexInit(c_getBase(kernel), &kernel->pendingDisposeListMutex); - v_entityInit(v_entity(kernel), V_KERNEL_VERSION, TRUE); + v_entityInit(v_entity(kernel), name); c_lockInit(c_getBase(kernel), &kernel->lock); { /* Fill GID with 'random' value */ @@ -1083,6 +1190,7 @@ v_kernelNew( } kernel->qos = v_kernelQosNew(kernel, qos); kernel->statistics = v_kernelStatisticsNew(kernel); + kernel->spliced = NULL; kernel->participants = c_setNew(v_kernelType(kernel,K_PARTICIPANT)); kernel->partitions = c_tableNew(v_kernelType(kernel,K_DOMAIN),"name"); kernel->topics = c_tableNew(v_kernelType(kernel,K_TOPIC),"name"); @@ -1095,9 +1203,9 @@ v_kernelNew( pa_st32 (&kernel->transactionCount, 0); kernel->transactionGroupAdmin = NULL; - kernel->accessCount = 0; + pa_st32(&kernel->accessCount, 0); kernel->accessBusy = FALSE; - c_mutexInit(c_getBase(kernel), &kernel->accessLock); + (void)c_mutexInit(c_getBase(kernel), &kernel->accessLock); c_condInit(c_getBase(kernel), &kernel->accessCond, &kernel->accessLock); kernel->splicedRunning = TRUE; @@ -1111,28 +1219,25 @@ v_kernelNew( retPeriod = V_KERNEL_RETENTION_PERIOD_DEF * OS_DURATION_MILLISECOND; kernel->retentionPeriod = retPeriod; - - c_mutexInit(c_getBase(kernel), &kernel->sharesMutex); kernel->shares = c_tableNew(v_kernelType(kernel,K_SUBSCRIBER), "qos.share.v.name"); - kernel->deliveryService = NULL; kernel->durabilitySupport = FALSE; + kernel->hasDurabilityService = FALSE; + kernel->durabilityAligned = FALSE; + pa_st32 (&kernel->purgeSuppressCount, 0); + pa_st32 (&kernel->isolate, 0); return kernel; } void v_kernelEnable( - v_kernel kernel, - const c_char *name) + _Inout_ v_kernel kernel) { - v_spliced sd; - kernel->builtin = v_builtinNew(kernel); - sd = v_splicedNew(kernel, TRUE); - c_free(sd); - ospl_c_bind(kernel,name); + kernel->spliced = v_service(v_splicedNew(kernel)); + ospl_c_bind(kernel, v_entityName(v_entity(kernel))); } v_partition @@ -1339,84 +1444,55 @@ v__lookupTypeRepresentation ( dummy.typeHash = typeHash; c_lockRead(&kernel->lock); - /* This does not remove anything because the alwaysFalse function always - * returns false */ + /* This does not remove anything because the alwaysFalse function always returns false */ c_remove(kernel->typeRepresentations, &dummy, alwaysFalseTypeRepresentation, &found); c_lockUnlock(&kernel->lock); return found; } -void -v_lockShares( - v_kernel kernel) -{ - c_mutexLock(&kernel->sharesMutex); -} -void -v_unlockShares( - v_kernel kernel) -{ - c_mutexUnlock(&kernel->sharesMutex); -} - -v_entity -v_addShareUnsafe( +v_subscriber +v_kernelAddSharedSubscriber( v_kernel kernel, - v_entity e) + v_subscriber subscriber) { - v_entity found; + v_subscriber found; assert(kernel != NULL); assert(C_TYPECHECK(kernel,v_kernel)); - assert(e != NULL); - assert(C_TYPECHECK(e,v_entity)); - - found = ospl_c_insert(kernel->shares,e); - - return found; -} - -v_entity -v_removeShareUnsafe( - v_kernel kernel, - v_entity e) -{ - v_entity found; - - assert(kernel != NULL); - assert(C_TYPECHECK(kernel,v_kernel)); - assert(e != NULL); - assert(C_TYPECHECK(e,v_entity)); - - found = c_remove(kernel->shares,e,NULL,NULL); + assert(subscriber != NULL); + assert(C_TYPECHECK(subscriber,v_subscriber)); + OSPL_LOCK(kernel); + found = ospl_c_insert(kernel->shares,subscriber); + if (found != subscriber) { + found->shareCount++; + } + OSPL_UNLOCK(kernel); return found; } - -c_iter -v_resolveShare( +c_ulong +v_kernelRemoveSharedSubscriber( v_kernel kernel, - const c_char *name) + v_subscriber subscriber) { - c_iter list; - c_collection q; - q_expr expr; - c_value params[1]; + c_ulong count; + v_subscriber found; assert(kernel != NULL); assert(C_TYPECHECK(kernel,v_kernel)); + assert(subscriber != NULL); + assert(C_TYPECHECK(subscriber,v_subscriber)); - expr = (q_expr)q_parse("name like %0"); - params[0] = c_stringValue((char *)name); - q = c_queryNew(kernel->shares,expr,params); - q_dispose(expr); - v_lockShares(kernel); - list = ospl_c_select(q,0); - v_unlockShares(kernel); - c_free(q); - return list; + OSPL_LOCK(kernel); + count = --subscriber->shareCount; + if (count == 0) { + found = c_remove(kernel->shares,subscriber,NULL,NULL); + c_free(found); + } + OSPL_UNLOCK(kernel); + return count; } @@ -1451,7 +1527,7 @@ v_resolveServiceByServiceType( c_lockRead(&kernel->lock); (void)c_setWalk(kernel->participants, v_resolveServiceByTypeHelper, &arg); c_lockUnlock(&kernel->lock); - return arg.iter; + return arg.iter; } c_iter @@ -1558,8 +1634,7 @@ v_lookupTopic( ((v_entity)(&dummyTopic))->name = c_stringNew(base,name); topicFound = NULL; c_lockRead(&kernel->lock); - /* This does not remove anything because the alwaysFalse function always - * returns false */ + /* This does not remove anything because the alwaysFalse function always returns false */ c_remove(kernel->topics, &dummyTopic, alwaysFalse, &topicFound); c_lockUnlock(&kernel->lock); c_free(((v_entity)(&dummyTopic))->name); @@ -1686,7 +1761,7 @@ v_loadDurabilitySupport( attr_val = v_cfElementAttributeValue(elem, "name"); assert(attr_val.kind == V_STRING); if (isServiceRequestedServiceKind("DurabilityService", attr_val.is.String, kernel->configuration)) { - kernel->durabilitySupport = TRUE; + kernel->hasDurabilityService = kernel->durabilitySupport = TRUE; break; } } @@ -1897,6 +1972,7 @@ v_writeBuiltinTopic( if (msg != NULL) { if (k->builtin != NULL) { writer = v_builtinWriterLookup(k->builtin,id); + if (writer != NULL) { /* No need to fill writerGID, this is done by the writer */ (void)v_writerWrite(writer,msg,os_timeWGet(),NULL); @@ -2016,7 +2092,7 @@ v_disableStatistics( const char *categoryName) { /* Not yet implemented */ - /* Here, we will have to walk over all entities and forward the disable + /* TODO: we will have to walk over all entities and forward the disable * request. The entity itself has to switch off the corresponding * statistics admin */ OS_UNUSED_ARG(k); @@ -2061,7 +2137,9 @@ v_kernelCreatePersistentSnapshot( event.kind = V_EVENT_PERSISTENT_SNAPSHOT; event.source = v_observable(_this); event.data = request; - v_observableNotify(v_observable(_this),&event); + event.handled = TRUE; + + OSPL_THROW_EVENT(_this, &event); c_free(request); } else { result = V_RESULT_OUT_OF_MEMORY; @@ -2073,8 +2151,7 @@ v_kernelCreatePersistentSnapshot( return result; } -/* - * ES, dds1576: This method consults the configuration info stored in the kernel +/* ES, dds1576: This method consults the configuration info stored in the kernel * to determine the access policy for this partition */ v_accessMode @@ -2196,7 +2273,7 @@ v_kernelTransactionGroupAdmin( { v_transactionGroupAdmin admin = NULL; - (void)c_lockWrite(&_this->lock); + c_lockWrite(&_this->lock); if (_this->transactionGroupAdmin == NULL) { _this->transactionGroupAdmin = v_transactionGroupAdminNew(v_object(_this)); assert(_this->transactionGroupAdmin); @@ -2214,32 +2291,48 @@ v_kernelGroupTransactionFlush( v_transactionGroupAdmin transactionGroupAdmin; assert(_this); - (void)c_lockRead(&_this->lock); + c_lockRead(&_this->lock); transactionGroupAdmin = c_keep(_this->transactionGroupAdmin); c_lockUnlock(&_this->lock); if (transactionGroupAdmin) { - v_transactionGroupAdminFlushPending(transactionGroupAdmin, admin); + if (v_kernelGroupTransactionTryLockAccess(_this)) { + v_transactionGroupAdminFlushPending(transactionGroupAdmin, admin); + v_kernelGroupTransactionUnlockAccess(_this); + } c_free(transactionGroupAdmin); } } +/** + * \brief This operation tries to obtain the access lock which + * is used for group transactions + * + * \param _this : The kernel this operation operates on. + * + * \return : TRUE when access locked as result of this operation + * FALSE operation was unable to lock access + */ c_bool -v_kernelGroupTransactionLockAccess( +v_kernelGroupTransactionTryLockAccess( v_kernel _this) { - c_bool accessBusy = FALSE; + c_bool result = FALSE; assert(v_objectKind(_this) == K_KERNEL); c_mutexLock(&_this->accessLock); - if (_this->accessCount > 0 || _this->accessBusy) { - accessBusy = TRUE; + if (pa_ld32(&_this->accessCount) > 0 || _this->accessBusy) { + /* Unable to get lock */ } else { - _this->accessBusy = TRUE; + result = _this->accessBusy = TRUE; +#ifndef NDEBUG + _this->accessOwner = os_threadIdToInteger(os_threadIdSelf()); +#endif } c_mutexUnlock(&_this->accessLock); - return accessBusy; + + return result; } void @@ -2251,16 +2344,18 @@ v_kernelGroupTransactionUnlockAccess( c_mutexLock(&_this->accessLock); if (_this->accessBusy) { _this->accessBusy = FALSE; +#ifndef NDEBUG + _this->accessOwner = 0; +#endif c_condBroadcast(&_this->accessCond); } c_mutexUnlock(&_this->accessLock); } -v_result +void v_kernelGroupTransactionBeginAccess( - v_kernel _this) + _Inout_ v_kernel _this) { - v_result result = V_RESULT_OK; c_bool flush = FALSE; v_transactionGroupAdmin transactionGroupAdmin; @@ -2268,11 +2363,11 @@ v_kernelGroupTransactionBeginAccess( while (_this->accessBusy) { c_condWait(&_this->accessCond, &_this->accessLock); } - if (_this->accessCount == 0) { + if (pa_ld32(&_this->accessCount) == 0) { _this->accessBusy = TRUE; flush = _this->accessBusy; } - _this->accessCount++; + (void)pa_inc32_nv(&_this->accessCount); c_mutexUnlock(&_this->accessLock); if (flush) { @@ -2289,30 +2384,22 @@ v_kernelGroupTransactionBeginAccess( c_condBroadcast(&_this->accessCond); c_mutexUnlock(&_this->accessLock); } - - return result; } -v_result +void v_kernelGroupTransactionEndAccess( - v_kernel _this) + _Inout_ v_kernel _this) { - c_bool flush = FALSE; - v_result result = V_RESULT_OK; + c_bool flush; v_transactionGroupAdmin transactionGroupAdmin; /* To update access counts, the access lock must be acquired. */ c_mutexLock(&_this->accessLock); - if (_this->accessCount > 0) { - _this->accessCount--; - flush = (_this->accessCount == 0); - if (flush) { - _this->accessBusy = TRUE; /* must set to hold off others until after the flush. */ - } - } else { - result = V_RESULT_PRECONDITION_NOT_MET; - assert(FALSE); + assert(pa_ld32(&_this->accessCount) > 0); + flush = (pa_dec32_nv(&_this->accessCount) == 0); + if (flush) { + _this->accessBusy = TRUE; /* must set to hold off others until after the flush. */ } c_mutexUnlock(&_this->accessLock); @@ -2330,8 +2417,6 @@ v_kernelGroupTransactionEndAccess( c_condBroadcast(&_this->accessCond); c_mutexUnlock(&_this->accessLock); } - - return result; } static c_bool @@ -2344,8 +2429,54 @@ collectAllParticipants( return TRUE; } +/* This operation will update the kernel according to a newly discovered publication and + * notify matching local subscriptions (synchronously). + * The given message holds the builtin publication data describing the discovered writer. + */ +void +v_kernelNotifyPublication( + v_kernel _this, + v_message msg) +{ + c_iter list; + v_participant participant; + + c_lockRead(&_this->lock); + list = c_iterNew(NULL); + (void)c_walk(_this->participants, collectAllParticipants, list); + c_lockUnlock(&_this->lock); + while ((participant = c_iterTakeFirst(list)) != NULL) { + v_participantNotifyPublication(participant, msg); + c_free(participant); + } + c_iterFree(list); +} + +/* This operation will update the kernel according to a newly discovered subscription and + * notify matching local publications (synchronously). + * The given message holds the builtin subscription data describing the discovered reader. + */ +void +v_kernelNotifySubscription( + v_kernel _this, + v_message msg) +{ + c_iter list; + v_participant participant; + + c_lockRead(&_this->lock); + list = c_iterNew(NULL); + (void)c_walk(_this->participants, collectAllParticipants, list); + c_lockUnlock(&_this->lock); + while ((participant = c_iterTakeFirst(list)) != NULL) { + v_participantNotifySubscription(participant, msg); + c_free(participant); + } + c_iterFree(list); +} + void -v_kernelNotifyGroupCoherentPublication( +v_kernelNotifyCoherentPublication( v_kernel _this, v_message msg) { @@ -2366,21 +2497,23 @@ v_kernelNotifyGroupCoherentPublication( for (i=0; igroupSet, info->partition.name[i], info->topic_name); while ((group = c_iterTakeFirst(list)) != NULL) { - v_groupNotifyGroupCoherentPublication(group, msg); + v_groupNotifyCoherentPublication(group, msg); } c_iterFree(list); } } - c_lockRead(&_this->lock); - list = c_iterNew(NULL); - (void)c_walk(_this->participants, collectAllParticipants, list); - c_lockUnlock(&_this->lock); - while ((participant = c_iterTakeFirst(list)) != NULL) { - v_participantNotifyGroupCoherentPublication(participant, msg); - c_free(participant); + if (info->presentation.access_scope == V_PRESENTATION_GROUP) { + c_lockRead(&_this->lock); + list = c_iterNew(NULL); + (void)c_walk(_this->participants, collectAllParticipants, list); + c_lockUnlock(&_this->lock); + while ((participant = c_iterTakeFirst(list)) != NULL) { + v_participantNotifyGroupCoherentPublication(participant, msg); + c_free(participant); + } + c_iterFree(list); } - c_iterFree(list); } v_result @@ -2526,9 +2659,10 @@ v_sampleMaskPass( return pass; } +_Ret_z_ const os_char * v_resultImage( - const v_result result) + _In_ v_result result) { const os_char *image; @@ -2871,6 +3005,19 @@ v_kernelThreadProtectCount ( } } +c_bool +v_kernelThreadInProtectedArea() +{ + c_bool result = FALSE; + struct v__kernelThreadInfo *threadMemInfo; + + threadMemInfo = os_threadMemGet(OS_THREAD_PROCESS_INFO); + if (threadMemInfo) { + result = (threadMemInfo->myProtectCount > 0); + } + return result; +} + _Check_return_ v_result v_kernelProtect( @@ -2890,7 +3037,8 @@ v_kernelProtect( if(threadMemInfo->myProtectCount) { /* If the thread already has a protectCount set, then this MUST be for - * the same domain. */ + * the same domain. + */ assert(threadMemInfo->pinfo == info); assert(threadMemInfo->tinfo == v_processInfoGetThreadInfo(info, os_threadIdToInteger(os_threadIdSelf()))); assert(threadMemInfo->serial == info->serial); @@ -2902,7 +3050,8 @@ v_kernelProtect( assert((threadMemInfo->flags & V_KERNEL_THREAD_FLAG_DOMAINID) == (info->serial & V_KERNEL_THREAD_FLAG_DOMAINID)); } else { /* Always cache info so it can be used in v_kernelUnprotect(), - * v__kernelProtectWaitEnter() and v__kernelProtectWaitExit(). */ + * v__kernelProtectWaitEnter() and v__kernelProtectWaitExit(). + */ if(threadMemInfo->serial == 0 || threadMemInfo->serial != info->serial) { threadMemInfo->serial = info->serial; threadMemInfo->pinfo = info; @@ -3019,6 +3168,14 @@ v_kernelProtectStrictReadOnlyExit(void) v__kernelProtectTrace(threadMemInfo->pinfo, count + 1, "CopyOutEnter"); } +/* + * This function unprotects the kernel + * + * return: NULL in case the protect count is lowered but has not yet reached 0 + * other protect count has reached 0, v_kernelUnprotectFinalize should now + * be called to finalize the unprotect. + */ +_Ret_maybenull_ void * v_kernelUnprotect(void) { @@ -3029,20 +3186,43 @@ v_kernelUnprotect(void) threadMemInfo = v__kernelThreadInfoGet(); - count = pa_dec32_nv(&threadMemInfo->pinfo->protectCount); threadMemInfo->myProtectCount--; threadMemInfo->tinfo->protectCount--; assert(threadMemInfo->myProtectCount == threadMemInfo->tinfo->protectCount); - v__kernelProtectTrace(threadMemInfo->pinfo, count + 1, "Unprotect"); if(threadMemInfo->myProtectCount == 0) { v__kernelThreadInfoFlags(threadMemInfo, V_KERNEL_THREAD_FLAG_DOMAINID, (os_uint32)-1); return threadMemInfo->usrData; } else { + count = pa_dec32_nv(&threadMemInfo->pinfo->protectCount); + v__kernelProtectTrace(threadMemInfo->pinfo, count + 1, "Unprotect"); return NULL; } } +/* + * This function finalizes the kernel unprotect, it should only be called after the + * v_kernelUnprotect function + */ +void +v_kernelUnprotectFinalize( + void * usrData) +{ + struct v__kernelThreadInfo *threadMemInfo; + os_uint32 count; + + if (usrData) { + assert(os_threadMemGet(OS_THREAD_PROCESS_INFO)); + + threadMemInfo = v__kernelThreadInfoGet(); + assert(threadMemInfo->usrData == usrData); + assert(threadMemInfo->myProtectCount == threadMemInfo->tinfo->protectCount); + + count = pa_dec32_nv(&threadMemInfo->pinfo->protectCount); + v__kernelProtectTrace(threadMemInfo->pinfo, count + 1, "Unprotect final"); + } +} + os_int32 v_kernelThreadInfoGetDomainId(void) { @@ -3060,11 +3240,9 @@ v_kernelGetSpliced( v_kernel _this) { v_spliced spliced; - c_iter list; - - list = v_resolveParticipants(_this, V_SPLICED_NAME); - spliced = v_spliced(c_iterTakeFirst(list)); - c_iterFree(list); + c_lockRead(&_this->lock); + spliced = c_keep(_this->spliced); + c_lockUnlock(&_this->lock); return spliced; } @@ -3113,9 +3291,7 @@ v_kernelDisposeAllData( topicList = c_iterAppend(topicList, c_keep(topic)); } } else { - v_observerLock( v_observer(topic) ); v_topicNotifyAllDataDisposed( topic ); - v_observerUnlock( v_observer(topic) ); } c_free(group); @@ -3124,9 +3300,7 @@ v_kernelDisposeAllData( if (topicList) { topic = c_iterTakeFirst(topicList); while (topic) { - v_observerLock( v_observer(topic) ); v_topicNotifyAllDataDisposed( topic ); - v_observerUnlock( v_observer(topic) ); c_free(topic); topic = c_iterTakeFirst(topicList); } @@ -3135,8 +3309,7 @@ v_kernelDisposeAllData( } else { - /* Group does not exist yet, store the timestamp etc for when the group is - created */ + /* Group does not exist yet, store the timestamp etc for when the group is created */ v_pendingDisposeElement element = NULL; c_base base = c_getBase(c_object(kernel)); int found = 0; @@ -3154,7 +3327,8 @@ v_kernelDisposeAllData( if ( os_timeWCompare( element->disposeTimestamp, timestamp ) == OS_LESS ) { /* Already an older existing record for this partition - and topic combination - update timestamp */ + * and topic combination - update timestamp + */ element->disposeTimestamp = timestamp; } break; @@ -3270,7 +3444,7 @@ v_rxoDataCompatible( c_bool v_kernelGetDurabilitySupport( - v_kernel kernel) + _In_ _Const_ v_kernel kernel) { assert(kernel != NULL); assert(C_TYPECHECK(kernel,v_kernel)); @@ -3278,3 +3452,265 @@ v_kernelGetDurabilitySupport( return kernel->durabilitySupport; } +c_bool +v_kernelHasDurabilityService( + _In_ _Const_ v_kernel kernel) +{ + assert(kernel != NULL); + assert(C_TYPECHECK(kernel,v_kernel)); + + return kernel->hasDurabilityService; +} + +c_bool +v_kernelGetAlignedState( + v_kernel _this) +{ + c_bool result; + + assert(_this != NULL); + assert(C_TYPECHECK(_this,v_kernel)); + + c_lockRead(&_this->lock); + result = _this->durabilityAligned; + c_lockUnlock(&_this->lock); + + return result; +} + +void +v_kernelSetAlignedState( + v_kernel _this, + c_bool aligned) +{ + assert(_this != NULL); + assert(C_TYPECHECK(_this,v_kernel)); + + c_lockWrite(&_this->lock); + _this->durabilityAligned = aligned; + c_lockUnlock(&_this->lock); +} + +void +v_kernelTransactionsPurge( + v_kernel _this) +{ + c_iter list; + v_participant participant; + + /* A transaction flush purges and flushes the obsolete groups, + * flushing is required in case the obsolete group contains samples + * which cannot be discarded. + */ + v_kernelGroupTransactionFlush(_this, NULL); + + list = c_iterNew(NULL); + c_lockRead(&_this->lock); + (void)c_walk(_this->participants, collectAllParticipants, list); + c_lockUnlock(&_this->lock); + while ((participant = c_iterTakeFirst(list)) != NULL) { + v_participantTransactionsPurge(participant); + c_free(participant); + } + c_iterFree(list); +} + +void +v_kernelConnectGroup( + v_kernel k, + v_group g) +{ + c_iter list; + v_participant p; + assert(k); + assert(g); + assert(C_TYPECHECK(k,v_kernel)); + c_lockRead(&k->lock); + list = ospl_c_select(k->participants, 0); + c_lockUnlock(&k->lock); + while ((p = c_iterTakeFirst(list)) != NULL) { + v_participantConnectGroup(p, g); + c_free(p); + } + c_iterFree(list); +} + +/* The operation WalkPublications will visit all discovered publication messages and + * invoke the given publication action function on each publication message. + * The given argument arg is passed as context information to the invoked action function. + * The walk will stop when all messages are processed or when the action function returns FALSE. + */ +v_result +v_kernelWalkPublications( + v_kernel _this, + v_publication_action action, /* signature: os_boolean (*action)(const v_message publication, void *arg) */ + c_voidp arg) +{ + /* The implementation of the system info storage is currently owned by + * the spliced but should move to the kernel. + */ + v_spliced spliced; + v_result result; + spliced = v_kernelGetSpliced(_this); + result = v_splicedWalkPublications(spliced, action, arg); + c_free(spliced); + return result; +} + +/* The operation WalkSubscriptions will visit all discovered subscription messages and + * invoke the given subscription action function on each subscription message. + * The given argument arg is passed as context information to the invoked action function. + * The walk will stop when all messages are processed or when the action function returns FALSE. + */ +v_result +v_kernelWalkSubscriptions( + v_kernel _this, + v_subscription_action action, /* signature: os_boolean (*action)(const v_message subscription, void *arg) */ + c_voidp arg) +{ + /* The implementation of the system info storage is currently owned by + * the spliced but should move to the kernel. + */ + v_spliced spliced; + v_result result; + spliced = v_kernelGetSpliced(_this); + result = v_splicedWalkSubscriptions(spliced, action, arg); + c_free(spliced); + return result; +} + +struct lookupPublicationArg { + v_gid wgid; + v_message msg; +}; + +static os_boolean +lookupPublication( + const v_message msg, + c_voidp arg) +{ + struct lookupPublicationArg *a = (struct lookupPublicationArg *)arg; + struct v_publicationInfo *info; + + info = v_builtinPublicationInfoData(msg); + if (v_gidEqual(info->key, a->wgid)) { + a->msg = c_keep(msg); + return OS_FALSE; + } + return OS_TRUE; +} + +/* This operation will lookup the publication message identified by the given gid. + * If found the message will be returned and must be freed after use. + */ +v_message +v_kernelLookupPublication( + v_kernel _this, + v_gid gid) +{ + struct lookupPublicationArg lpa; + + lpa.wgid = gid; + lpa.msg = NULL; + (void)v_kernelWalkPublications(_this, lookupPublication, &lpa); + return lpa.msg; +} + +struct kernelReadActionArg { + v_domainReadAction action; + const void *actionArg; + v_result result; +}; + +static os_boolean +kernelReadAction( + v_groupSample sample, + const void *arg) +{ + struct kernelReadActionArg *a = (struct kernelReadActionArg *)arg; + v_groupInstance instance = sample->instance; + + a->result = a->action(instance->group, instance, v_groupSampleTemplate(sample)->message, a->actionArg); + return (a->result == V_RESULT_OK); +} + +v_result +v_kernelRead( + const v_kernel _this, + const os_char *partition, + const os_char *topic, + const os_char *query, + const v_domainReadAction action, + const void *actionArg) +{ + v_result result = V_RESULT_OK; + v_groupStoreQuery store_query = NULL; + v_group group; + c_iter list; + c_value params[2]; + struct kernelReadActionArg arg; + + arg.action = action; + arg.actionArg = actionArg; + arg.result = V_RESULT_OK; + + params[0] = c_stringValue((c_string)partition); + params[1] = c_stringValue((c_string)topic); + + list = v_groupSetSelect(_this->groupSet, "partition.name like %0 AND topic.name like %1", params); + while ((result == V_RESULT_OK) && (group = c_iterTakeFirst(list)) != NULL) { + store_query = v_groupStoreQueryNew(group->store, query, NULL, 0); + result = v_groupStoreRead(group->store, store_query, kernelReadAction, &arg); + if (store_query) { + v_groupStoreQueryFree(store_query); + } + } + c_iterFree(list); + return result; +} + +v_result +v_kernelGroupRead( + const v_kernel _this, + const os_char *partition, + const os_char *topic, + const v_domainGroupReadAction action, + const void *actionArg) +{ + v_result result = V_RESULT_OK; + v_group group; + c_iter list; + c_value params[2]; + + params[0] = c_stringValue((c_string)partition); + params[1] = c_stringValue((c_string)topic); + + list = v_groupSetSelect(_this->groupSet, "partition.name like %0 AND topic.name like %1", params); + while ((group = c_iterTakeFirst(list)) != NULL) { + result = action(group, actionArg); + c_free(group); + } + result = action(NULL, actionArg); + c_iterFree(list); + return result; +} + +v_result +v_kernelSetIsolate( + const v_kernel _this, + const os_uint32 isolate) +{ + v_result result = V_RESULT_OK; + pa_st32(&_this->isolate, (os_uint32)isolate); + return result; +} + +v_result +v_kernelGetIsolate( + const v_kernel _this, + os_uint32 *isolate) +{ + v_result result = V_RESULT_OK; + *isolate = pa_ld32(&_this->isolate); + return result; +} diff --git a/src/kernel/code/v_kernel.odl b/src/kernel/code/v_kernel.odl index 63216335f..cb4d34406 100644 --- a/src/kernel/code/v_kernel.odl +++ b/src/kernel/code/v_kernel.odl @@ -913,7 +913,7 @@ module kernelModuleI { K_READER, K_WRITER, K_ENTRY, K_DATAREADERENTRY, K_DELIVERYSERVICEENTRY, K_GROUP, K_WRITERGROUP, K_CACHE, - K_GROUPACTION, K_GROUPSTREAM, + K_GROUPACTION, K_GROUPSTREAM, K_GROUPSTORE, K_GROUPQUEUE, K_GROUPQUEUESAMPLE, K_DATAREADER, K_DELIVERYSERVICE, K_PARTICIPANT, K_PURGELISTITEM, K_GROUPPURGEITEM, @@ -928,7 +928,7 @@ module kernelModuleI { K_WAITSETEVENTPERSISTENTSNAPSHOT, K_WAITSETEVENTCONNECTWRITER, K_SERVICEMANAGER, K_SERVICE, K_SERVICESTATE, K_NETWORKING, K_DURABILITY, K_CMSOAP, - K_RNR, K_NWBRIDGE, + K_RNR, K_NWBRIDGE, K_DBMSCONNECT, K_LEASEMANAGER, K_LEASE, K_LEASEACTION, K_SPLICED, K_CONFIGURATION, @@ -971,36 +971,38 @@ module kernelModuleI { attribute c_ulong index; }; + class v_observer; /* This proxy can be used for both local and remote public objects. */ class v_proxy extends v_object { attribute v_handle source; + attribute c_ulong eventMask; attribute c_voidp userData; - attribute c_voidp source2; + attribute v_observer source2; attribute v_proxy next; }; class v_observable extends v_public { - attribute c_mutex mutex; - attribute v_proxy observers; + attribute c_mutex mutex; /* General purpose Object lock. */ + attribute c_mutex eventLock; /* Event lock protects observers list and is used by v_observer to block events */ + attribute v_proxy observers; /* All observers that will be notified about events. */ }; + typedef c_ulong v_eventKind; + class v_observer extends v_observable { - attribute c_cond cv; - attribute c_mutex mutex; - attribute c_long waitCount; - attribute c_ulong eventMask; - attribute c_ulong eventFlags; - /* place to store event data by the observer */ - attribute c_voidp eventData; + attribute c_cond cv; + attribute c_long waitCount; + attribute c_ulong eventMask; + attribute c_ulong eventFlags; }; class v_status extends v_object { attribute c_ulong state; }; - enum v_entityState { V_ENTITYSTATE_DISABLED, V_ENTITYSTATE_SUSPENDED, V_ENTITYSTATE_ENABLED }; + enum v_entityState { V_ENTITYSTATE_DISABLED, V_ENTITYSTATE_ENABLING, V_ENTITYSTATE_ENABLED }; typedef c_ulong v_eventMask; @@ -1030,12 +1032,12 @@ module kernelModuleI { attribute v_listener listener; attribute v_eventMask listenerInterest; attribute c_voidp listenerData; - attribute c_bool enabled; + attribute v_entityState state; attribute v_objectLoan loan; }; class v_statusCondition extends v_observer { - attribute v_proxy entity; + attribute v_handle entity; }; class v_query; @@ -1088,6 +1090,7 @@ module kernelModuleI { attribute c_bool waitsetEventEnabled; attribute c_ulong waitDisconnectCount; attribute c_cond syncDisconnect; + attribute v_waitsetEvent eventList; }; enum v_leaseActionId { @@ -1638,11 +1641,12 @@ module kernelModuleI { }; class v_topicImpl extends v_topic { - attribute c_type messageType; - attribute c_type dataType; + attribute c_type messageType; // v_message + attribute c_type messageExtType; // v_messageExt + attribute c_type dataType; // topic data type attribute v_topicQos qos; - attribute c_string keyExpr; - attribute ARRAY messageKeyList; + attribute c_string keyExpr; // topic data type key expression + attribute ARRAY messageKeyList; // v_message key list attribute v_accessMode accessMode; /* keyType is a reference to a generated type 'topicName'. It is a structure that contains fields 'field1'.. 'fieldN'. @@ -1650,7 +1654,7 @@ module kernelModuleI { Note that this reference is only for convenience so default DataWriters and DataReaders do not have to create the type themselves. */ - attribute c_type keyType; + attribute c_type keyType; // Internal key type attribute c_ulong crcOfName; attribute c_ulong crcOfTypeName; }; @@ -1660,8 +1664,9 @@ module kernelModuleI { }; class v_filter { - attribute v_topic topic; - attribute c_object predicate; + attribute ARRAY _key; /* condition list holding key part of condition[i] */ + attribute ARRAY nonkey; /* condition list holding nonkey part of condition[i] */ + attribute c_ulong flags; /* HAS_KEY and HAS_NONKEY bits */ }; class v_typeRepresentation { @@ -1688,6 +1693,7 @@ module kernelModuleI { class v_instance extends v_public { attribute v_state state; attribute c_voidp entity; /* Owner of the instance. */ + attribute c_voidp userData; /* Application specific user data. */ }; class v_deadLineInstance extends v_instance { @@ -1762,6 +1768,67 @@ module kernelModuleI { attribute v_lifespanSample tail; }; + /* -------------------------------------------------------------------------- */ + /* Built-in Topic type definitions */ + /* -------------------------------------------------------------------------- */ + + enum v_infoId { + V_PARTICIPANTINFO_ID, + V_TYPEINFO_ID, + V_TOPICINFO_ID, + V_PUBLICATIONINFO_ID, + V_SUBSCRIPTIONINFO_ID, + V_HEARTBEATINFO_ID, + V_DELIVERYINFO_ID, + V_C_AND_M_COMMAND_ID, + V_CMPARTICIPANTINFO_ID, + V_CMDATAWRITERINFO_ID, + V_CMDATAREADERINFO_ID, + V_CMPUBLISHERINFO_ID, + V_CMSUBSCRIBERINFO_ID, + V_INFO_ID_COUNT + }; + + class v_heartbeatInfoTemplate extends v_message { + attribute kernelModule::v_heartbeatInfo userData; + }; + + class v_topicInfoTemplate extends v_message { + attribute kernelModule::v_topicInfo userData; + }; + + class v_typeInfoTemplate extends v_message { + attribute kernelModule::v_typeInfo userData; + }; + + class v_publicationInfoTemplate extends v_message { + attribute kernelModule::v_publicationInfo userData; + }; + + class v_dataWriterCMInfoTemplate extends v_message { + attribute kernelModule::v_dataWriterCMInfo userData; + }; + + class v_subscriptionInfoTemplate extends v_message { + attribute kernelModule::v_subscriptionInfo userData; + }; + + class v_dataReaderCMInfoTemplate extends v_message { + attribute kernelModule::v_dataReaderCMInfo userData; + }; + + class v_publisherCMInfoTemplate extends v_message { + attribute kernelModule::v_publisherCMInfo userData; + }; + + class v_subscriberCMInfoTemplate extends v_message { + attribute kernelModule::v_subscriberCMInfo userData; + }; + + class v_deliveryInfoTemplate extends v_message { + attribute kernelModule::v_deliveryInfo userData; + }; + /* -------------------------------------------------------------------------- */ /* Instance pipeline cache implementation */ /* -------------------------------------------------------------------------- */ @@ -1905,7 +1972,6 @@ class v_orderedInstanceSample extends v_dataViewSample { attribute c_bool inNotEmptyList; attribute os_timeE lastInsertionTime; attribute v_dataReaderSampleTemplate pending; - attribute c_voidp userData; }; class v_orderedInstance extends v_dataViewInstanceTemplate { @@ -1922,18 +1988,21 @@ class v_orderedInstanceSample extends v_dataViewSample { attribute c_voidp oldest; }; + /* N.B.: Order of labels is important! */ + enum v_alignState { + V_ALIGNSTATE_INCOMPLETE, /* Purging suppressed, wait-for-historical-data blocks */ + V_ALIGNSTATE_NO_INTEREST, /* Purging enabled, wait-for-historical-data blocks */ + V_ALIGNSTATE_COMPLETE, /* Purging enabled, wait-for-hsitorical-data returns */ + V_ALIGNSTATE_COUNT + }; + class v_entry extends v_object { attribute c_voidp reader; attribute SET groups; - attribute c_bool complete; /* completeness of all groups */ + attribute v_alignState alignState; /* completeness of group */ attribute c_long nvgCount; /* number of attached non volatile groups */ }; - struct v_entrySet { - c_mutex mutex; - SET entries; - }; - class v_historicalDeleteRequest extends v_object { attribute os_timeE deleteTime; attribute c_string partitionExpr; @@ -1956,7 +2025,7 @@ class v_orderedInstanceSample extends v_dataViewSample { }; class v_reader extends v_collection { - attribute v_entrySet entrySet; + attribute SET entries; attribute c_voidp subscriber; attribute v_subscriberQos subQos; /* ref is ro */ attribute v_readerQos qos; @@ -1978,7 +2047,8 @@ class v_orderedInstanceSample extends v_dataViewSample { attribute v_groupSample older; attribute c_voidp newer; attribute c_voidp instance; - attribute v_transaction transaction; /* Reference to the transaction it was part of */ + attribute c_voidp transaction; /* Backref to the transaction it is part of */ + attribute c_ulong readid; /* used during read to avoid duplicates */ }; class v_groupSampleTemplate extends v_groupSample { @@ -1992,7 +2062,7 @@ class v_orderedInstanceSample extends v_dataViewSample { attribute c_ulong sequenceNumber; /* sequenceNumber of the original message */ attribute os_timeE unregisterTime; /* Elapsed (monotonic) time */ attribute v_state state; /* message state of the original message */ - attribute v_transaction transaction; /* Reference to the transaction it was part of */ + attribute c_voidp transaction; /* Backref to the transaction it is part of */ attribute v_registration next; }; @@ -2015,6 +2085,10 @@ class v_orderedInstanceSample extends v_dataViewSample { * when complete. */ class v_transactionElement { + /* When instered is true the message for this element is received and counted. + * This boolean is required when receiving the same message multiple times, it + * should then only increase the transaction count once. */ + attribute c_bool inserted; attribute v_message message; attribute v_instance instance; }; @@ -2027,12 +2101,12 @@ class v_orderedInstanceSample extends v_dataViewSample { attribute c_long count; /* equals nr of unique messages received */ attribute c_long eotCount; /* equals nr of EOTs received */ attribute c_long size; /* equals nr of messages in transaction */ - attribute c_bool elementZero; /* true when first element of transaction is received */ attribute c_bool aborted; /* true when transaction is prematuraly aborted. */ attribute c_bool sampleLostNotified; /* true when sampleLostNotification is sent. */ attribute ARRAY elements; /* received messages */ attribute c_bool isMarked; /* true is the L_MARK flag was set on a message */ attribute c_voidp transactionGroup; /* transactionGroup backref */ + attribute pa_uint32_t historyLinks; /* amount of flushed samples linked to this transaction */ }; class v_transactionWriter extends v_object { @@ -2053,7 +2127,7 @@ class v_orderedInstanceSample extends v_dataViewSample { attribute kernelModule::v_gid gid; /* key */ attribute c_voidp publisher; /* owner backref */ attribute c_bool discovered; - attribute v_topic topic; + attribute c_string topicName; attribute v_rxoData rxo; attribute SET readers; /* set of readers with matching qos */ }; @@ -2061,12 +2135,17 @@ class v_orderedInstanceSample extends v_dataViewSample { class v_transactionGroup extends v_object { attribute c_ulong transactionId; /* key */ attribute c_voidp publisher; /* owner backref */ + attribute c_voidp admin; /* admin backref */ attribute c_ulong publisherId; attribute c_bool aborted; /* true when transaction is prematuraly aborted. */ attribute LIST transactions; /* complete writer transactions */ attribute SET writers; /* discovered matching writers for incomplete transactions */ attribute c_ulong matchCount; /* */ - attribute c_bool triggered; /* true when data_available trigger is sent for group */ + attribute c_bool obsolete; /* true when a never transaction is added to the pending list */ + attribute c_bool deleted; /* temporary variable until OSPL-9429 is implemented */ + attribute os_timeE allocTime; /* elapse time; to indicate when the group is allocated */ + attribute os_timeW writeTime; /* wall time; source time stamp */ + attribute pa_uint32_t historyLinks; /* amount of flushed samples linked to this transaction */ }; class v_transactionPublisher extends v_object { @@ -2075,7 +2154,6 @@ class v_orderedInstanceSample extends v_dataViewSample { attribute c_voidp admin; /* Backref to v_transactionGroupAdmin */ attribute SET writers; /* discovered writers with matchCounts */ attribute LIST transactions; /* reception time ordered incomplete coherent groups */ - attribute c_ulong lastRemovedTransactionId; }; class v_transactionAdmin extends v_object { @@ -2099,6 +2177,10 @@ class v_orderedInstanceSample extends v_dataViewSample { attribute v_groupSampleTemplate newest; }; + class v_groupInstanceGID extends v_groupInstanceTemplate { + attribute kernelModule::v_gid gid; + }; + class v_groupEntry { attribute v_entry entry; attribute c_long sequenceNumber; @@ -2124,10 +2206,20 @@ class v_orderedInstanceSample extends v_dataViewSample { }; class v_groupwriterAdministration { - attribute kernelModule::v_gid gid; + attribute kernelModule::v_gid gid; attribute c_ulong seqNumber; }; + class v_groupStore { + attribute c_mutex mutex; + attribute c_voidp group; + attribute SET instances; + /* next attributes for caching local processing state. */ + attribute c_array messageKeyList; + attribute c_bool gidkey; + attribute c_ulong readid; + }; + /** Class v_group: The attributes topic and partition specifies the data space of the group. The attribute writers is a set of all the writers @@ -2142,6 +2234,7 @@ class v_orderedInstanceSample extends v_dataViewSample { attribute v_topic topic; attribute v_partition partition; attribute v_accessMode partitionAccessMode; + attribute v_filter filter; /* Group associated Reader Entries */ attribute v_groupEntrySet topicEntrySet; /* Normal dataReader entries. */ attribute v_groupEntrySet networkEntrySet; /* Network interface entries. */ @@ -2149,15 +2242,12 @@ class v_orderedInstanceSample extends v_dataViewSample { attribute v_groupEntrySet variantEntrySet; /* Variant keyed dataReader entries. */ attribute SET streams; /* Streams interested in all actions */ - /* Group process control. */ - attribute c_mutex mutex; - /* Group state */ attribute c_long sequenceNumber; attribute c_long resourceSampleCount; attribute os_timeW lastDisposeAllTime; attribute c_bool infWait; - attribute c_bool complete; + attribute v_alignState alignState; attribute c_bool routingEnabled; /* Service attachment states*/ @@ -2165,7 +2255,7 @@ class v_orderedInstanceSample extends v_dataViewSample { attribute SET notInterestedServices; /* group data storage */ - attribute SET instances; + attribute v_groupStore store; attribute v_groupPurgeItem disposedInstances; attribute c_voidp disposedInstancesLast; attribute v_groupPurgeItem purgeListEmpty; @@ -2174,10 +2264,10 @@ class v_orderedInstanceSample extends v_dataViewSample { attribute v_lifespanAdmin lifespanAdmin; /* Group resource optimisation */ - attribute v_message cachedRegMsg; - attribute v_groupInstance cachedInstance; + attribute c_bool gidkey; attribute c_type instanceType; attribute c_type sampleType; + attribute c_array keyList; attribute SET writerAdministration; /* c_table writerAdministration */ attribute v_transactionAdmin transactionAdmin; attribute c_bool onRequest; @@ -2297,6 +2387,7 @@ class v_orderedInstanceSample extends v_dataViewSample { attribute c_type instanceType; attribute c_type sampleType; + attribute v_message pubInfo; /* current published publicationInfo message */ attribute v_deliveryGuard deliveryGuard; @@ -2318,9 +2409,7 @@ class v_orderedInstanceSample extends v_dataViewSample { class v_subscriber extends v_entity { attribute v_partitionAdmin partitions; attribute SET readers; - attribute c_mutex sharesMutex; attribute SET shares; - attribute c_mutex mutex; attribute c_cond cond; attribute c_voidp participant; @@ -2328,8 +2417,6 @@ class v_orderedInstanceSample extends v_dataViewSample { attribute c_ulong shareCount; attribute v_transactionGroupAdmin transactionGroupAdmin; attribute c_ulong accessCount; /* number of active Begin access */ - attribute c_bool accessBusy; /* access is in progress */ - attribute c_address accessOwner; /* debug: threadIdInteger of the thread which set accessBusy */ /* When ordered_access is true and access_scope is set to group, the * destination_order across all readers must be enforced. Creating a reader * that does not abide to the ordering policy will result in inconsistent @@ -2338,13 +2425,12 @@ class v_orderedInstanceSample extends v_dataViewSample { * first reader is added. */ attribute v_orderedInstance orderedInstance; - attribute kernelModule::v_presentationPolicy presentation; + attribute kernelModule::v_orderbyKind orderby; }; class v_publisher extends v_entity { attribute v_partitionAdmin partitions; attribute SET writers; - attribute c_lock lock; attribute c_voidp participant; attribute v_publisherQos qos; attribute os_timeE suspendTime; /* inf means not suspended */ @@ -2359,10 +2445,16 @@ class v_orderedInstanceSample extends v_dataViewSample { attribute kernelModule::v_orderbyKind orderby; }; + class v_ignoreAdmin { + attribute ARRAY participants; + attribute ARRAY publications; + attribute ARRAY subscriptions; + attribute ARRAY topics; + }; + const string V_BUILT_IN_PARTICIPANT_NAME = "Built-in participant"; class v_participant extends v_entity { attribute SET entities; - attribute c_lock lock; attribute v_participantQos qos; attribute v_leaseManager leaseManager; /* resend thread will wait on this condition. This thread is created in the @@ -2373,14 +2465,11 @@ class v_orderedInstanceSample extends v_dataViewSample { attribute c_mutex resendMutex; attribute SET resendWriters; attribute c_ulong resendIteration; - attribute c_mutex builtinLock; - attribute v_subscriber builtinSubscriber; - attribute c_mutex newGroupListMutex; - attribute LIST newGroupList; attribute c_longlong processId; attribute c_string processName; attribute SET typeRepresentations; attribute c_bool processIsZombie; + attribute v_ignoreAdmin ignore; }; /* -------------------------------------------------------------------------- */ @@ -2419,7 +2508,6 @@ class v_orderedInstanceSample extends v_dataViewSample { class v_serviceState extends v_observable { attribute c_string name; - attribute c_lock lock; attribute v_serviceStateKind stateKind; }; @@ -2427,6 +2515,7 @@ class v_orderedInstanceSample extends v_dataViewSample { attribute v_lease lease; attribute v_serviceState state; attribute v_serviceType serviceType; + attribute SET newGroups; }; class v_networking extends v_service { @@ -2450,8 +2539,11 @@ class v_orderedInstanceSample extends v_dataViewSample { attribute v_rnrStatistics statistics; }; + class v_dbmsconnect extends v_service { + attribute c_long dummy; /* unused variable, empty class not supported */ + }; + class v_serviceManager extends v_entity { - attribute c_mutex mutex; attribute SET serviceStates; }; @@ -2497,67 +2589,6 @@ class v_orderedInstanceSample extends v_dataViewSample { attribute c_value value; }; - /* -------------------------------------------------------------------------- */ - /* Built-in Topic type definitions */ - /* -------------------------------------------------------------------------- */ - - enum v_infoId { - V_PARTICIPANTINFO_ID, - V_TYPEINFO_ID, - V_TOPICINFO_ID, - V_PUBLICATIONINFO_ID, - V_SUBSCRIPTIONINFO_ID, - V_HEARTBEATINFO_ID, - V_DELIVERYINFO_ID, - V_C_AND_M_COMMAND_ID, - V_CMPARTICIPANTINFO_ID, - V_CMDATAWRITERINFO_ID, - V_CMDATAREADERINFO_ID, - V_CMPUBLISHERINFO_ID, - V_CMSUBSCRIBERINFO_ID, - V_INFO_ID_COUNT - }; - - class v_heartbeatInfoTemplate extends v_message { - attribute kernelModule::v_heartbeatInfo userData; - }; - - class v_topicInfoTemplate extends v_message { - attribute kernelModule::v_topicInfo userData; - }; - - class v_typeInfoTemplate extends v_message { - attribute kernelModule::v_typeInfo userData; - }; - - class v_publicationInfoTemplate extends v_message { - attribute kernelModule::v_publicationInfo userData; - }; - - class v_dataWriterCMInfoTemplate extends v_message { - attribute kernelModule::v_dataWriterCMInfo userData; - }; - - class v_subscriptionInfoTemplate extends v_message { - attribute kernelModule::v_subscriptionInfo userData; - }; - - class v_dataReaderCMInfoTemplate extends v_message { - attribute kernelModule::v_dataReaderCMInfo userData; - }; - - class v_publisherCMInfoTemplate extends v_message { - attribute kernelModule::v_publisherCMInfo userData; - }; - - class v_subscriberCMInfoTemplate extends v_message { - attribute kernelModule::v_subscriberCMInfo userData; - }; - - class v_deliveryInfoTemplate extends v_message { - attribute kernelModule::v_deliveryInfo userData; - }; - /* -------------------------------------------------------------------------- */ /* Table reader type implementation */ /* -------------------------------------------------------------------------- */ @@ -2583,8 +2614,7 @@ class v_orderedInstanceSample extends v_dataViewSample { class v_dataReaderEntry extends v_entry { attribute v_topic topic; attribute v_index index; - attribute ARRAY filterInstance; - attribute ARRAY filterData; + attribute v_filter filter; /* timed list of samples with a limited lifespan. */ attribute v_lifespanAdmin lifespanAdmin; /* Lists for garbagecollection/autopurging @@ -2593,6 +2623,7 @@ class v_orderedInstanceSample extends v_dataViewSample { attribute v_transactionAdmin transactionAdmin; attribute LIST purgeListDisposed; /* No Writers */ attribute LIST purgeListNotEmpty; /* No Writers */ + attribute ARRAY ignore; /* ignored publications */ }; class v_deadLineReaderInstanceList { @@ -2618,6 +2649,7 @@ class v_orderedInstanceSample extends v_dataViewSample { class v_dataReader extends v_reader { /* Attributes are protected by the observer lock! */ + attribute v_dataReaderEntry entry; attribute v_index index; attribute SET views; attribute v_deadLineInstanceList deadLineList; @@ -2630,13 +2662,15 @@ class v_orderedInstanceSample extends v_dataViewSample { attribute c_long notReadTriggerCount; attribute c_bool maxInstances; /* Attributes maintaining the current state wrt the policies */ - attribute c_ulong shareCount; + attribute c_ulong shareCount; /* only used by v_subscriber under control of subscriber lock. */ attribute c_type sampleType; + attribute v_message subInfo; /* current published subscriptionInfo message */ attribute v_projection projection; attribute v_orderedInstance orderedInstance; attribute v_dataReaderSample triggerValue; attribute c_bool walkRequired; attribute v_dataReaderStatistics statistics; + attribute c_bool accessBusy; /* This Count is the read/take sequence number of the reader. * Any read or take operation will increment this value and mark @@ -2677,7 +2711,6 @@ class v_orderedInstanceSample extends v_dataViewSample { class v_deliveryService extends v_reader { attribute SET subscriptions; attribute SET guards; - attribute c_mutex mutex; }; class v_deliveryServiceEntry extends v_entry { @@ -2885,6 +2918,7 @@ class v_orderedInstanceSample extends v_dataViewSample { attribute v_waitset waitset; attribute c_bool terminate; attribute c_bool y2038ready; + attribute c_bool alignBuiltin; attribute c_mutex mutex; attribute c_ulong requestId; /* last requestId handed out, initially 0 */ attribute c_voidp chains; /* table of chains allocated on heap */ @@ -2900,7 +2934,7 @@ class v_orderedInstanceSample extends v_dataViewSample { /* Kernel Class implementation */ /* -------------------------------------------------------------------------- */ - class v_groupSet extends v_observable { + class v_groupSet extends v_object { attribute SET groups; attribute c_lock lock; attribute c_long sequenceNumber; @@ -2913,6 +2947,7 @@ class v_orderedInstanceSample extends v_dataViewSample { attribute v_topic topics[V_INFO_ID_COUNT]; attribute v_writer writers[V_INFO_ID_COUNT]; attribute v_kernelQos kernelQos; + attribute c_voidp logfile; }; class v_pendingDisposeElement { @@ -2922,6 +2957,7 @@ class v_orderedInstanceSample extends v_dataViewSample { class v_kernel extends v_entity { attribute kernelModule::v_gid GID; + attribute v_service spliced; attribute SET participants; attribute SET topics; attribute SET partitions; @@ -2934,15 +2970,19 @@ class v_orderedInstanceSample extends v_dataViewSample { attribute v_transactionGroupAdmin transactionGroupAdmin; /* Following attributes are for synchronisation between group flushing and durability alignment requests. */ attribute c_mutex accessLock; /* Begin and End access lock */ - attribute c_ulong accessCount; /* multi durability service support, number of active Begin access */ + attribute pa_uint32_t accessCount; /* multi durability service support, number of active Begin access */ attribute c_bool accessBusy; /* access is in progress */ attribute c_cond accessCond; /* triggered on accessBusy set FALSE */ +#ifndef NDEBUG + attribute c_address accessOwner; /* debug: threadIdInteger of the thread which set accessBusy */ +#endif attribute v_serviceManager serviceManager; attribute v_leaseManager livelinessLM; attribute v_deliveryService deliveryService; attribute v_configuration configuration; attribute c_ulong networkServiceCount; attribute pa_uint32_t transactionCount; + attribute pa_uint32_t isolate; /* ES: dds2476: Added a boolean to indicate if the spliced is running or not * this boolean is set to false when it is detected by any (non-service) * participant that the splice deamon is not longer running. @@ -2973,13 +3013,19 @@ class v_orderedInstanceSample extends v_dataViewSample { attribute c_mutex pendingDisposeListMutex; /* Set of shared entities */ - attribute c_mutex sharesMutex; attribute SET shares; attribute SET attachedProcesses; attribute os_duration retentionPeriod; /* Flag to determine if (client)durability is enabled */ attribute c_bool durabilitySupport; + /* Flag to determine if a durability service is enabled */ + attribute c_bool hasDurabilityService; + /* Flag to indicate if durability is aligned (handling conflicts) */ + attribute c_bool durabilityAligned; + /* Counter that suppresses purging while durability is handling a new + * or reconnected node. */ + attribute pa_uint32_t purgeSuppressCount; }; /* -------------------------------------------------------------------------- */ @@ -3001,7 +3047,6 @@ class v_orderedInstanceSample extends v_dataViewSample { attribute c_bool cAndMCommandDispatcherQuit; attribute v_waitset cAndMCommandWaitSet; - attribute c_mutex mtx; attribute c_mutex cAndMCommandMutex; attribute c_mutex builtinDataMutex; attribute SET missedHB; /* c_table missedHB */ diff --git a/src/kernel/code/v_kernelQos.c b/src/kernel/code/v_kernelQos.c index 3bbb37c83..488337c40 100644 --- a/src/kernel/code/v_kernelQos.c +++ b/src/kernel/code/v_kernelQos.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,13 +23,6 @@ #include "os_report.h" #include "v_policy.h" -/************************************************************** - * private functions - **************************************************************/ - -/************************************************************** - * constructor/destructor - **************************************************************/ v_kernelQos v_kernelQosNew( v_kernel kernel, @@ -55,11 +49,3 @@ v_kernelQosNew( return q; } - -/************************************************************** - * Protected functions - **************************************************************/ - -/************************************************************** - * Public functions - **************************************************************/ diff --git a/src/kernel/code/v_kernelStatistics.c b/src/kernel/code/v_kernelStatistics.c index fd1dc5876..8339dc564 100644 --- a/src/kernel/code/v_kernelStatistics.c +++ b/src/kernel/code/v_kernelStatistics.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/code/v_lease.c b/src/kernel/code/v_lease.c index e7fe05948..744804620 100644 --- a/src/kernel/code/v_lease.c +++ b/src/kernel/code/v_lease.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -28,10 +29,6 @@ /* For design information, see v_leaseManager.c */ -/************************************************************** - * Private function/struct declarations - **************************************************************/ - static void v_leaseInit( v_lease _this, @@ -44,9 +41,6 @@ v_leaseCollectObservers( c_object o, c_voidp arg); -/************************************************************** - * constructor/destructor - **************************************************************/ v_lease v_leaseNew( v_kernel k, @@ -88,7 +82,7 @@ v_leaseInit( if (_this != NULL) { assert(C_TYPECHECK(_this, v_lease)); - c_mutexInit(c_getBase(_this), &_this->mutex); + (void)c_mutexInit(c_getBase(_this), &_this->mutex); v_leaseTimeInit(&_this->expiryTime, kind, leaseDuration); _this->duration = leaseDuration; _this->observers = c_setNew(v_kernelType(k, K_LEASEMANAGER)); @@ -115,10 +109,6 @@ v_leaseDeinit( } } -/************************************************************** - * Local functions - **************************************************************/ - void v_leaseLock( v_lease _this) @@ -294,7 +284,3 @@ v_leaseRemoveObserverNoLock( } return removed; } - -/************************************************************** - * Public functions - **************************************************************/ diff --git a/src/kernel/code/v_leaseManager.c b/src/kernel/code/v_leaseManager.c index bf71bf11f..4fef09f73 100644 --- a/src/kernel/code/v_leaseManager.c +++ b/src/kernel/code/v_leaseManager.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -272,7 +273,7 @@ v_leaseManagerInit( assert(C_TYPECHECK(_this, v_leaseManager)); k = v_objectKernel(_this); - c_mutexInit(c_getBase(_this), &_this->mutex); + (void)c_mutexInit(c_getBase(_this), &_this->mutex); c_condInit(c_getBase(_this), &_this->cond, &_this->mutex); _this->quit = FALSE; _this->monotonic.nextExpiryTime = v_leaseTimeInfinite(V_LEASE_KIND_MONOTONIC); @@ -606,7 +607,8 @@ v_leaseManagerEvaluateLeases( if (arg.shortestPeriod != 0) { /* Current time is apparently > next expiry-time, so calculate - * lag by subtracting nextExpiryTime from current time. */ + * lag by subtracting nextExpiryTime from current time. + */ *lag = v_leaseTimeDiff(arg.expiryTime, leaseAdmin->nextExpiryTime); } @@ -642,7 +644,8 @@ v_leaseManagerMain( /* The next expiry-time lies in the past, log a warning and proceed * as normal. The first cycle, the leaseManager may be late as the * thread is started asynchronously and leases may have been added - * before the thread is really started. */ + * before the thread is really started. + */ /* Only report warning if lag is more than the shortest period * of all registered leases. */ @@ -826,7 +829,8 @@ collectExpired( v_leaseUnlock(leaseAction->lease); /* Add to expiredLeases if the current expiry time is - * equal or later than the lease expiry time */ + * equal or later than the lease expiry time + */ expired = v_leaseTimeCompare(a->expiryTime, leaseExpiryTime); if (expired == OS_MORE) { @@ -834,10 +838,10 @@ collectExpired( a->expiredLeases = c_iterAppend(a->expiredLeases, c_keep(leaseAction)); /* Warn if the lease expiry processing is very late (twice the duration), - but not for the DEADLINE_MISSED cases as those tend to have very short - duration and cause too many warnings on highly loaded machines. For - aperiodic leases, we do not have enough information available. - (See OSPL-1681.) */ + * but not for the DEADLINE_MISSED cases as those tend to have very short + * duration and cause too many warnings on highly loaded machines. For + * aperiodic leases, we do not have enough information available. + */ if (leaseAction->actionId == V_LEASEACTION_READER_DEADLINE_MISSED || leaseAction->actionId == V_LEASEACTION_WRITER_DEADLINE_MISSED) { logWarning = FALSE; diff --git a/src/kernel/code/v_leaseTime.c b/src/kernel/code/v_leaseTime.c index 7c66dad86..94eabbe33 100644 --- a/src/kernel/code/v_leaseTime.c +++ b/src/kernel/code/v_leaseTime.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -123,19 +124,20 @@ v_leaseTimeDiff( return delta; } - v_leaseTime v_leaseTimeAdd( v_leaseTime t, os_duration duration) { - assert(t._d == V_LEASE_KIND_MONOTONIC || t._d == V_LEASE_KIND_ELAPSED); + v_leaseTime t1; + assert(t._d == V_LEASE_KIND_MONOTONIC || t._d == V_LEASE_KIND_ELAPSED); + t1._d = t._d; if (t._d == V_LEASE_KIND_MONOTONIC) { - os_timeMAdd(t._u.tm, duration); + t1._u.tm = os_timeMAdd(t._u.tm, duration); } else { - os_timeEAdd(t._u.te, duration); + t1._u.te = os_timeEAdd(t._u.te, duration); } - return t; + return t1; } diff --git a/src/kernel/code/v_lifespanAdmin.c b/src/kernel/code/v_lifespanAdmin.c index 9266bca34..db4c1220d 100644 --- a/src/kernel/code/v_lifespanAdmin.c +++ b/src/kernel/code/v_lifespanAdmin.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,14 +21,8 @@ #include "v__lifespanAdmin.h" #include "os_report.h" -/************************************************************** - * Private functions - **************************************************************/ #define CHECK_ADMIN(admin,sample) -/************************************************************** - * constructor/destructor - **************************************************************/ v_lifespanAdmin v_lifespanAdminNew( v_kernel kernel) @@ -41,9 +36,6 @@ v_lifespanAdminNew( return admin; } -/************************************************************** - * Protected functions - **************************************************************/ void v_lifespanAdminInsert( v_lifespanAdmin admin, @@ -80,7 +72,7 @@ v_lifespanAdminInsert( admin->head->prev = sample; admin->head = c_keep(sample); } else { - if (placeHolder->next != NULL) { + if (placeHolder->next != NULL) { placeHolder->next->prev = sample; } else { assert(placeHolder == admin->tail); @@ -178,8 +170,8 @@ v_lifespanAdminTakeExpired( proceed = TRUE; } if ((proceed) && (removed == admin->head)) { - /* The action routine might have already removed the sample, so - * we check if the head of the list has not changed! + /* The action routine might have already removed the sample, so + * we check if the head of the list has not changed! */ admin->head = removed->next; /* transfer refcount */ removed->next = NULL; @@ -210,7 +202,3 @@ v_lifespanAdminSampleCount( { return admin->sampleCount; } - -/************************************************************** - * Public functions - **************************************************************/ diff --git a/src/kernel/code/v_listener.c b/src/kernel/code/v_listener.c index df5495d93..56fca17de 100644 --- a/src/kernel/code/v_listener.c +++ b/src/kernel/code/v_listener.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -46,7 +47,7 @@ v_listenerNew( _this = v_listener(v_objectNew(kernel,K_LISTENER)); if (_this != NULL) { v_publicInit(v_public(_this)); - c_mutexInit(c_getBase(_this), &_this->mutex); + (void)c_mutexInit(c_getBase(_this), &_this->mutex); c_condInit(c_getBase(_this), &_this->cv, &_this->mutex); _this->participant = p; _this->eventList = NULL; @@ -100,7 +101,7 @@ v_listenerFree( delay = OS_DURATION_INIT(0, 1000); while (_this->waitCount > 0 && !p->processIsZombie) { - os_sleep(delay); + ospl_os_sleep(delay); } v_participantRemove(p, v_object(_this)); @@ -166,8 +167,7 @@ v_listenerNotify( v_event e, v_entity listener) { - /* - * The userData argument is typical the user layer entity to which + /* The userData argument is typical the user layer entity to which * this listener is attached. * The userData is passed to the v_listenerWait operation. * The eventData is optional for passing additional data, @@ -179,11 +179,10 @@ v_listenerNotify( assert(_this != NULL); assert(C_TYPECHECK(_this,v_listener)); + c_mutexLock(&_this->mutex); if (e != NULL) { - c_mutexLock(&_this->mutex); - /* It seems that the list of events can grow to infinite length. - */ found = NULL; + event = NULL; if (_this->combine && ((e->kind & V_EVENT_DATA_AVAILABLE) || (e->kind & V_EVENT_ON_DATA_ON_READERS)) ) { @@ -191,67 +190,67 @@ v_listenerNotify( * to avoid triggering after data is already read on behalf of the first * trigger. */ + c_voidp source = v_publicGetUserData(v_public(e->source)); found = _this->eventList; - while ((found != NULL) && - (found->source != v_publicGetUserData(v_public(e->source)))) - { - found = found->next; + while (found != NULL) { + if ((found->source == source) && + (found->kind == e->kind)) { + break; + } else { + found = found->next; + } } } if (found == NULL) { event = c_new(v_kernelType(v_objectKernel(_this),K_LISTENEREVENT)); - - /* Source is allowed to be NULL in case of trigger */ - if (e->source != NULL) { - event->source = v_publicGetUserData(v_public(e->source)); - } else { - assert (e->kind & V_EVENT_TRIGGER); - event->source = NULL; - } - if (listener) { - event->listenerData = listener->listenerData; - event->userData = v_publicGetUserData(v_public(listener)); /* Typical the language binding entity */ - } else { - event->listenerData = NULL; - event->userData = NULL; /* Typical the language binding entity */ - } - event->kind = e->kind; event->next = NULL; - /* For all events except for data availability and triggers + event->kind = e->kind; + event->source = v_publicGetUserData(v_public(e->source)); + /* For all events except for data availability * copy the entity status to keep the actual value until the * data is processed. The aforementioned events do not affect * status, so there is no need to copy the value nor reset any * counters. */ - switch (event->kind) { - case V_EVENT_DATA_AVAILABLE: - event->eventData = c_keep(e->data); - break; - case V_EVENT_TRIGGER: - event->eventData = NULL; - break; - default: - status = v_entityStatus(v_entity(e->source)); - event->eventData = v_statusCopyOut(status); - v_statusResetCounters(status, e->kind); - c_free(status); - break; - } - /* insert constructed listener event in the listeners event list. - */ - if (_this->lastEvent) { - _this->lastEvent->next = c_keep(event); - c_free(_this->lastEvent); + if (event->kind == V_EVENT_DATA_AVAILABLE) { + c_free(event->eventData); + event->eventData = c_keep(e->data); } else { - assert(_this->eventList == NULL); - _this->eventList = c_keep(event); + status = v_entityStatus(v_entity(e->source)); + c_free(event->eventData); + event->eventData = v_statusCopyOut(status); + v_statusResetCounters(status, e->kind); + c_free(status); } - _this->lastEvent = event /* transfer ref */; } - _TRACE_EVENTS_("v_listenerNotify: listener 0x%x, events 0x%x\n", _this, e->kind); - c_condBroadcast(&_this->cv); - c_mutexUnlock(&_this->mutex); + } else { + event = c_new(v_kernelType(v_objectKernel(_this),K_LISTENEREVENT)); + event->next = NULL; + event->kind = V_EVENT_TRIGGER; + event->source = NULL; + event->eventData = NULL; } + if (event) { + /* insert constructed listener event in the listeners event list. */ + if (_this->lastEvent) { + _this->lastEvent->next = c_keep(event); + c_free(_this->lastEvent); + } else { + assert(_this->eventList == NULL); + _this->eventList = c_keep(event); + } + _this->lastEvent = event /* transfer ref */; + if (listener) { + event->listenerData = listener->listenerData; + event->userData = v_publicGetUserData(v_public(listener)); /* Typical the language binding entity */ + } else { + event->listenerData = NULL; + event->userData = NULL; /* Typical the language binding entity */ + } + } + _TRACE_EVENTS_("v_listenerNotify: listener 0x%x, events 0x%x\n", _this, (e?e->kind:V_EVENT_TRIGGER)); + c_condBroadcast(&_this->cv); + c_mutexUnlock(&_this->mutex); } v_result @@ -289,69 +288,60 @@ v_listenerWait( _this->waitCount--; assert(_this->waitCount + 1 > _this->waitCount); c_mutexUnlock(&_this->mutex); - if ((result != V_RESULT_ALREADY_DELETED) && action) { - if (eventList != NULL) { - /* If we timed out but did find some events, we consider - it success, so that a timeout means no events were - processed and success means some events were - processed. */ - result = V_RESULT_OK; - } else { - _TRACE_EVENTS_("v_listenerWait: listener 0x%x, event list is empty so timeout\n", _this); - } - event = eventList; - while (event) { - _TRACE_EVENTS_("v_listenerWait process event: " - "listener 0x%x, event 0x%x\n", - _this, event->kind); + if (result == V_RESULT_ALREADY_DELETED) { + action = NULL; + } + if (eventList != NULL) { + /* If we timed out but did find some events, we consider + * it success, so that a timeout means no events were + * processed and success means some events were processed. + */ + result = V_RESULT_OK; + } else { + _TRACE_EVENTS_("v_listenerWait: listener 0x%x, event list is empty so timeout\n", _this); + } + event = eventList; + while (event) { + _TRACE_EVENTS_("v_listenerWait process event: " + "listener 0x%x, event 0x%x\n", + _this, event->kind); + + if (action && event->kind != V_EVENT_TRIGGER) { v_kernelProtectStrictReadOnlyEnter(); action(event, arg); v_kernelProtectStrictReadOnlyExit(); + } - /* If this event is a destroy event then we must remove all - * events from the same source that have arrived after this event. - * Generation of new event are disabled but there may still be - * events in the event list. - * So scan the rest of the list for any events. - */ - if (event->kind & V_EVENT_OBJECT_DESTROYED) { - v_listenerEvent prev = event; - v_listenerEvent e = event->next; - - while (e) { - if (e->source == event->source) { - prev->next = e->next; - v_listenerEventDeinit(e); - c_free(e); - e = prev->next; - } else { - prev = e; - e = e->next; - } + /* If this event is a destroy event then we must remove all + * events from the same source that have arrived after this event. + * Generation of new event are disabled but there may still be + * events in the event list. + * So scan the rest of the list for any events. + */ + if (event->kind & V_EVENT_OBJECT_DESTROYED) { + v_listenerEvent prev = event; + v_listenerEvent e = event->next; + + while (e) { + if (e->source == event->source) { + prev->next = e->next; + v_listenerEventDeinit(e); + c_free(e); + e = prev->next; + } else { + prev = e; + e = e->next; } - /* Now we are sure that no events exist anymore from this source. */ } - - eventList = event->next; - - /* free the Status object previously allocated by v_listenerNotify. */ - v_listenerEventDeinit(event); - c_free(event); - event = eventList; + /* Now we are sure that no events exist anymore from this source. */ } + eventList = event->next; + /* free the Status object previously allocated by v_listenerNotify. */ + v_listenerEventDeinit(event); + c_free(event); + event = eventList; } return result; } -void -v_listenerTrigger( - v_listener _this) -{ - assert(_this != NULL); - assert(C_TYPECHECK(_this,v_listener)); - - c_mutexLock(&_this->mutex); - c_condBroadcast(&_this->cv); - c_mutexUnlock(&_this->mutex); -} diff --git a/src/kernel/code/v_maxValue.c b/src/kernel/code/v_maxValue.c index a7c9667e4..cf49d2b57 100644 --- a/src/kernel/code/v_maxValue.c +++ b/src/kernel/code/v_maxValue.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/code/v_message.c b/src/kernel/code/v_message.c index c35eda879..0f28c6de5 100644 --- a/src/kernel/code/v_message.c +++ b/src/kernel/code/v_message.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -57,16 +58,57 @@ seqNrCompare( c_equality v_messageCompare ( - v_message m1, - v_message m2) + v_message insertedMessage, + v_message availableMessage) { - c_equality eq; + c_equality eq = C_ER; - if (m1 == m2) return C_EQ; - if ((eq = CMP_TO_EQ(os_timeWCompare(m1->writeTime, m2->writeTime))) == C_EQ && - (eq = v_gidCompare(m1->writerGID, m2->writerGID)) == C_EQ) - { - eq = seqNrCompare(m1, m2); + if (insertedMessage == availableMessage) return C_EQ; + if (v_messageStateTest(insertedMessage,L_IMPLICIT)) { + /* If the message to be inserted has the L_IMPLICIT flag, then it is by definition + * newer than the sample to which it is compared, regardless of their timestamps. + * Only exception is when the two samples are from different writers, in which case + * the normal rules apply. + */ + if (v_gidCompare(insertedMessage->writerGID, availableMessage->writerGID) == C_EQ) { + eq = C_GT; + } + } else if (v_messageStateTest(availableMessage,L_IMPLICIT)) { + /* If the original message has the L_IMPLICIT flag, then it is by definition + * older than the sample to which it is compared, regardless of their timestamps. + * Only exception is when the two samples are from different writers, in which case + * the normal rules apply. + */ + if (v_gidCompare(insertedMessage->writerGID, availableMessage->writerGID) == C_EQ) { + eq = C_GT; + } + } + /* If no ordering has been established yet, then apply default ordering rules. */ + if (eq == C_ER) { + if ((eq = CMP_TO_EQ(os_timeWCompare(insertedMessage->writeTime, availableMessage->writeTime))) == C_EQ && + (eq = v_gidCompare(insertedMessage->writerGID, availableMessage->writerGID)) == C_EQ) + { + eq = seqNrCompare(insertedMessage, availableMessage); + if ((eq == C_EQ) && + (v_messageState(insertedMessage) != v_messageState(availableMessage))) { + /* If the v_messageState differs then always put registrations + * first and unregistrations last. + */ + if ((v_messageStateTest(insertedMessage, L_REGISTER)) && + (!v_messageStateTest(availableMessage, L_REGISTER))) { + eq = C_LT; + } else if ((!v_messageStateTest(insertedMessage, L_REGISTER)) && + (v_messageStateTest(availableMessage, L_REGISTER))) { + eq = C_GT; + } else if ((v_messageStateTest(insertedMessage, L_UNREGISTER)) && + (!v_messageStateTest(availableMessage, L_UNREGISTER))) { + eq = C_GT; + } else if ((!v_messageStateTest(insertedMessage, L_UNREGISTER)) && + (v_messageStateTest(availableMessage, L_UNREGISTER))) { + eq = C_LT; + } + } + } } return eq; } diff --git a/src/kernel/code/v_messageExt.c b/src/kernel/code/v_messageExt.c index 1f782fd9e..267c115f9 100644 --- a/src/kernel/code/v_messageExt.c +++ b/src/kernel/code/v_messageExt.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -49,39 +50,26 @@ c_timeFromUint64( } -c_type v_messageExtTypeNew (v_topic topic) +c_type +v_messageExtTypeNew ( + v_topic topic) { - /* closely follows v_topic.c:messageTypeNew */ - static const char baseTypeName[] = "kernelModule::v_messageExt"; - c_type dataType = v_topicDataType (topic); - c_base base = c_getBase (topic); - c_type baseType = c_resolve (base, baseTypeName); - c_type type; - c_object o; - - assert (dataType); - assert (baseType); - - type = c_type(c_metaDefine (c_metaObject(base), M_CLASS)); - c_class(type)->extends = c_keep (c_class(baseType)); - o = c_metaDeclare (c_metaObject(type), "userData", M_ATTRIBUTE); - c_property(o)->type = c_keep (dataType); - c_metaObject(type)->definedIn = c_keep (base); - c_metaFinalize (c_metaObject(type)); - c_free (baseType); - c_free(o); - - /* leave anonymous */ - return type; + return c_keep(v_topicMessageExtType(topic)); } -void v_messageExtTypeFree (c_type xmsgType) +void +v_messageExtTypeFree ( + c_type xmsgType) { c_free (xmsgType); } -static void v_messageExtConvertHeaderFromExtCommon (v_message vmsg, const struct v_messageExt_s *xmsg, c_bool y2038Ready) +static void +v_messageExtConvertHeaderFromExtCommon ( + v_message vmsg, + const struct v_messageExt_s *xmsg, + c_bool y2038Ready) { vmsg->_parent.nodeState = xmsg->_parent.nodeState; if (y2038Ready) { @@ -97,7 +85,11 @@ static void v_messageExtConvertHeaderFromExtCommon (v_message vmsg, const struct vmsg->qos = xmsg->qos; } -static void v_messageExtConvertHeaderToExtCommon (v_messageExt xmsg, const struct v_message_s *vmsg, c_bool y2038Ready) +static void +v_messageExtConvertHeaderToExtCommon ( + v_messageExt xmsg, + const struct v_message_s *vmsg, + c_bool y2038Ready) { xmsg->_parent.nodeState = vmsg->_parent.nodeState; if (y2038Ready) { @@ -113,7 +105,10 @@ static void v_messageExtConvertHeaderToExtCommon (v_messageExt xmsg, const struc xmsg->qos = vmsg->qos; } -void v_messageExtConvertHeaderFromExt (v_message vmsg, const struct v_messageExt_s *xmsg) +void +v_messageExtConvertHeaderFromExt ( + v_message vmsg, + const struct v_messageExt_s *xmsg) { c_bool y2038Ready = v_stateTest(xmsg->_parent.nodeState, L_TIME_Y2038); @@ -125,7 +120,10 @@ void v_messageExtConvertHeaderFromExt (v_message vmsg, const struct v_messageExt } } -void v_messageExtConvertHeaderToExt (v_messageExt xmsg, const struct v_message_s *vmsg) +void +v_messageExtConvertHeaderToExt ( + v_messageExt xmsg, + const struct v_message_s *vmsg) { c_bool y2038Ready = c_baseGetY2038Ready(c_getBase(c_object(vmsg))); @@ -137,7 +135,10 @@ void v_messageExtConvertHeaderToExt (v_messageExt xmsg, const struct v_message_s } } -void v_messageExtConvertHeaderFromExtNoAllocTime (v_message vmsg, const struct v_messageExt_s *xmsg) +void +v_messageExtConvertHeaderFromExtNoAllocTime ( + v_message vmsg, + const struct v_messageExt_s *xmsg) { c_bool y2038Ready = v_stateTest(xmsg->_parent.nodeState, L_TIME_Y2038); @@ -145,7 +146,10 @@ void v_messageExtConvertHeaderFromExtNoAllocTime (v_message vmsg, const struct v vmsg->allocTime = os_timeEGet(); } -void v_messageExtConvertHeaderToExtNoAllocTime (v_messageExt xmsg, const struct v_message_s *vmsg) +void +v_messageExtConvertHeaderToExtNoAllocTime ( + v_messageExt xmsg, + const struct v_message_s *vmsg) { c_bool y2038Ready = c_baseGetY2038Ready(c_getBase(c_object(vmsg))); @@ -154,7 +158,10 @@ void v_messageExtConvertHeaderToExtNoAllocTime (v_messageExt xmsg, const struct xmsg->allocTime.nanoseconds = 0; } -void v_messageEOTExtConvertFromExtNoAllocTime (v_messageEOT vmsgEOT, const struct v_messageEOTExt_s *xmsgEOT) +void +v_messageEOTExtConvertFromExtNoAllocTime ( + v_messageEOT vmsgEOT, + const struct v_messageEOTExt_s *xmsgEOT) { v_messageExtConvertHeaderFromExtNoAllocTime (&vmsgEOT->_parent, &xmsgEOT->_parent); vmsgEOT->publisherId = xmsgEOT->publisherId; @@ -163,7 +170,10 @@ void v_messageEOTExtConvertFromExtNoAllocTime (v_messageEOT vmsgEOT, const struc vmsgEOT->tidList = xmsgEOT->tidList; } -void v_messageEOTExtConvertToExtNoAllocTime (v_messageEOTExt xmsgEOT, const struct v_messageEOT_s *vmsgEOT) +void +v_messageEOTExtConvertToExtNoAllocTime ( + v_messageEOTExt xmsgEOT, + const struct v_messageEOT_s *vmsgEOT) { v_messageExtConvertHeaderToExtNoAllocTime (&xmsgEOT->_parent, &vmsgEOT->_parent); xmsgEOT->publisherId = vmsgEOT->publisherId; @@ -172,7 +182,10 @@ void v_messageEOTExtConvertToExtNoAllocTime (v_messageEOTExt xmsgEOT, const stru xmsgEOT->tidList = vmsgEOT->tidList; } -v_message v_messageExtConvertFromExtType (c_type msgType, v_messageExt xmsg) +v_message +v_messageExtConvertFromExtType ( + c_type msgType, + v_messageExt xmsg) { c_type xmsgType = c_getType (xmsg); v_message vmsg; @@ -186,7 +199,10 @@ v_message v_messageExtConvertFromExtType (c_type msgType, v_messageExt xmsg) return vmsg; } -v_messageExt v_messageExtCopyToExtType (c_type xmsgType, const struct v_message_s *vmsg) +v_messageExt +v_messageExtCopyToExtType ( + c_type xmsgType, + const struct v_message_s *vmsg) { v_messageExt xmsg; xmsg = c_new (xmsgType); @@ -195,14 +211,18 @@ v_messageExt v_messageExtCopyToExtType (c_type xmsgType, const struct v_message_ return xmsg; } -void v_messageExtFree (v_messageExt xmsg) +void +v_messageExtFree ( + v_messageExt xmsg) { c_type xmsgType = c_getType (xmsg); memset (xmsg, 0, xmsgType->size); c_free (xmsg); } -v_messageEOTExt v_messageEOTExtCopyToExtType (const struct v_messageEOT_s *vmsg) +v_messageEOTExt +v_messageEOTExtCopyToExtType ( + const struct v_messageEOT_s *vmsg) { c_type xmsgType = c_resolve(c_getBase((c_object)vmsg), "kernelModule::v_messageEOTExt"); v_messageEOTExt xmsg; @@ -213,13 +233,17 @@ v_messageEOTExt v_messageEOTExtCopyToExtType (const struct v_messageEOT_s *vmsg) } -v_message v_messageEOTExtConvertFromExtType (v_messageEOTExt xmsg_eot) +v_message +v_messageEOTExtConvertFromExtType ( + v_messageEOTExt xmsg_eot) { c_type msgType = c_resolve(c_getBase((c_object)xmsg_eot), "kernelModuleI::v_messageEOT"); return v_messageExtConvertFromExtType (msgType, (v_messageExt) xmsg_eot); } -void v_messageEOTExtFree (v_messageEOTExt xmsg) +void +v_messageEOTExtFree ( + v_messageEOTExt xmsg) { c_type xmsgType = c_getType (xmsg); memset (xmsg, 0, xmsgType->size); @@ -236,7 +260,10 @@ struct v_messageExtCdrTmp { void *d; }; -struct v_messageExtCdrInfo *v_messageExtCdrInfoNew(c_type topicMessageType, const struct sd_cdrControl *control) +struct v_messageExtCdrInfo * +v_messageExtCdrInfoNew( + c_type topicMessageType, + const struct sd_cdrControl *control) { static const char headerTypeName[] = "kernelModule::v_messageExt"; c_base base = c_getBase (topicMessageType); @@ -306,13 +333,20 @@ struct v_messageExtCdrInfo *v_messageExtCdrInfoNew(c_type topicMessageType, cons return NULL; } -void v_messageExtCdrInfoFree(struct v_messageExtCdrInfo *xci) +void +v_messageExtCdrInfoFree( + struct v_messageExtCdrInfo *xci) { sd_cdrInfoFree(xci->ci); c_free(xci->vmsgType); } -int v_messageExtCdrSerializeNoAllocTime (int (*f) (const struct sd_cdrInfo *ci, void *serdata, const void *data), const struct v_messageExtCdrInfo *xci, void *serdata, const struct v_message_s *vmsg) +int +v_messageExtCdrSerializeNoAllocTime ( + int (*f) (const struct sd_cdrInfo *ci, void *serdata, const void *data), + const struct v_messageExtCdrInfo *xci, + void *serdata, + const struct v_message_s *vmsg) { struct v_messageExtCdrTmp tmp; struct v_messageExt_s xmsg; @@ -322,7 +356,13 @@ int v_messageExtCdrSerializeNoAllocTime (int (*f) (const struct sd_cdrInfo *ci, return f(xci->ci, serdata, &tmp); } -int v_messageExtCdrDeserializeNoAllocTime (int (*f) (void *dst, const struct sd_cdrInfo *ci, os_uint32 sz, const void *src), v_message *dst, const struct v_messageExtCdrInfo *xci, os_uint32 sz, const void *src) +int +v_messageExtCdrDeserializeNoAllocTime ( + int (*f) (void *dst, const struct sd_cdrInfo *ci, os_uint32 sz, const void *src), + v_message *dst, + const struct v_messageExtCdrInfo *xci, + os_uint32 sz, + const void *src) { struct v_messageExtCdrTmp tmp; struct v_messageExt_s xmsg; diff --git a/src/kernel/code/v_messageQos.c b/src/kernel/code/v_messageQos.c index 0178baf6d..471ef5bd8 100644 --- a/src/kernel/code/v_messageQos.c +++ b/src/kernel/code/v_messageQos.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -169,121 +170,6 @@ v_messageQos_new( return v_messageQos_from_wqos_new(writer->qos, writer->msgQosType, writer->resend._d, writer->coherent_access, writer->ordered_access); } - -#if 0 -v_messageQos -v_messageQos_new( - v_writer writer) -{ - v_messageQos _this; - v_writerQos wqos; - c_base base; - c_ulong offset = 6, /* byte0 + byte1 + transport_priority */ - strength_offset = 0, - latency_offset = 0, - deadline_offset = 0, - liveliness_offset = 0, - lifespan_offset = 0; - - c_octet byte0, byte1; - - c_octet *dst, *src; - - assert(C_TYPECHECK(writer,v_writer)); - - wqos = writer->qos; - base = c_getBase(writer); - - if (writer->msgQosType == NULL) { - writer->msgQosType = c_metaArrayTypeNew(c_metaObject(base), - "C_ARRAY", - c_octet_t(base), - 0); - } - byte0 = (c_octet) (_LSHIFT_(wqos->reliability.v.kind, MQ_BYTE0_RELIABILITY_OFFSET) | - _LSHIFT_(wqos->ownership.v.kind, MQ_BYTE0_OWNERSHIP_OFFSET) | - _LSHIFT_(wqos->orderby.v.kind, MQ_BYTE0_ORDERBY_OFFSET) | - _LSHIFT_(wqos->lifecycle.v.autodispose_unregistered_instances, MQ_BYTE0_AUTODISPOSE_OFFSET)); - byte1 = (c_octet) (_LSHIFT_(wqos->durability.v.kind, MQ_BYTE1_DURABILITY_OFFSET) | - _LSHIFT_(wqos->liveliness.v.kind, MQ_BYTE1_LIVELINESS_OFFSET) | - /* writer->resend._d contains the access_scope of the publisher-QoS */ - _LSHIFT_(writer->resend._d, MQ_BYTE1_PRESENTATION_OFFSET) | - _LSHIFT_(writer->coherent_access, MQ_BYTE1_COHERENT_ACCESS_OFFSET) | - _LSHIFT_(writer->ordered_access, MQ_BYTE1_ORDERED_ACCESS_OFFSET)); - - if (wqos->ownership.v.kind == V_OWNERSHIP_EXCLUSIVE) { - strength_offset = offset; - offset += (c_ulong) sizeof(wqos->strength.v.value); - } - if (c_timeIsZero(wqos->latency.v.duration)) { - byte0 = (c_octet) (byte0 | _LSHIFT_(1,MQ_BYTE0_LATENCY_OFFSET)); - } else { - latency_offset = offset; - offset += (c_ulong) sizeof(wqos->latency.v.duration); - } - if (c_timeIsInfinite(wqos->deadline.v.period)) { - byte0 = (c_octet) (byte0 | _LSHIFT_(1,MQ_BYTE0_DEADLINE_OFFSET)); - } else { - deadline_offset = offset; - offset += (c_ulong) sizeof(wqos->deadline.v.period); - } - if (c_timeIsInfinite(wqos->liveliness.v.lease_duration)) { - byte0 = (c_octet) (byte0 | _LSHIFT_(1,MQ_BYTE0_LIVELINESS_OFFSET)); - } else { - liveliness_offset = offset; - offset += (c_ulong) sizeof(wqos->liveliness.v.lease_duration); - } - if (c_timeIsInfinite(wqos->lifespan.v.duration)) { - byte0 = (c_octet) (byte0 | _LSHIFT_(1,MQ_BYTE0_LIFESPAN_OFFSET)); - } else { - lifespan_offset = offset; - offset += (c_ulong) sizeof(wqos->lifespan.v.duration); - } - - _this = c_newArray((c_collectionType)writer->msgQosType,offset); - - if (_this) { - ((c_octet *)_this)[0] = byte0; - ((c_octet *)_this)[1] = byte1; - src = (c_octet *)&wqos->transport.v.value; - dst = (c_octet *)&((c_octet *)_this)[2]; - _COPY4_(dst,src); - - if (strength_offset) { - src = (c_octet *)&wqos->strength.v.value; - dst = (c_octet *)&((c_octet *)_this)[strength_offset]; - _COPY4_(dst,src); - } - if (latency_offset) { - src = (c_octet *)&wqos->latency.v.duration; - dst = (c_octet *)&((c_octet *)_this)[latency_offset]; - _COPY8_(dst,src); - } - if (deadline_offset) { - src = (c_octet *)&wqos->deadline.v.period; - dst = (c_octet *)&((c_octet *)_this)[deadline_offset]; - _COPY8_(dst,src); - } - if (liveliness_offset) { - src = (c_octet *)&wqos->liveliness.v.lease_duration; - dst = (c_octet *)&((c_octet *)_this)[liveliness_offset]; - _COPY8_(dst,src); - } - if (lifespan_offset) { - src = (c_octet *)&wqos->lifespan.v.duration; - dst = (c_octet *)&((c_octet *)_this)[lifespan_offset]; - _COPY8_(dst,src); - } - } else { - OS_REPORT(OS_CRITICAL, - "v_messageQos_new",V_RESULT_INTERNAL_ERROR, - "Failed to allocate messageQos."); - assert(FALSE); - } - return _this; -} -#endif - v_messageQos v_messageQos_copy ( v_messageQos src) diff --git a/src/kernel/code/v_minValue.c b/src/kernel/code/v_minValue.c index 6ab2f8f0b..8024d428f 100644 --- a/src/kernel/code/v_minValue.c +++ b/src/kernel/code/v_minValue.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/code/v_nameSpace.c b/src/kernel/code/v_nameSpace.c new file mode 100644 index 000000000..c96d52625 --- /dev/null +++ b/src/kernel/code/v_nameSpace.c @@ -0,0 +1,361 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#include "v__nameSpace.h" +#include "v_cfAttribute.h" +#include "v_cfData.h" +#include "v_cfElement.h" +#include "v_cfNode.h" +#include "os_heap.h" + +#define V_MAX_STRLEN_NAMESPACE (101) /* same as D_MAX_STRLEN_NAMESPACE */ + +/* NOTE: function is base on d_nameSpaceAddElement */ +static struct v_nameSpacePartitionTopic * +formatPartitionTopic ( + const char * partitionTopic, + const char * topicGiven ) +{ + struct v_nameSpacePartitionTopic *result = NULL; + char * partition; + char * topic; + os_uint32 strlenPartitionTopic; + os_uint32 strlenTopicGiven; + + /* QAC EXPECT 1253; */ + strlenPartitionTopic = (os_uint32) (strlen(partitionTopic) + 1); + /* if strlen exceeds max strlen NULL is returned and assumed that + * the durability service reports an error */ + if (strlenPartitionTopic < V_MAX_STRLEN_NAMESPACE) { + if (topicGiven) { + /* QAC EXPECT 1253; */ + strlenTopicGiven = (os_uint32) (strlen(topicGiven) + 1); + /* QAC EXPECT 1253; */ + /* if strlen exceeds max strlen NULL is returned and assumed that + * the durability service reports an error */ + if (strlenTopicGiven < V_MAX_STRLEN_NAMESPACE) { + result = os_malloc(sizeof(struct v_nameSpacePartitionTopic)); + result->partition = os_strdup(partitionTopic); + result->topic = os_strdup(topicGiven); + } + } else { + partition = os_malloc(strlenPartitionTopic); + + os_strncpy(partition, partitionTopic, strlenPartitionTopic); + /* Make topic point to last character in partition string. + * partition points to first character and strlenPartitionTopic + * includes '\0', so subtract 2 to point to last character. + */ + topic = partition + (strlenPartitionTopic-2); + + /* QAC EXPECT 2106,3123; */ + while ((*topic != '.') && (topic != partition)) { + /* QAC EXPECT 0489; */ + topic--; + } + /* QAC EXPECT 2106,3123; */ + if (*topic == '.') { + *topic = 0; + /* QAC EXPECT 0489; */ + topic++; + /* QAC EXPECT 2106; */ + if (*topic != 0) { + result = os_malloc(sizeof(struct v_nameSpacePartitionTopic)); + result->partition = os_strdup(partition); + result->topic = os_strdup(topic); + } + } else { + /* Though was used in the definition of a namespace, only + * a partition is provided. */ + result = os_malloc(sizeof(struct v_nameSpacePartitionTopic)); + result->partition = os_strdup(partition); + result->topic = os_strdup("*"); + } + os_free(partition); + } + } + + return result; +} + +static c_iter +configurationCollectEnabledServices ( + v_configuration config) +{ + c_iter result = NULL; + + c_iter services; + v_cfNode tmp; + + v_cfAttribute attribute; + c_value value; + + services = v_cfElementXPath(config->root, "Domain/Service"); + + while ((tmp = v_cfNode(c_iterTakeFirst(services))) != NULL) { + if (v_cfNodeKind(tmp) == V_CFELEMENT) { + c_bool enabled = TRUE; + + attribute = v_cfElementAttribute(v_cfElement(tmp), "enabled"); + if (attribute != NULL) { + enabled = FALSE; + value = v_cfAttributeValue(attribute); + if (value.kind == V_STRING) { + if (strcmp(value.is.String, "true") == 0) { + enabled = TRUE; + } + } + } + + if (enabled) { + attribute = v_cfElementAttribute(v_cfElement(tmp), "name"); + if (attribute != NULL) { + value = v_cfAttributeValue(attribute); + if (value.kind == V_STRING) { + result = c_iterAppend(result, os_strdup(value.is.String)); + } + } + } + } + } + c_iterFree(services); + return result; +} + +static c_iter /* v_cfElement */ +configurationCollectDurabilityServices ( + v_configuration config) +{ + c_iter result = NULL; + c_iter enabledServices; + c_iter durabilityServices; + v_cfNode tmp; + v_cfAttribute attribute; + c_value value; + char *name; + + assert(config); + assert(C_TYPECHECK(config,v_configuration)); + + enabledServices = configurationCollectEnabledServices(config); + if (c_iterLength(enabledServices) > 0) { + durabilityServices = v_cfElementXPath(config->root, "DurabilityService"); + while ((tmp = v_cfNode(c_iterTakeFirst(durabilityServices))) != NULL) { + if (v_cfNodeKind(tmp) == V_CFELEMENT) { + attribute = v_cfElementAttribute(v_cfElement(tmp), "name"); + if (attribute != NULL) { + value = v_cfAttributeValue(attribute); + if (value.kind == V_STRING) { + c_iterIter it = c_iterIterGet(enabledServices); + + while ((name = c_iterNext(&it)) != NULL) { + if (strcmp(name, value.is.String) == 0) { + result = c_iterAppend(result, tmp); + break; + } + } + } + } + } + } + c_iterFree(durabilityServices); + } + + while ((name = c_iterTakeFirst(enabledServices)) != NULL) { + os_free(name); + } + c_iterFree(enabledServices); + + return result; +} + +static c_iter +elementResolvePartition ( + v_cfElement element) +{ + c_iter result = NULL; + c_iter nodes, nodes2; + v_cfNode tmp, tmp2; + + nodes = v_cfElementXPath(element, "Partition"); + while ((tmp = v_cfNode(c_iterTakeFirst(nodes))) != NULL) { + if (v_cfNodeKind(tmp) == V_CFELEMENT) { + nodes2 = v_cfElementGetChildren(v_cfElement(tmp)); + if (c_iterLength(nodes2) > 0) { + while ((tmp2 = v_cfNode(c_iterTakeFirst(nodes2))) != NULL) { + if(v_cfNodeKind(tmp2) == V_CFDATA) { + c_value value; + value = v_cfDataValue(v_cfData(tmp2)); + if (value.kind == V_STRING) { + struct v_nameSpacePartitionTopic * pt = formatPartitionTopic(value.is.String, "*"); + result = c_iterAppend(result, pt); + } + } + } + } else { + struct v_nameSpacePartitionTopic * pt = formatPartitionTopic("", "*"); + result = c_iterAppend(result, pt); + } + c_iterFree(nodes2); + } + } + c_iterFree(nodes); + return result; +} + +static c_iter +elementResolvePartitionTopic ( + v_cfElement element) +{ + c_iter result = NULL; + c_iter nodes, nodes2; + v_cfNode tmp, tmp2; + + nodes = v_cfElementXPath(element, "PartitionTopic"); + while ((tmp = v_cfNode(c_iterTakeFirst(nodes))) != NULL) { + if (v_cfNodeKind(tmp) == V_CFELEMENT) { + nodes2 = v_cfElementGetChildren(v_cfElement(tmp)); + if (c_iterLength(nodes2) > 0) { + while ((tmp2 = v_cfNode(c_iterTakeFirst(nodes2))) != NULL) { + if(v_cfNodeKind(tmp2) == V_CFDATA) { + c_value value; + value = v_cfDataValue(v_cfData(tmp2)); + if (value.kind == V_STRING) { + struct v_nameSpacePartitionTopic * pt = formatPartitionTopic(value.is.String, NULL); + result = c_iterAppend(result, pt); + } + } + } + } else { + struct v_nameSpacePartitionTopic * pt = formatPartitionTopic("*.*", NULL); + result = c_iterAppend(result, pt); + } + c_iterFree(nodes2); + } + } + c_iterFree(nodes); + return result; +} + +c_iter /* v_nameSpace */ +v__nameSpaceCollect ( + v_kernel kernel) +{ + c_iter result = NULL; + + v_configuration config; + + c_iter elements; + v_cfElement e; + c_iter nodes; + v_cfNode n; + v_cfAttribute attribute; + c_value value; + + assert(kernel); + assert(C_TYPECHECK(kernel,v_kernel)); + + config = v_getConfiguration(kernel); + if (config) { + elements = configurationCollectDurabilityServices(config); + while ((e = v_cfElement(c_iterTakeFirst(elements))) != NULL) { + assert(v_cfNodeKind(v_cfNode(e)) == V_CFELEMENT); + + nodes = v_cfElementXPath(e, "NameSpaces/NameSpace"); + while ((n = v_cfNode(c_iterTakeFirst(nodes))) != NULL) { + if (v_cfNodeKind(n) == V_CFELEMENT) { + attribute = v_cfElementAttribute(v_cfElement(n), "name"); + + if (attribute != NULL) { + value = v_cfAttributeValue(attribute); + if (value.kind == V_STRING) { + c_iter list = NULL; + list = elementResolvePartition(v_cfElement(n)); + list = c_iterConcat(list, elementResolvePartitionTopic(v_cfElement(n))); + + if (c_iterLength(list) > 0) { + struct v_nameSpace *ns; + + ns = os_malloc(sizeof(struct v_nameSpace)); + ns->name = os_strdup(value.is.String); + ns->partitionTopics = list; + result = c_iterAppend(result, ns); + } + } + } + } + } + c_iterFree(nodes); + } + c_iterFree(elements); + } + + return result; +} + +static c_bool +patternMatch( + char *pattern, + char *str) +{ + c_value p,n,r; + + p.kind = n.kind = V_STRING; + p.is.String = (char *)pattern; + n.is.String = (char *)str; + r = c_valueStringMatch(p,n); + return r.is.Boolean; +} + +c_bool +v__nameSpaceIsIn ( + struct v_nameSpace *ns, + os_char *partition, + os_char *topic) +{ + c_bool result = FALSE; + c_iterIter iter; + struct v_nameSpacePartitionTopic *pt; + + iter = c_iterIterGet(ns->partitionTopics); + while (((pt = c_iterNext(&iter)) != NULL) && (result == FALSE)) { + if ((patternMatch(pt->partition, partition)) && + (patternMatch(pt->topic, topic))) { + result = TRUE; + } + } + + return result; +} + +void +v__nameSpaceFree ( + struct v_nameSpace *ns) +{ + struct v_nameSpacePartitionTopic *pt; + + os_free(ns->name); + while ((pt = c_iterTakeFirst(ns->partitionTopics)) != NULL) { + os_free(pt->partition); + os_free(pt->topic); + os_free(pt); + } + os_free(ns); +} diff --git a/src/kernel/code/v_networkChannelStatistics.c b/src/kernel/code/v_networkChannelStatistics.c index 2dca8c824..450584dce 100644 --- a/src/kernel/code/v_networkChannelStatistics.c +++ b/src/kernel/code/v_networkChannelStatistics.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/code/v_networkHashValue.c b/src/kernel/code/v_networkHashValue.c new file mode 100644 index 000000000..46fdb6cce --- /dev/null +++ b/src/kernel/code/v_networkHashValue.c @@ -0,0 +1,76 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "kernelModuleI.h" +#include "c_typebase.h" +#include "v_networkHashValue.h" + +v_networkHashValue +v_networkHashValueCalculate( + const char * key1, + const char * key2) +{ + v_networkHashValue result = {0xa0, 0x22, 0x8d, 0x07}; + const char *currentPtr; + + assert(key1); + +#define NW_ROT_CHAR(val, rot) ((c_octet) (((val) << (rot)) + ((val) >> (8-(rot))))) + currentPtr = key1; + while (*currentPtr != '\0') { + /* gcc2.96 gave internal compile errrors (with optimisation enabled) + * when compiling the NW_ROT_CHAR macro twice in same command : + * these assignments are deliberatly split over 2 lines as workaround. + */ + result.h1 = (c_octet) (NW_ROT_CHAR(result.h1, 1) + NW_ROT_CHAR(*currentPtr, 4)); + result.h2 = (c_octet) (NW_ROT_CHAR(result.h2, 2) + NW_ROT_CHAR(*currentPtr, 7)); + result.h3 = (c_octet) (NW_ROT_CHAR(result.h3, 3) + NW_ROT_CHAR(*currentPtr, 1)); + result.h4 = (c_octet) (NW_ROT_CHAR(result.h4, 4) + NW_ROT_CHAR(*currentPtr, 5)); + currentPtr++; + } + + currentPtr = key2; + while (currentPtr && *currentPtr != '\0') { + result.h1 = (c_octet) (NW_ROT_CHAR(result.h1, 4) + NW_ROT_CHAR(*currentPtr, 7)); + result.h2 = (c_octet) (NW_ROT_CHAR(result.h2, 3) + NW_ROT_CHAR(*currentPtr, 1)); + result.h3 = (c_octet) (NW_ROT_CHAR(result.h3, 2) + NW_ROT_CHAR(*currentPtr, 5)); + result.h4 = (c_octet) (NW_ROT_CHAR(result.h4, 1) + NW_ROT_CHAR(*currentPtr, 4)); + currentPtr++; + } +#undef NW_ROT_CHAR + return result; +} + +c_equality +v_networkHashValueCompare( + v_networkHashValue * value1, + v_networkHashValue * value2) +{ + if (value1->h1 < value2->h1) return C_LT; + if (value1->h1 > value2->h1) return C_GT; + if (value1->h2 < value2->h2) return C_LT; + if (value1->h2 > value2->h2) return C_GT; + if (value1->h3 < value2->h3) return C_LT; + if (value1->h3 > value2->h3) return C_GT; + if (value1->h4 < value2->h4) return C_LT; + if (value1->h4 > value2->h4) return C_GT; + return C_EQ; +} diff --git a/src/kernel/code/v_networkMessage.h b/src/kernel/code/v_networkMessage.h index 3faeaacdd..8e9d8e2be 100644 --- a/src/kernel/code/v_networkMessage.h +++ b/src/kernel/code/v_networkMessage.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/code/v_networkQueue.c b/src/kernel/code/v_networkQueue.c index 813b77071..fe9f8c144 100644 --- a/src/kernel/code/v_networkQueue.c +++ b/src/kernel/code/v_networkQueue.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -83,7 +84,8 @@ v_networkQueueUpdateNextWakeup( TIMEE_TO_MSEC(now, msecsTime); /* Do a ++ because we are doing a ceil and TIME_TO_MSEC is doing a trunc. * Only if time was an exact multiple of milliseconds, this approach is - * not completely correct. But it saves us the hassle and this works fine */ + * not completely correct. But it saves us the hassle and this works fine + */ msecsTime++; msecsLeftOver = (msecsTime - queue->phaseMilliSeconds) % queue->msecsResolution; msecsResult = msecsTime - msecsLeftOver + queue->msecsResolution; @@ -142,7 +144,7 @@ v_networkQueueNew( result->freeStatusMarkers = NULL; result->freeSamples = NULL; /* Init cv stuff */ - c_mutexInit(c_getBase(result), &result->mutex); + (void)c_mutexInit(c_getBase(result), &result->mutex); c_condInit(c_getBase(result), &result->cv, &result->mutex); /* Currently no differentiation wrt qos */ result->priority = priority; @@ -210,7 +212,6 @@ v_networkQueueWrite( c_mutexLock(&queue->mutex); sendBefore = OS_TIMEE_ZERO; - /* numberOfSamplesArrived statistics */ if (queue->statistics) { queue->statistics->numberOfSamplesArrived++; } @@ -229,7 +230,6 @@ v_networkQueueWrite( if (!v_messageStateTest(msg,L_UNREGISTER)) { if (queue->currentMsgCount >= queue->maxMsgCount) { c_mutexUnlock(&queue->mutex); - /* numberOfSamplesRejected stat */ if (queue->statistics) { queue->statistics->numberOfSamplesRejected++; } @@ -331,7 +331,6 @@ v_networkQueueWrite( queue->currentMsgCount++; - /* numberOfSamplesInserted & numberOfSamplesWaiting + stats*/ if (queue->statistics) { queue->statistics->numberOfSamplesInserted++; v_fullCounterValueInc(&queue->statistics->numberOfSamplesWaiting); @@ -393,9 +392,10 @@ v_networkQueueTakeFirst( c_mutexLock(&queue->mutex); currentMarker = queue->firstStatusMarker; - /* Note: the current design expects that this function has been preceded + /* NOTE: the current design expects that this function has been preceded * by a NetworkReaderWait. Therefore, the currentMarker should never - * be NULL. */ + * be NULL. + */ if (currentMarker != NULL) { sample = currentMarker->firstSample; @@ -419,7 +419,6 @@ v_networkQueueTakeFirst( /* Remove and free holder */ queue->currentMsgCount--; - /* numberOfSamplesTaken+ & numberOfSamplesWaiting- stats */ if (queue->statistics) { queue->statistics->numberOfSamplesTaken++; v_fullCounterValueDec(&queue->statistics->numberOfSamplesWaiting); @@ -466,7 +465,6 @@ v_networkQueueTakeAction( if (sample != NULL) { proceed = action(sample, arg); queue->currentMsgCount--; - /* numberOfSamplesTaken+ & numberOfSamplesWaiting- stats */ if (queue->statistics) { queue->statistics->numberOfSamplesTaken++; v_fullCounterValueDec(&queue->statistics->numberOfSamplesWaiting); diff --git a/src/kernel/code/v_networkQueueStatistics.c b/src/kernel/code/v_networkQueueStatistics.c index 03f46cf76..c9ca2ade4 100644 --- a/src/kernel/code/v_networkQueueStatistics.c +++ b/src/kernel/code/v_networkQueueStatistics.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/code/v_networkReader.c b/src/kernel/code/v_networkReader.c index 308b789ee..0b300f920 100644 --- a/src/kernel/code/v_networkReader.c +++ b/src/kernel/code/v_networkReader.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,6 +25,7 @@ /* Implementation */ #include "vortex_os.h" #include "os_report.h" +#include "os_atomics.h" #include "c_base.h" #include "kernelModuleI.h" #include "v__networkQueue.h" @@ -67,7 +69,8 @@ v_networkReaderNew( c_bool ignoreReliabilityQoS) { /* Note: currently, no qos-es are supported. Everything is redirected - * to the defaultQueue */ + * to the defaultQueue + */ v_kernel kernel; v_networkReader reader = NULL; @@ -88,7 +91,9 @@ v_networkReaderNew( reader->statistics = v_networkReaderStatisticsNew(kernel); /* Initialization of parent */ - v_readerInit(v_reader(reader), name, subscriber, q, TRUE); + v_readerInit(v_reader(reader), name, subscriber, q); + (void)v_entityEnable(v_entity(reader)); + c_free(q); /* ref now in v_reader(queue)->qos */ /* This function only ever called once per network instance so no @@ -198,8 +203,7 @@ v_networkReaderCreateQueue( reader->queues[reader->nofQueues] = queue; reader->nofQueues++; result = reader->nofQueues; - /* insert statistics - */ + /* insert statistics */ if (nqs != NULL) { s = reader->statistics; if (s != NULL) { @@ -289,7 +293,8 @@ v_networkReaderSelectBestQueueByReliability( } else { if (prio < queuePrio) { /* This queue might be the best fit, it offers higher prio - * than requested */ + * than requested + */ if (possiblyBestQueue != NULL) { if (queuePrio < possiblyBestQueue->priority) { possiblyBestQueue = currentQueue; @@ -301,7 +306,8 @@ v_networkReaderSelectBestQueueByReliability( if (possiblyBestQueue == NULL) { /* No queue fits until now, but this queue * might be the best alternative if no queue - * offers the requested prio at all */ + * offers the requested prio at all + */ if (bestAlternativeQueue != NULL) { if (queuePrio > bestAlternativeQueue->priority) { bestAlternativeQueue = currentQueue; @@ -395,7 +401,8 @@ v_networkReaderSelectBestQueueIgnoreReliability( if (possiblyBestQueue == NULL) { /* No queue fits until now, but this queue * might be the best alternative if no queue - * offers the requested prio at all */ + * offers the requested prio at all + */ if (bestAlternativeQueue != NULL) { if (queuePrio > bestAlternativeQueue->priority) { bestAlternativeQueue = currentQueue; @@ -433,7 +440,8 @@ v_networkReaderSelectBestQueue( { if (reader->ignoreReliabilityQoS) { /* this mode is required for DDSi, where a singlee channel is - serving best-effort and reliable messages */ + * serving best-effort and reliable messages + */ return v_networkReaderSelectBestQueueIgnoreReliability (reader, qos, @@ -444,7 +452,8 @@ v_networkReaderSelectBestQueue( else { /* Note: else-branch is the fast path */ /* this mode is required for legacy OSPL protocol, change order - when DDSi becomes the default protocol */ + * when DDSi becomes the default protocol + */ return v_networkReaderSelectBestQueueByReliability (reader, qos, @@ -471,7 +480,7 @@ v_networkReaderWrite( assert(C_TYPECHECK(reader, v_networkReader)); /* First select the best queue */ - if (reader->remoteActivity) { + if (reader->remoteActivity && !(pa_ld32(&v_objectKernel(reader)->isolate) & V_ISOLATE_MUTE)) { if (message != NULL) { bestQueue = v_networkReaderSelectBestQueue( reader, @@ -527,10 +536,11 @@ v_networkReaderWaitDelayed( os_duration sleep; /* Simply sleeping here for resolution time, is not correct. - We should wakeup on, or just after the next wakeuptime.*/ + * We should wakeup on, or just after the next wakeuptime. + */ sleep = os_timeEDiff(v_networkQueue(reader->queues[queueId-1])->nextWakeup, os_timeEGet()); v__kernelProtectWaitEnter(NULL, NULL); - os_sleep(sleep); + ospl_os_sleep(sleep); v__kernelProtectWaitExit(); return V_WAITRESULT_TIMEOUT | v_networkReaderWait(reader, queueId, queue); @@ -558,68 +568,36 @@ void v_networkReaderFree( v_networkReader reader) { - /* call inherited free */ + c_bool sendTo, more; + v_message message; + c_ulong sequenceNumber, priority; + v_gid sender, receiver; + os_timeE sendBefore; + v_networkReaderEntry entry; + c_ulong i; + + c_keep(reader); + + /* call inherited free, + * which will remove the entry from the associated groups + */ v_readerFree(v_reader(reader)); -} - - -/* ------------------------ Subscription/Unsubscription --------------------- */ - -static c_bool -v_networkReaderEntryUnSubscribe( - v_networkReaderEntry entry, - v_partition partition) -{ - assert(C_TYPECHECK(entry, v_networkReaderEntry)); - assert(C_TYPECHECK(partition, v_partition)); - if (v_group(entry->group)->partition == partition) { - v_groupRemoveEntry(entry->group, v_entry(entry)); - } - - return TRUE; -} - - -c_bool -v_networkReaderUnSubscribe( - v_networkReader reader, - v_partition partition) -{ - assert(C_TYPECHECK(reader, v_networkReader)); - assert(C_TYPECHECK(partition, v_partition)); - - return v_readerWalkEntries(v_reader(reader), - (c_action)v_networkReaderEntryUnSubscribe, partition); -} - -static c_bool -v_networkReaderEntryUnSubscribeGroup( - v_networkReaderEntry entry, - v_group group) -{ - assert(C_TYPECHECK(entry, v_networkReaderEntry)); - assert(C_TYPECHECK(group, v_group)); - - if (v_group(entry->group) == group) { - v_groupRemoveEntry(entry->group, v_entry(entry)); + /* remove the messages still pressent in the network queues */ + for (i = 0; i < reader->nofQueues; i++) { + while (v_networkQueueTakeFirst ( + v_networkQueue(reader->queues[i]), &message, &entry, &sequenceNumber, + &sender, &sendTo, &receiver, &sendBefore, &priority, &more)) { + c_free(message); + c_free(entry); + } } - return TRUE; + c_free(reader); } -c_bool -v_networkReaderUnSubscribeGroup( - v_networkReader reader, - v_group group) -{ - assert(C_TYPECHECK(reader, v_networkReader)); - assert(C_TYPECHECK(group, v_group)); - - return v_readerWalkEntries(v_reader(reader), - (c_action)v_networkReaderEntryUnSubscribeGroup, group); -} +/* ------------------------ Subscription/Unsubscription --------------------- */ struct v_findEntryArg { v_group group; diff --git a/src/kernel/code/v_networkReaderEntry.c b/src/kernel/code/v_networkReaderEntry.c index 9793918a2..75b5a6130 100644 --- a/src/kernel/code/v_networkReaderEntry.c +++ b/src/kernel/code/v_networkReaderEntry.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -28,15 +29,16 @@ #include "v__reader.h" /* for v_reader() */ #include "v__writer.h" /* for v_writer() */ #include "v_writerSample.h" -#include "v_group.h" /* for v_group() */ -#include "v_message.h" /* for v_message() */ -#include "v_entity.h" /* for v_entity() */ +#include "v_group.h" /* for v_group() */ +#include "v_message.h" /* for v_message() */ +#include "v_entity.h" /* for v_entity() */ #include "v_handle.h" #include "v__networkReader.h" /* Friend class */ #include "v_public.h" #include "v_topic.h" #include "v_partition.h" #include "v_writerInstance.h" +#include "v_networkHashValue.h" #ifdef __VERBOSE__ #include "os_time.h" @@ -64,48 +66,15 @@ #define __PRINT_3__(msg, a1, a2, a3) #endif /* __VERBOSE__ */ - - /* ----------------------------- v_networkReaderEntry ----------------------- */ - -#define NW_ROT_CHAR(val, rot) ((c_octet) (((val) << (rot)) + ((val) >> (8-(rot))))) - static v_networkHashValue v_networkReaderEntryCalculateHashValue( v_networkReaderEntry entry) { - v_networkHashValue result = {0xa0, 0x22, 0x8d, 0x07}; - - const char *partitionName; - const char *topicName; - const char *currentPtr; - - partitionName = v_partitionName(v_groupPartition(entry->group)); - topicName = v_topicName(v_groupTopic(entry->group)); - currentPtr = partitionName; - - while (*currentPtr != '\0') { - /* gcc2.96 gave internal compile errrors (with optimisation enabled) - * when compiling the NW_ROT_CHAR macro twice in same command : - * these assignments are deliberatly split over 2 lines as workaround. - */ - result.h1 = (c_octet) (NW_ROT_CHAR(result.h1, 1) + NW_ROT_CHAR(*currentPtr, 4)); - result.h2 = (c_octet) (NW_ROT_CHAR(result.h2, 2) + NW_ROT_CHAR(*currentPtr, 7)); - result.h3 = (c_octet) (NW_ROT_CHAR(result.h3, 3) + NW_ROT_CHAR(*currentPtr, 1)); - result.h4 = (c_octet) (NW_ROT_CHAR(result.h4, 4) + NW_ROT_CHAR(*currentPtr, 5)); - currentPtr++; - } - - currentPtr = topicName; - while (*currentPtr != '\0') { - result.h1 = (c_octet) (NW_ROT_CHAR(result.h1, 4) + NW_ROT_CHAR(*currentPtr, 7)); - result.h2 = (c_octet) (NW_ROT_CHAR(result.h2, 3) + NW_ROT_CHAR(*currentPtr, 1)); - result.h3 = (c_octet) (NW_ROT_CHAR(result.h3, 2) + NW_ROT_CHAR(*currentPtr, 5)); - result.h4 = (c_octet) (NW_ROT_CHAR(result.h4, 1) + NW_ROT_CHAR(*currentPtr, 4)); - currentPtr++; - } - return result; + return v_networkHashValueCalculate( + v_partitionName(v_groupPartition(entry->group)), + v_topicName(v_groupTopic(entry->group))); } @@ -119,21 +88,17 @@ v_networkReaderEntryInit( v_networkPartitionId networkPartitionId, v_networkRoutingMode routing) { - v_networkReaderEntry found; - v_entryInit(v_entry(entry),v_reader(reader)); entry->group = c_keep(group); entry->networkId = networkId; entry->channelCountdown = channelsToConnect; - c_mutexInit(c_getBase(entry), &entry->channelCountdownMutex); + (void)c_mutexInit(c_getBase(entry), &entry->channelCountdownMutex); entry->networkPartitionId = networkPartitionId; entry->hashValue = v_networkReaderEntryCalculateHashValue(entry); entry->routing = routing; - found = v_networkReaderEntry(v_readerAddEntry(v_reader(reader), v_entry(entry))); - assert(found == entry); - c_free(found); + v_readerAddEntry(v_reader(reader), v_entry(entry)); } /* Protected constructor */ @@ -178,8 +143,10 @@ v_networkReaderEntryNotifyConnected( c_mutexUnlock(&entry->channelCountdownMutex); if (allChannelsConnected) { - v_groupAddEntry(v_group(entry->group), v_entry(entry)); - v_groupNotifyAwareness(v_group(entry->group),serviceName,TRUE); + if (v_groupAddEntry(v_group(entry->group), v_entry(entry))) { + v_entryAddGroup(v_entry(entry), v_group(entry->group)); + v_groupNotifyAwareness(v_group(entry->group),serviceName,TRUE); + } } } diff --git a/src/kernel/code/v_networkReaderStatistics.c b/src/kernel/code/v_networkReaderStatistics.c index 8a6e6683d..9a6b111c4 100644 --- a/src/kernel/code/v_networkReaderStatistics.c +++ b/src/kernel/code/v_networkReaderStatistics.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/code/v_networking.c b/src/kernel/code/v_networking.c index c0e28514b..ce5955970 100644 --- a/src/kernel/code/v_networking.c +++ b/src/kernel/code/v_networking.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,10 +22,12 @@ #include "v_networkingStatistics.h" #include "v_service.h" #include "v_participant.h" +#include "v__observable.h" #include "v__statCat.h" #include "v__kernel.h" #include "os_report.h" +#include "os_atomics.h" v_networking v_networkingNew( @@ -59,6 +62,8 @@ v_networkingNew( if (v_service(s)->state == NULL) { v_serviceFree(v_service(s)); s = NULL; + } else { + OSPL_ADD_OBSERVER(kernel, s, V_EVENT_NEW_GROUP, NULL); } } return s; diff --git a/src/kernel/code/v_networkingStatistics.c b/src/kernel/code/v_networkingStatistics.c index 9aa70fbbb..e65192ab7 100644 --- a/src/kernel/code/v_networkingStatistics.c +++ b/src/kernel/code/v_networkingStatistics.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/code/v_nwbridge.c b/src/kernel/code/v_nwbridge.c index bcfa38dc2..209c8254a 100644 --- a/src/kernel/code/v_nwbridge.c +++ b/src/kernel/code/v_nwbridge.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,6 +27,7 @@ #include "v__groupInstance.h" #include "v_group.h" #include "v__kernel.h" +#include "v__observable.h" #include "v_participant.h" #include "os_report.h" @@ -51,18 +53,13 @@ v_nwbridgeNew( } else { s = v_nwbridge(v_objectNew(kernel, K_NWBRIDGE)); -#if 0 - if (v_isEnabledStatistics(kernel, V_STATCAT_NWBRIDGE)) { - s->statistics = v_nwbridgeStatisticsNew(kernel); - } else { - s->statistics = NULL; - } -#endif v_serviceInit(v_service(s), name, extStateName, V_SERVICETYPE_NWBRIDGE, q, enable); c_free(q); if (v_service(s)->state == NULL) { v_serviceFree(v_service(s)); s = NULL; + } else { + OSPL_ADD_OBSERVER(kernel, s, V_EVENT_NEW_GROUP, NULL); } } return s; diff --git a/src/kernel/code/v_objectLoan.c b/src/kernel/code/v_objectLoan.c index c696a77fa..76d1801ab 100644 --- a/src/kernel/code/v_objectLoan.c +++ b/src/kernel/code/v_objectLoan.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -81,8 +82,12 @@ v_objectLoanRelease ( * E.g. we don't want to free and allocate a buffer for each read or take operation of * a reader, especially when reading one sample at the time. */ - c_free(v_objectBuffer(loan)->next); - v_objectBuffer(loan)->next = NULL; + while (v_objectBuffer(loan)->next != NULL) { + v_objectBuffer tmp = v_objectBuffer(loan)->next; + v_objectBuffer(loan)->next = tmp->next; + tmp->next = NULL; + c_free(tmp); + } if (loan->index > LOANSIZE) { loan->index = LOANSIZE; diff --git a/src/kernel/code/v_observable.c b/src/kernel/code/v_observable.c index 7bbe66501..d73a51388 100644 --- a/src/kernel/code/v_observable.c +++ b/src/kernel/code/v_observable.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,19 +19,55 @@ * */ #include "v__observable.h" -#include "v__entity.h" -#include "v_observer.h" +#include "v__observer.h" #include "v_proxy.h" #include "v_public.h" #include "v_event.h" -#include "os_report.h" +#include "vortex_os.h" -#define _USE_HANDLE_ +void v_observableBlock(v_observable o) { c_mutexLock(&o->eventLock); } +void v_observableUnblock(v_observable o) { c_mutexUnlock(&o->eventLock); } +void v_observableLock(v_observable o) { c_mutexLock(&o->mutex); } +void v_observableUnlock(v_observable o) { c_mutexUnlock(&o->mutex); } + +void +v_observableInit( + v_observable o) +{ + assert(o != NULL); + assert(C_TYPECHECK(o,v_observable)); + + o->observers = NULL; + (void)c_mutexInit(c_getBase(o), &o->mutex); + (void)c_mutexInit(c_getBase(o), &o->eventLock); + v_publicInit(v_public(o)); +} + +void +v_observableFree( + v_observable o) +{ + assert(o != NULL); + assert(C_TYPECHECK(o,v_observable)); + + v_publicFree(v_public(o)); +} + +void +v_observableDeinit( + v_observable o) +{ + assert(o != NULL); + assert(C_TYPECHECK(o,v_observable)); + + v_publicDeinit(v_public(o)); +} c_bool v_observableAddObserver( v_observable o, v_observer observer, + v_eventMask mask, c_voidp userData) { v_proxy proxy; @@ -42,25 +79,29 @@ v_observableAddObserver( assert(o != v_observable(observer)); - c_mutexLock(&o->mutex); + OSPL_ADD_EVENT_MASK(observer,mask); + OSPL_BLOCK_EVENTS(o); handle = v_publicHandle(v_public(observer)); proxy = o->observers; while (proxy) { - if (v_handleIsEqual(proxy->source, handle)) break; + assert(c_refCount(proxy) == 1); + if (v_handleIsEqual(proxy->source, handle)) { + proxy->eventMask |= mask; + proxy->userData = userData; + break; + } proxy = proxy->next; } - if (!proxy) { + if (proxy == NULL) { + /* add observer to the observer list */ proxy = v_proxyNew(v_objectKernel(o), handle, userData); - /* remnant of proto typing hard referenced proxy objects in stead of - * using handles. Needs some clean-up activity. - * Also see the undefined _USE_HANDLE_ macro. - */ - proxy->source2 = observer; + proxy->source2 = c_keep(observer); proxy->next = o->observers; + proxy->eventMask = mask; o->observers = proxy; + proxy = proxy->next; } - proxy->userData = userData; - c_mutexUnlock(&o->mutex); + OSPL_UNBLOCK_EVENTS(o); return TRUE; } @@ -68,6 +109,7 @@ c_bool v_observableRemoveObserver( v_observable o, v_observer observer, + v_eventMask mask, void** userData) { v_proxy proxy, prev; @@ -80,111 +122,73 @@ v_observableRemoveObserver( assert(o != v_observable(observer)); - c_mutexLock(&o->mutex); + OSPL_BLOCK_EVENTS(o); handle = v_publicHandle(v_public(observer)); prev = NULL; proxy = o->observers; while (proxy) { + assert(c_refCount(proxy) == 1); if (v_handleIsEqual(proxy->source, handle)) { + /* Found the observer in the list so now remove and free it. */ if (userData) { *userData = proxy->userData; } - if (prev) { - prev->next = proxy->next; - } else { - o->observers = proxy->next; + proxy->eventMask &= ~mask; + if (proxy->eventMask == 0) { + if (prev) { + prev->next = proxy->next; + } else { + o->observers = proxy->next; + } + proxy->next = NULL; + c_free(proxy); } - proxy->next = NULL; - c_free(proxy); result = TRUE; - break; + break; /* observer found and removed from the observer list => break out the loop */ } + /* proceed to the next observer in the list. */ prev = proxy; proxy = proxy->next; } - c_mutexUnlock(&o->mutex); + OSPL_UNBLOCK_EVENTS(o); return result; } -void -v_observableInit( - v_observable o) -{ - assert(o != NULL); - assert(C_TYPECHECK(o,v_observable)); - - o->observers = NULL; - c_mutexInit(c_getBase(o), &o->mutex); - v_publicInit(v_public(o)); -} - -void -v_observableFree( - v_observable o) -{ - assert(o != NULL); - assert(C_TYPECHECK(o,v_observable)); - - v_publicFree(v_public(o)); -} - -void -v_observableDeinit( - v_observable o) -{ - assert(o != NULL); - assert(C_TYPECHECK(o,v_observable)); - - v_publicDeinit(v_public(o)); -} +#if 0 +#define CLAIM(proxy, o) (V_HANDLE_OK == v_handleClaim(proxy->source,(v_object *)(o))); +#define RELEASE(proxy) (void) v_handleRelease(proxy->source) +#else +#define CLAIM(proxy, o) ((*(o) = proxy->source2) != NULL) +#define RELEASE(proxy) +#endif void v_observableNotify( - v_observable o, + v_observable _this, v_event event) { - v_proxy proxy, prev, next; - v_observer ob; - v_observer* oPtr; - v_handleResult r; - - assert(o != NULL); - assert(C_TYPECHECK(o,v_observable)); - - prev = NULL; - c_mutexLock(&o->mutex); - proxy = o->observers; - while (proxy) { - next = proxy->next; -#ifdef _USE_HANDLE_ - oPtr = &ob; - r = v_handleClaim(proxy->source,(v_object *)oPtr); - if (r == V_HANDLE_OK) { -#else - ob = proxy->source2; -#endif - if (v_observable(ob) == o) { - v_observerNotify(ob,event,proxy->userData); - } else { - v_observerLock(ob); - v_observerNotify(ob,event, proxy->userData); - v_observerUnlock(ob); + v_proxy proxy, next; + v_observer o; + + OSPL_BLOCK_EVENTS(_this); + if (event) { + proxy = _this->observers; + while (proxy) { + assert(c_refCount(proxy) == 1); + next = proxy->next; + /* CLAIM returns a ref counted object either via a handle or hard reference. */ + if (CLAIM(proxy, &o)) { + /* Check interest and don't self-trigger to avoid endless looping. */ + if ((v_observable(o) != _this) && (event->kind & proxy->eventMask)) + { + /* TODO : Need to lock o if not already locked by myself */ + OSPL_TRIGGER_EVENT(o, event, proxy->userData); + OSPL_THROW_EVENT(o, event); + } + RELEASE(proxy); } - prev = proxy; -#ifdef _USE_HANDLE_ - (void) v_handleRelease(proxy->source); - } else { - /* The source has already left the system */ - if (prev) { - prev->next = next; - } else { - o->observers = next; - } - proxy->next = NULL; - c_free(proxy); + proxy = next; } -#endif - proxy = next; } - c_mutexUnlock(&o->mutex); + OSPL_UNBLOCK_EVENTS(_this); } diff --git a/src/kernel/code/v_observer.c b/src/kernel/code/v_observer.c old mode 100644 new mode 100755 index 81feca267..6bfad19dd --- a/src/kernel/code/v_observer.c +++ b/src/kernel/code/v_observer.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,6 +22,7 @@ #include "v__observable.h" #include "v__participant.h" +#include "v__subscriber.h" #include "v__dataReader.h" #include "v__groupStream.h" #include "v__waitset.h" @@ -41,20 +43,22 @@ #include "os_report.h" #include "os_process.h" +/* The following three operations are depricated. */ +void v_observerLock(v_observer o) { OSPL_LOCK(o); } +void v_observerUnlock(v_observer o) { OSPL_UNLOCK(o); } + void v_observerInit( - v_observer o) + _Inout_ v_observer o) { assert(o != NULL); assert(C_TYPECHECK(o,v_observer)); - c_mutexInit(c_getBase(o), &o->mutex); /* mutex to protect attributes */ - c_condInit(c_getBase(o), &o->cv, &o->mutex); /* condition variable */ + v_observableInit(v_observable(o)); + c_condInit(c_getBase(o), &o->cv, &v_observable(o)->eventLock); /* condition variable */ o->waitCount = 0; /* number of waiting threads */ o->eventMask = 0; /* specifies, interested events */ o->eventFlags = 0; /* ocurred events */ - o->eventData = NULL; /* general post box for derived classes */ - v_observableInit(v_observable(o)); } void @@ -63,10 +67,12 @@ v_observerFree( { assert(C_TYPECHECK(o,v_observer)); - c_mutexLock(&o->mutex); + OSPL_LOCK(o); + OSPL_BLOCK_EVENTS(o); o->eventFlags |= V_EVENT_OBJECT_DESTROYED; c_condBroadcast(&o->cv); - c_mutexUnlock(&o->mutex); + OSPL_UNBLOCK_EVENTS(o); + OSPL_UNLOCK(o); v_observableFree(v_observable(o)); } @@ -90,13 +96,25 @@ v_observerGetEventFlags( assert(o != NULL); assert(C_TYPECHECK(o,v_observer)); + OSPL_BLOCK_EVENTS(o); flags = o->eventFlags; o->eventFlags &= V_EVENT_OBJECT_DESTROYED; + OSPL_UNBLOCK_EVENTS(o); + EVENT_TRACE("v_observerGetEventFlags(_this = 0x%x, flags = 0x%x)\n", o, flags); + return flags; +} - EVENT_TRACE("v_observerGetEventFlags(_this = 0x%x, flags = 0x%x)\n", - o, flags); +void +v_observerClearEventFlags( + v_observer o) +{ + assert(o != NULL); + assert(C_TYPECHECK(o,v_observer)); - return flags; + OSPL_BLOCK_EVENTS(o); + o->eventFlags &= V_EVENT_OBJECT_DESTROYED; + OSPL_UNBLOCK_EVENTS(o); + EVENT_TRACE("v_observerClearEventFlags(_this = 0x%x)\n", o); } /** @@ -119,7 +137,7 @@ v_observerNotify( * calling Notify(_this, event, userData). * This implies that _this cannot be locked within any Notify method * to avoid deadlocks. - * For consistency _this must be locked by v_observerLock(_this) before + * For consistency _this must be locked by OSPL_LOCK(_this) before * calling this method. */ @@ -129,6 +147,7 @@ v_observerNotify( assert(_this != NULL); assert(C_TYPECHECK(_this,v_observer)); + OSPL_BLOCK_EVENTS(_this); /* The observer will be made insensitive to event as soon as the * observer is deinitialized. However it may be that destruction * of the observer has started before the deinit of the observer @@ -138,7 +157,6 @@ v_observerNotify( if ((_this->eventFlags & V_EVENT_OBJECT_DESTROYED) == 0) { /* The observer is valid so the event can be processed. */ - if (event != NULL ) { trigger = event->kind & _this->eventMask; } else { @@ -149,11 +167,6 @@ v_observerNotify( EVENT_TRACE("v_observerNotify: %s(0x%x), event(0x%x), mask(0x%x), trigger(0x%x) userData(0x%x)\n", v_objectKindImage(_this), _this, event, _this->eventMask, trigger, userData); - if ((_this->eventFlags & trigger) && (trigger != V_EVENT_TRIGGER)) { - notify = FALSE; - } - _this->eventFlags |= trigger; /* store event before trigger is given to waiting threads or subclasses are notified*/ - /* The following code invokes the observers subclass specific * notification method. * This is a bit strange that the observer has knowledge about @@ -164,62 +177,60 @@ v_observerNotify( * method will typically be called from another process. */ if (trigger != 0) { - switch (v_objectKind(_this)) { - case K_DATAREADER: - v_dataReaderNotify(v_dataReader(_this), event, userData); - break; - case K_STATUSCONDITION: - v_observableNotify(v_observable(_this), event); - break; - case K_WAITSET: - v_waitsetNotify(v_waitset(_this), event, userData); - break; - case K_PARTICIPANT: - v_participantNotify(v_participant(_this), event, userData); - break; - case K_TOPIC: - v_topicNotify(v_topic(_this), event, userData); - break; - case K_TOPIC_ADAPTER: - v_topicAdapterNotify(v_topicAdapter(_this), event, userData); - break; - case K_QUERY: - /* v_queryNotify(v_query(_this), event, userData); */ - break; - case K_SPLICED: /* intentionally no break */ - case K_SERVICE: - case K_NETWORKING: - case K_DURABILITY: - case K_NWBRIDGE: - case K_CMSOAP: - case K_RNR: - v_serviceNotify(v_service(_this), event, userData); - break; - case K_SERVICEMANAGER: - v_serviceManagerNotify(v_serviceManager(_this), event, userData); - break; - case K_WRITER: /* no action for the following observers */ - case K_PUBLISHER: - case K_SUBSCRIBER: - case K_GROUPQUEUE: - case K_LISTENER: - break; - default: - OS_REPORT(OS_ERROR,"Kernel Observer",V_RESULT_INTERNAL_ERROR, - "Notify called on an unknown observer type: %d", - v_objectKind(_this)); - assert(FALSE); - break; + if (event != NULL) { + switch (v_objectKind(_this)) { + case K_WAITSET: + v_waitsetNotify(v_waitset(_this), event, userData); + break; + case K_PARTICIPANT: + v_participantNotify(v_participant(_this), event, userData); + break; + case K_TOPIC_ADAPTER: + v_topicAdapterNotify(v_topicAdapter(_this), event, userData); + break; + case K_SUBSCRIBER: + v_subscriberNotify(v_subscriber(_this), event, userData); + break; + case K_SPLICED: /* all services, intentionally no break */ + case K_SERVICE: + case K_NETWORKING: + case K_DURABILITY: + case K_NWBRIDGE: + case K_CMSOAP: + case K_RNR: + case K_DBMSCONNECT: + v_serviceNotify(v_service(_this), event, userData); + break; + case K_WRITER: /* no event passing for the following observers */ + case K_DATAREADER: + case K_QUERY: + case K_PUBLISHER: + case K_TOPIC: + case K_GROUPQUEUE: + case K_STATUSCONDITION: + case K_LISTENER: + case K_SERVICEMANAGER: + break; + default: + OS_REPORT(OS_ERROR,"Kernel Observer",V_RESULT_INTERNAL_ERROR, + "Notify called on an unknown observer type: %d", + v_objectKind(_this)); + assert(FALSE); + break; + } } - /* - * Only trigger condition variable if at least - * one thread is waiting AND the event is seen for the first time. - */ - if ((_this->waitCount > 0) && notify) - { - EVENT_TRACE("v_observerNotify(%s(0x%x), event(0x%x)) => signal blocking threads\n", - v_objectKindImage(_this), _this, event); + /* Only trigger condition variable if at least + * one thread is waiting AND the event is seen for the first time. + */ + if ((_this->eventFlags & trigger) && (trigger != V_EVENT_TRIGGER)) { + notify = FALSE; + } + /* store event before trigger is given to waiting threads or subclasses are notified*/ + _this->eventFlags |= trigger; + if ((_this->waitCount > 0) && notify) { + EVENT_TRACE("v_observerNotify(%s(0x%x), event(0x%x)) => signal blocking threads\n", + v_objectKindImage(_this), _this, event); c_condBroadcast(&_this->cv); } } @@ -227,94 +238,58 @@ v_observerNotify( EVENT_TRACE("v_observerNotify: Event(0x%x) is ignored for %s(0x%x) because it is currently being destroyed\n", event, v_objectKindImage(_this), _this); } + OSPL_UNBLOCK_EVENTS(_this); } c_ulong -v__observerWait( - v_observer o) -{ - v_result result; - c_ulong flags = 0; - - assert(o != NULL); - assert(C_TYPECHECK(o,v_observer)); - - if (o->eventFlags == 0) { - o->waitCount++; - EVENT_TRACE("v__observerWait: Block on %s(0x%x), eventFlags(0x%x)\n", - v_objectKindImage(o), o, o->eventFlags); - result = v_condWait(&o->cv,&o->mutex, OS_DURATION_INFINITE); - if (result != V_RESULT_OK) { - OS_REPORT(OS_CRITICAL,"v__observerWait",result, - "v_condWait failed with result = %d", - result); - } - flags = o->eventFlags; - EVENT_TRACE("v__observerWait: WakeUp %s(0x%x), eventFlags(0x%x)\n", - v_objectKindImage(o), o, o->eventFlags); - o->waitCount--; - } else { - flags = o->eventFlags; - EVENT_TRACE("v__observerWait: Wait fallthrough for %s(0x%x), " - "because of pending eventFlags(0x%x)\n", - v_objectKindImage(o), o, o->eventFlags); - } - - /* Reset events but remember destruction event. - * To avoid any further use of this observer in case of destruction. - */ - if (o->waitCount == 0) - { - o->eventFlags &= V_EVENT_OBJECT_DESTROYED; - } - return flags; -} - -c_ulong -v_observerWait( - v_observer o) -{ - c_ulong flags; - - assert(o != NULL); - assert(C_TYPECHECK(o,v_observer)); - - c_mutexLock(&o->mutex); - flags = v__observerWait(o); - c_mutexUnlock(&o->mutex); - - return flags; -} - -c_ulong -v__observerTimedWait( +v_observerTimedWaitAction( v_observer o, - const os_duration time) + const os_duration time, + const c_action action, + c_voidp arg) { - v_result result = V_RESULT_OK; c_ulong flags = 0; + v_result result = V_RESULT_OK; + c_bool relock = FALSE; assert(o != NULL); assert(C_TYPECHECK(o,v_observer)); + OSPL_BLOCK_EVENTS(o); if (o->eventFlags == 0) { - o->waitCount++; - EVENT_TRACE("v__observerTimedWait Block %s(0x%x) eventFlags(0x%x)\n", - v_objectKindImage(o), o, o->eventFlags); - result = v_condWait(&o->cv,&o->mutex, time); - o->waitCount--; - if (result == V_RESULT_TIMEOUT) { - o->eventFlags |= V_EVENT_TIMEOUT; - } - flags = o->eventFlags; - EVENT_TRACE("v__observerTimedWait: WakeUp %s(0x%x) eventFlags(0x%x)\n", - v_objectKindImage(o), o, o->eventFlags); + if (time <= OS_DURATION_ZERO) { + EVENT_TRACE("v__observerTimedWait: Zero-Timeout %s(0x%x), eventFlags(0x%x)\n", + v_objectKindImage(o), o, o->eventFlags); + result = V_RESULT_TIMEOUT; + } else { + /* Unlock the OSPL_LOCK, not allowed to sleep while holding this lock. + * This lock needs to be re-acquired again after the EVENT_LOCK is released. + */ + relock = TRUE; + OSPL_UNLOCK(o); + o->waitCount++; + EVENT_TRACE("v__observerTimedWait Block %s(0x%x) eventFlags(0x%x)\n", + v_objectKindImage(o), o, o->eventFlags); + + result = v_condWait(&o->cv,&v_observable(o)->eventLock, time); + o->waitCount--; + EVENT_TRACE("v__observerTimedWait: WakeUp %s(0x%x) eventFlags(0x%x)\n", + v_objectKindImage(o), o, o->eventFlags); + } } else { EVENT_TRACE("v__observerTimedWait: Fallthrough %s(0x%x), eventFlags(0x%x)\n", v_objectKindImage(o), o, o->eventFlags); } + if (o->eventFlags != 0) { + flags = o->eventFlags; + if (action) { + (void)action(o, arg); + } + } else if (result == V_RESULT_TIMEOUT) { + flags = V_EVENT_TIMEOUT; + } /* Reset events but remember destruction event. * To avoid any further use of this observer in case of destruction. @@ -322,40 +297,37 @@ v__observerTimedWait( if (o->waitCount == 0) { o->eventFlags &= V_EVENT_OBJECT_DESTROYED; } + + OSPL_UNBLOCK_EVENTS(o); + if (relock) { + // Coverity false positve : LOCK is only done when relock is set to TRUE + // because this function is entered with the lock, we have to relock in case + // we released the lock in this function + /* coverity[missing_unlock : FALSE] */ + OSPL_LOCK(o); + } + return flags; } + c_ulong v_observerTimedWait( v_observer o, const os_duration time) { - c_ulong flags; - - assert(o != NULL); - assert(C_TYPECHECK(o,v_observer)); - - c_mutexLock(&o->mutex); - flags = v__observerTimedWait(o, time); - c_mutexUnlock(&o->mutex); - - return flags; + return v_observerTimedWaitAction(o, time, NULL, NULL); } c_ulong -v__observerSetEvent( - v_observer o, - c_ulong event) +v_observerWait( + v_observer o) { - c_ulong eventMask; - - assert(o != NULL); - assert(C_TYPECHECK(o,v_observer)); - - eventMask = o->eventMask; - o->eventMask |= event; - - return eventMask; + c_ulong result; + OSPL_LOCK(o); + result = v_observerTimedWaitAction(o, OS_DURATION_INFINITE, NULL, NULL); + OSPL_UNLOCK(o); + return result; } c_ulong @@ -368,9 +340,10 @@ v_observerSetEvent( assert(o != NULL); assert(C_TYPECHECK(o,v_observer)); - c_mutexLock(&o->mutex); - eventMask = v__observerSetEvent(o, event); - c_mutexUnlock(&o->mutex); + OSPL_BLOCK_EVENTS(o); + eventMask = o->eventMask; + o->eventMask |= event; + OSPL_UNBLOCK_EVENTS(o); return eventMask; } @@ -385,10 +358,10 @@ v_observerClearEvent( assert(o != NULL); assert(C_TYPECHECK(o,v_observer)); - c_mutexLock(&o->mutex); + OSPL_BLOCK_EVENTS(o); eventMask = o->eventMask; o->eventMask &= ~event; - c_mutexUnlock(&o->mutex); + OSPL_UNBLOCK_EVENTS(o); return eventMask; } @@ -403,10 +376,10 @@ v_observerSetEventMask( assert(o != NULL); assert(C_TYPECHECK(o,v_observer)); - c_mutexLock(&o->mutex); + OSPL_BLOCK_EVENTS(o); eventMask = o->eventMask; o->eventMask = mask; - c_mutexUnlock(&o->mutex); + OSPL_UNBLOCK_EVENTS(o); return eventMask; } @@ -420,25 +393,9 @@ v_observerGetEventMask( assert(o != NULL); assert(C_TYPECHECK(o,v_observer)); - c_mutexLock(&o->mutex); + OSPL_BLOCK_EVENTS(o); eventMask = o->eventMask; - c_mutexUnlock(&o->mutex); + OSPL_UNBLOCK_EVENTS(o); return eventMask; } - -c_voidp -v_observerSetEventData( - v_observer o, - c_voidp eventData) -{ - c_voidp oldEventData; - - assert(o != NULL); - assert(C_TYPECHECK(o,v_observer)); - - oldEventData = o->eventData; - o->eventData = eventData; - - return oldEventData; -} diff --git a/src/kernel/code/v_orderedInstance.c b/src/kernel/code/v_orderedInstance.c index 8ddc56181..08ccbf8e7 100644 --- a/src/kernel/code/v_orderedInstance.c +++ b/src/kernel/code/v_orderedInstance.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,7 +25,8 @@ #include "v_public.h" #include "v_instance.h" #include "v_state.h" -#include "v_dataViewInstance.h" +#include "v_dataView.h" +#include "v__dataViewInstance.h" #include "v__dataReaderInstance.h" #include "v__dataReaderSample.h" #include "v__orderedInstance.h" @@ -85,9 +87,10 @@ v__orderedInstanceSampleNew ( } /* v_dataViewInstance objects are created only when a sample with the key - value is available. Since a v_orderedInstance might be created by the - subscriber (when a v_dataReader is created), the creation of a - v_orderedViewInstance cannot be delayed until a sample is available. */ + * value is available. Since a v_orderedInstance might be created by the + * subscriber (when a v_dataReader is created), the creation of a + * v_orderedViewInstance cannot be delayed until a sample is available. + */ v_orderedInstance v_orderedInstanceNew ( v_entity entity, /* Subscriber or DataReader based on access_scope */ @@ -105,24 +108,17 @@ v_orderedInstanceNew ( assert (C_TYPECHECK (entity, v_dataReader)); } #endif - kernel = v_objectKernel (entity); _this = v_orderedInstance (v_objectNew (kernel, K_ORDEREDINSTANCE)); - if (_this != NULL) { - _this->samples = NULL; - _this->bookmark = NULL; - _this->presentation = presentation; - _this->orderby = orderby; - _this->mask = V_MASK_ANY; - _this->lazynew = c_listNew(v_kernelType(kernel, K_TRANSACTIONGROUP)); - v_instanceInit (v_instance(_this), entity); - v_dataViewInstance(_this)->sampleCount = 0; - v_dataViewInstanceTemplate(_this)->sample = NULL; - } else { - OS_REPORT (OS_FATAL, OS_FUNCTION, V_RESULT_INTERNAL_ERROR, - "Failed to create v_orderedInstance"); - assert(_this != NULL); - } + _this->samples = NULL; + _this->bookmark = NULL; + _this->presentation = presentation; + _this->orderby = orderby; + _this->mask = V_MASK_ANY; + _this->lazynew = c_listNew(v_kernelType(kernel, K_TRANSACTIONGROUP)); + v_instanceInit (v_instance(_this), entity); + v_dataViewInstance(_this)->sampleCount = 0; + v_dataViewInstanceTemplate(_this)->sample = NULL; return _this; } @@ -175,8 +171,9 @@ v_orderedInstanceRemove ( assert (C_TYPECHECK (_this, v_orderedInstance)); /* Wipe and free v_orderedInstance if the entity that owns it invokes - this function, otherwise only the reference count needs to be - lowered, but that happens automatically. */ + * this function, otherwise only the reference count needs to be + * lowered, but that happens automatically. + */ if (v_instance(_this)->entity == entity) { assert (c_refCount (_this) > 0); v__orderedInstanceReset (_this); @@ -257,15 +254,17 @@ v_orderedInstanceGetDataReaders ( v_orderedInstanceSample next; /* First complete list of samples for v_orderedInstance, then iterate - over that list to generate the list of readers. Only destroy the - (possibly) already created current list of samples to ensure the - list that is already there remains valid even if creation of new - list fails. */ + * over that list to generate the list of readers. Only destroy the + * (possibly) already created current list of samples to ensure the + * list that is already there remains valid even if creation of new + * list fails. + */ proceed = v_dataViewInstanceReadSamples (v_dataViewInstance (_this), NULL, V_MASK_ANY, &v__orderedInstanceGetDataReaders, (c_voidp)&argument); /* c_iterAppend returns the c_iter whether the operation was successful - or not, so proceed must test positive for the V_PROCEED flag. */ + * or not, so proceed must test positive for the V_PROCEED flag. + */ assert (v_actionResultTest (proceed, V_PROCEED)); OS_UNUSED_ARG(proceed); iterator = c_iterIterGet (argument.samples); @@ -306,7 +305,6 @@ v__orderedInstanceWrite ( c_equality eq = C_NE; next = tail = head->next; /* head->next is tail */ - msgPrev = v_dataReaderSampleTemplate(v_dataReaderSample(v_dataViewSampleTemplate(previous)->sample))->message; do { msgNext = v_dataReaderSampleTemplate(v_dataReaderSample(v_dataViewSampleTemplate(next)->sample))->message; @@ -323,7 +321,7 @@ v__orderedInstanceWrite ( } } - v__dataViewInstanceWrite (v_dataViewInstance (_this), previous, position); + v_dataViewInstanceWrite (v_dataViewInstance (_this), previous, position); v_dataReaderSampleAddViewSample (sample, previous); return (v_orderedInstanceSample)previous; @@ -343,12 +341,13 @@ v_orderedInstanceWrite( current = v_dataViewSample (v__orderedInstanceWrite (_this, sample)); assert (current != NULL); /* For instance and topic scopes updates are not blocked, because - begin_access and end_access are optional. Samples older than last - read sample should be read in a second pass. Samples that are newer - must be offered to the user in the first pass though. The bookmark - points to the sample that should be read next. If the newly inserted - sample is inserted just before the bookmark, the bookmark must - updated to point to the newly inserted sample. */ + * begin_access and end_access are optional. Samples older than last + * read sample should be read in a second pass. Samples that are newer + * must be offered to the user in the first pass though. The bookmark + * points to the sample that should be read next. If the newly inserted + * sample is inserted just before the bookmark, the bookmark must + * updated to point to the newly inserted sample. + */ if (_this->bookmark == current->prev) { _this->bookmark = (c_voidp)current; } @@ -391,8 +390,9 @@ v__orderedInstanceReadSample ( assert (_this->samples == NULL); /* Bookmark is the sample to read next (if the mask matches), because the - the sample that is currently operated upon might be taken, which would - then also invalidate the bookmark. */ + * the sample that is currently operated upon might be taken, which would + * then also invalidate the bookmark. + */ current = _this->bookmark; if (current != NULL) { @@ -416,9 +416,10 @@ v__orderedInstanceListReadSample( } /* This function treats the sample list in the view as a circular buffer. Only - one sample per invocation is read, which means that the piece of code that - invokes this function should check if the sample that is returned was not - read before. */ + * one sample per invocation is read, which means that the piece of code that + * invokes this function should check if the sample that is returned was not + * read before. + */ v_dataReaderSample v_orderedInstanceReadSample ( v_orderedInstance _this, @@ -429,16 +430,16 @@ v_orderedInstanceReadSample ( assert (_this != NULL && C_TYPECHECK (_this, v_orderedInstance)); - /* Read must be circular, therefore v_dataViewInstanceReadSamples cannot - be used. */ + /* Read must be circular, therefore v_dataViewInstanceReadSamples cannot be used. */ if (v_dataViewInstance(_this)->sampleCount > 0) { if (_this->presentation == V_PRESENTATION_GROUP) { next = v__orderedInstanceListReadSample (_this); } else { /* Bookmark must be reset for topic and instance scopes, because - using a different mask is interpreted as the start of a new - read batch. */ + * using a different mask is interpreted as the start of a new + * read batch. + */ if (mask != _this->mask) { v__orderedInstanceReset (_this); _this->mask = mask; @@ -461,85 +462,6 @@ v_orderedInstanceReadSample ( return sample; } -#if 0 -static void -v__orderedInstanceUnreadSample ( - v_orderedInstance _this, - v_dataReaderSample sample) -{ - v_dataViewSample bookmark, next; - - assert (_this != NULL && C_TYPECHECK (_this, v_orderedInstance)); - assert (sample != NULL && C_TYPECHECK (sample, v_dataReaderSample)); - - bookmark = _this->bookmark; - if (bookmark != NULL) { - /* Something is seriously broken if bookmark is the sample that was - just operated upon. */ - assert (sample != v__orderedInstanceSampleDataReaderSample (bookmark)); - } else { - bookmark = v_dataViewInstanceTemplate(_this)->sample; - } - - /* Quickest mode of operation is to iterate the list in opposite - read order. */ - for (next = bookmark->next; - next != bookmark && - v__orderedInstanceSampleDataReaderSample (next) != sample; - next = next->next) - { - /* do nothing */ - } - - /* Something is seriously broken if sample cannot be unread! */ - assert (v__orderedInstanceSampleDataReaderSample (next) == sample); - _this->bookmark = next; -} - -/* Rewinding the bookmark for group scope access is expensive and although it - can easily be optimized, it is not worth the trouble because the code is - never used in normal use cases (only one sample is read during a read - operation). */ -static void -v__orderedInstanceListUnreadSample ( - v_orderedInstance _this, - v_dataReaderSample sample) -{ - v_dataViewSample previous; - - assert (_this != NULL && C_TYPECHECK (_this, v_orderedInstance)); - assert (sample != NULL && C_TYPECHECK (sample, v_dataReaderSample)); - - previous = v_dataViewSample (v_dataViewInstanceTemplate (_this)->sample); - /* First should never be a null pointer. */ - assert (previous != NULL); - while (sample != v__orderedInstanceSampleDataReaderSample (previous)) { - previous = previous->prev; - } - - /* Something is seriously broken if sample is not in the list. */ - assert (previous != NULL); - - c_iterInsert (_this->samples, (c_voidp)previous); -} - -void -v_orderedInstanceUnreadSample ( - v_orderedInstance _this, - v_dataReaderSample sample) -{ - assert (_this != NULL && C_TYPECHECK (_this, v_orderedInstance)); - assert (sample != NULL && C_TYPECHECK (sample, v_dataReaderSample)); - assert (v_dataViewInstance(_this)->sampleCount > 0); - - if (_this->presentation == V_PRESENTATION_GROUP) { - v__orderedInstanceListUnreadSample (_this, sample); - } else { - v__orderedInstanceUnreadSample (_this, sample); - } -} -#endif - c_bool v_orderedInstanceIsAligned ( v_orderedInstance _this) diff --git a/src/kernel/code/v_parser.l b/src/kernel/code/v_parser.l index a2a12e92b..24d78af0c 100644 --- a/src/kernel/code/v_parser.l +++ b/src/kernel/code/v_parser.l @@ -1,50 +1,20 @@ - -%option never-interactive - %{ -/********************************************************************** - * - * include-statements - * - **********************************************************************/ #include #include "os_stdlib.h" #include "os_heap.h" #include "os_errno.h" - -/********************************************************************** - * - * global macro definitions - * - **********************************************************************/ -#define YY_NEVER_INTERACTIVE 1 /* stops flex from calling isatty() */ - -#define isatty thisisnotisatty - -int isatty (int x) { OS_UNUSED_ARG(x); return 0; } - -/********************************************************************** - * - * local macro definitions - * - **********************************************************************/ - -#define pc(x) v_parser_column+=x - -#define RETURN(t) v_parser_column+=(int)strlen(yytext);return t - -/********************************************************************** - * - * static function prototypes - * - **********************************************************************/ +#define RETURN(t) context->column += (int)strlen(yytext);return t static long getParameterValue ( char *str); +static char * +removeDoubleQuotes( + char *str); + /* Removed tokens because these are currently unused "+" { RETURN (PLUS); } @@ -92,15 +62,22 @@ flatten { RETURN (FLATTEN); } %} -/* %option noyywrap */ +%option noyywrap +%option nounistd +%option never-interactive + +%option prefix="v__parser_" + +%option reentrant bison-bridge INTEGER -[0-9]+ UINTEGER \+?[0-9]+ FLOAT [+-]?({UINTEGER}"."{UINTEGER})(e[+-]?{UINTEGER})? CHAR \'[^\']\' -STR \"([^"]*\"\")*[^"]*\" -STR2 \'([^']*\'\')*[^']*\' -STR3 \`([^']*\'\')*[^']*\' +STR ([^']|(\'\'))* +STRSTART (\'|\`) +STREND (\') + IDENT [a-zA-Z_/][a-zA-Z0-9_/]* FIELDNAME {IDENT}(\.{IDENT})* @@ -108,6 +85,7 @@ PARAM [$%][0-9][0-9]? BLANK [ \t]+ NEWLINE \n +%x STRING %x COMMENT1 COMMENT2 "//"[^\n]* @@ -147,87 +125,77 @@ JOIN { RETURN (JOIN); } BETWEEN { RETURN (BETWEEN); } {BLANK} { - v_parser_column+=(int)strlen(yytext); + context->column += (int)strlen(yytext); } {COMMENT2} { - v_parser_column=0; + context->column = 0; } {NEWLINE} { - v_parser_line++; - v_parser_column=0; + context->line++; + context->column = 0; } {PARAM} { - yylval.Integer = getParameterValue(yytext); - v_parser_column+=(int)strlen(yytext); + context->column += (int)strlen(yytext); + yylval->Integer = getParameterValue(yytext); return (PARAM); } {IDENT} { - /* variable length string values are allocated dynamically and - must be freed by the parser calling this scanner. - */ - yylval.String = (char*)malloc(strlen(yytext)+1); - v_parser_column+=(int)strlen(yytext); - os_strcpy(yylval.String,yytext); + context->column += (int)strlen(yytext); + /* ensure parser frees memory */ + yylval->String = os_strdup(yytext); return (IDENTIFIER); } {FIELDNAME} { - yylval.String = (char*)malloc(strlen(yytext)+1); - v_parser_column+=(int)strlen(yytext); - os_strcpy(yylval.String,yytext); + context->column += (int)strlen(yytext); + yylval->String = os_strdup(yytext); return (FIELDNAME); } {INTEGER} { - c_char *ptr = NULL; - yylval.Integer = os_strtoll(yytext, &ptr, 0); - v_parser_column+=(int)strlen(yytext); + context->column += (int)strlen(yytext); + yylval->Integer = os_strtoll(yytext, NULL, 0); return (INTEGERVALUE); } {UINTEGER} { - c_char *ptr = NULL; - yylval.UInteger = os_strtoull(yytext, &ptr, 0); - v_parser_column+=(int)strlen(yytext); + context->column += (int)strlen(yytext); + yylval->UInteger = os_strtoull(yytext, NULL, 0); return (UINTEGERVALUE); } {FLOAT} { - yylval.Float = (double)atof(yytext); - v_parser_column+=(int)strlen(yytext); + context->column += (int)strlen(yytext); + yylval->Float = (double)atof(yytext); return (FLOATVALUE); } {CHAR} { -/* - yylval.Char = yytext[1]; - v_parser_column+=(int)strlen(yytext); - return (CHARVALUE); -*/ - os_size_t length = strlen(yytext); - v_parser_column+=length; - /* variable length string values are allocated dynamically and - must be freed by the parser calling this scanner. - */ - yylval.String = (char*)malloc(length-1); - os_strncpy(yylval.String, (char *)&yytext[1], length-2); - yylval.String[length-2]=0; + context->column += (int)strlen(yytext); + /* ensure parser frees memory */ + yylval->String = os_strndup(&yytext[1], 1); return (STRINGVALUE); } -{STR2}|{STR3} { - os_size_t length = strlen(yytext); - v_parser_column+=length; - /* variable length string values are allocated dynamically and - must be freed by the parser calling this scanner. - */ - yylval.String = (char*)malloc(length-1); - os_strncpy(yylval.String, (char *)&yytext[1], length-2); - yylval.String[length-2]=0; +\'|\` { + context->column++; + BEGIN(STRING); + } +{STR} { + context->column += (int)strlen(yytext); + yylval->String = removeDoubleQuotes(yytext); return (STRINGVALUE); } -. { v_parser_column+=(int)strlen(yytext); +\' { + context->column++; + BEGIN(INITIAL); + } +. { + context->column += (int)strlen(yytext); return (UNDEFINEDTOKEN); } #endif "/*" BEGIN(COMMENT1); [^*\n]* "*"+[^*/\n]* -\n { ++v_parser_line; v_parser_column=0; } +\n { + context->line++; + context->column = 0; + } "*"+"/" BEGIN(INITIAL); %% @@ -245,3 +213,28 @@ getParameterValue ( return value; } + +static char * +removeDoubleQuotes( + char *str) +{ + os_size_t i, j; + os_size_t len; + char *s = NULL; + + if (str) { + len = strlen(str); + + s = os_malloc(len+1); + + for (i = 0, j = 0; i < len; i++, j++) { + if (str[i] == '\'' && str[i+1] == '\'') { + i++; + } + s[j] = str[i]; + } + s[j] = '\0'; + } + + return s; +} diff --git a/src/kernel/code/v_parser.y b/src/kernel/code/v_parser.y index 4b292ba95..64438ded2 100644 --- a/src/kernel/code/v_parser.y +++ b/src/kernel/code/v_parser.y @@ -1,73 +1,46 @@ %{ - #include "c_iterator.h" #include "q_expr.h" +#include "q_helper.h" #include "ut_stack.h" -#include "os_stdlib.h" #include "os_heap.h" +#include "os_mutex.h" +#include "os_report.h" +#include "os_stdlib.h" +#include "os_string.h" #include "v_kernel.h" #include "v_kernelParser.h" -#ifdef _WIN32 -#define YY_NO_UNISTD_H -#endif - -#define YY_NEVER_INTERACTIVE 1 - -#define yyin v_parser_yyin -#define yyout v_parser_yyout -#define yyparse v_parser_yyparse -#define yychar v_parser_yychar -#define yyerror v_parser_yyerror -#define yylex v_parser_yylex -#define yylval v_parser_yylval -#define yyrestart v_parser_yyrestart -#define yywrap v_parser_yywrap -#define yytext v_parser_yytext -#define yynerrs v_parser_yynerrs -#define yyleng v_parser_yyleng -#define yy_scan_string v_parser_yy_scan_string -#define yy_scan_buffer v_parser_yy_scan_buffer -#define yy_init_buffer v_parser_yy_init_buffer -#define yy_flush_buffer v_parser_yy_flush_buffer -#define yy_switch_to_buffer v_parser_yy_switch_to_buffer -#define yy_delete_buffer v_parser_yy_delete_buffer -#define yy_create_buffer v_parser_yy_create_buffer -#define yy_load_buffer_state v_parser_yy_load_buffer_state -#define yy_scan_bytes v_parser_yy_scan_bytes +/* yyscan_t is an opaque pointer, a typedef is required here to break a + circular dependency introduced with bison 2.6 (normally a typedef is + generated by flex). the define is required to disable the typedef in flex + generated code */ +#define YY_TYPEDEF_YY_SCANNER_T +typedef void *yyscan_t; #define YYMALLOC os_malloc #define YYFREE os_free - -static q_expr expr; - -static ut_stack exprStack; -static q_list lastList; - -int v_parser_line = 1; -int v_parser_column = 0; -int v_parser_state = 0; - -int yylex(); -int yyerror ( char* text ); +struct v_context { + int line; + int column; + q_expr expr; + q_list lastList; + ut_stack exprStack; +}; static q_list -splitFieldname ( char *name ); +splitFieldname( + char *name); static void -clearExpressionStack ( ut_stack stack ); +clearExpressionStack( + ut_stack stack); static void -clearExpressionList ( q_list list ); - - -/*********************************************************************** - * - * Static function prototypes - * - ***********************************************************************/ +clearExpressionList( + q_list list); %} @@ -83,6 +56,28 @@ clearExpressionList ( q_list list ); q_tag Tag; } +%{ +/* q_parser_lex must be declared here because q_parser_lex (yylex if no prefix + would be specified) signature is augmented with an extra argument */ +int v__parser_lex( + YYSTYPE * yylval_param, yyscan_t yyscanner, struct v_context *context); + +#define YY_DECL int v__parser_lex \ + (YYSTYPE * yylval_param, yyscan_t yyscanner, struct v_context *context) + +static int +yyerror( + yyscan_t yyscanner, struct v_context *context, char *text); +%} + +%define api.pure full +%define api.prefix v__parser_ + +%lex-param {yyscan_t scanner} +%lex-param {struct v_context *context} +%parse-param {yyscan_t scanner} +%parse-param {struct v_context *context} + %start program %token AS_KEYWORD NIL TRUET FALSET LRPAR RRPAR @@ -138,8 +133,8 @@ clearExpressionList ( q_list list ); program: | query - { expr = F1(Q_EXPR_PROGRAM,$1); - ut_stackPop(exprStack); + { context->expr = F1(Q_EXPR_PROGRAM,$1); + ut_stackPop(context->exprStack); } ; @@ -159,10 +154,10 @@ query: topicExpression: SELECT aggregation fromClause whereClause { $$ = F3(Q_EXPR_SELECT,$2,$3,$4); - ut_stackPop(exprStack); - ut_stackPop(exprStack); - ut_stackPop(exprStack); - ut_stackPush(exprStack, $$); + ut_stackPop(context->exprStack); + ut_stackPop(context->exprStack); + ut_stackPop(context->exprStack); + ut_stackPush(context->exprStack, $$); } ; @@ -176,20 +171,20 @@ queryExpression: fromClause: FROM joinExpr { $$ = F1(Q_EXPR_FROM,$2); - ut_stackPop(exprStack); - ut_stackPush(exprStack, $$); + ut_stackPop(context->exprStack); + ut_stackPush(context->exprStack, $$); } ; aggregation: ALL { $$ = L0(Q_EXPR_PROJECTION); - ut_stackPush(exprStack, $$); + ut_stackPush(context->exprStack, $$); } | subjectFieldList { $$ = L1(Q_EXPR_PROJECTION,$1); - lastList = NULL; - ut_stackPush(exprStack, $$); + context->lastList = NULL; + ut_stackPush(context->exprStack, $$); } ; @@ -198,8 +193,8 @@ joinExpr: { $$ = $1; } | topicName naturalJoin joinExpr { $$ = F2(Q_EXPR_JOIN,$1,$3); - ut_stackPop(exprStack); - ut_stackPush(exprStack, $$); + ut_stackPop(context->exprStack); + ut_stackPush(context->exprStack, $$); } ; @@ -211,27 +206,27 @@ naturalJoin: whereClause: { $$ = L0(Q_EXPR_WHERE); - ut_stackPush(exprStack, $$); + ut_stackPush(context->exprStack, $$); } | WHERE condition { $$ = F1(Q_EXPR_WHERE,$2); - ut_stackPop(exprStack); - ut_stackPush(exprStack, $$); + ut_stackPop(context->exprStack); + ut_stackPush(context->exprStack, $$); } ; orderBy: ORDER BY fieldList { $$ = L1(Q_EXPR_ORDER,$3); - lastList = NULL; - ut_stackPush(exprStack, $$); + context->lastList = NULL; + ut_stackPush(context->exprStack, $$); } ; topicName: ident { $$ = q_newId($1); - ut_stackPush(exprStack, $$); + ut_stackPush(context->exprStack, $$); free($1); } ; @@ -239,11 +234,11 @@ topicName: subjectFieldList: subjectField { $$ = List1($1); - lastList = $$; + context->lastList = $$; } | subjectFieldList COMMA subjectField { $$ = q_append($1,$3); - lastList = $$; + context->lastList = $$; } ; @@ -252,27 +247,27 @@ subjectField: { $$ = $1; } | field AS_KEYWORD field { $$ = F2(Q_EXPR_BIND,$3,$1); - ut_stackPop(exprStack); - ut_stackPop(exprStack); - ut_stackPush(exprStack, $$); + ut_stackPop(context->exprStack); + ut_stackPop(context->exprStack); + ut_stackPush(context->exprStack, $$); } | field field { $$ = F2(Q_EXPR_BIND,$2,$1); - ut_stackPop(exprStack); - ut_stackPop(exprStack); - ut_stackPush(exprStack, $$); + ut_stackPop(context->exprStack); + ut_stackPop(context->exprStack); + ut_stackPush(context->exprStack, $$); } ; fieldList: field { $$ = List1($1); - ut_stackPop(exprStack); - lastList = $$; + ut_stackPop(context->exprStack); + context->lastList = $$; } | fieldList COMMA field { $$ = q_append($1,$3); - lastList = $$; + context->lastList = $$; } ; @@ -281,9 +276,9 @@ condition: { $$ = $1; } | condition2 OR condition { $$ = F2(Q_EXPR_OR,$1,$3); - ut_stackPop(exprStack); - ut_stackPop(exprStack); - ut_stackPush(exprStack, $$); + ut_stackPop(context->exprStack); + ut_stackPop(context->exprStack); + ut_stackPush(context->exprStack, $$); } ; @@ -299,9 +294,9 @@ condition2: { $$ = $1; } | condition3 AND condition { $$ = F2(Q_EXPR_AND,$1,$3); - ut_stackPop(exprStack); - ut_stackPop(exprStack); - ut_stackPush(exprStack, $$); + ut_stackPop(context->exprStack); + ut_stackPop(context->exprStack); + ut_stackPush(context->exprStack, $$); } ; @@ -310,8 +305,8 @@ condition3: { $$ = $1; } | NOT condition1 { $$ = F1(Q_EXPR_NOT,$2); - ut_stackPop(exprStack); - ut_stackPush(exprStack, $$); + ut_stackPop(context->exprStack); + ut_stackPush(context->exprStack, $$); } ; @@ -325,9 +320,9 @@ predicate: comparisonPredicate: comparisonPar relOp comparisonPar { $$ = F2($2,$1,$3); - ut_stackPop(exprStack); - ut_stackPop(exprStack); - ut_stackPush(exprStack, $$); + ut_stackPop(context->exprStack); + ut_stackPop(context->exprStack); + ut_stackPush(context->exprStack, $$); } ; @@ -341,34 +336,31 @@ comparisonPar: betweenPredicate: field BETWEEN parameter AND parameter { $$ = F2(Q_EXPR_AND,F2(Q_EXPR_GE,$1,$3),F2(Q_EXPR_LE,q_newId(q_getId($1)),$5)); - ut_stackPop(exprStack); - ut_stackPop(exprStack); - ut_stackPop(exprStack); - ut_stackPush(exprStack, $$); + ut_stackPop(context->exprStack); + ut_stackPop(context->exprStack); + ut_stackPop(context->exprStack); + ut_stackPush(context->exprStack, $$); } | field NOT BETWEEN parameter AND parameter { $$ = F2(Q_EXPR_OR,F2(Q_EXPR_LT,$1,$4),F2(Q_EXPR_GT,q_newId(q_getId($1)),$6)); - ut_stackPop(exprStack); - ut_stackPop(exprStack); - ut_stackPop(exprStack); - ut_stackPush(exprStack, $$); + ut_stackPop(context->exprStack); + ut_stackPop(context->exprStack); + ut_stackPop(context->exprStack); + ut_stackPush(context->exprStack, $$); } ; field: IDENTIFIER - { $$ = q_newId($1); - ut_stackPush(exprStack, $$); + { $$ = q_newId($1); + ut_stackPush(context->exprStack, $$); free($1); } | FIELDNAME - { - q_list list = splitFieldname($1); - if ( list == NULL ) { - assert(0); - } + { q_list list = splitFieldname($1); + assert(list != NULL); $$ = L1(Q_EXPR_PROPERTY,list); ; - ut_stackPush(exprStack, $$); + ut_stackPush(context->exprStack, $$); free($1); } ; @@ -393,33 +385,33 @@ relOp: parameter: INTEGERVALUE { $$ = q_newInt($1); - ut_stackPush(exprStack, $$); + ut_stackPush(context->exprStack, $$); } | UINTEGERVALUE { $$ = q_newUInt($1); - ut_stackPush(exprStack, $$); + ut_stackPush(context->exprStack, $$); } | FLOATVALUE { $$ = q_newDbl($1); - ut_stackPush(exprStack, $$); + ut_stackPush(context->exprStack, $$); } | CHARVALUE { $$ = q_newChr($1); - ut_stackPush(exprStack, $$); + ut_stackPush(context->exprStack, $$); } | STRINGVALUE { $$ = q_newStr($1); - ut_stackPush(exprStack, $$); + ut_stackPush(context->exprStack, $$); free($1); } | ENUMERATEDVALUE { $$ = q_newStr($1); - ut_stackPush(exprStack, $$); + ut_stackPush(context->exprStack, $$); free($1); } | PARAM { $$ = q_newVar($1); - ut_stackPush(exprStack, $$); + ut_stackPush(context->exprStack, $$); } | NIL { $$ = NULL; } @@ -427,107 +419,59 @@ parameter: ident: IDENTIFIER - { $$ = $1; } + { $$ = $1; } ; - - -/*********************************************************************** - * - * Query Select From clause - * - ***********************************************************************/ - -/*********************************************************************** - * - * Query Select Where clause - * - ***********************************************************************/ - -/*********************************************************************** - * - * Query q_newFnc - * - ***********************************************************************/ - -/*********************************************************************** - * - * Query Boolean q_newFnc - * - ***********************************************************************/ - -/*********************************************************************** - * - * Query Comparisson q_newFnc - * - ***********************************************************************/ - - %% +#define YY_NO_UNPUT +#define YY_NO_INPUT #include "v_parser.h" -#include "os_report.h" -#include "os_mutex.h" -#include "q_helper.h" -static os_mutex parserMutex; -static c_bool parserInitialized = FALSE; - -int -yyerror ( - char* text ) +static int +yyerror( + yyscan_t yyscanner, struct v_context *context, char *text) { - OS_REPORT(OS_ERROR,"SQL parse failed",V_RESULT_ILL_PARAM,"%s near %s at line: %d, column: %d", - text, yytext, v_parser_line, v_parser_column); - yyclearin; + OS_UNUSED_ARG(yyscanner); + OS_REPORT(OS_ERROR,"SQL parse failed",V_RESULT_ILL_PARAM,"%s at line: %d, column: %d", + text, context->line, context->column); - q_dispose(expr); - expr = NULL; + q_dispose(context->expr); + context->expr = NULL; return 0; } -int -yywrap() -{ - return 1; -} - q_expr -v_parser_parse ( +v_parser_parse( const char *queryString) { - q_expr e; + YY_BUFFER_STATE buffer; + yyscan_t scanner; + struct v_context context = { 1, 0, NULL, NULL, NULL }; assert(queryString != NULL); - if ( !parserInitialized) { - parserInitialized = TRUE; - os_mutexInit(&parserMutex, NULL); - } - os_mutexLock(&parserMutex); - - v_parser_line = 1; - v_parser_column = 0; - v_parser_state = 0; - expr = NULL; - lastList = NULL; - exprStack = ut_stackNew(32); - if ( exprStack ) { - yy_scan_string((char *)queryString); - yyparse(); - e = expr; - yy_delete_buffer(YY_CURRENT_BUFFER); - clearExpressionStack(exprStack); - clearExpressionList(lastList); - q_exprSetText(e, queryString); - } else { - e = NULL; - OS_REPORT(OS_ERROR,"SQL parse failed",V_RESULT_ILL_PARAM,"memory allocation failed"); + context.exprStack = ut_stackNew(32); + if (context.exprStack != NULL) { + v__parser_lex_init(&scanner); + buffer = v__parser__scan_string(queryString, scanner); + if (yyparse(scanner, &context) == 0) { + q_exprSetText(context.expr, queryString); + } else { + /* 1 on invalid input, 2 on memory exhaustion */ + q_dispose(context.expr); + context.expr = NULL; + } + + v__parser__delete_buffer(buffer, scanner); + v__parser_lex_destroy(scanner); + + clearExpressionStack(context.exprStack); + clearExpressionList(context.lastList); } - os_mutexUnlock(&parserMutex); - return e; + return context.expr; } static char * @@ -552,7 +496,6 @@ getProperty( return result; } - static q_list splitFieldname ( char *name) @@ -572,7 +515,6 @@ splitFieldname ( return list; } - static void clearExpressionStack ( ut_stack stack) @@ -594,6 +536,3 @@ clearExpressionList ( q_dispose(q); } } - - - diff --git a/src/kernel/code/v_participant.c b/src/kernel/code/v_participant.c index 11295997c..0fc758ddb 100644 --- a/src/kernel/code/v_participant.c +++ b/src/kernel/code/v_participant.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,6 +18,7 @@ * limitations under the License. * */ +#include "v__kernel.h" #include "v__participant.h" #include "v__participantQos.h" #include "v__kernel.h" @@ -24,7 +26,7 @@ #include "v__publisher.h" #include "v__writer.h" #include "v__subscriber.h" -#include "v_dataReader.h" +#include "v__dataReader.h" #include "v__reader.h" #include "v__observer.h" #include "v__builtin.h" @@ -35,6 +37,7 @@ #include "v__processInfo.h" #include "v__topicAdapter.h" #include "v__typeRepresentation.h" +#include "v__spliced.h" #include "v__entity.h" #include "v_event.h" @@ -75,10 +78,12 @@ v_participantNew( assert(C_TYPECHECK(kernel,v_kernel)); /* Do not use C_TYPECHECK on qos parameter, - * since it might be allocated on heap! */ + * since it might be allocated on heap! + */ /* do no use cast method on qos parameter, - * it is most likely allocated on heap! */ + * it is most likely allocated on heap! + */ if (v_participantQosCheck(qos) == V_RESULT_OK) { q = v_participantQosNew(kernel, qos); @@ -89,7 +94,10 @@ v_participantNew( p = NULL; } else { p = v_participant(v_objectNew(kernel,K_PARTICIPANT)); - v_participantInit(p, name, q, enable); + v_participantInit(p, name, q); + if(enable) { + (void)v_entityEnable(v_entity(p)); + } result = v_participantMonitorSpliceDeamonLiveliness(kernel, name, p); if(result != V_RESULT_OK) { OS_REPORT(OS_CRITICAL, "v_participant", result, @@ -106,7 +114,7 @@ v_participantNew( v_result v_participantEnable ( - v_participant p) + _In_ v_participant p) { v_kernel kernel = v_objectKernel(v_object(p)); v_message builtinMsg; @@ -158,6 +166,7 @@ v_participantMonitorSpliceDeamonLiveliness( "to the lease manager of participant %p (%s). " "The result code was %d.", (void*)participant, name, result); } + c_free(splicedParticipant); } else { v_participant p; result = V_RESULT_INTERNAL_ERROR; @@ -174,7 +183,8 @@ v_participantMonitorSpliceDeamonLiveliness( } else { /* else do nothing, exception for splice deamon monitoring are made for - * the splice deamon participant and the built in participant*/ + * the splice deamon participant and the built in participant + */ result = V_RESULT_OK; } return result; @@ -182,10 +192,9 @@ v_participantMonitorSpliceDeamonLiveliness( void v_participantInit( - v_participant p, - const c_char *name, - v_participantQos qos, - c_bool enable) + _Inout_ v_participant p, + _In_opt_z_ const c_char *name, + _In_ v_participantQos qos) { v_kernel kernel; c_base base; @@ -198,17 +207,17 @@ v_participantInit( kernel = v_objectKernel(p); base = c_getBase(p); - v_entityInit(v_entity(p), name, enable); + v_entityInit(v_entity(p), name); p->entities = c_setNew(c_resolve(base,"kernelModuleI::v_entity")); p->qos = c_keep(qos); /* Currently default LIVELINESS policy is used: kind=AUTOMATIC, * duration=INFINITE This setting implies no lease registration. - */ + */ p->leaseManager = v_leaseManagerNew(kernel); p->resendQuit = FALSE; - c_mutexInit(base, &p->resendMutex); + (void)c_mutexInit(base, &p->resendMutex); c_condInit(base, &p->resendCond, &p->resendMutex); writerProxyType = v_kernelType(kernel,K_PROXY); p->resendWriters = c_tableNew(writerProxyType, "source.index,source.serial"); @@ -217,27 +226,10 @@ v_participantInit( (void) os_procGetProcessName (procName, sizeof (procName)); p->processName = c_stringNew (base, procName); p->processIsZombie = FALSE; + p->ignore = NULL; // ignore Admin is initially NULL and lazy created when the user ignores entities. - p->builtinSubscriber = NULL; - if (!v_observableAddObserver(v_observable(kernel),v_observer(p), NULL)) { - if (name != NULL) { - OS_REPORT(OS_WARNING,"Kernel Participant",0, - "%s: Cannot observe Kernel events",name); - } else { - OS_REPORT(OS_WARNING,"Kernel Participant",0, - "Cannot observe Kernel events"); - } - } p->typeRepresentations = c_tableNew(v_kernelType(kernel,K_TYPEREPRESENTATION),"typeName"); - c_mutexInit(base, &p->newGroupListMutex); - p->newGroupList = c_listNew(c_resolve(base, "kernelModuleI::v_group")); - - v_observerSetEventMask(v_observer(p), V_EVENT_NEW_GROUP); - - c_lockInit(base, &p->lock); - c_mutexInit(base, &p->builtinLock); - v_addParticipant(kernel, p); if (v_entityEnabled(v_entity(p))) { @@ -271,18 +263,7 @@ v_participantFree( assert(C_TYPECHECK(p,v_participant)); kernel = v_objectKernel(p); - - if (!v_observableRemoveObserver(v_observable(kernel),v_observer(p), NULL)) { - if (v_participantName(p) != NULL) { - OS_REPORT(OS_WARNING,"v_participantFree",V_RESULT_INTERNAL_ERROR, - "Participant '%s' cannot disconnect from Kernel events", - v_participantName(p)); - } else { - OS_REPORT(OS_WARNING,"v_participantFree",V_RESULT_INTERNAL_ERROR, - "Participant cannot disconnect from Kernel events"); - } - } - + (void)OSPL_REMOVE_OBSERVER(kernel,p, V_EVENTMASK_ALL, NULL); if (v_entityEnabled(v_entity(p))) { builtinMsg = v_builtinCreateParticipantInfo(kernel->builtin,p); v_writeDisposeBuiltinTopic(kernel, V_PARTICIPANTINFO_ID, builtinMsg); @@ -301,10 +282,6 @@ v_participantFree( c_free(builtinMsg); } - if (p->builtinSubscriber) { - v_subscriberFree(p->builtinSubscriber); - p->builtinSubscriber = NULL; - } while ((e = c_take(p->entities)) != NULL) { switch (v_objectKind(e)) { case K_PUBLISHER: @@ -357,43 +334,6 @@ v_participantDeinit( v_entityDeinit(v_entity(p)); } -#if 0 -void -v_participantAdd( - v_participant p, - v_entity e) -{ - v_entity found; - - assert(p != NULL); - assert(C_TYPECHECK(p,v_participant)); - assert(e != NULL); - assert(C_TYPECHECK(e,v_entity)); - - (void)c_lockWrite(&p->lock); - found = c_setInsert(p->entities,e); - c_lockUnlock(&p->lock); - assert(found == e); -} - -void -v_participantRemove( - v_participant p, - v_entity e) -{ - v_entity found; - - assert(p != NULL); - assert(C_TYPECHECK(p,v_participant)); - assert(e != NULL); - assert(C_TYPECHECK(e,v_entity)); - - (void)c_lockWrite(&p->lock); - found = c_remove(p->entities,e,NULL,NULL); - c_lockUnlock(&p->lock); - c_free(found); -} -#else void v_participantAdd( v_participant p, @@ -406,9 +346,9 @@ v_participantAdd( assert(e != NULL); assert(C_TYPECHECK(e,v_object)); - (void)c_lockWrite(&p->lock); + OSPL_LOCK(p); found = c_setInsert(p->entities,e); - c_lockUnlock(&p->lock); + OSPL_UNLOCK(p); assert(found == e); OS_UNUSED_ARG(found); } @@ -425,65 +365,38 @@ v_participantRemove( assert(e != NULL); assert(C_TYPECHECK(e,v_object)); - (void)c_lockWrite(&p->lock); + OSPL_LOCK(p); found = c_remove(p->entities,e,NULL,NULL); - c_lockUnlock(&p->lock); + OSPL_UNLOCK(p); c_free(found); } -#endif - -static c_bool -connectNewGroup( - c_object o, - c_voidp arg) -{ - c_bool result = TRUE; - - switch (v_objectKind(o)) { - case K_PARTICIPANT: - case K_SPLICED: - case K_DURABILITY: - case K_NWBRIDGE: - case K_SERVICE: - case K_CMSOAP: - case K_NETWORKING: - (void)c_lockWrite(&v_participant(o)->lock); - result = c_walk(v_participant(o)->entities, connectNewGroup, (v_group)arg); - c_lockUnlock(&v_participant(o)->lock); - break; - case K_PUBLISHER: - result = v_publisherConnectNewGroup(v_publisher(o), (v_group)arg); - break; - case K_SUBSCRIBER: - result = v_subscriberConnectNewGroup(v_subscriber(o), (v_group)arg); - break; - default: - /* Other entities do not connect */ - break; - } - return result; -} void -v_participantConnectNewGroup ( +v_participantConnectGroup ( v_participant _this, - v_event event) + v_group g) { - v_group g; - - OS_UNUSED_ARG(event); - - c_mutexLock(&_this->newGroupListMutex); - g = c_take(_this->newGroupList); - while (g) { - c_mutexUnlock(&_this->newGroupListMutex); - (void)c_lockWrite(&_this->lock); - (void)c_walk(_this->entities, connectNewGroup, g); - c_lockUnlock(&_this->lock); - c_mutexLock(&_this->newGroupListMutex); - g = c_take(_this->newGroupList); + v_entity entity; + c_iter entities; + + OSPL_LOCK(_this); + entities = ospl_c_select(_this->entities, 0); + OSPL_UNLOCK(_this); + while ((entity = c_iterTakeFirst(entities)) != NULL) { + switch (v_objectKind(entity)) { + case K_PUBLISHER: + (void)v_publisherConnectNewGroup(v_publisher(entity), g); + break; + case K_SUBSCRIBER: + (void)v_subscriberConnectNewGroup(v_subscriber(entity), g); + break; + default: + /* Other entities do not connect */ + break; + } + c_free(entity); } - c_mutexUnlock(&_this->newGroupListMutex); + c_iterFree(entities); } static c_bool @@ -502,9 +415,9 @@ v_participantNotifyGroupCoherentPublication( v_participant _this, v_message msg) { - (void)c_lockWrite(&_this->lock); + OSPL_LOCK(_this); (void)c_walk(_this->entities, notifyGroupCoherentPublication, msg); - c_lockUnlock(&_this->lock); + OSPL_UNLOCK(_this); } static c_bool @@ -545,13 +458,13 @@ v_participantDeleteHistoricalData( params[0] = c_stringValue((c_string)partitionExpr); params[1] = c_stringValue((c_string)topicExpr); - c_lockRead(&participant->lock); + OSPL_LOCK(participant); t = os_timeEGet(); matchingGroups = v_groupSetSelect( v_objectKernel(participant)->groupSet, "partition.name like %0 AND topic.name like %1", params); - c_lockUnlock(&participant->lock); + OSPL_UNLOCK(participant); group = v_group(c_iterTakeFirst(matchingGroups)); while(group){ @@ -567,10 +480,13 @@ v_participantDeleteHistoricalData( hde->partitionExpr = c_stringNew(base, (c_char *)partitionExpr); hde->topicExpr = c_stringNew(base, (c_char *)topicExpr); hde->deleteTime = t; + event.kind = V_EVENT_HISTORY_DELETE; event.source = v_observable(participant); event.data = hde; - v_observableNotify(v_observable(v_objectKernel(participant)),&event); + event.handled = TRUE; + + OSPL_THROW_EVENT(v_objectKernel(participant), &event); c_free(hde); } } @@ -590,45 +506,35 @@ v_participantNotify( * calling Notify(_this, event, userData). * This implies that _this as observer cannot be locked within any * Notify method to avoid deadlocks. - * For consistency _this must be locked by v_observerLock(_this) before + * For consistency _this must be locked by OSPL_LOCK(_this) before * calling this method. */ OS_UNUSED_ARG(userData); assert(_this != NULL); assert(C_TYPECHECK(_this,v_participant)); + assert(event != NULL); - if (event) { - switch (event->kind) { - case V_EVENT_NEW_GROUP: - assert(event->data); - c_mutexLock(&_this->newGroupListMutex); - c_listInsert(_this->newGroupList,v_group(event->data)); - c_mutexUnlock(&_this->newGroupListMutex); - (void)v_entityNotifyListener(v_entity(_this), event); - break; - case V_EVENT_LIVELINESS_ASSERT: - (void)c_lockWrite(&_this->lock); - (void)c_walk(_this->entities, assertLivelinessPublisher, event); - c_lockUnlock(&_this->lock); - break; - case V_EVENT_SERVICESTATE_CHANGED: - case V_EVENT_DATA_AVAILABLE: - case V_EVENT_HISTORY_DELETE: - case V_EVENT_HISTORY_REQUEST: - case V_EVENT_PERSISTENT_SNAPSHOT: - case V_EVENT_CONNECT_WRITER: - /*Do nothing here.*/ - break; - case V_EVENT_ALL_DATA_DISPOSED: - case V_EVENT_INCONSISTENT_TOPIC: - (void)v_entityNotifyListener(v_entity(_this), event); - break; - default: - OS_REPORT(OS_WARNING,"v_participantNotify",V_RESULT_ILL_PARAM, - "Notify encountered unknown event kind (%d)", - event->kind); - break; - } + switch (event->kind) { + case V_EVENT_LIVELINESS_ASSERT: + (void)c_walk(_this->entities, assertLivelinessPublisher, event); + break; + case V_EVENT_NEW_GROUP: + case V_EVENT_SERVICESTATE_CHANGED: + case V_EVENT_DATA_AVAILABLE: + case V_EVENT_HISTORY_DELETE: + case V_EVENT_HISTORY_REQUEST: + case V_EVENT_PERSISTENT_SNAPSHOT: + case V_EVENT_CONNECT_WRITER: + /*Do nothing here.*/ + break; + case V_EVENT_ALL_DATA_DISPOSED: + case V_EVENT_INCONSISTENT_TOPIC: + (void)v_entityNotifyListener(v_entity(_this), event); + break; + default: + OS_REPORT(OS_WARNING,"v_participantNotify",V_RESULT_ILL_PARAM, + "Notify encountered unknown event kind (%d)", event->kind); + break; } } @@ -636,74 +542,13 @@ void v_participantAssertLiveliness( v_participant p) { - C_STRUCT(v_event) event; - assert(p != NULL); assert(C_TYPECHECK(p,v_participant)); - event.kind = V_EVENT_LIVELINESS_ASSERT; - event.source = v_observable(p); - event.data = NULL; /* Walk over all entities and assert liveliness on all writers */ - (void)c_lockWrite(&p->lock); - (void)c_walk(p->entities, assertLivelinessPublisher, &event); - c_lockUnlock(&p->lock); -} - -v_subscriber -v_participantGetBuiltinSubscriber( - v_participant p) -{ - v_subscriberQos sQos; - v_readerQos rQos; - v_kernel kernel; - - assert(p != NULL); - assert(C_TYPECHECK(p, v_participant)); - - c_mutexLock(&p->builtinLock); - if (p->builtinSubscriber == NULL) { - kernel = v_objectKernel(p); - sQos = v_subscriberQosNew(kernel, NULL); - sQos->presentation.v.access_scope = V_PRESENTATION_TOPIC; - c_free(sQos->partition.v); - sQos->partition.v = c_stringNew(c_getBase(c_object(kernel)), - V_BUILTIN_PARTITION); - sQos->entityFactory.v.autoenable_created_entities = TRUE; - - p->builtinSubscriber = v_subscriberNew(p, V_BUILTINSUBSCRIBER_NAME, sQos, TRUE); - v_subscriberQosFree(sQos); - - c_mutexUnlock(&p->builtinLock); - - assert(p->builtinSubscriber != NULL); - - rQos = v_readerQosNew(kernel, NULL); - rQos->durability.v.kind = V_DURABILITY_TRANSIENT; - rQos->reliability.v.kind = V_RELIABILITY_RELIABLE; - rQos->history.v.kind = V_HISTORY_KEEPLAST; - rQos->history.v.depth = 1; - -#define _CREATE_READER_(topicName) {\ - q_expr expr; \ - v_dataReader dr; \ - expr = q_parse("select * from " topicName);\ - dr = v_dataReaderNew(p->builtinSubscriber, topicName "Reader", \ - expr, NULL, rQos, TRUE);\ - c_free(dr); \ - q_dispose(expr); \ - } - _CREATE_READER_(V_PARTICIPANTINFO_NAME) - _CREATE_READER_(V_TOPICINFO_NAME) - _CREATE_READER_(V_PUBLICATIONINFO_NAME) - _CREATE_READER_(V_SUBSCRIPTIONINFO_NAME) -#undef _CREATE_READER_ - v_readerQosFree(rQos); - } else { - c_mutexUnlock(&p->builtinLock); - } - - return c_keep(p->builtinSubscriber); + OSPL_LOCK(p); + (void)c_walk(p->entities, assertLivelinessPublisher, NULL); + OSPL_UNLOCK(p); } v_participantQos @@ -714,9 +559,9 @@ v_participantGetQos( assert(C_TYPECHECK(_this,v_participant)); - c_lockRead(&_this->lock); + OSPL_LOCK(_this); qos = c_keep(_this->qos); - c_lockUnlock(&_this->lock); + OSPL_UNLOCK(_this); return qos; } @@ -737,7 +582,7 @@ v_participantSetQos( result = v_participantQosCheck(tmpl); if (result == V_RESULT_OK) { - c_lockWrite(&p->lock); + OSPL_LOCK(p); kernel = v_objectKernel(p); qos = v_participantQosNew(kernel, tmpl); @@ -746,7 +591,7 @@ v_participantSetQos( if ((result == V_RESULT_OK) && (cm != 0)) { c_free(p->qos); p->qos = c_keep(qos); - if (v_entityEnabled(v_entity(p))) { + if (v__entityEnabled_nl(v_entity(p))) { builtinMsg = v_builtinCreateParticipantInfo(kernel->builtin,p); } } @@ -754,7 +599,7 @@ v_participantSetQos( } else { result = V_RESULT_OUT_OF_MEMORY; } - c_lockUnlock(&p->lock); + OSPL_UNLOCK(p); } if (builtinMsg != NULL) { @@ -1006,12 +851,11 @@ v_participantGetEntityList(v_participant participant) assert(participant != NULL); /* Copy the current entity set into an iter list. */ - c_lockRead(&participant->lock); + OSPL_LOCK(participant); entities = ospl_c_select(participant->entities, 0); - c_lockUnlock(&participant->lock); + OSPL_UNLOCK(participant); - /* - * Unfortunately, the entities list of the participant can + /* Unfortunately, the entities list of the participant can * contain waitsets as well. * This loop makes sure that only entities are returned. */ @@ -1022,8 +866,7 @@ v_participantGetEntityList(v_participant participant) /* Remove this object from the list when it's not an entity. */ if (c_instanceOf(object, "v_entity") == FALSE) { - /* - * This is not an entity. + /* This is not an entity. * * Taking this object means that the remaining objects will shift a * place down in the list. Or when this is the last object, then this @@ -1058,9 +901,9 @@ v__participantAddTypeRepresentation ( assert(C_TYPECHECK(p, v_participant)); assert(tr != NULL); - c_lockWrite(&p->lock); + OSPL_LOCK(p); found = ospl_c_insert(p->typeRepresentations, tr); - c_lockUnlock(&p->lock); + OSPL_UNLOCK(p); return found; } @@ -1076,34 +919,402 @@ v__participantRemoveTypeRepresentation ( assert(C_TYPECHECK(p, v_participant)); assert(tr != NULL); - c_lockWrite(&p->lock); + OSPL_LOCK(p); found = c_remove(p->typeRepresentations, tr, NULL, NULL); - c_lockUnlock(&p->lock); + OSPL_UNLOCK(p); return found; } -v_typeRepresentation -v_participantLookupTypeRepresentation ( - v_participant p, - const os_char *typeName) +static c_bool +transactionsPurge ( + c_object o, + c_voidp arg) { - v_typeRepresentation found = NULL; - C_STRUCT(v_typeRepresentation) dummy; + c_bool result = TRUE; - assert(p != NULL); - assert(C_TYPECHECK(p, v_participant)); - assert(typeName != NULL); + OS_UNUSED_ARG(arg); + + switch(v_objectKind(o)) { + case K_SUBSCRIBER: + /* A transaction flush purges and flushes the obsolete groups, + * flushing is required in case the obsolete group contains samples + * which cannot be discarded. */ + v_subscriberGroupTransactionFlush(v_subscriber(o)); + break; + default: + /* No need to purge other entities */ + break; + } + + return result; +} - memset(&dummy, 0, sizeof(dummy)); - /* Removing const qualifier from typeName so it can be passed to the - * c_find function. c_find does not alter the dummy struct. +void +v_participantTransactionsPurge ( + v_participant _this) +{ + assert(_this != NULL); + assert(C_TYPECHECK(_this, v_participant)); + + OSPL_LOCK(_this); + (void)c_walk(_this->entities, transactionsPurge, NULL); + OSPL_UNLOCK(_this); +} + +static v_ignoreAdmin +getIgnoreAdmin( + v_participant _this) +{ + if (_this->ignore == NULL) { + c_type type = c_resolve(c_getBase(_this), "kernelModuleI::v_ignoreAdmin"); + _this->ignore = c_new(type); + c_free(type); + } + return _this->ignore; +} + +static os_boolean +inList( + c_array list, + v_gid gid) +{ + os_uint32 i, size; + v_gid *gidlist = (v_gid *)list; + size = c_arraySize(list); + for (i=0; iparticipant_key.systemId == a->gid.systemId && + info->participant_key.localId == a->gid.localId) + { + TRACE_IGNORE("Participant::ignore_participant found a publication for topic \"%s\"\n", info->topic_name); + + v_participantIgnorePublicationInfo(a->participant, info); + } + return OS_TRUE; +} + +static os_boolean +ignoreSubscriptions( + const v_message subscription, + c_voidp arg) +{ + const struct v_subscriptionInfo *info = (struct v_subscriptionInfo *)(subscription + 1); + ignoreArg a = (ignoreArg)arg; + + if (info->participant_key.systemId == a->gid.systemId && + info->participant_key.localId == a->gid.localId) + { + TRACE_IGNORE("Participant::ignore_participant found a subscription for topic \"%s\"\n", info->topic_name); + + v_participantIgnoreSubscription(a->participant, info->key); + } + return OS_TRUE; +} + +v_result +v_participantIgnoreParticipant ( + v_participant _this, + v_gid gid) +{ + v_result result = V_RESULT_OK; + v_kernel kernel; + v_ignoreAdmin ignore; + struct ignoreArg_s a; + + TRACE_IGNORE("Participant::ignore_participant called for participant GID: {%d, %d, %d}\n", + gid.systemId, gid.localId, gid.serial); + + OSPL_LOCK(_this); + ignore = getIgnoreAdmin(_this); + ignoreGID(ignore, &ignore->participants, gid); + OSPL_UNLOCK(_this); + + /* Now lookup all publications and subscriptions associated to this participant and add these to the + * ignore publication and ignore subscription list */ - dummy.typeName = (c_string) typeName; - c_lockRead(&p->lock); - found = v_typeRepresentation(c_find(p->typeRepresentations, &dummy)); - c_lockUnlock(&p->lock); + a.gid = gid; + a.participant = _this; + kernel = v_objectKernel(_this); + result = v_kernelWalkPublications(kernel, ignorePublications, &a); + assert(result == V_RESULT_OK); + result = v_kernelWalkSubscriptions(kernel, ignoreSubscriptions, &a); + assert(result == V_RESULT_OK); - return found; + return result; +} + +v_result +v_participantIgnoreTopic ( + v_participant _this, + v_gid gid) +{ + v_result result = V_RESULT_UNSUPPORTED; + v_ignoreAdmin ignore; + + OS_REPORT(OS_ERROR, "Kernel IgnoreTopic", result, "This operation is currently unsupported."); + + TRACE_IGNORE("v_participantIgnoreTopic called\n"); + + OSPL_LOCK(_this); + ignore = getIgnoreAdmin(_this); + ignoreGID(ignore, &ignore->topics, gid); + OSPL_UNLOCK(_this); + + /* Now lookup all publications and subscriptions associated to this topic and add these to the + * ignore publication and ignore subscription list + */ + + return result; +} + +static c_bool +ignoreOnReaders( + c_object o, + c_voidp publicationInfo) +{ + v_object vObject = v_object(o); + + if (v_objectKind(vObject) == K_DATAREADER) { + v_dataReaderIgnore(v_dataReader(o), publicationInfo, TRUE); + } + return TRUE; +} + +static c_bool +ignoreOnSubscribers( + c_object o, + c_voidp publicationInfo) +{ + v_object vObject = v_object(o); + + if (v_objectKind(vObject) == K_SUBSCRIBER) { + v_subscriberWalkReaders(v_subscriber(o), ignoreOnReaders, publicationInfo); + } + return TRUE; +} + +static v_result +v_participantIgnorePublicationInfo ( + v_participant _this, + const struct v_publicationInfo *info) +{ + v_result result = V_RESULT_OK; + v_ignoreAdmin ignore; + + TRACE_IGNORE("Participant::ignore_publication called for publication GID: {%d, %d, %d}\n", + info->key.systemId, info->key.localId, info->key.serial); + + OSPL_LOCK(_this); + ignore = getIgnoreAdmin(_this); + ignoreGID(ignore, &ignore->publications, info->key); + + /* Now visit local DataReaders and add gid to the DataReader ignore publication list */ + + (void)c_walk(_this->entities, ignoreOnSubscribers, (void *)info); + OSPL_UNLOCK(_this); + + return result; +} + +v_result +v_participantIgnorePublication ( + v_participant _this, + v_gid gid) +{ + v_result result = V_RESULT_UNSUPPORTED; + v_message msg; + + msg = v_kernelLookupPublication(v_objectKernel(_this), gid); + if (msg) { + struct v_publicationInfo *info = v_builtinPublicationInfoData(msg); + result = v_participantIgnorePublicationInfo(_this, info); + c_free(msg); + } else { + OS_REPORT(OS_ERROR, "Ignore Publication", 0, "Lookup builtin Publication data failed"); + } + return result; +} + +v_result +v_participantIgnoreSubscription ( + v_participant _this, + v_gid gid) +{ + v_result result = V_RESULT_OK; + v_ignoreAdmin ignore; + + TRACE_IGNORE("Participant::ignore_subscription called for subscription GID: {%d, %d, %d}\n", + gid.systemId, gid.localId, gid.serial); + + OSPL_LOCK(_this); + ignore = getIgnoreAdmin(_this); + ignoreGID(ignore, &ignore->subscriptions, gid); + OSPL_UNLOCK(_this); + + /* Now visit local DataWriters and add gid to the DataWriter ignore subscription list + * This is only required if performance is an issue but for noe this doesn't seem the case. + */ + + return result; +} + +static os_boolean +ignoredParticipant( + v_ignoreAdmin _this, + v_gid gid) +{ + if (inList(_this->participants, gid)) { + return TRUE; + } + return FALSE; +} + +void +v_participantNotifyPublication( + v_participant _this, + v_message msg) +{ + struct v_publicationInfo *info; + + OSPL_LOCK(_this); + if (_this->ignore) { + info = v_builtinPublicationInfoData(msg); + if (v_messageStateTest(msg, L_DISPOSED)) { + disposeGID(_this->ignore, &_this->ignore->publications, info->key); + TRACE_IGNORE("Participant is notified to remove Publication GID {%u,%u,%u} from the ignore list\n", + info->key.systemId, info->key.localId, info->key.serial); + } else if (ignoredParticipant(_this->ignore, info->participant_key)) { + TRACE_IGNORE("Participant is notified to add Publication GID {%u,%u,%u} to the ignore lists\n", + info->key.systemId, info->key.localId, info->key.serial); + ignoreGID(_this->ignore, &_this->ignore->publications, info->key); + /* Now visit local DataReaders and add gid to the DataReader ignore publication list */ + (void)c_walk(_this->entities, ignoreOnSubscribers, (void *)info); + } + } + OSPL_UNLOCK(_this); +} + +void +v_participantNotifySubscription( + v_participant _this, + v_message msg) +{ + struct v_subscriptionInfo *info; + c_bool ignore = FALSE; + OSPL_LOCK(_this); + if (_this->ignore) { + info = v_builtinSubscriptionInfoData(msg); + if (v_messageStateTest(msg, L_DISPOSED)) { + disposeGID(_this->ignore, &_this->ignore->subscriptions, info->key); + TRACE_IGNORE("Participant is notified to remove Subscription GID {%u,%u,%u} from the ignore list\n", + info->key.systemId, info->key.localId, info->key.serial); + } else if (ignoredParticipant(_this->ignore, info->participant_key)) { + TRACE_IGNORE("Participant is notified to add Subscription GID {%u,%u,%u} to the ignore lists\n", + info->key.systemId, info->key.localId, info->key.serial); + ignore = TRUE; + } + } + OSPL_UNLOCK(_this); + if (ignore) { + v_participantIgnoreSubscription(_this, info->key); + } + +} + +os_boolean +v_participantCheckPublicationIgnored( + v_participant _this, + const struct v_publicationInfo *info) +{ + os_boolean ignored = FALSE; + + OSPL_LOCK(_this); + if (_this->ignore) { + ignored = inList(_this->ignore->participants, info->participant_key); + if (!ignored) { + ignored = inList(_this->ignore->publications, info->key); + } + } + OSPL_UNLOCK(_this); + return ignored; } diff --git a/src/kernel/code/v_participantQos.c b/src/kernel/code/v_participantQos.c index 17b7f3ef7..2d4509fa5 100644 --- a/src/kernel/code/v_participantQos.c +++ b/src/kernel/code/v_participantQos.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,12 +26,8 @@ #include "os_report.h" -static const v_qosChangeMask immutableMask = - V_POLICY_BIT_SCHEDULING; +static const v_qosChangeMask immutableMask = V_POLICY_BIT_SCHEDULING; -/************************************************************** - * private functions - **************************************************************/ static c_bool v_participantQosValidValues( v_participantQos qos) @@ -52,9 +49,6 @@ v_participantQosValidValues( return (valuesNok) ? FALSE : TRUE; } -/************************************************************** - * constructor/destructor - **************************************************************/ v_participantQos v_participantQosNew( v_kernel kernel, @@ -106,9 +100,6 @@ v_participantQosFree( c_free(q); } -/************************************************************** - * Protected functions - **************************************************************/ v_result v_participantQosCompare( v_participantQos q, @@ -120,7 +111,7 @@ v_participantQosCompare( cm = 0; if ((q != NULL) && (tmpl != NULL) && (changeMask != NULL)) { - /* built change mask */ + /* built change mask */ if (!v_entityFactoryPolicyIEqual(q->entityFactory, tmpl->entityFactory)) { cm |= V_POLICY_BIT_ENTITYFACTORY; } @@ -144,9 +135,6 @@ v_participantQosCompare( return result; } -/************************************************************** - * Public functions - **************************************************************/ v_result v_participantQosCheck( v_participantQos _this) diff --git a/src/kernel/code/v_partition.c b/src/kernel/code/v_partition.c index a72c2395d..89d820e54 100644 --- a/src/kernel/code/v_partition.c +++ b/src/kernel/code/v_partition.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -32,8 +33,6 @@ #include "os_heap.h" #include "os_report.h" -/* Protected */ - c_bool v_partitionExpressionIsAbsolute( const c_char* expression) @@ -111,7 +110,8 @@ v_partitionNew( partition = c_iterTakeFirst(existing); } else { partition = v_partition(v_objectNew(kernel,K_DOMAIN)); - v_entityInit(v_entity(partition),name, TRUE); + v_entityInit(v_entity(partition), name); + (void)v_entityEnable(v_entity(partition)); found = v_addPartition(kernel,partition); if (found != partition) { v_partitionFree(partition); diff --git a/src/kernel/code/v_partitionAdmin.c b/src/kernel/code/v_partitionAdmin.c index 0c8e7e2b4..3aa3e0b54 100644 --- a/src/kernel/code/v_partitionAdmin.c +++ b/src/kernel/code/v_partitionAdmin.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -28,126 +29,6 @@ #define CLASSNAME "kernelModuleI::v_partitionAdmin" -/************************************************************** - * Private functions - **************************************************************/ -static c_bool -v__partitionAdminAdd( - v_partitionAdmin da, - const char *partitionName, - v_partition *newPartition) -{ - c_bool result = TRUE; - v_partition partition, found; - - assert(v_partitionExpressionIsAbsolute(partitionName)); - assert(newPartition != NULL); - - partition = v_partitionNew(v_objectKernel(da), partitionName, NULL); - found = c_tableInsert(da->partitions, partition); - if (found != partition) { - c_free(partition); - result = FALSE; - *newPartition = NULL; - } else { - /* Do not free partition here because it is returned */ - *newPartition = partition; - } - - return result; -} - -static c_bool -v_partitionAdminAddExpression( - v_partitionAdmin da, - const char *partitionExpr) -{ - c_bool result = TRUE; - v_partitionInterest partitionInterest, found; - - assert(!v_partitionExpressionIsAbsolute(partitionExpr)); - - partitionInterest = v_partitionInterestNew(v_objectKernel(da), partitionExpr); - found = c_tableInsert(da->partitionInterests, partitionInterest); - if (found != partitionInterest) { - result = FALSE; - } - c_free(partitionInterest); - - return result; -} - -static c_bool -v__partitionAdminRemove( - v_partitionAdmin da, - const char *partitionName, - v_partition *partitionRemoved) -{ - c_bool result; - v_partition partition, found; - q_expr expr; - c_collection q; - c_iter list; - c_value params[1]; - - assert(v_partitionExpressionIsAbsolute(partitionName)); - - expr = (q_expr)q_parse("name like %0"); - params[0] = c_stringValue((char *)partitionName); - q = c_queryNew(da->partitions, expr, params); - q_dispose(expr); - list = ospl_c_select(q,0); - assert(c_iterLength(list) <= 1); - partition = v_partition(c_iterTakeFirst(list)); - if (partition) { - found = c_tableRemove(da->partitions, partition, NULL, NULL); - *partitionRemoved = found; - c_free(partition); - result = TRUE; - } else { - *partitionRemoved = NULL; - result = FALSE; - } - c_free(q); - c_iterFree(list); - - return result; -} - -static c_bool -v_partitionAdminRemoveExpression( - v_partitionAdmin da, - const char *partitionExpr) -{ - c_bool result = FALSE; - v_partitionInterest partitionInterest, found; - q_expr expr; - c_collection q; - c_iter list; - c_value params[1]; - - assert(!v_partitionExpressionIsAbsolute(partitionExpr)); - - expr = (q_expr)q_parse("expression like %0"); - params[0] = c_stringValue((char *)partitionExpr); - q = c_queryNew(da->partitionInterests, expr, params); - q_dispose(expr); - list = ospl_c_select(q,0); - assert(c_iterLength(list) <= 1); - partitionInterest = v_partitionInterest(c_iterTakeFirst(list)); - while (partitionInterest) { - result = TRUE; - found = c_tableRemove(da->partitionInterests, partitionInterest, NULL, NULL); - c_free(partitionInterest); - c_free(found); - partitionInterest = v_partitionInterest(c_iterTakeFirst(list)); - } - c_free(q); - c_iterFree(list); - - return result; -} - static c_bool checkPartitionInterest( c_object o, @@ -250,13 +131,6 @@ addPartition( } } -/************************************************************** - * constructor/destructor - **************************************************************/ - -/************************************************************** - * Protected functions - **************************************************************/ v_partitionAdmin v_partitionAdminNew( v_kernel kernel) @@ -269,9 +143,9 @@ v_partitionAdminNew( if (da != NULL) { da->partitions = c_tableNew(v_kernelType(kernel, K_DOMAIN),"name"); da->partitionInterests = c_tableNew(v_kernelType(kernel, K_DOMAININTEREST), "expression"); - c_mutexInit(c_getBase(da), &da->mutex); - if ((da->partitions == NULL) || (da->partitionInterests == NULL)) { + if ((da->partitions == NULL) || (da->partitionInterests == NULL) || + c_mutexInit(c_getBase(da), &da->mutex) != SYNC_RESULT_SUCCESS) { c_free(da); da = NULL; } @@ -290,72 +164,55 @@ v_partitionAdminFree( } } -c_bool -v_partitionAdminFitsInterest( - v_partitionAdmin da, - v_partition d) -{ - c_bool result; - - c_mutexLock(&da->mutex); - result = !c_tableWalk(da->partitionInterests, checkPartitionInterest, d); - c_mutexUnlock(&da->mutex); - - return result; -} - -c_iter -v_partitionAdminAdd( +void +v_partitionAdminFill( v_partitionAdmin da, const c_char *partitionExpr) { -/* partitionExpr: expression or absolute partition name */ + /* partitionExpr: expression or absolute partition name */ c_iter partitions; v_partition d; partitions = NULL; c_mutexLock(&da->mutex); if (v_partitionExpressionIsAbsolute(partitionExpr)) { - v__partitionAdminAdd(da, partitionExpr, &d); - partitions = c_iterNew(d); + d = v_partitionNew(v_objectKernel(da), partitionExpr, NULL); + (void)ospl_c_insert(da->partitions, d); + c_free(d); } else { - if (v_partitionAdminAddExpression(da, partitionExpr)) { + v_partitionInterest pi, found; + pi = v_partitionInterestNew(v_objectKernel(da), partitionExpr); + found = c_tableInsert(da->partitionInterests, pi); + if (found == pi) { partitions = v_resolvePartitions(v_objectKernel(da), partitionExpr); - c_iterWalk(partitions, addPartition, (c_voidp)da->partitions); + while ((d = c_iterTakeFirst(partitions)) != NULL) { + (void)ospl_c_insert(da->partitions, d); + c_free(d); + } + c_iterFree(partitions); } /* else expression already member */ + c_free(pi); } c_mutexUnlock(&da->mutex); - - return partitions; } -c_iter -v_partitionAdminRemove( +c_bool +v_partitionAdminAdd( v_partitionAdmin da, - const c_char *partitionExpr) + v_partition d) { - /* partitionExpr: expression or absolute partition name */ - c_iter partitions; - v_partition d; - - partitions = NULL; + c_bool inserted; c_mutexLock(&da->mutex); - if (v_partitionExpressionIsAbsolute(partitionExpr)) { - v__partitionAdminRemove(da, partitionExpr, &d); - partitions = c_iterNew(d); - } else { - if (v_partitionAdminRemoveExpression(da, partitionExpr)) { - partitions = v_resolvePartitions(v_objectKernel(da), partitionExpr); - c_iterWalk(partitions, removePartition, (c_voidp)da->partitions); - } /* else expression already member */ + inserted = !c_tableWalk(da->partitionInterests, checkPartitionInterest, d); + if (inserted) { + inserted = (d == ospl_c_insert(da->partitions, d)); } c_mutexUnlock(&da->mutex); - - return partitions; + return inserted; } c_bool -v_partitionAdminSet( +v_partitionAdminUpdate( v_partitionAdmin da, v_partitionPolicyI partitionExpr, c_iter *addedPartitions, @@ -377,8 +234,7 @@ v_partitionAdminSet( resolveArg.kernel = v_objectKernel(da); c_mutexLock(&da->mutex); - /* - * The absolute partition names will be added at the end of + /* The absolute partition names will be added at the end of * the algorithm. * The partition expressions in the parameter of partitionExpr, * replace the existing in da->partitionInterests. @@ -409,8 +265,7 @@ v_partitionAdminSet( c_iterFree(dexpressions); } - /* - * The given expressions are now divided across + /* The given expressions are now divided across * 'addedpartitions' and 'da->partitionInterests'. * Now first add partitions to 'addedpartitions' that fit the * expressions in 'da->partitionInterests'. @@ -418,8 +273,7 @@ v_partitionAdminSet( resolveArg.partitions = addedPartitions; c_tableWalk(da->partitionInterests, resolvePartitions, (c_voidp)&resolveArg); - /* - * Now 'addedpartitions' contains all partitions to be added + /* Now 'addedpartitions' contains all partitions to be added * by the publisher/subscriber. * 'da->partitions' contains the old set of partitions. * We must check whether those partitions must remain in @@ -431,12 +285,11 @@ v_partitionAdminSet( */ updateArg.addPartitions = addedPartitions; updateArg.removePartitions = removedPartitions; - c_tableWalk(da->partitions, updatePartitions, (c_voidp)&updateArg); + (void)c_tableWalk(da->partitions, updatePartitions, (c_voidp)&updateArg); c_iterWalk(*removedPartitions, removePartition, (c_voidp)da->partitions); - /* - * The da->partitions now contains partitions that still comply to new + /* The da->partitions now contains partitions that still comply to new * partitionPolicy. So all partitions in added partitions, must be added * to da->partitions, so it reflects all connected partitions. */ @@ -446,30 +299,6 @@ v_partitionAdminSet( return TRUE; } -c_bool -v_partitionAdminExists( - v_partitionAdmin da, - const c_char *name) -{ - v_partition found; - C_STRUCT(v_entity) template; - - assert(da != NULL); - assert(C_TYPECHECK(da,v_partitionAdmin)); - - template.name = c_stringNew(c_getBase(da), name); - c_mutexLock(&da->mutex); - found = c_find(da->partitions,&template); - c_mutexUnlock(&da->mutex); - c_free(template.name); - - if (found) { - c_free(found); - return TRUE; - } - return FALSE; -} - c_iter v_partitionAdminLookup( v_partitionAdmin da, @@ -522,7 +351,3 @@ v_partitionAdminCount( return result; } - -/************************************************************** - * Public functions - **************************************************************/ diff --git a/src/kernel/code/v_policy.c b/src/kernel/code/v_policy.c index 69db15333..95e6c4038 100644 --- a/src/kernel/code/v_policy.c +++ b/src/kernel/code/v_policy.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -63,17 +64,6 @@ static const struct { int shift; const char *name; } vpolicymapping[] = { { V_SCHEDULINGPOLICY_ID, V_SCHEDULINGPOLICY_NAME } }; -/************************************************************** - * Private functions - **************************************************************/ - -/************************************************************** - * constructor/destructor - **************************************************************/ - -/************************************************************** - * Protected functions - **************************************************************/ v_partitionPolicyI v_partitionPolicyAdd( v_partitionPolicyI p, @@ -186,8 +176,7 @@ v_partitionPolicySplit( nibble[length-1]=0; iter = c_iterAppend(iter, nibble); } else { - /* head points to one of the delimiters, so we - add an empty string */ + /* head points to one of the delimiters, so we add an empty string */ length = 1; nibble = (c_string)os_malloc(length); nibble[length - 1 ] = 0; @@ -209,19 +198,34 @@ v_partitionPolicySplit( return iter; } -/* FIXME: - * "claim" parameter serves as a workaround for dds1784. We need to make sure - * that the owner is not set for DataReader instances when there are no more - * live DataWriters. Otherwise a new DataWriter with a lower strength would - * never be able to take over again! - * - * THIS IS A WORKAROUND AND NEEDS A REAL FIX. - */ +static v_ownershipResult claimOwnership( + struct v_owner *owner, + const struct v_owner *candidate, + v_state messageState) +{ + v_ownershipResult result; + + if (v_stateTest(messageState, L_REGISTER)) { + /* Don't modify anything: a register does not change state (yet). */ + result = V_OWNERSHIP_NOT_OWNER; + } else if (v_stateTest(messageState, L_UNREGISTER)) { + /* If the current owner unregisters, the ownership is reset. */ + v_gidSetNil (owner->gid); + owner->strength = 0; + result = V_OWNERSHIP_OWNER_RESET; + } else { + owner->gid = candidate->gid; + owner->strength = candidate->strength; + result = V_OWNERSHIP_OWNER; + } + return result; +} + v_ownershipResult v_determineOwnershipByStrength ( struct v_owner *owner, const struct v_owner *candidate, - c_bool claim) + v_state messageState) { c_equality equality; v_ownershipResult result; @@ -240,11 +244,7 @@ v_determineOwnershipByStrength ( result = V_OWNERSHIP_ALREADY_OWNER; owner->strength = candidate->strength; } else { - if (claim == TRUE) { - owner->gid = candidate->gid; - owner->strength = candidate->strength; - } - result = V_OWNERSHIP_OWNER; + result = claimOwnership(owner, candidate, messageState); } } else if (candidate->strength < owner->strength) { if (equality == C_EQ) { @@ -259,42 +259,24 @@ v_determineOwnershipByStrength ( result = V_OWNERSHIP_NOT_OWNER; } } else { - if (equality == C_EQ) { - result = V_OWNERSHIP_ALREADY_OWNER; - } else if (equality == C_GT) { - if (claim == TRUE) { - /* The current message comes from a writer, which - * is not owner AND has a strength that is equal to - * the strength of the current owner. So we must - * determine which writer should be the owner. - * Every reader must determine the ownership - * identically, so we determine it by comparing the - * identification of the writer. The writer with - * the highest gid will be the owner. - */ - owner->gid = candidate->gid; - } - result = V_OWNERSHIP_OWNER; - } else { + if (equality == C_LT) { result = V_OWNERSHIP_NOT_OWNER; + } else { + result = claimOwnership(owner, candidate, messageState); } } - } else if (claim == TRUE) { - owner->gid = candidate->gid; - owner->strength = candidate->strength; - result = V_OWNERSHIP_OWNER; } else { - /* Instance has no owner and no registrations either. - * This may happen during deletion of a DataReader or - * when inserting historical data + /* When the owner is not valid, nobody can claim ownership naturally because + * the smallest GID always wins. So enforce ownership transfer explicitly. */ - result = V_OWNERSHIP_OWNER; + result = claimOwnership(owner, candidate, messageState); } } else { result = V_OWNERSHIP_INCOMPATIBLE_QOS; } } else { v_gidSetNil (owner->gid); + owner->strength = 0; result = V_OWNERSHIP_OWNER_RESET; } } else { @@ -304,10 +286,6 @@ v_determineOwnershipByStrength ( return result; } -/************************************************************** - * Public functions - **************************************************************/ - void v_policyReportInvalid( c_ulong mask) diff --git a/src/kernel/code/v_processInfo.c b/src/kernel/code/v_processInfo.c index 8231e1d20..de3e8ec34 100644 --- a/src/kernel/code/v_processInfo.c +++ b/src/kernel/code/v_processInfo.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -128,7 +129,7 @@ v_processInfoGetThreadInfo ( c_mutexLock(&_this->lock); assert(c_tableNofKeys(_this->threads) == 1); - tinfo = c_tableFind(_this->threads, &tidval); + tinfo = c_tableFind(_this->threads, &tidval, 1); if(tinfo == NULL) { tinfo = v_threadInfoNew(c_getBase(c_object(_this)), _this->serial, tid); diff --git a/src/kernel/code/v_projection.c b/src/kernel/code/v_projection.c index b76825b89..85f74fab2 100644 --- a/src/kernel/code/v_projection.c +++ b/src/kernel/code/v_projection.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -234,9 +235,6 @@ v_projectionNew( } assert(resultType != NULL); - /* - p = v_projection(v_objectNew(kernel,K_PROJECTION)); - */ p = c_new(v_kernelType(kernel, K_PROJECTION)); p->rules = (c_array)rules; p->resultType = resultType; /* transfer refcount */ diff --git a/src/kernel/code/v_proxy.c b/src/kernel/code/v_proxy.c index b43ba299e..b4a5a1bf4 100644 --- a/src/kernel/code/v_proxy.c +++ b/src/kernel/code/v_proxy.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/code/v_public.c b/src/kernel/code/v_public.c index c20d77028..f1cd6562e 100644 --- a/src/kernel/code/v_public.c +++ b/src/kernel/code/v_public.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -49,7 +50,7 @@ #include "v__listener.h" #include "v_dataReaderQuery.h" #include "v_dataViewQuery.h" -#include "v_dataViewInstance.h" +#include "v__dataViewInstance.h" #include "v_statusCondition.h" c_bool @@ -106,6 +107,7 @@ v_publicDispose( case K_NWBRIDGE: case K_CMSOAP: case K_RNR: + case K_DBMSCONNECT: case K_SERVICE: v_serviceDeinit(v_service(o)); break; case K_SERVICESTATE: /* Is never freed! */ break; case K_CONFIGURATION: break; diff --git a/src/kernel/code/v_publisher.c b/src/kernel/code/v_publisher.c index 9d05b8ead..d714baa6b 100644 --- a/src/kernel/code/v_publisher.c +++ b/src/kernel/code/v_publisher.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -28,39 +29,130 @@ #include "v__entity.h" #include "v__builtin.h" #include "v_group.h" -#include "v_observable.h" #include "v__observer.h" +#include "v__observable.h" #include "v_public.h" #include "v__policy.h" #include "v_event.h" #include "v_proxy.h" #include "v_partition.h" +#include "v__nameSpace.h" +#include "c_stringSupport.h" #include "q_expr.h" #include "os_report.h" #include "os_heap.h" - -/************************************************************** - * Private functions - **************************************************************/ - +/** + * \brief This operation checks if writer(s) are in correct nameSpace for + * group coherence. + * + * This operation is intended for group coherent publishers and checks if + * writer(s) is/are in a single nameSpace and if they are all part of the + * same nameSpace + * + * \precondition publisher lock is obtained + * + * \param p The publisher to perform this operation on. + * \param writer When not NULL the single nameSpace check is only + * performed on this writer. + * + * \return TRUE when tested writer(s) is/are all in single nameSpace and + * all writers are in the same nameSpace. + * Otherwise FALSE is returned and an error is reported. + */ static c_bool -qosChangedAction( - c_object o, - c_voidp arg) +publisherGroupCoherenceNameSpaceCheck( + v_publisher p, + v_writer writer) { - v_writer w = v_writer(o); + c_bool result = TRUE; + v_kernel kernel; + c_iter nameSpaces; + c_iter partitions = NULL; + struct v_nameSpace *ns; + char *pName; + struct c_collectionIter it; + v_writer w; + char *n2, *n1 = NULL; + v_writerQos qos; - v_writerNotifyChangedQos(w, (v_writerNotifyChangedQosArg *)arg); + assert(p); + assert(C_TYPECHECK(p,v_publisher)); + assert(C_TYPECHECK(writer,v_writer)); - return TRUE; + kernel = v_objectKernel(p); + nameSpaces = v__nameSpaceCollect(kernel); + partitions = v_partitionPolicySplit(p->qos->partition); + if (partitions == NULL) { + partitions = c_iterAppend(partitions, os_strdup("")); + } + + if (writer) { + /* Check only the supplied writer if its in a single nameSpace */ + qos = v_writerGetQos(writer); + if (qos->durability.v.kind != V_DURABILITY_VOLATILE) { + if (v__writerInSingleNameSpace(writer, partitions, nameSpaces) == FALSE) { + result = FALSE; + } + } + c_free(qos); + } else { + /* Check if all writers are in a single nameSpace */ + for (w = c_collectionIterFirst(p->writers, &it); w; w = c_collectionIterNext(&it)) { + qos = v_writerGetQos(w); + if (qos->durability.v.kind != V_DURABILITY_VOLATILE) { + if (v__writerInSingleNameSpace(w, partitions, nameSpaces) == FALSE) { + result = FALSE; + } + } + c_free(qos); + } + } + + /* Check if writers are in the same nameSpace */ + if (result == TRUE) { + if (writer) { + /* Use the supplied writer to check for same nameSpace */ + /* result == TRUE so writer is non volatile + */ + n1 = v__writerGetNameSpaceNames(writer, partitions, nameSpaces); + } + for (w = c_collectionIterFirst(p->writers, &it); w && result == TRUE; w = c_collectionIterNext(&it)) { + qos = v_writerGetQos(w); + if (qos->durability.v.kind != V_DURABILITY_VOLATILE) { + if (writer == NULL) { + writer = w; /* use first non volatile writer for same check */ + n1 = v__writerGetNameSpaceNames(writer, partitions, nameSpaces); + } else { + n2 = v__writerGetNameSpaceNames(w, partitions, nameSpaces); + if (n1 == NULL || n2 == NULL || strcmp(n1, n2) != 0) { + OS_REPORT (OS_ERROR, OS_FUNCTION, V_RESULT_UNDEFINED, + "Not all writer for group coherent %s are in the same nameSpace", v_entityName(p)); + result = FALSE; + } + os_free(n2); + n2 = NULL; + } + } + c_free(qos); + } + os_free(n1); + } + + while ((pName = c_iterTakeFirst(partitions)) != NULL) { + os_free(pName); + } + c_iterFree(partitions); + while ((ns = c_iterTakeFirst(nameSpaces)) != NULL) { + v__nameSpaceFree(ns); + } + c_iterFree(nameSpaces); + + return result; } -/************************************************************** - * constructor/destructor - **************************************************************/ v_publisher v_publisherNew( v_participant participant, @@ -94,7 +186,7 @@ v_publisherNew( q = v_publisherQosNew(kernel,qos); if (q != NULL) { p = v_publisher(v_objectNew(kernel,K_PUBLISHER)); - v_entityInit(v_entity(p),name,enable); + v_entityInit(v_entity(p),name); p->partitions = v_partitionAdminNew(kernel); p->writers = c_setNew(v_kernelType(kernel,K_WRITER)); p->qos = q; @@ -105,11 +197,10 @@ v_publisherNew( p->tidList = NULL; p->orderbyFixed = FALSE; p->orderby = V_ORDERBY_RECEPTIONTIME; - c_lockInit(c_getBase(p), &p->lock); v_participantAdd(participant,v_object(p)); assert(c_refCount(p) == 3); /* as handle, by participant and the local variable p */ if (enable) { - v_publisherEnable(p); + (void)v_entityEnable(v_entity(p)); } } else { OS_REPORT(OS_ERROR, "v_publisherNew", V_RESULT_INTERNAL_ERROR, @@ -128,28 +219,41 @@ v_result v_publisherEnable( v_publisher _this) { - v_kernel kernel; - v_message builtinCMMsg; - c_iter list; - c_char *partitionName; v_result result = V_RESULT_ILL_PARAM; + v_kernel kernel; if (_this) { + v_message builtinCMMsg = NULL; kernel = v_objectKernel(_this); - v_observableAddObserver(v_observable(kernel->groupSet), v_observer(_this), NULL); + result = V_RESULT_OK; - if (_this->qos->partition.v != NULL) { - list = v_partitionPolicySplit(_this->qos->partition); - while((partitionName = c_iterTakeFirst(list)) != NULL) { - v_publisherPublish(_this,partitionName); - os_free(partitionName); + OSPL_LOCK(_this); + if ((_this->qos->presentation.v.access_scope == V_PRESENTATION_GROUP) && + (_this->qos->presentation.v.coherent_access == TRUE) && + (publisherGroupCoherenceNameSpaceCheck(_this, NULL) == FALSE)) { +#ifdef ENABLE_GROUP_COHERENT_NAMESPACE_CHECK_FAILURE + result = V_RESULT_PRECONDITION_NOT_MET; + OS_REPORT(OS_ERROR, OS_FUNCTION, V_RESULT_PRECONDITION_NOT_MET, + "Publisher enable failed: writer nameSpace error"); +#endif + } + if (result == V_RESULT_OK) { + if (_this->qos->partition.v != NULL) { + c_char *partitionName; + c_iter list = v_partitionPolicySplit(_this->qos->partition); + while((partitionName = c_iterTakeFirst(list)) != NULL) { + v_partitionAdminFill(_this->partitions, partitionName); + os_free(partitionName); + } + c_iterFree(list); } - c_iterFree(list); + builtinCMMsg = v_builtinCreateCMPublisherInfo(kernel->builtin, _this); + } + OSPL_UNLOCK(_this); + if (builtinCMMsg) { + v_writeBuiltinTopic(kernel, V_CMPUBLISHERINFO_ID, builtinCMMsg); + c_free(builtinCMMsg); } - builtinCMMsg = v_builtinCreateCMPublisherInfo(kernel->builtin, _this); - v_writeBuiltinTopic(kernel, V_CMPUBLISHERINFO_ID, builtinCMMsg); - c_free(builtinCMMsg); - result = V_RESULT_OK; } return result; } @@ -169,7 +273,6 @@ v_publisherFree( kernel = v_objectKernel(p); builtinCMMsg = v_builtinCreateCMPublisherInfo(kernel->builtin, p); unregisterCMMsg = v_builtinCreateCMPublisherInfo(kernel->builtin, p); - v_observableRemoveObserver(v_observable(kernel->groupSet),v_observer(p), NULL); while ((o = c_take(p->writers)) != NULL) { /* remove writer from all partitions */ @@ -198,10 +301,6 @@ v_publisherDeinit( v_entityDeinit(v_entity(p)); } -/************************************************************** - * Protected functions - **************************************************************/ - v_publisherQos v_publisherGetQos( v_publisher _this) @@ -211,9 +310,9 @@ v_publisherGetQos( assert(_this != NULL); assert(C_TYPECHECK(_this,v_publisher)); - c_lockRead(&_this->lock); + OSPL_LOCK(_this); qos = c_keep(_this->qos); - c_lockUnlock(&_this->lock); + OSPL_UNLOCK(_this); return qos; } @@ -225,7 +324,7 @@ v_publisherSetQos( { v_result result; v_kernel kernel; - v_publisherQos qos; + v_publisherQos qos, prevQos; v_qosChangeMask cm; v_writerNotifyChangedQosArg arg; v_partition d; @@ -239,18 +338,16 @@ v_publisherSetQos( result = v_publisherQosCheck(tmpl); if (result == V_RESULT_OK) { - c_lockWrite(&p->lock); + kernel = v_objectKernel(p); + qos = v_publisherQosNew(kernel, tmpl); + if (!qos) { + return V_RESULT_OUT_OF_MEMORY; + } /* For now we don't allow changing the publisher qos during a coherent update. * we might want to improve this by only disallowing changes that break * connectivity or eventually allow them and correctly handle the impact. */ if (p->coherentNestingLevel == 0) { - kernel = v_objectKernel(p); - qos = v_publisherQosNew(kernel, tmpl); - if (!qos) { - c_lockUnlock(&p->lock); - return V_RESULT_OUT_OF_MEMORY; - } /* ES, dds1576: When the QoS is being set we have to verify that the partitions * listed in the qos do not have an invalid access mode set. For a publisher @@ -267,46 +364,75 @@ v_publisherSetQos( } if (access == V_ACCESS_MODE_READ_WRITE || access == V_ACCESS_MODE_WRITE) { - result = v_publisherQosCompare(p->qos, qos, v_entityEnabled(v_entity(p)), &cm); + v_message builtinCMMsg = NULL; + c_iter writers = NULL; + v_writer writer; + OSPL_LOCK(p); + result = v_publisherQosCompare(p->qos, qos, v__entityEnabled_nl(v_entity(p)), &cm); if ((result == V_RESULT_OK) && (cm != 0)) { - v_message builtinCMMsg; - c_free(p->qos); + prevQos = p->qos; p->qos = c_keep(qos); if (cm & V_POLICY_BIT_PARTITION) { /* partition policy has changed! */ - v_partitionAdminSet(p->partitions, - p->qos->partition, - &arg.addedPartitions, - &arg.removedPartitions); - } - c_walk(p->writers, qosChangedAction, &arg); - - d = v_partition(c_iterTakeFirst(arg.addedPartitions)); - while (d != NULL) { - c_free(d); - d = v_partition(c_iterTakeFirst(arg.addedPartitions)); + /* Only the changing of the partition Qos policy of the publisher can + * change the namespace(s) a writer belongs too. */ + if ((p->qos->presentation.v.access_scope == V_PRESENTATION_GROUP) && + (p->qos->presentation.v.coherent_access == TRUE) && + (publisherGroupCoherenceNameSpaceCheck(p, NULL) == FALSE)) { + /* reset the qos */ +#ifdef ENABLE_GROUP_COHERENT_NAMESPACE_CHECK_FAILURE + c_free(p->qos); + p->qos = c_keep(prevQos); + result = V_RESULT_PRECONDITION_NOT_MET; + OS_REPORT(OS_ERROR, OS_FUNCTION, V_RESULT_PRECONDITION_NOT_MET, + "Publisher qos change failed: writer nameSpace error"); +#endif + } } - c_iterFree(arg.addedPartitions); - d = v_partition(c_iterTakeFirst(arg.removedPartitions)); - while (d != NULL) { - c_free(d); - d = v_partition(c_iterTakeFirst(arg.removedPartitions)); + c_free(prevQos); + + if (result == V_RESULT_OK) { + if (cm & V_POLICY_BIT_PARTITION) { /* partition policy has changed! */ + v_partitionAdminUpdate(p->partitions, + p->qos->partition, + &arg.addedPartitions, + &arg.removedPartitions); + } + writers = ospl_c_select(p->writers, 0); } - c_iterFree(arg.removedPartitions); - if (v_entity(p)->enabled) { + if (v__entityEnabled_nl(v_entity(p))) { builtinCMMsg = v_builtinCreateCMPublisherInfo (kernel->builtin, p); - v_writeBuiltinTopic(kernel, V_CMPUBLISHERINFO_ID, builtinCMMsg); - c_free(builtinCMMsg); } } + OSPL_UNLOCK(p); + while ((writer = c_iterTakeFirst(writers)) != NULL) { + v_writerNotifyChangedQos(writer, &arg); + c_free(writer); + } + c_iterFree(writers); + d = v_partition(c_iterTakeFirst(arg.addedPartitions)); + while (d != NULL) { + c_free(d); + d = v_partition(c_iterTakeFirst(arg.addedPartitions)); + } + c_iterFree(arg.addedPartitions); + d = v_partition(c_iterTakeFirst(arg.removedPartitions)); + while (d != NULL) { + c_free(d); + d = v_partition(c_iterTakeFirst(arg.removedPartitions)); + } + c_iterFree(arg.removedPartitions); + if (builtinCMMsg) { + v_writeBuiltinTopic(kernel, V_CMPUBLISHERINFO_ID, builtinCMMsg); + c_free(builtinCMMsg); + } } else { result = V_RESULT_PRECONDITION_NOT_MET; } - c_free(qos); } else { result = V_RESULT_PRECONDITION_NOT_MET; } - c_lockUnlock(&p->lock); + c_free(qos); } return result; } @@ -317,16 +443,14 @@ assertLivelinessWriter( c_object o, c_voidp arg) { - v_entity e = v_entity(o); - v_handle handle = *(v_handle *)arg; - - if (v_objectKind(e) == K_WRITER) { - if (arg == NULL) { /* assert ALL writers */ - v_writerAssertByPublisher(v_writer(e)); - } else { /* assert all writers except writer starting the event! */ - if (v_handleIsEqual(v_publicHandle(v_public(e)), handle) == FALSE) { - v_writerAssertByPublisher(v_writer(e)); - } + v_event e = (v_event)arg; + v_writer w = v_writer(o); + + if (e == NULL) { /* assert ALL writers */ + v_writerAssertByPublisher(w); + } else { /* assert all writers except writer starting the event! */ + if (w != v_writer(e->source)) { + v_writerAssertByPublisher(w); } } return TRUE; @@ -337,10 +461,10 @@ v_publisherAssertLiveliness( v_publisher p, v_event e) { - if (e->kind == V_EVENT_LIVELINESS_ASSERT) { - c_lockRead(&p->lock); - c_walk(p->writers, assertLivelinessWriter, (c_voidp)&e->source); - c_lockUnlock(&p->lock); + if (e == NULL || e->kind == V_EVENT_LIVELINESS_ASSERT) { + OSPL_LOCK(p); + c_walk(p->writers, assertLivelinessWriter, (c_voidp)e); + OSPL_UNLOCK(p); } } @@ -349,40 +473,29 @@ v_publisherConnectNewGroup( v_publisher p, v_group g) { - c_bool connect; - c_iter addedPartitions; - v_partition d; - + c_iter writers = NULL; + v_writer writer = NULL; /* ES, dds1576: Only process this group event if the access rights to * the partition listed in the group is write or read_write. */ if(v_groupPartitionAccessMode(g) == V_ACCESS_MODE_READ_WRITE || v_groupPartitionAccessMode(g) == V_ACCESS_MODE_WRITE) { - (void)c_lockWrite(&p->lock); - connect = v_partitionAdminFitsInterest(p->partitions, g->partition); - - if (connect) { - addedPartitions = v_partitionAdminAdd(p->partitions, - v_entityName(g->partition)); - d = v_partition(c_iterTakeFirst(addedPartitions)); - while (d != NULL) { - c_free(d); - d = v_partition(c_iterTakeFirst(addedPartitions)); - } - c_iterFree(addedPartitions); - - c_walk(p->writers, (c_action)v_writerPublishGroup, g); + OSPL_LOCK(p); + if (v_partitionAdminAdd(p->partitions, g->partition)) { + writers = ospl_c_select(p->writers, 0); }/*else do not connect */ - c_lockUnlock(&p->lock); + OSPL_UNLOCK(p); + while ((writer = c_iterTakeFirst(writers)) != NULL) { + v_writerPublishGroup(writer, g); + c_free(writer); + } + c_iterFree(writers); } return TRUE; } -/************************************************************** - * Public functions - **************************************************************/ static c_bool collectPartitions( c_object o, @@ -401,7 +514,7 @@ v_publisherAddWriter( { v_result result = V_RESULT_OK; v_partition d; - c_iter iter; + c_iter partitions = NULL; c_ulong transactionId; assert(p != NULL); @@ -409,11 +522,31 @@ v_publisherAddWriter( assert(w != NULL); assert(C_TYPECHECK(w,v_writer)); - iter = c_iterNew(NULL); - (void)c_lockWrite(&p->lock); + OSPL_LOCK(p); - if (p->qos->presentation.v.access_scope == V_PRESENTATION_GROUP && - p->qos->presentation.v.ordered_access == TRUE) + if ((p->qos->presentation.v.coherent_access == TRUE) && + (p->qos->presentation.v.access_scope != V_PRESENTATION_INSTANCE) && + (w->qos->history.v.kind == V_HISTORY_KEEPLAST)) { + result = V_RESULT_PRECONDITION_NOT_MET; + OS_REPORT(OS_ERROR, OS_FUNCTION, V_RESULT_PRECONDITION_NOT_MET, + "Could not enable writer, KEEP_LAST history QoS is not supported in combination with coherent access"); + } + + if ((result == V_RESULT_OK) && + (p->qos->presentation.v.access_scope == V_PRESENTATION_GROUP) && + (p->qos->presentation.v.coherent_access == TRUE)) { + if (publisherGroupCoherenceNameSpaceCheck(p, w) == FALSE) { +#ifdef ENABLE_GROUP_COHERENT_NAMESPACE_CHECK_FAILURE + result = V_RESULT_PRECONDITION_NOT_MET; + OS_REPORT(OS_ERROR, OS_FUNCTION, V_RESULT_PRECONDITION_NOT_MET, + "Failed to add writer to publisher: writer nameSpace error"); +#endif + } + } + + if ((result == V_RESULT_OK) && + (p->qos->presentation.v.access_scope == V_PRESENTATION_GROUP) && + (p->qos->presentation.v.ordered_access == TRUE)) { if (p->orderbyFixed == FALSE) { p->orderbyFixed = TRUE; @@ -426,11 +559,10 @@ v_publisherAddWriter( } if (result == V_RESULT_OK) { - if (p->coherentNestingLevel > 0) { + if (p->coherentNestingLevel > 0 && p->qos->presentation.v.coherent_access) { v_writerCoherentBegin(w, &transactionId); if (p->qos->presentation.v.access_scope == V_PRESENTATION_GROUP) { - /* - * A group coherent update is in progress so extend the existing + /* A group coherent update is in progress so extend the existing * tidList with new writer transactionId. */ c_ulong oldSize = c_arraySize(p->tidList); @@ -442,18 +574,20 @@ v_publisherAddWriter( ((struct v_tid *)p->tidList)[oldSize].seqnr = transactionId; } } + c_setInsert(p->writers,w); - v_partitionAdminWalk(p->partitions, collectPartitions, iter); - while ((d = c_iterTakeFirst(iter)) != NULL) { + partitions = c_iterNew(NULL); + v_partitionAdminWalk(p->partitions, collectPartitions, partitions); + } + OSPL_UNLOCK(p); + if (result == V_RESULT_OK) { + while ((d = c_iterTakeFirst(partitions)) != NULL) { v_writerPublish(w,d); c_free(d); } - c_setInsert(p->writers,w); + c_iterFree(partitions); } - c_lockUnlock(&p->lock); - c_iterFree(iter); - return result; } #define v_publisherId(_this) v_public(_this)->handle.index @@ -471,9 +605,9 @@ v_publisherRemoveWriter( assert(w != NULL); assert(C_TYPECHECK(w, v_writer)); - (void)c_lockWrite(&_this->lock); + OSPL_LOCK(_this); found = c_remove(_this->writers, w, NULL, NULL); - c_lockUnlock(&_this->lock); + OSPL_UNLOCK(_this); if (found) { c_free(found); @@ -494,86 +628,11 @@ v_publisherWalkWriters( assert(_this != NULL); assert(C_TYPECHECK(_this,v_publisher)); - (void)c_lockWrite(&_this->lock); + OSPL_LOCK(_this); (void)c_setWalk(_this->writers,(c_action)action,arg); - (void)c_lockUnlock(&_this->lock); -} - -c_bool -v_publisherCheckPartitionInterest( - v_publisher p, - v_partition partition) -{ - return v_partitionAdminFitsInterest(p->partitions, partition); -} - -void -v_publisherPublish( - v_publisher p, - const c_char *partitionExpr) -{ - v_partition d; - v_writerNotifyChangedQosArg arg; - v_partitionPolicyI old; - - assert(p != NULL); - assert(C_TYPECHECK(p,v_publisher)); - - arg.removedPartitions = NULL; - - (void)c_lockWrite(&p->lock); - arg.addedPartitions = v_partitionAdminAdd(p->partitions, partitionExpr); - - old = p->qos->partition; - p->qos->partition = v_partitionPolicyAdd(old, partitionExpr, c_getBase(c_object(p))); - c_free(old.v); - - c_walk(p->writers, qosChangedAction, &arg); - - d = v_partition(c_iterTakeFirst(arg.addedPartitions)); - while (d != NULL) { - c_free(d); - d = v_partition(c_iterTakeFirst(arg.addedPartitions)); - } - c_iterFree(arg.addedPartitions); - - c_lockUnlock(&p->lock); + OSPL_UNLOCK(_this); } -void -v_publisherUnPublish( - v_publisher p, - const c_char *partitionExpr) -{ - v_partition d; - v_writerNotifyChangedQosArg arg; - v_partitionPolicyI old; - - assert(p != NULL); - assert(C_TYPECHECK(p,v_publisher)); - - arg.addedPartitions = NULL; - - (void)c_lockWrite(&p->lock); - arg.removedPartitions = v_partitionAdminRemove(p->partitions, partitionExpr); - - old = p->qos->partition; - p->qos->partition = v_partitionPolicyRemove(old, partitionExpr, c_getBase(c_object(p))); - c_free(old.v); - - c_walk(p->writers, qosChangedAction, &arg); - - d = v_partition(c_iterTakeFirst(arg.removedPartitions)); - while (d != NULL) { - c_free(d); - d = v_partition(c_iterTakeFirst(arg.removedPartitions)); - } - c_iterFree(arg.removedPartitions); - - c_lockUnlock(&p->lock); -} - - c_iter v_publisherLookupWriters( v_publisher p, @@ -592,9 +651,9 @@ v_publisherLookupWriters( q = c_queryNew(p->writers,expr,params); q_dispose(expr); - c_lockRead(&p->lock); + OSPL_LOCK(p); list = ospl_c_select(q,0); - c_lockUnlock(&p->lock); + OSPL_UNLOCK(p); c_free(q); return list; } @@ -609,9 +668,9 @@ v_publisherLookupPartitions( assert(p != NULL); assert(C_TYPECHECK(p,v_publisher)); - c_lockRead(&p->lock); + OSPL_LOCK(p); list = v_partitionAdminLookup(p->partitions, partitionExpr); - c_lockUnlock(&p->lock); + OSPL_UNLOCK(p); return list; } @@ -623,11 +682,11 @@ v_publisherSuspend ( assert(p != NULL); assert(C_TYPECHECK(p,v_publisher)); - (void)c_lockWrite(&p->lock); + OSPL_LOCK(p); if (!v_publisherIsSuspended(p)) { p->suspendTime = os_timeEGet(); /* Compared with allocTime */ } /* else publisher was already suspended, so no-op */ - c_lockUnlock(&p->lock); + OSPL_UNLOCK(p); } c_bool @@ -642,12 +701,12 @@ v_publisherResume ( assert(p != NULL); assert(C_TYPECHECK(p,v_publisher)); - (void)c_lockWrite(&p->lock); + OSPL_LOCK(p); if (v_publisherIsSuspended(p)) { const os_timeW resumeTime = os_timeWGet(); p->suspendTime = OS_TIMEE_INFINITE; writers = ospl_c_select(p->writers, 0); - c_lockUnlock(&p->lock); + OSPL_UNLOCK(p); while ((w = v_writer(c_iterTakeFirst(writers))) != NULL) { v_writerResumePublication(w, &resumeTime); @@ -656,7 +715,7 @@ v_publisherResume ( c_iterFree(writers); resumed = TRUE; } else { - c_lockUnlock(&p->lock); + OSPL_UNLOCK(p); } return resumed; @@ -690,7 +749,7 @@ beginTransaction ( } c_bool -v__publisherCoherentTransactionSingleNoLock( +v_publisherStartTransaction( v_publisher p, c_ulong *publisherId, c_ulong *transactionId) @@ -701,6 +760,7 @@ v__publisherCoherentTransactionSingleNoLock( assert(publisherId != NULL); assert(transactionId != NULL); + OSPL_LOCK(p); if (p->qos->presentation.v.access_scope != V_PRESENTATION_INSTANCE && p->qos->presentation.v.coherent_access == TRUE) { if (p->coherentNestingLevel == 0) { *publisherId = (p->qos->presentation.v.access_scope == V_PRESENTATION_GROUP) ? v_publisherId(p) : 0; @@ -708,7 +768,7 @@ v__publisherCoherentTransactionSingleNoLock( result = TRUE; } } - + OSPL_UNLOCK(p); return result; } @@ -721,9 +781,11 @@ v_publisherCoherentBegin ( assert(p != NULL); assert(C_TYPECHECK(p,v_publisher)); - (void)c_lockWrite(&p->lock); + OSPL_LOCK(p); if (++(p->coherentNestingLevel) == 1) { - if (p->qos->presentation.v.access_scope != V_PRESENTATION_INSTANCE && p->qos->presentation.v.coherent_access == TRUE){ + if (p->qos->presentation.v.access_scope != V_PRESENTATION_INSTANCE && + p->qos->presentation.v.coherent_access == TRUE) + { struct beginTransactionInfo info; assert(p->tidList == NULL); @@ -739,7 +801,7 @@ v_publisherCoherentBegin ( result = info.result; } } - c_lockUnlock(&p->lock); + OSPL_UNLOCK(p); return result; } @@ -774,7 +836,7 @@ v_publisherCoherentEnd ( assert(p != NULL); assert(C_TYPECHECK(p,v_publisher)); - (void)c_lockWrite(&p->lock); + OSPL_LOCK(p); if (p->coherentNestingLevel == 0) { result = V_RESULT_PRECONDITION_NOT_MET; OS_REPORT(OS_ERROR, "v_publisherCoherentEnd", V_RESULT_PRECONDITION_NOT_MET, @@ -801,8 +863,7 @@ v_publisherCoherentEnd ( c_free(eotInfo.tidList); } } - - c_lockUnlock(&p->lock); + OSPL_UNLOCK(p); return result; } diff --git a/src/kernel/code/v_publisherQos.c b/src/kernel/code/v_publisherQos.c index 443a48a23..bfd991520 100644 --- a/src/kernel/code/v_publisherQos.c +++ b/src/kernel/code/v_publisherQos.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,9 +28,6 @@ static const v_qosChangeMask immutableMask = V_POLICY_BIT_PRESENTATION; -/************************************************************** - * private functions - **************************************************************/ static c_bool v_publisherQosValidValues( v_publisherQos qos) @@ -52,9 +50,6 @@ v_publisherQosValidValues( return (valuesNok) ? FALSE : TRUE; } -/************************************************************** - * constructor/destructor - **************************************************************/ v_publisherQos v_publisherQosNew( v_kernel kernel, @@ -108,9 +103,6 @@ v_publisherQosFree( c_free(q); } -/************************************************************** - * Protected functions - **************************************************************/ v_result v_publisherQosCompare ( v_publisherQos _this, @@ -153,9 +145,6 @@ v_publisherQosCompare ( return result; } -/************************************************************** - * Public functions - **************************************************************/ v_result v_publisherQosCheck( v_publisherQos _this) diff --git a/src/kernel/code/v_qos.c b/src/kernel/code/v_qos.c index 802cd6998..753ff1ded 100644 --- a/src/kernel/code/v_qos.c +++ b/src/kernel/code/v_qos.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,10 +28,12 @@ #include "v_kernelQos.h" #include "os_report.h" +_Check_return_ +_Pre_satisfies_(kind >= V_PARTITION_QOS && kind < V_COUNT_QOS) v_qos v_qosCreate( - c_base base, - v_qosKind kind) + _In_ c_base base, + _In_ v_qosKind kind) { v_qos qos; c_type type; @@ -55,19 +58,12 @@ v_qosCreate( OS_REPORT(OS_CRITICAL,"v_qos::Create",V_RESULT_ILL_PARAM, "Illegal Qos kind specified (%s)", v_qosKindImage(kind)); - return NULL; + type = c_resolve(base, "kernelModuleI::v_kernelQos"); } - qos = v_qos(c_new_s(type)); + qos = v_qos(c_new(type)); c_free(type); - if (qos) { - qos->kind = kind; - } else { - OS_REPORT(OS_FATAL, - "v_qosCreate",V_RESULT_INTERNAL_ERROR, - "Failed to allocate qos."); - assert(FALSE); - } + qos->kind = kind; return qos; diff --git a/src/kernel/code/v_query.c b/src/kernel/code/v_query.c index 1668519a0..d9c2041ee 100644 --- a/src/kernel/code/v_query.c +++ b/src/kernel/code/v_query.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,7 +23,7 @@ #include "v_queryStatistics.h" #include "v__dataReader.h" #include "v__dataView.h" -#include "v_dataViewInstance.h" +#include "v__dataViewInstance.h" #include "v_dataReaderQuery.h" #include "v_dataViewQuery.h" #include "v_entity.h" @@ -82,7 +83,7 @@ v_queryInit( { assert(C_TYPECHECK(_this,v_query)); - v_collectionInit(v_collection(_this), name, TRUE); + v_collectionInit(v_collection(_this), name); _this->source = src; _this->expression = c_stringNew(c_getBase(_this), expression); @@ -416,21 +417,6 @@ v_queryTake( return v_queryTakeInternal(_this, NULL, FALSE, action, arg, timeout); } -void -v_queryNotify( - v_query _this, - v_event event, - c_voidp userData) -{ - OS_UNUSED_ARG(userData); - if (_this && event) { - if (event->kind != V_EVENT_DATA_AVAILABLE) { - OS_REPORT(OS_WARNING, "v_query", V_RESULT_ILL_PARAM, - "Unexpected event %d", event->kind); - } - } -} - void v_queryDetachWaitsets( v_query _this) @@ -439,18 +425,18 @@ v_queryDetachWaitsets( v_observable observable = v_observable(_this); v_proxy proxy, next; - v_observerLock(observer); + OSPL_LOCK(observer); proxy = observable->observers; while (proxy) { next = proxy->next; if (v_objectKind(proxy->source2) == K_WAITSET) { - v_observerUnlock(observer); + OSPL_UNLOCK(observer); (void)v_waitsetDetach(v_waitset(proxy->source2), observable); - v_observerLock(observer); + OSPL_LOCK(observer); } proxy = next; } - v_observerUnlock(observer); + OSPL_UNLOCK(observer); } c_bool diff --git a/src/kernel/code/v_queryStatistics.c b/src/kernel/code/v_queryStatistics.c index 1caf06352..a487c7e62 100644 --- a/src/kernel/code/v_queryStatistics.c +++ b/src/kernel/code/v_queryStatistics.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/code/v_reader.c b/src/kernel/code/v_reader.c index 5c7467f01..403a29bf3 100644 --- a/src/kernel/code/v_reader.c +++ b/src/kernel/code/v_reader.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,31 +19,34 @@ * */ #include "v__kernel.h" +#include "v__builtin.h" #include "v__reader.h" #include "v__readerQos.h" +#include "v__subscriberQos.h" #include "v__observer.h" #include "v_subscriber.h" #include "v__entry.h" #include "v_query.h" #include "v__dataReader.h" #include "v__deliveryService.h" +#include "v_deliveryServiceEntry.h" #include "v__groupStream.h" #include "v__networkReader.h" -#include "v_entity.h" +#include "v__entity.h" #include "v_status.h" #include "v_public.h" #include "v__collection.h" #include "v_event.h" -#include "v_group.h" +#include "v__group.h" +#include "v_time.h" #include "v_proxy.h" #include "v_policy.h" #include "v_spliced.h" #include "v_durabilityClient.h" #include "v__partition.h" -#include "v_observable.h" +#include "v__observable.h" #include "v_historicalDataRequest.h" - #include "os_report.h" #include "vortex_os.h" @@ -52,31 +56,7 @@ #define _TRACE_EVENTS_(...) #endif -#define V_READER_LOCK(_this) v_observerLock(v_observer(_this)) -#define V_READER_UNLOCK(_this) v_observerUnlock(v_observer(_this)) -#define V_READER_GET_LOCK(_this) (v_observer(_this)->mutex) - -/************************************************************** - * Private functions - **************************************************************/ - -static c_bool -entryFree( - c_object o, - c_voidp arg) -{ - v_entry entry; - - OS_UNUSED_ARG(arg); - assert(o != NULL); - assert(arg == NULL); - - entry = v_entry(o); - assert(entry != NULL); - - v_entryFree(entry); - return TRUE; -} +#define V_READER_GET_LOCK(_this) (v_observable(_this)->mutex) /* This getHistoricalDataCommon function takes two optional parameters: * - the v_group parameter indicates the group from which to get the @@ -122,16 +102,12 @@ getHistoricalDataCommon( return result; } -/************************************************************** - * constructor/destructor - **************************************************************/ void v_readerInit( - v_reader r, - const c_char *name, - v_subscriber s, - v_readerQos qos, - c_bool enable) + _Inout_ v_reader r, + _In_z_ const c_char *name, + _In_ v_subscriber s, + _In_ v_readerQos qos) { v_kernel kernel; @@ -145,25 +121,15 @@ v_readerInit( */ kernel = v_objectKernel(r); - v_collectionInit(v_collection(r), name, enable); + v_collectionInit(v_collection(r), name); r->subscriber = s; r->qos = c_keep(qos); r->subQos = c_keep(s->qos); /* reference is readonly */ - r->entrySet.entries = c_setNew(v_kernelType(kernel,K_ENTRY)); - if (c_mutexInit(c_getBase(r), &r->entrySet.mutex) != SYNC_RESULT_SUCCESS) { - OS_REPORT(OS_ERROR, "v_readerInit", 0, - "Failed to initialize mutex for reader '%s'", name); - goto err_mutexInit; - } + r->entries = c_setNew(v_kernelType(kernel,K_ENTRY)); r->historicalDataRequest = NULL; r->historicalDataComplete = FALSE; - c_condInit(c_getBase(r), &r->historicalDataCondition, &(v_observer(r)->mutex)); - return; - -err_mutexInit: - c_free(r->entrySet.entries); - return; + c_condInit(c_getBase(r), &r->historicalDataCondition, &v_observable(r)->mutex); } void @@ -171,30 +137,36 @@ v_readerFree( v_reader r) { v_subscriber subscriber; + c_collection entries; + v_entry entry; assert(C_TYPECHECK(r,v_reader)); assert(r->subscriber != NULL); - V_READER_LOCK(r); + OSPL_LOCK(r); subscriber = r->subscriber; r->subscriber = NULL; - V_READER_UNLOCK(r); + OSPL_UNLOCK(r); - /* - * For each readerInstance in each entry, v_subscriberRemoveReader will + /* For each readerInstance in each entry, v_subscriberRemoveReader will * eventually deliver an UNREGISTER message to the Reader using * v_dataReaderEntryWrite, which on its turn locks the reader itself. * * For that reason, we don't do any locking here so that the entryFree * function is called without the readerLock being locked. - * - * Also see OSPL-3348 */ v_subscriberRemoveReader(subscriber,r); /* Free all entries */ - v_readerWalkEntries(r, entryFree, NULL); - + OSPL_LOCK(r); + entries = r->entries; + r->entries = NULL; + OSPL_UNLOCK(r); + while ((entry = v_entry(c_take(entries))) != NULL) { + v_entryFree(entry); + c_free(entry); + } + c_free(entries); /* Call inherited free */ v_collectionFree(v_collection(r)); } @@ -209,95 +181,72 @@ v_readerDeinit( v_collectionDeinit(v_collection(r)); } -/************************************************************** - * Protected functions - **************************************************************/ -c_bool -v_readerSubscribeGroup( - v_reader _this, - v_group group) +v_readerQos +v_readerGetQos( + v_reader _this) { - c_bool result; + v_readerQos qos; - assert(C_TYPECHECK(_this, v_reader)); - switch(v_objectKind(_this)) { - case K_DATAREADER: - /* ES, dds1576: For the K_DATAREADER object we need to verify if - * the access rights are correct. No subscriptions may be made onto - * groups which have a v_accessMode of write only. - */ - if(v_groupPartitionAccessMode(group) == V_ACCESS_MODE_READ_WRITE || - v_groupPartitionAccessMode(group) == V_ACCESS_MODE_READ) - { - result = v_dataReaderSubscribeGroup(v_dataReader(_this), group); - } else - { - result = FALSE; - } - break; - case K_GROUPQUEUE: - result = v_groupStreamSubscribeGroup(v_groupStream(_this), group); - break; - case K_NETWORKREADER: - result = FALSE; - (void)result; - assert(FALSE); - break; - default: - OS_REPORT(OS_CRITICAL,"v_readerSubscribeGroup failed",V_RESULT_ILL_PARAM, - "illegal reader kind (%d) specified", - v_objectKind(_this)); - result = FALSE; - (void)result; - assert(FALSE); - } - return result; -} + assert(C_TYPECHECK(_this,v_reader)); + + OSPL_LOCK(_this); + qos = c_keep(_this->qos); + OSPL_UNLOCK(_this); + return qos; +} -c_bool -v_readerUnSubscribeGroup( - v_reader reader, - v_group group) +static c_bool +groupGetOpenTransactions( + c_object o, + c_voidp arg) { - c_bool result; - - assert(C_TYPECHECK(reader, v_reader)); + v_group g = v_group(o); + v_entry e = v_entry(arg); + /* Do not get the open transactions from the groupAdmin as the reader + * missed those completely. Only get the open transactions form the + * transactionAdmin as those could still be received and completed. + */ + v_groupGetOpenTransactions(g,e,FALSE); + return TRUE; +} - switch(v_objectKind(reader)) { - case K_DATAREADER: - result = v_dataReaderUnSubscribeGroup(v_dataReader(reader), group); - break; - case K_GROUPQUEUE: - result = v_groupStreamUnSubscribeGroup(v_groupStream(reader), group); - break; - case K_NETWORKREADER: - result = v_networkReaderUnSubscribeGroup(v_networkReader(reader), group); - break; - default: - OS_REPORT(OS_CRITICAL,"v_readerUnSubscribeGroup failed",V_RESULT_ILL_PARAM, - "illegal reader kind (%d) specified", - v_objectKind(reader)); - assert(FALSE); - result = FALSE; +static c_bool +entryGetOpenTransactions( + c_object o, + c_voidp arg) +{ + v_entry e = v_entry(o); + OS_UNUSED_ARG(arg); + if (v_objectKind(e) != K_NETWORKREADERENTRY) { + v_entryWalkGroups(e, groupGetOpenTransactions, e); } - - return result; + return TRUE; } -v_readerQos -v_readerGetQos( +void +v_readerPublishBuiltinInfo( v_reader _this) { - v_readerQos qos; + v_kernel kernel; + v_message builtinMsg, builtinCMMsg; + assert(_this != NULL); assert(C_TYPECHECK(_this,v_reader)); - V_READER_LOCK(_this); - qos = c_keep(_this->qos); - V_READER_UNLOCK(_this); - - return qos; + if (v_entityEnabled(v_entity(_this))) { + kernel = v_objectKernel(_this); + builtinMsg = v_builtinCreateSubscriptionInfo(kernel->builtin, _this); + if (builtinMsg) { + v_writeBuiltinTopic(kernel, V_SUBSCRIPTIONINFO_ID, builtinMsg); + c_free(builtinMsg); + } + builtinCMMsg = v_builtinCreateCMDataReaderInfo(kernel->builtin, _this); + if (builtinCMMsg) { + v_writeBuiltinTopic(kernel, V_CMDATAREADERINFO_ID, builtinCMMsg); + c_free(builtinCMMsg); + } + } } v_result @@ -317,17 +266,21 @@ v_readerSetQos( if (result == V_RESULT_OK) { qos = v_readerQosNew(kernel, tmpl); if (qos != NULL) { - V_READER_LOCK(_this); - result = v_readerQosCompare(_this->qos, qos, v_entityEnabled(v_entity(_this)), &cm); + OSPL_LOCK(_this); + result = v_readerQosCompare(_this->qos, qos, v__entityEnabled_nl(v_entity(_this)), + v_subscriberQosIsGroupCoherent(_this->subQos), &cm); if ((result == V_RESULT_OK) && (cm != 0)) { c_free(_this->qos); _this->qos = c_keep(qos); - V_READER_UNLOCK(_this); - if (v_objectKind(_this) == K_DATAREADER) { - v_dataReaderNotifyChangedQos(v_dataReader(_this)); - } + OSPL_UNLOCK(_this); + v_readerPublishBuiltinInfo(_this); + /* On change of qos try to get all open transactions from the + * group, so that the group is able to determine completeness + * of the transaction. + */ + (void)c_setWalk(_this->entries, entryGetOpenTransactions, NULL); } else { - V_READER_UNLOCK(_this); + OSPL_UNLOCK(_this); } c_free(qos); } else { @@ -338,19 +291,30 @@ v_readerSetQos( } c_bool -v_readerWalkEntries( +v_readerWalkEntries_nl( v_reader r, c_action action, c_voidp arg) { - c_bool result; + c_bool result = TRUE; assert(C_TYPECHECK(r,v_reader)); + result = c_setWalk(r->entries, action, arg); + return result; +} - v_readerEntrySetLock(r); - result = c_setWalk(r->entrySet.entries, action, arg); - v_readerEntrySetUnlock(r); +c_bool +v_readerWalkEntries( + v_reader r, + c_action action, + c_voidp arg) +{ + c_bool result = TRUE; + assert(C_TYPECHECK(r,v_reader)); + OSPL_LOCK(r); + result = c_setWalk(r->entries, action, arg); + OSPL_UNLOCK(r); return result; } @@ -358,158 +322,55 @@ c_iter v_readerCollectEntries( v_reader r) { - c_iter result; + c_iter result = NULL; assert(C_TYPECHECK(r,v_reader)); if(r){ - v_readerEntrySetLock(r); - result = ospl_c_select(r->entrySet.entries, 0); - v_readerEntrySetUnlock(r); - } else { - result = NULL; + OSPL_LOCK(r); + result = ospl_c_select(r->entries, 0); + OSPL_UNLOCK(r); } return result; } -v_entry +void v_readerAddEntry( - v_reader r, - v_entry e) + _Inout_ v_reader r, + _In_ v_entry e) { - v_entry found; - assert(C_TYPECHECK(r,v_reader)); assert(C_TYPECHECK(e,v_entry)); - v_readerEntrySetLock(r); - found = c_setInsert(r->entrySet.entries, e); - v_readerEntrySetUnlock(r); - - return c_keep(found); -} - -v_entry -v_readerRemoveEntry( - v_reader r, - v_entry e) -{ - v_entry found; - - assert(C_TYPECHECK(r,v_reader)); - - v_readerEntrySetLock(r); - found = c_keep(c_remove(r->entrySet.entries, e, NULL, NULL)); - v_readerEntrySetUnlock(r); - - return found; -} - -/************************************************************** - * Public functions - **************************************************************/ -v_result -v_readerSubscribe( - v_reader r, - v_partition d) -{ - v_result result = V_RESULT_INTERNAL_ERROR; - - assert(C_TYPECHECK(r,v_reader)); - - switch(v_objectKind(r)) { - case K_DATAREADER: - if (v_dataReaderSubscribe(v_dataReader(r),d)) { - result = V_RESULT_OK; - } - break; - case K_DELIVERYSERVICE: - if (v_deliveryServiceSubscribe(v_deliveryService(r),d)) { - result = V_RESULT_OK; - } - break; - case K_GROUPQUEUE: - if (v_groupStreamSubscribe(v_groupStream(r),d)) { - result = V_RESULT_OK; - } - break; - case K_NETWORKREADER: - (void)result; - assert(FALSE); - break; - default: - OS_REPORT(OS_CRITICAL,"v_readerSubscribe failed",V_RESULT_ILL_PARAM, - "illegal reader kind (%d) specified", - v_objectKind(r)); - result = V_RESULT_ILL_PARAM; - (void)result; - assert(FALSE); - break; - } - - return result; + OSPL_LOCK(r); + (void)c_setInsert(r->entries, e); + /* c_setInsert will ALWAYS return e. If it was already in and if it wasn't. + * In both cases it is in the set afterwards */ + OSPL_UNLOCK(r); } -c_bool -v_readerUnSubscribe( - v_reader r, - v_partition d) +static c_bool +readerEntryAddTransactionAdmin( + _Inout_ c_object o, + _Inout_opt_ c_voidp arg) { - assert(C_TYPECHECK(r,v_reader)); - - switch(v_objectKind(r)) { - case K_DATAREADER: - return v_dataReaderUnSubscribe(v_dataReader(r),d); - case K_DELIVERYSERVICE: - return v_deliveryServiceUnSubscribe(v_deliveryService(r),d); - case K_GROUPQUEUE: - return v_groupStreamUnSubscribe(v_groupStream(r),d); - case K_NETWORKREADER: - return v_networkReaderUnSubscribe(v_networkReader(r),d); - default: - OS_REPORT(OS_CRITICAL,"v_readerUnSubscribe failed",V_RESULT_ILL_PARAM, - "illegal reader kind (%d) specified", - v_objectKind(r)); - assert(FALSE); - } + assert(C_TYPECHECK(o, v_dataReaderEntry)); - return TRUE; -} + v_dataReaderEntrySetTransactionAdmin(v_dataReaderEntry(o), arg); -static c_bool -collectEntries( - c_object o, - c_voidp arg) -{ - c_iter *list = (c_iter *)arg; - *list = c_iterAppend(*list, c_keep(o)); return TRUE; } -v_result -v_readerGetHistoricalData( - v_reader _this) +void +v_readerAddTransactionAdmin( + _Inout_ v_reader r, + _In_opt_ v_transactionGroupAdmin a) { - c_iter list = NULL; - c_object o; - v_result result; - - assert(_this != NULL); - assert(C_TYPECHECK(_this,v_reader)); + assert(a == NULL || v__readerIsGroupCoherent(r)); - result = V_RESULT_PRECONDITION_NOT_MET; - if (_this != NULL) { - result = V_RESULT_OK; - if (_this->qos->durability.v.kind != V_DURABILITY_VOLATILE) { - (void)v_readerWalkEntries(_this, collectEntries, &list); - while (((o = c_iterTakeFirst(list)) != NULL) && (result == V_RESULT_OK)) { - result = getHistoricalDataCommon(o, NULL, FALSE); - c_free(o); - } - c_iterFree(list); - } - } - return result; + OSPL_LOCK(r); + (void)c_setWalk(r->entries, &readerEntryAddTransactionAdmin, a); + OSPL_UNLOCK(r); } v_result @@ -527,7 +388,7 @@ v_readerGetDeadlineMissedStatus( result = V_RESULT_PRECONDITION_NOT_MET; if (_this != NULL) { - V_READER_LOCK(_this); + OSPL_LOCK(_this); status = v_entity(_this)->status; result = action(&v_readerStatus(status)->deadlineMissed, arg); if (reset) { @@ -536,7 +397,7 @@ _TRACE_EVENTS_("v_readerGetDeadlineMissedStatus::v_statusReset(0x%x, 0x%x) reade status, V_EVENT_REQUESTED_DEADLINE_MISSED, _this); } v_readerStatus(status)->deadlineMissed.totalChanged = 0; - V_READER_UNLOCK(_this); + OSPL_UNLOCK(_this); } return result; } @@ -557,7 +418,7 @@ v_readerGetIncompatibleQosStatus( result = V_RESULT_PRECONDITION_NOT_MET; if (_this != NULL) { - V_READER_LOCK(_this); + OSPL_LOCK(_this); status = v_entity(_this)->status; result = action(&v_readerStatus(status)->incompatibleQos, arg); if (reset) { @@ -569,7 +430,7 @@ _TRACE_EVENTS_("v_readerGetDeadlineMissedStatus::v_statusReset(0x%x, 0x%x) reade for (i=0; iincompatibleQos.policyCount[i] = 0; } - V_READER_UNLOCK(_this); + OSPL_UNLOCK(_this); } return result; } @@ -589,7 +450,7 @@ v_readerGetSampleRejectedStatus( result = V_RESULT_PRECONDITION_NOT_MET; if (_this != NULL) { - V_READER_LOCK(_this); + OSPL_LOCK(_this); status = v_entity(_this)->status; result = action(&v_readerStatus(status)->sampleRejected, arg); if (reset) { @@ -598,7 +459,7 @@ _TRACE_EVENTS_("v_readerGetDeadlineMissedStatus::v_statusReset(0x%x, 0x%x) reade status, V_EVENT_SAMPLE_REJECTED, _this); } v_readerStatus(status)->sampleRejected.totalChanged = 0; - V_READER_UNLOCK(_this); + OSPL_UNLOCK(_this); } return result; } @@ -618,7 +479,7 @@ v_readerGetSampleLostStatus( result = V_RESULT_PRECONDITION_NOT_MET; if (_this != NULL) { - V_READER_LOCK(_this); + OSPL_LOCK(_this); status = v_entity(_this)->status; result = action(&v_readerStatus(status)->sampleLost, arg); if (reset) { @@ -627,7 +488,7 @@ _TRACE_EVENTS_("v_readerGetDeadlineMissedStatus::v_statusReset(0x%x, 0x%x) reade status, V_EVENT_SAMPLE_LOST, _this); } v_readerStatus(status)->sampleLost.totalChanged = 0; - V_READER_UNLOCK(_this); + OSPL_UNLOCK(_this); } return result; } @@ -647,7 +508,7 @@ v_readerGetLivelinessChangedStatus( result = V_RESULT_PRECONDITION_NOT_MET; if (_this != NULL) { - V_READER_LOCK(_this); + OSPL_LOCK(_this); status = v_entity(_this)->status; result = action(&v_readerStatus(status)->livelinessChanged, arg); if (reset) { @@ -657,7 +518,7 @@ _TRACE_EVENTS_("v_readerGetDeadlineMissedStatus::v_statusReset(0x%x, 0x%x) reade } v_readerStatus(status)->livelinessChanged.activeChanged = 0; v_readerStatus(status)->livelinessChanged.inactiveChanged = 0; - V_READER_UNLOCK(_this); + OSPL_UNLOCK(_this); } return result; } @@ -677,7 +538,7 @@ v_readerGetSubscriptionMatchedStatus( result = V_RESULT_PRECONDITION_NOT_MET; if (_this != NULL) { - V_READER_LOCK(_this); + OSPL_LOCK(_this); status = v_entity(_this)->status; result = action(&v_readerStatus(status)->subscriptionMatch, arg); if (reset) { @@ -685,7 +546,7 @@ v_readerGetSubscriptionMatchedStatus( } v_readerStatus(status)->subscriptionMatch.totalChanged = 0; v_readerStatus(status)->subscriptionMatch.currentChanged = 0; - V_READER_UNLOCK(_this); + OSPL_UNLOCK(_this); } return result; } @@ -697,7 +558,8 @@ waitForHistoricalData( { v_result result = V_RESULT_OK; os_timeM starttime = os_timeMGet(); - V_READER_LOCK(_this); + OSPL_LOCK(_this); + while (!_this->historicalDataComplete && result == V_RESULT_OK && timeout > OS_DURATION_ZERO) { if (v_condWait(&_this->historicalDataCondition, &V_READER_GET_LOCK(_this), timeout) != V_RESULT_OK) { @@ -705,7 +567,7 @@ waitForHistoricalData( } timeout -= os_timeMDiff(os_timeMGet(), starttime); } - V_READER_UNLOCK(_this); + OSPL_UNLOCK(_this); return result; } @@ -726,8 +588,6 @@ v_readerDurableDataRequest( v_service durability_service = NULL; c_bool conditional; - kernel = v_objectKernel(_this); - /* Determine if a subset of durable data is requested. */ conditional = (filter || params || !OS_TIMEW_ISINVALID(minSourceTime) || !OS_TIMEW_ISINVALID(maxSourceTime) || @@ -739,9 +599,11 @@ v_readerDurableDataRequest( * non-volatile readers will automatically be aligned, so therefore * return precondition not met when requesting conditional alignment on non-volatile readers. */ - if (conditional && _this->qos->durability.v.kind > V_DURABILITY_TRANSIENT_LOCAL) { + if (conditional && _this->qos->durability.v.kind > V_DURABILITY_VOLATILE) { return V_RESULT_PRECONDITION_NOT_MET; } + + kernel = v_objectKernel(_this); /* Lookup the Durability Service */ services = v_resolveServiceByServiceType(kernel, V_SERVICETYPE_DURABILITY); assert(c_iterLength(services) <= 1); @@ -753,7 +615,9 @@ v_readerDurableDataRequest( durability_client = c_iterTakeFirst(services); c_iterFree(services); - /* Send a Request for durable data if a durable data source exists. */ + /* Send a Request for durable data if a durable data source exists, or if no networking services configured, + * in which case the explicit request of historical data for a volatile reader can still be done. + */ if (durability_service || durability_client) { v_historicalDataRequest request; V_DC_TRACE("%s - request historical data for reader %s\n", OS_FUNCTION, v_entityName(_this)); @@ -762,6 +626,7 @@ v_readerDurableDataRequest( minSourceTime, maxSourceTime, limits, OS_DURATION_ZERO); if (request != NULL) { + OSPL_LOCK(_this); if (_this->historicalDataRequest) { /* Historical data request already in progress or complete, check * whether request is equal to the original one. @@ -770,20 +635,23 @@ v_readerDurableDataRequest( /* Request is NOT equal to original request*/ result = V_RESULT_PRECONDITION_NOT_MET; } + OSPL_UNLOCK(_this); } else { C_STRUCT(v_event) event; + c_bool notDurable = (_this->qos->durability.v.kind == V_DURABILITY_VOLATILE); _this->historicalDataRequest = c_keep(request); + OSPL_UNLOCK(_this); /* Volatile readers don't automatically receive non-volatile data, * therefore for each entry copy the data from the associated groups into * the reader. */ - if (_this->qos->durability.v.kind == V_DURABILITY_VOLATILE) { + if (notDurable) { c_iter entries; v_entry e; - v_readerEntrySetLock(_this); - entries = ospl_c_select(_this->entrySet.entries, 0); - v_readerEntrySetUnlock(_this); + OSPL_LOCK(_this); + entries = ospl_c_select(_this->entries, 0); + OSPL_UNLOCK(_this); while ((e = (v_entry)c_iterTakeFirst(entries)) != NULL) { if (result == V_RESULT_OK) { if (conditional) { @@ -802,13 +670,14 @@ v_readerDurableDataRequest( event.kind = V_EVENT_HISTORY_REQUEST; event.source = v_observable (_this); event.data = request; + event.handled = TRUE; if (durability_service) { /* Trigger and request the durability service to provide historical data */ - v_observableNotify(v_observable(durability_service),&event); + OSPL_THROW_EVENT(durability_service, &event); } if (durability_client) { /* Trigger the durability client to send a historical data request */ - v_observableNotify(v_observable(durability_client),&event); + OSPL_THROW_EVENT(durability_client, &event); } } c_free(request); @@ -867,41 +736,44 @@ checkParameters( static v_result v_readerCheckDurableDataSupport( - v_reader _this) + _In_ _Const_ v_reader _this) { + v_kernel kernel = v_objectKernel(_this); v_result result = V_RESULT_OK; - if (!v_kernelGetDurabilitySupport(v_objectKernel(_this))) { + if (!v_kernelGetDurabilitySupport(kernel)) { result = V_RESULT_PRECONDITION_NOT_MET; } return result; } +static c_bool DurableGroupCount(c_object o, c_voidp arg) +{ + v_entry e = v_entry(o); + c_long *count = (c_long *)arg; + *count += v_entryDurableGroupCount(e); + return TRUE; +} + static c_long v_readerDurableGroupCount( v_reader _this) { - c_iter entries; - v_entry e; c_long count = 0; - - v_readerEntrySetLock(_this); - entries = ospl_c_select(_this->entrySet.entries, 0); - v_readerEntrySetUnlock(_this); - while ((e = (v_entry)c_iterTakeFirst(entries)) != NULL) { - count += v_entryDurableGroupCount(e); - c_free(e); - } + OSPL_LOCK(_this); + (void)c_setWalk(_this->entries, DurableGroupCount, &count); + OSPL_UNLOCK(_this); return count; } v_result v_readerWaitForHistoricalData( v_reader r, - os_duration timeout) + os_duration timeout, + c_bool enabling) { return v_readerWaitForHistoricalDataWithCondition(r, NULL, NULL, 0, OS_TIMEW_INVALID, OS_TIMEW_INVALID, - -1, -1, -1, timeout); + -1, -1, -1, timeout, enabling); } v_result @@ -915,11 +787,19 @@ v_readerWaitForHistoricalDataWithCondition( c_long max_samples, c_long max_instances, c_long max_samples_per_instance, - os_duration timeout) + os_duration timeout, + c_bool enabling) { v_result result = V_RESULT_OK; v_resourcePolicyI limits; + /* Check enabled status only if not currently being enabled via v_dataReaderEnable() */ + if (!enabling) { + if(!v_entityEnabled(v_entity(_this))) { + return V_RESULT_NOT_ENABLED; + } + } + limits.v.max_samples = max_samples; limits.v.max_instances = max_instances; limits.v.max_samples_per_instance = max_samples_per_instance; @@ -953,33 +833,30 @@ v_readerWaitForHistoricalDataWithCondition( return result; } +/* Precondition: reader is locked */ void -v_readerNotifyStateChange( +v__readerNotifyStateChange_nl( v_reader _this, c_bool complete) { - assert(C_TYPECHECK(_this, v_reader)); - - if(_this){ - V_READER_LOCK(_this); - if (_this->historicalDataComplete != complete) { - _this->historicalDataComplete = complete; - c_condBroadcast(&_this->historicalDataCondition); - } - V_READER_UNLOCK(_this); + if (_this->historicalDataComplete != complete) { + _this->historicalDataComplete = complete; + c_condBroadcast(&_this->historicalDataCondition); } - return; } -c_bool -v_readerIsAligned( - v_reader _this) +void +v_readerNotifyStateChange( + v_reader _this, + c_bool complete) { - c_bool isAligned = FALSE; - if (_this) { - isAligned = _this->historicalDataComplete; + assert(C_TYPECHECK(_this, v_reader)); + + if(_this){ + OSPL_LOCK(_this); + v__readerNotifyStateChange_nl(_this, complete); + OSPL_UNLOCK(_this); } - return isAligned; } c_iter @@ -987,14 +864,92 @@ v_readerGetPartitions( v_reader _this) { c_iter partitions = NULL; + v_subscriber s; if (_this) { - V_READER_LOCK(_this); - if (_this->subscriber) { - partitions = v_subscriberLookupPartitions(_this->subscriber, "*"); + OSPL_LOCK(_this); + s = c_keep(_this->subscriber); + OSPL_UNLOCK(_this); + if (s) { + partitions = v_subscriberLookupPartitions(s, "*"); } - V_READER_UNLOCK(_this); + c_free(s); } return partitions; } + +static c_bool +getTopic ( + c_object o, + c_voidp arg) +{ + v_topic *topic = (v_topic *)arg; + c_bool result = TRUE; + + switch (v_objectKind(o)) { + case K_DATAREADERENTRY: + { + v_dataReaderEntry entry = v_dataReaderEntry(o); + if (*topic == NULL) { + *topic = c_keep(entry->topic); + } else { + /* Already a topic was found so this must be a Multi Topic reader. + * In that case abort and clear the topic. + */ + c_free(*topic); + *topic = NULL; + result = FALSE; + } + } + break; + case K_DELIVERYSERVICEENTRY: + { + v_deliveryServiceEntry entry = v_deliveryServiceEntry(o); + *topic = c_keep(entry->topic); + } + break; + default: + break; + } + return result; +} + +v_topic +v_readerGetTopic_nl( + v_reader _this) +{ + v_topic topic = NULL; + + switch (v_objectKind(_this)) { + case K_DATAREADER: + case K_DELIVERYSERVICE: + (void)v_readerWalkEntries_nl(_this, getTopic, &topic); + break; + default: + break; + } + return topic; +} + +v_topic +v_readerGetTopic( + v_reader _this) +{ + v_topic topic = NULL; + OSPL_LOCK(_this); + topic = v_readerGetTopic_nl(_this); + OSPL_UNLOCK(_this); + return topic; +} + +v_subscriber +v_readerGetSubscriber( + v_reader _this) +{ + v_subscriber s; + OSPL_LOCK(_this); + s = c_keep(_this->subscriber); + OSPL_UNLOCK(_this); + return s; +} diff --git a/src/kernel/code/v_readerQos.c b/src/kernel/code/v_readerQos.c index 929684577..9285a9258 100644 --- a/src/kernel/code/v_readerQos.c +++ b/src/kernel/code/v_readerQos.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,6 +21,7 @@ #include "v__readerQos.h" +#include "v__subscriberQos.h" #include "v_qos.h" #include "v_kernel.h" #include "v_policy.h" @@ -38,9 +40,6 @@ static const v_qosChangeMask immutableMask = V_POLICY_BIT_OWNERSHIP | V_POLICY_BIT_RESOURCE; -/************************************************************** - * private functions - **************************************************************/ static c_bool v_readerQosValidValues( v_readerQos qos) @@ -104,9 +103,6 @@ v_readerQosConsistent( return result; } -/************************************************************** - * constructor/destructor - **************************************************************/ v_readerQos v_readerQosNew( v_kernel kernel, @@ -206,74 +202,85 @@ v_readerQosFree( c_free(q); } -/************************************************************** - * Protected functions - **************************************************************/ +_Success_(return == V_RESULT_OK) v_result v_readerQosCompare( - v_readerQos q, - v_readerQos tmpl, - c_bool enabled, - v_qosChangeMask *changeMask) + _In_ v_readerQos q, + _In_ v_readerQos tmpl, + _In_ c_bool enabled, + _In_ c_bool groupCoherent, + _Out_ v_qosChangeMask *changeMask) { - v_qosChangeMask cm; + v_qosChangeMask cm, immutable; v_result result; cm = 0; - if ((q != NULL) && (tmpl != NULL) && (changeMask != NULL)) { - if (v_readerQosValidValues(tmpl)) { - if (v_readerQosConsistent(tmpl)) { - /* built change mask */ + immutable = immutableMask; + if(enabled && groupCoherent) { + /* A group-coherent reader cannot be changed at all after it has + * been enabled. + */ + immutable |= V_POLICY_BIT_DURABILITY; + immutable |= V_POLICY_BIT_DEADLINE; + immutable |= V_POLICY_BIT_LATENCY; + immutable |= V_POLICY_BIT_LIVELINESS; + immutable |= V_POLICY_BIT_RELIABILITY; + immutable |= V_POLICY_BIT_ORDERBY; + immutable |= V_POLICY_BIT_HISTORY; + immutable |= V_POLICY_BIT_RESOURCE; + immutable |= V_POLICY_BIT_USERDATA; + immutable |= V_POLICY_BIT_OWNERSHIP; + immutable |= V_POLICY_BIT_PACING; + immutable |= V_POLICY_BIT_READERLIFECYCLE; + immutable |= V_POLICY_BIT_READERLIFESPAN; + immutable |= V_POLICY_BIT_SHARE; + immutable |= V_POLICY_BIT_USERKEY; + } + + if (v_readerQosValidValues(tmpl)) { + if (v_readerQosConsistent(tmpl)) { + /* built change mask */ #define _SETMASK_(type,qos,label) if (!v_##type##PolicyIEqual(q->qos, tmpl->qos)) { cm |= V_POLICY_BIT_##label; } - _SETMASK_(durability,durability,DURABILITY) - _SETMASK_(deadline,deadline,DEADLINE) - _SETMASK_(latency,latency,LATENCY) - _SETMASK_(liveliness,liveliness,LIVELINESS) - _SETMASK_(reliability,reliability,RELIABILITY) - _SETMASK_(orderby,orderby,ORDERBY) - _SETMASK_(history,history,HISTORY) - _SETMASK_(resource,resource,RESOURCE) - _SETMASK_(userData,userData,USERDATA) - _SETMASK_(ownership, ownership, OWNERSHIP); - _SETMASK_(pacing,pacing,PACING) - _SETMASK_(readerLifecycle,lifecycle,READERLIFECYCLE) - _SETMASK_(readerLifespan,lifespan,READERLIFESPAN) - _SETMASK_(share,share,SHARE) - _SETMASK_(userKey,userKey,USERKEY) + _SETMASK_(durability,durability,DURABILITY) + _SETMASK_(deadline,deadline,DEADLINE) + _SETMASK_(latency,latency,LATENCY) + _SETMASK_(liveliness,liveliness,LIVELINESS) + _SETMASK_(reliability,reliability,RELIABILITY) + _SETMASK_(orderby,orderby,ORDERBY) + _SETMASK_(history,history,HISTORY) + _SETMASK_(resource,resource,RESOURCE) + _SETMASK_(userData,userData,USERDATA) + _SETMASK_(ownership, ownership, OWNERSHIP); + _SETMASK_(pacing,pacing,PACING) + _SETMASK_(readerLifecycle,lifecycle,READERLIFECYCLE) + _SETMASK_(readerLifespan,lifespan,READERLIFESPAN) + _SETMASK_(share,share,SHARE) + _SETMASK_(userKey,userKey,USERKEY) #undef _SETMASK_ - /* check whether immutable policies are changed */ - if (((cm & immutableMask) != 0) && (enabled)) { - v_policyReportImmutable(cm, immutableMask); - result = V_RESULT_IMMUTABLE_POLICY; - OS_REPORT(OS_ERROR, "v_readerQosCompare", result, - "Precondition not met: Immutable Qos policy violation"); - } else { - *changeMask = cm; - result = V_RESULT_OK; - } - } else { - result = V_RESULT_INCONSISTENT_QOS; + /* check whether immutable policies are changed */ + if (((cm & immutable) != 0) && (enabled)) { + v_policyReportImmutable(cm, immutable); + result = V_RESULT_IMMUTABLE_POLICY; OS_REPORT(OS_ERROR, "v_readerQosCompare", result, - "Precondition not met: Detected Inconsistent Qos policy"); + "Precondition not met: Immutable Qos policy violation"); + } else { + *changeMask = cm; + result = V_RESULT_OK; } } else { - result = V_RESULT_ILL_PARAM; + result = V_RESULT_INCONSISTENT_QOS; OS_REPORT(OS_ERROR, "v_readerQosCompare", result, - "Bad parameter: Detected Invalid Qos policy"); + "Precondition not met: Detected Inconsistent Qos policy"); } } else { result = V_RESULT_ILL_PARAM; OS_REPORT(OS_ERROR, "v_readerQosCompare", result, - "Bad parameter: Qos1 = 0x%"PA_PRIxADDR", Qos2 = 0x%"PA_PRIxADDR", changeMask holder = 0x%"PA_PRIxADDR"", - (os_address)q, (os_address)tmpl, (os_address)changeMask); + "Bad parameter: Detected Invalid Qos policy"); } return result; } -/************************************************************** - * Public functions - **************************************************************/ v_result v_readerQosCheck( v_readerQos _this) diff --git a/src/kernel/code/v_rnr.c b/src/kernel/code/v_rnr.c index ad5eab969..3016fa10b 100644 --- a/src/kernel/code/v_rnr.c +++ b/src/kernel/code/v_rnr.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,6 +25,7 @@ #include "v_participant.h" #include "v_statistics.h" #include "v_rnrStatistics.h" +#include "v__observable.h" #include "os_report.h" @@ -52,11 +54,14 @@ v_rnrNew( v_serviceInit(v_service(_this), name, extStateName, V_SERVICETYPE_RECORD_REPLAY, q, enable); c_free(q); /* always add, even when s->state==NULL, since v_participantFree always - removes the participant.*/ + * removes the participant. + */ v_addParticipant(kernel, v_participant(_this)); if (v_service(_this)->state == NULL) { v_serviceFree(v_service(_this)); _this = NULL; + } else { + OSPL_ADD_OBSERVER(kernel, _this, V_EVENT_NEW_GROUP, NULL); } } return _this; diff --git a/src/kernel/code/v_rnrGroupStatistics.c b/src/kernel/code/v_rnrGroupStatistics.c index 8907515f5..b36db4f68 100644 --- a/src/kernel/code/v_rnrGroupStatistics.c +++ b/src/kernel/code/v_rnrGroupStatistics.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/code/v_rnrStatistics.c b/src/kernel/code/v_rnrStatistics.c index 300dd108b..aa01e38df 100644 --- a/src/kernel/code/v_rnrStatistics.c +++ b/src/kernel/code/v_rnrStatistics.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/code/v_rnrStorageStatistics.c b/src/kernel/code/v_rnrStorageStatistics.c index e2d51d368..60c8acbea 100644 --- a/src/kernel/code/v_rnrStorageStatistics.c +++ b/src/kernel/code/v_rnrStorageStatistics.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/code/v_scheduler.c b/src/kernel/code/v_scheduler.c index c0255e00d..ebbd51b56 100644 --- a/src/kernel/code/v_scheduler.c +++ b/src/kernel/code/v_scheduler.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/code/v_service.c b/src/kernel/code/v_service.c index 939d18d7d..91c4b5d04 100644 --- a/src/kernel/code/v_service.c +++ b/src/kernel/code/v_service.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -40,33 +41,6 @@ #define VSERVICESTATE_NAME "kernelModuleI::v_serviceState" #define VSERVICESTATE_NAME_LENGTH 14 -/************************************************************** - * private functions - **************************************************************/ - -static void -addAllGroups( - c_set newGroups, - v_groupSet groupSet) -{ - c_iter groups = NULL; - v_group g; - - assert(C_TYPECHECK(groupSet, v_groupSet)); - - groups = v_groupSetSelectAll(groupSet); - g = v_group(c_iterTakeFirst(groups)); - while (g != NULL) { - ospl_c_insert(newGroups, g); - c_free(g); - g = v_group(c_iterTakeFirst(groups)); - } - c_iterFree(groups); -} - -/************************************************************** - * constructor/destructor - **************************************************************/ v_service v_serviceNew( v_kernel kernel, @@ -127,11 +101,16 @@ v_serviceInit( manager = v_getServiceManager(kernel); /* v_participantInit writes the DCPSParticipant and CMParticipant topics, but - it downcasts to v_service to extract serviceType, and hence needs it available. */ + * it downcasts to v_service to extract serviceType, and hence needs it available. + */ service->serviceType = serviceType; - v_participantInit(v_participant(service), name, qos, enable); + v_participantInit(v_participant(service), name, qos); + if(enable) { + (void)v_entityEnable(v_entity(service)); + } service->state = v_serviceManagerRegister(manager, service, extStateName); service->lease = v_leaseMonotonicNew(kernel, lp); + service->newGroups = NULL; if(service->lease) { v_result result; @@ -198,7 +177,7 @@ v_serviceInit( if (strcmp(name, V_SPLICED_NAME) != 0) { v_serviceState splicedState; splicedState = v_serviceManagerGetServiceState(manager, V_SPLICED_NAME); - (void)v_observableAddObserver(v_observable(splicedState), v_observer(service), NULL); + (void)OSPL_ADD_OBSERVER(splicedState, service, V_EVENT_SERVICESTATE_CHANGED, NULL); } } else { OS_REPORT(OS_ERROR, "v_service", @@ -231,9 +210,6 @@ v_serviceDeinit( v_participantDeinit(v_participant(service)); } -/************************************************************** - * Protected functions - **************************************************************/ void v_serviceNotify( v_service service, @@ -242,21 +218,16 @@ v_serviceNotify( { assert(service != NULL); assert(C_TYPECHECK(service, v_service)); + assert(event != NULL); - if (event != NULL) { - if (event->kind == V_EVENT_NEW_GROUP) { - if ((event->data) && (v_observer(service)->eventData)) { - ospl_c_insert((c_set)v_observer(service)->eventData, event->data); - } + if (event->kind == V_EVENT_NEW_GROUP) { + if (event->data && service->newGroups) { + ospl_c_insert(service->newGroups, event->data); } - v_observableNotify(v_observable(service), event); } v_participantNotify(v_participant(service), event, userData); } -/************************************************************** - * Public functions - **************************************************************/ const c_char * v_serviceGetName( v_service service) @@ -320,6 +291,17 @@ v_serviceChangeState( return result; } +v_serviceStateKind +v_serviceGetState( + v_service service) +{ + assert(service != NULL); + assert(C_TYPECHECK(service, v_service)); + assert(service->state != NULL); + + return v_serviceStateGetKind(service->state); +} + void v_serviceFillNewGroups( v_service service) @@ -328,6 +310,7 @@ v_serviceFillNewGroups( C_STRUCT(v_event) ge; v_group g; v_kernel kernel; + c_iter groups = NULL; assert(service != NULL); assert(C_TYPECHECK(service, v_service)); @@ -336,19 +319,32 @@ v_serviceFillNewGroups( newGroups = (c_voidp)c_setNew(v_kernelType(kernel, K_GROUP)); if (newGroups != NULL) { - v_observerLock(v_observer(service)); - addAllGroups(newGroups, kernel->groupSet); - g = v_group(c_read(newGroups)); /* need a group for the event */ - /* just for safety, when assertion are compiled out, free the prev set */ - c_free((c_object)v_observer(service)->eventData); - v_observer(service)->eventData = (c_voidp)newGroups; - - ge.kind = V_EVENT_NEW_GROUP; - ge.source = v_observable(kernel); - ge.data = g; - v_observerNotify(v_observer(service), &ge, NULL); - v_observerUnlock(v_observer(service)); - c_free(g); + groups = v_groupSetSelectAll(kernel->groupSet); + + /* Take the first group and at the end notify the service about this new group. + * But before push all other groups to the servive newGroup set so that only one trigger + * is required to notify all groups. + * The first group is automatically added to the newGroup set by the notification. + * TODO : get rid of this mechanism. + */ + ge.data = v_group(c_iterTakeFirst(groups)); + if (ge.data) { + ge.kind = V_EVENT_NEW_GROUP; + ge.source = v_observable(kernel); + ospl_c_insert(newGroups, ge.data); + while ((g = v_group(c_iterTakeFirst(groups))) != NULL) { + ospl_c_insert(newGroups, g); + c_free(g); + } + + OSPL_BLOCK_EVENTS(service); + c_free(service->newGroups); + service->newGroups = (c_voidp)newGroups; + OSPL_UNBLOCK_EVENTS(service); + + OSPL_TRIGGER_EVENT((service), &ge, NULL); + } + c_iterFree(groups); } } @@ -365,8 +361,8 @@ v_serviceTakeNewGroups( result = c_iterNew(NULL); - v_observerLock(v_observer(service)); - newGroups = (c_set)v_observer(service)->eventData; + OSPL_BLOCK_EVENTS(service); + newGroups = service->newGroups; if (newGroups != NULL) { group = v_group(c_take(newGroups)); while (group != NULL) { @@ -374,7 +370,7 @@ v_serviceTakeNewGroups( group = v_group(c_take(newGroups)); } } - v_observerUnlock(v_observer(service)); + OSPL_UNBLOCK_EVENTS(service); return result; } @@ -387,7 +383,7 @@ v_serviceRenewLease( assert(service != NULL); assert(C_TYPECHECK(service, v_service)); - v_observerLock(v_observer(service)); + OSPL_LOCK(service); v_leaseRenew(service->lease, leasePeriod); - v_observerUnlock(v_observer(service)); + OSPL_UNLOCK(service); } diff --git a/src/kernel/code/v_serviceManager.c b/src/kernel/code/v_serviceManager.c index d0490ead1..231622967 100644 --- a/src/kernel/code/v_serviceManager.c +++ b/src/kernel/code/v_serviceManager.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,7 +27,7 @@ #include "v__serviceState.h" #include "v__lease.h" #include "v__observer.h" -#include "v_observable.h" +#include "v__observable.h" #include "v__entity.h" #include "v_public.h" #include "v_event.h" @@ -39,9 +40,6 @@ struct collectNamesArg { c_iter list; }; -/**************************************************************************** - * Private functions - ****************************************************************************/ static c_bool collectNames( c_object s, @@ -61,12 +59,9 @@ collectNames( return TRUE; } -/**************************************************************************** - * New/Free - ****************************************************************************/ static void v_serviceManagerInit( - v_serviceManager sm) + _Inout_ v_serviceManager sm) { v_kernel k; @@ -75,15 +70,17 @@ v_serviceManagerInit( k = v_objectKernel(sm); - v_entityInit(v_entity(sm), "ServiceManager", TRUE); + v_entityInit(v_entity(sm), "ServiceManager"); + (void)v_entityEnable(v_entity(sm)); - c_mutexInit(c_getBase(sm), &sm->mutex); sm->serviceStates = c_tableNew(v_kernelType(k, K_SERVICESTATE), "name"); } +_Check_return_ +_Ret_notnull_ v_serviceManager v_serviceManagerNew( - v_kernel k) + _In_ v_kernel k) { v_serviceManager sm; @@ -95,30 +92,6 @@ v_serviceManagerNew( return sm; } - -/**************************************************************************** - * Protected functions - ****************************************************************************/ -void -v_serviceManagerNotify( - v_serviceManager serviceManager, - v_event event, - c_voidp userData) -{ - OS_UNUSED_ARG(serviceManager); - OS_UNUSED_ARG(userData); - assert(serviceManager != NULL); - assert(C_TYPECHECK(serviceManager,v_serviceManager)); - - /* Only V_EVENT_SERVICESTATE_CHANGED is expected! - event may be NULL in case of termination. - */ - if ((event != NULL) && (event->kind != V_EVENT_SERVICESTATE_CHANGED)) { - OS_REPORT(OS_WARNING, "v_serviceManager", V_RESULT_INTERNAL_ERROR, "Unexpected event"); - assert(FALSE); - } -} - v_serviceState v_serviceManagerRegister( v_serviceManager serviceManager, @@ -137,7 +110,7 @@ v_serviceManagerRegister( kernel = v_objectKernel(serviceManager); state = v_serviceStateNew(kernel, v_participantName(service), extStateName); if (state != NULL) { - c_mutexLock(&serviceManager->mutex); + OSPL_LOCK(serviceManager); found = ospl_c_insert(serviceManager->serviceStates, state); @@ -145,10 +118,11 @@ v_serviceManagerRegister( c_free(state); state = NULL; c_keep(found); + } else { + OSPL_ADD_OBSERVER(state, serviceManager, V_EVENT_SERVICESTATE_CHANGED, NULL); } - c_mutexUnlock(&serviceManager->mutex); + OSPL_UNLOCK(serviceManager); /* observe the state */ - v_observableAddObserver(v_observable(found), v_observer(serviceManager), NULL); } else { found = NULL; } @@ -174,12 +148,12 @@ v_serviceManagerGetServiceState( expr = (q_expr)q_parse("name like %0"); params[0] = c_stringValue(c_stringNew(c_getBase(serviceManager), serviceName)); - c_mutexLock(&serviceManager->mutex); + OSPL_LOCK(serviceManager); q = c_queryNew(serviceManager->serviceStates, expr, params); q_dispose(expr); list = ospl_c_select(q, 0); c_free(q); - c_mutexUnlock(&serviceManager->mutex); + OSPL_UNLOCK(serviceManager); c_free(params[0].is.String); state = c_iterTakeFirst(list); @@ -189,9 +163,6 @@ v_serviceManagerGetServiceState( return state; } -/**************************************************************************** - * Public functions - ****************************************************************************/ v_serviceStateKind v_serviceManagerGetServiceStateKind( v_serviceManager serviceManager, @@ -229,9 +200,9 @@ v_serviceManagerGetServices( arg.kind = kind; arg.list = c_iterNew(NULL); - c_mutexLock(&serviceManager->mutex); + OSPL_LOCK(serviceManager); c_walk(serviceManager->serviceStates, collectNames, &arg); - c_mutexUnlock(&serviceManager->mutex); + OSPL_UNLOCK(serviceManager); return arg.list; } @@ -249,7 +220,7 @@ v_serviceManagerRemoveService( state = v_serviceManagerGetServiceState(serviceManager,serviceName); if (state) { - c_mutexLock(&serviceManager->mutex); + OSPL_LOCK(serviceManager); removed = c_remove(serviceManager->serviceStates, state, NULL, NULL); if (state != removed) { OS_REPORT(OS_ERROR, "v_serviceManagerRemoveService", V_RESULT_INTERNAL_ERROR, @@ -257,7 +228,7 @@ v_serviceManagerRemoveService( } else { result = TRUE; } - c_mutexUnlock(&serviceManager->mutex); + OSPL_UNLOCK(serviceManager); } else { OS_REPORT(OS_ERROR, "v_serviceManagerRemoveService", V_RESULT_INTERNAL_ERROR, "Could not get the service state for service %s",serviceName); diff --git a/src/kernel/code/v_serviceState.c b/src/kernel/code/v_serviceState.c index 64d10c5e6..7f16402d7 100644 --- a/src/kernel/code/v_serviceState.c +++ b/src/kernel/code/v_serviceState.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -33,9 +34,6 @@ #include "v_public.h" #include "os_report.h" -/************************************************************** - * constructor/destructor - **************************************************************/ v_serviceState v_serviceStateNew( v_kernel k, @@ -111,18 +109,9 @@ v_serviceStateInit( serviceState->name = c_stringNew(c_getBase(serviceState),name); - c_lockInit(c_getBase(serviceState), &serviceState->lock); serviceState->stateKind = STATE_NONE; } - -/************************************************************** - * Protected functions - **************************************************************/ - -/************************************************************** - * Public functions - **************************************************************/ c_bool v_serviceStateChangeState( v_serviceState serviceState, @@ -133,7 +122,7 @@ v_serviceStateChangeState( assert(C_TYPECHECK(serviceState, v_serviceState)); - c_lockWrite(&serviceState->lock); + OSPL_LOCK(serviceState); switch (stateKind) { case STATE_NONE: @@ -184,12 +173,14 @@ v_serviceStateChangeState( } else { changed = FALSE; } - c_lockUnlock(&serviceState->lock); event.kind = V_EVENT_SERVICESTATE_CHANGED; event.source = v_observable(serviceState); event.data = NULL; - v_observableNotify(v_observable(serviceState),&event); + event.handled = TRUE; + + OSPL_THROW_EVENT(serviceState, &event); + OSPL_UNLOCK(serviceState); return changed; } @@ -202,9 +193,9 @@ v_serviceStateGetKind( assert(C_TYPECHECK(serviceState, v_serviceState)); - c_lockRead(&serviceState->lock); + OSPL_LOCK(serviceState); kind = serviceState->stateKind; - c_lockUnlock(&serviceState->lock); + OSPL_UNLOCK(serviceState); return kind; } @@ -217,17 +208,9 @@ v_serviceStateGetName( assert(C_TYPECHECK(serviceState, v_serviceState)); - c_lockRead(&serviceState->lock); + OSPL_LOCK(serviceState); name = serviceState->name; - c_lockUnlock(&serviceState->lock); + OSPL_UNLOCK(serviceState); return (const c_char *)name; } - -void -v_serviceStateNotify( - v_serviceState serviceState, - v_serviceStateKind kind) -{ - v_serviceStateChangeState(serviceState, kind); -} diff --git a/src/kernel/code/v_spliced.c b/src/kernel/code/v_spliced.c index 0dd9c47b2..a4715de16 100644 --- a/src/kernel/code/v_spliced.c +++ b/src/kernel/code/v_spliced.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -58,7 +59,8 @@ #include "v__kernel.h" #include "v_public.h" #include "v_entity.h" -#include "v_observable.h" +#include "v__observer.h" +#include "v__observable.h" #include "v_event.h" #include "v_dataReaderSample.h" #include "v__subscriber.h" @@ -118,9 +120,6 @@ doCleanupPublication( c_bool isLocal, c_bool isImplicit); -/************************************************************** - * Private functions - **************************************************************/ static v_actionResult readerTakeAction( c_object s, @@ -138,22 +137,6 @@ readerTakeAction( return result; } -#if 0 -static c_bool -lookupAction( - c_object o, - c_voidp arg) -{ - c_iter *messages = (c_iter *)arg; - - if (o != NULL) { - *messages = c_iterAppend(*messages, c_keep(o)); - } - - return TRUE; -} -#endif - static v_actionResult takeOne( c_object s, @@ -195,128 +178,10 @@ static v_dataReader gidClaimDataReader(v_gid id, v_kernel kernel) return r; } -struct matchArg { - c_bool matched; - c_array partition; -}; - -static c_bool -partitionNotMatched( - v_entity o, - c_voidp arg) -{ - struct matchArg *matchArg = (struct matchArg *)arg; - c_value match; - c_value partitionName; - c_value expr; - c_ulong i; - - /* Don't re-evaluate if a matching partition has already been found */ - if (!matchArg->matched && v_objectKind(o) == K_DOMAIN) { - match.kind = V_BOOLEAN; - match.is.Boolean = FALSE; - i = 0; - while ((match.is.Boolean == FALSE) && (i < c_arraySize(matchArg->partition))) { - partitionName = c_stringValue(v_entityName(o)); - expr = c_stringValue(matchArg->partition[i]); - match = c_valueStringMatch(expr, partitionName); - i++; - } - matchArg->matched = match.is.Boolean; - } - - return TRUE; -} - -static c_bool -readerWriterMatch( - struct v_subscriptionInfo *rInfo, - v_dataReader r, - struct v_publicationInfo *oInfo, - v_writer w) -{ - struct matchArg matchArg; - v_gid gid; - v_public publ; - - /** - * If (w != NULL) then it is a local writer. - */ - if ((w == NULL) && (r == NULL)) { - /* nothing to check.... */ - matchArg.matched = FALSE; - } else { - if (w != NULL) { - /* for every partition of w, check if it matches - with the requested partition. - */ - matchArg.matched = FALSE; - matchArg.partition = rInfo->partition.name; - - /*Claim publisher first before walking over relations.*/ - gid = v_publicGid(v_public(w->publisher)); - publ = v_gidClaim(gid, v_objectKernel(w)); - - if (publ) { - v_entityWalkEntities(v_entity(publ), partitionNotMatched, &matchArg); - v_gidRelease(gid, v_objectKernel(w)); - } - } else { /* w == NULL && r != NULL */ - /* for every partition of r check if it matches - with the offered partition. - */ - matchArg.matched = FALSE; - matchArg.partition = oInfo->partition.name; - - /*Claim subscriber first before walking over relations*/ - gid = v_publicGid(v_public(v_reader(r)->subscriber)); - publ = v_gidClaim(gid, v_objectKernel(r)); - - if (publ) { - v_entityWalkEntities(v_entity(publ), partitionNotMatched, &matchArg); - v_gidRelease(gid, v_objectKernel(r)); - } - } - } - return matchArg.matched; -} - -#if 0 -/* spliced->builtinDataMutex must be locked before calling this function */ -static c_iter -lookupMatchingReadersByTopic( - v_spliced spliced, - struct v_publicationInfo *oInfo) -{ - c_iter requestedMessages; - q_expr qExpr; - c_value params[1]; - c_query q; - c_bool proceed; - - if (spliced->builtinData[V_SUBSCRIPTIONINFO_ID] == NULL) { - return NULL; /* this builtin topic is disabled */ - } - - requestedMessages = NULL; - qExpr = (q_expr)q_parse("userData.topic_name like %0"); - params[0] = c_stringValue(oInfo->topic_name); - q = c_queryNew((c_collection)spliced->builtinData[V_SUBSCRIPTIONINFO_ID], - qExpr, params); - q_dispose(qExpr); - proceed = c_readAction(q, (c_action)lookupAction, (c_voidp)&requestedMessages); - assert(proceed == TRUE); - OS_UNUSED_ARG(proceed); - c_free(q); - - return requestedMessages; -} -#else - typedef struct getMatchingReaderArg_s { c_iter iter; - c_char *topicName; v_kernel kernel; + struct v_publicationInfo *pubInfo; } *getMatchingReaderArg; static c_bool @@ -328,7 +193,7 @@ getMatchingReader( struct v_subscriptionInfo *info = v_builtinSubscriptionInfoData(o); if (o != NULL) { - if (strcmp(a->topicName, info->topic_name) == 0) { + if (strcmp(a->pubInfo->topic_name, info->topic_name) == 0) { a->iter = c_iterAppend(a->iter, c_keep(o)); } } @@ -344,7 +209,7 @@ lookupMatchingReadersByTopic( struct getMatchingReaderArg_s arg; arg.iter = NULL; - arg.topicName = oInfo->topic_name; + arg.pubInfo = oInfo; arg.kernel = v_objectKernel(spliced); (void)c_walk((c_collection)spliced->builtinData[V_SUBSCRIPTIONINFO_ID], @@ -353,34 +218,6 @@ lookupMatchingReadersByTopic( return arg.iter; } -#endif - -#if 0 -/* spliced->builtinDataMutex must be locked before calling this function */ -static c_iter -lookupMatchingWritersByTopic( - v_spliced spliced, - struct v_subscriptionInfo *rInfo) -{ - c_iter offeredMessages; - q_expr qExpr; - c_value params[1]; - c_query q; - c_bool proceed; - - offeredMessages = NULL; - qExpr = (q_expr)q_parse("userData.topic_name like %0"); - params[0] = c_stringValue(rInfo->topic_name); - q = c_queryNew((c_collection)spliced->builtinData[V_PUBLICATIONINFO_ID], - qExpr, params); - q_dispose(qExpr); - proceed = c_readAction(q, (c_action)lookupAction, (c_voidp)&offeredMessages); - assert(proceed == TRUE); - c_free(q); - - return offeredMessages; -} -#else typedef struct getMatchingWriterArg_s { c_iter iter; @@ -421,7 +258,7 @@ lookupMatchingWritersByTopic( return arg.iter; } -#endif + static c_bool checkOfferedRequested( struct v_publicationInfo *oInfo, @@ -628,38 +465,11 @@ checkTopicConsistency( info->name, info->key.systemId); } if (consistent == FALSE) { - v_observerLock(v_observer(topic)); v_topicNotifyInconsistentTopic(topic); - v_observerUnlock(v_observer(topic)); } return consistent; } -static c_bool -matchPartition( - c_array name1, - c_array name2) -{ - c_ulong i, j; - c_value val; - c_value str1, str2; - - val.kind = V_BOOLEAN; - val.is.Boolean = FALSE; - - for (i = 0; val.is.Boolean == FALSE && i < c_arraySize(name1); i++) { - str1 = c_stringValue(name1[i]); - for (j = 0; val.is.Boolean == FALSE && j < c_arraySize(name2); j++) { - str2 = c_stringValue(name2[j]); - val = c_valueStringMatch(str1, str2); - if (!val.is.Boolean) { - val = c_valueStringMatch(str2, str1); - } - } - } - return val.is.Boolean; -} - static conformState determineState( struct v_publicationInfo *oInfo, @@ -667,19 +477,9 @@ determineState( { conformState state = CONFORM_STATE_UNKNOWN; -#define COMPATIBLE_QOS(offered, requested) \ - (v_reliabilityPolicyCompatible((offered)->reliability, (requested)->reliability) && \ - v_durabilityPolicyCompatible((offered)->durability, (requested)->durability) && \ - v_presentationPolicyCompatible((offered)->presentation, (requested)->presentation) && \ - v_latencyPolicyCompatible((offered)->latency_budget, (requested)->latency_budget) && \ - v_orderbyPolicyCompatible((offered)->destination_order, (requested)->destination_order) && \ - v_deadlinePolicyCompatible((offered)->deadline, (requested)->deadline) && \ - v_livelinessPolicyCompatible((offered)->liveliness, (requested)->liveliness) && \ - v_ownershipPolicyCompatible((offered)->ownership, (requested)->ownership)) - if ((oInfo != NULL) && (rInfo != NULL)) { - if (matchPartition(oInfo->partition.name, rInfo->partition.name) == TRUE) { - if (COMPATIBLE_QOS(oInfo, rInfo) == TRUE) { + if (v_builtinTestPartitionMatch(oInfo, rInfo) == TRUE) { + if (v_builtinTestQosMatch(oInfo, rInfo) == TRUE) { state = CONFORM_STATE_OK; } else { state = CONFORM_STATE_MATCH_NOT_COMPATIBLE; @@ -688,8 +488,6 @@ determineState( state = CONFORM_STATE_NO_MATCH; } } -#undef COMPATIBLE_QOS - return state; } @@ -750,22 +548,24 @@ v_splicedProcessSubscriptionInfo( kernel = v_objectKernel(spliced); - /* Try to take one subscriptionInfo message from the built-in DataRaeder. - */ + /* Try to take one subscriptionInfo message from the built-in DataRaeder. */ rSample = NULL; if (spliced->readers[V_SUBSCRIPTIONINFO_ID] != NULL) { (void)v_dataReaderTake(spliced->readers[V_SUBSCRIPTIONINFO_ID], V_MASK_ANY, takeOne, &rSample, OS_DURATION_ZERO); } - /* If a subscriptionInfo message exists then process it. - */ + /* If a subscriptionInfo message exists then process it. */ if (rSample != NULL) { result = 1; + v_builtinLogSubscription(kernel->builtin, rSample); + msg = v_dataReaderSampleMessage(rSample); rInfo = (struct v_subscriptionInfo *) (msg + 1); + v_kernelNotifySubscription(kernel, msg); + if (v_stateTest(v_readerSample(rSample)->sampleState, L_DISPOSED)) { c_mutexLock(&spliced->builtinDataMutex); @@ -773,23 +573,16 @@ v_splicedProcessSubscriptionInfo( /* The subscription is disposed so the following * code will remove and free the registration. */ - oldMsg = c_remove(spliced->builtinData[V_SUBSCRIPTIONINFO_ID], - msg, NULL, NULL); - + oldMsg = c_remove(spliced->builtinData[V_SUBSCRIPTIONINFO_ID], msg, NULL, NULL); if (oldMsg == NULL) { - /* The instance is not yet know no need to - * take action. - */ + /* The instance is not yet know no need to take action. */ c_mutexUnlock(&spliced->builtinDataMutex); } else { - /* Notify the nodal delivery service about any synchronous - * DataReader topology changes. - */ + /* Notify the nodal delivery service about any synchronous DataReader topology changes. */ oldInfo = v_builtinSubscriptionInfoData(oldMsg); if (oldInfo->reliability.synchronous) { v_deliveryServiceUnregister(kernel->deliveryService, oldMsg); } - /* Notify matching writers that a matching subscription disappeared */ offeredMessages = lookupMatchingWritersByTopic(spliced, oldInfo); @@ -817,32 +610,24 @@ v_splicedProcessSubscriptionInfo( c_iterFree(offeredMessages); } } else { - /* Notify the nodal delivery service about any synchronous - * DataReader topology changes. - */ + /* Notify the nodal delivery service about any synchronous DataReader topology changes. */ if (rInfo->reliability.synchronous) { v_deliveryServiceRegister(kernel->deliveryService,msg); } - c_mutexLock(&spliced->builtinDataMutex); - oldMsg = c_replace(spliced->builtinData[V_SUBSCRIPTIONINFO_ID], - msg, NULL, NULL); - + oldMsg = c_replace(spliced->builtinData[V_SUBSCRIPTIONINFO_ID], msg, NULL, NULL); if (oldMsg == NULL) { - /* A new registration. - */ + /* A new registration. */ oldInfo = NULL; } else if (oldMsg->sequenceNumber >= msg->sequenceNumber) { - /* Sample already received, ignore duplicate. - */ + /* Sample already received, ignore duplicate. */ found = c_replace(spliced->builtinData[V_SUBSCRIPTIONINFO_ID], oldMsg, NULL, NULL); c_free(found); cont = FALSE; } else { - /* An update of a registration. - */ + /* An update of a registration. */ oldInfo = v_builtinSubscriptionInfoData(oldMsg); } @@ -850,9 +635,7 @@ v_splicedProcessSubscriptionInfo( c_mutexUnlock(&spliced->builtinDataMutex); } else { r = gidClaimDataReader(rInfo->key, kernel); - /* Check if there are matching DataWriters i.e. with - * compatible qos policies. - */ + /* Check if there are matching DataWriters i.e. with compatible qos policies. */ /* Read all publicationInfo, with the same topic name, this way * all remote publications are also taken into account. @@ -920,14 +703,11 @@ v_splicedProcessSubscriptionInfo( } } } - c_free(v_dataReaderSampleInstance(rSample)); c_free(rSample); /* msg is freed here */ c_free(oldMsg); rSample = NULL; - } - return result; } @@ -976,35 +756,43 @@ v_splicedProcessPublicationInfo if (oSample != NULL) { result = 1; - /* Read all subscriptionInfo, with the same topic name, this way - all remote subscriptions are also taken into account. - */ + v_builtinLogPublication(kernel->builtin, oSample); + msg = v_dataReaderSampleMessage(oSample); oInfo = (struct v_publicationInfo *) (msg + 1); + /* Update publication in the kernel. + * In case of newly created local writers this is not necessary but doing it + * doesn't change the state, only causes an undesired scan of local readers. + * For local writers this call is already performed by the v_writerEnabe. + * Optimize in V6.9 when improved locking is available and after this code has moved to the kernel. + */ + v_kernelNotifyPublication(kernel, msg); + if (v_dataReaderSampleInstanceStateTest(oSample, L_DISPOSED)) { c_bool validSample = v_dataReaderSampleStateTest(oSample, L_VALIDDATA); c_bool isImplicit = v_messageStateTest(msg, L_IMPLICIT); c_mutexLock(&spliced->builtinDataMutex); - oldMsg = c_remove(spliced->builtinData[V_PUBLICATIONINFO_ID], - msg, NULL, NULL); - /* If there is no predecessor but the sample is valid, then interpret the sample itself. - * (This is for example the case when the builtin topics have been disabled, in which - * case only the dispose message will be transmitted as a VOLATILE sample.) - */ - if (oldMsg == NULL && - validSample && - !kernel->builtin->kernelQos->builtin.v.enabled) { + oldMsg = c_remove(spliced->builtinData[V_PUBLICATIONINFO_ID], msg, NULL, NULL); + if (oldMsg == NULL && validSample && !kernel->builtin->kernelQos->builtin.v.enabled) { + /* If there is no predecessor but the sample is valid, then interpret the sample itself. + * (This is for example the case when the builtin topics have been disabled, in which + * case only the dispose message will be transmitted as a VOLATILE sample.) + */ oldMsg = msg; } if (oldMsg != NULL) { oldInfo = v_builtinPublicationInfoData(oldMsg); + /* Read all subscriptionInfo, with the same topic name, this way + * all remote subscriptions are also taken into account. + */ /* the resulting readers are not matched on partition so the readers that do not belong * to the required partition need to be filtered out later on. * This is because of the partition field being an internal sequence so no expression - * can be done on it*/ + * can be done on it. + */ requestedMessages = lookupMatchingReadersByTopic(spliced, oldInfo); } c_mutexUnlock(&spliced->builtinDataMutex); @@ -1068,9 +856,13 @@ v_splicedProcessPublicationInfo } c_iterFree(requestedMessages); } - v_kernelNotifyGroupCoherentPublication(kernel, msg); + if (oInfo->presentation.coherent_access) { + v_kernelNotifyCoherentPublication(kernel, msg); + } } else { - v_kernelNotifyGroupCoherentPublication(kernel, msg); + if (oInfo->presentation.coherent_access) { + v_kernelNotifyCoherentPublication(kernel, msg); + } c_mutexLock(&spliced->builtinDataMutex); oldMsg = c_replace(spliced->builtinData[V_PUBLICATIONINFO_ID], msg, NULL, NULL); @@ -1081,20 +873,15 @@ v_splicedProcessPublicationInfo */ if (oldMsg == NULL) { - /* A new registration. - */ + /* A new registration. */ oldInfo = NULL; } else if (oldMsg->sequenceNumber >= msg->sequenceNumber) { - /* Sample already received, ignore duplicate. - */ - found = c_replace(spliced->builtinData[V_PUBLICATIONINFO_ID], - oldMsg, NULL, NULL); + /* Duplicate: sample already received, ignore duplicate. */ + found = c_replace(spliced->builtinData[V_PUBLICATIONINFO_ID], oldMsg, NULL, NULL); c_free(found); cont = FALSE; } else { - /* An update of a registration. - */ - + /* An update of a registration. */ oldInfo = v_builtinPublicationInfoData(oldMsg); } if (cont == TRUE) { @@ -1131,8 +918,7 @@ v_splicedProcessPublicationInfo } else if ((oldState == CONFORM_STATE_OK) && (newState == CONFORM_STATE_OK)) { if (r != NULL) { - /* oldInfo can't be NULL here. - */ + /* oldInfo can't be NULL here. */ if (oldInfo->ownership_strength.value != oInfo->ownership_strength.value) { /* Notify reader ownership strength might have changed for it's instances. */ ownership.exclusive = (oInfo->ownership.kind == V_OWNERSHIP_EXCLUSIVE ? TRUE : FALSE); @@ -1184,7 +970,8 @@ v_splicedProcessPublicationInfo } /* returns 0, when no DCPSTopicInfo sample was available. - * Otherwise 1 is returned */ + * Otherwise 1 is returned + */ static int v_splicedProcessTopicInfo( v_spliced spliced) @@ -1213,6 +1000,8 @@ v_splicedProcessTopicInfo( kernel = v_objectKernel(spliced); s = v_dataReaderSample(c_iterTakeFirst(samples)); while (s != NULL) { + v_builtinLogTopic(kernel->builtin, s); + proceed = TRUE; m = v_dataReaderSampleMessage(s); info = (struct v_topicInfo *) (m + 1); @@ -1260,7 +1049,8 @@ v_splicedProcessTopicInfo( /* returns 0, when no DCPSTypeInfo sample was available. - * Otherwise 1 is returned */ + * Otherwise 1 is returned + */ static int v_splicedProcessTypeInfo( v_spliced spliced) @@ -1311,6 +1101,165 @@ v_splicedProcessTypeInfo( } } +static int +v_splicedProcessDataWriterCMInfo ( + v_spliced spliced) +{ + int result = 0; + c_iter samples; + v_dataReaderSample s; + v_kernel kernel; + + assert(spliced != NULL); + assert(C_TYPECHECK(spliced,v_spliced)); + + if (!spliced->readers[V_CMDATAWRITERINFO_ID]) return 0; + + samples = NULL; + (void)v_dataReaderTake(spliced->readers[V_CMDATAWRITERINFO_ID], V_MASK_ANY, + readerTakeAction, &samples, OS_DURATION_ZERO); + if (samples) { + kernel = v_objectKernel(spliced); + s = v_dataReaderSample(c_iterTakeFirst(samples)); + while (s != NULL) { + v_builtinLogCMDataWriter(kernel->builtin, s); + c_free(s); + s = v_dataReaderSample(c_iterTakeFirst(samples)); + } + } + assert(c_iterLength(samples) == 0); + c_iterFree(samples); + + return result; +} + +static int +v_splicedProcessDataReaderCMInfo ( + v_spliced spliced) +{ + int result = 0; + c_iter samples; + v_dataReaderSample s; + v_kernel kernel; + + assert(spliced != NULL); + assert(C_TYPECHECK(spliced,v_spliced)); + + if (!spliced->readers[V_CMDATAREADERINFO_ID]) return 0; + + samples = NULL; + (void)v_dataReaderTake(spliced->readers[V_CMDATAREADERINFO_ID], V_MASK_ANY, + readerTakeAction, &samples, OS_DURATION_ZERO); + if (samples) { + kernel = v_objectKernel(spliced); + s = v_dataReaderSample(c_iterTakeFirst(samples)); + while (s != NULL) { + v_builtinLogCMDataReader(kernel->builtin, s); + c_free(s); + s = v_dataReaderSample(c_iterTakeFirst(samples)); + } + } + assert(c_iterLength(samples) == 0); + c_iterFree(samples); + + return result; +} + +static int +v_splicedProcessPublisherCMInfo ( + v_spliced spliced) +{ + int result = 0; + c_iter samples; + v_dataReaderSample s; + v_kernel kernel; + + assert(spliced != NULL); + assert(C_TYPECHECK(spliced,v_spliced)); + + if (!spliced->readers[V_CMPUBLISHERINFO_ID]) return 0; + + samples = NULL; + (void)v_dataReaderTake(spliced->readers[V_CMPUBLISHERINFO_ID], V_MASK_ANY, + readerTakeAction, &samples, OS_DURATION_ZERO); + if (samples) { + kernel = v_objectKernel(spliced); + s = v_dataReaderSample(c_iterTakeFirst(samples)); + while (s != NULL) { + v_builtinLogCMPublisher(kernel->builtin, s); + c_free(s); + s = v_dataReaderSample(c_iterTakeFirst(samples)); + } + } + assert(c_iterLength(samples) == 0); + c_iterFree(samples); + + return result; +} + +static int +v_splicedProcessSubscriberCMInfo ( + v_spliced spliced) +{ + int result = 0; + c_iter samples; + v_dataReaderSample s; + v_kernel kernel; + + assert(spliced != NULL); + assert(C_TYPECHECK(spliced,v_spliced)); + + if (!spliced->readers[V_CMSUBSCRIBERINFO_ID]) return 0; + + samples = NULL; + (void)v_dataReaderTake(spliced->readers[V_CMSUBSCRIBERINFO_ID], V_MASK_ANY, + readerTakeAction, &samples, OS_DURATION_ZERO); + if (samples) { + kernel = v_objectKernel(spliced); + s = v_dataReaderSample(c_iterTakeFirst(samples)); + while (s != NULL) { + v_builtinLogCMSubscriber(kernel->builtin, s); + c_free(s); + s = v_dataReaderSample(c_iterTakeFirst(samples)); + } + } + assert(c_iterLength(samples) == 0); + c_iterFree(samples); + + return result; +} + +static int +v_splicedProcessParticipantCMInfo ( + v_spliced spliced) +{ + int result = 0; + c_iter samples; + v_dataReaderSample s; + v_kernel kernel; + + assert(spliced != NULL); + assert(C_TYPECHECK(spliced,v_spliced)); + + if (!spliced->readers[V_CMPARTICIPANTINFO_ID]) return 0; + + samples = NULL; + (void)v_dataReaderTake(spliced->readers[V_CMPARTICIPANTINFO_ID], V_MASK_ANY, + readerTakeAction, &samples, OS_DURATION_ZERO); + if (samples) { + kernel = v_objectKernel(spliced); + s = v_dataReaderSample(c_iterTakeFirst(samples)); + while (s != NULL) { + v_builtinLogCMParticipant(kernel->builtin, s); + c_free(s); + s = v_dataReaderSample(c_iterTakeFirst(samples)); + } + } + assert(c_iterLength(samples) == 0); + c_iterFree(samples); + + return result; +} struct matchHeartbeatHelper { c_ulong systemId; /* systemId from key of participantInfo sample */ @@ -1358,6 +1307,7 @@ v_splicedProcessParticipantInfo( (void)v_dataReaderTake(spliced->readers[V_PARTICIPANTINFO_ID], V_MASK_ANY, readerTakeAction, &samples, OS_DURATION_ZERO); sample = v_dataReaderSample(c_iterTakeFirst(samples)); while (sample != NULL) { + v_builtinLogParticipant(kernel->builtin, sample); /* Only process this instance if it isn't seen before */ if (v_dataReaderSampleStateTest(sample, L_NEW)) { v_message msg = v_dataReaderSampleMessage(sample); @@ -1372,8 +1322,9 @@ v_splicedProcessParticipantInfo( matchHeartbeatAction, &helper, OS_DURATION_ZERO); if (!helper.found) { /* fake heartbeat to ensure eventual cleanup if the DCPSParticipant - arrived via durability and the node has disappeared without us ever - receiving a heartbeat */ + * arrived via durability and the node has disappeared without us ever + * receiving a heartbeat + */ v_writer writer = v_builtinWriterLookup(kernel->builtin, V_HEARTBEATINFO_ID); (void)v_builtinWriteHeartbeat( @@ -1389,288 +1340,6 @@ v_splicedProcessParticipantInfo( return 0; /* is just a garbage collector, so no worries */ } -v_result -v_splicedGetMatchedSubscriptions( - v_spliced spliced, - v_writer w, - v_subscriptionInfo_action action, - c_voidp arg) -{ - v_kernel kernel; - v_result result; - c_iter requestedMessages = NULL; - v_message msg; - v_message reqMsg; - struct v_subscriptionInfo *rInfo; - struct v_publicationInfo *oInfo; - - v_dataReader r; - v_policyId compatible[V_POLICY_ID_COUNT]; - - result = V_RESULT_OK; - - assert(w != NULL); - assert(C_TYPECHECK(w,v_writer)); - - assert(spliced != NULL); - assert(C_TYPECHECK(spliced,v_spliced)); - - kernel = v_objectKernel(spliced); - - if (w != NULL) { - /* Create a template message */ - msg = v_builtinCreatePublicationInfo(kernel->builtin, w); - if (msg != NULL) { - oInfo = (struct v_publicationInfo *) (msg + 1); - v_gidClaim(oInfo->key, kernel); - - if (oInfo != NULL) { - /* get topic-matching subscriptions */ - c_mutexLock(&spliced->builtinDataMutex); - - requestedMessages = lookupMatchingReadersByTopic(spliced, oInfo); - reqMsg = c_iterTakeFirst(requestedMessages); - while (reqMsg != NULL && result == V_RESULT_OK) { - rInfo = v_builtinSubscriptionInfoData(reqMsg); - r = gidClaimDataReader(rInfo->key, kernel); - - /* if QoS are matching then add the subscription to return list */ - if (readerWriterMatch(rInfo, r, oInfo, w) == TRUE) { - if (checkOfferedRequested(oInfo, rInfo, compatible) == TRUE) { - result = action(rInfo, arg); - } - } - if(r != NULL) - { - v_gidRelease(rInfo->key, kernel); - } - c_free(reqMsg); - reqMsg = c_iterTakeFirst(requestedMessages); - } - c_iterFree(requestedMessages); - - c_mutexUnlock(&spliced->builtinDataMutex); - } - v_gidRelease(oInfo->key, kernel); - c_free(msg); - } - } - return result; -} - -v_result -v_splicedGetMatchedSubscriptionData( - v_spliced spliced, - v_writer w, - v_gid subscription, - v_subscriptionInfo_action action, - c_voidp arg) -{ - v_kernel kernel; - v_result result; - c_iter requestedMessages; - v_message msg; - v_message reqMsg; - struct v_subscriptionInfo *rInfo; - struct v_publicationInfo *oInfo; - - v_dataReader r; - v_policyId compatible[V_POLICY_ID_COUNT]; - - result = V_RESULT_ILL_PARAM; - - assert(w != NULL); - assert(C_TYPECHECK(w,v_writer)); - - assert(spliced != NULL); - assert(C_TYPECHECK(spliced,v_spliced)); - - kernel = v_objectKernel(spliced); - - if (w != NULL) { - /* Create a template message */ - msg = v_builtinCreatePublicationInfo(kernel->builtin, w); - if (msg != NULL) { - oInfo = (struct v_publicationInfo *) (msg + 1); - v_gidClaim(oInfo->key, kernel); - - if (oInfo != NULL) { - /* get topic-matching subscriptions */ - c_mutexLock(&spliced->builtinDataMutex); - - requestedMessages = lookupMatchingReadersByTopic(spliced, oInfo); - reqMsg = c_iterTakeFirst(requestedMessages); - while (reqMsg != NULL) { - rInfo = v_builtinSubscriptionInfoData(reqMsg); - r = gidClaimDataReader(rInfo->key, kernel); - - if (readerWriterMatch(rInfo, r, oInfo, w) == TRUE) { - if (checkOfferedRequested(oInfo, rInfo, compatible) == TRUE) { - /*if(v_gidCompare(rInfo->key, subscription) == C_EQ)*/ - if (rInfo->key.systemId == subscription.systemId - && rInfo->key.localId == subscription.localId) { - result = action(rInfo, arg); - } - } - } - if(r != NULL) - { - v_gidRelease(rInfo->key, kernel); - } - c_free(reqMsg); - reqMsg = c_iterTakeFirst(requestedMessages); - } - c_iterFree(requestedMessages); - - c_mutexUnlock(&spliced->builtinDataMutex); - } - v_gidRelease(oInfo->key, kernel); - c_free(msg); - } - } - return result; -} - -v_result -v_splicedGetMatchedPublications( - v_spliced spliced, - v_dataReader r, - v_publicationInfo_action action, - c_voidp arg) -{ - v_kernel kernel; - v_result result; - c_iter requestedMessages; - v_message msg; - v_message reqMsg; - struct v_subscriptionInfo *rInfo; - struct v_publicationInfo *oInfo; - - v_writer w; - v_policyId compatible[V_POLICY_ID_COUNT]; - - result = V_RESULT_OK; - - assert(r != NULL); - assert(C_TYPECHECK(r,v_reader)); - - assert(spliced != NULL); - assert(C_TYPECHECK(spliced,v_spliced)); - - kernel = v_objectKernel(spliced); - - if (r != NULL) { - /* Create a template message */ - msg = v_builtinCreateSubscriptionInfo(kernel->builtin, v_reader(r)); - if (msg != NULL) { - rInfo = (struct v_subscriptionInfo *) (msg + 1); - v_gidClaim(rInfo->key, kernel); - - if (rInfo != NULL) { - /* get topic-matching publications */ - c_mutexLock(&spliced->builtinDataMutex); - - requestedMessages = lookupMatchingWritersByTopic(spliced, rInfo); - reqMsg = c_iterTakeFirst(requestedMessages); - while (reqMsg != NULL && result == V_RESULT_OK) { - oInfo = (struct v_publicationInfo *) (reqMsg + 1); - w = v_writer(v_gidClaim(oInfo->key, kernel)); - /* if QoS are matching then add the publication to return list */ - if (readerWriterMatch(rInfo, r, oInfo, w) == TRUE) { - if (checkOfferedRequested(oInfo, rInfo, compatible) == TRUE) { - result = action(oInfo, arg); - } - } - if(w != NULL) - { - v_gidRelease(oInfo->key, kernel); - } - c_free(reqMsg); - reqMsg = c_iterTakeFirst(requestedMessages); - } - c_iterFree(requestedMessages); - - c_mutexUnlock(&spliced->builtinDataMutex); - } - v_gidRelease(rInfo->key, kernel); - c_free(msg); - } - } - return result; -} - -v_result -v_splicedGetMatchedPublicationData( - v_spliced spliced, - v_dataReader r, - v_gid publication, - v_publicationInfo_action action, - c_voidp arg) -{ - v_kernel kernel; - v_result result; - c_iter requestedMessages; - v_message msg; - v_message reqMsg; - struct v_subscriptionInfo *rInfo; - struct v_publicationInfo *oInfo; - v_writer w; - v_policyId compatible[V_POLICY_ID_COUNT]; - - result = V_RESULT_ILL_PARAM; - - assert(r != NULL); - assert(C_TYPECHECK(r,v_dataReader)); - - assert(spliced != NULL); - assert(C_TYPECHECK(spliced,v_spliced)); - - kernel = v_objectKernel(spliced); - - if (r != NULL) { - /* Create a template message */ - msg = v_builtinCreateSubscriptionInfo(kernel->builtin, v_reader(r)); - if (msg != NULL) { - rInfo = (struct v_subscriptionInfo *) (msg + 1); - v_gidClaim(rInfo->key, kernel); - - if (rInfo != NULL) { - /* get topic-matching publications */ - c_mutexLock(&spliced->builtinDataMutex); - - requestedMessages = lookupMatchingWritersByTopic(spliced, rInfo); - reqMsg = c_iterTakeFirst(requestedMessages); - while (reqMsg != NULL) { - oInfo = (struct v_publicationInfo *) (reqMsg + 1); - w = v_writer(v_gidClaim(oInfo->key, kernel)); - - if (readerWriterMatch(rInfo, r, oInfo, w) == TRUE) { - if (checkOfferedRequested(oInfo, rInfo, compatible) == TRUE) { - /*if(v_gidCompare(oInfo->key, publication) == C_EQ)*/ - if (oInfo->key.systemId == publication.systemId - && oInfo->key.localId == publication.localId) { - result = action(oInfo, arg); - } - } - } - if(w != NULL) - { - v_gidRelease(oInfo->key, kernel); - } - c_free(reqMsg); - reqMsg = c_iterTakeFirst(requestedMessages); - } - c_iterFree(requestedMessages); - - c_mutexUnlock(&spliced->builtinDataMutex); - } - v_gidRelease(rInfo->key, kernel); - c_free(msg); - } - } - return result; -} - static c_char * messageKeyExpr( v_topic topic) @@ -1723,10 +1392,10 @@ messageKeyExpr( expr = q_parse("select * from " _name);\ spliced->readers[_id] = v_dataReaderNew(spliced->builtinSubscriber,\ _name "Reader", \ - expr, NULL, rQos, TRUE);\ + expr, NULL, 0, rQos);\ + (void)v_entityEnable(v_entity(spliced->readers[_id])); \ q_dispose(expr); \ - v_observableAddObserver(v_observable(spliced->readers[_id]),\ - v_observer(spliced->ws), NULL) + OSPL_ADD_OBSERVER(spliced->readers[_id],spliced->ws, V_EVENT_DATA_AVAILABLE, NULL) static void v_splicedManageKernel( @@ -1747,7 +1416,7 @@ v_splicedManageKernel( kernel = v_objectKernel(spliced); spliced->ws = v_waitsetNew(v_participant(spliced)); - v_observerSetEventMask(v_observer(spliced->ws), + OSPL_SET_EVENT_MASK(spliced->ws, V_EVENT_OBJECT_DESTROYED | V_EVENT_DATA_AVAILABLE | V_EVENT_TRIGGER | @@ -1761,7 +1430,9 @@ v_splicedManageKernel( sQos->partition.v = c_stringNew(c_getBase(c_object(kernel)), V_BUILTIN_PARTITION); sQos->entityFactory.v.autoenable_created_entities = TRUE; spliced->builtinSubscriber = v_subscriberNew(v_participant(spliced), - "Builtin subscriber", sQos, TRUE); + "Builtin subscriber", sQos); + assert(spliced->builtinSubscriber); + (void)v_entityEnable(v_entity(spliced->builtinSubscriber)); v_subscriberQosFree(sQos); rQos = v_readerQosNew(kernel, NULL); @@ -1776,6 +1447,13 @@ v_splicedManageKernel( if (kernel->qos->builtin.v.enabled) { _INIT_BUILTIN_DATA_(V_SUBSCRIPTIONINFO_ID, V_SUBSCRIPTIONINFO_NAME); _INIT_BUILTIN_DATA_(V_PUBLICATIONINFO_ID, V_PUBLICATIONINFO_NAME); + if (kernel->builtin->logfile) { + _INIT_BUILTIN_DATA_(V_CMDATAWRITERINFO_ID, V_CMDATAWRITERINFO_NAME); + _INIT_BUILTIN_DATA_(V_CMDATAREADERINFO_ID, V_CMDATAREADERINFO_NAME); + _INIT_BUILTIN_DATA_(V_CMPUBLISHERINFO_ID, V_CMPUBLISHERINFO_NAME); + _INIT_BUILTIN_DATA_(V_CMSUBSCRIBERINFO_ID, V_CMSUBSCRIBERINFO_NAME); + _INIT_BUILTIN_DATA_(V_CMPARTICIPANTINFO_ID, V_CMPARTICIPANTINFO_NAME); + } } else { rQos->durability.v.kind = V_DURABILITY_VOLATILE; _INIT_BUILTIN_DATA_(V_PUBLICATIONINFO_ID, V_PUBLICATIONINFO_NAME); @@ -1815,10 +1493,11 @@ v_splicedManageKernel( spliced->readers[V_HEARTBEATINFO_ID] = v_dataReaderNew(spliced->builtinSubscriber, V_HEARTBEATINFO_NAME "Reader", - expr, params, - NULL, TRUE); + expr, params, 0, + NULL); + (void)v_entityEnable(v_entity(spliced->readers[V_HEARTBEATINFO_ID])); q_dispose(expr); - v_observableAddObserver(v_observable(spliced->readers[V_HEARTBEATINFO_ID]), v_observer(spliced->ws), NULL); + OSPL_ADD_OBSERVER(spliced->readers[V_HEARTBEATINFO_ID], spliced->ws, V_EVENT_DATA_AVAILABLE, NULL); topic = v_builtinTopicLookup(kernel->builtin, V_HEARTBEATINFO_ID); str = messageKeyExpr(topic); spliced->missedHB = c_tableNew(v_topicMessageType(topic), str); @@ -1831,9 +1510,10 @@ v_splicedManageKernel( spliced->readers[V_PARTICIPANTINFO_ID] = v_dataReaderNew(spliced->builtinSubscriber, V_PARTICIPANTINFO_NAME "Reader", - expr, params, - rQos, TRUE); - v_observableAddObserver(v_observable(spliced->readers[V_PARTICIPANTINFO_ID]), v_observer(spliced->ws), NULL); + expr, params, 0, + rQos); + (void)v_entityEnable(v_entity(spliced->readers[V_PARTICIPANTINFO_ID])); + OSPL_ADD_OBSERVER(spliced->readers[V_PARTICIPANTINFO_ID], spliced->ws, V_EVENT_DATA_AVAILABLE, NULL); q_dispose(expr); } v_readerQosFree(rQos); @@ -1846,21 +1526,20 @@ v_splicedManageKernel( spliced->readers[V_C_AND_M_COMMAND_ID] = v_dataReaderNew(spliced->builtinSubscriber, C_AND_M_READER_NAME, - expr, params, - rQos, TRUE); + expr, params, 0, + rQos); + (void)v_entityEnable(v_entity(spliced->readers[V_C_AND_M_COMMAND_ID])); v_readerQosFree(rQos); q_dispose(expr); } #undef _INIT_BUILTIN_DATA_ -/************************************************************** - * constructor/destructor - **************************************************************/ +_Check_return_ +_Ret_notnull_ v_spliced v_splicedNew( - v_kernel kernel, - c_bool enable) + _In_ v_kernel kernel) { v_spliced spliced; @@ -1868,15 +1547,14 @@ v_splicedNew( assert(C_TYPECHECK(kernel,v_kernel)); spliced = v_spliced(v_objectNew(kernel, K_SPLICED)); - v_splicedInit(spliced, enable); + v_splicedInit(spliced); return spliced; } void v_splicedInit( - v_spliced spliced, - c_bool enable) + _Inout_ v_spliced spliced) { v_kernel kernel; v_participantQos q; @@ -1904,16 +1582,15 @@ v_splicedInit( os_free(hostName); #undef MAX_HOST_NAME_LENGTH - v_serviceInit(v_service(spliced), V_SPLICED_NAME, NULL, V_SERVICETYPE_SPLICED, q, enable); + v_serviceInit(v_service(spliced), V_SPLICED_NAME, NULL, V_SERVICETYPE_SPLICED, q, TRUE); c_free(q); /* replace my leaseManager (created in v_serviceInit()) * with the kernel leaseManager */ c_free(v_participant(spliced)->leaseManager); v_participant(spliced)->leaseManager = c_keep(kernel->livelinessLM); - c_mutexInit(c_getBase(spliced), &spliced->mtx); - c_mutexInit(c_getBase(spliced), &spliced->cAndMCommandMutex); - c_mutexInit(c_getBase(spliced), &spliced->builtinDataMutex); + (void)c_mutexInit(c_getBase(spliced), &spliced->cAndMCommandMutex); + (void)c_mutexInit(c_getBase(spliced), &spliced->builtinDataMutex); spliced->readers[V_PARTICIPANTINFO_ID] = NULL; spliced->readers[V_TOPICINFO_ID] = NULL; @@ -1922,6 +1599,12 @@ v_splicedInit( spliced->readers[V_SUBSCRIPTIONINFO_ID] = NULL; spliced->readers[V_C_AND_M_COMMAND_ID] = NULL; + spliced->readers[V_CMPARTICIPANTINFO_ID] = NULL; + spliced->readers[V_CMDATAWRITERINFO_ID] = NULL; + spliced->readers[V_CMDATAREADERINFO_ID] = NULL; + spliced->readers[V_CMPUBLISHERINFO_ID] = NULL; + spliced->readers[V_CMSUBSCRIBERINFO_ID] = NULL; + spliced->builtinData[V_PARTICIPANTINFO_ID] = NULL; spliced->builtinData[V_TOPICINFO_ID] = NULL; spliced->builtinData[V_TYPEINFO_ID] = NULL; @@ -1952,9 +1635,11 @@ v_splicedFree( kernel = v_objectKernel(spliced); /* set builtin writer to NULL, to prevent - using those writers while publishing builtin topic information - */ + * using those writers while publishing builtin topic information + */ v_builtinWritersDisable(kernel->builtin); + c_free(kernel->spliced); + kernel->spliced = NULL; /* Stop heartbeats */ v_serviceFree(v_service(spliced)); @@ -1979,13 +1664,6 @@ v_splicedDeinit( v_serviceDeinit(v_service(spliced)); } -/************************************************************** - * Protected functions - **************************************************************/ - -/************************************************************** - * Protected functions - **************************************************************/ void v_splicedHeartbeat( v_spliced spliced) @@ -2079,7 +1757,8 @@ static v_actionResult processHeartbeatReadAction(c_object o, c_voidp varg) static int v_splicedProcessHeartbeat (v_spliced spliced) { /* Trigger the heartbeat lease action so that the actual processing is single - threaded by the thread at the correct priority. */ + * threaded by the thread at the correct priority. + */ struct processHeartbeatReadActionArg arg; arg.spliced = spliced; arg.resched = 0; @@ -2105,8 +1784,9 @@ v_splicedCheckHeartbeats( v_dataReaderSample s; /* Read updates first, ignoring disposes. NOT_ALIVE_NO_WRITERS instances - will be disposed (so will be taken below), writes result in checking the - heartbeat. */ + * will be disposed (so will be taken below), writes result in checking the + * heartbeat. + */ rtarg.result = NULL; rtarg.isdisposed = 0; v_dataReaderRead(spliced->readers[V_HEARTBEATINFO_ID], V_MASK_ANY, readTakeAction, &rtarg, OS_DURATION_ZERO); @@ -2120,14 +1800,16 @@ v_splicedCheckHeartbeats( assert(v_gidEqual(hb->id, v_publicGid(v_public(spliced))) == FALSE); if (OS_DURATION_ISINFINITE(hb_period)) { /* Unregister a fake heartbeats just in case we wrote one when - processing a DCPSParticipant sample */ + * processing a DCPSParticipant sample + */ v_writer writer = v_builtinWriterLookup( v_objectKernel(spliced)->builtin, V_HEARTBEATINFO_ID); (void)v_builtinWriteHeartbeat( writer, hb->id.systemId, msg->writeTime, hb_period, L_UNREGISTER); } else if (os_durationCompare(os_timeEDiff(tnow, msg->allocTime), hb_period) == OS_MORE) { /* Expired heartbeat, dispose to let the next part of the - processing hand it off to the garbage collector */ + * processing hand it off to the garbage collector + */ disposeHeartbeat(spliced, s); } else if (os_durationCompare(hb_period, nextPeriod) == OS_LESS) { /* This node's heartbeat is set to expire first. */ @@ -2139,28 +1821,26 @@ v_splicedCheckHeartbeats( c_iterFree(rtarg.result); /* For all heartbeats that we missed or were disposed, get the garbage collector - to eventually clean up all associated data (dispose built-in topics for remote - entities, (auto dispose and) unregister samples for remote writers, &c.) */ + * to eventually clean up all associated data (dispose built-in topics for remote + * entities, (auto dispose and) unregister samples for remote writers, &c.) + */ rtarg.result = NULL; rtarg.isdisposed = 1; (void)v_dataReaderTake(spliced->readers[V_HEARTBEATINFO_ID], V_MASK_ANY, readTakeAction, &rtarg, OS_DURATION_ZERO); - c_mutexLock(&spliced->mtx); + OSPL_LOCK(spliced); while ((s = c_iterTakeFirst(rtarg.result)) != NULL) { if(v_dataReaderSampleStateTest(s, L_VALIDDATA)) { - ospl_c_insert(spliced->missedHB, c_keep(v_dataReaderSampleMessage(s))); + ospl_c_insert(spliced->missedHB, v_dataReaderSampleMessage(s)); } c_free(s); } - c_mutexUnlock(&spliced->mtx); + OSPL_UNLOCK(spliced); c_iterFree(rtarg.result); } v_leaseRenew(spliced->hbCheck, nextPeriod); } -/************************************************************** - * Public functions - **************************************************************/ void v_splicedKernelManager( v_spliced spliced) @@ -2178,6 +1858,11 @@ v_splicedKernelManager( if (builtinEnabled) { dataProcessed += v_splicedProcessSubscriptionInfo(spliced); dataProcessed += v_splicedProcessParticipantInfo(spliced); + dataProcessed += v_splicedProcessDataWriterCMInfo(spliced); + dataProcessed += v_splicedProcessDataReaderCMInfo(spliced); + dataProcessed += v_splicedProcessPublisherCMInfo(spliced); + dataProcessed += v_splicedProcessSubscriberCMInfo(spliced); + dataProcessed += v_splicedProcessParticipantCMInfo(spliced); } if (dataProcessed == 0) { (void)v_waitsetWait(spliced->ws, NULL, NULL, OS_DURATION_INFINITE); @@ -2203,7 +1888,8 @@ v_splicedCAndMCommandDispatcherQuit( c_mutexLock(&spliced->cAndMCommandMutex); spliced->cAndMCommandDispatcherQuit = TRUE; /* Wakeup the C&M command dispatcher thread to take notice and terminate. - * Waitset mask must be set sensitive to V_EVENT_TRIGGER. */ + * Waitset mask must be set sensitive to V_EVENT_TRIGGER. + */ v_waitsetTrigger(spliced->cAndMCommandWaitSet, NULL); c_mutexUnlock(&spliced->cAndMCommandMutex); } @@ -2230,10 +1916,11 @@ v_splicedBuiltinCAndMCommandDispatcher( c_mutexLock(&spliced->cAndMCommandMutex); reader = spliced->readers[V_C_AND_M_COMMAND_ID]; - boolRes = v_waitsetAttach(spliced->cAndMCommandWaitSet, (v_observable)reader, NULL); /* The V_EVENT_TRIGGER interest is used stop the C&M command dispatcher thread. */ - v_observerSetEventMask((v_observer)spliced->cAndMCommandWaitSet, V_EVENT_DATA_AVAILABLE | V_EVENT_TRIGGER); + OSPL_SET_EVENT_MASK(spliced->cAndMCommandWaitSet, V_EVENT_DATA_AVAILABLE | V_EVENT_TRIGGER); + boolRes = v_waitsetAttach(spliced->cAndMCommandWaitSet, (v_observable)reader, NULL); + assert( boolRes ); OS_UNUSED_ARG(boolRes); @@ -2255,7 +1942,6 @@ v_splicedPrepareTermination( v_spliced spliced) { C_STRUCT(v_event) term; - v_observer o; v_kernel k; k = v_objectKernel(spliced); @@ -2264,14 +1950,10 @@ v_splicedPrepareTermination( term.kind = V_EVENT_TRIGGER; term.source = v_observable(spliced); term.data = NULL; - c_mutexLock(&spliced->mtx); + OSPL_LOCK(spliced); spliced->quit = TRUE; - c_mutexUnlock(&spliced->mtx); - - o = v_observer(spliced->ws); - v_observerLock(o); - v_observerNotify(o, &term, NULL); - v_observerUnlock(o); + OSPL_TRIGGER_EVENT(v_observer(spliced->ws), &term, NULL); + OSPL_UNLOCK(spliced); } static void @@ -2372,7 +2054,7 @@ v_splicedGarbageCollectorMissedHB ( c_bool pubComplete; /* Wait for alignment of DCPSPublication topic */ - vresult = v_readerWaitForHistoricalData(v_reader(spliced->readers[V_PUBLICATIONINFO_ID]), OS_DURATION_ZERO); + vresult = v_readerWaitForHistoricalData(v_reader(spliced->readers[V_PUBLICATIONINFO_ID]), OS_DURATION_ZERO, FALSE); pubComplete = (vresult == V_RESULT_OK); OS_REPORT(OS_INFO, "v_spliced", vresult, @@ -2393,7 +2075,7 @@ v_splicedGarbageCollectorMissedHB ( */ v_groupDisconnectNode(g, systemId, cleanTime); v__kernelProtectWaitEnter(NULL, NULL); - os_sleep(delay); + ospl_os_sleep(delay); v__kernelProtectWaitExit(); c_free(g); g = NULL; @@ -2410,7 +2092,7 @@ v_splicedGarbageCollectorMissedHB ( { v_groupDisconnectNode(g, systemId, cleanTime); v__kernelProtectWaitEnter(NULL, NULL); - os_sleep(delay); + ospl_os_sleep(delay); v__kernelProtectWaitExit(); c_free(g); g = v_group(c_iterTakeFirst(groups)); @@ -2437,14 +2119,14 @@ v_spliced spliced) /* wait until kernelmanager has initialized */ while (!spliced->missedHB) { - os_sleep(delay); + ospl_os_sleep(delay); } /*Continue for as long as the spliced doesn't need to terminate*/ while (!spliced->quit) { /*Check if a heartbeat has been missed*/ - c_mutexLock(&spliced->mtx); + OSPL_LOCK(spliced); missedHBMsg = c_take(spliced->missedHB); - c_mutexUnlock(&spliced->mtx); + OSPL_UNLOCK(spliced); /* If a heartbeat has been missed, walk over all groups and clean up * data from writers on the removed node. @@ -2456,7 +2138,8 @@ v_spliced spliced) os_timeW cleanTime; if (OS_DURATION_ISINFINITE(v_durationToOsDuration(hb->period))) { /* Can't trust the time stamp in msg->writeTime: it is that of the - original write, not of the unregister */ + * original write, not of the unregister + */ cleanTime = os_timeWGet (); } else { cleanTime = os_timeWAdd (missedHBMsg->writeTime, v_durationToOsDuration(hb->period)); @@ -2475,9 +2158,9 @@ v_spliced spliced) * of purgeLists. If a heartbeat has been missed, stop * updating purgeLists. */ - c_mutexLock(&spliced->mtx); + OSPL_LOCK(spliced); length = c_tableCount(spliced->missedHB); - c_mutexUnlock(&spliced->mtx); + OSPL_UNLOCK(spliced); /* A heartbeat has been missed, stop updating purgeLists now * but don't forget to free the iter of groups. @@ -2486,7 +2169,7 @@ v_spliced spliced) g = NULL; } else { v__kernelProtectWaitEnter(NULL, NULL); - os_sleep(delay); + ospl_os_sleep(delay); v__kernelProtectWaitExit(); g = v_group(c_iterTakeFirst(groups)); } @@ -2498,7 +2181,6 @@ v_spliced spliced) c_free(g); } g = v_group(c_iterTakeFirst(groups)); - while(g != NULL) { c_free(g); g = v_group(c_iterTakeFirst(groups)); @@ -2773,121 +2455,39 @@ static void v_splicedTakeCandMCommand(v_spliced spliced) } } -struct lookupPublicationArg { - v_gid wgid; - struct v_publicationInfo *info; -}; -static c_bool -lookupPublication( - c_object o, +v_result +v_splicedWalkSubscriptions( + v_spliced spliced, + v_subscription_action action, c_voidp arg) { - v_message msg = v_message(o); - struct lookupPublicationArg *a = (struct lookupPublicationArg *)arg; - struct v_publicationInfo *info; - - info = v_builtinPublicationInfoData(msg); - if (v_gidEqual(info->key, a->wgid)) { - a->info = info; - return FALSE; - } - return TRUE; -} + v_result result = V_RESULT_OK; -v_result -v_splicedLookupPublicationInfo( - v_spliced _this, - v_gid wgid, - publicationInfoAction action, - void *arg) -{ - v_result result = V_RESULT_UNDEFINED; - c_bool found = FALSE; - struct lookupPublicationArg lpa; - - lpa.wgid = wgid; - lpa.info = NULL; - c_mutexLock(&_this->builtinDataMutex); - found = !c_walk(_this->builtinData[V_PUBLICATIONINFO_ID], lookupPublication, &lpa); - if (found && action) { - result = action(lpa.info, arg); - } - c_mutexUnlock(&_this->builtinDataMutex); - return result; -} + assert(spliced != NULL); + assert(C_TYPECHECK(spliced,v_spliced)); -#if 1 /* Following code is deprecated and must be removed as soon as group transactions no longer depends on this*/ + c_mutexLock(&spliced->builtinDataMutex); + (void)c_walk((c_collection)spliced->builtinData[V_SUBSCRIPTIONINFO_ID], (c_action)action, arg); + c_mutexUnlock(&spliced->builtinDataMutex); -struct countMatchesArg { - v_spliced spliced; - struct v_publicationInfo *pInfo; - c_ulong count; -}; + return result; +} -static c_bool -countMatches( - v_reader o, +v_result +v_splicedWalkPublications( + v_spliced spliced, + v_publication_action action, c_voidp arg) { - struct countMatchesArg *a = (struct countMatchesArg *)arg; - v_subscriptionInfoTemplate msg; - conformState state; + v_result result = V_RESULT_OK; - /* Following is a bit too expensive. - * It would be better not to create a msg and to cache the resulting lookup - * in the v_transactionPublisher for future lookups. - */ - msg = (v_subscriptionInfoTemplate) - v_builtinCreateSubscriptionInfo(v_objectKernel(o)->builtin, o); - if (msg) { - if (strcmp(msg->userData.topic_name, a->pInfo->topic_name) == 0) { - state = determineState(a->pInfo, &msg->userData); - if (state == CONFORM_STATE_OK) { - a->count++; - } - } - c_free(msg); - } - return TRUE; -} + assert(spliced != NULL); + assert(C_TYPECHECK(spliced,v_spliced)); -c_bool -v_splicedPublicationMatchCount( - v_spliced _this, - v_object scope, /* matching scope: v_kernel or v_subscriber */ - v_gid wgid, - c_ulong *count) -{ - c_bool found = FALSE; - struct lookupPublicationArg arg; - struct countMatchesArg cma; - - arg.wgid = wgid; - arg.info = NULL; - c_mutexLock(&_this->builtinDataMutex); - found = !c_walk(_this->builtinData[V_PUBLICATIONINFO_ID], lookupPublication, &arg); - c_mutexUnlock(&_this->builtinDataMutex); - if (found) { - /* Now check if the found publication matches any of the readers in the matching scope. */ - if (v_objectKind(scope) == K_SUBSCRIBER) { - cma.spliced = _this; - cma.pInfo = arg.info; - cma.count = 0; - /* Only required for subscribers, kernel scope always matches. */ - v_subscriberWalkReaders(v_subscriber(scope), countMatches, &cma); - *count = cma.count; - } else { - /* The scope is the kernel which implies the durability service. - * Completeness at the durability service depends on namespace interest but - * this dependency is not yet implemented. - * For now the assumption is made that interest always exists which implies - * that the match count is 1 (fictive durability reader). - */ - assert(v_objectKind(scope) == K_KERNEL); - *count = 1; - } - } - return found; + c_mutexLock(&spliced->builtinDataMutex); + (void)c_walk((c_collection)spliced->builtinData[V_PUBLICATIONINFO_ID], (c_action)action, arg); + c_mutexUnlock(&spliced->builtinDataMutex); + + return result; } -#endif diff --git a/src/kernel/code/v_statistics.c b/src/kernel/code/v_statistics.c index e89228261..fb130a26b 100644 --- a/src/kernel/code/v_statistics.c +++ b/src/kernel/code/v_statistics.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -73,6 +74,7 @@ v_statisticsResetField( isMin = TRUE; } } + os_free(fieldNameCopy); if (result == TRUE) { field = c_fieldNew(type , fieldName); diff --git a/src/kernel/code/v_status.c b/src/kernel/code/v_status.c index b1e325c6d..e1b25d492 100644 --- a/src/kernel/code/v_status.c +++ b/src/kernel/code/v_status.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -575,7 +576,7 @@ v_statusResetCounters( c_ulong v_statusGetMask( - v_status s) + _In_ v_status s) { c_ulong mask; @@ -628,7 +629,8 @@ v_statusCopyOut( case K_PUBLISHERSTATUS: copy = v_status(v_objectNew(kernel,K_PUBLISHERSTATUS)); /* These status are just instantations of v_status and have no - * addition attributes! */ + * addition attributes! + */ memcpy(copy, s, sizeof(C_STRUCT(v_status))); break; default: diff --git a/src/kernel/code/v_statusCondition.c b/src/kernel/code/v_statusCondition.c index 862c7ae23..92c7ccd88 100644 --- a/src/kernel/code/v_statusCondition.c +++ b/src/kernel/code/v_statusCondition.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,10 +19,9 @@ * */ #include "v_statusCondition.h" -#include "v__observer.h" -#include "v_observable.h" #include "v_public.h" -#include "v_proxy.h" +#include "v__observer.h" +#include "v__observable.h" #include "v__entity.h" #include "v__status.h" @@ -39,9 +39,8 @@ v_statusConditionNew( _this = v_statusCondition(v_objectNew(kernel,K_STATUSCONDITION)); if (_this != NULL) { v_observerInit(v_observer(_this)); - v_observerSetEventData(v_observer(_this), NULL); - v_observableAddObserver(v_observable(entity), v_observer(_this), NULL); - _this->entity = v_proxyNew(kernel, v_publicHandle(v_public(entity)), NULL); + OSPL_ADD_OBSERVER(entity, _this, V_EVENTMASK_ALL, NULL); + _this->entity = v_publicHandle(v_public(entity)); } } return _this; @@ -57,10 +56,10 @@ v_statusConditionFree( assert(_this != NULL); assert(C_TYPECHECK(_this,v_statusCondition)); - result = v_handleClaim(_this->entity->source, (v_object *)&obs); + result = v_handleClaim(_this->entity, (v_object *)&obs); if (result == V_HANDLE_OK) { - (void)v_observableRemoveObserver(obs, v_observer(_this), NULL); - (void)v_handleRelease(_this->entity->source); + (void)OSPL_REMOVE_OBSERVER(obs, _this, V_EVENTMASK_ALL, NULL); + (void)v_handleRelease(_this->entity); } v_observerFree(v_observer(_this)); } @@ -84,17 +83,16 @@ v_statusConditionSetMask( assert(_this != NULL); assert(C_TYPECHECK(_this,v_statusCondition)); - v_observerSetEventMask(v_observer(_this), mask); - - /* TODO: the following line is a shortcut to copy the trigger value from the status. - * This is needed because the condition is actually true but no event will be generated to report this. - * IMO we need to have a closer look to the whole event propagation in the near future. - */ + OSPL_SET_EVENT_MASK(_this, mask); - result = v_handleClaim(_this->entity->source, (v_object *)&entity); + result = v_handleClaim(_this->entity, (v_object *)&entity); if (result == V_HANDLE_OK) { - v_observer(_this)->eventFlags = mask & v_entityGetTriggerValue(entity); - (void)v_handleRelease(_this->entity->source); + C_STRUCT(v_event) event; + event.kind = v_entityGetTriggerValue(entity); + event.source = v_observable(entity); + event.data = NULL; + v_observerNotify(v_observer(_this), &event, NULL); + (void)v_handleRelease(_this->entity); } } @@ -109,27 +107,11 @@ v_statusConditionGetTriggerValue ( assert(_this != NULL); assert(C_TYPECHECK(_this,v_statusCondition)); - result = v_handleClaim(_this->entity->source, (v_object *)&entity); + result = v_handleClaim(_this->entity, (v_object *)&entity); if (result == V_HANDLE_OK) { -#if 0 - triggerValue = v_observerGetEventMask(v_observer(_this)); -#else - /* test doing without locking */ - triggerValue = v_observerEventMask(v_observer(_this)); -#endif - -#if 1 - /* Sync all flags with the flags of the entity to which the condition is attached */ - triggerValue &= v_statusGetMask(entity->status); -#else - /* The status condition may indicate Data Availability even if the data is already taken. - * To avoid spurious wakeups verify if Data Availability is still set on the entity itself. - */ - if ((V_EVENT_DATA_AVAILABLE & v_entityGetTriggerValue(entity)) == 0) { - triggerValue &= ~(V_EVENT_DATA_AVAILABLE); - } -#endif - (void)v_handleRelease(_this->entity->source); + triggerValue = v_entityGetTriggerValue(entity); + triggerValue &= v_observerGetEventMask(v_observer(_this)); + (void)v_handleRelease(_this->entity); } return triggerValue; diff --git a/src/kernel/code/v_subscriber.c b/src/kernel/code/v_subscriber.c index 6b362e787..c0a4572f4 100644 --- a/src/kernel/code/v_subscriber.c +++ b/src/kernel/code/v_subscriber.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -30,11 +31,13 @@ #include "v_topic.h" #include "v__partitionAdmin.h" #include "v__reader.h" +#include "v__entry.h" #include "v__deliveryService.h" +#include "v_deliveryServiceEntry.h" #include "v__builtin.h" #include "v_group.h" #include "v__observer.h" -#include "v_observable.h" +#include "v__observable.h" #include "v_listener.h" #include "v_public.h" #include "v_groupSet.h" @@ -44,6 +47,7 @@ #include "v__groupStream.h" #include "v__groupQueue.h" #include "v__networkReader.h" +#include "v_networkReaderEntry.h" #include "v__dataReader.h" #include "v_dataReaderInstance.h" #include "v__policy.h" @@ -53,70 +57,55 @@ #include "os_atomics.h" #include "v__orderedInstance.h" -/** - * Subscriber locking - * - * The subscriber has two type of locking. - * - * - subscriber lock, the subscriber has a subscriber lock (v_subscriberLock and - * v_subscriberUnlock) which protects access to the subscriber. When holding this - * lock it's NOT allowed to call operations on the readers as the lock order is - * readerLock -> subscriberLock. - * - * - access lock, this is a sort of read/write locking used when the presentation - * qos GROUP with ordering or coherency is set. This lock is used to guarantee that - * the state of the readers belonging to this subscriber is not changed after a - * BeginAccess(read) is called. When this lock is acquired via LockAccess(write) - * the state of the readers can be changed and it's allowed to take the readerLock. - * BeginAccess and LockAccess are mutual exclusive. - */ - #if 0 #define _TRACE_EVENTS_ printf #else #define _TRACE_EVENTS_(...) #endif -#define subscriberCondWait(_this) \ - c_condWait(&_this->cond, &_this->mutex); - -#define subscriberCondBroadcast(_this) \ - c_condBroadcast(&_this->cond); +/* ----------------------------------- Private ------------------------------ */ static void -subscriberLockAccessIgnoreAccessCount( - v_subscriber _this); - -/* ----------------------------------- Private ------------------------------ */ -static c_bool -qosChangedAction( +updateConnections( c_object o, - c_voidp arg) + c_iterActionArg arg) { - v_dataReader r; - - if (v_objectKind(o) == K_DATAREADER) { - r = v_dataReader(o); - v_dataReaderUpdateConnections(r,(v_dataReaderConnectionChanges *)arg); - v_dataReaderNotifyChangedQos(r); + v_kernel kernel; + v_group g; + v_partition p; + c_iterIter it; + v_dataReaderConnectionChanges *a = (v_dataReaderConnectionChanges *)arg; + v_dataReaderEntry e = v_dataReaderEntry(o);; + + kernel = v_objectKernel(v_object(e)); + it = c_iterIterGet(a->addedPartitions); + while ((p = c_iterNext(&it)) != NULL) { + g = v_groupSetCreate(kernel->groupSet,p,e->topic); + if (v_groupAddEntry(g, v_entry(e))) { + v_entryAddGroup(v_entry(e), g); + } + } + it = c_iterIterGet(a->removedPartitions); + while ((p = c_iterNext(&it)) != NULL) { + g = v_groupSetCreate(kernel->groupSet,p,e->topic); + v_groupRemoveEntry(g, v_entry(e)); + v_entryRemoveGroup(v_entry(e), g); } - - return TRUE; } /* ----------------------------------- Public ------------------------------- */ +_Check_return_ +_Ret_maybenull_ v_subscriber v_subscriberNew( - v_participant p, - const c_char *name, - v_subscriberQos qos, - c_bool enable) + _In_ v_participant p, + _In_opt_z_ const c_char *name, + _In_opt_ v_subscriberQos qos) { v_kernel kernel; v_subscriber s = NULL; v_subscriberQos q; - v_entity found; v_accessMode access; kernel = v_objectKernel(p); @@ -138,22 +127,14 @@ v_subscriberNew( q = v_subscriberQosNew(kernel, qos); if (q != NULL) { s = v_subscriber(v_objectNew(kernel,K_SUBSCRIBER)); - v_entityInit(v_entity(s), name, enable); + v_entityInit(v_entity(s), name); s->qos = q; - /* Presentation policy must be properly initialized to avoid - dirty reads. The presentation policy is overwritten once the - subscriber is enabled. */ - s->presentation = s->qos->presentation.v; s->accessCount = 0; - s->accessBusy = FALSE; - c_mutexInit(c_getBase(s), &s->mutex); - c_condInit(c_getBase(s), &s->cond, &s->mutex); - c_mutexInit(c_getBase(s), &s->sharesMutex); + c_condInit(c_getBase(s), &s->cond, &v_observable(s)->mutex); if (q->share.v.enable) { - v_lockShares(kernel); - found = v_addShareUnsafe(kernel,v_entity(s)); - if (found != v_entity(s)) { + v_subscriber found = v_kernelAddSharedSubscriber(kernel,s); + if (found != s) { /* Make sure to set the partition list to NULL, because * v_publicFree will cause a crash in the v_subscriberDeinit * otherwise. @@ -163,8 +144,6 @@ v_subscriberNew( v_publicFree(v_public(s)); /*Now free the local reference as well.*/ c_free(s); - v_subscriber(found)->shareCount++; - v_unlockShares(kernel); return c_keep(found); } s->shares = c_tableNew(v_kernelType(kernel,K_READER), @@ -184,15 +163,7 @@ v_subscriberNew( } else { s->participant = p; } - v_participantAdd(v_participant(s->participant),v_object(s)); - - if (q->share.v.enable) { - v_unlockShares(kernel); - } - if (enable) { - v_subscriberEnable(s); - } } else { OS_REPORT(OS_ERROR, "v_subscriberNew", V_RESULT_INTERNAL_ERROR, "Subscriber <%s> not created: failed to create subscriber QoS", @@ -206,51 +177,145 @@ v_subscriberNew( return s; } +static void +v__subscriberWalkReaders_nl( + v_subscriber _this, + c_action action, + c_voidp arg); + +static c_bool +collect( + _Inout_ c_object object, + _Inout_ c_voidp arg); + + +static c_bool +initGroupCoherentReader( + _Inout_ c_object object, /* v_reader */ + _Inout_ c_voidp arg /* v_transactionGroupAdmin */) +{ + v_reader r; + v_transactionGroupAdmin a; + + assert(C_TYPECHECK(object,v_dataReader)); + assert(C_TYPECHECK(arg,v_transactionGroupAdmin)); + + r = v_reader(object); + a = v_transactionGroupAdmin(arg); + + v_readerAddTransactionAdmin(r, a); + v_transactionGroupAdminAddReader(a, r); + + return TRUE; +} + +struct order_policy { + v_result result; + int count; + v_orderbyKind kind; +}; + +static c_bool +getOrderPolicy( + _Inout_ c_object object, /* v_reader */ + _Inout_ c_voidp arg /* order_policy */) +{ + c_bool proceed = TRUE; + v_reader r = v_reader(object); + struct order_policy *policy = (struct order_policy *)arg; + + assert(C_TYPECHECK(r,v_dataReader)); + + if (policy->count == 0) { + policy->kind = r->qos->orderby.v.kind; + } else if (policy->kind != r->qos->orderby.v.kind) { + policy->result = V_RESULT_INCONSISTENT_QOS; + proceed = FALSE; + } + policy->count++; + + return proceed; +} + v_result -v_subscriberEnable ( - v_subscriber _this) +v__subscriberEnable ( + _Inout_ v_subscriber _this) { v_kernel kernel; v_message builtinCMMsg; c_iter list; c_char *partitionName; - v_result result = V_RESULT_ILL_PARAM; - - if (_this) { - /* The accessLock is only used in case of group access scope, but to - to check if it should be locked, the qos is dereferenced without - locking the subscriber. This is fine as the presentation qos is - immutable, but the qos object itself can be reset. A read-only copy - is saved to make sure no invalid memory will be read. Hereafter, - only the read-only copy should be used. */ - _this->presentation = _this->qos->presentation.v; - - kernel = v_objectKernel(_this); - - v_observableAddObserver(v_observable(kernel->groupSet), - v_observer(_this), NULL); - - if (_this->qos->partition.v != NULL) { - list = v_partitionPolicySplit(_this->qos->partition); - while((partitionName = c_iterTakeFirst(list)) != NULL) { - v_subscriberSubscribe(_this,partitionName); - os_free(partitionName); - } - c_iterFree(list); + c_bool groupCoherent = FALSE; + c_iter readers = NULL; + v_entity reader; + + OSPL_LOCK(_this); + kernel = v_objectKernel(_this); + if (_this->qos->presentation.v.ordered_access) { + assert(_this->orderedInstance == NULL); + if (_this->qos->presentation.v.access_scope == V_PRESENTATION_GROUP && + _this->qos->presentation.v.coherent_access && + _this->qos->entityFactory.v.autoenable_created_entities) + { + struct order_policy policy; + policy.result = V_RESULT_OK; + policy.count = 0; + policy.kind = V_ORDERBY_RECEPTIONTIME; + v__subscriberWalkReaders_nl(_this, &getOrderPolicy, &policy); + if (policy.result != V_RESULT_OK) return policy.result; + _this->orderby = policy.kind; + _this->orderedInstance = v_orderedInstanceNew (v_entity(_this), _this->qos->presentation.v.access_scope, _this->orderby); } + } - if (_this->presentation.access_scope == V_PRESENTATION_GROUP && - _this->presentation.coherent_access) - { - _this->transactionGroupAdmin = v_transactionGroupAdminNew(v_object(_this)); + if (_this->qos->partition.v != NULL) { + list = v_partitionPolicySplit(_this->qos->partition); + while((partitionName = c_iterTakeFirst(list)) != NULL) { + v_partitionAdminFill(_this->partitions, partitionName); + os_free(partitionName); } + c_iterFree(list); + } - builtinCMMsg = v_builtinCreateCMSubscriberInfo(kernel->builtin, _this); - v_writeBuiltinTopic(kernel, V_CMSUBSCRIBERINFO_ID, builtinCMMsg); - c_free(builtinCMMsg); - result = V_RESULT_OK; + if (_this->qos->presentation.v.access_scope == V_PRESENTATION_GROUP && _this->qos->presentation.v.coherent_access) + { + groupCoherent = TRUE; + _this->transactionGroupAdmin = v_transactionGroupAdminNew(v_object(_this)); + v__subscriberWalkReaders_nl(_this, &initGroupCoherentReader, _this->transactionGroupAdmin); } - return result; + + if(_this->qos->entityFactory.v.autoenable_created_entities || groupCoherent) { + v__subscriberWalkReaders_nl(_this, &collect, &readers); + } + + /* The following operation makes the subscriber sensitive to ON_DATA_ON_READER events. */ + v_observerSetEvent(v_observer(_this), V_EVENT_ON_DATA_ON_READERS); + + OSPL_UNLOCK(_this); + + /* Call kernel beginAccess so that the alignment data doesn't change. + * This needs to be maintained until all readers are enabled and have + * retrieved their historical data. + */ + if (groupCoherent) { + v_kernelGroupTransactionBeginAccess(kernel); + } + + while((reader = c_iterTakeFirst(readers)) != NULL) { + (void)v_entityEnable(reader); + c_free(reader); + } + c_iterFree(readers); + + if (groupCoherent) { + v_kernelGroupTransactionEndAccess(kernel); + } + + builtinCMMsg = v_builtinCreateCMSubscriberInfo(kernel->builtin, _this); + v_writeBuiltinTopic(kernel, V_CMSUBSCRIBERINFO_ID, builtinCMMsg); + c_free(builtinCMMsg); + + return V_RESULT_OK; } @@ -263,24 +328,14 @@ v_subscriberFree( v_message unregisterCMMsg; v_participant p; v_reader o; - v_entity found; kernel = v_objectKernel(s); - if (s->qos->share.v.enable) { - v_lockShares(kernel); - if (--s->shareCount == 0) { - found = v_removeShareUnsafe(kernel,v_entity(s)); - assert(found == v_entity(s)); - c_free(found); - v_unlockShares(kernel); - } else { - v_unlockShares(kernel); + if (v_kernelRemoveSharedSubscriber(kernel,s) > 0) { return; } } - v_observableRemoveObserver(v_observable(kernel->groupSet),v_observer(s), NULL); builtinCMMsg = v_builtinCreateCMSubscriberInfo(kernel->builtin, s); unregisterCMMsg = v_builtinCreateCMSubscriberInfo(kernel->builtin, s); @@ -330,20 +385,9 @@ v_subscriberDeinit( } static c_bool -collectPartitions( - c_object o, - c_voidp arg) -{ - v_partition d = (v_partition)o; - c_iter iter = (c_iter)arg; - (void) c_iterInsert(iter,c_keep(d)); - return TRUE; -} - -static c_bool -collectReaders( - c_object object, - c_voidp arg) +collect( + _Inout_ c_object object, + _Inout_ c_voidp arg) { c_iter *list = (c_iter *) arg; *list = c_iterInsert(*list, c_keep(object)); @@ -352,115 +396,164 @@ collectReaders( v_result v_subscriberAddReader( - v_subscriber s, - v_reader r) + _Inout_ v_subscriber s, + _Inout_ v_reader r) +{ + v_result result; + v_reader found; + + OSPL_LOCK(s); + found = c_setInsert(s->readers, r); + if (found != r) { + result = V_RESULT_PRECONDITION_NOT_MET; + OS_REPORT(OS_ERROR, OS_FUNCTION, result, "shared <%s> name already defined", r->qos->share.v.name); + goto err; + } + + if(!v__entityDisabled_nl(v_entity(s))){ + if (s->qos->presentation.v.access_scope == V_PRESENTATION_GROUP && s->qos->presentation.v.coherent_access) { + /* No mutations to an already enabled subscriber are allowed. */ + result = V_RESULT_PRECONDITION_NOT_MET; + OS_REPORT(OS_ERROR, OS_FUNCTION, result, + "Reader <%s> could not be added to subscriber <%s>," OS_REPORT_NL + "adding a reader to a GROUP-coherent subscriber is not allowed after the subscriber has been enabled.", + v_entity(r)->name, v_entity(s)->name); + goto err_immutable; + } + } + + OSPL_UNLOCK(s); + return V_RESULT_OK; + +err_immutable: + found = c_remove(s->readers, r, NULL, NULL); + c_free(found); +err: + OSPL_UNLOCK(s); + return result; +} + +static void +connectPartition( + c_object o, + c_iterActionArg arg) { - v_result result = V_RESULT_OK; - v_reader found = NULL; - v_partition d; - c_iter iter; v_kernel kernel; - c_iter groupReaders = NULL; - c_bool groupCoherent = FALSE; + v_topic topic = NULL; + v_group g; + v_partition d = (v_partition)arg; + v_entry e = v_entry(o);; + + kernel = v_objectKernel(v_object(e)); + switch (v_objectKind(v_entry(e)->reader)) { + case K_DATAREADER: + topic = v_dataReaderEntry(e)->topic; + break; + case K_DELIVERYSERVICE: + topic = v_deliveryServiceEntry(e)->topic; + break; + default: assert(0); break; + } + g = v_groupSetCreate(kernel->groupSet,d,topic); + if (v_groupAddEntry(g, v_entry(e))) { + v_entryAddGroup(v_entry(e), g); + } +} - assert(s != NULL); - assert(r != NULL); +v_result +v_subscriberEnableReader( + _Inout_ v_subscriber s, + _Inout_ v_reader r) +{ + v_result result = V_RESULT_OK; + v_partition d; + c_iter iter = NULL; - iter = c_iterNew(NULL); - v_subscriberLock(s); - kernel = v_objectKernel(s); - if (s->presentation.ordered_access) { - if (s->presentation.access_scope == V_PRESENTATION_GROUP) { + OSPL_LOCK(s); + if ((v_objectKind(v_entity(r)) == K_DATAREADER) && + (s->qos->presentation.v.ordered_access)) { + if (s->qos->presentation.v.access_scope == V_PRESENTATION_GROUP) { if (s->orderedInstance == NULL) { - s->orderedInstance = v_orderedInstanceNew ( - v_entity(s), s->presentation.access_scope, r->qos->orderby.v.kind); - if (s->orderedInstance == NULL) { - result = V_RESULT_OUT_OF_MEMORY; - OS_REPORT (OS_ERROR, OS_FUNCTION, result, - "Could not enabled reader, failed to create ordered instance"); - } else { - v_dataReader(r)->orderedInstance = c_keep (s->orderedInstance); - } + s->orderby = r->qos->orderby.v.kind; + s->orderedInstance = v_orderedInstanceNew (v_entity(s), s->qos->presentation.v.access_scope, s->orderby); + v_dataReader(r)->orderedInstance = c_keep (s->orderedInstance); + } else if (s->orderby == r->qos->orderby.v.kind) { + v_dataReader(r)->orderedInstance = c_keep (s->orderedInstance); } else { - if (r->qos->orderby.v.kind == s->orderedInstance->orderby) { - v_dataReader(r)->orderedInstance = c_keep (s->orderedInstance); - } else { - result = V_RESULT_INCONSISTENT_QOS; - OS_REPORT (OS_ERROR, OS_FUNCTION, result, - "Could not enable reader, destination order inconsistent " - "with presentation and reader set on subscriber"); - } + result = V_RESULT_PRECONDITION_NOT_MET; } } else { assert (s->orderedInstance == NULL); assert (v_dataReader(r)->orderedInstance == NULL); - v_dataReader(r)->orderedInstance = v_orderedInstanceNew ( - v_entity(r), s->presentation.access_scope, r->qos->orderby.v.kind); - if (v_dataReader(r)->orderedInstance == NULL) { - result = V_RESULT_OUT_OF_MEMORY; - OS_REPORT (OS_ERROR, OS_FUNCTION, result, - "Could not enable reader, failed to create ordered instance"); - } + v_dataReader(r)->orderedInstance = v_orderedInstanceNew (v_entity(r), + s->qos->presentation.v.access_scope, + r->qos->orderby.v.kind); } } - - v_subscriberLockAccess(s); if (result == V_RESULT_OK) { - if (s->presentation.access_scope == V_PRESENTATION_GROUP && - s->presentation.coherent_access) { - if (s->accessCount > 0) { /* At least one begin_access one */ - OS_REPORT(OS_ERROR, "v_subscriberAddReader", V_RESULT_INTERNAL_ERROR, - "Reader <%s> could not be added to subscriber <%s>," OS_REPORT_NL - "modification not allowed with open begin_access", - v_entity(r)->name, v_entity(s)->name); - result = V_RESULT_PRECONDITION_NOT_MET; - } else { - (void)c_setWalk(s->readers, (c_action)collectReaders, &groupReaders); - v_transactionGroupAdminAddReader(s->transactionGroupAdmin, r); - groupCoherent = TRUE; - } + c_iter entries; + v_entry e; + /* Subscribe reader to all partitions of the subscriber */ + v_partitionAdminWalk(s->partitions, &collect, &iter); + OSPL_UNLOCK(s); + + /* Enable the reader: data may be delivered during the next step and events raised potentially + * trigger listeners, which would be useless on a disabled reader */ + v_entity(r)->state = V_ENTITYSTATE_ENABLED; + + entries = v_readerCollectEntries(r); + while ((d = c_iterTakeFirst(iter)) != NULL) { + c_iterWalk(entries, connectPartition, d); + c_free(d); } - } - - if (result == V_RESULT_OK) { - v_partitionAdminWalk(s->partitions,collectPartitions,iter); - found = c_setInsert(s->readers,r); - if (found != r) { - result = V_RESULT_PRECONDITION_NOT_MET; - OS_REPORT(OS_ERROR, - "v_subscriberAddReader", V_RESULT_PRECONDITION_NOT_MET, - "shared <%s> name already defined", - r->qos->share.v.name); + while ((e = c_iterTakeFirst(entries)) != NULL) { + c_free(e); } + c_iterFree(entries); + c_iterFree(iter); + } else { + OSPL_UNLOCK(s); } - v_subscriberUnlock(s); + return result; +} - if (groupCoherent) { - /* Call kernel beginAccess so that the alignment data doesn't change */ - (void)v_kernelGroupTransactionBeginAccess(kernel); - } +static void +unsubscribePartition( + c_object o, + c_voidp arg) +{ + v_partition p = v_partition(arg); + v_kind kind = v_objectKind(o); - while ((result == V_RESULT_OK) && ((d = c_iterTakeFirst(iter)) != NULL)) { - result = v_readerSubscribe(r,d); - c_free(d); - } + assert(C_TYPECHECK(o,v_entry)); + assert(C_TYPECHECK(p,v_partition)); - if (groupCoherent) { - while ((found = c_iterTakeFirst(groupReaders)) != NULL) { - v_readerGetHistoricalData(found); - c_free(found); + if (kind == K_NETWORKREADERENTRY) { + if (v_group(v_networkReaderEntry(o)->group)->partition == p) { + v_groupRemoveEntry(v_networkReaderEntry(o)->group, v_entry(o)); + v_entryRemoveGroup(v_entry(o), v_networkReaderEntry(o)->group); } - v_kernelGroupTransactionEndAccess(kernel); - v_transactionGroupAdminTrigger(s->transactionGroupAdmin, NULL); - } - v_subscriberLock(s); - v_subscriberUnlockAccess(s); - v_subscriberUnlock(s); - - c_iterFree(groupReaders); - c_iterFree(iter); + } else { + v_kernel kernel; + v_group g; + c_value params[2]; + c_iter list; - return result; + params[0] = c_objectValue(p); + switch (v_objectKind(o)) { + case K_DATAREADERENTRY: params[1] = c_objectValue(v_dataReaderEntry(o)->topic); break; + case K_DELIVERYSERVICEENTRY: params[1] = c_objectValue(v_deliveryServiceEntry(o)->topic); break; + default: assert(0); break; + } + kernel = v_objectKernel(o); + list = v_groupSetSelect(kernel->groupSet, "partition = %0 and topic = %1", params); + while ((g = c_iterTakeFirst(list)) != NULL) { + v_groupRemoveEntry(g,v_entry(o)); + v_entryRemoveGroup(v_entry(o), g); + c_free(g); + } + c_iterFree(list); + } } void @@ -470,14 +563,11 @@ v_subscriberRemoveReader( { v_reader found; v_partition d; - c_iter iter; - c_bool groupCoherent = FALSE; + c_iter iter = NULL; assert(s != NULL); assert(r != NULL); - iter = c_iterNew(NULL); - /* Prevent inappropriate notifications to Subscriber caused by the reception * of unregister messages originating from the disconnection of the group. * For this reason we set the V_EVENT_PREPARE_DELETE flag, so that it is @@ -486,121 +576,118 @@ v_subscriberRemoveReader( */ v_observerSetEvent(v_observer(r), V_EVENT_PREPARE_DELETE); - v_subscriberLock(s); - subscriberLockAccessIgnoreAccessCount(s); - if (s->presentation.access_scope == V_PRESENTATION_GROUP && - s->presentation.coherent_access) { - groupCoherent = TRUE; + OSPL_LOCK(s); + if (s->transactionGroupAdmin) { v_transactionGroupAdminRemoveReader(s->transactionGroupAdmin, r); } found = c_remove(s->readers,r,NULL,NULL); - v_partitionAdminWalk(s->partitions,collectPartitions,iter); - v_subscriberUnlock(s); - if (groupCoherent) { - v_transactionGroupAdminTrigger(s->transactionGroupAdmin, NULL); - } - v_subscriberLock(s); - v_subscriberUnlockAccess(s); - v_subscriberUnlock(s); - while ((d = c_iterTakeFirst(iter)) != NULL) { - (void)v_readerUnSubscribe(r,d); - c_free(d); + if(v__entityEnabled_nl(v_entity(s))) { + v_partitionAdminWalk(s->partitions, &collect, &iter); + + if ((s->transactionGroupAdmin) && (s->accessCount == 0)) { + /* Removal of a reader could lead to new complete transactions */ + v_transactionGroupAdminFlushPending(s->transactionGroupAdmin, NULL); + } + OSPL_UNLOCK(s); + switch(v_objectKind(r)) { + case K_DATAREADER: + case K_DELIVERYSERVICE: + case K_NETWORKREADER: + { + c_iter entries; + v_entry e; + entries = v_readerCollectEntries(r); + while ((d = c_iterTakeFirst(iter)) != NULL) { + c_iterWalk(entries, unsubscribePartition, d); + c_free(d); + } + while ((e = c_iterTakeFirst(entries)) != NULL) { + c_free(e); + } + c_iterFree(entries); + } + break; + case K_GROUPQUEUE: + while ((d = c_iterTakeFirst(iter)) != NULL) { + (void) v_groupStreamUnSubscribe(v_groupStream(r),d); + c_free(d); + } + break; + default: + OS_REPORT(OS_CRITICAL,"v_subscriberRemoveReader failed",V_RESULT_ILL_PARAM, + "illegal reader kind (%d) specified", v_objectKind(r)); + assert(FALSE); + break; + } + c_iterFree(iter); + } else { + OSPL_UNLOCK(s); } - c_iterFree(iter); c_free(found); } -void -v_subscriberWalkReaders( +static void +v__subscriberWalkReaders_nl( v_subscriber _this, - c_bool (*action)(v_reader reader, c_voidp arg), + c_action action, c_voidp arg) { - assert(_this != NULL); assert(C_TYPECHECK(_this,v_subscriber)); - v_subscriberLock(_this); - (void)c_setWalk(_this->readers,(c_action)action,arg); - v_subscriberUnlock(_this); + (void)c_setWalk(_this->readers, action, arg); } void -v_subscriberLockShares( - v_subscriber _this) +v_subscriberWalkReaders( + v_subscriber _this, + c_action action, + c_voidp arg) { - c_mutexLock(&_this->sharesMutex); -} + assert(_this != NULL); + assert(C_TYPECHECK(_this,v_subscriber)); -void -v_subscriberUnlockShares( - v_subscriber _this) -{ - c_mutexUnlock(&_this->sharesMutex); + OSPL_LOCK(_this); + v__subscriberWalkReaders_nl(_this, action, arg); + OSPL_UNLOCK(_this); } -v_reader -v_subscriberAddShareUnsafe( - v_subscriber _this, - v_reader reader) +v_dataReader +v_subscriberAddShare( + _Inout_ v_subscriber _this, + _In_ v_dataReader reader) { - v_reader found; + v_dataReader found; + OSPL_LOCK(_this); found = c_tableInsert(_this->shares,reader); + if (found != reader) { + found->shareCount++; + } + OSPL_UNLOCK(_this); return found; } -v_reader -v_subscriberRemoveShareUnsafe( +c_ulong +v_subscriberRemoveShare( v_subscriber _this, - v_reader reader) + v_dataReader reader) { - v_reader found; - - found = c_remove(_this->shares,reader,NULL,NULL); + c_ulong count; + v_dataReader found; + + OSPL_LOCK(_this); + count = --reader->shareCount; + if (count == 0){ + found = c_remove(_this->shares,reader,NULL,NULL); + c_free(found); + } + OSPL_UNLOCK(_this); - return found; + return count; } -c_bool -v_subscriberCheckPartitionInterest( - v_subscriber s, - v_partition partition) -{ - return v_partitionAdminFitsInterest(s->partitions, partition); -} - -void -v_subscriberSubscribe( - v_subscriber s, - const c_char *partitionExpr) -{ - v_partition d; - v_dataReaderConnectionChanges arg; - v_partitionPolicyI old; - - assert(s != NULL); - - arg.removedPartitions = NULL; - - v_subscriberLock(s); - arg.addedPartitions = v_partitionAdminAdd(s->partitions, partitionExpr); - old = s->qos->partition; - s->qos->partition = v_partitionPolicyAdd(old, partitionExpr, - c_getBase(c_object(s))); - c_free(old.v); - - (void)c_setWalk(s->readers, qosChangedAction, &arg); - d = v_partition(c_iterTakeFirst(arg.addedPartitions)); - while (d != NULL) { - c_free(d); - d = v_partition(c_iterTakeFirst(arg.addedPartitions)); - } - c_iterFree(arg.addedPartitions); - v_subscriberUnlock(s); -} - struct lookupReaderByTopicArg { c_iter list; const c_char *topicName; @@ -655,9 +742,9 @@ v_subscriberLookupReadersByTopic( arg.list = NULL; arg.topicName = topicName; - v_subscriberLock(s); + OSPL_LOCK(s); (void)c_setWalk(s->readers, (c_action)lookupReaderByTopic, &arg); - v_subscriberUnlock(s); + OSPL_UNLOCK(s); return arg.list; } @@ -672,9 +759,9 @@ v_subscriberLookupPartitions( assert(s != NULL); assert(C_TYPECHECK(s,v_subscriber)); - v_subscriberLock(s); + OSPL_LOCK(s); list = v_partitionAdminLookup(s->partitions, partitionExpr); - v_subscriberUnlock(s); + OSPL_UNLOCK(s); return list; } @@ -688,9 +775,9 @@ v_subscriberGetQos( assert(_this != NULL); assert(C_TYPECHECK(_this,v_subscriber)); - v_subscriberLock(_this); + OSPL_LOCK(_this); qos = c_keep(_this->qos); - v_subscriberUnlock(_this); + OSPL_UNLOCK(_this); return qos; } @@ -707,7 +794,7 @@ v_subscriberSetQos( v_dataReaderConnectionChanges arg; v_partition d; v_accessMode access; - v_message builtinCMMsg; + v_message builtinCMMsg = NULL; assert(s != NULL); assert(C_TYPECHECK(s,v_subscriber)); @@ -717,11 +804,9 @@ v_subscriberSetQos( result = v_subscriberQosCheck(tmpl); if (result == V_RESULT_OK) { - v_subscriberLock(s); kernel = v_objectKernel(s); qos = v_subscriberQosNew(kernel, tmpl); if (!qos) { - v_subscriberUnlock(s); return V_RESULT_OUT_OF_MEMORY; } @@ -740,27 +825,36 @@ v_subscriberSetQos( } if (access == V_ACCESS_MODE_READ_WRITE || access == V_ACCESS_MODE_READ) { - result = v_subscriberQosCompare(s->qos, qos, v_entityEnabled(v_entity(s)), &cm); + c_iter readers = NULL; + OSPL_LOCK(s); + result = v_subscriberQosCompare(s->qos, qos, !v__entityDisabled_nl(v_entity(s)), &cm); if ((result == V_RESULT_OK) && (cm != 0)) { - if (v_entity(s)->enabled) { - + if(v__entityEnabled_nl(v_entity(s))) { builtinCMMsg = v_builtinCreateCMSubscriberInfo (kernel->builtin, s); - } else { - builtinCMMsg = NULL; } - c_free(s->qos); s->qos = c_keep(qos); - if (cm & V_POLICY_BIT_PARTITION) { /* partition policy has changed! */ - v_partitionAdminSet(s->partitions, - s->qos->partition, - &arg.addedPartitions, - &arg.removedPartitions); + v_partitionAdminUpdate(s->partitions, + s->qos->partition, + &arg.addedPartitions, + &arg.removedPartitions); + } + v__subscriberWalkReaders_nl(s, &collect, &readers); + } + OSPL_UNLOCK(s); + if ((result == V_RESULT_OK) && (cm != 0)) { + v_reader r; + while ((r = c_iterTakeFirst(readers)) != NULL) { + v_entry e; + c_iter entries = v_readerCollectEntries(r); + c_iterWalk(entries, updateConnections, &arg); + v_readerPublishBuiltinInfo(r); + while ((e = c_iterTakeFirst(entries)) != NULL) { + c_free(e); + } + c_iterFree(entries); } - - (void)c_setWalk(s->readers, qosChangedAction, &arg); - d = v_partition(c_iterTakeFirst(arg.addedPartitions)); while (d != NULL) { c_free(d); @@ -784,64 +878,62 @@ v_subscriberSetQos( "Precondition not met: invalid Partition access mode (%d)", access); } - v_subscriberUnlock(s); c_free(qos); } return result; } -static c_bool -notifyGroupQueues( - v_reader reader, - v_group group) -{ - if(v_objectKind(reader) == K_GROUPQUEUE){ - v_groupStreamConnectNewGroups(v_groupStream(reader), group); - } - return TRUE; -} - c_bool v_subscriberConnectNewGroup( v_subscriber s, v_group g) { c_bool result = TRUE; - c_bool connect; - c_iter addedPartitions; - v_partition d; + c_bool connect = TRUE; + c_iter readers = NULL; + v_reader r; - v_subscriberLock(s); - connect = v_partitionAdminFitsInterest(s->partitions, g->partition); - if (connect) { - addedPartitions = v_partitionAdminAdd(s->partitions, - v_partitionName(g->partition)); - d = v_partition(c_iterTakeFirst(addedPartitions)); - while (d != NULL) { - c_free(d); + OSPL_LOCK(s); + v__subscriberWalkReaders_nl(s, &collect, &readers); + connect = v_partitionAdminAdd(s->partitions, g->partition); + OSPL_UNLOCK(s); - d = v_partition(c_iterTakeFirst(addedPartitions)); + if (connect) { + while ((r = c_iterTakeFirst(readers)) != NULL) { + if(v_objectKind(r) == K_GROUPQUEUE){ + v_groupStreamConnectNewGroups(v_groupStream(r), g); + } else { + c_iter entries; + v_entry e; + c_bool match; + entries = v_readerCollectEntries(r); + while ((e = c_iterTakeFirst(entries)) != NULL) { + switch (v_objectKind(e)) { + case K_DATAREADERENTRY: + match = (v_dataReaderEntry(e)->topic == g->topic); + break; + case K_DELIVERYSERVICEENTRY: + match = (v_deliveryServiceEntry(e)->topic == g->topic); + break; + case K_NETWORKREADERENTRY: + match = TRUE; + break; + default: match = FALSE; /* assert(0); */ break; + } + if (match) { + if (v_groupAddEntry(g, v_entry(e))) { + v_entryAddGroup(v_entry(e), g); + } + } + c_free(e); + } + c_iterFree(entries); + } + c_free(r); } - c_iterFree(addedPartitions); - - /* - * Before doing a walk over the Readers, raise the accessBusy flag - * and unlock the Subscriber. The accessBusy flag prevents the reader - * list from being modified during the walk, and the Subscriber lock - * must be released to avoid cross-locking, since a reader lock may be - * claimed before a Subscriber lock, but not after a Subscriber lock. - */ - v_subscriberLockAccess(s); - v_subscriberUnlock(s); - result = c_setWalk(s->readers, (c_action)v_readerSubscribeGroup, g); - - /* After the walk, reset the accessBusy flag again. */ - v_subscriberLock(s); - v_subscriberUnlockAccess(s); } else { - /* - * Check if group fits interest. This extra steps are needed because + /* Check if group fits interest. This extra steps are needed because * the groupActionStream does not create the groups that match the * subscriber qos partition expression on creation. It only needs to * connect to new groups once they are created. This is a different @@ -854,25 +946,14 @@ v_subscriberConnectNewGroup( * determine whether the groupActionStream should connect to the new * group or if it is already connected. */ - /* - * Before doing a walk over the Readers, raise the accessBusy flag - * and unlock the Subscriber. The accessBusy flag prevents the reader - * list from being modified during the walk, and the Subscriber lock - * must be released to avoid cross-locking, since a reader lock may be - * claimed before a Subscriber lock, but not after a Subscriber lock. - */ - v_subscriberLockAccess(s); - v_subscriberUnlock(s); - if (v_partitionAdminExists(s->partitions, v_partitionName(g->partition))) { - (void)c_setWalk(s->readers, (c_action)notifyGroupQueues, g); + while ((r = c_iterTakeFirst(readers)) != NULL) { + if(v_objectKind(r) == K_GROUPQUEUE){ + v_groupStreamConnectNewGroups(v_groupStream(r), g); + } + c_free(r); } - - /* After the walk, reset the accessBusy flag again. */ - v_subscriberLock(s); - v_subscriberUnlockAccess(s); } - v_subscriberUnlock(s); - + c_iterFree(readers); return result; } @@ -881,7 +962,6 @@ v_subscriberNotifyDataAvailable( v_subscriber _this, v_event e) { - v_status status; C_STRUCT(v_event) event; OS_UNUSED_ARG(e); @@ -889,45 +969,43 @@ v_subscriberNotifyDataAvailable( assert(_this != NULL); assert(C_TYPECHECK(_this,v_subscriber)); - status = v_entityStatus(v_entity(_this)); - v_statusNotifyDataOnReaders(status); - c_free(status); + OSPL_ASSERT_LOCK(_this); _TRACE_EVENTS_("v_subscriberNotifyDataAvailable: Throw ON_DATA_ON_READERS event on K_SUBSCRIBER(0x%x)\n", _this); + /* Create and throw on data on readers event. */ event.kind = V_EVENT_ON_DATA_ON_READERS; event.source = v_observable(_this); event.data = NULL; - - v_observableNotify(v_observable(_this), &event); + OSPL_TRIGGER_EVENT(_this, &event, NULL); + OSPL_THROW_EVENT(_this, &event); } -v_transactionGroupAdmin -v_subscriberLookupTransactionGroupAdmin( - v_subscriber _this) +void +v_subscriberNotify( + v_subscriber _this, + v_event event, + c_voidp userData) { - assert(_this); - assert(C_TYPECHECK(_this,v_subscriber)); + v_status status; + assert(_this != NULL); + assert(C_TYPECHECK(_this, v_subscriber)); - return _this->transactionGroupAdmin; -} + OS_UNUSED_ARG(userData); + OS_UNUSED_ARG(event); -v_presentationKind -v_subscriberAccessScope( - v_subscriber _this) -{ - assert (_this != NULL && C_TYPECHECK (_this, v_subscriber)); - - return _this->presentation.access_scope; + status = v_entityStatus(v_entity(_this)); + v_statusNotifyDataOnReaders(status); + c_free(status); } -static c_bool updateReaderPurgeList(c_object o, c_voidp arg) +static c_bool readerBeginAccess(c_object o, c_voidp arg) { v_dataReader dr = v_dataReader(o); OS_UNUSED_ARG(arg); - v_dataReaderUpdatePurgeLists(dr); + v_dataReaderBeginAccess(dr); return TRUE; } @@ -942,43 +1020,33 @@ v_subscriberBeginAccess( v_subscriber _this) { v_result result = V_RESULT_OK; - c_bool flush = FALSE; - v_transactionGroupAdmin transactionGroupAdmin; - v_subscriberLock(_this); - while (_this->accessBusy) { - subscriberCondWait(_this); + OSPL_LOCK(_this); + if(!v__entityEnabled_nl(v_entity(_this))) { + OSPL_UNLOCK(_this); + return V_RESULT_NOT_ENABLED; } - if (_this->accessCount == 0) { + if (++_this->accessCount == 1) { + (void)c_setWalk(_this->readers, readerBeginAccess, NULL); if (_this->transactionGroupAdmin) { - flush = _this->accessBusy = TRUE; -#ifndef NDEBUG - _this->accessOwner = os_threadIdToInteger(os_threadIdSelf()); -#endif - transactionGroupAdmin = c_keep(_this->transactionGroupAdmin); - } - } - _this->accessCount++; - (void)c_setWalk(_this->readers, updateReaderPurgeList, NULL); - v_subscriberUnlock(_this); - - if (flush) { - if (transactionGroupAdmin) { - v_transactionGroupAdminFlush(transactionGroupAdmin); - c_free(transactionGroupAdmin); + v_transactionGroupAdminFlush(_this->transactionGroupAdmin); } - v_subscriberLock(_this); - _this->accessBusy = FALSE; -#ifndef NDEBUG - _this->accessOwner = 0; -#endif - subscriberCondBroadcast(_this); - v_subscriberUnlock(_this); } + OSPL_UNLOCK(_this); return result; } +static c_bool +readerEndAccess( + _Inout_ c_object object, + _Inout_ c_voidp arg) +{ + OS_UNUSED_ARG(arg); + v_dataReaderEndAccess(v_dataReader(object)); + return TRUE; +} + /** * This operation is called to notify the subscriber that the user is ready * accessing the DataReaders. @@ -990,112 +1058,33 @@ v_result v_subscriberEndAccess( v_subscriber _this) { - c_bool flush = FALSE; v_result result = V_RESULT_OK; - c_iter list = NULL; - v_dataReader reader; - v_transactionGroupAdmin transactionGroupAdmin; - v_subscriberLock(_this); + OSPL_LOCK(_this); + if(!v__entityEnabled_nl(v_entity(_this))) { + OSPL_UNLOCK(_this); + OS_REPORT(OS_WARNING, "v_subscriberEndAccess", V_RESULT_NOT_ENABLED, + "Precondition not met: Subscriber not enabled"); + return V_RESULT_NOT_ENABLED; + } if (_this->accessCount > 0) { - _this->accessCount--; - flush = (_this->accessCount == 0); - if (flush) { + if (--_this->accessCount == 0) { v_orderedInstanceReset (_this->orderedInstance); - (void)c_walk(_this->readers, collectReaders, &list); - - _this->accessBusy = TRUE; /* must set to hold off others until after the flush. */ -#ifndef NDEBUG - _this->accessOwner = os_threadIdToInteger(os_threadIdSelf()); -#endif - transactionGroupAdmin = c_keep(_this->transactionGroupAdmin); + (void)c_walk(_this->readers, readerEndAccess, NULL); + if (_this->transactionGroupAdmin) { + v_transactionGroupAdminFlush(_this->transactionGroupAdmin); + } } } else { + OS_REPORT(OS_ERROR, "v_subscriberEndAccess", V_RESULT_NOT_ENABLED, + "Precondition not met: No Begin Access"); result = V_RESULT_PRECONDITION_NOT_MET; } - v_subscriberUnlock(_this); - if (flush) { - while ((reader = c_iterTakeFirst(list)) != NULL) { - v_dataReaderFlushPending(reader); - c_free(reader); - } - - if (transactionGroupAdmin) { - v_transactionGroupAdminTrigger(transactionGroupAdmin, NULL); - c_free(transactionGroupAdmin); - } - - v_subscriberLock(_this); - _this->accessBusy = FALSE; -#ifndef NDEBUG - _this->accessOwner = 0; -#endif - subscriberCondBroadcast(_this); - v_subscriberUnlock(_this); - } - c_iterFree(list); + OSPL_UNLOCK(_this); return result; } -static c_bool -v__subscriberRequireAccessLock( - v_subscriber _this) -{ - c_bool lock = FALSE; - - if (_this->presentation.access_scope == V_PRESENTATION_GROUP) { - lock = (_this->presentation.coherent_access || - _this->presentation.ordered_access); - } - - return lock; -} - -c_bool -v__subscriberRequireAccessLockCoherent( - v_subscriber _this) -{ - c_bool lock = FALSE; - - if (_this->presentation.access_scope == V_PRESENTATION_GROUP) { - lock = _this->presentation.coherent_access; - } - - return lock; -} - -c_bool -v__subscriberRequireAccessLockOrdered( - v_subscriber _this) -{ - c_bool lock = FALSE; - - if (_this->presentation.access_scope == V_PRESENTATION_GROUP) { - /* coherent_access lock out ranks ordered_access - * Coherence locks the complete set no need to lock for single samples. - */ - if (_this->presentation.coherent_access == FALSE) { - lock = _this->presentation.ordered_access; - } - } - - return lock; -} - -static v_result -testBeginAccess( - v_subscriber _this) -{ - v_result result = V_RESULT_OK; - if (v__subscriberRequireAccessLock (_this)) { - if (_this->accessCount == 0) { - result = V_RESULT_PRECONDITION_NOT_MET; - } - } - return result; -} - /** * This operation is called by read and take operations to requests access to the * history cache. This operation will verify if beginAccess is called and if set @@ -1115,18 +1104,23 @@ v_subscriberGetDataReaders( assert(_this); assert(C_TYPECHECK(_this,v_subscriber)); - v_subscriberLock(_this); - result = testBeginAccess(_this); + OSPL_LOCK(_this); + if (_this->accessCount == 0 && + (_this->qos->presentation.v.coherent_access || + _this->qos->presentation.v.ordered_access)) + { + result = V_RESULT_PRECONDITION_NOT_MET; + } if (result == V_RESULT_OK) { - if ((_this->presentation.access_scope == V_PRESENTATION_GROUP) && - (_this->presentation.ordered_access == TRUE)) + if ((_this->qos->presentation.v.access_scope == V_PRESENTATION_GROUP) && + (_this->qos->presentation.v.ordered_access == TRUE)) { list = v_orderedInstanceGetDataReaders(_this->orderedInstance, mask); } else { - (void)c_setWalk(_this->readers, (c_action)collectReaders, &list); + (void)c_setWalk(_this->readers, &collect, &list); } } - v_subscriberUnlock(_this); + OSPL_UNLOCK(_this); while ((reader = v_dataReader(c_iterTakeFirst(list)))) { if (v_dataReaderHasMatchingSamples(reader, mask)) { @@ -1139,108 +1133,20 @@ v_subscriberGetDataReaders( return result; } -v_result -v_subscriberTestBeginAccess( - v_subscriber _this) -{ - v_result result = V_RESULT_OK; - - assert (_this != NULL && C_TYPECHECK (_this, v_subscriber)); - - v_subscriberLock(_this); - result = testBeginAccess(_this); - v_subscriberUnlock(_this); - return result; -} - -/* subscriberLock required before calling this function */ -static void -subscriberLockAccessIgnoreAccessCount( - v_subscriber _this) -{ - while (_this->accessBusy) { - subscriberCondWait(_this); - } - _this->accessBusy = TRUE; -#ifndef NDEBUG - _this->accessOwner = os_threadIdToInteger(os_threadIdSelf()); -#endif -} - -/* v_subscriberLock required before calling this function */ -void -v_subscriberLockAccess( - v_subscriber _this) -{ - while (_this->accessCount > 0 || _this->accessBusy) { - subscriberCondWait(_this); - } - _this->accessBusy = TRUE; -#ifndef NDEBUG - _this->accessOwner = os_threadIdToInteger(os_threadIdSelf()); -#endif -} - -/* v_subscriberLock required before calling this function */ -c_bool -v_subscriberTryLockAccess( - v_subscriber _this) -{ - c_bool result = FALSE; - - if (_this->accessCount > 0 || _this->accessBusy) { - /* Unable to get lock */ - } else { - result = _this->accessBusy = TRUE; -#ifndef NDEBUG - _this->accessOwner = os_threadIdToInteger(os_threadIdSelf()); -#endif - } - - return result; -} - -/* v_subscriberLock required before calling this function */ void -v_subscriberUnlockAccess( +v_subscriberGroupTransactionFlush( v_subscriber _this) { - if (_this->accessBusy) { - _this->accessBusy = FALSE; -#ifndef NDEBUG - _this->accessOwner = 0; -#endif - subscriberCondBroadcast(_this); - } -} - -static void -subscriberTriggerGroupCoherentNoLock( - v_subscriber _this, - v_reader owner) -{ - c_bool accessLock; - - assert(_this->presentation.access_scope == V_PRESENTATION_GROUP); - assert(_this->presentation.coherent_access == TRUE); + assert(_this != NULL); + assert(C_TYPECHECK(_this,v_subscriber)); - accessLock = v_subscriberTryLockAccess(_this); - if (accessLock) { - v_subscriberUnlock(_this); - v_transactionGroupAdminTrigger(_this->transactionGroupAdmin, owner); - v_subscriberLock(_this); - v_subscriberUnlockAccess(_this); + OSPL_LOCK(_this); + if (v__entityEnabled_nl(v_entity(_this)) && v_subscriberQosIsGroupCoherent(_this->qos)) { + if (_this->accessCount == 0) { + v_transactionGroupAdminFlushPending(_this->transactionGroupAdmin, NULL); + } } -} - -void -v_subscriberTriggerGroupCoherent( - v_subscriber _this, - v_reader owner) -{ - v_subscriberLock(_this); - subscriberTriggerGroupCoherentNoLock(_this, owner); - v_subscriberUnlock(_this); + OSPL_UNLOCK(_this); } void @@ -1248,22 +1154,24 @@ v_subscriberNotifyGroupCoherentPublication( v_subscriber _this, v_message msg) { - v_subscriberLock(_this); - if ((_this->presentation.access_scope == V_PRESENTATION_GROUP) && - (_this->presentation.coherent_access == TRUE)) + OSPL_LOCK(_this); + if ((_this->qos->presentation.v.access_scope == V_PRESENTATION_GROUP) && + (_this->qos->presentation.v.coherent_access == TRUE)) { c_bool dispose = FALSE; struct v_publicationInfo *info = v_builtinPublicationInfoData(msg); if (v_stateTest(v_nodeState(msg), L_DISPOSED)) { dispose = TRUE; } -/* Need this check to avoid crashes until OSPL-7992 is solved. */ -if (_this->transactionGroupAdmin && _this->participant) { - if (v_transactionGroupAdminNotifyGroupCoherentPublication(_this->transactionGroupAdmin, NULL, dispose, info) == TRUE) { - subscriberTriggerGroupCoherentNoLock(_this, NULL); + /* Need this check to avoid crashes until OSPL-7992 is solved. */ + if (_this->transactionGroupAdmin && _this->participant) { + if (v_transactionGroupAdminNotifyPublication(_this->transactionGroupAdmin, NULL, dispose, info) == TRUE) { + /* Receiving a DCPSPublication could lead to a complete group transaction */ + if (_this->accessCount == 0) { + v_transactionGroupAdminFlush(_this->transactionGroupAdmin); + } + } } -} } - - v_subscriberUnlock(_this); + OSPL_UNLOCK(_this); } diff --git a/src/kernel/code/v_subscriberQos.c b/src/kernel/code/v_subscriberQos.c index e9bfa299e..48cac1bbb 100644 --- a/src/kernel/code/v_subscriberQos.c +++ b/src/kernel/code/v_subscriberQos.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,10 +28,6 @@ static const v_qosChangeMask immutableMask = V_POLICY_BIT_PRESENTATION; - -/************************************************************** - * private functions - **************************************************************/ static c_bool v_subscriberQosValidValues( v_subscriberQos qos) @@ -53,13 +50,12 @@ v_subscriberQosValidValues( return (valuesNok) ? FALSE : TRUE; } -/************************************************************** - * constructor/destructor - **************************************************************/ +_Check_return_ +_When_(template, _Ret_maybenull_) v_subscriberQos v_subscriberQosNew( - v_kernel kernel, - v_subscriberQos template) + _In_ v_kernel kernel, + _In_opt_ v_subscriberQos template) { v_subscriberQos q; c_base base; @@ -68,40 +64,38 @@ v_subscriberQosNew( assert(C_TYPECHECK(kernel,v_kernel)); base = c_getBase(c_object(kernel)); - q = v_subscriberQos(v_qosCreate(base,V_SUBSCRIBER_QOS)); - - if (q != NULL) { - if (template != NULL) { - q->groupData.v.size = template->groupData.v.size; - if (template->groupData.v.size > 0) { - q->groupData.v.value = c_arrayNew_s(c_octet_t(base),(c_ulong)template->groupData.v.size); - if (q->groupData.v.value) { - memcpy(q->groupData.v.value,template->groupData.v.value,(c_ulong)template->groupData.v.size); - } else { - OS_REPORT(OS_ERROR, "v_subscriberQosNew", V_RESULT_OUT_OF_MEMORY, - "Failed to allocate group_data policy of subscriber QoS."); - c_free(q); - return NULL; - } + q = v_subscriberQos(v_qosCreate(base,V_SUBSCRIBER_QOS)); + + if (template != NULL) { + q->groupData.v.size = template->groupData.v.size; + if (template->groupData.v.size > 0) { + q->groupData.v.value = c_arrayNew_s(c_octet_t(base),(c_ulong)template->groupData.v.size); + if (q->groupData.v.value) { + memcpy(q->groupData.v.value,template->groupData.v.value,(c_ulong)template->groupData.v.size); } else { - q->groupData.v.value = NULL; + OS_REPORT(OS_ERROR, "v_subscriberQosNew", V_RESULT_OUT_OF_MEMORY, + "Failed to allocate group_data policy of subscriber QoS."); + c_free(q); + return NULL; } - q->partition.v = c_stringNew(base,template->partition.v); - q->presentation = template->presentation; - q->share.v.enable = template->share.v.enable; - q->share.v.name = c_stringNew(base,template->share.v.name); - q->entityFactory = template->entityFactory; } else { - q->groupData.v.value = NULL; - q->groupData.v.size = 0; - q->presentation.v.access_scope = V_PRESENTATION_INSTANCE; - q->presentation.v.coherent_access = FALSE; - q->presentation.v.ordered_access = FALSE; - q->partition.v = c_stringNew(base, ""); - q->share.v.enable = FALSE; - q->share.v.name = NULL; - q->entityFactory.v.autoenable_created_entities = TRUE; + q->groupData.v.value = NULL; } + q->partition.v = c_stringNew(base,template->partition.v); + q->presentation = template->presentation; + q->share.v.enable = template->share.v.enable; + q->share.v.name = c_stringNew(base,template->share.v.name); + q->entityFactory = template->entityFactory; + } else { + q->groupData.v.value = NULL; + q->groupData.v.size = 0; + q->presentation.v.access_scope = V_PRESENTATION_INSTANCE; + q->presentation.v.coherent_access = FALSE; + q->presentation.v.ordered_access = FALSE; + q->partition.v = c_stringNew(base, ""); + q->share.v.enable = FALSE; + q->share.v.name = NULL; + q->entityFactory.v.autoenable_created_entities = TRUE; } return q; @@ -109,59 +103,74 @@ v_subscriberQosNew( void v_subscriberQosFree( - v_subscriberQos q) + _In_opt_ _Post_invalid_ v_subscriberQos q) { c_free(q); } -/************************************************************** - * Protected functions - **************************************************************/ +_Success_(return == V_RESULT_OK) v_result v_subscriberQosCompare( - v_subscriberQos q, - v_subscriberQos tmpl, - c_bool enabled, - v_qosChangeMask *changeMask) + _In_ v_subscriberQos q, + _In_ v_subscriberQos tmpl, + _In_ c_bool enabled, + _Out_ v_qosChangeMask *changeMask) { - v_qosChangeMask cm; + v_qosChangeMask cm, immutable; v_result result; cm = 0; - if ((q != NULL) && (tmpl != NULL) && (changeMask != NULL)) { - /* built change mask */ - if (!v_presentationPolicyIEqual(q->presentation, tmpl->presentation)) { - cm |= V_POLICY_BIT_PRESENTATION; - } - if (!v_partitionPolicyIEqual(q->partition, tmpl->partition)) { - cm |= V_POLICY_BIT_PARTITION; - } - if (!v_groupDataPolicyIEqual(q->groupData, tmpl->groupData)) { - cm |= V_POLICY_BIT_GROUPDATA; - } - if (!v_entityFactoryPolicyIEqual(q->entityFactory, tmpl->entityFactory)) { - cm |= V_POLICY_BIT_ENTITYFACTORY; - } - /* check whether immutable policies are changed */ - if (((cm & immutableMask) != 0) && enabled) { - v_policyReportImmutable(cm, immutableMask); - result = V_RESULT_IMMUTABLE_POLICY; - } else { - *changeMask = cm; - result = V_RESULT_OK; - } + immutable = immutableMask; + if(enabled && v_subscriberQosIsGroupCoherent(q)) { + /* A group-coherent subscriber cannot be changed at all after it has + * been enabled. + */ + immutable |= V_POLICY_BIT_PARTITION; + /* Changing V_POLICY_BIT_GROUPDATA shouldn't matter, since it doesn't + * influence the middleware at all, but for now we block all changes. + */ + immutable |= V_POLICY_BIT_GROUPDATA; + /* Changing V_POLICY_BIT_ENTITYFACTORY shouldn't matter, since it is + * ignored anyway for a group-coherent subscriber. + */ + immutable |= V_POLICY_BIT_ENTITYFACTORY; + } + + /* built change mask */ + if (!v_presentationPolicyIEqual(q->presentation, tmpl->presentation)) { + cm |= V_POLICY_BIT_PRESENTATION; + } + if (!v_partitionPolicyIEqual(q->partition, tmpl->partition)) { + cm |= V_POLICY_BIT_PARTITION; + } + if (!v_groupDataPolicyIEqual(q->groupData, tmpl->groupData)) { + cm |= V_POLICY_BIT_GROUPDATA; + } + if (!v_entityFactoryPolicyIEqual(q->entityFactory, tmpl->entityFactory)) { + cm |= V_POLICY_BIT_ENTITYFACTORY; + } + /* check whether immutable policies are changed */ + if (((cm & immutable) != 0) && enabled) { + v_policyReportImmutable(cm, immutable); + result = V_RESULT_IMMUTABLE_POLICY; } else { - result = V_RESULT_ILL_PARAM; + *changeMask = cm; + result = V_RESULT_OK; } + return result; } -/************************************************************** - * Public functions - **************************************************************/ +c_bool +v_subscriberQosIsGroupCoherent ( + _In_ _Const_ v_subscriberQos _this) +{ + return _this->presentation.v.coherent_access && _this->presentation.v.access_scope == V_PRESENTATION_GROUP; +} + v_result v_subscriberQosCheck( - v_subscriberQos _this) + _In_opt_ v_subscriberQos _this) { v_result result = V_RESULT_OK; diff --git a/src/kernel/code/v_threadInfo.c b/src/kernel/code/v_threadInfo.c index 56363d471..4a9d90906 100644 --- a/src/kernel/code/v_threadInfo.c +++ b/src/kernel/code/v_threadInfo.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/code/v_time.c b/src/kernel/code/v_time.c index de55a811b..cb24df3c8 100644 --- a/src/kernel/code/v_time.c +++ b/src/kernel/code/v_time.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/code/v_timedValue.c b/src/kernel/code/v_timedValue.c index 0a7685c2f..49d3dfe71 100644 --- a/src/kernel/code/v_timedValue.c +++ b/src/kernel/code/v_timedValue.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/code/v_topic.c b/src/kernel/code/v_topic.c index 3c5d6e07e..7da357be2 100644 --- a/src/kernel/code/v_topic.c +++ b/src/kernel/code/v_topic.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -65,8 +66,8 @@ v_topicFree( } v_result -v_topicEnable( - v_topic _this) +v__topicEnable( + _Inout_ v_topic _this) { v_topicImpl ti; @@ -75,7 +76,8 @@ v_topicEnable( } else { ti = v_topicAdapter(_this)->topic; } - return v_topicImplEnable(ti); + assert(ti); + return v__topicImplEnable(ti); } v_topicQos @@ -267,35 +269,20 @@ v_topicMetaDescriptor ( return v_topicImplMetaDescriptor(ti); } - -void -v_topicNotify ( - v_topic _this, - v_event event, - c_voidp userData) -{ - v_topicImpl ti; - - if (v_objectKind(_this) == K_TOPIC) { - ti = v_topicImpl(_this); - } else { - ti = v_topicAdapter(_this)->topic; - } - v_topicImplNotify(ti, event, userData); -} - void v_topicNotifyInconsistentTopic ( v_topic _this) { v_topicImpl ti; + OSPL_LOCK(_this); if (v_objectKind(_this) == K_TOPIC) { ti = v_topicImpl(_this); } else { ti = v_topicAdapter(_this)->topic; } v_topicImplNotifyInconsistentTopic(ti); + OSPL_UNLOCK(_this); } void @@ -304,12 +291,14 @@ v_topicNotifyAllDataDisposed( { v_topicImpl ti; + OSPL_LOCK(_this); if (v_objectKind(_this) == K_TOPIC) { ti = v_topicImpl(_this); } else { ti = v_topicAdapter(_this)->topic; } v_topicImplNotifyAllDataDisposed(ti); + OSPL_UNLOCK(_this); } void diff --git a/src/kernel/code/v_topicAdapter.c b/src/kernel/code/v_topicAdapter.c index 5ea81ae55..20b958be4 100644 --- a/src/kernel/code/v_topicAdapter.c +++ b/src/kernel/code/v_topicAdapter.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -43,20 +44,21 @@ v_topicAdapterInit( v_participant p, const c_char *name) { + v_eventMask mask = V_EVENT_ALL_DATA_DISPOSED | V_EVENT_INCONSISTENT_TOPIC; + assert(adapter != NULL); assert(p != NULL); assert(C_TYPECHECK(adapter, v_topicAdapter)); assert(C_TYPECHECK(p,v_participant)); assert(C_TYPECHECK(topic,v_topic)); - v_entityInit(v_entity(adapter), name, TRUE); - + v_entityInit(v_entity(adapter), name); adapter->topic = c_keep(topic); + (void)v_entityEnable(v_entity(adapter)); - (void)v_observerSetEvent(v_observer(adapter), V_EVENT_ALL_DATA_DISPOSED | V_EVENT_INCONSISTENT_TOPIC); + (void)v_observerSetEvent(v_observer(adapter), mask); - v_observableAddObserver(v_observable(topic), v_observer(adapter), NULL); - v_observableAddObserver(v_observable(adapter), v_observer(p), NULL); + OSPL_ADD_OBSERVER(topic, adapter, mask, NULL); v_participantAdd(p, v_object(adapter)); v_topic(adapter)->owner = p; } @@ -148,8 +150,8 @@ v_topicAdapterFree( p = v_topicAdapterParticipant(adapter); - v_observableRemoveObserver(v_observable(adapter->topic), v_observer(adapter), NULL); - v_observableRemoveObserver(v_observable(adapter), v_observer(p), NULL); + OSPL_REMOVE_OBSERVER(adapter->topic, adapter, V_EVENTMASK_ALL, NULL); + OSPL_REMOVE_OBSERVER(adapter, p, V_EVENTMASK_ALL, NULL); if (p != NULL) { v_participantRemove(p,v_object(adapter)); @@ -176,32 +178,28 @@ v_topicAdapterNotify( { C_STRUCT(v_event) e; c_bool forward = TRUE; - c_bool notified; OS_UNUSED_ARG(userData); + assert(adapter != NULL); assert(C_TYPECHECK(adapter,v_topicAdapter)); - - if (event != NULL) { - switch (event->kind) { - case V_EVENT_ALL_DATA_DISPOSED: - v_statusNotifyAllDataDisposed(v_entity(adapter)->status); - break; - case V_EVENT_INCONSISTENT_TOPIC: - v_statusNotifyInconsistentTopic(v_entity(adapter)->status); - break; - default: - forward = FALSE; - break; - } - if (forward) { - e.kind = event->kind; - e.source = v_observable(adapter); - e.data = NULL; - notified = v_entityNotifyListener(v_entity(adapter), &e); - if (!notified) { - v_observableNotify(v_observable(adapter), &e); - } - } + assert(event != NULL); + + switch (event->kind) { + case V_EVENT_ALL_DATA_DISPOSED: + v_statusNotifyAllDataDisposed(v_entity(adapter)->status); + break; + case V_EVENT_INCONSISTENT_TOPIC: + v_statusNotifyInconsistentTopic(v_entity(adapter)->status); + break; + default: + forward = FALSE; + break; + } + if (forward) { + e.kind = event->kind; + e.source = v_observable(adapter); + e.data = NULL; + (void)v_entityNotifyListener(v_entity(adapter), &e); } } @@ -219,14 +217,14 @@ v_topicAdapterGetInconsistentTopicStatus( result = V_RESULT_PRECONDITION_NOT_MET; if (_this != NULL) { - v_observerLock(v_observer(_this)); + OSPL_LOCK(_this); status = v_entity(_this)->status; result = action(&v_topicStatus(status)->inconsistentTopic, arg); if (reset) { v_statusReset(status, V_EVENT_INCONSISTENT_TOPIC); } v_topicStatus(status)->inconsistentTopic.totalChanged = 0; - v_observerUnlock(v_observer(_this)); + OSPL_UNLOCK(_this); } return result; @@ -246,14 +244,14 @@ v_topicAdapterGetAllDataDisposedStatus( result = V_RESULT_PRECONDITION_NOT_MET; if (_this != NULL) { - v_observerLock(v_observer(_this)); + OSPL_LOCK(_this); status = v_entity(_this)->status; result = action(&v_topicStatus(status)->allDataDisposed, arg); if (reset) { v_statusReset(status, V_EVENT_ALL_DATA_DISPOSED); } v_topicStatus(status)->allDataDisposed.totalChanged = 0; - v_observerUnlock(v_observer(_this)); + OSPL_UNLOCK(_this); } return result; diff --git a/src/kernel/code/v_topicImpl.c b/src/kernel/code/v_topicImpl.c index 8885aaea5..0dae790e7 100644 --- a/src/kernel/code/v_topicImpl.c +++ b/src/kernel/code/v_topicImpl.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -56,14 +57,43 @@ v_partitionDetermineTopicAccessMode( const c_char* topicName, v_kernel kernel); +static c_type +messageTypeExtNew( + v_kernel kernel, + c_type dataType) +{ + c_base base; + c_metaObject o; + c_type type; + + static const char baseTypeName[] = "kernelModule::v_messageExt"; + + assert(C_TYPECHECK(kernel,v_kernel)); + + base = c_getBase(kernel); + assert (base); + + type = c_type(c_metaDefine(c_metaObject(base),M_CLASS)); + c_class(type)->extends = c_class(c_resolve(base, baseTypeName)); + assert(c_class(type)->extends); + o = c_metaDeclare(c_metaObject(type), USERDATA_FIELD_NAME, M_ATTRIBUTE); + c_property(o)->type = dataType; + c_free(o); + c_metaObject(type)->definedIn = c_keep(base); + c_metaFinalize(c_metaObject(type)); + + return type; +} + static c_type messageTypeNew( v_kernel kernel, - const c_char *typeName) + c_type dataType) { c_base base; c_metaObject o; - c_type baseType,dataType,type, foundType; + c_type baseType, type, foundType; + c_char *typeName; c_char *name; os_size_t length; int sres; @@ -71,23 +101,9 @@ messageTypeNew( assert(C_TYPECHECK(kernel,v_kernel)); base = c_getBase(kernel); - if (base == NULL) { - OS_REPORT(OS_ERROR, - "v_topic::messageTypeNew", V_RESULT_INTERNAL_ERROR, - "Could not create type 'v_message<%s>', " - "invalid kernel reference.", - typeName); - return NULL; - } - dataType = c_resolve(base,typeName); - if (dataType == NULL) { - OS_REPORT(OS_ERROR, - "v_topic::messageTypeNew", V_RESULT_INTERNAL_ERROR, - "Could not create type 'v_message<%s>', unknown type '%s'.", - typeName, typeName); - return NULL; - } -/* TODO: wrong place to do kernel locking, so v_kernelType should deal with it. */ + assert (base); + + /* TODO: wrong place to do kernel locking, so v_kernelType should deal with it. */ c_lockWrite(&kernel->lock); baseType = v_kernelType(kernel,K_MESSAGE); c_lockUnlock(&kernel->lock); @@ -95,9 +111,7 @@ messageTypeNew( type = c_type(c_metaDefine(c_metaObject(base),M_CLASS)); c_class(type)->extends = c_keep(c_class(baseType)); - o = c_metaDeclare(c_metaObject(type), - USERDATA_FIELD_NAME, - M_ATTRIBUTE); + o = c_metaDeclare(c_metaObject(type), USERDATA_FIELD_NAME, M_ATTRIBUTE); c_property(o)->type = dataType; c_free(o); c_metaObject(type)->definedIn = c_keep(base); @@ -106,11 +120,13 @@ messageTypeNew( #define MESSAGE_FORMAT "v_message<%s>" #define MESSAGE_NAME "v_message<>" + typeName = c_metaScopedName(c_metaObject(dataType)); length = sizeof(MESSAGE_NAME) + strlen(typeName); /* sizeof contains \0 */ name = os_malloc(length); sres = snprintf(name,length,MESSAGE_FORMAT,typeName); assert(sres >= 0 && (os_size_t) sres == (length-1)); OS_UNUSED_ARG(sres); + os_free(typeName); #undef MESSAGE_FORMAT #undef MESSAGE_NAME foundType = c_type(c_metaBind(c_metaObject(base),name,c_metaObject(type))); @@ -359,133 +375,101 @@ static c_bool isTopicConsistent( const v_topicImpl found, const c_char *name, - const c_char *typeName, + const c_type type, const v_topicQos qos, const c_char *keyExpr) { c_bool consistent = TRUE; - c_bool equal; - - if (c_compareString(v_topicName(found), name) == C_EQ) { - c_char *rTypeName = c_metaScopedName(c_metaObject(found->dataType)); - equal = (c_compareString(rTypeName, typeName) == C_EQ); - if (equal == TRUE) { - if (found->qos) { - c_bool valid = v_durabilityPolicyIEqual(found->qos->durability, qos->durability); - if (!valid) { - OS_REPORT(OS_WARNING, "v_topicNew", V_RESULT_INCONSISTENT_QOS, - "Create Topic <%s> failed: Unmatching QoS Policy: 'Durability'.", - name); - consistent = FALSE; - } - valid = v_durabilityServicePolicyIEqual(found->qos->durabilityService, qos->durabilityService); - if (!valid) { - OS_REPORT(OS_WARNING, "v_topicNew", V_RESULT_INCONSISTENT_QOS, - "Create Topic <%s> failed: Unmatching QoS Policy: 'DurabilityService'.", - name); - consistent = FALSE; - } - valid = v_deadlinePolicyIEqual(found->qos->deadline, qos->deadline); - if (!valid) { - OS_REPORT(OS_WARNING, "v_topicNew", V_RESULT_INCONSISTENT_QOS, - "Create Topic <%s> failed: Unmatching QoS Policy: 'Deadline'.", - name); - consistent = FALSE; - } - valid = v_latencyPolicyIEqual(found->qos->latency, qos->latency); - if (!valid) { - OS_REPORT(OS_WARNING, "v_topicNew", V_RESULT_INCONSISTENT_QOS, - "Create Topic <%s> failed: Unmatching QoS Policy: 'Latency'.", - name); - consistent = FALSE; - } - valid = v_livelinessPolicyIEqual(found->qos->liveliness, qos->liveliness); - if (!valid) { - OS_REPORT(OS_WARNING, "v_topicNew", V_RESULT_INCONSISTENT_QOS, - "Create Topic <%s> failed: Unmatching QoS Policy: 'Liveliness'.", - name); - consistent = FALSE; - } - valid = v_reliabilityPolicyIEqual(found->qos->reliability, qos->reliability); - if (!valid) { - OS_REPORT(OS_WARNING, "v_topicNew", V_RESULT_INCONSISTENT_QOS, - "Create Topic <%s> failed: Unmatching QoS Policy: 'Reliability'.", - name); - consistent = FALSE; - } - valid = v_orderbyPolicyIEqual(found->qos->orderby, qos->orderby); - if (!valid) { - OS_REPORT(OS_WARNING, "v_topicNew", V_RESULT_INCONSISTENT_QOS, - "Create Topic <%s> failed: Unmatching QoS Policy: 'OrderBy'.", - name); - consistent = FALSE; - } - valid = v_resourcePolicyIEqual(found->qos->resource, qos->resource); - if (!valid) { - OS_REPORT(OS_WARNING, "v_topicNew", V_RESULT_INCONSISTENT_QOS, - "Create Topic <%s> failed: Unmatching QoS Policy: 'Resource'.", - name); - consistent = FALSE; - } - valid = v_transportPolicyIEqual(found->qos->transport, qos->transport); - if (!valid) { - OS_REPORT(OS_WARNING, "v_topicNew", V_RESULT_INCONSISTENT_QOS, - "Create Topic <%s> failed: Unmatching QoS Policy: 'Transport'.", - name); - consistent = FALSE; - } - valid = v_lifespanPolicyIEqual(found->qos->lifespan, qos->lifespan); - if (!valid) { - OS_REPORT(OS_WARNING, "v_topicNew", V_RESULT_INCONSISTENT_QOS, - "Create Topic <%s> failed: Unmatching QoS Policy: 'Lifespan'.", - name); - consistent = FALSE; - } - valid = v_ownershipPolicyIEqual(found->qos->ownership, qos->ownership); - if (!valid) { - OS_REPORT(OS_WARNING, "v_topicNew", V_RESULT_INCONSISTENT_QOS, - "Create Topic <%s> failed: Unmatching QoS Policy: 'Ownership'.", - name); - consistent = FALSE; - } - valid = v_historyPolicyIEqual(found->qos->history, qos->history); - if (!valid) { - OS_REPORT(OS_WARNING, "v_topicNew", V_RESULT_INCONSISTENT_QOS, - "Create Topic <%s> failed: Unmatching QoS Policy: 'History'.", - name); - consistent = FALSE; - } - } else { - OS_REPORT(OS_WARNING, "v_topicNew", V_RESULT_INCONSISTENT_QOS, - "Create Topic \"%s\" failed: QoS value undefined", - name); - consistent = FALSE; - } - if (equal == TRUE) { - c_bool valid = keysConsistent(found, keyExpr); - if (!valid) - { - OS_REPORT(OS_ERROR, "v_topicNew", V_RESULT_INCONSISTENT_QOS, - "Precondition not met: Topic (%s) key \"%s\" doesn't match already existing Topic key \"%s\".", - name, keyExpr?keyExpr:"NULL", - found->keyExpr?found->keyExpr:"NULL"); - consistent = FALSE; - } - } - } else { - OS_REPORT(OS_ERROR, "v_topicNew", V_RESULT_INCONSISTENT_QOS, - "Precondition not met: Create Topic \"%s\" failed: typename <%s> differs exiting definition <%s>.", - name, rTypeName, typeName); - consistent = FALSE; - } - os_free(rTypeName); - } else { + + if (c_compareString(v_topicName(found), name) != C_EQ) { OS_REPORT(OS_ERROR, "v_topicNew", V_RESULT_INCONSISTENT_QOS, - "Precondition not met: Create Topic \"%s\" failed: name <%s> differs existing name <%s>.", - name, name, v_topicName(found)); - consistent = FALSE; + "Precondition not met: Create Topic \"%s\" failed: name <%s> differs existing name <%s>.", + name, name, v_topicName(found)); + return FALSE; + } + if (found->dataType != type) { + c_char *typeName1 = c_metaScopedName(c_metaObject(found->dataType)); + c_char *typeName2 = c_metaScopedName(c_metaObject(type)); + OS_REPORT(OS_ERROR, "v_topicNew", V_RESULT_INCONSISTENT_QOS, + "Precondition not met: Create Topic \"%s\" failed: type <%s> differs existing type <%s>.", + name, typeName2, typeName1); + os_free(typeName1); + os_free(typeName2); + return FALSE; + } + + if (found->qos == NULL) { + OS_REPORT(OS_WARNING, "v_topicNew", V_RESULT_INCONSISTENT_QOS, + "Create Topic \"%s\" failed: QoS value undefined", name); + return FALSE; } + if (!v_durabilityPolicyIEqual(found->qos->durability, qos->durability)) { + OS_REPORT(OS_WARNING, "v_topicNew", V_RESULT_INCONSISTENT_QOS, + "Create Topic <%s> failed: Unmatching QoS Policy: 'Durability'.", name); + consistent = FALSE; + } + if (!v_durabilityServicePolicyIEqual(found->qos->durabilityService, qos->durabilityService)) { + OS_REPORT(OS_WARNING, "v_topicNew", V_RESULT_INCONSISTENT_QOS, + "Create Topic <%s> failed: Unmatching QoS Policy: 'DurabilityService'.", name); + consistent = FALSE; + } + if (!v_deadlinePolicyIEqual(found->qos->deadline, qos->deadline)) { + OS_REPORT(OS_WARNING, "v_topicNew", V_RESULT_INCONSISTENT_QOS, + "Create Topic <%s> failed: Unmatching QoS Policy: 'Deadline'.", name); + consistent = FALSE; + } + if (!v_latencyPolicyIEqual(found->qos->latency, qos->latency)) { + OS_REPORT(OS_WARNING, "v_topicNew", V_RESULT_INCONSISTENT_QOS, + "Create Topic <%s> failed: Unmatching QoS Policy: 'Latency'.", name); + consistent = FALSE; + } + if (!v_livelinessPolicyIEqual(found->qos->liveliness, qos->liveliness)) { + OS_REPORT(OS_WARNING, "v_topicNew", V_RESULT_INCONSISTENT_QOS, + "Create Topic <%s> failed: Unmatching QoS Policy: 'Liveliness'.", name); + consistent = FALSE; + } + if (!v_reliabilityPolicyIEqual(found->qos->reliability, qos->reliability)) { + OS_REPORT(OS_WARNING, "v_topicNew", V_RESULT_INCONSISTENT_QOS, + "Create Topic <%s> failed: Unmatching QoS Policy: 'Reliability'.", name); + consistent = FALSE; + } + if (!v_orderbyPolicyIEqual(found->qos->orderby, qos->orderby)) { + OS_REPORT(OS_WARNING, "v_topicNew", V_RESULT_INCONSISTENT_QOS, + "Create Topic <%s> failed: Unmatching QoS Policy: 'OrderBy'.", name); + consistent = FALSE; + } + if (!v_resourcePolicyIEqual(found->qos->resource, qos->resource)) { + OS_REPORT(OS_WARNING, "v_topicNew", V_RESULT_INCONSISTENT_QOS, + "Create Topic <%s> failed: Unmatching QoS Policy: 'Resource'.", name); + consistent = FALSE; + } + if (!v_transportPolicyIEqual(found->qos->transport, qos->transport)) { + OS_REPORT(OS_WARNING, "v_topicNew", V_RESULT_INCONSISTENT_QOS, + "Create Topic <%s> failed: Unmatching QoS Policy: 'Transport'.", name); + consistent = FALSE; + } + if (!v_lifespanPolicyIEqual(found->qos->lifespan, qos->lifespan)) { + OS_REPORT(OS_WARNING, "v_topicNew", V_RESULT_INCONSISTENT_QOS, + "Create Topic <%s> failed: Unmatching QoS Policy: 'Lifespan'.", name); + consistent = FALSE; + } + if (!v_ownershipPolicyIEqual(found->qos->ownership, qos->ownership)) { + OS_REPORT(OS_WARNING, "v_topicNew", V_RESULT_INCONSISTENT_QOS, + "Create Topic <%s> failed: Unmatching QoS Policy: 'Ownership'.", name); + consistent = FALSE; + } + if (!v_historyPolicyIEqual(found->qos->history, qos->history)) { + OS_REPORT(OS_WARNING, "v_topicNew", V_RESULT_INCONSISTENT_QOS, + "Create Topic <%s> failed: Unmatching QoS Policy: 'History'.", name); + consistent = FALSE; + } + if (!keysConsistent(found, keyExpr)) { + OS_REPORT(OS_ERROR, "v_topicNew", V_RESULT_INCONSISTENT_QOS, + "Create Topic <%s> failed: key \"%s\" doesn't match already existing Topic key \"%s\".", + name, keyExpr?keyExpr:"NULL", found->keyExpr?found->keyExpr:"NULL"); + consistent = FALSE; + } return consistent; } @@ -501,8 +485,8 @@ v_topicImplNew( v_result result; v_topicImpl topic,found; c_type type; + c_type msgType; c_array keyList; - c_property field; v_topicQos newQos; c_char *str; v_message builtinMsg = NULL; @@ -520,15 +504,22 @@ v_topicImplNew( return NULL; } - if (v_topicQosCheck(qos) == V_RESULT_OK) { - newQos = v_topicQosNew(kernel,qos); - if (newQos == NULL) { - OS_REPORT(OS_ERROR, "v_topicNew", V_RESULT_INTERNAL_ERROR, - "Topic '%s' is not created: cannot create topic QoS.", - name); - return NULL; - } - } else { + if (v_topicQosCheck(qos) != V_RESULT_OK) { + OS_REPORT(OS_ERROR, "v_topicNew", V_RESULT_ILL_PARAM, + "Topic '%s' is not created: Topic QoS is invalid.", name); + return NULL; + } + type = c_resolve(c_getBase(kernel),typeName); + if (type == NULL) { + OS_REPORT(OS_ERROR, "v_topicNew", V_RESULT_ILL_PARAM, + "Topic '%s' is not created: Type '%s' is not found.", name, typeName); + return NULL; + } + newQos = v_topicQosNew(kernel,qos); + if (newQos == NULL) { + OS_REPORT(OS_FATAL, "v_topicNew", V_RESULT_INTERNAL_ERROR, + "Topic '%s' is not created: failed to copy topic QoS.", name); + c_free(type); return NULL; } @@ -538,7 +529,7 @@ v_topicImplNew( /* Check found topic with new topic */ /* compare topic, if inconsistent, reject creation! */ - if(isTopicConsistent(found, name, typeName, newQos, keyExpr)) { + if(isTopicConsistent(found, name, type, newQos, keyExpr)) { topic = c_keep(found); } @@ -546,38 +537,33 @@ v_topicImplNew( /* newQos is not used because the existing topic is returned */ v_topicQosFree(newQos); } else { - type = messageTypeNew(kernel,typeName); - if (type != NULL) { - if (createMessageKeyList(type, keyExpr, &keyList) == FALSE) { + msgType = messageTypeNew(kernel,type); + if (msgType != NULL) { + if (createMessageKeyList(msgType, keyExpr, &keyList) == FALSE) { topic = NULL; /* illegal key expression */ v_topicQosFree(newQos); OS_REPORT(OS_ERROR, "v_topicNew", V_RESULT_ILL_PARAM, "Failed to create Topic '%s': invalid key expression '%s'.", name, keyExpr); } else { - field = c_property(c_metaResolve(c_metaObject(type), - USERDATA_FIELD_NAME)); - assert(field != NULL); - assert((size_t) field->offset == sizeof (struct v_message_s)); - topic = v_topicImpl(v_objectNew(kernel,K_TOPIC)); - v_entityInit(v_entity(topic), name, TRUE); - topic->messageType = type; + v_entityInit(v_entity(topic), name); + topic->messageExtType = messageTypeExtNew(kernel,type); + topic->messageType = msgType; topic->messageKeyList = keyList; topic->keyType = createKeyType(name,keyList); - topic->dataType = c_keep (field->type); + topic->dataType = c_keep(type); topic->qos = newQos; topic->keyExpr = c_stringNew(c_getBase(kernel), keyExpr); topic->accessMode = v_partitionDetermineTopicAccessMode(name, kernel); - c_free (field); /* determine CRC codes */ - str = c_metaScopedName(c_metaObject(field->type)); + str = c_metaScopedName(c_metaObject(type)); topic->crcOfName = ut_crcCalculate(name, strlen(name)); topic->crcOfTypeName = ut_crcCalculate(str, strlen(str)); os_free(str); assert(found == NULL); - result = v_topicImplEnable(topic); + result = v_entityEnable(v_entity(topic)); switch(result) { case V_RESULT_OK: @@ -610,7 +596,7 @@ v_topicImplNew( name); } } - c_free(type); + c_free(msgType); } else { topic = NULL; v_topicQosFree(newQos); @@ -632,8 +618,8 @@ v_topicImplNew( * However this is currently implicitly done in the new operator. */ v_result -v_topicImplEnable ( - v_topicImpl topic) +v__topicImplEnable ( + _Inout_ v_topicImpl topic) { v_kernel kernel; v_topicImpl found; @@ -642,46 +628,23 @@ v_topicImplEnable ( assert(topic); assert(C_TYPECHECK(topic,v_topicImpl)); - if (topic) { - kernel = v_objectKernel(topic); - found = v_topicImpl(v__addTopic(kernel,v_topic(topic))); - /* - * If the topic was already added to the kernel, - * then the calling method should know so it can perform - * a roll-back. - */ - if(found != topic) - { - c_char *typeName = c_metaScopedName(c_metaObject(topic->dataType)); - - if(typeName) - { - if(isTopicConsistent(found, v_topicName(topic), typeName, topic->qos, topic->keyExpr)) - { - /* Compatible and already enabled topic found, - * so this request is superfluous. - */ - result = V_RESULT_PRECONDITION_NOT_MET; - } - else - { - result = V_RESULT_INCONSISTENT_QOS; - } - - os_free(typeName); - } - else - { - result = V_RESULT_INTERNAL_ERROR; - } - } - else - { - result = V_RESULT_OK; + kernel = v_objectKernel(topic); + found = v_topicImpl(v__addTopic(kernel,v_topic(topic))); + /* If the topic was already added to the kernel, + * then the calling method should know so it can perform + * a roll-back. + */ + if(found != topic) { + if (isTopicConsistent(found, v_topicName(topic), topic->dataType, topic->qos, topic->keyExpr)) { + /* Compatible and already enabled topic found, so this request is superfluous. */ + result = V_RESULT_PRECONDITION_NOT_MET; + } else { + result = V_RESULT_INCONSISTENT_QOS; } } else { - result = V_RESULT_ILL_PARAM; + result = V_RESULT_OK; } + return result; } @@ -697,7 +660,7 @@ v_topicImplAnnounce( /* publish V_TOPICINFO_TOPIC. */ kernel = v_objectKernel(v_object(topic)); -/* TODO: wrong place to do kernel locking, so v_builtinCreateTopicInfo should deal with it. */ + /* TODO: wrong place to do kernel locking, so v_builtinCreateTopicInfo should deal with it. */ c_lockWrite(&kernel->lock); builtinMsg = v_builtinCreateTopicInfo(kernel->builtin,v_topic(topic)); c_lockUnlock(&kernel->lock); @@ -899,9 +862,9 @@ v_topicImplGetQos( assert(_this); assert(C_TYPECHECK(_this,v_topicImpl)); - v_observerLock(v_observer(_this)); + OSPL_LOCK(_this); qos = c_keep(_this->qos); - v_observerUnlock(v_observer(_this)); + OSPL_UNLOCK(_this); return qos; } @@ -923,20 +886,20 @@ v_topicImplSetQos( */ result = v_topicQosCheck(tmpl); if (result == V_RESULT_OK) { - v_observerLock(v_observer(_this)); + OSPL_LOCK(_this); kernel = v_objectKernel(_this); qos = v_topicQosNew(kernel, tmpl); if (!qos) { - v_observerUnlock(v_observer(_this)); + OSPL_UNLOCK(_this); return V_RESULT_OUT_OF_MEMORY; } - result = v_topicQosCompare(_this->qos, qos, v_entityEnabled(v_entity(_this)), &cm); + result = v_topicQosCompare(_this->qos, qos, v__entityEnabled_nl(v_entity(_this)), &cm); if ((result == V_RESULT_OK) && (cm != 0)) { c_free(_this->qos); _this->qos = c_keep(qos); builtinMsg = v_builtinCreateTopicInfo(kernel->builtin,v_topic(_this)); } - v_observerUnlock(v_observer(_this)); + OSPL_UNLOCK(_this); if (builtinMsg != NULL) { v_writeBuiltinTopic(kernel, V_TOPICINFO_ID, builtinMsg); c_free(builtinMsg); @@ -972,8 +935,8 @@ v_topicImplNotifyInconsistentTopic( e.source = v_observable(topic); e.data = NULL; - (void)v_entityNotifyListener(v_entity(topic), &e); - v_observableNotify(v_observable(topic), &e); + e.handled = v_entityNotifyListener(v_entity(topic), &e); + OSPL_THROW_EVENT(topic, &e); } void @@ -988,9 +951,8 @@ v_topicImplNotifyAllDataDisposed( e.kind = V_EVENT_ALL_DATA_DISPOSED; e.source = v_observable(topic); e.data = NULL; - - (void)v_entityNotifyListener(v_entity(topic), &e); - v_observableNotify(v_observable(topic), &e); + e.handled = v_entityNotifyListener(v_entity(topic), &e); + OSPL_THROW_EVENT(topic, &e); } v_result @@ -1007,14 +969,14 @@ v_topicImplGetInconsistentTopicStatus( result = V_RESULT_PRECONDITION_NOT_MET; if (_this != NULL) { - v_observerLock(v_observer(_this)); + OSPL_LOCK(_this); status = v_entity(_this)->status; result = action(&v_topicStatus(status)->inconsistentTopic, arg); if (reset) { v_statusReset(status, V_EVENT_INCONSISTENT_TOPIC); } v_topicStatus(status)->inconsistentTopic.totalChanged = 0; - v_observerUnlock(v_observer(_this)); + OSPL_UNLOCK(_this); } return result; @@ -1034,14 +996,14 @@ v_topicImplGetAllDataDisposedStatus( result = V_RESULT_PRECONDITION_NOT_MET; if (_this != NULL) { - v_observerLock(v_observer(_this)); + OSPL_LOCK(_this); status = v_entity(_this)->status; result = action(&v_topicStatus(status)->allDataDisposed, arg); if (reset) { v_statusReset(status, V_EVENT_ALL_DATA_DISPOSED); } v_topicStatus(status)->allDataDisposed.totalChanged = 0; - v_observerUnlock(v_observer(_this)); + OSPL_UNLOCK(_this); } return result; @@ -1331,4 +1293,3 @@ v_topicImplNewFromTopicInfo ( } return newTopic; } - diff --git a/src/kernel/code/v_topicQos.c b/src/kernel/code/v_topicQos.c index c8106f5a2..d9f47ca3e 100644 --- a/src/kernel/code/v_topicQos.c +++ b/src/kernel/code/v_topicQos.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -36,9 +37,6 @@ static const v_qosChangeMask immutableMask = static const os_duration MAX_BLOCKING_TIME = OS_DURATION_INIT(0, 100000000); -/************************************************************** - * private functions - **************************************************************/ static c_bool v_topicQosValidValues( v_topicQos qos) @@ -93,9 +91,6 @@ v_topicQosConsistent( return result; } -/************************************************************** - * constructor/destructor - **************************************************************/ v_topicQos v_topicQosNew( v_kernel kernel, @@ -177,9 +172,6 @@ v_topicQosFree( c_free(q); } -/************************************************************** - * Protected functions - **************************************************************/ v_result v_topicQosCompare( v_topicQos q, @@ -192,7 +184,7 @@ v_topicQosCompare( cm = 0; if ((q != NULL) && (tmpl != NULL) && (changeMask != NULL)) { - /* built change mask */ + /* built change mask */ if (!v_topicDataPolicyIEqual(q->topicData, tmpl->topicData)) { cm |= V_POLICY_BIT_TOPICDATA; } @@ -247,9 +239,7 @@ v_topicQosCompare( return result; } -/************************************************************** - * Public functions - **************************************************************/ + v_result v_topicQosCheck( v_topicQos _this) diff --git a/src/kernel/code/v_transaction.c b/src/kernel/code/v_transaction.c index 5358279af..ed8b75558 100644 --- a/src/kernel/code/v_transaction.c +++ b/src/kernel/code/v_transaction.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,6 +30,7 @@ #include "v__subscriber.h" #include "v__reader.h" #include "v__observer.h" +#include "v__observable.h" #include "v_message.h" #include "v_public.h" #include "v_topic.h" @@ -37,6 +39,7 @@ #include "os_abstract.h" #include "os_report.h" #include "os_heap.h" +#include "os_atomics.h" /* Pick a block size that is small enough to fit in the 'small slab'categorie. * Be aware that additional headers may be inserted by the c_array, by the @@ -78,9 +81,9 @@ do { \ */ v_transactionAdmin v_transactionAdminNew( - v_object owner, - v_transactionGroupAdmin groupAdmin, - v_topic topic) + _In_ v_object owner, + _In_opt_ v_transactionGroupAdmin groupAdmin, + _In_ v_topic topic) { v_transactionAdmin _this; v_kernel kernel; @@ -213,12 +216,12 @@ v_transactionNew( transaction->count = 0; transaction->eotCount = 0; transaction->size = 0; - transaction->elementZero = FALSE; transaction->aborted = FALSE; transaction->sampleLostNotified = FALSE; transaction->transactionId = transactionId; transaction->isMarked = FALSE; transaction->transactionGroup = NULL; + pa_st32(&transaction->historyLinks, 0); transaction->elements = c_arrayNew(v_kernelType(kernel, K_TRANSACTIONELEMENT), V_TRANSACTION_BLOCKSIZE); if (transaction->elements == NULL) { @@ -231,7 +234,7 @@ v_transactionNew( assert(FALSE); } TRACE_COHERENT_UPDATE("v_transactionNew(%s) Writer(0x%"PA_PRIxADDR") WGID(%d) TID(%d) => 0x%"PA_PRIxADDR"\n", - WRITER_SCOPE(writer), (os_address)writer, + WRITER_SCOPE(writer), (os_address)writer, writer->writerGID.localId, transactionId, (os_address)transaction); } else { @@ -289,6 +292,9 @@ getTransactionElement( if (transaction->elements[index] == NULL) { transaction->elements[index] = c_new(v_kernelType(v_objectKernel(transaction), K_TRANSACTIONELEMENT)); + ((v_transactionElement)transaction->elements[index])->inserted = FALSE; + ((v_transactionElement)transaction->elements[index])->instance = NULL; + ((v_transactionElement)transaction->elements[index])->message = NULL; } return transaction->elements[index]; } @@ -416,37 +422,65 @@ storeMessageEOT( v_transactionElement targetElement; c_bool storeEOT = FALSE; - if ((_this->eotCount > 0) && - (v_objectKind(v_object(TRANSACTION_OWNER(_this))) == K_GROUP)) { + assert(v_messageStateTest(message, L_ENDOFTRANSACTION)); + assert(_this->eotCount >= 0); + assert(_this->size == 0 ? TRUE : _this->size == (c_long)index); + + if (_this->eotCount == 0) { + assert(!_this->eot); + storeEOT = TRUE; + } else { assert(_this->eot); + /* Already have an EOT message stored, only replace it with an EOT message + * without the L_TRANSACTION flag as this indicated completeness. An EOT + * messages without the L_TRANSACTION flag is therefore always more important + * than an EOT messages with. + */ if ((!v_messageStateTest(message, L_TRANSACTION)) && (v_messageStateTest(_this->eot, L_TRANSACTION))) { - /* EOT messages without the L_TRANSACTION flag indicate completeness. - * These messages are always more important than the messages with - * the flag. This can only happen for K_GROUP owned transactions as - * the group forwards the EOT to the readers when the group has become - * complete. + /* When an EOT message without L_TRANSACTION flag is received + * reset the eotCount as we now expect those EOT messages from + * all subscribed groups. */ + _this->eotCount = 0; + /* Free to old to make room for the new */ + c_free(_this->eot); + _this->eot = NULL; storeEOT = TRUE; } - } else { - assert(!_this->eot); - storeEOT = TRUE; } - if (storeEOT) { - if (v_objectKind(v_object(TRANSACTION_OWNER(_this))) == K_GROUP) { - _this->eotCount = 1; - } else { + if (v_objectKind(v_object(TRANSACTION_OWNER(_this))) == K_DATAREADER) { + if (_this->eot == NULL) { + _this->eotCount++; + } else if ((v_messageStateTest(message, L_TRANSACTION)) ? + (v_messageStateTest(_this->eot, L_TRANSACTION)) : + (!v_messageStateTest(_this->eot, L_TRANSACTION))) { + /* Only increase the eotCount when the stored EOT message has the + * same L_TRANSACTION state as the received EOT message (xor) + */ _this->eotCount++; } + } else { + assert(v_objectKind(v_object(TRANSACTION_OWNER(_this))) == K_GROUP); + _this->eotCount = 1; + } + if (storeEOT) { targetElement = getTransactionElement(_this, index); if (targetElement) { + if (targetElement->inserted) { + /* Should not be possible to receive a EOT which has the same + * index a transactional sample. + */ + assert(FALSE); + _this->count--; + } c_free(targetElement->message); c_free(targetElement->instance); targetElement->instance = NULL; targetElement->message = c_keep(message); + targetElement->inserted = FALSE; } _this->size = (c_long)index; _this->eot = c_keep(message); @@ -490,10 +524,6 @@ v_transactionInsertMessage ( C_MAX_ULONG - message->transactionId + message->sequenceNumber + 1; } - if (index == 0) { - _this->elementZero = TRUE; - } - /* If this is the End Of Transaction Marker, then calculate * the amount of expected samples and subtract it from the * amount of samples already received. If the end result @@ -509,9 +539,21 @@ v_transactionInsertMessage ( /* Handle message */ _this->count++; // increase message count - if ((v_messageStateTest(message, L_REGISTER)) || - (v_messageStateTest(message, L_UNREGISTER)) || - (v_messageStateTest(message, L_DISPOSED | L_AUTO))) { + if (((v_messageStateTest(message, L_REGISTER)) || + (v_messageStateTest(message, L_UNREGISTER)) || + (v_messageStateTest(message, L_DISPOSED | L_AUTO))) && + (instance)) { + + if (v_objectKind(v_object(instance)) == K_GROUPINSTANCE) { + if (v_messageStateTest(message, L_UNREGISTER)) { + v_writeResult wres; + wres = v_groupInstanceUnregister(v_groupInstance(instance), message, _this); + if (wres == V_WRITE_UNREGISTERED) { + (void)v_groupInstanceFlushTransaction(v_groupInstance(instance), message, _this); + } + } + } + /* Can never be lost, should always be added and don't require a claim. */ } else if (_this->aborted || abort) { /* If this transaction was aborted then this message is lost. */ @@ -557,7 +599,7 @@ v_transactionInsertMessage ( if (result == V_WRITE_SUCCESS) { targetElement = getTransactionElement(_this, index); if (targetElement) { - if (targetElement->message) { + if (targetElement->inserted) { _this->count--; } c_free(targetElement->message); @@ -569,6 +611,8 @@ v_transactionInsertMessage ( targetElement->message = NULL; targetElement->instance = NULL; } + /* element is inserted even when instance is NULL */ + targetElement->inserted = TRUE; } } /* If message is NOT_STORED then abort the transaction. */ @@ -691,30 +735,18 @@ v_transactionAdminFlush( } if (_this->groupAdmin && (v_messageQos_presentationKind(v_message(transaction->eot)->qos) == V_PRESENTATION_GROUP)) { - v_topicQos topicQos = NULL; - if (v_objectKind(v_object(_this->owner)) == K_GROUP) { - topicQos = v_topicGetQos(_this->topic); - assert(topicQos); - result = FALSE; - } - if ((topicQos != NULL) && (topicQos->durability.v.kind == V_DURABILITY_VOLATILE)) { + if ((v_objectKind(v_object(_this->owner)) == K_GROUP) && + (v_messageQos_durabilityKind(v_message(transaction->eot)->qos) == V_DURABILITY_VOLATILE)) { /* Do not insert transaction in TGA when group owned and volatile. * Do abort and flush the transaction so that unregisters are processed. */ v_transactionAbort(transaction); - v_transactionFlush(transaction, _this); + v_transactionFlush_nl(transaction); } else { result = v_transactionGroupAdminInsertTransaction(_this->groupAdmin, transaction, _this->topic); } - c_free(topicQos); } else { - v_transactionFlush(transaction, _this); - if (v_objectKind(v_object(_this->owner)) == K_GROUP) { - assert(_this->history != NULL); - (void)c_append(_this->history, transaction); - - v_transactionAdminPurgeHistory(_this); - } + v_transactionFlush_nl(transaction); } return result; } @@ -725,9 +757,6 @@ v_transactionAdminFlush( * param _this : The transaction this operation operates on. * return : TRUE if complete or FALSE if incomplete. * - * The count represents the number of messages for as long the transaction is - * incomplete, as soon as a transaction becomes complete the count is set to - * zero to indicate completeness. */ static c_bool v_transactionComplete( @@ -743,17 +772,14 @@ v_transactionComplete( owner = TRANSACTION_OWNER(_this); if (_this->eot) { if (v_objectKind(owner) == K_DATAREADER) { - if ((_this->elementZero) || - (!v_messageStateTest(_this->eot, L_TRANSACTION))) { - partitions = v_transactionWriter(_this->writer)->matchCount; - if (partitions == 0) { - if ((v_readerSubscriber(v_reader(owner))) && - (v_subscriberPartitionCount(v_readerSubscriber(v_reader(owner))) == 1)) { - partitions = 1; /* no need to wait for discovery if subscriber has only one partition. */ - } + partitions = v_transactionWriter(_this->writer)->matchCount; + if (partitions == 0) { + if ((v_readerSubscriber(v_reader(owner))) && + (v_subscriberPartitionCount(v_readerSubscriber(v_reader(owner))) == 1)) { + partitions = 1; /* no need to wait for discovery if subscriber has only one partition. */ } - result = (_this->eotCount == (c_long)partitions); } + result = (_this->eotCount == (c_long)partitions); } else { /* If L_TRANSACTION is not set on an EOT message then its complete */ if (!v_messageStateTest(_this->eot, L_TRANSACTION)) { @@ -862,6 +888,7 @@ v_transactionAdminNotifyPublication( assert(_this); assert(C_TYPECHECK(_this,v_transactionAdmin)); + OSPL_ASSERT_LOCK(_this->owner); TRACE_COHERENT_UPDATE("v_transactionAdminNotifyPublication(%s): WGID(%d)\n", ADMIN_SCOPE(_this), writerGID.localId); if (dispose) { @@ -875,7 +902,7 @@ v_transactionAdminNotifyPublication( } /* Fall through */ default: - result = v_transactionGroupAdminNotifyGroupCoherentPublication(_this->groupAdmin, writer, dispose, info); + result = v_transactionGroupAdminNotifyPublication(_this->groupAdmin, writer, dispose, info); } } while ((txn = c_take(writer->transactions)) != NULL) { @@ -890,10 +917,13 @@ v_transactionAdminNotifyPublication( */ v_transactionNotifySampleLost(txn, _this); } - v_transactionFlush(txn, _this); + if (txn->admin == _this) { + v_transactionFlush_nl(txn); + } else { + v_transactionFlush(txn); + } c_free(txn); } - v_transactionAdminPurgeHistory(_this); } } else { writer = v_transactionAdminLookupWriter(_this, writerGID); @@ -952,7 +982,7 @@ v_transactionAdminNotifyPublication( if (transaction->eot->publisherId != 0) { writer->publisherId = transaction->eot->publisherId; } - (void)v_transactionAdminFlush(_this, transaction); + result = v_transactionAdminFlush(_this, transaction); c_free(transaction); } c_iterFree(list); @@ -966,7 +996,9 @@ v_transactionAdminNotifyPublication( } /* Fall through */ default: - result = v_transactionGroupAdminNotifyGroupCoherentPublication(_this->groupAdmin, writer, dispose, info); + if(v_transactionGroupAdminNotifyPublication(_this->groupAdmin, writer, dispose, info)) { + result = TRUE; + } } } } @@ -1133,8 +1165,16 @@ v_transactionPurge( */ void v_transactionFlush( - v_transaction _this, - v_transactionAdmin owner) + v_transaction _this) +{ + OSPL_LOCK(v_transactionAdmin(_this->admin)->owner); + v_transactionFlush_nl(_this); + OSPL_UNLOCK(v_transactionAdmin(_this->admin)->owner); +} + +void +v_transactionFlush_nl( + v_transaction _this) { v_transactionAdmin admin; struct v_groupFlushTransactionArg arg; @@ -1143,51 +1183,22 @@ v_transactionFlush( assert(C_TYPECHECK(_this,v_transaction)); admin = v_transactionAdmin(_this->admin); + OSPL_ASSERT_LOCK(admin->owner); switch(v_objectKind(v_object(admin->owner))) { case K_GROUP: arg.group = admin->owner; arg.txn = _this; - if (admin != owner) { - c_mutexLock(&v_group(admin->owner)->mutex); - } v_transactionWalk(_this, v_groupFlushTransactionNoLock, &arg); - if (admin != owner) { - c_mutexUnlock(&v_group(admin->owner)->mutex); - } v_transactionPurge(_this); break; case K_DATAREADER: - if (admin != owner) { - v_observerLock(v_observer(admin->owner)); - } v_transactionWalk(_this, v_dataReaderEntryFlushTransactionNoLock, NULL); - if (admin != owner) { - v_observerUnlock(v_observer(admin->owner)); - } break; default: assert(0); break; } } -void -v_transactionTriggerList( - v_transaction _this, - c_iter triggerList) -{ - v_transactionAdmin admin; - - assert(_this); - assert(C_TYPECHECK(_this,v_transaction)); - - admin = v_transactionAdmin(_this->admin); - if (v_objectKind(v_object(admin->owner)) == K_DATAREADER) { - if (_this->size > 0) { - c_iterInsert(triggerList, admin->owner); - } - } -} - /** * \brief This operation inserts a received coherent message into the * administration. @@ -1300,7 +1311,6 @@ v_transactionAdminWalkTransactions( walkArg.action = action; walkArg.arg = arg; - v_transactionAdminPurgeHistory(_this); (void)c_walk(_this->history, action, arg); (void)c_walk(_this->writers, writerWalk, &walkArg); } @@ -1340,15 +1350,6 @@ v_transactionGetGroupAdmin( return (v_transactionGroupAdmin)_this->groupAdmin; } -void -v_transactionAdminTrigger( - v_transactionAdmin _this) -{ - if (_this && _this->groupAdmin) { - v_transactionGroupAdminTrigger((v_transactionGroupAdmin)_this->groupAdmin, NULL); - } -} - /** * \brief This operation will send a SampleLost notification to the owner. * @@ -1400,9 +1401,9 @@ v_transactionNotifySampleLost( if (nrSamplesLost > 0) { if (_this->admin == admin) { - v_dataReaderNotifySampleLost(v_dataReader(owner), nrSamplesLost); + v_dataReaderNotifySampleLost_nl(v_dataReader(owner), nrSamplesLost); } else { - v_dataReaderNotifySampleLostLock(v_dataReader(owner), nrSamplesLost); + v_dataReaderNotifySampleLost(v_dataReader(owner), nrSamplesLost); } } } @@ -1462,32 +1463,58 @@ v_transactionAdminNoMessageFromWriterExist( return c_walk(_this->writers, writerWalk, &walkArg); } - -/** - * \brief This operation removes transactions from the history when - * the contained transactions are not referenced by samples - * anymore - * - * \param _this : The v_transactionAdmin this operation operates on. - * - * \return : None - */ void -v_transactionAdminPurgeHistory( - v_transactionAdmin _this) +v_transactionLink( + v_transaction _this) { - v_transaction txn; - struct c_collectionIterD it; - - if (v_objectKind(ADMIN_OWNER(_this)) == K_GROUP) { - for (txn = c_collectionIterDFirst(_this->history, &it); txn; txn = c_collectionIterDNext(&it)) { - if (c_refCount(txn) == 1) { - TRACE_COHERENT_UPDATE("%s(%s) Admin(0x%"PA_PRIxADDR") Removed TID(%u) from history\n", - OS_FUNCTION, ADMIN_SCOPE(_this), (os_address)_this, txn->transactionId); - c_collectionIterDRemove(&it); - c_free(txn); - } + os_uint32 value; + v_transactionAdmin admin; + v_transaction found; + + if (_this) { + assert(C_TYPECHECK(_this,v_transaction)); + + value = pa_inc32_nv(&_this->historyLinks); + if (_this->transactionGroup) { + v_transactionGroupLink(_this->transactionGroup); + } else if (value == 1) { + admin = v_transactionAdmin(_this->admin); + assert(v_objectKind(v_object(admin->owner)) == K_GROUP); + + TRACE_COHERENT_UPDATE("%s(%s) Admin(0x%"PA_PRIxADDR") Add TID(%u) to history\n", + OS_FUNCTION, ADMIN_SCOPE(admin), (os_address)admin, _this->transactionId); + + found = c_append(admin->history, _this); + assert(found == _this); + OS_UNUSED_ARG(found); } } } +void +v_transactionUnlink( + v_transaction _this) +{ + os_uint32 value; + v_transactionAdmin admin; + v_transaction found; + + if (_this != NULL) { + assert(C_TYPECHECK(_this,v_transaction)); + + value = pa_dec32_nv(&_this->historyLinks); + if (_this->transactionGroup) { + v_transactionGroupUnlink(_this->transactionGroup); + } else if (value == 0) { + admin = v_transactionAdmin(_this->admin); + assert(v_objectKind(v_object(admin->owner)) == K_GROUP); + + TRACE_COHERENT_UPDATE("%s(%s) Admin(0x%"PA_PRIxADDR") Remove TID(%u) from history\n", + OS_FUNCTION, ADMIN_SCOPE(admin), (os_address)admin, _this->transactionId); + + found = c_remove(admin->history, _this, NULL, NULL); + assert(found == _this); + c_free(found); + } + } +} diff --git a/src/kernel/code/v_transactionGroup.c b/src/kernel/code/v_transactionGroup.c index f6ecd073d..db7d9441a 100644 --- a/src/kernel/code/v_transactionGroup.c +++ b/src/kernel/code/v_transactionGroup.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,19 +22,22 @@ #include "v__transactionGroup.h" #include "v__transaction.h" #include "v__kernel.h" -#include "v__spliced.h" #include "v_public.h" #include "v_message.h" #include "v_instance.h" #include "v__subscriber.h" +#include "v__reader.h" #include "v__dataReader.h" #include "v__builtin.h" #include "v__policy.h" +#include "v_time.h" #include "os_abstract.h" #include "os_report.h" #include "os_heap.h" +#include "os_atomics.h" #include "c_collection.h" + #define V_TRANSACTION_BLOCKSIZE (50) #define TRACE_COHERENT 0 @@ -62,16 +66,13 @@ do { \ NULL) #define TRANSACTION_OWNER(o) \ - (((o) && (v_transactionGroup(o)->publisher)) ? \ - (v_transactionGroupAdmin(v_transactionPublisher(v_transactionGroup(o)->publisher)->admin)->owner) : \ + ((o) ? \ + (v_transactionGroupAdmin(v_transactionGroup(o)->admin)->owner) : \ NULL) #define v_transactionPublisherCount(p) \ (p ? (v_transactionPublisher(p)->writers ? c_count(v_transactionPublisher(p)->writers) : 0) : 0) -/**************************************************************************** - * Private New/Free - ****************************************************************************/ static v_transactionPublisher v_transactionPublisherNew( v_transactionGroupAdmin admin, @@ -90,7 +91,6 @@ v_transactionPublisherNew( _this->publisherId = publisherId; _this->admin = admin; _this->transactions = c_listNew(v_kernelType(kernel, K_TRANSACTIONGROUP)); - _this->lastRemovedTransactionId = 0; _this->writers = c_tableNew(v_kernelType(kernel, K_TRANSACTIONGROUPWRITER), "gid.systemId,gid.localId,gid.serial"); TRACE_COHERENT_UPDATE(ADMIN_OWNER(admin), @@ -108,13 +108,16 @@ v_transactionPublisherNew( static v_transactionGroup v_transactionGroupNew( v_transactionPublisher publisher, + v_transactionGroupAdmin admin, v_transaction transaction) { v_transactionGroup group; v_kernel kernel = v_objectKernel(transaction); + assert(admin != NULL); assert(transaction != NULL); assert(C_TYPECHECK(publisher, v_transactionPublisher)); + assert(C_TYPECHECK(admin, v_transactionGroupAdmin)); assert(C_TYPECHECK(transaction, v_transaction)); group = v_transactionGroup(v_objectNew(kernel, K_TRANSACTIONGROUP)); @@ -129,10 +132,14 @@ v_transactionGroupNew( group->publisher = (c_voidp)publisher; group->publisherId = publisher->publisherId; } + group->admin = admin; group->matchCount = 0; - group->triggered = FALSE; group->writers = c_tableNew(v_kernelType(kernel, K_TRANSACTIONGROUPWRITER), "gid.systemId,gid.localId,gid.serial"); + group->obsolete = FALSE; + group->allocTime = os_timeEGet(); + group->writeTime = v_message(transaction->eot)->writeTime; + pa_st32(&group->historyLinks, 0); TRACE_COHERENT_UPDATE(PUBLISHER_OWNER(publisher), "PID(%d) TID(%d) => 0x%"PA_PRIxADDR"\n", @@ -164,6 +171,8 @@ v_transactionGroupWriterNew ( _this->publisher = publisher; _this->readers = c_tableNew(v_kernelType(kernel, K_TRANSACTIONGROUPREADER), "gid.systemId,gid.localId,gid.serial"); + _this->rxo = NULL; + _this->topicName = NULL; TRACE_COHERENT_UPDATE(PUBLISHER_OWNER(publisher), "PID(%d) Writer(%u) => 0x%"PA_PRIxADDR"\n", @@ -177,9 +186,6 @@ v_transactionGroupWriterNew ( return _this; } -/**************************************************************************** - * Private functions - ****************************************************************************/ static void v_transactionGroupInsertTransaction ( v_transactionGroup _this, @@ -188,6 +194,7 @@ v_transactionGroupInsertTransaction ( struct c_collectionIter it; v_transaction txn; c_bool duplicate = FALSE; + os_uint32 oldValue, value; assert(_this); assert(transaction); @@ -205,7 +212,9 @@ v_transactionGroupInsertTransaction ( /* Mark group transaction as aborted, on flush this flag is reevaluated. */ _this->aborted = TRUE; } - transaction->transactionGroup = _this; + + + for (txn = c_collectionIterFirst(_this->transactions, &it); txn; txn = c_collectionIterNext(&it)) { if (txn->admin == transaction->admin && txn->writer == transaction->writer) { @@ -218,25 +227,29 @@ v_transactionGroupInsertTransaction ( } } if (!duplicate) { - c_append(_this->transactions, transaction); - } -} + if (v_objectKind(TRANSACTION_OWNER(_this)) == K_KERNEL) { + oldValue = pa_ld32(&_this->historyLinks); + value = pa_add32_nv(&_this->historyLinks, pa_ld32(&transaction->historyLinks)); -static c_bool -writerDiscovered( - c_object o, - c_voidp arg) -{ - v_transactionGroupWriter writer = v_transactionGroupWriter(o); - OS_UNUSED_ARG(arg); - return writer->discovered; -} + if ((value > 0) && (oldValue == 0)) { + v_transactionGroupAdmin admin = v_transactionGroupAdmin(_this->admin); + v_transactionGroup found; -static c_bool -v_transactionGroupAllWritersDiscovered( - v_transactionGroup _this) -{ - return c_walk(_this->writers, writerDiscovered, NULL); + /* Transaction already has samples commited in the group instance so + * it needs to be added to the history + */ + TRACE_COHERENT_UPDATE(TRANSACTION_OWNER(_this), "Group(0x%"PA_PRIxADDR") PID(%u) TID(%u) " + "add to history\n", + (os_address)_this, _this->publisherId, _this->transactionId); + + found = c_append(admin->history, _this); + assert(found == _this); + OS_UNUSED_ARG(found); + } + } + transaction->transactionGroup = _this; + c_append(_this->transactions, transaction); + } } /** @@ -253,86 +266,47 @@ v_transactionGroupHasData( return (c_count(_this->transactions) > 0); } +static c_bool +writerDiscovered( + c_object o, + c_voidp arg) +{ + v_transactionGroupWriter writer = v_transactionGroupWriter(o); + OS_UNUSED_ARG(arg); + return writer->discovered; +} + /** * This operation determines the completeness of a group coherent transaction. * - * A group is complete if it contains all transactions which are defined by - * the writers listed in the EOT message of any of the available transactions. - * For each writer in the list a transaction is expected for each matching reader. - * - * This operation will first check if the number of discovered DataWriters equals - * the number of DataWriters listed in the EOT messages, if these numbers are equal then - * all DataWriters are discovered and match, in that case completeness is reached as soon - * as the number of available transactions equal the number of known DataWriters. - * If the number of known DataWriters differ from the number listed in the EOT messages - * then some DataWriters don't match or are not discovered yet, in that case this - * operation will ask the spliced to give more information about the missing DataWriters. - * The spliced will acknowledge if it has discovered the DataWriter and return the number - * of matching DataReaders for the DataWriter and then report the status which can either - * be a match, an unmatch or unknown. - * In case one or more DataWriters are not discovered yet, this operation cannot determine - * completeness and will therefore return a unknown status. + * A group is complete if all the writers listed in the EOT message are discovered + * and the number of received transactions is equal to the matchCount. + * The matchCount is calculated differently for kernel and subscriber owned + * transactionGroupAdmins. For the kernel owned the matchCount equals the number of + * writers listed in the EOT message. For the subscriber owned the matchCount is + * equal to total number of readers matching the writers listed in the EOT message, + * a writer can have 0 to multiple reader matches. */ static c_bool v_transactionGroupComplete( v_transactionGroup _this) { c_bool complete = FALSE; - c_bool allDiscovered = FALSE; assert(_this); assert(C_TYPECHECK(_this, v_transactionGroup)); - if (c_count(_this->transactions) == 0) { - v_transactionPublisher publisher = v_transactionPublisher(_this->publisher); - OS_UNUSED_ARG(publisher); - /* The count attribute is the number of available (received) writer transactions, - * this number is initially one when the transactionGroup is created. - * When the value is zero it means that the group is empty (i.e. already flushed) - * so can be ignored. - * This can occur when the group is added to the pending list because of an - * undiscovered writer. In that case the group can be flushed when the writer - * is discovered while remaining in the pending list until the pending list is - * flushed. - */ - TRACE_COHERENT_UPDATE(TRANSACTION_OWNER(_this), "NO TRANSACTIONS: Group(0x%"PA_PRIxADDR") PID(%u) TID(%u) " - "transaction count(%d) == writer count(%d) EOT count (%d) results in (%d) matches\n", - (os_address)_this, _this->publisherId, _this->transactionId, - c_count(_this->transactions), v_transactionPublisherCount(publisher), - 0, _this->matchCount); - - return FALSE; + if (c_count(_this->transactions) == _this->matchCount) { + complete = c_walk(_this->writers, writerDiscovered, NULL); } - - allDiscovered = v_transactionGroupAllWritersDiscovered(_this); - if (allDiscovered && - (c_count(_this->transactions) == _this->matchCount)) { - complete = TRUE; - } - TRACE_COHERENT_UPDATE(TRANSACTION_OWNER(_this), "Group(0x%"PA_PRIxADDR") PID(%u) TID(%u) " - "allDiscovered (%s), number of transactions (%u), " - "matchCount (%u) %s\n", + "number of transactions (%u), matchCount (%u) %s\n", (os_address)_this, _this->publisherId, _this->transactionId, - allDiscovered ? "TRUE": "FALSE", c_count(_this->transactions), - _this->matchCount, complete?"complete":"incomplete"); + c_count(_this->transactions), _this->matchCount, complete?"complete":"incomplete"); return complete; } -static v_transactionGroup -v_transactionPublisherRemoveTransaction( - v_transactionPublisher _this, - v_transactionGroup group) -{ - assert(_this); - assert(C_TYPECHECK(_this, v_transactionPublisher)); - assert(group); - assert(C_TYPECHECK(group, v_transactionGroup)); - - return c_remove(_this->transactions, group, NULL, NULL); -} - /** * This operation flushes all transactions belonging to this group. * A precondition is that the group is complete. @@ -352,14 +326,10 @@ v_transactionGroupFlush( if (_this->aborted) { if (reevaluateAbort) { - /* Need to check it the aborted transaction is still part of the group - * transaction. */ + /* If one of the transactions is aborted then the whole group is aborted. */ for (txn = c_collectionIterFirst(_this->transactions, &it); txn; txn = c_collectionIterNext(&it)) { abort = v_transactionIsAborted(txn); - if (abort == TRUE) { - /* One of the transactions is still aborted, abort everything */ - break; - } + if (abort == TRUE) { break; } } } else { abort = TRUE; @@ -369,9 +339,15 @@ v_transactionGroupFlush( for (txn = c_collectionIterFirst(_this->transactions, &it); txn; txn = c_collectionIterNext(&it)) { if (abort) { v_transactionAbort(txn); - v_transactionNotifySampleLost(txn, owner); + if (!_this->deleted) { + v_transactionNotifySampleLost(txn, owner); + } + } + if (txn->admin == owner) { + v_transactionFlush_nl(txn); + } else { + v_transactionFlush(txn); } - v_transactionFlush(txn, owner); } } @@ -572,7 +548,7 @@ v_transactionPublisherLookupTransaction( template.transactionId = transaction->eot->transactionId; group = v_transactionGroup(c_listTemplateFind(_this->transactions, compareTransactionId, &template)); if (group == NULL) { - group = v_transactionGroupNew(_this, transaction); + group = v_transactionGroupNew(_this, _this->admin, transaction); group = ospl_c_insert(_this->transactions, group); #if TRACE_COHERENT inserted = TRUE; @@ -590,87 +566,6 @@ v_transactionPublisherLookupTransaction( return group; } -/** - * \brief This operation removes older transactions from the publisher - * - * \param _this : The v_transactionPublisher this operation operates on. - * \param transaction : Transactions older then this transaction are removed. - * - * \return : List of removed transactions. - */ -static c_iter -v_transactionPublisherRemoveOlderTransactions( - v_transactionPublisher _this, - v_transactionGroup transaction) -{ - c_iter list = NULL; - v_transactionGroup group; - struct c_collectionIterD it; - c_bool old; - - assert(_this); - assert(C_TYPECHECK(_this, v_transactionPublisher)); - - for (group = c_collectionIterDFirst(_this->transactions, &it); group; group = c_collectionIterDNext(&it)) { - old = FALSE; - - if (transaction->transactionId < _this->lastRemovedTransactionId) { - if ((group->transactionId >= _this->lastRemovedTransactionId) || - (group->transactionId < transaction->transactionId)) { - old = TRUE; - } - } else if ((group->transactionId >= _this->lastRemovedTransactionId) && - (group->transactionId < transaction->transactionId)) { - old = TRUE; - } - - if (old) { - if (v_transactionGroupComplete(group) != TRUE) { - list = c_iterInsert(list, c_keep(group)); - c_collectionIterDRemove(&it); - c_free(group); - } - } - } - - return list; -} - -static v_topic -getTopicByName( - v_kernel kernel, - const c_char *name) -{ - v_topic topic; - c_iter topics; - - topics = v_resolveTopics(kernel, name); - assert(c_iterLength(topics) == 1); - topic = v_topic(c_iterTakeFirst(topics)); - c_iterFree(topics); - - return topic; -} - -struct processPublicationInfoHelper { - v_kernel kernel; - v_rxoData rxo; - v_topic topic; -}; - -static v_result -processPublicationInfo( - struct v_publicationInfo *info, - void *arg) -{ - struct processPublicationInfoHelper *helper = (struct processPublicationInfoHelper *)arg; - - helper->rxo = v_kernel_rxoDataFromPublicationInfo(helper->kernel, info); - helper->topic = getTopicByName(helper->kernel, info->topic_name); - - return V_RESULT_OK; -} - static c_bool v_transactionGroupWriterMatchReader( v_transactionGroupWriter _this, @@ -681,7 +576,7 @@ v_transactionGroupWriterMatchReader( v_transactionGroupReader r; if ((dispose == FALSE) && - (strcmp(v_topicName(reader->topic), v_topicName(_this->topic)) == 0) && + (strcmp(v_topicName(reader->topic), _this->topicName) == 0) && (v_rxoDataCompatible(_this->rxo, reader->rxo) == TRUE)) { r = c_find(_this->readers, reader); if (r == NULL) { @@ -713,7 +608,7 @@ matchWriter( struct matchWriterHelper *helper = (struct matchWriterHelper *) arg; assert(reader->topic); - assert(helper->writer->topic); + assert(helper->writer->topicName); helper->updated |= v_transactionGroupWriterMatchReader(helper->writer, reader, FALSE); @@ -736,7 +631,8 @@ matchReader( assert(helper->reader->topic); if (writer->discovered) { - assert(writer->topic); + assert(writer->rxo); + assert(writer->topicName); helper->updated |= v_transactionGroupWriterMatchReader(writer, helper->reader, helper->dispose); } @@ -775,13 +671,8 @@ v_transactionGroupWriterGetMatches( if (_this->discovered == TRUE) { if (v_objectKind(PUBLISHER_OWNER(_this->publisher)) == K_SUBSCRIBER) { matches = c_count(_this->readers); - } else { - v_topicQos topicQos; - topicQos = v_topicGetQos(_this->topic); - if (topicQos->durability.v.kind != V_DURABILITY_VOLATILE) { - matches = 1; - } - c_free(topicQos); + } else if (_this->rxo->durability.v.kind != V_DURABILITY_VOLATILE) { + matches = 1; } } return matches; @@ -855,7 +746,8 @@ v_transactionGroupRecalculateMatchCount( oldCount = _this->matchCount; /* Run through the discovered writers list to determine how many matches there are. - * When publisherId==0, then it should not change. */ + * When publisherId==0, then it should not change. + */ if ((_this->publisherId != 0) && (_this->publisher != NULL)) { _this->matchCount = 0; (void)c_walk(_this->writers, calculateMatchCount, &_this->matchCount); @@ -896,7 +788,8 @@ v_transactionGroupRemoveReader( reader->gid.localId); /* First, remove all transactions that are related to this reader. - * But do not clean KERNEL owned transactions as these are required for alignment. */ + * But do not clean KERNEL owned transactions as these are required for alignment. + */ if ((_this->publisher != NULL) && (v_objectKind(TRANSACTION_OWNER(_this)) != K_KERNEL)) { @@ -921,7 +814,9 @@ v_transactionGroupRemoveReader( (void)c_walk(_this->writers, matchReader, &helper); /* Third, re-calculate the matchCount. */ - v_transactionGroupRecalculateMatchCount(_this); + if (helper.updated) { + v_transactionGroupRecalculateMatchCount(_this); + } /* Sanity check. */ if (oldComplete) { @@ -932,7 +827,7 @@ v_transactionGroupRemoveReader( } } -static c_bool +static void v_transactionGroupWriterUpdate( v_transactionGroupWriter _this, const struct v_publicationInfo *info) @@ -948,12 +843,10 @@ v_transactionGroupWriterUpdate( c_free(_this->rxo); } else { /* Topic cannot be changed so only set it once */ - _this->topic = getTopicByName(kernel, info->topic_name); /* pass reference */ + _this->topicName = c_keep(info->topic_name); } _this->rxo = v_kernel_rxoDataFromPublicationInfo(kernel, info); /* pass reference */ _this->discovered = TRUE; - - return TRUE; } static void @@ -968,65 +861,83 @@ v_transactionPublisherRecalculateMatchCounts( } } -/** - * \brief This operation removes groupTransactions from the history - * when the contained transactions are not referenced by samples - * anymore - * - * \param _this : The transactionGroupAdmin this operation operates on. - * - * \return : None - */ static void -transactionGroupAdminPurgeHistory( - v_transactionGroupAdmin _this) +v_transactionPublisherMarkObsolete( + v_transactionPublisher _this, + os_timeW writeTime, + c_ulong transactionId) { - v_transactionGroup group; - v_transaction txn; struct c_collectionIterD it; - struct c_collectionIter jt; - c_long cnt; - - if (v_objectKind(ADMIN_OWNER(_this)) == K_KERNEL) { - for (group = c_collectionIterDFirst(_this->history, &it); group; group = c_collectionIterDNext(&it)) { - cnt = 0; - for (txn = c_collectionIterFirst(group->transactions, &jt); txn; txn = c_collectionIterNext(&jt)) { - /* Determine if the this transactionGroup hold the only reference. - */ - cnt += (c_refCount(txn) - 1); - } - if (cnt == 0) { - /* There are no longer samples/registrations referencing this - * transactionGroup. It's now safe to remove it. - */ - TRACE_COHERENT_UPDATE(ADMIN_OWNER(_this), "TID(%u) GroupTransaction(0x%"PA_PRIxADDR") " - "Removed from history list\n", - group->transactionId, (os_address)group); - c_collectionIterDRemove(&it); - c_free(group); + v_transactionGroup tg; + os_compare eq; + + assert(_this); + assert(C_TYPECHECK(_this, v_transactionPublisher)); + + for (tg = c_collectionIterDFirst(_this->transactions, &it); tg; tg = c_collectionIterDNext(&it)) { + eq = os_timeWCompare(tg->writeTime, writeTime); + if (eq == OS_EQUAL) { + if (tg->transactionId < transactionId) { + eq = OS_LESS; } } + if (eq == OS_LESS) { + tg->obsolete = TRUE; + } } } -/** - * \brief This operation adds a groupTransaction to the history list - * - * \param _this : The transactionGroupAdmin this operation operates on. - * \param group : The transactionGroup to add to the history list - * - * \return : None - */ -static void -v_transactionGroupAdminAddGroupToHistory( +static c_bool +v_transactionGroupAdminAddGroupToPending( v_transactionGroupAdmin _this, v_transactionGroup group) { - if (v_objectKind(_this->owner) == K_KERNEL) { - (void)c_append(_this->history, group); + c_bool result = FALSE; + v_transactionGroup found; + v_transactionPublisher publisher; + + assert(_this); + assert(C_TYPECHECK(_this, v_transactionGroupAdmin)); + assert(group); + assert(C_TYPECHECK(group, v_transactionGroup)); + + publisher = v_transactionPublisher(group->publisher); + if ((group->obsolete == FALSE) && + (group->aborted == FALSE)){ + v_transactionPublisherMarkObsolete(publisher, group->writeTime, group->transactionId); } + group->publisher = NULL; + + if (v_transactionGroupHasData(group)) { + found = c_append(_this->pending, group); + assert(found == group); + OS_UNUSED_ARG(found); + result = TRUE; + TRACE_COHERENT_UPDATE(ADMIN_OWNER(_this), + "Add %sgroup TID(%u) (0x%"PA_PRIxADDR") to pending list (size:%u)\n", + (group->aborted ?"aborted ":""), + group->transactionId, + (os_address)group, + c_count(_this->pending)); + } else { + TRACE_COHERENT_UPDATE(ADMIN_OWNER(_this), + "Removing complete but empty group TID(%u) (0x%"PA_PRIxADDR")\n", + group->transactionId, + (os_address)group); + } + return result; } +/** + * \brief This operation moves all complete transactions from the + * transactionPublisher to the pending list. This operation + * is required because of the asynchronous detection of writers. + * + * \param _this : The transactionGroupAdmin this operation operates on. + * \param publisher : The transactionPublisher to check for complete transactions + * + * \return : TRUE when at least one transaction has become complete + */ static c_bool v_transactionGroupAdminPendCompleteTransactions( v_transactionGroupAdmin _this, @@ -1038,43 +949,40 @@ v_transactionGroupAdminPendCompleteTransactions( for (group = c_collectionIterDFirst(publisher->transactions, &it); group; group = c_collectionIterDNext(&it)) { if (v_transactionGroupComplete(group) == TRUE) { - if (!c_exists(_this->pending, group)) { - if (v_transactionGroupHasData(group)) { - c_append(_this->pending, group); - result = TRUE; - TRACE_COHERENT_UPDATE(ADMIN_OWNER(_this), - "Add group TID(%u) (0x%"PA_PRIxADDR") to pending list (size:%u)\n", - group->transactionId, - (os_address)group, - c_count(_this->pending)); - } else { - TRACE_COHERENT_UPDATE(ADMIN_OWNER(_this), - "Removing complete but empty group TID(%u) (0x%"PA_PRIxADDR")\n", - group->transactionId, - (os_address)group); - c_collectionIterDRemove(&it); - c_free(group); - } - } + result = v_transactionGroupAdminAddGroupToPending(_this, group); + c_collectionIterDRemove(&it); + c_free(group); } } return result; } +static c_bool +publisherPurgeObsolete( + c_object o, + c_voidp arg); + +/** + * \brief This operation moves all obsolete transactions from the + * transactionPublishers to the pending list when durability + * is not aligning data. + * + * \param _this : The transactionGroupAdmin this operation operates on. + * + * \return : void + */ static void -remove_pending_from_publishers( - c_list list) +purgeObsolete ( + v_transactionGroupAdmin _this) { - struct c_collectionIter it; - v_transactionGroup group, found; - v_transactionPublisher pub; + v_kernel kernel = v_objectKernel(v_object(_this)); - for (group = c_collectionIterFirst(list, &it); group; group = c_collectionIterNext(&it)) { - pub = v_transactionPublisher(group->publisher); - if (pub) { - found = v_transactionPublisherRemoveTransaction(pub, group); - c_free(found); - } + if ((v_kernelGetDurabilitySupport(kernel) == TRUE) && + (v_kernelGetAlignedState(kernel) == FALSE)) { + /* Durability is currently not aligned, do not purge obsolete groups as + * they can still become complete. */ + } else { + (void)c_walk(_this->publishers, publisherPurgeObsolete, _this->pending); } } @@ -1090,129 +998,37 @@ v_transactionGroupAdminFlushPending( v_transactionGroup group; c_list pending = NULL; v_kernel kernel; - c_iter oldList = NULL; - c_iter historyList = NULL; assert(_this); assert(C_TYPECHECK(_this, v_transactionGroupAdmin)); assert(C_TYPECHECK(admin, v_transactionAdmin)); c_mutexLock(&_this->mutex); + kernel = v_objectKernel(_this); + + purgeObsolete(_this); + if (c_count(_this->pending) > 0) { - kernel = v_objectKernel(_this); pending = _this->pending; _this->pending = c_listNew(v_kernelType(kernel, K_TRANSACTIONGROUP)); assert(_this->pending); - remove_pending_from_publishers(pending); - - group = c_read(pending); - if (group) { - if (group->publisher) { - oldList = v_transactionPublisherRemoveOlderTransactions(v_transactionPublisher(group->publisher), group); - } - c_free(group); - } - } - if (v_objectKind(ADMIN_OWNER(_this)) == K_KERNEL) { - historyList = c_iterNew(NULL); } + c_mutexUnlock(&_this->mutex); - while ((group = c_iterTakeFirst(oldList)) != NULL) { - group->aborted = TRUE; - TRACE_COHERENT_UPDATE(ADMIN_OWNER(_this), "PID(%u) Abort incomplete old " - "group(0x%"PA_PRIxADDR") TID(%u)\n", - group->publisherId, (os_address)group, - group->transactionId); - v_transactionGroupFlush(group, admin, FALSE); - if (historyList) { - c_iterAppend(historyList, c_keep(group)); - } - c_free(group); - } - c_iterFree(oldList); while (pending && ((group = c_take(pending)) != NULL)) { TRACE_COHERENT_UPDATE(ADMIN_OWNER(_this), "PID(%u) Flush group (0x%"PA_PRIxADDR") TID(%u) " "from pending list\n", group->publisherId, (os_address)group, group->transactionId); + v_transactionGroupFlush(group, admin, TRUE); - if (historyList) { - c_iterAppend(historyList, c_keep(group)); - } c_free(group); } - - if (historyList) { - c_mutexLock(&_this->mutex); - while ((group = c_iterTakeFirst(historyList)) != NULL) { - /* Add all emptied (all elements are flushed and freed, only EOTs still - * exist) transactionGroups to the history list. - */ - v_transactionGroupAdminAddGroupToHistory(_this, group); - c_free(group); - } - transactionGroupAdminPurgeHistory(_this); - c_mutexUnlock(&_this->mutex); - c_iterFree(historyList); - } - c_free(pending); } -void -v_transactionGroupAdminTrigger( - v_transactionGroupAdmin _this, - v_reader owner) -{ - c_iter triggerList = c_iterNew(NULL); - v_dataReader reader; - v_transactionGroup group; - v_transaction transaction; - struct c_collectionIter it, jt; - - c_mutexLock(&_this->mutex); - if (c_count(_this->pending) > 0) { - for (group = c_collectionIterFirst(_this->pending, &it); group; group = c_collectionIterNext(&it)) { - if (group->triggered == FALSE) { - for (transaction = c_collectionIterFirst(group->transactions, &jt); transaction; transaction = c_collectionIterNext(&jt)) { - v_transactionTriggerList(transaction, triggerList); - } - group->triggered = TRUE; - } - } - TRACE_COHERENT_UPDATE(ADMIN_OWNER(_this), - "Trigger %u readers data available\n", c_iterLength(triggerList)); - } - c_mutexUnlock(&_this->mutex); - while ((reader = c_iterTakeFirst(triggerList)) != NULL) { - if (reader == v_dataReader(owner)) { - v_dataReaderTriggerNoLock(reader); - } else { - v_dataReaderTrigger(reader); - } - } - c_iterFree(triggerList); -} - -static c_bool -publisherReaderUpdate( - c_object o, - c_voidp arg) -{ - v_transactionPublisher publisher = v_transactionPublisher(o); - - assert(publisher); - assert(arg == NULL); - OS_UNUSED_ARG(arg); - - v_transactionPublisherRecalculateMatchCounts(publisher); - (void)v_transactionGroupAdminPendCompleteTransactions(v_transactionGroupAdmin(publisher->admin), publisher); - - return TRUE; -} - static c_bool publisherRecalculateMatchCounts( c_object o, @@ -1224,26 +1040,6 @@ publisherRecalculateMatchCounts( return TRUE; } -static c_bool -transactionWriterRemoveReader( - c_object o, - c_voidp arg) -{ - v_transactionGroupWriter writer = v_transactionGroupWriter(o); - v_transactionGroupReader found, reader = v_transactionGroupReader(arg); - - found = c_remove(writer->readers, reader, NULL, NULL); - if (found) { - TRACE_COHERENT_UPDATE(PUBLISHER_OWNER(v_transactionPublisher(writer->publisher)), - "PID(%u) WID(%u) removed reader(%u)\n", - v_transactionPublisher(writer->publisher)->publisherId, - writer->gid.localId, found->gid.localId); - c_free(found); - } - - return TRUE; -} - static c_bool v_transactionPublisherRemoveReader( c_object o, @@ -1268,21 +1064,17 @@ v_transactionPublisherRemoveReader( c_free(group); } } - - (void)c_walk(publisher->writers, transactionWriterRemoveReader, groupReader); - - publisherReaderUpdate(o, NULL); + (void)v_transactionGroupAdminPendCompleteTransactions(v_transactionGroupAdmin(publisher->admin), publisher); return TRUE; } - -/**************************************************************************** - * Protected functions - ****************************************************************************/ +_Check_return_ +_Ret_notnull_ +_Pre_satisfies_(v_objectKind(owner) == K_KERNEL || v_objectKind(owner) == K_SUBSCRIBER) v_transactionGroupAdmin v_transactionGroupAdminNew( - v_object owner) + _In_ v_object owner) { v_transactionGroupAdmin _this; v_kernel kernel; @@ -1292,39 +1084,59 @@ v_transactionGroupAdminNew( kernel = v_objectKernel(owner); _this = v_transactionGroupAdmin(v_objectNew(kernel, K_TRANSACTIONGROUPADMIN)); - if (_this) { - base = c_getBase(kernel); - c_mutexInit(base, &_this->mutex); + base = c_getBase(kernel); + (void)c_mutexInit(base, &_this->mutex); - if (v_objectKind(owner) == K_SUBSCRIBER) { - _this->readers = c_tableNew(v_kernelType(kernel, K_TRANSACTIONGROUPREADER), - "gid.systemId,gid.localId,gid.serial"); - } else { - assert(v_objectKind(owner) == K_KERNEL); - _this->readers = NULL; - } - _this->publishers = c_tableNew(v_kernelType(kernel, K_TRANSACTIONPUBLISHER), - "systemId, publisherId"); - _this->pending = c_listNew(v_kernelType(kernel, K_TRANSACTIONGROUP)); - if (v_objectKind(owner) == K_KERNEL) { - /* Only kernel owned transactionGroupAdmins need keep to history as this - * is a list of EOTs (wrapped in v_transactionGroups and v_transactions) - * which are required for alignment. - */ - _this->history = c_listNew(v_kernelType(kernel, K_TRANSACTIONGROUP)); - } else { - _this->history = NULL; - } - _this->owner = owner; - TRACE_COHERENT_UPDATE(owner, "=> 0x%"PA_PRIxADDR"\n", (os_address)_this); + if (v_objectKind(owner) == K_SUBSCRIBER) { + _this->readers = c_tableNew(v_kernelType(kernel, K_TRANSACTIONGROUPREADER), + "gid.systemId,gid.localId,gid.serial"); } else { - OS_REPORT(OS_ERROR, "v_transactionGroupAdminNew",0, - "Failed to allocate v_transactionGroupAdmin object"); - assert(FALSE); + assert(v_objectKind(owner) == K_KERNEL); + _this->readers = NULL; } + _this->publishers = c_tableNew(v_kernelType(kernel, K_TRANSACTIONPUBLISHER), + "systemId, publisherId"); + _this->pending = c_listNew(v_kernelType(kernel, K_TRANSACTIONGROUP)); + if (v_objectKind(owner) == K_KERNEL) { + /* Only kernel owned transactionGroupAdmins need keep to history as this + * is a list of EOTs (wrapped in v_transactionGroups and v_transactions) + * which are required for alignment. + */ + _this->history = c_listNew(v_kernelType(kernel, K_TRANSACTIONGROUP)); + } else { + _this->history = NULL; + } + _this->owner = owner; + + TRACE_COHERENT_UPDATE(owner, "=> 0x%"PA_PRIxADDR"\n", (os_address)_this); + return _this; } +struct processPublicationInfoHelper { + v_transactionGroupWriter writer; + v_kernel kernel; +}; + +static os_boolean +processPublicationInfo( + const v_message msg, + c_voidp arg) +{ + struct processPublicationInfoHelper *a = (struct processPublicationInfoHelper *)arg; + struct v_publicationInfo *info; + + info = v_builtinPublicationInfoData(msg); + if (v_gidEqual(info->key, a->writer->gid)) { + a->writer->rxo = v_kernel_rxoDataFromPublicationInfo(a->kernel, info); + a->writer->topicName = c_keep(info->topic_name); + a->writer->discovered = TRUE; + return OS_FALSE; + } + return OS_TRUE; +} + + /** * This operation inserts complete transactions into the group admin. * The transaction administration will move transactions that become complete @@ -1343,8 +1155,6 @@ v_transactionGroupAdminInsertTransaction( v_transactionGroup group, found; v_transactionGroupWriter writer, thisWriter = NULL; v_kernel kernel; - v_spliced spliced; - struct processPublicationInfoHelper helper; c_iter list = NULL; c_ulong i; c_ulong length; @@ -1361,7 +1171,7 @@ v_transactionGroupAdminInsertTransaction( if (transaction->eot->publisherId == 0) { assert(c_arraySize(transaction->eot->tidList) == 1); - group = v_transactionGroupNew(NULL, transaction); + group = v_transactionGroupNew(NULL, _this, transaction); if (group) { group->matchCount = 1; v_transactionGroupInsertTransaction(group, transaction); @@ -1387,8 +1197,6 @@ v_transactionGroupAdminInsertTransaction( group = v_transactionPublisherLookupTransaction(publisher, transaction); if (group) { kernel = v_objectKernel(_this); - spliced = v_kernelGetSpliced(kernel); - if (group->matchCount == 0) { /* matchCount can only be zero when the transactionGroup is just created */ struct v_tid *tidList = (struct v_tid *)transaction->eot->tidList; @@ -1403,27 +1211,21 @@ v_transactionGroupAdminInsertTransaction( thisWriter = c_keep(writer); } /* discovery of thisWriter is done later */ - if ((thisWriter != writer) && - (writer->discovered == FALSE)) { - assert(writer->topic == NULL); + if ((thisWriter != writer) && (writer->discovered == FALSE)) + { + struct processPublicationInfoHelper helper; + assert(writer->topicName == NULL); assert(writer->rxo == NULL); - memset(&helper, 0, sizeof(struct processPublicationInfoHelper)); helper.kernel = kernel; + helper.writer = writer; /* TGwriter can only be discovered here if the PublicationInfo * was received before the TGwriter was created. This also means * that this discovery will not impact any other open transactions. */ - if (v_splicedLookupPublicationInfo(spliced, - writer->gid, - processPublicationInfo, - &helper) == V_RESULT_OK) { - writer->rxo = helper.rxo; /* pass reference */ - writer->topic = helper.topic; /* pass reference */ - writer->discovered = TRUE; - + (void) v_kernelWalkPublications(kernel, processPublicationInfo, &helper); + if (writer->discovered) { (void)v_transactionGroupWriterMatch(writer, _this); - TRACE_COHERENT_UPDATE(ADMIN_OWNER(_this), "TID(%d) PID(%d) discovered %sWID(%u) matches %u\n", transaction->eot->transactionId, @@ -1451,10 +1253,10 @@ v_transactionGroupAdminInsertTransaction( writer = v_transactionPublisherLookupWriter(publisher, v_message(transaction->eot)->writerGID); } if (writer->discovered == FALSE) { - assert(writer->topic == NULL); + assert(writer->topicName == NULL); assert(writer->rxo == NULL); - writer->topic = c_keep(topic); + writer->topicName = c_keep(v_topicName(topic)); writer->rxo = v_kernel_rxoDataFromMessageQos(kernel, v_message(transaction->eot)->qos); writer->discovered = TRUE; @@ -1462,7 +1264,8 @@ v_transactionGroupAdminInsertTransaction( if (c_refCount(writer) > 3) { /* This writer is also referenced by other group transactions, - * update all groups including this one. */ + * update all groups including this one. + */ v_transactionPublisherRecalculateMatchCounts(publisher); } else { group->matchCount += v_transactionGroupWriterGetMatches(writer); @@ -1484,26 +1287,11 @@ v_transactionGroupAdminInsertTransaction( transaction->eot->publisherId, (os_address)group, group->matchCount); v_transactionGroupInsertTransaction(group, transaction); - if (v_transactionGroupComplete(group) == TRUE) { - if (!c_exists(_this->pending, group)) { - if (v_transactionGroupHasData(group)) { - c_append(_this->pending, group); - result = TRUE; - TRACE_COHERENT_UPDATE(ADMIN_OWNER(_this), - "Add group TID(%u) (0x%"PA_PRIxADDR") to pending list (size:%u)\n", - group->transactionId, - (os_address)group, - c_count(_this->pending)); - } else { - TRACE_COHERENT_UPDATE(ADMIN_OWNER(_this), - "Removing complete but empty group TID(%u) (0x%"PA_PRIxADDR")\n", - group->transactionId, - (os_address)group); - found = c_remove(publisher->transactions, group, NULL, NULL); - assert(found == group); - c_free(found); - } - } + if (v_transactionGroupComplete(group) == TRUE) { + result = v_transactionGroupAdminAddGroupToPending(_this, group); + found = c_remove(publisher->transactions, group, NULL, NULL); + assert(found == group); + c_free(found); } c_free(group); @@ -1520,9 +1308,7 @@ v_transactionGroupAdminAddReader( v_transactionGroupAdmin _this, v_reader reader) { - v_transactionGroupReader groupReader, added; - v_transactionGroup group; - c_list pending; + v_transactionGroupReader groupReader, found = NULL; v_kernel kernel; #ifdef TRACE_COHERENT v_topic topic; @@ -1533,50 +1319,38 @@ v_transactionGroupAdminAddReader( assert(v_objectKind(ADMIN_OWNER(_this)) == K_SUBSCRIBER); #ifdef TRACE_COHERENT - topic = v_dataReaderGetTopic(v_dataReader(reader)); - TRACE_COHERENT_UPDATE(ADMIN_OWNER(_this), - "add reader(%d) for topic '%s'\n", - v_publicGid(v_public(reader)).localId, - v_topicName(topic)); - c_free(topic); + topic = v_readerGetTopic(reader); + if(topic){ + TRACE_COHERENT_UPDATE(ADMIN_OWNER(_this), + "add reader(%d) for topic '%s'\n", + v_publicGid(v_public(reader)).localId, + v_topicName(topic)); + c_free(topic); + } else { + TRACE_COHERENT_UPDATE(ADMIN_OWNER(_this), + "add reader(%d), but it has already been deleted\n", + v_publicGid(v_public(reader)).localId); + } #endif kernel = v_objectKernel(_this); groupReader = v_transactionGroupReader(v_objectNew(kernel, K_TRANSACTIONGROUPREADER)); if (groupReader) { groupReader->gid = v_publicGid(v_public(reader)); - groupReader->topic = v_dataReaderGetTopic(v_dataReader(reader)); /* pass reference */ + groupReader->topic = v_readerGetTopic(reader); /* pass reference */ groupReader->rxo = v_kernel_rxoDataFromReaderQos(kernel, reader->qos); - c_mutexLock(&_this->mutex); - added = ospl_c_insert(_this->readers, groupReader); - assert(added == groupReader); - v_transactionGroupAdminMatchReader(_this, groupReader, FALSE); - (void)c_walk(_this->publishers, publisherRecalculateMatchCounts, NULL); - - pending = _this->pending; - _this->pending = c_listNew(v_kernelType(kernel, K_TRANSACTIONGROUP)); - while((group = c_take(pending)) != NULL) { - if (group->publisher == NULL) { - /* Group was complete before all its writers were deleted, with - * new reader it's no longer possible to determine completeness, - * remove it from pending list (group transaction is not in a - * publisher list anymore so it is removed). - */ - } else if (v_transactionGroupComplete(group)) { - ospl_c_insert(_this->pending, group); - } else { - /* Group has become incomplete again, reset trigger flag so it's - * triggered again when complete again. - */ - group->triggered = FALSE; + if(groupReader->topic){ + c_mutexLock(&_this->mutex); + found = ospl_c_insert(_this->readers, groupReader); + assert(found == groupReader); + if (v_transactionGroupAdminMatchReader(_this, groupReader, FALSE)) { + (void)c_walk(_this->publishers, publisherRecalculateMatchCounts, NULL); } - c_free(group); + c_mutexUnlock(&_this->mutex); + c_free(groupReader->topic); + c_free(found); } - c_free(pending); - c_mutexUnlock(&_this->mutex); - - c_free(added); } else { OS_REPORT(OS_ERROR, OS_FUNCTION, OS_ERROR, "Failed to allocate v_transactionGroupWriter object"); @@ -1590,8 +1364,8 @@ v_transactionGroupAdminRemoveReader( v_reader reader) { v_transactionGroupReader groupReader; - v_transactionGroup group, found; C_STRUCT(v_transactionGroupReader) dummy; + v_transactionGroup group; struct c_collectionIterD it; assert(_this); @@ -1614,10 +1388,10 @@ v_transactionGroupAdminRemoveReader( /* Now, remove all transactions related to this reader from the pending list. */ for (group = c_collectionIterDFirst(_this->pending, &it); group; group = c_collectionIterDNext(&it)) { + /* Sanity check, publisher should always be cleared for pending transactions */ + assert(group->publisher == NULL); - /* Remove the reader information from this group. - * It is most likely that this is already done by v_transactionPublisherRemoveReader, - * but not always (f.i. when the _this->publisher has been cleared and set to NULL). */ + /* Remove the reader information from this group. */ v_transactionGroupRemoveReader(group, groupReader); /* If the group is empty: remove it from the pending list. */ @@ -1627,61 +1401,18 @@ v_transactionGroupAdminRemoveReader( TRACE_COHERENT_UPDATE(ADMIN_OWNER(_this), "group(0x%"PA_PRIxADDR") TID(%u) removed as it became empty\n", (os_address)group, group->transactionId); + c_free(group); + } else if (group->aborted) { + c_collectionIterDRemove(&it); - /* Sanity check: - * The group should not be available in it's own linked publisher anymore. */ - if (group->publisher) { - found = c_find(v_transactionPublisher(group->publisher)->transactions, group); - assert(found == NULL); - if (found) { - c_free(found); - } - } - + TRACE_COHERENT_UPDATE(ADMIN_OWNER(_this), + "group(0x%"PA_PRIxADDR") TID(%u) removed as it became aborted\n", + (os_address)group, group->transactionId); c_free(group); } else { assert(v_transactionGroupComplete(group)); } } - - c_free(groupReader); - } - - c_mutexUnlock(&_this->mutex); -} - -void -v_transactionGroupAdminUpdateReader( - v_transactionGroupAdmin _this, - v_reader reader) -{ - v_transactionGroupReader groupReader; - C_STRUCT(v_transactionGroupReader) dummy; - v_kernel kernel; - - assert(_this); - assert(C_TYPECHECK(_this, v_transactionGroupAdmin)); - assert(v_objectKind(ADMIN_OWNER(_this)) == K_SUBSCRIBER); - - TRACE_COHERENT_UPDATE(ADMIN_OWNER(_this), - "update reader(%d)\n", - v_publicGid(v_public(reader)).localId); - - kernel = v_objectKernel(_this); - memset(&dummy, 0, C_SIZEOF(v_transactionGroupReader)); - dummy.gid = v_publicGid(v_public(reader)); - - c_mutexLock(&_this->mutex); - groupReader = c_find(_this->readers, &dummy); - assert(groupReader); /* Reader should exist within administration */ - if (groupReader) { - c_free(groupReader->rxo); - groupReader->rxo = v_kernel_rxoDataFromReaderQos(kernel, reader->qos); - if (v_transactionGroupAdminMatchReader(_this, groupReader, TRUE) == FALSE) { - /* Reader is updated but it did not result in a match change */ - } else { - (void)c_walk(_this->publishers, publisherReaderUpdate, NULL); - } c_free(groupReader); } @@ -1689,7 +1420,7 @@ v_transactionGroupAdminUpdateReader( } c_bool -v_transactionGroupAdminNotifyGroupCoherentPublication( +v_transactionGroupAdminNotifyPublication( v_transactionGroupAdmin _this, v_transactionWriter writer, c_bool dispose, @@ -1731,27 +1462,37 @@ v_transactionGroupAdminNotifyGroupCoherentPublication( assert(C_TYPECHECK(publisher, v_transactionPublisher)); if (dispose) { + C_STRUCT(v_transactionGroupWriter) dummy; + memset(&dummy, 0, C_SIZEOF(v_transactionGroupWriter)); + dummy.gid = writerGID; + /* Removal of a writer cannot make a previous incomplete transaction + * complete. Removal of a writer does ensure that we'll never receive + * data from it again and thus incomplete transactions will never + * become complete. + */ groupWriter = v_transactionPublisherRemoveWriter(publisher, writerGID); c_free(groupWriter); count = c_count(publisher->writers); for (group = c_collectionIterDFirst(publisher->transactions, &idt); group; group = c_collectionIterDNext(&idt)) { if (v_transactionGroupComplete(group) == FALSE) { - /* Remove incomplete group transactions from publisher */ - c_collectionIterDRemove(&idt); - /* Incomplete transactions should not be in the pending list. */ - assert(c_remove(_this->pending, group, NULL, NULL) == NULL); - c_free(group); - } else { - if (count == 0) { - /* Remove backref from group. When the group is complete the pending - * list also has a reference. - */ + /* Only remove groups that are affected by the disposal of this writer. */ + if (c_exists(group->writers, &dummy)) { + group->aborted = TRUE; + group->obsolete = TRUE; + group->deleted = TRUE; group->publisher = NULL; + + c_append(_this->pending, group); + /* Remove incomplete group transactions from publisher */ + c_collectionIterDRemove(&idt); + c_free(group); + result = TRUE; } } } if (count == 0) { + /* Publisher not longer has writer so it can be removed */ found = c_remove(_this->publishers,publisher,NULL,NULL); c_free(found); } @@ -1759,24 +1500,27 @@ v_transactionGroupAdminNotifyGroupCoherentPublication( groupWriter = v_transactionPublisherFindWriter(publisher, writerGID); if (groupWriter) { if (info) { - if (groupWriter->discovered == FALSE) { - /* The writer update function (see a few lines below this), - * will indicate that the writer is discovered. - * Link this discovered writer into the related groups. */ - for (group = c_collectionIterFirst(publisher->transactions, &it); group; group = c_collectionIterNext(&it)) { - (void)ospl_c_insert(group->writers, groupWriter); - } - } + /* For newly discovered writers link info to the relaed groups. */ v_transactionGroupWriterUpdate(groupWriter, info); - } - if (v_objectKind(ADMIN_OWNER(_this)) == K_SUBSCRIBER) { - if (v_transactionGroupWriterMatch(groupWriter, _this) == TRUE) { - v_transactionPublisherRecalculateMatchCounts(publisher); + (void)v_transactionGroupWriterMatch(groupWriter, _this); + for (group = c_collectionIterFirst(publisher->transactions, &it); group; group = c_collectionIterNext(&it)) { + /* Get the EOT writer list and verify that the group is affected by the discovered writer + * before updating the group admin. + */ + v_transaction t = c_read(group->transactions); + if (t) { + c_ulong i, length; + struct v_tid *tidList = (struct v_tid *)t->eot->tidList; + length = c_arraySize(t->eot->tidList); + for (i=0; itransactions, &it); txn && result; txn = c_collectionIterNext(&it)) { - admin = v_transactionGetAdmin(txn); - if (v_objectKind(admin->owner) == K_GROUP) { - if (v_group(admin->owner) == a->vgroup) { - result = a->action (txn, a->arg); + if (!group->aborted) { + for (txn = c_collectionIterFirst(group->transactions, &it); txn && result; txn = c_collectionIterNext(&it)) { + admin = v_transactionGetAdmin(txn); + if (v_objectKind(admin->owner) == K_GROUP) { + if (v_group(admin->owner) == a->vgroup) { + result = a->action (txn, a->arg); + } } } } return result; } - static c_bool publisherWalk( c_object o, @@ -1847,16 +1592,12 @@ v_transactionGroupAdminWalkTransactions( walkArg.arg = arg; walkArg.vgroup = vgroup; - transactionGroupAdminPurgeHistory(_this); (void)c_walk(_this->history, groupWalk, &walkArg); (void)c_walk(_this->pending, groupWalk, &walkArg); (void)c_walk(_this->publishers, publisherWalk, &walkArg); c_mutexUnlock(&_this->mutex); } -/* - * Call should be protected by v_subscriberLockAccess - */ void v_transactionGroupAdminFlush( v_transactionGroupAdmin _this) @@ -1926,22 +1667,114 @@ v_transactionGroupAdminNoMessageFromWriterExist( return result; } +static c_bool +publisherPurgeObsolete( + c_object o, + c_voidp arg) +{ + v_transactionPublisher publisher = v_transactionPublisher(o); + struct c_collectionIterD it; + v_transactionGroup group, found; + c_list list = (c_list)arg; + + for (group = c_collectionIterDFirst(publisher->transactions, &it); group; group = c_collectionIterDNext(&it)) { + if (group->obsolete == TRUE) { + found = c_append(list, group); + assert(found == group); + OS_UNUSED_ARG(found); + group->publisher = NULL; + group->aborted = TRUE; + c_collectionIterDRemove(&it); + c_free(group); + } + } + + return TRUE; +} /** - * \brief This operation removes groupTransactions from the history - * when the contained transactions are not referenced by samples - * anymore + * \brief This operation links to the groupTransactions. + * When this is the first link it is added to the history. * * \param _this : The transactionGroupAdmin this operation operates on. * * \return : None */ void -v_transactionGroupAdminPurgeHistory( - v_transactionGroupAdmin _this) +v_transactionGroupLink( + v_transactionGroup _this) { - c_mutexLock(&_this->mutex); - transactionGroupAdminPurgeHistory(_this); - c_mutexUnlock(&_this->mutex); + os_uint32 value; + v_transactionGroupAdmin admin; + v_transactionGroup found; + + if (_this) { + value = pa_inc32_nv(&_this->historyLinks); + + if (value == 1) { + admin = v_transactionGroupAdmin(_this->admin); + assert(v_objectKind(admin->owner) == K_KERNEL); + + TRACE_COHERENT_UPDATE(TRANSACTION_OWNER(_this), "Group(0x%"PA_PRIxADDR") PID(%u) TID(%u) " + "add to history\n", + (os_address)_this, _this->publisherId, _this->transactionId); + + c_mutexLock(&admin->mutex); + found = c_append(admin->history, _this); + assert(found == _this); + OS_UNUSED_ARG(found); + c_mutexUnlock(&admin->mutex); + } + } } +/** + * \brief This operation unlinks from the groupTransactions. + * When there are no more links to the groupTransaction it is + * removed from the history. + * + * \param _this : The transactionGroupAdmin this operation operates on. + * + * \return : None + */ +void +v_transactionGroupUnlink( + v_transactionGroup _this) +{ + os_uint32 value; + v_transactionGroupAdmin admin; + v_transactionGroup found; + + if (_this) { + value = pa_dec32_nv(&_this->historyLinks); + + if (value == 0) { + admin = v_transactionGroupAdmin(_this->admin); + assert(v_objectKind(admin->owner) == K_KERNEL); + + TRACE_COHERENT_UPDATE(TRANSACTION_OWNER(_this), "Group(0x%"PA_PRIxADDR") PID(%u) TID(%u) " + "remove from history\n", + (os_address)_this, _this->publisherId, _this->transactionId); + + c_mutexLock(&admin->mutex); + +#ifndef NDEBUG + /* Sanity check, when value equals zero non of the transactions are + * allowed to have a link remaining. + */ + { + struct c_collectionIter it; + v_transaction txn; + for (txn = c_collectionIterFirst(_this->transactions, &it); txn; txn = c_collectionIterNext(&it)) { + assert(pa_ld32(&txn->historyLinks) == 0); + } + } +#endif + + found = c_remove(admin->history, _this, NULL, NULL); + assert(found == _this); + c_mutexUnlock(&admin->mutex); + c_free(found); + } + } +} diff --git a/src/kernel/code/v_typeRepresentation.c b/src/kernel/code/v_typeRepresentation.c index 28da837f6..95761582e 100644 --- a/src/kernel/code/v_typeRepresentation.c +++ b/src/kernel/code/v_typeRepresentation.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,9 +24,6 @@ #include "v__participant.h" #include "v_typeRepresentation.h" -/************************************************************** - * Protected functions - **************************************************************/ v_typeRepresentation v__typeRepresentationNew ( v_kernel kernel, @@ -64,9 +62,6 @@ v__typeRepresentationNew ( return tr; } -/************************************************************** - * Public functions - **************************************************************/ v_typeHash v_typeHashFromArray ( const os_uchar *array, @@ -142,8 +137,7 @@ v_typeRepresentationNew ( if ((tr->dataRepresentationId != found->dataRepresentationId) || (tr->typeHash.msb != found->typeHash.msb) || (tr->typeHash.lsb != found->typeHash.lsb)) { - /* Already a TypeRepresentation in participant which is not the one - * being added. */ + /* Already a TypeRepresentation in participant which is not the one being added. */ c_free(found); c_free(tr); tr = NULL; diff --git a/src/kernel/code/v_waitset.c b/src/kernel/code/v_waitset.c index 72f81a42d..cd74beed0 100644 --- a/src/kernel/code/v_waitset.c +++ b/src/kernel/code/v_waitset.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,7 +22,7 @@ #include "v__observer.h" #include "v__subscriber.h" #include "v__dataView.h" -#include "v_observable.h" +#include "v__observable.h" #include "v_public.h" #include "v_proxy.h" #include "v_event.h" @@ -37,10 +38,7 @@ #define WAITSET_BUSY_FLAG (0x80000000) #define v_waitsetEventList(_this) \ - (v_observer(_this)->eventData) - -#define v_waitsetWakeup(_this,event,userData) \ - v_observerNotify(v_observer(_this),event,userData) + (_this->eventList) static void v_waitsetClearRemovedObserverPendingEvents( @@ -57,9 +55,9 @@ waitsetDetachAll(v_waitset _this) void* userDataRemoved = NULL; /* disable interest to avoid arrival of new events. */ - v_observerSetEventMask(v_observer(_this), 0); + OSPL_SET_EVENT_MASK(_this, 0); - v_waitsetLock(_this); + OSPL_LOCK(_this); /* remove and free all events */ eventList = v_waitsetEvent(v_waitsetEventList(_this)); @@ -73,14 +71,14 @@ waitsetDetachAll(v_waitset _this) proxy = _this->observables; _this->observables = NULL; /* wakeup blocking threads. */ - v_waitsetWakeup(_this, NULL, NULL); - v_waitsetUnlock(_this); + OSPL_TRIGGER_EVENT(_this, NULL, NULL); + OSPL_UNLOCK(_this); while (proxy) { result = v_handleClaim(proxy->source,(v_object *)&o); if (result == V_HANDLE_OK) { + (void)OSPL_REMOVE_OBSERVER(o,_this, V_EVENTMASK_ALL, &userDataRemoved); (void)v_handleRelease(proxy->source); - (void)v_observableRemoveObserver(o,v_observer(_this), &userDataRemoved); } removed = proxy; proxy = proxy->next; @@ -102,13 +100,13 @@ v_waitsetNew( _this = v_waitset(v_objectNew(kernel,K_WAITSET)); if (_this != NULL) { v_observerInit(v_observer(_this)); - v_observerSetEventData(v_observer(_this), NULL); _this->observables = NULL; _this->participant = p; _this->waitsetEventEnabled = TRUE; _this->count = 0; _this->waitDisconnectCount = 0; - c_condInit(c_getBase(_this), &_this->syncDisconnect, &v_observer(_this)->mutex); + _this->eventList = NULL; + c_condInit(c_getBase(_this), &_this->syncDisconnect, &v_observable(_this)->mutex); v_participantAdd(p, v_object(_this)); } @@ -170,10 +168,11 @@ v_waitsetNotify( assert(_this != NULL); assert(C_TYPECHECK(_this,v_waitset)); + assert(e != NULL); EVENT_TRACE("v_waitsetNotify: _this(0x%x), event(0x%x), userData(0x%x)\n", _this, e, userData); - if ((_this->waitsetEventEnabled) && (e != NULL)) { + if (_this->waitsetEventEnabled && e->source) { sourceHandle = v_publicHandle(v_public(e->source)); /* Group events by origin of event */ @@ -216,39 +215,6 @@ on_data_available( return OS_TRUE; } -static void -flush_pending_grouptransactions( - v_query query) -{ - v_collection src; - v_subscriber subscriber; - - src = v_querySource(query); - switch (v_objectKind(src)) { - case K_DATAREADER: - subscriber = v_readerSubscriber(v_reader(src)); - break; - case K_DATAVIEW: - subscriber = v_readerSubscriber(v_reader(v_dataViewReader(v_dataView(src)))); - break; - default: - subscriber = NULL; - break; - } - if (subscriber) { - v_subscriberLock(subscriber); - if (v__subscriberRequireAccessLockCoherent(subscriber)) { - v_subscriberLockAccess(subscriber); - v_subscriberUnlock(subscriber); - v_transactionGroupAdminFlush(subscriber->transactionGroupAdmin); - v_subscriberLock(subscriber); - v_subscriberUnlockAccess(subscriber); - } - v_subscriberUnlock(subscriber); - } - c_free(src); -} - c_bool test_condition ( v_handle handle) @@ -265,12 +231,10 @@ test_condition ( break; case K_DATAREADERQUERY: EVENT_TRACE("v_waitset::test_condition K_DATAREADERQUERY:(0x%x) }\n", condition); - flush_pending_grouptransactions(v_query(condition)); (void)v_dataReaderQueryTest(v_dataReaderQuery(condition), on_data_available, &events); break; case K_DATAVIEWQUERY: EVENT_TRACE("v_waitset::test_condition K_DATAVIEWQUERY::(0x%x) }\n", condition); - flush_pending_grouptransactions(v_query(condition)); (void)v_dataViewQueryTest(v_dataViewQuery(condition), on_data_available, &events); break; default: @@ -296,7 +260,6 @@ v_waitsetWait2( v_proxy *buffer, proxy; c_long count; c_ulong length, i, bufferSize; - os_boolean triggered; assert(_this != NULL); assert(C_TYPECHECK(_this,v_waitset)); @@ -304,7 +267,7 @@ v_waitsetWait2( /* Test trigger values of attached observables. */ count = 0; - v_waitsetLock(_this); + OSPL_LOCK(_this); if (_this->count > INITIAL_BUFFER_SIZE) { /* Initial buffer size is insufficient so allocate a new one. */ buffer = os_malloc(_this->count * sizeof(*buffer)); @@ -321,18 +284,11 @@ v_waitsetWait2( } assert(length == _this->count); - /* We need to release the lock to avoid deadlock while checking the conditions, - * this implies that data available triggers may be received just after testing them - * (i.e. conditions becoming true). - * To avoid missing these triggers the data available event flag is reset and afterwards - * just before blocking the flags are checked for events. - */ - triggered = (v_observer(_this)->eventFlags & V_EVENT_TRIGGER); - v_observer(_this)->eventFlags &= V_EVENT_OBJECT_DESTROYED; + (void)v_observerGetEventFlags(v_observer(_this)); /* reset event flags */ if (length > 0) { _this->waitDisconnectCount |= WAITSET_BUSY_FLAG; } - v_waitsetUnlock(_this); + OSPL_UNLOCK(_this); for (i=0; isource)) { @@ -343,8 +299,7 @@ v_waitsetWait2( } proceed = action(NULL, arg); /* test guard conditions. */ - /* - * If none of the conditions evaluate true then block until triggered and then + /* If none of the conditions evaluate true then block until triggered and then * reevaluate the conditions and callback on each true conditions. */ @@ -354,15 +309,15 @@ v_waitsetWait2( } else { c_ulong wait_flags; - v_waitsetLock(_this); + OSPL_LOCK(_this); _this->waitDisconnectCount &= ~WAITSET_BUSY_FLAG; if (_this->waitDisconnectCount > 0) { c_condBroadcast(&_this->syncDisconnect); } - if (!(triggered) && (v_observerGetEventFlags(v_observer(_this)) == 0)) { + if (v_observerGetEventFlags(v_observer(_this)) == 0) { EVENT_TRACE("v_waitsetWait: Enter Timed Wait waitset(0x%x)\n", _this); - wait_flags = v__observerTimedWait(v_observer(_this),time); - v__observerClearEventFlags(_this); + wait_flags = OSPL_CATCH_EVENT(_this,time); + OSPL_CLEAR_EVENT_FLAGS(_this); if (wait_flags & V_EVENT_OBJECT_DESTROYED) { result = V_RESULT_DETACHING; } else if (wait_flags & V_EVENT_TIMEOUT) { @@ -387,7 +342,7 @@ v_waitsetWait2( _this->waitDisconnectCount |= WAITSET_BUSY_FLAG; } } - v_waitsetUnlock(_this); + OSPL_UNLOCK(_this); if (result != V_RESULT_TIMEOUT) { for (i=0; isource)) { @@ -401,12 +356,12 @@ v_waitsetWait2( } } - v_waitsetLock(_this); + OSPL_LOCK(_this); _this->waitDisconnectCount &= ~WAITSET_BUSY_FLAG; if (_this->waitDisconnectCount > 0) { c_condBroadcast(&_this->syncDisconnect); } - v_waitsetUnlock(_this); + OSPL_UNLOCK(_this); if (bufferSize > INITIAL_BUFFER_SIZE) { assert(buffer != initial); @@ -417,6 +372,20 @@ v_waitsetWait2( return result; } +static c_bool +event_list_action( + c_object o, + c_voidp arg) +{ + v_waitset ws = v_waitset(o); + v_waitsetEvent *list = (v_waitsetEvent *)arg; + + *list = v_waitsetEvent(v_waitsetEventList(ws)); + v_waitsetEventList(ws) = NULL; + + return TRUE; +} + v_result v_waitsetWait( v_waitset _this, @@ -424,7 +393,8 @@ v_waitsetWait( c_voidp arg, const os_duration time) { - v_waitsetEvent event, eventList; + v_waitsetEvent event; + v_waitsetEvent eventList = NULL; v_result result = V_RESULT_OK; c_ulong wait_flags; @@ -432,21 +402,16 @@ v_waitsetWait( assert(C_TYPECHECK(_this,v_waitset)); wait_flags = 0; - v_waitsetLock(_this); - eventList = v_waitsetEvent(v_waitsetEventList(_this)); + OSPL_LOCK(_this); EVENT_TRACE("v_waitsetWait: Enter Timed Wait waitset(0x%x)\n", _this); - while ((eventList == NULL) && - (!(wait_flags & (V_EVENT_OBJECT_DESTROYED | V_EVENT_TIMEOUT)))) - { + do { EVENT_TRACE("v_waitsetWait: -- waitset(0x%x) No events => block!\n", _this); - wait_flags = v__observerTimedWait(v_observer(_this),time); + wait_flags = OSPL_CATCH_EVENT_ACTION(_this, time, event_list_action, &eventList); EVENT_TRACE("v_waitsetWait: -- waitset(0x%x) Trigger! => unblock! result flags = 0x%x\n", _this, wait_flags); - eventList = v_waitsetEvent(v_waitsetEventList(_this)); - } - v__observerClearEventFlags(_this); - v_waitsetEventList(_this) = NULL; - v_waitsetUnlock(_this); + } while ((eventList == NULL) && + (!(wait_flags & (V_EVENT_OBJECT_DESTROYED | V_EVENT_TIMEOUT)))); + OSPL_UNLOCK(_this); if (wait_flags & V_EVENT_OBJECT_DESTROYED) { result = V_RESULT_DETACHING; @@ -475,35 +440,59 @@ v_waitsetWait( return result; } -void -v_waitsetTrigger( +static void +_waitsetTriggerEvent( v_waitset _this, + v_event e, c_voidp eventArg) { v_waitsetEvent event; - assert(_this != NULL); - assert(C_TYPECHECK(_this,v_waitset)); - - v_waitsetLock(_this); + OSPL_LOCK(_this); if (_this->waitsetEventEnabled) { event = c_new(v_kernelType(v_objectKernel(_this),K_WAITSETEVENT)); - event->kind = V_EVENT_TRIGGER; + event->kind = (e == NULL) ? V_EVENT_TRIGGER : e->kind; event->source = v_publicHandle(v_public(_this)); event->userData = eventArg; event->eventData = NULL; event->next = v_waitsetEvent(v_waitsetEventList(_this)); v_waitsetEventList(_this) = (c_voidp)event; - EVENT_TRACE("v_waitsetTrigger: waitset(0x%x), userData(0x%x) }\n", _this, eventArg); - v_observerNotify(v_observer(_this), NULL, NULL); - } else { - /* TODO: It would be more efficient only to trigger when waiting but this not always work - * e.g. tc_waitset_stress test will crash. need to investigate. - */ - EVENT_TRACE("v_waitsetTrigger: waitset(0x%x), userData(0x%x) }\n", _this, eventArg); - v_observerNotify(v_observer(_this), NULL, NULL); } - v_waitsetUnlock(_this); + /* TODO: It would be more efficient only to trigger when waiting but this not always work + * e.g. tc_waitset_stress test will crash. need to investigate. + */ + EVENT_TRACE("v_waitsetTrigger: waitset(0x%x), userData(0x%x) }\n", _this, eventArg); + OSPL_TRIGGER_EVENT(_this, e, NULL); + OSPL_UNLOCK(_this); +} + +void +v_waitsetTrigger( + v_waitset _this, + c_voidp eventArg) +{ + assert(_this != NULL); + assert(C_TYPECHECK(_this,v_waitset)); + + _waitsetTriggerEvent(_this, NULL, eventArg); +} + +void +v_waitsetPrepareDestroy( + v_waitset _this, + c_voidp eventArg) +{ + C_STRUCT(v_event) e; + + assert(_this != NULL); + assert(C_TYPECHECK(_this,v_waitset)); + + e.kind = V_EVENT_OBJECT_DESTROYED; + e.data = NULL; + e.handled = FALSE; + e.source = NULL; + + _waitsetTriggerEvent(_this, &e, eventArg); } c_bool @@ -519,7 +508,7 @@ v_waitsetAttach ( assert(_this != NULL); assert(C_TYPECHECK(_this,v_waitset)); - v_waitsetLock(_this); + OSPL_LOCK(_this); handle = v_publicHandle(v_public(o)); proxy = _this->observables; while (proxy) { @@ -533,19 +522,22 @@ v_waitsetAttach ( _this->count++; } _this->waitDisconnectCount |= WAITSET_BUSY_FLAG; - v_waitsetUnlock(_this); - result = v_observableAddObserver(o,v_observer(_this), userData); + OSPL_UNLOCK(_this); + { + c_ulong mask = OSPL_GET_EVENT_MASK(_this); + result = OSPL_ADD_OBSERVER(o,_this, mask, userData); + } /* wakeup blocking threads to evaluate new condition. */ if (test_condition(handle)) { v_waitsetTrigger(_this, NULL); } - v_waitsetLock(_this); + OSPL_LOCK(_this); _this->waitDisconnectCount &= ~WAITSET_BUSY_FLAG; if (_this->waitDisconnectCount > 0) { c_condBroadcast(&_this->syncDisconnect); } - v_waitsetUnlock(_this); + OSPL_UNLOCK(_this); return result; } @@ -565,7 +557,7 @@ v_waitsetDetach ( assert(C_TYPECHECK(_this,v_waitset)); handle = v_publicHandle(v_public(o)); - v_waitsetLock(_this); + OSPL_LOCK(_this); prev = NULL; proxy = _this->observables; while (proxy) { @@ -585,11 +577,11 @@ v_waitsetDetach ( } _this->waitDisconnectCount++; while ((_this->waitDisconnectCount & WAITSET_BUSY_FLAG) == WAITSET_BUSY_FLAG) { - c_condWait(&_this->syncDisconnect, &v_observer(_this)->mutex); + c_condWait(&_this->syncDisconnect, &v_observable(_this)->mutex); } _this->waitDisconnectCount--; - v_waitsetUnlock(_this); - removed = v_observableRemoveObserver(o,v_observer(_this), &userDataRemoved); + OSPL_UNLOCK(_this); + removed = OSPL_REMOVE_OBSERVER(o,_this, V_EVENTMASK_ALL, &userDataRemoved); if (removed) { result = (c_long) _this->count; } else { @@ -617,7 +609,7 @@ v_waitsetClearRemovedObserverPendingEvents( v_waitsetEvent event; v_waitsetEvent prevEvent = NULL; - v_waitsetLock(_this); + OSPL_LOCK(_this); EVENT_TRACE("v_waitsetClearRemovedObserverPendingEvents: waitset(0x%x), userData(0x%x)\n", _this, userDataRemoved); eventList = v_waitsetEvent(v_waitsetEventList(_this)); @@ -655,7 +647,7 @@ v_waitsetClearRemovedObserverPendingEvents( event = event->next; } } - v_waitsetUnlock(_this); + OSPL_UNLOCK(_this); } } @@ -668,9 +660,9 @@ v_waitsetCount( assert(_this != NULL); assert(C_TYPECHECK(_this,v_waitset)); - v_waitsetLock(_this); + OSPL_LOCK(_this); count = _this->count; - v_waitsetUnlock(_this); + OSPL_UNLOCK(_this); return count; } diff --git a/src/kernel/code/v_writer.c b/src/kernel/code/v_writer.c index 597dbd26f..dbd9635a2 100644 --- a/src/kernel/code/v_writer.c +++ b/src/kernel/code/v_writer.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -56,6 +57,7 @@ #include "v_writerStatistics.h" #include "v_message.h" #include "v_messageQos.h" +#include "v__nameSpace.h" #include "c_iterator.h" #include "c_stringSupport.h" @@ -65,9 +67,6 @@ #include "stdio.h" -/************************************************************** - * Private functions - **************************************************************/ const char* v_writeResultString( v_writeResult result) @@ -154,29 +153,42 @@ v_writerGroupSetAdd ( v_group g) { c_type type; - v_writerGroup proxy; + v_writerGroup proxy = NULL; + v_writerGroup wg; v_kernel kernel; struct v_writerGroupSet *set; + c_bool found = FALSE; set = &w->groupSet; - kernel = v_objectKernel(g); - type = v_kernelType(kernel,K_WRITERGROUP); - proxy = c_new(type); - if (proxy) { - proxy->group = c_keep(g); - proxy->next = set->firstGroup; - proxy->targetCache = v_writerCacheNew(kernel, V_CACHE_CONNECTION); - set->firstGroup = proxy; - } else { - OS_REPORT(OS_FATAL, - "v_writerGroupSetAdd",V_RESULT_INTERNAL_ERROR, - "Failed to allocate proxy."); - assert(FALSE); + wg = set->firstGroup; + while (wg && !found) { + if (wg->group == g) { + found = TRUE; + } + wg = wg->next; } - /* Notify the group about this writer being connected. */ - v_groupNotifyWriter(g,w); + if (!found) { + kernel = v_objectKernel(g); + type = v_kernelType(kernel,K_WRITERGROUP); + proxy = c_new(type); + + if (proxy) { + proxy->group = c_keep(g); + proxy->next = set->firstGroup; + proxy->targetCache = v_writerCacheNew(kernel, V_CACHE_CONNECTION); + set->firstGroup = proxy; + } else { + OS_REPORT(OS_FATAL, + "v_writerGroupSetAdd",V_RESULT_INTERNAL_ERROR, + "Failed to allocate proxy."); + assert(FALSE); + } + + /* Notify the group about this writer being connected. */ + v_groupNotifyWriter(g,w); + } return c_keep(proxy); } @@ -229,14 +241,14 @@ v_writerGroupWalk( { c_bool proceed; - v_observerLock(v_observer(w)); + OSPL_LOCK(w); proceed = v_writerGroupWalkUnlocked(w, action, arg); - v_observerUnlock(v_observer(w)); + OSPL_UNLOCK(w); return proceed; } -/* This function can only be called in case the observerLock of the writer has +/* This function can only be called in case the OSPL_LOCK of the writer has * been locked prior to calling this function. */ c_bool @@ -397,7 +409,8 @@ doWait ( if(v_writerIsSynchronous(w)){ /* In case the writer is synchronous, there will be no blocking on * resource limits. In this case the write will immediately return - * with OUT_OF_RESOURCES. See dds2810 for more details. */ + * with OUT_OF_RESOURCES. See dds2810 for more details. + */ result = V_WRITE_OUT_OF_RESOURCES; OS_REPORT(OS_ERROR, "v_writer::doWait", result, "Out of resources: Synchronous DataWriter out of history resources"); @@ -405,12 +418,12 @@ doWait ( if (w->infWait == FALSE) { relTimeOut = os_timeEDiff(until, os_timeEGet()); if (relTimeOut > 0) { - flags = v__observerTimedWait(v_observer(w), relTimeOut); + flags = OSPL_CATCH_EVENT(w, relTimeOut); } else { flags = V_EVENT_TIMEOUT; } } else { - flags = v__observerWait(v_observer(w)); + flags = OSPL_CATCH_EVENT(w, OS_DURATION_INFINITE); } if (flags & V_EVENT_OBJECT_DESTROYED) { result = V_WRITE_PRE_NOT_MET; @@ -455,6 +468,7 @@ groupWrite( item = v_writerCacheItemNew(proxy->targetCache,instance); v_writerCacheInsert(proxy->targetCache,item); v_writerCacheInsert(a->instance->targetCache,item); + v_writerInstanceResetState(a->instance, L_UNREGISTER); v_writerInstanceSetState(a->instance, L_REGISTER); c_free(instance); c_free(item); @@ -620,7 +634,8 @@ writeGroupInstance( instance = v_groupInstance(item->instance); if (instance && (v_groupInstanceOwner(instance) == a->group)) { /* This call is only used for L_DISPOSED and L_UNREGISTER messages, - * which will never be rejected. */ + * which will never be rejected. + */ (void) v_groupWrite(v_groupInstanceOwner(instance), a->message, &instance, @@ -654,7 +669,8 @@ disconnectInstanceCommon( /* It is not correct to leave out the DISPOSE in case the state of the * writer-instance is DISPOSED, since there is no guarantee the state * of the instance in the group and the readers is the same (e.g., - * changed by another writer). */ + * changed by another writer). + */ message = v_writerInstanceCreateMessage(i); v_nodeState(message) = L_DISPOSED; if (w->transactionStarted) { @@ -673,7 +689,6 @@ disconnectInstanceCommon( grouparg.node = NULL; (void) v_writerCacheWalk(i->targetCache, writeGroupInstance, &grouparg); c_free(message); - v_writerInstanceSetState(i, L_DISPOSED); } @@ -695,7 +710,8 @@ disconnectInstanceCommon( /* The v_writerCacheWalk function stops iterating when a cacheNode for a * matching group has been found. In that case it aborts the walk with - * return value FALSE. */ + * return value FALSE. + */ if (!v_writerCacheWalk(i->targetCache, writeGroupInstance, &grouparg)) { /* When a match was found, the resulting node should be non-NULL. */ assert(grouparg.node); @@ -970,23 +986,24 @@ autoPurgeSuspendedSamples( } } -static void +static v_message assertLiveliness ( v_writer w) { v_kernel kernel; - v_message builtinMsg; + v_message msg = NULL; v_leaseRenew(w->livelinessLease, w->qos->liveliness.v.lease_duration); if (w->alive == FALSE) { kernel = v_objectKernel(w); w->alive = TRUE; if (kernel->builtin && kernel->builtin->kernelQos->builtin.v.enabled) { - builtinMsg = v_builtinCreatePublicationInfo(kernel->builtin,w); - v_writeBuiltinTopic(kernel, V_PUBLICATIONINFO_ID, builtinMsg); - c_free(builtinMsg); + c_free(w->pubInfo); + w->pubInfo = v_builtinCreatePublicationInfo(kernel->builtin,w); + msg = c_keep(w->pubInfo); } } + return msg; } static v_writeResult @@ -1052,7 +1069,8 @@ writerDispose( } /* The writer statistics are updated for the newly inserted * instance (with its initial values). The previous state - * was nothing, so 0 is passed as the oldState. */ + * was nothing, so 0 is passed as the oldState. + */ UPDATE_WRITER_STATISTICS(w, instance, 0); } else { found = c_remove(w->instances,instance,NULL,NULL); @@ -1130,7 +1148,6 @@ writerUnregister( assert(C_TYPECHECK(w,v_writer)); assert(C_TYPECHECK(message,v_message)); - /* statistics update */ if (w->statistics) { w->statistics->numberOfUnregisters++; } @@ -1220,19 +1237,14 @@ writerUnregister( message->sequenceNumber = w->sequenceNumber++; if (( v__writerNeedsInOrderResends(w) && !v__writerHasResendsPending(w)) || (!v__writerNeedsInOrderResends(w) && v_writerInstanceTestState(instance, L_EMPTY))) { - /* An unregister-message is never rejected */ if (c_baseMakeMemReservation(c_getBase(w), C_MM_RESERVATION_HIGH)) { (void) writerWrite(w, instance, message); c_baseReleaseMemReservation(c_getBase(w), C_MM_RESERVATION_HIGH); v_writerInstanceSetState(instance, L_UNREGISTER); + v_writerInstanceResetState(instance, L_REGISTER); + v_writerCacheDeinit(instance->targetCache); if (v_writerInstanceTestState(instance, L_EMPTY)) { found = c_remove(w->instances, instance, NULL, NULL); - /* Instance is removed from writer, so also subtract related - * statistics. */ - assert(found == instance); - UPDATE_WRITER_STATISTICS_REMOVE_INSTANCE(w, instance); - v_writerCacheDeinit(instance->targetCache); - v_writerInstanceResetState(instance, L_REGISTER); v_writerFreeInstance(found); } else { UPDATE_WRITER_STATISTICS(w, instance, oldState); @@ -1260,26 +1272,25 @@ v_writerAssertByPublisher( v_writer w) { v_kernel kernel; - v_message builtinMsg; - c_bool writeBuiltinSample = FALSE; + v_message builtinMsg = NULL; assert(w != NULL); assert(C_TYPECHECK(w,v_writer)); if (w->qos->liveliness.v.kind == V_LIVELINESS_PARTICIPANT) { - v_observerLock(v_observer(w)); + OSPL_LOCK(w); kernel = v_objectKernel(w); if (w->alive == FALSE) { w->alive = TRUE; if (kernel->builtin && kernel->builtin->kernelQos->builtin.v.enabled) { - writeBuiltinSample = TRUE; + c_free(w->pubInfo); + w->pubInfo = v_builtinCreatePublicationInfo(kernel->builtin, w); + builtinMsg = c_keep(w->pubInfo); } } - v_observerUnlock(v_observer(w)); - v_leaseRenew(w->livelinessLease, w->qos->liveliness.v.lease_duration); - if (writeBuiltinSample) { - builtinMsg = v_builtinCreatePublicationInfo(kernel->builtin, w); + OSPL_UNLOCK(w); + if (builtinMsg) { v_writeBuiltinTopic(kernel, V_PUBLICATIONINFO_ID, builtinMsg); c_free(builtinMsg); } @@ -1302,8 +1313,10 @@ publish( g = v_groupSetCreate(kernel->groupSet,d,w->topic); proxy = v_writerGroupSetAdd(writer,g); - c_tableWalk(w->instances, connectInstance, proxy); - c_free(proxy); + if (proxy) { + c_tableWalk(w->instances, connectInstance, proxy); + c_free(proxy); + } } static void @@ -1492,14 +1505,11 @@ writerSingleTransaction( (w->coherent_access == TRUE) && (w->transactionStarted == FALSE)) { p = c_keep(w->publisher); - v_observerUnlock(v_observer(w)); - - c_lockWrite(&p->lock); + OSPL_UNLOCK(w); - result = v__publisherCoherentTransactionSingleNoLock(p, publisherId, transactionId); + result = v_publisherStartTransaction(p, publisherId, transactionId); - v_observerLock(v_observer(w)); - c_lockUnlock(&p->lock); + OSPL_LOCK(w); if (result == TRUE) { w->transactionStarted = TRUE; @@ -1553,9 +1563,6 @@ writerCreateEOT( return message; } -/************************************************************** - * constructor/destructor - **************************************************************/ v_writer v_writerNew( v_publisher p, @@ -1630,7 +1637,7 @@ v_writerInit( } else { writer->statistics = NULL; } - v_entityInit(v_entity(writer), name, FALSE); + v_entityInit(v_entity(writer), name); writer->count = 0; writer->eotCount = 0; @@ -1716,8 +1723,9 @@ v_writerInit( } v_result -v_writerEnable( - v_writer writer) +v__writerEnable( + v_writer writer, + os_boolean builtin) { v_kernel kernel; v_participant participant; @@ -1728,7 +1736,10 @@ v_writerEnable( result = v_publisherAddWriter (writer->publisher, writer); if (result == V_RESULT_OK) { - v_observerLock(v_observer(writer)); + v_message builtinMsg = NULL; + v_message builtinCMMsg = NULL; + + OSPL_LOCK(writer); qos = writer->qos; if (qos->history.v.kind == V_HISTORY_KEEPLAST) { @@ -1743,28 +1754,6 @@ v_writerEnable( writer->infWait = OS_DURATION_ISINFINITE(qos->reliability.v.max_blocking_time); assert(writer->publisher != NULL); - participant = v_participant(v_publisher(writer->publisher)->participant); - assert(participant != NULL); - - /* Register with the lease manager for periodic resending - * This has to be done for all kinds of reliability because - * dispose-messages always have to be sent reliably */ - /* The only condition is existence of writer->history */ - if (participant) { - /* Add writer as observer of participant in case liveliness is - * BY PARTICIPANT - * This simplifies the liveliness assertion of the participant. - */ - if (qos->liveliness.v.kind == V_LIVELINESS_PARTICIPANT) { - v_observableAddObserver(v_observable(writer), - v_observer(participant), - NULL); - v_observerUnlock(v_observer(writer)); - v_observerSetEvent(v_observer(participant), - V_EVENT_LIVELINESS_ASSERT); - v_observerLock(v_observer(writer)); - } - } kernel = v_objectKernel(writer); assert(kernel != NULL); @@ -1777,14 +1766,12 @@ v_writerEnable( if (!OS_DURATION_ISINFINITE(qos->liveliness.v.lease_duration)) { writer->livelinessLease = v_leaseElapsedNew(kernel, qos->liveliness.v.lease_duration); if(writer->livelinessLease) { - result = v_leaseManagerRegister( - kernel->livelinessLM, - writer->livelinessLease, - V_LEASEACTION_LIVELINESS_CHECK, - v_public(writer), - TRUE /* repeat lease if expired */); - if(result != V_RESULT_OK) - { + result = v_leaseManagerRegister(kernel->livelinessLM, + writer->livelinessLease, + V_LEASEACTION_LIVELINESS_CHECK, + v_public(writer), + TRUE /* repeat lease if expired */); + if (result != V_RESULT_OK) { c_free(writer->livelinessLease); writer->livelinessLease = NULL; OS_REPORT(OS_CRITICAL, "v_writer", result, @@ -1796,29 +1783,82 @@ v_writerEnable( } initMsgQos(writer); - if (kernel->builtin && kernel->builtin->kernelQos->builtin.v.enabled) { - v_message builtinMsg, builtinCMMsg; - builtinMsg = v_builtinCreatePublicationInfo(kernel->builtin, writer); + + c_free(writer->pubInfo); + writer->pubInfo = v_builtinCreatePublicationInfo(kernel->builtin, writer); + + if (builtin && kernel->builtin->kernelQos->builtin.v.enabled) { builtinCMMsg = v_builtinCreateCMDataWriterInfo(kernel->builtin, writer); - v_writeBuiltinTopic(kernel, V_PUBLICATIONINFO_ID, builtinMsg); - v_writeBuiltinTopic(kernel, V_CMDATAWRITERINFO_ID, builtinCMMsg); - c_free(builtinMsg); - c_free(builtinCMMsg); + builtinMsg = c_keep(writer->pubInfo); } - v_observerUnlock(v_observer(writer)); + if (qos->liveliness.v.kind == V_LIVELINESS_PARTICIPANT) { + participant = c_keep(v_publisher(writer->publisher)->participant); + assert(participant != NULL); + } else { + participant = NULL; + } + + /* Synchronous update of kernel builtin data for local entities. + * Avoid discovery latencies, e.g. in case of readers ignoring publications. + * Has overlap with the asynchronous spliced process publication data. + */ + v_kernelNotifyPublication(kernel, writer->pubInfo); if (qos->reliability.v.synchronous) { writer->deliveryGuard = v_deliveryGuardNew(kernel->deliveryService,writer); } else { writer->deliveryGuard = NULL; } + OSPL_UNLOCK(writer); + + if (participant) { + /* Add participant as observer of the writer in case liveliness is + * BY PARTICIPANT + * This simplifies the liveliness assertion of the participant. + */ + OSPL_ADD_OBSERVER(writer, participant, V_EVENT_LIVELINESS_ASSERT, NULL); + v_observerSetEvent(v_observer(participant), V_EVENT_LIVELINESS_ASSERT); + } + + if (builtinMsg) { + v_writeBuiltinTopic(kernel, V_PUBLICATIONINFO_ID, builtinMsg); + c_free(builtinMsg); + } + if (builtinCMMsg) { + v_writeBuiltinTopic(kernel, V_CMDATAWRITERINFO_ID, builtinCMMsg); + c_free(builtinCMMsg); + } } } return result; } +v_result +v_writerEnable( + v_writer writer) +{ + return v__writerEnable(writer, OS_TRUE); +} + +/* This operation will return the actual builtin publication data for this writer. + * The writer caches this last published publication data. + */ +v_message +v_writerPublication( + v_writer _this) +{ + v_message publication; + OSPL_LOCK(_this); + if (_this->pubInfo == NULL) { + _this->pubInfo = v_builtinCreatePublicationInfo(v_objectKernel(_this)->builtin, _this); + } + publication = c_keep(_this->pubInfo); + OSPL_UNLOCK(_this); + return publication; +} + static c_bool removeFromGroup ( v_writerGroup g, @@ -1841,7 +1881,6 @@ reconnectToGroup( c_tableWalk(w->instances, disconnectInstanceForReconnect, g); v_writerCacheDeinit(g->targetCache); - c_tableWalk(w->instances, connectInstance, g); return TRUE; } @@ -1892,7 +1931,7 @@ v_writerFree( */ v_participantResendManagerRemoveWriterBlocking(v_participant(p->participant), w); - v_observerLock(v_observer(w)); + OSPL_LOCK(w); singleTransaction = writerSingleTransaction(w, &publisherId, &transactionId, &tidList); /* NOTE: this function can re-lock the writer */ kernel = v_objectKernel(w); @@ -1929,7 +1968,7 @@ v_writerFree( w->publisher = NULL; - v_observerUnlock(v_observer(w)); + OSPL_UNLOCK(w); if (w->deliveryGuard) { v_deliveryGuardFree(w->deliveryGuard); @@ -1973,9 +2012,6 @@ v_writerDeinit( v_entityDeinit(v_entity(w)); } -/************************************************************** - * Protected functions - **************************************************************/ c_bool v_writerPublishGroup( v_writer writer, @@ -1988,12 +2024,14 @@ v_writerPublishGroup( assert(C_TYPECHECK(group, v_group)); if (group->topic == writer->topic) { - v_observerLock(v_observer(writer)); + OSPL_LOCK(writer); proxy = v_writerGroupSetAdd(writer,group); - c_tableWalk(writer->instances, connectInstance, proxy); - c_free(proxy); + if (proxy) { + c_tableWalk(writer->instances, connectInstance, proxy); + c_free(proxy); + } - v_observerUnlock(v_observer(writer)); + OSPL_UNLOCK(writer); } return TRUE; @@ -2009,24 +2047,23 @@ v_writerNotifyIncompatibleQos( v_writer w, v_policyId id) { - c_bool handled; C_STRUCT(v_event) e; assert(w != NULL); assert(C_TYPECHECK(w,v_writer)); - v_observerLock(v_observer(w)); + OSPL_LOCK(w); v_statusNotifyOfferedIncompatibleQos(v_entity(w)->status, id); e.kind = V_EVENT_OFFERED_INCOMPATIBLE_QOS; e.source = v_observable(w); e.data = NULL; - handled = v_entityNotifyListener(v_entity(w), &e); - v_observerUnlock(v_observer(w)); - if (!handled) { - v_observableNotify(v_observable(w), &e); + e.handled = v_entityNotifyListener(v_entity(w), &e); + if (!e.handled) { + OSPL_THROW_EVENT(w, &e); } + OSPL_UNLOCK(w); } @@ -2036,23 +2073,22 @@ v_writerNotifyPublicationMatched ( v_gid readerGID, c_bool dispose) { - c_bool handled; C_STRUCT(v_event) e; assert(w != NULL); assert(C_TYPECHECK(w,v_writer)); - v_observerLock(v_observer(w)); + OSPL_LOCK(w); v_statusNotifyPublicationMatched(v_entity(w)->status, readerGID, dispose); e.kind = V_EVENT_PUBLICATION_MATCHED; e.source = v_observable(w); e.data = NULL; - handled = v_entityNotifyListener(v_entity(w), &e); - v_observerUnlock(v_observer(w)); - if (!handled) { - v_observableNotify(v_observable(w), &e); + e.handled = v_entityNotifyListener(v_entity(w), &e); + if (!e.handled) { + OSPL_THROW_EVENT(w, &e); } + OSPL_UNLOCK(w); } void @@ -2061,33 +2097,35 @@ v_writerNotifyChangedQos( v_writerNotifyChangedQosArg *arg) { v_kernel kernel; + v_message builtinMsg = NULL; + v_message builtinCMMsg = NULL; assert(w != NULL); assert(C_TYPECHECK(w,v_writer)); - v_observerLock(v_observer(w)); - if ((arg != NULL) && - ((arg->addedPartitions != NULL) || (arg->removedPartitions != NULL))) { + OSPL_LOCK(w); + if ((arg != NULL) && ((arg->addedPartitions != NULL) || (arg->removedPartitions != NULL))) + { /* partition policy has changed */ -/** - * Now the builtin topic is published, after all connections are updated. - * Depending on the outcome of the RTPS protocol standardisation, this - * solution is subject to change. - */ c_iterWalk(arg->addedPartitions, publish, w); c_iterWalk(arg->removedPartitions, unpublish, w); } kernel = v_objectKernel(w); - if (kernel->builtin && kernel->builtin->kernelQos->builtin.v.enabled && v_entity(w)->enabled) { - v_message builtinMsg, builtinCMMsg; - builtinMsg = v_builtinCreatePublicationInfo(kernel->builtin,w); + if (kernel->builtin && kernel->builtin->kernelQos->builtin.v.enabled && v__entityEnabled_nl(v_entity(w))) { + c_free(w->pubInfo); + w->pubInfo = v_builtinCreatePublicationInfo(kernel->builtin,w); + builtinMsg = c_keep(w->pubInfo); builtinCMMsg = v_builtinCreateCMDataWriterInfo(kernel->builtin,w); + } + OSPL_UNLOCK(w); + if (builtinMsg) { v_writeBuiltinTopic(kernel, V_PUBLICATIONINFO_ID, builtinMsg); - v_writeBuiltinTopic(kernel, V_CMDATAWRITERINFO_ID, builtinCMMsg); c_free(builtinMsg); + } + if (builtinCMMsg) { + v_writeBuiltinTopic(kernel, V_CMDATAWRITERINFO_ID, builtinCMMsg); c_free(builtinCMMsg); } - v_observerUnlock(v_observer(w)); } v_writerQos @@ -2099,9 +2137,9 @@ v_writerGetQos ( assert(_this); assert(C_TYPECHECK(_this,v_writer)); - v_observerLock(v_observer(_this)); + OSPL_LOCK(_this); qos = c_keep(_this->qos); - v_observerUnlock(v_observer(_this)); + OSPL_UNLOCK(_this); return qos; } @@ -2122,14 +2160,14 @@ v_writerSetQos( result = v_writerQosCheck(tmpl); if (result == V_RESULT_OK) { - v_observerLock(v_observer(w)); + OSPL_LOCK(w); kernel = v_objectKernel(w); qos = v_writerQosNew(kernel, tmpl); if (!qos) { - v_observerUnlock(v_observer(w)); + OSPL_UNLOCK(w); return V_RESULT_OUT_OF_MEMORY; } - result = v_writerQosCompare(w->qos, qos, v_entityEnabled(v_entity(w)), &cm); + result = v_writerQosCompare(w->qos, qos, v__entityEnabled_nl(v_entity(w)), &cm); if ((result == V_RESULT_OK) && (cm != 0)) { c_free(w->qos); w->qos = c_keep(qos); @@ -2140,12 +2178,14 @@ v_writerSetQos( if (cm & (V_POLICY_BIT_DEADLINE | V_POLICY_BIT_LATENCY)) { v_writerGroupSetWalk(&w->groupSet, reconnectToGroup, (c_voidp)w); } - if (kernel->builtin && kernel->builtin->kernelQos->builtin.v.enabled && v_entity(w)->enabled) { - builtinMsg = v_builtinCreatePublicationInfo(kernel->builtin, w); + if (kernel->builtin && kernel->builtin->kernelQos->builtin.v.enabled && v__entityEnabled_nl(v_entity(w))) { + c_free(w->pubInfo); + w->pubInfo = v_builtinCreatePublicationInfo(kernel->builtin, w); + builtinMsg = c_keep(w->pubInfo); builtinCMMsg = v_builtinCreateCMDataWriterInfo(kernel->builtin,w); } } - v_observerUnlock(v_observer(w)); + OSPL_UNLOCK(w); c_free(qos); } @@ -2165,14 +2205,13 @@ void v_writerNotifyLivelinessLost( v_writer w) { - c_bool handled; C_STRUCT(v_event) e; v_kernel kernel; v_message builtinMsg = NULL; assert(C_TYPECHECK(w,v_writer)); - v_observerLock(v_observer(w)); + OSPL_LOCK(w); kernel = v_objectKernel(w); w->alive = FALSE; /* suspend liveliness check */ @@ -2183,14 +2222,16 @@ v_writerNotifyLivelinessLost( e.kind = V_EVENT_LIVELINESS_LOST; e.source = v_observable(w); e.data = NULL; - handled = v_entityNotifyListener(v_entity(w), &e); + e.handled = v_entityNotifyListener(v_entity(w), &e); if (kernel->builtin && kernel->builtin->kernelQos->builtin.v.enabled) { - builtinMsg = v_builtinCreatePublicationInfo(kernel->builtin,w); + c_free(w->pubInfo); + w->pubInfo = v_builtinCreatePublicationInfo(kernel->builtin,w);; + builtinMsg = c_keep(w->pubInfo); } - v_observerUnlock(v_observer(w)); - if (!handled) { - v_observableNotify(v_observable(w), &e); + if (!e.handled) { + OSPL_THROW_EVENT(w, &e); } + OSPL_UNLOCK(w); if (builtinMsg != NULL) { v_writeBuiltinTopic(kernel, V_PUBLICATIONINFO_ID, builtinMsg); @@ -2198,24 +2239,6 @@ v_writerNotifyLivelinessLost( } } -v_typeRepresentation -v__writerGetTypeRepresentation ( - v_writer _this) -{ - c_char *typeName; - v_typeRepresentation found; - - typeName = c_metaScopedName(c_metaObject(v_topicDataType(v_writerTopic(_this)))); - found = v_participantLookupTypeRepresentation(v_writerParticipant(_this), typeName); - os_free(typeName); - - return found; -} - -/************************************************************** - * Public functions - **************************************************************/ - v_writeResult v_writerRegister( v_writer w, @@ -2233,10 +2256,10 @@ v_writerRegister( *inst = NULL; - v_observerLock(v_observer(w)); + OSPL_LOCK(w); if (!w->publisher) { - v_observerUnlock(v_observer(w)); + OSPL_UNLOCK(w); OS_REPORT(OS_ERROR, "v_writerRegister", V_WRITE_ERROR,"Writer is in process of deletion, link to publisher already deleted."); return V_WRITE_ERROR; } @@ -2283,7 +2306,7 @@ v_writerRegister( (inst != NULL)) { *inst = c_keep(found); } - v_observerUnlock(v_observer(w)); + OSPL_UNLOCK(w); return result; } @@ -2298,7 +2321,7 @@ v_writerLookupInstance( assert(C_TYPECHECK(w,v_writer)); assert(C_TYPECHECK(keyTemplate,v_message)); - v_observerLock(v_observer(w)); + OSPL_LOCK(w); instance = v_writerNewInstance(w, keyTemplate); if (instance) { @@ -2309,7 +2332,7 @@ v_writerLookupInstance( "Out of resources: not enough memory available"); } - v_observerUnlock(v_observer(w)); + OSPL_UNLOCK(w); return found; } @@ -2327,9 +2350,9 @@ v_writerUnregister( assert(C_TYPECHECK(message,v_message)); assert(message != NULL); - v_observerLock(v_observer(w)); + OSPL_LOCK(w); if (!w->publisher) { - v_observerUnlock(v_observer(w)); + OSPL_UNLOCK(w); OS_REPORT(OS_ERROR, "v_writerUnregister", V_WRITE_ERROR, "Writer is in process of deletion, link to publisher already deleted."); return V_WRITE_ERROR; @@ -2344,7 +2367,7 @@ v_writerUnregister( message->transactionId = w->transactionId; result = writerUnregister(w, message, timestamp, instance); - v_observerUnlock(v_observer(w)); + OSPL_UNLOCK(w); /* Rewrite internal return code which is for use only in the kernel */ if ( result == V_WRITE_REJECTED ) { @@ -2366,19 +2389,19 @@ v_writerWrite( os_timeE until = OS_TIMEE_ZERO; c_ulong blocked; /* Used for statistics */ enum v_livelinessKind livKind; - C_STRUCT(v_event) event; v_deliveryWaitList waitlist; os_duration max_blocking_time = OS_DURATION_ZERO; const os_timeE nowEl = message->allocTime; + v_message builtinMsg = NULL; assert(C_TYPECHECK(w,v_writer)); assert(C_TYPECHECK(message,v_message)); V_MESSAGE_STAMP(message,writerCopyTime); - v_observerLock(v_observer(w)); + OSPL_LOCK(w); if (!w->publisher) { - v_observerUnlock(v_observer(w)); + OSPL_UNLOCK(w); OS_REPORT(OS_ERROR, "v_writerWrite", V_WRITE_ERROR,"Writer is in process of deletion, link to publisher already deleted."); return V_WRITE_ERROR; } @@ -2423,12 +2446,13 @@ v_writerWrite( if (result != V_WRITE_SUCCESS) { if(result == V_WRITE_TIMEOUT || result == V_WRITE_OUT_OF_RESOURCES) { /* Both results are a case of (immediate) timeout, so are counted - * in this statistic. */ + * in this statistic. + */ if (w->statistics) { w->statistics->numberOfTimedOutWrites++; } } - v_observerUnlock(v_observer(w)); + OSPL_UNLOCK(w); return result; } } @@ -2467,7 +2491,8 @@ v_writerWrite( } /* The writer statistics are updated for the newly inserted * instance (with its initial values). The previous state - * was nothing, so 0 is passed as the oldState. */ + * was nothing, so 0 is passed as the oldState. + */ UPDATE_WRITER_STATISTICS(w, instance, 0); } else { found = c_remove(w->instances,instance,NULL,NULL); @@ -2528,13 +2553,6 @@ v_writerWrite( c_baseMakeMemReservation(c_getBase(w), C_MM_RESERVATION_HIGH)) { result = writerWrite(w, instance, message); c_baseReleaseMemReservation(c_getBase(w), C_MM_RESERVATION_HIGH); -#if 0 - if (result == V_WRITE_SUCCESS) { - /* Successful delivered to all so no need to wait. */ - v_deliveryWaitListFree(waitlist); - waitlist = NULL; - } -#endif v_writerInstanceResetState(instance, L_DISPOSED); v_writerInstanceResetState(instance, L_UNREGISTER); deadlineUpdate(w, instance, nowEl); @@ -2551,15 +2569,24 @@ v_writerWrite( } livKind = qos->liveliness.v.kind; - assertLiveliness(w); + builtinMsg = assertLiveliness(w); + + OSPL_UNLOCK(w); - v_observerUnlock(v_observer(w)); + if (builtinMsg) { + v_writeBuiltinTopic(v_objectKernel(w), V_PUBLICATIONINFO_ID, builtinMsg); + c_free(builtinMsg); + } if (livKind == V_LIVELINESS_PARTICIPANT) { + C_STRUCT(v_event) event; + event.kind = V_EVENT_LIVELINESS_ASSERT; event.source = v_observable(w); event.data = NULL; - v_observableNotify(v_observable(w), &event); + event.handled = TRUE; + + OSPL_THROW_EVENT(w, &event); } if (waitlist) { @@ -2600,10 +2627,10 @@ v_writerDispose( assert(C_TYPECHECK(message,v_message)); waitlist = NULL; - v_observerLock(v_observer(_this)); + OSPL_LOCK(_this); if (!_this->publisher) { - v_observerUnlock(v_observer(_this)); + OSPL_UNLOCK(_this); OS_REPORT(OS_ERROR, "v_writerDispose", V_WRITE_ERROR,"Writer is in process of deletion, link to publisher already deleted."); return V_WRITE_ERROR; } @@ -2626,7 +2653,7 @@ v_writerDispose( } } - v_observerUnlock(v_observer(_this)); + OSPL_UNLOCK(_this); if (waitlist) { /* This implies the writer is synchronous. */ @@ -2658,20 +2685,20 @@ v_writerWriteDispose( v_writerQos qos; os_timeE until = OS_TIMEE_ZERO; enum v_livelinessKind livKind; - C_STRUCT(v_event) event; v_deliveryWaitList waitlist; os_duration max_blocking_time = OS_DURATION_ZERO; const os_timeE nowEl = message->allocTime; + v_message builtinMsg = NULL; assert(C_TYPECHECK(w,v_writer)); assert(C_TYPECHECK(message,v_message)); assert(message != NULL); assert(C_TIME_GET_KIND(nowEl) == C_TIME_ELAPSED); - v_observerLock(v_observer(w)); + OSPL_LOCK(w); if (!w->publisher) { - v_observerUnlock(v_observer(w)); + OSPL_UNLOCK(w); OS_REPORT(OS_ERROR, "v_writerWriteDispose", V_WRITE_ERROR,"Writer is in process of deletion, link to publisher already deleted."); return V_WRITE_ERROR; } @@ -2708,7 +2735,7 @@ v_writerWriteDispose( (w->count >= (c_ulong)qos->resource.v.max_samples)) { result = doWait(w,until); if (result != V_WRITE_SUCCESS) { - v_observerUnlock(v_observer(w)); + OSPL_UNLOCK(w); return result; } } @@ -2735,7 +2762,8 @@ v_writerWriteDispose( } /* The writer statistics are updated for the newly inserted * instance (with its initial values). The previous state - * was nothing, so 0 is passed as the oldState. */ + * was nothing, so 0 is passed as the oldState. + */ UPDATE_WRITER_STATISTICS(w, instance, 0); } else { found = c_remove(w->instances,instance,NULL,NULL); @@ -2809,15 +2837,23 @@ v_writerWriteDispose( } livKind = qos->liveliness.v.kind; - assertLiveliness(w); + builtinMsg = assertLiveliness(w); - v_observerUnlock(v_observer(w)); + OSPL_UNLOCK(w); + + if (builtinMsg) { + v_writeBuiltinTopic(v_objectKernel(w), V_PUBLICATIONINFO_ID, builtinMsg); + c_free(builtinMsg); + } if (livKind == V_LIVELINESS_PARTICIPANT) { + C_STRUCT(v_event) event; event.kind = V_EVENT_LIVELINESS_ASSERT; event.source = v_observable(w); event.data = NULL; - v_observableNotify(v_observable(w), &event); + event.handled = TRUE; + + OSPL_THROW_EVENT(w, &event); } if (waitlist) { @@ -2843,16 +2879,16 @@ v_writerPublish( v_writer w, v_partition d) { + v_group g; + v_kernel kernel; + assert(C_TYPECHECK(w,v_writer)); assert(d != NULL); assert(C_TYPECHECK(d,v_partition)); - v_observerLock(v_observer(w)); - - publish(d, w); - - v_observerUnlock(v_observer(w)); - + kernel = v_objectKernel(w); + g = v_groupSetCreate(kernel->groupSet,d,w->topic); + v_writerPublishGroup(w,g); return TRUE; } @@ -2865,11 +2901,11 @@ v_writerUnPublish( assert(d != NULL); assert(C_TYPECHECK(d,v_partition)); - v_observerLock(v_observer(w)); + OSPL_LOCK(w); unpublish(d, w); - v_observerUnlock(v_observer(w)); + OSPL_UNLOCK(w); return TRUE; } @@ -2886,10 +2922,9 @@ waitForAcknowledgments( assert(C_TYPECHECK(w,v_writer)); - if (OS_DURATION_ISINFINITE(timeout)) { while (v__writerHasResendsPending(w)) { - flags = v__observerWait(v_observer(w)); + flags = OSPL_CATCH_EVENT(w, OS_DURATION_INFINITE); if(v__writerHasResendsPending(w) && (flags & V_EVENT_OBJECT_DESTROYED)){ result = V_RESULT_ILL_PARAM; break; @@ -2903,7 +2938,7 @@ waitForAcknowledgments( result = V_RESULT_TIMEOUT; while (v__writerHasResendsPending(w) && (os_timeMCompare(curTime, endTime) == OS_LESS)) { - flags = v__observerTimedWait(v_observer(w), waitTime); + flags = OSPL_CATCH_EVENT(w, waitTime); if(v__writerHasResendsPending(w)) { if(flags & V_EVENT_OBJECT_DESTROYED){ @@ -2936,11 +2971,11 @@ v_writerWaitForAcknowledgments( assert(C_TYPECHECK(w,v_writer)); if(w){ - v_observerLock(v_observer(w)); + OSPL_LOCK(w); result = waitForAcknowledgments(w, timeout); - v_observerUnlock(v_observer(w)); + OSPL_UNLOCK(w); } else { result = V_RESULT_ILL_PARAM; } @@ -2993,6 +3028,11 @@ writerResend( if (grouparg.result == V_WRITE_REJECTED) { assert(grouparg.rejectScope != V_RESEND_NONE); v_writerSampleSetResendScope(sample, grouparg.rejectScope); + if (v_messageStateTest(message,L_UNREGISTER)) { + v_writerInstanceSetState(instance, L_UNREGISTER); + v_writerInstanceResetState(instance, L_REGISTER); + v_writerCacheDeinit(instance->targetCache); + } } else { if (v_messageStateTest(message,L_UNREGISTER)) { v_writerInstanceSetState(instance, L_UNREGISTER); @@ -3099,7 +3139,8 @@ v__writerResendInOrder( } else { /* When all samples that were in the history from before the publisher * was suspended are (re)sent, it doesn't make sense to retry until - * the publisher is resumed. */ + * the publisher is resumed. + */ v_participantResendManagerRemoveWriter(v_writerParticipant(writer), writer); break; } @@ -3155,7 +3196,8 @@ v__writerResendInstance( if (v_writerInstanceTestState(instance, L_EMPTY)) { /* If the instance has become empty it is inserted into an emptyList - * that is returned to the callee. */ + * that is returned to the callee. + */ *emptyList = c_iterInsert(*emptyList, c_keep(instance)); } @@ -3195,8 +3237,6 @@ v__writerResendByInstance( found = c_remove(writer->instances, instance, NULL, NULL); assert(found == instance); UPDATE_WRITER_STATISTICS_REMOVE_INSTANCE(writer, instance); - v_writerCacheDeinit(instance->targetCache); - v_writerInstanceResetState(instance, L_REGISTER); v_writerFreeInstance(found); } v_writerFreeInstance(instance); @@ -3218,7 +3258,7 @@ v_writerResend( assert(writer != NULL); assert(C_TYPECHECK(writer,v_writer)); - v_observerLock(v_observer(writer)); + OSPL_LOCK(writer); initialCount = writer->count + writer->eotCount; @@ -3232,18 +3272,20 @@ v_writerResend( /* If this writer has no more resends pending, it can be removed from * the resend-manager. Perhaps this shouldn't be done immediately, since * it is quite cheap for a writer to be registered with the resend- - * manager when there is nothing to resend. */ + * manager when there is nothing to resend. + */ v_participantResendManagerRemoveWriter(v_writerParticipant(writer), writer); } if(initialCount > (writer->count + writer->eotCount)) { /* Some space was cleared in the history of one of this writer's instances. * Space is only cleared if data counting for the resource-limits has been - * resent. EOT's and instance-state changes don't count. */ - v_observerNotify(v_observer(writer), NULL, NULL); + * resent. EOT's and instance-state changes don't count. + */ + OSPL_TRIGGER_EVENT(writer, NULL, NULL); } - v_observerUnlock(v_observer(writer)); + OSPL_UNLOCK(writer); return result != V_WRITE_OUT_OF_RESOURCES; } @@ -3254,19 +3296,28 @@ v_writerAssertLiveliness( { enum v_livelinessKind livKind; C_STRUCT(v_event) event; + v_message builtinMsg = NULL; assert(w != NULL); assert(C_TYPECHECK(w,v_writer)); - v_observerLock(v_observer(w)); + OSPL_LOCK(w); livKind = w->qos->liveliness.v.kind; - assertLiveliness(w); - v_observerUnlock(v_observer(w)); + builtinMsg = assertLiveliness(w); + OSPL_UNLOCK(w); + + if (builtinMsg) { + v_writeBuiltinTopic(v_objectKernel(w), V_PUBLICATIONINFO_ID, builtinMsg); + c_free(builtinMsg); + } + if (livKind == V_LIVELINESS_PARTICIPANT) { event.kind = V_EVENT_LIVELINESS_ASSERT; event.source = v_observable(w); event.data = NULL; - v_observableNotify(v_observable(w), &event); + event.handled = TRUE; + + OSPL_THROW_EVENT(w, &event); } } @@ -3285,14 +3336,14 @@ v_writerGetLivelinessLostStatus( result = V_RESULT_PRECONDITION_NOT_MET; if (_this != NULL) { - v_observerLock(v_observer(_this)); + OSPL_LOCK(_this); status = v_entityStatus(v_entity(_this)); result = action(&v_writerStatus(status)->livelinessLost, arg); if (reset) { v_statusReset(status, V_EVENT_LIVELINESS_LOST); } v_writerStatus(status)->livelinessLost.totalChanged = 0; - v_observerUnlock(v_observer(_this)); + OSPL_UNLOCK(_this); c_free(status); } return result; @@ -3313,14 +3364,14 @@ v_writerGetDeadlineMissedStatus( result = V_RESULT_PRECONDITION_NOT_MET; if (_this != NULL) { - v_observerLock(v_observer(_this)); + OSPL_LOCK(_this); status = v_entity(_this)->status; result = action(&v_writerStatus(status)->deadlineMissed, arg); if (reset) { v_statusReset(status, V_EVENT_OFFERED_DEADLINE_MISSED); } v_writerStatus(status)->deadlineMissed.totalChanged = 0; - v_observerUnlock(v_observer(_this)); + OSPL_UNLOCK(_this); } return result; } @@ -3341,7 +3392,7 @@ v_writerGetIncompatibleQosStatus( result = V_RESULT_PRECONDITION_NOT_MET; if (_this != NULL) { - v_observerLock(v_observer(_this)); + OSPL_LOCK(_this); status = v_entity(_this)->status; result = action(&v_writerStatus(status)->incompatibleQos, arg); if (reset) { @@ -3351,7 +3402,7 @@ v_writerGetIncompatibleQosStatus( for (i=0; iincompatibleQos.policyCount[i] = 0; } - v_observerUnlock(v_observer(_this)); + OSPL_UNLOCK(_this); } return result; } @@ -3371,7 +3422,7 @@ v_writerGetPublicationMatchedStatus( result = V_RESULT_PRECONDITION_NOT_MET; if (_this != NULL) { - v_observerLock(v_observer(_this)); + OSPL_LOCK(_this); status = v_entity(_this)->status; result = action(&v_writerStatus(status)->publicationMatch, arg); if (reset) { @@ -3379,7 +3430,7 @@ v_writerGetPublicationMatchedStatus( } v_writerStatus(status)->publicationMatch.totalChanged = 0; v_writerStatus(status)->publicationMatch.currentChanged = 0; - v_observerUnlock(v_observer(_this)); + OSPL_UNLOCK(_this); } return result; } @@ -3390,7 +3441,6 @@ v_writerCheckDeadlineMissed( os_timeE now) { v_result result = V_RESULT_OK; - c_bool handled; C_STRUCT(v_event) e; c_iter missed; v_writerInstance instance; @@ -3399,14 +3449,14 @@ v_writerCheckDeadlineMissed( os_timeW unregisterTime; c_bool notify = FALSE; - v_observerLock(v_observer(w)); + OSPL_LOCK(w); e.kind = V_EVENT_OFFERED_DEADLINE_MISSED; e.source = v_observable(w); e.data = NULL; + e.handled = TRUE; - /* - * We are dealing with a potential automatic unregister under the + /* We are dealing with a potential automatic unregister under the * following conditions: * 1. the deadlineCountLimit equals 1 * 2. the deadlineList is not empty AND the first instance in the deadline @@ -3443,8 +3493,8 @@ v_writerCheckDeadlineMissed( } else { v_statusNotifyOfferedDeadlineMissed(v_entity(w)->status,v_publicHandle(v_public(instance))); - handled = v_entityNotifyListener(v_entity(w), &e); - notify = !handled; + e.handled = v_entityNotifyListener(v_entity(w), &e); + notify = !e.handled; } instance = v_writerInstance(c_iterTakeFirst(missed)); } @@ -3469,11 +3519,9 @@ v_writerCheckDeadlineMissed( v_deadLineInstanceListSetDuration(w->deadlineList, period); } if(notify) { - v_observerUnlock(v_observer(w)); - v_observableNotify(v_observable(w), &e); - } else { - v_observerUnlock(v_observer(w)); + OSPL_THROW_EVENT(w, &e); } + OSPL_UNLOCK(w); return result; } @@ -3507,11 +3555,11 @@ v_writerRead ( assert(C_TYPECHECK(writer,v_writer)); assert(action != NULL); - v_observerLock(v_observer(writer)); + OSPL_LOCK(writer); a.action = (v_writerInstanceWalkAction)action; a.arg = arg; c_tableWalk(writer->instances, instanceRead, &a); - v_observerUnlock(v_observer(writer)); + OSPL_UNLOCK(writer); return result; } @@ -3526,7 +3574,7 @@ v_writerResumePublication( assert(resumeTime); assert(C_TIME_GET_KIND(*resumeTime) == C_TIME_REALTIME); - v_observerLock(v_observer(writer)); + OSPL_LOCK(writer); /* Auto-purge last remaining samples, since publisher was suspended but * now resumed. @@ -3543,11 +3591,12 @@ v_writerResumePublication( /* There is stuff to be resent, so add writer to resend-manager again. * It is possible that the writer was still registered with the resend- * manager (when there are still unsuspended samples in the history), - * but that shouldn't matter. */ + * but that shouldn't matter. + */ v_participantResendManagerAddWriter(v_publisherParticipant(writer->publisher), writer); } - v_observerUnlock(v_observer(writer)); + OSPL_UNLOCK(writer); } void @@ -3559,11 +3608,11 @@ v_writerCoherentBegin ( assert(C_TYPECHECK(_this,v_writer)); assert(transactionId != NULL); - v_observerLock(v_observer(_this)); + OSPL_LOCK(_this); _this->transactionId = _this->sequenceNumber; _this->transactionStarted = TRUE; *transactionId = _this->transactionId; - v_observerUnlock(v_observer(_this)); + OSPL_UNLOCK(_this); } v_result @@ -3580,7 +3629,7 @@ v_writerCoherentEnd ( assert(_this != NULL); assert(C_TYPECHECK(_this,v_writer)); - v_observerLock(v_observer(_this)); + OSPL_LOCK(_this); /* This function instantiates a new (dummy) message from scratch, one * that indicates that it no longer belongs to the coherent set, thus @@ -3590,7 +3639,8 @@ v_writerCoherentEnd ( /* The end-of-transaction marker is recognized by the fact that * it still has its L_TRANSACTION bit set, but that it also has - * the L_ENDOFTRANSACTION bit set. */ + * the L_ENDOFTRANSACTION bit set. + */ v_stateSet(v_nodeState(message), L_TRANSACTION | L_ENDOFTRANSACTION); message->allocTime = os_timeEGet(); message->writeTime = os_timeWGet(); @@ -3609,7 +3659,8 @@ v_writerCoherentEnd ( * group-coherent update. In that case, we need to flush all * writer-histories so that a newer transaction cannot be * delivered before this one. It is possible to do this more - * fine-grained, but functionally this is correct. */ + * fine-grained, but functionally this is correct. + */ result = waitForAcknowledgments(_this, OS_DURATION_INFINITE); } else { result = V_RESULT_OK; @@ -3622,7 +3673,7 @@ v_writerCoherentEnd ( c_free (message); _this->transactionStarted = FALSE; - v_observerUnlock(v_observer(_this)); + OSPL_UNLOCK(_this); return result; } @@ -3663,9 +3714,210 @@ c_ulong v_writerAllocSequenceNumber ( v_writer _this) { - c_ulong seqNr; - v_observerLock(v_observer(_this)); - seqNr = _this->sequenceNumber++; - v_observerUnlock(v_observer(_this)); - return seqNr; + c_ulong seqNr; + OSPL_LOCK(_this); + seqNr = _this->sequenceNumber++; + OSPL_UNLOCK(_this); + return seqNr; +} + +char * +v__writerGetNameSpaceNames( + v_writer writer, + c_iter partitions, + c_iter nameSpaces) +{ + struct v_nameSpace *ns; + char *p; + c_iterIter iter; + char *names = NULL; + os_size_t len = 0; + + assert(writer != NULL); + assert(C_TYPECHECK(writer, v_writer)); + + iter = c_iterIterGet(nameSpaces); + while ((ns = c_iterNext(&iter)) != NULL) { + c_iterIter iter2 = c_iterIterGet(partitions); + c_bool inNs = FALSE; + while ((p = c_iterNext(&iter2)) != NULL) { + if ((v__nameSpaceIsIn(ns, p, v_topicName(writer->topic)) == TRUE) && + (inNs == FALSE)) { + inNs = TRUE; + + names = os_realloc(names, len + strlen(ns->name) + 1); + if (len) { + strcat(names, ","); + } else { + names[0] = '\0'; + } + strcat(names, ns->name); + len = strlen(names) + 1; + } + } + } + return names; +} + +c_bool +v__writerInSingleNameSpace( + v_writer writer, + c_iter partitions, + c_iter nameSpaces) +{ + struct v_nameSpace *ns; + char *p; + c_iterIter iter; + c_ulong matches = 0; + char *names = NULL; + os_size_t len = 0; + + assert(writer != NULL); + assert(C_TYPECHECK(writer, v_writer)); + + iter = c_iterIterGet(nameSpaces); + while ((ns = c_iterNext(&iter)) != NULL) { + c_iterIter iter2 = c_iterIterGet(partitions); + c_bool inNs = FALSE; + while ((p = c_iterNext(&iter2)) != NULL) { + if ((v__nameSpaceIsIn(ns, p, v_topicName(writer->topic)) == TRUE) && + (inNs == FALSE)) { + inNs = TRUE; + matches++; + + names = os_realloc(names, len + strlen(ns->name) + 1); + if (len) { + strcat(names, ","); + } else { + names[0] = '\0'; + } + strcat(names, ns->name); + len = strlen(names) + 1; + } + } + } + + if (matches == 0) { + OS_REPORT (OS_ERROR, OS_FUNCTION, V_RESULT_UNDEFINED, + "%s is in zero configured nameSpaces", v_entityName(writer)); + } else if (matches > 1) { + OS_REPORT (OS_ERROR, OS_FUNCTION, V_RESULT_UNDEFINED, + "%s is in multiple(%d) configured nameSpaces: \'%s\'", v_entityName(writer), matches, names); + } + os_free(names); + + return matches == 1 ? TRUE : FALSE; +} + +v_publisher +v_writerGetPublisher( + v_writer _this) +{ + v_publisher p; + OSPL_LOCK(_this); + p = c_keep(_this->publisher); + OSPL_UNLOCK(_this); + return p; +} + +struct matchingSubscriptionArg { + struct v_publicationInfo *pubInfo; + v_subscriptionInfo_action action; + void *arg; +}; + +static os_boolean +actionOnMatch( + v_message subscription, + void *arg) +{ + struct matchingSubscriptionArg *a = (struct matchingSubscriptionArg *)arg; + struct v_subscriptionInfo *subInfo = (struct v_subscriptionInfo *)(subscription + 1); + + if ((strcmp(subInfo->topic_name, a->pubInfo->topic_name) == 0) && + v_builtinTestPartitionMatch(a->pubInfo, subInfo) && + v_builtinTestQosMatch(a->pubInfo, subInfo) ) + { + a->action(subInfo, a->arg); + } + return OS_TRUE; +} + +/* This operation will visit the kernel discovered subscriptions and invoke + * the given action routine on each available matching subscription message. + */ +v_result +v_writerReadMatchedSubscriptions( + v_writer _this, + v_subscriptionInfo_action action, + c_voidp arg) +{ + v_message msg; + v_result result; + struct matchingSubscriptionArg ctx; + + msg = v_writerPublication(_this); + assert(msg); + ctx.pubInfo = (struct v_publicationInfo *)(msg + 1); + ctx.action = action; + ctx.arg = arg; + result = v_kernelWalkSubscriptions(v_objectKernel(_this), actionOnMatch, &ctx); + c_free(msg); + return result; +} + +struct readMatchedDataArg { + struct v_publicationInfo *pubInfo; + v_subscriptionInfo_action action; + void *arg; + v_gid subscription; +}; + +static os_boolean +readMatchedData( + v_message subscription, + void *arg) +{ + os_boolean proceed = OS_TRUE; + struct readMatchedDataArg *a = (struct readMatchedDataArg *)arg; + struct v_subscriptionInfo *subInfo = (struct v_subscriptionInfo *)(subscription + 1); + + if (subInfo->key.systemId == a->subscription.systemId && + subInfo->key.localId == a->subscription.localId) + { + if ((strcmp(subInfo->topic_name, a->pubInfo->topic_name) == 0) && + v_builtinTestPartitionMatch(a->pubInfo, subInfo) && + v_builtinTestQosMatch(a->pubInfo, subInfo) ) + { + a->action(subInfo, a->arg); + } + proceed = OS_FALSE; + } + return proceed; +} + +/* This operation will visit the kernel discovered subscriptions and lookup + * the subscription builtin info data identified by the given subscription gid and + * if found invoke the given action routine on the matching subscription message. + */ +v_result +v_writerReadMatchedSubscriptionData( + v_writer _this, + v_gid subscription, + v_subscriptionInfo_action action, + c_voidp arg) +{ + v_message msg; + v_result result; + struct readMatchedDataArg ctx; + + msg = v_writerPublication(_this); + assert(msg); + ctx.pubInfo = (struct v_publicationInfo *)(msg + 1); + ctx.action = action; + ctx.arg = arg; + ctx.subscription = subscription; + result = v_kernelWalkSubscriptions(v_objectKernel(_this), readMatchedData, &ctx); + c_free(msg); + return result; } diff --git a/src/kernel/code/v_writerCache.c b/src/kernel/code/v_writerCache.c index e63d7bf4e..ad1421ec4 100644 --- a/src/kernel/code/v_writerCache.c +++ b/src/kernel/code/v_writerCache.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/code/v_writerCache.h b/src/kernel/code/v_writerCache.h index 9319348cd..2c582d07c 100644 --- a/src/kernel/code/v_writerCache.h +++ b/src/kernel/code/v_writerCache.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/code/v_writerInstance.c b/src/kernel/code/v_writerInstance.c index c34250324..0c8a51fe3 100644 --- a/src/kernel/code/v_writerInstance.c +++ b/src/kernel/code/v_writerInstance.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -247,6 +248,9 @@ v_writerInstanceInsert( } /* remove last WRITE sample. */ if (last != NULL) { + if (cursor == last) { + cursor = last->next; + } if (last->next != NULL) { last->next->prev = v_writerSample(last->prev); } else { @@ -259,7 +263,8 @@ v_writerInstanceInsert( v_writerSample(last->prev)->next = last->next; } else { /* Avoiding writerInstanceSetHead because - * last->next's reference is transferred */ + * last->next's reference is transferred + */ v_writerInstanceTemplate(instance)->sample = last->next; } last->next = NULL; diff --git a/src/kernel/code/v_writerQos.c b/src/kernel/code/v_writerQos.c index 0cf655792..dd998b064 100644 --- a/src/kernel/code/v_writerQos.c +++ b/src/kernel/code/v_writerQos.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -34,9 +35,6 @@ static const v_qosChangeMask immutableMask = V_POLICY_BIT_HISTORY | V_POLICY_BIT_RESOURCE; -/************************************************************** - * private functions - **************************************************************/ static c_bool v_writerQosValidValues( v_writerQos qos) @@ -89,9 +87,7 @@ v_writerQosConsistent( return result; } -/************************************************************** - * constructor/destructor - **************************************************************/ + v_writerQos v_writerQosNew( v_kernel kernel, @@ -153,9 +149,6 @@ v_writerQosFree( c_free(q); } -/************************************************************** - * Protected functions - **************************************************************/ v_result v_writerQosCompare( v_writerQos q, @@ -226,10 +219,6 @@ v_writerQosCompare( return result; } -/************************************************************** - * Public functions - **************************************************************/ - v_result v_writerQosCheck( v_writerQos _this) diff --git a/src/kernel/code/v_writerSample.c b/src/kernel/code/v_writerSample.c index c39d0cbd7..d55c4e8af 100644 --- a/src/kernel/code/v_writerSample.c +++ b/src/kernel/code/v_writerSample.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/code/v_writerSample.h b/src/kernel/code/v_writerSample.h index 3f120f536..31826c2f6 100644 --- a/src/kernel/code/v_writerSample.h +++ b/src/kernel/code/v_writerSample.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/code/v_writerStatistics.c b/src/kernel/code/v_writerStatistics.c index 7b6735e55..56abe3d89 100644 --- a/src/kernel/code/v_writerStatistics.c +++ b/src/kernel/code/v_writerStatistics.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/include/v_ackReader.h b/src/kernel/include/v_ackReader.h index e0c2edce8..eb81b5dac 100644 --- a/src/kernel/include/v_ackReader.h +++ b/src/kernel/include/v_ackReader.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/include/v_avgValue.h b/src/kernel/include/v_avgValue.h index 793e194af..eb180b542 100644 --- a/src/kernel/include/v_avgValue.h +++ b/src/kernel/include/v_avgValue.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/include/v_builtin.h b/src/kernel/include/v_builtin.h index ba8fc4119..4a3406972 100644 --- a/src/kernel/include/v_builtin.h +++ b/src/kernel/include/v_builtin.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/include/v_cfAttribute.h b/src/kernel/include/v_cfAttribute.h index 19918a424..d56839e75 100644 --- a/src/kernel/include/v_cfAttribute.h +++ b/src/kernel/include/v_cfAttribute.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/include/v_cfData.h b/src/kernel/include/v_cfData.h index 5f9672387..6790b16bf 100644 --- a/src/kernel/include/v_cfData.h +++ b/src/kernel/include/v_cfData.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/include/v_cfElement.h b/src/kernel/include/v_cfElement.h index c45da2ffe..ad9b4bb9c 100644 --- a/src/kernel/include/v_cfElement.h +++ b/src/kernel/include/v_cfElement.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/include/v_cfNode.h b/src/kernel/include/v_cfNode.h index 3cff29c87..0c2538419 100644 --- a/src/kernel/include/v_cfNode.h +++ b/src/kernel/include/v_cfNode.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/include/v_cmsoap.h b/src/kernel/include/v_cmsoap.h index 08542350f..6a547247f 100644 --- a/src/kernel/include/v_cmsoap.h +++ b/src/kernel/include/v_cmsoap.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/include/v_cmsoapStatistics.h b/src/kernel/include/v_cmsoapStatistics.h index 877686538..fdfff11c7 100644 --- a/src/kernel/include/v_cmsoapStatistics.h +++ b/src/kernel/include/v_cmsoapStatistics.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/include/v_collection.h b/src/kernel/include/v_collection.h index d59eb1aa0..7bc3716df 100644 --- a/src/kernel/include/v_collection.h +++ b/src/kernel/include/v_collection.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/include/v_configuration.h b/src/kernel/include/v_configuration.h index e52467967..eed9eddbd 100644 --- a/src/kernel/include/v_configuration.h +++ b/src/kernel/include/v_configuration.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -92,6 +93,11 @@ v_configurationGetSchedulingPolicy ( const c_char* name, v_schedulePolicyI *policy); +OS_API c_bool +v_configurationContainsService( + v_configuration config, + const char *serviceName); + #undef OS_API #endif /* V_CONFIGURATION_H */ diff --git a/src/kernel/include/v_copyIn.h b/src/kernel/include/v_copyIn.h index c3b4d2242..fc3f000e0 100644 --- a/src/kernel/include/v_copyIn.h +++ b/src/kernel/include/v_copyIn.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/include/v_dataReader.h b/src/kernel/include/v_dataReader.h index 96337a6cc..3e5a273a5 100644 --- a/src/kernel/include/v_dataReader.h +++ b/src/kernel/include/v_dataReader.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -34,6 +35,7 @@ #include "v_reader.h" #include "v_readerQos.h" #include "v_dataReaderSample.h" +#include "v_builtin.h" #if defined (__cplusplus) extern "C" { @@ -71,12 +73,12 @@ v_dataReaderWalkInstances ( OS_API v_dataReader v_dataReaderNew( - v_subscriber subscriber, - const c_char *name, - q_expr OQLexpr, + _In_ v_subscriber subscriber, + _In_opt_z_ const c_char *name, + _In_opt_ q_expr OQLexpr, const c_value params[], - v_readerQos qos, - c_bool enable); + os_uint32 nrOfParams, + _In_opt_ v_readerQos qos); OS_API v_dataReader v_dataReaderNewBySQL ( @@ -84,8 +86,8 @@ v_dataReaderNewBySQL ( const os_char *name, const os_char *expr, const c_value params[], - v_readerQos qos, - c_bool enable); + os_uint32 nrOfParams, + v_readerQos qos); OS_API void v_dataReaderFree( @@ -93,7 +95,7 @@ v_dataReaderFree( OS_API v_result v_dataReaderEnable( - v_dataReader _this); + _Inout_ v_dataReader _this); OS_API c_type v_dataReaderInstanceType( @@ -177,6 +179,36 @@ OS_API c_ulong v_dataReaderGetNumberOpenTransactions( v_dataReader _this); +OS_API v_result +v_dataReaderSetQos( + v_dataReader _this, + v_readerQos qos); + +/* This operation will visit all discovered matching publications for this dataReader. + * The given action routine will be invoked on each publication info message. + * The signature of the action routine : v_result (*action)(const v_publicationInfo *info, void *arg) + * Issue: don't like operating on info as being an attribute of a message, + * better visit the whole message then it can also be returned as kept ref. + */ +OS_API v_result +v_dataReaderReadMatchedPublications( + v_dataReader _this, + v_publicationInfo_action action, + c_voidp arg); + +/* This operation will visit the discovered matching publication for this dataReader identified by the given GID. + * The given action routine will be invoked on the GID associated publication info message. + * The signature of the action routine : v_result (*action)(const v_publicationInfo *info, void *arg) + * Issue: don't like operating on info as being an attribute of a message, + * better visit the whole message then it can also be returned as kept ref. + */ +OS_API v_result +v_dataReaderReadMatchedPublicationData( + v_dataReader _this, + v_gid publication, + v_publicationInfo_action action, + c_voidp arg); + #undef OS_API #if defined (__cplusplus) diff --git a/src/kernel/include/v_dataReaderEntry.h b/src/kernel/include/v_dataReaderEntry.h index e21705bf8..b10f0c3f8 100644 --- a/src/kernel/include/v_dataReaderEntry.h +++ b/src/kernel/include/v_dataReaderEntry.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -56,15 +57,20 @@ extern "C" { OS_API v_dataReaderEntry v_dataReaderEntryNew( v_dataReader dataReader, - v_index index, v_topic topic, q_expr _where, - const c_value *params[]); + const c_value *params[], + os_uint32 nrOfParams); OS_API void v_dataReaderEntryFree( v_dataReaderEntry _this); +OS_API void +v_dataReaderEntrySetTransactionAdmin( + _Inout_ v_dataReaderEntry _this, + _In_opt_ v_transactionGroupAdmin admin); + OS_API v_writeResult v_dataReaderEntryWrite( v_dataReaderEntry _this, diff --git a/src/kernel/include/v_dataReaderInstance.h b/src/kernel/include/v_dataReaderInstance.h index efcc80ea8..8804388e1 100644 --- a/src/kernel/include/v_dataReaderInstance.h +++ b/src/kernel/include/v_dataReaderInstance.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/include/v_dataReaderQuery.h b/src/kernel/include/v_dataReaderQuery.h index 158e0676c..f82b10f5e 100644 --- a/src/kernel/include/v_dataReaderQuery.h +++ b/src/kernel/include/v_dataReaderQuery.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/include/v_dataReaderSample.h b/src/kernel/include/v_dataReaderSample.h index 15a4131e2..7f7e675f4 100644 --- a/src/kernel/include/v_dataReaderSample.h +++ b/src/kernel/include/v_dataReaderSample.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/include/v_dataReaderStatistics.h b/src/kernel/include/v_dataReaderStatistics.h index 9e86aa512..9dd7e6982 100644 --- a/src/kernel/include/v_dataReaderStatistics.h +++ b/src/kernel/include/v_dataReaderStatistics.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -40,13 +41,14 @@ */ #define v_dataReaderStatistics(s) (C_CAST(s,v_dataReaderStatistics)) +_Ret_notnull_ OS_API v_dataReaderStatistics v_dataReaderStatisticsNew( - v_kernel k); + _In_ v_kernel k); OS_API void v_dataReaderStatisticsInit( - v_dataReaderStatistics _this); + _Inout_ v_dataReaderStatistics _this); OS_API void v_dataReaderStatisticsDeinit( diff --git a/src/kernel/include/v_dataView.h b/src/kernel/include/v_dataView.h index 0233f7399..9f97d3ad2 100644 --- a/src/kernel/include/v_dataView.h +++ b/src/kernel/include/v_dataView.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,7 +28,6 @@ #include "v_kernel.h" #include "v_reader.h" -#include "v_dataViewSample.h" #if defined (__cplusplus) extern "C" { @@ -49,7 +49,20 @@ extern "C" { * the type of the object is checked to be v_dataView or * one of its subclasses. */ -#define v_dataView(o) (C_CAST(o,v_dataView)) +#define v_dataView(o) (C_CAST(o,v_dataView)) +/** + * \brief The v_dataViewSample cast method. + * + * This method casts an object to a v_dataViewSample object. + * Before the cast is performed, if compiled with the NDEBUG flag not set, + * the type of the object is checked to be v_dataViewSample or + * one of its subclasses. + */ +#define v_dataViewSample(_this) (C_CAST(_this,v_dataViewSample)) + +#define v_dataViewInstance(_this) (C_CAST(_this,v_dataViewInstance)) +#define v_dataViewInstanceTemplate(_this) ((v_dataViewInstanceTemplate)(_this)) +#define v_dataViewSampleTemplate(_this) ((v_dataViewSampleTemplate)(_this)) #define v_dataView_t(scope) \ c_type(c_resolve(c_getBase(scope), \ diff --git a/src/kernel/include/v_dataViewInstance.h b/src/kernel/include/v_dataViewInstance.h deleted file mode 100644 index 30202399a..000000000 --- a/src/kernel/include/v_dataViewInstance.h +++ /dev/null @@ -1,159 +0,0 @@ -/* - * OpenSplice DDS - * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -#ifndef V_DATAVIEWINSTANCE_H -#define V_DATAVIEWINSTANCE_H - -/** \file kernel/include/v_dataViewInstance.h - * \brief This file defines the interface - * - */ - -#include "v_kernel.h" -#include "v_dataViewSample.h" -#include "os_if.h" -#include "v_query.h" -#include "v_dataReaderInstance.h" - -#ifdef OSPL_BUILD_CORE -#define OS_API OS_API_EXPORT -#else -#define OS_API OS_API_IMPORT -#endif -/* !!!!!!!!NOTE From here no more includes are allowed!!!!!!! */ - -/** - * \brief The v_dataViewInstance cast method. - * - * This method casts an object to a v_dataViewInstance object. - * Before the cast is performed, if compiled with the NDEBUG flag not set, - * the type of the object is checked to be v_dataViewInstance or - * one of its subclasses. - */ -#define v_dataViewInstance(_this) (C_CAST(_this,v_dataViewInstance)) - -#define v_dataViewInstanceTemplate(_this) ((v_dataViewInstanceTemplate)(_this)) - -#define v_dataViewInstanceEmpty(_this) \ - (v_dataViewInstance(_this)->sampleCount == 0) - -#define v_dataViewInstanceSampleCount(_this) \ - (v_dataViewInstance(_this)->sampleCount) - -#define v_dataViewInstanceState(_this) \ - (v_dataViewInstance(_this)->instanceState) - -#define v_dataViewInstanceView(_this) \ - (v_dataViewInstance(_this)->dataView) - - -typedef c_bool -(*v_dataViewInstanceAction)( - v_dataViewInstance _this, - c_voidp arg); - -OS_API v_dataViewInstance -v_dataViewInstanceNew( - v_dataView dataView, - v_readerSample sample); - -OS_API void -v_dataViewInstanceDeinit( - v_dataViewInstance _this); - -OS_API v_writeResult -v_dataViewInstanceWrite ( - v_dataViewInstance _this, - v_readerSample sample); - -OS_API void -v_dataViewInstanceWipe( - v_dataViewInstance _this); - -OS_API v_dataViewSample -v__dataViewInstanceWrite( - v_dataViewInstance instance, - v_dataViewSample sample, - v_dataViewSample position); - -OS_API void -v_dataViewInstanceRemove( - v_dataViewInstance _this); - -/** Getter and setter for users of the kernel */ -OS_API c_voidp -v_dataViewInstanceGetUserData( - v_dataViewInstance _this); - -OS_API void -v_dataViewInstanceSetUserData( - v_dataViewInstance _this, - c_voidp userData); - -/** New methods that will replace depricated methods */ - -OS_API c_bool -v_dataViewInstanceReadSamples( - v_dataViewInstance _this, - c_query query, - v_state sampleMask, - v_readerSampleAction action, - c_voidp arg); - -OS_API c_bool -v_dataViewInstanceTakeSamples( - v_dataViewInstance _this, - c_query query, - v_state sampleMask, - v_readerSampleAction action, - c_voidp arg); - -OS_API void -v_dataViewInstanceWalkSamples( - v_dataViewInstance _this, - v_readerSampleAction action, - c_voidp arg); - -OS_API c_bool -v_dataViewInstanceRemoveSample( - v_dataViewInstance _this, - v_dataViewSample sample); - -OS_API void -v_dataViewInstancePurge( - v_dataViewInstance _this); - -OS_API c_bool -v_dataViewInstanceTest( - v_dataViewInstance _this, - c_query query, - v_state sampleMask, - v_queryAction action, - c_voidp args); - -OS_API v_actionResult -v_dataViewSampleReadTake( - v_dataViewSample sample, - v_readerSampleAction action, - c_voidp arg, - c_bool consume); - -#undef OS_API - -#endif diff --git a/src/kernel/include/v_dataViewQos.h b/src/kernel/include/v_dataViewQos.h index 357856260..dae48082c 100644 --- a/src/kernel/include/v_dataViewQos.h +++ b/src/kernel/include/v_dataViewQos.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/include/v_dataViewQuery.h b/src/kernel/include/v_dataViewQuery.h index 607e57247..164f3381c 100644 --- a/src/kernel/include/v_dataViewQuery.h +++ b/src/kernel/include/v_dataViewQuery.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -28,7 +29,6 @@ #include "v_kernel.h" #include "v_event.h" #include "v_dataView.h" -#include "v_dataViewSample.h" #include "v_query.h" #if defined (__cplusplus) diff --git a/src/kernel/include/v_dataViewSample.h b/src/kernel/include/v_dataViewSample.h deleted file mode 100644 index c955850be..000000000 --- a/src/kernel/include/v_dataViewSample.h +++ /dev/null @@ -1,89 +0,0 @@ -/* - * OpenSplice DDS - * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -#ifndef V_DATAVIEWSAMPLE_H -#define V_DATAVIEWSAMPLE_H - -/** \file kernel/include/v_dataViewSample.h - * \brief This file defines the interface - * - */ - -#include "v_kernel.h" -#include "v_readerSample.h" -#include "os_if.h" - -#ifdef OSPL_BUILD_CORE -#define OS_API OS_API_EXPORT -#else -#define OS_API OS_API_IMPORT -#endif -/* !!!!!!!!NOTE From here no more includes are allowed!!!!!!! */ - -/** - * \brief The v_dataViewSample cast method. - * - * This method casts an object to a v_dataViewSample object. - * Before the cast is performed, if compiled with the NDEBUG flag not set, - * the type of the object is checked to be v_dataViewSample or - * one of its subclasses. - */ -#define v_dataViewSample(_this) (C_CAST(_this,v_dataViewSample)) - -#define v_dataViewSampleState(_this) \ - (v_readerSample(_this)->sampleState) - -#define v_dataViewSampleTestState(_this,mask) \ - v_stateTest(v_dataViewSampleState(_this),mask) - -#define v_dataViewSampleInstance(o) \ - ((v_dataViewInstance)(v_readerSampleInstance(v_readerSample(o)))) - -/** - * \brief The v_dataViewSampleList cast method. - * - * This method casts an object to a v_dataViewSampleList object. - * Before the cast is performed, if compiled with the NDEBUG flag not set, - * the type of the object is checked to be v_dataViewSampleList or - * one of its subclasses. - */ -#define v_dataViewSampleList(_this) (C_CAST(_this,v_dataViewSampleList)) - -#define v_dataViewSampleTemplate(_this) ((v_dataViewSampleTemplate)(_this)) - -OS_API v_dataViewSample -v_dataViewSampleNew ( - v_dataViewInstance instance, - v_readerSample sample); - -OS_API void -v_dataViewSampleFree ( - v_dataViewSample _this); - -OS_API void -v_dataViewSampleRemove( - v_dataViewSample _this); - -OS_API void -v_dataViewSampleListRemove( - v_dataViewSampleList _this); - -#undef OS_API - -#endif diff --git a/src/kernel/include/v_dbmsconnect.h b/src/kernel/include/v_dbmsconnect.h new file mode 100644 index 000000000..bd5d177c9 --- /dev/null +++ b/src/kernel/include/v_dbmsconnect.h @@ -0,0 +1,92 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#ifndef V_DBMSCONNECT_H +#define V_DBMSCONNECT_H + +#include "kernelModule.h" +#include "v_participantQos.h" + +#if defined (__cplusplus) +extern "C" { +#endif +#include "os_if.h" + +#ifdef OSPL_BUILD_CORE +#define OS_API OS_API_EXPORT +#else +#define OS_API OS_API_IMPORT +#endif +/* !!!!!!!!NOTE From here no more includes are allowed!!!!!!! */ + +/** + * \brief The v_dbmsconnect cast method. + * + * This method casts an object to a v_dbmsconnect object. + * Before the cast is performed, if compiled with the NDEBUG flag not set, + * the type of the object is checked to be v_dbmsconnect or + * one of its subclasses. + */ +#define v_dbmsconnect(o) (C_CAST(o,v_dbmsconnect)) + +/** + * \brief The v_dbmsconnect constructor. + * + * This method creates a record and replay service participant. + * + * Currently this class is part of the kernel but as being a pluggable service + * This definition should be part of the service itself. + * + * \param manager the kernel service manager + * \param name the participant name of the service + * \param extStateName the name by which the service state is identified. + * the state will be made accessible via this name. + * \param qos the service participant QoS policy values. + * + * \return NULL if construction fails, otherwise + * a reference to a newly instantiated service object. + */ +OS_API v_dbmsconnect +v_dbmsconnectNew( + v_kernel kernel, + const c_char *name, + const c_char *extStateName, + v_participantQos qos, + c_bool enable); + +/** + * \brief The v_dbmsconnect destructor. + * + * This method destroys the record and replay service participant. + * + * \param service the service to be destroyed. + * + */ +OS_API void +v_dbmsconnectFree( + v_dbmsconnect service); + +#undef OS_API + +#if defined (__cplusplus) +} +#endif + +#endif /* V_DBMSCONNECT_H */ diff --git a/src/kernel/include/v_durability.h b/src/kernel/include/v_durability.h index f2004d3f9..334338f8c 100644 --- a/src/kernel/include/v_durability.h +++ b/src/kernel/include/v_durability.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/include/v_durabilityClient.h b/src/kernel/include/v_durabilityClient.h index a9b0c191d..59428d608 100644 --- a/src/kernel/include/v_durabilityClient.h +++ b/src/kernel/include/v_durabilityClient.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/include/v_durabilityStatistics.h b/src/kernel/include/v_durabilityStatistics.h index 90395bf7b..de2745e1a 100644 --- a/src/kernel/include/v_durabilityStatistics.h +++ b/src/kernel/include/v_durabilityStatistics.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/include/v_entity.h b/src/kernel/include/v_entity.h index 514cecdad..eece22a1b 100644 --- a/src/kernel/include/v_entity.h +++ b/src/kernel/include/v_entity.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -210,13 +211,56 @@ v_entityWalkDependantEntities( v_entityAction action, c_voidp arg); +/** + * \brief Tries to enable the entity. + * + * An entity has state V_ENTITYSTATE_DISABLED after creation. Calling v_entityEnable + * will try to transition the entity to V_ENTITYSTATE_ENABLED. The state diagram + * for an entity is as follows. + * + * --> V_ENTITYSTATE_DISABLED --> v_entityEnable(...) --> V_ENTITYSTATE_ENABLING --> + * V_RESULT_OK: --> V_ENTITYSTATE_ENABLED + * !V_RESULT_OK: --> V_ENTITYSTATE_DISABLED + * + * --> V_ENTITYSTATE_ENABLING --> v_entityEnable(...) --> + * V_RESULT_OK: --> V_ENTITYSTATE_ENABLED + * !V_RESULT_OK: --> V_ENTITYSTATE_DISABLED + * + * --> V_ENTITYSTATE_ENABLED --> v_entityEnable(...) --> V_ENTITYSTATE_ENABLED + * + * So calling v_entityEnable on an already enabled entity will be a no-op. + * + * \return V_RESULT_OK if successfully enabled. + */ OS_API v_result v_entityEnable ( - v_entity _this); + _Inout_ v_entity _this); +/** + * \brief Returns true if the entity is enabled + * + * Once this function returns true, it will always be true for that entity. + * + * Use this function to check whether the entity is neither disabled nor enabling. + * + * \param _this The entity to check the state for + * \return true if the entity is enabled (so neither disabled or enabling) + */ OS_API c_bool v_entityEnabled ( - v_entity _this); + _In_ v_entity _this); + +/** + * \brief Returns true if the entity is in disabled state + * + * Use this function to check whether the entity is neither enabled nor enabling. + * + * \param _this The entity to check the state for + * \return true if the entity is disabled (so neither enabled or enabling) + */ +OS_API c_bool +v_entityDisabled ( + _In_ v_entity _this); /** * \brief The Entity getName method. @@ -278,6 +322,22 @@ c_longlong v_entityGetProcessId( v_entity _this); +OS_API v_state +v_entityGetStatusFlags( + v_entity e); + +OS_API v_result +v_entityGetProperty( + const v_entity _this, + const os_char * property, + os_char ** value); + +OS_API v_result +v_entitySetProperty( + const v_entity _this, + const os_char * property, + const os_char * value); + #undef OS_API #if defined (__cplusplus) diff --git a/src/kernel/include/v_entry.h b/src/kernel/include/v_entry.h index 7ec84ab12..035ec9728 100644 --- a/src/kernel/include/v_entry.h +++ b/src/kernel/include/v_entry.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -63,15 +64,17 @@ v_entryResend ( v_entry _this, v_message msg); -OS_API c_bool -v_entrySubscribe ( - v_entry _this, - v_partition d); - -OS_API c_bool -v_entryUnSubscribe ( +/** + * Adds the group to the entry. Returns TRUE if the entry was not yet connected + * to the group and the group has thus been added. Returns FALSE otherwise. + * + * @param _this The entry to add the group to + * @param g The group to be added to the entry + */ +OS_API void +v_entryAddGroup ( v_entry _this, - v_partition d); + v_group g); #undef OS_API diff --git a/src/kernel/include/v_event.h b/src/kernel/include/v_event.h index f22d9528d..56123c649 100644 --- a/src/kernel/include/v_event.h +++ b/src/kernel/include/v_event.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -77,13 +78,12 @@ #define v_eventTest(events,kind) (((events)&(kind))==(kind)) #define v_eventMaskTest(events,mask) (((events)&(mask))!=0) -typedef c_ulong v_eventKind; - C_CLASS(v_event); C_STRUCT(v_event) { v_eventKind kind; v_observable source; c_voidp data; + c_bool handled; /* if true then listeners will not be invoked. */ }; C_CLASS(v_historyDeleteEventData); diff --git a/src/kernel/include/v_filter.h b/src/kernel/include/v_filter.h index 4637bf4ff..6592ca1b6 100644 --- a/src/kernel/include/v_filter.h +++ b/src/kernel/include/v_filter.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -37,29 +38,29 @@ extern "C" { OS_API v_filter v_filterNew ( - v_topic t, + c_type t, + c_array keyList, q_expr e, - const c_value params[]); + const c_value params[], + os_uint32 nrOfParams); -OS_API v_filter -v_filterNewFromIndex ( - v_index t, - q_expr e, - const c_value params[]); +OS_API c_bool +v_filterEvalKey ( + v_filter _this, + c_object o); OS_API c_bool v_filterEval ( v_filter _this, c_object o); -OS_API void -v_filterSplit ( - v_topic topic, - q_expr where, - const c_value params[], - c_array *instanceQ, - c_array *sampleQ, - v_index index); +OS_API c_bool +v_filterHasKey ( + v_filter _this); + +OS_API c_bool +v_filterHasNonKey ( + v_filter _this); #undef OS_API diff --git a/src/kernel/include/v_fullCounter.h b/src/kernel/include/v_fullCounter.h index ea4fb90eb..36a765484 100644 --- a/src/kernel/include/v_fullCounter.h +++ b/src/kernel/include/v_fullCounter.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/include/v_group.h b/src/kernel/include/v_group.h index bda1a3d2c..15287d10f 100644 --- a/src/kernel/include/v_group.h +++ b/src/kernel/include/v_group.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -41,10 +42,6 @@ extern "C" { /* !!!!!!!!NOTE From here no more includes are allowed!!!!!!! */ typedef c_bool (*v_groupEntryAction)(v_entry e, c_voidp arg); -typedef c_bool (*v_groupWriterAction)(v_writer w, c_voidp arg); -typedef c_bool (*groupInstanceDisposeFunc)(v_groupInstance instance, c_voidp arg); -typedef c_bool (*dataReaderInstanceDisposeFunc)(v_dataReaderInstance instance, c_voidp arg); - /** * \brief The v_group cast method. @@ -85,10 +82,10 @@ typedef c_bool (*dataReaderInstanceDisposeFunc)(v_dataReaderInstance instance, c v_data(v_group(_this)->dataDescription) #define v_groupTopic(_this)\ - v_topic(v_group(_this)->topic) + (v_group(_this)->topic) #define v_groupPartition(_this)\ - v_partition(v_group(_this)->partition) + (v_group(_this)->partition) #define v_groupSampleMessage(_this) \ (v_groupSampleTemplate(_this)->message) @@ -125,7 +122,7 @@ OS_API void v_groupFree ( v_group _this); -OS_API void +OS_API c_bool v_groupAddEntry ( v_group _this, v_entry e); @@ -135,11 +132,6 @@ v_groupRemoveEntry ( v_group _this, v_entry e); -OS_API v_entry -v_groupLookupEntry ( - v_group _this, - v_reader r); - OS_API c_bool v_groupAddStream ( v_group _this, @@ -191,10 +183,10 @@ v_groupWrite ( v_resendScope *resendScope); OS_API v_writeResult -v_groupResend ( - v_group _this, v_message o, +v_groupWriteHistoricalData ( + v_group group, + v_message msg, v_groupInstance *instancePtr, - v_resendScope *resendScope, v_networkId writingNetworkId); OS_API v_writeResult @@ -205,12 +197,11 @@ v_groupWriteNoStream ( v_networkId writingNetworkId); OS_API v_writeResult -v_groupWriteNoStreamWithEntry ( - v_group group, - v_message msg, +v_groupResend ( + v_group _this, v_message o, v_groupInstance *instancePtr, - v_networkId writingNetworkId, - v_entry entry); + v_resendScope *resendScope, + v_networkId writingNetworkId); OS_API v_writeResult v_groupWriteCheckSampleLost( @@ -307,14 +298,14 @@ OS_API c_bool v_groupNwAttachedGet ( v_group _this ); -OS_API c_bool +OS_API v_alignState v_groupCompleteGet ( - v_group _this ); + _In_ v_group _this ); -OS_API void +OS_API v_alignState v_groupCompleteSet ( - v_group _this, - c_bool complete); + _Inout_ v_group _this, + _In_ v_alignState alignState); OS_API void v_groupNotifyAwareness ( @@ -367,19 +358,6 @@ OS_API void v_groupUpdatePurgeList( v_group group); -OS_API v_groupInstance -v_groupLookupInstance( - v_group group, - c_value keyValue[]); - -OS_API v_groupInstance -v_groupLookupInstanceAndRegistration( - v_group group, - c_value keyValue[], - v_gid gidTemplate, - v_matchIdentityAction predicate, - v_registration *registration); - OS_API v_message v_groupCreateUntypedInvalidMessage( v_kernel kernel, @@ -461,6 +439,22 @@ v_groupDisconnectWriter( c_bool isLocal, c_bool isImplicit); +OS_API const char * +v_alignStateImage( + _In_ v_alignState s); + +OS_API void +v_groupWalkInstances( + v_group _this, + c_action action, + void *actionArg); + +OS_API v_writeResult +v_groupWriteHistoricalToReader ( + v_group group, + v_message msg, + v_entry entry); + #undef OS_API #if defined (__cplusplus) diff --git a/src/kernel/include/v_groupInstance.h b/src/kernel/include/v_groupInstance.h index c8544fd43..0d16a79ea 100644 --- a/src/kernel/include/v_groupInstance.h +++ b/src/kernel/include/v_groupInstance.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -43,15 +44,21 @@ v_groupInstanceCreateTypedInvalidMessage( OS_API v_registration v_groupInstanceGetRegistration( - v_groupInstance instance, + v_groupInstance _this, v_gid gidTemplate, v_matchIdentityAction predicate); OS_API void v_groupInstanceUnregisterByTime ( - v_groupInstance instance, + v_groupInstance _this, os_timeW time); +OS_API void +v_groupInstanceKeyToString( + v_groupInstance _this, + char *keystr, + size_t keystr_size); + #undef OS_API #endif diff --git a/src/kernel/include/v_groupQueue.h b/src/kernel/include/v_groupQueue.h index b0ed019b5..a5ed3a583 100644 --- a/src/kernel/include/v_groupQueue.h +++ b/src/kernel/include/v_groupQueue.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/include/v_groupQueueStatistics.h b/src/kernel/include/v_groupQueueStatistics.h index 778c75c24..9c7a4ef2a 100644 --- a/src/kernel/include/v_groupQueueStatistics.h +++ b/src/kernel/include/v_groupQueueStatistics.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/include/v_groupSet.h b/src/kernel/include/v_groupSet.h index 924c9af6d..d26f2db17 100644 --- a/src/kernel/include/v_groupSet.h +++ b/src/kernel/include/v_groupSet.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/include/v_groupStore.h b/src/kernel/include/v_groupStore.h new file mode 100644 index 000000000..a80eb445f --- /dev/null +++ b/src/kernel/include/v_groupStore.h @@ -0,0 +1,70 @@ +/* + * OpenSplice DDS + * + * This software and documentation are Copyright 2006 to TO_YEAR PrismTech + * Limited, its affiliated companies and licensors. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#ifndef V_GROUPSTORE_H +#define V_GROUPSTORE_H + +#include "v_kernel.h" + +#if defined (__cplusplus) +extern "C" { +#endif + +#ifdef OSPL_BUILD_CORE +#define OS_API OS_API_EXPORT +#else +#define OS_API OS_API_IMPORT +#endif + +C_CLASS(v_groupStoreQuery); + +OS_API v_groupStoreQuery +v_groupStoreQueryNew( + const v_groupStore _this, + const os_char *expression, + const c_value params[], + const os_uint32 nrOfParams); + +OS_API v_groupStoreQuery +v_groupStoreQueryNew2( + const v_groupStore _this, + const os_char *expression, + const os_char *params[], + const os_uint32 nrOfParams); + +OS_API void +v_groupStoreQueryFree( + v_groupStoreQuery _this); + +typedef os_boolean (*v_groupStoreAction)(const v_groupSample sample, const void *actionArg); + +OS_API v_result +v_groupStoreRead( + const v_groupStore _this, + const v_groupStoreQuery query, + const v_groupStoreAction action, + const void *actionArg); + +#undef OS_API + +#if defined (__cplusplus) +} +#endif + +#endif diff --git a/src/kernel/include/v_groupStream.h b/src/kernel/include/v_groupStream.h index 20020c5cb..b5e4c7fbf 100644 --- a/src/kernel/include/v_groupStream.h +++ b/src/kernel/include/v_groupStream.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -54,19 +55,19 @@ extern "C" { */ #define v_groupStream(s) (C_CAST(s,v_groupStream)) -OS_API void +OS_API void v_groupStreamInit( v_groupStream stream, const c_char *name, v_subscriber subscriber, v_readerQos qos, c_iter expr); - -OS_API void + +OS_API void v_groupStreamDeinit( v_groupStream stream); -OS_API void +OS_API void v_groupStreamFree( v_groupStream stream); diff --git a/src/kernel/include/v_handle.h b/src/kernel/include/v_handle.h index f4ebbffc3..549071786 100644 --- a/src/kernel/include/v_handle.h +++ b/src/kernel/include/v_handle.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -102,19 +103,6 @@ OS_API v_handleServer v_handleServerNew ( c_base base); - -/** - * \brief The HandleServer destructor. - * - * This method will free all resources related to the given HandleServer object. - * - * \param _this The given HandleServer object that must be destroyed. - ** -OS_API void -v_handleServerFree( - v_handleServer _this); - */ - /** * \brief The register method that creates a new Handle for a specified object. * @@ -156,7 +144,7 @@ typedef enum { V_HANDLE_ILLEGAL, /* The handle is bogus */ V_HANDLE_SUSPENDED/* The handle server is suspended. */ } v_handleResult; - + OS_API v_handleResult v_handleClaim( v_handle _this, @@ -168,7 +156,7 @@ v_handleClaim( * This method will release a previous claimed handle and thereby notifying * the HandleServer that the object associated to this handle will not be * accessed anymore. - * + * * \param _this The handle which specifies the required object. * \return The result indicates the state of the supplied handle */ diff --git a/src/kernel/include/v_historicalDataRequest.h b/src/kernel/include/v_historicalDataRequest.h index 2611a17d7..b2e75f258 100644 --- a/src/kernel/include/v_historicalDataRequest.h +++ b/src/kernel/include/v_historicalDataRequest.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/include/v_instance.h b/src/kernel/include/v_instance.h index 3a68c9abc..6461d9174 100644 --- a/src/kernel/include/v_instance.h +++ b/src/kernel/include/v_instance.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,6 +25,13 @@ #include "v_kernel.h" +#ifdef OSPL_BUILD_CORE +#define OS_API OS_API_EXPORT +#else +#define OS_API OS_API_IMPORT +#endif +/* !!!!!!!!NOTE From here no more includes are allowed!!!!!!! */ + #define v_instance(o) (C_CAST(o,v_instance)) #define v_instanceState(_this) (v_instance(_this)->state) @@ -40,4 +48,15 @@ void v_instanceDeinit ( v_instance _this); +OS_API c_voidp +v_instanceSetUserData( + v_instance _this, + c_voidp userData); + +OS_API c_voidp +v_instanceGetUserData( + v_instance _this); + +#undef OS_API + #endif diff --git a/src/kernel/include/v_kernel.h b/src/kernel/include/v_kernel.h index 3e3439f98..76fe0cadc 100644 --- a/src/kernel/include/v_kernel.h +++ b/src/kernel/include/v_kernel.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -39,9 +40,6 @@ extern "C" { #define OS_API OS_API_IMPORT #endif /* !!!!!!!!NOTE From here no more includes are allowed!!!!!!! */ - -#define V_KERNEL_VERSION "Kernel 4.1.0" - #define C_REPORT(s) printf(s) /** @@ -72,9 +70,10 @@ extern "C" { #define v_objectKernel(o) (v_kernel(v_object(o)->kernel)) #define v_objectKind(o) (v_object(o)->kind) -char * +_Ret_z_ +const char * v_objectKindImage( - v_object _this); + _In_ v_object _this); #define v_kernelType(k,kind) (v_kernel(k)->type[kind]) @@ -130,22 +129,25 @@ v_isEnabledStatistics ( v_kernel _this, const char *categoryName); +_Check_return_ +_Ret_maybenull_ +_Success_(return != NULL) OS_API v_kernel v_kernelNew ( - c_base b, - const c_char *name, - v_kernelQos qos, - v_processInfo *procInfo); + _In_ c_base base, + _In_z_ const c_char *name, + _In_ v_kernelQos qos, + _Outptr_ v_processInfo* procInfo); OS_API void v_kernelEnable( - v_kernel kernel, - const c_char *name); + _Inout_ v_kernel kernel); OS_API v_kernel v_kernelAttach ( c_base b, const c_char *name, + os_duration timeout, v_processInfo *procInfo /* Don't free this reference */); OS_API c_ulong @@ -225,15 +227,20 @@ v_resolveParticipants ( v_kernel _this, const c_char *name); +_Check_return_ +_Ret_notnull_ +_Pre_satisfies_(kind >= K_KERNEL && kind < K_TYPECOUNT) OS_API v_object v_objectNew ( - v_kernel _this, - v_kind kind); + _In_ v_kernel _this, + _In_ v_kind kind); +_Check_return_ +_Ret_maybenull_ OS_API v_object v_objectNew_s ( - v_kernel _this, - v_kind kind); + _In_ v_kernel _this, + _In_ v_kind kind); OS_API v_object v_new ( @@ -291,6 +298,27 @@ v_kernelCreatePersistentSnapshot( const c_char * topic_expression, const c_char * uri); +typedef v_result (*v_domainReadAction)(const v_group group, const v_groupInstance instance, const v_message msg, const void *actionArg); + +OS_API v_result +v_kernelRead( + const v_kernel _this, + const os_char *partition, + const os_char *topic, + const os_char *query, + const v_domainReadAction action, + const void *actionArg); + +typedef v_result (*v_domainGroupReadAction)(const v_group group, const void *actionArg); + +OS_API v_result +v_kernelGroupRead( + const v_kernel _this, + const os_char *partition, + const os_char *topic, + const v_domainGroupReadAction action, + const void *actionArg); + OS_API v_accessMode v_kernelPartitionAccessMode( v_kernel _this, @@ -311,9 +339,10 @@ v_kernel_lookup_type( v_kernel _this, const os_char *type_name); +_Ret_z_ OS_API const os_char * v_resultImage ( - v_result result); + _In_ v_result result); OS_API const os_char * v_writeResultImage( @@ -376,7 +405,7 @@ v_kernelGetProcessInfo( _Ret_notnull_ _Must_inspect_result_ OS_API v_processInfo -v_kernelGetOwnProcessInfo( +v_kernelGetOwnProcessInfoWeakRef( _Inout_ v_kernel _this); #define V_KERNEL_THREAD_FLAGS_GET (0U) @@ -389,6 +418,9 @@ v_kernelThreadFlags ( _In_ os_uint32 mask, _In_ os_uint32 value); +OS_API c_bool +v_kernelThreadInProtectedArea(); + OS_API os_uint32 v_kernelThreadProtectCount ( _In_ os_uint32 serial); @@ -462,6 +494,10 @@ _Ret_maybenull_ OS_API void * v_kernelUnprotect(void); +OS_API void +v_kernelUnprotectFinalize( + void * usrData); + OS_API os_int32 v_kernelThreadInfoGetDomainId(void); @@ -472,24 +508,83 @@ v_kernelThreadInfoGetDomainId(void); */ OS_API c_bool v_kernelGetDurabilitySupport( - v_kernel kernel); + _In_ _Const_ v_kernel kernel); + +OS_API c_bool +v_kernelHasDurabilityService( + _In_ _Const_ v_kernel kernel); /** * This call acquires the kernel group transaction access lock. * Taking the kernel group transaction access lock ensures that the group transaction * information can be read without being modified by a writer. */ -OS_API v_result +OS_API void v_kernelGroupTransactionBeginAccess( - v_kernel _this); + _Inout_ v_kernel _this); /** * This call releases the kernel group transaction access lock. */ -OS_API v_result +OS_API void v_kernelGroupTransactionEndAccess( + _Inout_ v_kernel _this); + + +OS_API c_bool +v_kernelGetAlignedState( v_kernel _this); +OS_API void +v_kernelSetAlignedState( + v_kernel _this, + c_bool aligned); + +OS_API void +v_kernelTransactionsPurge( + v_kernel _this); + +/* The operation WalkPublications will visit all discovered publication messages and + * invoke the given publication action function on each publication message. + * The given argument arg is passed as context information to the invoked action function. + * The walk will stop when all messages are processed or when the action function returns FALSE. + */ +typedef os_boolean (*v_publication_action)(const v_message publication, void *arg); + +OS_API v_result +v_kernelWalkPublications( + v_kernel _this, + v_publication_action action, + void *arg); + +/* The operation WalkSubscriptions will visit all discovered subscription messages and + * invoke the given subscription action function on each subscription message. + * The given argument arg is passed as context information to the invoked action function. + * The walk will stop when all messages are processed or when the action function returns FALSE. + */ +typedef os_boolean (*v_subscription_action)(const v_message subscription, void *arg); + +OS_API v_result +v_kernelWalkSubscriptions( + v_kernel _this, + v_subscription_action action, + void *arg); + +#define V_ISOLATE_NONE (0) +#define V_ISOLATE_DEAF (1) +#define V_ISOLATE_MUTE (2) +#define V_ISOLATE_ALL (V_ISOLATE_DEAF | V_ISOLATE_MUTE) + +OS_API v_result +v_kernelSetIsolate( + const v_kernel _this, + const os_uint32 isolate); + +OS_API v_result +v_kernelGetIsolate( + const v_kernel _this, + os_uint32 *isolate); + #undef OS_API #if defined (__cplusplus) diff --git a/src/kernel/include/v_kernelParser.h b/src/kernel/include/v_kernelParser.h index 21110e2e8..19739ab07 100644 --- a/src/kernel/include/v_kernelParser.h +++ b/src/kernel/include/v_kernelParser.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/include/v_kernelQos.h b/src/kernel/include/v_kernelQos.h index 96ebd8fef..92c828b9f 100644 --- a/src/kernel/include/v_kernelQos.h +++ b/src/kernel/include/v_kernelQos.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/include/v_kernelStatistics.h b/src/kernel/include/v_kernelStatistics.h index 622198eb8..727c42903 100644 --- a/src/kernel/include/v_kernelStatistics.h +++ b/src/kernel/include/v_kernelStatistics.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/include/v_leaseManager.h b/src/kernel/include/v_leaseManager.h index 8243078df..a00f7816f 100644 --- a/src/kernel/include/v_leaseManager.h +++ b/src/kernel/include/v_leaseManager.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/include/v_lifespanSample.h b/src/kernel/include/v_lifespanSample.h index 2e92c4e43..ed10037d0 100644 --- a/src/kernel/include/v_lifespanSample.h +++ b/src/kernel/include/v_lifespanSample.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/include/v_listener.h b/src/kernel/include/v_listener.h index 57376efd5..4cfbbd9a7 100644 --- a/src/kernel/include/v_listener.h +++ b/src/kernel/include/v_listener.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -101,16 +102,6 @@ v_listenerWait( c_voidp arg, const os_duration time); -/** - * Wake-up the thread(s) waiting on the listener. - * The event returned to the waiting thread is V_EVENT_TRIGGER. - * - * \param _this a reference to the listener object. - */ -OS_API void -v_listenerTrigger( - v_listener _this); - /** * Notifies the listener on a state change of one of the conditions. * Every event the listener receives is stored in a list. The events @@ -118,7 +109,8 @@ v_listenerTrigger( * * \param _this a reference to the listener object. * \param e a reference to the event describing the reason of the - * notification. + * notification. A NULL event only triggers blocking wait + * calls to wakeup. * \param listener reference to listening entity. */ OS_API void diff --git a/src/kernel/include/v_maxValue.h b/src/kernel/include/v_maxValue.h index 9a7aa3d7d..0868c2623 100644 --- a/src/kernel/include/v_maxValue.h +++ b/src/kernel/include/v_maxValue.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/include/v_message.h b/src/kernel/include/v_message.h index baf4b4425..e6d01a6cb 100644 --- a/src/kernel/include/v_message.h +++ b/src/kernel/include/v_message.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -110,16 +111,23 @@ extern "C" { #endif /** - * Returns the relative order two v_message's. - * @param m1 The address of a v_message - * @param m2 The address of a v_message - * @return C_EQ, C_LT or C_GT if m1 is respectively equal, less or greater than m2 + * Returns the relative order two v_message's. It is important to realize that + * the outcome of this function is not commutative: the sample that is to be + * inserted needs to be passed first, and the already available sample that it + * is compared to needs to be passed second. The reason for this is that the + * semantical meaning of the L_IMPLICIT flag is different for a sample that is + * to be inserted (it will always be newer than any existing sample) than for + * a sample that is already available (any non-implicit sample will always be + * newer than an available implicit sample). + * @param insertedMessage The address of the v_message to be inserted + * @param availableMessage The address of the already available v_message that it is compared to. + * @return C_EQ, C_LT or C_GT if insertedMessage is respectively equal, less or greater than availableMessage */ OS_API c_equality v_messageCompare ( - v_message m1, - v_message m2); + v_message insertedMessage, + v_message availableMessage); /** diff --git a/src/kernel/include/v_messageExt.h b/src/kernel/include/v_messageExt.h index 5c043a43b..f11db1df5 100644 --- a/src/kernel/include/v_messageExt.h +++ b/src/kernel/include/v_messageExt.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/include/v_messageQos.h b/src/kernel/include/v_messageQos.h index 8edae974c..ec290d9d7 100644 --- a/src/kernel/include/v_messageQos.h +++ b/src/kernel/include/v_messageQos.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/include/v_minValue.h b/src/kernel/include/v_minValue.h index 34d57006f..9ee7a25e9 100644 --- a/src/kernel/include/v_minValue.h +++ b/src/kernel/include/v_minValue.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/include/v_misc.h b/src/kernel/include/v_misc.h index 885dcc8ad..9f0bd1646 100644 --- a/src/kernel/include/v_misc.h +++ b/src/kernel/include/v_misc.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/include/v_networkChannelStatistics.h b/src/kernel/include/v_networkChannelStatistics.h index 4ae3963a0..cf7e5561c 100644 --- a/src/kernel/include/v_networkChannelStatistics.h +++ b/src/kernel/include/v_networkChannelStatistics.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/include/v_networkHashValue.h b/src/kernel/include/v_networkHashValue.h new file mode 100644 index 000000000..d32b95d50 --- /dev/null +++ b/src/kernel/include/v_networkHashValue.h @@ -0,0 +1,54 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef V_NETWORKHASHVALUE_H +#define V_NETWORKHASHVALUE_H + +#include "kernelModuleI.h" + +#if defined (__cplusplus) +extern "C" { +#endif +#include "os_if.h" + +#ifdef OSPL_BUILD_CORE +#define OS_API OS_API_EXPORT +#else +#define OS_API OS_API_IMPORT +#endif + +OS_API v_networkHashValue +v_networkHashValueCalculate( + const char * key1, + const char * key2); + +OS_API c_equality +v_networkHashValueCompare( + v_networkHashValue * value1, + v_networkHashValue * value2); + +#undef OS_API + +#if defined (__cplusplus) +} +#endif + +#endif /* V_NETWORKHASHVALUE_H */ diff --git a/src/kernel/include/v_networkQueue.h b/src/kernel/include/v_networkQueue.h index 65ba822e2..c82b2020d 100644 --- a/src/kernel/include/v_networkQueue.h +++ b/src/kernel/include/v_networkQueue.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/include/v_networkQueueStatistics.h b/src/kernel/include/v_networkQueueStatistics.h index 1ebbc0e23..584fe59e1 100644 --- a/src/kernel/include/v_networkQueueStatistics.h +++ b/src/kernel/include/v_networkQueueStatistics.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/include/v_networkReader.h b/src/kernel/include/v_networkReader.h index a1f6ebcb8..2f96cef28 100644 --- a/src/kernel/include/v_networkReader.h +++ b/src/kernel/include/v_networkReader.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/include/v_networkReaderEntry.h b/src/kernel/include/v_networkReaderEntry.h index 1b11ab0d6..30fc2c8e5 100644 --- a/src/kernel/include/v_networkReaderEntry.h +++ b/src/kernel/include/v_networkReaderEntry.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/include/v_networkReaderStatistics.h b/src/kernel/include/v_networkReaderStatistics.h index 49b1c8e8c..61fe22ff6 100644 --- a/src/kernel/include/v_networkReaderStatistics.h +++ b/src/kernel/include/v_networkReaderStatistics.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/include/v_networking.h b/src/kernel/include/v_networking.h index b54642d4c..39bd323e2 100644 --- a/src/kernel/include/v_networking.h +++ b/src/kernel/include/v_networking.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/include/v_networkingStatistics.h b/src/kernel/include/v_networkingStatistics.h index dafb59b4e..c7760e7d7 100644 --- a/src/kernel/include/v_networkingStatistics.h +++ b/src/kernel/include/v_networkingStatistics.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/include/v_nwbridge.h b/src/kernel/include/v_nwbridge.h index 68dfc956d..4f868b858 100644 --- a/src/kernel/include/v_nwbridge.h +++ b/src/kernel/include/v_nwbridge.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/include/v_objectLoan.h b/src/kernel/include/v_objectLoan.h index 1b07ab59b..362691df6 100644 --- a/src/kernel/include/v_objectLoan.h +++ b/src/kernel/include/v_objectLoan.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/include/v_observable.h b/src/kernel/include/v_observable.h index 55382c334..aaacd6158 100644 --- a/src/kernel/include/v_observable.h +++ b/src/kernel/include/v_observable.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -28,18 +29,6 @@ * describes the reason of notification. */ -#include "v_kernel.h" -#include "v_observer.h" -#include "v_event.h" -#include "os_if.h" - -#ifdef OSPL_BUILD_CORE -#define OS_API OS_API_EXPORT -#else -#define OS_API OS_API_IMPORT -#endif -/* !!!!!!!!NOTE From here no more includes are allowed!!!!!!! */ - /** * \brief The v_observable cast method. * @@ -49,51 +38,24 @@ */ #define v_observable(_this) (C_CAST(_this,v_observable)) -/** - * Notifies all observers of the observable. - * - * \param _this the reference to an observable object. - * \param event the event describes the reason of notification and - * is passed to the observers. +/* Following is a temporary public declaration of v_observableAddObserver to support cmx legacy API. + * The dependency on this operation must be removed so it can be made private as intended. */ -OS_API void -v_observableNotify( - v_observable _this, - v_event event); +#include "kernelModuleI.h" + +#ifdef OSPL_BUILD_CORE +#define OS_API OS_API_EXPORT +#else +#define OS_API OS_API_IMPORT +#endif -/** - * Add an observer to the observable. - * By adding an observer to the observable, the observer is notified on - * state changes of the observable. With this notification the given - * userData is also sent. - * - * \param _this the reference to an observable object. - * \param observer the reference to the observer object to add. - * \param userData this data also sent when notify the given observer. - * \return TRUE if the observer is added, otherwise FALSE. - */ OS_API c_bool v_observableAddObserver( v_observable _this, v_observer observer, + v_eventMask mask, c_voidp userData); -/** - * Removes an observer from the observable. - * By removing an observer from the observable, the observer is no longer - * notified on state changes of the observable. - * - * \param _this the reference to an observable object. - * \param observer the reference to the observer object to remove. - * \param userData the reference to the userdata belonging to the proxy of the observer object to remove. - * \return TRUE if the observer is removed, otherwise FALSE. - */ -OS_API c_bool -v_observableRemoveObserver ( - v_observable _this, - v_observer observer, - void** userData); - #undef OS_API #endif diff --git a/src/kernel/include/v_observer.h b/src/kernel/include/v_observer.h index 435f588a7..666de6f7d 100644 --- a/src/kernel/include/v_observer.h +++ b/src/kernel/include/v_observer.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -50,6 +51,7 @@ #include "v_kernel.h" #include "v_event.h" +#include "v_observable.h" #include "os_if.h" #ifdef OSPL_BUILD_CORE @@ -68,6 +70,9 @@ */ #define v_observer(o) (C_CAST(o,v_observer)) +#define v_observerWaitCount(_this) \ + (v_observer(_this)->waitCount) + /** * Notify the observer. * This method notifies the observer. @@ -125,6 +130,13 @@ v_observerTimedWait( v_observer _this, const os_duration timeout); +c_ulong +v_observerTimedWaitAction( + v_observer o, + const os_duration time, + const c_action action, + c_voidp arg); + /** * Add the event(s) the observer is interested in. * @@ -187,14 +199,20 @@ v_observerSetEventMask( v_observer _this, c_ulong mask); -#define v_observerLock(_this) \ - (void)c_mutexLock(&v_observer(_this)->mutex) +/* + * The following three operations are depriated! + */ +OS_API void +v_observerLock( + v_observer o); -#define v_observerUnlock(_this) \ - c_mutexUnlock(&v_observer(_this)->mutex) +OS_API void +v_observerUnlock( + v_observer o); -#define v_observerWaitCount(_this) \ - (v_observer(_this)->waitCount) +OS_API void +v_observerClearEventFlags( + v_observer _this); #undef OS_API diff --git a/src/kernel/include/v_participant.h b/src/kernel/include/v_participant.h index 9c028793c..a97cb4251 100644 --- a/src/kernel/include/v_participant.h +++ b/src/kernel/include/v_participant.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -88,10 +89,9 @@ v_participantNew( */ OS_API void v_participantInit( - v_participant _this, - const c_char *name, - v_participantQos qos, - c_bool enable); + _Inout_ v_participant _this, + _In_opt_z_ const c_char *name, + _In_ v_participantQos qos); /** \fn void v_participantFree (v_participant _this) * \brief This function will free all resources claimed by the participant or any @@ -116,7 +116,7 @@ v_participantDeinit( OS_API v_result v_participantEnable ( - v_participant p); + _In_ v_participant p); OS_API v_participantQos v_participantGetQos( @@ -158,17 +158,6 @@ v_participantNotify( v_event e, c_voidp userData); -/** \fn void v_participantConnectNewGroup( v_participant _this, v_event event); - * \brief This function will connect all DataWriters and DataReaders of - * intrest to the new group (indecated by the 'new group' event. - * Note that for now the event is passed but eventually the group should be - * passed. - */ -OS_API void -v_participantConnectNewGroup ( - v_participant _this, - v_event event); - OS_API void v_participantAssertLiveliness( v_participant _this); @@ -195,10 +184,29 @@ OS_API void v_participantResendManagerQuit( v_participant _this); -OS_API v_typeRepresentation -v_participantLookupTypeRepresentation ( - v_participant p, - const os_char *typeName); +OS_API void +v_participantTransactionsPurge ( + v_participant _this); + +OS_API v_result +v_participantIgnoreParticipant ( + v_participant _this, + v_gid gid); + +OS_API v_result +v_participantIgnoreTopic ( + v_participant _this, + v_gid gid); + +OS_API v_result +v_participantIgnorePublication ( + v_participant _this, + v_gid gid); + +OS_API v_result +v_participantIgnoreSubscription ( + v_participant _this, + v_gid gid); #undef OS_API diff --git a/src/kernel/include/v_participantQos.h b/src/kernel/include/v_participantQos.h index f9a16510a..fc7cecdd0 100644 --- a/src/kernel/include/v_participantQos.h +++ b/src/kernel/include/v_participantQos.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/include/v_partition.h b/src/kernel/include/v_partition.h index 9e1004a50..22fd23d23 100644 --- a/src/kernel/include/v_partition.h +++ b/src/kernel/include/v_partition.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/include/v_policy.h b/src/kernel/include/v_policy.h index 5a519f9b4..1f4184565 100644 --- a/src/kernel/include/v_policy.h +++ b/src/kernel/include/v_policy.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -222,7 +223,10 @@ extern "C" { (((p).max_instances == V_LENGTH_UNLIMITED) ||\ ((p).max_instances > 0)) &&\ (((p).max_samples_per_instance == V_LENGTH_UNLIMITED) ||\ - ((p).max_samples_per_instance > 0))) + ((p).max_samples_per_instance > 0)) &&\ + (((p).max_samples == V_LENGTH_UNLIMITED) ||\ + ((p).max_samples_per_instance == V_LENGTH_UNLIMITED) ||\ + ((p).max_samples >= (p).max_samples_per_instance))) #define v_resourcePolicyIsUnlimited(p)\ (((p).max_samples == V_LENGTH_UNLIMITED) &&\ diff --git a/src/kernel/include/v_processInfo.h b/src/kernel/include/v_processInfo.h index bf308cbbb..39cb9fd03 100644 --- a/src/kernel/include/v_processInfo.h +++ b/src/kernel/include/v_processInfo.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,7 +28,7 @@ extern "C" { #endif #include "os_if.h" -#ifdef OSPL_BUILD_KERNEL +#ifdef OSPL_BUILD_CORE #define OS_API OS_API_EXPORT #else #define OS_API OS_API_IMPORT diff --git a/src/kernel/include/v_projection.h b/src/kernel/include/v_projection.h index 4476b180a..b7da7f5e7 100644 --- a/src/kernel/include/v_projection.h +++ b/src/kernel/include/v_projection.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/include/v_proxy.h b/src/kernel/include/v_proxy.h index 6962013d2..41684348b 100644 --- a/src/kernel/include/v_proxy.h +++ b/src/kernel/include/v_proxy.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/include/v_public.h b/src/kernel/include/v_public.h index cf138efb4..9eb42e683 100644 --- a/src/kernel/include/v_public.h +++ b/src/kernel/include/v_public.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/include/v_publisher.h b/src/kernel/include/v_publisher.h index 623973963..a20f5bdc4 100644 --- a/src/kernel/include/v_publisher.h +++ b/src/kernel/include/v_publisher.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -78,26 +79,11 @@ OS_API v_result v_publisherEnable ( v_publisher _this); -OS_API void -v_publisherPublish ( - v_publisher _this, - const c_char *partitionExpr); - -OS_API void -v_publisherUnPublish ( - v_publisher _this, - const c_char *partitionExpr); - OS_API c_iter v_publisherLookupPartitions ( v_publisher _this, const c_char *partitionExpr); -OS_API c_bool -v_publisherCheckPartitionInterest ( - v_publisher _this, - v_partition partition); - OS_API v_result v_publisherAddWriter ( v_publisher _this, diff --git a/src/kernel/include/v_publisherQos.h b/src/kernel/include/v_publisherQos.h index 7a93dc56f..ed03a4ded 100644 --- a/src/kernel/include/v_publisherQos.h +++ b/src/kernel/include/v_publisherQos.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/include/v_qos.h b/src/kernel/include/v_qos.h index 13ce7cd72..1f2e48edb 100644 --- a/src/kernel/include/v_qos.h +++ b/src/kernel/include/v_qos.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -47,10 +48,12 @@ extern "C" { typedef c_ulong v_qosChangeMask; /* mask indicating, which policies have changed */ +_Check_return_ +_Pre_satisfies_(kind >= V_PARTITION_QOS && kind < V_COUNT_QOS) OS_API v_qos -v_qosCreate ( - c_base base, - v_qosKind kind); +v_qosCreate( + _In_ c_base base, + _In_ v_qosKind kind); OS_API void v_qosFree ( diff --git a/src/kernel/include/v_query.h b/src/kernel/include/v_query.h index 905783093..301d6b955 100644 --- a/src/kernel/include/v_query.h +++ b/src/kernel/include/v_query.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/include/v_queryStatistics.h b/src/kernel/include/v_queryStatistics.h index b1230b406..02d7f43e6 100644 --- a/src/kernel/include/v_queryStatistics.h +++ b/src/kernel/include/v_queryStatistics.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/include/v_reader.h b/src/kernel/include/v_reader.h index d836e97c6..9ef406bc9 100644 --- a/src/kernel/include/v_reader.h +++ b/src/kernel/include/v_reader.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -104,7 +105,8 @@ v_readerGetSubscriptionMatchedStatus( OS_API v_result v_readerWaitForHistoricalData( v_reader _this, - os_duration timeout); + os_duration timeout, + c_bool enable); OS_API v_result v_readerWaitForHistoricalDataWithCondition( @@ -117,13 +119,20 @@ v_readerWaitForHistoricalDataWithCondition( c_long max_samples, c_long max_instances, c_long max_samples_per_instance, - os_duration timeout); + os_duration timeout, + c_bool enable); OS_API void v_readerNotifyStateChange( v_reader _this, c_bool complete); +OS_API c_bool +v_readerWalkEntries_nl( + v_reader _this, + c_action action, + c_voidp arg); + OS_API c_bool v_readerWalkEntries( v_reader _this, diff --git a/src/kernel/include/v_readerQos.h b/src/kernel/include/v_readerQos.h index 64214b53c..5c5906a1f 100644 --- a/src/kernel/include/v_readerQos.h +++ b/src/kernel/include/v_readerQos.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/include/v_readerSample.h b/src/kernel/include/v_readerSample.h index fbc1fa033..8eb012a4b 100644 --- a/src/kernel/include/v_readerSample.h +++ b/src/kernel/include/v_readerSample.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/include/v_rnr.h b/src/kernel/include/v_rnr.h index 18daf9cdd..b68c7e4f9 100644 --- a/src/kernel/include/v_rnr.h +++ b/src/kernel/include/v_rnr.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/include/v_rnrGroupStatistics.h b/src/kernel/include/v_rnrGroupStatistics.h index 479e5f0ce..6267a35ea 100644 --- a/src/kernel/include/v_rnrGroupStatistics.h +++ b/src/kernel/include/v_rnrGroupStatistics.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/include/v_rnrStatistics.h b/src/kernel/include/v_rnrStatistics.h index c42a3e10f..32c859783 100644 --- a/src/kernel/include/v_rnrStatistics.h +++ b/src/kernel/include/v_rnrStatistics.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/include/v_rnrStorageStatistics.h b/src/kernel/include/v_rnrStorageStatistics.h index 1dfd3d949..ea97d3444 100644 --- a/src/kernel/include/v_rnrStorageStatistics.h +++ b/src/kernel/include/v_rnrStorageStatistics.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/include/v_scheduler.h b/src/kernel/include/v_scheduler.h index bffe5682d..279de370e 100644 --- a/src/kernel/include/v_scheduler.h +++ b/src/kernel/include/v_scheduler.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/include/v_service.h b/src/kernel/include/v_service.h index 003219f02..7363e1f0b 100644 --- a/src/kernel/include/v_service.h +++ b/src/kernel/include/v_service.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -118,20 +119,6 @@ OS_API void v_serviceDeinit( v_service service); -/** - * \brief Returns the state of the service. - * - * Each service has a state, whose validity must be confirmed periodically. - * - * \param service the service object to operate on. - * - * \return a reference to the v_serviceState object of - * this service. - */ -OS_API v_serviceState -v_serviceGetState( - v_service service); - /** * \brief Returns the registered name of the service. * diff --git a/src/kernel/include/v_serviceManager.h b/src/kernel/include/v_serviceManager.h index cb9b77a79..e1da2179f 100644 --- a/src/kernel/include/v_serviceManager.h +++ b/src/kernel/include/v_serviceManager.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,7 +22,7 @@ * \file v_serviceManager.h * \brief * - * Currently the service manager is passes all requests to the garbage + * Currently the service manager is passes all requests to the garbage * collector. For A02 the lease mechanism will remain in the garbage collector, * while the service state management is moved to the service manager. */ @@ -54,17 +55,18 @@ extern "C" { /** * \brief The v_serviceManager constructor. - * + * * The constructor will create a new v_serviceManager object. * - * \param kernel the kernel + * \param kernel the kernel * - * \return NULL if memory allocation failed, otherwise a reference to a newly - * created v_serviceManager object. + * \return a reference to a newly created v_serviceManager object. */ +_Check_return_ +_Ret_notnull_ OS_API v_serviceManager v_serviceManagerNew( - v_kernel kernel); + _In_ v_kernel kernel); /** * \brief Retrieves the state kind of a given service. diff --git a/src/kernel/include/v_serviceState.h b/src/kernel/include/v_serviceState.h index b0d73325e..5a326b99f 100644 --- a/src/kernel/include/v_serviceState.h +++ b/src/kernel/include/v_serviceState.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -137,15 +138,6 @@ OS_API const c_char * v_serviceStateGetName( v_serviceState serviceState); -/** - * \todo remove this function and replace it in the garbage collector by - * a call to change the state. - */ -OS_API void -v_serviceStateNotify( - v_serviceState serviceState, - v_serviceStateKind kind); - #undef OS_API #if defined (__cplusplus) diff --git a/src/kernel/include/v_spliced.h b/src/kernel/include/v_spliced.h index 321feb573..f243ccf3f 100644 --- a/src/kernel/include/v_spliced.h +++ b/src/kernel/include/v_spliced.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -86,36 +87,6 @@ OS_API void v_splicedBuiltinCAndMCommandDispatcher( v_spliced spliced); -OS_API v_result -v_splicedGetMatchedSubscriptions( - v_spliced spliced, - v_writer w, - v_subscriptionInfo_action action, - c_voidp arg); - -OS_API v_result -v_splicedGetMatchedSubscriptionData( - v_spliced spliced, - v_writer w, - v_gid subscription, - v_subscriptionInfo_action action, - c_voidp arg); - -OS_API v_result -v_splicedGetMatchedPublications( - v_spliced spliced, - v_dataReader r, - v_publicationInfo_action action, - c_voidp arg); - -OS_API v_result -v_splicedGetMatchedPublicationData( - v_spliced spliced, - v_dataReader r, - v_gid publication, - v_publicationInfo_action action, - c_voidp arg); - /** * \brief Setup the durability client within spliced. * diff --git a/src/kernel/include/v_state.h b/src/kernel/include/v_state.h index 29559d7af..fa1438867 100644 --- a/src/kernel/include/v_state.h +++ b/src/kernel/include/v_state.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/include/v_statistics.h b/src/kernel/include/v_statistics.h index c9659b11b..d11b00014 100644 --- a/src/kernel/include/v_statistics.h +++ b/src/kernel/include/v_statistics.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/include/v_status.h b/src/kernel/include/v_status.h index 93e4c6d2b..c0abece5d 100644 --- a/src/kernel/include/v_status.h +++ b/src/kernel/include/v_status.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -62,7 +63,7 @@ OS_API void v_statusInit (v_status s, const c_char *name); OS_API void v_statusDeinit (v_status s); OS_API void v_statusReset (v_status s, c_ulong mask); -OS_API c_ulong v_statusGetMask (v_status s); +OS_API c_ulong v_statusGetMask (_In_ v_status s); #undef OS_API diff --git a/src/kernel/include/v_statusCondition.h b/src/kernel/include/v_statusCondition.h index f715f35ed..411c55603 100644 --- a/src/kernel/include/v_statusCondition.h +++ b/src/kernel/include/v_statusCondition.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/include/v_subscriber.h b/src/kernel/include/v_subscriber.h index 494c872d9..08948048a 100644 --- a/src/kernel/include/v_subscriber.h +++ b/src/kernel/include/v_subscriber.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -53,12 +54,13 @@ extern "C" { #define v_subscriberParticipant(_this) \ v_participant(_this->participant) +_Check_return_ +_Ret_maybenull_ OS_API v_subscriber v_subscriberNew( - v_participant participant, - const c_char *name, - v_subscriberQos qos, - c_bool enable); + _In_ v_participant participant, + _In_opt_z_ const c_char *name, + _In_opt_ v_subscriberQos qos); OS_API void v_subscriberFree( @@ -73,33 +75,24 @@ v_subscriberSetQos( v_subscriber _this, v_subscriberQos qos); -OS_API v_result -v_subscriberEnable( - v_subscriber _this); - OS_API void v_subscriberDeinit( v_subscriber _this); -OS_API void -v_subscriberSubscribe( - v_subscriber _this, - const c_char *partitionExpr); - OS_API c_iter v_subscriberLookupPartitions( v_subscriber _this, const c_char *partitionExpr); -OS_API c_bool -v_subscriberCheckPartitionInterest( - v_subscriber _this, - v_partition partition); - OS_API v_result v_subscriberAddReader( - v_subscriber _this, - v_reader reader); + _Inout_ v_subscriber _this, + _Inout_ v_reader reader); + +OS_API v_result +v_subscriberEnableReader( + _Inout_ v_subscriber s, + _Inout_ v_reader r); OS_API void v_subscriberRemoveReader( @@ -111,10 +104,6 @@ v_subscriberLookupReadersByTopic( v_subscriber _this, const c_char *topicName); -OS_API v_presentationKind -v_subscriberAccessScope( - v_subscriber _this); - OS_API v_result v_subscriberBeginAccess( v_subscriber _this); diff --git a/src/kernel/include/v_subscriberQos.h b/src/kernel/include/v_subscriberQos.h index 794630cb4..9961c0248 100644 --- a/src/kernel/include/v_subscriberQos.h +++ b/src/kernel/include/v_subscriberQos.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -44,18 +45,20 @@ extern "C" { */ #define v_subscriberQos(_this) (C_CAST(_this,v_subscriberQos)) +_Check_return_ +_When_(template, _Ret_maybenull_) OS_API v_subscriberQos v_subscriberQosNew( - v_kernel kernel, - v_subscriberQos template); - + _In_ v_kernel kernel, + _In_opt_ v_subscriberQos template); + OS_API void v_subscriberQosFree( - v_subscriberQos _this); + _In_opt_ _Post_invalid_ v_subscriberQos _this); OS_API v_result v_subscriberQosCheck( - v_subscriberQos _this); + _In_opt_ v_subscriberQos _this); #undef OS_API diff --git a/src/kernel/include/v_threadInfo.h b/src/kernel/include/v_threadInfo.h index 26465f197..49467fc78 100644 --- a/src/kernel/include/v_threadInfo.h +++ b/src/kernel/include/v_threadInfo.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,7 +28,7 @@ extern "C" { #endif #include "os_if.h" -#ifdef OSPL_BUILD_KERNEL +#ifdef OSPL_BUILD_CORE #define OS_API OS_API_EXPORT #else #define OS_API OS_API_IMPORT diff --git a/src/kernel/include/v_time.h b/src/kernel/include/v_time.h index c7c6767ee..22b9e0bcb 100644 --- a/src/kernel/include/v_time.h +++ b/src/kernel/include/v_time.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/include/v_timedValue.h b/src/kernel/include/v_timedValue.h index 7c9397be6..9bdc174f8 100644 --- a/src/kernel/include/v_timedValue.h +++ b/src/kernel/include/v_timedValue.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/include/v_topic.h b/src/kernel/include/v_topic.h index 3246ec89d..982993108 100644 --- a/src/kernel/include/v_topic.h +++ b/src/kernel/include/v_topic.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -54,6 +55,9 @@ extern "C" { #define v_topicIsAdapter(_this)\ (v_objectKind(_this) == K_TOPIC_ADAPTER) +#define v_topicMessageExtType(o) \ + (v_topicIsAdapter(o) ? v_topicAdapter(o)->topic->messageExtType : v_topicImpl(o)->messageExtType) + #define v_topicMessageType(o) \ (v_topicIsAdapter(o) ? v_topicAdapter(o)->topic->messageType : v_topicImpl(o)->messageType) @@ -83,10 +87,6 @@ OS_API void v_topicFree( v_topic _this); -OS_API v_result -v_topicEnable( - v_topic _this); - OS_API v_topicQos v_topicGetQos( v_topic _this); diff --git a/src/kernel/include/v_topicAdapter.h b/src/kernel/include/v_topicAdapter.h index 9d77392f1..d8ac575ce 100644 --- a/src/kernel/include/v_topicAdapter.h +++ b/src/kernel/include/v_topicAdapter.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/include/v_topicImpl.h b/src/kernel/include/v_topicImpl.h index decd6cb84..1ee8af98d 100644 --- a/src/kernel/include/v_topicImpl.h +++ b/src/kernel/include/v_topicImpl.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/include/v_topicQos.h b/src/kernel/include/v_topicQos.h index 5ffa54594..0937d19fc 100644 --- a/src/kernel/include/v_topicQos.h +++ b/src/kernel/include/v_topicQos.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/include/v_typeRepresentation.h b/src/kernel/include/v_typeRepresentation.h index de004142c..ddb51a2d2 100644 --- a/src/kernel/include/v_typeRepresentation.h +++ b/src/kernel/include/v_typeRepresentation.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/include/v_waitset.h b/src/kernel/include/v_waitset.h index 1250de115..a7f923051 100644 --- a/src/kernel/include/v_waitset.h +++ b/src/kernel/include/v_waitset.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -187,6 +188,11 @@ v_waitsetTrigger( v_waitset ws, c_voidp eventArg); +OS_API void +v_waitsetPrepareDestroy( + v_waitset _this, + c_voidp eventArg); + OS_API void v_waitsetLogEvents( v_waitset _this, diff --git a/src/kernel/include/v_writer.h b/src/kernel/include/v_writer.h index af9bcca07..ca3505bcd 100644 --- a/src/kernel/include/v_writer.h +++ b/src/kernel/include/v_writer.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,6 +26,7 @@ #include "v_publisher.h" #include "v_topic.h" #include "v_status.h" +#include "v_builtin.h" #if defined (__cplusplus) extern "C" { @@ -233,6 +235,33 @@ v_writerCoherentEnd ( c_ulong transactionId, c_array tidList); +/* This function is made public accessible only + * for the purpose to be used in design based testing. + */ +OS_API c_ulong +v_writerAllocSequenceNumber ( + v_writer _this); + +/* This operation will visit the kernel discovered subscriptions and invoke + * the given action routine on each available matching subscription message. + */ +OS_API v_result +v_writerReadMatchedSubscriptions( + v_writer _this, + v_subscriptionInfo_action action, + c_voidp arg); + +/* This operation will visit the kernel discovered subscriptions and lookup + * the subscription builtin info data identified by the given subscription gid and + * if found invoke the given action routine on the matching subscription message. + */ +OS_API v_result +v_writerReadMatchedSubscriptionData( + v_writer _this, + v_gid subscription, + v_subscriptionInfo_action action, + c_voidp arg); + #undef OS_API #if defined (__cplusplus) diff --git a/src/kernel/include/v_writerInstance.h b/src/kernel/include/v_writerInstance.h index b5245497d..17bf5dddb 100644 --- a/src/kernel/include/v_writerInstance.h +++ b/src/kernel/include/v_writerInstance.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/include/v_writerQos.h b/src/kernel/include/v_writerQos.h index 6a10801e5..744c1be8a 100644 --- a/src/kernel/include/v_writerQos.h +++ b/src/kernel/include/v_writerQos.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/kernel/include/v_writerStatistics.h b/src/kernel/include/v_writerStatistics.h index 46a5c3a7b..1bc2edca8 100644 --- a/src/kernel/include/v_writerStatistics.h +++ b/src/kernel/include/v_writerStatistics.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/osplcore/makefile.mak b/src/osplcore/makefile.mak index 380801dc5..7efd8c10f 100644 --- a/src/osplcore/makefile.mak +++ b/src/osplcore/makefile.mak @@ -69,9 +69,6 @@ ifneq "$(ABSTR_HOME)" "$(OSPL_HOME)/src/abstraction" endif CPPFLAGS += -DOSPL_BUILD_CORE -DMODEL_kernelModule_IMPLEMENTATION -DMODEL_kernelModuleI_IMPLEMENTATION -ifneq "$(OSPL_OUTER_HOME)" "" - CPPFLAGS += -DUSE_ADV_MEM_MNG -endif ifneq "$(findstring yes, $(INCLUDE_PLUGGABLE_REPORTING))" "" CPPFLAGS += -DINCLUDE_PLUGGABLE_REPORTING endif @@ -91,18 +88,13 @@ endif CFLAGS += $(CFLAGS_XSTRICT) $(CFLAGS_W_ERROR) ut_snappy$O c_odlbase$O q_parser$O v_parser$O: \ CFLAGS := $(filter-out $(CFLAGS_XSTRICT), $(CFLAGS)) -os_cond$O os_report$O os_time$O os_time_monotonic$O os_socket$O \ - os_sharedmem$O ut_snappy$O c_odlbase$O q_parser$O v_parser$O \ - u_cfData$O u_cfValue$O: \ +c_odlbase$O q_parser$O v_parser$O: \ CFLAGS := $(filter-out $(CFLAGS_W_ERROR), $(CFLAGS)) ut_snappy$O: \ CFLAGS += $(CFLAGS_PERMISSIVE) ODLPP_PATH := $(OSPL_HOME)/src/database/odlpp ST1_PATH := $(ABSTR_PATH) $(ST1_MODULES:%=$(OSPL_HOME)/src/%) -ifneq "$(OSPL_OUTER_HOME)" "" - ST1_PATH += $(OSPL_OUTER_HOME)/src/database/database -endif vpath %.c $(addsuffix /code, $(ST1_PATH) $(ODLPP_PATH)) vpath %.l $(addsuffix /code, $(ST1_PATH) $(ODLPP_PATH)) vpath %.y $(addsuffix /code, $(ST1_PATH) $(ODLPP_PATH)) diff --git a/src/services/cmagent/code/cma__configuration.h b/src/services/cmagent/code/cma__configuration.h index d60748fbd..453a8223b 100644 --- a/src/services/cmagent/code/cma__configuration.h +++ b/src/services/cmagent/code/cma__configuration.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/services/cmagent/code/cma__log.h b/src/services/cmagent/code/cma__log.h index 90d33fcc5..9f110a8ea 100644 --- a/src/services/cmagent/code/cma__log.h +++ b/src/services/cmagent/code/cma__log.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -93,26 +94,26 @@ cma_trace( #define CMA_INFO(context, ...) \ do { \ cma_log(LOG_INFO, __VA_ARGS__); \ - os_report(OS_INFO, context, __FILE__, __LINE__, 0, __VA_ARGS__); \ + OS_REPORT(OS_INFO, context, 0, __VA_ARGS__); \ } while (0) /* CMA_WARNING: log to trace log as LL_WARNING and to OpenSplice log as OS_WARNING */ #define CMA_WARNING(context, ...) \ do { \ cma_log(LOG_WARNING, __VA_ARGS__); \ - os_report(OS_WARNING, context, __FILE__, __LINE__, 0, __VA_ARGS__); \ + OS_REPORT(OS_WARNING, context, 0, __VA_ARGS__); \ } while (0) #define CMA_ERROR(context, ...) \ do { \ cma_log(LOG_ERROR, __VA_ARGS__); \ - os_report(OS_ERROR, context, __FILE__, __LINE__, 0, __VA_ARGS__); \ + OS_REPORT(OS_ERROR, context, 0, __VA_ARGS__); \ } while (0) #define CMA_FATAL(context, ...) \ do { \ cma_log(LOG_FATAL, __VA_ARGS__); \ - os_report(OS_FATAL, context, __FILE__, __LINE__, 0, __VA_ARGS__); \ + OS_REPORT(OS_FATAL, context, 0, __VA_ARGS__); \ } while (0) #endif /* CMA__LOG_H_ */ diff --git a/src/services/cmagent/code/cma__object.h b/src/services/cmagent/code/cma__object.h index 2d34ca527..09a90a93b 100644 --- a/src/services/cmagent/code/cma__object.h +++ b/src/services/cmagent/code/cma__object.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/services/cmagent/code/cma__service.h b/src/services/cmagent/code/cma__service.h index f6faf33c7..9a337b5ca 100644 --- a/src/services/cmagent/code/cma__service.h +++ b/src/services/cmagent/code/cma__service.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/services/cmagent/code/cma__thread.h b/src/services/cmagent/code/cma__thread.h index 627ae5f57..341f44d3a 100644 --- a/src/services/cmagent/code/cma__thread.h +++ b/src/services/cmagent/code/cma__thread.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/services/cmagent/code/cma__types.h b/src/services/cmagent/code/cma__types.h index 3ffa71df6..aba7a87ad 100644 --- a/src/services/cmagent/code/cma__types.h +++ b/src/services/cmagent/code/cma__types.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/services/cmagent/code/cma__util.h b/src/services/cmagent/code/cma__util.h index 874eab607..d7dd915bf 100644 --- a/src/services/cmagent/code/cma__util.h +++ b/src/services/cmagent/code/cma__util.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/services/cmagent/code/cma_configuration.c b/src/services/cmagent/code/cma_configuration.c index 789c41d97..8e3ecf27b 100644 --- a/src/services/cmagent/code/cma_configuration.c +++ b/src/services/cmagent/code/cma_configuration.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -1214,7 +1215,7 @@ static int cfgst_node_cmp (const void *va, const void *vb) return memcmp (va, vb, sizeof (struct cfgst_nodekey)); } -struct cfgst * config_init(u_participant participant, const char *servicename, cma_configuration config) +static struct cfgst * cma_config_init(u_participant participant, const char *servicename, cma_configuration config) { /* pre: all parameters in config should be 0 */ int ok = 1; @@ -1235,7 +1236,7 @@ struct cfgst * config_init(u_participant participant, const char *servicename, c if ((root = u_participantGetConfiguration ((u_participant) participant)) == NULL) { - CMA_ERROR ("cmagent_config", "config_init: u_participantGetConfiguration failed"); + CMA_ERROR ("cmagent_config", "cma_config_init: u_participantGetConfiguration failed"); ut_avlFree (&cfgst_found_treedef, &cfgst->found, os_free); os_free (cfgst); return NULL; @@ -1313,7 +1314,7 @@ struct cfgst * config_init(u_participant participant, const char *servicename, c } } -void config_print_and_free_cfgst (struct cfgst *cfgst) +static void cma_config_print_and_free_cfgst (struct cfgst *cfgst) { if (cfgst == NULL) return; @@ -1322,7 +1323,7 @@ void config_print_and_free_cfgst (struct cfgst *cfgst) os_free (cfgst); } -void config_fini (cma_configuration config) +static void cma_config_fini (cma_configuration config) { if (config->valid) { @@ -1353,7 +1354,7 @@ cma_configurationNew( _this->participant = cma_serviceParticipant(service); _this->serviceName = cma_serviceName(service); /* weak ref, cma_service outlives cma_configuration */ - _this->cfgst = config_init(_this->participant, _this->serviceName, _this); + _this->cfgst = cma_config_init(_this->participant, _this->serviceName, _this); if (!_this->cfgst) { os_free(_this); return NULL; @@ -1369,6 +1370,7 @@ cma__configurationDeinit( assert(_this); /* TODO deinit config */ + cma_config_fini (_this); cma__objectDeinit(cma_object(_this)); } @@ -1377,7 +1379,7 @@ void cma_configurationPrint( cma_configuration _this) { - config_print_and_free_cfgst(_this->cfgst); + cma_config_print_and_free_cfgst(_this->cfgst); _this->cfgst = NULL; } diff --git a/src/services/cmagent/code/cma_log.c b/src/services/cmagent/code/cma_log.c index ebaef91c4..0ef2e0f4e 100644 --- a/src/services/cmagent/code/cma_log.c +++ b/src/services/cmagent/code/cma_log.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,9 +25,10 @@ #include "vortex_os.h" #include "os_report.h" +#define DATE_SIZE (OS_CTIME_R_BUFSIZE) #define MAX_TIMESTAMP_LENGTH (10 + 1 + 6) #define MAX_TID_LENGTH (15) -#define MAX_HDR_LENGTH (MAX_TIMESTAMP_LENGTH + 1 + MAX_TID_LENGTH + 2) +#define MAX_HDR_LENGTH (DATE_SIZE + 1 + MAX_TIMESTAMP_LENGTH + 1 + MAX_TID_LENGTH + 2) #define BUF_OFFSET MAX_HDR_LENGTH @@ -82,16 +84,21 @@ cma__logbufFlushReal( if (gc->tracing.file) { char hdr[MAX_HDR_LENGTH + 1]; + char date[DATE_SIZE]; int n, tsec, tusec; + os_timeW time; if (_this->tstamp < 0) { _this->tstamp = cma_timeNow(); } cma_time_sec_usec_conv(_this->tstamp, &tsec, &tusec); + OS_TIMEW_SET_VALUE(time, _this->tstamp); + os_ctimeW_r(&time, date, DATE_SIZE); + _this->tstamp = -1; - n = snprintf(hdr, sizeof(hdr), "%d.%06d/%*.*s: ", - tsec, tusec, MAX_TID_LENGTH, MAX_TID_LENGTH, cma_threadName(self)); + n = snprintf(hdr, sizeof(hdr), "%s %d.%06d/%*.*s: ", + date, tsec, tusec, MAX_TID_LENGTH, MAX_TID_LENGTH, cma_threadName(self)); assert(n > 0 && n <= BUF_OFFSET); memcpy(_this->buf + BUF_OFFSET - (size_t)n, hdr, (size_t)n); (void)fwrite(_this->buf + BUF_OFFSET - (size_t)n, 1, _this->pos - BUF_OFFSET + (size_t)n, gc->tracing.file); diff --git a/src/services/cmagent/code/cma_object.c b/src/services/cmagent/code/cma_object.c index 7f1d0beeb..cc64fe6d9 100644 --- a/src/services/cmagent/code/cma_object.c +++ b/src/services/cmagent/code/cma_object.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/services/cmagent/code/cma_service.c b/src/services/cmagent/code/cma_service.c index 6a5f16ed3..a401932db 100644 --- a/src/services/cmagent/code/cma_service.c +++ b/src/services/cmagent/code/cma_service.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -65,13 +66,14 @@ cma__serviceMain( static os_result cma__exceptionHandler( - os_callbackArg cbArg, - void *arg) __nonnull_all__; + void *callingThreadContext, + void *arg); static os_result cma__exitRequestHandler( os_callbackArg cbArg, - void *arg) __nonnull_all__; + void *callingThreadContext, + void *arg); static c_bool cma__serviceChangeState( @@ -240,8 +242,8 @@ cma__serviceNew( } if (!os_serviceGetSingleProcess()) { - _this->erh = os_signalHandlerRegisterExitRequestCallback(cma__exitRequestHandler, _this); - _this->eh = os_signalHandlerRegisterExceptionCallback(cma__exceptionHandler, _this); + _this->erh = os_signalHandlerRegisterExitRequestCallback(cma__exitRequestHandler, NULL, NULL, NULL, _this); + _this->eh = os_signalHandlerRegisterExceptionCallback(cma__exceptionHandler, NULL, NULL, NULL, _this); } else { _this->erh = os_signalHandlerExitRequestHandleNil; _this->eh = os_signalHandlerExceptionHandleNil; @@ -271,7 +273,7 @@ cma__serviceNew( " (OpenSplice " OSPL_VERSION_STR ", build " OSPL_INNER_REV_STR "/" OSPL_OUTER_REV_STR ")\n"); #else cma_log(LOG_INFO, "Started Control and Monitoring Agent service" - " (OpenSplice " OSPL_VERSION_STR ", non-PrismTech build)\n"); + " (OpenSplice " OSPL_VERSION_STR ", non-ADLINK build)\n"); #endif /* defined(OSPL_INNER_REV) && defined(OSPL_OUTER_REV) */ cma_configurationPrint(_this->config); @@ -416,11 +418,13 @@ cma__serviceMain( static os_result cma__exitRequestHandler( os_callbackArg cbArg, + void *callingThreadContext, void *arg) { cma_service _this = cma_service(arg); OS_UNUSED_ARG(cbArg); + OS_UNUSED_ARG(callingThreadContext); assert(_this); @@ -432,12 +436,12 @@ cma__exitRequestHandler( static os_result cma__exceptionHandler( - os_callbackArg cbArg, + void *callingThreadContext, void *arg) { cma_service _this = cma_service(arg); - OS_UNUSED_ARG(cbArg); + OS_UNUSED_ARG(callingThreadContext); assert(_this); (void)cma__serviceChangeState(_this, STATE_DIED); diff --git a/src/services/cmagent/code/cma_thread.c b/src/services/cmagent/code/cma_thread.c index dfafcdb60..afd33df75 100644 --- a/src/services/cmagent/code/cma_thread.c +++ b/src/services/cmagent/code/cma_thread.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/services/cmagent/code/cma_util.c b/src/services/cmagent/code/cma_util.c index 074d277f4..43aca00c6 100644 --- a/src/services/cmagent/code/cma_util.c +++ b/src/services/cmagent/code/cma_util.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/services/cmagent/include/cma_service.h b/src/services/cmagent/include/cma_service.h index e9816823c..1e738c101 100644 --- a/src/services/cmagent/include/cma_service.h +++ b/src/services/cmagent/include/cma_service.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/services/cmsoap/code/cms__soap.h b/src/services/cmsoap/code/cms__soap.h index fbc5cdc25..4abc0ac19 100644 --- a/src/services/cmsoap/code/cms__soap.h +++ b/src/services/cmsoap/code/cms__soap.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/services/cmsoap/code/cms__thread.h b/src/services/cmsoap/code/cms__thread.h index 863875ce4..1fa1bfbca 100644 --- a/src/services/cmsoap/code/cms__thread.h +++ b/src/services/cmsoap/code/cms__thread.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -39,7 +40,7 @@ extern "C" { * @param thread The thread to initialize. * @param name The name for the thread. */ -void cms_threadInit (cms_thread thread, const c_char* name, os_threadAttr * attr); +c_bool cms_threadInit (cms_thread thread, const c_char* name, os_threadAttr * attr); /** * Deinitializes the supplied thread. diff --git a/src/services/cmsoap/code/cms__typebase.h b/src/services/cmsoap/code/cms__typebase.h index f42cbe75e..d740a9af4 100644 --- a/src/services/cmsoap/code/cms__typebase.h +++ b/src/services/cmsoap/code/cms__typebase.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/services/cmsoap/code/cms_client.c b/src/services/cmsoap/code/cms_client.c index 517f5773a..f529c8871 100644 --- a/src/services/cmsoap/code/cms_client.c +++ b/src/services/cmsoap/code/cms_client.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -84,36 +85,40 @@ cms_clientNew( os_result osr; client = os_malloc(sizeof *client); - cms_threadInit(cms_thread(client), "cms_client", &service->configuration->clientScheduling); if(client != NULL){ - cms_object(client)->kind = CMS_CLIENT; - cms_thread(client)->did = service->did; - cms_thread(client)->uri = os_strdup(service->uri); - client->ip = ip; - client->initCount = 0; - client->service = service; - client->internalFree = FALSE; - osr = os_mutexInit(&client->soapMutex, NULL); - client->soapEnvs = c_iterNew(NULL); - - if(osr == os_resultSuccess){ - osr = os_mutexInit(&client->conditionMutex, NULL); + if (cms_threadInit(cms_thread(client), "cms_client", &service->configuration->clientScheduling)) { + cms_object(client)->kind = CMS_CLIENT; + cms_thread(client)->did = service->did; + cms_thread(client)->uri = os_strdup(service->uri); + client->ip = ip; + client->initCount = 0; + client->service = service; + client->internalFree = FALSE; + osr = os_mutexInit(&client->soapMutex, NULL); + client->soapEnvs = c_iterNew(NULL); + if(osr == os_resultSuccess){ - osr = os_condInit(&client->condition, &client->conditionMutex, NULL ); + osr = os_mutexInit(&client->conditionMutex, NULL); if(osr == os_resultSuccess){ - osr = os_mutexInit(&client->threadMutex, NULL); - + osr = os_condInit(&client->condition, &client->conditionMutex, NULL ); if(osr == os_resultSuccess){ - client->threads = c_iterNew(NULL); - } else { - cms_clientFree(client); + osr = os_mutexInit(&client->threadMutex, NULL); + + if(osr == os_resultSuccess){ + client->threads = c_iterNew(NULL); + } else { + cms_clientFree(client); + } } + } else { + cms_clientFree(client); } } else { cms_clientFree(client); } } else { cms_clientFree(client); + client = NULL; } } @@ -330,7 +335,7 @@ cms_clientRun( } found = TRUE; } else { - os_sleep(OS_DURATION_MICROSECOND); + ospl_os_sleep(OS_DURATION_MICROSECOND); } } else { cms_soapThreadHandleRequest(soapThread, soap); diff --git a/src/services/cmsoap/code/cms_configuration.c b/src/services/cmsoap/code/cms_configuration.c index a46fd2d93..444feabd5 100644 --- a/src/services/cmsoap/code/cms_configuration.c +++ b/src/services/cmsoap/code/cms_configuration.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/services/cmsoap/code/cms_service.c b/src/services/cmsoap/code/cms_service.c index 7f03543d5..0dbba5baa 100644 --- a/src/services/cmsoap/code/cms_service.c +++ b/src/services/cmsoap/code/cms_service.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -41,6 +42,8 @@ #include "os_report.h" #include "v_qos.h" #include "os_stdlib.h" +#include "u_domain.h" +#include "u_participantQos.h" #define CMSERVICE_ATTACH_TIMEOUT 30 diff --git a/src/services/cmsoap/code/cms_soap2.c b/src/services/cmsoap/code/cms_soap2.c index 1e7953337..c87973506 100644 --- a/src/services/cmsoap/code/cms_soap2.c +++ b/src/services/cmsoap/code/cms_soap2.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/services/cmsoap/code/cms_soapThread.c b/src/services/cmsoap/code/cms_soapThread.c index f385560f4..359a6b81f 100644 --- a/src/services/cmsoap/code/cms_soapThread.c +++ b/src/services/cmsoap/code/cms_soapThread.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -62,16 +63,17 @@ cms_soapThreadNew( thread = cms_soapThread(os_malloc(C_SIZEOF(cms_soapThread))); if (thread != NULL) { cms_object(thread)->kind = CMS_SOAPTHREAD; - cms_threadInit(cms_thread(thread), name, &client->service->configuration->clientScheduling); - cms_thread(thread)->did = cms_thread(client)->did; - cms_thread(thread)->uri = os_strdup(cms_thread(client)->uri); - thread->client = client; - thread->soap = NULL; - - osr = os_mutexInit(&thread->soapMutex, NULL); - if(osr == os_resultSuccess){ - osr = os_condInit(&thread->condition, &thread->soapMutex, NULL); - } + if (cms_threadInit(cms_thread(thread), name, &client->service->configuration->clientScheduling)) { + cms_thread(thread)->did = cms_thread(client)->did; + cms_thread(thread)->uri = os_strdup(cms_thread(client)->uri); + thread->client = client; + thread->soap = NULL; + + osr = os_mutexInit(&thread->soapMutex, NULL); + if(osr == os_resultSuccess){ + osr = os_condInit(&thread->condition, &thread->soapMutex, NULL); + } + } } } diff --git a/src/services/cmsoap/code/cms_thread.c b/src/services/cmsoap/code/cms_thread.c index 16974eb2d..b689f7243 100644 --- a/src/services/cmsoap/code/cms_thread.c +++ b/src/services/cmsoap/code/cms_thread.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -32,16 +33,20 @@ cms_threadNew( cms_thread thread; thread = os_malloc(sizeof *thread); cms_object(thread)->kind = CMS_THREAD; - cms_threadInit(thread, name, attr); + if (!cms_threadInit(thread, name, attr)){ + os_free(thread); + thread = NULL; + } return thread; } -void +c_bool cms_threadInit( cms_thread thread, const c_char* name, os_threadAttr * attr) { + c_bool retValue = FALSE; if(thread != NULL){ if(name != NULL){ thread->ready = TRUE; @@ -50,20 +55,19 @@ cms_threadInit( thread->name = name; thread->did.id[0] = '\0'; thread->uri = NULL; - + retValue = TRUE; if (attr != NULL) { thread->attr = *attr; } else { os_threadAttrInit(&thread->attr); } } else { - os_free(thread); - thread = NULL; OS_REPORT(OS_ERROR, CMS_CONTEXT, 0, "cms_threadInit failed. (no name supplied)"); } } else { OS_REPORT(OS_ERROR, CMS_CONTEXT, 0, "cms_threadInit failed."); } + return (retValue); } void diff --git a/src/services/cmsoap/code/cmsoap.c b/src/services/cmsoap/code/cmsoap.c index 74a8b2720..f2697d259 100644 --- a/src/services/cmsoap/code/cmsoap.c +++ b/src/services/cmsoap/code/cmsoap.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -54,22 +55,25 @@ /*static cms_uri_cache uri_cache = NULL;*/ -static void cmsoapAtExit(u_service service, void *privateData); - static os_result exitRequestHandler( os_callbackArg ignore, + void *callingThreadContext, void * arg) { cms_service cms = (cms_service)arg; + OS_UNUSED_ARG(callingThreadContext); OS_UNUSED_ARG(ignore); + assert(cms); /* Terminate cmsoap */ cms->terminate = TRUE; - return os_resultFail; /* Don't invoke further handlers; main thread will take care of termination. */ + OS_REPORT(OS_INFO, "CMSoap Exit Handler", 0, "Initiated CMSoap Service termination..."); + + return os_resultSuccess; } @@ -93,13 +97,9 @@ OPENSPLICE_SERVICE_ENTRYPOINT (ospl_cmsoap, cmsoap) if(cms != NULL){ os_signalHandlerExitRequestHandle erh = os_signalHandlerExitRequestHandleNil; - if (u_serviceAtExit(cms->uservice, cmsoapAtExit, cms) != U_RESULT_OK) { - OS_REPORT(OS_ERROR, CMS_CONTEXT, 0, - "Could not register atExit."); - cms->terminate = TRUE; - } + if(!os_serviceGetSingleProcess()){ - erh = os_signalHandlerRegisterExitRequestCallback(exitRequestHandler, cms); + erh = os_signalHandlerRegisterExitRequestCallback(exitRequestHandler, NULL, NULL, NULL, cms); } while(cms->terminate == FALSE){ @@ -189,16 +189,6 @@ OPENSPLICE_SERVICE_ENTRYPOINT (ospl_cmsoap, cmsoap) return 0; } -static void -cmsoapAtExit( - u_service service, - void *privateData) -{ - cms_service cms = cms_service(privateData); - OS_UNUSED_ARG(service); - cms->terminate = TRUE; -} - static c_bool validateInitialization( struct soap *soap) diff --git a/src/services/cmsoap/include/cms_client.h b/src/services/cmsoap/include/cms_client.h index d04ed3a51..bb52d1bfa 100644 --- a/src/services/cmsoap/include/cms_client.h +++ b/src/services/cmsoap/include/cms_client.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/services/cmsoap/include/cms_configuration.h b/src/services/cmsoap/include/cms_configuration.h index ba9c18773..9d0c51ae2 100644 --- a/src/services/cmsoap/include/cms_configuration.h +++ b/src/services/cmsoap/include/cms_configuration.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/services/cmsoap/include/cms_service.h b/src/services/cmsoap/include/cms_service.h index df8a5686a..91cb97ea6 100644 --- a/src/services/cmsoap/include/cms_service.h +++ b/src/services/cmsoap/include/cms_service.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/services/cmsoap/include/cms_soapThread.h b/src/services/cmsoap/include/cms_soapThread.h index 348c9c427..b8299ac5c 100644 --- a/src/services/cmsoap/include/cms_soapThread.h +++ b/src/services/cmsoap/include/cms_soapThread.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/services/cmsoap/include/cms_thread.h b/src/services/cmsoap/include/cms_thread.h index 675bd0116..554812bab 100644 --- a/src/services/cmsoap/include/cms_thread.h +++ b/src/services/cmsoap/include/cms_thread.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/services/cmsoap/include/cmsoap.h b/src/services/cmsoap/include/cmsoap.h index 1f93a3e73..f540a1f5f 100644 --- a/src/services/cmsoap/include/cmsoap.h +++ b/src/services/cmsoap/include/cmsoap.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/services/cmsoap/makefile.mak b/src/services/cmsoap/makefile.mak index 5a9aa8667..31ce97ea9 100644 --- a/src/services/cmsoap/makefile.mak +++ b/src/services/cmsoap/makefile.mak @@ -38,6 +38,7 @@ CPPFLAGS += -DOSPL_BUILD_CMSOAP CPPFLAGS += -DWITH_FAST CFLAGS += $(SHCFLAGS) CFLAGS += $(CFLAGS_XSTRICT) +CFLAGS += $(CFLAGS_W_ERROR) stdsoap2$(OBJ_POSTFIX) soapC$(OBJ_POSTFIX): CFLAGS := $(filter-out $(CFLAGS_XSTRICT), $(CFLAGS)) $(CFLAGS_PERMISSIVE) diff --git a/src/services/ddsi2/code/ddsi_ssl.h b/src/services/ddsi2/code/ddsi_ssl.h deleted file mode 100644 index 35785a308..000000000 --- a/src/services/ddsi2/code/ddsi_ssl.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * OpenSplice DDS - * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -#ifndef _DDSI_SSL_H_ -#define _DDSI_SSL_H_ - -#ifdef DDSI_INCLUDE_SSL - -#ifdef _WIN32 -/* WinSock2 must be included before openssl headers - otherwise winsock will be used */ -#include -#endif - -#include - -void ddsi_ssl_plugin (void); - -#endif -#endif - -/* SHA1 not available (unoffical build.) */ diff --git a/src/services/ddsi2/code/ddsi_tcp.h b/src/services/ddsi2/code/ddsi_tcp.h deleted file mode 100644 index 62ec83a04..000000000 --- a/src/services/ddsi2/code/ddsi_tcp.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * OpenSplice DDS - * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -#ifndef _DDSI_TCP_H_ -#define _DDSI_TCP_H_ - -#include "ddsi_tran.h" - -#ifdef DDSI_INCLUDE_SSL - -#include "ddsi_ssl.h" - -struct ddsi_ssl_plugins -{ - void (*config) (void); - c_bool (*init) (void); - void (*fini) (void); - void (*ssl_free) (SSL * ssl); - void (*bio_vfree) (BIO * bio); - os_ssize_t (*read) (SSL * ssl, void * buf, os_size_t len, int * err); - os_ssize_t (*write) (SSL * ssl, const void * msg, os_size_t len, int * err); - SSL * (*connect) (os_socket sock); - BIO * (*listen) (os_socket sock); - SSL * (*accept) (BIO * bio, os_socket * sock); -}; - -struct ddsi_ssl_plugins ddsi_tcp_ssl_plugin; - -#endif - -int ddsi_tcp_init (void); - -#endif - -/* SHA1 not available (unoffical build.) */ diff --git a/src/services/ddsi2/code/ddsi_udp.h b/src/services/ddsi2/code/ddsi_udp.h deleted file mode 100644 index eace5f8fc..000000000 --- a/src/services/ddsi2/code/ddsi_udp.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * OpenSplice DDS - * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -#ifndef _DDSI_UDP_H_ -#define _DDSI_UDP_H_ - -int ddsi_udp_init (void); - -#endif - -/* SHA1 not available (unoffical build.) */ diff --git a/src/services/ddsi2/code/q_addrset.h b/src/services/ddsi2/code/q_addrset.h deleted file mode 100644 index 32affbb34..000000000 --- a/src/services/ddsi2/code/q_addrset.h +++ /dev/null @@ -1,93 +0,0 @@ -/* - * OpenSplice DDS - * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -#ifndef NN_ADDRSET_H -#define NN_ADDRSET_H - -#include "os_mutex.h" -#include "os_socket.h" - -#include "ut_avl.h" -#include "q_log.h" -#include "q_protocol.h" -#include "q_feature_check.h" - -#if defined (__cplusplus) -extern "C" { -#endif - -typedef struct addrset_node { - ut_avlNode_t avlnode; - nn_locator_t loc; -} * addrset_node_t; - -struct addrset { - os_mutex lock; - pa_uint32_t refc; - ut_avlCTree_t ucaddrs, mcaddrs; -}; - -typedef void (*addrset_forall_fun_t) (const nn_locator_t *loc, void *arg); -typedef os_ssize_t (*addrset_forone_fun_t) (const nn_locator_t *loc, void *arg); - -struct addrset *new_addrset (void); -struct addrset *ref_addrset (struct addrset *as); -void unref_addrset (struct addrset *as); -void add_to_addrset (struct addrset *as, const nn_locator_t *loc); -void remove_from_addrset (struct addrset *as, const nn_locator_t *loc); -int addrset_purge (struct addrset *as); -int compare_locators (const nn_locator_t *a, const nn_locator_t *b); - -/* These lock ASADD, then lock/unlock AS any number of times, then - unlock ASADD */ -void copy_addrset_into_addrset_uc (struct addrset *as, const struct addrset *asadd); -void copy_addrset_into_addrset_mc (struct addrset *as, const struct addrset *asadd); -void copy_addrset_into_addrset (struct addrset *as, const struct addrset *asadd); - -os_size_t addrset_count (const struct addrset *as); -os_size_t addrset_count_uc (const struct addrset *as); -int addrset_empty_uc (const struct addrset *as); -int addrset_empty_mc (const struct addrset *as); -int addrset_empty (const struct addrset *as); -int addrset_any_uc (const struct addrset *as, nn_locator_t *dst); -int addrset_any_mc (const struct addrset *as, nn_locator_t *dst); - -/* Keeps AS locked */ -int addrset_forone (struct addrset *as, addrset_forone_fun_t f, void *arg); -void addrset_forall (struct addrset *as, addrset_forall_fun_t f, void *arg); -os_size_t addrset_forall_count (struct addrset *as, addrset_forall_fun_t f, void *arg); -void nn_log_addrset (logcat_t tf, const char *prefix, const struct addrset *as); - -/* Tries to lock A then B for a decent check, returning false if - trylock B fails */ -int addrset_eq_onesidederr (const struct addrset *a, const struct addrset *b); - -int is_mcaddr (const nn_locator_t *loc); -int is_unspec_locator (const nn_locator_t *loc); -void set_unspec_locator (nn_locator_t *loc); - -int add_addresses_to_addrset (struct addrset *as, const char *addrs, int port_mode, const char *msgtag, int req_mc); - - -#if defined (__cplusplus) -} -#endif -#endif /* NN_ADDRSET_H */ - -/* SHA1 not available (unoffical build.) */ diff --git a/src/services/ddsi2/code/q_align.h b/src/services/ddsi2/code/q_align.h deleted file mode 100644 index f99755354..000000000 --- a/src/services/ddsi2/code/q_align.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * OpenSplice DDS - * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -#ifndef NN_ALIGN_H -#define NN_ALIGN_H - -#define ALIGN4(x) (((x) + 3) & -4u) -#define ALIGN8(x) (((x) + 7) & -8u) - -#endif /* NN_ALIGN_H */ - -/* SHA1 not available (unoffical build.) */ diff --git a/src/services/ddsi2/code/q_bitset.h b/src/services/ddsi2/code/q_bitset.h deleted file mode 100644 index d9eae6deb..000000000 --- a/src/services/ddsi2/code/q_bitset.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * OpenSplice DDS - * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -#ifndef NN_BITSET_H -#define NN_BITSET_H - -#include -#include - -#include "q_inline.h" - -#if NN_HAVE_C99_INLINE && !defined SUPPRESS_BITSET_INLINES -#include "q_bitset_template.c" -#else -#if defined (__cplusplus) -extern "C" { -#endif -int nn_bitset_isset (unsigned numbits, const unsigned *bits, unsigned idx); -void nn_bitset_set (unsigned numbits, unsigned *bits, unsigned idx); -void nn_bitset_clear (unsigned numbits, unsigned *bits, unsigned idx); -void nn_bitset_zero (unsigned numbits, unsigned *bits); -void nn_bitset_one (unsigned numbits, unsigned *bits); -#if defined (__cplusplus) -} -#endif -#endif - -#endif /* NN_BITSET_H */ - -/* SHA1 not available (unoffical build.) */ diff --git a/src/services/ddsi2/code/q_bitset_inlines.c b/src/services/ddsi2/code/q_bitset_inlines.c deleted file mode 100644 index 86d473cba..000000000 --- a/src/services/ddsi2/code/q_bitset_inlines.c +++ /dev/null @@ -1,26 +0,0 @@ -/* - * OpenSplice DDS - * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -#define SUPPRESS_BITSET_INLINES - -#include "q_bitset.h" -#include "q_bitset_template.c" - - -/* SHA1 not available (unoffical build.) */ diff --git a/src/services/ddsi2/code/q_bitset_template.c b/src/services/ddsi2/code/q_bitset_template.c deleted file mode 100644 index fb5a9e6f1..000000000 --- a/src/services/ddsi2/code/q_bitset_template.c +++ /dev/null @@ -1,63 +0,0 @@ -/* - * OpenSplice DDS - * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -/* -*- c -*- */ - -#include "q_unused.h" - -#if defined SUPPRESS_BITSET_INLINES && defined NN_C99_INLINE -#undef NN_C99_INLINE -#define NN_C99_INLINE -#endif - -NN_C99_INLINE int nn_bitset_isset (unsigned numbits, const unsigned *bits, unsigned idx) -{ - return idx < numbits && (bits[idx/32] & (1u << (31 - (idx%32)))); -} - -NN_C99_INLINE void nn_bitset_set (UNUSED_ARG_NDEBUG (unsigned numbits), unsigned *bits, unsigned idx) -{ - assert (idx < numbits); - bits[idx/32] |= 1u << (31 - (idx%32)); -} - -NN_C99_INLINE void nn_bitset_clear (UNUSED_ARG_NDEBUG (unsigned numbits), unsigned *bits, unsigned idx) -{ - assert (idx < numbits); - bits[idx/32] &= ~(1u << (31 - (idx%32))); -} - -NN_C99_INLINE void nn_bitset_zero (unsigned numbits, unsigned *bits) -{ - memset (bits, 0, 4 * ((numbits + 31) / 32)); -} - -NN_C99_INLINE void nn_bitset_one (unsigned numbits, unsigned *bits) -{ - memset (bits, 0xff, 4 * ((numbits + 31) / 32)); - - /* clear bits "accidentally" set */ - { - const unsigned k = numbits / 32; - const unsigned n = numbits % 32; - bits[k] &= ~(~0u >> n); - } -} - -/* SHA1 not available (unoffical build.) */ diff --git a/src/services/ddsi2/code/q_bswap.c b/src/services/ddsi2/code/q_bswap.c deleted file mode 100644 index 175ca5669..000000000 --- a/src/services/ddsi2/code/q_bswap.c +++ /dev/null @@ -1,90 +0,0 @@ -/* - * OpenSplice DDS - * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -#include "q_bswap.h" - -nn_guid_prefix_t nn_hton_guid_prefix (nn_guid_prefix_t p) -{ - int i; - for (i = 0; i < 3; i++) - p.u[i] = toBE4u (p.u[i]); - return p; -} - -nn_guid_prefix_t nn_ntoh_guid_prefix (nn_guid_prefix_t p) -{ - int i; - for (i = 0; i < 3; i++) - p.u[i] = fromBE4u (p.u[i]); - return p; -} - -nn_entityid_t nn_hton_entityid (nn_entityid_t e) -{ - e.u = toBE4u (e.u); - return e; -} - -nn_entityid_t nn_ntoh_entityid (nn_entityid_t e) -{ - e.u = fromBE4u (e.u); - return e; -} - -nn_guid_t nn_hton_guid (nn_guid_t g) -{ - g.prefix = nn_hton_guid_prefix (g.prefix); - g.entityid = nn_hton_entityid (g.entityid); - return g; -} - -nn_guid_t nn_ntoh_guid (nn_guid_t g) -{ - g.prefix = nn_ntoh_guid_prefix (g.prefix); - g.entityid = nn_ntoh_entityid (g.entityid); - return g; -} - -void bswap_sequence_number_set_hdr (nn_sequence_number_set_t *snset) -{ - bswapSN (&snset->bitmap_base); - snset->numbits = bswap4u (snset->numbits); -} - -void bswap_sequence_number_set_bitmap (nn_sequence_number_set_t *snset) -{ - unsigned i, n = (snset->numbits + 31) / 32; - for (i = 0; i < n; i++) - snset->bits[i] = bswap4u (snset->bits[i]); -} - -void bswap_fragment_number_set_hdr (nn_fragment_number_set_t *fnset) -{ - fnset->bitmap_base = bswap4u (fnset->bitmap_base); - fnset->numbits = bswap4u (fnset->numbits); -} - -void bswap_fragment_number_set_bitmap (nn_fragment_number_set_t *fnset) -{ - unsigned i, n = (fnset->numbits + 31) / 32; - for (i = 0; i < n; i++) - fnset->bits[i] = bswap4u (fnset->bits[i]); -} - -/* SHA1 not available (unoffical build.) */ diff --git a/src/services/ddsi2/code/q_bswap_inlines.c b/src/services/ddsi2/code/q_bswap_inlines.c deleted file mode 100644 index 6e9e40e56..000000000 --- a/src/services/ddsi2/code/q_bswap_inlines.c +++ /dev/null @@ -1,25 +0,0 @@ -/* - * OpenSplice DDS - * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -#define SUPPRESS_BSWAP_INLINES - -#include "q_bswap.h" -#include "q_bswap_template.c" - -/* SHA1 not available (unoffical build.) */ diff --git a/src/services/ddsi2/code/q_bswap_template.c b/src/services/ddsi2/code/q_bswap_template.c deleted file mode 100644 index 113871b12..000000000 --- a/src/services/ddsi2/code/q_bswap_template.c +++ /dev/null @@ -1,51 +0,0 @@ -/* - * OpenSplice DDS - * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -/* -*- c -*- */ - -#if defined SUPPRESS_BSWAP_INLINES && defined NN_C99_INLINE -#undef NN_C99_INLINE -#define NN_C99_INLINE -#endif - -NN_C99_INLINE unsigned short bswap2u (unsigned short x) -{ - return (unsigned short) ((x >> 8) | (x << 8)); -} - -NN_C99_INLINE unsigned bswap4u (unsigned x) -{ - return (x >> 24) | ((x >> 8) & 0xff00) | ((x << 8) & 0xff0000) | (x << 24); -} - -NN_C99_INLINE unsigned long long bswap8u (unsigned long long x) -{ - const unsigned newhi = bswap4u ((unsigned) x); - const unsigned newlo = bswap4u ((unsigned) (x >> 32)); - return ((unsigned long long) newhi << 32) | (unsigned long long) newlo; -} - -NN_C99_INLINE void bswapSN (nn_sequence_number_t *sn) -{ - sn->high = bswap4 (sn->high); - sn->low = bswap4u (sn->low); -} - - -/* SHA1 not available (unoffical build.) */ diff --git a/src/services/ddsi2/code/q_builtin_topic.h b/src/services/ddsi2/code/q_builtin_topic.h deleted file mode 100644 index f6d016ef4..000000000 --- a/src/services/ddsi2/code/q_builtin_topic.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * OpenSplice DDS - * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -#ifndef Q_BUILTIN_TOPIC_H -#define Q_BUILTIN_TOPIC_H - -struct proxy_participant; -struct proxy_writer; -struct proxy_reader; - -struct nn_plist; - -/* Functions called at proxy entity creation/deletion time, so they - can do whatever is necessary to get the builtin topics function - correctly. - - These probably should return an error code, but I don't quite know - how to handle it yet and this way we have Coverity on our side. - Implementation is outside the common core. - - These may assume the proxy entities are stable, without parallel QoS - changes. */ -void write_builtin_topic_proxy_participant (const struct proxy_participant *proxypp); -void write_builtin_topic_proxy_participant_cm (const struct proxy_participant *proxypp); -void dispose_builtin_topic_proxy_participant (const struct proxy_participant *proxypp, int isimplicit); -void write_builtin_topic_proxy_writer (const struct proxy_writer *pwr); -void dispose_builtin_topic_proxy_writer (const struct proxy_writer *pwr, int isimplicit); -void write_builtin_topic_proxy_reader (const struct proxy_reader *prd); -void dispose_builtin_topic_proxy_reader (const struct proxy_reader *prd, int isimplicit); -void write_builtin_topic_proxy_group (const struct proxy_group *pgroup); -void dispose_builtin_topic_proxy_group (const struct proxy_group *pgroup, int isimplicit); - -void write_builtin_topic_proxy_topic (const struct nn_plist *datap); - -#endif - -/* SHA1 not available (unoffical build.) */ diff --git a/src/services/ddsi2/code/q_config.c b/src/services/ddsi2/code/q_config.c deleted file mode 100644 index 01ee01b9a..000000000 --- a/src/services/ddsi2/code/q_config.c +++ /dev/null @@ -1,2576 +0,0 @@ -/* - * OpenSplice DDS - * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -#include -#include -#include -#include -#include -#include - -#include "os_stdlib.h" -#include "os_socket.h" -#include "os_heap.h" - -#include "ut_crc.h" -#include "u_participant.h" -#include "u_cfElement.h" -#include "u_cfData.h" -#include "u_cfNode.h" - -#include "q_config.h" -#include "q_log.h" -#include "ut_avl.h" -#include "q_unused.h" -#include "q_misc.h" -#include "q_addrset.h" -#include "q_nwif.h" -#include "q_error.h" -#include "sysdeps.h" - - -#define WARN_DEPRECATED_ALIAS 1 -#define WARN_DEPRECATED_UNIT 1 -#define MAX_PATH_DEPTH 10 /* max nesting level of configuration elements */ - -struct cfgelem; -struct cfgst; - -typedef int (*init_fun_t) (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem); -typedef int (*update_fun_t) (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int first, const char *value); -typedef void (*free_fun_t) (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem); -typedef void (*print_fun_t) (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int is_default); - -#ifdef DDSI_INCLUDE_SECURITY -struct q_security_plugins q_security_plugin = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; -#endif - -struct unit { - const char *name; - os_int64 multiplier; -}; - -struct cfgelem { - const char *name; - const struct cfgelem *children; - const struct cfgelem *attributes; - int multiplicity; - const char *defvalue; /* NULL -> no default */ - int relative_offset; - int elem_offset; - init_fun_t init; - update_fun_t update; - free_fun_t free; - print_fun_t print; - const char *description; -}; - -struct cfgst_nodekey { - const struct cfgelem *e; -}; - -struct cfgst_node { - ut_avlNode_t avlnode; - struct cfgst_nodekey key; - int count; - int failed; - int is_default; -}; - -struct cfgst { - ut_avlTree_t found; - struct config *cfg; - - /* Servicename is used by uf_service_name to use as a default value - when the supplied string is empty, which happens when the service - is started without a DDSI2Service configuration item, i.e. when - everything is left at the default. */ - const char *servicename; - - /* path_depth, isattr and path together control the formatting of - error messages by cfg_error() */ - int path_depth; - int isattr[MAX_PATH_DEPTH]; - const struct cfgelem *path[MAX_PATH_DEPTH]; - void *parent[MAX_PATH_DEPTH]; -}; - -/* "trace" is special: it enables (nearly) everything */ -static const char *logcat_names[] = { - "fatal", "error", "warning", "config", "info", "discovery", "data", "radmin", "timing", "traffic", "topic", "tcp", "plist", "whc", "trace", NULL -}; -static const logcat_t logcat_codes[] = { - LC_FATAL, LC_ERROR, LC_WARNING, LC_CONFIG, LC_INFO, LC_DISCOVERY, LC_DATA, LC_RADMIN, LC_TIMING, LC_TRAFFIC, LC_TOPIC, LC_TCP, LC_PLIST, LC_WHC, LC_ALLCATS -}; - -/* We want the tracing/verbosity settings to be fixed while parsing - the configuration, so we update this variable instead. */ -static unsigned enabled_logcats; - -static int cfgst_node_cmp (const void *va, const void *vb); -static const ut_avlTreedef_t cfgst_found_treedef = - UT_AVL_TREEDEF_INITIALIZER (offsetof (struct cfgst_node, avlnode), offsetof (struct cfgst_node, key), cfgst_node_cmp, 0); - -#define DU(fname) static int fname (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int first, const char *value) -DU (uf_networkAddress); -DU (uf_networkAddresses); -DU (uf_ipv4); -DU (uf_allow_multicast); -DU (uf_boolean); -DU (uf_negated_boolean); -DU (uf_string); -DU (uf_tracingOutputFileName); -DU (uf_verbosity); -DU (uf_logcat); -DU (uf_float); -DU (uf_int); -DU (uf_uint); -DU (uf_int32); -DU (uf_uint32); -DU (uf_natint); -DU (uf_natint_255); -DU (uf_participantIndex); -DU (uf_port); -DU (uf_dyn_port); -DU (uf_memsize); -DU (uf_duration_inf); -DU (uf_duration_ms_1hr); -DU (uf_duration_ms_1s); -DU (uf_duration_us_1s); -DU (uf_standards_conformance); -DU (uf_besmode); -DU (uf_retransmit_merging); -DU (uf_sched_prio_class); -DU (uf_sched_class); -DU (uf_maybe_memsize); -DU (uf_maybe_int32); -DU (uf_domainId); -DU (uf_maybe_duration_inf); -DU (uf_service_name); -DU (uf_boolean_default); -#undef DU - -#define DF(fname) static void fname (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem) -DF (ff_free); -DF (ff_networkAddresses); -#undef DF - -#define DI(fname) static int fname (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem) -DI (if_peer); -DI (if_thread_properties); -#undef DI - -#define PF(fname) static void fname (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int is_default) -PF (pf_nop); -PF (pf_string); -PF (pf_networkAddress); -PF (pf_participantIndex); -PF (pf_networkAddresses); -PF (pf_memsize); -PF (pf_duration); -PF (pf_int); -PF (pf_uint); -PF (pf_int32); -PF (pf_uint32); -PF (pf_float); -PF (pf_allow_multicast); -PF (pf_boolean); -PF (pf_negated_boolean); -PF (pf_logcat); -PF (pf_standards_conformance); -PF (pf_besmode); -PF (pf_retransmit_merging); -PF (pf_sched_prio_class); -PF (pf_sched_class); -PF (pf_maybe_memsize); -PF (pf_maybe_int32); -PF (pf_maybe_duration); -PF (pf_boolean_default); -#undef PF - -#define CO(name) ((int) offsetof (struct config, name)) -#define ABSOFF(name) 0, CO (name) -#define RELOFF(parent,name) 1, ((int) offsetof (struct parent, name)) -#define NODATA 1, NULL, 0, 0, 0, 0, 0, 0 -#define END_MARKER { NULL, NULL, NULL, NODATA, NULL } -#define WILDCARD { "*", NULL, NULL, NODATA, NULL } -#define LEAF(name) name, NULL, NULL -#define LEAF_W_ATTRS(name, attrs) name, NULL, attrs -#define GROUP(name, children) name, children, NULL, 1, NULL, 0, 0, 0, 0, 0, 0 -#define MGROUP(name, children, attrs) name, children, attrs -#define ATTR(name) name, NULL, NULL -/* MOVED: whereto must be a path relative to DDSI2Service, may not be used in/for lists and only for elements, may not be chained */ -#define MOVED(name, whereto) ">" name, NULL, NULL, 0, whereto, 0, 0, 0, 0, 0, 0, NULL -static const struct cfgelem timestamp_cfgattrs[] = { - { ATTR ("absolute"), 1, "false", ABSOFF (tracingRelativeTimestamps), 0, uf_negated_boolean, 0, pf_negated_boolean, - "

    This option has no effect

    " }, - END_MARKER -}; - -static const struct cfgelem general_cfgelems[] = { - { LEAF ("NetworkInterfaceAddress"), 1, "auto", ABSOFF (networkAddressString), 0, uf_networkAddress, ff_free, pf_networkAddress, - "

    This element specifies the preferred network interface for use by DDSI2. The preferred network interface determines the IP address that DDSI2 advertises in the discovery protocol (but see also General/ExternalNetworkAddress), and is also the only interface over which multicasts are transmitted. The interface can be identified by its IP address, network interface name or network portion of the address. If the value \"auto\" is entered here, DDSI2 will select what it considers the most suitable interface.

    " }, - { LEAF ("MulticastRecvNetworkInterfaceAddresses"), 1, "preferred", ABSOFF (networkRecvAddressStrings), 0, uf_networkAddresses, ff_networkAddresses, pf_networkAddresses, - "

    This element specifies on which network interfaces DDSI2 listens to multicasts. The following options are available:

    \n\ -
      \n\ -
    • all: listen for multicasts on all multicast-capable interfaces; or
    • \n\ -
    • any: listen for multicasts on the operating system default interface; or
    • \n\ -
    • preferred: listen for multicasts on the preferred interface (General/NetworkInterfaceAddress); or
    • \n\ -
    • none: does not listen for multicasts on any interface; or
    • \n\ -
    • a comma-separated list of network addresses: configures DDSI2 to listen for multicasts on all of the listed addresses.
    • \n\ -
    \n\ -

    If DDSI2 is in IPv6 mode and the address of the preferred network interface is a link-local address, \"all\" is treated as a synonym for \"preferred\" and a comma-separated list is treated as \"preferred\" if it contains the preferred interface and as \"none\" if not.

    " }, - { LEAF ("ExternalNetworkAddress"), 1, "auto", ABSOFF (externalAddressString), 0, uf_networkAddress, ff_free, pf_networkAddress, - "

    This element allows explicitly overruling the network address DDSI2 advertises in the discovery protocol, which by default is the address of the preferred network interface (General/NetworkInterfaceAddress), to allow DDSI2 to communicate across a Network Address Translation (NAT) device.

    " }, - { LEAF ("ExternalNetworkMask"), 1, "0.0.0.0", ABSOFF (externalMaskString), 0, uf_string, ff_free, pf_string, - "

    This element specifies the network mask of the external network address. This element is relevant only when an external network address (General/ExternalNetworkAddress) is explicitly configured. In this case locators received via the discovery protocol that are within the same external subnet (as defined by this mask) will be translated to an internal address by replacing the network portion of the external address with the corresponding portion of the preferred network interface address. This option is IPv4-only.

    " }, - { LEAF ("AllowMulticast"), 1, "true", ABSOFF (allowMulticast), 0, uf_allow_multicast, 0, pf_allow_multicast, - "

    This element controls whether DDSI2 uses multicasts for data traffic.

    \n\ -

    It is a comma-separated list of some of the following keywords: \"spdp\", \"asm\", \"ssm\", or either of \"false\" or \"true\".

    \n\ -
      \n\ -
    • spdp: enables the use of ASM (any-source multicast) for participant discovery
    • \n\ -
    • asm: enables the use of ASM for all traffic (including SPDP)
    • \n\ -
    • ssm: enables the use of SSM (source-specific multicast) for all non-SPDP traffic (if supported)
    • \n\ -
    \n\ -

    When set to \"false\" all multicasting is disabled. The default, \"true\" enables full use of multicasts. Listening for multicasts can be controlled by General/MulticastRecvNetworkInterfaceAddresses.

    " }, - { LEAF ("MulticastTimeToLive"), 1, "32", ABSOFF (multicast_ttl), 0, uf_natint_255, 0, pf_int, - "

    This element specifies the time-to-live setting for outgoing multicast packets.

    " }, - { LEAF ("DontRoute"), 1, "false", ABSOFF (dontRoute), 0, uf_boolean, 0, pf_boolean, - "

    This element allows setting the SO_DONTROUTE option for outgoing packets, to bypass the local routing tables. This is generally useful only when the routing tables cannot be trusted, which is highly unusual.

    " }, - { LEAF ("UseIPv6"), 1, "false", ABSOFF (useIpv6), 0, uf_boolean, 0, pf_boolean , - "

    This element can be used to DDSI2 use IPv6 instead of IPv4. This is currently an either/or switch.

    " }, - { LEAF ("EnableMulticastLoopback"), 1, "true", ABSOFF (enableMulticastLoopback), 0, uf_boolean, 0, pf_boolean, - "

    This element specifies whether DDSI2 allows IP multicast packets to be visible to all DDSI participants in the same node, including itself. It must be \"true\" for intra-node multicast communications, but if a node runs only a single DDSI2 service and does not host any other DDSI-capable programs, it should be set to \"false\" for improved performance.

    " }, - { LEAF ("CoexistWithNativeNetworking"), 1, "false", ABSOFF (coexistWithNativeNetworking), 0, uf_boolean, 0, pf_boolean, - "

    This element specifies whether the DDSI2 service operates in conjunction with the OpenSplice RT Networking service. When \"false\", the DDSI2 service will take care of all communications, including those between OpenSplice nodes; when \"true\", the DDSI2 service only communicates with DDS implementations other than OpenSplice. In this case the RT Networking service should be configured as well.

    " }, - { LEAF ("StartupModeDuration"), 1, "2 s", ABSOFF (startup_mode_duration), 0, uf_duration_ms_1hr, 0, pf_duration, - "

    This element specifies how long the DDSI2 remains in its \"startup\" mode. While in \"startup\" mode all volatile reliable data published on the local node is retained as-if it were transient-local data, allowing existing readers on remote nodes to obtain the data even though discovering them takes some time. Best-effort data by definition need not arrive, and transient and persistent data are covered by the durability service.

    \n\ -

    Once the system is stable, DDSI2 keeps track of the existence of remote readers whether or not matching writers exist locally, avoiding this discovery delay and ensuring this is merely a node startup issue.

    \n\ -

    Setting General/StartupModeDuration to 0s will disable it.

    " }, - { LEAF ("StartupModeCoversTransient"), 1, "true", ABSOFF (startup_mode_full), 0, uf_boolean, 0, pf_boolean, - "

    This element configures whether startup-mode should also cover transient and persistent data, for configurations where the durability service does not take care of it. Configurations without defined merge policies best leave this enabled.

    " }, - { LEAF ("MaxMessageSize"), 1, "4096 B", ABSOFF (max_msg_size), 0, uf_memsize, 0, pf_memsize, - "

    This element specifies the maximum size of the UDP payload that DDSI2 will generate. DDSI2 will try to maintain this limit within the bounds of the DDSI specification, which means that in some cases (especially for very low values of MaxMessageSize) larger payloads may sporadically be observed (currently up to 1192 B).

    \n\ -

    On some networks it may be necessary to set this item to keep the packetsize below the MTU to prevent IP fragmentation. In those cases, it is generally advisable to also consider reducing Internal/FragmentSize.

    " }, - { LEAF ("FragmentSize"), 1, "1280 B", ABSOFF (fragment_size), 0, uf_memsize, 0, pf_memsize, - "

    This element specifies the size of DDSI sample fragments generated by DDSI2. Samples larger than FragmentSize are fragmented into fragments of FragmentSize bytes each, except the last one, which may be smaller. The DDSI spec mandates a minimum fragment size of 1025 bytes, but DDSI2 will do whatever size is requested, accepting fragments of which the size is at least the minimum of 1025 and FragmentSize.

    " }, - END_MARKER -}; - - - - -static const struct cfgelem thread_properties_sched_cfgelems[] = { - { LEAF ("Class"), 1, "default", RELOFF (config_thread_properties_listelem, sched_class), 0, uf_sched_class, 0, pf_sched_class, - "

    This element specifies the thread scheduling class (realtime, timeshare or default). The user may need special privileges from the underlying operating system to be able to assign some of the privileged scheduling classes.

    " }, - { LEAF ("Priority"), 1, "default", RELOFF (config_thread_properties_listelem, sched_priority), 0, uf_maybe_int32, 0, pf_maybe_int32, - "

    This element specifies the thread priority (decimal integer or default). Only priorities that are supported by the underlying operating system can be assigned to this element. The user may need special privileges from the underlying operating system to be able to assign some of the privileged priorities.

    " }, - END_MARKER -}; - -static const struct cfgelem thread_properties_cfgattrs[] = { - { ATTR ("Name"), 1, NULL, RELOFF (config_thread_properties_listelem, name), 0, uf_string, ff_free, pf_string, - "

    The Name of the thread for which properties are being set. The following threads exist:

    \n\ -
    • gc: garbage collector thread involved in deleting entities;
    • \n\ -
    • recv: receive thread, taking data from the network and running the protocol state machine;
    • \n\ -
    • dq.builtins: delivery thread for DDSI-builtin data, primarily for discovery;
    • \n\ -
    • lease: DDSI liveliness monitoring;
    • \n\ -
    • tev: general timed-event handling, retransmits and discovery;
    • \n\ -
    • xmit.CHAN: transmit thread for channel CHAN;
    • \n\ -
    • dq.CHAN: delivery thread for channel CHAN;
    • \n\ -
    • tev.CHAN: timed-even thread for channel CHAN.
    " }, - END_MARKER -}; - -static const struct cfgelem thread_properties_cfgelems[] = { - { GROUP ("Scheduling", thread_properties_sched_cfgelems), - "

    This element configures the scheduling properties of the thread.

    " }, - { LEAF ("StackSize"), 1, "default", RELOFF (config_thread_properties_listelem, stack_size), 0, uf_maybe_memsize, 0, pf_maybe_memsize, - "

    This element configures the stack size for this thread. The default value default leaves the stack size at the operating system default.

    " }, - END_MARKER -}; - -static const struct cfgelem threads_cfgelems[] = { - { MGROUP ("Thread", thread_properties_cfgelems, thread_properties_cfgattrs), 1000, 0, ABSOFF (thread_properties), if_thread_properties, 0, 0, 0, - "

    This element is used to set thread properties.

    " }, - END_MARKER -}; - -static const struct cfgelem compatibility_cfgelems[] = { - { LEAF ("StandardsConformance"), 1, "lax", ABSOFF (standards_conformance), 0, uf_standards_conformance, 0, pf_standards_conformance, - "

    This element sets the level of standards conformance of this instance of the DDSI2 Service. Stricter conformance typically means less interoperability with other implementations. Currently three modes are defined:

    \n\ -
    • pedantic: very strictly conform to the specification, ultimately for compliancy testing, but currently of little value because it adheres even to what will most likely turn out to be editing errors in the DDSI standard. Arguably, as long as no errata have been published it is the current text that is in effect, and that is what pedantic currently does.
    • \n\ -
    • strict: a slightly less strict view of the standard than does pedantic: it follows the established behaviour where the standard is obviously in error.
    • \n\ -
    • lax: attempt to provide the smoothest possible interoperability, anticipating future revisions of elements in the standard in areas that other implementations do not adhere to, even though there is no good reason not to.
    \n\ -

    The default setting is \"lax\".

    " }, - { LEAF ("ExplicitlyPublishQosSetToDefault"), 1, "false", ABSOFF (explicitly_publish_qos_set_to_default), 0, uf_boolean, 0, pf_boolean, - "

    This element specifies whether QoS settings set to default values are explicitly published in the discovery protocol. Implementations are to use the default value for QoS settings not published, which allows a significant reduction of the amount of data that needs to be exchanged for the discovery protocol, but this requires all implementations to adhere to the default values specified by the specifications.

    \n\ -

    When interoperability is required with an implementation that does not follow the specifications in this regard, setting this option to true will help.

    " }, - { LEAF ("ManySocketsMode"), 1, "false", ABSOFF (many_sockets_mode), 0, uf_boolean, 0, pf_boolean, - "

    This option specifies whether a network socket will be created for each domain participant on a host. The specification seems to assume that each participant has a unique address, and setting this option will ensure this to be the case. This is not the defeault.

    \n\ -

    Disabling it slightly improves performance and reduces network traffic somewhat. It also causes the set of port numbers needed by DDSI2 to become predictable, which may be useful for firewall and NAT configuration.

    " }, - { LEAF ("ArrivalOfDataAssertsPpAndEpLiveliness"), 1, "true", ABSOFF (arrival_of_data_asserts_pp_and_ep_liveliness), 0, uf_boolean, 0, pf_boolean, - "

    When set to true, arrival of a message from a peer asserts liveliness of that peer. When set to false, only SPDP and explicit lease renewals have this effect.

    " }, - { LEAF ("AckNackNumbitsEmptySet"), 1, "0", ABSOFF (acknack_numbits_emptyset), 0, uf_natint, 0, pf_int, - "

    This element governs the representation of an acknowledgement message that does not also negatively-acknowledge some samples. If set to 0, the generated acknowledgements have an invalid form and will be reject by the strict and pedantic conformance modes, but several other implementation require this setting for smooth interoperation.

    \n\ -

    If set to 1, all acknowledgements sent by DDSI2 adhere the form of acknowledgement messages allowed by the standard, but this causes problems when interoperating with these other implementations. The strict and pedantic standards conformance modes always overrule an AckNackNumbitsEmptySet=0 to prevent the transmitting of invalid messages.

    " }, - { LEAF ("RespondToRtiInitZeroAckWithInvalidHeartbeat"), 1, "false", ABSOFF (respond_to_rti_init_zero_ack_with_invalid_heartbeat), 0, uf_boolean, 0, pf_boolean, - "

    This element allows a closer mimicking of the behaviour of some other DDSI implementations, albeit at the cost of generating even more invalid messages. Setting it to true ensures a Heartbeat can be sent at any time when a remote node requests one, setting it to false delays it until a valid one can be sent.

    \n\ -

    The latter is fully compliant with the specification, and no adverse effects have been observed. It is the default.

    " }, - { LEAF ("AssumeRtiHasPmdEndpoints"), 1, "false", ABSOFF (assume_rti_has_pmd_endpoints), 0, uf_boolean, 0, pf_boolean, - "

    This option assumes ParticipantMessageData endpoints required by the liveliness protocol are present in RTI participants even when not properly advertised by the participant discovery protocol.

    " }, - END_MARKER -}; - -static const struct cfgelem unsupp_test_cfgelems[] = { - { LEAF ("XmitLossiness"), 1, "0", ABSOFF (xmit_lossiness), 0, uf_int, 0, pf_int, - "

    This element controls the fraction of outgoing packets to drop, specified as samples per thousand.

    " }, - END_MARKER -}; - -static const struct cfgelem unsupp_watermarks_cfgelems[] = { - { LEAF ("WhcLow"), 1, "1 kB", ABSOFF (whc_lowwater_mark), 0, uf_memsize, 0, pf_memsize, - "

    This element sets the low-water mark for the DDSI2 WHCs, expressed in bytes. A suspended writer resumes transmitting when its DDSI2 WHC shrinks to this size.

    " }, - { LEAF ("WhcHigh"), 1, "100 kB", ABSOFF (whc_highwater_mark), 0, uf_memsize, 0, pf_memsize, - "

    This element sets the maximum allowed high-water mark for the DDSI2 WHCs, expressed in bytes. A writer is suspended when the WHC reaches this size.

    " }, - { LEAF ("WhcHighInit"), 1, "30 kB", ABSOFF (whc_init_highwater_mark), 0, uf_maybe_memsize, 0, pf_maybe_memsize, - "

    This element sets the initial level of the high-water mark for the DDSI2 WHCs, expressed in bytes.

    "}, - { LEAF ("WhcAdaptive|WhcAdaptative"), 1, "true", ABSOFF (whc_adaptive), 0, uf_boolean, 0, pf_boolean, - "

    This element controls whether DDSI2 will adapt the high-water mark to current traffic conditions, based on retransmit requests and transmit pressure.

    " }, - END_MARKER -}; - -static const struct cfgelem control_topic_cfgattrs[] = { - { ATTR ("enable"), 1, "false", ABSOFF (enable_control_topic), 0, uf_boolean, 0, pf_boolean, - "

    This attribute controls whether the DDSI2 control topic is defined and acted upon by DDSI2

    " }, - END_MARKER -}; - -static const struct cfgelem control_topic_cfgelems[] = { - { LEAF ("DeafMute"), 1, "false", ABSOFF (initial_deaf_mute), 0, uf_boolean, 0, pf_boolean, - "

    This element controls whether DDSI2 defaults to deaf-mute mode or to normal mode. This controls both the initial behaviour and what behaviour it auto-reverts to.

    " }, - END_MARKER -}; - -static const struct cfgelem rediscovery_blacklist_duration_attrs[] = { - { ATTR ("enforce"), 1, "false", ABSOFF (prune_deleted_ppant.enforce_delay), 0, uf_boolean, 0, pf_boolean, - "

    This attribute controls whether the configured time during which recently deleted participants will not be rediscovered (i.e., \"black listed\") is enforced and following complete removal of the participant in DDSI2, or whether it can be rediscovered earlier provided all traces of that participant have been removed already.

    " }, - END_MARKER -}; - -static const struct cfgelem unsupp_cfgelems[] = { - { MOVED ("MaxMessageSize", "General/MaxMessageSize") }, - { MOVED ("FragmentSize", "General/FragmentSize") }, - { LEAF ("DeliveryQueueMaxSamples"), 1, "256", ABSOFF (delivery_queue_maxsamples), 0, uf_uint, 0, pf_uint, - "

    This element controls the Maximum size of a delivery queue, expressed in samples. Once a delivery queue is full, incoming samples destined for that queue are dropped until space becomes available again.

    " }, - { LEAF ("PrimaryReorderMaxSamples"), 1, "64", ABSOFF (primary_reorder_maxsamples), 0, uf_uint, 0, pf_uint, - "

    This element sets the maximum size in samples of a primary re-order administration. Each proxy writer has one primary re-order administration to buffer the packet flow in case some packets arrive out of order. Old samples are forwarded to secondary re-order administrations associated with readers in need of historical data.

    " }, - { LEAF ("SecondaryReorderMaxSamples"), 1, "16", ABSOFF (secondary_reorder_maxsamples), 0, uf_uint, 0, pf_uint, - "

    This element sets the maximum size in samples of a secondary re-order administration. The secondary re-order administration is per reader in need of historical data.

    " }, - { LEAF ("DefragUnreliableMaxSamples"), 1, "4", ABSOFF (defrag_unreliable_maxsamples), 0, uf_uint, 0, pf_uint, - "

    This element sets the maximum number of samples that can be defragmented simultaneously for a best-effort writers.

    " }, - { LEAF ("DefragReliableMaxSamples"), 1, "16", ABSOFF (defrag_reliable_maxsamples), 0, uf_uint, 0, pf_uint, - "

    This element sets the maximum number of samples that can be defragmented simultaneously for a reliable writer. This has to be large enough to handle retransmissions of historical data in addition to new samples.

    " }, - { LEAF ("BuiltinEndpointSet"), 1, "writers", ABSOFF (besmode), 0, uf_besmode, 0, pf_besmode, - "

    This element controls which participants will have which built-in endpoints for the discovery and liveliness protocols. Valid values are:

    \n\ -
    • full: all participants have all endpoints;
    • \n\ -
    • writers: all participants have the writers, but just one has the readers;
    • \n\ -
    • minimal: only one participant has built-in endpoints.
    \n\ -

    The default is writers, as this is thought to be compliant and reasonably efficient. Minimal may or may not be compliant but is most efficient, and full is inefficient but certain to be compliant. See also Internal/ConservativeBuiltinReaderStartup.

    " }, - { LEAF ("AggressiveKeepLastWhc|AggressiveKeepLast1Whc"), 1, "false", ABSOFF (aggressive_keep_last_whc), 0, uf_boolean, 0, pf_boolean, - "

    This element controls whether to drop a reliable sample from a DDSI2 WHC before all readers have acknowledged it as soon as a later sample becomes available. It only affects DCPS data writers with a history QoS setting of KEEP_LAST with depth 1. The default setting, false, mimics the behaviour of the OpenSplice RT networking and is necessary to make the behaviour of wait_for_acknowledgements() consistent across the networking services.

    " }, - { LEAF ("ConservativeBuiltinReaderStartup"), 1, "false", ABSOFF (conservative_builtin_reader_startup), 0, uf_boolean, 0, pf_boolean, - "

    This element forces all DDSI2 built-in discovery-related readers to request all historical data, instead of just one for each \"topic\". There is no indication that any of the current DDSI implementations requires changing of this setting, but it is conceivable that an implementation might track which participants have been informed of the existence of endpoints and which have not been, refusing communication with those that have \"can't\" know.

    \n\ -

    Should it be necessary to hide DDSI2's shared discovery behaviour, set this to true and Internal/BuiltinEndpointSet to full.

    " }, - { LEAF ("MeasureHbToAckLatency"), 1, "false", ABSOFF (meas_hb_to_ack_latency), 0, uf_boolean, 0, pf_boolean, - "

    This element enables heartbeat-to-ack latency among DDSI2 services by prepending timestamps to Heartbeat and AckNack messages and calculating round trip times. This is non-standard behaviour. The measured latencies are quite noisy and are currently not used anywhere.

    " }, - { LEAF ("SuppressSPDPMulticast"), 1, "false", ABSOFF (suppress_spdp_multicast), 0, uf_boolean, 0, pf_boolean, - "

    The element controls whether the mandatory multicasting of the participant discovery packets occurs. Completely disabling multicasting requires this element be set to true, and generally requires explicitly listing peers to ping for unicast discovery.

    \n\ -

    See also General/AllowMulticast.

    " }, - { LEAF ("UnicastResponseToSPDPMessages"), 1, "true", ABSOFF (unicast_response_to_spdp_messages), 0, uf_boolean, 0, pf_boolean, - "

    This element controls whether the response to a newly discovered participant is sent as a unicasted SPDP packet, instead of rescheduling the periodic multicasted one. There is no known benefit to setting this to false.

    " }, - { LEAF ("SynchronousDeliveryPriorityThreshold"), 1, "0", ABSOFF (synchronous_delivery_priority_threshold), 0, uf_int, 0, pf_int, - "

    This element controls whether samples sent by a writer with QoS settings latency_budget <= SynchronousDeliveryLatencyBound and transport_priority greater than or equal to this element's value will be delivered synchronously from the \"recv\" thread, all others will be delivered asynchronously through delivery queues. This reduces latency at the expense of aggregate bandwidth.

    " }, - { LEAF ("SynchronousDeliveryLatencyBound"), 1, "inf", ABSOFF (synchronous_delivery_latency_bound), 0, uf_duration_inf, 0, pf_duration, - "

    This element controls whether samples sent by a writer with QoS settings transport_priority >= SynchronousDeliveryPriorityThreshold and a latency_budget at most this element's value will be delivered synchronously from the \"recv\" thread, all others will be delivered asynchronously through delivery queues. This reduces latency at the expense of aggregate bandwidth.

    " }, - { LEAF ("MaxParticipants"), 1, "0", ABSOFF (max_participants), 0, uf_natint, 0, pf_int, - "

    This elements configures the maximum number of DCPS domain participants this DDSI2 instance is willing to service. 0 is unlimited.

    " }, - { LEAF ("AccelerateRexmitBlockSize"), 1, "0", ABSOFF (accelerate_rexmit_block_size), 0, uf_uint, 0, pf_uint, - "

    Proxy readers that are assumed to sill be retrieving historical data get this many samples retransmitted when they NACK something, even if some of these samples have sequence numbers outside the set covered by the NACK.

    " }, - { LEAF ("ResponsivenessTimeout"), 1, "inf", ABSOFF (responsiveness_timeout), 0, uf_duration_inf, 0, pf_duration, - "

    This element controls for how long an unresponsive reader can block the transmit thread by failing to acknowledge data when a writer's DDSI2 write cache is full. If after this time the writer's cache has not shrunk to below the low-water mark, the reader is considered unresponsive and degraded to unreliable. It will be restored to reliable service once it resumes acknowledging samples.

    " }, - { LEAF ("RetransmitMerging"), 1, "adaptive", ABSOFF (retransmit_merging), 0, uf_retransmit_merging, 0, pf_retransmit_merging, - "

    This elements controls the addressing and timing of retransmits. Possible values are:

    \n\ -
    • never: retransmit only to the NACK-ing reader;
    • \n\ -
    • adaptive: attempt to combine retransmits needed for reliability, but send historical (transient-local) data to the requesting reader only;
    • \n\ -
    • always: do not distinguish between different causes, always try to merge.
    \n\ -

    The default is adaptive. See also Internal/RetransmitMergingPeriod.

    " }, - { LEAF ("RetransmitMergingPeriod"), 1, "5 ms", ABSOFF (retransmit_merging_period), 0, uf_duration_us_1s, 0, pf_duration, - "

    This setting determines the size of the time window in which a NACK of some sample is ignored because a retransmit of that sample has been multicasted too recently. This setting has no effect on unicasted retransmits.

    \n\ -

    See also Internal/RetransmitMerging.

    " }, - { LEAF ("MaxQueuedRexmitBytes"), 1, "50 kB", ABSOFF (max_queued_rexmit_bytes), 0, uf_memsize, 0, pf_memsize, - "

    This setting limits the maximum number of bytes queued for retransmission. The default value of 0 is unlimited unless an AuxiliaryBandwidthLimit has been set, in which case it becomes NackDelay * AuxiliaryBandwidthLimit. It must be large enough to contain the largest sample that may need to be retransmitted.

    " }, - { LEAF ("MaxQueuedRexmitMessages"), 1, "200", ABSOFF (max_queued_rexmit_msgs), 0, uf_uint, 0, pf_uint, - "

    This settings limits the maximum number of samples queued for retransmission.

    " }, - { LEAF ("MirrorRemoteEntities"), 1, "default", ABSOFF (mirror_remote_entities), 0, uf_boolean_default, 0, pf_boolean_default, - "

    This element controls whether DDSI2 mirrors all entities in the domain in DDSI or only local ones. Default is to discover remote ones iff General/LocalDiscoveryPartition is not the built-in partition.

    " }, - { LEAF ("ForwardRemoteData"), 1, "default", ABSOFF (forward_remote_data), 0, uf_boolean_default, 0, pf_boolean, - "

    This element controls whether DDSI2 forwards data received from other network services in the domain.

    " }, - { LEAF ("LeaseDuration"), 1, "0 s", ABSOFF (lease_duration), 0, uf_duration_ms_1hr, 0, pf_duration, - "

    This setting controls the default participant lease duration.

    " }, - { LEAF ("WriterLingerDuration"), 1, "1 s", ABSOFF (writer_linger_duration), 0, uf_duration_ms_1hr, 0, pf_duration, - "

    This setting controls the maximum duration for which actual deletion of a reliable writer with unacknowledged data in its history will be postponed to provide proper reliable transmission.

    " }, - { LEAF ("MinimumSocketReceiveBufferSize"), 1, "default", ABSOFF (socket_min_rcvbuf_size), 0, uf_maybe_memsize, 0, pf_maybe_memsize, - "

    This setting controls the minimum size of socket receive buffers. The operating system provides some size receive buffer upon creation of the socket, this option can be used to increase the size of the buffer beyond that initially provided by the operating system. If the buffer size cannot be increased to the specified size, an error is reported.

    \n\ -

    The default setting is the word \"default\", which means DDSI2 will attempt to increase the buffer size to 1MB, but will silently accept a smaller buffer should that attempt fail.

    " }, - { LEAF ("MinimumSocketSendBufferSize"), 1, "64 KiB", ABSOFF (socket_min_sndbuf_size), 0, uf_memsize, 0, pf_memsize, - "

    This setting controls the minimum size of socket send buffers. This setting can only increase the size of the send buffer, if the operating system by default creates a larger buffer, it is left unchanged.

    " }, - { LEAF ("NackDelay"), 1, "10 ms", ABSOFF (nack_delay), 0, uf_duration_ms_1hr, 0, pf_duration, - "

    This setting controls the delay between receipt of a HEARTBEAT indicating missing samples and a NACK (ignored when the HEARTBEAT requires an answer). However, no NACK is sent if a NACK had been scheduled already for a response earlier than the delay requests: then that NACK will incorporate the latest information.

    " }, - { LEAF ("PreEmptiveAckDelay"), 1, "10 ms", ABSOFF (preemptive_ack_delay), 0, uf_duration_ms_1hr, 0, pf_duration, - "

    This setting controls the delay between the discovering a remote writer and sending a pre-emptive AckNack to discover the range of data available.

    " }, - { LEAF ("ScheduleTimeRounding"), 1, "0 ms", ABSOFF (schedule_time_rounding), 0, uf_duration_ms_1hr, 0, pf_duration, - "

    This setting allows the timing of scheduled events to be rounded up so that more events can be handled in a single cycle of the event queue. The default is 0 and causes no rounding at all, i.e. are scheduled exactly, whereas a value of 10ms would mean that events are rounded up to the nearest 10 milliseconds.

    " }, - { LEAF ("DDSI2DirectMaxThreads"), 1, "1", ABSOFF (ddsi2direct_max_threads), 0, uf_uint, 0, pf_uint, - "

    This element sets the maximum number of extra threads for an experimental, undocumented and unsupported direct mode.

    " }, - { LEAF ("SquashParticipants"), 1, "false", ABSOFF (squash_participants), 0, uf_boolean, 0, pf_boolean, - "

    This element controls whether DDSI2 advertises all the domain participants it serves in DDSI (when set to false), or rather only one domain participant (the one corresponding to the DDSI2 process; when set to true). In the latter case DDSI2 becomes the virtual owner of all readers and writers of all domain participants, dramatically reducing discovery traffic (a similar effect can be obtained by setting Internal/BuiltinEndpointSet to \"minimal\" but with less loss of information).

    " }, - { LEAF ("LegacyFragmentation"), 1, "false", ABSOFF (buggy_datafrag_flags_mode), 0, uf_boolean, 0, pf_boolean, - "

    This option enables a backwards-compatible, non-compliant setting and interpretation of the control flags in fragmented data messages. To be enabled only when requiring interoperability between compliant and non-compliant versions of DDSI2 for large messages.

    " }, - { LEAF ("SPDPResponseMaxDelay"), 1, "0 ms", ABSOFF (spdp_response_delay_max), 0, uf_duration_ms_1s, 0, pf_duration, - "

    Maximum pseudo-random delay in milliseconds between discovering a remote participant and responding to it.

    " }, - { LEAF ("LateAckMode"), 1, "false", ABSOFF (late_ack_mode), 0, uf_boolean, 0, pf_boolean, - "

    Ack a sample only when it has been delivered, instead of when committed to delivering it.

    " }, - { LEAF ("ForwardAllMessages"), 1, "false", ABSOFF (forward_all_messages), 0, uf_boolean, 0, pf_boolean, - "

    Forward all messages from a writer, rather than trying to forward each sample only once. The default of trying to forward each sample only once filters out duplicates for writers in multiple partitions under nearly all circumstances, but may still publish the odd duplicate. Note: the current implementation also can lose in contrived test cases, that publish more than 2**32 samples using a single data writer in conjunction with carefully controlled management of the writer history via cooperating local readers.

    " }, - { LEAF ("RetryOnRejectDuration"), 1, "default", ABSOFF (retry_on_reject_duration), 0, uf_maybe_duration_inf, 0, pf_maybe_duration, - "

    How long to keep locally retrying pushing a received sample into the reader caches when resource limits are reached. Default is dependent on Internal/LateAckMode: if the latter is false, it is 80% of Internal/ResponsivenessTimeout, otherwise it is 0.

    " }, - { LEAF ("RetryOnRejectBestEffort"), 1, "false", ABSOFF (retry_on_reject_besteffort), 0, uf_boolean, 0, pf_boolean, - "

    Whether or not to locally retry pushing a received best-effort sample into the reader caches when resource limits are reached.

    " }, - { LEAF ("GenerateKeyhash"), 1, "true", ABSOFF (generate_keyhash), 0, uf_boolean, 0, pf_boolean, - "

    When true, include keyhashes in outgoing data for topics with keys.

    " }, - { LEAF ("MaxSampleSize"), 1, "2147483647 B", ABSOFF (max_sample_size), 0, uf_memsize, 0, pf_memsize, - "

    This setting controls the maximum (CDR) serialised size of samples that DDSI2 will forward in either direction. Samples larger than this are discarded with a warning.

    " }, - { LEAF ("LogStackTraces"), 1, "true", ABSOFF (noprogress_log_stacktraces), 0, uf_boolean, 0, pf_boolean, - "

    This element controls whether or not to write stack traces to the DDSI2 trace when a thread fails to make progress (on select platforms only).

    " }, - { LEAF ("MonitorPort"), 1, "-1", ABSOFF (monitor_port), 0, uf_int, 0, pf_int, - "

    This element allows configuring a service that dumps a text description of part the internal state to TCP clients. By default (-1), this is disabled; specifying 0 means a kernel-allocated port is used; a positive number is used as the TCP port number.

    " }, - { LEAF ("AssumeMulticastCapable"), 1, "", ABSOFF (assumeMulticastCapable), 0, uf_string, ff_free, pf_string, - "

    This element controls which network interfaces are assumed to be capable of multicasting even when the interface flags returned by the operating system state it is not (this provides a workaround for some platforms). It is a comma-separated lists of patterns (with ? and * wildcards) against which the interface names are matched.

    " }, - { LEAF ("PrioritizeRetransmit"), 1, "true", ABSOFF (prioritize_retransmit), 0, uf_boolean, 0, pf_boolean, - "

    This element controls whether retransmits are prioritized over new data, speeding up recovery.

    " }, - { LEAF ("UseMulticastIfMreqn"), 1, "0", ABSOFF (use_multicast_if_mreqn), 0, uf_int, 0, pf_int, - "

    Do not use.

    " }, - { LEAF_W_ATTRS ("RediscoveryBlacklistDuration", rediscovery_blacklist_duration_attrs), 1, "10s", ABSOFF (prune_deleted_ppant.delay), 0, uf_duration_inf, 0, pf_duration, - "

    This element controls for how long a remote participant that was previously deleted will remain on a blacklist to prevent rediscovery, giving the software on a node time to perform any cleanup actions it needs to do. To some extent this delay is required internally by DDSI2, but in the default configuration with the 'enforce' attribute set to false, DDSI2 will reallow rediscovery as soon as it has cleared its internal administration. Setting it to too small a value may result in the entry being pruned from the blacklist before DDSI2 is ready, it is therefore recommended to set it to at least several seconds.

    " }, - { MGROUP ("ControlTopic", control_topic_cfgelems, control_topic_cfgattrs), 1, 0, 0, 0, 0, 0, 0, 0, - "

    The ControlTopic element allows configured whether DDSI2 provides a special control interface via a predefined topic or not.

    " }, - { GROUP ("Test", unsupp_test_cfgelems), - "

    Testing options.

    " }, - { GROUP ("Watermarks", unsupp_watermarks_cfgelems), - "

    Watermarks for flow-control.

    " }, - END_MARKER -}; - -static const struct cfgelem sizing_cfgelems[] = -{ - { LEAF ("ReceiveBufferSize"), 1, "1 MiB", ABSOFF (rbuf_size), 0, uf_memsize, 0, pf_memsize, - "

    This element sets the size of a single receive buffer. Many receive buffers may be needed. Their size must be greater than ReceiveBufferChunkSize by a modest amount.

    " }, - { LEAF ("ReceiveBufferChunkSize"), 1, "128 KiB", ABSOFF (rmsg_chunk_size), 0, uf_memsize, 0, pf_memsize, - "

    This element specifies the size of one allocation unit in the receive buffer. Must be greater than the maximum packet size by a modest amount (too large packets are dropped). Each allocation is shrunk immediately after processing a message, or freed straightaway.

    " }, - { LEAF ("LocalEndpoints"), 1, "1000", ABSOFF (gid_hash_softlimit), 0, uf_uint32, 0, pf_uint32, - "

    This element specifies the expected maximum number of endpoints local to one DDSI2 service. Underestimating this number will have a significant performance impact, but will not affect correctness; signficantly overestimating it will cause more memory to be used than necessary.

    " }, - { LEAF ("EndpointsInSystem"), 1, "20000", ABSOFF (guid_hash_softlimit), 0, uf_uint32, 0, pf_uint32, - "

    This endpoint specifies the expected maximum number of endpoints in the network. Underestimating this number will have a significant performance impact, but will not affect correctness; signficantly overestimating it will cause more memory to be used than necessary.

    " }, - { LEAF ("NetworkQueueSize"), 1, "1000", ABSOFF (nw_queue_size), 0, uf_uint, 0, pf_uint, - "

    This element specifies the maximum number of samples in the network queue. Write/dispose operations add samples to this queue, the DDSI2 service drains it. Larger values allow large bursts of writes to occur without forcing synchronization between the application and the DDSI2 service, but do introduce the potential for longer latencies and increase the maximum amount of memory potentially occupied by messages in the queue.

    " }, - END_MARKER -}; - -static const struct cfgelem discovery_ports_cfgelems[] = { - { LEAF ("Base"), 1, "7400", ABSOFF (port_base), 0, uf_port, 0, pf_int, - "

    This element specifies the base port number (refer to the DDSI 2.1 specification, section 9.6.1, constant PB).

    " }, - { LEAF ("DomainGain"), 1, "250", ABSOFF (port_dg), 0, uf_int, 0, pf_int, - "

    This element specifies the domain gain, relating domain ids to sets of port numbers (refer to the DDSI 2.1 specification, section 9.6.1, constant DG).

    " }, - { LEAF ("ParticipantGain"), 1, "2", ABSOFF (port_pg), 0, uf_int, 0, pf_int, - "

    This element specifies the participant gain, relating p0, articipant index to sets of port numbers (refer to the DDSI 2.1 specification, section 9.6.1, constant PG).

    " }, - { LEAF ("MulticastMetaOffset"), 1, "0", ABSOFF (port_d0), 0, uf_int, 0, pf_int, - "

    This element specifies the port number for multicast meta traffic (refer to the DDSI 2.1 specification, section 9.6.1, constant d0).

    " }, - { LEAF ("UnicastMetaOffset"), 1, "10", ABSOFF (port_d1), 0, uf_int, 0, pf_int, - "

    This element specifies the port number for unicast meta traffic (refer to the DDSI 2.1 specification, section 9.6.1, constant d1).

    " }, - { LEAF ("MulticastDataOffset"), 1, "1", ABSOFF (port_d2), 0, uf_int, 0, pf_int, - "

    This element specifies the port number for multicast meta traffic (refer to the DDSI 2.1 specification, section 9.6.1, constant d2).

    " }, - { LEAF ("UnicastDataOffset"), 1, "11", ABSOFF (port_d3), 0, uf_int, 0, pf_int, - "

    This element specifies the port number for unicast meta traffic (refer to the DDSI 2.1 specification, section 9.6.1, constant d3).

    " }, - END_MARKER -}; - -static const struct cfgelem tcp_cfgelems[] = { - { LEAF ("Enable"), 1, "false", ABSOFF (tcp_enable), 0, uf_boolean, 0, pf_boolean, - "

    This element enables the optional TCP transport.

    " }, - { LEAF ("NoDelay"), 1, "true", ABSOFF (tcp_nodelay), 0, uf_boolean, 0, pf_boolean, - "

    This element enables the TCP_NODELAY socket option, preventing multiple DDSI messages being sent in the same TCP request. Setting this option typically optimises latency over throughput.

    " }, - { LEAF ("Port"), 1, "-1", ABSOFF (tcp_port), 0, uf_dyn_port, 0, pf_int, - "

    This element specifies the TCP port number on which DDSI2 accepts connections. If the port is set it is used in entity locators, published with DDSI discovery. Dynamically allocated if zero. Disabled if -1 or not configured. If disabled other DDSI services will not be able to establish connections with the service, the service can only communicate by establishing connections to other services.

    " }, - { LEAF ("ReadTimeout"), 1, "2 s", ABSOFF (tcp_read_timeout), 0, uf_duration_ms_1hr, 0, pf_duration, - "

    This element specifies the timeout for blocking TCP read operations. If this timeout expires then the connection is closed.

    " }, - { LEAF ("WriteTimeout"), 1, "2 s", ABSOFF (tcp_write_timeout), 0, uf_duration_ms_1hr, 0, pf_duration, - "

    This element specifies the timeout for blocking TCP write operations. If this timeout expires then the connection is closed.

    " }, - END_MARKER -}; - -#ifdef DDSI_INCLUDE_SSL -static const struct cfgelem ssl_cfgelems[] = { - { LEAF ("Enable"), 1, "false", ABSOFF (ssl_enable), 0, uf_boolean, 0, pf_boolean, - "

    This enables SSL/TLS for TCP.

    " }, - { LEAF ("CertificateVerification"), 1, "true", ABSOFF (ssl_verify), 0, uf_boolean, 0, pf_boolean, - "

    If disabled this allows SSL connections to occur even if an X509 certificate fails verification.

    " }, - { LEAF ("VerifyClient"), 1, "false", ABSOFF (ssl_verify_client), 0, uf_boolean, 0, pf_boolean, - "

    This enables an SSL server checking the X509 certificate of a connecting client.

    " }, - { LEAF ("SelfSignedCertificates"), 1, "false", ABSOFF (ssl_self_signed), 0, uf_boolean, 0, pf_boolean, - "

    This enables the use of self signed X509 certificates.

    " }, - { LEAF ("KeystoreFile"), 1, "keystore", ABSOFF (ssl_keystore), 0, uf_string, ff_free, pf_string, - "

    The SSL/TLS key and certificate store file name. The keystore must be in PEM format.

    " }, - { LEAF ("KeyPassphrase"), 1, "secret", ABSOFF (ssl_key_pass), 0, uf_string, ff_free, pf_string, - "

    The SSL/TLS key pass phrase for encrypted keys.

    " }, - { LEAF ("Ciphers"), 1, "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH", ABSOFF (ssl_ciphers), 0, uf_string, ff_free, pf_string, - "

    The set of ciphers used by SSL/TLS

    " }, - { LEAF ("EntropyFile"), 1, "", ABSOFF (ssl_rand_file), 0, uf_string, ff_free, pf_string, - "

    The SSL/TLS random entropy file name.

    " }, - END_MARKER -}; -#endif - -static const struct cfgelem tp_cfgelems[] = { - { LEAF ("Enable"), 1, "false", ABSOFF (tp_enable), 0, uf_boolean, 0, pf_boolean, - "

    This element enables the optional thread pool.

    " }, - { LEAF ("Threads"), 1, "4", ABSOFF (tp_threads), 0, uf_natint, 0, pf_int, - "

    This elements configures the initial number of threads in the thread pool.

    " }, - { LEAF ("ThreadMax"), 1, "8", ABSOFF (tp_max_threads), 0, uf_natint, 0, pf_int, - "

    This elements configures the maximum number of threads in the thread pool.

    " }, - END_MARKER -}; - -static const struct cfgelem discovery_peer_cfgattrs[] = { - { ATTR ("Address"), 1, NULL, RELOFF (config_peer_listelem, peer), 0, uf_ipv4, ff_free, pf_string, - "

    This element specifies an IP address to which discovery packets must be sent, in addition to the default multicast address (see also General/AllowMulticast). Both a hostnames and a numerical IP address is accepted; the hostname or IP address may be suffixed with :PORT to explicitly set the port to which it must be sent. Multiple Peers may be specified.

    " }, - END_MARKER -}; - -static const struct cfgelem discovery_peers_group_cfgelems[] = { - { MGROUP ("Peer", NULL, discovery_peer_cfgattrs), 0, NULL, ABSOFF (peers_group), if_peer, 0, 0, 0, - "

    This element statically configures an addresses for discovery.

    " }, - END_MARKER -}; - -static const struct cfgelem discovery_peers_cfgelems[] = { - { MGROUP ("Peer", NULL, discovery_peer_cfgattrs), 0, NULL, ABSOFF (peers), if_peer, 0, 0, 0, - "

    This element statically configures an addresses for discovery.

    " }, - { GROUP ("Group", discovery_peers_group_cfgelems), - "

    This element statically configures a fault tolerant group of addresses for discovery. Each member of the group is tried in sequence until one succeeds.

    " }, - END_MARKER -}; - -static const struct cfgelem discovery_cfgelems[] = { - { LEAF ("DomainId"), 1, "default", ABSOFF (discoveryDomainId), 0, uf_maybe_int32, 0, pf_maybe_int32, - "

    This element allows overriding of the DDS Domain Id that is used for DDSI2.

    " }, - { LEAF ("LocalDiscoveryPartition"), 1, "__BUILT-IN PARTITION__", ABSOFF (local_discovery_partition), 0, uf_string, ff_free, pf_string, - "

    This element controls which partition is monitored by DDSI2 for built-in topics describing entities the it mirrors in DDSI.

    " }, - { LEAF ("GenerateBuiltinTopics"), 1, "true", ABSOFF (generate_builtin_topics), 0, uf_boolean, 0, pf_boolean, - "

    This element controls whether or not DDSI2 generates built-in topics from its discovery. When disabled, it relies on the durability service.

    " }, - { LEAF ("AdvertiseBuiltinTopicWriters"), 1, "true", ABSOFF (advertise_builtin_topic_writers), 0, uf_boolean, 0, pf_boolean, - "

    This element controls whether or not DDSI2 advertises writers for the built-in topics from its discovery for backwards compatibility with older OpenSplice versions.

    " }, - { GROUP ("Peers", discovery_peers_cfgelems), - "

    This element statically configures addresses for discovery.

    " }, - { LEAF ("ParticipantIndex"), 1, "auto", ABSOFF (participantIndex), 0, uf_participantIndex, 0, pf_participantIndex, - "

    This element specifies the DDSI participant index used by this instance of the DDSI2 service for discovery purposes. Only one such participant id is used, independent of the number of actual DomainParticipants on the node. It is either:

    \n\ -
    • auto: which will attempt to automatically determine an available participant index (see also Discovery/MaxAutoParticipantIndex), or
    • \n\ -
    • a non-negative integer less than 120, or
    • \n\ -
    • none:, which causes it to use arbitrary port numbers for unicast sockets which entirely removes the constraints on the participant index but makes unicast discovery impossible.
    \n\ -

    The default is auto. The participant index is part of the port number calculation and if predictable port numbers are needed and fixing the participant index has no adverse effects, it is recommended that the second be option be used.

    " }, - { LEAF ("MaxAutoParticipantIndex"), 1, "9", ABSOFF (maxAutoParticipantIndex), 0, uf_natint, 0, pf_int, - "

    This element specifies the maximum DDSI participant index selected by this instance of the DDSI2 service if the Discovery/ParticipantIndex is \"auto\".

    " }, - { LEAF ("SPDPMulticastAddress"), 1, "239.255.0.1", ABSOFF (spdpMulticastAddressString), 0, uf_ipv4, ff_free, pf_string, - "

    This element specifies the multicast address that is used as the destination for the participant discovery packets. In IPv4 mode the default is the (standardised) 239.255.0.1, in IPv6 mode it becomes ff02::ffff:239.255.0.1, which is a non-standardised link-local multicast address.

    " }, - { LEAF ("SPDPInterval"), 1, "30 s", ABSOFF (spdp_interval), 0, uf_duration_ms_1hr, 0, pf_duration, - "

    This element specifies the interval between spontaneous transmissions of participant discovery packets.

    " }, - { LEAF ("DefaultMulticastAddress"), 1, "auto", ABSOFF (defaultMulticastAddressString), 0, uf_networkAddress, 0, pf_networkAddress, - "

    This element specifies the default multicast address for all traffic other than participant discovery packets. It defaults to Discovery/SPDPMulticastAddress.

    " }, - { GROUP ("Ports", discovery_ports_cfgelems), - "

    The Ports element allows specifying various parameters related to the port numbers used for discovery. These all have default values specified by the DDSI 2.1 specification and rarely need to be changed.

    " }, - END_MARKER -}; - -static const struct cfgelem tracing_cfgelems[] = { - { LEAF ("EnableCategory"), 1, "", 0, 0, 0, uf_logcat, 0, pf_logcat, - "

    This element enables individual logging categories. These are enabled in addition to those enabled by Tracing/Verbosity. Recognised categories are:

    \n\ -
    • fatal: all fatal errors, errors causing immediate termination
    • \n\ -
    • error: failures probably impacting correctness but not necessarily causing immediate termination
    • \n\ -
    • warning: abnormal situations that will likely not impact correctness
    • \n\ -
    • config: full dump of the configuration
    • \n\ -
    • info: general informational notices
    • \n\ -
    • discovery: all discovery activity
    • \n\ -
    • data: include data content of samples in traces
    • \n\ -
    • radmin: receive buffer administration
    • \n\ -
    • timing: periodic reporting of CPU loads per thread
    • \n\ -
    • traffic: periodic reporting of total outgoing data
    • \n\ -
    • whc: tracing of writer history cache changes
    • \n\ -
    • tcp: tracing of TCP-specific activity
    • \n\ -
    • topic: tracing of topic definitions
    • \n\ -
    • >i>plist: tracing of discovery parameter list interpretation
    \n\ -

    In addition, there is the keyword trace that enables all but radmin, topic, plist and whc

    .\n\ -

    The categorisation of tracing output is incomplete and hence most of the verbosity levels and categories are not of much use in the current release. This is an ongoing process and here we describe the target situation rather than the current situation. Currently, the most useful is trace.

    " }, - { LEAF ("Verbosity"), 1, "none", 0, 0, 0, uf_verbosity, 0, pf_nop, - "

    This element enables standard groups of categories, based on a desired verbosity level. This is in addition to the categories enabled by the Tracing/EnableCategory setting. Recognised verbosity levels and the categories they map to are:

    \n\ -
    • none: no DDSI2 log
    • \n\ -
    • severe: error and fatal
    • \n\ -
    • warning: severe + warning
    • \n\ -
    • info: warning + info
    • \n\ -
    • config: info + config
    • \n\ -
    • fine: config + discovery
    • \n\ -
    • finer: fine + traffic and timing
    • \n\ -
    • finest: finer + trace
    \n\ -

    The categorisation of tracing output is incomplete and hence most of the verbosity levels and categories are not of much use in the current release. This is an ongoing process and here we describe the target situation rather than the current situation. Currently, the most useful verbosity levels are config, fine and finest.

    " }, - { LEAF ("OutputFile"), 1, "ddsi2.log", ABSOFF (tracingOutputFileName), 0, uf_tracingOutputFileName, ff_free, pf_string, - "

    This option specifies where the logging is printed to. Note that stdout and stderr are treated as special values, representing \"standard out\" and \"standard error\" respectively. No file is created unless logging categories are enabled using the Tracing/Verbosity or Tracing/EnabledCategory settings.

    "}, - { LEAF_W_ATTRS ("Timestamps", timestamp_cfgattrs), 1, "true", ABSOFF (tracingTimestamps), 0, uf_boolean, 0, pf_boolean, - "

    This option has no effect.

    " }, - { LEAF ("AppendToFile"), 1, "false", ABSOFF (tracingAppendToFile), 0, uf_boolean, 0, pf_boolean, - "

    This option specifies whether the output is to be appended to an existing log file. The default is to create a new log file each time, which is generally the best option if a detailed log is generated.

    " }, - { LEAF ("PacketCaptureFile"), 1, "", ABSOFF (pcap_file), 0, uf_string, ff_free, pf_string, - "

    This option specifies the file to which received and sent packets will be logged in the \"pcap\" format suitable for analysis using common networking tools, such as WireShark. IP and UDP headers are ficitious, in particular the destination address of received packets. The TTL may be used to distinguish between sent and received packets: it is 255 for sent packets and 128 for received ones. Currently IPv4 only.

    " }, - END_MARKER -}; - -static const struct cfgelem sched_prio_cfgattrs[] = { - { ATTR ("priority_kind"), 1, "relative", ABSOFF (watchdog_sched_priority_class), 0, uf_sched_prio_class, 0, pf_sched_prio_class, - "

    This attribute specifies whether the specified Priority is a relative or absolute priority.

    " }, - END_MARKER -}; - -static const struct cfgelem sched_cfgelems[] = { - { LEAF ("Class"), 1, "default", ABSOFF (watchdog_sched_class), 0, uf_sched_class, 0, pf_sched_class, - "

    This element specifies the thread scheduling class that will be used by the watchdog thread. The user may need the appropriate privileges from the underlying operating system to be able to assign some of the privileged scheduling classes.

    " }, - { LEAF_W_ATTRS ("Priority", sched_prio_cfgattrs), 1, "0", ABSOFF (watchdog_sched_priority), 0, uf_int32, 0, pf_int32, - "

    This element specifies the thread priority. Only priorities that are supported by the underlying operating system can be assigned to this element. The user may need special privileges from the underlying operating system to be able to assign some of the privileged priorities.

    " }, - END_MARKER -}; - -static const struct cfgelem watchdog_cfgelems[] = { - { GROUP ("Scheduling", sched_cfgelems), - "

    This element specifies the type of OS scheduling class will be used by the thread that announces its liveliness periodically.

    " }, - END_MARKER -}; - -static const struct cfgelem ddsi2_cfgelems[] = { - { GROUP ("General", general_cfgelems), - "

    The General element specifies overall DDSI2 service settings.

    " }, - { GROUP ("Threads", threads_cfgelems), - "

    This element is used to set thread properties.

    " }, - { GROUP ("Sizing", sizing_cfgelems), - "

    The Sizing element specifies a variety of configuration settings dealing with expected system sizes, buffer sizes, &c.

    " }, - { GROUP ("Compatibility", compatibility_cfgelems), - "

    The Compatibility elements allows specifying various settings related to compatability with standards and with other DDSI implementations.

    " }, - { GROUP ("Discovery", discovery_cfgelems), - "

    The Discovery element allows specifying various parameters related to the discovery of peers.

    " }, - { GROUP ("Tracing", tracing_cfgelems), - "

    The Tracing element controls the amount and type of information that is written into the tracing log by the DDSI service. This is useful to track the DDSI service during application development.

    " }, - { GROUP ("Internal|Unsupported", unsupp_cfgelems), - "

    The Internal elements deal with a variety of settings that evolving and that are not necessarily fully supported. For the vast majority of the Internal settings, the functionality per-se is supported, but the right to change the way the options control the functionality is reserved. This includes renaming or moving options.

    " }, - { GROUP ("Watchdog", watchdog_cfgelems), - "

    This element specifies the type of OS scheduling class will be used by the thread that announces its liveliness periodically.

    " }, - { GROUP ("TCP", tcp_cfgelems), - "

    The TCP element allows specifying various parameters related to running DDSI over TCP.

    " }, - { GROUP ("ThreadPool", tp_cfgelems), - "

    The ThreadPool element allows specifying various parameters related to using a thread pool to send DDSI messages to multiple unicast addresses (TCP or UDP).

    " }, -#ifdef DDSI_INCLUDE_SSL - { GROUP ("SSL", ssl_cfgelems), - "

    The SSL element allows specifying various parameters related to using SSL/TLS for DDSI over TCP.

    " }, -#endif - END_MARKER -}; - -/* Note: using 2e-1 instead of 0.2 to avoid use of the decimal - separator, which is locale dependent. */ -static const struct cfgelem lease_expiry_time_cfgattrs[] = { - { ATTR ("update_factor"), 1, "2e-1", ABSOFF (servicelease_update_factor), 0, uf_float, 0, pf_float, NULL }, - END_MARKER -}; - -static const struct cfgelem lease_cfgelems[] = { - { LEAF_W_ATTRS ("ExpiryTime", lease_expiry_time_cfgattrs), 1, "10", ABSOFF (servicelease_expiry_time), 0, uf_float, 0, pf_float, NULL }, - END_MARKER -}; - - -static const struct cfgelem domain_cfgelems[] = { - { GROUP ("Lease", lease_cfgelems), NULL }, - { LEAF ("Id"), 1, "0", ABSOFF (domainId), 0, uf_domainId, 0, pf_int, NULL }, - WILDCARD, - END_MARKER -}; - -static const struct cfgelem ddsi2_cfgattrs[] = { - { ATTR ("name"), 1, NULL, ABSOFF (servicename), 0, uf_service_name, ff_free, pf_string, - "

    This attribute identifies the configuration for the DDSI2 Service. Multiple DDSI2 service configurations can be specified in one single resource. The actual applicable configuration is determined by the value of the name attribute, which must match the specified under the element OpenSplice/Domain/Service[@name] in the Domain Service configuration.

    " }, - END_MARKER -}; - -static const struct cfgelem root_cfgelems[] = { - { "DDSI2Service", ddsi2_cfgelems, ddsi2_cfgattrs, NODATA, - "

    The root element of a DDSI2 networking service configuration.

    "}, - { "Lease", lease_cfgelems, NULL, NODATA, NULL }, - { "Domain", domain_cfgelems, NULL, NODATA, NULL }, - END_MARKER -}; - -static const struct cfgelem root_cfgelem = - { "root", root_cfgelems, NULL, NODATA, NULL }; - - -#undef ATTR -#undef GROUP -#undef LEAF_W_ATTRS -#undef LEAF -#undef WILDCARD -#undef END_MARKER -#undef NODATA -#undef RELOFF -#undef ABSOFF -#undef CO - -struct config config; -struct ddsi_plugin ddsi_plugin; - -static const struct unit unittab_duration[] = { - { "ns", 1 }, - { "us", 1000 }, - { "ms", T_MILLISECOND }, - { "s", T_SECOND }, - { "min", 60 * T_SECOND }, - { "hr", 3600 * T_SECOND }, - { "day", 24 * 3600 * T_SECOND }, - { NULL, 0 } -}; - -/* note: order affects whether printed as KiB or kB, for consistency - with bandwidths and pedanticness, favour KiB. */ -static const struct unit unittab_memsize[] = { - { "B", 1 }, - { "KiB", 1024 }, - { "kB", 1024 }, - { "MiB", 1048576 }, - { "MB", 1048576 }, - { "GiB", 1073741824 }, - { "GB", 1073741824 }, - { NULL, 0 } -}; - - -static void cfgst_push (struct cfgst *cfgst, int isattr, const struct cfgelem *elem, void *parent) -{ - assert (cfgst->path_depth < MAX_PATH_DEPTH); - assert (isattr == 0 || isattr == 1); - cfgst->isattr[cfgst->path_depth] = isattr; - cfgst->path[cfgst->path_depth] = elem; - cfgst->parent[cfgst->path_depth] = parent; - cfgst->path_depth++; -} - -static void cfgst_pop (struct cfgst *cfgst) -{ - assert (cfgst->path_depth > 0); - cfgst->path_depth--; -} - -static const struct cfgelem *cfgst_tos (const struct cfgst *cfgst) -{ - assert (cfgst->path_depth > 0); - return cfgst->path[cfgst->path_depth-1]; -} - -static void *cfgst_parent (const struct cfgst *cfgst) -{ - assert (cfgst->path_depth > 0); - return cfgst->parent[cfgst->path_depth-1]; -} - -struct cfg_note_buf { - size_t bufpos; - size_t bufsize; - char *buf; -}; - -static size_t cfg_note_vsnprintf (struct cfg_note_buf *bb, const char *fmt, va_list ap) -{ - int x; - x = os_vsnprintf (bb->buf + bb->bufpos, bb->bufsize - bb->bufpos, fmt, ap); - if (x >= 0 && (size_t) x >= bb->bufsize - bb->bufpos) - { - size_t nbufsize = ((bb->bufsize + (size_t)x+1) + 1023) & (size_t)(-1024); - char *nbuf = os_realloc (bb->buf, nbufsize); - bb->buf = nbuf; - bb->bufsize = nbufsize; - return nbufsize; - } - if (x < 0) - NN_FATAL0 ("cfg_note_vsnprintf: os_vsnprintf failed\n"); - else - bb->bufpos += (size_t)x; - return 0; -} - -static void cfg_note_snprintf (struct cfg_note_buf *bb, const char *fmt, ...) -{ - /* The reason the 2nd call to os_vsnprintf is here and not inside - cfg_note_vsnprintf is because I somehow doubt that all platforms - implement va_copy() */ - va_list ap; - size_t r; - va_start (ap, fmt); - r = cfg_note_vsnprintf (bb, fmt, ap); - va_end (ap); - if (r > 0) - { - int s; - va_start (ap, fmt); - s = os_vsnprintf (bb->buf + bb->bufpos, bb->bufsize - bb->bufpos, fmt, ap); - if (s < 0 || (size_t)s >= bb->bufsize - bb->bufpos) - NN_FATAL0 ("cfg_note_snprintf: os_vsnprintf failed\n"); - va_end (ap); - bb->bufpos += (size_t)s; - } -} - -static size_t cfg_note (struct cfgst *cfgst, logcat_t cat, size_t bsz, const char *fmt, va_list ap) -{ - /* Have to snprintf our way to a single string so we can OS_REPORT - as well as nn_log. Otherwise configuration errors will be lost - completely on platforms where stderr doesn't actually work for - outputting error messages (this includes Windows because of the - way "ospl start" does its thing). */ - struct cfg_note_buf bb; - int i, sidx; - size_t r; - - bb.bufpos = 0; - bb.bufsize = (bsz == 0) ? 1024 : bsz; - if ((bb.buf = os_malloc (bb.bufsize)) == NULL) - NN_FATAL0 ("cfg_note: out of memory\n"); - - cfg_note_snprintf (&bb, "config: "); - - /* Path to element/attribute causing the error. Have to stop once an - attribute is reached: a NULL marker may have been pushed onto the - stack afterward in the default handling. */ - sidx = 0; - while (sidx < cfgst->path_depth && cfgst->path[sidx]->name == NULL) - sidx++; - for (i = sidx; i < cfgst->path_depth && (i == sidx || !cfgst->isattr[i-1]); i++) - { - if (cfgst->path[i] == NULL) - { - assert (i > sidx); - cfg_note_snprintf (&bb, "/#text"); - } - else if (cfgst->isattr[i]) - { - cfg_note_snprintf (&bb, "[@%s]", cfgst->path[i]->name); - } - else - { - const char *p = strchr (cfgst->path[i]->name, '|'); - int n = p ? (int) (p - cfgst->path[i]->name) : (int) strlen (cfgst->path[i]->name); - cfg_note_snprintf (&bb, "%s%*.*s", (i == sidx) ? "" : "/", n, n, cfgst->path[i]->name); - } - } - - cfg_note_snprintf (&bb, ": "); - if ((r = cfg_note_vsnprintf (&bb, fmt, ap)) > 0) - { - /* Can't reset ap ... and va_copy isn't widely available - so - instead abort and hope the caller tries again with a larger - initial buffer */ - os_free (bb.buf); - return r; - } - - switch (cat) - { - case LC_CONFIG: - nn_log (cat, "%s\n", bb.buf); - break; - case LC_WARNING: - NN_WARNING1 ("%s\n", bb.buf); - break; - case LC_ERROR: - NN_ERROR1 ("%s\n", bb.buf); - break; - default: - NN_FATAL2 ("cfg_note unhandled category %u for message %s\n", (unsigned) cat, bb.buf); - break; - } - - os_free (bb.buf); - return 0; -} - -#if WARN_DEPRECATED_ALIAS || WARN_DEPRECATED_UNIT -static void cfg_warning (struct cfgst *cfgst, const char *fmt, ...) -{ - va_list ap; - size_t bsz = 0; - do { - va_start (ap, fmt); - bsz = cfg_note (cfgst, LC_WARNING, bsz, fmt, ap); - va_end (ap); - } while (bsz > 0); -} -#endif - -static int cfg_error (struct cfgst *cfgst, const char *fmt, ...) -{ - va_list ap; - size_t bsz = 0; - do { - va_start (ap, fmt); - bsz = cfg_note (cfgst, LC_ERROR, bsz, fmt, ap); - va_end (ap); - } while (bsz > 0); - return 0; -} - -static int cfg_log (struct cfgst *cfgst, const char *fmt, ...) -{ - va_list ap; - size_t bsz = 0; - do { - va_start (ap, fmt); - bsz = cfg_note (cfgst, LC_CONFIG, bsz, fmt, ap); - va_end (ap); - } while (bsz > 0); - return 0; -} - -static int list_index (const char *list[], const char *elem) -{ - int i; - for (i = 0; list[i] != NULL; i++) - { - if (os_strcasecmp (list[i], elem) == 0) - return i; - } - return -1; -} - -static os_int64 lookup_multiplier (struct cfgst *cfgst, const struct unit *unittab, const char *value, int unit_pos, int value_is_zero, os_int64 def_mult, int err_on_unrecognised) -{ - assert (0 <= unit_pos && (os_size_t) unit_pos <= strlen (value)); - while (value[unit_pos] == ' ') - unit_pos++; - if (value[unit_pos] == 0) - { - if (value_is_zero) - { - /* No matter what unit, 0 remains just that. For convenience, - always allow 0 to be specified without a unit */ - return 1; - } - else if (def_mult == 0 && err_on_unrecognised) - { - cfg_error (cfgst, "%s: unit is required", value); - return 0; - } - else - { -#if WARN_DEPRECATED_UNIT - cfg_warning (cfgst, "%s: use of default unit is deprecated", value); -#endif - return def_mult; - } - } - else - { - int i; - for (i = 0; unittab[i].name != NULL; i++) - { - if (strcmp (unittab[i].name, value + unit_pos) == 0) - return unittab[i].multiplier; - } - if (err_on_unrecognised) - cfg_error (cfgst, "%s: unrecognised unit", value + unit_pos); - return 0; - } -} - -static void *cfg_address (UNUSED_ARG (struct cfgst *cfgst), void *parent, struct cfgelem const * const cfgelem) -{ - assert (cfgelem->multiplicity == 1); - return (char *) parent + cfgelem->elem_offset; -} - -static void *cfg_deref_address (UNUSED_ARG (struct cfgst *cfgst), void *parent, struct cfgelem const * const cfgelem) -{ - assert (cfgelem->multiplicity != 1); - return *((void **) ((char *) parent + cfgelem->elem_offset)); -} - -static void *if_common (UNUSED_ARG (struct cfgst *cfgst), void *parent, struct cfgelem const * const cfgelem, unsigned size) -{ - struct config_listelem **current = (struct config_listelem **) ((char *) parent + cfgelem->elem_offset); - struct config_listelem *new = os_malloc (size); - new->next = *current; - *current = new; - return new; -} - -static int if_thread_properties (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem) -{ - struct config_thread_properties_listelem *new = if_common (cfgst, parent, cfgelem, sizeof (*new)); - if (new == NULL) - return -1; - new->name = NULL; - return 0; -} - - - - -static int if_peer (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem) -{ - struct config_peer_listelem *new = if_common (cfgst, parent, cfgelem, sizeof (struct config_peer_listelem)); - if (new == NULL) - return -1; - new->peer = NULL; - return 0; -} - -static void ff_free (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem) -{ - void **elem = cfg_address (cfgst, parent, cfgelem); - os_free (*elem); -} - -static int uf_boolean (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, UNUSED_ARG (int first), const char *value) -{ - static const char *vs[] = { "false", "true", NULL }; - int *elem = cfg_address (cfgst, parent, cfgelem); - int idx = list_index (vs, value); - if (idx < 0) - return cfg_error (cfgst, "'%s': undefined value", value); - else - { - *elem = idx; - return 1; - } -} - -static int uf_negated_boolean (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int first, const char *value) -{ - if (!uf_boolean (cfgst, parent, cfgelem, first, value)) - return 0; - else - { - int *elem = cfg_address (cfgst, parent, cfgelem); - *elem = ! *elem; - return 1; - } -} - -static int uf_boolean_default (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, UNUSED_ARG (int first), const char *value) -{ - static const char *vs[] = { "default", "false", "true", NULL }; - static const enum boolean_default ms[] = { - BOOLDEF_DEFAULT, BOOLDEF_FALSE, BOOLDEF_TRUE, 0, - }; - int *elem = cfg_address (cfgst, parent, cfgelem); - int idx = list_index (vs, value); - assert (sizeof (vs) / sizeof (*vs) == sizeof (ms) / sizeof (*ms)); - if (idx < 0) - return cfg_error (cfgst, "'%s': undefined value", value); - *elem = ms[idx]; - return 1; -} - -static void pf_boolean_default (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int is_default) -{ - enum besmode *p = cfg_address (cfgst, parent, cfgelem); - const char *str = "INVALID"; - switch (*p) - { - case BOOLDEF_DEFAULT: str = "default"; break; - case BOOLDEF_FALSE: str = "false"; break; - case BOOLDEF_TRUE: str = "true"; break; - } - cfg_log (cfgst, "%s%s", str, is_default ? " [def]" : ""); -} - -static int uf_logcat (struct cfgst *cfgst, UNUSED_ARG (void *parent), UNUSED_ARG (struct cfgelem const * const cfgelem), UNUSED_ARG (int first), const char *value) -{ - static const char **vs = logcat_names; - static const logcat_t *lc = logcat_codes; - char *copy = os_strdup (value), *cursor = copy, *tok; - while ((tok = os_strsep (&cursor, ",")) != NULL) - { - int idx = list_index (vs, tok); - if (idx < 0) - { - int ret = cfg_error (cfgst, "'%s' in '%s' undefined", tok, value); - os_free (copy); - return ret; - } - enabled_logcats |= lc[idx]; - } - os_free (copy); - return 1; -} - -static int uf_verbosity (struct cfgst *cfgst, UNUSED_ARG (void *parent), UNUSED_ARG (struct cfgelem const * const cfgelem), UNUSED_ARG (int first), const char *value) -{ - static const char *vs[] = { - "finest", "finer", "fine", "config", "info", "warning", "severe", "none", NULL - }; - static const logcat_t lc[] = { - LC_ALLCATS, LC_TRAFFIC | LC_TIMING, LC_DISCOVERY, LC_CONFIG, LC_INFO, LC_WARNING, LC_ERROR | LC_FATAL, 0, 0 - }; - int idx = list_index (vs, value); - assert (sizeof (vs) / sizeof (*vs) == sizeof (lc) / sizeof (*lc)); - if (idx < 0) - return cfg_error (cfgst, "'%s': undefined value", value); - else - { - int i; - for (i = (int) (sizeof (vs) / sizeof (*vs)) - 1; i >= idx; i--) - enabled_logcats |= lc[i]; - return 1; - } -} - -static int uf_besmode (struct cfgst *cfgst, UNUSED_ARG (void *parent), UNUSED_ARG (struct cfgelem const * const cfgelem), UNUSED_ARG (int first), const char *value) -{ - static const char *vs[] = { - "full", "writers", "minimal", NULL - }; - static const enum besmode ms[] = { - BESMODE_FULL, BESMODE_WRITERS, BESMODE_MINIMAL, 0, - }; - int idx = list_index (vs, value); - enum besmode *elem = cfg_address (cfgst, parent, cfgelem); - assert (sizeof (vs) / sizeof (*vs) == sizeof (ms) / sizeof (*ms)); - if (idx < 0) - return cfg_error (cfgst, "'%s': undefined value", value); - *elem = ms[idx]; - return 1; -} - -static void pf_besmode (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int is_default) -{ - enum besmode *p = cfg_address (cfgst, parent, cfgelem); - const char *str = "INVALID"; - switch (*p) - { - case BESMODE_FULL: str = "full"; break; - case BESMODE_WRITERS: str = "writers"; break; - case BESMODE_MINIMAL: str = "minimal"; break; - } - cfg_log (cfgst, "%s%s", str, is_default ? " [def]" : ""); -} - - -static int uf_retransmit_merging (struct cfgst *cfgst, UNUSED_ARG (void *parent), UNUSED_ARG (struct cfgelem const * const cfgelem), UNUSED_ARG (int first), const char *value) -{ - static const char *vs[] = { - "never", "adaptive", "always", NULL - }; - static const enum retransmit_merging ms[] = { - REXMIT_MERGE_NEVER, REXMIT_MERGE_ADAPTIVE, REXMIT_MERGE_ALWAYS, 0, - }; - int idx = list_index (vs, value); - enum retransmit_merging *elem = cfg_address (cfgst, parent, cfgelem); - assert (sizeof (vs) / sizeof (*vs) == sizeof (ms) / sizeof (*ms)); - if (idx < 0) - return cfg_error (cfgst, "'%s': undefined value", value); - *elem = ms[idx]; - return 1; -} - -static void pf_retransmit_merging (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int is_default) -{ - enum retransmit_merging *p = cfg_address (cfgst, parent, cfgelem); - const char *str = "INVALID"; - switch (*p) - { - case REXMIT_MERGE_NEVER: str = "never"; break; - case REXMIT_MERGE_ADAPTIVE: str = "adaptive"; break; - case REXMIT_MERGE_ALWAYS: str = "always"; break; - } - cfg_log (cfgst, "%s%s", str, is_default ? " [def]" : ""); -} - -static int uf_string (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, UNUSED_ARG (int first), const char *value) -{ - char **elem = cfg_address (cfgst, parent, cfgelem); - *elem = os_strdup (value); - return 1; -} - -static int uf_natint64_unit (struct cfgst *cfgst, os_int64 *elem, const char *value, const struct unit *unittab, os_int64 def_mult, os_int64 max) -{ - int pos; - double v_dbl; - os_int64 v_int; - os_int64 mult; - /* try convert as integer + optional unit; if that fails, try - floating point + optional unit (round, not truncate, to integer) */ - if (*value == 0) - { - *elem = 0; /* some static analyzers don't "get it" */ - return cfg_error (cfgst, "%s: empty string is not a valid value", value); - } - else if (sscanf (value, "%lld%n", (long long int *) &v_int, &pos) == 1 && (mult = lookup_multiplier (cfgst, unittab, value, pos, v_int == 0, def_mult, 0)) != 0) - { - assert (mult > 0); - if (v_int < 0 || v_int > max / mult) - return cfg_error (cfgst, "%s: value out of range", value); - *elem = mult * v_int; - return 1; - } - else if (sscanf (value, "%lf%n", &v_dbl, &pos) == 1 && (mult = lookup_multiplier (cfgst, unittab, value, pos, v_dbl == 0, def_mult, 1)) != 0) - { - double dmult = (double) mult; - assert (dmult > 0); - if (v_dbl < 0 || (os_int64) (v_dbl * dmult + 0.5) > max) - return cfg_error (cfgst, "%s: value out of range", value); - *elem = (os_int64) (v_dbl * dmult + 0.5); - return 1; - } - else - { - *elem = 0; /* some static analyzers don't "get it" */ - return cfg_error (cfgst, "%s: invalid value", value); - } -} - - -static int uf_memsize (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, UNUSED_ARG (int first), const char *value) -{ - os_int64 size = 0; - if (!uf_natint64_unit (cfgst, &size, value, unittab_memsize, 1, INT32_MAX)) - return 0; - else - { - os_uint32 *elem = cfg_address (cfgst, parent, cfgelem); - *elem = (os_uint32) size; - return 1; - } -} - - -static int uf_service_name (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, UNUSED_ARG (int first), const char *value) -{ - char **elem = cfg_address (cfgst, parent, cfgelem); - if (*value == 0) - *elem = os_strdup (cfgst->servicename); - else - *elem = os_strdup (value); - return 1; -} - -static int uf_tracingOutputFileName (struct cfgst *cfgst, UNUSED_ARG (void *parent), UNUSED_ARG (struct cfgelem const * const cfgelem), UNUSED_ARG (int first), const char *value) -{ - struct config *cfg = cfgst->cfg; - if (os_strcasecmp (value, "stdout") != 0 && os_strcasecmp (value, "stderr") != 0) - cfg->tracingOutputFileName = os_fileNormalize (value); - else - { - cfg->tracingOutputFileName = os_strdup (value); - } - return 1; -} - -static int uf_ipv4 (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int first, const char *value) -{ - /* Not actually doing any checking yet */ - return uf_string (cfgst, parent, cfgelem, first, value); -} - -static int uf_networkAddress (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int first, const char *value) -{ - if (os_strcasecmp (value, "auto") != 0) - return uf_ipv4 (cfgst, parent, cfgelem, first, value); - else - { - char **elem = cfg_address (cfgst, parent, cfgelem); - *elem = NULL; - return 1; - } -} - -static void ff_networkAddresses (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem) -{ - char ***elem = cfg_address (cfgst, parent, cfgelem); - int i; - for (i = 0; (*elem)[i]; i++) - os_free ((*elem)[i]); - os_free (*elem); -} - -static int uf_networkAddresses_simple (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, UNUSED_ARG (int first), const char *value) -{ - char ***elem = cfg_address (cfgst, parent, cfgelem); - if ((*elem = os_malloc (2 * sizeof(char *))) == NULL) - return cfg_error (cfgst, "out of memory"); - if (((*elem)[0] = os_strdup (value)) == NULL) - { - os_free (*elem); - *elem = NULL; - return cfg_error (cfgst, "out of memory"); - } - (*elem)[1] = NULL; - return 1; -} - -static int uf_networkAddresses (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int first, const char *value) -{ - /* Check for keywords first */ - { - static const char *keywords[] = { "all", "any", "none" }; - int i; - for (i = 0; i < (int) (sizeof (keywords) / sizeof (*keywords)); i++) - { - if (os_strcasecmp (value, keywords[i]) == 0) - return uf_networkAddresses_simple (cfgst, parent, cfgelem, first, keywords[i]); - } - } - - /* If not keyword, then comma-separated list of addresses */ - { - char ***elem = cfg_address (cfgst, parent, cfgelem); - char *copy; - unsigned count; - - /* First count how many addresses we have - but do it stupidly by - counting commas and adding one (so two commas in a row are both - counted) */ - { - const char *scan = value; - count = 1; - while (*scan) - count += (*scan++ == ','); - } - - copy = os_strdup (value); - - /* Allocate an array of address strings (which may be oversized a - bit because of the counting of the commas) */ - *elem = os_malloc ((count+1) * sizeof (char *)); - - { - char *cursor = copy, *tok; - unsigned idx = 0; - while ((tok = os_strsep (&cursor, ",")) != NULL) - { - assert (idx < count); - (*elem)[idx] = os_strdup (tok); - idx++; - } - (*elem)[idx] = NULL; - } - os_free (copy); - } - return 1; -} - -static int uf_allow_multicast (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, UNUSED_ARG (int first), const char *value) -{ - static const char *vs[] = { "false", "spdp", "asm", "true", NULL }; - static const unsigned bs[] = { AMC_FALSE, AMC_SPDP, AMC_ASM, AMC_TRUE }; - char *copy = os_strdup (value), *cursor = copy, *tok; - unsigned *elem = cfg_address (cfgst, parent, cfgelem); - if (copy == NULL) - return cfg_error (cfgst, "out of memory"); - *elem = 0; - while ((tok = os_strsep (&cursor, ",")) != NULL) - { - int idx = list_index (vs, tok); - if (idx < 0) - { - int ret = cfg_error (cfgst, "'%s' in '%s' undefined", tok, value); - os_free (copy); - return ret; - } - *elem |= bs[idx]; - } - os_free (copy); - return 1; -} - -static void pf_allow_multicast (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int is_default) -{ - unsigned *p = cfg_address (cfgst, parent, cfgelem); - const char *str = "INVALID"; - switch (*p) - { - case AMC_FALSE: str = "false"; break; - case AMC_SPDP: str = "spdp"; break; - case AMC_ASM: str = "asm"; break; - case AMC_TRUE: str = "true"; break; - } - cfg_log (cfgst, "%s%s", str, is_default ? " [def]" : ""); -} - -static int uf_sched_prio_class (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem,UNUSED_ARG (int first), const char *value) -{ - int ret; - q__schedPrioClass *prio; - - assert (value != NULL); - - prio = cfg_address (cfgst, parent, cfgelem); - - if (os_strcasecmp (value, "relative") == 0) { - *prio = Q__SCHED_PRIO_RELATIVE; - ret = 1; - } else if (os_strcasecmp (value, "absolute") == 0) { - *prio = Q__SCHED_PRIO_ABSOLUTE; - ret = 1; - } else { - ret = cfg_error (cfgst, "'%s': undefined value", value); - } - - return ret; -} - -static void pf_sched_prio_class (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int is_default) -{ - char *str; - q__schedPrioClass *prio = cfg_address (cfgst, parent, cfgelem); - - if (*prio == Q__SCHED_PRIO_RELATIVE) { - str = "relative"; - } else if (*prio == Q__SCHED_PRIO_ABSOLUTE) { - str = "absolute"; - } else { - str = "INVALID"; - } - - cfg_log (cfgst, "%s%s", str, is_default ? " [def]" : ""); -} - -static int uf_sched_class (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, UNUSED_ARG (int first), const char *value) -{ - static const char *vs[] = { "realtime", "timeshare", "default" }; - static const os_schedClass ms[] = { OS_SCHED_REALTIME, OS_SCHED_TIMESHARE, OS_SCHED_DEFAULT }; - int idx = list_index (vs, value); - os_schedClass *elem = cfg_address (cfgst, parent, cfgelem); - assert (sizeof (vs) / sizeof (*vs) == sizeof (ms) / sizeof (*ms)); - if (idx < 0) - return cfg_error (cfgst, "'%s': undefined value", value); - *elem = ms[idx]; - return 1; -} - -static void pf_sched_class (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int is_default) -{ - os_schedClass *p = cfg_address (cfgst, parent, cfgelem); - const char *str = "INVALID"; - switch (*p) - { - case OS_SCHED_DEFAULT: str = "default"; break; - case OS_SCHED_TIMESHARE: str = "timeshare"; break; - case OS_SCHED_REALTIME: str = "realtime"; break; - } - cfg_log (cfgst, "%s%s", str, is_default ? " [def]" : ""); -} - -static int uf_maybe_int32 (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, UNUSED_ARG (int first), const char *value) -{ - struct config_maybe_int32 *elem = cfg_address (cfgst, parent, cfgelem); - int pos; - if (os_strcasecmp (value, "default") == 0) { - elem->isdefault = 1; - elem->value = 0; - return 1; - } else if (sscanf (value, "%d%n", &elem->value, &pos) == 1 && value[pos] == 0) { - elem->isdefault = 0; - return 1; - } else { - return cfg_error (cfgst, "'%s': neither 'default' nor a decimal integer\n", value); - } -} - -static int uf_maybe_memsize (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, UNUSED_ARG (int first), const char *value) -{ - struct config_maybe_uint32 *elem = cfg_address (cfgst, parent, cfgelem); - os_int64 size = 0; - if (os_strcasecmp (value, "default") == 0) { - elem->isdefault = 1; - elem->value = 0; - return 1; - } else if (!uf_natint64_unit (cfgst, &size, value, unittab_memsize, 1, INT32_MAX)) { - return 0; - } else { - elem->isdefault = 0; - elem->value = (os_uint32) size; - return 1; - } -} - -static int uf_maybe_duration_inf (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, UNUSED_ARG (int first), const char *value) -{ - struct config_maybe_int64 *elem = cfg_address (cfgst, parent, cfgelem); - if (os_strcasecmp (value, "default") == 0) { - elem->isdefault = 1; - elem->value = 0; - return 1; - } else if (os_strcasecmp (value, "inf") == 0) { - elem->isdefault = 0; - elem->value = T_NEVER; - return 1; - } else if (uf_natint64_unit (cfgst, &elem->value, value, unittab_duration, 0, T_NEVER - 1)) { - elem->isdefault = 0; - return 1; - } else { - return 0; - } -} - -static int uf_float (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, UNUSED_ARG (int first), const char *value) -{ - float *elem = cfg_address (cfgst, parent, cfgelem); - char *endptr; - float f = os_strtof (value, &endptr); - if (*value == 0 || *endptr != 0) - return cfg_error (cfgst, "%s: not a floating point number", value); - *elem = f; - return 1; -} - -static int uf_int (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, UNUSED_ARG (int first), const char *value) -{ - int *elem = cfg_address (cfgst, parent, cfgelem); - char *endptr; - long v = strtol (value, &endptr, 10); - if (*value == 0 || *endptr != 0) - return cfg_error (cfgst, "%s: not a decimal integer", value); - if (v != (int) v) - return cfg_error (cfgst, "%s: value out of range", value); - *elem = (int) v; - return 1; -} - -static int uf_duration_gen (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, const char *value, os_int64 def_mult, os_int64 max_ns) -{ - return uf_natint64_unit (cfgst, cfg_address (cfgst, parent, cfgelem), value, unittab_duration, def_mult, max_ns); -} - -static int uf_duration_inf (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, UNUSED_ARG (int first), const char *value) -{ - if (os_strcasecmp (value, "inf") == 0) - { - os_int64 *elem = cfg_address (cfgst, parent, cfgelem); - *elem = T_NEVER; - return 1; - } - else - { - return uf_duration_gen (cfgst, parent, cfgelem, value, 0, T_NEVER - 1); - } -} - -static int uf_duration_ms_1hr (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, UNUSED_ARG (int first), const char *value) -{ - return uf_duration_gen (cfgst, parent, cfgelem, value, T_MILLISECOND, 3600 * T_SECOND); -} - -static int uf_duration_ms_1s (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, UNUSED_ARG (int first), const char *value) -{ - return uf_duration_gen (cfgst, parent, cfgelem, value, T_MILLISECOND, T_SECOND); -} - -static int uf_duration_us_1s (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, UNUSED_ARG (int first), const char *value) -{ - return uf_duration_gen (cfgst, parent, cfgelem, value, 1000, T_SECOND); -} - -static int uf_int32 (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, UNUSED_ARG (int first), const char *value) -{ - os_int32 *elem = cfg_address (cfgst, parent, cfgelem); - char *endptr; - long v = strtol (value, &endptr, 10); - if (*value == 0 || *endptr != 0) - return cfg_error (cfgst, "%s: not a decimal integer", value); - if (v != (os_int32) v) - return cfg_error (cfgst, "%s: value out of range", value); - *elem = (os_int32) v; - return 1; -} - -static int uf_uint32 (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, UNUSED_ARG (int first), const char *value) -{ - os_uint32 *elem = cfg_address (cfgst, parent, cfgelem); - char *endptr; - unsigned long v = strtoul (value, &endptr, 10); - if (*value == 0 || *endptr != 0) - return cfg_error (cfgst, "%s: not a decimal integer", value); - if (v != (os_uint32) v) - return cfg_error (cfgst, "%s: value out of range", value); - *elem = (os_uint32) v; - return 1; -} - -static int uf_uint (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, UNUSED_ARG (int first), const char *value) -{ - unsigned *elem = cfg_address (cfgst, parent, cfgelem); - char *endptr; - unsigned long v = strtoul (value, &endptr, 10); - if (*value == 0 || *endptr != 0) - return cfg_error (cfgst, "%s: not a decimal integer", value); - if (v != (unsigned) v) - return cfg_error (cfgst, "%s: value out of range", value); - *elem = (unsigned) v; - return 1; -} - -static int uf_int_min_max (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int first, const char *value, int min, int max) -{ - int *elem = cfg_address (cfgst, parent, cfgelem); - if (!uf_int (cfgst, parent, cfgelem, first, value)) - return 0; - else if (*elem < min || *elem > max) - return cfg_error (cfgst, "%s: out of range", value); - else - return 1; -} - -static int uf_domainId (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int first, const char *value) -{ - return uf_int_min_max (cfgst, parent, cfgelem, first, value, 0, 230); -} - -static int uf_participantIndex (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int first, const char *value) -{ - int *elem = cfg_address (cfgst, parent, cfgelem); - if (os_strcasecmp (value, "auto") == 0) { - *elem = PARTICIPANT_INDEX_AUTO; - return 1; - } else if (os_strcasecmp (value, "none") == 0) { - *elem = PARTICIPANT_INDEX_NONE; - return 1; - } else { - return uf_int_min_max (cfgst, parent, cfgelem, first, value, 0, 120); - } -} - -static int uf_port (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int first, const char *value) -{ - return uf_int_min_max (cfgst, parent, cfgelem, first, value, 1, 65535); -} - -static int uf_dyn_port (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int first, const char *value) -{ - return uf_int_min_max (cfgst, parent, cfgelem, first, value, -1, 65535); -} - -static int uf_natint (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int first, const char *value) -{ - return uf_int_min_max (cfgst, parent, cfgelem, first, value, 0, INT32_MAX); -} - -static int uf_natint_255 (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int first, const char *value) -{ - return uf_int_min_max (cfgst, parent, cfgelem, first, value, 0, 255); -} - -static int do_update (struct cfgst *cfgst, update_fun_t upd, void *parent, struct cfgelem const * const cfgelem, const char *value, int is_default) -{ - struct cfgst_node *n; - struct cfgst_nodekey key; - ut_avlIPath_t np; - int ok; - key.e = cfgelem; - if ((n = ut_avlLookupIPath (&cfgst_found_treedef, &cfgst->found, &key, &np)) == NULL) - { - if ((n = os_malloc (sizeof (*n))) == NULL) - return cfg_error (cfgst, "out of memory"); - - n->key = key; - n->count = 0; - n->failed = 0; - n->is_default = is_default; - ut_avlInsertIPath (&cfgst_found_treedef, &cfgst->found, n, &np); - } - if (cfgelem->multiplicity == 0 || n->count < cfgelem->multiplicity) - ok = upd (cfgst, parent, cfgelem, (n->count == n->failed), value); - else - ok = cfg_error (cfgst, "only %d instance(s) allowed",cfgelem->multiplicity); - n->count++; - if (!ok) - { - n->failed++; - } - return ok; -} - -static int set_default (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem) -{ - if (cfgelem->defvalue == NULL) - return cfg_error (cfgst, "element missing in configuration"); - return do_update (cfgst, cfgelem->update, parent, cfgelem, cfgelem->defvalue, 1); -} - -static int set_defaults (struct cfgst *cfgst, void *parent, int isattr, struct cfgelem const * const cfgelem, int clear_found) -{ - const struct cfgelem *ce; - int ok = 1; - for (ce = cfgelem; ce && ce->name; ce++) - { - struct cfgst_node *n; - struct cfgst_nodekey key; - key.e = ce; - cfgst_push (cfgst, isattr, ce, parent); - if (ce->multiplicity == 1) - { - if (ut_avlLookup (&cfgst_found_treedef, &cfgst->found, &key) == NULL) - { - if (ce->update) - { - int ok1; - cfgst_push (cfgst, 0, NULL, NULL); - ok1 = set_default (cfgst, parent, ce); - cfgst_pop (cfgst); - ok = ok && ok1; - } - } - if ((n = ut_avlLookup (&cfgst_found_treedef, &cfgst->found, &key)) != NULL) - { - if (clear_found) - { - ut_avlDelete (&cfgst_found_treedef, &cfgst->found, n); - os_free (n); - } - } - if (ce->children) - { - int ok1 = set_defaults (cfgst, parent, 0, ce->children, clear_found); - ok = ok && ok1; - } - if (ce->attributes) - { - int ok1 = set_defaults (cfgst, parent, 1, ce->attributes, clear_found); - ok = ok && ok1; - } - } - cfgst_pop (cfgst); - } - return ok; -} - -static void pf_nop (UNUSED_ARG (struct cfgst *cfgst), UNUSED_ARG (void *parent), UNUSED_ARG (struct cfgelem const * const cfgelem), UNUSED_ARG (int is_default)) -{ -} - -static void pf_string (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int is_default) -{ - char **p = cfg_address (cfgst, parent, cfgelem); - cfg_log (cfgst, "%s%s", *p ? *p : "(null)", is_default ? " [def]" : ""); -} - -static void pf_int64_unit (struct cfgst *cfgst, os_int64 value, int is_default, const struct unit *unittab, const char *zero_unit) -{ - if (value == 0) - { - /* 0s is a bit of a special case: we don't want to print 0hr (or - whatever unit will have the greatest multiplier), so hard-code - as 0s */ - cfg_log (cfgst, "0 %s%s", zero_unit, is_default ? " [def]" : ""); - } - else - { - os_int64 m = 0; - const char *unit = NULL; - int i; - for (i = 0; unittab[i].name != NULL; i++) - { - if (unittab[i].multiplier > m && (value % unittab[i].multiplier) == 0) - { - m = unittab[i].multiplier; - unit = unittab[i].name; - } - } - assert (m > 0); - assert (unit != NULL); - cfg_log (cfgst, "%lld %s%s", value / m, unit, is_default ? " [def]" : ""); - } -} - - -static void pf_networkAddress (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int is_default) -{ - char **p = cfg_address (cfgst, parent, cfgelem); - cfg_log (cfgst, "%s%s", *p ? *p : "auto", is_default ? " [def]" : ""); -} - -static void pf_participantIndex (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int is_default) -{ - int *p = cfg_address (cfgst, parent, cfgelem); - switch (*p) - { - case PARTICIPANT_INDEX_NONE: - cfg_log (cfgst, "none%s", is_default ? " [def]" : ""); - break; - case PARTICIPANT_INDEX_AUTO: - cfg_log (cfgst, "auto%s", is_default ? " [def]" : ""); - break; - default: - cfg_log (cfgst, "%d%s", *p, is_default ? " [def]" : ""); - break; - } -} - -static void pf_networkAddresses (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int is_default) -{ - int i; - char ***p = cfg_address (cfgst, parent, cfgelem); - for (i = 0; (*p)[i] != NULL; i++) - cfg_log (cfgst, "%s%s", (*p)[i], is_default ? " [def]" : ""); -} - -static void pf_int (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int is_default) -{ - int *p = cfg_address (cfgst, parent, cfgelem); - cfg_log (cfgst, "%d%s", *p, is_default ? " [def]" : ""); -} - -static void pf_uint (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int is_default) -{ - unsigned *p = cfg_address (cfgst, parent, cfgelem); - cfg_log (cfgst, "%u%s", *p, is_default ? " [def]" : ""); -} - -static void pf_duration (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int is_default) -{ - const os_int64 *elem = cfg_address (cfgst, parent, cfgelem); - if (*elem == T_NEVER) - cfg_log (cfgst, "inf%s", is_default ? " [def]" : ""); - else - pf_int64_unit (cfgst, *elem, is_default, unittab_duration, "s"); -} - - -static void pf_memsize (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int is_default) -{ - const int *elem = cfg_address (cfgst, parent, cfgelem); - pf_int64_unit (cfgst, *elem, is_default, unittab_memsize, "B"); -} - -static void pf_int32 (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int is_default) -{ - os_int32 *p = cfg_address (cfgst, parent, cfgelem); - cfg_log (cfgst, "%d%s", *p, is_default ? " [def]" : ""); -} - -static void pf_uint32 (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int is_default) -{ - os_uint32 *p = cfg_address (cfgst, parent, cfgelem); - cfg_log (cfgst, "%u%s", *p, is_default ? " [def]" : ""); -} - -static void pf_maybe_int32 (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int is_default) -{ - struct config_maybe_int32 *p = cfg_address (cfgst, parent, cfgelem); - if (p->isdefault) - cfg_log (cfgst, "default%s", is_default ? " [def]" : ""); - else - cfg_log (cfgst, "%d%s", p->value, is_default ? " [def]" : ""); -} - -static void pf_maybe_memsize (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int is_default) -{ - struct config_maybe_uint32 *p = cfg_address (cfgst, parent, cfgelem); - if (p->isdefault) - cfg_log (cfgst, "default%s", is_default ? " [def]" : ""); - else - pf_int64_unit (cfgst, p->value, is_default, unittab_memsize, "B"); -} - -static void pf_maybe_duration (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int is_default) -{ - struct config_maybe_int64 *p = cfg_address (cfgst, parent, cfgelem); - if (p->isdefault) - cfg_log (cfgst, "default%s", is_default ? " [def]" : ""); - else if (p->value == T_NEVER) - cfg_log (cfgst, "inf%s", is_default ? " [def]" : ""); - else - pf_int64_unit (cfgst, p->value, is_default, unittab_duration, "s"); -} - -static void pf_float (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int is_default) -{ - float *p = cfg_address (cfgst, parent, cfgelem); - cfg_log (cfgst, "%f%s", *p, is_default ? " [def]" : ""); -} - -static void pf_boolean (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int is_default) -{ - int *p = cfg_address (cfgst, parent, cfgelem); - cfg_log (cfgst, "%s%s", *p ? "true" : "false", is_default ? " [def]" : ""); -} - -static void pf_negated_boolean (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int is_default) -{ - int *p = cfg_address (cfgst, parent, cfgelem); - cfg_log (cfgst, "%s%s", *p ? "false" : "true", is_default ? " [def]" : ""); -} - -static int uf_standards_conformance (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, UNUSED_ARG (int first), const char *value) -{ - static const char *vs[] = { - "pedantic", "strict", "lax", NULL - }; - static const logcat_t lc[] = { - NN_SC_PEDANTIC, NN_SC_STRICT, NN_SC_LAX, 0 - }; - enum nn_standards_conformance *elem = cfg_address (cfgst, parent, cfgelem); - int idx = list_index (vs, value); - assert (sizeof (vs) / sizeof (*vs) == sizeof (lc) / sizeof (*lc)); - if (idx < 0) - return cfg_error (cfgst, "'%s': undefined value", value); - else - { - *elem = lc[idx]; - return 1; - } -} - -static void pf_standards_conformance (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int is_default) -{ - enum nn_standards_conformance *p = cfg_address (cfgst, parent, cfgelem); - const char *str = "INVALID"; - switch (*p) - { - case NN_SC_PEDANTIC: str = "pedantic"; break; - case NN_SC_STRICT: str = "strict"; break; - case NN_SC_LAX: str = "lax"; break; - } - cfg_log (cfgst, "%s%s", str, is_default ? " [def]" : ""); -} - -static void pf_logcat (struct cfgst *cfgst, UNUSED_ARG (void *parent), UNUSED_ARG (struct cfgelem const * const cfgelem), UNUSED_ARG (int is_default)) -{ - logcat_t remaining = config.enabled_logcats; - char res[256] = "", *resp = res; - const char *prefix = ""; - size_t i; -#ifndef NDEBUG - { - size_t max; - for (i = 0, max = 0; i < sizeof (logcat_codes) / sizeof (*logcat_codes); i++) - max += 1 + strlen (logcat_names[i]); - max += 11; /* ,0x%x */ - max += 1; /* \0 */ - assert (max <= sizeof (res)); - } -#endif - /* TRACE enables ALLCATS, all the others just one */ - if ((remaining & LC_ALLCATS) == LC_ALLCATS) - { - resp += snprintf (resp, 256, "%strace", prefix); - remaining &= ~LC_ALLCATS; - prefix = ","; - } - for (i = 0; i < sizeof (logcat_codes) / sizeof (*logcat_codes); i++) - { - if (remaining & logcat_codes[i]) - { - resp += snprintf (resp, 256, "%s%s", prefix, logcat_names[i]); - remaining &= ~logcat_codes[i]; - prefix = ","; - } - } - if (remaining) - { - resp += snprintf (resp, 256, "%s0x%x", prefix, (unsigned) remaining); - } - assert (resp <= res + sizeof (res)); - /* can't do default indicator: user may have specified Verbosity, in - which case EnableCategory is at default, but for these two - settings, I don't mind. */ - cfg_log (cfgst, "%s", res); -} - - -static void print_configitems (struct cfgst *cfgst, void *parent, int isattr, struct cfgelem const * const cfgelem, int unchecked) -{ - const struct cfgelem *ce; - for (ce = cfgelem; ce && ce->name; ce++) - { - struct cfgst_nodekey key; - struct cfgst_node *n; - if (ce->name[0] == '>') /* moved, so don't care */ - continue; - key.e = ce; - cfgst_push (cfgst, isattr, ce, parent); - if (ce->multiplicity == 1) - { - if ((n = ut_avlLookup (&cfgst_found_treedef, &cfgst->found, &key)) != NULL) - { - cfgst_push (cfgst, 0, NULL, NULL); - ce->print (cfgst, parent, ce, n->is_default); - cfgst_pop (cfgst); - } - else - { - if (unchecked && ce->print) - { - cfgst_push (cfgst, 0, NULL, NULL); - ce->print (cfgst, parent, ce, 0); - cfgst_pop (cfgst); - } - } - - if (ce->children) - print_configitems (cfgst, parent, 0, ce->children, unchecked); - if (ce->attributes) - print_configitems (cfgst, parent, 1, ce->attributes, unchecked); - } - else - { - struct config_listelem *p = cfg_deref_address (cfgst, parent, ce); - while (p) - { - cfgst_push (cfgst, 0, NULL, NULL); - if (ce->print) - { - ce->print (cfgst, p, ce, 0); - } - cfgst_pop (cfgst); - if (ce->attributes) - print_configitems (cfgst, p, 1, ce->attributes, 1); - if (ce->children) - print_configitems (cfgst, p, 0, ce->children, 1); - p = p->next; - } - } - cfgst_pop (cfgst); - } -} - - -static void free_all_elements (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem) -{ - const struct cfgelem *ce; - - for (ce = cfgelem; ce && ce->name; ce++) - { - if (ce->name[0] == '>') /* moved, so don't care */ - continue; - - if (ce->free) - ce->free (cfgst, parent, ce); - - if (ce->multiplicity == 1) - { - if (ce->children) - free_all_elements (cfgst, parent, ce->children); - if (ce->attributes) - free_all_elements (cfgst, parent, ce->attributes); - } - else - { - struct config_listelem *p = cfg_deref_address (cfgst, parent, ce); - struct config_listelem *r ; - while (p) { - if (ce->attributes) - free_all_elements (cfgst, p, ce->attributes); - if (ce->children) - free_all_elements (cfgst, p, ce->children); - r = p; - p = p->next; - os_free(r); - } - } - } -} - -static void free_configured_elements (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem) -{ - const struct cfgelem *ce; - for (ce = cfgelem; ce && ce->name; ce++) - { - struct cfgst_nodekey key; - struct cfgst_node *n; - if (ce->name[0] == '>') /* moved, so don't care */ - continue; - key.e = ce; - if ((n = ut_avlLookup (&cfgst_found_treedef, &cfgst->found, &key)) != NULL) - { - if (ce->free && n->count > n->failed) - ce->free (cfgst, parent, ce); - } - - if (ce->multiplicity == 1) - { - if (ce->children) - free_configured_elements (cfgst, parent, ce->children); - if (ce->attributes) - free_configured_elements (cfgst, parent, ce->attributes); - } - else - { - struct config_listelem *p = cfg_deref_address (cfgst, parent, ce); - struct config_listelem *r; - while (p) - { - if (ce->attributes) - free_all_elements (cfgst, p, ce->attributes); - if (ce->children) - free_all_elements (cfgst, p, ce->children); - r = p; - p = p->next; - os_free(r); - } - } - } -} - -static int matching_name_index (const char *name_w_aliases, const char *name) -{ - const char *ns = name_w_aliases, *p = strchr (ns, '|'); - int idx = 0; - while (p) - { - if (os_strncasecmp (ns, name, (size_t) (p-ns)) == 0 && name[p-ns] == 0) - { - /* ns upto the pipe symbol is a prefix of name, and name is terminated at that point */ - return idx; - } - /* If primary name followed by '||' instead of '|', aliases are non-warning */ - ns = p + 1 + (idx == 0 && p[1] == '|'); - p = strchr (ns, '|'); - idx++; - } - return (os_strcasecmp (ns, name) == 0) ? idx : -1; -} - -static const struct cfgelem *lookup_redirect (const char *target) -{ - const struct cfgelem *cfgelem = ddsi2_cfgelems; - char *target_copy = os_strdup(target), *p1; - const char *p = target_copy; - while (p) { - p1 = strchr (p, '/'); - if (p1) *p1++ = 0; - for (; cfgelem->name; cfgelem++) - { - /* not supporting multiple redirects */ - assert(cfgelem->name[0] != '>'); - if (matching_name_index (cfgelem->name, p) >= 0) - break; - } - if (p1) - { - cfgelem = cfgelem->children; - } - p = p1; - } - os_free(target_copy); - return cfgelem; -} - -static int proc_elem_open (void *varg, const char *name) -{ - struct cfgst * const cfgst = varg; - const struct cfgelem *cfgelem = cfgst_tos (cfgst); - const struct cfgelem *cfg_subelem; - int moved = 0; - if (cfgelem == NULL) - { - /* Ignoring, but do track the structure so we can know when to stop ignoring */ - cfgst_push (cfgst, 0, NULL, NULL); - return 1; - } - for (cfg_subelem = cfgelem->children; cfg_subelem && cfg_subelem->name && strcmp (cfg_subelem->name, "*") != 0; cfg_subelem++) - { - const char *csename = cfg_subelem->name; - int idx; - moved = (csename[0] == '>'); - if (moved) - csename++; - idx = matching_name_index (csename, name); -#if WARN_DEPRECATED_ALIAS - if (idx > 0) - { - int n = (int) (strchr (csename, '|') - csename); - if (csename[n+1] != '|') - cfg_warning (cfgst, "'%s': deprecated alias for '%*.*s'", name, n, n, csename); - } -#endif - if (idx >= 0) - { - break; - } - } - if (cfg_subelem == NULL || cfg_subelem->name == NULL) - return cfg_error (cfgst, "%s: unknown element", name); - else if (strcmp (cfg_subelem->name, "*") == 0) - { - /* Push a marker that we are to ignore this part of the DOM tree */ - cfgst_push (cfgst, 0, NULL, NULL); - return 1; - } - else - { - void *parent, *dynparent; - - if (moved) - { -#if WARN_DEPRECATED_ALIAS - cfg_warning (cfgst, "'%s': deprecated alias for '%s'", name, cfg_subelem->defvalue); -#endif - cfg_subelem = lookup_redirect (cfg_subelem->defvalue); - } - - parent = cfgst_parent (cfgst); - assert (cfgelem->init || cfgelem->multiplicity == 1); /*multi-items must have an init-func */ - if (cfg_subelem->init) - { - if (cfg_subelem->init (cfgst, parent, cfg_subelem) < 0) - return 0; - } - - if (cfg_subelem->multiplicity != 1) - dynparent = cfg_deref_address (cfgst, parent, cfg_subelem); - else - dynparent = parent; - - cfgst_push (cfgst, 0, cfg_subelem, dynparent); - return 1; - } -} - -static int proc_attr (void *varg, const char *name, const char *value) -{ - /* All attributes are processed immediately after opening the element */ - struct cfgst * const cfgst = varg; - const struct cfgelem *cfgelem = cfgst_tos (cfgst); - const struct cfgelem *cfg_attr; - if (cfgelem == NULL) - return 1; - for (cfg_attr = cfgelem->attributes; cfg_attr && cfg_attr->name; cfg_attr++) - { - if (os_strcasecmp (cfg_attr->name, name) == 0) - break; - } - if (cfg_attr == NULL || cfg_attr->name == NULL) - return cfg_error (cfgst, "%s: unknown attribute", name); - else - { - void *parent = cfgst_parent (cfgst); - int ok; - cfgst_push (cfgst, 1, cfg_attr, parent); - ok = do_update (cfgst, cfg_attr->update, parent, cfg_attr, value, 0); - cfgst_pop (cfgst); - return ok; - } -} - -static int proc_elem_data (void *varg, const char *value) -{ - struct cfgst * const cfgst = varg; - const struct cfgelem *cfgelem = cfgst_tos (cfgst); - if (cfgelem == NULL) - return 1; - if (cfgelem->update == 0) - return cfg_error (cfgst, "%s: no data expected", value); - else - { - void *parent = cfgst_parent (cfgst); - int ok; - cfgst_push (cfgst, 0, NULL, parent); - ok = do_update (cfgst, cfgelem->update, parent, cfgelem, value, 0); - cfgst_pop (cfgst); - return ok; - } -} - -static int proc_elem_close (void *varg) -{ - struct cfgst * const cfgst = varg; - const struct cfgelem * cfgelem = cfgst_tos (cfgst); - int ok = 1; - if (cfgelem && cfgelem->multiplicity != 1) - { - void *parent = cfgst_parent (cfgst); - int ok1; - ok1 = set_defaults (cfgst, parent, 1, cfgelem->attributes, 1); - ok = ok && ok1; - ok1 = set_defaults (cfgst, parent, 0, cfgelem->children, 1); - ok = ok && ok1; - } - cfgst_pop (cfgst); - return ok; -} - -static int walk_element (struct cfgst *cfgst, const char *name, u_cfElement elem); - -static int walk_attributes (struct cfgst *cfgst, u_cfElement base) -{ - c_iter iter; - u_cfNode child; - int ok = 1; - iter = u_cfElementGetAttributes (base); - child = u_cfNode (c_iterTakeFirst (iter)); - while (child) - { - u_cfAttribute attr; - c_char *name, *value; - int ok1 = 0; - name = u_cfNodeName (child); - assert (name != NULL); - assert (u_cfNodeKind (child) == V_CFATTRIBUTE); - attr = u_cfAttribute (child); - if (!u_cfAttributeStringValue (attr, &value)) - ok1 = cfg_error (cfgst, "failed to extract data"); - else - { - ok1 = proc_attr (cfgst, name, value); - os_free (value); - } - ok = ok && ok1; - os_free (name); - u_cfNodeFree (child); - child = u_cfNode (c_iterTakeFirst (iter)); - } - c_iterFree (iter); - return ok; -} - -static int walk_children (struct cfgst *cfgst, u_cfElement base) -{ - c_iter iter; - u_cfNode child; - int ok = 1; - iter = u_cfElementGetChildren (base); - child = u_cfNode (c_iterTakeFirst (iter)); - while (child) - { - c_char *child_name; - int ok1 = 0; - child_name = u_cfNodeName (child); - assert (child_name != NULL); - switch (u_cfNodeKind (child)) - { - case V_CFELEMENT: - { - u_cfElement elem = u_cfElement (child); - ok1 = walk_element (cfgst, child_name, elem); - break; - } - case V_CFDATA: - { - u_cfData data = u_cfData (child); - c_char *value; - if (!u_cfDataStringValue (data, &value)) - ok1 = cfg_error (cfgst, "failed to extract data"); - else - { - if (strspn (value, " \t\r\n") != strlen (value)) - ok1 = proc_elem_data (cfgst, value); - else - ok1 = 1; - os_free (value); - } - break; - } - default: - abort (); - } - ok = ok && ok1; - os_free (child_name); - u_cfNodeFree (child); - child = u_cfNode (c_iterTakeFirst (iter)); - } - c_iterFree (iter); - return ok; -} - -static int walk_element (struct cfgst *cfgst, const char *name, u_cfElement elem) -{ - if (!proc_elem_open (cfgst, name)) - return 0; - else - { - int ok; - ok = walk_attributes (cfgst, elem) && walk_children (cfgst, elem); - if (!proc_elem_close (cfgst)) - ok = 0; - return ok; - } -} - -static int cfgst_node_cmp (const void *va, const void *vb) -{ - return memcmp (va, vb, sizeof (struct cfgst_nodekey)); -} - - -struct cfgst * config_init -( - /* C_STRUCT (u_participant) const * */u_participant participant, const char *servicename -) -{ - int ok = 1; - struct cfgst *cfgst; - u_cfElement root, elem; - c_iter iter; - int rootidx; - assert (participant != NULL); - - memset (&config, 0, sizeof (config)); - - /* Enable logging of errors &c. to stderr until configuration is read */ - config.enabled_logcats = LC_FATAL | LC_ERROR | LC_WARNING; - config.tracingOutputFile = stderr; - - cfgst = os_malloc (sizeof (*cfgst)); - memset (cfgst, 0, sizeof (*cfgst)); - - ut_avlInit (&cfgst_found_treedef, &cfgst->found); - cfgst->cfg = &config; - cfgst->servicename = servicename; - - if ((root = u_participantGetConfiguration ((u_participant) participant)) == NULL) - { - NN_ERROR0 ("config_init: u_participantGetConfiguration failed"); - ut_avlFree (&cfgst_found_treedef, &cfgst->found, os_free); - os_free (cfgst); - return NULL; - } - - /* Only suitable for Domain (without a attributes) and a service - with a matching name attribute */ - cfgst_push (cfgst, 0, &root_cfgelem, &config); - for (rootidx = 0; root_cfgelems[rootidx].name; rootidx++) - { - const struct cfgelem *root_cfgelem = &root_cfgelems[rootidx]; - char *copy = os_strdup (root_cfgelem->name), *cursor = copy, *tok; - while ((tok = os_strsep (&cursor, "|")) != NULL) - { - if (*tok == 0) - { - /* The configuration tables are supposed to be reasonable and not contain empty tags. Then, "||" is returned as an empty token by os_strsep, but we can simply skip it */ - continue; - } - iter = u_cfElementXPath (root, tok); - elem = u_cfElement (c_iterTakeFirst (iter)); - while (elem) - { - c_char *str; - if (root_cfgelem->attributes == NULL) - { - /* Domain element */ - int ok1; - char *name = u_cfNodeName (u_cfNode (elem)); - ok1 = walk_element (cfgst, name, elem); - os_free (name); - ok = ok && ok1; - } - else if (u_cfElementAttributeStringValue (elem, "name", &str)) - { - int ok1; - if (os_strcasecmp (servicename, str) != 0) - ok1 = 1; - else - { - char *name = u_cfNodeName (u_cfNode (elem)); - ok1 = walk_element (cfgst, name, elem); - os_free (name); - } - ok = ok && ok1; - os_free (str); - } - u_cfElementFree (elem); - elem = u_cfElement (c_iterTakeFirst (iter)); - } - c_iterFree (iter); - } - os_free (copy); - } - cfgst_pop (cfgst); - u_cfElementFree (root); - - /* Set defaults for everything not set that we have a default value - for, signal errors for things unset but without a default. */ - { - int ok1 = set_defaults (cfgst, cfgst->cfg, 0, root_cfgelems, 0); - ok = ok && ok1; - } - - - - - /* Now switch to configured tracing settings */ - config.enabled_logcats = enabled_logcats; - - if (!ok) - { - free_configured_elements (cfgst, cfgst->cfg, root_cfgelems); - } - - if (ok) - { - config.valid = 1; - return cfgst; - } - else - { - ut_avlFree (&cfgst_found_treedef, &cfgst->found, os_free); - os_free (cfgst); - return NULL; - } -} - -void config_print_and_free_cfgst (struct cfgst *cfgst) -{ - if (cfgst == NULL) - return; - print_configitems (cfgst, cfgst->cfg, 0, root_cfgelems, 0); - ut_avlFree (&cfgst_found_treedef, &cfgst->found, os_free); - os_free (cfgst); -} - -void config_fini (void) -{ - if (config.valid) - { - struct cfgst cfgst; - cfgst.cfg = &config; - free_all_elements (&cfgst, cfgst.cfg, root_cfgelems); - if (config.tracingOutputFile) - { - fclose (config.tracingOutputFile); - } - memset (&config, 0, sizeof (config)); - } -} - - - -/* SHA1 not available (unoffical build.) */ diff --git a/src/services/ddsi2/code/q_config.h b/src/services/ddsi2/code/q_config.h deleted file mode 100644 index 93086cb9e..000000000 --- a/src/services/ddsi2/code/q_config.h +++ /dev/null @@ -1,326 +0,0 @@ -/* - * OpenSplice DDS - * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -#ifndef NN_CONFIG_H -#define NN_CONFIG_H - -#include "os_socket.h" - -#include "q_log.h" -#include "q_thread.h" -#include "q_xqos.h" -#include "c_typebase.h" -#include "ddsi_tran.h" -#include "q_feature_check.h" - - -#if defined (__cplusplus) -extern "C" { -#endif - -#ifdef OSPL_BUILD_DDSI2 -#define OS_API OS_API_EXPORT -#else -#define OS_API OS_API_IMPORT -#endif - -/* FIXME: should eventually move to abstraction layer */ -typedef enum q__schedPrioClass { - Q__SCHED_PRIO_RELATIVE, - Q__SCHED_PRIO_ABSOLUTE -} q__schedPrioClass; - -enum nn_standards_conformance { - NN_SC_PEDANTIC, - NN_SC_STRICT, - NN_SC_LAX -}; - -#define NN_PEDANTIC_P (config.standards_conformance <= NN_SC_PEDANTIC) -#define NN_STRICT_P (config.standards_conformance <= NN_SC_STRICT) - -enum besmode { - BESMODE_FULL, - BESMODE_WRITERS, - BESMODE_MINIMAL -}; - -enum retransmit_merging { - REXMIT_MERGE_NEVER, - REXMIT_MERGE_ADAPTIVE, - REXMIT_MERGE_ALWAYS -}; - -enum boolean_default { - BOOLDEF_DEFAULT, - BOOLDEF_FALSE, - BOOLDEF_TRUE -}; - - -#define PARTICIPANT_INDEX_AUTO -1 -#define PARTICIPANT_INDEX_NONE -2 - -/* config_listelem must be an overlay for all used listelem types */ -struct config_listelem { - struct config_listelem *next; -}; - - - - -struct config_maybe_int32 { - int isdefault; - os_int32 value; -}; - -struct config_maybe_uint32 { - int isdefault; - os_uint32 value; -}; - -struct config_maybe_int64 { - int isdefault; - os_int64 value; -}; - -struct config_thread_properties_listelem { - struct config_thread_properties_listelem *next; - char *name; - os_schedClass sched_class; - struct config_maybe_int32 sched_priority; - struct config_maybe_uint32 stack_size; -}; - -struct config_peer_listelem -{ - struct config_peer_listelem *next; - char *peer; -}; - -struct prune_deleted_ppant { - os_int64 delay; - int enforce_delay; -}; - -/* allow multicast bits: */ -#define AMC_FALSE 0u -#define AMC_SPDP 1u -#define AMC_ASM 2u -#define AMC_TRUE (AMC_SPDP | AMC_ASM) - -struct config -{ - int valid; - logcat_t enabled_logcats; - char *servicename; - char *pcap_file; - - char *networkAddressString; - char **networkRecvAddressStrings; - char *externalAddressString; - char *externalMaskString; - FILE *tracingOutputFile; - char *tracingOutputFileName; - int tracingTimestamps; - int tracingRelativeTimestamps; - int tracingAppendToFile; - unsigned allowMulticast; - int useIpv6; - int dontRoute; - int enableMulticastLoopback; - int domainId; - int participantIndex; - int maxAutoParticipantIndex; - int port_base; - struct config_maybe_int32 discoveryDomainId; - char *spdpMulticastAddressString; - char *defaultMulticastAddressString; - char *assumeMulticastCapable; - os_int64 spdp_interval; - os_int64 spdp_response_delay_max; - os_int64 startup_mode_duration; - os_int64 lease_duration; - enum retransmit_merging retransmit_merging; - os_int64 retransmit_merging_period; - int squash_participants; - int startup_mode_full; - int forward_all_messages; - int noprogress_log_stacktraces; - int prioritize_retransmit; - - char *local_discovery_partition; - enum boolean_default mirror_remote_entities; - enum boolean_default forward_remote_data; - - unsigned primary_reorder_maxsamples; - unsigned secondary_reorder_maxsamples; - - unsigned delivery_queue_maxsamples; - - float servicelease_expiry_time; - float servicelease_update_factor; - - os_uint32 guid_hash_softlimit; - - os_uint32 gid_hash_softlimit; - int coexistWithNativeNetworking; - - unsigned nw_queue_size; - - int buggy_datafrag_flags_mode; - - os_uint32 max_msg_size; - os_uint32 fragment_size; - - int publish_uc_locators; /* Publish discovery unicast locators */ - - /* TCP transport configuration */ - - int tcp_enable; - int tcp_nodelay; - int tcp_port; - os_int64 tcp_read_timeout; - os_int64 tcp_write_timeout; - -#ifdef DDSI_INCLUDE_SSL - - /* SSL support for TCP */ - - int ssl_enable; - int ssl_verify; - int ssl_verify_client; - int ssl_self_signed; - char * ssl_keystore; - char * ssl_rand_file; - char * ssl_key_pass; - char * ssl_ciphers; - -#endif - - /* Thread pool configuration */ - - int tp_enable; - os_uint32 tp_threads; - os_uint32 tp_max_threads; - - int generate_builtin_topics; - int advertise_builtin_topic_writers; - - struct config_peer_listelem *peers; - struct config_peer_listelem *peers_group; - struct config_thread_properties_listelem *thread_properties; - - /* debug/test/undoc features: */ - int xmit_lossiness; /**<< fraction of packets to drop on xmit, in units of 1e-3 */ - os_uint32 rmsg_chunk_size; /**<< size of a chunk in the receive buffer */ - os_uint32 rbuf_size; /* << size of a single receiver buffer */ - enum besmode besmode; - int aggressive_keep_last_whc; - int conservative_builtin_reader_startup; - int meas_hb_to_ack_latency; - int suppress_spdp_multicast; - int unicast_response_to_spdp_messages; - int synchronous_delivery_priority_threshold; - os_int64 synchronous_delivery_latency_bound; - - /* Write cache */ - - os_uint32 whc_lowwater_mark; - os_uint32 whc_highwater_mark; - struct config_maybe_uint32 whc_init_highwater_mark; - int whc_adaptive; - - unsigned defrag_unreliable_maxsamples; - unsigned defrag_reliable_maxsamples; - unsigned accelerate_rexmit_block_size; - os_int64 responsiveness_timeout; - os_uint32 max_participants; - os_int64 writer_linger_duration; - int multicast_ttl; - struct config_maybe_uint32 socket_min_rcvbuf_size; - os_uint32 socket_min_sndbuf_size; - os_int64 nack_delay; - os_int64 preemptive_ack_delay; - os_int64 schedule_time_rounding; - os_uint32 max_queued_rexmit_bytes; - unsigned max_queued_rexmit_msgs; - unsigned ddsi2direct_max_threads; - int late_ack_mode; - struct config_maybe_int64 retry_on_reject_duration; - int retry_on_reject_besteffort; - int generate_keyhash; - os_uint32 max_sample_size; - - /* compability options */ - enum nn_standards_conformance standards_conformance; - int explicitly_publish_qos_set_to_default; - int many_sockets_mode; - int arrival_of_data_asserts_pp_and_ep_liveliness; - int acknack_numbits_emptyset; - int respond_to_rti_init_zero_ack_with_invalid_heartbeat; - int assume_rti_has_pmd_endpoints; - - int port_dg; - int port_pg; - int port_d0; - int port_d1; - int port_d2; - int port_d3; - - int monitor_port; - - int enable_control_topic; - int initial_deaf_mute; - int use_multicast_if_mreqn; - struct prune_deleted_ppant prune_deleted_ppant; - - /* not used by ddsi2, only validated; user layer directly accesses - the configuration tree */ - os_schedClass watchdog_sched_class; - os_int32 watchdog_sched_priority; - q__schedPrioClass watchdog_sched_priority_class; -}; - - -struct ddsi_plugin -{ - int (*init_fn) (void); - void (*fini_fn) (void); - -}; - -extern struct config OS_API config; -extern struct ddsi_plugin ddsi_plugin; - -struct cfgst; - -struct u_participant_s; -struct cfgst *config_init (struct u_participant_s *participant, const char *serviceName); -void config_print_and_free_cfgst (struct cfgst *cfgst); -void config_fini (void); - -#undef OS_API -#if defined (__cplusplus) -} -#endif - -#endif /* NN_CONFIG_H */ - -/* SHA1 not available (unoffical build.) */ diff --git a/src/services/ddsi2/code/q_ddsi2.h b/src/services/ddsi2/code/q_ddsi2.h deleted file mode 100644 index 680cc6dce..000000000 --- a/src/services/ddsi2/code/q_ddsi2.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * OpenSplice DDS - * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -#ifndef NN_DDSI2_H -#define NN_DDSI2_H - -#include "vortex_os.h" -#include "kernelModuleI.h" -#if defined (__cplusplus) -extern "C" { -#endif - -#include "os_if.h" - -#ifdef OSPL_BUILD_DDSI2 -#define OS_API OS_API_EXPORT -#else -#define OS_API OS_API_IMPORT -#endif -/* !!!!!!!!NOTE From here no more includes are allowed!!!!!!! */ - -OS_API OPENSPLICE_ENTRYPOINT_DECL(ospl_ddsi2); - -#undef OS_API - -#if defined (__cplusplus) -} -#endif - -#endif /* NN_DDSI2_H */ - -/* SHA1 not available (unoffical build.) */ diff --git a/src/services/ddsi2/code/q_ddsi_discovery.h b/src/services/ddsi2/code/q_ddsi_discovery.h deleted file mode 100644 index 5fa2824a0..000000000 --- a/src/services/ddsi2/code/q_ddsi_discovery.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * OpenSplice DDS - * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -#ifndef NN_DDSI_DISCOVERY_H -#define NN_DDSI_DISCOVERY_H - -#include "q_unused.h" - -#if defined (__cplusplus) -extern "C" { -#endif - -struct participant; -struct writer; -struct reader; -struct nn_rsample_info; -struct nn_rdata; -struct nn_plist; - -int spdp_write (struct participant *pp); -int spdp_dispose_unregister (struct participant *pp); - -int sedp_write_writer (struct writer *wr); -int sedp_write_reader (struct reader *rd); -int sedp_dispose_unregister_writer (struct writer *wr); -int sedp_dispose_unregister_reader (struct reader *rd); - -int sedp_write_topic (struct participant *pp, const struct nn_plist *datap); -int sedp_write_cm_participant (struct participant *pp, int alive); -int sedp_write_cm_publisher (const struct nn_plist *datap, int alive); -int sedp_write_cm_subscriber (const struct nn_plist *datap, int alive); - -int builtins_dqueue_handler (const struct nn_rsample_info *sampleinfo, const struct nn_rdata *fragchain, const nn_guid_t *rdguid, void *qarg); - -#if defined (__cplusplus) -} -#endif - -#endif /* NN_DDSI_DISCOVERY_H */ - -/* SHA1 not available (unoffical build.) */ diff --git a/src/services/ddsi2/code/q_debmon.h b/src/services/ddsi2/code/q_debmon.h deleted file mode 100644 index 85f023599..000000000 --- a/src/services/ddsi2/code/q_debmon.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * OpenSplice DDS - * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -#ifndef Q_DEBMON_H -#define Q_DEBMON_H - -struct debug_monitor; -typedef int (*debug_monitor_cpf_t) (ddsi_tran_conn_t conn, const char *fmt, ...); -typedef int (*debug_monitor_plugin_t) (ddsi_tran_conn_t conn, debug_monitor_cpf_t cpf, void *arg); - -struct debug_monitor *new_debug_monitor (int port); -void add_debug_monitor_plugin (struct debug_monitor *dm, debug_monitor_plugin_t fn, void *arg); -void free_debug_monitor (struct debug_monitor *dm); - -#endif /* defined(__ospli_osplo__q_debmon__) */ - -/* SHA1 not available (unoffical build.) */ diff --git a/src/services/ddsi2/code/q_error.h b/src/services/ddsi2/code/q_error.h deleted file mode 100644 index 887f01897..000000000 --- a/src/services/ddsi2/code/q_error.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * OpenSplice DDS - * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -#ifndef NN_ERROR_H -#define NN_ERROR_H - -#define ERR_UNSPECIFIED -1 -#define ERR_INVALID -2 -#define ERR_OUT_OF_MEMORY -3 -#define ERR_ENTITY_EXISTS -4 -#define ERR_UNKNOWN_ENTITY -5 -#define ERR_OUT_OF_IDS -6 -#define ERR_INVALID_DATA -7 -#define ERR_BUSY -8 -#define ERR_NO_ADDRESS -9 -#define ERR_TIMEOUT -10 - -#endif /* NN_ERROR_H */ - -/* SHA1 not available (unoffical build.) */ diff --git a/src/services/ddsi2/code/q_feature_check.h b/src/services/ddsi2/code/q_feature_check.h deleted file mode 100644 index c4ccc9358..000000000 --- a/src/services/ddsi2/code/q_feature_check.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * OpenSplice DDS - * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -/* Feature macros: - - - ENCRYPTION: support for encryption - requires: NETWORK_PARTITIONS - - - SSM: support for source-specific multicast - requires: NETWORK_PARTIITONS - also requires platform support; SSM is silently disabled if the - platform doesn't support it - - - BANDWIDTH_LIMITING: transmit-side bandwidth limiting - requires: NETWORK_CHANNELS (for now, anyway) - - - IPV6: support for IPV6 - requires: platform support (which itself is not part of DDSI) - - - NETWORK_PARTITIONS: support for multiple network partitions - - - NETWORK_CHANNELS: support for multiple network channels - -*/ - - - - -/* SHA1 not available (unoffical build.) */ diff --git a/src/services/ddsi2/code/q_fill_msg_qos.h b/src/services/ddsi2/code/q_fill_msg_qos.h deleted file mode 100644 index 101df20bb..000000000 --- a/src/services/ddsi2/code/q_fill_msg_qos.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * OpenSplice DDS - * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -#ifndef Q_FILL_MSG_QOS_H -#define Q_FILL_MSG_QOS_H - -#include "os_defs.h" -#include "c_base.h" - -struct v_message; - -struct nn_xqos; -struct proxy_writer; -struct nn_prismtech_writer_info; - -c_array new_v_message_qos (const struct nn_xqos *xqos); - -#endif /* Q_FILL_MSG_QOS_H */ - -/* SHA1 not available (unoffical build.) */ diff --git a/src/services/ddsi2/code/q_gc.h b/src/services/ddsi2/code/q_gc.h deleted file mode 100644 index b190a5c17..000000000 --- a/src/services/ddsi2/code/q_gc.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * OpenSplice DDS - * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -#ifndef Q_GC_H -#define Q_GC_H - -#include "q_thread.h" - -#if defined (__cplusplus) -extern "C" { -#endif - -struct gcreq; -struct gcreq_queue; - -struct writer; -struct reader; -struct proxy_writer; -struct proxy_reader; - -typedef void (*gcreq_cb_t) (struct gcreq *gcreq); - -struct idx_vtime { - unsigned idx; - vtime_t vtime; -}; - -struct gcreq { - struct gcreq *next; - struct gcreq_queue *queue; - gcreq_cb_t cb; - void *arg; - unsigned nvtimes; - struct idx_vtime vtimes[1 /* really a flex ary */]; -}; - -struct gcreq_queue *gcreq_queue_new (void); -void gcreq_queue_free (struct gcreq_queue *q); - -struct gcreq *gcreq_new (struct gcreq_queue *gcreq_queue, gcreq_cb_t cb); -void gcreq_free (struct gcreq *gcreq); -void gcreq_enqueue (struct gcreq *gcreq); -int gcreq_requeue (struct gcreq *gcreq, gcreq_cb_t cb); - -#if defined (__cplusplus) -} -#endif - -#endif /* Q_GC_H */ - -/* SHA1 not available (unoffical build.) */ diff --git a/src/services/ddsi2/code/q_groupset.h b/src/services/ddsi2/code/q_groupset.h deleted file mode 100644 index a2dce0784..000000000 --- a/src/services/ddsi2/code/q_groupset.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * OpenSplice DDS - * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -#ifndef NN_GROUPSET_H -#define NN_GROUPSET_H - -struct nn_groupset; - -typedef int (*nn_groupset_foreach_t) (v_group g, void *arg); - -int nn_groupset_add_group (struct nn_groupset *gs, v_group g); - -/* groupset_add locks ADD, then calls groupset_add_group, which locks - GS. Don't do groupset_add(a,b) PAR groupset_add(b,a). */ -int nn_groupset_add (struct nn_groupset *gs, const struct nn_groupset *add); - -void nn_groupset_free (struct nn_groupset *gs); -int nn_groupset_fromqos (struct nn_groupset *gs, v_kernel kernel, const nn_xqos_t *qos); -struct nn_groupset *nn_groupset_new (void); - -/* groupset_foreach locks GS, and keeps it locked across calls to f() */ -int nn_groupset_foreach (const struct nn_groupset *gs, nn_groupset_foreach_t f, void *arg); -int nn_groupset_empty (const struct nn_groupset *gs); - -#endif /* NN_GROUPSET_H */ - -/* SHA1 not available (unoffical build.) */ diff --git a/src/services/ddsi2/code/q_hbcontrol.h b/src/services/ddsi2/code/q_hbcontrol.h deleted file mode 100644 index ce18d5b6d..000000000 --- a/src/services/ddsi2/code/q_hbcontrol.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * OpenSplice DDS - * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -#ifndef Q_HBCONTROL_H -#define Q_HBCONTROL_H - -#if defined (__cplusplus) -extern "C" { -#endif - -struct writer; - -struct hbcontrol { - nn_mtime_t t_of_last_write; - nn_mtime_t t_of_last_hb; - nn_mtime_t t_of_last_ackhb; - nn_mtime_t tsched; - unsigned hbs_since_last_write; - unsigned last_packetid; -}; - -void writer_hbcontrol_init (struct hbcontrol *hbc); -os_int64 writer_hbcontrol_intv (const struct writer *wr, nn_mtime_t tnow); -void writer_hbcontrol_note_asyncwrite (struct writer *wr, nn_mtime_t tnow); -int writer_hbcontrol_ack_required (const struct writer *wr, nn_mtime_t tnow); -struct nn_xmsg *writer_hbcontrol_piggyback (struct writer *wr, nn_mtime_t tnow, unsigned packetid, int *hbansreq); -int writer_hbcontrol_must_send (const struct writer *wr, nn_mtime_t tnow); -struct nn_xmsg *writer_hbcontrol_create_heartbeat (struct writer *wr, nn_mtime_t tnow, int hbansreq, int issync); - -#if defined (__cplusplus) -} -#endif - -#endif /* Q_HBCONTROL_H */ - -/* SHA1 not available (unoffical build.) */ diff --git a/src/services/ddsi2/code/q_lat_estim.h b/src/services/ddsi2/code/q_lat_estim.h deleted file mode 100644 index 919146119..000000000 --- a/src/services/ddsi2/code/q_lat_estim.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * OpenSplice DDS - * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -#ifndef NN_LAT_ESTIM_H -#define NN_LAT_ESTIM_H - -#include "os_defs.h" - -#include "q_log.h" - -#if defined (__cplusplus) -extern "C" { -#endif - -#define NN_LAT_ESTIM_MEDIAN_WINSZ 7 - -struct nn_lat_estim { - /* median filtering with a small window in an attempt to remove the - worst outliers */ - int index; - float window[NN_LAT_ESTIM_MEDIAN_WINSZ]; - /* simple alpha filtering for smoothing */ - float smoothed; -}; - -void nn_lat_estim_init (struct nn_lat_estim *le); -void nn_lat_estim_fini (struct nn_lat_estim *le); -void nn_lat_estim_update (struct nn_lat_estim *le, os_int64 est); -double nn_lat_estim_current (const struct nn_lat_estim *le); -int nn_lat_estim_log (logcat_t logcat, const char *tag, const struct nn_lat_estim *le); - -#if defined (__cplusplus) -} -#endif - -#endif /* NN_LAT_ESTIM_H */ - -/* SHA1 not available (unoffical build.) */ diff --git a/src/services/ddsi2/code/q_lease.h b/src/services/ddsi2/code/q_lease.h deleted file mode 100644 index 8b07d193d..000000000 --- a/src/services/ddsi2/code/q_lease.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * OpenSplice DDS - * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -#ifndef Q_LEASE_H -#define Q_LEASE_H - -#include "q_time.h" - -#if defined (__cplusplus) -extern "C" { -#endif - -struct receiver_state; -struct participant; -struct lease; -struct entity_common; -struct thread_state1; - -void lease_management_init (void); -void lease_management_term (void); -struct lease *lease_new (os_int64 tdur, struct entity_common *e); -void lease_register (struct lease *l); -void lease_free (struct lease *l); -void lease_renew (struct lease *l, nn_etime_t tnow); -void check_and_handle_lease_expiration (struct thread_state1 *self, nn_etime_t tnow); - -void handle_PMD (const struct receiver_state *rst, unsigned statusinfo, const void *vdata, unsigned len); - -#if defined (__cplusplus) -} -#endif - -#endif /* Q_LEASE_H */ - -/* SHA1 not available (unoffical build.) */ diff --git a/src/services/ddsi2/code/q_log.h b/src/services/ddsi2/code/q_log.h deleted file mode 100644 index d5c7c5acb..000000000 --- a/src/services/ddsi2/code/q_log.h +++ /dev/null @@ -1,243 +0,0 @@ -/* - * OpenSplice DDS - * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -#ifndef NN_LOG_H -#define NN_LOG_H - -#include - -#include "os_report.h" -#include "os_defs.h" -#include "q_time.h" - -#if defined (__cplusplus) -extern "C" { -#endif - -#ifdef OSPL_BUILD_DDSI2 -#define OS_API OS_API_EXPORT -#else -#define OS_API OS_API_IMPORT -#endif - -#define LC_FATAL 1u -#define LC_ERROR 2u -#define LC_WARNING 4u -#define LC_CONFIG 8u -#define LC_INFO 16u -#define LC_DISCOVERY 32u -#define LC_DATA 64u -#define LC_TRACE 128u -#define LC_RADMIN 256u -#define LC_TIMING 512u -#define LC_TRAFFIC 1024u -#define LC_TOPIC 2048u -#define LC_TCP 4096u -#define LC_PLIST 8192u -#define LC_WHC 16384u -#define LC_ALLCATS (LC_FATAL | LC_ERROR | LC_WARNING | LC_CONFIG | LC_INFO | LC_DISCOVERY | LC_DATA | LC_TRACE | LC_TIMING | LC_TRAFFIC | LC_TCP) - -typedef unsigned logcat_t; - -typedef struct logbuf { - char buf[2048]; - size_t bufsz; - size_t pos; - nn_wctime_t tstamp; -} *logbuf_t; - -logbuf_t logbuf_new (void); -void logbuf_init (logbuf_t lb); -void logbuf_free (logbuf_t lb); - -int nn_vlog (logcat_t cat, const char *fmt, va_list ap); -OS_API int nn_log (logcat_t cat, const char *fmt, ...) __attribute_format__((printf,2,3)); -OS_API int nn_trace (const char *fmt, ...) __attribute_format__((printf,1,2)); -void nn_log_set_tstamp (nn_wctime_t tnow); - -#define TRACE(args) ((config.enabled_logcats & LC_TRACE) ? (nn_trace args) : 0) - -#define LOG_THREAD_CPUTIME(guard) do { \ - if (config.enabled_logcats & LC_TIMING) \ - { \ - nn_mtime_t tnow = now_mt (); \ - if (tnow.v >= (guard).v) \ - { \ - os_int64 ts = get_thread_cputime (); \ - nn_log (LC_TIMING, "thread_cputime %d.%09d\n", \ - (int) (ts / T_SECOND), (int) (ts % T_SECOND)); \ - (guard).v = tnow.v + T_SECOND; \ - } \ - } \ - } while (0) - - -#define NN_WARNING0(fmt) do { \ - nn_log (LC_WARNING, (fmt)); \ - os_report (OS_WARNING, config.servicename, __FILE__, __LINE__, 0, (fmt)); \ - } while (0) -#define NN_WARNING1(fmt,a) do { \ - nn_log (LC_WARNING, (fmt), a); \ - os_report (OS_WARNING, config.servicename, __FILE__, __LINE__, 0, (fmt), a); \ - } while (0) -#define NN_WARNING2(fmt,a,b) do { \ - nn_log (LC_WARNING, (fmt), a, b); \ - os_report (OS_WARNING, config.servicename, __FILE__, __LINE__, 0, (fmt), a, b); \ - } while (0) -#define NN_WARNING3(fmt,a,b,c) do { \ - nn_log (LC_WARNING, (fmt), a, b, c); \ - os_report (OS_WARNING, config.servicename, __FILE__, __LINE__, 0, (fmt), a, b, c); \ - } while (0) -#define NN_WARNING4(fmt,a,b,c,d) do { \ - nn_log (LC_WARNING, (fmt), a, b, c, d); \ - os_report (OS_WARNING, config.servicename, __FILE__, __LINE__, 0, (fmt), a, b, c, d); \ - } while (0) -#define NN_WARNING5(fmt,a,b,c,d,e) do { \ - nn_log (LC_WARNING, (fmt), a, b, c, d, e); \ - os_report (OS_WARNING, config.servicename, __FILE__, __LINE__, 0, (fmt), a, b, c, d, e); \ - } while (0) -#define NN_WARNING6(fmt,a,b,c,d,e,f) do { \ - nn_log (LC_WARNING, (fmt), a, b, c, d, e, f); \ - os_report (OS_WARNING, config.servicename, __FILE__, __LINE__, 0, (fmt), a, b, c, d, e, f); \ - } while (0) -#define NN_WARNING7(fmt,a,b,c,d,e,f,g) do { \ - nn_log (LC_WARNING, (fmt), a, b, c, d, e, f, g); \ - os_report (OS_WARNING, config.servicename, __FILE__, __LINE__, 0, (fmt), a, b, c, d, e, f, g); \ - } while (0) -#define NN_WARNING8(fmt,a,b,c,d,e,f,g,h) do { \ - nn_log (LC_WARNING, (fmt), a, b, c, d, e, f, g, h); \ - os_report (OS_WARNING, config.servicename, __FILE__, __LINE__, 0, (fmt), a, b, c, d, e, f, g, h); \ - } while (0) -#define NN_WARNING9(fmt,a,b,c,d,e,f,g,h,i) do { \ - nn_log (LC_WARNING, (fmt), a, b, c, d, e, f, g, h, i); \ - os_report (OS_WARNING, config.servicename, __FILE__, __LINE__, 0, (fmt), a, b, c, d, e, f, g, h, i); \ - } while (0) -#define NN_WARNING10(fmt,a,b,c,d,e,f,g,h,i,j) do { \ - nn_log (LC_WARNING, (fmt), a, b, c, d, e, f, g, h, i, j); \ - os_report (OS_WARNING, config.servicename, __FILE__, __LINE__, 0, (fmt), a, b, c, d, e, f, g, h, i, j); \ - } while (0) - -#define NN_ERROR0(fmt) do { \ - nn_log (LC_ERROR, (fmt)); \ - os_report (OS_ERROR, config.servicename, __FILE__, __LINE__, 0, (fmt)); \ - } while (0) -#define NN_ERROR1(fmt,a) do { \ - nn_log (LC_ERROR, (fmt), a); \ - os_report (OS_ERROR, config.servicename, __FILE__, __LINE__, 0, (fmt), a); \ - } while (0) -#define NN_ERROR2(fmt,a,b) do { \ - nn_log (LC_ERROR, (fmt), a, b); \ - os_report (OS_ERROR, config.servicename, __FILE__, __LINE__, 0, (fmt), a, b); \ - } while (0) -#define NN_ERROR3(fmt,a,b,c) do { \ - nn_log (LC_ERROR, (fmt), a, b, c); \ - os_report (OS_ERROR, config.servicename, __FILE__, __LINE__, 0, (fmt), a, b, c); \ - } while (0) -#define NN_ERROR4(fmt,a,b,c,d) do { \ - nn_log (LC_ERROR, (fmt), a, b, c, d); \ - os_report (OS_ERROR, config.servicename, __FILE__, __LINE__, 0, (fmt), a, b, c, d); \ - } while (0) -#define NN_ERROR5(fmt,a,b,c,d,e) do { \ - nn_log (LC_ERROR, (fmt), a, b, c, d, e); \ - os_report (OS_ERROR, config.servicename, __FILE__, __LINE__, 0, (fmt), a, b, c, d, e); \ - } while (0) -#define NN_ERROR6(fmt,a,b,c,d,e,f) do { \ - nn_log (LC_ERROR, (fmt), a, b, c, d, e, f); \ - os_report (OS_ERROR, config.servicename, __FILE__, __LINE__, 0, (fmt), a, b, c, d, e, f); \ - } while (0) -#define NN_ERROR7(fmt,a,b,c,d,e,f,g) do { \ - nn_log (LC_ERROR, (fmt), a, b, c, d, e, f, g); \ - os_report (OS_ERROR, config.servicename, __FILE__, __LINE__, 0, (fmt), a, b, c, d, e, f, g); \ - } while (0) -#define NN_ERROR8(fmt,a,b,c,d,e,f,g,h) do { \ - nn_log (LC_ERROR, (fmt), a, b, c, d, e, f, g, h); \ - os_report (OS_ERROR, config.servicename, __FILE__, __LINE__, 0, (fmt), a, b, c, d, e, f, g, h); \ - } while (0) -#define NN_ERROR9(fmt,a,b,c,d,e,f,g,h,i) do { \ - nn_log (LC_ERROR, (fmt), a, b, c, d, e, f, g, h, i); \ - os_report (OS_ERROR, config.servicename, __FILE__, __LINE__, 0, (fmt), a, b, c, d, e, f, g, h, i); \ - } while (0) -#define NN_ERROR10(fmt,a,b,c,d,e,f,g,h,i,j) do { \ - nn_log (LC_ERROR, (fmt), a, b, c, d, e, f, g, h, i, j); \ - os_report (OS_ERROR, config.servicename, __FILE__, __LINE__, 0, (fmt), a, b, c, d, e, f, g, h, i, j); \ - } while (0) - -#define NN_FATAL0(fmt) do { \ - nn_log (LC_FATAL, (fmt)); \ - os_report (OS_FATAL, config.servicename, __FILE__, __LINE__, 0, (fmt)); \ - abort (); \ - } while (0) -#define NN_FATAL1(fmt,a) do { \ - nn_log (LC_FATAL, (fmt), a); \ - os_report (OS_FATAL, config.servicename, __FILE__, __LINE__, 0, (fmt), a); \ - abort (); \ - } while (0) -#define NN_FATAL2(fmt,a,b) do { \ - nn_log (LC_FATAL, (fmt), a, b); \ - os_report (OS_FATAL, config.servicename, __FILE__, __LINE__, 0, (fmt), a, b); \ - abort (); \ - } while (0) -#define NN_FATAL3(fmt,a,b,c) do { \ - nn_log (LC_FATAL, (fmt), a, b, c); \ - os_report (OS_FATAL, config.servicename, __FILE__, __LINE__, 0, (fmt), a, b, c); \ - abort (); \ - } while (0) -#define NN_FATAL4(fmt,a,b,c,d) do { \ - nn_log (LC_FATAL, (fmt), a, b, c, d); \ - os_report (OS_FATAL, config.servicename, __FILE__, __LINE__, 0, (fmt), a, b, c, d); \ - abort (); \ - } while (0) -#define NN_FATAL5(fmt,a,b,c,d,e) do { \ - nn_log (LC_FATAL, (fmt), a, b, c, d, e); \ - os_report (OS_FATAL, config.servicename, __FILE__, __LINE__, 0, (fmt), a, b, c, d, e); \ - abort (); \ - } while (0) -#define NN_FATAL6(fmt,a,b,c,d,e,f) do { \ - nn_log (LC_FATAL, (fmt), a, b, c, d, e, f); \ - os_report (OS_FATAL, config.servicename, __FILE__, __LINE__, 0, (fmt), a, b, c, d, e, f); \ - abort (); \ - } while (0) -#define NN_FATAL7(fmt,a,b,c,d,e,f,g) do { \ - nn_log (LC_FATAL, (fmt), a, b, c, d, e, f, g); \ - os_report (OS_FATAL, config.servicename, __FILE__, __LINE__, 0, (fmt), a, b, c, d, e, f, g); \ - abort (); \ - } while (0) -#define NN_FATAL8(fmt,a,b,c,d,e,f,g,h) do { \ - nn_log (LC_FATAL, (fmt), a, b, c, d, e, f, g, h); \ - os_report (OS_FATAL, config.servicename, __FILE__, __LINE__, 0, (fmt), a, b, c, d, e, f, g, h); \ - abort (); \ - } while (0) -#define NN_FATAL9(fmt,a,b,c,d,e,f,g,h,i) do { \ - nn_log (LC_FATAL, (fmt), a, b, c, d, e, f, g, h, i); \ - os_report (OS_FATAL, config.servicename, __FILE__, __LINE__, 0, (fmt), a, b, c, d, e, f, g, h, i); \ - abort (); \ - } while (0) -#define NN_FATAL10(fmt,a,b,c,d,e,f,g,h,i,j) do { \ - nn_log (LC_FATAL, (fmt), a, b, c, d, e, f, g, h, i, j); \ - os_report (OS_FATAL, config.servicename, __FILE__, __LINE__, 0, (fmt), a, b, c, d, e, f, g, h, i, j); \ - abort (); \ - } while (0) -#undef OS_API -#if defined (__cplusplus) -} -#endif - -#endif /* NN_LOG_H */ - -/* SHA1 not available (unoffical build.) */ diff --git a/src/services/ddsi2/code/q_misc.c b/src/services/ddsi2/code/q_misc.c deleted file mode 100644 index 79607edf1..000000000 --- a/src/services/ddsi2/code/q_misc.c +++ /dev/null @@ -1,153 +0,0 @@ -/* - * OpenSplice DDS - * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -#include - -#include "kernelModule.h" -#include "q_misc.h" -#include "q_bswap.h" -#include "q_md5.h" - -int vendor_is_rti (nn_vendorid_t vendor) -{ - const nn_vendorid_t rti = NN_VENDORID_RTI; - return vendor.id[0] == rti.id[0] && vendor.id[1] == rti.id[1]; -} - -int vendor_is_twinoaks (nn_vendorid_t vendor) -{ - const nn_vendorid_t twinoaks = NN_VENDORID_TWINOAKS; - return vendor.id[0] == twinoaks.id[0] && vendor.id[1] == twinoaks.id[1]; -} - -int vendor_is_cloud (nn_vendorid_t vendor) -{ - const nn_vendorid_t cloud = NN_VENDORID_PRISMTECH_CLOUD; - return vendor.id[0] == cloud.id[0] && vendor.id[1] == cloud.id[1]; -} - -int vendor_is_prismtech (nn_vendorid_t vid) -{ - const nn_vendorid_t pt1 = NN_VENDORID_PRISMTECH_OSPL; - const nn_vendorid_t pt2 = NN_VENDORID_PRISMTECH_LITE; - const nn_vendorid_t pt3 = NN_VENDORID_PRISMTECH_GATEWAY; - const nn_vendorid_t pt4 = NN_VENDORID_PRISMTECH_JAVA; - const nn_vendorid_t pt5 = NN_VENDORID_PRISMTECH_CLOUD; - - return - (vid.id[0] == pt1.id[0]) && - ((vid.id[1] == pt1.id[1]) || (vid.id[1] == pt2.id[1]) - || (vid.id[1] == pt3.id[1]) || (vid.id[1] == pt4.id[1]) - || (vid.id[1] == pt5.id[1])); -} - -int vendor_is_opensplice (nn_vendorid_t vid) -{ - const nn_vendorid_t pt1 = NN_VENDORID_PRISMTECH_OSPL; - return (vid.id[0] == pt1.id[0] && vid.id[1] == pt1.id[1]); -} - -int is_own_vendor (nn_vendorid_t vendor) -{ - const nn_vendorid_t ownid = MY_VENDOR_ID; - return vendor.id[0] == ownid.id[0] && vendor.id[1] == ownid.id[1]; -} - -int gid_is_fake (const struct v_gid_s *gid) -{ - /* 0:0:0 is not so much fake as invalid, but here they both mean we - pretend there is no gid. For the localId mask, see v_handle.c -- - this is very much an undocumented characteristic of GIDs ... */ - if (gid->systemId == 0 && gid->localId == 0 && gid->serial == 0) - return 1; - else if (gid->localId & 0xffc00000) - return 1; - else - return 0; -} - -os_int64 fromSN (const nn_sequence_number_t sn) -{ - return ((os_int64) sn.high << 32) | sn.low; -} - -nn_sequence_number_t toSN (os_int64 n) -{ - nn_sequence_number_t x; - x.high = (int) (n >> 32); - x.low = (unsigned) n; - return x; -} - - -int ddsi2_patmatch (const char *pat, const char *str) -{ - c_value p, n, r; - p.kind = n.kind = V_STRING; - p.is.String = (char *) pat; - n.is.String = (char *) str; - r = c_valueStringMatch (p, n); - return r.is.Boolean; -} - -void nn_guid_to_ospl_gid (v_gid *gid, const nn_guid_t *guid, int guid_has_systemid) -{ - /* Try hard to fake a writer id for OpenSplice based on a GUID. All - systems I know of have something resembling a host/system id in - the first 32 bits, so copy that as the system id and copy half of - an MD5 hash into the remaining 64 bits. Now if only OpenSplice - would use all 96 bits as a key, we'd be doing reasonably well ... */ - const nn_guid_t nguid = nn_hton_guid (*guid); - union { os_uint32 u[4]; unsigned char md5[16]; } hp, hg; - md5_state_t md5st; - - if (guid_has_systemid) - { - /* for old OpenSplice versions: modern durability relies on the systemId for - liveliness of its fellows, so we must not modify it */ - gid->systemId = guid->prefix.u[0]; - } - else - { - md5_init (&md5st); - md5_append (&md5st, (unsigned char *) &nguid.prefix, sizeof (nguid.prefix)); - md5_finish (&md5st, hp.md5); - gid->systemId = fromBE4u (hp.u[0]); - } - - md5_init (&md5st); - md5_append (&md5st, (unsigned char *) &nguid, sizeof (nguid)); - md5_finish (&md5st, hg.md5); - - /* See also gid_is_fake for the masking of bits in localId */ - gid->localId = fromBE4u (hg.u[0]) & 0x3fffff; - gid->serial = guid->entityid.u; -} - -int version_info_is_6_4_1 (const char *internals) -{ - /* node/version/...; unfortunately, the version is quoted on some platforms */ - const char *p; - if (internals == NULL || (p = strchr (internals, '/')) == NULL) - return 0; - return (strncmp (p + 1, "V6.4.1/", 7) == 0 || strncmp (p + 1, "\"V6.4.1\"/", 9) == 0); -} - - -/* SHA1 not available (unoffical build.) */ diff --git a/src/services/ddsi2/code/q_misc.h b/src/services/ddsi2/code/q_misc.h deleted file mode 100644 index 847081ba0..000000000 --- a/src/services/ddsi2/code/q_misc.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * OpenSplice DDS - * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -#ifndef NN_MISC_H -#define NN_MISC_H - -#include "q_protocol.h" - -#if defined (__cplusplus) -extern "C" { -#endif - -struct v_gid_s; -struct nn_guid; - -int vendor_is_opensplice (nn_vendorid_t vid); -int vendor_is_rti (nn_vendorid_t vendor); -int vendor_is_twinoaks (nn_vendorid_t vendor); -int vendor_is_prismtech (nn_vendorid_t vendor); -int vendor_is_cloud (nn_vendorid_t vendor); -int is_own_vendor (nn_vendorid_t vendor); -unsigned char normalize_data_datafrag_flags (const SubmessageHeader_t *smhdr, int datafrag_as_data); -int version_info_is_6_4_1 (const char *internals); - -os_int64 fromSN (const nn_sequence_number_t sn); -nn_sequence_number_t toSN (os_int64); - - -int ddsi2_patmatch (const char *pat, const char *str); - -void nn_guid_to_ospl_gid (struct v_gid_s *gid, const struct nn_guid *guid, int guid_has_systemid); -int gid_is_fake (const struct v_gid_s *gid); - - -#if defined (__cplusplus) -} -#endif - -#endif /* NN_MISC_H */ - -/* SHA1 not available (unoffical build.) */ diff --git a/src/services/ddsi2/code/q_mtreader.h b/src/services/ddsi2/code/q_mtreader.h deleted file mode 100644 index 6787fcbd5..000000000 --- a/src/services/ddsi2/code/q_mtreader.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - * OpenSplice DDS - * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -#ifndef Q_MTREADER_H -#define Q_MTREADER_H - -#include "ut_avl.h" -#include "ut_fibheap.h" - -struct mtreader; -struct u_topic_s; - -enum mtr_sample_state { - MTR_SST_NEW, - MTR_SST_UPD, - MTR_SST_DEL -}; - -struct mtr_iter { - ut_avlIter_t it; -}; - -struct mtr_sample { - ut_avlNode_t avlnode; - ut_fibheapNode_t fhnode; - v_gid gid; - unsigned ntopics; - enum mtr_sample_state state; - nn_mtime_t texpire; - unsigned flag; -#if __STDC_VERSION__ >= 199901L - struct v_message_s *vmsg[/* ntopics */]; -#else - struct v_message_s *vmsg[1]; -#endif -}; - -/* NOTE: Only for readers of built-in topics, that have the of a GID as key, - and that should have the full GID as a key */ - -struct mtreader *new_mtreader (unsigned ntopics, struct u_topic_s **topics); -void delete_mtreader (struct mtreader *mtr); - -int update_mtreader (struct mtreader *mtr, const struct mtr_sample *outputs[2], const struct u_topic_s *tp, v_state sample_state, struct v_message_s *vmsg); - -/* Updates UDATA field in mtr_sample corresponding to KEY; returns ERR_INVALID_DATA if no such sample */ -int update_mtreader_setflag (struct mtreader *mtr, const v_gid *key, unsigned flag); - -/* Allocates and returns array of live, complete samples for which pred(&TP.FIELD,B) && !FLAG, return value is length. All returned samples are in state UPD. */ -int query_mtreader (const struct mtreader *mtr, const struct mtr_sample ***result, const struct u_topic_s *tp, const char *field, int (*pred) (const void *a, const void *b), const void *b); - -const struct mtr_sample *mtr_first (const struct mtreader *mtr, struct mtr_iter *it); -const struct mtr_sample *mtr_next (struct mtr_iter *it); - -#endif - -/* SHA1 not available (unoffical build.) */ diff --git a/src/services/ddsi2/code/q_osplbuiltin.h b/src/services/ddsi2/code/q_osplbuiltin.h deleted file mode 100644 index 7ca00b366..000000000 --- a/src/services/ddsi2/code/q_osplbuiltin.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * OpenSplice DDS - * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -#ifndef Q_OSPLBUILTIN_H -#define Q_OSPLBUILTIN_H - -struct v_subscriptionInfo; -struct v_publicationInfo; -struct v_publisherCMInfo; -struct v_subscriberCMInfo; -struct v_topicInfo; -struct u_participant_s; -struct v_topicQos_s; -struct nn_xqos; -struct nn_plist; - -int init_reader_qos (const struct v_subscriptionInfo *data, const struct v_dataReaderCMInfo *cmdata, struct nn_xqos *xqos, int interpret_user_data); -int init_writer_qos (const struct v_publicationInfo *data, const struct v_dataWriterCMInfo *cmdata, v_topic ospl_topic, struct nn_xqos *xqos, int interpret_user_data); -int init_reader_qos_from_topicQos (const struct v_topicQos_s *data, struct nn_xqos *xqos); -int init_topic_plist (const struct v_topicInfo *data, struct nn_plist *ps); -int init_cm_publisher_plist (const struct v_publisherCMInfo *data, const nn_guid_t *guid, struct nn_plist *ps); -int init_cm_subscriber_plist (const struct v_subscriberCMInfo *data, const nn_guid_t *guid, struct nn_plist *ps); -int init_participant_plist (const struct v_participantInfo *data, const struct v_participantCMInfo *cmdata, struct nn_plist *ps); -u_result create_builtin_topic_writers (struct u_participant_s *p); -int is_builtin_topic_writer (const struct v_gid_s *gid); -void destroy_builtin_topic_writers (void); -int is_topic_discoverable (const char *topic); - -#endif - -/* SHA1 not available (unoffical build.) */ diff --git a/src/services/ddsi2/code/q_osplserModule.odl b/src/services/ddsi2/code/q_osplserModule.odl deleted file mode 100644 index 2eaad8132..000000000 --- a/src/services/ddsi2/code/q_osplserModule.odl +++ /dev/null @@ -1,62 +0,0 @@ -/* -*- C -*- - * OpenSplice DDS - * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -module q_osplserModule { - typedef struct type4u_s { - c_ulong a; - c_ulong b; - c_ulong c; - c_ulong d; - } type4u; - - typedef struct pmd_s { - c_ulong a; - c_ulong b; - c_ulong c; /* officially: octets */ - c_ulong kind; /* officially: octets */ - sequence value; - } pmd; - - enum bubble_kind { - BTK_DELETE_WRITER - }; - - typedef struct bubble_s { - bubble_kind kind; - c_ulong systemId; - c_ulong localId; - c_ulong serial; - } bubble; - - struct name_value { - string name; - string value; - }; - typedef sequence seq_name_value; - - struct ddsi_control { - c_ulong systemId; - c_ulong localId; - c_ulong serial; - c_bool deaf_mute; - c_double duration; /* 0: infinite */ - }; -}; - -/* SHA1 not available (unoffical build.) */ diff --git a/src/services/ddsi2/code/q_pcap.h b/src/services/ddsi2/code/q_pcap.h deleted file mode 100644 index ec6c0595c..000000000 --- a/src/services/ddsi2/code/q_pcap.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * OpenSplice DDS - * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -#ifndef Q_PCAP_H -#define Q_PCAP_H - -#include -#include "q_time.h" - -#if defined (__cplusplus) -extern "C" { -#endif - -struct msghdr; - -FILE * new_pcap_file (const char *name); - -void write_pcap_received -( - FILE * fp, - nn_wctime_t tstamp, - const os_sockaddr_storage * src, - const os_sockaddr_storage * dst, - unsigned char * buf, - os_size_t sz -); - -void write_pcap_sent -( - FILE * fp, - nn_wctime_t tstamp, - const os_sockaddr_storage * src, - const struct msghdr * hdr, - os_size_t sz -); - -#if defined (__cplusplus) -} -#endif - -#endif /* Q_PCAP_H */ - -/* SHA1 not available (unoffical build.) */ diff --git a/src/services/ddsi2/code/q_qosmatch.h b/src/services/ddsi2/code/q_qosmatch.h deleted file mode 100644 index 7b4840bd4..000000000 --- a/src/services/ddsi2/code/q_qosmatch.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * OpenSplice DDS - * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -#ifndef Q_QOSMATCH_H -#define Q_QOSMATCH_H - -#if defined (__cplusplus) -extern "C" { -#endif - -struct nn_xqos; - -int partition_match_based_on_wildcard_in_left_operand (const struct nn_xqos *a, const struct nn_xqos *b, const char **realname); -int partitions_match_p (const struct nn_xqos *a, const struct nn_xqos *b); -int is_wildcard_partition (const char *str); - -/* Returns -1 on success, or QoS id of first missmatch (>=0) */ - -os_int32 qos_match_p (const struct nn_xqos *rd, const struct nn_xqos *wr); - -#if defined (__cplusplus) -} -#endif - -#endif /* Q_QOSMATCH_H */ - -/* SHA1 not available (unoffical build.) */ diff --git a/src/services/ddsi2/code/q_receive.h b/src/services/ddsi2/code/q_receive.h deleted file mode 100644 index 37a67753a..000000000 --- a/src/services/ddsi2/code/q_receive.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * OpenSplice DDS - * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -#ifndef Q_RECEIVE_H -#define Q_RECEIVE_H - -#if defined (__cplusplus) -extern "C" { -#endif - -struct nn_rbufpool; -struct nn_rsample_info; -struct nn_rdata; -struct ddsi_tran_listener; - -void *recv_thread (struct nn_rbufpool *rbpool); -void *listen_thread (struct ddsi_tran_listener * listener); -int user_dqueue_handler (const struct nn_rsample_info *sampleinfo, const struct nn_rdata *fragchain, const nn_guid_t *rdguid, void *qarg); - -#if defined (__cplusplus) -} -#endif - -#endif /* Q_RECEIVE_H */ - -/* SHA1 not available (unoffical build.) */ diff --git a/src/services/ddsi2/code/q_security.c b/src/services/ddsi2/code/q_security.c deleted file mode 100644 index 30fc3e679..000000000 --- a/src/services/ddsi2/code/q_security.c +++ /dev/null @@ -1,24 +0,0 @@ -/* - * OpenSplice DDS - * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -int ddsi_dummy_val = 0; - - -/* SHA1 not available (unoffical build.) */ diff --git a/src/services/ddsi2/code/q_servicelease.h b/src/services/ddsi2/code/q_servicelease.h deleted file mode 100644 index 49ff9024b..000000000 --- a/src/services/ddsi2/code/q_servicelease.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * OpenSplice DDS - * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -#ifndef NN_SERVICELEASE_H -#define NN_SERVICELEASE_H - -#if defined (__cplusplus) -extern "C" { -#endif - -struct nn_servicelease; - -struct nn_servicelease *nn_servicelease_new (void (*renew_cb) (void *arg), void *renew_arg); -int nn_servicelease_start_renewing (struct nn_servicelease *sl); -void nn_servicelease_free (struct nn_servicelease *sl); -void nn_servicelease_statechange_barrier (struct nn_servicelease *sl); - -#if defined (__cplusplus) -} -#endif - -#endif /* NN_SERVICELEASE_H */ - -/* SHA1 not available (unoffical build.) */ diff --git a/src/services/ddsi2/code/q_static_assert.h b/src/services/ddsi2/code/q_static_assert.h deleted file mode 100644 index abf852ab5..000000000 --- a/src/services/ddsi2/code/q_static_assert.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * OpenSplice DDS - * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -#ifndef Q_STATIC_ASSERT_H -#define Q_STATIC_ASSERT_H - -/* There are many tricks to use a constant expression to yield an - illegal type or expression at compile time, such as zero-sized - arrays and duplicate case or enum labels. So this is but one of the - many tricks. */ - -#define Q_STATIC_ASSERT_CODE(pred) do { switch(0) { case 0: case pred: ; } } while (0) - -#endif /* Q_STATIC_ASSERT_H */ - -/* SHA1 not available (unoffical build.) */ diff --git a/src/services/ddsi2/code/q_thread_inlines.c b/src/services/ddsi2/code/q_thread_inlines.c deleted file mode 100644 index 0633a13df..000000000 --- a/src/services/ddsi2/code/q_thread_inlines.c +++ /dev/null @@ -1,25 +0,0 @@ -/* - * OpenSplice DDS - * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -#define SUPPRESS_THREAD_INLINES - -#include "q_thread.h" -#include "q_thread_template.c" - -/* SHA1 not available (unoffical build.) */ diff --git a/src/services/ddsi2/code/q_transmit.h b/src/services/ddsi2/code/q_transmit.h deleted file mode 100644 index 5fab8323a..000000000 --- a/src/services/ddsi2/code/q_transmit.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * OpenSplice DDS - * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -#ifndef Q_TRANSMIT_H -#define Q_TRANSMIT_H - -#include "os_defs.h" -#include "q_rtps.h" /* for nn_entityid_t */ - -#if defined (__cplusplus) -extern "C" { -#endif - -struct nn_xpack; -struct nn_xmsg; -struct writer; -struct proxy_reader; -struct serdata; - -/* Writing new data; serdata_twrite (serdata) is assumed to be really - recentish; serdata is unref'd. If xp == NULL, data is queued, else - packed. */ -int write_sample (struct nn_xpack *xp, struct writer *wr, struct serdata *serdata); -int write_sample_kernel_seq (struct nn_xpack *xp, struct writer *wr, struct serdata *serdata, int have_kernel_seq, os_uint32 kernel_seq); - -void begin_coherent_set (struct writer *wr); -/* plist (if != NULL) gets "consumed" by end_coherent_set */ -int end_coherent_set (struct nn_xpack *xp, struct writer *wr, struct nn_plist *plist, struct serdata *serdata, int have_kernel_seq, os_uint32 kernel_seq); - -/* When calling the following functions, wr->lock must be held */ -int create_fragment_message (struct writer *wr, os_int64 seq, const struct nn_plist *plist, struct serdata *serdata, unsigned fragnum, struct proxy_reader *prd,struct nn_xmsg **msg, int isnew); -int enqueue_sample_wrlock_held (struct writer *wr, os_int64 seq, const struct nn_plist *plist, struct serdata *serdata, struct proxy_reader *prd, int isnew); -void add_Heartbeat (struct nn_xmsg *msg, struct writer *wr, int hbansreq, nn_entityid_t dst, int issync); - -#if defined (__cplusplus) -} -#endif - -#endif /* Q_TRANSMIT_H */ - -/* SHA1 not available (unoffical build.) */ diff --git a/src/services/ddsi2/code/q_unused.h b/src/services/ddsi2/code/q_unused.h deleted file mode 100644 index a527b7403..000000000 --- a/src/services/ddsi2/code/q_unused.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * OpenSplice DDS - * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -#ifndef NN_UNUSED_H -#define NN_UNUSED_H - -#ifdef __GNUC__ -#define UNUSED_ARG(x) x __attribute__ ((unused)) -#else -#define UNUSED_ARG(x) x -#endif - -#ifndef NDEBUG -#define UNUSED_ARG_NDEBUG(x) x -#else -#define UNUSED_ARG_NDEBUG(x) UNUSED_ARG (x) -#endif - -#endif /* NN_UNUSED_H */ - -/* SHA1 not available (unoffical build.) */ diff --git a/src/services/ddsi2/generate.mak b/src/services/ddsi2/generate.mak new file mode 100644 index 000000000..3cd238da9 --- /dev/null +++ b/src/services/ddsi2/generate.mak @@ -0,0 +1,20 @@ + +all link: sources + +.PHONY: code_clean +code_clean: + @rm -rf code + +clean: code_clean + +DDSI2E_SOURCES := $(wildcard $(addprefix ../ddsi2e/code/, *.[ch] *.template *.odl)) $(wildcard $(addprefix ../ddsi2e/core/, *.[ch] *.template *.odl)) + +.PHONY: sources +sources: code/.STAMP + +code/.STAMP: ../ddsi2e/sanitize.sh ../ddsi2e/sanitize.pl $(DDSI2E_SOURCES) + ../ddsi2e/sanitize.sh ../ddsi2e/sanitize.pl ../ddsi2e/code ../ddsi2e/core code + touch $@ + + + diff --git a/src/services/ddsi2/makefile b/src/services/ddsi2/makefile index 9d3d2442d..fae5c02c2 100644 --- a/src/services/ddsi2/makefile +++ b/src/services/ddsi2/makefile @@ -3,9 +3,10 @@ include $(OSPL_HOME)/setup/makefiles/makefile.mak all link: bld/$(SPLICE_TARGET)/makefile @$(MAKE) -C bld/$(SPLICE_TARGET) $@ - clean: @rm -rf bld/$(SPLICE_TARGET) osplconf osplconf-update: bld/$(SPLICE_TARGET)/makefile @$(MAKE) -C bld/$(SPLICE_TARGET) $@ + +-include generate.mak diff --git a/src/services/ddsi2/makefile.mak b/src/services/ddsi2/makefile.mak index 953538b78..f7ec74797 100644 --- a/src/services/ddsi2/makefile.mak +++ b/src/services/ddsi2/makefile.mak @@ -3,6 +3,7 @@ ODL_MODULES := q_osplserModule C_FILES_TO_FILTER := %_template.c include $(OSPL_HOME)/setup/makefiles/target.mak +-include $(OSPL_OUTER_HOME)/setup/makefiles/commercial.mak ## ## FIXME introduce LDLIBS_IN variable @@ -14,7 +15,7 @@ CPPFLAGS += -DOSPL_BUILD_DDSI2 -DMODEL_q_osplserModule_IMPLEMENTATION $(OSPL_OS_ CFLAGS += $(SHCFLAGS) CFLAGS += $(CFLAGS_XSTRICT) -#CFLAGS += $(CFLAGS_W_ERROR) +CFLAGS += $(CFLAGS_W_ERROR) #ddsi_ssl$(OBJ_POSTFIX) ddsi_tcp$(OBJ_POSTFIX) q_sockwaitset$(OBJ_POSTFIX): CFLAGS += $(CFLAGS_W_NOERROR) LDFLAGS += $(SHLDFLAGS) @@ -39,5 +40,10 @@ ifneq "$(WCECOMPAT)" "" CINCS += "-I$(WCECOMPAT)/include" endif +ifeq "$(INCLUDE_SECURITY)" "yes" +CPPFLAGS += -DDDSI_INCLUDE_SSL +CINCS += $(CINCS_NW_SEC) +LDLIBS += $(LDLIBS_NW_SEC) +endif -include $(DEPENDENCIES) diff --git a/src/services/ddsi2e/code/q_ddsi2.h b/src/services/ddsi2e/code/q_ddsi2.h new file mode 100644 index 000000000..f43bfb55b --- /dev/null +++ b/src/services/ddsi2e/code/q_ddsi2.h @@ -0,0 +1,48 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#ifndef NN_DDSI2_H +#define NN_DDSI2_H + +#include "vortex_os.h" +#include "kernelModuleI.h" +#if defined (__cplusplus) +extern "C" { +#endif + +#include "os_if.h" + +#ifdef OSPL_BUILD_DDSI2 +#define OS_API OS_API_EXPORT +#else +#define OS_API OS_API_IMPORT +#endif +/* !!!!!!!!NOTE From here no more includes are allowed!!!!!!! */ + +#ifdef DDSI2E_OR_NOT2E +OS_API OPENSPLICE_ENTRYPOINT_DECL(ospl_ddsi2e); +#else +OS_API OPENSPLICE_ENTRYPOINT_DECL(ospl_ddsi2); +#endif + +#undef OS_API + +#if defined (__cplusplus) +} +#endif + +#endif /* NN_DDSI2_H */ diff --git a/src/services/ddsi2/code/q_fill_msg_qos.c b/src/services/ddsi2e/code/q_fill_msg_qos.c similarity index 91% rename from src/services/ddsi2/code/q_fill_msg_qos.c rename to src/services/ddsi2e/code/q_fill_msg_qos.c index b019d341c..de479d623 100644 --- a/src/services/ddsi2/code/q_fill_msg_qos.c +++ b/src/services/ddsi2e/code/q_fill_msg_qos.c @@ -1,18 +1,16 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * @@ -239,5 +237,3 @@ c_array new_v_message_qos (const nn_xqos_t *xqos) memcpy (msgqos, qosbase, (size_t) (dst - qosbase)); return msgqos; } - -/* SHA1 not available (unoffical build.) */ diff --git a/src/services/ddsi2e/code/q_fill_msg_qos.h b/src/services/ddsi2e/code/q_fill_msg_qos.h new file mode 100644 index 000000000..05b777f01 --- /dev/null +++ b/src/services/ddsi2e/code/q_fill_msg_qos.h @@ -0,0 +1,32 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#ifndef Q_FILL_MSG_QOS_H +#define Q_FILL_MSG_QOS_H + +#include "os_defs.h" +#include "c_base.h" + +struct v_message; + +struct nn_xqos; +struct proxy_writer; +struct nn_prismtech_writer_info; + +c_array new_v_message_qos (const struct nn_xqos *xqos); + +#endif /* Q_FILL_MSG_QOS_H */ diff --git a/src/services/ddsi2/code/q_groupset.c b/src/services/ddsi2e/code/q_groupset.c similarity index 86% rename from src/services/ddsi2/code/q_groupset.c rename to src/services/ddsi2e/code/q_groupset.c index 368e97f15..8a2b3f8f3 100644 --- a/src/services/ddsi2/code/q_groupset.c +++ b/src/services/ddsi2e/code/q_groupset.c @@ -1,18 +1,16 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * @@ -177,5 +175,3 @@ int nn_groupset_empty (const struct nn_groupset *gs) UNLOCK (gs); return res; } - -/* SHA1 not available (unoffical build.) */ diff --git a/src/services/ddsi2e/code/q_groupset.h b/src/services/ddsi2e/code/q_groupset.h new file mode 100644 index 000000000..893507679 --- /dev/null +++ b/src/services/ddsi2e/code/q_groupset.h @@ -0,0 +1,39 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#ifndef NN_GROUPSET_H +#define NN_GROUPSET_H + +struct nn_groupset; + +typedef int (*nn_groupset_foreach_t) (v_group g, void *arg); + +int nn_groupset_add_group (struct nn_groupset *gs, v_group g); + +/* groupset_add locks ADD, then calls groupset_add_group, which locks + GS. Don't do groupset_add(a,b) PAR groupset_add(b,a). */ +int nn_groupset_add (struct nn_groupset *gs, const struct nn_groupset *add); + +void nn_groupset_free (struct nn_groupset *gs); +int nn_groupset_fromqos (struct nn_groupset *gs, v_kernel kernel, const nn_xqos_t *qos); +struct nn_groupset *nn_groupset_new (void); + +/* groupset_foreach locks GS, and keeps it locked across calls to f() */ +int nn_groupset_foreach (const struct nn_groupset *gs, nn_groupset_foreach_t f, void *arg); +int nn_groupset_empty (const struct nn_groupset *gs); + +#endif /* NN_GROUPSET_H */ diff --git a/src/services/ddsi2/code/q_main.c b/src/services/ddsi2e/code/q_main.c similarity index 88% rename from src/services/ddsi2/code/q_main.c rename to src/services/ddsi2e/code/q_main.c index b4bffcb45..44c4becae 100644 --- a/src/services/ddsi2/code/q_main.c +++ b/src/services/ddsi2e/code/q_main.c @@ -1,23 +1,20 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ - #include #include "vortex_os.h" @@ -88,8 +85,9 @@ #include "q_debmon.h" #include "ddsi_tran.h" - -#define PGID(g) ((g).systemId), ((g).localId), ((g).serial) +#ifdef OSPL_ENTRY_OVERRIDE +#include "ospl_entry_override.h" +#endif static u_participant participant = NULL; static u_subscriber networkSubscriber = NULL; @@ -150,6 +148,9 @@ struct channel_reader_arg { struct builtin_datareader_set *drset; ddsi_tran_conn_t transmit_conn; +#ifdef DDSI_INCLUDE_NETWORK_CHANNELS + struct config_channel_listelem *channel_cfg; +#endif }; static int compare_gid (const v_gid *a, const v_gid *b); @@ -275,7 +276,7 @@ static void map_group_gid_to_guid (nn_guid_t *group_guid, const struct v_gid_s * g->refc++; } *group_guid = g->guid; - nn_log (LC_DISCOVERY, "map group %x:%x:%x -> %x:%x:%x:%x refc %u (ref)\n", PGID (*group_gid), PGUID (*group_guid), g->refc); + nn_log (LC_DISCOVERY, "map group "PGIDFMT" -> "PGUIDFMT" refc %u (ref)\n", PGID (*group_gid), PGUID (*group_guid), g->refc); } else if ((g = os_malloc (sizeof (*g))) == NULL) { @@ -291,7 +292,7 @@ static void map_group_gid_to_guid (nn_guid_t *group_guid, const struct v_gid_s * ut_avlInsertIPath (&group_gid_guid_td, &group_gid_guid_tree, g, &ipath); ut_avlInsert (&group_guid_gid_td, &group_guid_gid_tree, g); *group_guid = g->guid; - nn_log (LC_DISCOVERY, "map group %x:%x:%x -> %x:%x:%x:%x refc %u (new)\n", PGID (*group_gid), PGUID (*group_guid), g->refc); + nn_log (LC_DISCOVERY, "map group "PGIDFMT" -> "PGUIDFMT" refc %u (new)\n", PGID (*group_gid), PGUID (*group_guid), g->refc); } os_mutexUnlock (&group_gid_guid_lock); } @@ -306,10 +307,10 @@ static void unmap_group_gid_to_guid (const nn_guid_t *group_guid) { assert (ut_avlLookup (&group_gid_guid_td, &group_gid_guid_tree, &g->gid) != NULL); if (--g->refc != 0) - nn_log (LC_DISCOVERY, "unmap group %x:%x:%x -> %x:%x:%x:%x refc %u (unref)\n", PGID (g->gid), PGUID (g->guid), g->refc); + nn_log (LC_DISCOVERY, "unmap group "PGIDFMT" -> "PGUIDFMT" refc %u (unref)\n", PGID (g->gid), PGUID (g->guid), g->refc); else { - nn_log (LC_DISCOVERY, "unmap group %x:%x:%x -> %x:%x:%x:%x refc %u (free)\n", PGID (g->gid), PGUID (g->guid), g->refc); + nn_log (LC_DISCOVERY, "unmap group "PGIDFMT" -> "PGUIDFMT" refc %u (free)\n", PGID (g->gid), PGUID (g->guid), g->refc); ut_avlDeleteDPath (&group_guid_gid_td, &group_guid_gid_tree, g, &dpath); ut_avlDelete (&group_gid_guid_td, &group_gid_guid_tree, g); os_free (g); @@ -328,11 +329,11 @@ static int new_writer_gid (const nn_guid_t *ppguid, const nn_guid_t *group_guid, if (ephash_lookup_writer_gid (gid_hash, gid)) { - TRACE (("new_writer(gid %x:%x:%x) - already known\n", PGID (*gid))); + nn_log (LC_DISCOVERY, "new_writer(gid "PGIDFMT") - already known\n", PGID (*gid)); return ERR_ENTITY_EXISTS; } - TRACE (("new_writer(gid %x:%x:%x)\n", PGID (*gid))); + nn_log (LC_DISCOVERY, "new_writer(gid "PGIDFMT")\n", PGID (*gid)); if ((topic = deftopic (ospl_topic)) == NULL) return ERR_UNSPECIFIED; @@ -350,10 +351,10 @@ int delete_writer_gid (const struct v_gid_s *gid) assert (v_gidIsValid (*gid)); if ((wr = ephash_lookup_writer_gid (gid_hash, gid)) == NULL) { - nn_log (LC_DISCOVERY, "delete_writer(gid %x:%x:%x) - unknown gid\n", PGID (*gid)); + nn_log (LC_DISCOVERY, "delete_writer(gid "PGIDFMT") - unknown gid\n", PGID (*gid)); return ERR_UNKNOWN_ENTITY; } - nn_log (LC_DISCOVERY, "delete_writer(gid %x:%x:%x) ...\n", PGID (*gid)); + nn_log (LC_DISCOVERY, "delete_writer(gid "PGIDFMT") ...\n", PGID (*gid)); ephash_remove_writer_gid (gid_hash, wr); unmap_group_gid_to_guid(&wr->c.group_guid); delete_writer (&wr->e.guid); @@ -371,11 +372,11 @@ static int new_reader_gid (const nn_guid_t *ppguid, const nn_guid_t *group_guid, if (ephash_lookup_reader_gid (gid_hash, gid)) { - TRACE (("new_reader(gid %x:%x:%x) - already known\n", PGID (*gid))); + nn_log (LC_DISCOVERY, "new_reader(gid "PGIDFMT") - already known\n", PGID (*gid)); return ERR_ENTITY_EXISTS; } - TRACE (("new_reader(gid %x:%x:%x)\n", PGID (*gid))); + nn_log (LC_DISCOVERY, "new_reader(gid "PGIDFMT")\n", PGID (*gid)); if ((topic = deftopic (ospl_topic)) == NULL) return ERR_UNSPECIFIED; @@ -392,10 +393,10 @@ int delete_reader_gid (const struct v_gid_s *gid) assert (v_gidIsValid (*gid)); if ((rd = ephash_lookup_reader_gid (gid_hash, gid)) == NULL) { - nn_log (LC_DISCOVERY, "delete_reader_gid(gid %x:%x:%x) - unknown gid\n", PGID (*gid)); + nn_log (LC_DISCOVERY, "delete_reader_gid(gid "PGIDFMT") - unknown gid\n", PGID (*gid)); return ERR_UNKNOWN_ENTITY; } - nn_log (LC_DISCOVERY, "delete_reader_gid(gid %x:%x:%x) ...\n", PGID (*gid)); + nn_log (LC_DISCOVERY, "delete_reader_gid(gid "PGIDFMT") ...\n", PGID (*gid)); ephash_remove_reader_gid (gid_hash, rd); unmap_group_gid_to_guid(&rd->c.group_guid); return delete_reader (&rd->e.guid); @@ -411,7 +412,7 @@ static void handle_bubble (C_STRUCT (v_message) const * msg) gid.systemId = data->systemId; gid.localId = data->localId; gid.serial = data->serial; - nn_log (LC_DISCOVERY, "handle_bubble: delete_writer(%x:%x:%x)\n", PGID (gid)); + nn_log (LC_DISCOVERY, "handle_bubble: delete_writer("PGIDFMT")\n", PGID (gid)); delete_writer_gid (&gid); break; default: @@ -424,14 +425,14 @@ void trace_v_message_eot (const struct v_messageEOT_s *eot) { const struct v_tid *tids = (const struct v_tid *) eot->tidList; unsigned i; - TRACE (("EOT = { state %u seq %u txnid %u wtime %"PA_PRItime" wrgid %x:%x:%x wrinstgid %x:%x:%x }", + TRACE (("EOT = { state %u seq %u txnid %u wtime %"PA_PRItime" wrgid "PGIDFMT" wrinstgid "PGIDFMT" }", eot->_parent._parent.nodeState, eot->_parent.sequenceNumber, eot->_parent.transactionId, OS_TIMEW_PRINT(eot->_parent.writeTime), PGID (eot->_parent.writerGID), PGID (eot->_parent.writerInstanceGID))); TRACE ((" pubid %u txnid %u %u:{", eot->publisherId, eot->transactionId, (unsigned)c_arraySize(eot->tidList))); for (i = 0; i < (unsigned)c_arraySize(eot->tidList); i++) - TRACE ((" %x:%x:%x,%u", PGID (tids[i].wgid), tids[i].seqnr)); + TRACE ((" "PGIDFMT",%u", PGID (tids[i].wgid), tids[i].seqnr)); TRACE (("}")); } @@ -440,13 +441,16 @@ int rtps_write (struct nn_xpack *xp, const struct v_gid_s *wrgid, C_STRUCT (v_me serdata_t serdata; struct writer *wr; + /* Note: may toggle thread states, so GC may occur and we must not cache a pointer past + the write/end_coherent_set calls */ + if ((wr = ephash_lookup_writer_gid (gid_hash, wrgid)) == NULL) { if (is_builtin_topic_writer (wrgid)) return 0; else { - TRACE (("rtps_write(gid %x:%x:%x) - unknown gid\n", PGID (*wrgid))); + nn_log (LC_DISCOVERY, "rtps_write(gid "PGIDFMT") - unknown gid\n", PGID (*wrgid)); return ERR_UNKNOWN_ENTITY; } } @@ -463,7 +467,7 @@ int rtps_write (struct nn_xpack *xp, const struct v_gid_s *wrgid, C_STRUCT (v_me nn_prismtech_eotinfo_t *txnid; nn_plist_t *ps; os_uint32 i; - TRACE (("rtps_write(gid %x:%x:%x) - seq %u txn id %u ends\n", PGID (*wrgid), msg->sequenceNumber, msg->transactionId)); + TRACE (("rtps_write(gid "PGIDFMT") - seq %u txn id %u ends\n", PGID (*wrgid), msg->sequenceNumber, msg->transactionId)); trace_v_message_eot (eot); TRACE (("\n")); ps = os_malloc (sizeof (*ps)); @@ -487,13 +491,13 @@ int rtps_write (struct nn_xpack *xp, const struct v_gid_s *wrgid, C_STRUCT (v_me } if (i < txnid->n) { - TRACE (("rtps_write(gid %x:%x:%x) - dropping transaction including unknown gid %x:%x:%x\n", PGID (*wrgid), PGID (tids[i].wgid))); + nn_log (LC_DISCOVERY, "rtps_write(gid "PGIDFMT") - dropping transaction including unknown gid "PGIDFMT"\n", PGID (*wrgid), PGID (tids[i].wgid)); nn_plist_fini (ps); os_free (ps); return ERR_UNKNOWN_ENTITY; } } - return end_coherent_set (xp, wr, ps, d, 1, msg->sequenceNumber); + return end_coherent_set_gc (xp, wr, ps, d, 1, msg->sequenceNumber); } else { @@ -503,14 +507,15 @@ int rtps_write (struct nn_xpack *xp, const struct v_gid_s *wrgid, C_STRUCT (v_me level */ if ((v_nodeState ((v_message) msg) & L_TRANSACTION) && msg->sequenceNumber == msg->transactionId) { - TRACE (("rtps_write(gid %x:%x:%x) - seq %u txn id %u begins\n", PGID (*wrgid), msg->sequenceNumber, msg->transactionId)); + TRACE (("rtps_write(gid "PGIDFMT") - seq %u txn id %u begins\n", PGID (*wrgid), msg->sequenceNumber, msg->transactionId)); begin_coherent_set (wr); } - switch (v_nodeState ((v_message) msg) & ~(L_SYNCHRONOUS | L_TRANSACTION | L_ENDOFTRANSACTION)) + switch (v_nodeState ((v_message) msg) & ~(L_SYNCHRONOUS | L_TRANSACTION | L_ENDOFTRANSACTION | L_AUTO)) { case L_WRITE: case L_WRITE | L_DISPOSED: + case L_WRITE | L_DISPOSED | L_UNREGISTER: if ((serdata = serialize (gv.serpool, wr->topic, msg)) == NULL) { NN_WARNING0 ("serialization (data) failed\n"); @@ -519,6 +524,7 @@ int rtps_write (struct nn_xpack *xp, const struct v_gid_s *wrgid, C_STRUCT (v_me break; case L_DISPOSED: case L_UNREGISTER: + case L_DISPOSED | L_UNREGISTER: if ((serdata = serialize_key (gv.serpool, wr->topic, msg)) == NULL) { NN_WARNING0 ("serialization (key) failed\n"); @@ -535,24 +541,35 @@ int rtps_write (struct nn_xpack *xp, const struct v_gid_s *wrgid, C_STRUCT (v_me if ((config.enabled_logcats & LC_TRACE) && (v_nodeState ((v_message) msg) & L_WRITE)) assert (serdata_verify (serdata, msg)); #endif - return write_sample_kernel_seq (xp, wr, serdata, 1, msg->sequenceNumber); + return write_sample_kernel_seq_gc (xp, wr, serdata, 1, msg->sequenceNumber); } } static void *channel_reader_thread_main (v_entity e, struct channel_reader_arg *arg) { struct thread_state1 *self = lookup_thread_state (); + nn_mtime_t next_thread_cputime = { 0 }; v_networkReader vnetworkReader = v_networkReader(e); v_networkQueue vnetworkQueue = NULL; struct nn_xpack *xp; os_uint32 bw_limit = 0; +#ifdef DDSI_INCLUDE_BANDWIDTH_LIMITING + bw_limit = arg->channel_cfg->data_bandwidth_limit; +#endif xp = nn_xpack_new (arg->transmit_conn, bw_limit); +#ifdef DDSI_INCLUDE_NETWORK_CHANNELS + nn_log (LC_CONFIG, "reader_thread: \"%s\" (priority %d) started \n", arg->channel_cfg->name, arg->channel_cfg->priority); +#endif while (!gv.terminate && !gv.exception) { +#ifdef DDSI_INCLUDE_NETWORK_CHANNELS + const c_ulong queueId = arg->channel_cfg->queueId; +#else const c_ulong queueId = gv.networkQueueId; +#endif v_networkReaderWaitResult nrwr; c_bool sendTo, more; v_message message; @@ -561,6 +578,8 @@ static void *channel_reader_thread_main (v_entity e, struct channel_reader_arg * os_timeE sendBefore; v_networkReaderEntry entry; + LOG_THREAD_CPUTIME (next_thread_cputime); + nrwr = v_networkReaderWait (vnetworkReader, queueId, &vnetworkQueue); if ((nrwr & V_WAITRESULT_MSGWAITING) == V_WAITRESULT_MSGWAITING) { @@ -587,11 +606,11 @@ static void *channel_reader_thread_main (v_entity e, struct channel_reader_arg * (void) handleDataWriters (arg->drset); if (rtps_write (xp, &sender, message) == ERR_UNKNOWN_ENTITY) - nn_log (LC_TRACE, "message dropped because sender %x:%x:%x is unknown\n", - sender.systemId, sender.localId, sender.serial); + nn_log (LC_DISCOVERY, "message dropped because sender "PGIDFMT" is unknown\n", PGID(sender)); os_mutexUnlock (&gluelock); } c_free (message); + c_free (entry); } } while (more); nn_xpack_send (xp); @@ -626,17 +645,6 @@ static void determine_kernel_service (u_participant participant) u_observableAction (u_observable(participant), determine_kernel_service_helper, NULL); } -static void service_fill_new_groups_helper (v_public object, UNUSED_ARG (void *varg)) -{ - v_service s = v_service(object); - v_serviceFillNewGroups(s); -} - -static void service_fill_new_groups (u_participant participant) -{ - u_observableAction (u_observable (participant), service_fill_new_groups_helper, NULL); -} - static void watch_spliced (v_serviceStateKind spliceDaemonState, UNUSED_ARG (void *usrData)) { switch (spliceDaemonState) @@ -652,8 +660,18 @@ static void watch_spliced (v_serviceStateKind spliceDaemonState, UNUSED_ARG (voi if (local_discovery_waitset) u_waitsetNotify (local_discovery_waitset, NULL); if (networkReader) { +#ifndef DDSI_INCLUDE_NETWORK_CHANNELS if (gv.networkQueueId) u_networkReaderTrigger (networkReader, gv.networkQueueId); +#else + struct config_channel_listelem *chptr = config.channels; + while (chptr != NULL) + { + if (chptr->queueId) + u_networkReaderTrigger (networkReader, chptr->queueId); + chptr = chptr->next; + } +#endif } os_mutexUnlock (&gluelock); } @@ -699,7 +717,10 @@ static u_waitset create_discovery_waitset (u_participant participant, struct bui goto err_dispatchSetEventMask; } - service_fill_new_groups (participant); + if (u_serviceFillNewGroups(u_service(participant)) != U_RESULT_OK) { + NN_ERROR0 ("could not fill service new group event list\n"); + goto err_waitsetAttach; + } if (u_waitsetAttach (waitset, (u_observable) participant, (u_object) participant) != U_RESULT_OK) { NN_ERROR0 ("could not attach participant to waitset\n"); @@ -872,8 +893,8 @@ static u_result handleGroup (v_networkReader vnetworkReader, v_group group) if (!config.coexistWithNativeNetworking && istransient) { suppress_fictitious_transient_reader = 1; - v_groupCompleteSet (group, TRUE); - TRACE (("new group '%s.%s': marked complete\n", partition, topic)); + (void)v_groupCompleteSet (group, V_ALIGNSTATE_COMPLETE); + nn_log (LC_DISCOVERY, "new group '%s.%s': marked complete\n", partition, topic); } } } @@ -894,6 +915,14 @@ static u_result handleGroup (v_networkReader vnetworkReader, v_group group) nn_log (LC_DISCOVERY, "Found new group '%s.%s'; node-local partition / built-in topic ignored\n", partition, topic); } else +#ifdef DDSI_INCLUDE_NETWORK_PARTITIONS + if (is_ignored_partition (partition, topic) && !is_bubble_group) + { + v_groupNotifyAwareness (group, config.servicename, FALSE); + nn_log (LC_DISCOVERY, "Found new group '%s.%s'; ignored, because it matches an ignoredPartition\n", partition, topic); + } + else +#endif { v_networkReaderEntry entry; v_networkRoutingMode routing = V_NETWORKROUTING_NONE; @@ -930,6 +959,7 @@ static u_result handleGroup (v_networkReader vnetworkReader, v_group group) } v_networkReaderEntryNotifyConnected (entry, config.servicename); v_networkReaderRemoteActivityDetected (vnetworkReader); + v_networkReaderEntryFree(entry); if (is_bubble_group) { TRACE (("bubble writer's group now discovered\n")); @@ -1012,7 +1042,7 @@ static u_result initial_local_discovery (const struct builtin_datareader_set *dr u_result res, res1; int i; - TRACE (("Mirror DDSI itself ...\n")); + nn_log (LC_DISCOVERY, "Mirror DDSI itself ...\n"); thread_state_awake (self); os_mutexLock (&gluelock); @@ -1029,7 +1059,7 @@ static u_result initial_local_discovery (const struct builtin_datareader_set *dr fictitious data readers for transient data and pretend they are owned by ourself. For that, we need to mirror ourself before we start looking at the groups.*/ - TRACE (("Initial local discovery ...\n")); + nn_log (LC_DISCOVERY, "Initial local discovery ...\n"); thread_state_awake (self); os_mutexLock (&gluelock); @@ -1144,7 +1174,7 @@ static u_result monitor_local_entities (const u_waitset waitset, const struct bu os_result osr; os_timePowerEvents powerEvents; - TRACE (("Mirroring DCPS entities in DDSI ...\n")); + nn_log (LC_DISCOVERY, "Mirroring DCPS entities in DDSI ...\n"); ctx.result = U_RESULT_OK; ctx.drset = drset; @@ -1250,8 +1280,9 @@ static int string_eq (const void *va, const void *vb) static void reset_deaf_mute (struct xevent *xev, UNUSED_ARG (void *varg), UNUSED_ARG (nn_mtime_t tnow)) { - gv.deaf_mute = config.initial_deaf_mute; - TRACE (("DEAFMUTE auto-reset to %d\n", gv.deaf_mute)); + gv.deaf = 0; + gv.mute = 0; + TRACE (("DEAFMUTE auto-reset to [deaf, mute]=[%d, %d]\n", gv.deaf, gv.mute)); delete_xevent (xev); } @@ -1273,8 +1304,9 @@ static u_result handleDDSIControl (const struct builtin_datareader_set *drset) (c->serial == 0 || c->serial == ddsi2_participant_gid.serial))))) { if (vmsg->_parent.nodeState & L_WRITE) { - gv.deaf_mute = c->deaf_mute; - TRACE ((" DEAFMUTE set %d", gv.deaf_mute)); + gv.deaf = c->deaf; + gv.mute = c->mute; + TRACE ((" DEAFMUTE set [deaf, mute]=[%d, %d]", gv.deaf, gv.mute)); if (c->duration > 0) { os_int64 d = (os_int64) (1e9 * c->duration); @@ -1286,7 +1318,7 @@ static u_result handleDDSIControl (const struct builtin_datareader_set *drset) } else { - TRACE ((" (%x:%x:%x ignore)", c->systemId, c->localId, c->serial)); + TRACE ((" ("PGIDFMT" ignore)", PGID(*c))); } c_free (sample); } @@ -1303,11 +1335,11 @@ static u_result handleSelectEntities (const struct builtin_datareader_set *drset if (n < 0) NN_WARNING2 ("handleSelectEndpoints: %s lookup failed (%d)\n", what, n); else if (n == 0) - TRACE (("handleSelectEndpoints: no %ss\n", what)); + nn_log (LC_DISCOVERY, "handleSelectEndpoints: no %ss\n", what); else { int i; - TRACE (("handleSelectEndpoints: instantiating %ss\n", what)); + nn_log (LC_DISCOVERY, "handleSelectEndpoints: instantiating %ss\n", what); for (i = 0; i < n; i++) handle (drset, setidx, res[i], MTR_SST_NEW); os_free ((void *) res); @@ -1317,7 +1349,7 @@ static u_result handleSelectEntities (const struct builtin_datareader_set *drset static u_result handleParticipantSubEntities (const struct builtin_datareader_set *drset, int setidx, const v_gid *ppgid) { - TRACE (("participant %x:%x:%x: instantiating sub-entities\n", PGID (*ppgid))); + nn_log (LC_DISCOVERY, "participant "PGIDFMT": instantiating sub-entities\n", PGID (*ppgid)); (void) handleSelectEntities (drset, setidx, "reader", drset->e[setidx].datareader_mtr, drset->subscription_tp, "participant_key", gid_eq, ppgid, handleDataReader); (void) handleSelectEntities (drset, setidx, "writer", drset->e[setidx].datawriter_mtr, drset->publication_tp, "participant_key", gid_eq, ppgid, handleDataWriter); (void) handleSelectEntities (drset, setidx, "subscriber", drset->e[setidx].subscriber_mtr, drset->cm_subscriber_tp, "participant_key", gid_eq, ppgid, handleSubscriber); @@ -1332,12 +1364,12 @@ static u_result handleTopicReadersWriters (const struct builtin_datareader_set * c_free (topic); if (topic == NULL) { - TRACE (("topic %s: topic not yet known in kernel\n", tpname)); + nn_log (LC_DISCOVERY, "topic %s: topic not yet known in kernel\n", tpname); return U_RESULT_PRECONDITION_NOT_MET; } else { - TRACE (("topic %s: instantiating readers/writers\n", tpname)); + nn_log (LC_DISCOVERY, "topic %s: instantiating readers/writers\n", tpname); (void) handleSelectEntities (drset, setidx, "reader", drset->e[setidx].datareader_mtr, drset->subscription_tp, "topic_name", string_eq, tpname, handleDataReader); (void) handleSelectEntities (drset, setidx, "writer", drset->e[setidx].datawriter_mtr, drset->publication_tp, "topic_name", string_eq, tpname, handleDataWriter); return U_RESULT_OK; @@ -1370,22 +1402,22 @@ static int is_proxypp_or_deleted_pp (const char *label, const struct v_gid_s *pk if (ephash_lookup_proxy_participant_guid (&ppguid) || is_non_opensplice_bridged_proxy_participant (pkey)) { if (v_gidEqual (*pkey, *ekey)) - TRACE (("handle%s: ignoring mt sample for proxypp %x:%x:%x\n", label, PGID (*pkey))); + nn_log (LC_DISCOVERY, "handle%s: ignoring mt sample for proxypp "PGIDFMT"\n", label, PGID (*pkey)); else - TRACE (("handle%s: ignoring mt sample for %x:%x:%x owned by proxypp %x:%x:%x\n", label, PGID (*ekey), PGID (*pkey))); + nn_log (LC_DISCOVERY, "handle%s: ignoring mt sample for "PGIDFMT" owned by proxypp "PGIDFMT"\n", label, PGID (*ekey), PGID (*pkey)); return 1; } else if (samp_state != MTR_SST_DEL && is_deleted_participant_guid (&ppguid, DPG_LOCAL)) { if (v_gidEqual (*pkey, *ekey)) - TRACE (("handle%s: ignoring mt sample for recently deleted participant %x:%x:%x\n", label, PGID (*pkey))); + nn_log (LC_DISCOVERY, "handle%s: ignoring mt sample for recently deleted participant "PGIDFMT"\n", label, PGID (*pkey)); else - TRACE (("handle%s: ignoring mt sample for %x:%x:%x owned by deleted participant %x:%x:%x\n", label, PGID (*ekey), PGID (*pkey))); + nn_log (LC_DISCOVERY, "handle%s: ignoring mt sample for "PGIDFMT" owned by deleted participant "PGIDFMT"\n", label, PGID (*ekey), PGID (*pkey)); return 1; } else { - TRACE (("handle%s: received mt sample for %x:%x:%x (%s)\n", label, PGID (*ekey), mtr_sample_state_str (samp_state))); + nn_log (LC_DISCOVERY, "handle%s: received mt sample for "PGIDFMT" (%s)\n", label, PGID (*ekey), mtr_sample_state_str (samp_state)); return 0; } } @@ -1412,7 +1444,7 @@ static u_result handleParticipant (const struct builtin_datareader_set *drset, i nn_plist_t ps; update_mtreader_setflag (drset->e[setidx].participant_mtr, &pdata->key, 1); if (init_participant_plist (pdata, cmpdata, &ps) < 0) - NN_WARNING3 ("participant info initialisation error for %x:%x:%x\n", pdata->key.systemId, pdata->key.localId, pdata->key.serial); + NN_WARNING1 ("participant info initialisation error for "PGIDFMT"\n", PGID(pdata->key)); else { unsigned flags = 0; @@ -1424,7 +1456,7 @@ static u_result handleParticipant (const struct builtin_datareader_set *drset, i discovery for the benefit of Cloud-over-Bridge. Also give those participants the full complement of readers/writers, regardless of config.besmode, as Cloud otherwise still wouldn't know where to send the data. */ - TRACE (("handleParticipants: %x:%x:%x is a ddsi2 participant\n", PGID (pdata->key))); + nn_log (LC_DISCOVERY, "handleParticipants: "PGIDFMT" is a ddsi2 participant\n", PGID (pdata->key)); flags = RTPS_PF_IS_DDSI2_PP; } else @@ -1443,7 +1475,7 @@ static u_result handleParticipant (const struct builtin_datareader_set *drset, i } } if (new_participant_gid (&pdata->key, &ps, flags) < 0) - NN_WARNING3 ("participant %x:%x:%x: failed to create\n", pdata->key.systemId, pdata->key.localId, pdata->key.serial); + NN_WARNING1 ("participant "PGIDFMT": failed to create\n", PGID(pdata->key)); else handleParticipantSubEntities (drset, setidx, &pdata->key); nn_plist_fini (&ps); @@ -1517,12 +1549,12 @@ static void handleParticipantsSelfAction (v_public vpub, void *varg) struct v_participantInfo const * const pdata = (struct v_participantInfo *) (p_msg + 1); struct v_participantCMInfo const * const cmpdata = (struct v_participantCMInfo *) (cm_msg + 1); - TRACE (("handleParticipantsSelf: found %x:%x:%x (self)\n", PGID (pdata->key))); + nn_log (LC_DISCOVERY, "handleParticipantsSelf: found "PGIDFMT" (self)\n", PGID (pdata->key)); assert (v_gidEqual (ddsi2_participant_gid, pdata->key)); assert (v_gidEqual (ddsi2_participant_gid, cmpdata->key)); if (init_participant_plist (pdata, cmpdata, &arg->ps) < 0) - NN_WARNING1 ("participant info initialisation error for %x:%x:%x\n", PGID (pdata->key)); + NN_WARNING1 ("participant info initialisation error for "PGIDFMT"\n", PGID (pdata->key)); else arg->result = U_RESULT_OK; } @@ -1545,7 +1577,7 @@ static u_result handleParticipantsSelf (const struct builtin_datareader_set *drs } else { if (new_participant_gid (&ddsi2_participant_gid, &arg.ps, RTPS_PF_PRIVILEGED_PP | RTPS_PF_IS_DDSI2_PP) < 0) { - NN_FATAL1 ("participant %x:%x:%x (self): failed to create\n", PGID (ddsi2_participant_gid)); + NN_FATAL1 ("participant "PGIDFMT" (self): failed to create\n", PGID (ddsi2_participant_gid)); result = U_RESULT_INTERNAL_ERROR; } nn_plist_fini (&arg.ps); @@ -1553,6 +1585,23 @@ static u_result handleParticipantsSelf (const struct builtin_datareader_set *drs return result; } +#ifdef DDSI_INCLUDE_NETWORK_PARTITIONS +static int all_partitions_ignored (struct v_builtinPartitionPolicy partition, const char *topic) +{ + int result = 1; + c_ulong i; + for (i = 0; result && i < c_arraySize (partition.name); i++) + { + /* a partition is considered ignored if it contains no wildcards + and does not match the ignored partition patterns */ + result = result && + !strchr (partition.name[i], '*') && + !strchr (partition.name[i], '?') && + is_ignored_partition (partition.name[i], topic); + } + return result; +} +#endif /* DDSI_INCLUDE_NETWORK_PARTITIONS */ static int ignore_builtin_readerwriter (const char *partition, const char *topic_name, enum ignore_builtin whatfor) { @@ -1592,10 +1641,17 @@ static u_result handleDataReaderWriter_check (const v_gid *ppgid, const v_gid *g nn_log (LC_DISCOVERY, "handleDataReaderWriter_check: %s: node-local partition / built-in topic ignored\n", topic_name); return U_RESULT_PRECONDITION_NOT_MET; } +#ifdef DDSI_INCLUDE_NETWORK_PARTITIONS + if (all_partitions_ignored (partition, topic_name)) + { + nn_log (LC_DISCOVERY, "handleDataReaderWriter_check: %s: ignored for all partitions, due to ignoredPartitions\n", topic_name); + return U_RESULT_PRECONDITION_NOT_MET; + } +#endif /* DDSI_INCLUDE_NETWORK_PARTITIONS */ if ((*topic = v_lookupTopic (gv.ospl_kernel, topic_name)) == NULL) { - nn_log (LC_DISCOVERY, "handleDataReaderWriter_check: %x:%x:%x topic %s unknown\n", PGID (*key), topic_name); + nn_log (LC_DISCOVERY, "handleDataReaderWriter_check: "PGIDFMT" topic %s unknown\n", PGID (*key), topic_name); return U_RESULT_PRECONDITION_NOT_MET; } @@ -1606,7 +1662,7 @@ static u_result handleDataReaderWriter_check (const v_gid *ppgid, const v_gid *g if ((pp = ephash_lookup_participant_guid (ppguid)) == NULL) { - nn_log (LC_DISCOVERY, "handleDataReaderWriter_check: %x:%x:%x participant %x:%x:%x unknown\n", PGID (*key), PGID (*ppgid)); + nn_log (LC_DISCOVERY, "handleDataReaderWriter_check: "PGIDFMT" participant "PGIDFMT" unknown\n", PGID (*key), PGID (*ppgid)); return U_RESULT_PRECONDITION_NOT_MET; } @@ -1687,19 +1743,19 @@ static void schedule_delete_writer (const v_gid *key) u_result res; if (!bubble_writer_group_attached) { - TRACE (("schedule_delete_writer(%x:%x:%x) deleting immediately: bubble writer's group not yet attached\n", PGID (*key))); + nn_log (LC_DISCOVERY, "schedule_delete_writer("PGIDFMT") deleting immediately: bubble writer's group not yet attached\n", PGID (*key)); delete_writer_gid (key); } else { - TRACE (("schedule_delete_writer(%x:%x:%x) writing bubble\n", PGID (*key))); + nn_log (LC_DISCOVERY, "schedule_delete_writer("PGIDFMT") writing bubble\n", PGID (*key)); data.kind = BTK_DELETE_WRITER; data.systemId = key->systemId; data.localId = key->localId; data.serial = key->serial; if ((res = u_writerWrite (bubble_writer, bubble_writer_copy, &data, os_timeWGet(), U_INSTANCEHANDLE_NIL)) != U_RESULT_OK) { - NN_WARNING2 ("schedule_delete_writer(%x:%x:%x) failed with result %d, deleting immediately instead\n", PGID (*key), (int) res); + NN_WARNING2 ("schedule_delete_writer("PGIDFMT") failed with result %d, deleting immediately instead\n", PGID (*key), (int) res); delete_writer_gid (key); } } @@ -1792,7 +1848,7 @@ static void handleTopicReadersWriters_cb (struct xevent *xev, void *varg, nn_mti if (ures != U_RESULT_PRECONDITION_NOT_MET) { if (ures != U_RESULT_OK) - TRACE (("handleTopicReadersWriters_cb: giving up on topic %s ...\n", arg->name)); + nn_log (LC_DISCOVERY, "handleTopicReadersWriters_cb: giving up on topic %s ...\n", arg->name); delete_xevent (xev); os_free (arg->name); os_free (arg); @@ -1814,10 +1870,10 @@ static u_result handleTopics (const struct builtin_datareader_set *drset) /* See also ddsi_discovery.c: we are only forwarding topic definitions, not interpreting them (perhaps we will change this at some point). */ if (!is_topic_discoverable(data->name)) - TRACE (("TOPIC %s/%s: skipping built-in\n", data->name, data->type_name)); + nn_log (LC_DISCOVERY, "TOPIC %s/%s: skipping built-in\n", data->name, data->type_name); else { - TRACE (("TOPIC %s/%s\n", data->name, data->type_name)); + nn_log (LC_DISCOVERY, "TOPIC %s/%s\n", data->name, data->type_name); if (init_topic_plist (data, &ps) >= 0) { struct participant *pp; @@ -1881,7 +1937,7 @@ static u_result handlePublisherSubscriber (const struct builtin_datareader_set * if (ignore_builtin_readerwriter_partpol(*partition, NULL, IGNB_ANY)) { - TRACE (("handle%s %x:%x:%x: node-local partition ignored\n", which, PGID (*key))); + nn_log (LC_DISCOVERY, "handle%s "PGIDFMT": node-local partition ignored\n", which, PGID (*key)); return U_RESULT_OK; } @@ -1890,11 +1946,11 @@ static u_result handlePublisherSubscriber (const struct builtin_datareader_set * case MTR_SST_DEL: { nn_guid_t group_guid; - if (lookup_group_guid (&group_guid, key)) + if (lookup_group_guid (&group_guid, key)) { write_sedp (data, &group_guid, 0); - else + unmap_group_gid_to_guid (&group_guid); + } else TRACE ((" unknown\n")); - unmap_group_gid_to_guid (&group_guid); } break; case MTR_SST_UPD: @@ -2025,15 +2081,6 @@ static void new_fictitious_transient_reader (v_group group) nn_xqos_fini (&xqos); } -/* NOTE: Blatantly stolen from the "native" networking implementation - (src/services/networking/code/nw_controller.c). Methinks these - should be guaranteed unique, not hopefully unique. Surely one could - just a "service instance id" or somesuch for this purpose ... - - NOTE 2: And fixed after stealing ... Native networking uses (0 <= - id < (1e9-1)), we use one in (1e-9 <= id' < (2e9-1)). So there - never should (1) be an id collision and (2) an accidental use of - LOCAL by DDSI2. */ static v_networkId getNetworkId (void) { os_timeM time; @@ -2181,7 +2228,9 @@ static u_result create_builtin_readers (struct builtin_datareader_set *drset, u_ if ((sQos->partition.v = os_strdup (parts[i])) == NULL) goto fail; snprintf (name, sizeof (name), "DDSI2BuiltinSubscriber%d", (int) i); - if ((drset->e[i].subscriber = u_subscriberNew (p, name, sQos, TRUE)) == NULL) + if ((drset->e[i].subscriber = u_subscriberNew (p, name, sQos)) == NULL) + goto fail; + if(u_entityEnable(u_entity(drset->e[i].subscriber)) != U_RESULT_OK) goto fail; u_subscriberQosFree (sQos); sQos = NULL; @@ -2258,7 +2307,9 @@ static u_result create_builtin_readers (struct builtin_datareader_set *drset, u_ assert (n < (int) sizeof (expr)); (void) n; - if ((*pdr = u_subscriberCreateDataReader (drset->e[i].subscriber, rdname, expr, ps, rdQos, TRUE)) == NULL) + if ((*pdr = u_subscriberCreateDataReader (drset->e[i].subscriber, rdname, expr, ps, 1, rdQos)) == NULL) + goto fail; + if(u_entityEnable(u_entity(*pdr)) != U_RESULT_OK) goto fail; } } @@ -2331,7 +2382,7 @@ static u_result create_bubble_topic_writer (u_participant p) goto err_writer; u_entityEnable(u_entity(bubble_writer)); bubble_writer_gid = u_observableGid (u_observable(bubble_writer)); - nn_log (LC_DISCOVERY, "bubble writer: gid %x:%x:%x\n", bubble_writer_gid.systemId, bubble_writer_gid.localId, bubble_writer_gid.serial); + nn_log (LC_DISCOVERY, "bubble writer: gid "PGIDFMT"\n", PGID(bubble_writer_gid)); u_writerQosFree (wrqos); u_publisherQosFree (pqos); @@ -2387,7 +2438,11 @@ static struct thread_state1 * create_channel_reader_thread ( const char * name, struct builtin_datareader_set * drset, +#ifdef DDSI_INCLUDE_NETWORK_CHANNELS + struct config_channel_listelem *chptr +#else ddsi_tran_conn_t transmit_conn +#endif ) { /* create one (or more, eventually) threads to read from the network @@ -2397,7 +2452,12 @@ static struct thread_state1 * create_channel_reader_thread struct thread_state1 *ts; sprintf (thread_name, "xmit.%s", name); arg->drset = drset; +#ifdef DDSI_INCLUDE_NETWORK_CHANNELS + arg->channel_cfg = chptr; + arg->transmit_conn = chptr->transmit_conn; +#else arg->transmit_conn = transmit_conn; +#endif if ((ts = create_thread ( thread_name, (void * (*) (void *)) channel_reader_thread, @@ -2416,6 +2476,7 @@ static void lease_renew_cb (void *vparticipant) static os_result exit_request_handler( UNUSED_ARG(os_callbackArg ignore), + UNUSED_ARG(void *callingThreadContext), UNUSED_ARG(void * arg)) { gv.terminate = TRUE; @@ -2423,15 +2484,25 @@ exit_request_handler( if (local_discovery_waitset) u_waitsetNotify (local_discovery_waitset, NULL); if (networkReader) { +#ifndef DDSI_INCLUDE_NETWORK_CHANNELS if (gv.networkQueueId) u_networkReaderTrigger (networkReader, gv.networkQueueId); +#else + struct config_channel_listelem *chptr = config.channels; + while (chptr != NULL) + { + if (chptr->queueId) + u_networkReaderTrigger (networkReader, chptr->queueId); + chptr = chptr->next; + } +#endif } os_mutexUnlock (&gluelock); return os_resultSuccess; /* the main thread will take care of termination */ } static os_result exception_request_handler ( - UNUSED_ARG(os_callbackArg exceptionCallbackArg), UNUSED_ARG(void * arg)) + UNUSED_ARG(void * callingThreadContext), UNUSED_ARG(void * arg)) { c_bool ret = TRUE; gv.exception = TRUE; @@ -2470,7 +2541,7 @@ static int debmon_plugin_mtr (ddsi_tran_conn_t conn, debug_monitor_cpf_t cpf, vo ppguid_from_ppgid(&ppguid, &s->gid); ispp = (ephash_lookup_participant_guid (&ppguid) != NULL); isproxypp = (ephash_lookup_proxy_participant_guid (&ppguid) != NULL); - x += cpf (conn, " %x:%x:%x (%s) %d%d ", PGID (s->gid), mtr_sample_state_str (s->state), ispp, isproxypp); + x += cpf (conn, " "PGIDFMT" (%s) %d%d ", PGID (s->gid), mtr_sample_state_str (s->state), ispp, isproxypp); switch (s->state) { case MTR_SST_DEL: @@ -2490,7 +2561,7 @@ static int debmon_plugin_mtr (ddsi_tran_conn_t conn, debug_monitor_cpf_t cpf, vo return x; } -OPENSPLICE_SERVICE_ENTRYPOINT (ospl_ddsi2, ddsi2) +OPENSPLICE_SERVICE_ENTRYPOINT (ospl_ddsi2e, ddsi2e) { /* Exit status: 0: ok, 1: configuration error, 2: abnormal termination. Default to abnormal termination, then override if @@ -2507,11 +2578,12 @@ OPENSPLICE_SERVICE_ENTRYPOINT (ospl_ddsi2, ddsi2) /* Default service name and service URI, taken from command line if given; config stores the service name in case it is needed at some later stage. */ - const char *service_name = "ddsi2"; + const char *service_name = "ddsi2e"; const char *service_uri = NULL; struct builtin_datareader_set drset; struct debug_monitor *debmon = NULL; u_waitset disc_ws; + nn_mtime_t reset_deaf_mute_time = { T_NEVER }; /* Init static log buffer early as possible -- but we don't even have a lock yet. This is ok if we are certain the log functions @@ -2520,7 +2592,8 @@ OPENSPLICE_SERVICE_ENTRYPOINT (ospl_ddsi2, ddsi2) gv.static_logbuf_lock_inited = 0; gv.exception = FALSE; gv.terminate = FALSE; - gv.deaf_mute = FALSE; + gv.deaf = FALSE; + gv.mute = FALSE; logbuf_init (&gv.static_logbuf); if (argc > 1) @@ -2564,7 +2637,11 @@ OPENSPLICE_SERVICE_ENTRYPOINT (ospl_ddsi2, ddsi2) start monitoring the splicedaemon state, so we can terminate if he says so. */ { +#if DDSI2E_OR_NOT2E + v_serviceType serviceType = V_SERVICETYPE_DDSI2E; +#else v_serviceType serviceType = V_SERVICETYPE_DDSI2; +#endif u_participantQos participantQos; if ((participantQos = u_participantQosNew (NULL)) == NULL) { NN_ERROR0 ("allocation of participantQos failed\n"); @@ -2604,14 +2681,14 @@ OPENSPLICE_SERVICE_ENTRYPOINT (ospl_ddsi2, ddsi2) and exit with status 1 to indicate a configuration error. */ { struct cfgst *cfgst; - if ((cfgst = config_init (participant, service_name)) == NULL) { - /* This field is used in NN_ERRORx, but is freed on failed config_init, so + if ((cfgst = q_config_init (participant, service_name)) == NULL) { + /* This field is used in NN_ERRORx, but is freed on failed q_config_init, so * it is temporarily initialised for errors in configuration initialisation * error reporting. */ config.servicename = (char*) service_name; NN_ERROR0 ("Could not initialise configuration\n"); exitstatus = 1; - goto err_config_init; + goto err_q_config_init; } if (config.lease_duration == 0) @@ -2634,8 +2711,14 @@ OPENSPLICE_SERVICE_ENTRYPOINT (ospl_ddsi2, ddsi2) } /* Allow configuration to set "deaf_mute" in case we want to start out that way */ - if (config.enable_control_topic) - gv.deaf_mute = config.initial_deaf_mute; + if (config.enable_control_topic) { + gv.deaf = config.initial_deaf; + gv.mute = config.initial_mute; + if (gv.deaf || gv.mute) { + TRACE (("DEAFMUTE initial deaf=%d mute=%d reset after %"PA_PRId64" ns\n", gv.deaf, gv.mute, config.initial_deaf_mute_reset)); + reset_deaf_mute_time = add_duration_to_mtime (now_mt (), config.initial_deaf_mute_reset); + } + } /* Initialize the power events. Any power event that happenend before the * initialization will not be recognized. Preferable we want to intialize @@ -2664,6 +2747,12 @@ OPENSPLICE_SERVICE_ENTRYPOINT (ospl_ddsi2, ddsi2) if (rtps_init () < 0) goto err_rtps_init; + if (reset_deaf_mute_time.v < T_NEVER) + { + qxev_callback(reset_deaf_mute_time, reset_deaf_mute, 0); + } + + /* Prepare hash table for mapping GUIDs to entities */ if ((gid_hash = ephash_new (config.gid_hash_softlimit)) == NULL) goto err_gid_hash; @@ -2680,23 +2769,46 @@ OPENSPLICE_SERVICE_ENTRYPOINT (ospl_ddsi2, ddsi2) os_free (subscriberQos->partition.v); subscriberQos->partition.v = NULL; - if ((networkSubscriber = u_subscriberNew (participant, "networkSubscriber", subscriberQos, TRUE)) == NULL) { + if ((networkSubscriber = u_subscriberNew (participant, "networkSubscriber", subscriberQos)) == NULL) { NN_ERROR0 ("creation of message subscriber failed\n"); u_subscriberQosFree (subscriberQos); goto err_client_subscriber; } u_subscriberQosFree (subscriberQos); + if (u_entityEnable (u_entity(networkSubscriber)) != U_RESULT_OK) { + NN_ERROR0 ("enabling of message subscriber failed\n"); + goto err_client_subscriber_enable; + } + if ((networkReader = u_networkReaderNew (networkSubscriber, "networkReader", NULL, TRUE)) == NULL) { NN_ERROR0 ("creation of network reader failed\n"); goto err_networkReaderNew; } +#ifdef DDSI_INCLUDE_NETWORK_CHANNELS + { + struct config_channel_listelem *chptr = config.channels; + while (chptr) { + /* Kernel expects an unsigned, we do a signed following the DDS spec. */ + assert (chptr->queue_size > 0); + assert (chptr->priority >= 0); + assert (chptr->resolution >= T_MILLISECOND && chptr->resolution <= T_SECOND); + resolution = (os_duration) chptr->resolution; + if (u_networkReaderCreateQueue (networkReader, chptr->queue_size, (os_uint32) chptr->priority, FALSE, FALSE, resolution, FALSE, &chptr->queueId, "DDSI2E") != U_RESULT_OK) { + NN_ERROR0 ("creation of network reader queue failed\n"); + goto err_networkReaderCreateQueue; + } + chptr = chptr->next; + } + } +#else resolution = OS_DURATION_SECOND; if (u_networkReaderCreateQueue (networkReader, config.nw_queue_size, 0, FALSE, FALSE, resolution, FALSE, &gv.networkQueueId, "DDSI2") != U_RESULT_OK) { NN_ERROR0 ("creation of network reader queue failed\n"); goto err_networkReaderCreateQueue; } +#endif /* DDSI_INCLUDE_NETWORK_CHANNELS */ } /* create GID <-> GUID mapping for implicit group discovery */ @@ -2759,12 +2871,27 @@ OPENSPLICE_SERVICE_ENTRYPOINT (ospl_ddsi2, ddsi2) os_mutexUnlock (&gluelock); TRACE (("attached to bubble writer's group, continuing\n")); +#ifdef DDSI_INCLUDE_NETWORK_CHANNELS + { + struct config_channel_listelem *chptr = config.channels; + int num_channels = 0; + while (chptr != NULL) + { + num_channels++; + if ((chptr->channel_reader_ts = create_channel_reader_thread (chptr->name, &drset, chptr)) == NULL) + goto err_channel_reader_thread; + chptr = chptr->next; + } + nn_log (LC_INFO, "%d channels configured\n", num_channels); + } +#else TRACE (("transmit port %d\n", (int) ddsi_tran_port (gv.data_conn_uc))); if ((gv.channel_reader_ts = create_channel_reader_thread ("user", &drset, gv.data_conn_uc)) == NULL) { goto err_channel_reader_thread; } +#endif /* DDSI_INCLUDE_NETWORK_CHANNELS */ if (config.monitor_port >= 0) { @@ -2781,8 +2908,8 @@ OPENSPLICE_SERVICE_ENTRYPOINT (ospl_ddsi2, ddsi2) u_serviceChangeState (u_service (participant), STATE_OPERATIONAL); if (!os_serviceGetSingleProcess()){ - erh = os_signalHandlerRegisterExitRequestCallback(exit_request_handler, NULL); - eh = os_signalHandlerRegisterExceptionCallback(exception_request_handler, NULL); + erh = os_signalHandlerRegisterExitRequestCallback(exit_request_handler, NULL, NULL, NULL, NULL); + eh = os_signalHandlerRegisterExceptionCallback(exception_request_handler, NULL, NULL, NULL, NULL); } uresult = monitor_local_entities (local_discovery_waitset, &drset); @@ -2797,7 +2924,7 @@ OPENSPLICE_SERVICE_ENTRYPOINT (ospl_ddsi2, ddsi2) os_sem_wait(&wait_for_ever); } else { os_duration t = OS_DURATION_INIT(100, 0); - os_sleep(t); + ospl_os_sleep(t); } } @@ -2822,9 +2949,22 @@ OPENSPLICE_SERVICE_ENTRYPOINT (ospl_ddsi2, ddsi2) free_debug_monitor (debmon); err_channel_reader_thread: u_waitsetNotify (local_discovery_waitset, NULL); +#ifdef DDSI_INCLUDE_NETWORK_CHANNELS + { + struct config_channel_listelem *chptr = config.channels; + while (chptr != NULL) + { + u_networkReaderTrigger (networkReader, chptr->queueId); + if (chptr->channel_reader_ts) + join_thread (chptr->channel_reader_ts, NULL); + chptr = chptr->next; + } + } +#else u_networkReaderTrigger (networkReader, gv.networkQueueId); if (gv.channel_reader_ts) join_thread (gv.channel_reader_ts, NULL); +#endif os_mutexLock (&gluelock); local_discovery_waitset = NULL; os_mutexUnlock (&gluelock); @@ -2850,6 +2990,8 @@ OPENSPLICE_SERVICE_ENTRYPOINT (ospl_ddsi2, ddsi2) networkReader = NULL; os_mutexUnlock (&gluelock); err_networkReaderNew: + /* No undo for enable needed */ +err_client_subscriber_enable: u_objectFree (u_object (networkSubscriber)); err_client_subscriber: ephash_free (gid_hash); @@ -2864,8 +3006,8 @@ OPENSPLICE_SERVICE_ENTRYPOINT (ospl_ddsi2, ddsi2) downgrade_main_thread (); thread_states_fini (); err_config_late_error: - /* would expect config_fini() here, but no, it is postponed. */ - err_config_init: + /* would expect q_config_fini() here, but no, it is postponed. */ +err_q_config_init: c_free (gv.ospl_eotgroup_tidlist_type); c_free (gv.ospl_qostype); /* Service mgmt framework doesn't allow INITIALISING -> TERMINATED */ @@ -2885,11 +3027,9 @@ OPENSPLICE_SERVICE_ENTRYPOINT (ospl_ddsi2, ddsi2) should be before os_osExit (which appears to be called from u_userExit(), which is not called by u_userDetach but by an exit handler, it appears.) */ - config_fini (); + q_config_fini (); os_mutexDestroy (&gv.static_logbuf_lock); err_static_logbuf_lock: err_userInitialise: return exitstatus; } - -/* SHA1 not available (unoffical build.) */ diff --git a/src/services/ddsi2/code/q_mtreader.c b/src/services/ddsi2e/code/q_mtreader.c similarity index 94% rename from src/services/ddsi2/code/q_mtreader.c rename to src/services/ddsi2e/code/q_mtreader.c index 3256a1eb3..a3343f991 100644 --- a/src/services/ddsi2/code/q_mtreader.c +++ b/src/services/ddsi2e/code/q_mtreader.c @@ -1,18 +1,16 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * @@ -231,7 +229,7 @@ static void expire_one_mtr_sample (struct mtreader *mtr) assert (s != NULL); if ((s1 = ut_avlLookupDPath (&mtr_samples_td, &mtr->samples, &s->gid, &dp)) != NULL && s == s1) { - TRACE (("expire_one_mtr_sample: deleting %x:%x:%x\n", s->gid.systemId, s->gid.localId, s->gid.serial)); + TRACE (("expire_one_mtr_sample: deleting "PGIDFMT"\n", PGID(s->gid))); ut_avlDeleteDPath (&mtr_samples_td, &mtr->samples, s1, &dp); } free_mtr_sample (mtr, s); @@ -439,7 +437,7 @@ int update_mtreader (struct mtreader *mtr, const struct mtr_sample *out[2], cons if (config.enabled_logcats & LC_TRACE) { char *tpname = u_topicName (mtr->topics[idx]); - TRACE (("update_mtreader: %s gid %x:%x:%x sample state %x vmsg state %x\n", tpname, gid.systemId, gid.localId, gid.serial, (unsigned) sample_state, (unsigned) vmsg->_parent.nodeState)); + TRACE (("update_mtreader: %s gid "PGIDFMT" sample state %x vmsg state %x\n", tpname, PGID(gid), (unsigned) sample_state, (unsigned) vmsg->_parent.nodeState)); os_free (tpname); } @@ -564,5 +562,3 @@ const struct mtr_sample *mtr_next (struct mtr_iter *it) return ut_avlIterNext (&it->it); } - -/* SHA1 not available (unoffical build.) */ diff --git a/src/services/ddsi2e/code/q_mtreader.h b/src/services/ddsi2e/code/q_mtreader.h new file mode 100644 index 000000000..e00bd6561 --- /dev/null +++ b/src/services/ddsi2e/code/q_mtreader.h @@ -0,0 +1,69 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#ifndef Q_MTREADER_H +#define Q_MTREADER_H + +#include "ut_avl.h" +#include "ut_fibheap.h" + +struct mtreader; +struct u_topic_s; + +enum mtr_sample_state { + MTR_SST_NEW, + MTR_SST_UPD, + MTR_SST_DEL +}; + +struct mtr_iter { + ut_avlIter_t it; +}; + +struct mtr_sample { + ut_avlNode_t avlnode; + ut_fibheapNode_t fhnode; + v_gid gid; + unsigned ntopics; + enum mtr_sample_state state; + nn_mtime_t texpire; + unsigned flag; +#if __STDC_VERSION__ >= 199901L + struct v_message_s *vmsg[/* ntopics */]; +#else + struct v_message_s *vmsg[1]; +#endif +}; + +/* NOTE: Only for readers of built-in topics, that have the of a GID as key, + and that should have the full GID as a key */ + +struct mtreader *new_mtreader (unsigned ntopics, struct u_topic_s **topics); +void delete_mtreader (struct mtreader *mtr); + +int update_mtreader (struct mtreader *mtr, const struct mtr_sample *outputs[2], const struct u_topic_s *tp, v_state sample_state, struct v_message_s *vmsg); + +/* Updates UDATA field in mtr_sample corresponding to KEY; returns ERR_INVALID_DATA if no such sample */ +int update_mtreader_setflag (struct mtreader *mtr, const v_gid *key, unsigned flag); + +/* Allocates and returns array of live, complete samples for which pred(&TP.FIELD,B) && !FLAG, return value is length. All returned samples are in state UPD. */ +int query_mtreader (const struct mtreader *mtr, const struct mtr_sample ***result, const struct u_topic_s *tp, const char *field, int (*pred) (const void *a, const void *b), const void *b); + +const struct mtr_sample *mtr_first (const struct mtreader *mtr, struct mtr_iter *it); +const struct mtr_sample *mtr_next (struct mtr_iter *it); + +#endif diff --git a/src/services/ddsi2/code/q_murmurhash3.c b/src/services/ddsi2e/code/q_murmurhash3.c similarity index 96% rename from src/services/ddsi2/code/q_murmurhash3.c rename to src/services/ddsi2e/code/q_murmurhash3.c index da08e9e9f..e4c90ffea 100644 --- a/src/services/ddsi2/code/q_murmurhash3.c +++ b/src/services/ddsi2e/code/q_murmurhash3.c @@ -77,11 +77,9 @@ os_uint32 murmurhash3(const void *key, size_t len, os_uint32 seed) //---------- // finalization - h1 ^= len; + h1 ^= (os_uint32)len; h1 = fmix(h1); return h1; } - -/* SHA1 not available (unoffical build.) */ diff --git a/src/services/ddsi2/code/q_murmurhash3.h b/src/services/ddsi2e/code/q_murmurhash3.h similarity index 78% rename from src/services/ddsi2/code/q_murmurhash3.h rename to src/services/ddsi2e/code/q_murmurhash3.h index 94e00df09..c87923fb5 100644 --- a/src/services/ddsi2/code/q_murmurhash3.h +++ b/src/services/ddsi2e/code/q_murmurhash3.h @@ -6,5 +6,3 @@ os_uint32 murmurhash3 (const void *key, size_t len, os_uint32 seed); #endif - -/* SHA1 not available (unoffical build.) */ diff --git a/src/services/ddsi2/code/q_osplbuiltin.c b/src/services/ddsi2e/code/q_osplbuiltin.c similarity index 94% rename from src/services/ddsi2/code/q_osplbuiltin.c rename to src/services/ddsi2e/code/q_osplbuiltin.c index 40234cbc7..2c9dd7b22 100644 --- a/src/services/ddsi2/code/q_osplbuiltin.c +++ b/src/services/ddsi2e/code/q_osplbuiltin.c @@ -1,18 +1,16 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * @@ -60,8 +58,6 @@ #include "ut_xmlparser.h" -#define PGID(g) ((g).systemId), ((g).localId), ((g).serial) - struct faked_systems { ut_avlNode_t avlnode; c_ulong systemId; @@ -1803,7 +1799,7 @@ static v_copyin_result write_builtin_topic_copyin_topicInfo (UNUSED_ARG (c_type return V_COPYIN_RESULT_OK; } -void write_builtin_topic_proxy_participant (const struct proxy_participant *proxypp) +void write_builtin_topic_proxy_participant (const struct proxy_participant *proxypp, nn_wctime_t timestamp) { /* Note: we discover/create/call write_builtin... for the proxy participant based on the arrival of the SPDP data, but this usually occurs before we have @@ -1816,6 +1812,7 @@ void write_builtin_topic_proxy_participant (const struct proxy_participant *prox we should when talking to, e.g., RTI. */ u_result res; struct faked_systems *node; + const os_timeW ts = nn_wctime_to_os_timeW(timestamp); os_mutexLock(&faked_systems_lock); node = ut_avlLookup(&faked_systems_treedef, &faked_systems_tree, &proxypp->gid.systemId); @@ -1826,41 +1823,53 @@ void write_builtin_topic_proxy_participant (const struct proxy_participant *prox ut_avlInsert(&faked_systems_treedef, &faked_systems_tree, node); (void)u_builtinWriteFakeHeartbeat( heartbeatInfo_wr, proxypp->gid.systemId, L_WRITE); + { + v_group g = v_groupSetGet(gv.ospl_kernel->groupSet, V_BUILTIN_PARTITION, V_PARTICIPANTINFO_NAME); + (void)v_groupCompleteSet(g, V_ALIGNSTATE_COMPLETE); + c_free(g); + g = v_groupSetGet(gv.ospl_kernel->groupSet, V_BUILTIN_PARTITION, V_HEARTBEATINFO_NAME); + (void)v_groupCompleteSet(g, V_ALIGNSTATE_COMPLETE); + c_free(g); + g = v_groupSetGet(gv.ospl_kernel->groupSet, V_BUILTIN_PARTITION, V_C_AND_M_COMMAND_NAME); + (void)v_groupCompleteSet(g, V_ALIGNSTATE_COMPLETE); + c_free(g); + } } else { node->participant_count++; } os_mutexUnlock(&faked_systems_lock); - if ((res = u_writerWrite (participantInfo_wr, write_builtin_topic_copyin_participantInfo, (void *) proxypp, os_timeWGet(), U_INSTANCEHANDLE_NIL)) != U_RESULT_OK) + if ((res = u_writerWrite (participantInfo_wr, write_builtin_topic_copyin_participantInfo, (void *) proxypp, ts, U_INSTANCEHANDLE_NIL)) != U_RESULT_OK) NN_ERROR1 ("write_builtin_topic_proxy_participant: u_writerWrite error %d\n", (int) res); } -void write_builtin_topic_proxy_participant_cm (const struct proxy_participant *proxypp) +void write_builtin_topic_proxy_participant_cm (const struct proxy_participant *proxypp, nn_wctime_t timestamp) { u_result res; - if ((res = u_writerWrite (participantCMInfo_wr, write_builtin_topic_copyin_participantCMInfo, (void *) proxypp, os_timeWGet(), U_INSTANCEHANDLE_NIL)) != U_RESULT_OK) + const os_timeW ts = nn_wctime_to_os_timeW(timestamp); + if ((res = u_writerWrite (participantCMInfo_wr, write_builtin_topic_copyin_participantCMInfo, (void *) proxypp, ts, U_INSTANCEHANDLE_NIL)) != U_RESULT_OK) NN_ERROR1 ("write_builtin_topic_proxy_participant_cm: u_writerWrite error %d\n", (int) res); } -void dispose_builtin_topic_proxy_participant (const struct proxy_participant *proxypp, int isimplicit) +void dispose_builtin_topic_proxy_participant (const struct proxy_participant *proxypp, nn_wctime_t timestamp, int isimplicit) { /* Note: dispose_... is called after all endpoints have been cleaned up and are no longer referenced anywhere, as it is called when the number of references to the proxy participant drops to 0. So at this point, we can safely dispose/unregister the CM data. But we do need to writeDispose it, as it may not have been published yet (no data, or just not received yet). */ - const os_timeW tnow = os_timeWGet(); + const os_timeW ts = nn_wctime_to_os_timeW(timestamp); u_result res; struct faked_systems *node; - TRACE (("dispose_builtin_topic_proxy_participant %x:%x:%x%s\n", PGID (proxypp->gid), isimplicit ? " implicit" : "")); - if ((res = u_writerWriteDispose (participantInfo_wr, write_builtin_topic_copyin_participantInfo, (void *) proxypp, tnow, U_INSTANCEHANDLE_NIL)) != U_RESULT_OK) + nn_log (LC_DISCOVERY, "dispose_builtin_topic_proxy_participant "PGIDFMT"%s\n", PGID (proxypp->gid), isimplicit ? " implicit" : ""); + if ((res = u_writerWriteDispose (participantInfo_wr, write_builtin_topic_copyin_participantInfo, (void *) proxypp, ts, U_INSTANCEHANDLE_NIL)) != U_RESULT_OK) NN_ERROR1 ("dispose_builtin_topic_proxy_participant: u_writerWriteDispose error %d\n", (int) res); - if ((res = u_writerWriteDispose (participantCMInfo_wr, write_builtin_topic_copyin_participantCMInfo, (void *) proxypp, tnow, U_INSTANCEHANDLE_NIL)) != U_RESULT_OK) + if ((res = u_writerWriteDispose (participantCMInfo_wr, write_builtin_topic_copyin_participantCMInfo, (void *) proxypp, ts, U_INSTANCEHANDLE_NIL)) != U_RESULT_OK) NN_ERROR1 ("dispose_builtin_topic_proxy_participant[cm]: u_writerWriteDispose error %d\n", (int) res); - if ((res = u_writerUnregisterInstance (participantInfo_wr, write_builtin_topic_copyin_participantInfo, (void *) proxypp, tnow, U_INSTANCEHANDLE_NIL)) != U_RESULT_OK) + if ((res = u_writerUnregisterInstance (participantInfo_wr, write_builtin_topic_copyin_participantInfo, (void *) proxypp, ts, U_INSTANCEHANDLE_NIL)) != U_RESULT_OK) NN_ERROR1 ("dispose_builtin_topic_proxy_participant: u_writerUnregisterInstance error %d\n", (int) res); - if ((res = u_writerUnregisterInstance (participantCMInfo_wr, write_builtin_topic_copyin_participantCMInfo, (void *) proxypp, tnow, U_INSTANCEHANDLE_NIL)) != U_RESULT_OK) + if ((res = u_writerUnregisterInstance (participantCMInfo_wr, write_builtin_topic_copyin_participantCMInfo, (void *) proxypp, ts, U_INSTANCEHANDLE_NIL)) != U_RESULT_OK) NN_ERROR1 ("dispose_builtin_topic_proxy_participant[cm]: u_writerUnregisterInstance error %d\n", (int) res); os_mutexLock(&faked_systems_lock); @@ -1872,24 +1881,25 @@ void dispose_builtin_topic_proxy_participant (const struct proxy_participant *pr state |= L_IMPLICIT; ut_avlDelete(&faked_systems_treedef, &faked_systems_tree, node); os_free(node); + nn_log (LC_DISCOVERY, "dispose_builtin_topic_proxy_participant "PGIDFMT"%s dispose DCPSHeartbeat\n", PGID (proxypp->gid), isimplicit ? " implicit" : ""); (void)u_builtinWriteFakeHeartbeat(heartbeatInfo_wr, proxypp->gid.systemId, state); } } os_mutexUnlock(&faked_systems_lock); } -void write_builtin_topic_proxy_writer (const struct proxy_writer *pwr) +void write_builtin_topic_proxy_writer (const struct proxy_writer *pwr, nn_wctime_t timestamp) { - const os_timeW tnow = os_timeWGet(); + const os_timeW ts = nn_wctime_to_os_timeW(timestamp); u_result res; /* NOTE: If and when QoS changes are implemented, need to make sure disposes and unregisters are generated properly by DDSI - we're no longer relying on spliced to do that. */ - if ((res = u_writerWrite (publicationInfo_wr, write_builtin_topic_copyin_publicationInfo, (void *) pwr, tnow, U_INSTANCEHANDLE_NIL)) != U_RESULT_OK) + if ((res = u_writerWrite (publicationInfo_wr, write_builtin_topic_copyin_publicationInfo, (void *) pwr, ts, U_INSTANCEHANDLE_NIL)) != U_RESULT_OK) NN_ERROR1 ("write_builtin_topic_proxy_writer: u_writerWrite error %d\n", (int) res); - if ((res = u_writerWrite (dataWriterCMInfo_wr, write_builtin_topic_copyin_dataWriterCMInfo, (void *) pwr, tnow, U_INSTANCEHANDLE_NIL)) != U_RESULT_OK) + if ((res = u_writerWrite (dataWriterCMInfo_wr, write_builtin_topic_copyin_dataWriterCMInfo, (void *) pwr, ts, U_INSTANCEHANDLE_NIL)) != U_RESULT_OK) NN_ERROR1 ("write_builtin_topic_proxy_writer[cm]: u_writerWrite error %d\n", (int) res); } @@ -1922,98 +1932,98 @@ static int disconnect_writer_helper (v_group g, void *varg) return 0; } -void dispose_builtin_topic_proxy_writer (const struct proxy_writer *pwr, int isimplicit) +void dispose_builtin_topic_proxy_writer (const struct proxy_writer *pwr, nn_wctime_t timestamp, int isimplicit) { - const os_timeW tnow = os_timeWGet(); + const os_timeW ts = nn_wctime_to_os_timeW(timestamp); struct v_publicationInfo pubinfo; struct disconnect_writer_arg arg; u_result res; - TRACE (("dispose_builtin_topic_proxy_writer %x:%x:%x%s\n", PGID (pwr->c.gid), isimplicit ? " implicit" : "")); + nn_log (LC_DISCOVERY, "dispose_builtin_topic_proxy_writer "PGIDFMT"%s\n", PGID (pwr->c.gid), isimplicit ? " implicit" : ""); memset (&pubinfo, 0, sizeof (pubinfo)); pubinfo.key = pwr->c.gid; arg.uwriter = publicationInfo_wr; arg.pubinfo = &pubinfo; arg.isimplicit = (isimplicit != 0); - arg.timestamp = tnow; + arg.timestamp = ts; (void) nn_groupset_foreach (pwr->groups, disconnect_writer_helper, &arg); - if ((res = u_writerWriteDispose (publicationInfo_wr, write_builtin_topic_copyin_publicationInfo, (void *) pwr, tnow, U_INSTANCEHANDLE_NIL)) != U_RESULT_OK) + if ((res = u_writerWriteDispose (publicationInfo_wr, write_builtin_topic_copyin_publicationInfo, (void *) pwr, ts, U_INSTANCEHANDLE_NIL)) != U_RESULT_OK) NN_ERROR1 ("dispose_builtin_topic_proxy_writer: u_writerWriteDispose error %d\n", (int) res); - if ((res = u_writerWriteDispose (dataWriterCMInfo_wr, write_builtin_topic_copyin_dataWriterCMInfo, (void *) pwr, tnow, U_INSTANCEHANDLE_NIL)) != U_RESULT_OK) + if ((res = u_writerWriteDispose (dataWriterCMInfo_wr, write_builtin_topic_copyin_dataWriterCMInfo, (void *) pwr, ts, U_INSTANCEHANDLE_NIL)) != U_RESULT_OK) NN_ERROR1 ("dispose_builtin_topic_proxy_writer[cm]: u_writerWriteDispose error %d\n", (int) res); - if ((res = u_writerUnregisterInstance (publicationInfo_wr, write_builtin_topic_copyin_publicationInfo, (void *) pwr, tnow, U_INSTANCEHANDLE_NIL)) != U_RESULT_OK) + if ((res = u_writerUnregisterInstance (publicationInfo_wr, write_builtin_topic_copyin_publicationInfo, (void *) pwr, ts, U_INSTANCEHANDLE_NIL)) != U_RESULT_OK) NN_ERROR1 ("dispose_builtin_topic_proxy_writer: u_writerUnregisterInstance error %d\n", (int) res); - if ((res = u_writerUnregisterInstance (dataWriterCMInfo_wr, write_builtin_topic_copyin_dataWriterCMInfo, (void *) pwr, tnow, U_INSTANCEHANDLE_NIL)) != U_RESULT_OK) + if ((res = u_writerUnregisterInstance (dataWriterCMInfo_wr, write_builtin_topic_copyin_dataWriterCMInfo, (void *) pwr, ts, U_INSTANCEHANDLE_NIL)) != U_RESULT_OK) NN_ERROR1 ("dispose_builtin_topic_proxy_writer[cm]: u_writerUnregisterInstance error %d\n", (int) res); } -void write_builtin_topic_proxy_reader (const struct proxy_reader *prd) +void write_builtin_topic_proxy_reader (const struct proxy_reader *prd, nn_wctime_t timestamp) { - const os_timeW tnow = os_timeWGet(); + const os_timeW ts = nn_wctime_to_os_timeW(timestamp); u_result res; - if ((res = u_writerWrite (subscriptionInfo_wr, write_builtin_topic_copyin_subscriptionInfo, (void *) prd, tnow, U_INSTANCEHANDLE_NIL)) != U_RESULT_OK) + if ((res = u_writerWrite (subscriptionInfo_wr, write_builtin_topic_copyin_subscriptionInfo, (void *) prd, ts, U_INSTANCEHANDLE_NIL)) != U_RESULT_OK) NN_ERROR1 ("write_builtin_topic_proxy_reader: u_writerWrite error %d\n", (int) res); - if ((res = u_writerWrite (dataReaderCMInfo_wr, write_builtin_topic_copyin_dataReaderCMInfo, (void *) prd, tnow, U_INSTANCEHANDLE_NIL)) != U_RESULT_OK) + if ((res = u_writerWrite (dataReaderCMInfo_wr, write_builtin_topic_copyin_dataReaderCMInfo, (void *) prd, ts, U_INSTANCEHANDLE_NIL)) != U_RESULT_OK) NN_ERROR1 ("write_builtin_topic_proxy_reader[cm]: u_writerWrite error %d\n", (int) res); } -void dispose_builtin_topic_proxy_reader (const struct proxy_reader *prd, int isimplicit) +void dispose_builtin_topic_proxy_reader (const struct proxy_reader *prd, nn_wctime_t timestamp, int isimplicit) { - const os_timeW tnow = os_timeWGet(); + const os_timeW ts = nn_wctime_to_os_timeW(timestamp); u_result res; - TRACE (("dispose_builtin_topic_proxy_reader %x:%x:%x%s\n", PGID (prd->c.gid), isimplicit ? " implicit" : "")); - if ((res = u_writerWriteDispose (subscriptionInfo_wr, write_builtin_topic_copyin_subscriptionInfo, (void *) prd, tnow, U_INSTANCEHANDLE_NIL)) != U_RESULT_OK) + nn_log (LC_DISCOVERY, "dispose_builtin_topic_proxy_reader "PGIDFMT"%s\n", PGID (prd->c.gid), isimplicit ? " implicit" : ""); + if ((res = u_writerWriteDispose (subscriptionInfo_wr, write_builtin_topic_copyin_subscriptionInfo, (void *) prd, ts, U_INSTANCEHANDLE_NIL)) != U_RESULT_OK) NN_ERROR1 ("dispose_builtin_topic_proxy_reader: u_writerWriteDispose error %d\n", (int) res); - if ((res = u_writerWriteDispose (dataReaderCMInfo_wr, write_builtin_topic_copyin_dataReaderCMInfo, (void *) prd, tnow, U_INSTANCEHANDLE_NIL)) != U_RESULT_OK) + if ((res = u_writerWriteDispose (dataReaderCMInfo_wr, write_builtin_topic_copyin_dataReaderCMInfo, (void *) prd, ts, U_INSTANCEHANDLE_NIL)) != U_RESULT_OK) NN_ERROR1 ("dispose_builtin_topic_proxy_reader[cm]: u_writerWriteDispose error %d\n", (int) res); - if ((res = u_writerUnregisterInstance (subscriptionInfo_wr, write_builtin_topic_copyin_subscriptionInfo, (void *) prd, tnow, U_INSTANCEHANDLE_NIL)) != U_RESULT_OK) + if ((res = u_writerUnregisterInstance (subscriptionInfo_wr, write_builtin_topic_copyin_subscriptionInfo, (void *) prd, ts, U_INSTANCEHANDLE_NIL)) != U_RESULT_OK) NN_ERROR1 ("dispose_builtin_topic_proxy_reader: u_writerUnregisterInstance error %d\n", (int) res); - if ((res = u_writerUnregisterInstance (dataReaderCMInfo_wr, write_builtin_topic_copyin_dataReaderCMInfo, (void *) prd, tnow, U_INSTANCEHANDLE_NIL)) != U_RESULT_OK) + if ((res = u_writerUnregisterInstance (dataReaderCMInfo_wr, write_builtin_topic_copyin_dataReaderCMInfo, (void *) prd, ts, U_INSTANCEHANDLE_NIL)) != U_RESULT_OK) NN_ERROR1 ("dispose_builtin_topic_proxy_reader[cm]: u_writerUnregisterInstance error %d\n", (int) res); } -void write_builtin_topic_proxy_group (const struct proxy_group *pgroup) +void write_builtin_topic_proxy_group (const struct proxy_group *pgroup, nn_wctime_t timestamp) { - const os_timeW tnow = os_timeWGet(); + const os_timeW ts = nn_wctime_to_os_timeW(timestamp); u_result res; - TRACE (("write_builtin_topic_proxy_group %x:%x:%x:%x gid %x:%x:%x\n", PGUID (pgroup->guid), PGID (pgroup->gid))); + nn_log (LC_DISCOVERY, "write_builtin_topic_proxy_group "PGUIDFMT" gid "PGIDFMT"\n", PGUID (pgroup->guid), PGID (pgroup->gid)); switch (pgroup->guid.entityid.u & (NN_ENTITYID_SOURCE_MASK | NN_ENTITYID_KIND_MASK)) { case NN_ENTITYID_SOURCE_VENDOR | NN_ENTITYID_KIND_PRISMTECH_PUBLISHER: - if ((res = u_writerWrite (publisherCMInfo_wr, write_builtin_topic_copyin_publisherCMInfo, (void *) pgroup, tnow, U_INSTANCEHANDLE_NIL)) != U_RESULT_OK) + if ((res = u_writerWrite (publisherCMInfo_wr, write_builtin_topic_copyin_publisherCMInfo, (void *) pgroup, ts, U_INSTANCEHANDLE_NIL)) != U_RESULT_OK) NN_ERROR1 ("write_builtin_topic_proxy_group[pub]: u_writerWrite error %d\n", (int) res); break; case NN_ENTITYID_SOURCE_VENDOR | NN_ENTITYID_KIND_PRISMTECH_SUBSCRIBER: - if ((res = u_writerWrite (subscriberCMInfo_wr, write_builtin_topic_copyin_subscriberCMInfo, (void *) pgroup, tnow, U_INSTANCEHANDLE_NIL)) != U_RESULT_OK) + if ((res = u_writerWrite (subscriberCMInfo_wr, write_builtin_topic_copyin_subscriberCMInfo, (void *) pgroup, ts, U_INSTANCEHANDLE_NIL)) != U_RESULT_OK) NN_ERROR1 ("write_builtin_topic_proxy_group[sub]: u_writerWrite error %d\n", (int) res); break; } } -void dispose_builtin_topic_proxy_group (const struct proxy_group *pgroup, int isimplicit) +void dispose_builtin_topic_proxy_group (const struct proxy_group *pgroup, nn_wctime_t timestamp, int isimplicit) { - const os_timeW tnow = os_timeWGet(); + const os_timeW ts = nn_wctime_to_os_timeW(timestamp); u_result res; - TRACE (("dispose_builtin_topic_proxy_group %x:%x:%x:%x gid %x:%x:%x%s\n", PGUID (pgroup->guid), PGID (pgroup->gid), isimplicit ? " implicit" : "")); + nn_log (LC_DISCOVERY, "dispose_builtin_topic_proxy_group "PGUIDFMT" gid "PGIDFMT"%s\n", PGUID (pgroup->guid), PGID (pgroup->gid), isimplicit ? " implicit" : ""); switch (pgroup->guid.entityid.u & (NN_ENTITYID_SOURCE_MASK | NN_ENTITYID_KIND_MASK)) { case NN_ENTITYID_SOURCE_VENDOR | NN_ENTITYID_KIND_PRISMTECH_PUBLISHER: - if ((res = u_writerWriteDispose (publisherCMInfo_wr, write_builtin_topic_copyin_publisherCMInfo, (void *) pgroup, tnow, U_INSTANCEHANDLE_NIL)) != U_RESULT_OK) + if ((res = u_writerWriteDispose (publisherCMInfo_wr, write_builtin_topic_copyin_publisherCMInfo, (void *) pgroup, ts, U_INSTANCEHANDLE_NIL)) != U_RESULT_OK) NN_ERROR1 ("dispose_builtin_topic_proxy_group[pub]: u_writerWriteDispose error %d\n", (int) res); - if ((res = u_writerUnregisterInstance (publisherCMInfo_wr, write_builtin_topic_copyin_publisherCMInfo, (void *) pgroup, tnow, U_INSTANCEHANDLE_NIL)) != U_RESULT_OK) + if ((res = u_writerUnregisterInstance (publisherCMInfo_wr, write_builtin_topic_copyin_publisherCMInfo, (void *) pgroup, ts, U_INSTANCEHANDLE_NIL)) != U_RESULT_OK) NN_ERROR1 ("dispose_builtin_topic_proxy_group[pub]: u_writerUnregisterInstance error %d\n", (int) res); break; case NN_ENTITYID_SOURCE_VENDOR | NN_ENTITYID_KIND_PRISMTECH_SUBSCRIBER: - if ((res = u_writerWriteDispose (subscriberCMInfo_wr, write_builtin_topic_copyin_subscriberCMInfo, (void *) pgroup, tnow, U_INSTANCEHANDLE_NIL)) != U_RESULT_OK) + if ((res = u_writerWriteDispose (subscriberCMInfo_wr, write_builtin_topic_copyin_subscriberCMInfo, (void *) pgroup, ts, U_INSTANCEHANDLE_NIL)) != U_RESULT_OK) NN_ERROR1 ("dispose_builtin_topic_proxy_group[sub]: u_writerWriteDispose error %d\n", (int) res); - if ((res = u_writerUnregisterInstance (subscriberCMInfo_wr, write_builtin_topic_copyin_subscriberCMInfo, (void *) pgroup, tnow, U_INSTANCEHANDLE_NIL)) != U_RESULT_OK) + if ((res = u_writerUnregisterInstance (subscriberCMInfo_wr, write_builtin_topic_copyin_subscriberCMInfo, (void *) pgroup, ts, U_INSTANCEHANDLE_NIL)) != U_RESULT_OK) NN_ERROR1 ("dispose_builtin_topic_proxy_group[sub]: u_writerUnregisterInstance error %d\n", (int) res); break; } } -void write_builtin_topic_proxy_topic (const struct nn_plist *datap) +void write_builtin_topic_proxy_topic (const struct nn_plist *datap, nn_wctime_t timestamp) { const char *tpname; assert (datap->qos.present & QP_TOPIC_NAME); @@ -2022,9 +2032,9 @@ void write_builtin_topic_proxy_topic (const struct nn_plist *datap) TRACE ((" (ignoring built-in topic %s)", tpname)); else { - const os_timeW tnow = os_timeWGet(); + const os_timeW ts = nn_wctime_to_os_timeW(timestamp); u_result res; - if ((res = u_writerWrite (topicInfo_wr, write_builtin_topic_copyin_topicInfo, (void *) datap, tnow, U_INSTANCEHANDLE_NIL)) != U_RESULT_OK) + if ((res = u_writerWrite (topicInfo_wr, write_builtin_topic_copyin_topicInfo, (void *) datap, ts, U_INSTANCEHANDLE_NIL)) != U_RESULT_OK) NN_ERROR1 ("write_builtin_topic_proxy_topic: u_writerWrite error %d\n", (int) res); } } @@ -2106,5 +2116,3 @@ void destroy_builtin_topic_writers (void) ut_avlFree(&faked_systems_treedef, &faked_systems_tree, os_free); os_mutexDestroy (&faked_systems_lock); } - -/* SHA1 not available (unoffical build.) */ diff --git a/src/services/ddsi2e/code/q_osplbuiltin.h b/src/services/ddsi2e/code/q_osplbuiltin.h new file mode 100644 index 000000000..d99cfd202 --- /dev/null +++ b/src/services/ddsi2e/code/q_osplbuiltin.h @@ -0,0 +1,43 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#ifndef Q_OSPLBUILTIN_H +#define Q_OSPLBUILTIN_H + +struct v_subscriptionInfo; +struct v_publicationInfo; +struct v_publisherCMInfo; +struct v_subscriberCMInfo; +struct v_topicInfo; +struct u_participant_s; +struct v_topicQos_s; +struct nn_xqos; +struct nn_plist; + +int init_reader_qos (const struct v_subscriptionInfo *data, const struct v_dataReaderCMInfo *cmdata, struct nn_xqos *xqos, int interpret_user_data); +int init_writer_qos (const struct v_publicationInfo *data, const struct v_dataWriterCMInfo *cmdata, v_topic ospl_topic, struct nn_xqos *xqos, int interpret_user_data); +int init_reader_qos_from_topicQos (const struct v_topicQos_s *data, struct nn_xqos *xqos); +int init_topic_plist (const struct v_topicInfo *data, struct nn_plist *ps); +int init_cm_publisher_plist (const struct v_publisherCMInfo *data, const nn_guid_t *guid, struct nn_plist *ps); +int init_cm_subscriber_plist (const struct v_subscriberCMInfo *data, const nn_guid_t *guid, struct nn_plist *ps); +int init_participant_plist (const struct v_participantInfo *data, const struct v_participantCMInfo *cmdata, struct nn_plist *ps); +u_result create_builtin_topic_writers (struct u_participant_s *p); +int is_builtin_topic_writer (const struct v_gid_s *gid); +void destroy_builtin_topic_writers (void); +int is_topic_discoverable (const char *topic); + +#endif diff --git a/src/services/ddsi2/code/q_osplser.c b/src/services/ddsi2e/code/q_osplser.c similarity index 97% rename from src/services/ddsi2/code/q_osplser.c rename to src/services/ddsi2e/code/q_osplser.c index 6cde0f415..039c0718a 100644 --- a/src/services/ddsi2/code/q_osplser.c +++ b/src/services/ddsi2e/code/q_osplser.c @@ -1,18 +1,16 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * @@ -103,6 +101,16 @@ #define USE_ATOMIC_LIFO 0 #endif +/* Error codes used in defining topics */ +enum errcode { + ERRCODE_SUCCESS, + ERRCODE_INTERNAL, + ERRCODE_TOO_DEEPLY_NESTED, + ERRCODE_NOT_FOUND, + ERRCODE_NOT_KEYTYPE, + ERRCODE_KEYS_TOO_LARGE +}; + static int serialize1 (serstate_t st, C_STRUCT(c_type) const * const type, const char *data, unsigned off); static int deserialize1 (C_STRUCT(c_type) const * const type, char *dst, const char *src, size_t srcoff, size_t srcsize); static int deserialize1S (C_STRUCT(c_type) const * const type, char *dst, const char *src, size_t srcoff, size_t srcsize); @@ -285,7 +293,7 @@ static int iskeytype (C_STRUCT(c_type) const * const type) } } -static int findkey (struct dds_key_descriptor *ki, C_STRUCT(c_type) const *type, const char *key, unsigned *maxsz) +static enum errcode findkey (struct dds_key_descriptor *ki, C_STRUCT(c_type) const *type, const char *key, unsigned *maxsz) { /* Looks up dot-separated field names in type (accepting only structures & ending on a primitive type or a string); sets @@ -293,6 +301,7 @@ static int findkey (struct dds_key_descriptor *ki, C_STRUCT(c_type) const *type, char *keycopy = os_strdup (key), *cursor = keycopy, *name; C_STRUCT (c_member) const *member = NULL; int ordpos = 63; /* So we never try to compute (uint64_t)0 << 64 */ + enum errcode errcode = ERRCODE_INTERNAL; ki->ord = 0; ki->off = 0; type = c_typeActualType ((c_type) type); /* WT? not const? */ @@ -324,6 +333,7 @@ static int findkey (struct dds_key_descriptor *ki, C_STRUCT(c_type) const *type, if (ordpos < 0) { nn_log (LC_TOPIC, " - too deeply nested (n %u -> %u ordpos' %d)\n", n, ceiling_lg2 (n), ordpos); + errcode = ERRCODE_TOO_DEEPLY_NESTED; goto too_deeply_nested; } ki->ord |= ((unsigned long long) i) << ordpos; @@ -334,6 +344,7 @@ static int findkey (struct dds_key_descriptor *ki, C_STRUCT(c_type) const *type, if (i == n) { nn_log (LC_TOPIC, " - not found\n"); + errcode = ERRCODE_NOT_FOUND; goto not_found; } nn_log (LC_TOPIC, "\n"); @@ -344,6 +355,7 @@ static int findkey (struct dds_key_descriptor *ki, C_STRUCT(c_type) const *type, a member in something other than a struct, ... */ nn_log (LC_TOPIC, " not found or not a key type (%p, %p, %d)\n", (void *) name, (void *) member, (int) iskeytype (type)); + errcode = (name != NULL || member == NULL) ? ERRCODE_NOT_FOUND : ERRCODE_NOT_KEYTYPE; goto unhappy; } os_free (keycopy); @@ -377,12 +389,12 @@ static int findkey (struct dds_key_descriptor *ki, C_STRUCT(c_type) const *type, default: assert (0); } - return 1; + return ERRCODE_SUCCESS; unhappy: not_found: too_deeply_nested: os_free (keycopy); - return 0; + return errcode; } static int calc_m_seroff (sertopic_t tp, const unsigned *maxstrlengths) @@ -435,7 +447,6 @@ static int calc_m_seroff (sertopic_t tp, const unsigned *maxstrlengths) for (i = 1; i < tp->nkeys; i++) { assert (tp->keys[i].m_seroff > tp->keys[i-1].m_seroff); - assert (tp->keys[i].m_seroff < sizeof (((struct serdata *) 0)->v.key)); } } #endif @@ -479,6 +490,21 @@ static int cdr_serdata_tag (os_uint32 *tag, void *vtp, enum sd_cdrTagType type, } #endif +static const char *errcodestr (enum errcode errcode) +{ + const char *m = "undefined"; + switch (errcode) + { + case ERRCODE_SUCCESS: m = "success"; break; + case ERRCODE_INTERNAL: m = "internal"; break; + case ERRCODE_TOO_DEEPLY_NESTED: m = "key field(s) too deeply nested"; break; + case ERRCODE_NOT_FOUND: m = "key field(s) not found"; break; + case ERRCODE_NOT_KEYTYPE: m = "key field(s) of unsupported type"; break; + case ERRCODE_KEYS_TOO_LARGE: m = "serialized form of keys too long"; break; + } + return m; +} + static sertopic_t deftopic_unl (const char *name, C_STRUCT(v_topic) const * const ospl_topic, const char *typename, C_STRUCT(c_type) const * const type, unsigned nkeys, char const * const *keys) { sertopic_t tp; @@ -486,6 +512,7 @@ static sertopic_t deftopic_unl (const char *name, C_STRUCT(v_topic) const * cons unsigned *maxstrlengths; /* for fixed-length strings: maximum string length; anything else: 0 */ ut_avlIPath_t path; char *name_typename; + enum errcode errcode = ERRCODE_INTERNAL; /* Reuse known definition, if available; compare is on name+typeame, just in case. But we forget about the keys ... */ @@ -514,13 +541,14 @@ static sertopic_t deftopic_unl (const char *name, C_STRUCT(v_topic) const * cons tp->nkeys = nkeys; for (i = 0; i < nkeys; i++) { - if (!findkey (&tp->keys[i], type, keys[i], &maxstrlengths[i])) + if ((errcode = findkey (&tp->keys[i], type, keys[i], &maxstrlengths[i])) != ERRCODE_SUCCESS) goto fail3; tp->keys[i].specord_idx = (unsigned short) i; } if (!calc_m_seroff (tp, maxstrlengths)) { /* Keys don't fit in available space */ + errcode = ERRCODE_KEYS_TOO_LARGE; goto fail3; } /* sort on serialization order */ @@ -579,6 +607,7 @@ static sertopic_t deftopic_unl (const char *name, C_STRUCT(v_topic) const * cons os_free (tp); os_free (maxstrlengths); os_free (name_typename); + NN_ERROR3 ("topic %s type %s not supported by DDSI2: %s\n", name, typename, errcodestr (errcode)); return NULL; } @@ -600,7 +629,8 @@ sertopic_t deftopic (C_STRUCT(v_topic) const * const ospl_topic) { if (nkeys == MAX_NKEYS) goto fail; - keys[nkeys++] = k; + if (*k!='\0') + keys[nkeys++] = k; } } ospl_type = v_topicDataType ((v_topic) ospl_topic); @@ -741,22 +771,14 @@ serdata_t serialize_raw static unsigned statusinfo_from_msg (C_STRUCT (v_message) const *msg) { - switch (v_nodeState ((v_message) msg) & ~(L_SYNCHRONOUS | L_TRANSACTION | L_ENDOFTRANSACTION)) - { - case 0: - /* kernel doesn't produce it state = 0, but we do temporarily - for pretty-printing incoming data */ - case L_WRITE: - return 0; - case L_WRITE | L_DISPOSED: - case L_DISPOSED: - return NN_STATUSINFO_DISPOSE; - case L_UNREGISTER: - return NN_STATUSINFO_UNREGISTER; - default: - NN_WARNING1 ("statusinfo_from_msg: unhandled message state: %u\n", (unsigned) v_nodeState ((v_message) msg)); - return 0; - } + unsigned st = 0; + if (v_nodeState ((v_message) msg) & L_DISPOSED) + st |= NN_STATUSINFO_DISPOSE; + if (v_nodeState ((v_message) msg) & L_UNREGISTER) + st |= NN_STATUSINFO_UNREGISTER; + if (v_nodeState ((v_message) msg) & L_AUTO) + st |= NN_STATUSINFO_OSPL_AUTO; + return st; } static void set_msginfo (serdata_t d, unsigned statusinfo, C_STRUCT (v_message) const *msg) @@ -1701,7 +1723,7 @@ static int desercollG (C_STRUCT(c_type) const * const type, char *dst, const cha static unsigned isprint_runlen (const unsigned char *s, unsigned n) { unsigned m; - for (m = 0; m < n && isprint (s[m]); m++) + for (m = 0; m < n && s[m] != '"' && isprint (s[m]); m++) ; return m; } @@ -1772,7 +1794,7 @@ static int desercollP (C_STRUCT(c_type) const * const type, char **dst, int *dst unsigned i = 0, j; while (i < n) { - unsigned m = isprint_runlen ((unsigned char *) (src + srcoff), n); + unsigned m = isprint_runlen ((unsigned char *) (src + srcoff), n - i); if (m >= 4) { mysnprintf (dst, dstsize, "%s\"", i != 0 ? "," : ""); @@ -2066,7 +2088,6 @@ static int deserialize_prep default: return 0; } - if ((*msg = v_topicMessageNew_s ((v_topic) ospl_topic)) == NULL) return 0; (*msg)->qos = NULL; @@ -2735,7 +2756,7 @@ unsigned serdata_hash (const struct serdata *a) { const struct cdrstring *astr = (const struct cdrstring *) (a->v.key + *((unsigned *) (a->v.key + p))); h = murmurhash3(astr, 4 + astr->length, h); - p += sizeof (unsigned); + p += (unsigned)sizeof (unsigned); } } if (p < keysersize) @@ -2803,5 +2824,3 @@ void serstate_free (serstate_t st) os_free (st->data); os_free (st); } - -/* SHA1 not available (unoffical build.) */ diff --git a/src/services/ddsi2/code/q_osplser.h b/src/services/ddsi2e/code/q_osplser.h similarity index 77% rename from src/services/ddsi2/code/q_osplser.h rename to src/services/ddsi2e/code/q_osplser.h index 7db30b30c..ba60d6ed2 100644 --- a/src/services/ddsi2/code/q_osplser.h +++ b/src/services/ddsi2e/code/q_osplser.h @@ -1,18 +1,16 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * @@ -58,5 +56,3 @@ void serstate_init (serstate_t st, const struct sertopic * topic); void serstate_free (serstate_t st); #endif /* NN_OSPLSER_H */ - -/* SHA1 not available (unoffical build.) */ diff --git a/src/services/ddsi2e/code/q_osplserModule.odl b/src/services/ddsi2e/code/q_osplserModule.odl new file mode 100644 index 000000000..2ef615a7c --- /dev/null +++ b/src/services/ddsi2e/code/q_osplserModule.odl @@ -0,0 +1,60 @@ +/* -*- C -*- */ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_OUTER_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +module q_osplserModule { + typedef struct type4u_s { + c_ulong a; + c_ulong b; + c_ulong c; + c_ulong d; + } type4u; + + typedef struct pmd_s { + c_ulong a; + c_ulong b; + c_ulong c; /* officially: octets */ + c_ulong kind; /* officially: octets */ + sequence value; + } pmd; + + enum bubble_kind { + BTK_DELETE_WRITER + }; + + typedef struct bubble_s { + bubble_kind kind; + c_ulong systemId; + c_ulong localId; + c_ulong serial; + } bubble; + + struct name_value { + string name; + string value; + }; + typedef sequence seq_name_value; + + struct ddsi_control { + c_ulong systemId; + c_ulong localId; + c_ulong serial; + c_bool deaf; + c_bool mute; + c_double duration; /* 0: infinite */ + }; +}; diff --git a/src/services/ddsi2/code/ddsi_ser.c b/src/services/ddsi2e/core/ddsi_ser.c similarity index 91% rename from src/services/ddsi2/code/ddsi_ser.c rename to src/services/ddsi2e/core/ddsi_ser.c index 9eda027b7..812f86796 100644 --- a/src/services/ddsi2/code/ddsi_ser.c +++ b/src/services/ddsi2e/core/ddsi_ser.c @@ -1,18 +1,16 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * @@ -171,12 +169,17 @@ void ddsi_serstate_append_blob (serstate_t st, size_t align, size_t sz, const vo void ddsi_serstate_set_msginfo ( serstate_t st, unsigned statusinfo, nn_wctime_t timestamp, +#if LITE + void * dummy +#else const struct nn_prismtech_writer_info *wri +#endif ) { serdata_t d = st->data; d->v.msginfo.statusinfo = statusinfo; d->v.msginfo.timestamp = timestamp; +#if !LITE if (wri == NULL) d->v.msginfo.have_wrinfo = 0; else @@ -184,6 +187,7 @@ void ddsi_serstate_set_msginfo d->v.msginfo.have_wrinfo = 1; d->v.msginfo.wrinfo = *wri; } +#endif } os_uint32 ddsi_serdata_size (const struct serdata *serdata) @@ -249,6 +253,9 @@ void ddsi_serstate_release (serstate_t st) if (pa_dec32_nv (&st->refcount) == 0) { serstatepool_t pool = st->pool; +#if LITE + sertopic_free ((sertopic_t) st->topic); +#endif #if USE_ATOMIC_LIFO if (pa_inc32_nv(&pool->approx_nfree) <= MAX_POOL_SIZE) os_atomic_lifo_push (&pool->freelist, st, offsetof (struct serstate, next)); @@ -311,5 +318,3 @@ static size_t alignup_size (size_t x, size_t a) assert (ispowerof2_size (a)); return -((-x) & (-a)); } - -/* SHA1 not available (unoffical build.) */ diff --git a/src/services/ddsi2/code/ddsi_ser.h b/src/services/ddsi2e/core/ddsi_ser.h similarity index 77% rename from src/services/ddsi2/code/ddsi_ser.h rename to src/services/ddsi2e/core/ddsi_ser.h index 2e3683abe..b9ef1492e 100644 --- a/src/services/ddsi2/code/ddsi_ser.h +++ b/src/services/ddsi2e/core/ddsi_ser.h @@ -1,18 +1,16 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * @@ -31,6 +29,10 @@ #define OS_API OS_API_IMPORT #endif +#if LITE +#include "dds.h" +#include "dds_topic.h" +#endif #ifndef PLATFORM_IS_LITTLE_ENDIAN #ifdef PA_BIG_ENDIAN @@ -70,12 +72,14 @@ struct serdata_msginfo { unsigned statusinfo; nn_wctime_t timestamp; +#if !LITE #ifndef NDEBUG unsigned have_wrinfo: 2; #else unsigned have_wrinfo: 1; #endif struct nn_prismtech_writer_info wrinfo; +#endif }; enum serstate_kind { @@ -91,7 +95,9 @@ struct serstate pa_uint32_t refcount; size_t pos; size_t size; +#if !LITE int keyidx; /* current index in topic.keys */ +#endif const struct sertopic * topic; enum serstate_kind kind; serstatepool_t pool; @@ -111,6 +117,22 @@ struct serstatepool #endif }; +#if LITE + +#define DDS_KEY_SET 0x0001 +#define DDS_KEY_HASH_SET 0x0002 +#define DDS_KEY_IS_HASH 0x0004 + +typedef struct dds_key_hash +{ + char m_hash [16]; /* Key hash value. Also possibly key. */ + uint32_t m_key_len; /* Length of key (may be in m_hash or m_key_buff) */ + uint32_t m_key_buff_size; /* Size of allocated key buffer (m_key_buff) */ + char * m_key_buff; /* Key buffer */ + uint32_t m_flags; /* State of key/hash (see DDS_KEY_XXX) */ +} +dds_key_hash_t; +#endif struct serdata_base { @@ -118,8 +140,13 @@ struct serdata_base struct serdata_msginfo msginfo; int hash_valid; /* whether hash is valid or must be computed from key/data */ os_uint32 hash; /* cached serdata hash, valid only if hash_valid != 0 */ +#if LITE + dds_key_hash_t keyhash; + bool bswap; /* Whether state is native endian or requires swapping */ +#else char key[32]; /* copies + 32-bit offsets (from &key[0] into data) to CDR strings */ unsigned isstringref; /* (isstringref & (1 << k)) iff key[k] is first of an offset */ +#endif }; struct serdata @@ -133,6 +160,11 @@ struct serdata char data[1]; }; +#if LITE + +struct dds_key_descriptor; + +#else typedef enum dds_keytype { @@ -157,8 +189,15 @@ typedef struct dds_key_descriptor } dds_key_descriptor_t; +#endif +#if LITE +struct dds_topic; +typedef void (*topic_cb_t) (struct dds_topic * topic); +typedef bool (*dds_topic_intern_filter_fn) (const void * sample, void *ctx); +#else struct v_topic_s; +#endif struct sertopic { @@ -169,10 +208,23 @@ struct sertopic void * type; unsigned nkeys; +#if LITE + uint32_t id; + uint32_t hash; + uint32_t flags; + pa_uint32_t refcount; + topic_cb_t status_cb; + dds_topic_intern_filter_fn filter_fn; + void * filter_sample; + void * filter_ctx; + struct dds_topic * status_cb_entity; + const struct dds_key_descriptor * keys; +#else struct v_topic_s *ospl_topic; struct sd_cdrInfo *ci; unsigned keysersize; struct dds_key_descriptor keys[1]; +#endif /* Array of keys, represented as offset in the OpenSplice internal @@ -204,7 +256,11 @@ OS_API void ddsi_serstate_append_blob (serstate_t st, size_t align, size_t sz, c OS_API void ddsi_serstate_set_msginfo ( serstate_t st, unsigned statusinfo, nn_wctime_t timestamp, +#if LITE + void * dummy +#else const struct nn_prismtech_writer_info *wri +#endif ); OS_API serstate_t ddsi_serstate_new (serstatepool_t pool, const struct sertopic * topic); OS_API serdata_t ddsi_serstate_fix (serstate_t st); @@ -216,5 +272,3 @@ void * ddsi_serstate_append_align (serstate_t st, size_t a); void * ddsi_serstate_append_aligned (serstate_t st, size_t n, size_t a); #undef OS_API #endif - -/* SHA1 not available (unoffical build.) */ diff --git a/src/services/ddsi2/code/ddsi_ssl.c b/src/services/ddsi2e/core/ddsi_ssl.c similarity index 92% rename from src/services/ddsi2/code/ddsi_ssl.c rename to src/services/ddsi2e/core/ddsi_ssl.c index b129db4e3..0f5536b76 100644 --- a/src/services/ddsi2/code/ddsi_ssl.c +++ b/src/services/ddsi2e/core/ddsi_ssl.c @@ -1,18 +1,16 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * @@ -319,7 +317,7 @@ static SSL_CTX * ddsi_ssl_ctx_init (void) { SSL_CTX_set_verify (ctx, SSL_VERIFY_NONE, NULL); } - SSL_CTX_set_options (ctx, SSL_OP_ALL | SSL_OP_NO_SSLv2); + SSL_CTX_set_options (ctx, (long)(SSL_OP_ALL | SSL_OP_NO_SSLv2)); return ctx; @@ -444,5 +442,3 @@ void ddsi_ssl_plugin (void) } #endif /* DDSI_INCLUDE_SSL */ - -/* SHA1 not available (unoffical build.) */ diff --git a/src/services/ddsi2e/core/ddsi_ssl.h b/src/services/ddsi2e/core/ddsi_ssl.h new file mode 100644 index 000000000..6c945b378 --- /dev/null +++ b/src/services/ddsi2e/core/ddsi_ssl.h @@ -0,0 +1,34 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#ifndef _DDSI_SSL_H_ +#define _DDSI_SSL_H_ + +#ifdef DDSI_INCLUDE_SSL + +#ifdef _WIN32 +/* WinSock2 must be included before openssl headers + otherwise winsock will be used */ +#include +#endif + +#include + +void ddsi_ssl_plugin (void); + +#endif +#endif diff --git a/src/services/ddsi2/code/ddsi_tcp.c b/src/services/ddsi2e/core/ddsi_tcp.c similarity index 97% rename from src/services/ddsi2/code/ddsi_tcp.c rename to src/services/ddsi2e/core/ddsi_tcp.c index 29854c37d..e0276b0da 100644 --- a/src/services/ddsi2/code/ddsi_tcp.c +++ b/src/services/ddsi2e/core/ddsi_tcp.c @@ -1,18 +1,16 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * @@ -367,7 +365,7 @@ static c_bool ddsi_tcp_select (os_socket sock, c_bool read, os_size_t pos) os_int64 tval = read ? config.tcp_read_timeout : config.tcp_write_timeout; FD_ZERO (&fds); - FD_SET (sock, &fds); + os_sock_set (sock, &fds); timeout = (os_duration)tval; TRACE_TCP (("%s blocked %s: sock %d\n", ddsi_name, read ? "read" : "write", (int) sock)); @@ -1039,7 +1037,9 @@ int ddsi_tcp_init (void) ddsi_tcp_base_init (&ddsi_tcp_conn_client); #ifdef DDSI_INCLUDE_SSL +#if !LITE ddsi_ssl_plugin (); +#endif if (ddsi_tcp_ssl_plugin.config) { (ddsi_tcp_ssl_plugin.config) (); @@ -1062,5 +1062,3 @@ int ddsi_tcp_init (void) } return 0; } - -/* SHA1 not available (unoffical build.) */ diff --git a/src/services/ddsi2e/core/ddsi_tcp.h b/src/services/ddsi2e/core/ddsi_tcp.h new file mode 100644 index 000000000..6321db079 --- /dev/null +++ b/src/services/ddsi2e/core/ddsi_tcp.h @@ -0,0 +1,47 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#ifndef _DDSI_TCP_H_ +#define _DDSI_TCP_H_ + +#include "ddsi_tran.h" + +#ifdef DDSI_INCLUDE_SSL + +#include "ddsi_ssl.h" + +struct ddsi_ssl_plugins +{ + void (*config) (void); + c_bool (*init) (void); + void (*fini) (void); + void (*ssl_free) (SSL * ssl); + void (*bio_vfree) (BIO * bio); + os_ssize_t (*read) (SSL * ssl, void * buf, os_size_t len, int * err); + os_ssize_t (*write) (SSL * ssl, const void * msg, os_size_t len, int * err); + SSL * (*connect) (os_socket sock); + BIO * (*listen) (os_socket sock); + SSL * (*accept) (BIO * bio, os_socket * sock); +}; + +struct ddsi_ssl_plugins ddsi_tcp_ssl_plugin; + +#endif + +int ddsi_tcp_init (void); + +#endif diff --git a/src/services/ddsi2/code/ddsi_tran.c b/src/services/ddsi2e/core/ddsi_tran.c similarity index 86% rename from src/services/ddsi2/code/ddsi_tran.c rename to src/services/ddsi2e/core/ddsi_tran.c index 459e5fd43..dfe4821a0 100644 --- a/src/services/ddsi2/code/ddsi_tran.c +++ b/src/services/ddsi2e/core/ddsi_tran.c @@ -1,18 +1,16 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * @@ -200,5 +198,3 @@ void ddsi_listener_free (ddsi_tran_listener_t listener) (listener->m_factory->m_release_listener_fn) (listener); } } - -/* SHA1 not available (unoffical build.) */ diff --git a/src/services/ddsi2/code/ddsi_tran.h b/src/services/ddsi2e/core/ddsi_tran.h similarity index 90% rename from src/services/ddsi2/code/ddsi_tran.h rename to src/services/ddsi2e/core/ddsi_tran.h index 003752eb0..60bc9157d 100644 --- a/src/services/ddsi2/code/ddsi_tran.h +++ b/src/services/ddsi2e/core/ddsi_tran.h @@ -1,18 +1,16 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * @@ -202,5 +200,3 @@ void ddsi_listener_unblock (ddsi_tran_listener_t listener); void ddsi_listener_free (ddsi_tran_listener_t listener); #undef OS_API #endif - -/* SHA1 not available (unoffical build.) */ diff --git a/src/services/ddsi2/code/ddsi_udp.c b/src/services/ddsi2e/core/ddsi_udp.c similarity index 89% rename from src/services/ddsi2/code/ddsi_udp.c rename to src/services/ddsi2e/core/ddsi_udp.c index c1a90915d..09f317d3c 100644 --- a/src/services/ddsi2/code/ddsi_udp.c +++ b/src/services/ddsi2e/core/ddsi_udp.c @@ -1,18 +1,16 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * @@ -25,6 +23,7 @@ #include "q_log.h" #include "q_pcap.h" #include "os_errno.h" +#include "os_atomics.h" extern void ddsi_factory_conn_init (ddsi_tran_factory_t factory, ddsi_tran_conn_t conn); @@ -49,6 +48,7 @@ typedef struct ddsi_udp_conn static struct ddsi_udp_config ddsi_udp_config_g; static struct ddsi_tran_factory ddsi_udp_factory_g; +static pa_uint32_t init_g = PA_UINT32_INIT(0); static os_ssize_t ddsi_udp_conn_read (ddsi_tran_conn_t conn, unsigned char * buf, os_size_t len) { @@ -239,6 +239,12 @@ static ddsi_tran_conn_t ddsi_udp_create_conn uc->m_sock, uc->m_base.m_base.m_port ); +#ifdef DDSI_INCLUDE_NETWORK_CHANNELS + if ((uc->m_diffserv != 0) && (ddsi_udp_factory_g.m_kind == NN_LOCATOR_KIND_UDPv4)) + { + set_socket_diffserv (uc->m_sock, uc->m_diffserv); + } +#endif } else { @@ -296,10 +302,7 @@ static void ddsi_udp_release_conn (ddsi_tran_conn_t conn) int ddsi_udp_init (void) { - static c_bool init = FALSE; - if (! init) - { - init = TRUE; + if (pa_inc32_nv(&init_g) == 1) { memset (&ddsi_udp_factory_g, 0, sizeof (ddsi_udp_factory_g)); ddsi_udp_factory_g.m_kind = NN_LOCATOR_KIND_UDPv4; ddsi_udp_factory_g.m_typename = "udp"; @@ -315,7 +318,6 @@ int ddsi_udp_init (void) ddsi_udp_factory_g.m_kind = NN_LOCATOR_KIND_UDPv6; } #endif - ddsi_factory_add (&ddsi_udp_factory_g); ddsi_udp_config_g.mship = new_group_membership(); @@ -325,4 +327,11 @@ int ddsi_udp_init (void) return 0; } -/* SHA1 not available (unoffical build.) */ +void ddsi_udp_deinit(void) +{ + if (pa_dec32_nv(&init_g) == 0) { + if (ddsi_udp_config_g.mship) + free_group_membership(ddsi_udp_config_g.mship); + nn_log (LC_INFO | LC_CONFIG, "udp de-initialized\n"); + } +} diff --git a/src/services/ddsi2e/core/ddsi_udp.h b/src/services/ddsi2e/core/ddsi_udp.h new file mode 100644 index 000000000..a9f36591d --- /dev/null +++ b/src/services/ddsi2e/core/ddsi_udp.h @@ -0,0 +1,24 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#ifndef _DDSI_UDP_H_ +#define _DDSI_UDP_H_ + +int ddsi_udp_init (void); +void ddsi_udp_deinit(void); + +#endif diff --git a/src/services/ddsi2/code/q_addrset.c b/src/services/ddsi2e/core/q_addrset.c similarity index 81% rename from src/services/ddsi2/code/q_addrset.c rename to src/services/ddsi2e/core/q_addrset.c index 412b6fce0..76788bbae 100644 --- a/src/services/ddsi2/code/q_addrset.c +++ b/src/services/ddsi2e/core/q_addrset.c @@ -1,18 +1,16 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * @@ -251,6 +249,82 @@ int is_unspec_locator (const nn_locator_t *loc) memcmp (&zloc.address, loc->address, sizeof (zloc.address)) == 0); } +#ifdef DDSI_INCLUDE_SSM +int is_ssm_mcaddr (const nn_locator_t *loc) +{ + os_sockaddr_storage tmp; + nn_loc_to_address (&tmp, loc); + switch (loc->kind) + { + case NN_LOCATOR_KIND_UDPv4: { + const os_sockaddr_in *x = (const os_sockaddr_in *) &tmp; + return (((os_uint32) ntohl (x->sin_addr.s_addr)) >> 24) == 232; + } +#if OS_SOCKET_HAS_IPV6 + case NN_LOCATOR_KIND_UDPv6: { + const os_sockaddr_in6 *x = (const os_sockaddr_in6 *) &tmp; + return x->sin6_addr.s6_addr[0] == 0xff && (x->sin6_addr.s6_addr[1] & 0xf0) == 0x30; + } +#endif + default: { + return 0; + } + } +} + +int addrset_contains_ssm (const struct addrset *as) +{ + struct addrset_node *n; + ut_avlCIter_t it; + LOCK (as); + for (n = ut_avlCIterFirst (&addrset_treedef, &as->mcaddrs, &it); n; n = ut_avlCIterNext (&it)) + { + if (is_ssm_mcaddr (&n->loc)) + { + UNLOCK (as); + return 1; + } + } + UNLOCK (as); + return 0; +} + +int addrset_any_ssm (const struct addrset *as, nn_locator_t *dst) +{ + struct addrset_node *n; + ut_avlCIter_t it; + LOCK (as); + for (n = ut_avlCIterFirst (&addrset_treedef, &as->mcaddrs, &it); n; n = ut_avlCIterNext (&it)) + { + if (is_ssm_mcaddr (&n->loc)) + { + *dst = n->loc; + UNLOCK (as); + return 1; + } + } + UNLOCK (as); + return 0; +} + +int addrset_any_non_ssm_mc (const struct addrset *as, nn_locator_t *dst) +{ + struct addrset_node *n; + ut_avlCIter_t it; + LOCK (as); + for (n = ut_avlCIterFirst (&addrset_treedef, &as->mcaddrs, &it); n; n = ut_avlCIterNext (&it)) + { + if (!is_ssm_mcaddr (&n->loc)) + { + *dst = n->loc; + UNLOCK (as); + return 1; + } + } + UNLOCK (as); + return 0; +} +#endif int addrset_purge (struct addrset *as) { @@ -318,6 +392,45 @@ void copy_addrset_into_addrset (struct addrset *as, const struct addrset *asadd) copy_addrset_into_addrset_mc (as, asadd); } +#ifdef DDSI_INCLUDE_SSM +void copy_addrset_into_addrset_no_ssm_mc (struct addrset *as, const struct addrset *asadd) +{ + struct addrset_node *n; + ut_avlCIter_t it; + LOCK (asadd); + for (n = ut_avlCIterFirst (&addrset_treedef, &asadd->mcaddrs, &it); n; n = ut_avlCIterNext (&it)) + { + if (!is_ssm_mcaddr (&n->loc)) + add_to_addrset (as, &n->loc); + } + UNLOCK (asadd); + +} + +void copy_addrset_into_addrset_no_ssm (struct addrset *as, const struct addrset *asadd) +{ + copy_addrset_into_addrset_uc (as, asadd); + copy_addrset_into_addrset_no_ssm_mc (as, asadd); +} + +void addrset_purge_ssm (struct addrset *as) +{ + struct addrset_node *n; + LOCK (as); + n = ut_avlCFindMin (&addrset_treedef, &as->mcaddrs); + while (n) + { + struct addrset_node *n1 = n; + n = ut_avlCFindSucc (&addrset_treedef, &as->mcaddrs, n); + if (is_ssm_mcaddr (&n1->loc)) + { + ut_avlCDelete (&addrset_treedef, &as->mcaddrs, n1); + os_free (n1); + } + } + UNLOCK (as); +} +#endif os_size_t addrset_count (const struct addrset *as) { @@ -529,5 +642,3 @@ int addrset_eq_onesidederr (const struct addrset *a, const struct addrset *b) UNLOCK (a); return iseq; } - -/* SHA1 not available (unoffical build.) */ diff --git a/src/services/ddsi2e/core/q_addrset.h b/src/services/ddsi2e/core/q_addrset.h new file mode 100644 index 000000000..0b9018560 --- /dev/null +++ b/src/services/ddsi2e/core/q_addrset.h @@ -0,0 +1,98 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#ifndef NN_ADDRSET_H +#define NN_ADDRSET_H + +#include "os_mutex.h" +#include "os_socket.h" + +#include "ut_avl.h" +#include "q_log.h" +#include "q_protocol.h" +#include "q_feature_check.h" + +#if defined (__cplusplus) +extern "C" { +#endif + +typedef struct addrset_node { + ut_avlNode_t avlnode; + nn_locator_t loc; +} * addrset_node_t; + +struct addrset { + os_mutex lock; + pa_uint32_t refc; + ut_avlCTree_t ucaddrs, mcaddrs; +}; + +typedef void (*addrset_forall_fun_t) (const nn_locator_t *loc, void *arg); +typedef os_ssize_t (*addrset_forone_fun_t) (const nn_locator_t *loc, void *arg); + +struct addrset *new_addrset (void); +struct addrset *ref_addrset (struct addrset *as); +void unref_addrset (struct addrset *as); +void add_to_addrset (struct addrset *as, const nn_locator_t *loc); +void remove_from_addrset (struct addrset *as, const nn_locator_t *loc); +int addrset_purge (struct addrset *as); +int compare_locators (const nn_locator_t *a, const nn_locator_t *b); + +/* These lock ASADD, then lock/unlock AS any number of times, then + unlock ASADD */ +void copy_addrset_into_addrset_uc (struct addrset *as, const struct addrset *asadd); +void copy_addrset_into_addrset_mc (struct addrset *as, const struct addrset *asadd); +void copy_addrset_into_addrset (struct addrset *as, const struct addrset *asadd); + +os_size_t addrset_count (const struct addrset *as); +os_size_t addrset_count_uc (const struct addrset *as); +int addrset_empty_uc (const struct addrset *as); +int addrset_empty_mc (const struct addrset *as); +int addrset_empty (const struct addrset *as); +int addrset_any_uc (const struct addrset *as, nn_locator_t *dst); +int addrset_any_mc (const struct addrset *as, nn_locator_t *dst); + +/* Keeps AS locked */ +int addrset_forone (struct addrset *as, addrset_forone_fun_t f, void *arg); +void addrset_forall (struct addrset *as, addrset_forall_fun_t f, void *arg); +os_size_t addrset_forall_count (struct addrset *as, addrset_forall_fun_t f, void *arg); +void nn_log_addrset (logcat_t tf, const char *prefix, const struct addrset *as); + +/* Tries to lock A then B for a decent check, returning false if + trylock B fails */ +int addrset_eq_onesidederr (const struct addrset *a, const struct addrset *b); + +int is_mcaddr (const nn_locator_t *loc); +int is_unspec_locator (const nn_locator_t *loc); +void set_unspec_locator (nn_locator_t *loc); + +int add_addresses_to_addrset (struct addrset *as, const char *addrs, int port_mode, const char *msgtag, int req_mc); + +#ifdef DDSI_INCLUDE_SSM +int is_ssm_mcaddr (const nn_locator_t *loc); +int addrset_contains_ssm (const struct addrset *as); +int addrset_any_ssm (const struct addrset *as, nn_locator_t *dst); +int addrset_any_non_ssm_mc (const struct addrset *as, nn_locator_t *dst); +void copy_addrset_into_addrset_no_ssm_mc (struct addrset *as, const struct addrset *asadd); +void copy_addrset_into_addrset_no_ssm (struct addrset *as, const struct addrset *asadd); +void addrset_pruge_ssm (struct addrset *as); +#endif + +#if defined (__cplusplus) +} +#endif +#endif /* NN_ADDRSET_H */ diff --git a/src/services/ddsi2e/core/q_align.h b/src/services/ddsi2e/core/q_align.h new file mode 100644 index 000000000..ed080fe6c --- /dev/null +++ b/src/services/ddsi2e/core/q_align.h @@ -0,0 +1,24 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#ifndef NN_ALIGN_H +#define NN_ALIGN_H + +#define ALIGN4(x) (((x) + 3) & -4u) +#define ALIGN8(x) (((x) + 7) & -8u) + +#endif /* NN_ALIGN_H */ diff --git a/src/services/ddsi2e/core/q_bitset.h b/src/services/ddsi2e/core/q_bitset.h new file mode 100644 index 000000000..50128c9d7 --- /dev/null +++ b/src/services/ddsi2e/core/q_bitset.h @@ -0,0 +1,42 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#ifndef NN_BITSET_H +#define NN_BITSET_H + +#include +#include + +#include "q_inline.h" + +#if NN_HAVE_C99_INLINE && !defined SUPPRESS_BITSET_INLINES +#include "q_bitset_template.c" +#else +#if defined (__cplusplus) +extern "C" { +#endif +int nn_bitset_isset (unsigned numbits, const unsigned *bits, unsigned idx); +void nn_bitset_set (unsigned numbits, unsigned *bits, unsigned idx); +void nn_bitset_clear (unsigned numbits, unsigned *bits, unsigned idx); +void nn_bitset_zero (unsigned numbits, unsigned *bits); +void nn_bitset_one (unsigned numbits, unsigned *bits); +#if defined (__cplusplus) +} +#endif +#endif + +#endif /* NN_BITSET_H */ diff --git a/src/services/ddsi2e/core/q_bitset_inlines.c b/src/services/ddsi2e/core/q_bitset_inlines.c new file mode 100644 index 000000000..65b5f3d34 --- /dev/null +++ b/src/services/ddsi2e/core/q_bitset_inlines.c @@ -0,0 +1,22 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#define SUPPRESS_BITSET_INLINES + +#include "q_bitset.h" +#include "q_bitset_template.c" + diff --git a/src/services/ddsi2e/core/q_bitset_template.c b/src/services/ddsi2e/core/q_bitset_template.c new file mode 100644 index 000000000..acd46a2f1 --- /dev/null +++ b/src/services/ddsi2e/core/q_bitset_template.c @@ -0,0 +1,59 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +/* -*- c -*- */ + +#include "q_unused.h" + +#if defined SUPPRESS_BITSET_INLINES && defined NN_C99_INLINE +#undef NN_C99_INLINE +#define NN_C99_INLINE +#endif + +NN_C99_INLINE int nn_bitset_isset (unsigned numbits, const unsigned *bits, unsigned idx) +{ + return idx < numbits && (bits[idx/32] & (1u << (31 - (idx%32)))); +} + +NN_C99_INLINE void nn_bitset_set (UNUSED_ARG_NDEBUG (unsigned numbits), unsigned *bits, unsigned idx) +{ + assert (idx < numbits); + bits[idx/32] |= 1u << (31 - (idx%32)); +} + +NN_C99_INLINE void nn_bitset_clear (UNUSED_ARG_NDEBUG (unsigned numbits), unsigned *bits, unsigned idx) +{ + assert (idx < numbits); + bits[idx/32] &= ~(1u << (31 - (idx%32))); +} + +NN_C99_INLINE void nn_bitset_zero (unsigned numbits, unsigned *bits) +{ + memset (bits, 0, 4 * ((numbits + 31) / 32)); +} + +NN_C99_INLINE void nn_bitset_one (unsigned numbits, unsigned *bits) +{ + memset (bits, 0xff, 4 * ((numbits + 31) / 32)); + + /* clear bits "accidentally" set */ + { + const unsigned k = numbits / 32; + const unsigned n = numbits % 32; + bits[k] &= ~(~0u >> n); + } +} diff --git a/src/services/ddsi2e/core/q_bswap.c b/src/services/ddsi2e/core/q_bswap.c new file mode 100644 index 000000000..fba089511 --- /dev/null +++ b/src/services/ddsi2e/core/q_bswap.c @@ -0,0 +1,86 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#include "q_bswap.h" + +nn_guid_prefix_t nn_hton_guid_prefix (nn_guid_prefix_t p) +{ + int i; + for (i = 0; i < 3; i++) + p.u[i] = toBE4u (p.u[i]); + return p; +} + +nn_guid_prefix_t nn_ntoh_guid_prefix (nn_guid_prefix_t p) +{ + int i; + for (i = 0; i < 3; i++) + p.u[i] = fromBE4u (p.u[i]); + return p; +} + +nn_entityid_t nn_hton_entityid (nn_entityid_t e) +{ + e.u = toBE4u (e.u); + return e; +} + +nn_entityid_t nn_ntoh_entityid (nn_entityid_t e) +{ + e.u = fromBE4u (e.u); + return e; +} + +nn_guid_t nn_hton_guid (nn_guid_t g) +{ + g.prefix = nn_hton_guid_prefix (g.prefix); + g.entityid = nn_hton_entityid (g.entityid); + return g; +} + +nn_guid_t nn_ntoh_guid (nn_guid_t g) +{ + g.prefix = nn_ntoh_guid_prefix (g.prefix); + g.entityid = nn_ntoh_entityid (g.entityid); + return g; +} + +void bswap_sequence_number_set_hdr (nn_sequence_number_set_t *snset) +{ + bswapSN (&snset->bitmap_base); + snset->numbits = bswap4u (snset->numbits); +} + +void bswap_sequence_number_set_bitmap (nn_sequence_number_set_t *snset) +{ + unsigned i, n = (snset->numbits + 31) / 32; + for (i = 0; i < n; i++) + snset->bits[i] = bswap4u (snset->bits[i]); +} + +void bswap_fragment_number_set_hdr (nn_fragment_number_set_t *fnset) +{ + fnset->bitmap_base = bswap4u (fnset->bitmap_base); + fnset->numbits = bswap4u (fnset->numbits); +} + +void bswap_fragment_number_set_bitmap (nn_fragment_number_set_t *fnset) +{ + unsigned i, n = (fnset->numbits + 31) / 32; + for (i = 0; i < n; i++) + fnset->bits[i] = bswap4u (fnset->bits[i]); +} diff --git a/src/services/ddsi2/code/q_bswap.h b/src/services/ddsi2e/core/q_bswap.h similarity index 78% rename from src/services/ddsi2/code/q_bswap.h rename to src/services/ddsi2e/core/q_bswap.h index 2767647cf..7f3bb1e0b 100644 --- a/src/services/ddsi2/code/q_bswap.h +++ b/src/services/ddsi2e/core/q_bswap.h @@ -1,18 +1,16 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * @@ -93,5 +91,3 @@ void bswap_fragment_number_set_bitmap (nn_fragment_number_set_t *fnset); #endif #endif /* NN_BSWAP_H */ - -/* SHA1 not available (unoffical build.) */ diff --git a/src/services/ddsi2e/core/q_bswap_inlines.c b/src/services/ddsi2e/core/q_bswap_inlines.c new file mode 100644 index 000000000..da4047639 --- /dev/null +++ b/src/services/ddsi2e/core/q_bswap_inlines.c @@ -0,0 +1,21 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#define SUPPRESS_BSWAP_INLINES + +#include "q_bswap.h" +#include "q_bswap_template.c" diff --git a/src/services/ddsi2e/core/q_bswap_template.c b/src/services/ddsi2e/core/q_bswap_template.c new file mode 100644 index 000000000..c999e75d5 --- /dev/null +++ b/src/services/ddsi2e/core/q_bswap_template.c @@ -0,0 +1,47 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +/* -*- c -*- */ + +#if defined SUPPRESS_BSWAP_INLINES && defined NN_C99_INLINE +#undef NN_C99_INLINE +#define NN_C99_INLINE +#endif + +NN_C99_INLINE unsigned short bswap2u (unsigned short x) +{ + return (unsigned short) ((x >> 8) | (x << 8)); +} + +NN_C99_INLINE unsigned bswap4u (unsigned x) +{ + return (x >> 24) | ((x >> 8) & 0xff00) | ((x << 8) & 0xff0000) | (x << 24); +} + +NN_C99_INLINE unsigned long long bswap8u (unsigned long long x) +{ + const unsigned newhi = bswap4u ((unsigned) x); + const unsigned newlo = bswap4u ((unsigned) (x >> 32)); + return ((unsigned long long) newhi << 32) | (unsigned long long) newlo; +} + +NN_C99_INLINE void bswapSN (nn_sequence_number_t *sn) +{ + sn->high = bswap4 (sn->high); + sn->low = bswap4u (sn->low); +} + diff --git a/src/services/ddsi2e/core/q_builtin_topic.h b/src/services/ddsi2e/core/q_builtin_topic.h new file mode 100644 index 000000000..a98c33ba9 --- /dev/null +++ b/src/services/ddsi2e/core/q_builtin_topic.h @@ -0,0 +1,49 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#ifndef Q_BUILTIN_TOPIC_H +#define Q_BUILTIN_TOPIC_H + +struct proxy_participant; +struct proxy_writer; +struct proxy_reader; + +struct nn_plist; + +/* Functions called at proxy entity creation/deletion time, so they + can do whatever is necessary to get the builtin topics function + correctly. + + These probably should return an error code, but I don't quite know + how to handle it yet and this way we have Coverity on our side. + Implementation is outside the common core. + + These may assume the proxy entities are stable, without parallel QoS + changes. */ +void write_builtin_topic_proxy_participant (const struct proxy_participant *proxypp, nn_wctime_t timestamp); +void write_builtin_topic_proxy_participant_cm (const struct proxy_participant *proxypp, nn_wctime_t timestamp); +void dispose_builtin_topic_proxy_participant (const struct proxy_participant *proxypp, nn_wctime_t timestamp, int isimplicit); +void write_builtin_topic_proxy_writer (const struct proxy_writer *pwr, nn_wctime_t timestamp); +void dispose_builtin_topic_proxy_writer (const struct proxy_writer *pwr, nn_wctime_t timestamp, int isimplicit); +void write_builtin_topic_proxy_reader (const struct proxy_reader *prd, nn_wctime_t timestamp); +void dispose_builtin_topic_proxy_reader (const struct proxy_reader *prd, nn_wctime_t timestamp, int isimplicit); +void write_builtin_topic_proxy_group (const struct proxy_group *pgroup, nn_wctime_t timestamp); +void dispose_builtin_topic_proxy_group (const struct proxy_group *pgroup, nn_wctime_t timestamp, int isimplicit); + +void write_builtin_topic_proxy_topic (const struct nn_plist *datap, nn_wctime_t timestamp); + +#endif diff --git a/src/services/ddsi2e/core/q_config.c b/src/services/ddsi2e/core/q_config.c new file mode 100644 index 000000000..16153afbe --- /dev/null +++ b/src/services/ddsi2e/core/q_config.c @@ -0,0 +1,3357 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#include +#include +#include +#include +#include +#include + +#include "os_stdlib.h" +#include "os_socket.h" +#include "os_heap.h" + +#if !LITE +#include "ut_crc.h" +#include "u_participant.h" +#include "u_cfElement.h" +#include "u_cfData.h" +#include "u_cfNode.h" +#endif + +#include "q_config.h" +#include "q_log.h" +#include "ut_avl.h" +#include "q_unused.h" +#include "q_misc.h" +#include "q_addrset.h" +#include "q_nwif.h" +#include "q_error.h" +#include "sysdeps.h" + +#if LITE +#include "qhxml.h" +#endif + +#define WARN_DEPRECATED_ALIAS 1 +#define WARN_DEPRECATED_UNIT 1 +#define MAX_PATH_DEPTH 10 /* max nesting level of configuration elements */ + +struct cfgelem; +struct cfgst; + +typedef int (*init_fun_t) (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem); +typedef int (*update_fun_t) (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int first, const char *value); +typedef void (*free_fun_t) (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem); +typedef void (*print_fun_t) (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int is_default); + +#ifdef DDSI_INCLUDE_SECURITY +struct q_security_plugins q_security_plugin = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; +#endif + +struct unit { + const char *name; + os_int64 multiplier; +}; + +struct cfgelem { + const char *name; + const struct cfgelem *children; + const struct cfgelem *attributes; + int multiplicity; + const char *defvalue; /* NULL -> no default */ + int relative_offset; + int elem_offset; + init_fun_t init; + update_fun_t update; + free_fun_t free; + print_fun_t print; + const char *description; +}; + +struct cfgst_nodekey { + const struct cfgelem *e; +}; + +struct cfgst_node { + ut_avlNode_t avlnode; + struct cfgst_nodekey key; + int count; + int failed; + int is_default; +}; + +struct cfgst { + ut_avlTree_t found; + struct config *cfg; + +#if !LITE + /* Servicename is used by uf_service_name to use as a default value + when the supplied string is empty, which happens when the service + is started without a DDSI2EService configuration item, i.e. when + everything is left at the default. */ + const char *servicename; +#endif + + /* path_depth, isattr and path together control the formatting of + error messages by cfg_error() */ + int path_depth; + int isattr[MAX_PATH_DEPTH]; + const struct cfgelem *path[MAX_PATH_DEPTH]; + void *parent[MAX_PATH_DEPTH]; +}; + +/* "trace" is special: it enables (nearly) everything */ +static const char *logcat_names[] = { + "fatal", "error", "warning", "config", "info", "discovery", "data", "radmin", "timing", "traffic", "topic", "tcp", "plist", "whc", "throttle", "trace", NULL +}; +static const logcat_t logcat_codes[] = { + LC_FATAL, LC_ERROR, LC_WARNING, LC_CONFIG, LC_INFO, LC_DISCOVERY, LC_DATA, LC_RADMIN, LC_TIMING, LC_TRAFFIC, LC_TOPIC, LC_TCP, LC_PLIST, LC_WHC, LC_THROTTLE, LC_ALLCATS +}; + +/* We want the tracing/verbosity settings to be fixed while parsing + the configuration, so we update this variable instead. */ +static unsigned enabled_logcats; + +static int cfgst_node_cmp (const void *va, const void *vb); +static const ut_avlTreedef_t cfgst_found_treedef = + UT_AVL_TREEDEF_INITIALIZER (offsetof (struct cfgst_node, avlnode), offsetof (struct cfgst_node, key), cfgst_node_cmp, 0); + +#define DU(fname) static int fname (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int first, const char *value) +DU (uf_networkAddress); +DU (uf_networkAddresses); +DU (uf_ipv4); +DU (uf_allow_multicast); +DU (uf_boolean); +DU (uf_negated_boolean); +DU (uf_string); +DU (uf_tracingOutputFileName); +DU (uf_verbosity); +DU (uf_logcat); +DU (uf_float); +DU (uf_int); +DU (uf_uint); +DU (uf_int32); +DU (uf_uint32); +DU (uf_natint); +DU (uf_natint_255); +DU (uf_participantIndex); +DU (uf_port); +DU (uf_dyn_port); +DU (uf_memsize); +DU (uf_duration_inf); +DU (uf_duration_ms_1hr); +DU (uf_duration_ms_1s); +DU (uf_duration_us_1s); +DU (uf_standards_conformance); +DU (uf_besmode); +DU (uf_retransmit_merging); +DU (uf_sched_prio_class); +DU (uf_sched_class); +DU (uf_maybe_memsize); +DU (uf_maybe_int32); +#ifdef DDSI_INCLUDE_ENCRYPTION +DU (uf_cipher); +#endif +#ifdef DDSI_INCLUDE_BANDWIDTH_LIMITING +DU (uf_bandwidth); +#endif +DU (uf_domainId); +#if !LITE +DU (uf_maybe_duration_inf); +DU (uf_service_name); +DU (uf_boolean_default); +#endif +#if LITE +DU (uf_durability_cdr); +#endif +#undef DU + +#define DF(fname) static void fname (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem) +DF (ff_free); +DF (ff_networkAddresses); +#undef DF + +#define DI(fname) static int fname (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem) +#ifdef DDSI_INCLUDE_NETWORK_CHANNELS +DI (if_channel); +#endif /* DDSI_INCLUDE_NETWORK_CHANNELS */ +#ifdef DDSI_INCLUDE_ENCRYPTION +DI (if_security_profile); +#endif +#ifdef DDSI_INCLUDE_NETWORK_PARTITIONS +DI (if_network_partition); +DI (if_ignored_partition); +DI (if_partition_mapping); +#endif +DI (if_peer); +DI (if_thread_properties); +#undef DI + +#define PF(fname) static void fname (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int is_default) +PF (pf_nop); +PF (pf_string); +PF (pf_networkAddress); +PF (pf_participantIndex); +PF (pf_networkAddresses); +PF (pf_memsize); +PF (pf_duration); +PF (pf_int); +PF (pf_uint); +PF (pf_int32); +PF (pf_uint32); +PF (pf_float); +PF (pf_allow_multicast); +PF (pf_boolean); +PF (pf_negated_boolean); +PF (pf_logcat); +PF (pf_standards_conformance); +PF (pf_besmode); +PF (pf_retransmit_merging); +PF (pf_sched_prio_class); +PF (pf_sched_class); +PF (pf_maybe_memsize); +PF (pf_maybe_int32); +#if ! LITE +PF (pf_maybe_duration); +PF (pf_boolean_default); +#endif +#if LITE +PF (pf_durability_cdr); +#endif +#ifdef DDSI_INCLUDE_ENCRYPTION +PF (pf_cipher); +PF (pf_key); +#endif +#ifdef DDSI_INCLUDE_BANDWIDTH_LIMITING +PF (pf_bandwidth); +#endif +#undef PF + +#define CO(name) ((int) offsetof (struct config, name)) +#define ABSOFF(name) 0, CO (name) +#define RELOFF(parent,name) 1, ((int) offsetof (struct parent, name)) +#define NODATA 1, NULL, 0, 0, 0, 0, 0, 0 +#define END_MARKER { NULL, NULL, NULL, NODATA, NULL } +#define WILDCARD { "*", NULL, NULL, NODATA, NULL } +#define LEAF(name) name, NULL, NULL +#define LEAF_W_ATTRS(name, attrs) name, NULL, attrs +#define GROUP(name, children) name, children, NULL, 1, NULL, 0, 0, 0, 0, 0, 0 +#define MGROUP(name, children, attrs) name, children, attrs +#define ATTR(name) name, NULL, NULL +/* MOVED: whereto must be a path relative to DDSI2EService, may not be used in/for lists and only for elements, may not be chained */ +#define MOVED(name, whereto) ">" name, NULL, NULL, 0, whereto, 0, 0, 0, 0, 0, 0, NULL +static const struct cfgelem timestamp_cfgattrs[] = { + { ATTR ("absolute"), 1, "false", ABSOFF (tracingRelativeTimestamps), 0, uf_negated_boolean, 0, pf_negated_boolean, + "

    This option has no effect

    " }, + END_MARKER +}; + +static const struct cfgelem general_cfgelems[] = { + { LEAF ("NetworkInterfaceAddress"), 1, "auto", ABSOFF (networkAddressString), 0, uf_networkAddress, ff_free, pf_networkAddress, + "

    This element specifies the preferred network interface for use by DDSI2E. The preferred network interface determines the IP address that DDSI2E advertises in the discovery protocol (but see also General/ExternalNetworkAddress), and is also the only interface over which multicasts are transmitted. The interface can be identified by its IP address, network interface name or network portion of the address. If the value \"auto\" is entered here, DDSI2E will select what it considers the most suitable interface.

    " }, + { LEAF ("MulticastRecvNetworkInterfaceAddresses"), 1, "preferred", ABSOFF (networkRecvAddressStrings), 0, uf_networkAddresses, ff_networkAddresses, pf_networkAddresses, + "

    This element specifies on which network interfaces DDSI2E listens to multicasts. The following options are available:

    \n\ +
      \n\ +
    • all: listen for multicasts on all multicast-capable interfaces; or
    • \n\ +
    • any: listen for multicasts on the operating system default interface; or
    • \n\ +
    • preferred: listen for multicasts on the preferred interface (General/NetworkInterfaceAddress); or
    • \n\ +
    • none: does not listen for multicasts on any interface; or
    • \n\ +
    • a comma-separated list of network addresses: configures DDSI2E to listen for multicasts on all of the listed addresses.
    • \n\ +
    \n\ +

    If DDSI2E is in IPv6 mode and the address of the preferred network interface is a link-local address, \"all\" is treated as a synonym for \"preferred\" and a comma-separated list is treated as \"preferred\" if it contains the preferred interface and as \"none\" if not.

    " }, + { LEAF ("ExternalNetworkAddress"), 1, "auto", ABSOFF (externalAddressString), 0, uf_networkAddress, ff_free, pf_networkAddress, + "

    This element allows explicitly overruling the network address DDSI2E advertises in the discovery protocol, which by default is the address of the preferred network interface (General/NetworkInterfaceAddress), to allow DDSI2E to communicate across a Network Address Translation (NAT) device.

    " }, + { LEAF ("ExternalNetworkMask"), 1, "0.0.0.0", ABSOFF (externalMaskString), 0, uf_string, ff_free, pf_string, + "

    This element specifies the network mask of the external network address. This element is relevant only when an external network address (General/ExternalNetworkAddress) is explicitly configured. In this case locators received via the discovery protocol that are within the same external subnet (as defined by this mask) will be translated to an internal address by replacing the network portion of the external address with the corresponding portion of the preferred network interface address. This option is IPv4-only.

    " }, + { LEAF ("AllowMulticast"), 1, "true", ABSOFF (allowMulticast), 0, uf_allow_multicast, 0, pf_allow_multicast, + "

    This element controls whether DDSI2E uses multicasts for data traffic.

    \n\ +

    It is a comma-separated list of some of the following keywords: \"spdp\", \"asm\", \"ssm\", or either of \"false\" or \"true\".

    \n\ +
      \n\ +
    • spdp: enables the use of ASM (any-source multicast) for participant discovery
    • \n\ +
    • asm: enables the use of ASM for all traffic (including SPDP)
    • \n\ +
    • ssm: enables the use of SSM (source-specific multicast) for all non-SPDP traffic (if supported)
    • \n\ +
    \n\ +

    When set to \"false\" all multicasting is disabled. The default, \"true\" enables full use of multicasts. Listening for multicasts can be controlled by General/MulticastRecvNetworkInterfaceAddresses.

    " }, + { LEAF ("MulticastTimeToLive"), 1, "32", ABSOFF (multicast_ttl), 0, uf_natint_255, 0, pf_int, + "

    This element specifies the time-to-live setting for outgoing multicast packets.

    " }, + { LEAF ("DontRoute"), 1, "false", ABSOFF (dontRoute), 0, uf_boolean, 0, pf_boolean, + "

    This element allows setting the SO_DONTROUTE option for outgoing packets, to bypass the local routing tables. This is generally useful only when the routing tables cannot be trusted, which is highly unusual.

    " }, + { LEAF ("UseIPv6"), 1, "false", ABSOFF (useIpv6), 0, uf_boolean, 0, pf_boolean , + "

    This element can be used to DDSI2E use IPv6 instead of IPv4. This is currently an either/or switch.

    " }, + { LEAF ("EnableMulticastLoopback"), 1, "true", ABSOFF (enableMulticastLoopback), 0, uf_boolean, 0, pf_boolean, + "

    This element specifies whether DDSI2E allows IP multicast packets to be visible to all DDSI participants in the same node, including itself. It must be \"true\" for intra-node multicast communications, but if a node runs only a single DDSI2E service and does not host any other DDSI-capable programs, it should be set to \"false\" for improved performance.

    " }, +#if LITE + { LEAF ("EnableLoopback"), 1, "false", ABSOFF (enableLoopback), 0, uf_boolean, 0, pf_boolean, + "

    This element specifies whether DDSI packets are visible to all DDSI participants in the same process. It must be \"true\" for intra-process communications, i.e. a reader and writer communicating in the same address space. If enabled and using multicast then EnableMulticastLoopback must also be enabled.

    " }, +#else + { LEAF ("CoexistWithNativeNetworking"), 1, "false", ABSOFF (coexistWithNativeNetworking), 0, uf_boolean, 0, pf_boolean, + "

    This element specifies whether the DDSI2E service operates in conjunction with the OpenSplice RT Networking service. When \"false\", the DDSI2E service will take care of all communications, including those between OpenSplice nodes; when \"true\", the DDSI2E service only communicates with DDS implementations other than OpenSplice. In this case the RT Networking service should be configured as well.

    " }, +#endif + { LEAF ("StartupModeDuration"), 1, "2 s", ABSOFF (startup_mode_duration), 0, uf_duration_ms_1hr, 0, pf_duration, + "

    This element specifies how long the DDSI2E remains in its \"startup\" mode. While in \"startup\" mode all volatile reliable data published on the local node is retained as-if it were transient-local data, allowing existing readers on remote nodes to obtain the data even though discovering them takes some time. Best-effort data by definition need not arrive, and transient and persistent data are covered by the durability service.

    \n\ +

    Once the system is stable, DDSI2E keeps track of the existence of remote readers whether or not matching writers exist locally, avoiding this discovery delay and ensuring this is merely a node startup issue.

    \n\ +

    Setting General/StartupModeDuration to 0s will disable it.

    " }, + { LEAF ("StartupModeCoversTransient"), 1, "true", ABSOFF (startup_mode_full), 0, uf_boolean, 0, pf_boolean, + "

    This element configures whether startup-mode should also cover transient and persistent data, for configurations where the durability service does not take care of it. Configurations without defined merge policies best leave this enabled.

    " }, + { LEAF ("MaxMessageSize"), 1, "4096 B", ABSOFF (max_msg_size), 0, uf_memsize, 0, pf_memsize, + "

    This element specifies the maximum size of the UDP payload that DDSI2E will generate. DDSI2E will try to maintain this limit within the bounds of the DDSI specification, which means that in some cases (especially for very low values of MaxMessageSize) larger payloads may sporadically be observed (currently up to 1192 B).

    \n\ +

    On some networks it may be necessary to set this item to keep the packetsize below the MTU to prevent IP fragmentation. In those cases, it is generally advisable to also consider reducing Internal/FragmentSize.

    " }, + { LEAF ("FragmentSize"), 1, "1280 B", ABSOFF (fragment_size), 0, uf_memsize, 0, pf_memsize, + "

    This element specifies the size of DDSI sample fragments generated by DDSI2E. Samples larger than FragmentSize are fragmented into fragments of FragmentSize bytes each, except the last one, which may be smaller. The DDSI spec mandates a minimum fragment size of 1025 bytes, but DDSI2E will do whatever size is requested, accepting fragments of which the size is at least the minimum of 1025 and FragmentSize.

    " }, + END_MARKER +}; + +#ifdef DDSI_INCLUDE_ENCRYPTION +static const struct cfgelem securityprofile_cfgattrs[] = { + { ATTR ("Name"), 1, NULL, RELOFF (config_securityprofile_listelem, name), 0, uf_string, ff_free, pf_string, + "

    This attribute specifies the name of this DDSI2E security profile. Two security profiles cannot have the same name.

    " }, + { ATTR ("Cipher"), 1, "null", RELOFF (config_securityprofile_listelem, cipher), 0, uf_cipher, 0, pf_cipher, + "

    This attribute specifies the cipher to be used for encrypting traffic over network partitions secured by this security profile. The possible ciphers are:

    \n\ +
    • aes128: AES with a 128-bit key;
    • \n\ +
    • aes192: AES with a 192-bit key;
    • \n\ +
    • aes256: AES with a 256-bit key;
    • \n\ +
    • blowfish: the Blowfish cipher with a 128 bit key;
    • \n\ +
    • null: no encryption;
    \n\ +

    SHA1 is used on conjunction with all ciphers except \"null\" to ensure data integrity.

    " }, + { ATTR ("CipherKey"), 1, "", RELOFF (config_securityprofile_listelem, key), 0, uf_string, ff_free, pf_key, + "

    The CipherKey attribute is used to define the secret key required by the cipher selected using the Cipher attribute. The value can be a URI referencing an external file containing the secret key, or the secret key can be defined in-place as a string value.

    \n\ +

    The key must be specified as a hexadecimal string with each character representing 4 bits of the key. E.g., 1ABC represents the 16-bit key 0001 1010 1011 1100. The key should not follow a well-known pattern and must exactly match the key length of the selected cipher.

    \n\ +

    A malformed key will cause the security profile to be marked as invalid, and disable all network partitions secured by the (invalid) security profile to prevent information leaks.

    \n\ +

    As all DDS applications require read access to the XML configuration file, for security reasons it is recommended to store the secret key in an external file in the file system, referenced by its URI. The file should be protected against read and write access from other users on the host.

    " }, + END_MARKER +}; + +static const struct cfgelem security_cfgelems[] = { + { LEAF_W_ATTRS ("SecurityProfile", securityprofile_cfgattrs), 0, 0, ABSOFF (securityProfiles), if_security_profile, 0, 0, 0, + "

    This element defines a DDSI2E security profile.

    " }, + END_MARKER +}; +#endif /* DDSI_INCLUDE_ENCRYPTION */ + +#ifdef DDSI_INCLUDE_NETWORK_PARTITIONS +static const struct cfgelem networkpartition_cfgattrs[] = { + { ATTR ("Name"), 1, NULL, RELOFF (config_networkpartition_listelem, name), 0, uf_string, ff_free, pf_string, + "

    This attribute specifies the name of this DDSI2E network partition. Two network partitions cannot have the same name.

    " }, + { ATTR ("Address"), 1, NULL, RELOFF (config_networkpartition_listelem, address_string), 0, uf_string, ff_free, pf_string, + "

    This attribute specifies the multicast addresses associated with the network partition as a comma-separated list. Readers matching this network partition (cf. Partitioning/PartitionMappings) will listen for multicasts on all of these addresses and advertise them in the discovery protocol. The writers will select the most suitable address from the addresses advertised by the readers.

    " }, + { ATTR ("Connected"), 1, "true", RELOFF (config_networkpartition_listelem, connected), 0, uf_boolean, 0, pf_boolean, + "

    This attribute is a placeholder.

    " }, +#ifdef DDSI_INCLUDE_ENCRYPTION + { ATTR ("SecurityProfile"), 1, "null", RELOFF (config_networkpartition_listelem, profileName), 0, uf_string, ff_free, pf_string, + "

    This attribute selects the DDSI2E security profile for encrypting the traffic mapped to this DDSI2E network partition. The default \"null\" means the network partition is unsecured; any other name refers to a security profile defined using the Security/SecurityProfile elements.

    " }, +#endif /* DDSI_INCLUDE_ENCRYPTION */ + END_MARKER +}; + +static const struct cfgelem networkpartitions_cfgelems[] = { + { LEAF_W_ATTRS ("NetworkPartition", networkpartition_cfgattrs), 0, 0, ABSOFF (networkPartitions), if_network_partition, 0, 0, 0, + "

    This element defines a DDSI2E network partition.

    " }, + END_MARKER +}; + +static const struct cfgelem ignoredpartitions_cfgattrs[] = { + { ATTR ("DCPSPartitionTopic"), 1, NULL, RELOFF (config_ignoredpartition_listelem, DCPSPartitionTopic), 0, uf_string, ff_free, pf_string, + "

    This attribute specifies a partition and a topic expression, separated by a single '.', that are used to determine if a given partition and topic will be ignored or not. The expressions may use the usual wildcards '*' and '?'. DDSI2E will consider an wildcard DCPS partition to match an expression iff there exists a string that satisfies both expressions.

    " }, + END_MARKER +}; + +static const struct cfgelem ignoredpartitions_cfgelems[] = { + { LEAF_W_ATTRS ("IgnoredPartition", ignoredpartitions_cfgattrs), 0, 0, ABSOFF (ignoredPartitions), if_ignored_partition, 0, 0, 0, + "

    This element can be used to prevent certain combinations of DCPS partition and topic from being transmitted over the network. DDSI2E will complete ignore readers and writers for which all DCPS partitions as well as their topic is ignored, not even creating DDSI readers and writers to mirror the DCPS ones.

    " }, + END_MARKER +}; + +static const struct cfgelem partitionmappings_cfgattrs[] = { + { ATTR ("NetworkPartition"), 1, NULL, RELOFF (config_partitionmapping_listelem, networkPartition), 0, uf_string, ff_free, pf_string, + "

    This attribute specifies which DDSI2E network partition is to be used for DCPS partition/topic combinations matching the DCPSPartitionTopic attribute within this PartitionMapping element.

    " }, + { ATTR ("DCPSPartitionTopic"), 1, NULL, RELOFF (config_partitionmapping_listelem, DCPSPartitionTopic), 0, uf_string, ff_free, pf_string, + "

    This attribute specifies a partition and a topic expression, separated by a single '.', that are used to determine if a given partition and topic maps to the DDSI2E network partition named by the NetworkPartition attribute in this PartitionMapping element. The expressions may use the usual wildcards '*' and '?'. DDSI2E will consider a wildcard DCPS partition to match an expression if there exists a string that satisfies both expressions.

    " }, + END_MARKER +}; + +static const struct cfgelem partitionmappings_cfgelems[] = { + { LEAF_W_ATTRS ("PartitionMapping", partitionmappings_cfgattrs), 0, 0, ABSOFF (partitionMappings), if_partition_mapping, 0, 0, 0, + "

    This element defines a mapping from a DCPS partition/topic combination to a DDSI2E network partition. This allows partitioning data flows by using special multicast addresses for part of the data and possibly also encrypting the data flow.

    " }, + END_MARKER +}; + +static const struct cfgelem partitioning_cfgelems[] = { + { GROUP ("NetworkPartitions", networkpartitions_cfgelems), + "

    The NetworkPartitions element specifies the DDSI2E network partitions.

    " }, + { GROUP ("IgnoredPartitions", ignoredpartitions_cfgelems), + "

    The IgnoredPartitions element specifies DCPS partition/topic combinations that are not distributed over the network.

    " }, + { GROUP ("PartitionMappings", partitionmappings_cfgelems), + "

    The PartitionMappings element specifies the mapping from DCPS partition/topic combinations to DDSI2E network partitions.

    " }, + END_MARKER +}; +#endif /* DDSI_INCLUDE_NETWORK_PARTITIONS */ + +#ifdef DDSI_INCLUDE_NETWORK_CHANNELS +static const struct cfgelem channel_cfgelems[] = { + { LEAF ("QueueSize"), 1, "0", RELOFF (config_channel_listelem, queue_size), 0, uf_natint, 0, pf_int, + "

    This element specifies the number of messages the network queue for this channel can contain. The OpenSplice kernel writes data to be transmitted to the network queue, and DDSI2E takes them from this queue. If this queue is full when an application tries to write a sample, the sample will be dropped or the writer suspended, depending on the QoS settings of the writer. OpenSplice and its services are optimised for a well-balanced system design, where the queue never becomes full.

    " }, +#ifdef DDSI_INCLUDE_BANDWIDTH_LIMITING + { LEAF ("DataBandwidthLimit"), 1, "inf", RELOFF (config_channel_listelem, data_bandwidth_limit), 0, uf_bandwidth, 0, pf_bandwidth, + "

    This element specifies the maximum transmit rate of new samples and directly related data, for this channel. Bandwidth limiting uses a leaky bucket scheme. The default value \"inf\" means DDSI2E imposes no limitation, the underlying operating system and hardware will likely limit the maimum transmit rate.

    " }, + { LEAF ("AuxiliaryBandwidthLimit"), 1, "inf", RELOFF (config_channel_listelem, auxiliary_bandwidth_limit), 0, uf_bandwidth, 0, pf_bandwidth, + "

    This element specifies the maximum transmit rate of auxiliary traffic on this channel (e.g. retransmits, heartbeats, etc). Bandwidth limiting uses a leaky bucket scheme. The default value \"inf\" means DDSI2E imposes no limitation, the underlying operating system and hardware will likely limit the maimum transmit rate.

    " }, +#endif + { LEAF ("DiffServField"), 1, "0", RELOFF (config_channel_listelem, diffserv_field), 0, uf_natint, 0, pf_int, + "

    This element describes the DiffServ setting the channel will apply to the networking messages. This parameter determines the value of the diffserv field of the IP version 4 packets sent on this channel which allows QoS setting to be applied to the network traffic send on this channel.
    \n\ +Windows platform support for setting the diffserv field is dependent on the OS version.
    \n\ +For Windows versions XP SP2 and 2003 to use the diffserv field the following parameter should be added to the register:

    \n\ +HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\TcpIp\\Parameters\\DisableUserTOSSetting

    \n\ +The type of this parameter is a DWORD and its value should be set to 0 to allow setting of the diffserv field.

    \n\ +For Windows version 7 or higher a new API (qWAVE) has been introduced. For these platforms the specified diffserv value is mapped to one of the support traffic types.\n\ +The mapping is as follows: 1-8 background traffic; 9-40 excellent traffic; 41-55 audio/video traffic; 56 voice traffic; 57-63 control traffic.\n\ +When an application is run without Administrative priveleges then only the diffserv value of 0, 8, 40 or 56 is allowed.

    " }, +#if ! LITE + { ATTR ("Resolution"), 1, "1s", RELOFF (config_channel_listelem, resolution), 0, uf_duration_ms_1s, 0, pf_duration, + "

    This element specifies the interval at which the DDSI2E transmit thread for this channel wakes up, and which controls the smallest latency_budget that has an effect. A shorter latency_budget is rounded to 0. The downside of a reducing this setting is that it increases the number of idle wake-ups of the transmit thread when there is no data to be sent.

    " }, +#endif + END_MARKER +}; + +static const struct cfgelem channel_cfgattrs[] = { + { ATTR ("Name"), 1, NULL, RELOFF (config_channel_listelem, name), 0, uf_string, ff_free, pf_string, + "

    This attribute specifies name of this channel. The name should uniquely identify the channel.

    " }, + { ATTR ("TransportPriority"), 1, "0", RELOFF (config_channel_listelem, priority), 0, uf_natint, 0, pf_int, + "

    This attribute sets the transport priority threshold for the channel. Each DCPS data writer has a \"transport_priority\" QoS and this QoS is used to select a channel for use by this writer. The selected channel is the one with the largest threshold not greater than the writer's transport priority, and if no such channel exists, the channel with the lowest threshold.

    " }, + END_MARKER +}; + +static const struct cfgelem channels_cfgelems[] = { + { MGROUP ("Channel", channel_cfgelems, channel_cfgattrs), 42, 0, ABSOFF (channels), if_channel, 0, 0, 0, + "

    This element defines a channel.

    " }, + END_MARKER +}; +#endif /* DDSI_INCLUDE_NETWORK_CHANNELS */ + +static const struct cfgelem thread_properties_sched_cfgelems[] = { + { LEAF ("Class"), 1, "default", RELOFF (config_thread_properties_listelem, sched_class), 0, uf_sched_class, 0, pf_sched_class, + "

    This element specifies the thread scheduling class (realtime, timeshare or default). The user may need special privileges from the underlying operating system to be able to assign some of the privileged scheduling classes.

    " }, + { LEAF ("Priority"), 1, "default", RELOFF (config_thread_properties_listelem, sched_priority), 0, uf_maybe_int32, 0, pf_maybe_int32, + "

    This element specifies the thread priority (decimal integer or default). Only priorities that are supported by the underlying operating system can be assigned to this element. The user may need special privileges from the underlying operating system to be able to assign some of the privileged priorities.

    " }, + END_MARKER +}; + +static const struct cfgelem thread_properties_cfgattrs[] = { + { ATTR ("Name"), 1, NULL, RELOFF (config_thread_properties_listelem, name), 0, uf_string, ff_free, pf_string, + "

    The Name of the thread for which properties are being set. The following threads exist:

    \n\ +
    • gc: garbage collector thread involved in deleting entities;
    • \n\ +
    • recv: receive thread, taking data from the network and running the protocol state machine;
    • \n\ +
    • dq.builtins: delivery thread for DDSI-builtin data, primarily for discovery;
    • \n\ +
    • lease: DDSI liveliness monitoring;
    • \n\ +
    • tev: general timed-event handling, retransmits and discovery;
    • \n\ +
    • xmit.CHAN: transmit thread for channel CHAN;
    • \n\ +
    • dq.CHAN: delivery thread for channel CHAN;
    • \n\ +
    • tev.CHAN: timed-even thread for channel CHAN.
    " }, + END_MARKER +}; + +static const struct cfgelem thread_properties_cfgelems[] = { + { GROUP ("Scheduling", thread_properties_sched_cfgelems), + "

    This element configures the scheduling properties of the thread.

    " }, + { LEAF ("StackSize"), 1, "default", RELOFF (config_thread_properties_listelem, stack_size), 0, uf_maybe_memsize, 0, pf_maybe_memsize, + "

    This element configures the stack size for this thread. The default value default leaves the stack size at the operating system default.

    " }, + END_MARKER +}; + +static const struct cfgelem threads_cfgelems[] = { + { MGROUP ("Thread", thread_properties_cfgelems, thread_properties_cfgattrs), 1000, 0, ABSOFF (thread_properties), if_thread_properties, 0, 0, 0, + "

    This element is used to set thread properties.

    " }, + END_MARKER +}; + +static const struct cfgelem compatibility_cfgelems[] = { + { LEAF ("StandardsConformance"), 1, "lax", ABSOFF (standards_conformance), 0, uf_standards_conformance, 0, pf_standards_conformance, + "

    This element sets the level of standards conformance of this instance of the DDSI2E Service. Stricter conformance typically means less interoperability with other implementations. Currently three modes are defined:

    \n\ +
    • pedantic: very strictly conform to the specification, ultimately for compliancy testing, but currently of little value because it adheres even to what will most likely turn out to be editing errors in the DDSI standard. Arguably, as long as no errata have been published it is the current text that is in effect, and that is what pedantic currently does.
    • \n\ +
    • strict: a slightly less strict view of the standard than does pedantic: it follows the established behaviour where the standard is obviously in error.
    • \n\ +
    • lax: attempt to provide the smoothest possible interoperability, anticipating future revisions of elements in the standard in areas that other implementations do not adhere to, even though there is no good reason not to.
    \n\ +

    The default setting is \"lax\".

    " }, + { LEAF ("ExplicitlyPublishQosSetToDefault"), 1, "false", ABSOFF (explicitly_publish_qos_set_to_default), 0, uf_boolean, 0, pf_boolean, + "

    This element specifies whether QoS settings set to default values are explicitly published in the discovery protocol. Implementations are to use the default value for QoS settings not published, which allows a significant reduction of the amount of data that needs to be exchanged for the discovery protocol, but this requires all implementations to adhere to the default values specified by the specifications.

    \n\ +

    When interoperability is required with an implementation that does not follow the specifications in this regard, setting this option to true will help.

    " }, + { LEAF ("ManySocketsMode"), 1, "false", ABSOFF (many_sockets_mode), 0, uf_boolean, 0, pf_boolean, + "

    This option specifies whether a network socket will be created for each domain participant on a host. The specification seems to assume that each participant has a unique address, and setting this option will ensure this to be the case. This is not the defeault.

    \n\ +

    Disabling it slightly improves performance and reduces network traffic somewhat. It also causes the set of port numbers needed by DDSI2E to become predictable, which may be useful for firewall and NAT configuration.

    " }, + { LEAF ("ArrivalOfDataAssertsPpAndEpLiveliness"), 1, "true", ABSOFF (arrival_of_data_asserts_pp_and_ep_liveliness), 0, uf_boolean, 0, pf_boolean, + "

    When set to true, arrival of a message from a peer asserts liveliness of that peer. When set to false, only SPDP and explicit lease renewals have this effect.

    " }, + { LEAF ("AckNackNumbitsEmptySet"), 1, "0", ABSOFF (acknack_numbits_emptyset), 0, uf_natint, 0, pf_int, + "

    This element governs the representation of an acknowledgement message that does not also negatively-acknowledge some samples. If set to 0, the generated acknowledgements have an invalid form and will be reject by the strict and pedantic conformance modes, but several other implementation require this setting for smooth interoperation.

    \n\ +

    If set to 1, all acknowledgements sent by DDSI2E adhere the form of acknowledgement messages allowed by the standard, but this causes problems when interoperating with these other implementations. The strict and pedantic standards conformance modes always overrule an AckNackNumbitsEmptySet=0 to prevent the transmitting of invalid messages.

    " }, + { LEAF ("RespondToRtiInitZeroAckWithInvalidHeartbeat"), 1, "false", ABSOFF (respond_to_rti_init_zero_ack_with_invalid_heartbeat), 0, uf_boolean, 0, pf_boolean, + "

    This element allows a closer mimicking of the behaviour of some other DDSI implementations, albeit at the cost of generating even more invalid messages. Setting it to true ensures a Heartbeat can be sent at any time when a remote node requests one, setting it to false delays it until a valid one can be sent.

    \n\ +

    The latter is fully compliant with the specification, and no adverse effects have been observed. It is the default.

    " }, + { LEAF ("AssumeRtiHasPmdEndpoints"), 1, "false", ABSOFF (assume_rti_has_pmd_endpoints), 0, uf_boolean, 0, pf_boolean, + "

    This option assumes ParticipantMessageData endpoints required by the liveliness protocol are present in RTI participants even when not properly advertised by the participant discovery protocol.

    " }, + END_MARKER +}; + +static const struct cfgelem unsupp_test_cfgelems[] = { + { LEAF ("XmitLossiness"), 1, "0", ABSOFF (xmit_lossiness), 0, uf_int, 0, pf_int, + "

    This element controls the fraction of outgoing packets to drop, specified as samples per thousand.

    " }, + END_MARKER +}; + +static const struct cfgelem unsupp_watermarks_cfgelems[] = { + { LEAF ("WhcLow"), 1, "1 kB", ABSOFF (whc_lowwater_mark), 0, uf_memsize, 0, pf_memsize, + "

    This element sets the low-water mark for the DDSI2E WHCs, expressed in bytes. A suspended writer resumes transmitting when its DDSI2E WHC shrinks to this size.

    " }, + { LEAF ("WhcHigh"), 1, "100 kB", ABSOFF (whc_highwater_mark), 0, uf_memsize, 0, pf_memsize, + "

    This element sets the maximum allowed high-water mark for the DDSI2E WHCs, expressed in bytes. A writer is suspended when the WHC reaches this size.

    " }, + { LEAF ("WhcHighInit"), 1, "30 kB", ABSOFF (whc_init_highwater_mark), 0, uf_maybe_memsize, 0, pf_maybe_memsize, + "

    This element sets the initial level of the high-water mark for the DDSI2E WHCs, expressed in bytes.

    "}, + { LEAF ("WhcAdaptive|WhcAdaptative"), 1, "true", ABSOFF (whc_adaptive), 0, uf_boolean, 0, pf_boolean, + "

    This element controls whether DDSI2E will adapt the high-water mark to current traffic conditions, based on retransmit requests and transmit pressure.

    " }, + END_MARKER +}; + +static const struct cfgelem control_topic_cfgattrs[] = { + { ATTR ("enable"), 1, "false", ABSOFF (enable_control_topic), 0, uf_boolean, 0, pf_boolean, + "

    This attribute controls whether the DDSI2E control topic is defined and acted upon by DDSI2

    " }, + { ATTR ("initialreset"), 1, "inf", ABSOFF (initial_deaf_mute_reset), 0, uf_duration_inf, 0, pf_duration, + "

    This attribute sets the time until the deaf and mute settings are automatically reset to false

    " }, + END_MARKER +}; + +static const struct cfgelem control_topic_cfgelems[] = { + { LEAF ("Deaf"), 1, "false", ABSOFF (initial_deaf), 0, uf_boolean, 0, pf_boolean, + "

    This element controls whether DDSI2E defaults to deaf mode or to normal mode. This controls both the initial behaviour and what behaviour it auto-reverts to.

    " }, + { LEAF ("Mute"), 1, "false", ABSOFF (initial_mute), 0, uf_boolean, 0, pf_boolean, + "

    This element controls whether DDSI2E defaults to mute mode or to normal mode. This controls both the initial behaviour and what behaviour it auto-reverts to.

    " }, + END_MARKER +}; + +static const struct cfgelem rediscovery_blacklist_duration_attrs[] = { + { ATTR ("enforce"), 1, "false", ABSOFF (prune_deleted_ppant.enforce_delay), 0, uf_boolean, 0, pf_boolean, + "

    This attribute controls whether the configured time during which recently deleted participants will not be rediscovered (i.e., \"black listed\") is enforced and following complete removal of the participant in DDSI2E, or whether it can be rediscovered earlier provided all traces of that participant have been removed already.

    " }, + END_MARKER +}; + +static const struct cfgelem heartbeat_interval_attrs[] = { + { ATTR ("min"), 1, "5 ms", ABSOFF (const_hb_intv_min), 0, uf_duration_inf, 0, pf_duration, + "

    This attribute sets the minimum interval that must have passed since the most recent heartbeat from a writer, before another asynchronous (not directly related to writing) will be sent.

    " }, + { ATTR ("minsched"), 1, "20 ms", ABSOFF (const_hb_intv_sched_min), 0, uf_duration_inf, 0, pf_duration, + "

    This attribute sets the minimum interval for periodic heartbeats. Other events may still cause heartbeats to go out.

    " }, + { ATTR ("max"), 1, "8 s", ABSOFF (const_hb_intv_sched_max), 0, uf_duration_inf, 0, pf_duration, + "

    This attribute sets the maximum interval for periodic heartbeats.

    " }, + END_MARKER +}; + +static const struct cfgelem unsupp_cfgelems[] = { + { MOVED ("MaxMessageSize", "General/MaxMessageSize") }, + { MOVED ("FragmentSize", "General/FragmentSize") }, + { LEAF ("DeliveryQueueMaxSamples"), 1, "256", ABSOFF (delivery_queue_maxsamples), 0, uf_uint, 0, pf_uint, + "

    This element controls the Maximum size of a delivery queue, expressed in samples. Once a delivery queue is full, incoming samples destined for that queue are dropped until space becomes available again.

    " }, + { LEAF ("PrimaryReorderMaxSamples"), 1, "64", ABSOFF (primary_reorder_maxsamples), 0, uf_uint, 0, pf_uint, + "

    This element sets the maximum size in samples of a primary re-order administration. Each proxy writer has one primary re-order administration to buffer the packet flow in case some packets arrive out of order. Old samples are forwarded to secondary re-order administrations associated with readers in need of historical data.

    " }, + { LEAF ("SecondaryReorderMaxSamples"), 1, "16", ABSOFF (secondary_reorder_maxsamples), 0, uf_uint, 0, pf_uint, + "

    This element sets the maximum size in samples of a secondary re-order administration. The secondary re-order administration is per reader in need of historical data.

    " }, + { LEAF ("DefragUnreliableMaxSamples"), 1, "4", ABSOFF (defrag_unreliable_maxsamples), 0, uf_uint, 0, pf_uint, + "

    This element sets the maximum number of samples that can be defragmented simultaneously for a best-effort writers.

    " }, + { LEAF ("DefragReliableMaxSamples"), 1, "16", ABSOFF (defrag_reliable_maxsamples), 0, uf_uint, 0, pf_uint, + "

    This element sets the maximum number of samples that can be defragmented simultaneously for a reliable writer. This has to be large enough to handle retransmissions of historical data in addition to new samples.

    " }, + { LEAF ("BuiltinEndpointSet"), 1, "writers", ABSOFF (besmode), 0, uf_besmode, 0, pf_besmode, + "

    This element controls which participants will have which built-in endpoints for the discovery and liveliness protocols. Valid values are:

    \n\ +
    • full: all participants have all endpoints;
    • \n\ +
    • writers: all participants have the writers, but just one has the readers;
    • \n\ +
    • minimal: only one participant has built-in endpoints.
    \n\ +

    The default is writers, as this is thought to be compliant and reasonably efficient. Minimal may or may not be compliant but is most efficient, and full is inefficient but certain to be compliant. See also Internal/ConservativeBuiltinReaderStartup.

    " }, +#if !LITE + { LEAF ("AggressiveKeepLastWhc|AggressiveKeepLast1Whc"), 1, "false", ABSOFF (aggressive_keep_last_whc), 0, uf_boolean, 0, pf_boolean, + "

    This element controls whether to drop a reliable sample from a DDSI2E WHC before all readers have acknowledged it as soon as a later sample becomes available. It only affects DCPS data writers with a history QoS setting of KEEP_LAST with depth 1. The default setting, false, mimics the behaviour of the OpenSplice RT networking and is necessary to make the behaviour of wait_for_acknowledgements() consistent across the networking services.

    " }, +#else + { LEAF ("AggressiveKeepLastWhc|AggressiveKeepLast1Whc"), 1, "true", ABSOFF (aggressive_keep_last_whc), 0, uf_boolean, 0, pf_boolean, + "

    This element controls whether to drop a reliable sample from a DDSI2E WHC before all readers have acknowledged it as soon as a later sample becomes available. It only affects DCPS data writers with a history QoS setting of KEEP_LAST with depth 1. The default setting, false, mimics the behaviour of the OpenSplice RT networking and is necessary to make the behaviour of wait_for_acknowledgements() consistent across the networking services.

    " }, +#endif + { LEAF ("ConservativeBuiltinReaderStartup"), 1, "false", ABSOFF (conservative_builtin_reader_startup), 0, uf_boolean, 0, pf_boolean, + "

    This element forces all DDSI2E built-in discovery-related readers to request all historical data, instead of just one for each \"topic\". There is no indication that any of the current DDSI implementations requires changing of this setting, but it is conceivable that an implementation might track which participants have been informed of the existence of endpoints and which have not been, refusing communication with those that have \"can't\" know.

    \n\ +

    Should it be necessary to hide DDSI2E's shared discovery behaviour, set this to true and Internal/BuiltinEndpointSet to full.

    " }, + { LEAF ("MeasureHbToAckLatency"), 1, "false", ABSOFF (meas_hb_to_ack_latency), 0, uf_boolean, 0, pf_boolean, + "

    This element enables heartbeat-to-ack latency among DDSI2E services by prepending timestamps to Heartbeat and AckNack messages and calculating round trip times. This is non-standard behaviour. The measured latencies are quite noisy and are currently not used anywhere.

    " }, + { LEAF ("SuppressSPDPMulticast"), 1, "false", ABSOFF (suppress_spdp_multicast), 0, uf_boolean, 0, pf_boolean, + "

    The element controls whether the mandatory multicasting of the participant discovery packets occurs. Completely disabling multicasting requires this element be set to true, and generally requires explicitly listing peers to ping for unicast discovery.

    \n\ +

    See also General/AllowMulticast.

    " }, + { LEAF ("UnicastResponseToSPDPMessages"), 1, "true", ABSOFF (unicast_response_to_spdp_messages), 0, uf_boolean, 0, pf_boolean, + "

    This element controls whether the response to a newly discovered participant is sent as a unicasted SPDP packet, instead of rescheduling the periodic multicasted one. There is no known benefit to setting this to false.

    " }, + { LEAF ("SynchronousDeliveryPriorityThreshold"), 1, "0", ABSOFF (synchronous_delivery_priority_threshold), 0, uf_int, 0, pf_int, + "

    This element controls whether samples sent by a writer with QoS settings latency_budget <= SynchronousDeliveryLatencyBound and transport_priority greater than or equal to this element's value will be delivered synchronously from the \"recv\" thread, all others will be delivered asynchronously through delivery queues. This reduces latency at the expense of aggregate bandwidth.

    " }, + { LEAF ("SynchronousDeliveryLatencyBound"), 1, "inf", ABSOFF (synchronous_delivery_latency_bound), 0, uf_duration_inf, 0, pf_duration, + "

    This element controls whether samples sent by a writer with QoS settings transport_priority >= SynchronousDeliveryPriorityThreshold and a latency_budget at most this element's value will be delivered synchronously from the \"recv\" thread, all others will be delivered asynchronously through delivery queues. This reduces latency at the expense of aggregate bandwidth.

    " }, + { LEAF ("MaxParticipants"), 1, "0", ABSOFF (max_participants), 0, uf_natint, 0, pf_int, + "

    This elements configures the maximum number of DCPS domain participants this DDSI2E instance is willing to service. 0 is unlimited.

    " }, + { LEAF ("AccelerateRexmitBlockSize"), 1, "0", ABSOFF (accelerate_rexmit_block_size), 0, uf_uint, 0, pf_uint, + "

    Proxy readers that are assumed to sill be retrieving historical data get this many samples retransmitted when they NACK something, even if some of these samples have sequence numbers outside the set covered by the NACK.

    " }, +#if !LITE + { LEAF ("ResponsivenessTimeout"), 1, "inf", ABSOFF (responsiveness_timeout), 0, uf_duration_inf, 0, pf_duration, + "

    This element controls for how long an unresponsive reader can block the transmit thread by failing to acknowledge data when a writer's DDSI2E write cache is full. If after this time the writer's cache has not shrunk to below the low-water mark, the reader is considered unresponsive and degraded to unreliable. It will be restored to reliable service once it resumes acknowledging samples.

    " }, +#endif + { LEAF ("RetransmitMerging"), 1, "adaptive", ABSOFF (retransmit_merging), 0, uf_retransmit_merging, 0, pf_retransmit_merging, + "

    This elements controls the addressing and timing of retransmits. Possible values are:

    \n\ +
    • never: retransmit only to the NACK-ing reader;
    • \n\ +
    • adaptive: attempt to combine retransmits needed for reliability, but send historical (transient-local) data to the requesting reader only;
    • \n\ +
    • always: do not distinguish between different causes, always try to merge.
    \n\ +

    The default is adaptive. See also Internal/RetransmitMergingPeriod.

    " }, + { LEAF ("RetransmitMergingPeriod"), 1, "5 ms", ABSOFF (retransmit_merging_period), 0, uf_duration_us_1s, 0, pf_duration, + "

    This setting determines the size of the time window in which a NACK of some sample is ignored because a retransmit of that sample has been multicasted too recently. This setting has no effect on unicasted retransmits.

    \n\ +

    See also Internal/RetransmitMerging.

    " }, + { LEAF ("MaxQueuedRexmitBytes"), 1, "50 kB", ABSOFF (max_queued_rexmit_bytes), 0, uf_memsize, 0, pf_memsize, + "

    This setting limits the maximum number of bytes queued for retransmission. The default value of 0 is unlimited unless an AuxiliaryBandwidthLimit has been set, in which case it becomes NackDelay * AuxiliaryBandwidthLimit. It must be large enough to contain the largest sample that may need to be retransmitted.

    " }, + { LEAF_W_ATTRS ("HeartbeatInterval", heartbeat_interval_attrs), 1, "100 ms", ABSOFF (const_hb_intv_sched), 0, uf_duration_inf, 0, pf_duration, + "

    This element sets the base interval for the asynchronous, periodic writer heartbeats when unacknowledged data is present in its writer history cache. The actual interval is dynamically adjusted, the attributes of this element allow further configuration.

    " }, + { LEAF ("MaxQueuedRexmitMessages"), 1, "200", ABSOFF (max_queued_rexmit_msgs), 0, uf_uint, 0, pf_uint, + "

    This settings limits the maximum number of samples queued for retransmission.

    " }, +#if !LITE + { LEAF ("MirrorRemoteEntities"), 1, "default", ABSOFF (mirror_remote_entities), 0, uf_boolean_default, 0, pf_boolean_default, + "

    This element controls whether DDSI2 mirrors all entities in the domain in DDSI or only local ones. Default is to discover remote ones iff General/LocalDiscoveryPartition is not the built-in partition.

    " }, + { LEAF ("ForwardRemoteData"), 1, "default", ABSOFF (forward_remote_data), 0, uf_boolean_default, 0, pf_boolean, + "

    This element controls whether DDSI2E forwards data received from other network services in the domain.

    " }, +#endif +#if LITE + { LEAF ("LeaseDuration"), 1, "10 s", ABSOFF (lease_duration), 0, uf_duration_ms_1hr, 0, pf_duration, + "

    This setting controls the default participant lease duration.

    " }, +#else + { LEAF ("LeaseDuration"), 1, "0 s", ABSOFF (lease_duration), 0, uf_duration_ms_1hr, 0, pf_duration, + "

    This setting controls the default participant lease duration.

    " }, +#endif + { LEAF ("WriterLingerDuration"), 1, "1 s", ABSOFF (writer_linger_duration), 0, uf_duration_ms_1hr, 0, pf_duration, + "

    This setting controls the maximum duration for which actual deletion of a reliable writer with unacknowledged data in its history will be postponed to provide proper reliable transmission.

    " }, + { LEAF ("MinimumSocketReceiveBufferSize"), 1, "default", ABSOFF (socket_min_rcvbuf_size), 0, uf_maybe_memsize, 0, pf_maybe_memsize, + "

    This setting controls the minimum size of socket receive buffers. The operating system provides some size receive buffer upon creation of the socket, this option can be used to increase the size of the buffer beyond that initially provided by the operating system. If the buffer size cannot be increased to the specified size, an error is reported.

    \n\ +

    The default setting is the word \"default\", which means DDSI2E will attempt to increase the buffer size to 1MB, but will silently accept a smaller buffer should that attempt fail.

    " }, + { LEAF ("MinimumSocketSendBufferSize"), 1, "64 KiB", ABSOFF (socket_min_sndbuf_size), 0, uf_memsize, 0, pf_memsize, + "

    This setting controls the minimum size of socket send buffers. This setting can only increase the size of the send buffer, if the operating system by default creates a larger buffer, it is left unchanged.

    " }, + { LEAF ("NackDelay"), 1, "10 ms", ABSOFF (nack_delay), 0, uf_duration_ms_1hr, 0, pf_duration, + "

    This setting controls the delay between receipt of a HEARTBEAT indicating missing samples and a NACK (ignored when the HEARTBEAT requires an answer). However, no NACK is sent if a NACK had been scheduled already for a response earlier than the delay requests: then that NACK will incorporate the latest information.

    " }, + { LEAF ("AutoReschedNackDelay"), 1, "1 s", ABSOFF (auto_resched_nack_delay), 0, uf_duration_inf, 0, pf_duration, + "

    This setting controls the interval with which a reader will continue NACK'ing missing samples in the absence of a response from the writer, as a protection mechanism against writers incorrectly stopping the sending of HEARTBEAT messages.

    "}, + { LEAF ("PreEmptiveAckDelay"), 1, "10 ms", ABSOFF (preemptive_ack_delay), 0, uf_duration_ms_1hr, 0, pf_duration, + "

    This setting controls the delay between the discovering a remote writer and sending a pre-emptive AckNack to discover the range of data available.

    " }, + { LEAF ("ScheduleTimeRounding"), 1, "0 ms", ABSOFF (schedule_time_rounding), 0, uf_duration_ms_1hr, 0, pf_duration, + "

    This setting allows the timing of scheduled events to be rounded up so that more events can be handled in a single cycle of the event queue. The default is 0 and causes no rounding at all, i.e. are scheduled exactly, whereas a value of 10ms would mean that events are rounded up to the nearest 10 milliseconds.

    " }, +#ifdef DDSI_INCLUDE_BANDWIDTH_LIMITING + { LEAF ("AuxiliaryBandwidthLimit"), 1, "inf", ABSOFF (auxiliary_bandwidth_limit), 0, uf_bandwidth, 0, pf_bandwidth, + "

    This element specifies the maximum transmit rate of auxiliary traffic not bound to a specific channel, such as discovery traffic, as well as auxiliary traffic related to a certain channel if that channel has elected to share this global AuxiliaryBandwidthLimit. Bandwidth limiting uses a leaky bucket scheme. The default value \"inf\" means DDSI2E imposes no limitation, the underlying operating system and hardware will likely limit the maimum transmit rate.

    "}, +#endif + { LEAF ("DDSI2DirectMaxThreads"), 1, "1", ABSOFF (ddsi2direct_max_threads), 0, uf_uint, 0, pf_uint, + "

    This element sets the maximum number of extra threads for an experimental, undocumented and unsupported direct mode.

    " }, + { LEAF ("SquashParticipants"), 1, "false", ABSOFF (squash_participants), 0, uf_boolean, 0, pf_boolean, + "

    This element controls whether DDSI2E advertises all the domain participants it serves in DDSI (when set to false), or rather only one domain participant (the one corresponding to the DDSI2E process; when set to true). In the latter case DDSI2E becomes the virtual owner of all readers and writers of all domain participants, dramatically reducing discovery traffic (a similar effect can be obtained by setting Internal/BuiltinEndpointSet to \"minimal\" but with less loss of information).

    " }, + { LEAF ("LegacyFragmentation"), 1, "false", ABSOFF (buggy_datafrag_flags_mode), 0, uf_boolean, 0, pf_boolean, + "

    This option enables a backwards-compatible, non-compliant setting and interpretation of the control flags in fragmented data messages. To be enabled only when requiring interoperability between compliant and non-compliant versions of DDSI2E for large messages.

    " }, + { LEAF ("SPDPResponseMaxDelay"), 1, "0 ms", ABSOFF (spdp_response_delay_max), 0, uf_duration_ms_1s, 0, pf_duration, + "

    Maximum pseudo-random delay in milliseconds between discovering a remote participant and responding to it.

    " }, + { LEAF ("LateAckMode"), 1, "false", ABSOFF (late_ack_mode), 0, uf_boolean, 0, pf_boolean, + "

    Ack a sample only when it has been delivered, instead of when committed to delivering it.

    " }, + { LEAF ("ForwardAllMessages"), 1, "false", ABSOFF (forward_all_messages), 0, uf_boolean, 0, pf_boolean, + "

    Forward all messages from a writer, rather than trying to forward each sample only once. The default of trying to forward each sample only once filters out duplicates for writers in multiple partitions under nearly all circumstances, but may still publish the odd duplicate. Note: the current implementation also can lose in contrived test cases, that publish more than 2**32 samples using a single data writer in conjunction with carefully controlled management of the writer history via cooperating local readers.

    " }, +#if !LITE + { LEAF ("RetryOnRejectDuration"), 1, "default", ABSOFF (retry_on_reject_duration), 0, uf_maybe_duration_inf, 0, pf_maybe_duration, + "

    How long to keep locally retrying pushing a received sample into the reader caches when resource limits are reached. Default is dependent on Internal/LateAckMode: if the latter is false, it is 80% of Internal/ResponsivenessTimeout, otherwise it is 0.

    " }, +#endif + { LEAF ("RetryOnRejectBestEffort"), 1, "false", ABSOFF (retry_on_reject_besteffort), 0, uf_boolean, 0, pf_boolean, + "

    Whether or not to locally retry pushing a received best-effort sample into the reader caches when resource limits are reached.

    " }, + { LEAF ("GenerateKeyhash"), 1, "true", ABSOFF (generate_keyhash), 0, uf_boolean, 0, pf_boolean, + "

    When true, include keyhashes in outgoing data for topics with keys.

    " }, + { LEAF ("MaxSampleSize"), 1, "2147483647 B", ABSOFF (max_sample_size), 0, uf_memsize, 0, pf_memsize, + "

    This setting controls the maximum (CDR) serialised size of samples that DDSI2E will forward in either direction. Samples larger than this are discarded with a warning.

    " }, +#if LITE + { LEAF ("WriteBatch"), 1, "false", ABSOFF (whc_batch), 0, uf_boolean, 0, pf_boolean, + "

    This element enables the batching of write operations. By default each write operation writes through the write cache and out onto the transport. Enabling write batching causes multiple small write operations to be aggregated within the write cache into a single larger write. This gives greater throughput at the expense of latency. Currently there is no mechanism for the write cache to automatically flush itself, so that if write batching is enabled, the application may havee to use the dds_write_flush function to ensure thta all samples are written.

    " }, +#endif + { LEAF ("LogStackTraces"), 1, "true", ABSOFF (noprogress_log_stacktraces), 0, uf_boolean, 0, pf_boolean, + "

    This element controls whether or not to write stack traces to the DDSI2 trace when a thread fails to make progress (on select platforms only).

    " }, + { LEAF ("MonitorPort"), 1, "-1", ABSOFF (monitor_port), 0, uf_int, 0, pf_int, + "

    This element allows configuring a service that dumps a text description of part the internal state to TCP clients. By default (-1), this is disabled; specifying 0 means a kernel-allocated port is used; a positive number is used as the TCP port number.

    " }, + { LEAF ("AssumeMulticastCapable"), 1, "", ABSOFF (assumeMulticastCapable), 0, uf_string, ff_free, pf_string, + "

    This element controls which network interfaces are assumed to be capable of multicasting even when the interface flags returned by the operating system state it is not (this provides a workaround for some platforms). It is a comma-separated lists of patterns (with ? and * wildcards) against which the interface names are matched.

    " }, + { LEAF ("PrioritizeRetransmit"), 1, "true", ABSOFF (prioritize_retransmit), 0, uf_boolean, 0, pf_boolean, + "

    This element controls whether retransmits are prioritized over new data, speeding up recovery.

    " }, + { LEAF ("UseMulticastIfMreqn"), 1, "0", ABSOFF (use_multicast_if_mreqn), 0, uf_int, 0, pf_int, + "

    Do not use.

    " }, + { LEAF_W_ATTRS ("RediscoveryBlacklistDuration", rediscovery_blacklist_duration_attrs), 1, "10s", ABSOFF (prune_deleted_ppant.delay), 0, uf_duration_inf, 0, pf_duration, + "

    This element controls for how long a remote participant that was previously deleted will remain on a blacklist to prevent rediscovery, giving the software on a node time to perform any cleanup actions it needs to do. To some extent this delay is required internally by DDSI2E, but in the default configuration with the 'enforce' attribute set to false, DDSI2E will reallow rediscovery as soon as it has cleared its internal administration. Setting it to too small a value may result in the entry being pruned from the blacklist before DDSI2E is ready, it is therefore recommended to set it to at least several seconds.

    " }, + { MGROUP ("ControlTopic", control_topic_cfgelems, control_topic_cfgattrs), 1, 0, 0, 0, 0, 0, 0, 0, + "

    The ControlTopic element allows configured whether DDSI2E provides a special control interface via a predefined topic or not.

    " }, + { GROUP ("Test", unsupp_test_cfgelems), + "

    Testing options.

    " }, + { GROUP ("Watermarks", unsupp_watermarks_cfgelems), + "

    Watermarks for flow-control.

    " }, + END_MARKER +}; + +static const struct cfgelem sizing_cfgelems[] = +{ +#if LITE + { LEAF ("ReceiveBufferSize"), 1, "128 KiB", ABSOFF (rbuf_size), 0, uf_memsize, 0, pf_memsize, + "

    This element sets the size of a single receive buffer. Many receive buffers may be needed. Their size must be greater than ReceiveBufferChunkSize by a modest amount.

    " }, + { LEAF ("ReceiveBufferChunkSize"), 1, "64 KiB", ABSOFF (rmsg_chunk_size), 0, uf_memsize, 0, pf_memsize, + "

    This element specifies the size of one allocation unit in the receive buffer. Must be greater than the maximum packet size by a modest amount (too large packets are dropped). Each allocation is shrunk immediately after processing a message, or freed straightaway.

    " }, + { LEAF ("EndpointsInSystem"), 1, "200", ABSOFF (guid_hash_softlimit), 0, uf_uint32, 0, pf_uint32, + "

    This endpoint specifies the expected maximum number of endpoints in the network. Underestimating this number will have a significant performance impact, but will not affect correctness; signficantly overestimating it will cause more memory to be used than necessary.

    " }, + { LEAF ("NetworkQueueSize"), 1, "10", ABSOFF (nw_queue_size), 0, uf_uint, 0, pf_uint }, +#else + { LEAF ("ReceiveBufferSize"), 1, "1 MiB", ABSOFF (rbuf_size), 0, uf_memsize, 0, pf_memsize, + "

    This element sets the size of a single receive buffer. Many receive buffers may be needed. Their size must be greater than ReceiveBufferChunkSize by a modest amount.

    " }, + { LEAF ("ReceiveBufferChunkSize"), 1, "128 KiB", ABSOFF (rmsg_chunk_size), 0, uf_memsize, 0, pf_memsize, + "

    This element specifies the size of one allocation unit in the receive buffer. Must be greater than the maximum packet size by a modest amount (too large packets are dropped). Each allocation is shrunk immediately after processing a message, or freed straightaway.

    " }, + { LEAF ("LocalEndpoints"), 1, "1000", ABSOFF (gid_hash_softlimit), 0, uf_uint32, 0, pf_uint32, + "

    This element specifies the expected maximum number of endpoints local to one DDSI2E service. Underestimating this number will have a significant performance impact, but will not affect correctness; signficantly overestimating it will cause more memory to be used than necessary.

    " }, + { LEAF ("EndpointsInSystem"), 1, "20000", ABSOFF (guid_hash_softlimit), 0, uf_uint32, 0, pf_uint32, + "

    This endpoint specifies the expected maximum number of endpoints in the network. Underestimating this number will have a significant performance impact, but will not affect correctness; signficantly overestimating it will cause more memory to be used than necessary.

    " }, + { LEAF ("NetworkQueueSize"), 1, "1000", ABSOFF (nw_queue_size), 0, uf_uint, 0, pf_uint, + "

    This element specifies the maximum number of samples in the network queue. Write/dispose operations add samples to this queue, the DDSI2E service drains it. Larger values allow large bursts of writes to occur without forcing synchronization between the application and the DDSI2E service, but do introduce the potential for longer latencies and increase the maximum amount of memory potentially occupied by messages in the queue.

    " }, +#endif + END_MARKER +}; + +static const struct cfgelem discovery_ports_cfgelems[] = { + { LEAF ("Base"), 1, "7400", ABSOFF (port_base), 0, uf_port, 0, pf_int, + "

    This element specifies the base port number (refer to the DDSI 2.1 or 2.2 specification, section 9.6.1, constant PB).

    " }, + { LEAF ("DomainGain"), 1, "250", ABSOFF (port_dg), 0, uf_int, 0, pf_int, + "

    This element specifies the domain gain, relating domain ids to sets of port numbers (refer to the DDSI 2.1 or 2.2 specification, section 9.6.1, constant DG).

    " }, + { LEAF ("ParticipantGain"), 1, "2", ABSOFF (port_pg), 0, uf_int, 0, pf_int, + "

    This element specifies the participant gain, relating p0, articipant index to sets of port numbers (refer to the DDSI 2.1 or 2.2 specification, section 9.6.1, constant PG).

    " }, + { LEAF ("MulticastMetaOffset"), 1, "0", ABSOFF (port_d0), 0, uf_int, 0, pf_int, + "

    This element specifies the port number for multicast meta traffic (refer to the DDSI 2.1 or 2.2 specification, section 9.6.1, constant d0).

    " }, + { LEAF ("UnicastMetaOffset"), 1, "10", ABSOFF (port_d1), 0, uf_int, 0, pf_int, + "

    This element specifies the port number for unicast meta traffic (refer to the DDSI 2.1 or 2.2 specification, section 9.6.1, constant d1).

    " }, + { LEAF ("MulticastDataOffset"), 1, "1", ABSOFF (port_d2), 0, uf_int, 0, pf_int, + "

    This element specifies the port number for multicast meta traffic (refer to the DDSI 2.1 or 2.2 specification, section 9.6.1, constant d2).

    " }, + { LEAF ("UnicastDataOffset"), 1, "11", ABSOFF (port_d3), 0, uf_int, 0, pf_int, + "

    This element specifies the port number for unicast meta traffic (refer to the DDSI 2.1 or 2.2 specification, section 9.6.1, constant d3).

    " }, + END_MARKER +}; + +static const struct cfgelem tcp_cfgelems[] = { + { LEAF ("Enable"), 1, "false", ABSOFF (tcp_enable), 0, uf_boolean, 0, pf_boolean, + "

    This element enables the optional TCP transport.

    " }, + { LEAF ("NoDelay"), 1, "true", ABSOFF (tcp_nodelay), 0, uf_boolean, 0, pf_boolean, + "

    This element enables the TCP_NODELAY socket option, preventing multiple DDSI messages being sent in the same TCP request. Setting this option typically optimises latency over throughput.

    " }, + { LEAF ("Port"), 1, "-1", ABSOFF (tcp_port), 0, uf_dyn_port, 0, pf_int, + "

    This element specifies the TCP port number on which DDSI2E accepts connections. If the port is set it is used in entity locators, published with DDSI discovery. Dynamically allocated if zero. Disabled if -1 or not configured. If disabled other DDSI services will not be able to establish connections with the service, the service can only communicate by establishing connections to other services.

    " }, + { LEAF ("ReadTimeout"), 1, "2 s", ABSOFF (tcp_read_timeout), 0, uf_duration_ms_1hr, 0, pf_duration, + "

    This element specifies the timeout for blocking TCP read operations. If this timeout expires then the connection is closed.

    " }, + { LEAF ("WriteTimeout"), 1, "2 s", ABSOFF (tcp_write_timeout), 0, uf_duration_ms_1hr, 0, pf_duration, + "

    This element specifies the timeout for blocking TCP write operations. If this timeout expires then the connection is closed.

    " }, + END_MARKER +}; + +#ifdef DDSI_INCLUDE_SSL +static const struct cfgelem ssl_cfgelems[] = { + { LEAF ("Enable"), 1, "false", ABSOFF (ssl_enable), 0, uf_boolean, 0, pf_boolean, + "

    This enables SSL/TLS for TCP.

    " }, + { LEAF ("CertificateVerification"), 1, "true", ABSOFF (ssl_verify), 0, uf_boolean, 0, pf_boolean, + "

    If disabled this allows SSL connections to occur even if an X509 certificate fails verification.

    " }, + { LEAF ("VerifyClient"), 1, "false", ABSOFF (ssl_verify_client), 0, uf_boolean, 0, pf_boolean, + "

    This enables an SSL server checking the X509 certificate of a connecting client.

    " }, + { LEAF ("SelfSignedCertificates"), 1, "false", ABSOFF (ssl_self_signed), 0, uf_boolean, 0, pf_boolean, + "

    This enables the use of self signed X509 certificates.

    " }, + { LEAF ("KeystoreFile"), 1, "keystore", ABSOFF (ssl_keystore), 0, uf_string, ff_free, pf_string, + "

    The SSL/TLS key and certificate store file name. The keystore must be in PEM format.

    " }, + { LEAF ("KeyPassphrase"), 1, "secret", ABSOFF (ssl_key_pass), 0, uf_string, ff_free, pf_string, + "

    The SSL/TLS key pass phrase for encrypted keys.

    " }, + { LEAF ("Ciphers"), 1, "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH", ABSOFF (ssl_ciphers), 0, uf_string, ff_free, pf_string, + "

    The set of ciphers used by SSL/TLS

    " }, + { LEAF ("EntropyFile"), 1, "", ABSOFF (ssl_rand_file), 0, uf_string, ff_free, pf_string, + "

    The SSL/TLS random entropy file name.

    " }, + END_MARKER +}; +#endif + +static const struct cfgelem tp_cfgelems[] = { + { LEAF ("Enable"), 1, "false", ABSOFF (tp_enable), 0, uf_boolean, 0, pf_boolean, + "

    This element enables the optional thread pool.

    " }, + { LEAF ("Threads"), 1, "4", ABSOFF (tp_threads), 0, uf_natint, 0, pf_int, + "

    This elements configures the initial number of threads in the thread pool.

    " }, + { LEAF ("ThreadMax"), 1, "8", ABSOFF (tp_max_threads), 0, uf_natint, 0, pf_int, + "

    This elements configures the maximum number of threads in the thread pool.

    " }, + END_MARKER +}; + +static const struct cfgelem discovery_peer_cfgattrs[] = { + { ATTR ("Address"), 1, NULL, RELOFF (config_peer_listelem, peer), 0, uf_ipv4, ff_free, pf_string, + "

    This element specifies an IP address to which discovery packets must be sent, in addition to the default multicast address (see also General/AllowMulticast). Both a hostnames and a numerical IP address is accepted; the hostname or IP address may be suffixed with :PORT to explicitly set the port to which it must be sent. Multiple Peers may be specified.

    " }, + END_MARKER +}; + +static const struct cfgelem discovery_peers_group_cfgelems[] = { + { MGROUP ("Peer", NULL, discovery_peer_cfgattrs), 0, NULL, ABSOFF (peers_group), if_peer, 0, 0, 0, + "

    This element statically configures an addresses for discovery.

    " }, + END_MARKER +}; + +static const struct cfgelem discovery_peers_cfgelems[] = { + { MGROUP ("Peer", NULL, discovery_peer_cfgattrs), 0, NULL, ABSOFF (peers), if_peer, 0, 0, 0, + "

    This element statically configures an addresses for discovery.

    " }, + { GROUP ("Group", discovery_peers_group_cfgelems), + "

    This element statically configures a fault tolerant group of addresses for discovery. Each member of the group is tried in sequence until one succeeds.

    " }, + END_MARKER +}; + +static const struct cfgelem discovery_cfgelems[] = { + { LEAF ("DomainId"), 1, "default", ABSOFF (discoveryDomainId), 0, uf_maybe_int32, 0, pf_maybe_int32, + "

    This element allows overriding of the DDS Domain Id that is used for DDSI2E.

    " }, +#if !LITE + { LEAF ("LocalDiscoveryPartition"), 1, "__BUILT-IN PARTITION__", ABSOFF (local_discovery_partition), 0, uf_string, ff_free, pf_string, + "

    This element controls which partition is monitored by DDSI2E for built-in topics describing entities the it mirrors in DDSI.

    " }, +#endif + { LEAF ("GenerateBuiltinTopics"), 1, "true", ABSOFF (generate_builtin_topics), 0, uf_boolean, 0, pf_boolean, + "

    This element controls whether or not DDSI2E generates built-in topics from its discovery. When disabled, it relies on the durability service.

    " }, + { LEAF ("AdvertiseBuiltinTopicWriters"), 1, "true", ABSOFF (advertise_builtin_topic_writers), 0, uf_boolean, 0, pf_boolean, + "

    This element controls whether or not DDSI2E advertises writers for the built-in topics from its discovery for backwards compatibility with older OpenSplice versions.

    " }, + { LEAF ("DSGracePeriod"), 1, "30 s", ABSOFF (ds_grace_period), 0, uf_duration_inf, 0, pf_duration, + "

    This setting controls for how long endpoints discovered via a Cloud discovery service will survive after the discovery service disappeared, allowing reconnect without loss of data when the discovery service restarts (or another instance takes over).

    " }, + { GROUP ("Peers", discovery_peers_cfgelems), + "

    This element statically configures addresses for discovery.

    " }, + { LEAF ("ParticipantIndex"), 1, "auto", ABSOFF (participantIndex), 0, uf_participantIndex, 0, pf_participantIndex, + "

    This element specifies the DDSI participant index used by this instance of the DDSI2E service for discovery purposes. Only one such participant id is used, independent of the number of actual DomainParticipants on the node. It is either:

    \n\ +
    • auto: which will attempt to automatically determine an available participant index (see also Discovery/MaxAutoParticipantIndex), or
    • \n\ +
    • a non-negative integer less than 120, or
    • \n\ +
    • none:, which causes it to use arbitrary port numbers for unicast sockets which entirely removes the constraints on the participant index but makes unicast discovery impossible.
    \n\ +

    The default is auto. The participant index is part of the port number calculation and if predictable port numbers are needed and fixing the participant index has no adverse effects, it is recommended that the second be option be used.

    " }, + { LEAF ("MaxAutoParticipantIndex"), 1, "9", ABSOFF (maxAutoParticipantIndex), 0, uf_natint, 0, pf_int, + "

    This element specifies the maximum DDSI participant index selected by this instance of the DDSI2E service if the Discovery/ParticipantIndex is \"auto\".

    " }, + { LEAF ("SPDPMulticastAddress"), 1, "239.255.0.1", ABSOFF (spdpMulticastAddressString), 0, uf_ipv4, ff_free, pf_string, + "

    This element specifies the multicast address that is used as the destination for the participant discovery packets. In IPv4 mode the default is the (standardised) 239.255.0.1, in IPv6 mode it becomes ff02::ffff:239.255.0.1, which is a non-standardised link-local multicast address.

    " }, + { LEAF ("SPDPInterval"), 1, "30 s", ABSOFF (spdp_interval), 0, uf_duration_ms_1hr, 0, pf_duration, + "

    This element specifies the interval between spontaneous transmissions of participant discovery packets.

    " }, + { LEAF ("DefaultMulticastAddress"), 1, "auto", ABSOFF (defaultMulticastAddressString), 0, uf_networkAddress, 0, pf_networkAddress, + "

    This element specifies the default multicast address for all traffic other than participant discovery packets. It defaults to Discovery/SPDPMulticastAddress.

    " }, + { GROUP ("Ports", discovery_ports_cfgelems), + "

    The Ports element allows specifying various parameters related to the port numbers used for discovery. These all have default values specified by the DDSI 2.1 (and 2.2) specification and rarely need to be changed.

    " }, + END_MARKER +}; + +static const struct cfgelem tracing_cfgelems[] = { + { LEAF ("EnableCategory"), 1, "", 0, 0, 0, uf_logcat, 0, pf_logcat, + "

    This element enables individual logging categories. These are enabled in addition to those enabled by Tracing/Verbosity. Recognised categories are:

    \n\ +
    • fatal: all fatal errors, errors causing immediate termination
    • \n\ +
    • error: failures probably impacting correctness but not necessarily causing immediate termination
    • \n\ +
    • warning: abnormal situations that will likely not impact correctness
    • \n\ +
    • config: full dump of the configuration
    • \n\ +
    • info: general informational notices
    • \n\ +
    • discovery: all discovery activity
    • \n\ +
    • data: include data content of samples in traces
    • \n\ +
    • radmin: receive buffer administration
    • \n\ +
    • timing: periodic reporting of CPU loads per thread
    • \n\ +
    • traffic: periodic reporting of total outgoing data
    • \n\ +
    • whc: tracing of writer history cache changes
    • \n\ +
    • tcp: tracing of TCP-specific activity
    • \n\ +
    • topic: tracing of topic definitions
    • \n\ +
    • >i>plist: tracing of discovery parameter list interpretation
    \n\ +

    In addition, there is the keyword trace that enables all but radmin, topic, plist and whc

    .\n\ +

    The categorisation of tracing output is incomplete and hence most of the verbosity levels and categories are not of much use in the current release. This is an ongoing process and here we describe the target situation rather than the current situation. Currently, the most useful is trace.

    " }, +#if LITE + { LEAF ("Verbosity"), 1, "none", 0, 0, 0, uf_verbosity, 0, pf_nop, + "

    This element enables standard groups of categories, based on a desired verbosity level. This is in addition to the categories enabled by the Tracing/EnableCategory setting. Recognised verbosity levels and the categories they map to are:

    \n\ +
    • none: no DDSI2E log
    • \n\ +
    • severe: error and fatal
    • \n\ +
    • warning: severe + warning
    • \n\ +
    • info: warning + info
    • \n\ +
    • config: info + config
    • \n\ +
    • fine: config + discovery
    • \n\ +
    • finer: fine + traffic and timing
    • \n\ +
    • finest: finer + trace
    \n\ +

    While none prevents any message from being written to a DDSI2 log file.

    \n\ +

    The categorisation of tracing output is incomplete and hence most of the verbosity levels and categories are not of much use in the current release. This is an ongoing process and here we describe the target situation rather than the current situation. Currently, the most useful verbosity levels are config, fine and finest.

    " }, + { LEAF ("OutputFile"), 1, "lite.log", ABSOFF (tracingOutputFileName), 0, uf_tracingOutputFileName, ff_free, pf_string, + "

    This option specifies where the logging is printed to. Note that stdout and stderr are treated as special values, representing \"standard out\" and \"standard error\" respectively. No file is created unless logging categories are enabled using the Tracing/Verbosity or Tracing/EnabledCategory settings.

    " }, +#else + { LEAF ("Verbosity"), 1, "none", 0, 0, 0, uf_verbosity, 0, pf_nop, + "

    This element enables standard groups of categories, based on a desired verbosity level. This is in addition to the categories enabled by the Tracing/EnableCategory setting. Recognised verbosity levels and the categories they map to are:

    \n\ +
    • none: no DDSI2E log
    • \n\ +
    • severe: error and fatal
    • \n\ +
    • warning: severe + warning
    • \n\ +
    • info: warning + info
    • \n\ +
    • config: info + config
    • \n\ +
    • fine: config + discovery
    • \n\ +
    • finer: fine + traffic and timing
    • \n\ +
    • finest: finer + trace
    \n\ +

    The categorisation of tracing output is incomplete and hence most of the verbosity levels and categories are not of much use in the current release. This is an ongoing process and here we describe the target situation rather than the current situation. Currently, the most useful verbosity levels are config, fine and finest.

    " }, + { LEAF ("OutputFile"), 1, "ddsi2.log", ABSOFF (tracingOutputFileName), 0, uf_tracingOutputFileName, ff_free, pf_string, + "

    This option specifies where the logging is printed to. Note that stdout and stderr are treated as special values, representing \"standard out\" and \"standard error\" respectively. No file is created unless logging categories are enabled using the Tracing/Verbosity or Tracing/EnabledCategory settings.

    "}, +#endif + { LEAF_W_ATTRS ("Timestamps", timestamp_cfgattrs), 1, "true", ABSOFF (tracingTimestamps), 0, uf_boolean, 0, pf_boolean, + "

    This option has no effect.

    " }, + { LEAF ("AppendToFile"), 1, "false", ABSOFF (tracingAppendToFile), 0, uf_boolean, 0, pf_boolean, + "

    This option specifies whether the output is to be appended to an existing log file. The default is to create a new log file each time, which is generally the best option if a detailed log is generated.

    " }, + { LEAF ("PacketCaptureFile"), 1, "", ABSOFF (pcap_file), 0, uf_string, ff_free, pf_string, + "

    This option specifies the file to which received and sent packets will be logged in the \"pcap\" format suitable for analysis using common networking tools, such as WireShark. IP and UDP headers are ficitious, in particular the destination address of received packets. The TTL may be used to distinguish between sent and received packets: it is 255 for sent packets and 128 for received ones. Currently IPv4 only.

    " }, + END_MARKER +}; + +static const struct cfgelem sched_prio_cfgattrs[] = { + { ATTR ("priority_kind"), 1, "relative", ABSOFF (watchdog_sched_priority_class), 0, uf_sched_prio_class, 0, pf_sched_prio_class, + "

    This attribute specifies whether the specified Priority is a relative or absolute priority.

    " }, + END_MARKER +}; + +static const struct cfgelem sched_cfgelems[] = { + { LEAF ("Class"), 1, "default", ABSOFF (watchdog_sched_class), 0, uf_sched_class, 0, pf_sched_class, + "

    This element specifies the thread scheduling class that will be used by the watchdog thread. The user may need the appropriate privileges from the underlying operating system to be able to assign some of the privileged scheduling classes.

    " }, + { LEAF_W_ATTRS ("Priority", sched_prio_cfgattrs), 1, "0", ABSOFF (watchdog_sched_priority), 0, uf_int32, 0, pf_int32, + "

    This element specifies the thread priority. Only priorities that are supported by the underlying operating system can be assigned to this element. The user may need special privileges from the underlying operating system to be able to assign some of the privileged priorities.

    " }, + END_MARKER +}; + +static const struct cfgelem watchdog_cfgelems[] = { + { GROUP ("Scheduling", sched_cfgelems), + "

    This element specifies the type of OS scheduling class will be used by the thread that announces its liveliness periodically.

    " }, + END_MARKER +}; + +static const struct cfgelem ddsi2_cfgelems[] = { + { GROUP ("General", general_cfgelems), + "

    The General element specifies overall DDSI2E service settings.

    " }, +#ifdef DDSI_INCLUDE_ENCRYPTION + { GROUP ("Security", security_cfgelems), + "

    The Security element specifies DDSI2E security profiles that can be used to encrypt traffic mapped to DDSI2E network partitions.

    " }, +#endif +#ifdef DDSI_INCLUDE_NETWORK_PARTITIONS + { GROUP ("Partitioning", partitioning_cfgelems), + "

    The Partitioning element specifies DDSI2E network partitions and how DCPS partition/topic combinations are mapped onto the network partitions.

    " }, +#endif +#ifdef DDSI_INCLUDE_NETWORK_CHANNELS + { GROUP ("Channels", channels_cfgelems), + "

    This element is used to group a set of channels. The channels are independent data paths through DDSI2E and by using separate threads and setting their priorities appropriately, chanenls can be used to map transport priorities to operating system scheduler priorities, ensuring system-wide end-to-end priority preservation.

    "}, +#endif + { GROUP ("Threads", threads_cfgelems), + "

    This element is used to set thread properties.

    " }, + { GROUP ("Sizing", sizing_cfgelems), + "

    The Sizing element specifies a variety of configuration settings dealing with expected system sizes, buffer sizes, &c.

    " }, + { GROUP ("Compatibility", compatibility_cfgelems), + "

    The Compatibility elements allows specifying various settings related to compatability with standards and with other DDSI implementations.

    " }, + { GROUP ("Discovery", discovery_cfgelems), + "

    The Discovery element allows specifying various parameters related to the discovery of peers.

    " }, + { GROUP ("Tracing", tracing_cfgelems), + "

    The Tracing element controls the amount and type of information that is written into the tracing log by the DDSI service. This is useful to track the DDSI service during application development.

    " }, + { GROUP ("Internal|Unsupported", unsupp_cfgelems), + "

    The Internal elements deal with a variety of settings that evolving and that are not necessarily fully supported. For the vast majority of the Internal settings, the functionality per-se is supported, but the right to change the way the options control the functionality is reserved. This includes renaming or moving options.

    " }, + { GROUP ("Watchdog", watchdog_cfgelems), + "

    This element specifies the type of OS scheduling class will be used by the thread that announces its liveliness periodically.

    " }, + { GROUP ("TCP", tcp_cfgelems), + "

    The TCP element allows specifying various parameters related to running DDSI over TCP.

    " }, + { GROUP ("ThreadPool", tp_cfgelems), + "

    The ThreadPool element allows specifying various parameters related to using a thread pool to send DDSI messages to multiple unicast addresses (TCP or UDP).

    " }, +#ifdef DDSI_INCLUDE_SSL + { GROUP ("SSL", ssl_cfgelems), + "

    The SSL element allows specifying various parameters related to using SSL/TLS for DDSI over TCP.

    " }, +#endif + END_MARKER +}; + +/* Note: using 2e-1 instead of 0.2 to avoid use of the decimal + separator, which is locale dependent. */ +static const struct cfgelem lease_expiry_time_cfgattrs[] = { + { ATTR ("update_factor"), 1, "2e-1", ABSOFF (servicelease_update_factor), 0, uf_float, 0, pf_float, NULL }, + END_MARKER +}; + +static const struct cfgelem lease_cfgelems[] = { + { LEAF_W_ATTRS ("ExpiryTime", lease_expiry_time_cfgattrs), 1, "10", ABSOFF (servicelease_expiry_time), 0, uf_float, 0, pf_float, NULL }, + END_MARKER +}; + +#if LITE + +static const struct cfgelem domain_cfgelems[] = { + { GROUP ("Lease", lease_cfgelems), NULL }, + { LEAF ("Id"), 1, "0", ABSOFF (domainId), 0, uf_domainId, 0, pf_int, NULL }, + WILDCARD, + END_MARKER +}; + +static const struct cfgelem durability_cfgelems[] = { + { LEAF ("Encoding"), 1, "CDR_CLIENT", ABSOFF (durability_cdr), 0, uf_durability_cdr, 0, pf_durability_cdr, NULL }, + END_MARKER +}; + +static const struct cfgelem root_cfgelems[] = { + { "Domain", domain_cfgelems, NULL, NODATA, NULL }, + { "DDSI2E", ddsi2_cfgelems, NULL, NODATA, NULL }, + { "Durability", durability_cfgelems, NULL, NODATA, NULL }, + { "Lease", lease_cfgelems, NULL, NODATA, NULL }, + END_MARKER +}; + +static const struct cfgelem lite_root_cfgelems[] = +{ + { "Lite", root_cfgelems, NULL, NODATA, NULL }, + END_MARKER +}; + +static const struct cfgelem root_cfgelem = + { "root", lite_root_cfgelems, NULL, NODATA, NULL }; + +#else + +static const struct cfgelem domain_cfgelems[] = { + { GROUP ("Lease", lease_cfgelems), NULL }, + { LEAF ("Id"), 1, "0", ABSOFF (domainId), 0, uf_domainId, 0, pf_int, NULL }, + WILDCARD, + END_MARKER +}; + +static const struct cfgelem ddsi2_cfgattrs[] = { + { ATTR ("name"), 1, NULL, ABSOFF (servicename), 0, uf_service_name, ff_free, pf_string, + "

    This attribute identifies the configuration for the DDSI2E Service. Multiple DDSI2E service configurations can be specified in one single resource. The actual applicable configuration is determined by the value of the name attribute, which must match the specified under the element OpenSplice/Domain/Service[@name] in the Domain Service configuration.

    " }, + END_MARKER +}; + +static const struct cfgelem root_cfgelems[] = { + { "DDSI2EService|DDSI2Service", ddsi2_cfgelems, ddsi2_cfgattrs, NODATA, + "

    The root element of a DDSI2E networking service configuration.

    "}, + { "Lease", lease_cfgelems, NULL, NODATA, NULL }, + { "Domain", domain_cfgelems, NULL, NODATA, NULL }, + END_MARKER +}; + +static const struct cfgelem root_cfgelem = + { "root", root_cfgelems, NULL, NODATA, NULL }; + +#endif + +#undef ATTR +#undef GROUP +#undef LEAF_W_ATTRS +#undef LEAF +#undef WILDCARD +#undef END_MARKER +#undef NODATA +#undef RELOFF +#undef ABSOFF +#undef CO + +struct config config; +struct ddsi_plugin ddsi_plugin; + +static const struct unit unittab_duration[] = { + { "ns", 1 }, + { "us", 1000 }, + { "ms", T_MILLISECOND }, + { "s", T_SECOND }, + { "min", 60 * T_SECOND }, + { "hr", 3600 * T_SECOND }, + { "day", 24 * 3600 * T_SECOND }, + { NULL, 0 } +}; + +/* note: order affects whether printed as KiB or kB, for consistency + with bandwidths and pedanticness, favour KiB. */ +static const struct unit unittab_memsize[] = { + { "B", 1 }, + { "KiB", 1024 }, + { "kB", 1024 }, + { "MiB", 1048576 }, + { "MB", 1048576 }, + { "GiB", 1073741824 }, + { "GB", 1073741824 }, + { NULL, 0 } +}; + +#ifdef DDSI_INCLUDE_BANDWIDTH_LIMITING +static const struct unit unittab_bandwidth_bps[] = { + { "b/s", 1 }, { "bps", 1 }, + { "Kib/s", 1024 }, { "Kibps", 1024 }, + { "kb/s", 1000 }, { "kbps", 1000 }, + { "Mib/s", 1048576 }, { "Mibps", 1000 }, + { "Mb/s", 1000000 }, { "Mbps", 1000000 }, + { "Gib/s", 1073741824 }, { "Gibps", 1073741824 }, + { "Gb/s", 1000000000 }, { "Gbps", 1000000000 }, + { "B/s", 8 }, { "Bps", 8 }, + { "KiB/s", 8 * 1024 }, { "KiBps", 8 * 1024 }, + { "kB/s", 8 * 1000 }, { "kBps", 8 * 1000 }, + { "MiB/s", 8 * 1048576 }, { "MiBps", 8 * 1048576 }, + { "MB/s", 8 * 1000000 }, { "MBps", 8 * 1000000 }, + { "GiB/s", 8 * (os_int64) 1073741824 }, { "GiBps", 8 * (os_int64) 1073741824 }, + { "GB/s", 8 * (os_int64) 1000000000 }, { "GBps", 8 * (os_int64) 1000000000 }, + { NULL, 0 } +}; + +static const struct unit unittab_bandwidth_Bps[] = { + { "B/s", 1 }, { "Bps", 1 }, + { "KiB/s", 1024 }, { "KiBps", 1024 }, + { "kB/s", 1000 }, { "kBps", 1000 }, + { "MiB/s", 1048576 }, { "MiBps", 1048576 }, + { "MB/s", 1000000 }, { "MBps", 1000000 }, + { "GiB/s", 1073741824 }, { "GiBps", 1073741824 }, + { "GB/s", 1000000000 }, { "GBps", 1000000000 }, + { NULL, 0 } +}; +#endif + +static void cfgst_push (struct cfgst *cfgst, int isattr, const struct cfgelem *elem, void *parent) +{ + assert (cfgst->path_depth < MAX_PATH_DEPTH); + assert (isattr == 0 || isattr == 1); + cfgst->isattr[cfgst->path_depth] = isattr; + cfgst->path[cfgst->path_depth] = elem; + cfgst->parent[cfgst->path_depth] = parent; + cfgst->path_depth++; +} + +static void cfgst_pop (struct cfgst *cfgst) +{ + assert (cfgst->path_depth > 0); + cfgst->path_depth--; +} + +static const struct cfgelem *cfgst_tos (const struct cfgst *cfgst) +{ + assert (cfgst->path_depth > 0); + return cfgst->path[cfgst->path_depth-1]; +} + +static void *cfgst_parent (const struct cfgst *cfgst) +{ + assert (cfgst->path_depth > 0); + return cfgst->parent[cfgst->path_depth-1]; +} + +struct cfg_note_buf { + size_t bufpos; + size_t bufsize; + char *buf; +}; + +static size_t cfg_note_vsnprintf (struct cfg_note_buf *bb, const char *fmt, va_list ap) +{ + int x; + x = os_vsnprintf (bb->buf + bb->bufpos, bb->bufsize - bb->bufpos, fmt, ap); + if (x >= 0 && (size_t) x >= bb->bufsize - bb->bufpos) + { + size_t nbufsize = ((bb->bufsize + (size_t)x+1) + 1023) & (size_t)(-1024); + char *nbuf = os_realloc (bb->buf, nbufsize); + bb->buf = nbuf; + bb->bufsize = nbufsize; + return nbufsize; + } + if (x < 0) + NN_FATAL0 ("cfg_note_vsnprintf: os_vsnprintf failed\n"); + else + bb->bufpos += (size_t)x; + return 0; +} + +static void cfg_note_snprintf (struct cfg_note_buf *bb, const char *fmt, ...) +{ + /* The reason the 2nd call to os_vsnprintf is here and not inside + cfg_note_vsnprintf is because I somehow doubt that all platforms + implement va_copy() */ + va_list ap; + size_t r; + va_start (ap, fmt); + r = cfg_note_vsnprintf (bb, fmt, ap); + va_end (ap); + if (r > 0) + { + int s; + va_start (ap, fmt); + s = os_vsnprintf (bb->buf + bb->bufpos, bb->bufsize - bb->bufpos, fmt, ap); + if (s < 0 || (size_t)s >= bb->bufsize - bb->bufpos) + NN_FATAL0 ("cfg_note_snprintf: os_vsnprintf failed\n"); + va_end (ap); + bb->bufpos += (size_t)s; + } +} + +static size_t cfg_note (struct cfgst *cfgst, logcat_t cat, size_t bsz, const char *fmt, va_list ap) +{ + /* Have to snprintf our way to a single string so we can OS_REPORT + as well as nn_log. Otherwise configuration errors will be lost + completely on platforms where stderr doesn't actually work for + outputting error messages (this includes Windows because of the + way "ospl start" does its thing). */ + struct cfg_note_buf bb; + int i, sidx; + size_t r; + + bb.bufpos = 0; + bb.bufsize = (bsz == 0) ? 1024 : bsz; + if ((bb.buf = os_malloc (bb.bufsize)) == NULL) + NN_FATAL0 ("cfg_note: out of memory\n"); + + cfg_note_snprintf (&bb, "config: "); + + /* Path to element/attribute causing the error. Have to stop once an + attribute is reached: a NULL marker may have been pushed onto the + stack afterward in the default handling. */ + sidx = 0; + while (sidx < cfgst->path_depth && cfgst->path[sidx]->name == NULL) + sidx++; + for (i = sidx; i < cfgst->path_depth && (i == sidx || !cfgst->isattr[i-1]); i++) + { + if (cfgst->path[i] == NULL) + { + assert (i > sidx); + cfg_note_snprintf (&bb, "/#text"); + } + else if (cfgst->isattr[i]) + { + cfg_note_snprintf (&bb, "[@%s]", cfgst->path[i]->name); + } + else + { + const char *p = strchr (cfgst->path[i]->name, '|'); + int n = p ? (int) (p - cfgst->path[i]->name) : (int) strlen (cfgst->path[i]->name); + cfg_note_snprintf (&bb, "%s%*.*s", (i == sidx) ? "" : "/", n, n, cfgst->path[i]->name); + } + } + + cfg_note_snprintf (&bb, ": "); + if ((r = cfg_note_vsnprintf (&bb, fmt, ap)) > 0) + { + /* Can't reset ap ... and va_copy isn't widely available - so + instead abort and hope the caller tries again with a larger + initial buffer */ + os_free (bb.buf); + return r; + } + + switch (cat) + { + case LC_CONFIG: + nn_log (cat, "%s\n", bb.buf); + break; + case LC_WARNING: + NN_WARNING1 ("%s\n", bb.buf); + break; + case LC_ERROR: + NN_ERROR1 ("%s\n", bb.buf); + break; + default: + NN_FATAL2 ("cfg_note unhandled category %u for message %s\n", (unsigned) cat, bb.buf); + break; + } + + os_free (bb.buf); + return 0; +} + +#if WARN_DEPRECATED_ALIAS || WARN_DEPRECATED_UNIT +static void cfg_warning (struct cfgst *cfgst, const char *fmt, ...) +{ + va_list ap; + size_t bsz = 0; + do { + va_start (ap, fmt); + bsz = cfg_note (cfgst, LC_WARNING, bsz, fmt, ap); + va_end (ap); + } while (bsz > 0); +} +#endif + +static int cfg_error (struct cfgst *cfgst, const char *fmt, ...) +{ + va_list ap; + size_t bsz = 0; + do { + va_start (ap, fmt); + bsz = cfg_note (cfgst, LC_ERROR, bsz, fmt, ap); + va_end (ap); + } while (bsz > 0); + return 0; +} + +static int cfg_log (struct cfgst *cfgst, const char *fmt, ...) +{ + va_list ap; + size_t bsz = 0; + do { + va_start (ap, fmt); + bsz = cfg_note (cfgst, LC_CONFIG, bsz, fmt, ap); + va_end (ap); + } while (bsz > 0); + return 0; +} + +static int list_index (const char *list[], const char *elem) +{ + int i; + for (i = 0; list[i] != NULL; i++) + { + if (os_strcasecmp (list[i], elem) == 0) + return i; + } + return -1; +} + +static os_int64 lookup_multiplier (struct cfgst *cfgst, const struct unit *unittab, const char *value, int unit_pos, int value_is_zero, os_int64 def_mult, int err_on_unrecognised) +{ + assert (0 <= unit_pos && (os_size_t) unit_pos <= strlen (value)); + while (value[unit_pos] == ' ') + unit_pos++; + if (value[unit_pos] == 0) + { + if (value_is_zero) + { + /* No matter what unit, 0 remains just that. For convenience, + always allow 0 to be specified without a unit */ + return 1; + } + else if (def_mult == 0 && err_on_unrecognised) + { + cfg_error (cfgst, "%s: unit is required", value); + return 0; + } + else + { +#if WARN_DEPRECATED_UNIT + cfg_warning (cfgst, "%s: use of default unit is deprecated", value); +#endif + return def_mult; + } + } + else + { + int i; + for (i = 0; unittab[i].name != NULL; i++) + { + if (strcmp (unittab[i].name, value + unit_pos) == 0) + return unittab[i].multiplier; + } + if (err_on_unrecognised) + cfg_error (cfgst, "%s: unrecognised unit", value + unit_pos); + return 0; + } +} + +static void *cfg_address (UNUSED_ARG (struct cfgst *cfgst), void *parent, struct cfgelem const * const cfgelem) +{ + assert (cfgelem->multiplicity == 1); + return (char *) parent + cfgelem->elem_offset; +} + +static void *cfg_deref_address (UNUSED_ARG (struct cfgst *cfgst), void *parent, struct cfgelem const * const cfgelem) +{ + assert (cfgelem->multiplicity != 1); + return *((void **) ((char *) parent + cfgelem->elem_offset)); +} + +static void *if_common (UNUSED_ARG (struct cfgst *cfgst), void *parent, struct cfgelem const * const cfgelem, unsigned size) +{ + struct config_listelem **current = (struct config_listelem **) ((char *) parent + cfgelem->elem_offset); + struct config_listelem *new = os_malloc (size); + new->next = *current; + *current = new; + return new; +} + +static int if_thread_properties (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem) +{ + struct config_thread_properties_listelem *new = if_common (cfgst, parent, cfgelem, sizeof (*new)); + if (new == NULL) + return -1; + new->name = NULL; + return 0; +} + +#ifdef DDSI_INCLUDE_NETWORK_CHANNELS +static int if_channel (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem) +{ + struct config_channel_listelem *new = if_common (cfgst, parent, cfgelem, sizeof (*new)); + if (new == NULL) + return -1; + new->name = NULL; + new->channel_reader_ts = NULL; + new->dqueue = NULL; + new->queueId = 0; + new->evq = NULL; + new->transmit_conn = NULL; + return 0; +} +#endif /* DDSI_INCLUDE_NETWORK_CHANNELS */ + +#ifdef DDSI_INCLUDE_ENCRYPTION +static int if_security_profile (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem) +{ + if (if_common (cfgst, parent, cfgelem, sizeof (struct config_securityprofile_listelem)) == NULL) + return -1; + return 0; +} +#endif /* DDSI_INCLUDE_ENCRYPTION */ + +#ifdef DDSI_INCLUDE_NETWORK_PARTITIONS +static int if_network_partition (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem) +{ + struct config_networkpartition_listelem *new = if_common (cfgst, parent, cfgelem, sizeof (*new)); + if (new == NULL) + return -1; + new->address_string = NULL; +#ifdef DDSI_INCLUDE_ENCRYPTION + new->profileName = NULL; + new->securityProfile = NULL; +#endif /* DDSI_INCLUDE_ENCRYPTION */ + return 0; +} + +static int if_ignored_partition (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem) +{ + if (if_common (cfgst, parent, cfgelem, sizeof (struct config_ignoredpartition_listelem)) == NULL) + return -1; + return 0; +} + +static int if_partition_mapping (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem) +{ + if (if_common (cfgst, parent, cfgelem, sizeof (struct config_partitionmapping_listelem)) == NULL) + return -1; + return 0; +} +#endif /* DDSI_INCLUDE_NETWORK_PARTITIONS */ + +static int if_peer (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem) +{ + struct config_peer_listelem *new = if_common (cfgst, parent, cfgelem, sizeof (struct config_peer_listelem)); + if (new == NULL) + return -1; + new->peer = NULL; + return 0; +} + +static void ff_free (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem) +{ + void **elem = cfg_address (cfgst, parent, cfgelem); + os_free (*elem); +} + +static int uf_boolean (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, UNUSED_ARG (int first), const char *value) +{ + static const char *vs[] = { "false", "true", NULL }; + int *elem = cfg_address (cfgst, parent, cfgelem); + int idx = list_index (vs, value); + if (idx < 0) + return cfg_error (cfgst, "'%s': undefined value", value); + else + { + *elem = idx; + return 1; + } +} + +static int uf_negated_boolean (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int first, const char *value) +{ + if (!uf_boolean (cfgst, parent, cfgelem, first, value)) + return 0; + else + { + int *elem = cfg_address (cfgst, parent, cfgelem); + *elem = ! *elem; + return 1; + } +} + +#if ! LITE +static int uf_boolean_default (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, UNUSED_ARG (int first), const char *value) +{ + static const char *vs[] = { "default", "false", "true", NULL }; + static const enum boolean_default ms[] = { + BOOLDEF_DEFAULT, BOOLDEF_FALSE, BOOLDEF_TRUE, 0, + }; + int *elem = cfg_address (cfgst, parent, cfgelem); + int idx = list_index (vs, value); + assert (sizeof (vs) / sizeof (*vs) == sizeof (ms) / sizeof (*ms)); + if (idx < 0) + return cfg_error (cfgst, "'%s': undefined value", value); + *elem = ms[idx]; + return 1; +} + +static void pf_boolean_default (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int is_default) +{ + enum besmode *p = cfg_address (cfgst, parent, cfgelem); + const char *str = "INVALID"; + switch (*p) + { + case BOOLDEF_DEFAULT: str = "default"; break; + case BOOLDEF_FALSE: str = "false"; break; + case BOOLDEF_TRUE: str = "true"; break; + } + cfg_log (cfgst, "%s%s", str, is_default ? " [def]" : ""); +} +#endif + +static int uf_logcat (struct cfgst *cfgst, UNUSED_ARG (void *parent), UNUSED_ARG (struct cfgelem const * const cfgelem), UNUSED_ARG (int first), const char *value) +{ + static const char **vs = logcat_names; + static const logcat_t *lc = logcat_codes; + char *copy = os_strdup (value), *cursor = copy, *tok; + while ((tok = os_strsep (&cursor, ",")) != NULL) + { + int idx = list_index (vs, tok); + if (idx < 0) + { + int ret = cfg_error (cfgst, "'%s' in '%s' undefined", tok, value); + os_free (copy); + return ret; + } + enabled_logcats |= lc[idx]; + } + os_free (copy); + return 1; +} + +static int uf_verbosity (struct cfgst *cfgst, UNUSED_ARG (void *parent), UNUSED_ARG (struct cfgelem const * const cfgelem), UNUSED_ARG (int first), const char *value) +{ + static const char *vs[] = { + "finest", "finer", "fine", "config", "info", "warning", "severe", "none", NULL + }; + static const logcat_t lc[] = { + LC_ALLCATS, LC_TRAFFIC | LC_TIMING, LC_DISCOVERY | LC_THROTTLE, LC_CONFIG, LC_INFO, LC_WARNING, LC_ERROR | LC_FATAL, 0, 0 + }; + int idx = list_index (vs, value); + assert (sizeof (vs) / sizeof (*vs) == sizeof (lc) / sizeof (*lc)); + if (idx < 0) + return cfg_error (cfgst, "'%s': undefined value", value); + else + { + int i; + for (i = (int) (sizeof (vs) / sizeof (*vs)) - 1; i >= idx; i--) + enabled_logcats |= lc[i]; + return 1; + } +} + +static int uf_besmode (struct cfgst *cfgst, UNUSED_ARG (void *parent), UNUSED_ARG (struct cfgelem const * const cfgelem), UNUSED_ARG (int first), const char *value) +{ + static const char *vs[] = { + "full", "writers", "minimal", NULL + }; + static const enum besmode ms[] = { + BESMODE_FULL, BESMODE_WRITERS, BESMODE_MINIMAL, 0, + }; + int idx = list_index (vs, value); + enum besmode *elem = cfg_address (cfgst, parent, cfgelem); + assert (sizeof (vs) / sizeof (*vs) == sizeof (ms) / sizeof (*ms)); + if (idx < 0) + return cfg_error (cfgst, "'%s': undefined value", value); + *elem = ms[idx]; + return 1; +} + +static void pf_besmode (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int is_default) +{ + enum besmode *p = cfg_address (cfgst, parent, cfgelem); + const char *str = "INVALID"; + switch (*p) + { + case BESMODE_FULL: str = "full"; break; + case BESMODE_WRITERS: str = "writers"; break; + case BESMODE_MINIMAL: str = "minimal"; break; + } + cfg_log (cfgst, "%s%s", str, is_default ? " [def]" : ""); +} + +#if LITE + +static int uf_durability_cdr (struct cfgst *cfgst, UNUSED_ARG (void *parent), UNUSED_ARG (struct cfgelem const * const cfgelem), UNUSED_ARG (int first), const char *value) +{ + static const char *vs[] = { "cdr_le", "cdr_be", "cdr_server", "cdr_client", NULL }; + static const enum durability_cdr ms[] = { DUR_CDR_LE, DUR_CDR_BE, DUR_CDR_SERVER, DUR_CDR_CLIENT, 0 }; + int idx = list_index (vs, value); + enum durability_cdr * elem = cfg_address (cfgst, parent, cfgelem); + if (idx < 0) + { + return cfg_error (cfgst, "'%s': undefined value", value); + } + *elem = ms[idx]; + return 1; +} + +static void pf_durability_cdr (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int is_default) +{ + enum durability_cdr *p = cfg_address (cfgst, parent, cfgelem); + const char *str = "INVALID"; + switch (*p) + { + case DUR_CDR_LE: str = "cdr_le"; break; + case DUR_CDR_BE: str = "cdr_be"; break; + case DUR_CDR_SERVER: str = "cdr_server"; break; + case DUR_CDR_CLIENT: str = "cdr_client"; break; + } + cfg_log (cfgst, "%s%s", str, is_default ? " [def]" : ""); +} + +#endif + +static int uf_retransmit_merging (struct cfgst *cfgst, UNUSED_ARG (void *parent), UNUSED_ARG (struct cfgelem const * const cfgelem), UNUSED_ARG (int first), const char *value) +{ + static const char *vs[] = { + "never", "adaptive", "always", NULL + }; + static const enum retransmit_merging ms[] = { + REXMIT_MERGE_NEVER, REXMIT_MERGE_ADAPTIVE, REXMIT_MERGE_ALWAYS, 0, + }; + int idx = list_index (vs, value); + enum retransmit_merging *elem = cfg_address (cfgst, parent, cfgelem); + assert (sizeof (vs) / sizeof (*vs) == sizeof (ms) / sizeof (*ms)); + if (idx < 0) + return cfg_error (cfgst, "'%s': undefined value", value); + *elem = ms[idx]; + return 1; +} + +static void pf_retransmit_merging (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int is_default) +{ + enum retransmit_merging *p = cfg_address (cfgst, parent, cfgelem); + const char *str = "INVALID"; + switch (*p) + { + case REXMIT_MERGE_NEVER: str = "never"; break; + case REXMIT_MERGE_ADAPTIVE: str = "adaptive"; break; + case REXMIT_MERGE_ALWAYS: str = "always"; break; + } + cfg_log (cfgst, "%s%s", str, is_default ? " [def]" : ""); +} + +static int uf_string (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, UNUSED_ARG (int first), const char *value) +{ + char **elem = cfg_address (cfgst, parent, cfgelem); + *elem = os_strdup (value); + return 1; +} + +static int uf_natint64_unit (struct cfgst *cfgst, os_int64 *elem, const char *value, const struct unit *unittab, os_int64 def_mult, os_int64 max) +{ + int pos; + double v_dbl; + os_int64 v_int; + os_int64 mult; + /* try convert as integer + optional unit; if that fails, try + floating point + optional unit (round, not truncate, to integer) */ + if (*value == 0) + { + *elem = 0; /* some static analyzers don't "get it" */ + return cfg_error (cfgst, "%s: empty string is not a valid value", value); + } + else if (sscanf (value, "%lld%n", (long long int *) &v_int, &pos) == 1 && (mult = lookup_multiplier (cfgst, unittab, value, pos, v_int == 0, def_mult, 0)) != 0) + { + assert (mult > 0); + if (v_int < 0 || v_int > max / mult) + return cfg_error (cfgst, "%s: value out of range", value); + *elem = mult * v_int; + return 1; + } + else if (sscanf (value, "%lf%n", &v_dbl, &pos) == 1 && (mult = lookup_multiplier (cfgst, unittab, value, pos, v_dbl == 0, def_mult, 1)) != 0) + { + double dmult = (double) mult; + assert (dmult > 0); + if (v_dbl < 0 || (os_int64) (v_dbl * dmult + 0.5) > max) + return cfg_error (cfgst, "%s: value out of range", value); + *elem = (os_int64) (v_dbl * dmult + 0.5); + return 1; + } + else + { + *elem = 0; /* some static analyzers don't "get it" */ + return cfg_error (cfgst, "%s: invalid value", value); + } +} + +#ifdef DDSI_INCLUDE_BANDWIDTH_LIMITING +static int uf_bandwidth (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, UNUSED_ARG (int first), const char *value) +{ + os_int64 bandwidth_bps = 0; + if (strncmp (value, "inf", 3) == 0) { + /* special case: inf needs no unit */ + int *elem = cfg_address (cfgst, parent, cfgelem); + if (strspn (value + 3, " ") != strlen (value + 3) && + lookup_multiplier (cfgst, unittab_bandwidth_bps, value, 3, 1, 8, 1) == 0) + return 0; + *elem = 0; + return 1; + } else if (!uf_natint64_unit (cfgst, &bandwidth_bps, value, unittab_bandwidth_bps, 8, INT64_MAX)) { + return 0; + } else if (bandwidth_bps / 8 > INT_MAX) { + return cfg_error (cfgst, "%s: value out of range", value); + } else { + os_uint32 *elem = cfg_address (cfgst, parent, cfgelem); + *elem = (os_uint32) (bandwidth_bps / 8); + return 1; + } +} +#endif + +static int uf_memsize (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, UNUSED_ARG (int first), const char *value) +{ + os_int64 size = 0; + if (!uf_natint64_unit (cfgst, &size, value, unittab_memsize, 1, INT32_MAX)) + return 0; + else + { + os_uint32 *elem = cfg_address (cfgst, parent, cfgelem); + *elem = (os_uint32) size; + return 1; + } +} + +#ifdef DDSI_INCLUDE_ENCRYPTION +static int uf_cipher (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, UNUSED_ARG (int first), const char *value) +{ + if (q_security_plugin.cipher_type_from_string) + { + q_cipherType *elem = cfg_address (cfgst, parent, cfgelem); + if ((q_security_plugin.cipher_type_from_string) (value, elem)) + { + return 1; + } + else + { + return cfg_error (cfgst, "%s: undefined value", value); + } + } + return 1; +} +#endif /* DDSI_INCLUDE_ENCRYPTION */ + +#if !LITE +static int uf_service_name (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, UNUSED_ARG (int first), const char *value) +{ + char **elem = cfg_address (cfgst, parent, cfgelem); + if (*value == 0) + *elem = os_strdup (cfgst->servicename); + else + *elem = os_strdup (value); + return 1; +} +#endif + +static int uf_tracingOutputFileName (struct cfgst *cfgst, UNUSED_ARG (void *parent), UNUSED_ARG (struct cfgelem const * const cfgelem), UNUSED_ARG (int first), const char *value) +{ + struct config *cfg = cfgst->cfg; +#if !LITE + if (os_strcasecmp (value, "stdout") != 0 && os_strcasecmp (value, "stderr") != 0) + cfg->tracingOutputFileName = os_fileNormalize (value); + else +#endif + { + cfg->tracingOutputFileName = os_strdup (value); + } + return 1; +} + +static int uf_ipv4 (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int first, const char *value) +{ + /* Not actually doing any checking yet */ + return uf_string (cfgst, parent, cfgelem, first, value); +} + +static int uf_networkAddress (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int first, const char *value) +{ + if (os_strcasecmp (value, "auto") != 0) + return uf_ipv4 (cfgst, parent, cfgelem, first, value); + else + { + char **elem = cfg_address (cfgst, parent, cfgelem); + *elem = NULL; + return 1; + } +} + +static void ff_networkAddresses (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem) +{ + char ***elem = cfg_address (cfgst, parent, cfgelem); + int i; + for (i = 0; (*elem)[i]; i++) + os_free ((*elem)[i]); + os_free (*elem); +} + +static int uf_networkAddresses_simple (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, UNUSED_ARG (int first), const char *value) +{ + char ***elem = cfg_address (cfgst, parent, cfgelem); + if ((*elem = os_malloc (2 * sizeof(char *))) == NULL) + return cfg_error (cfgst, "out of memory"); + if (((*elem)[0] = os_strdup (value)) == NULL) + { + os_free (*elem); + *elem = NULL; + return cfg_error (cfgst, "out of memory"); + } + (*elem)[1] = NULL; + return 1; +} + +static int uf_networkAddresses (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int first, const char *value) +{ + /* Check for keywords first */ + { + static const char *keywords[] = { "all", "any", "none" }; + int i; + for (i = 0; i < (int) (sizeof (keywords) / sizeof (*keywords)); i++) + { + if (os_strcasecmp (value, keywords[i]) == 0) + return uf_networkAddresses_simple (cfgst, parent, cfgelem, first, keywords[i]); + } + } + + /* If not keyword, then comma-separated list of addresses */ + { + char ***elem = cfg_address (cfgst, parent, cfgelem); + char *copy; + unsigned count; + + /* First count how many addresses we have - but do it stupidly by + counting commas and adding one (so two commas in a row are both + counted) */ + { + const char *scan = value; + count = 1; + while (*scan) + count += (*scan++ == ','); + } + + copy = os_strdup (value); + + /* Allocate an array of address strings (which may be oversized a + bit because of the counting of the commas) */ + *elem = os_malloc ((count+1) * sizeof (char *)); + + { + char *cursor = copy, *tok; + unsigned idx = 0; + while ((tok = os_strsep (&cursor, ",")) != NULL) + { + assert (idx < count); + (*elem)[idx] = os_strdup (tok); + idx++; + } + (*elem)[idx] = NULL; + } + os_free (copy); + } + return 1; +} + +static int uf_allow_multicast (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, UNUSED_ARG (int first), const char *value) +{ +#ifdef DDSI_INCLUDE_SSM + static const char *vs[] = { "false", "spdp", "asm", "ssm", "true", NULL }; + static const unsigned bs[] = { AMC_FALSE, AMC_SPDP, AMC_ASM, AMC_SSM, AMC_TRUE }; +#else + static const char *vs[] = { "false", "spdp", "asm", "true", NULL }; + static const unsigned bs[] = { AMC_FALSE, AMC_SPDP, AMC_ASM, AMC_TRUE }; +#endif + char *copy = os_strdup (value), *cursor = copy, *tok; + unsigned *elem = cfg_address (cfgst, parent, cfgelem); + if (copy == NULL) + return cfg_error (cfgst, "out of memory"); + *elem = 0; + while ((tok = os_strsep (&cursor, ",")) != NULL) + { + int idx = list_index (vs, tok); + if (idx < 0) + { + int ret = cfg_error (cfgst, "'%s' in '%s' undefined", tok, value); + os_free (copy); + return ret; + } + *elem |= bs[idx]; + } + os_free (copy); + return 1; +} + +static void pf_allow_multicast (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int is_default) +{ + unsigned *p = cfg_address (cfgst, parent, cfgelem); + const char *str = "INVALID"; + switch (*p) + { + case AMC_FALSE: str = "false"; break; + case AMC_SPDP: str = "spdp"; break; + case AMC_ASM: str = "asm"; break; +#ifdef DDSI_INCLUDE_SSM + case AMC_SSM: str = "ssm"; break; + case (AMC_SPDP | AMC_ASM): str = "spdp,asm"; break; + case (AMC_SPDP | AMC_SSM): str = "spdp,ssm"; break; +#endif + case AMC_TRUE: str = "true"; break; + } + cfg_log (cfgst, "%s%s", str, is_default ? " [def]" : ""); +} + +static int uf_sched_prio_class (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem,UNUSED_ARG (int first), const char *value) +{ + int ret; + q__schedPrioClass *prio; + + assert (value != NULL); + + prio = cfg_address (cfgst, parent, cfgelem); + + if (os_strcasecmp (value, "relative") == 0) { + *prio = Q__SCHED_PRIO_RELATIVE; + ret = 1; + } else if (os_strcasecmp (value, "absolute") == 0) { + *prio = Q__SCHED_PRIO_ABSOLUTE; + ret = 1; + } else { + ret = cfg_error (cfgst, "'%s': undefined value", value); + } + + return ret; +} + +static void pf_sched_prio_class (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int is_default) +{ + char *str; + q__schedPrioClass *prio = cfg_address (cfgst, parent, cfgelem); + + if (*prio == Q__SCHED_PRIO_RELATIVE) { + str = "relative"; + } else if (*prio == Q__SCHED_PRIO_ABSOLUTE) { + str = "absolute"; + } else { + str = "INVALID"; + } + + cfg_log (cfgst, "%s%s", str, is_default ? " [def]" : ""); +} + +static int uf_sched_class (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, UNUSED_ARG (int first), const char *value) +{ + static const char *vs[] = { "realtime", "timeshare", "default" }; + static const os_schedClass ms[] = { OS_SCHED_REALTIME, OS_SCHED_TIMESHARE, OS_SCHED_DEFAULT }; + int idx = list_index (vs, value); + os_schedClass *elem = cfg_address (cfgst, parent, cfgelem); + assert (sizeof (vs) / sizeof (*vs) == sizeof (ms) / sizeof (*ms)); + if (idx < 0) + return cfg_error (cfgst, "'%s': undefined value", value); + *elem = ms[idx]; + return 1; +} + +static void pf_sched_class (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int is_default) +{ + os_schedClass *p = cfg_address (cfgst, parent, cfgelem); + const char *str = "INVALID"; + switch (*p) + { + case OS_SCHED_DEFAULT: str = "default"; break; + case OS_SCHED_TIMESHARE: str = "timeshare"; break; + case OS_SCHED_REALTIME: str = "realtime"; break; + } + cfg_log (cfgst, "%s%s", str, is_default ? " [def]" : ""); +} + +static int uf_maybe_int32 (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, UNUSED_ARG (int first), const char *value) +{ + struct config_maybe_int32 *elem = cfg_address (cfgst, parent, cfgelem); + int pos; + if (os_strcasecmp (value, "default") == 0) { + elem->isdefault = 1; + elem->value = 0; + return 1; + } else if (sscanf (value, "%d%n", &elem->value, &pos) == 1 && value[pos] == 0) { + elem->isdefault = 0; + return 1; + } else { + return cfg_error (cfgst, "'%s': neither 'default' nor a decimal integer\n", value); + } +} + +static int uf_maybe_memsize (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, UNUSED_ARG (int first), const char *value) +{ + struct config_maybe_uint32 *elem = cfg_address (cfgst, parent, cfgelem); + os_int64 size = 0; + if (os_strcasecmp (value, "default") == 0) { + elem->isdefault = 1; + elem->value = 0; + return 1; + } else if (!uf_natint64_unit (cfgst, &size, value, unittab_memsize, 1, INT32_MAX)) { + return 0; + } else { + elem->isdefault = 0; + elem->value = (os_uint32) size; + return 1; + } +} + +#if !LITE +static int uf_maybe_duration_inf (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, UNUSED_ARG (int first), const char *value) +{ + struct config_maybe_int64 *elem = cfg_address (cfgst, parent, cfgelem); + if (os_strcasecmp (value, "default") == 0) { + elem->isdefault = 1; + elem->value = 0; + return 1; + } else if (os_strcasecmp (value, "inf") == 0) { + elem->isdefault = 0; + elem->value = T_NEVER; + return 1; + } else if (uf_natint64_unit (cfgst, &elem->value, value, unittab_duration, 0, T_NEVER - 1)) { + elem->isdefault = 0; + return 1; + } else { + return 0; + } +} +#endif + +static int uf_float (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, UNUSED_ARG (int first), const char *value) +{ + float *elem = cfg_address (cfgst, parent, cfgelem); + char *endptr; + float f = os_strtof (value, &endptr); + if (*value == 0 || *endptr != 0) + return cfg_error (cfgst, "%s: not a floating point number", value); + *elem = f; + return 1; +} + +static int uf_int (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, UNUSED_ARG (int first), const char *value) +{ + int *elem = cfg_address (cfgst, parent, cfgelem); + char *endptr; + long v = strtol (value, &endptr, 10); + if (*value == 0 || *endptr != 0) + return cfg_error (cfgst, "%s: not a decimal integer", value); + if (v != (int) v) + return cfg_error (cfgst, "%s: value out of range", value); + *elem = (int) v; + return 1; +} + +static int uf_duration_gen (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, const char *value, os_int64 def_mult, os_int64 max_ns) +{ + return uf_natint64_unit (cfgst, cfg_address (cfgst, parent, cfgelem), value, unittab_duration, def_mult, max_ns); +} + +static int uf_duration_inf (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, UNUSED_ARG (int first), const char *value) +{ + if (os_strcasecmp (value, "inf") == 0) + { + os_int64 *elem = cfg_address (cfgst, parent, cfgelem); + *elem = T_NEVER; + return 1; + } + else + { + return uf_duration_gen (cfgst, parent, cfgelem, value, 0, T_NEVER - 1); + } +} + +static int uf_duration_ms_1hr (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, UNUSED_ARG (int first), const char *value) +{ + return uf_duration_gen (cfgst, parent, cfgelem, value, T_MILLISECOND, 3600 * T_SECOND); +} + +static int uf_duration_ms_1s (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, UNUSED_ARG (int first), const char *value) +{ + return uf_duration_gen (cfgst, parent, cfgelem, value, T_MILLISECOND, T_SECOND); +} + +static int uf_duration_us_1s (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, UNUSED_ARG (int first), const char *value) +{ + return uf_duration_gen (cfgst, parent, cfgelem, value, 1000, T_SECOND); +} + +static int uf_int32 (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, UNUSED_ARG (int first), const char *value) +{ + os_int32 *elem = cfg_address (cfgst, parent, cfgelem); + char *endptr; + long v = strtol (value, &endptr, 10); + if (*value == 0 || *endptr != 0) + return cfg_error (cfgst, "%s: not a decimal integer", value); + if (v != (os_int32) v) + return cfg_error (cfgst, "%s: value out of range", value); + *elem = (os_int32) v; + return 1; +} + +static int uf_uint32 (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, UNUSED_ARG (int first), const char *value) +{ + os_uint32 *elem = cfg_address (cfgst, parent, cfgelem); + char *endptr; + unsigned long v = strtoul (value, &endptr, 10); + if (*value == 0 || *endptr != 0) + return cfg_error (cfgst, "%s: not a decimal integer", value); + if (v != (os_uint32) v) + return cfg_error (cfgst, "%s: value out of range", value); + *elem = (os_uint32) v; + return 1; +} + +static int uf_uint (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, UNUSED_ARG (int first), const char *value) +{ + unsigned *elem = cfg_address (cfgst, parent, cfgelem); + char *endptr; + unsigned long v = strtoul (value, &endptr, 10); + if (*value == 0 || *endptr != 0) + return cfg_error (cfgst, "%s: not a decimal integer", value); + if (v != (unsigned) v) + return cfg_error (cfgst, "%s: value out of range", value); + *elem = (unsigned) v; + return 1; +} + +static int uf_int_min_max (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int first, const char *value, int min, int max) +{ + int *elem = cfg_address (cfgst, parent, cfgelem); + if (!uf_int (cfgst, parent, cfgelem, first, value)) + return 0; + else if (*elem < min || *elem > max) + return cfg_error (cfgst, "%s: out of range", value); + else + return 1; +} + +static int uf_domainId (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int first, const char *value) +{ + return uf_int_min_max (cfgst, parent, cfgelem, first, value, 0, 230); +} + +static int uf_participantIndex (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int first, const char *value) +{ + int *elem = cfg_address (cfgst, parent, cfgelem); + if (os_strcasecmp (value, "auto") == 0) { + *elem = PARTICIPANT_INDEX_AUTO; + return 1; + } else if (os_strcasecmp (value, "none") == 0) { + *elem = PARTICIPANT_INDEX_NONE; + return 1; + } else { + return uf_int_min_max (cfgst, parent, cfgelem, first, value, 0, 120); + } +} + +static int uf_port (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int first, const char *value) +{ + return uf_int_min_max (cfgst, parent, cfgelem, first, value, 1, 65535); +} + +static int uf_dyn_port (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int first, const char *value) +{ + return uf_int_min_max (cfgst, parent, cfgelem, first, value, -1, 65535); +} + +static int uf_natint (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int first, const char *value) +{ + return uf_int_min_max (cfgst, parent, cfgelem, first, value, 0, INT32_MAX); +} + +static int uf_natint_255 (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int first, const char *value) +{ + return uf_int_min_max (cfgst, parent, cfgelem, first, value, 0, 255); +} + +static int do_update (struct cfgst *cfgst, update_fun_t upd, void *parent, struct cfgelem const * const cfgelem, const char *value, int is_default) +{ + struct cfgst_node *n; + struct cfgst_nodekey key; + ut_avlIPath_t np; + int ok; + key.e = cfgelem; + if ((n = ut_avlLookupIPath (&cfgst_found_treedef, &cfgst->found, &key, &np)) == NULL) + { + if ((n = os_malloc (sizeof (*n))) == NULL) + return cfg_error (cfgst, "out of memory"); + + n->key = key; + n->count = 0; + n->failed = 0; + n->is_default = is_default; + ut_avlInsertIPath (&cfgst_found_treedef, &cfgst->found, n, &np); + } + if (cfgelem->multiplicity == 0 || n->count < cfgelem->multiplicity) + ok = upd (cfgst, parent, cfgelem, (n->count == n->failed), value); + else + ok = cfg_error (cfgst, "only %d instance(s) allowed",cfgelem->multiplicity); + n->count++; + if (!ok) + { + n->failed++; + } + return ok; +} + +static int set_default (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem) +{ + if (cfgelem->defvalue == NULL) + return cfg_error (cfgst, "element missing in configuration"); + return do_update (cfgst, cfgelem->update, parent, cfgelem, cfgelem->defvalue, 1); +} + +static int set_defaults (struct cfgst *cfgst, void *parent, int isattr, struct cfgelem const * const cfgelem, int clear_found) +{ + const struct cfgelem *ce; + int ok = 1; + for (ce = cfgelem; ce && ce->name; ce++) + { + struct cfgst_node *n; + struct cfgst_nodekey key; + key.e = ce; + cfgst_push (cfgst, isattr, ce, parent); + if (ce->multiplicity == 1) + { + if (ut_avlLookup (&cfgst_found_treedef, &cfgst->found, &key) == NULL) + { + if (ce->update) + { + int ok1; + cfgst_push (cfgst, 0, NULL, NULL); + ok1 = set_default (cfgst, parent, ce); + cfgst_pop (cfgst); + ok = ok && ok1; + } + } + if ((n = ut_avlLookup (&cfgst_found_treedef, &cfgst->found, &key)) != NULL) + { + if (clear_found) + { + ut_avlDelete (&cfgst_found_treedef, &cfgst->found, n); + os_free (n); + } + } + if (ce->children) + { + int ok1 = set_defaults (cfgst, parent, 0, ce->children, clear_found); + ok = ok && ok1; + } + if (ce->attributes) + { + int ok1 = set_defaults (cfgst, parent, 1, ce->attributes, clear_found); + ok = ok && ok1; + } + } + cfgst_pop (cfgst); + } + return ok; +} + +static void pf_nop (UNUSED_ARG (struct cfgst *cfgst), UNUSED_ARG (void *parent), UNUSED_ARG (struct cfgelem const * const cfgelem), UNUSED_ARG (int is_default)) +{ +} + +static void pf_string (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int is_default) +{ + char **p = cfg_address (cfgst, parent, cfgelem); + cfg_log (cfgst, "%s%s", *p ? *p : "(null)", is_default ? " [def]" : ""); +} + +static void pf_int64_unit (struct cfgst *cfgst, os_int64 value, int is_default, const struct unit *unittab, const char *zero_unit) +{ + if (value == 0) + { + /* 0s is a bit of a special case: we don't want to print 0hr (or + whatever unit will have the greatest multiplier), so hard-code + as 0s */ + cfg_log (cfgst, "0 %s%s", zero_unit, is_default ? " [def]" : ""); + } + else + { + os_int64 m = 0; + const char *unit = NULL; + int i; + for (i = 0; unittab[i].name != NULL; i++) + { + if (unittab[i].multiplier > m && (value % unittab[i].multiplier) == 0) + { + m = unittab[i].multiplier; + unit = unittab[i].name; + } + } + assert (m > 0); + assert (unit != NULL); + cfg_log (cfgst, "%lld %s%s", value / m, unit, is_default ? " [def]" : ""); + } +} + +#ifdef DDSI_INCLUDE_ENCRYPTION +static void pf_key (struct cfgst *cfgst, UNUSED_ARG (void *parent), UNUSED_ARG (struct cfgelem const * const cfgelem), UNUSED_ARG (int is_default)) +{ + cfg_log (cfgst, ""); +} + +static void pf_cipher (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int is_default) +{ + q_cipherType *p = cfg_address (cfgst, parent, cfgelem); + if (q_security_plugin.cipher_type) + { + cfg_log (cfgst, "%s%s", (q_security_plugin.cipher_type) (*p), is_default ? " [def]" : ""); + } +} +#endif /* DDSI_INCLUDE_ENCRYPTION */ + +static void pf_networkAddress (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int is_default) +{ + char **p = cfg_address (cfgst, parent, cfgelem); + cfg_log (cfgst, "%s%s", *p ? *p : "auto", is_default ? " [def]" : ""); +} + +static void pf_participantIndex (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int is_default) +{ + int *p = cfg_address (cfgst, parent, cfgelem); + switch (*p) + { + case PARTICIPANT_INDEX_NONE: + cfg_log (cfgst, "none%s", is_default ? " [def]" : ""); + break; + case PARTICIPANT_INDEX_AUTO: + cfg_log (cfgst, "auto%s", is_default ? " [def]" : ""); + break; + default: + cfg_log (cfgst, "%d%s", *p, is_default ? " [def]" : ""); + break; + } +} + +static void pf_networkAddresses (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int is_default) +{ + int i; + char ***p = cfg_address (cfgst, parent, cfgelem); + for (i = 0; (*p)[i] != NULL; i++) + cfg_log (cfgst, "%s%s", (*p)[i], is_default ? " [def]" : ""); +} + +static void pf_int (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int is_default) +{ + int *p = cfg_address (cfgst, parent, cfgelem); + cfg_log (cfgst, "%d%s", *p, is_default ? " [def]" : ""); +} + +static void pf_uint (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int is_default) +{ + unsigned *p = cfg_address (cfgst, parent, cfgelem); + cfg_log (cfgst, "%u%s", *p, is_default ? " [def]" : ""); +} + +static void pf_duration (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int is_default) +{ + const os_int64 *elem = cfg_address (cfgst, parent, cfgelem); + if (*elem == T_NEVER) + cfg_log (cfgst, "inf%s", is_default ? " [def]" : ""); + else + pf_int64_unit (cfgst, *elem, is_default, unittab_duration, "s"); +} + +#ifdef DDSI_INCLUDE_BANDWIDTH_LIMITING +static void pf_bandwidth (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int is_default) +{ + const os_uint32 *elem = cfg_address (cfgst, parent, cfgelem); + if (*elem == 0) + cfg_log (cfgst, "inf%s", is_default ? " [def]" : ""); + else + pf_int64_unit (cfgst, *elem, is_default, unittab_bandwidth_Bps, "B/s"); +} +#endif + +static void pf_memsize (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int is_default) +{ + const int *elem = cfg_address (cfgst, parent, cfgelem); + pf_int64_unit (cfgst, *elem, is_default, unittab_memsize, "B"); +} + +static void pf_int32 (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int is_default) +{ + os_int32 *p = cfg_address (cfgst, parent, cfgelem); + cfg_log (cfgst, "%d%s", *p, is_default ? " [def]" : ""); +} + +static void pf_uint32 (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int is_default) +{ + os_uint32 *p = cfg_address (cfgst, parent, cfgelem); + cfg_log (cfgst, "%u%s", *p, is_default ? " [def]" : ""); +} + +static void pf_maybe_int32 (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int is_default) +{ + struct config_maybe_int32 *p = cfg_address (cfgst, parent, cfgelem); + if (p->isdefault) + cfg_log (cfgst, "default%s", is_default ? " [def]" : ""); + else + cfg_log (cfgst, "%d%s", p->value, is_default ? " [def]" : ""); +} + +static void pf_maybe_memsize (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int is_default) +{ + struct config_maybe_uint32 *p = cfg_address (cfgst, parent, cfgelem); + if (p->isdefault) + cfg_log (cfgst, "default%s", is_default ? " [def]" : ""); + else + pf_int64_unit (cfgst, p->value, is_default, unittab_memsize, "B"); +} + +#if !LITE +static void pf_maybe_duration (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int is_default) +{ + struct config_maybe_int64 *p = cfg_address (cfgst, parent, cfgelem); + if (p->isdefault) + cfg_log (cfgst, "default%s", is_default ? " [def]" : ""); + else if (p->value == T_NEVER) + cfg_log (cfgst, "inf%s", is_default ? " [def]" : ""); + else + pf_int64_unit (cfgst, p->value, is_default, unittab_duration, "s"); +} +#endif + +static void pf_float (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int is_default) +{ + float *p = cfg_address (cfgst, parent, cfgelem); + cfg_log (cfgst, "%f%s", *p, is_default ? " [def]" : ""); +} + +static void pf_boolean (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int is_default) +{ + int *p = cfg_address (cfgst, parent, cfgelem); + cfg_log (cfgst, "%s%s", *p ? "true" : "false", is_default ? " [def]" : ""); +} + +static void pf_negated_boolean (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int is_default) +{ + int *p = cfg_address (cfgst, parent, cfgelem); + cfg_log (cfgst, "%s%s", *p ? "false" : "true", is_default ? " [def]" : ""); +} + +static int uf_standards_conformance (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, UNUSED_ARG (int first), const char *value) +{ + static const char *vs[] = { + "pedantic", "strict", "lax", NULL + }; + static const logcat_t lc[] = { + NN_SC_PEDANTIC, NN_SC_STRICT, NN_SC_LAX, 0 + }; + enum nn_standards_conformance *elem = cfg_address (cfgst, parent, cfgelem); + int idx = list_index (vs, value); + assert (sizeof (vs) / sizeof (*vs) == sizeof (lc) / sizeof (*lc)); + if (idx < 0) + return cfg_error (cfgst, "'%s': undefined value", value); + else + { + *elem = lc[idx]; + return 1; + } +} + +static void pf_standards_conformance (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int is_default) +{ + enum nn_standards_conformance *p = cfg_address (cfgst, parent, cfgelem); + const char *str = "INVALID"; + switch (*p) + { + case NN_SC_PEDANTIC: str = "pedantic"; break; + case NN_SC_STRICT: str = "strict"; break; + case NN_SC_LAX: str = "lax"; break; + } + cfg_log (cfgst, "%s%s", str, is_default ? " [def]" : ""); +} + +static void pf_logcat (struct cfgst *cfgst, UNUSED_ARG (void *parent), UNUSED_ARG (struct cfgelem const * const cfgelem), UNUSED_ARG (int is_default)) +{ + logcat_t remaining = config.enabled_logcats; + char res[256] = "", *resp = res; + const char *prefix = ""; + size_t i; +#ifndef NDEBUG + { + size_t max; + for (i = 0, max = 0; i < sizeof (logcat_codes) / sizeof (*logcat_codes); i++) + max += 1 + strlen (logcat_names[i]); + max += 11; /* ,0x%x */ + max += 1; /* \0 */ + assert (max <= sizeof (res)); + } +#endif + /* TRACE enables ALLCATS, all the others just one */ + if ((remaining & LC_ALLCATS) == LC_ALLCATS) + { + resp += snprintf (resp, 256, "%strace", prefix); + remaining &= ~LC_ALLCATS; + prefix = ","; + } + for (i = 0; i < sizeof (logcat_codes) / sizeof (*logcat_codes); i++) + { + if (remaining & logcat_codes[i]) + { + resp += snprintf (resp, 256, "%s%s", prefix, logcat_names[i]); + remaining &= ~logcat_codes[i]; + prefix = ","; + } + } + if (remaining) + { + resp += snprintf (resp, 256, "%s0x%x", prefix, (unsigned) remaining); + } + assert (resp <= res + sizeof (res)); + /* can't do default indicator: user may have specified Verbosity, in + which case EnableCategory is at default, but for these two + settings, I don't mind. */ + cfg_log (cfgst, "%s", res); +} + + +static void print_configitems (struct cfgst *cfgst, void *parent, int isattr, struct cfgelem const * const cfgelem, int unchecked) +{ + const struct cfgelem *ce; + for (ce = cfgelem; ce && ce->name; ce++) + { + struct cfgst_nodekey key; + struct cfgst_node *n; + if (ce->name[0] == '>') /* moved, so don't care */ + continue; + key.e = ce; + cfgst_push (cfgst, isattr, ce, parent); + if (ce->multiplicity == 1) + { + if ((n = ut_avlLookup (&cfgst_found_treedef, &cfgst->found, &key)) != NULL) + { + cfgst_push (cfgst, 0, NULL, NULL); + ce->print (cfgst, parent, ce, n->is_default); + cfgst_pop (cfgst); + } + else + { + if (unchecked && ce->print) + { + cfgst_push (cfgst, 0, NULL, NULL); + ce->print (cfgst, parent, ce, 0); + cfgst_pop (cfgst); + } + } + + if (ce->children) + print_configitems (cfgst, parent, 0, ce->children, unchecked); + if (ce->attributes) + print_configitems (cfgst, parent, 1, ce->attributes, unchecked); + } + else + { + struct config_listelem *p = cfg_deref_address (cfgst, parent, ce); + while (p) + { + cfgst_push (cfgst, 0, NULL, NULL); + if (ce->print) + { + ce->print (cfgst, p, ce, 0); + } + cfgst_pop (cfgst); + if (ce->attributes) + print_configitems (cfgst, p, 1, ce->attributes, 1); + if (ce->children) + print_configitems (cfgst, p, 0, ce->children, 1); + p = p->next; + } + } + cfgst_pop (cfgst); + } +} + + +static void free_all_elements (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem) +{ + const struct cfgelem *ce; + + for (ce = cfgelem; ce && ce->name; ce++) + { + if (ce->name[0] == '>') /* moved, so don't care */ + continue; + + if (ce->free) + ce->free (cfgst, parent, ce); + + if (ce->multiplicity == 1) + { + if (ce->children) + free_all_elements (cfgst, parent, ce->children); + if (ce->attributes) + free_all_elements (cfgst, parent, ce->attributes); + } + else + { + struct config_listelem *p = cfg_deref_address (cfgst, parent, ce); + struct config_listelem *r ; + while (p) { + if (ce->attributes) + free_all_elements (cfgst, p, ce->attributes); + if (ce->children) + free_all_elements (cfgst, p, ce->children); + r = p; + p = p->next; + os_free(r); + } + } + } +} + +static void free_configured_elements (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem) +{ + const struct cfgelem *ce; + for (ce = cfgelem; ce && ce->name; ce++) + { + struct cfgst_nodekey key; + struct cfgst_node *n; + if (ce->name[0] == '>') /* moved, so don't care */ + continue; + key.e = ce; + if ((n = ut_avlLookup (&cfgst_found_treedef, &cfgst->found, &key)) != NULL) + { + if (ce->free && n->count > n->failed) + ce->free (cfgst, parent, ce); + } + + if (ce->multiplicity == 1) + { + if (ce->children) + free_configured_elements (cfgst, parent, ce->children); + if (ce->attributes) + free_configured_elements (cfgst, parent, ce->attributes); + } + else + { + struct config_listelem *p = cfg_deref_address (cfgst, parent, ce); + struct config_listelem *r; + while (p) + { + if (ce->attributes) + free_all_elements (cfgst, p, ce->attributes); + if (ce->children) + free_all_elements (cfgst, p, ce->children); + r = p; + p = p->next; + os_free(r); + } + } + } +} + +static int matching_name_index (const char *name_w_aliases, const char *name) +{ + const char *ns = name_w_aliases, *p = strchr (ns, '|'); + int idx = 0; + while (p) + { + if (os_strncasecmp (ns, name, (size_t) (p-ns)) == 0 && name[p-ns] == 0) + { + /* ns upto the pipe symbol is a prefix of name, and name is terminated at that point */ + return idx; + } + /* If primary name followed by '||' instead of '|', aliases are non-warning */ + ns = p + 1 + (idx == 0 && p[1] == '|'); + p = strchr (ns, '|'); + idx++; + } + return (os_strcasecmp (ns, name) == 0) ? idx : -1; +} + +static const struct cfgelem *lookup_redirect (const char *target) +{ + const struct cfgelem *cfgelem = ddsi2_cfgelems; + char *target_copy = os_strdup(target), *p1; + const char *p = target_copy; + while (p) { + p1 = strchr (p, '/'); + if (p1) *p1++ = 0; + for (; cfgelem->name; cfgelem++) + { + /* not supporting multiple redirects */ + assert(cfgelem->name[0] != '>'); + if (matching_name_index (cfgelem->name, p) >= 0) + break; + } + if (p1) + { + cfgelem = cfgelem->children; + } + p = p1; + } + os_free(target_copy); + return cfgelem; +} + +static int proc_elem_open (void *varg, const char *name) +{ + struct cfgst * const cfgst = varg; + const struct cfgelem *cfgelem = cfgst_tos (cfgst); + const struct cfgelem *cfg_subelem; + int moved = 0; + if (cfgelem == NULL) + { + /* Ignoring, but do track the structure so we can know when to stop ignoring */ + cfgst_push (cfgst, 0, NULL, NULL); + return 1; + } + for (cfg_subelem = cfgelem->children; cfg_subelem && cfg_subelem->name && strcmp (cfg_subelem->name, "*") != 0; cfg_subelem++) + { + const char *csename = cfg_subelem->name; + int idx; + moved = (csename[0] == '>'); + if (moved) + csename++; + idx = matching_name_index (csename, name); +#if WARN_DEPRECATED_ALIAS + if (idx > 0) + { + int n = (int) (strchr (csename, '|') - csename); + if (csename[n+1] != '|') + cfg_warning (cfgst, "'%s': deprecated alias for '%*.*s'", name, n, n, csename); + } +#endif + if (idx >= 0) + { + break; + } + } + if (cfg_subelem == NULL || cfg_subelem->name == NULL) + return cfg_error (cfgst, "%s: unknown element", name); + else if (strcmp (cfg_subelem->name, "*") == 0) + { + /* Push a marker that we are to ignore this part of the DOM tree */ + cfgst_push (cfgst, 0, NULL, NULL); + return 1; + } + else + { + void *parent, *dynparent; + + if (moved) + { +#if WARN_DEPRECATED_ALIAS + cfg_warning (cfgst, "'%s': deprecated alias for '%s'", name, cfg_subelem->defvalue); +#endif + cfg_subelem = lookup_redirect (cfg_subelem->defvalue); + } + + parent = cfgst_parent (cfgst); + assert (cfgelem->init || cfgelem->multiplicity == 1); /*multi-items must have an init-func */ + if (cfg_subelem->init) + { + if (cfg_subelem->init (cfgst, parent, cfg_subelem) < 0) + return 0; + } + + if (cfg_subelem->multiplicity != 1) + dynparent = cfg_deref_address (cfgst, parent, cfg_subelem); + else + dynparent = parent; + + cfgst_push (cfgst, 0, cfg_subelem, dynparent); + return 1; + } +} + +static int proc_attr (void *varg, const char *name, const char *value) +{ + /* All attributes are processed immediately after opening the element */ + struct cfgst * const cfgst = varg; + const struct cfgelem *cfgelem = cfgst_tos (cfgst); + const struct cfgelem *cfg_attr; + if (cfgelem == NULL) + return 1; + for (cfg_attr = cfgelem->attributes; cfg_attr && cfg_attr->name; cfg_attr++) + { + if (os_strcasecmp (cfg_attr->name, name) == 0) + break; + } + if (cfg_attr == NULL || cfg_attr->name == NULL) + return cfg_error (cfgst, "%s: unknown attribute", name); + else + { + void *parent = cfgst_parent (cfgst); + int ok; + cfgst_push (cfgst, 1, cfg_attr, parent); + ok = do_update (cfgst, cfg_attr->update, parent, cfg_attr, value, 0); + cfgst_pop (cfgst); + return ok; + } +} + +static int proc_elem_data (void *varg, const char *value) +{ + struct cfgst * const cfgst = varg; + const struct cfgelem *cfgelem = cfgst_tos (cfgst); + if (cfgelem == NULL) + return 1; + if (cfgelem->update == 0) + return cfg_error (cfgst, "%s: no data expected", value); + else + { + void *parent = cfgst_parent (cfgst); + int ok; + cfgst_push (cfgst, 0, NULL, parent); + ok = do_update (cfgst, cfgelem->update, parent, cfgelem, value, 0); + cfgst_pop (cfgst); + return ok; + } +} + +static int proc_elem_close (void *varg) +{ + struct cfgst * const cfgst = varg; + const struct cfgelem * cfgelem = cfgst_tos (cfgst); + int ok = 1; + if (cfgelem && cfgelem->multiplicity != 1) + { + void *parent = cfgst_parent (cfgst); + int ok1; + ok1 = set_defaults (cfgst, parent, 1, cfgelem->attributes, 1); + ok = ok && ok1; + ok1 = set_defaults (cfgst, parent, 0, cfgelem->children, 1); + ok = ok && ok1; + } + cfgst_pop (cfgst); + return ok; +} + +#if ! LITE +static int walk_element (struct cfgst *cfgst, const char *name, u_cfElement elem); + +static int walk_attributes (struct cfgst *cfgst, u_cfElement base) +{ + c_iter iter; + u_cfNode child; + int ok = 1; + iter = u_cfElementGetAttributes (base); + child = u_cfNode (c_iterTakeFirst (iter)); + while (child) + { + u_cfAttribute attr; + c_char *name, *value; + int ok1 = 0; + name = u_cfNodeName (child); + assert (name != NULL); + assert (u_cfNodeKind (child) == V_CFATTRIBUTE); + attr = u_cfAttribute (child); + if (!u_cfAttributeStringValue (attr, &value)) + ok1 = cfg_error (cfgst, "failed to extract data"); + else + { + ok1 = proc_attr (cfgst, name, value); + os_free (value); + } + ok = ok && ok1; + os_free (name); + u_cfNodeFree (child); + child = u_cfNode (c_iterTakeFirst (iter)); + } + c_iterFree (iter); + return ok; +} + +static int walk_children (struct cfgst *cfgst, u_cfElement base) +{ + c_iter iter; + u_cfNode child; + int ok = 1; + iter = u_cfElementGetChildren (base); + child = u_cfNode (c_iterTakeFirst (iter)); + while (child) + { + c_char *child_name; + int ok1 = 0; + child_name = u_cfNodeName (child); + assert (child_name != NULL); + switch (u_cfNodeKind (child)) + { + case V_CFELEMENT: + { + u_cfElement elem = u_cfElement (child); + ok1 = walk_element (cfgst, child_name, elem); + break; + } + case V_CFDATA: + { + u_cfData data = u_cfData (child); + c_char *value; + if (!u_cfDataStringValue (data, &value)) + ok1 = cfg_error (cfgst, "failed to extract data"); + else + { + if (strspn (value, " \t\r\n") != strlen (value)) + ok1 = proc_elem_data (cfgst, value); + else + ok1 = 1; + os_free (value); + } + break; + } + default: + abort (); + } + ok = ok && ok1; + os_free (child_name); + u_cfNodeFree (child); + child = u_cfNode (c_iterTakeFirst (iter)); + } + c_iterFree (iter); + return ok; +} + +static int walk_element (struct cfgst *cfgst, const char *name, u_cfElement elem) +{ + if (!proc_elem_open (cfgst, name)) + return 0; + else + { + int ok; + ok = walk_attributes (cfgst, elem) && walk_children (cfgst, elem); + if (!proc_elem_close (cfgst)) + ok = 0; + return ok; + } +} +#endif + +static int cfgst_node_cmp (const void *va, const void *vb) +{ + return memcmp (va, vb, sizeof (struct cfgst_nodekey)); +} + +#ifdef DDSI_INCLUDE_NETWORK_CHANNELS +static int set_default_channel (struct config *cfg) +{ + if (cfg->channels == NULL) + { + /* create one default channel if none configured */ + struct config_channel_listelem *c; + if ((c = os_malloc (sizeof (*c))) == NULL) + return ERR_OUT_OF_MEMORY; + c->next = NULL; + c->name = os_strdup ("user"); + c->priority = 0; + c->resolution = 1 * T_SECOND; +#ifdef DDSI_INCLUDE_BANDWIDTH_LIMITING + c->data_bandwidth_limit = 0; + c->auxiliary_bandwidth_limit = 0; +#endif + c->queue_size = 0; + c->diffserv_field = 0; + c->channel_reader_ts = NULL; + c->queueId = 0; + c->dqueue = NULL; + c->evq = NULL; + c->transmit_conn = NULL; + cfg->channels = c; + } + return 0; +} + +static int sort_channels_cmp (const void *va, const void *vb) +{ + const struct config_channel_listelem * const *a = va; + const struct config_channel_listelem * const *b = vb; + return ((*a)->priority == (*b)->priority) ? 0 : ((*a)->priority < (*b)->priority) ? -1 : 1; +} + +static int sort_channels_check_nodups (struct config *cfg) +{ + /* Selecting a channel is much easier & more elegant if the channels + are sorted on descending priority. While we do retain the list + structure, sorting is much easier in an array, and hence we + convert back and forth. */ + struct config_channel_listelem **ary, *c; + unsigned i, n; + int result; + + n = 0; + for (c = cfg->channels; c; c = c->next) + n++; + assert (n > 0); + + ary = os_malloc (n * sizeof (*ary)); + + i = 0; + for (c = cfg->channels; c; c = c->next) + ary[i++] = c; + qsort (ary, n, sizeof (*ary), sort_channels_cmp); + + result = 0; + for (i = 0; i < n-1; i++) + { + if (ary[i]->priority == ary[i+1]->priority) + { + NN_ERROR3 ("config: duplicate channel definition for priority %u: channels %s and %s\n", + ary[i]->priority, ary[i]->name, ary[i+1]->name); + result = ERR_ENTITY_EXISTS; + } + } + + if (result == 0) + { + cfg->channels = ary[0]; + for (i = 0; i < n-1; i++) + ary[i]->next = ary[i+1]; + ary[i]->next = NULL; + cfg->max_channel = ary[i]; + } + + os_free (ary); + return result; +} +#endif /* DDSI_INCLUDE_NETWORK_CHANNELS */ + +struct cfgst * q_config_init +( +#if LITE + const char *configfile +#else + /* C_STRUCT (u_participant) const * */u_participant participant, const char *servicename +#endif +) +{ + int ok = 1; + struct cfgst *cfgst; +#if !LITE + u_cfElement root, elem; + c_iter iter; + int rootidx; + assert (participant != NULL); +#endif + + memset (&config, 0, sizeof (config)); + +#if ! LITE + /* Enable logging of errors &c. to stderr until configuration is read */ + config.enabled_logcats = LC_FATAL | LC_ERROR | LC_WARNING; +#ifdef DDSI_INCLUDE_ENCRYPTION + ddsi_security_plugin (); +#endif +#endif + config.tracingOutputFile = stderr; + + cfgst = os_malloc (sizeof (*cfgst)); + memset (cfgst, 0, sizeof (*cfgst)); + + ut_avlInit (&cfgst_found_treedef, &cfgst->found); + cfgst->cfg = &config; +#if !LITE + cfgst->servicename = servicename; +#endif + +#if LITE + /* configfile == NULL will get you the default configuration */ + if (configfile) + { + char *copy = os_strdup (configfile), *cursor = copy, *tok; + while ((tok = os_strsep (&cursor, ",")) != NULL) + { + struct qhxml_state *qx; + FILE *fp; + + if ((fp = fopen (tok, "r")) == NULL) + { + if (strncmp (tok, "file://", 7) != 0 || (fp = fopen (tok + 7, "r")) == NULL) + { + os_free (copy); + os_free (cfgst); + NN_ERROR1 ("can't open configuration file %s\n", tok); + return NULL; + } + } + if ((qx = qhxml_newfp (fp, tok, cfgst, proc_elem_open, proc_attr, proc_elem_data, proc_elem_close)) == NULL) + { + (void)fclose (fp); + os_free (copy); + os_free (cfgst); + return NULL; + } + cfgst_push (cfgst, 0, &root_cfgelem, &config); + + ok = qhxml_proc (qx); + /* Pop until stack empty: error handling is rather brutal */ + assert (!ok || cfgst->path_depth == 1); + while (cfgst->path_depth > 0) + cfgst_pop (cfgst); + qhxml_free (qx); + (void)fclose (fp); + } + os_free (copy); + } +#else + if ((root = u_participantGetConfiguration ((u_participant) participant)) == NULL) + { + NN_ERROR0 ("q_config_init: u_participantGetConfiguration failed"); + ut_avlFree (&cfgst_found_treedef, &cfgst->found, os_free); + os_free (cfgst); + return NULL; + } + + /* Only suitable for Domain (without a attributes) and a service + with a matching name attribute */ + cfgst_push (cfgst, 0, &root_cfgelem, &config); + for (rootidx = 0; root_cfgelems[rootidx].name; rootidx++) + { + const struct cfgelem *root_cfgelem = &root_cfgelems[rootidx]; + char *copy = os_strdup (root_cfgelem->name), *cursor = copy, *tok; + while ((tok = os_strsep (&cursor, "|")) != NULL) + { + if (*tok == 0) + { + /* The configuration tables are supposed to be reasonable and not contain empty tags. Then, "||" is returned as an empty token by os_strsep, but we can simply skip it */ + continue; + } + iter = u_cfElementXPath (root, tok); + elem = u_cfElement (c_iterTakeFirst (iter)); + while (elem) + { + c_char *str; + if (root_cfgelem->attributes == NULL) + { + /* Domain element */ + int ok1; + char *name = u_cfNodeName (u_cfNode (elem)); + ok1 = walk_element (cfgst, name, elem); + os_free (name); + ok = ok && ok1; + } + else if (u_cfElementAttributeStringValue (elem, "name", &str)) + { + int ok1; + if (os_strcasecmp (servicename, str) != 0) + ok1 = 1; + else + { + char *name = u_cfNodeName (u_cfNode (elem)); + ok1 = walk_element (cfgst, name, elem); + os_free (name); + } + ok = ok && ok1; + os_free (str); + } + u_cfElementFree (elem); + elem = u_cfElement (c_iterTakeFirst (iter)); + } + c_iterFree (iter); + } + os_free (copy); + } + cfgst_pop (cfgst); + u_cfElementFree (root); +#endif + + /* Set defaults for everything not set that we have a default value + for, signal errors for things unset but without a default. */ + { + int ok1 = set_defaults (cfgst, cfgst->cfg, 0, root_cfgelems, 0); + ok = ok && ok1; + } + +#ifdef DDSI_INCLUDE_NETWORK_CHANNELS + /* Default channel gets set outside set_defaults -- a bit too + complicated for the poor framework */ + + if (set_default_channel (cfgst->cfg) < 0) + { + ok = 0; + } + if (cfgst->cfg->channels && sort_channels_check_nodups (cfgst->cfg) < 0) + { + ok = 0; + } +#endif + +#ifdef DDSI_INCLUDE_ENCRYPTION + /* Check security profiles */ + { + struct config_securityprofile_listelem *s = config.securityProfiles; + while (s) + { + switch (s->cipher) + { + case Q_CIPHER_UNDEFINED: + case Q_CIPHER_NULL: + /* nop */ + if (s->key && strlen (s->key) > 0) { + NN_ERROR1 ("config: DDSI2EService/Security/SecurityProfile[@cipherkey]: %s: cipher key not required\n",s->key); + } + break; + + default: + /* read the cipherkey if present */ + if (!s->key || strlen (s->key) == 0) { + NN_ERROR0 ("config: DDSI2EService/Security/SecurityProfile[@cipherkey]: cipher key missing\n"); + ok = 0; + } else if (q_security_plugin.valid_uri && ! (q_security_plugin.valid_uri) (s->cipher,s->key)) { + NN_ERROR1 ("config: DDSI2EService/Security/SecurityProfile[@cipherkey]: %s : incorrect key\n", s->key); + ok = 0; + } + } + s = s->next; + } + } +#endif /* DDSI_INCLUDE_ENCRYPTION */ + +#ifdef DDSI_INCLUDE_NETWORK_PARTITIONS + /* Assign network partition ids */ +#ifdef DDSI_INCLUDE_ENCRYPTION + /* also create links from the network partitions to the + securityProfiles and signal errors if profiles do not exist */ +#endif /* DDSI_INCLUDE_ENCRYPTION */ + { + struct config_networkpartition_listelem *p = config.networkPartitions; + config.nof_networkPartitions = 0; + while (p) + { +#ifdef DDSI_INCLUDE_ENCRYPTION + if (os_strcasecmp (p->profileName, "null") == 0) + p->securityProfile = NULL; + else + { + struct config_securityprofile_listelem *s = config.securityProfiles; + while (s && os_strcasecmp (p->profileName, s->name) != 0) + s = s->next; + if (s) + p->securityProfile = s; + else + { + NN_ERROR1 ("config: DDSI2EService/Partitioning/NetworkPartitions/NetworkPartition[@securityprofile]: %s: unknown securityprofile\n", p->profileName); + ok = 0; + } + } +#endif /* DDSI_INCLUDE_ENCRYPTION */ + config.nof_networkPartitions++; + /* also use crc32 just like native nw and ordinary ddsi2e, only + for interoperability because it is asking for trouble & + forces us to include a crc32 routine when we have md5 + available anyway */ + p->partitionId = config.nof_networkPartitions; /* starting at 1 */ +#if LITE + p->partitionHash = crc32_calc (p->name, (int) strlen (p->name)); +#else + p->partitionHash = ut_crcCalculate (p->name, strlen (p->name)); +#endif + p = p->next; + } + } + + /* Create links from the partitionmappings to the network partitions + and signal errors if partitions do not exist */ + { + struct config_partitionmapping_listelem * m = config.partitionMappings; + while (m) { + struct config_networkpartition_listelem * p = config.networkPartitions; + while (p && os_strcasecmp(m->networkPartition, p->name) != 0) { + p = p->next; + } + if (p) { + m->partition = p; + } else { + NN_ERROR1 ("config: DDSI2EService/Partitioning/PartitionMappings/PartitionMapping[@networkpartition]: %s: unknown partition\n", m->networkPartition); + ok = 0; + } + m = m->next; + } + } +#endif /* DDSI_INCLUDE_NETWORK_PARTITIONS */ + + /* Now switch to configured tracing settings */ + config.enabled_logcats = enabled_logcats; + + if (!ok) + { + free_configured_elements (cfgst, cfgst->cfg, root_cfgelems); + } + + if (ok) + { + config.valid = 1; + return cfgst; + } + else + { + ut_avlFree (&cfgst_found_treedef, &cfgst->found, os_free); + os_free (cfgst); + return NULL; + } +} + +void q_config_print_and_free_cfgst (struct cfgst *cfgst) +{ + if (cfgst == NULL) + return; + print_configitems (cfgst, cfgst->cfg, 0, root_cfgelems, 0); + ut_avlFree (&cfgst_found_treedef, &cfgst->found, os_free); + os_free (cfgst); +} + +void q_config_fini (void) +{ + if (config.valid) + { + struct cfgst cfgst; + cfgst.cfg = &config; + free_all_elements (&cfgst, cfgst.cfg, root_cfgelems); + if (config.tracingOutputFile) + { + (void)fclose (config.tracingOutputFile); + } + memset (&config, 0, sizeof (config)); + } +} + +#ifdef DDSI_INCLUDE_NETWORK_PARTITIONS +static char *get_partition_search_pattern (const char *partition, const char *topic) +{ + char *pt = os_malloc (strlen (partition) + strlen (topic) + 2); + os_sprintf (pt, "%s.%s", partition, topic); + return pt; +} + +struct config_partitionmapping_listelem *find_partitionmapping (const char *partition, const char *topic) +{ + char *pt = get_partition_search_pattern (partition, topic); + struct config_partitionmapping_listelem *pm; + for (pm = config.partitionMappings; pm; pm = pm->next) + if (WildcardOverlap (pt, pm->DCPSPartitionTopic)) + break; + os_free (pt); + return pm; +} + +struct config_networkpartition_listelem *find_networkpartition_by_id (os_uint32 id) +{ + struct config_networkpartition_listelem *np; + for (np = config.networkPartitions; np; np = np->next) + if (np->partitionId == id) + return np; + return 0; +} + +int is_ignored_partition (const char *partition, const char *topic) +{ + char *pt = get_partition_search_pattern (partition, topic); + struct config_ignoredpartition_listelem *ip; + for (ip = config.ignoredPartitions; ip; ip = ip->next) + if (WildcardOverlap (pt, ip->DCPSPartitionTopic)) + break; + os_free (pt); + return ip != NULL; +} +#endif /* DDSI_INCLUDE_NETWORK_PARTITIONS */ + +#ifdef DDSI_INCLUDE_NETWORK_CHANNELS +struct config_channel_listelem *find_channel (nn_transport_priority_qospolicy_t transport_priority) +{ + struct config_channel_listelem *c; + /* Channel selection is to use the channel with the lowest priority + not less than transport_priority, or else the one with the + highest priority. */ + assert (config.channels != NULL); + assert (config.max_channel != NULL); + for (c = config.channels; c; c = c->next) + { + assert (c->next == NULL || c->next->priority > c->priority); + if (transport_priority.value <= c->priority) + return c; + } + return config.max_channel; +} +#endif /* DDSI_INCLUDE_NETWORK_CHANNELS */ diff --git a/src/services/ddsi2e/core/q_config.h b/src/services/ddsi2e/core/q_config.h new file mode 100644 index 000000000..b37164556 --- /dev/null +++ b/src/services/ddsi2e/core/q_config.h @@ -0,0 +1,495 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#ifndef NN_CONFIG_H +#define NN_CONFIG_H + +#include "os_socket.h" + +#include "q_log.h" +#include "q_thread.h" +#ifdef DDSI_INCLUDE_ENCRYPTION +#include "q_security.h" +#endif /* DDSI_INCLUDE_ENCRYPTION */ +#include "q_xqos.h" +#include "c_typebase.h" +#include "ddsi_tran.h" +#include "q_feature_check.h" + +#if LITE +#include "dds/os/vortex_os.h" +#endif + +#if defined (__cplusplus) +extern "C" { +#endif + +#ifdef OSPL_BUILD_DDSI2 +#define OS_API OS_API_EXPORT +#else +#define OS_API OS_API_IMPORT +#endif + +/* FIXME: should eventually move to abstraction layer */ +typedef enum q__schedPrioClass { + Q__SCHED_PRIO_RELATIVE, + Q__SCHED_PRIO_ABSOLUTE +} q__schedPrioClass; + +enum nn_standards_conformance { + NN_SC_PEDANTIC, + NN_SC_STRICT, + NN_SC_LAX +}; + +#define NN_PEDANTIC_P (config.standards_conformance <= NN_SC_PEDANTIC) +#define NN_STRICT_P (config.standards_conformance <= NN_SC_STRICT) + +enum besmode { + BESMODE_FULL, + BESMODE_WRITERS, + BESMODE_MINIMAL +}; + +enum retransmit_merging { + REXMIT_MERGE_NEVER, + REXMIT_MERGE_ADAPTIVE, + REXMIT_MERGE_ALWAYS +}; + +enum boolean_default { + BOOLDEF_DEFAULT, + BOOLDEF_FALSE, + BOOLDEF_TRUE +}; + +#if LITE +enum durability_cdr +{ + DUR_CDR_LE, + DUR_CDR_BE, + DUR_CDR_SERVER, + DUR_CDR_CLIENT +}; +#endif + +#define PARTICIPANT_INDEX_AUTO -1 +#define PARTICIPANT_INDEX_NONE -2 + +/* config_listelem must be an overlay for all used listelem types */ +struct config_listelem { + struct config_listelem *next; +}; + +#ifdef DDSI_INCLUDE_ENCRYPTION +struct q_security_plugins +{ + c_bool (*encode) (q_securityEncoderSet, os_uint32, void *, os_uint32, os_uint32 *); + c_bool (*decode) (q_securityDecoderSet, void *, size_t, size_t *); + q_securityEncoderSet (*new_encoder) (void); + q_securityDecoderSet (*new_decoder) (void); + c_bool (*free_encoder) (q_securityEncoderSet); + c_bool (*free_decoder) (q_securityDecoderSet); + os_ssize_t (*send_encoded) (ddsi_tran_conn_t, struct msghdr *, q_securityEncoderSet *, os_uint32, os_uint32); + char * (*cipher_type) (q_cipherType); + c_bool (*cipher_type_from_string) (const char *, q_cipherType *); + os_uint32 (*header_size) (q_securityEncoderSet, os_uint32); + q_cipherType (*encoder_type) (q_securityEncoderSet, os_uint32); + c_bool (*valid_uri) (q_cipherType, const char *); +}; + +struct q_security_plugins q_security_plugin; + +struct config_securityprofile_listelem +{ + struct config_securityprofile_listelem *next; + char *name; + q_cipherType cipher; + char *key; +}; +#endif /* DDSI_INCLUDE_ENCRYPTION */ + +#ifdef DDSI_INCLUDE_NETWORK_PARTITIONS +struct config_networkpartition_listelem { + struct config_networkpartition_listelem *next; + char *name; + char *address_string; + struct addrset *as; + int connected; +#ifdef DDSI_INCLUDE_ENCRYPTION + char *profileName; + struct config_securityprofile_listelem *securityProfile; +#endif /* DDSI_INCLUDE_ENCRYPTION */ + os_uint32 partitionHash; + os_uint32 partitionId; +}; + +struct config_ignoredpartition_listelem { + struct config_ignoredpartition_listelem *next; + os_char *DCPSPartitionTopic; +}; + +struct config_partitionmapping_listelem { + struct config_partitionmapping_listelem *next; + char *networkPartition; + char *DCPSPartitionTopic; + struct config_networkpartition_listelem *partition; +}; +#endif /* DDSI_INCLUDE_NETWORK_PARTITIONS */ + +#ifdef DDSI_INCLUDE_NETWORK_CHANNELS +struct config_channel_listelem { + struct config_channel_listelem *next; + char *name; + int priority; + unsigned queue_size; + os_int64 resolution; +#ifdef DDSI_INCLUDE_BANDWIDTH_LIMITING + os_uint32 data_bandwidth_limit; + os_uint32 auxiliary_bandwidth_limit; +#endif + int diffserv_field; + struct thread_state1 *channel_reader_ts; /* keeping an handle to the running thread for this channel */ + struct nn_dqueue *dqueue; /* The handle of teh delivery queue servicing incoming data for this channel*/ + struct xeventq *evq; /* The handle of the event queue servicing this channel*/ + os_uint32 queueId; /* the index of the networkqueue serviced by this channel*/ + struct ddsi_tran_conn * transmit_conn; /* the connection used for sending data out via this channel */ +}; +#endif /* DDSI_INCLUDE_NETWORK_CHANNELS */ + +struct config_maybe_int32 { + int isdefault; + os_int32 value; +}; + +struct config_maybe_uint32 { + int isdefault; + os_uint32 value; +}; + +struct config_maybe_int64 { + int isdefault; + os_int64 value; +}; + +struct config_thread_properties_listelem { + struct config_thread_properties_listelem *next; + char *name; + os_schedClass sched_class; + struct config_maybe_int32 sched_priority; + struct config_maybe_uint32 stack_size; +}; + +struct config_peer_listelem +{ + struct config_peer_listelem *next; + char *peer; +}; + +struct prune_deleted_ppant { + os_int64 delay; + int enforce_delay; +}; + +/* allow multicast bits: */ +#define AMC_FALSE 0u +#define AMC_SPDP 1u +#define AMC_ASM 2u +#ifdef DDSI_INCLUDE_SSM +#define AMC_SSM 4u +#define AMC_TRUE (AMC_SPDP | AMC_ASM | AMC_SSM) +#else +#define AMC_TRUE (AMC_SPDP | AMC_ASM) +#endif + +struct config +{ + int valid; + logcat_t enabled_logcats; + char *servicename; + char *pcap_file; + + char *networkAddressString; + char **networkRecvAddressStrings; + char *externalAddressString; + char *externalMaskString; + FILE *tracingOutputFile; + char *tracingOutputFileName; + int tracingTimestamps; + int tracingRelativeTimestamps; + int tracingAppendToFile; + unsigned allowMulticast; + int useIpv6; + int dontRoute; + int enableMulticastLoopback; + int domainId; + int participantIndex; + int maxAutoParticipantIndex; + int port_base; + struct config_maybe_int32 discoveryDomainId; + char *spdpMulticastAddressString; + char *defaultMulticastAddressString; + char *assumeMulticastCapable; + os_int64 spdp_interval; + os_int64 spdp_response_delay_max; + os_int64 startup_mode_duration; + os_int64 lease_duration; + os_int64 const_hb_intv_sched; + os_int64 const_hb_intv_sched_min; + os_int64 const_hb_intv_sched_max; + os_int64 const_hb_intv_min; + enum retransmit_merging retransmit_merging; + os_int64 retransmit_merging_period; + int squash_participants; + int startup_mode_full; + int forward_all_messages; + int noprogress_log_stacktraces; + int prioritize_retransmit; + +#if ! LITE + char *local_discovery_partition; + enum boolean_default mirror_remote_entities; + enum boolean_default forward_remote_data; +#endif + + unsigned primary_reorder_maxsamples; + unsigned secondary_reorder_maxsamples; + + unsigned delivery_queue_maxsamples; + + float servicelease_expiry_time; + float servicelease_update_factor; + + os_uint32 guid_hash_softlimit; + +#if LITE + int enableLoopback; + enum durability_cdr durability_cdr; +#else + os_uint32 gid_hash_softlimit; + int coexistWithNativeNetworking; +#endif + + unsigned nw_queue_size; + + int buggy_datafrag_flags_mode; + + os_uint32 max_msg_size; + os_uint32 fragment_size; + + int publish_uc_locators; /* Publish discovery unicast locators */ + + /* TCP transport configuration */ + + int tcp_enable; + int tcp_nodelay; + int tcp_port; + os_int64 tcp_read_timeout; + os_int64 tcp_write_timeout; + +#ifdef DDSI_INCLUDE_SSL + + /* SSL support for TCP */ + + int ssl_enable; + int ssl_verify; + int ssl_verify_client; + int ssl_self_signed; + char * ssl_keystore; + char * ssl_rand_file; + char * ssl_key_pass; + char * ssl_ciphers; + +#endif + + /* Thread pool configuration */ + + int tp_enable; + os_uint32 tp_threads; + os_uint32 tp_max_threads; + + int generate_builtin_topics; + int advertise_builtin_topic_writers; + +#ifdef DDSI_INCLUDE_NETWORK_CHANNELS + struct config_channel_listelem *channels; + struct config_channel_listelem *max_channel; /* channel with highest prio; always computed */ +#endif /* DDSI_INCLUDE_NETWORK_CHANNELS */ +#ifdef DDSI_INCLUDE_ENCRYPTION + struct config_securityprofile_listelem *securityProfiles; +#endif /* DDSI_INCLUDE_ENCRYPTION */ +#ifdef DDSI_INCLUDE_NETWORK_PARTITIONS + struct config_networkpartition_listelem *networkPartitions; + unsigned nof_networkPartitions; + struct config_ignoredpartition_listelem *ignoredPartitions; + struct config_partitionmapping_listelem *partitionMappings; +#endif /* DDSI_INCLUDE_NETWORK_PARTITIONS */ + struct config_peer_listelem *peers; + struct config_peer_listelem *peers_group; + struct config_thread_properties_listelem *thread_properties; + + /* debug/test/undoc features: */ + int xmit_lossiness; /**<< fraction of packets to drop on xmit, in units of 1e-3 */ + os_uint32 rmsg_chunk_size; /**<< size of a chunk in the receive buffer */ + os_uint32 rbuf_size; /* << size of a single receiver buffer */ + enum besmode besmode; + int aggressive_keep_last_whc; + int conservative_builtin_reader_startup; + int meas_hb_to_ack_latency; + int suppress_spdp_multicast; + int unicast_response_to_spdp_messages; + int synchronous_delivery_priority_threshold; + os_int64 synchronous_delivery_latency_bound; + + /* Write cache */ + +#if LITE + int whc_batch; +#endif + os_uint32 whc_lowwater_mark; + os_uint32 whc_highwater_mark; + struct config_maybe_uint32 whc_init_highwater_mark; + int whc_adaptive; + + unsigned defrag_unreliable_maxsamples; + unsigned defrag_reliable_maxsamples; + unsigned accelerate_rexmit_block_size; + os_int64 responsiveness_timeout; + os_uint32 max_participants; + os_int64 writer_linger_duration; + int multicast_ttl; + struct config_maybe_uint32 socket_min_rcvbuf_size; + os_uint32 socket_min_sndbuf_size; + os_int64 nack_delay; + os_int64 preemptive_ack_delay; + os_int64 schedule_time_rounding; + os_int64 auto_resched_nack_delay; + os_int64 ds_grace_period; +#ifdef DDSI_INCLUDE_BANDWIDTH_LIMITING + os_uint32 auxiliary_bandwidth_limit; /* bytes/second */ +#endif + os_uint32 max_queued_rexmit_bytes; + unsigned max_queued_rexmit_msgs; + unsigned ddsi2direct_max_threads; + int late_ack_mode; +#if !LITE + struct config_maybe_int64 retry_on_reject_duration; +#endif + int retry_on_reject_besteffort; + int generate_keyhash; + os_uint32 max_sample_size; + + /* compability options */ + enum nn_standards_conformance standards_conformance; + int explicitly_publish_qos_set_to_default; + int many_sockets_mode; + int arrival_of_data_asserts_pp_and_ep_liveliness; + int acknack_numbits_emptyset; + int respond_to_rti_init_zero_ack_with_invalid_heartbeat; + int assume_rti_has_pmd_endpoints; + + int port_dg; + int port_pg; + int port_d0; + int port_d1; + int port_d2; + int port_d3; + + int monitor_port; + + int enable_control_topic; + int initial_deaf; + int initial_mute; + os_int64 initial_deaf_mute_reset; + int use_multicast_if_mreqn; + struct prune_deleted_ppant prune_deleted_ppant; + + /* not used by ddsi2, only validated; user layer directly accesses + the configuration tree */ + os_schedClass watchdog_sched_class; + os_int32 watchdog_sched_priority; + q__schedPrioClass watchdog_sched_priority_class; +}; + +#if LITE +struct rhc; +struct nn_xqos; +struct tkmap_instance; +struct nn_rsample_info; +struct serdata; +struct sertopic; +struct proxy_writer; +struct proxy_writer_info; +#endif + +struct ddsi_plugin +{ + int (*init_fn) (void); + void (*fini_fn) (void); + +#if LITE + + /* Read cache */ + + void (*rhc_free_fn) (struct rhc *rhc); + void (*rhc_fini_fn) (struct rhc *rhc); + bool (*rhc_store_fn) + (struct rhc * restrict rhc, const struct nn_rsample_info * restrict sampleinfo, + struct serdata * restrict sample, struct tkmap_instance * restrict tk); + void (*rhc_unregister_wr_fn) + (struct rhc * restrict rhc, const struct proxy_writer_info * restrict pwr_info); + void (*rhc_relinquish_ownership_fn) + (struct rhc * restrict rhc, const uint64_t wr_iid); + void (*rhc_set_qos_fn) (struct rhc * rhc, const struct nn_xqos * qos); + struct tkmap_instance * (*rhc_lookup_fn) (struct serdata *serdata); + void (*rhc_unref_fn) (struct tkmap_instance *tk); + + /* IID generator */ + + uint64_t (*iidgen_fn) (void); + +#endif +}; + +extern struct config OS_API config; +extern struct ddsi_plugin ddsi_plugin; + +struct cfgst; + +#if LITE +struct cfgst *q_config_init (const char *configfile); +#else +struct u_participant_s; +struct cfgst *q_config_init (struct u_participant_s *participant, const char *serviceName); +#endif +void q_config_print_and_free_cfgst (struct cfgst *cfgst); +void q_config_fini (void); + +#ifdef DDSI_INCLUDE_NETWORK_PARTITIONS +struct config_partitionmapping_listelem *find_partitionmapping (const char *partition, const char *topic); +struct config_networkpartition_listelem *find_networkpartition_by_id (os_uint32 id); +int is_ignored_partition (const char *partition, const char *topic); +#endif +#ifdef DDSI_INCLUDE_NETWORK_CHANNELS +struct config_channel_listelem *find_channel (nn_transport_priority_qospolicy_t transport_priority); +#endif +#undef OS_API +#if defined (__cplusplus) +} +#endif + +#endif /* NN_CONFIG_H */ diff --git a/src/services/ddsi2/code/q_ddsi_discovery.c b/src/services/ddsi2e/core/q_ddsi_discovery.c similarity index 81% rename from src/services/ddsi2/code/q_ddsi_discovery.c rename to src/services/ddsi2e/core/q_ddsi_discovery.c index e8170f77e..d370b9537 100644 --- a/src/services/ddsi2/code/q_ddsi_discovery.c +++ b/src/services/ddsi2e/core/q_ddsi_discovery.c @@ -1,18 +1,16 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * @@ -192,11 +190,11 @@ int spdp_write (struct participant *pp) char node[64]; os_uint64 qosdiff; - TRACE (("spdp_write(%x:%x:%x:%x)\n", PGUID (pp->e.guid))); + TRACE (("spdp_write("PGUIDFMT")\n", PGUID (pp->e.guid))); if ((wr = get_builtin_writer (pp, NN_ENTITYID_SPDP_BUILTIN_PARTICIPANT_WRITER)) == NULL) { - TRACE (("spdp_write(%x:%x:%x:%x) - builtin participant writer not found\n", PGUID (pp->e.guid))); + TRACE (("spdp_write("PGUIDFMT") - builtin participant writer not found\n", PGUID (pp->e.guid))); return 0; } @@ -250,8 +248,19 @@ int spdp_write (struct participant *pp) if (config.allowMulticast) { int include = 0; +#ifdef DDSI_INCLUDE_SSM + /* Note that if the default multicast address is an SSM address, + we will simply advertise it. The recipients better understand + it means the writers will publish to address and the readers + favour SSM. */ + if (is_ssm_mcaddr (&gv.loc_default_mc)) + include = (config.allowMulticast & AMC_SSM) != 0; + else + include = (config.allowMulticast & AMC_ASM) != 0; +#else if (config.allowMulticast & AMC_ASM) include = 1; +#endif if (include) { ps.present |= PP_DEFAULT_MULTICAST_LOCATOR | PP_METATRAFFIC_MULTICAST_LOCATOR; @@ -277,9 +286,12 @@ int spdp_write (struct participant *pp) ps.prismtech_participant_version_info.flags = NN_PRISMTECH_FL_DDSI2_PARTICIPANT_FLAG | NN_PRISMTECH_FL_PTBES_FIXED_0; +#if !LITE ps.prismtech_participant_version_info.flags |= NN_PRISMTECH_FL_DISCOVERY_INCLUDES_GID | - NN_PRISMTECH_FL_KERNEL_SEQUENCE_NUMBER; + NN_PRISMTECH_FL_KERNEL_SEQUENCE_NUMBER | + NN_PRISMTECH_FL_SUPPORTS_STATUSINFOX; +#endif if (config.besmode == BESMODE_MINIMAL) ps.prismtech_participant_version_info.flags |= NN_PRISMTECH_FL_MINIMAL_BES_MODE; os_mutexLock (&gv.privileged_pp_lock); @@ -289,12 +301,21 @@ int spdp_write (struct participant *pp) os_gethostname(node, sizeof(node)-1); node[sizeof(node)-1] = '\0'; +#if LITE + size = strlen(node) + strlen(OSPL_VERSION_STR) + strlen(OSPL_HOST_STR) + strlen(OSPL_TARGET_STR) + 4; /* + ///'\0' */ +#else size = strlen(node) + strlen(OSPL_VERSION_STR) + strlen(OSPL_INNER_REV_STR) + strlen(OSPL_OUTER_REV_STR) + strlen(OSPL_HOST_STR) + strlen(OSPL_TARGET_STR) + 6; /* + /////'\0' */ +#endif ps.prismtech_participant_version_info.internals = os_malloc(size); +#if LITE + snprintf(ps.prismtech_participant_version_info.internals, size, "%s/%s/%s/%s", + node, OSPL_VERSION_STR, OSPL_HOST_STR, OSPL_TARGET_STR); +#else snprintf(ps.prismtech_participant_version_info.internals, size, "%s/%s/%s/%s/%s/%s", node, OSPL_VERSION_STR, OSPL_INNER_REV_STR, OSPL_OUTER_REV_STR, OSPL_HOST_STR, OSPL_TARGET_STR); - TRACE (("spdp_write(%x:%x:%x:%x) - internals: %s\n", PGUID (pp->e.guid), ps.prismtech_participant_version_info.internals)); +#endif + TRACE (("spdp_write("PGUIDFMT") - internals: %s\n", PGUID (pp->e.guid), ps.prismtech_participant_version_info.internals)); } /* Participant QoS's insofar as they are set, different from the default, and mapped to the SPDP data, rather than to the PrismTech-specific CMParticipant endpoint. Currently, that means just USER_DATA. */ @@ -319,7 +340,7 @@ int spdp_write (struct participant *pp) nn_plist_fini(&ps); nn_xmsg_free (mpayload); - return write_sample (NULL, wr, serdata); + return write_sample_nogc (NULL, wr, serdata); } int spdp_dispose_unregister (struct participant *pp) @@ -335,7 +356,7 @@ int spdp_dispose_unregister (struct participant *pp) if ((wr = get_builtin_writer (pp, NN_ENTITYID_SPDP_BUILTIN_PARTICIPANT_WRITER)) == NULL) { - TRACE (("spdp_dispose_unregister(%x:%x:%x:%x) - builtin participant writer not found\n", PGUID (pp->e.guid))); + TRACE (("spdp_dispose_unregister("PGUIDFMT") - builtin participant writer not found\n", PGUID (pp->e.guid))); return 0; } @@ -355,7 +376,7 @@ int spdp_dispose_unregister (struct participant *pp) serdata = ddsi_serstate_fix (serstate); nn_xmsg_free (mpayload); - return write_sample (NULL, wr, serdata); + return write_sample_nogc (NULL, wr, serdata); } static unsigned pseudo_random_delay (const nn_guid_t *x, const nn_guid_t *y, nn_mtime_t tnow) @@ -414,34 +435,50 @@ static void respond_to_spdp (const nn_guid_t *dest_proxypp_guid) ephash_enum_participant_fini (&est); } -static void handle_SPDP_dead (const struct receiver_state *rst, const nn_plist_t *datap) +static int handle_SPDP_dead (const struct receiver_state *rst, nn_wctime_t timestamp, const nn_plist_t *datap, unsigned statusinfo) { nn_guid_t guid; + nn_log (LC_DISCOVERY, "SPDP ST%x", statusinfo); + if (datap->present & PP_PARTICIPANT_GUID) { guid = datap->participant_guid; - TRACE ((" %x:%x:%x:%x", PGUID (guid))); + nn_log (LC_DISCOVERY, " "PGUIDFMT"", PGUID (guid)); assert (guid.entityid.u == NN_ENTITYID_PARTICIPANT); - if (delete_proxy_participant_by_guid (&guid, 0) < 0) + if (delete_proxy_participant_by_guid (&guid, timestamp, 0) < 0) { - TRACE ((" unknown\n")); + nn_log (LC_DISCOVERY, " unknown\n"); } else { - TRACE ((" delete\n")); + nn_log (LC_DISCOVERY, " delete\n"); } } else { NN_WARNING2 ("data (SPDP, vendor %d.%d): no/invalid payload\n", rst->vendor.id[0], rst->vendor.id[1]); } + return 1; } static void allowmulticast_aware_add_to_addrset (struct addrset *as, const nn_locator_t *loc) { +#if DDSI_INCLUDE_SSM + if (is_ssm_mcaddr (loc)) + { + if (!(config.allowMulticast & AMC_SSM)) + return; + } + else if (is_mcaddr (loc)) + { + if (!(config.allowMulticast & AMC_ASM)) + return; + } +#else if (is_mcaddr (loc) && !(config.allowMulticast & AMC_ASM)) return; +#endif add_to_addrset (as, loc); } @@ -459,7 +496,7 @@ static struct proxy_participant *find_ddsi2_proxy_participant (const nn_guid_t * return pp; } -static void make_participants_dependent_on_ddsi2 (const nn_guid_t *ddsi2guid) +static void make_participants_dependent_on_ddsi2 (const nn_guid_t *ddsi2guid, nn_wctime_t timestamp) { struct ephash_enum_proxy_participant it; struct proxy_participant *pp, *d2pp; @@ -472,12 +509,12 @@ static void make_participants_dependent_on_ddsi2 (const nn_guid_t *ddsi2guid) { if (vendor_is_opensplice (pp->vendor) && pp->e.guid.prefix.u[0] == ddsi2guid->prefix.u[0] && !pp->is_ddsi2_pp) { - TRACE (("proxy participant %x:%x:%x:%x depends on ddsi2 %x:%x:%x:%x", PGUID (pp->e.guid), PGUID (*ddsi2guid))); + nn_log (LC_DISCOVERY, "proxy participant "PGUIDFMT" depends on ddsi2 "PGUIDFMT"", PGUID (pp->e.guid), PGUID (*ddsi2guid)); os_mutexLock (&pp->e.lock); pp->privileged_pp_guid = *ddsi2guid; os_mutexUnlock (&pp->e.lock); proxy_participant_reassign_lease (pp, d2pp_lease); - TRACE (("\n")); + nn_log (LC_DISCOVERY, "\n"); if (ephash_lookup_proxy_participant_guid (ddsi2guid) == NULL) { @@ -492,12 +529,12 @@ static void make_participants_dependent_on_ddsi2 (const nn_guid_t *ddsi2guid) if (pp != NULL) { - TRACE (("make_participants_dependent_on_ddsi2: ddsi2 %x:%x:%x:%x is no more, delete %x:%x:%x:%x\n", PGUID (*ddsi2guid), PGUID (pp->e.guid))); - delete_proxy_participant_by_guid (&pp->e.guid, 1); + nn_log (LC_DISCOVERY, "make_participants_dependent_on_ddsi2: ddsi2 "PGUIDFMT" is no more, delete "PGUIDFMT"\n", PGUID (*ddsi2guid), PGUID (pp->e.guid)); + delete_proxy_participant_by_guid (&pp->e.guid, timestamp, 1); } } -static void handle_SPDP_alive (const struct receiver_state *rst, const nn_plist_t *datap) +static int handle_SPDP_alive (const struct receiver_state *rst, nn_wctime_t timestamp, const nn_plist_t *datap) { const unsigned bes_sedp_announcer_mask = NN_DISC_BUILTIN_ENDPOINT_SUBSCRIPTION_ANNOUNCER | @@ -513,7 +550,7 @@ static void handle_SPDP_alive (const struct receiver_state *rst, const nn_plist_ if (!(datap->present & PP_PARTICIPANT_GUID) || !(datap->present & PP_BUILTIN_ENDPOINT_SET)) { NN_WARNING2 ("data (SPDP, vendor %d.%d): no/invalid payload\n", rst->vendor.id[0], rst->vendor.id[1]); - return; + return 1; } /* At some point the RTI implementation didn't mention @@ -545,15 +582,13 @@ static void handle_SPDP_alive (const struct receiver_state *rst, const nn_plist_ but it would cause problems with cases where we would be happy with only (say) CM participant. Have to do a backwards-compatible fix because it has already been released with the flags all aliased to bits 0 and 1 ... */ - TRACE ((" (ptbes_fixed_0 %x)", prismtech_builtin_endpoint_set)); + nn_log (LC_DISCOVERY, " (ptbes_fixed_0 %x)", prismtech_builtin_endpoint_set); if (prismtech_builtin_endpoint_set & NN_DISC_BUILTIN_ENDPOINT_CM_PARTICIPANT_READER) prismtech_builtin_endpoint_set |= NN_DISC_BUILTIN_ENDPOINT_CM_PUBLISHER_READER | NN_DISC_BUILTIN_ENDPOINT_CM_SUBSCRIBER_READER; if (prismtech_builtin_endpoint_set & NN_DISC_BUILTIN_ENDPOINT_CM_PARTICIPANT_WRITER) prismtech_builtin_endpoint_set |= NN_DISC_BUILTIN_ENDPOINT_CM_PUBLISHER_WRITER | NN_DISC_BUILTIN_ENDPOINT_CM_SUBSCRIBER_WRITER; } - TRACE ((" %x:%x:%x:%x", PGUID (datap->participant_guid))); - /* Local SPDP packets may be looped back, and that may include ones currently being deleted. The first thing that happens when deleting a participant is removing it from the hash table, and @@ -562,14 +597,18 @@ static void handle_SPDP_alive (const struct receiver_state *rst, const nn_plist_ if (is_deleted_participant_guid (&datap->participant_guid, DPG_REMOTE)) { - TRACE ((" (recently deleted)\n")); - return; + TRACE (("SPDP ST0 "PGUIDFMT" (recently deleted)\n", PGUID (datap->participant_guid))); + return 1; } +#if LITE + if (!config.enableLoopback) +#endif { int islocal = 0; if (ephash_lookup_participant_guid (&datap->participant_guid)) islocal = 1; +#if ! LITE if (!islocal && is_own_vendor (datap->vendorid)) { os_mutexLock (&gv.privileged_pp_lock); @@ -577,10 +616,11 @@ static void handle_SPDP_alive (const struct receiver_state *rst, const nn_plist_ islocal = 2; os_mutexUnlock (&gv.privileged_pp_lock); } +#endif if (islocal) { - TRACE ((" (local %d)\n", islocal)); - return; + TRACE (("SPDP ST0 "PGUIDFMT" (local %d)\n", PGUID (datap->participant_guid), islocal)); + return 0; } } @@ -590,21 +630,21 @@ static void handle_SPDP_alive (const struct receiver_state *rst, const nn_plist_ are even skipping the automatic lease renewal. Therefore do it regardless of config.arrival_of_data_asserts_pp_and_ep_liveliness. */ - TRACE ((" (known)")); + TRACE (("SPDP ST0 "PGUIDFMT" (known)", PGUID (datap->participant_guid))); lease_renew (pa_ldvoidp (&proxypp->lease), now_et ()); os_mutexLock (&proxypp->e.lock); if (proxypp->implicitly_created) { TRACE ((" (NEW was-implicitly-created)")); proxypp->implicitly_created = 0; - update_proxy_participant_plist_locked (proxypp, datap, UPD_PROXYPP_SPDP); + update_proxy_participant_plist_locked (proxypp, datap, UPD_PROXYPP_SPDP, timestamp); } os_mutexUnlock (&proxypp->e.lock); TRACE (("\n")); - return; + return 0; } - TRACE ((" bes %x ptbes %x NEW", builtin_endpoint_set, prismtech_builtin_endpoint_set)); + nn_log (LC_DISCOVERY, "SPDP ST0 "PGUIDFMT" bes %x ptbes %x NEW", PGUID (datap->participant_guid), builtin_endpoint_set, prismtech_builtin_endpoint_set); if (datap->present & PP_PARTICIPANT_LEASE_DURATION) { @@ -612,14 +652,16 @@ static void handle_SPDP_alive (const struct receiver_state *rst, const nn_plist_ } else { - TRACE ((" (PARTICIPANT_LEASE_DURATION defaulting to 100s)")); + nn_log (LC_DISCOVERY, " (PARTICIPANT_LEASE_DURATION defaulting to 100s)"); lease_duration = nn_to_ddsi_duration (100 * T_SECOND); } +#if !LITE if ((datap->present & PP_PRISMTECH_SERVICE_TYPE) && (datap->service_type == (unsigned) V_SERVICETYPE_DDSI2 || datap->service_type == (unsigned) V_SERVICETYPE_DDSI2E)) custom_flags |= CF_PARTICIPANT_IS_DDSI2; +#endif if (datap->present & PP_PRISMTECH_PARTICIPANT_VERSION_INFO) { if (datap->prismtech_participant_version_info.flags & NN_PRISMTECH_FL_KERNEL_SEQUENCE_NUMBER) @@ -629,13 +671,13 @@ static void handle_SPDP_alive (const struct receiver_state *rst, const nn_plist_ (datap->prismtech_participant_version_info.flags & NN_PRISMTECH_FL_PARTICIPANT_IS_DDSI2)) custom_flags |= CF_PARTICIPANT_IS_DDSI2; - TRACE ((" (0x%08x-0x%08x-0x%08x-0x%08x-0x%08x %s)", + nn_log (LC_DISCOVERY, " (0x%08x-0x%08x-0x%08x-0x%08x-0x%08x %s)", datap->prismtech_participant_version_info.version, datap->prismtech_participant_version_info.flags, datap->prismtech_participant_version_info.unused[0], datap->prismtech_participant_version_info.unused[1], datap->prismtech_participant_version_info.unused[2], - datap->prismtech_participant_version_info.internals)); + datap->prismtech_participant_version_info.internals); } /* If any of the SEDP announcer are missing AND the guid prefix of @@ -649,7 +691,7 @@ static void handle_SPDP_alive (const struct receiver_state *rst, const nn_plist_ if (0 && (builtin_endpoint_set & bes_sedp_announcer_mask) != bes_sedp_announcer_mask && memcmp (&privileged_pp_guid, &datap->participant_guid, sizeof (nn_guid_t)) != 0) { - TRACE ((" (depends on %x:%x:%x:%x)", PGUID (privileged_pp_guid))); + nn_log (LC_DISCOVERY, " (depends on "PGUIDFMT")", PGUID (privileged_pp_guid)); /* never expire lease for this proxy: it won't actually expire until the "privileged" one expires anyway */ lease_duration = nn_to_ddsi_duration (T_NEVER); @@ -665,7 +707,7 @@ static void handle_SPDP_alive (const struct receiver_state *rst, const nn_plist_ { privileged_pp_guid.prefix = ddsi2->e.guid.prefix; lease_duration = nn_to_ddsi_duration (T_NEVER); - TRACE ((" (depends on %x:%x:%x:%x)", PGUID (privileged_pp_guid))); + nn_log (LC_DISCOVERY, " (depends on "PGUIDFMT")", PGUID (privileged_pp_guid)); } } else @@ -696,7 +738,7 @@ static void handle_SPDP_alive (const struct receiver_state *rst, const nn_plist_ else { uc_same_subnet = 1; - TRACE ((" subnet-filter")); + nn_log (LC_DISCOVERY, " subnet-filter"); } /* If unicast locators not present, then try to obtain from connection */ @@ -710,22 +752,22 @@ static void handle_SPDP_alive (const struct receiver_state *rst, const nn_plist_ else if (ddsi_conn_peer_locator (rst->conn, &loc)) add_to_addrset (as_meta, &loc); - nn_log_addrset (LC_TRACE, " (data", as_default); - nn_log_addrset (LC_TRACE, " meta", as_meta); - TRACE ((")")); + nn_log_addrset (LC_DISCOVERY, " (data", as_default); + nn_log_addrset (LC_DISCOVERY, " meta", as_meta); + nn_log (LC_DISCOVERY, ")"); } if (addrset_empty_uc (as_default) || addrset_empty_uc (as_meta)) { - TRACE ((" (no unicast address)\n")); + nn_log (LC_DISCOVERY, " (no unicast address)\n"); unref_addrset (as_default); unref_addrset (as_meta); - return; + return 1; } - TRACE ((" QOS={")); - nn_log_xqos (LC_TRACE, &datap->qos); - TRACE (("}\n")); + nn_log (LC_DISCOVERY, " QOS={"); + nn_log_xqos (LC_DISCOVERY, &datap->qos); + nn_log (LC_DISCOVERY, "}\n"); maybe_add_pp_as_meta_to_as_disc (as_meta); @@ -740,7 +782,8 @@ static void handle_SPDP_alive (const struct receiver_state *rst, const nn_plist_ datap, nn_from_ddsi_duration (lease_duration), rst->vendor, - custom_flags + custom_flags, + timestamp ); /* Force transmission of SPDP messages - we're not very careful @@ -751,13 +794,12 @@ static void handle_SPDP_alive (const struct receiver_state *rst, const nn_plist_ (rst->dst_guid_prefix.u[0] != 0 || rst->dst_guid_prefix.u[1] != 0 || rst->dst_guid_prefix.u[2] != 0); if (!have_dst) { - TRACE (("broadcasted SPDP packet -> answering")); + nn_log (LC_DISCOVERY, "broadcasted SPDP packet -> answering"); respond_to_spdp (&datap->participant_guid); - TRACE (("\n")); } else { - TRACE (("directed SPDP packet -> not responding\n")); + nn_log (LC_DISCOVERY, "directed SPDP packet -> not responding"); } } @@ -765,7 +807,7 @@ static void handle_SPDP_alive (const struct receiver_state *rst, const nn_plist_ { /* If we just discovered DDSI2, make sure any existing participants served by it are made dependent on it */ - make_participants_dependent_on_ddsi2 (&datap->participant_guid); + make_participants_dependent_on_ddsi2 (&datap->participant_guid, timestamp); } else if (privileged_pp_guid.prefix.u[0] || privileged_pp_guid.prefix.u[1] || privileged_pp_guid.prefix.u[2]) { @@ -774,25 +816,26 @@ static void handle_SPDP_alive (const struct receiver_state *rst, const nn_plist_ of DDSI2. */ if (ephash_lookup_proxy_participant_guid (&privileged_pp_guid) == NULL) { - TRACE (("make_participants_dependent_on_ddsi2: ddsi2 %x:%x:%x:%x is no more, delete %x:%x:%x:%x\n", PGUID (privileged_pp_guid), PGUID (datap->participant_guid))); - delete_proxy_participant_by_guid (&datap->participant_guid, 1); + nn_log (LC_DISCOVERY, "make_participants_dependent_on_ddsi2: ddsi2 "PGUIDFMT" is no more, delete "PGUIDFMT"\n", PGUID (privileged_pp_guid), PGUID (datap->participant_guid)); + delete_proxy_participant_by_guid (&datap->participant_guid, timestamp, 1); } } + return 1; } -static void handle_SPDP (const struct receiver_state *rst, unsigned statusinfo, const void *vdata, unsigned len) +static void handle_SPDP (const struct receiver_state *rst, nn_wctime_t timestamp, unsigned statusinfo, const void *vdata, unsigned len) { const struct CDRHeader *data = vdata; /* built-ins not deserialized (yet) */ - TRACE (("SPDP ST%x", statusinfo)); if (data == NULL) { - TRACE ((" no payload?\n")); + TRACE (("SPDP ST%x no payload?\n", statusinfo)); return; } else { nn_plist_t decoded_data; nn_plist_src_t src; + int interesting = 0; src.protocol_version = rst->protocol_version; src.vendorid = rst->vendor; src.encoding = data->identifier; @@ -807,17 +850,18 @@ static void handle_SPDP (const struct receiver_state *rst, unsigned statusinfo, switch (statusinfo & (NN_STATUSINFO_DISPOSE | NN_STATUSINFO_UNREGISTER)) { case 0: - handle_SPDP_alive (rst, &decoded_data); + interesting = handle_SPDP_alive (rst, timestamp, &decoded_data); break; case NN_STATUSINFO_DISPOSE: case NN_STATUSINFO_UNREGISTER: case (NN_STATUSINFO_DISPOSE | NN_STATUSINFO_UNREGISTER): - handle_SPDP_dead (rst, &decoded_data); + interesting = handle_SPDP_dead (rst, timestamp, &decoded_data, statusinfo); break; } nn_plist_fini (&decoded_data); + nn_log (interesting ? LC_DISCOVERY : LC_TRACE, "\n"); } } @@ -881,6 +925,7 @@ static int sedp_write_endpoint nn_plist_init_empty (&ps); ps.present |= PP_ENDPOINT_GUID; ps.endpoint_guid = *epguid; +#if ! LITE if (epcommon && !gid_is_fake (&epcommon->gid)) { /* Built-in endpoints are not published, so the absence of a GID for @@ -890,10 +935,12 @@ static int sedp_write_endpoint ps.present |= PP_PRISMTECH_ENDPOINT_GID; ps.endpoint_gid = epcommon->gid; } +#endif if (common && *common->name != 0) { ps.present |= PP_ENTITY_NAME; + ps.aliased |= PP_ENTITY_NAME; ps.entity_name = common->name; } @@ -916,10 +963,28 @@ static int sedp_write_endpoint { ps.present |= PP_GROUP_GUID; ps.group_guid = epcommon->group_guid; +#if ! LITE ps.present |= PP_PRISMTECH_GROUP_GID; ps.group_gid = epcommon->group_gid; +#endif } +#ifdef DDSI_INCLUDE_SSM + /* A bit of a hack -- the easy alternative would be to make it yet + another parameter. We only set "reader favours SSM" if we + really do: no point in telling the world that everything is at + the default. */ + if (!is_writer_entityid (epguid->entityid)) + { + const struct reader *rd = ephash_lookup_reader_guid (epguid); + assert (rd); + if (rd->favours_ssm) + { + ps.present |= PP_READER_FAVOURS_SSM; + ps.reader_favours_ssm.state = 1u; + } + } +#endif qosdiff = nn_xqos_delta (xqos, defqos, ~(os_uint64)0); if (config.explicitly_publish_qos_set_to_default) @@ -939,6 +1004,7 @@ static int sedp_write_endpoint nn_plist_addtomsg (mpayload, &ps, ~(os_uint64)0, ~(os_uint64)0); if (xqos) nn_xqos_addtomsg (mpayload, xqos, qosdiff); nn_xmsg_addpar_sentinel (mpayload); + nn_plist_fini (&ps); /* Then we take the payload from the message and turn it into a serdata, and then we can write it as normal data */ @@ -955,15 +1021,15 @@ static int sedp_write_endpoint serdata = ddsi_serstate_fix (serstate); nn_xmsg_free (mpayload); - TRACE (("sedp: write for %x:%x:%x:%x via %x:%x:%x:%x\n", PGUID (*epguid), PGUID (wr->e.guid))); - return write_sample (NULL, wr, serdata); + TRACE (("sedp: write for "PGUIDFMT" via "PGUIDFMT"\n", PGUID (*epguid), PGUID (wr->e.guid))); + return write_sample_nogc (NULL, wr, serdata); } static struct writer *get_sedp_writer (const struct participant *pp, unsigned entityid) { struct writer *sedp_wr = get_builtin_writer (pp, entityid); if (sedp_wr == NULL) - NN_FATAL2 ("sedp_write_writer: no SEDP builtin writer %x for %x:%x:%x:%x\n", entityid, PGUID (pp->e.guid)); + NN_FATAL2 ("sedp_write_writer: no SEDP builtin writer %x for "PGUIDFMT"\n", entityid, PGUID (pp->e.guid)); return sedp_wr; } @@ -972,7 +1038,11 @@ int sedp_write_writer (struct writer *wr) if (! is_builtin_entityid (wr->e.guid.entityid, ownvendorid)) { struct writer *sedp_wr = get_sedp_writer (wr->c.pp, NN_ENTITYID_SEDP_BUILTIN_PUBLICATIONS_WRITER); +#ifdef DDSI_INCLUDE_SSM + struct addrset *as = wr->ssm_as; +#else struct addrset *as = NULL; +#endif return sedp_write_endpoint (sedp_wr, 0, &wr->e.guid, &wr->e, &wr->c, wr->xqos, as); } return 0; @@ -983,7 +1053,11 @@ int sedp_write_reader (struct reader *rd) if (! is_builtin_entityid (rd->e.guid.entityid, ownvendorid)) { struct writer *sedp_wr = get_sedp_writer (rd->c.pp, NN_ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_WRITER); +#ifdef DDSI_INCLUDE_NETWORK_PARTITIONS + struct addrset *as = rd->as; +#else struct addrset *as = NULL; +#endif return sedp_write_endpoint (sedp_wr, 0, &rd->e.guid, &rd->e, &rd->c, rd->xqos, as); } return 0; @@ -1021,13 +1095,13 @@ static const char *durability_to_string (nn_durability_kind_t k) abort (); return 0; } -static struct proxy_participant *implicitly_create_proxypp (const nn_guid_t *ppguid, nn_plist_t *datap /* note: potentially modifies datap */, const nn_guid_prefix_t *src_guid_prefix, nn_vendorid_t vendorid) +static struct proxy_participant *implicitly_create_proxypp (const nn_guid_t *ppguid, nn_plist_t *datap /* note: potentially modifies datap */, const nn_guid_prefix_t *src_guid_prefix, nn_vendorid_t vendorid, nn_wctime_t timestamp) { nn_guid_t privguid; nn_plist_t pp_plist; if (memcmp (&ppguid->prefix, src_guid_prefix, sizeof (ppguid->prefix)) == 0) - /* if the writer is owned by the participant itself, we're not interest */ + /* if the writer is owned by the participant itself, we're not interested */ return NULL; privguid.prefix = *src_guid_prefix; @@ -1036,16 +1110,29 @@ static struct proxy_participant *implicitly_create_proxypp (const nn_guid_t *ppg if (vendor_is_cloud (vendorid)) { + nn_vendorid_t actual_vendorid; /* Some endpoint that we discovered through the DS, but then it must have at least some locators */ - TRACE ((" from-DS %x:%x:%x:%x", PGUID (privguid))); + nn_log (LC_DISCOVERY, " from-DS "PGUIDFMT"", PGUID (privguid)); /* avoid "no address" case, so we never create the proxy participant for nothing (FIXME: rework some of this) */ if (!(datap->present & (PP_UNICAST_LOCATOR | PP_MULTICAST_LOCATOR))) { - TRACE ((" data locator absent\n")); + nn_log (LC_DISCOVERY, " data locator absent\n"); goto err; } - TRACE ((" new-proxypp %x:%x:%x:%x\n", PGUID (*ppguid))); - new_proxy_participant(ppguid, 0, 0, &privguid, new_addrset(), new_addrset(), &pp_plist, T_NEVER, vendorid, CF_IMPLICITLY_CREATED_PROXYPP); + nn_log (LC_DISCOVERY, " new-proxypp "PGUIDFMT"\n", PGUID (*ppguid)); + /* We need to handle any source of entities, but we really want to try to keep the GIDs (and + certainly the systemId component) unchanged for OSPL. The new proxy participant will take + the GID from the GUID if it is from a "modern" OSPL that advertises it includes all GIDs in + the endpoint discovery; else if it is OSPL it will take at the systemId and fake the rest. + However, (1) Cloud filters out the GIDs from the discovery, and (2) DDSI2 deliberately + doesn't include the GID for internally generated endpoints (such as the fictitious transient + data readers) to signal that these are internal and have no GID (and not including a GID if + there is none is quite a reasonable approach). Point (2) means we have no reliable way of + determining whether GIDs are included based on the first endpoint, and so there is no point + doing anything about (1). That means we fall back to the legacy mode of locally generating + GIDs but leaving the system id unchanged if the remote is OSPL. */ + actual_vendorid = (datap->present & PP_VENDORID) ? datap->vendorid : vendorid; + new_proxy_participant(ppguid, 0, 0, &privguid, new_addrset(), new_addrset(), &pp_plist, T_NEVER, actual_vendorid, CF_IMPLICITLY_CREATED_PROXYPP, timestamp); } else if (ppguid->prefix.u[0] == src_guid_prefix->u[0] && vendor_is_opensplice (vendorid)) { @@ -1054,18 +1141,18 @@ static struct proxy_participant *implicitly_create_proxypp (const nn_guid_t *ppg with a minimal built-in endpoint set */ struct proxy_participant *privpp; if ((privpp = ephash_lookup_proxy_participant_guid (&privguid)) == NULL) { - TRACE ((" unknown-src-proxypp?\n")); + nn_log (LC_DISCOVERY, " unknown-src-proxypp?\n"); goto err; } else if (!privpp->is_ddsi2_pp) { - TRACE ((" src-proxypp-not-ddsi2?\n")); + nn_log (LC_DISCOVERY, " src-proxypp-not-ddsi2?\n"); goto err; } else if (!privpp->minimal_bes_mode) { - TRACE ((" src-ddsi2-not-minimal-bes-mode?\n")); + nn_log (LC_DISCOVERY, " src-ddsi2-not-minimal-bes-mode?\n"); goto err; } else { struct addrset *as_default, *as_meta; nn_plist_t tmp_plist; - TRACE ((" from-ddsi2 %x:%x:%x:%x", PGUID (privguid))); + nn_log (LC_DISCOVERY, " from-ddsi2 "PGUIDFMT"", PGUID (privguid)); nn_plist_init_empty (&pp_plist); os_mutexLock (&privpp->e.lock); @@ -1079,7 +1166,7 @@ static struct proxy_participant *implicitly_create_proxypp (const nn_guid_t *ppg os_mutexUnlock (&privpp->e.lock); pp_plist.prismtech_participant_version_info.flags &= ~NN_PRISMTECH_FL_PARTICIPANT_IS_DDSI2; - new_proxy_participant (ppguid, 0, 0, &privguid, as_default, as_meta, &pp_plist, T_NEVER, vendorid, CF_IMPLICITLY_CREATED_PROXYPP | CF_PROXYPP_NO_SPDP); + new_proxy_participant (ppguid, 0, 0, &privguid, as_default, as_meta, &pp_plist, T_NEVER, vendorid, CF_IMPLICITLY_CREATED_PROXYPP | CF_PROXYPP_NO_SPDP, timestamp); } } @@ -1088,9 +1175,9 @@ static struct proxy_participant *implicitly_create_proxypp (const nn_guid_t *ppg return ephash_lookup_proxy_participant_guid (ppguid); } -static void handle_SEDP_alive (nn_plist_t *datap /* note: potentially modifies datap */, const nn_guid_prefix_t *src_guid_prefix, nn_vendorid_t vendorid) +static void handle_SEDP_alive (nn_plist_t *datap /* note: potentially modifies datap */, const nn_guid_prefix_t *src_guid_prefix, nn_vendorid_t vendorid, nn_wctime_t timestamp) { -#define E(msg, lbl) do { nn_log (LC_TRACE, (msg)); goto lbl; } while (0) +#define E(msg, lbl) do { nn_log (LC_DISCOVERY, (msg)); goto lbl; } while (0) struct proxy_participant *pp; struct proxy_writer * pwr = NULL; struct proxy_reader * prd = NULL; @@ -1099,12 +1186,15 @@ static void handle_SEDP_alive (nn_plist_t *datap /* note: potentially modifies d int reliable; struct addrset *as; int is_writer; +#ifdef DDSI_INCLUDE_SSM + int ssm; +#endif assert (datap); if (!(datap->present & PP_ENDPOINT_GUID)) E (" no guid?\n", err); - TRACE ((" %x:%x:%x:%x", PGUID (datap->endpoint_guid))); + nn_log (LC_DISCOVERY, " "PGUIDFMT"", PGUID (datap->endpoint_guid)); ppguid.prefix = datap->endpoint_guid.prefix; ppguid.entityid.u = NN_ENTITYID_PARTICIPANT; @@ -1113,6 +1203,9 @@ static void handle_SEDP_alive (nn_plist_t *datap /* note: potentially modifies d if ( +#if LITE + (! config.enableLoopback) && +#endif (ephash_lookup_participant_guid (&ppguid) != NULL) ) E (" local pp?\n", err); @@ -1126,11 +1219,11 @@ static void handle_SEDP_alive (nn_plist_t *datap /* note: potentially modifies d if ((pp = ephash_lookup_proxy_participant_guid (&ppguid)) == NULL) { - TRACE ((" unknown-proxypp")); - if ((pp = implicitly_create_proxypp (&ppguid, datap, src_guid_prefix, vendorid)) == NULL) + nn_log (LC_DISCOVERY, " unknown-proxypp"); + if ((pp = implicitly_create_proxypp (&ppguid, datap, src_guid_prefix, vendorid, timestamp)) == NULL) E ("?\n", err); /* Repeat regular SEDP trace for convenience */ - TRACE (("SEDP ST0 %x:%x:%x:%x (cont)", PGUID (datap->endpoint_guid))); + nn_log (LC_DISCOVERY, "SEDP ST0 "PGUIDFMT" (cont)", PGUID (datap->endpoint_guid)); } xqos = &datap->qos; @@ -1150,7 +1243,7 @@ static void handle_SEDP_alive (nn_plist_t *datap /* note: potentially modifies d assert (xqos->present & QP_DURABILITY); reliable = (xqos->reliability.kind == NN_RELIABLE_RELIABILITY_QOS); - nn_log (LC_TRACE, " %s %s %s: %s%s.%s/%s", + nn_log (LC_DISCOVERY, " %s %s %s: %s%s.%s/%s", reliable ? "reliable" : "best-effort", durability_to_string (xqos->durability.kind), is_writer ? "writer" : "reader", @@ -1178,14 +1271,28 @@ static void handle_SEDP_alive (nn_plist_t *datap /* note: potentially modifies d if (! vendor_is_cloud (vendorid)) { - TRACE ((" known\n")); + nn_log (LC_DISCOVERY, " known\n"); goto err; } - TRACE ((" known-DS\n")); + + /* Re-bind the proxy participant to the discovery service - and do this if it is currently + bound to another DS instance, because that other DS instance may have already failed and + with a new one taking over, without our noticing it. */ + nn_log (LC_DISCOVERY, " known-DS"); + if (vendor_is_cloud (vendorid) && pp->implicitly_created && memcmp(&pp->privileged_pp_guid.prefix, src_guid_prefix, sizeof(pp->privileged_pp_guid.prefix)) != 0) + { + nn_etime_t never = { T_NEVER }; + nn_log (LC_DISCOVERY, " "PGUIDFMT" attach-to-DS "PGUIDFMT"", PGUID(pp->e.guid), PGUIDPREFIX(*src_guid_prefix), pp->privileged_pp_guid.entityid.u); + os_mutexLock (&pp->e.lock); + pp->privileged_pp_guid.prefix = *src_guid_prefix; + lease_set_expiry(pa_ldvoidp(&pp->lease), never); + os_mutexUnlock (&pp->e.lock); + } + nn_log (LC_DISCOVERY, "\n"); } else { - TRACE ((" NEW")); + nn_log (LC_DISCOVERY, " NEW"); } { @@ -1206,17 +1313,26 @@ static void handle_SEDP_alive (nn_plist_t *datap /* note: potentially modifies d E (" no address", err); } - nn_log_addrset (LC_TRACE, " (as", as); - TRACE ((") QOS={")); - nn_log_xqos (LC_TRACE, xqos); - TRACE (("}\n")); + nn_log_addrset (LC_DISCOVERY, " (as", as); +#ifdef DDSI_INCLUDE_SSM + ssm = 0; + if (is_writer) + ssm = addrset_contains_ssm (as); + else if (datap->present & PP_READER_FAVOURS_SSM) + ssm = (datap->reader_favours_ssm.state != 0); + nn_log (LC_DISCOVERY, " ssm=%u", ssm); +#endif + nn_log (LC_DISCOVERY, ") QOS={"); + nn_log_xqos (LC_DISCOVERY, xqos); + nn_log (LC_DISCOVERY, "}\n"); if ((datap->endpoint_guid.entityid.u & NN_ENTITYID_SOURCE_MASK) == NN_ENTITYID_SOURCE_VENDOR && !vendor_is_prismtech (vendorid)) { - TRACE (("ignoring vendor-specific endpoint %x:%x:%x:%x\n", PGUID (datap->endpoint_guid))); + nn_log (LC_DISCOVERY, "ignoring vendor-specific endpoint "PGUIDFMT"\n", PGUID (datap->endpoint_guid)); } else { +#if ! LITE if ((datap->present & PP_GROUP_GUID) && vendor_is_prismtech (vendorid)) { /* For PrismTech peers, make sure we have a proxy group: not @@ -1228,10 +1344,11 @@ static void handle_SEDP_alive (nn_plist_t *datap /* note: potentially modifies d if (datap->present & PP_PRISMTECH_GROUP_GID) { struct v_gid_s *gid = (datap->present & PP_PRISMTECH_GROUP_GID) ? &datap->group_gid : NULL; - new_proxy_group (&datap->group_guid, gid, NULL, NULL); + new_proxy_group (&datap->group_guid, gid, NULL, NULL, timestamp); } } } +#endif if (is_writer) { if (pwr) @@ -1242,7 +1359,14 @@ static void handle_SEDP_alive (nn_plist_t *datap /* note: potentially modifies d { /* not supposed to get here for built-in ones, so can determine the channel based on the transport priority */ assert (!is_builtin_entityid (datap->endpoint_guid.entityid, vendorid)); - new_proxy_writer (&ppguid, &datap->endpoint_guid, as, datap, gv.user_dqueue, gv.xevents); +#ifdef DDSI_INCLUDE_NETWORK_CHANNELS + { + struct config_channel_listelem *channel = find_channel (xqos->transport_priority); + new_proxy_writer (&ppguid, &datap->endpoint_guid, as, datap, channel->dqueue, channel->evq ? channel->evq : gv.xevents, timestamp); + } +#else + new_proxy_writer (&ppguid, &datap->endpoint_guid, as, datap, gv.user_dqueue, gv.xevents, timestamp); +#endif } } else @@ -1253,7 +1377,11 @@ static void handle_SEDP_alive (nn_plist_t *datap /* note: potentially modifies d } else { - new_proxy_reader (&ppguid, &datap->endpoint_guid, as, datap); +#ifdef DDSI_INCLUDE_SSM + new_proxy_reader (&ppguid, &datap->endpoint_guid, as, datap, timestamp, ssm); +#else + new_proxy_reader (&ppguid, &datap->endpoint_guid, as, datap, timestamp); +#endif } } } @@ -1266,33 +1394,33 @@ static void handle_SEDP_alive (nn_plist_t *datap /* note: potentially modifies d #undef E } -static void handle_SEDP_dead (nn_plist_t *datap) +static void handle_SEDP_dead (nn_plist_t *datap, nn_wctime_t timestamp) { int res; if (!(datap->present & PP_ENDPOINT_GUID)) { - TRACE ((" no guid?\n")); + nn_log (LC_DISCOVERY, " no guid?\n"); return; } - TRACE ((" %x:%x:%x:%x", PGUID (datap->endpoint_guid))); + nn_log (LC_DISCOVERY, " "PGUIDFMT"", PGUID (datap->endpoint_guid)); if (is_writer_entityid (datap->endpoint_guid.entityid)) { - res = delete_proxy_writer (&datap->endpoint_guid, 0); + res = delete_proxy_writer (&datap->endpoint_guid, timestamp, 0); } else { - res = delete_proxy_reader (&datap->endpoint_guid, 0); + res = delete_proxy_reader (&datap->endpoint_guid, timestamp, 0); } - TRACE ((" %s\n", (res < 0) ? " unknown" : " delete")); + nn_log (LC_DISCOVERY, " %s\n", (res < 0) ? " unknown" : " delete"); } -static void handle_SEDP (const struct receiver_state *rst, unsigned statusinfo, const void *vdata, unsigned len) +static void handle_SEDP (const struct receiver_state *rst, nn_wctime_t timestamp, unsigned statusinfo, const void *vdata, unsigned len) { const struct CDRHeader *data = vdata; /* built-ins not deserialized (yet) */ - TRACE (("SEDP ST%x", statusinfo)); + nn_log (LC_DISCOVERY, "SEDP ST%x", statusinfo); if (data == NULL) { - TRACE ((" no payload?\n")); + nn_log (LC_DISCOVERY, " no payload?\n"); return; } else @@ -1313,13 +1441,13 @@ static void handle_SEDP (const struct receiver_state *rst, unsigned statusinfo, switch (statusinfo & (NN_STATUSINFO_DISPOSE | NN_STATUSINFO_UNREGISTER)) { case 0: - handle_SEDP_alive (&decoded_data, &rst->src_guid_prefix, rst->vendor); + handle_SEDP_alive (&decoded_data, &rst->src_guid_prefix, rst->vendor, timestamp); break; case NN_STATUSINFO_DISPOSE: case NN_STATUSINFO_UNREGISTER: case (NN_STATUSINFO_DISPOSE | NN_STATUSINFO_UNREGISTER): - handle_SEDP_dead (&decoded_data); + handle_SEDP_dead (&decoded_data, timestamp); break; } @@ -1375,19 +1503,20 @@ int sedp_write_topic (struct participant *pp, const struct nn_plist *datap) serdata = ddsi_serstate_fix (serstate); nn_xmsg_free (mpayload); - TRACE (("sedp: write topic %s via %x:%x:%x:%x\n", datap->qos.topic_name, PGUID (sedp_wr->e.guid))); - return write_sample (NULL, sedp_wr, serdata); + TRACE (("sedp: write topic %s via "PGUIDFMT"\n", datap->qos.topic_name, PGUID (sedp_wr->e.guid))); + return write_sample_nogc (NULL, sedp_wr, serdata); } -static void handle_SEDP_TOPIC (const struct receiver_state *rst, nn_entityid_t wr_entity_id, unsigned statusinfo, const void *vdata, unsigned len) +#if ! LITE +static void handle_SEDP_TOPIC (const struct receiver_state *rst, nn_entityid_t wr_entity_id, nn_wctime_t timestamp, unsigned statusinfo, const void *vdata, unsigned len) { const struct CDRHeader *data = vdata; /* built-ins not deserialized (yet) */ - TRACE (("SEDP_TOPIC ST%x", statusinfo)); + nn_log (LC_DISCOVERY, "SEDP_TOPIC ST%x", statusinfo); assert (wr_entity_id.u == NN_ENTITYID_SEDP_BUILTIN_TOPIC_WRITER); (void) wr_entity_id; if (data == NULL) { - TRACE ((" no payload?\n")); + nn_log (LC_DISCOVERY, " no payload?\n"); return; } else @@ -1417,18 +1546,19 @@ static void handle_SEDP_TOPIC (const struct receiver_state *rst, nn_entityid_t w } else { - TRACE ((" %s/%s QOS={", decoded_data.qos.topic_name, decoded_data.qos.type_name)); + nn_log (LC_DISCOVERY, " %s/%s QOS={", decoded_data.qos.topic_name, decoded_data.qos.type_name); nn_xqos_mergein_missing (&decoded_data.qos, &gv.default_xqos_tp); - nn_log_xqos (LC_TRACE, &decoded_data.qos); - TRACE (("}")); - write_builtin_topic_proxy_topic (&decoded_data); + nn_log_xqos (LC_DISCOVERY, &decoded_data.qos); + nn_log (LC_DISCOVERY, "}"); + write_builtin_topic_proxy_topic (&decoded_data, timestamp); } } nn_plist_fini (&decoded_data); } - TRACE (("\n")); + nn_log (LC_DISCOVERY, "\n"); } +#endif /****************************************************************************** *** @@ -1482,19 +1612,19 @@ int sedp_write_cm_participant (struct participant *pp, int alive) serdata = ddsi_serstate_fix (serstate); nn_xmsg_free (mpayload); - TRACE (("sedp: write CMParticipant ST%x for %x:%x:%x:%x via %x:%x:%x:%x\n", statusinfo, PGUID (pp->e.guid), PGUID (sedp_wr->e.guid))); - return write_sample (NULL, sedp_wr, serdata); + TRACE (("sedp: write CMParticipant ST%x for "PGUIDFMT" via "PGUIDFMT"\n", statusinfo, PGUID (pp->e.guid), PGUID (sedp_wr->e.guid))); + return write_sample_nogc (NULL, sedp_wr, serdata); } -static void handle_SEDP_CM (const struct receiver_state *rst, nn_entityid_t wr_entity_id, unsigned statusinfo, const void *vdata, unsigned len) +static void handle_SEDP_CM (const struct receiver_state *rst, nn_entityid_t wr_entity_id, nn_wctime_t timestamp, unsigned statusinfo, const void *vdata, unsigned len) { const struct CDRHeader *data = vdata; /* built-ins not deserialized (yet) */ - TRACE (("SEDP_CM ST%x", statusinfo)); + nn_log (LC_DISCOVERY, "SEDP_CM ST%x", statusinfo); assert (wr_entity_id.u == NN_ENTITYID_SEDP_BUILTIN_CM_PARTICIPANT_WRITER); (void) wr_entity_id; if (data == NULL) { - TRACE ((" no payload?\n")); + nn_log (LC_DISCOVERY, " no payload?\n"); return; } else @@ -1521,15 +1651,15 @@ static void handle_SEDP_CM (const struct receiver_state *rst, nn_entityid_t wr_e else { if ((proxypp = ephash_lookup_proxy_participant_guid (&decoded_data.participant_guid)) == NULL) - proxypp = implicitly_create_proxypp (&decoded_data.participant_guid, &decoded_data, &rst->src_guid_prefix, rst->vendor); + proxypp = implicitly_create_proxypp (&decoded_data.participant_guid, &decoded_data, &rst->src_guid_prefix, rst->vendor, timestamp); if (proxypp != NULL) - update_proxy_participant_plist (proxypp, &decoded_data, UPD_PROXYPP_CM); + update_proxy_participant_plist (proxypp, &decoded_data, UPD_PROXYPP_CM, timestamp); } } nn_plist_fini (&decoded_data); } - TRACE (("\n")); + nn_log (LC_DISCOVERY, "\n"); } static struct participant *group_guid_to_participant (const nn_guid_t *group_guid) @@ -1555,7 +1685,7 @@ int sedp_write_cm_publisher (const struct nn_plist *datap, int alive) if ((pp = group_guid_to_participant (&datap->group_guid)) == NULL) { - TRACE (("sedp: write CMPublisher alive:%d for %x:%x:%x:%x dropped: no participant\n", + TRACE (("sedp: write CMPublisher alive:%d for "PGUIDFMT" dropped: no participant\n", alive, PGUID (datap->group_guid))); return 0; } @@ -1592,11 +1722,13 @@ int sedp_write_cm_publisher (const struct nn_plist *datap, int alive) serdata = ddsi_serstate_fix (serstate); nn_xmsg_free (mpayload); - TRACE (("sedp: write CMPublisher ST%x for %x:%x:%x:%x (%x:%x:%x) via %x:%x:%x:%x\n", +#if ! LITE + TRACE (("sedp: write CMPublisher ST%x for "PGUIDFMT" ("PGIDFMT") via "PGUIDFMT"\n", statusinfo, PGUID (datap->group_guid), - datap->group_gid.systemId, datap->group_gid.localId, datap->group_gid.serial, + PGID(datap->group_gid), PGUID (sedp_wr->e.guid))); - return write_sample (NULL, sedp_wr, serdata); +#endif + return write_sample_nogc (NULL, sedp_wr, serdata); } int sedp_write_cm_subscriber (const struct nn_plist *datap, int alive) @@ -1614,7 +1746,7 @@ int sedp_write_cm_subscriber (const struct nn_plist *datap, int alive) if ((pp = group_guid_to_participant (&datap->group_guid)) == NULL) { - TRACE (("sedp: write CMSubscriber alive:%d for %x:%x:%x:%x dropped: no participant\n", + TRACE (("sedp: write CMSubscriber alive:%d for "PGUIDFMT" dropped: no participant\n", alive, PGUID (datap->group_guid))); return 0; } @@ -1651,62 +1783,66 @@ int sedp_write_cm_subscriber (const struct nn_plist *datap, int alive) serdata = ddsi_serstate_fix (serstate); nn_xmsg_free (mpayload); - TRACE (("sedp: write CMSubscriber ST%x for %x:%x:%x:%x (%x:%x:%x) via %x:%x:%x:%x\n", +#if ! LITE + TRACE (("sedp: write CMSubscriber ST%x for "PGUIDFMT" ("PGIDFMT") via "PGUIDFMT"\n", statusinfo, PGUID (datap->group_guid), - datap->group_gid.systemId, datap->group_gid.localId, datap->group_gid.serial, + PGID(datap->group_gid), PGUID (sedp_wr->e.guid))); - return write_sample (NULL, sedp_wr, serdata); +#endif + return write_sample_nogc (NULL, sedp_wr, serdata); } -static void handle_SEDP_GROUP_alive (nn_plist_t *datap /* note: potentially modifies datap */) +static void handle_SEDP_GROUP_alive (nn_plist_t *datap /* note: potentially modifies datap */, nn_wctime_t timestamp) { -#define E(msg, lbl) do { nn_log (LC_TRACE, (msg)); goto lbl; } while (0) +#define E(msg, lbl) do { nn_log (LC_DISCOVERY, (msg)); goto lbl; } while (0) nn_guid_t ppguid; if (!(datap->present & PP_GROUP_GUID)) E (" no guid?\n", err); - TRACE ((" %x:%x:%x:%x", PGUID (datap->group_guid))); + nn_log (LC_DISCOVERY, " "PGUIDFMT"", PGUID (datap->group_guid)); ppguid.prefix = datap->group_guid.prefix; ppguid.entityid.u = NN_ENTITYID_PARTICIPANT; if (ephash_lookup_proxy_participant_guid (&ppguid) == NULL) E (" unknown proxy pp?\n", err); - TRACE ((" alive\n")); + nn_log (LC_DISCOVERY, " alive\n"); { struct v_gid_s *gid = NULL; char *name; +#if ! LITE if (datap->present & PP_PRISMTECH_GROUP_GID) { gid = &datap->group_gid; } +#endif name = (datap->present & PP_ENTITY_NAME) ? datap->entity_name : ""; - new_proxy_group (&datap->group_guid, gid, name, &datap->qos); + new_proxy_group (&datap->group_guid, gid, name, &datap->qos, timestamp); } err: return; #undef E } -static void handle_SEDP_GROUP_dead (nn_plist_t *datap) +static void handle_SEDP_GROUP_dead (nn_plist_t *datap, nn_wctime_t timestamp) { if (!(datap->present & PP_GROUP_GUID)) { - TRACE ((" no guid?\n")); + nn_log (LC_DISCOVERY, " no guid?\n"); return; } - TRACE ((" %x:%x:%x:%x\n", PGUID (datap->group_guid))); - delete_proxy_group (&datap->group_guid, 0); + nn_log (LC_DISCOVERY, " "PGUIDFMT"\n", PGUID (datap->group_guid)); + delete_proxy_group (&datap->group_guid, timestamp, 0); } -static void handle_SEDP_GROUP (const struct receiver_state *rst, unsigned statusinfo, const void *vdata, unsigned len) +static void handle_SEDP_GROUP (const struct receiver_state *rst, nn_wctime_t timestamp, unsigned statusinfo, const void *vdata, unsigned len) { const struct CDRHeader *data = vdata; /* built-ins not deserialized (yet) */ - TRACE (("SEDP_GROUP ST%x", statusinfo)); + nn_log (LC_DISCOVERY, "SEDP_GROUP ST%x", statusinfo); if (data == NULL) { - TRACE ((" no payload?\n")); + nn_log (LC_DISCOVERY, " no payload?\n"); return; } else @@ -1727,13 +1863,13 @@ static void handle_SEDP_GROUP (const struct receiver_state *rst, unsigned status switch (statusinfo & (NN_STATUSINFO_DISPOSE | NN_STATUSINFO_UNREGISTER)) { case 0: - handle_SEDP_GROUP_alive (&decoded_data); + handle_SEDP_GROUP_alive (&decoded_data, timestamp); break; case NN_STATUSINFO_DISPOSE: case NN_STATUSINFO_UNREGISTER: case (NN_STATUSINFO_DISPOSE | NN_STATUSINFO_UNREGISTER): - handle_SEDP_GROUP_dead (&decoded_data); + handle_SEDP_GROUP_dead (&decoded_data, timestamp); break; } @@ -1793,6 +1929,8 @@ int builtins_dqueue_handler (const struct nn_rsample_info *sampleinfo, const str unsigned char *datap; int needs_free; os_uint32 datasz = sampleinfo->size; + nn_wctime_t timestamp; + needs_free = defragment (&datap, fragchain, sampleinfo->size); /* Luckily, most of the Data and DataFrag headers are the same - and @@ -1839,7 +1977,7 @@ int builtins_dqueue_handler (const struct nn_rsample_info *sampleinfo, const str src.bufsz = NN_RDATA_PAYLOAD_OFF (fragchain) - qos_offset; if (nn_plist_init_frommsg (&qos, NULL, PP_STATUSINFO | PP_KEYHASH, 0, &src) < 0) { - NN_WARNING4 ("data(builtin, vendor %d.%d): %x:%x:%x:%x #%lld: invalid inline qos\n", + NN_WARNING4 ("data(builtin, vendor %d.%d): "PGUIDFMT" #%lld: invalid inline qos\n", src.vendorid.id[0], src.vendorid.id[1], PGUID (srcguid), (long long int) sampleinfo->seq); goto done_upd_deliv; @@ -1864,7 +2002,7 @@ int builtins_dqueue_handler (const struct nn_rsample_info *sampleinfo, const str { if (datasz == 0 || !(data_smhdr_flags & DATA_FLAG_DATAFLAG)) { - NN_WARNING4 ("data(builtin, vendor %d.%d): %x:%x:%x:%x #%lld: " + NN_WARNING4 ("data(builtin, vendor %d.%d): "PGUIDFMT" #%lld: " "built-in data but no payload\n", sampleinfo->rst->vendor.id[0], sampleinfo->rst->vendor.id[1], PGUID (srcguid), (long long int) sampleinfo->seq); @@ -1878,7 +2016,7 @@ int builtins_dqueue_handler (const struct nn_rsample_info *sampleinfo, const str hasn't been checked fully yet. */ if (!(data_smhdr_flags & DATA_FLAG_KEYFLAG)) { - NN_WARNING4 ("data(builtin, vendor %d.%d): %x:%x:%x:%x #%lld: " + NN_WARNING4 ("data(builtin, vendor %d.%d): "PGUIDFMT" #%lld: " "dispose/unregister of built-in data but payload not just key\n", sampleinfo->rst->vendor.id[0], sampleinfo->rst->vendor.id[1], PGUID (srcguid), (long long int) sampleinfo->seq); @@ -1920,7 +2058,7 @@ int builtins_dqueue_handler (const struct nn_rsample_info *sampleinfo, const str pid = PID_ENDPOINT_GUID; break; default: - NN_WARNING4 ("data(builtin, vendor %d.%d): %x:%x:%x:%x #%lld: mapping keyhash to ENDPOINT_GUID", + NN_WARNING4 ("data(builtin, vendor %d.%d): "PGUIDFMT" #%lld: mapping keyhash to ENDPOINT_GUID", sampleinfo->rst->vendor.id[0], sampleinfo->rst->vendor.id[1], PGUID (srcguid), (long long int) sampleinfo->seq); pid = PID_ENDPOINT_GUID; @@ -1937,37 +2075,40 @@ int builtins_dqueue_handler (const struct nn_rsample_info *sampleinfo, const str } else { - NN_WARNING4 ("data(builtin, vendor %d.%d): %x:%x:%x:%x #%lld: " + NN_WARNING4 ("data(builtin, vendor %d.%d): "PGUIDFMT" #%lld: " "dispose/unregister with no content\n", sampleinfo->rst->vendor.id[0], sampleinfo->rst->vendor.id[1], PGUID (srcguid), (long long int) sampleinfo->seq); goto done_upd_deliv; } + timestamp = valid_ddsi_timestamp(sampleinfo->timestamp) ? nn_wctime_from_ddsi_time(sampleinfo->timestamp): now(); switch (srcguid.entityid.u) { case NN_ENTITYID_SPDP_BUILTIN_PARTICIPANT_WRITER: - handle_SPDP (sampleinfo->rst, statusinfo, datap, datasz); + handle_SPDP (sampleinfo->rst, timestamp, statusinfo, datap, datasz); break; case NN_ENTITYID_SEDP_BUILTIN_PUBLICATIONS_WRITER: case NN_ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_WRITER: - handle_SEDP (sampleinfo->rst, statusinfo, datap, datasz); + handle_SEDP (sampleinfo->rst, timestamp, statusinfo, datap, datasz); break; case NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_WRITER: - handle_PMD (sampleinfo->rst, statusinfo, datap, datasz); + handle_PMD (sampleinfo->rst, timestamp, statusinfo, datap, datasz); break; case NN_ENTITYID_SEDP_BUILTIN_CM_PARTICIPANT_WRITER: - handle_SEDP_CM (sampleinfo->rst, srcguid.entityid, statusinfo, datap, datasz); + handle_SEDP_CM (sampleinfo->rst, srcguid.entityid, timestamp, statusinfo, datap, datasz); break; case NN_ENTITYID_SEDP_BUILTIN_CM_PUBLISHER_WRITER: case NN_ENTITYID_SEDP_BUILTIN_CM_SUBSCRIBER_WRITER: - handle_SEDP_GROUP (sampleinfo->rst, statusinfo, datap, datasz); + handle_SEDP_GROUP (sampleinfo->rst, timestamp, statusinfo, datap, datasz); break; +#if ! LITE case NN_ENTITYID_SEDP_BUILTIN_TOPIC_WRITER: - handle_SEDP_TOPIC (sampleinfo->rst, srcguid.entityid, statusinfo, datap, datasz); + handle_SEDP_TOPIC (sampleinfo->rst, srcguid.entityid, timestamp, statusinfo, datap, datasz); break; +#endif default: - NN_WARNING4 ("data(builtin, vendor %d.%d): %x:%x:%x:%x #%lld: not handled\n", + NN_WARNING4 ("data(builtin, vendor %d.%d): "PGUIDFMT" #%lld: not handled\n", sampleinfo->rst->vendor.id[0], sampleinfo->rst->vendor.id[1], PGUID (srcguid), (long long int) sampleinfo->seq); break; @@ -1983,5 +2124,3 @@ int builtins_dqueue_handler (const struct nn_rsample_info *sampleinfo, const str } return 0; } - -/* SHA1 not available (unoffical build.) */ diff --git a/src/services/ddsi2e/core/q_ddsi_discovery.h b/src/services/ddsi2e/core/q_ddsi_discovery.h new file mode 100644 index 000000000..e3b446e16 --- /dev/null +++ b/src/services/ddsi2e/core/q_ddsi_discovery.h @@ -0,0 +1,53 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#ifndef NN_DDSI_DISCOVERY_H +#define NN_DDSI_DISCOVERY_H + +#include "q_unused.h" + +#if defined (__cplusplus) +extern "C" { +#endif + +struct participant; +struct writer; +struct reader; +struct nn_rsample_info; +struct nn_rdata; +struct nn_plist; + +int spdp_write (struct participant *pp); +int spdp_dispose_unregister (struct participant *pp); + +int sedp_write_writer (struct writer *wr); +int sedp_write_reader (struct reader *rd); +int sedp_dispose_unregister_writer (struct writer *wr); +int sedp_dispose_unregister_reader (struct reader *rd); + +int sedp_write_topic (struct participant *pp, const struct nn_plist *datap); +int sedp_write_cm_participant (struct participant *pp, int alive); +int sedp_write_cm_publisher (const struct nn_plist *datap, int alive); +int sedp_write_cm_subscriber (const struct nn_plist *datap, int alive); + +int builtins_dqueue_handler (const struct nn_rsample_info *sampleinfo, const struct nn_rdata *fragchain, const nn_guid_t *rdguid, void *qarg); + +#if defined (__cplusplus) +} +#endif + +#endif /* NN_DDSI_DISCOVERY_H */ diff --git a/src/services/ddsi2/code/q_debmon.c b/src/services/ddsi2e/core/q_debmon.c similarity index 89% rename from src/services/ddsi2/code/q_debmon.c rename to src/services/ddsi2e/core/q_debmon.c index 00d60ad12..20582f27a 100644 --- a/src/services/ddsi2/code/q_debmon.c +++ b/src/services/ddsi2e/core/q_debmon.c @@ -1,18 +1,16 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * @@ -53,16 +51,16 @@ #include "ddsi_ser.h" #include "ddsi_tran.h" #include "ddsi_tcp.h" +#if ! LITE #include "q_mtreader.h" #include "q_groupset.h" #include "v_topic.h" #include "v_partition.h" #include "v_group.h" +#endif #include "sysdeps.h" -#define PGID(x) (x).systemId, (x).localId, (x).serial - struct plugin { debug_monitor_plugin_t fn; void *arg; @@ -138,11 +136,17 @@ static int print_addrset_if_notempty (ddsi_tran_conn_t conn, const char *prefix, } static int print_any_endpoint_common (ddsi_tran_conn_t conn, const char *label, const struct entity_common *e, +#if ! LITE const struct v_gid_s *gid, +#endif const struct nn_xqos *xqos, const struct sertopic *topic) { int x = 0; - x += cpf (conn, " %s %x:%x:%x:%x gid %x:%x:%x ", label, PGUID (e->guid), PGID (*gid)); +#if ! LITE + x += cpf (conn, " %s "PGUIDFMT" gid "PGIDFMT" ", label, PGUID (e->guid), PGID (*gid)); +#else + x += cpf (conn, " %s "PGUIDFMT" ", label, PGUID (e->guid)); +#endif if (xqos->present & QP_PARTITION) { unsigned i; @@ -160,21 +164,32 @@ static int print_any_endpoint_common (ddsi_tran_conn_t conn, const char *label, static int print_endpoint_common (ddsi_tran_conn_t conn, const char *label, const struct entity_common *e, const struct endpoint_common *c, const struct nn_xqos *xqos, const struct sertopic *topic) { +#if ! LITE return print_any_endpoint_common (conn, label, e, &c->gid, xqos, topic); +#else + OS_UNUSED_ARG (c); + return print_any_endpoint_common (conn, label, e, xqos, topic); +#endif } static int print_proxy_endpoint_common (ddsi_tran_conn_t conn, const char *label, const struct entity_common *e, const struct proxy_endpoint_common *c) { int x = 0; +#if ! LITE x += print_any_endpoint_common (conn, label, e, &c->gid, c->xqos, c->topic); +#else + x += print_any_endpoint_common (conn, label, e, c->xqos, c->topic); +#endif x += print_addrset_if_notempty (conn, " as", c->as, "\n"); return x; } +#if ! LITE static int print_group_helper (v_group group, void *vconn) { return cpf (vconn, " group %p %s.%s\n", group, v_topicName(v_groupTopic(group)), v_partitionName(v_groupPartition(group))); } +#endif static int print_participants (struct thread_state1 *self, ddsi_tran_conn_t conn) { @@ -186,7 +201,7 @@ static int print_participants (struct thread_state1 *self, ddsi_tran_conn_t conn while ((p = ephash_enum_participant_next (&e)) != NULL) { os_mutexLock (&p->e.lock); - x += cpf (conn, "pp %x:%x:%x:%x %s%s\n", PGUID (p->e.guid), p->e.name, p->is_ddsi2_pp ? " [ddsi2]" : ""); + x += cpf (conn, "pp "PGUIDFMT" %s%s\n", PGUID (p->e.guid), p->e.name, p->is_ddsi2_pp ? " [ddsi2]" : ""); os_mutexUnlock (&p->e.lock); { @@ -201,9 +216,14 @@ static int print_participants (struct thread_state1 *self, ddsi_tran_conn_t conn continue; os_mutexLock (&r->e.lock); print_endpoint_common (conn, "rd", &r->e, &r->c, r->xqos, r->topic); +#if ! LITE nn_groupset_foreach (r->matching_groups, print_group_helper, conn); +#endif +#ifdef DDSI_INCLUDE_NETWORK_PARTITIONS + x += print_addrset_if_notempty (conn, " as", r->as, "\n"); +#endif for (m = ut_avlIterFirst (&rd_writers_treedef, &r->writers, &writ); m; m = ut_avlIterNext (&writ)) - x += cpf (conn, " pwr %x:%x:%x:%x\n", PGUID (m->pwr_guid)); + x += cpf (conn, " pwr "PGUIDFMT"\n", PGUID (m->pwr_guid)); os_mutexUnlock (&r->e.lock); } ephash_enum_reader_fini (&er); @@ -245,7 +265,7 @@ static int print_participants (struct thread_state1 *self, ddsi_tran_conn_t conn wr_prd_flags[1] = m->assumed_in_sync ? 's' : '.'; wr_prd_flags[2] = m->has_replied_to_hb ? 'a' : '.'; /* a = ack seen */ wr_prd_flags[3] = 0; - x += cpf (conn, " prd %x:%x:%x:%x %s @ %lld [%lld,%lld] #nacks %u\n", + x += cpf (conn, " prd "PGUIDFMT" %s @ %lld [%lld,%lld] #nacks %u\n", PGUID (m->prd_guid), wr_prd_flags, m->seq, m->min_seq, m->max_seq, m->rexmit_requests); } os_mutexUnlock (&w->e.lock); @@ -268,7 +288,11 @@ static int print_proxy_participants (struct thread_state1 *self, ddsi_tran_conn_ while ((p = ephash_enum_proxy_participant_next (&e)) != NULL) { os_mutexLock (&p->e.lock); - x += cpf (conn, "proxypp %x:%x:%x:%x gid %x:%x:%x%s\n", PGUID (p->e.guid), PGID (p->gid), p->is_ddsi2_pp ? " [ddsi2]" : ""); +#if ! LITE + x += cpf (conn, "proxypp "PGUIDFMT" gid "PGIDFMT"%s\n", PGUID (p->e.guid), PGID (p->gid), p->is_ddsi2_pp ? " [ddsi2]" : ""); +#else + x += cpf (conn, "proxypp "PGUIDFMT"%s\n", PGUID (p->e.guid), p->is_ddsi2_pp ? " [ddsi2]" : ""); +#endif os_mutexUnlock (&p->e.lock); x += print_addrset (conn, " as data", p->as_default, ""); x += print_addrset (conn, " meta", p->as_default, "\n"); @@ -286,7 +310,7 @@ static int print_proxy_participants (struct thread_state1 *self, ddsi_tran_conn_ os_mutexLock (&r->e.lock); print_proxy_endpoint_common (conn, "prd", &r->e, &r->c); for (m = ut_avlIterFirst (&rd_writers_treedef, &r->writers, &writ); m; m = ut_avlIterNext (&writ)) - x += cpf (conn, " wr %x:%x:%x:%x\n", PGUID (m->wr_guid)); + x += cpf (conn, " wr "PGUIDFMT"\n", PGUID (m->wr_guid)); os_mutexUnlock (&r->e.lock); } ephash_enum_proxy_reader_fini (&er); @@ -304,11 +328,13 @@ static int print_proxy_participants (struct thread_state1 *self, ddsi_tran_conn_ continue; os_mutexLock (&w->e.lock); print_proxy_endpoint_common (conn, "pwr", &w->e, &w->c); +#if ! LITE nn_groupset_foreach (w->groups, print_group_helper, conn); +#endif x += cpf (conn, " last_seq %lld last_fragnum %u cs_seq %lld txn %u\n", w->last_seq, w->last_fragnum, w->cs_seq, w->transaction_id); for (m = ut_avlIterFirst (&wr_readers_treedef, &w->readers, &rdit); m; m = ut_avlIterNext (&rdit)) { - x += cpf (conn, " rd %x:%x:%x:%x (nack %lld %lld)\n", + x += cpf (conn, " rd "PGUIDFMT" (nack %lld %lld)\n", PGUID (m->rd_guid), m->seq_last_nack, m->t_last_nack); switch (m->in_sync) { @@ -459,5 +485,3 @@ void free_debug_monitor (struct debug_monitor *dm) os_free (dm); } - -/* SHA1 not available (unoffical build.) */ diff --git a/src/services/ddsi2e/core/q_debmon.h b/src/services/ddsi2e/core/q_debmon.h new file mode 100644 index 000000000..4fc0fcba2 --- /dev/null +++ b/src/services/ddsi2e/core/q_debmon.h @@ -0,0 +1,29 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#ifndef Q_DEBMON_H +#define Q_DEBMON_H + +struct debug_monitor; +typedef int (*debug_monitor_cpf_t) (ddsi_tran_conn_t conn, const char *fmt, ...); +typedef int (*debug_monitor_plugin_t) (ddsi_tran_conn_t conn, debug_monitor_cpf_t cpf, void *arg); + +struct debug_monitor *new_debug_monitor (int port); +void add_debug_monitor_plugin (struct debug_monitor *dm, debug_monitor_plugin_t fn, void *arg); +void free_debug_monitor (struct debug_monitor *dm); + +#endif /* defined(__ospli_osplo__q_debmon__) */ diff --git a/src/services/ddsi2/code/q_entity.c b/src/services/ddsi2e/core/q_entity.c similarity index 77% rename from src/services/ddsi2/code/q_entity.c rename to src/services/ddsi2e/core/q_entity.c index e83882996..60822601a 100644 --- a/src/services/ddsi2/code/q_entity.c +++ b/src/services/ddsi2e/core/q_entity.c @@ -1,18 +1,16 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * @@ -30,9 +28,12 @@ #include "os_socket.h" #include "os_atomics.h" +#if !LITE #include "v_partition.h" #include "v_entity.h" #include "v_groupSet.h" +#include "v_builtin.h" +#endif #include "q_entity.h" #include "q_config.h" @@ -45,7 +46,9 @@ #include "q_lease.h" #include "q_osplser.h" #include "q_qosmatch.h" +#if !LITE #include "q_groupset.h" +#endif #include "q_ephash.h" #include "q_globals.h" #include "q_addrset.h" @@ -55,7 +58,9 @@ #include "q_radmin.h" #include "q_protocol.h" /* NN_ENTITYID_... */ #include "q_unused.h" +#if !LITE #include "q_fill_msg_qos.h" +#endif #include "q_error.h" #include "q_builtin_topic.h" #include "ddsi_ser.h" @@ -106,9 +111,14 @@ static struct writer * new_writer_guid struct participant *pp, const struct sertopic *topic, const struct nn_xqos *xqos, +#if LITE + status_cb_t status_cb, + void *status_cbarg +#else const struct v_gid_s *gid, const struct v_gid_s *group_gid, const char *endpoint_name +#endif ); static struct reader * new_reader_guid ( @@ -117,13 +127,19 @@ static struct reader * new_reader_guid struct participant *pp, const struct sertopic *topic, const struct nn_xqos *xqos, +#if LITE + struct rhc *rhc, + status_cb_t status_cb, + void *status_cbarg +#else const struct v_gid_s *gid, const struct v_gid_s *group_gid, const char *endpoint_name +#endif ); static struct participant *ref_participant (struct participant *pp, const struct nn_guid *guid_of_refing_entity); static void unref_participant (struct participant *pp, const struct nn_guid *guid_of_refing_entity); -static void delete_proxy_group_locked (struct proxy_group *pgroup, int isimplicit); +static void delete_proxy_group_locked (struct proxy_group *pgroup, nn_wctime_t timestamp, int isimplicit); static int gcreq_participant (struct participant *pp); static int gcreq_writer (struct writer *wr); @@ -193,6 +209,9 @@ static void entity_common_init (struct entity_common *e, const struct nn_guid *g e->guid = *guid; e->kind = kind; e->name = os_strdup (name ? name : ""); +#if LITE + e->iid = (ddsi_plugin.iidgen_fn) (); +#endif os_mutexInit (&e->lock, NULL); } @@ -280,7 +299,7 @@ static void remove_deleted_participant_guid (const struct nn_guid *guid, unsigne if (!config.prune_deleted_ppant.enforce_delay) { struct deleted_participant *n; - TRACE (("remove_deleted_participant_guid(%x:%x:%x:%x for_what=%x)\n", PGUID (*guid), for_what)); + TRACE (("remove_deleted_participant_guid("PGUIDFMT" for_what=%x)\n", PGUID (*guid), for_what)); os_mutexLock (&deleted_participants_lock); if ((n = ut_avlLookup (&deleted_participants_treedef, &deleted_participants, guid)) != NULL) { @@ -308,6 +327,7 @@ static void remove_deleted_participant_guid (const struct nn_guid *guid, unsigne } } +#if !LITE /* DYNAMIC GROUP CREATION FOR WILDCARD ENDPOINTS -------------------- */ static void add_group_to_readers_and_proxy_writers_locked (const struct sertopic *topic, const char *name, v_group group) { @@ -317,7 +337,7 @@ static void add_group_to_readers_and_proxy_writers_locked (const struct sertopic struct proxy_writer *pwr; struct reader *rd; - TRACE (("add_group_to_readers_and_proxy_writers_locked: %s.%s group %p scanning all readers/writers\n", name, topic->name, (void *) group)); + nn_log (LC_DISCOVERY, "add_group_to_readers_and_proxy_writers_locked: %s.%s group %p scanning all readers/writers\n", name, topic->name, (void *) group); nn_xqos_init_empty (&dummy_part_xqos); dummy_part_xqos.present = QP_PARTITION; @@ -329,7 +349,7 @@ static void add_group_to_readers_and_proxy_writers_locked (const struct sertopic { if (rd->topic == topic && partitions_match_p (rd->xqos, &dummy_part_xqos)) { - TRACE ((" add to rd %x:%x:%x:%x\n", PGUID (rd->e.guid))); + nn_log (LC_DISCOVERY, " add to rd "PGUIDFMT"\n", PGUID (rd->e.guid)); nn_groupset_add_group (rd->matching_groups, group); } } @@ -339,7 +359,7 @@ static void add_group_to_readers_and_proxy_writers_locked (const struct sertopic { if (pwr->c.topic == topic && partitions_match_p (pwr->c.xqos, &dummy_part_xqos)) { - TRACE ((" add to pwr %x:%x:%x:%x\n", PGUID (pwr->e.guid))); + nn_log (LC_DISCOVERY, " add to pwr "PGUIDFMT"\n", PGUID (pwr->e.guid)); nn_groupset_add_group (pwr->groups, group); } } @@ -366,7 +386,7 @@ static void create_a_group (const char *name, const struct sertopic *topic) /* any non-wildcard one will do */ /* create it -- partitions require a v_partitionQos parameter, but that (thankfully!) isn't used by it ... phew! */ - TRACE (("create_a_group: %s.%s\n", name, topic->name)); + nn_log (LC_DISCOVERY, "create_a_group: %s.%s\n", name, topic->name); memset (&pqos, 0, sizeof (pqos)); part = v_partitionNew (gv.ospl_kernel, name, pqos); group = v_groupSetCreate (gv.ospl_kernel->groupSet, part, topic_ospl_topic (topic)); @@ -380,6 +400,7 @@ static void create_a_group (const char *name, const struct sertopic *topic) really too messy and time consuming once qos changes are allowed. */ add_group_to_readers_and_proxy_writers_locked (topic, name, group); } +#endif /* PARTICIPANT ------------------------------------------------------ */ @@ -434,12 +455,12 @@ int new_participant_guid (const nn_guid_t *ppguid, unsigned flags, const nn_plis else { os_mutexUnlock (&gv.participant_set_lock); - NN_ERROR2 ("new_participant(%x:%x:%x:%x, %x) failed: max participants reached\n", PGUID (*ppguid), flags); + NN_ERROR2 ("new_participant("PGUIDFMT", %x) failed: max participants reached\n", PGUID (*ppguid), flags); return ERR_OUT_OF_IDS; } } - nn_log (LC_DISCOVERY, "new_participant(%x:%x:%x:%x, %x)\n", PGUID (*ppguid), flags); + nn_log (LC_DISCOVERY, "new_participant("PGUIDFMT", %x)\n", PGUID (*ppguid), flags); pp = os_malloc (sizeof (*pp)); @@ -455,11 +476,11 @@ int new_participant_guid (const nn_guid_t *ppguid, unsigned flags, const nn_plis nn_plist_copy (pp->plist, plist); nn_plist_mergein_missing (pp->plist, &gv.default_plist_pp); - if (config.enabled_logcats & LC_TRACE) + if (config.enabled_logcats & LC_DISCOVERY) { - TRACE (("PARTICIPANT %x:%x:%x:%x QOS={", PGUID (pp->e.guid))); - nn_log_xqos (LC_TRACE, &pp->plist->qos); - TRACE (("}\n")); + nn_log (LC_DISCOVERY, "PARTICIPANT "PGUIDFMT" QOS={", PGUID (pp->e.guid)); + nn_log_xqos (LC_DISCOVERY, &pp->plist->qos); + nn_log (LC_DISCOVERY, "}\n"); } if (config.many_sockets_mode) @@ -480,7 +501,11 @@ int new_participant_guid (const nn_guid_t *ppguid, unsigned flags, const nn_plis subguid.prefix = pp->e.guid.prefix; memset (&group_guid, 0, sizeof (group_guid)); /* SPDP writer */ +#if LITE +#define LAST_WR_PARAMS NULL, NULL +#else #define LAST_WR_PARAMS NULL, NULL, NULL +#endif /* Note: skip SEDP <=> skip SPDP because of the way ddsi_discovery.c does things currently. */ @@ -530,7 +555,9 @@ int new_participant_guid (const nn_guid_t *ppguid, unsigned flags, const nn_plis pp->prismtech_bes |= NN_DISC_BUILTIN_ENDPOINT_CM_SUBSCRIBER_WRITER; } +#if !LITE if (flags & RTPS_PF_PRIVILEGED_PP) +#endif { /* TODO: make this one configurable, we don't want all participants to publish all topics (or even just those that they use themselves) */ subguid.entityid = to_entityid (NN_ENTITYID_SEDP_BUILTIN_TOPIC_WRITER); @@ -577,6 +604,7 @@ int new_participant_guid (const nn_guid_t *ppguid, unsigned flags, const nn_plis new_reader_guid (&subguid, &group_guid, pp, NULL, &gv.builtin_endpoint_xqos_rd, NULL, NULL, NULL); pp->prismtech_bes |= NN_DISC_BUILTIN_ENDPOINT_CM_SUBSCRIBER_READER; +#if ! LITE if (config.generate_builtin_topics) { /* No point in having a reader for topic discovery if we won't be generating the corresponding DCPSTopic, since that is the only thing it is currently being used for */ @@ -584,6 +612,7 @@ int new_participant_guid (const nn_guid_t *ppguid, unsigned flags, const nn_plis new_reader_guid (&subguid, &group_guid, pp, NULL, &gv.builtin_endpoint_xqos_rd, NULL, NULL, NULL); pp->bes |= NN_DISC_BUILTIN_ENDPOINT_TOPIC_DETECTOR; } +#endif } #undef LAST_WR_PARAMS @@ -652,6 +681,24 @@ int new_participant_guid (const nn_guid_t *ppguid, unsigned flags, const nn_plis return 0; } +#if LITE +int new_participant (nn_guid_t *p_ppguid, unsigned flags, const nn_plist_t *plist) +{ + nn_guid_t ppguid; + + os_mutexLock (&gv.privileged_pp_lock); + ppguid = gv.next_ppguid; + if (gv.next_ppguid.prefix.u[2]++ == ~0u) + { + os_mutexUnlock (&gv.privileged_pp_lock); + return ERR_OUT_OF_IDS; + } + os_mutexUnlock (&gv.privileged_pp_lock); + *p_ppguid = ppguid; + + return new_participant_guid (p_ppguid, flags, plist); +} +#endif static void delete_builtin_endpoint (const struct nn_guid *ppguid, unsigned entityid) { @@ -678,8 +725,8 @@ static struct participant *ref_participant (struct participant *pp, const struct stguid = *guid_of_refing_entity; else memset (&stguid, 0, sizeof (stguid)); - TRACE (("ref_participant(%x:%x:%x:%x @ %p <- %x:%x:%x:%x @ %p) user %d builtin %d\n", - PGUID (pp->e.guid), (void*)pp, PGUID (stguid), (void*)guid_of_refing_entity, pp->user_refc, pp->builtin_refc)); + nn_log (LC_DISCOVERY, "ref_participant("PGUIDFMT" @ %p <- "PGUIDFMT" @ %p) user %d builtin %d\n", + PGUID (pp->e.guid), (void*)pp, PGUID (stguid), (void*)guid_of_refing_entity, pp->user_refc, pp->builtin_refc); os_mutexUnlock (&pp->refc_lock); return pp; } @@ -719,8 +766,8 @@ static void unref_participant (struct participant *pp, const struct nn_guid *gui stguid = *guid_of_refing_entity; else memset (&stguid, 0, sizeof (stguid)); - TRACE (("unref_participant(%x:%x:%x:%x @ %p <- %x:%x:%x:%x @ %p) user %d builtin %d\n", - PGUID (pp->e.guid), (void*)pp, PGUID (stguid), (void*)guid_of_refing_entity, pp->user_refc, pp->builtin_refc)); + nn_log (LC_DISCOVERY, "unref_participant("PGUIDFMT" @ %p <- "PGUIDFMT" @ %p) user %d builtin %d\n", + PGUID (pp->e.guid), (void*)pp, PGUID (stguid), (void*)guid_of_refing_entity, pp->user_refc, pp->builtin_refc); if (pp->user_refc == 0 && (pp->bes != 0 || pp->prismtech_bes != 0) && !pp->builtins_deleted) { @@ -828,7 +875,7 @@ static void unref_participant (struct participant *pp, const struct nn_guid *gui static void gc_delete_participant (struct gcreq *gcreq) { struct participant *pp = gcreq->arg; - TRACE (("gc_delete_participant(%p, %x:%x:%x:%x)\n", (void *) gcreq, PGUID (pp->e.guid))); + nn_log (LC_DISCOVERY, "gc_delete_participant(%p, "PGUIDFMT")\n", (void *) gcreq, PGUID (pp->e.guid)); gcreq_free (gcreq); unref_participant (pp, NULL); } @@ -915,6 +962,9 @@ struct writer *get_builtin_writer (const struct participant *pp, unsigned entity very similar that co-locating them eases editing and checking. */ static int rebuild_writer_addrset_addone_mc (struct addrset *as, const struct wr_prd_match *m +#ifdef DDSI_INCLUDE_SSM + , int wr_supports_ssm +#endif ) { /* prd->c.as better be constant, or else we need to do this sort of @@ -923,8 +973,19 @@ static int rebuild_writer_addrset_addone_mc (struct addrset *as, const struct wr nn_locator_t loc; if ((prd = ephash_lookup_proxy_reader_guid (&m->prd_guid)) != NULL) { +#ifdef DDSI_INCLUDE_SSM + /* If writer supports SSM and the remote reader favours it, don't + add an address for this reader to the address set, but indicate + to the rebuild_writer_addrset that it should include the + writer's SSM address instead */ + if (wr_supports_ssm && prd->favours_ssm) + return 1; + if (addrset_any_non_ssm_mc (prd->c.as, &loc)) + add_to_addrset (as, &loc); +#else if (addrset_any_mc (prd->c.as, &loc)) add_to_addrset (as, &loc); +#endif else if (addrset_any_uc (prd->c.as, &loc)) add_to_addrset (as, &loc); } @@ -973,11 +1034,28 @@ static void rebuild_writer_addrset (struct writer *wr) unicasts */ if (addrset_count_uc (newas) > 1 || need_mc) { +#ifdef DDSI_INCLUDE_SSM + int include_ssm = 0; +#endif addrset_purge (newas); for (m = ut_avlIterFirst (&wr_readers_treedef, &wr->readers, &it); m; m = ut_avlIterNext (&it)) { +#ifdef DDSI_INCLUDE_SSM + include_ssm += rebuild_writer_addrset_addone_mc (newas, m, wr->supports_ssm); +#else (void) rebuild_writer_addrset_addone_mc (newas, m); +#endif + } +#ifdef DDSI_INCLUDE_SSM + if (include_ssm && wr->ssm_as) + { + /* FIXME: If at least one reader favours SSM, include the SSM address. Suppose: + - R1 advertises G and favours SSM + - R2 advertises G but does not favour SSM + Then this will cause both ASM to G & SSM even though just an ASM to G would suffice. */ + copy_addrset_into_addrset_mc (newas, wr->ssm_as); } +#endif } } } @@ -986,13 +1064,15 @@ static void rebuild_writer_addrset (struct writer *wr) wr->as = newas; unref_addrset (oldas); - TRACE (("rebuild_writer_addrset(%x:%x:%x:%x):", PGUID (wr->e.guid))); - nn_log_addrset (LC_TRACE, "", wr->as); - TRACE (("\n")); + nn_log (LC_DISCOVERY, "rebuild_writer_addrset("PGUIDFMT"):", PGUID (wr->e.guid)); + nn_log_addrset (LC_DISCOVERY, "", wr->as); + nn_log (LC_DISCOVERY, "\n"); } +#if !LITE #include "v_public.h" #include "v_reader.h" +#include "v_group.h" static void notify_wait_for_historical_data_impl (const nn_guid_t *rd_guid) { @@ -1001,18 +1081,15 @@ static void notify_wait_for_historical_data_impl (const nn_guid_t *rd_guid) if ((rd = ephash_lookup_reader_guid(rd_guid)) == NULL) { - TRACE(("wfh(%x:%x:%x:%x ddsi2-reader-gone)\n", PGUID(*rd_guid))); + nn_log (LC_DISCOVERY, "wfh("PGUIDFMT" ddsi2-reader-gone)\n", PGUID(*rd_guid)); return; } - if (v_gidIsNil(rd->c.gid)) - { - return; - } - TRACE(("wfh(%x:%x:%x:%x gid %x:%x:%x ", PGUID(*rd_guid), rd->c.gid.systemId, rd->c.gid.localId, rd->c.gid.serial)); - if (rd->c.gid.systemId != gv.ospl_kernel->GID.systemId) + + nn_log(LC_DISCOVERY, "wfh("PGUIDFMT" gid "PGIDFMT" ", PGUID(*rd_guid), PGID(rd->c.gid)); + if (!v_gidIsNil(rd->c.gid) && (rd->c.gid.systemId != gv.ospl_kernel->GID.systemId)) { /* bridging mode can mean proxying remote entities, no possibility to do anything for those */ - TRACE(("bridged-remote-reader)\n")); + nn_log (LC_DISCOVERY, "bridged-remote-reader)\n"); return; } @@ -1033,7 +1110,7 @@ static void notify_wait_for_historical_data_impl (const nn_guid_t *rd_guid) os_mutexLock (&pwr->e.lock); if ((pwrm = ut_avlLookup (&pwr_readers_treedef, &pwr->readers, rd_guid)) != NULL && pwrm->in_sync != PRMSS_SYNC) { - TRACE(("pwr %x:%x:%x:%x incomplete)\n", PGUID(pwr_guid))); + nn_log (LC_DISCOVERY, "pwr "PGUIDFMT" incomplete)\n", PGUID(pwr_guid)); all_complete = 0; } os_mutexUnlock (&pwr->e.lock); @@ -1048,23 +1125,67 @@ static void notify_wait_for_historical_data_impl (const nn_guid_t *rd_guid) } } - if (v_gidClaimChecked (rd->c.gid, gv.ospl_kernel, &kr) != V_HANDLE_OK) - { - TRACE(("kernel-reader-gone)\n")); - return; - } + if (is_builtin_entityid(rd->e.guid.entityid, ownvendorid)) { + const char * t[3] = {0}; + unsigned i; - if (c_instanceOf(kr, "v_reader")) - { - TRACE(("notifying)\n")); - v_readerNotifyStateChange(v_reader(kr),TRUE); + nn_log(LC_DISCOVERY, "group-set-complete"); + switch (rd->e.guid.entityid.u) + { + case NN_ENTITYID_SPDP_BUILTIN_PARTICIPANT_READER: + t[0] = V_PARTICIPANTINFO_NAME; + break; + case NN_ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_READER: + t[0] = V_SUBSCRIPTIONINFO_NAME; + t[1] = V_CMDATAREADERINFO_NAME; + break; + case NN_ENTITYID_SEDP_BUILTIN_PUBLICATIONS_READER: + t[0] = V_PUBLICATIONINFO_NAME; + t[1] = V_CMDATAWRITERINFO_NAME; + break; + case NN_ENTITYID_SEDP_BUILTIN_CM_PARTICIPANT_READER: + t[0] = V_CMPARTICIPANTINFO_NAME; + break; + case NN_ENTITYID_SEDP_BUILTIN_CM_PUBLISHER_READER: + t[0] = V_CMPUBLISHERINFO_NAME; + break; + case NN_ENTITYID_SEDP_BUILTIN_CM_SUBSCRIBER_READER: + t[0] = V_CMSUBSCRIBERINFO_NAME; + break; + case NN_ENTITYID_SEDP_BUILTIN_TOPIC_READER: + t[0] = V_TOPICINFO_NAME; + break; + } + + for (i = 0; t[i]; i++) + { + v_group g; + nn_log(LC_DISCOVERY," %s", t[i]); + g = v_groupSetGet(gv.ospl_kernel->groupSet, V_BUILTIN_PARTITION, t[i]); + (void)v_groupCompleteSet(g, V_ALIGNSTATE_COMPLETE); + c_free(g); + } + nn_log(LC_DISCOVERY,")\n"); } else { - TRACE(("kernel-object-not-a-reader)\n")); - } + if (v_gidClaimChecked (rd->c.gid, gv.ospl_kernel, &kr) != V_HANDLE_OK) + { + nn_log(LC_DISCOVERY,"kernel-reader-gone)\n"); + return; + } - v_gidRelease (rd->c.gid, gv.ospl_kernel); + if (c_instanceOf(kr, "v_reader")) + { + nn_log(LC_DISCOVERY,"notifying)\n"); + v_readerNotifyStateChange(v_reader(kr),TRUE); + } + else + { + nn_log(LC_DISCOVERY,"kernel-object-not-a-reader)\n"); + } + v_gidRelease (rd->c.gid, gv.ospl_kernel); + } } struct notify_wait_for_historical_data_cb_arg { @@ -1082,16 +1203,13 @@ void notify_wait_for_historical_data (struct proxy_writer *pwr, const nn_guid_t { /* always trigger asynchronously via the delivery queue: data received in "out-of-sync" mode is delivered asynchronously, and the overhead of the asynchronous notification is negligible */ - nn_vendorid_t vendorid = MY_VENDOR_ID; - if (!is_builtin_entityid(rd_guid->entityid, vendorid)) - { - struct notify_wait_for_historical_data_cb_arg *arg; - TRACE (("msr_in_sync(%x:%x:%x:%x queue-wfh)\n", PGUID (*rd_guid))); - arg = os_malloc(sizeof(*arg)); - arg->rd_guid = *rd_guid; - nn_dqueue_enqueue_callback(pwr ? pwr->dqueue : gv.builtins_dqueue, notify_wait_for_historical_data_cb, arg); - } + struct notify_wait_for_historical_data_cb_arg *arg; + nn_log (LC_DISCOVERY, "msr_in_sync("PGUIDFMT" queue-wfh)\n", PGUID (*rd_guid)); + arg = os_malloc(sizeof(*arg)); + arg->rd_guid = *rd_guid; + nn_dqueue_enqueue_callback(pwr ? pwr->dqueue : gv.builtins_dqueue, notify_wait_for_historical_data_cb, arg); } +#endif static void free_wr_prd_match (struct wr_prd_match *m) { @@ -1106,6 +1224,15 @@ static void free_rd_pwr_match (struct rd_pwr_match *m) { if (m) { +#ifdef DDSI_INCLUDE_SSM + if (!is_unspec_locator (&m->ssm_mc_loc)) + { + assert (is_mcaddr (&m->ssm_mc_loc)); + assert (!is_unspec_locator (&m->ssm_src_loc)); + if (ddsi_conn_leave_mc (gv.data_conn_mc, &m->ssm_src_loc, &m->ssm_mc_loc) < 0) + nn_log (LC_WARNING, "failed to leave network partition ssm group\n"); + } +#endif os_free (m); } } @@ -1139,6 +1266,16 @@ static void writer_drop_connection (const struct nn_guid * wr_guid, const struct rebuild_writer_addrset (wr); remove_acked_messages (wr); wr->num_reliable_readers -= m->is_reliable; +#if LITE + if (wr->status_cb) + { + status_cb_data_t data; + data.status = DDS_PUBLICATION_MATCHED_STATUS; + data.add = false; + data.handle = prd->e.iid; + (wr->status_cb) (wr->status_cb_entity, &data); + } +#endif } os_mutexUnlock (&wr->e.lock); free_wr_prd_match (m); @@ -1157,6 +1294,31 @@ static void reader_drop_connection (const struct nn_guid *rd_guid, const struct os_mutexUnlock (&rd->e.lock); free_rd_pwr_match (m); +#if LITE + if (rd->rhc) + { + struct proxy_writer_info pwr_info; + pwr_info.guid = pwr->e.guid; + pwr_info.ownership_strength = pwr->c.xqos->ownership_strength.value; + pwr_info.auto_dispose = pwr->c.xqos->writer_data_lifecycle.autodispose_unregistered_instances; + pwr_info.iid = pwr->e.iid; + + (ddsi_plugin.rhc_unregister_wr_fn) (rd->rhc, &pwr_info); + } + if (rd->status_cb) + { + status_cb_data_t data; + + data.add = false; + data.handle = pwr->e.iid; + + data.status = DDS_LIVELINESS_CHANGED_STATUS; + (rd->status_cb) (rd->status_cb_entity, &data); + + data.status = DDS_SUBSCRIPTION_MATCHED_STATUS; + (rd->status_cb) (rd->status_cb_entity, &data); + } +#endif } } @@ -1166,19 +1328,19 @@ static void update_reader_init_acknack_count (const struct nn_guid *rd_guid, nn_ /* Update the initial acknack sequence number for the reader. See also reader_add_connection(). */ - TRACE (("update_reader_init_acknack_count (%x:%x:%x:%x, %d): ", PGUID (*rd_guid), count)); + nn_log (LC_DISCOVERY, "update_reader_init_acknack_count ("PGUIDFMT", %d): ", PGUID (*rd_guid), count); if ((rd = ephash_lookup_reader_guid (rd_guid)) != NULL) { os_mutexLock (&rd->e.lock); - TRACE (("%d -> ", rd->init_acknack_count)); + nn_log (LC_DISCOVERY, "%d -> ", rd->init_acknack_count); if (count > rd->init_acknack_count) rd->init_acknack_count = count; - TRACE (("%d\n", count)); + nn_log (LC_DISCOVERY, "%d\n", count); os_mutexUnlock (&rd->e.lock); } else { - TRACE (("reader no longer exists\n")); + nn_log (LC_DISCOVERY, "reader no longer exists\n"); } } @@ -1205,6 +1367,24 @@ static void proxy_writer_drop_connection (const struct nn_guid *pwr_guid, struct pwr->n_reliable_readers--; } +#if LITE + { + int i; + os_mutexLock (&pwr->rdary_lock); + for (i = 0; i < pwr->n_readers; i++) + { + if (pwr->rdary[i] == rd) + break; + } + assert (i < pwr->n_readers); + /* if i == N-1 copy is a no-op */ + pwr->rdary[i] = pwr->rdary[pwr->n_readers - 1]; + pwr->n_readers--; + pwr->rdary[pwr->n_readers] = NULL; + pwr->rdary = os_realloc (pwr->rdary, (pwr->n_readers + 1) * sizeof (*pwr->rdary)); + os_mutexUnlock (&pwr->rdary_lock); + } +#endif os_mutexUnlock (&pwr->e.lock); if (m != NULL) @@ -1249,8 +1429,8 @@ static void writer_add_connection (struct writer *wr, struct proxy_reader *prd) os_mutexLock (&prd->e.lock); if (prd->deleting) { - TRACE ((" writer_add_connection(wr %x:%x:%x:%x prd %x:%x:%x:%x) - prd is being deleted\n", - PGUID (wr->e.guid), PGUID (prd->e.guid))); + nn_log (LC_DISCOVERY, " writer_add_connection(wr "PGUIDFMT" prd "PGUIDFMT") - prd is being deleted\n", + PGUID (wr->e.guid), PGUID (prd->e.guid)); pretend_everything_acked = 1; } else if (!m->is_reliable) @@ -1277,21 +1457,31 @@ static void writer_add_connection (struct writer *wr, struct proxy_reader *prd) m->seq = wr->seq; if (ut_avlLookupIPath (&wr_readers_treedef, &wr->readers, &prd->e.guid, &path)) { - TRACE ((" writer_add_connection(wr %x:%x:%x:%x prd %x:%x:%x:%x) - already connected\n", - PGUID (wr->e.guid), PGUID (prd->e.guid))); + nn_log (LC_DISCOVERY, " writer_add_connection(wr "PGUIDFMT" prd "PGUIDFMT") - already connected\n", + PGUID (wr->e.guid), PGUID (prd->e.guid)); os_mutexUnlock (&wr->e.lock); nn_lat_estim_fini (&m->hb_to_ack_latency); os_free (m); } else { - TRACE ((" writer_add_connection(wr %x:%x:%x:%x prd %x:%x:%x:%x) - ack seq %"PA_PRId64"\n", - PGUID (wr->e.guid), PGUID (prd->e.guid), m->seq)); + nn_log (LC_DISCOVERY, " writer_add_connection(wr "PGUIDFMT" prd "PGUIDFMT") - ack seq %"PA_PRId64"\n", + PGUID (wr->e.guid), PGUID (prd->e.guid), m->seq); ut_avlInsertIPath (&wr_readers_treedef, &wr->readers, m, &path); rebuild_writer_addrset (wr); wr->num_reliable_readers += m->is_reliable; os_mutexUnlock (&wr->e.lock); +#if LITE + if (wr->status_cb) + { + status_cb_data_t data; + data.status = DDS_PUBLICATION_MATCHED_STATUS; + data.add = true; + data.handle = prd->e.iid; + (wr->status_cb) (wr->status_cb_entity, &data); + } +#else /* for proxy readers using a non-wildcard partition matching a wildcard partition at the writer (and only a wildcard partition), ensure that a matching non-wildcard partition exists */ @@ -1305,6 +1495,7 @@ static void writer_add_connection (struct writer *wr, struct proxy_reader *prd) create_a_group (realname, wr->topic); } } +#endif /* If reliable and/or transient-local, we may have data available in the WHC, but if all has been acknowledged by the previously @@ -1348,27 +1539,58 @@ static void reader_add_connection (struct reader *rd, struct proxy_writer *pwr, writer will always see monotonically increasing sequence numbers from one particular reader. This is then used for the pwr_rd_match initialization */ - TRACE ((" reader %x:%x:%x:%x init_acknack_count = %d\n", PGUID (rd->e.guid), rd->init_acknack_count)); + nn_log (LC_DISCOVERY, " reader "PGUIDFMT" init_acknack_count = %d\n", PGUID (rd->e.guid), rd->init_acknack_count); *init_count = rd->init_acknack_count; if (ut_avlLookupIPath (&rd_writers_treedef, &rd->writers, &pwr->e.guid, &path)) { - TRACE ((" reader_add_connection(pwr %x:%x:%x:%x rd %x:%x:%x:%x) - already connected\n", - PGUID (pwr->e.guid), PGUID (rd->e.guid))); + nn_log (LC_DISCOVERY, " reader_add_connection(pwr "PGUIDFMT" rd "PGUIDFMT") - already connected\n", + PGUID (pwr->e.guid), PGUID (rd->e.guid)); os_mutexUnlock (&rd->e.lock); os_free (m); } else { - TRACE ((" reader_add_connection(pwr %x:%x:%x:%x rd %x:%x:%x:%x)\n", - PGUID (pwr->e.guid), PGUID (rd->e.guid))); + nn_log (LC_DISCOVERY, " reader_add_connection(pwr "PGUIDFMT" rd "PGUIDFMT")\n", + PGUID (pwr->e.guid), PGUID (rd->e.guid)); ut_avlInsertIPath (&rd_writers_treedef, &rd->writers, m, &path); os_mutexUnlock (&rd->e.lock); +#ifdef DDSI_INCLUDE_SSM + if (rd->favours_ssm && pwr->supports_ssm) + { + /* pwr->supports_ssm is set if addrset_contains_ssm(pwr->ssm), so + any_ssm must succeed. */ + if (!addrset_any_uc (pwr->c.as, &m->ssm_src_loc)) + assert (0); + if (!addrset_any_ssm (pwr->c.as, &m->ssm_mc_loc)) + assert (0); + /* FIXME: for now, assume that the ports match for datasock_mc -- + 't would be better to dynamically create and destroy sockets on + an as needed basis. */ + ddsi_conn_join_mc (gv.data_conn_mc, &m->ssm_src_loc, &m->ssm_mc_loc); + } + else + { + set_unspec_locator (&m->ssm_src_loc); + set_unspec_locator (&m->ssm_mc_loc); + } +#endif +#if LITE + if (rd->status_cb) + { + status_cb_data_t data; + data.status = DDS_SUBSCRIPTION_MATCHED_STATUS; + data.add = true; + data.handle = pwr->e.iid; + (rd->status_cb) (rd->status_cb_entity, &data); + } +#endif } } +#if !LITE static int add_matching_groups_helper (v_group g, void *varg) { /* Damn. Didn't think it through all the way, so now I need to check @@ -1405,6 +1627,7 @@ static const char *any_nonwildcard_partition (const nn_partition_qospolicy_t *ps return ps->strs[i]; return NULL; } +#endif static void proxy_writer_add_connection (struct proxy_writer *pwr, struct reader *rd, nn_mtime_t tnow /* monotonic */, nn_count_t init_count) { @@ -1416,14 +1639,20 @@ static void proxy_writer_add_connection (struct proxy_writer *pwr, struct reader if (ut_avlLookupIPath (&pwr_readers_treedef, &pwr->readers, &rd->e.guid, &path)) goto already_matched; +#if LITE + if (pwr->c.topic == NULL && rd->topic) + pwr->c.topic = rd->topic; +#else if (pwr->c.topic == NULL) pwr->c.topic = rd->topic; +#endif - TRACE ((" proxy_writer_add_connection(pwr %x:%x:%x:%x rd %x:%x:%x:%x)", - PGUID (pwr->e.guid), PGUID (rd->e.guid))); + nn_log (LC_DISCOVERY, " proxy_writer_add_connection(pwr "PGUIDFMT" rd "PGUIDFMT")", + PGUID (pwr->e.guid), PGUID (rd->e.guid)); m->rd_guid = rd->e.guid; m->tcreate = now_mt (); +#if !LITE { int ngroups; @@ -1450,6 +1679,7 @@ static void proxy_writer_add_connection (struct proxy_writer *pwr, struct reader assert (!nn_groupset_empty (rd->matching_groups)); } } +#endif /* We track the last heartbeat count value per reader--proxy-writer pair, so that we can correctly handle directed heartbeats. The @@ -1477,10 +1707,10 @@ static void proxy_writer_add_connection (struct proxy_writer *pwr, struct reader else if (last_deliv_seq == 0) { /* proxy-writer hasn't seen any data yet, in which case this reader is in sync with the proxy writer (i.e., no reader-specific reorder buffer needed), but still should generate a notification when all historical data has been received, except for the built-in ones (for now anyway, it may turn out to be useful for determining discovery status). */ - m->in_sync = is_builtin_entityid (rd->e.guid.entityid, ownvendorid) ? PRMSS_SYNC : PRMSS_TLCATCHUP; + m->in_sync = PRMSS_TLCATCHUP; m->u.not_in_sync.end_of_tl_seq = MAX_SEQ_NUMBER; if (m->in_sync != PRMSS_SYNC) - TRACE ((" - tlcatchup")); + nn_log (LC_DISCOVERY, " - tlcatchup"); } else if (!config.conservative_builtin_reader_startup && is_builtin_entityid (rd->e.guid.entityid, ownvendorid) && !ut_avlIsEmpty (&pwr->readers)) { @@ -1491,9 +1721,9 @@ static void proxy_writer_add_connection (struct proxy_writer *pwr, struct reader { /* normal transient-local, reader is behind proxy writer */ m->in_sync = PRMSS_OUT_OF_SYNC; - m->u.not_in_sync.end_of_tl_seq = MAX_SEQ_NUMBER; + m->u.not_in_sync.end_of_tl_seq = pwr->last_seq; m->u.not_in_sync.end_of_out_of_sync_seq = last_deliv_seq; - TRACE ((" - out-of-sync %"PA_PRId64, m->u.not_in_sync.end_of_out_of_sync_seq)); + nn_log (LC_DISCOVERY, " - out-of-sync %"PA_PRId64, m->u.not_in_sync.end_of_out_of_sync_seq); } if (m->in_sync != PRMSS_SYNC) pwr->n_readers_out_of_sync++; @@ -1520,19 +1750,37 @@ static void proxy_writer_add_connection (struct proxy_writer *pwr, struct reader ut_avlInsertIPath (&pwr_readers_treedef, &pwr->readers, m, &path); +#if LITE + os_mutexLock (&pwr->rdary_lock); + pwr->n_readers++; + pwr->rdary = os_realloc (pwr->rdary, (pwr->n_readers + 1) * sizeof (*pwr->rdary)); + pwr->rdary[pwr->n_readers - 1] = rd; + pwr->rdary[pwr->n_readers] = NULL; + os_mutexUnlock (&pwr->rdary_lock); +#endif os_mutexUnlock (&pwr->e.lock); qxev_pwr_entityid (pwr, &rd->e.guid.prefix); - TRACE (("\n")); + nn_log (LC_DISCOVERY, "\n"); +#if LITE + if (rd->status_cb) + { + status_cb_data_t data; + data.status = DDS_LIVELINESS_CHANGED_STATUS; + data.add = true; + data.handle = pwr->e.iid; + (rd->status_cb) (rd->status_cb_entity, &data); + } +#endif return; already_matched: assert (is_builtin_entityid (pwr->e.guid.entityid, pwr->c.vendor) ? (pwr->c.topic == NULL) : (pwr->c.topic != NULL)); - TRACE ((" proxy_writer_add_connection(pwr %x:%x:%x:%x rd %x:%x:%x:%x) - already connected\n", - PGUID (pwr->e.guid), PGUID (rd->e.guid))); + nn_log (LC_DISCOVERY, " proxy_writer_add_connection(pwr "PGUIDFMT" rd "PGUIDFMT") - already connected\n", + PGUID (pwr->e.guid), PGUID (rd->e.guid)); os_mutexUnlock (&pwr->e.lock); os_free (m); return; @@ -1549,15 +1797,15 @@ static void proxy_reader_add_connection (struct proxy_reader *prd, struct writer prd->c.topic = wr->topic; if (ut_avlLookupIPath (&prd_writers_treedef, &prd->writers, &wr->e.guid, &path)) { - TRACE ((" proxy_reader_add_connection(wr %x:%x:%x:%x prd %x:%x:%x:%x) - already connected\n", - PGUID (wr->e.guid), PGUID (prd->e.guid))); + nn_log (LC_DISCOVERY, " proxy_reader_add_connection(wr "PGUIDFMT" prd "PGUIDFMT") - already connected\n", + PGUID (wr->e.guid), PGUID (prd->e.guid)); os_mutexUnlock (&prd->e.lock); os_free (m); } else { - TRACE ((" proxy_reader_add_connection(wr %x:%x:%x:%x prd %x:%x:%x:%x)\n", - PGUID (wr->e.guid), PGUID (prd->e.guid))); + nn_log (LC_DISCOVERY, " proxy_reader_add_connection(wr "PGUIDFMT" prd "PGUIDFMT")\n", + PGUID (wr->e.guid), PGUID (prd->e.guid)); ut_avlInsertIPath (&prd_writers_treedef, &prd->writers, m, &path); os_mutexUnlock (&prd->e.lock); qxev_prd_entityid (prd, &wr->e.guid.prefix); @@ -1630,6 +1878,30 @@ static nn_entityid_t builtin_entityid_match (nn_entityid_t x) return res; } +#if LITE +static void writer_qos_missmatch (struct writer * wr, os_int32 reason) +{ + if (reason == DDS_INVALID_QOS_POLICY_ID) + { + /* Handle INCONSISTENT_TOPIC on topic */ + + if (wr->topic->status_cb) + { + (wr->topic->status_cb) (wr->topic->status_cb_entity); + } + } + else + { + if (wr->status_cb) + { + status_cb_data_t data; + data.status = DDS_OFFERED_INCOMPATIBLE_QOS_STATUS; + data.extra = reason; + (wr->status_cb) (wr->status_cb_entity, &data); + } + } +} +#endif static void match_writer_with_proxy_readers (struct writer *wr, UNUSED_ARG (nn_mtime_t tnow)) { @@ -1639,7 +1911,7 @@ static void match_writer_with_proxy_readers (struct writer *wr, UNUSED_ARG (nn_m if (!is_builtin_entityid (wr->e.guid.entityid, ownvendorid)) { struct ephash_enum_proxy_reader est; - TRACE (("match_writer_with_proxy_readers(wr %x:%x:%x:%x) scanning all proxy readers\n", PGUID (wr->e.guid))); + nn_log (LC_DISCOVERY, "match_writer_with_proxy_readers(wr "PGUIDFMT") scanning all proxy readers\n", PGUID (wr->e.guid)); /* Note: we visit at least all proxies that existed when we called init (with the -- possible -- exception of ones that were deleted between our calling init and our reaching it while @@ -1661,6 +1933,12 @@ static void match_writer_with_proxy_readers (struct writer *wr, UNUSED_ARG (nn_m writer_add_connection (wr, prd); proxy_reader_add_connection (prd, wr); } +#if LITE + else + { + writer_qos_missmatch (wr, reason); + } +#endif } os_rwlockUnlock (&gv.qoslock); ephash_enum_proxy_reader_fini (&est); @@ -1670,7 +1948,7 @@ static void match_writer_with_proxy_readers (struct writer *wr, UNUSED_ARG (nn_m /* Built-ins have fixed QoS */ struct ephash_enum_proxy_participant est; nn_entityid_t tgt_ent = builtin_entityid_match (wr->e.guid.entityid); - TRACE (("match_writer_with_proxy_readers(wr %x:%x:%x:%x) scanning proxy participants tgt=%x\n", PGUID (wr->e.guid), tgt_ent.u)); + nn_log (LC_DISCOVERY, "match_writer_with_proxy_readers(wr "PGUIDFMT") scanning proxy participants tgt=%x\n", PGUID (wr->e.guid), tgt_ent.u); if (tgt_ent.u != NN_ENTITYID_UNKNOWN) { struct proxy_participant *proxypp; @@ -1691,6 +1969,30 @@ static void match_writer_with_proxy_readers (struct writer *wr, UNUSED_ARG (nn_m } } +#if LITE +static void reader_qos_missmatch (struct reader * rd, os_int32 reason) +{ + if (reason == DDS_INVALID_QOS_POLICY_ID) + { + /* Handle INCONSISTENT_TOPIC on topic */ + + if (rd->topic->status_cb) + { + (rd->topic->status_cb) (rd->topic->status_cb_entity); + } + } + else + { + if (rd->status_cb) + { + status_cb_data_t data; + data.status = DDS_REQUESTED_INCOMPATIBLE_QOS_STATUS; + data.extra = reason; + (rd->status_cb) (rd->status_cb_entity, &data); + } + } +} +#endif static void match_reader_with_proxy_writers (struct reader *rd, nn_mtime_t tnow /* monotonic */) { @@ -1701,7 +2003,7 @@ static void match_reader_with_proxy_writers (struct reader *rd, nn_mtime_t tnow if (!is_builtin_entityid (rd->e.guid.entityid, ownvendorid)) { struct ephash_enum_proxy_writer est; - TRACE (("match_reader_with_proxy_writers(wr %x:%x:%x:%x) scanning all proxy writers\n", PGUID (rd->e.guid))); + nn_log (LC_DISCOVERY, "match_reader_with_proxy_writers(wr "PGUIDFMT") scanning all proxy writers\n", PGUID (rd->e.guid)); ephash_enum_proxy_writer_init (&est); os_rwlockRead (&gv.qoslock); while ((pwr = ephash_enum_proxy_writer_next (&est)) != NULL) @@ -1715,6 +2017,12 @@ static void match_reader_with_proxy_writers (struct reader *rd, nn_mtime_t tnow reader_add_connection (rd, pwr, &init_count); proxy_writer_add_connection (pwr, rd, tnow /* monotonic */, init_count); } +#if LITE + else + { + reader_qos_missmatch (rd, reason); + } +#endif } os_rwlockUnlock (&gv.qoslock); ephash_enum_proxy_writer_fini (&est); @@ -1723,7 +2031,7 @@ static void match_reader_with_proxy_writers (struct reader *rd, nn_mtime_t tnow { struct ephash_enum_proxy_participant est; nn_entityid_t tgt_ent = builtin_entityid_match (rd->e.guid.entityid); - TRACE (("match_reader_with_proxy_writers(rd %x:%x:%x:%x) scanning proxy participants tgt=%x\n", PGUID (rd->e.guid), tgt_ent.u)); + nn_log (LC_DISCOVERY, "match_reader_with_proxy_writers(rd "PGUIDFMT") scanning proxy participants tgt=%x\n", PGUID (rd->e.guid), tgt_ent.u); if (tgt_ent.u != NN_ENTITYID_UNKNOWN) { struct proxy_participant *proxypp; @@ -1755,7 +2063,7 @@ static void match_proxy_writer_with_readers (struct proxy_writer *pwr, nn_mtime_ if (!is_builtin_entityid (pwr->e.guid.entityid, pwr->c.vendor)) { struct ephash_enum_reader est; - TRACE (("match_proxy_writer_with_readers(pwr %x:%x:%x:%x) scanning all readers\n", PGUID (pwr->e.guid))); + nn_log (LC_DISCOVERY, "match_proxy_writer_with_readers(pwr "PGUIDFMT") scanning all readers\n", PGUID (pwr->e.guid)); ephash_enum_reader_init (&est); os_rwlockRead (&gv.qoslock); while ((rd = ephash_enum_reader_next (&est)) != NULL) @@ -1771,6 +2079,12 @@ static void match_proxy_writer_with_readers (struct proxy_writer *pwr, nn_mtime_ reader_add_connection (rd, pwr, &init_count); proxy_writer_add_connection (pwr, rd, tnow /* monotonic */, init_count); } +#if LITE + else + { + reader_qos_missmatch (rd, reason); + } +#endif } os_rwlockUnlock (&gv.qoslock); ephash_enum_reader_fini (&est); @@ -1779,7 +2093,7 @@ static void match_proxy_writer_with_readers (struct proxy_writer *pwr, nn_mtime_ { nn_entityid_t tgt_ent = builtin_entityid_match (pwr->e.guid.entityid); struct ephash_enum_participant est; - TRACE (("match_proxy_writer_with_readers(pwr %x:%x:%x:%x) scanning participants tgt=%x\n", PGUID (pwr->e.guid), tgt_ent.u)); + nn_log (LC_DISCOVERY, "match_proxy_writer_with_readers(pwr "PGUIDFMT") scanning participants tgt=%x\n", PGUID (pwr->e.guid), tgt_ent.u); if (tgt_ent.u != NN_ENTITYID_UNKNOWN) { struct participant *pp; @@ -1810,7 +2124,7 @@ static void match_proxy_reader_with_writers (struct proxy_reader *prd, UNUSED_AR if (!is_builtin_entityid (prd->e.guid.entityid, prd->c.vendor)) { struct ephash_enum_writer est; - TRACE (("match_proxy_reader_with_writers(prd %x:%x:%x:%x) scanning all writers\n", PGUID (prd->e.guid))); + nn_log (LC_DISCOVERY, "match_proxy_reader_with_writers(prd "PGUIDFMT") scanning all writers\n", PGUID (prd->e.guid)); ephash_enum_writer_init (&est); os_rwlockRead (&gv.qoslock); while ((wr = ephash_enum_writer_next (&est)) != NULL) @@ -1823,6 +2137,12 @@ static void match_proxy_reader_with_writers (struct proxy_reader *prd, UNUSED_AR proxy_reader_add_connection (prd, wr); writer_add_connection (wr, prd); } +#if LITE + else + { + writer_qos_missmatch (wr, reason); + } +#endif } os_rwlockUnlock (&gv.qoslock); ephash_enum_writer_fini (&est); @@ -1831,7 +2151,7 @@ static void match_proxy_reader_with_writers (struct proxy_reader *prd, UNUSED_AR { struct ephash_enum_participant est; nn_entityid_t tgt_ent = builtin_entityid_match (prd->e.guid.entityid); - TRACE (("match_proxy_reader_with_writers(prd %x:%x:%x:%x) scanning participants tgt=%x\n", PGUID (prd->e.guid), tgt_ent.u)); + nn_log (LC_DISCOVERY, "match_proxy_reader_with_writers(prd "PGUIDFMT") scanning participants tgt=%x\n", PGUID (prd->e.guid), tgt_ent.u); if (tgt_ent.u != NN_ENTITYID_UNKNOWN) { struct participant *pp; @@ -1872,7 +2192,7 @@ static void new_reader_writer_common (const struct nn_guid *guid, const struct s if (xqos->partition.n > 1) partition_suffix = "+"; } - nn_log (LC_DISCOVERY, "new_%s(guid %x:%x:%x:%x, %s%s.%s/%s)\n", + nn_log (LC_DISCOVERY, "new_%s(guid "PGUIDFMT", %s%s.%s/%s)\n", is_writer_entityid (guid->entityid) ? "writer" : "reader", PGUID (*guid), partition, partition_suffix, @@ -1888,12 +2208,19 @@ static void endpoint_common_init const struct nn_guid *guid, const struct nn_guid *group_guid, struct participant *pp +#if ! LITE ,const struct v_gid_s *gid, const struct v_gid_s *group_gid, const char *endpoint_name +#endif ) { +#if LITE + entity_common_init (e, guid, NULL, kind); +#else entity_common_init (e, guid, endpoint_name, kind); +#endif +#if ! LITE if (gid) { assert (group_gid != NULL); @@ -1905,6 +2232,7 @@ static void endpoint_common_init memset (&c->gid, 0, sizeof (c->gid)); memset (&c->group_gid, 0, sizeof (c->group_gid)); } +#endif c->pp = ref_participant (pp, &e->guid); if (group_guid) { @@ -1939,6 +2267,19 @@ static int set_topic_type_name (nn_xqos_t *xqos, const struct sertopic * topic) /* WRITER ----------------------------------------------------------- */ +#ifdef DDSI_INCLUDE_NETWORK_PARTITIONS +static os_uint32 get_partitionid_from_mapping (const char *partition, const char *topic) +{ + struct config_partitionmapping_listelem *pm; + if ((pm = find_partitionmapping (partition, topic)) == NULL) + return 0; + else + { + nn_log (LC_DISCOVERY, "matched writer for topic \"%s\" in partition \"%s\" to networkPartition \"%s\"\n", topic, partition, pm->networkPartition); + return pm->partition->partitionId; + } +} +#endif /* DDSI_INCLUDE_NETWORK_PARTITIONS */ static void augment_wr_prd_match (void *vnode, const void *vleft, const void *vright) { @@ -2108,7 +2449,7 @@ unsigned remove_acked_messages (struct writer *wr) writer_clear_retransmitting (wr); if (wr->state == WRST_LINGERING && n_unacked == 0) { - nn_log (LC_DISCOVERY, "remove_acked_messages: deleting lingering writer %x:%x:%x:%x\n", PGUID (wr->e.guid)); + nn_log (LC_DISCOVERY, "remove_acked_messages: deleting lingering writer "PGUIDFMT"\n", PGUID (wr->e.guid)); delete_writer_nolinger_locked (wr); } return n; @@ -2121,12 +2462,21 @@ static struct writer * new_writer_guid struct participant *pp, const struct sertopic *topic, const struct nn_xqos *xqos, +#if LITE + status_cb_t status_cb, + void * status_entity +#else const struct v_gid_s *gid, const struct v_gid_s *group_gid, const char *endpoint_name +#endif ) { +#if LITE + const os_size_t sample_overhead = 80; /* INFO_TS + DATA (approximate figure) + inline QoS */ +#else const os_size_t sample_overhead = 120; /* INFO_TS + DATA (approximate figure) + inline QoS */ +#endif struct writer *wr; nn_mtime_t tnow = now_mt (); @@ -2141,7 +2491,11 @@ static struct writer * new_writer_guid delete_participant won't interfere with our ability to address the participant */ +#if LITE + endpoint_common_init (&wr->e, &wr->c, EK_WRITER, guid, group_guid, pp); +#else endpoint_common_init (&wr->e, &wr->c, EK_WRITER, guid, group_guid, pp, gid, group_gid, endpoint_name); +#endif os_condInit (&wr->throttle_cond, &wr->e.lock, NULL); wr->seq = 0; @@ -2162,9 +2516,14 @@ static struct writer * new_writer_guid wr->num_acks_received = 0; wr->num_nacks_received = 0; wr->throttle_count = 0; + wr->throttle_tracing = 0; wr->rexmit_count = 0; wr->rexmit_lost_count = 0; +#if LITE + wr->status_cb = status_cb; + wr->status_cb_entity = status_entity; +#endif /* Copy QoS, merging in defaults */ @@ -2174,17 +2533,18 @@ static struct writer * new_writer_guid assert (wr->xqos->aliased == 0); set_topic_type_name (wr->xqos, topic); - if (config.enabled_logcats & LC_TRACE) + if (config.enabled_logcats & LC_DISCOVERY) { - TRACE (("WRITER %x:%x:%x:%x QOS={", PGUID (wr->e.guid))); - nn_log_xqos (LC_TRACE, wr->xqos); - TRACE (("}\n")); + nn_log (LC_DISCOVERY, "WRITER "PGUIDFMT" QOS={", PGUID (wr->e.guid)); + nn_log_xqos (LC_DISCOVERY, wr->xqos); + nn_log (LC_DISCOVERY, "}\n"); } assert (wr->xqos->present & QP_RELIABILITY); wr->reliable = (wr->xqos->reliability.kind != NN_BEST_EFFORT_RELIABILITY_QOS); assert (wr->xqos->present & QP_DURABILITY); if (is_builtin_entityid (wr->e.guid.entityid, ownvendorid)) { + assert (wr->xqos->history.kind == NN_KEEP_LAST_HISTORY_QOS); assert (wr->xqos->durability.kind == NN_TRANSIENT_LOCAL_DURABILITY_QOS); wr->aggressive_keep_last = 1; } @@ -2216,14 +2576,79 @@ static struct writer * new_writer_guid (wr->xqos->durability.kind == NN_VOLATILE_DURABILITY_QOS && wr->xqos->reliability.kind != NN_BEST_EFFORT_RELIABILITY_QOS); } +#if LITE + if (topic) + { + pa_inc32 (&((struct sertopic *)topic)->refcount); + } +#endif wr->topic = topic; wr->as = new_addrset (); wr->as_group = NULL; - +#ifdef DDSI_INCLUDE_NETWORK_PARTITIONS + { + unsigned i; + /* This is an open issue how to encrypt mesages send for various + partitions that match multiple network partitions. From a safety + point of view a wierd configuration. Here we chose the first one + that we find */ + wr->partition_id = 0; + for (i = 0; i < wr->xqos->partition.n && wr->partition_id == 0; i++) + wr->partition_id = get_partitionid_from_mapping (wr->xqos->partition.strs[i], wr->xqos->topic_name); + } +#endif /* DDSI_INCLUDE_NETWORK_PARTITIONS */ + +#ifdef DDSI_INCLUDE_SSM + /* Writer supports SSM if it is mapped to a network partition for + which the address set includes an SSM address. If it supports + SSM, it arbitrarily selects one SSM address from the address set + to advertise. */ + wr->supports_ssm = 0; + wr->ssm_as = NULL; + if (config.allowMulticast & AMC_SSM) + { + nn_locator_t loc; + int have_loc = 0; + if (wr->partition_id == 0) + { + if (is_ssm_mcaddr (&gv.loc_default_mc)) + { + loc = gv.loc_default_mc; + have_loc = 1; + } + } + else + { + const struct config_networkpartition_listelem *np = find_networkpartition_by_id (wr->partition_id); + assert (np); + if (addrset_any_ssm (np->as, &loc)) + have_loc = 1; + } + if (have_loc) + { + wr->supports_ssm = 1; + wr->ssm_as = new_addrset (); + add_to_addrset (wr->ssm_as, &loc); + nn_log (LC_DISCOVERY, "writer "PGUIDFMT": ssm=%d", PGUID (wr->e.guid), wr->supports_ssm); + nn_log_addrset (LC_DISCOVERY, "", wr->ssm_as); + nn_log (LC_DISCOVERY, "\n"); + } + } +#endif /* for non-builtin writers, select the eventqueue based on the channel it is mapped to */ +#ifdef DDSI_INCLUDE_NETWORK_CHANNELS + if (!is_builtin_entityid (wr->e.guid.entityid, ownvendorid)) + { + struct config_channel_listelem *channel = find_channel (wr->xqos->transport_priority); + nn_log (LC_DISCOVERY, "writer "PGUIDFMT": transport priority %d => channel '%s' priority %d\n", + PGUID (wr->e.guid), wr->xqos->transport_priority.value, channel->name, channel->priority); + wr->evq = channel->evq ? channel->evq : gv.xevents; + } + else +#endif { wr->evq = gv.xevents; } @@ -2246,7 +2671,7 @@ static struct writer * new_writer_guid if (wr->xqos->liveliness.kind != NN_AUTOMATIC_LIVELINESS_QOS || nn_from_ddsi_duration (wr->xqos->liveliness.lease_duration) != T_NEVER) { - nn_log (LC_INFO, "writer %x:%x:%x:%x: incorrectly treating it as of automatic liveliness kind with lease duration = inf (%d, %"PA_PRId64")\n", PGUID (wr->e.guid), (int) wr->xqos->liveliness.kind, nn_from_ddsi_duration (wr->xqos->liveliness.lease_duration)); + nn_log (LC_INFO | LC_DISCOVERY, "writer "PGUIDFMT": incorrectly treating it as of automatic liveliness kind with lease duration = inf (%d, %"PA_PRId64")\n", PGUID (wr->e.guid), (int) wr->xqos->liveliness.kind, nn_from_ddsi_duration (wr->xqos->liveliness.lease_duration)); } wr->lease_duration = T_NEVER; /* FIXME */ @@ -2275,14 +2700,15 @@ static struct writer * new_writer_guid /* hdepth > 0 => "aggressive keep last", and in that case: why bother blocking for a slow receiver when the entire point of KEEP_LAST is to keep going (at least in a typical interpretation - of the spec */ - wr->whc_low = wr->whc_high = 2147483647u; + of the spec. */ + wr->whc_low = wr->whc_high = INT32_MAX; } else { wr->whc_low = config.whc_lowwater_mark; wr->whc_high = config.whc_init_highwater_mark.value; } + assert (!is_builtin_entityid(wr->e.guid.entityid, ownvendorid) || (wr->whc_low == wr->whc_high && wr->whc_low == INT32_MAX)); } /* Connection admin */ @@ -2319,9 +2745,14 @@ struct writer * new_writer const struct nn_guid *ppguid, const struct sertopic *topic, const struct nn_xqos *xqos, +#if LITE + status_cb_t status_cb, + void * status_cb_arg +#else const struct v_gid_s *gid, const struct v_gid_s *group_gid, const char *endpoint_name +#endif ) { struct participant *pp; @@ -2330,7 +2761,7 @@ struct writer * new_writer if ((pp = ephash_lookup_participant_guid (ppguid)) == NULL) { - TRACE (("new_writer - participant %x:%x:%x:%x not found\n", PGUID (*ppguid))); + nn_log (LC_DISCOVERY, "new_writer - participant "PGUIDFMT" not found\n", PGUID (*ppguid)); return NULL; } /* participant can't be freed while we're mucking around cos we are @@ -2340,16 +2771,28 @@ struct writer * new_writer wrguid->prefix = pp->e.guid.prefix; if (pp_allocate_entityid (&wrguid->entityid, entity_kind, pp) < 0) return NULL; +#if LITE + wr = new_writer_guid (wrguid, group_guid, pp, topic, xqos, status_cb, status_cb_arg); +#else wr = new_writer_guid (wrguid, group_guid, pp, topic, xqos, gid, group_gid, endpoint_name); +#endif return wr; } static void gc_delete_writer (struct gcreq *gcreq) { struct writer *wr = gcreq->arg; - TRACE (("gc_delete_writer(%p, %x:%x:%x:%x)\n", (void *) gcreq, PGUID (wr->e.guid))); + nn_log (LC_DISCOVERY, "gc_delete_writer(%p, "PGUIDFMT")\n", (void *) gcreq, PGUID (wr->e.guid)); gcreq_free (gcreq); + /* We now allow GC while blocked on a full WHC, but we still don't allow deleting a writer while blocked on it. + * The writer's state must be DELETING by the time we get here, and that means the transmit path is no longer blocked. + * It doesn't imply that the write thread is no longer in throttle_writer(), just that if it is, it will soon return from there. + * Therefore, block until it isn't throttling anymore. We can safely lock the writer, as we're on the separate GC thread. + */ + assert (wr->state == WRST_DELETING); + assert (!wr->throttling); + if (wr->heartbeat_xevent) { wr->hbcontrol.tsched.v = T_NEVER; @@ -2370,21 +2813,51 @@ static void gc_delete_writer (struct gcreq *gcreq) /* Do last gasp on SEDP and free writer. */ if (!is_builtin_entityid (wr->e.guid.entityid, ownvendorid)) sedp_dispose_unregister_writer (wr); +#if LITE + if (wr->status_cb) + { + (wr->status_cb) (wr->status_cb_entity, NULL); + } +#endif whc_free (wr->whc); +#ifdef DDSI_INCLUDE_SSM + if (wr->ssm_as) + unref_addrset (wr->ssm_as); +#endif unref_addrset (wr->as); /* must remain until readers gone (rebuilding of addrset) */ nn_xqos_fini (wr->xqos); os_free (wr->xqos); os_condDestroy (&wr->throttle_cond); +#if LITE + sertopic_free ((struct sertopic *) wr->topic); +#endif endpoint_common_fini (&wr->e, &wr->c); os_free (wr); } +static void gc_delete_writer_throttlewait (struct gcreq *gcreq) +{ + struct writer *wr = gcreq->arg; + nn_log (LC_DISCOVERY, "gc_delete_writer_throttlewait(%p, "PGUIDFMT")\n", (void *) gcreq, PGUID (wr->e.guid)); + /* We now allow GC while blocked on a full WHC, but we still don't allow deleting a writer while blocked on it. + * The writer's state must be DELETING by the time we get here, and that means the transmit path is no longer blocked. + * It doesn't imply that the write thread is no longer in throttle_writer(), just that if it is, it will soon return from there. + * Therefore, block until it isn't throttling anymore. We can safely lock the writer, as we're on the separate GC thread. + */ + assert (wr->state == WRST_DELETING); + os_mutexLock (&wr->e.lock); + while (wr->throttling) + os_condWait (&wr->throttle_cond, &wr->e.lock); + os_mutexUnlock (&wr->e.lock); + gcreq_requeue (gcreq, gc_delete_writer); +} + static void writer_set_state (struct writer *wr, enum writer_state newstate) { ASSERT_MUTEX_HELD (&wr->e.lock); - TRACE (("writer_set_state(%x:%x:%x:%x) state transition %d -> %d\n", PGUID (wr->e.guid), wr->state, newstate)); + nn_log (LC_DISCOVERY, "writer_set_state("PGUIDFMT") state transition %d -> %d\n", PGUID (wr->e.guid), wr->state, newstate); assert (newstate > wr->state); if (wr->state == WRST_OPERATIONAL) { @@ -2401,7 +2874,7 @@ static void writer_set_state (struct writer *wr, enum writer_state newstate) int delete_writer_nolinger_locked (struct writer *wr) { - nn_log (LC_DISCOVERY, "delete_writer_nolinger(guid %x:%x:%x:%x) ...\n", PGUID (wr->e.guid)); + nn_log (LC_DISCOVERY, "delete_writer_nolinger(guid "PGUIDFMT") ...\n", PGUID (wr->e.guid)); ASSERT_MUTEX_HELD (&wr->e.lock); ephash_remove_writer_guid (wr); writer_set_state (wr, WRST_DELETING); @@ -2421,10 +2894,10 @@ int delete_writer_nolinger (const struct nn_guid *guid) assert (is_writer_entityid (guid->entityid)); if ((wr = ephash_lookup_writer_guid (guid)) == NULL) { - nn_log (LC_DISCOVERY, "delete_writer_nolinger(guid %x:%x:%x:%x) - unknown guid\n", PGUID (*guid)); + nn_log (LC_DISCOVERY, "delete_writer_nolinger(guid "PGUIDFMT") - unknown guid\n", PGUID (*guid)); return ERR_UNKNOWN_ENTITY; } - nn_log (LC_DISCOVERY, "delete_writer_nolinger(guid %x:%x:%x:%x) ...\n", PGUID (*guid)); + nn_log (LC_DISCOVERY, "delete_writer_nolinger(guid "PGUIDFMT") ...\n", PGUID (*guid)); os_mutexLock (&wr->e.lock); delete_writer_nolinger_locked (wr); os_mutexUnlock (&wr->e.lock); @@ -2436,10 +2909,10 @@ int delete_writer (const struct nn_guid *guid) struct writer *wr; if ((wr = ephash_lookup_writer_guid (guid)) == NULL) { - nn_log (LC_DISCOVERY, "delete_writer(guid %x:%x:%x:%x) - unknown guid\n", PGUID (*guid)); + nn_log (LC_DISCOVERY, "delete_writer(guid "PGUIDFMT") - unknown guid\n", PGUID (*guid)); return ERR_UNKNOWN_ENTITY; } - nn_log (LC_DISCOVERY, "delete_writer(guid %x:%x:%x:%x) ...\n", PGUID (*guid)); + nn_log (LC_DISCOVERY, "delete_writer(guid "PGUIDFMT") ...\n", PGUID (*guid)); os_mutexLock (&wr->e.lock); /* If no unack'ed data, don't waste time or resources (expected to @@ -2448,7 +2921,7 @@ int delete_writer (const struct nn_guid *guid) again in the future) it'll potentially be discarded. */ if (whc_unacked_bytes (wr->whc) == 0) { - TRACE (("delete_writer(guid %x:%x:%x:%x) - no unack'ed samples\n", PGUID (*guid))); + nn_log (LC_DISCOVERY, "delete_writer(guid "PGUIDFMT") - no unack'ed samples\n", PGUID (*guid)); delete_writer_nolinger_locked (wr); os_mutexUnlock (&wr->e.lock); } @@ -2461,8 +2934,8 @@ int delete_writer (const struct nn_guid *guid) os_mutexUnlock (&wr->e.lock); tsched = add_duration_to_mtime (now_mt (), config.writer_linger_duration); mtime_to_sec_usec (&tsec, &tusec, tsched); - TRACE (("delete_writer(guid %x:%x:%x:%x) - unack'ed samples, will delete when ack'd or at t = %"PA_PRId64".%06d\n", - PGUID (*guid), tsec, tusec)); + nn_log (LC_DISCOVERY, "delete_writer(guid "PGUIDFMT") - unack'ed samples, will delete when ack'd or at t = %"PA_PRId64".%06d\n", + PGUID (*guid), tsec, tusec); qxev_delete_writer (tsched, &wr->e.guid); } return 0; @@ -2474,7 +2947,7 @@ void writer_exit_startup_mode (struct writer *wr) /* startup mode and handle_as_transient_local may not both be set */ assert (!(wr->startup_mode && wr->handle_as_transient_local)); if (!wr->startup_mode) - TRACE ((" wr %x:%x:%x:%x skipped\n", PGUID (wr->e.guid))); + nn_log (LC_DISCOVERY, " wr "PGUIDFMT" skipped\n", PGUID (wr->e.guid)); else { unsigned n; @@ -2483,13 +2956,51 @@ void writer_exit_startup_mode (struct writer *wr) whc_downgrade_to_volatile (wr->whc); n = remove_acked_messages (wr); writer_clear_retransmitting (wr); - TRACE ((" wr %x:%x:%x:%x dropped %u entr%s\n", PGUID (wr->e.guid), n, n == 1 ? "y" : "ies")); + nn_log (LC_DISCOVERY, " wr "PGUIDFMT" dropped %u entr%s\n", PGUID (wr->e.guid), n, n == 1 ? "y" : "ies"); } os_mutexUnlock (&wr->e.lock); } /* READER ----------------------------------------------------------- */ +#ifdef DDSI_INCLUDE_NETWORK_PARTITIONS +static struct addrset * get_as_from_mapping (const char *partition, const char *topic) +{ + struct config_partitionmapping_listelem *pm; + struct addrset *as = new_addrset (); + if ((pm = find_partitionmapping (partition, topic)) != NULL) + { + nn_log (LC_DISCOVERY, "matched reader for topic \"%s\" in partition \"%s\" to networkPartition \"%s\"\n", topic, partition, pm->networkPartition); + assert (pm->partition->as); + copy_addrset_into_addrset (as, pm->partition->as); + } + return as; +} + +static void join_mcast_helper (const nn_locator_t *n, void * varg) +{ + ddsi_tran_conn_t conn = (ddsi_tran_conn_t) varg; + if (is_mcaddr (n)) + { + if (ddsi_conn_join_mc (conn, NULL, n) < 0) + { + nn_log (LC_WARNING, "failed to join network partition multicast group\n"); + } + } +} + +static void leave_mcast_helper (const nn_locator_t *n, void * varg) +{ + ddsi_tran_conn_t conn = (ddsi_tran_conn_t) varg; + if (is_mcaddr (n)) + { + if (ddsi_conn_leave_mc (conn, NULL, n) < 0) + { + nn_log (LC_WARNING, "failed to leave network partition multicast group\n"); + } + } +} +#endif /* DDSI_INCLUDE_NETWORK_PARTITIONS */ static struct reader * new_reader_guid ( @@ -2498,9 +3009,15 @@ static struct reader * new_reader_guid struct participant *pp, const struct sertopic *topic, const struct nn_xqos *xqos, +#if LITE + struct rhc *rhc, + status_cb_t status_cb, + void * status_entity +#else const struct v_gid_s *gid, const struct v_gid_s *group_gid, const char *endpoint_name +#endif ) { /* see new_writer_guid for commenets */ @@ -2515,7 +3032,11 @@ static struct reader * new_reader_guid new_reader_writer_common (guid, topic, xqos); rd = os_malloc (sizeof (*rd)); +#if LITE + endpoint_common_init (&rd->e, &rd->c, EK_READER, guid, group_guid, pp); +#else endpoint_common_init (&rd->e, &rd->c, EK_READER, guid, group_guid, pp, gid, group_gid, endpoint_name); +#endif /* Copy QoS, merging in defaults */ rd->xqos = os_malloc (sizeof (*rd->xqos)); @@ -2524,39 +3045,117 @@ static struct reader * new_reader_guid assert (rd->xqos->aliased == 0); set_topic_type_name (rd->xqos, topic); - if (config.enabled_logcats & LC_TRACE) + if (config.enabled_logcats & LC_DISCOVERY) { - TRACE (("READER %x:%x:%x:%x QOS={", PGUID (rd->e.guid))); - nn_log_xqos (LC_TRACE, rd->xqos); - TRACE (("}\n")); + nn_log (LC_DISCOVERY, "READER "PGUIDFMT" QOS={", PGUID (rd->e.guid)); + nn_log_xqos (LC_DISCOVERY, rd->xqos); + nn_log (LC_DISCOVERY, "}\n"); } assert (rd->xqos->present & QP_RELIABILITY); rd->reliable = (rd->xqos->reliability.kind != NN_BEST_EFFORT_RELIABILITY_QOS); assert (rd->xqos->present & QP_DURABILITY); rd->handle_as_transient_local = (rd->xqos->durability.kind == NN_TRANSIENT_LOCAL_DURABILITY_QOS); +#if LITE + if (topic) + { + pa_inc32 (&((struct sertopic *)topic)->refcount); + } +#endif rd->topic = topic; rd->init_acknack_count = 0; +#ifdef DDSI_INCLUDE_SSM + rd->favours_ssm = 0; +#endif +#if LITE + if (topic == NULL) + { + assert (is_builtin_entityid (rd->e.guid.entityid, ownvendorid)); + } + rd->status_cb = status_cb; + rd->status_cb_entity = status_entity; + rd->rhc = rhc; + /* set rhc qos for reader */ + if (rhc) + { + (ddsi_plugin.rhc_set_qos_fn) (rd->rhc, rd->xqos); + } +#else rd->matching_groups = nn_groupset_new (); if (!is_builtin_entityid (rd->e.guid.entityid, ownvendorid)) nn_groupset_fromqos (rd->matching_groups, gv.ospl_kernel, rd->xqos); +#endif assert (rd->xqos->present & QP_LIVELINESS); if (rd->xqos->liveliness.kind != NN_AUTOMATIC_LIVELINESS_QOS || nn_from_ddsi_duration (rd->xqos->liveliness.lease_duration) != T_NEVER) { - nn_log (LC_INFO, "reader %x:%x:%x:%x: incorrectly treating it as of automatic liveliness kind with lease duration = inf (%d, %"PA_PRId64")\n", PGUID (rd->e.guid), (int) rd->xqos->liveliness.kind, nn_from_ddsi_duration (rd->xqos->liveliness.lease_duration)); + nn_log (LC_INFO | LC_DISCOVERY, "reader "PGUIDFMT": incorrectly treating it as of automatic liveliness kind with lease duration = inf (%d, %"PA_PRId64")\n", PGUID (rd->e.guid), (int) rd->xqos->liveliness.kind, nn_from_ddsi_duration (rd->xqos->liveliness.lease_duration)); } +#ifdef DDSI_INCLUDE_NETWORK_PARTITIONS + rd->as = new_addrset (); + if (config.allowMulticast & ~AMC_SPDP) + { + unsigned i; + + /* compile address set from the mapped network partitions */ + for (i = 0; i < rd->xqos->partition.n; i++) + { + struct addrset *pas = get_as_from_mapping (rd->xqos->partition.strs[i], rd->xqos->topic_name); + if (pas) + { +#ifdef DDSI_INCLUDE_SSM + copy_addrset_into_addrset_no_ssm (rd->as, pas); + if (addrset_contains_ssm (pas) && config.allowMulticast & AMC_SSM) + rd->favours_ssm = 1; +#else + copy_addrset_into_addrset (rd->as, pas); +#endif + unref_addrset (pas); + } + } + if (!addrset_empty (rd->as)) + { + /* Iterate over all udp addresses: + * - Set the correct portnumbers + * - Join the socket if a multicast address + */ + addrset_forall (rd->as, join_mcast_helper, gv.data_conn_mc); + if (config.enabled_logcats & LC_DISCOVERY) + { + nn_log (LC_DISCOVERY, "READER "PGUIDFMT" locators={", PGUID (rd->e.guid)); + nn_log_addrset (LC_DISCOVERY, "", rd->as); + nn_log (LC_DISCOVERY, "}\n"); + } + } +#ifdef DDSI_INCLUDE_SSM + else + { + /* Note: SSM requires NETWORK_PARTITIONS; if network partitions + do not override the default, we should check whether the + default is an SSM address. */ + if (is_ssm_mcaddr (&gv.loc_default_mc) && config.allowMulticast & AMC_SSM) + rd->favours_ssm = 1; + } +#endif + } +#ifdef DDSI_INCLUDE_SSM + if (rd->favours_ssm) + nn_log (LC_DISCOVERY, "READER "PGUIDFMT" ssm=%d\n", PGUID (rd->e.guid), rd->favours_ssm); +#endif +#endif ut_avlInit (&rd_writers_treedef, &rd->writers); ephash_insert_reader_guid (rd); match_reader_with_proxy_writers (rd, tnow); sedp_write_reader (rd); +#if !LITE /* If no writers matched, must notify a wait_for_historical_data in OSPL. In Lite, I would argue that wait_for_historical_data should look at the state in DDSI ... but that coupling is problematic in OSPL. */ if (rd->xqos->durability.kind == NN_TRANSIENT_LOCAL_DURABILITY_QOS) notify_wait_for_historical_data (NULL, &rd->e.guid); +#endif return rd; } @@ -2567,9 +3166,15 @@ struct reader * new_reader const struct nn_guid *ppguid, const struct sertopic *topic, const struct nn_xqos *xqos, +#if LITE + struct rhc * rhc, + status_cb_t status_cb, + void * status_cbarg +#else const struct v_gid_s *gid, const struct v_gid_s *group_gid, const char *endpoint_name +#endif ) { struct participant * pp; @@ -2578,14 +3183,18 @@ struct reader * new_reader if ((pp = ephash_lookup_participant_guid (ppguid)) == NULL) { - TRACE (("new_reader - participant %x:%x:%x:%x not found\n", PGUID (*ppguid))); + nn_log (LC_DISCOVERY, "new_reader - participant "PGUIDFMT" not found\n", PGUID (*ppguid)); return NULL; } entity_kind = (topic->nkeys ? NN_ENTITYID_KIND_READER_WITH_KEY : NN_ENTITYID_KIND_READER_NO_KEY); rdguid->prefix = pp->e.guid.prefix; if (pp_allocate_entityid (&rdguid->entityid, entity_kind, pp) < 0) return NULL; +#if LITE + rd = new_reader_guid (rdguid, group_guid, pp, topic, xqos, rhc, status_cb, status_cbarg); +#else rd = new_reader_guid (rdguid, group_guid, pp, topic, xqos, gid, group_gid, endpoint_name); +#endif return rd; } @@ -2593,7 +3202,7 @@ static void gc_delete_reader (struct gcreq *gcreq) { /* see gc_delete_writer for comments */ struct reader *rd = gcreq->arg; - TRACE (("gc_delete_reader(%p, %x:%x:%x:%x)\n", (void *) gcreq, PGUID (rd->e.guid))); + nn_log (LC_DISCOVERY, "gc_delete_reader(%p, "PGUIDFMT")\n", (void *) gcreq, PGUID (rd->e.guid)); gcreq_free (gcreq); while (!ut_avlIsEmpty (&rd->writers)) @@ -2606,10 +3215,28 @@ static void gc_delete_reader (struct gcreq *gcreq) if (!is_builtin_entityid (rd->e.guid.entityid, ownvendorid)) sedp_dispose_unregister_reader (rd); +#ifdef DDSI_INCLUDE_NETWORK_PARTITIONS + addrset_forall (rd->as, leave_mcast_helper, gv.data_conn_mc); +#endif +#if LITE + if (rd->rhc) + { + (ddsi_plugin.rhc_free_fn) (rd->rhc); + } + if (rd->status_cb) + { + (rd->status_cb) (rd->status_cb_entity, NULL); + } + sertopic_free ((struct sertopic *) rd->topic); +#else nn_groupset_free (rd->matching_groups); +#endif nn_xqos_fini (rd->xqos); os_free (rd->xqos); +#ifdef DDSI_INCLUDE_NETWORK_PARTITIONS + unref_addrset (rd->as); +#endif endpoint_common_fini (&rd->e, &rd->c); os_free (rd); @@ -2621,10 +3248,16 @@ int delete_reader (const struct nn_guid *guid) assert (!is_writer_entityid (guid->entityid)); if ((rd = ephash_lookup_reader_guid (guid)) == NULL) { - nn_log (LC_DISCOVERY, "delete_reader_guid(guid %x:%x:%x:%x) - unknown guid\n", PGUID (*guid)); + nn_log (LC_DISCOVERY, "delete_reader_guid(guid "PGUIDFMT") - unknown guid\n", PGUID (*guid)); return ERR_UNKNOWN_ENTITY; } - nn_log (LC_DISCOVERY, "delete_reader_guid(guid %x:%x:%x:%x) ...\n", PGUID (*guid)); +#if LITE + if (rd->rhc) + { + (ddsi_plugin.rhc_fini_fn) (rd->rhc); + } +#endif + nn_log (LC_DISCOVERY, "delete_reader_guid(guid "PGUIDFMT") ...\n", PGUID (*guid)); ephash_remove_reader_guid (rd); gcreq_reader (rd); return 0; @@ -2677,7 +3310,8 @@ void new_proxy_participant const nn_plist_t *plist, os_int64 tlease_dur, nn_vendorid_t vendor, - unsigned custom_flags + unsigned custom_flags, + nn_wctime_t timestamp ) { /* No locking => iff all participants use unique guids, and sedp @@ -2727,7 +3361,10 @@ void new_proxy_participant } else { - pa_stvoidp (&proxypp->lease, lease_new (tlease_dur, &proxypp->e)); + /* Lease duration is meaningless when the lease never expires, but when proxy participants are created implicitly because of endpoint discovery from a cloud service, we do want the lease to expire eventually when the cloud discovery service disappears and never reappears. The normal data path renews the lease, so if the lease expiry is changed after the DS disappears but data continues to flow (even if it is only a single sample) the proxy participant would immediately go back to a non-expiring lease with no further triggers for deleting it. Instead, we take tlease_dur == NEVER as a special value meaning a lease that doesn't expire now and that has a "reasonable" lease duration. That way the lease renewal in the data path is fine, and we only need to do something special in SEDP handling. */ + nn_etime_t texp = add_duration_to_etime (now_et(), tlease_dur); + os_int64 dur = (tlease_dur == T_NEVER) ? config.lease_duration : tlease_dur; + pa_stvoidp (&proxypp->lease, lease_new (texp, dur, &proxypp->e)); proxypp->owns_lease = 1; } } @@ -2738,6 +3375,7 @@ void new_proxy_participant proxypp->plist = nn_plist_dup (plist); ut_avlInit (&proxypp_groups_treedef, &proxypp->groups); +#if !LITE /* - the proxypp gid only matters when generate_builtin_topics is set - with generate_builtin_topics set: - proxy gids are faked unless ENDPOINT_GID present, from 6.4.1 @@ -2759,6 +3397,7 @@ void new_proxy_participant { nn_guid_to_ospl_gid (&proxypp->gid, ppguid, vendor_is_opensplice (vendor)); } +#endif if (custom_flags & CF_INC_KERNEL_SEQUENCE_NUMBERS) proxypp->kernel_sequence_numbers = 1; @@ -2841,11 +3480,16 @@ void new_proxy_participant assert (is_builtin_entityid (guid1.entityid, proxypp->vendor)); if (is_writer_entityid (guid1.entityid)) { - new_proxy_writer (ppguid, &guid1, proxypp->as_meta, &plist_wr, gv.builtins_dqueue, gv.xevents); + new_proxy_writer (ppguid, &guid1, proxypp->as_meta, &plist_wr, gv.builtins_dqueue, gv.xevents, timestamp); } else { - new_proxy_reader (ppguid, &guid1, proxypp->as_meta, &plist_rd); +#ifdef DDSI_INCLUDE_SSM + const int ssm = addrset_contains_ssm (proxypp->as_meta); + new_proxy_reader (ppguid, &guid1, proxypp->as_meta, &plist_rd, timestamp, ssm); +#else + new_proxy_reader (ppguid, &guid1, proxypp->as_meta, &plist_rd, timestamp); +#endif } } } @@ -2862,20 +3506,22 @@ void new_proxy_participant lease_register (pa_ldvoidp (&proxypp->lease)); os_mutexUnlock (&proxypp->e.lock); +#if ! LITE if (config.generate_builtin_topics) { os_mutexLock ((os_mutex *) &proxypp->e.lock); if (proxypp->proxypp_have_spdp) { - write_builtin_topic_proxy_participant (proxypp); + write_builtin_topic_proxy_participant (proxypp, timestamp); if (proxypp->proxypp_have_cm) - write_builtin_topic_proxy_participant_cm (proxypp); + write_builtin_topic_proxy_participant_cm (proxypp, timestamp); } os_mutexUnlock ((os_mutex *) &proxypp->e.lock); } +#endif } -int update_proxy_participant_plist_locked (struct proxy_participant *proxypp, const struct nn_plist *datap, enum update_proxy_participant_source source) +int update_proxy_participant_plist_locked (struct proxy_participant *proxypp, const struct nn_plist *datap, enum update_proxy_participant_source source, nn_wctime_t timestamp) { /* Currently, built-in processing is single-threaded, and it is only through this function and the proxy participant deletion (which necessarily happens when no-one else potentially references the proxy participant anymore). So at the moment, the lock is superfluous. */ nn_plist_t *new_plist; @@ -2886,27 +3532,29 @@ int update_proxy_participant_plist_locked (struct proxy_participant *proxypp, co os_free (proxypp->plist); proxypp->plist = new_plist; +#if ! LITE if (config.generate_builtin_topics) { switch (source) { case UPD_PROXYPP_SPDP: - write_builtin_topic_proxy_participant (proxypp); + write_builtin_topic_proxy_participant (proxypp, timestamp); if (!proxypp->proxypp_have_spdp && proxypp->proxypp_have_cm) - write_builtin_topic_proxy_participant_cm (proxypp); + write_builtin_topic_proxy_participant_cm (proxypp, timestamp); proxypp->proxypp_have_spdp = 1; break; case UPD_PROXYPP_CM: if (proxypp->proxypp_have_spdp) - write_builtin_topic_proxy_participant_cm (proxypp); + write_builtin_topic_proxy_participant_cm (proxypp, timestamp); proxypp->proxypp_have_cm = 1; break; } } +#endif return 0; } -int update_proxy_participant_plist (struct proxy_participant *proxypp, const struct nn_plist *datap, enum update_proxy_participant_source source) +int update_proxy_participant_plist (struct proxy_participant *proxypp, const struct nn_plist *datap, enum update_proxy_participant_source source, nn_wctime_t timestamp) { nn_plist_t tmp; @@ -2915,7 +3563,7 @@ int update_proxy_participant_plist (struct proxy_participant *proxypp, const str switch (source) { case UPD_PROXYPP_SPDP: - update_proxy_participant_plist_locked (proxypp, datap, source); + update_proxy_participant_plist_locked (proxypp, datap, source, timestamp); break; case UPD_PROXYPP_CM: tmp = *datap; @@ -2924,7 +3572,7 @@ int update_proxy_participant_plist (struct proxy_participant *proxypp, const str PP_PRISMTECH_WATCHDOG_SCHEDULING | PP_PRISMTECH_LISTENER_SCHEDULING | PP_PRISMTECH_SERVICE_TYPE | PP_ENTITY_NAME; tmp.qos.present &= QP_PRISMTECH_ENTITY_FACTORY; - update_proxy_participant_plist_locked (proxypp, &tmp, source); + update_proxy_participant_plist_locked (proxypp, &tmp, source, timestamp); break; } os_mutexUnlock (&proxypp->e.lock); @@ -2950,6 +3598,7 @@ static void ref_proxy_participant (struct proxy_participant *proxypp, struct pro static void unref_proxy_participant (struct proxy_participant *proxypp, struct proxy_endpoint_common *c) { os_uint32 refc; + const nn_wctime_t tnow = now(); os_mutexLock (&proxypp->e.lock); refc = --proxypp->refc; @@ -2968,13 +3617,15 @@ static void unref_proxy_participant (struct proxy_participant *proxypp, struct p { assert (proxypp->endpoints == NULL); os_mutexUnlock (&proxypp->e.lock); - TRACE (("unref_proxy_participant(%x:%x:%x:%x): refc=0, freeing\n", PGUID (proxypp->e.guid))); + nn_log (LC_DISCOVERY, "unref_proxy_participant("PGUIDFMT"): refc=0, freeing\n", PGUID (proxypp->e.guid)); +#if ! LITE if (config.generate_builtin_topics) { if (proxypp->proxypp_have_spdp) - dispose_builtin_topic_proxy_participant (proxypp, proxypp->lease_expired); + dispose_builtin_topic_proxy_participant (proxypp, tnow, proxypp->lease_expired); } +#endif unref_addrset (proxypp->as_default); unref_addrset (proxypp->as_meta); @@ -2990,8 +3641,8 @@ static void unref_proxy_participant (struct proxy_participant *proxypp, struct p { assert (refc == 1); os_mutexUnlock (&proxypp->e.lock); - TRACE (("unref_proxy_participant(%x:%x:%x:%x): refc=%u, no endpoints, implicitly created, deleting\n", PGUID (proxypp->e.guid), (unsigned) refc)); - delete_proxy_participant_by_guid(&proxypp->e.guid, 1); + nn_log (LC_DISCOVERY, "unref_proxy_participant("PGUIDFMT"): refc=%u, no endpoints, implicitly created, deleting\n", PGUID (proxypp->e.guid), (unsigned) refc); + delete_proxy_participant_by_guid(&proxypp->e.guid, tnow, 1); /* Deletion is still (and has to be) asynchronous. A parallel endpoint creation may or may not succeed, and if it succeeds it will be deleted along with the proxy participant. So "your mileage may vary". Also, the proxy participant may be blacklisted for a little ... */ @@ -2999,14 +3650,14 @@ static void unref_proxy_participant (struct proxy_participant *proxypp, struct p else { os_mutexUnlock (&proxypp->e.lock); - TRACE (("unref_proxy_participant(%x:%x:%x:%x): refc=%u\n", PGUID (proxypp->e.guid), (unsigned) refc)); + nn_log (LC_DISCOVERY, "unref_proxy_participant("PGUIDFMT"): refc=%u\n", PGUID (proxypp->e.guid), (unsigned) refc); } } static void gc_delete_proxy_participant (struct gcreq *gcreq) { struct proxy_participant *proxypp = gcreq->arg; - TRACE (("gc_delete_proxy_participant(%p, %x:%x:%x:%x)\n", (void *) gcreq, PGUID (proxypp->e.guid))); + nn_log (LC_DISCOVERY, "gc_delete_proxy_participant(%p, "PGUIDFMT")\n", (void *) gcreq, PGUID (proxypp->e.guid)); gcreq_free (gcreq); unref_proxy_participant (proxypp, NULL); } @@ -3020,22 +3671,45 @@ static struct entity_common *entity_common_from_proxy_endpoint_common (const str return (struct entity_common *) ((char *) c - offsetof (struct proxy_writer, c)); } -static void delete_ppt (struct proxy_participant * proxypp, int isimplicit) +static void delete_or_detach_dependent_pp (struct proxy_participant *p, struct proxy_participant *proxypp, nn_wctime_t timestamp, int isimplicit) +{ + os_mutexLock (&p->e.lock); + if (memcmp (&p->privileged_pp_guid, &proxypp->e.guid, sizeof (proxypp->e.guid)) != 0) + { + /* p not dependent on proxypp */ + os_mutexUnlock (&p->e.lock); + return; + } + else if (!(vendor_is_cloud(p->vendor) && p->implicitly_created)) + { + /* DDSI2 minimal participant mode -- but really, anything not discovered via Cloud gets deleted */ + os_mutexUnlock (&p->e.lock); + (void) delete_proxy_participant_by_guid (&p->e.guid, timestamp, isimplicit); + } + else + { + nn_etime_t texp = add_duration_to_etime (now_et(), config.ds_grace_period); + /* Clear dependency (but don't touch entity id, which must be 0x1c1) and set the lease ticking */ + nn_log (LC_DISCOVERY, ""PGUIDFMT" detach-from-DS "PGUIDFMT"\n", PGUID(p->e.guid), PGUID(proxypp->e.guid)); + memset (&p->privileged_pp_guid.prefix, 0, sizeof (p->privileged_pp_guid.prefix)); + lease_set_expiry (pa_ldvoidp (&p->lease), texp); + os_mutexUnlock (&p->e.lock); + } +} + +static void delete_ppt (struct proxy_participant * proxypp, nn_wctime_t timestamp, int isimplicit) { struct proxy_endpoint_common * c; int ret; /* if any proxy participants depend on this participant, delete them */ - TRACE (("delete_ppt(%x:%x:%x:%x) - deleting dependent proxy participants\n", PGUID (proxypp->e.guid))); + nn_log (LC_DISCOVERY, "delete_ppt("PGUIDFMT") - deleting dependent proxy participants\n", PGUID (proxypp->e.guid)); { struct ephash_enum_proxy_participant est; struct proxy_participant *p; ephash_enum_proxy_participant_init (&est); while ((p = ephash_enum_proxy_participant_next (&est)) != NULL) - { - if (memcmp (&p->privileged_pp_guid, &proxypp->e.guid, sizeof (proxypp->e.guid)) == 0) - (void) delete_proxy_participant_by_guid (&p->e.guid, isimplicit); - } + delete_or_detach_dependent_pp(p, proxypp, timestamp, isimplicit); ephash_enum_proxy_participant_fini (&est); } @@ -3046,22 +3720,22 @@ static void delete_ppt (struct proxy_participant * proxypp, int isimplicit) if (isimplicit) proxypp->lease_expired = 1; - TRACE (("delete_ppt(%x:%x:%x:%x) - deleting groups\n", PGUID (proxypp->e.guid))); + nn_log (LC_DISCOVERY, "delete_ppt("PGUIDFMT") - deleting groups\n", PGUID (proxypp->e.guid)); while (!ut_avlIsEmpty (&proxypp->groups)) - delete_proxy_group_locked (ut_avlRoot (&proxypp_groups_treedef, &proxypp->groups), isimplicit); + delete_proxy_group_locked (ut_avlRoot (&proxypp_groups_treedef, &proxypp->groups), timestamp, isimplicit); - TRACE (("delete_ppt(%x:%x:%x:%x) - deleting endpoints\n", PGUID (proxypp->e.guid))); + nn_log (LC_DISCOVERY, "delete_ppt("PGUIDFMT") - deleting endpoints\n", PGUID (proxypp->e.guid)); c = proxypp->endpoints; while (c) { struct entity_common *e = entity_common_from_proxy_endpoint_common (c); if (is_writer_entityid (e->guid.entityid)) { - ret = delete_proxy_writer (&e->guid, isimplicit); + ret = delete_proxy_writer (&e->guid, timestamp, isimplicit); } else { - ret = delete_proxy_reader (&e->guid, isimplicit); + ret = delete_proxy_reader (&e->guid, timestamp, isimplicit); } (void) ret; c = c->next_ep; @@ -3074,13 +3748,14 @@ static void delete_ppt (struct proxy_participant * proxypp, int isimplicit) typedef struct proxy_purge_data { struct proxy_participant *proxypp; const nn_locator_t *loc; + nn_wctime_t timestamp; } *proxy_purge_data_t; static void purge_helper (const nn_locator_t *n, void * varg) { proxy_purge_data_t data = (proxy_purge_data_t) varg; if (compare_locators (n, data->loc) == 0) - delete_proxy_participant_by_guid (&data->proxypp->e.guid, 1); + delete_proxy_participant_by_guid (&data->proxypp->e.guid, data->timestamp, 1); } void purge_proxy_participants (const nn_locator_t *loc, c_bool delete_from_as_disc) @@ -3096,6 +3771,7 @@ void purge_proxy_participants (const nn_locator_t *loc, c_bool delete_from_as_di thread_state_awake(self); data.loc = loc; + data.timestamp = now(); ephash_enum_proxy_participant_init (&est); while ((data.proxypp = ephash_enum_proxy_participant_next (&est)) != NULL) addrset_forall (data.proxypp->as_meta, purge_helper, &data); @@ -3109,31 +3785,31 @@ void purge_proxy_participants (const nn_locator_t *loc, c_bool delete_from_as_di thread_state_asleep(self); } -int delete_proxy_participant_by_guid (const struct nn_guid * guid, int isimplicit) +int delete_proxy_participant_by_guid (const struct nn_guid * guid, nn_wctime_t timestamp, int isimplicit) { struct proxy_participant * ppt; - TRACE (("delete_proxy_participant_by_guid(%x:%x:%x:%x) ", PGUID (*guid))); + nn_log (LC_DISCOVERY, "delete_proxy_participant_by_guid("PGUIDFMT") ", PGUID (*guid)); os_mutexLock (&gv.lock); ppt = ephash_lookup_proxy_participant_guid (guid); if (ppt == NULL) { os_mutexUnlock (&gv.lock); - TRACE (("- unknown\n")); + nn_log (LC_DISCOVERY, "- unknown\n"); return ERR_UNKNOWN_ENTITY; } - TRACE (("- deleting\n")); + nn_log (LC_DISCOVERY, "- deleting\n"); remember_deleted_participant_guid (&ppt->e.guid); ephash_remove_proxy_participant_guid (ppt); os_mutexUnlock (&gv.lock); - delete_ppt (ppt, isimplicit); + delete_ppt (ppt, timestamp, isimplicit); return 0; } /* PROXY-GROUP --------------------------------------------------- */ -int new_proxy_group (const struct nn_guid *guid, const struct v_gid_s *gid, const char *name, const struct nn_xqos *xqos) +int new_proxy_group (const struct nn_guid *guid, const struct v_gid_s *gid, const char *name, const struct nn_xqos *xqos, nn_wctime_t timestamp) { struct proxy_participant *proxypp; nn_guid_t ppguid; @@ -3141,7 +3817,7 @@ int new_proxy_group (const struct nn_guid *guid, const struct v_gid_s *gid, cons ppguid.entityid.u = NN_ENTITYID_PARTICIPANT; if ((proxypp = ephash_lookup_proxy_participant_guid (&ppguid)) == NULL) { - TRACE (("new_proxy_group(%x:%x:%x:%x) - unknown participant\n", PGUID (*guid))); + nn_log (LC_DISCOVERY, "new_proxy_group("PGUIDFMT") - unknown participant\n", PGUID (*guid)); return 0; } else @@ -3173,9 +3849,10 @@ int new_proxy_group (const struct nn_guid *guid, const struct v_gid_s *gid, cons else { /* Always have a guid, may not have a gid */ - TRACE (("new_proxy_group(%x:%x:%x:%x): new\n", PGUID (*guid))); + nn_log (LC_DISCOVERY, "new_proxy_group("PGUIDFMT"): new\n", PGUID (*guid)); pgroup = os_malloc (sizeof (*pgroup)); pgroup->guid = *guid; +#if ! LITE if (gid) { pgroup->gid = *gid; @@ -3184,6 +3861,7 @@ int new_proxy_group (const struct nn_guid *guid, const struct v_gid_s *gid, cons { nn_guid_to_ospl_gid (&pgroup->gid, guid, vendor_is_opensplice (proxypp->vendor)); } +#endif pgroup->proxypp = proxypp; pgroup->name = NULL; pgroup->xqos = NULL; @@ -3192,25 +3870,27 @@ int new_proxy_group (const struct nn_guid *guid, const struct v_gid_s *gid, cons if (name) { assert (xqos != NULL); - TRACE (("new_proxy_group(%x:%x:%x:%x): setting name (%s) and qos\n", PGUID (*guid), name)); + nn_log (LC_DISCOVERY, "new_proxy_group("PGUIDFMT"): setting name (%s) and qos\n", PGUID (*guid), name); pgroup->name = os_strdup (name); pgroup->xqos = nn_xqos_dup (xqos); nn_xqos_mergein_missing (pgroup->xqos, is_sub ? &gv.default_xqos_sub : &gv.default_xqos_pub); +#if ! LITE if (config.generate_builtin_topics) - write_builtin_topic_proxy_group (pgroup); + write_builtin_topic_proxy_group (pgroup, timestamp); +#endif } out: os_mutexUnlock (&proxypp->e.lock); - TRACE (("\n")); + nn_log (LC_DISCOVERY, "\n"); return 0; } } -static void delete_proxy_group_locked (struct proxy_group *pgroup, int isimplicit) +static void delete_proxy_group_locked (struct proxy_group *pgroup, nn_wctime_t timestamp, int isimplicit) { struct proxy_participant *proxypp = pgroup->proxypp; assert ((pgroup->xqos != NULL) == (pgroup->name != NULL)); - TRACE (("delete_proxy_group_locked %x:%x:%x:%x\n", PGUID (pgroup->guid))); + nn_log (LC_DISCOVERY, "delete_proxy_group_locked "PGUIDFMT"\n", PGUID (pgroup->guid)); ut_avlDelete (&proxypp_groups_treedef, &proxypp->groups, pgroup); /* Publish corresponding built-in topic only if it is not a place holder: in that case we haven't announced its presence and @@ -3219,8 +3899,10 @@ static void delete_proxy_group_locked (struct proxy_group *pgroup, int isimplici generation */ if (pgroup->name) { +#if ! LITE if (config.generate_builtin_topics) - dispose_builtin_topic_proxy_group (pgroup, isimplicit); + dispose_builtin_topic_proxy_group (pgroup, timestamp, isimplicit); +#endif nn_xqos_fini (pgroup->xqos); os_free (pgroup->xqos); os_free (pgroup->name); @@ -3228,7 +3910,7 @@ static void delete_proxy_group_locked (struct proxy_group *pgroup, int isimplici os_free (pgroup); } -void delete_proxy_group (const nn_guid_t *guid, int isimplicit) +void delete_proxy_group (const nn_guid_t *guid, nn_wctime_t timestamp, int isimplicit) { struct proxy_participant *proxypp; nn_guid_t ppguid; @@ -3239,7 +3921,7 @@ void delete_proxy_group (const nn_guid_t *guid, int isimplicit) struct proxy_group *pgroup; os_mutexLock (&proxypp->e.lock); if ((pgroup = ut_avlLookup (&proxypp_groups_treedef, &proxypp->groups, guid)) != NULL) - delete_proxy_group_locked (pgroup, isimplicit); + delete_proxy_group_locked (pgroup, timestamp, isimplicit); os_mutexUnlock (&proxypp->e.lock); } } @@ -3271,13 +3953,16 @@ static void proxy_endpoint_common_init c->group_guid = plist->group_guid; else memset (&c->group_guid, 0, sizeof (c->group_guid)); +#if ! LITE if (plist->present & PP_PRISMTECH_GROUP_GID) c->group_gid = plist->group_gid; else if (plist->present & PP_GROUP_GUID) nn_guid_to_ospl_gid (&c->group_gid, &c->group_guid, vendor_is_opensplice (proxypp->vendor)); else memset (&c->group_gid, 0, sizeof (c->group_gid)); +#endif +#if ! LITE if (is_builtin_endpoint (guid->entityid, proxypp->vendor)) memset (&c->gid, 0, sizeof (c->gid)); else if (plist->present & PP_PRISMTECH_ENDPOINT_GID) @@ -3286,6 +3971,7 @@ static void proxy_endpoint_common_init memset (&c->gid, 0, sizeof (c->gid)); /* done lazily */ else nn_guid_to_ospl_gid (&c->gid, guid, vendor_is_opensplice (proxypp->vendor)); +#endif ref_proxy_participant (proxypp, c); } @@ -3303,7 +3989,7 @@ static void proxy_endpoint_common_fini (struct entity_common *e, struct proxy_en /* PROXY-WRITER ----------------------------------------------------- */ -int new_proxy_writer (const struct nn_guid *ppguid, const struct nn_guid *guid, struct addrset *as, const nn_plist_t *plist, struct nn_dqueue *dqueue, struct xeventq *evq) +int new_proxy_writer (const struct nn_guid *ppguid, const struct nn_guid *guid, struct addrset *as, const nn_plist_t *plist, struct nn_dqueue *dqueue, struct xeventq *evq, nn_wctime_t timestamp) { struct proxy_participant *proxypp; struct proxy_writer *pwr; @@ -3315,7 +4001,7 @@ int new_proxy_writer (const struct nn_guid *ppguid, const struct nn_guid *guid, if ((proxypp = ephash_lookup_proxy_participant_guid (ppguid)) == NULL) { - NN_WARNING1 ("new_proxy_writer(%x:%x:%x:%x): proxy participant unknown\n", PGUID (*guid)); + NN_WARNING1 ("new_proxy_writer("PGUIDFMT"): proxy participant unknown\n", PGUID (*guid)); return ERR_UNKNOWN_ENTITY; } @@ -3323,11 +4009,13 @@ int new_proxy_writer (const struct nn_guid *ppguid, const struct nn_guid *guid, proxy_endpoint_common_init (&pwr->e, &pwr->c, EK_PROXY_WRITER, guid, proxypp, as, plist); ut_avlInit (&pwr_readers_treedef, &pwr->readers); +#if !LITE pwr->groups = nn_groupset_new (); pwr->v_message_qos = new_v_message_qos (pwr->c.xqos); pwr->seq_offset = 0; pwr->transaction_id = 0; pwr->cs_seq = 0; +#endif pwr->n_reliable_readers = 0; pwr->n_readers_out_of_sync = 0; pwr->last_seq = 0; @@ -3349,6 +4037,12 @@ int new_proxy_writer (const struct nn_guid *ppguid, const struct nn_guid *guid, pwr->deliver_synchronously = 0; } pwr->have_seen_heartbeat = 0; +#ifdef DDSI_INCLUDE_SSM + pwr->supports_ssm = (addrset_contains_ssm (as) && config.allowMulticast & AMC_SSM) ? 1 : 0; +#endif +#if LITE + pwr->deleting = 0; +#endif isreliable = (pwr->c.xqos->reliability.kind != NN_BEST_EFFORT_RELIABILITY_QOS); /* Only assert PP lease on receipt of data if enabled (duh) and the proxy participant is a @@ -3358,12 +4052,12 @@ int new_proxy_writer (const struct nn_guid *ppguid, const struct nn_guid *guid, assert (pwr->c.xqos->present & QP_LIVELINESS); if (pwr->c.xqos->liveliness.kind != NN_AUTOMATIC_LIVELINESS_QOS) - TRACE ((" FIXME: only AUTOMATIC liveliness supported")); + nn_log (LC_DISCOVERY, " FIXME: only AUTOMATIC liveliness supported"); #if 0 pwr->tlease_dur = nn_from_ddsi_duration (pwr->c.xqos->liveliness.lease_duration); if (pwr->tlease_dur == 0) { - TRACE ((" FIXME: treating lease_duration=0 as inf")); + nn_log (LC_DISCOVERY, " FIXME: treating lease_duration=0 as inf"); pwr->tlease_dur = T_NEVER; } pwr->tlease_end = add_duration_to_wctime (tnow, pwr->tlease_dur); @@ -3382,13 +4076,21 @@ int new_proxy_writer (const struct nn_guid *ppguid, const struct nn_guid *guid, pwr->dqueue = dqueue; pwr->evq = evq; +#if LITE + os_mutexInit (&pwr->rdary_lock, NULL); + pwr->n_readers = 0; + pwr->rdary = os_malloc (sizeof (*pwr->rdary)); + pwr->rdary[0] = NULL; +#endif ephash_insert_proxy_writer_guid (pwr); match_proxy_writer_with_readers (pwr, tnow); +#if ! LITE if (!is_builtin_entityid (pwr->e.guid.entityid, pwr->c.vendor) && config.generate_builtin_topics) { - write_builtin_topic_proxy_writer (pwr); + write_builtin_topic_proxy_writer (pwr, timestamp); } +#endif return 0; } @@ -3404,6 +4106,9 @@ void update_proxy_writer (struct proxy_writer * pwr, struct addrset * as) os_mutexLock (&pwr->e.lock); if (! addrset_eq_onesidederr (pwr->c.as, as)) { +#ifdef DDSI_INCLUDE_SSM + pwr->supports_ssm = (addrset_contains_ssm (as) && config.allowMulticast & AMC_SSM) ? 1 : 0; +#endif unref_addrset (pwr->c.as); ref_addrset (as); pwr->c.as = as; @@ -3476,7 +4181,7 @@ void update_proxy_reader (struct proxy_reader * prd, struct addrset * as) static void gc_delete_proxy_writer (struct gcreq *gcreq) { struct proxy_writer *pwr = gcreq->arg; - TRACE (("gc_delete_proxy_writer(%p, %x:%x:%x:%x)\n", (void *) gcreq, PGUID (pwr->e.guid))); + nn_log (LC_DISCOVERY, "gc_delete_proxy_writer(%p, "PGUIDFMT")\n", (void *) gcreq, PGUID (pwr->e.guid)); gcreq_free (gcreq); while (!ut_avlIsEmpty (&pwr->readers)) @@ -3488,39 +4193,59 @@ static void gc_delete_proxy_writer (struct gcreq *gcreq) free_pwr_rd_match (m); } +#if LITE + os_free (pwr->rdary); + os_mutexDestroy (&pwr->rdary_lock); +#endif proxy_endpoint_common_fini (&pwr->e, &pwr->c); +#if !LITE nn_groupset_free (pwr->groups); c_free (pwr->v_message_qos); +#endif nn_defrag_free (pwr->defrag); nn_reorder_free (pwr->reorder); os_free (pwr); } -int delete_proxy_writer (const struct nn_guid *guid, int isimplicit) +int delete_proxy_writer (const struct nn_guid *guid, nn_wctime_t timestamp, int isimplicit) { struct proxy_writer *pwr; - TRACE (("delete_proxy_writer (%x:%x:%x:%x) ", PGUID (*guid))); + nn_log (LC_DISCOVERY, "delete_proxy_writer ("PGUIDFMT") ", PGUID (*guid)); os_mutexLock (&gv.lock); if ((pwr = ephash_lookup_proxy_writer_guid (guid)) == NULL) { os_mutexUnlock (&gv.lock); - TRACE (("- unknown\n")); + nn_log (LC_DISCOVERY, "- unknown\n"); return ERR_UNKNOWN_ENTITY; } - TRACE (("- deleting\n")); +#if LITE + /* Set "deleting" flag in particular for Lite, to signal to the receive path it can't + trust rdary[] anymore, which is because removing the proxy writer from the hash + table will prevent the readers from looking up the proxy writer, and consequently + from removing themselves from the proxy writer's rdary[]. */ + os_mutexLock (&pwr->rdary_lock); + pwr->deleting = 1; + os_mutexUnlock (&pwr->rdary_lock); +#endif + nn_log (LC_DISCOVERY, "- deleting\n"); ephash_remove_proxy_writer_guid (pwr); os_mutexUnlock (&gv.lock); +#if ! LITE if (!is_builtin_entityid (pwr->e.guid.entityid, pwr->c.vendor) && config.generate_builtin_topics) { - dispose_builtin_topic_proxy_writer (pwr, isimplicit); + dispose_builtin_topic_proxy_writer (pwr, timestamp, isimplicit); } +#endif gcreq_proxy_writer (pwr); return 0; } /* PROXY-READER ----------------------------------------------------- */ -int new_proxy_reader (const struct nn_guid *ppguid, const struct nn_guid *guid, struct addrset *as, const nn_plist_t *plist +int new_proxy_reader (const struct nn_guid *ppguid, const struct nn_guid *guid, struct addrset *as, const nn_plist_t *plist, nn_wctime_t timestamp +#ifdef DDSI_INCLUDE_SSM + , int favours_ssm +#endif ) { struct proxy_participant *proxypp; @@ -3532,7 +4257,7 @@ int new_proxy_reader (const struct nn_guid *ppguid, const struct nn_guid *guid, if ((proxypp = ephash_lookup_proxy_participant_guid (ppguid)) == NULL) { - NN_WARNING1 ("new_proxy_reader(%x:%x:%x:%x): proxy participant unknown\n", PGUID (*guid)); + NN_WARNING1 ("new_proxy_reader("PGUIDFMT"): proxy participant unknown\n", PGUID (*guid)); return ERR_UNKNOWN_ENTITY; } @@ -3540,10 +4265,14 @@ int new_proxy_reader (const struct nn_guid *ppguid, const struct nn_guid *guid, proxy_endpoint_common_init (&prd->e, &prd->c, EK_PROXY_READER, guid, proxypp, as, plist); prd->deleting = 0; +#ifdef DDSI_INCLUDE_SSM + prd->favours_ssm = (favours_ssm && config.allowMulticast & AMC_SSM) ? 1 : 0; +#endif prd->is_fict_trans_reader = 0; /* Only assert PP lease on receipt of data if enabled (duh) and the proxy participant is a "real" participant, rather than the thing we use for endpoints discovered via the DS */ prd->assert_pp_lease = (unsigned) !!config.arrival_of_data_asserts_pp_and_ep_liveliness; +#if ! LITE if (!is_builtin_entityid (guid->entityid, prd->c.vendor) && (proxypp->plist->present & PP_PRISMTECH_PARTICIPANT_VERSION_INFO) && (proxypp->plist->prismtech_participant_version_info.flags & NN_PRISMTECH_FL_DISCOVERY_INCLUDES_GID) && @@ -3551,17 +4280,20 @@ int new_proxy_reader (const struct nn_guid *ppguid, const struct nn_guid *guid, (plist->endpoint_gid.systemId != 0 || plist->endpoint_gid.localId != 0 || plist->endpoint_gid.serial != 0))) { - TRACE (("proxy_reader(%x:%x:%x:%x): no GID, considering fictitious transient data reader\n", PGUID (*guid))); + nn_log (LC_DISCOVERY, "proxy_reader("PGUIDFMT"): no GID, considering fictitious transient data reader\n", PGUID (*guid)); prd->is_fict_trans_reader = 1; } +#endif ut_avlInit (&prd_writers_treedef, &prd->writers); ephash_insert_proxy_reader_guid (prd); match_proxy_reader_with_writers (prd, tnow); +#if ! LITE if (!is_builtin_entityid (prd->e.guid.entityid, prd->c.vendor) && !prd->is_fict_trans_reader && config.generate_builtin_topics) { - write_builtin_topic_proxy_reader (prd); + write_builtin_topic_proxy_reader (prd, timestamp); } +#endif return 0; } @@ -3613,7 +4345,7 @@ static void proxy_reader_set_delete_and_ack_all_messages (struct proxy_reader *p static void gc_delete_proxy_reader (struct gcreq *gcreq) { struct proxy_reader *prd = gcreq->arg; - TRACE (("gc_delete_proxy_reader(%p, %x:%x:%x:%x)\n", (void *) gcreq, PGUID (prd->e.guid))); + nn_log (LC_DISCOVERY, "gc_delete_proxy_reader(%p, "PGUIDFMT")\n", (void *) gcreq, PGUID (prd->e.guid)); gcreq_free (gcreq); while (!ut_avlIsEmpty (&prd->writers)) @@ -3628,20 +4360,20 @@ static void gc_delete_proxy_reader (struct gcreq *gcreq) os_free (prd); } -int delete_proxy_reader (const struct nn_guid *guid, int isimplicit) +int delete_proxy_reader (const struct nn_guid *guid, nn_wctime_t timestamp, int isimplicit) { struct proxy_reader *prd; - TRACE (("delete_proxy_reader (%x:%x:%x:%x) ", PGUID (*guid))); + nn_log (LC_DISCOVERY, "delete_proxy_reader ("PGUIDFMT") ", PGUID (*guid)); os_mutexLock (&gv.lock); if ((prd = ephash_lookup_proxy_reader_guid (guid)) == NULL) { os_mutexUnlock (&gv.lock); - TRACE (("- unknown\n")); + nn_log (LC_DISCOVERY, "- unknown\n"); return ERR_UNKNOWN_ENTITY; } ephash_remove_proxy_reader_guid (prd); os_mutexUnlock (&gv.lock); - TRACE (("- deleting\n")); + nn_log (LC_DISCOVERY, "- deleting\n"); /* If the proxy reader is reliable, pretend it has just acked all messages: this allows a throttled writer to once again make @@ -3649,10 +4381,12 @@ int delete_proxy_reader (const struct nn_guid *guid, int isimplicit) do its work. */ proxy_reader_set_delete_and_ack_all_messages (prd); +#if ! LITE if (!is_builtin_entityid (prd->e.guid.entityid, prd->c.vendor) && !prd->is_fict_trans_reader && config.generate_builtin_topics) { - dispose_builtin_topic_proxy_reader (prd, isimplicit); + dispose_builtin_topic_proxy_reader (prd, timestamp, isimplicit); } +#endif gcreq_proxy_reader (prd); return 0; } @@ -3669,7 +4403,7 @@ static int gcreq_participant (struct participant *pp) static int gcreq_writer (struct writer *wr) { - struct gcreq *gcreq = gcreq_new (gv.gcreq_queue, gc_delete_writer); + struct gcreq *gcreq = gcreq_new (gv.gcreq_queue, wr->throttling ? gc_delete_writer_throttlewait : gc_delete_writer); gcreq->arg = wr; gcreq_enqueue (gcreq); return 0; @@ -3695,7 +4429,7 @@ static void gc_delete_proxy_writer_dqueue_bubble_cb (struct gcreq *gcreq) { /* delete proxy_writer, phase 3 */ struct proxy_writer *pwr = gcreq->arg; - TRACE (("gc_delete_proxy_writer_dqueue_bubble(%p, %x:%x:%x:%x)\n", (void *) gcreq, PGUID (pwr->e.guid))); + nn_log (LC_DISCOVERY, "gc_delete_proxy_writer_dqueue_bubble(%p, "PGUIDFMT")\n", (void *) gcreq, PGUID (pwr->e.guid)); gcreq_requeue (gcreq, gc_delete_proxy_writer); } @@ -3704,7 +4438,7 @@ static void gc_delete_proxy_writer_dqueue (struct gcreq *gcreq) /* delete proxy_writer, phase 2 */ struct proxy_writer *pwr = gcreq->arg; struct nn_dqueue *dqueue = pwr->dqueue; - TRACE (("gc_delete_proxy_writer_dqueue(%p, %x:%x:%x:%x)\n", (void *) gcreq, PGUID (pwr->e.guid))); + nn_log (LC_DISCOVERY, "gc_delete_proxy_writer_dqueue(%p, "PGUIDFMT")\n", (void *) gcreq, PGUID (pwr->e.guid)); nn_dqueue_enqueue_callback (dqueue, (void (*) (void *)) gc_delete_proxy_writer_dqueue_bubble_cb, gcreq); } @@ -3723,5 +4457,3 @@ static int gcreq_proxy_reader (struct proxy_reader *prd) gcreq_enqueue (gcreq); return 0; } - -/* SHA1 not available (unoffical build.) */ diff --git a/src/services/ddsi2/code/q_entity.h b/src/services/ddsi2e/core/q_entity.h similarity index 87% rename from src/services/ddsi2/code/q_entity.h rename to src/services/ddsi2e/core/q_entity.h index 7160cd2d5..da84645ad 100644 --- a/src/services/ddsi2/code/q_entity.h +++ b/src/services/ddsi2e/core/q_entity.h @@ -1,18 +1,16 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * @@ -25,7 +23,11 @@ #include "os_cond.h" #include "os_socket.h" +#if LITE +#include "dds_types.h" +#else #include "kernelModuleI.h" +#endif #include "ut_avl.h" #include "q_rtps.h" @@ -43,7 +45,9 @@ extern "C" { struct xevent; struct nn_reorder; +#if ! LITE struct nn_groupset; +#endif struct nn_defrag; struct nn_dqueue; struct addrset; @@ -56,6 +60,18 @@ struct v_gid_s; struct proxy_group; struct proxy_endpoint_common; +#if LITE +typedef struct status_cb_data +{ + uint32_t status; + uint32_t extra; + uint64_t handle; + bool add; +} +status_cb_data_t; + +typedef void (*status_cb_t) (void * entity, const status_cb_data_t * data); +#endif struct prd_wr_match { ut_avlNode_t avlnode; @@ -65,6 +81,10 @@ struct prd_wr_match { struct rd_pwr_match { ut_avlNode_t avlnode; nn_guid_t pwr_guid; +#ifdef DDSI_INCLUDE_SSM + nn_locator_t ssm_mc_loc; + nn_locator_t ssm_src_loc; +#endif }; struct wr_prd_match { @@ -133,6 +153,9 @@ struct entity_common { enum entity_kind kind; nn_guid_t guid; char *name; +#if LITE + uint64_t iid; +#endif os_mutex lock; }; @@ -157,9 +180,11 @@ struct participant struct endpoint_common { struct participant *pp; +#if ! LITE struct ephash_chain_entry gid_hash_chain; v_gid gid; v_gid group_gid; +#endif nn_guid_t group_guid; }; @@ -178,6 +203,10 @@ struct writer { struct entity_common e; struct endpoint_common c; +#if LITE + status_cb_t status_cb; + void * status_cb_entity; +#endif os_cond throttle_cond; long long seq; /* last sequence number (transmitted seqs are 1 ... seq) */ long long cs_seq; /* 1st seq in coherent set (or 0) */ @@ -195,6 +224,10 @@ struct writer unsigned startup_mode: 1; /* causes data to be treated as T-L for a while */ unsigned include_keyhash: 1; unsigned retransmitting: 1; +#ifdef DDSI_INCLUDE_SSM + unsigned supports_ssm: 1; + struct addrset *ssm_as; +#endif const struct sertopic * topic; struct addrset *as; /* set of addresses to publish to */ struct addrset *as_group; @@ -206,9 +239,13 @@ struct writer nn_etime_t t_whc_high_upd; int num_reliable_readers; ut_avlTree_t readers; +#ifdef DDSI_INCLUDE_NETWORK_PARTITIONS + os_uint32 partition_id; +#endif os_uint32 num_acks_received; os_uint32 num_nacks_received; os_uint32 throttle_count; + os_uint32 throttle_tracing; os_uint32 rexmit_count; os_uint32 rexmit_lost_count; struct xeventq *evq; @@ -218,11 +255,23 @@ struct reader { struct entity_common e; struct endpoint_common c; +#if LITE + status_cb_t status_cb; + void * status_cb_entity; + struct rhc * rhc; +#else struct nn_groupset *matching_groups; +#endif struct nn_xqos *xqos; unsigned reliable: 1; unsigned handle_as_transient_local: 1; +#ifdef DDSI_INCLUDE_SSM + unsigned favours_ssm: 1; +#endif nn_count_t init_acknack_count; +#ifdef DDSI_INCLUDE_NETWORK_PARTITIONS + struct addrset *as; +#endif const struct sertopic * topic; ut_avlTree_t writers; }; @@ -236,7 +285,9 @@ struct proxy_participant unsigned prismtech_bes; nn_guid_t privileged_pp_guid; /* if this PP depends on another PP for its SEDP writing */ nn_plist_t *plist; +#if ! LITE v_gid gid; +#endif pa_voidp_t lease; /* struct lease *; owns_lease flag indicates whether the proxypp owns the lease */ struct addrset *as_default; struct addrset *as_meta; @@ -262,7 +313,9 @@ struct proxy_participant struct proxy_group { ut_avlNode_t avlnode; nn_guid_t guid; +#if ! LITE v_gid gid; +#endif char *name; struct proxy_participant *proxypp; struct nn_xqos *xqos; @@ -278,14 +331,17 @@ struct proxy_endpoint_common struct addrset *as; nn_guid_t group_guid; /* 0:0:0:0 if not available */ nn_vendorid_t vendor; /* cached from proxypp->vendor */ +#if ! LITE v_gid gid; /* 0:0:0 for built-in endpoints */ v_gid group_gid; /* 0:0:0 if not available */ +#endif }; struct proxy_writer { struct entity_common e; struct proxy_endpoint_common c; ut_avlTree_t readers; +#if ! LITE struct nn_groupset *groups; c_array v_message_qos; /* Transactions: current transaction id for the kernel and DDSI @@ -296,6 +352,7 @@ struct proxy_writer { c_ulong transaction_id; os_int64 cs_seq; os_int64 seq_offset; +#endif int n_reliable_readers; int n_readers_out_of_sync; long long last_seq; /* last known seq, not last delivered */ @@ -306,10 +363,19 @@ struct proxy_writer { unsigned deliver_synchronously: 1; unsigned have_seen_heartbeat: 1; unsigned assert_pp_lease: 1; +#ifdef DDSI_INCLUDE_SSM + unsigned supports_ssm: 1; +#endif struct nn_defrag *defrag; struct nn_reorder *reorder; struct nn_dqueue *dqueue; struct xeventq *evq; +#if LITE + os_mutex rdary_lock; + int n_readers; + struct reader **rdary; /* for efficient delivery, null-pointer terminated */ + unsigned deleting: 1; /* set when being deleted and (about to be) removed from GUID hash */ +#endif }; struct proxy_reader { @@ -318,6 +384,9 @@ struct proxy_reader { unsigned deleting: 1; /* set when being deleted */ unsigned is_fict_trans_reader: 1; /* only true when this is certain */ unsigned assert_pp_lease: 1; +#ifdef DDSI_INCLUDE_SSM + unsigned favours_ssm: 1; +#endif ut_avlTree_t writers; }; @@ -396,6 +465,9 @@ int pp_allocate_entityid (nn_entityid_t *id, unsigned kind, struct participant * (a.o.) */ int new_participant_guid (const nn_guid_t *ppguid, unsigned flags, const struct nn_plist *plist); +#if LITE +int new_participant (struct nn_guid *ppguid, unsigned flags, const struct nn_plist *plist); +#endif /* To delete a DDSI participant: this only removes the participant from the hash tables and schedules the actual delete operation, @@ -422,9 +494,14 @@ struct writer * new_writer const struct nn_guid *ppguid, const struct sertopic *topic, const struct nn_xqos *xqos, +#if LITE + status_cb_t status_cb, + void * status_cb_arg +#else const struct v_gid_s *gid, const struct v_gid_s *group_gid, const char *endpoint_name +#endif ); struct reader * new_reader @@ -434,9 +511,15 @@ struct reader * new_reader const struct nn_guid *ppguid, const struct sertopic *topic, const struct nn_xqos *xqos, +#if LITE + struct rhc * rhc, + status_cb_t status_cb, + void * status_cb_arg +#else const struct v_gid_s *gid, const struct v_gid_s *group_gid, const char *endpoint_name +#endif ); unsigned remove_acked_messages (struct writer *wr); @@ -475,24 +558,27 @@ int delete_reader (const struct nn_guid *guid); /* Set when this proxy participant is not to be announced on the built-in topics yet */ #define CF_PROXYPP_NO_SPDP (1 << 3) -void new_proxy_participant (const struct nn_guid *guid, unsigned bes, unsigned prismtech_bes, const struct nn_guid *privileged_pp_guid, struct addrset *as_default, struct addrset *as_meta, const struct nn_plist *plist, os_int64 tlease_dur, nn_vendorid_t vendor, unsigned custom_flags); -int delete_proxy_participant_by_guid (const struct nn_guid * guid, int isimplicit); +void new_proxy_participant (const struct nn_guid *guid, unsigned bes, unsigned prismtech_bes, const struct nn_guid *privileged_pp_guid, struct addrset *as_default, struct addrset *as_meta, const struct nn_plist *plist, os_int64 tlease_dur, nn_vendorid_t vendor, unsigned custom_flags, nn_wctime_t timestamp); +int delete_proxy_participant_by_guid (const struct nn_guid * guid, nn_wctime_t timestamp, int isimplicit); enum update_proxy_participant_source { UPD_PROXYPP_SPDP, UPD_PROXYPP_CM }; -int update_proxy_participant_plist_locked (struct proxy_participant *proxypp, const struct nn_plist *datap, enum update_proxy_participant_source source); -int update_proxy_participant_plist (struct proxy_participant *proxypp, const struct nn_plist *datap, enum update_proxy_participant_source source); +int update_proxy_participant_plist_locked (struct proxy_participant *proxypp, const struct nn_plist *datap, enum update_proxy_participant_source source, nn_wctime_t timestamp); +int update_proxy_participant_plist (struct proxy_participant *proxypp, const struct nn_plist *datap, enum update_proxy_participant_source source, nn_wctime_t timestamp); void proxy_participant_reassign_lease (struct proxy_participant *proxypp, struct lease *newlease); void purge_proxy_participants (const nn_locator_t *loc, c_bool delete_from_as_disc); /* To create a new proxy writer or reader; the proxy participant is determined from the GUID and must exist. */ -int new_proxy_writer (const struct nn_guid *ppguid, const struct nn_guid *guid, struct addrset *as, const struct nn_plist *plist, struct nn_dqueue *dqueue, struct xeventq *evq); -int new_proxy_reader (const struct nn_guid *ppguid, const struct nn_guid *guid, struct addrset *as, const struct nn_plist *plist +int new_proxy_writer (const struct nn_guid *ppguid, const struct nn_guid *guid, struct addrset *as, const struct nn_plist *plist, struct nn_dqueue *dqueue, struct xeventq *evq, nn_wctime_t timestamp); +int new_proxy_reader (const struct nn_guid *ppguid, const struct nn_guid *guid, struct addrset *as, const struct nn_plist *plist, nn_wctime_t timestamp +#ifdef DDSI_INCLUDE_SSM + , int favours_ssm +#endif ); /* To delete a proxy writer or reader; these synchronously hide it @@ -500,26 +586,26 @@ int new_proxy_reader (const struct nn_guid *ppguid, const struct nn_guid *guid, reader or writer. Actual deletion is scheduled in the future, when no outstanding references may still exist (determined by checking thread progress, &c.). */ -int delete_proxy_writer (const struct nn_guid *guid, int isimplicit); -int delete_proxy_reader (const struct nn_guid *guid, int isimplicit); +int delete_proxy_writer (const struct nn_guid *guid, nn_wctime_t timestamp, int isimplicit); +int delete_proxy_reader (const struct nn_guid *guid, nn_wctime_t timestamp, int isimplicit); void update_proxy_reader (struct proxy_reader * prd, struct addrset *as); void update_proxy_writer (struct proxy_writer * pwr, struct addrset *as); -int new_proxy_group (const struct nn_guid *guid, const struct v_gid_s *gid, const char *name, const struct nn_xqos *xqos); -void delete_proxy_group (const struct nn_guid *guid, int isimplicit); +int new_proxy_group (const struct nn_guid *guid, const struct v_gid_s *gid, const char *name, const struct nn_xqos *xqos, nn_wctime_t timestamp); +void delete_proxy_group (const struct nn_guid *guid, nn_wctime_t timestamp, int isimplicit); void writer_exit_startup_mode (struct writer *wr); +#if ! LITE /* To update readers/proxy writers with new groups when they are created by the kernel */ void add_group_to_readers_and_proxy_writers (const struct sertopic *topic, const char *partition, v_group group); /* to signal historical data is complete, pwr may be NULL */ void notify_wait_for_historical_data (struct proxy_writer *pwr, const nn_guid_t *rd_guid); +#endif #if defined (__cplusplus) } #endif #endif /* Q_ENTITY_H */ - -/* SHA1 not available (unoffical build.) */ diff --git a/src/services/ddsi2/code/q_ephash.c b/src/services/ddsi2e/core/q_ephash.c similarity index 96% rename from src/services/ddsi2/code/q_ephash.c rename to src/services/ddsi2e/core/q_ephash.c index 6ef345d22..3eabc2032 100644 --- a/src/services/ddsi2/code/q_ephash.c +++ b/src/services/ddsi2e/core/q_ephash.c @@ -1,18 +1,16 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * @@ -35,8 +33,10 @@ #include "q_rtps.h" /* guid_t */ #include "q_thread.h" /* for assert(thread is awake) */ +#if ! LITE #include "kernelModule.h" /* v_gid */ #include "v_public.h" /* v_handleIsEqual */ +#endif #define CONTAINER_OF(ptr, type, member) ((type *) ((char *) (ptr) - offsetof (type, member))) @@ -66,6 +66,7 @@ static const os_uint64 unihashconsts[] = { static void ephash_update_enums_on_delete (struct ephash *h, struct ephash_chain_entry *ce); +#if ! LITE static int hash_gid (const v_gid *gid, int nbitskey) { /* Universal hashing relying on 64-bit arithmetic. SystemId is a constant for local writers, but with bridging support requires handling entities from all over the domain and hence is needed in at least some cases. Easiest is to always take it into account. See, e.g., http://en.wikipedia.org/wiki/Universal_hash_function. */ @@ -75,6 +76,7 @@ static int hash_gid (const v_gid *gid, int nbitskey) ((os_uint32) gid->serial * unihashconsts[2])) >> (64 - nbitskey)); } +#endif static int hash_guid (const struct nn_guid *guid, int nbitskey) { @@ -86,10 +88,12 @@ static int hash_guid (const struct nn_guid *guid, int nbitskey) >> (64 - nbitskey)); } +#if ! LITE static int gid_eq (const struct v_gid_s *a, const struct v_gid_s *b) { return v_gidEqual (*a, *b); } +#endif static int guid_eq (const struct nn_guid *a, const struct nn_guid *b) { @@ -330,6 +334,7 @@ struct proxy_reader *ephash_lookup_proxy_reader_guid (const struct nn_guid *guid return ephash_lookup_guid (gv.guid_hash, guid, EK_PROXY_READER); } +#if ! LITE /* GID-based */ static void ephash_gid_insert (struct ephash *gid_hash, struct generic_endpoint *ep) @@ -392,6 +397,7 @@ struct reader *ephash_lookup_reader_gid (const struct ephash *gid_hash, const st assert (ep == NULL || ep->e.kind == EK_READER); return (struct reader *) ep; } +#endif /* Enumeration */ @@ -551,5 +557,3 @@ void ephash_enum_proxy_participant_fini (struct ephash_enum_proxy_participant *s { ephash_enum_fini (&st->st); } - -/* SHA1 not available (unoffical build.) */ diff --git a/src/services/ddsi2/code/q_ephash.h b/src/services/ddsi2e/core/q_ephash.h similarity index 90% rename from src/services/ddsi2/code/q_ephash.h rename to src/services/ddsi2e/core/q_ephash.h index ac18fb1b6..9a1717214 100644 --- a/src/services/ddsi2/code/q_ephash.h +++ b/src/services/ddsi2e/core/q_ephash.h @@ -1,18 +1,16 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * @@ -100,6 +98,7 @@ struct reader *ephash_lookup_reader_guid (const struct nn_guid *guid); struct proxy_writer *ephash_lookup_proxy_writer_guid (const struct nn_guid *guid); struct proxy_reader *ephash_lookup_proxy_reader_guid (const struct nn_guid *guid); +#if ! LITE struct v_gid_s; void ephash_insert_writer_gid (struct ephash *gid_hash, struct writer *wr); void ephash_insert_reader_gid (struct ephash *gid_hash, struct reader *rd); @@ -107,6 +106,7 @@ void ephash_remove_writer_gid (struct ephash *gid_hash, struct writer *wr); void ephash_remove_reader_gid (struct ephash *gid_hash, struct reader *rd); struct writer *ephash_lookup_writer_gid (const struct ephash *gid_hash, const struct v_gid_s *gid); struct reader *ephash_lookup_reader_gid (const struct ephash *gid_hash, const struct v_gid_s *gid); +#endif /* Enumeration of entries in the hash table: @@ -154,5 +154,3 @@ void ephash_enum_proxy_participant_fini (struct ephash_enum_proxy_participant *s #endif #endif /* Q_EPHASH_H */ - -/* SHA1 not available (unoffical build.) */ diff --git a/src/services/ddsi2e/core/q_error.h b/src/services/ddsi2e/core/q_error.h new file mode 100644 index 000000000..16c301c84 --- /dev/null +++ b/src/services/ddsi2e/core/q_error.h @@ -0,0 +1,32 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#ifndef NN_ERROR_H +#define NN_ERROR_H + +#define ERR_UNSPECIFIED -1 +#define ERR_INVALID -2 +#define ERR_OUT_OF_MEMORY -3 +#define ERR_ENTITY_EXISTS -4 +#define ERR_UNKNOWN_ENTITY -5 +#define ERR_OUT_OF_IDS -6 +#define ERR_INVALID_DATA -7 +#define ERR_BUSY -8 +#define ERR_NO_ADDRESS -9 +#define ERR_TIMEOUT -10 + +#endif /* NN_ERROR_H */ diff --git a/src/services/ddsi2e/core/q_feature_check.h b/src/services/ddsi2e/core/q_feature_check.h new file mode 100644 index 000000000..689f0fd09 --- /dev/null +++ b/src/services/ddsi2e/core/q_feature_check.h @@ -0,0 +1,63 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +/* Feature macros: + + - ENCRYPTION: support for encryption + requires: NETWORK_PARTITIONS + + - SSM: support for source-specific multicast + requires: NETWORK_PARTIITONS + also requires platform support; SSM is silently disabled if the + platform doesn't support it + + - BANDWIDTH_LIMITING: transmit-side bandwidth limiting + requires: NETWORK_CHANNELS (for now, anyway) + + - IPV6: support for IPV6 + requires: platform support (which itself is not part of DDSI) + + - NETWORK_PARTITIONS: support for multiple network partitions + + - NETWORK_CHANNELS: support for multiple network channels + +*/ + +#ifdef DDSI_INCLUDE_ENCRYPTION + #ifndef DDSI_INCLUDE_NETWORK_PARTITIONS + #error "ENCRYPTION requires NETWORK_PARTITIONS" + #endif +#endif + +#ifdef DDSI_INCLUDE_SSM + #ifndef DDSI_INCLUDE_NETWORK_PARTITIONS + #error "SSM requires NETWORK_PARTITIONS" + #endif + + #include "os_socket.h" + #ifndef OS_SOCKET_HAS_SSM + #error "OS_SOCKET_HAS_SSM should be defined" + #elif ! OS_SOCKET_HAS_SSM + #undef DDSI_INCLUDE_SSM + #endif +#endif + +#ifdef DDSI_INCLUDE_BANDWIDTH_LIMITING + #ifndef DDSI_INCLUDE_NETWORK_CHANNELS + #error "BANDWIDTH_LIMITING requires NETWORK_CHANNELS" + #endif +#endif diff --git a/src/services/ddsi2/code/q_gc.c b/src/services/ddsi2e/core/q_gc.c similarity index 90% rename from src/services/ddsi2/code/q_gc.c rename to src/services/ddsi2e/core/q_gc.c index eff3f2505..e563aaef3 100644 --- a/src/services/ddsi2/code/q_gc.c +++ b/src/services/ddsi2e/core/q_gc.c @@ -1,18 +1,16 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * @@ -90,11 +88,13 @@ static int threads_vtime_check (unsigned *nivs, struct idx_vtime *ivs) static void *gcreq_queue_thread (struct gcreq_queue *q) { struct thread_state1 *self = lookup_thread_state (); + nn_mtime_t next_thread_cputime = { 0 }; struct gcreq *gcreq = NULL; int trace_shortsleep = 1; os_mutexLock (&q->lock); while (!(q->terminate && q->count == 0)) { + LOG_THREAD_CPUTIME (next_thread_cputime); /* If we are waiting for a gcreq to become ready, don't bother looking at the queue; if we aren't, wait for a request to come in. We can't really wait until something came in because we're @@ -136,7 +136,7 @@ static void *gcreq_queue_thread (struct gcreq_queue *q) TRACE (("gc %p: not yet, shortsleep\n", (void*)gcreq)); trace_shortsleep = 0; } - os_sleep(1*OS_DURATION_MILLISECOND); + ospl_os_sleep(1*OS_DURATION_MILLISECOND); } else { @@ -259,5 +259,3 @@ int gcreq_requeue (struct gcreq *gcreq, gcreq_cb_t cb) gcreq->cb = cb; return gcreq_enqueue_common (gcreq); } - -/* SHA1 not available (unoffical build.) */ diff --git a/src/services/ddsi2e/core/q_gc.h b/src/services/ddsi2e/core/q_gc.h new file mode 100644 index 000000000..6003aee13 --- /dev/null +++ b/src/services/ddsi2e/core/q_gc.h @@ -0,0 +1,63 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#ifndef Q_GC_H +#define Q_GC_H + +#include "q_thread.h" + +#if defined (__cplusplus) +extern "C" { +#endif + +struct gcreq; +struct gcreq_queue; + +struct writer; +struct reader; +struct proxy_writer; +struct proxy_reader; + +typedef void (*gcreq_cb_t) (struct gcreq *gcreq); + +struct idx_vtime { + unsigned idx; + vtime_t vtime; +}; + +struct gcreq { + struct gcreq *next; + struct gcreq_queue *queue; + gcreq_cb_t cb; + void *arg; + unsigned nvtimes; + struct idx_vtime vtimes[1 /* really a flex ary */]; +}; + +struct gcreq_queue *gcreq_queue_new (void); +void gcreq_queue_free (struct gcreq_queue *q); + +struct gcreq *gcreq_new (struct gcreq_queue *gcreq_queue, gcreq_cb_t cb); +void gcreq_free (struct gcreq *gcreq); +void gcreq_enqueue (struct gcreq *gcreq); +int gcreq_requeue (struct gcreq *gcreq, gcreq_cb_t cb); + +#if defined (__cplusplus) +} +#endif + +#endif /* Q_GC_H */ diff --git a/src/services/ddsi2/code/q_globals.h b/src/services/ddsi2e/core/q_globals.h similarity index 86% rename from src/services/ddsi2/code/q_globals.h rename to src/services/ddsi2e/core/q_globals.h index 4a4133bf0..e7423bc2d 100644 --- a/src/services/ddsi2/code/q_globals.h +++ b/src/services/ddsi2e/core/q_globals.h @@ -1,18 +1,16 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * @@ -31,14 +29,19 @@ #include "ut_fibheap.h" +#if !LITE #include "c_base.h" #include "kernelModuleI.h" +#endif #include "q_plist.h" #include "q_protocol.h" #include "q_nwif.h" #include "q_sockwaitset.h" +#ifdef DDSI_INCLUDE_ENCRYPTION +#include "q_security.h" /* for q_securityDecoderSet */ +#endif /* DDSI_INCLUDE_ENCRYPTION */ #if defined (__cplusplus) extern "C" { @@ -84,13 +87,16 @@ enum recvips_mode { struct q_globals { volatile int terminate; volatile int exception; - volatile int deaf_mute; + volatile int deaf; + volatile int mute; +#if ! LITE /* OpenSplice base & kernel pointers, QoS type */ c_base ospl_base; v_kernel ospl_kernel; c_collectionType ospl_qostype; c_collectionType ospl_eotgroup_tidlist_type; +#endif /* Hash tables for participants, readers, writers, proxy participants, proxy readers and proxy writers by GUID @@ -158,6 +164,11 @@ struct q_globals { struct participant *privileged_pp; os_mutex privileged_pp_lock; +#if LITE + /* GUID to be used in next call to new_participant; also protected + by privileged_pp_lock */ + struct nn_guid next_ppguid; +#endif /* number of up, non-loopback, IPv4/IPv6 interfaces, the index of the selected/preferred one, and the discovered interfaces. */ @@ -206,6 +217,12 @@ struct q_globals { os_mutex lock; +#if LITE + /* guarantees serialisation of attach/detach operations on waitsets + -- a single global lock is a bit coarse, but these operations are + rare and at initialisation time anyway */ + os_mutex attach_lock; +#endif /* Receive thread. (We can only has one for now, cos of the signal trigger socket.) Receive buffer pool is per receive thread, @@ -263,11 +280,13 @@ struct q_globals { struct ddsi_tran_conn * tev_conn; +#ifndef DDSI_INCLUDE_NETWORK_CHANNELS os_uint32 networkQueueId; struct thread_state1 *channel_reader_ts; /* Application data gets its own delivery queue */ struct nn_dqueue *user_dqueue; +#endif /* Transmit side: pools for the serializer & transmit messages and a transmit queue*/ @@ -279,10 +298,18 @@ struct q_globals { remove the need to include kernelModule.h) */ os_uint32 myNetworkId; +#if ! LITE /* Shared memory exhaustion warnings */ pa_uint32_t last_threshold_warning_sec; pa_uint32_t memory_shortage_dropcount; +#endif +#ifdef DDSI_INCLUDE_ENCRYPTION + /* Codecs needed for decoding incoming encrypted messages + FIXME: should be a property of the receiver thread, and pass down + while processing messages. For now made global */ + q_securityDecoderSet recvSecurityCodec; +#endif /* DDSI_INCLUDE_ENCRYPTION */ /* File for dumping captured packets, NULL if disabled */ FILE *pcap_fp; @@ -306,5 +333,3 @@ extern struct q_globals OS_API gv; #endif #endif /* Q_GLOBALS_H */ - -/* SHA1 not available (unoffical build.) */ diff --git a/src/services/ddsi2e/core/q_hbcontrol.h b/src/services/ddsi2e/core/q_hbcontrol.h new file mode 100644 index 000000000..1df35f6c4 --- /dev/null +++ b/src/services/ddsi2e/core/q_hbcontrol.h @@ -0,0 +1,48 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#ifndef Q_HBCONTROL_H +#define Q_HBCONTROL_H + +#if defined (__cplusplus) +extern "C" { +#endif + +struct writer; + +struct hbcontrol { + nn_mtime_t t_of_last_write; + nn_mtime_t t_of_last_hb; + nn_mtime_t t_of_last_ackhb; + nn_mtime_t tsched; + unsigned hbs_since_last_write; + unsigned last_packetid; +}; + +void writer_hbcontrol_init (struct hbcontrol *hbc); +os_int64 writer_hbcontrol_intv (const struct writer *wr, nn_mtime_t tnow); +void writer_hbcontrol_note_asyncwrite (struct writer *wr, nn_mtime_t tnow); +int writer_hbcontrol_ack_required (const struct writer *wr, nn_mtime_t tnow); +struct nn_xmsg *writer_hbcontrol_piggyback (struct writer *wr, nn_mtime_t tnow, unsigned packetid, int *hbansreq); +int writer_hbcontrol_must_send (const struct writer *wr, nn_mtime_t tnow); +struct nn_xmsg *writer_hbcontrol_create_heartbeat (struct writer *wr, nn_mtime_t tnow, int hbansreq, int issync); + +#if defined (__cplusplus) +} +#endif + +#endif /* Q_HBCONTROL_H */ diff --git a/src/services/ddsi2/code/q_init.c b/src/services/ddsi2e/core/q_init.c similarity index 80% rename from src/services/ddsi2/code/q_init.c rename to src/services/ddsi2e/core/q_init.c index 242d844ca..35fb36a5b 100644 --- a/src/services/ddsi2/code/q_init.c +++ b/src/services/ddsi2e/core/q_init.c @@ -1,18 +1,16 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * @@ -312,6 +310,13 @@ static int set_spdp_address (void) rc = string_to_default_locator (&gv.loc_spdp_mc, def, port, 1, "SPDP address"); assert (rc > 0); } +#ifdef DDSI_INCLUDE_SSM + if (is_ssm_mcaddr (&gv.loc_spdp_mc)) + { + NN_ERROR1 ("%s: SPDP address may not be an SSM address\n", config.spdpMulticastAddressString); + return -1; + } +#endif if (!(config.allowMulticast & AMC_SPDP) || config.suppress_spdp_multicast) { /* Explicitly disabling SPDP multicasting is always possible */ @@ -374,10 +379,25 @@ static int set_ext_address_and_mask (void) return 0; } +#ifdef DDSI_INCLUDE_NETWORK_CHANNELS +static int known_channel_p (const char *name) +{ + const struct config_channel_listelem *c; + for (c = config.channels; c; c = c->next) + if (strcmp (name, c->name) == 0) + return 1; + return 0; +} +#endif static int check_thread_properties (void) { +#ifdef DDSI_INCLUDE_NETWORK_CHANNELS + static const char *fixed[] = { "recv", "tev", "gc", "lease", "dq.builtins", "debmon", NULL }; + static const char *chanprefix[] = { "xmit.", "tev.","dq.",NULL }; +#else static const char *fixed[] = { "recv", "tev", "gc", "lease", "dq.builtins", "xmit.user", "dq.user", "debmon", NULL }; +#endif const struct config_thread_properties_listelem *e; int ok = 1, i; for (e = config.thread_properties; e; e = e->next) @@ -387,8 +407,24 @@ static int check_thread_properties (void) break; if (fixed[i] == NULL) { +#ifdef DDSI_INCLUDE_NETWORK_CHANNELS + /* Some threads are named after the channel, with names of the form PREFIX.CHAN */ + + for (i = 0; chanprefix[i]; i++) + { + size_t n = strlen (chanprefix[i]); + if (strncmp (chanprefix[i], e->name, n) == 0 && known_channel_p (e->name + n)) + break; + } + if (chanprefix[i] == NULL) + { + NN_ERROR1 ("config: DDSI2Service/Threads/Thread[@name=\"%s\"]: unknown thread\n", e->name); + ok = 0; + } +#else NN_ERROR1 ("config: DDSI2Service/Threads/Thread[@name=\"%s\"]: unknown thread\n", e->name); ok = 0; +#endif /* DDSI_INCLUDE_NETWORK_CHANNELS */ } } return ok; @@ -431,6 +467,10 @@ int rtps_config_open (void) int rtps_config_prep (struct cfgst *cfgst) { +#ifdef DDSI_INCLUDE_NETWORK_CHANNELS + unsigned num_channels = 0; + unsigned num_channel_threads = 0; +#endif /* if the discovery domain id was explicitly set, override the default here */ if (!config.discoveryDomainId.isdefault) @@ -440,6 +480,7 @@ int rtps_config_prep (struct cfgst *cfgst) /* retry_on_reject_duration default is dependent on late_ack_mode and responsiveness timeout, so fix up */ +#if !LITE if (config.retry_on_reject_duration.isdefault) { if (config.late_ack_mode) @@ -447,6 +488,7 @@ int rtps_config_prep (struct cfgst *cfgst) else config.retry_on_reject_duration.value = 4 * (config.responsiveness_timeout / 5); } +#endif if (config.whc_init_highwater_mark.isdefault) config.whc_init_highwater_mark.value = config.whc_lowwater_mark; @@ -485,7 +527,22 @@ int rtps_config_prep (struct cfgst *cfgst) } if (config.max_queued_rexmit_bytes == 0) { +#ifdef DDSI_INCLUDE_BANDWIDTH_LIMITING + if (config.auxiliary_bandwidth_limit == 0) + config.max_queued_rexmit_bytes = 2147483647u; + else + { + double max = (double) config.auxiliary_bandwidth_limit * ((double) config.nack_delay / 1e9); + if (max < 0) + NN_FATAL1 ("AuxiliaryBandwidthLimit * NackDelay = %g bytes is insane\n", max); + if (max > 2147483647.0) + config.max_queued_rexmit_bytes = 2147483647u; + else + config.max_queued_rexmit_bytes = (unsigned) max; + } +#else config.max_queued_rexmit_bytes = 2147483647u; +#endif /* DDSI_INCLUDE_BANDWIDTH_LIMITING */ } /* Verify thread properties refer to defined threads */ @@ -507,6 +564,47 @@ int rtps_config_prep (struct cfgst *cfgst) } #endif +#ifdef DDSI_INCLUDE_NETWORK_CHANNELS + { + /* Determine number of configured channels to be able to + determine the correct number of threads. Also fix fields if + at default, and check for some known IPv4/IPv6 + "compatibility" issues */ + struct config_channel_listelem *chptr = config.channels; + int error = 0; + + while (chptr) + { + os_size_t slen = strlen (chptr->name) + 5; + char *thread_name = os_malloc (slen); + snprintf (thread_name, slen, "tev.%s", chptr->name); + if (chptr->queue_size == 0) + chptr->queue_size = config.nw_queue_size; + + num_channels++; + num_channel_threads += 2; /* xmit and dqueue */ + + if (config.useIpv6 && chptr->diffserv_field != 0) + { + NN_ERROR1 ("channel %s specifies IPv4 DiffServ settings which is incompatible with IPv6 use\n", + chptr->name); + error = 1; + } + + if ( +#ifdef DDSI_INCLUDE_BANDWIDTH_LIMITING + chptr->auxiliary_bandwidth_limit > 0 || +#endif + lookup_thread_properties (thread_name)) + num_channel_threads++; + + os_free (thread_name); + chptr = chptr->next; + } + if (error) + goto err_config_late_error; + } +#endif /* DDSI_INCLUDE_NETWORK_CHANNELS */ /* Open tracing file after all possible config errors have been printed */ @@ -526,15 +624,43 @@ int rtps_config_prep (struct cfgst *cfgst) /* For Lite - Temporary Thread states for each application thread is managed using thread_states structure */ +#if LITE +#define USER_MAX_THREADS 50 +#else #define USER_MAX_THREADS 0 +#endif +#ifdef DDSI_INCLUDE_NETWORK_CHANNELS + const unsigned max_threads = 7 + USER_MAX_THREADS + num_channel_threads + config.ddsi2direct_max_threads; +#else const unsigned max_threads = 9 + USER_MAX_THREADS + config.ddsi2direct_max_threads; +#endif thread_states_init (max_threads); } /* Now the per-thread-log-buffers are set up, so print the configuration */ - config_print_and_free_cfgst (cfgst); + q_config_print_and_free_cfgst (cfgst); +#ifdef DDSI_INCLUDE_NETWORK_PARTITIONS + /* Convert address sets in partition mappings from string to address sets */ + { + const int port = config.port_base + config.port_dg * config.domainId + config.port_d2; + struct config_networkpartition_listelem *np; + for (np = config.networkPartitions; np; np = np->next) + { + static const char msgtag_fixed[] = ": partition address"; + os_size_t slen = strlen (np->name) + sizeof (msgtag_fixed); + char * msgtag = os_malloc (slen); + int rc; + snprintf (msgtag, slen, "%s%s", np->name, msgtag_fixed); + np->as = new_addrset (); + rc = add_addresses_to_addrset (np->as, np->address_string, port, msgtag, 1); + os_free (msgtag); + if (rc < 0) + goto err_config_late_error; + } + } +#endif return 0; @@ -552,6 +678,11 @@ static void joinleave_spdp_defmcip_helper (const nn_locator_t *loc, void *varg) struct joinleave_spdp_defmcip_helper_arg *arg = varg; if (!is_mcaddr (loc)) return; +#ifdef DDSI_INCLUDE_SSM + /* Can't join SSM until we actually have a source */ + if (is_ssm_mcaddr (loc)) + return; +#endif if (arg->dojoin) { if (ddsi_conn_join_mc (gv.disc_conn_mc, NULL, loc) < 0 || ddsi_conn_join_mc (gv.data_conn_mc, NULL, loc) < 0) arg->errcount++; @@ -678,6 +809,9 @@ int rtps_init (void) nn_log (LC_CONFIG, "networkid: 0x%lx\n", (unsigned long) gv.myNetworkId); nn_log (LC_CONFIG, "SPDP MC: %s\n", locator_to_string_no_port (buf, &gv.loc_spdp_mc)); nn_log (LC_CONFIG, "default MC: %s\n", locator_to_string_no_port (buf, &gv.loc_default_mc)); +#ifdef DDSI_INCLUDE_SSM + nn_log (LC_CONFIG, "SSM support included\n"); +#endif } if (gv.ownip.ss_family != gv.extip.ss_family) @@ -691,6 +825,13 @@ int rtps_init (void) gv.xmsgpool = nn_xmsgpool_new (); gv.serpool = ddsi_serstatepool_new (); +#ifdef DDSI_INCLUDE_ENCRYPTION + if (q_security_plugin.new_decoder) + { + gv.recvSecurityCodec = (q_security_plugin.new_decoder) (); + nn_log (LC_CONFIG, "decoderset created\n"); + } +#endif nn_plist_init_default_participant (&gv.default_plist_pp); nn_xqos_init_default_reader (&gv.default_xqos_rd); @@ -713,14 +854,23 @@ int rtps_init (void) os_mutexInit (&gv.privileged_pp_lock, NULL); gv.privileged_pp = NULL; +#if LITE + /* Template PP guid -- protected by privileged_pp_lock for simplicity */ + gv.next_ppguid.prefix.u[0] = sockaddr_to_hopefully_unique_uint32 (&gv.ownip); + gv.next_ppguid.prefix.u[1] = (unsigned) getpid (); /* FIXME! OS abstraction */ + gv.next_ppguid.prefix.u[2] = 1; + gv.next_ppguid.entityid.u = NN_ENTITYID_PARTICIPANT; +#endif os_mutexInit (&gv.lock, NULL); os_mutexInit (&gv.spdp_lock, NULL); gv.spdp_defrag = nn_defrag_new (NN_DEFRAG_DROP_OLDEST, config.defrag_unreliable_maxsamples); gv.spdp_reorder = nn_reorder_new (NN_REORDER_MODE_ALWAYS_DELIVER, config.primary_reorder_maxsamples); +#if ! LITE pa_st32 (&gv.last_threshold_warning_sec, 0); pa_st32 (&gv.memory_shortage_dropcount, 0); +#endif if (gv.m_factory->m_connless) { @@ -850,6 +1000,62 @@ int rtps_init (void) gv.tev_conn = gv.data_conn_uc; TRACE (("Timed event transmit port: %d\n", (int) ddsi_tran_port (gv.tev_conn))); +#ifdef DDSI_INCLUDE_NETWORK_CHANNELS + { + struct config_channel_listelem *chptr = config.channels; + while (chptr) + { + os_size_t slen = strlen (chptr->name) + 5; + char * tname = os_malloc (slen); + snprintf (tname, slen, "tev.%s", chptr->name); + + /* Only actually create new connection if diffserv set */ + + if (chptr->diffserv_field) + { + ddsi_tran_qos_t qos = ddsi_tran_create_qos (); + qos->m_diffserv = chptr->diffserv_field; + chptr->transmit_conn = ddsi_factory_create_conn (gv.m_factory, 0, qos); + ddsi_tran_free_qos (qos); + if (chptr->transmit_conn == NULL) + { + NN_FATAL1 ("failed to create transmit connection for channel %s\n", chptr->name); + } + } + else + { + chptr->transmit_conn = gv.data_conn_uc; + } + TRACE (("channel %s: transmit port %d\n", chptr->name, (int) ddsi_tran_port (chptr->transmit_conn))); + +#ifdef DDSI_INCLUDE_BANDWIDTH_LIMITING + if (chptr->auxiliary_bandwidth_limit > 0 || lookup_thread_properties (tname)) + { + chptr->evq = xeventq_new + ( + chptr->transmit_conn, + config.max_queued_rexmit_bytes, + config.max_queued_rexmit_msgs, + chptr->auxiliary_bandwidth_limit + ); + } +#else + if (lookup_thread_properties (tname)) + { + chptr->evq = xeventq_new + ( + chptr->transmit_conn, + config.max_queued_rexmit_bytes, + config.max_queued_rexmit_msgs, + 0 + ); + } +#endif + os_free (tname); + chptr = chptr->next; + } + } +#endif /* DDSI_INCLUDE_NETWORK_CHANNELS */ /* Create event queues */ @@ -858,7 +1064,11 @@ int rtps_init (void) gv.tev_conn, config.max_queued_rexmit_bytes, config.max_queued_rexmit_msgs, +#ifdef DDSI_INCLUDE_BANDWIDTH_LIMITING + config.auxiliary_bandwidth_limit +#else 0 +#endif ); gv.as_disc = new_addrset (); @@ -897,7 +1107,25 @@ int rtps_init (void) } } +#ifdef DDSI_INCLUDE_NETWORK_CHANNELS + /* Create a delivery queue and start tev for each channel */ + { + struct config_channel_listelem * chptr = config.channels; + while (chptr) + { + chptr->dqueue = nn_dqueue_new (chptr->name, config.delivery_queue_maxsamples, user_dqueue_handler, NULL); + if (chptr->evq) + { + int r; + if ((r = xeventq_start (chptr->evq, chptr->name)) < 0) + NN_FATAL2 ("failed to start event processing thread for channel '%s' (%d)\n", chptr->name, r); + } + chptr = chptr->next; + } + } +#else gv.user_dqueue = nn_dqueue_new ("user", config.delivery_queue_maxsamples, user_dqueue_handler, NULL); +#endif gv.recv_ts = create_thread ("recv", (void * (*) (void *)) recv_thread, gv.rbufpool); if (gv.listener) @@ -938,6 +1166,10 @@ int rtps_init (void) lease_management_term (); os_condDestroy (&gv.participant_set_cond); os_mutexDestroy (&gv.participant_set_lock); +#ifdef DDSI_INCLUDE_ENCRYPTION + if (q_security_plugin.free_decoder) + q_security_plugin.free_decoder (gv.recvSecurityCodec); +#endif nn_xqos_fini (&gv.builtin_endpoint_xqos_wr); nn_xqos_fini (&gv.builtin_endpoint_xqos_rd); nn_xqos_fini (&gv.spdp_endpoint_xqos); @@ -1004,6 +1236,9 @@ void rtps_term_prep (void) void rtps_term (void) { struct thread_state1 *self = lookup_thread_state (); +#ifdef DDSI_INCLUDE_NETWORK_CHANNELS + struct config_channel_listelem * chptr; +#endif /* Stop all I/O */ rtps_term_prep (); @@ -1017,6 +1252,13 @@ void rtps_term (void) } xeventq_stop (gv.xevents); +#ifdef DDSI_INCLUDE_NETWORK_CHANNELS + for (chptr = config.channels; chptr; chptr = chptr->next) + { + if (chptr->evq) + xeventq_stop (chptr->evq); + } +#endif /* DDSI_INCLUDE_NETWORK_CHANNELS */ /* Send a bubble through the delivery queue for built-ins, so that any pending proxy participant discovery is finished before we start @@ -1040,10 +1282,17 @@ void rtps_term (void) nn_reorder_free (gv.spdp_reorder); nn_defrag_free (gv.spdp_defrag); os_mutexDestroy (&gv.spdp_lock); +#ifdef DDSI_INCLUDE_ENCRYPTION + if (q_security_plugin.free_decoder) + { + (q_security_plugin.free_decoder) (gv.recvSecurityCodec); + } +#endif /* DDSI_INCLUDE_ENCRYPTION */ { struct ephash_enum_proxy_participant est; struct proxy_participant *proxypp; + const nn_wctime_t tnow = now(); /* Clean up proxy readers, proxy writers and proxy participants. Deleting a proxy participants deletes all its readers and writers automatically */ @@ -1051,7 +1300,7 @@ void rtps_term (void) ephash_enum_proxy_participant_init (&est); while ((proxypp = ephash_enum_proxy_participant_next (&est)) != NULL) { - delete_proxy_participant_by_guid(&proxypp->e.guid, 1); + delete_proxy_participant_by_guid(&proxypp->e.guid, tnow, 1); } ephash_enum_proxy_participant_fini (&est); thread_state_asleep (self); @@ -1116,10 +1365,34 @@ void rtps_term (void) the expected reference counts all over the radmin thingummies. */ nn_dqueue_free (gv.builtins_dqueue); +#ifdef DDSI_INCLUDE_NETWORK_CHANNELS + chptr = config.channels; + while (chptr) + { + nn_dqueue_free (chptr->dqueue); + chptr = chptr->next; + } +#else nn_dqueue_free (gv.user_dqueue); +#endif xeventq_free (gv.xevents); +#ifdef DDSI_INCLUDE_NETWORK_CHANNELS + chptr = config.channels; + while (chptr) + { + if (chptr->evq) + { + xeventq_free (chptr->evq); + } + if (chptr->transmit_conn != gv.data_conn_uc) + { + ddsi_conn_free (chptr->transmit_conn); + } + chptr = chptr->next; + } +#endif ut_thread_pool_free (gv.thread_pool); @@ -1143,6 +1416,9 @@ void rtps_term (void) ddsi_factory_free (gv.m_factory); + if (!config.tcp_enable) + ddsi_udp_deinit(); + if (gv.pcap_fp) { os_mutexDestroy (&gv.pcap_lock); @@ -1195,5 +1471,3 @@ void rtps_term (void) nn_xmsgpool_free (gv.xmsgpool); (ddsi_plugin.fini_fn) (); } - -/* SHA1 not available (unoffical build.) */ diff --git a/src/services/ddsi2/code/q_inline.h b/src/services/ddsi2e/core/q_inline.h similarity index 76% rename from src/services/ddsi2/code/q_inline.h rename to src/services/ddsi2e/core/q_inline.h index 1ff67717d..acb13a440 100644 --- a/src/services/ddsi2/code/q_inline.h +++ b/src/services/ddsi2e/core/q_inline.h @@ -1,18 +1,16 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * @@ -76,5 +74,3 @@ #endif #endif /* NN_INLINE_H */ - -/* SHA1 not available (unoffical build.) */ diff --git a/src/services/ddsi2/code/q_lat_estim.c b/src/services/ddsi2e/core/q_lat_estim.c similarity index 77% rename from src/services/ddsi2/code/q_lat_estim.c rename to src/services/ddsi2e/core/q_lat_estim.c index e94676c63..cd82b1e7b 100644 --- a/src/services/ddsi2/code/q_lat_estim.c +++ b/src/services/ddsi2e/core/q_lat_estim.c @@ -1,18 +1,16 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * @@ -90,5 +88,3 @@ double nn_lat_estim_current (const struct nn_lat_estim *le) { } #endif - -/* SHA1 not available (unoffical build.) */ diff --git a/src/services/ddsi2e/core/q_lat_estim.h b/src/services/ddsi2e/core/q_lat_estim.h new file mode 100644 index 000000000..f4de22b1f --- /dev/null +++ b/src/services/ddsi2e/core/q_lat_estim.h @@ -0,0 +1,50 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#ifndef NN_LAT_ESTIM_H +#define NN_LAT_ESTIM_H + +#include "os_defs.h" + +#include "q_log.h" + +#if defined (__cplusplus) +extern "C" { +#endif + +#define NN_LAT_ESTIM_MEDIAN_WINSZ 7 + +struct nn_lat_estim { + /* median filtering with a small window in an attempt to remove the + worst outliers */ + int index; + float window[NN_LAT_ESTIM_MEDIAN_WINSZ]; + /* simple alpha filtering for smoothing */ + float smoothed; +}; + +void nn_lat_estim_init (struct nn_lat_estim *le); +void nn_lat_estim_fini (struct nn_lat_estim *le); +void nn_lat_estim_update (struct nn_lat_estim *le, os_int64 est); +double nn_lat_estim_current (const struct nn_lat_estim *le); +int nn_lat_estim_log (logcat_t logcat, const char *tag, const struct nn_lat_estim *le); + +#if defined (__cplusplus) +} +#endif + +#endif /* NN_LAT_ESTIM_H */ diff --git a/src/services/ddsi2/code/q_lease.c b/src/services/ddsi2e/core/q_lease.c similarity index 76% rename from src/services/ddsi2/code/q_lease.c rename to src/services/ddsi2e/core/q_lease.c index 6db03bd0b..0dde0bbd2 100644 --- a/src/services/ddsi2/code/q_lease.c +++ b/src/services/ddsi2e/core/q_lease.c @@ -1,18 +1,16 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * @@ -59,7 +57,7 @@ struct lease { ut_fibheapNode_t heapnode; nn_etime_t tsched; /* access guarded by leaseheap_lock */ nn_etime_t tend; /* access guarded by lock_lease/unlock_lease */ - os_int64 tdur; /* constant */ + os_int64 tdur; /* constant (renew depends on it) */ struct entity_common *entity; /* constant */ }; @@ -110,14 +108,14 @@ static void unlock_lease (const struct lease *l) os_mutexUnlock (lock_lease_addr (l)); } -struct lease *lease_new (os_int64 tdur, struct entity_common *e) +struct lease *lease_new (nn_etime_t texpire, os_int64 tdur, struct entity_common *e) { struct lease *l; if ((l = os_malloc (sizeof (*l))) == NULL) return NULL; - TRACE (("lease_new(tdur %"PA_PRId64" guid %x:%x:%x:%x) @ %p\n", tdur, PGUID (e->guid), (void *) l)); + TRACE (("lease_new(tdur %"PA_PRId64" guid "PGUIDFMT") @ %p\n", tdur, PGUID (e->guid), (void *) l)); l->tdur = tdur; - l->tend = add_duration_to_etime (now_et (), tdur); + l->tend = texpire; l->tsched.v = TSCHED_NOT_ON_HEAP; l->entity = e; return l; @@ -125,25 +123,26 @@ struct lease *lease_new (os_int64 tdur, struct entity_common *e) void lease_register (struct lease *l) { - TRACE (("lease_register(l %p guid %x:%x:%x:%x)\n", (void *) l, PGUID (l->entity->guid))); - assert (l->tsched.v == TSCHED_NOT_ON_HEAP); + TRACE (("lease_register(l %p guid "PGUIDFMT")\n", (void *) l, PGUID (l->entity->guid))); os_mutexLock (&gv.leaseheap_lock); lock_lease (l); - l->tsched = l->tend; + assert (l->tsched.v == TSCHED_NOT_ON_HEAP); + if (l->tend.v != T_NEVER) + { + l->tsched = l->tend; + ut_fibheapInsert (&lease_fhdef, &gv.leaseheap, l); + } unlock_lease (l); - ut_fibheapInsert (&lease_fhdef, &gv.leaseheap, l); os_mutexUnlock (&gv.leaseheap_lock); } void lease_free (struct lease *l) { - TRACE (("lease_free(l %p guid %x:%x:%x:%x)\n", (void *) l, PGUID (l->entity->guid))); + TRACE (("lease_free(l %p guid "PGUIDFMT")\n", (void *) l, PGUID (l->entity->guid))); + os_mutexLock (&gv.leaseheap_lock); if (l->tsched.v != TSCHED_NOT_ON_HEAP) - { - os_mutexLock (&gv.leaseheap_lock); ut_fibheapDelete (&lease_fhdef, &gv.leaseheap, l); - os_mutexUnlock (&gv.leaseheap_lock); - } + os_mutexUnlock (&gv.leaseheap_lock); os_free (l); } @@ -152,7 +151,8 @@ void lease_renew (struct lease *l, nn_etime_t tnowE) nn_etime_t tend_new = add_duration_to_etime (tnowE, l->tdur); int did_update; lock_lease (l); - if (tend_new.v <= l->tend.v) + /* do not touch tend if moving forward or if already expired */ + if (tend_new.v <= l->tend.v || tnowE.v >= l->tend.v) did_update = 0; else { @@ -161,7 +161,7 @@ void lease_renew (struct lease *l, nn_etime_t tnowE) } unlock_lease (l); - if ((config.enabled_logcats & LC_TRACE) && did_update) + if (did_update && (config.enabled_logcats & LC_TRACE)) { int tusec; os_int64 tsec; @@ -169,15 +169,39 @@ void lease_renew (struct lease *l, nn_etime_t tnowE) if (l->entity->guid.entityid.u == NN_ENTITYID_PARTICIPANT) TRACE ((":%x", l->entity->guid.entityid.u)); else - TRACE (("%x:%x:%x:%x", PGUID (l->entity->guid))); + TRACE ((""PGUIDFMT"", PGUID (l->entity->guid))); etime_to_sec_usec (&tsec, &tusec, tend_new); TRACE ((" %"PA_PRId64".%06d)", tsec, tusec)); } } +void lease_set_expiry (struct lease *l, nn_etime_t when) +{ + assert (when.v >= 0); + os_mutexLock (&gv.leaseheap_lock); + lock_lease (l); + l->tend = when; + if (l->tend.v < l->tsched.v) + { + /* moved forward and currently scheduled (by virtue of + TSCHED_NOT_ON_HEAP == INT64_MIN) */ + l->tsched = l->tend; + ut_fibheapDecreaseKey (&lease_fhdef, &gv.leaseheap, l); + } + else if (l->tsched.v == TSCHED_NOT_ON_HEAP && l->tend.v < T_NEVER) + { + /* not currently scheduled, with a finite new expiry time */ + l->tsched = l->tend; + ut_fibheapInsert (&lease_fhdef, &gv.leaseheap, l); + } + unlock_lease (l); + os_mutexUnlock (&gv.leaseheap_lock); +} + void check_and_handle_lease_expiration (UNUSED_ARG (struct thread_state1 *self), nn_etime_t tnowE) { struct lease *l; + const nn_wctime_t tnow = now(); os_mutexLock (&gv.leaseheap_lock); while ((l = ut_fibheapMin (&lease_fhdef, &gv.leaseheap)) != NULL && l->tsched.v <= tnowE.v) { @@ -190,13 +214,19 @@ void check_and_handle_lease_expiration (UNUSED_ARG (struct thread_state1 *self), lock_lease (l); if (tnowE.v < l->tend.v) { - l->tsched = l->tend; - unlock_lease (l); - ut_fibheapInsert (&lease_fhdef, &gv.leaseheap, l); + if (l->tend.v == T_NEVER) { + /* don't reinsert if it won't expire */ + l->tsched.v = TSCHED_NOT_ON_HEAP; + unlock_lease (l); + } else { + l->tsched = l->tend; + unlock_lease (l); + ut_fibheapInsert (&lease_fhdef, &gv.leaseheap, l); + } continue; } - TRACE (("lease expired: l %p guid %x:%x:%x:%x tend %"PA_PRId64" < now %"PA_PRId64"\n", (void *) l, PGUID (g), l->tend.v, tnowE.v)); + nn_log (LC_DISCOVERY, "lease expired: l %p guid "PGUIDFMT" tend %"PA_PRId64" < now %"PA_PRId64"\n", (void *) l, PGUID (g), l->tend.v, tnowE.v); /* If the proxy participant is relying on another participant for writing its discovery data (on the privileged participant, @@ -229,8 +259,8 @@ void check_and_handle_lease_expiration (UNUSED_ARG (struct thread_state1 *self), if ((proxypp = ephash_lookup_proxy_participant_guid (&g)) != NULL && ephash_lookup_proxy_participant_guid (&proxypp->privileged_pp_guid) != NULL) { - TRACE (("but postponing because privileged pp %x:%x:%x:%x is still live\n", - PGUID (proxypp->privileged_pp_guid))); + nn_log (LC_DISCOVERY, "but postponing because privileged pp "PGUIDFMT" is still live\n", + PGUID (proxypp->privileged_pp_guid)); l->tsched = l->tend = add_duration_to_etime (tnowE, 200 * T_MILLISECOND); unlock_lease (l); ut_fibheapInsert (&lease_fhdef, &gv.leaseheap, l); @@ -249,19 +279,19 @@ void check_and_handle_lease_expiration (UNUSED_ARG (struct thread_state1 *self), delete_participant (&g); break; case EK_PROXY_PARTICIPANT: - delete_proxy_participant_by_guid (&g, 1); + delete_proxy_participant_by_guid (&g, tnow, 1); break; case EK_WRITER: delete_writer_nolinger (&g); break; case EK_PROXY_WRITER: - delete_proxy_writer (&g, 1); + delete_proxy_writer (&g, tnow, 1); break; case EK_READER: delete_reader (&g); break; case EK_PROXY_READER: - delete_proxy_reader (&g, 1); + delete_proxy_reader (&g, tnow, 1); break; } @@ -287,7 +317,7 @@ static void debug_print_rawdata (const char *msg, const void *data, size_t len) TRACE ((">")); } -void handle_PMD (UNUSED_ARG (const struct receiver_state *rst), unsigned statusinfo, const void *vdata, unsigned len) +void handle_PMD (UNUSED_ARG (const struct receiver_state *rst), nn_wctime_t timestamp, unsigned statusinfo, const void *vdata, unsigned len) { const struct CDRHeader *data = vdata; /* built-ins not deserialized (yet) */ const int bswap = (data->identifier == CDR_LE) ^ PLATFORM_IS_LITTLE_ENDIAN; @@ -310,7 +340,7 @@ void handle_PMD (UNUSED_ARG (const struct receiver_state *rst), unsigned statusi nn_guid_prefix_t p = nn_ntoh_guid_prefix (pmd->participantGuidPrefix); unsigned kind = ntohl (pmd->kind); unsigned length = bswap ? bswap4u (pmd->length) : pmd->length; - TRACE ((" pp %x:%x:%x kind %u data %d", p.u[0], p.u[1], p.u[2], kind, length)); + TRACE ((" pp "PGIDFMT" kind %u data %d", PGUIDPREFIX(p), kind, length)); if (len - sizeof (struct CDRHeader) - offsetof (ParticipantMessageData_t, value) < length) debug_print_rawdata (" SHORT2", pmd->value, len - sizeof (struct CDRHeader) - offsetof (ParticipantMessageData_t, value)); else @@ -340,7 +370,7 @@ void handle_PMD (UNUSED_ARG (const struct receiver_state *rst), unsigned statusi { ppguid.prefix = nn_ntoh_guid_prefix (*((nn_guid_prefix_t *) (data + 1))); ppguid.entityid.u = NN_ENTITYID_PARTICIPANT; - if (delete_proxy_participant_by_guid (&ppguid, 0) < 0) + if (delete_proxy_participant_by_guid (&ppguid, timestamp, 0) < 0) TRACE ((" unknown")); else TRACE ((" delete")); @@ -349,5 +379,3 @@ void handle_PMD (UNUSED_ARG (const struct receiver_state *rst), unsigned statusi } TRACE (("\n")); } - -/* SHA1 not available (unoffical build.) */ diff --git a/src/services/ddsi2e/core/q_lease.h b/src/services/ddsi2e/core/q_lease.h new file mode 100644 index 000000000..8895e8205 --- /dev/null +++ b/src/services/ddsi2e/core/q_lease.h @@ -0,0 +1,48 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#ifndef Q_LEASE_H +#define Q_LEASE_H + +#include "q_time.h" + +#if defined (__cplusplus) +extern "C" { +#endif + +struct receiver_state; +struct participant; +struct lease; +struct entity_common; +struct thread_state1; + +void lease_management_init (void); +void lease_management_term (void); +struct lease *lease_new (nn_etime_t texpire, os_int64 tdur, struct entity_common *e); +void lease_register (struct lease *l); +void lease_free (struct lease *l); +void lease_renew (struct lease *l, nn_etime_t tnow); +void lease_set_expiry (struct lease *l, nn_etime_t when); +void check_and_handle_lease_expiration (struct thread_state1 *self, nn_etime_t tnow); + +void handle_PMD (const struct receiver_state *rst, nn_wctime_t timestamp, unsigned statusinfo, const void *vdata, unsigned len); + +#if defined (__cplusplus) +} +#endif + +#endif /* Q_LEASE_H */ diff --git a/src/services/ddsi2/code/q_log.c b/src/services/ddsi2e/core/q_log.c similarity index 81% rename from src/services/ddsi2/code/q_log.c rename to src/services/ddsi2e/core/q_log.c index 79d35fc90..3417bcf45 100644 --- a/src/services/ddsi2/code/q_log.c +++ b/src/services/ddsi2e/core/q_log.c @@ -1,18 +1,16 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * @@ -32,9 +30,10 @@ #include "q_time.h" #include "q_log.h" +#define DATE_SIZE (OS_CTIME_R_BUFSIZE) #define MAX_TIMESTAMP_LENGTH (10 + 1 + 6) #define MAX_TID_LENGTH 10 -#define MAX_HDR_LENGTH (MAX_TIMESTAMP_LENGTH + 1 + MAX_TID_LENGTH + + 2) +#define MAX_HDR_LENGTH (DATE_SIZE + 1 + MAX_TIMESTAMP_LENGTH + 1 + MAX_TID_LENGTH + + 2) #define BUF_OFFSET MAX_HDR_LENGTH @@ -44,13 +43,17 @@ static void logbuf_flush_real (struct thread_state1 *self, logbuf_t lb) { const char *tname = self ? self->name : "(anon)"; char hdr[MAX_HDR_LENGTH + 1]; + char date[DATE_SIZE]; int n, tusec; os_int64 tsec; + os_timeW time; if (lb->tstamp.v < 0) lb->tstamp = now (); + OS_TIMEW_SET_VALUE(time, lb->tstamp.v); wctime_to_sec_usec (&tsec, &tusec, lb->tstamp); lb->tstamp.v = -1; - n = snprintf (hdr, sizeof (hdr), "%"PA_PRId64".%06d/%*.*s: ", tsec, tusec, MAX_TID_LENGTH, MAX_TID_LENGTH, tname); + os_ctimeW_r(&time, date, DATE_SIZE); + n = snprintf (hdr, sizeof (hdr), "%s %"PA_PRId64".%06d/%*.*s: ", date, tsec, tusec, MAX_TID_LENGTH, MAX_TID_LENGTH, tname); assert (0 < n && n <= BUF_OFFSET); memcpy (lb->buf + BUF_OFFSET - n, hdr, (size_t) n); fwrite (lb->buf + BUF_OFFSET - n, 1, lb->pos - BUF_OFFSET + (size_t) n, config.tracingOutputFile); @@ -166,6 +169,12 @@ int nn_log (logcat_t cat, const char *fmt, ...) nn_vlogb (self, fmt, ap); va_end (ap); } +#if LITE + if (cat == LC_FATAL) + { + abort (); + } +#endif return 0; } @@ -188,5 +197,3 @@ void nn_log_set_tstamp (nn_wctime_t tnow) if (self && self->lb) self->lb->tstamp = tnow; } - -/* SHA1 not available (unoffical build.) */ diff --git a/src/services/ddsi2e/core/q_log.h b/src/services/ddsi2e/core/q_log.h new file mode 100644 index 000000000..147354932 --- /dev/null +++ b/src/services/ddsi2e/core/q_log.h @@ -0,0 +1,267 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#ifndef NN_LOG_H +#define NN_LOG_H + +#include + +#if !LITE +#include "os_report.h" +#endif +#include "os_defs.h" +#include "q_time.h" + +#if defined (__cplusplus) +extern "C" { +#endif + +#ifdef OSPL_BUILD_DDSI2 +#define OS_API OS_API_EXPORT +#else +#define OS_API OS_API_IMPORT +#endif + +#define LC_FATAL 1u +#define LC_ERROR 2u +#define LC_WARNING 4u +#define LC_CONFIG 8u +#define LC_INFO 16u +#define LC_DISCOVERY 32u +#define LC_DATA 64u +#define LC_TRACE 128u +#define LC_RADMIN 256u +#define LC_TIMING 512u +#define LC_TRAFFIC 1024u +#define LC_TOPIC 2048u +#define LC_TCP 4096u +#define LC_PLIST 8192u +#define LC_WHC 16384u +#define LC_THROTTLE 32768u +#define LC_ALLCATS (LC_FATAL | LC_ERROR | LC_WARNING | LC_CONFIG | LC_INFO | LC_DISCOVERY | LC_DATA | LC_TRACE | LC_TIMING | LC_TRAFFIC | LC_TCP | LC_THROTTLE) + +typedef unsigned logcat_t; + +typedef struct logbuf { + char buf[2048]; + size_t bufsz; + size_t pos; + nn_wctime_t tstamp; +} *logbuf_t; + +logbuf_t logbuf_new (void); +void logbuf_init (logbuf_t lb); +void logbuf_free (logbuf_t lb); + +int nn_vlog (logcat_t cat, const char *fmt, va_list ap); +OS_API int nn_log (logcat_t cat, const char *fmt, ...) __attribute_format__((printf,2,3)); +OS_API int nn_trace (const char *fmt, ...) __attribute_format__((printf,1,2)); +void nn_log_set_tstamp (nn_wctime_t tnow); + +#define TRACE(args) ((config.enabled_logcats & LC_TRACE) ? (nn_trace args) : 0) + +#define LOG_THREAD_CPUTIME(guard) do { \ + if (config.enabled_logcats & LC_TIMING) \ + { \ + nn_mtime_t tnow = now_mt (); \ + if (tnow.v >= (guard).v) \ + { \ + os_int64 ts = get_thread_cputime (); \ + nn_log (LC_TIMING, "thread_cputime %d.%09d\n", \ + (int) (ts / T_SECOND), (int) (ts % T_SECOND)); \ + (guard).v = tnow.v + T_SECOND; \ + } \ + } \ + } while (0) + +#if LITE + +#define NN_WARNING0(fmt) nn_log (LC_WARNING, (" " fmt)) +#define NN_WARNING1(fmt,a) nn_log (LC_WARNING, (" " fmt),a) +#define NN_WARNING2(fmt,a,b) nn_log (LC_WARNING, (" " fmt),a,b) +#define NN_WARNING3(fmt,a,b,c) nn_log (LC_WARNING, (" " fmt),a,b,c) +#define NN_WARNING4(fmt,a,b,c,d) nn_log (LC_WARNING, (" " fmt),a,b,c,d) +#define NN_WARNING5(fmt,a,b,c,d,e) nn_log (LC_WARNING, (" " fmt),a,b,c,d,e) +#define NN_WARNING6(fmt,a,b,c,d,e,f) nn_log (LC_WARNING, (" " fmt),a,b,c,d,e,f) +#define NN_WARNING7(fmt,a,b,c,d,e,f,g) nn_log (LC_WARNING, (" " fmt),a,b,c,d,e,f,g) + +#define NN_ERROR0(fmt) nn_log (LC_ERROR, (" " fmt)) +#define NN_ERROR1(fmt,a) nn_log (LC_ERROR, (" " fmt),a) +#define NN_ERROR2(fmt,a,b) nn_log (LC_ERROR, (" " fmt),a,b) +#define NN_ERROR3(fmt,a,b,c) nn_log (LC_ERROR, (" " fmt),a,b,c) +#define NN_ERROR4(fmt,a,b,c,d) nn_log (LC_ERROR, (" " fmt),a,b,c,d) + +#define NN_FATAL0(fmt) nn_log (LC_FATAL, (" " fmt)) +#define NN_FATAL1(fmt,a) nn_log (LC_FATAL, (" " fmt),a) +#define NN_FATAL2(fmt,a,b) nn_log (LC_FATAL, (" " fmt),a,b) +#define NN_FATAL3(fmt,a,b,c) nn_log (LC_FATAL, (" " fmt),a,b,c) +#define NN_FATAL4(fmt,a,b,c,d) nn_log (LC_FATAL, (" " fmt),a,b,c,d) + +#else + +#define NN_WARNING0(fmt) do { \ + nn_log (LC_WARNING, (fmt)); \ + os_report (OS_WARNING, config.servicename, __FILE__, __LINE__, 0, -1, OS_TRUE, (fmt)); \ + } while (0) +#define NN_WARNING1(fmt,a) do { \ + nn_log (LC_WARNING, (fmt), a); \ + os_report (OS_WARNING, config.servicename, __FILE__, __LINE__, 0, -1, OS_TRUE, (fmt), a); \ + } while (0) +#define NN_WARNING2(fmt,a,b) do { \ + nn_log (LC_WARNING, (fmt), a, b); \ + os_report (OS_WARNING, config.servicename, __FILE__, __LINE__, 0, -1, OS_TRUE, (fmt), a, b); \ + } while (0) +#define NN_WARNING3(fmt,a,b,c) do { \ + nn_log (LC_WARNING, (fmt), a, b, c); \ + os_report (OS_WARNING, config.servicename, __FILE__, __LINE__, 0, -1, OS_TRUE, (fmt), a, b, c); \ + } while (0) +#define NN_WARNING4(fmt,a,b,c,d) do { \ + nn_log (LC_WARNING, (fmt), a, b, c, d); \ + os_report (OS_WARNING, config.servicename, __FILE__, __LINE__, 0, -1, OS_TRUE, (fmt), a, b, c, d); \ + } while (0) +#define NN_WARNING5(fmt,a,b,c,d,e) do { \ + nn_log (LC_WARNING, (fmt), a, b, c, d, e); \ + os_report (OS_WARNING, config.servicename, __FILE__, __LINE__, 0, -1, OS_TRUE, (fmt), a, b, c, d, e); \ + } while (0) +#define NN_WARNING6(fmt,a,b,c,d,e,f) do { \ + nn_log (LC_WARNING, (fmt), a, b, c, d, e, f); \ + os_report (OS_WARNING, config.servicename, __FILE__, __LINE__, 0, -1, OS_TRUE, (fmt), a, b, c, d, e, f); \ + } while (0) +#define NN_WARNING7(fmt,a,b,c,d,e,f,g) do { \ + nn_log (LC_WARNING, (fmt), a, b, c, d, e, f, g); \ + os_report (OS_WARNING, config.servicename, __FILE__, __LINE__, 0, -1, OS_TRUE, (fmt), a, b, c, d, e, f, g); \ + } while (0) +#define NN_WARNING8(fmt,a,b,c,d,e,f,g,h) do { \ + nn_log (LC_WARNING, (fmt), a, b, c, d, e, f, g, h); \ + os_report (OS_WARNING, config.servicename, __FILE__, __LINE__, 0, -1, OS_TRUE, (fmt), a, b, c, d, e, f, g, h); \ + } while (0) +#define NN_WARNING9(fmt,a,b,c,d,e,f,g,h,i) do { \ + nn_log (LC_WARNING, (fmt), a, b, c, d, e, f, g, h, i); \ + os_report (OS_WARNING, config.servicename, __FILE__, __LINE__, 0, -1, OS_TRUE, (fmt), a, b, c, d, e, f, g, h, i); \ + } while (0) +#define NN_WARNING10(fmt,a,b,c,d,e,f,g,h,i,j) do { \ + nn_log (LC_WARNING, (fmt), a, b, c, d, e, f, g, h, i, j); \ + os_report (OS_WARNING, config.servicename, __FILE__, __LINE__, 0, -1, OS_TRUE, (fmt), a, b, c, d, e, f, g, h, i, j); \ + } while (0) + +#define NN_ERROR0(fmt) do { \ + nn_log (LC_ERROR, (fmt)); \ + os_report (OS_ERROR, config.servicename, __FILE__, __LINE__, 0, -1, OS_TRUE, (fmt)); \ + } while (0) +#define NN_ERROR1(fmt,a) do { \ + nn_log (LC_ERROR, (fmt), a); \ + os_report (OS_ERROR, config.servicename, __FILE__, __LINE__, 0, -1, OS_TRUE, (fmt), a); \ + } while (0) +#define NN_ERROR2(fmt,a,b) do { \ + nn_log (LC_ERROR, (fmt), a, b); \ + os_report (OS_ERROR, config.servicename, __FILE__, __LINE__, 0, -1, OS_TRUE, (fmt), a, b); \ + } while (0) +#define NN_ERROR3(fmt,a,b,c) do { \ + nn_log (LC_ERROR, (fmt), a, b, c); \ + os_report (OS_ERROR, config.servicename, __FILE__, __LINE__, 0, -1, OS_TRUE, (fmt), a, b, c); \ + } while (0) +#define NN_ERROR4(fmt,a,b,c,d) do { \ + nn_log (LC_ERROR, (fmt), a, b, c, d); \ + os_report (OS_ERROR, config.servicename, __FILE__, __LINE__, 0, -1, OS_TRUE, (fmt), a, b, c, d); \ + } while (0) +#define NN_ERROR5(fmt,a,b,c,d,e) do { \ + nn_log (LC_ERROR, (fmt), a, b, c, d, e); \ + os_report (OS_ERROR, config.servicename, __FILE__, __LINE__, 0, -1, OS_TRUE, (fmt), a, b, c, d, e); \ + } while (0) +#define NN_ERROR6(fmt,a,b,c,d,e,f) do { \ + nn_log (LC_ERROR, (fmt), a, b, c, d, e, f); \ + os_report (OS_ERROR, config.servicename, __FILE__, __LINE__, 0, -1, OS_TRUE, (fmt), a, b, c, d, e, f); \ + } while (0) +#define NN_ERROR7(fmt,a,b,c,d,e,f,g) do { \ + nn_log (LC_ERROR, (fmt), a, b, c, d, e, f, g); \ + os_report (OS_ERROR, config.servicename, __FILE__, __LINE__, 0, -1, OS_TRUE, (fmt), a, b, c, d, e, f, g); \ + } while (0) +#define NN_ERROR8(fmt,a,b,c,d,e,f,g,h) do { \ + nn_log (LC_ERROR, (fmt), a, b, c, d, e, f, g, h); \ + os_report (OS_ERROR, config.servicename, __FILE__, __LINE__, 0, -1, OS_TRUE, (fmt), a, b, c, d, e, f, g, h); \ + } while (0) +#define NN_ERROR9(fmt,a,b,c,d,e,f,g,h,i) do { \ + nn_log (LC_ERROR, (fmt), a, b, c, d, e, f, g, h, i); \ + os_report (OS_ERROR, config.servicename, __FILE__, __LINE__, 0, -1, OS_TRUE, (fmt), a, b, c, d, e, f, g, h, i); \ + } while (0) +#define NN_ERROR10(fmt,a,b,c,d,e,f,g,h,i,j) do { \ + nn_log (LC_ERROR, (fmt), a, b, c, d, e, f, g, h, i, j); \ + os_report (OS_ERROR, config.servicename, __FILE__, __LINE__, 0, -1, OS_TRUE, (fmt), a, b, c, d, e, f, g, h, i, j); \ + } while (0) + +#define NN_FATAL0(fmt) do { \ + nn_log (LC_FATAL, (fmt)); \ + os_report (OS_FATAL, config.servicename, __FILE__, __LINE__, 0, -1, OS_TRUE, (fmt)); \ + abort (); \ + } while (0) +#define NN_FATAL1(fmt,a) do { \ + nn_log (LC_FATAL, (fmt), a); \ + os_report (OS_FATAL, config.servicename, __FILE__, __LINE__, 0, -1, OS_TRUE, (fmt), a); \ + abort (); \ + } while (0) +#define NN_FATAL2(fmt,a,b) do { \ + nn_log (LC_FATAL, (fmt), a, b); \ + os_report (OS_FATAL, config.servicename, __FILE__, __LINE__, 0, -1, OS_TRUE, (fmt), a, b); \ + abort (); \ + } while (0) +#define NN_FATAL3(fmt,a,b,c) do { \ + nn_log (LC_FATAL, (fmt), a, b, c); \ + os_report (OS_FATAL, config.servicename, __FILE__, __LINE__, 0, -1, OS_TRUE, (fmt), a, b, c); \ + abort (); \ + } while (0) +#define NN_FATAL4(fmt,a,b,c,d) do { \ + nn_log (LC_FATAL, (fmt), a, b, c, d); \ + os_report (OS_FATAL, config.servicename, __FILE__, __LINE__, 0, -1, OS_TRUE, (fmt), a, b, c, d); \ + abort (); \ + } while (0) +#define NN_FATAL5(fmt,a,b,c,d,e) do { \ + nn_log (LC_FATAL, (fmt), a, b, c, d, e); \ + os_report (OS_FATAL, config.servicename, __FILE__, __LINE__, 0, -1, OS_TRUE, (fmt), a, b, c, d, e); \ + abort (); \ + } while (0) +#define NN_FATAL6(fmt,a,b,c,d,e,f) do { \ + nn_log (LC_FATAL, (fmt), a, b, c, d, e, f); \ + os_report (OS_FATAL, config.servicename, __FILE__, __LINE__, 0, -1, OS_TRUE, (fmt), a, b, c, d, e, f); \ + abort (); \ + } while (0) +#define NN_FATAL7(fmt,a,b,c,d,e,f,g) do { \ + nn_log (LC_FATAL, (fmt), a, b, c, d, e, f, g); \ + os_report (OS_FATAL, config.servicename, __FILE__, __LINE__, 0, -1, OS_TRUE, (fmt), a, b, c, d, e, f, g); \ + abort (); \ + } while (0) +#define NN_FATAL8(fmt,a,b,c,d,e,f,g,h) do { \ + nn_log (LC_FATAL, (fmt), a, b, c, d, e, f, g, h); \ + os_report (OS_FATAL, config.servicename, __FILE__, __LINE__, 0, -1, OS_TRUE, (fmt), a, b, c, d, e, f, g, h); \ + abort (); \ + } while (0) +#define NN_FATAL9(fmt,a,b,c,d,e,f,g,h,i) do { \ + nn_log (LC_FATAL, (fmt), a, b, c, d, e, f, g, h, i); \ + os_report (OS_FATAL, config.servicename, __FILE__, __LINE__, 0, -1, OS_TRUE, (fmt), a, b, c, d, e, f, g, h, i); \ + abort (); \ + } while (0) +#define NN_FATAL10(fmt,a,b,c,d,e,f,g,h,i,j) do { \ + nn_log (LC_FATAL, (fmt), a, b, c, d, e, f, g, h, i, j); \ + os_report (OS_FATAL, config.servicename, __FILE__, __LINE__, 0, -1, OS_TRUE, (fmt), a, b, c, d, e, f, g, h, i, j); \ + abort (); \ + } while (0) +#endif +#undef OS_API +#if defined (__cplusplus) +} +#endif + +#endif /* NN_LOG_H */ diff --git a/src/services/ddsi2/code/q_md5.c b/src/services/ddsi2e/core/q_md5.c similarity index 95% rename from src/services/ddsi2/code/q_md5.c rename to src/services/ddsi2e/core/q_md5.c index 0bd21a6c2..83c090ea7 100644 --- a/src/services/ddsi2/code/q_md5.c +++ b/src/services/ddsi2e/core/q_md5.c @@ -1,19 +1,17 @@ -/* Minimal changes introduced, for which: - * - * OpenSplice DDS - * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. +/* Minimal changes introduced, for which: */ +/* + * Vortex OpenSplice * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * @@ -403,5 +401,3 @@ md5_finish(md5_state_t *pms, md5_byte_t digest[16]) for (i = 0; i < 16; ++i) digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3)); } - -/* SHA1 not available (unoffical build.) */ diff --git a/src/services/ddsi2/code/q_md5.h b/src/services/ddsi2e/core/q_md5.h similarity index 85% rename from src/services/ddsi2/code/q_md5.h rename to src/services/ddsi2e/core/q_md5.h index c7a11b309..36438ac01 100644 --- a/src/services/ddsi2/code/q_md5.h +++ b/src/services/ddsi2e/core/q_md5.h @@ -1,19 +1,17 @@ /* Minimal changes introduced, for which: * - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * @@ -111,5 +109,3 @@ void md5_finish(md5_state_t *pms, md5_byte_t digest[16]); #endif #endif /* md5_INCLUDED */ - -/* SHA1 not available (unoffical build.) */ diff --git a/src/services/ddsi2e/core/q_misc.c b/src/services/ddsi2e/core/q_misc.c new file mode 100644 index 000000000..cf41f86d7 --- /dev/null +++ b/src/services/ddsi2e/core/q_misc.c @@ -0,0 +1,295 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#include + +#if ! LITE +#include "kernelModule.h" +#endif +#include "q_misc.h" +#include "q_bswap.h" +#include "q_md5.h" + +int vendor_is_rti (nn_vendorid_t vendor) +{ + const nn_vendorid_t rti = NN_VENDORID_RTI; + return vendor.id[0] == rti.id[0] && vendor.id[1] == rti.id[1]; +} + +int vendor_is_twinoaks (nn_vendorid_t vendor) +{ + const nn_vendorid_t twinoaks = NN_VENDORID_TWINOAKS; + return vendor.id[0] == twinoaks.id[0] && vendor.id[1] == twinoaks.id[1]; +} + +int vendor_is_cloud (nn_vendorid_t vendor) +{ + const nn_vendorid_t cloud = NN_VENDORID_PRISMTECH_CLOUD; + return vendor.id[0] == cloud.id[0] && vendor.id[1] == cloud.id[1]; +} + +int vendor_is_prismtech (nn_vendorid_t vid) +{ + const nn_vendorid_t pt1 = NN_VENDORID_PRISMTECH_OSPL; + const nn_vendorid_t pt2 = NN_VENDORID_PRISMTECH_LITE; + const nn_vendorid_t pt3 = NN_VENDORID_PRISMTECH_GATEWAY; + const nn_vendorid_t pt4 = NN_VENDORID_PRISMTECH_JAVA; + const nn_vendorid_t pt5 = NN_VENDORID_PRISMTECH_CLOUD; + + return + (vid.id[0] == pt1.id[0]) && + ((vid.id[1] == pt1.id[1]) || (vid.id[1] == pt2.id[1]) + || (vid.id[1] == pt3.id[1]) || (vid.id[1] == pt4.id[1]) + || (vid.id[1] == pt5.id[1])); +} + +int vendor_is_opensplice (nn_vendorid_t vid) +{ + const nn_vendorid_t pt1 = NN_VENDORID_PRISMTECH_OSPL; + return (vid.id[0] == pt1.id[0] && vid.id[1] == pt1.id[1]); +} + +int vendor_is_lite (nn_vendorid_t vid) +{ + const nn_vendorid_t pt1 = NN_VENDORID_PRISMTECH_LITE; + return (vid.id[0] == pt1.id[0] && vid.id[1] == pt1.id[1]); +} + +int is_own_vendor (nn_vendorid_t vendor) +{ + const nn_vendorid_t ownid = MY_VENDOR_ID; + return vendor.id[0] == ownid.id[0] && vendor.id[1] == ownid.id[1]; +} + +#if ! LITE +int gid_is_fake (const struct v_gid_s *gid) +{ + /* 0:0:0 is not so much fake as invalid, but here they both mean we + pretend there is no gid. For the localId mask, see v_handle.c -- + this is very much an undocumented characteristic of GIDs ... */ + if (gid->systemId == 0 && gid->localId == 0 && gid->serial == 0) + return 1; + else if (gid->localId & 0xffc00000) + return 1; + else + return 0; +} +#endif + +os_int64 fromSN (const nn_sequence_number_t sn) +{ + return ((os_int64) sn.high << 32) | sn.low; +} + +nn_sequence_number_t toSN (os_int64 n) +{ + nn_sequence_number_t x; + x.high = (int) (n >> 32); + x.low = (unsigned) n; + return x; +} + +#ifdef DDSI_INCLUDE_NETWORK_PARTITIONS +int WildcardOverlap(char * p1, char * p2) +{ + /* both patterns are empty or contain wildcards => overlap */ + if ((p1 == NULL || strcmp(p1,"") == 0 || strcmp(p1,"*") == 0) && + (p2 == NULL || strcmp(p2,"") == 0 || strcmp(p2,"*") == 0)) + return 1; + + /* Either pattern is empty (but the other is not empty or wildcard only) => no overlap */ + if (p1 == NULL || strcmp(p1,"") == 0 || p2 == NULL || strcmp(p2,"")==0) + return 0; + + if ( (p1[0] == '*' || p2[0] == '*') && (WildcardOverlap(p1,p2+1)|| WildcardOverlap(p1+1,p2))) + return 1; + + if ( (p1[0] == '?' || p2[0] == '?' || p1[0] == p2[0] ) && WildcardOverlap(p1+1,p2+1)) + return 1; + + /* else, no match, return false */ + return 0; +} +#endif + +#if ! LITE +int ddsi2_patmatch (const char *pat, const char *str) +{ + c_value p, n, r; + p.kind = n.kind = V_STRING; + p.is.String = (char *) pat; + n.is.String = (char *) str; + r = c_valueStringMatch (p, n); + return r.is.Boolean; +} +#else +int ddsi2_patmatch (const char *pat, const char *str) +{ + while (*pat) + { + if (*pat == '?') + { + /* any character will do */ + if (*str++ == 0) + { + return 0; + } + pat++; + } + else if (*pat == '*') + { + /* collapse a sequence of wildcards, requiring as many + characters in str as there are ?s in the sequence */ + while (*pat == '*' || *pat == '?') + { + if (*pat == '?' && *str++ == 0) + { + return 0; + } + pat++; + } + /* try matching on all positions where str matches pat */ + while (*str) + { + if (*str == *pat && ddsi2_patmatch (pat+1, str+1)) + { + return 1; + } + str++; + } + return *pat == 0; + } + else + { + /* only an exact match */ + if (*str++ != *pat++) + { + return 0; + } + } + } + return *str == 0; +} +#endif + +#if ! LITE +void nn_guid_to_ospl_gid (v_gid *gid, const nn_guid_t *guid, int guid_has_systemid) +{ + /* Try hard to fake a writer id for OpenSplice based on a GUID. All + systems I know of have something resembling a host/system id in + the first 32 bits, so copy that as the system id and copy half of + an MD5 hash into the remaining 64 bits. Now if only OpenSplice + would use all 96 bits as a key, we'd be doing reasonably well ... */ + const nn_guid_t nguid = nn_hton_guid (*guid); + union { os_uint32 u[4]; unsigned char md5[16]; } hp, hg; + md5_state_t md5st; + + if (guid_has_systemid) + { + /* for old OpenSplice versions: modern durability relies on the systemId for + liveliness of its fellows, so we must not modify it */ + gid->systemId = guid->prefix.u[0]; + } + else + { + md5_init (&md5st); + md5_append (&md5st, (unsigned char *) &nguid.prefix, sizeof (nguid.prefix)); + md5_finish (&md5st, hp.md5); + gid->systemId = fromBE4u (hp.u[0]); + } + + md5_init (&md5st); + md5_append (&md5st, (unsigned char *) &nguid, sizeof (nguid)); + md5_finish (&md5st, hg.md5); + + /* See also gid_is_fake for the masking of bits in localId */ + gid->localId = fromBE4u (hg.u[0]) & 0x3fffff; + gid->serial = guid->entityid.u; +} + +int version_info_is_6_4_1 (const char *internals) +{ + /* node/version/...; unfortunately, the version is quoted on some platforms */ + const char *p; + if (internals == NULL || (p = strchr (internals, '/')) == NULL) + return 0; + return (strncmp (p + 1, "V6.4.1/", 7) == 0 || strncmp (p + 1, "\"V6.4.1\"/", 9) == 0); +} +#endif + +#if LITE +static const os_uint32 crc32_table[] = { + 0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b, + 0x1a864db2, 0x1e475005, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61, + 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd, 0x4c11db70, 0x48d0c6c7, + 0x4593e01e, 0x4152fda9, 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75, + 0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3, + 0x709f7b7a, 0x745e66cd, 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039, + 0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 0xbe2b5b58, 0xbaea46ef, + 0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d, + 0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49, 0xc7361b4c, 0xc3f706fb, + 0xceb42022, 0xca753d95, 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1, + 0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, 0x34867077, 0x30476dc0, + 0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072, + 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16, 0x018aeb13, 0x054bf6a4, + 0x0808d07d, 0x0cc9cdca, 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde, + 0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02, 0x5e9f46bf, 0x5a5e5b08, + 0x571d7dd1, 0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba, + 0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b, 0xbb60adfc, + 0xb6238b25, 0xb2e29692, 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6, + 0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a, 0xe0b41de7, 0xe4750050, + 0xe9362689, 0xedf73b3e, 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2, + 0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34, + 0xdc3abded, 0xd8fba05a, 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637, + 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb, 0x4f040d56, 0x4bc510e1, + 0x46863638, 0x42472b8f, 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53, + 0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5, + 0x3f9b762c, 0x3b5a6b9b, 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff, + 0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, 0xf12f560e, 0xf5ee4bb9, + 0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b, + 0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f, 0xc423cd6a, 0xc0e2d0dd, + 0xcda1f604, 0xc960ebb3, 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7, + 0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, 0x9b3660c6, 0x9ff77d71, + 0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3, + 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640, 0x4e8ee645, 0x4a4ffbf2, + 0x470cdd2b, 0x43cdc09c, 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8, + 0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24, 0x119b4be9, 0x155a565e, + 0x18197087, 0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec, + 0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d, 0x2056cd3a, + 0x2d15ebe3, 0x29d4f654, 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0, + 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c, 0xe3a1cbc1, 0xe760d676, + 0xea23f0af, 0xeee2ed18, 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4, + 0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662, + 0x933eb0bb, 0x97ffad0c, 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668, + 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4 +}; + +os_uint32 crc32_calc (const void *buf, os_uint32 length) +{ + const uint8_t *vptr = buf; + os_uint32 i, reg = 0; + uint8_t top; + for (i = 0; i < length; i++) + { + top = (uint8_t) (reg >> 24); + top ^= *vptr; + reg = (reg << 8) ^ crc32_table[top]; + vptr++; + } + return reg; +} +#endif diff --git a/src/services/ddsi2e/core/q_misc.h b/src/services/ddsi2e/core/q_misc.h new file mode 100644 index 000000000..74d4f2037 --- /dev/null +++ b/src/services/ddsi2e/core/q_misc.h @@ -0,0 +1,64 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#ifndef NN_MISC_H +#define NN_MISC_H + +#include "q_protocol.h" + +#if defined (__cplusplus) +extern "C" { +#endif + +struct v_gid_s; +struct nn_guid; + +int vendor_is_lite (nn_vendorid_t vendor); +int vendor_is_opensplice (nn_vendorid_t vid); +int vendor_is_rti (nn_vendorid_t vendor); +int vendor_is_twinoaks (nn_vendorid_t vendor); +int vendor_is_prismtech (nn_vendorid_t vendor); +int vendor_is_cloud (nn_vendorid_t vendor); +int is_own_vendor (nn_vendorid_t vendor); +unsigned char normalize_data_datafrag_flags (const SubmessageHeader_t *smhdr, int datafrag_as_data); +#if !LITE +int version_info_is_6_4_1 (const char *internals); +#endif + +os_int64 fromSN (const nn_sequence_number_t sn); +nn_sequence_number_t toSN (os_int64); + +#ifdef DDSI_INCLUDE_NETWORK_PARTITIONS +int WildcardOverlap(char * p1, char * p2); +#endif + +int ddsi2_patmatch (const char *pat, const char *str); + +#if !LITE +void nn_guid_to_ospl_gid (struct v_gid_s *gid, const struct nn_guid *guid, int guid_has_systemid); +int gid_is_fake (const struct v_gid_s *gid); +#endif + +#if LITE +os_uint32 crc32_calc (const void *buf, os_uint32 length); +#endif + +#if defined (__cplusplus) +} +#endif + +#endif /* NN_MISC_H */ diff --git a/src/services/ddsi2/code/q_nwif.c b/src/services/ddsi2e/core/q_nwif.c similarity index 91% rename from src/services/ddsi2/code/q_nwif.c rename to src/services/ddsi2e/core/q_nwif.c index 6e14e1764..93f74e6f4 100644 --- a/src/services/ddsi2/code/q_nwif.c +++ b/src/services/ddsi2e/core/q_nwif.c @@ -1,18 +1,16 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * @@ -334,6 +332,32 @@ char *locator_to_string_no_port (char addrbuf[INET6_ADDRSTRLEN_EXTENDED], const return sockaddr_to_string_no_port (addrbuf, &addr); } +#if LITE +unsigned sockaddr_to_hopefully_unique_uint32 (const os_sockaddr_storage *src) +{ + switch (src->ss_family) + { + case AF_INET: + return (unsigned) ((const os_sockaddr_in *) src)->sin_addr.s_addr; +#if OS_SOCKET_HAS_IPV6 + case AF_INET6: + { + unsigned id; + md5_state_t st; + md5_byte_t digest[16]; + md5_init (&st); + md5_append (&st, (const md5_byte_t *) ((const os_sockaddr_in6 *) src)->sin6_addr.s6_addr, 16); + md5_finish (&st, digest); + memcpy (&id, digest, sizeof (id)); + return id; + } +#endif + default: + NN_FATAL0 ("sockaddr_to_hopefully_unique_uint32: unknown address family\n"); + return 0; + } +} +#endif unsigned short get_socket_port (os_socket socket) { @@ -358,6 +382,15 @@ unsigned short get_socket_port (os_socket socket) } } +#ifdef DDSI_INCLUDE_NETWORK_CHANNELS +void set_socket_diffserv (os_socket sock, int diffserv) +{ + if (os_sockSetsockopt (sock, IPPROTO_IP, IP_TOS, (char*) &diffserv, sizeof (diffserv)) != os_resultSuccess) + { + print_sockerror ("IP_TOS"); + } +} +#endif #ifdef SO_NOSIGPIPE static void set_socket_nosigpipe (os_socket sock) @@ -647,13 +680,50 @@ static int joinleave_asm_mcgroup (os_socket socket, int join, const os_sockaddr_ return (rc == -1) ? os_getErrno() : 0; } +#ifdef DDSI_INCLUDE_SSM +static int joinleave_ssm_mcgroup (os_socket socket, int join, const os_sockaddr_storage *srcip, const os_sockaddr_storage *mcip, const struct nn_interface *interf) +{ + int rc; +#if OS_SOCKET_HAS_IPV6 + if (config.useIpv6) + { + struct group_source_req gsr; + memset (&gsr, 0, sizeof (gsr)); + gsr.gsr_interface = interf ? interf->if_index : 0; + memcpy (&gsr.gsr_group, mcip, sizeof (gsr.gsr_group)); + memcpy (&gsr.gsr_source, srcip, sizeof (gsr.gsr_source)); + rc = os_sockSetsockopt (socket, IPPROTO_IPV6, join ? MCAST_JOIN_SOURCE_GROUP : MCAST_LEAVE_SOURCE_GROUP, &gsr, sizeof (gsr)); + } + else +#endif + { + struct ip_mreq_source mreq; + memset (&mreq, 0, sizeof (mreq)); + mreq.imr_sourceaddr = ((os_sockaddr_in *) srcip)->sin_addr; + mreq.imr_multiaddr = ((os_sockaddr_in *) mcip)->sin_addr; + if (interf) + mreq.imr_interface = ((os_sockaddr_in *) &interf->addr)->sin_addr; + else + mreq.imr_interface.s_addr = INADDR_ANY; + rc = os_sockSetsockopt (socket, IPPROTO_IP, join ? IP_ADD_SOURCE_MEMBERSHIP : IP_DROP_SOURCE_MEMBERSHIP, &mreq, sizeof (mreq)); + } + return (rc == -1) ? os_getErrno() : 0; +} +#endif static char *make_joinleave_msg (char *buf, size_t bufsz, os_socket socket, int join, const os_sockaddr_storage *srcip, const os_sockaddr_storage *mcip, const struct nn_interface *interf, int err) { char mcstr[INET6_ADDRSTRLEN_EXTENDED], srcstr[INET6_ADDRSTRLEN_EXTENDED], interfstr[INET6_ADDRSTRLEN_EXTENDED]; int n; +#ifdef DDSI_INCLUDE_SSM + if (srcip) + sockaddr_to_string_no_port(srcstr, srcip); + else + strcpy (srcstr, "*"); +#else OS_UNUSED_ARG (srcip); strcpy (srcstr, "*"); +#endif sockaddr_to_string_no_port (mcstr, mcip); if (interf) sockaddr_to_string_no_port(interfstr, &interf->addr); @@ -670,8 +740,15 @@ static int joinleave_mcgroup (os_socket socket, int join, const os_sockaddr_stor char buf[256]; int err; TRACE (("%s\n", make_joinleave_msg (buf, sizeof(buf), socket, join, srcip, mcip, interf, 0))); +#ifdef DDSI_INCLUDE_SSM + if (srcip) + err = joinleave_ssm_mcgroup(socket, join, srcip, mcip, interf); + else + err = joinleave_asm_mcgroup(socket, join, mcip, interf); +#else assert (srcip == NULL); err = joinleave_asm_mcgroup(socket, join, mcip, interf); +#endif if (err) NN_WARNING1 ("%s\n", make_joinleave_msg (buf, sizeof(buf), socket, join, srcip, mcip, interf, err)); return err ? -1 : 0; @@ -1072,5 +1149,3 @@ int find_own_ip (const char *requested_address) return 1; } } - -/* SHA1 not available (unoffical build.) */ diff --git a/src/services/ddsi2/code/q_nwif.h b/src/services/ddsi2e/core/q_nwif.h similarity index 76% rename from src/services/ddsi2/code/q_nwif.h rename to src/services/ddsi2e/core/q_nwif.h index fdde3e472..eda8ff460 100644 --- a/src/services/ddsi2/code/q_nwif.h +++ b/src/services/ddsi2e/core/q_nwif.h @@ -1,18 +1,16 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * @@ -58,12 +56,16 @@ int join_mcgroups (struct nn_group_membership *mship, os_socket socket, const os int leave_mcgroups (struct nn_group_membership *mship, os_socket socket, const os_sockaddr_storage *srcip, const os_sockaddr_storage *mcip); void sockaddr_set_port (os_sockaddr_storage *addr, unsigned short port); unsigned short sockaddr_get_port (const os_sockaddr_storage *addr); +#if LITE +unsigned sockaddr_to_hopefully_unique_uint32 (const os_sockaddr_storage *src); +#endif #if defined (__cplusplus) } #endif +#ifdef DDSI_INCLUDE_NETWORK_CHANNELS +void set_socket_diffserv (os_socket sock, int diffserv); +#endif #endif /* Q_NWIF_H */ - -/* SHA1 not available (unoffical build.) */ diff --git a/src/services/ddsi2/code/q_pcap.c b/src/services/ddsi2e/core/q_pcap.c similarity index 90% rename from src/services/ddsi2/code/q_pcap.c rename to src/services/ddsi2e/core/q_pcap.c index 9d8c7b40e..7fb683254 100644 --- a/src/services/ddsi2/code/q_pcap.c +++ b/src/services/ddsi2e/core/q_pcap.c @@ -1,18 +1,16 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * @@ -215,5 +213,3 @@ void write_pcap_sent os_mutexUnlock (&gv.pcap_lock); } } - -/* SHA1 not available (unoffical build.) */ diff --git a/src/services/ddsi2e/core/q_pcap.h b/src/services/ddsi2e/core/q_pcap.h new file mode 100644 index 000000000..f018c5c79 --- /dev/null +++ b/src/services/ddsi2e/core/q_pcap.h @@ -0,0 +1,55 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#ifndef Q_PCAP_H +#define Q_PCAP_H + +#include +#include "q_time.h" + +#if defined (__cplusplus) +extern "C" { +#endif + +struct msghdr; + +FILE * new_pcap_file (const char *name); + +void write_pcap_received +( + FILE * fp, + nn_wctime_t tstamp, + const os_sockaddr_storage * src, + const os_sockaddr_storage * dst, + unsigned char * buf, + os_size_t sz +); + +void write_pcap_sent +( + FILE * fp, + nn_wctime_t tstamp, + const os_sockaddr_storage * src, + const struct msghdr * hdr, + os_size_t sz +); + +#if defined (__cplusplus) +} +#endif + +#endif /* Q_PCAP_H */ diff --git a/src/services/ddsi2/code/q_plist.c b/src/services/ddsi2e/core/q_plist.c similarity index 97% rename from src/services/ddsi2/code/q_plist.c rename to src/services/ddsi2e/core/q_plist.c index 106aa3a3c..dfbc5592b 100644 --- a/src/services/ddsi2/code/q_plist.c +++ b/src/services/ddsi2e/core/q_plist.c @@ -1,18 +1,16 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * @@ -39,6 +37,7 @@ #include "q_config.h" #include "q_protocol.h" /* for NN_STATUSINFO_... */ #include "q_radmin.h" /* for nn_plist_quickscan */ +#include "q_static_assert.h" #include "ut_avl.h" #include "q_misc.h" /* for vendor_is_... */ @@ -1334,7 +1333,7 @@ static int do_guid (nn_guid_t *dst, os_uint64 *present, os_uint64 fl, int (*vali if (fl == PP_PARTICIPANT_GUID && vendor_is_twinoaks (dd->vendorid) && dst->entityid.u == 0 && ! NN_STRICT_P) { - NN_WARNING6 ("plist(vendor %d.%d): rewriting invalid participant guid %x:%x:%x:%x\n", + NN_WARNING6 ("plist(vendor %d.%d): rewriting invalid participant guid "PGUIDFMT"\n", dd->vendorid.id[0], dd->vendorid.id[1], dst->prefix.u[0], dst->prefix.u[1], dst->prefix.u[2], dst->entityid.u); dst->entityid.u = NN_ENTITYID_PARTICIPANT; @@ -1348,6 +1347,7 @@ static int do_guid (nn_guid_t *dst, os_uint64 *present, os_uint64 fl, int (*vali return 0; } +#if !LITE static void bswap_prismtech_writer_info (nn_prismtech_writer_info_t *wri) { wri->transactionId = bswap4u (wri->transactionId); @@ -1359,6 +1359,7 @@ static void bswap_prismtech_writer_info (nn_prismtech_writer_info_t *wri) wri->writerInstanceGID.serial = bswap4u (wri->writerInstanceGID.serial); wri->sequenceNumber = bswap4u (wri->sequenceNumber); } +#endif static void bswap_prismtech_participant_version_info (nn_prismtech_participant_version_info_t *pvi) { @@ -1402,6 +1403,7 @@ static int do_prismtech_participant_version_info (nn_prismtech_participant_versi } } +#if !LITE static int do_share_qospolicy (nn_share_qospolicy_t *q, os_uint64 *present, os_uint64 *aliased, os_uint64 fl, const struct dd *dd) { struct dd dd1; @@ -1428,11 +1430,14 @@ static int do_share_qospolicy (nn_share_qospolicy_t *q, os_uint64 *present, os_u } return res; } +#endif +#if !LITE static void unalias_share_qospolicy (nn_share_qospolicy_t *q, int bswap) { unalias_string (&q->name, bswap); } +#endif static int do_subscription_keys_qospolicy (nn_subscription_keys_qospolicy_t *q, os_uint64 *present, os_uint64 *aliased, os_uint64 fl, const struct dd *dd) { @@ -1963,15 +1968,25 @@ static int init_one_parameter } memcpy (&dest->statusinfo, dd->buf, sizeof (dest->statusinfo)); dest->statusinfo = fromBE4u (dest->statusinfo); - if (NN_STRICT_P && !protocol_version_is_newer (dd->protocol_version) && - (dest->statusinfo & ~(NN_STATUSINFO_DISPOSE | NN_STATUSINFO_UNREGISTER))) + if (NN_STRICT_P && !protocol_version_is_newer (dd->protocol_version) && (dest->statusinfo & ~NN_STATUSINFO_STANDARDIZED)) { /* Spec says I may not interpret the reserved bits. But no-one - may use them in this version of the specification */ + may use them in this version of the specification */ TRACE (("plist/init_one_parameter[pid=STATUSINFO,mode=STRICT,proto=%d.%d]: invalid statusinfo (0x%x)\n", dd->protocol_version.major, dd->protocol_version.minor, dest->statusinfo)); return ERR_INVALID; } + /* Clear all bits we don't understand, then add the extended bits if present */ + dest->statusinfo &= NN_STATUSINFO_STANDARDIZED; + if (dd->bufsz >= 2 * sizeof (dest->statusinfo) && vendor_is_opensplice(dd->vendorid)) + { + os_uint32 statusinfox; + Q_STATIC_ASSERT_CODE (sizeof(statusinfox) == sizeof(dest->statusinfo)); + memcpy (&statusinfox, dd->buf + sizeof (dest->statusinfo), sizeof (statusinfox)); + statusinfox = fromBE4u (statusinfox); + if (statusinfox & NN_STATUSINFOX_OSPL_AUTO) + dest->statusinfo |= NN_STATUSINFO_OSPL_AUTO; + } dest->present |= PP_STATUSINFO; return 0; @@ -2037,6 +2052,7 @@ static int init_one_parameter return 0; } +#if ! LITE case PID_PRISMTECH_ENDPOINT_GID: if (!vendor_is_prismtech (dd->vendorid)) return 0; @@ -2100,6 +2116,7 @@ static int init_one_parameter dest->present |= PP_PRISMTECH_WRITER_INFO; return 0; } +#endif case PID_PRISMTECH_PARTICIPANT_VERSION_INFO: return do_prismtech_participant_version_info(&dest->prismtech_participant_version_info, &dest->present, &dest->aliased, dd); @@ -2114,10 +2131,12 @@ static int init_one_parameter return 0; return do_reader_lifespan_qospolicy (&dest->qos.reader_lifespan, &dest->qos.present, QP_PRISMTECH_READER_LIFESPAN, dd); +#if !LITE case PID_PRISMTECH_SHARE: if (!vendor_is_prismtech (dd->vendorid)) return 0; return do_share_qospolicy (&dest->qos.share, &dest->qos.present, &dest->qos.aliased, QP_PRISMTECH_SHARE, dd); +#endif case PID_PRISMTECH_ENTITY_FACTORY: if (!vendor_is_prismtech (dd->vendorid)) @@ -2213,6 +2232,28 @@ static int init_one_parameter return 0; } +#ifdef DDSI_INCLUDE_SSM + case PID_READER_FAVOURS_SSM: + if (dd->bufsz < sizeof (dest->reader_favours_ssm)) + { + TRACE (("plist/init_one_parameter[pid=READER_FAVOURS_SSM]: buffer too small\n")); + return ERR_INVALID; + } + else + { + nn_reader_favours_ssm_t *rfssm = &dest->reader_favours_ssm; + memcpy (rfssm, dd->buf, sizeof (*rfssm)); + if (dd->bswap) + rfssm->state = bswap4u (rfssm->state); + if (rfssm->state != 0 && rfssm->state != 1) + { + TRACE (("plist/init_one_parameter[pid=READER_FAVOURS_SSM]: unsupported value: %u\n", rfssm->state)); + rfssm->state = 0; + } + dest->present |= PP_READER_FAVOURS_SSM; + return 0; + } +#endif /* Deprecated ones (used by RTI, but not relevant to DDSI) */ case PID_PERSISTENCE: @@ -2304,9 +2345,14 @@ void nn_plist_mergein_missing (nn_plist_t *a, const nn_plist_t *b) CQ (PRISMTECH_SERVICE_TYPE, service_type); CQ (PRISMTECH_PROCESS_ID, process_id); CQ (PRISMTECH_BUILTIN_ENDPOINT_SET, prismtech_builtin_endpoint_set); +#if ! LITE CQ (PRISMTECH_WRITER_INFO, prismtech_writer_info); CQ (PRISMTECH_GROUP_GID, group_gid); CQ (PRISMTECH_ENDPOINT_GID, endpoint_gid); +#endif +#ifdef DDSI_INCLUDE_SSM + CQ (READER_FAVOURS_SSM, reader_favours_ssm); +#endif #undef CQ /* For allocated ones it is Not strictly necessary to use tmp, as @@ -2565,6 +2611,16 @@ unsigned char *nn_plist_quickscan (struct nn_rsample_info *dest, const struct nn case PID_PAD: break; case PID_KEYHASH: +#if LITE + if (length < sizeof (dest->keyhash)) + { + TRACE (("plist(vendor %d.%d): quickscan(PID_KEYHASH): buffer too small\n", + src->vendorid.id[0], src->vendorid.id[1])); + return NULL; + } + memcpy (&dest->keyhash, pl, sizeof (dest->keyhash)); + dest->hashash = 1; +#endif break; case PID_STATUSINFO: if (length < 4) @@ -2576,14 +2632,16 @@ unsigned char *nn_plist_quickscan (struct nn_rsample_info *dest, const struct nn else { unsigned stinfo = fromBE4u (*((unsigned *) pl)); + unsigned stinfox = (length < 8 || !vendor_is_opensplice(src->vendorid)) ? 0 : fromBE4u (*((unsigned *) pl + 1)); #if (NN_STATUSINFO_DISPOSE | NN_STATUSINFO_UNREGISTER) != 3 #error "expected dispose/unregister to be in lowest 2 bits" #endif dest->statusinfo = stinfo & 3u; - if (stinfo & ~3u) + if ((stinfo & ~3u) || stinfox) dest->complex_qos = 1; } break; +#if !LITE case PID_PRISMTECH_WRITER_INFO: if (length < sizeof (nn_prismtech_writer_info_old_t)) { @@ -2593,6 +2651,7 @@ unsigned char *nn_plist_quickscan (struct nn_rsample_info *dest, const struct nn } dest->pt_wr_info_zoff = NN_OFF_TO_ZOFF ((unsigned) (pl - NN_RMSG_PAYLOAD (rmsg))); break; +#endif default: TRACE_PLIST (("(pid=%x complex_qos=1)", pid)); dest->complex_qos = 1; @@ -2607,6 +2666,7 @@ unsigned char *nn_plist_quickscan (struct nn_rsample_info *dest, const struct nn return NULL; } +#if !LITE void nn_plist_extract_wrinfo (nn_prismtech_writer_info_t *wri, const struct nn_rsample_info *sampleinfo, const struct nn_rdata *rdata) { unsigned wrinfo_off = NN_SAMPLEINFO_WRINFO_OFF (sampleinfo); @@ -2616,6 +2676,7 @@ void nn_plist_extract_wrinfo (nn_prismtech_writer_info_t *wri, const struct nn_r if (sampleinfo->bswap) bswap_prismtech_writer_info (wri); } +#endif void nn_xqos_init_empty (nn_xqos_t *dest) { @@ -2705,10 +2766,12 @@ void nn_xqos_init_default_reader (nn_xqos_t *xqos) xqos->reader_lifespan.use_lifespan = 0; xqos->reader_lifespan.duration = nn_to_ddsi_duration (T_NEVER); +#if !LITE xqos->present |= QP_PRISMTECH_SHARE; xqos->aliased |= QP_PRISMTECH_SHARE; xqos->share.enable = 0; xqos->share.name = ""; +#endif xqos->present |= QP_PRISMTECH_SUBSCRIPTION_KEYS; xqos->subscription_keys.use_key_list = 0; @@ -2788,10 +2851,12 @@ void nn_xqos_init_default_subscriber (nn_xqos_t *xqos) xqos->present |= QP_PRISMTECH_ENTITY_FACTORY; xqos->entity_factory.autoenable_created_entities = 1; +#if !LITE xqos->present |= QP_PRISMTECH_SHARE; xqos->aliased |= QP_PRISMTECH_SHARE; xqos->share.enable = 0; xqos->share.name = ""; +#endif xqos->present |= QP_PARTITION; xqos->partition.n = 0; @@ -2863,7 +2928,9 @@ void nn_xqos_mergein_missing (nn_xqos_t *a, const nn_xqos_t *b) CQ (USER_DATA, user_data, octetseq, nn_octetseq_t); CQ (TOPIC_NAME, topic_name, string, char *); CQ (TYPE_NAME, type_name, string, char *); +#if !LITE CQ (PRISMTECH_SHARE, share, share_qospolicy, nn_share_qospolicy_t); +#endif CQ (RTI_TYPECODE, rti_typecode, octetseq, nn_octetseq_t); #undef CQ if (!(a->present & QP_PRISMTECH_SUBSCRIPTION_KEYS) && (b->present & QP_PRISMTECH_SUBSCRIPTION_KEYS)) @@ -2900,7 +2967,9 @@ void nn_xqos_unalias (nn_xqos_t *xqos) Q (TOPIC_NAME, string, topic_name); Q (TYPE_NAME, string, type_name); Q (PARTITION, stringseq, partition); +#if !LITE Q (PRISMTECH_SHARE, share_qospolicy, share); +#endif Q (PRISMTECH_SUBSCRIPTION_KEYS, subscription_keys_qospolicy, subscription_keys); Q (RTI_TYPECODE, octetseq, rti_typecode); #undef Q @@ -2916,7 +2985,9 @@ void nn_xqos_fini (nn_xqos_t *xqos) { QP_USER_DATA, offsetof (nn_xqos_t, user_data.value) }, { QP_TOPIC_NAME, offsetof (nn_xqos_t, topic_name) }, { QP_TYPE_NAME, offsetof (nn_xqos_t, type_name) }, +#if !LITE { QP_PRISMTECH_SHARE, offsetof (nn_xqos_t, share.name) }, +#endif { QP_RTI_TYPECODE, offsetof (nn_xqos_t, rti_typecode.value) }, }; int i; @@ -3218,6 +3289,7 @@ os_uint64 nn_xqos_delta (const nn_xqos_t *a, const nn_xqos_t *b, os_uint64 mask) durations_differ (&a->reader_lifespan.duration, &b->reader_lifespan.duration))) delta |= QP_PRISMTECH_READER_LIFESPAN; } +#if !LITE if (check & QP_PRISMTECH_SHARE) { /* Note: the conjunction need not test both a & b for having use_lifespan set */ if (a->share.enable != b->share.enable || @@ -3225,6 +3297,7 @@ os_uint64 nn_xqos_delta (const nn_xqos_t *a, const nn_xqos_t *b, os_uint64 mask) strcmp (a->share.name, b->share.name))) delta |= QP_PRISMTECH_SHARE; } +#endif if (check & QP_PRISMTECH_SUBSCRIPTION_KEYS) { /* Note: the conjunction need not test both a & b for having use_lifespan set */ if (a->subscription_keys.use_key_list != b->subscription_keys.use_key_list || @@ -3301,7 +3374,9 @@ void nn_xqos_addtomsg (struct nn_xmsg *m, const nn_xqos_t *xqos, os_uint64 wante SIMPLE (PRISMTECH_WRITER_DATA_LIFECYCLE, writer_data_lifecycle); SIMPLE (PRISMTECH_RELAXED_QOS_MATCHING, relaxed_qos_matching); SIMPLE (PRISMTECH_READER_LIFESPAN, reader_lifespan); +#if !LITE FUNC_BY_REF (PRISMTECH_SHARE, share, share); +#endif FUNC_BY_REF (PRISMTECH_SUBSCRIPTION_KEYS, subscription_keys, subscription_keys); SIMPLE (PRISMTECH_ENTITY_FACTORY, entity_factory); SIMPLE (PRISMTECH_SYNCHRONOUS_ENDPOINT, synchronous_endpoint); @@ -3367,7 +3442,8 @@ void nn_plist_addtomsg (struct nn_xmsg *m, const nn_plist_t *ps, os_uint64 pwant FUNC_BY_REF (PARTICIPANT_GUID, participant_guid, guid); SIMPLE_TYPE (BUILTIN_ENDPOINT_SET, builtin_endpoint_set, unsigned); SIMPLE_TYPE (KEYHASH, keyhash, nn_keyhash_t); - FUNC_BY_VAL (STATUSINFO, statusinfo, BE4u); + if (w & PP_STATUSINFO) + nn_xmsg_addpar_statusinfo (m, ps->statusinfo); SIMPLE_TYPE (COHERENT_SET, coherent_set_seqno, nn_sequence_number_t); if (! NN_PEDANTIC_P) FUNC_BY_REF (ENDPOINT_GUID, endpoint_guid, guid); @@ -3386,11 +3462,16 @@ void nn_plist_addtomsg (struct nn_xmsg *m, const nn_plist_t *ps, os_uint64 pwant FUNC_BY_VAL (PRISMTECH_EXEC_NAME, exec_name, string); SIMPLE_TYPE (PRISMTECH_PROCESS_ID, process_id, unsigned); SIMPLE_TYPE (PRISMTECH_SERVICE_TYPE, service_type, unsigned); +#if ! LITE SIMPLE_TYPE (PRISMTECH_WRITER_INFO, prismtech_writer_info, nn_prismtech_writer_info_t); SIMPLE_TYPE (PRISMTECH_GROUP_GID, group_gid, v_gid); SIMPLE_TYPE (PRISMTECH_ENDPOINT_GID, endpoint_gid, v_gid); +#endif FUNC_BY_VAL (PRISMTECH_TYPE_DESCRIPTION, type_description, string); FUNC_BY_REF (PRISMTECH_EOTINFO, eotinfo, eotinfo); +#ifdef DDSI_INCLUDE_SSM + SIMPLE_TYPE (READER_FAVOURS_SSM, reader_favours_ssm, nn_reader_favours_ssm_t); +#endif #undef FUNC_BY_REF #undef FUNC_BY_VAL #undef SIMPLE @@ -3512,7 +3593,9 @@ void nn_log_xqos (logcat_t cat, const nn_xqos_t *xqos) } nn_log (cat, "}}"); }); +#if !LITE DO (PRISMTECH_SHARE, { LOGB2 ("share={%d,%s}", xqos->share.enable, xqos->share.name ? xqos->share.name : "(null)"); }); +#endif DO (PRISMTECH_ENTITY_FACTORY, { LOGB1 ("entity_factory=%d", xqos->entity_factory.autoenable_created_entities); }); DO (PRISMTECH_SYNCHRONOUS_ENDPOINT, { LOGB1 ("synchronous_endpoint=%d", xqos->synchronous_endpoint.value); }); DO (RTI_TYPECODE, { @@ -3531,5 +3614,3 @@ void nn_log_xqos (logcat_t cat, const nn_xqos_t *xqos) #undef LOGB1 #undef LOGB0 } - -/* SHA1 not available (unoffical build.) */ diff --git a/src/services/ddsi2/code/q_plist.h b/src/services/ddsi2e/core/q_plist.h similarity index 90% rename from src/services/ddsi2/code/q_plist.h rename to src/services/ddsi2e/core/q_plist.h index 2e1c9afca..30669b419 100644 --- a/src/services/ddsi2/code/q_plist.h +++ b/src/services/ddsi2e/core/q_plist.h @@ -1,18 +1,16 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * @@ -23,8 +21,10 @@ #include "q_feature_check.h" #include "q_xqos.h" +#if !LITE #include "c_base.h" #include "kernelModule.h" +#endif #if defined (__cplusplus) extern "C" { @@ -81,10 +81,15 @@ typedef struct nn_original_writer_info { #define PP_PRISMTECH_LISTENER_SCHEDULING ((os_uint64)1 << 32) #define PP_PRISMTECH_BUILTIN_ENDPOINT_SET ((os_uint64)1 << 33) #define PP_PRISMTECH_TYPE_DESCRIPTION ((os_uint64)1 << 34) +#if ! LITE #define PP_PRISMTECH_ENDPOINT_GID ((os_uint64)1 << 35) #define PP_PRISMTECH_GROUP_GID ((os_uint64)1 << 36) +#endif #define PP_COHERENT_SET ((os_uint64)1 << 37) #define PP_PRISMTECH_EOTINFO ((os_uint64)1 << 38) +#ifdef DDSI_INCLUDE_SSM +#define PP_READER_FAVOURS_SSM ((os_uint64)1 << 39) +#endif #define PP_RTI_TYPECODE ((os_uint64)1 << 40) /* Set for unrecognized parameters that are in the reserved space or in our own vendor-specific space that have the @@ -99,6 +104,9 @@ typedef struct nn_original_writer_info { #define NN_PRISMTECH_FL_DDSI2_PARTICIPANT_FLAG (1u << 3) #define NN_PRISMTECH_FL_PARTICIPANT_IS_DDSI2 (1u << 4) #define NN_PRISMTECH_FL_MINIMAL_BES_MODE (1u << 5) +#define NN_PRISMTECH_FL_SUPPORTS_STATUSINFOX (1u << 5) +/* SUPPORTS_STATUSINFOX: when set, also means any combination of + write/unregister/dispose supported */ /* For locators one could patch the received message data to create singly-linked lists (parameter header -> offset of next entry in @@ -124,6 +132,7 @@ typedef struct nn_keyhash { unsigned char value[16]; } nn_keyhash_t; +#if !LITE typedef struct nn_prismtech_writer_info_old { os_uint32 transactionId; @@ -138,7 +147,13 @@ typedef struct nn_prismtech_writer_info v_gid writerInstanceGID; os_uint32 sequenceNumber; } nn_prismtech_writer_info_t; +#endif +#ifdef DDSI_INCLUDE_SSM +typedef struct nn_reader_favours_ssm { + unsigned state; /* default is false */ +} nn_reader_favours_ssm_t; +#endif typedef struct nn_prismtech_participant_version_info { @@ -194,18 +209,25 @@ typedef struct nn_plist { char *entity_name; nn_keyhash_t keyhash; unsigned statusinfo; +#if !LITE nn_prismtech_writer_info_t prismtech_writer_info; +#endif nn_prismtech_participant_version_info_t prismtech_participant_version_info; char *node_name; char *exec_name; unsigned char is_service; unsigned service_type; unsigned process_id; +#if ! LITE v_gid endpoint_gid; v_gid group_gid; +#endif char *type_description; nn_sequence_number_t coherent_set_seqno; nn_prismtech_eotinfo_t eotinfo; +#ifdef DDSI_INCLUDE_SSM + nn_reader_favours_ssm_t reader_favours_ssm; +#endif } nn_plist_t; @@ -249,12 +271,12 @@ struct nn_rsample_info; struct nn_rdata; unsigned char *nn_plist_quickscan (struct nn_rsample_info *dest, const struct nn_rmsg *rmsg, const nn_plist_src_t *src); +#if !LITE void nn_plist_extract_wrinfo (nn_prismtech_writer_info_t *wri, const struct nn_rsample_info *sampleinfo, const struct nn_rdata *rdata); +#endif #if defined (__cplusplus) } #endif #endif /* NN_PLIST_H */ - -/* SHA1 not available (unoffical build.) */ diff --git a/src/services/ddsi2/code/q_protocol.h b/src/services/ddsi2e/core/q_protocol.h similarity index 93% rename from src/services/ddsi2/code/q_protocol.h rename to src/services/ddsi2e/core/q_protocol.h index 5e4a5da1c..a58f9c809 100644 --- a/src/services/ddsi2/code/q_protocol.h +++ b/src/services/ddsi2e/core/q_protocol.h @@ -1,18 +1,16 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * @@ -89,7 +87,9 @@ struct cdrstring { #define NN_STATUSINFO_DISPOSE 0x1u #define NN_STATUSINFO_UNREGISTER 0x2u - +#define NN_STATUSINFO_STANDARDIZED (NN_STATUSINFO_DISPOSE | NN_STATUSINFO_UNREGISTER) +#define NN_STATUSINFO_OSPL_AUTO 0x10000000u /* OSPL extension, not on the wire */ +#define NN_STATUSINFOX_OSPL_AUTO 0x1 /* statusinfo word 2, OSPL L_AUTO flag on the wire */ #define NN_GUID_PREFIX_UNKNOWN_INITIALIZER {{0,0,0,0, 0,0,0,0, 0,0,0,0}} @@ -142,7 +142,11 @@ struct cdrstring { #define NN_VENDORID_EPROSIMA {{ 0x01, 0x0f }} #define NN_VENDORID_PRISMTECH_CLOUD {{ 0x01, 0x20 }} +#if LITE +#define MY_VENDOR_ID NN_VENDORID_PRISMTECH_LITE +#else #define MY_VENDOR_ID NN_VENDORID_PRISMTECH_OSPL +#endif /* Only one specific version is grokked */ #define RTPS_MAJOR 2 @@ -412,7 +416,17 @@ typedef struct ParticipantMessageData { #define PID_RTI_TYPECODE (PID_VENDORSPECIFIC_FLAG | 0x4u) +#ifdef DDSI_INCLUDE_SSM +/* To indicate whether a reader favours the use of SSM. Iff the + reader favours SSM, it will use SSM if available. */ +#define PID_READER_FAVOURS_SSM 0x72u +#endif +#ifdef DDSI_INCLUDE_SSM +/* To indicate whether a reader favours the use of SSM. Iff the + reader favours SSM, it will use SSM if available. */ +#define PID_READER_FAVOURS_SSM 0x72u +#endif /* Deprecated parameter IDs (accepted but ignored) */ #define PID_PERSISTENCE 0x03u @@ -428,7 +442,9 @@ typedef struct ParticipantMessageData { #define PID_RELIABILITY_OFFERED 0x19u #define PID_PRISMTECH_BUILTIN_ENDPOINT_SET (PID_VENDORSPECIFIC_FLAG | 0x0u) +#if !LITE #define PID_PRISMTECH_WRITER_INFO (PID_VENDORSPECIFIC_FLAG | 0x1u) +#endif /* parameter ids for READER_DATA_LIFECYCLE & WRITER_DATA_LIFECYCLE are undefined, but let's publish them anyway */ @@ -458,7 +474,9 @@ typedef struct ParticipantMessageData { #define PID_PRISMTECH_LISTENER_SCHEDULING (PID_VENDORSPECIFIC_FLAG | 0xeu) #define PID_PRISMTECH_SUBSCRIPTION_KEYS (PID_VENDORSPECIFIC_FLAG | 0xfu) #define PID_PRISMTECH_READER_LIFESPAN (PID_VENDORSPECIFIC_FLAG | 0x10u) +#if !LITE #define PID_PRISMTECH_SHARE (PID_VENDORSPECIFIC_FLAG | 0x11u) +#endif #define PID_PRISMTECH_TYPE_DESCRIPTION (PID_VENDORSPECIFIC_FLAG | 0x12u) #define PID_PRISMTECH_LAN (PID_VENDORSPECIFIC_FLAG | 0x13u) #define PID_PRISMTECH_ENDPOINT_GID (PID_VENDORSPECIFIC_FLAG | 0x14u) @@ -472,5 +490,3 @@ typedef struct ParticipantMessageData { #endif #endif /* NN_PROTOCOL_H */ - -/* SHA1 not available (unoffical build.) */ diff --git a/src/services/ddsi2/code/q_qosmatch.c b/src/services/ddsi2e/core/q_qosmatch.c similarity index 90% rename from src/services/ddsi2/code/q_qosmatch.c rename to src/services/ddsi2e/core/q_qosmatch.c index 5499a1be4..616e59488 100644 --- a/src/services/ddsi2/code/q_qosmatch.c +++ b/src/services/ddsi2e/core/q_qosmatch.c @@ -1,18 +1,16 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * @@ -230,5 +228,3 @@ os_int32 qos_match_p (const nn_xqos_t *rd, const nn_xqos_t *wr) } return -1; } - -/* SHA1 not available (unoffical build.) */ diff --git a/src/services/ddsi2e/core/q_qosmatch.h b/src/services/ddsi2e/core/q_qosmatch.h new file mode 100644 index 000000000..0c57d0ef5 --- /dev/null +++ b/src/services/ddsi2e/core/q_qosmatch.h @@ -0,0 +1,39 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#ifndef Q_QOSMATCH_H +#define Q_QOSMATCH_H + +#if defined (__cplusplus) +extern "C" { +#endif + +struct nn_xqos; + +int partition_match_based_on_wildcard_in_left_operand (const struct nn_xqos *a, const struct nn_xqos *b, const char **realname); +int partitions_match_p (const struct nn_xqos *a, const struct nn_xqos *b); +int is_wildcard_partition (const char *str); + +/* Returns -1 on success, or QoS id of first missmatch (>=0) */ + +os_int32 qos_match_p (const struct nn_xqos *rd, const struct nn_xqos *wr); + +#if defined (__cplusplus) +} +#endif + +#endif /* Q_QOSMATCH_H */ diff --git a/src/services/ddsi2/code/q_radmin.c b/src/services/ddsi2e/core/q_radmin.c similarity index 99% rename from src/services/ddsi2/code/q_radmin.c rename to src/services/ddsi2e/core/q_radmin.c index 5768366ff..a698b4d7b 100644 --- a/src/services/ddsi2/code/q_radmin.c +++ b/src/services/ddsi2e/core/q_radmin.c @@ -1,18 +1,16 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * @@ -2467,7 +2465,9 @@ static void *dqueue_thread (struct nn_dqueue *q) struct nn_rsample_chain_elem *e = sc.first; int ret; sc.first = e->next; - pa_dec32 (&q->nof_samples); + if (pa_dec32_nv (&q->nof_samples) == 0) { + os_condBroadcast (&q->cond); + } thread_state_awake (self); switch (dqueue_elem_kind (e)) { @@ -2595,7 +2595,7 @@ void nn_dqueue_enqueue (struct nn_dqueue *q, struct nn_rsample_chain *sc, nn_reo os_mutexLock (&q->lock); pa_add32 (&q->nof_samples, (os_uint32) rres); if (nn_dqueue_enqueue_locked (q, sc)) - os_condSignal (&q->cond); + os_condBroadcast (&q->cond); os_mutexUnlock (&q->lock); } @@ -2614,7 +2614,7 @@ static void nn_dqueue_enqueue_bubble (struct nn_dqueue *q, struct nn_dqueue_bubb os_mutexLock (&q->lock); pa_inc32 (&q->nof_samples); if (nn_dqueue_enqueue_bubble_locked (q, b)) - os_condSignal (&q->cond); + os_condBroadcast (&q->cond); os_mutexUnlock (&q->lock); } @@ -2644,7 +2644,7 @@ void nn_dqueue_enqueue1 (struct nn_dqueue *q, const nn_guid_t *rdguid, struct nn os_mutexLock (&q->lock); pa_add32 (&q->nof_samples, 1 + (os_uint32) rres); if (nn_dqueue_enqueue_bubble_locked (q, b)) - os_condSignal (&q->cond); + os_condBroadcast (&q->cond); nn_dqueue_enqueue_locked (q, sc); os_mutexUnlock (&q->lock); } @@ -2662,6 +2662,18 @@ int nn_dqueue_is_full (struct nn_dqueue *q) return (count >= q->max_samples); } +void nn_dqueue_wait_until_empty_if_full (struct nn_dqueue *q) +{ + const os_uint32 count = pa_ld32 (&q->nof_samples); + if (count >= q->max_samples) + { + os_mutexLock (&q->lock); + while (pa_ld32 (&q->nof_samples) > 0) + os_condWait (&q->cond, &q->lock); + os_mutexUnlock (&q->lock); + } +} + void nn_dqueue_free (struct nn_dqueue *q) { /* There must not be any thread enqueueing things anymore at this @@ -2680,5 +2692,3 @@ void nn_dqueue_free (struct nn_dqueue *q) os_free (q->name); os_free (q); } - -/* SHA1 not available (unoffical build.) */ diff --git a/src/services/ddsi2/code/q_radmin.h b/src/services/ddsi2e/core/q_radmin.h similarity index 92% rename from src/services/ddsi2/code/q_radmin.h rename to src/services/ddsi2e/core/q_radmin.h index 36980e80e..303b683dc 100644 --- a/src/services/ddsi2/code/q_radmin.h +++ b/src/services/ddsi2e/core/q_radmin.h @@ -1,18 +1,16 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * @@ -116,6 +114,15 @@ struct receiver_state { ddsi_tran_conn_t conn; /* Connection for request */ }; +#if LITE +struct proxy_writer_info +{ + nn_guid_t guid; + bool auto_dispose; + int32_t ownership_strength; + uint64_t iid; +}; +#endif struct nn_rsample_info { os_int64 seq; @@ -129,6 +136,11 @@ struct nn_rsample_info { unsigned pt_wr_info_zoff: 16; /* PrismTech writer info offset */ unsigned bswap: 1; /* so we can extract well formatted writer info quicker */ unsigned complex_qos: 1; /* includes QoS other than keyhash, 2-bit statusinfo, PT writer info */ +#if LITE + unsigned hashash: 1; /* Do we have a key hash */ + nn_keyhash_t keyhash; /* Key hash. Not currently used by OSPL */ + struct proxy_writer_info pwr_info; +#endif }; struct nn_rdata { @@ -239,11 +251,10 @@ void nn_dqueue_enqueue (struct nn_dqueue *q, struct nn_rsample_chain *sc, nn_reo void nn_dqueue_enqueue1 (struct nn_dqueue *q, const nn_guid_t *rdguid, struct nn_rsample_chain *sc, nn_reorder_result_t rres); void nn_dqueue_enqueue_callback (struct nn_dqueue *q, nn_dqueue_callback_t cb, void *arg); int nn_dqueue_is_full (struct nn_dqueue *q); +void nn_dqueue_wait_until_empty_if_full (struct nn_dqueue *q); #if defined (__cplusplus) } #endif #endif /* NN_RADMIN_H */ - -/* SHA1 not available (unoffical build.) */ diff --git a/src/services/ddsi2/code/q_receive.c b/src/services/ddsi2e/core/q_receive.c similarity index 88% rename from src/services/ddsi2/code/q_receive.c rename to src/services/ddsi2e/core/q_receive.c index c558e821d..8a538b039 100644 --- a/src/services/ddsi2/code/q_receive.c +++ b/src/services/ddsi2e/core/q_receive.c @@ -1,18 +1,16 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * @@ -32,11 +30,13 @@ #include "os_if.h" #include "os_atomics.h" +#if ! LITE #include "v_group.h" #include "v_state.h" #include "v_message.h" #include "v_public.h" #include "v_reader.h" +#endif #include "q_md5.h" #include "ut_avl.h" @@ -48,7 +48,9 @@ #include "q_log.h" #include "q_plist.h" #include "q_unused.h" +#if ! LITE #include "q_groupset.h" +#endif #include "q_bswap.h" #include "q_lat_estim.h" #include "q_bitset.h" @@ -103,13 +105,15 @@ static void maybe_set_reader_in_sync (struct proxy_writer *pwr, struct pwr_rd_ma { wn->in_sync = PRMSS_SYNC; pwr->n_readers_out_of_sync--; +#if !LITE notify_wait_for_historical_data (pwr, &wn->rd_guid); +#endif } break; case PRMSS_OUT_OF_SYNC: if (nn_reorder_next_seq (wn->u.not_in_sync.reorder) - 1 >= wn->u.not_in_sync.end_of_out_of_sync_seq) { - TRACE ((" msr_in_sync(%x:%x:%x:%x out-of-sync to tlcatchup)", PGUID (wn->rd_guid))); + TRACE ((" msr_in_sync("PGUIDFMT" out-of-sync to tlcatchup)", PGUID (wn->rd_guid))); wn->in_sync = PRMSS_TLCATCHUP; maybe_set_reader_in_sync (pwr, wn, last_deliv_seq); } @@ -341,6 +345,15 @@ static void set_sampleinfo_proxy_writer (struct nn_rsample_info *sampleinfo, nn_ { struct proxy_writer * pwr = ephash_lookup_proxy_writer_guid (pwr_guid); sampleinfo->pwr = pwr; +#if LITE + if (pwr) + { + sampleinfo->pwr_info.guid = pwr->e.guid; + sampleinfo->pwr_info.ownership_strength = pwr->c.xqos->ownership_strength.value; + sampleinfo->pwr_info.auto_dispose = pwr->c.xqos->writer_data_lifecycle.autodispose_unregistered_instances; + sampleinfo->pwr_info.iid = pwr->e.iid; + } +#endif } static int valid_Data (const struct receiver_state *rst, struct nn_rmsg *rmsg, Data_t *msg, size_t size, int byteswap, struct nn_rsample_info *sampleinfo, unsigned char **payloadp) @@ -642,14 +655,14 @@ static void force_heartbeat_to_peer (struct writer *wr, struct proxy_reader *prd } add_Gap (m, wr, prd, seq, seq+1, 1, &bits); add_Heartbeat (m, wr, hbansreq, prd->e.guid.entityid, 1); - TRACE (("force_heartbeat_to_peer: %x:%x:%x:%x -> %x:%x:%x:%x - whc empty, queueing gap #%"PA_PRId64" + heartbeat for transmit\n", + TRACE (("force_heartbeat_to_peer: "PGUIDFMT" -> "PGUIDFMT" - whc empty, queueing gap #%"PA_PRId64" + heartbeat for transmit\n", PGUID (wr->e.guid), PGUID (prd->e.guid), seq)); } else { /* Send a Heartbeat just to this peer */ add_Heartbeat (m, wr, hbansreq, prd->e.guid.entityid, 0); - TRACE (("force_heartbeat_to_peer: %x:%x:%x:%x -> %x:%x:%x:%x - queue for transmit\n", + TRACE (("force_heartbeat_to_peer: "PGUIDFMT" -> "PGUIDFMT" - queue for transmit\n", PGUID (wr->e.guid), PGUID (prd->e.guid))); } qxev_msg (wr->evq, m); @@ -657,7 +670,7 @@ static void force_heartbeat_to_peer (struct writer *wr, struct proxy_reader *prd static os_int64 grow_gap_to_next_seq (const struct writer *wr, os_int64 seq) { - os_int64 next_seq = whc_next_seq (wr->whc, seq); + os_int64 next_seq = whc_next_seq (wr->whc, seq - 1); if (next_seq == MAX_SEQ_NUMBER) /* no next sample */ return wr->seq_xmit + 1; else if (next_seq > wr->seq_xmit) /* next is beyond last actually transmitted */ @@ -748,13 +761,13 @@ static int handle_AckNack (struct receiver_state *rst, nn_etime_t tnow, const Ac if (!rst->forme) { - TRACE ((" %x:%x:%x:%x -> %x:%x:%x:%x not-for-me)", PGUID (src), PGUID (dst))); + TRACE ((" "PGUIDFMT" -> "PGUIDFMT" not-for-me)", PGUID (src), PGUID (dst))); return 1; } if ((wr = ephash_lookup_writer_guid (&dst)) == NULL) { - TRACE ((" %x:%x:%x:%x -> %x:%x:%x:%x?)", PGUID (src), PGUID (dst))); + TRACE ((" "PGUIDFMT" -> "PGUIDFMT"?)", PGUID (src), PGUID (dst))); return 1; } /* Always look up the proxy reader -- even though we don't need for @@ -763,7 +776,7 @@ static int handle_AckNack (struct receiver_state *rst, nn_etime_t tnow, const Ac only retrieve it when needed. */ if ((prd = ephash_lookup_proxy_reader_guid (&src)) == NULL) { - TRACE ((" %x:%x:%x:%x? -> %x:%x:%x:%x)", PGUID (src), PGUID (dst))); + TRACE ((" "PGUIDFMT"? -> "PGUIDFMT")", PGUID (src), PGUID (dst))); return 1; } @@ -773,14 +786,14 @@ static int handle_AckNack (struct receiver_state *rst, nn_etime_t tnow, const Ac if (!wr->reliable) /* note: reliability can't be changed */ { - TRACE ((" %x:%x:%x:%x -> %x:%x:%x:%x not a reliable writer!)", PGUID (src), PGUID (dst))); + TRACE ((" "PGUIDFMT" -> "PGUIDFMT" not a reliable writer!)", PGUID (src), PGUID (dst))); return 1; } os_mutexLock (&wr->e.lock); if ((rn = ut_avlLookup (&wr_readers_treedef, &wr->readers, &src)) == NULL) { - TRACE ((" %x:%x:%x:%x -> %x:%x:%x:%x not a connection)", PGUID (src), PGUID (dst))); + TRACE ((" "PGUIDFMT" -> "PGUIDFMT" not a connection)", PGUID (src), PGUID (dst))); goto out; } @@ -800,10 +813,10 @@ static int handle_AckNack (struct receiver_state *rst, nn_etime_t tnow, const Ac if (!accept_ack_or_hb_w_timeout (*countp, &rn->next_acknack, tnow, &rn->t_acknack_accepted, is_preemptive_ack)) { - TRACE ((" [%x:%x:%x:%x -> %x:%x:%x:%x])", PGUID (src), PGUID (dst))); + TRACE ((" ["PGUIDFMT" -> "PGUIDFMT"])", PGUID (src), PGUID (dst))); goto out; } - TRACE ((" %x:%x:%x:%x -> %x:%x:%x:%x", PGUID (src), PGUID (dst))); + TRACE ((" "PGUIDFMT" -> "PGUIDFMT"", PGUID (src), PGUID (dst))); /* Update latency estimates if we have a timestamp -- won't actually work so well if the timestamp can be a left over from some other @@ -822,7 +835,7 @@ static int handle_AckNack (struct receiver_state *rst, nn_etime_t tnow, const Ac else if (config.enabled_logcats & LC_INFO) { char tagbuf[2*(4*8+3) + 4 + 1]; - snprintf (tagbuf, sizeof (tagbuf), "%x:%x:%x:%x -> %x:%x:%x:%x", PGUID (src), PGUID (dst)); + snprintf (tagbuf, sizeof (tagbuf), ""PGUIDFMT" -> "PGUIDFMT"", PGUID (src), PGUID (dst)); if (nn_lat_estim_log (LC_INFO, tagbuf, &rn->hb_to_ack_latency)) nn_log (LC_INFO, "\n"); } @@ -869,7 +882,7 @@ static int handle_AckNack (struct receiver_state *rst, nn_etime_t tnow, const Ac rn->seq = wr->seq; } ut_avlAugmentUpdate (&wr_readers_treedef, rn); - NN_WARNING2 ("writer %x:%x:%x:%x considering reader %x:%x:%x:%x responsive again\n", PGUID (wr->e.guid), PGUID (rn->prd_guid)); + NN_WARNING2 ("writer "PGUIDFMT" considering reader "PGUIDFMT" responsive again\n", PGUID (wr->e.guid), PGUID (rn->prd_guid)); } /* Second, the NACK bits (literally, that is). To do so, attempt to @@ -1047,6 +1060,9 @@ static int handle_AckNack (struct receiver_state *rst, nn_etime_t tnow, const Ac for (i = 0; i < gapnumbits; i++) TRACE (("%c", nn_bitset_isset (gapnumbits, gapbits, i) ? '1' : '0')); m = nn_xmsg_new (gv.xmsgpool, &wr->e.guid.prefix, 0, NN_XMSG_KIND_CONTROL); +#ifdef DDSI_INCLUDE_NETWORK_PARTITIONS + nn_xmsg_setencoderid (m, wr->partition_id); +#endif if (nn_xmsg_setdstPRD (m, prd) < 0) nn_xmsg_free (m); else @@ -1154,7 +1170,7 @@ static void handle_Heartbeat_helper (struct pwr_rd_match * const wn, struct hand /* Not supposed to respond to repeats and old heartbeats. */ if (!accept_ack_or_hb_w_timeout (msg->count, &wn->next_heartbeat, arg->tnow, &wn->t_heartbeat_accepted, 0)) { - TRACE ((" (%x:%x:%x:%x)", PGUID (wn->rd_guid))); + TRACE ((" ("PGUIDFMT")", PGUID (wn->rd_guid))); return; } @@ -1165,7 +1181,7 @@ static void handle_Heartbeat_helper (struct pwr_rd_match * const wn, struct hand refseq = nn_reorder_next_seq (pwr->reorder) - 1; else refseq = nn_reorder_next_seq (wn->u.not_in_sync.reorder) - 1; - TRACE ((" %x:%x:%x:%x@%"PA_PRId64"%s", PGUID (wn->rd_guid), refseq, (wn->in_sync == PRMSS_SYNC) ? "(sync)" : (wn->in_sync == PRMSS_TLCATCHUP) ? "(tlcatchup)" : "")); + TRACE ((" "PGUIDFMT"@%"PA_PRId64"%s", PGUID (wn->rd_guid), refseq, (wn->in_sync == PRMSS_SYNC) ? "(sync)" : (wn->in_sync == PRMSS_TLCATCHUP) ? "(tlcatchup)" : "")); /* Reschedule AckNack transmit if deemed appropriate; unreliable readers have acknack_xevent == NULL and can't do this. @@ -1229,13 +1245,13 @@ static int handle_Heartbeat (struct receiver_state *rst, nn_etime_t tnow, struct if (!rst->forme) { - TRACE (("%x:%x:%x:%x -> %x:%x:%x:%x not-for-me)", PGUID (src), PGUID (dst))); + TRACE ((""PGUIDFMT" -> "PGUIDFMT" not-for-me)", PGUID (src), PGUID (dst))); return 1; } if ((pwr = ephash_lookup_proxy_writer_guid (&src)) == NULL) { - TRACE (("%x:%x:%x:%x? -> %x:%x:%x:%x)", PGUID (src), PGUID (dst))); + TRACE ((""PGUIDFMT"? -> "PGUIDFMT")", PGUID (src), PGUID (dst))); return 1; } @@ -1243,7 +1259,7 @@ static int handle_Heartbeat (struct receiver_state *rst, nn_etime_t tnow, struct if (pwr->assert_pp_lease) lease_renew (pa_ldvoidp (&pwr->c.proxypp->lease), tnow); - TRACE (("%x:%x:%x:%x -> %x:%x:%x:%x:", PGUID (src), PGUID (dst))); + TRACE ((""PGUIDFMT" -> "PGUIDFMT":", PGUID (src), PGUID (dst))); os_mutexLock (&pwr->e.lock); @@ -1303,7 +1319,7 @@ static int handle_Heartbeat (struct receiver_state *rst, nn_etime_t tnow, struct if (wn->u.not_in_sync.end_of_tl_seq == MAX_SEQ_NUMBER) { wn->u.not_in_sync.end_of_tl_seq = fromSN (msg->lastSN); - TRACE ((" end-of-tl-seq(rd %x:%x:%x:%x #%"PA_PRId64")", PGUID(wn->rd_guid), wn->u.not_in_sync.end_of_tl_seq)); + TRACE ((" end-of-tl-seq(rd "PGUIDFMT" #%"PA_PRId64")", PGUID(wn->rd_guid), wn->u.not_in_sync.end_of_tl_seq)); } maybe_set_reader_in_sync (pwr, wn, last_deliv_seq); } @@ -1338,13 +1354,13 @@ static int handle_HeartbeatFrag (struct receiver_state *rst, UNUSED_ARG(nn_etime TRACE (("HEARTBEATFRAG(#%d:%"PA_PRId64"/[1,%u]", msg->count, seq, fragnum+1)); if (!rst->forme) { - TRACE ((" %x:%x:%x:%x -> %x:%x:%x:%x not-for-me)", PGUID (src), PGUID (dst))); + TRACE ((" "PGUIDFMT" -> "PGUIDFMT" not-for-me)", PGUID (src), PGUID (dst))); return 1; } if ((pwr = ephash_lookup_proxy_writer_guid (&src)) == NULL) { - TRACE ((" %x:%x:%x:%x? -> %x:%x:%x:%x)", PGUID (src), PGUID (dst))); + TRACE ((" "PGUIDFMT"? -> "PGUIDFMT")", PGUID (src), PGUID (dst))); return 1; } @@ -1352,7 +1368,7 @@ static int handle_HeartbeatFrag (struct receiver_state *rst, UNUSED_ARG(nn_etime if (pwr->assert_pp_lease) lease_renew (pa_ldvoidp (&pwr->c.proxypp->lease), tnow); - TRACE ((" %x:%x:%x:%x -> %x:%x:%x:%x", PGUID (src), PGUID (dst))); + TRACE ((" "PGUIDFMT" -> "PGUIDFMT"", PGUID (src), PGUID (dst))); os_mutexLock (&pwr->e.lock); if (seq > pwr->last_seq) @@ -1457,13 +1473,13 @@ static int handle_NackFrag (struct receiver_state *rst, nn_etime_t tnow, const N if (!rst->forme) { - TRACE ((" %x:%x:%x:%x -> %x:%x:%x:%x not-for-me)", PGUID (src), PGUID (dst))); + TRACE ((" "PGUIDFMT" -> "PGUIDFMT" not-for-me)", PGUID (src), PGUID (dst))); return 1; } if ((wr = ephash_lookup_writer_guid (&dst)) == NULL) { - TRACE ((" %x:%x:%x:%x -> %x:%x:%x:%x?)", PGUID (src), PGUID (dst))); + TRACE ((" "PGUIDFMT" -> "PGUIDFMT"?)", PGUID (src), PGUID (dst))); return 1; } /* Always look up the proxy reader -- even though we don't need for @@ -1472,7 +1488,7 @@ static int handle_NackFrag (struct receiver_state *rst, nn_etime_t tnow, const N only retrieve it when needed. */ if ((prd = ephash_lookup_proxy_reader_guid (&src)) == NULL) { - TRACE ((" %x:%x:%x:%x? -> %x:%x:%x:%x)", PGUID (src), PGUID (dst))); + TRACE ((" "PGUIDFMT"? -> "PGUIDFMT")", PGUID (src), PGUID (dst))); return 1; } @@ -1482,25 +1498,25 @@ static int handle_NackFrag (struct receiver_state *rst, nn_etime_t tnow, const N if (!wr->reliable) /* note: reliability can't be changed */ { - TRACE ((" %x:%x:%x:%x -> %x:%x:%x:%x not a reliable writer)", PGUID (src), PGUID (dst))); + TRACE ((" "PGUIDFMT" -> "PGUIDFMT" not a reliable writer)", PGUID (src), PGUID (dst))); return 1; } os_mutexLock (&wr->e.lock); if ((rn = ut_avlLookup (&wr_readers_treedef, &wr->readers, &src)) == NULL) { - TRACE ((" %x:%x:%x:%x -> %x:%x:%x:%x not a connection", PGUID (src), PGUID (dst))); + TRACE ((" "PGUIDFMT" -> "PGUIDFMT" not a connection", PGUID (src), PGUID (dst))); goto out; } /* Ignore old NackFrags (see also handle_AckNack) */ if (*countp < rn->next_nackfrag) { - TRACE ((" [%x:%x:%x:%x -> %x:%x:%x:%x]", PGUID (src), PGUID (dst))); + TRACE ((" ["PGUIDFMT" -> "PGUIDFMT"]", PGUID (src), PGUID (dst))); goto out; } rn->next_nackfrag = *countp + 1; - TRACE ((" %x:%x:%x:%x -> %x:%x:%x:%x", PGUID (src), PGUID (dst))); + TRACE ((" "PGUIDFMT" -> "PGUIDFMT"", PGUID (src), PGUID (dst))); /* Resend the requested fragments if we still have the sample, send a Gap if we don't have them anymore. */ @@ -1510,6 +1526,9 @@ static int handle_NackFrag (struct receiver_state *rst, nn_etime_t tnow, const N struct nn_xmsg *m; TRACE ((" msg not available: scheduling Gap\n")); m = nn_xmsg_new (gv.xmsgpool, &wr->e.guid.prefix, 0, NN_XMSG_KIND_CONTROL); +#ifdef DDSI_INCLUDE_NETWORK_PARTITIONS + nn_xmsg_setencoderid (m, wr->partition_id); +#endif if (nn_xmsg_setdstPRD (m, prd) < 0) nn_xmsg_free (m); else @@ -1555,7 +1574,7 @@ static int handle_NackFrag (struct receiver_state *rst, nn_etime_t tnow, const N static int handle_InfoDST (struct receiver_state *rst, const InfoDST_t *msg, const nn_guid_prefix_t *dst_prefix) { rst->dst_guid_prefix = nn_ntoh_guid_prefix (msg->guid_prefix); - TRACE (("INFODST(%x:%x:%x)", PGUIDPREFIX (rst->dst_guid_prefix))); + TRACE (("INFODST("PGIDFMT")", PGUIDPREFIX (rst->dst_guid_prefix))); if (rst->dst_guid_prefix.u[0] == 0 && rst->dst_guid_prefix.u[1] == 0 && rst->dst_guid_prefix.u[2] == 0) { if (dst_prefix) @@ -1577,7 +1596,7 @@ static int handle_InfoSRC (struct receiver_state *rst, const InfoSRC_t *msg) rst->src_guid_prefix = nn_ntoh_guid_prefix (msg->guid_prefix); rst->protocol_version = msg->version; rst->vendor = msg->vendorid; - TRACE (("INFOSRC(%x:%x:%x vendor %d.%d)", + TRACE (("INFOSRC("PGIDFMT" vendor %d.%d)", PGUIDPREFIX (rst->src_guid_prefix), rst->vendor.id[0], rst->vendor.id[1])); return 1; } @@ -1707,13 +1726,13 @@ static int handle_Gap (struct receiver_state *rst, nn_etime_t tnow, struct nn_rm if (!rst->forme) { - TRACE (("%x:%x:%x:%x -> %x:%x:%x:%x not-for-me)", PGUID (src), PGUID (dst))); + TRACE ((""PGUIDFMT" -> "PGUIDFMT" not-for-me)", PGUID (src), PGUID (dst))); return 1; } if ((pwr = ephash_lookup_proxy_writer_guid (&src)) == NULL) { - TRACE (("%x:%x:%x:%x? -> %x:%x:%x:%x)", PGUID (src), PGUID (dst))); + TRACE ((""PGUIDFMT"? -> "PGUIDFMT")", PGUID (src), PGUID (dst))); return 1; } @@ -1724,11 +1743,11 @@ static int handle_Gap (struct receiver_state *rst, nn_etime_t tnow, struct nn_rm os_mutexLock (&pwr->e.lock); if ((wn = ut_avlLookup (&pwr_readers_treedef, &pwr->readers, &dst)) == NULL) { - TRACE (("%x:%x:%x:%x -> %x:%x:%x:%x not a connection)", PGUID (src), PGUID (dst))); + TRACE ((""PGUIDFMT" -> "PGUIDFMT" not a connection)", PGUID (src), PGUID (dst))); os_mutexUnlock (&pwr->e.lock); return 1; } - TRACE (("%x:%x:%x:%x -> %x:%x:%x:%x", PGUID (src), PGUID (dst))); + TRACE ((""PGUIDFMT" -> "PGUIDFMT"", PGUID (src), PGUID (dst))); /* Notify reordering in proxy writer & and the addressed reader (if it is out-of-sync, &c.), while delivering samples that become @@ -1783,6 +1802,133 @@ static int handle_Gap (struct receiver_state *rst, nn_etime_t tnow, struct nn_rm return 1; } +#if LITE +static serstate_t make_raw_serstate +( + struct sertopic const * const topic, + const struct nn_rdata *fragchain, os_uint32 sz, int justkey, + unsigned statusinfo, nn_wctime_t tstamp +) +{ + serstate_t st = ddsi_serstate_new (gv.serpool, topic); + ddsi_serstate_set_msginfo (st, statusinfo, tstamp, NULL); + st->kind = justkey ? STK_KEY : STK_DATA; + /* the CDR header is always fully contained in the first fragment + (see valid_DataFrag), so extracting it is easy */ + assert (fragchain->min == 0); + + /* alignment at head-of-stream is guaranteed, requesting 1 byte + alignment is therefore fine for pasting together fragments of + data */ + { + os_uint32 off = 4; /* must skip the CDR header */ + while (fragchain) + { + assert (fragchain->min <= off); + assert (fragchain->maxp1 <= sz); + if (fragchain->maxp1 > off) + { + /* only copy if this fragment adds data */ + const char *payload = NN_RMSG_PAYLOADOFF (fragchain->rmsg, NN_RDATA_PAYLOAD_OFF (fragchain)); + ddsi_serstate_append_blob (st, 1, fragchain->maxp1 - off, payload + off - fragchain->min); + off = fragchain->maxp1; + } + fragchain = fragchain->nextfrag; + } + } + return st; +} + +static serdata_t extract_sample_from_data +( + const struct nn_rsample_info *sampleinfo, unsigned char data_smhdr_flags, + const nn_plist_t *qos, const struct nn_rdata *fragchain, unsigned statusinfo, + nn_wctime_t tstamp, struct sertopic const * const topic +) +{ + static const nn_guid_t null_guid = {{{0,0,0,0,0,0,0,0,0,0,0,0}},{0}}; + const char *failmsg = NULL; + serdata_t sample = NULL; + + if (statusinfo == 0) + { + /* normal write */ + serstate_t st; + if (!(data_smhdr_flags & DATA_FLAG_DATAFLAG) || sampleinfo->size == 0) + { + const struct proxy_writer *pwr = sampleinfo->pwr; + nn_guid_t guid = pwr ? pwr->e.guid : null_guid; /* can't be null _yet_, but that might change some day */ + TRACE (("data(application, vendor %d.%d): "PGUIDFMT" #%"PA_PRId64 + ": write without proper payload (data_smhdr_flags 0x%x size %u)\n", + sampleinfo->rst->vendor.id[0], sampleinfo->rst->vendor.id[1], + PGUID (guid), sampleinfo->seq, + data_smhdr_flags, sampleinfo->size)); + return NULL; + } + st = make_raw_serstate (topic, fragchain, sampleinfo->size, 0, statusinfo, tstamp); + sample = ddsi_serstate_fix (st); + } + else if (sampleinfo->size) + { + /* dispose or unregister with included serialized key or data + (data is a PrismTech extension) -- i.e., dispose or unregister + as one would expect to receive */ + serstate_t st; + if (data_smhdr_flags & DATA_FLAG_KEYFLAG) + { + st = make_raw_serstate (topic, fragchain, sampleinfo->size, 1, statusinfo, tstamp); + sample = ddsi_serstate_fix (st); + } + else + { + assert (data_smhdr_flags & DATA_FLAG_DATAFLAG); + st = make_raw_serstate (topic, fragchain, sampleinfo->size, 0, statusinfo, tstamp); + sample = ddsi_serstate_fix (st); + } + } + else if (data_smhdr_flags & DATA_FLAG_INLINE_QOS) + { + /* RTI always tries to make us survive on the keyhash. RTI must + mend its ways. */ + if (NN_STRICT_P) + failmsg = "no content"; + else if (!(qos->present & PP_KEYHASH)) + failmsg = "qos present but without keyhash"; + else + { + serstate_t st; + st = ddsi_serstate_new (gv.serpool, topic); + ddsi_serstate_set_msginfo (st, statusinfo, tstamp, NULL); + st->kind = STK_KEY; + ddsi_serstate_append_blob (st, 1, sizeof (qos->keyhash), qos->keyhash.value); + sample = ddsi_serstate_fix (st); + } + } + else + { + failmsg = "no content whatsoever"; + } + if (sample == NULL) + { + /* No message => error out */ + const struct proxy_writer *pwr = sampleinfo->pwr; + nn_guid_t guid = pwr ? pwr->e.guid : null_guid; /* can't be null _yet_, but that might change some day */ + NN_WARNING7 + ( + "data(application, vendor %d.%d): "PGUIDFMT" #%"PA_PRId64": deserialization %s/%s failed (%s)\n", + sampleinfo->rst->vendor.id[0], sampleinfo->rst->vendor.id[1], + PGUID (guid), sampleinfo->seq, + topic->name, topic->typename, + failmsg ? failmsg : "for reasons unknown" + ); + } + else + { + sample->v.bswap = sampleinfo->bswap; + } + return sample; +} +#else static int defragment (unsigned char **datap, const struct nn_rdata *fragchain, os_uint32 sz) { if (fragchain->nextfrag == NULL) @@ -1836,7 +1982,7 @@ static v_message extract_vmsg_from_data if (pwr == NULL || pwr->cs_seq == 0) { nn_guid_t guid = pwr ? pwr->e.guid : null_guid; - TRACE (("data(application, vendor %d.%d): %x:%x:%x:%x #%"PA_PRId64": write without proper payload (data_smhdr_flags 0x%x size %u)\n", + TRACE (("data(application, vendor %d.%d): "PGUIDFMT" #%"PA_PRId64": write without proper payload (data_smhdr_flags 0x%x size %u)\n", sampleinfo->rst->vendor.id[0], sampleinfo->rst->vendor.id[1], PGUID (guid), sampleinfo->seq, data_smhdr_flags, sampleinfo->size)); @@ -1893,7 +2039,7 @@ static v_message extract_vmsg_from_data /* No message => error out */ const struct proxy_writer *pwr = sampleinfo->pwr; nn_guid_t guid = pwr ? pwr->e.guid : null_guid; /* can't be null _yet_, but that might change some day */ - NN_WARNING7 ("data(application, vendor %d.%d): %x:%x:%x:%x #%"PA_PRId64": deserialization %s/%s failed (%s)\n", + NN_WARNING7 ("data(application, vendor %d.%d): "PGUIDFMT" #%"PA_PRId64": deserialization %s/%s failed (%s)\n", sampleinfo->rst->vendor.id[0], sampleinfo->rst->vendor.id[1], PGUID (guid), sampleinfo->seq, topic->name, topic->typename, @@ -1934,14 +2080,12 @@ static int do_groupwrite (v_group g, void *varg) r = 1; else { - /* 1kHz repeat rate taken from native networking; "until" is - clearly not respective as a hard deadline */ const os_duration sleep = OS_DURATION_INIT(0, 1 * T_MILLISECOND); nn_mtime_t until = add_duration_to_mtime (now_mt (), config.retry_on_reject_duration.value); TRACE (("reject-retrying\n")); do { thread_state_blocked (lookup_thread_state ()); - os_sleep (sleep); + ospl_os_sleep (sleep); thread_state_unblocked (lookup_thread_state ()); rc = v_groupResend (g, arg->msg, &inst, &resendScope, gv.myNetworkId); } while (rc == V_WRITE_REJECTED && now_mt ().v < until.v && !gv.terminate); @@ -1992,17 +2136,21 @@ static void set_vmsg_header (const struct proxy_writer *pwr, v_message vmsg, con v_stateSet (v_nodeState (vmsg), L_WRITE); } - if (statusinfo == NN_STATUSINFO_UNREGISTER) + if (statusinfo & NN_STATUSINFO_UNREGISTER) v_stateSet (v_nodeState (vmsg), L_UNREGISTER); - if (statusinfo == NN_STATUSINFO_DISPOSE) + if (statusinfo & NN_STATUSINFO_DISPOSE) v_stateSet (v_nodeState (vmsg), L_DISPOSED); + if (statusinfo & NN_STATUSINFO_OSPL_AUTO) + v_stateSet (v_nodeState (vmsg), L_AUTO); if (pwr->cs_seq) v_stateSet (v_nodeState (vmsg), L_TRANSACTION); if (pwr->c.xqos->synchronous_endpoint.value) v_stateSet (v_nodeState (vmsg), L_SYNCHRONOUS); - assert ((statusinfo & ~(NN_STATUSINFO_DISPOSE | NN_STATUSINFO_UNREGISTER)) == 0); + if ((statusinfo & ~(NN_STATUSINFO_DISPOSE | NN_STATUSINFO_UNREGISTER | NN_STATUSINFO_OSPL_AUTO)) != 0) + NN_WARNING3("received message from vendor %d.%d with statusinfo %x\n", pwr->c.vendor.id[0], pwr->c.vendor.id[1], statusinfo); } +#endif unsigned char normalize_data_datafrag_flags (const SubmessageHeader_t *smhdr, int datafrag_as_data) { @@ -2028,6 +2176,7 @@ unsigned char normalize_data_datafrag_flags (const SubmessageHeader_t *smhdr, in } } +#if ! LITE static void maybe_end_transaction(struct proxy_writer * const pwr, const nn_prismtech_writer_info_t *wri, nn_ddsi_time_t timestamp, os_int64 seq, const nn_plist_t *ps, int have_data) { os_int64 cs_seq = (ps->present & PP_COHERENT_SET) ? fromSN(ps->coherent_set_seqno) : 0; @@ -2038,7 +2187,7 @@ static void maybe_end_transaction(struct proxy_writer * const pwr, const nn_pris { v_message vmsg; - TRACE (("(commit %x:%x:%x:%x txn %u %u seq_offset %"PA_PRId64, PGUID(pwr->e.guid), pwr->transaction_id, txnid ? wri->transactionId : 0, pwr->seq_offset)); + TRACE (("(commit "PGUIDFMT" txn %u %u seq_offset %"PA_PRId64, PGUID(pwr->e.guid), pwr->transaction_id, txnid ? wri->transactionId : 0, pwr->seq_offset)); if (txnid == NULL && pwr->c.xqos->presentation.access_scope == NN_GROUP_PRESENTATION_QOS) { @@ -2095,7 +2244,7 @@ static void maybe_end_transaction(struct proxy_writer * const pwr, const nn_pris wrguid.entityid = txnid->tids[i].writer_entityid; if ((some_pwr = ephash_lookup_proxy_writer_guid (&wrguid)) == NULL) { - TRACE (("dropping transaction including unknown guid %x:%x:%x:%x\n", PGUID (wrguid))); + TRACE (("dropping transaction including unknown guid "PGUIDFMT"\n", PGUID (wrguid))); break; } } @@ -2139,7 +2288,7 @@ static void maybe_end_transaction(struct proxy_writer * const pwr, const nn_pris /* "early" ack mode and a rejection means the sample will never be delivered; updating next_deliv_seq_lowword in this case is a formality because it is irrelevant in this mode. */ - NN_WARNING2 ("incomplete delivery of writer %x:%x:%x:%x sample %"PA_PRId64"\n", PGUID (pwr->e.guid), seq); + NN_WARNING2 ("incomplete delivery of writer "PGUIDFMT" sample %"PA_PRId64"\n", PGUID (pwr->e.guid), seq); pa_st32 (&pwr->next_deliv_seq_lowword, (os_uint32) (seq + 1)); } @@ -2167,10 +2316,12 @@ static void maybe_begin_transaction(struct proxy_writer * const pwr, const nn_pr else pwr->transaction_id = (os_uint32) seq; - TRACE (("(begin %x:%x:%x:%x txn %u)", PGUID(pwr->e.guid), pwr->transaction_id)); + TRACE (("(begin "PGUIDFMT" txn %u)", PGUID(pwr->e.guid), pwr->transaction_id)); } } +#endif +#if ! LITE static void get_writer_info (nn_prismtech_writer_info_t *wri, struct proxy_writer *pwr, const struct nn_rsample_info *sampleinfo, const struct nn_rdata *fragchain, int pwr_locked) { /* If config.generate_builtin_topics is set, we always have a GID @@ -2209,7 +2360,9 @@ static void get_writer_info (nn_prismtech_writer_info_t *wri, struct proxy_write if (!config.generate_builtin_topics && !pwr_locked) os_mutexUnlock (&pwr->e.lock); } +#endif +#if ! LITE static int wait_for_memory_threshold (c_base base) { if (c_baseGetMemThresholdStatus (base) == C_MEMTHRESHOLD_OK) @@ -2243,7 +2396,7 @@ static int wait_for_memory_threshold (c_base base) do { const os_duration shortdelay = OS_DURATION_INIT(0, 10000000); thread_state_blocked (lookup_thread_state ()); - os_sleep (shortdelay); + ospl_os_sleep (shortdelay); thread_state_unblocked (lookup_thread_state ()); } while (c_baseGetMemThresholdStatus (base) != C_MEMTHRESHOLD_OK && os_timeMCompare (os_timeMGet(), abstimeout) == OS_LESS); @@ -2261,6 +2414,7 @@ static int wait_for_memory_threshold (c_base base) } } } +#endif static int deliver_user_data (const struct nn_rsample_info *sampleinfo, const struct nn_rdata *fragchain, const nn_guid_t *rdguid, int pwr_locked) { @@ -2272,8 +2426,12 @@ static int deliver_user_data (const struct nn_rsample_info *sampleinfo, const st unsigned char data_smhdr_flags; nn_plist_t qos; int need_keyhash; +#if LITE + serdata_t payload; +#else v_message payload; nn_prismtech_writer_info_t wri; +#endif /* NOTE: pwr->e.lock need not be held for correct processing (though it may be useful to hold it for maintaining order all the way to @@ -2282,8 +2440,10 @@ static int deliver_user_data (const struct nn_rsample_info *sampleinfo, const st pwr->groupset takes care of itself. FIXME: groupset may be taking care of itself, but it is currently doing so in an annoyingly simplistic manner ... */ +#if ! LITE if (!wait_for_memory_threshold (gv.ospl_base)) return 0; +#endif /* FIXME: fragments are now handled by copying the message to freshly malloced memory (see defragment()) ... that'll have to @@ -2329,7 +2489,7 @@ static int deliver_user_data (const struct nn_rsample_info *sampleinfo, const st src.bufsz = NN_RDATA_PAYLOAD_OFF (fragchain) - qos_offset; if (nn_plist_init_frommsg (&qos, NULL, PP_STATUSINFO | PP_KEYHASH | PP_COHERENT_SET | PP_PRISMTECH_EOTINFO, 0, &src) < 0) { - NN_WARNING4 ("data(application, vendor %d.%d): %x:%x:%x:%x #%"PA_PRIu64": invalid inline qos\n", + NN_WARNING4 ("data(application, vendor %d.%d): "PGUIDFMT" #%"PA_PRIu64": invalid inline qos\n", src.vendorid.id[0], src.vendorid.id[1], PGUID (pwr->e.guid), sampleinfo->seq); return 0; } @@ -2340,10 +2500,22 @@ static int deliver_user_data (const struct nn_rsample_info *sampleinfo, const st data sample (once per reader that cares about that data). For now, this is accepted as sufficiently abnormal behaviour to not worry about it. */ +#if LITE + { + nn_wctime_t tstamp; + if (valid_ddsi_timestamp (sampleinfo->timestamp)) + tstamp = nn_wctime_from_ddsi_time (sampleinfo->timestamp); + else + tstamp.v = 0; + payload = extract_sample_from_data (sampleinfo, data_smhdr_flags, &qos, fragchain, statusinfo, tstamp, topic); + } +#else payload = extract_vmsg_from_data (sampleinfo, data_smhdr_flags, &qos, fragchain, statusinfo, topic); get_writer_info (&wri, pwr, sampleinfo, fragchain, pwr_locked); +#endif if (payload == NULL) { +#if ! LITE if (pwr->c.xqos->presentation.coherent_access && pwr->c.xqos->presentation.access_scope != NN_INSTANCE_PRESENTATION_QOS) { if (pwr_locked) @@ -2357,9 +2529,11 @@ static int deliver_user_data (const struct nn_rsample_info *sampleinfo, const st /* maybe_end_transaction doesn't flush */ TRACE (("\n")); } +#endif goto no_payload; } +#if ! LITE /* If tracing, print the full contents */ if (config.enabled_logcats & LC_TRACE) { @@ -2379,14 +2553,111 @@ static int deliver_user_data (const struct nn_rsample_info *sampleinfo, const st ddsi_serdata_unref (qq); } assert (res >= 0); - nn_log (LC_TRACE, "data(application, vendor %d.%d): %x:%x:%x:%x #%"PA_PRId64"", + nn_log (LC_TRACE, "data(application, vendor %d.%d): "PGUIDFMT" #%"PA_PRId64"", rst->vendor.id[0], rst->vendor.id[1], PGUID (pwr->e.guid), sampleinfo->seq); if (cs_seq != 0) nn_log (LC_TRACE, " C#%"PA_PRId64"", cs_seq); nn_log (LC_TRACE, ": ST%x %s/%s:%s%s\n", statusinfo, topic->name, topic->typename, tmp, res < tmpsize ? "" : " (trunc)"); } +#endif + +#if LITE + /* Generate the DDS_SampleInfo (which is faked to some extent + because we don't actually have a data reader); also note that + the PRISMTECH_WRITER_INFO thing is completely meaningless to + us */ + { + struct tkmap_instance * tk; + + if (sampleinfo->hashash) + { + payload->v.keyhash.m_flags = DDS_KEY_HASH_SET; + memcpy (&payload->v.keyhash.m_hash, &sampleinfo->keyhash, sizeof (payload->v.keyhash.m_hash)); + } + tk = (ddsi_plugin.rhc_lookup_fn) (payload); + + if (tk) + { + if (rdguid == NULL) + { + TRACE ((" %"PA_PRId64"=>EVERYONE\n", sampleinfo->seq)); + + /* FIXME: pwr->rdary is an array of pointers to attached + readers. There's only one thread delivering data for the + proxy writer (as long as there is only one receive thread), + so could get away with not locking at all, and doing safe + updates + GC of rdary instead. */ + + /* Retry loop, for re-delivery of rejected reliable samples. Is a + temporary hack till throttling back of writer is implemented + (with late acknowledgement of sample and nack). */ +retry: + os_mutexLock (&pwr->rdary_lock); + if (!pwr->deleting) + { + struct reader ** const rdary = pwr->rdary; + unsigned i; + for (i = 0; rdary[i]; i++) + { + TRACE (("reader "PGUIDFMT"\n", PGUID (rdary[i]->e.guid))); + if (! (ddsi_plugin.rhc_store_fn) (rdary[i]->rhc, sampleinfo, payload, tk)) + { + if (pwr_locked) os_mutexUnlock (&pwr->e.lock); + os_mutexUnlock (&pwr->rdary_lock); + dds_sleepfor (DDS_MSECS (10)); + if (pwr_locked) os_mutexLock (&pwr->e.lock); + goto retry; + } + } + os_mutexUnlock (&pwr->rdary_lock); + } + else + { + /* When deleting, pwr is no longer accessible via the hash + tables, and consequently, a reader may be deleted without + it being possible to remove it from rdary. The primary + reason rdary exists is to avoid locking the proxy writer + but this is less of an issue when we are deleting it, so + we fall back to using the GUIDs so that we can deliver all + samples we received from it. As writer being deleted any + reliable samples that are rejected are simply discarded. */ + ut_avlIter_t it; + struct pwr_rd_match *m; + os_mutexUnlock (&pwr->rdary_lock); + if (!pwr_locked) os_mutexLock (&pwr->e.lock); + for (m = ut_avlIterFirst (&pwr_readers_treedef, &pwr->readers, &it); m != NULL; m = ut_avlIterNext (&it)) + { + struct reader *rd; + if ((rd = ephash_lookup_reader_guid (&m->rd_guid)) != NULL) + { + TRACE (("reader-via-guid "PGUIDFMT"\n", PGUID (rd->e.guid))); + (void) (ddsi_plugin.rhc_store_fn) (rd->rhc, sampleinfo, payload, tk); + } + } + if (!pwr_locked) os_mutexUnlock (&pwr->e.lock); + } + + pa_st32 (&pwr->next_deliv_seq_lowword, (os_uint32) (sampleinfo->seq + 1)); + } + else + { + struct reader *rd = ephash_lookup_reader_guid (rdguid);; + TRACE ((" %"PA_PRId64"=>"PGUIDFMT"%s\n", sampleinfo->seq, PGUID (*rdguid), rd ? "" : "?")); + while (! (ddsi_plugin.rhc_store_fn) (rd->rhc, sampleinfo, payload, tk) && !pwr->deleting) + { + if (pwr_locked) os_mutexUnlock (&pwr->e.lock); + dds_sleepfor (DDS_MSECS (10)); + if (pwr_locked) os_mutexLock (&pwr->e.lock); + } + } + (ddsi_plugin.rhc_unref_fn) (tk); + } + } + ddsi_serdata_unref (payload); +#endif +#if ! LITE (void) rdguid; /* Fill in the non-payload part of the v_message */ { @@ -2428,12 +2699,13 @@ static int deliver_user_data (const struct nn_rsample_info *sampleinfo, const st /* "early" ack mode and a rejection means the sample will never be delivered; updating next_deliv_seq_lowword in this case is a formality because it is irrelevant in this mode. */ - NN_WARNING2 ("incomplete delivery of writer %x:%x:%x:%x sample %"PA_PRId64"\n", + NN_WARNING2 ("incomplete delivery of writer "PGUIDFMT" sample %"PA_PRId64"\n", PGUID (pwr->e.guid), sampleinfo->seq); pa_st32 (&pwr->next_deliv_seq_lowword, (os_uint32) (sampleinfo->seq + 1)); } } c_free (payload); +#endif no_payload: nn_plist_fini (&qos); return 0; @@ -2495,7 +2767,7 @@ static void handle_regular (struct receiver_state *rst, nn_etime_t tnow, struct nn_guid_t src; src.prefix = rst->src_guid_prefix; src.entityid = msg->writerId; - TRACE ((" %x:%x:%x:%x? -> %x:%x:%x:%x", PGUID (src), PGUID (dst))); + TRACE ((" "PGUIDFMT"? -> "PGUIDFMT"", PGUID (src), PGUID (dst))); return; } @@ -2512,7 +2784,7 @@ static void handle_regular (struct receiver_state *rst, nn_etime_t tnow, struct if (ut_avlIsEmpty (&pwr->readers)) { os_mutexUnlock (&pwr->e.lock); - TRACE ((" %x:%x:%x:%x -> %x:%x:%x:%x: no readers", PGUID (pwr->e.guid), PGUID (dst))); + TRACE ((" "PGUIDFMT" -> "PGUIDFMT": no readers", PGUID (pwr->e.guid), PGUID (dst))); return; } @@ -2539,8 +2811,9 @@ static void handle_regular (struct receiver_state *rst, nn_etime_t tnow, struct struct nn_rsample_chain sc; struct nn_rdata *fragchain = nn_rsample_fragchain (rsample); nn_reorder_result_t rres; + int dq_full = (pwr->dqueue == gv.builtins_dqueue) ? nn_dqueue_is_full (pwr->dqueue) : 0; - rres = nn_reorder_rsample (&sc, pwr->reorder, rsample, &refc_adjust, nn_dqueue_is_full (pwr->dqueue)); + rres = nn_reorder_rsample (&sc, pwr->reorder, rsample, &refc_adjust, dq_full); if (rres == NN_REORDER_ACCEPT && pwr->n_reliable_readers == 0) { @@ -2626,6 +2899,8 @@ static void handle_regular (struct receiver_state *rst, nn_etime_t tnow, struct nn_fragchain_adjust_refcount (fragchain, refc_adjust); } os_mutexUnlock (&pwr->e.lock); + if (!pwr->deliver_synchronously && pwr->dqueue != gv.builtins_dqueue) + nn_dqueue_wait_until_empty_if_full (pwr->dqueue); } static int handle_SPDP (const struct nn_rsample_info *sampleinfo, struct nn_rdata *rdata) @@ -2655,7 +2930,7 @@ static void drop_oversize (struct receiver_state *rst, struct nn_rmsg *rmsg, con cause periodic warnings. */ if (msg->writerId.u == NN_ENTITYID_SPDP_BUILTIN_PARTICIPANT_WRITER) { - NN_WARNING5 ("dropping oversize (%u > %u) SPDP sample %"PA_PRId64" from remote writer %x:%x:%x:%x\n", + NN_WARNING5 ("dropping oversize (%u > %u) SPDP sample %"PA_PRId64" from remote writer "PGUIDFMT"\n", sampleinfo->size, config.max_sample_size, sampleinfo->seq, PGUIDPREFIX (rst->src_guid_prefix), msg->writerId.u); } @@ -2685,7 +2960,7 @@ static void drop_oversize (struct receiver_state *rst, struct nn_rmsg *rmsg, con { const char *tname = pwr->c.topic ? pwr->c.topic->name : "(null)"; const char *ttname = pwr->c.topic ? pwr->c.topic->typename : "(null)"; - NN_WARNING7 ("dropping oversize (%u > %u) sample %"PA_PRId64" from remote writer %x:%x:%x:%x %s/%s\n", + NN_WARNING7 ("dropping oversize (%u > %u) sample %"PA_PRId64" from remote writer "PGUIDFMT" %s/%s\n", sampleinfo->size, config.max_sample_size, sampleinfo->seq, PGUIDPREFIX (rst->src_guid_prefix), msg->writerId.u, tname, ttname); @@ -2695,7 +2970,7 @@ static void drop_oversize (struct receiver_state *rst, struct nn_rmsg *rmsg, con static int handle_Data (struct receiver_state *rst, nn_etime_t tnow, struct nn_rmsg *rmsg, const Data_t *msg, size_t size, struct nn_rsample_info *sampleinfo, unsigned char *datap) { - TRACE (("DATA(%x:%x:%x:%x -> %x:%x:%x:%x #%"PA_PRId64"", + TRACE (("DATA("PGUIDFMT" -> "PGUIDFMT" #%"PA_PRId64"", PGUIDPREFIX (rst->src_guid_prefix), msg->x.writerId.u, PGUIDPREFIX (rst->dst_guid_prefix), msg->x.readerId.u, fromSN (msg->x.writerSN))); @@ -2739,7 +3014,7 @@ static int handle_Data (struct receiver_state *rst, nn_etime_t tnow, struct nn_r static int handle_DataFrag (struct receiver_state *rst, nn_etime_t tnow, struct nn_rmsg *rmsg, const DataFrag_t *msg, size_t size, struct nn_rsample_info *sampleinfo, unsigned char *datap) { - TRACE (("DATAFRAG(%x:%x:%x:%x -> %x:%x:%x:%x #%"PA_PRId64"/[%u..%u]", + TRACE (("DATAFRAG("PGUIDFMT" -> "PGUIDFMT" #%"PA_PRId64"/[%u..%u]", PGUIDPREFIX (rst->src_guid_prefix), msg->x.writerId.u, PGUIDPREFIX (rst->dst_guid_prefix), msg->x.readerId.u, fromSN (msg->x.writerSN), @@ -2759,7 +3034,7 @@ static int handle_DataFrag (struct receiver_state *rst, nn_etime_t tnow, struct os_uint32 begin, endp1; if (msg->x.writerId.u == NN_ENTITYID_SPDP_BUILTIN_PARTICIPANT_WRITER) { - NN_WARNING5 ("DATAFRAG(%x:%x:%x:%x #%"PA_PRId64" -> %x:%x:%x:%x) - fragmented builtin data not yet supported\n", + NN_WARNING5 ("DATAFRAG("PGUIDFMT" #%"PA_PRId64" -> "PGUIDFMT") - fragmented builtin data not yet supported\n", PGUIDPREFIX (rst->src_guid_prefix), msg->x.writerId.u, fromSN (msg->x.writerSN), PGUIDPREFIX (rst->dst_guid_prefix), msg->x.readerId.u); return 1; @@ -2809,6 +3084,21 @@ static int handle_DataFrag (struct receiver_state *rst, nn_etime_t tnow, struct return 1; } +#ifdef DDSI_INCLUDE_ENCRYPTION +static size_t decode_container (unsigned char *submsg, size_t len) +{ + size_t result = len; + if (gv.recvSecurityCodec && len > 0) + { + if (! (q_security_plugin.decode) + (gv.recvSecurityCodec, submsg, len, &result /* in/out, decrements the length*/)) + { + result = 0; + } + } + return result; +} +#endif /* DDSI_INCLUDE_ENCRYPTION */ static void malformed_packet_received_nosubmsg ( @@ -3130,6 +3420,9 @@ static int handle_submsg_sequence { struct nn_rsample_info sampleinfo; unsigned char *datap; +#if LITE + sampleinfo.hashash = 0; +#endif /* valid_DataFrag does not validate the payload */ if (!valid_DataFrag (rst, rmsg, &sm->datafrag, submsg_size, byteswap, &sampleinfo, &datap)) goto malformed; @@ -3145,6 +3438,9 @@ static int handle_submsg_sequence { struct nn_rsample_info sampleinfo; unsigned char *datap; +#if LITE + sampleinfo.hashash = 0; +#endif /* valid_Data does not validate the payload */ if (!valid_Data (rst, rmsg, &sm->data, submsg_size, byteswap, &sampleinfo, &datap)) { @@ -3159,7 +3455,7 @@ static int handle_submsg_sequence break; case SMID_PT_INFO_CONTAINER: - if (is_own_vendor (rst->vendor)) + if (is_own_vendor (rst->vendor) || vendor_is_lite(rst->vendor)) { state = "parse:pt_info_container"; TRACE (("PT_INFO_CONTAINER(")); @@ -3168,6 +3464,22 @@ static int handle_submsg_sequence switch (sm->pt_infocontainer.id) { case PTINFO_ID_ENCRYPT: +#ifdef DDSI_INCLUDE_ENCRYPTION + if (q_security_plugin.decode) + { + /* we have: msg .. submsg .. submsg+submsg_size-1 submsg .. msg+len-1 + our container: data starts immediately following the pt_infocontainer */ + const size_t len1 = submsg_size - sizeof (PT_InfoContainer_t); + unsigned char * const submsg1 = submsg + sizeof (PT_InfoContainer_t); + size_t len2 = decode_container (submsg1, len1); + if ( len2 != 0 ) { + TRACE ((")\n")); + if (handle_submsg_sequence (conn, self, tnowWC, tnowE, src_prefix, dst_prefix, msg, (size_t) (submsg1 - msg) + len2, submsg1, rmsg) < 0) + goto malformed; + } + TRACE (("PT_INFO_CONTAINER END")); + } +#endif /* DDSI_INCLUDE_ENCRYPTION */ break; default: TRACE (("(unknown id %u?)\n", sm->pt_infocontainer.id)); @@ -3318,7 +3630,7 @@ static c_bool do_packet sz = ddsi_conn_read (conn, buff, buff_len); } - if (sz > 0 && !gv.deaf_mute) + if (sz > 0 && !gv.deaf && !(pa_ld32(&gv.ospl_kernel->isolate) & V_ISOLATE_DEAF)) { nn_rmsg_setsize (rmsg, (os_uint32) sz); assert (vtime_asleep_p (self->vtime)); @@ -3330,10 +3642,9 @@ static c_bool do_packet hdr->version.major != RTPS_MAJOR || (hdr->version.major == RTPS_MAJOR && hdr->version.minor < RTPS_MINOR_MINIMUM) ) { - if ((hdr->version.major == RTPS_MAJOR && hdr->version.minor < RTPS_MINOR_MINIMUM)) - TRACE (("HDR(%x:%x:%x vendor %d.%d) len %lu\n, version mismatch: %d.%d\n", - PGUIDPREFIX (hdr->guid_prefix), hdr->vendorid.id[0], hdr->vendorid.id[1], (unsigned long) sz, hdr->version.major, hdr->version.minor)); - + if ((hdr->version.major == RTPS_MAJOR && hdr->version.minor < RTPS_MINOR_MINIMUM)) + TRACE (("HDR("PGIDFMT" vendor %d.%d) len %lu\n, version mismatch: %d.%d\n", + PGUIDPREFIX (hdr->guid_prefix), hdr->vendorid.id[0], hdr->vendorid.id[1], (unsigned long) sz, hdr->version.major, hdr->version.minor)); if (NN_PEDANTIC_P) malformed_packet_received_nosubmsg (buff, sz, "header", hdr->vendorid); } @@ -3341,14 +3652,16 @@ static c_bool do_packet { hdr->guid_prefix = nn_ntoh_guid_prefix (hdr->guid_prefix); - TRACE (("HDR(%x:%x:%x vendor %d.%d) len %lu\n", + TRACE (("HDR("PGIDFMT" vendor %d.%d) len %lu\n", PGUIDPREFIX (hdr->guid_prefix), hdr->vendorid.id[0], hdr->vendorid.id[1], (unsigned long) sz)); +#if ! LITE if (config.coexistWithNativeNetworking && is_own_vendor (hdr->vendorid)) { /* ignore */ } else +#endif { handle_submsg_sequence ( @@ -3463,7 +3776,7 @@ static void rebuild_local_participant_set (struct thread_state1 *self, struct lo { lps->ps[lps->nps].m_conn = pp->m_conn; lps->ps[lps->nps].guid_prefix = pp->e.guid.prefix; - TRACE ((" pp %x:%x:%x:%x handle %d\n", PGUID (pp->e.guid), ddsi_conn_handle (pp->m_conn))); + TRACE ((" pp "PGUIDFMT" handle %d\n", PGUID (pp->e.guid), ddsi_conn_handle (pp->m_conn))); lps->nps++; } } @@ -3596,5 +3909,3 @@ void * recv_thread (struct nn_rbufpool * rbpool) local_participant_set_fini (&lps); return NULL; } - -/* SHA1 not available (unoffical build.) */ diff --git a/src/services/ddsi2e/core/q_receive.h b/src/services/ddsi2e/core/q_receive.h new file mode 100644 index 000000000..b42aca839 --- /dev/null +++ b/src/services/ddsi2e/core/q_receive.h @@ -0,0 +1,38 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#ifndef Q_RECEIVE_H +#define Q_RECEIVE_H + +#if defined (__cplusplus) +extern "C" { +#endif + +struct nn_rbufpool; +struct nn_rsample_info; +struct nn_rdata; +struct ddsi_tran_listener; + +void *recv_thread (struct nn_rbufpool *rbpool); +void *listen_thread (struct ddsi_tran_listener * listener); +int user_dqueue_handler (const struct nn_rsample_info *sampleinfo, const struct nn_rdata *fragchain, const nn_guid_t *rdguid, void *qarg); + +#if defined (__cplusplus) +} +#endif + +#endif /* Q_RECEIVE_H */ diff --git a/src/services/ddsi2/code/q_rtps.h b/src/services/ddsi2e/core/q_rtps.h similarity index 81% rename from src/services/ddsi2/code/q_rtps.h rename to src/services/ddsi2e/core/q_rtps.h index 6f96da2e3..c35dd7b37 100644 --- a/src/services/ddsi2/code/q_rtps.h +++ b/src/services/ddsi2e/core/q_rtps.h @@ -1,18 +1,16 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * @@ -46,6 +44,10 @@ typedef struct nn_guid { #define PGUIDPREFIX(gp) (gp).u[0], (gp).u[1], (gp).u[2] #define PGUID(g) PGUIDPREFIX ((g).prefix), (g).entityid.u +#define PGUIDFMT "%u:%u:%u:%u" + +#define PGID(x) (x).systemId, (x).localId, (x).serial +#define PGIDFMT "%u:%u:%u" /* predefined entity ids; here viewed as an unsigned int, on the network as four bytes corresponding to the integer in network byte @@ -94,5 +96,3 @@ void rtps_term (void); #endif #endif /* NN_RTPS_H */ - -/* SHA1 not available (unoffical build.) */ diff --git a/src/services/ddsi2e/core/q_security.c b/src/services/ddsi2e/core/q_security.c new file mode 100644 index 000000000..6c0fcd097 --- /dev/null +++ b/src/services/ddsi2e/core/q_security.c @@ -0,0 +1,1835 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#ifdef DDSI_INCLUDE_ENCRYPTION + +/* Ordering of the include files is utterly irrational but works. + Don't mess with it: you'll enter Dependency Hell Territory on + WinCE. Here Be Dragons. */ + +#include "q_security.h" +#include "q_config.h" +#include "q_log.h" +#include "q_error.h" +#include "v_kernel.h" +#include "os_stdlib.h" +#include "os_process.h" +#include "os_thread.h" +#include "os_heap.h" +#include "os_atomics.h" + +#include /* for memcpy */ +#include /* for isspace */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "sysdeps.h" + +/* We don't get FILENAME_MAX on WinCE but can't put it in the abstraction + * without complications to the examples so here we go: */ + +#ifndef FILENAME_MAX +#ifdef WINCE +#define FILENAME_MAX 260 +#endif +#endif + +/* Supported URI schema by parser */ +#define URI_FILESCHEMA "file://" + +/* The max. key-length is defined by crypto-lib, here set to 32 bytes by + * OpenSSL */ +#define Q_MAX_KEY_LENGTH EVP_MAX_KEY_LENGTH + +/* The block-size defines the range of sequence-counter, it varies per + * cipher */ +#define Q_BLOWFISH_BLOCK_SIZE (8) +#define Q_AES_BLOCK_SIZE (16) +#define Q_BLOCK_SIZE_MAX (16) + +/** The counter length corresponds to the specific blocksize */ +#define Q_NULL_COUNTER_SIZE (0L) +#define Q_BLOWFISH_COUNTER_SIZE Q_BLOWFISH_BLOCK_SIZE +#define Q_AES_COUNTER_SIZE Q_AES_BLOCK_SIZE + +/* Define macros for 20 bytes digest, but as a single bit-flip shall change + * half of the digests bits, only 12 bytes of them are transfered in security + * header (CHECKME, shall we take lower 12 bytes or higher 12 bytes?) + * Assure the used digest length is 4bytes alligned, to ensure proper alignment of headersize*/ +#define Q_DIGEST_LENGTH (SHA_DIGEST_LENGTH) +#define Q_DIGEST_LENGTH_2 (12) +#define Q_SHA1 SHA1 + +/* For future usage, byte-size of unique value to define lower 4 bytes of each + * counter, shall be chosen randomly */ +#define Q_KEYID_LENGTH 4 + +#define Q_REPORT_OPENSSL_ERR(x) \ +while ( ERR_peek_error() ) \ + NN_ERROR1(x "%s", ERR_error_string(ERR_get_error(), NULL)); + + + +typedef unsigned char q_sha1Digest[SHA_DIGEST_LENGTH]; /* 20 bytes + '\0' */ + + +C_STRUCT(q_sha1Header) { + unsigned char hash[Q_DIGEST_LENGTH_2]; /* hash over body and security attributes */ + /* ----- up to here encrypted ------*/ +}; + + +/* class declarations */ +C_CLASS(q_nullHeader); +C_CLASS(q_blowfishHeader); +C_CLASS(q_aesHeader); + + +/* structure declarations */ +C_STRUCT(q_nullHeader) { + q_cipherType cipherType; /* network order */ /* OPTME */ + os_uint32 partitionId; /* network order */ +}; + +C_STRUCT(q_blowfishHeader) { + unsigned char keyId[Q_KEYID_LENGTH]; /* required for re-keying (reserved for future usage) */ + unsigned char counter[Q_BLOWFISH_BLOCK_SIZE]; /* cipher block length */ + q_cipherType cipherType; /* network order */ /* OPTME */ + os_uint32 partitionId; /* network order */ +}; + +C_STRUCT(q_aesHeader) { + unsigned char keyId[Q_KEYID_LENGTH]; /* required for re-keying (reserved for future usage)*/ + unsigned char counter[Q_AES_BLOCK_SIZE]; /* cipher block length */ + q_cipherType cipherType; /* network order */ /* OPTME */ + os_uint32 partitionId; /* network order */ +}; + +/* To prevent fragmentations of heap and costly pointer dereferencing with + * possible lot of cache-misses, we declare a union that allows us to allocate + * a single array of codecs, each entry realizing a different cipher and + * header-size. */ +C_STRUCT(q_securityHeader) { + union { + C_STRUCT(q_nullHeader) null; /* obsolete */ + C_STRUCT(q_blowfishHeader) blowfish; + C_STRUCT(q_aesHeader) aes; + } u; +}; + + +/* a number of error states, each codec within the set can be in: + * + * Q_CODEC_STATE_OK: everything is Ok, encryption/decryption is performed + * + * Q_CODEC_STATE_REQUIRES_REKEYING: same as Q_CODEC_STATE_OK, but codec has + * reached a state which requires re-keying, shall be used as signal for codec + * manegement + * + * Q_CODEC_STATE_DROP_TEMP: drop encodings/decodings temporarily, caused by + * faulty cipher-keys read form file. Updating the key-file will solve the + * problem and release the block. + * + * Q_CODEC_STATE_DROP_PERM: drop encodings/decodings permanently, caused by + * 'un-connected' partitions, or faulty security-profiles, eg. un-known + * cipher. +*/ +typedef enum { + Q_CODEC_STATE_OK=0, + Q_CODEC_STATE_REQUIRES_REKEYING=1, + Q_CODEC_STATE_DROP_TEMP=2, + Q_CODEC_STATE_DROP_PERM=4 +} q_securityCodecState; + +/* if not 0, the codec is blocked */ +#define IS_DROP_STATE(state) \ + ((state)&(Q_CODEC_STATE_DROP_TEMP|Q_CODEC_STATE_DROP_PERM)) + +/* declaration of codec */ +C_CLASS(q_securityPartitionDecoder); +C_CLASS(q_securityPartitionEncoder); + +C_STRUCT(q_securityPartitionDecoder) { + q_securityCodecState state; + char *cipherKeyURL; + q_cipherType cipherType; + os_char * partitionName; + EVP_CIPHER_CTX *cipherContext; + /* this codec does hold state and therfor does not require securityHeader + * attributes */ +}; + + +C_STRUCT(q_securityPartitionEncoder){ + q_securityCodecState state; + char *cipherKeyURL; + q_cipherType cipherType; + os_char * partitionName; + EVP_CIPHER_CTX *cipherContext; + /* The current state will be appendend to message and will be used by + * receiver to decrypt the message in question. To avoid cache misses + * store the current state close to EVP_CIPHER_CTX */ + C_STRUCT(q_securityHeader) securityHeader; /* holds the state */ +}; + + +C_STRUCT(q_securityDecoderSet) { + os_uint32 nofPartitions; + q_securityPartitionDecoder decoders; +}; + +C_STRUCT(q_securityEncoderSet) { + os_uint32 nofPartitions; + os_uint32 headerSizeMax; + q_securityPartitionEncoder encoders; +}; + + +#if 1 +/* no dumping of buffer before and after en-/decrypting */ +#define DUMP_BUFFER(partitionName,chan,buffer,length,label,counter,counterLength, bufferLength) +#else +/* Use this line to dump to the ddsi tracefile */ +#define DUMP_BUFFER(partitionName,chan,buffer,length,label,counter,counterLength,bufferLenght) tdumpBuffer(partitionName,chan,buffer,length,label,counter,counterLength, bufferLength) +/* Use this line to dump to a file in the /tmp/directory */ +#define DUMP_BUFFER(partitionName,chan,buffer,length,label,counter,counterLength,bufferLenght) dumpBuffer(partitionName,chan,buffer,length,label,counter,counterLength, bufferLength) +#endif + +/** private operations */ +#if OPENSSL_VERSION_NUMBER < 0x10100000 +#include +static void *OPENSSL_zalloc(size_t num) +{ + void *ret = OPENSSL_malloc(num); + + if (ret != NULL) + memset(ret, 0, num); + return ret; +} + +EVP_MD_CTX *EVP_MD_CTX_new(void) +{ + return OPENSSL_zalloc(sizeof(EVP_MD_CTX)); +} + +void EVP_MD_CTX_free(EVP_MD_CTX *ctx) +{ + EVP_MD_CTX_cleanup(ctx); + OPENSSL_free(ctx); +} +#if OPENSSL_VERSION_NUMBER < 0x0090800f +EVP_CIPHER_CTX *EVP_CIPHER_CTX_new(void) +{ + return OPENSSL_zalloc(sizeof(EVP_CIPHER_CTX)); +} + +void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx) +{ + EVP_CIPHER_CTX_cleanup(ctx); + OPENSSL_free(ctx); +} +#endif +#endif + +#if 0 +static void dumpCounter (FILE *of, unsigned char* counter, int counterLength) +{ + int i = 0; + if (counter) { + for (i=0; iheaderSizeMax; +} + +#if !LITE +/** + * Convert the binary hash of a certificate's fingerprint to + * base64 format, for printing it (e.g. log mesages) + **/ +char* binaryToBase64(const char* data, os_size_t len) +{ + BIO* b64 = NULL; + BIO* bio = NULL; + char* encoded = NULL; + os_size_t encodedLen = 0; + char* result = NULL; + + /* encode to Base64 */ + b64 = BIO_new( BIO_f_base64() ); + /* no new line on end */ + BIO_set_flags( b64, BIO_FLAGS_BASE64_NO_NL ); + bio = BIO_new( BIO_s_mem() ); + bio = BIO_push( b64, bio ); + (void)BIO_write( bio, data, (int)len); + (void)BIO_flush( bio ); /* tell b64 that no more data follows */ + + /* encoded stays owned by openssl */ + encodedLen = (os_size_t) BIO_get_mem_data(bio, &encoded); + + result = (char*)os_malloc(encodedLen+1); + memcpy(result,encoded,encodedLen); + result[encodedLen] = 0; + + BIO_free_all(bio); + + return result; +} + +#endif + +static c_bool decoderIsBlocked (q_securityPartitionDecoder codec) +{ + return (IS_DROP_STATE(codec->state) > 0); +} + +static c_bool encoderIsBlocked (q_securityPartitionEncoder codec) +{ + return (IS_DROP_STATE(codec->state) > 0); +} + +/* returns -1 on error */ +static short hex2bin(char hexChar) +{ + switch (hexChar) { + case '0': return 0; + case '1': return 1; + case '2': return 2; + case '3': return 3; + case '4': return 4; + case '5': return 5; + case '6': return 6; + case '7': return 7; + case '8': return 8; + case '9': return 9; + + case 'a': return 10; + case 'b': return 11; + case 'c': return 12; + case 'd': return 13; + case 'e': return 14; + case 'f': return 15; + + case 'A': return 10; + case 'B': return 11; + case 'C': return 12; + case 'D': return 13; + case 'E': return 14; + case 'F': return 15; + default: + return -1; /* error */ + } +} + +/* returns NULL on error, eg bad hex-string */ +static c_bool hex2key +( + const char* hexKey, + os_uint32 expectedLength, + unsigned char *result /* out */ ) +{ + size_t i, len=0; + short val; + + len = strlen(hexKey); + + for (i=0; i 0) return "unknown"; + else return "ok"; +} + +/* this function is based on original code of + * components/configuration/parser/code/cfg_parser.y */ + +static c_bool q_securityResolveCipherKeyFromUri +( + const char *uriStr, + os_uint32 expectedLength, + unsigned char *cipherKey /* out buffer */ +) +{ + char *filename; + FILE *file = NULL; + char readBuffer[256]; /*at most strings of 255 chars */ + char *hexStr = NULL; + int ret; + c_bool result = FALSE; + + if ((uriStr != NULL) && + (strncmp(uriStr, URI_FILESCHEMA, strlen(URI_FILESCHEMA)) == 0)) { + + /* TBD: compare file-permissions with uid/gid of this process, the + * file should be protected against read/write by others, otherwise we + * should refuse to read from it */ + const char *justPath = + (char *)(uriStr + strlen(URI_FILESCHEMA)); + +#if LITE + filename = os_strdup (justPath); +#else + filename = os_fileNormalize(justPath); +#endif + file = fopen(filename, "r"); + if (file) { + /* read at most 255 chars from file, this should suffice if the + * secret key has atmost 32 chars */ + ret = fscanf (file, "%255s", readBuffer); + + if (ret != EOF) + { + /* skip leading white spaces */ + for (hexStr=readBuffer; + isspace((unsigned char) *hexStr); + ++hexStr); + + result = hex2key(hexStr, expectedLength, cipherKey); + } + + fclose(file); + } else { + NN_ERROR1("q_securityResolveCipherKeyFromUri: Could not open %s",uriStr); + } + + os_free(filename); + + } else if (uriStr != NULL) { + /* seems to be a hex string */ + result = hex2key(uriStr, expectedLength, cipherKey); + } + + return result; +} + + +/* Validate the cipherkey, parsing the hex-string directly or the content of + * file */ +static c_bool q_securityIsValidCipherKeyUri +( + q_cipherType cipherType, + const char* cipherKeyUri +) +{ + unsigned char tmpCipherKey[Q_MAX_KEY_LENGTH]; /* transient */ + os_uint32 expectedLength = q_securityCipherKeyLength(cipherType); + + assert(expectedLength > 0); + + /* we are not interested in the key, jsut doing the syntax check */ + return q_securityResolveCipherKeyFromUri(cipherKeyUri, expectedLength, tmpCipherKey); +} + +/* compare cipherName to known identifiers, comparison is case-insensitive */ +static c_bool q_securityCipherTypeFromString(const char* cipherName, + q_cipherType *cipherType) /* out */ +{ + if (cipherName == NULL) + { + NN_ERROR0("q_securityCipherTypeFromString:internal error, empty cipher string"); + *cipherType = Q_CIPHER_UNDEFINED; + return FALSE; + } + + if (os_strcasecmp(cipherName, "null") == 0) { + *cipherType = Q_CIPHER_NULL; + } else if (os_strcasecmp(cipherName, "blowfish") == 0 || + os_strcasecmp(cipherName, "blowfish-sha1") == 0) { + *cipherType = Q_CIPHER_BLOWFISH; + } else if (os_strcasecmp(cipherName, "aes128") == 0 || + os_strcasecmp(cipherName, "aes128-sha1") == 0) { + *cipherType = Q_CIPHER_AES128; + } else if (os_strcasecmp(cipherName, "aes192") == 0 || + os_strcasecmp(cipherName, "aes192-sha1") == 0) { + *cipherType = Q_CIPHER_AES192; + } else if (os_strcasecmp(cipherName, "aes256") == 0 || + os_strcasecmp(cipherName, "aes256-sha1") == 0) { + *cipherType = Q_CIPHER_AES256; +#if 0 + } else if (os_strcasecmp(cipherName, "rsa-null") == 0) { + *cipherType = Q_CIPHER_RSA_WITH_NULL; + } else if (os_strcasecmp(cipherName, "rsa-blowfish") == 0 || + os_strcasecmp(cipherName, "rsa-blowfish-sha1") == 0) { + *cipherType = Q_CIPHER_RSA_WITH_BLOWFISH; + } else if (os_strcasecmp(cipherName, "rsa-aes128") == 0 || + os_strcasecmp(cipherName, "rsa-aes128-sha1") == 0) { + *cipherType = Q_CIPHER_RSA_WITH_AES128; + } else if (os_strcasecmp(cipherName, "rsa-aes192") == 0 || + os_strcasecmp(cipherName, "rsa-aes192-sha1") == 0) { + *cipherType = Q_CIPHER_RSA_WITH_AES192; + } else if (os_strcasecmp(cipherName, "rsa-aes256") == 0 || + os_strcasecmp(cipherName, "rsa-aes256-sha1") == 0) { + *cipherType = Q_CIPHER_RSA_WITH_AES256; +#endif + } else { + *cipherType = Q_CIPHER_UNDEFINED; + return FALSE; + } + return TRUE; +} + +static os_uint32 cipherTypeToHeaderSize(q_cipherType cipherType) { + switch (cipherType) { + case Q_CIPHER_UNDEFINED: + case Q_CIPHER_NONE: + return 0; + case Q_CIPHER_NULL: + return sizeof(C_STRUCT(q_nullHeader)); + + case Q_CIPHER_BLOWFISH: + return sizeof(C_STRUCT(q_sha1Header)) + + sizeof(C_STRUCT(q_blowfishHeader)); + + case Q_CIPHER_AES128: + case Q_CIPHER_AES192: + case Q_CIPHER_AES256: + return sizeof(C_STRUCT(q_sha1Header)) + + sizeof(C_STRUCT(q_aesHeader)); + + default: + assert(0 && "unsupported cipher"); + } + + assert(FALSE); + return 0; +} + +/*these two methods are not static for the moment because of tests*/ + +#if LITE +static +#endif +void q_securityRNGSeed (void) +{ + os_timeM time=os_timeMGet(); + RAND_seed((const void *)&time,sizeof(os_timeM)); +} + +#if LITE +static +#endif +void q_securityRNGGetRandomNumber(int number_length,unsigned char * randNumber) +{ + RAND_bytes(randNumber,number_length); +} + + +static +c_bool +q_securityPartitionEncoderInit(q_securityPartitionEncoder encoder,struct config_networkpartition_listelem *p) +{ + unsigned char cipherKey[Q_MAX_KEY_LENGTH]; + char *cipherKeyURL = p->securityProfile?p->securityProfile->key:NULL; + os_char * partitionName = p->name; + c_bool connected = (c_bool) p->connected; + q_cipherType cipherType = p->securityProfile?p->securityProfile->cipher: Q_CIPHER_NONE; + os_uint32 hash = p->partitionHash; + os_uint32 partitionId = p->partitionId; + + /* init */ + memset(encoder, 0, sizeof(*encoder)); + memset(cipherKey, 0, sizeof(*cipherKey)); + + + if (!connected) { + TRACE(("Network Partition '%s' (%d) not connected, dropping outbound traffic permanently", partitionName, partitionId)); + + encoder->state = Q_CODEC_STATE_DROP_PERM; + encoder->cipherType = Q_CIPHER_UNDEFINED; + encoder->partitionName = partitionName; + + return TRUE; + } + + assert(cipherType != Q_CIPHER_UNDEFINED); + + { + /* init the cipher */ + + const os_uint32 partitionHashNetworkOrder = htonl(hash); + const q_cipherType cipherTypeNetworkOrder = htonl(cipherType); + const unsigned char *iv = NULL; /* ignored by ECBs ciphers */ + const EVP_CIPHER *cipher = NULL; + const os_uint32 cipherKeyLength = q_securityCipherKeyLength(cipherType); + unsigned char randCounter[Q_KEYID_LENGTH]; + + /*TRACE(("Security Encoder init: partition '%s' (%d) (connected), cipherType %d, cipherKey %s\n", + partitionName,partitionId, cipherType, cipherKeyURL));*/ + + encoder->state = Q_CODEC_STATE_OK; + encoder->cipherKeyURL = cipherKeyURL; /* const, required for re-keying */ + encoder->cipherType = cipherType; + encoder->partitionName = partitionName; /* const */ + + q_securityRNGGetRandomNumber(Q_KEYID_LENGTH, randCounter); + + switch (cipherType) { + case Q_CIPHER_NULL: + case Q_CIPHER_NONE: + cipher = EVP_enc_null(); + encoder->securityHeader.u.null.cipherType = cipherTypeNetworkOrder; + encoder->securityHeader.u.null.partitionId = partitionHashNetworkOrder; + break; + + case Q_CIPHER_BLOWFISH: + cipher = EVP_bf_ecb(); + assert(8 == EVP_CIPHER_block_size(cipher)); + assert(16 == cipherKeyLength); + + encoder->securityHeader.u.blowfish.cipherType = cipherTypeNetworkOrder; + encoder->securityHeader.u.blowfish.partitionId = partitionHashNetworkOrder; + + memcpy(encoder->securityHeader.u.blowfish.counter,&randCounter, sizeof(randCounter)); + break; + + case Q_CIPHER_AES128: + cipher = EVP_aes_128_ecb(); + assert(16 == EVP_CIPHER_block_size(cipher)); + assert(16 == cipherKeyLength); + + encoder->securityHeader.u.aes.cipherType = cipherTypeNetworkOrder; + encoder->securityHeader.u.aes.partitionId = partitionHashNetworkOrder; + + memcpy(encoder->securityHeader.u.aes.counter, &randCounter, sizeof(randCounter)); + break; + + case Q_CIPHER_AES192: + cipher = EVP_aes_192_ecb(); + + assert(16 == EVP_CIPHER_block_size(cipher)); + assert(24 == cipherKeyLength); + + encoder->securityHeader.u.aes.cipherType = cipherTypeNetworkOrder; + encoder->securityHeader.u.aes.partitionId = partitionHashNetworkOrder; + + memcpy(encoder->securityHeader.u.aes.counter, &randCounter, sizeof(randCounter)); + break; + + case Q_CIPHER_AES256: + cipher = EVP_aes_256_ecb(); + + assert(16 == EVP_CIPHER_block_size(cipher)); + assert(32 == cipherKeyLength); + + encoder->securityHeader.u.aes.cipherType = cipherTypeNetworkOrder; + encoder->securityHeader.u.aes.partitionId = partitionHashNetworkOrder; + + memcpy(encoder->securityHeader.u.aes.counter, &randCounter, sizeof(randCounter)); + break; + + default: + assert(0 && "never reach"); + } + + /* intitialize the key-buffer */ + if (cipherType != Q_CIPHER_NULL && cipherType != Q_CIPHER_NONE && + !q_securityResolveCipherKeyFromUri(cipherKeyURL,cipherKeyLength,cipherKey)) { + NN_ERROR2("DDSI Security Encoder: dropping traffic of partition '%s' (%d) due to invalid cipher key", + encoder->partitionName, partitionId); + encoder->state = Q_CODEC_STATE_DROP_TEMP; + } + + encoder->cipherContext = EVP_CIPHER_CTX_new(); + + EVP_EncryptInit_ex(encoder->cipherContext, + cipher, + NULL, + cipherKey, + iv); /* IV is ignored by ECB ciphers */ + } + + return TRUE; +} + + +static +c_bool +q_securityPartitionEncoderFini(q_securityPartitionEncoder encoder) +{ + if (encoder->cipherType != Q_CIPHER_UNDEFINED) { + /* release the cipher */ + EVP_CIPHER_CTX_free(encoder->cipherContext); + } + + return TRUE; +} + +static +c_bool +q_securityPartitionDecoderInit(q_securityPartitionDecoder decoder,struct config_networkpartition_listelem *p) +{ + unsigned char cipherKey[Q_MAX_KEY_LENGTH]; + char *cipherKeyURL = p->securityProfile?p->securityProfile->key:NULL; + os_char * partitionName = p->name; + c_bool connected = (c_bool) p->connected; + q_cipherType cipherType = p->securityProfile?p->securityProfile->cipher: Q_CIPHER_NONE; + os_uint32 partitionId = p->partitionId; + + + /* init */ + memset(decoder, 0, sizeof(*decoder)); + memset(cipherKey, 0, sizeof(cipherKey)); + + if (!connected) { + TRACE(("Network Partition '%s' (%d) not connected, dropping inbound traffic permanently\n", partitionName, partitionId)); + + decoder->state = Q_CODEC_STATE_DROP_PERM; + decoder->cipherType = Q_CIPHER_UNDEFINED; + decoder->partitionName = partitionName; + return TRUE; + } + + + assert(cipherType != Q_CIPHER_UNDEFINED); + + { + /* init the cipher */ + const unsigned char *iv = NULL; /* ignored by ECBs ciphers */ + const EVP_CIPHER *cipher = NULL; + const os_uint32 cipherKeyLength = q_securityCipherKeyLength(cipherType); + + /*TRACE(("Security Decoder init: partition '%s' (%d) (connected), cipherType %d, cipherKey %s \n", + partitionName,partitionId, cipherType, cipherKeyURL));*/ + + decoder->state = Q_CODEC_STATE_OK; + decoder->cipherKeyURL = cipherKeyURL; /* const, required for re-keying */ + decoder->cipherType = cipherType; + decoder->partitionName = partitionName; /* const */ + + switch (cipherType) { + case Q_CIPHER_NULL: + case Q_CIPHER_NONE: + cipher = EVP_enc_null(); + break; + + case Q_CIPHER_BLOWFISH: + cipher = EVP_bf_ecb(); + + assert(8 == EVP_CIPHER_block_size(cipher)); + assert(16 == cipherKeyLength); + break; + + case Q_CIPHER_AES128: + cipher = EVP_aes_128_ecb(); + + assert(16 == EVP_CIPHER_block_size(cipher)); + assert(16 == cipherKeyLength); + break; + + case Q_CIPHER_AES192: + cipher = EVP_aes_192_ecb(); + + assert(16 == EVP_CIPHER_block_size(cipher)); + assert(24 == cipherKeyLength); + break; + + case Q_CIPHER_AES256: + cipher = EVP_aes_256_ecb(); + + assert(16 == EVP_CIPHER_block_size(cipher)); + assert(32 == cipherKeyLength); + break; + + default: + assert(0 && "never reach"); + } + + /* init key-buffer from URL */ + if (cipherType != Q_CIPHER_NULL && cipherType != Q_CIPHER_NONE && + !q_securityResolveCipherKeyFromUri(cipherKeyURL,cipherKeyLength,cipherKey)) { + NN_ERROR2("DDSI Security Decoder: dropping traffic of partition '%s' (%d) due to invalid cipher key", + decoder->partitionName, partitionId); + /* can be solved by re-keying, rewriting the file */ + decoder->state = Q_CODEC_STATE_DROP_TEMP; + } + + decoder->cipherContext = EVP_CIPHER_CTX_new(); + + EVP_EncryptInit_ex(decoder->cipherContext, + cipher, + NULL, + cipherKey, + iv); /* IV is ignored by ECB ciphers */ + + } + + return TRUE; +} + + +static c_bool q_securityPartitionDecoderFini (q_securityPartitionDecoder decoder) +{ + if (decoder->cipherType != Q_CIPHER_UNDEFINED) { + /* release the cipher */ + EVP_CIPHER_CTX_free(decoder->cipherContext); + } + + return 1; /* true */ +} + +/* returns NULL on error */ + +static q_securityEncoderSet q_securityEncoderSetNew (void) +{ + const os_uint32 nofPartitions = config.nof_networkPartitions; + + q_securityEncoderSet result = + os_malloc(sizeof(C_STRUCT(q_securityEncoderSet))); + + if (!result) { + return NULL; + } + + result->nofPartitions = 0; /* init */ + result->headerSizeMax = 0; + if (nofPartitions == 0) { + result->encoders = NULL; + } else { + result->encoders = os_malloc(sizeof(C_STRUCT(q_securityPartitionEncoder)) * nofPartitions); + memset(result->encoders, + 0, + sizeof(C_STRUCT(q_securityPartitionEncoder)) * + nofPartitions); + } + + /* if not done yet, init the RNG within this thread*/ + if(!RAND_status()) { + q_securityRNGSeed(); + } + + /* init each codec per network parition */ + { + q_securityPartitionEncoder currentEncoder = NULL; + os_uint32 headerSizeProfile = 0; + + struct config_networkpartition_listelem *p = config.networkPartitions; + + while (p) { + + currentEncoder = + &(result->encoders[p->partitionId-1]); + + if (p->securityProfile) { + if (!q_securityPartitionEncoderInit(currentEncoder,p)) { + /* the codec config is faulty, the codec has been set into + * DROP_TERMP or DROP_PERM state, depending on the kind of + * fault. Continue to intitialize remaining codecs */ + NN_ERROR2("q_securityEncoderSet:failed to initialize codec of partition '%s' (%d)\n", + p->name,p->partitionId ); + } + + TRACE(("Network Partition '%s' (%d) encoder secured by %s cipher, in status '%s'\n", + p->name, + p->partitionId, + cipherTypeAsString(currentEncoder->cipherType), + stateAsString(currentEncoder->state))); + + headerSizeProfile = cipherTypeToHeaderSize(currentEncoder->cipherType); + result->headerSizeMax = (headerSizeProfile > (result->headerSizeMax)) ? headerSizeProfile: (result->headerSizeMax); + result->headerSizeMax = (result->headerSizeMax + 4u) & ~4u; /* enforce mutiple of 4 */ + } else { + memset(currentEncoder, 0, sizeof(*currentEncoder)); + currentEncoder->state = Q_CODEC_STATE_DROP_PERM; + currentEncoder->cipherType = Q_CIPHER_NONE; + currentEncoder->partitionName = p->name; + + TRACE(("Network Partition '%s' (%d) is not secured by a cipher\n", + p->name, + p->partitionId)); + } + /* count up step by step, so in case of error + * q_securityEncoderSetFree will only iterate those already + * intialized */ + ++(result->nofPartitions); + p = p->next; + + } + + + TRACE(("reserving %d bytes for security header\n", result->headerSizeMax)); + + } + + return result; +} + +/* returns NULL on error */ + +static q_securityDecoderSet q_securityDecoderSetNew (void) +{ + q_securityDecoderSet result; + const os_uint32 nofPartitions = config.nof_networkPartitions; + + if (nofPartitions == 0) + { + return NULL; + } + + result = os_malloc (sizeof(C_STRUCT(q_securityDecoderSet))); + result->nofPartitions = 0; + + result->decoders = + os_malloc(sizeof(C_STRUCT(q_securityPartitionDecoder)) * nofPartitions); + + /* init the memory region */ + memset(result->decoders, + 0, + sizeof(C_STRUCT(q_securityPartitionDecoder)) * + nofPartitions); + + /* if not done yet, init the RNG within this thread*/ + if(!RAND_status()) { + q_securityRNGSeed(); + } + + /* init codec per network partition */ + { + q_securityPartitionDecoder currentDecoder = NULL; + + struct config_networkpartition_listelem *p = config.networkPartitions; + + while (p) { + currentDecoder = + &(result->decoders[p->partitionId-1]); + if ( p->securityProfile ) { + if (!q_securityPartitionDecoderInit(currentDecoder,p)) { + /* the codec config is faulty, the codec has been set into + * DROP_TERMP or DROP_PERM state, depending on the kind of + * fault. Continue to intitialize remaining codecs */ + NN_ERROR2("q_securityDecoderSet:failed to initialize codec of partition '%s' (%d)\n", + p->name,p->partitionId); + } + + TRACE(("Network Partition '%s' (%d) decoder secured by %s cipher, in status '%s'\n", + p->name, + p->partitionId, + cipherTypeAsString(currentDecoder->cipherType), + stateAsString(currentDecoder->state))); + } else { + memset(currentDecoder, 0, sizeof(*currentDecoder)); + currentDecoder->state = Q_CODEC_STATE_DROP_PERM; + currentDecoder->cipherType = Q_CIPHER_NONE; + currentDecoder->partitionName = p->name; + + TRACE(("Network Partition '%s' (%d) is not secured by a cipher\n", + p->name, + p->partitionId)); + } + /* count up step by step, so in case of error + * q_securityEncoderSetFree will only iterate those already + * intialized */ + ++(result->nofPartitions); + p = p->next; + } + } + + return result; + +} + +static c_bool q_securityEncoderSetFree (q_securityEncoderSet codec) +{ + q_securityPartitionEncoder currentEncoder = NULL; + os_uint32 ix; + + if (!codec) { + /* parameter is NULL */ + return TRUE; + } + + for (ix=0; ixnofPartitions; ++ix) { + currentEncoder = + &(codec->encoders[ix]); + + q_securityPartitionEncoderFini(currentEncoder); + } + os_free(codec->encoders); + os_free(codec); + + return 1; /* true */ +} + +static c_bool q_securityDecoderSetFree (q_securityDecoderSet codec) +{ + q_securityPartitionDecoder currentDecoder = NULL; + os_uint32 ix; + + if (!codec) { + /* parameter is NULL */ + return TRUE; + } + + for (ix=0; ixnofPartitions; ++ix) { + currentDecoder = + &(codec->decoders[ix]); + + q_securityPartitionDecoderFini(currentDecoder); + } + os_free(codec->decoders); + os_free(codec); + + return TRUE; /* true */ +} + +static os_uint32 q_securityEncoderHeaderSize (q_securityEncoderSet codec, os_uint32 partitionId) +{ + assert(partitionId > 0); + if (!codec) { + /* security not initialized or disabled */ + return 0; + } + assert(partitionId <= codec->nofPartitions); + return cipherTypeToHeaderSize(codec->encoders[partitionId-1].cipherType); +} + +static q_cipherType q_securityEncoderCipherType (q_securityEncoderSet codec, os_uint32 partitionId) +{ + assert(partitionId > 0); + if (!codec) { + /* security not initialized or disabled */ + return 0; + } + assert(partitionId <= codec->nofPartitions); + return codec->encoders[partitionId-1].cipherType; +} + + + +/* returns 0 on error, otherwise 1, */ +static c_bool counterEncryptOrDecryptInPlace +( + EVP_CIPHER_CTX *ctx, + unsigned char *counter, /* in/out */ + unsigned char *buffer, + int length +) +{ + int i, j, num; + int where = 0; + int bl = EVP_CIPHER_CTX_block_size(ctx); + unsigned char keyStream[Q_BLOCK_SIZE_MAX]; + + /* <= is correct, so that we handle any possible non-aligned data */ + for (i = 0; i <= length / bl && where < length; ++i) { + /* encrypt the current counter */ + if (!EVP_EncryptUpdate(ctx, keyStream, &num, counter, bl)) { /* ECB encrypts exactly 'bl' bytes */ + + NN_WARNING3("Incoming encrypted sub-message dropped: Decrypt failed (bufferLength %u, blockSize %u, where %u)",length, bl, where); + + return FALSE; + } + + /* use the keystream to encrypt a single block of buffer */ + { + if ( ((int) (length - where)) < bl) { + /* non aligned data, encrypt remaining block-fragment only */ + for (j = 0; j < ((int) (length - where)); ++j) { + buffer[where+j] ^= keyStream[j]; + } + } else { + /* default case, encrypt full block */ + for (j = 0; j < bl; ++j) { + buffer[where+j] ^= keyStream[j]; + } + } + } + + /* increment the counter, remember it's an array of single characters */ + for (j = Q_KEYID_LENGTH; j < bl; ++j) { /*the four first bytes=random value. It is kept unchanged */ + if (++(counter[j])) + break; + } + + where += num; + } + + return TRUE; +} + + +static void +attachHeaderAndDoSha1(unsigned char* data, os_uint32 dataLength, + const void *symCipherHeader, os_uint32 symCipherHeaderLength) +{ + const os_uint32 sha1HeaderLength = sizeof(C_STRUCT(q_sha1Header)); + const os_uint32 overallLength = dataLength + + sha1HeaderLength + + symCipherHeaderLength; + + unsigned char md[Q_DIGEST_LENGTH]; + + /* put the fixed attributes into buffer to calculate the digest */ + void *digStart = &(data[dataLength]); + void *cipStart = &(data[dataLength + sha1HeaderLength]); + + memset(digStart, 0, sha1HeaderLength); /* zero out */ + memcpy(cipStart, symCipherHeader, symCipherHeaderLength); + + /* calculate over complete send buffer */ + Q_SHA1(data, overallLength, md); + + /* Finally place the (half of) digest */ + memcpy(digStart, md, Q_DIGEST_LENGTH_2); +} + +static void +attachHeader(unsigned char* data, os_uint32 dataLength, + const void *symCipherHeader, os_uint32 symCipherHeaderLength) +{ + /* pur the fixed attributes into buffer to calculate the digest */ + void *cipStart = &(data[dataLength]); + memcpy(cipStart, symCipherHeader, symCipherHeaderLength); +} + +static c_bool +verifySha1(unsigned char* data, os_uint32 dataLength, void *digStart) +{ + const os_uint32 sha1HeaderLength = sizeof(C_STRUCT(q_sha1Header)); + C_STRUCT(q_sha1Header) sha1Header; + unsigned char md[Q_DIGEST_LENGTH]; + + /* backup the sha1 digest */ + memcpy(&sha1Header, digStart, sha1HeaderLength); + + /* zero out the bytes in buffer */ + memset(digStart, 0, sha1HeaderLength); + + /* verify digest */ + Q_SHA1(data, dataLength, md); + + return !memcmp(md, sha1Header.hash, Q_DIGEST_LENGTH_2); +} + +static c_bool q_securityEncodeInPlace_Generic +( + q_securityPartitionEncoder encoder, + os_uint32 partitionId, /* debugging */ + unsigned char *buffer, + os_uint32 *dataLength, /* in/out */ + os_uint32 bufferLength /* for debug */ +) +{ + const os_uint32 overallHeaderSize = cipherTypeToHeaderSize(encoder->cipherType); + + EVP_CIPHER_CTX *ctx = encoder->cipherContext; + unsigned char *plainText = buffer; + os_uint32 plainTextLength = *dataLength; + c_bool result = TRUE; + + + TRACE((":ENCRYPT:'%s'(%d)",encoder->partitionName, partitionId)); + + (void) bufferLength; + + switch (encoder->cipherType) { + case Q_CIPHER_NULL: { + const os_uint32 symCipherHeaderLength = sizeof(C_STRUCT(q_nullHeader)); + + q_nullHeader symCipherHeader = &((encoder->securityHeader).u.null); + + DUMP_BUFFER(encoder->partitionName, partitionId, buffer, *dataLength, "encode->", + NULL, Q_NULL_COUNTER_SIZE, bufferLength); + + attachHeader(plainText, plainTextLength, + symCipherHeader, symCipherHeaderLength); + + TRACE((":NULL:%s", result?"OK":"ERROR")); /* debug */ + + DUMP_BUFFER(encoder->partitionName, partitionId, buffer, *dataLength+overallHeaderSize, "<-encode", NULL, + Q_NULL_COUNTER_SIZE, bufferLength); + } + break; + + case Q_CIPHER_BLOWFISH: { + const os_uint32 symCipherHeaderLength = sizeof(C_STRUCT(q_blowfishHeader)); + q_blowfishHeader symCipherHeader = &((encoder->securityHeader).u.blowfish); + unsigned char *counter = symCipherHeader->counter; + + DUMP_BUFFER(encoder->partitionName, partitionId, buffer, *dataLength, "encode->", counter, + Q_BLOWFISH_COUNTER_SIZE, bufferLength); + + attachHeaderAndDoSha1(plainText, plainTextLength, + symCipherHeader, symCipherHeaderLength); + + /* encrypt load and digest */ + result = counterEncryptOrDecryptInPlace(ctx, + counter, + plainText, + (int) (plainTextLength + sizeof(C_STRUCT(q_sha1Header)))); + + TRACE((":BLF:%s", result?"OK":"ERROR")); /* debug */ + + DUMP_BUFFER(encoder->partitionName, partitionId, buffer, *dataLength+overallHeaderSize, "<-encode", counter, + Q_BLOWFISH_COUNTER_SIZE, bufferLength); + } + break; + + case Q_CIPHER_AES128: + case Q_CIPHER_AES192: + case Q_CIPHER_AES256: { + const os_uint32 symCipherHeaderLength = sizeof(C_STRUCT(q_aesHeader)); + q_aesHeader symCipherHeader = &((encoder->securityHeader).u.aes); + unsigned char *counter = symCipherHeader->counter; + + DUMP_BUFFER(encoder->partitionName, partitionId, buffer, *dataLength, "encode->", counter, + Q_AES_COUNTER_SIZE, bufferLength); + + attachHeaderAndDoSha1(plainText, plainTextLength, + symCipherHeader, symCipherHeaderLength); + + /* encrypt load and digest */ + result = counterEncryptOrDecryptInPlace(ctx, + counter, + plainText, + (int) (plainTextLength + sizeof(C_STRUCT(q_sha1Header)))); + + TRACE((":AES:%s", result?"OK":"ERROR")); /* debug */ + + DUMP_BUFFER(encoder->partitionName, partitionId, buffer, *dataLength+overallHeaderSize, "<-encode", counter, + Q_AES_COUNTER_SIZE, bufferLength); + } + break; + default: + assert(0 && "do not reach"); + } + TRACE((":(%d->%d)", *dataLength, *dataLength + overallHeaderSize)); + + *dataLength += overallHeaderSize; + return result; +} + + +static c_bool q_securityDecodeInPlace_Generic +( + q_securityPartitionDecoder decoder, + os_uint32 partitionId, + unsigned char *buffer, + os_uint32 *dataLength, /* in/out */ + q_cipherType sendersCipherType, + os_uint32 bufferLength +) +{ + const os_uint32 overallHeaderSize = cipherTypeToHeaderSize(sendersCipherType); + EVP_CIPHER_CTX *ctx = decoder->cipherContext; + c_bool result = TRUE; + + TRACE((":DECRYPT:'%s'(%d)",decoder->partitionName, partitionId)); + + (void) bufferLength; + + switch (sendersCipherType) { + case Q_CIPHER_NULL: + { + DUMP_BUFFER(decoder->partitionName, partitionId, buffer, *dataLength, "decode->", + NULL, + Q_NULL_COUNTER_SIZE, bufferLength); + + /* nothing todo here, just decreasing the buffer length at end of this function */ + TRACE((":NULL:%s", result?"OK":"ERROR")); /* debug */ + + DUMP_BUFFER(decoder->partitionName, partitionId, buffer, *dataLength - overallHeaderSize, "<-decode", + NULL, + Q_NULL_COUNTER_SIZE, bufferLength); + } + break; + + case Q_CIPHER_BLOWFISH: + { + const os_uint32 sha1HeaderLength = sizeof(C_STRUCT(q_sha1Header)); + const os_uint32 cipherTextLength = *dataLength - overallHeaderSize + sha1HeaderLength; + C_STRUCT(q_blowfishHeader) symCipherHeader; + + void *cipherText = buffer; + void *sha1HeaderStart = &(buffer[*dataLength - overallHeaderSize]); + void *symCipherHeaderStart = &(buffer[*dataLength - overallHeaderSize + sha1HeaderLength]); + + /* copy from buffer into aligned memory */ + memcpy(&symCipherHeader, symCipherHeaderStart, sizeof(C_STRUCT(q_blowfishHeader))); + + DUMP_BUFFER(decoder->partitionName, partitionId, buffer, *dataLength, "decode->", symCipherHeader.counter,Q_BLOWFISH_COUNTER_SIZE, bufferLength); + + /* decrypt the load and the digest */ + result = counterEncryptOrDecryptInPlace(ctx, + symCipherHeader.counter, + cipherText, + (int) cipherTextLength); + if (result) { + /* will zero out the sha1Header values in buffer */ + result = verifySha1(cipherText, *dataLength, sha1HeaderStart); + TRACE((":BLF:%s", result?"OK":"ERROR")); /* debug */ + if (!result) { + NN_WARNING1("Incoming encrypted sub-message dropped: Decrypt (blowfish) verification failed for partition '%s' - possible Key-mismatch", decoder->partitionName); + } + } + + DUMP_BUFFER(decoder->partitionName, partitionId, buffer, *dataLength - overallHeaderSize, "<-decode",symCipherHeader.counter, Q_BLOWFISH_COUNTER_SIZE, bufferLength); + } + break; + + case Q_CIPHER_AES128: + case Q_CIPHER_AES192: + case Q_CIPHER_AES256: + { + const os_uint32 sha1HeaderLength = sizeof(C_STRUCT(q_sha1Header)); + const os_uint32 cipherTextLength = *dataLength - overallHeaderSize + sha1HeaderLength; + C_STRUCT(q_aesHeader) symCipherHeader; + + void *cipherText = buffer; + void *sha1HeaderStart = &(buffer[*dataLength - overallHeaderSize]); + void *symCipherHeaderStart = &(buffer[*dataLength - overallHeaderSize + sha1HeaderLength]); + + /* copy from buffer into aligned memory */ + memcpy(&symCipherHeader, symCipherHeaderStart, sizeof(C_STRUCT(q_aesHeader))); + + DUMP_BUFFER(decoder->partitionName, partitionId, buffer, *dataLength, "decode->",symCipherHeader.counter, Q_AES_COUNTER_SIZE, bufferLength); + + /* decrypt the load and the digest */ + result = counterEncryptOrDecryptInPlace(ctx, + symCipherHeader.counter, + cipherText, + (int) cipherTextLength); + if ( result){ + /* will zero out the sha1Header values in buffer */ + result = verifySha1(cipherText, *dataLength, sha1HeaderStart); + TRACE((":AES:%s", result?"OK":"ERROR")); /* debug */ + if (!result) { + NN_WARNING1("Incoming encrypted sub-message dropped: Decrypt (AES) verification failed for partition '%s' - possible Key-mismatch", decoder->partitionName); + } + } + + DUMP_BUFFER(decoder->partitionName, partitionId, buffer, *dataLength - overallHeaderSize, "<-decode", symCipherHeader.counter, Q_AES_COUNTER_SIZE, bufferLength); + } + break; + default: + assert(0 && "do not reach"); + } + + TRACE((":(%d->%d)", *dataLength, *dataLength - overallHeaderSize)); + + *dataLength -= overallHeaderSize; /* out */ + + return result; +} + + + +/* returns 0 on error, otherwise 1, + @param codec the security context object + @param partitionId defines the security policy to be used + @param buffer with content, with reserved space at end + @param fragmentLength overall length of buffer + @param dataLength the occupied space of buffer, must leave enough space for security attribute header */ + +static c_bool q_securityEncodeInPlace +( + q_securityEncoderSet codec, + os_uint32 partitionId, + void *buffer, + os_uint32 fragmentLength, + os_uint32 *dataLength /* in/out */ +) +{ + q_securityPartitionEncoder encoder = NULL; + os_uint32 overallHeaderSize; + c_bool result = FALSE; + + assert(codec); + + + if (partitionId == 0 || partitionId > codec->nofPartitions) { + /* if partitionId is larger than number of partitions, network service + * seems to be in undefined state */ + NN_ERROR1("q_securityEncodeInPlace:Sending message blocked, bad partitionid '%d'", + partitionId); + return FALSE; + } + + encoder = &(codec->encoders[partitionId-1]); + + + if (encoderIsBlocked(encoder)) { + NN_ERROR1("q_securityEncodeInPlace:Sending message blocked, encoder of partitionid '%d' in bad state", + partitionId); + return FALSE; + } + + if (*dataLength <= 0) { + NN_WARNING0("q_securityEncodeInPlace:encoder called with empty buffer"); + return FALSE; + } + + overallHeaderSize = cipherTypeToHeaderSize(encoder->cipherType); + + if (*dataLength + overallHeaderSize > fragmentLength) { + NN_ERROR2("q_securityEncodeInPlace:sending message of %"PA_PRIu32" bytes overlaps with reserved space of %"PA_PRIu32" bytes", + *dataLength, overallHeaderSize); + return FALSE; + } + + assert(sizeof(os_uint32) == sizeof(os_uint32)); + + /* do the encoding now */ + result = q_securityEncodeInPlace_Generic(encoder, partitionId, buffer, dataLength, fragmentLength); + + return result; +} + +static c_bool q_securityGetHashFromCipherText +( + unsigned char* buffer, + os_uint32 dataLength, + os_uint32 *hash, + q_cipherType *sendersCipherType +) +{ + C_STRUCT(q_nullHeader) header; + + const os_uint32 headerSize = sizeof(C_STRUCT(q_nullHeader)); + + unsigned char* end = NULL; + + assert(dataLength >= headerSize); + assert(sizeof(os_uint32) == sizeof(os_uint32)); + + end = &(buffer[dataLength - headerSize]); + + memcpy(&header, end, headerSize); + *hash = ntohl(header.partitionId); + *sendersCipherType = ntohl(header.cipherType); + return TRUE; +} + +/* returns 0 on error, otherwise 1, + @param codec the security context object + @param buffer containing the ciphertext + @param fragmentLength overall length of buffer + @param dataLength the occupied space within buffer, on return it contains the length of plaintext in buffer */ +static c_bool q_securityDecodeInPlace +( + q_securityDecoderSet codec, + void *buffer, + size_t fragmentLength, + size_t *dataLength /* in/out */ +) +{ + q_securityPartitionDecoder decoder = NULL; + c_bool result = FALSE; + os_uint32 hash; + os_uint32 partitionId = 0; + os_uint32 dataLength32 = (os_uint32) *dataLength; + os_uint32 overallHeaderSize; + q_cipherType sendersCipherType; + struct config_networkpartition_listelem *p = config.networkPartitions; + + assert(codec); + + q_securityGetHashFromCipherText(buffer,dataLength32,&hash,&sendersCipherType); + + /* lookup hash in config to determine partitionId */ + while(p && ! partitionId) { + if (p->partitionHash == hash) partitionId = p->partitionId; + p = p->next; + } + + if ((partitionId < 1) || (partitionId > codec->nofPartitions)) { + NN_WARNING1("Incoming encrypted sub-message dropped, bad partition hash '%u'", hash); + return FALSE; + } + + decoder = &(codec->decoders[partitionId-1]); + + overallHeaderSize = cipherTypeToHeaderSize(sendersCipherType); + + if (sendersCipherType!=decoder->cipherType) { + NN_WARNING3("Incoming encrypted sub-message dropped: cipherType mismatch (%d != %d) for partition '%s'", sendersCipherType,decoder->cipherType, decoder->partitionName); + return FALSE; + } + if (decoderIsBlocked(decoder)) { + NN_WARNING1("Incoming encrypted sub-message dropped: decoder is blocked for partition '%s'", decoder->partitionName); + return FALSE; + } + + if (overallHeaderSize > dataLength32) { + NN_WARNING2("Incoming encrypted sub-message dropped: submessage too small(%"PA_PRIu32" bytes),for partition '%s'", dataLength32, decoder->partitionName); + return FALSE; + } + + result = q_securityDecodeInPlace_Generic(decoder, partitionId, buffer, &dataLength32, sendersCipherType, (os_uint32) fragmentLength); + *dataLength = dataLength32; + + return result; +} + +/* + * Substitute for the sendmsg call that send the message encrypted: + * iov[0] contains the RTPS header and is not encrypted + * iov[1] contains the security header and is also not encrypted + * iov[2..n] are concatenated into one buffer + * Buffer is encrypted and will be the new third iov. + * The size of the encrypted data is set in the second iov as the "octets to next message" + * + */ + +static os_ssize_t q_security_sendmsg +( + ddsi_tran_conn_t conn, + struct msghdr *message, + q_securityEncoderSet *codec, + os_uint32 encoderId, + os_uint32 flags +) +{ + char stbuf[2048], *buf; + os_uint32 sz, data_size; + os_ssize_t ret = ERR_UNSPECIFIED; + PT_InfoContainer_t * securityHeader = (PT_InfoContainer_t*) message->msg_iov[1].iov_base; + unsigned i; + +#if SYSDEPS_MSGHDR_ACCRIGHTS + assert (message->msg_accrightslen == 0); +#else + assert (message->msg_controllen == 0); +#endif + assert (message->msg_iovlen > 2); + /* first determine the size of the message, then select the + on-stack buffer or allocate one on the heap ... */ + sz = q_securityEncoderSetHeaderSize (*codec); /* reserve appropriate headersize */ + for (i = 2; i < (unsigned) message->msg_iovlen; i++) + { + sz += (os_uint32) message->msg_iov[i].iov_len; + } + if (sz <= sizeof (stbuf)) + { + buf = stbuf; + } + else + { + buf = os_malloc (sz); + } + /* ... then copy data into buffer */ + data_size = 0; + for (i = 2; i < (unsigned) message->msg_iovlen; i++) + { + memcpy (buf + data_size, message->msg_iov[i].iov_base, message->msg_iov[i].iov_len); + data_size += (os_uint32) message->msg_iov[i].iov_len; + } + sz = data_size + q_securityEncoderSetHeaderSize (*codec); + + /* Encrypt the buf in place with the given encoder */ + + if (q_securityEncodeInPlace (*codec, encoderId, buf, sz, &data_size)) + { + os_size_t nbytes; + /* replace encrypted buffer into iov */ + + message->msg_iov[2].iov_base = buf; + message->msg_iov[2].iov_len = data_size; + message->msg_iovlen = 3; + /* correct size in security header */ + securityHeader->smhdr.octetsToNextHeader = (unsigned short) (data_size + 4); + + /* send the encrypted data to the connection */ + + nbytes = message->msg_iov[0].iov_len + message->msg_iov[1].iov_len + message->msg_iov[2].iov_len; + if (!gv.mute && !(pa_ld32(&gv.ospl_kernel->isolate) & V_ISOLATE_MUTE)) + ret = ddsi_conn_write (conn, message, nbytes, flags); + else + { + TRACE (("(dropped)")); + ret = (os_ssize_t) nbytes; + } + } + + if (buf != stbuf) + { + os_free (buf); + } + return ret; +} + +void ddsi_security_plugin (void) +{ + q_security_plugin.encode = q_securityEncodeInPlace; + q_security_plugin.decode = q_securityDecodeInPlace; + q_security_plugin.new_encoder = q_securityEncoderSetNew; + q_security_plugin.new_decoder = q_securityDecoderSetNew; + q_security_plugin.free_encoder = q_securityEncoderSetFree; + q_security_plugin.free_decoder = q_securityDecoderSetFree; + q_security_plugin.send_encoded = q_security_sendmsg; + q_security_plugin.cipher_type = cipherTypeAsString; + q_security_plugin.cipher_type_from_string = q_securityCipherTypeFromString; + q_security_plugin.header_size = q_securityEncoderHeaderSize; + q_security_plugin.encoder_type = q_securityEncoderCipherType; + q_security_plugin.valid_uri = q_securityIsValidCipherKeyUri; +} + +#else + +int ddsi_dummy_val = 0; + +#endif /* DDSI_INCLUDE_ENCRYPTION */ diff --git a/src/services/ddsi2e/core/q_security.h b/src/services/ddsi2e/core/q_security.h new file mode 100644 index 000000000..19cff68a4 --- /dev/null +++ b/src/services/ddsi2e/core/q_security.h @@ -0,0 +1,53 @@ +#ifdef DDSI_INCLUDE_ENCRYPTION + +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#ifndef Q_SECURITY_H +#define Q_SECURITY_H + +#include "c_typebase.h" + +#if defined (__cplusplus) +extern "C" { +#endif + +/* Generic class */ +C_CLASS(q_securityEncoderSet); +C_CLASS(q_securityDecoderSet); + +/* Set of supported ciphers */ +typedef enum +{ + Q_CIPHER_UNDEFINED, + Q_CIPHER_NULL, + Q_CIPHER_BLOWFISH, + Q_CIPHER_AES128, + Q_CIPHER_AES192, + Q_CIPHER_AES256, + Q_CIPHER_NONE, + Q_CIPHER_MAX +} q_cipherType; + +void ddsi_security_plugin (void); + +#if defined (__cplusplus) +} +#endif + +#endif +#endif diff --git a/src/services/ddsi2/code/q_servicelease.c b/src/services/ddsi2e/core/q_servicelease.c similarity index 91% rename from src/services/ddsi2/code/q_servicelease.c rename to src/services/ddsi2e/core/q_servicelease.c index 8b2ecbb31..488b753ea 100644 --- a/src/services/ddsi2/code/q_servicelease.c +++ b/src/services/ddsi2e/core/q_servicelease.c @@ -1,18 +1,16 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * @@ -78,6 +76,7 @@ static void *lease_renewal_thread (struct nn_servicelease *sl) assignment. */ const os_int64 min_progress_check_intv = 100 * T_MILLISECOND; struct thread_state1 *self = lookup_thread_state (); + nn_mtime_t next_thread_cputime = { 0 }; nn_mtime_t tlast = { 0 }; int was_alive = 1; unsigned i; @@ -92,6 +91,8 @@ static void *lease_renewal_thread (struct nn_servicelease *sl) unsigned n_alive = 0; nn_mtime_t tnow = now_mt (); + LOG_THREAD_CPUTIME (next_thread_cputime); + TRACE (("servicelease: tnow %"PA_PRId64":", tnow.v)); /* Check progress only if enough time has passed: there is no @@ -254,5 +255,3 @@ void nn_servicelease_free (struct nn_servicelease *sl) os_free (sl->av_ary); os_free (sl); } - -/* SHA1 not available (unoffical build.) */ diff --git a/src/services/ddsi2e/core/q_servicelease.h b/src/services/ddsi2e/core/q_servicelease.h new file mode 100644 index 000000000..e842d8508 --- /dev/null +++ b/src/services/ddsi2e/core/q_servicelease.h @@ -0,0 +1,36 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#ifndef NN_SERVICELEASE_H +#define NN_SERVICELEASE_H + +#if defined (__cplusplus) +extern "C" { +#endif + +struct nn_servicelease; + +struct nn_servicelease *nn_servicelease_new (void (*renew_cb) (void *arg), void *renew_arg); +int nn_servicelease_start_renewing (struct nn_servicelease *sl); +void nn_servicelease_free (struct nn_servicelease *sl); +void nn_servicelease_statechange_barrier (struct nn_servicelease *sl); + +#if defined (__cplusplus) +} +#endif + +#endif /* NN_SERVICELEASE_H */ diff --git a/src/services/ddsi2/code/q_sockwaitset.c b/src/services/ddsi2e/core/q_sockwaitset.c similarity index 94% rename from src/services/ddsi2/code/q_sockwaitset.c rename to src/services/ddsi2e/core/q_sockwaitset.c index 66e8a10d7..aed9b4a87 100644 --- a/src/services/ddsi2/code/q_sockwaitset.c +++ b/src/services/ddsi2e/core/q_sockwaitset.c @@ -1,18 +1,16 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * @@ -430,7 +428,7 @@ os_sockWaitset os_sockWaitsetNew (void) fcntl (ws->pipe[0], F_SETFD, fcntl (ws->pipe[0], F_GETFD) | FD_CLOEXEC); fcntl (ws->pipe[1], F_SETFD, fcntl (ws->pipe[1], F_GETFD) | FD_CLOEXEC); #endif - FD_SET (ws->set.fds[0], &ws->ctx.rdset); + os_sock_set ((os_socket)ws->set.fds[0], &ws->ctx.rdset); #if ! defined (_WIN32) ws->fdmax_plus_1 = ws->set.fds[0] + 1; #endif @@ -611,7 +609,7 @@ os_sockWaitsetCtx os_sockWaitsetWait (os_sockWaitset ws) FD_ZERO (rdset); for (u = 0; u < dst->n; u++) { - FD_SET (dst->fds[u], rdset); + os_sock_set ((os_socket)dst->fds[u], rdset); } do @@ -633,7 +631,7 @@ os_sockWaitsetCtx os_sockWaitsetWait (os_sockWaitset ws) { /* this simply skips the trigger fd */ ctx->index = 1; - if (FD_ISSET (dst->fds[0], rdset)) + if (os_sock_isset ((os_socket)dst->fds[0], rdset)) { char buf; int n; @@ -662,7 +660,7 @@ int os_sockWaitsetNextEvent (os_sockWaitsetCtx ctx, ddsi_tran_conn_t * conn) unsigned idx = ctx->index++; os_handle fd = ctx->set.fds[idx]; assert(idx > 0); - if (FD_ISSET (fd, &ctx->rdset)) + if (os_sock_isset ((os_socket)fd, &ctx->rdset)) { *conn = ctx->set.conns[idx]; @@ -672,5 +670,3 @@ int os_sockWaitsetNextEvent (os_sockWaitsetCtx ctx, ddsi_tran_conn_t * conn) return -1; } #endif /* WINCE */ - -/* SHA1 not available (unoffical build.) */ diff --git a/src/services/ddsi2/code/q_sockwaitset.h b/src/services/ddsi2e/core/q_sockwaitset.h similarity index 84% rename from src/services/ddsi2/code/q_sockwaitset.h rename to src/services/ddsi2e/core/q_sockwaitset.h index a41aaf33e..c01511b6e 100644 --- a/src/services/ddsi2/code/q_sockwaitset.h +++ b/src/services/ddsi2e/core/q_sockwaitset.h @@ -1,18 +1,16 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * @@ -117,5 +115,3 @@ void os_sockWaitsetRemove (os_sockWaitset ws, struct ddsi_tran_conn * conn); } #endif #endif /* Q_SOCKWAITSET_H */ - -/* SHA1 not available (unoffical build.) */ diff --git a/src/services/ddsi2e/core/q_static_assert.h b/src/services/ddsi2e/core/q_static_assert.h new file mode 100644 index 000000000..26cd48be8 --- /dev/null +++ b/src/services/ddsi2e/core/q_static_assert.h @@ -0,0 +1,28 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#ifndef Q_STATIC_ASSERT_H +#define Q_STATIC_ASSERT_H + +/* There are many tricks to use a constant expression to yield an + illegal type or expression at compile time, such as zero-sized + arrays and duplicate case or enum labels. So this is but one of the + many tricks. */ + +#define Q_STATIC_ASSERT_CODE(pred) do { switch(0) { case 0: case pred: ; } } while (0) + +#endif /* Q_STATIC_ASSERT_H */ diff --git a/src/services/ddsi2/code/q_thread.c b/src/services/ddsi2e/core/q_thread.c similarity index 92% rename from src/services/ddsi2/code/q_thread.c rename to src/services/ddsi2e/core/q_thread.c index 892bc1666..d9233b040 100644 --- a/src/services/ddsi2/code/q_thread.c +++ b/src/services/ddsi2e/core/q_thread.c @@ -1,18 +1,16 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * @@ -31,7 +29,9 @@ #include "q_globals.h" #include "sysdeps.h" +#if !LITE #include "u_service.h" +#endif static char main_thread_name[] = "main"; @@ -237,7 +237,11 @@ struct thread_state1 *create_thread (const char *name, void * (*f) (void *arg), tattr.stackSize = tprops->stack_size.value; } TRACE (("create_thread: %s: class %d priority %d stack %u\n", name, (int) tattr.schedClass, tattr.schedPriority, tattr.stackSize)); +#if ! LITE if (u_serviceThreadCreate (&tid, name, &tattr, (void * (*) (void *)) create_thread_wrapper, ctxt) != os_resultSuccess) +#else + if (os_threadCreate (&tid, name, &tattr, (void * (*) (void *)) create_thread_wrapper, ctxt) != os_resultSuccess) +#endif { ts1->state = THREAD_STATE_ZERO; NN_FATAL1 ("create_thread: %s: os_threadCreate failed\n", name); @@ -328,5 +332,3 @@ void log_stack_traces (void) } } - -/* SHA1 not available (unoffical build.) */ diff --git a/src/services/ddsi2/code/q_thread.h b/src/services/ddsi2e/core/q_thread.h similarity index 85% rename from src/services/ddsi2/code/q_thread.h rename to src/services/ddsi2e/core/q_thread.h index 6405b2f9c..c76ec5de8 100644 --- a/src/services/ddsi2/code/q_thread.h +++ b/src/services/ddsi2e/core/q_thread.h @@ -1,18 +1,16 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * @@ -138,5 +136,3 @@ void thread_state_unblocked (struct thread_state1 *ts1); #endif #endif /* Q_THREAD_H */ - -/* SHA1 not available (unoffical build.) */ diff --git a/src/services/ddsi2e/core/q_thread_inlines.c b/src/services/ddsi2e/core/q_thread_inlines.c new file mode 100644 index 000000000..316c7dc89 --- /dev/null +++ b/src/services/ddsi2e/core/q_thread_inlines.c @@ -0,0 +1,21 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#define SUPPRESS_THREAD_INLINES + +#include "q_thread.h" +#include "q_thread_template.c" diff --git a/src/services/ddsi2/code/q_thread_template.c b/src/services/ddsi2e/core/q_thread_template.c similarity index 76% rename from src/services/ddsi2/code/q_thread_template.c rename to src/services/ddsi2e/core/q_thread_template.c index 0b2e25195..9a54ee11f 100644 --- a/src/services/ddsi2/code/q_thread_template.c +++ b/src/services/ddsi2e/core/q_thread_template.c @@ -1,18 +1,16 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * @@ -120,5 +118,3 @@ NN_C99_INLINE void thread_state_unblocked (struct thread_state1 *ts1) } - -/* SHA1 not available (unoffical build.) */ diff --git a/src/services/ddsi2/code/q_time.c b/src/services/ddsi2e/core/q_time.c similarity index 88% rename from src/services/ddsi2/code/q_time.c rename to src/services/ddsi2e/core/q_time.c index 8e01aa30c..fdfe6fa4f 100644 --- a/src/services/ddsi2/code/q_time.c +++ b/src/services/ddsi2e/core/q_time.c @@ -1,18 +1,16 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * @@ -126,10 +124,10 @@ nn_mtime_t mtime_round_up (nn_mtime_t t, os_int64 round) static os_int64 add_duration_to_time (os_int64 t, os_int64 d) { - /* assumed T_NEVER <=> MAX_INT64 */ - os_int64 sum = t + d; + os_uint64 sum; assert (t >= 0 && d >= 0); - return sum < t ? T_NEVER : sum; + sum = (os_uint64)t + (os_uint64)d; + return sum >= T_NEVER ? T_NEVER : (os_int64)sum; } nn_mtime_t add_duration_to_mtime (nn_mtime_t t, os_int64 d) @@ -245,5 +243,3 @@ nn_wctime_to_os_timeW(nn_wctime_t t) tw = OS_TIMEW_INIT(0,(os_uint64)t.v); return tw; } - -/* SHA1 not available (unoffical build.) */ diff --git a/src/services/ddsi2/code/q_time.h b/src/services/ddsi2e/core/q_time.h similarity index 78% rename from src/services/ddsi2/code/q_time.h rename to src/services/ddsi2e/core/q_time.h index 0c2ac1b1d..295fc5714 100644 --- a/src/services/ddsi2/code/q_time.h +++ b/src/services/ddsi2e/core/q_time.h @@ -1,18 +1,16 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * @@ -94,5 +92,3 @@ os_timeW nn_wctime_to_os_timeW(nn_wctime_t t); #endif #endif /* NN_TIME_H */ - -/* SHA1 not available (unoffical build.) */ diff --git a/src/services/ddsi2/code/q_transmit.c b/src/services/ddsi2e/core/q_transmit.c similarity index 83% rename from src/services/ddsi2/code/q_transmit.c rename to src/services/ddsi2e/core/q_transmit.c index 2730e3c52..6adc11017 100644 --- a/src/services/ddsi2/code/q_transmit.c +++ b/src/services/ddsi2e/core/q_transmit.c @@ -1,18 +1,16 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * @@ -24,6 +22,7 @@ #include "os_stdlib.h" #include "os_mutex.h" #include "os_heap.h" +#include "os_atomics.h" #include "ut_avl.h" #include "q_whc.h" @@ -42,9 +41,14 @@ #include "q_entity.h" #include "q_unused.h" #include "q_hbcontrol.h" +#include "q_lease.h" #include "q_static_assert.h" +#if LITE +#include "ddsi_ser.h" +#else #include "q_osplser.h" +#endif #include "sysdeps.h" @@ -58,11 +62,6 @@ #define POS_INFINITY_DOUBLE 1e1000 #endif -static const os_int64 const_hb_intv_sched = 100 * T_MILLISECOND; -static const os_int64 const_hb_intv_sched_min = 20 * T_MILLISECOND; -static const os_int64 const_hb_intv_sched_max = 8000 * T_MILLISECOND; -static const os_int64 const_hb_intv_min = 5 * T_MILLISECOND; - static const struct wr_prd_match *root_rdmatch (const struct writer *wr) { return ut_avlRoot (&wr_readers_treedef, &wr->readers); @@ -103,13 +102,13 @@ static void writer_hbcontrol_note_hb (struct writer *wr, nn_mtime_t tnow, int an os_int64 writer_hbcontrol_intv (const struct writer *wr, UNUSED_ARG (nn_mtime_t tnow)) { struct hbcontrol const * const hbc = &wr->hbcontrol; - os_int64 ret = const_hb_intv_sched; + os_int64 ret = config.const_hb_intv_sched; os_size_t n_unacked; if (hbc->hbs_since_last_write > 2) { unsigned cnt = hbc->hbs_since_last_write; - while (cnt-- > 2 && 2 * ret < const_hb_intv_sched_max) + while (cnt-- > 2 && 2 * ret < config.const_hb_intv_sched_max) ret *= 2; } @@ -120,8 +119,8 @@ os_int64 writer_hbcontrol_intv (const struct writer *wr, UNUSED_ARG (nn_mtime_t ret /= 2; if (wr->throttling) ret /= 2; - if (ret < const_hb_intv_sched_min) - ret = const_hb_intv_sched_min; + if (ret < config.const_hb_intv_sched_min) + ret = config.const_hb_intv_sched_min; return ret; } @@ -136,7 +135,7 @@ void writer_hbcontrol_note_asyncwrite (struct writer *wr, nn_mtime_t tnow) /* We know this is new data, so we want a heartbeat event after one base interval */ - tnext.v = tnow.v + const_hb_intv_sched; + tnext.v = tnow.v + config.const_hb_intv_sched; if (tnext.v < hbc->tsched.v) { /* Insertion of a message with WHC locked => must now have at @@ -199,11 +198,11 @@ struct nn_xmsg *writer_hbcontrol_create_heartbeat (struct writer *wr, nn_mtime_t } } - TRACE (("writer_hbcontrol: wr %x:%x:%x:%x ", PGUID (wr->e.guid))); + TRACE (("writer_hbcontrol: wr "PGUIDFMT" ", PGUID (wr->e.guid))); if (prd_guid == NULL) TRACE (("multicasting ")); else - TRACE (("unicasting to prd %x:%x:%x:%x ", PGUID (*prd_guid))); + TRACE (("unicasting to prd "PGUIDFMT" ", PGUID (*prd_guid))); TRACE (("(rel-prd %d seq-eq-max %d seq %lld maxseq %"PA_PRId64")\n", wr->num_reliable_readers, ut_avlIsEmpty (&wr->readers) ? -1 : root_rdmatch (wr)->num_reliable_readers_where_seq_equals_max, @@ -213,6 +212,9 @@ struct nn_xmsg *writer_hbcontrol_create_heartbeat (struct writer *wr, nn_mtime_t if (prd_guid == NULL) { nn_xmsg_setdstN (msg, wr->as, wr->as_group); +#ifdef DDSI_INCLUDE_NETWORK_PARTITIONS + nn_xmsg_setencoderid (msg, wr->partition_id); +#endif add_Heartbeat (msg, wr, hbansreq, to_entityid (NN_ENTITYID_UNKNOWN), issync); } else @@ -220,7 +222,7 @@ struct nn_xmsg *writer_hbcontrol_create_heartbeat (struct writer *wr, nn_mtime_t struct proxy_reader *prd; if ((prd = ephash_lookup_proxy_reader_guid (prd_guid)) == NULL) { - TRACE (("writer_hbcontrol: wr %x:%x:%x:%x unknown prd %x:%x:%x:%x\n", PGUID (wr->e.guid), PGUID (*prd_guid))); + TRACE (("writer_hbcontrol: wr "PGUIDFMT" unknown prd "PGUIDFMT"\n", PGUID (wr->e.guid), PGUID (*prd_guid))); nn_xmsg_free (msg); return NULL; } @@ -231,6 +233,9 @@ struct nn_xmsg *writer_hbcontrol_create_heartbeat (struct writer *wr, nn_mtime_t nn_xmsg_free (msg); return NULL; } +#ifdef DDSI_INCLUDE_NETWORK_PARTITIONS + nn_xmsg_setencoderid (msg, wr->partition_id); +#endif add_Heartbeat (msg, wr, hbansreq, prd_guid->entityid, issync); } @@ -241,7 +246,7 @@ struct nn_xmsg *writer_hbcontrol_create_heartbeat (struct writer *wr, nn_mtime_t static int writer_hbcontrol_ack_required_generic (const struct writer *wr, nn_mtime_t tlast, nn_mtime_t tnow, int piggyback) { struct hbcontrol const * const hbc = &wr->hbcontrol; - const os_int64 hb_intv_ack = const_hb_intv_sched; + const os_int64 hb_intv_ack = config.const_hb_intv_sched; if (piggyback) { @@ -263,9 +268,9 @@ static int writer_hbcontrol_ack_required_generic (const struct writer *wr, nn_mt if (whc_unacked_bytes (wr->whc) >= wr->whc_low + (wr->whc_high - wr->whc_low) / 2) { - if (tnow.v >= hbc->t_of_last_ackhb.v + const_hb_intv_sched_min) + if (tnow.v >= hbc->t_of_last_ackhb.v + config.const_hb_intv_sched_min) return 2; - else if (tnow.v >= hbc->t_of_last_ackhb.v + const_hb_intv_min) + else if (tnow.v >= hbc->t_of_last_ackhb.v + config.const_hb_intv_min) return 1; } @@ -315,7 +320,7 @@ struct nn_xmsg *writer_hbcontrol_piggyback (struct writer *wr, nn_mtime_t tnow, if (msg) { - TRACE (("heartbeat(wr %x:%x:%x:%x%s) piggybacked, resched in %g s (min-ack %"PA_PRId64"%s, avail-seq %"PA_PRId64", xmit %lld)\n", + TRACE (("heartbeat(wr "PGUIDFMT"%s) piggybacked, resched in %g s (min-ack %"PA_PRId64"%s, avail-seq %"PA_PRId64", xmit %lld)\n", PGUID (wr->e.guid), *hbansreq ? "" : " final", (hbc->tsched.v == T_NEVER) ? POS_INFINITY_DOUBLE : (double) (hbc->tsched.v - tnow.v) / 1e9, @@ -443,6 +448,10 @@ int create_fragment_message (struct writer *wr, os_int64 seq, const struct nn_pl if ((*pmsg = nn_xmsg_new (gv.xmsgpool, &wr->e.guid.prefix, sizeof (InfoTimestamp_t) + sizeof (DataFrag_t) + expected_inline_qos_size, xmsg_kind)) == NULL) return ERR_OUT_OF_MEMORY; +#ifdef DDSI_INCLUDE_NETWORK_PARTITIONS + /* use the partition_id from the writer to select the proper encoder */ + nn_xmsg_setencoderid (*pmsg, wr->partition_id); +#endif if (prd) { @@ -546,6 +555,7 @@ int create_fragment_message (struct writer *wr, os_int64 seq, const struct nn_pl { nn_xmsg_addpar_statusinfo (*pmsg, serdata->v.msginfo.statusinfo); } +#if !LITE if (plist) { nn_plist_addtomsg (*pmsg, plist, ~(os_uint64)0, ~(os_uint64)0); @@ -556,6 +566,7 @@ int create_fragment_message (struct writer *wr, os_int64 seq, const struct nn_pl { nn_xmsg_addpar_wrinfo (*pmsg, &serdata->v.msginfo.wrinfo); } +#endif rc = nn_xmsg_addpar_sentinel_ifparam (*pmsg); if (rc > 0) { @@ -567,7 +578,7 @@ int create_fragment_message (struct writer *wr, os_int64 seq, const struct nn_pl nn_xmsg_serdata (*pmsg, serdata, fragstart, fraglen); nn_xmsg_submsg_setnext (*pmsg, sm_marker); #if 0 - TRACE (("queue data%s %x:%x:%x:%x #%lld/%u[%u..%u)\n", + TRACE (("queue data%s "PGUIDFMT" #%lld/%u[%u..%u)\n", fragging ? "frag" : "", PGUID (wr->e.guid), seq, fragnum+1, fragstart, fragstart + fraglen)); #endif @@ -582,6 +593,9 @@ static void create_HeartbeatFrag (struct writer *wr, os_int64 seq, unsigned frag ASSERT_MUTEX_HELD (&wr->e.lock); if ((*pmsg = nn_xmsg_new (gv.xmsgpool, &wr->e.guid.prefix, sizeof (HeartbeatFrag_t), NN_XMSG_KIND_CONTROL)) == NULL) return; /* ignore out-of-memory: HeartbeatFrag is only advisory anyway */ +#ifdef DDSI_INCLUDE_NETWORK_PARTITIONS + nn_xmsg_setencoderid (*pmsg, wr->partition_id); +#endif if (prd) { if (nn_xmsg_setdstPRD (*pmsg, prd) < 0) @@ -764,8 +778,13 @@ static int insert_sample_in_whc (struct writer *wr, os_int64 seq, struct nn_plis int tmp; const char *tname = wr->topic ? wr->topic->name : "(null)"; const char *ttname = wr->topic ? wr->topic->typename : "(null)"; +#if LITE + ppbuf[0] = '\0'; + tmp = sizeof (ppbuf) - 1; +#else tmp = prettyprint_serdata (ppbuf, sizeof (ppbuf), serdata); - nn_log (LC_TRACE, "write_sample %x:%x:%x:%x #%"PA_PRId64"", PGUID (wr->e.guid), seq); +#endif + nn_log (LC_TRACE, "write_sample "PGUIDFMT" #%"PA_PRId64"", PGUID (wr->e.guid), seq); if (plist != 0 && (plist->present & PP_COHERENT_SET)) nn_log (LC_TRACE, " C#%"PA_PRId64"", fromSN (plist->coherent_set_seqno)); nn_log (LC_TRACE, ": ST%d %s/%s:%s%s\n", @@ -804,6 +823,7 @@ static int writer_may_continue (const struct writer *wr) return (whc_unacked_bytes (wr->whc) <= wr->whc_low && !wr->retransmitting) || (wr->state != WRST_OPERATIONAL); } +#if !LITE static void throttle_helper (struct wr_prd_match *wprd, struct writer * const wr) { /* Mark connected readers that haven't acked all data as "not @@ -818,7 +838,33 @@ static void throttle_helper (struct wr_prd_match *wprd, struct writer * const wr chance to recover */ wprd->has_replied_to_hb = 0; ut_avlAugmentUpdate (&wr_readers_treedef, wprd); - NN_WARNING3 ("writer %x:%x:%x:%x topic %s considering reader %x:%x:%x:%x non-responsive\n", + NN_WARNING3 ("writer "PGUIDFMT" topic %s considering reader "PGUIDFMT" non-responsive\n", + PGUID (wr->e.guid), wr->topic ? wr->topic->name : "(null)", PGUID (wprd->prd_guid)); + { + nn_guid_t ppguid; + struct proxy_participant *proxypp; + ppguid.prefix = wprd->prd_guid.prefix; + ppguid.entityid.u = NN_ENTITYID_PARTICIPANT; + if ((proxypp = ephash_lookup_proxy_participant_guid (&ppguid)) != NULL) + { + const nn_etime_t immediately = { 0 }; + lease_set_expiry (pa_ldvoidp (&proxypp->lease), immediately); + } + } + } +} +#endif + +static void tracing_helper (struct wr_prd_match *wprd, struct writer * const wr) +{ + /* Trace connected readers that haven't acked all data. + Both wprd->seq (&c.) and wr->seq are protected by + wr->e.lock, which must be held on entry. */ + ASSERT_MUTEX_HELD (&wr->e.lock); + + if (wprd->seq < wr->seq) + { + NN_WARNING3 ("writer "PGUIDFMT" topic %s waiting on high watermark due to reader "PGUIDFMT"\n", PGUID (wr->e.guid), wr->topic ? wr->topic->name : "(null)", PGUID (wprd->prd_guid)); } } @@ -860,19 +906,25 @@ static os_result throttle_writer (struct nn_xpack *xp, struct writer *wr) writer. */ nn_mtime_t tnow = now_mt (); +#if LITE + const nn_mtime_t abstimeout = add_duration_to_mtime (tnow, nn_from_ddsi_duration (wr->xqos->reliability.max_blocking_time)); +#else const nn_mtime_t abstimeout = add_duration_to_mtime (tnow, config.responsiveness_timeout); +#endif os_size_t n_unacked = whc_unacked_bytes (wr->whc); os_result result; - /* We don't _really_ need to hold the lock if we can decide whether - or not to throttle based on atomically updated state. Currently, - this is the case, and if it remains that way, maybe we should - eventually remove the precondition that the lock be held. */ - ASSERT_MUTEX_HELD (&wr->e.lock); - assert (vtime_awake_p (lookup_thread_state ()->vtime)); + { + nn_vendorid_t ownvendorid = MY_VENDOR_ID; + ASSERT_MUTEX_HELD (&wr->e.lock); + assert (wr->throttling == 0); + assert (vtime_awake_p (lookup_thread_state ()->vtime)); + assert (!is_builtin_entityid(wr->e.guid.entityid, ownvendorid)); + OS_UNUSED_ARG(ownvendorid); + } - TRACE (("writer %x:%x:%x:%x topic %s waiting for whc to shrink below low-water mark (whc %"PA_PRIuSIZE" low=%u high=%u)\n", PGUID (wr->e.guid), wr->topic ? wr->topic->name : "(null)", n_unacked, wr->whc_low, wr->whc_high)); - wr->throttling++; + nn_log (LC_THROTTLE, "writer "PGUIDFMT" topic %s waiting for whc to shrink below low-water mark (whc %"PA_PRIuSIZE" low=%u high=%u)\n", PGUID (wr->e.guid), wr->topic ? wr->topic->name : "(null)", n_unacked, wr->whc_low, wr->whc_high); + wr->throttling = 1; wr->throttle_count++; /* Force any outstanding packet out: there will be a heartbeat @@ -902,12 +954,26 @@ static os_result throttle_writer (struct nn_xpack *xp, struct writer *wr) } else { timeout = reltimeout; } - thread_state_blocked (lookup_thread_state ()); + thread_state_asleep (lookup_thread_state ()); + /* GC allowed, but wr won't be destroyed until after wr->throttling becomes 0 again */ (void)os_condTimedWait (&wr->throttle_cond, &wr->e.lock, timeout); - thread_state_unblocked (lookup_thread_state ()); + thread_state_awake (lookup_thread_state ()); tnow = now_mt (); + /* Trace that this writer reached the high-water + * mark longer than the timeout period. */ + if ((wr->throttle_count > wr->throttle_tracing) && (!writer_may_continue(wr))) { + ut_avlWalk (&wr_readers_treedef, &wr->readers, (ut_avlWalk_t)tracing_helper, wr); + wr->throttle_tracing = (wr->throttle_count * 2) + 1; + } } +#if LITE + /* Lite wants to know whether a timeout occurred (to propage out to the application) */ + if (tnow.v < abstimeout.v) + result = os_resultSuccess; + else + result = os_resultTimeout; +#else /* OSPL simply needs to know whether it must drop data or not, whether a timeout occurred is irrelevant if the writer may not continue */ @@ -915,16 +981,22 @@ static os_result throttle_writer (struct nn_xpack *xp, struct writer *wr) if (!writer_may_continue (wr)) { n_unacked = whc_unacked_bytes (wr->whc); - TRACE (("writer %x:%x:%x:%x topic %s whc not shrunk enough after maximum blocking time (whc %"PA_PRIuSIZE")\n", PGUID (wr->e.guid), wr->topic ? wr->topic->name : "(null)", n_unacked)); + nn_log (LC_THROTTLE, "writer "PGUIDFMT" topic %s whc not shrunk enough after maximum blocking time (whc %"PA_PRIuSIZE")\n", PGUID (wr->e.guid), wr->topic ? wr->topic->name : "(null)", n_unacked); /* Walk over all connected readers and mark them "not responsive" if they have unacked data. */ ut_avlWalk (&wr_readers_treedef, &wr->readers, (ut_avlWalk_t) throttle_helper, wr); remove_acked_messages (wr); os_condBroadcast (&wr->throttle_cond); } +#endif - wr->throttling--; + wr->throttling = 0; + if (wr->state != WRST_OPERATIONAL) + { + /* gc_delete_writer may be waiting */ + os_condBroadcast (&wr->throttle_cond); + } n_unacked = whc_unacked_bytes (wr->whc); - TRACE (("writer %x:%x:%x:%x done waiting for whc to shrink below low-water mark (whc %"PA_PRIuSIZE" low=%u high=%u)\n", PGUID (wr->e.guid), n_unacked, wr->whc_low, wr->whc_high)); + nn_log (LC_THROTTLE, "writer "PGUIDFMT" done waiting for whc to shrink below low-water mark (whc %"PA_PRIuSIZE" low=%u high=%u)\n", PGUID (wr->e.guid), n_unacked, wr->whc_low, wr->whc_high); return result; } @@ -945,20 +1017,28 @@ static int maybe_grow_whc (struct writer *wr) return 0; } -static int write_sample_kernel_seq_eot (struct nn_xpack *xp, struct writer *wr, struct nn_plist *plist, serdata_t serdata, int have_kernel_seq, os_uint32 kernel_seq, int end_of_txn) +static int write_sample_kernel_seq_eot (struct nn_xpack *xp, struct writer *wr, struct nn_plist *plist, serdata_t serdata, int have_kernel_seq, os_uint32 kernel_seq, int end_of_txn, UNUSED_ARG(int gc_allowed)) { int r; os_int64 seq; nn_mtime_t tnow; + /* If GC not allowed, we must be sure to never block when writing. That is only the case for (true, aggressive) KEEP_LAST writers, and also only if there is no limit to how much unacknowledged data the WHC may contain. */ + assert(gc_allowed || (wr->xqos->history.kind == NN_KEEP_LAST_HISTORY_QOS && wr->aggressive_keep_last && wr->whc_low == INT32_MAX)); + if (ddsi_serdata_size (serdata) > config.max_sample_size) { char ppbuf[1024]; int tmp; const char *tname = wr->topic ? wr->topic->name : "(null)"; const char *ttname = wr->topic ? wr->topic->typename : "(null)"; +#if LITE + ppbuf[0] = '\0'; + tmp = sizeof (ppbuf) - 1; +#else tmp = prettyprint_serdata (ppbuf, sizeof (ppbuf), serdata); - NN_WARNING7 ("dropping oversize (%u > %u) sample from local writer %x:%x:%x:%x %s/%s:%s%s\n", +#endif + NN_WARNING7 ("dropping oversize (%u > %u) sample from local writer "PGUIDFMT" %s/%s:%s%s\n", ddsi_serdata_size (serdata), config.max_sample_size, PGUID (wr->e.guid), tname, ttname, ppbuf, tmp < (int) sizeof (ppbuf) ? "" : " (trunc)"); @@ -984,7 +1064,7 @@ static int write_sample_kernel_seq_eot (struct nn_xpack *xp, struct writer *wr, else { os_mutexUnlock (&wr->e.lock); - TRACE (("write_sample %x:%x:%x:%x - dropping kernel seq %u as duplicate\n", + TRACE (("write_sample "PGUIDFMT" - dropping kernel seq %u as duplicate\n", PGUID (wr->e.guid), kernel_seq)); r = 0; goto drop; @@ -992,27 +1072,28 @@ static int write_sample_kernel_seq_eot (struct nn_xpack *xp, struct writer *wr, /* If WHC overfull, block. */ - { os_size_t unacked_bytes = whc_unacked_bytes (wr->whc); - os_result ores; - if (unacked_bytes <= wr->whc_high) - ores = os_resultSuccess; - else if (config.prioritize_retransmit && wr->retransmitting) - ores = throttle_writer (xp, wr); - else + if (unacked_bytes > wr->whc_high) { - maybe_grow_whc (wr); - if (unacked_bytes <= wr->whc_high) - ores = os_resultSuccess; - else + os_result ores; + assert(gc_allowed); /* also see beginning of the function */ + if (config.prioritize_retransmit && wr->retransmitting) ores = throttle_writer (xp, wr); - } - if (ores == os_resultTimeout) - { - os_mutexUnlock (&wr->e.lock); - r = ERR_TIMEOUT; - goto drop; + else + { + maybe_grow_whc (wr); + if (unacked_bytes <= wr->whc_high) + ores = os_resultSuccess; + else + ores = throttle_writer (xp, wr); + } + if (ores == os_resultTimeout) + { + os_mutexUnlock (&wr->e.lock); + r = ERR_TIMEOUT; + goto drop; + } } } @@ -1089,20 +1170,23 @@ static int write_sample_kernel_seq_eot (struct nn_xpack *xp, struct writer *wr, return r; } -int write_sample_kernel_seq (struct nn_xpack *xp, struct writer *wr, serdata_t serdata, int have_kernel_seq, os_uint32 kernel_seq) +int write_sample_kernel_seq_gc (struct nn_xpack *xp, struct writer *wr, serdata_t serdata, int have_kernel_seq, os_uint32 kernel_seq) { - return write_sample_kernel_seq_eot (xp, wr, NULL, serdata, have_kernel_seq, kernel_seq, 0); + return write_sample_kernel_seq_eot (xp, wr, NULL, serdata, have_kernel_seq, kernel_seq, 0, 1); } -int write_sample (struct nn_xpack *xp, struct writer *wr, serdata_t serdata) +int write_sample_nogc (struct nn_xpack *xp, struct writer *wr, serdata_t serdata) { +#if ! LITE #ifndef NDEBUG const nn_vendorid_t ownvendorid = MY_VENDOR_ID; assert (is_builtin_entityid (wr->e.guid.entityid, ownvendorid)); #endif - return write_sample_kernel_seq_eot (xp, wr, NULL, serdata, 0, 0, 0); +#endif + return write_sample_kernel_seq_eot (xp, wr, NULL, serdata, 0, 0, 0, 0); } +#if ! LITE void begin_coherent_set (struct writer *wr) { os_mutexLock (&wr->e.lock); @@ -1111,9 +1195,8 @@ void begin_coherent_set (struct writer *wr) os_mutexUnlock (&wr->e.lock); } -int end_coherent_set (struct nn_xpack *xp, struct writer *wr, struct nn_plist *plist, serdata_t serdata, int have_kernel_seq, os_uint32 kernel_seq) +int end_coherent_set_gc (struct nn_xpack *xp, struct writer *wr, struct nn_plist *plist, serdata_t serdata, int have_kernel_seq, os_uint32 kernel_seq) { - return write_sample_kernel_seq_eot (xp, wr, plist, serdata, have_kernel_seq, kernel_seq, 1); + return write_sample_kernel_seq_eot (xp, wr, plist, serdata, have_kernel_seq, kernel_seq, 1, 1); } - -/* SHA1 not available (unoffical build.) */ +#endif diff --git a/src/services/ddsi2e/core/q_transmit.h b/src/services/ddsi2e/core/q_transmit.h new file mode 100644 index 000000000..3ec6a44d0 --- /dev/null +++ b/src/services/ddsi2e/core/q_transmit.h @@ -0,0 +1,59 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#ifndef Q_TRANSMIT_H +#define Q_TRANSMIT_H + +#include "os_defs.h" +#include "q_rtps.h" /* for nn_entityid_t */ + +#if defined (__cplusplus) +extern "C" { +#endif + +struct nn_xpack; +struct nn_xmsg; +struct writer; +struct proxy_reader; +struct serdata; + +/* Writing new data; serdata_twrite (serdata) is assumed to be really + recentish; serdata is unref'd. If xp == NULL, data is queued, else + packed. + + "nogc": no GC may occur, so it may not block to throttle the writer if the high water mark of the WHC is reached, which implies true KEEP_LAST behaviour. This is true for all the DDSI built-in writers. + "gc": GC may occur, which means the writer history and watermarks can be anything. This must be used for all application data. +*/ +int write_sample_nogc (struct nn_xpack *xp, struct writer *wr, struct serdata *serdata); +int write_sample_kernel_seq_gc (struct nn_xpack *xp, struct writer *wr, struct serdata *serdata, int have_kernel_seq, os_uint32 kernel_seq); + +#if ! LITE +void begin_coherent_set (struct writer *wr); +/* plist (if != NULL) gets "consumed" by end_coherent_set */ +int end_coherent_set_gc (struct nn_xpack *xp, struct writer *wr, struct nn_plist *plist, struct serdata *serdata, int have_kernel_seq, os_uint32 kernel_seq); +#endif + +/* When calling the following functions, wr->lock must be held */ +int create_fragment_message (struct writer *wr, os_int64 seq, const struct nn_plist *plist, struct serdata *serdata, unsigned fragnum, struct proxy_reader *prd,struct nn_xmsg **msg, int isnew); +int enqueue_sample_wrlock_held (struct writer *wr, os_int64 seq, const struct nn_plist *plist, struct serdata *serdata, struct proxy_reader *prd, int isnew); +void add_Heartbeat (struct nn_xmsg *msg, struct writer *wr, int hbansreq, nn_entityid_t dst, int issync); + +#if defined (__cplusplus) +} +#endif + +#endif /* Q_TRANSMIT_H */ diff --git a/src/services/ddsi2e/core/q_unused.h b/src/services/ddsi2e/core/q_unused.h new file mode 100644 index 000000000..b0aa6dd8e --- /dev/null +++ b/src/services/ddsi2e/core/q_unused.h @@ -0,0 +1,33 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#ifndef NN_UNUSED_H +#define NN_UNUSED_H + +#ifdef __GNUC__ +#define UNUSED_ARG(x) x __attribute__ ((unused)) +#else +#define UNUSED_ARG(x) x +#endif + +#ifndef NDEBUG +#define UNUSED_ARG_NDEBUG(x) x +#else +#define UNUSED_ARG_NDEBUG(x) UNUSED_ARG (x) +#endif + +#endif /* NN_UNUSED_H */ diff --git a/src/services/ddsi2/code/q_whc.c b/src/services/ddsi2e/core/q_whc.c similarity index 96% rename from src/services/ddsi2/code/q_whc.c rename to src/services/ddsi2e/core/q_whc.c index 99629b6fc..dc90c6daf 100644 --- a/src/services/ddsi2/code/q_whc.c +++ b/src/services/ddsi2e/core/q_whc.c @@ -1,18 +1,16 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * @@ -568,7 +566,7 @@ unsigned whc_remove_acked_messages (struct whc *whc, os_int64 max_drop_seq) assert (max_drop_seq < MAX_SEQ_NUMBER); assert (max_drop_seq >= whc->max_drop_seq); - TRACE_WHC(("whc_removed_acked_messages(%p max_drop_seq %"PA_PRId64")\n", (void *)whc, max_drop_seq)); + TRACE_WHC(("whc_remove_acked_messages(%p max_drop_seq %"PA_PRId64")\n", (void *)whc, max_drop_seq)); TRACE_WHC((" whc: [%"PA_PRId64",%"PA_PRId64"] max_drop_seq %"PA_PRId64" h %u tl %u\n", whc_empty(whc) ? (os_int64)-1 : whc_min_seq(whc), whc_empty(whc) ? (os_int64)-1 : whc_max_seq(whc), @@ -813,6 +811,13 @@ int whc_insert (struct whc *whc, os_int64 max_drop_seq, os_int64 seq, struct nn_ { TRACE_WHC((" unreg:delete\n")); delete_one_instance_from_idx (whc, max_drop_seq, idxn); + if (newn->seq <= max_drop_seq) + { + struct whc_node *prev_seq = newn->prev_seq; + TRACE_WHC((" unreg:seq <= max_drop_seq: delete newn\n")); + whc_delete_one (whc, newn); + whc->maxseq_node = prev_seq; + } } else { @@ -876,6 +881,13 @@ int whc_insert (struct whc *whc, os_int64 max_drop_seq, os_int64 seq, struct nn_ else { TRACE_WHC((" unreg:skip")); + if (newn->seq <= max_drop_seq) + { + struct whc_node *prev_seq = newn->prev_seq; + TRACE_WHC((" unreg:seq <= max_drop_seq: delete newn\n")); + whc_delete_one (whc, newn); + whc->maxseq_node = prev_seq; + } } TRACE_WHC(("\n")); } @@ -886,5 +898,3 @@ os_size_t whc_unacked_bytes (struct whc *whc) { return whc->unacked_bytes; } - -/* SHA1 not available (unoffical build.) */ diff --git a/src/services/ddsi2/code/q_whc.h b/src/services/ddsi2e/core/q_whc.h similarity index 83% rename from src/services/ddsi2/code/q_whc.h rename to src/services/ddsi2e/core/q_whc.h index 271e28825..1c02da09f 100644 --- a/src/services/ddsi2/code/q_whc.h +++ b/src/services/ddsi2e/core/q_whc.h @@ -1,18 +1,16 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * @@ -107,5 +105,3 @@ unsigned whc_remove_acked_messages (struct whc *whc, os_int64 max_drop_seq); #endif #endif /* Q_WHC_H */ - -/* SHA1 not available (unoffical build.) */ diff --git a/src/services/ddsi2/code/q_xevent.c b/src/services/ddsi2e/core/q_xevent.c similarity index 95% rename from src/services/ddsi2/code/q_xevent.c rename to src/services/ddsi2e/core/q_xevent.c index 801b2f690..34f507223 100644 --- a/src/services/ddsi2/code/q_xevent.c +++ b/src/services/ddsi2e/core/q_xevent.c @@ -1,18 +1,16 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * @@ -206,7 +204,7 @@ static void trace_msg (const char *func, const struct nn_xmsg *m) os_int64 wrseq; nn_fragment_number_t wrfragid; nn_xmsg_guid_seq_fragid (m, &wrguid, &wrseq, &wrfragid); - TRACE ((" %s(%x:%x:%x:%x/%lld/%u)", func, PGUID (wrguid), wrseq, wrfragid)); + TRACE ((" %s("PGUIDFMT"/%lld/%u)", func, PGUID (wrguid), wrseq, wrfragid)); } } #else @@ -612,7 +610,7 @@ static void handle_xevk_heartbeat (struct nn_xpack *xp, struct xevent *ev, nn_mt if ((wr = ephash_lookup_writer_guid (&ev->u.heartbeat.wr_guid)) == NULL) { - TRACE (("heartbeat(wr %x:%x:%x:%x) writer gone\n", + TRACE (("heartbeat(wr "PGUIDFMT") writer gone\n", PGUID (ev->u.heartbeat.wr_guid))); return; } @@ -638,7 +636,7 @@ static void handle_xevk_heartbeat (struct nn_xpack *xp, struct xevent *ev, nn_mt t_next.v = tnow.v + writer_hbcontrol_intv (wr, tnow); } - TRACE (("heartbeat(wr %x:%x:%x:%x%s) %s, resched in %g s (min-ack %"PA_PRId64"%s, avail-seq %"PA_PRId64", xmit %lld)\n", + TRACE (("heartbeat(wr "PGUIDFMT"%s) %s, resched in %g s (min-ack %"PA_PRId64"%s, avail-seq %"PA_PRId64", xmit %lld)\n", PGUID (wr->e.guid), hbansreq ? "" : " final", msg ? "sent" : "suppressed", @@ -833,7 +831,7 @@ static void add_AckNack (struct nn_xmsg *msg, struct proxy_writer *pwr, struct p nn_xmsg_shrink (msg, sm_marker, ACKNACK_SIZE (an->readerSNState.numbits)); nn_xmsg_submsg_setnext (msg, sm_marker); - TRACE (("acknack %x:%x:%x:%x -> %x:%x:%x:%x: #%d:%"PA_PRId64"/%d:", + TRACE (("acknack "PGUIDFMT" -> "PGUIDFMT": #%d:%"PA_PRId64"/%d:", PGUID (rwn->rd_guid), PGUID (pwr->e.guid), rwn->count, base, an->readerSNState.numbits)); for (ui = 0; ui != an->readerSNState.numbits; ui++) @@ -922,13 +920,19 @@ static void handle_xevk_acknack (UNUSED_ARG (struct nn_xpack *xp), struct xevent { rwn->t_last_nack = tnow; rwn->seq_last_nack = nack_seq; + /* If NACKing, make sure we don't give up too soon: even though + we're not allowed to send an ACKNACK unless in response to a + HEARTBEAT, I've seen too many cases of not sending an NACK + because the writing side got confused ... Better to recover + eventually. */ + resched_xevent_if_earlier (ev, add_duration_to_mtime (tnow, config.auto_resched_nack_delay)); } - TRACE (("send acknack(rd %x:%x:%x:%x -> pwr %x:%x:%x:%x)\n", + TRACE (("send acknack(rd "PGUIDFMT" -> pwr "PGUIDFMT")\n", PGUID (ev->u.acknack.rd_guid), PGUID (ev->u.acknack.pwr_guid))); } else { - TRACE (("skip acknack(rd %x:%x:%x:%x -> pwr %x:%x:%x:%x): no address\n", + TRACE (("skip acknack(rd "PGUIDFMT" -> pwr "PGUIDFMT"): no address\n", PGUID (ev->u.acknack.rd_guid), PGUID (ev->u.acknack.pwr_guid))); msg = NULL; } @@ -977,14 +981,14 @@ static void handle_xevk_spdp (UNUSED_ARG (struct nn_xpack *xp), struct xevent *e if ((pp = ephash_lookup_participant_guid (&ev->u.spdp.pp_guid)) == NULL) { - TRACE (("handle_xevk_spdp %x:%x:%x:%x - unknown guid\n", + TRACE (("handle_xevk_spdp "PGUIDFMT" - unknown guid\n", PGUID (ev->u.spdp.pp_guid))); return; } if ((spdp_wr = get_builtin_writer (pp, NN_ENTITYID_SPDP_BUILTIN_PARTICIPANT_WRITER)) == NULL) { - TRACE (("handle_xevk_spdp %x:%x:%x:%x - spdp writer of participant not found\n", + TRACE (("handle_xevk_spdp "PGUIDFMT" - spdp writer of participant not found\n", PGUID (ev->u.spdp.pp_guid))); goto skip; } @@ -1002,7 +1006,7 @@ static void handle_xevk_spdp (UNUSED_ARG (struct nn_xpack *xp), struct xevent *e guid.entityid.u = NN_ENTITYID_SPDP_BUILTIN_PARTICIPANT_READER; if ((prd = ephash_lookup_proxy_reader_guid (&guid)) == NULL) { - TRACE (("xmit spdp: no proxy reader %x:%x:%x:%x\n", PGUID (guid))); + TRACE (("xmit spdp: no proxy reader "PGUIDFMT"\n", PGUID (guid))); goto skip; } } @@ -1010,7 +1014,7 @@ static void handle_xevk_spdp (UNUSED_ARG (struct nn_xpack *xp), struct xevent *e /* Look up data in (transient-local) WHC by key value */ if ((st = ddsi_serstate_new (gv.serpool, NULL)) == NULL) { - TRACE (("xmit spdp: skip %x:%x:%x:%x: out of memory\n", PGUID (ev->u.spdp.pp_guid))); + TRACE (("xmit spdp: skip "PGUIDFMT": out of memory\n", PGUID (ev->u.spdp.pp_guid))); goto skip; } kh = nn_hton_guid (ev->u.spdp.pp_guid); @@ -1053,7 +1057,7 @@ static void handle_xevk_spdp (UNUSED_ARG (struct nn_xpack *xp), struct xevent *e } else { - TRACE (("xmit spdp: suppressing early spdp response from %x:%x:%x:%x to %x:%x:%x:%x\n", + TRACE (("xmit spdp: suppressing early spdp response from "PGUIDFMT" to "PGUIDFMT"\n", PGUID (pp->e.guid), PGUIDPREFIX (ev->u.spdp.dest_proxypp_guid_prefix), NN_ENTITYID_PARTICIPANT)); } } @@ -1085,7 +1089,7 @@ static void handle_xevk_spdp (UNUSED_ARG (struct nn_xpack *xp), struct xevent *e if (intv > config.spdp_interval) intv = config.spdp_interval; tnext = add_duration_to_mtime (tnow, intv); - TRACE (("xmit spdp %x:%x:%x:%x to %x:%x:%x:%x (resched %gs)\n", + TRACE (("xmit spdp "PGUIDFMT" to "PGUIDFMT" (resched %gs)\n", PGUID (pp->e.guid), PGUIDPREFIX (ev->u.spdp.dest_proxypp_guid_prefix), NN_ENTITYID_SPDP_BUILTIN_PARTICIPANT_READER, (double)(tnext.v - tnow.v) / 1e9)); @@ -1106,7 +1110,7 @@ static void write_pmd_message (struct nn_xpack *xp, struct participant *pp, unsi if ((wr = get_builtin_writer (pp, NN_ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_WRITER)) == NULL) { - TRACE (("write_pmd_message(%x:%x:%x:%x) - builtin pmd writer not found\n", PGUID (pp->e.guid))); + TRACE (("write_pmd_message("PGUIDFMT") - builtin pmd writer not found\n", PGUID (pp->e.guid))); return; } @@ -1121,12 +1125,12 @@ static void write_pmd_message (struct nn_xpack *xp, struct participant *pp, unsi ddsi_serstate_set_msginfo (serstate, 0, now (), NULL); serdata = ddsi_serstate_fix (serstate); - /* HORRIBLE HACK ALERT -- serstate/serdata looks at whether topic is + /* workaround: serstate/serdata looks at whether topic is a null pointer to choose PL_CDR_x encoding or regular CDR_x encoding. */ serdata->hdr.identifier = PLATFORM_IS_LITTLE_ENDIAN ? CDR_LE : CDR_BE; - write_sample (xp, wr, serdata); + write_sample_nogc (xp, wr, serdata); #undef PMD_DATA_LENGTH } @@ -1156,7 +1160,7 @@ static void handle_xevk_pmd_update (struct nn_xpack *xp, struct xevent *ev, nn_m if (intv == T_NEVER) { tnext.v = T_NEVER; - TRACE (("resched pmd(%x:%x:%x:%x): never\n", PGUID (pp->e.guid))); + TRACE (("resched pmd("PGUIDFMT"): never\n", PGUID (pp->e.guid))); } else { @@ -1166,7 +1170,7 @@ static void handle_xevk_pmd_update (struct nn_xpack *xp, struct xevent *ev, nn_m tnext.v = tnow.v + intv - 2 * T_SECOND; else tnext.v = tnow.v + 4 * intv / 5; - TRACE (("resched pmd(%x:%x:%x:%x): %gs\n", PGUID (pp->e.guid), (double)(tnext.v - tnow.v) / 1e9)); + TRACE (("resched pmd("PGUIDFMT"): %gs\n", PGUID (pp->e.guid), (double)(tnext.v - tnow.v) / 1e9)); } resched_xevent_if_earlier (ev, tnext); @@ -1178,7 +1182,7 @@ static void handle_xevk_end_startup_mode (UNUSED_ARG (struct nn_xpack *xp), stru struct ephash_enum_writer est; struct writer *wr; assert (gv.startup_mode); - TRACE (("end startup mode\n")); + nn_log (LC_DISCOVERY, "end startup mode\n"); gv.startup_mode = 0; /* FIXME: MEMBAR needed for startup mode (or use a lock) */ ephash_enum_writer_init (&est); @@ -1191,7 +1195,7 @@ static void handle_xevk_end_startup_mode (UNUSED_ARG (struct nn_xpack *xp), stru static void handle_xevk_delete_writer (UNUSED_ARG (struct nn_xpack *xp), struct xevent *ev, UNUSED_ARG (nn_mtime_t tnow)) { /* don't worry if the writer is already gone by the time we get here. */ - TRACE (("handle_xevk_delete_writer: %x:%x:%x:%x\n", PGUID (ev->u.delete_writer.guid))); + TRACE (("handle_xevk_delete_writer: "PGUIDFMT"\n", PGUID (ev->u.delete_writer.guid))); delete_writer_nolinger (&ev->u.delete_writer.guid); delete_xevent (ev); } @@ -1340,6 +1344,7 @@ static void * xevent_thread (struct xeventq * xevq) { struct thread_state1 *self = lookup_thread_state (); struct nn_xpack *xp; + nn_mtime_t next_thread_cputime = { 0 }; xp = nn_xpack_new (xevq->tev_conn, xevq->auxiliary_bandwidth_limit); @@ -1348,6 +1353,8 @@ static void * xevent_thread (struct xeventq * xevq) { nn_mtime_t tnow = now_mt (); + LOG_THREAD_CPUTIME (next_thread_cputime); + handle_xevents (self, xevq, xp, tnow); /* Send to the network unlocked, as it may sleep due to bandwidth @@ -1417,7 +1424,7 @@ void qxev_prd_entityid (struct proxy_reader * prd, nn_guid_prefix_t * id) msg = nn_xmsg_new (gv.xmsgpool, id, sizeof (EntityId_t), NN_XMSG_KIND_CONTROL); if (nn_xmsg_setdstPRD (msg, prd) == 0) { - TRACE ((" qxev_prd_entityid (%x:%x:%x)\n", PGUIDPREFIX (*id))); + TRACE ((" qxev_prd_entityid ("PGIDFMT")\n", PGUIDPREFIX (*id))); nn_xmsg_add_entityid (msg); os_mutexLock (&gv.xevents->lock); ev = qxev_common_nt (gv.xevents, XEVK_ENTITYID); @@ -1444,7 +1451,7 @@ void qxev_pwr_entityid (struct proxy_writer * pwr, nn_guid_prefix_t * id) msg = nn_xmsg_new (gv.xmsgpool, id, sizeof (EntityId_t), NN_XMSG_KIND_CONTROL); if (nn_xmsg_setdstPWR (msg, pwr) == 0) { - TRACE ((" qxev_pwr_entityid (%x:%x:%x)\n", PGUIDPREFIX (*id))); + TRACE ((" qxev_pwr_entityid ("PGIDFMT")\n", PGUIDPREFIX (*id))); nn_xmsg_add_entityid (msg); os_mutexLock (&pwr->evq->lock); ev = qxev_common_nt (pwr->evq, XEVK_ENTITYID); @@ -1592,5 +1599,3 @@ struct xevent *qxev_callback (nn_mtime_t tsched, void (*cb) (struct xevent *ev, os_mutexUnlock (&gv.xevents->lock); return ev; } - -/* SHA1 not available (unoffical build.) */ diff --git a/src/services/ddsi2/code/q_xevent.h b/src/services/ddsi2e/core/q_xevent.h similarity index 80% rename from src/services/ddsi2/code/q_xevent.h rename to src/services/ddsi2e/core/q_xevent.h index f87864fbb..0bf0a84b8 100644 --- a/src/services/ddsi2/code/q_xevent.h +++ b/src/services/ddsi2e/core/q_xevent.h @@ -1,18 +1,16 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * @@ -79,5 +77,3 @@ struct xevent *qxev_callback (nn_mtime_t tsched, void (*cb) (struct xevent *xev, } #endif #endif /* NN_XEVENT_H */ - -/* SHA1 not available (unoffical build.) */ diff --git a/src/services/ddsi2/code/q_xmsg.c b/src/services/ddsi2e/core/q_xmsg.c similarity index 86% rename from src/services/ddsi2/code/q_xmsg.c rename to src/services/ddsi2e/core/q_xmsg.c index ec5bc9332..16ce7d606 100644 --- a/src/services/ddsi2/code/q_xmsg.c +++ b/src/services/ddsi2e/core/q_xmsg.c @@ -1,18 +1,16 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * @@ -33,6 +31,8 @@ #include "ut_avl.h" #include "ut_thread_pool.h" +#include "v_kernel.h" + #include "ddsi_ser.h" #include "q_protocol.h" #include "q_xqos.h" @@ -97,6 +97,9 @@ struct nn_xmsg { struct serdata *refd_payload; struct iovec refd_payload_iov; os_int64 maxdelay; +#ifdef DDSI_INCLUDE_NETWORK_PARTITIONS + os_uint32 encoderid; +#endif /* Backref for late updating of available sequence numbers, and merging of retransmits. */ @@ -151,6 +154,15 @@ struct nn_xmsg_chain { struct nn_xmsg_chain_elem *latest; }; +#ifdef DDSI_INCLUDE_BANDWIDTH_LIMITING +#define NN_BW_UNLIMITED (0) + +struct nn_bw_limiter { + os_uint32 bandwidth; /*Config in bytes/s (0 = UNLIMITED)*/ + os_int64 balance; + nn_mtime_t last_update; +}; +#endif struct nn_xpack { @@ -180,8 +192,20 @@ struct nn_xpack struct nn_xmsg_chain included_msgs; +#ifdef DDSI_INCLUDE_BANDWIDTH_LIMITING + struct nn_bw_limiter limiter; +#endif +#ifdef DDSI_INCLUDE_NETWORK_PARTITIONS + os_uint32 encoderId; +#endif /* DDSI_INCLUDE_NETWORK_PARTITIONS */ +#ifdef DDSI_INCLUDE_ENCRYPTION + /* each partion is associated with a SecurityPolicy, this codecset will serve */ + /* all of them, different cipher for each partition */ + q_securityEncoderSet codec; + PT_InfoContainer_t SecurityHeader; +#endif /* DDSI_INCLUDE_ENCRYPTION */ }; static unsigned align4u (unsigned x) @@ -253,6 +277,9 @@ static void nn_xmsg_reinit (struct nn_xmsg *m, enum nn_xmsg_kind kind) m->dstmode = NN_XMSG_DST_UNSET; m->kind = kind; m->maxdelay = 0; +#ifdef DDSI_INCLUDE_NETWORK_PARTITIONS + m->encoderid = 0; +#endif memset (&m->kindspecific, 0, sizeof (m->kindspecific)); } @@ -376,7 +403,7 @@ static int submsg_is_compatible (const struct nn_xmsg *msg, SubmessageKind_t smk /* normal control stuff is ok */ return 1; case SMID_DATA: case SMID_DATA_FRAG: - /* but data is strictly verboten */ + /* but data is strictly forbidden */ return 0; } assert (0); @@ -407,7 +434,7 @@ static int submsg_is_compatible (const struct nn_xmsg *msg, SubmessageKind_t smk case SMID_PT_INFO_CONTAINER: case SMID_PT_MSG_LEN: case SMID_PT_ENTITY_ID: - /* anything else is strictly verboten */ + /* anything else is strictly forbidden */ return 0; } assert (0); @@ -576,7 +603,7 @@ int nn_xmsg_setdstPRD (struct nn_xmsg *m, const struct proxy_reader *prd) } else { - NN_WARNING1("nn_xmsg_setdstPRD: no address for %x:%x:%x:%x", PGUID (prd->e.guid)); + NN_WARNING1("nn_xmsg_setdstPRD: no address for "PGUIDFMT"", PGUID (prd->e.guid)); return ERR_NO_ADDRESS; } } @@ -589,7 +616,7 @@ int nn_xmsg_setdstPWR (struct nn_xmsg *m, const struct proxy_writer *pwr) nn_xmsg_setdst1 (m, &pwr->e.guid.prefix, &loc); return 0; } - NN_WARNING1 ("nn_xmsg_setdstPRD: no address for %x:%x:%x:%x", PGUID (pwr->e.guid)); + NN_WARNING1 ("nn_xmsg_setdstPRD: no address for "PGUIDFMT"", PGUID (pwr->e.guid)); return ERR_NO_ADDRESS; } @@ -645,7 +672,7 @@ int nn_xmsg_merge_rexmit_destinations_wrlock_held (struct nn_xmsg *m, const stru assert (m->kindspecific.data.readerId_off != 0); assert (madd->kindspecific.data.readerId_off != 0); - TRACE ((" (%x:%x:%x:%x#%"PA_PRId64"/%u:", + TRACE ((" ("PGUIDFMT"#%"PA_PRId64"/%u:", PGUID (m->kindspecific.data.wrguid), m->kindspecific.data.wrseq, m->kindspecific.data.wrfragid + 1)); switch (m->dstmode) @@ -723,6 +750,14 @@ int nn_xmsg_setmaxdelay (struct nn_xmsg *msg, os_int64 maxdelay) return 0; } +#ifdef DDSI_INCLUDE_NETWORK_PARTITIONS +int nn_xmsg_setencoderid (struct nn_xmsg *msg, os_uint32 encoderid) +{ + assert (msg->encoderid == 0); + msg->encoderid = encoderid; + return 0; +} +#endif void nn_xmsg_setwriterseq (struct nn_xmsg *msg, const nn_guid_t *wrguid, os_int64 wrseq) { @@ -804,7 +839,11 @@ void nn_xmsg_addpar_keyhash (struct nn_xmsg *m, const struct serdata *serdata) if (!ddsi_serdata_is_empty (serdata)) { char *p = nn_xmsg_addpar (m, PID_KEYHASH, 16); +#if LITE + memcpy (p, serdata->v.keyhash.m_hash, 16); +#else serdata_keyhash (serdata, p); +#endif } } @@ -869,15 +908,28 @@ void nn_xmsg_addpar_BE4u (struct nn_xmsg *m, unsigned pid, unsigned x) void nn_xmsg_addpar_statusinfo (struct nn_xmsg *m, unsigned statusinfo) { - nn_xmsg_addpar_BE4u (m, PID_STATUSINFO, statusinfo); + if ((statusinfo & ~NN_STATUSINFO_STANDARDIZED) == 0) + nn_xmsg_addpar_BE4u (m, PID_STATUSINFO, statusinfo); + else + { + unsigned *p = nn_xmsg_addpar (m, PID_STATUSINFO, 8); + unsigned statusinfox = 0; + assert ((statusinfo & ~NN_STATUSINFO_STANDARDIZED) == NN_STATUSINFO_OSPL_AUTO); + if (statusinfo & NN_STATUSINFO_OSPL_AUTO) + statusinfox |= NN_STATUSINFOX_OSPL_AUTO; + p[0] = toBE4u (statusinfo & NN_STATUSINFO_STANDARDIZED); + p[1] = toBE4u (statusinfox); + } } +#if !LITE void nn_xmsg_addpar_wrinfo (struct nn_xmsg *m, const struct nn_prismtech_writer_info *wri) { struct nn_prismtech_writer_info *p; p = nn_xmsg_addpar (m, PID_PRISMTECH_WRITER_INFO, sizeof (*p)); *p = *wri; } +#endif void nn_xmsg_addpar_share (struct nn_xmsg *m, unsigned pid, const struct nn_share_qospolicy *q) { @@ -1027,7 +1079,7 @@ static void nn_xmsg_chain_release (struct nn_xmsg_chain *chain) if (m->kindspecific.data.wrseq > wr->seq_xmit) { #if 0 - TRACE (("seq(%x:%x:%x:%x -> %lld)", PGUID (m->kindspecific.data.wrguid), m->kindspecific.data.wrseq)); + TRACE (("seq("PGUIDFMT" -> %lld)", PGUID (m->kindspecific.data.wrguid), m->kindspecific.data.wrseq)); #endif wr->seq_xmit = m->kindspecific.data.wrseq; } @@ -1046,6 +1098,71 @@ static void nn_xmsg_chain_add (struct nn_xmsg_chain *chain, struct nn_xmsg *m) chain->latest = &m->link; } +#ifdef DDSI_INCLUDE_BANDWIDTH_LIMITING +/* BW_LIMITER ---------------------------------------------------------- + + Helper for XPACKS, that contain the configuration and state to handle Bandwidth limitation.*/ + +/* To be called after Xpack sends out a packet. + * Keeps a balance of real data vs. allowed data according to the bandwidth limit. + * If data is send too fast, a sleep is inserted to get the used bandwidth at the configured rate. + */ + +#define NN_BW_LIMIT_MAX_BUFFER (-30 * T_MILLISECOND) +#define NN_BW_LIMIT_MIN_SLEEP (2 * T_MILLISECOND) +static void nn_bw_limit_sleep_if_needed(struct nn_bw_limiter* this, os_ssize_t size) +{ + if ( this->bandwidth > 0 ) { + nn_mtime_t tnow = now_mt(); + os_int64 actual_interval; + os_int64 target_interval; + + /* calculate intervals */ + actual_interval = tnow.v - this->last_update.v; + this->last_update = tnow; + + target_interval = T_SECOND*size/this->bandwidth; + + this->balance += (target_interval - actual_interval); + + + TRACE ((" balance < NN_BW_LIMIT_MAX_BUFFER ) + { + /* We're below the bandwidth limit, do not further accumulate */ + this->balance = NN_BW_LIMIT_MAX_BUFFER; + TRACE ((":%"PA_PRId64":max",this->balance/1000)); + } + else if ( this->balance > NN_BW_LIMIT_MIN_SLEEP ) + { + /* We're over the bandwidth limit far enough, to warrent a sleep. */ + os_duration delay; + TRACE ((":%"PA_PRId64":sleep",this->balance/1000)); + delay = OS_DURATION_INIT(0, this->balance); + thread_state_blocked (lookup_thread_state ()); + ospl_os_sleep (delay); + thread_state_unblocked (lookup_thread_state ()); + } + else + { + TRACE ((":%"PA_PRId64"",this->balance/1000)); + } + TRACE ((">")); + } +} + + +static void nn_bw_limit_init (struct nn_bw_limiter *limiter, os_uint32 bandwidth_limit) +{ + limiter->bandwidth = bandwidth_limit; + limiter->balance = 0; + if (bandwidth_limit) + limiter->last_update = now_mt (); + else + limiter->last_update.v = 0; +} +#endif /* DDSI_INCLUDE_BANDWIDTH_LIMITING */ /* XPACK --------------------------------------------------------------- @@ -1061,6 +1178,9 @@ static void nn_xpack_reinit (struct nn_xpack *xp) xp->msg_len.length = 0; xp->included_msgs.latest = NULL; xp->maxdelay = T_NEVER; +#ifdef DDSI_INCLUDE_NETWORK_PARTITIONS + xp->encoderId = 0; +#endif xp->packetid++; } @@ -1092,7 +1212,21 @@ struct nn_xpack * nn_xpack_new (ddsi_tran_conn_t conn , os_uint32 bw_limit) os_sem_init (&xp->sem, 0); +#ifdef DDSI_INCLUDE_ENCRYPTION + if (q_security_plugin.new_encoder) + { + xp->codec = (q_security_plugin.new_encoder) (); + xp->SecurityHeader.smhdr.submessageId = SMID_PT_INFO_CONTAINER; + xp->SecurityHeader.smhdr.flags = PLATFORM_IS_LITTLE_ENDIAN ? SMFLAG_ENDIANNESS : 0;; + xp->SecurityHeader.smhdr.octetsToNextHeader = 4; + xp->SecurityHeader.id = PTINFO_ID_ENCRYPT; + } +#endif +#ifdef DDSI_INCLUDE_BANDWIDTH_LIMITING + nn_bw_limit_init (&xp->limiter, bw_limit); +#else (void) bw_limit; +#endif return xp; } @@ -1100,6 +1234,12 @@ void nn_xpack_free (struct nn_xpack *xp) { assert (xp->niov == 0); assert (xp->included_msgs.latest == NULL); +#ifdef DDSI_INCLUDE_ENCRYPTION + if (q_security_plugin.free_encoder) + { + (q_security_plugin.free_encoder) (xp->codec); + } +#endif os_sem_destroy (&xp->sem); os_free (xp); } @@ -1162,8 +1302,15 @@ static os_ssize_t nn_xpack_send1 (const nn_locator_t *loc, void * varg) mhdr.msg_name = &addr; mhdr.msg_namelen = sockaddr_size (&addr); +#ifdef DDSI_INCLUDE_ENCRYPTION + if (q_security_plugin.send_encoded && xp->encoderId != 0 && (q_security_plugin.encoder_type) (xp->codec, xp->encoderId) != Q_CIPHER_NONE) { - if (!gv.deaf_mute) + nbytes = (q_security_plugin.send_encoded) (xp->conn, &mhdr, &xp->codec, xp->encoderId, xp->call_flags); + } + else +#endif + { + if (!gv.mute && !(pa_ld32(&gv.ospl_kernel->isolate) & V_ISOLATE_MUTE)) nbytes = ddsi_conn_write (xp->conn, &mhdr, xp->msg_len.length, xp->call_flags); else { @@ -1176,6 +1323,12 @@ static os_ssize_t nn_xpack_send1 (const nn_locator_t *loc, void * varg) xp->call_flags = 0; +#ifdef DDSI_INCLUDE_BANDWIDTH_LIMITING + if (nbytes > 0) + { + nn_bw_limit_sleep_if_needed (&xp->limiter, nbytes); + } +#endif return nbytes; } @@ -1335,6 +1488,15 @@ static int nn_xpack_mayaddmsg (const struct nn_xpack *xp, const struct nn_xmsg * payload_size = m->refd_payload ? (unsigned) m->refd_payload_iov.iov_len : 0; +#ifdef DDSI_INCLUDE_ENCRYPTION + if (xp->encoderId) + { + unsigned security_header; + security_header = (q_security_plugin.header_size) (xp->codec, xp->encoderId); + assert (security_header < max_msg_size); + max_msg_size -= security_header; + } +#endif /* Check if max message size exceeded */ @@ -1350,6 +1512,11 @@ static int nn_xpack_mayaddmsg (const struct nn_xpack *xp, const struct nn_xmsg * return 0; } +#ifdef DDSI_INCLUDE_NETWORK_PARTITIONS + /* Don't mix up xmsg for different encoders */ + if (xp->encoderId != m->encoderid) + return 0; +#endif return addressing_info_eq_onesidederr (xp, m); } @@ -1411,7 +1578,7 @@ int nn_xpack_addmsg (struct nn_xpack *xp, struct nn_xmsg *m, const os_uint32 fla break; case NN_XMSG_KIND_DATA: case NN_XMSG_KIND_DATA_REXMIT: - TRACE (("%s(%x:%x:%x:%x:#%"PA_PRId64"/%u)", + TRACE (("%s("PGUIDFMT":#%"PA_PRId64"/%u)", (m->kind == NN_XMSG_KIND_DATA) ? "data" : "rexmit", PGUID (m->kindspecific.data.wrguid), m->kindspecific.data.wrseq, @@ -1441,6 +1608,20 @@ int nn_xpack_addmsg (struct nn_xpack *xp, struct nn_xmsg *m, const os_uint32 fla niov++; } +#ifdef DDSI_INCLUDE_NETWORK_PARTITIONS + xp->encoderId = m->encoderid; +#endif +#ifdef DDSI_INCLUDE_ENCRYPTION + if (xp->encoderId > 0 && (q_security_plugin.encoder_type) (xp->codec, xp->encoderId) != Q_CIPHER_NONE) + { + /* Insert a reference to the security header + the correct size will be set upon encryption in q_xpack_sendmsg_encoded */ + xp->iov[niov].iov_base = (void*) &xp->SecurityHeader; + xp->iov[niov].iov_len = sizeof (xp->SecurityHeader); + sz += xp->iov[niov].iov_len; + niov++; + } +#endif xp->last_src = &xp->hdr.guid_prefix; xp->last_dst = NULL; } @@ -1557,5 +1738,3 @@ unsigned nn_xpack_packetid (const struct nn_xpack *xp) { return xp->packetid; } - -/* SHA1 not available (unoffical build.) */ diff --git a/src/services/ddsi2/code/q_xmsg.h b/src/services/ddsi2e/core/q_xmsg.h similarity index 91% rename from src/services/ddsi2/code/q_xmsg.h rename to src/services/ddsi2e/core/q_xmsg.h index 6e836d0d3..cd42a460b 100644 --- a/src/services/ddsi2/code/q_xmsg.h +++ b/src/services/ddsi2e/core/q_xmsg.h @@ -1,18 +1,16 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * @@ -79,6 +77,9 @@ void nn_xmsg_setdstN (struct nn_xmsg *msg, struct addrset *as, struct addrset *a int nn_xmsg_setmaxdelay (struct nn_xmsg *msg, os_int64 maxdelay); +#ifdef DDSI_INCLUDE_NETWORK_PARTITIONS +int nn_xmsg_setencoderid (struct nn_xmsg *msg, os_uint32 encoderid); +#endif /* Sets the location of the destination readerId within the message (address changes because of reallocations are handled correctly). @@ -136,7 +137,9 @@ void nn_xmsg_addpar_reliability (struct nn_xmsg *m, unsigned pid, const struct n void nn_xmsg_addpar_share (struct nn_xmsg *m, unsigned pid, const struct nn_share_qospolicy *rq); void nn_xmsg_addpar_subscription_keys (struct nn_xmsg *m, unsigned pid, const struct nn_subscription_keys_qospolicy *rq); +#if !LITE void nn_xmsg_addpar_wrinfo (struct nn_xmsg *m, const struct nn_prismtech_writer_info *wri); +#endif void nn_xmsg_addpar_parvinfo (struct nn_xmsg *m, unsigned pid, const struct nn_prismtech_participant_version_info *pvi); void nn_xmsg_addpar_eotinfo (struct nn_xmsg *m, unsigned pid, const struct nn_prismtech_eotinfo *txnid); void nn_xmsg_addpar_sentinel (struct nn_xmsg *m); @@ -155,5 +158,3 @@ unsigned nn_xpack_packetid (const struct nn_xpack *xp); } #endif #endif /* NN_XMSG_H */ - -/* SHA1 not available (unoffical build.) */ diff --git a/src/services/ddsi2/code/q_xqos.h b/src/services/ddsi2e/core/q_xqos.h similarity index 94% rename from src/services/ddsi2/code/q_xqos.h rename to src/services/ddsi2e/core/q_xqos.h index 162e3c2da..2e0596485 100644 --- a/src/services/ddsi2/code/q_xqos.h +++ b/src/services/ddsi2e/core/q_xqos.h @@ -1,18 +1,16 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * @@ -242,7 +240,9 @@ typedef struct nn_share_qospolicy { #define QP_PRISMTECH_RELAXED_QOS_MATCHING ((os_uint64)1 << 23) #define QP_PRISMTECH_READER_LIFESPAN ((os_uint64)1 << 24) #define QP_PRISMTECH_SUBSCRIPTION_KEYS ((os_uint64)1 << 25) +#if !LITE #define QP_PRISMTECH_SHARE ((os_uint64)1 << 26) +#endif #define QP_PRISMTECH_ENTITY_FACTORY ((os_uint64)1 << 27) #define QP_PRISMTECH_SYNCHRONOUS_ENDPOINT ((os_uint64)1 << 28) #define QP_RTI_TYPECODE ((os_uint64)1 << 29) @@ -326,5 +326,3 @@ nn_xqos_t *nn_xqos_dup (const nn_xqos_t *src); #endif #endif /* NN_XQOS_H */ - -/* SHA1 not available (unoffical build.) */ diff --git a/src/services/ddsi2/code/sysdeps.c b/src/services/ddsi2e/core/sysdeps.c similarity index 86% rename from src/services/ddsi2/code/sysdeps.c rename to src/services/ddsi2e/core/sysdeps.c index ff39d0c2d..f3ba3fdc1 100644 --- a/src/services/ddsi2/code/sysdeps.c +++ b/src/services/ddsi2e/core/sysdeps.c @@ -1,18 +1,16 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * @@ -27,6 +25,9 @@ #include "os_socket.h" #include "os_atomics.h" #include "os_errno.h" +#ifndef SYSDEPS_HAVE_RANDOM +#include "os_stdlib.h" +#endif #include "q_error.h" #include "q_log.h" @@ -200,7 +201,7 @@ long random (void) union { long x; unsigned char c[4]; } t; int i; for (i = 0; i < 4; i++) - t.c[i] = (unsigned char) ((rand () >> 4) & 0xff); + t.c[i] = (unsigned char) ((os_rand () >> 4) & 0xff); #if RAND_MAX == 0x7fffffff || RAND_MAX == 0x7fff t.x &= RAND_MAX; #elif RAND_MAX <= 0x7ffffffe @@ -277,20 +278,18 @@ void log_stacktrace (const char *name, os_threadId tid) #include static pa_uint32_t log_stacktrace_flag = PA_UINT32_INIT(0); +static struct { + int depth; + void *stk[64]; +} log_stacktrace_stk; + static void log_stacktrace_sigh (int sig __attribute__ ((unused))) { - void *stk[64]; - char **strs; - int i, n; - nn_log (~0u, "-- stack trace follows --\n"); - n = backtrace (stk, (int) (sizeof (stk) / sizeof (*stk))); - strs = backtrace_symbols (stk, n); - for (i = 0; i < n; i++) - nn_log (~0u, "%s\n", strs[i]); - free (strs); - nn_log (~0u, "-- end of stack trace --\n"); + int e = os_getErrno(); + log_stacktrace_stk.depth = backtrace (log_stacktrace_stk.stk, (int) (sizeof (log_stacktrace_stk.stk) / sizeof (*log_stacktrace_stk.stk))); pa_inc32 (&log_stacktrace_flag); + os_setErrno(e); } void log_stacktrace (const char *name, os_threadId tid) @@ -303,20 +302,26 @@ void log_stacktrace (const char *name, os_threadId tid) { const os_duration d = OS_DURATION_INIT(0, 1000000); struct sigaction act, oact; + char **strs; + int i; nn_log (~0u, "-- stack trace of %s requested --\n", name); act.sa_handler = log_stacktrace_sigh; act.sa_flags = 0; - sigfillset (&act.sa_mask); + (void)sigfillset (&act.sa_mask); while (!pa_cas32 (&log_stacktrace_flag, 0, 1)) - os_sleep (d); + ospl_os_sleep (d); sigaction (SIGXCPU, &act, &oact); pthread_kill (tid, SIGXCPU); while (!pa_cas32 (&log_stacktrace_flag, 2, 3)) - os_sleep (d); + ospl_os_sleep (d); sigaction (SIGXCPU, &oact, NULL); + nn_log (~0u, "-- stack trace follows --\n"); + strs = backtrace_symbols (log_stacktrace_stk.stk, log_stacktrace_stk.depth); + for (i = 0; i < log_stacktrace_stk.depth; i++) + nn_log (~0u, "%s\n", strs[i]); + free (strs); + nn_log (~0u, "-- end of stack trace --\n"); pa_st32 (&log_stacktrace_flag, 0); } } #endif - -/* SHA1 not available (unoffical build.) */ diff --git a/src/services/ddsi2/code/sysdeps.h b/src/services/ddsi2e/core/sysdeps.h similarity index 89% rename from src/services/ddsi2/code/sysdeps.h rename to src/services/ddsi2e/core/sysdeps.h index 1eddc7309..6873e0e5e 100644 --- a/src/services/ddsi2/code/sysdeps.h +++ b/src/services/ddsi2e/core/sysdeps.h @@ -1,18 +1,16 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * @@ -206,5 +204,3 @@ NN_C99_INLINE void *os_atomic_lifo_pop (os_atomic_lifo_t *head, os_size_t linkof #endif #endif /* SYSDEPS_H */ - -/* SHA1 not available (unoffical build.) */ diff --git a/src/services/ddsi2e/extract-configurator-xml.awk b/src/services/ddsi2e/extract-configurator-xml.awk new file mode 100644 index 000000000..8c9a8455c --- /dev/null +++ b/src/services/ddsi2e/extract-configurator-xml.awk @@ -0,0 +1,442 @@ +#!/usr/bin/gawk -f + +# NOTES: +# - limited formatting freedom +# - default value may not contain a semicolon +# - absolutely no HTML-tag-like things in descriptions +# +# UGLINESSES: +# - knowledge of conversion functions in here +# - hard definitions of enums in here +# - negated_boolean is A BIT WEIRD and special-cased + +BEGIN { + if (version != "COMMUNITY" && version != "COMMERCIAL") { + print "script error: variable 'version' must be set to COMMUNITY or COMMERCIAL" > "/dev/stderr"; + exit 1; + } + + typehint2xmltype["____"] = "____"; + typehint2xmltype["networkAddress"] = "String"; + typehint2xmltype["partitionAddress"] = "String"; + typehint2xmltype["networkAddresses"] = "String"; + typehint2xmltype["ipv4"] = "String"; + typehint2xmltype["boolean"] = "Boolean"; + typehint2xmltype["negated_boolean"] = "Boolean"; + typehint2xmltype["boolean_default"] = "Enum"; + typehint2xmltype["string"] = "String"; + typehint2xmltype["tracingOutputFileName"] = "String"; + typehint2xmltype["verbosity"] = "Enum"; + typehint2xmltype["logcat"] = "String"; + typehint2xmltype["peer"] = "String"; + typehint2xmltype["float"] = "Float"; + typehint2xmltype["int"] = "Int"; + typehint2xmltype["int32"] = "Int"; + typehint2xmltype["uint"] = "Int"; + typehint2xmltype["uint32"] = "Int"; + typehint2xmltype["natint"] = "Int"; + typehint2xmltype["natint_255"] = "Int"; + typehint2xmltype["domainId"] = "Int"; + typehint2xmltype["participantIndex"] = "String"; + typehint2xmltype["port"] = "Int"; + typehint2xmltype["dyn_port"] = "Int"; + typehint2xmltype["duration_inf"] = "String"; + typehint2xmltype["duration_ms_1hr"] = "String"; + typehint2xmltype["duration_ms_1s"] = "String"; + typehint2xmltype["duration_us_1s"] = "String"; + typehint2xmltype["memsize"] = "String"; + typehint2xmltype["bandwidth"] = "String"; + typehint2xmltype["standards_conformance"] = "Enum"; + typehint2xmltype["locators"] = "Enum"; + typehint2xmltype["service_name"] = "String"; + typehint2xmltype["sched_class"] = "Enum"; + typehint2xmltype["cipher"] = "Enum"; + typehint2xmltype["besmode"] = "Enum"; + typehint2xmltype["retransmit_merging"] = "Enum"; + typehint2xmltype["sched_prio_class"] = "Enum"; + typehint2xmltype["sched_class"] = "Enum"; + typehint2xmltype["maybe_int32"] = "String"; + typehint2xmltype["maybe_memsize"] = "String"; + typehint2xmltype["maybe_duration_inf"] = "String"; + typehint2xmltype["allow_multicast"] = "String"; + + typehint2unit["duration_inf"] = "duration_inf"; + typehint2unit["duration_ms_1hr"] = "duration"; + typehint2unit["duration_ms_1s"] = "duration"; + typehint2unit["duration_us_1s"] = "duration"; + typehint2unit["bandwidth"] = "bandwidth"; + typehint2unit["memsize"] = "memsize"; + typehint2unit["maybe_memsize"] = "memsize"; + typehint2unit["maybe_duration_inf"] = "duration_inf"; + + enum_values["locators"] = "local;none"; + enum_values["standards_conformance"] = "lax;strict;pedantic"; + enum_values["verbosity"] = "finest;finer;fine;config;info;warning;severe;none"; + enum_values["besmode"] = "full;writers;minimal"; + enum_values["retransmit_merging"] = "never;adaptive;always"; + enum_values["sched_prio_class"] = "relative;absolute"; + enum_values["sched_class"] = "realtime;timeshare;default"; + enum_values["cipher"] = "null;blowfish;aes128;aes192;aes256"; + enum_values["boolean_default"] = "false;true;default"; + + range["port"] = "1;65535"; + range["dyn_port"] = "-1;65535"; + range["domainId"] = "0;229"; + range["general_cfgelems/startupmodeduration"] = "0;60000"; + range["natint_255"] = "0;255"; + range["duration_ms_1hr"] = "0;1hr"; + range["duration_ms_1s"] = "0;1s"; + range["duration_us_1s"] = "0;1s"; + + unit_blurb["bandwidth"] = "\n

    The unit must be specified explicitly. Recognised units: Xb/s, Xbps for bits/s or XB/s, XBps for bytes/s; where X is an optional prefix: k for 103, Ki for 210, M for 106, Mi for 220, G for 109, Gi for 230.

    "; + unit_blurb["memsize"] = "\n

    The unit must be specified explicitly. Recognised units: B (bytes), kB & KiB (210 bytes), MB & MiB (220 bytes), GB & GiB (230 bytes).

    "; + unit_blurb["duration"] = "\n

    The unit must be specified explicitly. Recognised units: ns, us, ms, s, min, hr, day.

    "; + unit_blurb["duration_inf"] = "\n

    Valid values are finite durations with an explicit unit or the keyword 'inf' for infinity. Recognised units: ns, us, ms, s, min, hr, day.

    "; + + # Some default overrides are set in the END section, as they are + # dependent on some configuration items + #default_overrides["ddsi2_cfgattrs/name"] + + for(x in typehint2xmltype) { + if(typehint2xmltype[x] == "Enum") { + if(enum_values[x] == "") { + print "script error: values of enum type "x" unknown" > "/dev/stderr"; + exit 1; + } + } + } +} + +function clean_description(desc) { + desc = gensub (/^ *"/, "", 1, desc); + desc = gensub (/ *" *(\} *, *$)?$/, "", 1, desc); + desc = gensub (/\\"/, "\"", "g", desc); + desc = gensub (/\\n\\/, "\n", "g", desc); + desc = gensub (/\\\\/, "\\", "g", desc); + return desc; +} + +function store_entry() { + name = gensub (/\|.*/, "", 1, name); # aliases are not visible in osplconf + ltable = tolower(table); + lname = tolower(name); + if(tab2elems[ltable] == "") { + tab2elems[ltable] = name; + } else { + tab2elems[ltable] = tab2elems[table]";"name + } + elem[ltable"/"lname] = kind";"subtable";"multiplicity";"defaultvalue";"typehint; + desc[ltable"/"lname] = clean_description(description)""unit_blurb[typehint2unit[typehint]]; + if(typehint2xmltype[typehint] == "") { + print FILENAME":near "NR": error: no mapping defined for type "typehint > "/dev/stderr"; + exit 1; + } + typehint_seen[typehint] = 1; + #print ltable"/"lname" - "elem[ltable"/"lname]; + #typehint = ""; +} + +function print_description(desc,indent, ls,i) { # ls,i: locals + print indent" "; +} + +function kind_to_kstr(kind,typehint,table,name) { + if(kind == "GROUP" || kind == "MGROUP") { + return "element"; + } else if(kind == "ATTR") { + return "attribute"typehint2xmltype[typehint]; + } else if(kind == "LEAF") { + return "leaf"typehint2xmltype[typehint]; + } else { + print FILENAME": error: fs_to_kstr: "kind" unrecognized kind ("table"/"name")" > "/dev/stderr"; + exit 1; + } +} + +function transform_default(fs, tmp,map) { # tmp, map: local + tmp = gensub(/^"(.*)"$/, "\\1", 1, fs[4]); + if(fs[5] != "negated_boolean") { + return tmp; + } else { + map["true"] = "false"; + map["false"] = "true"; + return map[tolower(tmp)]; + } +} + +function conv_to_xml(table,name,indent,prefix, fs,vs,vsn,kstr,ts,tsi,tsn,i,min_occ,max_occ,rr,req) { # fs,vs,kstr,... are locals + split(elem[tolower(table"/"name)], fs, ";"); + #print table"/"name" - "; for(x in fs) { print " - "x" "fs[x]; } + kstr = kind_to_kstr(fs[1], fs[5], table, name); + if(fs[3] == 0) { + min_occ = max_occ = 0; + } else if(fs[3] == 1) { # multiplicity = 1 => required if no default + if(fs[1] == "GROUP" || fs[1] == "MGROUP") { + min_occ = 0; # unless it's a group + } else if(fs[4] == "" || fs[4] == "NULL") { + min_occ = 1; + } else { + min_occ = 0; + } + max_occ = 1; + } else { + min_occ = 0; max_occ = fs[3]; + } + if(fs[1] == "ATTR") { + req = (min_occ == 0) ? "false" : "true"; + print indent"<"kstr" name=\""name"\" required=\""req"\" version=\""version"\">"; + } else { + print indent"<"kstr" name=\""name"\" minOccurrences=\""min_occ"\" maxOccurrences=\""max_occ"\" version=\""version"\">"; + } + print_description(prefix""desc[tolower(table"/"name)], indent); + # enum, int ranges + if(enum_values[fs[5]]) { + vsn=split(enum_values[fs[5]], vs, ";"); + for(i = 1; i <= vsn; i++) { + print indent" "vs[i]""; + } + } + rr = range[tolower(table"/"name)]; + if(rr == "" && range[fs[5]] != "") { rr = range[fs[5]]; } + if(rr != "") { + split(rr, vs, ";"); + print indent" "vs[1]""; + print indent" "vs[2]""; + } + # remarkably, osplconf can't deal with strings for which no maximum + # length is specified, even though it accepts unlimited length + # strings ... + if(typehint2xmltype[fs[5]] == "String") { + print indent" 0"; + } + # default not applicable to GROUPs + if(fs[1] != "GROUP" && fs[1] != "MGROUP") { + defover = default_overrides[tolower(table"/"name)]; + if(defover != "") { + print indent" "defover""; + } else if(fs[4] == "" || fs[4] == "NULL") { + print indent" "; + } else { + print indent" "transform_default(fs)""; + } + } + # recurse into subtables if any + if(fs[2] != "") { + split(fs[2], ts, ","); + tsn = asort(ts,tsi); + for(i = 1; i <= tsn; i++) { + conv_table_to_xml(tsi[i], indent" ", prefix); + } + } + print indent""; +} + +function conv_table_to_xml(table,indent,prefix, ns,nsi,nsn,i) { # ns,i are locals + split(tab2elems[table], ns, ";"); + nsn = asort(ns,nsi); + for(i = 1; i <= nsn; i++) { + conv_to_xml(table, nsi[i], indent, (table == "unsupp_cfgelems") ? "Internal" : prefix); + } +} + +gobbling_description { + description = description""$0; + #print " .. "$0; +} + +gobbling_description && /(^|") *\} *, *$/ { + gobbling_description = 0; + store_entry(); + next; +} + +gobbling_description { + next; +} + +/^[ \t]*#[ \t]*(if[ \t]+LITE($|[^A-Za-z_0-9]))/ { + # skip LITE, but note that we ONLY handle #if LITE ... (#else ...) + # #endif, no support for comments or anything similarly fancy. + skip_lite=1; +} +skip_lite && /^[ \t]*#[ \t]*(else|endif)[ \t]*$/ { + skip_lite=0; +} + +skip_lite || /^[ \t]*(#[ \t]*(if|ifdef|ifndef|else|endif).*)?$/ { # skip empty lines, preproc + next; +} + +/^ *END_MARKER *$/ { + if(!in_table) { + print FILENAME":near "NR": END_MARKER seen while not in a table" > "/dev/stderr"; + } + in_table = 0; + #print "END_MARKER "table; + next; +} + +/^static +const +struct +cfgelem +/ { + in_table = 1; + table = gensub(/^static +const +struct +cfgelem +([A-Za-z_0-9]+).*/, "\\1", 1, $0); + #print "TABLE "table; + next; +} + +in_table && /^ *WILDCARD *, *$|^ *\{ *(MOVED) *\(/ { + next; +} + +# Recognise all "normal" entries: attributes, groups, leaves and +# leaves with attributes. This doesn't recognise the ones used for the +# root groups: those are dealt with by the next pattern +in_table && /^ *\{ *(ATTR|GROUP|MGROUP|LEAF|LEAF_W_ATTRS) *\(/ { + rest = $0; + # extract kind + re = "^ *\\{ *(ATTR|GROUP|MGROUP|LEAF|LEAF_W_ATTRS) *\\( *"; + kind = gensub(re".*", "\\1", 1, rest); rest = gensub(re, "", 1, rest); + # extract name + reference to subtable + re = "\"([A-Za-z_0-9|]+)\" *"; + name = gensub(re".*", "\\1", 1, rest); rest = gensub(re, "", 1, rest); + subelems = subattrs = ""; + if(kind == "GROUP" || kind == "MGROUP") { + re = ", *([A-Za-z_0-9]+) *"; + subelems = gensub(re".*", "\\1", 1, rest); rest = gensub(re, "", 1, rest); + } + if(kind == "LEAF_W_ATTRS" || kind == "MGROUP") { + re = ", *([A-Za-z_0-9]+) *"; + subattrs = gensub(re".*", "\\1", 1, rest); rest = gensub(re, "", 1, rest); + } + + subtable = ""; + if(subelems != "") { subtable = subelems; } + if(subattrs != "") { + if(subtable != "") { subtable = subtable","subattrs; } + else { subtable = subattrs; } + } + rest = gensub(/ *) *, */, "", 1, rest); + #print " kind "kind" name "name" subtable "subtable; + + # don't care about the distinction between LEAF and LEAF_W_ATTRS + # in the remainer of the code: we simply rely on subtable. + if(kind == "LEAF_W_ATTRS") { + kind = "LEAF"; + } +} + +# Root groups: use a special trick, which allows them to do groups +# with attributes. Which the DDSI2 proper doesn't use, but which the +# service configuration stuff does rely on. +in_table && /^ *\{ *"([A-Za-z_0-9|]+)" *, */ { + rest = $0; + # root elements are all groups, formatted as: , , + # , NODATA, description. They're therefore pretty easy to + # parse. + kind = "GROUP"; + re = "^ *\\{ *\"([A-Za-z_0-9|]+)\" *, *"; + name = gensub (re".*", "\\1", 1, rest); rest = gensub(re, "", 1, rest); + # then follow the sub-elements and the attributes + re = "([A-Za-z_0-9]+) *, *"; + subelems = gensub(re".*", "\\1", 1, rest); rest = gensub(re, "", 1, rest); + subattrs = gensub(re".*", "\\1", 1, rest); rest = gensub(re, "", 1, rest); + # then we require NODATA (could do this in the pattern also) + if(!match(rest, /^NODATA *,/)) { + print FILENAME":near "NR": error: NODATA expected" > "/dev/stderr"; + exit 1; + } + # multiplicity is hard coded: we want to allow multiple ddsi2 services + multiplicity = 0; + subtable = ""; + if(subelems != "NULL") { subtable = subelems; } + if(subattrs != "NULL") { + if(subtable != "") { subtable = subtable","subattrs; } + else { subtable = subattrs; } + } + rest = gensub(re, "", 1, rest); +} + +# Extract stuff specific to ATTRs, LEAFs and MGROUPs +in_table && (kind == "ATTR" || kind == "LEAF" || kind == "MGROUP") { + # extract multiplicity + re = "([0-9]+) *, *"; + multiplicity = gensub(re".*", "\\1", 1, rest); rest = gensub(re, "", 1, rest); + # extract default value + re = "(\"([^\"]*)\"|NULL|0) *, *"; + defaultvalue = gensub(re".*", "\\1", 1, rest); rest = gensub(re, "", 1, rest); + if(defaultvalue == "0") { defaultvalue = "NULL"; } + # skip reference to internal name (either ABSOFF(field), + # RELOFF(field,field) or , (the latter being used by + # "verbosity") + rest = gensub(/(ABSOFF *\( *[A-Za-z_0-9.]+ *\)|RELOFF *\( *[A-Za-z_0-9.]+ *, *[A-Za-z_0-9]+ *\)|[0-9]+ *, *[0-9]+) *, */, "", 1, rest); + # skip init function + rest = gensub(/([A-Za-z_0-9]+|0) *, */, "", 1, rest); + # type hint from conversion function + re = "(uf_([A-Za-z_0-9]+)|NULL|0) *, *"; + typehint = gensub(re".*", "\\1", 1, rest); rest = gensub(re, "", 1, rest); + typehint = gensub(/^uf_/, "", 1, typehint); + # accept typehint = NULL for a LEAF_WITH_ATTRS: there is no defined + # "syntax" for groups that have only attributes, pretending it is a + # group because that causes us to emit an "element" and not a + # "leaf". + if(typehint == "0" || typehint == "NULL") { + kind = "GROUP"; + typehint = "____"; + } + # skip free, print functions + rest = gensub(/([A-Za-z_0-9]+|0) *, *([A-Za-z_0-9]+|0) *, */, "", 1, rest); + #print " .. multiplicity "multiplicity" default "defaultvalue" typehint "typehint; +} + +# Extract description (or NULL, if not to be included in the configurator XML) +in_table { + #print " .. "rest; + # description or NULL + if(match(rest, /NULL *\} *, *$/)) { + # no description - discard this one/simply continue with next one + } else if(match(rest, /".*" *\} *, *$/)) { + # description ending on same line + description = gensub(/(".*").*/, "\\1", 1, rest); + store_entry(); + } else { + # strip the quotes &c. once the full text has been gathered + description = rest; + gobbling_description = 1; + } + #print " .. gobbling "gobbling_description; + next; +} + +END { + #print FILENAME": "tab2elems["root_cfgelems"] + nrootnames = split(tab2elems["root_cfgelems"], rootnames, ";"); + if(nrootnames != 1) { + print FILENAME": error: root_cfgelems has no multiple entries, service name not known" > "/dev/stderr"; + exit 1; + } + servicename = rootnames[1]; + + # Default service name attribute is executable name, which we can + # derive from the root element, DDSI2Service and DDSI2EService. If + # the root element is neither of those, error out (though we could + # also simply use some other sane default). + if(servicename != "DDSI2Service" && servicename != "DDSI2EService") { + print FILENAME": error: top element expected to be DDSI2Service or DDSI2EService " > "/dev/stderr"; + exit 1; + } else { + execname = tolower(gensub(/Service/, "", "g", servicename)); + } + default_overrides["ddsi2_cfgattrs/name"] = execname; + + print ""; + #print ""; + conv_table_to_xml("root_cfgelems", " ", ""); + print ""; + + for(x in typehint_seen) { + if(x == 0) { + print "script warning: type mapping defined for "x" but not used" > "/dev/stderr"; + } + } +} diff --git a/src/services/ddsi2e/extract.py b/src/services/ddsi2e/extract.py new file mode 100755 index 000000000..77fd6aa6c --- /dev/null +++ b/src/services/ddsi2e/extract.py @@ -0,0 +1,63 @@ +#!/usr/bin/python + +import sys + +all_features = ['NETWORK_CHANNELS','BANDWIDTH_LIMITING','NETWORK_PARTITIONS','ENCRYPTION','SSL'] + +def extract (in_file, out_file, version, service, features): + state = [] + in_scope = True + cmd_line = False + fr = open (in_file, 'r') + fw = open (out_file, 'w') + for line in fr: + if line[0:5] == 'START': + state.append (in_scope) + in_scope = in_scope and line[6:len(line)-1] in features + cmd_line = True + elif line[0:3] == 'END': + in_scope = state.pop () + cmd_line = True + else: + cmd_line = False + if in_scope and not cmd_line: + line = line.replace ('VERSION', version) + line = line.replace ('LC_SNAME', service.lower ()) + line = line.replace ('SNAME', service) + fw.write (line), + fr.close () + fw.close () + +def usage (): + sys.stdout.write ('usage: extract.py meta_config_file (lite | ddsi2 | ddsi2e)') + for f in all_features: sys.stdout.write (' [' + f + ']') + sys.stdout.write ('\n') + sys.exit (1) + +def main (argv): + features = [] + version = 'COMMERCIAL' + service = 'DDSI2E' + try: + meta = argv[0] + config = argv[1] + except: usage () + if config == 'ddsi2': + version = 'COMMUNITY' + service = 'DDSI2' + features.append ('OSPL') + elif config == 'ddsi2e': + features.append ('OSPL') + elif config == 'lite': + version = 'LITE' + features.append ('LITE') + else: usage () + for arg in argv[2:]: + if all_features.count (arg) == 0: + print 'Unsupported feature: ' + arg + usage () + else: features.append (arg) + extract (meta, config + '.xml', version, service, features) + +if __name__ == "__main__": + main (sys.argv[1:]) diff --git a/src/services/ddsi2e/makefile b/src/services/ddsi2e/makefile new file mode 100644 index 000000000..92d1823f4 --- /dev/null +++ b/src/services/ddsi2e/makefile @@ -0,0 +1,12 @@ +# +include $(OSPL_HOME)/setup/makefiles/makefile.mak + +all link: bld/$(SPLICE_TARGET)/makefile + @$(MAKE) -C bld/$(SPLICE_TARGET) $@ + + +clean: + @rm -rf bld/$(SPLICE_TARGET) + +osplconf osplconf-update ddsi2e-config: bld/$(SPLICE_TARGET)/makefile + @$(MAKE) -C bld/$(SPLICE_TARGET) $@ diff --git a/src/services/ddsi2e/makefile.mak b/src/services/ddsi2e/makefile.mak new file mode 100644 index 000000000..29f8910c8 --- /dev/null +++ b/src/services/ddsi2e/makefile.mak @@ -0,0 +1,93 @@ +TARGET_DLIB := ddsi2e +ODL_MODULES := q_osplserModule + +C_FILES := $(notdir $(filter-out %_template.c, $(wildcard ../../code/*.c ../../core/*.c))) +include $(OSPL_HOME)/setup/makefiles/target.mak +-include $(OSPL_OUTER_HOME)/setup/makefiles/commercial.mak + +DDSI2E_CONFIG = -DDDSI2E_OR_NOT2E -DDDSI_INCLUDE_NETWORK_PARTITIONS -DDDSI_INCLUDE_NETWORK_CHANNELS -DDDSI_INCLUDE_BANDWIDTH_LIMITING -DDDSI_INCLUDE_SSM +ifeq "$(INCLUDE_SECURITY)" "yes" +DDSI2E_CONFIG += -DDDSI_INCLUDE_ENCRYPTION -DDDSI_INCLUDE_SSL +endif + +CPPFLAGS += $(DDSI2E_CONFIG) +CPPFLAGS += -DOSPL_BUILD_DDSI2 -DMODEL_q_osplserModule_IMPLEMENTATION + +CFLAGS += $(SHCFLAGS) +LDFLAGS += $(SHLDFLAGS) +LDLIBS += $(SHLDLIBS) + +CFLAGS += $(CFLAGS_XSTRICT) +CFLAGS += $(CFLAGS_W_ERROR) +#ddsi_ssl$(OBJ_POSTFIX) ddsi_tcp$(OBJ_POSTFIX) q_sockwaitset$(OBJ_POSTFIX): CFLAGS += $(CFLAGS_W_NOERROR) + +ifneq (,$(findstring solaris10_gcc,$(SPLICE_TARGET))) +LDFLAGS += -mimpure-text +endif + +VPATH = +vpath %.c +vpath %.c ../../code ../../core + +CPPFLAGS += $(CPPFLAGS_T_RLM) +CFLAGS += $(CFLAGS_T_RLM) + +## +## FIXME introduce LDLIBS_IN variable +ifneq "$(INCLUDE_SECURITY)" "" +LDLIBS += $(LDLIBS_NW_SEC) +endif + +LDLIBS += -l$(DDS_CORE) +LDLIBS += $(LDLIBS_NW) +LDLIBS += $(LDLIBS_ZLIB) + +# Include dirs for this component + +CINCS += -I../../code +CINCS += -I../../core + +CINCS += -I$(OSPL_HOME)/src/user/include +CINCS += -I$(OSPL_HOME)/src/kernel/include +CINCS += -I$(OSPL_HOME)/src/database/database/include +CINCS += -I$(OSPL_HOME)/src/database/serialization/include +CINCS += -I$(OSPL_HOME)/src/configuration/config/include +CINCS += -I$(OSPL_HOME)/src/utilities/include +## workaround until v__networkQueue.h has moved from code/ to include/ +CINCS += -I$(OSPL_HOME)/src/kernel/code +CINCS += -I$(OSPL_HOME)/src/user/code +CINCS += -I$(OSPL_HOME)/src/configuration/config/include +CINCS += -I"$(OPENSSL_TARGET_HOME)/include" +CINCS += $(CINCS_NW_SEC) +ifneq "$(WCECOMPAT)" "" +CINCS += "-I$(WCECOMPAT)/include" +endif +CINCS += $(CINCS_ZLIB) + +LDFLAGS += $(LDFLAGS_ZLIB) + +# automagic generation/updating of osplconf input +METACONFIG := splice_metaconfig_$(firstword $(subst ., , $(patsubst V%, %, $(PACKAGE_VERSION)))).1.xml + +.PHONY: osplconf osplconf-update +osplconf: $(METACONFIG) + +.PHONY: ddsi2e-config +ddsi2e-config: + @echo $(DDSI2E_CONFIG) + +# don't want a cyclical dependency +osplconf-update: $(METACONFIG) + if [ $(METACONFIG) -nt $(OSPL_HOME)/src/tools/cm/config/code/$(METACONFIG) ] ; then \ + cp -p $< $(OSPL_HOME)/src/tools/cm/config/code/$(METACONFIG) ; \ + $(MAKE) -C $(OSPL_HOME)/src/tools/cm/config ; \ + fi + +$(METACONFIG): ../../extract-configurator-xml.awk ../../core/q_config.c $(OSPL_HOME)/src/services/ddsi2/code/q_config.c $(OSPL_HOME)/src/tools/cm/config/code/$(METACONFIG) ../../merge-metaconfig + gawk -vversion=COMMERCIAL -f ../../extract-configurator-xml.awk ../../core/q_config.c >config-ddsi2e.xml + $(SHELL) ../../merge-metaconfig $(OSPL_HOME)/src/tools/cm/config/code/$(METACONFIG) config-ddsi2e.xml >$@.tmp + gawk -vversion=COMMUNITY -f ../../extract-configurator-xml.awk $(OSPL_HOME)/src/services/ddsi2/code/q_config.c >config-ddsi2.xml + $(SHELL) ../../merge-metaconfig $@.tmp config-ddsi2.xml >$@ + rm -f $@.tmp + +-include $(DEPENDENCIES) diff --git a/src/services/ddsi2e/merge-metaconfig b/src/services/ddsi2e/merge-metaconfig new file mode 100644 index 000000000..a40319a0b --- /dev/null +++ b/src/services/ddsi2e/merge-metaconfig @@ -0,0 +1,11 @@ +if [ $# -ne 2 ] ; then + echo "usage: $0 METACONFIG NEW_DDSI2_CONFIG" >&2 + exit 1 +fi + +hdmarker=`head -1 "$2"` +tlmarker=`tail -1 "$2"` + +gawk '$0 == "'"$hdmarker"'" {exit} {print}' "$1" +cat "$2" +gawk '$0 == "'"$tlmarker"'" {p=1;next} p {print}' "$1" diff --git a/src/services/ddsi2e/metaconfig.xml b/src/services/ddsi2e/metaconfig.xml new file mode 100644 index 000000000..745fbc447 --- /dev/null +++ b/src/services/ddsi2e/metaconfig.xml @@ -0,0 +1,1361 @@ +START OSPL + + +END OSPL +START LITE + + +END LITE + The root element of a SNAME networking service configuration.

    + ]]>
    + 0 +START OSPL + + This attribute identifies the configuration for the SNAME Service. Multiple SNAME service configurations can be specified in one single resource. The actual applicable configuration is determined by the value of the name attribute, which must match the specified under the element OpenSplice/Domain/Service[@name] in the Domain Service configuration.

    + ]]>
    + 0 + LC_SNAME +
    +END OSPL +START NETWORK_CHANNELS + + This element is used to group a set of channels. The channels are independent data paths through SNAME and by using separate threads and setting their priorities appropriately, channels can be used to map transport priorities to operating system scheduler priorities, ensuring system-wide end-to-end priority preservation.

    +

    This element is used to group a set of channels. The channels are independent data paths through SNAME and by using separate threads and setting their priorities appropriately, channels can be used to map transport priorities to operating system scheduler priorities, ensuring system-wide end-to-end priority preservation.

    + ]]>
    + + This element defines a channel.

    + ]]>
    + + This attribute specifies name of this channel. The name should uniquely identify the channel.

    + ]]>
    + 0 + +
    + + This attribute sets the transport priority threshold for the channel. Each DCPS data writer has a "transport_priority" QoS and this QoS is used to select a channel for use by this writer. The selected channel is the one with the largest threshold not greater than the writer's transport priority, and if no such channel exists, the channel with the lowest threshold.

    + ]]>
    + 0 +
    +START BANDWIDTH_LIMITING + + This element specifies the maximum transmit rate of auxiliary traffic on this channel (e.g. retransmits, heartbeats, etc). Bandwidth limiting uses a leaky bucket scheme. The default value "inf" means SNAME imposes no limitation, the underlying operating system and hardware will likely limit the maimum transmit rate. +

    The unit must be specified explicitly. Recognised units: Xb/s, Xbps for bits/s or XB/s, XBps for bytes/s; where X is an optional prefix: k for 103, Ki for 210, M for 106, Mi for 220, G for 109, Gi for 230.

    + ]]>
    + 0 + inf +
    + + This element specifies the maximum transmit rate of new samples and directly related data, for this channel. Bandwidth limiting uses a leaky bucket scheme. The default value "inf" means SNAME imposes no limitation, the underlying operating system and hardware will likely limit the maimum transmit rate.

    +

    The unit must be specified explicitly. Recognised units: Xb/s, Xbps for bits/s or XB/s, XBps for bytes/s; where X is an optional prefix: k for 103, Ki for 210, M for 106, Mi for 220, G for 109, Gi for 230.

    + ]]>
    + 0 + inf +
    +END BANDWIDTH_LIMITING + + This element describes the DiffServ setting the channel will apply to the networking messages. This parameter determines the value of the diffserv field of the IP version 4 packets sent on this channel which allows QoS setting to be applied to the network traffic send on this channel.
    +Windows platform support for setting the diffserv field is dependent on the OS version.
    +For Windows versions XP SP2 and 2003 to use the diffserv field the following parameter should be added to the register:

    +HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\TcpIp\Parameters\DisableUserTOSSetting

    +The type of this parameter is a DWORD and its value should be set to 0 to allow setting of the diffserv field.

    +For Windows version 7 or higher a new API (qWAVE) has been introduced. For these platforms the specified diffserv value is mapped to one of the support traffic types. +The mapping is as follows: 1-8 background traffic; 9-40 excellent traffic; 41-55 audio/video traffic; 56 voice traffic; 57-63 control traffic. +When an application is run without Administrative priveleges then only the diffserv value of 0, 8, 40 or 56 is allowed.

    + ]]>
    + 0 +
    + +START OSPL + This element specifies the number of messages the network queue for this channel can contain. The OpenSplice kernel writes data to be transmitted to the network queue, and SNAME takes them from this queue. If this queue is full when an application tries to write a sample, the sample will be dropped or the writer suspended, depending on the QoS settings of the writer. OpenSplice and its services are optimised for a well-balanced system design, where the queue never becomes full.

    + ]]>
    +END OSPL +START LITE + This element specifies the number of messages the network queue for this channel can contain. If this queue is full when an application tries to write a sample, the sample will be dropped or the writer suspended, depending on the QoS settings of the writer.

    + ]]>
    +END LITE + 0 +
    + + This element specifies the interval at which the SNAME transmit thread for this channel wakes up, and which controls the smallest latency_budget that has an effect. A shorter latency_budget is rounded to 0. The downside of a reducing this setting is that it increases the number of idle wake-ups of the transmit thread when there is no data to be sent.

    +

    Valid values are finite durations with an explicit unit or the keyword 'inf' for infinity. Recognised units: ns, us, ms, s, min, hr, day.

    + ]]>
    + 0 + 1s +
    +
    +
    +END NETWORK_CHANNELS + + The Compatibility elements allows specifying various settings related to compatability with standards and with other DDSI implementations.

    + ]]>
    + + This element governs the representation of an acknowledgement message that does not also negatively-acknowledge some samples. If set to 0, the generated acknowledgements have an invalid form and will be reject by the strict and pedantic conformance modes, but several other implementation require this setting for smooth interoperation.

    +

    If set to 1, all acknowledgements sent by SNAME adhere the form of acknowledgement messages allowed by the standard, but this causes problems when interoperating with these other implementations. The strict and pedantic standards conformance modes always overrule an AckNackNumbitsEmptySet=0 to prevent the transmitting of invalid messages.

    + ]]>
    + 0 +
    + + This setting is currently ignored (accepted for backwards compatibility).

    + ]]>
    + true +
    + + This option assumes ParticipantMessageData endpoints required by the liveliness protocol are present in RTI participants even when not properly advertised by the participant discovery protocol.

    + ]]>
    + false +
    + + This element specifies whether QoS settings set to default values are explicitly published in the discovery protocol. Implementations are to use the default value for QoS settings not published, which allows a significant reduction of the amount of data that needs to be exchanged for the discovery protocol, but this requires all implementations to adhere to the default values specified by the specifications.

    +

    When interoperability is required with an implementation that does not follow the specifications in this regard, setting this option to true will help.

    + ]]>
    + false +
    + + This option specifies whether a network socket will be created for each domain participant on a host. The specification seems to assume that each participant has a unique address, and setting this option will ensure this to be the case. This is not the default.

    +

    Disabling it slightly improves performance and reduces network traffic somewhat. It also causes the set of port numbers needed by SNAME to become predictable, which may be useful for firewall and NAT configuration.

    + ]]>
    + false +
    + + This element allows a closer mimicking of the behaviour of some other DDSI implementations, albeit at the cost of generating even more invalid messages. Setting it to true ensures a Heartbeat can be sent at any time when a remote node requests one, setting it to false delays it until a valid one can be sent.

    +

    The latter is fully compliant with the specification, and no adverse effects have been observed. It is the default.

    + ]]>
    + false +
    + + This element sets the level of standards conformance of this instance of the SNAME Service. Stricter conformance typically means less interoperability with other implementations. Currently three modes are defined:

    +
    • pedantic: very strictly conform to the specification, ultimately for compliancy testing, but currently of little value because it adheres even to what will most likely turn out to be editing errors in the DDSI standard. Arguably, as long as no errata have been published it is the current text that is in effect, and that is what pedantic currently does.
    • +
    • strict: a slightly less strict view of the standard than does pedantic: it follows the established behaviour where the standard is obviously in error.
    • +
    • lax: attempt to provide the smoothest possible interoperability, anticipating future revisions of elements in the standard in areas that other implementations do not adhere to, even though there is no good reason not to.
    +

    The default setting is "lax".

    + ]]>
    + lax + strict + pedantic + lax +
    +
    + + The Discovery element allows specifying various parameters related to the discovery of peers.

    + ]]>
    + + This element specifies the lease duration for entities discovered through a discovery service.

    +

    Valid values are finite durations with an explicit unit or the keyword 'inf' for infinity. Recognised units: ns, us, ms, s, min, hr, day.

    + ]]>
    + 0 + 300 s +
    + + This element allows overriding of the DDS Domain Id that is used for SNAME.

    + ]]>
    + 0 + default +
    + + This element controls whether or not SNAME generates built-in topics from its discovery. When disabled, it relies on the durability service.

    + ]]>
    + true +
    + + This element controls whether or not SNAME advertises writers for the built-in topics from its discovery for backwards compatibility with older OpenSplice versions.

    + ]]>
    + true +
    + + This element specifies the maximum DDSI participant index selected by this instance of the SNAME service if the Discovery/ParticipantIndex is "auto".

    + ]]>
    + 9 +
    + + This element specifies the DDSI participant index used by this instance of the SNAME service for discovery purposes. Only one such participant id is used, independent of the number of actual DomainParticipants on the node. It is either:

    +
    • auto: which will attempt to automatically determine an available participant index (see also Discovery/MaxAutoParticipantIndex), or
    • +
    • a non-negative integer less than 120, or
    • +
    • none:, which causes it to use arbitrary port numbers for unicast sockets which entirely removes the constraints on the participant index but makes unicast discovery impossible.
    +

    The default is auto. The participant index is part of the port number calculation and if predictable port numbers are needed and fixing the participant index has no adverse effects, it is recommended that the second be option be used.

    + ]]>
    + 0 + auto +
    +START OSPL + + This element controls which partition is monitored by DDSI2E for built-in topics describing entities the it mirrors in DDSI.

    + ]]>
    + 0 + __BUILT_IN_PARTITION__ +
    +END OSPL + + This element statically configures addresses for discovery.

    + ]]>
    + + This element statically configures a fault tolerant group of addresses for discovery. Each member of the group is tried in sequence until one succeeds.

    + ]]>
    + + This element statically configures an addresses for discovery.

    + ]]>
    + + This element specifies an IP address to which discovery packets must be sent, in addition to the default multicast address (see also General/AllowMulticast). Both a hostnames and a numerical IP address is accepted; the hostname or IP address may be suffixed with :PORT to explicitly set the port to which it must be sent. Multiple Peers may be specified.

    + ]]>
    + 0 + +
    +
    +
    +
    + + The Ports element allows specifying various parameters related to the port numbers used for discovery. These all have default values specified by the DDSI 2.1 specification and rarely need to be changed.

    + ]]>
    + 0 + + This element specifies the base port number (refer to the DDSI 2.1 specification, section 9.6.1, constant PB).

    + ]]>
    + 1 + 65535 + 7400 +
    + + This element specifies the domain gain, relating domain ids to sets of port numbers (refer to the DDSI 2.1 specification, section 9.6.1, constant DG).

    + ]]>
    + 250 +
    + + This element specifies the port number for multicast meta traffic (refer to the DDSI 2.1 specification, section 9.6.1, constant d2).

    + ]]>
    + 1 +
    + + This element specifies the port number for multicast meta traffic (refer to the DDSI 2.1 specification, section 9.6.1, constant d0).

    + ]]>
    + 0 +
    + + This element specifies the participant gain, relating p0, articipant index to sets of port numbers (refer to the DDSI 2.1 specification, section 9.6.1, constant PG).

    + ]]>
    + 2 +
    + + This element specifies the port number for unicast meta traffic (refer to the DDSI 2.1 specification, section 9.6.1, constant d3).

    + ]]>
    + 11 +
    + + This element specifies the port number for unicast meta traffic (refer to the DDSI 2.1 specification, section 9.6.1, constant d1).

    + ]]>
    + 10 +
    +
    + + This element specifies the interval between spontaneous transmissions of participant discovery packets.

    +

    The unit must be specified explicitly. Recognised units: ns, us, ms, s, min, hr, day.

    + ]]>
    + 0 + 1hr + 0 + 30 s +
    + + This element specifies the multicast address that is used as the destination for the participant discovery packets. In IPv4 mode the default is the (standardised) 239.255.0.1, in IPv6 mode it becomes ff02::ffff:239.255.0.1, which is a non-standardised link-local multicast address.

    + ]]>
    + 0 + 239.255.0.1 +
    +
    + + The General element specifies overall SNAME settings.

    + ]]>
    + + This element controls whether SNAME uses multicasts for data traffic.

    +

    It is a comma-separated list of some of the following keywords: "spdp", "asm", "ssm", or either of "false" or "true".

    +
      +
    • spdp: enables the use of ASM (any-source multicast) for participant discovery
    • +
    • asm: enables the use of ASM for all traffic (including SPDP)
    • +
    • ssm: enables the use of SSM (source-specific multicast) for all non-SPDP traffic (if supported)
    • +
    +

    When set to "false" all multicasting is disabled. The default, "true" enables full use of multicasts. Listening for multicasts can be controlled by General/MulticastRecvNetworkInterfaceAddresses.

    + ]]>
    + 0 + true +
    +START LITE + + This element specifies whether DDSI packets are visible to all DDSI participants in the same process. It must be \"true\" for intra-process communications, i.e. a reader and writer communicating in the same address space. If enabled and using multicast then EnableMulticastLoopback must also be enabled.

    + ]]>
    + false +
    +END LITE +START OSPL + + This element specifies whether the SNAME service operates in conjunction with the OpenSplice RT Networking service. When "false", the SNAME service will take care of all communications, including those between OpenSplice nodes; when "true", the SNAME service only communicates with DDS implementations other than OpenSplice. In this case the RT Networking service should be configured as well.

    + ]]>
    + false +
    +END OSPL + + This element allows setting the SO_DONTROUTE option for outgoing packets, to bypass the local routing tables. This is generally useful only when the routing tables cannot be trusted, which is highly unusual.

    + ]]>
    + false +
    + + This element specifies whether SNAME allows IP multicast packets to be visible to all DDSI participants in the same node, including itself. It must be "true" for intra-node multicast communications, but if a node runs only a single SNAME service and does not host any other DDSI-capable programs, it should be set to "false" for improved performance.

    + ]]>
    + true +
    + + This element allows explicitly overruling the network address SNAME advertises in the discovery protocol, which by default is the address of the preferred network interface (General/NetworkInterfaceAddress), to allow SNAME to communicate across a Network Address Translation (NAT) device.

    + ]]>
    + 0 + auto +
    + + This element specifies the network mask of the external network address. This element is relevant only when an external network address (General/ExternalNetworkAddress) is explicitly configured. In this case locators received via the discovery protocol that are within the same external subnet (as defined by this mask) will be translated to an internal address by replacing the network portion of the external address with the corresponding portion of the preferred network interface address. This option is IPv4-only.

    + ]]>
    + 0 + 0.0.0.0 +
    + + This element specifies on which network interfaces SNAME listens to multicasts. The following options are available:

    +
      +
    • all: listen for multicasts on all multicast-capable interfaces; or
    • +
    • any: listen for multicasts on the operating system default interface; or
    • +
    • preferred: listen for multicasts on the preferred interface (General/NetworkInterfaceAddress); or
    • +
    • none: does not listen for multicasts on any interface; or
    • +
    • a comma-separated list of network addresses: configures SNAME to listen for multicasts on all of the listed addresses.
    • +
    +

    If SNAME is in IPv6 mode and the address of the preferred network interface is a link-local address, "all" is treated as a synonym for "preferred" and a comma-separated list is treated as "preferred" if it contains the preferred interface and as "none" if not.

    + ]]>
    + 0 + preferred +
    + + This element specifies the time-to-live setting for outgoing multicast packets.

    + ]]>
    + 0 + 255 + 32 +
    + + This element specifies the preferred network interface for use by SNAME. The preferred network interface determines the IP address that SNAME advertises in the discovery protocol (but see also General/ExternalNetworkAddress), and is also the only interface over which multicasts are transmitted. The interface can be identified by its IP address, network interface name or network portion of the address. If the value "auto" is entered here, SNAME will select what it considers the most suitable interface.

    + ]]>
    + 0 + auto +
    + + This element configures whether startup-mode should also cover transient and persistent data, for configurations where the durability service does not take care of it. Configurations without defined merge policies best leave this enabled.

    + ]]>
    + true +
    + + This element specifies how long the SNAME remains in its "startup" mode. While in "startup" mode all volatile reliable data published on the local node is retained as-if it were transient-local data, allowing existing readers on remote nodes to obtain the data even though discovering them takes some time. Best-effort data by definition need not arrive, and transient and persistent data are covered by the durability service.

    +

    Once the system is stable, SNAME keeps track of the existence of remote readers whether or not matching writers exist locally, avoiding this discovery delay and ensuring this is merely a node startup issue.

    +

    Setting General/StartupModeDuration to 0s will disable it.

    +

    The unit must be specified explicitly. Recognised units: ns, us, ms, s, min, hr, day.

    + ]]>
    + 0 + 60000 + 0 + 2 s +
    + + This element can be used to SNAME use IPv6 instead of IPv4. This is currently an either/or switch.

    + ]]>
    + false +
    +
    + + The Internal elements deal with a variety of settings that are still evolving.

    + ]]>
    + + Internal Proxy readers that are assumed to sill be retrieving historical data get this many samples retransmitted when they NACK something, even if some of these samples have sequence numbers outside the set covered by the NACK.

    + ]]>
    + 0 +
    + +START OSPL + Internal This element controls whether to drop a reliable sample from a SNAME WHC before all readers have acknowledged it as soon as a later sample becomes available. It only affects DCPS data writers with a history QoS setting of KEEP_LAST with depth 1. The default setting, false, mimics the behaviour of the OpenSplice RT networking and is necessary to make the behaviour of wait_for_acknowledgements() consistent across the networking services.

    + ]]>
    +END OSPL +START LITE + Internal This element controls whether to drop a reliable sample from a SNAME WHC before all readers have acknowledged it as soon as a later sample becomes available. It only affects DCPS data writers with a history QoS setting of KEEP_LAST with depth 1.

    + ]]>
    +END LITE + false +
    + + Internal This element controls which network interfaces are assumed to be capable of multicasting even when the interface flags returned by the operating system state it is not (this provides a workaround for some platforms). It is a comma-separated lists of patterns (with ? and * wildcards) against which the interface names are matched.

    + ]]>
    + 0 + +
    +START BANDWIDTH_LIMITING + + Internal This element specifies the maximum transmit rate of auxiliary traffic not bound to a specific channel, such as discovery traffic, as well as auxiliary traffic related to a certain channel if that channel has elected to share this global AuxiliaryBandwidthLimit. Bandwidth limiting uses a leaky bucket scheme. The default value "inf" means SNAME imposes no limitation, the underlying operating system and hardware will likely limit the maimum transmit rate.

    +

    The unit must be specified explicitly. Recognised units: Xb/s, Xbps for bits/s or XB/s, XBps for bytes/s; where X is an optional prefix: k for 103, Ki for 210, M for 106, Mi for 220, G for 109, Gi for 230.

    + ]]>
    + 0 + inf +
    +END BANDWIDTH_LIMITING + + Internal This element controls which participants will have which built-in endpoints for the discovery and liveliness protocols. Valid values are:

    +
    • full: all participants have all endpoints;
    • +
    • writers: all participants have the writers, but just one has the readers;
    • +
    • minimal: only one participant has built-in endpoints.
    +

    The default is writers, as this is thought to be compliant and reasonably efficient. Minimal may or may not be compliant but is most efficient, and full is inefficient but certain to be compliant. See also Internal/ConservativeBuiltinReaderStartup.

    + ]]>
    + full + writers + minimal + writers +
    + + Internal This element forces all SNAME built-in discovery-related readers to request all historical data, instead of just one for each "topic". There is no indication that any of the current DDSI implementations requires changing of this setting, but it is conceivable that an implementation might track which participants have been informed of the existence of endpoints and which have not been, refusing communication with those that have "can't" know.

    +

    Should it be necessary to hide SNAME's shared discovery behaviour, set this to true and Internal/BuiltinEndpointSet to full.

    + ]]>
    + false +
    + + Internal This element sets the maximum number of extra threads for an experimental, undocumented and unsupported direct mode.

    + ]]>
    + 1 +
    + + Internal This element sets the maximum number of samples that can be defragmented simultaneously for a reliable writer. This has to be large enough to handle retransmissions of historical data in addition to new samples.

    + ]]>
    + 16 +
    + + Internal This element sets the maximum number of samples that can be defragmented simultaneously for a best-effort writers.

    + ]]>
    + 4 +
    + + Internal This element controls the Maximum size of a delivery queue, expressed in samples. Once a delivery queue is full, incoming samples destined for that queue are dropped until space becomes available again.

    + ]]>
    + 256 +
    + + Internal Forward all messages from a writer, rather than trying to forward each sample only once. The default of trying to forward each sample only once filters out duplicates for writers in multiple partitions under nearly all circumstances, but may still publish the odd duplicate. Note: the current implementation also can lose in contrived test cases, that publish more than 2**32 samples using a single data writer in conjunction with carefully controlled management of the writer history via cooperating local readers.

    + ]]>
    + false +
    +START OSPL + + This element controls whether SNAME forwards data received from other network services in the domain.

    + ]]>
    + false + default + true + default +
    +END OSPL + + Internal This element specifies the size of DDSI sample fragments generated by SNAME. Samples larger than FragmentSize are fragmented into fragments of FragmentSize bytes each, except the last one, which may be smaller. The DDSI spec mandates a minimum fragment size of 1025 bytes, but SNAME will do whatever size is requested, accepting fragments of which the size is at least the minimum of 1025 and FragmentSize.

    +

    The unit must be specified explicitly. Recognised units: B (bytes), kB & KiB (210 bytes), MB & MiB (220 bytes), GB & GiB (230 bytes).

    + ]]>
    + 0 + 1280 B +
    + + Internal When true, include keyhashes in outgoing data for topics with keys.

    + ]]>
    + true +
    + + Internal Ack a sample only when it has been delivered, instead of when committed to delivering it.

    + ]]>
    + false +
    +START LITE + + Internal This setting controls the default participant lease duration.

    + ]]> + 0 + 1hr + 0 + 10 s + +END LITE +START OSPL + + Internal This setting controls the default participant lease duration, with 0s (the default) indicating that it is to be derived from the domain ExpiryTime: either 10% or 1s longer, whichever is shortest.

    +

    The unit must be specified explicitly. Recognised units: ns, us, ms, s, min, hr, day.

    + ]]>
    + 0 + 1hr + 0 + 0 s +
    +END OSPL + + Internal This option enables a backwards-compatible, non-compliant setting and interpretation of the control flags in fragmented data messages. To be enabled only when requiring interoperability between compliant and non-compliant versions of SNAME for large messages.

    + ]]>
    + false +
    + + Internal This element specifies the maximum size of the UDP payload that SNAME will generate. SNAME will try to maintain this limit within the bounds of the DDSI specification, which means that in some cases (especially for very low values of MaxMessageSize) larger payloads may sporadically be observed (currently up to 1192 B).

    +

    On some networks it may be necessary to set this item to keep the packetsize below the MTU to prevent IP fragmentation. In those cases, it is generally advisable to also consider reducing Internal/FragmentSize.

    +

    The unit must be specified explicitly. Recognised units: B (bytes), kB & KiB (210 bytes), MB & MiB (220 bytes), GB & GiB (230 bytes).

    + ]]>
    + 0 + 4096 B +
    + + This element controls whether or not to write stack traces to the DDSI2 trace when a thread fails to make progress (on select platforms only).

    + ]]>
    + false +
    + + Internal This elements configures the maximum number of DCPS domain participants this SNAME instance is willing to service. 0 is unlimited.

    + ]]>
    + 0 +
    + + Internal This setting limits the maximum number of bytes queued for retransmission. The default value of 0 is unlimited unless an AuxiliaryBandwidthLimit has been set, in which case it becomes NackDelay * AuxiliaryBandwidthLimit. It must be large enough to contain the largest sample that may need to be retransmitted.

    +

    The unit must be specified explicitly. Recognised units: B (bytes), kB & KiB (210 bytes), MB & MiB (220 bytes), GB & GiB (230 bytes).

    + ]]>
    + 0 + 0 B +
    + + Internal This settings limits the maximum number of samples queued for retransmission.

    + ]]>
    + 200 +
    + + Internal This setting controls the maximum (CDR) serialised size of samples that SNAME will forward in either direction. Samples larger than this are discarded with a warning.

    +

    The unit must be specified explicitly. Recognised units: B (bytes), kB & KiB (210 bytes), MB & MiB (220 bytes), GB & GiB (230 bytes).

    + ]]>
    + 0 + 2147483647 B +
    + + Internal This element enables heartbeat-to-ack latency among SNAME services by prepending timestamps to Heartbeat and AckNack messages and calculating round trip times. This is non-standard behaviour. The measured latencies are quite noisy and are currently not used anywhere.

    + ]]>
    + false +
    + + Internal This setting controls the minimum size of socket receive buffers. The operating system provides some size receive buffer upon creation of the socket, this option can be used to increase the size of the buffer beyond that initially provided by the operating system. If the buffer size cannot be increased to the specified size, an error is reported.

    +

    The default setting is the word "default", which means SNAME will attempt to increase the buffer size to 1MB, but will silently accept a smaller buffer should that attempt fail.

    +

    The unit must be specified explicitly. Recognised units: B (bytes), kB & KiB (210 bytes), MB & MiB (220 bytes), GB & GiB (230 bytes).

    + ]]>
    + 0 + default +
    + + Internal This setting controls the minimum size of socket send buffers. This setting can only increase the size of the send buffer, if the operating system by default creates a larger buffer, it is left unchanged.

    +

    The unit must be specified explicitly. Recognised units: B (bytes), kB & KiB (210 bytes), MB & MiB (220 bytes), GB & GiB (230 bytes).

    + ]]>
    + 0 + 64 KiB +
    +START OSPL + + This element controls whether DDSI2 mirrors all entities in the domain in DDSI or only local ones. Default is to discover remote ones iff General/LocalDiscoveryPartition is not the built-in partition.

    + ]]>
    + false + default + true + default +
    +END OSPL + + Internal This setting controls the delay between receipt of a HEARTBEAT indicating missing samples and a NACK (ignored when the HEARTBEAT requires an answer). However, no NACK is sent if a NACK had been scheduled already for a response earlier than the delay requests: then that NACK will incorporate the latest information.

    +

    The unit must be specified explicitly. Recognised units: ns, us, ms, s, min, hr, day.

    + ]]>
    + 0 + 1hr + 0 + 10 ms +
    + + Internal This setting controls the delay between the discovering a remote writer and sending a pre-emptive AckNack to discover the range of data available.

    +

    The unit must be specified explicitly. Recognised units: ns, us, ms, s, min, hr, day.

    + ]]>
    + 0 + 1hr + 0 + 10 ms +
    + + Internal This element sets the maximum size in samples of a primary re-order administration. Each proxy writer has one primary re-order administration to buffer the packet flow in case some packets arrive out of order. Old samples are forwarded to secondary re-order administrations associated with readers in need of historical data.

    + ]]>
    + 64 +
    + + This element controls for how long a remote participant that was previously deleted will remain on a blacklist to prevent rediscovery, giving the software on a node time to perform any cleanup actions it needs to do. To some extent this delay is required internally by SNAME, but in the default configuration with the 'enforce' attribute set to false, SNAME will reallow rediscovery as soon as it has cleared its internal administration. Setting it to too small a value may result in the entry being pruned from the blacklist before SNAME is ready, it is therefore recommended to set it to at least several seconds.

    +

    The unit must be specified explicitly. Recognised units: ns, us, ms, s, min, hr, day.

    + ]]>
    + + If this attribute is set to 'false', SNAME will remove a participant from the blacklist as soon as it has removed all traces from the participant from its internal administration. When set to 'true', SNAME will leave it on the blacklist for the specified duration.

    + ]]>
    + false +
    + 0 + 1hr + 0 + 10 s +
    +START OSPL + + Internal This element controls for how long an unresponsive reader can block the transmit thread by failing to acknowledge data when a writer's SNAME write cache is full. If after this time the writer's cache has not shrunk to below the low-water mark, the reader is considered unresponsive and degraded to unreliable. It will be restored to reliable service once it resumes acknowledging samples.

    +

    The unit must be specified explicitly. Recognised units: ns, us, ms, s, min, hr, day.

    + ]]>
    + 0 + 1hr + 0 + 1 s +
    +END OSPL + + Internal This elements controls the addressing and timing of retransmits. Possible values are:

    +
    • never: retransmit only to the NACK-ing reader;
    • +
    • adaptive: attempt to combine retransmits needed for reliability, but send historical (transient-local) data to the requesting reader only;
    • +
    • always: do not distinguish between different causes, always try to merge.
    +

    The default is adaptive. See also Internal/RetransmitMergingPeriod.

    + ]]>
    + never + adaptive + always + adaptive +
    + + Internal This setting determines the size of the time window in which a NACK of some sample is ignored because a retransmit of that sample has been multicasted too recently. This setting has no effect on unicasted retransmits.

    +

    See also Internal/RetransmitMerging.

    +

    The unit must be specified explicitly. Recognised units: ns, us, ms, s, min, hr, day.

    + ]]>
    + 0 + 1s + 0 + 5 ms +
    + + Internal Whether or not to locally retry pushing a received best-effort sample into the reader caches when resource limits are reached.

    + ]]>
    + false +
    + + Internal How long to keep locally retrying pushing a received sample into the reader caches when resource limits are reached. Default is dependent on Internal/LateAckMode: if the latter is false, it is 80% of Internal/ResponsivenessTimeout, otherwise it is 0.

    +

    Valid values are finite durations with an explicit unit or the keyword 'inf' for infinity. Recognised units: ns, us, ms, s, min, hr, day.

    + ]]>
    + 0 + default +
    + + Internal Maximum pseudo-random delay in milliseconds between discovering a remote participant and responding to it.

    +

    The unit must be specified explicitly. Recognised units: ns, us, ms, s, min, hr, day.

    + ]]>
    + 0 + 1s + 0 + 0 ms +
    + + Internal This setting allows the timing of scheduled events to be rounded up so that more events can be handled in a single cycle of the event queue. The default is 0 and causes no rounding at all, i.e. are scheduled exactly, whereas a value of 10ms would mean that events are rounded up to the nearest 10 milliseconds.

    +

    The unit must be specified explicitly. Recognised units: ns, us, ms, s, min, hr, day.

    + ]]>
    + 0 + 1hr + 0 + 0 ms +
    + + Internal This element sets the maximum size in samples of a secondary re-order administration. The secondary re-order administration is per reader in need of historical data.

    + ]]>
    + 16 +
    + + Internal This element controls whether SNAME advertises all the domain participants it serves in DDSI (when set to false), or rather only one domain participant (the one corresponding to the SNAME process; when set to true). In the latter case SNAME becomes the virtual owner of all readers and writers of all domain participants, dramatically reducing discovery traffic.

    + ]]>
    + false +
    + + Internal The element controls whether the mandatory multicasting of the participant discovery packets occurs. Completely disabling multicasting requires this element be set to true, and generally requires explicitly listing peers to ping for unicast discovery.

    +

    See also General/AllowMulticast.

    + ]]>
    + false +
    + + Internal This element controls whether samples sent by a writer with QoS settings transport_priority >= SynchronousDeliveryPriorityThreshold and a latency_budget at most this element's value will be delivered synchronously from the "recv" thread, all others will be delivered asynchronously through delivery queues. This reduces latency at the expense of aggregate bandwidth.

    +

    Valid values are finite durations with an explicit unit or the keyword 'inf' for infinity. Recognised units: ns, us, ms, s, min, hr, day.

    + ]]>
    + 0 + inf +
    + + Internal This element controls whether samples sent by a writer with QoS settings latency_budget <= SynchronousDeliveryLatencyBound and transport_priority greater than or equal to this element's value will be delivered synchronously from the "recv" thread, all others will be delivered asynchronously through delivery queues. This reduces latency at the expense of aggregate bandwidth.

    + ]]>
    + 0 +
    + + Internal Testing options.

    +

    The unit must be specified explicitly.

    + ]]>
    + 0 + + Internal This element controls the fraction of outgoing packets to drop, specified as samples per thousand.

    + ]]>
    + 0 +
    +
    + + Internal This element controls whether the response to a newly discovered participant is sent as a unicasted SPDP packet, instead of rescheduling the periodic multicasted one. There is no known benefit to setting this to false.

    + ]]>
    + true +
    + + Internal Watermarks for flow-control.

    +

    The unit must be specified explicitly. Recognised units: B (bytes), kB & KiB (210 bytes), MB & MiB (220 bytes), GB & GiB (230 bytes).

    + ]]>
    + 0 + + Internal This element sets the high-water mark for the SNAME WHCs, expressed in bytes. A writer is suspended when the WHC reaches this size.

    +

    The unit must be specified explicitly. Recognised units: B (bytes), kB & KiB (210 bytes), MB & MiB (220 bytes), GB & GiB (230 bytes).

    + ]]>
    + 0 + 100 kB +
    + + Internal This element sets the low-water mark for the SNAME WHCs, expressed in bytes. A suspended writer resumes transmitting when its SNAME WHC shrinks to this size.

    +

    The unit must be specified explicitly. Recognised units: B (bytes), kB & KiB (210 bytes), MB & MiB (220 bytes), GB & GiB (230 bytes).

    + ]]>
    + 0 + 1 kB +
    +
    +START LITE + + This element enables the batching of write operations. By default each write operation writes through the write +cache and out onto the transport. Enabling write batching causes multiple small write operations to be aggregated within the write cache into a single larger write. This gives greater throughput at the expense of latency. Currently there is no +mechanism for the write cache to automatically flush itself, so that if write batching is enabled, the application may havee to use the dds_write_flush function to ensure thta all samples are written.

    + ]]>
    + false +
    +END LITE + + Internal This setting controls the maximum duration for which actual deletion of a reliable writer with unacknowledged data in its history will be postponed to provide proper reliable transmission.

    +

    The unit must be specified explicitly. Recognised units: ns, us, ms, s, min, hr, day.

    + ]]>
    + 0 + 1hr + 0 + 1 s +
    +
    +START NETWORK_PARTITIONS + + The Partitioning element specifies SNAME network partitions and how DCPS partition/topic combinations are mapped onto the network partitions.

    + ]]>
    + + The IgnoredPartitions element specifies DCPS partition/topic combinations that are not distributed over the network.

    + ]]>
    + + This element can be used to prevent certain combinations of DCPS partition and topic from being transmitted over the network. SNAME will complete ignore readers and writers for which all DCPS partitions as well as their topic is ignored, not even creating DDSI readers and writers to mirror the DCPS ones.

    + ]]>
    + + This attribute specifies a partition and a topic expression, separated by a single '.', that are used to determine if a given partition and topic will be ignored or not. The expressions may use the usual wildcards '*' and '?'. SNAME will consider an wildcard DCPS partition to match an expression iff there exists a string that satisfies both expressions.

    + ]]>
    + 0 + +
    +
    +
    + + The NetworkPartitions element specifies the SNAME network partitions.

    + ]]>
    + + This element defines a SNAME network partition.

    + ]]>
    + + This attribute specifies the multicast addresses associated with the network partition as a comma-separated list. Readers matching this network partition (cf. Partitioning/PartitionMappings) will listen for multicasts on all of these addresses and advertise them in the discovery protocol. The writers will select the most suitable address from the addresses advertised by the readers.

    + ]]>
    + 0 + +
    + + This attribute is a placeholder.

    + ]]>
    + true +
    + + This attribute specifies the name of this SNAME network partition. Two network partitions cannot have the same name.

    + ]]>
    + 0 + +
    +START ENCRYPTION + + This attribute selects the SNAME security profile for encrypting the traffic mapped to this SNAME network partition. The default "null" means the network partition is unsecured; any other name refers to a security profile defined using the Security/SecurityProfile elements.

    + ]]>
    + 0 + null +
    +END ENCRYPTION +
    +
    + + The PartitionMappings element specifies the mapping from DCPS partition/topic combinations to SNAME network partitions.

    + ]]>
    + + This element defines a mapping from a DCPS partition/topic combination to a SNAME network partition. This allows partitioning data flows by using special multicast addresses for part of the data and possibly also encrypting the data flow.

    + ]]>
    + + This attribute specifies a partition and a topic expression, separated by a single '.', that are used to determine if a given partition and topic maps to the SNAME network partition named by the NetworkPartition attribute in this PartitionMapping element. The expressions may use the usual wildcards '*' and '?'. SNAME will consider a wildcard DCPS partition to match an expression if there exists a string that satisfies both expressions.

    + ]]>
    + 0 + +
    + + This attribute specifies which SNAME network partition is to be used for DCPS partition/topic combinations matching the DCPSPartitionTopic attribute within this PartitionMapping element.

    + ]]>
    + 0 + +
    +
    +
    +
    +END NETWORK_PARTITIONS +START SSL + + The SSL element allows specifying various parameters related to using SSL/TLS for DDSI over TCP.

    + ]]>
    + + If disabled this allows SSL connections to occur even if an X509 certificate fails verification.

    + ]]>
    + true +
    + + The set of ciphers used by SSL/TLS

    + ]]>
    + 0 + ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH +
    + + This enables SSL/TLS for TCP.

    + ]]>
    + false +
    + + The SSL/TLS random entropy file name.

    + ]]>
    + 0 + +
    + + The SSL/TLS key pass phrase for encrypted keys.

    + ]]>
    + 0 + secret +
    + + The SSL/TLS key and certificate store file name. The keystore must be in PEM format.

    + ]]>
    + 0 + keystore +
    + + This enables the use of self signed X509 certificates.

    + ]]>
    + false +
    + + This enables an SSL server checking the X509 certificate of a connecting client.

    + ]]>
    + false +
    +
    +END SSL +START ENCRYPTION + + The Security element specifies SNAME security profiles that can be used to encrypt traffic mapped to SNAME network partitions.

    + ]]>
    + + This element defines a SNAME security profile.

    + ]]>
    + + This attribute specifies the cipher to be used for encrypting traffic over network partitions secured by this security profile. The possible ciphers are:

    +
    • aes128: AES with a 128-bit key;
    • +
    • aes192: AES with a 192-bit key;
    • +
    • aes256: AES with a 256-bit key;
    • +
    • blowfish: the Blowfish cipher with a 128 bit key;
    • +
    • null: no encryption;
    +

    SHA1 is used on conjunction with all ciphers except "null" to ensure data integrity.

    + ]]>
    + null + blowfish + aes128 + aes192 + aes256 + null +
    + + The CipherKey attribute is used to define the secret key required by the cipher selected using the Cipher attribute. The value can be a URI referencing an external file containing the secret key, or the secret key can be defined in-place as a string value.

    +

    The key must be specified as a hexadecimal string with each character representing 4 bits of the key. E.g., 1ABC represents the 16-bit key 0001 1010 1011 1100. The key should not follow a well-known pattern and must exactly match the key length of the selected cipher.

    +

    A malformed key will cause the security profile to be marked as invalid, and disable all network partitions secured by the (invalid) security profile to prevent information leaks.

    +

    As all DDS applications require read access to the XML configuration file, for security reasons it is recommended to store the secret key in an external file in the file system, referenced by its URI. The file should be protected against read and write access from other users on the host.

    + ]]>
    + 0 + +
    + + This attribute specifies the name of this SNAME security profile. Two security profiles cannot have the same name.

    + ]]>
    + 0 + +
    +
    +
    +END ENCRYPTION + + The Sizing element specifies a variety of configuration settings dealing with expected system sizes, buffer sizes, &c.

    + ]]>
    + + This endpoint specifies the expected maximum number of endpoints in the network. Underestimating this number will have a significant performance impact, but will not affect correctness; signficantly overestimating it will cause more memory to be used than necessary.

    + ]]>
    +START OSPL + 20000 +END OSPL +START LITE + 200 +END LITE +
    +START OSPL + + This element specifies the expected maximum number of endpoints local to one SNAME service. Underestimating this number will have a significant performance impact, but will not affect correctness; signficantly overestimating it will cause more memory to be used than necessary.

    + ]]>
    + 1000 +
    +END OSPL + + This element specifies the maximum number of samples in the network queue. Write/dispose operations add samples to this queue, the SNAME service drains it. Larger values allow large bursts of writes to occur without forcing synchronization between the application and the SNAME service, but do introduce the potential for longer latencies and increase the maximum amount of memory potentially occupied by messages in the queue.

    + ]]>
    +START OSPL + 1000 +END OSPL +START LITE + 10 +END LITE +
    + + This element specifies the size of one allocation unit in the receive buffer. Must be greater than the maximum packet size by a modest amount (too large packets are dropped). Each allocation is shrunk immediately after processing a message, or freed straightaway.

    +

    The unit must be specified explicitly. Recognised units: B (bytes), kB & KiB (210 bytes), MB & MiB (220 bytes), GB & GiB (230 bytes).

    + ]]>
    + 0 +START OSPL + 128 KiB +END OSPL +START LITE + 64 KiB +END LITE +
    + + This element sets the size of a single receive buffer. Many receive buffers may be needed. Their size must be greater than ReceiveBufferChunkSize by a modest amount.

    +

    The unit must be specified explicitly. Recognised units: B (bytes), kB & KiB (210 bytes), MB & MiB (220 bytes), GB & GiB (230 bytes).

    + ]]>
    + 0 +START OSPL + 1 MiB +END OSPL +START LITE + 128 KiB +END LITE +
    +
    + + The TCP element allows specifying various parameters related to running DDSI over TCP.

    + ]]>
    + + This element enables the optional TCP transport.

    + ]]>
    + false +
    + + This element enables the TCP_NODELAY socket option, preventing multiple DDSI messages being sent in the same TCP request. Setting this option typically optimises latency over throughput.

    + ]]>
    + true +
    + + This element specifies the TCP port number on which SNAME accepts connections. If the port is set it is used in entity locators, published with DDSI discovery. Dynamically allocated if zero. Disabled if -1 or not configured. If disabled other DDSI services will not be able to establish connections with the service, the service can only communicate by establishing connections to other services.

    + ]]>
    + -1 + 65535 + -1 +
    + + This element specifies the timeout for blocking TCP read operations. If this timeout expires then the connection is closed.

    +

    The unit must be specified explicitly. Recognised units: ns, us, ms, s, min, hr, day.

    + ]]>
    + 0 + 1hr + 0 + 2 s +
    + + This element specifies the timeout for blocking TCP write operations. If this timeout expires then the connection is closed.

    +

    The unit must be specified explicitly. Recognised units: ns, us, ms, s, min, hr, day.

    + ]]>
    + 0 + 1hr + 0 + 2 s +
    +
    + + The ThreadPool element allows specifying various parameters related to using a thread pool to send DDSI messages to multiple unicast addresses (TCP or UDP).

    + ]]>
    + + This element enables the optional thread pool.

    + ]]>
    + false +
    + + This elements configures the maximum number of threads in the thread pool.

    + ]]>
    + 8 +
    + + This elements configures the initial number of threads in the thread pool.

    + ]]>
    + 4 +
    +
    + + This element is used to set thread properties.

    + ]]>
    + + This element specifies thread properties, such as scheduling parameters and stack size.

    + ]]>
    + + The Name of the thread for which properties are being set. The following threads exist:

    +
    • gc: garbage collector thread involved in deleting entities;
    • +
    • main: main thread, primarily handling local discovery;
    • +
    • recv: receive thread, taking data from the network and running the protocol state machine;
    • +
    • dq.builtins: delivery thread for DDSI-builtin data, primarily for discovery;
    • +
    • lease: DDSI liveliness monitoring;
    • +
    • tev: general timed-event handling, retransmits and discovery;
    • +
    • xmit.CHAN: transmit thread for channel CHAN;
    • +
    • dq.CHAN: delivery thread for channel CHAN;
    • +
    • tev.CHAN: timed-even thread for channel CHAN.
    + ]]>
    + 0 + +
    + + This element configures the scheduling properties of the thread.

    + ]]>
    + 0 + + This element specifies the thread scheduling class (realtime, timeshare or default). The user may need special privileges from the underlying operating system to be able to assign some of the privileged scheduling classes.

    + ]]>
    + realtime + timeshare + default + default +
    + + This element specifies the thread priority (decimal integer or default). Only priorities that are supported by the underlying operating system can be assigned to this element. The user may need special privileges from the underlying operating system to be able to assign some of the privileged priorities.

    + ]]>
    + 0 + default +
    +
    + + This element configures the stack size for this thread. The default value default leaves the stack size at the operating system default.

    +

    The unit must be specified explicitly. Recognised units: B (bytes), kB & KiB (210 bytes), MB & MiB (220 bytes), GB & GiB (230 bytes).

    + ]]>
    + 0 + default +
    +
    +
    + + The Tracing element controls the amount and type of information that is written into the tracing log by SNAME. This is useful to monitor SNAME during application development.

    + ]]>
    + + This option specifies whether the output is to be appended to an existing log file. The default is to create a new log file each time, which is generally the best option if a detailed log is generated.

    + ]]>
    + false +
    + + This element enables individual logging categories. These are enabled in addition to those enabled by Tracing/Verbosity. Recognised categories are:

    +
    • fatal: all fatal errors, errors causing immediate termination
    • +
    • error: failures probably impacting correctness but not necessarily causing immediate termination
    • +
    • warning: abnormal situations that will likely not impact correctness
    • +
    • config: full dump of the configuration
    • +
    • info: general informational notices
    • +
    • discovery: all discovery activity
    • +
    • data: include data content of samples in traces
    • +
    • radmin: receive buffer administration
    • +
    • timing: periodic reporting of CPU loads per thread
    • +
    • traffic: periodic reporting of total outgoing data
    +

    In addition, there is the keyword trace that enables all but radmin

    . +

    The categorisation of tracing output is incomplete and hence most of the verbosity levels and categories are not of much use in the current release. This is an ongoing process and here we describe the target situation rather than the current situation. Currently, the most useful is trace.

    + ]]>
    + 0 + +
    + + This option specifies where the logging is printed to. Note that stdout and stderr are treated as special values, representing "standard out" and "standard error" respectively. No file is created unless logging categories are enabled using the Tracing/Verbosity or Tracing/EnabledCategory settings.

    + ]]>
    + 0 +START OSPL + ddsi2.log +END OSPL +START LITE + lite.log +END LITE +
    + + This option specifies the file to which received and sent packets will be logged in the "pcap" format suitable for analysis using common networking tools, such as WireShark. IP and UDP headers are ficitious, in particular the destination address of received packets. The TTL may be used to distinguish between sent and received packets: it is 255 for sent packets and 128 for received ones. Currently IPv4 only.

    + ]]>
    + 0 + +
    + + This option has no effect.

    + ]]>
    + true + + + true + +
    + + This element enables standard groups of categories, based on a desired verbosity level. This is in addition to the categories enabled by the Tracing/EnableCategory setting. Recognised verbosity levels and the categories they map to are:

    +
    • none: no SNAME log
    • +
    • severe: error and fatal
    • +
    • warning: severe + warning
    • +
    • info: warning + info
    • +
    • config: info + config
    • +
    • fine: config + discovery
    • +
    • finer: fine + traffic and timing
    • +
    • finest: finer + trace
    +START OSPL +

    While none prevents any message from being written to a DDSI2 log file, warnings and errors are still logged in the ospl-info.log and ospl-error.log files.

    +END OSPL +START LITE +

    While none prevents any message from being written to a DDSI2 log file.

    +END LITE +

    The categorisation of tracing output is incomplete and hence most of the verbosity levels and categories are not of much use in the current release. This is an ongoing process and here we describe the target situation rather than the current situation. Currently, the most useful verbosity levels are config and finest.

    + ]]>
    + finest + finer + fine + config + info + warning + severe + none + none +
    +
    + + This element specifies the type of OS scheduling class will be used by the thread that announces its liveliness periodically.

    + ]]>
    + + This element specifies the type of OS scheduling class will be used by the thread that announces its liveliness periodically.

    + ]]>
    + + This element specifies the thread scheduling class that will be used by the watchdog thread. The user may need the appropriate privileges from the underlying operating system to be able to assign some of the privileged scheduling classes.

    + ]]>
    + realtime + timeshare + default + default +
    + + This element specifies the thread priority. Only priorities that are supported by the underlying operating system can be assigned to this element. The user may need special privileges from the underlying operating system to be able to assign some of the privileged priorities.

    + ]]>
    + 0 + + This attribute specifies whether the specified Priority is a relative or absolute priority.

    + ]]>
    + relative + absolute + relative +
    +
    +
    +
    +
    +START OSPL + +END OSPL +START LITE + +END LITE diff --git a/src/services/ddsi2e/sanitize.pl b/src/services/ddsi2e/sanitize.pl new file mode 100755 index 000000000..875f19c28 --- /dev/null +++ b/src/services/ddsi2e/sanitize.pl @@ -0,0 +1,176 @@ +#!/usr/bin/env perl -w + +#print "@ARGV\n"; + +die "usage: $0 SRCDIR... DSTDIR" unless @ARGV >= 2; +my ($DSTDIR) = pop @ARGV; +my (@SRCDIRS) = @ARGV; + +die "$0: destination dir $DSTDIR exists" if -d $DSTDIR; +mkdir $DSTDIR or die "$0: failed to create destination dir $DSTDIR"; + +@sources = map { glob "$_/*.[ch] $_/*.odl" } @SRCDIRS; +die "$0: no files in source dir @SRCDIRS" unless @sources > 0; + +my @stk = (); # stack of conditional nesting, for each: copy/discard/ignore +my $stkdc = 0; # discard count + +# %isenh contains the macros that are considered to indicate DDSI2-E +# features. Each macro maps to one of three values: +# +# - undef: copy as if it is not feature flag (for easy changing & +# self-documenting); +# +# - 0: indicates a feature for inclusion in DDSI2; +# +# - 1: indicates a feature exclusive to DDSI2-E. +my %isenh = ('LITE' => 1, + 'DDSI_INCLUDE_ENCRYPTION' => 1, + 'DDSI_INCLUDE_NETWORK_CHANNELS' => 1, + 'DDSI_INCLUDE_BANDWIDTH_LIMITING' => 1, + 'DDSI_INCLUDE_NETWORK_PARTITIONS' => 1, + 'DDSI_INCLUDE_SSM' => 1, + 'DDSI2E_OR_NOT2E' => 1); + +my %specials = ('q_main.c' => \&q_main_xforms, 'q_config.c' => \&q_config_xforms); + +my $inner_lic = '/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */'; +print STDOUT "Updating license header\n"; + +for my $src (@sources) { + (my $src_notdir = $src) =~ s/^.*?\/([^\/]+)$/$1/g; + my $dst = "$DSTDIR/$src_notdir"; + my $special_xform = $specials{$src_notdir}; + my $drop = 0, $copy = 0; + + my $comment = ''; + my $cline = 0; + my $cfound = 0; + + die unless @stk == 0 && $stkdc == 0; + + #print STDERR "$src => $dst ... "; + open SRC, "< $src" or die "$0: can't open $src"; + open DST, "> $dst" or die "$0: can't open $dst"; + while () { + my $orig = $_; + chomp; + + #detect and replace copyright header + if (($cfound == 0) && (/^\s*\/\*$/)) { + $comment .= $orig; + $cline = 1; + next; + } elsif ($cline >= 1) { + if (/^\s*\*\s*Vortex OpenSplice$/) { + $cline++; + $cfound = 1; + next; + } elsif ($cline == 1) { + print DST $comment; + $comment = ''; + $cline = 0; + } elsif (/^\s*\*\/$/) { + $cline = 0; + print DST $inner_lic . "\n"; + next; + } else { + next; + } + } + + if (/^\s*\#\s*if(?:def)?\s+([A-Za-z_][A-Za-z_0-9]*)\s*(?:\/(?:\/.*|\*.*?\*\/)\s*)?$/) { + if (not defined $isenh{$1}) { + push @stk, 'ignore'; + } elsif ($isenh{$1}) { + push @stk, 'discard'; + $stkdc++; + next; + } else { + push @stk, 'copy'; + next; + } + } elsif (/^\s*\#\s*if(?:ndef\s+|\s+!\s*)([A-Za-z_][A-Za-z_0-9]*)\s*(?:\/(?:\/.*|\*.*?\*\/)\s*)?$/) { + if (not defined $isenh{$1}) { + push @stk, 'ignore'; + } elsif ($isenh{$1}) { + push @stk, 'copy'; + next; + } else { + push @stk, 'discard'; + $stkdc++; + next; + } + } elsif (/^\s*\#\s*if\s/) { # not relevant to DDSI-E + push @stk, 'ignore'; + } elsif (/^\s*\#\s*else($|\s)/) { + if ($stk[$#stk] eq 'discard') { + $stk[$#stk] = 'copy'; + $stkdc--; + next; + } elsif ($stk[$#stk] eq 'copy') { + $stk[$#stk] = 'discard'; + $stkdc++; + next; + } + } elsif (/^\s*\#\s*endif($|\s)/) { + my $x = pop @stk; + $stkdc-- if $x eq 'discard'; + next unless $x eq 'ignore'; + } + + $orig = &$special_xform ($orig) if defined $special_xform; + + if ($stkdc == 0 && defined $orig) { + print DST $orig; + $copy++; + } else { + $drop++; + } + } + close DST; + close SRC; + + if ($copy == 0) { + #print STDERR "deleted\n"; + unlink $dst or die "$0: can't delete $dst"; + } else { + #printf STDERR "%.0f%% dropped\n", (100.0 * $drop / ($drop + $copy)); + } +} + +# Currently the transforms below are good enough, but perhaps it would +# be better to be slightly more careful. + +sub q_main_xforms { + my ($line) = @_; + $line =~ s/ddsi2e/ddsi2/g; + $line =~ s/(?&2 + exit 1 +fi +script=$1 ; shift +srcs="" +while [ $# -gt 1 ] ; do + srcs="$srcs $1" ; shift +done +dst=$1 + +trap "rm -rf $dst.tmp" EXIT + +rm -rf $dst.tmp +perl -w $script $srcs $dst.tmp || { r=$? ; echo "error: $script" >&2 ; exit $r ; } + +if [ ! -d $dst ] ; then + mkdir $dst || { r=$? ; echo "error: mkdir" >&2 ; exit $r ; } +fi + +for x in $dst.tmp/* ; do + echo "" >> $x + if [ "$OSPL_OUTER_REV" != "" ]; then + echo "/* SHA1 used $OSPL_OUTER_REV */" >> $x + else + echo "/* SHA1 not available (unoffical build.) */" >> $x + fi + + bx=`basename $x` + if [ ! -f $dst/$bx ] ; then + cp=true + else + diff $x $dst/$bx >/dev/null 2>/dev/null + case $? in + 0) # no change + cp=false + ;; + 1) + cp=true + ;; + *) + r=$? + echo "error: diff $x failed" >&2 + exit $r + ;; + esac + fi + + if $cp ; then + #echo "changed: $bx" + cp -p $x $dst/$bx || { r=$? ; echo "error: cp" >&2 ; exit $r ; } + fi +done diff --git a/src/services/durability/code/d__actionQueue.h b/src/services/durability/code/d__actionQueue.h new file mode 100644 index 000000000..20b9a0be2 --- /dev/null +++ b/src/services/durability/code/d__actionQueue.h @@ -0,0 +1,116 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef D__ACTIONQUEUE_H +#define D__ACTIONQUEUE_H + +#include "d__types.h" +#include "os_time.h" +#include "os_thread.h" + +#if defined (__cplusplus) +extern "C" { +#endif + +/** + * Macro that checks the d_actionQueue validity. + * Because d_actionQueue is a concrete class typechecking is required. + */ +#define d_actionQueueIsValid(_this) \ + d_objectIsValid(d_object(_this), D_ACTION_QUEUE) + +/** + * Macro that checks the d_action validity. + * Because d_action is a concrete class typechecking is required. + */ +#define d_actionIsValid(_this) \ + d_objectIsValid(d_object(_this), D_ACTION) + +/** + * \brief The d_actionQueue cast macro. + * + * This macro casts an object to a d_actionQueue object. + */ +#define d_actionQueue(_this) ((d_actionQueue)(_this)) + +/** + * \brief The d_action cast macro. + * + * This macro casts an object to a d_action object. + */ +#define d_action(_this) ((d_action)(_this)) + +typedef c_bool (*d_actionFunction)(d_action action, c_bool terminate); + +C_STRUCT(d_action) { + C_EXTENDS(d_object); + os_timeM execTime; + os_duration sleepTime; + d_actionFunction action; + c_voidp args; +}; + +C_STRUCT(d_actionQueue) { + C_EXTENDS(d_lock); + os_threadId actionThread; + os_duration sleepTime; + c_bool terminate; + c_iter actions; + c_iter remove; + c_char* name; +}; + +void* d_actionQueueRun (void* userData); + +d_actionQueue d_actionQueueNew (const c_char* name, + os_duration sleepTime, + os_threadAttr attr); + +void d_actionQueueDeinit (d_actionQueue queue); + +void d_actionQueueFree (d_actionQueue queue); + +c_bool d_actionQueueAdd (d_actionQueue queue, + d_action action); + +c_bool d_actionQueueRemove (d_actionQueue queue, + d_action action); + +d_action d_actionNew (os_timeM execTime, + os_duration sleepTime, + d_actionFunction action, + c_voidp args); + +void d_actionDeinit (d_action action); + +void d_actionFree (d_action action); + +c_voidp d_actionGetArgs (d_action action); + +os_timeM d_actionGetExecTime (d_action action); + +os_duration d_actionGetSleepTime (d_action action); + +void d_actionSetSleepTime (d_action action, + os_duration sleepTime); + +#if defined (__cplusplus) +} +#endif + +#endif /*D__ACTIONQUEUE_H*/ diff --git a/src/services/durability/code/d__admin.h b/src/services/durability/code/d__admin.h new file mode 100644 index 000000000..e1d7a19b7 --- /dev/null +++ b/src/services/durability/code/d__admin.h @@ -0,0 +1,541 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef D__ADMIN_H +#define D__ADMIN_H + +#include "d__types.h" +#include "d__lock.h" +#include "d__statistics.h" +#include "d__conflictMonitor.h" +#include "d__client.h" +#include "u_user.h" +#include "os_cond.h" +#include "os_mutex.h" +#include "c_iterator.h" + +#if defined (__cplusplus) +extern "C" { +#endif + +/** + * \brief Durability topic definitions + */ +#define D_GROUPS_REQ_TOPIC_NAME "d_groupsRequest" +#define D_GROUPS_REQ_TYPE_NAME D_MODULE_NAME"::d_groupsRequest_s" +#define D_GROUPS_REQ_TOP_NAME "v_message<" D_GROUPS_REQ_TYPE_NAME ">" +#define D_GROUPS_REQ_KEY_LIST "parentMsg.senderAddress.systemId" + +#define D_SAMPLE_REQ_TOPIC_NAME "d_sampleRequest" +#define D_SAMPLE_REQ_TYPE_NAME D_MODULE_NAME"::d_sampleRequest_s" +#define D_SAMPLE_REQ_TOP_NAME "v_message<" D_SAMPLE_REQ_TYPE_NAME ">" +#define D_SAMPLE_REQ_KEY_LIST "parentMsg.senderAddress.systemId" + +#define D_STATUS_TOPIC_NAME "d_status" +#define D_STATUS_TYPE_NAME D_MODULE_NAME"::d_status_s" +#define D_STATUS_TOP_NAME "v_message<" D_STATUS_TYPE_NAME ">" +#define D_STATUS_KEY_LIST "parentMsg.senderAddress.systemId" + +#define D_NEWGROUP_TOPIC_NAME "d_newGroup" +#define D_NEWGROUP_TYPE_NAME D_MODULE_NAME"::d_newGroup_s" +#define D_NEWGROUP_TOP_NAME "v_message<" D_NEWGROUP_TYPE_NAME ">" +#define D_NEWGROUP_KEY_LIST "parentMsg.senderAddress.systemId" + +#define D_SAMPLE_CHAIN_TOPIC_NAME "d_sampleChain" +#define D_SAMPLE_CHAIN_TYPE_NAME D_MODULE_NAME"::d_sampleChain_s" +#define D_SAMPLE_CHAIN_TOP_NAME "v_message<" D_SAMPLE_CHAIN_TYPE_NAME ">" +#define D_SAMPLE_CHAIN_KEY_LIST "parentMsg.senderAddress.systemId" + +#define D_NAMESPACES_TOPIC_NAME "d_nameSpaces" +#define D_NAMESPACES_TYPE_NAME D_MODULE_NAME"::d_nameSpaces_s" +#define D_NAMESPACES_TOP_NAME "v_message<" D_NAMESPACES_TYPE_NAME ">" +#define D_NAMESPACES_KEY_LIST "parentMsg.senderAddress.systemId" + +#define D_NAMESPACES_REQ_TOPIC_NAME "d_nameSpacesRequest" +#define D_NAMESPACES_REQ_TYPE_NAME D_MODULE_NAME"::d_nameSpacesRequest_s" +#define D_NAMESPACES_REQ_TOP_NAME "v_message<" D_NAMESPACES_REQ_TYPE_NAME ">" +#define D_NAMESPACES_REQ_KEY_LIST "parentMsg.senderAddress.systemId" + +#define D_DELETE_DATA_TOPIC_NAME "d_deleteData" +#define D_DELETE_DATA_TYPE_NAME D_MODULE_NAME"::d_deleteData_s" +#define D_DELETE_DATA_TOP_NAME "v_message<" D_DELETE_DATA_TYPE_NAME ">" +#define D_DELETE_DATA_KEY_LIST "parentMsg.senderAddress.systemId" + +#define D_DURABILITY_STATE_REQUEST_TOPIC_NAME "d_durabilityStateRequest" +#define D_DURABILITY_STATE_REQUEST_TYPE_NAME "DDS::DurabilityStateRequest" +#define D_DURABILITY_STATE_REQUEST_TOP_NAME "v_message<" D_DURABILITY_STATE_REQUEST_TYPE_NAME ">" +#define D_DURABILITY_STATE_REQUEST_KEY_LIST "requestId.clientId.prefix,requestId.clientId.suffix" + +#define D_DURABILITY_STATE_TOPIC_NAME "d_durabilityState" +#define D_DURABILITY_STATE_TYPE_NAME "DDS::DurabilityState" +#define D_DURABILITY_STATE_TOP_NAME "v_message<" D_DURABILITY_STATE_TYPE_NAME ">" +#define D_DURABILITY_STATE_KEY_LIST "serverId.prefix,serverId.suffix" + +#define D_HISTORICAL_DATA_REQUEST_TOPIC_NAME "d_historicalDataRequest" +#define D_HISTORICAL_DATA_REQUEST_TYPE_NAME "DDS::HistoricalDataRequest" +#define D_HISTORICAL_DATA_REQUEST_TOP_NAME "v_message<" D_HISTORICAL_DATA_REQUEST_TYPE_NAME ">" +#define D_HISTORICAL_DATA_REQUEST_KEY_LIST "requestId.clientId.prefix,requestId.clientId.suffix" + +#define D_HISTORICAL_DATA_TOPIC_NAME "d_historicalData" +#define D_HISTORICAL_DATA_TYPE_NAME "DDS::HistoricalData" +#define D_HISTORICAL_DATA_TOP_NAME "v_message<" D_HISTORICAL_DATA_TYPE_NAME ">" +#define D_HISTORICAL_DATA_KEY_LIST "serverId.prefix,serverId.suffix" + +#define D_CAPABILITY_TOPIC_NAME "d_capability" +#define D_CAPABILITY_TYPE_NAME D_MODULE_NAME"::d_capability_s" +#define D_CAPABILITY_TOP_NAME "v_message<" D_CAPABILITY_TYPE_NAME ">" +#define D_CAPABILITY_KEY_LIST "parentMsg.senderAddress.systemId" + + +/** + * \brief Flags to indicate which mutexes and conditions are initialized + */ +#define D__INIT_FLAG_NONE (0u) +#define D__INIT_FLAG_EVENT_MUTEX (1u<<0) +#define D__INIT_FLAG_EVENT_COND (1u<<1) +#define D__INIT_FLAG_EVENT_THREAD (1u<<2) +#define D__INIT_FLAG_CONFLICTQUEUE_MUTEX (1u<<3) +#define D__INIT_FLAG_SEQNUM_MUTEX (1u<<4) + +/* Sequence numbers. + * Sequence numbers are encoded in the seconds field of the + * productionTimestamp if bit 30 of the nanoseconds field is + * set. + */ +#define D_MAX_VALID_SEQNUM 0xFFFFFFFEul +#define D_SEQNUM_INFINITE 0xFFFFFFFFul +#define D_SEQNUM_ISVALID(seqnum) ((seqnum) <= D_MAX_VALID_SEQNUM) + +/** + * Macro that checks the d_admin validity. + * Because d_admin is a concrete class typechecking is required. + */ +#define d_adminIsValid(_this) \ + d_objectIsValid(d_object(_this), D_ADMIN) + +/** + * Macro that checks the d_adminEvent validity. + * Because d_adminEvent is a concrete class typechecking is required. + */ +#define d_adminEventIsValid(_this) \ + d_objectIsValid(d_object(_this), D_ADMIN_EVENT) + +/** + * \brief The d_admin cast macro. + * + * This macro casts an object to a d_admin object. + */ +#define d_admin(_this) ((d_admin)(_this)) + +/** + * \brief The d_adminEvent cast macro. + * + * This macro casts an object to a d_adminEvent object. + */ +#define d_adminEvent(_this) ((d_adminEvent)(_this)) + +C_STRUCT(d_admin){ + C_EXTENDS(d_lock); + d_durability durability; + d_table unconfirmedFellows; + d_table fellows; + d_table clients; + d_table groups; + d_table readerRequests; + d_networkAddress myAddress; + c_ulong alignerGroupCount; + d_fellow cachedFellow; + + d_publisher publisher; + d_subscriber subscriber; + + u_topic groupsRequestTopic; + u_topic sampleRequestTopic; + u_topic statusTopic; + u_topic newGroupTopic; + u_topic sampleChainTopic; + u_topic nameSpacesTopic; + u_topic nameSpacesRequestTopic; + u_topic deleteDataTopic; + u_topic durabilityStateRequestTopic; + u_topic durabilityStateTopic; + u_topic historicalDataRequestTopic; + u_topic historicalDataTopic; + u_topic capabilityTopic; + + d_actionQueue actionQueue; + + os_mutex eventMutex; + c_iter eventListeners; + c_iter eventQueue; + os_cond eventCondition; + os_threadId eventThread; + c_bool eventThreadTerminate; + + c_iter nameSpaces; + + c_ulong initMask; /* Mask to indicate which mutexes have been initialized */ + d_table terminateFellows; /* Table of fellows that have recently terminated */ + + c_iter conflictQueue; /* Detected conflicts */ + os_mutex conflictQueueMutex; + + d_conflictMonitor conflictMonitor; + d_conflictResolver conflictResolver; + + os_uint32 seqnum; /* durability service specific message sequence number */ + os_mutex seqnumMutex; /* Mutex to automically increment the sequence number */ + + d_table initial_fellows; /* The list of fellows used when resolving an initial conflict */ +}; + +C_CLASS(d_adminEvent); + +C_STRUCT(d_adminEvent){ + C_EXTENDS(d_object); + c_ulong event; + d_fellow fellow; + d_nameSpace nameSpace; + d_group group; + c_voidp userData; +}; + +struct cleanupData{ + c_iter fellows; + d_durability durability; +}; + +struct sendData{ + d_admin admin; + d_configuration configuration; + d_networkAddress addressee; +}; + +struct masterCountForRoleHelper +{ + d_name role; + d_nameSpace nameSpace; + c_ulong masterCount; +}; + +struct collectMatchingGroupsHelper { + d_admin admin; + char *topic; /* topic to match */ + c_iter partitions; /* list of partition expressions to match */ + d_table matchingGroups; /* table of collected matching groups */ + c_bool forMe; /* originating request was addressed to me */ + c_bool forEverybody; /* originating request was addressed to everybody */ + c_bool isAligner; /* Indicates if I am an aligner for one of the matching partition/topic expressions */ + c_bool isResponsible; /* Indicates if I am responsible for alignment */ + c_bool masterKnown; /* Indicates if a master confirmed master is selected */ + c_bool groupFound; /* Indicates if a group is found for which this master is responsible */ + c_bool isHistoricalDataRequest; /* Indicates if the request was a historicalDataRequest or a DurabilityStateRequest */ + os_uint64 seqnum; /* durability service specific message sequence number */ +}; + + +void d_adminUpdateStatistics (d_admin admin, + d_adminStatisticsInfo statistics); + +d_admin d_adminNew (d_durability durability); + +void d_adminDeinit (d_admin admin); + +void d_adminFree (d_admin admin); + +void d_adminInitSubscriber (d_admin admin); + +d_durability d_adminGetDurability (d_admin admin); + +d_publisher d_adminGetPublisher (d_admin admin); + +d_subscriber d_adminGetSubscriber (d_admin admin); + +c_bool d_adminAddLocalGroup (d_admin admin, + d_group group); + +d_group d_adminGetLocalGroup (d_admin admin, + const c_char* partition, + const c_char* topic, + d_durabilityKind kind); + +c_ulong d_adminGetAlignerGroupCount (d_admin admin); + +void d_adminGroupWalk (d_admin admin, + c_bool ( * action ) ( + d_group group, + c_voidp userData), + c_voidp args); + +d_fellow d_adminGetUnconfirmedFellow (d_admin admin, + d_networkAddress address); + +d_fellow d_adminGetFellow (d_admin admin, + d_networkAddress address); + +d_fellow d_adminAddFellow (d_admin admin, + d_fellow fellow); + +d_fellow d_adminRemoveFellow (d_admin admin, + d_fellow fellow, + c_bool trackFellow); + +void d_adminAsymRemoveFellow (d_admin admin, + d_fellow fellow, + c_bool trackFellow); + +d_networkAddress d_adminGetMyAddress (d_admin admin); + +c_bool d_adminFellowWalk (d_admin admin, + c_bool ( * action ) ( + d_fellow fellow, + c_voidp userData), + c_voidp userData); + +c_bool d_adminInitialFellowWalk (d_admin admin, + c_bool ( * action ) ( + d_fellow fellow, + c_voidp userData), + c_voidp userData); + +c_ulong d_adminGetFellowCount (d_admin admin); + +c_ulong d_adminGetInitialFellowCount (d_admin admin); + +void d_adminCleanupTerminateFellows (d_admin admin); + +void d_adminAddNameSpace (d_admin admin, + d_nameSpace nameSpace); + +void d_adminNameSpaceWalk (d_admin admin, + void (*action)( + d_nameSpace nameSpace, + c_voidp userData), + c_voidp userData); + +c_iter d_adminNameSpaceCollect (d_admin admin); +void d_adminNameSpaceCollectFree (d_admin admin, c_iter nameSpaces); + +c_ulong d_adminGetNameSpacesCount (d_admin admin); + +d_nameSpace d_adminGetNameSpaceForGroupNoLock (d_admin admin, + d_partition partition, + d_topic topic); + +d_nameSpace d_adminGetNameSpaceForGroup (d_admin admin, + d_partition partition, + d_topic topic); + +c_bool d_adminInNameSpace (d_nameSpace ns, + d_partition partition, + d_topic topic, + c_bool aligner); + +c_bool d_adminGroupInInitialAligneeNS (d_admin admin, + d_partition partition, + d_topic topic); + +/** + * Determines whether the supplied partition-topic combination is in the + * aligner namespace for persistent data. + * + * @param admin The admin that contains the namespaces. + * @param partition The partition to check. + * @param topic The topic to check. + * @return TRUE if it is in the namespace, FALSE otherwise. + */ +c_bool d_adminGroupInAlignerNS (d_admin admin, + d_partition partition, + d_topic topic); +/** + * Determines whether the supplied partition-topic combination is in the + * alignee namespace for non-volatile data and the + * alignmentKind != D_ALIGNMENT_ON_REQUEST. + * + * @param admin The admin that contains the namespaces. + * @param partition The partition to check. + * @param topic The topic to check. + * @param kind The durability kind. + * @return TRUE if it is in the namespace, FALSE otherwise. + */ +c_bool d_adminGroupInActiveAligneeNS (d_admin admin, + d_partition partition, + d_topic topic); +/** + * Determines whether the supplied partition-topic combination is in the + * alignee namespace for non-volatile data. + * + * @param admin The admin that contains the namespaces. + * @param partition The partition to check. + * @param topic The topic to check. + * @param kind The durability kind. + * @return TRUE if it is in the namespace, FALSE otherwise. + */ +c_bool d_adminGroupInAligneeNS (d_admin admin, + d_partition partition, + d_topic topic); + +u_topic d_adminGetStatusTopic (d_admin admin); + +u_topic d_adminGetNewGroupTopic (d_admin admin); + +u_topic d_adminGetGroupsRequestTopic (d_admin admin); + +u_topic d_adminGetStatusRequestTopic (d_admin admin); + +u_topic d_adminGetSampleRequestTopic (d_admin admin); + +u_topic d_adminGetSampleChainTopic (d_admin admin); + +u_topic d_adminGetNameSpacesTopic (d_admin admin); + +u_topic d_adminGetNameSpacesRequestTopic (d_admin admin); + +u_topic d_adminGetDeleteDataTopic (d_admin admin); + +u_topic d_adminGetDurabilityStateRequestTopic (d_admin admin); + +u_topic d_adminGetDurabilityStateTopic (d_admin admin); + +u_topic d_adminGetHistoricalDataRequestTopic (d_admin admin); + +u_topic d_adminGetHistoricalDataTopic (d_admin admin); + +u_topic d_adminGetCapabilityTopic (d_admin admin); + +c_bool d_adminAreLocalGroupsComplete (d_admin admin, + c_bool report); + +void d_adminAddListener (d_admin admin, + d_eventListener listener); + +void d_adminRemoveListener (d_admin admin, + d_eventListener listener); + +void d_adminNotifyListeners (d_admin admin, + c_ulong mask, + d_fellow fellow, + d_nameSpace nameSpace, + d_group group, + c_voidp userData); + +d_actionQueue d_adminGetActionQueue (d_admin admin); + +c_ulong d_adminGetIncompatibleStateCount (d_admin admin); + +c_ulong d_adminGetIncompatibleDataModelCount (d_admin admin); + +c_bool d_adminAddReaderRequest (d_admin admin, + d_readerRequest request); + +c_bool d_adminRemoveReaderRequest (d_admin admin, + d_networkAddress source); + +d_readerRequest d_adminGetReaderRequest (d_admin admin, + d_networkAddress source); + +c_bool d_adminCheckReaderRequestFulfilled (d_admin admin, + d_readerRequest request); + +d_nameSpace d_adminGetNameSpace (d_admin admin, + os_char* name); + +void d_adminReportMaster (d_admin admin, + d_fellow fellow, + d_nameSpace nameSpace); + +void d_adminReportDelayedInitialSet (d_admin admin, + d_nameSpace nameSpace, + d_fellow fellow); + +c_bool d_nameSpaceCountMastersForRoleWalk (d_fellow fellow, + void* userData); + +u_topic d_adminInitTopic (d_admin admin, + const c_char* topicName, + const c_char* typeName, + const c_char* keyList, + v_reliabilityKind reliability, + v_historyQosKind historyKind, + v_orderbyKind orderKind, + c_long historyDepth); + +void d_adminInitAddress (v_public entity, + c_voidp args); + +c_bool d_adminSendLocalGroupsAction (d_group group, + c_voidp userData); + +d_adminEvent d_adminEventNew (c_ulong event, + d_fellow fellow, + d_nameSpace nameSpace, + d_group group, + c_voidp userData); + +void d_adminEventDeinit (d_adminEvent event); + +void d_adminEventFree (d_adminEvent event); + +void* d_adminEventThreadStart (void* arg); + +void d_adminCollectMatchingGroups (d_admin admin, + c_voidp arg); + +char * d_adminGetStaticFilterExpression (d_admin admin, + char *partition, + char *topic); + +d_client d_adminGetClient (d_admin admin, + d_networkAddress address); + +d_client d_adminAddClient (d_admin admin, + d_client client); + +d_client d_adminRemoveClient (d_admin admin, + d_client client); + +d_client d_adminFindClientByClientId (d_admin admin, + struct _DDS_Gid_t clientId); + +os_uint32 d_adminGetNextSeqNum (d_admin admin); + +c_iter d_adminGetNameSpaces (d_admin admin); + +void d_admin_sync_mergeStates (d_admin admin); + +void d_adminReportGroup (d_admin admin,d_group group); + +/* Marks all groups that fall within a namespace of durability complete/incomplete. */ +void d_adminMarkNameSpaceKernelGroupsCompleteness (_Inout_ d_admin admin, + _In_ c_bool complete); + +void d_adminStoreGroup (d_admin admin, d_group group); + +void d_adminSetConflictResolver (d_admin admin, d_conflictResolver conflictResolver); + +void d_adminInitialFellowsCreate (d_admin admin); + +void d_adminInitialFellowsDestroy (d_admin admin); + +char * d_adminGetInitialFellowsString (d_admin admin); + +#if defined (__cplusplus) +} +#endif + +#endif /* D__ADMIN_H */ diff --git a/src/services/durability/code/d__capability.h b/src/services/durability/code/d__capability.h new file mode 100644 index 000000000..8f17cc816 --- /dev/null +++ b/src/services/durability/code/d__capability.h @@ -0,0 +1,56 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef D__CAPABILITY_H +#define D__CAPABILITY_H + +#include "d__types.h" +#include "d__admin.h" + +#if defined (__cplusplus) +extern "C" { +#endif + +/* Number of capabilities for this durability service */ +#define D_NUMBER_OF_CAPABILITIES (5) + +/* List of capability names */ +#define D_CAPABILITY_GROUP_HASH "groupHash" +#define D_CAPABILITY_EOT_SUPPORT "EOTsupport" +#define D_CAPABILITY_Y2038READY "Y2038Ready" +#define D_CAPABILITY_MASTER_SELECTION "masterSelection" +#define D_CAPABILITY_INCARNATION "incarnation" + +/** + * \brief The d_capability cast macro. + * + * This macro casts an object to a d_capability object. + */ +#define d_capability(s) ((d_capability)(s)) + +d_capability d_capabilityNew (d_admin admin, c_ulong incarnation); + +void d_capabilityFree (d_capability capability); + +char * d_capabilityToString (d_capability capability); + +#if defined (__cplusplus) +} +#endif + +#endif /* D__CAPABILITY_H */ diff --git a/src/services/durability/code/d__capabilityListener.h b/src/services/durability/code/d__capabilityListener.h new file mode 100644 index 000000000..6918aa141 --- /dev/null +++ b/src/services/durability/code/d__capabilityListener.h @@ -0,0 +1,37 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef D__CAPABILITYLISTENER_H_ +#define D__CAPABILITYLISTENER_H_ + +#include "d__types.h" + +#if defined (__cplusplus) +extern "C" { +#endif + +d_capabilityListener d_capabilityListenerNew (d_subscriber subscriber); +void d_capabilityListenerFree (d_capabilityListener listener); +c_bool d_capabilityListenerStart (d_capabilityListener listener); +c_bool d_capabilityListenerStop (d_capabilityListener listener); + +#if defined (__cplusplus) +} +#endif + +#endif /* D__CAPABILITYLISTENER_H_ */ diff --git a/src/services/durability/code/d__client.h b/src/services/durability/code/d__client.h new file mode 100644 index 000000000..9a826f937 --- /dev/null +++ b/src/services/durability/code/d__client.h @@ -0,0 +1,103 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#ifndef D__CLIENT_H +#define D__CLIENT_H + +#include "d__types.h" +#include "d__lock.h" +#include "d__table.h" +#include "os_mutex.h" +#include "os_time.h" + +#include "client_durabilitySplType.h" + + +#if defined (__cplusplus) +extern "C" { +#endif + +/* client durability reader flags. + * These flags can be used to determine what functionality is + * offered by a fellow + */ +#define D_HISTORICALDATAREQUEST_READER_FLAG (0x0001U << 9) /* 1 */ +#define D_DURABILITYSTATEREQUEST_READER_FLAG (0x0001U << 10) /* 2 */ +#define D_HISTORICALDATA_READER_FLAG (0x0001U << 11) /* 4 */ +#define D_DURABILITYSTATE_READER_FLAG (0x0001U << 12) /* 8 */ + +#define D_BASIC_CLIENT_DURABILITY_READER_FLAGS \ + D_HISTORICALDATA_READER_FLAG + +#define D_FULL_CLIENT_DURABILITY_READER_FLAGS \ + (D_HISTORICALDATA_READER_FLAG | D_DURABILITYSTATE_READER_FLAG) + +/** + * Macro that checks the d_client validity. + * Because d_client is a concrete class typechecking is required. + */ +#define d_clientIsValid(_this) \ + d_objectIsValid(d_object(_this), D_CLIENT) + +/** + * \brief The d_client cast macro. + * + * This macro casts an object to a d_client object. + */ +#define d_client(_this) ((d_client)(_this)) + + +C_STRUCT(d_client){ + C_EXTENDS(d_lock); + d_networkAddress address; /* Federation of the client */ + struct _DDS_Gid_t clientId; /* Client id */ + c_ulong readers; /* Bit pattern to indicate which client durability readers are discovered */ + c_ulong requiredReaders; /* Bit pattern to indicate which client durability readers MUST BE discovered before the client is considered responsive */ + c_bool isConfirmed; /* Indicates if client is confirmed or not */ +}; + +d_client d_clientNew (d_networkAddress address); + +void d_clientDeinit (d_client client); + +void d_clientFree (d_client client); + +int d_clientCompareByAddress (d_client client1, + d_client client2); + +d_networkAddress d_clientGetAddress (d_client client); + +void d_clientAddReader (d_client client, + c_ulong reader); + +void d_clientRemoveReader (d_client client, + c_ulong reader); + +void d_clientSetClientId (d_client client, + struct _DDS_Gid_t clientId); + +c_bool d_clientIsConfirmed (d_client client); + +c_bool d_clientIsResponsive (d_client client, + c_ulong requiredReaders, + c_bool waitForRemoteReaders); + +#if defined (__cplusplus) +} +#endif + +#endif /* D__CLIENT_H */ diff --git a/src/services/durability/code/d__configuration.h b/src/services/durability/code/d__configuration.h new file mode 100644 index 000000000..bb29ec45c --- /dev/null +++ b/src/services/durability/code/d__configuration.h @@ -0,0 +1,596 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef D__CONFIGURATION_H +#define D__CONFIGURATION_H + +#include "d__types.h" +#include "u_user.h" +#include "v_kernel.h" + +#if defined (__cplusplus) +extern "C" { +#endif + +/** + * Macro that checks the d_configuration validity. + * Because d_configuration is a concrete class typechecking is required. + */ +#define d_configurationIsValid(_this) \ + d_objectIsValid(d_object(_this), D_CONFIGURATION) + +/** + * \brief The d_configuration cast macro. + * + * This macro casts an object to a d_configuration object. + */ +#define d_configuration(_this) ((d_configuration)(_this)) + +/* Configuration defaults */ +#define D_MINIMUM_LIVELINESS_EXPIRY_TIME ((float) 0.2e0) +#define D_DEFAULT_LIVELINESS_EXPIRY_TIME ((float)10.0e0) +#define D_MAXIMUM_LIVELINESS_EXPIRY_TIME ((float)2147483647.2147483647) + +#define D_MINIMUM_LIVELINESS_UPDATE_FACTOR ((float)0.01e0) +#define D_DEFAULT_LIVELINESS_UPDATE_FACTOR ((float)0.2e0) +#define D_MAXIMUM_LIVELINESS_UPDATE_FACTOR ((float)1.0e0) + +#define D_MINIMUM_HEARTBEAT_UPDATE_FACTOR ((float)0.1e0) +#define D_DEFAULT_HEARTBEAT_UPDATE_FACTOR ((float)0.25e0) +#define D_MAXIMUM_HEARTBEAT_UPDATE_FACTOR ((float)0.9e0) + +#define D_MINIMUM_HEARTBEAT_EXPIRY_TIME ((float)0.2e0) +#define D_DEFAULT_HEARTBEAT_EXPIRY_TIME ((float)4.0e0) +#define D_MAXIMUM_HEARTBEAT_EXPIRY_TIME ((float)2147483647.2147483647) + +#define D_MINIMUM_TIMING_INITIAL_WAIT_PERIOD ((float)0.10e0) +#define D_DEFAULT_TIMING_INITIAL_WAIT_PERIOD ((float)3.000e0) +#define D_MAXIMUM_TIMING_INITIAL_WAIT_PERIOD ((float)60.000e0) + +#define D_MINIMUM_INITIAL_REQUEST_COMBINE_PERIOD ((float)0.01e0) +#define D_DEFAULT_INITIAL_REQUEST_COMBINE_PERIOD ((float)0.5e0) +#define D_MAXIMUM_INITIAL_REQUEST_COMBINE_PERIOD ((float)5.0e0) + +#define D_MINIMUM_OPERATIONAL_REQUEST_COMBINE_PERIOD ((float)0.01e0) +#define D_DEFAULT_OPERATIONAL_REQUEST_COMBINE_PERIOD ((float)0.01e0) +#define D_MAXIMUM_OPERATIONAL_REQUEST_COMBINE_PERIOD ((float)5.0e0) + +#define D_MINIMUM_LATENCY_BUDGET ((float)0.0e0) +#define D_DEFAULT_LATENCY_BUDGET ((float)0.0e0) +#define D_MAXIMUM_LATENCY_BUDGET ((float)2147483647.2147483647) + +#define D_MINIMUM_TRANSPORT_PRIORITY (0) +#define D_DEFAULT_TRANSPORT_PRIORITY (0) +#define D_MAXIMUM_TRANSPORT_PRIORITY (2147483647) + +#define D_MINIMUM_NETWORK_MAX_WAITCOUNT (1) +#define D_DEFAULT_NETWORK_MAX_WAITCOUNT (200) +#define D_MAXIMUM_NETWORK_MAX_WAITCOUNT (1000) + +#define D_PUBLISHER_NAME "durabilityPublisher" +#define D_SUBSCRIBER_NAME "durabilitySubscriber" +#define D_PARTITION_NAME "durabilityPartition" +#define D_CLIENT_DURABILITY_PARTITION_NAME D_PARTITION_NAME +#define D_CLIENT_DURABILITY_PUBLISHER_NAME "clientDurabilityPublisher" +#define D_CLIENT_DURABILITY_SUBSCRIBER_NAME "clientDurabilitySubscriber" +#define D_DURABILITY_BUILTIN_SUBSCRIBER_NAME "durabilityBuiltinSubscriber" + +#define D_DEFAULT_TRACING_OUTFILE "durability.log" + +#define D_MINIMUM_PERSISTENT_STORE_SLEEP_TIME ((float)0.0e0) +#define D_DEFAULT_PERSISTENT_STORE_SLEEP_TIME ((float)0.0e0) +#define D_MAXIMUM_PERSISTENT_STORE_SLEEP_TIME ((float)10.0e0) + +#define D_MINIMUM_PERSISTENT_STORE_SESSION_TIME ((float)0.001e0) +#define D_DEFAULT_PERSISTENT_STORE_SESSION_TIME ((float)20.0e0) +#define D_MAXIMUM_PERSISTENT_STORE_SESSION_TIME ((float)60.0e0) + +#define D_MINIMUM_PERSISTENT_QUEUE_SIZE (0) +#define D_DEFAULT_PERSISTENT_QUEUE_SIZE (0) +#define D_MAXIMUM_PERSISTENT_QUEUE_SIZE (10000) + +#define D_DEFAULT_PERSISTENT_KV_COMPRESSION_ENABLED (FALSE) +#define D_DEFAULT_PERSISTENT_KV_COMPRESSION_ALGORITHM "lzf" + +#define D_MINIMUM_OPTIMIZE_INTERVAL (10) +#define D_DEFAULT_OPTIMIZE_INTERVAL (0) +#define D_MAXIMUM_OPTIMIZE_INTERVAL (1000000000) + +#define D_MINIMUM_TIME_TO_WAIT_FOR_ALIGNER ((float)0.0e0) +#define D_DEFAULT_TIME_TO_WAIT_FOR_ALIGNER ((float)1.0e0) +#define D_MAXIMUM_TIME_TO_WAIT_FOR_ALIGNER ((float)1.0e0) + +#define D_MINIMUM_SERVICE_TERMINATE_PERIOD ((float)0.0e0) +#define D_DEFAULT_SERVICE_TERMINATE_PERIOD ((float)10.0e0) +#define D_MAXIMUM_SERVICE_TERMINATE_PERIOD ((float)60.0e0) + +#define D_DEFAULT_TERMINATE_REMOVAL_PERIOD ((float)5.0e0) + +#define D_DEFAULT_ROLE "DefaultRole" + +#define D_DEFAULT_EQUALITY_CHECK (FALSE) + +#define D_MINIMUM_MASTER_PRIORITY (0) +#define D_DEFAULT_MASTER_PRIORITY (255) +#define D_MAXIMUM_MASTER_PRIORITY (255) + +#define D_MINIMUM_MASTER_ELECTION_WAIT_TIME ((float)0.0e0) +#define D_DEFAULT_MASTER_ELECTION_WAIT_TIME ((float)0.0e0) +#define D_MAXIMUM_MASTER_ELECTION_WAIT_TIME ((float)10.0e0) + +#define IS_LEGACY_MASTER_SELECTION(priority) ((priority == D_MAXIMUM_MASTER_PRIORITY)) + +#define D_MINIMUM_MAJORITY_VOTING_THRESHOLD (5) +#define D_DEFAULT_MAJORITY_VOTING_THRESHOLD (D_MINIMUM_MAJORITY_VOTING_THRESHOLD) +#define D_MAXIMUM_MAJORITY_VOTING_THRESHOLD (50) + +#define D_DEFAULT_DURABLE_POLICY_CACHE (TRUE) + +#define D_DEFAULT_THREAD_LIVELINESS_REPORT_PERIOD ((float)0.0e0) + +/* Master selection algorithm */ +#define D_USE_LEGACY_ALGORITHM (0) +#define D_USE_MASTER_PRIORITY_ALGORITHM (1) + +/* Mask settings for additional tracing */ +#define D_TRACE_PRIO_QUEUE (0x0001U << 0) /* 1 */ +#define D_TRACE_GROUP (0x0001U << 1) /* 2 */ +#define D_TRACE_CLIENT_DURABILITY (0x0001U << 2) /* 4 */ +#define D_TRACE_GROUP_HASH (0x0001U << 3) /* 8 */ +#define D_TRACE_MASTER_SELECTION (0x0001U << 4) /* 16 */ +#define D_TRACE_COMBINE_REQUESTS (0x0001U << 5) /* 32 */ +#define D_TRACE_CHAINS (0x0001U << 6) /* 64 */ +#define D_TRACE_NONE (0U) +#define D_TRACE_ALL (~0U) + + +C_STRUCT(d_configuration){ + C_EXTENDS(d_object); + c_bool builtinTopicsEnabled; + os_duration livelinessExpiryTime; /* ExpiryTime (duration */ + c_float livelinessExpiry; /* ExpiryTime (float) */ + os_duration livelinessUpdateInterval; /* ExpiryTime * update_factor */ + os_threadAttr livelinessScheduling; /* Not implemented yet.*/ + os_duration heartbeatUpdateInterval; + os_duration heartbeatExpiryTime; + c_float heartbeatExpiry; + os_threadAttr heartbeatScheduling; + os_duration timingInitialWaitPeriod; + c_ulong networkMaxWaitCount; + os_duration networkMaxWaitTime; + d_table networkServiceNames; + c_iter services; + c_char* publisherName; + c_char* subscriberName; + c_char* partitionName; + FILE* tracingOutputFile; + c_char* tracingOutputFileName; + c_bool tracingSynchronous; + c_bool tracingTimestamps; + c_bool tracingRelativeTimestamps; + d_level tracingVerbosityLevel; + c_char* persistentStoreDirectory; + d_storeType persistentStoreMode; + c_ulong persistentStoreStackSize; + c_char* persistentKVStoreStorageType; + c_char* persistentKVStoreStorageParameters; + c_bool persistentKVStoreCompressionEnabled; + d_compressionKV persistentKVStoreCompressionAlgorithm; + os_duration persistentStoreSleepTime; + os_duration persistentStoreSessionTime; + c_ulong persistentQueueSize; + os_threadAttr persistentScheduling; + c_iter nameSpaces; + c_iter policies; + c_iter filters; + c_iter durablePolicies; + os_timeW startWTime; + os_timeM startMTime; + os_timeE startETime; + c_ulong persistentUpdateInterval; + os_duration latencyBudget; + c_long transportPriority; + os_duration heartbeatLatencyBudget; + c_long heartbeatTransportPriority; + os_duration alignerLatencyBudget; + c_long alignerTransportPriority; + os_threadAttr alignerScheduling; + os_threadAttr aligneeScheduling; + os_duration initialRequestCombinePeriod; + os_duration operationalRequestCombinePeriod; + c_bool timeAlignment; + d_name role; + os_duration timeToWaitForAligner; + c_bool mustAlignBuiltinTopics; /* if TRUE durability will align builtin topics */ + c_bool waitForRemoteReaders; /* if TRUE durability will send its + * nameSpaces to a fellow only if + * ALL durability readers of the + * fellow have been discovered. + * The same holds for response to client durability requests. + */ + c_float serviceTerminate; /* Amount of time the domain should wait for other services to terminate */ + os_duration serviceTerminatePeriod; + os_duration terminateRemovalPeriod; /* Period to ignore messages from the fellow after it has terminated */ + c_bool clientDurabilityEnabled; /* if TRUE durability is able to provide historical data when asked for by a client durability service */ + c_char* clientDurabilityPartitionName; /* client durability partition name */ + c_char* clientDurabilityPublisherName; /* client durability publisher name */ + c_char* clientDurabilitySubscriberName; /* client durability subscriber name */ + c_bool deadlockDetection; + c_bool capabilitySupport; /* if TRUE the capability interface is supported; default is TRUE. + * Capability support can be disabled by setting environment var + * OSPL_DURABILITY_CAPABILITY_SUPPORT to 0 + */ + c_bool capabilityGroupHash; /* if TRUE the ability to calculate a hash of a data set for a group is enabled */ + c_bool capabilityEOTSupport; /* if TRUE the durability service support the ability to align EOT messages */ + c_bool capabilityY2038Ready; /* if TRUE the durability service can advertise times beyond 2038 */ + c_ulong traceMask; /* mask to indicate what traces to log, only effective when verbosity level is set to D_LEVEL_FINEST */ + + os_uint32 seqnum_initval; /* initial sequence number value (0 by default, can be changed using environment variable OSPL_DURABILITY_SEQNUM_INITIAL_VALUE */ + c_ulong capabilityMasterSelection; /* Indicator for master selection algorithm to use */ + + c_bool masterSelectionLegacy; /* Use legacy mode */ + os_duration masterElectionWaitTime; /* Time to wait before selecting a master, defaults to 0 */ + c_ulong majorityVotingThreshold; /* Number of rounds before ending up in majority voting, defaults to D_MINIMUM_MAJORITY_VOTING_THRESHOLD */ + c_ulong initialMergeStateValue; + os_duration threadLivelinessReportPeriod; /* Period to report thread liveliness, 0 when infinite */ +}; + + +struct durablePolicy { + char *obtain; + c_bool cache; +}; + + +/** + * Allocates a new configuration. + * The configuration is read from the user layer service of the supplied + * d_durability object. + * + * @param service The object to resolve the user layer service from. This + * contains the configuration that was read when creating it. + * @param serviceName The name of the service. This is used to locate the + * correct configuration entity in the configuration file. + * The 'name' attribute of the durability service in the + * configuration must match this parameter. + * @return The read configuration. The configuration items that were not in + * the configuration file have the default value. + */ +d_configuration d_configurationNew (d_durability service, + const c_char* serviceName, + c_long domainId); + +/** + * Frees the supplied configuration. + * + * @param configuration The configuration to free. + */ +void d_configurationFree (d_configuration config); + +c_bool d_configurationInNameSpace (d_nameSpace ns, + d_partition partition, + d_topic topic, + c_bool aligner); + +int d_configurationInit (d_configuration config, + u_cfElement cfg, + d_durability durability, + u_cfElement domainElement, + u_cfElement element); + +void d_configurationDeinit (d_configuration config); + +void d_configurationSetLivelinessExpiryTime (d_configuration config, + c_float seconds); + +void d_configurationSetLivelinessUpdateFactor (d_configuration config, + u_cfElement element, + const c_char* expiryTimePath, + const c_char* updateFactorName); + +void d_configurationSetLivelinessSchedulingClass (d_configuration config, + const c_char* class); + +void d_configurationSetLivelinessSchedulingPriority (d_configuration config, + c_long priority); + +void d_configurationSetPersistentSchedulingClass (d_configuration config, + const c_char* class); + +void d_configurationSetPersistentSchedulingPriority (d_configuration config, + c_long priority); + +void d_configurationSetHeartbeatSchedulingClass (d_configuration config, + const c_char* class); + +void d_configurationSetHeartbeatSchedulingPriority (d_configuration config, + c_long priority); + +void d_configurationSetAlignerSchedulingClass (d_configuration config, + const c_char* class); + +void d_configurationSetAlignerSchedulingPriority (d_configuration config, + c_long priority); + +void d_configurationSetPersistentSchedulingStackSize (d_configuration config, + c_ulong stackSize); + +void d_configurationSetAligneeSchedulingClass (d_configuration config, + const c_char* class); + +void d_configurationSetAligneeSchedulingPriority (d_configuration config, + c_long priority); + +void d_configurationSetHeartbeatExpiryTime (d_configuration config, + c_float seconds); + +void d_configurationSetHeartbeatUpdateFactor (d_configuration config, + u_cfElement element, + const c_char* expiryTimePath, + const c_char* updateFactorName); + +void d_configurationSetTimingInitialWaitPeriod (d_configuration config, + c_float seconds); + +void d_configurationSetInitialRequestCombinePeriod (d_configuration config, + c_float seconds); + +void d_configurationSetOperationalRequestCombinePeriod (d_configuration config, + c_float seconds); + +void d_configurationSetMasterElectionWaitTime (d_configuration config, + c_float seconds); + +void d_configurationSetLatencyBudget (d_configuration config, + c_float seconds); + +void d_configurationSetHeartbeatLatencyBudget (d_configuration config, + c_float seconds); + +void d_configurationSetAlignmentLatencyBudget (d_configuration config, + c_float seconds); + +void d_configurationSetMajorityVotingThreshold (d_configuration config, + c_ulong threshold); + +void d_configurationSetTransportPriority (d_configuration config, + c_long prio); + +void d_configurationSetHeartbeatTransportPriority (d_configuration config, + c_long prio); + +void d_configurationSetAlignmentTransportPriority (d_configuration config, + c_long prio); + +void d_configurationSetNetworkWaitForAttachmentMaxWaitCount (d_configuration config, + c_ulong maxWaits); + +void d_configurationSetNetworkWaitForAttachment (d_configuration config, + u_cfElement elementParent, + const c_char* attachName, + const c_char* serviceName); + +void d_configurationSetNetworkResendTimeRange (d_configuration config, + c_float seconds); + +void d_configurationSetClientDurabilityEnabled (d_configuration config, + const c_bool enabled); + +void d_configurationSetPublisherName (d_configuration config, + const c_char * publisherName); + +void d_configurationSetSubscriberName (d_configuration config, + const c_char * subscriberName); + +void d_configurationSetPartitionName (d_configuration config, + const c_char * partitionName); + +void d_configurationSetClientDurabilityPartitionName (d_configuration config, + const c_char * partitionName); + +void d_configurationSetClientDurabilityPublisherName (d_configuration config, + const c_char * publisherName); + +void d_configurationSetClientDurabilitySubscriberName (d_configuration config, + const c_char * subscriberName); + +void d_configurationSetTracingSynchronous (d_configuration config, + const c_bool synchronous); + +void d_configurationSetTracingOutputFile (d_configuration config, + const c_char* value); + +void d_configurationSetTracingTimestamps (d_configuration config, + c_bool useTimestamp); + +void d_configurationSetTimeAlignment (d_configuration config, + c_bool alignment); + +void d_configurationSetTimeToWaitForAligner (d_configuration config, + c_float seconds); + +void d_configurationSetTracingRelativeTimestamps (d_configuration config, + u_cfElement element, + const c_char* timestampsPath, + const c_char* absoluteName); + +void d_configurationSetTracingVerbosity (d_configuration config, + const c_char* value); + + +void d_configurationSetPersistentStoreDirectory (d_configuration config, + const c_char* storePath); + + +void d_configurationSetPersistentStoreMode (d_configuration config, + const c_char * storeModeName); + +void d_configurationResolvePersistentKVConfig (d_configuration config, + u_cfElement elementParent, + const c_char *elementName); + +void d_configurationSetPersistentKVStorageParameters (d_configuration config, + const c_char * parameters); + +void d_configurationResolvePersistentKVCompression (d_configuration config, + u_cfElement elementParent, + const c_char *elementName); + +void d_configurationSetPersistentKVCompressionEnabled (d_configuration config, + c_bool enabled); + +void d_configurationSetPersistentKVCompressionAlgorithm (d_configuration config, + const c_char *algorithm); + +void d_configurationSetPersistentQueueSize (d_configuration config, + c_ulong size); + +void d_configurationSetPersistentStoreSleepTime (d_configuration config, + c_float seconds); + +void d_configurationSetPersistentStoreSessionTime(d_configuration config, + c_float seconds); + +void d_configurationSetBuiltinTopicsEnabled (d_configuration config, + c_bool enabled); + +void d_configurationSetDuration (os_duration *duration, + c_float seconds ); + +c_iter d_configurationResolvePolicies (u_cfElement elementParent, + const c_char * policyName); + +c_iter d_configurationResolveNameSpaces (d_configuration config, + u_cfElement elementParent, + const c_char * nameSpaceName, + int * resolveResult); + +c_iter d_configurationResolveFilters (d_configuration config, + u_cfElement elementParent, + const c_char *filterElement, + d_durability durability); + +int d_configurationResolvePartition (d_nameSpace nameSpace, + u_cfElement element, + c_char * name, + const c_char * tag, + const c_char * topic); + +int d_configurationResolvePartitionTopic (d_nameSpace nameSpace, + u_cfElement element, + c_char * name, + const c_char * tag); + +void d_configurationAttrValueLong (d_configuration configuration, + u_cfElement element, + const char * tag, + const char * attr, + void (* const setAction)(d_configuration config, c_long longValue)); + +void d_configurationAttrValueULong (d_configuration configuration, + u_cfElement element, + const char * tag, + const char * attr, + void (* const setAction)(d_configuration config, c_ulong longValue)); + +void d_configurationAttrValueFloat (d_configuration configuration, + u_cfElement element, + const char * tag, + const char * attr, + void (* const setAction)(d_configuration config, c_float floatValue)); + +void d_configurationAttrValueBoolean (d_configuration configuration, + u_cfElement element, + const char * tag, + const char * attr, + void (* const setAction)(d_configuration config, c_bool boolValue)); + +void d_configurationValueULong (d_configuration configuration, + u_cfElement element, + const char * tag, + void (* const setAction)(d_configuration config, c_ulong longValue)); + +void d_configurationValueSize (d_configuration configuration, + u_cfElement element, + const char * tag, + void (* const setAction)(d_configuration config, c_size size)); + +void d_configurationValueLong (d_configuration configuration, + u_cfElement element, + const char * tag, + void (* const setAction)(d_configuration config, c_long longValue)); + +void d_configurationValueFloat (d_configuration configuration, + u_cfElement element, + const char * tag, + void (* const setAction)(d_configuration config, c_float floatValue)); + +void d_configurationValueString (d_configuration configuration, + u_cfElement element, + const char * tag, + void (* const setAction)(d_configuration config, const c_char* str)); +void d_configurationValueMemAddr (d_configuration configuration, + u_cfElement element, + const char * tag, + void (* const setAction)(d_configuration config, c_address addr)); + +void d_configurationValueBoolean (d_configuration configuration, + u_cfElement element, + const char * tag, + void (* const setAction)(d_configuration config, c_bool str)); + +void d_configurationSetOptimizeUpdateInterval (d_configuration config, + c_ulong size); + +void d_configurationReport (d_configuration config, + d_durability durability); + +void d_configurationSetRole (d_configuration config, + const c_char* role); + +void d_configurationSetServiceTerminatePeriod (d_configuration config, + const c_float seconds); + +void d_configurationSetThreadLivelinessReportPeriod (d_configuration config, + const c_float seconds); + +void d_configurationSetDeadlockDetection (d_configuration config, + c_bool deadlockDetection); + +void d_configurationSetY2038Ready (d_configuration config, + const c_char *y2038Ready); + +int d_configurationResolveFilterPartitionTopic (d_filter filter, + u_cfElement elementParent, + const c_char *name, + const c_char *tag); + +c_iter d_configurationResolveDurablePolicies (u_cfElement elementParent, + const c_char * policy); + +c_bool d_configurationCheckFilterInNameSpace (d_configuration config, d_nameSpace nameSpace); + +d_policy d_configurationFindPolicyForNameSpace (d_configuration config, + const char * nameSpaceName); + + +#if defined (__cplusplus) +} +#endif + +#endif /* D__CONFIGURATION_H */ diff --git a/src/services/durability/code/d__conflict.h b/src/services/durability/code/d__conflict.h new file mode 100644 index 000000000..cdfe4c574 --- /dev/null +++ b/src/services/durability/code/d__conflict.h @@ -0,0 +1,107 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef D__CONFLICT_H +#define D__CONFLICT_H + +#include "d__types.h" +#include "d__lock.h" +#include "d_networkAddress.h" +#include "os_time.h" + +#if defined (__cplusplus) +extern "C" { +#endif + +#define D_CONFLICT_NAMESPACE_MASTER (0x0001U << 0) +#define D_CONFLICT_NAMESPACE_NATIVE_STATE (0x0001U << 1) +#define D_CONFLICT_NAMESPACE_FOREIGN_STATE (0x0001U << 2) +#define D_CONFLICT_FELLOW_DISCONNECTED (0x0001U << 4) +#define D_CONFLICT_FELLOW_CONNECTED (0x0001U << 5) +#define D_CONFLICT_FEDERATION_DISCONNECTED (0x0001U << 6) +#define D_CONFLICT_INITIAL (0x0001U << 7) +#define D_CONFLICT_LOCAL_GROUP_COMPLETE (0x0001U << 8) +#define D_CONFLICT_HEARTBEAT_PROCESSED (0x0001U << 9) + +#define IS_MASTER_CONFLICT(conflict) ((conflict->event == D_CONFLICT_NAMESPACE_MASTER)) +#define IS_NATIVE_STATE_CONFLICT(conflict) ((conflict->event == D_CONFLICT_NAMESPACE_NATIVE_STATE)) +#define IS_FOREIGN_STATE_CONFLICT(conflict) ((conflict->event == D_CONFLICT_NAMESPACE_FOREIGN_STATE)) +#define IS_FELLOW_DISCONNECTED_CONFLICT(conflict) ((conflict->event == D_CONFLICT_FELLOW_DISCONNECTED)) +#define IS_FELLOW_CONNECTED_CONFLICT(conflict) ((conflict->event == D_CONFLICT_FELLOW_CONNECTED)) +#define IS_FEDERATION_DISCONNECTED_CONFLICT(conflict) ((conflict->event == D_CONFLICT_FEDERATION_DISCONNECTED)) +#define IS_INITIAL_CONFLICT(conflict) ((conflict->event == D_CONFLICT_INITIAL)) +#define IS_LOCAL_GROUP_COMPLETE_CONFLICT(conflict) ((conflict->event == D_CONFLICT_LOCAL_GROUP_COMPLETE)) +#define IS_HEARTBEAT_PROCESSED_CONFLICT(conflict) ((conflict->event == D_CONFLICT_HEARTBEAT_PROCESSED)) + +#define IS_NAMESPACE_CONFLICT(conflict) (IS_MASTER_CONFLICT(conflict) || IS_NATIVE_STATE_CONFLICT(conflict) || IS_FOREIGN_STATE_CONFLICT(conflict)) + +/** + * Macro that checks the d_conflict validity. + * Because d_conflict is a concrete class typechecking is required. + */ +#define d_conflictIsValid(_this) \ + d_objectIsValid(d_object(_this), D_CONFLICT) + +/** + * \brief The d_conflict cast macro. + * + * This macro casts an object to a d_conflict object. + */ +#define d_conflict(_this) ((d_conflict)(_this)) + +C_STRUCT(d_conflict) { + C_EXTENDS(d_lock); + c_ulong event; /* conflict event */ + c_ulong id; /* unique conflict id */ + c_ulong nr; /* number of actions to solve as part of this conflict */ + c_ulong reQueueCount; /* indicates the number of times the conflict is queued */ + os_timeM creationTime; /* time of conflict creation */ + os_timeM lastQueueTime; /* last time when added to the conflict resolver queue */ + d_networkAddress fellowAddr; /* address of the fellow in conflict */ + d_nameSpace nameSpaceCopy; /* copy of the namespace used when the conflict was determined */ + d_nameSpace fellowNameSpaceCopy; /* copy of the fellow namespace used when the conflict was determined */ + c_iter foreign_stateConflicts; /* List of foreign state conflicts between nameSpaceCopy and fellowNameSpaceCopy */ +}; + +d_conflict d_conflictNew (c_ulong conflictEvent, + d_networkAddress fellowAddr, + d_nameSpace nameSpaceCopy, + d_nameSpace fellowNameSpaceCopy); + +void d_conflictDeinit (d_object object); + +void d_conflictFree (d_conflict conflict); + +c_ulong d_conflictGetId (d_conflict conflict); + +c_ulong d_conflictSetId (d_conflict conflict, + d_durability durability); + +os_timeM d_conflictGetCreationTime (d_conflict conflict); + +void d_conflictUpdate (d_conflict conflict, + d_nameSpace nameSpaceCopy, + d_nameSpace fellowNameSpaceCopy); + +void d_conflictUpdateQueueTime (d_conflict conflict); + +#if defined (__cplusplus) +} +#endif + +#endif /* D__CONFLICT_H */ diff --git a/src/services/durability/code/d__conflictMonitor.h b/src/services/durability/code/d__conflictMonitor.h new file mode 100644 index 000000000..eab05c79d --- /dev/null +++ b/src/services/durability/code/d__conflictMonitor.h @@ -0,0 +1,80 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef D__CONFLICT_MONITOR_H +#define D__CONFLICT_MONITOR_H + +#include "d__types.h" +#include "d__conflict.h" +#include "d__admin.h" +#include "os_time.h" + +#if defined (__cplusplus) +extern "C" { +#endif + +/** + * Macro that checks the d_conflictMonitor validity. + * Because d_conflictMonitor is a concrete class typechecking is required. + */ +#define d_conflictMonitorIsValid(_this) \ + d_objectIsValid(d_object(_this), D_CONFLICT_MONITOR) + +/** + * \brief The d_conflictMonitor cast macro. + * + * This macro casts an object to a d_conflictMonitor object. + */ +#define d_conflictMonitor(_this) ((d_conflictMonitor)(_this)) + +C_STRUCT(d_conflictMonitor) { + C_EXTENDS(d_lock); + os_timeM lastTimeChecked; + d_admin admin; +}; + + +d_conflictMonitor d_conflictMonitorNew (d_admin admin); + +void d_conflictMonitorDeinit (d_conflictMonitor conflictMonitor); + +void d_conflictMonitorFree (d_conflictMonitor conflictMonitor); + +void d_conflictMonitorCheckForConflicts (d_conflictMonitor conflictMonitor, + d_fellow fellow, + d_nameSpace nameSpace); + +void d_conflictMonitorCheckFellowDisconnected (d_conflictMonitor conflictMonitor, + d_fellow fellow); + +void d_conflictMonitorCheckFellowConnected (d_conflictMonitor conflictMonitor, + d_fellow fellow); + +void d_conflictMonitorCheckFederationDisconnected(d_conflictMonitor conflictMonitor); + +d_conflict d_conflictMonitorEvaluateConflict (d_conflictMonitor conflictMonitor, + d_conflict conflict); + + + + +#if defined (__cplusplus) +} +#endif + +#endif /* D__CONFLICT_MONITOR_H */ diff --git a/src/services/durability/code/d__conflictResolver.h b/src/services/durability/code/d__conflictResolver.h new file mode 100644 index 000000000..1bec6da7c --- /dev/null +++ b/src/services/durability/code/d__conflictResolver.h @@ -0,0 +1,86 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef D__CONFLICT_RESOLVER_H +#define D__CONFLICT_RESOLVER_H + +#include "d__types.h" +#include "d__conflict.h" +#include "d__admin.h" +#include "d__lock.h" +#include "os_time.h" +#include "os_mutex.h" + +#if defined (__cplusplus) +extern "C" { +#endif + +/** + * Macro that checks the d_conflictResolver validity. + * Because d_conflictResolver is a concrete class typechecking is required. + */ +#define d_conflictResolverIsValid(_this) \ + d_objectIsValid(d_object(_this), D_CONFLICT_RESOLVER) + +/** + * \brief The d_conflictResolver cast macro. + * + * This macro casts an object to a d_conflictResolver object. + */ +#define d_conflictResolver(_this) ((d_conflictResolver)(_this)) + +C_STRUCT(d_conflictResolver) { + C_EXTENDS(d_lock); + d_admin admin; + os_threadId actionThread; + os_timeM lastTimeResolved; + os_timeM lastTimeChecked; + c_ulong totalConflicts; + c_bool threadTerminate; + c_ulong conflictInProgress; /* id of the conflict that is currently being resolved, 0 if none */ + d_conflict current_conflict; /* the conflict that is currently handled, NULL if no conflict */ + os_timeM nextReportTime; /* next time to report progress of the initial conflict */ +}; + + +d_conflictResolver d_conflictResolverNew (d_admin admin); + +void d_conflictResolverDeinit (d_object object); + +void d_conflictResolverFree (d_conflictResolver conflictResolver); + +void d_conflictResolverAddConflict (d_conflictResolver conflictResolver, + d_conflict conflict); + +c_bool d_conflictResolverConflictExists (d_conflictResolver conflictResolver, + d_conflict conflict); + +void d_conflictResolverSetConflictInProgress (d_conflictResolver conflictResolver, + d_conflict conflict); + +void d_conflictResolverResetConflictInProgress (d_conflictResolver conflictResolver, + d_conflict conflict); + +c_bool d_conflictResolverHasConflictInProgress (d_conflictResolver conflictResolver); + + +#if defined (__cplusplus) +} +#endif + +#endif /* D__CONFLICT_RESOLVER_H */ diff --git a/src/services/durability/code/d__dcpsHeartbeatListener.h b/src/services/durability/code/d__dcpsHeartbeatListener.h new file mode 100644 index 000000000..66d80bb9e --- /dev/null +++ b/src/services/durability/code/d__dcpsHeartbeatListener.h @@ -0,0 +1,37 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef D__DCPSHEARTBEATLISTENER_H_ +#define D__DCPSHEARTBEATLISTENER_H_ + +#include "d__types.h" + +#if defined (__cplusplus) +extern "C" { +#endif + +d_dcpsHeartbeatListener d_dcpsHeartbeatListenerNew (d_subscriber subscriber); +void d_dcpsHeartbeatListenerFree (d_dcpsHeartbeatListener listener); +c_bool d_dcpsHeartbeatListenerStop (d_dcpsHeartbeatListener listener); +c_bool d_dcpsHeartbeatListenerStart (d_dcpsHeartbeatListener listener); + +#if defined (__cplusplus) +} +#endif + +#endif /* D__DCPSHEARTBEATLISTENER_H_ */ diff --git a/src/services/durability/code/d__dcpsPublicationListener.h b/src/services/durability/code/d__dcpsPublicationListener.h new file mode 100644 index 000000000..e9363a643 --- /dev/null +++ b/src/services/durability/code/d__dcpsPublicationListener.h @@ -0,0 +1,37 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef D__DCPSPUBLICATIONLISTENER_H_ +#define D__DCPSPUBLICATIONLISTENER_H_ + +#include "d__types.h" + +#if defined (__cplusplus) +extern "C" { +#endif + +d_dcpsPublicationListener d_dcpsPublicationListenerNew (d_subscriber subscriber); +void d_dcpsPublicationListenerFree (d_dcpsPublicationListener listener); +c_bool d_dcpsPublicationListenerStop (d_dcpsPublicationListener listener); +c_bool d_dcpsPublicationListenerStart (d_dcpsPublicationListener listener); + +#if defined (__cplusplus) +} +#endif + +#endif /* D__DCPSPUBLICATIONLISTENER_H_ */ diff --git a/src/services/durability/code/d__deleteDataListener.h b/src/services/durability/code/d__deleteDataListener.h new file mode 100644 index 000000000..2b325c611 --- /dev/null +++ b/src/services/durability/code/d__deleteDataListener.h @@ -0,0 +1,36 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#ifndef D__DELETEDATALISTENER_H +#define D__DELETEDATALISTENER_H + +#include "d__types.h" + +#if defined (__cplusplus) +extern "C" { +#endif + +d_deleteDataListener d_deleteDataListenerNew (d_subscriber subscriber); +void d_deleteDataListenerFree (d_deleteDataListener listener); +c_bool d_deleteDataListenerStart (d_deleteDataListener listener); +c_bool d_deleteDataListenerStop (d_deleteDataListener listener); + +#if defined (__cplusplus) +} +#endif + +#endif /* D__DELETEDATALISTENER_H */ diff --git a/src/services/durability/code/d__durability.h b/src/services/durability/code/d__durability.h new file mode 100644 index 000000000..8b7bdff43 --- /dev/null +++ b/src/services/durability/code/d__durability.h @@ -0,0 +1,199 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef D__DURABILITY_H +#define D__DURABILITY_H + +#include "d__types.h" +#include "d__thread.h" +#include "u_user.h" +#include "vortex_os.h" +#include "os_thread.h" +#include "os_time.h" +#include "os_atomics.h" + + +#if defined (__cplusplus) +extern "C" { +#endif + +/* Vendor ids, used for client-durability */ +#define D_VENDORID_UNKNOWN {{ 0x00, 0x00 }} +#define D_VENDORID_RTI {{ 0x01, 0x01 }} +#define D_VENDORID_PRISMTECH_OSPL {{ 0x01, 0x02 }} +#define D_VENDORID_OCI {{ 0x01, 0x03 }} +#define D_VENDORID_MILSOFT {{ 0x01, 0x04 }} +#define D_VENDORID_KONGSBERG {{ 0x01, 0x05 }} +#define D_VENDORID_TWINOAKS {{ 0x01, 0x06 }} +#define D_VENDORID_LAKOTA {{ 0x01, 0x07 }} +#define D_VENDORID_ICOUP {{ 0x01, 0x08 }} +#define D_VENDORID_ETRI {{ 0x01, 0x09 }} +#define D_VENDORID_RTI_MICRO {{ 0x01, 0x0a }} +#define D_VENDORID_PRISMTECH_JAVA {{ 0x01, 0x0b }} +#define D_VENDORID_PRISMTECH_GATEWAY {{ 0x01, 0x0c }} +#define D_VENDORID_PRISMTECH_LITE {{ 0x01, 0x0d }} +#define D_VENDORID_TECHNICOLOR {{ 0x01, 0x0e }} +#define D_VENDORID_EPROSIMA {{ 0x01, 0x0f }} +#define D_VENDORID_PRISMTECH_CLOUD {{ 0x01, 0x20 }} + +#define MY_VENDOR_ID D_VENDORID_PRISMTECH_OSPL + +/* Durability version */ +#define D_DURABILITY_VERSION_MAJOR 2 +#define D_DURABILITY_VERSION_MINOR 0 /* From version 2.0 timestamps beyond 2038 are supported */ +#define D_DURABILITY_VERSION_VENDOR_ID MY_VENDOR_ID + +/** + * Macro that checks the d_durability validity. + * Because d_durability is a concrete class typechecking is required. + */ +#define d_durabilityIsValid(_this) \ + d_objectIsValid(d_object(_this), D_DURABILITY) + +/** + * \brief The d_durability cast macro. + * + * This macro casts an object to a d_durability object. + */ +#define d_durability(_this) ((d_durability)(_this)) + +typedef void (*d_durabilityStatisticsCallback)(v_durabilityStatistics statistics, c_voidp userData); + +C_STRUCT(d_durability){ + C_EXTENDS(d_object); + u_service service; + u_serviceManager serviceManager; + d_configuration configuration; + d_admin admin; + d_serviceState state; + os_threadId statusThread; + volatile c_bool splicedRunning; + os_cond terminateCondition; + os_mutex terminateMutex; + c_bool died; /* set to TRUE if something bad happened, + * used in d_durabilityDeinit to annnounce + * the service has died + */ + struct _DDS_DurabilityVersion_t myVersion; + struct _DDS_Gid_t myServerId; + pa_uint32_t requestId; /* atomic id to handout to new requests */ + pa_uint32_t conflictId; /* monotonic conflict-id counter */ + pa_uint32_t incarnation; /* incarnation used to detect asymmetric disconnects */ + pa_uint32_t forceStatusWrite; +}; + +typedef enum d_connectivity_s { + D_CONNECTIVITY_UNDETERMINED, + D_CONNECTIVITY_OK, + D_CONNECTIVITY_INCOMPATIBLE_STATE, + D_CONNECTIVITY_INCOMPATIBLE_DATA_MODEL +} d_connectivity; + +#define D_OSPL_NODE "__NODE" +#define D_OSPL_BUILTIN_PARTITION "BUILT-IN PARTITION__" + +d_durability d_durabilityNew (const c_char* uri, + const c_char* serviceName, + c_long domainId); + +void d_durabilityInit (d_durability durability); + +void d_durabilityDeinit (d_durability durability); + +d_connectivity d_durabilityDetermineConnectivity (d_durability durability); + +void d_durabilityHandlePersistentInitial (d_durability durability); + +void d_durabilityHandleInitialAlignment (d_durability durability); + +void d_durabilityFree (d_durability durability); + +c_bool d_durabilityArgumentsProcessing (int argc, + char *argv[], + c_char **uri, + c_char **serviceName); + +void d_durabilityWatchSpliceDaemon (v_serviceStateKind spliceDaemonState, + c_voidp usrData); + +void d_durabilityLoadModule (v_public entity, + c_voidp args); + +u_service d_durabilityGetService (d_durability durability); + +d_configuration d_durabilityGetConfiguration (d_durability durability); + +c_bool d_durabilityWaitForAttachToGroup (d_durability durability, + v_group group); + +d_serviceState d_durabilityGetState (d_durability durability); + +void d_durabilitySetState (d_durability durability, + d_serviceState state); + +void d_durabilityHeartbeatProcessed (_In_ d_durability durability); + +c_bool d_durabilityMustTerminate (d_durability durability); + +void d_durabilityTerminate (d_durability durability, + c_bool died); + +void d_durabilityUpdateStatistics (d_durability durability, + d_durabilityStatisticsCallback callback, + c_voidp userData); + +u_result d_durabilityTakePersistentSnapshot (d_durability durability, + c_char* partitionExpr, + c_char* topicExpr, + c_char* uri); + +void d_durabilitySetVersion (d_durability durability, + c_ushort major, + c_ushort minor); + +struct _DDS_DurabilityVersion_t d_durabilityGetMyVersion (d_durability durability); + +struct _DDS_Gid_t d_durabilityGetMyServerId (d_durability durability); + +c_bool d_durabilityRequestIsForMe (d_durability durability, + c_iter serverIds, + c_bool *forMe, + c_bool *forEverybody); + +struct _DDS_RequestId_t d_durabilityGetRequestId (d_durability durability); + +c_ulong d_durabilityGenerateConflictId (_Inout_ d_durability durability); + +d_fellow d_durabilityGetOrCreateFellowFromMessage(d_admin admin, + d_networkAddress fellowAddr, + d_message message); + +c_ulong d_durabilityGetNewIncarnation (d_durability durability); + +void d_durabilityDetermineNameSpaceCompleteness ( + d_durability durability); + +void d_durabilityDoInitialMerge (d_durability durability); + +void d_durabilityReportKernelGroupCompleteness (_In_ d_durability durability); + +#if defined (__cplusplus) +} +#endif + +#endif /* D__DURABILITY_H */ diff --git a/src/services/durability/code/d__durabilityState.h b/src/services/durability/code/d__durabilityState.h new file mode 100644 index 000000000..fbf614e09 --- /dev/null +++ b/src/services/durability/code/d__durabilityState.h @@ -0,0 +1,68 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef D__DURABILITY_STATE_H +#define D__DURABILITY_STATE_H + +#include "d__types.h" +#include "d__admin.h" +#include "d__durabilityStateRequest.h" +#include "client_durabilitySplType.h" + +#if defined (__cplusplus) +extern "C" { +#endif + +/** + * Macro that checks the d_durabilityState validity. + * Because d_durabilityState is a concrete class typechecking is required. + */ +#define d_durabilityStateIsValid(_this) \ + d_objectIsValid(d_object(_this), D_DURABILITY_STATE) + + +/** + * \brief The d_durabilityState cast macro. + * + * This macro casts an object to a d_durabilityState object. + */ +#define d_durabilityState(s) ((d_durabilityState)(s)) + + +C_STRUCT(d_durabilityState) { + C_EXTENDS(d_object); + struct _DDS_DurabilityVersion_t version; + struct _DDS_Gid_t serverId; + c_iter requestIds; + c_iter dataState; + c_iter extensions; + d_durabilityStateRequest request; /* The request to respond to */ +}; + + +d_durabilityState d_durabilityStateNew (d_admin admin); + +void d_durabilityStateDeinit (d_durabilityState durabilityState); + +void d_durabilityStateFree (d_durabilityState durabilityState); + +#if defined (__cplusplus) +} +#endif + +#endif /* D__DURABILITY_STATE_H */ diff --git a/src/services/durability/code/d__durabilityStateRequest.h b/src/services/durability/code/d__durabilityStateRequest.h new file mode 100644 index 000000000..73d17242a --- /dev/null +++ b/src/services/durability/code/d__durabilityStateRequest.h @@ -0,0 +1,80 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef D__DURABILITY_STATE_REQUEST_H +#define D__DURABILITY_STATE_REQUEST_H + +#include "d__types.h" +#include "d__admin.h" +#include "client_durabilitySplType.h" + +#if defined (__cplusplus) +extern "C" { +#endif + +/** + * Macro that checks the d_durabilityStateRequest validity. + * Because d_durabilityStateRequest is a concrete class typechecking is required. + */ +#define d_durabilityStateRequestIsValid(_this) \ + d_objectIsValid(d_object(_this), D_DURABILITY_STATE_REQ) + + +/** + * \brief The d_durabilityStateRequest cast macro. + * + * This macro casts an object to a d_durabilityStateRequest object. + */ +#define d_durabilityStateRequest(s) ((d_durabilityStateRequest)(s)) + + +C_STRUCT(d_durabilityStateRequest) { + C_EXTENDS(d_object); + struct _DDS_DurabilityStateRequest *request; + struct _DDS_DurabilityVersion_t version; + struct _DDS_RequestId_t requestId; + char *topic; + c_iter partitions; + c_iter serverIds; + c_time timeout; + c_iter extensions; + c_bool forMe; + c_bool forEverybody; +}; + + +d_durabilityStateRequest d_durabilityStateRequestNew (d_admin admin, + struct _DDS_DurabilityVersion_t version, + struct _DDS_RequestId_t requestId, + d_topic topic, + c_iter partitions, + c_iter serverIds, + c_time timeout, + c_iter extensions); + +void d_durabilityStateRequestDeinit (d_durabilityStateRequest durabilityStateRequest); + +void d_durabilityStateRequestFree (d_durabilityStateRequest durabilityStateRequest); + +c_ulong d_durabilityStateRequestSanityCheck (d_durabilityStateRequest durabilityStateRequest); + +#if defined (__cplusplus) +} +#endif + +#endif /* D__DURABILITY_STATE_REQUEST_H */ diff --git a/src/services/durability/code/d__durabilityStateRequestListener.h b/src/services/durability/code/d__durabilityStateRequestListener.h new file mode 100644 index 000000000..db91d9e53 --- /dev/null +++ b/src/services/durability/code/d__durabilityStateRequestListener.h @@ -0,0 +1,39 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef D__DURABILITY_STATE_REQUEST_LISTENER_H +#define D__DURABILITY_STATE_REQUEST_LISTENER_H + +#include "d__types.h" + +#if defined (__cplusplus) +extern "C" { +#endif + +d_durabilityStateRequestListener d_durabilityStateRequestListenerNew (d_subscriber subscriber); +void d_durabilityStateRequestListenerFree (d_durabilityStateRequestListener listener); +c_bool d_durabilityStateRequestListenerStart (d_durabilityStateRequestListener listener); +c_bool d_durabilityStateRequestListenerStop (d_durabilityStateRequestListener listener); +void d_durabilityStateRequestListenerAddRequest (d_durabilityStateRequestListener listener, + d_durabilityStateRequest request); + +#if defined (__cplusplus) +} +#endif + +#endif /* D__DURABILITY_STATE_REQUEST_LISTENER_H */ diff --git a/src/services/durability/code/d__element.h b/src/services/durability/code/d__element.h new file mode 100644 index 000000000..135b65144 --- /dev/null +++ b/src/services/durability/code/d__element.h @@ -0,0 +1,66 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef D__ELEMENT_H +#define D__ELEMENT_H + +#include "d__types.h" + +#if defined (__cplusplus) +extern "C" { +#endif + +/** + * \brief The d_element cast macro. + * + * This macro casts an object to a d_element object. + */ +#define d_element(_this) ((d_element)(_this)) + +/** + * The class d_element is used in the definition + * of namespaces (sets of partition/topics) and + * filters. In both partition and topic a '*' + * matches for any number of characters and a '?' + * matches one character. + */ +C_STRUCT(d_element) { + d_partition partition; /**< partition name */ + d_topic topic; /**< topic name */ + d_name name; /**< element name */ + os_uint32 strlenPartition; /**< partition name's length */ + os_uint32 strlenTopic; /**< topic name's length */ + os_uint32 strlenName; /**< name's length */ +}; + +d_element d_elementNew (const char *name, + const char *partition, + const char *topic); + +void d_elementFree (d_element element); + +d_name d_elementGetExpression (d_element element); + +int d_elementCompare (c_voidp object1, + c_voidp object2); + +#if defined (__cplusplus) +} +#endif + +#endif /* D__ELEMENT_H */ diff --git a/src/services/durability/code/d__eventListener.h b/src/services/durability/code/d__eventListener.h new file mode 100644 index 000000000..7fc80b636 --- /dev/null +++ b/src/services/durability/code/d__eventListener.h @@ -0,0 +1,81 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef D__EVENTLISTENER_H +#define D__EVENTLISTENER_H + +#include "d__types.h" +#include "d__listener.h" + +#if defined (__cplusplus) +extern "C" { +#endif + +#define D_NONE (0) +#define D_GROUP_LOCAL_NEW (0x0001U << 0) +#define D_FELLOW_NEW (0x0001U << 1) +#define D_FELLOW_REMOVED (0x0001U << 2) +#define D_FELLOW_LOST (0x0001U << 3) +#define D_NAMESPACE_NEW (0x0001U << 4) +#define D_NAMESPACE_STATE_CONFLICT (0x0001U << 5) +#define D_NAMESPACE_MASTER_CONFLICT (0x0001U << 6) +#define D_NAMESPACE_DELAYED_INITIAL (0x0001U << 7) +#define D_GROUP_LOCAL_COMPLETE (0x0001U << 8) +/** + * Macro that checks the d_eventListener validity. + * Because d_eventListener is a concrete class typechecking is required. + */ +#define d_eventListenerIsValid(_this) \ + d_objectIsValid(d_object(_this), D_EVENT_LISTENER) + +/** + * \brief The d_eventListener cast macro. + * + * This macro casts an object to a d_eventListener object. + */ +#define d_eventListener(_this) ((d_eventListener)(_this)) + +typedef c_bool (*d_eventListenerFunc) (c_ulong event, + d_fellow fellow, + d_nameSpace nameSpace, + d_group group, + c_voidp userData, + c_voidp args); + +C_STRUCT(d_eventListener){ + C_EXTENDS(d_object); + c_ulong interest; + d_eventListenerFunc func; + c_voidp args; +}; + +d_eventListener d_eventListenerNew (c_ulong interest, + d_eventListenerFunc func, + c_voidp args); + +c_voidp d_eventListenerGetUserData (d_eventListener listener); + +void d_eventListenerFree (d_eventListener listener); + +void d_eventListenerDeinit (d_eventListener listener); + +#if defined (__cplusplus) +} +#endif + +#endif /* D__EVENTLISTENER_H */ diff --git a/src/services/durability/code/d__fellow.h b/src/services/durability/code/d__fellow.h new file mode 100644 index 000000000..04cdf3c14 --- /dev/null +++ b/src/services/durability/code/d__fellow.h @@ -0,0 +1,297 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#ifndef D__FELLOW_H +#define D__FELLOW_H + +#include "d__types.h" +#include "d__lock.h" +#include "d__table.h" +#include "os_mutex.h" +#include "os_time.h" + +#if defined (__cplusplus) +extern "C" { +#endif + +/* Durability reader flags. + * These flags can be used to determine what functionality is + * offered by a fellow + */ +#define D_NAMESPACES_READER_FLAG (0x0001U << 0) /* 1 */ +#define D_NAMESPACESREQUEST_READER_FLAG (0x0001U << 1) /* 2 */ +#define D_STATUS_READER_FLAG (0x0001U << 2) /* 4 */ +#define D_GROUPSREQUEST_READER_FLAG (0x0001U << 3) /* 8 */ +#define D_DELETEDATA_READER_FLAG (0x0001U << 4) /* 16 */ +#define D_NEWGROUP_READER_FLAG (0x0001U << 5) /* 32 */ +#define D_SAMPLREQUEST_READER_FLAG (0x0001U << 6) /* 64 */ +#define D_SAMPLECHAIN_READER_FLAG (0x0001U << 7) /* 128 */ +#define D_CAPABILITY_READER_FLAG (0x0001U << 8) /* 256 */ + +#define D_BASIC_DURABILITY_READER_FLAGS \ + D_NAMESPACES_READER_FLAG | D_NAMESPACESREQUEST_READER_FLAG | D_STATUS_READER_FLAG | \ + D_GROUPSREQUEST_READER_FLAG | D_DELETEDATA_READER_FLAG | D_NEWGROUP_READER_FLAG | \ + D_SAMPLREQUEST_READER_FLAG | D_SAMPLECHAIN_READER_FLAG + +typedef enum d_communicationState_s { + D_COMMUNICATION_STATE_UNKNOWN = 0, + D_COMMUNICATION_STATE_APPROVED = 1, + D_COMMUNICATION_STATE_INCOMPATIBLE_STATE = 2, + D_COMMUNICATION_STATE_INCOMPATIBLE_DATA_MODEL = 3, + D_COMMUNICATION_STATE_TERMINATED = 4 +} d_communicationState; + +/* Translate fellow state to text */ +extern char* d_fellowState_text[]; +#define d_fellowStateText(state) d_fellowState_text[state] + +typedef enum d_fellowAlignStatus_s { + D_ALIGN_FALSE, + D_ALIGN_TRUE, + D_ALIGN_UNKNOWN +} d_fellowAlignStatus; + + +/** + * Macro that checks the d_fellow validity. + * Because d_fellow is a concrete class typechecking is required. + */ +#define d_fellowIsValid(_this) \ + d_objectIsValid(d_object(_this), D_FELLOW) + +/** + * \brief The d_fellow cast macro. + * + * This macro casts an object to a d_fellow object. + */ +#define d_fellow(_this) ((d_fellow)(_this)) + +/** + * Descriptor to hold all capabilities of the fellow. + */ +struct capabilityDescriptor { + c_bool groupHash; + c_bool EOTSupport; + c_bool Y2038Ready; + c_ulong masterSelection; + c_ulong incarnation; +}; + +C_STRUCT(d_fellow){ + C_EXTENDS(d_lock); + d_networkAddress address; + d_serviceState state; + d_communicationState communicationState; + d_name role; + os_timeM lastStatusReport; + os_uint32 lastSeqNum; + d_table groups; + d_table nameSpaces; + c_ulong requestCount; + c_long expectedGroupCount; + c_ulong expectedNameSpaces; + c_bool groupsRequested; /* Indicates whether I have requested groups from the fellow */ + c_bool isConfirmed; /* TRUE if this fellow is confirmed, FALSE otherwise. */ + c_bool hasConfirmed; /* TRUE if this fellow has become confirmed but no nameSpaces have been requested yet from this fellow. */ + c_bool recentlyTerminated; /* Indicates if the message that this fellow has recently terminated has been printed or not. */ + os_timeM removalTime; /* Time (monotonic) when the fellow is removed */ + c_bool capabilitySupport; /* Indicates if the fellow supports the capability interface or not */ + c_long heartbeatDisposeCount; + c_ulong readers; /* Bit pattern to indicate which durability readers are discovered of the fellow */ + c_ulong requiredReaders; /* Bit pattern to indicate which durability readers MUST BE discovered before the fellow is considered responsive */ + c_bool recently_joined; /* Indicator if the fellow has recently joined */ + c_bool responsive; /* Indicates if a namespacerequest has been sent to the fellow */ + c_bool has_requested_namespaces; /* Indicates if the fellow has requested namespaces from me */ + struct capabilityDescriptor capabilities; /* Indicates the capabilities received from this fellow */ + c_ulong incarnation; /* The incarnation that I advertise to my fellow */ +}; + +d_fellow d_fellowNew (d_networkAddress address, + d_serviceState state, + c_bool isConfirmed); + +void d_fellowDeinit (d_fellow fellow); + +void d_fellowFree (d_fellow fellow); + +d_serviceState d_fellowGetState (d_fellow fellow); + +void d_fellowUpdateStatus (d_fellow fellow, + d_serviceState state, + os_uint32 seqnum); + +c_bool d_fellowAddGroup (d_fellow fellow, + d_group group); + +d_group d_fellowGetGroup (d_fellow fellow, + const c_char* partition, + const c_char* topic, + d_durabilityKind kind); + +d_group d_fellowRemoveGroup (d_fellow fellow, + d_group group); + +int d_fellowCompare (d_fellow fellow1, + d_fellow fellow2); + +c_bool d_fellowGroupWalk (d_fellow fellow, + c_bool ( * action ) ( + d_group group, + c_voidp userData), + c_voidp userData); + +os_timeM d_fellowGetLastStatusReport (d_fellow fellow); + +d_networkAddress d_fellowGetAddress (d_fellow fellow); + +void d_fellowSetAddress (d_fellow fellow, + d_networkAddress address); + +d_communicationState d_fellowGetCommunicationState (d_fellow fellow); + +void d_fellowSetCommunicationState (d_fellow fellow, + d_communicationState state); + +c_bool d_fellowSetGroupsRequested (d_fellow fellow); + +c_bool d_fellowGetGroupsRequested (d_fellow fellow); + +c_bool d_fellowAddNameSpace (d_fellow fellow, + d_nameSpace nameSpace); + +c_bool d_fellowAreNameSpacesComplete (d_fellow fellow); + +c_ulong d_fellowNameSpaceCount (d_fellow fellow); + +c_bool d_fellowNameSpaceWalk (d_fellow fellow, + c_bool ( * action ) ( + d_nameSpace nameSpace, + c_voidp userData), + c_voidp userData); + +d_nameSpace d_fellowGetNameSpace (d_fellow fellow, + d_nameSpace template); + +void d_fellowRequestAdd (d_fellow fellow); + +void d_fellowRequestRemove (d_fellow fellow); + +c_ulong d_fellowRequestCountGet (d_fellow fellow); + +void d_fellowRequestCountSet (d_fellow fellow, + c_ulong count); + +void d_fellowSetExpectedGroupCount (d_fellow fellow, + c_long count); + +c_long d_fellowGetExpectedGroupCount (d_fellow fellow); + +void d_fellowSetExpectedNameSpaces (d_fellow fellow, + c_ulong count); + +c_ulong d_fellowGetExpectedNameSpaces (d_fellow fellow); + +c_ulong d_fellowGetGroupCount (d_fellow fellow); + +c_bool d_fellowIsCompleteForGroup (d_fellow fellow, + const c_char* partition, + const c_char* topic, + d_durabilityKind kind); + +d_fellowAlignStatus d_fellowIsAlignerForGroup (d_fellow fellow, + const c_char* partition, + const c_char* topic, + d_durabilityKind kind, + c_ulong *masterPriority); + +d_fellowAlignStatus d_fellowIsAlignerForNameSpace (d_fellow fellow, + d_nameSpace nameSpace); + +c_bool d_fellowIsGroupInNameSpaces (d_fellow fellow, + const c_char* partition, + const c_char* topic, + d_durabilityKind kind); + +c_bool d_fellowHasGroup (d_fellow fellow, + const c_char* partition, + const c_char* topic, + d_durabilityKind kind); + +void d_fellowClearMaster (d_fellow fellow, + d_networkAddress master); + +void d_fellowSetRole (d_fellow fellow, + d_name role); + +d_name d_fellowGetRole (d_fellow fellow); + +c_bool d_fellowIsConfirmed (d_fellow fellow); + +void d_fellowSetConfirmed (d_fellow fellow, + c_bool confirmed); + +c_bool d_fellowHasConfirmed (d_fellow fellow); + + +c_bool d_fellowHasRecentlyTerminated (d_fellow fellow); + +c_long d_fellowSetLastDisposeCount (d_fellow fellow, + c_long disposeCount); + +c_long d_fellowGetLastDisposeCount (d_fellow fellow); + +void d_fellowSetCapabilitySupport (d_fellow fellow, + c_bool capabilitySupport); + +c_bool d_fellowHasCapabilitySupport (d_fellow fellow); + +c_bool d_fellowIsResponsive (d_fellow fellow, + c_bool waitForRemoteReaders); + +void d_fellowAddReader (d_fellow fellow, + c_ulong reader); + +void d_fellowRemoveReader (d_fellow fellow, + c_ulong reader); + +c_bool d_fellowHasDiscoveredReaders (d_fellow fellow, + c_ulong mask, + c_bool waitForRemoteReaders); + +void d_fellowSetCapability (d_fellow fellow, + d_capability capability); + +c_bool d_fellowHasCapabilityGroupHash (d_fellow fellow); + +c_bool d_fellowHasCapabilityEOTSupport (d_fellow fellow); + +c_bool d_fellowHasCapabilityY2038Ready (d_fellow fellow); + +void d_fellowSendNSRequest (d_fellow fellow); + +void d_fellowCheckSendCapabilities (d_fellow fellow, c_bool initial); + +os_uint32 d_fellowGetLastSeqNum (d_fellow fellow); +c_bool d_fellowHasRecentlyJoined (d_fellow fellow); + +void d_fellowCheckInitialResponsiveness(d_fellow fellow); + +#if defined (__cplusplus) +} +#endif + +#endif /* D__FELLOW_H */ diff --git a/src/services/durability/code/d__filter.h b/src/services/durability/code/d__filter.h new file mode 100644 index 000000000..711992f35 --- /dev/null +++ b/src/services/durability/code/d__filter.h @@ -0,0 +1,69 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef D__FILTER_H +#define D__FILTER_H + +#include "d__types.h" + +#if defined (__cplusplus) +extern "C" { +#endif + +/** + * Macro that checks the d_filter validity. + * Because d_filter is a concrete class typechecking is required. + */ +#define d_filterIsValid(_this) \ + d_objectIsValid(d_object(_this), D_FILTER) + +/** + * \brief The d_filter cast macro. + * + * This macro casts an object to a d_filter object. + */ +#define d_filter(_this) ((d_filter)(_this)) + +C_STRUCT(d_filter) { + C_EXTENDS(d_object); + c_char *xmlExpression; /* The xml expression associated with this filter */ + c_char *sqlExpression; /* The sql expression associated with this filter. + * This is not necessarily equal to the xml expression + * because the expression may contain <, > etc. + * but the sqlExpression may not. + */ + c_iter elements; /* The and elements of this filter */ +}; + + +d_filter d_filterNew (const char* xmlExpression); + +void d_filterDeinit (d_filter filter); + +void d_filterFree (d_filter filter); + +c_bool d_filterAddElement (d_filter filter, + const char *name, + const char *partitionTopic, + const char *topicGiven); + +#if defined (__cplusplus) +} +#endif + +#endif /* D__FILTER_H */ diff --git a/src/services/durability/code/d__group.h b/src/services/durability/code/d__group.h new file mode 100644 index 000000000..9a4862ac9 --- /dev/null +++ b/src/services/durability/code/d__group.h @@ -0,0 +1,138 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef D__GROUP_H +#define D__GROUP_H + +#include "d__types.h" +#include "d__admin.h" +#include "d__misc.h" +#include "v_group.h" + +#if defined (__cplusplus) +extern "C" { +#endif + +#define D_BITSPERBYTE (8) +#define D_BITS(type) (D_BITSPERBYTE * (os_int32)sizeof (type)) +#if defined(__STDC__) +#define D_HIBITL (1UL << (D_BITS(os_int32) - 1)) +#else +#define D_HIBITL (1L << (D_BITS(os_int32) - 1)) +#endif + +/** + * Macro that checks the d_group validity. + * Because d_group is a concrete class typechecking is required. + */ +#define d_groupIsValid(_this) \ + d_objectIsValid(d_object(_this), D_GROUP) + +/** + * \brief The d_group cast macro. + * + * This macro casts an object to a d_group object. + */ +#define d_group(_this) ((d_group)(_this)) + +C_STRUCT(d_group) { + C_EXTENDS(d_object); + d_topic topic; + d_partition partition; + d_durabilityKind kind; + d_completeness completeness; + d_quality quality; + v_group vgroup; + c_ulong storeCount; + c_bool private; + c_ulong creationRetryCount; /* number of tries to create a local group, used in the d_groupCreationQueueRun() */ + c_bool storeMessagesLoaded; +}; + +d_group d_groupNew (const c_char* partition, + const c_char* topic, + d_durabilityKind kind, + d_completeness completeness, + d_quality quality); + +void d_groupDeinit (d_group group); + +void d_groupFree (d_group group); + +int d_groupCompare (d_group group1, + d_group group2); + +d_completeness d_groupGetCompleteness (d_group group); + +d_partition d_groupGetPartition (d_group group); + +d_topic d_groupGetTopic (d_group group); + +d_durabilityKind d_groupGetKind (d_group group); + +d_quality d_groupGetQuality (d_group group); + +void d_groupUpdate (d_group group, + d_completeness completeness, + d_quality quality, + d_admin admin); + +void d_groupSetKernelGroup (d_group group, + v_group vgroup); + +void d_groupSetKernelGroupCompleteness( + _In_ d_group group, + _In_ c_bool complete); + +void d_groupSetKernelGroupNoInterest( + _In_ d_group group); + +v_group d_groupGetKernelGroup (d_group group); + +c_bool d_groupIsBuiltinGroup (d_group group); + +void d_groupSetComplete (d_group group, + d_admin admin); + +void d_groupSetNoInterest (d_group group, + d_admin admin); + +void d_groupSetUnaligned (d_group group, + d_admin admin); + +void d_groupSetIncomplete (d_group group, + d_admin admin); + +void d_groupSetPrivate (d_group group, + c_bool isPrivate); + +c_bool d_groupIsPrivate (d_group group); + +void d_groupPublishStateUpdate (d_group group, + d_admin admin); + +void d_groupSetStoreMessagesLoaded(d_group group, + c_bool isLoaded); + +c_bool d_groupIsStoreMessagesLoaded(d_group group); + +#if defined (__cplusplus) +} +#endif + +#endif /* D__GROUP_H */ diff --git a/src/services/durability/code/d__groupCreationQueue.h b/src/services/durability/code/d__groupCreationQueue.h new file mode 100644 index 000000000..ac79db3ed --- /dev/null +++ b/src/services/durability/code/d__groupCreationQueue.h @@ -0,0 +1,68 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#ifndef D__GROUPCREATIONQUEUE_H +#define D__GROUPCREATIONQUEUE_H + +#include "d__types.h" +#include "d__lock.h" + +#if defined (__cplusplus) +extern "C" { +#endif + +/** + * Macro that checks the d_groupCreationQueue validity. + * Because d_groupCreationQueue is a concrete class typechecking is required. + */ +#define d_groupCreationQueueIsValid(_this) \ + d_objectIsValid(d_object(_this), D_GROUP_CREATION_QUEUE) + +/** + * \brief The d_groupCreationQueue cast macro. + * + * This macro casts an object to a d_groupCreationQueue object. + */ +#define d_groupCreationQueue(_this) ((d_groupCreationQueue)(_this)) + +C_STRUCT(d_groupCreationQueue) { + C_EXTENDS(d_lock); + os_threadId actionThread; + c_bool terminate; + c_iter groups; + d_admin admin; + c_ulong groupsToCreateVolatile; + c_ulong groupsToCreateTransient; + c_ulong groupsToCreatePersistent; +}; + +d_groupCreationQueue d_groupCreationQueueNew (d_admin admin); + +void d_groupCreationQueueDeinit (d_groupCreationQueue queue); + +void d_groupCreationQueueFree (d_groupCreationQueue queue); + +c_bool d_groupCreationQueueAdd (d_groupCreationQueue queue, + d_group group); + +c_bool d_groupCreationQueueIsEmpty (d_groupCreationQueue queue); + +#if defined (__cplusplus) +} +#endif + +#endif /* D__GROUPCREATIONQUEUE_H */ diff --git a/src/services/durability/code/d__groupHash.h b/src/services/durability/code/d__groupHash.h new file mode 100644 index 000000000..d11db0f4f --- /dev/null +++ b/src/services/durability/code/d__groupHash.h @@ -0,0 +1,47 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#ifndef D__GROUPHASH_H +#define D__GROUPHASH_H + +#include "c_typebase.h" +#include "c_iterator.h" + +#if defined (__cplusplus) +extern "C" { +#endif + +struct d_groupHash { + c_octet flags; + c_ulong nrSamples; + c_octet hash[16]; +}; + +void d_groupHashCalculate (struct d_groupHash *groupHash, const c_iter list); + +c_char* d_groupHashToString (struct d_groupHash *groupHash); + +c_bool d_groupHashFromString (struct d_groupHash *groupHash, c_char *hashString); + +c_bool d_groupHashIsEqual (struct d_groupHash *groupHash1, struct d_groupHash *groupHash2); + + +#if defined (__cplusplus) +} +#endif + +#endif /* D__GROUPHASH_H */ diff --git a/src/services/durability/code/d__groupLocalListener.h b/src/services/durability/code/d__groupLocalListener.h new file mode 100644 index 000000000..a3726446e --- /dev/null +++ b/src/services/durability/code/d__groupLocalListener.h @@ -0,0 +1,53 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#ifndef D__GROUPLOCALLISTENER_H +#define D__GROUPLOCALLISTENER_H + +#include "d__types.h" +#include "d__listener.h" + +#if defined (__cplusplus) +extern "C" { +#endif + +d_groupLocalListener d_groupLocalListenerNew (d_subscriber subscriber); + +void d_groupLocalListenerFree (d_groupLocalListener listener); + +c_bool d_groupLocalListenerStart (d_groupLocalListener listener); + +c_bool d_groupLocalListenerStop (d_groupLocalListener listener); + +void d_groupLocalListenerHandleAlignment (d_groupLocalListener listener, + d_group dgroup, + d_readerRequest request); + +void d_groupLocalListenerDetermineNewMasters(d_groupLocalListener listener, + c_iter nameSpaces); + +void handleMergeAlignment (d_groupLocalListener listener, + d_conflict conflict, + d_nameSpace fellowNameSpace, + c_iter fellows, + d_mergeState newState); + +#if defined (__cplusplus) +} +#endif + +#endif /* D__GROUPLOCALLISTENER_H */ diff --git a/src/services/durability/code/d__groupRemoteListener.h b/src/services/durability/code/d__groupRemoteListener.h new file mode 100644 index 000000000..b2173b35c --- /dev/null +++ b/src/services/durability/code/d__groupRemoteListener.h @@ -0,0 +1,38 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef D__GROUPREMOTELISTENER_H +#define D__GROUPREMOTELISTENER_H + +#include "d__types.h" + +#if defined (__cplusplus) +extern "C" { +#endif + +d_groupRemoteListener d_groupRemoteListenerNew (d_subscriber subscriber); +void d_groupRemoteListenerFree (d_groupRemoteListener listener); +c_bool d_groupRemoteListenerStart (d_groupRemoteListener listener); +c_bool d_groupRemoteListenerStop (d_groupRemoteListener listener); +c_bool d_groupRemoteListenerAreRemoteGroupsHandled (d_groupRemoteListener listener); + +#if defined (__cplusplus) +} +#endif + +#endif /* D__GROUPREMOTELISTENER_H */ diff --git a/src/services/durability/code/d__groupsRequestListener.h b/src/services/durability/code/d__groupsRequestListener.h new file mode 100644 index 000000000..2c2ea40e4 --- /dev/null +++ b/src/services/durability/code/d__groupsRequestListener.h @@ -0,0 +1,41 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef D__GROUPSREQUESTLISTENER_H +#define D__GROUPSREQUESTLISTENER_H + +#include "d__types.h" +#include "d__readerListener.h" + +#if defined (__cplusplus) +extern "C" { +#endif + +d_groupsRequestListener d_groupsRequestListenerNew (d_subscriber subscriber); + +void d_groupsRequestListenerFree (d_groupsRequestListener listener); + +c_bool d_groupsRequestListenerStart (d_groupsRequestListener listener); + +c_bool d_groupsRequestListenerStop (d_groupsRequestListener listener); + +#if defined (__cplusplus) +} +#endif + +#endif /* D__GROUPREQUESTLISTENER_H */ diff --git a/src/services/durability/code/d__historicalData.h b/src/services/durability/code/d__historicalData.h new file mode 100644 index 000000000..2b758884a --- /dev/null +++ b/src/services/durability/code/d__historicalData.h @@ -0,0 +1,100 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef D__HISTORICAL_DATA_H +#define D__HISTORICAL_DATA_H + +#include "d__types.h" +#include "d__admin.h" +#include "d__historicalDataRequestListener.h" +#include "d__historicalDataRequest.h" +#include "client_durabilitySplType.h" + +#if defined (__cplusplus) +extern "C" { +#endif + +/** + * Macro that checks the d_historicalData validity. + * Because d_historicalData is a concrete class typechecking is required. + */ +#define d_historicalDataIsValid(_this) \ + d_objectIsValid(d_object(_this), D_HISTORICAL_DATA) + + +/** + * \brief The d_historicalData cast macro. + * + * This macro casts an object to a d_historicalData object. + */ +#define d_historicalData(s) ((d_historicalData)(s)) + +C_STRUCT(d_historicalData) { + C_EXTENDS(d_object); + d_durability durability; /* the durability service */ + d_historicalDataRequest historicalDataRequest; /* (combined) historicalDataRequest to answer */ + struct _DDS_DurabilityVersion_t version; /* durability version of the server */ + struct _DDS_Gid_t serverId; /* Id of the server */ + char *alignmentPartition; /* The partition used to publish the data */ + struct _DDS_HistoricalDataContent_t content; /* data content */ + c_iter requestIds; /* list of (combined) request ids */ + c_iter extensions; + c_iter partitions; + c_ulong errorCode; + /* Data collection */ + c_iter list; /* the group data (vmessages) to send */ + c_iter instances; /* group instance data */ + d_group group; /* durability group to write */ + v_group vgroup; /* associated vgroup to write */ + struct sd_cdrInfo *cdrInfo; /* cdr serializer info */ + v_message vmessage; /* the vmessage associated with the bead */ + c_ulong beadSize; /* size of the current payload */ + c_ulong totalSize; /* cumulative size of all payloads per group */ + c_bool checkTimeRange; /* time range checking required */ + unsigned short messageKind; /* kind of message */ + c_voidp *blob; /* serialized data blob */ + /* Various counters*/ + c_ulong count; + c_ulong writeCount; + c_ulong disposeCount; + c_ulong writeDisposeCount; + c_ulong registerCount; + c_ulong unregisterCount; + c_ulong skipCount; + /* completeness */ + unsigned short completeness; + /* publisher struct containing the publisher and writer */ + struct pubInfo *pubinfo; +}; + + +d_historicalData d_historicalDataNew (d_admin admin, d_historicalDataRequest request); + +void d_historicalDataDeinit (d_historicalData historicalData); + +void d_historicalDataFree (d_historicalData historicalData); + +c_bool d_historicalDataWrite (c_voidp *data); + +c_bool delete_pubinfo(void *listener, void *arg); + +#if defined (__cplusplus) +} +#endif + +#endif /* D__HISTORICAL_DATA_H */ diff --git a/src/services/durability/code/d__historicalDataRequest.h b/src/services/durability/code/d__historicalDataRequest.h new file mode 100644 index 000000000..a520ea9b2 --- /dev/null +++ b/src/services/durability/code/d__historicalDataRequest.h @@ -0,0 +1,107 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef D__HISTORICAL_DATA_REQUEST_H +#define D__HISTORICAL_DATA_REQUEST_H + +#include "d__types.h" +#include "d__admin.h" +#include "os_time.h" +#include "client_durabilitySplType.h" + +#if defined (__cplusplus) +extern "C" { +#endif + +#define HISTORICAL_DATA_KIND_BEAD 0 +#define HISTORICAL_DATA_KIND_LINK 1 + + +#define HISTORICAL_DATA_COMPLETENESS_UNKNOWN 0 +#define HISTORICAL_DATA_COMPLETENESS_INCOMPLETE 1 +#define HISTORICAL_DATA_COMPLETENESS_COMPLETE 2 + +#define PAYLOAD_SERIALIZATION_FORMAT_CDR_ANY 0 +#define PAYLOAD_SERIALIZATION_FORMAT_CDR_BE 1 +#define PAYLOAD_SERIALIZATION_FORMAT_CDR_LE 2 + +/** + * Macro that checks the d_historicalDataRequest validity. + * Because d_historicalDataRequest is a concrete class typechecking is required. + */ +#define d_historicalDataRequestIsValid(_this) \ + d_objectIsValid(d_object(_this), D_HISTORICAL_DATA_REQ) + + +/** + * \brief The d_historicalDataRequest cast macro. + * + * This macro casts an object to a d_historicalDataRequest object. + */ +#define d_historicalDataRequest(s) ((d_historicalDataRequest)(s)) + +C_STRUCT(d_historicalDataRequest) { + C_EXTENDS(d_object); + struct _DDS_DurabilityVersion_t version; /* version of the request */ + c_iter requestIds; /* list of (combined) request ids */ + char * topic; /* requested topic */ + c_iter partitions; /* list of partitions expressions */ + _DDS_PayloadSerializationFormat_t serializationFormat; /* serialization format */ + struct _DDS_DataReaderQos dataReaderQos; /* qos of datareader for the topic */ + os_timeW startTime; /* start time for matching historical data */ + os_timeW endTime; /* end time for matching historical data; this will never be higher than the time when the historicalDataRequest is received */ + char *sqlFilter; /* filter expression, if "" no filter is applied */ + char **sqlFilterParams; /* list of ptr to parameters of filter expressions */ + c_ulong sqlFilterParamsSize; /* nr of parameters */ + c_long maxSamples; /* max samples to request, -1 for unlimited */ + c_long maxInstances; /* max instances to request, -1 for unlimited */ + c_long maxSamplesPerInstance; /* max samples per instance, -1 for unlimited */ + c_iter alignmentPartition; /* candidate partitions to receive the response */ + c_iter serverIds; /* serverIds that should respond */ + os_duration timeout; /* timeout that indicates how long the server has to respond */ + c_iter extensions; /* future extensions */ + os_timeE receptionTime; /* elapsed time when request was received */ + os_timeE expirationTime; /* elapsed time before which the request needs to be answered */ + os_timeE answerTime; /* elapsed time when it is decide to answer the request */ + c_bool forMe; /* indicates if the request is addressed to me */ + c_bool forEverybody; /* indicates if request is addressed to everybody */ + c_ulong errorCode; /* result of sanity check for this request */ + /* various response control settings */ + c_bool include_payload_unregistrations; /* Indicates whether or not to include the payload in the unregistration response to this request */ +}; + + +#define D_CLIENT_DURABILITY_MAX_ERROR_LENGTH 255 + +d_historicalDataRequest d_historicalDataRequestNew (d_admin admin, + struct _DDS_HistoricalDataRequest *request); + +void d_historicalDataRequestDeinit (d_historicalDataRequest historicalDataRequest); + +void d_historicalDataRequestFree (d_historicalDataRequest historicalDataRequest); + +c_ulong d_historicalDataRequestSanityCheck (d_historicalDataRequest historicalDataRequest); + +int d_historicalDataRequestCompareByRequestId (d_historicalDataRequest historicalDataRequest1, + d_historicalDataRequest historicalDataRequest2); + +#if defined (__cplusplus) +} +#endif + +#endif /* D__HISTORICAL_DATA_REQUEST_H */ diff --git a/src/services/durability/code/d__historicalDataRequestListener.h b/src/services/durability/code/d__historicalDataRequestListener.h new file mode 100644 index 000000000..4c2a8231d --- /dev/null +++ b/src/services/durability/code/d__historicalDataRequestListener.h @@ -0,0 +1,90 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef D__HISTORICAL_DATA_REQUEST_LISTENER_H +#define D__HISTORICAL_DATA_REQUEST_LISTENER_H + +#include "d__types.h" +#include "d__listener.h" +#include "d__table.h" +#include "d__historicalDataRequest.h" +#include "ut_fibheap.h" +#include "ut_avl.h" +#include "u_dataReader.h" + +#if defined (__cplusplus) +extern "C" { +#endif + +C_STRUCT(d_historicalDataRequestListener) { + C_EXTENDS(d_listener); + u_dataReader dataReader; + d_waitsetEntity waitsetData; + d_eventListener historicalDataRequestEventListener; + d_subscriber subscriber; + /* Internal structure to administrate pending historicalDataRquests */ + ut_avlTreedef_t request_avltreedef; /* tree definition for requests */ + ut_avlTreedef_t pubinfo_avltreedef; /* tree definition for writer/publisher */ + ut_avlTree_t request_id_tree; /* tree structure for request lookup by id */ + ut_avlTree_t pubinfo_tree; /* tree structure for pubinfo lookup by partition */ + ut_fibheap_t prioqueue; /* priority queue structure ordered on expiration time */ + os_mutex queue_lock; /* lock to protect modifications to the request queue */ + os_cond cond; /* condition variable to trigger the answering of requests */ + c_bool terminate; /* Indicates whether or not the listener should terminate */ + os_threadId handlerThread; /* Thread to handle incoming requests */ + c_bool handlerThreadExists; /* Indicates if handlerThread creation succeeded or not */ +}; + + +/* Internal structure to administrate pending historicalDataRquests */ +struct request_admin_node { + ut_avlNode_t request_avlnode; /* node in request_avltreedef */ + ut_avlNode_t pubinfo_avlnode; /* node in pubinfo_avltreedef */ + ut_fibheapNode_t fhnode; /* ptr to node in fibheap priority queue */ + os_timeE insert_time; /* time to insert */ + os_timeE expiration_time; /* time to expire */ + os_timeE handle_time; /* time to handle */ + c_bool (*callback)(void *listener, void *arg); /* callback function to call when item is handled */ + void *listener; /* listener that provides the context for the callback */ + void *arg; /* argument of callback function */ +}; + + + +/* Internal structure to administrate cached publishers */ +struct pubInfo { + u_publisher publisher; /* publisher */ + u_writer writer; /* writer for historical data */ + char *partition; /* partition used to publish the data */ +}; + +extern const ut_fibheapDef_t prioqueue_fhdef; + +d_historicalDataRequestListener d_historicalDataRequestListenerNew (d_subscriber subscriber); + +void d_historicalDataRequestListenerFree (d_historicalDataRequestListener listener); + +c_bool d_historicalDataRequestListenerStart (d_historicalDataRequestListener listener); + +c_bool d_historicalDataRequestListenerStop (d_historicalDataRequestListener listener); + +#if defined (__cplusplus) +} +#endif + +#endif /* D__HISTORICAL_DATA_REQUEST_LISTENER_H */ diff --git a/src/services/durability/code/d__listener.h b/src/services/durability/code/d__listener.h new file mode 100644 index 000000000..677accdb3 --- /dev/null +++ b/src/services/durability/code/d__listener.h @@ -0,0 +1,101 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef D__LISTENER_H +#define D__LISTENER_H + +#include "d__types.h" +#include "d__lock.h" + +#if defined (__cplusplus) +extern "C" { +#endif + +#define USE_WAITSET 1 + +/** + * Macro that checks the d_listener validity. + * Because d_listener is an abstract class typechecking can + * only be done on the abstract listener object. + */ +#define d_listenerIsValid(_this) \ + d_objectIsValid(d_object(_this), D_LISTENER) + +/** + * \brief The d_listener cast macro. + * + * This macro casts an object to a d_listener object. + */ +#define d_listener(_this) ((d_listener)(_this)) + +typedef void (*d_listenerAction)(d_listener listener, d_message message); + +typedef enum d_listenerKind { + D_STATUS_LISTENER, + D_GROUP_REMOTE_LISTENER, + D_GROUP_LOCAL_LISTENER, + D_GROUPS_REQ_LISTENER, + D_SAMPLE_REQ_LISTENER, + D_SAMPLE_CHAIN_LISTENER, + D_NAMESPACES_REQ_LISTENER, + D_NAMESPACES_LISTENER, + D_PERSISTENT_DATA_LISTENER, + D_DELETE_DATA_LISTENER, + D_REMOTE_READER_LISTENER, + D_DCPS_HEARTBEAT_LISTENER, + D_HISTORICAL_DATA_REQ_LISTENER, + D_DURABILITY_STATE_REQ_LISTENER, + D_DCPS_PUBLICATION_LISTENER, + D_CAPABILITY_LISTENER +} d_listenerKind; + + +C_STRUCT(d_listener) { + C_EXTENDS(d_lock); + d_listenerKind kind; + d_admin admin; + d_listenerAction action; + c_bool attached; +}; + +void d_listenerInit (d_listener listener, + d_listenerKind kind, + d_subscriber subscriber, + d_listenerAction action, + d_objectDeinitFunc deinit); + +c_bool d_listenerIsValidKind (d_listener listener, + d_listenerKind kind); + +void d_listenerDeinit (d_listener listener); + +d_listenerAction d_listenerGetAction (d_listener listener); + +c_bool d_listenerIsAttached (d_listener listener); + +d_admin d_listenerGetAdmin (d_listener listener); + +void d_listenerLock (d_listener listener); + +void d_listenerUnlock (d_listener listener); + +#if defined (__cplusplus) +} +#endif + +#endif /* D__LISTENER_H */ diff --git a/src/services/durability/code/d__lock.h b/src/services/durability/code/d__lock.h new file mode 100644 index 000000000..961563f3a --- /dev/null +++ b/src/services/durability/code/d__lock.h @@ -0,0 +1,69 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef D__LOCK_H +#define D__LOCK_H + +#include "d__types.h" +#include "os_mutex.h" + +#if defined (__cplusplus) +extern "C" { +#endif + +/** + * Macro that checks the d_lock validity. + * Because the d_lock is an abstract class it is checked + * if the pointer is non-NULL. + */ +#define d_lockIsValid(_this) (_this != NULL) + +/** + * \brief The d_lock cast macro. + * + * This macro casts an object to a d_lock object. + */ +#define d_lock(d) ((d_lock)(d)) + +C_STRUCT(d_lock) { + C_EXTENDS(d_object); + d_objectDeinitFunc deinit; + os_mutex lock; +#ifndef NDEBUG + os_ulong_int tid; +#endif +}; + + +void d_lockInit (d_lock lock, + d_kind kind, + d_objectDeinitFunc deinit); + +void d_lockDeinit (d_lock lock); + +void d_lockFree (d_lock lock); + +void d_lockLock (d_lock lock); + +void d_lockUnlock (d_lock lock); + +#if defined (__cplusplus) +} +#endif + +#endif /* D__LOCK_H */ diff --git a/src/services/durability/code/d__mergeAction.h b/src/services/durability/code/d__mergeAction.h new file mode 100644 index 000000000..9b1dd4096 --- /dev/null +++ b/src/services/durability/code/d__mergeAction.h @@ -0,0 +1,98 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#include "d__types.h" +#include "d__lock.h" +#include "c_iterator.h" + +#ifndef D__MERGEACTION_H +#define D__MERGEACTION_H + +#if defined (__cplusplus) +extern "C" { +#endif + +/** + * Macro that checks the d_mergeAction validity. + * Because d_mergeAction is a concrete class typechecking is required. + */ +#define d_mergeActionIsValid(_this) \ + d_objectIsValid(d_object(_this), D_MERGE_ACTION) + +/** + * \brief The d_mergeAction cast macro. + * + * This macro casts an object to a d_mergeAction object. + */ +#define d_mergeAction(_this) ((d_mergeAction)(_this)) + +C_STRUCT(d_mergeAction) { + C_EXTENDS(d_lock); + d_conflict conflict; /* conflict that led to the creation of this mergeAction */ + d_nameSpace nameSpace; /* Local nameSpace that needs merging. */ + d_table fellows; /* Fellows to merge with. */ + d_mergeState newState; /* New state for merge (after action is handled) */ + d_table chains; /* Requests that have not been fulfilled yet. */ + c_bool stateChanged; /* Has one of the chains updated the state */ +}; + + +d_mergeAction d_mergeActionNew (d_conflict conflict, + d_nameSpace nameSpace, + c_iter fellows, + d_mergeState fellowState); + +void d_mergeActionFree (d_mergeAction action); + +void d_mergeActionDeinit (d_mergeAction action); + +c_bool d_mergeActionAddChain (d_mergeAction action, + d_chain chain); + +c_bool d_mergeActionRemoveChain (d_mergeAction action, + d_chain dummy); + +d_chain d_mergeActionGetChain (d_mergeAction action, + d_chain dummy); + +c_ulong d_mergeActionGetChainCount (d_mergeAction action); + +void d_mergeActionChainWalk (d_mergeAction mergeAction, + c_bool ( * action ) ( + d_chain chain, + c_voidp data), + c_voidp userData); + +int d_mergeActionCompare (d_mergeAction a1, + d_mergeAction a2); + +d_nameSpace d_mergeActionGetNameSpace (d_mergeAction action); + +d_mergeState d_mergeActionGetNewState (d_mergeAction action); + +void d_mergeActionSetStateChanged (d_mergeAction action, + c_bool stateChanged); + +c_bool d_mergeActionGetStateChanged (d_mergeAction action); + +void d_mergeActionUpdateMergeCount (d_mergeAction action); + +#if defined (__cplusplus) +} +#endif + +#endif /* D__MERGEACTION_H */ diff --git a/src/services/durability/code/d__mergeState.h b/src/services/durability/code/d__mergeState.h new file mode 100644 index 000000000..24683034d --- /dev/null +++ b/src/services/durability/code/d__mergeState.h @@ -0,0 +1,73 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#ifndef D__MERGESTATE_H_ +#define D__MERGESTATE_H_ + +#include "d__types.h" + +#if defined (__cplusplus) +extern "C" { +#endif + +#define d_mergeState(s) ((d_mergeState)(s)) + +d_mergeState +d_mergeStateNew( + const d_name role, + c_ulong value); + +void +d_mergeStateInit( + d_mergeState mergeState, + const d_name role, + c_ulong value); + +void +d_mergeStateFree( + d_mergeState mergeState); + +void +d_mergeStateDeinit( + d_mergeState mergeState); + +int +d_mergeStateCompare( + d_mergeState state1, + d_mergeState state2); + +int +d_mergeStateRoleValueCompare( + d_mergeState state1, + d_mergeState state2); + +void +d_mergeStateSetRole( + d_mergeState mergeState, + d_name role); + +void +d_mergeStateSetValue( + d_mergeState mergeState, + c_ulong value); + + +#if defined (__cplusplus) +} +#endif + +#endif /* D__MERGESTATE_H_ */ diff --git a/src/services/durability/code/d__misc.h b/src/services/durability/code/d__misc.h new file mode 100644 index 000000000..6c311fd1f --- /dev/null +++ b/src/services/durability/code/d__misc.h @@ -0,0 +1,183 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef D__MISC_H +#define D__MISC_H + +#include "d__types.h" +#include "c_time.h" +#include "c_base.h" +#include "vortex_os.h" + +#if defined (__cplusplus) +extern "C" { +#endif + +#define D_CONTEXT_DURABILITY "Durability Service" +#define RR_MALLOC_FAILED "Malloc failed for '%s'\n" + +#define D_DDS_COMPLETENESS_UNKNOWN 0U +#define D_DDS_COMPLETENESS_INCOMPLETE 1U +#define D_DDS_COMPLETENESS_COMPLETE 2U + +/* The following defines specify the error codes that may + * be returned to a durability client as respons to a request + * from that client. + * Currently this list is defined both here and in the implementation + * of the durability client. When this list of error codes is + * changed the change should also be implemented in the durability + * client. + */ +/* no error */ +#define D_DDS_RETCDE_NO_ERROR 0x0 +/* Syntax errors -- 1 - 8388607 (= 1 .. 2^23-1) */ +#define D_DDS_RETCDE_INCOMPATIBLE_VERSION 0x1 +#define D_DDS_RETCDE_NO_TOPIC 0x2 +#define D_DDS_RETCDE_INVALID_START_TIME 0x3 +#define D_DDS_RETCDE_INVALID_END_TIME 0x4 +#define D_DDS_RETCDE_INVALID_TIME_RANGE 0x5 +#define D_DDS_RETCDE_INVALID_SERIAZATION 0x6 +#define D_DDS_RETCDE_NO_PARTITIONS 0x7 +#define D_DDS_RETCDE_INVALID_MAX_SAMPLES 0x8 +#define D_DDS_RETCDE_INVALID_MAX_INSTANCES 0x9 +#define D_DDS_RETCDE_INVALID_MAX_SAMPLES_PER_INSTANCE 0xA +/* Syntax OK, but server is not able process -- 8388608 - (= 2^23 - 2^24-1) - */ +#define D_DDS_RETCDE_SERVER_IS_NOT_ALIGNER 0x80000000 +#define D_DDS_RETCDE_SERVER_IS_NOT_RESPONSIBLE 0x80000001 +#define D_DDS_RETCDE_READER_NOT_KNOWN 0x80000002 +#define D_DDS_RETCDE_NO_MASTER_SELECTED 0x80000003 +#define D_DDS_RETCDE_GROUP_NOT_FOUND 0x80000004 +#define D_DDS_RETCDE_NO_CLIENTS 0x80000005 +#define D_DDS_RETCDE_INVALID 0xFFFFFFFF + +struct error { + c_ulong errorCode; + char *errorMessage; +}; + +extern const char *d_builtinTopics[]; +extern const struct error Error[]; + +/* Internal quality is mapped as os_timeW */ +typedef os_timeW d_quality; +#define D_QUALITY_ZERO OS_TIMEW_ZERO +#define D_QUALITY_INFINITE OS_TIMEW_INFINITE +#define D_QUALITY_ISZERO(q) (OS_TIMEW_ISZERO(q)) +#define D_QUALITY_ISINFINITE(q) (OS_TIMEW_ISINFINITE(q)) + +struct baseFind { + c_base base; +}; + + +void d_free (c_voidp allocated ); + +c_voidp d_malloc (size_t size, + const char * errorText); + +void d_printTimedEvent (d_durability durability, + d_level level, + const char * eventText, + ...); + +void d_printEvent (d_durability durability, + d_level level, + const char * eventText, + ...); + +void d_reportLocalGroup (_In_ d_durability d, + _In_ _Const_ v_group group); + +c_base d_findBase (d_durability durability); + +c_bool d_patternMatch (const char* str, + const char* pattern); + +c_bool d_isBuiltinGroup (_In_z_ _Const_ d_partition partition, + _In_z_ _Const_ d_topic topic); + +c_bool d_isHeartbeatGroup (_In_z_ _Const_ d_partition partition, + _In_z_ _Const_ d_topic topic); + +void d_printState (d_durability durability, + d_configuration config, + const char* threadName, + char* header); + +const char * d_inBuiltinTopicNames (const char* str, + size_t len); + +c_bool d_shmAllocAssert (c_voidp ptr, + const char* errorMessage); + +c_bool d_shmAllocAllowed (void); + +_DDS_Completeness_t d_mapCompleteness (d_completeness completeness); + +char * d_getErrorMessage (c_ulong errorCode); + +unsigned short d_swap2uToBE (unsigned short x); + +unsigned d_swap4uToBE (unsigned x); + +unsigned long long d_swap8uToBE (unsigned long long x); + +#define d_swap2uFromBE d_swap2uToBE +#define d_swap4uFromBE d_swap4uToBE +#define d_swap8uFromBE d_swap8uToBE + +c_bool sequenceOfStringCopyOut (c_iter *to, + const c_sequence from); + +d_durabilityKind d_durabilityKindFromKernel (v_durabilityKind kind); + +const char *d_compressionKVImage (d_compressionKV compression); + +void d_trace (c_ulong mask, const char *fmt, ...); + +void d_tracegroupGenKeystr (char *keystr, size_t keystr_size, v_groupInstance gi); + +void d_tracegroupGenMsgKeystr (char *keystr, size_t keystr_size, v_group g, v_message msg); + +void d_tracegroupInstance (v_groupInstance gi, d_durability dur, const char *prefix); + +void d_tracegroup (d_durability dur, v_group g, const char *info); + +void d_timestampFromTimeW (d_timestamp *t1, os_timeW *t2, c_bool Y2038Ready); + +void d_timestampToTimeW (os_timeW *t1, d_timestamp *t2, c_bool Y2038Ready); + +void d_qualityExtFromQuality (d_qualityExt *q1, d_quality *q2, c_bool Y2038Ready); + +void d_qualityExtToQuality (d_quality *q1, d_qualityExt *q2, c_bool Y2038Ready); + +os_compare d_qualityCompare (d_quality q1, d_quality q2); + +void d_productionTimestampToSeqnum(os_uint32 *seqnum, d_timestamp *t); + +void d_productionTimestampFromSeqnum(d_timestamp *t, os_uint32 *seqnum); + +os_timeE d_timeWToTimeE (os_timeW t); + +void d_traceMergeAction (d_mergeAction mergeAction, const char *info); + +#if defined (__cplusplus) +} +#endif + +#endif /* D__MISC_H */ diff --git a/src/services/durability/code/d__nameSpace.h b/src/services/durability/code/d__nameSpace.h new file mode 100644 index 000000000..3d6f3e150 --- /dev/null +++ b/src/services/durability/code/d__nameSpace.h @@ -0,0 +1,235 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#include "d__types.h" +#include "d__lock.h" +#include "d__misc.h" + +#ifndef D__NAMESPACE_H +#define D__NAMESPACE_H + +#if defined (__cplusplus) +extern "C" { +#endif + +/** + * Macro that checks the d_nameSpace validity. + * Because d_nameSpace is a concrete class typechecking is required. + */ +#define d_nameSpaceIsValid(_this) \ + d_objectIsValid(d_object(_this), D_NAMESPACE) + +/** + * \brief The d_nameSpace cast macro. + * + * This macro casts an object to a d_nameSpace object. + */ +#define d_nameSpace(_this) ((d_nameSpace)(_this)) + +/** + * \brief The d_filter cast macro. + * + * This macro casts an object to a d_filter object. + */ +#define d_filter(_this) ((d_filter)(_this)) + +/* used when searching for a match on partition and topic */ +C_CLASS(d_nameSpaceSearch); +C_STRUCT(d_nameSpaceSearch) { + d_partition partition; + d_topic topic; + c_bool match; +}; + +C_STRUCT(d_nameSpace) { + C_EXTENDS(d_lock); + d_name name; + d_policy policy; + d_quality quality; + d_networkAddress master; + d_serviceState masterState; + c_bool masterConfirmed; + d_table elements; + d_mergeState mergeState; /* The internal mergeState for this nameSpace */ + d_mergeState advertisedMergeState; /* The mergeState that is advertised to fellows */ + d_table mergedRoleStates; + c_bool mustAlignBuiltinTopics; /* TRUE if durability must align builtin topics */ + c_bool alignable; /* TRUE if the fellow that owns this nameSpace + * is a candidate to align from. The alignable + * attribute has only meaning for fellow nameSpaces + */ + c_bool compatibility_check_required; /* Indicator if compatibility check is still required */ + c_ulong mergeCount; +}; + +typedef enum d_nameSpaceHelperKind_s { + D_NS_COUNT, D_NS_COPY +} d_nameSpaceHelperKind; + +struct d_nameSpaceHelper{ + d_nameSpaceHelperKind kind; + os_uint32 count; + c_char* value; + d_nameSpace ns; +}; + +d_nameSpace d_nameSpaceNew (const char * name, + d_policy policy); + +d_nameSpace d_nameSpaceCopy (d_nameSpace nameSpace); + +int d_nameSpaceCompare (d_nameSpace ns1, + d_nameSpace ns2); + +int d_nameSpaceCompatibilityCompare (d_nameSpace ns1, + d_nameSpace ns2); + +int d_nameSpaceNameCompare (d_nameSpace ns1, + d_nameSpace ns2); + +void d_nameSpaceFree (d_nameSpace nameSpace); + +int d_nameSpaceAddElement (d_nameSpace nameSpace, + const char * name, + const char * partition, + const char * topic); + +char * d_nameSpaceGetName (d_nameSpace nameSpace); + +d_policy d_nameSpaceGetPolicy (d_nameSpace nameSpace); + + +c_bool d_nameSpaceIsEmpty (d_nameSpace nameSpace); + +c_bool d_nameSpaceIsIn (d_nameSpace nameSpace, + d_partition partition, + d_topic topic); + +void d_nameSpaceElementWalk (d_nameSpace nameSpace, + c_bool ( * action ) ( + d_element element, + c_voidp userData), + c_voidp args); + +c_bool d_nameSpaceIsAligner (d_nameSpace nameSpace) ; + +c_char* d_nameSpaceGetPartitions (d_nameSpace nameSpace); + +c_char* d_nameSpaceGetPartitionTopics (d_nameSpace nameSpace); + +void d_nameSpaceCopyPartitions (d_nameSpace to, + d_nameSpace from); + +void d_nameSpaceSetInitialQuality (d_nameSpace nameSpace, + d_quality quality); + +d_quality d_nameSpaceGetInitialQuality (d_nameSpace nameSpace); + +d_nameSpace d_nameSpaceFromNameSpaces (d_configuration config, + d_nameSpaces ns); + +d_alignmentKind d_nameSpaceGetAlignmentKind (d_nameSpace nameSpace); + +d_durabilityKind d_nameSpaceGetDurabilityKind (d_nameSpace nameSpace); + + +void d_nameSpaceSetMasterState (d_nameSpace nameSpace, + d_serviceState serviceState); + +d_serviceState d_nameSpaceGetMasterState (d_nameSpace nameSpace); + +void d_nameSpaceSetMaster (d_nameSpace nameSpace, + d_networkAddress master); + +d_networkAddress d_nameSpaceGetMaster (d_nameSpace nameSpace); + +void d_nameSpaceMasterConfirmed (d_nameSpace nameSpace); + +void d_nameSpaceMasterPending (d_nameSpace nameSpace); + +void d_nameSpaceSetMasterConfirmed (d_nameSpace nameSpace, + c_bool masterConfirmed); + +c_bool d_nameSpaceIsMasterConfirmed (d_nameSpace nameSpace); + +c_bool d_nameSpaceMasterIsMe (d_nameSpace nameSpace, + d_admin admin); + +c_bool d_nameSpaceMasterIsAddress (d_nameSpace nameSpace, + d_networkAddress addr); + +c_bool d_nameSpaceIsAlignmentNotInitial (d_nameSpace nameSpace); + +c_bool d_nameSpaceGetDelayedAlignment (d_nameSpace nameSpace); + +c_bool d_nameSpaceStringMatches (c_string str, + c_string pattern); + +d_name d_nameSpaceGetRole (d_nameSpace nameSpace); + +d_mergePolicy d_nameSpaceGetMergePolicy (d_nameSpace nameSpace, + d_name role); + +d_mergeState d_nameSpaceGetMergeState (d_nameSpace nameSpace, + d_name role); + +d_mergeState d_nameSpaceGetAdvertisedMergeState (d_nameSpace nameSpace); + +void d_nameSpaceSetMergeState (d_nameSpace nameSpace, + d_mergeState state); + +int d_nameSpaceGetMergePolicyFromStates (d_nameSpace ns1, + d_nameSpace ns2); + +void d_nameSpaceClearMergeState (d_nameSpace nameSpace, + d_name role); + +void d_nameSpaceReplaceMergeStates (d_nameSpace ns1, + d_nameSpace ns2); + +c_iter d_nameSpaceGetMergedStatesDiff (d_nameSpace ns1, + d_nameSpace ns2); + +c_bool d_nameSpaceGetPartitionsAction (d_element element, + c_voidp args); + +c_bool d_nameSpaceGetPartitionTopicsAction (d_element element, + c_voidp args); + +void d_nameSpaceDeinit (d_nameSpace nameSpace); + +c_bool d_nameSpaceIsAlignable (d_nameSpace nameSpace); + +void d_nameSpaceSetAlignable (d_nameSpace nameSpace, + c_bool alignable); + +c_bool d_nameSpaceGetEqualityCheck (d_nameSpace nameSpace); + +c_ulong d_nameSpaceGetMasterPriority (d_nameSpace nameSpace); + +void d_nameSpaceSyncMergeState (d_nameSpace nameSpace); + +void d_nameSpaceSetMergeCount (d_nameSpace nameSpace, + c_ulong mergeCount); + +c_ulong d_nameSpaceGetMergeCount (d_nameSpace nameSpace); + +#if defined (__cplusplus) +} +#endif + +#endif /* D__NAMESPACE_H */ diff --git a/src/services/durability/code/d__nameSpaces.h b/src/services/durability/code/d__nameSpaces.h new file mode 100644 index 000000000..d129b7f68 --- /dev/null +++ b/src/services/durability/code/d__nameSpaces.h @@ -0,0 +1,32 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef D__NAMESPACES_H +#define D__NAMESPACES_H + +#include "d__types.h" + +#if defined (__cplusplus) +extern "C" { +#endif + +#if defined (__cplusplus) +} +#endif + +#endif /*D__NAMESPACES_H*/ diff --git a/src/services/durability/code/d__nameSpacesListener.h b/src/services/durability/code/d__nameSpacesListener.h new file mode 100644 index 000000000..d178ed82c --- /dev/null +++ b/src/services/durability/code/d__nameSpacesListener.h @@ -0,0 +1,37 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef D__NAMESPACESLISTENER_H +#define D__NAMESPACESLISTENER_H + +#include "d__types.h" + +#if defined (__cplusplus) +extern "C" { +#endif + +d_nameSpacesListener d_nameSpacesListenerNew (d_subscriber subscriber); +void d_nameSpacesListenerFree (d_nameSpacesListener listener); +c_bool d_nameSpacesListenerStart (d_nameSpacesListener listener); +c_bool d_nameSpacesListenerStop (d_nameSpacesListener listener); + +#if defined (__cplusplus) +} +#endif + +#endif /* D__NAMESPACESLISTENER_H */ diff --git a/src/services/durability/code/d__nameSpacesRequestListener.h b/src/services/durability/code/d__nameSpacesRequestListener.h new file mode 100644 index 000000000..5deb2c1cd --- /dev/null +++ b/src/services/durability/code/d__nameSpacesRequestListener.h @@ -0,0 +1,38 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef D__NAMESPACESREQUESTLISTENER_H +#define D__NAMESPACESREQUESTLISTENER_H + +#include "d__types.h" + +#if defined (__cplusplus) +extern "C" { +#endif + +d_nameSpacesRequestListener d_nameSpacesRequestListenerNew (d_subscriber subscriber); +void d_nameSpacesRequestListenerFree (d_nameSpacesRequestListener listener); +c_bool d_nameSpacesRequestListenerStart (d_nameSpacesRequestListener listener); +c_bool d_nameSpacesRequestListenerStop (d_nameSpacesRequestListener listener); +void d_nameSpacesRequestListenerReportNameSpaces (d_nameSpacesRequestListener listener); + +#if defined (__cplusplus) +} +#endif + +#endif /* D__NAMESPACESREQUESTLISTENER_H */ diff --git a/src/services/durability/code/d__pQos.h b/src/services/durability/code/d__pQos.h new file mode 100644 index 000000000..50a070dc1 --- /dev/null +++ b/src/services/durability/code/d__pQos.h @@ -0,0 +1,18 @@ +#ifndef D__PQOS_H +#define D__PQOS_H + +#include "v_kernel.h" +#include "durabilityModule2.h" + +#if defined (__cplusplus) +extern "C" { +#endif + +d_persistentTopicQosV0 d_pQosFromTopicQos (const struct v_topicQos_s *qos); +v_topicQos d_topicQosFromPQos (c_base base, const struct d_persistentTopicQosV0_s *pqos); + +#if defined (__cplusplus) +} +#endif + +#endif diff --git a/src/services/durability/code/d__partitionTopicState.h b/src/services/durability/code/d__partitionTopicState.h new file mode 100644 index 000000000..7ad63b408 --- /dev/null +++ b/src/services/durability/code/d__partitionTopicState.h @@ -0,0 +1,65 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef D__PARTITION_TOPIC_STATE_H +#define D__PARTITION_TOPIC_STATE_H + +#include "d__types.h" +#include "d__admin.h" +#include "client_durabilitySplType.h" + +#if defined (__cplusplus) +extern "C" { +#endif + +/** + * Macro that checks the d_partitionTopicState validity. + * Because d_partitionTopicState is a concrete class typechecking is required. + */ +#define d_partitionTopicStateIsValid(_this) \ + d_objectIsValid(d_object(_this), D_PART_TOPIC_STATE) + + +/** + * \brief The d_partitionTopicState cast macro. + * + * This macro casts an object to a d_partitionTopicState object. + */ +#define d_partitionTopicState(s) ((d_partitionTopicState)(s)) + + +C_STRUCT(d_partitionTopicState) { + C_EXTENDS(d_object); + d_topic topic; + d_partition partition; + d_completeness completeness; + c_iter extensions; +}; + + +d_partitionTopicState d_partitionTopicStateNew (d_group group); + +void d_partitionTopicStateDeinit (d_partitionTopicState state); + +void d_partitionTopicStateFree (d_partitionTopicState state); + +#if defined (__cplusplus) +} +#endif + +#endif /* D__PARTITION_TOPIC_STATE_H */ diff --git a/src/services/durability/code/d__persistentDataListener.h b/src/services/durability/code/d__persistentDataListener.h new file mode 100644 index 000000000..01029b267 --- /dev/null +++ b/src/services/durability/code/d__persistentDataListener.h @@ -0,0 +1,42 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef D__PERSISTENTDATALISTENER_H +#define D__PERSISTENTDATALISTENER_H + +#include "d__types.h" +#include "d__listener.h" +#include "u_groupQueue.h" + +#if defined (__cplusplus) +extern "C" { +#endif + +d_persistentDataListener d_persistentDataListenerNew (d_subscriber subscriber); + +void d_persistentDataListenerFree (d_persistentDataListener listener); + +c_bool d_persistentDataListenerStart (d_persistentDataListener listener); + +c_bool d_persistentDataListenerStop (d_persistentDataListener listener); + +#if defined (__cplusplus) +} +#endif + +#endif /* D__PERSISTENTDATALISTENER_H */ diff --git a/src/services/durability/code/d__policy.h b/src/services/durability/code/d__policy.h new file mode 100644 index 000000000..48c35eded --- /dev/null +++ b/src/services/durability/code/d__policy.h @@ -0,0 +1,122 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef D__POLICY_H +#define D__POLICY_H + +#include "d__types.h" + +#if defined (__cplusplus) +extern "C" { +#endif + +/** + * Macro that checks the d_policy validity. + * Because d_policy is a concrete class typechecking is required. + */ +#define d_policyIsValid(_this) \ + d_objectIsValid(d_object(_this), D_POLICY) + +/** + * \brief The d_policy cast macro. + * + * This macro casts an object to a d_policy object. + */ +#define d_policy(_this) ((d_policy)(_this)) + + +typedef struct +d_policyMergeRule { + d_mergePolicy mergeType; + c_char* scope; +} d_policyMergeRule; + +C_STRUCT(d_policy) { + C_EXTENDS(d_object); + d_name nameSpace; + c_bool aligner; + d_alignmentKind alignmentKind; + c_bool delayedAlignment; + d_durabilityKind durabilityKind; + c_iter mergePolicyRules; + c_bool equalityCheck; /* Indicates if a hash over the set of samples + * needs to be calculated to determine equality. + * Used for align-on-change. + */ + c_ulong masterPriority; /* Indicates the willingness of the federation + * to become master for the given nameSpace. + * Needs to be used in combination with 'aligner' + * is TRUE and where 0 indicates never become + * master but do align my master. + */ +}; + + +/* Create new policy object */ +d_policy d_policyNew (const char* namespace, + c_bool aligner, + d_alignmentKind alignmentKind, + c_bool delayedAlignment, + d_durabilityKind durabilityKind, + c_bool equalityCheck, + c_ulong masterPriority); + +void d_policyDeinit (d_policy policy); + +/* Delete policies */ +void d_policyFree (d_policy policy); + +/* Find policy for namespace ==> Move to configuration */ +d_policy d_policyGet (d_configuration config, + const char* namespace); + +/* Get aligner policy */ +c_bool d_policyGetAligner (d_policy policy); + +/* Get policy for alignment kind */ +d_alignmentKind d_policyGetAlignmentKind (d_policy policy); + +/* Get policy for delayed alignment */ +c_bool d_policyGetDelayedAlignment (d_policy policy); + +/* Get policy for durabiltiy kind */ +d_durabilityKind d_policyGetDurabilityKind (d_policy policy); + +/* Get namespace pattern from policy */ +c_string d_policyGetNameSpace (d_policy policy); + +/* Get policy for equalityCheck */ +c_bool d_policyGetEqualityCheck (d_policy policy); + +/* Get policy for masterPriority */ +c_ulong d_policyGetMasterPriority (d_policy policy); + +/* Add merge policy rule to policy */ +void d_policyAddMergeRule (d_policy policy, + d_mergePolicy mergeType, + const char* scope); + +/* Get merge policy for role */ +d_mergePolicy d_policyGetMergePolicy (d_policy policy, + char* role); + +#if defined (__cplusplus) +} +#endif + +#endif /* D__POLICY_H */ diff --git a/src/services/durability/code/d__publisher.h b/src/services/durability/code/d__publisher.h new file mode 100644 index 000000000..ded61855d --- /dev/null +++ b/src/services/durability/code/d__publisher.h @@ -0,0 +1,176 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef D__PUBLISHER_H +#define D__PUBLISHER_H + +#include "d__types.h" +#include "u_user.h" +#include "os_mutex.h" + +#if defined (__cplusplus) +extern "C" { +#endif + +/** + * Macro that checks the d_publisher validity. + * Because d_publisher is a concrete class typechecking is required. + */ +#define d_publisherIsValid(_this) \ + d_objectIsValid(d_object(_this), D_PUBLISHER) + +/** + * \brief The d_publisher cast macro. + * + * This macro casts an object to a d_publisher object. + */ +#define d_publisher(_this) ((d_publisher)(_this)) + +C_STRUCT(d_publisher){ + C_EXTENDS(d_object); + d_admin admin; + u_publisher publisher; /* publisher for durability protocol topics */ + u_publisher publisher2; /* publisher for client durability */ + c_bool enabled; + c_bool capabilitySupport; + u_writer groupsRequestWriter; + c_ulong groupsRequestNumber; + u_writer sampleRequestWriter; + c_ulong sampleRequestNumber; + u_writer statusWriter; + c_ulong statusNumber; + u_writer newGroupWriter; + c_ulong newGroupNumber; + u_writer sampleChainWriter; + c_ulong sampleChainNumber; + u_writer nameSpacesRequestWriter; + c_ulong nameSpacesRequestNumber; + u_writer nameSpacesWriter; + c_ulong nameSpacesNumber; + u_writer deleteDataWriter; + c_ulong deleteDataNumber; + u_writer durabilityStateWriter; + c_ulong durabilityStateNumber; + c_ulong historicalDataNumber; + u_writer capabilityWriter; + c_ulong capabilityNumber; +}; + +v_copyin_result d_publisherMessageWriterCopy (d_message msgFrom, + d_message msgTo); + +v_copyin_result d_publisherStatusWriterCopy (c_type type, + const void *data, + void *to); + +v_copyin_result d_publisherNewGroupWriterCopy (c_type type, + const void *data, + void *to); + +v_copyin_result d_publisherGroupsRequestWriterCopy (c_type type, + const void *data, + void *to); + + +v_copyin_result d_publisherSampleRequestWriterCopy (c_type type, + const void *data, + void *to); + +v_copyin_result d_publisherSampleChainWriterCopy (c_type type, + const void *data, + void *to); + +v_copyin_result d_publisherNameSpacesWriterCopy (c_type type, + const void *data, + void *to); + +v_copyin_result d_publisherNameSpacesRequestWriterCopy (c_type type, + const void *data, + void *to); + +v_copyin_result d_publisherDeleteDataWriterCopy (c_type type, + const void *data, + void *to); + +v_copyin_result d_publisherCapabilityWriterCopy (c_type type, + const void *data, + void *to); + +void d_publisherInitMessage (d_publisher publisher, + d_message message); + +void d_publisherEnsureServicesAttached (v_public entity, + c_voidp args); + +void d_publisherDeinit (d_publisher publisher); + +d_publisher d_publisherNew (d_admin admin); + +void d_publisherFree (d_publisher publisher); + +c_bool d_publisherStatusWrite (d_publisher publisher, + d_status message, + d_networkAddress addressee); + +c_bool d_publisherStatusResend (d_publisher publisher, + d_status message); + +c_bool d_publisherNewGroupWrite (d_publisher publisher, + d_newGroup message, + d_networkAddress addressee); + +c_bool d_publisherGroupsRequestWrite (d_publisher publisher, + d_groupsRequest message, + d_networkAddress addressee); + +c_bool d_publisherSampleRequestWrite (d_publisher publisher, + d_sampleRequest message, + d_networkAddress addressee); + +c_bool d_publisherSampleChainWrite (d_publisher publisher, + d_sampleChain message, + d_networkAddress addressee); + +c_bool d_publisherNameSpacesRequestWrite (d_publisher publisher, + d_nameSpacesRequest message, + d_networkAddress addressee, + d_serviceState state); + +c_bool d_publisherNameSpacesWrite (d_publisher publisher, + d_nameSpaces message, + d_networkAddress addressee); + +c_bool d_publisherDeleteDataWrite (d_publisher publisher, + d_deleteData message, + d_networkAddress addressee); + +c_bool d_publisherCapabilityWrite (d_publisher publisher, + d_capability message, + d_networkAddress addressee); + +c_bool d_publisherDurabilityStateWrite (d_publisher publisher, + d_durabilityState durabilityState); + +c_bool d_publisherUnregisterInstances (d_publisher publisher, + d_networkAddress addressee); + +#if defined (__cplusplus) +} +#endif + +#endif /* D__PUBLISHER_H */ diff --git a/src/services/durability/code/d__readerListener.h b/src/services/durability/code/d__readerListener.h new file mode 100644 index 000000000..f4935d735 --- /dev/null +++ b/src/services/durability/code/d__readerListener.h @@ -0,0 +1,75 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef D__READERLISTENER_H +#define D__READERLISTENER_H + +#include "d__types.h" +#include "d__listener.h" +#include "d__subscriber.h" +#include "u_object.h" + +#if defined (__cplusplus) +extern "C" { +#endif + +/** + * \brief The d_readerListener cast macro. + * + * This macro casts an object to a d_readerListener object. + */ +#define d_readerListener(_this) ((d_readerListener)(_this)) + +C_STRUCT(d_readerListener){ + C_EXTENDS(d_listener); + u_dataReader dataReader; + os_size_t fieldOffset; + c_iter takenSamples; + c_object value; + c_bool processMessage; + d_waitsetEntity waitsetData; + os_threadAttr attr; + c_char* name; + c_ulong samplesTotal; + c_ulong samplesFromMe; + c_ulong samplesForMe; + os_timeW lastInsertTime; + os_timeW lastSourceTime; + c_ulong myAddr; +}; + +c_bool d_readerListenerStart (d_readerListener listener); +c_bool d_readerListenerStop (d_readerListener listener); +void d_readerListenerDeinit (d_readerListener listener); +void d_readerListenerInit (d_readerListener listener, + d_listenerKind kind, + d_listenerAction action, + d_subscriber subscriber, + const c_char* topicName, + const c_char* fieldName, + v_reliabilityKind reliability, + v_historyQosKind historyKind, + c_long historyDepth, + os_threadAttr attr, + d_objectDeinitFunc deinit); + +#if defined (__cplusplus) +} +#endif + +#endif /* D__READERLISTENER_H */ diff --git a/src/services/durability/code/d__readerRequest.h b/src/services/durability/code/d__readerRequest.h new file mode 100644 index 000000000..228f637d1 --- /dev/null +++ b/src/services/durability/code/d__readerRequest.h @@ -0,0 +1,101 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#ifndef D__READERREQUEST_H +#define D__READERREQUEST_H + +#include "d__types.h" +#include "d__lock.h" + +#if defined (__cplusplus) +extern "C" { +#endif + +/** + * Macro that checks the d_readerRequest validity. + * Because d_readerRequest is a concrete class typechecking is required. + */ +#define d_readerRequestIsValid(_this) \ + d_objectIsValid(d_object(_this), D_READER_REQUEST) + +/** + * \brief The d_readerRequest cast macro. + * + * This macro casts an object to a d_readerRequest object. + */ +#define d_readerRequest(_this) ((d_readerRequest)(_this)) + +C_STRUCT(d_readerRequest){ + C_EXTENDS(d_lock); + d_admin admin; + v_handle readerHandle; + c_char* filter; + c_char** filterParams; + c_ulong filterParamsCount; + v_resourcePolicyI resourceLimits; + c_time minSourceTimestamp; + c_time maxSourceTimestamp; + d_table requests; + d_table groups; + c_bool groupsIgnored; +}; + +void d_readerRequestDeinit (d_readerRequest request); + +d_readerRequest d_readerRequestNew (d_admin admin, + v_waitsetEvent event); + +d_readerRequest d_readerRequestProxyNew (v_handle source); + +d_admin d_readerRequestGetAdmin (d_readerRequest request); + +v_handle d_readerRequestGetHandle (d_readerRequest request); + +c_long d_readerRequestCompare (d_readerRequest request1, + d_readerRequest request2); + +void d_readerRequestFree (d_readerRequest request); + +c_bool d_readerRequestAddChain (d_readerRequest request, + d_chain chain); + +c_bool d_readerRequestRemoveChain (d_readerRequest request, + d_chain chain); + +c_bool d_readerRequestHasChains (d_readerRequest request); + +c_bool d_readerRequestAreGroupsComplete (d_readerRequest request); + +c_bool d_readerRequestAddGroup (d_readerRequest request, + d_group group); + +d_table d_readerRequestGetGroups (d_readerRequest request); + +void d_readerRequestRemoveGroup (d_readerRequest request, + d_group group); + +void d_readerRequestPrint (d_readerRequest request); + +void d_readerRequestSetGroupIgnored (d_readerRequest request); + +c_bool d_readerRequestGetGroupIgnored (d_readerRequest request); + +#if defined (__cplusplus) +} +#endif + +#endif /* D__READERREQUEST_H */ diff --git a/src/services/durability/code/d__remoteReaderListener.h b/src/services/durability/code/d__remoteReaderListener.h new file mode 100644 index 000000000..4ae40ecbc --- /dev/null +++ b/src/services/durability/code/d__remoteReaderListener.h @@ -0,0 +1,39 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef D__REMOTE_READER_LISTENER_H +#define D__REMOTE_READER_LISTENER_H + +#include "d__types.h" + +#if defined (__cplusplus) +extern "C" { +#endif + +d_remoteReaderListener d_remoteReaderListenerNew (d_subscriber subscriber); +void d_remoteReaderListenerFree (d_remoteReaderListener listener); +c_bool d_remoteReaderListenerStop (d_remoteReaderListener listener); +c_bool d_remoteReaderListenerStart (d_remoteReaderListener listener); +void d_remoteReaderListenerCheckReaders (d_remoteReaderListener listener); + +#if defined (__cplusplus) +} +#endif + +#endif /* D__REMOTE_READER_LISTENER_H */ + diff --git a/src/services/durability/code/d__sampleChainListener.h b/src/services/durability/code/d__sampleChainListener.h new file mode 100644 index 000000000..aa1ff6c42 --- /dev/null +++ b/src/services/durability/code/d__sampleChainListener.h @@ -0,0 +1,79 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef D__SAMPLECHAINLISTENER_H +#define D__SAMPLECHAINLISTENER_H + +#include "d__types.h" + +#if defined (__cplusplus) +extern "C" { +#endif + +/** + * \brief The d_chain cast macro. + * + * This macro casts an object to a d_chain object. + */ +#define d_chain(_this) ((d_chain)(_this)) + +/** + * Macro that checks the d_chain validity. + * Because d_chain is a concrete class typechecking is required. + */ +#define d_chainIsValid(_this) \ + d_objectIsValid(d_object(_this), D_CHAIN) + +/** + * Macro that checks the d_sampleChainListener validity. + * Because d_sampleChainListener is a concrete class typechecking is required. + */ +#define d_sampleChainListenerIsValid(_this) \ + d_listenerIsValidKind(d_listener(_this), D_SAMPLE_CHAIN_LISTENER) + +d_sampleChainListener d_sampleChainListenerNew (d_subscriber subscriber); +void d_sampleChainListenerFree (d_sampleChainListener listener); +c_bool d_sampleChainListenerStart (d_sampleChainListener listener); +c_bool d_sampleChainListenerStop (d_sampleChainListener listener); +c_bool d_sampleChainListenerCheckChainComplete (d_sampleChainListener listener, + d_chain chain); +void d_sampleChainListenerInsertRequest (d_sampleChainListener listener, + d_chain chain, + c_bool reportGroupWhenUnfullfilled); +c_bool d_sampleChainListenerInsertMergeAction (d_sampleChainListener listener, + d_mergeAction action); +void d_sampleChainListenerTryFulfillChains (d_sampleChainListener listener, + d_group group); +void d_sampleChainListenerReportStatus (d_sampleChainListener listener); +void d_sampleChainListenerReportGroup (d_sampleChainListener listener, + d_group group); +void d_sampleChainListenerCheckUnfulfilled (d_sampleChainListener listener, + d_nameSpace nameSpace, + d_networkAddress fellowAddress); +void d_traceChain (d_chain chain); +int d_chainCompare (d_chain chain1, + d_chain chain2); +d_chain d_chainNew (d_admin admin, + d_sampleRequest request); +void d_chainFree (d_chain chain); + +#if defined (__cplusplus) +} +#endif + +#endif /* D__SAMPLECHAINLISTENER_H */ diff --git a/src/services/durability/code/d__sampleRequestListener.h b/src/services/durability/code/d__sampleRequestListener.h new file mode 100644 index 000000000..28552dc30 --- /dev/null +++ b/src/services/durability/code/d__sampleRequestListener.h @@ -0,0 +1,39 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef D__SAMPLEREQUESTLISTENER_H +#define D__SAMPLEREQUESTLISTENER_H + +#include "d__types.h" + +#if defined (__cplusplus) +extern "C" { +#endif + +C_CLASS(d_sampleRequestHelper); + +d_sampleRequestListener d_sampleRequestListenerNew (d_subscriber subscriber); +void d_sampleRequestListenerFree (d_sampleRequestListener listener); +c_bool d_sampleRequestListenerStart (d_sampleRequestListener listener); +c_bool d_sampleRequestListenerStop (d_sampleRequestListener listener); + +#if defined (__cplusplus) +} +#endif + +#endif /* D__SAMPLEREQUESTLISTENER_H */ diff --git a/src/services/durability/code/d__statistics.h b/src/services/durability/code/d__statistics.h new file mode 100644 index 000000000..4c7ca4b1e --- /dev/null +++ b/src/services/durability/code/d__statistics.h @@ -0,0 +1,171 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#ifndef D__STATISTICS_H +#define D__STATISTICS_H + +#include "d__types.h" +#include "v_durabilityStatistics.h" + +#if defined (__cplusplus) +extern "C" { +#endif + +/** + * Macro that checks the d_aligneeStatistics validity. + * Because d_aligneeStatistics is a concrete class typechecking is required. + */ +#define d_aligneeStatisticsIsValid(_this) \ + d_objectIsValid(d_object(_this), D_ALIGNEE_STATS) + +/** + * \brief The d_aligneeStatistics cast method. + * + * This method casts an object to a d_aligneeStatistics object. + */ +#define d_aligneeStatistics(_this) ((d_aligneeStatistics)(_this)) + +C_STRUCT(d_aligneeStatistics){ + C_EXTENDS(d_object); + c_ulong aligneeRequestsWaiting; + c_ulong aligneeRequestsSentDif; + c_long aligneeRequestsOpenDif; + c_ulong aligneeSamplesTotalDif; + c_ulong aligneeSamplesRegisterDif; + c_ulong aligneeSamplesWriteDif; + c_ulong aligneeSamplesDisposeDif; + c_ulong aligneeSamplesWriteDisposeDif; + c_ulong aligneeSamplesUnregisterDif; + c_ulong aligneeTotalSizeDif; +}; + +d_aligneeStatistics d_aligneeStatisticsNew (); + +void d_aligneeStatisticsDeinit (d_aligneeStatistics stats); + +void d_aligneeStatisticsFree (d_aligneeStatistics stats); + +/** + * Macro that checks the d_alignerStatistics validity. + * Because d_alignerStatistics is a concrete class typechecking is required. + */ +#define d_alignerStatisticsIsValid(_this) \ + d_objectIsValid(d_object(_this), D_ALIGNER_STATS) + +/** + * \brief The d_alignerStatistics cast macro. + * + * This macro casts an object to a d_alignerStatistics object. + */ +#define d_alignerStatistics(_this) ((d_alignerStatistics)(_this)) + +C_STRUCT(d_alignerStatistics){ + C_EXTENDS(d_object); + c_ulong alignerRequestsReceivedDif; + c_ulong alignerRequestsIgnoredDif; + c_ulong alignerRequestsAnsweredDif; + c_long alignerRequestsOpenDif; + c_ulong alignerRequestsCombinedDif; + c_long alignerRequestsCombinedOpenDif; + c_ulong alignerRequestsCombinedAnsweredDif; + c_ulong alignerSamplesTotalDif; + c_ulong alignerSamplesRegisterDif; + c_ulong alignerSamplesWriteDif; + c_ulong alignerSamplesDisposeDif; + c_ulong alignerSamplesWriteDisposeDif; + c_ulong alignerSamplesUnregisterDif; + c_ulong alignerTotalSizeDif; +}; + + +d_alignerStatistics d_alignerStatisticsNew (); + +void d_alignerStatisticsDeinit (d_alignerStatistics stats); + +void d_alignerStatisticsFree (d_alignerStatistics stats); + + +typedef enum d_adminStatisticsInfoKind { + D_ADMIN_STATISTICS_FELLOW, + D_ADMIN_STATISTICS_GROUP +} d_adminStatisticsInfoKind; + +/** + * Macro that checks the d_adminStatisticsInfo validity. + * Because d_adminStatisticsInfo is a concrete class typechecking is required. + */ +#define d_adminStatisticsInfoIsValid(_this) \ + d_objectIsValid(d_object(_this), D_ADMIN_STATS_INFO) + +/** + * \brief The d_adminStatisticsInfo cast macro. + * + * This macro casts an object to a d_adminStatisticsInfo object. + */ +#define d_adminStatisticsInfo(_this) ((d_adminStatisticsInfo)(_this)) + +C_STRUCT(d_adminStatisticsInfo) { + C_EXTENDS(d_object); + d_adminStatisticsInfoKind kind; + c_long fellowsKnownDif; + c_long fellowsApprovedDif; + c_long fellowsIncompatibleStateDif; + c_long fellowsIncompatibleDataModelDif; + + c_long groupsKnownVolatileDif; + c_long groupsKnownTransientDif; + c_long groupsKnownPersistentDif; + + c_long groupsCompleteVolatileDif; + c_long groupsCompleteTransientDif; + c_long groupsCompletePersistentDif; + + c_long groupsIncompleteVolatileDif; + c_long groupsIncompleteTransientDif; + c_long groupsIncompletePersistentDif; + + c_long groupsIgnoredVolatileDif; + c_long groupsIgnoredTransientDif; + c_long groupsIgnoredPersistentDif; +}; + +d_adminStatisticsInfo d_adminStatisticsInfoNew (); + +void d_adminStatisticsInfoDeinit (d_adminStatisticsInfo info); + +void d_adminStatisticsInfoFree (d_adminStatisticsInfo info); + +void d_statisticsUpdateAlignee (v_durabilityStatistics s, + c_voidp args); + +void d_statisticsUpdateAligner (v_durabilityStatistics ds, + c_voidp args); + +void d_statisticsUpdateAdmin (v_durabilityStatistics statistics, + c_voidp args); + +void d_statisticsUpdateConfiguration (v_durabilityStatistics statistics, + c_voidp args); + +void d_statisticsUpdateGroupsToCreate (v_durabilityStatistics ds, + c_voidp args); + +#if defined (__cplusplus) +} +#endif + +#endif /* D__STATISTICS_H */ diff --git a/src/services/durability/code/d__statusListener.h b/src/services/durability/code/d__statusListener.h new file mode 100644 index 000000000..dd2669f54 --- /dev/null +++ b/src/services/durability/code/d__statusListener.h @@ -0,0 +1,38 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef D__STATUSLISTENER_H +#define D__STATUSLISTENER_H + +#include "d__types.h" +#include "d__readerListener.h" + +#if defined (__cplusplus) +extern "C" { +#endif + +d_statusListener d_statusListenerNew (d_subscriber subscriber); +void d_statusListenerFree (d_statusListener listener); +c_bool d_statusListenerStart (d_statusListener listener); +c_bool d_statusListenerStop (d_statusListener listener); + +#if defined (__cplusplus) +} +#endif + +#endif /* D__STATUSLISTENER_H */ diff --git a/src/services/durability/code/d__store.h b/src/services/durability/code/d__store.h new file mode 100644 index 000000000..bc14c4ae3 --- /dev/null +++ b/src/services/durability/code/d__store.h @@ -0,0 +1,160 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef D__STORE_H +#define D__STORE_H + +#include "d__types.h" +#include "d__lock.h" +#include "d__groupHash.h" +#include "d__misc.h" +#include "u_participant.h" + +#if defined (__cplusplus) +extern "C" { +#endif + +void d_storeInit (d_store store, d_objectDeinitFunc deinit); + +void d_storeDeinit (d_store store); + +typedef d_storeResult (*d_storeOpenFunc) (d_store store); + +typedef d_storeResult (*d_storeCloseFunc) (d_store store); + +typedef d_storeResult (*d_storeGroupsReadFunc) (const d_store store, + d_groupList *list); + +typedef d_storeResult (*d_storeGroupListFreeFunc) (const d_store store, + d_groupList list); + +typedef d_storeResult (*d_storeActionStartFunc) (const d_store store); + +typedef d_storeResult (*d_storeActionStopFunc) (const d_store store); + +typedef d_storeResult (*d_storeGroupInjectFunc) (const d_store store, + const c_char* partition, + const c_char* topic, + const u_participant participant, + d_group *group); + +typedef d_storeResult (*d_storeGroupStoreFunc) (const d_store store, + const d_group group, + const d_nameSpace nameSpace); + +typedef d_storeResult (*d_storeGetQualityFunc) (const d_store store, + const d_nameSpace nameSpace, + d_quality* quality); + +typedef d_storeResult (*d_storeBackupFunc) (const d_store store, + const d_nameSpace nameSpace); + +typedef d_storeResult (*d_storeRestoreBackupFunc) (const d_store store, + const d_nameSpace nameSpace); + +typedef d_storeResult (*d_storeMessageStoreFunc) (const d_store store, + const v_groupAction message); + +typedef d_storeResult (*d_storeInstanceDisposeFunc) (const d_store store, + const v_groupAction message); + +typedef d_storeResult (*d_storeInstanceExpungeFunc) (const d_store store, + const v_groupAction message); + +typedef d_storeResult (*d_storeMessageExpungeFunc) (const d_store store, + const v_groupAction message); + +typedef d_storeResult (*d_storeDeleteHistoricalDataFunc) (const d_store store, + const v_groupAction message); + +typedef d_storeResult (*d_storeMessagesInjectFunc) (const d_store store, + const d_group group); + +typedef d_storeResult (*d_storeInstanceRegisterFunc) (const d_store store, + const v_groupAction message); + +typedef d_storeResult (*d_storeInstanceUnregisterFunc) (const d_store store, + const v_groupAction message); + +typedef d_storeResult (*d_storeCreatePersistentSnapshotFunc)(const d_store store, + const os_char* partitionExpr, + const os_char* topicExpr, + const os_char* uri); + +typedef d_storeResult (*d_storeOptimizeGroupFunc) (const d_store store, + const d_group group); + +typedef d_storeResult (*d_storeNsIsCompleteFunc) (const d_store store, + const d_nameSpace nameSpace, + c_bool* isComplete); + +typedef d_storeResult (*d_storeNsMarkCompleteFunc) (const d_store store, + const d_nameSpace nameSpace, + c_bool isComplete); + +typedef d_storeResult (*d_storeTransactionCompleteFunc) (const d_store store, + const v_groupAction message); + +typedef d_storeResult (*d_storeMessagesLoadFunc) (const d_store store, + const d_group group, + struct d_groupHash *groupHash); + +typedef d_storeResult (*d_storeMessagesLoadFlushFunc) (const d_store store, + const d_group group, + c_bool inject); + +C_STRUCT(d_store){ + C_EXTENDS(d_lock); + d_admin admin; + d_configuration config; + d_storeType type; + + d_storeOpenFunc openFunc; + d_storeCloseFunc closeFunc; + + d_storeActionStartFunc actionStartFunc; + d_storeActionStopFunc actionStopFunc; + d_storeGetQualityFunc getQualityFunc; + d_storeBackupFunc backupFunc; + d_storeRestoreBackupFunc restoreBackupFunc; + d_storeGroupsReadFunc groupsReadFunc; + d_storeGroupListFreeFunc groupListFreeFunc; + d_storeGroupStoreFunc groupStoreFunc; + d_storeGroupInjectFunc groupInjectFunc; + d_storeMessageStoreFunc messageStoreFunc; + d_storeInstanceDisposeFunc instanceDisposeFunc; + d_storeInstanceExpungeFunc instanceExpungeFunc; + d_storeMessageExpungeFunc messageExpungeFunc; + d_storeDeleteHistoricalDataFunc deleteHistoricalDataFunc; + d_storeMessagesInjectFunc messagesInjectFunc; + d_storeInstanceRegisterFunc instanceRegisterFunc; + d_storeInstanceUnregisterFunc instanceUnregisterFunc; + d_storeCreatePersistentSnapshotFunc createPersistentSnapshotFunc; + d_storeOptimizeGroupFunc optimizeGroupFunc; + d_storeNsIsCompleteFunc nsIsCompleteFunc; + d_storeNsMarkCompleteFunc nsMarkCompleteFunc; + d_storeTransactionCompleteFunc transactionCompleteFunc; + d_storeMessagesLoadFunc messagesLoadFunc; + d_storeMessagesLoadFlushFunc messagesLoadFlushFunc; +}; + +#if defined (__cplusplus) +} +#endif + +#endif /* D__STORE_H */ diff --git a/src/services/durability/code/d__storeXML.h b/src/services/durability/code/d__storeXML.h new file mode 100644 index 000000000..f1a17e431 --- /dev/null +++ b/src/services/durability/code/d__storeXML.h @@ -0,0 +1,195 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#ifndef D__STOREXML_H +#define D__STOREXML_H + +#include "d__types.h" +#include "d__store.h" +#include "d_store.h" + +#if defined (__cplusplus) +extern "C" { +#endif + +#define EXTRA_BACKSLS (4) +#define EXTRA_BACKSLS_U (4U) +#define MAX_MESSAGE_SIZE (10485760) +#define MAX_KEY_SIZE (8192) +#define D_PERSISTENT_STORE_DIR_SIZE (512) +#define RR_NO_DIRECTORY "No PersistentStoreDirectory found in URI. "\ + "No persistent service possible!\n" +#define RR_TOPIC_SHOULD_BEGIN_WITH_TOPIC_TAG " topic '%s' should begin with topic tag\n" +#define RR_META_DATA_MISMATCH " Could not read topic from disk '%s' meta data does not match\n" +#define RR_COULD_NOT_PROTECT " Could not Protect ('%s')\n" +#define RR_COULD_NOT_WRITE_META_DATA " Could not write meta data to disk '%s'\n" +#define RR_STORE_MODE_NOT_YET_SUPPORTED " storeMode '%s' not yet supported\n" +#define RR_CREATE_GROUP_FAILED " createGroup '%s'.'%s' failed\n" +#define RR_UNKNOWN_STORE_MODE " unknown storeMode\n" +#define RR_COULD_NOT_OPEN_STOREPATH "Could not open persistent store path '%s'\n" +#define RR_COULD_NOT_MAKE_STOREDIR "Failed to make storeDirectory '%s'\n" + +#define RR_COULD_NOT_WRITE_TOPIC "Could not write topic '%s' to disk" +#define RR_COULD_NOT_WRITE__TOPIC_NOT_FOUND \ + "Could not write topic '%s' to disk (TOPIC not found)\n" +#define RR_COULD_NOT_READ_TOPIC " Could not read topic '%s' from disk" +#define RR_TOPIC_TAG_MISSING_IN_FILE \ + "Could not read topic '%s' from disk, TOPIC tag missing in file\n" +#define RR_TOPIC_TAG_MISSING \ + "Could not read topic '%s' from disk, TOPIC tag missing in backup file \n" +#define RR_TOPIC_TAG_ALSO_MISSING_IN_BACKUP_FILE \ + "Could not read topic '%s' from disk, TOPIC tag also missing in backup file \n" +#define RR_COULD_NOT_READ_TOPIC__MISSING_TAG \ + "Could not read topic '%s' from disk, TOPIC tag missing using backup file \n" +#define RR_TOPIC_NOT_YET_KNOWN \ + "Could not read topic '%s' from disk: not yet know by persistent service\n" +#define RR_TOPIC_FILESIZE_INVALID \ + "Could not read topic '%s' from disk: file size invalid\n" + +#define STORE_READ_TOPIC_XML "persistentStoreReadTopicXML" +#define STORE_STORE_TOPIC_XML "persistentStoreStoreTopicXML" +#define STORE_GET_SERIALIZED_DATA "persistentStoreGetSerializedData" +#define STORE_STORE_TOPIC "persistentStoreStoreTopic" + + +#define STRLEN_BACKSLASH_N ((os_uint32)(2)) +#define STRLEN_NEEDED_FOR_A_BIG_TAG ((os_uint32)(13)) /* adapt for a bigger */ + +#define DOT_XML "_meta.xml" +#define STRLEN_DOT_XML ((os_uint32)(9)) +#define DOT_SAVED ".saved" +#define STRLEN_DOT_SAVED ((os_uint32)(6)) +#define TOPIC_TAG_OPEN "" +#define STRLEN_TOPIC_TAG_OPEN ((os_uint32)(10)) +#define TOPIC_TAG_CLOSE "" +#define STRLEN_TOPIC_TAG_CLOSE ((os_uint32)(11)) + +#define KEY_START_TAG "" +#define KEY_END_TAG "" +#define D_STORE_VERSION (6) +#define D_STORE_START_STRING "Do_not_edit_this_file\n" +#define D_STORE_END_STRING "\n" +#define D_STORE_END_STRING_NO_NL "" + + +C_CLASS(d_storeFile); + +C_STRUCT(d_storeFile){ + c_char* path; + FILE* fdes; + c_char* mode; +}; + +#define d_storeFile(t) ((d_storeFile)(t)) + +C_STRUCT(d_storeXML){ + C_EXTENDS(d_store); + c_bool opened; + d_groupList groups; + c_ulong maxPathLen; + c_char* diskStorePath; + c_bool sessionAlive; + d_table openedFiles; + d_storeFile dummyFile; + c_char* dataBuffer; + c_char* keyBuffer; + d_table expungeActions; + os_mutex mutex; +}; + +void d_storeDeinitXML (d_storeXML store); + +d_storeXML d_storeNewXML (u_participant participant); + +d_storeResult d_storeFreeXML (d_storeXML store); + +d_storeResult d_storeOpenXML (d_store store); + +d_storeResult d_storeCloseXML (d_store store); + +d_storeResult d_storeActionStartXML (const d_store store); + +d_storeResult d_storeActionStopXML (const d_store store); + +d_storeResult d_storeGetQualityXML (const d_store store, + const d_nameSpace nameSpace, + d_quality* quality); + +d_storeResult d_storeBackupXML (const d_store store, + const d_nameSpace nameSpace); + +d_storeResult d_storeRestoreBackupXML (const d_store store, + const d_nameSpace nameSpace); + +d_storeResult d_storeGroupsReadXML (const d_store store, + d_groupList *list); + +d_storeResult d_storeGroupInjectXML (const d_store store, + const c_char* partition, + const c_char* topic, + const u_participant participant, + d_group *group); + +d_storeResult d_storeGroupStoreXML (const d_store store, + const d_group group, + const d_nameSpace nameSpace); + +d_storeResult d_storeMessageStoreXML (const d_store store, + const v_groupAction message); + +d_storeResult d_storeInstanceDisposeXML (const d_store store, + const v_groupAction message); + +d_storeResult d_storeInstanceExpungeXML (const d_store store, + const v_groupAction message); + +d_storeResult d_storeMessageExpungeXML (const d_store store, + const v_groupAction message); + +d_storeResult d_storeDeleteHistoricalDataXML (const d_store store, + const v_groupAction message); + +d_storeResult d_storeMessagesInjectXML (const d_store store, + const d_group group); + +d_storeResult d_storeInstanceRegisterXML (const d_store store, + const v_groupAction message); + +d_storeResult d_storeCreatePersistentSnapshotXML (const d_store store, + const c_char* partitionExpr, + const c_char* topicExpr, + const c_char* uri); + +d_storeResult d_storeInstanceUnregisterXML (const d_store store, + const v_groupAction message); + +d_storeResult d_storeOptimizeGroupXML (const d_store store, + const d_group group); + +d_storeResult d_storeNsIsCompleteXML (const d_store store, + const d_nameSpace nameSpace, + c_bool* isComplete); + +d_storeResult d_storeNsMarkCompleteXML (const d_store store, + const d_nameSpace nameSpace, + c_bool isComplete); + +#if defined (__cplusplus) +} +#endif + +#endif /*D__STOREXML_H*/ diff --git a/src/services/durability/code/d__subscriber.h b/src/services/durability/code/d__subscriber.h new file mode 100644 index 000000000..afb8e1ae0 --- /dev/null +++ b/src/services/durability/code/d__subscriber.h @@ -0,0 +1,107 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef D__SUBSCRIBER_H +#define D__SUBSCRIBER_H + +#include "d__types.h" +#include "u_user.h" + +#if defined (__cplusplus) +extern "C" { +#endif + +/** + * Macro that checks the d_subscriber validity. + * Because d_subscriber is a concrete class typechecking is required. + */ +#define d_subscriberIsValid(_this) \ + d_objectIsValid(d_object(_this), D_SUBSCRIBER) + +/** + * \brief The d_subscriber cast macro. + * + * This macro casts an object to a d_subscriber object. + */ +#define d_subscriber(_this) ((d_subscriber)(_this)) + +C_STRUCT(d_subscriber){ + C_EXTENDS(d_object); + d_admin admin; + u_subscriber subscriber; /* subscriber for durability protocol */ + u_subscriber subscriber2; /* subscriber for client-side durability protocol */ + u_subscriber builtinSubscriber; /* builtin subscriber */ + u_subscriber persistentSubscriber; + d_waitset waitset; + + d_statusListener statusListener; + d_groupRemoteListener groupRemoteListener; + d_groupLocalListener groupLocalListener; + d_groupsRequestListener groupsRequestListener; + d_sampleRequestListener sampleRequestListener; + d_sampleChainListener sampleChainListener; + d_nameSpacesRequestListener nameSpacesRequestListener; + d_nameSpacesListener nameSpacesListener; + d_persistentDataListener persistentDataListener; + d_deleteDataListener deleteDataListener; + d_remoteReaderListener remoteReaderListener; + d_dcpsHeartbeatListener dcpsHeartbeatListener; + d_historicalDataRequestListener historicalDataRequestListener; + d_durabilityStateRequestListener durabilityStateRequestListener; + d_dcpsPublicationListener dcpsPublicationListener; + d_capabilityListener capabilityListener; + + d_store persistentStore; +}; + + +d_subscriber d_subscriberNew (d_admin admin); + +void d_subscriberDeinit (d_subscriber subscriber); + +void d_subscriberFree (d_subscriber subscriber); + +d_admin d_subscriberGetAdmin (d_subscriber subscriber); + +u_subscriber d_subscriberGetSubscriber (d_subscriber subscriber); + +d_waitset d_subscriberGetWaitset (d_subscriber subscriber); + +u_subscriber d_subscriberGetPersistentSubscriber (d_subscriber subscriber); + +c_bool d_subscriberStartListeners (d_subscriber subscriber); + +void d_subscriberStopListeners (d_subscriber subscriber); + +d_store d_subscriberGetPersistentStore (d_subscriber subscriber); + +c_bool d_subscriberAreRemoteGroupsHandled (d_subscriber subscriber); + +d_groupLocalListener d_subscriberGetGroupLocalListener (d_subscriber subscriber); + +d_sampleChainListener d_subscriberGetSampleChainListener (d_subscriber subscriber); + +d_nameSpacesRequestListener d_subscriberGetNameSpacesRequestListener (d_subscriber subscriber); + +d_historicalDataRequestListener d_subscriberGetHistoricalDataRequestListener(d_subscriber subscriber); + +#if defined (__cplusplus) +} +#endif + +#endif /* D__SUBSCRIBER_H */ diff --git a/src/services/durability/code/d__table.h b/src/services/durability/code/d__table.h new file mode 100644 index 000000000..644fbda0e --- /dev/null +++ b/src/services/durability/code/d__table.h @@ -0,0 +1,105 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#ifndef D__TABLE_H +#define D__TABLE_H + +#include "d__types.h" +#include "ut_avl.h" + +#if defined (__cplusplus) +extern "C" { +#endif + +/** + * Macro that checks the d_table validity. + * Because d_table is a concrete class typechecking is required. + */ +#define d_tableIsValid(_this) \ + d_objectIsValid(d_object(_this), D_TABLE) + +/** + * \brief The d_table cast macro. + * + * This macro casts an object to a d_table object. + */ +#define d_table(_this) ((d_table)(_this)) + +C_STRUCT(d_tableNode) { + ut_avlNode_t avlnode; + void *object; +}; +C_CLASS(d_tableNode); + +C_STRUCT(d_table) { + C_EXTENDS(d_object); + void ( * cleanAction) (); /**< the user's cleanup action */ + ut_avlCTreedef_t td; + ut_avlCTree_t tree; +}; + + +typedef struct { + ut_avlCIter_t it; +} d_tableIter; + + +d_table d_tableNew (int ( * compare )(), + void ( * cleanAction )() ); + +void d_tableFree (d_table table); + +void d_tableDeinit (d_table table); + +/** returns zero if the entry is added */ +c_voidp d_tableInsert (d_table table, + c_voidp object ); + +/** returns non-zero (the data) if the entry is removed */ +c_voidp d_tableRemove (d_table table, + c_voidp arg); + +/** returns non-zero (the data) if the entry is taken */ +c_voidp d_tableTake (d_table table); + +/** returns non-zero (the data) if the entry is found */ +c_voidp d_tableFind (d_table table, + c_voidp arg ); + +/** returns non-zero (the data) if the entry is found */ +/** returns non-zero (the data) if an entry is found */ +c_voidp d_tableFirst (d_table table); + +/** returns non-zero (the data) if an entry is taken */ +c_bool d_tableWalk (d_table table, + c_bool ( * action ) (), + c_voidp userData); + +c_ulong d_tableSize (d_table table); + +/** Iterator for d_table */ +void * d_tableIterFirst (d_table table, + d_tableIter *iter); + +void * d_tableIterNext (d_tableIter *iter); + + +#if defined (__cplusplus) +} +#endif + +#endif /* D__TABLE_H */ diff --git a/src/services/durability/code/d__thread.h b/src/services/durability/code/d__thread.h new file mode 100644 index 000000000..6c9da0992 --- /dev/null +++ b/src/services/durability/code/d__thread.h @@ -0,0 +1,46 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#ifndef D_THREAD_H +#define D_THREAD_H + +#include "os_defs.h" +#include "ut_thread.h" + +typedef ut_thread d_thread; + +os_result d_threadsInit (d_durability durability); +d_durability d_threadsDurability(); +void d_threadsDeinit (void); +os_result d_threadCreate (os_threadId *threadId, const char *name, const os_threadAttr *threadAttr, os_threadRoutine start_routine, void *arg); +d_thread d_threadLookupId (os_threadId tid); +d_thread d_threadLookupSelf (void); +os_result d_threadWaitExit (os_threadId threadId, void **thread_result); + +#define d_threadAsleep(thr, sleep_secs) ut_threadAsleep((ut_thread)thr, sleep_secs) +#define d_threadAwake(thr) (thr?ut_threadAwake((ut_thread)thr):(void)0) +#define d_sleep(thr, d) ut_sleep((ut_thread)thr, d) +#define d_condWait(thr, cv, mtx) ut_condWait((ut_thread)thr, cv, mtx) +#define d_condTimedWait(thr, cv, mtx, d) ut_condTimedWait((ut_thread)thr, cv, mtx, d) + +#define d_threadName(thr) (thr?ut_threadGetName((ut_thread)thr):"anonimous") +const char* d_threadSelfName(); + +void d_threadLivelinessInit (os_duration min_intv); +os_boolean d_threadLivelinessCheck (os_timeM currentTime, os_duration updateInterval); + +#endif /* D_THREAD_H */ diff --git a/src/services/durability/code/d__types.h b/src/services/durability/code/d__types.h new file mode 100644 index 000000000..78a7f8a39 --- /dev/null +++ b/src/services/durability/code/d__types.h @@ -0,0 +1,157 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef D__TYPES_H +#define D__TYPES_H + +#include "c_typebase.h" +#include "kernelModuleI.h" +#include "durabilityModule2.h" +#include "client_durabilitySplType.h" +#include "d_object.h" + +#if defined (__cplusplus) +extern "C" { +#endif + +typedef enum d_storeType{ + D_STORE_TYPE_UNKNOWN, + D_STORE_TYPE_XML, + D_STORE_TYPE_BIG_ENDIAN, + D_STORE_TYPE_MEM_MAPPED_FILE, /* obsolete */ + D_STORE_TYPE_KV +} d_storeType; + +typedef enum d_storeResult{ + D_STORE_RESULT_ERROR, D_STORE_RESULT_OK, + D_STORE_RESULT_ILL_PARAM, D_STORE_RESULT_UNSUPPORTED, + D_STORE_RESULT_PRECONDITION_NOT_MET, D_STORE_RESULT_IO_ERROR, + D_STORE_RESULT_MUTILATED, D_STORE_RESULT_DROPPED, + D_STORE_RESULT_REJECTED_BY_INSTANCE, D_STORE_RESULT_REJECTED_BY_SAMPLE, + D_STORE_RESULT_REJECTED_BY_SAMPLE_PER_INSTANCE, + D_STORE_RESULT_METADATA_MISMATCH, D_STORE_RESULT_OUT_OF_RESOURCES +} d_storeResult; + +typedef enum d_level { + D_LEVEL_FINEST, D_LEVEL_FINER, D_LEVEL_FINE, + D_LEVEL_CONFIG, D_LEVEL_INFO, + D_LEVEL_WARNING, D_LEVEL_SEVERE, D_LEVEL_NONE +} d_level; + +C_CLASS(d_durability); +C_CLASS(d_configuration); +C_CLASS(d_nameSpace); +C_CLASS(d_policy); +C_CLASS(d_element); +C_CLASS(d_table); +C_CLASS(d_group); +C_CLASS(d_fellow); +C_CLASS(d_admin); +C_CLASS(d_publisher); +C_CLASS(d_subscriber); +C_CLASS(d_waitset); +C_CLASS(d_waitsetEntity); +C_CLASS(d_listener); +C_CLASS(d_readerListener); +C_CLASS(d_statusListener); +C_CLASS(d_groupLocalListener); +C_CLASS(d_groupRemoteListener); +C_CLASS(d_groupsRequestListener); +C_CLASS(d_sampleRequestListener); +C_CLASS(d_sampleChainListener); +C_CLASS(d_nameSpacesRequestListener); +C_CLASS(d_nameSpacesListener); +C_CLASS(d_persistentDataListener); +C_CLASS(d_deleteDataListener); +C_CLASS(d_eventListener); +C_CLASS(d_groupList); +C_CLASS(d_store); +C_CLASS(d_storeXML); +C_CLASS(d_storeKV); +C_CLASS(d_action); +C_CLASS(d_actionQueue); +C_CLASS(d_groupCreationQueue); +C_CLASS(d_chain); +C_CLASS(d_chainBead); +C_CLASS(d_chainLink); +C_CLASS(d_readerRequest); +C_CLASS(d_mergeAction); +C_CLASS(d_remoteReaderListener); +C_CLASS(d_conflict); +C_CLASS(d_conflictMonitor); +C_CLASS(d_conflictResolver); +C_CLASS(d_aligneeStatistics); +C_CLASS(d_alignerStatistics); +C_CLASS(d_adminStatisticsInfo); +C_CLASS(d_lock); +C_CLASS(d_dcpsHeartbeatListener); +C_CLASS(d_filter); +C_CLASS(d_dcpsPublicationListener); +C_CLASS(d_capabilityListener); + +/** + * The following definitions make "classes" of the + * structs for client-side durability. + */ +C_CLASS(d_historicalDataRequestListener); +C_CLASS(d_historicalDataRequest); +C_CLASS(d_historicalData); +C_CLASS(d_durabilityStateRequestListener); +C_CLASS(d_durabilityStateRequest); +C_CLASS(d_durabilityState); +C_CLASS(d_partitionTopicState); +C_CLASS(d_client); + +/** + * These definitions make "classes" of the odl-structs. + * This completes the 'struct'-definitions in 'durability.odl' + */ +C_CLASS(d_message); +C_CLASS(d_groupsRequest); +C_CLASS(d_sampleRequest); +C_CLASS(d_status); +C_CLASS(d_newGroup); +C_CLASS(d_sampleChain); +C_CLASS(d_networkAddress); +C_CLASS(d_nameSpaces); +C_CLASS(d_nameSpacesRequest); +C_CLASS(d_deleteData); +C_CLASS(d_mergeState); +C_CLASS(d_capability); + + +#define D_ARG_NAME "-name" +#define D_ARG_STRLEN_NAME ((size_t)(5)) +#define D_ARG_SERVICENAME "-servicename" +#define D_ARG_STRLEN_SERVICENAME ((size_t)(12)) +#define D_ARG_URI_START "file://" +#define D_ARG_STRLEN_URI_START ((size_t)(7)) +#define D_SERVICE_NAME "DurabilityService" +#define D_STRING_LENGTH_LIMIT (1024) +#define D_CONTEXT "DurabilityService" +#define D_CONFIDENCE ((c_ulong)0x4E614D65u) /* 'NaMe' */ +#define D_CONFIDENCE_NULL ((c_ulong)0x000000000) + +#define D_MAX_STRLEN_NAMESPACE (101) +#define D_MODULE_NAME "durabilityModule2" + +#if defined (__cplusplus) +} +#endif + +#endif /* D__TYPES_H */ diff --git a/src/services/durability/code/d__waitset.h b/src/services/durability/code/d__waitset.h new file mode 100644 index 000000000..67857e1b4 --- /dev/null +++ b/src/services/durability/code/d__waitset.h @@ -0,0 +1,111 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef D__WAITSET_H +#define D__WAITSET_H + +#include "d__types.h" +#include "d__lock.h" +#include "u_object.h" +#include "os_thread.h" + +#if defined (__cplusplus) +extern "C" { +#endif + +/* Prototype for d_waitsetAction function */ +typedef c_ulong (*d_waitsetAction)(u_object object, v_waitsetEvent event, c_voidp usrData); + +/** + * Macro that checks the d_waitset validity. + * Because d_waitset is a concrete class typechecking is required. + */ +#define d_waitsetIsValid(_this) \ + d_objectIsValid(d_object(_this), D_WAITSET) + +/** + * Macro that checks the d_waitsetEntity validity. + * Because d_waitsetEntity is a concrete class typechecking is required. + */ +#define d_waitsetEntityIsValid(_this) \ + d_objectIsValid(d_object(_this), D_WAITSET_ENTITY) + +/** + * \brief The d_waitset cast macro. + * + * This meacro casts an object to a d_waitset object. + */ +#define d_waitset(_this) ((d_waitset)(_this)) + +/** + * \brief The d_waitsetEntity cast macro. + * + * This macro casts an object to a d_waitsetEntity object. + */ +#define d_waitsetEntity(_this) ((d_waitsetEntity)(_this)) + +C_STRUCT(d_waitsetEntity) { + C_EXTENDS(d_object); + c_char* name; + d_waitset waitset; + u_object object; + c_ulong mask; + d_waitsetAction action; + os_threadAttr attr; + c_voidp usrData; +}; + +C_STRUCT(d_waitset) { + C_EXTENDS(d_lock); + c_bool terminate; + d_subscriber subscriber; + c_iter entities; + c_iter threads; +}; + +d_waitset d_waitsetNew (d_subscriber subscriber); + +void d_waitsetDeinit (d_waitset waitset); + +void d_waitsetFree (d_waitset waitset); + +c_bool d_waitsetAttach (d_waitset waitset, + d_waitsetEntity we); + +c_bool d_waitsetDetach (d_waitset waitset, + d_waitsetEntity we); + +d_subscriber d_waitsetGetSubscriber (d_waitset waitset); + +d_waitsetEntity d_waitsetEntityNew (const c_char* name, + u_object object, + d_waitsetAction action, + c_ulong mask, + os_threadAttr attr, + c_voidp usrData); + +void d_waitsetEntityDeinit (d_waitsetEntity waitsetEntity); + +void d_waitsetEntityFree (d_waitsetEntity we); + + +#if defined (__cplusplus) +} +#endif + +#endif /* D__WAITSET_H */ diff --git a/src/services/durability/code/d_actionQueue.c b/src/services/durability/code/d_actionQueue.c new file mode 100644 index 000000000..1183466f7 --- /dev/null +++ b/src/services/durability/code/d_actionQueue.c @@ -0,0 +1,321 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + + +#include "d__lock.h" +#include "d__actionQueue.h" +#include "d__thread.h" +#include "os_heap.h" +#include "os_time.h" +#include "os_stdlib.h" + +void* +d_actionQueueRun( + void* userData) +{ + d_thread self = d_threadLookupSelf (); + d_actionQueue queue; + d_action action; + c_bool result; + os_timeM curTime; + os_compare eq; + c_iter actions, redo; + + redo = c_iterNew(NULL); + actions = c_iterNew(NULL); + queue = d_actionQueue(userData); + + while(queue->terminate == FALSE) { + /** + * Copy the actions here to allow other threads to add actions during the + * execution of the actions. + */ + d_lockLock(d_lock(queue)); + action = d_action(c_iterTakeFirst(queue->actions)); + + while(action){ + actions = c_iterInsert(actions, action); + action = d_action(c_iterTakeFirst(queue->actions)); + } + d_lockUnlock(d_lock(queue)); + + action = d_action(c_iterTakeFirst(actions)); + + while(action && (queue->terminate == FALSE)){ + curTime = os_timeMGet(); + eq = os_timeMCompare(curTime, action->execTime); + + if(eq != OS_LESS) { + result = action->action(action, FALSE); + + if(result == FALSE) { + d_actionFree(action); + } else { + curTime = os_timeMGet(); + curTime = os_timeMAdd(curTime, action->sleepTime); + action->execTime = curTime; + redo = c_iterInsert(redo, action); + } + } else { + redo = c_iterInsert(redo, action); + } + action = d_action(c_iterTakeFirst(actions)); + } + + while(action){ /*in case of terminate*/ + redo = c_iterInsert(redo, action); + action = d_action(c_iterTakeFirst(actions)); + } + + c_iterFree(actions); + actions = redo; + redo = c_iterNew(NULL); + + if(queue->terminate == FALSE) { + d_sleep(self, queue->sleepTime); + } + } + action = d_action(c_iterTakeFirst(actions)); + + while(action) { + action->action(action, TRUE); + d_actionFree(action); + action = d_action(c_iterTakeFirst(actions)); + } + d_lockLock(d_lock(queue)); + action = d_action(c_iterTakeFirst(queue->actions)); + + while(action) { + action->action(action, TRUE); + d_actionFree(action); + action = d_action(c_iterTakeFirst(queue->actions)); + } + d_lockUnlock(d_lock(queue)); + c_iterFree(actions); + c_iterFree(redo); + + return NULL; +} + + +d_actionQueue +d_actionQueueNew( + const c_char* name, + os_duration sleepTime, + os_threadAttr attr) +{ + d_actionQueue queue; + os_result osr; + const c_char* actualName; + + /* Allocate actionQueue object */ + queue = d_actionQueue(os_malloc(C_SIZEOF(d_actionQueue))); + if (queue) { + /* Call super-init */ + d_lockInit(d_lock(queue), D_ACTION_QUEUE, + (d_objectDeinitFunc)d_actionQueueDeinit); + /* Initialize the actionQueue */ + if (queue) { + queue->actions = c_iterNew(NULL); + queue->remove = c_iterNew(NULL); + queue->sleepTime = sleepTime; + queue->terminate = FALSE; + queue->name = NULL; + if (name == NULL) { + actualName = "actionQueueThread"; + } else { + actualName = name; + } + queue->name = os_strdup(actualName); + osr = d_threadCreate(&queue->actionThread, actualName, + &attr, (void*(*)(void*))d_actionQueueRun, + (void*)queue); + if (osr != os_resultSuccess) { + d_actionQueueFree(queue); + queue = NULL; + } + } + } + return queue; +} + + +void +d_actionQueueDeinit( + d_actionQueue queue) +{ + assert(d_actionQueueIsValid(queue)); + + if (os_threadIdToInteger(queue->actionThread)) { + queue->terminate = TRUE; + d_threadWaitExit(queue->actionThread, NULL); + } + if (queue->actions) { + c_iterFree(queue->actions); + } + if (queue->remove) { + c_iterFree(queue->remove); + } + if (queue->name) { + os_free(queue->name); + } + /* Call super-deinit */ + d_lockDeinit(d_lock(queue)); +} + + +void +d_actionQueueFree( + d_actionQueue queue) +{ + assert(d_actionQueueIsValid(queue)); + + d_objectFree(d_object(queue)); +} + + +c_bool +d_actionQueueAdd( + d_actionQueue queue, + d_action action) +{ + c_bool result = FALSE; + + assert(d_actionQueueIsValid(queue)); + assert(d_actionIsValid(action)); + + d_lockLock(d_lock(queue)); + if (c_iterContains(queue->actions, action) == FALSE) { + queue->actions = c_iterInsert(queue->actions, action); + result = TRUE; + } + d_lockUnlock(d_lock(queue)); + + return result; +} + + +c_bool +d_actionQueueRemove( + d_actionQueue queue, + d_action action) +{ + c_bool result = FALSE; + + assert(d_actionQueueIsValid(queue)); + assert(d_actionIsValid(action)); + + d_lockLock(d_lock(queue)); + if (c_iterContains(queue->actions, action) == TRUE) { + c_iterTake(queue->actions, action); + result = TRUE; + } + d_lockUnlock(d_lock(queue)); + + return result; +} + + +d_action +d_actionNew( + os_timeM execTime, + os_duration sleepTime, + d_actionFunction actionFunc, + c_voidp args) +{ + d_action action; + + /* Allocate action object */ + action = d_action(os_malloc(C_SIZEOF(d_action))); + if (action) { + /* Call super-init */ + d_objectInit(d_object(action), D_ACTION, + (d_objectDeinitFunc)d_actionDeinit); + /* Initialize the action */ + if (action) { + action->execTime = execTime; + action->sleepTime = sleepTime; + action->action = actionFunc; + action->args = args; + } + } + return action; +} + + +void +d_actionDeinit( + d_action action) +{ + assert(d_actionIsValid(action)); + + /* Nothing to deallocate */ + /* Call super-deinit */ + d_objectDeinit(d_object(action)); +} + + +void +d_actionFree( + d_action action) +{ + assert(d_actionIsValid(action)); + + d_objectFree(d_object(action)); +} + + +c_voidp +d_actionGetArgs( + d_action action) +{ + assert(d_actionIsValid(action)); + + return action->args; +} + + +os_timeM +d_actionGetExecTime( + d_action action) +{ + assert(d_actionIsValid(action)); + + return action->execTime; +} + + +os_duration +d_actionGetSleepTime( + d_action action) +{ + assert(d_actionIsValid(action)); + + return action->sleepTime; +} + + +void +d_actionSetSleepTime( + d_action action, + os_duration sleepTime) +{ + assert(d_actionIsValid(action)); + + action->sleepTime = sleepTime; +} diff --git a/src/services/durability/code/d_admin.c b/src/services/durability/code/d_admin.c new file mode 100644 index 000000000..6e7986c27 --- /dev/null +++ b/src/services/durability/code/d_admin.c @@ -0,0 +1,3370 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#include "d__lock.h" +#include "d__admin.h" +#include "d__durability.h" +#include "d__actionQueue.h" +#include "d__fellow.h" +#include "d__nameSpace.h" +#include "d__configuration.h" +#include "d__group.h" +#include "d__table.h" +#include "d__listener.h" +#include "d__publisher.h" +#include "d__subscriber.h" +#include "d__nameSpacesRequestListener.h" +#include "d__remoteReaderListener.h" +#include "d__misc.h" +#include "d__readerRequest.h" +#include "d__eventListener.h" +#include "d__conflictMonitor.h" +#include "d__conflictResolver.h" +#include "d__filter.h" +#include "d__element.h" +#include "vortex_os.h" +#include "d_newGroup.h" +#include "d__mergeState.h" +#include "d_nameSpaces.h" +#include "d_groupsRequest.h" +#include "d_nameSpacesRequest.h" +#include "d_message.h" +#include "d_qos.h" +#include "d_store.h" +#include "d_networkAddress.h" +#include "d__statistics.h" +#include "d__thread.h" +#include "v_kernel.h" +#include "v_topic.h" +#include "v_event.h" +#include "v_reader.h" +#include "v_service.h" +#include "v_group.h" +#include "v_public.h" +#include "v_builtin.h" +#include "v_time.h" +#include "u_observable.h" +#include "u_entity.h" +#include "os_heap.h" +#include "os_mutex.h" +#include "os_defs.h" +#include "os_report.h" +#include "os_time.h" +#include "c_base.h" +#include + +/* + * TODO: Determine the compatibility of the namespaces of two fellows before + * allowing communication between them. + */ + +/* Prototype function used in checkAlignerForRole */ +static d_nameSpace d_adminGetNameSpaceNoLock(d_admin admin, c_char *name); + +void +d_adminUpdateStatistics( + d_admin admin, + d_adminStatisticsInfo statistics) +{ + assert(d_objectIsValid(d_object(admin), D_ADMIN) == TRUE); + + if(admin){ + d_lockLock(d_lock(admin)); + d_durabilityUpdateStatistics(admin->durability, d_statisticsUpdateAdmin, statistics); + d_lockUnlock(d_lock(admin)); + } + return; +} + +d_admin +d_adminNew( + d_durability durability) +{ + d_admin admin; + os_threadAttr ta; + os_result osr; + os_duration sleepTime; + d_configuration config; + u_result uResult; + int fail = FALSE; + + assert(d_durabilityIsValid(durability)); + config = d_durabilityGetConfiguration(durability); + assert(d_configurationIsValid(config)); + /* Allocate admin object */ + admin = d_admin(os_malloc(C_SIZEOF(d_admin))); + if (admin) { + /* zero fill structure so d_adminDeinit can safely be invoked */ + memset(admin, 0, sizeof(C_STRUCT(d_admin))); + /* Call super-init */ + d_lockInit(d_lock(admin), D_ADMIN, + (d_objectDeinitFunc)d_adminDeinit); + /* Initialize admin */ + admin->durability = durability; + admin->seqnum = config->seqnum_initval; + uResult = u_observableAction( + u_observable(d_durabilityGetService(durability)), + d_adminInitAddress, + admin); + assert(admin->myAddress != NULL); + if (uResult != U_RESULT_OK) { + fail = TRUE; + } + admin->initMask = D__INIT_FLAG_NONE; + admin->conflictResolver = NULL; + /* Various mutexes and condition variables */ + if (!fail) { + d_printTimedEvent(durability, D_LEVEL_FINER, "Initializing administration...\n"); + if (os_mutexInit(&admin->eventMutex, NULL) == os_resultSuccess) { + admin->initMask |= D__INIT_FLAG_EVENT_MUTEX; + } else { + fail = TRUE; + } + } + if (!fail) { + if (os_mutexInit(&admin->conflictQueueMutex, NULL) == os_resultSuccess) { + admin->initMask |= D__INIT_FLAG_CONFLICTQUEUE_MUTEX; + } else { + fail = TRUE; + } + } + if (!fail) { + if (os_condInit(&admin->eventCondition, &admin->eventMutex, NULL) == os_resultSuccess) { + admin->initMask |= D__INIT_FLAG_EVENT_COND; + } else { + fail = TRUE; + } + } + if (!fail) { + if (os_mutexInit(&admin->seqnumMutex, NULL) == os_resultSuccess) { + admin->initMask |= D__INIT_FLAG_SEQNUM_MUTEX; + } else { + fail = TRUE; + } + } + if (!fail) { + admin->cachedFellow = d_fellowNew(admin->myAddress, D_STATE_INIT, TRUE); + /* Various tables and iters */ + admin->unconfirmedFellows = d_tableNew(d_fellowCompare, d_fellowFree); + admin->fellows = d_tableNew(d_fellowCompare, d_fellowFree); + admin->initial_fellows = NULL; /* Lazy initialized when resolving an initial conflict */ + admin->clients = (config->clientDurabilityEnabled) ? d_tableNew(d_clientCompareByAddress, d_clientFree) : NULL; + admin->readerRequests = d_tableNew(d_readerRequestCompare, d_readerRequestFree); + admin->terminateFellows = d_tableNew(d_fellowCompare, d_fellowFree); + admin->eventListeners = c_iterNew(NULL); + admin->nameSpaces = c_iterNew(NULL); + admin->eventQueue = c_iterNew(NULL); + admin->conflictQueue = c_iterNew(NULL); + admin->groups = d_tableNew(d_groupCompare, d_groupFree); + admin->alignerGroupCount = 0; + admin->eventThreadTerminate = FALSE; + /* Check for failures */ + fail = (admin->cachedFellow == NULL); + fail |= (admin->unconfirmedFellows == NULL); + fail |= (admin->fellows == NULL); + fail |= (admin->readerRequests == NULL); + fail |= (admin->terminateFellows == NULL); + fail |= (admin->eventListeners == NULL); + fail |= (admin->nameSpaces == NULL); + fail |= (admin->eventQueue == NULL); + fail |= (admin->conflictQueue == NULL); + fail |= (admin->groups == NULL); + } + if (!fail) { + /* Set the conflictMonitor */ + d_printTimedEvent(durability, D_LEVEL_FINEST, "Initializing conflict monitor...\n"); + admin->conflictMonitor = d_conflictMonitorNew(admin); + fail = (admin->conflictMonitor == NULL); + } + if (!fail) { + /* Initialize topics */ + d_printTimedEvent(durability, D_LEVEL_FINEST, "Initializing protocol topics...\n"); + admin->groupsRequestTopic = d_adminInitTopic( + admin, D_GROUPS_REQ_TOPIC_NAME, + D_GROUPS_REQ_TYPE_NAME, + D_GROUPS_REQ_KEY_LIST, + V_RELIABILITY_RELIABLE, + V_HISTORY_KEEPALL, + V_ORDERBY_RECEPTIONTIME, + V_LENGTH_UNLIMITED); + + admin->sampleRequestTopic = d_adminInitTopic( + admin, D_SAMPLE_REQ_TOPIC_NAME, + D_SAMPLE_REQ_TYPE_NAME, + D_SAMPLE_REQ_KEY_LIST, + V_RELIABILITY_RELIABLE, + V_HISTORY_KEEPALL, + V_ORDERBY_RECEPTIONTIME, + V_LENGTH_UNLIMITED); + + admin->newGroupTopic = d_adminInitTopic( + admin, D_NEWGROUP_TOPIC_NAME, + D_NEWGROUP_TYPE_NAME, + D_NEWGROUP_KEY_LIST, + V_RELIABILITY_RELIABLE, + V_HISTORY_KEEPALL, + V_ORDERBY_RECEPTIONTIME, + V_LENGTH_UNLIMITED); + + admin->statusTopic = d_adminInitTopic( + admin, D_STATUS_TOPIC_NAME, + D_STATUS_TYPE_NAME, + D_STATUS_KEY_LIST, + V_RELIABILITY_RELIABLE, + V_HISTORY_KEEPLAST, + V_ORDERBY_RECEPTIONTIME, + 1); + + admin->sampleChainTopic = d_adminInitTopic( + admin, D_SAMPLE_CHAIN_TOPIC_NAME, + D_SAMPLE_CHAIN_TYPE_NAME, + D_SAMPLE_CHAIN_KEY_LIST, + V_RELIABILITY_RELIABLE, + V_HISTORY_KEEPALL, + V_ORDERBY_RECEPTIONTIME, + V_LENGTH_UNLIMITED); + + admin->nameSpacesTopic = d_adminInitTopic( + admin, D_NAMESPACES_TOPIC_NAME, + D_NAMESPACES_TYPE_NAME, + D_NAMESPACES_KEY_LIST, + V_RELIABILITY_RELIABLE, + V_HISTORY_KEEPALL, + V_ORDERBY_RECEPTIONTIME, + V_LENGTH_UNLIMITED); + + admin->nameSpacesRequestTopic = d_adminInitTopic( + admin, D_NAMESPACES_REQ_TOPIC_NAME, + D_NAMESPACES_REQ_TYPE_NAME, + D_NAMESPACES_REQ_KEY_LIST, + V_RELIABILITY_RELIABLE, + V_HISTORY_KEEPALL, + V_ORDERBY_RECEPTIONTIME, + V_LENGTH_UNLIMITED); + + admin->deleteDataTopic = d_adminInitTopic( + admin, D_DELETE_DATA_TOPIC_NAME, + D_DELETE_DATA_TYPE_NAME, + D_DELETE_DATA_KEY_LIST, + V_RELIABILITY_RELIABLE, + V_HISTORY_KEEPALL, + V_ORDERBY_RECEPTIONTIME, + V_LENGTH_UNLIMITED); + + if (config->capabilitySupport) { + admin->capabilityTopic = d_adminInitTopic( + admin, D_CAPABILITY_TOPIC_NAME, + D_CAPABILITY_TYPE_NAME, + D_CAPABILITY_KEY_LIST, + V_RELIABILITY_RELIABLE, + V_HISTORY_KEEPLAST, + V_ORDERBY_RECEPTIONTIME, + 1); + } else { + admin->capabilityTopic = NULL; + } + + if (config->clientDurabilityEnabled) { + admin->durabilityStateRequestTopic = d_adminInitTopic( + admin, D_DURABILITY_STATE_REQUEST_TOPIC_NAME, + D_DURABILITY_STATE_REQUEST_TYPE_NAME, + D_DURABILITY_STATE_REQUEST_KEY_LIST, + V_RELIABILITY_RELIABLE, + V_HISTORY_KEEPALL, + V_ORDERBY_SOURCETIME, + V_LENGTH_UNLIMITED); + + admin->durabilityStateTopic = d_adminInitTopic( + admin, D_DURABILITY_STATE_TOPIC_NAME, + D_DURABILITY_STATE_TYPE_NAME, + D_DURABILITY_STATE_KEY_LIST, + V_RELIABILITY_RELIABLE, + V_HISTORY_KEEPALL, + V_ORDERBY_SOURCETIME, + V_LENGTH_UNLIMITED); + + admin->historicalDataRequestTopic = d_adminInitTopic( + admin, D_HISTORICAL_DATA_REQUEST_TOPIC_NAME, + D_HISTORICAL_DATA_REQUEST_TYPE_NAME, + D_HISTORICAL_DATA_REQUEST_KEY_LIST, + V_RELIABILITY_RELIABLE, + V_HISTORY_KEEPALL, + V_ORDERBY_SOURCETIME, + V_LENGTH_UNLIMITED); + + admin->historicalDataTopic = d_adminInitTopic( + admin, D_HISTORICAL_DATA_TOPIC_NAME, + D_HISTORICAL_DATA_TYPE_NAME, + D_HISTORICAL_DATA_KEY_LIST, + V_RELIABILITY_RELIABLE, + V_HISTORY_KEEPALL, + V_ORDERBY_SOURCETIME, + V_LENGTH_UNLIMITED); + } else { + admin->durabilityStateRequestTopic = NULL; + admin->durabilityStateTopic = NULL; + admin->historicalDataRequestTopic = NULL; + admin->historicalDataTopic = NULL; + } + + fail = (admin->groupsRequestTopic == NULL); + fail |= (admin->sampleRequestTopic == NULL); + fail |= (admin->newGroupTopic == NULL); + fail |= (admin->statusTopic == NULL); + fail |= (admin->sampleChainTopic == NULL); + fail |= (admin->nameSpacesTopic == NULL); + fail |= (admin->nameSpacesRequestTopic == NULL); + fail |= (admin->deleteDataTopic == NULL); + fail |= (config->capabilitySupport && admin->capabilityTopic == NULL); + fail |= (config->clientDurabilityEnabled && admin->durabilityStateRequestTopic == NULL); + fail |= (config->clientDurabilityEnabled && admin->durabilityStateTopic == NULL); + fail |= (config->clientDurabilityEnabled && admin->historicalDataRequestTopic == NULL); + fail |= (config->clientDurabilityEnabled && admin->historicalDataTopic == NULL); + + } + if (!fail) { + /* Create the action queue. + * Actions in this queue are scheduled every 100ms + */ + sleepTime = OS_DURATION_INIT(0, 100000000); + admin->actionQueue = d_actionQueueNew("d_adminActionQueue", sleepTime, + config->heartbeatScheduling); + fail = (admin->actionQueue == NULL); + } + + if (!fail) { + /* start adminEventThread */ + os_threadAttrInit(&ta); + osr = d_threadCreate(&(admin->eventThread), + "AdminEventDispatcher", + &ta, + (void*(*)(void*))d_adminEventThreadStart, + (void*)admin); + fail = (osr != os_resultSuccess); + if (!fail) { + admin->initMask |= D__INIT_FLAG_EVENT_THREAD; + } + } + + if (!fail) { + d_printTimedEvent(durability, D_LEVEL_FINEST, "Initializing protocol publisher and writers...\n"); + admin->publisher = d_publisherNew(admin); + fail = (admin->publisher == NULL); + } + } + if (fail) { + d_printTimedEvent(durability, D_LEVEL_SEVERE, "Failed to initialize the administration, trying to cleanup admin\n"); + if (admin) { + d_adminFree(admin); + admin = NULL; + } + } + return admin; +} + + +void +d_adminInitSubscriber( + d_admin admin) +{ + d_durability durability; + + durability = d_adminGetDurability(admin); + + /* Initialize protocol subscriber. Needs to be seperated from d_adminNew because + * of dependency between store (which is created by subscriber) and nameSpaces + * list in admin. + */ + d_printTimedEvent(durability, D_LEVEL_FINER, "Initializing protocol subscriber...\n"); + admin->subscriber = d_subscriberNew(admin); + assert(admin->subscriber); +} + +c_bool +d_adminAddLocalGroup( + d_admin admin, + d_group group) +{ + d_group duplicate; + c_bool result; + d_adminStatisticsInfo info; + + assert(d_objectIsValid(d_object(admin), D_ADMIN) == TRUE); + assert(d_objectIsValid(d_object(group), D_GROUP) == TRUE); + + result = FALSE; + + if(group && admin){ + d_lockLock(d_lock(admin)); + duplicate = d_tableInsert(admin->groups, group); + /* In some cases a group might be registered multiple times. Of + * course, it is not added and notified anymore. + */ + if(duplicate == NULL){ + info = d_adminStatisticsInfoNew(); + info->kind = D_ADMIN_STATISTICS_GROUP; + + switch(d_groupGetCompleteness(group)){ + case D_GROUP_COMPLETE: + switch(d_groupGetKind(group)){ + case D_DURABILITY_VOLATILE: + info->groupsKnownVolatileDif += 1; + info->groupsCompleteVolatileDif += 1; + break; + case D_DURABILITY_TRANSIENT: + case D_DURABILITY_TRANSIENT_LOCAL: + info->groupsKnownTransientDif += 1; + info->groupsCompleteTransientDif += 1; + break; + case D_DURABILITY_PERSISTENT: + info->groupsKnownPersistentDif += 1; + info->groupsCompletePersistentDif += 1; + break; + case D_DURABILITY_ALL: + break; + } + break; + case D_GROUP_INCOMPLETE: + switch(d_groupGetKind(group)){ + case D_DURABILITY_VOLATILE: + info->groupsKnownVolatileDif += 1; + info->groupsIncompleteVolatileDif += 1; + break; + case D_DURABILITY_TRANSIENT: + case D_DURABILITY_TRANSIENT_LOCAL: + info->groupsKnownTransientDif += 1; + info->groupsIncompleteTransientDif += 1; + break; + case D_DURABILITY_PERSISTENT: + info->groupsKnownPersistentDif += 1; + info->groupsCompletePersistentDif += 1; + break; + case D_DURABILITY_ALL: + break; + } + break; + case D_GROUP_KNOWLEDGE_UNDEFINED: + case D_GROUP_UNKNOWN: + break; + } + + d_durabilityUpdateStatistics(admin->durability, d_statisticsUpdateAdmin, info); + d_adminStatisticsInfoFree(info); + + admin->alignerGroupCount++; + d_adminNotifyListeners(admin, D_GROUP_LOCAL_NEW, NULL, NULL, group, NULL); + result = TRUE; + } + d_lockUnlock(d_lock(admin)); + } + return result; +} + +c_ulong +d_adminGetAlignerGroupCount( + d_admin admin) +{ + c_ulong count = 0; + + assert(d_objectIsValid(d_object(admin), D_ADMIN) == TRUE); + + if(admin){ + count = admin->alignerGroupCount; + } + return count; +} + + +d_group +d_adminGetLocalGroupNoLock( + d_admin admin, + const c_char* partition, + const c_char* topic, + d_durabilityKind kind) +{ + d_group dummy; + d_group found; + + assert(d_adminIsValid(admin)); + + dummy = d_groupNew(partition, topic, kind, D_GROUP_KNOWLEDGE_UNDEFINED, D_QUALITY_ZERO); + found = d_tableFind(admin->groups, dummy); + d_groupFree(dummy); + return found; +} + + +d_group +d_adminGetLocalGroup( + d_admin admin, + const c_char* partition, + const c_char* topic, + d_durabilityKind kind) +{ + d_group found; + + assert(d_adminIsValid(admin)); + + d_lockLock(d_lock(admin)); + found = d_adminGetLocalGroupNoLock(admin, partition, topic, kind); + d_lockUnlock(d_lock(admin)); + return found; +} + + +void +d_adminDeinit( + d_admin admin) +{ + d_durability durability; + d_nameSpace nameSpace; + d_adminEvent event; + d_conflict conflict; + + assert(d_adminIsValid(admin)); + + durability = admin->durability; + assert(d_durabilityIsValid(durability)); + + /* First stop the threads associated with the admin and + * destroy associated mutexes and conditions. + * + * Deinitialization can be invoked either by failure of + * d_adminNew(), or by stopping the durability service. + * In latter case threads may have already been stopped. + * To test for this* flags are used. These flags are set + * when the objects are created, and reset when destroyed. + */ + if (admin->initMask & D__INIT_FLAG_EVENT_MUTEX) { + if (admin->initMask & D__INIT_FLAG_EVENT_COND) { + os_mutexLock(&admin->eventMutex); + admin->eventThreadTerminate = TRUE; + os_condSignal(&admin->eventCondition); + os_mutexUnlock(&admin->eventMutex); + /* Stop it if it is still running. */ + if (admin->initMask & D__INIT_FLAG_EVENT_THREAD) { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Waiting for admin event dispatcher thread to terminate...\n"); + d_threadWaitExit(admin->eventThread, NULL); + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Thread destroyed.\n"); + /* Reset the flag to indicate that the event thread has been cleared */ + admin->initMask &= ~(D__INIT_FLAG_EVENT_THREAD); + } + os_condDestroy(&admin->eventCondition); + /* Reset the flag to indicate that the eventcondition has been destroyed */ + admin->initMask &= ~(D__INIT_FLAG_EVENT_COND); + } + /* Removing eventListeners */ + if (admin->eventListeners) { + os_mutexLock(&admin->eventMutex); + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Removing event listeners.\n"); + c_iterFree(admin->eventListeners); + admin->eventListeners = NULL; + os_mutexUnlock(&admin->eventMutex); + } + /* Clearing the event queue */ + if (admin->eventQueue) { + os_mutexLock(&admin->eventMutex); + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Clearing event queue.\n"); + event = d_adminEvent(c_iterTakeFirst(admin->eventQueue)); + while(event){ + d_adminEventFree(event); + event = d_adminEvent(c_iterTakeFirst(admin->eventQueue)); + } + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Destroying event queue.\n"); + c_iterFree(admin->eventQueue); + os_mutexUnlock(&admin->eventMutex); + } + /* Destroy eventMutex */ + os_mutexDestroy(&admin->eventMutex); + admin->initMask &= ~(D__INIT_FLAG_EVENT_MUTEX); + } + + /* Destroy the conflictMonitor */ + if (admin->conflictMonitor) { + d_printTimedEvent(durability, D_LEVEL_FINER, + "Destroying conflict monitor...\n"); + d_conflictMonitorFree(admin->conflictMonitor); + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Conflict monitor destroyed\n"); + } + + /* Destroy the conflictResolver */ + if (admin->conflictResolver) { + d_printTimedEvent(durability, D_LEVEL_FINER, + "Destroying conflict resolver...\n"); + d_conflictResolverFree(admin->conflictResolver); + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Conflict resolver destroyed\n"); + admin->conflictResolver = NULL; + } + + + /* Destroy the conflictQueue */ + if (admin->conflictQueue) { + while ((conflict = d_conflict(c_iterTakeFirst(admin->conflictQueue))) != NULL) { + d_conflictFree(conflict); + } + c_iterFree(admin->conflictQueue); + } + if (admin->initMask & D__INIT_FLAG_CONFLICTQUEUE_MUTEX) { + os_mutexDestroy(&admin->conflictQueueMutex); + /* Reset the flag to indicate that the eventcondition has been destroyed */ + admin->initMask &= ~(D__INIT_FLAG_CONFLICTQUEUE_MUTEX); + } + /* Destroy the admin->actionQueue. */ + if (admin->actionQueue) { + d_printTimedEvent(durability, D_LEVEL_FINER, "Destroying action queue %s .\n", admin->actionQueue->name); + d_actionQueueFree(admin->actionQueue); + } + /* Destroying subscriber */ + if (admin->subscriber) { + d_printTimedEvent(durability, D_LEVEL_FINER, "Destroying subscriber...\n"); + d_subscriberFree(admin->subscriber); + + d_printTimedEvent(durability, D_LEVEL_FINER, "Subscriber destroyed\n"); + admin->subscriber = NULL; + } + /* Destroying publisher */ + if (admin->publisher) { + d_printTimedEvent(durability, D_LEVEL_FINER, "Destroying publisher...\n"); + d_publisherFree(admin->publisher); + d_printTimedEvent(durability, D_LEVEL_FINEST, "Publisher destroyed\n"); + admin->publisher = NULL; + } + /* Destroy pending reader requests */ + if (admin->readerRequests) { + d_printTimedEvent(durability, D_LEVEL_FINER, "Destroying readerRequests...\n"); + d_tableFree(admin->readerRequests); + admin->readerRequests = NULL; + d_printTimedEvent(durability, D_LEVEL_FINEST, "ReaderRequests destroyed\n"); + } + /* Destroy list of fellows that have recently terminated */ + if (admin->terminateFellows) { + d_printTimedEvent(durability, D_LEVEL_FINER, "Destroying terminateFellow admin...\n"); + d_tableFree(admin->terminateFellows); + admin->terminateFellows = NULL; + d_printTimedEvent(durability, D_LEVEL_FINEST, "TerminateFellows destroyed\n"); + } + /* Destroy fellow administration */ + if (admin->fellows) { + d_printTimedEvent(durability, D_LEVEL_FINEST, "Destroying fellow admin...\n"); + d_tableFree(admin->fellows); + admin->fellows = NULL; + d_printTimedEvent(durability, D_LEVEL_FINEST, "Fellows destroyed\n"); + } + /* Destroy unconfirmed fellow administration */ + if (admin->unconfirmedFellows) { + d_printTimedEvent(durability, D_LEVEL_FINER, "Destroying unconfirmed fellow admin...\n"); + d_tableFree(admin->unconfirmedFellows); + admin->unconfirmedFellows = NULL; + d_printTimedEvent(durability, D_LEVEL_FINEST, "Unconfirmed fellows destroyed\n"); + } + /* Destroy client administration */ + if (admin->clients) { + d_printTimedEvent(durability, D_LEVEL_FINER, "Destroying clients admin...\n"); + d_tableFree(admin->clients); + admin->clients = NULL; + d_printTimedEvent(durability, D_LEVEL_FINEST, "Clients destroyed\n"); + } + /* Destroy group administration */ + if (admin->groups) { + d_tableFree(admin->groups); + d_printTimedEvent(durability, D_LEVEL_FINER, "My groups destroyed\n"); + } + if (admin->cachedFellow) { + d_fellowFree(admin->cachedFellow); + admin->cachedFellow = NULL; + d_printTimedEvent(durability, D_LEVEL_FINEST, "Cached fellow destroyed\n"); + } + /* Destroy topics */ + d_printTimedEvent(durability, D_LEVEL_FINER, "Destroying topics...\n"); + if (admin->statusTopic) { + u_objectFree(u_object(admin->statusTopic)); + admin->statusTopic = NULL; + d_printTimedEvent(durability, D_LEVEL_FINEST, "%s topic destroyed\n", D_STATUS_TOPIC_NAME); + } + if (admin->newGroupTopic) { + u_objectFree(u_object(admin->newGroupTopic)); + admin->newGroupTopic = NULL; + d_printTimedEvent(durability, D_LEVEL_FINEST, "%s topic destroyed\n", D_NEWGROUP_TOPIC_NAME); + } + if (admin->groupsRequestTopic) { + u_objectFree(u_object(admin->groupsRequestTopic)); + admin->groupsRequestTopic = NULL; + d_printTimedEvent(durability, D_LEVEL_FINEST, "%s topic destroyed\n", D_GROUPS_REQ_TOPIC_NAME); + } + if (admin->sampleRequestTopic) { + u_objectFree(u_object(admin->sampleRequestTopic)); + admin->sampleRequestTopic = NULL; + d_printTimedEvent(durability, D_LEVEL_FINEST, "%s topic destroyed\n", D_SAMPLE_REQ_TOPIC_NAME); + } + if(admin->sampleChainTopic){ + u_objectFree(u_object(admin->sampleChainTopic)); + admin->sampleChainTopic = NULL; + d_printTimedEvent(durability, D_LEVEL_FINEST, "%s topic destroyed\n", D_SAMPLE_CHAIN_TOPIC_NAME); + } + if (admin->nameSpacesTopic) { + u_objectFree(u_object(admin->nameSpacesTopic)); + admin->nameSpacesTopic = NULL; + d_printTimedEvent(durability, D_LEVEL_FINEST, "%s topic destroyed\n", D_NAMESPACES_TOPIC_NAME); + } + if (admin->nameSpacesRequestTopic) { + u_objectFree(u_object(admin->nameSpacesRequestTopic)); + admin->nameSpacesRequestTopic = NULL; + d_printTimedEvent(durability, D_LEVEL_FINEST, "%s topic destroyed\n", D_NAMESPACES_REQ_TOPIC_NAME); + } + if (admin->deleteDataTopic) { + u_objectFree(u_object(admin->deleteDataTopic)); + admin->deleteDataTopic = NULL; + d_printTimedEvent(durability, D_LEVEL_FINEST, "%s topic destroyed\n", D_DELETE_DATA_TOPIC_NAME); + } + if (admin->capabilityTopic) { + u_objectFree(u_object(admin->capabilityTopic)); + admin->capabilityTopic = NULL; + d_printTimedEvent(durability, D_LEVEL_FINEST, "%s topic destroyed\n", D_CAPABILITY_TOPIC_NAME); + } + if (admin->durabilityStateRequestTopic) { + u_objectFree(u_object(admin->durabilityStateRequestTopic)); + admin->durabilityStateRequestTopic = NULL; + d_printTimedEvent(durability, D_LEVEL_FINEST, "%s topic destroyed\n", D_DURABILITY_STATE_REQUEST_TOPIC_NAME); + } + if (admin->durabilityStateTopic) { + u_objectFree(u_object(admin->durabilityStateTopic)); + admin->durabilityStateTopic = NULL; + d_printTimedEvent(durability, D_LEVEL_FINEST, "%s topic destroyed\n", D_DURABILITY_STATE_TOPIC_NAME); + } + if (admin->historicalDataRequestTopic) { + u_objectFree(u_object(admin->historicalDataRequestTopic)); + admin->historicalDataRequestTopic = NULL; + d_printTimedEvent(durability, D_LEVEL_FINEST, "%s topic destroyed\n", D_HISTORICAL_DATA_REQUEST_TOPIC_NAME); + } + if (admin->historicalDataTopic) { + u_objectFree(u_object(admin->historicalDataTopic)); + admin->historicalDataTopic = NULL; + d_printTimedEvent(durability, D_LEVEL_FINEST, "%s topic destroyed\n", D_HISTORICAL_DATA_TOPIC_NAME); + } + d_printTimedEvent(durability, D_LEVEL_FINEST, "Topics destroyed\n"); + if (admin->myAddress) { + d_networkAddressFree(admin->myAddress); + admin->myAddress = NULL; + } + /* Destroy namespaces administration */ + if (admin->nameSpaces) { + nameSpace = d_nameSpace(c_iterTakeFirst(admin->nameSpaces)); + + while(nameSpace){ + d_nameSpaceFree(nameSpace); + nameSpace = d_nameSpace(c_iterTakeFirst(admin->nameSpaces)); + } + c_iterFree (admin->nameSpaces); + admin->nameSpaces = NULL; + } + /* Destroy seqnumMutex */ + if (admin->initMask & D__INIT_FLAG_SEQNUM_MUTEX) { + os_mutexDestroy(&admin->seqnumMutex); + admin->initMask &= ~(D__INIT_FLAG_SEQNUM_MUTEX); + } + /* Call super-deinit */ + d_lockDeinit(d_lock(admin)); + d_printTimedEvent(durability, D_LEVEL_FINER, "Admin destroyed\n"); +} + +void +d_adminFree( + d_admin admin) +{ + assert(d_adminIsValid(admin)); + + d_objectFree(d_object(admin)); +} + + +/** + * \brief Retrieve the confirmed fellow that matches the address + * + * If found, a reference to the fellow is returned. + * If no confirmed fellow could be found, NULL is returned. + */ +d_fellow +d_adminGetFellow( + d_admin admin, + d_networkAddress address) +{ + d_fellow found = NULL; + + assert(d_objectIsValid(d_object(admin), D_ADMIN) == TRUE); + + d_lockLock(d_lock(admin)); + + d_fellowSetAddress(admin->cachedFellow, address); + found = d_tableFind(admin->fellows, admin->cachedFellow); + + if (found) { + found = d_fellow(d_objectKeep(d_object(found))); + } + + d_lockUnlock(d_lock(admin)); + + return found; +} + + + +/** + * \brief Retrieve the unconfirmed fellow that matches the address + * + * If found, a reference to the fellow is returned. + * If no unconfirmed fellow could be found, NULL is returned. + */ +d_fellow +d_adminGetUnconfirmedFellow( + d_admin admin, + d_networkAddress address) +{ + d_fellow found, dummy; + + assert(d_objectIsValid(d_object(admin), D_ADMIN) == TRUE); + + found = NULL; + dummy = d_fellowNew(address, D_STATE_INIT, FALSE); + + d_lockLock(d_lock(admin)); + found = d_tableFind(admin->unconfirmedFellows, dummy); + if(found){ + found = d_fellow(d_objectKeep(d_object(found))); + } + d_lockUnlock(d_lock(admin)); + d_fellowFree(dummy); + + return found; +} + + +/** + * \brief Add a reference to the fellow to the durability administration. + * + * If the fellow was recently terminated it is not added and NULL is returned. + * + * If the fellow is confirmed but there already exists and unconfirmed fellow + * with the same address, then this fellow is promoted to become confirmed. + * If there already exists a confirmed fellow with the same address then this + * fellow returned. + * + * The fellow is refCounted, so it must be freed by the caller. + * + * @return + * NULL, if the fellow has recently terminated. + * the fellow that is added, otherwise. + */ +d_fellow +d_adminAddFellow( + d_admin admin, + d_fellow fellow) +{ + d_networkAddress fellowAddr; + d_fellow found, duplicate, result = NULL; + d_adminStatisticsInfo info; + c_bool isConfirmed; + c_bool justConfirmed = FALSE; + d_configuration config = d_durabilityGetConfiguration(d_adminGetDurability(admin)); + d_serviceState fellowState; + + assert(d_adminIsValid(admin)); + assert(d_fellowIsValid(fellow)); + + /* The admin maintains two lists of fellows + * admin->fellows contains the list of confirmed fellows + * admin->unconfirmedFellows contains the list of unconfirmed fellows + * Adding a confirmed fellow may result in moving the fellow from + * admin->unconfirmedFellows to admin->fellows. + * Trying to add an unconfiremd fellow while it has been confirmed + * previously is not possible, in that case the confirmed fellow will + * be returned. + */ + result = NULL; + isConfirmed = d_fellowIsConfirmed(fellow); + fellowAddr = d_fellowGetAddress(fellow); + fellowState = d_fellowGetState(fellow); + + d_lockLock(d_lock(admin)); + + /* If the fellow has been terminated recently then do not add it + * for a while to prevent stuttering */ + found = d_tableFind(admin->terminateFellows, fellow); + if (found) { + if (!d_fellowHasRecentlyTerminated(found)) { + d_printTimedEvent(admin->durability, D_LEVEL_INFO, + "Fellow %u has recently terminated, therefore NOT added to admin until this fellow is cleaned up.\n", + fellowAddr->systemId); + } + goto ret; + } + + if (!isConfirmed) { + /* Trying to add an unconfirmed fellow while it has been confirmed + * earlier is not possible */ + if ((found = d_tableFind(admin->fellows, fellow)) != NULL) { + d_printTimedEvent(admin->durability, D_LEVEL_FINEST, + "Fellow %u is already confirmed, no need to make it unconfirmed again.\n", + fellowAddr->systemId); + result = d_fellow(d_objectKeep(d_object(found))); + goto ret; + } + + /* Do not add an unconfirmed fellow if there already exists one */ + if ((duplicate = d_tableInsert(admin->unconfirmedFellows, fellow)) != NULL) { + d_printTimedEvent(admin->durability, D_LEVEL_FINEST, + "Fellow %u is already unconfirmed, no need to add it again.\n", + fellowAddr->systemId); + result = d_fellow(d_objectKeep(d_object(duplicate))); + } else { + /* A new unconfirmed fellow was added. */ + d_printTimedEvent(admin->durability, D_LEVEL_INFO, + "Unconfirmed fellow %u added to admin [state %s].\n", + fellowAddr->systemId, d_fellowStateText(fellowState)); + result = d_fellow(d_objectKeep(d_object(fellow))); + } + goto ret; + + } else { + /* An existing unconfirmed fellow is about to become + * confirmed. Update the state and last status. */ + if ((found = d_tableRemove(admin->unconfirmedFellows, fellow)) != NULL) { + d_fellowUpdateStatus(found, d_fellowGetState(fellow), d_fellowGetLastSeqNum(fellow)); + d_printTimedEvent(admin->durability, D_LEVEL_INFO, + "Confirming fellow %u\n", + fellowAddr->systemId); + justConfirmed = TRUE; + d_fellowSetConfirmed(found, TRUE); + fellow = found; + } + duplicate = (d_fellow)d_tableInsert(admin->fellows, fellow); + + /* Duplicate confirmed fellow found. Update the last status. */ + if (duplicate) { + d_fellowUpdateStatus(duplicate, d_fellowGetState(duplicate), d_fellowGetLastSeqNum(fellow)); + result = d_fellow(d_objectKeep(d_object(duplicate))); + + /* The fellow has become confirmed for the first time. */ + } else { + d_printTimedEvent(admin->durability, D_LEVEL_INFO, + "Confirmed fellow %u added to admin [state %s].\n", + fellowAddr->systemId, d_fellowStateText(fellowState)); + justConfirmed = TRUE; + d_adminNotifyListeners(admin, D_FELLOW_NEW, fellow, NULL, NULL, NULL); + info = d_adminStatisticsInfoNew(); + info->fellowsKnownDif = 1; + d_durabilityUpdateStatistics(admin->durability, d_statisticsUpdateAdmin, info); + d_adminStatisticsInfoFree(info); + result = d_fellow(d_objectKeep(d_object(fellow))); + } + } + +ret: + d_lockUnlock(d_lock(admin)); + /* Rediscover readers, but only when you must wait for remote readers */ + if ((justConfirmed) && (config->waitForRemoteReaders)) { + d_remoteReaderListenerCheckReaders(admin->subscriber->remoteReaderListener); + } + d_networkAddressFree(fellowAddr); + return result; +} + +static c_bool +clearMaster( + d_fellow fellow, + c_voidp userData) +{ + d_fellowClearMaster(fellow, d_networkAddress(userData)); + + return TRUE; +} + +struct fellowsExistForRoleHelper +{ + d_name role; + c_bool found; +}; + + +struct checkAlignerForRoleHelper { + d_admin admin; /* the admininistration */ + d_fellow fellow; /* the fellow */ + c_char *role; /* the fellow role */ +}; + + +/** + * \brief Clears the mergestate of the namespace if no alternative aligner + * in the same role as myself could be found for this namespace. + * + * @return TRUE + */ +c_bool +checkAlignerForRole (d_nameSpace nameSpace, void *userData) { + + struct checkAlignerForRoleHelper *roleHelper; + d_nameSpace myNameSpace; + + roleHelper = (struct checkAlignerForRoleHelper *)userData; + + assert(roleHelper->admin); + assert(roleHelper->fellow); + + /* Retrieve the local namespace corresponding to the fellow's namespace + * from my own administration. + */ + myNameSpace = d_adminGetNameSpaceNoLock(roleHelper->admin, d_nameSpaceGetName(nameSpace)); + if (myNameSpace != NULL) { + d_durability durability = d_adminGetDurability(roleHelper->admin); + d_configuration config = d_durabilityGetConfiguration(durability); + d_networkAddress masterAddr = d_nameSpaceGetMaster(myNameSpace); + d_networkAddress fellowAddr = d_fellowGetAddress(roleHelper->fellow); + + if ( (strcmp(config->role, roleHelper->role) == 0) && /* same role */ + (d_networkAddressEquals(masterAddr, fellowAddr)) && /* removed fellow was master */ + ((!d_nameSpaceIsAligner(myNameSpace)) || (d_nameSpaceGetMasterPriority(myNameSpace) == D_MINIMUM_MASTER_PRIORITY))) { + + d_networkAddress unAddressed = d_networkAddressUnaddressed(); + + /* No alternative aligner has been found (not even myself). + * Reset the master and the current state of the namespace for this role + */ + d_nameSpaceSetMaster(myNameSpace, unAddressed); + d_printTimedEvent(roleHelper->admin->durability, D_LEVEL_INFO, + "Confirming master: Fellow '%u' is the master for nameSpace '%s'.\n", + unAddressed->systemId, d_nameSpaceGetName(myNameSpace)); + d_nameSpaceMasterConfirmed(myNameSpace); + + d_nameSpaceClearMergeState (myNameSpace, roleHelper->role); + /* Log the clearing of the state to indicate that no aligner is available for the namespace. */ + d_printTimedEvent(roleHelper->admin->durability, D_LEVEL_FINER, + "State and master of namespace '%s' for role '%s' cleared\n", + d_nameSpaceGetName(nameSpace), + roleHelper->role); + d_networkAddressFree(unAddressed); + } + d_networkAddressFree(masterAddr); + d_networkAddressFree(fellowAddr); + d_nameSpaceFree(myNameSpace); + } + return TRUE; +} + + +/** + * \brief Remove a fellow from the durability administration. + * + * If the fellow was a master for one of my namespaces in my role then check + * if an alternative master can be found. If no alternative aligner can be + * found then the mergestate for this namespace is cleared. + * + * @return a reference to the fellow that is removed, or NULL otherwise. + */ +d_fellow +d_adminRemoveFellow( + d_admin admin, + d_fellow fellow, + c_bool trackFellow) +{ + d_fellow result; + d_networkAddress fellowAddr; + d_adminStatisticsInfo info; + struct checkAlignerForRoleHelper helper; + d_durability durability; + d_configuration config; + + assert(d_objectIsValid(d_object(admin), D_ADMIN) == TRUE); + assert(d_objectIsValid(d_object(fellow), D_FELLOW) == TRUE); + + result = NULL; + if (admin && fellow) { + d_lockLock(d_lock(admin)); + durability = d_adminGetDurability(admin); + assert(d_durabilityIsValid(durability)); + config = d_durabilityGetConfiguration(durability); + assert(d_configurationIsValid(config)); + /* Remove the fellow from the admin */ + result = d_tableRemove(admin->fellows, fellow); + if (result) { + /* Check if there exists an alternative aligner for + * the namespaces for which the fellow was an aligner. + * If not found then there is nobody who can align + * the namespace. In this case the merge state for + * this namespace and role is cleared. + */ + helper.fellow = result; + helper.admin = admin; + helper.role = d_fellowGetRole(result); + d_fellowNameSpaceWalk(result, checkAlignerForRole, &helper); + + info = d_adminStatisticsInfoNew(); + info->fellowsKnownDif = -1; + + switch(d_fellowGetCommunicationState(fellow)){ + case D_COMMUNICATION_STATE_APPROVED: + info->fellowsApprovedDif -= 1; + break; + case D_COMMUNICATION_STATE_INCOMPATIBLE_STATE: + info->fellowsIncompatibleStateDif -= 1; + break; + case D_COMMUNICATION_STATE_INCOMPATIBLE_DATA_MODEL: + info->fellowsIncompatibleDataModelDif -= 1; + break; + case D_COMMUNICATION_STATE_TERMINATED: + case D_COMMUNICATION_STATE_UNKNOWN: + break; + } + /* Make sure that a termination message exceeds the maximum valid sequence number. + * This prevents resurrection of the fellow in case another threads indicates that it + * is still alive. + */ + d_fellowUpdateStatus(result, D_STATE_TERMINATED, D_SEQNUM_INFINITE); + fellowAddr = d_fellowGetAddress(result); + d_tableWalk(admin->fellows, clearMaster, fellowAddr); + + d_durabilityUpdateStatistics(admin->durability, d_statisticsUpdateAdmin, info); + d_adminStatisticsInfoFree(info); + if ((os_durationCompare(config->terminateRemovalPeriod, OS_DURATION_ZERO) != OS_EQUAL) && (trackFellow == TRUE)) { + /* The fellow has a non-zero terminateRemovalTime. + * To prevent that pending messages from the fellow cause the + * fellow to be added again to the admin, we add the fellow + * to the list admin->terminateFellow. This list is cleaned up + * after awhile in d_durabilityUpdateLeaseAndNotifyStatus. + */ + result->removalTime = os_timeMGet(); + (void)d_tableInsert(admin->terminateFellows, d_objectKeep(d_object(result))); + d_printTimedEvent(admin->durability, D_LEVEL_INFO, + "Removing confirmed fellow %u, ignoring messages from this fellow for %"PA_PRIduration"\n", + fellowAddr->systemId, OS_DURATION_PRINT(config->terminateRemovalPeriod)); + } else { + d_printTimedEvent(admin->durability, D_LEVEL_INFO, + "Removing confirmed fellow %u.\n", + fellowAddr->systemId); + } + /* Notify that the fellow is removed */ + d_adminNotifyListeners(admin, D_FELLOW_REMOVED, result, NULL, NULL, NULL); + d_lockUnlock(d_lock(admin)); + + d_publisherUnregisterInstances(admin->publisher, fellowAddr); + + d_networkAddressFree(fellowAddr); + } else { + d_lockUnlock(d_lock(admin)); + } + } + return result; +} + +void +d_adminAsymRemoveFellow( + d_admin admin, + d_fellow fellow, + c_bool trackFellow) +{ + /* The fellow was asymmetrically disconnected + * Even though the fellow was not actually removed, + * I must do as if it was removed (even if it was + * never actually removed from admin->fellows) + */ + + OS_UNUSED_ARG(trackFellow); + + if (admin && fellow) { + d_printTimedEvent(admin->durability, D_LEVEL_INFO, + "Reestablish connection with asymmetrically disconnected fellow %u.\n", + fellow->address->systemId); + + d_lockLock(d_lock(admin)); + d_adminNotifyListeners(admin, D_FELLOW_REMOVED, fellow, NULL, NULL, NULL); + d_lockUnlock(d_lock(admin)); + } +} + +struct findNsWalkData +{ + const char* name; + c_bool found; +}; + +static void +findNsWalk ( + void* o, void* userData) +{ + struct findNsWalkData* walkData = (struct findNsWalkData*)userData; + if (!walkData->found && (strcmp (d_nameSpaceGetName(d_nameSpace(o)), walkData->name) == 0)) + { + walkData->found = TRUE; + } +} + +/** + * \brief Add a namespace received by the nameSpacesListener to the administration. + * + * This implements dynamic namespace functionality. + */ +void +d_adminAddNameSpace( + d_admin admin, + d_nameSpace nameSpace) +{ + d_durability durability; + struct findNsWalkData walkData; + + /* For convenient logging output */ + const char* akindStr[3] = + {"INITIAL", "LAZY", "ON_REQUEST"}; + const char* dkindStr[5] = + {"VOLATILE", "TRANSIENT_LOCAL", "TRANSIENT", "PERSISTENT", "ALL"}; + + assert(d_objectIsValid(d_object(admin), D_ADMIN) == TRUE); + assert(d_objectIsValid(d_object(nameSpace), D_NAMESPACE) == TRUE); + + durability = d_adminGetDurability(admin); + + if (admin && nameSpace) + { + d_lockLock(d_lock(admin)); + + /* Check if namespace with that name is already in list */ + walkData.name = d_nameSpaceGetName(nameSpace); + + if (walkData.name) + { + walkData.found = FALSE; + + c_iterWalk (admin->nameSpaces, findNsWalk, &walkData); + + if (!walkData.found) + { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Add namespace '%s' to administration with policy {aligner=%d, alignee=%s, durability=%s}\n", + d_nameSpaceGetName(nameSpace), + d_nameSpaceIsAligner(nameSpace), + akindStr[d_nameSpaceGetAlignmentKind(nameSpace)], + dkindStr[d_nameSpaceGetDurabilityKind(nameSpace)]); + + /* Add namespace to admin */ + admin->nameSpaces = c_iterAppend( + admin->nameSpaces, d_objectKeep(d_object(nameSpace))); + + d_printTimedEvent(durability, D_LEVEL_FINER, "Namespace '%s' added to administration, notifying listeners...\n", d_nameSpaceGetName(nameSpace)); + + /* New namespace event */ + d_adminNotifyListeners(admin, D_NAMESPACE_NEW, NULL, nameSpace, NULL, NULL); + } + } + + d_lockUnlock(d_lock(admin)); + } +} + +/* This function may only be called when its context has lock admin */ +d_nameSpace +d_adminGetNameSpaceForGroupNoLock( + d_admin admin, + d_partition partition, + d_topic topic) +{ + d_durability d; + d_configuration c; + d_nameSpace nameSpace; + c_ulong i; + + assert(d_adminIsValid(admin)); + + if (d_isBuiltinGroup(partition, topic)) { + d = d_adminGetDurability(admin); + c = d_durabilityGetConfiguration(d); + if (!c->mustAlignBuiltinTopics) { + return NULL; + } + } + + nameSpace = NULL; + for(i=0; (inameSpaces)) && (nameSpace == NULL); i++) { + nameSpace = d_nameSpace(c_iterObject(admin->nameSpaces, i)); + if (d_adminInNameSpace(nameSpace, partition, topic, FALSE) == TRUE) { + /* do nothing */ + } else { + nameSpace = NULL; + } + } + return nameSpace; +} + +d_nameSpace +d_adminGetNameSpaceForGroup( + d_admin admin, + d_partition partition, + d_topic topic) +{ + d_nameSpace nameSpace; + + assert(d_adminIsValid(admin)); + + d_lockLock (d_lock(admin)); + nameSpace = d_adminGetNameSpaceForGroupNoLock(admin, partition, topic); + d_lockUnlock (d_lock(admin)); + + return nameSpace; +} + +c_bool +d_adminInNameSpace( + d_nameSpace ns, + d_partition partition, + d_topic topic, + c_bool aligner) +{ + d_group group; + c_bool result; + d_durabilityKind durabilityKind = D_DURABILITY_VOLATILE; + result = FALSE; + + /* DCPSHeartbeat has become transient, but must not ever be + * considered by durability + */ + if (strcmp (partition, V_BUILTIN_PARTITION) == 0 && strcmp (topic, V_HEARTBEATINFO_NAME) == 0) { + return FALSE; + } + + if ((group = d_adminGetLocalGroupNoLock(d_threadsDurability()->admin, partition, topic, 0/*kind is don't care in d_adminGetLocalGroup*/)) != NULL) { + durabilityKind = d_groupGetKind(group); + } + /* If DDSI will take care of builtin topic alignment + * (indicated by ns->mustAlignBuiltinTopics == FALSE) + * then durability must exclude builtin topics from + * alignment by durability. + * + * If DDSI does NOT take care of builtin topic alignment + * (indicated by ns->mustAlignBuiltinTopics == TRUE) + * then durability must ALWAYS align these. For this case, a + * namespace is automatically added by durability with the + * proper merge-policy. This is to ensure that builtin + * topics are always aligned even when customers have not + * explicitly configured namespaces for builtin topics. + */ + if (d_isBuiltinGroup(partition, topic)) { + if(!ns->mustAlignBuiltinTopics){ + return FALSE; + } + } + + /* For all non-builtin topics check whether it matches the namespace. */ + if (d_nameSpaceIsIn(ns, partition, topic) == TRUE) { + if(aligner == TRUE) { + if (d_nameSpaceIsAligner(ns) == TRUE) { + result = TRUE; + } + } else { + result = TRUE; + } + } + if (durabilityKind == D_DURABILITY_TRANSIENT_LOCAL) { + result &= ns->mustAlignBuiltinTopics; + } + + return result; +} + +c_bool +d_adminGroupInAligneeNS( + d_admin admin, + d_partition partition, + d_topic topic) +{ + d_nameSpace ns; + c_bool inNameSpace; + c_ulong count, i; + + assert(d_objectIsValid(d_object(admin), D_ADMIN) == TRUE); + + inNameSpace = FALSE; + + d_lockLock (d_lock(admin)); + count = c_iterLength(admin->nameSpaces); + for(i=0; (inameSpaces, i)); + inNameSpace = d_adminInNameSpace(ns, partition, topic, FALSE); + } + d_lockUnlock(d_lock(admin)); + + return inNameSpace; +} + +c_bool +d_adminGroupInActiveAligneeNS( + d_admin admin, + d_partition partition, + d_topic topic) +{ + d_nameSpace ns; + c_bool inNameSpace; + c_ulong count, i; + + assert(d_objectIsValid(d_object(admin), D_ADMIN) == TRUE); + + inNameSpace = FALSE; + + d_lockLock (d_lock(admin)); + count = c_iterLength(admin->nameSpaces); + for(i=0; (inameSpaces, i)); + inNameSpace = d_adminInNameSpace(ns, partition, topic, FALSE); + if (inNameSpace) { + /* Defer alignment of non-builtin topics in case + * alignment policy is ON_REQUEST. + */ + if (!d_isBuiltinGroup(partition, topic)) { + if (d_nameSpaceGetAlignmentKind(ns) == D_ALIGNEE_ON_REQUEST) { + inNameSpace = FALSE; + } + } + } + } + d_lockUnlock (d_lock(admin)); + + return inNameSpace; +} + + +c_bool +d_adminGroupInAlignerNSNoLock( + d_admin admin, + d_partition partition, + d_topic topic) +{ + d_nameSpace ns; + c_bool inNameSpace; + c_ulong count, i; + + assert(d_objectIsValid(d_object(admin), D_ADMIN) == TRUE); + + inNameSpace = FALSE; + count = c_iterLength(admin->nameSpaces); + for(i=0; (inameSpaces, i)); + inNameSpace = d_adminInNameSpace(ns, partition, topic, TRUE); + } + + return inNameSpace; +} + +c_bool +d_adminGroupInAlignerNS( + d_admin admin, + d_partition partition, + d_topic topic) +{ + c_bool inNameSpace; + + assert(d_objectIsValid(d_object(admin), D_ADMIN) == TRUE); + + d_lockLock(d_lock(admin)); + inNameSpace = d_adminGroupInAlignerNSNoLock(admin, partition, topic); + d_lockUnlock(d_lock(admin)); + + return inNameSpace; +} + +c_bool +d_adminGroupInInitialAligneeNS( + d_admin admin, + d_partition partition, + d_topic topic) +{ + d_nameSpace ns; + c_bool inNameSpace; + c_ulong count, i; + + assert(d_objectIsValid(d_object(admin), D_ADMIN) == TRUE); + + inNameSpace = FALSE; + + d_lockLock (d_lock(admin)); + + count = c_iterLength(admin->nameSpaces); + for(i=0; (inameSpaces, i)); + inNameSpace = d_adminInNameSpace(ns, partition, topic, FALSE); + if (inNameSpace == TRUE) { + /* Defer alignment of non-builtin groups in case + * alignment policy does not match INITIAL. + */ + if (!d_isBuiltinGroup(partition, topic)) { + switch(d_nameSpaceGetAlignmentKind(ns)) { + case D_ALIGNEE_INITIAL: + break; + default: + inNameSpace = FALSE; + break; + } + } + } + } + d_lockUnlock(d_lock(admin)); + + return inNameSpace; +} + +d_durability +d_adminGetDurability( + d_admin admin) +{ + assert(d_adminIsValid(admin)); + + return admin->durability; +} + +d_publisher +d_adminGetPublisher( + d_admin admin) +{ + assert(d_objectIsValid(d_object(admin), D_ADMIN) == TRUE); + + return admin->publisher; +} + +d_subscriber +d_adminGetSubscriber( + d_admin admin) +{ + assert(d_objectIsValid(d_object(admin), D_ADMIN) == TRUE); + + return admin->subscriber; +} + +d_networkAddress +d_adminGetMyAddress( + d_admin admin) +{ + d_networkAddress address; + + assert(d_objectIsValid(d_object(admin), D_ADMIN) == TRUE); + address = d_networkAddressNew( + admin->myAddress->systemId, + admin->myAddress->localId, + admin->myAddress->lifecycleId); + + return address; +} + +u_topic +d_adminGetStatusTopic( + d_admin admin) +{ + u_topic topic = NULL; + assert(d_objectIsValid(d_object(admin), D_ADMIN) == TRUE); + + if(admin){ + topic = admin->statusTopic; + } + return topic; +} + +u_topic +d_adminGetNewGroupTopic( + d_admin admin) +{ + u_topic topic = NULL; + assert(d_objectIsValid(d_object(admin), D_ADMIN) == TRUE); + + if(admin){ + topic = admin->newGroupTopic; + } + return topic; +} + +u_topic +d_adminGetGroupsRequestTopic( + d_admin admin) +{ + u_topic topic = NULL; + assert(d_objectIsValid(d_object(admin), D_ADMIN) == TRUE); + + if(admin){ + topic = admin->groupsRequestTopic; + } + return topic; +} + +u_topic +d_adminGetSampleRequestTopic( + d_admin admin) +{ + u_topic topic = NULL; + assert(d_objectIsValid(d_object(admin), D_ADMIN) == TRUE); + + if(admin){ + topic = admin->sampleRequestTopic; + } + return topic; +} + +u_topic +d_adminGetSampleChainTopic( + d_admin admin) +{ + u_topic topic = NULL; + assert(d_objectIsValid(d_object(admin), D_ADMIN) == TRUE); + + if(admin){ + topic = admin->sampleChainTopic; + } + return topic; +} + +u_topic +d_adminGetNameSpacesTopic( + d_admin admin) +{ + u_topic topic = NULL; + assert(d_objectIsValid(d_object(admin), D_ADMIN) == TRUE); + + if(admin){ + topic = admin->nameSpacesTopic; + } + return topic; +} + +u_topic +d_adminGetNameSpacesRequestTopic( + d_admin admin) +{ + u_topic topic = NULL; + assert(d_objectIsValid(d_object(admin), D_ADMIN) == TRUE); + + if(admin){ + topic = admin->nameSpacesRequestTopic; + } + return topic; +} + +u_topic +d_adminGetDeleteDataTopic( + d_admin admin) +{ + u_topic topic = NULL; + assert(d_objectIsValid(d_object(admin), D_ADMIN) == TRUE); + + if(admin){ + topic = admin->deleteDataTopic; + } + return topic; +} + + +u_topic +d_adminGetDurabilityStateRequestTopic( + d_admin admin) +{ + assert(d_adminIsValid(admin)); + + return admin->durabilityStateRequestTopic; +} + + +u_topic +d_adminGetDurabilityStateTopic( + d_admin admin) +{ + assert(d_adminIsValid(admin)); + + return admin->durabilityStateTopic; +} + + +u_topic +d_adminGetHistoricalDataRequestTopic( + d_admin admin) +{ + assert(d_adminIsValid(admin)); + + return admin->historicalDataRequestTopic; +} + +u_topic +d_adminGetHistoricalDataTopic( + d_admin admin) +{ + assert(d_adminIsValid(admin)); + + return admin->historicalDataTopic; +} + +u_topic +d_adminGetCapabilityTopic( + d_admin admin) +{ + assert(d_adminIsValid(admin)); + + return admin->capabilityTopic; +} + + +void +d_adminInitAddress( + v_public entity, + c_voidp args) +{ + d_admin admin; + d_durability durability; + v_gid gid; + + admin = d_admin(args); + assert(d_objectIsValid(d_object(admin), D_ADMIN) == TRUE); + + durability = d_adminGetDurability(admin); + gid = v_kernel(v_object(entity)->kernel)->GID; + admin->myAddress = d_networkAddressNew( + v_gidSystemId(gid), v_gidLocalId(gid), v_gidLifecycleId(gid)); + /* Also set the durability gid that is used for client-side durability. + * The gid is determined as follows: + * - gid.prefix = systemId << 32 + localId + * - gid.suffix = lifecycleId + */ + durability->myServerId.prefix = admin->myAddress->systemId; + durability->myServerId.prefix = ((durability->myServerId.prefix) << 32) + admin->myAddress->localId; + durability->myServerId.suffix = admin->myAddress->lifecycleId; +} + +u_topic +d_adminInitTopic( + d_admin admin, + const c_char* topicName, + const c_char* typeName, + const c_char* keyList, + v_reliabilityKind reliability, + v_historyQosKind historyKind, + v_orderbyKind orderKind, + c_long historyDepth) +{ + v_topicQos topicQos; + u_topic topic; + assert(d_objectIsValid(d_object(admin), D_ADMIN) == TRUE); + topic = NULL; + + topicQos = d_topicQosNew(V_DURABILITY_VOLATILE, reliability); + + if(topicQos){ + topicQos->history.v.kind = historyKind; + topicQos->history.v.depth = historyDepth; + topicQos->orderby.v.kind = orderKind; + + /* Unfortunately d_topicQosNew() delivers different qos settings for the + * max_blocking_time and lease_duration than the defaults. u_topicQosNew() + * is to blame for that. For the clientDurability topics this is compensated + * by explicitly setting these to the defaults. For compatibility reason + * this is not done for the other durability topics. + */ + + if ( (strcmp(topicName, D_DURABILITY_STATE_REQUEST_TOPIC_NAME) == 0) || + (strcmp(topicName, D_DURABILITY_STATE_TOPIC_NAME) == 0) || + (strcmp(topicName, D_HISTORICAL_DATA_REQUEST_TOPIC_NAME) == 0) || + (strcmp(topicName, D_HISTORICAL_DATA_TOPIC_NAME) == 0)) { + topicQos->liveliness.v.lease_duration = OS_DURATION_INFINITE; + topicQos->reliability.v.max_blocking_time = OS_DURATION_INIT(0,100000000); + } + + /* Create the topic */ + topic = u_topicNew( + u_participant(d_durabilityGetService( + d_adminGetDurability(admin))), + topicName, typeName, keyList, topicQos); + d_topicQosFree(topicQos); + } + return topic; +} + +struct localGroupsCompleteArg { + c_bool complete; + c_bool report; + d_durability durability; +}; + +static c_bool +d__adminLocalGroupsCompleteAction( + d_group group, + c_voidp userData) +{ + c_bool result; + struct localGroupsCompleteArg *arg = (struct localGroupsCompleteArg *)userData; + d_completeness c; + + c = d_groupGetCompleteness(group); + if((c != D_GROUP_COMPLETE) && (c != D_GROUP_UNKNOWN)){ + /* If true, all groups will be reported. Otherwise first non-complete group will stop the walk. */ + result = arg->report; + arg->complete = FALSE; + if(arg->report) { + assert(arg->durability); + d_printTimedEvent(arg->durability, D_LEVEL_FINEST, + "Waiting for local group '%s.%s' to become complete.\n", group->partition, group->topic); + } + } else { + result = TRUE; /* Continue walk */ + } + return result; +} + + +c_bool +d_adminAreLocalGroupsComplete( + d_admin admin, + c_bool report) +{ + struct localGroupsCompleteArg arg; + + assert(d_objectIsValid(d_object(admin), D_ADMIN) == TRUE); + + d_lockLock(d_lock(admin)); + if(d_tableSize(admin->groups) >= 1){ + arg.complete = TRUE; + + if(admin->subscriber) { + arg.complete = d_subscriberAreRemoteGroupsHandled(admin->subscriber); + } + + if(arg.complete == TRUE) { + arg.report = report; + if(report){ + arg.durability = d_adminGetDurability(admin); + } + d_tableWalk(admin->groups, &d__adminLocalGroupsCompleteAction, &arg); + } else if (report) { + d_printTimedEvent(d_adminGetDurability(admin), D_LEVEL_FINEST, + "Completeness of local groups not yet determined. Still waiting for remote groups to be handled first.\n"); + } + } else { + arg.complete = FALSE; + } + d_lockUnlock(d_lock(admin)); + + return arg.complete; +} + +c_ulong +d_adminGetFellowCount( + d_admin admin) +{ + c_ulong result; + + assert(d_objectIsValid(d_object(admin), D_ADMIN) == TRUE); + result = 0; + + if(admin){ + d_lockLock(d_lock(admin)); + result = d_tableSize(admin->fellows); + d_lockUnlock(d_lock(admin)); + } + return result; +} + +c_ulong +d_adminGetInitialFellowCount( + d_admin admin) +{ + c_ulong result = 0; + + assert(d_adminIsValid(admin)); + + if (admin) { + d_lockLock(d_lock(admin)); + result = d_tableSize(admin->initial_fellows); + d_lockUnlock(d_lock(admin)); + } + return result; +} + +c_ulong +d_adminGetNameSpacesCount( + d_admin admin) +{ + c_ulong result; + + assert(d_objectIsValid(d_object(admin), D_ADMIN) == TRUE); + result = 0; + + if(admin){ + d_lockLock(d_lock(admin)); + result = c_iterLength(admin->nameSpaces); + d_lockUnlock(d_lock(admin)); + } + return result; +} + +static d_nameSpace +d_adminGetNameSpaceNoLock( + d_admin admin, + os_char* name) +{ + d_nameSpace nameSpace = NULL; + c_ulong i; + + assert(d_objectIsValid(d_object(admin), D_ADMIN) == TRUE); + + if(admin && name){ + + for(i=0; inameSpaces) && !nameSpace; i++){ + nameSpace = d_nameSpace(c_iterObject(admin->nameSpaces, i)); + + if(strcmp(d_nameSpaceGetName(nameSpace), name) == 0){ + nameSpace = d_nameSpace(d_objectKeep(d_object(nameSpace))); + } else { + nameSpace = NULL; + } + } + } + return nameSpace; +} + + +d_nameSpace +d_adminGetNameSpace( + d_admin admin, + os_char* name) +{ + d_nameSpace nameSpace = NULL; + + assert(d_objectIsValid(d_object(admin), D_ADMIN) == TRUE); + + if(admin && name){ + d_lockLock(d_lock(admin)); + nameSpace = d_adminGetNameSpaceNoLock(admin, name); + d_lockUnlock(d_lock(admin)); + } + return nameSpace; +} + + +c_bool +d_adminFellowWalk( + d_admin admin, + c_bool ( * action ) (d_fellow fellow, c_voidp userData), + c_voidp userData) +{ + c_bool result; + + assert(d_objectIsValid(d_object(admin), D_ADMIN) == TRUE); + result = FALSE; + + if(admin){ + result = TRUE; + d_lockLock(d_lock(admin)); + d_tableWalk(admin->fellows, action, userData); + d_lockUnlock(d_lock(admin)); + } + return result; +} + +c_bool +d_adminInitialFellowWalk( + d_admin admin, + c_bool ( * action ) (d_fellow fellow, c_voidp userData), + c_voidp userData) +{ + c_bool result; + + assert(d_objectIsValid(d_object(admin), D_ADMIN) == TRUE); + result = FALSE; + + if(admin){ + result = TRUE; + d_lockLock(d_lock(admin)); + (void)d_tableWalk(admin->initial_fellows, action, userData); + d_lockUnlock(d_lock(admin)); + } + return result; +} + + +void +d_adminNameSpaceWalk( + d_admin admin, + void (*action) (d_nameSpace nameSpace, c_voidp userData), + c_voidp userData) +{ + assert(d_objectIsValid(d_object(admin), D_ADMIN) == TRUE); + + if(admin){ + d_lockLock(d_lock(admin)); + c_iterWalk(admin->nameSpaces, (c_iterWalkAction)action, userData); + d_lockUnlock(d_lock(admin)); + } +} + +static void +collectNsWalk( + d_nameSpace ns, void* userData) +{ + c_iter nameSpaces = (c_iter)userData; + + if (ns) + { + d_objectKeep(d_object(ns)); + assert(nameSpaces != NULL); + (void)c_iterInsert (nameSpaces, ns); + } +} + +static void +deleteNsWalk( + void* o, void* userData) +{ + OS_UNUSED_ARG(userData); + d_nameSpaceFree(o); +} + +c_iter +d_adminNameSpaceCollect( + d_admin admin) +{ + c_iter result; + result = c_iterNew(NULL); + d_adminNameSpaceWalk(admin, collectNsWalk, result); + return result; +} + +void +d_adminNameSpaceCollectFree( + d_admin admin, + c_iter nameSpaces) +{ + OS_UNUSED_ARG(admin); + c_iterWalk(nameSpaces, deleteNsWalk, NULL); + c_iterFree(nameSpaces); +} + + +void +d_adminGroupWalk( + d_admin admin, + c_bool ( * action ) (d_group group, c_voidp userData), + c_voidp args) +{ + assert(d_objectIsValid(d_object(admin), D_ADMIN) == TRUE); + + if(admin){ + d_lockLock(d_lock(admin)); + d_tableWalk(admin->groups, action, args); + d_lockUnlock(d_lock(admin)); + } +} + +void +d_adminAddListener( + d_admin admin, + d_eventListener listener) +{ + assert(d_objectIsValid(d_object(admin), D_ADMIN) == TRUE); + assert(d_objectIsValid(d_object(listener), D_EVENT_LISTENER) == TRUE); + + if (admin && listener) { + if (admin->initMask & D__INIT_FLAG_EVENT_MUTEX) { + os_mutexLock(&admin->eventMutex); + admin->eventListeners = c_iterInsert(admin->eventListeners, listener); + os_mutexUnlock(&admin->eventMutex); + } + } +} + +void +d_adminRemoveListener( + d_admin admin, + d_eventListener listener) +{ + assert(d_objectIsValid(d_object(admin), D_ADMIN) == TRUE); + assert(d_objectIsValid(d_object(listener), D_EVENT_LISTENER) == TRUE); + + if (admin && listener) { + if (admin->initMask & D__INIT_FLAG_EVENT_MUTEX) { + os_mutexLock(&admin->eventMutex); + c_iterTake(admin->eventListeners, listener); + os_mutexUnlock(&admin->eventMutex); + } + } +} + + +/* TODO: redesign this to pass through only userdata */ +void +d_adminNotifyListeners( + d_admin admin, + c_ulong mask, + d_fellow fellow, + d_nameSpace nameSpace, + d_group group, + c_voidp userData) +{ + d_adminEvent event; + + assert(d_objectIsValid(d_object(admin), D_ADMIN) == TRUE); + + if(admin){ + event = d_adminEventNew(mask, fellow, nameSpace, group, userData); + os_mutexLock(&admin->eventMutex); + admin->eventQueue = c_iterAppend(admin->eventQueue, event); + os_condSignal(&admin->eventCondition); + os_mutexUnlock(&admin->eventMutex); + } +} + + +d_adminEvent +d_adminEventNew( + c_ulong event, + d_fellow fellow, + d_nameSpace nameSpace, + d_group group, + c_voidp userData) +{ + d_adminEvent evt = NULL; + d_networkAddress addr; + c_char *topic, *partition; + v_group vgroup; + + /* Allocate adminEvent object */ + evt = d_adminEvent(os_malloc(C_SIZEOF(d_adminEvent))); + if (evt) { + /* Call super-init */ + d_objectInit(d_object(evt), D_ADMIN_EVENT, + (d_objectDeinitFunc)d_adminEventDeinit); + /* Initialize adminEvent */ + evt->event = event; + evt->userData = userData; + if (fellow) { + assert(d_fellowIsValid(fellow)); + addr = d_fellowGetAddress(fellow); + evt->fellow = d_fellowNew(addr, d_fellowGetState(fellow), TRUE); + d_networkAddressFree(addr); + } else { + evt->fellow = NULL; + } + if (group) { + assert(d_objectIsValid(d_object(group), D_GROUP) == TRUE); + partition = d_groupGetPartition(group); + topic = d_groupGetTopic(group); + evt->group = d_groupNew (partition, topic, d_groupGetKind(group), + d_groupGetCompleteness(group), + d_groupGetQuality(group)); + vgroup = d_groupGetKernelGroup(group); + if (vgroup) { + d_groupSetKernelGroup(evt->group, vgroup); + c_free(vgroup); + } + os_free(partition); + os_free(topic); + } else { + evt->group = NULL; + } + if (nameSpace) { + assert(d_nameSpaceIsValid(nameSpace)); + evt->nameSpace = nameSpace; + } else { + evt->nameSpace = NULL; + } + } + return evt; +} + + +void +d_adminEventDeinit( + d_adminEvent event) +{ + assert(d_adminEventIsValid(event)); + + if (event->fellow) { + d_fellowFree(event->fellow); + } + if (event->group) { + d_groupFree(event->group); + } + /* Call super-deinit */ + d_objectDeinit(d_object(event)); +} + + +void +d_adminEventFree( + d_adminEvent event) +{ + assert(d_adminEventIsValid(event)); + + d_objectFree(d_object(event)); +} + + +void* +d_adminEventThreadStart( + void* arg) +{ + d_thread self = d_threadLookupSelf (); + d_admin admin; + d_adminEvent event; + d_eventListener listener; + c_ulong i; + + admin = d_admin(arg); + + while(admin->eventThreadTerminate == FALSE){ + os_mutexLock(&admin->eventMutex); + event = c_iterTakeFirst(admin->eventQueue); + os_mutexUnlock(&admin->eventMutex); + + while(event){ + for(i=0; ieventListeners); i++){ + listener = d_eventListener(c_iterObject(admin->eventListeners, i)); + + if((listener->interest & event->event) == event->event){ + (void)listener->func(event->event, event->fellow, event->nameSpace, + event->group, event->userData, listener->args); + } + } + d_adminEventFree(event); + os_mutexLock(&admin->eventMutex); + event = c_iterTakeFirst(admin->eventQueue); + os_mutexUnlock(&admin->eventMutex); + } + os_mutexLock(&admin->eventMutex); + + if((c_iterLength(admin->eventQueue) == 0) && (admin->eventThreadTerminate == FALSE)){ + d_condWait(self, &admin->eventCondition, &admin->eventMutex); + } + os_mutexUnlock(&admin->eventMutex); + } + + /* Added assert to ensure the conflictResolver is always stopped after this thread */ + assert(admin->conflictResolver != NULL); + + return NULL; +} + + + +d_actionQueue +d_adminGetActionQueue( + d_admin admin) +{ + d_actionQueue queue = NULL; + + assert(d_objectIsValid(d_object(admin), D_ADMIN) == TRUE); + + if(admin) { + d_lockLock(d_lock(admin)); + queue = admin->actionQueue; + d_lockUnlock(d_lock(admin)); + } + return queue; +} + + +static c_bool +getIncompatibleStateCount( + d_fellow fellow, + c_voidp args) +{ + c_ulong* count; + + count = (c_ulong*)args; + + if(d_fellowGetCommunicationState(fellow) == D_COMMUNICATION_STATE_INCOMPATIBLE_STATE){ + (*count)++; + } + return TRUE; +} + +c_ulong +d_adminGetIncompatibleStateCount( + d_admin admin) +{ + c_ulong count; + + assert(d_objectIsValid(d_object(admin), D_ADMIN) == TRUE); + count = 0; + + if(admin) { + d_lockLock(d_lock(admin)); + d_tableWalk(admin->fellows, getIncompatibleStateCount, &count); + d_lockUnlock(d_lock(admin)); + } + return count; +} + +static c_bool +getIncompatibleDataModelCount( + d_fellow fellow, + c_voidp args) +{ + c_ulong* count; + + count = (c_ulong*)args; + + if (d_fellowGetCommunicationState(fellow) == D_COMMUNICATION_STATE_INCOMPATIBLE_DATA_MODEL) { + (*count)++; + } + return TRUE; +} + +c_ulong +d_adminGetIncompatibleDataModelCount( + d_admin admin) +{ + c_ulong count; + + assert(d_objectIsValid(d_object(admin), D_ADMIN) == TRUE); + count = 0; + + if(admin) { + d_lockLock(d_lock(admin)); + d_tableWalk(admin->fellows, getIncompatibleDataModelCount, &count); + d_lockUnlock(d_lock(admin)); + } + return count; +} + +c_bool +d_adminAddReaderRequest( + d_admin admin, + d_readerRequest request) +{ + d_readerRequest found; + c_bool result; + + assert(d_objectIsValid(d_object(admin), D_ADMIN) == TRUE); + + if(admin && request){ + d_lockLock(d_lock(admin)); + found = d_tableInsert(admin->readerRequests, request); + d_lockUnlock(d_lock(admin)); + + if(!found){ + d_objectKeep(d_object(request)); + result = TRUE; + } else { + result = FALSE; + } + } else { + result = FALSE; + } + return result; +} + +c_bool +d_adminRemoveReaderRequest( + d_admin admin, + d_networkAddress source) +{ + d_readerRequest request, found; + c_bool result; + v_handle handle; + + assert(d_objectIsValid(d_object(admin), D_ADMIN) == TRUE); + + if(admin && source){ + handle.index = source->systemId; + handle.serial = source->localId; + handle.server = 0; + request = d_readerRequestProxyNew(handle); + + d_lockLock(d_lock(admin)); + found = d_tableRemove(admin->readerRequests, request); + d_lockUnlock(d_lock(admin)); + + d_readerRequestFree(request); + + if(found){ + d_readerRequestFree(found); + result = TRUE; + } else { + result = FALSE; + } + } else { + result = FALSE; + } + return result; +} + +d_readerRequest +d_adminGetReaderRequest( + d_admin admin, + d_networkAddress source) +{ + d_readerRequest request, found; + v_handle handle; + + assert(d_objectIsValid(d_object(admin), D_ADMIN) == TRUE); + + if(admin && source){ + handle.index = source->systemId; + handle.serial = source->localId; + handle.server = 0; + request = d_readerRequestProxyNew(handle); + + d_lockLock(d_lock(admin)); + found = d_tableFind(admin->readerRequests, request); + + if(found){ + d_objectKeep(d_object(found)); + } + d_lockUnlock(d_lock(admin)); + d_readerRequestFree(request); + } else { + found = NULL; + } + return found; +} + +c_bool +d_adminCheckReaderRequestFulfilled( + d_admin admin, + d_readerRequest request) +{ + c_bool result; + d_readerRequest found; + v_reader reader; + v_handle handle; + v_handleResult handleResult; + + assert(d_objectIsValid(d_object(admin), D_ADMIN) == TRUE); + assert(d_objectIsValid(d_object(request), D_READER_REQUEST) == TRUE); + + if(admin && request){ + d_lockLock(d_lock(admin)); + found = d_tableFind(admin->readerRequests, request); + + if(found){ + if(!d_readerRequestHasChains(found)){ + if(d_readerRequestAreGroupsComplete(found)){ + found = d_tableRemove(admin->readerRequests, request); + if (d_readerRequestGetGroupIgnored(found) == FALSE){ + handle = d_readerRequestGetHandle(found); + handleResult = v_handleClaim(handle, (v_object*)&reader); + + if(handleResult == V_HANDLE_OK){ + v_readerNotifyStateChange(reader, TRUE); + v_handleRelease(handle); + } + } + result = TRUE; + d_readerRequestFree(found); + } else { + result = FALSE; + } + } else { + result = FALSE; + } + } else { + result = FALSE; + } + d_lockUnlock(d_lock(admin)); + } else { + result = FALSE; + } + return result; +} + + +c_bool +d_nameSpaceCountMastersForRoleWalk ( + d_fellow fellow, + void* userData) +{ + d_nameSpace fellowNameSpace; + d_networkAddress fellowAddress, nsMaster; + struct masterCountForRoleHelper* helper; + d_name fellowRole; + + helper = (struct masterCountForRoleHelper*)userData; + fellowRole = d_fellowGetRole(fellow); + + if (fellowRole) { + if (strcmp(fellowRole, helper->role) == 0) { + fellowNameSpace = d_fellowGetNameSpace (fellow, helper->nameSpace); + + if (fellowNameSpace) { + fellowAddress = d_fellowGetAddress (fellow); + nsMaster = d_nameSpaceGetMaster (fellowNameSpace); + + if (d_networkAddressEquals (fellowAddress, nsMaster)) { + helper->masterCount++; + } + d_networkAddressFree (fellowAddress); + d_networkAddressFree (nsMaster); + } + } + } + + return TRUE; +} + + +void +d_adminReportMaster( + d_admin admin, + d_fellow fellow, + d_nameSpace nameSpace) +{ + /* Check for conflicts, and if a conflict is found, add it to the resolver queue. */ + d_conflictMonitorCheckForConflicts(admin->conflictMonitor, fellow, nameSpace); +} + + +void +d_adminReportDelayedInitialSet ( + d_admin admin, + d_nameSpace nameSpace, + d_fellow fellow) +{ + d_durability durability; + d_nameSpace localNameSpace; + d_quality q; + d_subscriber subscriber; + d_nameSpacesRequestListener nsrListener; + d_networkAddress addr; + + subscriber = d_adminGetSubscriber(admin); + nsrListener = d_subscriberGetNameSpacesRequestListener(subscriber); + durability = admin->durability; + localNameSpace = d_adminGetNameSpace(admin, d_nameSpaceGetName(nameSpace)); + + /* Do not report when the namespace is not configured to allow delayed alignment. */ + if(localNameSpace && d_nameSpaceGetDelayedAlignment(localNameSpace)) { + + /* Get quality of local namespace */ + q = d_nameSpaceGetInitialQuality(localNameSpace); + + /* If own quality is non-zero, delayed alignment is not allowed. */ + if (d_qualityCompare(q, D_QUALITY_ZERO) == OS_EQUAL) { + + /* When the namespace-master is not confirmed, the service is determining masters, in which case this will resolve itself. */ + if(d_nameSpaceIsMasterConfirmed(localNameSpace)) { + + /* Set namespace state to pending - so incoming namespace messages will not re-trigger the namespacesListener. */ + d_nameSpaceMasterPending(localNameSpace); + + /* Set master to 0 */ + addr = d_networkAddressNew(0,0,0); + d_nameSpaceSetMaster(localNameSpace, addr); + d_networkAddressFree(addr); + + /* Let others know that I'm reconsidering my master */ + d_nameSpacesRequestListenerReportNameSpaces(nsrListener); + + d_printTimedEvent(durability, D_LEVEL_FINER, + "Delayed initial set discovered for namespace '%s'.\n", + d_nameSpaceGetName(nameSpace)); + + /* Notify others that a delayed initial set is available */ + d_adminNotifyListeners(admin, D_NAMESPACE_DELAYED_INITIAL, fellow, localNameSpace, NULL, NULL); + } + } else { + d_printTimedEvent( + durability, D_LEVEL_FINER, + "No delayed alignment for local namespace '%s', local quality is non-zero.\n", + d_nameSpaceGetName(nameSpace)); + } + } else { + d_printTimedEvent( + durability, D_LEVEL_FINEST, + "No delayed alignment for local namespace '%s', namespace does not exist locally, or delayed alignment is not enabled.\n", + d_nameSpaceGetName(nameSpace)); + } + if (localNameSpace) { + d_nameSpaceFree(localNameSpace); + } +} + +static c_bool +cleanupTerminateFellowsAction( + d_fellow fellow, + c_voidp args) +{ + os_timeM timeToRemove; + struct cleanupData *data; + d_durability durability; + d_configuration config; + + data = (struct cleanupData*)(args); + durability = data->durability; + config = d_durabilityGetConfiguration(durability); + /* Select the fellow if its removalTime is more than + * config->terminateRemovalPeriod in the past. This + * is currently fixed to 5sec. + */ + timeToRemove = os_timeMAdd(fellow->removalTime, config->terminateRemovalPeriod); + if (os_timeMCompare(timeToRemove, os_timeMGet()) == OS_LESS) { + /* The fellow has been removed at least terminateRemovalPeriod ago. + * Now it is safe to remove it from the admin->terminateFellows list + */ + data->fellows = c_iterInsert(data->fellows, fellow); + } + return TRUE; +} + +/** + * \brief Clean up fellows that have terminated. + * + * Fellows that have recently terminated are stored some while + * in admin->terminateFellows. The durability service will be + * immune for messages from the fellow that are received AFTER + * the fellow has been removed for config->terminateRemovalPeriod + * seconds. A monotonic clock is used so that any time spent in + * hibernate state is not counted. + */ +void +d_adminCleanupTerminateFellows( + d_admin admin) +{ + struct cleanupData data; + d_fellow fellow; + d_networkAddress address; + d_durability durability; + + assert(d_objectIsValid(d_object(admin), D_ADMIN) == TRUE); + + durability = admin->durability; + data.fellows = c_iterNew(NULL); + data.durability = durability; + + d_lockLock(d_lock(admin)); + (void)d_tableWalk(admin->terminateFellows, cleanupTerminateFellowsAction , &data); + fellow = c_iterTakeFirst(data.fellows); + while(fellow){ + address = d_fellowGetAddress(fellow); + d_printTimedEvent(durability, D_LEVEL_FINER, + "Cleaning up terminated fellow %u\n", + address->systemId); + d_networkAddressFree(address); + (void)d_tableRemove(admin->terminateFellows, fellow); + d_fellowFree(fellow); + fellow = c_iterTakeFirst(data.fellows); + } + d_lockUnlock(d_lock(admin)); + c_iterFree(data.fellows); +} + + +/** + * \brief Collect the group if it matches the specified partitionExpr + * and topic in the argument. + * + * Groups are only collected under the following conditions. + * - The group must match a namespace for which I am aligner, and + * - The orginating request for this group was explicitly addressed + * to me, or the request was addressed to everybody and I am master + * for the namespace of the group. + * + * This implies that groups for which I am not an aligner are + * never collected. + * + * Every group that is collected is added to helper->matchingGroups. + */ +static c_bool +collectMatchingGroups( + d_group group, + c_voidp arg) +{ + c_string partitionExpr; + d_group duplicate; + struct collectMatchingGroupsHelper *helper = (struct collectMatchingGroupsHelper *)arg; + c_bool isAligner; + c_bool isResponsible = FALSE; + c_bool masterKnown = FALSE; + c_bool toCollect = FALSE; + d_nameSpace nameSpace; + d_admin admin; + c_iterIter iter; + d_durability durability; + + assert(d_groupIsValid(group)); + + admin = helper->admin; + assert(d_adminIsValid(admin)); + durability = d_adminGetDurability(admin); + iter = c_iterIterGet(helper->partitions); + + d_printTimedEvent(durability, D_LEVEL_FINER, + " Checking group '%s.%s'\n", group->partition, group->topic); + /* The server reacts to all requests, even requests for private groups. + * This is to enable remote monitoring use case where a remote application + * wants to see the group state of a remote federation. It is the client's + * responsibility to prevent unnecessary requests, not the server's responsibility + * to deny a request. + */ + while (((partitionExpr = (c_string)c_iterNext(&iter)) != NULL) && (!toCollect)) { + /* Look for a partitionExpr.topic that matches the group. */ + d_printTimedEvent(durability, D_LEVEL_FINEST, + " Using partition expression '%s'\n", partitionExpr); + + if ( d_patternMatch(group->partition, partitionExpr) && (strcmp(group->topic, helper->topic) == 0) ) { + + d_printTimedEvent(durability, D_LEVEL_FINER, + " Match for partition expression '%s' and topic '%s'\n", partitionExpr, helper->topic); + + /* Collect group data if I am aligner for the group AND the + * request was addressed to me, or if it the request was + * addressed to everyone and I am master for the group + */ + nameSpace = d_adminGetNameSpaceForGroupNoLock(admin, group->partition, group->topic); + if (nameSpace) { + isAligner = d_nameSpaceIsAligner(nameSpace); + masterKnown = d_nameSpaceIsMasterConfirmed(nameSpace); + if (masterKnown ) { + isResponsible = d_nameSpaceMasterIsMe(nameSpace, admin); + } + + /* Only collect groups for which I can be aligner */ + if (isAligner) { + if (helper->forMe) { + /* Always collect groups for requests that are explicitly addressed to me. */ + toCollect = TRUE; + } else if (helper->forEverybody) { + /* Always collect groups for DurabilityStateRequests that are addressed to everybody. + * Only collect groups for HistoricalDataRequests hat are addressed to everybody only if I am responsible. + */ + toCollect = (helper->isHistoricalDataRequest) ? (isResponsible==TRUE) : TRUE; + } + } + + d_printTimedEvent(durability, D_LEVEL_FINEST, + " Matching namespace '%s' found for group '%s.%s' (isAligner=%d, isResponsible=%d, forMe=%d, forEverybody=%d, toCollect=%d)\n", + nameSpace->name, group->partition, group->topic, isAligner, isResponsible, helper->forMe, helper->forEverybody, toCollect); + + helper->isAligner |= isAligner; /* I am an aligner for a matching request */ + helper->isResponsible |= isResponsible; /* I am responsible for a matching request */ + + if (toCollect) { + /* The group is a valid candidate to be aligned */ + duplicate = d_tableInsert(helper->matchingGroups, d_objectKeep(d_object(group))); + if (!duplicate) { + d_printTimedEvent(durability, D_LEVEL_FINER, + " Collecting group '%s.%s' collected partition expression '%s' and topic '%s'\n", + group->partition, group->topic, partitionExpr, helper->topic); + } + /* Done checking this group, I am going to align it */ + } + } else { + d_printTimedEvent(durability, D_LEVEL_FINEST, + " No namespace found for group '%s.%s'\n", group->partition, group->topic); + } + } else { + d_printTimedEvent(durability, D_LEVEL_FINEST, + " No match for partition expression '%s', skip\n", partitionExpr); + } + } /* while */ + return !toCollect; +} + + +/** + * \brief Check if the nameSpace matches one of the partition expressions and + * topic in arg. To match the namespace must be configured as aligner. + */ +static void +hasMatchingAlignerNameSpace( + d_nameSpace nameSpace, + void *arg) +{ + struct collectMatchingGroupsHelper *helper = (struct collectMatchingGroupsHelper *)arg; + c_iterIter iter; + c_string partitionExpr; + d_admin admin; + d_durability durability; + + assert(d_nameSpaceIsValid(nameSpace)); + + admin = helper->admin; + /* Not yet found evidence that a response must be sent */ + durability = d_adminGetDurability(admin); + + d_printTimedEvent(durability, D_LEVEL_FINEST, + " Checking namespace '%s'\n", nameSpace->name); + if (d_nameSpaceIsAligner(nameSpace)) { + d_printTimedEvent(durability, D_LEVEL_FINEST, + " Namespace '%s' is aligner, check against partition expressions\n", nameSpace->name); + iter = c_iterIterGet(helper->partitions); + while (((partitionExpr = (c_string)c_iterNext(&iter)) != NULL) && (!helper->isAligner)) { + d_printTimedEvent(durability, D_LEVEL_FINEST, + " Check against partition expression '%s'\n", partitionExpr); + if (d_nameSpaceIsIn(nameSpace, partitionExpr, helper->topic)) { + d_printTimedEvent(durability, D_LEVEL_FINEST, + " Partition expression '%s' does match aligner namespace '%s'\n", partitionExpr, nameSpace->name); + /* The nameSpace is aligner and matches partitionExpr.topic */ + helper->isAligner = TRUE; + /* Check if I am responsible for alignment (i.e., I am able to align) */ + if (d_nameSpaceIsMasterConfirmed(nameSpace)) { + helper->isResponsible |= d_nameSpaceMasterIsMe(nameSpace, admin); + helper->masterKnown = TRUE; + } + + d_printTimedEvent(durability, D_LEVEL_FINEST, + " helper->isAligner=%d, helper->isResponsible=%d helper->masterKnown=%d\n", + helper->isAligner, helper->isResponsible, helper->masterKnown); + } else { + d_printTimedEvent(durability, D_LEVEL_FINEST, + " Partition expression '%s' does NOT match aligner namespace '%s'\n", partitionExpr, nameSpace->name); + } + } + } else { + d_printTimedEvent(durability, D_LEVEL_FINEST, + " Namespace '%s' is NOT aligner, skip\n"); + + } +} + + +/** + * \brief Collect all groups that match the specified partitionExpr.topic + * in the argument, and decide if a response is required. + */ +void +d_adminCollectMatchingGroups( + d_admin admin, + void *arg) +{ + struct collectMatchingGroupsHelper *helper = (struct collectMatchingGroupsHelper *)arg; + + d_durability durability = d_adminGetDurability(admin); + + d_printTimedEvent(durability, D_LEVEL_FINER, + " Start calculating the matching groups\n"); + + /* Collect all groups for which data must be retrieved. */ + d_adminGroupWalk(admin, collectMatchingGroups, helper); + + d_printTimedEvent(durability, D_LEVEL_FINER, + " End calculating matching groups (%d)\n", d_tableSize(helper->matchingGroups)); + + helper->groupFound = (d_tableSize(helper->matchingGroups) > 0); + + /* We now have collected all groups that matched the request. */ + if (!helper->isAligner) { + /* I have not yet found a namespace that matches one of the + * partition/topic expressions and for which I am aligner. This + * might be because only namespaces for groups have been checked, + * but there may be namespaces for which there are no groups yet. + * So let's find out if there exists a namespace that matches + * my request and for which I am aligner. + */ + + d_printTimedEvent(durability, D_LEVEL_FINEST, + " No matching aligner namespace found yet, check all namespaces now\n"); + + d_adminNameSpaceWalk(admin, hasMatchingAlignerNameSpace, helper); + } + return; +} + +/** + * \brief Get the sql expressions for which the static filter expression matches the + * partition and topic + * + * If no match is found NULL is returned. + */ +char * +d_adminGetStaticFilterExpression( + d_admin admin, + char *partition, + char *topic) +{ + c_iterIter iter, iter2; + d_durability durability; + d_configuration config; + c_bool matchFound = FALSE; + d_filter filter; + d_element element; + + assert(d_adminIsValid(admin)); + assert(partition); + assert(topic); + + /* Walk over the filters and return the sql expression as + * soon as there is a match + */ + durability = d_adminGetDurability(admin); + config = d_durabilityGetConfiguration(durability); + if (config->filters) { + iter = c_iterIterGet(config->filters); + while ((!matchFound) && ((filter = (d_filter)c_iterNext(&iter)) != NULL)) { + iter2 = c_iterIterGet(filter->elements); + while ((!matchFound) && ((element = (d_element)c_iterNext(&iter2)) != NULL)) { + if (d_patternMatch(partition, element->partition) && + d_patternMatch(topic, element->topic)) { + /* Match found */ + matchFound = TRUE; + } + } + } + } + if (matchFound) { + return filter->sqlExpression; + } else { + return NULL; + } +} + + +d_client +d_adminGetClient( + d_admin admin, + d_networkAddress address) +{ + d_client dummy, found; + + assert(d_adminIsValid(admin)); + + d_lockLock(d_lock(admin)); + dummy = d_clientNew(address); + found = d_tableFind(admin->clients, dummy); + d_clientFree(dummy); + if (found) { + found = d_client(d_objectKeep(d_object(found))); + } + d_lockUnlock(d_lock(admin)); + return found; +} + + +d_client +d_adminAddClient( + d_admin admin, + d_client client) +{ + d_client result, duplicate; + + assert(d_adminIsValid(admin)); + assert(d_clientIsValid(client)); + assert(admin->clients); /* If and only if config->clientDurabilityEnabled is TRUE */ + + d_lockLock(d_lock(admin)); + duplicate = d_tableInsert(admin->clients, client); + if (!duplicate) { + d_networkAddress clientAddr = d_clientGetAddress(client); + result = d_client(d_objectKeep(d_object(client))); + d_printTimedEvent(admin->durability, D_LEVEL_INFO, + "Adding client for federation %u.\n", clientAddr->systemId); + d_networkAddressFree(clientAddr); + } else { + result = d_client(d_objectKeep(d_object(duplicate))); + } + d_lockUnlock(d_lock(admin)); + return result; +} + + +d_client +d_adminRemoveClient( + d_admin admin, + d_client client) +{ + d_client found = NULL; + + assert(d_adminIsValid(admin)); + assert(d_clientIsValid(client)); + assert(admin->clients); /* If and only if config->clientDurabilityEnabled is TRUE */ + + d_lockLock(d_lock(admin)); + found = d_client(d_tableRemove(admin->clients, client)); + if (found) { + d_networkAddress clientAddr = d_clientGetAddress(found); + d_printTimedEvent(admin->durability, D_LEVEL_INFO, + "Removing client for federation %u.\n", clientAddr->systemId); + d_networkAddressFree(clientAddr); + } + d_lockUnlock(d_lock(admin)); + return found; +} + + +d_client +d_adminFindClientByClientId( + d_admin admin, + struct _DDS_Gid_t clientId) +{ + d_tableIter tableIter; + d_client client = NULL; + c_bool found = FALSE; + + assert(d_adminIsValid(admin)); + + /* Currently we do a linear walk over admin->clients to find the + * client with the specified clientId. Better would be to use a + * tree structure + */ + d_lockLock(d_lock(admin)); + client = d_client(d_tableIterFirst(admin->clients, &tableIter)); + while ((client) && (!found)) { + if ((found = ((client->clientId.prefix == clientId.prefix) && (client->clientId.suffix == clientId.suffix))) == FALSE) { + client = d_client(d_tableIterNext(&tableIter)); + } + } + d_lockUnlock(d_lock(admin)); + return client; +} + +os_uint32 +d_adminGetNextSeqNum( + d_admin admin) +{ + os_uint32 seqnum; + c_bool wrap = FALSE; + + assert(d_adminIsValid(admin)); + + /* Increment the sequence number (32-bit unsigned) atomically. */ + os_mutexLock(&admin->seqnumMutex); + if (admin->seqnum == D_MAX_VALID_SEQNUM) { + wrap = TRUE; + admin->seqnum = 1; + } else { + admin->seqnum += 1; + } + seqnum = admin->seqnum; + os_mutexUnlock(&admin->seqnumMutex); + if (wrap) { + d_durability durability = d_adminGetDurability(admin); + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Durability service sequence number has reached max (%"PA_PRIu32"), wrapping occurred\n", D_MAX_VALID_SEQNUM); + } + return seqnum; +} + +c_iter +d_adminGetNameSpaces( + d_admin admin) +{ + c_iter nameSpaces = NULL; + c_iterIter iter; + d_nameSpace nameSpace; + + if (c_iterLength(admin->nameSpaces) > 0) { + nameSpaces = c_iterNew(NULL); + iter = c_iterIterGet(admin->nameSpaces); + while ((nameSpace = d_nameSpace(c_iterNext(&iter))) != NULL) { + nameSpaces = c_iterAppend(nameSpaces, d_objectKeep(d_object(nameSpace))); + } + } + return nameSpaces; +} + +void +d_admin_sync_mergeStates( + d_admin admin) +{ + d_durability durability; + d_nameSpace nameSpace; + c_iter nameSpaces; + c_bool synced = FALSE; + c_iterIter iter; + d_mergeState mergeState, advertisedMergeState; + durability = d_adminGetDurability(admin); + + d_printTimedEvent(durability, D_LEVEL_FINER, + "No more pending conflicts, going to sync the advertised namespace states for which I am confirmed master\n"); + + nameSpaces = d_adminGetNameSpaces(admin); + iter = c_iterIterGet(nameSpaces); + while ((nameSpace = d_nameSpace(c_iterNext(&iter))) != NULL) { + if (d_nameSpaceMasterIsMe(nameSpace, admin) && d_nameSpaceIsMasterConfirmed(nameSpace)) { + c_long mv, amv; + + mergeState = d_nameSpaceGetMergeState(nameSpace, NULL); + advertisedMergeState = d_nameSpaceGetAdvertisedMergeState(nameSpace); + /* I am the confirmed master of a namespace, so the mergeState and advertisedMergeState + * can never be cleared + */ + assert(mergeState == NULL || advertisedMergeState == NULL || strcmp(mergeState->role, advertisedMergeState->role) == 0); + + mv = mergeState ? (c_long)mergeState->value : -1; + amv = advertisedMergeState ? (c_long)advertisedMergeState->value : -1; + + d_printTimedEvent(durability, D_LEVEL_FINE, + " - Syncing namespace state for namespace '%s' in role '%s' (%d -> %d)\n", + nameSpace->name, nameSpace->mergeState->role, amv, mv); + + /* Sync the advertised mergeState with the internal mergeState */ + if (mv != amv) { + d_nameSpaceSyncMergeState(nameSpace); + synced = TRUE; + } + + d_mergeStateFree(mergeState); + d_mergeStateFree(advertisedMergeState); + + } + } + + /* Cleanup the nameSpaces */ + nameSpace = d_nameSpace(c_iterTakeFirst(nameSpaces)); + while(nameSpace){ + d_nameSpaceFree(nameSpace); + nameSpace = d_nameSpace(c_iterTakeFirst(nameSpaces)); + } + c_iterFree (nameSpaces); + + /* Advertise namespaces in case syncing took place */ + if (synced) { + d_subscriber subscriber = d_adminGetSubscriber(admin); + d_nameSpacesRequestListener nsrListener = d_subscriberGetNameSpacesRequestListener(subscriber); + + d_nameSpacesRequestListenerReportNameSpaces(nsrListener); + } + +} + +void +d_adminReportGroup( + d_admin admin, + d_group group) +{ + d_newGroup newGroup; + d_completeness completeness; + d_networkAddress addr; + c_char *partition, *topic; + d_publisher publisher; + d_durabilityKind kind; + c_bool inNameSpace; + d_durability durability; + d_quality quality; + + if(!d_groupIsPrivate(group)){ + durability = d_adminGetDurability(admin); + publisher = d_adminGetPublisher(admin); + + completeness = d_groupGetCompleteness(group); + partition = d_groupGetPartition(group); + topic = d_groupGetTopic(group); + quality = d_groupGetQuality(group); + kind = d_groupGetKind(group); + + inNameSpace = d_adminGroupInAlignerNS(admin, partition, topic); + + if((inNameSpace == TRUE) || (completeness != D_GROUP_COMPLETE)) { + d_printTimedEvent(durability, D_LEVEL_FINER, + "Reporting group %s.%s, kind: %u, completeness: %u\n", + partition, topic, kind, completeness); + newGroup = d_newGroupNew(admin, partition, topic, kind, completeness, + quality); + addr = d_networkAddressUnaddressed(); + d_publisherNewGroupWrite(publisher, newGroup, addr); + d_networkAddressFree(addr); + d_newGroupFree(newGroup); + } + os_free(partition); + os_free(topic); + } + return; +} + +struct groupAdmin { + d_group group; + c_bool isAligner; +}; + +struct collectNameSpaceGroupsArg { + c_iter groups /* d_group */; + d_admin admin; +}; + +static c_bool +collectNameSpaceGroups( + d_group group, + c_voidp arg /* struct collectNameSpaceGroupsArg * */) +{ + struct collectNameSpaceGroupsArg *a = (struct collectNameSpaceGroupsArg *)arg; + d_nameSpace inNameSpace; + + if(!d_groupIsPrivate(group) && (d_groupGetCompleteness(group) > D_GROUP_UNKNOWN)) { + inNameSpace = d_adminGetNameSpaceForGroupNoLock(a->admin, group->partition, group->topic); + if (inNameSpace) { + assert(d_adminInNameSpace(inNameSpace, group->partition, group->topic, FALSE)); + a->groups = c_iterAppend(a->groups, d_objectKeep(d_object(group))); + } + } + + return TRUE; +} + +void +d_adminMarkNameSpaceKernelGroupsCompleteness( + _Inout_ d_admin admin, + _In_ c_bool complete) +{ + d_durability durability; + u_domain domain; + struct collectNameSpaceGroupsArg arg; + d_group g; + + arg.groups = NULL; + arg.admin = admin; + + assert(d_adminIsValid(admin)); + + durability = d_adminGetDurability(admin); + domain = u_participantDomain(u_participant(durability->service)); + (void)u_domainSetAlignedState(domain, (complete == FALSE) ? OS_FALSE : OS_TRUE); + + d_adminGroupWalk(admin, &collectNameSpaceGroups, &arg); + while((g = c_iterTakeFirst(arg.groups)) != NULL){ + d_printTimedEvent(d_adminGetDurability(admin), D_LEVEL_FINEST, "Marking kernel group '%s.%s' %s\n", + g->partition, g->topic, complete ? "COMPLETE" : "INCOMPLETE"); + d_groupSetKernelGroupCompleteness(g, complete); + + d_groupFree(g); + } + c_iterFree(arg.groups); + + if (complete) { + (void)u_domainTransactionsPurge(domain); + } +} + +void +d_adminStoreGroup( + d_admin admin, + d_group group) +{ + d_store store; + d_nameSpace nameSpace; + d_durabilityKind kind, nskind; + d_storeResult result; + d_durability durability; + + assert(admin); + assert(d_adminIsValid(admin)); + assert(group); + assert(d_groupIsValid(group)); + + d_lockLock(d_lock(admin)); + durability = admin->durability; + nameSpace = d_adminGetNameSpaceForGroupNoLock(admin, group->partition, group->topic); + store = d_subscriberGetPersistentStore(admin->subscriber); + d_lockUnlock(d_lock(admin)); + + if ((nameSpace) && (store)) { + kind = d_groupGetKind(group); + nskind = d_nameSpaceGetDurabilityKind(nameSpace); + + if ((kind == D_DURABILITY_PERSISTENT) && + ((nskind == D_DURABILITY_ALL) || + (nskind == D_DURABILITY_PERSISTENT))) { + + result = d_storeGroupStore(store, group, nameSpace); + if (result == D_STORE_RESULT_OK) { + d_printTimedEvent(durability, D_LEVEL_FINE, + "Persistent group %s.%s stored on disk.\n", group->partition, group->topic); + } else { + d_printTimedEvent(durability, D_LEVEL_FINE, + "Storing persistent group %s.%s on disk failed (error code: %d).\n", + group->partition, group->topic, result); + } + } + } +} + +void +d_adminSetConflictResolver( + d_admin admin, + d_conflictResolver conflictResolver) +{ + assert(admin); + assert(d_adminIsValid(admin)); + + d_lockLock(d_lock(admin)); + assert(admin->conflictResolver == NULL); + admin->conflictResolver = conflictResolver; + d_lockUnlock(d_lock(admin)); +} + +void +d_adminInitialFellowsCreate( + d_admin admin) +{ + d_tableIter tableIter; + d_fellow fellow; + + assert(admin); + assert(d_adminIsValid(admin)); + + d_lockLock(d_lock(admin)); + if (admin->initial_fellows != NULL) { + /* Initial fellow list already created */ + d_tableFree(admin->initial_fellows); + admin->initial_fellows = NULL; + } + if (admin->fellows != NULL) { + admin->initial_fellows = d_tableNew(d_fellowCompare, d_fellowFree); + + for (fellow = d_fellow(d_tableIterFirst(admin->fellows, &tableIter)); + fellow != NULL; + fellow = d_fellow(d_tableIterNext(&tableIter))) { + d_tableInsert(admin->initial_fellows, d_objectKeep(d_object(fellow))); + } + } + d_lockUnlock(d_lock(admin)); +} + +void +d_adminInitialFellowsDestroy( + d_admin admin) +{ + assert(d_adminIsValid(admin)); + + d_lockLock(d_lock(admin)); + if (admin->initial_fellows != NULL) { + d_tableFree(admin->initial_fellows); + admin->initial_fellows = NULL; + } + d_lockUnlock(d_lock(admin)); +} + +char * +d_adminGetInitialFellowsString( + d_admin admin) +{ + char *str = NULL; + c_ulong size; + d_tableIter tableIter; + d_fellow fellow; + size_t pos = 0; + + assert(d_adminIsValid(admin)); + + d_lockLock(d_lock(admin)); + /* size = (number of initial fellow * (max character in decimal systemId + comma)) + terminator */ + size = (d_tableSize(admin->initial_fellows) * 11) + 1; + str = os_malloc(size); + str[0] = '\0'; + for (fellow = d_fellow(d_tableIterFirst(admin->initial_fellows, &tableIter)); + fellow != NULL; + fellow = d_fellow(d_tableIterNext(&tableIter))) { + int n = snprintf(str + pos, size - pos, "%s%u", str[0] == '\0' ? "" : ",", fellow->address->systemId); + if (n > 0) { + pos += (size_t)n; + } + } + d_lockUnlock(d_lock(admin)); + + return str; +} diff --git a/src/services/durability/code/d_capability.c b/src/services/durability/code/d_capability.c new file mode 100644 index 000000000..a7060e737 --- /dev/null +++ b/src/services/durability/code/d_capability.c @@ -0,0 +1,169 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#include "d__capability.h" +#include "d__admin.h" +#include "d__durability.h" +#include "d__misc.h" +#include "d__configuration.h" +#include "d_message.h" +#include "vortex_os.h" + + + +d_capability +d_capabilityNew( + d_admin admin, + c_ulong incarnation) +{ + d_capability capability; + d_durability durability; + d_configuration config; + struct d_nameValue_s *nameValue; + + assert(d_adminIsValid(admin)); + + durability = d_adminGetDurability(admin); + config = d_durabilityGetConfiguration(durability); + + /* Allocate sampleRequest */ + capability = d_capability(os_malloc(C_SIZEOF(d_capability))); + /* Initialize to NULL */ + memset(capability, 0, sizeof(C_STRUCT(d_capability))); + /* Call super-init */ + d_messageInit(d_message(capability), admin); + /* Add all my capabilities */ + nameValue = os_malloc(D_NUMBER_OF_CAPABILITIES * sizeof(struct d_nameValue_s)); + + /* Add group hash capability */ + nameValue[0].name = os_strdup(D_CAPABILITY_GROUP_HASH); + nameValue[0].value = os_malloc(sizeof(c_octet)); + ((c_octet*)nameValue[0].value)[0] = (config->capabilityGroupHash) ? 1 : 0; + + /* Add EOT support capability */ + nameValue[1].name = os_strdup(D_CAPABILITY_EOT_SUPPORT); + nameValue[1].value = os_malloc(sizeof(c_octet)); + ((c_octet*)nameValue[1].value)[0] = (config->capabilityEOTSupport) ? 1 : 0; + + /* Add Y2038 capability */ + nameValue[2].name = os_strdup(D_CAPABILITY_Y2038READY); + nameValue[2].value = os_malloc(sizeof(c_octet)); + ((c_octet*)nameValue[2].value)[0] = (config->capabilityY2038Ready) ? 1 : 0; + + /* Add Master selection version capability */ + nameValue[3].name = os_strdup(D_CAPABILITY_MASTER_SELECTION); + nameValue[3].value = os_malloc(sizeof(c_ulong)); + { + /* The value to provide is determined by the config */ + c_ulong value = config->capabilityMasterSelection; + memcpy(nameValue[3].value, &value, sizeof(c_ulong)); + } + + /* Add incarnation number */ + nameValue[4].name = os_strdup(D_CAPABILITY_INCARNATION); + nameValue[4].value = os_malloc(sizeof(c_ulong)); + { + /* Set the incarnation value */ + c_ulong value = incarnation; + memcpy(nameValue[4].value, &value, sizeof(c_ulong)); + } + + capability->capabilities = (c_sequence)nameValue; + + return capability; +} + + +void +d_capabilityFree( + d_capability capability) +{ + struct d_nameValue_s *nameValue; + c_ulong i; + + if (capability) { + /* Clean up all existing capabilities */ + if (capability->capabilities) { + + nameValue = (struct d_nameValue_s *)capability->capabilities; + + for (i=0; icapabilities); + capability->capabilities = NULL; + } + + d_messageDeinit(d_message(capability)); + os_free(capability); + } +} + +char * +d_capabilityToString( + d_capability capability) +{ +#define D_CAPABILITY_STRING_BLKSIZE (256) + char *str = NULL; + c_ulong blksize = D_CAPABILITY_STRING_BLKSIZE; + c_ulong i,j; + c_ulong offset = 0; + c_ulong nameLen; + c_ulong valueCount; + c_ulong capabilitiesCount; + const struct d_nameValue_s *capabilities; + const c_octet *value; + + if (capability) { + str = os_malloc(blksize); + str[offset++] = '['; + + capabilitiesCount = c_sequenceSize(capability->capabilities); + capabilities = (const struct d_nameValue_s *)capability->capabilities; + + for (i=0; i blksize) { + blksize += D_CAPABILITY_STRING_BLKSIZE; + str = os_realloc(str, blksize); + } + + offset += (c_ulong)snprintf(&str[offset], blksize, "%s%s(", (i!=0)?",":"", capabilities[i].name); + + for (j=0;jsenderAddress.systemId, + message->senderAddress.localId, + message->senderAddress.lifecycleId); + /* Get the capability and determine if it was a request + * or response + */ + + capability = d_capability(message); + + /* The fellow has sent its capabilities to me. + * I can only send my capabilities if I have detected + * the capabilityListener of the fellow. In case + * the fellow's capabilityListener is not yet detected + * I must postpone sending my capabilities until the + * capabilityListener of the fellow is detected. + */ + capabilityStr = d_capabilityToString(capability); + d_printTimedEvent(durability, D_LEVEL_FINE, + "Received capabilities from fellow %u %s\n",fellowAddr->systemId, capabilityStr); + os_free(capabilityStr); + + /* Get or create the fellow, set its capability and check its responsiveness */ + fellow = d_durabilityGetOrCreateFellowFromMessage(admin, fellowAddr, message); + if (fellow) { + /* I received a capability from the fellow, so the fellow must have capability support */ + assert(d_fellowHasCapabilitySupport(fellow)); + d_fellowSetCapability(fellow, capability); + d_fellowCheckInitialResponsiveness(fellow); + d_fellowFree(fellow); + } else { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "No fellow retrieved or created when capabilities from fellow %u were received\n", + fellowAddr->systemId); + } + d_networkAddressFree(fellowAddr); + return; +} + +static void +d_capabilityListenerDeinit( + d_capabilityListener listener) +{ + assert(d_capabilityListenerIsValid(listener)); + + /* Stop the listener */ + d_capabilityListenerStop(listener); + /* Nothing to deallocate, call super-deinit */ + d_readerListenerDeinit(d_readerListener(listener)); +} + +static c_bool +d_capabilityListenerInit( + d_capabilityListener listener, + d_subscriber subscriber) +{ + os_threadAttr attr; + + /* Do not assert the listener because the initialization + * of the listener has not yet completed + */ + + assert(d_subscriberIsValid(subscriber)); + assert(listener); + + /* Call super-init */ + (void)os_threadAttrInit(&attr); + d_readerListenerInit(d_readerListener(listener), + D_CAPABILITY_LISTENER, + d_capabilityListenerAction, + subscriber, + D_CAPABILITY_TOPIC_NAME, + D_CAPABILITY_TOP_NAME, + V_RELIABILITY_RELIABLE, + V_HISTORY_KEEPLAST, + 1, + attr, + (d_objectDeinitFunc)d_capabilityListenerDeinit); + return TRUE; +} + +d_capabilityListener +d_capabilityListenerNew( + d_subscriber subscriber) +{ + d_capabilityListener listener; + c_bool success; + + assert(d_subscriberIsValid(subscriber)); + + /* Allocate capabilityListener */ + listener = d_capabilityListener(os_malloc(C_SIZEOF(d_capabilityListener))); + if (listener) { + /* Initialize the capabilityListener */ + success = d_capabilityListenerInit(listener, subscriber); + if (!success) { + os_free(listener); + listener = NULL; + } + } + return listener; +} + +void +d_capabilityListenerFree( + d_capabilityListener listener) +{ + assert(d_capabilityListenerIsValid(listener)); + + d_objectFree(d_object(listener)); +} + + +c_bool +d_capabilityListenerStart( + d_capabilityListener listener) +{ + return d_readerListenerStart(d_readerListener(listener)); +} + + +c_bool +d_capabilityListenerStop( + d_capabilityListener listener) +{ + return d_readerListenerStop(d_readerListener(listener)); +} + diff --git a/src/services/durability/code/d_client.c b/src/services/durability/code/d_client.c new file mode 100644 index 000000000..3752adb8b --- /dev/null +++ b/src/services/durability/code/d_client.c @@ -0,0 +1,244 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "d__client.h" +#include "d__thread.h" +#include "d__durability.h" +#include "d__misc.h" +#include "d__admin.h" +#include "d_networkAddress.h" +#include "os_heap.h" + +d_client +d_clientNew( + d_networkAddress address) +{ + d_client client; + + /* Allocate client object */ + client = d_client(os_malloc(C_SIZEOF(d_client))); + if (client) { + /* Call super-init */ + d_lockInit(d_lock(client), D_CLIENT, + (d_objectDeinitFunc)d_clientDeinit); + /* Initialize the client */ + client->address = d_networkAddressNew(address->systemId, + address->localId, + address->lifecycleId); + client->clientId.prefix = 0; + client->clientId.suffix = 0; + client->readers = 0; /* No readers detected yet for this client */ + client->requiredReaders = D_BASIC_CLIENT_DURABILITY_READER_FLAGS; + client->isConfirmed = FALSE; /* set to TRUE when clientId is set */ + } + return client; +} + + +void +d_clientDeinit( + d_client client) +{ + assert(d_clientIsValid(client)); + + if (client->address) { + d_networkAddressFree(client->address); + client->address = NULL; + } + /* Call super-deinit */ + d_lockDeinit(d_lock(client)); + +} + + +void +d_clientFree( + d_client client) +{ + assert(d_clientIsValid(client)); + + d_objectFree(d_object(client)); +} + + +int +d_clientCompareByAddress( + d_client client1, + d_client client2) +{ + int result = 0; + + if (client1 != client2) { + result = d_networkAddressCompare(client1->address, client2->address); + } + return result; +} + + +d_networkAddress +d_clientGetAddress( + d_client client) +{ + assert(d_clientIsValid(client)); + + return d_networkAddressNew(client->address->systemId, client->address->localId, client->address->lifecycleId); +} + + +void +d_clientAddReader( + d_client client, + c_ulong reader) +{ + assert(d_clientIsValid(client)); + + d_lockLock(d_lock(client)); + if ((client->readers & reader) == 0) { + d_durability durability = d_threadsDurability(); + d_networkAddress clientAddr; + + clientAddr = d_clientGetAddress(client); + client->readers |= reader; + d_printTimedEvent(durability, D_LEVEL_FINER, + "Client durability reader %04lx for federation %u discovered (readers: %04lx, required readers: %04lx).\n", + reader, clientAddr->systemId, client->readers, client->requiredReaders); + d_networkAddressFree(clientAddr); + } + d_lockUnlock(d_lock(client)); +} + + + +void +d_clientRemoveReader( + d_client client, + c_ulong reader) +{ + assert(d_clientIsValid(client)); + + /* Note: there is an issue when there are more than 1 clients per participant. + * The first client that leaves will remove the readers and hence prevent communication + */ + + d_lockLock(d_lock(client)); + if ((client->readers & reader) == reader) { + d_durability durability = d_threadsDurability(); + d_admin admin = durability->admin; + d_networkAddress clientAddr; + d_client result; + + clientAddr = d_clientGetAddress(client); + client->readers &= (~reader); + d_printTimedEvent(durability, D_LEVEL_FINER, + "Client durability reader %lx for federation %u lost (readers: %lx, requiredReaders: %lx).\n", + reader, clientAddr->systemId, client->readers, client->requiredReaders); + if (client->readers == 0) { + /* No client durability reader exists for this client anymore. + * Remove the client. When the client reappears discovery + * of readers will be started again + */ + d_printTimedEvent(durability, D_LEVEL_FINER, + "All client durability readers for federation %u have been lost\n", + clientAddr->systemId); + if ((result = d_adminRemoveClient(admin, client)) != NULL) { + d_clientFree(result); + } + } + d_networkAddressFree(clientAddr); + } + d_lockUnlock(d_lock(client)); +} + + /* Client that sets the requestId will be confirmed by definition */ +void +d_clientSetClientId( + d_client client, + struct _DDS_Gid_t clientId) +{ + assert(d_clientIsValid(client)); + + if (!client->isConfirmed) { + d_durability durability = d_threadsDurability(); + + d_lockLock(d_lock(client)); + client->clientId = clientId; + client->isConfirmed = TRUE; + + d_printTimedEvent(durability, D_LEVEL_FINER, + "Confirming client for federation %u\n", client->address->systemId); + + d_lockUnlock(d_lock(client)); + } +} + + +c_bool +d_clientIsConfirmed( + d_client client) +{ + c_bool result; + + assert(d_clientIsValid(client)); + + d_lockLock(d_lock(client)); + result = client->isConfirmed; + d_lockUnlock(d_lock(client)); + return result; +} + + +/** + * \brief Check if all readers in the mask have been discovered for the client + * + * If waitForRemoteReaders is FALSE then there is no need to discover readers, + * so TRUE is returned. + */ +static c_bool +d_clientHasDiscoveredReaders( + d_client client, + c_ulong mask, + c_bool waitForRemoteReaders) +{ + c_bool result = TRUE; + + assert(d_clientIsValid(client)); + + d_lockLock(d_lock(client)); + if (waitForRemoteReaders) { + /* Check if the discovered readers of the fellow + * match the ones specified in the mask. + */ + result = (((client->readers) & (mask)) == (mask)); + } + d_lockUnlock(d_lock(client)); + return result; + +} + + +c_bool +d_clientIsResponsive( + d_client client, + c_ulong requiredReaders, + c_bool waitForRemoteReaders) +{ + assert(d_clientIsValid(client)); + + return (d_clientHasDiscoveredReaders(client, requiredReaders, waitForRemoteReaders) && d_clientIsConfirmed(client)); +} + diff --git a/src/services/durability/code/d_configuration.c b/src/services/durability/code/d_configuration.c new file mode 100644 index 000000000..2c3d36403 --- /dev/null +++ b/src/services/durability/code/d_configuration.c @@ -0,0 +1,3771 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +/* TODO: Check consistency between namespaces. Overlap between them is not a + * valid situation. + */ +#include "d__configuration.h" +#include "d__durability.h" +#include "d__nameSpace.h" +#include "d__policy.h" +#include "d__filter.h" +#include "d__table.h" +#include "d__misc.h" +#include "d__element.h" +#include "d_object.h" +#include "ut_xmlparser.h" +#include "os_heap.h" +#include "os_report.h" +#include "os_version.h" +#include "os_gitrev.h" +#include "os_stdlib.h" +#include "v_builtin.h" +#include "u_domain.h" +#include "q_expr.h" + + +typedef struct mustAlignHelper { + u_cfElement cfg; + char *serviceName; + c_bool mustAlign; + c_bool hasNetwork; +} mustAlignHelper; + + +static c_bool +isServiceEnabled( + u_cfElement serviceElement) +{ + c_bool enabled, success; + + assert(serviceElement); + + success = u_cfElementAttributeBoolValue(serviceElement, "enabled", &enabled); + + if (!success || enabled) { + return TRUE; + } + return FALSE; +} + +static void +isNetworkService ( + void* o, + c_iterActionArg userData) +{ + u_cfElement element = (u_cfElement)o; + mustAlignHelper *helper = (mustAlignHelper *)userData; + c_char *networkServiceName; + c_bool success; + + assert(helper->serviceName); + + if ((!helper->mustAlign) && element) { + if(isServiceEnabled(element)){ + /* Get the "name"-attribute of the network service */ + success = u_cfElementAttributeStringValue(element, "name", &networkServiceName); + if (success) { + if (strcmp(helper->serviceName, networkServiceName) == 0) { + /* The enabled service is a . + * In this case durability must generate + * the builtin topics. + */ + helper->mustAlign = TRUE; + helper->hasNetwork = TRUE; + } + os_free(networkServiceName); + } + } + } +} + +static void +cfElementIterFree ( + c_iter iter) +{ + u_cfElement elem; + while ((elem = c_iterTakeFirst(iter)) != NULL) { + u_cfElementFree(elem); + } + c_iterFree(iter); +} + +static void +isDDSIServiceWithGenerateBuiltinTopics ( + void* o, + c_iterActionArg userData) +{ + u_cfElement element = (u_cfElement)o; + mustAlignHelper *helper = (mustAlignHelper *)userData; + c_char *ddsiServiceName; + c_iter iter; + u_cfData data; + c_bool success, b; + + assert(helper->serviceName); + + if ((!helper->mustAlign) && element) { + if(isServiceEnabled(element)){ + /* Get the "name"-attribute of the ddsi service */ + success = u_cfElementAttributeStringValue(element, "name", &ddsiServiceName); + if (success) { + if (strcmp(helper->serviceName, ddsiServiceName) == 0) { + iter = u_cfElementXPath(element, "Discovery/GenerateBuiltinTopics/#text"); + if (iter) { + if (c_iterLength(iter) == 1) { + data = u_cfData(c_iterTakeFirst(iter)); + if (data) { + success = u_cfDataBoolValue(data, &b); + if (success == TRUE) { + /* If is set to + * "false" for this DDSI service then + * durability must align the built-in + * topics. + */ + helper->mustAlign = !b; + } + u_cfDataFree(data); + } + } else if (c_iterLength(iter) > 1) { + /* Multiple elements are + * present for this DDSI service. This should not + * occur and should have resulted in an error + * when parsing the configuration. To be on the + * safe side we treat this case as if durability + * must align the built-in topics. + */ + OS_REPORT(OS_ERROR, D_CONTEXT, 0, + "%d configurations found for serviceName '%s', ignoring these settings.", + c_iterLength(iter), helper->serviceName); + helper->mustAlign = TRUE; + } else { + /* No -element was + * present. Assume the default; DDSI + * generates built-in topics. This means + * durability must not align built-in + * topics. + */ + helper->mustAlign = FALSE; + } + cfElementIterFree(iter); + } + helper->hasNetwork = TRUE; + } + } + os_free(ddsiServiceName); + } + } +} + + +static void +durabilityMustAlign( + void* o, + c_iterActionArg userData) +{ + u_cfElement element = (u_cfElement)o; + mustAlignHelper *helper = (mustAlignHelper *)userData; + char *serviceName; + c_iter iter; + c_bool success; + c_bool enabled = TRUE; + + assert(helper->cfg); + + if ((!helper->mustAlign) && element) { + /* Get the "name"-attribute of the service */ + success = u_cfElementAttributeStringValue(element, "name", &serviceName); + if (success) { + helper->serviceName = serviceName; + /* Get the (optional) "enabled"-attribute of the service. + * If not present then "enabled=true" is assumed. + * Only if enabled="false" the service must not be checked. + */ + success = u_cfElementAttributeBoolValue(element, "enabled", &enabled); + if (!success || enabled) { + iter = u_cfElementXPath(helper->cfg, "NetworkService"); + if (iter) { + c_iterWalk(iter, isNetworkService, helper); + cfElementIterFree(iter); + } + if (!helper->mustAlign) { + iter = u_cfElementXPath(helper->cfg, "SNetworkService"); + if (iter) { + c_iterWalk(iter, isNetworkService, helper); + cfElementIterFree(iter); + } + } + if (!helper->mustAlign) { + iter = u_cfElementXPath(helper->cfg, "DDSI2Service"); + if (iter) { + c_iterWalk(iter, isDDSIServiceWithGenerateBuiltinTopics, helper); + cfElementIterFree(iter); + } + } + if (!helper->mustAlign) { + iter = u_cfElementXPath(helper->cfg, "DDSI2EService"); + if (iter) { + c_iterWalk(iter, isDDSIServiceWithGenerateBuiltinTopics, helper); + cfElementIterFree(iter); + } + } + } + os_free(serviceName); + } + } +} + + +/** \brief Determine if the durability service must align the builtin topics. + */ +static c_bool +d_configurationDurabilityMustAlignBuiltin( + u_cfElement cfg) +{ + c_iter iter; + mustAlignHelper helper; + + helper.cfg = cfg; + helper.serviceName = NULL; + helper.mustAlign = FALSE; + helper.hasNetwork = FALSE; + + if (cfg) { + iter = u_cfElementXPath(cfg, "Domain/Service"); + if (iter) { + c_iterWalk(iter, durabilityMustAlign, &helper); + cfElementIterFree(iter); + + if((helper.mustAlign == FALSE) && (helper.hasNetwork == FALSE)){ + helper.mustAlign = TRUE; + } + } + } + return helper.mustAlign; +} + + +d_configuration +d_configurationNew( + d_durability service, + const c_char* serviceName, + c_long domainId) +{ + d_configuration config; + u_cfElement cfg; + c_iter iter; + u_cfElement element, found, domainElement; + c_char* attrValue; + c_bool success; + + OS_UNUSED_ARG(domainId); + /* Allocate configuration object */ + config = d_configuration(os_malloc(C_SIZEOF(d_configuration))); + memset(config, 0, C_SIZEOF(d_configuration)); + + /* Call super-init */ + d_objectInit(d_object(config), D_CONFIGURATION, + (d_objectDeinitFunc)d_configurationDeinit); + /* Initialize the configuration */ + cfg = u_participantGetConfiguration(u_participant(d_durabilityGetService(service))); + if (cfg != NULL) { + iter = u_cfElementXPath(cfg, "Domain"); + if (c_iterLength(iter) > 1) { + OS_REPORT(OS_WARNING, D_CONTEXT, 0, + "%d Domain configurations found.", + c_iterLength(iter)); + } else if (c_iterLength(iter) == 0) { + OS_REPORT(OS_WARNING, D_CONTEXT, 0, + "No Domain configuration found. Applying defaults..."); + } + + domainElement = NULL; + element = u_cfElement(c_iterTakeFirst(iter)); + while (element) { + if (domainElement) { + u_cfElementFree(domainElement); + } + domainElement = element; + element = u_cfElement(c_iterTakeFirst(iter)); + } + c_iterFree(iter); + + iter = u_cfElementXPath(cfg, "DurabilityService"); + if (c_iterLength(iter) > 1) { + OS_REPORT(OS_WARNING, D_CONTEXT, 0, + "%d DurabilityService configurations found for serviceName '%s'.", + c_iterLength(iter), serviceName); + } else if(c_iterLength(iter) == 0) { + OS_REPORT(OS_WARNING, D_CONTEXT, 0, + "No DurabilityService configurations found for serviceName '%s'.", + serviceName); + } + + found = NULL; + element = u_cfElement(c_iterTakeFirst(iter)); + while (element) { + success = u_cfElementAttributeStringValue(element, "name", &attrValue); + if (success == TRUE) { + if (strcmp(serviceName, attrValue) == 0) { + if (found) { + u_cfElementFree(found); + } + found = element; + element = NULL; + } + os_free(attrValue); + } + if (element) { + u_cfElementFree(element); + } + element = u_cfElement(c_iterTakeFirst(iter)); + } + + if (found) { + if (d_configurationInit(config, cfg, service, domainElement, found) != 0) { + d_configurationFree(config); + config = NULL; + } + u_cfElementFree(found); + } else { + OS_REPORT(OS_FATAL, D_CONTEXT, 0, + "No DurabilityService configurations found for serviceName '%s'", + serviceName); + d_configurationFree(config); + config = NULL; + } + if (domainElement) { + u_cfElementFree(domainElement); + } + c_iterFree(iter); + u_cfElementFree(cfg); + } + + if (config) { + d_configurationReport(config, service); + } + return config; +} + +void +d_configurationDeinit( + d_configuration config) +{ + d_nameSpace ns; + d_policy policy; + d_filter filter; + c_char* name; + struct durablePolicy *dp; + + assert(d_configurationIsValid(config)); + + if (config->persistentStoreDirectory) { + os_free(config->persistentStoreDirectory); + config->persistentStoreDirectory = NULL; + } + if (config->persistentKVStoreStorageType) { + os_free(config->persistentKVStoreStorageType); + config->persistentKVStoreStorageType = NULL; + } + if (config->persistentKVStoreStorageParameters) { + os_free(config->persistentKVStoreStorageParameters); + config->persistentKVStoreStorageParameters = NULL; + } + if (config->filters) { + filter = d_filter(c_iterTakeFirst(config->filters)); + while (filter) { + d_filterFree(filter); + filter = d_filter(c_iterTakeFirst(config->filters)); + } + c_iterFree(config->filters); + config->filters = NULL; + } + if (config->policies) { + policy = d_policy(c_iterTakeFirst(config->policies)); + while (policy) { + d_policyFree(policy); + policy = d_policy(c_iterTakeFirst(config->policies)); + } + c_iterFree(config->policies); + config->policies = NULL; + } + if (config->nameSpaces) { + ns = d_nameSpace(c_iterTakeFirst(config->nameSpaces)); + while (ns) { + d_nameSpaceFree(ns); + ns = d_nameSpace(c_iterTakeFirst(config->nameSpaces)); + } + c_iterFree(config->nameSpaces); + config->nameSpaces = NULL; + } + if (config->networkServiceNames) { + d_tableFree(config->networkServiceNames); + config->networkServiceNames = NULL; + } + if (config->services) { + name = (c_char*)(c_iterTakeFirst(config->services)); + while(name){ + os_free(name); + name = (c_char*)(c_iterTakeFirst(config->services)); + } + c_iterFree(config->services); + config->services = NULL; + } + if (config->durablePolicies) { + dp = (struct durablePolicy *)(c_iterTakeFirst(config->durablePolicies)); + while(dp){ + os_free(dp->obtain); + os_free(dp); + dp = (struct durablePolicy *)(c_iterTakeFirst(config->durablePolicies)); + } + c_iterFree(config->durablePolicies); + config->durablePolicies = NULL; + } + if (config->publisherName) { + os_free(config->publisherName); + config->publisherName = NULL; + } + if (config->subscriberName) { + os_free(config->subscriberName); + config->subscriberName = NULL; + } + if (config->partitionName) { + os_free(config->partitionName); + config->partitionName = NULL; + } + if (config->clientDurabilityPartitionName) { + os_free(config->clientDurabilityPartitionName); + config->clientDurabilityPartitionName = NULL; + } + if (config->clientDurabilityPublisherName) { + os_free(config->clientDurabilityPublisherName); + config->clientDurabilityPublisherName = NULL; + } + if (config->clientDurabilitySubscriberName) { + os_free(config->clientDurabilitySubscriberName); + config->clientDurabilitySubscriberName = NULL; + } + if (config->tracingOutputFileName) { + if( (strcmp(config->tracingOutputFileName, "stdout") != 0) && + (strcmp(config->tracingOutputFileName, "stderr") != 0)) { + if (config->tracingOutputFile){ + fclose(config->tracingOutputFile); + config->tracingOutputFile = NULL; + } + } + os_free(config->tracingOutputFileName); + config->tracingOutputFileName = NULL; + } + if (config->role) { + os_free (config->role); + } + /* Call super-deinit */ + d_objectDeinit(d_object(config)); +} + +void +d_configurationFree( + d_configuration config) +{ + assert(d_configurationIsValid(config)); + + d_objectFree(d_object(config)); +} + +void +d_configurationSetBuiltinTopicsEnabled( + d_configuration config, + c_bool enabled); + + +static void +d_configurationParseEnvVars( + d_configuration config) +{ + char *p; + + /* Capabilities are enabled by default, unless they have + * been disabled using an environment variable. The only + * way to disable capabilities is to set the environment + * variable OSPL_DURABILITY_CAPABILITY_SUPPORT to 0 + */ + if ((p = os_getenv ("OSPL_DURABILITY_CAPABILITY_SUPPORT")) != NULL && atoi (p) == 0) { + config->capabilitySupport = FALSE; + } + + /* Ability to hash data sets is enabled by default, unless + * it is disabled using an environment variable. The only + * way to disable the hash ability is to set the environment + * variable OSPL_DURABILITY_CAPABILITY_HASH_DATA_SETS to 0 + */ + if ((p = os_getenv ("OSPL_DURABILITY_CAPABILITY_GROUP_HASH")) != NULL && atoi (p) == 0) { + config->capabilityGroupHash = FALSE; + } + + /* Ability to align End Of Transactions (EOT) */ + if ((p = os_getenv ("OSPL_DURABILITY_CAPABILITY_EOT_SUPPORT")) != NULL && atoi (p) == 0) { + config->capabilityEOTSupport = FALSE; + } + + /* Ability to specify master selection algorithm */ + if ((p = os_getenv ("OSPL_DURABILITY_CAPABILITY_MASTER_SELECTION")) != NULL) { + config->capabilityMasterSelection = (c_ulong)atoi(p); + } + + /* Ability to control majority voting threshold */ + if ((p = os_getenv ("OSPL_DURABILITY_MAJORITY_VOTING_THRESHOLD")) != NULL) { + d_configurationSetMajorityVotingThreshold(config,(c_ulong)atoi(p)); + } + + /* Ability to test for rollover of merge states */ + if ((p = os_getenv ("OSPL_DURABILITY_INITIAL_MERGE_STATE_VALUE")) != NULL) { + config->initialMergeStateValue = (c_ulong)atoi(p); + } + + /* Set thread liveliness report period */ + if ((p = os_getenv ("OSPL_DURABILITY_THREAD_LIVELINESS_REPORT_PERIOD")) != NULL) { + d_configurationSetDuration(&(config->threadLivelinessReportPeriod), (c_float)atof(p)); + } + + /* Trace mask settings */ + if ((p = os_getenv ("OSPL_DURABILITY_TRACE_ALL")) != NULL && atoi (p) != 0) { + config->traceMask |= D_TRACE_ALL; + } else if ((p = os_getenv ("OSPL_DURABILITY_TRACE_NONE")) != NULL && atoi (p) != 0) { + config->traceMask |= D_TRACE_NONE; + } else { + /* Trace mask setting for priority queue */ + if ((p = os_getenv ("OSPL_DURABILITY_TRACE_PRIO_QUEUE")) != NULL && atoi (p) != 0) { + config->traceMask |= D_TRACE_PRIO_QUEUE; + } + /* Trace mask setting for group instances and messages */ + if ((p = os_getenv ("OSPL_DURABILITY_TRACE_GROUP")) != NULL && atoi (p) != 0) { + config->traceMask |= D_TRACE_GROUP; + } + /* Trace mask setting for client durability */ + if ((p = os_getenv ("OSPL_DURABILITY_TRACE_CLIENT_DURABILITY")) != NULL && atoi (p) != 0) { + config->traceMask |= D_TRACE_CLIENT_DURABILITY; + } + /* Trace mask setting for client durability */ + if ((p = os_getenv ("OSPL_DURABILITY_TRACE_GROUP_HASH")) != NULL && atoi (p) != 0) { + config->traceMask |= D_TRACE_GROUP_HASH; + } + /* Trace mask setting for master selection */ + if ((p = os_getenv ("OSPL_DURABILITY_TRACE_MASTER_SELECTION")) != NULL && atoi (p) != 0) { + config->traceMask |= D_TRACE_MASTER_SELECTION; + } + /* Trace mask setting for master selection */ + if ((p = os_getenv ("OSPL_DURABILITY_TRACE_COMBINE_REQUESTS")) != NULL && atoi (p) != 0) { + config->traceMask |= D_TRACE_COMBINE_REQUESTS; + } + if ((p = os_getenv ("OSPL_DURABILITY_TRACE_CHAINS")) != NULL && atoi (p) != 0) { + config->traceMask |= D_TRACE_CHAINS; + } + + } + /* Start the durability service with the specified sequence numbers. */ + if ((p = os_getenv ("OSPL_DURABILITY_SEQNUM_INITIAL_VALUE")) != NULL) { + config->seqnum_initval = (os_uint32)strtoul(p, NULL, 10); + } + return; +} + +c_bool +d_configurationCheckFilterInNameSpace(d_configuration config, d_nameSpace nameSpace) { + c_iterIter iter1, iter2; + c_bool found = FALSE; + d_filter filter = NULL; + d_element element; + + iter1 = c_iterIterGet(config->filters); + while((!found) && ((filter = d_filter(c_iterNext(&iter1))) != NULL)) { + iter2 = c_iterIterGet(filter->elements); + while ((!found) && ((element = d_element(c_iterNext(&iter2))) != NULL)) { + found = (d_nameSpaceIsAligner(nameSpace) && (d_nameSpaceGetMasterPriority(nameSpace) > D_MINIMUM_MASTER_PRIORITY) && (d_configurationInNameSpace(nameSpace, element->partition, element->topic, TRUE))) ; + if (found) { + OS_REPORT(OS_ERROR, D_CONTEXT, 0, + "Unable to be a master of namespace %s as the filter \"%s\" for partition \"%s\" topic \"%s\" is defined which will cause to filter out some data." + "This is not allowed for a master", nameSpace->name, filter->sqlExpression, element->partition, element->topic); + } + } + } + return found; +} + +static int +d_configurationSanityCheck( + d_configuration config) +{ + c_iterIter iter, iter2; + d_tableIter tableIter; + int result = 0; + struct durablePolicy *dp; + d_nameSpace nameSpace; + d_element element; + + assert(d_configurationIsValid(config)); + + /* Perform all kinds of sanity checks. + * Failure to meet these sanity checks will result in durability not starting up. + */ + + /* Check that there is no overlap between the NameSpaces and DurabilityPolicies */ + if (config->durablePolicies) { + iter = c_iterIterGet(config->durablePolicies); + while ((!result) && ((dp = (struct durablePolicy *)c_iterNext(&iter)) != NULL)) { + iter2 = c_iterIterGet(config->nameSpaces); + while ((!result) && ((nameSpace = d_nameSpace(c_iterNext(&iter2))) != NULL)) { + element = d_element(d_tableIterFirst(nameSpace->elements, &tableIter)); + while ((!result) && (element != NULL)) { + char *str; + os_size_t len = strlen(element->partition) + strlen(element->topic) + 2; + + str = os_malloc(len); + snprintf(str, len, "%s.%s", element->partition, element->topic); + result = (d_patternMatch(str, dp->obtain) || d_patternMatch(dp->obtain, str)); + if (result) { + OS_REPORT(OS_ERROR, D_CONTEXT, 0, + "Ambiguous namespace and durable policy definitions, the durability service is not started. " + "The expressions '%s' in //OpenSplice/DurabilityService/NameSpaces/ and " + "'%s' in //OpenSplice/Domain/DurablePolicies/ are not disjunct.", str, dp->obtain); + result = -1; + } + os_free(str); + + element = d_element(d_tableIterNext(&tableIter)); + } + } + } + } + + /* Verify that the merge policy for builtin is IGNORE or MERGE when the durability + * service is responsible for the alignment of builtin topics. + */ + if ((config->mustAlignBuiltinTopics) && (result == 0) && (config->nameSpaces)) { + c_bool found = FALSE; + iter = c_iterIterGet(config->nameSpaces); + while ((!found) && ((nameSpace = d_nameSpace(c_iterNext(&iter))) != NULL)) { + /* Look for the nameSpace containing the DCPSTopic */ + found = d_configurationInNameSpace(nameSpace, V_BUILTIN_PARTITION, V_TOPICINFO_NAME, TRUE); + if (found) { + d_mergePolicy mergePolicy = d_nameSpaceGetMergePolicy(nameSpace, config->role); + if ((mergePolicy != D_MERGE_IGNORE) && (mergePolicy != D_MERGE_MERGE)) { + OS_REPORT(OS_ERROR, D_CONTEXT, 0, + "The merge policy for namespace '%s' that is responsible for the builtin topics must be IGNORE or MERGE. " + "Check //OpenSplice/DurabilityService/NameSpaces/Policy in the deployment manual.", nameSpace->name); + result = -1; + } + } + } + } + /* Verify that there are no filters for namespaces we're master for */ + if ((config->filters) && (result == 0 ) && (config->nameSpaces)) { + c_bool found = FALSE; + + iter = c_iterIterGet(config->nameSpaces); + while ((!found) && ((nameSpace = d_nameSpace(c_iterNext(&iter))) != NULL)) { + found = d_configurationCheckFilterInNameSpace(config, nameSpace); + if (found) { + OS_REPORT(OS_ERROR, D_CONTEXT, 0, "Termination durability"); + result = -1; + } + } + } + + return result; +} + + +static c_bool +d_configurationHasTag( + d_configuration config, + u_cfElement element, + const c_char* tag) +{ + c_iter iter; + c_bool result = FALSE; + u_cfElement e; + + OS_UNUSED_ARG(config); + + iter = u_cfElementXPath(element, tag); + if (iter) { + result = (c_iterLength(iter) > 0); + /* Clean up the elements */ + e = u_cfElement(c_iterTakeFirst(iter)); + while(e) { + u_cfElementFree(e); + e = u_cfElement(c_iterTakeFirst(iter)); + } + c_iterFree(iter); + } + return result; +} + + +int +d_configurationInit( + d_configuration config, + u_cfElement cfg, + d_durability durability, + u_cfElement domainElement, + u_cfElement element) +{ + d_policy policy; + c_ulong i; + int result = 0; + d_nameSpace ns = NULL; + c_iterIter iter; + + assert(config); + + /* First apply all defaults. */ + d_printTimedEvent(durability, D_LEVEL_FINER, "Initializing configuration...\n"); + + config->persistentStoreDirectory = NULL; + config->persistentStoreMode = D_STORE_TYPE_XML; + config->persistentKVStoreStorageType = NULL; + config->persistentKVStoreStorageParameters = NULL; + config->persistentKVStoreCompressionEnabled = FALSE; + config->persistentKVStoreCompressionAlgorithm = D_COMPRESSION_NONE; + config->partitionName = NULL; + config->publisherName = NULL; + config->subscriberName = NULL; + config->clientDurabilityPartitionName = NULL; + config->clientDurabilityPublisherName = NULL; + config->clientDurabilitySubscriberName = NULL; + config->tracingOutputFile = NULL; + config->tracingOutputFileName = NULL; + config->tracingSynchronous = FALSE; + config->networkServiceNames = d_tableNew(strcmp, os_free); + config->services = c_iterNew(NULL); + config->tracingVerbosityLevel = D_LEVEL_INFO; + config->nameSpaces = NULL; + config->policies = NULL; + config->durablePolicies = NULL; + config->filters = NULL; + config->tracingTimestamps = TRUE; + config->tracingRelativeTimestamps = FALSE; + config->timeAlignment = TRUE; + config->startWTime = os_timeWGet(); /* RTC start time, used in log messages when tracingRelativeTimestamps = FALSE */ + config->startMTime = os_timeMGet(); /* Monotonic start time, used in log messages when tracingRelativeTimestamps = TRUE */ + config->startETime = os_timeEGet(); /* Elapsed start time */ + config->networkMaxWaitCount = D_DEFAULT_NETWORK_MAX_WAITCOUNT; + config->builtinTopicsEnabled = TRUE; + config->waitForRemoteReaders = FALSE; + config->role = NULL; + config->clientDurabilityEnabled = FALSE; /* Initially no client durability */ + config->capabilitySupport = TRUE; /* Capability interface enabled by default, can be overruled by OSPL_DURABILITY_CAPABILITY_SUPPORT environment variable */ + config->capabilityGroupHash = TRUE; /* Capability to hash data sets per group */ + config->capabilityEOTSupport = TRUE; /* Capability to align EOT messages */ + config->capabilityY2038Ready = FALSE; /* Capability to support times beyond 2038 */ + config->traceMask = 0; /* Initially do not log any trace information */ + config->seqnum_initval = 0ul; /* Initial start sequence number */ + config->capabilityMasterSelection = D_USE_MASTER_PRIORITY_ALGORITHM; /* Capability to use master priorities in the selection algorithm */ + config->masterSelectionLegacy = TRUE; /* Initially use the legacy master selection algorithm */ + config->initialMergeStateValue = 0; /* Initial merge state value */ + + /* Apply defaults */ + d_configurationSetDuration(&(config->heartbeatExpiryTime), D_DEFAULT_HEARTBEAT_EXPIRY_TIME); + config->heartbeatExpiry = D_DEFAULT_HEARTBEAT_EXPIRY_TIME; + d_configurationSetDuration(&(config->heartbeatUpdateInterval), D_DEFAULT_HEARTBEAT_UPDATE_FACTOR*D_DEFAULT_HEARTBEAT_EXPIRY_TIME); + d_configurationSetDuration(&(config->livelinessUpdateInterval), D_DEFAULT_LIVELINESS_UPDATE_FACTOR*D_DEFAULT_LIVELINESS_EXPIRY_TIME); + config->livelinessExpiry = D_DEFAULT_LIVELINESS_EXPIRY_TIME; + d_configurationSetDuration(&(config->livelinessExpiryTime), D_DEFAULT_LIVELINESS_EXPIRY_TIME); + d_configurationSetDuration(&(config->timeToWaitForAligner), D_DEFAULT_TIME_TO_WAIT_FOR_ALIGNER); + d_configurationSetDuration(&(config->serviceTerminatePeriod), D_DEFAULT_SERVICE_TERMINATE_PERIOD); + d_configurationSetDuration(&(config->terminateRemovalPeriod), D_DEFAULT_TERMINATE_REMOVAL_PERIOD); + d_configurationSetDuration(&(config->masterElectionWaitTime), D_DEFAULT_MASTER_ELECTION_WAIT_TIME); + d_configurationSetDuration(&(config->threadLivelinessReportPeriod), D_DEFAULT_THREAD_LIVELINESS_REPORT_PERIOD); + + /* Parse environment variables */ + d_configurationParseEnvVars(config); + + /* Parse the configuration and apply the settings as specified */ + os_threadAttrInit(&config->livelinessScheduling); + os_threadAttrInit(&config->heartbeatScheduling); + os_threadAttrInit(&config->persistentScheduling); + os_threadAttrInit(&config->alignerScheduling); + os_threadAttrInit(&config->aligneeScheduling); + config->persistentStoreStackSize = config->persistentScheduling.stackSize; /* Set the default stackSize to the OS default */ + + d_configurationSetTimingInitialWaitPeriod (config, D_DEFAULT_TIMING_INITIAL_WAIT_PERIOD); + d_configurationSetNetworkWaitForAttachmentMaxWaitCount (config, D_DEFAULT_NETWORK_MAX_WAITCOUNT); + d_configurationSetPublisherName (config, D_PUBLISHER_NAME); + d_configurationSetSubscriberName (config, D_SUBSCRIBER_NAME); + d_configurationSetPartitionName (config, D_PARTITION_NAME); + d_configurationSetTracingOutputFile (config, NULL); + d_configurationSetPersistentStoreSleepTime (config, D_DEFAULT_PERSISTENT_STORE_SLEEP_TIME); + d_configurationSetPersistentStoreSessionTime (config, D_DEFAULT_PERSISTENT_STORE_SESSION_TIME); + d_configurationSetPersistentQueueSize (config, D_DEFAULT_PERSISTENT_QUEUE_SIZE); + d_configurationSetPersistentKVCompressionEnabled (config, D_DEFAULT_PERSISTENT_KV_COMPRESSION_ENABLED); + d_configurationSetPersistentKVCompressionAlgorithm (config, D_DEFAULT_PERSISTENT_KV_COMPRESSION_ALGORITHM); + d_configurationSetOptimizeUpdateInterval (config, D_DEFAULT_OPTIMIZE_INTERVAL); + + d_configurationSetInitialRequestCombinePeriod (config, D_DEFAULT_INITIAL_REQUEST_COMBINE_PERIOD); + d_configurationSetOperationalRequestCombinePeriod (config, D_DEFAULT_OPERATIONAL_REQUEST_COMBINE_PERIOD); + d_configurationSetLatencyBudget (config, D_DEFAULT_LATENCY_BUDGET); + d_configurationSetHeartbeatLatencyBudget (config, D_DEFAULT_LATENCY_BUDGET); + d_configurationSetAlignmentLatencyBudget (config, D_DEFAULT_LATENCY_BUDGET); + d_configurationSetTransportPriority (config, D_DEFAULT_TRANSPORT_PRIORITY); + d_configurationSetHeartbeatTransportPriority (config, D_DEFAULT_TRANSPORT_PRIORITY); + d_configurationSetAlignmentTransportPriority (config, D_DEFAULT_TRANSPORT_PRIORITY); + d_configurationSetRole (config, D_DEFAULT_ROLE); + d_configurationSetMajorityVotingThreshold (config, D_DEFAULT_MAJORITY_VOTING_THRESHOLD); + + /* Determine if durability must align builtin topics. + * The current implementation will not align builtin topics + * if all DDSI services in the configuration have their + * element set to TRUE, and no native + * networking service is configured. If no networking at all + * is configured then mustAlignBuiltinTopics = TRUE. + * + * NOTE: Whether or not to align is decided based on analysis + * of the configuration during startup. This is a rather static + * approach and does not work in use cases where services + * can be created or die dynamically, wich may affect this + * decision. To support these kind of use cases a better + * approach would be for the durability service be notified + * if a networking services or DDSI services dies or joins, + * so durability can review the decision whether or not to align + * builtin topics. This will probably require new functionality + * in the process framework. + */ + + config->mustAlignBuiltinTopics = d_configurationDurabilityMustAlignBuiltin(cfg); + /* Only wait for remote readers if durability does NOT have to align + * builtin topics. + */ + config->waitForRemoteReaders = (!config->mustAlignBuiltinTopics); + config->deadlockDetection = FALSE; + durability->configuration = config; + + if(element){ + d_printTimedEvent(durability, D_LEVEL_INFO, + "Configuration defaults applied. Now searching for actual one...\n"); + + if(domainElement){ + d_configurationValueFloat(config, domainElement, "Lease/ExpiryTime/#text", d_configurationSetLivelinessExpiryTime); + d_configurationSetLivelinessUpdateFactor(config, domainElement, "Lease/ExpiryTime", "update_factor"); + d_configurationValueString(config, domainElement, "Role/#text", d_configurationSetRole); + d_configurationAttrValueBoolean(config, domainElement, "BuiltinTopics", "enabled", d_configurationSetBuiltinTopicsEnabled); + d_configurationValueFloat(config, domainElement, "ServiceTerminatePeriod/#text", d_configurationSetServiceTerminatePeriod); + d_configurationAttrValueBoolean(config, domainElement, "Watchdog", "deadlockDetection", d_configurationSetDeadlockDetection); + d_configurationValueString(config, domainElement, "y2038Ready/#text", d_configurationSetY2038Ready); + d_configurationValueString (config, domainElement, "GeneralWatchdog/Scheduling/Class/#text", d_configurationSetLivelinessSchedulingClass); + d_configurationValueLong (config, domainElement, "GeneralWatchdog/Scheduling/Priority/#text", d_configurationSetLivelinessSchedulingPriority); + config->durablePolicies = d_configurationResolveDurablePolicies(domainElement, "DurablePolicies/Policy"); + config->filters = d_configurationResolveFilters(config, domainElement, "Filters/Filter", durability); + } else { + OS_REPORT(OS_WARNING, D_CONTEXT, 0, + "No Domain configuration found. Applying default Lease and Role..."); + } + d_configurationAttrValueBoolean(config, element, "Watchdog", "deadlockDetection", d_configurationSetDeadlockDetection); + d_configurationValueString (config, element, "Watchdog/Scheduling/Class/#text", d_configurationSetLivelinessSchedulingClass); + d_configurationValueLong (config, element, "Watchdog/Scheduling/Priority/#text", d_configurationSetLivelinessSchedulingPriority); + + d_configurationValueString (config, element, "Persistent/StoreDirectory/#text", d_configurationSetPersistentStoreDirectory); + + d_configurationValueString (config, element, "Persistent/Scheduling/Class/#text", d_configurationSetPersistentSchedulingClass); + d_configurationValueLong (config, element, "Persistent/Scheduling/Priority/#text", d_configurationSetPersistentSchedulingPriority); + + d_configurationValueFloat (config, element, "Persistent/StoreSleepTime/#text", d_configurationSetPersistentStoreSleepTime); + d_configurationValueULong (config, element, "Persistent/QueueSize/#text", d_configurationSetPersistentQueueSize); + d_configurationValueString (config, element, "Persistent/StoreMode/#text", d_configurationSetPersistentStoreMode); + + d_configurationResolvePersistentKVConfig (config, element, "Persistent/KeyValueStore"); + + d_configurationValueULong (config, element, "Persistent/StoreOptimizeInterval/#text", d_configurationSetOptimizeUpdateInterval); + d_configurationValueFloat (config, element, "Persistent/StoreSessionTime/#text", d_configurationSetPersistentStoreSessionTime); + + d_configurationValueString (config, element, "EntityNames/Partition/#text", d_configurationSetPartitionName); + d_configurationValueString (config, element, "EntityNames/Publisher/#text", d_configurationSetPublisherName); + d_configurationValueString (config, element, "EntityNames/Subscriber/#text", d_configurationSetSubscriberName); + + d_configurationAttrValueBoolean (config, element, "Tracing", "synchronous", d_configurationSetTracingSynchronous); + d_configurationValueString (config, element, "Tracing/Verbosity/#text", d_configurationSetTracingVerbosity); + d_configurationValueString (config, element, "Tracing/OutputFile/#text", d_configurationSetTracingOutputFile); + d_configurationValueBoolean (config, element, "Tracing/Timestamps/#text", d_configurationSetTracingTimestamps); + d_configurationSetTracingRelativeTimestamps(config, element, "Tracing/Timestamps", "absolute"); + + d_configurationValueFloat (config, element, "Network/Heartbeat/ExpiryTime/#text", d_configurationSetHeartbeatExpiryTime); + d_configurationSetHeartbeatUpdateFactor(config, element,"Network/Heartbeat/ExpiryTime", "update_factor"); + d_configurationValueString (config, element, "Network/Heartbeat/Scheduling/Class/#text", d_configurationSetHeartbeatSchedulingClass); + d_configurationValueLong (config, element, "Network/Heartbeat/Scheduling/Priority/#text", d_configurationSetHeartbeatSchedulingPriority); + + d_configurationValueFloat (config, element, "Network/InitialDiscoveryPeriod/#text", d_configurationSetTimingInitialWaitPeriod); + d_configurationValueBoolean(config, element, "Network/Alignment/TimeAlignment/#text", d_configurationSetTimeAlignment); + d_configurationValueFloat (config, element, "Network/Alignment/TimeToWaitForAligner/#text", d_configurationSetTimeToWaitForAligner); + d_configurationValueFloat (config, element, "Network/Alignment/RequestCombinePeriod/Initial/#text", d_configurationSetInitialRequestCombinePeriod); + d_configurationValueFloat (config, element, "Network/Alignment/RequestCombinePeriod/Operational/#text", d_configurationSetOperationalRequestCombinePeriod); + d_configurationValueString (config, element, "Network/Alignment/AlignerScheduling/Class/#text", d_configurationSetAlignerSchedulingClass); + d_configurationValueLong (config, element, "Network/Alignment/AlignerScheduling/Priority/#text", d_configurationSetAlignerSchedulingPriority); + d_configurationValueString (config, element, "Network/Alignment/AligneeScheduling/Class/#text", d_configurationSetAligneeSchedulingClass); + d_configurationValueLong (config, element, "Network/Alignment/AligneeScheduling/Priority/#text", d_configurationSetAligneeSchedulingPriority); + + d_configurationAttrValueLong(config, element, "Network", "transport_priority", d_configurationSetTransportPriority); + /*Take over default transport priority first...*/ + d_configurationAttrValueLong(config, element, "Network", "transport_priority", d_configurationSetHeartbeatTransportPriority); + d_configurationAttrValueLong(config, element, "Network", "transport_priority", d_configurationSetAlignmentTransportPriority); + /*Now override with actual values if available.*/ + d_configurationAttrValueLong(config, element, "Network/Heartbeat", "transport_priority", d_configurationSetHeartbeatTransportPriority); + d_configurationAttrValueLong(config, element, "Network/Alignment", "transport_priority", d_configurationSetAlignmentTransportPriority); + + d_configurationAttrValueFloat(config, element, "Network", "latency_budget", d_configurationSetLatencyBudget); + /*Take over default latency budget first...*/ + d_configurationAttrValueFloat(config, element, "Network", "latency_budget", d_configurationSetHeartbeatLatencyBudget); + d_configurationAttrValueFloat(config, element, "Network", "latency_budget", d_configurationSetAlignmentLatencyBudget); + /*Now override with actual values if available.*/ + d_configurationAttrValueFloat(config, element, "Network/Heartbeat", "latency_budget", d_configurationSetHeartbeatLatencyBudget); + d_configurationAttrValueFloat(config, element, "Network/Alignment", "latency_budget", d_configurationSetAlignmentLatencyBudget); + + d_configurationSetNetworkWaitForAttachment(config, element, "Network/WaitForAttachment", "ServiceName/#text"); + + /* MasterElectionWaitTime */ + d_configurationValueFloat (config, element, "MasterElection/WaitTime/#text", d_configurationSetMasterElectionWaitTime); + + /* Client durability, enable by default if the ClientDurability tag is available */ + if (d_configurationHasTag(config, element, "ClientDurability")) { + config->clientDurabilityEnabled = TRUE; + } + d_configurationAttrValueBoolean(config, element, "ClientDurability", "enabled", d_configurationSetClientDurabilityEnabled); + if (config->clientDurabilityEnabled) { + /* Set default entitynames for client durability. + * Note that we use the durability partition as the default partition + */ + d_configurationSetClientDurabilityPartitionName (config, config->partitionName); + d_configurationSetClientDurabilityPublisherName (config, D_CLIENT_DURABILITY_PUBLISHER_NAME); + d_configurationSetClientDurabilitySubscriberName (config, D_CLIENT_DURABILITY_SUBSCRIBER_NAME); + /* Overwrite the defaults if specified in the config */ + d_configurationValueString (config, element, "ClientDurability/EntityNames/Partition/#text", d_configurationSetClientDurabilityPartitionName); + d_configurationValueString (config, element, "ClientDurability/EntityNames/Publisher/#text", d_configurationSetClientDurabilityPublisherName); + d_configurationValueString (config, element, "ClientDurability/EntityNames/Subscriber/#text", d_configurationSetClientDurabilitySubscriberName); + } + /* NameSpaces */ + config->policies = d_configurationResolvePolicies (element, "NameSpaces/Policy"); + config->nameSpaces = d_configurationResolveNameSpaces(config, element, "NameSpaces/NameSpace", &result); + } else { + d_printTimedEvent(durability, D_LEVEL_INFO, "Configuration defaults applied. No actual one found...\n"); + } + + if (c_iterLength(config->policies) == 0) { + /* If no policies are found, create a default policy for all namespaces */ + policy = d_policyNew("*", TRUE, D_ALIGNEE_INITIAL, FALSE, D_DURABILITY_ALL, + D_DEFAULT_EQUALITY_CHECK, D_DEFAULT_MASTER_PRIORITY); + config->policies = c_iterInsert(config->policies, policy); + } + /* Determine whether or not to use the legacy master selection algorithm + * We only use the new algorithm if there is at least one policy with a priority that differs from D_MAXIMUM_MASTER_PRIORITY + */ + iter = c_iterIterGet(config->policies); + while (((policy = d_policy(c_iterNext(&iter))) != NULL) && (config->masterSelectionLegacy)) { + config->masterSelectionLegacy = (policy->masterPriority == D_MAXIMUM_MASTER_PRIORITY); + } + + if (c_iterLength(config->nameSpaces) == 0) { + d_printTimedEvent(durability, D_LEVEL_SEVERE, "No namespaces configured, unable to start.\n"); + OS_REPORT(OS_FATAL, D_CONTEXT, 0, "Unable to start with empty namespaces configuration"); + result = -1; + } else { + c_bool found = FALSE; + /* Make sure the V_BUILTIN_PARTITION is part of the namespace */ + for(i=0; inameSpaces) && !found; i++){ + ns = d_nameSpace(c_iterObject(config->nameSpaces, i)); + found = d_configurationInNameSpace( + ns, + V_BUILTIN_PARTITION, V_TOPICINFO_NAME, TRUE); + if (!found) { + ns = NULL; + } + } + /* If DCPSTopic is not found, don't bother looking for the others. If it is found, look for the + * other topics in the same namespace. + * If builtin-topics are not enabled, just create namespace for DCPSTopic. + */ + if (found && config->builtinTopicsEnabled) { + for (i = 0; d_builtinTopics[i] != NULL && found; i++) { + found = d_configurationInNameSpace(ns, V_BUILTIN_PARTITION, (d_topic) d_builtinTopics[i], TRUE); + } + } + + if (!found) { + if (ns) { + char bs[256], *bsp = bs; + for (i = 0; d_builtinTopics[i] != NULL && bsp < bs + sizeof (bs); i++) { + bsp += snprintf (bsp, (size_t) (bs + sizeof (bs) - bsp), "%s%s", (i == 0) ? "" : ", ", d_builtinTopics[i]); + } + d_printTimedEvent(durability, D_LEVEL_SEVERE, "%s should all be in the same namespace.\n", bs); + OS_REPORT(OS_ERROR, D_CONTEXT, 0, "%s should all be in the same namespace.", bs); + result = -1; + } else { + d_policy policy; + d_mergePolicy mergeType; + + policy = d_policyNew("AutoBuiltinTopics", TRUE, D_ALIGNEE_INITIAL, FALSE, D_DURABILITY_TRANSIENT, + D_DEFAULT_EQUALITY_CHECK, config->masterSelectionLegacy); + + ns = d_nameSpaceNew("AutoBuiltinTopics", policy); + + d_nameSpaceAddElement(ns, "NoName", V_BUILTIN_PARTITION, V_TOPICINFO_NAME); + /* Only add these groups to the namespace when builtin-topics are enabled */ + if(config->builtinTopicsEnabled) { + for (i = 0; d_builtinTopics[i] != NULL; i++) { + d_nameSpaceAddElement(ns, "NoName", V_BUILTIN_PARTITION, d_builtinTopics[i]); + } + } + config->nameSpaces = c_iterInsert(config->nameSpaces, ns); + /* Decide the policy of this nameSpace based on the mustAlignBuiltinTopics setting */ + if (config->mustAlignBuiltinTopics) { + /* builtin topics must be merged */ + mergeType = D_MERGE_MERGE; + } else { + /* builtin topics can be ignored */ + mergeType = D_MERGE_IGNORE; + } + /* Use the merge policy */ + d_policyAddMergeRule(policy, mergeType, "AutoBuiltinTopics"); + d_policyFree(policy); + } + } + } + + if (result == 0) { + result = d_configurationSanityCheck(config); + } + + return result; +} + +static void +d_configurationReportPolicy( + c_voidp object, + c_voidp userData) +{ + d_policy policy; + d_durability durability; + const c_char* aligner; + const c_char* alignee; + const c_char* kind; + const c_char* name; + const c_char* delayed; + const c_char* equality; + + policy = d_policy(object); + durability = d_durability(userData); + + switch(d_policyGetDurabilityKind(policy)){ + case D_DURABILITY_ALL: + kind = "ALL"; + break; + case D_DURABILITY_PERSISTENT: + kind = "PERSISTENT"; + break; + case D_DURABILITY_TRANSIENT: + kind = "TRANSIENT"; + break; + case D_DURABILITY_TRANSIENT_LOCAL: + kind = "TRANSIENT_LOCAL"; + break; + default: + kind = "NOT_VALID"; + (void)kind; + assert(FALSE); + break; + } + switch(d_policyGetAlignmentKind(policy)){ + case D_ALIGNEE_INITIAL: + alignee = "INITIAL"; + break; + case D_ALIGNEE_LAZY: + alignee = "LAZY"; + break; + case D_ALIGNEE_ON_REQUEST: + alignee = "ON_REQUEST"; + break; + default: + alignee = "<>"; + (void)alignee; + assert(FALSE); + break; + } + + if(d_policyGetAligner(policy)){ + aligner = "TRUE"; + } else { + aligner = "FALSE"; + } + if(d_policyGetDelayedAlignment(policy)){ + delayed = "TRUE"; + } else { + delayed = "FALSE"; + } + if (d_policyGetEqualityCheck(policy)) { + equality = "TRUE"; + } else { + equality = "FALSE"; + } + name = d_policyGetNameSpace(policy); + + d_printEvent(durability, D_LEVEL_CONFIG, + " - Policy:\n" \ + " - NameSpace : %s\n" \ + " - Aligner : %s\n" \ + " - Alignee : %s\n" \ + " - DurabilityKind : %s\n" \ + " - DelayedAlignment : %s\n" \ + " - EqualityCheck : %s\n", + name, aligner, alignee, kind, delayed, equality); + if (d_policyGetAligner(policy) == TRUE) { + d_printEvent(durability, D_LEVEL_CONFIG, + " - MasterPriority : %u\n", + d_policyGetMasterPriority(policy)); + } + + /* Print the merge rules, if any */ + if (policy->mergePolicyRules == NULL) { + d_printEvent(durability, D_LEVEL_CONFIG, + " - Rules : NULL\n"); + } else { + d_policyMergeRule* rule; + char *mergeTypeStr = "IGNORE"; + c_iterIter iter = c_iterIterGet(policy->mergePolicyRules); + d_printEvent(durability, D_LEVEL_CONFIG, + " - Rules :"); + while ((rule = (d_policyMergeRule *)c_iterNext(&iter)) != NULL) { + switch (rule->mergeType) { + case D_MERGE_IGNORE : + mergeTypeStr = "IGNORE"; + break; + case D_MERGE_MERGE : + mergeTypeStr = "MERGE"; + break; + case D_MERGE_DELETE : + mergeTypeStr = "DELETE"; + break; + case D_MERGE_REPLACE : + mergeTypeStr = "REPLACE"; + break; + case D_MERGE_CATCHUP : + mergeTypeStr = "CATCHUP"; + break; + } + d_printEvent(durability, D_LEVEL_CONFIG, " (%s,%s)", rule->scope, mergeTypeStr); + } + d_printEvent(durability, D_LEVEL_CONFIG, "\n"); + } + +} + + +static void +d_configurationReportDurablePolicies( + d_durability durability) +{ + d_configuration config = d_durabilityGetConfiguration(durability); + c_iterIter iter = c_iterIterGet(config->durablePolicies); + struct durablePolicy *rule; + + d_printEvent(durability, D_LEVEL_CONFIG, + "- DurablePolicies :"); + while ((rule = (struct durablePolicy *)c_iterNext(&iter)) != NULL) { + d_printEvent(durability, D_LEVEL_CONFIG, " (%s,%s)", rule->obtain, rule->cache ? "TRUE" : "FALSE"); + } + d_printEvent(durability, D_LEVEL_CONFIG, "\n"); +} + + +static void +d_configurationNameSpacesCombine( + c_voidp object, + c_voidp userData) +{ + d_nameSpace ns; + d_durability durability; + c_char* partitionTopic; + c_char* name; + + const c_char* aligner; + const c_char* alignee; + const c_char* kind; + + ns = d_nameSpace(object); + durability = d_durability(userData); + partitionTopic = d_nameSpaceGetPartitionTopics(ns); + + switch(d_nameSpaceGetDurabilityKind(ns)){ + case D_DURABILITY_ALL: + kind = "ALL"; + break; + case D_DURABILITY_PERSISTENT: + kind = "PERSISTENT"; + break; + case D_DURABILITY_TRANSIENT: + kind = "TRANSIENT"; + break; + case D_DURABILITY_TRANSIENT_LOCAL: + kind = "TRANSIENT_LOCAL"; + break; + default: + kind = "NOT_VALID"; + (void)kind; + assert(FALSE); + break; + } + switch(d_nameSpaceGetAlignmentKind(ns)){ + case D_ALIGNEE_INITIAL: + alignee = "INITIAL"; + break; + case D_ALIGNEE_LAZY: + alignee = "LAZY"; + break; + case D_ALIGNEE_ON_REQUEST: + alignee = "ON_REQUEST"; + break; + default: + alignee = "<>"; + (void)alignee; + assert(FALSE); + break; + } + + if(d_nameSpaceIsAligner(ns)){ + aligner = "TRUE"; + } else { + aligner = "FALSE"; + } + + name = d_nameSpaceGetName(ns); + + d_printEvent(durability, D_LEVEL_CONFIG, + " - NameSpace:\n" \ + " - Name : %s\n" \ + " - Aligner : %s\n" \ + " - Alignee : %s\n" \ + " - DurabilityKind : %s\n" \ + " - PartitionTopic : %s\n" \ + " - DelayedAlignment : %s\n", + name, aligner, alignee, kind, partitionTopic, + d_nameSpaceGetDelayedAlignment(ns) ? "TRUE" : "FALSE"); + + os_free(partitionTopic); + + return; +} + +static c_bool +d_configurationServiceNamesCombine( + c_char* serviceName, + c_voidp userData) +{ + d_durability durability; + + durability = d_durability(userData); + + d_printEvent(durability, D_LEVEL_CONFIG, " - %s\n", serviceName); + + return TRUE; +} + +void +d_configurationReport( + d_configuration config, + d_durability durability) +{ + const c_char* class, *class2; + const c_char* pstoreDir; + const c_char* pstoreMode; + const c_char* verbosity; + const c_char* timestamps; + const c_char* timeAlignment; + const c_char* relativeTimestamps; + const c_char* tracingSynchronous; + const c_char* algorithm; + + d_printTimedEvent(durability, D_LEVEL_CONFIG, "Configuration:\n"); + + d_printEvent(durability, D_LEVEL_CONFIG, + "- OSPL Version : %s\n", + OSPL_VERSION_STR); + if (strcmp(OSPL_INNER_REV_STR, "") != 0) { + d_printEvent(durability, D_LEVEL_CONFIG, + " - ospli revision : %s\n", + OSPL_INNER_REV_STR); + } + if (strcmp(OSPL_OUTER_REV_STR, "") != 0) { + d_printEvent(durability, D_LEVEL_CONFIG, + " - osplo revision : %s\n", + OSPL_OUTER_REV_STR); + } + + d_printEvent(durability, D_LEVEL_CONFIG, + "- Version : %hu.%hu (vendorId %x%x)\n", + durability->myVersion.major, durability->myVersion.minor, + durability->myVersion.vendorId.vendorId[0], durability->myVersion.vendorId.vendorId[1]); + + d_printEvent(durability, D_LEVEL_CONFIG, + "- Role : %s\n", + config->role); + + switch(config->livelinessScheduling.schedClass){ + case OS_SCHED_DEFAULT: + class = "DEFAULT"; + break; + case OS_SCHED_REALTIME: + class = "REALTIME"; + break; + case OS_SCHED_TIMESHARE: + class = "TIMESHARE"; + break; + default: + assert(FALSE); + class = "UNKNOWN"; + break; + } + d_printEvent(durability, D_LEVEL_CONFIG, + "- ServiceTerminatePeriod : %"PA_PRIduration"\n" \ + "- Liveliness.ExpiryTime : %"PA_PRIduration"\n" \ + "- Liveliness.UpdateInterval : %"PA_PRIduration"\n" \ + "- TerminateRemovalPeriod : %"PA_PRIduration"\n" \ + "- MasterElection.WaitTime : %"PA_PRIduration"\n" \ + "- Liveliness.Scheduling.Class : %s\n" \ + "- Liveliness.Scheduling.Priority : %d\n" \ + "- Liveliness.DeadlockDetection : %s\n" + , OS_DURATION_PRINT(config->serviceTerminatePeriod) + , OS_DURATION_PRINT(config->livelinessExpiryTime) + , OS_DURATION_PRINT(config->livelinessUpdateInterval) + , OS_DURATION_PRINT(config->terminateRemovalPeriod) + , OS_DURATION_PRINT(config->masterElectionWaitTime) + , class + , config->livelinessScheduling.schedPriority + , (config->deadlockDetection?"TRUE":"FALSE")); + + d_configurationReportDurablePolicies(durability); + + if(!(config->persistentStoreDirectory)){ + pstoreDir = "NULL"; + } else { + pstoreDir = config->persistentStoreDirectory; + } + + switch(config->persistentStoreMode){ + case D_STORE_TYPE_XML: + pstoreMode = "XML"; + break; + case D_STORE_TYPE_BIG_ENDIAN: + pstoreMode = "BIG ENDIAN"; + break; + case D_STORE_TYPE_UNKNOWN: + pstoreMode = "UNKNOWN"; + break; + case D_STORE_TYPE_KV: + pstoreMode = "KV"; + break; + default: + assert(FALSE); + pstoreMode = "UNKNOWN"; + break; + } + + switch(config->persistentScheduling.schedClass){ + case OS_SCHED_DEFAULT: + class = "DEFAULT"; + break; + case OS_SCHED_REALTIME: + class = "REALTIME"; + break; + case OS_SCHED_TIMESHARE: + class = "TIMESHARE"; + break; + default: + assert(FALSE); + class = "UNKNOWN"; + break; + } + + d_printEvent(durability, D_LEVEL_CONFIG, + "- Persistent.StoreDirectory : %s\n" \ + "- Persistent.StoreMode : %s%s%s\n" + , pstoreDir + , pstoreMode + , config->persistentKVStoreStorageType ? ":" : "" + , config->persistentKVStoreStorageType ? config->persistentKVStoreStorageType : ""); + + if (config->persistentStoreMode == D_STORE_TYPE_KV) { + d_printEvent(durability, D_LEVEL_CONFIG, + "- Persistent.KeyValueStore.KeyValueStore : %s\n" \ + "- Persistent.KeyValueStore.Compression.enabled: %s\n", + config->persistentKVStoreStorageParameters ? config->persistentKVStoreStorageParameters : "", + config->persistentKVStoreCompressionEnabled ? "TRUE" : "FALSE"); + if (config->persistentKVStoreCompressionEnabled == TRUE) { + algorithm = d_compressionKVImage(config->persistentKVStoreCompressionAlgorithm); + d_printEvent(durability, D_LEVEL_CONFIG, + "- Persistent.KeyValueStore.Compression.algorithm: %s\n" \ + , algorithm); + } + } + + d_printEvent(durability, D_LEVEL_CONFIG, + "- Persistent.QueueSize : %u\n" + , config->persistentQueueSize); + + d_printEvent(durability, D_LEVEL_CONFIG, + "- Persistent.StoreSleepTime : %"PA_PRIduration"\n" \ + "- Persistent.StoreSessionTime : %"PA_PRIduration"\n" \ + "- Persistent.StoreOptimizeInterval : %d\n" \ + "- Persistent.Scheduling.Class : %s\n" \ + "- Persistent.Scheduling.Priority : %d\n" + , OS_DURATION_PRINT(config->persistentStoreSleepTime) + , OS_DURATION_PRINT(config->persistentStoreSessionTime) + , config->persistentUpdateInterval + , class + , config->persistentScheduling.schedPriority); + + d_printEvent(durability, D_LEVEL_CONFIG, + "- EntityNames.Publisher : %s\n" \ + "- EntityNames.Subscriber : %s\n" \ + "- EntityNames.Partition : %s\n" + , config->publisherName + , config->subscriberName + , config->partitionName); + + switch(config->tracingVerbosityLevel){ + case D_LEVEL_NONE: + verbosity = "NONE"; + break; + case D_LEVEL_SEVERE: + verbosity = "SEVERE"; + break; + case D_LEVEL_WARNING: + verbosity = "WARNING"; + break; + case D_LEVEL_CONFIG: + verbosity = "CONFIG"; + break; + case D_LEVEL_INFO: + verbosity = "INFO"; + break; + case D_LEVEL_FINE: + verbosity = "FINE"; + break; + case D_LEVEL_FINER: + verbosity = "FINER"; + break; + case D_LEVEL_FINEST: + verbosity = "FINEST"; + break; + default: + assert(FALSE); + verbosity = "UNKNOWN"; + break; + } + if(config->tracingTimestamps == TRUE){ + timestamps = "TRUE"; + } else { + timestamps = "FALSE"; + } + if(config->tracingRelativeTimestamps == TRUE){ + relativeTimestamps = "TRUE"; + } else { + relativeTimestamps = "FALSE"; + } + if(config->tracingSynchronous == TRUE){ + tracingSynchronous = "TRUE"; + } else { + tracingSynchronous = "FALSE"; + } + d_printEvent(durability, D_LEVEL_CONFIG, + "- Tracing.Verbosity : %s\n" \ + "- Tracing.OutputFile : %s\n" \ + "- Tracing.Synchronous : %s\n" \ + "- Tracing.Timestamps : %s\n" \ + "- Tracing.RelativeTimestamps : %s\n" + , verbosity + , config->tracingOutputFileName + , tracingSynchronous + , timestamps + , relativeTimestamps); + + d_printEvent(durability, D_LEVEL_CONFIG, + "- Network.InitialDiscoveryPeriod : %"PA_PRIduration"\n" \ + "- Network.LatencyBudget : %"PA_PRIduration"\n" \ + "- Network.TransportPriority : %d\n" + , OS_DURATION_PRINT(config->timingInitialWaitPeriod) + , OS_DURATION_PRINT(config->latencyBudget) + , config->transportPriority); + + switch(config->heartbeatScheduling.schedClass){ + case OS_SCHED_DEFAULT: + class = "DEFAULT"; + break; + case OS_SCHED_REALTIME: + class = "REALTIME"; + break; + case OS_SCHED_TIMESHARE: + class = "TIMESHARE"; + break; + default: + assert(FALSE); + class = "UNKNOWN"; + break; + } + + d_printEvent(durability, D_LEVEL_CONFIG, + "- Network.Heartbeat.ExpiryTime : %"PA_PRIduration"\n" \ + "- Network.Heartbeat.UpdateInterval : %"PA_PRIduration"\n" \ + "- Network.Heartbeat.LatencyBudget : %"PA_PRIduration"\n" \ + "- Network.Heartbeat.TransportPriority : %d\n" \ + "- Network.Heartbeat.Scheduling.Class : %s\n" \ + "- Network.Heartbeat.Scheduling.Priority : %d\n" \ + , OS_DURATION_PRINT(config->heartbeatExpiryTime) + , OS_DURATION_PRINT(config->heartbeatUpdateInterval) + , OS_DURATION_PRINT(config->heartbeatLatencyBudget) + , config->heartbeatTransportPriority + , class + , config->heartbeatScheduling.schedPriority + ); + + switch(config->alignerScheduling.schedClass){ + case OS_SCHED_DEFAULT: + class = "DEFAULT"; + break; + case OS_SCHED_REALTIME: + class = "REALTIME"; + break; + case OS_SCHED_TIMESHARE: + class = "TIMESHARE"; + break; + default: + assert(FALSE); + class = "UNKNOWN"; + break; + } + + switch(config->aligneeScheduling.schedClass){ + case OS_SCHED_DEFAULT: + class2 = "DEFAULT"; + break; + case OS_SCHED_REALTIME: + class2 = "REALTIME"; + break; + case OS_SCHED_TIMESHARE: + class2 = "TIMESHARE"; + break; + default: + assert(FALSE); + class2 = "UNKNOWN"; + break; + } + + if(config->timeAlignment == TRUE){ + timeAlignment = "TRUE"; + } else { + timeAlignment = "FALSE"; + } + + d_printEvent(durability, D_LEVEL_CONFIG, + "- Network.TimeAlignment : %s\n" \ + "- Network.Alignment.RequestCombine.Initial : %"PA_PRIduration"\n" \ + "- Network.Alignment.RequestCombine.Operational: %"PA_PRIduration"\n" \ + "- Network.Alignment.LatencyBudget : %"PA_PRIduration"\n" \ + "- Network.Alignment.TransportPriority : %d\n" \ + , timeAlignment + , OS_DURATION_PRINT(config->initialRequestCombinePeriod) + , OS_DURATION_PRINT(config->operationalRequestCombinePeriod) + , OS_DURATION_PRINT(config->alignerLatencyBudget) + , config->alignerTransportPriority); + + d_printEvent(durability, D_LEVEL_CONFIG, + "- Network.Alignment.AlignerScheduling.Class : %s\n" \ + "- Network.Alignment.AlignerScheduling.Priority: %d\n" \ + "- Network.Alignment.AligneeScheduling.Class : %s\n" \ + "- Network.Alignment.AligneeScheduling.Priority: %d\n" \ + "- Network.Alignment.TimeToWaitForAligner : %"PA_PRIduration"\n" + , class + , config->alignerScheduling.schedPriority + , class2 + , config->aligneeScheduling.schedPriority + , OS_DURATION_PRINT(config->timeToWaitForAligner)); + + + d_printEvent(durability, D_LEVEL_CONFIG, + "- Network.WaitForAttachment.MaxWaitCount : %u\n" \ + "- Network.WaitForAttachment.ServiceNames : \n" + , config->networkMaxWaitCount + ); + + d_printEvent(durability, D_LEVEL_CONFIG, + "- BuiltinTopics.enabled : %s\n", + (config->builtinTopicsEnabled) ? "TRUE" : "FALSE"); + + d_printEvent(durability, D_LEVEL_CONFIG, + "- BuiltinTopicAlignment : %s\n", + (config->mustAlignBuiltinTopics) ? "TRUE" : "FALSE"); + + d_printEvent(durability, D_LEVEL_CONFIG, + "- MajorityVotingThreshold : %u\n", config->majorityVotingThreshold); + + d_printEvent(durability, D_LEVEL_CONFIG, + "- WaitForRemoteReaders : %s\n", + (config->waitForRemoteReaders) ? "TRUE" : "FALSE"); + + d_printEvent(durability, D_LEVEL_CONFIG, + "- capabilitySupport enabled : %s\n", + (config->capabilitySupport) ? "TRUE" : "FALSE"); + + if (config->capabilitySupport) { + d_printEvent(durability, D_LEVEL_CONFIG, + " - groupHash : %s\n" \ + " - EOTSupport : %s\n" \ + " - y2038Ready : %s\n", + (config->capabilityGroupHash) ? "TRUE" : "FALSE", + (config->capabilityEOTSupport) ? "TRUE" : "FALSE", + (config->capabilityY2038Ready) ? "TRUE" : "FALSE"); + } + + if (config->clientDurabilityEnabled) { + d_printEvent(durability, D_LEVEL_CONFIG, + "- ClientDurabilityEnabled : TRUE\n" \ + "- ClientDurability.EntityNames.Publisher : %s\n" \ + "- ClientDurability.EntityNames.Subscriber : %s\n" \ + "- ClientDurability.EntityNames.Partition : %s\n" + , config->clientDurabilityPublisherName + , config->clientDurabilitySubscriberName + , config->clientDurabilityPartitionName); + } else { + d_printEvent(durability, D_LEVEL_CONFIG, + "- ClientDurabilityEnabled : FALSE\n"); + } + + d_printEvent(durability, D_LEVEL_CONFIG, + "- masterSelectionLegacy : %s\n", + (config->masterSelectionLegacy) ? "TRUE" : "FALSE"); + + d_printEvent(durability, D_LEVEL_CONFIG, + "- ThreadLivelinessReportPeriod : %"PA_PRIduration"\n", + OS_DURATION_PRINT(config->threadLivelinessReportPeriod)); + + d_tableWalk(config->networkServiceNames, d_configurationServiceNamesCombine, durability); + + d_printEvent(durability, D_LEVEL_CONFIG, + "- NameSpaces :\n"); + c_iterWalk(config->nameSpaces, d_configurationNameSpacesCombine, durability); + + d_printEvent(durability, D_LEVEL_CONFIG, + "- Policies :\n"); + c_iterWalk(config->policies, d_configurationReportPolicy, durability); +} + +void +d_configurationSetRole( + d_configuration config, + const c_char* role) +{ + if(config->role){ + os_free(config->role); + config->role = NULL; + } + config->role = os_strdup(role); +} + +void +d_configurationSetServiceTerminatePeriod( + d_configuration config, + const c_float seconds) +{ + c_float sec; + + sec = seconds; + + if (sec < D_MINIMUM_SERVICE_TERMINATE_PERIOD) { + sec = D_MINIMUM_SERVICE_TERMINATE_PERIOD; + } + if (sec > D_MAXIMUM_SERVICE_TERMINATE_PERIOD) { + sec = D_MAXIMUM_SERVICE_TERMINATE_PERIOD; + } + config->serviceTerminate = sec; + d_configurationSetDuration(&(config->serviceTerminatePeriod), sec); +} + + +void +d_configurationSetLivelinessExpiryTime( + d_configuration config, + c_float seconds) +{ + c_float sec; + + sec = seconds; + + if (sec < D_MINIMUM_LIVELINESS_EXPIRY_TIME) { + sec = D_MINIMUM_LIVELINESS_EXPIRY_TIME; + } + if (sec > D_MAXIMUM_LIVELINESS_EXPIRY_TIME) { + sec = D_MAXIMUM_LIVELINESS_EXPIRY_TIME; + } + config->livelinessExpiry = sec; + d_configurationSetDuration(&(config->livelinessExpiryTime), sec); +} + +void +d_configurationSetLivelinessUpdateFactor( + d_configuration config, + u_cfElement element, + const c_char* expiryTimePath, + const c_char* updateFactorName) +{ + c_float sec; + u_cfElement expiryElement; + c_iter elements; + c_bool success; + + elements = u_cfElementXPath(element, expiryTimePath); + + if(elements){ + expiryElement = u_cfElement(c_iterTakeFirst(elements)); + + while(expiryElement){ + success = u_cfElementAttributeFloatValue(expiryElement, updateFactorName, &sec); + + if(success == TRUE){ + if (sec < D_MINIMUM_LIVELINESS_UPDATE_FACTOR) { + sec = D_MINIMUM_LIVELINESS_UPDATE_FACTOR; + } + if (sec > D_MAXIMUM_LIVELINESS_UPDATE_FACTOR) { + sec = D_MAXIMUM_LIVELINESS_UPDATE_FACTOR; + } + sec = config->livelinessExpiry * sec; + d_configurationSetDuration(&(config->livelinessUpdateInterval), sec); + } + u_cfElementFree(expiryElement); + expiryElement = u_cfElement(c_iterTakeFirst(elements)); + } + c_iterFree(elements); + } +} + +void +d_configurationSetLivelinessSchedulingClass( + d_configuration config, + const c_char* class) +{ + if(os_strcasecmp(class, "Timeshare") == 0){ + config->livelinessScheduling.schedClass = OS_SCHED_TIMESHARE; + } else if(os_strcasecmp(class, "Realtime") == 0){ + config->livelinessScheduling.schedClass = OS_SCHED_REALTIME; + } else { + config->livelinessScheduling.schedClass = OS_SCHED_DEFAULT; + } +} + +void +d_configurationSetLivelinessSchedulingPriority( + d_configuration config, + c_long priority) +{ + config->livelinessScheduling.schedPriority = priority; +} + +void +d_configurationSetHeartbeatSchedulingClass( + d_configuration config, + const c_char* class) +{ + if(os_strcasecmp(class, "Timeshare") == 0){ + config->heartbeatScheduling.schedClass = OS_SCHED_TIMESHARE; + } else if(os_strcasecmp(class, "Realtime") == 0){ + config->heartbeatScheduling.schedClass = OS_SCHED_REALTIME; + } else { + config->heartbeatScheduling.schedClass = OS_SCHED_DEFAULT; + } +} + +void +d_configurationSetHeartbeatSchedulingPriority( + d_configuration config, + c_long priority) +{ + config->heartbeatScheduling.schedPriority = priority; +} + +void +d_configurationSetPersistentSchedulingClass( + d_configuration config, + const c_char* class) +{ + if(os_strcasecmp(class, "Timeshare") == 0){ + config->persistentScheduling.schedClass = OS_SCHED_TIMESHARE; + } else if(os_strcasecmp(class, "Realtime") == 0){ + config->persistentScheduling.schedClass = OS_SCHED_REALTIME; + } else { + config->persistentScheduling.schedClass = OS_SCHED_DEFAULT; + } +} + +void +d_configurationSetPersistentSchedulingPriority( + d_configuration config, + c_long priority) +{ + config->persistentScheduling.schedPriority = priority; +} + +void +d_configurationSetAlignerSchedulingClass( + d_configuration config, + const c_char* class) +{ + if(os_strcasecmp(class, "Timeshare") == 0){ + config->alignerScheduling.schedClass = OS_SCHED_TIMESHARE; + } else if(os_strcasecmp(class, "Realtime") == 0){ + config->alignerScheduling.schedClass = OS_SCHED_REALTIME; + } else { + config->alignerScheduling.schedClass = OS_SCHED_DEFAULT; + } +} + +void +d_configurationSetPersistentSchedulingStackSize( + d_configuration config, + c_ulong stackSize) +{ + config->persistentScheduling.stackSize = stackSize; +} + +void +d_configurationSetAlignerSchedulingPriority( + d_configuration config, + c_long priority) +{ + config->alignerScheduling.schedPriority = priority; +} + +void +d_configurationSetAligneeSchedulingClass( + d_configuration config, + const c_char* class) +{ + if(os_strcasecmp(class, "Timeshare") == 0){ + config->aligneeScheduling.schedClass = OS_SCHED_TIMESHARE; + } else if(os_strcasecmp(class, "Realtime") == 0){ + config->aligneeScheduling.schedClass = OS_SCHED_REALTIME; + } else { + config->aligneeScheduling.schedClass = OS_SCHED_DEFAULT; + } +} + +void +d_configurationSetAligneeSchedulingPriority( + d_configuration config, + c_long priority) +{ + config->aligneeScheduling.schedPriority = priority; +} + +void +d_configurationSetHeartbeatUpdateFactor( + d_configuration config, + u_cfElement element, + const c_char* expiryTimePath, + const c_char* updateFactorName) +{ + c_float sec; + u_cfElement expiryElement; + c_iter elements; + c_bool success; + + elements = u_cfElementXPath(element, expiryTimePath); + + if(elements){ + expiryElement = u_cfElement(c_iterTakeFirst(elements)); + + while(expiryElement){ + success = u_cfElementAttributeFloatValue(expiryElement, updateFactorName, &sec); + + if(success == TRUE){ + if (sec < D_MINIMUM_HEARTBEAT_UPDATE_FACTOR) { + sec = D_MINIMUM_HEARTBEAT_UPDATE_FACTOR; + } + if (sec > D_MAXIMUM_HEARTBEAT_UPDATE_FACTOR) { + sec = D_MAXIMUM_HEARTBEAT_UPDATE_FACTOR; + } + sec = config->heartbeatExpiry * sec; + d_configurationSetDuration(&(config->heartbeatUpdateInterval), sec); + } + u_cfElementFree(expiryElement); + expiryElement = u_cfElement(c_iterTakeFirst(elements)); + } + c_iterFree(elements); + } +} + +void +d_configurationSetBuiltinTopicsEnabled( + d_configuration config, + c_bool enabled) +{ + config->builtinTopicsEnabled = enabled; +} + +void +d_configurationSetDeadlockDetection( + d_configuration config, + c_bool deadlockDetection) +{ + config->deadlockDetection = deadlockDetection; +} + +void +d_configurationSetY2038Ready( + d_configuration config, + const c_char *y2038Ready) +{ + config->capabilityY2038Ready = (os_strcasecmp(y2038Ready, "true") == 0); +} + + +void +d_configurationSetHeartbeatExpiryTime( + d_configuration config, + c_float seconds) +{ + c_float sec; + + sec = seconds; + + if (sec < D_MINIMUM_HEARTBEAT_EXPIRY_TIME) { + sec = D_MINIMUM_HEARTBEAT_EXPIRY_TIME; + } + if (sec > D_MAXIMUM_HEARTBEAT_EXPIRY_TIME) { + sec = D_MAXIMUM_HEARTBEAT_EXPIRY_TIME; + } + d_configurationSetDuration(&(config->heartbeatExpiryTime), sec); + config->heartbeatExpiry = sec; +} + +void +d_configurationSetTimingInitialWaitPeriod( + d_configuration config, + c_float seconds) +{ + c_float sec; + + sec = seconds; + + if (sec < D_MINIMUM_TIMING_INITIAL_WAIT_PERIOD) { + sec = D_MINIMUM_TIMING_INITIAL_WAIT_PERIOD; + } + if (sec > D_MAXIMUM_TIMING_INITIAL_WAIT_PERIOD) { + sec = D_MAXIMUM_TIMING_INITIAL_WAIT_PERIOD; + } + d_configurationSetDuration(&(config->timingInitialWaitPeriod), sec); +} + + +void +d_configurationSetMasterElectionWaitTime( + d_configuration config, + c_float seconds) +{ + c_float sec; + + sec = seconds; + + if (sec < D_MINIMUM_MASTER_ELECTION_WAIT_TIME) { + sec = D_MINIMUM_MASTER_ELECTION_WAIT_TIME; + } + if (sec > D_MAXIMUM_MASTER_ELECTION_WAIT_TIME) { + sec = D_MAXIMUM_MASTER_ELECTION_WAIT_TIME; + } + d_configurationSetDuration(&(config->masterElectionWaitTime), sec); +} + +void +d_configurationSetLatencyBudget( + d_configuration config, + c_float seconds) +{ + c_float sec; + + sec = seconds; + + if (sec < D_MINIMUM_LATENCY_BUDGET) { + sec = D_MINIMUM_LATENCY_BUDGET; + } + if (sec > D_MAXIMUM_LATENCY_BUDGET) { + sec = D_MAXIMUM_LATENCY_BUDGET; + } + d_configurationSetDuration(&(config->latencyBudget), sec); +} + +void +d_configurationSetHeartbeatLatencyBudget( + d_configuration config, + c_float seconds) +{ + c_float sec; + + sec = seconds; + + if (sec < D_MINIMUM_LATENCY_BUDGET) { + sec = D_MINIMUM_LATENCY_BUDGET; + } + if (sec > D_MAXIMUM_LATENCY_BUDGET) { + sec = D_MAXIMUM_LATENCY_BUDGET; + } + d_configurationSetDuration(&(config->heartbeatLatencyBudget), sec); +} + +void +d_configurationSetAlignmentLatencyBudget( + d_configuration config, + c_float seconds) +{ + c_float sec; + + sec = seconds; + + if (sec < D_MINIMUM_LATENCY_BUDGET) { + sec = D_MINIMUM_LATENCY_BUDGET; + } + if (sec > D_MAXIMUM_LATENCY_BUDGET) { + sec = D_MAXIMUM_LATENCY_BUDGET; + } + d_configurationSetDuration(&(config->alignerLatencyBudget), sec); +} + + +void +d_configurationSetTransportPriority( + d_configuration config, + c_long prio) +{ + c_long p; + + p = prio; + + if (p < D_MINIMUM_TRANSPORT_PRIORITY) { + p = D_MINIMUM_TRANSPORT_PRIORITY; + } + if (p > D_MAXIMUM_TRANSPORT_PRIORITY) { + p = D_MAXIMUM_TRANSPORT_PRIORITY; + } + config->transportPriority = p; +} + +void +d_configurationSetHeartbeatTransportPriority( + d_configuration config, + c_long prio) +{ + c_long p; + + p = prio; + + if (p < D_MINIMUM_TRANSPORT_PRIORITY) { + p = D_MINIMUM_TRANSPORT_PRIORITY; + } + if (p > D_MAXIMUM_TRANSPORT_PRIORITY) { + p = D_MAXIMUM_TRANSPORT_PRIORITY; + } + config->heartbeatTransportPriority = p; +} + +void +d_configurationSetAlignmentTransportPriority( + d_configuration config, + c_long prio) +{ + c_long p; + + p = prio; + + if (p < D_MINIMUM_TRANSPORT_PRIORITY) { + p = D_MINIMUM_TRANSPORT_PRIORITY; + } + if (p > D_MAXIMUM_TRANSPORT_PRIORITY) { + p = D_MAXIMUM_TRANSPORT_PRIORITY; + } + config->alignerTransportPriority = p; +} + +void +d_configurationSetMajorityVotingThreshold( + d_configuration config, + c_ulong threshold) +{ + c_ulong p; + + p = threshold; + + if (p < D_MINIMUM_MAJORITY_VOTING_THRESHOLD) { + p = D_MINIMUM_MAJORITY_VOTING_THRESHOLD; + } + if (p > D_MAXIMUM_MAJORITY_VOTING_THRESHOLD) { + p = D_MAXIMUM_MAJORITY_VOTING_THRESHOLD; + } + config->majorityVotingThreshold = p; +} + + +void +d_configurationSetInitialRequestCombinePeriod( + d_configuration config, + c_float seconds) +{ + c_float sec; + + sec = seconds; + + if (sec < D_MINIMUM_INITIAL_REQUEST_COMBINE_PERIOD) { + sec = D_MINIMUM_INITIAL_REQUEST_COMBINE_PERIOD; + } + if (sec > D_MAXIMUM_INITIAL_REQUEST_COMBINE_PERIOD) { + sec = D_MAXIMUM_INITIAL_REQUEST_COMBINE_PERIOD; + } + d_configurationSetDuration(&(config->initialRequestCombinePeriod), sec); +} + +void +d_configurationSetOperationalRequestCombinePeriod( + d_configuration config, + c_float seconds) +{ + c_float sec; + + sec = seconds; + + if (sec < D_MINIMUM_OPERATIONAL_REQUEST_COMBINE_PERIOD) { + sec = D_MINIMUM_OPERATIONAL_REQUEST_COMBINE_PERIOD; + } + if (sec > D_MAXIMUM_OPERATIONAL_REQUEST_COMBINE_PERIOD) { + sec = D_MAXIMUM_OPERATIONAL_REQUEST_COMBINE_PERIOD; + } + d_configurationSetDuration(&(config->operationalRequestCombinePeriod), sec); +} + +void +d_configurationSetNetworkWaitForAttachmentMaxWaitCount( + d_configuration config, + c_ulong maxWaits ) +{ + config->networkMaxWaitCount = maxWaits; + + if (config->networkMaxWaitCount < D_MINIMUM_NETWORK_MAX_WAITCOUNT) { + config->networkMaxWaitCount = D_MINIMUM_NETWORK_MAX_WAITCOUNT; + } + if (config->networkMaxWaitCount > D_MAXIMUM_NETWORK_MAX_WAITCOUNT) { + config->networkMaxWaitCount = D_MAXIMUM_NETWORK_MAX_WAITCOUNT; + } + /* Set the maxWaitTime */ + config->networkMaxWaitTime = os_realToDuration((c_float)config->networkMaxWaitCount * 0.1f /* 100 ms */); +} + +void +d_configurationSetNetworkWaitForAttachment( + d_configuration config, + u_cfElement elementParent, + const c_char* attachName, + const c_char* service) +{ + c_iter attachIter, iter; + u_cfElement element; + u_cfData data; + c_ulong maxWaitCount; + c_bool success; + c_char* serviceName; + + attachIter = u_cfElementXPath(elementParent, attachName); + element = u_cfElement(c_iterTakeFirst(attachIter)); + + if(element){ + success = u_cfElementAttributeULongValue(element, "maxWaitCount", &maxWaitCount); + + if(success){ + d_configurationSetNetworkWaitForAttachmentMaxWaitCount(config, maxWaitCount); + } + iter = u_cfElementXPath(element, service); + data = u_cfData(c_iterTakeFirst(iter)); + + while(data) { + success = u_cfDataStringValue(data, &serviceName); + + if (success == TRUE) { + d_tableInsert(config->networkServiceNames, serviceName); + config->services = c_iterInsert(config->services, os_strdup(serviceName)); + } + u_cfDataFree(data); + data = u_cfData(c_iterTakeFirst(iter)); + } + c_iterFree(iter); + u_cfElementFree(element); + + element = u_cfElement(c_iterTakeFirst(attachIter)); + + while(element){ + u_cfElementFree(element); + element = u_cfElement(c_iterTakeFirst(attachIter)); + } + } + c_iterFree(attachIter); +} + +/** + * \brief Set client durability according to the ClientDurability[@enabled] + * attribute in the configuration. + */ +void +d_configurationSetClientDurabilityEnabled( + d_configuration config, + const c_bool enabled) +{ + config->clientDurabilityEnabled = enabled; +} + +void +d_configurationSetPublisherName( + d_configuration config, + const c_char * publisherName) +{ + if (config) { + if (publisherName != NULL) { + if (config->publisherName) { + d_free(config->publisherName); + config->publisherName = NULL; + } + config->publisherName = os_strdup(publisherName); + } + } +} + +void +d_configurationSetSubscriberName( + d_configuration config, + const c_char * subscriberName) +{ + if (config) { + if (subscriberName != NULL) { + if(config->subscriberName) { + d_free(config->subscriberName); + config->subscriberName = NULL; + } + config->subscriberName = os_strdup(subscriberName); + } + } +} + +void +d_configurationSetPartitionName( + d_configuration config, + const c_char * partitionName) +{ + if (config) { + if (partitionName != NULL) { + if (config->partitionName) { + d_free(config->partitionName); + config->partitionName = NULL; + } + config->partitionName = os_strdup(partitionName); + } + } +} + + +void +d_configurationSetClientDurabilityPartitionName( + d_configuration config, + const c_char * partitionName) +{ + if (config) { + if (partitionName != NULL) { + if (config->clientDurabilityPartitionName) { + d_free(config->clientDurabilityPartitionName); + } + config->clientDurabilityPartitionName = os_strdup(partitionName); + } + } +} + +void +d_configurationSetClientDurabilityPublisherName( + d_configuration config, + const c_char * publisherName) +{ + if (config) { + if (publisherName != NULL) { + if (config->clientDurabilityPublisherName) { + d_free(config->clientDurabilityPublisherName); + } + config->clientDurabilityPublisherName = os_strdup(publisherName); + } + } +} + + +void +d_configurationSetClientDurabilitySubscriberName( + d_configuration config, + const c_char * subscriberName) +{ + if (config) { + if (subscriberName != NULL) { + if (config->clientDurabilitySubscriberName) { + d_free(config->clientDurabilitySubscriberName); + } + config->clientDurabilitySubscriberName = os_strdup(subscriberName); + } + } +} + + +void +d_configurationSetTracingSynchronous( + d_configuration config, + const c_bool synchronous) +{ + config->tracingSynchronous = synchronous; +} + +void +d_configurationSetTracingOutputFile( + d_configuration config, + const c_char* value) +{ + if(value){ + if(config->tracingOutputFileName){ + if( (os_strcasecmp(config->tracingOutputFileName, "stdout") != 0) && + (os_strcasecmp(config->tracingOutputFileName, "stderr") != 0)) + { + if(config->tracingOutputFile){ + fclose(config->tracingOutputFile); + config->tracingOutputFile = NULL; + } + } + os_free(config->tracingOutputFileName); + config->tracingOutputFileName = NULL; + } + + + if (os_strcasecmp(value, "stdout") == 0) { + config->tracingOutputFileName = os_strdup("stdout"); + config->tracingOutputFile = stdout; /* default */ + } else if (os_strcasecmp(value, "stderr") == 0) { + config->tracingOutputFileName = os_strdup("stderr"); + config->tracingOutputFile = stderr; + } else { + char *filename; + if (os_strcasecmp(value, "") == 0) { + OS_REPORT(OS_WARNING, D_CONTEXT, 0, + "OutputFile configuration-parameter is empty, using default value \"" D_DEFAULT_TRACING_OUTFILE "\""); + filename = os_fileNormalize(D_DEFAULT_TRACING_OUTFILE); + } else { + filename = os_fileNormalize(value); + } + + if (filename) { + config->tracingOutputFile = fopen(filename, "a"); + if (!config->tracingOutputFile) { + const os_char *msg = os_getErrno() ? os_strError(os_getErrno()) : NULL; + OS_REPORT(OS_ERROR, D_CONTEXT, 0, + "Failed to open tracing OutputFile \"%s\": %s", + filename, msg ? msg : "Unknown reason"); + } + config->tracingOutputFileName = os_strdup(filename); + os_free(filename); + } + } + } +} + +void +d_configurationSetTracingTimestamps( + d_configuration config, + c_bool useTimestamp) +{ + if (config) { + config->tracingTimestamps = useTimestamp; + } +} + +void +d_configurationSetTimeAlignment( + d_configuration config, + c_bool alignment) +{ + if (config) { + config->timeAlignment = alignment; + } +} + +void +d_configurationSetTimeToWaitForAligner( + d_configuration config, + c_float seconds) +{ + c_float sec; + + sec = seconds; + + if (sec < D_MINIMUM_TIME_TO_WAIT_FOR_ALIGNER) { + sec = D_MINIMUM_TIME_TO_WAIT_FOR_ALIGNER; + } + if (sec > D_MAXIMUM_TIME_TO_WAIT_FOR_ALIGNER) { + sec = D_MAXIMUM_TIME_TO_WAIT_FOR_ALIGNER; + } + /* The only allowed supported values at the moment are + * D_MINIMUM_TIME_TO_WAIT_FOR_ALIGNER (0), or the default + * D_MAXIMUM_TIME_TO_WAIT_FOR_ALIGNER (maxfloat). + * Any specified value > D_MINIMUM_TIME_TO_WAIT_FOR_ALIGNER + * will for the moment be mapped to D_MAXIMUM_TIME_TO_WAIT_FOR_ALIGNER + * and a warning is generated. + * + * The support for more values is identified as a future extension. + */ + if (sec > D_MINIMUM_TIME_TO_WAIT_FOR_ALIGNER) { + sec = D_MAXIMUM_TIME_TO_WAIT_FOR_ALIGNER; + } + /* generate a warning if necessary */ + if ( (seconds != D_MINIMUM_TIME_TO_WAIT_FOR_ALIGNER) && + (seconds != D_MAXIMUM_TIME_TO_WAIT_FOR_ALIGNER) ) { + OS_REPORT(OS_WARNING, D_CONTEXT, 0, + "TimeToWaitForAligner currently only supports 0.0 and 1.0 (infinite), using 1.0 for now"); + } + d_configurationSetDuration(&(config->timeToWaitForAligner), sec); +} + +void +d_configurationSetTracingRelativeTimestamps( + d_configuration config, + u_cfElement element, + const c_char* timestampsPath, + const c_char* absoluteName) +{ + u_cfElement timestampsElement; + c_iter elements; + c_bool success, absolute; + + elements = u_cfElementXPath(element, timestampsPath); + + if(elements){ + timestampsElement = u_cfElement(c_iterTakeFirst(elements)); + + while(timestampsElement){ + success = u_cfElementAttributeBoolValue(timestampsElement, absoluteName, &absolute); + + if(success == TRUE){ + config->tracingRelativeTimestamps = (!absolute); + } + u_cfElementFree(timestampsElement); + timestampsElement = u_cfElement(c_iterTakeFirst(elements)); + } + c_iterFree(elements); + } +} + +void +d_configurationSetTracingVerbosity( + d_configuration config, + const c_char* value) +{ + if(value){ + if(os_strcasecmp(value, "SEVERE") == 0){ + config->tracingVerbosityLevel = D_LEVEL_SEVERE; + } else if(os_strcasecmp(value, "WARNING") == 0){ + config->tracingVerbosityLevel = D_LEVEL_WARNING; + } else if(os_strcasecmp(value, "INFO") == 0){ + config->tracingVerbosityLevel = D_LEVEL_INFO; + } else if(os_strcasecmp(value, "CONFIG") == 0){ + config->tracingVerbosityLevel = D_LEVEL_CONFIG; + } else if(os_strcasecmp(value, "FINE") == 0){ + config->tracingVerbosityLevel = D_LEVEL_FINE; + } else if(os_strcasecmp(value, "FINER") == 0){ + config->tracingVerbosityLevel = D_LEVEL_FINER; + } else if(os_strcasecmp(value, "FINEST") == 0){ + config->tracingVerbosityLevel = D_LEVEL_FINEST; + } else if(os_strcasecmp(value, "NONE") == 0){ + config->tracingVerbosityLevel = D_LEVEL_NONE; + } + } +} + +void +d_configurationSetPersistentStoreDirectory( + d_configuration config, + const c_char* storePath) +{ + if(config){ + if(config->persistentStoreDirectory != NULL){ + os_free(config->persistentStoreDirectory); + } + config->persistentStoreDirectory = os_fileNormalize(storePath); + } +} + +void +d_configurationSetPersistentStoreMode( + d_configuration config, + const c_char * storeModeName) +{ + if (config) { + if (storeModeName != NULL) { + if(os_strcasecmp(storeModeName, "XML") == 0){ + config->persistentStoreMode = D_STORE_TYPE_XML; + } else if(os_strcasecmp(storeModeName, "KV") == 0 || os_strncasecmp(storeModeName, "KV:", 3) == 0){ + config->persistentStoreMode = D_STORE_TYPE_KV; + } else { + config->persistentStoreMode = D_STORE_TYPE_XML; + } + } + } +} + +void +d_configurationSetPersistentKVStorageParameters ( + d_configuration config, + const c_char * parameters) +{ + if (config) { + if (parameters != NULL) { + if(config->persistentKVStoreStorageParameters) { + d_free(config->persistentKVStoreStorageParameters); + config->persistentKVStoreStorageParameters = NULL; + } + config->persistentKVStoreStorageParameters = os_strdup(parameters); + } + } +} + +void +d_configurationResolvePersistentKVConfig ( + d_configuration config, + u_cfElement elementParent, + const c_char *elementName) +{ + c_iter iter; + u_cfElement element; + c_char *value; + c_bool found; + + iter = u_cfElementXPath(elementParent, elementName); + element = (u_cfElement)c_iterTakeFirst(iter); + + while (element) { + found = u_cfElementAttributeStringValue(element, "type", &value); + if (found) { + if (config->persistentKVStoreStorageType) { + os_free(config->persistentKVStoreStorageType); + } + config->persistentKVStoreStorageType = value; + } + d_configurationValueString (config, element, "StorageParameters/#text", d_configurationSetPersistentKVStorageParameters); + + d_configurationResolvePersistentKVCompression (config, element, "Compression"); + u_cfElementFree(element); + element = (u_cfElement)c_iterTakeFirst(iter); + } + c_iterFree(iter); +} + +void +d_configurationResolvePersistentKVCompression ( + d_configuration config, + u_cfElement elementParent, + const c_char *elementName) +{ + c_iter iter; + u_cfElement element; + c_char *algorithm; + c_bool enabled; + + iter = u_cfElementXPath(elementParent, elementName); + element = (u_cfElement)c_iterTakeFirst(iter); + + if (element) { + /* If the compression element is defined compression should be enabled unless + * the optional enabled field is set to false. + */ + d_configurationSetPersistentKVCompressionEnabled(config, TRUE); + } + + while (element) { + if (u_cfElementAttributeStringValue(element, "algorithm", &algorithm)) { + d_configurationSetPersistentKVCompressionAlgorithm(config, algorithm); + } + if (u_cfElementAttributeBoolValue(element, "enabled", &enabled)) { + d_configurationSetPersistentKVCompressionEnabled(config, enabled); + } + u_cfElementFree(element); + element = (u_cfElement)c_iterTakeFirst(iter); + } + + if ((config->persistentKVStoreCompressionEnabled == TRUE) && + (config->persistentKVStoreCompressionAlgorithm == D_COMPRESSION_LZF)) { + /* LZF compression requires a big stackSize to operate, make sure it + * has at least 1MB + */ + if (config->persistentStoreStackSize < 1048576) { + config->persistentStoreStackSize = 1048576; + } + d_configurationSetPersistentSchedulingStackSize(config, config->persistentStoreStackSize); + } + + c_iterFree(iter); +} + +void +d_configurationSetPersistentKVCompressionEnabled ( + d_configuration config, + c_bool enabled) +{ + config->persistentKVStoreCompressionEnabled = enabled; +} + +void +d_configurationSetPersistentKVCompressionAlgorithm ( + d_configuration config, + const c_char *algorithm) +{ + assert(algorithm); + + if (os_strcasecmp(algorithm, "LZF") == 0) { + config->persistentKVStoreCompressionAlgorithm = D_COMPRESSION_LZF; + } else if (os_strcasecmp(algorithm, "SNAPPY") == 0) { + config->persistentKVStoreCompressionAlgorithm = D_COMPRESSION_SNAPPY; + } else if (os_strcasecmp(algorithm, "ZLIB") == 0) { + config->persistentKVStoreCompressionAlgorithm = D_COMPRESSION_ZLIB; + } else if (os_strcasecmp(algorithm, "CUSTOM") == 0) { + config->persistentKVStoreCompressionAlgorithm = D_COMPRESSION_CUSTOM; + } else { + config->persistentKVStoreCompressionAlgorithm = D_COMPRESSION_NONE; + OS_REPORT(OS_WARNING, OS_FUNCTION, 0, + "Invalid Persistent/KeyValueStore/Compression[@algorithm] selected, compression disabled"); + } +} + +void +d_configurationSetPersistentStoreSleepTime( + d_configuration config, + c_float seconds) +{ + c_float sec; + + sec = seconds; + + if (sec < D_MINIMUM_PERSISTENT_STORE_SLEEP_TIME) { + sec = D_MINIMUM_PERSISTENT_STORE_SLEEP_TIME; + } + if (sec > D_MAXIMUM_PERSISTENT_STORE_SLEEP_TIME) { + sec = D_MAXIMUM_PERSISTENT_STORE_SLEEP_TIME; + } + d_configurationSetDuration(&(config->persistentStoreSleepTime), sec); +} + +void +d_configurationSetPersistentStoreSessionTime( + d_configuration config, + c_float seconds) +{ + c_float sec; + + sec = seconds; + + if (sec < D_MINIMUM_PERSISTENT_STORE_SESSION_TIME) { + sec = D_MINIMUM_PERSISTENT_STORE_SESSION_TIME; + } + if (sec > D_MAXIMUM_PERSISTENT_STORE_SESSION_TIME) { + sec = D_MAXIMUM_PERSISTENT_STORE_SESSION_TIME; + } + d_configurationSetDuration(&(config->persistentStoreSessionTime), sec); +} + +void +d_configurationSetPersistentQueueSize( + d_configuration config, + c_ulong size) +{ + config->persistentQueueSize = size; + + if (config->persistentQueueSize > D_MAXIMUM_PERSISTENT_QUEUE_SIZE) { + config->persistentQueueSize = D_MAXIMUM_PERSISTENT_QUEUE_SIZE; + } +} + +void +d_configurationSetOptimizeUpdateInterval( + d_configuration config, + c_ulong size) +{ + config->persistentUpdateInterval = size; + + if ((config->persistentUpdateInterval < D_MINIMUM_OPTIMIZE_INTERVAL) && (config->persistentUpdateInterval != 0)) { + config->persistentUpdateInterval = D_MINIMUM_OPTIMIZE_INTERVAL; + } + if (config->persistentUpdateInterval > D_MAXIMUM_OPTIMIZE_INTERVAL) { + config->persistentUpdateInterval = D_MAXIMUM_OPTIMIZE_INTERVAL; + } +} + + +void +d_configurationSetDuration( + os_duration *duration, + c_float seconds) +{ + *duration = os_realToDuration((os_timeReal)seconds); +} + +int +d_configurationResolvePartition( + d_nameSpace nameSpace, + u_cfElement element, + c_char* name, + const c_char* tag, + const c_char* topic) +{ + c_iter iter, iter2; + u_cfElement partitionElement; + u_cfNode data; + c_ulong size; + c_bool found; + c_char* partition; + int result; + result = 0; + + iter = u_cfElementXPath(element, tag); + partitionElement = u_cfElement(c_iterTakeFirst(iter)); + + while(partitionElement){ + iter2 = u_cfElementGetChildren(partitionElement); + size = c_iterLength(iter2); + + if(size != 0){ + data = u_cfNode(c_iterTakeFirst(iter2)); + + if(u_cfNodeKind(data) == V_CFDATA){ + found = u_cfDataStringValue(u_cfData(data), &partition); + + if (found == TRUE) { + result = d_nameSpaceAddElement(nameSpace, name, partition, topic); + os_free(partition); + } + } + u_cfNodeFree(data); + } else { + result = d_nameSpaceAddElement(nameSpace, name, "", topic); + } + c_iterFree(iter2); + u_cfElementFree(partitionElement); + partitionElement = u_cfElement(c_iterTakeFirst(iter)); + } + c_iterFree(iter); + + return result; +} + +int +d_configurationResolvePartitionTopic( + d_nameSpace nameSpace, + u_cfElement element, + c_char* name, + const c_char* tag) +{ + c_iter iter, iter2; + u_cfElement partitionElement; + u_cfNode data; + c_ulong size; + c_bool found; + c_char* partitionTopic; + int result; + result = 0; + + iter = u_cfElementXPath(element, tag); + partitionElement = u_cfElement(c_iterTakeFirst(iter)); + + while(partitionElement){ + iter2 = u_cfElementGetChildren(partitionElement); + size = c_iterLength(iter2); + + if(size != 0){ + data = u_cfNode(c_iterTakeFirst(iter2)); + + if(u_cfNodeKind(data) == V_CFDATA){ + found = u_cfDataStringValue(u_cfData(data), &partitionTopic); + if (found == TRUE) { + result = d_nameSpaceAddElement(nameSpace, name, partitionTopic, NULL); + os_free(partitionTopic); + } + } + u_cfNodeFree(data); + } else { + result = d_nameSpaceAddElement(nameSpace, name, "*.*", NULL); + } + c_iterFree(iter2); + u_cfElementFree(partitionElement); + partitionElement = u_cfElement(c_iterTakeFirst(iter)); + } + c_iterFree(iter); + + return result; +} + + +void +d_configurationAttrValueLong( + d_configuration configuration, + u_cfElement element, + const char * tag, + const char * attr, + void (* const setAction)(d_configuration config, c_long longValue) ) +{ + c_iter iter; + u_cfElement e; + u_cfAttribute a; + c_long longValue; + c_bool found; + + iter = u_cfElementXPath(element, tag); + e = u_cfElement(c_iterTakeFirst(iter)); + + while (e != NULL) { + a = u_cfElementAttribute(e, attr); + + if(a){ + found = u_cfAttributeLongValue(a, &longValue); + /* QAC EXPECT 2100; */ + if (found == TRUE) { + setAction(configuration, longValue); + } + u_cfAttributeFree(a); + } + u_cfElementFree(e); + e = u_cfElement(c_iterTakeFirst(iter)); + } + c_iterFree(iter); +} + +void +d_configurationAttrValueULong( + d_configuration configuration, + u_cfElement element, + const char * tag, + const char * attr, + void (* const setAction)(d_configuration config, c_ulong longValue) ) +{ + c_iter iter; + u_cfElement e; + u_cfAttribute a; + c_ulong ulongValue; + c_bool found; + + iter = u_cfElementXPath(element, tag); + e = u_cfElement(c_iterTakeFirst(iter)); + + while (e != NULL) { + a = u_cfElementAttribute(e, attr); + + if(a){ + found = u_cfAttributeULongValue(a, &ulongValue); + /* QAC EXPECT 2100; */ + if (found == TRUE) { + setAction(configuration, ulongValue); + } + u_cfAttributeFree(a); + } + u_cfElementFree(e); + e = u_cfElement(c_iterTakeFirst(iter)); + } + c_iterFree(iter); +} + +void +d_configurationAttrValueFloat( + d_configuration configuration, + u_cfElement element, + const char * tag, + const char * attr, + void (* const setAction)(d_configuration config, c_float floatValue) ) +{ + c_iter iter; + u_cfElement e; + u_cfAttribute a; + c_float floatValue; + c_bool found; + + iter = u_cfElementXPath(element, tag); + e = u_cfElement(c_iterTakeFirst(iter)); + + while (e != NULL) { + a = u_cfElementAttribute(e, attr); + + if(a){ + found = u_cfAttributeFloatValue(a, &floatValue); + /* QAC EXPECT 2100; */ + if (found == TRUE) { + setAction(configuration, floatValue); + } + u_cfAttributeFree(a); + } + u_cfElementFree(e); + e = u_cfElement(c_iterTakeFirst(iter)); + } + c_iterFree(iter); +} + +void +d_configurationAttrValueBoolean( + d_configuration configuration, + u_cfElement element, + const char * tag, + const char * attr, + void (* const setAction)(d_configuration config, c_bool boolValue) ) +{ + c_iter iter; + u_cfElement e; + u_cfAttribute a; + c_bool boolValue, found; + + iter = u_cfElementXPath(element, tag); + e = u_cfElement(c_iterTakeFirst(iter)); + + while (e != NULL) { + a = u_cfElementAttribute(e, attr); + + if(a){ + found = u_cfAttributeBoolValue(a, &boolValue); + /* QAC EXPECT 2100; */ + if (found == TRUE) { + setAction(configuration, boolValue); + } + u_cfAttributeFree(a); + } + u_cfElementFree(e); + e = u_cfElement(c_iterTakeFirst(iter)); + } + c_iterFree(iter); +} + +void +d_configurationValueLong( + d_configuration configuration, + u_cfElement element, + const char * tag, + void (* const setAction)(d_configuration config, c_long longValue) ) +{ + c_iter iter; + u_cfData data; + c_long longValue; + c_bool found; + + iter = u_cfElementXPath(element, tag); + data = u_cfData(c_iterTakeFirst(iter)); + + while (data != NULL) { + found = u_cfDataLongValue(data, &longValue); + /* QAC EXPECT 2100; */ + if (found == TRUE) { + setAction(configuration, longValue); + } + u_cfDataFree(data); + data = u_cfData(c_iterTakeFirst(iter)); + } + c_iterFree(iter); +} + +void +d_configurationValueULong( + d_configuration configuration, + u_cfElement element, + const char * tag, + void (* const setAction)(d_configuration config, c_ulong longValue) ) +{ + c_iter iter; + u_cfData data; + c_long longValue; + c_ulong ulongValue; + c_bool found; + + iter = u_cfElementXPath(element, tag); + data = u_cfData(c_iterTakeFirst(iter)); + while (data != NULL) { + found = u_cfDataLongValue(data, &longValue); + /* QAC EXPECT 2100; */ + if (found == TRUE) { + if (longValue < 0) { + longValue = -longValue; + if (longValue < 0) { + longValue++; + longValue = -longValue; + } + } + ulongValue = (c_ulong)longValue; + setAction(configuration, ulongValue); + } + u_cfDataFree(data); + data = u_cfData(c_iterTakeFirst(iter)); + } + c_iterFree(iter); +} + +void +d_configurationValueSize( + d_configuration configuration, + u_cfElement element, + const char *tag, + void (* const setAction)(d_configuration config, c_size size)) +{ + c_iter iter; + u_cfData data; + u_size size; + c_bool found; + + iter = u_cfElementXPath(element, tag); + data = u_cfData(c_iterTakeFirst(iter)); + while (data != NULL) { + found = u_cfDataSizeValue(data, &size); + /* QAC EXPECT 2100; */ + if (found == TRUE) { + setAction(configuration, size); + } + u_cfDataFree(data); + data = u_cfData(c_iterTakeFirst(iter)); + } + c_iterFree(iter); +} + +void +d_configurationValueMemAddr( + d_configuration configuration, + u_cfElement element, + const char * tag, + void (* const setAction)(d_configuration config, c_address addr) ) +{ + c_iter iter; + u_cfData data; + c_bool found; + c_char * str; + c_address addr; + + iter = u_cfElementXPath(element, tag); + data = u_cfData(c_iterTakeFirst(iter)); + + while (data) { + found = u_cfDataStringValue(data, &str); + if (found == TRUE) { + if ( (strlen(str) > 2) && + (strncmp("0x", str, 2) == 0) ) { + sscanf(str, "0x" PA_ADDRFMT, &addr); + } else { + sscanf(str, PA_ADDRFMT, &addr); + } + setAction(configuration, addr); + os_free(str); + } + u_cfDataFree(data); + data = u_cfData(c_iterTakeFirst(iter)); + } + c_iterFree(iter); +} + +void +d_configurationValueFloat( + d_configuration configuration, + u_cfElement element, + const c_char * tag, + void (* const setAction)(d_configuration config, c_float floatValue) ) +{ + c_iter iter; + u_cfData data; + c_bool found; + c_float floatValue; + + iter = u_cfElementXPath(element, tag); + data = u_cfData(c_iterTakeFirst(iter)); + + while (data != NULL) { + found = u_cfDataFloatValue(data, &floatValue); + + if (found == TRUE) { + setAction(configuration, floatValue); + } + u_cfDataFree(data); + data = u_cfData(c_iterTakeFirst(iter)); + } + c_iterFree(iter); +} + + +void +d_configurationValueBoolean( + d_configuration configuration, + u_cfElement element, + const char * tag, + void (* const setAction)(d_configuration config, c_bool str) ) +{ + c_iter iter; + u_cfData data; + c_bool found; + c_bool b; + + iter = u_cfElementXPath(element, tag); + data = u_cfData(c_iterTakeFirst(iter)); + + while (data) { + found = u_cfDataBoolValue(data, &b); + /* QAC EXPECT 2100; */ + if (found == TRUE) { + setAction(configuration, b); + } + u_cfDataFree(data); + data = u_cfData(c_iterTakeFirst(iter)); + } + c_iterFree(iter); +} + +void +d_configurationValueString( + d_configuration configuration, + u_cfElement element, + const char * tag, + void (* const setAction)(d_configuration config, const c_char * str) ) +{ + c_iter iter; + u_cfData data; + c_bool found; + c_char * str; + + iter = u_cfElementXPath(element, tag); + data = u_cfData(c_iterTakeFirst(iter)); + + while (data) { + found = u_cfDataStringValue(data, &str); + /* QAC EXPECT 2100; */ + if (found == TRUE) { + setAction(configuration, str); + os_free(str); + } + u_cfDataFree(data); + data = u_cfData(c_iterTakeFirst(iter)); + } + c_iterFree(iter); +} + +c_bool +d_configurationInNameSpace( + d_nameSpace ns, + d_partition partition, + d_topic topic, + c_bool aligner) +{ + c_bool result; + result = FALSE; + + if(d_nameSpaceIsIn(ns, partition, topic) == TRUE){ + if(aligner == TRUE) { + if(d_nameSpaceIsAligner(ns) == TRUE){ + result = TRUE; + } + } else { + result = TRUE; + } + } + + return result; +} + +void +d_configurationResolveMergePolicies( + d_policy policy, + u_cfElement elementParent, + const c_char * mergePolicyName) +{ + c_iter iter; + u_cfElement element; + c_bool found; + c_string mergeType_str, scope; + d_mergePolicy mergeType; + + mergeType = D_MERGE_IGNORE; + iter = u_cfElementXPath(elementParent, mergePolicyName); + + element = (u_cfElement)c_iterTakeFirst(iter); + + while (element) + { + found = u_cfElementAttributeStringValue (element, "type", &mergeType_str); + if (found){ + if (os_strcasecmp (mergeType_str, "IGNORE") == 0){ + mergeType = D_MERGE_IGNORE; + }else if (os_strcasecmp (mergeType_str, "MERGE") == 0){ + mergeType = D_MERGE_MERGE; + }else if (os_strcasecmp (mergeType_str, "DELETE") == 0){ + mergeType = D_MERGE_DELETE; + }else if (os_strcasecmp (mergeType_str, "REPLACE") == 0){ + mergeType = D_MERGE_REPLACE; + }else if (os_strcasecmp (mergeType_str, "CATCHUP") == 0){ + mergeType = D_MERGE_CATCHUP; + } + os_free (mergeType_str); + } + + scope = NULL; + found = u_cfElementAttributeStringValue (element, "scope", &scope); + + /* Role should always be available */ + assert (found && scope != NULL); + + /* Add merge policy to role */ + d_policyAddMergeRule (policy, mergeType, scope); + + os_free (scope); + + u_cfElementFree(element); + element = (u_cfElement)c_iterTakeFirst(iter); + } + + c_iterFree (iter); +} + +c_iter +d_configurationResolvePolicies( + u_cfElement elementParent, + const c_char * policyName ) +{ + c_iter iter, result; + u_cfElement element; + c_char * durabilityKind; + c_char * aligner; + c_char * delayedAlignment; + c_char * alignmentKind; + c_char * namespace; + c_bool found; + d_policy policy; + c_bool isAligner; + c_bool delayAlignmentEnabled; + d_alignmentKind akind; + d_durabilityKind dkind; + c_ulong length; + c_bool equalityCheck; + c_long longMasterPriority; + c_ulong masterPriority; + + result = c_iterNew(NULL); + iter = u_cfElementXPath(elementParent, policyName); + element = c_iterTakeFirst(iter); + + while (element) { + + /* Parse durability kind element */ + found = u_cfElementAttributeStringValue(element, "durability", &durabilityKind); + if(found){ + if(os_strcasecmp(durabilityKind, "TRANSIENT") == 0){ + dkind = D_DURABILITY_TRANSIENT; + } else if(os_strcasecmp(durabilityKind, "TRANSIENT_LOCAL") == 0){ + dkind = D_DURABILITY_TRANSIENT_LOCAL; + } else if(os_strcasecmp(durabilityKind, "PERSISTENT") == 0){ + dkind = D_DURABILITY_PERSISTENT; + } else { + dkind = D_DURABILITY_ALL; + } + os_free(durabilityKind); + } else { + dkind = D_DURABILITY_ALL; + } + + /* Parse aligner element */ + found = u_cfElementAttributeStringValue(element, "aligner", &aligner); + if (found){ + if (os_strcasecmp(aligner, "TRUE") == 0){ + isAligner = TRUE; + }else { + isAligner = FALSE; + } + os_free(aligner); + }else + { + isAligner = TRUE; + } + + /* Parse aligner element */ + found = u_cfElementAttributeStringValue(element, "delayedAlignment", &delayedAlignment); + if (found){ + if (os_strcasecmp(delayedAlignment, "TRUE") == 0){ + delayAlignmentEnabled = TRUE; + }else { + delayAlignmentEnabled = FALSE; + } + os_free(delayedAlignment); + }else + { + delayAlignmentEnabled = FALSE; + } + + /* Parse alignment kind element */ + found = u_cfElementAttributeStringValue(element, "alignee", &alignmentKind); + if(found){ + if(os_strcasecmp(alignmentKind, "ON_REQUEST") == 0){ + akind = D_ALIGNEE_ON_REQUEST; + } else if(os_strcasecmp(alignmentKind, "INITIAL") == 0){ + akind = D_ALIGNEE_INITIAL; + } else if(os_strcasecmp(alignmentKind, "LAZY") == 0){ + akind = D_ALIGNEE_LAZY; + } else { + akind = D_ALIGNEE_INITIAL; + } + os_free(alignmentKind); + } else { + akind = D_ALIGNEE_INITIAL; + } + + /* Parse namespace element */ + found = u_cfElementAttributeStringValue(element, "nameSpace", &namespace); + if(!found){ + + /* TODO: Shouldn't this be moved to the code which checks the + * empty namespace (backwards compatibility) + */ + length = c_iterLength(result); + namespace = os_malloc(17); + os_sprintf(namespace, "NoName%u", length); + } + + /* Parse equalityCheck atribute */ + found = u_cfElementAttributeBoolValue(element, "equalityCheck", &equalityCheck); + if (!found) { + equalityCheck = D_DEFAULT_EQUALITY_CHECK; + } + + found = u_cfElementAttributeLongValue(element, "masterPriority", &longMasterPriority); + if (!found) { + masterPriority = D_DEFAULT_MASTER_PRIORITY; + } else { + if (longMasterPriority < D_MINIMUM_MASTER_PRIORITY) { + OS_REPORT(OS_WARNING, D_CONTEXT, 0, + "Configuration //OpenSplice/DurabilityService/NameSpaces/Policy[@masterPriority] " + "value(%d) less then minimum supported value(%d) using minimum.", + longMasterPriority, D_MINIMUM_MASTER_PRIORITY); + masterPriority = D_MINIMUM_MASTER_PRIORITY; + } else if (longMasterPriority > D_MAXIMUM_MASTER_PRIORITY) { + OS_REPORT(OS_WARNING, D_CONTEXT, 0, + "Configuration //OpenSplice/DurabilityService/NameSpaces/Policy[@masterPriority] " + "value(%d) greater then maximum supported value(%d) using maximum.", + longMasterPriority, D_MAXIMUM_MASTER_PRIORITY); + masterPriority = D_MAXIMUM_MASTER_PRIORITY; + } else { + masterPriority = (c_ulong)longMasterPriority; + } + + if (isAligner == FALSE) { + /* When policy has aligner set to false the masterPriority is not relevant */ + OS_REPORT(OS_WARNING, D_CONTEXT, 0, + "Configuration set with no effect on //OpenSplice/DurabilityService/NameSpaces/Policy. " + "When [@aligner] is set to \'false\' [@masterPriority] has no effect."); + } + } + + /* Create new policy */ + policy = d_policyNew (namespace, isAligner, akind, delayAlignmentEnabled, + dkind, equalityCheck, masterPriority); + os_free(namespace); + + /* Resolve merge policies */ + d_configurationResolveMergePolicies(policy, element, "Merge"); + + /* Insert policy in result */ + result = c_iterInsert(result, policy); + + u_cfElementFree(element); + element = (u_cfElement)c_iterTakeFirst(iter); + } + c_iterFree(iter); + + return result; +} + +static c_bool +resolveNameSpaceDeprecated ( + u_cfElement element, + d_durabilityKind* durabilityKind_out, + d_alignmentKind* alignmentKind_out, + c_bool* isAligner_out) +{ + c_bool useDeprecated; + c_bool isAligner; + d_alignmentKind akind; + d_durabilityKind dkind; + c_char * durabilityKind; + c_char * alignmentKind; + c_bool found; + + useDeprecated = FALSE; + isAligner = FALSE; + + /* Parse durability kind element */ + found = u_cfElementAttributeStringValue(element, "durabilityKind", &durabilityKind); + if(found){ + useDeprecated = TRUE; + + if(os_strcasecmp(durabilityKind, "TRANSIENT") == 0){ + dkind = D_DURABILITY_TRANSIENT; + } else if(os_strcasecmp(durabilityKind, "TRANSIENT_LOCAL") == 0){ + dkind = D_DURABILITY_TRANSIENT_LOCAL; + } else if(os_strcasecmp(durabilityKind, "PERSISTENT") == 0){ + dkind = D_DURABILITY_PERSISTENT; + } else { + dkind = D_DURABILITY_ALL; + } + os_free(durabilityKind); + } else { + dkind = D_DURABILITY_ALL; + } + + /* Parse alignment kind element */ + found = u_cfElementAttributeStringValue(element, "alignmentKind", &alignmentKind); + if(found){ + useDeprecated = TRUE; + + if(os_strcasecmp(alignmentKind, "ON_REQUEST") == 0){ + akind = D_ALIGNEE_ON_REQUEST; + } else if(os_strcasecmp(alignmentKind, "INITIAL") == 0){ + akind = D_ALIGNEE_INITIAL; + } else if (os_strcasecmp(alignmentKind, "INITIAL_AND_ALIGNER") == 0){ + akind = D_ALIGNEE_INITIAL; + isAligner = TRUE; + } else if(os_strcasecmp(alignmentKind, "LAZY") == 0){ + akind = D_ALIGNEE_LAZY; + } else { + akind = D_ALIGNEE_INITIAL; + } + os_free(alignmentKind); + } else { + akind = D_ALIGNEE_INITIAL; + } + + *durabilityKind_out = dkind; + *alignmentKind_out = akind; + *isAligner_out = isAligner; + + return useDeprecated; +} + +c_iter +d_configurationResolveNameSpaces( + d_configuration config, + u_cfElement elementParent, + const c_char * nameSpaceName, + int * resolveResult) +{ + c_iter iter, result; + u_cfElement element; + c_char * name; + c_bool found; + d_nameSpace ns; + c_ulong length; + c_bool noError; + d_policy policy; + /* For deprecated configuration */ + c_bool isAligner; + d_alignmentKind akind; + d_durabilityKind dkind; + c_bool useDeprecated; + + *resolveResult = 0; + + result = c_iterNew(NULL); + iter = u_cfElementXPath(elementParent, nameSpaceName); + element = c_iterTakeFirst(iter); + useDeprecated = FALSE; + akind = D_ALIGNEE_INITIAL; + dkind = D_DURABILITY_ALL; + isAligner = TRUE; + noError = TRUE; + + while (element && noError) { + useDeprecated = + useDeprecated || resolveNameSpaceDeprecated ( + element, + &dkind, + &akind, + &isAligner); + + /* Parse name element */ + found = u_cfElementAttributeStringValue(element, "name", &name); + if(!found){ + length = c_iterLength(result); + name = os_malloc(17); + os_sprintf(name, "NoName%u", length); + useDeprecated = TRUE; + } + + /* If deprecated, create namespace with private policy */ + if (useDeprecated) { + policy = d_policyNew(name, isAligner, akind, FALSE, dkind, D_DEFAULT_EQUALITY_CHECK, D_DEFAULT_MASTER_PRIORITY); + } else { + policy = d_configurationFindPolicyForNameSpace(config, name); + } + ns = d_nameSpaceNew(name, policy); + + d_policyFree(policy); + os_free(name); + + if (ns) { + *resolveResult = d_configurationResolvePartition(ns, element, "NoName", "Partition", "*"); + if (*resolveResult == 0) { + *resolveResult = d_configurationResolvePartitionTopic(ns, element, "NoName", "PartitionTopic"); + } + if (*resolveResult == 0) { + result = c_iterInsert(result, ns); + } else { + d_nameSpaceFree(ns); + OS_REPORT(OS_ERROR, D_CONTEXT, 0, "Topic in //OpenSplice/DurabilityService/NameSpaces/NameSpace/PartitionTopic of config file cannot be blank. The notation is 'partition.topic'"); + c_iterFree(result); + result = NULL; + noError = FALSE; + } + } else { + ns = d_nameSpace(c_iterTakeFirst(result)); + + while(ns){ + d_nameSpaceFree(ns); + ns = d_nameSpace(c_iterTakeFirst(result)); + } + c_iterFree(result); + result = NULL; + noError = FALSE; + } + u_cfElementFree(element); + + if(noError){ + element = (u_cfElement)c_iterTakeFirst(iter); + } + } + /* Not all elements may have been taken from iter and freed in previous + * loop. Ensuring clean-up here. + */ + element = (u_cfElement)c_iterTakeFirst(iter); + + while(element){ + u_cfElementFree(element); + element = (u_cfElement)c_iterTakeFirst(iter); + } + c_iterFree(iter); + + return result; +} + + +c_iter +d_configurationResolveFilters( + d_configuration config, + u_cfElement elementParent, + const c_char *filterElement, + d_durability durability) +{ + c_iter iter, result; + u_cfElement element; + c_bool noError = TRUE; + c_char *xmlExpression = NULL; + c_bool found; + d_filter filter; + + OS_UNUSED_ARG(config); + + result = c_iterNew(NULL); + iter = u_cfElementXPath(elementParent, filterElement); + element = (u_cfElement)c_iterTakeFirst(iter); + while (element && noError) { + /* Parse filter expression attribute */ + xmlExpression = NULL; + found = u_cfElementAttributeStringValue(element, "content", &xmlExpression); + if (!found) { + /* A filter without any content attribute is detected. + * We use a strict parsing regime and consider a filter + * without any content expression as an error. + */ + OS_REPORT(OS_WARNING, D_CONTEXT, 0, + "Missing 'content' attribute of -element in the configuration, ignoring this filter"); + } else if (strlen(xmlExpression )== 0) { + /* This is the empty string, print a warning and ignore */ + OS_REPORT(OS_WARNING, D_CONTEXT, 0, + "The 'content' attribute of -element in the configuration resolves to the empty string, ignoring this filter"); + } else { + /* The filter expression has a valid syntax. + * Create a filter and add the and + * child elements + */ + filter = d_filterNew(xmlExpression); + if (filter) { + if (d_configurationResolveFilterPartitionTopic(filter, element, "NoName", "PartitionTopic") == 0) { + OS_REPORT(OS_WARNING, D_CONTEXT, 0, + "The -element with content attribute '%s' has no matching , ignoring this filter", xmlExpression); + d_filterFree(filter); + } else { + result = c_iterAppend(result, filter); + } + } else { + OS_REPORT(OS_ERROR, D_CONTEXT, 0, + "Failed to create a filter for -expression with content '%s', remove all filters and terminate", xmlExpression); + noError = FALSE; + } + } + if (noError) { + element = (u_cfElement)c_iterTakeFirst(iter); + } + } /* while */ + if (noError == FALSE) { + if (iter) { + /* Clean up cfElements */ + element = (u_cfElement)c_iterTakeFirst(iter); + while (element) { + u_cfElementFree(element); + element = (u_cfElement)c_iterTakeFirst(iter); + } + c_iterFree(iter); + iter = NULL; + } + if (result) { + /* Clean up filters */ + filter = d_filter(c_iterTakeFirst(result)); + while (filter) { + d_filterFree(filter); + filter = d_filter(c_iterTakeFirst(result)); + } + c_iterFree(result); + result = NULL; + } + /* Terminate durability */ + d_durabilityTerminate(durability, TRUE); + } + c_iterFree(iter); + + return result; +} + + + +/** + * \brief Parse the -fields in a -expression + * + * @return the number of successfully parsed expressions, or -1 in case of error + */ +int +d_configurationResolveFilterPartitionTopic( + d_filter filter, + u_cfElement elementParent, + const c_char *name, + const c_char *tag) +{ + c_iter iter, iter2; + u_cfElement partitionTopicElement; + char *partitionTopic; + c_bool found; + u_cfNode data; + int i = 0; + + assert(d_filterIsValid(filter)); + + /* Currently only support */ + iter = u_cfElementXPath(elementParent, tag); + partitionTopicElement = u_cfElement(c_iterTakeFirst(iter)); + while (partitionTopicElement) { + iter2 = u_cfElementGetChildren(partitionTopicElement); + if (c_iterLength(iter2) != 0) { + data = u_cfNode(c_iterTakeFirst(iter2)); + if (u_cfNodeKind(data) == V_CFDATA) { + found = u_cfDataStringValue(u_cfData(data), &partitionTopic); + if (found == TRUE) { + if (d_filterAddElement(filter, name, partitionTopic, NULL)) { + i++; + } + os_free(partitionTopic); + } + } + u_cfNodeFree(data); + } + c_iterFree(iter2); + u_cfElementFree(partitionTopicElement); + partitionTopicElement = u_cfElement(c_iterTakeFirst(iter)); + } /* while */ + c_iterFree(iter); + return i; +} + + +c_iter +d_configurationResolveDurablePolicies( + u_cfElement elementParent, + const c_char * policy) +{ + c_iter iter, result; + u_cfElement element; + c_bool found; + c_bool isCache = FALSE; + c_char *obtain; + c_char *cache; + struct durablePolicy *dp; + + result = c_iterNew(NULL); + iter = u_cfElementXPath(elementParent, policy); + element = (u_cfElement)c_iterTakeFirst(iter); + while (element) { + /* Parse obtain attribute */ + found = u_cfElementAttributeStringValue(element, "obtain", &obtain); + if (!found) { + OS_REPORT(OS_WARNING, D_CONTEXT, 0, + "Missing 'obtain' attribute of //Opensplice/Domain/durablePolicies/Policy-element in the configuration, ignoring this setting"); + } else { + /* Parse cache attribute */ + found = u_cfElementAttributeStringValue(element, "cache", &cache); + if (found){ + isCache = (os_strcasecmp(cache, "TRUE") == 0) ? TRUE : FALSE; + os_free(cache); + } else { + isCache = D_DEFAULT_DURABLE_POLICY_CACHE; + } + /* Add to durablePolicy struct */ + dp = (struct durablePolicy *)os_malloc(sizeof(struct durablePolicy)); + dp->obtain = os_strdup(obtain); + dp->cache = isCache; + result = c_iterAppend(result, dp); + os_free(obtain); + } + u_cfElementFree(element); + element = (u_cfElement)c_iterTakeFirst(iter); + } /* while */ + c_iterFree(iter); + return result; +} + +/** + * \brief Find the first matching policy for the given namespace + * + * @return first matching policy, or NULL if not found + */ +d_policy +d_configurationFindPolicyForNameSpace( + d_configuration config, + const char * nameSpaceName) +{ + d_policy policy = NULL; + c_iterIter iter; + + iter = c_iterIterGet(config->policies); + while ((policy = (d_policy)c_iterNext(&iter)) != NULL) { + if (d_patternMatch(nameSpaceName, policy->nameSpace)) { + policy = d_policy(d_objectKeep(d_object(policy))); + break; + } + } + return policy; +} diff --git a/src/services/durability/code/d_conflict.c b/src/services/durability/code/d_conflict.c new file mode 100644 index 000000000..bba9ea9fd --- /dev/null +++ b/src/services/durability/code/d_conflict.c @@ -0,0 +1,177 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "d__conflict.h" +#include "d__nameSpace.h" +#include "d__nameSpace.h" +#include "d__durability.h" +#include "d_object.h" +#include "os_time.h" +#include "os_heap.h" +#include "os_abstract.h" + +d_conflict +d_conflictNew( + c_ulong conflictEvent, + d_networkAddress fellowAddr, + d_nameSpace nameSpaceCopy, + d_nameSpace fellowNameSpaceCopy) +{ + d_conflict conflict = NULL; + + /* Create conflict object */ + conflict = d_conflict(os_malloc(C_SIZEOF(d_conflict))); + if (conflict) { + /* Call super-init */ + d_lockInit(d_lock(conflict), D_CONFLICT, d_conflictDeinit); + /* Initialize conflict */ + conflict->event = conflictEvent; + conflict->reQueueCount = 0; + conflict->id = 0; /* Initially 0, will be set to the real id when the conflict is added to the resolverQueue. */ + conflict->nr = 0; + conflict->fellowAddr = (fellowAddr == NULL) ? NULL : d_networkAddressNew(fellowAddr->systemId, fellowAddr->localId, fellowAddr->lifecycleId); + conflict->creationTime = os_timeMGet(); + conflict->lastQueueTime = OS_TIMEM_INIT(0,0); /* Initially no conflicts queued. */ + conflict->nameSpaceCopy = (nameSpaceCopy == NULL) ? NULL : d_nameSpace(d_objectKeep(d_object(nameSpaceCopy))); /* copy of the namespace at the time the conflict was determined */ + conflict->fellowNameSpaceCopy = (fellowNameSpaceCopy == NULL) ? NULL : d_nameSpace(d_objectKeep(d_object(fellowNameSpaceCopy))); /* copy of the fellow namespace at the time the conflict was determined. */ + /* Create the list of foreign state conflicts */ + conflict->foreign_stateConflicts = d_nameSpaceGetMergedStatesDiff(conflict->nameSpaceCopy, conflict->fellowNameSpaceCopy); + /* Verify that the nameSpaceCopy must be set if the fellowNameSpaceCopy is set */ + assert((conflict->fellowNameSpaceCopy == NULL) || (conflict->nameSpaceCopy != NULL)); + } + return conflict; +} + + +void +d_conflictDeinit( + d_object object) +{ + d_conflict conflict; + + assert(d_objectIsValid(object, D_CONFLICT) == TRUE); + + if (object) { + conflict = d_conflict(object); + + if (conflict->fellowAddr) { + d_networkAddressFree(conflict->fellowAddr); + } + + if (conflict->nameSpaceCopy) { + d_nameSpaceFree(conflict->nameSpaceCopy); + } + + if (conflict->fellowNameSpaceCopy) { + d_nameSpaceFree(conflict->fellowNameSpaceCopy); + } + + if (conflict->foreign_stateConflicts) { + c_iterFree(conflict->foreign_stateConflicts); + } + } +} + + +void d_conflictFree( + d_conflict conflict) +{ + assert(d_conflictIsValid(conflict)); + + d_objectFree(d_object(conflict)); + +} + + +/** + * \brief Assign a unique id to the conflict. + * + * The id of the conflict is a monotonically increased number starting + * with 1, and every new id is increased by 1. + * + * The id is unique modulo 0xFFFFFFFF, after which a conflict id is + * wrapped around to 1. + */ +c_ulong +d_conflictSetId( + d_conflict conflict, + d_durability durability) +{ + assert(d_conflictIsValid(conflict)); + assert(d_durabilityIsValid(durability)); + + conflict->id = d_durabilityGenerateConflictId(durability); + + return conflict->id; +} + + +c_ulong +d_conflictGetId( + d_conflict conflict) +{ + assert(d_conflictIsValid(conflict)); + + return conflict->id; +} + + +os_timeM +d_conflictGetCreationTime( + d_conflict conflict) +{ + assert(d_conflictIsValid(conflict)); + + return conflict->creationTime; +} + + +void +d_conflictUpdate( + d_conflict conflict, + d_nameSpace nameSpaceCopy, + d_nameSpace fellowNameSpaceCopy) +{ + assert(d_conflictIsValid(conflict)); + + d_lockLock(d_lock(conflict)); + /* Update the nameSpaceCopy and fellowNameSpaceCopy and foreign_stateConflicts fields */ + if (conflict->nameSpaceCopy) { + d_nameSpaceFree(conflict->nameSpaceCopy); + } + conflict->nameSpaceCopy = (nameSpaceCopy == NULL) ? NULL : d_nameSpace(d_objectKeep(d_object(nameSpaceCopy))); + if (conflict->fellowNameSpaceCopy) { + d_nameSpaceFree(conflict->fellowNameSpaceCopy); + } + conflict->fellowNameSpaceCopy = (fellowNameSpaceCopy == NULL) ? NULL : d_nameSpace(d_objectKeep(d_object(fellowNameSpaceCopy))); + c_iterFree(conflict->foreign_stateConflicts); + conflict->foreign_stateConflicts = d_nameSpaceGetMergedStatesDiff(conflict->nameSpaceCopy, conflict->fellowNameSpaceCopy); + d_lockUnlock(d_lock(conflict)); +} + +void +d_conflictUpdateQueueTime( + d_conflict conflict) +{ + assert(d_conflictIsValid(conflict)); + + d_lockLock(d_lock(conflict)); + conflict->lastQueueTime = os_timeMGet(); /* update the last queue time */ + ++(conflict->reQueueCount); /* update the number of times the conflict is queued */ + d_lockUnlock(d_lock(conflict)); +} diff --git a/src/services/durability/code/d_conflictMonitor.c b/src/services/durability/code/d_conflictMonitor.c new file mode 100644 index 000000000..1dcc3e4d4 --- /dev/null +++ b/src/services/durability/code/d_conflictMonitor.c @@ -0,0 +1,986 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "d__conflictMonitor.h" +#include "d__conflict.h" +#include "d__nameSpace.h" +#include "d__policy.h" +#include "d__thread.h" +#include "d__admin.h" +#include "d__durability.h" +#include "d__fellow.h" +#include "d__conflictResolver.h" +#include "d__mergeState.h" +#include "d__subscriber.h" +#include "d__nameSpacesRequestListener.h" +#include "d__configuration.h" +#include "d__table.h" +#include "d__durability.h" +#include "d__admin.h" +#include "d__nameSpace.h" +#include "d__fellow.h" +#include "d__misc.h" +#include "d_networkAddress.h" +#include "d_object.h" +#include "os_time.h" +#include "os_heap.h" + + +d_conflictMonitor +d_conflictMonitorNew( + d_admin admin) +{ + d_conflictMonitor conflictMonitor = NULL; + + /* Create conflictMonitor object */ + conflictMonitor = d_conflictMonitor(os_malloc(C_SIZEOF(d_conflictMonitor))); + if (conflictMonitor) { + /* Call super-init */ + d_lockInit(d_lock(conflictMonitor), D_CONFLICT_MONITOR, (d_objectDeinitFunc)d_conflictMonitorDeinit); + /* Initialize conflictMonitor */ + conflictMonitor->admin = admin; + conflictMonitor->lastTimeChecked = OS_TIMEM_ZERO; + } + return conflictMonitor; +} + + +void +d_conflictMonitorDeinit( + d_conflictMonitor conflictMonitor) +{ + assert(d_conflictMonitorIsValid(conflictMonitor)); + + /* Call super-deinit */ + d_lockDeinit(d_lock(conflictMonitor)); +} + + +void d_conflictMonitorFree( + d_conflictMonitor conflictMonitor) +{ + assert(d_conflictMonitorIsValid(conflictMonitor)); + + d_objectFree(d_object(conflictMonitor)); +} + +static void traceNetworkAddress (d_durability dur, const char *label, d_networkAddress a) +{ + d_printTimedEvent (dur, D_LEVEL_FINEST, "%s {%u,%u,%u}\n", label, a->systemId, a->localId, a->lifecycleId); +} + +static void traceFellow (d_durability dur, const char *label, d_fellow f) +{ + d_printTimedEvent (dur, D_LEVEL_FINEST, "%s %p {%u,%u,%u} state %d commstate %d role %s isConfirmed %d hasConfirmed %d \n", label, f, f->address->systemId, f->address->localId, f->address->lifecycleId, (int)f->state, (int)f->communicationState, f->role, f->isConfirmed, f->hasConfirmed); +} + +static void traceNameSpace (d_durability dur, const char *label, d_nameSpace ns) +{ + struct d_policy_s dpst; + struct d_networkAddress_s mst; + d_policy dp = ns->policy ? ns->policy : &dpst; + d_networkAddress m = ns->master ? ns->master : &mst; + memset (&dpst, 0, sizeof (dpst)); + memset (&mst, 0, sizeof (mst)); + d_printTimedEvent (dur, D_LEVEL_FINEST, + "%s %p %s [policy %s %d %d %d %d] mergeState (%s,%d) master {%u,%u,%u} st %d conf %d alignable %d\n", + label, ns, ns->name ? ns->name : "(null)", dp->nameSpace ? dp->nameSpace : "(null)", + (int)dp->aligner, (int)dp->alignmentKind, (int)dp->delayedAlignment, (int)dp->durabilityKind, + ns->mergeState->role, ns->mergeState->value, m->systemId, m->localId, m->lifecycleId, + (int)ns->masterState, (int)ns->masterConfirmed, (int)ns->alignable); +} + +static void traceConflict (d_durability dur, const char *label, d_conflict c) +{ + d_printTimedEvent (dur, D_LEVEL_FINEST, "%s %p id %u event %u requeuecnt %u fellowAddr {%u,%u,%u} nameSpaceCopy %p fellowNameSpaceCopy %p\n", label, c, c->id, c->event, c->reQueueCount, c->fellowAddr->systemId, c->fellowAddr->localId, c->fellowAddr->lifecycleId, (void*)c->nameSpaceCopy, (void*)c->fellowNameSpaceCopy); + if (c->nameSpaceCopy) { + traceNameSpace (dur, "conflict nameSpaceCopy", c->nameSpaceCopy); + } +} + +/** + * \brief Verify if there is a master conflict between the namespace and the fellowNameSpace. + * + * @return TRUE if there is a master conflict, FALSE otherwise. + */ +static c_bool +d_conflictMonitorHasMasterConflict( + d_conflictMonitor conflictMonitor, + d_networkAddress fellowAddr, + d_nameSpace nameSpaceCopy, + d_nameSpace fellowNameSpaceCopy) +{ + d_networkAddress masterAddr, fellowMasterAddr, unAddressed; + d_durability durability; + d_admin admin; + d_fellow fellow; + d_serviceState myState, fellowState; + c_bool result = FALSE; + + assert(d_conflictMonitorIsValid(conflictMonitor)); + + admin = conflictMonitor->admin; + durability = d_adminGetDurability(admin); + myState = d_durabilityGetState(durability); + unAddressed = d_networkAddressUnaddressed(); + + /* Get the (confirmed) fellow with the fellowAddr */ + fellow = d_adminGetFellow(admin, fellowAddr); + if (fellow) { + d_lockLock(d_lock(fellow)); + traceFellow (durability, "HasMasterConflict fellow", fellow); + fellowState = d_fellowGetState(fellow); + if ( (fellowState != D_STATE_TERMINATING) && (fellowState != D_STATE_TERMINATED) ) { + masterAddr = d_nameSpaceGetMaster(nameSpaceCopy); + fellowMasterAddr = d_nameSpaceGetMaster(fellowNameSpaceCopy); + + traceNetworkAddress (durability, "masterAddr", masterAddr); + traceNetworkAddress (durability, "fellowMasterAddr", fellowMasterAddr); + d_printTimedEvent (durability, D_LEVEL_FINEST, "myState %u fellowState %u\n", myState, fellowState); + + /* Only check for conflicts if I'm complete and fellow is past injecting persistent data. */ + if ( ( (myState >= D_STATE_DISCOVER_PERSISTENT_SOURCE) && (fellowState >= D_STATE_INJECT_PERSISTENT) ) ) { + + /* A master conflict is detected when a fellow that has a + * different master than me, and my master is confirmed. + * + * Note that this criterion will result in a master + * conflict when there is no aligner (master:0, confirmed: 1) + * and suddenly an aligner appears that becomes master. + * + * Also note that we do NOT require that the master of the + * fellow is confirmed! This is to ensure that master + * selection is triggered with a fellow that may been master + * a little while before, but has recently unconfirmed its + * mastership because it may be involved in master selection + * with another node. */ + d_printTimedEvent (durability, D_LEVEL_FINEST, + "myrole %s fellowrole %s isMasterConfirmed %d\n", + nameSpaceCopy->mergeState->role, fellowNameSpaceCopy->mergeState->role, + d_nameSpaceIsMasterConfirmed(nameSpaceCopy)); + + result = ( (strcmp(nameSpaceCopy->mergeState->role, fellowNameSpaceCopy->mergeState->role) == 0) && /* my role equals fellow role */ + (d_networkAddressCompare(masterAddr, fellowMasterAddr) != 0) && /* fellow has a different master than me */ + (d_nameSpaceIsMasterConfirmed(nameSpaceCopy)) ); /* my master is confirmed */ + + d_printTimedEvent (durability, D_LEVEL_FINEST, "-=- hasMasterConflict evaluates to %d\n", result); + + + } else { + d_printTimedEvent (durability, D_LEVEL_FINEST, + "-=- state progress mimatch prior to master checking: " \ + "myState=%d, fellowState=%d (%d,%d)\n", myState, fellowState, (myState >= D_STATE_DISCOVER_PERSISTENT_SOURCE), (fellowState >= D_STATE_INJECT_PERSISTENT)); + } + d_networkAddressFree(fellowMasterAddr); + d_networkAddressFree(masterAddr); + + } else { + d_printTimedEvent (durability, D_LEVEL_FINEST, "-=- fellow state: %d\n", fellowState); + } + d_lockUnlock(d_lock(fellow)); + d_fellowFree(fellow); + } else { + d_printTimedEvent (durability, D_LEVEL_FINEST, "-=- fellow with address %u not found\n", fellowAddr->systemId); + } + d_networkAddressFree(unAddressed); + d_printTimedEvent (durability, D_LEVEL_FINER, "HasMasterConflict returns %d\n", (int)result); + return result; +} + + +/** + * \brief Verify if there is a native state conflict between the namespace and the fellowNameSpace. + * + * @return TRUE if there is a native state conflict, FALSE otherwise. + */ +static c_bool +d_conflictMonitorHasNativeStateConflict( + d_conflictMonitor conflictMonitor, + d_networkAddress fellowAddr, + d_nameSpace nameSpaceCopy, + d_nameSpace fellowNameSpaceCopy) +{ + d_networkAddress masterAddr, fellowMasterAddr; + d_durability durability; + d_admin admin; + d_fellow fellow; + d_serviceState myState, fellowState; + d_configuration config; + c_bool result = FALSE; + d_mergeState myMergeState, fellowMergeState; + + assert(d_conflictMonitorIsValid(conflictMonitor)); + + admin = conflictMonitor->admin; + durability = d_adminGetDurability(admin); + myState = d_durabilityGetState(durability); + config = d_durabilityGetConfiguration(durability); + + /* Get the confirmed fellow with the fellowAddr */ + fellow = d_adminGetFellow(admin, fellowAddr); + if (fellow) { + d_lockLock(d_lock(fellow)); + fellowState = d_fellowGetState(fellow); + if ( (fellowState != D_STATE_TERMINATING) && (fellowState != D_STATE_TERMINATED) ) { + masterAddr = d_nameSpaceGetMaster(nameSpaceCopy); + fellowMasterAddr = d_nameSpaceGetMaster(fellowNameSpaceCopy); + /* Only check for conflicts if I'm complete and fellow is past injecting persistent data. */ + if ( ( (myState >= D_STATE_DISCOVER_PERSISTENT_SOURCE) && (fellowState >= D_STATE_INJECT_PERSISTENT) ) ) { + + myMergeState = d_nameSpaceGetMergeState(nameSpaceCopy, config->role); + fellowMergeState = d_nameSpaceGetMergeState(fellowNameSpaceCopy, fellow->role); + /* A native state conflict occurs if the fellow and myself + * have the same role and the fellow is a confirmed + * master for the namespace, but the fellow has advertised + * a higher namespace state than I am aware of. In that case + * I need to request data from my master in order to update + * my namespace state. + * + * There is no need to require that my master is confirmed. + * In fact, doing so might lead to the situation that the + * fellow send its new confirmed namespace state while I + * still have not confirmed the fellow. As a consequence + * no native state conflict would be detected until the + * fellow re-sends it namespace state and I have confirmed + * that the fellow is master. To prevent this we do not + * require that I have confirmed the fellow as master. */ + + result = ( (d_networkAddressCompare(masterAddr, fellowAddr) == 0) && /* fellow is my master for the namespace */ + (d_networkAddressCompare(fellowMasterAddr, fellowAddr) == 0) && /* the fellow's master is the fellow itself */ + (d_nameSpaceIsMasterConfirmed(fellowNameSpaceCopy)) && /* the fellow's master is confirmed */ + (strcmp(config->role, fellow->role) == 0) && /* fellow has the same role as me */ + (d_mergeStateRoleValueCompare(myMergeState, fellowMergeState) == -1) ); /* fellow has a higher native merge state than me */ + + d_mergeStateFree(myMergeState); + d_mergeStateFree(fellowMergeState); + } + d_networkAddressFree(fellowMasterAddr); + d_networkAddressFree(masterAddr); + } + d_lockUnlock(d_lock(fellow)); + d_fellowFree(fellow); + } + return result; +} + + +/** + * \brief Verify if there is a foreign state conflict between the namespace and the fellowNameSpace. + * + * @return TRUE if there is a foreign state conflict, FALSE otherwise. + */ +static c_bool +d_conflictMonitorHasForeignStateConflict( + d_conflictMonitor conflictMonitor, + d_networkAddress fellowAddr, + d_nameSpace nameSpaceCopy, + d_nameSpace fellowNameSpaceCopy) +{ + d_networkAddress masterAddr, fellowMasterAddr, myAddr; + d_durability durability; + d_admin admin; + d_fellow fellow; + d_serviceState myState, fellowState; + d_configuration config; + d_mergeState mergeState, fellowMergeState; + c_bool result = FALSE; + + assert(d_conflictMonitorIsValid(conflictMonitor)); + + admin = conflictMonitor->admin; + durability = d_adminGetDurability(admin); + myState = d_durabilityGetState(durability); + config = d_durabilityGetConfiguration(durability); + myAddr = d_adminGetMyAddress(admin); + + /* Get the confirmed fellow with the fellowAddr */ + fellow = d_adminGetFellow(admin, fellowAddr); + if (fellow) { + d_lockLock(d_lock(fellow)); + fellowState = d_fellowGetState(fellow); + if ( (fellowState != D_STATE_TERMINATING) && (fellowState != D_STATE_TERMINATED) ) { + masterAddr = d_nameSpaceGetMaster(nameSpaceCopy); + fellowMasterAddr = d_nameSpaceGetMaster(fellowNameSpaceCopy); + /* Only check for conflicts if I'm complete and fellow is past injecting persistent data. */ + if ( ( (myState >= D_STATE_DISCOVER_PERSISTENT_SOURCE) && (fellowState >= D_STATE_INJECT_PERSISTENT) ) ) { + + /* A foreign state conflict occurs if I am master confirmed + * master for the namespace in my own role, the fellow is + * confirmed master for the namespace in a different role, + * and the native state of the namespace as advertised by the + * fellow differs from my knowledge of the namespace state + * in the fellow's role. */ + + result = ( (d_networkAddressCompare(masterAddr, myAddr) == 0) && /* I am master for the namespace */ + (d_nameSpaceIsMasterConfirmed(nameSpaceCopy)) && /* I have a confirmed master */ + (d_networkAddressCompare(fellowMasterAddr, fellowAddr) == 0) && /* the fellow is also master for the namespace */ + (d_nameSpaceIsMasterConfirmed(fellowNameSpaceCopy)) && /* the fellow master is confirmed */ + (strcmp(config->role, fellow->role) != 0) ); /* fellow has a different role than me */ + + if (result) { + /* Now check if my mergeState for the namespace in the fellow's role + * differs from the one advertised by the fellow. */ + mergeState = d_nameSpaceGetMergeState(nameSpaceCopy, fellow->role); + fellowMergeState = d_nameSpaceGetMergeState(fellowNameSpaceCopy, fellow->role); + if ( (mergeState != NULL) && (fellowMergeState != NULL) ) { + result = (mergeState->value < fellowMergeState->value); /* Fellow merge state is higher than my merge state */ + } else { + /* Only foreign conflict if the fellow has a real merge state + * and I have not. */ + result = (fellowMergeState != NULL); + } + d_mergeStateFree(mergeState); + d_mergeStateFree(fellowMergeState); + } + } + d_networkAddressFree(fellowMasterAddr); + d_networkAddressFree(masterAddr); + } + d_lockUnlock(d_lock(fellow)); + d_fellowFree(fellow); + } + d_networkAddressFree(myAddr); + + return result; +} + + +static c_bool +d_conflictMonitorHasFellowDisconnectedConflict( + d_conflictMonitor conflictMonitor, + d_networkAddress fellowAddr) +{ + d_durability durability; + d_admin admin; + d_fellow fellow; + d_serviceState myState, fellowState; + c_bool result = FALSE; + + assert(d_conflictMonitorIsValid(conflictMonitor)); + + admin = conflictMonitor->admin; + durability = d_adminGetDurability(admin); + myState = d_durabilityGetState(durability); + fellow = d_adminGetFellow(admin, fellowAddr); + if (fellow) { + d_lockLock(d_lock(fellow)); + fellowState = d_fellowGetState(fellow); + if ( (fellowState != D_STATE_TERMINATING) && (fellowState != D_STATE_TERMINATED) && + (myState != D_STATE_TERMINATING) && (myState != D_STATE_TERMINATED) ) { + + /* A fellow disconnect conflict has occurred if a fellow has been disconnected + * from me. */ + result = TRUE; + + } + d_lockUnlock(d_lock(fellow)); + d_fellowFree(fellow); + } + return result; +} + + +static c_bool +d_conflictMonitorHasFellowConnectedConflict( + d_conflictMonitor conflictMonitor, + d_networkAddress fellowAddr) +{ + d_durability durability; + d_admin admin; + d_fellow fellow; + d_serviceState myState, fellowState; + c_bool result = FALSE; + + assert(d_conflictMonitorIsValid(conflictMonitor)); + + admin = conflictMonitor->admin; + durability = d_adminGetDurability(admin); + myState = d_durabilityGetState(durability); + fellow = d_adminGetFellow(admin, fellowAddr); + if (fellow) { + d_lockLock(d_lock(fellow)); + fellowState = d_fellowGetState(fellow); + if ( (fellowState != D_STATE_TERMINATING) && (fellowState != D_STATE_TERMINATED) && + (myState != D_STATE_TERMINATING) && (myState != D_STATE_TERMINATED) ) { + + /* A fellow connect conflict has occurred if a new fellow has recently arrived */ + result = fellow->recently_joined; + + } + d_lockUnlock(d_lock(fellow)); + d_fellowFree(fellow); + } + return result; +} + + +static c_bool +d_conflictMonitorHasFederationDisconnectedConflict( + d_conflictMonitor conflictMonitor) +{ + assert(d_conflictMonitorIsValid(conflictMonitor)); + + OS_UNUSED_ARG(conflictMonitor); + + /* Always try to resolve this conflict when it appears */ + return TRUE; +} + +/** + * \brief Verify if a master conflict for the namespace and the fellowNameSpace still exists. + * + * @return TRUE if the master conflict still exists, FALSE otherwise. + */ +static c_bool +d_conflictMonitorMasterConflictStillExists( + d_conflictMonitor conflictMonitor, + d_networkAddress fellowAddr, + d_nameSpace nameSpaceCopy, + d_nameSpace fellowNameSpaceCopy) +{ + d_networkAddress masterAddr, fellowMasterAddr; + d_durability durability; + d_admin admin; + d_fellow fellow; + d_serviceState myState, fellowState; + c_bool result = FALSE; + + assert(d_conflictMonitorIsValid(conflictMonitor)); + + admin = conflictMonitor->admin; + durability = d_adminGetDurability(admin); + myState = d_durabilityGetState(durability); + fellow = d_adminGetFellow(admin, fellowAddr); + if (fellow) { + d_lockLock(d_lock(fellow)); + fellowState = d_fellowGetState(fellow); + if ( (fellowState != D_STATE_TERMINATING) && (fellowState != D_STATE_TERMINATED) ) { + masterAddr = d_nameSpaceGetMaster(nameSpaceCopy); + fellowMasterAddr = d_nameSpaceGetMaster(fellowNameSpaceCopy); + /* Only check for conflicts if I'm complete and fellow is past injecting persistent data. */ + if ( ( (myState >= D_STATE_DISCOVER_PERSISTENT_SOURCE) && (fellowState >= D_STATE_INJECT_PERSISTENT) ) ) { + + /* The master conflict still exists if the nameSpaces and the fellowNameSpace + * do not have the same confirmed master. */ + result = ( ! ( (d_networkAddressCompare(masterAddr, fellowMasterAddr) == 0) && /* fellow has the same master than me */ + (d_nameSpaceIsMasterConfirmed(nameSpaceCopy)) && /* my master is confirmed */ + (d_nameSpaceIsMasterConfirmed(fellowNameSpaceCopy)) ) ); /* the fellow's master is confirmed */ + } + d_networkAddressFree(fellowMasterAddr); + d_networkAddressFree(masterAddr); + } + d_lockUnlock(d_lock(fellow)); + d_fellowFree(fellow); + } else { + /* The fellow left, but because my namespace has been set to unconfirmed + * so I still must determine my master */ + result = TRUE; + } + return result; +} + + +/** + * \brief Verify if the native state conflict for the namespace and the fellowNameSpace still exists. + * + * @return TRUE if the native state conflict still exists, FALSE otherwise. + */ +static c_bool +d_conflictMonitorNativeStateConflictStillExists( + d_conflictMonitor conflictMonitor, + d_networkAddress fellowAddr, + d_nameSpace nameSpaceCopy, + d_nameSpace fellowNameSpaceCopy) +{ + return d_conflictMonitorHasNativeStateConflict(conflictMonitor, fellowAddr, nameSpaceCopy, fellowNameSpaceCopy); +} + + +/** + * \brief Verify if the foreign state conflict between the namespace and the fellowNameSpace still exists. + * + * @return TRUE if the foreign state conflict still exists, FALSE otherwise. + */ +static c_bool +d_conflictMonitorForeignStateConflictStillExists( + d_conflictMonitor conflictMonitor, + d_networkAddress fellowAddr, + d_nameSpace nameSpaceCopy, + d_nameSpace fellowNameSpaceCopy) +{ + return d_conflictMonitorHasForeignStateConflict(conflictMonitor, fellowAddr, nameSpaceCopy, fellowNameSpaceCopy); +} + + + +/** + * \brief Verify if a federation disconnected conflict still exists. + * + * @return TRUE if the federation disconnected conflict still exists, FALSE otherwise. + */ +static c_bool +d_conflictMonitorFederationDisconnectedConflictStillExists( + d_conflictMonitor conflictMonitor) +{ + return d_conflictMonitorHasFederationDisconnectedConflict(conflictMonitor); +} + + + +/** + * \brief Verify if a fellow disconnected conflict still exists. + * + * @return TRUE if the fellow disconnected conflict still exists, FALSE otherwise. + */ +static c_bool +d_conflictMonitorFellowDisconnectedConflictStillExists( + d_conflictMonitor conflictMonitor, + d_networkAddress fellowAddr) +{ + return d_conflictMonitorHasFellowDisconnectedConflict(conflictMonitor, fellowAddr); +} + + +/** + * \brief Verify if a fellow connected conflict still exists. + * + * @return TRUE if the fellow connected conflict still exists, FALSE otherwise. + */ +static c_bool +d_conflictMonitorFellowConnectedConflictStillExists( + d_conflictMonitor conflictMonitor, + d_networkAddress fellowAddr) +{ + return d_conflictMonitorHasFellowConnectedConflict(conflictMonitor, fellowAddr); +} + + +/** + * \brief Check whether I have a conflict with the fellow for the namespace + * + * The namespace provided is the namespace as received from the fellow + * + * @param conflictMonitor This monitor used to check for conflicts + * @param fellow The fellow in conflict + * @param nameSpace The namespace in conflict + */ +void +d_conflictMonitorCheckForConflicts( + d_conflictMonitor conflictMonitor, + d_fellow fellow, + d_nameSpace nameSpace) +{ + d_conflict conflict = NULL; + d_admin admin; + d_durability durability; + d_subscriber subscriber; + d_nameSpacesRequestListener nsrListener; + d_networkAddress fellowAddr, masterAddr, unAddressed; + d_nameSpace fellowNameSpace, nameSpaceCopy, fellowNameSpaceCopy; + c_bool use_legacy; + + assert(d_conflictMonitorIsValid(conflictMonitor)); + + admin = conflictMonitor->admin; + durability = d_adminGetDurability(admin); + subscriber = d_adminGetSubscriber(admin); + nsrListener = d_subscriberGetNameSpacesRequestListener(subscriber); + if (fellow && nameSpace) { + /* We do NOT want to check for conflicts immediately after the fellow + * has joined, because in that case we want the fellow to slave to + * existing masters. Only when the fellow has progressed "far enough" + * we may conclude that a conflict has occurred. We also do not want + * to check for conflicts if I have not progressed far enough. */ + masterAddr = d_nameSpaceGetMaster(nameSpace); + unAddressed = d_networkAddressUnaddressed(); + + traceFellow (durability, "fellow", fellow); + traceNameSpace (durability, "nameSpace", nameSpace); + + if ( ( (d_durabilityGetState(durability) >= D_STATE_INJECT_PERSISTENT) && /* I have progressed far enough */ + (d_fellowGetState(fellow) >= D_STATE_DISCOVER_PERSISTENT_SOURCE) && /* The fellow has progressed far enough */ + (d_fellowIsConfirmed(fellow) ) ) || /* The fellow is confirmed or */ + ( (d_networkAddressCompare(masterAddr, unAddressed) == 0) && /* I have an unaddressed master */ + (d_nameSpaceIsMasterConfirmed(nameSpace)) && /* My master is confirmed */ + (d_fellowIsConfirmed(fellow)) ) ) { /* The fellow is confirmed */ + d_printTimedEvent(durability, D_LEVEL_FINER, + "Checking for conflicts in namespace '%s' with confirmed fellow %u\n", + nameSpace->name, fellow->address->systemId); + d_lockLock(d_lock(conflictMonitor)); + conflictMonitor->lastTimeChecked = os_timeMGet(); + fellowAddr = d_fellowGetAddress(fellow); + /* Get a copy of nameSpace and the corresponding nameSpace for the fellow */ + nameSpaceCopy = d_nameSpaceCopy(nameSpace); + fellowNameSpace = d_fellowGetNameSpace(fellow, nameSpace); + if (fellowNameSpace) { + fellowNameSpaceCopy = d_nameSpaceCopy(fellowNameSpace); + + traceNameSpace (durability, "fellowNameSpaceCopy", fellowNameSpaceCopy); + /* Check for a master conflict. */ + if (d_conflictMonitorHasMasterConflict(conflictMonitor, fellowAddr, nameSpaceCopy, fellowNameSpaceCopy)) { + conflict = d_conflictNew(D_CONFLICT_NAMESPACE_MASTER, fellowAddr, nameSpaceCopy, fellowNameSpaceCopy); + if (!d_conflictResolverConflictExists(admin->conflictResolver, conflict)) { + traceConflict (durability, "new conflict", conflict); + d_conflictSetId(conflict, durability); + use_legacy = IS_LEGACY_MASTER_SELECTION(d_nameSpaceGetMasterPriority(nameSpace)); + d_printTimedEvent(durability, D_LEVEL_FINE, + "Master conflict in namespace '%s' for fellow %u detected, conflict %d created (use_legacy: %d)\n", + nameSpace->name, fellow->address->systemId, conflict->id, use_legacy); + if (use_legacy) { + /* Re-publish my namespaces to let other fellows know that + * there was a conflict, and unconfirm mastership for the + * conflicting namespace in case of the legacy algorithm. + * This prevents that the same conflict + * is generated again. + * TODO: An optimization would be to broadcast the conflicting + * namespace iso all namespaces. */ + d_nameSpacesRequestListenerReportNameSpaces(nsrListener); + d_nameSpaceMasterPending(nameSpace); + } + } else { + traceConflict (durability, "dropping temp conflict: already pending", conflict); + d_conflictFree(conflict); + conflict = NULL; + } + } + + /* Check for a native state conflict */ + else if (d_conflictMonitorHasNativeStateConflict(conflictMonitor, fellowAddr, nameSpaceCopy, fellowNameSpaceCopy)) { + conflict = d_conflictNew(D_CONFLICT_NAMESPACE_NATIVE_STATE, fellowAddr, nameSpaceCopy, fellowNameSpaceCopy); + if (!d_conflictResolverConflictExists(admin->conflictResolver, conflict)) { + d_conflictSetId(conflict, durability); + d_printTimedEvent(durability, D_LEVEL_FINE, + "Native state conflict in namespace '%s' for fellow %u detected, conflict %d created\n", + nameSpace->name, fellow->address->systemId, conflict->id); + } else { + d_conflictFree(conflict); + conflict = NULL; + } + } + + /* Check for a foreign state conflict */ + else if (d_conflictMonitorHasForeignStateConflict(conflictMonitor, fellowAddr, nameSpaceCopy, fellowNameSpaceCopy)) { + conflict = d_conflictNew(D_CONFLICT_NAMESPACE_FOREIGN_STATE, fellowAddr, nameSpaceCopy, fellowNameSpaceCopy); + if (!d_conflictResolverConflictExists(admin->conflictResolver, conflict)) { + d_conflictSetId(conflict, durability); + d_printTimedEvent(durability, D_LEVEL_FINE, + "Foreign state conflict in namespace '%s' for fellow %u detected, conflict %d created\n", + nameSpace->name, fellow->address->systemId, conflict->id); + } else { + d_conflictFree(conflict); + conflict = NULL; + } + } + + /* Add conflict to the conflictResolver */ + if (conflict) { + d_printTimedEvent(durability, D_LEVEL_FINER, + "Adding conflict %d to the conflict resolver queue\n", + conflict->id); + d_conflictResolverAddConflict(admin->conflictResolver, conflict); + } + d_nameSpaceFree(fellowNameSpaceCopy); + } else { + d_printTimedEvent(durability, D_LEVEL_FINEST, "no matching fellow nameSpace\n"); + } + + d_nameSpaceFree(nameSpaceCopy); + d_networkAddressFree(fellowAddr); + d_lockUnlock(d_lock(conflictMonitor)); + } + d_networkAddressFree(unAddressed); + d_networkAddressFree(masterAddr); + } +} + + +void d_conflictMonitorCheckFellowDisconnected( + d_conflictMonitor conflictMonitor, + d_fellow fellow) +{ + d_networkAddress fellowAddr; + d_conflict conflict; + d_admin admin; + d_durability durability; + + assert(d_conflictMonitorIsValid(conflictMonitor)); + assert(d_fellowIsValid(fellow)); + + /* Schedule the conflict. + * When the conflict is about to be resolved we are going to check whether the conditions + * for the conflict apply. */ + fellowAddr = d_fellowGetAddress(fellow); + admin = conflictMonitor->admin; + durability = d_adminGetDurability(admin); + if (d_conflictMonitorHasFellowDisconnectedConflict(conflictMonitor, fellowAddr)) { + conflict = d_conflictNew(D_CONFLICT_FELLOW_DISCONNECTED, fellowAddr, NULL, NULL); + if (!d_conflictResolverConflictExists(admin->conflictResolver, conflict)) { + d_conflictSetId(conflict, durability); + d_printTimedEvent(durability, D_LEVEL_FINE, + "Fellow disconnect conflict for fellow %u detected, conflict %d created\n", + fellow->address->systemId, conflict->id); + + d_printTimedEvent(durability, D_LEVEL_FINER, + "Adding conflict %d to the conflict resolver queue\n", + conflict->id); + + d_conflictResolverAddConflict(admin->conflictResolver, conflict); + } else { + d_conflictFree(conflict); + conflict = NULL; + } + } + d_networkAddressFree(fellowAddr); +} + + +void d_conflictMonitorCheckFellowConnected( + d_conflictMonitor conflictMonitor, + d_fellow fellow) +{ + d_networkAddress fellowAddr; + d_conflict conflict; + d_admin admin; + d_durability durability; + + assert(d_conflictMonitorIsValid(conflictMonitor)); + assert(d_fellowIsValid(fellow)); + + /* Schedule the conflict. + * When the conflict is about to be resolved we are going to check whether the conditions + * for the conflict apply. */ + fellowAddr = d_fellowGetAddress(fellow); + admin = conflictMonitor->admin; + durability = d_adminGetDurability(admin); + + if (d_conflictMonitorHasFellowConnectedConflict(conflictMonitor, fellowAddr)) { + conflict = d_conflictNew(D_CONFLICT_FELLOW_CONNECTED, fellowAddr, NULL, NULL); + if (!d_conflictResolverConflictExists(admin->conflictResolver, conflict)) { + d_conflictSetId(conflict, durability); + d_printTimedEvent(durability, D_LEVEL_FINE, + "Fellow connect conflict for fellow %u detected, conflict %d created\n", + fellow->address->systemId, conflict->id); + + d_printTimedEvent(durability, D_LEVEL_FINER, + "Adding conflict %d to the conflict resolver queue\n", + conflict->id); + + d_conflictResolverAddConflict(admin->conflictResolver, conflict); + } else { + d_conflictFree(conflict); + conflict = NULL; + } + } + d_networkAddressFree(fellowAddr); +} + + +void d_conflictMonitorCheckFederationDisconnected( + d_conflictMonitor conflictMonitor) +{ + d_conflict conflict; + d_admin admin; + d_durability durability; + + assert(d_conflictMonitorIsValid(conflictMonitor)); + + /* Schedule the conflict. + * When the conflict is about to be resolved we are going to check whether the conditions + * for the conflict apply. */ + admin = conflictMonitor->admin; + durability = d_adminGetDurability(admin); + if (d_conflictMonitorHasFederationDisconnectedConflict(conflictMonitor)) { + conflict = d_conflictNew(D_CONFLICT_FEDERATION_DISCONNECTED, NULL, NULL, NULL); + if (!d_conflictResolverConflictExists(admin->conflictResolver, conflict)) { + d_conflictSetId(conflict, durability); + d_printTimedEvent(durability, D_LEVEL_FINE, + "Federation disconnect conflict detected, conflict %d created\n", + conflict->id); + + d_printTimedEvent(durability, D_LEVEL_FINER, + "Adding conflict %d to the conflict resolver queue\n", + conflict->id); + + d_conflictResolverAddConflict(admin->conflictResolver, conflict); + } else { + d_conflictFree(conflict); + conflict = NULL; + } + } +} + + +/** + * \brief Re-evaluate the conflict. + * + * It is checked if the conflict still exists. During conflict evaluation + * the nameSpaceCopy field and fellowNameSpaceCopy field is updated with + * the latest information. + * + * @return The updated conflict if the conflict still exists, or NULL otherwise + */ +d_conflict +d_conflictMonitorEvaluateConflict( + d_conflictMonitor conflictMonitor, + d_conflict conflict) +{ + d_admin admin; + d_durability durability; + d_fellow fellow; + d_nameSpace nameSpace, fellowNameSpace, nameSpaceCopy, fellowNameSpaceCopy; + c_bool updated = FALSE; + c_bool result = TRUE; + + assert(d_conflictMonitorIsValid(conflictMonitor)); + assert(d_conflictIsValid(conflict)); + + admin = conflictMonitor->admin; + durability = d_adminGetDurability(admin); + + if (conflict->fellowAddr == NULL) { + /* The conflict is independent of a fellow. + * This conflict is never discarded and by default updated */ + return conflict; + } + fellow = d_adminGetFellow(admin, conflict->fellowAddr); + if (fellow) { + /* Get a copy of the latest state of my namespace and the fellow's namespace */ + nameSpace = (conflict->nameSpaceCopy == NULL) ? NULL : d_adminGetNameSpace(admin, conflict->nameSpaceCopy->name); + fellowNameSpace = (nameSpace == NULL) ? NULL : d_fellowGetNameSpace(fellow, nameSpace); + nameSpaceCopy = (nameSpace == NULL) ? NULL : d_nameSpaceCopy(nameSpace); + fellowNameSpaceCopy = (fellowNameSpace == NULL) ? NULL : d_nameSpaceCopy(fellowNameSpace); + + if (IS_NAMESPACE_CONFLICT(conflict)) { + /* For namespace related conflicts both copies must exist + * in order to resolve the conflict */ + if (nameSpaceCopy == NULL) { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Could not find a local namespace with name '%s', discarding conflict %d\n", + conflict->nameSpaceCopy->name, conflict->id); + result = FALSE; + } else if (fellowNameSpaceCopy == NULL) { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Could not find namespace '%s' for fellow %u, discarding conflict %d\n", + conflict->nameSpaceCopy->name, conflict->fellowAddr->systemId, conflict->id); + result = FALSE; + } + } + + if (result) { + /* Now check if the conflict still exists */ + d_lockLock(d_lock(conflictMonitor)); + conflictMonitor->lastTimeChecked = os_timeMGet(); + switch (conflict->event) { + case D_CONFLICT_FEDERATION_DISCONNECTED: + if (d_conflictMonitorFederationDisconnectedConflictStillExists(conflictMonitor)) { + d_conflictUpdate(conflict, NULL, NULL); + updated = TRUE; + } + break; + case D_CONFLICT_HEARTBEAT_PROCESSED: + updated = TRUE; + break; + case D_CONFLICT_FELLOW_DISCONNECTED: + if (d_conflictMonitorFellowDisconnectedConflictStillExists(conflictMonitor, conflict->fellowAddr)) { + d_conflictUpdate(conflict, NULL, NULL); + updated = TRUE; + } + break; + case D_CONFLICT_FELLOW_CONNECTED: + if (d_conflictMonitorFellowConnectedConflictStillExists(conflictMonitor, conflict->fellowAddr)) { + d_conflictUpdate(conflict, NULL, NULL); + updated = TRUE; + } + break; + case D_CONFLICT_NAMESPACE_MASTER : + if (d_conflictMonitorMasterConflictStillExists(conflictMonitor, conflict->fellowAddr, nameSpaceCopy, fellowNameSpaceCopy)) { + d_conflictUpdate(conflict, nameSpaceCopy, fellowNameSpaceCopy); + updated = TRUE; + } + break; + case D_CONFLICT_NAMESPACE_NATIVE_STATE : + if (d_conflictMonitorNativeStateConflictStillExists(conflictMonitor, conflict->fellowAddr, nameSpaceCopy, fellowNameSpaceCopy)) { + d_conflictUpdate(conflict, nameSpaceCopy, fellowNameSpaceCopy); + updated = TRUE; + } + break; + case D_CONFLICT_NAMESPACE_FOREIGN_STATE : + if (d_conflictMonitorForeignStateConflictStillExists(conflictMonitor, conflict->fellowAddr, nameSpaceCopy, fellowNameSpaceCopy)) { + d_conflictUpdate(conflict, nameSpaceCopy, fellowNameSpaceCopy); + updated = TRUE; + } + break; + default : + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Invalid conflict event (%d), discarding the conflict\n", conflict->event); + } + d_lockUnlock(d_lock(conflictMonitor)); + } + + if (nameSpaceCopy) { + d_nameSpaceFree(nameSpaceCopy); + } + if (fellowNameSpaceCopy) { + d_nameSpaceFree(fellowNameSpaceCopy); + } + if (nameSpace) { + d_nameSpaceFree(nameSpace); + } + d_fellowFree(fellow); + } else { + /* The fellow does not exist any more. In case of a master conflict I have + * unconfirmed my master, so I must look for a new master anyway */ + + /* Get a copy of the latest state of my namespace and the fellow's namespace */ + nameSpace = (conflict->nameSpaceCopy == NULL) ? NULL : d_adminGetNameSpace(admin, conflict->nameSpaceCopy->name); + nameSpaceCopy = (nameSpace == NULL) ? NULL : d_nameSpaceCopy(nameSpace); + + /* Now check if the conflict still exists */ + d_lockLock(d_lock(conflictMonitor)); + conflictMonitor->lastTimeChecked = os_timeMGet(); + switch (conflict->event) { + case D_CONFLICT_NAMESPACE_MASTER : + if (d_conflictMonitorMasterConflictStillExists(conflictMonitor, conflict->fellowAddr, nameSpaceCopy, NULL)) { + d_conflictUpdate(conflict, nameSpaceCopy, NULL); + updated = TRUE; + } + break; + /* For the following conflicts the disappearing of the fellow is not relevant */ + case D_CONFLICT_FELLOW_DISCONNECTED: + case D_CONFLICT_FELLOW_CONNECTED: + case D_CONFLICT_NAMESPACE_NATIVE_STATE : + case D_CONFLICT_NAMESPACE_FOREIGN_STATE : + break; + case D_CONFLICT_HEARTBEAT_PROCESSED : + updated = TRUE; + break; + default : + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Invalid conflict event (%d), discarding the conflict\n", conflict->event); + } + d_lockUnlock(d_lock(conflictMonitor)); + + if (nameSpaceCopy) { + d_nameSpaceFree(nameSpaceCopy); + } + if (nameSpace) { + d_nameSpaceFree(nameSpace); + } + } + return (updated ? conflict : NULL); +} diff --git a/src/services/durability/code/d_conflictResolver.c b/src/services/durability/code/d_conflictResolver.c new file mode 100644 index 000000000..fd79f2769 --- /dev/null +++ b/src/services/durability/code/d_conflictResolver.c @@ -0,0 +1,1793 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "d__conflictResolver.h" +#include "d__conflictMonitor.h" +#include "d__conflict.h" +#include "d__thread.h" +#include "d__conflict.h" +#include "d__nameSpace.h" +#include "d__groupLocalListener.h" +#include "d__mergeState.h" +#include "d__configuration.h" +#include "d__fellow.h" +#include "d__nameSpace.h" +#include "d__misc.h" +#include "d__groupLocalListener.h" +#include "d__subscriber.h" +#include "d__admin.h" +#include "d__durability.h" +#include "d__mergeAction.h" +#include "d__eventListener.h" +#include "d__nameSpacesRequestListener.h" +#include "d__sampleChainListener.h" +#include "d_object.h" +#include "os_time.h" +#include "os_heap.h" + +/** + * \brief Helper structure to collect all fellow aligners with the + * specified role. + */ +struct collectAlignableFellowsHelper { + d_durability durability; + d_nameSpace nameSpace; + c_iter fellows; + char *role; + c_ulong maxValue; +}; + +/** + * \brief Collect all fellow aligners that have the same role as specified + * in the helper, and collect the maximum value of the merge states. + * + * Only fellows are selected that are complete and for which all namespaces + * have been received. + */ +static c_bool +collectAlignableFellows ( + d_fellow fellow, + c_voidp userData) +{ + struct collectAlignableFellowsHelper *helper; + d_serviceState fellowState; + d_durability durability; + d_mergeState mergeState; + d_nameSpace fellowNs; + + helper = (struct collectAlignableFellowsHelper *)userData; + durability = helper->durability; + if (fellow->role && strcmp(fellow->role, helper->role) == 0) { + fellowState = d_fellowGetState(fellow); + + if ((fellowState == D_STATE_TERMINATING) || (fellowState == D_STATE_TERMINATED)) { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Fellow %u terminated, so it is not no candidate aligner.\n", + fellow->address->systemId); + + } else if (fellowState != D_STATE_COMPLETE) { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Fellow %u is not yet complete, so it is no candidate aligner\n", + fellow->address->systemId); + + } else if (!d_fellowAreNameSpacesComplete(fellow)) { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Not all namespaces of fellow %u are received yet, so it is no candidate aligner\n", + fellow->address->systemId); + + } else { + /* Check if the fellow is aligner for the namespace. If so, + * the fellow is a candidate to request samples from. Add + * it to the fellows list and determine the maximum mergeState + * value. The fellows are refCounted. They are lateron added + * to the mergeAction and freed when the mergeAction is + * destroyed. + */ + fellowNs = d_fellowGetNameSpace(fellow, helper->nameSpace); + if (d_nameSpaceIsAligner(fellowNs)) { + if (d_nameSpaceIsAlignable(fellowNs)) { + helper->fellows = c_iterAppend(helper->fellows, d_fellow(d_objectKeep(d_object(fellow)))); + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Fellow %u is a candidate aligner\n", + fellow->address->systemId); + /* Calculate the new state value. + * Only take non-cleared states into account. + */ + if ((mergeState = d_nameSpaceGetMergeState(fellowNs, fellow->role)) != NULL) { + if (mergeState->value > helper->maxValue) { + helper->maxValue = mergeState->value; + } + d_mergeStateFree(mergeState); + } + } else { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Fellow %u is not marked as alignable, so it is no candidate aligner\n", + fellow->address->systemId); + } + } + } + } + return TRUE; +} + +static void +fellowsFree( + c_iter fellows) +{ + d_fellow fellow; + assert(fellows); + fellow = c_iterTakeFirst(fellows); + while (fellow) { + d_fellowFree(fellow); + fellow = c_iterTakeFirst(fellows); + } + c_iterFree(fellows); +} + +static c_bool +resolveMasterConflict( + d_conflictResolver conflictResolver, + d_conflict conflict) +{ + d_nameSpace nameSpace, nameSpaceCopy, fellowNameSpace; + c_iter nameSpaces, fellows; + d_groupLocalListener listener; + d_networkAddress myAddr, masterAddr, unAddressed; + d_admin admin; + d_durability durability; + d_configuration config; + d_fellow fellow; + d_mergeState newState; + c_bool reschedule = FALSE; + struct collectAlignableFellowsHelper helper; + d_mergeState fellowMergeState; + + assert(d_conflictResolverIsValid(conflictResolver)); + assert(d_conflictIsValid(conflict)); + assert(IS_MASTER_CONFLICT(conflict)); + + admin = conflictResolver->admin; + durability = d_adminGetDurability(admin); + config = d_durabilityGetConfiguration(durability); + d_printTimedEvent(durability, D_LEVEL_FINER, + "Resolving master conflict %u for namespace '%s' (run: %u)\n", + conflict->id, conflict->nameSpaceCopy->name, conflict->reQueueCount); + + myAddr = d_adminGetMyAddress(admin); + unAddressed = d_networkAddressUnaddressed(); + listener = d_subscriberGetGroupLocalListener(d_adminGetSubscriber(admin)); + nameSpace = d_adminGetNameSpace(admin, conflict->nameSpaceCopy->name); + if (nameSpace) { + /* A master conflict needs to be resolved. + * Determine a new master for the namespace. + */ + nameSpaces = c_iterNew(nameSpace); + d_groupLocalListenerDetermineNewMasters(listener, nameSpaces); + c_iterFree(nameSpaces); + + /* At this point in time we should have a confirmed master, but it may + * not be me. In fact, in may not even be the fellow, e.g., when + * multiple nodes have competed for mastership. So let's find out who the + * confirmed master for the nameSpace is. If it turns out that I have + * become master then I must request samples from all other fellows that + * participated in the master conflicts. + */ + masterAddr = d_nameSpaceGetMaster(nameSpace); + fellow = d_adminGetFellow(admin, masterAddr); + + /* A fellow has become master */ + if (fellow) { + if ( (d_networkAddressCompare(masterAddr, myAddr) != 0) && /* somebody else is master for the namespace */ + (d_networkAddressCompare(masterAddr, unAddressed) != 0) && /* this somebody is not (0,0,0) */ + (d_nameSpaceIsMasterConfirmed(nameSpace)) && /* the master is confirmed */ + (strcmp(config->role, fellow->role) == 0) ) { /* the master has the same role as me */ + + if (d_nameSpaceGetMergePolicy(nameSpace, config->role) != D_MERGE_IGNORE) { + + fellowNameSpace = d_fellowGetNameSpace(fellow, nameSpace); + if (fellowNameSpace) { + fellowMergeState = d_nameSpaceGetMergeState(fellowNameSpace, fellow->role); + /* The fellow might have published transient data without having raised its state. + * Therefore, I must send a request for data. + * Only retrieve if the fellow state exists + */ + if (fellowMergeState) { + fellows = c_iterNew(d_fellow(d_objectKeep(d_object(fellow)))); + + nameSpaceCopy = d_nameSpaceCopy(nameSpace); + handleMergeAlignment(listener, conflict, nameSpaceCopy, fellows, fellowMergeState); + d_nameSpaceFree(nameSpaceCopy); + + d_printTimedEvent(durability, D_LEVEL_INFO, + "Fellow %u has become master when resolving conflict %d, I am going to retrieve data.\n", + fellow->address->systemId, conflict->id); + + fellowsFree(fellows); + + d_mergeStateFree(fellowMergeState); + } + } + } else { + /* I have an IGNORE merge policy so I better not request data */ + d_printTimedEvent(durability, D_LEVEL_INFO, + "Fellow %u has become master when resolving conflict %d, but I have an IGNORE merge policy so I will not request any data.\n", + fellow->address->systemId, conflict->id); + } + } else { + d_printTimedEvent(durability, D_LEVEL_INFO, + "No need to merge with fellow %u as a result of solving conflict %d\n", + fellow->address->systemId, conflict->id); + } + d_fellowFree(fellow); + + /* I have become master */ + } else if ( (d_networkAddressCompare(masterAddr, myAddr) == 0) && /* I have become master */ + (d_nameSpaceIsMasterConfirmed(nameSpace)) ) { /* the master is confirmed */ + + d_printTimedEvent(durability, D_LEVEL_INFO, + "I have become master when resolving conflict %d.\n", conflict->id); + + if (d_nameSpaceGetMergePolicy(nameSpace, config->role) != D_MERGE_IGNORE) { + /* Retrieve all potential fellow aligners that have the same role as me, and + * determine the maximum merge state value of all of them. + * + * Note: currently ALL fellow aligners are collected. An optimized + * approach would be to request the former master fellows for the + * nameSpace. + */ + + /* Get a copy of the namespace at this moment in time. */ + nameSpaceCopy = d_nameSpaceCopy(nameSpace); + + /* Collect fellow aligners for the namespace */ + helper.durability = durability; + helper.fellows = c_iterNew(NULL); + helper.role = config->role; + helper.maxValue = (nameSpaceCopy->mergeState == NULL) ? 0 : nameSpaceCopy->mergeState->value; + helper.nameSpace = nameSpaceCopy; + d_adminFellowWalk(admin, collectAlignableFellows, &helper); + if (c_iterLength(helper.fellows) > 0) { + /* The new merge state must be higher than the maximum mergeState + * value of all potential fellow aligners including myself + */ + newState = d_mergeStateNew(config->role, helper.maxValue + 1); + d_printTimedEvent(durability, D_LEVEL_INFO, + "I am going to request data for namespace '%s' from %d fellow aligners.\n", + d_nameSpaceGetName(nameSpaceCopy), c_iterLength(helper.fellows)); + /* Request data from the fellows, and set the new merge state when all + * fellows have send their data. + */ + handleMergeAlignment(listener, conflict, nameSpaceCopy, helper.fellows, newState); + d_mergeStateFree(newState); + } else { + d_printTimedEvent(durability, D_LEVEL_FINER, "No fellow aligners available\n"); + } + d_nameSpaceFree(nameSpaceCopy); + fellowsFree(helper.fellows); + } else { + /* I have an IGNORE merge policy so I better not request data */ + d_printTimedEvent(durability, D_LEVEL_INFO, + "I have become master when resolving conflict %d, but I have an IGNORE merge policy so I will not request any data.\n", + conflict->id); + } + /* No master found */ + } else { + d_printTimedEvent(durability, D_LEVEL_INFO, + "No need to request data because there is no master\n"); + } + d_networkAddressFree(masterAddr); + d_nameSpaceFree(nameSpace); + } else { + d_printTimedEvent(durability, D_LEVEL_FINER, + "Cancelling conflict %d because namespace '%s' could not be found.\n", + conflict->id, conflict->nameSpaceCopy->name); + } + d_networkAddressFree(myAddr); + d_networkAddressFree(unAddressed); + + return reschedule; +} + + +static c_bool +resolveNativeStateConflict( + d_conflictResolver conflictResolver, + d_conflict conflict) +{ + d_nameSpace nameSpace, fellowNameSpace, fellowNameSpaceCopy; + d_fellow fellow; + d_groupLocalListener listener; + d_admin admin; + d_durability durability; + d_configuration config; + d_serviceState fellowState; + d_networkAddress myAddr, masterAddr, fellowAddr, unAddressed; + d_mergeState newState, mergeState, fellowMergeState; + d_mergePolicy mergePolicy; + d_alignmentKind alignmentKind; + c_bool reschedule = FALSE; + c_iter fellows; + + assert(d_conflictResolverIsValid(conflictResolver)); + assert(d_conflictIsValid(conflict)); + assert(IS_NATIVE_STATE_CONFLICT(conflict)); + + admin = conflictResolver->admin; + durability = d_adminGetDurability(admin); + config = d_durabilityGetConfiguration(durability); + d_printTimedEvent(durability, D_LEVEL_FINER, + "Resolving native state conflict %u for namespace '%s' (run: %u)\n", + conflict->id, conflict->nameSpaceCopy->name, conflict->reQueueCount); + /* A native state conflict needs to be resolved. + * First find out if the native state conflict still exists. + */ + myAddr = d_adminGetMyAddress(admin); + unAddressed = d_networkAddressUnaddressed(); + listener = d_subscriberGetGroupLocalListener(d_adminGetSubscriber(admin)); + nameSpace = d_adminGetNameSpace(admin, conflict->nameSpaceCopy->name); + if (nameSpace) { + masterAddr = d_nameSpaceGetMaster(nameSpace); + if (d_networkAddressCompare(masterAddr, conflict->fellowAddr) == 0) { + /* The fellow is still the master that was detected when the conflict + * was generated. + */ + fellow = d_adminGetFellow(admin, conflict->fellowAddr); + if (fellow) { + fellowAddr = d_fellowGetAddress(fellow); + if ( (d_networkAddressCompare(masterAddr, myAddr) != 0) && /* somebody else is master for the namespace */ + (d_networkAddressCompare(masterAddr, unAddressed) != 0) && /* this somebody is not (0,0,0) */ + (d_networkAddressCompare(masterAddr, fellowAddr) == 0) && /* the fellow is master */ + (strcmp(config->role, fellow->role) == 0) ) { /* the master has the same role as me */ + + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Native state conflict %d for namespace '%s' may still exist, checking further\n", + conflict->id, nameSpace->name); + + fellowState = d_fellowGetState(fellow); + fellowNameSpace = d_fellowGetNameSpace(fellow, nameSpace); + mergePolicy = d_nameSpaceGetMergePolicy(nameSpace, config->role); + alignmentKind = d_nameSpaceGetAlignmentKind(nameSpace); + /* Get the merge state for my role */ + mergeState = d_nameSpaceGetMergeState(nameSpace, config->role); + fellowMergeState = d_nameSpaceGetMergeState(fellowNameSpace, config->role); + + if (!d_nameSpaceIsMasterConfirmed(nameSpace)) { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "I do not (yet) have a confirmed master, rescheduling conflict %d.\n", + conflict->id); + reschedule = TRUE; + + } else if ((fellowState == D_STATE_TERMINATING) || (fellowState == D_STATE_TERMINATED)) { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Cancelling conflict %d because fellow %u has terminated.\n", + conflict->id, fellow->address->systemId); + + } else if ((alignmentKind != D_ALIGNEE_INITIAL) && (alignmentKind != D_ALIGNEE_LAZY)) { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Cancelling conflict %d because alignee policy does not ask for it.\n", + conflict->id); + + } else if (fellowMergeState == NULL) { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Cancelling conflict %d, unable to merge namespace '%s' of fellow %u because its merge state is NULL\n", + conflict->id, nameSpace->name, fellowAddr->systemId); + + } else if (fellowState < D_STATE_INJECT_PERSISTENT) { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Fellow %u is not yet ready, re-scheduling conflict %d\n", + fellow->address->systemId, conflict->id); + reschedule = TRUE; + + } else if (!d_fellowAreNameSpacesComplete(fellow)) { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Not all namespaces of fellow %u are received yet, re-scheduling conflict %d\n", + fellow->address->systemId, conflict->id); + reschedule = TRUE; + + } else if (nameSpace->mergeState->value != conflict->nameSpaceCopy->mergeState->value) { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "The merge state of my namespace '%s' has changed after conflict %d was detected from (%s,%d) to (%s,%d)," \ + " canceling the conflict", + nameSpace->name, conflict->id, + conflict->nameSpaceCopy->mergeState->role, conflict->nameSpaceCopy->mergeState->value, + nameSpace->mergeState->role, nameSpace->mergeState->value); + + } else if (fellowNameSpace->mergeState->value != conflict->fellowNameSpaceCopy->mergeState->value) { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "The merge state of the namespace '%s' of my master %u has changed after conflict %d was detected from (%s,%d) to (%s,%d)," \ + " canceling the conflict", + fellowNameSpace->name, masterAddr->systemId, conflict->id, + conflict->fellowNameSpaceCopy->mergeState->role, conflict->fellowNameSpaceCopy->mergeState->value, + fellowNameSpace->mergeState->role, fellowNameSpace->mergeState->value); + + } else { + c_bool doMerge = FALSE; + /* Only merge if my state was empty or differs. + * There is also no need to merge if the merge policy is IGNORE + */ + if (mergeState != NULL) { + doMerge = ((mergeState->value != fellowMergeState->value) && (mergePolicy != D_MERGE_IGNORE)); + } else { + doMerge = TRUE; + } + if (doMerge) { + /* I need to retrieve data from my master and update my + * mergestate to that of the master's. + */ + d_printTimedEvent(durability, D_LEVEL_FINER, + "Applying merge with my master fellow %u for nameSpace '%s' to solve conflict %d.\n", + fellow->address->systemId, d_nameSpaceGetName(nameSpace), conflict->id); + /* Get a copy of the masters's nameSpace at this moment in time. */ + fellowNameSpaceCopy = d_nameSpaceCopy(fellowNameSpace); + /* Copy the master's namespace state */ + newState = d_mergeStateNew(conflict->fellowNameSpaceCopy->mergeState->role, conflict->fellowNameSpaceCopy->mergeState->value); + /* A merge is needed with the fellow for the nameSpace. */ + fellows = c_iterNew(d_fellow(d_objectKeep(d_object(fellow)))); + handleMergeAlignment(listener, conflict, fellowNameSpaceCopy, fellows, newState); + fellowsFree(fellows); + d_mergeStateFree(newState); + d_nameSpaceFree(fellowNameSpaceCopy); + } else if (mergeState->value == fellowMergeState->value) { + d_printTimedEvent(durability, D_LEVEL_FINER, + "No difference in merge state detected for namespace '%s' from fellow %u, done solving conflict %d\n", + nameSpace->name, fellowAddr->systemId, conflict->id); + } else { + /* The only possibility left for doMerge to be FALSE is that + * the merge policy is D_MERGE_IGNORE. In that case there is + * no need to align, it is sufficient to take over the fellow's + * merge state + */ + d_printTimedEvent(durability, D_LEVEL_FINEST, + "No need to merge with fellow %u to solve native state conflict %d because the merge policy is IGNORE\n", + fellowAddr->systemId, conflict->id); + d_nameSpaceSetMergeState(nameSpace, fellowMergeState); + d_printTimedEvent(durability, D_LEVEL_FINER, + "Updating merge state for role '%s' to fellow's %u merge state %d, done solving conflict %d\n", + fellow->role, fellowAddr->systemId, fellowMergeState->value, conflict->id); + } + } + if (mergeState) { + d_mergeStateFree(mergeState); + } + if (fellowMergeState) { + d_mergeStateFree(fellowMergeState); + } + } else { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "No need to merge with fellow %u as a result of solving conflict %d\n", + fellow->address->systemId, conflict->id); + } + d_networkAddressFree(fellowAddr); + d_fellowFree(fellow); + } else { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Cancelling conflict %d because no fellow for master %u could be found.\n", + conflict->id, masterAddr->systemId); + } + } else { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "NameSpace '%s' now has changed master from %u to %u, cancelling conflict %d.\n", + conflict->nameSpaceCopy->name, conflict->fellowAddr->systemId, masterAddr->systemId, conflict->id); + } + d_networkAddressFree(masterAddr); + d_nameSpaceFree(nameSpace); + } else { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Cancelling conflict %d because no namespace '%s' could be found.\n", + conflict->id, conflict->nameSpaceCopy->name); + } + d_networkAddressFree(unAddressed); + d_networkAddressFree(myAddr); + + return reschedule; +} + + +static c_bool +resolveForeignStateConflict( + d_conflictResolver conflictResolver, + d_conflict conflict) +{ + d_nameSpace nameSpace, fellowNameSpace, fellowNameSpaceCopy; + d_fellow fellow; + d_groupLocalListener listener; + d_admin admin; + d_durability durability; + d_configuration config; + d_serviceState fellowState; + d_networkAddress myAddr, masterAddr, fellowAddr, fellowMasterAddr, unAddressed; + d_mergeState newState, mergeState, fellowMergeState; + d_mergePolicy mergePolicy; + d_alignmentKind alignmentKind; + c_bool reschedule = FALSE; + c_iter fellows; + assert(d_conflictResolverIsValid(conflictResolver)); + assert(d_conflictIsValid(conflict)); + assert(IS_FOREIGN_STATE_CONFLICT(conflict)); + + admin = conflictResolver->admin; + durability = d_adminGetDurability(admin); + config = d_durabilityGetConfiguration(durability); + d_printTimedEvent(durability, D_LEVEL_FINER, + "Resolving foreign state conflict %u for namespace '%s' (run: %u)\n", + conflict->id, conflict->nameSpaceCopy->name, conflict->reQueueCount); + /* A foreign state conflict needs to be resolved. + * First find out if the foreign state conflict still exists. + */ + myAddr = d_adminGetMyAddress(admin); + unAddressed = d_networkAddressUnaddressed(); + listener = d_subscriberGetGroupLocalListener(d_adminGetSubscriber(admin)); + nameSpace = d_adminGetNameSpace(admin, conflict->nameSpaceCopy->name); + if (nameSpace) { + masterAddr = d_nameSpaceGetMaster(nameSpace); + fellow = d_adminGetFellow(admin, conflict->fellowAddr); + if (fellow) { + fellowAddr = d_fellowGetAddress(fellow); + fellowNameSpace = d_fellowGetNameSpace(fellow, nameSpace); + if (fellowNameSpace) { + fellowMasterAddr = d_nameSpaceGetMaster(fellowNameSpace); + + if ( (d_networkAddressCompare(masterAddr, myAddr) == 0) && /* I am master for the namespace */ + (d_nameSpaceIsMasterConfirmed(nameSpace)) && /* my master is confirmed */ + (d_networkAddressCompare(fellowMasterAddr, fellowAddr) == 0) && /* the fellow is master for the fellow namespace */ + (d_nameSpaceIsMasterConfirmed(fellowNameSpace)) && /* the master for the fellow namespace is confirmed */ + (strcmp(config->role, fellow->role) != 0) ) { /* the fellow has a different role than me */ + + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Foreign state conflict %d for namespace '%s' may still exist, checking further\n", + conflict->id, nameSpace->name); + + fellowState = d_fellowGetState(fellow); + mergePolicy = d_nameSpaceGetMergePolicy(nameSpace, fellow->role); + alignmentKind = d_nameSpaceGetAlignmentKind(nameSpace); + /* Get the merge state for the fellow role */ + mergeState = d_nameSpaceGetMergeState(nameSpace, fellow->role); + fellowMergeState = d_nameSpaceGetMergeState(fellowNameSpace, fellow->role); + + if ((fellowState == D_STATE_TERMINATING) || (fellowState == D_STATE_TERMINATED)) { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Cancelling conflict %d because fellow %u has terminated.\n", + conflict->id, fellowAddr->systemId); + + } else if ((alignmentKind != D_ALIGNEE_INITIAL) && (alignmentKind != D_ALIGNEE_LAZY)) { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Cancelling conflict %d because alignee policy does not ask for it.\n", + conflict->id); + + } else if (fellowMergeState == NULL) { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Cancelling conflict %d, unable to merge namespace '%s' of fellow %u because its merge state is NULL\n", + conflict->id, nameSpace->name, fellowAddr->systemId); + + } else if (!d_fellowAreNameSpacesComplete(fellow)) { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Not all namespaces of fellow %u are received yet, re-scheduling conflict %d\n", + fellowAddr->systemId, conflict->id); + reschedule = TRUE; + + } else if (d_durabilityGetState(durability) != D_STATE_COMPLETE) { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "I am not complete, re-scheduleing conflict %d\n", + conflict->id); + reschedule = TRUE; + + } else if (nameSpace->mergeState->value != conflict->nameSpaceCopy->mergeState->value) { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "The merge state of my namespace '%s' has changed after conflict %d was detected from (%s,%d) to (%s,%d)," \ + " rescheduling the conflict", + nameSpace->name, conflict->id, + conflict->nameSpaceCopy->mergeState->role, conflict->nameSpaceCopy->mergeState->value, + nameSpace->mergeState->role, nameSpace->mergeState->value); + reschedule = TRUE; + + } else if (fellowNameSpace->mergeState->value != conflict->fellowNameSpaceCopy->mergeState->value) { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "The merge state of the conflicting namespace '%s' of fellow %u has changed after conflict %d was detected from (%s,%d) to (%s,%d)," \ + " rescheduling the conflict", + fellowNameSpace->name, fellowAddr->systemId, conflict->id, + conflict->fellowNameSpaceCopy->mergeState->role, conflict->fellowNameSpaceCopy->mergeState->value, + fellowNameSpace->mergeState->role, fellowNameSpace->mergeState->value); + reschedule = TRUE; + } else if (mergePolicy == D_MERGE_IGNORE) { + /* No need to align, it is sufficient to take over the fellow's merge state */ + d_printTimedEvent(durability, D_LEVEL_FINER, + "No need to merge with fellow %u to solve foreign state conflict %d because the merge policy is IGNORE\n", + fellowAddr->systemId, conflict->id); + d_nameSpaceSetMergeState(nameSpace, fellowMergeState); + d_printTimedEvent(durability, D_LEVEL_FINE, + "Updating merge state for role '%s' to fellow's %u merge state %d, done solving conflict %d\n", + fellow->role, fellowAddr->systemId, fellowMergeState->value, conflict->id); + } else if (mergeState && (mergeState->value == fellowMergeState->value)) { + d_printTimedEvent(durability, D_LEVEL_FINER, + "No difference in merge state detected for namespace '%s' from fellow %u, done solving conflict %d\n", + nameSpace->name, fellowAddr->systemId, conflict->id); + } else { + d_printTimedEvent(durability, D_LEVEL_FINER, + "Applying merge with my fellow %u for nameSpace '%s' to solve foreign state conflict %d.\n", + fellow->address->systemId, + d_nameSpaceGetName(nameSpace), + conflict->id); + /* Get a copy of the masters's nameSpace at this moment in time. */ + fellowNameSpaceCopy = d_nameSpaceCopy(fellowNameSpace); + /* Copy state from master fellow */ + newState = d_mergeStateNew(fellow->role, fellowNameSpaceCopy->mergeState->value); + /* A merge is needed with the fellow for the nameSpace. + * Get a copy of the fellow's namespace at this moment + * in time. + */ + fellows = c_iterNew(d_fellow(d_objectKeep(d_object(fellow)))); + handleMergeAlignment(listener, conflict, fellowNameSpaceCopy, fellows, newState); + fellowsFree(fellows); + d_mergeStateFree(newState); + d_nameSpaceFree(fellowNameSpaceCopy); + } + if (mergeState) { + d_mergeStateFree(mergeState); + } + if (fellowMergeState) { + d_mergeStateFree(fellowMergeState); + } + } else { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "No need to merge with fellow %u as a result of solving conflict %d\n", + fellow->address->systemId, conflict->id); + } + d_networkAddressFree(fellowMasterAddr); + } else { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Cancelling conflict %d because no fellow for master %u could be found.\n", + conflict->id, masterAddr->systemId); + } + d_fellowFree(fellow); + d_networkAddressFree(fellowAddr); + } else { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "NameSpace '%s' now has changed master from %u to %u, cancelling conflict %d.\n", + conflict->nameSpaceCopy->name, conflict->fellowAddr->systemId, masterAddr->systemId, conflict->id); + } + d_networkAddressFree(masterAddr); + d_nameSpaceFree(nameSpace); + } else { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Cancelling conflict %d because no namespace '%s' could be found.\n", + conflict->id, conflict->nameSpaceCopy->name); + } + d_networkAddressFree(unAddressed); + d_networkAddressFree(myAddr); + + return reschedule; +} + + +static c_bool +resolveFellowDisconnectConflict( + d_conflictResolver conflictResolver, + d_conflict conflict) +{ + d_admin admin; + d_durability durability; + c_bool reschedule = FALSE; + d_fellow fellow; + d_networkAddress fellowAddr; + d_serviceState myState, fellowState; + + assert(d_conflictResolverIsValid(conflictResolver)); + assert(d_conflictIsValid(conflict)); + assert(IS_FELLOW_DISCONNECTED_CONFLICT(conflict)); + + admin = conflictResolver->admin; + durability = d_adminGetDurability(admin); + d_printTimedEvent(durability, D_LEVEL_FINER, + "Resolving fellow disconnected conflict %u for fellow %u (run: %u)\n", + conflict->id, conflict->fellowAddr->systemId, conflict->reQueueCount); + /* To solve a fellow disconnected conflict we need to request data for all + * namespaces for which I am confirmed master. + */ + fellow = d_adminGetFellow(admin, conflict->fellowAddr); + if (fellow) { + myState = d_durabilityGetState(durability); + fellowAddr = d_fellowGetAddress(fellow); + fellowState = d_fellowGetState(fellow); + + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Fellow disconnected conflict %d may still exist, checking further\n", + conflict->id); + + if ((myState == D_STATE_TERMINATING) || (myState == D_STATE_TERMINATED)) { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Canceling conflict %d because I am terminating.\n", + conflict->id); + + } else if ((fellowState == D_STATE_TERMINATING) || (fellowState == D_STATE_TERMINATED)) { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Canceling conflict %d because fellow %u has terminated.\n", + conflict->id, fellowAddr->systemId); + + } else if (!d_fellowAreNameSpacesComplete(fellow)) { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Not all namespaces of fellow %"PA_PRIu32" are received yet, re-scheduling conflict %"PA_PRIu32"\n", + fellowAddr->systemId, conflict->id); + reschedule = TRUE; + + } else { + /* Apparently the fellow experienced a disconnect with me, but I did not notice that. + * Still I might have lost data when the fellow was publishing data, e.g., because my acks/nacks + * where not received by the fellow. + * To ensure a consistent state I must align from my master (assuming some fellow is the master), + * or I must acquire the data from the fellow if I was master. + */ + c_iter nameSpaces; + c_iterIter iter; + d_nameSpace nameSpace; + d_networkAddress masterAddr; + d_networkAddress myAddr; + d_mergeState newState; + d_groupLocalListener listener; + d_networkAddress unAddressed = d_networkAddressUnaddressed(); + + nameSpaces = d_adminGetNameSpaces(admin); + iter = c_iterIterGet(nameSpaces); + listener = d_subscriberGetGroupLocalListener(d_adminGetSubscriber(admin)); + + myAddr = d_adminGetMyAddress(admin); + while ((nameSpace = (d_nameSpace)c_iterNext(&iter)) != NULL) { + masterAddr = d_nameSpaceGetMaster(nameSpace); + + /* If I have no confirmed master for the namespace then I am busy negotiating + * a master. This will already lead to alignment, so I can safely discard this case. + */ + if (!d_nameSpaceIsMasterConfirmed(nameSpace)) { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "I have no confirmed master for namespace %s, discarding conflict %"PA_PRIu32"\n", nameSpace->name, conflict->id); + } + + else if (d_networkAddressCompare(masterAddr, unAddressed) == 0) { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "No aligner is available for namespace %s, discarding conflict %"PA_PRIu32"\n", nameSpace->name, conflict->id); + } + + /* If I was the master myself then I must retrieve the data that I + * potentially missed and update my state. + */ + else if (d_networkAddressCompare(masterAddr, myAddr) == 0) { + c_iter fellows; + d_nameSpace fellowNameSpace; + + fellowNameSpace = d_fellowGetNameSpace(fellow, nameSpace); + if (d_nameSpaceIsAligner(fellowNameSpace)) { + /* I am the confirmed master for this nameSpace, so I must make sure + * to obtain any data that I missed + */ + d_printTimedEvent(durability, D_LEVEL_FINER, + "I am the confirmed master for namespace %s, " + "I am going to request data from fellow %"PA_PRIu32"\n", + nameSpace->name, fellow->address->systemId); + /* Set the new state */ + newState = d_mergeStateNew(fellow->role, nameSpace->mergeState->value + 1); + /* A merge is needed with the fellow for the nameSpace. */ + fellows = c_iterNew(d_fellow(d_objectKeep(d_object(fellow)))); + handleMergeAlignment(listener, conflict, nameSpace, fellows, newState); + fellowsFree(fellows); + d_mergeStateFree(newState); + } else { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "I am the confirmed master for namespace %s, " + "no need to request data from fellow %"PA_PRIu32" since it can't align\n", + nameSpace->name, fellow->address->systemId); + } + + /* A fellow was master, I must realign with this fellow to get synchronized again. + * Clear my merge state and initiate a native state conflict to get + * data from my master again + */ + } else { + d_fellow master; + + d_printTimedEvent(durability, D_LEVEL_FINER, + " - Fellow %"PA_PRIu32" is the confirmed master for namespace %s, clear the namespace state and realign with my master\n", masterAddr->systemId, nameSpace->name); + + d_nameSpaceClearMergeState(nameSpace, NULL); + if ((master = d_adminGetFellow(admin, masterAddr)) != NULL) { + d_fellowSendNSRequest(master); + d_fellowFree(master); + } else { + d_printTimedEvent(durability, D_LEVEL_FINEST, + " - Unable to find the confirmed %"PA_PRIu32" for namespace %s in my administration, I only cleared the namespace state\n", masterAddr->systemId, nameSpace->name); + } + + } + d_networkAddressFree(masterAddr); + d_nameSpaceFree(nameSpace); + } + c_iterFree(nameSpaces); + d_networkAddressFree(myAddr); + d_networkAddressFree(unAddressed); + + } + d_networkAddressFree(fellowAddr); + d_fellowFree(fellow); + } else { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Canceling conflict %d because fellow = .\n", + conflict->id); + } + + return reschedule; +} + + +static c_bool +resolveFellowConnectConflict( + d_conflictResolver conflictResolver, + d_conflict conflict) +{ + d_admin admin; + d_durability durability; + d_configuration config; + c_bool reschedule = FALSE; + d_fellow fellow; + d_networkAddress fellowAddr; + d_serviceState myState, fellowState; + + assert(d_conflictResolverIsValid(conflictResolver)); + assert(d_conflictIsValid(conflict)); + assert(IS_FELLOW_CONNECTED_CONFLICT(conflict)); + + admin = conflictResolver->admin; + durability = d_adminGetDurability(admin); + config = d_durabilityGetConfiguration(durability); + d_printTimedEvent(durability, D_LEVEL_FINER, + "Resolving fellow connected conflict %u for fellow %u (run: %u)\n", + conflict->id, conflict->fellowAddr->systemId, conflict->reQueueCount); + + /* A fellowConnect conflict occurs if a fellow is recently connected. + * This can happen when a fellow just joins, or when an asymmetric disconnect + * has been discovered. In both cases the fellow may already have published data. + * This data needs to be retrieved for nodes that are master + */ + fellow = d_adminGetFellow(admin, conflict->fellowAddr); + if (fellow) { + myState = d_durabilityGetState(durability); + fellowAddr = d_fellowGetAddress(fellow); + fellowState = d_fellowGetState(fellow); + + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Fellow connected conflict %d may still exist, checking further\n", + conflict->id); + + if ((myState == D_STATE_TERMINATING) || (myState == D_STATE_TERMINATED)) { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Canceling conflict %d because I am terminating.\n", + conflict->id); + fellow->recently_joined = FALSE; + + } else if ((fellowState == D_STATE_TERMINATING) || (fellowState == D_STATE_TERMINATED)) { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Canceling conflict %d because fellow %u has terminated.\n", + conflict->id, fellowAddr->systemId); + fellow->recently_joined = FALSE; + + + } else if (!d_fellowAreNameSpacesComplete(fellow)) { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Not all namespaces of fellow %"PA_PRIu32" are received yet, re-scheduling conflict %"PA_PRIu32"\n", + fellowAddr->systemId, conflict->id); + reschedule = TRUE; + + } else { + /* The fellow may have published data that I do not know. + * To receive the data that I potentially missed I should re-align. + */ + c_iter nameSpaces; + c_iterIter iter; + d_nameSpace nameSpace; + d_networkAddress masterAddr; + d_networkAddress myAddr; + d_mergeState newState; + d_groupLocalListener listener; + d_networkAddress unAddressed = d_networkAddressUnaddressed(); + + nameSpaces = d_adminGetNameSpaces(admin); + iter = c_iterIterGet(nameSpaces); + listener = d_subscriberGetGroupLocalListener(d_adminGetSubscriber(admin)); + + myAddr = d_adminGetMyAddress(admin); + while ((nameSpace = (d_nameSpace)c_iterNext(&iter)) != NULL) { + masterAddr = d_nameSpaceGetMaster(nameSpace); + + /* If I have no confirmed master for the namespace then I am busy negotiating + * a master. This will already to alignment, so I can safely discard this case. + */ + if (!d_nameSpaceIsMasterConfirmed(nameSpace)) { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "I have no confirmed master for namespace %s yet, reschedule conflict %"PA_PRIu32"\n", + nameSpace->name, conflict->id); + reschedule = TRUE; + } + else if (d_networkAddressCompare(masterAddr, unAddressed) == 0) { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "No aligner is available for namespace %s, discarding conflict %"PA_PRIu32"\n", + nameSpace->name, conflict->id); + } + /* If I was the master myself then I must retrieve the data that I + * potentially missed and update my state. + */ + else if (d_networkAddressCompare(masterAddr, myAddr) == 0) { + c_iter fellows; + d_nameSpace fellowNameSpace; + + fellowNameSpace = d_fellowGetNameSpace(fellow, nameSpace); + if (d_nameSpaceIsAligner(fellowNameSpace)) { + d_mergePolicy mergePolicy = d_nameSpaceGetMergePolicy(nameSpace, d_fellowGetRole(fellow)); + if (mergePolicy != D_MERGE_IGNORE) { + /* I am the confirmed master for this nameSpace, so I must make sure + * to obtain any data that I missed + */ + d_printTimedEvent(durability, D_LEVEL_FINER, + "I am the confirmed master for namespace %s, " + "I am going to request data from fellow %"PA_PRIu32"\n", + nameSpace->name, fellow->address->systemId); + /* Set the new state */ + newState = d_mergeStateNew(fellow->role, nameSpace->mergeState->value + 1); + /* A merge is needed with the fellow for the nameSpace. */ + fellows = c_iterNew(d_fellow(d_objectKeep(d_object(fellow)))); + handleMergeAlignment(listener, conflict, nameSpace, fellows, newState); + fellowsFree(fellows); + d_mergeStateFree(newState); + } else { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "I am the confirmed master but configured to ignore the namespace %s, " + "I am NOT going to request data from fellow %"PA_PRIu32"\n", + nameSpace->name, fellow->address->systemId); + } + } else { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "I am the confirmed master for namespace %s, " + "no need to request data from fellow %"PA_PRIu32" since it can't align\n", + nameSpace->name, fellow->address->systemId); + } + } else if (d_networkAddressCompare(masterAddr, fellowAddr) == 0) { + d_nameSpace fellowNameSpace; + fellowNameSpace = d_fellowGetNameSpace(fellow, nameSpace); + + if (d_nameSpaceIsAligner(fellowNameSpace)) { + d_mergePolicy mergePolicy = d_nameSpaceGetMergePolicy(nameSpace, d_fellowGetRole(fellow)); + + if (d_nameSpaceGetMergeCount(fellowNameSpace) == 0) { + if (mergePolicy != D_MERGE_IGNORE) { + d_nameSpace fellowNameSpaceCopy; + c_iter fellows; + + d_printTimedEvent(durability, D_LEVEL_FINER, + "Applying merge with my master fellow %u for nameSpace '%s' to solve conflict %d.\n", + fellow->address->systemId, d_nameSpaceGetName(nameSpace), conflict->id); + + /* Get a copy of the masters's nameSpace at this moment in time. */ + fellowNameSpaceCopy = d_nameSpaceCopy(fellowNameSpace); + /* Copy the master's namespace state */ + newState = d_mergeStateNew(fellowNameSpaceCopy->mergeState->role, fellowNameSpaceCopy->mergeState->value); + /* A merge is needed with the fellow for the nameSpace. */ + fellows = c_iterNew(d_fellow(d_objectKeep(d_object(fellow)))); + handleMergeAlignment(listener, conflict, fellowNameSpaceCopy, fellows, newState); + fellowsFree(fellows); + d_mergeStateFree(newState); + d_nameSpaceFree(fellowNameSpaceCopy); + } else { + d_mergeState fellowMergeState; + fellowMergeState = d_nameSpaceGetMergeState(fellowNameSpace, config->role); + assert(fellowMergeState); + /* No need to align, it is sufficient to take over the fellow's merge state */ + d_printTimedEvent(durability, D_LEVEL_FINER, + "No need to merge with fellow %"PA_PRIu32" to solve connect conflict %d because the merge policy is IGNORE\n", + fellowAddr->systemId, conflict->id); + d_nameSpaceSetMergeState(nameSpace, fellowMergeState); + d_printTimedEvent(durability, D_LEVEL_FINE, + "Updating merge state for role '%s' to fellow's %u merge state %d, done solving conflict %d\n", + fellow->role, fellowAddr->systemId, fellowMergeState->value, conflict->id); + d_mergeStateFree(fellowMergeState); + } + } else { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Already applied merge policy for namespace %s after connect, no need to do anything\n", + nameSpace->name); + } + } + } else { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Neither me nor fellow %"PA_PRIu32" is master for namespace %s when solving conflict %u, no need to do anything\n", + masterAddr->systemId, nameSpace->name, conflict->id); + } + + d_networkAddressFree(masterAddr); + d_nameSpaceFree(nameSpace); + } + c_iterFree(nameSpaces); + d_networkAddressFree(myAddr); + d_networkAddressFree(unAddressed); + + if (reschedule != TRUE) { + fellow->recently_joined = FALSE; + } + } + d_networkAddressFree(fellowAddr); + d_fellowFree(fellow); + } else { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Canceling conflict %d because fellow = .\n", + conflict->id); + } + + return reschedule; +} + + +static c_bool +resolveFederationDisconnectConflict( + d_conflictResolver conflictResolver, + d_conflict conflict) +{ + d_admin admin; + d_durability durability; + c_bool reschedule = FALSE; + d_serviceState myState; + + assert(d_conflictResolverIsValid(conflictResolver)); + assert(d_conflictIsValid(conflict)); + assert(IS_FEDERATION_DISCONNECTED_CONFLICT(conflict)); + + admin = conflictResolver->admin; + durability = d_adminGetDurability(admin); + myState = d_durabilityGetState(durability); + d_printTimedEvent(durability, D_LEVEL_FINER, + "Resolving federation disconnected conflict %u (run: %u)\n", + conflict->id, conflict->reQueueCount); + + if ((myState == D_STATE_TERMINATING) || (myState == D_STATE_TERMINATED)) { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Canceling conflict %d because I am terminating.\n", conflict->id); + + } else if (myState != D_STATE_COMPLETE) { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Rescheduling conflict %d because I have not reached state D_STATE_COMPLETE yet (current state %d).\n", + conflict->id, myState); + reschedule = TRUE; + + } else { + /* No real resolution needed for this conflict. + * The only purpose is to trigger a conflict so that d_conflictResolverRun + * marks all aligner groups complete in case there are no pending conflicts + */ + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Federation disconnected conflict %d still valid, checking whether to groups needs to become complete\n", + conflict->id); + } + return reschedule; +} + + +static c_bool +checkFellowNameSpacesKnown( + d_fellow fellow, + c_voidp args) +{ + c_bool* known; + + known = (c_bool*)args; + *known = d_fellowAreNameSpacesComplete(fellow); + + return *known; + +} + +static c_bool +resolveInitialConflict( + _Inout_ d_conflictResolver conflictResolver, + _Inout_ d_conflict conflict) +{ + d_admin admin; + d_durability durability; + c_bool reschedule = FALSE; + d_serviceState myState; + c_bool complete; + c_bool fellowNameSpacesKnown = FALSE; + d_subscriber subscriber; + d_configuration config; + d_sampleChainListener sampleChainListener; + + assert(d_conflictResolverIsValid(conflictResolver)); + assert(d_conflictIsValid(conflict)); + assert(IS_INITIAL_CONFLICT(conflict)); + + admin = conflictResolver->admin; + durability = d_adminGetDurability(admin); + config = d_durabilityGetConfiguration(durability); + subscriber = d_adminGetSubscriber(admin); + sampleChainListener = d_subscriberGetSampleChainListener(subscriber); + + myState = d_durabilityGetState(durability); + d_printTimedEvent(durability, D_LEVEL_FINER, + "Resolving initial conflict %u (run: %u)\n", + conflict->id, conflict->reQueueCount); + + if ((myState == D_STATE_TERMINATING) || (myState == D_STATE_TERMINATED)) { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Canceling conflict %d because I am terminating.\n", + conflict->id); + } else { + os_timeM now = os_timeMGet(); + c_bool toReport; + + /* Get a copy of the list of currently available fellows. + * This list will be used when resolving the initial conflict. + * Any fellow that will appear during the resolution of the initial + * conflict will not play a role in resolving the initial conflict */ + d_adminInitialFellowsCreate(admin); + + /* Check whether or not to report */ + toReport = (os_timeMCompare(conflictResolver->nextReportTime, now) == OS_LESS); + if (toReport) { + char *str; + + str = d_adminGetInitialFellowsString(admin); + d_printTimedEvent(durability, D_LEVEL_INFO, + "Checking for completeness of local groups with fellows [%s].\n", str); + os_free(str); + } + + /* Reschedule initial conflict if namespaces not yet known */ + d_adminInitialFellowWalk(durability->admin, checkFellowNameSpacesKnown, &fellowNameSpacesKnown); + if ((fellowNameSpacesKnown == FALSE) && (d_adminGetInitialFellowCount(admin) > 0)) { + reschedule = TRUE; + return reschedule; + } + + if (toReport) { + d_printTimedEvent(durability, D_LEVEL_FINEST, "Fellow nameSpaces complete.\n"); + } + + /* Start groupLocalListener; cannot be started multiple times due to listener->attached */ + if (durability->splicedRunning == TRUE) { + d_groupLocalListenerStart(d_subscriberGetGroupLocalListener(subscriber)); + } + + /* Check for group completeness */ + complete = d_adminAreLocalGroupsComplete(durability->admin, FALSE); + + if (!complete) { + if (toReport && (config->tracingVerbosityLevel <= D_LEVEL_FINER)) { + d_printTimedEvent(durability, D_LEVEL_FINER, "Waiting for local groups to get complete...\n"); + } + + if (toReport && (config->tracingVerbosityLevel == D_LEVEL_FINEST)) { + d_sampleChainListenerReportStatus(sampleChainListener); + d_durabilityReportKernelGroupCompleteness(durability); + } + + } else { + c_bool ret; + + /* Wait until the persistent store has marked all relevant + * namespaces as complete and change the state + */ + d_durabilityDetermineNameSpaceCompleteness (durability); + + d_printTimedEvent(durability, D_LEVEL_FINER, "Local groups are complete now.\n"); + d_durabilitySetState(durability, D_STATE_COMPLETE); + ret = u_serviceChangeState(durability->service, STATE_OPERATIONAL); + if (ret) { + d_printTimedEvent(durability, D_LEVEL_INFO, "Durability service up and fully operational.\n"); + d_durabilityDoInitialMerge(durability); + } + } + + /* Update nextReportTime */ + if (toReport) { + /* Set next reporting period over 10 seconds */ + os_duration d = OS_DURATION_INIT(10,0); + conflictResolver->nextReportTime = os_timeMAdd(conflictResolver->nextReportTime, d); + } + + d_adminInitialFellowsDestroy(admin); + + /* Reschedule conflict if local groups are not yet complete */ + reschedule = !complete; + } + return reschedule; +} + +static c_bool +resolveLocalGroupCompleteConflict( + _Inout_ d_conflictResolver conflictResolver, + _Inout_ d_conflict conflict) +{ + d_admin admin; + d_durability durability; + + assert(d_conflictResolverIsValid(conflictResolver)); + assert(d_conflictIsValid(conflict)); + assert(IS_LOCAL_GROUP_COMPLETE_CONFLICT(conflict)); + + admin = conflictResolver->admin; + durability = d_adminGetDurability(admin); + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Resolving local group complete conflict %u (run: %u)\n", + conflict->id, conflict->reQueueCount); + + return FALSE; /* Never reschedule local group conflict. */ +} + +static c_bool +resolveHeartbeatProcessedConflict( + _Inout_ d_conflictResolver conflictResolver, + _Inout_ d_conflict conflict) +{ + d_admin admin; + d_durability durability; + + assert(d_conflictResolverIsValid(conflictResolver)); + assert(d_conflictIsValid(conflict)); + assert(IS_HEARTBEAT_PROCESSED_CONFLICT(conflict)); + + admin = conflictResolver->admin; + durability = d_adminGetDurability(admin); + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Resolving heartbeat processed (for federation %u) conflict %u (run: %u)\n", + conflict->fellowAddr->systemId, conflict->id, conflict->reQueueCount); + + d_durabilityHeartbeatProcessed(durability); + + return FALSE; /* Never reschedule local group conflict. */ +} + +/* Verifies if existing conflict1 can be combined with conflict2. + * + * The caller must ensure that the conflictQueueMutex is taken before + * this function is called + * + * Returns TRUE if can be combined, FALSE otherwise */ +static c_bool +can_combine_conflict(d_conflict conflict1, d_conflict conflict2) +{ + d_durability durability = d_threadsDurability(); + c_bool result = FALSE; + + if ((conflict1->event) != (conflict2->event)) { + /* Conflicts for different events can never be combined */\ + return FALSE; + } + + /* From now on we know that conflict1->event == conflict2->event */ + + if (IS_HEARTBEAT_PROCESSED_CONFLICT(conflict1)) { + /* heartbeat process/federation/initial/local group complete conflicts are never combined */ + return FALSE; + } + + if (IS_MASTER_CONFLICT(conflict1)) { + /* master conclicts can be combined if they are for the same namespace independent of the fellow */ + assert(conflict1->nameSpaceCopy && conflict2->nameSpaceCopy && conflict1->fellowNameSpaceCopy && conflict2->fellowNameSpaceCopy); + result = ((d_nameSpaceCompare(conflict1->nameSpaceCopy, conflict2->nameSpaceCopy) == 0) && + (d_nameSpaceCompare(conflict1->fellowNameSpaceCopy, conflict2->fellowNameSpaceCopy) == 0)); + + } else if (IS_FEDERATION_DISCONNECTED_CONFLICT(conflict1) || IS_INITIAL_CONFLICT(conflict1) || IS_LOCAL_GROUP_COMPLETE_CONFLICT(conflict1)) { + /* federation disconnect/initial/local group complete conflicts are always combined */ + result = TRUE; + + } else if (IS_NATIVE_STATE_CONFLICT(conflict1) || IS_FOREIGN_STATE_CONFLICT(conflict1)) { + /* native/foreign state conflicts can be combined if they are for the same fellow and same namespace */ + result = (d_networkAddressCompare(conflict1->fellowAddr, conflict2->fellowAddr) == 0); + if (result) { + result = ((d_nameSpaceCompare(conflict1->nameSpaceCopy, conflict2->nameSpaceCopy) == 0) && + (d_nameSpaceCompare(conflict1->fellowNameSpaceCopy, conflict2->fellowNameSpaceCopy) == 0)); + } + + } else if (IS_FELLOW_DISCONNECTED_CONFLICT(conflict1) || IS_FELLOW_CONNECTED_CONFLICT(conflict1)) { + /* fellow connected/disconnect conflicts can be combined if they are for the same fellow */ + result = (d_networkAddressCompare(conflict1->fellowAddr, conflict2->fellowAddr) == 0); + + } + + if (result) { + d_printTimedEvent(durability, D_LEVEL_FINER, + "Conflict %d is similar to already existing conflict %d, discarding conflict %d\n", + conflict2->id, conflict1->id, conflict2->id); + } + return result; +} + + +struct findConflictHelper { + d_conflict conflict; + c_bool found; + d_admin admin; +}; + +static void +findConflict( + c_voidp o, + c_voidp userData) +{ + struct findConflictHelper *helper; + d_conflict conflict; + + assert(userData); + + helper = (struct findConflictHelper *)userData; + conflict = d_conflict(o); + + if (helper->conflict) { + d_lockLock(d_lock(conflict)); + /* Only check for combination if not yet combined */ + if (!helper->found) { + helper->found = can_combine_conflict(conflict, helper->conflict); + } + d_lockUnlock(d_lock(conflict)); + } +} + +static void +check_remove_pending_requests( + d_conflictResolver conflictResolver, + d_conflict conflict) +{ + + d_durability durability; + d_fellow fellow; + + assert(d_conflictResolverIsValid(conflictResolver)); + + durability = d_adminGetDurability(conflictResolver->admin); + + /* If my fellow was asymmetrically disconnected from me and I have + * pending unanswered sampleRequests to this fellow, then the fellow might have + * missed some of them. To prevent that I will be waiting indefinitely for + * replies that will never come I must assume that the fellow was disconnected + * and clean up pending chains for this fellow + */ + if (IS_FELLOW_DISCONNECTED_CONFLICT(conflict)) { + fellow = d_adminGetFellow(conflictResolver->admin, conflict->fellowAddr); + if (fellow) { + d_printTimedEvent(durability, D_LEVEL_FINER, + "Fellow %u was asymmetrically disconnected from me while I have outstanding sample requests to this fellow," \ + "clearing pending requests to this fellow\n", + conflict->fellowAddr->systemId); + /* Do as if the fellow was removed without actually removing it + * This will trigger new merges + */ + d_adminAsymRemoveFellow(durability->admin, fellow, FALSE); + d_fellowFree(fellow); + } + } +} + +/** + * \brief Checks if the conflict exists in the queue of conflicts + * + * @return TRUE if the conflict already exists, FALSE otherwise + */ +c_bool +d_conflictResolverConflictExists( + d_conflictResolver conflictResolver, + d_conflict conflict) +{ + struct findConflictHelper helper; + d_durability durability = d_threadsDurability(); + + d_printTimedEvent(durability, D_LEVEL_FINER, "Trying fo find similar conflict as conflict %d\n", conflict->id); + + /* Check the current conflict */ + check_remove_pending_requests(conflictResolver, conflict); + + helper.conflict = conflict; + helper.found = FALSE; + helper.admin = conflictResolver->admin; + + /* Lock the conflict queue to prevent any update to the queue or + * the current conflict */ + os_mutexLock(&helper.admin->conflictQueueMutex); + + /* Check if a similar conflict is currently being processed */ + if (conflictResolver->current_conflict != NULL) { + helper.found = can_combine_conflict(conflictResolver->current_conflict, conflict); + } + + if (!helper.found) { + /* Check if a similar conflict is pending in the queue */ + c_iterWalk(helper.admin->conflictQueue, findConflict, &helper); + } + + /* Unlock the conflict queue*/ + os_mutexUnlock(&helper.admin->conflictQueueMutex); + + return helper.found; +} + +static void +set_current_conflict( + d_conflictResolver conflictResolver, + d_conflict conflict) +{ + assert(d_conflictResolverIsValid(conflictResolver)); + assert(d_conflictIsValid(conflict)); + + /* Only set the current conflict if it was reset previously */ + assert(conflictResolver->current_conflict == NULL); + + os_mutexLock(&conflictResolver->admin->conflictQueueMutex); + conflictResolver->current_conflict = d_conflict(d_objectKeep(d_object(conflict))); + os_mutexUnlock(&conflictResolver->admin->conflictQueueMutex); +} + + +static void +reset_current_conflict( + d_conflictResolver conflictResolver) +{ + assert(d_conflictResolverIsValid(conflictResolver)); + + /* Only reset the current conflict if it was set previously */ + assert(conflictResolver->current_conflict != NULL); + + os_mutexLock(&conflictResolver->admin->conflictQueueMutex); + d_objectFree(d_object(conflictResolver->current_conflict)); + conflictResolver->current_conflict = NULL; + os_mutexUnlock(&conflictResolver->admin->conflictQueueMutex); + +} + +/** + * \brief Main loop to resolve conflicts. + * + * The loop checks every 200ms if there are any conflicts, and if so, + * handles them. + * + * A future extension could be to define various strategies to handle + * conflicts, such as: + * 1) handle conflicts on a first come first serve basis + * 2) wait until no new conflicts appear, then get all pending conflicts, + * analyse the pending conflicts, and decide about a optimal order + * to resolve them. + * 3) Blacklist the fellow that causes the conflict. + * + * NOTE: + * The code is NOT thread safe, but this is OK since the conflict resolution + * code is executed by a single, dedicated thread. + */ +static void* +d_conflictResolverRun( + void* userData) +{ + d_conflictResolver conflictResolver; + os_duration sleepTime = OS_DURATION_INIT(0, 200000000); /* 200 ms */ + d_durability durability = d_threadsDurability(); + d_conflict conflict = NULL, updatedConflict; + d_admin admin; + c_iter toReschedule; + c_ulong startLen, conflictQueueSize; + d_thread self = d_threadLookupSelf (); + + conflictResolver = (d_conflictResolver)userData; + admin = conflictResolver->admin; + durability = d_adminGetDurability(admin); + toReschedule = c_iterNew(NULL); + while ( (!conflictResolver->threadTerminate) && (d_durabilityMustTerminate(durability) == FALSE) ) { + /* Check if a conflict is being resolved. */ + if (!d_conflictResolverHasConflictInProgress(conflictResolver)) { + /* Take a conflict from the queue (if any). */ + os_mutexLock(&admin->conflictQueueMutex); + startLen = c_iterLength(admin->conflictQueue); + conflict = d_conflict(c_iterTakeFirst(admin->conflictQueue)); + os_mutexUnlock(&admin->conflictQueueMutex); + while (conflict && (d_durabilityMustTerminate(durability) == FALSE)) { + d_printTimedEvent(durability, D_LEVEL_FINER, + "Trying to resolve conflict %u.\n", + conflict->id); + /* admin->conflictMonitor is necessarily initialised by + * the time a conflict exists, but currently not at the + * time conflictResolverRun starts + */ + updatedConflict = d_conflictMonitorEvaluateConflict(admin->conflictMonitor, conflict); + if (updatedConflict) { + c_bool reschedule; + + set_current_conflict(conflictResolver, updatedConflict); + switch (updatedConflict->event) { + case D_CONFLICT_NAMESPACE_MASTER : + reschedule = resolveMasterConflict(conflictResolver, updatedConflict); + break; + case D_CONFLICT_NAMESPACE_NATIVE_STATE : + reschedule = resolveNativeStateConflict(conflictResolver, updatedConflict); + break; + case D_CONFLICT_NAMESPACE_FOREIGN_STATE : + reschedule = resolveForeignStateConflict(conflictResolver, updatedConflict); + break; + case D_CONFLICT_FELLOW_DISCONNECTED : + reschedule = resolveFellowDisconnectConflict(conflictResolver, updatedConflict); + break; + case D_CONFLICT_FELLOW_CONNECTED : + reschedule = resolveFellowConnectConflict(conflictResolver, updatedConflict); + break; + case D_CONFLICT_FEDERATION_DISCONNECTED : + reschedule = resolveFederationDisconnectConflict(conflictResolver, updatedConflict); + break; + case D_CONFLICT_INITIAL: + reschedule = resolveInitialConflict(conflictResolver, updatedConflict); + break; + case D_CONFLICT_LOCAL_GROUP_COMPLETE: + reschedule = resolveLocalGroupCompleteConflict(conflictResolver, updatedConflict); + break; + case D_CONFLICT_HEARTBEAT_PROCESSED: + reschedule = resolveHeartbeatProcessedConflict(conflictResolver, updatedConflict); + break; + default: + d_printTimedEvent(durability, D_LEVEL_WARNING, + "Unknown conflict %u (type: %d, nameSpace: '%s', fellow: %u, run: %d). Conflict is dicarded.\n", + updatedConflict->id, updatedConflict->event, updatedConflict->nameSpaceCopy->name, + updatedConflict->fellowAddr->systemId, updatedConflict->reQueueCount); + reschedule = FALSE; + } + if (reschedule) { + reset_current_conflict(conflictResolver); + toReschedule = c_iterAppend(toReschedule, updatedConflict); + + d_printTimedEvent(durability, D_LEVEL_FINER, + "Rescheduling conflict %u\n", + updatedConflict->id); + } else { + reset_current_conflict(conflictResolver); + + d_printTimedEvent(durability, D_LEVEL_FINER, + "Finished solving conflict %u\n", + updatedConflict->id); + + d_conflictFree(updatedConflict); + } + } else { + d_printTimedEvent(durability, D_LEVEL_FINER, + "The conditions for conflict %u do not apply anymore, discarding the conflict\n", + conflict->id); + /* Free the conflict, it is not needed anymore */ + d_conflictFree(conflict); + } + + if (!d_conflictResolverHasConflictInProgress(conflictResolver)) { + /* Get the next conflict */ + os_mutexLock(&admin->conflictQueueMutex); + conflict = d_conflict(c_iterTakeFirst(admin->conflictQueue)); + os_mutexUnlock(&admin->conflictQueueMutex); + } else { + /* No next conflicts */ + conflict = NULL; + } + } + os_mutexLock(&admin->conflictQueueMutex); + while ((updatedConflict = d_conflict(c_iterTakeFirst(toReschedule))) != NULL) { + d_conflictUpdateQueueTime(updatedConflict); + admin->conflictQueue = c_iterAppend(admin->conflictQueue, updatedConflict); + } + /* If the conflict queue became empty then mark all incomplete groups complete */ + conflictQueueSize = c_iterLength(admin->conflictQueue); + os_mutexUnlock(&admin->conflictQueueMutex); + + if(startLen && (conflictQueueSize == 0) && !d_conflictResolverHasConflictInProgress(conflictResolver)) { + d_printTimedEvent(durability, D_LEVEL_FINER, + "Conflict-queue became empty. Marking all namespace kernel groups complete.\n"); + d_adminMarkNameSpaceKernelGroupsCompleteness(admin, TRUE); + d_admin_sync_mergeStates(admin); + } + } /* if */ + d_sleep(self, sleepTime); + } /* while */ + if (conflict) { + d_printTimedEvent(durability, D_LEVEL_FINER, + "Durability is terminating while resolving conflict %u, discarding this conflict\n", + conflict->id); + d_conflictFree(conflict); + } + c_iterFree(toReschedule); + return NULL; +} + + +d_conflictResolver +d_conflictResolverNew( + d_admin admin) +{ + d_conflictResolver conflictResolver = NULL; + os_threadAttr attr; + d_configuration config; + + config = d_durabilityGetConfiguration(admin->durability); + /* Create conflictResolver object */ + conflictResolver = d_conflictResolver(os_malloc(C_SIZEOF(d_conflictResolver))); + if (conflictResolver) { + /* Call super-init */ + d_lockInit(d_lock(conflictResolver), D_CONFLICT_RESOLVER, d_conflictResolverDeinit); + /* Initialize conflictResolver */ + conflictResolver->admin = admin; + conflictResolver->lastTimeChecked = OS_TIMEM_ZERO; + conflictResolver->lastTimeResolved = OS_TIMEM_ZERO; + conflictResolver->totalConflicts = 0; + conflictResolver->threadTerminate = FALSE; + conflictResolver->conflictInProgress = 0; + conflictResolver->current_conflict = NULL; + conflictResolver->nextReportTime = config->startMTime; + + os_threadAttrInit(&attr); + (void) d_threadCreate(&conflictResolver->actionThread, "conflictResolver", + &attr, (void*(*)(void*))d_conflictResolverRun, + (void*)conflictResolver); + } + return conflictResolver; +} + + +void +d_conflictResolverDeinit( + d_object object) +{ + d_conflictResolver conflictResolver; + d_admin admin; + d_durability durability; + os_result osr; + + assert(d_objectIsValid(object, D_CONFLICT_RESOLVER) == TRUE); + + if (object) { + conflictResolver = d_conflictResolver(object); + admin = conflictResolver->admin; + durability = d_adminGetDurability(admin); + + /* Terminate the conflictResolver thread */ + if (os_threadIdToInteger(conflictResolver->actionThread)) { + conflictResolver->threadTerminate = TRUE; + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Waiting for resolver thread to terminate...\n"); + osr = d_threadWaitExit(conflictResolver->actionThread, NULL); + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Resolver thread destroyed (%s).\n", os_resultImage(osr)); + } + d_lockDeinit(d_lock(conflictResolver)); + } +} + + +void d_conflictResolverFree( + d_conflictResolver conflictResolver) +{ + assert(d_conflictResolverIsValid(conflictResolver)); + + d_objectFree(d_object(conflictResolver)); +} + + +void +d_conflictResolverAddConflict( + d_conflictResolver conflictResolver, + d_conflict conflict) +{ + d_admin admin; + + assert(d_conflictResolverIsValid(conflictResolver)); + assert(d_conflictIsValid(conflict)); + + admin = conflictResolver->admin; + d_lockLock(d_lock(conflict)); + conflict->lastQueueTime = os_timeMGet(); /* update the last queue time */ + ++(conflict->reQueueCount); /* update the number of times the conflict is queued */ + d_lockUnlock(d_lock(conflict)); + os_mutexLock(&admin->conflictQueueMutex); + admin->conflictQueue = c_iterAppend(admin->conflictQueue, conflict); + if (c_iterLength(admin->conflictQueue) == 1) { + d_printTimedEvent(d_adminGetDurability(admin), D_LEVEL_FINER, + "Added conflict to empty conflict queue; marking groups incomplete.\n"); + d_adminMarkNameSpaceKernelGroupsCompleteness(admin, FALSE); + } + os_mutexUnlock(&admin->conflictQueueMutex); +} + +void +d_conflictResolverSetConflictInProgress( + d_conflictResolver conflictResolver, + d_conflict conflict) +{ + d_durability durability; + c_ulong conflict_id; + + assert(d_conflictResolverIsValid(conflictResolver)); + + durability = d_adminGetDurability(conflictResolver->admin); + d_lockLock(d_lock(conflictResolver)); + d_lockLock(d_lock(conflict)); + conflict_id = d_conflictGetId(conflict); + if (conflict_id == 0) { + d_printTimedEvent(durability, D_LEVEL_FINER, "Cannot resolve conflict 0, invalid config id\n"); + } else if ((conflictResolver->conflictInProgress != 0) && (conflictResolver->conflictInProgress != conflict_id)) { + d_printTimedEvent(durability, D_LEVEL_FINER, "Cannot resolve conflict %u because conflict %u is being resolved\n", conflict_id, conflictResolver->conflictInProgress); + } else { + /* Solve the conflict. + * Only print a message when the first task of the conflict is being resolved */ + assert((conflictResolver->conflictInProgress == 0) || (conflictResolver->conflictInProgress == conflict_id)); + conflict->nr++; + if (conflictResolver->conflictInProgress == 0) { + d_printTimedEvent(durability, D_LEVEL_FINER, "Start resolving conflict %u\n", conflict_id); + conflictResolver->conflictInProgress = conflict_id; + } else { + d_printTimedEvent(durability, D_LEVEL_FINEST, "Resolving subtask of conflict %u (total: %u subtasks pending)\n", conflict_id, conflict->nr); + } + } + d_lockUnlock(d_lock(conflict)); + d_lockUnlock(d_lock(conflictResolver)); +} + +void +d_conflictResolverResetConflictInProgress( + d_conflictResolver conflictResolver, + d_conflict conflict) +{ + d_durability durability; + c_ulong conflict_id, len; + d_admin admin; + + assert(d_conflictResolverIsValid(conflictResolver)); + + durability = d_adminGetDurability(conflictResolver->admin); + d_lockLock(d_lock(conflictResolver)); + d_lockLock(d_lock(conflict)); + conflict_id = d_conflictGetId(conflict); + if (conflictResolver->conflictInProgress == conflict_id) { + conflict->nr--; + if (conflict->nr == 0) { + d_printTimedEvent(durability, D_LEVEL_FINER, "Stop resolving conflict %u\n", conflictResolver->conflictInProgress); + conflictResolver->conflictInProgress = 0; + admin = conflictResolver->admin; + os_mutexLock(&admin->conflictQueueMutex); + len = c_iterLength(admin->conflictQueue); + os_mutexUnlock(&admin->conflictQueueMutex); + if (len == 0) { + d_printTimedEvent(durability, D_LEVEL_FINER, + "Conflict-queue became empty. Marking all namespace kernel groups complete.\n"); + d_adminMarkNameSpaceKernelGroupsCompleteness(admin, TRUE); + d_admin_sync_mergeStates(admin); + } + } else { + d_printTimedEvent(durability, D_LEVEL_FINEST, "Subtask of conflict %u resolved, still %u subtasks to go\n", conflictResolver->conflictInProgress, conflict->nr); + } + } else { + d_printTimedEvent(durability, D_LEVEL_FINEST, "Cannot stop resolving conflict %u because conflict %u is currently being resolved\n", + conflict_id, conflictResolver->conflictInProgress); + } + d_lockUnlock(d_lock(conflict)); + d_lockUnlock(d_lock(conflictResolver)); +} + +c_bool +d_conflictResolverHasConflictInProgress( + d_conflictResolver conflictResolver) +{ + c_bool inProgress; + + assert(d_conflictResolverIsValid(conflictResolver)); + + d_lockLock(d_lock(conflictResolver)); + inProgress = (conflictResolver->conflictInProgress != 0); + d_lockUnlock(d_lock(conflictResolver)); + + return inProgress; +} + diff --git a/src/services/durability/code/d_dcpsHeartbeatListener.c b/src/services/durability/code/d_dcpsHeartbeatListener.c new file mode 100644 index 000000000..4c2a4d565 --- /dev/null +++ b/src/services/durability/code/d_dcpsHeartbeatListener.c @@ -0,0 +1,502 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "d__dcpsHeartbeatListener.h" +#include "d__subscriber.h" +#include "d__admin.h" +#include "d__listener.h" +#include "d__durability.h" +#include "d_qos.h" +#include "d__waitset.h" +#include "d__misc.h" +#include "d__fellow.h" +#include "d__conflictResolver.h" +#include "u_types.h" +#include "u_participant.h" +#include "u_subscriber.h" +#include "u_dataReader.h" +#include "u_observable.h" +#include "v_builtin.h" +#include "v_event.h" +#include "v_readerSample.h" +#include "v_message.h" +#include "v_kernel.h" +#include "v_observer.h" +#include "os_heap.h" +#include "os_report.h" +#include "v_dataReaderSample.h" +#include "v_dataReaderInstance.h" + +#define d_dcpsHeartbeatListener(_this) ((d_dcpsHeartbeatListener)(_this)) + +#define d_dcpsHeartbeatListenerIsValid(_this) \ + d_listenerIsValidKind(d_listener(_this), D_DCPS_HEARTBEAT_LISTENER) + +C_STRUCT(d_dcpsHeartbeatListener){ + C_EXTENDS(d_listener); + d_waitsetEntity waitsetData; + u_dataReader dataReader; + d_subscriber subscriber; + + /* Federations that have not been discovered by means of the durability + * protocol. They will be discovered by means of the DCPSHeartbeat before + * durability protocol messages will trigger adding of a fellow. To ensure + * no periods of (potential) loss of reliability are missed, this list + * is needed next to the regular fellow administration. + * + * A federation will also be in this list in case no durability service runs + * in that federation. + */ + d_table discoveredFederations; +}; + +static void +processHeartbeat( + v_dataReaderSample heartbeatSample, + d_dcpsHeartbeatListener listener); + +static u_actionResult +takeHeartbeats( + c_object object, + c_voidp copyArg); + +static c_ulong +d_dcpsHeartbeatListenerAction( + u_object o, + u_waitsetEvent event, + c_voidp usrData) +{ + d_dcpsHeartbeatListener listener; + u_result result; + d_admin admin; + d_durability durability; + c_iter heartbeatSamples = c_iterNew(NULL); + + listener = d_dcpsHeartbeatListener(usrData); + + assert(d_dcpsHeartbeatListenerIsValid(listener)); + + d_listenerLock(d_listener(listener)); + /* Read the latest DCPSHeartbeat and process it */ + result = u_dataReaderTake(u_dataReader(o), U_STATE_ANY, takeHeartbeats, heartbeatSamples, OS_DURATION_ZERO); + if (result == U_RESULT_OK) { + v_dataReaderSample sample; + + while ((sample = v_dataReaderSample(c_iterTakeFirst(heartbeatSamples)))) { + processHeartbeat(sample, listener); + c_free(v_readerSampleInstance(sample)); + c_free(sample); + } + } else if (result != U_RESULT_NO_DATA) { + admin = d_listenerGetAdmin(d_listener(listener)); + durability = d_adminGetDurability(admin); + OS_REPORT(OS_ERROR, D_CONTEXT_DURABILITY, result, + "Failed to read data from dcpsHeartbeatReader (result: %s)", u_resultImage(result)); + d_durabilityTerminate(durability, TRUE); + } + d_listenerUnlock(d_listener(listener)); + c_iterFree(heartbeatSamples); + + return event->kind; +} + +static void +d_dcpsHeartbeatListenerDeinit( + d_dcpsHeartbeatListener listener) +{ + assert(d_dcpsHeartbeatListenerIsValid(listener)); + + /* Stop the listener */ + d_dcpsHeartbeatListenerStop(listener); + + if (listener->waitsetData) { + d_waitsetEntityFree(listener->waitsetData); + listener->waitsetData = NULL; + } + if (listener->dataReader) { + u_objectFree(u_object(listener->dataReader)); + listener->dataReader = NULL; + } + if (listener->discoveredFederations) { + d_tableFree(listener->discoveredFederations); + listener->discoveredFederations = NULL; + } + listener->subscriber = NULL; + /* Call super-deinit */ + d_listenerDeinit(d_listener(listener)); + + return; +} + +static c_bool +d_dcpsHeartbeatListenerInit( + d_dcpsHeartbeatListener listener, + d_subscriber subscriber) +{ + d_admin admin; + d_durability durability; + u_participant participant; + c_bool result; + v_readerQos readerQos; + os_threadAttr attr; + v_gid gid; + c_value ps[1]; + + assert(d_subscriberIsValid(subscriber)); + assert(listener); + + /* Call super-init */ + d_listenerInit(d_listener(listener), D_DCPS_HEARTBEAT_LISTENER, subscriber, NULL, + (d_objectDeinitFunc)d_dcpsHeartbeatListenerDeinit); + + result = FALSE; + admin = d_listenerGetAdmin(d_listener(listener)); + durability = d_adminGetDurability(admin); + participant = u_participant(d_durabilityGetService(durability)); + + if (participant != NULL) { + listener->subscriber = subscriber; + listener->discoveredFederations = d_tableNew(d_fellowCompare, d_fellowFree); + assert(listener->discoveredFederations); + + if (subscriber->builtinSubscriber != NULL) { + /* The reader uses V_DURABILITY_VOLATILE for backwards compatibility. + * In order to obtain the new V_DURABILITY_TRANSIENT samples as well, + * a wait_for_historical_data is done. + */ + readerQos = d_readerQosNew(V_DURABILITY_VOLATILE, V_RELIABILITY_BESTEFFORT); + + if(readerQos){ + readerQos->history.v.kind = V_HISTORY_KEEPALL; + + gid = u_observableGid((u_observable)subscriber->builtinSubscriber); + ps[0].kind = V_ULONG; + ps[0].is.ULong = gid.systemId; + + listener->dataReader = u_subscriberCreateDataReader( + subscriber->builtinSubscriber, + "DCPSHeartbeat_Reader", + "select * from " V_HEARTBEATINFO_NAME " where id.systemId <> %0", + ps, 1, readerQos); + + if (listener->dataReader != NULL) { + if (u_entityEnable(u_entity(listener->dataReader)) == U_RESULT_OK) { + os_threadAttrInit(&attr); + listener->waitsetData = d_waitsetEntityNew( + "dcpsHeartbeatListener", + u_object(listener->dataReader), + d_dcpsHeartbeatListenerAction, + V_EVENT_DATA_AVAILABLE, + attr, listener); + assert(listener->waitsetData); + + (void) u_dataReaderWaitForHistoricalData(listener->dataReader, OS_DURATION_ZERO); + result = TRUE; + } + } + u_readerQosFree(readerQos); + } + } + } + return result; +} + +d_dcpsHeartbeatListener +d_dcpsHeartbeatListenerNew( + d_subscriber subscriber) +{ + d_dcpsHeartbeatListener listener; + c_bool success; + + assert(d_subscriberIsValid(subscriber)); + + listener = d_dcpsHeartbeatListener(os_malloc(C_SIZEOF(d_dcpsHeartbeatListener))); + + if(listener){ + success = d_dcpsHeartbeatListenerInit(listener, subscriber); + + if(success != TRUE){ + os_free(listener); + listener = NULL; + } + } + return listener; +} + +void +d_dcpsHeartbeatListenerFree( + d_dcpsHeartbeatListener listener) +{ + assert(d_dcpsHeartbeatListenerIsValid(listener)); + + d_objectFree(d_object(listener)); +} + +c_bool +d_dcpsHeartbeatListenerStop( + d_dcpsHeartbeatListener listener) +{ + c_bool result; + d_admin admin; + d_subscriber subscriber; + d_waitset waitset; + + assert(d_dcpsHeartbeatListenerIsValid(listener)); + + result = FALSE; + + if (listener) { + d_listenerLock(d_listener(listener)); + + if (d_listener(listener)->attached == TRUE) { + admin = d_listenerGetAdmin(d_listener(listener)); + subscriber = d_adminGetSubscriber(admin); + waitset = d_subscriberGetWaitset(subscriber); + d_listenerUnlock(d_listener(listener)); + result = d_waitsetDetach(waitset, listener->waitsetData); + d_listenerLock(d_listener(listener)); + + if (result == TRUE) { + d_listener(listener)->attached = FALSE; + } + } else { + result = TRUE; + } + d_listenerUnlock(d_listener(listener)); + } + return result; +} + +c_bool +d_dcpsHeartbeatListenerStart( + d_dcpsHeartbeatListener listener) +{ + c_bool result; + d_waitset waitset; + u_result ur; + c_iter heartbeatSamples = c_iterNew(NULL); + + assert(d_dcpsHeartbeatListenerIsValid(listener)); + + result = FALSE; + + if (listener) { + d_listenerLock(d_listener(listener)); + + if (d_listener(listener)->attached == FALSE) { + waitset = d_subscriberGetWaitset(listener->subscriber); + result = d_waitsetAttach(waitset, listener->waitsetData); + + if (result == TRUE) { + /* A V_DATA_AVAILABLE event is only generated when new data + * arrives. It is NOT generated when historical data is inserted. + * In case this durability service receives historical + * DCPSHeartbeat from another durability service that + * was started earlier, all these DCPSHeartbeat are + * inserted in the reader at creation time. To read these + * we must explicitly trigger a take action. + */ + ur = u_dataReaderTake(listener->dataReader, U_STATE_ANY, takeHeartbeats, heartbeatSamples, OS_DURATION_ZERO); + if (ur == U_RESULT_OK || ur == U_RESULT_NO_DATA) { + v_dataReaderSample sample; + + while ((sample = v_dataReaderSample(c_iterTakeFirst(heartbeatSamples)))) { + processHeartbeat(sample, listener); + c_free(v_readerSampleInstance(sample)); + c_free(sample); + } + d_listener(listener)->attached = TRUE; + result = TRUE; + } else { + OS_REPORT(OS_ERROR, D_CONTEXT_DURABILITY, ur, + "Failed to read data from dcpsHeartbeatReader (result: %s)", + u_resultImage(ur)); + } + } + } else { + result = TRUE; + } + d_listenerUnlock(d_listener(listener)); + } + c_iterFree(heartbeatSamples); + return result; +} + +static u_actionResult +takeHeartbeats( + c_object object, + c_voidp copyArg) +{ + if (object) { + c_iter heartbeatSamples = (c_iter) copyArg; + (void) c_iterAppend(heartbeatSamples, c_keep(v_dataReaderSample(object))); + /* Because the backref to the instance is not refCounted, also keep the instance itself. */ + (void) c_keep(v_readerSampleInstance(object)); + } + return V_PROCEED; +} + +static void +processHeartbeat( + v_dataReaderSample sample, + d_dcpsHeartbeatListener listener) +{ + d_admin admin; + d_durability durability; + v_dataReaderInstance instance; + v_message message; + v_heartbeatInfoTemplate template; + d_networkAddress address; + d_fellow fellow, existingFellow; + c_long prevDisposeCount; + const struct v_heartbeatInfo* heartbeat; + + assert(sample != NULL); + admin = d_listenerGetAdmin(d_listener(listener)); + durability = d_adminGetDurability(admin); + instance = v_readerSampleInstance(sample); + message = v_dataReaderSampleTemplate(sample)->message; + template = (v_heartbeatInfoTemplate)message; + + if(template){ + heartbeat = &template->userData; + address = d_networkAddressNew(heartbeat->id.systemId, 0, 0); + fellow = d_adminGetFellow(admin, address); + d_printTimedEvent(durability, D_LEVEL_FINE, + "Incoming federation heartbeat for federation '%u', state = '%u', instance state = '%u', noWriterCount = '%d', period = %d.%d\n", + address->systemId, + v_messageState(message), + v_dataReaderInstanceState(instance), + instance->noWritersCount, + heartbeat->period.seconds, + heartbeat->period.nanoseconds); + + if(fellow != NULL) { + if (v_dataReaderInstanceStateTest(instance, L_DISPOSED)) { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Known fellow '%u' has been disconnected, removing it from my administration\n", + address->systemId); + + existingFellow = d_adminRemoveFellow(admin, fellow, FALSE); + + if(existingFellow){ + d_fellowFree(existingFellow); + } + existingFellow = d_tableRemove(listener->discoveredFederations, fellow); + + if(existingFellow){ + d_fellowFree(existingFellow); + } + /* Generate a federation disconnect event */ + d_conflictMonitorCheckFederationDisconnected(admin->conflictMonitor); + } else { + existingFellow = d_tableInsert(listener->discoveredFederations, fellow); + + if(!existingFellow){ + /* Keeping fellow as it has been inserted into the + * table, but will be freed later on. + */ + existingFellow = d_fellow(d_objectKeep(d_object(fellow))); + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Discovered federation '%u' (disposeCount = %d), but already knew fellow.\n", + address->systemId, sample->disposeCount); + (void)d_fellowSetLastDisposeCount(existingFellow, sample->disposeCount); + } else { + prevDisposeCount = d_fellowSetLastDisposeCount(existingFellow, sample->disposeCount); + /* In case the disposeCount has increased, it means + * that the fellow has been disconnected for a while + * and is now connected again before I saw the + * disconnect. It means reliability has been lost for + * a while and I'll have to remove the fellow and + * (re-)align with it. + */ + if(prevDisposeCount != sample->disposeCount){ + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Fellow '%u' got disconnected, but reconnected already before I noticed the disconnect. " + "Removing fellow recover from (potential) loss of reliability and trigger (re)alignment.\n", + address->systemId); + existingFellow = d_adminRemoveFellow(admin, fellow, FALSE); + + if(existingFellow){ + d_fellowFree(existingFellow); + } + /* Generate a federation disconnect event */ + d_conflictMonitorCheckFederationDisconnected(admin->conflictMonitor); + } else { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Fellow '%u' (disposeCount = %d) is still connected.\n", + address->systemId, sample->disposeCount); + } + } + } + d_fellowFree(fellow); + } else if (v_dataReaderInstanceStateTest(instance, L_DISPOSED)) { + fellow = d_fellowNew(address, D_STATE_INIT, FALSE); + existingFellow = d_tableRemove(listener->discoveredFederations, fellow); + d_fellowFree(fellow); + + /* Fellow may never have been seen at all, in which case it + * won't exist in the table; + */ + if(existingFellow){ + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Federation '%u' got disconnected. I don't know any fellow durability service for it.\n", + address->systemId); + d_fellowFree(existingFellow); + } else { + d_printTimedEvent(durability, D_LEVEL_FINE, + "Federation '%u' got disconnected, but I never saw it anyway, so ignoring.\n", + address->systemId); + } + /* Generate a federation disconnect event */ + d_conflictMonitorCheckFederationDisconnected(admin->conflictMonitor); + } else { + fellow = d_fellowNew(address, D_STATE_INIT, FALSE); + existingFellow = d_tableInsert(listener->discoveredFederations, fellow); + + /* Federation already exists */ + if(existingFellow){ + d_fellowFree(fellow); /* throw away the newly created one */ + prevDisposeCount = d_fellowSetLastDisposeCount(existingFellow, sample->disposeCount); + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Updating known federation '%u' (disposeCount: %d -> %d). I haven't discovered any fellow for it yet.\n", + address->systemId, prevDisposeCount, sample->disposeCount); + } else { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Discovered new federation '%u' (disposeCount = %d). I haven't discovered any fellow for it yet.\n", + address->systemId, sample->disposeCount); + (void)d_fellowSetLastDisposeCount(fellow, sample->disposeCount); + } + } + + d_printTimedEvent(durability, D_LEVEL_FINER, + "I currently know %u federations.\n", + d_tableSize(listener->discoveredFederations)); + + if(v_readerSampleTestState(sample, L_VALIDDATA) && c_timeIsInfinite(heartbeat->period)) { + d_conflict conflict = d_conflictNew(D_CONFLICT_HEARTBEAT_PROCESSED, address, NULL, NULL); + d_conflictSetId(conflict, durability); + d_printTimedEvent(durability, D_LEVEL_FINEST, "Adding heartbeat processed (for federation %u) conflict %d to the conflict resolver queue\n", + address->systemId, d_conflictGetId(conflict)); + + d_conflictResolverAddConflict(durability->admin->conflictResolver, conflict); + } + + d_networkAddressFree(address); + } +} diff --git a/src/services/durability/code/d_dcpsPublicationListener.c b/src/services/durability/code/d_dcpsPublicationListener.c new file mode 100644 index 000000000..0172edcaf --- /dev/null +++ b/src/services/durability/code/d_dcpsPublicationListener.c @@ -0,0 +1,409 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "d__dcpsPublicationListener.h" +#include "d__subscriber.h" +#include "d__admin.h" +#include "d__listener.h" +#include "d__durability.h" +#include "d_qos.h" +#include "d__waitset.h" +#include "d__misc.h" +#include "d__fellow.h" +#include "u_participant.h" +#include "u_subscriber.h" +#include "u_dataReader.h" +#include "u_observable.h" +#include "u_group.h" +#include "v_builtin.h" +#include "v_event.h" +#include "v_readerSample.h" +#include "v_message.h" +#include "v_kernel.h" +#include "v_observer.h" +#include "os_heap.h" +#include "os_report.h" +#include "v_dataReaderSample.h" + +#define d_dcpsPublicationListener(_this) ((d_dcpsPublicationListener)(_this)) +#define d_dcpsPublicationListenerIsValid(_this) \ + d_listenerIsValidKind(d_listener(_this), D_DCPS_PUBLICATION_LISTENER) + + +/** + * The dcpsPublicationListener listens to DCPSPublication messages. + * The dcpsPublicationListener is used to learn about new group when + * client durability is enabled + */ +C_STRUCT(d_dcpsPublicationListener){ + C_EXTENDS(d_listener); + d_waitsetEntity waitsetData; + u_dataReader dataReader; + d_subscriber subscriber; +}; + +static u_actionResult processPublication(c_object object,c_voidp copyArg); + +static c_ulong +d_dcpsPublicationListenerAction( + u_object o, + u_waitsetEvent event, + c_voidp usrData) +{ + d_dcpsPublicationListener listener; + u_result result; + d_admin admin; + d_durability durability; + + listener = d_dcpsPublicationListener(usrData); + + assert(d_dcpsPublicationListenerIsValid(listener)); + + d_listenerLock(d_listener(listener)); + /* Read the latest DCPSPublication and process it */ + result = u_dataReaderTake(u_dataReader(o), U_STATE_ANY, processPublication, listener, OS_DURATION_ZERO); + + if (result != U_RESULT_OK && result != U_RESULT_NO_DATA) { + admin = d_listenerGetAdmin(d_listener(listener)); + durability = d_adminGetDurability(admin); + OS_REPORT(OS_ERROR, D_CONTEXT_DURABILITY, result, + "Failed to read data from dcpsPublicationReader (result: %s)", u_resultImage(result)); + d_durabilityTerminate(durability, TRUE); + } + d_listenerUnlock(d_listener(listener)); + + return event->kind; +} + + +static void +d_dcpsPublicationListenerDeinit( + d_dcpsPublicationListener listener) +{ + assert(d_dcpsPublicationListenerIsValid(listener)); + + /* Stop the listener */ + d_dcpsPublicationListenerStop(listener); + + if (listener->waitsetData) { + d_waitsetEntityFree(listener->waitsetData); + listener->waitsetData = NULL; + } + if (listener->dataReader) { + u_objectFree(u_object(listener->dataReader)); + listener->dataReader = NULL; + } + listener->subscriber = NULL; + /* Call super-deinit */ + d_listenerDeinit(d_listener(listener)); + + return; +} + +static c_bool +d_dcpsPublicationListenerInit( + d_dcpsPublicationListener listener, + d_subscriber subscriber) +{ + d_admin admin; + d_durability durability; + u_participant participant; + c_bool result; + v_readerQos readerQos; + os_threadAttr attr; + u_result ur; + v_gid gid; + c_value ps[1]; + + assert(d_subscriberIsValid(subscriber)); + assert(listener); + + /* Call super-init */ + d_listenerInit(d_listener(listener), D_DCPS_PUBLICATION_LISTENER, subscriber, NULL, + (d_objectDeinitFunc)d_dcpsPublicationListenerDeinit); + result = FALSE; + admin = d_listenerGetAdmin(d_listener(listener)); + durability = d_adminGetDurability(admin); + participant = u_participant(d_durabilityGetService(durability)); + if (participant != NULL) { + listener->subscriber = subscriber; + if (subscriber->builtinSubscriber != NULL) { + /* Create a reader that listens to DCPSPublication + * topics. The reader uses the builtin subscriber, and + * only listens to topics that have a different systemId + * than myself. */ + if ((readerQos = d_readerQosNew(V_DURABILITY_TRANSIENT, V_RELIABILITY_RELIABLE)) != NULL) { + readerQos->history.v.kind = V_HISTORY_KEEPLAST; + readerQos->history.v.depth = 1; + gid = u_observableGid((u_observable)subscriber->builtinSubscriber); + ps[0].kind = V_ULONG; + ps[0].is.ULong = gid.systemId; + listener->dataReader = u_subscriberCreateDataReader( + subscriber->builtinSubscriber, + "DCPSPublicationReader", + "select * from " V_PUBLICATIONINFO_NAME " where key.systemId <> %0", + ps, 1, + readerQos); + if (listener->dataReader != NULL) { + ur = u_entityEnable(u_entity(listener->dataReader)); + + if (ur == U_RESULT_OK) { + os_threadAttrInit(&attr); + listener->waitsetData = d_waitsetEntityNew( + "dcpsPublicationListener", + u_object(listener->dataReader), + d_dcpsPublicationListenerAction, + V_EVENT_DATA_AVAILABLE, + attr, listener); + assert(listener->waitsetData); + (void) u_dataReaderWaitForHistoricalData(listener->dataReader, OS_DURATION_ZERO); + result = TRUE; + } else { + u_objectFree(u_object(listener->dataReader)); + listener->dataReader = NULL; + } + } + u_readerQosFree(readerQos); + } + } + } + return result; +} + +d_dcpsPublicationListener +d_dcpsPublicationListenerNew( + d_subscriber subscriber) +{ + d_dcpsPublicationListener listener; + c_bool success; + + assert(d_subscriberIsValid(subscriber)); + + listener = d_dcpsPublicationListener(os_malloc(C_SIZEOF(d_dcpsPublicationListener))); + if (listener) { + success = d_dcpsPublicationListenerInit(listener, subscriber); + if (success != TRUE) { + os_free(listener); + listener = NULL; + } + } + return listener; +} + +void +d_dcpsPublicationListenerFree( + d_dcpsPublicationListener listener) +{ + assert(d_dcpsPublicationListenerIsValid(listener)); + + d_objectFree(d_object(listener)); +} + +c_bool +d_dcpsPublicationListenerStop( + d_dcpsPublicationListener listener) +{ + c_bool result; + d_admin admin; + d_subscriber subscriber; + d_waitset waitset; + + assert(d_dcpsPublicationListenerIsValid(listener)); + + result = FALSE; + + if (listener) { + d_listenerLock(d_listener(listener)); + + if (d_listener(listener)->attached == TRUE) { + admin = d_listenerGetAdmin(d_listener(listener)); + subscriber = d_adminGetSubscriber(admin); + waitset = d_subscriberGetWaitset(subscriber); + d_listenerUnlock(d_listener(listener)); + result = d_waitsetDetach(waitset, listener->waitsetData); + d_listenerLock(d_listener(listener)); + + if (result == TRUE) { + d_listener(listener)->attached = FALSE; + } + } else { + result = TRUE; + } + d_listenerUnlock(d_listener(listener)); + } + return result; +} + +c_bool +d_dcpsPublicationListenerStart( + d_dcpsPublicationListener listener) +{ + c_bool result; + d_waitset waitset; + u_result ur; + + assert(d_dcpsPublicationListenerIsValid(listener)); + + result = FALSE; + + if (listener) { + d_listenerLock(d_listener(listener)); + + if (d_listener(listener)->attached == FALSE) { + waitset = d_subscriberGetWaitset(listener->subscriber); + result = d_waitsetAttach(waitset, listener->waitsetData); + + if (result == TRUE) { + /* A V_DATA_AVAILABLE event is only generated when new data + * arrives. It is NOT generated when historical data is inserted. + * In case this durability service receives historical + * DCPSPublication from another durability service that + * was started earlier, all these DCPSPublications are + * inserted in the reader at creation time. To read these + * we must explicitly trigger a take action. */ + ur = u_dataReaderTake(listener->dataReader, U_STATE_ANY, processPublication, listener, OS_DURATION_ZERO); + + if (ur != U_RESULT_OK && ur != U_RESULT_NO_DATA) { + OS_REPORT(OS_ERROR, D_CONTEXT_DURABILITY, ur, + "Failed to read data from dcpsPublicationReader (result: %s)", + u_resultImage(ur)); + } else { + d_listener(listener)->attached = TRUE; + result = TRUE; + } + } + } else { + result = TRUE; + } + d_listenerUnlock(d_listener(listener)); + } + return result; +} + +static c_bool +create_local_group( + d_durability durability, + char *partition, + char *topic, + v_durabilityKind kind) +{ + u_group ugroup; + c_bool result = TRUE; + + assert(d_durabilityIsValid(durability)); + + OS_UNUSED_ARG(kind); + + ugroup = u_groupNew( + u_participant(d_durabilityGetService(durability)), + partition, topic, 10*OS_DURATION_MILLISECOND); + if (ugroup) { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Group '%s.%s' created locally.\n", + partition, topic); + /* FIXME: enable again after fix is in place + u_objectFree(u_object(ugroup));*/ + } else { + d_printTimedEvent(durability, D_LEVEL_WARNING, + "Group '%s.%s' could NOT be created locally.\n", + partition, topic); + } + return result; +} + + +static u_actionResult +processPublication( + c_object object, + c_voidp copyArg) +{ + d_dcpsPublicationListener listener; + d_admin admin; + d_durability durability; + v_message message; + v_publicationInfoTemplate template; + const struct v_publicationInfo* publication; + c_iter partitions; + v_durabilityKind kind; + d_durabilityKind dkind; + char *topic; + char *partition; + d_group group; + + if (object != NULL) { + listener = d_dcpsPublicationListener(copyArg); + admin = d_listenerGetAdmin(d_listener(listener)); + durability = d_adminGetDurability(admin); + message = v_dataReaderSampleTemplate(object)->message; + template = (v_publicationInfoTemplate)message; + + if (template) { + publication = &template->userData; + d_printTimedEvent(durability, D_LEVEL_FINE, + "Received DCPSPublication for writer (%u,%u,%u) (state=%lu)\n", + publication->key.systemId, + publication->key.localId, + publication->key.serial, + v_messageState(message)); + /* Create local groups for each partition/topic + * combination that matches one or more aligner + * namespaces. Ignore groups for partitions that + * contain matching wildcards. Volatile groups can + * also be ignored, because no the durability service + * will not maintain any historical data for these + * groups. */ + kind = publication->durability.kind; + dkind = d_durabilityKindFromKernel(kind); + topic = publication->topic_name; + partitions = c_iterNew(NULL); + if (!sequenceOfStringCopyOut(&partitions, publication->partition.name)) { + OS_REPORT(OS_WARNING, "processPublication", 0, + "Unable to retrieve the list of partitions from DCPSPublication for writer (%u,%u,%u), skipping", + publication->key.systemId, + publication->key.localId, + publication->key.serial); + c_iterFree(partitions); + return V_PROCEED; + } + while ((partition = c_iterTakeFirst(partitions)) != NULL) { + if ((group = d_adminGetLocalGroup(admin, partition, topic, dkind)) != NULL) { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Group '%s.%s' already locally known, no need to create locally\n", + partition, topic); + } else if (kind == V_DURABILITY_VOLATILE) { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Group '%s.%s' is volatile, no need to create locally\n", + partition, topic); + } else if (!d_adminGroupInAligneeNS(admin, partition,topic)) { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Group '%s.%s' not in alignee namespace, no need to create locally\n", + partition,topic); + } else { + d_printTimedEvent(durability, D_LEVEL_FINER, + "Creating group '%s.%s' with kind %d locally\n", + partition, topic, kind); + /* create a local group */ + (void)create_local_group(durability, partition, topic, kind); + } + os_free(partition); + } /* while */ + c_iterFree(partitions); + } + } + return V_PROCEED; +} diff --git a/src/services/durability/code/d_deleteData.c b/src/services/durability/code/d_deleteData.c new file mode 100644 index 000000000..22c1ff734 --- /dev/null +++ b/src/services/durability/code/d_deleteData.c @@ -0,0 +1,68 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#include "d_deleteData.h" +#include "d_message.h" +#include "d__misc.h" +#include "vortex_os.h" + +d_deleteData +d_deleteDataNew( + d_admin admin, + os_timeW actionTime, + const c_char* partitionExpr, + const c_char* topicExpr) +{ + d_deleteData deleteData = NULL; + + if (admin) { + deleteData = d_deleteData(os_malloc(C_SIZEOF(d_deleteData))); + d_messageInit(d_message(deleteData), admin); + d_timestampFromTimeW(&deleteData->actionTime, &actionTime, IS_Y2038READY(deleteData)); + + if (partitionExpr) { + deleteData->partitionExpr = os_strdup(partitionExpr); + } else { + deleteData->partitionExpr = NULL; + } + if (topicExpr) { + deleteData->topicExpr = os_strdup(topicExpr); + } else { + deleteData->topicExpr = NULL; + } + } + return deleteData; +} + +void +d_deleteDataFree( + d_deleteData deleteData) +{ + if(deleteData){ + d_messageDeinit(d_message(deleteData)); + + if(deleteData->partitionExpr){ + os_free(deleteData->partitionExpr); + deleteData->partitionExpr = NULL; + } + if(deleteData->topicExpr){ + os_free(deleteData->topicExpr); + deleteData->topicExpr = NULL; + } + os_free(deleteData); + } +} diff --git a/src/services/durability/code/d_deleteDataListener.c b/src/services/durability/code/d_deleteDataListener.c new file mode 100644 index 000000000..80f4ebdc7 --- /dev/null +++ b/src/services/durability/code/d_deleteDataListener.c @@ -0,0 +1,374 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#include "d__deleteDataListener.h" +#include "d__readerListener.h" +#include "d__listener.h" +#include "d__admin.h" +#include "d__durability.h" +#include "d__configuration.h" +#include "d__misc.h" +#include "d__fellow.h" +#include "d__actionQueue.h" +#include "d_message.h" +#include "d_object.h" +#include "d_deleteData.h" +#include "d_networkAddress.h" +#include "u_observable.h" +#include "v_entity.h" +#include "v_groupSet.h" +#include "v_group.h" +#include "v_partition.h" +#include "v_topic.h" +#include "v_participant.h" +#include "os_heap.h" + +/** + * Macro that checks the d_deleteDataListener validity. + * Because d_deleteDataListener is a concrete class typechecking is required. + */ +#define d_deleteDataListenerIsValid(_this) \ + d_listenerIsValidKind(d_listener(_this), D_DELETE_DATA_LISTENER) + +/** + * \brief The d_deleteDataListener cast macro. + * + * This macro casts an object to a d_deleteDataListener object. + */ +#define d_deleteDataListener(_this) ((d_deleteDataListener)(_this)) + +C_STRUCT(d_deleteDataListener){ + C_EXTENDS(d_readerListener); +}; + +C_CLASS(deleteGroupData); + +C_STRUCT(deleteGroupData) { + c_char* partitionExpression; + c_char* topicExpression; + os_timeE deleteTime; + d_fellow sender; + d_deleteDataListener listener; +}; + +#define deleteGroupData(d) ((deleteGroupData)(d)) + +static deleteGroupData +deleteGroupDataNew( + const c_char* partitionExpression, + const c_char* topicExpression, + os_timeE deleteTime, + d_fellow sender, + d_deleteDataListener listener) +{ + deleteGroupData data; + + assert(sender); + assert(listener); + assert(d_deleteDataListenerIsValid(listener)); + assert(d_fellowIsValid(sender)); + + data = deleteGroupData(os_malloc(C_SIZEOF(deleteGroupData))); + + if(data){ + if(partitionExpression){ + data->partitionExpression = os_strdup(partitionExpression); + } else { + data->partitionExpression = NULL; + } + if(topicExpression){ + data->topicExpression = os_strdup(topicExpression); + } else { + data->topicExpression = NULL; + } + data->deleteTime = deleteTime; + data->sender = d_fellow(d_objectKeep(d_object(sender))); + data->listener = listener; + } + return data; +} + +static void +deleteGroupDataFree( + deleteGroupData data) +{ + if(data){ + if(data->partitionExpression){ + os_free(data->partitionExpression); + } + if(data->topicExpression){ + os_free(data->topicExpression); + } + if(data->sender){ + d_fellowFree(data->sender); + } + os_free(data); + } + return; +} + +static void +deleteAction( + v_public entity, + c_voidp args) +{ + deleteGroupData data; + c_iter matchingGroups; + v_group group; + v_participant participant; + os_timeE t; + c_value params[2]; + d_admin admin; + c_char *partition, *topic; + + assert(entity != NULL); + assert(C_TYPECHECK(entity, v_participant)); + + data = deleteGroupData(args); + participant = v_participant(entity); + t = data->deleteTime; + admin = d_listenerGetAdmin(d_listener(data->listener)); + + params[0] = c_stringValue(data->partitionExpression); + params[1] = c_stringValue(data->topicExpression); + + matchingGroups = v_groupSetSelect( + v_kernel(v_object(participant)->kernel)->groupSet, + "partition.name like %0 AND topic.name like %1", + params); + group = v_group(c_iterTakeFirst(matchingGroups)); + + while(group){ + partition = v_partitionName(v_groupPartition(group)); + topic = v_topicName(v_groupTopic(group)); + + if(d_adminGroupInAligneeNS (admin, + partition, + topic) == TRUE){ + if(d_fellowIsGroupInNameSpaces(data->sender, + partition, + topic, + D_DURABILITY_ALL) == TRUE){ + v_groupDeleteHistoricalData(group, t); + } + } + c_free(group); + group = v_group(c_iterTakeFirst(matchingGroups)); + } + c_iterFree(matchingGroups); + + return; +} + +static c_bool +deleteGroupDataAction( + d_action action, + c_bool terminate) +{ + deleteGroupData data; + d_durability durability; + d_admin admin; + c_bool callOnceMore; + d_communicationState comState; + + data = deleteGroupData(d_actionGetArgs(action)); + + if(terminate == FALSE){ + admin = d_listenerGetAdmin(d_listener(data->listener)); + durability = d_adminGetDurability(admin); + + if(d_durabilityGetState(durability) == D_STATE_COMPLETE){ + comState = d_fellowGetCommunicationState(data->sender); + + if(comState == D_COMMUNICATION_STATE_APPROVED){ + /*fellow approved and I am complete, so take action now.*/ + (void)u_observableAction(u_observable( + d_durabilityGetService(durability)), + deleteAction, data); + deleteGroupDataFree(data); + callOnceMore = FALSE; + } else if(comState == D_COMMUNICATION_STATE_UNKNOWN){ + /*communication state unknown so far, so try again later.*/ + callOnceMore = TRUE; + } else { + /*fellow not approved, so ignore deletion.*/ + deleteGroupDataFree(data); + callOnceMore = FALSE; + } + } else { + callOnceMore = TRUE; + } + } else { + /*durability is terminating, so clean up data and forget action */ + deleteGroupDataFree(data); + callOnceMore = FALSE; + } + return callOnceMore; +} + +static void +d_deleteDataListenerAction( + d_listener listener, + d_message message) +{ + d_networkAddress sender; + d_fellow fellow; + d_admin admin; + d_durability durability; + d_deleteData delData; + deleteGroupData data; + d_actionQueue queue; + d_action action; + os_duration sleepTime = OS_DURATION_INIT(1, 0); + os_timeW actionTimeW; + os_timeE actionTimeE; + os_duration duration; + + assert(d_deleteDataListenerIsValid(listener)); + + admin = d_listenerGetAdmin(listener); + queue = d_adminGetActionQueue(admin); + durability = d_adminGetDurability(admin); + delData = d_deleteData(message); + sender = d_networkAddressNew(message->senderAddress.systemId, + message->senderAddress.localId, + message->senderAddress.lifecycleId); + + fellow = d_adminGetFellow(admin, sender); + + if(fellow){ + if(d_fellowGetCommunicationState(fellow) == D_COMMUNICATION_STATE_APPROVED){ + d_printTimedEvent(durability, D_LEVEL_FINE, + "Received deleteData message for partition/topic expression '%s.%s'\n", + (delData->partitionExpr) ? delData->partitionExpr : "NULL", + (delData->topicExpr) ? delData->topicExpr : "NULL"); + /* To delete data the v_groupDeleteHistoricalData() is called. + * This function requires a timeE. The deleteData message however + * contains a timeW indicating that all data before this time must + * be purged. Therefore, we need to calculate the corresponding local + * timeE. Note that this only works if clocks on nodes are aligned! */ + d_timestampToTimeW(&actionTimeW, &delData->actionTime, IS_Y2038READY(delData)); + duration = os_timeWDiff(os_timeWGet(), actionTimeW); + actionTimeE = os_timeEAdd(os_timeEGet(), duration); + + data = deleteGroupDataNew(delData->partitionExpr, delData->topicExpr, + actionTimeE, fellow, + d_deleteDataListener(listener)); + action = d_actionNew(os_timeMGet(), sleepTime, deleteGroupDataAction, data); + d_actionQueueAdd(queue, action); + } else { + d_printTimedEvent(durability, D_LEVEL_WARNING, + "Fellow not approved, so ignore the message.\n"); + } + d_fellowFree(fellow); + } else { + d_printTimedEvent(durability, D_LEVEL_WARNING, + "Fellow unknown so far, so ignore the message.\n"); + } + d_networkAddressFree(sender); + + return; +} + +static void +d_deleteDataListenerDeinit( + d_deleteDataListener listener) +{ + assert(d_deleteDataListenerIsValid(listener)); + + /* Stop the deleteDataListener */ + if (d_deleteDataListenerStop(listener)) { + /* Nothing to clean for the deleteDataListener because + * nothing was allocated. + * Call super-deinit */ + d_readerListenerDeinit(d_readerListener(listener)); + } +} + + +static void +d_deleteDataListenerInit( + d_deleteDataListener listener, + d_subscriber subscriber) +{ + os_threadAttr attr; + + /* Do not assert the listener because the initialization + * of the listener has not yet completed */ + + assert(d_subscriberIsValid(subscriber)); + + if (subscriber) { + os_threadAttrInit(&attr); + /* Call super-init */ + d_readerListenerInit( d_readerListener(listener), + D_DELETE_DATA_LISTENER, + d_deleteDataListenerAction, + subscriber, + D_DELETE_DATA_TOPIC_NAME, + D_DELETE_DATA_TOP_NAME, + V_RELIABILITY_RELIABLE, + V_HISTORY_KEEPALL, + V_LENGTH_UNLIMITED, + attr, + (d_objectDeinitFunc)d_deleteDataListenerDeinit); + } +} + +d_deleteDataListener +d_deleteDataListenerNew( + d_subscriber subscriber) +{ + d_deleteDataListener listener; + + listener = NULL; + + if (subscriber) { + /* Allocate deleteDataListener object */ + listener = d_deleteDataListener(os_malloc(C_SIZEOF(d_deleteDataListener))); + if (listener) { + d_deleteDataListenerInit(listener, subscriber); + } + } + return listener; +} + +void +d_deleteDataListenerFree( + d_deleteDataListener listener) +{ + assert(d_deleteDataListenerIsValid(listener)); + + d_objectFree(d_object(listener)); +} + + +c_bool +d_deleteDataListenerStart( + d_deleteDataListener listener) +{ + return d_readerListenerStart(d_readerListener(listener)); +} + + +c_bool +d_deleteDataListenerStop( + d_deleteDataListener listener) +{ + return d_readerListenerStop(d_readerListener(listener)); +} + diff --git a/src/services/durability/code/d_durability.c b/src/services/durability/code/d_durability.c new file mode 100644 index 000000000..8442519bf --- /dev/null +++ b/src/services/durability/code/d_durability.c @@ -0,0 +1,1747 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#include "d_durability.h" +#include "d__durability.h" +#include "d__remoteReaderListener.h" +#include "d__groupLocalListener.h" +#include "d__sampleChainListener.h" +#include "d__sampleRequestListener.h" +#include "d__groupRemoteListener.h" +#include "d__deleteDataListener.h" +#include "d__persistentDataListener.h" +#include "d__groupsRequestListener.h" +#include "d__statusListener.h" +#include "d__nameSpacesRequestListener.h" +#include "d__dcpsHeartbeatListener.h" +#include "d__nameSpacesListener.h" +#include "d__historicalDataRequestListener.h" +#include "d__durabilityStateRequestListener.h" +#include "d__dcpsPublicationListener.h" +#include "d__capabilityListener.h" +#include "d__configuration.h" +#include "d__admin.h" +#include "d__publisher.h" +#include "d__subscriber.h" +#include "d__table.h" +#include "d__misc.h" +#include "d__fellow.h" +#include "d__actionQueue.h" +#include "d__group.h" +#include "d__nameSpace.h" +#include "d__conflictMonitor.h" +#include "d__conflictResolver.h" +#include "d__capability.h" +#include "d__mergeState.h" +#include "d_status.h" +#include "d_groupsRequest.h" +#include "d_nameSpacesRequest.h" +#include "d_message.h" +#include "d_networkAddress.h" +#include "d__thread.h" +#include "u_observable.h" +#include "u_entity.h" +#include "u_durability.h" +#include "u_serviceManager.h" +#include "v_group.h" +#include "v_topic.h" +#include "v_partition.h" +#include "v_durability.h" +#include "v_time.h" +#include "v_entity.h" +#include "os_process.h" +#include "v_builtin.h" +#include "v_groupSet.h" +#include "os_report.h" +#include "os_heap.h" +#include "os_time.h" +#include "d_store.h" +#include "c_iterator.h" +#ifdef INTEGRITY +#include "include/os_getRSObjects.h" +#endif +#ifdef OSPL_ENTRY_OVERRIDE +#include "ospl_entry_override.h" +#endif +/* TODO: The waitForAttachToGroup only supports one service to wait for. This + * must be a set of services. + */ + +static void +durabilityTerminate( + d_durability durability) +{ + d_status status; + d_publisher publisher; + d_networkAddress addr; + + /* Code cloned from d_durabilityWatchSpliceDaemon(). */ + if(durability->admin){ + addr = d_networkAddressUnaddressed(); + publisher = d_adminGetPublisher(durability->admin); + status = d_statusNew(durability->admin); + d_durabilitySetState(durability, D_STATE_TERMINATING); + if (!d_publisherStatusWrite(publisher, status, addr)) { + d_printTimedEvent(durability, D_LEVEL_SEVERE, + "Failed to send d_status message, because durability is terminating.\n"); + OS_REPORT(OS_WARNING, D_CONTEXT_DURABILITY, 0, + "Failed to send d_status message, because durability is terminating."); + } + d_statusFree(status); + d_networkAddressFree(addr); + } + os_mutexLock(&durability->terminateMutex); + durability->splicedRunning = FALSE; + (void)os_condBroadcast(&durability->terminateCondition); + os_mutexUnlock(&durability->terminateMutex); +} + + +static c_bool +checkNameSpaces( + d_fellow fellow, + c_voidp args) +{ + c_bool* ready; + d_communicationState state; + + ready = (c_bool*)args; + state = d_fellowGetCommunicationState(fellow); + + if(state == D_COMMUNICATION_STATE_UNKNOWN){ + *ready = FALSE; + } else { + *ready = TRUE; + } + return *ready; +} + +c_bool +d_durabilityArgumentsProcessing( + int argc, + char * argv[], + c_char ** uri, + c_char ** serviceName ) +{ + c_bool result = FALSE; + + *uri = NULL; + *serviceName = NULL; + + if(argc == 2){ + *serviceName = os_strdup(argv[1]); + result = TRUE; + OS_REPORT(OS_WARNING, D_CONTEXT, 0, + "No URI supplied, using default settings."); + } else if(argc == 3){ + *serviceName = os_strdup(argv[1]); + *uri = os_strdup(argv[2]); + result = TRUE; + } else { + OS_REPORT(OS_ERROR, D_CONTEXT, 0, + "Arguments are missing. Usage: %s []", + argv[0]); + } + return result; +} + +void +d_durabilityWatchSpliceDaemon( + v_serviceStateKind spliceDaemonState, + c_voidp usrData ) +{ + d_durability durability; + + switch(spliceDaemonState){ + case STATE_TERMINATING: + case STATE_TERMINATED: + case STATE_DIED: + durability = (d_durability)usrData; + assert(d_objectIsValid(d_object(durability), D_DURABILITY) == TRUE); + + if (durability) { + d_printTimedEvent(durability, D_LEVEL_INFO, + "Splicedaemon is stopping, terminating durability now...\n"); + durabilityTerminate(durability); + } + break; + default: + break; + } +} + +static c_voidp +d_durabilityUpdateLeaseAndNotifyStatus( + c_voidp args) +{ + d_thread self = d_threadLookupSelf (); + d_durability durability; + d_configuration config; + d_admin admin; + os_duration expiryTime; + os_duration intvCheck, terminateCheck; + os_timeM tNextCheck, tNextRenew, tNextStatus, tNextTerminate; + os_boolean all_is_well = OS_TRUE; + d_status status; + d_publisher publisher; + d_networkAddress addressee; + int resendCount; + os_result waitResult; + int noDeadlockDetection; + c_bool forceStatusUpdate; + + durability = d_durability(args); + if (!d_objectIsValid (d_object (durability), D_DURABILITY)) { + return NULL; + } + config = d_durabilityGetConfiguration(durability); + admin = durability->admin; + publisher = d_adminGetPublisher(admin); + addressee = d_networkAddressUnaddressed (); + status = d_statusNew (admin); + resendCount = 0; + + intvCheck = OS_DURATION_INIT(0, 100000000); /* 100 ms */ + expiryTime = durability->configuration->livelinessExpiryTime; + noDeadlockDetection = (durability->configuration->deadlockDetection==FALSE)?1:0; + + d_threadLivelinessInit(expiryTime); + tNextCheck = tNextRenew = tNextStatus = tNextTerminate = os_timeMGet (); + while (!d_durabilityMustTerminate(durability)) { + os_timeM tNow = os_timeMGet (); + + /* Report thread status every 10 sec. */ + if (os_timeMCompare (tNow, tNextCheck) != OS_LESS) { + tNextCheck = os_timeMAdd (tNextCheck, intvCheck); + all_is_well = d_threadLivelinessCheck (tNow, config->threadLivelinessReportPeriod); + } + + /* Renew lease every livelinessUpdateInterval */ + if (os_timeMCompare (tNow, tNextRenew) != OS_LESS) { + tNextRenew = os_timeMAdd (tNextRenew, durability->configuration->livelinessUpdateInterval); + if (all_is_well || noDeadlockDetection) { + (void)u_serviceRenewLease (durability->service, durability->configuration->livelinessExpiryTime); + } else { + OS_REPORT(OS_WARNING, "d_durabilityUpdateLeaseAndNotifyStatus", 0, + "One or more threads did not proceed, liveliness not asserted"); + } + } + + /* Note this the only location where forceStatusWrite is decremented */ + forceStatusUpdate = (pa_ld32(&durability->forceStatusWrite) > 0); + if (forceStatusUpdate) { + pa_dec32(&durability->forceStatusWrite); + } + + /* Publish status every heartbeatUpdateInterval */ + if (resendCount > 0) { + if (all_is_well || noDeadlockDetection) { + if (d_publisherStatusResend (publisher, status)) { + resendCount = 0; + tNextStatus = os_timeMAdd (tNextStatus, durability->configuration->heartbeatUpdateInterval); + } else { + resendCount++; + if (d_message(status)->senderState == D_STATE_TERMINATING) { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Failed to resend d_status message, because durability is terminating.\n"); + OS_REPORT(OS_WARNING, D_CONTEXT_DURABILITY, 0, + "Failed to send d_status message, because durability is terminating."); + } else if ((resendCount % 5) == 0) { + d_printTimedEvent(durability, D_LEVEL_WARNING, + "Already tried to resend d_status message '%d' times.\n", resendCount); + } + } + } + } else if (os_timeMCompare (tNow, tNextStatus) != OS_LESS || forceStatusUpdate) { + if (all_is_well || noDeadlockDetection) { + if (d_publisherStatusWrite (publisher, status, addressee)) { + tNextStatus = os_timeMAdd (tNextStatus, durability->configuration->heartbeatUpdateInterval); + } else { + resendCount = 1; + if (d_message(status)->senderState == D_STATE_TERMINATING) { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Failed to resend d_status message, because durability is terminating.\n"); + OS_REPORT(OS_WARNING, D_CONTEXT_DURABILITY, 0, + "Failed to send d_status message, because durability is terminating."); + } else { + d_printTimedEvent(durability, D_LEVEL_WARNING, + "Already tried to resend d_status message '%d' times.\n", resendCount); + } + } + } + } + + /* Check for cleanup of terminateFellows every second. */ + terminateCheck = OS_DURATION_INIT(1, 0); /* 1 sec */ + if (os_timeMCompare (tNow, tNextTerminate) != OS_LESS) { + tNextTerminate = os_timeMAdd (tNextTerminate, terminateCheck); + if (all_is_well || noDeadlockDetection) { + d_adminCleanupTerminateFellows(admin); + } + } + + /* splicedRunning flag is also accessed outside the mutex + * lock. This is no problem, protection guarantees no wait + * entry while setting the flag. + */ + os_mutexLock (&durability->terminateMutex); + if (durability->splicedRunning) { + os_timeM tNext = tNextCheck; + os_duration sleepTime; + + if (os_timeMCompare (tNextRenew, tNext) == OS_LESS) { + tNext = tNextRenew; + } + if (os_timeMCompare (tNextStatus, tNext) == OS_LESS) { + tNext = tNextStatus; + } + sleepTime = os_timeMDiff (tNext, tNow); + if (os_durationCompare (sleepTime, OS_DURATION_ZERO) == OS_MORE) { + waitResult = d_condTimedWait(self, + &durability->terminateCondition, + &durability->terminateMutex, sleepTime); + if (waitResult == os_resultFail) { + OS_REPORT(OS_CRITICAL, "d_durabilityUpdateLeaseAndNotifyStatus", 0, + "d_condTimedWait failed"); + os_mutexUnlock (&durability->terminateMutex); + d_durabilityTerminate(durability, TRUE); + os_mutexLock (&durability->terminateMutex); + } + } + } + os_mutexUnlock (&durability->terminateMutex); + } /* while */ + + d_statusFree (status); + d_networkAddressFree (addressee); + + if (all_is_well) { + u_serviceRenewLease (durability->service, 20*OS_DURATION_SECOND); + } + return NULL; +} + +static void +durabilityRegisterNsWalk( + void* o, + c_iterActionArg arg) +{ + d_durability durability; + d_admin admin; + d_nameSpace ns; + + durability = d_durability(arg); + admin = durability->admin; + ns = d_nameSpace(o); + + /* Add namespace to runtime administration */ + d_adminAddNameSpace (admin, ns); +} + +static void +d_durabilityRegisterNameSpaces( + d_durability durability) +{ + d_configuration config; + c_iter nameSpaces; + + config = durability->configuration; + nameSpaces = config->nameSpaces; + + c_iterWalk (nameSpaces, durabilityRegisterNsWalk, durability); +} + +d_durability +d_durabilityNew( + const c_char* uri, + const c_char* serviceName, + c_long domainId) +{ + u_result uresult; + d_durability durability; + os_result osr; + c_bool result, ret; + + durability = NULL; + uresult = u_userInitialise(); + if (uresult == U_RESULT_OK) { + /* Allocate durability object */ + durability = d_durability(os_malloc(C_SIZEOF(d_durability))); + if (durability) { + /* Call super-init */ + d_objectInit(d_object(durability), D_DURABILITY, + (d_objectDeinitFunc)d_durabilityDeinit); + /* Initialize durability */ + durability->state = D_STATE_INIT; + durability->service = NULL; + durability->splicedRunning = TRUE; + durability->configuration = NULL; + durability->admin = NULL; + durability->serviceManager = NULL; + durability->statusThread = OS_THREAD_ID_NONE; + durability->died = FALSE; + durability->myVersion.major = D_DURABILITY_VERSION_MAJOR; + durability->myVersion.minor = D_DURABILITY_VERSION_MINOR; + { + struct _DDS_VendorId_t vendorId = D_DURABILITY_VERSION_VENDOR_ID; + durability->myVersion.vendorId = vendorId; + } + pa_st32(&durability->requestId,0); + pa_st32(&durability->conflictId, 0); + pa_st32(&durability->incarnation, 0); + pa_st32(&durability->forceStatusWrite,0); + /* Create terminate mutex and terminate condition */ + osr = os_mutexInit(&durability->terminateMutex, NULL); + if (osr == os_resultSuccess) { + osr = os_condInit(&durability->terminateCondition, &durability->terminateMutex, NULL ); + } + if (osr == os_resultSuccess) { + d_durabilitySetState(durability, D_STATE_INIT); + /* Has to happen before any thread gets created -- at the time + * of writing this, d_adminNew is the first to do that. + */ + osr = d_threadsInit(durability); + /* From now on threads liveliness is available */ + } + if (osr == os_resultSuccess) { + + /* Note: The following message is never printed because + * durability has not yet read the configuration which + * specifies the location of log file. It would be better + * to buffer the messages until the location of the log file + * has been read and flush the buffer as soon as the log + * file is available. A similar approach is implemented in + * ddsi. + */ + d_printTimedEvent(durability, D_LEVEL_FINER, "Creating user service...\n"); + durability->service = u_durabilityNew(uri, U_DOMAIN_ID_ANY, 30, serviceName, NULL, TRUE); + if (durability->service != NULL) { + ret = u_serviceChangeState(durability->service, STATE_INITIALISING); + if (ret) { + durability->serviceManager = u_serviceManagerNew(u_participant(durability->service)); + d_printTimedEvent(durability, D_LEVEL_FINER, "Loading durability module...\n"); + uresult = u_observableWriteAction(u_observable(durability->service), d_durabilityLoadModule, (c_voidp)&result); + if (uresult == U_RESULT_OK) { + d_printTimedEvent(durability, D_LEVEL_FINER, "Reading configuration...\n"); + if (!(durability->configuration = d_configurationNew(durability, serviceName, domainId))) { + /* Error occurred in loading configuration. */ + uresult = U_RESULT_UNDEFINED; + } else { + d_printTimedEvent(durability, D_LEVEL_FINER, "Starting splicedaemon listener...\n"); + uresult = u_serviceWatchSpliceDaemon(durability->service, d_durabilityWatchSpliceDaemon, durability); + } + } + if ((uresult == U_RESULT_OK) && durability->configuration) { + durability->admin = d_adminNew(durability); + if (durability->admin) { + /* Register configured namespaces with admin */ + d_durabilityRegisterNameSpaces(durability); + /* Now ready to initialize protocol subscriber */ + d_adminInitSubscriber(durability->admin); + /* Initialize listeners */ + d_durabilityInit(durability); + } else { + d_durabilityFree(durability); + durability = NULL; + } + } else { + d_durabilityFree(durability); + durability = NULL; + } + } else { + d_durabilityFree(durability); + durability = NULL; + } + } else { + if (uri) { + OS_REPORT(OS_ERROR, D_CONTEXT, 0, "Could not connect to URI '%s'.", uri); + } else { + OS_REPORT(OS_ERROR, D_CONTEXT, 0, "Could not connect to default URI."); + } + d_durabilityFree(durability); + durability = NULL; + } + } else { + d_durabilityFree(durability); + durability = NULL; + } + } else { + OS_REPORT(OS_ERROR, D_CONTEXT, 0, "Memory allocation failure, unable to start durability."); + } + } + return durability; +} + + +void +d_durabilityInit( + d_durability durability) +{ + d_subscriber subscriber; + os_result osr; + + subscriber = d_adminGetSubscriber(durability->admin); + + if (d_subscriberStartListeners(subscriber)) { + d_printTimedEvent(durability, D_LEVEL_FINER, "Starting subscriber listeners ...\n"); + } else { + d_printTimedEvent(durability, D_LEVEL_SEVERE, "Starting subscriber listeners failed\n"); + } + + if (durability->splicedRunning == TRUE) { + os_threadAttr tattr = durability->configuration->heartbeatScheduling; + + /* Create the status thread that is responsible for sending status + * messages and updating leases + */ + d_printTimedEvent (durability, D_LEVEL_FINER, "Starting lease update and notification of own state...\n"); + if (tattr.schedClass != OS_SCHED_REALTIME && durability->configuration->livelinessScheduling.schedClass == OS_SCHED_REALTIME) { + tattr = durability->configuration->livelinessScheduling; + } + osr = d_threadCreate(&(durability->statusThread), "statusThread", + &tattr, + d_durabilityUpdateLeaseAndNotifyStatus, durability); + if (osr != os_resultSuccess) { + d_printTimedEvent(durability, D_LEVEL_SEVERE, + "Failed to start updating lease and notifying status\n"); + OS_REPORT(OS_ERROR, D_CONTEXT, 0, "Failed to start updating lease and notifying status."); + } + } +} + + +d_connectivity +d_durabilityDetermineConnectivity( + d_durability durability) +{ + d_thread self = d_threadLookupSelf (); + d_nameSpacesRequest nsRequest; + d_networkAddress addr; + c_bool nsComplete; + os_duration sleepTime = OS_DURATION_INIT(0, 200000000); /* 200 ms */ + os_timeM stopTime; + d_publisher publisher; + c_ulong incompatibleCount; + d_connectivity connectivity; + d_networkAddress myAddr; + struct _DDS_Gid_t myServerId; + + d_durabilitySetState(durability, D_STATE_DISCOVER_FELLOWS_GROUPS); + + /* Initially set connectivity to undetermined. Only when + * connectivity can be determined it is assigned another value. + */ + connectivity = D_CONNECTIVITY_UNDETERMINED; + if (durability->splicedRunning == TRUE) { + myAddr = d_adminGetMyAddress(durability->admin); + myServerId = d_durabilityGetMyServerId(durability); + d_printTimedEvent(durability, D_LEVEL_INFO, "My address is: '%u'\n", myAddr->systemId); + d_printTimedEvent(durability, D_LEVEL_FINER, "My server Id is: %lld.%lld\n", myServerId.prefix, myServerId.suffix); + OS_REPORT(OS_INFO, D_SERVICE_NAME, 0, "The durability service can be identified by ID: %u", myAddr->systemId); + d_networkAddressFree(myAddr); + d_printTimedEvent(durability, D_LEVEL_FINE, "Requesting fellow namespaces...\n"); + addr = d_networkAddressUnaddressed(); + publisher = d_adminGetPublisher(durability->admin); + nsRequest = d_nameSpacesRequestNew(durability->admin); + d_publisherNameSpacesRequestWrite(publisher, nsRequest, addr, d_durabilityGetState(durability)); + d_nameSpacesRequestFree(nsRequest); + d_printTimedEvent(durability, D_LEVEL_FINER, "Waiting some time to allow fellows to report...\n"); + + /* Set the InitialWaitingPeriod to allow fellows to report. */ + stopTime = os_timeMGet(); + stopTime = os_timeMAdd(stopTime, durability->configuration->timingInitialWaitPeriod); + /* Wait the InitialWaitingPeriod to allow fellows to report. */ + while ((durability->splicedRunning == TRUE) && (os_timeMCompare(os_timeMGet(), stopTime) == OS_LESS)) { + d_sleep(self, sleepTime); + } + /* Free the network address */ + d_networkAddressFree(addr); + + d_printTimedEvent(durability, D_LEVEL_FINE, + "I now know %u fellows. Wait for fellow namespaces to get complete...\n", + d_adminGetFellowCount(durability->admin)); + nsComplete = TRUE; + d_adminFellowWalk(durability->admin, checkNameSpaces, &nsComplete); + + /* Wait until all fellows are completed. */ + while ((nsComplete == FALSE) && + (durability->splicedRunning == TRUE)) { + d_sleep(self,sleepTime); + /* Check if all fellows are complete */ + d_adminFellowWalk(durability->admin, checkNameSpaces, &nsComplete); + if (d_adminGetFellowCount(durability->admin) == 0) { + nsComplete = TRUE; + } + } + incompatibleCount = d_adminGetIncompatibleStateCount(durability->admin); + + if (incompatibleCount > 0) { + connectivity = D_CONNECTIVITY_INCOMPATIBLE_STATE; + d_printTimedEvent(durability, D_LEVEL_WARNING, + "Unable to start, because %u incompatible fellow states have been detected. " \ + "Restarting now...\n", incompatibleCount); + } else { + incompatibleCount = d_adminGetIncompatibleDataModelCount(durability->admin); + + if (incompatibleCount > 0) { + connectivity = D_CONNECTIVITY_INCOMPATIBLE_DATA_MODEL; + d_printTimedEvent(durability, D_LEVEL_WARNING, + "Unable to start, because %u incompatible data models have been detected. " \ + "Shutting down now...\n", incompatibleCount); + } else { + connectivity = D_CONNECTIVITY_OK; + } + } + } + return connectivity; +} + + +typedef struct nsCompleteWalkData +{ + c_bool confirmed; +} nsCompleteWalkData; + + +/* Check if namespaces are confirmed */ +static void +nameSpaceConfirmedWalk ( + d_nameSpace nameSpace, + c_voidp userData) +{ + /* Check if master is confirmed for namespace */ + if (!d_nameSpaceIsMasterConfirmed(nameSpace)) { + ((struct nsCompleteWalkData*)userData)->confirmed = FALSE; + } +} + +static void +storeNsMarkComplete ( + d_durability durability, + d_store store, + d_nameSpace nameSpace, + c_bool isComplete) +{ + if (d_storeNsMarkComplete (store, nameSpace, isComplete) == D_STORE_RESULT_OK) { + d_printTimedEvent(durability, D_LEVEL_FINER, + "Local copy of namespace '%s' is %scomplete\n", + d_nameSpaceGetName (nameSpace), + isComplete ? "" : "not "); + } else { + d_printTimedEvent(durability, D_LEVEL_SEVERE, + "Failed to mark local copy of namespace '%s' as %scomplete\n", + d_nameSpaceGetName (nameSpace), + isComplete ? "" : "in"); + OS_REPORT(OS_ERROR, D_CONTEXT_DURABILITY, 0, + "Failed to mark local copy of namespace '%s' as %scomplete\n", + d_nameSpaceGetName (nameSpace), + isComplete ? "" : "in"); + } +} + +static void +nameSpaceMarkCompleteness( + d_durability durability, + d_nameSpace nameSpace) +{ + d_durabilityKind durabilityKind; + d_subscriber subscriber; + d_store store = NULL; + d_networkAddress masterAddr; + d_fellow masterFellow; + d_mergeState masterMergeState = NULL; + + durabilityKind = d_nameSpaceGetDurabilityKind(nameSpace); + if ((durabilityKind == D_DURABILITY_PERSISTENT) || + (durabilityKind == D_DURABILITY_ALL)) { + subscriber = d_adminGetSubscriber(durability->admin); + store = d_subscriberGetPersistentStore(subscriber); + } + + /* Check master state of namespace, was it complete during alignment? */ + if (d_nameSpaceGetMasterState(nameSpace) == D_STATE_COMPLETE) { + masterAddr = d_nameSpaceGetMaster(nameSpace); + masterFellow = d_adminGetFellow(durability->admin, masterAddr); + if (masterFellow) { + d_nameSpace masterNameSpace; + masterNameSpace = d_fellowGetNameSpace(masterFellow, nameSpace); + if (masterNameSpace) { + masterMergeState = d_nameSpaceGetMergeState(masterNameSpace, NULL); + } + d_fellowFree(masterFellow); + } + d_networkAddressFree(masterAddr); + + if (masterMergeState) { + d_nameSpaceSetMergeState(nameSpace, masterMergeState); + d_printTimedEvent(durability, D_LEVEL_FINER, + "Namespace '%s' complete, set state to %d\n", nameSpace->name, masterMergeState->value); + d_mergeStateFree(masterMergeState); + } + + if (store) { + storeNsMarkComplete(durability, store, nameSpace, TRUE); + } + } else if (store) { + /* Mark namespace incomplete */ + storeNsMarkComplete(durability, store, nameSpace, FALSE); + } +} + +void +d_durabilityDetermineNameSpaceCompleteness( + d_durability durability) +{ + d_thread self = d_threadLookupSelf (); + d_admin admin = durability->admin; + nsCompleteWalkData walkData; + os_duration sleepTime = OS_DURATION_INIT(0, 100000000); /* 100 ms */ + c_iter nameSpaces; + d_nameSpace nameSpace; + + do { + d_sleep(self, sleepTime); + /* Reset confirmed status to true */ + walkData.confirmed = TRUE; + d_adminNameSpaceWalk (admin, nameSpaceConfirmedWalk, &walkData); + } while (!walkData.confirmed && durability->splicedRunning); + + nameSpaces = d_adminNameSpaceCollect(admin); + while ((nameSpace = c_iterTakeFirst(nameSpaces))) { + nameSpaceMarkCompleteness(durability, nameSpace); + d_nameSpaceFree(nameSpace); + } + c_iterFree(nameSpaces); +} + + +static c_bool +collectNameSpaces( + d_nameSpace nameSpace, + void* userData) +{ + c_iter nameSpaces; + + nameSpaces = (c_iter)userData; + assert(nameSpaces != NULL); + (void) c_iterInsert(nameSpaces, d_objectKeep(d_object(nameSpace))); + + return TRUE; +} + + +static c_bool +collectFellows( + d_fellow fellow, + void* userData) +{ + c_iter fellows; + + fellows = (c_iter)userData; + (void) c_iterInsert(fellows, d_objectKeep(d_object(fellow))); + + return TRUE; +} + + +void +d_durabilityDoInitialMerge( + d_durability durability) +{ + d_thread self = d_threadLookupSelf (); + c_iter fellows, fellowNameSpaces; + d_fellow fellow; + d_name fellowRole; + d_nameSpace nameSpace, fellowNameSpace; + d_networkAddress fellowAddress, fellowMasterAddress; + d_admin admin; + + admin = durability->admin; + fellows = c_iterNew(NULL); + d_adminFellowWalk(admin, collectFellows, fellows); + fellow = d_fellow(c_iterTakeFirst(fellows)); + while (fellow) { + if (d_fellowGetCommunicationState(fellow) == D_COMMUNICATION_STATE_APPROVED) { + /* If communication state is approved all fellow namespaces are received and fellowRole must be + * available. + */ + fellowRole = d_fellowGetRole(fellow); + if (fellowRole && strcmp(durability->configuration->role, fellowRole) != 0) { + fellowAddress = d_fellowGetAddress(fellow); + fellowNameSpaces = c_iterNew(NULL); + (void)d_fellowNameSpaceWalk(fellow, collectNameSpaces, fellowNameSpaces); + fellowNameSpace = d_nameSpace(c_iterTakeFirst(fellowNameSpaces)); + while (fellowNameSpace) { + fellowMasterAddress = d_nameSpaceGetMaster(fellowNameSpace); + if (d_networkAddressEquals(fellowAddress, fellowMasterAddress)) { + d_printTimedEvent(durability, D_LEVEL_FINE, + "Investigating initial merge with fellow %u in role %s for nameSpace %s.\n", + fellowAddress->systemId, fellowRole, + d_nameSpaceGetName(fellowNameSpace)); + /* Get the nameSpace with the same name as the fellow's nameSpace */ + nameSpace = d_adminGetNameSpace(admin, d_nameSpaceGetName(fellowNameSpace)); + if (nameSpace) { + d_adminReportMaster(admin, fellow, nameSpace); + d_nameSpaceFree(nameSpace); + } + } + d_networkAddressFree(fellowMasterAddress); + d_nameSpaceFree(fellowNameSpace); + fellowNameSpace = d_nameSpace(c_iterTakeFirst(fellowNameSpaces)); + } + c_iterFree(fellowNameSpaces); + d_networkAddressFree(fellowAddress); + } + d_fellowFree(fellow); + fellow = d_fellow(c_iterTakeFirst(fellows)); + /* If state is unknown, wait until communication is either approved or rejected */ + } else if (d_fellowGetCommunicationState(fellow) == D_COMMUNICATION_STATE_UNKNOWN && + d_fellowGetState(fellow) != D_STATE_TERMINATED) { + os_duration waitTime = OS_DURATION_INIT(0, 100000000); /* 100 ms */ + d_sleep(self, waitTime); + /* Communication with fellow is not approved. Move to next fellow. */ + } else { + d_fellowFree(fellow); + fellow = d_fellow(c_iterTakeFirst(fellows)); + } + } + c_iterFree(fellows); +} + +/* Below code assumes the V_ALIGNSTATE enum to start with 0. V_ALIGNSTATE_COUNT + * should be the last (unused) label. No easy way to assert on that. + */ +struct alignstate_order_constraint { + char require_V_ALIGNSTATE_INCOMPLETE_eq_0 [V_ALIGNSTATE_INCOMPLETE == 0]; + char non_empty_dummy_last_member[1]; +}; + +struct completeness { + c_iter alignState[V_ALIGNSTATE_COUNT]; + os_uint32 psc; +}; + +static c_bool +collectGroups ( + c_object o, + c_voidp arg) +{ + v_group g; + struct completeness *c = (struct completeness *)arg; + + g = v_group(o); + if(v_topicGetQos(v_groupTopic(g))->durability.v.kind != V_DURABILITY_VOLATILE) { + c->alignState[g->alignState] = c_iterAppend(c->alignState[g->alignState], os_strdup(v_groupName(g))); + } + + return TRUE; +} + +static void +d__durabilityCollectCompleteness ( + v_public _this, + void *varg) +{ + v_kernel k; + struct completeness *c = (struct completeness *)varg; + + k = v_objectKernel(_this); + assert(k != NULL); + assert(v_kernelHasDurabilityService(k)); + + c->psc = pa_ld32(&k->purgeSuppressCount); + + v_groupSetWalk(k->groupSet, &collectGroups, varg); +} + +void +d_durabilityReportKernelGroupCompleteness ( + _In_ d_durability durability) +{ + u_result result; + struct completeness completeness; + static const struct completeness zeroed; + char *gn; + char *str[V_ALIGNSTATE_COUNT]; + size_t gnLen, len; + int pos; + unsigned int i; + + completeness = zeroed; + result = u_observableAction (u_observable (durability->service), &d__durabilityCollectCompleteness, &completeness); + if(result == U_RESULT_OK) { + for(i = 0; i < V_ALIGNSTATE_COUNT; i++ ) { + len = strlen(v_alignStateImage(i)) + strlen(": "); + str[i] = os_malloc(len + 1); + pos = snprintf(str[i], len + 1, "%s: ", v_alignStateImage(i)); + while((gn = c_iterTakeFirst(completeness.alignState[i])) != NULL) { + gnLen = strlen(gn) + 2; + len = gnLen + len; + str[i] = os_realloc(str[i], len + 1); + pos += snprintf(str[i] + pos, gnLen + 1, "%s, ", gn) ; + os_free(gn); + } + c_iterFree(completeness.alignState[i]); + str[i][pos - 2] = '\0'; + } + + for(i = 0; i < V_ALIGNSTATE_COUNT; i++) { + d_printTimedEvent(durability, D_LEVEL_FINER, "%s\n", str[i]); + os_free(str[i]); + } + d_printTimedEvent(durability, D_LEVEL_FINEST, "Kernel purgeSuppressionCount = %u\n", completeness.psc); + } else { + d_printTimedEvent(durability, D_LEVEL_SEVERE, "d_durabilityReportKernelGroupCompleteness failed to access kernel: %s. \n", u_resultImage(result)); + } + return; +} + +void +d_durabilityDeinit( + d_durability durability) +{ + d_status status; + d_networkAddress addr; + d_subscriber subscriber; + d_admin admin; + + assert(d_durabilityIsValid(durability)); + + /* Durability is about to terminate. + * To clean up resources we first stop as many threads as possible + * before actually freeing resources. In this way we avoid that + * a resources is freed while another tread still holds references + * to this this resources. Once all threads are stopped it is safe + * to clean up. + * The persistenDataListener() is an exception to this rule. In case + * there is still persistent data available in the persistent data + * queue when durability is about to terminate, then part of the + * ServiceTerminatePeriod is used to persist as many samples as + * possible. To prevent that other listeners will not be freed + * while persisting data we free the persistentDataListener + * as the last listener. + */ + + /* Set state to terminating and make sure that threads testing + * splicedRunning will stop + */ + d_durabilitySetState(durability, D_STATE_TERMINATING); + os_mutexLock(&durability->terminateMutex); + durability->splicedRunning = FALSE; + (void)os_condBroadcast(&durability->terminateCondition); + os_mutexUnlock(&durability->terminateMutex); + + /* Stop the heartbeat publication thread */ + if (durability->service) { + u_serviceChangeState(durability->service, STATE_TERMINATING); + u_serviceWatchSpliceDaemon(durability->service, NULL, durability); + } + if (os_threadIdToInteger(durability->statusThread)) { + d_threadWaitExit(durability->statusThread, NULL); + } + if (durability->admin) { + admin = durability->admin; + assert(d_adminIsValid(admin)); + subscriber = d_adminGetSubscriber(admin); + assert(d_subscriberIsValid(subscriber)); + + /* Publish the last known status to the fellows */ + status = d_statusNew(admin); + addr = d_networkAddressUnaddressed(); + if (!d_publisherStatusWrite(d_adminGetPublisher(admin), status, addr)) { + d_printTimedEvent(durability, D_LEVEL_SEVERE, + "Failed to send d_status message, because durability is terminating.\n"); + OS_REPORT(OS_WARNING, D_CONTEXT_DURABILITY, 0, + "Failed to send d_status message, because durability is terminating."); + } + + d_networkAddressFree(addr); + d_statusFree(status); + + /* we need to disable and free the heartbeat listener first as it is dependent on the + * conflictresolver and its not useful to process heartbeats during termination */ + if (subscriber->dcpsHeartbeatListener) { + d_dcpsHeartbeatListenerStop(subscriber->dcpsHeartbeatListener); + d_dcpsHeartbeatListenerFree(subscriber->dcpsHeartbeatListener); + subscriber->dcpsHeartbeatListener = ((void *)0); + } + + d_subscriberStopListeners(subscriber); + + /* Destroy the admin */ + d_printTimedEvent(durability, D_LEVEL_FINE, "destroying administration...\n"); + d_adminFree(durability->admin); + d_printTimedEvent(durability, D_LEVEL_FINE, "administration destroyed\n"); + durability->admin = NULL; + } + /* Destroy serviceManager */ + if (durability->serviceManager) { + u_objectFree(durability->serviceManager); + durability->serviceManager = NULL; + } + /* Signal the service state change to the splice daemon. + * From this point onwards the splice daemon may clean up + * the service, and the service should not access shared + * memory any more state to splice daemon + */ + if (durability->service) { + if (!durability->died) { + /* Apparently the service has terminated gracefully */ + u_serviceChangeState(durability->service, STATE_TERMINATED); + d_durabilitySetState(durability, D_STATE_TERMINATED); + } else { + /* Apparently something bad has happened.*/ + u_serviceChangeState(durability->service, STATE_DIED); + } + u_objectFree(u_object(durability->service)); + durability->service = NULL; + } + /* Clear the threads management. */ + d_threadsDeinit(); + /* Clean up the configuration */ + if (durability->configuration) { + d_configurationFree(durability->configuration); + durability->configuration = NULL; + } + /* Destroy mutex and condition */ + (void)os_condDestroy(&durability->terminateCondition); + (void)os_mutexDestroy(&durability->terminateMutex); + /* Print message BEFORE the super class is destroyed, + * because that frees the durability object + */ + d_printTimedEvent(durability, D_LEVEL_FINE, "Durability destroyed\n"); + /* Call super-deinit */ + d_objectDeinit(d_object(durability)); +} + + +void +d_durabilityFree( + d_durability durability) +{ + assert(d_durabilityIsValid(durability)); + + d_objectFree(d_object(durability)); +} + + +void +d_durabilityLoadModule( + v_public entity, + c_voidp args /* c_bool */) +{ + c_base base; + c_bool *result = (c_bool *)args; + c_metaObject hd_obj; + + base = c_getBase((c_object)entity); + /* Load the durability odl definitions. */ + *result = loaddurabilityModule2(base); + if (*result) { + /* The client durability idl definitions should already + * have been loaded by the kernel. + */ + hd_obj = c_metaResolve(c_metaObject(base),"DDS::HistoricalData"); + if (hd_obj == NULL) { + *result = FALSE; + OS_REPORT(OS_ERROR, D_CONTEXT, 0, + "Failed to resolve client durability module"); + } + c_free(hd_obj); + } else { + OS_REPORT(OS_ERROR, D_CONTEXT, 0, + "Failed to load durability module"); + } +} + +d_configuration +d_durabilityGetConfiguration( + d_durability durability) +{ + d_configuration config = NULL; + + assert(d_objectIsValid(d_object(durability), D_DURABILITY) == TRUE); + + if(durability){ + config = durability->configuration; + } + return config; +} + + +static os_result +exitRequestHandler( + os_callbackArg ignore, + void *callingThreadContext, + void * arg) +{ + d_durability durability = (d_durability)arg; + + OS_UNUSED_ARG(callingThreadContext); + OS_UNUSED_ARG(ignore); + + assert(durability); + + /* Terminate durability */ + os_mutexLock(&durability->terminateMutex); + durability->splicedRunning = FALSE; + (void)os_condBroadcast(&durability->terminateCondition); + os_mutexUnlock(&durability->terminateMutex); + + OS_REPORT(OS_INFO, "Durability Exit Handler", 0, "Initiated Durability Service termination..."); + + return os_resultSuccess; +} + +#if 0 /* Need to review if this is still required. */ +static os_result +ExceptionRequestHandler( + void * arg) +{ + d_durability durability = (d_durability)arg; + + assert(durability); + + u_serviceChangeState(durability->service, STATE_DIED); + + if (durability->oldExceptionHandlerInfo.callback) { + return durability->oldExceptionHandlerInfo.callback(durability->oldExceptionHandlerInfo.arg); + } else { + return os_resultSuccess; + } +} +#endif + +OPENSPLICE_SERVICE_ENTRYPOINT (ospl_durability, durability) +{ + c_char *uri = NULL; + c_char *serviceName; + d_connectivity connectivity; + c_bool stop, success=TRUE; + c_ulong maxTries, tryCount; + int result = 0; + c_long domainId = 1; + d_durability durability; + int enable_allocation_report = 0; + d_conflict conflict; + + OS_UNUSED_ARG(enable_allocation_report); /* to avoid build failure in case of release builds using -Werror */ + + { + char *p; + enable_allocation_report = ((p = os_getenv ("OSPL_DURABILITY_ALLOCATION_REPORT")) != NULL && atoi (p) != 0) ? 1 : 0; + } + + /** + * Expecting: durability + */ + + success = d_durabilityArgumentsProcessing(argc, argv, &uri, &serviceName); + + if(success == TRUE){ + stop = FALSE; + maxTries = 10; + tryCount = 0; + domainId = 1; + +#ifdef EVAL_V + OS_REPORT(OS_INFO,"d_durability", 0, + "+++++++++++++++++++++++++++++++++++" OS_REPORT_NL + "++ durability EVALUATION VERSION ++" OS_REPORT_NL + "+++++++++++++++++++++++++++++++++++\n"); +#endif + + while((stop == FALSE) && (tryCount < maxTries) ){ + stop = TRUE; + tryCount++; + + durability = d_durabilityNew(uri, serviceName, domainId); + + if(durability){ + os_signalHandlerExitRequestHandle erh = os_signalHandlerExitRequestHandleNil; + d_thread self = d_threadLookupSelf (); + + if(!os_serviceGetSingleProcess()){ + erh = os_signalHandlerRegisterExitRequestCallback(exitRequestHandler, NULL, NULL, NULL, durability); + } + + connectivity = d_durabilityDetermineConnectivity(durability); + if((connectivity == D_CONNECTIVITY_OK) && (durability->splicedRunning == TRUE)){ + conflict = d_conflictNew(D_CONFLICT_INITIAL, NULL, NULL, NULL); + d_conflictSetId(conflict, durability); + d_printTimedEvent(durability, D_LEVEL_FINER, "Initial conflict created, conflict %d created\n", + d_conflictGetId(conflict)); + d_printTimedEvent(durability, D_LEVEL_FINER, "Adding conflict %d to the conflict resolver queue\n", + d_conflictGetId(conflict)); + + d_conflictResolverAddConflict(durability->admin->conflictResolver, conflict); + + os_mutexLock(&durability->terminateMutex); + while(durability->splicedRunning == TRUE){ + d_condWait(self, &durability->terminateCondition, &durability->terminateMutex); + } + os_mutexUnlock(&durability->terminateMutex); + } else if((connectivity == D_CONNECTIVITY_INCOMPATIBLE_STATE) && (durability->splicedRunning == TRUE)){ + d_printTimedEvent(durability, D_LEVEL_WARNING, "State is incompatible, restarting now...\n"); + stop = FALSE; + } + + os_signalHandlerUnregisterExitRequestCallback(erh); + + d_durabilityFree(durability); + } else { + result = 2; + } + } + if(uri){ + os_free(uri); + } + if(serviceName){ + os_free(serviceName); + } + } else { + result = 1; + } + assert(d_objectValidate(0, enable_allocation_report)); + + return result; +} + +u_service +d_durabilityGetService( + d_durability durability) +{ + assert(d_objectIsValid(d_object(durability), D_DURABILITY) == TRUE); + return durability->service; +} + +d_serviceState +d_durabilityGetState( + d_durability durability) +{ + assert(d_durabilityIsValid(durability)); + + return durability->state; +} + +c_bool +d_durabilityMustTerminate( + d_durability durability) +{ + c_bool result; + + assert(d_objectIsValid(d_object(durability), D_DURABILITY) == TRUE); + + if(durability->splicedRunning == FALSE){ + result = TRUE; + } else { + result = FALSE; + } + return result; +} + +void +d_durabilityTerminate( + d_durability durability, + c_bool died) +{ + assert(d_objectIsValid(d_object(durability), D_DURABILITY) == TRUE); + + if (! died) { + /* The durability service is in a state that is incompatible with + * its configuration, e.g., because the time to wait for an aligner + * is exceeded and no aligner is found. Terminate and report the service + * state of durability as STATE_INCOMPATIBLE_CONFIGURATION. + */ + d_printTimedEvent(durability, D_LEVEL_SEVERE, + "An incompatibility with the configuration was detected; terminating and reporting as incompatible configuration.\n"); + u_serviceChangeState(durability->service, STATE_INCOMPATIBLE_CONFIGURATION); + } else { + /* In all other cases something bad happened. Terminate the durability + * service and report as died. We cannot set the service state of + * durability to DIED yet because this will signal the splice daemon + * to free shared memory while durability may not have finished + * cleaning up! Therefore we postpone setting the service state + * state to died when durability is de-initialized (see + * d_durabilityDeinit). + */ + d_printTimedEvent(durability, D_LEVEL_SEVERE, + "Unrecoverable error occurred; terminating and reporting as died.\n"); + durability->died = TRUE; + } + os_mutexLock(&durability->terminateMutex); + durability->splicedRunning = FALSE; + (void)os_condBroadcast(&durability->terminateCondition); + os_mutexUnlock(&durability->terminateMutex); +} + +void +d_durabilitySetState( + d_durability durability, + d_serviceState state) +{ + d_serviceState curState; + + assert(d_durabilityIsValid(durability)); + + /* Log and broadcast state changes, including the + * initial state change to D_STATE_INIT that occurs + * when durability starts + */ + curState = d_durabilityGetState(durability); + if ((state == D_STATE_INIT) || (curState != state)) { + d_printTimedEvent(durability, D_LEVEL_INFO, "----LEAVING STATE----\n\n\n"); + durability->state = state; + d_printTimedEvent(durability, D_LEVEL_INFO, "----ENTERING STATE----\n"); + /* Broadcast the state, but only if all listeners are + * initialized and the publisher is not destroyed yet */ + if ((state > D_STATE_INIT) && (state < D_STATE_TERMINATING)) { + d_status status; + d_networkAddress addr; + d_publisher publisher; + + addr = d_networkAddressUnaddressed(); + status = d_statusNew(durability->admin); + publisher = d_adminGetPublisher(durability->admin); + if (!d_publisherStatusWrite(publisher, status, addr)) { + d_printTimedEvent(durability, D_LEVEL_SEVERE, + "Failed to write d_status message when updating state.\n"); + pa_inc32(&durability->forceStatusWrite); + } + d_statusFree(status); + d_networkAddressFree(addr); + } + } +} + +void +d_durabilityHeartbeatProcessed( + _In_ d_durability durability) +{ + os_uint32 newCount; + u_result r; + + r = u_durabilityHeartbeatProcessed(durability->service, &newCount); + if(r == U_RESULT_OK) { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "PurgeSuppressionCount lowered to %u.\n", newCount); + } else { + d_printTimedEvent(durability, D_LEVEL_SEVERE, + "Failed to lower purgeSuppressionCount, u_durabilityHeartbeatProcessed(...) returned %s.\n", + u_resultImage(r)); + OS_REPORT(OS_FATAL, D_CONTEXT_DURABILITY, r, + "Failed to lower purgeSuppressionCount, u_durabilityHeartbeatProcessed(...) returned %s.", + u_resultImage(r)); + d_durabilityTerminate(durability, TRUE); + } +} + + + +c_bool +d_durabilityWaitForAttachToGroup( + d_durability durability, + v_group group) +{ + d_thread self = d_threadLookupSelf (); + v_serviceStateKind serviceStateKind; + c_iter services; + c_char *name, *partition, *topic; + c_bool result; + os_timeM endTime; + os_duration waitTime = OS_DURATION_INIT(0, 100000000); + v_groupAttachState attachState; + + if(c_iterLength(durability->configuration->services) > 0){ + /* Wait for networkMaxWaitTime. */ + endTime = os_timeMAdd(os_timeMGet(), durability->configuration->networkMaxWaitTime); + result = FALSE; + services = c_iterCopy(durability->configuration->services); + name = c_iterTakeFirst(services); + while ((name) && (!d_durabilityMustTerminate(durability))) { + serviceStateKind = u_serviceManagerGetServiceStateKind( + durability->serviceManager, name); + + switch (serviceStateKind) { + case STATE_INITIALISING: + case STATE_OPERATIONAL: + case STATE_NONE: /* also wait with STATE_NONE, because networking might not have been started up yet */ + attachState = v_groupServiceGetAttachState(group, name); + + switch(attachState){ + case V_GROUP_ATTACH_STATE_UNKNOWN: + if(os_timeMCompare(os_timeMGet(), endTime) == OS_LESS){ + d_sleep(self, waitTime); /* Try again after waitTime*/ + } else { + OS_REPORT(OS_WARNING, D_CONTEXT, 0, + "Service '%s' did NOT attach to the group '%s.%s' within time range.\n", + name, v_entity(group->partition)->name, v_entity(group->topic)->name); + d_printTimedEvent(durability, D_LEVEL_WARNING, + "Service '%s' did NOT attach to the group within time range.\n", + name); + name = (c_char*)c_iterTakeFirst(services); + } + break; + case V_GROUP_ATTACH_STATE_ATTACHED: + result = TRUE; + d_printTimedEvent(durability, D_LEVEL_FINER, + "Service '%s' has attached to group %s.%s.\n", + name, v_entity(group->partition)->name, v_entity(group->topic)->name); + name = (c_char*)c_iterTakeFirst(services); + break; + case V_GROUP_ATTACH_STATE_NO_INTEREST: + d_printTimedEvent(durability, D_LEVEL_FINER, + "Service '%s' has no interest in group %s.%s.\n", + name, v_entity(group->partition)->name, v_entity(group->topic)->name); + name = (c_char*)c_iterTakeFirst(services); + break; + } + break; + case STATE_INCOMPATIBLE_CONFIGURATION: + case STATE_TERMINATING: + case STATE_TERMINATED: + case STATE_DIED: + default: + d_printTimedEvent(durability, D_LEVEL_WARNING, + "Not waiting for service '%s' to attach to the group\n", name); + OS_REPORT(OS_WARNING, D_CONTEXT_DURABILITY, 0, + "Not waiting for service %s to attach to the group.", name); + name = (c_char*)c_iterTakeFirst(services); + break; + } + } + c_iterFree(services); + } else { + result = TRUE; + } + + if(result == TRUE) { + partition = v_entity(group->partition)->name; + topic = v_entity(group->topic)->name; + /* If partition string is formatted '__NODEBUILT-IN PARTITION__' + * it should be considered a local partition. + */ + /* Verify whether partition has length to potentially have the format + * we're looking for. + */ + if(strlen(partition) > (strlen(D_OSPL_NODE) + strlen(D_OSPL_BUILTIN_PARTITION))){ + /* Check if starts with __NODE */ + if(strncmp(D_OSPL_NODE, partition, strlen(D_OSPL_NODE)) == 0){ + /* Set pointer to the end of the string minus the length of the + * partition postfix 'BUILT-IN PARTITION__' + */ + partition = partition + strlen(partition) - strlen(D_OSPL_BUILTIN_PARTITION); + /* Verify whether it ends with 'BUILT-IN PARTITION__' */ + if(strncmp(D_OSPL_BUILTIN_PARTITION, partition, strlen(D_OSPL_BUILTIN_PARTITION)) == 0){ + /* If so consider it local */ + result = FALSE; + + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Found group %s.%s which is a built-in local group.\n", + v_entity(group->partition)->name, + v_entity(group->topic)->name); + } + } + } else if((strlen(partition) == strlen(V_BUILTIN_PARTITION)) && + (strlen(topic) == strlen(V_HEARTBEATINFO_NAME))){ + + if(strncmp(partition, V_BUILTIN_PARTITION, strlen(V_BUILTIN_PARTITION)) == 0){ + if(strncmp(topic, V_HEARTBEATINFO_NAME, strlen(V_HEARTBEATINFO_NAME)) == 0){ + result = FALSE; + + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Found group %s.%s which is a built-in local group.\n", + v_entity(group->partition)->name, + v_entity(group->topic)->name); + } + } + } + } + return result; + +} + +struct updateStatistics { + d_durabilityStatisticsCallback callback; + c_voidp userData; +}; + +static void +d_durabilityUpdateStatisticsCallback( + v_public entity, + c_voidp args) +{ + struct updateStatistics* update; + v_durability durability = v_durability(entity); + + + if(durability->statistics){ + update = (struct updateStatistics*)args; + update->callback(durability->statistics, update->userData); + } + return; +} + +void +d_durabilityUpdateStatistics( + d_durability durability, + d_durabilityStatisticsCallback callback, + c_voidp args) +{ + struct updateStatistics update; + + update.callback = callback; + update.userData = args; + + if (durability != NULL) { + (void)u_observableAction( + u_observable(durability->service), + d_durabilityUpdateStatisticsCallback, &update); + } +} + +u_result +d_durabilityTakePersistentSnapshot( + d_durability durability, + c_char* partitionExpr, + c_char* topicExpr, + c_char* uri) +{ + u_result result; + d_storeResult storeResult; + d_admin admin; + d_subscriber subscriber; + d_store store; + d_serviceState state; + + assert(durability); + assert(partitionExpr); + assert(topicExpr); + assert(uri); + + state = d_durabilityGetState(durability); + if(state == D_STATE_COMPLETE) + { + admin = durability->admin; + subscriber = d_adminGetSubscriber(admin); + store = d_subscriberGetPersistentStore(subscriber); + storeResult = d_storeCreatePersistentSnapshot(store, partitionExpr, topicExpr, uri); + /* Map the store result to a u_result */ + switch(storeResult) + { + case D_STORE_RESULT_OK: + result = U_RESULT_OK; + break; + case D_STORE_RESULT_OUT_OF_RESOURCES: + result = U_RESULT_OUT_OF_MEMORY; + break; + case D_STORE_RESULT_ILL_PARAM: + result = U_RESULT_ILL_PARAM; + break; + default: + result = U_RESULT_PRECONDITION_NOT_MET; + break; + } + } else + { + result = U_RESULT_PRECONDITION_NOT_MET; + } + return result; +} + + +/** + * \brief Get the durability version + */ +struct _DDS_DurabilityVersion_t +d_durabilityGetMyVersion ( + d_durability durability) +{ + assert(d_durabilityIsValid(durability)); + + return durability->myVersion; +} + + +/** + * \brief Retrieve the serverId of this durability service. + */ +struct _DDS_Gid_t +d_durabilityGetMyServerId( + d_durability durability) +{ + assert(d_durabilityIsValid(durability)); + + return durability->myServerId; +} + +/** + * \brief Check if the list of serverIds contains an ID that matches + * my serverID. + * + * This function retuns TRUE if I am addressed in the list of serverIds + * in the request, or if the list of serverIds in the request is empty. + * In the latter case the request is meant for everybody. + * + * The boolean forMe will be set if the request was explicitly addressed + * to me. The boolean forEveryBody will be addressed if the request was + * addressed to everybody. + * + * @return TRUE, if the request is for me or for everybody, + * FALSE, otherwise + */ +c_bool +d_durabilityRequestIsForMe( + d_durability durability, + c_iter serverIds, + c_bool *forMe, + c_bool *forEverybody) +{ + struct _DDS_Gid_t myServerId; + struct _DDS_Gid_t *serverId; + c_iterIter iter; + + assert(d_durabilityIsValid(durability)); + + *forMe = FALSE; + myServerId = d_durabilityGetMyServerId(durability); + /* If the list of serverIds is empty then the request is meant for every + * aligner, but only the aligner who is master for the group is allowed + * to respond. + */ + *forEverybody = (c_iterLength(serverIds) == 0); + iter = c_iterIterGet(serverIds); + while ((!*forMe) && ((serverId = (struct _DDS_Gid_t *)c_iterNext(&iter)) != NULL)) { + *forMe = ((serverId->prefix == myServerId.prefix) && (serverId->suffix == myServerId.suffix)); + } + return *forMe || *forEverybody; +} + + +/** + * \brief Get a unique request Id + * + * @return A unique request Id (module 2^64) + */ +struct _DDS_RequestId_t +d_durabilityGetRequestId( + d_durability durability) +{ + struct _DDS_RequestId_t requestId; + + assert(d_durabilityIsValid(durability)); + + requestId.clientId = d_durabilityGetMyServerId(durability); + requestId.requestId = pa_inc32_nv(&durability->requestId); + return requestId; +} + +/** + * \brief Get a unique conflict Id + * + * @return A unique conflict Id. Never 0. + */ +c_ulong +d_durabilityGenerateConflictId( + _Inout_ d_durability durability) +{ + c_ulong newId; + + do { + newId = pa_inc32_nv(&durability->conflictId); + } while (newId == 0); + + return newId; +} + +/* This function is called from the following listeners threads + * capabilityListener + * nameSpacesListener + * nameSpacesRequestListener + * statusListener + * Each of these may create a confirmed fellow. + */ +d_fellow +d_durabilityGetOrCreateFellowFromMessage( + d_admin admin, + d_networkAddress fellowAddr, + d_message message) +{ + d_fellow fellow, fellow2; + os_uint32 seqnum; + d_durability durability = d_threadsDurability(); + + d_productionTimestampToSeqnum(&seqnum, &d_message(message)->productionTimestamp); + fellow = d_adminGetFellow(admin, fellowAddr); + if (!fellow) { + if ((message->senderState != D_STATE_TERMINATING) && + (message->senderState != D_STATE_TERMINATED)) { + fellow2 = d_fellowNew(fellowAddr, message->senderState, TRUE); + d_fellowUpdateStatus(fellow2, message->senderState, seqnum); + fellow = d_adminAddFellow(admin, fellow2); + if (fellow) { + if (fellow != fellow2) { + /* There must have been another confirmed fellow + * with the same address, use that one. + */ + d_fellowFree(fellow2); + d_fellowUpdateStatus(fellow, message->senderState, seqnum); + } + + } else { + /* d_adminAddFellow returns NULL when the fellow has recently + * terminated. Ignore the fellow for now. + */ + d_fellowFree(fellow2); + } + } else { + d_printTimedEvent(durability, D_LEVEL_FINE, + "Fellow %u unknown but terminating, so ignoring the message.\n", + message->senderAddress.systemId); + } + } else { + /* The fellow already exist, update the status of the last report time */ + d_fellowUpdateStatus(fellow, message->senderState, seqnum); + } + + /* A fellow's state change may cause that capabilities must be send + * and may affect my responsiveness, so let's check. + */ + if (fellow) { + /* Set capability support */ + d_fellowSetCapabilitySupport(fellow, d_messageHasCapabilitySupport(message)); + /* Check whether to send my capabilities initially to the fellow */ + d_fellowCheckSendCapabilities(fellow, TRUE); + /* The fellow's capability setting support may have affected the responsiveness, so check */ + d_fellowCheckInitialResponsiveness(fellow); + } + return fellow; +} + + +c_ulong +d_durabilityGetNewIncarnation( + d_durability durability) +{ + c_ulong newIncarnation; + + do { + newIncarnation = pa_inc32_nv(&durability->incarnation); + } while (newIncarnation == 0); + + return newIncarnation; +} diff --git a/src/services/durability/code/d_durabilityState.c b/src/services/durability/code/d_durabilityState.c new file mode 100644 index 000000000..d194bacaa --- /dev/null +++ b/src/services/durability/code/d_durabilityState.c @@ -0,0 +1,126 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#include "d__durabilityState.h" +#include "d__types.h" +#include "d__durabilityStateRequest.h" +#include "d__partitionTopicState.h" +#include "d__durability.h" +#include "client_durabilitySplType.h" + + +/** + * \brief Create a durabilityState + * + * The durabilityState object + */ +d_durabilityState +d_durabilityStateNew( + d_admin admin) +{ + d_durability durability; + d_durabilityState durabilityState = NULL; + + assert(d_adminIsValid(admin)); + + durability = d_adminGetDurability(admin); + + /* Allocate durabilityState */ + durabilityState = d_durabilityState(os_malloc(C_SIZEOF(d_durabilityState))); + if (durabilityState) { + /* Call super-init */ + d_objectInit(d_object(durabilityState), D_DURABILITY_STATE, + (d_objectDeinitFunc)d_durabilityStateDeinit); + /* Initialize durabilityState */ + durabilityState->version = d_durabilityGetMyVersion(durability); + durabilityState->serverId = d_durabilityGetMyServerId(durability); + durabilityState->requestIds = c_iterNew(NULL); + if (!durabilityState->requestIds) { + goto err_allocRequestIds; + } + durabilityState->dataState = c_iterNew(NULL); + if (!durabilityState->dataState) { + goto err_allocDataState; + } + durabilityState->extensions = c_iterNew(NULL); + if (!durabilityState->extensions) { + goto err_allocExtensions; + } + } + return durabilityState; + +err_allocExtensions: +err_allocDataState: +err_allocRequestIds: + d_durabilityStateFree(durabilityState); + return NULL; +} + +/** + * \brief Deinitialize a durabilityState + */ +void +d_durabilityStateDeinit( + d_durabilityState durabilityState) +{ + struct _DDS_RequestId_t *requestId; + d_partitionTopicState state; + struct _DDS_NameValue_t *extension; + + assert(d_durabilityStateIsValid(durabilityState)); + + if (durabilityState->requestIds) { + requestId = (struct _DDS_RequestId_t *)c_iterTakeFirst(durabilityState->requestIds); + while (requestId != NULL) { + os_free(requestId); + requestId = (struct _DDS_RequestId_t *)c_iterTakeFirst(durabilityState->requestIds); + } + c_iterFree(durabilityState->requestIds); + } + if (durabilityState->dataState) { + state = d_partitionTopicState(c_iterTakeFirst(durabilityState->dataState)); + while (state) { + d_partitionTopicStateFree(state); + state = d_partitionTopicState(c_iterTakeFirst(durabilityState->dataState)); + } + c_iterFree(durabilityState->dataState); + } + if (durabilityState->extensions) { + extension = (struct _DDS_NameValue_t *)c_iterTakeFirst(durabilityState->extensions); + while (extension) { + os_free(extension); + extension = (struct _DDS_NameValue_t *)c_iterTakeFirst(durabilityState->extensions); + } + c_iterFree(durabilityState->extensions); + } + /* call super-deinit */ + d_objectDeinit(d_object(durabilityState)); +} + + +/** + * \brief Free the durabilityState + */ +void +d_durabilityStateFree( + d_durabilityState durabilityState) +{ + assert(d_durabilityStateIsValid(durabilityState)); + + d_objectFree(d_object(durabilityState)); +} + diff --git a/src/services/durability/code/d_durabilityStateRequest.c b/src/services/durability/code/d_durabilityStateRequest.c new file mode 100644 index 000000000..c85a6b381 --- /dev/null +++ b/src/services/durability/code/d_durabilityStateRequest.c @@ -0,0 +1,140 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#include "d__durabilityStateRequest.h" +#include "d__admin.h" +#include "d__types.h" +#include "client_durabilitySplType.h" +#include "d__misc.h" + + +/** + * \brief Create a durabilityStateRequest + */ +d_durabilityStateRequest +d_durabilityStateRequestNew( + d_admin admin, + struct _DDS_DurabilityVersion_t version, + struct _DDS_RequestId_t requestId, + d_topic topic, + c_iter partitions, + c_iter serverIds, + c_time timeout, + c_iter extensions) +{ + d_durabilityStateRequest request = NULL; + + OS_UNUSED_ARG(admin); + + /* Allocate durabilityStateRequest */ + request = d_durabilityStateRequest(os_malloc(C_SIZEOF(d_durabilityStateRequest))); + if (request) { + /* Call super-init */ + d_objectInit(d_object(request), D_DURABILITY_STATE_REQ, + (d_objectDeinitFunc)d_durabilityStateRequestDeinit); + /* Initialize durabilityStateRequest */ + request->version = version; + request->requestId = requestId; + request->timeout = timeout; + request->topic = os_strdup(topic); + request->partitions = c_iterCopy(partitions); /* NULL equals empty iter */ + request->serverIds = c_iterCopy(serverIds); /* NULL equals empty iter */ + request->extensions = c_iterCopy(extensions); /* NULL equals empty iter */ + request->forMe = FALSE; + request->forEverybody = (c_iterLength(serverIds) == 0); + } + return request; +} + + +/** + * \brief Deinitialize a durabilityStateRequest + */ +void +d_durabilityStateRequestDeinit( + d_durabilityStateRequest durabilityStateRequest) +{ + char *partition; + struct _DDS_Gid_t *serverId; + struct _DDS_NameValue_t *extension; + + assert(d_durabilityStateRequestIsValid(durabilityStateRequest)); + + if (durabilityStateRequest->topic) { + os_free(durabilityStateRequest->topic); + } + if (durabilityStateRequest->partitions) { + partition = c_iterTakeFirst(durabilityStateRequest->partitions); + while (partition) { + os_free(partition); + partition = c_iterTakeFirst(durabilityStateRequest->partitions); + } + } + if (durabilityStateRequest->serverIds) { + serverId = c_iterTakeFirst(durabilityStateRequest->serverIds); + while (serverId) { + os_free(serverId); + serverId = c_iterTakeFirst(durabilityStateRequest->serverIds); + } + } + if (durabilityStateRequest->extensions) { + extension = c_iterTakeFirst(durabilityStateRequest->extensions); + while (extension) { + os_free(extension); + extension = c_iterTakeFirst(durabilityStateRequest->extensions); + } + } + /* call super-deinit */ + d_objectDeinit(d_object(durabilityStateRequest)); +} + + +/** + * \brief Free the durabilityStateRequest + */ +void +d_durabilityStateRequestFree( + d_durabilityStateRequest durabilityStateRequest) +{ + assert(d_durabilityStateRequestIsValid(durabilityStateRequest)); + + d_objectFree(d_object(durabilityStateRequest)); +} + + +/** + * \brief Check if the durabilityStateRequest contains errors. + * + * If errors are encountered, the error code and error string are returned. + * Only one error message will be returned. + * + * @return TRUE, if no errors are detected, FALSE otherwise + */ +c_ulong +d_durabilityStateRequestSanityCheck( + d_durabilityStateRequest durabilityStateRequest) +{ + assert(d_durabilityStateRequestIsValid(durabilityStateRequest)); + + if (durabilityStateRequest->topic == NULL) { + return D_DDS_RETCDE_NO_TOPIC; + } else if ( c_iterLength(durabilityStateRequest->partitions) == 0 ) { + return D_DDS_RETCDE_NO_PARTITIONS; + } + /* No sanity error */ + return D_DDS_RETCDE_NO_ERROR; +} diff --git a/src/services/durability/code/d_durabilityStateRequestListener.c b/src/services/durability/code/d_durabilityStateRequestListener.c new file mode 100644 index 000000000..8b510c9ef --- /dev/null +++ b/src/services/durability/code/d_durabilityStateRequestListener.c @@ -0,0 +1,657 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#include "vortex_os.h" +#include "d__durabilityStateRequestListener.h" +#include "d__durabilityStateRequest.h" +#include "d__durabilityState.h" +#include "d__publisher.h" +#include "d__configuration.h" +#include "d__admin.h" +#include "d__durability.h" +#include "d__misc.h" +#include "d__thread.h" +#include "d__waitset.h" +#include "d__listener.h" +#include "d__subscriber.h" +#include "d__group.h" +#include "d__partitionTopicState.h" +#include "d_qos.h" +#include "u_listener.h" +#include "v_message.h" +#include "v_observer.h" + +#include "v_group.h" +#include "v_builtin.h" +#include "v_time.h" +#include "v_state.h" +#include "v_historicalDataRequest.h" +#include "v_groupInstance.h" +#include "v_entity.h" +#include "v_message.h" +#include "v_dataReaderInstance.h" +#include "v_topic.h" +#include "sd_serializer.h" +#include "sd_serializerBigE.h" +#include "sd_cdr.h" +#include "os_heap.h" +#include "os_report.h" +#include "c_misc.h" + +#include "client_durabilitySplType.h" + + +/** + * Macro that checks the d_durabilityStateRequestListener validity. + * Because d_durabilityStateRequestListener is a concrete class typechecking is required. + */ +#define d_durabilityStateRequestListenerIsValid(_this) \ + d_listenerIsValidKind(d_listener(_this), D_DURABILITY_STATE_REQ_LISTENER) + +/** + * \brief The d_durabilityStateRequestListener cast macro. + * + * This macro casts an object to a d_durabilityStateRequestListener object. + */ +#define d_durabilityStateRequestListener(_this) ((d_durabilityStateRequestListener)(_this)) + + +C_STRUCT(d_durabilityStateRequestListener) { + C_EXTENDS(d_listener); + u_dataReader dataReader; + d_waitsetEntity waitsetData; + c_iter requests; + d_subscriber subscriber; +}; + + +static c_iter * +partitionsCopyOut( + c_iter *to, + c_sequence from) +{ + c_ulong length, i; + c_string *fromStr, toStr; + size_t len; + + assert(to); + + fromStr = (c_string*)from; + /* The generic copy routines do not always handle c_sequenceSize + * correctly, but luckily we can just as well use c_arraySize. */ + length = c_arraySize(from); + for (i = 0; i < length; i++) { + len = strlen(fromStr[i]); + toStr = os_malloc(len+1); /* add '\0' */ + toStr = os_strncpy(toStr, fromStr[i], len); + toStr[len] = '\0'; + *to = c_iterAppend(*to, toStr); + } /* for */ + return to; +} + + +static c_iter * +serverIdsCopyOut( + c_iter *to, + c_sequence from) +{ + c_ulong length, i; + struct _DDS_Gid_t *toServerId, *fromServerId; + + assert(*to); + + fromServerId = (struct _DDS_Gid_t *)from; + /* The generic copy routines do not always handle c_sequenceSize + * correctly, but luckily we can just as well use c_arraySize. */ + length = c_arraySize(from); + + for (i = 0; i < length; i++) { + toServerId = os_malloc(sizeof(struct _DDS_Gid_t)); + *toServerId = fromServerId[i]; + *to = c_iterAppend(*to, toServerId); + } /* for */ + return to; +} + + +static c_iter * +extensionsCopyOut( + c_iter *to, + c_sequence from) +{ + c_ulong length, i; + struct _DDS_NameValue_t *toNameValue, *fromNameValue; + + assert(*to); + + fromNameValue = (struct _DDS_NameValue_t *)from; + /* The generic copy routines do not always handle c_sequenceSize + * correctly, but luckily we can just as well use c_arraySize. */ + length = c_arraySize(from); + + for (i = 0; i < length; i++) { + toNameValue = os_malloc(sizeof(struct _DDS_NameValue_t)); + *toNameValue = fromNameValue[i]; + *to = c_iterAppend(*to, toNameValue); + } /* for */ + return to; +} + +/** + * \brief Construct and send an durabilityState answer to a + * durabilityStateRequest + * + */ +static void +d_durabilityStateRequestListenerAnswer( + d_durabilityStateRequestListener listener, + d_durabilityStateRequest request) +{ + d_admin admin; + d_durability durability; + d_publisher publisher; + d_durabilityState durabilityState; + struct collectMatchingGroupsHelper helper; + d_tableIter tableIter; + d_group group; + d_partitionTopicState state; + struct _DDS_Gid_t myClientId; + c_bool selfInflicted; + + assert(d_durabilityStateRequestListenerIsValid(listener)); + assert(d_durabilityStateRequestIsValid(request)); + + admin = d_listenerGetAdmin(d_listener(listener)); + durability = d_adminGetDurability(admin); + publisher = d_adminGetPublisher(admin); + myClientId = d_durabilityGetMyServerId(durability); + selfInflicted = ((myClientId.prefix == request->requestId.clientId.prefix) && (myClientId.suffix == request->requestId.clientId.suffix)); + d_printTimedEvent(durability, D_LEVEL_FINER, + "Answering durabilityStateRequest (%"PA_PRId64".%"PA_PRId64",%"PA_PRIu32")%s\n", + request->requestId.clientId.prefix, + request->requestId.clientId.suffix, + request->requestId.requestId, + selfInflicted ? " (self-inflicted)" : ""); + /* Create a durabilityState message */ + durabilityState = d_durabilityStateNew(admin); + if (!durabilityState) { + d_printTimedEvent(durability, D_LEVEL_WARNING, + "Unable to respond to durabilityStateRequest (%"PA_PRId64".%"PA_PRId64",%"PA_PRIu32"), I am going to drop this request\n", + request->requestId.clientId.prefix, request->requestId.clientId.suffix, request->requestId.requestId); + goto err_allocDurabilityState; + } + /* Self-inflicted requests do not have a requestId. + * Clients will interpret DurabilityState messages + * with an empty list of requestIds as a push message + * from a server */ + if (!selfInflicted) { + struct _DDS_RequestId_t *requestId; + + requestId = os_malloc(sizeof(struct _DDS_RequestId_t)); + *requestId = request->requestId; + (void)c_iterAppend(durabilityState->requestIds, (c_voidp)requestId); + } + /* Set the request to answer */ + durabilityState->request = request; + /* Retrieve the matching groups */ + helper.admin = admin; + helper.topic = request->topic; + helper.partitions = request->partitions; + helper.matchingGroups = d_tableNew(d_groupCompare, d_groupFree); + if (!helper.matchingGroups) { + goto err_allocMatchingGroups; + } + helper.forMe = request->forMe; + helper.forEverybody = request->forEverybody; + helper.isAligner = FALSE; + helper.isResponsible = FALSE; + helper.masterKnown = FALSE; + helper.groupFound = FALSE; + helper.isHistoricalDataRequest = FALSE; + d_adminCollectMatchingGroups(admin, &helper); + if (helper.isAligner || helper.forMe) { + /* Always reply if I am aligner or the request is addressed to me */ + d_printTimedEvent(durability, D_LEVEL_FINER, + "Total %d groups matched durabilityStateRequest (%"PA_PRId64".%"PA_PRId64",%"PA_PRIu32"), going to reply\n", + d_tableSize(helper.matchingGroups), request->requestId.clientId.prefix, request->requestId.clientId.suffix, request->requestId.requestId); + /* Collect info for the matching groups */ + group = d_group(d_tableIterFirst(helper.matchingGroups, &tableIter)); + while (group) { + state = d_partitionTopicStateNew(group); + (void)c_iterAppend(durabilityState->dataState, (c_voidp)state); + group = d_group(d_tableIterNext(&tableIter)); + } + /* Publish the durabilityState. */ + d_publisherDurabilityStateWrite(publisher, durabilityState); + } else { + d_printTimedEvent(durability, D_LEVEL_FINER, + "Igoring durabilityStateRequest (%"PA_PRId64".%"PA_PRId64",%"PA_PRIu32") because I cannot align any of the requested data\n", + request->requestId.clientId.prefix, request->requestId.clientId.suffix, request->requestId.requestId); + } + /* Free the durabilityState */ + d_durabilityStateFree(durabilityState); + /* Free allocated stuff */ + d_tableFree(helper.matchingGroups); + d_durabilityStateRequestFree(request); + return; + +err_allocMatchingGroups: + d_tableFree(helper.matchingGroups); + d_durabilityStateFree(durabilityState); +err_allocDurabilityState: + OS_REPORT(OS_ERROR, "d_durabilityStateRequestListenerAnswer", 0, "Unable to answer durabilityStateRequest %u", + request->requestId.requestId); + d_durabilityStateRequestFree(request); + return; +} + + +static +u_actionResult +processDurabilityStateRequest( + c_object o, + c_voidp userData /* listener * */) +{ + d_durabilityStateRequestListener listener; + struct _DDS_DurabilityStateRequest *request; + d_durabilityStateRequest durabilityStateRequest; + v_dataReaderSample s; + v_actionResult result = V_STOP; + v_message message; + d_admin admin; + d_durability durability; + c_ulong errorCode; + c_iter partitions; + c_iter serverIds; + c_iter extensions; + c_time timeout; + d_client client, duplicate; + d_networkAddress clientAddr; + + listener = d_durabilityStateRequestListener(userData); + s = v_dataReaderSample(o); + if (s != NULL) { + admin = d_listenerGetAdmin(d_listener(listener)); + durability = d_adminGetDurability(admin); + v_actionResultSet(result, V_PROCEED); + if (v_dataReaderSampleStateTest(s, L_VALIDDATA) && !(v_dataReaderSampleInstanceStateTest(s, L_DISPOSED))) { + message = v_dataReaderSampleTemplate(s)->message; + request = (struct _DDS_DurabilityStateRequest *)C_DISPLACE(message, C_MAXALIGNSIZE(sizeof(*message))); + /* Create a d_durabilityStateRequest object to store the request. + * The request is freed when it has been answered successfully */ + timeout.seconds = request->timeout.sec; + timeout.nanoseconds = request->timeout.nanosec; + partitions = c_iterNew(NULL); + if (!partitionsCopyOut(&partitions, request->partitions)) { + goto err_allocRequestPartitions; + } + serverIds = c_iterNew(NULL); + if (!serverIdsCopyOut(&serverIds, request->serverIds)) { + goto err_allocRequestServerIds; + } + extensions = c_iterNew(NULL); + if (!extensionsCopyOut(&extensions, request->extensions)) { + goto err_allocRequestExtensions; + } + durabilityStateRequest = d_durabilityStateRequestNew( + admin, + request->version, + request->requestId, + request->topic, + partitions, + serverIds, + timeout, + extensions); + c_iterFree(partitions); + c_iterFree(serverIds); + c_iterFree(extensions); + /* Get or create client and store the requestId.clientId */ + clientAddr = d_networkAddressNew(message->writerGID.systemId, 0, 0); + client = d_clientNew(clientAddr); + if ((duplicate = d_adminAddClient(admin, client)) != client) { + d_clientFree(client); + client = duplicate; + } + d_clientSetClientId(client, durabilityStateRequest->requestId.clientId); + d_printTimedEvent(durability, D_LEVEL_FINE, + "Received durabilityStateRequest (%"PA_PRId64".%"PA_PRId64",%"PA_PRIu32") for topic '%s' from federation %u\n", + request->requestId.clientId.prefix, + request->requestId.clientId.suffix, + request->requestId.requestId, + request->topic, + clientAddr->systemId); + /* Check if the request is for me or for everybody*/ + if (!d_durabilityRequestIsForMe(durability, durabilityStateRequest->serverIds, + &durabilityStateRequest->forMe, &durabilityStateRequest->forEverybody)) { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "durabilityStateRequest %"PA_PRId64".%"PA_PRId64",%"PA_PRIu32") for topic '%s' from federation %u is not meant for me, ignoring this request\n", + durabilityStateRequest->requestId.clientId.prefix, + durabilityStateRequest->requestId.clientId.suffix, + durabilityStateRequest->requestId.requestId, + durabilityStateRequest->topic, + clientAddr->systemId); + goto skip_notMeantForMe; + } + /* Let's check if the request itself contains any sanity errors. + * If there are any errors then ignore the request. */ + errorCode = d_durabilityStateRequestSanityCheck(durabilityStateRequest); + if (errorCode != 0) { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Sanity error in durabilitystateRequest (%"PA_PRId64".%"PA_PRId64",%"PA_PRIu32"), ignoring this request : '%s'\n", + durabilityStateRequest->requestId.clientId.prefix, + durabilityStateRequest->requestId.clientId.suffix, + durabilityStateRequest->requestId.requestId, + d_getErrorMessage(errorCode)); + goto skip_sanityError; + } + /* Add the request to the listener. + * The request is freed once it is handled properly. */ + d_printTimedEvent(durability, D_LEVEL_FINER, + "Adding durabilityStateRequest %lu to queue\n", + request->requestId.requestId); + d_durabilityStateRequestListenerAddRequest(listener, durabilityStateRequest); + /* Free the stuff */ + d_networkAddressFree(clientAddr); + d_clientFree(client); + } else if (v_dataReaderSampleInstanceStateTest(s, L_DISPOSED)) { + /* The request is disposed, so in this case we should remove pending requests. */ + } + } + return result; + +skip_sanityError: +skip_notMeantForMe: + d_durabilityStateRequestFree(durabilityStateRequest); + d_networkAddressFree(clientAddr); + return result; +err_allocRequestExtensions: + c_iterFree(serverIds); +err_allocRequestServerIds: + c_iterFree(partitions); +err_allocRequestPartitions: + return result; +} + + + +static c_ulong +d_durabilityStateRequestListenerAction( + u_object o, /* the observable that triggered the event */ + v_waitsetEvent event, /* the event that was triggered */ + c_voidp userData /* d_historicalDataRequestListener */) +{ + d_durabilityStateRequestListener listener = d_durabilityStateRequestListener(userData); + d_thread self = d_threadLookupSelf(); + u_result ur; + + OS_UNUSED_ARG(o); + + d_threadAwake(self); + if (event->kind & V_EVENT_DATA_AVAILABLE) { + d_lockLock(d_lock(listener)); + + ur = u_dataReaderTake(listener->dataReader, U_STATE_ANY, processDurabilityStateRequest, listener, OS_DURATION_ZERO); + + if (ur != U_RESULT_OK && ur != U_RESULT_NO_DATA) { + OS_REPORT(OS_ERROR, D_CONTEXT_DURABILITY, ur, + "Failed to read data from DurabilityStateReader (result: %s)", + u_resultImage(ur)); + } + d_lockUnlock(d_lock(listener)); + } + d_threadAsleep(self, ~0u); + return event->kind; +} + + +/** + * \brief Deinitialize the durabilityStateRequestListener + */ +static void +d_durabilityStateRequestListenerDeinit( + d_durabilityStateRequestListener listener) +{ + d_durabilityStateRequest request; + + assert(d_durabilityStateRequestListenerIsValid(listener)); + + /* Stop the durabilityStateRequestListener */ + d_durabilityStateRequestListenerStop(listener); + if (listener->waitsetData) { + d_waitsetEntityFree(listener->waitsetData); + listener->waitsetData = NULL; + } + if (listener->dataReader) { + u_objectFree(u_object(listener->dataReader)); + listener->dataReader = NULL; + } + /* Clean up pending requests */ + request = d_durabilityStateRequest(c_iterTakeFirst(listener->requests)); + while (request) { + d_durabilityStateRequestFree(request); + request = d_durabilityStateRequest(c_iterTakeFirst(listener->requests)); + } + listener->subscriber = NULL; + /* Call super-deinit */ + d_listenerDeinit(d_listener(listener)); +} + +/** + * \brief Create a durabilityStateRequestListener object + * + * The listener listens to durabilityStateRequest messages that + * are published on the durability partition. Requests that + * originate from myself are discarded. + */ +d_durabilityStateRequestListener +d_durabilityStateRequestListenerNew( + d_subscriber subscriber) +{ + d_durabilityStateRequestListener listener; + v_readerQos readerQos; + d_admin admin; + d_durability durability; + d_configuration config; + c_value ps[2]; + struct _DDS_Gid_t myServerId; + + assert(d_subscriberIsValid(subscriber)); + + admin = d_subscriberGetAdmin(subscriber); + assert(d_adminIsValid(admin)); + durability = d_adminGetDurability(admin); + assert(d_durabilityIsValid(durability)); + config = d_durabilityGetConfiguration(durability); + /* Allocate historicalDataRequestListener object */ + listener = d_durabilityStateRequestListener(os_malloc(C_SIZEOF(d_durabilityStateRequestListener))); + /* Call super-init */ + d_listenerInit(d_listener(listener), D_DURABILITY_STATE_REQ_LISTENER, subscriber, NULL, + (d_objectDeinitFunc)d_durabilityStateRequestListenerDeinit); + /* Initialize the durabilityStateRequestListener */ + listener->subscriber = subscriber; + if ((readerQos = d_readerQosNew(V_DURABILITY_VOLATILE, V_RELIABILITY_RELIABLE)) == NULL) { + goto err_reader_qos; + } + /* d_readerQosNew does not always return the proper settings. + * The following settings ensure that the reader qos is correct */ + readerQos->history.v.kind = V_HISTORY_KEEPALL; + readerQos->history.v.depth = V_LENGTH_UNLIMITED; + readerQos->liveliness.v.lease_duration = OS_DURATION_INFINITE; + readerQos->reliability.v.max_blocking_time = OS_DURATION_INIT(0,100000000); + /* Prevent that the DurabilityStateRequestReader listens to requests from itself. */ + myServerId = d_durabilityGetMyServerId(durability); + ps[0].kind= V_LONGLONG; + ps[0].is.LongLong = myServerId.prefix; + ps[1].kind= V_LONGLONG; + ps[1].is.LongLong = myServerId.suffix; + listener->dataReader = u_subscriberCreateDataReader( + subscriber->subscriber2, + D_DURABILITY_STATE_REQUEST_TOPIC_NAME "Reader", + "select * from " D_DURABILITY_STATE_REQUEST_TOPIC_NAME " where requestId.clientId.prefix <> %0 OR requestId.clientId.suffix <> %1", + ps, 2, + readerQos); + if (listener->dataReader == NULL) { + goto err_dataReader; + } + + if(u_entityEnable(u_entity(listener->dataReader)) != U_RESULT_OK) { + goto err_dataReaderEnable; + } + listener->waitsetData = d_waitsetEntityNew( + "durabilityStateRequestListener", + u_object(listener->dataReader), + d_durabilityStateRequestListenerAction, + V_EVENT_DATA_AVAILABLE, + config->alignerScheduling, listener); + if (!listener->waitsetData) { + goto err_waitsetData; + } + /* No need to obtain historical data because topic is volatile */ + d_readerQosFree(readerQos); + listener->requests = c_iterNew(NULL); + + return listener; + +err_waitsetData: + /* No undo for u_entityEnable(...) */ +err_dataReaderEnable: +err_dataReader: + d_readerQosFree(readerQos); +err_reader_qos: + d_durabilityStateRequestListenerFree(listener); + return NULL; +} + + +/** + * \brief Free the durabilitystateRequestListener object + */ +void +d_durabilityStateRequestListenerFree( + d_durabilityStateRequestListener listener) +{ + assert(d_durabilityStateRequestListenerIsValid(listener)); + + d_objectFree(d_object(listener)); +} + + + +/** + * \brief Start the durabilityStateRequestListener + */ +c_bool +d_durabilityStateRequestListenerStart( + d_durabilityStateRequestListener listener) +{ + c_bool result; + d_waitset waitset; + u_result ur; + + result = FALSE; + + assert(d_durabilityStateRequestListenerIsValid(listener)); + + d_lockLock(d_lock(listener)); + if (d_listener(listener)->attached == FALSE) { + waitset = d_subscriberGetWaitset(listener->subscriber); + result = d_waitsetAttach(waitset, listener->waitsetData); + if (result == TRUE) { + /* A V_DATA_AVAILABLE event is only generated when new data + * arrives. It is NOT generated when historical data is inserted. + * In case this durability service receives historical + * DCPSSubscriptions from another durability service that + * was started earlier, all these DCPSSubscriptions are + * inserted in the reader at creation time. To read these + * we must explicitly trigger a take action. */ + ur = u_dataReaderTake(listener->dataReader, U_STATE_ANY, processDurabilityStateRequest, listener, OS_DURATION_ZERO); + if (ur != U_RESULT_OK && ur != U_RESULT_NO_DATA) { + OS_REPORT(OS_ERROR, D_CONTEXT_DURABILITY, ur, + "Failed to read data from historicalDataRequestListenerReader (result: %s)", u_resultImage(ur)); + } else { + d_listener(listener)->attached = TRUE; + result = TRUE; + } + } + } else { + result = TRUE; + } + d_lockUnlock(d_lock(listener)); + return result; +} + + +/** + * \brief Stop the durabilityStateRequestListener + */ +c_bool +d_durabilityStateRequestListenerStop( + d_durabilityStateRequestListener listener) +{ + c_bool result = FALSE; + d_admin admin; + d_subscriber subscriber; + d_waitset waitset; + + assert(d_durabilityStateRequestListenerIsValid(listener)); + + d_lockLock(d_lock(listener)); + if (d_listener(listener)->attached == TRUE) { + admin = d_listenerGetAdmin(d_listener(listener)); + subscriber = d_adminGetSubscriber(admin); + waitset = d_subscriberGetWaitset(subscriber); + d_lockUnlock(d_lock(listener)); + result = d_waitsetDetach(waitset, listener->waitsetData); + d_lockLock(d_lock(listener)); + if (result) { + d_listener(listener)->attached = FALSE; + result = TRUE; + } + } else { + result = TRUE; + } + d_lockUnlock(d_lock(listener)); + + return result; +} + + +struct d_durabilityStateRequestHelper { + d_durabilityStateRequest request; + d_table clientIds; +}; + + + +/** + * \brief Add a durabilityStateRequest to the list of pending requests. + * + * NOTE: similar requests are not combined, but immediately answered. + */ +void +d_durabilityStateRequestListenerAddRequest( + d_durabilityStateRequestListener listener, + d_durabilityStateRequest request) +{ + assert(d_durabilityStateRequestListenerIsValid(listener)); + assert(d_durabilityStateRequestIsValid(request)); + + d_durabilityStateRequestListenerAnswer(listener, request); + + return; +} diff --git a/src/services/durability/code/d_element.c b/src/services/durability/code/d_element.c new file mode 100644 index 000000000..65adc0875 --- /dev/null +++ b/src/services/durability/code/d_element.c @@ -0,0 +1,116 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "d__element.h" +#include "os_heap.h" + +d_element +d_elementNew( + const char * name, + const char * partition, + const char * topic ) +{ + d_element element; + + element = os_malloc(C_SIZEOF(d_element)); + element->name = NULL; + element->partition = NULL; + element->topic = NULL; + /* QAC EXPECT 1253; */ + element->strlenName = (os_uint32) (strlen(name) + 1); + /* QAC EXPECT 1253; */ + element->strlenPartition = (os_uint32) (strlen(partition) + 1); + /* QAC EXPECT 1253; */ + element->strlenTopic = (os_uint32) (strlen(topic) + 1); + + element->name = os_malloc(element->strlenName); + /* QAC EXPECT 5007; use of strcpy */ + os_strcpy(element->name, name); + element->partition = os_malloc(element->strlenPartition); + /* QAC EXPECT 5007; use of strcpy */ + os_strcpy(element->partition, partition); + element->topic = os_malloc(element->strlenTopic); + /* QAC EXPECT 5007; use of strcpy */ + os_strcpy(element->topic, topic); + return element; +} + + +void +d_elementFree( + d_element element ) +{ + if (element) { + if (element->name) { + os_free(element->name); + element->name = NULL; + } + if (element->partition) { + os_free(element->partition); + element->partition = NULL; + } + if (element->topic) { + os_free(element->topic); + element->topic = NULL; + } + os_free(element); + element = NULL; + } +} + + +c_string +d_elementGetExpression( + d_element element) +{ + char *result; + size_t size; + + size = element->strlenPartition + element->strlenTopic + 1; /* For the '/0'*/ + if (element->topic) { + size++; /* For the '.' */ + } + result = os_malloc(size); + if (element->topic) { + sprintf(result, "%s.%s", element->partition, element->topic); + } else { + sprintf(result, "%s", element->partition); + } + return result; +} + + +int +d_elementCompare( + c_voidp object1, + c_voidp object2 ) +{ + d_element element1, element2; + int result; + + result = 0; + element1 = d_element(object1); + element2 = d_element(object2); + if (element1 != element2) { + result = strncmp(element1->topic, element2->topic, element2->strlenTopic); + if (result == 0) { + result = strncmp(element1->partition, element2->partition, element2->strlenPartition); + } + } + return result; +} diff --git a/src/services/durability/code/d_eventListener.c b/src/services/durability/code/d_eventListener.c new file mode 100644 index 000000000..2d5095f78 --- /dev/null +++ b/src/services/durability/code/d_eventListener.c @@ -0,0 +1,77 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "d__eventListener.h" +#include "os_heap.h" + +d_eventListener +d_eventListenerNew( + c_ulong interest, + d_eventListenerFunc func, + c_voidp args) +{ + d_eventListener listener = NULL; + + if (func) { + /* Allocate eventListener object */ + listener = d_eventListener(os_malloc(C_SIZEOF(d_eventListener))); + if (listener) { + /* Call super-init */ + d_objectInit(d_object(listener), D_EVENT_LISTENER, + (d_objectDeinitFunc)d_eventListenerDeinit); + /* Initialize eventListener */ + listener->interest = interest; + listener->func = func; + listener->args = args; + } + } + return listener; +} + +c_voidp +d_eventListenerGetUserData( + d_eventListener listener) +{ + c_voidp userData = NULL; + + assert(d_eventListenerIsValid(listener)); + + if(listener){ + userData = listener->args; + } + return userData; +} + +void +d_eventListenerDeinit( + d_eventListener listener) +{ + assert(d_eventListenerIsValid(listener)); + + /* Nothing to deallocate, call super-deinit */ + d_objectDeinit(d_object(listener)); +} + +void +d_eventListenerFree( + d_eventListener listener) +{ + assert(d_eventListenerIsValid(listener)); + + d_objectFree(d_object(listener)); +} diff --git a/src/services/durability/code/d_fellow.c b/src/services/durability/code/d_fellow.c new file mode 100644 index 000000000..0e859dcae --- /dev/null +++ b/src/services/durability/code/d_fellow.c @@ -0,0 +1,1793 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "d__fellow.h" +#include "d__listener.h" +#include "d__admin.h" +#include "d__misc.h" +#include "d__table.h" +#include "d__group.h" +#include "d__nameSpace.h" +#include "d__configuration.h" +#include "d__publisher.h" +#include "d__durability.h" +#include "d__mergeState.h" +#include "d__thread.h" +#include "d__durability.h" +#include "d__capability.h" +#include "d__thread.h" +#include "d_message.h" +#include "d_networkAddress.h" +#include "d_nameSpacesRequest.h" +#include "os_heap.h" +#include "os_stdlib.h" +#include "os_time.h" +#include "os_report.h" + +struct findNameSpace{ + d_nameSpace template; + d_nameSpace nameSpace; +}; + +struct alignerHelper{ + const c_char* partition; + const c_char* topic; + d_durabilityKind kind; + c_bool aligner; + c_ulong masterPriority; +}; + +struct alignerNSHelper{ + d_nameSpace nameSpace; + c_bool aligner; +}; + +char* d_fellowState_text[] = { + "D_STATE_INIT", + "D_STATE_DISCOVER_FELLOWS_GROUPS", + "D_STATE_DISCOVER_LOCAL_GROUPS", + "D_STATE_DISCOVER_PERSISTENT_SOURCE", + "D_STATE_INJECT_PERSISTENT", + "D_STATE_FETCH_INITIAL", + "D_STATE_COMPLETE", + "D_STATE_FETCH", + "D_STATE_ALIGN", + "D_STATE_FETCH_ALIGN", + "D_STATE_TERMINATING", + "D_STATE_TERMINATED" +}; + +d_fellow +d_fellowNew( + d_networkAddress address, + d_serviceState state, + c_bool isConfirmed) +{ + d_fellow fellow; + + /* Allocate fellow object */ + fellow = d_fellow(os_malloc(C_SIZEOF(d_fellow))); + if (fellow) { + /* Call super-init */ + d_lockInit(d_lock(fellow), D_FELLOW, + (d_objectDeinitFunc)d_fellowDeinit); + /* Initialize the fellow */ + fellow->address = d_networkAddressNew(address->systemId, + address->localId, + address->lifecycleId); + fellow->communicationState = D_COMMUNICATION_STATE_UNKNOWN; + fellow->state = state; + fellow->lastStatusReport = OS_TIMEM_ZERO; /* last status report */ + fellow->lastSeqNum = 0ULL; /* unsigned long long */ + fellow->groups = NULL; /*Lazy initialization*/ + fellow->nameSpaces = NULL; /*Lazy initialization*/ + fellow->requestCount = 0; + fellow->expectedGroupCount = -1; + fellow->expectedNameSpaces = 1; /*At least one namespace is expected*/ + fellow->groupsRequested = FALSE; + fellow->role = NULL; + fellow->isConfirmed = isConfirmed; + fellow->hasConfirmed = isConfirmed; /* Initially, when a confirmed fellow is + * created it is confirmed for the first time. */ + fellow->recentlyTerminated = FALSE; + fellow->removalTime = OS_TIMEM_ZERO; + fellow->heartbeatDisposeCount = -1; + fellow->capabilitySupport = TRUE; /* Initially assume that all fellows support capabilities. + * This is set to FALSE when a message is received from + * this fellow with the most-significant bit of the + * nanoseconds in the production timestamp field set to 0 + */ + fellow->readers = 0; /* No readers detected yet for this fellow */ + fellow->requiredReaders = D_BASIC_DURABILITY_READER_FLAGS | D_CAPABILITY_READER_FLAG; + fellow->responsive = FALSE; /* Initially no nameSpaceRequest has been sent to this fellow */ + fellow->recently_joined = TRUE; /* Initially the fellow did not recently join; it is set when the fellow is added to the admin */ + fellow->capabilities.groupHash = TRUE; + fellow->capabilities.EOTSupport = TRUE; + fellow->capabilities.masterSelection = D_USE_MASTER_PRIORITY_ALGORITHM; /* Use priority-based masterSelection algorithm */ + fellow->capabilities.incarnation = 0; /* Initial incarnation */ + fellow->has_requested_namespaces = FALSE; /* Initially the fellow has not yet requested namespaces from me */ + fellow->incarnation = 0; /* The incarnation that I advertise to my fellow */ + } + return fellow; +} + +/** + * \brief Set the property fellow->groupsRequested to TRUE. + * + * This property indicates that groups are requested from the fellow. + * + * @return TRUE if groups->requested changed from FALSE to TRUE, + * FALSE otherwise + */ +c_bool +d_fellowSetGroupsRequested( + d_fellow fellow) +{ + c_bool result; + + assert(d_fellowIsValid(fellow)); + + d_lockLock(d_lock(fellow)); + if (fellow->groupsRequested) { + result = FALSE; + } else { + fellow->groupsRequested = TRUE; + result = TRUE; + } + d_lockUnlock(d_lock(fellow)); + return result; +} + +c_bool +d_fellowGetGroupsRequested( + d_fellow fellow) +{ + c_bool result; + + assert(d_fellowIsValid(fellow)); + + d_lockLock(d_lock(fellow)); + result = fellow->groupsRequested; + d_lockUnlock(d_lock(fellow)); + return result; +} + +d_networkAddress +d_fellowGetAddress( + d_fellow fellow) +{ + d_networkAddress address = NULL; + assert(d_objectIsValid(d_object(fellow), D_FELLOW) == TRUE); + + if (fellow) { + address = d_networkAddressNew(fellow->address->systemId, + fellow->address->localId, + fellow->address->lifecycleId); + } + return address; +} + +void +d_fellowSetAddress( + d_fellow fellow, + d_networkAddress address) +{ + assert(d_fellowIsValid(fellow)); + + d_lockLock(d_lock(fellow)); + fellow->address->systemId = address->systemId; + fellow->address->localId = address->localId; + fellow->address->lifecycleId = address->lifecycleId; + d_lockUnlock(d_lock(fellow)); + return; +} + +void +d_fellowDeinit( + d_fellow fellow) +{ + assert(d_fellowIsValid(fellow)); + + if (fellow->groups) { + d_tableFree(fellow->groups); + fellow->groups = NULL; + } + if (fellow->address) { + d_networkAddressFree(fellow->address); + fellow->address = NULL; + } + if (fellow->nameSpaces) { + d_tableFree(fellow->nameSpaces); + fellow->nameSpaces = NULL; + } + if (fellow->role) { + os_free (fellow->role); + fellow->role = NULL; + } + /* Call super-deinit */ + d_lockDeinit(d_lock(fellow)); + +} + +void +d_fellowFree( + d_fellow fellow) +{ + assert(d_fellowIsValid(fellow)); + + d_objectFree(d_object(fellow)); +} + +d_serviceState +d_fellowGetState( + d_fellow fellow) +{ + d_serviceState state = D_STATE_INIT; + + assert(d_objectIsValid(d_object(fellow), D_FELLOW) == TRUE); + + if(fellow){ + state = fellow->state; + } + return state; +} + +void +d_fellowUpdateStatus( + d_fellow fellow, + d_serviceState state, + os_uint32 seqnum) +{ + d_durability durability = d_threadsDurability(); + os_timeM timestamp = os_timeMGet(); + + assert(d_objectIsValid(d_object(fellow), D_FELLOW) == TRUE); + + if(fellow){ + d_lockLock(d_lock(fellow)); + /* Check if seqnum do not go backward (modulo wrapping). + * If no sequence number support is available then the sequence number will + * always be 0 (which is never handed out when sequence numbers are supported). + * To keep updating in this case >= iso > + */ + if (D_SEQNUM_ISVALID(seqnum) && ((seqnum >= fellow->lastSeqNum) || ((os_uint32)(fellow->lastSeqNum + seqnum) < fellow->lastSeqNum))) { + /* Update the last state of the fellow. + * Only print a log line if the state changed. + */ + if (fellow->state != state) { + d_printTimedEvent (durability, D_LEVEL_FINEST, + "Updating state of fellow '%d' to '%s' (lastSeqNum=%"PA_PRIu32", seqnum=%"PA_PRIu32", lastStatusReport=%"PA_PRItime", timestamp=%"PA_PRItime").\n", + fellow->address->systemId, d_fellowStateText(state), fellow->lastSeqNum, seqnum, + OS_TIMEM_PRINT(fellow->lastStatusReport), + OS_TIMEM_PRINT(timestamp)); + } + fellow->lastStatusReport = timestamp; + fellow->lastSeqNum = seqnum; + fellow->state = state; + } + d_lockUnlock(d_lock(fellow)); + } +} + +c_bool +d_fellowAddGroup( + d_fellow fellow, + d_group group) +{ + c_bool result; + d_group duplicate; + + assert(d_objectIsValid(d_object(fellow), D_FELLOW) == TRUE); + assert(d_objectIsValid(d_object(group), D_GROUP) == TRUE); + + result = FALSE; + + if(group && fellow){ + d_lockLock(d_lock(fellow)); + + if(!fellow->groups){ + fellow->groups = d_tableNew(d_groupCompare, d_groupFree); + } + duplicate = d_tableInsert(fellow->groups, group); + d_lockUnlock(d_lock(fellow)); + + if(!duplicate){ + result = TRUE; + } + } + return result; +} + +void +d_fellowSetExpectedGroupCount( + d_fellow fellow, + c_long count) +{ + assert(d_objectIsValid(d_object(fellow), D_FELLOW) == TRUE); + + if(fellow){ + fellow->expectedGroupCount = count; + } +} + +c_long +d_fellowGetExpectedGroupCount( + d_fellow fellow) +{ + c_long count; + + assert(d_objectIsValid(d_object(fellow), D_FELLOW) == TRUE); + count = -1; + + if(fellow){ + d_lockLock(d_lock(fellow)); + count = fellow->expectedGroupCount; + d_lockUnlock(d_lock(fellow)); + } + return count; +} + +c_ulong +d_fellowGetGroupCount( + d_fellow fellow) +{ + c_ulong count; + + assert(d_objectIsValid(d_object(fellow), D_FELLOW) == TRUE); + + if (fellow) { + d_lockLock(d_lock(fellow)); + if (fellow->groups) { + count = d_tableSize(fellow->groups); + } else { + count = 0; + } + d_lockUnlock(d_lock(fellow)); + } else { + count = 0; + } + return count; +} + +d_group +d_fellowRemoveGroup( + d_fellow fellow, + d_group group) +{ + d_group result = NULL; + assert(d_objectIsValid(d_object(fellow), D_FELLOW) == TRUE); + assert(d_objectIsValid(d_object(group), D_GROUP) == TRUE); + + if(group && fellow){ + d_lockLock(d_lock(fellow)); + + if(fellow->groups){ + result = d_tableRemove(fellow->groups, group); + } + d_lockUnlock(d_lock(fellow)); + } + return result; +} + +d_group +d_fellowGetGroup( + d_fellow fellow, + const c_char* partition, + const c_char* topic, + d_durabilityKind kind) +{ + d_group dummy; + d_group found = NULL; + + assert(d_fellowIsValid(fellow)); + + dummy = d_groupNew(partition, topic, kind, D_GROUP_KNOWLEDGE_UNDEFINED, D_QUALITY_ZERO); + d_lockLock(d_lock(fellow)); + if (fellow->groups) { + found = d_tableFind(fellow->groups, dummy); + if(found){ + d_objectKeep(d_object(found)); + } + } + d_lockUnlock(d_lock(fellow)); + d_groupFree(dummy); + return found; + +} + +c_bool +d_fellowHasGroup( + d_fellow fellow, + const c_char* partition, + const c_char* topic, + d_durabilityKind kind) +{ + c_bool hasGroup = FALSE; + d_group found; + + assert(d_objectIsValid(d_object(fellow), D_FELLOW) == TRUE); + + if(fellow){ + found = d_fellowGetGroup(fellow, partition, topic, kind); + + if(found){ + hasGroup = TRUE; + d_groupFree(found); + } + } + return hasGroup; +} + + +c_bool +d_fellowGroupWalk( + d_fellow fellow, + c_bool ( * action ) (d_group group, c_voidp userData), + c_voidp userData) +{ + c_bool result; + + assert(d_objectIsValid(d_object(fellow), D_FELLOW) == TRUE); + result = FALSE; + + if(fellow){ + result = TRUE; + d_lockLock(d_lock(fellow)); + + if(fellow->groups){ + d_tableWalk(fellow->groups, action, userData); + } + d_lockUnlock(d_lock(fellow)); + } + return result; +} + +int +d_fellowCompare( + d_fellow fellow1, + d_fellow fellow2) +{ + int result = 0; + + if (fellow1 != fellow2) { + result = d_networkAddressCompare(fellow1->address, fellow2->address); + } + return result; +} + +os_timeM +d_fellowGetLastStatusReport( + d_fellow fellow) +{ + os_timeM s = OS_TIMEM_INIT(0,0); + + assert(d_objectIsValid(d_object(fellow), D_FELLOW) == TRUE); + + if(fellow) { + s = fellow->lastStatusReport; + } + return s; +} + +d_communicationState +d_fellowGetCommunicationState( + d_fellow fellow) +{ + d_communicationState state = D_COMMUNICATION_STATE_UNKNOWN; + assert(d_objectIsValid(d_object(fellow), D_FELLOW) == TRUE); + + if(fellow) { + state = fellow->communicationState; + } + return state; +} + +void +d_fellowSetCommunicationState( + d_fellow fellow, + d_communicationState state) +{ + assert(d_objectIsValid(d_object(fellow), D_FELLOW) == TRUE); + + d_lockLock(d_lock(fellow)); + fellow->communicationState = state; + d_lockUnlock(d_lock(fellow)); +} + +c_bool +d_fellowAddNameSpace( + d_fellow fellow, + d_nameSpace nameSpace) +{ + c_bool result; + d_nameSpace duplicate; + d_networkAddress master, myAddr; + c_bool masterConfirmed; + d_mergeState mergeState; + d_durability durability; + + assert(d_objectIsValid(d_object(fellow), D_FELLOW) == TRUE); + assert(d_objectIsValid(d_object(nameSpace), D_NAMESPACE) == TRUE); + + result = FALSE; + durability = d_threadsDurability(); + myAddr = d_adminGetMyAddress(durability->admin); + if (fellow && nameSpace) { + d_lockLock(d_lock(fellow)); + master = d_nameSpaceGetMaster(nameSpace); + if (!fellow->nameSpaces) { + fellow->nameSpaces = d_tableNew(d_nameSpaceNameCompare, d_nameSpaceFree); + } + duplicate = d_tableInsert(fellow->nameSpaces, nameSpace); + if (duplicate) { + /* There was a duplicate. + * Update the master fellow of the namespace. + */ + d_nameSpaceSetMaster(duplicate, master); + /* update the confirmed property of the fellow nameSpace */ + masterConfirmed = d_nameSpaceIsMasterConfirmed(nameSpace); + d_nameSpaceSetMasterConfirmed(duplicate, masterConfirmed); + /* update the merge state of the fellow namespace in its native role */ + mergeState = d_nameSpaceGetMergeState(nameSpace, NULL); + d_nameSpaceSetMergeState(duplicate, mergeState); + d_mergeStateFree(mergeState); + nameSpace = duplicate; + } + d_networkAddressFree(master); + d_lockUnlock(d_lock(fellow)); + + if (!duplicate) { + /* A duplicate was found, return FALSE */ + result = TRUE; + } + } + d_networkAddressFree(myAddr); + return result; +} + +static c_bool +determineNameSpace( + d_nameSpace nameSpace, + c_voidp args) +{ + struct findNameSpace* fn; + c_bool proceed; + + fn = (struct findNameSpace*)args; + proceed = TRUE; + + if(d_nameSpaceNameCompare(nameSpace, fn->template) == 0){ + proceed = FALSE; + fn->nameSpace = nameSpace; + } + return proceed; +} + +d_nameSpace +d_fellowGetNameSpace( + d_fellow fellow, + d_nameSpace template) +{ + struct findNameSpace fn; + + fn.template = template; + fn.nameSpace = NULL; + + assert(d_objectIsValid(d_object(fellow), D_FELLOW) == TRUE); + + if(fellow){ + d_lockLock(d_lock(fellow)); + + if(fellow->nameSpaces){ + d_tableWalk(fellow->nameSpaces, determineNameSpace, &fn); + } + d_lockUnlock(d_lock(fellow)); + } + return fn.nameSpace; +} + +static c_bool +clearMaster( + d_nameSpace nameSpace, + c_voidp args) +{ + d_networkAddress addr; + + if(nameSpace){ + addr = d_nameSpaceGetMaster(nameSpace); + + if(d_networkAddressEquals(addr, d_networkAddress(args))){ + d_networkAddressFree(addr); + addr = d_networkAddressUnaddressed(); + d_nameSpaceSetMaster(nameSpace, addr); + } + d_networkAddressFree(addr); + } + return TRUE; +} + +void +d_fellowClearMaster( + d_fellow fellow, + d_networkAddress master) +{ + assert(d_objectIsValid(d_object(fellow), D_FELLOW) == TRUE); + + if(fellow){ + d_lockLock(d_lock(fellow)); + + if(fellow->nameSpaces){ + d_tableWalk(fellow->nameSpaces, clearMaster, master); + } + d_lockUnlock(d_lock(fellow)); + } + return; +} + +c_ulong +d_fellowNameSpaceCount( + d_fellow fellow) +{ + c_ulong count; + + assert(d_objectIsValid(d_object(fellow), D_FELLOW) == TRUE); + + if(fellow){ + d_lockLock(d_lock(fellow)); + + if(fellow->nameSpaces){ + count = d_tableSize(fellow->nameSpaces); + } else { + count = 0; + } + d_lockUnlock(d_lock(fellow)); + } else { + count = 0; + } + return count; +} + +c_bool +d_fellowAreNameSpacesComplete( + d_fellow fellow) +{ + c_bool result; + + assert(d_objectIsValid(d_object(fellow), D_FELLOW) == TRUE); + + if(fellow){ + d_lockLock(d_lock(fellow)); + + if(fellow->nameSpaces){ + if(fellow->expectedNameSpaces == d_tableSize(fellow->nameSpaces)){ + result = TRUE; + } else { + result = FALSE; + } + } else { + if(fellow->expectedNameSpaces == 0){ + result = TRUE; + } else { + result = FALSE; + } + } + d_lockUnlock(d_lock(fellow)); + } else { + result = FALSE; + } + return result; +} + +c_ulong +d_fellowGetExpectedNameSpaces( + d_fellow fellow) +{ + c_ulong count = 0; + + assert(d_objectIsValid(d_object(fellow), D_FELLOW) == TRUE); + + if(fellow){ + d_lockLock(d_lock(fellow)); + count = fellow->expectedNameSpaces; + d_lockUnlock(d_lock(fellow)); + } + return count; +} + +void +d_fellowSetExpectedNameSpaces( + d_fellow fellow, + c_ulong expected) +{ + assert(d_objectIsValid(d_object(fellow), D_FELLOW) == TRUE); + + if(fellow){ + d_lockLock(d_lock(fellow)); + fellow->expectedNameSpaces = expected; + d_lockUnlock(d_lock(fellow)); + } + return; +} + +c_bool +d_fellowNameSpaceWalk( + d_fellow fellow, + c_bool ( * action ) (d_nameSpace nameSpace, c_voidp userData), + c_voidp userData) +{ + c_bool result; + assert(d_objectIsValid(d_object(fellow), D_FELLOW) == TRUE); + + result = TRUE; + + if(fellow){ + d_lockLock(d_lock(fellow)); + + if(fellow->nameSpaces){ + result = d_tableWalk(fellow->nameSpaces, action, userData); + } + d_lockUnlock(d_lock(fellow)); + } + return result; +} + +void +d_fellowRequestAdd( + d_fellow fellow) +{ + assert(d_objectIsValid(d_object(fellow), D_FELLOW) == TRUE); + + if(fellow){ + d_lockLock(d_lock(fellow)); + fellow->requestCount++; + assert(fellow->requestCount >= 1); + d_lockUnlock(d_lock(fellow)); + } + return; +} + +void +d_fellowRequestRemove( + d_fellow fellow) +{ + assert(d_objectIsValid(d_object(fellow), D_FELLOW) == TRUE); + + if(fellow){ + d_lockLock(d_lock(fellow)); + assert(fellow->requestCount >= 1); + fellow->requestCount--; + d_lockUnlock(d_lock(fellow)); + } + return; +} + +c_ulong +d_fellowRequestCountGet( + d_fellow fellow) +{ + c_ulong count = 0; + + assert(d_objectIsValid(d_object(fellow), D_FELLOW) == TRUE); + + if(fellow){ + d_lockLock(d_lock(fellow)); + count = fellow->requestCount; + d_lockUnlock(d_lock(fellow)); + } + return count; +} + +void +d_fellowRequestCountSet( + d_fellow fellow, + c_ulong count) +{ + assert(d_objectIsValid(d_object(fellow), D_FELLOW) == TRUE); + + if(fellow){ + d_lockLock(d_lock(fellow)); + fellow->requestCount = count; + d_lockUnlock(d_lock(fellow)); + } + return; +} + +c_bool +d_fellowIsCompleteForGroup( + d_fellow fellow, + const c_char* partition, + const c_char* topic, + d_durabilityKind kind) +{ + c_bool result = FALSE; + d_group group; + + assert(d_objectIsValid(d_object(fellow), D_FELLOW) == TRUE); + + if(fellow){ + group = d_fellowGetGroup(fellow, partition, topic, kind); + + if(group){ + if(d_groupGetCompleteness(group) == D_GROUP_COMPLETE){ + result = TRUE; + } + d_groupFree(group); + } + } + return result; +} + + + +static c_bool +isAligner( + d_nameSpace nameSpace, + c_voidp args) +{ + struct alignerHelper* helper; + + helper = (struct alignerHelper*)args; + + helper->aligner = d_adminInNameSpace( + nameSpace, + (d_partition)(helper->partition), + (d_topic)(helper->topic), + TRUE); + helper->masterPriority = d_nameSpaceGetMasterPriority(nameSpace); + return (!helper->aligner); +} + +d_fellowAlignStatus +d_fellowIsAlignerForGroup( + d_fellow fellow, + const c_char* partition, + const c_char* topic, + d_durabilityKind kind, + c_ulong *masterPriority) +{ + struct alignerHelper helper; + d_fellowAlignStatus status; + + assert(d_objectIsValid(d_object(fellow), D_FELLOW) == TRUE); + + *masterPriority = D_MINIMUM_MASTER_PRIORITY; + if(fellow){ + helper.partition = partition; + helper.topic = topic; + helper.kind = kind; + helper.aligner = FALSE; + helper.masterPriority = D_MINIMUM_MASTER_PRIORITY; + + d_lockLock(d_lock(fellow)); + + if(fellow->nameSpaces){ + d_tableWalk(fellow->nameSpaces, isAligner, &helper); + /* Make sure to return the masterPriority of the fellow namespace + * It is used in findAligner to determine whether the fellow + * is a candidate aligner */ + *masterPriority = helper.masterPriority; + if(helper.aligner == FALSE){ + status = D_ALIGN_FALSE; + } else { + status = D_ALIGN_TRUE; + } + } else { + status = D_ALIGN_FALSE; + } + d_lockUnlock(d_lock(fellow)); + } else { + status = D_ALIGN_FALSE; + } + return status; +} + +static c_bool +inNameSpace( + d_nameSpace nameSpace, + c_voidp args) +{ + struct alignerHelper* helper; + + helper = (struct alignerHelper*)args; + + helper->aligner = d_adminInNameSpace( + nameSpace, + (d_partition)(helper->partition), + (d_topic)(helper->topic), + FALSE); + + return (!helper->aligner); +} + +c_bool +d_fellowIsGroupInNameSpaces( + d_fellow fellow, + const c_char* partition, + const c_char* topic, + d_durabilityKind kind) +{ + struct alignerHelper helper; + c_bool result; + + assert(d_objectIsValid(d_object(fellow), D_FELLOW) == TRUE); + + if(fellow){ + helper.partition = partition; + helper.topic = topic; + helper.kind = kind; + helper.aligner = FALSE; + + d_lockLock(d_lock(fellow)); + + if(fellow->nameSpaces){ + d_tableWalk(fellow->nameSpaces, inNameSpace, &helper); + } + result = helper.aligner; + + d_lockUnlock(d_lock(fellow)); + } else { + result = FALSE; + } + return result; +} + + +static c_bool +isNSAligner( + d_nameSpace nameSpace, + c_voidp args) +{ + struct alignerNSHelper* helper; + c_bool match; + + helper = (struct alignerNSHelper*)args; + match = (d_nameSpaceCompatibilityCompare(nameSpace, helper->nameSpace) == 0); + + if(match == TRUE){ + helper->aligner = d_nameSpaceIsAligner(nameSpace); + } + return (!helper->aligner); +} + +d_fellowAlignStatus +d_fellowIsAlignerForNameSpace( + d_fellow fellow, + d_nameSpace nameSpace) +{ + struct alignerNSHelper helper; + d_fellowAlignStatus status; + + assert(d_objectIsValid(d_object(fellow), D_FELLOW) == TRUE); + + if(fellow){ + helper.nameSpace = nameSpace; + helper.aligner = FALSE; + + d_lockLock(d_lock(fellow)); + + if(fellow->nameSpaces){ + d_tableWalk(fellow->nameSpaces, isNSAligner, &helper); + + if(helper.aligner == FALSE){ + status = D_ALIGN_FALSE; + } else { + status = D_ALIGN_TRUE; + } + } else { + status = D_ALIGN_FALSE; + } + d_lockUnlock(d_lock(fellow)); + } else { + status = D_ALIGN_FALSE; + } + return status; +} + +void +d_fellowSetRole ( + d_fellow fellow, + d_name role) +{ + if (fellow) { + assert(d_objectIsValid(d_object(fellow), D_FELLOW) == TRUE); + d_lockLock(d_lock(fellow)); + + if (!fellow->role) { + fellow->role = os_strdup(role); + } + + d_lockUnlock(d_lock(fellow)); + } +} + +d_name +d_fellowGetRole ( + d_fellow fellow) +{ + d_name result; + + result = NULL; + + if (fellow) { + assert(d_objectIsValid(d_object(fellow), D_FELLOW) == TRUE); + d_lockLock(d_lock(fellow)); + + result = fellow->role; + + d_lockUnlock(d_lock(fellow)); + } + + return result; +} + + +void +d_fellowAddReader( + d_fellow fellow, + c_ulong reader) +{ + assert(d_fellowIsValid(fellow)); + + /* If a new reader is discovered then add the reader flag + * to the fellow and check if the fellow has become responsive. + * + * There is no need to lock the fellow when modifying the + * reader flags because only a single thread calls this + * function. + */ + if ((fellow->readers & reader) == 0) { + d_durability durability = d_threadsDurability(); + d_networkAddress fellowAddr; + + fellowAddr = d_fellowGetAddress(fellow); + fellow->readers |= reader; + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Durability reader %04lx of fellow %u discovered (readers: %04lx, required readers: %04lx).\n", + reader, fellowAddr->systemId, fellow->readers, fellow->requiredReaders); + /* Check whether or not to send capabilities to the fellow for the first time */ + d_fellowCheckSendCapabilities(fellow, TRUE); + /* Check initial responsiveness */ + d_fellowCheckInitialResponsiveness(fellow); + + d_networkAddressFree(fellowAddr); + } +} + + +void +d_fellowRemoveReader( + d_fellow fellow, + c_ulong reader) +{ + d_fellow fellow2; + c_bool oldResponsive, newResponsive; + + assert(d_fellowIsValid(fellow)); + + /* A previously discovered reader was lost for the fellow. + * Reset the reader flag for this fellow and recheck if + * responsiveness is not lost. + * + * There is no need to lock the fellow when modifying the + * reader flags because only a single thread calls this + * function. + */ + if ((fellow->readers & reader) == reader) { + d_durability durability = d_threadsDurability(); + d_configuration config = d_durabilityGetConfiguration(durability); + d_networkAddress fellowAddr; + + fellowAddr = d_fellowGetAddress(fellow); + oldResponsive = d_fellowIsResponsive(fellow, config->waitForRemoteReaders); + fellow->readers &= (~reader); + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Durability reader %lx of fellow %u lost (readers: %lx, requiredReaders: %lx).\n", + reader, fellowAddr->systemId, fellow->readers, fellow->requiredReaders); + newResponsive = d_fellowIsResponsive(fellow, config->waitForRemoteReaders); + if ((oldResponsive) && !newResponsive) { + d_admin admin; + + admin = durability->admin; + /* The fellow has just become non-responsive */ + d_printTimedEvent(durability, D_LEVEL_FINER, + "Fellow %u has become non-responsive, removing the fellow\n", + fellowAddr->systemId); + fellow2 = d_adminRemoveFellow(admin, fellow, FALSE); + if (fellow2) { + d_fellowFree(fellow2); + } + } + d_networkAddressFree(fellowAddr); + } +} + +/** + * \brief Return the 'confirmed' status of the fellow. + * + * @return TRUE if the fellow is confirmed, FALSE otherwise. + */ +c_bool +d_fellowIsConfirmed( + d_fellow fellow) +{ + c_bool result; + + assert(d_fellowIsValid(fellow)); + + d_lockLock(d_lock(fellow)); + result = fellow->isConfirmed; + d_lockUnlock(d_lock(fellow)); + return result; +} + +/** + * \brief Set the 'confirmed' property of the fellow. + * + * If the fellow moves from 'unconfirmed' to 'confirmed' then + * the fellow->hasConfirmed property is set to TRUE. + */ +void +d_fellowSetConfirmed( + d_fellow fellow, + c_bool confirmed) +{ + assert(d_objectIsValid(d_object(fellow), D_FELLOW)); + + d_lockLock(d_lock(fellow)); + if ((!fellow->isConfirmed) && (confirmed == TRUE)) { + /* The fellow moves from unconfirmed to confirmed, + * so set fellow->hasConfirmed. + */ + fellow->hasConfirmed = TRUE; + } + fellow->isConfirmed = confirmed; + d_lockUnlock(d_lock(fellow)); +} + + +/** + * \brief Returns whether the fellow has recently become confirmed. + * + * When the fellow has recently become confirmed TRUE will be returned and + * its hasConfirmed property is reset to FALSE. + * + * @return TRUE if the fellow has recently become confirmed, FALSE otherwise + */ +c_bool +d_fellowHasConfirmed( + d_fellow fellow) +{ + c_bool result = FALSE; + + assert(d_objectIsValid(d_object(fellow), D_FELLOW)); + + d_lockLock(d_lock(fellow)); + if (fellow->hasConfirmed) { + /* Reset hasConfirmed to prevent that the same fellow + * is considered a recently confirmed fellow again. + */ + result = TRUE; + fellow->hasConfirmed = FALSE; + } + d_lockUnlock(d_lock(fellow)); + return result; +} + + +/** + * \brief Check whether a message that the fellow has recently terminated is + * printed or not. + * + * When the message has not been printed FALSE is returned and + * fellow->recentlyTerminated is set to TRUE to prevent that + * the same message is printed the next time. + * + * @return FALSE, if the has not been printed, TRUE otherwise. + */ +c_bool +d_fellowHasRecentlyTerminated( + d_fellow fellow) +{ + c_bool result = TRUE; + + assert(d_objectIsValid(d_object(fellow), D_FELLOW)); + + d_lockLock(d_lock(fellow)); + if (!fellow->recentlyTerminated) { + /* Prevent printing of messages the next time. */ + fellow->recentlyTerminated = TRUE; + result = FALSE; + } + d_lockUnlock(d_lock(fellow)); + return result; +} + + +/** + * \brief Verify if all required readers of this fellow have been discovered. + * + * @return FALSE, if the fellow must wait for remote readers but not all remote readers have been discovered yet, + * TRUE, otherwise + */ +c_bool +d_fellowHasAllRequiredReaders( + d_fellow fellow, + c_bool waitForRemoteReaders) +{ + c_bool result = TRUE; + + assert(d_fellowIsValid(fellow)); + + d_lockLock(d_lock(fellow)); + if (waitForRemoteReaders) { + /* Check if all required readers are discovered. */ + result = (((fellow->readers) & (fellow->requiredReaders)) == (fellow->requiredReaders)); + } + d_lockUnlock(d_lock(fellow)); + return result; +} + +/** + * \brief Check if all readers in the mask have been discovered for the fellow + * + * If waitForRemoteReaders is FALSE then there is no need to discover readers, + * so TRUE is returned. + */ +c_bool +d_fellowHasDiscoveredReaders( + d_fellow fellow, + c_ulong mask, + c_bool waitForRemoteReaders) +{ + c_bool result = TRUE; + + assert(d_fellowIsValid(fellow)); + + if (waitForRemoteReaders) { + /* Check if the discovered readers of the fellow + * match the ones specified in the mask. + */ + result = (((fellow->readers) & (mask)) == (mask)); + } + return result; + +} + +c_long +d_fellowSetLastDisposeCount( + d_fellow fellow, + c_long disposeCount) +{ + c_long prevCount; + + assert(d_objectIsValid(d_object(fellow), D_FELLOW)); + + d_lockLock(d_lock(fellow)); + prevCount = fellow->heartbeatDisposeCount; + fellow->heartbeatDisposeCount = disposeCount; + d_lockUnlock(d_lock(fellow)); + + return prevCount; +} + +c_long +d_fellowGetLastDisposeCount( + d_fellow fellow) +{ + c_long prevCount; + + assert(d_objectIsValid(d_object(fellow), D_FELLOW)); + + d_lockLock(d_lock(fellow)); + prevCount = fellow->heartbeatDisposeCount; + d_lockUnlock(d_lock(fellow)); + + return prevCount; +} + + +/** + * \brief Set capability support for the fellow to the specified value. + */ +void +d_fellowSetCapabilitySupport( + d_fellow fellow, + c_bool capabilitySupport) +{ + d_durability durability = d_threadsDurability(); + + assert(d_fellowIsValid(fellow)); + + d_lockLock(d_lock(fellow)); + if (!capabilitySupport) { + /* The fellow has no support for capabilities. + * This means we do NOT have to wait for the + * remote d_capability reader to check if all + * readers have become available. + * Update the fellow if not done so already + */ + if (fellow->capabilitySupport) { + durability = d_threadsDurability(); + + fellow->capabilitySupport = FALSE; + /* Reset the flag for the capability interface in the mask */ + fellow->requiredReaders = fellow->requiredReaders & (~D_CAPABILITY_READER_FLAG); + + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Fellow %u has NO capability support, required readers becomes %04lx\n", + fellow->address->systemId, fellow->requiredReaders); + + } + } else { + /* The fellow has support for capabilities. + * This means we must wait for the d_capability + * reader to be present. + * Update the fellow if not done so already + */ + if (!fellow->capabilitySupport) { + + fellow->capabilitySupport = TRUE; + /* Set the flag for the capability interface in the mask */ + fellow->requiredReaders = fellow->requiredReaders | (D_CAPABILITY_READER_FLAG); + + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Fellow %u has capability support, required readers becomes %04lx\n", + fellow->address->systemId, fellow->requiredReaders); + + } + } + d_lockUnlock(d_lock(fellow)); +} + + +/** + * \brief Set the capabilities of the fellow + */ +void +d_fellowSetCapability( + d_fellow fellow, + d_capability capability) +{ + c_ulong i, length; + struct d_nameValue_s *cap; + c_bool has_y2038_capability = FALSE; + d_durability durability = d_threadsDurability(); + c_bool check_for_conflicts = FALSE; + c_bool incarnation_present = FALSE; + c_ulong incarnation = 0; + c_bool progress; + const c_ulong thres = 1u << (8* sizeof(c_ulong)-1); + + assert(d_fellowIsValid(fellow)); + + if (capability) { + d_conflictMonitor conflictMonitor = durability->admin->conflictMonitor; + + d_lockLock(d_lock(fellow)); + + /* Store the capabilities received */ + length = c_sequenceSize(capability->capabilities); + + for (i = 0; i < length; i++) { + cap = &((struct d_nameValue_s *)capability->capabilities)[i]; + + /* Group hash capability */ + if (strcmp(cap->name, D_CAPABILITY_GROUP_HASH) == 0) { + fellow->capabilities.groupHash = (((c_octet *)cap->value)[0] == 0) ? FALSE : TRUE; + /* EOT support capability */ + } else if (strcmp(cap->name, D_CAPABILITY_EOT_SUPPORT) == 0) { + fellow->capabilities.EOTSupport = (((c_octet *)cap->value)[0] == 0) ? FALSE : TRUE; + } else if (strcmp(cap->name, D_CAPABILITY_MASTER_SELECTION) == 0) { + c_ulong version; + memcpy (&version, cap->value, sizeof (c_ulong)); + fellow->capabilities.masterSelection = d_swap4uFromBE(version); + } else if (strcmp(cap->name, D_CAPABILITY_INCARNATION) == 0) { + c_ulong inc; + memcpy(&inc, cap->value, sizeof(c_ulong)); + incarnation = d_swap4uFromBE(inc); + incarnation_present = TRUE; + } else if (strcmp(cap->name, D_CAPABILITY_Y2038READY) == 0) { + /* Y2038Ready support + * Receiving this capability means that the fellow is capable to receive extended (64-bit) times. + * It does not mean that the fellow actually sends extended timestamp, + * that depends on the actual value + */ + fellow->capabilities.Y2038Ready = (((c_octet *)cap->value)[0] == 0) ? FALSE : TRUE; + has_y2038_capability = TRUE; + } + /* Any other capability that is send to me I cannot understand, I simply ignore it. */ + } /* for */ + + /* If a fellow does not specify an incarnation, then the best guess + * is to take the new incarnation as the increment of the incarnation + */ + if (!incarnation_present) { + incarnation = fellow->capabilities.incarnation+1; + } + + /* Now incarnation contains the new incarnation, even in case the received + * capabilities did not contain an incarnation at all + */ + + /* Incarnations are assumed to be monotonically increasing (modulo wrapping) */ + progress = ((incarnation > fellow->capabilities.incarnation) && (incarnation - fellow->capabilities.incarnation < thres)) || + ((incarnation < fellow->capabilities.incarnation) && (incarnation > thres - fellow->capabilities.incarnation)); + + + /* Detect asymmetric disconnect, ignore the first time the fellow was detected + * Account for possible wrapping, see https://en.wikipedia.org/wiki/Serial_number_arithmetic + */ + if ( (fellow->capabilities.incarnation != 0) && progress) { + /* A new incarnation is received, meaning the fellow has disconnected from + * me and reconnected to me without me noticing it. This is an asymmetrical + * disconnect + */ + + d_printTimedEvent(durability, D_LEVEL_FINE, + "Fellow %u was asymmetrically disconnected from me, I may have published data that was missed by the fellow.\n", + fellow->address->systemId); + + check_for_conflicts = TRUE; + + /* Drop all knowledge of the fellow's namespaces to not interact with it until + * after it has responded to our namespace request + */ + if (fellow->nameSpaces) { + d_tableFree(fellow->nameSpaces); + fellow->nameSpaces = NULL; /* New initializes it lazily, too */ + } + } + + /* To prevent stuttering we only update the incarnation state in case progress was made */ + if (progress) { + fellow->capabilities.incarnation = incarnation; + } + + d_lockUnlock(d_lock(fellow)); + + /* I received a new capability from the fellow + * so I may have to send my capability back + */ + if (progress) { + d_fellowCheckSendCapabilities(fellow, FALSE); + } + + /* If this fellow does NOT advertise the D_CAPABILITY_Y2038READY + * capability, then this fellow must be a legacy fellow that is + * not capable to understand time stamps beyond 2038. In that case + * we may not advertise 64-bit times. If we do, then we have an + * invalid system configuration, but continue anyway. + */ + if ((!has_y2038_capability) && (durability->configuration->capabilityY2038Ready)) { + /* I advertise timestamps beyond 2038. In + * combination with legacy fellows this is + * considered an invalid configuration + */ + OS_REPORT(OS_FATAL, D_CONTEXT, 0, + "I advertise timestamps that go beyond 2038, but federation with "\ + "systemid %"PA_PRIu32" can only understand legacy timestamps.\n" \ + "This is considered an invalid configuration, see the user manual for information", + fellow->address->systemId); + } + if (check_for_conflicts) { + /* Schedule a conflict to resolve the asymmetric disconnect */ + d_conflictMonitorCheckFellowDisconnected(conflictMonitor, fellow); + d_fellowSendNSRequest(fellow); + } + } + return; +} + + +/** + * \brief Check if a fellow supports capabilities + * + * @return TRUE if the fellow's capabilitySupport attribute is set to TRUE and the fellow is confirmed + * FALSE, otherwise + * + * Note that unconfirmed fellows are never assumed to have capabilitySupport. + */ +c_bool +d_fellowHasCapabilitySupport( + d_fellow fellow) +{ + assert(d_fellowIsValid(fellow)); + + return fellow->capabilitySupport; +} + + +/** + * \brief Returns TRUE if all expected readers of the fellow have been discovered, + * and (fellow support capabilities => I must have received its capabilities) + * + * If there is no need to wait for remote readers then always TRUE is returned + */ +c_bool +d_fellowIsResponsive( + d_fellow fellow, + c_bool waitForRemoteReaders) +{ + d_durability durability = d_threadsDurability(); + d_configuration config = d_durabilityGetConfiguration(durability); + c_bool result = TRUE; + + assert(d_fellowIsValid(fellow)); + + /* All remote readers must have been discovered when ddsi is used */ + if (!d_fellowHasDiscoveredReaders(fellow, fellow->requiredReaders, waitForRemoteReaders)) { + result = FALSE; + + /* When capabilities are supported the fellow's capabilities must have been received */ + } else if (config->capabilitySupport) { + /* I have capability support + * If the fellow has capability support then check if the capabilities are received + */ + if (d_fellowHasCapabilitySupport(fellow)) { + /* The fellow must have send me his capabilities at least once */ + result = (fellow->capabilities.incarnation > 0); + } + } + return result; +} + + +/** + * \brief Return if the fellow supports the capability to calculate group hashes + */ +c_bool +d_fellowHasCapabilityGroupHash ( + d_fellow fellow) +{ + assert(d_fellowIsValid(fellow)); + + if (fellow->capabilitySupport) { + return fellow->capabilities.groupHash; + } else { + return FALSE; + } +} + + +/** + * \brief Return if the fellow supports the capability to support alignment of EOTs + */ +c_bool +d_fellowHasCapabilityEOTSupport ( + d_fellow fellow) +{ + assert(d_fellowIsValid(fellow)); + + if (fellow->capabilitySupport) { + return fellow->capabilities.EOTSupport; + } else { + return FALSE; + } +} + + +/** + * \brief Return the fellow its masterSelectionVersion + */ +c_ulong +d_fellowGetCapabilityMasterSelection ( + d_fellow fellow) +{ + assert(d_fellowIsValid(fellow)); + + if (fellow->capabilitySupport) { + return fellow->capabilities.masterSelection; + } else { + return 0; + } +} + + +/** + * \brief Return true if the fellow can accept extended timestamps + */ +c_bool +d_fellowHasCapabilityY2038Ready ( + d_fellow fellow) +{ + assert(d_fellowIsValid(fellow)); + + if (fellow->capabilitySupport) { + return fellow->capabilities.Y2038Ready; + } else { + return FALSE; + } +} + + +/** + * \brief Request nameSpaces from fellow + */ +void +d_fellowSendNSRequest( + d_fellow fellow) +{ + d_durability durability; + d_admin admin; + d_publisher publisher; + d_nameSpacesRequest request; + + assert(d_fellowIsValid(fellow)); + + durability = d_threadsDurability(); + admin = durability->admin; + publisher = d_adminGetPublisher(admin); + + d_printTimedEvent(durability, D_LEVEL_FINE, + "Requesting nameSpaces from fellow %u.\n", + fellow->address->systemId); + request = d_nameSpacesRequestNew(admin); + d_messageSetAddressee(d_message(request), fellow->address); + d_publisherNameSpacesRequestWrite(publisher, request, fellow->address, d_durabilityGetState(durability)); + d_nameSpacesRequestFree(request); +} + + +/* Send my capabilities + * + * The initial parameter indicates whether the function is called to send out the + * initial capability, or whether a capability has to be sent out because an + * asymmetrical disconnect was detected. + */ +void +d_fellowCheckSendCapabilities( + d_fellow fellow, c_bool initial) +{ + d_durability durability; + d_admin admin; + d_publisher publisher; + d_capability capability; + d_configuration config; + + assert(d_fellowIsValid(fellow)); + + durability = d_threadsDurability(); + admin = durability->admin; + publisher = d_adminGetPublisher(admin); + config = d_durabilityGetConfiguration(durability); + + /* Ensure that capabilities are sent once to the fellow + * Capabilities may only be sent when the fellow is past its initializing state + */ + d_lockLock(d_lock(fellow)); + + /* skip if request is initial, but an incarnation has already been sent to the fellow */ + if (initial && (fellow->incarnation != 0)) { + goto skip; + } + + /* skip if I do not support capabilities */ + if (!config->capabilitySupport) { + goto skip; + } + + /* skip if fellow does not support capabilities */ + if (!fellow->capabilitySupport) { + goto skip; + } + + /* skip if the fellow's capability reader has not yet been discovered in case ddsi is being used*/ + if ((config->waitForRemoteReaders) && + ((fellow->readers & D_CAPABILITY_READER_FLAG) != D_CAPABILITY_READER_FLAG)) { + goto skip; + } + + /* skip if fellow is still initializing */ + if ((d_fellowGetState(fellow) == D_STATE_INIT) || d_fellowGetState(fellow) >= D_STATE_TERMINATING) { + goto skip; + } + + /* skip if I am still initializing */ + if ((d_durabilityGetState(durability) == D_STATE_INIT) || d_fellowGetState(fellow) >= D_STATE_TERMINATING) { + goto skip; + } + + d_printTimedEvent(durability, D_LEVEL_FINE, "Sending my capabilities to fellow %u.\n", + fellow->address->systemId); + + /* Set the incarnation that I must sent to the fellow + * Determine a new value when no incarnation is set before + */ + if (fellow->incarnation == 0) { + fellow->incarnation = d_durabilityGetNewIncarnation(durability); + } + + /* Send the capability */ + capability = d_capabilityNew(admin, fellow->incarnation); + d_messageSetAddressee(d_message(capability), fellow->address); + d_publisherCapabilityWrite(publisher, capability, fellow->address); + d_capabilityFree(capability); + + d_lockUnlock(d_lock(fellow)); + return; + +skip: + d_lockUnlock(d_lock(fellow)); + return; +} + +os_uint32 +d_fellowGetLastSeqNum( + d_fellow fellow) +{ + os_uint32 lastSeqNum; + + assert(d_fellowIsValid(fellow)); + + lastSeqNum = fellow->lastSeqNum; + return lastSeqNum; +} + +c_bool +d_fellowHasRecentlyJoined( + d_fellow fellow) +{ + c_bool result; + + assert(d_fellowIsValid(fellow)); + + d_lockLock(d_lock(fellow)); + result = fellow->recently_joined; + d_lockUnlock(d_lock(fellow)); + return result; +} + +void +d_fellowCheckInitialResponsiveness( + d_fellow fellow) +{ + d_durability durability = d_threadsDurability(); + d_configuration config = d_durabilityGetConfiguration(durability); + + d_lockLock(d_lock(fellow)); + if (d_fellowIsResponsive(fellow, config->waitForRemoteReaders) && (!fellow->responsive)) { + /* The fellow has become responsive for the first time, so I have discovered + * its readers and capabilities. We can safely sent a namespacesRequest to + * the fellow now to start the durability protocol + */ + fellow->responsive = TRUE; + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Fellow %u became responsive, I am going to send a request for namespaces to this fellow\n", + fellow->address->systemId); + d_fellowSendNSRequest(fellow); + /* If the fellow already sent a request for namespaces, then send the namespaces now */ + if (fellow->has_requested_namespaces) { + /* Create a request to send namesSpaces to the fellow */ + d_admin admin = durability->admin; + d_publisher publisher = d_adminGetPublisher(admin); + d_networkAddress myAddr = d_adminGetMyAddress(admin); + d_nameSpacesRequest request; + + d_printTimedEvent(durability, D_LEVEL_FINE, + "Going to answer cached namespace request to fellow %u.\n", fellow->address->systemId); + request = d_nameSpacesRequestNew(admin); + d_messageSetAddressee(d_message(request), myAddr); /* Send the nameSpacesRequest to myself. */ + d_messageSetSenderAddress(d_message(request), fellow->address); /* Pretend that the request to send the nameSpaces came from (0,0,0). */ + d_publisherNameSpacesRequestWrite(publisher, request, fellow->address, d_fellowGetState(fellow)); + d_nameSpacesRequestFree(request); + d_networkAddressFree(myAddr); + } + } + d_lockUnlock(d_lock(fellow)); + +} diff --git a/src/services/durability/code/d_filter.c b/src/services/durability/code/d_filter.c new file mode 100644 index 000000000..7803afbac --- /dev/null +++ b/src/services/durability/code/d_filter.c @@ -0,0 +1,209 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "d__filter.h" +#include "d__element.h" +#include "d__misc.h" +#include "os_report.h" +#include "ut_xmlparser.h" + +static c_bool +d_filterAddPartitionTopic( + d_filter filter, + const char *name, + const char *partition, + const char *topic) +{ + d_element element; + c_bool added = FALSE; + + assert(d_filterIsValid(filter)); + + element = d_elementNew(name, partition, topic); + if (element) { + c_iterAppend(filter->elements, element); + added = TRUE; + } + return added; +} + + +d_filter +d_filterNew ( + const char *xmlExpression) +{ + d_filter filter; + /* Allocate filter object */ + filter = d_filter(os_malloc(C_SIZEOF(d_filter))); + if (filter != NULL){ + /* Call super-init */ + d_objectInit(d_object(filter), D_FILTER, + (d_objectDeinitFunc)d_filterDeinit); + /* Initialize filter object */ + if (xmlExpression != NULL) { + filter->xmlExpression = os_strdup(xmlExpression); + } else { + filter->xmlExpression = NULL; + } + filter->elements = NULL; + filter->sqlExpression = NULL; + if (filter->xmlExpression != NULL) { + size_t n; + q_expr expr; + /* Construct a sqlExpression from the filter. + * The xmlxpression may contain escapes such as + * <, >, &, ', ", but the + * sql expression may not + */ + if ((filter->sqlExpression = os_strdup(xmlExpression)) == NULL) { + goto err_allocFilterSqlExpression; + } + n = strlen(xmlExpression); + if (ut_xmlUnescapeInsitu(filter->sqlExpression, &n) < 0) { + /* Parse <, >, &, ', " failed */ + OS_REPORT(OS_WARNING, D_CONTEXT, 0, + "Content attribute ' %s' in -element contains invalid escape sequences, terminate the durability service", filter->xmlExpression); + goto err_invalidUnescape; + } + assert(n<=strlen(xmlExpression)); + filter->sqlExpression[n] = '\0'; + if ((expr = (q_expr)q_parse(filter->sqlExpression)) == NULL) { + /* A filter with an invalid syntax is detected. This + * also covers the case where the content attribute + * is empty. + */ + OS_REPORT(OS_WARNING, D_CONTEXT, 0, + "The -element with content attribute '%s' has invalid sql syntax '%s', terminate the durability service", filter->xmlExpression, filter->sqlExpression); + goto err_invalidSqlExpression; + } + if (expr) { + q_dispose(expr); + } + } + filter->elements = c_iterNew(NULL); + } + return filter; + +err_invalidSqlExpression: +err_invalidUnescape: +err_allocFilterSqlExpression: + d_filterFree(filter); + return NULL; +} + + +void +d_filterDeinit ( + d_filter filter) +{ + assert(d_filterIsValid(filter)); + + if (filter->xmlExpression) { + os_free(filter->xmlExpression); + filter->xmlExpression = NULL; + } + if (filter->sqlExpression) { + os_free(filter->sqlExpression); + filter->sqlExpression = NULL; + } + if (filter->elements) { + d_element element; + + element = d_element(c_iterTakeFirst(filter->elements)); + while (element) { + d_elementFree(element); + element = d_element(c_iterTakeFirst(filter->elements)); + } + c_iterFree(filter->elements); + filter->elements = NULL; + } + /* Call super-deinit */ + d_objectDeinit(d_object(filter)); +} + + +void +d_filterFree ( + d_filter filter) +{ + assert(d_filterIsValid(filter)); + + d_objectFree(d_object(filter)); +} + + +c_bool +d_filterAddElement( + d_filter filter, + const char *name, + const char *partitionTopic, + const char *topicGiven) +{ + c_bool added = FALSE; + char *partition; + char *topic; + os_uint32 len1, len2; + + assert(d_filterIsValid(filter)); + + len1 = (os_uint32) (strlen(partitionTopic) + 1); + if (len1 < D_MAX_STRLEN_NAMESPACE) { + if (topicGiven) { + len2 = (os_uint32) (strlen(topicGiven) + 1); + if (len2 < D_MAX_STRLEN_NAMESPACE) { + added = d_filterAddPartitionTopic(filter, name, partitionTopic, topicGiven); + } + } else { + /* The topic is not given. If the partitionTopic string contains + * a '.', then try to split the string in a partition part and a + * topic part. If there is no topic then use '*' by default. + */ + partition = os_malloc(len1); + os_strncpy(partition, partitionTopic, len1); + /* Make topic point to last character in partition string. + * partition points to first character and len1 + * includes '\0', so subtract 2 to point to last character. + */ + topic = partition + (len1-2); + /* QAC EXPECT 2106,3123; */ + while ((*topic != '.') && (topic != partition)) { + /* QAC EXPECT 0489; */ + topic--; + } + /* QAC EXPECT 2106,3123; */ + if (*topic == '.') { + *topic = 0; + /* QAC EXPECT 0489; */ + topic++; + /* QAC EXPECT 2106; */ + if (*topic != 0) { + added = d_filterAddPartitionTopic(filter, name, partition, topic); + } + } else { + /* Though was used in the filter, only + * a partition is provided. In that case assume the topic + * top be '*' + */ + added = d_filterAddPartitionTopic(filter, name, partition, "*"); + } + os_free(partition); + } + } + return added; +} + diff --git a/src/services/durability/code/d_group.c b/src/services/durability/code/d_group.c new file mode 100644 index 000000000..cc7ace291 --- /dev/null +++ b/src/services/durability/code/d_group.c @@ -0,0 +1,517 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "d__group.h" +#include "d__misc.h" +#include "d__durability.h" +#include "d__configuration.h" +#include "d__conflictResolver.h" +#include "d__durabilityStateRequest.h" +#include "d__durabilityStateRequestListener.h" +#include "d__subscriber.h" +#include "d__eventListener.h" +#include "vortex_os.h" +#include "d__thread.h" + +d_group +d_groupNew( + const c_char* partition, + const c_char* topic, + d_durabilityKind kind, + d_completeness completeness, + d_quality quality) +{ + d_group group = NULL; + + if (topic && partition) { + /* Allocate group object */ + group = os_malloc(sizeof *group); + /* Call super-init */ + d_objectInit(d_object(group), D_GROUP, (d_objectDeinitFunc)d_groupDeinit); + /* Initialize group */ + group->topic = os_strdup(topic); + group->partition = os_strdup(partition); + group->kind = kind; + group->completeness = completeness; + group->quality = quality; + group->vgroup = NULL; + group->storeCount = 0; + group->private = FALSE; + group->creationRetryCount = 0; /* Number of retries to create the group */ + group->storeMessagesLoaded = FALSE; + } + return group; +} + +void +d_groupSetKernelGroup( + d_group group, + v_group vgroup) +{ + assert(d_objectIsValid(d_object(group), D_GROUP) == TRUE); + assert(vgroup); + + if(group){ + group->vgroup = c_keep(vgroup); + } +} + +void +d_groupSetKernelGroupCompleteness( + _In_ d_group group, + _In_ c_bool complete) +{ + v_alignState c = complete ? V_ALIGNSTATE_COMPLETE : V_ALIGNSTATE_INCOMPLETE; + + assert(d_objectIsValid(d_object(group), D_GROUP) == TRUE); + assert(group->vgroup); + + if(group->completeness != D_GROUP_UNKNOWN) { + if(group->vgroup){ + v_groupCompleteSet(group->vgroup, c); + } + } +} + +void +d_groupSetKernelGroupNoInterest( + _In_ d_group group) +{ + assert(d_objectIsValid(d_object(group), D_GROUP) == TRUE); + assert(d_groupIsPrivate(group) || (d_groupGetCompleteness(group) == D_GROUP_UNKNOWN)); + assert(group->vgroup); + + if(group->vgroup){ + v_groupCompleteSet(group->vgroup, V_ALIGNSTATE_NO_INTEREST); + } +} + +v_group +d_groupGetKernelGroup( + d_group group) +{ + v_group result = NULL; + + assert(d_objectIsValid(d_object(group), D_GROUP) == TRUE); + + if(group){ + result = c_keep(group->vgroup); + } + return result; +} + +void +d_groupDeinit( + d_group group) +{ + + assert(d_groupIsValid(group)); + + os_free(group->topic); + os_free(group->partition); + + if (group->vgroup) { + /* TODO: can't just c_free something from user-space. OSPL-9419 */ + c_free(group->vgroup); + } + /* Call super-deinit */ + d_objectDeinit(d_object(group)); +} + + +void +d_groupFree( + d_group group) +{ + assert(d_groupIsValid(group)); + + d_objectFree(d_object(group)); +} + + +/** + * \brief Return the completeness of a group + * + * The completeness of a group is primarily determined by the completeness + * of the associated vgroup. This will always give the correct group + * completeness, even if durability is not responsible for alignment of the + * group. For example, if durability does not align the builtin topics + * because DDSI is responsible for discovery, then the completeness of + * the group will remain D_GROUP_KNOWLEDGE_UNDEFINED although the vgroup + * can be complete. If a historicalDataRequest for a builtin topic is received + * then the advertised completeness of the group should be D_GROUP_COMPLETE + * and not D_GROUP_KNOWLEDGE_UNDEFINED. + */ +d_completeness +d_groupGetCompleteness( + d_group group) +{ + d_completeness result; + + if (group) { + result = group->completeness; + } else { + result = D_GROUP_KNOWLEDGE_UNDEFINED; + } + return result; +} + + +void +d_groupUpdate( + d_group group, + d_completeness completeness, + d_quality quality, + d_admin admin) +{ + c_bool changed; + + assert(d_groupIsValid(group)); + assert(d_adminIsValid(admin)); + + /* TEMPORARY SOLUTION: + * Prevent that a D_COMPLETE state becomes 'not D_COMPLETE'. + * This is a temporary solution for a bigger problem that + * causes old information to be send later than new information. + * OSPL-5057 is there to fix this. + */ + if (!((group->completeness == D_GROUP_COMPLETE) && (completeness != D_GROUP_COMPLETE))) { + changed = (group->completeness != completeness); + group->completeness = completeness; + group->quality = quality; + /* Publish the completeness state if it has changed */ + if (changed) { + d_groupPublishStateUpdate(group, admin); + } + } +} + +void +d_groupSetComplete( + d_group group, + d_admin admin) +{ + d_conflict conflict; + d_durability durability; + + assert(d_groupIsValid(group)); + assert(d_adminIsValid(admin)); + + group->quality = D_QUALITY_INFINITE; + if(group->completeness != D_GROUP_COMPLETE) { + + durability = d_adminGetDurability(admin); + conflict = d_conflictNew(D_CONFLICT_LOCAL_GROUP_COMPLETE, NULL, NULL, NULL); + d_conflictSetId(conflict, durability); + d_printTimedEvent(durability, D_LEVEL_FINEST, "Local group complete conflict created for group '%s.%s', conflict %d created\n", + group->partition, group->topic, d_conflictGetId(conflict)); + d_conflictResolverAddConflict(durability->admin->conflictResolver, conflict); + + group->completeness = D_GROUP_COMPLETE; + d_adminReportGroup(admin, group); + } + + /* Publish the completeness state */ + d_groupPublishStateUpdate(group, admin); +} + +void +d_groupSetNoInterest( + d_group group, + d_admin admin) +{ + assert(d_groupIsValid(group)); + assert(d_adminIsValid(admin)); + + group->quality = OS_TIMEW_INIT(0,0); + group->completeness = D_GROUP_UNKNOWN; + + /* Publish the completeness state */ + d_groupPublishStateUpdate(group, admin); +} + +void +d_groupSetUnaligned( + d_group group, + d_admin admin) +{ + assert(d_groupIsValid(group)); + assert(d_adminIsValid(admin)); + + group->quality = D_QUALITY_ZERO; + group->completeness = D_GROUP_UNKNOWN; + if (group->vgroup) { + v_groupCompleteSet(group->vgroup, V_ALIGNSTATE_NO_INTEREST); + } + /* Publish the completeness state */ + d_groupPublishStateUpdate(group, admin); +} + +void d_groupSetIncomplete( + d_group group, + d_admin admin) +{ + assert(d_groupIsValid(group)); + assert(d_adminIsValid(admin)); + + group->quality = D_QUALITY_ZERO; + group->completeness = D_GROUP_INCOMPLETE; + + /* Publish the completeness state */ + d_groupPublishStateUpdate(group, admin); +} + +int +d_groupCompare( + d_group group1, + d_group group2) +{ + int result; + + result = 0; + + if (group1 != group2) { + result = strcmp(group1->topic, group2->topic); + + if (result == 0) { + result = strcmp(group1->partition, group2->partition); + } + } + return result; +} + +d_partition +d_groupGetPartition( + d_group group) +{ + d_partition p; + + assert(d_objectIsValid(d_object(group), D_GROUP) == TRUE); + p = NULL; + + if ((group) && (group->partition != NULL)) { + p = os_strdup(group->partition); + } + return p; +} + +d_topic +d_groupGetTopic( + d_group group) +{ + d_topic t; + + assert(d_objectIsValid(d_object(group), D_GROUP) == TRUE); + t = NULL; + + if ((group) && (group->topic != NULL)) { + t = os_strdup(group->topic); + } + return t; +} + +d_durabilityKind +d_groupGetKind( + d_group group) +{ + d_durabilityKind k; + + assert(d_objectIsValid(d_object(group), D_GROUP) == TRUE); + + if(group){ + k = group->kind; + } else { + k = D_DURABILITY_VOLATILE; + } + return k; +} + +d_quality +d_groupGetQuality( + d_group group) +{ + assert(d_groupIsValid(group)); + + return group->quality; +} + +c_bool +d_groupIsBuiltinGroup( + d_group group) +{ + assert(d_objectIsValid(d_object(group), D_GROUP) == TRUE); + if(group){ + return d_isBuiltinGroup (group->partition, group->topic); + } else { + return FALSE; + } +} + +void +d_groupSetPrivate( + d_group group, + c_bool isPrivate) +{ + assert(d_groupIsValid(group)); + + group->private = isPrivate; + return; +} + +c_bool +d_groupIsPrivate( + d_group group) +{ + assert(d_groupIsValid(group)); + + return group->private; +} + +void +d_groupSetStoreMessagesLoaded( + d_group group, + c_bool isLoaded) +{ + assert(d_groupIsValid(group)); + + group->storeMessagesLoaded = isLoaded; + return; +} + +c_bool +d_groupIsStoreMessagesLoaded( + d_group group) +{ + assert(d_groupIsValid(group)); + + return group->storeMessagesLoaded; +} + + +/** + * \brief Publish a durabilityState update for the group, but only if client-durability + * is enabled. + * + * The state is published immediately. + */ +void +d_groupPublishStateUpdate ( + d_group group, + d_admin admin) +{ + d_durability durability; + d_configuration config; + d_subscriber subscriber; + d_durabilityStateRequestListener dsrlistener = NULL; + d_historicalDataRequestListener hdrlistener = NULL; + struct _DDS_DurabilityVersion_t version; + struct _DDS_RequestId_t requestId; + d_topic topic; + d_partition partition; + c_iter partitions; + c_iter serverIds; + c_time timeout; + c_iter extensions; + d_durabilityStateRequest request = NULL; + + assert(d_groupIsValid(group)); + assert(d_adminIsValid(admin)); + + durability = d_adminGetDurability(admin); + config = d_durabilityGetConfiguration(durability); + if (config->clientDurabilityEnabled) { + /* Trigger the publication of a durabilityState message to everybody. + * This is done by creating a (fake) durabilityStateRequest and + * adding this request to the durabilityStateRequestListener. + */ + version = d_durabilityGetMyVersion(durability); /* Pretend that the request came from a server with the same version as me */ + requestId = d_durabilityGetRequestId(durability); /* Get a new request Id */ + if ((topic = d_groupGetTopic(group)) == NULL) { /* uses os_strdup, must be freed later */ + goto err_allocTopic; + } + if ((partition = d_groupGetPartition(group)) == NULL) { /* uses os_strdup. The partition is passed to d_durabilityStateRequestNew and freed when d_durabilityStateRequestFree() is called */ + goto err_allocPartition; + } + if ((partitions = c_iterNew(partition)) == NULL) { /* Set the partition */ + goto err_allocPartitions; + } + if ((serverIds = c_iterNew(NULL)) == NULL) { /* Broadcast to everybody */ + goto err_allocServerIds; + } + timeout = C_TIME_ZERO; /* Send the message without delay */ + extensions = c_iterNew(NULL); /* No extensions */ + if (extensions == NULL) { + goto err_allocExtensions; + } + request = d_durabilityStateRequestNew( + admin, + version, + requestId, + topic, + partitions, + serverIds, + timeout, + extensions); + if (request == NULL) { + goto err_allocRequest; + } + subscriber = d_adminGetSubscriber(admin); + assert(d_subscriberIsValid(subscriber)); + dsrlistener = subscriber->durabilityStateRequestListener; + if (dsrlistener != NULL) { + d_printTimedEvent(durability, D_LEVEL_FINER, + "Update for group '%s.%s' detected (completeness: %d), adding self-inflicted durabilityStateRequest (%lld,%lld:%lu) to queue\n", + partition, + topic, + group->completeness, + request->requestId.clientId.prefix, + request->requestId.clientId.suffix, + request->requestId.requestId); + /* Add the request to the listener */ + d_durabilityStateRequestListenerAddRequest(dsrlistener, request); + } + hdrlistener = subscriber->historicalDataRequestListener; + if (hdrlistener != NULL) { + /* Notify listeners of group state update event */ + if (group->completeness == D_GROUP_COMPLETE) { + d_adminNotifyListeners(admin, D_GROUP_LOCAL_COMPLETE, NULL, NULL, group, hdrlistener); + } + } + /* Free the stuff */ + /* No need to free partition, because this is freed when request is freed */ + os_free(topic); + c_iterFree(partitions); + c_iterFree(serverIds); + c_iterFree(extensions); + } + return; + +err_allocRequest: + c_iterFree(extensions); +err_allocExtensions: + c_iterFree(serverIds); +err_allocServerIds: + c_iterFree(partitions); +err_allocPartitions: + os_free(partition); +err_allocPartition: + os_free(topic); +err_allocTopic: + return; +} + diff --git a/src/services/durability/code/d_groupCreationQueue.c b/src/services/durability/code/d_groupCreationQueue.c new file mode 100644 index 000000000..e5e295770 --- /dev/null +++ b/src/services/durability/code/d_groupCreationQueue.c @@ -0,0 +1,466 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#include "d__groupCreationQueue.h" +#include "d__lock.h" +#include "d__admin.h" +#include "d__configuration.h" +#include "d__misc.h" +#include "d__conflictResolver.h" +#include "d__group.h" +#include "d__thread.h" +#include "d__group.h" +#include "d__durability.h" +#include "u_group.h" +#include "u_entity.h" +#include "v_builtin.h" +#include "c_iterator.h" +#include "os_heap.h" +#include "os_time.h" +#include "os_thread.h" + +static void +d_waitForCompletenessDCPSTopic( + d_groupCreationQueue queue) +{ + d_thread self = d_threadLookupSelf (); + d_group dcpstopicGroup; + d_completeness completeness; + d_admin admin; + os_duration sleepTime = OS_DURATION_INIT(1, 0); + d_durability durability; + + admin = queue->admin; + durability = d_adminGetDurability(admin); + + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Waiting for group '%s.%s' to be created.\n",V_BUILTIN_PARTITION, V_TOPICINFO_NAME); + + do { + dcpstopicGroup = d_adminGetLocalGroup(admin, + V_BUILTIN_PARTITION, V_TOPICINFO_NAME, + D_DURABILITY_TRANSIENT); + if((dcpstopicGroup == NULL) && (queue->terminate == FALSE)){ + d_sleep(self, sleepTime); + } + } while((dcpstopicGroup == NULL) && (queue->terminate == FALSE)); + + if(queue->terminate == FALSE){ + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Group '%s.%s' is available. Waiting for completeness...\n", V_BUILTIN_PARTITION, V_TOPICINFO_NAME); + } + + do{ + if(dcpstopicGroup){ + completeness = d_groupGetCompleteness(dcpstopicGroup); + + if((completeness != D_GROUP_COMPLETE) && (queue->terminate == FALSE)){ + d_sleep(self, sleepTime); + } + } else { + completeness = D_GROUP_KNOWLEDGE_UNDEFINED; + } + } while((completeness != D_GROUP_COMPLETE) && (queue->terminate == FALSE)); + + if (queue->terminate == FALSE) { + d_printTimedEvent(durability, D_LEVEL_FINER, + "Group '%s.%s' is complete now.\n", V_BUILTIN_PARTITION, V_TOPICINFO_NAME); + } else { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Not waiting for group '%s.%s', because termination is in progress.\n", + V_BUILTIN_PARTITION, V_TOPICINFO_NAME); + } + return; +} + +static void* +d_groupCreationQueueRun( + void* userData) +{ + d_thread self = d_threadLookupSelf (); + d_groupCreationQueue queue; + c_iter groupsToCreate, reinsert; + d_group group, localGroup; + d_durability durability; + d_durabilityKind kind; + u_participant uservice; + c_char *partition, *topic; + u_group ugroup; + c_ulong creationCountVolatile, creationCountTransient, creationCountPersistent; + c_ulong maxBurst; + os_duration sleepTime = OS_DURATION_INIT(1,0); + os_duration maxBurstSleepTime = OS_DURATION_INIT(0, 10000000); /* 10 ms */ + c_bool update; + c_ulong nrOfPendingConflicts; + + creationCountVolatile = 0; + creationCountTransient = 0; + creationCountPersistent = 0; + + queue = d_groupCreationQueue(userData); + groupsToCreate = c_iterNew(NULL); + reinsert = c_iterNew(NULL); + durability = d_adminGetDurability(queue->admin); + uservice = u_participant(d_durabilityGetService(durability)); + + d_waitForCompletenessDCPSTopic(queue); + + while(queue->terminate == FALSE) { + d_lockLock(d_lock(queue)); + + assert(queue->groupsToCreateVolatile >= creationCountVolatile); + queue->groupsToCreateVolatile -= creationCountVolatile; + assert(queue->groupsToCreateTransient >= creationCountTransient); + queue->groupsToCreateTransient -= creationCountTransient; + assert(queue->groupsToCreatePersistent >= creationCountPersistent); + queue->groupsToCreatePersistent -= creationCountPersistent; + + group = d_group(c_iterTakeFirst(queue->groups)); + + while(group){ + groupsToCreate = c_iterInsert(groupsToCreate, group); + group = d_group(c_iterTakeFirst(queue->groups)); + } + assert((queue->groupsToCreateVolatile + + queue->groupsToCreateTransient + + queue->groupsToCreatePersistent) == + c_iterLength(groupsToCreate)); + + durability = d_adminGetDurability(queue->admin); + d_durabilityUpdateStatistics(durability, d_statisticsUpdateGroupsToCreate, queue); + + d_lockUnlock(d_lock(queue)); + + creationCountVolatile = 0; + creationCountTransient = 0; + creationCountPersistent = 0; + maxBurst = 10; + + group = c_iterTakeFirst(groupsToCreate); + + while(group && (queue->terminate == FALSE)){ + partition = d_groupGetPartition(group); + topic = d_groupGetTopic(group); + kind = d_groupGetKind(group); + localGroup = d_adminGetLocalGroup(queue->admin, partition, topic, kind); + update = FALSE; + + if(localGroup) { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Remote group %s.%s has already been created locally.\n", + partition, topic); + update = TRUE; + } else { + ugroup = u_groupNew(uservice, partition, topic, 0); + + if(ugroup){ + d_printTimedEvent(durability, D_LEVEL_FINER, + "Remote group %s.%s created locally.\n", + partition, topic); + update = TRUE; + /* FIXME: enable again after fix is in place + u_objectFree(u_object(ugroup)); */ + maxBurst--; + + if(maxBurst == 0){ + d_sleep(self, maxBurstSleepTime); + maxBurst = 10; + } + } else { + maxBurst++; + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Remote group %s.%s could not be created locally.\n", + partition, topic); + if(d_durabilityGetState(durability) == D_STATE_COMPLETE){ + /* SUB-OPTIMAL: + * If group creation failed then retry if there + * still exist pending conflicts. When there are + * are no conflicts then retry 300 times (=5 min.). + * If there are no conflicts and 300 times. + * When still not created, then give up. + * + * This solution is sub-optimal because there is + * still the (theoretical?) risk that the topic + * definition is not discovered after 300 retries. + * A better solution would be to DISCOVER the + * topic definition by waiting for the DCPSTopic + * of fellows that have its definition. */ + os_mutexLock(&queue->admin->conflictQueueMutex); + nrOfPendingConflicts = c_iterLength(queue->admin->conflictQueue); + os_mutexUnlock(&queue->admin->conflictQueueMutex); + if (nrOfPendingConflicts > 0) { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "There are still pending conflicts. Retry to create group %s.%s when no pending conflicts exist.\n", + partition, topic); + group->creationRetryCount = 0; + reinsert = c_iterInsert(reinsert, group); + } else if (group->creationRetryCount < 299) { + if (group->creationRetryCount % 10 == 0) { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "No pending conflicts, but the type definition for group %s.%s may not have been discovered yet, retry (%u).\n", + partition, topic, group->creationRetryCount); + } + group->creationRetryCount++; + reinsert = c_iterInsert(reinsert, group); + } else { + d_printTimedEvent(durability, D_LEVEL_WARNING, + "No pending conflicts, but I failed to create local group %s.%s after %u retries, I give up.\n", + partition, topic, group->creationRetryCount); + update = TRUE; + } + } else if(d_adminGetFellowCount(queue->admin) == 0){ + d_printTimedEvent(durability, D_LEVEL_WARNING, + "No fellows available to provide me with group information. " \ + "Ignoring group %s.%s.\n", + partition, topic); + update = TRUE; + } else { + reinsert = c_iterInsert(reinsert, group); + } + } + } + if(update){ + switch(d_groupGetKind(group)){ + case D_DURABILITY_VOLATILE: + creationCountVolatile++; + break; + case D_DURABILITY_TRANSIENT: + case D_DURABILITY_TRANSIENT_LOCAL: + creationCountTransient++; + break; + case D_DURABILITY_PERSISTENT: + creationCountPersistent++; + break; + default: + assert(FALSE); + break; + } + d_groupFree(group); + } + os_free(partition); + os_free(topic); + group = c_iterTakeFirst(groupsToCreate); + } + group = d_group(c_iterTakeFirst(reinsert)); + + while(group){ + groupsToCreate = c_iterInsert(groupsToCreate, group); + group = d_group(c_iterTakeFirst(reinsert)); + } + if(queue->terminate == FALSE){ + d_sleep(self, sleepTime); + } + } + + group = d_group(c_iterTakeFirst(groupsToCreate)); + + while(group) { + d_groupFree(group); + group = d_group(c_iterTakeFirst(groupsToCreate)); + } + c_iterFree(groupsToCreate); + c_iterFree(reinsert); + + d_lockLock(d_lock(queue)); + group = d_group(c_iterTakeFirst(queue->groups)); + + while(group) { + d_groupFree(group); + group = d_group(c_iterTakeFirst(queue->groups)); + } + d_lockUnlock(d_lock(queue)); + + return NULL; +} + +static c_equality +compareGroups( + d_group group, + d_group compareGroup) +{ + c_equality result; + c_char *partition, *partition2, *topic, *topic2; + c_long comp; + + assert(group); + assert(compareGroup); + + if(group == compareGroup){ + result = C_EQ; + } else { + partition = d_groupGetPartition(group); + partition2 = d_groupGetPartition(compareGroup); + comp = strcmp(partition, partition2); + + if(comp == 0){ + topic = d_groupGetTopic(group); + topic2 = d_groupGetTopic(compareGroup); + comp = strcmp(topic, topic2); + + if(comp == 0){ + result = C_EQ; + } else if(comp > 0){ + result = C_GT; + } else { + result = C_LT; + } + os_free(topic); + os_free(topic2); + } else if(comp > 0){ + result = C_GT; + } else { + result = C_LT; + } + os_free(partition); + os_free(partition2); + } + return result; +} + +d_groupCreationQueue +d_groupCreationQueueNew( + d_admin admin) +{ + d_groupCreationQueue queue; + os_result osr; + os_threadAttr attr; + + assert(d_adminIsValid(admin)); + + /* Allocate groupCreationQueue object */ + queue = d_groupCreationQueue(os_malloc(C_SIZEOF(d_groupCreationQueue))); + if (queue) { + /* Call super-init */ + d_lockInit(d_lock(queue), D_GROUP_CREATION_QUEUE, + (d_objectDeinitFunc)d_groupCreationQueueDeinit); + /* Initialize groupCreationQueue */ + if (queue) { + queue->groups = c_iterNew(NULL); + queue->terminate = FALSE; + queue->admin = admin; + queue->groupsToCreateVolatile = 0; + queue->groupsToCreateTransient = 0; + queue->groupsToCreatePersistent = 0; + + os_threadAttrInit(&attr); + osr = d_threadCreate(&queue->actionThread, "groupCreationThread", + &attr, (void*(*)(void*))d_groupCreationQueueRun, + (void*)queue); + if (osr != os_resultSuccess) { + d_groupCreationQueueFree(queue); + queue = NULL; + } + } + } + return queue; +} + + +void +d_groupCreationQueueDeinit( + d_groupCreationQueue queue) +{ + assert(d_groupCreationQueueIsValid(queue)); + + if (os_threadIdToInteger(queue->actionThread)) { + queue->terminate = TRUE; + d_threadWaitExit(queue->actionThread, NULL); + } + if (queue->groups){ + c_iterFree(queue->groups); + } + /* Call super-deinit */ + d_lockDeinit(d_lock(queue)); +} + + +void +d_groupCreationQueueFree( + d_groupCreationQueue queue) +{ + assert(d_groupCreationQueueIsValid(queue)); + + d_objectFree(d_object(queue)); +} + + +c_bool +d_groupCreationQueueAdd( + d_groupCreationQueue queue, + d_group group) +{ + c_bool result; + d_group found; + d_durability durability; + assert(d_objectIsValid(d_object(queue), D_GROUP_CREATION_QUEUE) == TRUE); + + result = FALSE; + + if(queue) { + d_lockLock(d_lock(queue)); + + found = c_iterResolve(queue->groups, (c_iterResolveCompare)compareGroups, group); + + if(found == NULL){ + queue->groups = c_iterInsert(queue->groups, group); + + switch(d_groupGetKind(group)){ + case D_DURABILITY_VOLATILE: + queue->groupsToCreateVolatile++; + break; + case D_DURABILITY_TRANSIENT: + case D_DURABILITY_TRANSIENT_LOCAL: + queue->groupsToCreateTransient++; + break; + case D_DURABILITY_PERSISTENT: + queue->groupsToCreatePersistent++; + break; + default: + assert(FALSE); + break; + } + durability = d_adminGetDurability(queue->admin); + d_durabilityUpdateStatistics(durability, d_statisticsUpdateGroupsToCreate, queue); + result = TRUE; + } + d_lockUnlock(d_lock(queue)); + + } + return result; +} + +c_bool +d_groupCreationQueueIsEmpty( + d_groupCreationQueue queue) +{ + c_bool result; + + assert(d_objectIsValid(d_object(queue), D_GROUP_CREATION_QUEUE) == TRUE); + + d_lockLock(d_lock(queue)); + + if((queue->groupsToCreateVolatile == 0) && + (queue->groupsToCreateTransient == 0) && + (queue->groupsToCreatePersistent == 0)){ + result = TRUE; + } else { + result = FALSE; + } + d_lockUnlock(d_lock(queue)); + + return result; +} diff --git a/src/services/durability/code/d_groupHash.c b/src/services/durability/code/d_groupHash.c new file mode 100644 index 000000000..9e3da0ad6 --- /dev/null +++ b/src/services/durability/code/d_groupHash.c @@ -0,0 +1,210 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#include "d__groupHash.h" + +#include "kernelModule.h" +#include "v_group.h" +#include "v_state.h" +#include "ut_md5.h" +#include "d__misc.h" +#include "d__configuration.h" + + +static const char* +v_groupFlushTypeImage(v_groupFlushType type) +{ +#define _CASE(x) case x: return #x + switch(type) { + _CASE(V_GROUP_FLUSH_REGISTRATION); + _CASE(V_GROUP_FLUSH_UNREGISTRATION); + _CASE(V_GROUP_FLUSH_MESSAGE); + _CASE(V_GROUP_FLUSH_TRANSACTION); + } +#undef _CASE + return "(unknown)"; +} + + +void +d_groupHashCalculate( + struct d_groupHash *groupHash, + const c_iter list) +{ + struct v_groupFlushData *flushData; + v_message message; + c_iterIter local; + ut_md5_state_t md5st; + c_octet key[25]; + c_octet state; + unsigned dataBE[6]; + int i; + int item = 0; + + assert(groupHash); + + memset(&groupHash->hash, 0, 16); + groupHash->flags = 1; + groupHash->nrSamples = c_iterLength(list); + if (groupHash->nrSamples > 0) { + local = c_iterIterGet(list); + flushData = c_iterNext(&local); + + ut_md5_init(&md5st); + + while (flushData) { + assert(flushData->object); + switch (flushData->flushType) { + case V_GROUP_FLUSH_REGISTRATION: + case V_GROUP_FLUSH_UNREGISTRATION: + groupHash->nrSamples--; + break; + case V_GROUP_FLUSH_MESSAGE: + case V_GROUP_FLUSH_TRANSACTION: + message = (v_message)flushData->object; + + dataBE[0] = d_swap4uToBE(message->writerGID.systemId); + dataBE[1] = d_swap4uToBE(message->writerGID.localId); + dataBE[2] = d_swap4uToBE(message->writerGID.serial); + dataBE[3] = d_swap4uToBE((unsigned)OS_TIMEW_GET_SECONDS(message->writeTime)); + dataBE[4] = d_swap4uToBE((unsigned)OS_TIMEW_GET_NANOSECONDS(message->writeTime)); + dataBE[5] = d_swap4uToBE(message->sequenceNumber); + for (i = 0; i < 6; i++) { + memcpy(&key[i*4], &dataBE[i], 4); + } + if (flushData->instance) { + state = v_stateTest(flushData->instance->state, L_NOWRITERS) ? 1 : 0; + } else { + /* Instance for message unknown, this occurs when the message is read from + * a store and therefore should be handled as if the instance is in the + * L_NOWRITERS state */ + state = 1; + } + key[24] = state; + ut_md5_append(&md5st, (const unsigned char *) &key, sizeof(key)); + + d_trace(D_TRACE_GROUP_HASH, "%s: [%d] %s {%d.%d.%d}, %"PA_PRItime", %u, %u\n", OS_FUNCTION, item++, + v_groupFlushTypeImage(flushData->flushType), + message->writerGID.systemId,message->writerGID.localId,message->writerGID.serial, + OS_TIMEW_PRINT(message->writeTime), + message->sequenceNumber, state); + break; + } + flushData = c_iterNext(&local); + } + ut_md5_finish(&md5st, groupHash->hash); + if (groupHash->nrSamples == 0) { + groupHash->flags = 0; + memset(&groupHash->hash, 0, 16); + } + } +} + +c_char * +d_groupHashToString( + struct d_groupHash *groupHash) +{ + c_char *hashString; + int i; + + if (groupHash->nrSamples > 0) { + hashString = os_malloc(50); /* flags(1) + stringified(nrSamples(8) + hash(16))(48) + \0 */ + assert(groupHash->flags); + hashString[0] = (char)groupHash->flags; + sprintf(&hashString[1], "%08x", groupHash->nrSamples); + for (i=0;i<16;i++) { + sprintf(&hashString[9+(i*2)], "%02x", groupHash->hash[i]); + } + } else { + hashString = os_malloc(1); + hashString[0] = '\0'; + } + d_trace(D_TRACE_GROUP_HASH, "%s: %s\n", OS_FUNCTION, hashString); + + return hashString; +} + +/** + * \brief This operation translates a hashString to a d_groupHash + * + * \param[out] groupHash : The groupHash to store the translated hashString in. + * \param[in] hashString : The hashString to be translated. + * + * \return : TRUE when a non-empty valid hashString was supplied and + * transformed. + */ +c_bool +d_groupHashFromString( + struct d_groupHash *groupHash, + c_char *hashString) +{ + c_bool result = FALSE; + c_char buf[9]; + c_char *hex; + int i; + + assert(groupHash); + assert(hashString); + + d_trace(D_TRACE_GROUP_HASH, "%s: %s\n", OS_FUNCTION, hashString); + + groupHash->flags = (c_octet)hashString[0]; + if (groupHash->flags == 1) { + memset(&buf, 0, 9); + for (hex = &hashString[9], i=0; i<16; i++) { + memcpy(&buf, &hex[i*2], 2); + groupHash->hash[i] = (c_octet)strtol(buf, NULL, 16); + } + memcpy(&buf, &hashString[1], 8); + groupHash->nrSamples = (c_ulong)strtol(buf, NULL, 16); + result = TRUE; + } else { + groupHash->nrSamples = 0; + memset(groupHash->hash, 0, 16); + } + + return result; +} + +c_bool +d_groupHashIsEqual( + struct d_groupHash *groupHash1, + struct d_groupHash *groupHash2) +{ + c_bool equality = TRUE; + int i; + + assert(groupHash1); + assert(groupHash2); + + if (groupHash1 == groupHash2) { + equality = TRUE; + } else if ((groupHash1->nrSamples != groupHash2->nrSamples) || + (groupHash1->flags != groupHash2->flags)) { + equality = FALSE; + } else { + for (i=0; i<16; i++) { + if (groupHash1->hash[i] != groupHash2->hash[i]) { + equality = FALSE; + break; + } + } + } + + return equality; +} + diff --git a/src/services/durability/code/d_groupLocalListener.c b/src/services/durability/code/d_groupLocalListener.c new file mode 100644 index 000000000..887cbcf70 --- /dev/null +++ b/src/services/durability/code/d_groupLocalListener.c @@ -0,0 +1,3482 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#include "vortex_os.h" +#include "d_nameSpacesRequest.h" +#include "d__configuration.h" +#include "d__admin.h" +#include "d__durability.h" +#include "d__groupLocalListener.h" +#include "d__sampleChainListener.h" +#include "d__nameSpacesRequestListener.h" +#include "d__group.h" +#include "d__thread.h" +#include "d__nameSpace.h" +#include "d__admin.h" +#include "d__fellow.h" +#include "d__misc.h" +#include "d__table.h" +#include "d__listener.h" +#include "d__nameSpace.h" +#include "d__actionQueue.h" +#include "d__publisher.h" +#include "d__subscriber.h" +#include "d__waitset.h" +#include "d__readerRequest.h" +#include "d__group.h" +#include "d__eventListener.h" +#include "d_newGroup.h" +#include "d_deleteData.h" +#include "d_message.h" +#include "d_sampleRequest.h" +#include "d_groupsRequest.h" +#include "d_deleteData.h" +#include "d_networkAddress.h" +#include "d_store.h" +#include "u_observable.h" +#include "u_group.h" +#include "v_event.h" +#include "v_observer.h" +#include "v_waitset.h" +#include "v_service.h" +#include "v_participant.h" +#include "v_entity.h" +#include "v_topic.h" +#include "v_partition.h" +#include "v_group.h" +#include "v_time.h" +#include "c_time.h" +#include "c_iterator.h" +#include "os_heap.h" +#include "os_report.h" +#include "d_durability.h" +#include "d__mergeAction.h" +#include "d__mergeState.h" +#include "d__conflictResolver.h" + +/** + * Macro that checks the d_groupLocalListener validity. + * Because d_groupLocalListener is a concrete class typechecking is required. + */ +#define d_groupLocalListenerIsValid(_this) \ + d_listenerIsValidKind(d_listener(_this), D_GROUP_LOCAL_LISTENER) + +/** + * \brief The d_groupLocalListener cast macro. + * + * This macro casts an object to a d_groupLocalListener object. + */ +#define d_groupLocalListener(_this) ((d_groupLocalListener)(_this)) + +#define D_FLOOR_SEQUENCE_NUMBER (-1) + +C_CLASS(d_groupIncomplete); + +C_STRUCT(d_groupIncomplete){ + d_group dgroup; + v_group vgroup; +}; + +/** + * \brief The d_groupIncomplete cast macro. + * + * This macro casts an object to a d_groupIncomplete object. + */ +#define d_groupIncomplete(g) ((d_groupIncomplete)(g)) + +C_STRUCT(d_groupLocalListener){ + C_EXTENDS(d_listener); + c_bool initialGroupsAdministrated; + c_long lastSequenceNumber; + os_mutex masterLock; + d_eventListener fellowListener; + d_eventListener nameSpaceListener; + d_sampleChainListener sampleChainListener; + d_waitsetEntity waitsetData; + d_actionQueue actionQueue; + d_actionQueue masterMonitor; + c_long snapshotRequestNumber; +}; + +struct findAligner{ + d_fellow fellow; + d_group group; +}; + +struct createPersistentSnapshotHelper { + c_char* partExpr; + c_char* topicExpr; + c_char* uri; + d_listener listener; +}; + +struct fellowState { + d_networkAddress address; + d_serviceState state; + d_table nameSpaces; /* Namespace states */ +}; + +/* TODO: d_groupLocalListenerHandleAlignment: take appropriate action on + * lazy alignment where injection of data fails. + */ + + +struct checkNameSpacesHelper { + d_nameSpacesRequest request; + d_publisher publisher; + c_iter retryFellows; + os_timeE retryTime; + os_duration retryDelay; +}; + +static c_bool +checkNameSpaces( + d_fellow fellow, + c_voidp args) +{ + struct checkNameSpacesHelper *helper; + d_communicationState state; + d_networkAddress fellowAddress; + + helper = (struct checkNameSpacesHelper*)args; + state = d_fellowGetCommunicationState (fellow); + + /* If an incomplete fellow is found, send a namespaces request to that fellow, and reset the retryTime. + * The fellow is added to the retryFellows list and removed from the administration (by the caller function), + * when retryTime eventually exceeds and the fellow is still in the list. + */ + if (state == D_COMMUNICATION_STATE_APPROVED) { + d_fellow retryFellow; + retryFellow = c_iterTake(helper->retryFellows, fellow); + if(retryFellow) { + d_objectFree(d_object(retryFellow)); + } + } else { + if (!c_iterContains(helper->retryFellows, fellow)) { + d_durability durability = d_threadsDurability(); + + fellowAddress = d_fellowGetAddress(fellow); + d_messageSetAddressee(d_message(helper->request), fellowAddress); + d_publisherNameSpacesRequestWrite(helper->publisher, helper->request, fellowAddress, d_durabilityGetState(durability)); + /* Increase retrytime, in case this is a new fellow give it a fair chance to respond */ + helper->retryTime = os_timeEAdd(os_timeEGet(), helper->retryDelay); + d_objectKeep((d_object)fellow); + helper->retryFellows = c_iterAppend(helper->retryFellows, fellow); + d_networkAddressFree(fellowAddress); + } + } + + return TRUE; +} + +struct masterHelper { + d_groupLocalListener listener; + c_iter nameSpaces; +}; + +static c_bool +determineNewMastersAction( + d_action action, + c_bool terminate) +{ + struct masterHelper* helper; + + helper = (struct masterHelper*)(d_actionGetArgs(action)); + + if(terminate == FALSE){ + d_groupLocalListenerDetermineNewMasters (helper->listener, helper->nameSpaces); + } + + c_iterFree(helper->nameSpaces); + os_free(helper); + + return FALSE; +} + +static c_bool +notifyFellowEvent( + c_ulong event, + d_fellow fellow, + d_nameSpace ns, + d_group group, + c_voidp eventUserData, + c_voidp userData) +{ + d_groupLocalListener listener; + d_admin admin; + d_durability durability; + c_ulong length, i; + d_nameSpace nameSpace; + d_action masterAction; + os_duration sleepTime = OS_DURATION_INIT(0, 100000000); /* 100 ms */ + d_networkAddress masterAddress, fellowAddress; + d_serviceState fellowState; + c_iter nameSpaces, nsCollect; + struct masterHelper *helper; + + OS_UNUSED_ARG(ns); + OS_UNUSED_ARG(group); + OS_UNUSED_ARG(eventUserData); + + listener = d_groupLocalListener(userData); + admin = d_listenerGetAdmin(d_listener(listener)); + durability = d_adminGetDurability(admin); + fellowAddress = d_fellowGetAddress(fellow); + + if (event == D_FELLOW_NEW) { + fellowState = d_fellowGetState(fellow); + + d_printTimedEvent(durability, D_LEVEL_INFO, + "New fellow '%u' with state %s\n", + fellowAddress->systemId, + d_fellowStateText(fellowState)); + + d_printTimedEvent(durability, D_LEVEL_FINER, + "Potentially I need merging with fellow '%u' with state %s\n", + fellowAddress->systemId, + d_fellowStateText(fellowState)); + + /* The fellow might have published data that I missed. + * To retrieve the data the I am going to schedule a conflict + */ + d_conflictMonitorCheckFellowConnected(admin->conflictMonitor, fellow); + + } else if(event == D_FELLOW_REMOVED){ + nameSpaces = c_iterNew(NULL); + + d_printTimedEvent(durability, D_LEVEL_INFO, + "Fellow '%d' removed, checking whether new master must be determined.\n", + fellowAddress->systemId); + + nsCollect = d_adminNameSpaceCollect(admin); + length = c_iterLength(nsCollect); + + for(i=0; (isystemId, d_nameSpaceIsMasterConfirmed(nameSpace)); + } + d_networkAddressFree(masterAddress); + } + length = c_iterLength(nameSpaces); + + /* TODO: Remove merge action from sampleChainListener if it exists */ + if(length > 0){ + helper = (struct masterHelper*)(os_malloc(sizeof(struct masterHelper))); + helper->listener = listener; + helper->nameSpaces = nameSpaces; + masterAction = d_actionNew(os_timeMGet(), sleepTime, determineNewMastersAction, helper); + d_actionQueueAdd(listener->masterMonitor, masterAction); + } else { + c_iterFree(nameSpaces); + } + + /* Free namespace list */ + d_adminNameSpaceCollectFree(admin, nsCollect); + } + + d_networkAddressFree(fellowAddress); + + return TRUE; + +} + +struct nsGroupAlignWalkData +{ + d_durability durability; + d_nameSpace nameSpace; + d_groupLocalListener listener; + c_iter groups; +}; + +/* Start alignment for existing groups in specific namespace */ +static c_bool +nsCollectGroupWalk( + d_group group, + c_voidp userData) +{ + c_bool inNameSpace; + d_partition partition; + d_topic topic; + struct nsGroupAlignWalkData* walkData = (struct nsGroupAlignWalkData*)userData; + + assert(walkData); + + partition = d_groupGetPartition(group); + topic = d_groupGetTopic(group); + + if(walkData->nameSpace){ + inNameSpace = d_nameSpaceIsIn(walkData->nameSpace, partition, topic); + + if(inNameSpace){ + d_printTimedEvent(walkData->durability, D_LEVEL_FINEST, + "-Group %s.%s.\n", partition, topic); + c_iterAppend (walkData->groups, group); + } + } else { + d_printTimedEvent(walkData->durability, D_LEVEL_FINEST, + "- Group %s.%s.\n", partition, topic); + c_iterAppend (walkData->groups, group); + } + os_free(partition); + os_free(topic); + + return TRUE; +} + +static void +handleGroupAlignmentWalk ( + void* o, + c_voidp userData) +{ + struct nsGroupAlignWalkData* walkData = (struct nsGroupAlignWalkData*)userData; + + d_group group = d_group(o); + d_groupLocalListener listener; + d_admin admin; + d_nameSpace nameSpace; + d_partition partition; + d_topic topic; + + admin = d_listenerGetAdmin(d_listener(walkData->listener)); + partition = d_groupGetPartition(group); + topic = d_groupGetTopic(group); + listener = walkData->listener; + + /* Compare namespace in walkdata with namespace from group */ + nameSpace = d_adminGetNameSpaceForGroup(admin, partition, topic); + if (!d_nameSpaceCompare (walkData->nameSpace, nameSpace)) + { + /* Start alignment of group when namespaces are equal */ + d_groupLocalListenerHandleAlignment( + listener, + group, + NULL); + } + + os_free (partition); + os_free (topic); +} + + +typedef struct applyDelayedAlignment_t { + d_groupLocalListener listener; + d_nameSpace nameSpace; + d_fellow fellow; +}applyDelayedAlignment_t; + +static void +setGroupIncomplete ( + void* o, + c_voidp userData) +{ + d_group group = d_group(o); + d_admin admin= d_admin(userData); + d_groupSetIncomplete(group, admin); +} + +static c_bool +applyDelayedAlignment ( + d_action action, + c_bool terminate) +{ + c_iter nameSpaces; + d_admin admin; + d_durability durability; + d_groupLocalListener listener; + d_nameSpace ns; + applyDelayedAlignment_t* actionData; + d_networkAddress master; + d_fellow masterFellow; + d_quality q; + c_bool callAgain = TRUE; + struct nsGroupAlignWalkData walkData; + + actionData = (applyDelayedAlignment_t*)d_actionGetArgs(action); + listener = actionData->listener; + durability = d_adminGetDurability(d_listenerGetAdmin(d_listener(listener))); + admin = d_listenerGetAdmin(d_listener(listener)); + ns = d_nameSpace(d_objectKeep(d_object(actionData->nameSpace))); + + if (terminate == FALSE) { + /* Only do action when fellow has reached discover_persistent_source state, so master-selection is synced. */ + if(d_fellowGetState(actionData->fellow) >= D_STATE_DISCOVER_PERSISTENT_SOURCE) { + + /* Re-determine master for namespace */ + nameSpaces = c_iterNew(ns); + d_groupLocalListenerDetermineNewMasters (listener, nameSpaces); + c_iterFree(nameSpaces); + + /* If I am not the new master, and the namespace quality of the new master is not infinite, I will + * request alignment for the namespace. + */ + + /* Get master */ + master = d_nameSpaceGetMaster(ns); + + /* Get fellow namespace */ + masterFellow = d_adminGetFellow(admin, master); + + if (masterFellow) { + /* Re-align groups */ + if(d_durabilityMustTerminate(durability) == FALSE){ + walkData.durability = durability; + walkData.listener = listener; + walkData.nameSpace = ns; + walkData.groups = c_iterNew(NULL); + admin = d_listenerGetAdmin(d_listener(listener)); + + d_printTimedEvent(durability, D_LEVEL_FINER, + "Collecting groups for namespace %s to apply delayed alignment.\n", + d_nameSpaceGetName(ns)); + /* Collect groups */ + d_adminGroupWalk (admin, nsCollectGroupWalk, &walkData); + + /* Set completeness of group back to incomplete again */ + c_iterWalk(walkData.groups, setGroupIncomplete, admin); + + /* Align groups */ + c_iterWalk (walkData.groups, handleGroupAlignmentWalk, &walkData); + + /* Namespace has no longer zero-quality, set it to infinite so it can't be written to anymore. */ + q = D_QUALITY_INFINITE; + d_nameSpaceSetInitialQuality(ns, q); + } + d_fellowFree(masterFellow); + } else { + d_printTimedEvent(durability, D_LEVEL_INFO, + "Fellow '%d' lost before starting delayed alignment, or I have become master.\n", + master->systemId); + } + d_networkAddressFree(master); + d_fellowFree(actionData->fellow); + os_free(actionData); + callAgain = FALSE; + } else { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Redo applyDelayedAlignment (namespace %s) - fellow not yet in DISCOVER_PERSISTENT_SOURCE state.\n", + d_nameSpaceGetName(ns)); + } + } else { + d_fellowFree(actionData->fellow); + os_free(actionData); + callAgain = FALSE; + } + d_nameSpaceFree(ns); + + return callAgain; +} + +/* Mark namespace with state of fellow */ +static c_bool +notifyNameSpaceEvent( + c_ulong event, + d_fellow fellow, + d_nameSpace ns, + d_group group, + c_voidp eventUserData, + c_voidp userData) +{ + d_durability durability; + d_admin admin; + d_groupLocalListener listener; + d_action action; + + OS_UNUSED_ARG(group); + OS_UNUSED_ARG(eventUserData); + + listener = d_groupLocalListener(userData); + assert(listener); + admin = d_listenerGetAdmin(d_listener(listener)); + durability = d_adminGetDurability(admin); + /* New namespace detected */ + if (event == D_NAMESPACE_NEW) { + /* A new namespace has been learned. To ensure that data is acquired for this namespace we + * generate a master conflict. When this master conflict is resolved alignment will occur + * automatically. */ + d_conflict conflict; + d_nameSpace nameSpaceCopy; + nameSpaceCopy = d_nameSpaceCopy(ns); + + conflict = d_conflictNew(D_CONFLICT_NAMESPACE_MASTER, NULL, nameSpaceCopy, NULL); + if (!d_conflictResolverConflictExists(admin->conflictResolver, conflict)) { + d_conflictSetId(conflict, durability); + + d_printTimedEvent(durability, D_LEVEL_FINE, + "New nameSpace '%s' detected, master conflict %d created\n", + ns->name, conflict->id); + d_conflictResolverAddConflict(admin->conflictResolver, conflict); + } else { + d_conflictFree(conflict); + } + d_nameSpaceFree(nameSpaceCopy); + + /* Late-joining node with initial data joined */ + } else if (event & D_NAMESPACE_DELAYED_INITIAL) { + applyDelayedAlignment_t* actionData; + d_fellow adminFellow; + d_networkAddress fellowAddr; + os_duration sleepTime = OS_DURATION_INIT(1, 0); + + listener = d_groupLocalListener(userData); + admin = d_listenerGetAdmin(d_listener(listener)); + + fellowAddr = d_fellowGetAddress(fellow); + adminFellow = d_adminGetFellow(admin, fellowAddr); + d_networkAddressFree(fellowAddr); + + actionData = os_malloc(sizeof(applyDelayedAlignment_t)); + actionData->listener = listener; + actionData->nameSpace = ns; + actionData->fellow = adminFellow; + + /* Post delayed alignment action */ + action = d_actionNew(os_timeMGet(), sleepTime, applyDelayedAlignment, actionData); + d_actionQueueAdd(listener->actionQueue, action); + } + return TRUE; +} + +static void +d_groupLocalListenerDeinit( + d_groupLocalListener listener) +{ + assert(d_groupLocalListenerIsValid(listener)); + + /* Stop the groupLocalListener */ + d_groupLocalListenerStop(listener); + /* Deallocate */ + if (listener->nameSpaceListener) { + d_eventListenerFree(listener->nameSpaceListener); + } + if (listener->fellowListener) { + d_eventListenerFree(listener->fellowListener); + } + if (listener->actionQueue) { + d_actionQueueFree(listener->actionQueue); + } + if (listener->masterMonitor) { + d_actionQueueFree(listener->masterMonitor); + } + (void)os_mutexDestroy(&(listener->masterLock)); + /* Call super-deinit */ + d_listenerDeinit(d_listener(listener)); +} + +static void +d_groupLocalListenerInit( + d_groupLocalListener listener) +{ + os_duration sleepTime; + os_threadAttr ta; + d_durability durability; + + /* Initialize groupLocalListener */ + sleepTime = OS_DURATION_INIT(0, 100000000); /* 100 ms */ + listener->lastSequenceNumber = D_FLOOR_SEQUENCE_NUMBER; + listener->initialGroupsAdministrated = FALSE; + os_threadAttrInit(&ta); + listener->masterMonitor = d_actionQueueNew( + "masterMonitor", + sleepTime, ta); + + durability = d_adminGetDurability(d_listenerGetAdmin(d_listener(listener))); + /* The groupLocalListerActionQueue thread has access to the persistent store + * and should therefore set the persistentStoreStackSize + */ + ta.stackSize = durability->configuration->persistentStoreStackSize; + listener->actionQueue = d_actionQueueNew( + "groupLocalListenerActionQueue", + sleepTime, ta); + os_mutexInit(&(listener->masterLock), NULL); + listener->fellowListener = d_eventListenerNew( + D_FELLOW_NEW | D_FELLOW_REMOVED, + notifyFellowEvent, + listener); + listener->nameSpaceListener = d_eventListenerNew( + D_NAMESPACE_NEW | D_NAMESPACE_DELAYED_INITIAL, + notifyNameSpaceEvent, + listener); + listener->snapshotRequestNumber = 0; +} + +d_groupLocalListener +d_groupLocalListenerNew( + d_subscriber subscriber) +{ + d_groupLocalListener listener = NULL; + + assert(d_subscriberIsValid(subscriber)); + + if (subscriber->sampleChainListener) { + assert(d_sampleChainListenerIsValid(subscriber->sampleChainListener)); + /* Allocate grouplocalListener object */ + listener = d_groupLocalListener(os_malloc(C_SIZEOF(d_groupLocalListener))); + if (listener) { + /* Call super-init */ + d_listenerInit(d_listener(listener), D_GROUP_LOCAL_LISTENER, subscriber, NULL, + (d_objectDeinitFunc)d_groupLocalListenerDeinit); + /* Initialize the d_groupLocalListener */ + listener->sampleChainListener = subscriber->sampleChainListener; + d_groupLocalListenerInit(listener); + } + } + return listener; +} + +void +d_groupLocalListenerFree( + d_groupLocalListener listener) +{ + assert(d_groupLocalListenerIsValid(listener)); + + d_objectFree(d_object(listener)); +} + +/*************** START NEW IMPL *************************/ + +/** + * \brief Check if all groups of the fellow have been received + * + * If no groupsRequest message has been sent to the fellow yet + * then TRUE is returned. + * + * @return TRUE, if all groups have been received, FALSE otherwise + */ +static c_bool +checkFellowGroupsKnown( + d_fellow fellow, + c_voidp args) +{ + c_long expected; + c_ulong actual; + c_bool* known; + c_bool requested; + + known = (c_bool*)args; + requested = d_fellowGetGroupsRequested(fellow); + if (requested) { + expected = d_fellowGetExpectedGroupCount(fellow); + if (expected != -1) { + actual = d_fellowGetGroupCount(fellow); + if (actual >= ((c_ulong)expected)) { + *known = TRUE; + } else { + *known = FALSE; + } + } else if ( (d_fellowGetCommunicationState(fellow) == D_COMMUNICATION_STATE_INCOMPATIBLE_STATE) || + (d_fellowGetCommunicationState(fellow) == D_COMMUNICATION_STATE_INCOMPATIBLE_DATA_MODEL)) { + *known = TRUE; + } else { + *known = FALSE; + } + } else { + *known = TRUE; + } + return *known; + +} + + +struct groupInfo { + c_iter nameSpaces; + c_bool iAmAMaster; + d_groupsRequest request; + d_publisher publisher; + d_durability durability; + c_bool requested; /* Indicates if a groupsRequest has been sent */ +}; + + +static c_bool +requestGroups( + d_fellow fellow, + c_voidp args) +{ + c_bool toRequest = TRUE; + d_networkAddress fellowAddr, master; + struct groupInfo *info; + c_ulong i; + d_nameSpace ns; + c_bool notInitial; + d_admin admin; + d_subscriber subscriber; + d_sampleChainListener sampleChainListener; + c_bool allFellowGroupsKnown = FALSE; + + /* Only attempt to request groups if never requested before or the groups have not yet been received */ + info = (struct groupInfo*)args; + info->requested = FALSE; + /* groupsRequests only moves from FALSE to TRUE so the race condition on groupsRequested can + * only lead to requesting the groups more often than strictly necessary + * As long as not all fellows groups are known keep requesting all groups are requested. + * This is a precondition for handleMergeAlignment to wait for. + * Eventually groupsRequested and allFellowGroupsKnown will become TRUE, at which point + * no further requests will be issued + */ + checkFellowGroupsKnown(fellow, &allFellowGroupsKnown); + if ((!fellow->groupsRequested) || (!allFellowGroupsKnown)) { + fellowAddr = d_fellowGetAddress(fellow); + if (!info->iAmAMaster) { + /* I am not the master. If the fellow is master for one of my + * nameSpaces then request groups from this fellow in case + * alignment is initial + */ + admin = info->durability->admin; + subscriber = d_adminGetSubscriber(admin); + sampleChainListener = d_subscriberGetSampleChainListener(subscriber); + toRequest = FALSE; + for(i=0; inameSpaces) && (!toRequest); i++) { + d_networkAddress unAddressed = d_networkAddressUnaddressed(); + + ns = d_nameSpace(c_iterObject(info->nameSpaces, i)); + master = d_nameSpaceGetMaster(ns); + + /* Request groups from the fellow if the fellow is the master */ + + if (d_networkAddressEquals(master, fellowAddr)) { + notInitial = d_nameSpaceIsAlignmentNotInitial(ns); + if (notInitial) { + d_printTimedEvent(info->durability, D_LEVEL_FINER, + "I am very lazy and will not request groups from master %u\n", + fellowAddr->systemId); + /* Request groups that are still being aligned */ + d_sampleChainListenerCheckUnfulfilled(sampleChainListener, ns, master); + toRequest = FALSE; + } else { + toRequest = TRUE; + } + + /* Request groups from the fellow if my master is 'nobody' and + * I cannot act as aligner myself. + */ + } else if (d_networkAddressEquals(master, unAddressed) && !d_nameSpaceIsAligner(ns)) { + d_printTimedEvent(info->durability, D_LEVEL_FINER, + "I have no master and cannot act as aligner, but fellow %u may be a potential master\n", + fellowAddr->systemId); + toRequest = TRUE; + } + + d_networkAddressFree(master); + d_networkAddressFree(unAddressed); + } /* for */ + if (!toRequest) { + d_printTimedEvent(info->durability, D_LEVEL_FINER, + "No need to request groups from fellow %u\n", + fellowAddr->systemId); + } + } else { + /* Groups are only requested if not requested already */ + toRequest = !(fellow->groupsRequested); + } + if (toRequest) { + /* Actually do the request. */ + d_printTimedEvent(info->durability, D_LEVEL_FINE, + "Requesting all groups from fellow %u\n", + fellowAddr->systemId); + fellow->groupsRequested = TRUE; + info->requested = TRUE; + d_messageSetAddressee(d_message(info->request), fellowAddr); + d_publisherGroupsRequestWrite(info->publisher, info->request, fellowAddr); + } + d_networkAddressFree(fellowAddr); + } + return TRUE; +} + + +static void +doGroupsRequest( + d_groupLocalListener listener, + c_iter nameSpaces, + c_bool iAmAMaster) +{ + d_admin admin; + struct groupInfo info; + + if(listener){ + admin = d_listenerGetAdmin(d_listener(listener)); + + info.nameSpaces = nameSpaces; + info.durability = d_adminGetDurability(admin); + info.iAmAMaster = iAmAMaster; + info.publisher = d_adminGetPublisher(admin); + info.request = d_groupsRequestNew(admin, NULL, NULL); + /* Request groups from all known fellows */ + d_adminFellowWalk(admin, requestGroups, &info); + d_groupsRequestFree(info.request); + } + return; +} + + +struct addressList { + d_networkAddress address; + c_ulong count; + c_voidp next; +}; + +struct masterInfo { + d_nameSpace nameSpace; + d_networkAddress master; + c_bool masterConfirmed; + d_quality masterQuality; + c_bool conflicts; /* Indicator if all fellows agree with the proposal */ + d_serviceState masterState; + d_durability durability; + c_bool conflictsAllowed; + struct addressList* list; + c_bool fellowExists; /* Indicator to determine if the fellow exists */ + c_bool initial; /* boolean to decide to use the fixed fellow table admin->initial_fellows or the dynamically changing table admin->fellows */ +}; + +static void +addMajorityMaster( + struct masterInfo* info, + d_networkAddress address) +{ + struct addressList *list, *prevList = NULL; + c_bool found; + + assert(info); + + found = FALSE; + + if(info->list){ + list = info->list; + + while(list && !found){ + prevList = list; + if(d_networkAddressEquals(address, list->address)){ + found = TRUE; + list->count++; + } + list = list->next; + } + if(!found){ + prevList->next = (struct addressList*)(os_malloc(sizeof(struct addressList))); + list = prevList->next; + } + } else { + info->list = (struct addressList*)(os_malloc(sizeof(struct addressList))); + list = info->list; + } + + if(!found){ + list->address = d_networkAddressNew(address->systemId, address->localId, address->lifecycleId); + list->count = 1; + list->next = NULL; + } + return; +} + +static void +removeMajorityMaster( + struct masterInfo* info, + d_networkAddress address) +{ + struct addressList *list, *prev; + c_bool found; + + assert(info); + + prev = NULL; + list = info->list; + found = FALSE; + + while(list && !found){ + if(d_networkAddressEquals(list->address, address)){ + if(prev){ + prev->next = list->next; + } else { + info->list = list->next; + } + d_networkAddressFree(list->address); + os_free(list); + found = TRUE; + } + + if (!found) { + prev = list; + list = list->next; + } + } + return; +} + +static d_networkAddress +getMajorityMaster( + struct masterInfo* info) +{ + d_networkAddress master; + c_ulong count; + c_bool replace; + struct addressList* list; + + assert(info); + + if(info->list){ + master = d_networkAddressNew(info->list->address->systemId, + info->list->address->localId, info->list->address->lifecycleId); + count = info->list->count; + + list = (struct addressList*)(info->list->next); + + while(list){ + replace = FALSE; + + if(list->count > count){ + replace = TRUE; + } else if (list->count == count){ + if(d_networkAddressCompare(list->address, master) > 0){ + replace = TRUE; + } + } + + if(replace){ + d_networkAddressFree(master); + master = d_networkAddressNew(list->address->systemId, + list->address->localId, list->address->lifecycleId); + count = list->count; + } + list = (struct addressList*)list->next; + } + } else { + master = d_networkAddressUnaddressed(); + } + return master; +} + +static void +freeMajorityMasters( + struct masterInfo* info) +{ + struct addressList *list, *prevList; + + assert(info); + + list = info->list; + + while(list){ + d_networkAddressFree(list->address); + prevList = list; + list = list->next; + os_free(prevList); + } + return; +} + +static c_bool +determineExistingMaster( + d_fellow fellow, + c_voidp userData) +{ + struct masterInfo* m; + d_nameSpace fellowNameSpace; + d_networkAddress fellowMaster, fellowAddress; + char *role, *fellowRole; + + m = (struct masterInfo*)userData; + fellowNameSpace = d_fellowGetNameSpace(fellow, m->nameSpace); + role = d_nameSpaceGetRole(m->nameSpace); + + /* Check if fellow has compatible nameSpace. If not go to the next one */ + if (fellowNameSpace) { + fellowMaster = d_nameSpaceGetMaster(fellowNameSpace); + fellowRole = d_nameSpaceGetRole(fellowNameSpace); + + if (strcmp(fellowRole, role) == 0) { + /* If I haven't found a potential master so far, check whether the + * fellow determined a (potential) master already. If so, conform + * to the selected master. + */ + if(d_networkAddressIsUnaddressed(m->master)){ + if(!d_networkAddressIsUnaddressed(fellowMaster)){ + d_networkAddressFree(m->master); + m->master = d_networkAddressNew( + fellowMaster->systemId, + fellowMaster->localId, + fellowMaster->lifecycleId); + addMajorityMaster(m, fellowMaster); + } + } else if(!d_networkAddressIsUnaddressed(fellowMaster)){ + /* If the fellow has determined a (potential) master + * that doesn't match my current one, there's a conflict and + * I need to drop out of this function. + */ + d_printTimedEvent(m->durability, D_LEVEL_FINEST, + "m->master %u:%s fellowMaster %u:%s\n", + m->master->systemId, m->masterConfirmed?"TRUE":"FALSE", + fellowMaster->systemId, d_nameSpaceIsMasterConfirmed(fellowNameSpace)?"TRUE":"FALSE"); + + if(!d_networkAddressEquals(m->master, fellowMaster)){ + c_bool fellowMasterConfirmed = d_nameSpaceIsMasterConfirmed(fellowNameSpace); + + if ((fellowMasterConfirmed) && + (!m->masterConfirmed)) { + + fellowAddress = d_fellowGetAddress(fellow); + d_printTimedEvent(m->durability, D_LEVEL_FINEST, + "Fellow '%u' reports confirmed master '%u' for nameSpace '%s'. " \ + "while I found unconfirmed master '%u'.\n", + fellowAddress->systemId, + fellowMaster->systemId, + d_nameSpaceGetName(m->nameSpace), + m->master->systemId); + d_networkAddressFree(fellowAddress); + + d_networkAddressFree(m->master); + m->master = d_networkAddressNew( + fellowMaster->systemId, + fellowMaster->localId, + fellowMaster->lifecycleId); + m->masterConfirmed = TRUE; + m->conflicts = FALSE; + } else if ((fellowMasterConfirmed) && + (m->masterConfirmed)) { + m->conflicts = TRUE; + + fellowAddress = d_fellowGetAddress(fellow); + d_printTimedEvent(m->durability, D_LEVEL_FINEST, + "Fellow '%u' reports master '%u' for nameSpace '%s'. " \ + "while I found master '%u'.\n", + fellowAddress->systemId, + fellowMaster->systemId, + d_nameSpaceGetName(m->nameSpace), + m->master->systemId); + d_networkAddressFree(fellowAddress); + } else if ((!fellowMasterConfirmed) && + (!m->masterConfirmed)) { + fellowAddress = d_fellowGetAddress(fellow); + d_printTimedEvent(m->durability, D_LEVEL_FINEST, + "Fellow '%u' reports unconfirmed master '%u' for nameSpace '%s'. " \ + "while I found unconfirmed master '%u', dropping mine\n", + fellowAddress->systemId, + fellowMaster->systemId, + d_nameSpaceGetName(m->nameSpace), + m->master->systemId); + d_networkAddressFree(fellowAddress); + + d_networkAddressFree(m->master); + m->master = d_networkAddressUnaddressed(); + } else { + /* No need to do anything, I already am my own confirmed master */ + } + } + addMajorityMaster(m, fellowMaster); + } + } + + d_networkAddressFree(fellowMaster); + os_free (fellowRole); + /* If fellow namespace is from other role, it can't be master for this node */ + } + + os_free (role); + + return TRUE; +} + + +static c_bool +determineNewMasterLegacy( + d_fellow fellow, + c_voidp userData) +{ + struct masterInfo* m; + d_nameSpace fellowNameSpace; + d_networkAddress fellowAddress; + c_bool isAligner, replace; + d_quality quality; + d_serviceState fellowState; + char *role, *fellowRole; + c_bool contEval = FALSE; + + m = (struct masterInfo*)userData; + replace = FALSE; + fellowNameSpace = d_fellowGetNameSpace(fellow, m->nameSpace); + + if(fellowNameSpace){ + + role = d_nameSpaceGetRole (m->nameSpace); + fellowRole = d_nameSpaceGetRole (fellowNameSpace); + + if (strcmp (role, fellowRole) == 0) { + isAligner = d_nameSpaceIsAligner(fellowNameSpace); + quality = d_nameSpaceGetInitialQuality(fellowNameSpace); + fellowState = d_fellowGetState(fellow); + + if(isAligner){ + if(d_networkAddressIsUnaddressed(m->master)){ + replace = TRUE; + + /* This behavior is undesired when delayedAlignment is active */ + } else if(!d_nameSpaceGetDelayedAlignment(m->nameSpace)) { + if ((m->masterState <= D_STATE_DISCOVER_PERSISTENT_SOURCE) && + (fellowState > D_STATE_DISCOVER_PERSISTENT_SOURCE)) + { + replace = TRUE; + } else if ((m->masterState > D_STATE_DISCOVER_PERSISTENT_SOURCE) && + (fellowState <= D_STATE_DISCOVER_PERSISTENT_SOURCE)) + { + replace = FALSE; + } else { + contEval = TRUE; + } + } else { + contEval = TRUE; + } + + if (contEval) { + os_compare eq; + eq = d_qualityCompare(quality, m->masterQuality); + if (eq == OS_MORE) { + replace = TRUE; + } else if (eq == OS_EQUAL) { + fellowAddress = d_fellowGetAddress(fellow); + if(d_networkAddressCompare(fellowAddress, m->master) > 0){ + replace = TRUE; + } + d_networkAddressFree(fellowAddress); + } + } + } + } + os_free (role); + os_free (fellowRole); + } + + if(replace){ + if(m->master){ + d_networkAddressFree(m->master); + } + m->master = d_fellowGetAddress(fellow); + m->masterQuality = quality; + m->masterState = fellowState; + } + return TRUE; +} + +static int +determineNewMasterPriorityCompare( + struct masterInfo *m, + d_fellow fellow, + d_nameSpace fellowNameSpace) +{ + d_quality quality = d_nameSpaceGetInitialQuality(fellowNameSpace); + os_compare qcmp; + + + /* Replace if priority of proposed master is worse than that of fellow */ + if (d_nameSpaceGetMasterPriority(m->nameSpace) < d_nameSpaceGetMasterPriority(fellowNameSpace)) { + return -1; + } else if (d_nameSpaceGetMasterPriority(m->nameSpace) > d_nameSpaceGetMasterPriority(fellowNameSpace)) { + return 1; + + /* Replace if quality of proposed master is worse than that of fellow */ + } else if ((qcmp = d_qualityCompare(m->masterQuality, quality)) == OS_LESS) { + return -1; + } else if (qcmp == OS_MORE) { + return 1; + + /* Replace if systemId of proposed master is lower than that of fellow */ + } else { + d_networkAddress fellowAddress = d_fellowGetAddress(fellow); + int cmp = d_networkAddressCompare(m->master, fellowAddress); + d_networkAddressFree(fellowAddress); + return cmp; + } +} + +static int +determineNewMasterPriorityIsFellowCandidate( + struct masterInfo* m, + d_nameSpace fellowNameSpace) +{ + char *role = d_nameSpaceGetRole (m->nameSpace); + char *fellowRole = d_nameSpaceGetRole (fellowNameSpace); + int samerole = (strcmp (role, fellowRole) == 0); + os_free (role); + os_free (fellowRole); + /* A fellow is a candidate master for me if it has the same role as me, is aligner and has a priority > 0 */ + return samerole && d_nameSpaceIsAligner(fellowNameSpace) && (d_nameSpaceGetMasterPriority(fellowNameSpace) > 0); +} + +static void +determineNewMasterPriorityNoreturn( + d_fellow fellow, + struct masterInfo* m) +{ + d_nameSpace fellowNameSpace; + c_bool replace; + d_quality quality; + + assert(m); + + /* Skip if no fellow nameSpace found */ + if ((fellowNameSpace = d_fellowGetNameSpace(fellow, m->nameSpace)) == NULL) { + d_trace(D_TRACE_MASTER_SELECTION, "%s - REJECT fellow %u as candidate master for nameSpace %s. Reason: nameSpace unknown\n", + OS_FUNCTION, fellow->address->systemId, m->nameSpace->name); + return; + } + + /* Skip if fellow is not a replacement candidate */ + if (!determineNewMasterPriorityIsFellowCandidate(m, fellowNameSpace)) { + d_trace(D_TRACE_MASTER_SELECTION, "%s - REJECT fellow %u as candidate master for nameSpace %s. Reason: Not a suitable candidate\n", + OS_FUNCTION, fellow->address->systemId, m->nameSpace->name); + return; + } + + quality = d_nameSpaceGetInitialQuality(fellowNameSpace); + + d_trace(D_TRACE_MASTER_SELECTION, "%s - Checking fellow '%u' (priority: %u, quality: %"PA_PRItime")\n", + OS_FUNCTION, fellow->address->systemId, d_nameSpaceGetMasterPriority(fellowNameSpace), OS_TIMEW_PRINT(quality)); + + if (d_networkAddressIsUnaddressed(m->master)) { + d_trace(D_TRACE_MASTER_SELECTION, "%s - ACCEPT fellow %u as candidate master for nameSpace %s. Reason: current master is unAddressed\n", + OS_FUNCTION, fellow->address->systemId, m->nameSpace->name); + replace = TRUE; + /* This behavior is undesired when delayedAlignment is active */ + } else if(d_nameSpaceGetDelayedAlignment(m->nameSpace)) { + d_trace(D_TRACE_MASTER_SELECTION, "%s - REJECT fellow %u as candidate master for nameSpace %s. Reason: delayedAlignment configured\n", + OS_FUNCTION, fellow->address->systemId, m->nameSpace->name); + replace = FALSE; + } else if (determineNewMasterPriorityCompare(m, fellow, fellowNameSpace) < 0) { + d_trace(D_TRACE_MASTER_SELECTION, "%s - ACCEPT fellow %u as candidate master for nameSpace %s. Reason: fellow is better candidate than current master\n", + OS_FUNCTION, fellow->address->systemId, m->nameSpace->name); + replace = TRUE; + } else { + d_trace(D_TRACE_MASTER_SELECTION, "%s - REJECT fellow %u as candidate master for nameSpace %s. Reason: fellow is worse candidate than current master\n", + OS_FUNCTION, fellow->address->systemId, m->nameSpace->name); + replace = FALSE; + } + + if (replace) { + + if(m->master){ + d_networkAddressFree(m->master); + } + m->master = d_fellowGetAddress(fellow); + m->masterQuality = quality; + m->masterState = d_fellowGetState(fellow); + d_trace(D_TRACE_MASTER_SELECTION, "%s - Current master candidate for nameSpace %s: %u\n", + OS_FUNCTION, m->nameSpace->name, fellow->address->systemId); + m->conflicts = TRUE; + + } +} + +static c_bool +determineNewMasterPriority( + d_fellow fellow, + c_voidp userData) +{ + determineNewMasterPriorityNoreturn(fellow, userData); + return TRUE; +} + +static c_bool +determineNewMaster( + d_fellow fellow, + c_voidp userData) +{ + c_bool result = FALSE; + d_durability durability = d_threadsDurability(); + d_configuration config = d_durabilityGetConfiguration(durability); + struct masterInfo *mastership = (struct masterInfo *)userData; + + /* Determine the master selection algorithm to use from the config. */ + + if (config->masterSelectionLegacy) { + result = determineNewMasterLegacy(fellow, mastership); + } else { + result = determineNewMasterPriority(fellow, mastership); + } + + return result; +} + + +static void +wait_for_responses( + os_duration d) +{ + d_durability durability = d_threadsDurability(); + os_result osr; + d_thread const self = d_threadLookupSelf (); + + /* Do not wait for fellows */ + if (OS_DURATION_ISZERO(d)) { + return; + } + + d_printTimedEvent(durability, D_LEVEL_FINER, "Waiting %f seconds for responses.\n", os_durationToReal(d)); + + os_mutexLock(&(durability->terminateMutex)); + if ((osr = d_condTimedWait(self, &durability->terminateCondition, &durability->terminateMutex, d)) == os_resultFail) { + OS_REPORT(OS_CRITICAL, D_CONTEXT_DURABILITY, 0, "d_condTimedWait failed; terminating"); + /* terminate durability */ + os_mutexUnlock(&(durability->terminateMutex)); + d_durabilityTerminate(durability, TRUE); + os_mutexLock(&(durability->terminateMutex)); + } + os_mutexUnlock(&(durability->terminateMutex)); +} + + +static void +propose_master_for_namespace( + d_admin admin, + d_nameSpace nameSpace, + struct masterInfo *mastership) +{ + char master_string[18]; /* maximum representation 'fellow ' (7) + c_ulong (10) + '\0' (1) */ + d_networkAddress myAddress = d_adminGetMyAddress(admin); + d_networkAddress unAddressed = d_networkAddressUnaddressed(); + d_durability durability = d_threadsDurability(); + + /* Determine the best possible master given the current state of the fellows + * Include myself if I am aligner and my master priority > 0 + */ + mastership->nameSpace = nameSpace; + mastership->conflicts = FALSE; + mastership->masterState = d_durabilityGetState(durability); + mastership->list = NULL; + + if (d_nameSpaceIsAligner(nameSpace) && (d_nameSpaceGetMasterPriority(nameSpace) > 0)) { + mastership->master = d_adminGetMyAddress(admin); + d_trace(D_TRACE_MASTER_SELECTION, "%s - initial master selected for %s: myself (priority: %u, quality: %"PA_PRItime")\n", + OS_FUNCTION, nameSpace->name, d_nameSpaceGetMasterPriority(nameSpace), OS_TIMEW_PRINT(d_nameSpaceGetInitialQuality(nameSpace))); + + } else { + mastership->master = d_networkAddressUnaddressed(); + d_trace(D_TRACE_MASTER_SELECTION, "%s - initial master selected for %s: nobody (priority: %u, quality: %"PA_PRItime")\n", + OS_FUNCTION, nameSpace->name, d_nameSpaceGetMasterPriority(nameSpace), OS_TIMEW_PRINT(d_nameSpaceGetInitialQuality(nameSpace))); + } + + /* Determine the best master among the available fellows */ + if (mastership->initial) { + d_adminInitialFellowWalk(admin, determineNewMaster, mastership); + } else { + d_adminFellowWalk(admin, determineNewMaster, mastership); + } + + /* Create a log entry of the proposal */ + if (d_networkAddressEquals(mastership->master, myAddress)) { + snprintf(master_string, sizeof(master_string), "myself"); + } else if (d_networkAddressEquals(mastership->master, unAddressed)) { + snprintf(master_string, sizeof(master_string), "nobody"); + } else { + snprintf(master_string, sizeof(master_string), "fellow %u", mastership->master->systemId); + } + + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Proposing %s as master for nameSpace '%s' (confirmed: %d, conflicts: %d)\n", + master_string, d_nameSpaceGetName(mastership->nameSpace), d_nameSpaceIsMasterConfirmed(mastership->nameSpace), mastership->conflicts); + + d_networkAddressFree(myAddress); + d_networkAddressFree(unAddressed); +} + + + +c_bool +d_groupLocalListenerDetermineMastersImproved( + d_groupLocalListener listener, + c_iter nameSpaces, + c_bool initial) +{ + /* Select a master for each of the nameSpaces. + * When initial is set the master is determined for fellows in admin->initial_fellows + * (which is set during the resolution of the initial conflict in + * d_conflictResolver.c:resolveInitialConflict(). + * + * Return TRUE if I have become master for one of the nameSpaces + */ + + d_admin admin; + d_durability durability; + d_configuration configuration; + d_nameSpace nameSpace; + d_subscriber subscriber; + d_nameSpacesRequestListener nsrListener; + d_networkAddress unAddressed, myAddress; + c_iterIter iter; + c_bool IAmMaster = FALSE; + struct masterInfo mastership; + + admin = d_listenerGetAdmin(d_listener(listener)); + durability = d_adminGetDurability(admin); + configuration = d_durabilityGetConfiguration(durability); + subscriber = d_adminGetSubscriber(admin); + nsrListener = d_subscriberGetNameSpacesRequestListener(subscriber); + unAddressed = d_networkAddressUnaddressed(); + myAddress = d_adminGetMyAddress(admin); + mastership.initial = initial; + + /* Wait the masterElectionWaitTime (default: zero). */ + wait_for_responses(configuration->masterElectionWaitTime); + + mastership.masterQuality = D_QUALITY_ZERO; + + iter = c_iterIterGet(nameSpaces); + while (((nameSpace = (d_nameSpace)c_iterNext(&iter)) != NULL) && (!d_durabilityMustTerminate(durability))) { + + propose_master_for_namespace(admin, nameSpace, &mastership); + + /* Set and confirm the chosen master */ + d_nameSpaceSetMaster(nameSpace, mastership.master); + d_nameSpaceMasterConfirmed(nameSpace); + + /* Indicate who has become master */ + if (d_networkAddressEquals(nameSpace->master, myAddress)) { + d_printTimedEvent(durability, D_LEVEL_INFO, + "Confirming master: I am the master for nameSpace '%s'.\n", + d_nameSpaceGetName(nameSpace)); + IAmMaster = TRUE; + } else { + d_printTimedEvent(durability, D_LEVEL_INFO, + "Confirming master: Fellow '%u' is the master for nameSpace '%s'.\n", + mastership.master->systemId, d_nameSpaceGetName(nameSpace)); + } + + d_networkAddressFree(mastership.master); + } + + /* Set quality of namespace to quality of master */ + if (d_qualityCompare(mastership.masterQuality, D_QUALITY_ZERO) == OS_MORE) { + iter = c_iterIterGet(nameSpaces); + while (((nameSpace = (d_nameSpace)c_iterNext(&iter)) != NULL)) { + d_nameSpaceSetInitialQuality(nameSpace, mastership.masterQuality); + } + } + + /* Report my namespace choices to others */ + d_nameSpacesRequestListenerReportNameSpaces(nsrListener); + + if (!d_durabilityMustTerminate(durability)) { + /* Request groups */ + doGroupsRequest(listener, nameSpaces, IAmMaster); + } + + d_networkAddressFree(myAddress); + d_networkAddressFree(unAddressed); + + return IAmMaster; +} + + +/* PRECONDTION: listener->masterLock is locked + * + * @return Returns TRUE if I have become a master for one or more nameSpaces. + */ +static c_bool +d_groupLocalListenerDetermineMastersLegacy( + d_groupLocalListener listener, + c_iter nameSpaces, + c_bool initial) +{ + d_thread self = d_threadLookupSelf (); + d_admin admin; + d_durability durability; + d_configuration configuration; + c_ulong length, i; + d_nameSpace nameSpace; + d_subscriber subscriber; + d_publisher publisher; + d_nameSpacesRequestListener nsrListener; + d_networkAddress unaddressed, myAddress, master, lastMaster, dummyAddress; + struct checkNameSpacesHelper checkNsHelper; + struct masterInfo mastership; + os_duration sleepTime = OS_DURATION_INIT(0, 100000000); /* 100 ms */ + os_timeE endTime; + c_bool conflicts, firstTime, cont, proceed; + d_quality myQuality; + c_bool iAmAMaster; + d_serviceState fellowState; + d_fellow fellow, retryFellow, dummy; + c_ulong tries, maxTries; + c_bool initialUnaddressed; + + admin = d_listenerGetAdmin(d_listener(listener)); + durability = d_adminGetDurability(admin); + configuration = d_durabilityGetConfiguration(durability); + length = c_iterLength(nameSpaces); + subscriber = d_adminGetSubscriber(admin); + publisher = d_adminGetPublisher(admin); + nsrListener = d_subscriberGetNameSpacesRequestListener(subscriber); + unaddressed = d_networkAddressUnaddressed(); + myAddress = d_adminGetMyAddress(admin); + firstTime = TRUE; + iAmAMaster = FALSE; + maxTries = configuration->majorityVotingThreshold; + tries = 0; + + /* The legacy algorithm can already handle the situation where + * new nodes appear while masters are being selected. For that reason + * the 'initial' argument is not used. */ + OS_UNUSED_ARG(initial); + + mastership.durability = durability; + mastership.masterQuality = D_QUALITY_ZERO; + + checkNsHelper.request = d_nameSpacesRequestNew(admin); + checkNsHelper.retryFellows = NULL; + checkNsHelper.publisher = publisher; + checkNsHelper.retryDelay = configuration->heartbeatExpiryTime; + + do { + conflicts = FALSE; + tries++; + + /* Check if namespaces still have the same master */ + for(i=0; (i < length) && (d_durabilityMustTerminate(durability) == FALSE); i++){ + nameSpace = d_nameSpace(c_iterObject(nameSpaces, i)); + + /* Remember the last master I selected. If the 'existing' + * one I find now is different, I need to do this whole loop again. + */ + if (firstTime) { + lastMaster = d_nameSpaceGetMaster(nameSpace); + + if (d_networkAddressIsUnaddressed(lastMaster)) { + initialUnaddressed = TRUE; + } else { + d_networkAddressFree(lastMaster); + lastMaster = d_networkAddressUnaddressed(); + initialUnaddressed = FALSE; + } + } else { + lastMaster = d_nameSpaceGetMaster(nameSpace); + if (d_networkAddressIsUnaddressed(lastMaster)) { + initialUnaddressed = TRUE; + } else { + initialUnaddressed = FALSE; + } + } + + mastership.nameSpace = nameSpace; + mastership.master = d_nameSpaceGetMaster(nameSpace); + mastership.masterConfirmed = d_nameSpaceIsMasterConfirmed(nameSpace); + mastership.conflicts = FALSE; + mastership.list = NULL; + + /* Always use un-addressed as my master when looking for an + * existing master. + */ + d_nameSpaceSetMaster(nameSpace, unaddressed); + d_nameSpaceMasterPending (nameSpace); + + if(tries >= maxTries){ + mastership.conflictsAllowed = TRUE; + } else { + mastership.conflictsAllowed = FALSE; + } + + if (initialUnaddressed || !firstTime) { + /* Walk over all fellows that are approved */ + d_adminFellowWalk(admin, determineExistingMaster, &mastership); + } + + if((!mastership.conflicts) && (!d_networkAddressIsUnaddressed(mastership.master))){ + /* Check whether the found fellow is still alive and kicking. */ + + /* Some node(s) could already have chosen me as master */ + if(!d_networkAddressEquals(mastership.master, myAddress)){ + fellow = d_adminGetFellow(admin, mastership.master); + + /*Fellow may be gone already or is currently terminating*/ + if(!fellow){ + d_networkAddressFree(mastership.master); + mastership.master = d_networkAddressUnaddressed(); + } else { + fellowState = d_fellowGetState(fellow); + + if((fellowState == D_STATE_TERMINATING) || (fellowState == D_STATE_TERMINATED)){ + d_networkAddressFree(mastership.master); + mastership.master = d_networkAddressUnaddressed(); + } else if(!d_networkAddressEquals(lastMaster, mastership.master)){ + /* Check whether I determined a master already + * in the previous loop. + */ + if(!d_networkAddressIsUnaddressed(lastMaster)) { + /* Existing master is not the same as the one I found before + * so make sure I'll check once more. + */ + conflicts = TRUE; + d_printTimedEvent(durability, D_LEVEL_FINEST, + "The existing master '%u' I found now for nameSpace '%s'" \ + "doesn't match the one '%u' I found before. " \ + "Waiting for confirmation...\n", + mastership.master->systemId, + d_nameSpaceGetName(nameSpace), + lastMaster->systemId); + } + } + d_fellowFree(fellow); + } + } + } else if(mastership.conflictsAllowed){ + cont = TRUE; + mastership.conflicts = FALSE; + + OS_REPORT(OS_WARNING, OS_FUNCTION, 0, "Determining master based on majority voting, this may cause alignment issues."); + + while(cont){ + if(mastership.master){ + d_networkAddressFree(mastership.master); + } + mastership.master = getMajorityMaster(&mastership); + + if(!d_networkAddressIsUnaddressed(mastership.master)){ + fellow = d_adminGetFellow(admin, mastership.master); + + /*Fellow may be gone already or is currently terminating*/ + if(!fellow){ + if (d_networkAddressEquals(mastership.master, myAddress)) { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Found myself as majority master '%d' for nameSpace '%s'.\n", + mastership.master->systemId, + d_nameSpaceGetName(nameSpace)); + cont = FALSE; + } else { + removeMajorityMaster(&mastership, mastership.master); + } + } else { + fellowState = d_fellowGetState(fellow); + + if((fellowState == D_STATE_TERMINATING) || (fellowState == D_STATE_TERMINATED)){ + removeMajorityMaster(&mastership, mastership.master); + } else { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Found majority master '%d' for nameSpace '%s'.\n", + mastership.master->systemId, + d_nameSpaceGetName(nameSpace)); + cont = FALSE; + } + d_fellowFree(fellow); + } + } else { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Tried to find majority master for nameSpace '%s', but found none.\n", + d_nameSpaceGetName(nameSpace)); + cont = FALSE; + } + } + } + freeMajorityMasters(&mastership); + + if((mastership.conflicts) || d_networkAddressIsUnaddressed(mastership.master)){ + if(mastership.conflicts){ + d_printTimedEvent(durability, D_LEVEL_FINER, + "Found conflicting masters for nameSpace '%s'. " \ + "Determining new master now...\n", + d_nameSpaceGetName(nameSpace)); + conflicts = TRUE; + mastership.conflicts = FALSE; + } else { + d_printTimedEvent(durability, D_LEVEL_FINER, + "Found no existing master for nameSpace '%s'. " \ + "Determining new master now...\n", + d_nameSpaceGetName(nameSpace)); + } + d_networkAddressFree(mastership.master); + + if(d_nameSpaceIsAligner(nameSpace)) { + /* Advertise myself as candidate master */ + myQuality = d_nameSpaceGetInitialQuality(nameSpace); + mastership.master = d_adminGetMyAddress(admin); + mastership.masterQuality = myQuality; + mastership.masterState = d_durabilityGetState(durability); + } else { + /* Do not advertise myself as candidate master */ + mastership.master = d_networkAddressUnaddressed(); + mastership.masterQuality = D_QUALITY_ZERO; + mastership.masterState = D_STATE_INIT; + } + /*7. Walk over all fellows that are approved again.*/ + d_adminFellowWalk(admin, determineNewMaster, &mastership); + + if(d_networkAddressIsUnaddressed(mastership.master)){ + /* Depending on the configuration setting TimeToWaitForAligner + * the service should keep waiting until an aligner becomes + * available. If no aligner is available within the specified time + * the system should move to state INCOMPATIBLE_CONFIGURATION and + * gracefully exit. + * The INCOMPATIBLE_CONFIGURATION is then picked up by the splice + * daemon that can execute the configured FailureAction. + * Note: at the moment only 0 is supported, any other value + * will result in waiting indefinitely for an aligner. + */ + if (os_durationCompare(configuration->timeToWaitForAligner, OS_DURATION_ZERO) != OS_EQUAL) { + /* For the moment it is assumed that in case timeToWaitForAligner != 0 + * then the service will wait indefinitely until an aligner becomes available. + */ + d_printTimedEvent(durability, D_LEVEL_FINER, + "There's no new master available for nameSpace '%s'. " \ + "Awaiting availability of a new master...\n", + d_nameSpaceGetName(nameSpace)); + } else { + d_printTimedEvent(durability, D_LEVEL_FINER, + "There's no new master available for nameSpace '%s'. " \ + "Incompatible configuration.\n", + d_nameSpaceGetName(nameSpace)); + /* Move the state of the durability service to + * STATE_INCOMPATIBLE_CONFIGURATION and terminate + * gracefully. + */ + d_durabilityTerminate(durability, FALSE); + } + } else if(d_networkAddressEquals(mastership.master, myAddress)){ + d_printTimedEvent(durability, D_LEVEL_FINER, + "I want to be the new master for nameSpace '%s'. " \ + "Waiting for confirmation...\n", + d_nameSpaceGetName(nameSpace)); + } else { + d_printTimedEvent(durability, D_LEVEL_FINER, + "I want fellow '%u' to be the new master for nameSpace '%s'. " \ + "Waiting for confirmation...\n", + mastership.master->systemId, + d_nameSpaceGetName(nameSpace)); + } + } else { + d_printTimedEvent(durability, D_LEVEL_FINER, + "Found existing master '%u' for nameSpace '%s'. " \ + "Waiting for confirmation...\n", + mastership.master->systemId, + d_nameSpaceGetName(nameSpace)); + } + d_nameSpaceSetMaster(nameSpace, mastership.master); + d_networkAddressFree(mastership.master); + d_networkAddressFree(lastMaster); + } /* for */ + + d_nameSpacesRequestListenerReportNameSpaces(nsrListener); + + /* Do the same thing again if there were conflicts. + * Since this step must be taken at least once (even if there are + * no conflicts), 'firstTime' is checked also. + */ + if(conflicts || firstTime){ + if(firstTime){ + firstTime = FALSE; + /*To make sure the do-while is done at least once more: */ + conflicts = TRUE; + } + + /* Wait the heartbeat expiry time. */ + endTime = os_timeEGet(); + endTime = os_timeEAdd(endTime, configuration->heartbeatExpiryTime); + + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Waiting the heartbeat expiry period: %f seconds.\n", + os_durationToReal(configuration->heartbeatExpiryTime)); + + while ((d_durabilityMustTerminate(durability) == FALSE) && + (os_timeECompare(os_timeEGet(), endTime) == OS_LESS)) { + d_sleep(self, sleepTime); + } + + proceed = FALSE; + while((d_durabilityMustTerminate(durability) == FALSE) && (proceed == FALSE)) { + d_adminFellowWalk(admin, checkNameSpaces, &checkNsHelper); + if (c_iterLength(checkNsHelper.retryFellows) > 0) { + d_printTimedEvent(durability, D_LEVEL_FINER, + "Found %d incomplete fellow(s)\n", c_iterLength(checkNsHelper.retryFellows)); + proceed = FALSE; + if (os_timeECompare(os_timeEGet(), checkNsHelper.retryTime) == OS_MORE) { + /* There hasn't been a new incomplete fellow for the last 2*heartbeat period, remove any remaining incomplete fellows */ + retryFellow = d_fellow(c_iterTakeFirst(checkNsHelper.retryFellows)); + + while(retryFellow){ + d_fellowSetCommunicationState(retryFellow, D_COMMUNICATION_STATE_TERMINATED); + dummy = d_adminRemoveFellow(admin, retryFellow, FALSE); + if (dummy) { + dummyAddress = d_fellowGetAddress(dummy); + d_printTimedEvent(durability, D_LEVEL_INFO, + "Removed incomplete fellow %u from admin\n", + dummyAddress->systemId); + d_networkAddressFree(dummyAddress); + d_fellowFree(dummy); + } + d_fellowFree(retryFellow); + retryFellow = d_fellow(c_iterTakeFirst(checkNsHelper.retryFellows)); + } + c_iterFree(checkNsHelper.retryFellows); + checkNsHelper.retryFellows = NULL; + proceed = TRUE; + } + } else { + d_printTimedEvent(durability, D_LEVEL_INFO, + "All fellows' namespaces complete\n"); + c_iterFree(checkNsHelper.retryFellows); + checkNsHelper.retryFellows = NULL; + proceed = TRUE; + } + if (proceed == FALSE) { + d_sleep(self, sleepTime); + } + } + if((d_durabilityMustTerminate(durability) == TRUE) && checkNsHelper.retryFellows){ + retryFellow = d_fellow(c_iterTakeFirst(checkNsHelper.retryFellows)); + + while(retryFellow){ + d_fellowFree(retryFellow); + retryFellow = d_fellow(c_iterTakeFirst(checkNsHelper.retryFellows)); + } + c_iterFree(checkNsHelper.retryFellows); + checkNsHelper.retryFellows = NULL; + } + + } else if(d_durabilityMustTerminate(durability) == FALSE){ + assert(conflicts == FALSE); + /*No more conflicts; all masters have been confirmed*/ + for(i=0; isystemId, + d_nameSpaceGetName(nameSpace)); + + /* Get masterfellow */ + fellow = d_adminGetFellow(admin, master); + if(fellow) { + d_nameSpace fellowNamespace; + d_quality q; + + /* Get fellow namespace */ + fellowNamespace = d_fellowGetNameSpace(fellow, nameSpace); + + q = d_nameSpaceGetInitialQuality(fellowNamespace); + + /* Set quality of namespace to quality of master */ + d_nameSpaceSetInitialQuality(nameSpace, q); + + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Quality of namespace '%s' set to %"PA_PRItime".\n", + d_nameSpaceGetName(nameSpace), OS_TIMEW_PRINT(q)); + d_fellowFree(fellow); + } + } + d_networkAddressFree(master); + d_nameSpaceMasterConfirmed(nameSpace); + + } + } + } while ((conflicts == TRUE) && (d_durabilityMustTerminate(durability) == FALSE)); + + d_nameSpacesRequestFree(checkNsHelper.request); + assert(!checkNsHelper.retryFellows); + + d_durabilityUpdateStatistics(durability, d_statisticsUpdateConfiguration, admin); + + /* Re-report namespaces with correct confirmed status */ + d_nameSpacesRequestListenerReportNameSpaces(nsrListener); + + /* Request groups */ + doGroupsRequest(listener, nameSpaces, iAmAMaster); + + d_networkAddressFree(unaddressed); + d_networkAddressFree(myAddress); + + return iAmAMaster; +} + +c_bool +d_groupLocalListenerDetermineMasters( + d_groupLocalListener listener, + c_iter nameSpaces, + c_bool initial) +{ + d_admin admin = d_listenerGetAdmin(d_listener(listener)); + d_durability durability = d_adminGetDurability(admin); + d_configuration config = d_durabilityGetConfiguration(durability); + c_bool result; + + /* Determine whether or not to use the legacy algorithm */ + if (config->masterSelectionLegacy) { + result = d_groupLocalListenerDetermineMastersLegacy(listener, nameSpaces, initial); + } else { + result = d_groupLocalListenerDetermineMastersImproved(listener, nameSpaces, initial); + } + return result; +} + + +/*****************************************************************************/ + +static void +initPersistentData( + d_groupLocalListener listener) +{ + d_thread self = d_threadLookupSelf (); + d_admin admin; + d_subscriber subscriber; + d_store store; + d_durability durability; + d_group group; + u_participant participant; + d_storeResult result; + d_groupList list, next; + c_ulong i, length; + d_nameSpace nameSpace; + d_durabilityKind dkind; + c_iter nameSpaces; + c_bool attached; + v_group vgroup; + c_ulong count; + d_mergeState mergeState; + + admin = d_listenerGetAdmin(d_listener(listener)); + durability = d_adminGetDurability(admin); + subscriber = d_adminGetSubscriber(admin); + store = d_subscriberGetPersistentStore(subscriber); + participant = u_participant(d_durabilityGetService(durability)); + result = d_storeGroupsRead(store, &list); + + /* Collect namespaces from admin */ + nameSpaces = d_adminNameSpaceCollect(admin); + length = c_iterLength(nameSpaces); + + if(result == D_STORE_RESULT_OK){ + + /* Loop namespaces */ + for(i=0; (ipartition, next->topic) == TRUE) { + result = d_storeGroupInject(store, next->partition, next->topic, participant, &group); + + if(result == D_STORE_RESULT_OK) { + d_printTimedEvent(durability, D_LEVEL_FINER, + "Group %s.%s locally created\n", + next->partition, next->topic); + + + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Data from group %s.%s must now be injected\n", + next->partition, next->topic); + + vgroup = d_groupGetKernelGroup(group); + attached = d_durabilityWaitForAttachToGroup(durability, vgroup); + + + count = 0; + + while( (c_count(vgroup->streams) == 0) && + (count < 30)){ + d_sleep(self, OS_DURATION_INIT(0, 100000000)); /* 100 ms */ + count++; + } + c_free(vgroup); + + result = d_storeMessagesInject(store, group); + + if(result == D_STORE_RESULT_OK) { + d_printTimedEvent(durability, D_LEVEL_FINE, + "All data for group %s.%s has been injected from local store.\n", + next->partition, next->topic); + } else { + d_printTimedEvent(durability, D_LEVEL_SEVERE, + "All data for group %s.%s could not be injected.\n", + next->partition, next->topic); + } + if(!attached){ + d_groupSetPrivate(group, TRUE); + d_groupSetKernelGroupCompleteness(group, TRUE); + } + d_groupSetComplete(group, admin); + + d_adminAddLocalGroup(admin, group); + d_sampleChainListenerReportGroup(listener->sampleChainListener, group); + } else { + d_printTimedEvent(durability, D_LEVEL_SEVERE, + "Group %s.%s could NOT be created locally (%d)\n", + next->partition, next->topic, result); + } + } else { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Group %s.%s not in nameSpace.\n", + next->partition, next->topic); + } + } + next = d_groupList(next->next); + } + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Initializing persistent data took %f sec\n", + os_durationToReal(os_timeMDiff(os_timeMGet(), t))); + + /* Update the nameSpace state to trigger alignment */ + mergeState = d_nameSpaceGetMergeState(nameSpace, NULL); + d_mergeStateSetValue(mergeState, mergeState->value+1); + d_nameSpaceSetMergeState(nameSpace, mergeState); + + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Persistent data injected for nameSpace %s, state bumped to %d\n", nameSpace->name, mergeState->value); + + d_mergeStateFree(mergeState); + } + } else { + /* If not master, backup old persistent data (would be overwritten otherwise) */ + result = d_storeBackup(store, nameSpace); + + if(result != D_STORE_RESULT_OK) { + d_printTimedEvent(durability, D_LEVEL_SEVERE, + "Namespace could NOT be backupped in local persistent store (%d)\n", + result); + } + + /* Mark namespace incomplete */ + d_storeNsMarkComplete (store, nameSpace, FALSE); + } + } + } else { + d_printTimedEvent(durability, D_LEVEL_SEVERE, + "Could not read groups from persistent store. Persistent data not injected.\n"); + } + + d_storeGroupListFree(store, list); + + /* Free namespace list */ + d_adminNameSpaceCollectFree(admin, nameSpaces); +} + +/* + * PRECONDTION: listener->masterLock is locked + */ +static void +initMasters( + d_groupLocalListener listener) +{ + d_thread self = d_threadLookupSelf (); + d_admin admin; + d_durability durability; + c_bool fellowGroupsKnown, terminate; + c_iter nameSpaces; + + admin = d_listenerGetAdmin(d_listener(listener)); + durability = d_adminGetDurability(admin); + + /* Collect namespaces from admin */ + nameSpaces = d_adminNameSpaceCollect(admin); + + /* Initialize with namespaces from configuration */ + d_groupLocalListenerDetermineMasters(listener, nameSpaces, TRUE); + + fellowGroupsKnown = FALSE; + terminate = d_durabilityMustTerminate(durability); + + /*now wait for completion of groups*/ + while((fellowGroupsKnown == FALSE) && (!terminate) && (d_adminGetInitialFellowCount(admin) > 0)){ + d_adminInitialFellowWalk(admin, checkFellowGroupsKnown, &fellowGroupsKnown); + d_sleep(self, OS_DURATION_INIT(0, 100000000)); /* 100 ms */ + terminate = d_durabilityMustTerminate(durability); + } + + if(!terminate){ + d_printTimedEvent(durability, D_LEVEL_FINE, "Fellow groups complete.\n"); + } + + /* Free namespace list */ + d_adminNameSpaceCollectFree(admin, nameSpaces); +} + +void +d_groupLocalListenerDetermineNewMasters( + d_groupLocalListener listener, + c_iter nameSpaces) +{ + c_bool tryChains; + os_result osr; + d_durability durability; + d_thread self = d_threadLookupSelf (); + + tryChains = FALSE; + if(d_objectIsValid(d_object(listener), D_LISTENER)){ + durability = d_adminGetDurability(d_listener(listener)->admin); + /* Because master determination can take quite some time + * liveliness of this thread must regularly be asserted + * to prevent that this thread is declared dead. + * To ensure thread liveness we use a tryLock icw + * d_sleep instead of an ordinary lock (the latter + * does not asserts liveliness in case another thread + * holds the lock for a very long time). + */ + do { + osr = os_mutexTryLock(&listener->masterLock); + if (osr == os_resultFail) { + OS_REPORT(OS_ERROR, "d_groupLocalListenerStart", 0, + "Failure to try to acquire the masterlock"); + d_durabilityTerminate(durability, FALSE); + break; + } else if (osr == os_resultBusy) { + d_sleep(self, OS_DURATION_INIT(0,100000000)); /* 100 ms */ + } + } while (osr != os_resultSuccess); + + if (osr == os_resultSuccess) { + if(c_iterLength(nameSpaces) > 0){ + tryChains = d_groupLocalListenerDetermineMasters(listener, nameSpaces, FALSE); + } + os_mutexUnlock(&listener->masterLock); + + if(tryChains){ + d_sampleChainListenerTryFulfillChains(listener->sampleChainListener, NULL); + } + } + } +} + +static c_bool +collectGroupsToAlign( + d_group group, + c_voidp args) +{ + d_durability durability = d_threadsDurability(); + d_configuration config = d_durabilityGetConfiguration(durability); + + if (d_groupIsPrivate(group)) { + return TRUE; + } + if (d_groupIsBuiltinGroup(group) && (!config->mustAlignBuiltinTopics)) { + return TRUE; + } + (void)c_iterInsert((c_iter)args, d_objectKeep(d_object(group))); + return TRUE; +} + + +/** + * \brief Wait until the fellows have sent their groups. + * + * No response is required from a fellow that has prematurely left. + */ +static void +waitForGroups( + c_iter fellowAddresses, + d_durability durability) +{ + c_bool allFellowGroupsKnown; + c_bool fellowGroupsKnown; + c_bool terminate; + d_networkAddress fellowAddr; + d_fellow fellow; + c_ulong i; + d_thread self = d_threadLookupSelf (); + + if (c_iterLength(fellowAddresses) > 0) { + /* There are pending groupsRequests. + * Wait until all groups of the fellows are known. + * We currently use a polling loop for this, but + * maybe a condWait is a better approach. + */ + allFellowGroupsKnown = FALSE; + terminate = d_durabilityMustTerminate(durability); + while ((!allFellowGroupsKnown) && (!terminate)) { + allFellowGroupsKnown = TRUE; + for(i=0; ((i < c_iterLength(fellowAddresses)) && allFellowGroupsKnown); i++) { + fellowAddr = d_networkAddress(c_iterObject(fellowAddresses, i)); + fellow = d_adminGetFellow(durability->admin, fellowAddr); + if (fellow) { + /* The fellow still exists, let's check if its groups are known */ + fellowGroupsKnown = FALSE; + (void)checkFellowGroupsKnown(fellow, &fellowGroupsKnown); + d_fellowFree(fellow); + } else { + /* The fellow is not present anymore, skip */ + fellowGroupsKnown = TRUE; + } + allFellowGroupsKnown = allFellowGroupsKnown && fellowGroupsKnown; + } /* for */ + d_sleep(self,OS_DURATION_INIT(0, 100000000)); /* 100 ms */ + terminate = d_durabilityMustTerminate(durability); + } + /* Clean up the list of pending groupsRequests */ + fellowAddr = d_networkAddress(c_iterTakeFirst(fellowAddresses)); + while (fellowAddr) { + d_networkAddressFree(fellowAddr); + fellowAddr = d_networkAddress(c_iterTakeFirst(fellowAddresses)); + } + } + (void)c_iterFree(fellowAddresses); +} + + +/** + * \brief Request alignment data for the nameSpace from a set of fellows. + * + * When all alignment data is retrieved the new merge state is advertised. + */ +void +handleMergeAlignment( + d_groupLocalListener listener, + d_conflict conflict, + d_nameSpace nameSpace, + c_iter fellows, /* fellows to request samples from */ + d_mergeState newState /* new merge state AFTER alignment has succeeded */) +{ + d_mergeAction mergeAction; + d_admin admin; + d_durability durability; + d_configuration config; + c_iter groups; + d_group group; + d_partition partition; + d_topic topic; + d_durabilityKind dkind; + c_bool inNameSpace, success; + d_chain chain; + os_timeW stamp, networkAttachTime; + d_sampleRequest request; + c_ulong i; + c_ulong fellowCount = c_iterLength(fellows); + c_long chainCount = 0; + d_networkAddress source; + d_fellow fellow; + c_iter pendingGroupsRequest; + struct groupInfo info; + + admin = d_listenerGetAdmin(d_listener(listener)); + durability = d_adminGetDurability(admin); + config = d_durabilityGetConfiguration(durability); + + if (fellowCount == 0) { + /* No fellows to request */ + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Not inserting merge request for nameSpace '%s' because there are no fellows to merge with.\n", + d_nameSpaceGetName(nameSpace)); + return; + } + + groups = c_iterNew(NULL); + source = d_networkAddressUnaddressed(); + + /* We need to request data from the fellows. To ensure + * that a sampleChain is generated for all groups known by + * the fellow we must first be sure that we know all groups + * from the fellow. Therefore, request all groups from the + * fellows for which no previous groupsRequest has been sent. + */ + pendingGroupsRequest = c_iterNew(NULL); + for(i=0; i < fellowCount; i++) { + fellow = d_fellow(c_iterObject(fellows, i)); + assert(d_fellowIsValid(fellow)); + /* Request all groups from the fellow */ + info.nameSpaces = c_iterNew(nameSpace); + info.durability = durability; + info.iAmAMaster = d_nameSpaceMasterIsMe(nameSpace, admin); + info.publisher = d_adminGetPublisher(admin); + info.request = d_groupsRequestNew(admin, NULL, NULL); + (void)requestGroups(fellow, &info); + d_groupsRequestFree(info.request); + c_iterFree(info.nameSpaces); + if (info.requested) { + /* A groupsRequest has actually been sent to this fellow */ + c_iterAppend(pendingGroupsRequest, d_fellowGetAddress(fellow)); + d_printTimedEvent(durability, D_LEVEL_FINER, + "Waiting for groups from fellow %u\n", fellow->address->systemId); + } + } + /* Wait for the pending groups requests */ + waitForGroups(pendingGroupsRequest, durability); + + /* Now we are sure that all groups of the fellows are known. + * Create a merge action. The mergeAction is freed in + * d_sampleChainListenerCheckChainComplete once + * all samples in the chain have been received. + */ + + mergeAction = d_mergeActionNew(conflict, nameSpace, fellows, newState); + /* For each group create a request for data for the + * fellows. Also create a corresponding chain where all + * responses (beads, links) from all fellows to the request + * will be stored. Because responses from multiple fellows + * are stored in a single chain we have to make sure + * that they use the same source. + */ + d_adminGroupWalk(admin, collectGroupsToAlign, groups); + group = d_group(c_iterTakeFirst(groups)); + while (group) { + partition = d_groupGetPartition(group); + topic = d_groupGetTopic(group); + dkind = d_groupGetKind(group); + inNameSpace = d_adminInNameSpace(nameSpace, partition, topic, FALSE); + if (inNameSpace) { + stamp = os_timeWGet(); + if (config->timeAlignment) { + networkAttachTime = stamp; + } else { + networkAttachTime = OS_TIMEW_INFINITE; + } + /* Now create sampleRequests and corresponding chains + * to collect the beads for these sampleRequests. + * We use the address (0,0,0) as the source of the + * sampleRequests. This ensures that responses from + * multiple fellows to the request are collected + * in the same set, and data for the same instance + * is only stored once (on a by-reception-time policy). + */ + request = d_sampleRequestNew( + admin, partition, topic, + dkind, stamp, FALSE, + OS_TIMEW_ZERO, networkAttachTime); + d_sampleRequestSetSource(request,source); + chain = d_chainNew(admin, request); + if (d_mergeActionAddChain(mergeAction, chain)) { + /* Chain is successfully added to the mergeAction */ + chainCount++; + } else { + /* The mergeAction already contains a chain + * for this partition/topic to the fellow, no + * need to added it again. + */ + d_chainFree(chain); + } + } + os_free(partition); + os_free(topic); + d_groupFree(group); + group = d_group(c_iterTakeFirst(groups)); + } /* while */ + + d_traceMergeAction(mergeAction, "Created"); + + /* Now a single mergeAction exists that contains chains + * for all groups that match the namespace. + */ + if (chainCount > 0) { + d_printTimedEvent(durability, D_LEVEL_FINER, + "Inserting merge requests to merge %d groups to %u fellows for nameSpace '%s'\n", + chainCount, fellowCount, d_nameSpaceGetName(nameSpace)); + /* Publish the sampleRequest(s) for this chain */ + success = d_sampleChainListenerInsertMergeAction(listener->sampleChainListener, mergeAction); + if (success == FALSE) { + if (d_tableSize(mergeAction->fellows) == 0) { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "All fellows targeted for the merge request have disappeared, so canceling the merge action.\n"); + } else { + /* A merge action already exists for this */ + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Merge requests to merge %d groups for nameSpace '%s' to %u fellows "\ + "are already in progress, so not issuing a new "\ + "merge action.\n", + chainCount, d_nameSpaceGetName(nameSpace), fellowCount); + } + d_mergeActionFree(mergeAction); + } + } else { + /* The mergeAction does not contain any chain, so no + * data needs to be requested. That means we're done + * with this mergeAction. + */ + d_printTimedEvent(durability, D_LEVEL_FINER, + "No merge requests inserted to %u fellows for nameSpace '%s'\n", + fellowCount, d_nameSpaceGetName(nameSpace)); + d_mergeActionFree(mergeAction); + } + + c_iterFree(groups); + d_networkAddressFree(source); +} + + +struct applyMergePolicyHelper { + d_groupLocalListener listener; + d_fellow fellow; /* When set this fellow is master for the namespace. */ + d_nameSpace nameSpace; /* If set, applyMergePolicy will only check this namespace, otherwise all namespaces are evaluated */ + d_table fellowStates; /* Fellow states at the time of the namespace event */ + c_iter conflictStates; /* Result of mergeState compare between own namespace and fellow namespace */ + c_ulong event; /* the event that triggered the merge action */ + d_mergeState oldMergeState; /* the merge state of the namespace before a new master was determined */ +}; + +/*************** END NEW IMPL *************************/ + +/** + * \brief Handle the appearance of a new local group + */ +void +d_groupLocalListenerHandleNewGroupsLocal( + v_public entity, + c_voidp args) +{ + d_listener listener; + d_groupLocalListener groupListener; + v_service kservice; + c_iter groups; + d_admin admin; + v_group group; + v_group group2; + d_group dgroup; + d_durabilityKind kind; + d_durability durability; + c_bool added, attached, groupAlreadyKnown; + v_topicQos qos; + d_adminStatisticsInfo info; + + listener = d_listener(args); + groupListener = d_groupLocalListener(args); + kservice = v_service(entity); + admin = d_listenerGetAdmin(listener); + durability = d_adminGetDurability(admin); + + groups = v_serviceTakeNewGroups(kservice); + while ((group = v_group(c_iterTakeFirst(groups))) != NULL) { + dgroup = NULL; + qos = v_topicQosRef(group->topic); + kind = d_durabilityKindFromKernel(qos->durability.v.kind); + d_reportLocalGroup(durability, group); + + /* Check durability kind. Only transient, transient local + * and persistent groups require actions + */ + if (kind == D_DURABILITY_VOLATILE){ + d_printTimedEvent(durability, D_LEVEL_FINER, + "Ignoring group %s.%s.\n", + v_partitionName(v_groupPartition(group)), + v_topicName(v_groupTopic(group))); + /* update statistics */ + info = d_adminStatisticsInfoNew(); + info->kind = D_ADMIN_STATISTICS_GROUP; + info->groupsKnownVolatileDif += 1; + info->groupsIgnoredVolatileDif +=1; + d_adminUpdateStatistics(admin, info); + d_adminStatisticsInfoFree(info); + } else { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Wait for services to attach.\n"); + attached = d_durabilityWaitForAttachToGroup(durability, group); + d_printTimedEvent(durability, D_LEVEL_FINER, + "Administrating group %s.%s.\n", + v_partitionName(v_groupPartition(group)), + v_topicName(v_groupTopic(group))); + + /* New groups may be notified multiple times by the kernel. + * Therefore no alignment should be done if group is + * already known in the durability administration. + */ + groupAlreadyKnown = TRUE; + dgroup = d_adminGetLocalGroup( + admin, + v_partitionName(v_groupPartition(group)), + v_topicName(v_groupTopic(group)), + kind); + + if(!dgroup){ + dgroup = d_groupNew(v_partitionName(v_groupPartition(group)), + v_topicName(v_groupTopic(group)), + kind, D_GROUP_INCOMPLETE, D_QUALITY_ZERO); + d_groupSetKernelGroup(dgroup, group); + + if(!attached){ + d_groupSetPrivate(dgroup, TRUE); + d_groupSetKernelGroupCompleteness(dgroup, TRUE); + } + added = d_adminAddLocalGroup(admin, dgroup); + + if(added == FALSE){ + d_groupFree(dgroup); + dgroup = d_adminGetLocalGroup( + admin, + v_partitionName(v_groupPartition(group)), + v_topicName(v_groupTopic(group)), + kind); + if(!attached){ + d_groupSetPrivate(dgroup, TRUE); + d_groupSetKernelGroupCompleteness(dgroup, TRUE); + } + } else { + d_adminStoreGroup(admin, dgroup); + groupAlreadyKnown = FALSE; + } + } else if(!attached){ + d_groupSetPrivate(dgroup, TRUE); + d_groupSetKernelGroupCompleteness(dgroup, TRUE); + } + + if ((d_groupGetCompleteness(dgroup) != D_GROUP_COMPLETE) && (!groupAlreadyKnown)) { + /* Make sure that a group is associated with a d_group */ + group2 = d_groupGetKernelGroup(dgroup); + + if(group2){ + c_free(group2); + } else { + d_groupSetKernelGroup(dgroup, group); + } + + if(d_durabilityMustTerminate(durability) == FALSE){ + d_groupLocalListenerHandleAlignment(groupListener, dgroup, NULL); + } + } else if(groupAlreadyKnown){ + d_printTimedEvent(durability, D_LEVEL_FINER, + "Group %s.%s already known in admin.\n", + v_partitionName(v_groupPartition(group)), + v_topicName(v_groupTopic(group))); + } else { + d_printTimedEvent(durability, D_LEVEL_FINER, + "Group %s.%s already complete.\n", + v_partitionName(v_groupPartition(group)), + v_topicName(v_groupTopic(group))); + } + } + c_free(group); + } + c_iterFree(groups); +} + +static c_bool +d_groupLocalAction( + d_action action, + c_bool terminate) +{ + d_listener listener; + d_durability durability; + d_admin admin; + u_entity service; + + listener = d_listener(d_actionGetArgs(action)); + + if(d_objectIsValid(d_object(listener), D_LISTENER)){ + if(terminate == FALSE){ + admin = d_listenerGetAdmin(listener); + durability = d_adminGetDurability(admin); + service = u_entity(d_durabilityGetService(durability)); + + (void)u_observableAction(u_observable(service), d_groupLocalListenerHandleNewGroupsLocal, listener); + } + } + return FALSE; +} + + +static c_bool +d_groupCreatePersistentSnapshotAction( + d_action action, + c_bool terminate) +{ + d_durability durability; + d_admin admin; + struct createPersistentSnapshotHelper* cps; + u_result result; + + cps = (struct createPersistentSnapshotHelper*)(d_actionGetArgs(action)); + + if(d_objectIsValid(d_object(cps->listener), D_LISTENER)) + { + if(terminate == FALSE) + { + admin = d_listenerGetAdmin(cps->listener); + durability = d_adminGetDurability(admin); + + result = d_durabilityTakePersistentSnapshot( + durability, + cps->partExpr, + cps->topicExpr, + cps->uri); + if (result == U_RESULT_OK) { + OS_REPORT( + OS_INFO, + "d_groupCreatePersistentSnapshotAction", + 0, + "Creation of persistent snapshot number %d successfully completed." + "Snapshot was requested for partition expression '%s'," + " topic expression '%s' and was to be stored at location '%s'.", + d_groupLocalListener(cps->listener)->snapshotRequestNumber++, + cps->partExpr, + cps->topicExpr, + cps->uri); + } else { + OS_REPORT( + OS_ERROR, + "d_groupCreatePersistentSnapshotAction", + 0, + "Creation of persistent snapshot failed with result " + "'%s'. Snapshot was requested for partition expression '%s'," + " topic expression '%s' and was to be stored at location '%s'.", + u_resultImage(result), + cps->partExpr, + cps->topicExpr, + cps->uri); + } + + } + } + os_free(cps->partExpr); + os_free(cps->topicExpr); + os_free(cps->uri); + os_free(cps); + + return FALSE; +} + +struct deleteHistoricalDataHelper { + os_timeW deleteTimeW; + c_char* partExpr; + c_char* topicExpr; + d_listener listener; +}; + +static c_bool +d_groupDeleteHistoricalDataAction( + d_action action, + c_bool terminate) +{ + d_durability durability; + d_admin admin; + d_publisher publisher; + d_networkAddress unaddressed; + d_deleteData delData; + struct deleteHistoricalDataHelper* dhd; + + dhd = (struct deleteHistoricalDataHelper*)(d_actionGetArgs(action)); + + if(d_objectIsValid(d_object(dhd->listener), D_LISTENER)){ + if(terminate == FALSE){ + admin = d_listenerGetAdmin(dhd->listener); + durability = d_adminGetDurability(admin); + publisher = d_adminGetPublisher(admin); + + d_printTimedEvent(durability, D_LEVEL_FINE, + "Notifying fellows to delete historical data for partition/topic expression '%s.%s' up to time %"PA_PRItime"\n", + dhd->partExpr, dhd->topicExpr, OS_TIMEW_PRINT(dhd->deleteTimeW)); + + unaddressed = d_networkAddressUnaddressed(); + + delData = d_deleteDataNew(admin, dhd->deleteTimeW, dhd->partExpr, dhd->topicExpr); + d_publisherDeleteDataWrite(publisher, delData, unaddressed); + d_networkAddressFree(unaddressed); + d_deleteDataFree(delData); + } + } + os_free(dhd->partExpr); + os_free(dhd->topicExpr); + os_free(dhd); + + return FALSE; +} + +struct readerRequestHelper { + d_readerRequest request; + d_admin admin; + d_groupLocalListener listener; +}; + +static c_bool +d_groupLocalReaderRequestAction( + d_action action, + c_bool terminate) +{ + c_bool callAgain, fulfilled; + d_table groups; + d_group group, localGroup; + c_char *partition, *topic; + d_durabilityKind kind; + d_durability durability; + v_handle handle; + struct readerRequestHelper* helper; + + helper = (struct readerRequestHelper*)d_actionGetArgs(action); + + if(!terminate){ + callAgain = FALSE; + groups = d_readerRequestGetGroups(helper->request); + durability = d_adminGetDurability(helper->admin); + handle = d_readerRequestGetHandle(helper->request); + + group = d_tableTake(groups); + + while(group && !callAgain){ + partition = d_groupGetPartition(group); + topic = d_groupGetTopic(group); + kind = d_groupGetKind(group); + localGroup = d_adminGetLocalGroup(helper->admin, partition, topic, kind); + + if(!localGroup){ + callAgain = TRUE; + } else { + d_printTimedEvent(durability, D_LEVEL_FINE, + "Handling alignment of group %s.%s as part of "\ + "historicalDataRequest from reader [%d, %d]\n", + partition, topic, handle.index, handle.serial); + d_groupLocalListenerHandleAlignment(helper->listener, + localGroup, helper->request); + } + os_free(partition); + os_free(topic); + + d_groupFree(group); + + if(!callAgain){ + group = d_tableTake(groups); + } else { + group = NULL; + } + } + d_tableFree(groups); + + if (!callAgain) { + d_printTimedEvent(durability, D_LEVEL_FINER, + "Alignment for historicalDataRequest from "\ + "reader [%d, %d] in progress\n", + handle.index, handle.serial); + fulfilled = d_adminCheckReaderRequestFulfilled( + helper->admin, helper->request); + + if (fulfilled) { + d_printTimedEvent(durability, D_LEVEL_FINER, + "historicalDataRequest from reader [%d, %d] fulfilled.\n", + handle.index, handle.serial); + } + } + } else { + callAgain = FALSE; + } + + + if(!callAgain){ + d_readerRequestFree(helper->request); + os_free(helper); + } + + return callAgain; +} + +/* Lookup namespace */ +typedef struct lookupNameSpace_t { + v_group group; + d_nameSpace namespace; +}lookupNameSpace_t; +static void lookupNamespace(d_nameSpace ns, void* data) { + lookupNameSpace_t* userData; + + userData = (lookupNameSpace_t*)data; + + if(!userData->namespace) { + if(d_nameSpaceIsIn(ns, v_entity(userData->group->partition)->name, v_entity(userData->group->topic)->name)) { + userData->namespace = ns; + } + } +} + +/* Set namespace quality to infinite. This behavior supports delayed alignment functionality. */ +static void markGroupNamespaceWritten(d_admin admin, v_group group) { + lookupNameSpace_t walkData; + d_quality q; + d_durability durability; + + durability = d_adminGetDurability(admin); + + /* Lookup namespace */ + walkData.group = group; + walkData.namespace = 0; + d_adminNameSpaceWalk(admin, lookupNamespace, &walkData); + + /* Check if namespace is found */ + if(!walkData.namespace) { + d_printTimedEvent(durability, D_LEVEL_WARNING, + "Namespace for group '%s.%s' not found in administration (cannot update namespace quality).\n", + v_entity(group->partition)->name, v_entity(group->topic)->name); + return; + } + + /* Set quality to infinite when delayed alignment is enabled. */ + if(d_nameSpaceGetDelayedAlignment(walkData.namespace)) { + q = d_nameSpaceGetInitialQuality(walkData.namespace); + if (!D_QUALITY_ISINFINITE(q)) { + q = D_QUALITY_INFINITE; + /* Set quality to infinite */ + d_nameSpaceSetInitialQuality(walkData.namespace, q); + /* Report that quality of namespace is set to infinite */ + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Quality of namespace '%s' is set to infinite.\n", + d_nameSpaceGetName(walkData.namespace)); + } + } +} + +static void +d_groupLocalListenerHandleReaderRequest( + d_groupLocalListener listener, + v_waitsetEvent event) +{ + d_admin admin; + d_durability durability; + d_readerRequest readerRequest; + os_duration sleepTime = OS_DURATION_INIT(0, 500000000); /* 500 ms */ + struct readerRequestHelper* requestHelper; + d_action action; + c_bool added; + + admin = d_listenerGetAdmin(d_listener(listener)); + durability = d_adminGetDurability(admin); + + readerRequest = d_readerRequestNew(admin, event); + added = d_adminAddReaderRequest(admin, readerRequest); + + if (added) { + d_printTimedEvent(durability, D_LEVEL_FINE, + "Received historicalDataRequest from reader [%d, %d]\n", + event->source.index, event->source.serial); + + requestHelper = (struct readerRequestHelper*) + os_malloc(sizeof(struct readerRequestHelper)); + requestHelper->admin = admin; + requestHelper->listener = d_groupLocalListener(listener); + requestHelper->request = readerRequest; + + action = d_actionNew(os_timeMGet(), + sleepTime, d_groupLocalReaderRequestAction, requestHelper); + d_actionQueueAdd(listener->actionQueue, action); + } + return; +} + +/** + * \brief Schedules local actions such as the appearance of a new local group, + * a request for historical data, a request to delete data, and a + * a request to take a snapshot. + */ +c_ulong +d_groupLocalListenerAction( + u_object o, + v_waitsetEvent event, + c_voidp userData) +{ + d_listener listener; + d_admin admin; + d_durability durability; + d_actionQueue queue; + d_action action; + os_duration sleepTime = OS_DURATION_INIT(1, 0); + os_duration duration; + os_timeW deleteTimeW; + struct deleteHistoricalDataHelper* data; + struct createPersistentSnapshotHelper* snapshotHelper; + + if (o && userData) { + listener = d_listener(userData); + assert(d_groupLocalListenerIsValid(listener)); + admin = d_listenerGetAdmin(listener); + durability = d_adminGetDurability(admin); + queue = d_groupLocalListener(listener)->actionQueue; + + if((event->kind & V_EVENT_NEW_GROUP) == V_EVENT_NEW_GROUP){ + action = d_actionNew(os_timeMGet(), sleepTime, d_groupLocalAction, listener); + d_actionQueueAdd(queue, action); + } + if((event->kind & V_EVENT_HISTORY_REQUEST) == V_EVENT_HISTORY_REQUEST){ + d_groupLocalListenerHandleReaderRequest( + d_groupLocalListener(listener), event); + } + + if((event->kind & V_EVENT_HISTORY_DELETE) == V_EVENT_HISTORY_DELETE){ + data = (struct deleteHistoricalDataHelper*)(os_malloc( + sizeof(struct deleteHistoricalDataHelper))); + /* To notify fellows a d_deleteData message will generated. This + * message requires the wallclock timestamp that is used as discriminator + * which data to purge. The event, however, has this data available as + * an elapsed time. Therefore, we need to calculate the wall clock time + * from the elapsed time. + * Note that this calculation requires time alignment between nodes. + */ + duration = os_timeEDiff(os_timeEGet(), v_waitsetEventHistoryDeleteTime(event)); + deleteTimeW = os_timeWAdd(os_timeWGet(), duration); + + data->deleteTimeW = deleteTimeW; + data->partExpr = os_strdup(v_waitsetEventHistoryDeletePartitionExpr(event)); + data->topicExpr = os_strdup(v_waitsetEventHistoryDeleteTopicExpr(event)); + data->listener = listener; + + d_printTimedEvent(durability, D_LEVEL_FINE, + "Received local deleteHistoricalData event for partition topic %s.%s upto time %"PA_PRItime". Going to notify fellows ...\n", + data->partExpr, data->topicExpr, OS_TIMEW_PRINT(deleteTimeW)); + + action = d_actionNew(os_timeMGet(), sleepTime, d_groupDeleteHistoricalDataAction, data); + d_actionQueueAdd(queue, action); + } + if((event->kind & V_EVENT_PERSISTENT_SNAPSHOT) == V_EVENT_PERSISTENT_SNAPSHOT) + { + d_printTimedEvent(durability, D_LEVEL_FINE, + "Received a request for a persistent snapshot for partition " + "expression '%s' and topic expression '%s' to be stored at" + "destination '%s'.\n", + v_waitsetEventPersistentSnapshotPartitionExpr(event), + v_waitsetEventPersistentSnapshotTopicExpr(event), + v_waitsetEventPersistentSnapshotURI(event)); + + snapshotHelper = (struct createPersistentSnapshotHelper*)(os_malloc( + sizeof(struct createPersistentSnapshotHelper))); + snapshotHelper->partExpr = os_strdup(v_waitsetEventPersistentSnapshotPartitionExpr(event)); + snapshotHelper->topicExpr = os_strdup(v_waitsetEventPersistentSnapshotTopicExpr(event)); + snapshotHelper->uri = os_strdup(v_waitsetEventPersistentSnapshotURI(event)); + snapshotHelper->listener = listener; + + action = d_actionNew(os_timeMGet(), sleepTime, d_groupCreatePersistentSnapshotAction, snapshotHelper); + d_actionQueueAdd(queue, action); + } + if((event->kind & V_EVENT_CONNECT_WRITER) == V_EVENT_CONNECT_WRITER) { + admin = d_listenerGetAdmin(listener); + + /* Set namespace quality to infinite */ + markGroupNamespaceWritten(admin, v_waitsetEventConnectWriterGroup(event)); + } + } + + return event->kind; +} + +#define _MASK_ (V_EVENT_CONNECT_WRITER | V_EVENT_NEW_GROUP | \ + V_EVENT_HISTORY_DELETE | V_EVENT_HISTORY_REQUEST | \ + V_EVENT_PERSISTENT_SNAPSHOT | V_EVENT_TRIGGER) + +c_bool +d_groupLocalListenerStart( + d_groupLocalListener listener) +{ + c_bool result; + u_object object; + u_result ur; + u_eventMask mask; + d_durability durability; + + c_bool wsResult; + d_waitset waitset; + d_admin admin; + d_subscriber subscriber; + d_waitsetAction action; + d_store store; + os_threadAttr attr; + os_result osr; + d_thread self = d_threadLookupSelf (); + + result = FALSE; + + assert(d_groupLocalListenerIsValid(listener)); + + /* Setup listener for CONNECT_WRITER, NEW_GROUP, HISTORY_DELETE, HISTORY_REQUEST and PERSISTENT_SNAPSHOT events */ + if(listener){ + d_listenerLock(d_listener(listener)); + durability = d_adminGetDurability(d_listenerGetAdmin(d_listener(listener))); + object = u_object( d_durabilityGetService(durability)); + action = d_groupLocalListenerAction; /* callback function */ + + if(d_listener(listener)->attached == FALSE){ + ur = u_observableGetListenerMask(u_observable(object), &mask); + + if(ur == U_RESULT_OK){ + mask = mask | _MASK_; + ur = u_observableSetListenerMask(u_observable(object), mask); + + if(ur == U_RESULT_OK){ + admin = d_listenerGetAdmin(d_listener(listener)); + subscriber = d_adminGetSubscriber(admin); + store = d_subscriberGetPersistentStore(subscriber); + waitset = d_subscriberGetWaitset(subscriber); + + /* Create and attach waitset for listener */ + os_threadAttrInit(&attr); + listener->waitsetData = d_waitsetEntityNew( + "groupLocalListener", + object, action, + _MASK_, + attr, listener); + wsResult = d_waitsetAttach(waitset, listener->waitsetData); + + if(wsResult == TRUE) { + ur = U_RESULT_OK; + } else { + ur = U_RESULT_ILL_PARAM; + } + + if (listener->initialGroupsAdministrated == FALSE) { + d_durabilitySetState(durability, D_STATE_DISCOVER_PERSISTENT_SOURCE); + /* Because master determination can take quite some time + * liveliness of this thread must regularly be asserted + * to prevent that this thread is declared dead. + * To ensure thread liveness we use a tryLock icw + * d_sleep instead of an ordinary lock (the latter + * does not asserts liveliness in case another thread + * holds the lock for a very long time). + */ + do { + osr = os_mutexTryLock(&listener->masterLock); + if (osr == os_resultFail) { + OS_REPORT(OS_ERROR, "d_groupLocalListenerStart", 0, + "Failure to try to acquire the masterlock"); + d_durabilityTerminate(durability, FALSE); + break; + } else if (osr == os_resultBusy) { + d_sleep(self, OS_DURATION_INIT(0, 100000000)); /* 100 ms */ + } + } while (osr != os_resultSuccess); + d_adminAddListener(admin, listener->fellowListener); + d_adminAddListener(admin, listener->nameSpaceListener); + + initMasters(listener); + + if(store != NULL){ + initPersistentData(listener); + d_printTimedEvent(durability, D_LEVEL_FINER, "Persistency has been enabled...\n"); + } else { + d_printTimedEvent(durability, D_LEVEL_FINER, "Persistency has not been enabled...\n"); + } + os_mutexUnlock(&listener->masterLock); + d_durabilitySetState(durability, D_STATE_DISCOVER_LOCAL_GROUPS); + d_printTimedEvent(durability, D_LEVEL_FINER, "Initializing local groups...\n"); + + if(d_durabilityMustTerminate(durability) == FALSE){ + (void)u_serviceFillNewGroups(u_service(object)); + (void)u_observableAction(u_observable(object), d_groupLocalListenerHandleNewGroupsLocal, listener); + } + d_durabilitySetState(durability, D_STATE_FETCH_INITIAL); + listener->initialGroupsAdministrated = TRUE; + d_printTimedEvent(durability, D_LEVEL_FINEST, "Local groups initialized.\n"); + } + if(ur == U_RESULT_OK){ + d_listener(listener)->attached = TRUE; + result = TRUE; + d_listenerUnlock(d_listener(listener)); + (void) u_observableNotify(u_observable(object)); + } else { + d_listenerUnlock(d_listener(listener)); + } + } else { + d_listenerUnlock(d_listener(listener)); + } + } else { + d_listenerUnlock(d_listener(listener)); + } + } else { + d_listenerUnlock(d_listener(listener)); + result = TRUE; + } + } + return result; +} + +c_bool +d_groupLocalListenerStop( + d_groupLocalListener listener) +{ + c_bool result; + u_result ur; + d_admin admin; + d_subscriber subscriber; + d_waitset waitset; + + assert(d_groupLocalListenerIsValid(listener)); + + result = FALSE; + + if(listener){ + d_listenerLock(d_listener(listener)); + + if(d_listener(listener)->attached == TRUE){ + admin = d_listenerGetAdmin(d_listener(listener)); + subscriber = d_adminGetSubscriber(admin); + + /* Remove the listeners */ + d_adminRemoveListener(admin, listener->nameSpaceListener); + d_adminRemoveListener(admin, listener->fellowListener); + + waitset = d_subscriberGetWaitset(subscriber); + result = d_waitsetDetach(waitset, listener->waitsetData); + + if(result == TRUE) { + d_waitsetEntityFree(listener->waitsetData); + ur = U_RESULT_OK; + } else { + ur = U_RESULT_ILL_PARAM; + } + if(ur == U_RESULT_OK) { + d_listener(listener)->attached = FALSE; + result = TRUE; + } + } else { + result = TRUE; + } + d_listenerUnlock(d_listener(listener)); + } + return result; +} + +c_ulong +d_groupLocalListenerNewGroupLocalAction( + u_object o, + c_ulong event, + c_voidp userData) +{ + d_admin admin; + d_durability durability; + d_listener listener; + + if (o && (event & V_EVENT_NEW_GROUP)) { + if (userData) { + listener = d_listener(userData); + assert(d_groupLocalListenerIsValid(listener)); + admin = d_listenerGetAdmin(listener); + durability = d_adminGetDurability(admin); + + (void)u_observableAction(u_observable(d_durabilityGetService(durability)), d_groupLocalListenerHandleNewGroupsLocal, userData); + + } + } + return V_EVENT_NEW_GROUP; +} + +/** + * \brief Called when a new local group is created. + */ +void +d_groupLocalListenerHandleAlignment( + d_groupLocalListener listener, + d_group dgroup, + d_readerRequest readerRequest) +{ + os_timeW stamp, networkAttachTime; + d_sampleRequest request; + d_admin admin; + d_durability durability; + d_subscriber subscriber; + d_store store; + d_completeness completeness; + d_configuration config; + d_durabilityKind dkind; + c_bool timeRangeActive, requestRemote, inject; + d_group localGroup; + c_char *partition, *topic; + d_nameSpace nameSpace; + d_alignmentKind akind; + d_chain chain; + d_adminStatisticsInfo info; + d_nameSpace groupNameSpace; + + assert(d_groupLocalListenerIsValid(listener)); + + admin = d_listenerGetAdmin(d_listener(listener)); + subscriber = d_adminGetSubscriber(admin); + store = d_subscriberGetPersistentStore(subscriber); + durability = d_adminGetDurability(admin); + config = d_durabilityGetConfiguration(durability); + partition = d_groupGetPartition(dgroup); + topic = d_groupGetTopic(dgroup); + localGroup = d_adminGetLocalGroup(admin, partition, topic, d_groupGetKind(dgroup)); + + if(localGroup){ + completeness = d_groupGetCompleteness(localGroup); + dkind = d_groupGetKind(localGroup); + nameSpace = d_adminGetNameSpaceForGroup(admin, partition, topic); + + if(readerRequest){ + requestRemote = FALSE; + + if(nameSpace){ + d_storeResult result; + akind = d_nameSpaceGetAlignmentKind(nameSpace); + + if((akind == D_ALIGNEE_ON_REQUEST) && (completeness != D_GROUP_COMPLETE)){ + if(dkind == D_DURABILITY_PERSISTENT){ + inject = d_nameSpaceMasterIsMe(nameSpace, admin); + + if(inject || d_groupIsPrivate(localGroup)){ + result = d_storeMessagesInject(store, localGroup); + if(result == D_STORE_RESULT_OK){ + if(d_groupIsPrivate(localGroup)) { + d_groupSetComplete(localGroup, admin); + d_groupSetKernelGroupCompleteness(localGroup, TRUE); + } + d_printTimedEvent(durability, D_LEVEL_FINE, + "Data for group %s.%s injected from disk. Group is complete now (0).\n", + partition, topic); + } else { + d_printTimedEvent(durability, D_LEVEL_SEVERE, + "Injecting data from disk for group %s.%s failed (0).\n", + partition, topic); + } + d_readerRequestRemoveGroup(readerRequest, localGroup); + } else { + requestRemote = TRUE; + } + } else if(!d_groupIsPrivate(localGroup)){ + requestRemote = TRUE; + } else { + /* All data available, so we're done for this group*/ + } + + } else if(completeness == D_GROUP_COMPLETE){ + d_readerRequestRemoveGroup(readerRequest, localGroup); + } else { + /* Simply wait for group completeness later on */ + } + } else { + /* Not in nameSpace so ignore request for this group */ + d_readerRequestSetGroupIgnored(readerRequest); + + d_readerRequestRemoveGroup(readerRequest, localGroup); + + d_printTimedEvent(durability, D_LEVEL_WARNING, + "Received a historicalDataRequest from a reader for group %s.%s, "\ + "but that is not in the nameSpace and therefore ignored.\n", + partition, topic); + + } + + if(requestRemote == TRUE){ + stamp = os_timeWGet(); + + if(config->timeAlignment){ + networkAttachTime = stamp; + } else { + networkAttachTime = OS_TIMEW_INFINITE; + } + timeRangeActive = FALSE; + + request = d_sampleRequestNew( + admin, partition, topic, + dkind, stamp, timeRangeActive, + OS_TIMEW_ZERO, networkAttachTime); + + d_sampleRequestSetCondition(request, readerRequest); + chain = d_chainNew(admin, request); + d_readerRequestAddChain(readerRequest, chain); + d_readerRequestRemoveGroup(readerRequest, localGroup); + + if (akind == D_ALIGNEE_ON_REQUEST) { + /* set ignoreTransactionFlush on kernel group to ensure that the + * possible transaction messages are forwarded to the group + * but when the transaction becomes complete it is not flushed to + * the group. + */ + v_groupSetOnRequest(dgroup->vgroup, TRUE); + } + + d_sampleChainListenerInsertRequest( + d_groupLocalListener(listener)->sampleChainListener, + chain, TRUE); + + } + + /* No request has been received */ + } else if(d_adminGroupInActiveAligneeNS(admin, partition, topic) == TRUE){ + if(completeness != D_GROUP_COMPLETE){ + if(dkind == D_DURABILITY_PERSISTENT){ + assert(nameSpace); + akind = d_nameSpaceGetAlignmentKind(nameSpace); + inject = d_nameSpaceMasterIsMe(nameSpace, admin); + + if(inject == TRUE){ + if(akind == D_ALIGNEE_LAZY){ + d_storeResult result = d_storeMessagesInject(store, localGroup); + + if(result == D_STORE_RESULT_OK){ + d_printTimedEvent(durability, D_LEVEL_FINE, + "Data for group %s.%s injected from disk. Group is complete now (1).\n", + partition, topic); + } else { + d_printTimedEvent(durability, D_LEVEL_SEVERE, + "Injecting data from disk for group %s.%s failed (1).\n", + partition, topic); + } + } else if(akind == D_ALIGNEE_ON_REQUEST){ + d_storeResult result = d_storeMessagesInject(store, localGroup); + + if(result == D_STORE_RESULT_OK){ + d_printTimedEvent(durability, D_LEVEL_FINE, + "Data for group %s.%s injected from disk. Group is complete now (2).\n", + partition, topic); + } else { + d_printTimedEvent(durability, D_LEVEL_SEVERE, + "Injecting data from disk for group %s.%s failed (1).\n", + partition, topic); + } + } else if(akind == D_ALIGNEE_INITIAL){ + d_printTimedEvent(durability, D_LEVEL_FINE, + "Persistent group %s.%s complete, because I am persistent source and already injected data.\n", + partition, topic); + } else { + assert(FALSE); + } + if(d_groupIsPrivate(localGroup)){ + d_groupSetComplete(localGroup, admin); + d_groupSetKernelGroupCompleteness(localGroup, TRUE); + requestRemote = FALSE; + } else { + requestRemote = TRUE; + } + } else if(d_groupIsPrivate(localGroup)){ + /* I am not the master, but this is a persistent group + * that exists on this node only, so inject data for + * group. + */ + d_storeResult result = d_storeMessagesInject(store, localGroup); + + if(result == D_STORE_RESULT_OK){ + d_printTimedEvent(durability, D_LEVEL_FINE, + "Data for local group %s.%s injected from disk. Group is complete now (3).\n", + partition, topic); + } else { + d_printTimedEvent(durability, D_LEVEL_SEVERE, + "Injecting data from disk for local group %s.%s failed (3).\n", + partition, topic); + } + d_groupSetComplete(localGroup, admin); + d_groupSetKernelGroupCompleteness(localGroup, TRUE); + requestRemote = FALSE; + } else { + /*Only request if complete.*/ + requestRemote = TRUE; + } + } else if(d_groupIsPrivate(localGroup)){ + /* This group is private and transient so it is complete */ + d_groupSetComplete(localGroup, admin); + d_groupSetKernelGroupCompleteness(localGroup, TRUE); + d_printTimedEvent(durability, D_LEVEL_FINE, + "Transient group %s.%s complete, because it is local.\n", + partition, topic); + requestRemote = FALSE; + } else { + requestRemote = TRUE; + } + + /* Request samples for this group */ + if(requestRemote == TRUE){ + stamp = os_timeWGet(); + + if(config->timeAlignment){ + networkAttachTime = stamp; + } else { + networkAttachTime = OS_TIMEW_INFINITE; + } + timeRangeActive = FALSE; + + if((dkind == D_DURABILITY_PERSISTENT) && store){ + + } + + request = d_sampleRequestNew(admin, partition, topic, + dkind, stamp, timeRangeActive, OS_TIMEW_ZERO, networkAttachTime); + + chain = d_chainNew(admin, request); + d_sampleChainListenerInsertRequest( + d_groupLocalListener(listener)->sampleChainListener, + chain, TRUE); + } + } + } else if(d_adminGroupInAligneeNS(admin, partition, topic) == TRUE){ + d_sampleChainListenerReportGroup(listener->sampleChainListener, localGroup); + /* For those topics in a on_request namespace, they will be marked unaligned */ + groupNameSpace = d_adminGetNameSpaceForGroup(admin, + d_groupGetPartition(localGroup), + d_groupGetTopic(localGroup)); + + if ((d_nameSpaceGetAlignmentKind(groupNameSpace) == D_ALIGNEE_ON_REQUEST) + && (d_groupIsBuiltinGroup(localGroup) != TRUE)) { + + d_groupSetUnaligned(localGroup, admin); + + d_printTimedEvent(durability, D_LEVEL_FINE, + "Group %s.%s is transient group in the namespace with " \ + "on_request policy will be marked unaligned.\n", + partition, topic); + } + } else { + d_configuration c = d_durabilityGetConfiguration(durability); + + d_printTimedEvent(durability, D_LEVEL_FINE, + "Group %s.%s not in alignee namespace, so no alignment action taken.\n", + partition, topic); + + /* Always mark d_group as no-interest */ + d_groupSetNoInterest(localGroup, admin); + + /* If DDSI is running, it is responsible for both TRANSIENT_LOCAL as + * well as built-in groups. In that case durability should not mark + * v_group-alignstate. In all other cases, it should + */ + if (d_isBuiltinGroup(partition, topic) || (d_groupGetKind(localGroup) == D_DURABILITY_TRANSIENT_LOCAL)) { + /* The heartbeat-group should never be considered TRANSIENT, so + * it is marked NO_INTEREST in all cases. + */ + if (c->mustAlignBuiltinTopics || d_isHeartbeatGroup(partition, topic)) { + d_groupSetKernelGroupNoInterest(localGroup); + } + } else { + d_groupSetKernelGroupNoInterest(localGroup); + } + + /* update statistics */ + info = d_adminStatisticsInfoNew(); + info->kind = D_ADMIN_STATISTICS_GROUP; + + switch(dkind){ + case D_DURABILITY_VOLATILE: + info->groupsIncompleteVolatileDif -= 1; + info->groupsIgnoredVolatileDif +=1; + break; + case D_DURABILITY_TRANSIENT_LOCAL: + case D_DURABILITY_TRANSIENT: + info->groupsIncompleteTransientDif -= 1; + info->groupsIgnoredTransientDif +=1; + break; + case D_DURABILITY_PERSISTENT: + info->groupsIncompletePersistentDif -= 1; + info->groupsIgnoredPersistentDif +=1; + break; + default: + break; + } + + d_adminUpdateStatistics(admin, info); + d_adminStatisticsInfoFree(info); + } + } + os_free(partition); + os_free(topic); +} diff --git a/src/services/durability/code/d_groupRemoteListener.c b/src/services/durability/code/d_groupRemoteListener.c new file mode 100644 index 000000000..17e73f9f3 --- /dev/null +++ b/src/services/durability/code/d_groupRemoteListener.c @@ -0,0 +1,398 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#include "vortex_os.h" +#include "d__groupRemoteListener.h" +#include "d__sampleChainListener.h" +#include "d__readerListener.h" +#include "d__listener.h" +#include "d__admin.h" +#include "d__fellow.h" +#include "d__actionQueue.h" +#include "d__subscriber.h" +#include "d__configuration.h" +#include "d__publisher.h" +#include "d__nameSpace.h" +#include "d__durability.h" +#include "d__misc.h" +#include "d__groupCreationQueue.h" +#include "d__group.h" +#include "d__eventListener.h" +#include "d_newGroup.h" +#include "d_message.h" +#include "d_nameSpacesRequest.h" +#include "d_networkAddress.h" +#include "u_group.h" +#include "u_participant.h" +#include "u_entity.h" +#include "os_heap.h" +#include "os_thread.h" + +/** + * Macro that checks the d_groupRemoteListener validity. + * Because d_groupRemoteListener is a concrete class typechecking is required. + */ +#define d_groupRemoteListenerIsValid(_this) \ + d_listenerIsValidKind(d_listener(_this), D_GROUP_REMOTE_LISTENER) + +/** + * \brief The d_groupRemoteListener cast macro. + * + * This macro casts an object to a d_groupRemoteListener object. + */ +#define d_groupRemoteListener(_this) ((d_groupRemoteListener)(_this)) + + +C_STRUCT(d_groupRemoteListener){ + C_EXTENDS(d_readerListener); + d_groupCreationQueue groupCreationQueue; +}; + +/** + * \brief Handle the reception of a d_group message + */ +static void +d_groupRemoteListenerAction( + d_listener listener, + d_message message) +{ + d_newGroup remote; + d_durability durability; + d_admin admin; + d_group group, group2; + d_fellow fellow; + c_bool createLocally, added; + u_group ugroup; + d_networkAddress addr; + c_bool result; + d_subscriber subscriber; + d_sampleChainListener sampleChainListener; + d_completeness localCompleteness; + d_quality quality; + + assert(d_groupRemoteListenerIsValid(listener)); + + remote = d_newGroup(message); + admin = d_listenerGetAdmin(listener); + durability = d_adminGetDurability(admin); + addr = d_networkAddressNew(message->senderAddress.systemId, + message->senderAddress.localId, + message->senderAddress.lifecycleId); + + fellow = d_adminGetFellow(admin, addr); + + d_qualityExtToQuality(&quality, &remote->quality, IS_Y2038READY(remote)); + if (remote->partition && remote->topic) { + d_printTimedEvent(durability, D_LEVEL_FINE, + "Received remote group '%s.%s' with completeness=%d and quality=%"PA_PRItime" from fellow: %u.\n", + remote->partition, remote->topic, + remote->completeness, + OS_TIMEW_PRINT(quality), + message->senderAddress.systemId); + } + if (fellow) { + if (d_fellowGetCommunicationState(fellow) == D_COMMUNICATION_STATE_APPROVED) { + /* When a remote group message is received with both + * partition and topic NULL, this indicates that the + * fellow does not have any groups. The expected number + * of groups is transferred always, even the partition + * and topic are NULL. + */ + d_fellowSetExpectedGroupCount(fellow, (c_long) remote->alignerCount); + if ((remote->partition != NULL) && (remote->topic != NULL)) { + group = d_adminGetLocalGroup(admin, remote->partition, + remote->topic, remote->durabilityKind); + if (!group) { + /* The remote group is not yet locally known, so try to create it.*/ + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Received remote group %s.%s which is locally unknown.\n", + remote->partition, remote->topic); + group = d_groupNew(remote->partition, remote->topic, + remote->durabilityKind, + remote->completeness, quality); + added = d_fellowAddGroup(fellow, group); + d_fellowSetExpectedGroupCount(fellow, (c_long) remote->alignerCount); + if (added == FALSE) { + /* Remote group already present in the fellow administration */ + d_groupFree(group); + group = d_fellowGetGroup(fellow, remote->partition, + remote->topic, + remote->durabilityKind); + if (group) { + d_printTimedEvent(durability, D_LEVEL_FINER, + "Remote group %s.%s already known for fellow %u, updating quality=%"PA_PRItime" and completeness=%d.\n", + remote->partition, remote->topic, message->senderAddress.systemId, + OS_TIMEW_PRINT(quality), remote->completeness); + /* Update the group */ + d_groupUpdate(group, remote->completeness, quality, admin); + d_groupFree(group); + } else { + d_printTimedEvent(durability, D_LEVEL_WARNING, + "Remote group %s.%s not added for fellow %u, but also not found.\n", + remote->partition, remote->topic, + message->senderAddress.systemId); + } + } else { + /* Remote group was not known yet in the fellow administration, + * register the group with the fellow. + */ + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Remote group %s.%s registered for fellow %u with quality=%"PA_PRItime" and completeness=%d.\n", + remote->partition, remote->topic, message->senderAddress.systemId, + OS_TIMEW_PRINT(quality), remote->completeness); + } + + /* Even though the group didn't exist when entering this function, + * this might no longer be the case. + * A complete group might be interesting in case there are + * still unfullfilled chain requests. + */ + if (remote->completeness == D_GROUP_COMPLETE) { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Remote group '%s.%s' complete, check for unfulfilled chains.\n", + remote->partition, remote->topic); + subscriber = d_adminGetSubscriber(admin); + sampleChainListener = d_subscriberGetSampleChainListener(subscriber); + group = d_groupNew(remote->partition, remote->topic, + remote->durabilityKind, + remote->completeness, quality); + d_sampleChainListenerTryFulfillChains(sampleChainListener, group); + d_groupFree(group); + } + + /* Group unknown locally, check if it should be aligned + * initially. In case DDSI is responsible for builtin + * topics then durability must NOT create the local + * group. + */ + createLocally = d_adminGroupInInitialAligneeNS( + admin, remote->partition, + remote->topic); + + if (createLocally == TRUE) { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Remote group %s.%s in initial alignee namespace, so creating locally...\n", + remote->partition, remote->topic); + + ugroup = u_groupNew( + u_participant(d_durabilityGetService(durability)), + remote->partition, remote->topic, 10*OS_DURATION_MILLISECOND); + + if(ugroup){ + d_printTimedEvent(durability, D_LEVEL_FINER, + "Remote group %s.%s with quality %"PA_PRItime" created locally.\n", + remote->partition, remote->topic, OS_TIMEW_PRINT(quality)); + u_objectFree(u_object(ugroup)); + } else { + d_printTimedEvent(durability, D_LEVEL_WARNING, + "Remote group %s.%s with quality %"PA_PRItime" could NOT be created locally.\n", + remote->partition, remote->topic, OS_TIMEW_PRINT(quality)); + /* TODO: quality must not be taken over from remote. */ + group2 = d_groupNew(remote->partition, remote->topic, + remote->durabilityKind, D_GROUP_INCOMPLETE, quality); + result = d_groupCreationQueueAdd( + d_groupRemoteListener(listener)->groupCreationQueue, + group2); + + if(result == FALSE){ + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Remote group %s.%s already in creation queue. Skipping this one.\n", + remote->partition, remote->topic); + d_groupFree(group2); + } + } + } else { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Remote group %s.%s NOT created locally.\n", + remote->partition, remote->topic); + } + } else { + /* The group is already locally known */ + localCompleteness = d_groupGetCompleteness(group); + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Remote group '%s.%s' already known locally with completeness=%d.\n", + remote->partition, remote->topic, localCompleteness); + group = d_fellowGetGroup(fellow, remote->partition, + remote->topic, remote->durabilityKind); + if (group) { + /* The fellow already knows the group, update the group */ + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Updating remote group '%s.%s' for fellow %u with completeness=%d and quality=%"PA_PRItime".\n", + remote->partition, remote->topic, message->senderAddress.systemId, + remote->completeness, OS_TIMEW_PRINT(quality)); + d_groupUpdate(group, remote->completeness, quality, admin); + d_groupFree(group); + } else { + /* The fellow does not know the group, add it to the fellow */ + group = d_groupNew(remote->partition, remote->topic, remote->durabilityKind, remote->completeness, quality); + added = d_fellowAddGroup(fellow, group); + if (added == FALSE) { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Remote group '%s.%s' with completeness=%d and quality=%"PA_PRItime" could not be registered for fellow %u.\n", + remote->partition, remote->topic, remote->completeness, + OS_TIMEW_PRINT(quality), message->senderAddress.systemId); + d_groupFree(group); + group = d_fellowGetGroup(fellow, remote->partition, remote->topic, remote->durabilityKind); + if (group) { + d_printTimedEvent(durability, D_LEVEL_FINER, + "Updating remote group '%s.%s' for fellow %u with completeness=%d and quality=%"PA_PRItime".\n", + remote->partition, remote->topic, message->senderAddress.systemId, + remote->completeness, OS_TIMEW_PRINT(quality)); + d_groupUpdate(group, remote->completeness, quality, admin); + d_groupFree(group); + } + } else { + d_printTimedEvent(durability, D_LEVEL_FINER, + "Remote group '%s.%s' with completeness=%d and quality=%"PA_PRItime" registered for fellow %u.\n", + remote->partition, remote->topic, remote->completeness, + OS_TIMEW_PRINT(quality), message->senderAddress.systemId); + } + } + /* A complete group might be interesting in case there are + * still unfullfilled chain requests. + */ + if (remote->completeness == D_GROUP_COMPLETE) { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Remote group '%s.%s' complete, check for unfulfilled chains.\n", + remote->partition, remote->topic); + subscriber = d_adminGetSubscriber(admin); + sampleChainListener = d_subscriberGetSampleChainListener(subscriber); + group = d_groupNew(remote->partition, remote->topic, remote->durabilityKind, + remote->completeness, quality); + d_sampleChainListenerTryFulfillChains(sampleChainListener, group); + d_groupFree(group); + } + } + } + } else { + d_printTimedEvent(durability, D_LEVEL_WARNING, + "Fellow %u not approved, so ignoring remote group message.\n", + message->senderAddress.systemId); + } + d_fellowFree(fellow); + } else { + d_printTimedEvent(durability, D_LEVEL_WARNING, + "Fellow %u unknown so far, so ignoring remote group message.\n", + message->senderAddress.systemId); + } + d_networkAddressFree(addr); + + return; +} +static void +d_groupRemoteListenerDeinit( + d_groupRemoteListener listener) +{ + assert(d_groupRemoteListenerIsValid(listener)); + + /* Stop the groupRemoteListener before cleaning up. */ + d_groupRemoteListenerStop(listener); + /* Destroy the groupCreationQueue */ + if (listener->groupCreationQueue) { + d_groupCreationQueueFree(listener->groupCreationQueue); + } + /* Call super-deinit */ + d_readerListenerDeinit(d_readerListener(listener)); +} + +static void +d_groupRemoteListenerInit( + d_groupRemoteListener listener, + d_subscriber subscriber) +{ + os_threadAttr attr; + d_admin admin; + + /* Do not assert the listener because the initialization + * of the listener has not yet completed + */ + + assert(d_subscriberIsValid(subscriber)); + + /* Call super-init */ + os_threadAttrInit(&attr); + d_readerListenerInit( d_readerListener(listener), + D_GROUP_REMOTE_LISTENER, + d_groupRemoteListenerAction, + subscriber, + D_NEWGROUP_TOPIC_NAME, + D_NEWGROUP_TOP_NAME, + V_RELIABILITY_RELIABLE, + V_HISTORY_KEEPALL, + V_LENGTH_UNLIMITED, + attr, + (d_objectDeinitFunc)d_groupRemoteListenerDeinit); + /* Create the groupCreationQueue */ + admin = d_listenerGetAdmin(d_listener(listener)); + assert(d_adminIsValid(admin)); + listener->groupCreationQueue = d_groupCreationQueueNew(admin); +} + +d_groupRemoteListener +d_groupRemoteListenerNew( + d_subscriber subscriber) +{ + d_groupRemoteListener listener; + + assert(d_subscriberIsValid(subscriber)); + + /* Allocate groupRemoteListener object */ + listener = d_groupRemoteListener(os_malloc(C_SIZEOF(d_groupRemoteListener))); + if (listener) { + /* Initialize the groupsRequestListener */ + d_groupRemoteListenerInit(listener, subscriber); + } + return listener; +} + +void +d_groupRemoteListenerFree( + d_groupRemoteListener listener) +{ + assert(d_groupRemoteListenerIsValid(listener)); + + d_objectFree(d_object(listener)); +} + +c_bool +d_groupRemoteListenerStart( + d_groupRemoteListener listener) +{ + assert(d_groupRemoteListenerIsValid(listener)); + + return d_readerListenerStart(d_readerListener(listener)); +} + +c_bool +d_groupRemoteListenerStop( + d_groupRemoteListener listener) +{ + c_bool result; + + result = d_readerListenerStop(d_readerListener(listener)); + + return result; +} + + + +c_bool +d_groupRemoteListenerAreRemoteGroupsHandled( + d_groupRemoteListener listener) +{ + return d_groupCreationQueueIsEmpty(listener->groupCreationQueue); +} diff --git a/src/services/durability/code/d_groupsRequest.c b/src/services/durability/code/d_groupsRequest.c new file mode 100644 index 000000000..8988853aa --- /dev/null +++ b/src/services/durability/code/d_groupsRequest.c @@ -0,0 +1,68 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "d_groupsRequest.h" +#include "d_message.h" +#include "os_heap.h" +#include "vortex_os.h" + +d_groupsRequest +d_groupsRequestNew( + d_admin admin, + d_partition partition, + d_topic topic) +{ + d_groupsRequest groupsRequest = NULL; + + if(admin){ + groupsRequest = d_groupsRequest(os_malloc(C_SIZEOF(d_groupsRequest))); + d_messageInit(d_message(groupsRequest), admin); + + if(partition){ + groupsRequest->partition = os_strdup(partition); + } else { + groupsRequest->partition = NULL; + } + if(topic){ + groupsRequest->topic = os_strdup(topic); + } else { + groupsRequest->topic = NULL; + } + + } + return groupsRequest; +} + +void +d_groupsRequestFree( + d_groupsRequest groupsRequest) +{ + if(groupsRequest){ + d_messageDeinit(d_message(groupsRequest)); + + if(groupsRequest->partition){ + os_free(groupsRequest->partition); + groupsRequest->partition = NULL; + } + if(groupsRequest->topic){ + os_free(groupsRequest->topic); + groupsRequest->topic = NULL; + } + os_free(groupsRequest); + } +} diff --git a/src/services/durability/code/d_groupsRequestListener.c b/src/services/durability/code/d_groupsRequestListener.c new file mode 100644 index 000000000..2c5346737 --- /dev/null +++ b/src/services/durability/code/d_groupsRequestListener.c @@ -0,0 +1,301 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "vortex_os.h" +#include "d__groupsRequestListener.h" +#include "d__readerListener.h" +#include "d__listener.h" +#include "d__configuration.h" +#include "d__admin.h" +#include "d__misc.h" +#include "d__table.h" +#include "d__publisher.h" +#include "d__group.h" +#include "d__durability.h" +#include "d__thread.h" +#include "d_networkAddress.h" +#include "d_message.h" +#include "d_newGroup.h" +#include "v_time.h" +#include "os_heap.h" + +/** + * Macro that checks the d_groupsRequestListener validity. + * Because d_groupsRequestListener is a concrete class typechecking is required. + */ +#define d_groupsRequestListenerIsValid(_this) \ + d_listenerIsValidKind(d_listener(_this), D_GROUPS_REQ_LISTENER) + +/** + * \brief The d_groupsRequestListener cast macro. + * + * This macro casts an object to a d_groupsRequestListener object. + */ +#define d_groupsRequestListener(_this) ((d_groupsRequestListener)(_this)) + +C_STRUCT(d_groupsRequestListener){ + C_EXTENDS(d_readerListener); +}; + +struct collectGroupsHelper { + d_table groups; + d_admin admin; + d_configuration config; + d_networkAddress addressee; + d_partition partition; + d_topic topic; +}; + + +/** + * \brief Collect group messages for all non-private local groups + * that match the partition/topic specified in args. + */ +static c_bool +collectLocalGroups( + d_group group, + c_voidp args) +{ + struct collectGroupsHelper *helper; + c_char *partition, *topic; + d_durabilityKind kind; + d_completeness completeness; + d_quality quality; + c_bool proceed; + + d_newGroup newGroup; + + helper = (struct collectGroupsHelper *)args; + + partition = d_groupGetPartition(group); + topic = d_groupGetTopic(group); + kind = d_groupGetKind(group); + completeness = d_groupGetCompleteness(group); + quality = d_groupGetQuality(group); + + /* Only send groups that fulfill the partition and/or topic that + * are requested. Besides that, local groups must also NOT be sent. + */ + proceed = TRUE; + if (proceed) { + if (d_groupIsPrivate(group)) { + proceed = FALSE; /* Don't send private groups */ + } + } + if (helper->partition) { + if(strcmp(helper->partition, partition) != 0){ + proceed = FALSE; /* Don't send groups with unmatching partition */ + } + } + if (proceed) { + if (helper->topic) { + if (strcmp(helper->topic, topic) != 0) { + proceed = FALSE; /* Don't send groups with unmatching topic */ + } + } + } + if (proceed) { + /* Also send the groups where I am not the aligner for since the master + * might not know this group and the data for this group will not be aligned + * when not sending the group. + */ + newGroup = d_newGroupNew(helper->admin, partition, topic, kind, + completeness, quality); + d_messageSetAddressee(d_message(newGroup), helper->addressee); + d_tableInsert(helper->groups, newGroup); + } + os_free(partition); + os_free(topic); + + return TRUE; +} + +struct sendGroupsHelper{ + d_publisher publisher; + d_networkAddress addressee; + d_durability durability; + c_ulong groupCount; + d_thread self; +}; + + +/** + * \brief Send the group to another durability service + * + * The group is send in a newGroup message. Each newGroup message contains + * the number of groups that the recipient can expect. + */ +static c_bool +sendLocalGroups( + d_newGroup group, + c_voidp args) +{ + struct sendGroupsHelper* helper; + + helper = (struct sendGroupsHelper*)args; + d_threadAwake(helper->self); + d_newGroupSetAlignerCount(group, helper->groupCount); + if (group->partition && group->topic) { + d_printTimedEvent(helper->durability, D_LEVEL_FINEST, + "-Group %s.%s with completeness=%d and quality=%d.%d\n", + group->partition, group->topic, group->completeness, + group->quality.seconds, group->quality.nanoseconds); + } + d_publisherNewGroupWrite(helper->publisher, group, helper->addressee); + + return TRUE; +} + +static void +d_groupsRequestListenerAction( + d_listener listener, + d_message message) +{ + d_durability durability; + struct collectGroupsHelper helper; + struct sendGroupsHelper sendHelper; + d_newGroup group; + d_groupsRequest request; + d_thread self = d_threadLookupSelf(); + + assert(d_groupsRequestListenerIsValid(listener)); + + request = (d_groupsRequest)message; + + helper.admin = d_listenerGetAdmin(listener); + durability = d_adminGetDurability(helper.admin); + helper.partition = request->partition; + helper.topic = request->topic; + helper.groups = d_tableNew(d_newGroupCompare, d_newGroupFree); + helper.config = d_durabilityGetConfiguration(durability); + helper.addressee = d_networkAddressNew(message->senderAddress.systemId, + message->senderAddress.localId, + message->senderAddress.lifecycleId); + + d_printTimedEvent(durability, D_LEVEL_FINE, + "Received groupsRequest from fellow %u; sending all groups\n", + message->senderAddress.systemId); + + d_adminGroupWalk(helper.admin, collectLocalGroups, &helper); + + sendHelper.groupCount = d_tableSize(helper.groups); + + d_printTimedEvent(durability, D_LEVEL_FINE, + "Sending %u groups to fellow %u.\n", sendHelper.groupCount, message->senderAddress.systemId); + sendHelper.publisher = d_adminGetPublisher(helper.admin); + sendHelper.addressee = helper.addressee; + sendHelper.durability = durability; + sendHelper.self = self; + + d_tableWalk(helper.groups, sendLocalGroups, &sendHelper); + + if(sendHelper.groupCount == 0){ /*let the sender know I received the request.*/ + group = d_newGroupNew(helper.admin, NULL, NULL, D_DURABILITY_TRANSIENT, + D_GROUP_COMPLETE, os_timeWGet()); + d_newGroupSetAlignerCount(group, 0); + d_publisherNewGroupWrite(sendHelper.publisher, group, sendHelper.addressee); + d_newGroupFree(group); + } + + d_networkAddressFree(helper.addressee); + d_tableFree(helper.groups); + + d_printTimedEvent(durability, D_LEVEL_FINEST, "All local groups sent to fellow\n"); + return; +} + +static void +d_groupsRequestListenerDeinit( + d_groupsRequestListener listener) +{ + assert(d_groupsRequestListenerIsValid(listener)); + + /* Stop the groupsRequestListener before cleaning up. */ + d_groupsRequestListenerStop(listener); + /* Nothing to deallocate, all super-deinit */ + d_readerListenerDeinit(d_readerListener(listener)); +} + +static void +d_groupsRequestListenerInit( + d_groupsRequestListener listener, + d_subscriber subscriber) +{ + os_threadAttr attr; + + /* Do not assert the listener because the initialization + * of the listener has not yet completed + */ + + assert(d_subscriberIsValid(subscriber)); + + /* Call super-init */ + os_threadAttrInit(&attr); + d_readerListenerInit( d_readerListener(listener), + D_GROUPS_REQ_LISTENER, + d_groupsRequestListenerAction, + subscriber, + D_GROUPS_REQ_TOPIC_NAME, + D_GROUPS_REQ_TOP_NAME, + V_RELIABILITY_RELIABLE, + V_HISTORY_KEEPALL, + V_LENGTH_UNLIMITED, + attr, + (d_objectDeinitFunc)d_groupsRequestListenerDeinit); +} + +d_groupsRequestListener +d_groupsRequestListenerNew( + d_subscriber subscriber) +{ + d_groupsRequestListener listener; + + assert(d_subscriberIsValid(subscriber)); + + /* Allocate groupsRequestListener object */ + listener = d_groupsRequestListener(os_malloc(C_SIZEOF(d_groupsRequestListener))); + if (listener) { + /* Initialize the groupsRequestListener */ + d_groupsRequestListenerInit(listener, subscriber); + } + return listener; +} + +void +d_groupsRequestListenerFree( + d_groupsRequestListener listener) +{ + assert(d_groupsRequestListenerIsValid(listener)); + + d_objectFree(d_object(listener)); +} + +c_bool +d_groupsRequestListenerStart( + d_groupsRequestListener listener) +{ + return d_readerListenerStart(d_readerListener(listener)); +} + +c_bool +d_groupsRequestListenerStop( + d_groupsRequestListener listener) +{ + return d_readerListenerStop(d_readerListener(listener)); +} + diff --git a/src/services/durability/code/d_historicalData.c b/src/services/durability/code/d_historicalData.c new file mode 100644 index 000000000..e57884344 --- /dev/null +++ b/src/services/durability/code/d_historicalData.c @@ -0,0 +1,538 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "d__historicalData.h" +#include "d__historicalDataRequest.h" +#include "d__admin.h" +#include "d__durability.h" +#include "d__publisher.h" +#include "d__subscriber.h" +#include "d__historicalDataRequestListener.h" +#include "d__configuration.h" +#include "d__misc.h" +#include "d_qos.h" +#include "v_time.h" +#include "os_report.h" + +c_bool delete_pubinfo(void *listener,void *arg); + + +/* Implementation of the callback to answer a request */ +c_bool +delete_pubinfo( + void *listener, + void *arg) +{ + OS_UNUSED_ARG(listener); + OS_UNUSED_ARG(arg); + + /* The only action is to cleanup the pubinfo. + * This will be done by the cleanup_node in + * d_historicalDataRequestListener::d_historicalDataRequestListenerHandlerThread */ + return FALSE; +} + + +/* Add pubInfo to deathrow, schedule execution in 10s from now. + * Returns pubInfo if an existing pubInfo is rescheduled, NULL otherwise */ +static struct pubInfo * +insert_pubinfo (d_historicalDataRequestListener listener, struct pubInfo * pubinfo) +{ + ut_avlIPath_t ip; + struct request_admin_node *n; + os_mutexLock (&listener->queue_lock); + if ((n = ut_avlLookupIPath (&listener->pubinfo_avltreedef, &listener->pubinfo_tree, pubinfo, &ip)) != NULL) { + /* This should never happen */ + os_mutexUnlock (&listener->queue_lock); + assert(0); + return NULL; + } else { + /* Insert the node in the tree and in the priority queue */ + n = os_malloc (sizeof (*n)); + n->insert_time = os_timeEGet(); + n->expiration_time = os_timeEAdd(n->insert_time, OS_DURATION_INIT(10, 0)); + n->handle_time = OS_TIMEE_ZERO; + n->callback = delete_pubinfo; /* callback function */ + n->arg = pubinfo; /* argument of the callback function */ + ut_avlInsertIPath (&listener->pubinfo_avltreedef, &listener->pubinfo_tree, n, &ip); + ut_fibheapInsert (&prioqueue_fhdef, &listener->prioqueue, n); + d_trace(D_TRACE_PRIO_QUEUE, "%s: avlnode %p created and added to deathrow, insert_time=%"PA_PRItime", expiration_time = %"PA_PRItime"\n", + OS_FUNCTION, (void *)n, OS_TIMEE_PRINT(n->insert_time), OS_TIMEE_PRINT(n->expiration_time)); + if (n == ut_fibheapMin (&prioqueue_fhdef, &listener->prioqueue)) { + d_trace(D_TRACE_PRIO_QUEUE, "%s: avlnode %p added to front of queue\n", OS_FUNCTION, (void *)n); + os_condSignal (&listener->cond); + } + os_mutexUnlock (&listener->queue_lock); + return NULL; + } +} + + +/* Release pubInfo from deathrow, return NULL if not found */ +struct pubInfo * +release_pubinfo (d_historicalDataRequestListener listener, struct pubInfo * pubinfo) +{ + ut_avlIPath_t ip; + struct request_admin_node *n; + os_mutexLock (&listener->queue_lock); + if ((n = ut_avlLookupIPath (&listener->pubinfo_avltreedef, &listener->pubinfo_tree, pubinfo, &ip)) != NULL) { + /* An old pubinfo (according to compare_request_by_pubinfo) already exists. + * Take and return the old request */ + /* Remove the node from the priority queue and the tree */ + struct pubInfo *old_pubinfo = (struct pubInfo *)(n->arg); + d_trace(D_TRACE_PRIO_QUEUE, "%s: avlnode %p released from the deathrow, insert_time=%"PA_PRItime", expiration_time=%"PA_PRItime"\n", + OS_FUNCTION, (void *)n, OS_TIMEE_PRINT(n->insert_time), OS_TIMEE_PRINT(n->expiration_time)); + ut_avlDelete (&listener->pubinfo_avltreedef, &listener->pubinfo_tree, n); + ut_fibheapDelete (&prioqueue_fhdef, &listener->prioqueue, n); + os_mutexUnlock (&listener->queue_lock); + return old_pubinfo; + } else { + d_trace(D_TRACE_PRIO_QUEUE, "%s: no matching avlnode found\n", OS_FUNCTION); + os_mutexUnlock (&listener->queue_lock); + return NULL; + } +} + + +struct pubInfo * +get_or_create_pubinfo (d_historicalData historicalData) +{ + d_durability durability; + d_subscriber subscriber; + d_historicalDataRequestListener listener; + d_configuration config; + struct pubInfo *tmp_pubinfo, *found_pubinfo; + v_publisherQos publisherQos; + v_writerQos writerQos; + u_result ur; + + assert(d_historicalDataIsValid(historicalData)); + + durability = historicalData->durability; + config = d_durabilityGetConfiguration(durability); + subscriber = d_adminGetSubscriber(durability->admin); + listener = d_subscriberGetHistoricalDataRequestListener(subscriber); + tmp_pubinfo = (struct pubInfo *)os_malloc(sizeof(struct pubInfo)); + tmp_pubinfo->publisher = NULL; + tmp_pubinfo->writer = NULL; + tmp_pubinfo->partition = os_strdup(historicalData->alignmentPartition); + if ((found_pubinfo = release_pubinfo(listener, tmp_pubinfo)) == NULL) { + /* no publisher/writer exist for this combination yet */ + if ((publisherQos = d_publisherQosNew(historicalData->alignmentPartition)) == NULL) { + goto err_allocPublisherQos; + } + if ((tmp_pubinfo->publisher = u_publisherNew(u_participant(d_durabilityGetService(durability)), config->clientDurabilityPublisherName, publisherQos, TRUE)) == NULL) { + d_publisherQosFree(publisherQos); + goto err_allocPublisher; + } + d_publisherQosFree(publisherQos); + /* There are historicalData readers out there that read the data with a liveliness.lease_duration 0. + * Since the liveliness qos matches only if the writerQos is less than or equal to the reader qos + * we must ensure that the historicalDataWriter has a lease_duration of 0 also to prevent any + * backwards compatibilites. + * Because the writer and publisher will be destroyed when all historicalData has been + * written we must ensure that autodispose_unregistered_instances is set to FALSE. This + * ensures that the data is not removed when the writer is destroyed. */ + if ((writerQos = d_writerQosNew(V_DURABILITY_VOLATILE,V_RELIABILITY_RELIABLE,V_ORDERBY_SOURCETIME, config->alignerLatencyBudget, config->alignerTransportPriority)) == NULL) { + goto err_allocWriterQos; + } + writerQos->lifecycle.v.autodispose_unregistered_instances = FALSE; + if ((tmp_pubinfo->writer = u_writerNew (tmp_pubinfo->publisher, "historicalDataWriter", d_adminGetHistoricalDataTopic(durability->admin), writerQos)) == NULL) { + d_writerQosFree(writerQos); + goto err_allocWriter; + } + d_writerQosFree(writerQos); + if (u_entityEnable(u_entity(tmp_pubinfo->writer)) != U_RESULT_OK) { + goto err_writerEnable; + } + if ((ur = u_observableAction(u_observable(tmp_pubinfo->writer),d_publisherEnsureServicesAttached,durability)) != U_RESULT_OK) { + goto err_observableAction; + } + historicalData->pubinfo = tmp_pubinfo; + } else { + /* a publisher/writer already exist */ + os_free(tmp_pubinfo->partition); + os_free(tmp_pubinfo); + historicalData->pubinfo = found_pubinfo; + } + return historicalData->pubinfo; + +err_observableAction: +err_writerEnable: + u_objectFree(u_object(tmp_pubinfo->writer)); +err_allocWriter: +err_allocWriterQos: + u_objectFree(u_object(tmp_pubinfo->publisher)); +err_allocPublisher: +err_allocPublisherQos: + os_free(tmp_pubinfo->partition); + os_free(tmp_pubinfo); + return NULL; +} + + +static v_copyin_result +d_publisherHistoricalDataWriterCopy( + c_type type, + const void *from, + void *to) +{ + d_historicalData historicalData = d_historicalData(from); + struct _DDS_HistoricalData *msgTo = (struct _DDS_HistoricalData *)to; + c_base base = c_getBase(type); + + /* Copy the version */ + msgTo->version = historicalData->version; + /* Copy my server gid */ + msgTo->serverId = historicalData->serverId; + /* Copy the list of requestIds */ + { + c_ulong len = 1; + c_type subtype0; + struct _DDS_RequestId_t *dst0; + + subtype0 = c_type(c_metaResolve (c_metaObject(base), "DDS::RequestId_t")); + dst0 = (struct _DDS_RequestId_t *)c_sequenceNew_s(subtype0, len, len); + c_free(subtype0); + if (!dst0) { + OS_REPORT (OS_ERROR, "copyIn", 0, "Member 'HistoricalData.requestIds' could not be allocated."); + goto err_allocRequestIds; + } + { + c_iterIter iter = c_iterIterGet(historicalData->historicalDataRequest->requestIds); + struct _DDS_RequestId_t *requestId; + c_ulong i = 0; + + while ((requestId = c_iterNext(&iter)) != NULL) { + dst0[i].clientId = requestId->clientId; + dst0[i].requestId = requestId->requestId; + i++; + } + } + msgTo->requestIds = (c_sequence)dst0; + } + /* Copy content */ + msgTo->content._d = historicalData->content._d; + /* Copy historicalDataContent */ + switch (msgTo->content._d) { + case HISTORICAL_DATA_KIND_BEAD: + memcpy(&msgTo->content._u.bead.writerId, &historicalData->content._u.bead.writerId, 16); + msgTo->content._u.bead.sourceTimestamp = historicalData->content._u.bead.sourceTimestamp; + msgTo->content._u.bead.sequenceNumber = historicalData->content._u.bead.sequenceNumber; + msgTo->content._u.bead.qos = historicalData->content._u.bead.qos; + { + c_ulong len = c_iterLength(historicalData->partitions); + c_type subtype0; + c_string *dst0; + + subtype0 = c_type(c_metaResolve (c_metaObject(base), "c_string")); + dst0 = (c_string *)c_sequenceNew_s(subtype0, len, len); + c_free(subtype0); + if (!dst0) { + OS_REPORT (OS_ERROR, "copyIn", 0, "Member 'HistoricalData.partitions' could not be allocated."); + goto err_allocPartitions; + } + { + c_iterIter iter = c_iterIterGet(historicalData->partitions); + char * partition; + c_ulong i = 0; + + while ((partition = (char *)c_iterNext(&iter)) != NULL) { + dst0[i] = c_stringNew_s(base, partition); + if (!dst0[i]) { + goto err_allocPartition; + } + i++; + } + } + msgTo->content._u.bead.partitions = (c_sequence)dst0; + } + msgTo->content._u.bead.kind = historicalData->content._u.bead.kind; + memcpy(msgTo->content._u.bead.keyHash, historicalData->content._u.bead.keyHash, 16); + msgTo->content._u.bead.serializationFormat = historicalData->content._u.bead.serializationFormat; + { + c_type subtype0; + c_ulong len; + c_octet *dst0; + + len = historicalData->beadSize; + subtype0 = c_type(c_metaResolve (c_metaObject(base), "c_octet")); + dst0 = (c_octet *)c_sequenceNew_s(subtype0, len, len); + c_free(subtype0); + if (!dst0) { + OS_REPORT (OS_ERROR, "copyIn", 0,"Member 'HistoricalData.content._u.bead.payload' could not be allocated."); + goto err_allocPayload; + } + memcpy(dst0, historicalData->blob, len); + msgTo->content._u.bead.payload=(c_sequence)dst0; + } + break; + case HISTORICAL_DATA_KIND_LINK: + msgTo->content._u.link.sampleCount = historicalData->content._u.link.sampleCount; + msgTo->content._u.link.completeness = historicalData->content._u.link.completeness; + msgTo->content._u.link.errorCode = historicalData->content._u.link.errorCode; + break; + default: + OS_REPORT (OS_ERROR, "copyIn", 0,"Member 'HistoricalData.content._d' is invalid"); + goto err_invalidUnionSelector; + break; + } + /* Copy the extensions */ + { + c_ulong len = c_iterLength(historicalData->extensions); + c_type subtype0; + struct _DDS_NameValue_t *dst0; + + subtype0 = c_type(c_metaResolve (c_metaObject(base), "DDS::NameValue_t")); + dst0 = (struct _DDS_NameValue_t *)c_sequenceNew_s(subtype0, len, len); + c_free(subtype0); + if (!dst0) { + OS_REPORT (OS_ERROR, "copyIn", 0, "Member 'HistoricalData.extensions' could not be allocated."); + goto err_allocExtensionsSeq; + } + { + c_iterIter iter = c_iterIterGet(historicalData->extensions); + struct _DDS_NameValue_t *extension; + c_ulong i = 0; + + while ((extension = c_iterNext(&iter)) != NULL) { + dst0[i].name = extension->name; + dst0[i].value = extension->value; + i++; + } + } + msgTo->extensions = (c_sequence)dst0; + } + return V_COPYIN_RESULT_OK; + + +err_allocExtensionsSeq: +err_invalidUnionSelector: +err_allocPayload: +err_allocPartition: + { + c_iterIter iter = c_iterIterGet(historicalData->partitions); + char * partition; + + while ((partition = (char *)c_iterNext(&iter)) != NULL) { + c_free(partition); + } + } +err_allocPartitions: +err_allocRequestIds: + + return V_COPYIN_RESULT_OUT_OF_MEMORY; +} + + + +/** + * \brief Write a HistoricalData message + */ +c_bool +d_historicalDataWrite( + c_voidp *arg) +{ + d_durability durability; + c_bool result = FALSE; + u_result ur; + int resendCount; + c_bool terminate; + d_serviceState state; + d_historicalData historicalData = d_historicalData(arg); + d_thread self = d_threadLookupSelf (); + + durability = historicalData->durability; + state = d_durabilityGetState(durability); + if ((state != D_STATE_TERMINATING) && (state != D_STATE_TERMINATED)) { + /* The service is not about to terminate, so it is OK to + * publish historicalData messages. */ + if (historicalData->content._d == HISTORICAL_DATA_KIND_BEAD) { + d_printTimedEvent(historicalData->durability, D_LEVEL_FINEST, "TRACE %s: write bead msg %p\n", OS_FUNCTION, (void *)historicalData->vmessage); + } else { + d_printTimedEvent(historicalData->durability, D_LEVEL_FINEST, "TRACE %s: write link\n", OS_FUNCTION); + } + terminate = FALSE; + resendCount = 0; + while ((!result) && (!terminate)) { + d_threadAwake(self); + ur = u_writerWrite(historicalData->pubinfo->writer, + d_publisherHistoricalDataWriterCopy, + historicalData, os_timeWGet(), U_INSTANCEHANDLE_NIL); + if (ur == U_RESULT_OK) { + result = TRUE; + } else if (ur == U_RESULT_TIMEOUT) { + terminate = d_durabilityMustTerminate(durability); + resendCount++; + if (terminate) { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Failed to send historicalData message because durability is terminating.\n"); + } else if (resendCount == 1) { + /* Only a single log line in case of resends to prevent log pollution */ + d_printTimedEvent(durability, D_LEVEL_WARNING, + "Failed to publish historicalData message with result %s, try to resend.\n", u_resultImage(ur)); + OS_REPORT(OS_WARNING, D_CONTEXT_DURABILITY, 0, + "Failed to publish historicalData message with result %s, try to resend.", u_resultImage(ur)); + } + } else { + d_printTimedEvent(durability, D_LEVEL_SEVERE, + "Publication of historicalData message FAILED with result %s, I am going to terminate\n", u_resultImage(ur)); + OS_REPORT(OS_ERROR, D_CONTEXT_DURABILITY, 0, + "Publication of historicalData message FAILED with result %s, I am going to terminate", u_resultImage(ur)); + d_durabilityTerminate(durability, TRUE); + terminate = d_durabilityMustTerminate(durability); + } + } /* while */ + if ((result) && (resendCount > 0) && (!terminate)) { + d_printTimedEvent(durability, D_LEVEL_SEVERE, + "Publication of historicalData message succeeded after %d resends\n", resendCount); + } + } + return result; +} + + +static struct _DDS_DurabilityVersion_t +respond_with_version( + d_durability durability, + struct _DDS_DurabilityVersion_t version) +{ + struct _DDS_DurabilityVersion_t v; + assert(d_durabilityIsValid(durability)); + + v = d_durabilityGetMyVersion(durability); + if ((version.major < v.major) || ((version.major == v.major) && (version.minor < v.minor))) { + v = version; + } + return v; +} + + +d_historicalData +d_historicalDataNew( + d_admin admin, + d_historicalDataRequest historicalDataRequest) +{ + d_historicalData historicalData; + d_durability durability; + + assert(d_adminIsValid(admin)); + + durability = d_adminGetDurability(admin); + + /* Allocate historical data request */ + historicalData = d_historicalData(os_malloc(C_SIZEOF(d_historicalData))); + memset(historicalData, 0, sizeof(C_STRUCT(d_historicalData))); + /* Call super-init */ + d_objectInit(d_object(historicalData), D_HISTORICAL_DATA, (d_objectDeinitFunc)d_historicalDataDeinit); + /* Initialize historicalData */ + historicalData->durability = durability; + historicalData->historicalDataRequest = historicalDataRequest; + /* If the client uses a lower version than the server, + * then the server must advertise the client's version + * in the response to make sure that the client's + * understands the message. */ + historicalData->version = respond_with_version(durability, historicalDataRequest->version); + historicalData->serverId = d_durabilityGetMyServerId(durability); + historicalData->errorCode = historicalDataRequest->errorCode; + historicalData->requestIds = c_iterCopy(historicalDataRequest->requestIds); + historicalData->partitions = c_iterNew(NULL); + /* The historicalDataRequest already contains the list of matching + * alignmentPartitions. According to the spec we must take the first + * matching one */ + if (c_iterLength(historicalDataRequest->alignmentPartition) == 0) { + historicalData->alignmentPartition = os_strdup(""); /* use default partition */ + } else { + historicalData->alignmentPartition = os_strdup((char *)c_iterObject(historicalDataRequest->alignmentPartition, 0)); + } + historicalData->extensions = c_iterNew(NULL); + /* Set the attributes for the historicalDataState */ + historicalData->errorCode = historicalDataRequest->errorCode; + historicalData->group = NULL; + historicalData->count = 0; + historicalData->writeCount = 0; + historicalData->disposeCount = 0; + historicalData->writeDisposeCount = 0; + historicalData->registerCount = 0; + historicalData->unregisterCount = 0; + historicalData->skipCount = 0; + historicalData->beadSize = 0; + historicalData->totalSize = 0; + /* Initial completeness */ + historicalData->completeness = D_DDS_COMPLETENESS_COMPLETE; + /* Create a writer/publisher */ + get_or_create_pubinfo(historicalData); + return historicalData; +} + + +void +d_historicalDataDeinit( + d_historicalData historicalData) +{ + + d_admin admin; + d_subscriber subscriber; + d_historicalDataRequestListener listener; + + assert(d_historicalDataIsValid(historicalData)); + + /* DDSI will drop data for writers that it doesn't know. + * In case the publisher and writer and destroyed before + * DDSI is able to send the data, DDSI will drop the data. + * To prevent this from happening we will put the publisher + * and writer on a death row. This gives DDSI some time to + * send the data before the publisher and writer are destroyed. */ + admin = historicalData->durability->admin; + subscriber = d_adminGetSubscriber(admin); + listener = d_subscriberGetHistoricalDataRequestListener(subscriber); + /* cache the publisher and writer on the deathrow */ + insert_pubinfo(listener, historicalData->pubinfo); + + if (historicalData->requestIds) { + /* RequestIds is an iter that was created using c_iterCopy. + * Because c_iterCopy does not copy the contents we do not + * have to free the contents. */ + c_iterFree(historicalData->requestIds); + historicalData->requestIds = NULL; + } + if (historicalData->alignmentPartition) { + os_free(historicalData->alignmentPartition); + historicalData->alignmentPartition = NULL; + } + if (historicalData->extensions) { + c_iterFree(historicalData->extensions); + historicalData->extensions = NULL; + } + if (historicalData->partitions) { + c_iterFree(historicalData->partitions); + historicalData->partitions = NULL; + } + /* Call super deinit */ + d_objectDeinit(d_object(historicalData)); +} + + +void +d_historicalDataFree( + d_historicalData historicalData) +{ + assert(d_historicalDataIsValid(historicalData)); + + d_objectFree(d_object(historicalData)); +} diff --git a/src/services/durability/code/d_historicalDataRequest.c b/src/services/durability/code/d_historicalDataRequest.c new file mode 100644 index 000000000..18168ccec --- /dev/null +++ b/src/services/durability/code/d_historicalDataRequest.c @@ -0,0 +1,363 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#include "d__readerRequest.h" +#include "d__historicalDataRequest.h" +#include "d__admin.h" +#include "d__thread.h" +#include "d__durability.h" +#include "d__misc.h" +#include "d__configuration.h" +#include "d__nameSpace.h" +#include "v_kernel.h" +#include "client_durabilitySplType.h" +#include "vortex_os.h" +#include "os_time.h" + + +static c_bool +vendor_is_prismtech_lite (struct _DDS_VendorId_t vendor) +{ + const struct _DDS_VendorId_t lite = D_VENDORID_PRISMTECH_LITE; + return ((vendor.vendorId[0] == lite.vendorId[0]) && (vendor.vendorId[1] == lite.vendorId[1])); +} + +static c_bool +is_Y2038READY(struct _DDS_DurabilityVersion_t version) { + /* Extended timestamps are supported for all versions 2.0 and above */ + if ((version.major < (c_ushort)2)) { + return FALSE; + } + return TRUE; +} + + +static os_timeW +ddsTimeToTimeW(struct _DDS_Time_t t, struct _DDS_DurabilityVersion_t version) +{ + os_timeW t2; + + if ((t.sec == (c_long)-1) && (t.nanosec == (c_ulong)4294967295U)) { + /* DDS_TIME_INVALID */ + t2 = OS_TIMEW_INVALID; + } else { + if (is_Y2038READY(version)) { + /* The sender of the historicalDataRequest used timestamps beyond 2038 */ + t2 = OS_TIMEW_INIT(0, (((os_uint64)(t.sec)) << 32) + (os_uint64)(t.nanosec)); + } else { + /* The timestamp was a legacy timestamp. + * Since the timestamp effectively contains a c_time, we convert + * the corresponding c_time to an os_timeW. */ + c_time ct; + + ct.seconds = t.sec; + ct.nanoseconds = t.nanosec; + t2 = c_timeToTimeW(ct); + } + } + return t2; +} + + +static void +historicalDataRequestCopyRequest( + d_historicalDataRequest historicalDataRequest, + const struct _DDS_HistoricalDataRequest *request) +{ + c_ulong i; + struct _DDS_RequestId_t *requestId; + os_timeE now = os_timeEGet(); + + assert(d_historicalDataRequestIsValid(historicalDataRequest)); + assert(request); + + historicalDataRequest->version = request->version; + requestId = (struct _DDS_RequestId_t *)os_malloc(sizeof(struct _DDS_RequestId_t)); + (*requestId) = request->requestId; + historicalDataRequest->requestIds = c_iterNew(requestId); + historicalDataRequest->topic = (request->topic == NULL) ? NULL : os_strdup(request->topic); + historicalDataRequest->partitions = c_iterNew(NULL); + for (i=0; ipartitions); i++) { + c_iterAppend(historicalDataRequest->partitions, os_strdup(request->partitions[i])); + } + historicalDataRequest->serializationFormat = request->serializationFormat; + historicalDataRequest->dataReaderQos = request->dataReaderQos; + /* Convert startTime and endTime */ + historicalDataRequest->startTime = ddsTimeToTimeW(request->startTime, request->version); + historicalDataRequest->endTime = ddsTimeToTimeW(request->endTime, request->version); + /* If an empty filter is received then do not use a filter */ + if ((request->sqlFilter == NULL) || (strcmp(request->sqlFilter, "")==0)) { + historicalDataRequest->sqlFilter = NULL; + } else { + historicalDataRequest->sqlFilter = os_strdup(request->sqlFilter); + } + /* Create list of pointers that refer to parameters of the sql expression. + * This is the required format for v_historicalDataRequestNew + * (see d_historicalDataRequestListener.c) */ + historicalDataRequest->sqlFilterParamsSize = c_sequenceSize(request->sqlFilterParams); + if (historicalDataRequest->sqlFilterParamsSize > 0) { + historicalDataRequest->sqlFilterParams = (char **)os_malloc(historicalDataRequest->sqlFilterParamsSize * sizeof(*historicalDataRequest->sqlFilterParams)); + for (i=0; isqlFilterParamsSize; i++) { + historicalDataRequest->sqlFilterParams[i] = os_strdup(request->sqlFilterParams[i]); + } + } else { + historicalDataRequest->sqlFilterParams = NULL; + } + historicalDataRequest->maxSamples = request->maxSamples; + historicalDataRequest->maxInstances = request->maxInstances; + historicalDataRequest->maxSamplesPerInstance = request->maxSamplesPerInstance; + historicalDataRequest->alignmentPartition = c_iterNew(NULL); + for (i=0; ialignmentPartition); i++) { + c_iterAppend(historicalDataRequest->alignmentPartition, os_strdup(request->alignmentPartition[i])); + } + historicalDataRequest->serverIds = c_iterNew(NULL); + for (i=0; iserverIds); i++) { + struct _DDS_Gid_t *serverIds = (struct _DDS_Gid_t *)request->serverIds; + struct _DDS_Gid_t *serverId = (struct _DDS_Gid_t *)os_malloc(sizeof(struct _DDS_Gid_t)); + *serverId = serverIds[i]; + c_iterAppend(historicalDataRequest->serverIds, serverId); + } + historicalDataRequest->receptionTime = now; + /* Convert DDS_Duration to os_duration */ + historicalDataRequest->timeout = OS_DURATION_INIT(request->timeout.sec, request->timeout.nanosec); + historicalDataRequest->extensions = c_iterNew(NULL); + for (i=0; iextensions); i++) { + c_ulong size; + struct _DDS_NameValue_t *extensions = (struct _DDS_NameValue_t *)request->extensions; + struct _DDS_NameValue_t *extension = (struct _DDS_NameValue_t *)os_malloc(sizeof(struct _DDS_NameValue_t)); + /* skip extensions that do not have a name or value */ + extension->name = (extensions[i].name == NULL) ? NULL : os_strdup(extensions[i].name); + if (extension->name != NULL) { + size = c_sequenceSize(extensions[i].value); + extension->value = (size == 0) ? NULL : os_malloc(size * sizeof(c_octet)); + if (extension->value) { + memcpy(extension->value, extensions[i].value, size); + c_iterAppend(historicalDataRequest->extensions, extension); + } else { + os_free(extension->name); + } + } + } + return; +} + + +d_historicalDataRequest +d_historicalDataRequestNew( + d_admin admin, + struct _DDS_HistoricalDataRequest *request) +{ + d_historicalDataRequest historicalDataRequest; + d_durability durability; + + assert(request); + + durability = d_adminGetDurability(admin); + OS_UNUSED_ARG(durability); + /* Allocate historical data request */ + historicalDataRequest = d_historicalDataRequest(os_malloc(C_SIZEOF(d_historicalDataRequest))); + memset(historicalDataRequest, 0, (os_uint32)sizeof(C_STRUCT(d_historicalDataRequest))); + /* Call super-init */ + d_objectInit(d_object(historicalDataRequest), D_HISTORICAL_DATA_REQ, + (d_objectDeinitFunc)d_historicalDataRequestDeinit); + /* Initialize historicalDataRequest */ + + historicalDataRequestCopyRequest(historicalDataRequest, request); + /* Determine if the request is meant for me */ + (void)d_durabilityRequestIsForMe(durability, historicalDataRequest->serverIds, + &historicalDataRequest->forMe, &historicalDataRequest->forEverybody); + /* Response control settings */ + historicalDataRequest->include_payload_unregistrations = (c_bool) (vendor_is_prismtech_lite(request->version.vendorId) ? FALSE : TRUE); + return historicalDataRequest; +} + + +void +d_historicalDataRequestDeinit( + d_historicalDataRequest historicalDataRequest) + { + char *str; + struct _DDS_Gid_t *serverId; + struct _DDS_NameValue_t *extension; + c_ulong i; + + + assert(d_historicalDataRequestIsValid(historicalDataRequest)); + + if (historicalDataRequest->topic) { + os_free(historicalDataRequest->topic); + } + if (historicalDataRequest->partitions) { + while ((str = (char *)c_iterTakeFirst(historicalDataRequest->partitions)) != NULL) { + os_free(str); + } + c_iterFree(historicalDataRequest->partitions); + } + if (historicalDataRequest->sqlFilter) { + os_free(historicalDataRequest->sqlFilter); + } + if (historicalDataRequest->sqlFilterParams) { + for (i=0; isqlFilterParamsSize; i++) { + os_free(historicalDataRequest->sqlFilterParams[i]); + } + os_free(historicalDataRequest->sqlFilterParams); + } + if (historicalDataRequest->alignmentPartition) { + while ((str = (char *)c_iterTakeFirst(historicalDataRequest->alignmentPartition)) != NULL) { + os_free(str); + } + c_iterFree(historicalDataRequest->alignmentPartition); + } + if (historicalDataRequest->serverIds) { + while ((serverId = (struct _DDS_Gid_t *)c_iterTakeFirst(historicalDataRequest->serverIds)) != NULL) { + os_free(serverId); + } + c_iterFree(historicalDataRequest->serverIds); + } + if (historicalDataRequest->extensions) { + while ((extension = (struct _DDS_NameValue_t *)c_iterTakeFirst(historicalDataRequest->extensions)) != NULL) { + os_free(extension->name); + os_free(extension->value); + os_free(extension); + } + c_iterFree(historicalDataRequest->extensions); + } + /* call super-deinit */ + d_objectDeinit(d_object(historicalDataRequest)); +} + + +void +d_historicalDataRequestFree( + d_historicalDataRequest historicalDataRequest) +{ + assert(d_historicalDataRequestIsValid(historicalDataRequest)); + + d_objectFree(d_object(historicalDataRequest)); +} + + +static c_bool +time_is_sane(os_timeW t, c_bool isY2038Ready) +{ + c_bool is_sane; + + if (isY2038Ready) { + /* The startTime is a 64-bit time (os_timeW). + * A valid time must be normalized */ + is_sane = (OS_TIMEW_ISINVALID(t) || OS_TIMEW_ISNORMALIZED(t)); + } else { + /* The startTime is a legacy time (c_time). + * Either the time must be C_TIME_INVALID or it must be a valid time */ + c_time ct = c_timeFromTimeW(t); + is_sane = (c_timeIsInvalid(ct) || c_timeValid(ct)); + } + return is_sane; +} + + +/** + * + * + * \brief Check if the historicalDataRequest contains errors. + * + * If errors are encountered, the error code and error string are returned. + * Only one error message will be returned. + * + * @return 0, if no errors are detected + * @return errno, if an error is detected + */ +c_ulong +d_historicalDataRequestSanityCheck( + d_historicalDataRequest historicalDataRequest) +{ + assert(d_historicalDataRequestIsValid(historicalDataRequest)); + + /* perform sanity checks */ + if (historicalDataRequest->topic == NULL) { + /* topic is NULL */ + return 2; + } else if (!time_is_sane(historicalDataRequest->startTime, is_Y2038READY(historicalDataRequest->version))) { + /* not a valid startTime */ + return 3; + } else if (!time_is_sane(historicalDataRequest->endTime, is_Y2038READY(historicalDataRequest->version))) { + /* not a valid endTime */ + return 4; + } else if ( (!OS_TIMEW_ISINVALID(historicalDataRequest->startTime)) && + (!OS_TIMEW_ISINVALID(historicalDataRequest->endTime)) && + (os_timeWCompare(historicalDataRequest->startTime, historicalDataRequest->endTime) == OS_MORE) ) { + /* starttime > endTime */ + return 5; + } else if ( (historicalDataRequest->serializationFormat > PAYLOAD_SERIALIZATION_FORMAT_CDR_LE) ) { + /* invalid serializationFormat */ + return 6; + } else if ( c_iterLength(historicalDataRequest->partitions) == 0 ) { + /* no partitions */ + return 7; + } else if ( (historicalDataRequest->maxSamples != V_LENGTH_UNLIMITED) && (historicalDataRequest->maxSamples <= 0) ) { + /* invalid maxSamples */ + return 8; + } else if ( (historicalDataRequest->maxInstances != V_LENGTH_UNLIMITED) && (historicalDataRequest->maxInstances <= 0) ) { + /* invalid maxInstances */ + return 9; + } else if ( (historicalDataRequest->maxSamplesPerInstance != V_LENGTH_UNLIMITED) && (historicalDataRequest->maxSamplesPerInstance <= 0) ) { + /* invalid maxSamplesPerInstance */ + return 10; + } else if ( (OS_DURATION_ISINVALID(historicalDataRequest->timeout)) || + (os_durationCompare(historicalDataRequest->timeout, OS_DURATION_ZERO) == OS_LESS) ) { + /* invalid timeout */ + return 11; + } + /* No sanity error */ + return 0; +} + + + +int +d_historicalDataRequestCompareByRequestId( + d_historicalDataRequest historicalDataRequest1, + d_historicalDataRequest historicalDataRequest2) +{ + struct _DDS_RequestId_t *request1, *request2; + + assert(d_historicalDataRequestIsValid(historicalDataRequest1)); + assert(d_historicalDataRequestIsValid(historicalDataRequest2)); + + /* NOTE : for the moment assume there is only a single requestId */ + + assert(c_iterLength(historicalDataRequest1->requestIds) == 1); + assert(c_iterLength(historicalDataRequest2->requestIds) == 1); + + request1 = (struct _DDS_RequestId_t *)c_iterObject(historicalDataRequest1->requestIds, 0); + request2 = (struct _DDS_RequestId_t *)c_iterObject(historicalDataRequest2->requestIds, 0); + if (request1->clientId.prefix < request2->clientId.prefix) { + return -1; + } else if (request1->clientId.prefix > request2->clientId.prefix) { + return 1; + } else if (request1->clientId.suffix < request2->clientId.suffix) { + return -1; + } else if (request1->clientId.suffix > request2->clientId.suffix) { + return 1; + } else if (request1->requestId < request2->requestId) { + return -1; + } else if (request1->requestId < request2->requestId) { + return 1; + } + return 0; +} + diff --git a/src/services/durability/code/d_historicalDataRequestListener.c b/src/services/durability/code/d_historicalDataRequestListener.c new file mode 100644 index 000000000..8dd3b0e0b --- /dev/null +++ b/src/services/durability/code/d_historicalDataRequestListener.c @@ -0,0 +1,1639 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#include "vortex_os.h" +#include "d__historicalDataRequestListener.h" +#include "d__historicalDataRequest.h" +#include "d__historicalData.h" +#include "d__configuration.h" +#include "d__admin.h" +#include "d__durability.h" +#include "d__actionQueue.h" +#include "d__readerListener.h" +#include "d__misc.h" +#include "d__thread.h" +#include "d__waitset.h" +#include "d__group.h" +#include "d__publisher.h" +#include "d__nameSpace.h" +#include "d__eventListener.h" +#include "d_qos.h" +#include "u_listener.h" +#include "v_message.h" +#include "v_dataReaderSample.h" +#include "v_observer.h" +#include /* for definition of offsetof */ + +#include "ut_md5.h" +#include "v_group.h" +#include "v_builtin.h" +#include "v_time.h" +#include "v_state.h" +#include "v_historicalDataRequest.h" +#include "v_groupInstance.h" +#include "v_entity.h" +#include "v_message.h" +#include "v_dataReaderInstance.h" +#include "v_topic.h" +#include "v_messageQos.h" +#include "sd_serializer.h" +#include "sd_serializerBigE.h" +#include "sd_cdr.h" +#include "os_heap.h" +#include "os_report.h" +#include "os_abstract.h" +#include "os_time.h" +#include "c_misc.h" + +#include "client_durabilitySplType.h" + +/** + * Macro that checks the d_historicalDataRequestListener validity. + * Because d_historicalDataRequestListener is a concrete class typechecking is required. + */ +#define d_historicalDataRequestListenerIsValid(_this) \ + d_listenerIsValidKind(d_listener(_this), D_HISTORICAL_DATA_REQ_LISTENER) + +/** + * \brief The d_historicalDataRequestListener cast macro. + * + * This macro casts an object to a d_historicalDataRequestListener object. + */ +#define d_historicalDataRequestListener(_this) ((d_historicalDataRequestListener)(_this)) + +static int compare_by_prio (const void *va, const void *vb); + +/* Callback function signatures */ +c_bool answer_request(void *listener, void *arg); +static void cleanup_request (void *n); +static void cleanup_pubinfo (void *n); + +const ut_fibheapDef_t prioqueue_fhdef = UT_FIBHEAPDEF_INITIALIZER(offsetof (struct request_admin_node, fhnode), compare_by_prio); + +static int +compare_request_by_requestId (const void *va, const void *vb) +{ + const d_historicalDataRequest a = d_historicalDataRequest(va); + const d_historicalDataRequest b = d_historicalDataRequest(vb); + + /* Compare requests based on their requestId. + * A precondition is that a historicalDataRequest may only contain a single requestId. + * Combined requests containing multiple requestIds should NOT be compared! + */ + assert(c_iterLength(a->requestIds)==1); + assert(c_iterLength(b->requestIds)==1); + + return d_historicalDataRequestCompareByRequestId(a, b); +} + + +static int +compare_pubinfo_by_partition (const void *va, const void *vb) +{ + const struct pubInfo *a = (struct pubInfo *)va; + const struct pubInfo *b = (struct pubInfo *)vb; + + /* Compare pubInfo based on their partition. */ + + assert(a); + assert(b); + assert(a->partition); + assert(b->partition); + + return strcmp(a->partition, b->partition); +} + + +static int +compare_by_prio (const void *va, const void *vb) +{ + const struct request_admin_node *a = (struct request_admin_node *)va; + const struct request_admin_node *b = (struct request_admin_node *)vb; + + os_compare eq; + eq = os_timeECompare(a->expiration_time, b->expiration_time); + if (eq == OS_LESS) { + return -1; + } else if (eq == OS_MORE) { + return 1; + } else { + return 0; + } +} + + +static os_timeE +time_of_next_request_unlocked (d_historicalDataRequestListener listener) +{ + struct request_admin_node *n; + os_timeE t; + if ((n = ut_fibheapMin (&prioqueue_fhdef, &listener->prioqueue)) != NULL) { + t = n->expiration_time; + } else { + t = OS_TIMEE_INFINITE; + } + return t; +} + +d_historicalDataRequest +reschedule_request (d_historicalDataRequestListener listener, d_historicalDataRequest historicalDataRequest, os_duration d) +{ + ut_avlIPath_t ip; + struct request_admin_node *n; + + assert(d_historicalDataRequestListenerIsValid(listener)); + assert(d_historicalDataRequestIsValid(historicalDataRequest)); + + os_mutexLock (&listener->queue_lock); + if ((n = ut_avlLookupIPath (&listener->request_avltreedef, &listener->request_id_tree, historicalDataRequest, &ip)) != NULL) { + /* An old request (according to compare_request_by_requestId) already exists. + * Update the expiration time of the old request and return the old request + */ + d_historicalDataRequest oldreq = d_historicalDataRequest(n->arg); + oldreq->expirationTime = os_timeEAdd(oldreq->expirationTime, d); + d_trace(D_TRACE_PRIO_QUEUE, "%s: existing avlnode %p found, insert_time=%"PA_PRItime", expiration_time = %"PA_PRItime"\n", + OS_FUNCTION, (void *)n, OS_TIMEE_PRINT(n->insert_time), OS_TIMEE_PRINT(n->expiration_time)); + os_mutexUnlock (&listener->queue_lock); + return oldreq; + } else { + /* Insert the node in the tree and in the priority queue */ + n = os_malloc (sizeof (*n)); + n->insert_time = os_timeEGet(); + n->expiration_time = os_timeEAdd(historicalDataRequest->expirationTime, d); + n->handle_time = OS_TIMEE_ZERO; + n->callback = answer_request; /* callback function */ + n->arg = historicalDataRequest; /* argument of the callback function */ + d_trace(D_TRACE_PRIO_QUEUE, "%s: avlnode %p rescheduled insert_time=%"PA_PRItime", expiration_time = %"PA_PRItime"\n", + OS_FUNCTION, (void *)n, OS_TIMEE_PRINT(n->insert_time), OS_TIMEE_PRINT(n->expiration_time)); + ut_avlInsertIPath (&listener->request_avltreedef, &listener->request_id_tree, n, &ip); + ut_fibheapInsert (&prioqueue_fhdef, &listener->prioqueue, n); + /* Signal if the element was added to the front of the priority queue */ + if (n == ut_fibheapMin (&prioqueue_fhdef, &listener->prioqueue)) { + d_trace(D_TRACE_PRIO_QUEUE, "%s: avlnode %p rescheduled to front of queue\n", OS_FUNCTION, (void *)n, (void *)historicalDataRequest); + os_condSignal (&listener->cond); + } + os_mutexUnlock (&listener->queue_lock); + return NULL; + } +} + +/** + * Inserts a historicalDatataRequest in the priority queue + */ +d_historicalDataRequest +insert_request (d_historicalDataRequestListener listener, d_historicalDataRequest historicalDataRequest) +{ + ut_avlIPath_t ip; + struct request_admin_node *n; + + assert(d_historicalDataRequestListenerIsValid(listener)); + assert(d_historicalDataRequestIsValid(historicalDataRequest)); + + os_mutexLock (&listener->queue_lock); + if ((n = ut_avlLookupIPath (&listener->request_avltreedef, &listener->request_id_tree, historicalDataRequest, &ip)) != NULL) { + /* An old request (according to compare_request_by_requestId) already exists. + * Ignore the new request and return the old request + */ + d_historicalDataRequest oldreq = d_historicalDataRequest(n->arg); + d_trace(D_TRACE_PRIO_QUEUE, "%s: existing avlnode %p found, insert_time=%"PA_PRItime", expiration_time = %"PA_PRItime"\n", + OS_FUNCTION, (void *)n, OS_TIMEE_PRINT(n->insert_time), OS_TIMEE_PRINT(n->expiration_time)); + d_historicalDataRequestFree(historicalDataRequest); + os_mutexUnlock (&listener->queue_lock); + return oldreq; + } else { + /* Insert the node in the tree and in the priority queue */ + n = os_malloc (sizeof (*n)); + n->insert_time = os_timeEGet(); + n->expiration_time = historicalDataRequest->expirationTime; + n->handle_time = OS_TIMEE_ZERO; + n->callback = answer_request; /* callback function */ + n->arg = historicalDataRequest; /* argument of the callback function */ + d_trace(D_TRACE_PRIO_QUEUE, "%s: avlnode %p created insert_time=%"PA_PRItime", expiration_time = %"PA_PRItime"\n", + OS_FUNCTION, (void *)n, OS_TIMEE_PRINT(n->insert_time), OS_TIMEE_PRINT(n->expiration_time)); + ut_avlInsertIPath (&listener->request_avltreedef, &listener->request_id_tree, n, &ip); + ut_fibheapInsert (&prioqueue_fhdef, &listener->prioqueue, n); + /* Signal if the element was added to the front of the priority queue */ + if (n == ut_fibheapMin (&prioqueue_fhdef, &listener->prioqueue)) { + d_trace(D_TRACE_PRIO_QUEUE, "%s: avlnode %p added to front of queue\n", OS_FUNCTION, (void *)n, (void *)historicalDataRequest); + os_condSignal (&listener->cond); + } + os_mutexUnlock (&listener->queue_lock); + return NULL; + } +} + +/** + * Take the next node from the priority queue. + * + * It is assumed that the caller locks the request queue. + */ +static struct request_admin_node * +take_next_request_unlocked ( + d_historicalDataRequestListener listener) +{ + struct request_admin_node *n; + + assert(d_historicalDataRequestListenerIsValid(listener)); + + if ((n = ut_fibheapExtractMin (&prioqueue_fhdef, &listener->prioqueue)) != NULL) { + /* To determine from which tree to delete the node we use the callback */ + if (n->callback == answer_request) { + ut_avlDelete (&listener->request_avltreedef, &listener->request_id_tree, n); + } else if (n->callback == delete_pubinfo) { + ut_avlDelete (&listener->pubinfo_avltreedef, &listener->pubinfo_tree, n); + } else { + abort(); + } + d_trace(D_TRACE_PRIO_QUEUE, "%s: avlnode %p extracted from queue\n", OS_FUNCTION, (void *)n); + return n; + } else { + d_trace(D_TRACE_PRIO_QUEUE, "%s: queue is empty\n", OS_FUNCTION, (void *)n); + return NULL; + } +} + +/** + * \brief Indicates if the specified type is a primitive type. + * + * For primitive types it returns the size of the type + * in number of bytes. + * + * If the type is not a keyType then 0 is returned. + */ +static int isKeyType (c_type type) +{ + switch (c_baseObjectKind (type)) + { + case M_PRIMITIVE: + switch (c_primitiveKind ((c_object) type)) { + case P_BOOLEAN: + case P_CHAR: + case P_OCTET: + case P_SHORT: + case P_USHORT: + case P_LONG: + case P_ULONG: + case P_LONGLONG: + case P_ULONGLONG: + case P_FLOAT: + case P_DOUBLE: + return 1; + default: + return 0; + } + /* NOTREACHED */ + case M_ENUMERATION: + return 1; + case M_COLLECTION: + switch (c_collectionTypeKind ((c_object) type)) + { + case OSPL_C_STRING: + return 1; + default: + return 0; + } + /* NOTREACHED */ + default: + return 0; + } +} + + +/** + * \brief Calculate the keyHash associated with a vgroup + * + * The keyHash is a CDR-BE encoded hash of the message keys. The + * keyHash is calculated conform section 9.6.3.3 of the DDSI spec + * (v2.2). + * + * Keys are hashed in the order in which they appear in the + * messageKeyList of the topic. + * + * NOTE: + * The current implementations is a first attempt. + * Initially, 16 bytes are allocated for the keys. If keys do not + * fit in these 16-bytes a realloc is performed every time a key + * is added. From a performance point of view it may be better + * to initially allocate a larger memory for key storage in order + * to prevent successive calls to realloc. + */ +static void +calculate_key_hash( + v_group vgroup, + v_message vmessage, + c_octet keyHash[16]) +{ + c_array messageKeyList; + c_ulong i, nrOfKeys; + c_type keyTypes[32]; + c_value keyValues[32]; + size_t size; + c_ulong maxSize; + c_bool fit = TRUE; + char *keys; /* temporary key storage */ + size_t offset = 0; + size_t length = 16; + ut_md5_state_t md5st; + + keys = (char *)os_malloc(16); + memset(keys,0x00,16); + messageKeyList = v_topicMessageKeyList(v_groupTopic(vgroup)); + nrOfKeys = c_arraySize(messageKeyList); + for (i=0; isize; + if (offset + size > length) { + /* There is not enough room in the keys list. + * Extend the keys list so that the new value fits */ + length = offset + size; + keys = os_realloc(keys, length); + } + /* The spec requires the keys to be in BE, so + * make sure to swap when possible */ + switch (size) { + case 2: + { + unsigned short x = d_swap2uToBE(*((const unsigned short *) &keyValues[i].is)); + memcpy(keys+offset, &x, sizeof(x)); + break; + } + case 4: + { + unsigned x = d_swap4uToBE(*((const unsigned *) &keyValues[i].is)); + memcpy(keys+offset, &x, sizeof(x)); + break; + } + case 8: + { + unsigned long long x = d_swap8uToBE(*((const unsigned long long *) &keyValues[i].is)); + memcpy(keys+offset, &x, sizeof(x)); + break; + } + default: + /* Size must be 1 byte, no need to swap */ + assert(size==1); + memcpy(keys+offset, &keyValues[i].is, size); + } + /* Update the offset */ + offset = offset + size; + break; + case M_COLLECTION: + /* We now need to calculate the size of the collection. + * The only supported collection type is C_STRING. + * This is usually a 4-byte pointer reference, followed + * by the string itself + */ + maxSize = c_collectionTypeMaxSize(keyTypes[i]); + if (maxSize == 0) { + /* This is an unbounded string, it will not fit by definition */ + fit = FALSE; + } + /* Store the number of elements and their references */ + size = strlen(keyValues[i].is.String) + 1; /* including the '\0' */ + if ((offset + 4 + size) > length) { + /* There is not enough room in the keys list. + * Extend the keys list so that the new value fits + */ + length = offset + 4 + (maxSize == 0 ? size : maxSize); + keys = os_realloc(keys, length); + /* Add padding */ + memset(keys+offset, 0x00, length-offset); + } + /* Copy the string length (in BE) and the string */ + { + unsigned x = d_swap4uToBE(*((const unsigned *)&size)); + memcpy(keys+offset, &x, sizeof(x)); + } + memcpy(keys+offset+4, keyValues[i].is.String, size); + offset = offset + 4 + size; + break; + default: + /* This should never be possible */ + assert(FALSE); + } + } + } /* for */ + if (fit && length <= 16) { + memcpy(keyHash,keys,16); + } else { + /* MD5 hash required */ + ut_md5_init(&md5st); + ut_md5_append(&md5st, (const unsigned char *) keys, (unsigned) length); + ut_md5_finish(&md5st, keyHash); + } + os_free(keys); + return; +} + + +/* When flushing the group, the kernel may return both v_messages and v_registrations. When + * a v_registration is flushed this can indicate a register or an unregister which is + * specified by the flushType. The flushed objects are stored in a temporary list which is + * eventually used to align the samples to other nodes. When the function interpreting this list + * encounters a v_registration it must be able to tell whether this was a register or an unregister. + * That information is stored by using this struct. + */ +typedef struct flushedDataObject { + c_object object; /* v_message or v_registration */ + v_groupFlushType flushType; /* MESSAGE, REGISTRATION or UNREGISTRATION */ +} flushedDataObject; + + + +static struct _DDS_Duration_t +os_duration_to_DDS_Duration_t( + os_duration d) +{ + struct _DDS_Duration_t d2; + c_time t; + + t = c_timeFromDuration(d); + d2.sec = t.seconds; + d2.nanosec = t.nanoseconds; + return d2; +} + + +/** + * \brief Publish a bead. + */ +static void +writeBead( + c_object object, /* vmessage to write */ + c_voidp userData) +{ + v_message vmessage; + d_historicalData historicalData = d_historicalData(userData); + struct sd_cdrSerdata *serializedData = NULL; + const void *blob; /* *blob will contain the address of the blob */ + d_historicalDataRequest historicalDataRequest = historicalData->historicalDataRequest; + + vmessage = (v_message)object; + historicalData->vmessage = vmessage; + d_trace(D_TRACE_CLIENT_DURABILITY, "%s: BEAD msg %p state=%u time=%"PA_PRItime" wrgid=%u:%u:%u\n", + OS_FUNCTION, (void *)vmessage, v_nodeState(vmessage), OS_TIMEW_PRINT(vmessage->writeTime), + vmessage->writerGID.systemId, vmessage->writerGID.localId, vmessage->writerGID.serial); + /* Serialize the userData associated with the vmessage. + * The serialization format depends on what the client has requested. + */ + if (v_stateTest(v_nodeState(vmessage), L_UNREGISTER) && (!historicalDataRequest->include_payload_unregistrations)) { + d_trace(D_TRACE_CLIENT_DURABILITY, "%s: BEAD msg %p beadsize set to 0\n", OS_FUNCTION, (void *)vmessage); + historicalData->beadSize = 0; + blob = NULL; + } else { + switch (historicalDataRequest->serializationFormat) { + case PAYLOAD_SERIALIZATION_FORMAT_CDR_ANY: + serializedData = sd_cdrSerialize(historicalData->cdrInfo, vmessage + 1); + break; + case PAYLOAD_SERIALIZATION_FORMAT_CDR_BE: + serializedData = sd_cdrSerializeBE(historicalData->cdrInfo, vmessage + 1); + break; + case PAYLOAD_SERIALIZATION_FORMAT_CDR_LE: + serializedData = sd_cdrSerializeLE(historicalData->cdrInfo, vmessage + 1); + break; + default: + /* This should never happen, because if the serializationFormat is + * invalid we will never reach writeBead + */ + assert(FALSE); + return; + } + historicalData->beadSize = sd_cdrSerdataBlob(&blob, serializedData); + } + /* Set the counters */ + historicalData->count++; + if ((v_stateTest(v_nodeState(vmessage), L_WRITE)) && + (v_stateTest(v_nodeState(vmessage), L_DISPOSED))) { + historicalData->writeDisposeCount++; + historicalData->messageKind = 3; /* MESSAGE_FLAG_WRITE_DISPOSE */ + } else if(v_stateTest(v_nodeState(vmessage), L_WRITE)) { + historicalData->writeCount++; + historicalData->messageKind = 0; /* MESSAGE_FLAG_WRITE */ + } else if(v_stateTest(v_nodeState(vmessage), L_DISPOSED)) { + historicalData->disposeCount++; + historicalData->messageKind = 1; /* MESSAGE_FLAG_DISPOSE */ + } else if(v_stateTest(v_nodeState(vmessage), L_REGISTER)) { + historicalData->registerCount++; + historicalData->messageKind = 4; /* MESSAGE_FLAG_REGISTER */ + } else if(v_stateTest(v_nodeState(vmessage), L_UNREGISTER)) { + historicalData->unregisterCount++; + historicalData->messageKind = 2; /* MESSAGE_FLAG_UNREGISTER */ + } + historicalData->totalSize += historicalData->beadSize; + /* Set the content */ + historicalData->content._d = HISTORICAL_DATA_KIND_BEAD; + historicalData->content._u.bead.sourceTimestamp.sec = (c_long)OS_TIMEW_GET_SECONDS(vmessage->writeTime); + historicalData->content._u.bead.sourceTimestamp.nanosec = (c_ulong)OS_TIMEW_GET_NANOSECONDS(vmessage->writeTime); + /* writerId */ + memset(historicalData->content._u.bead.writerId, 0x00, 16); + memcpy(historicalData->content._u.bead.writerId, &vmessage->writerGID, 12); + /* sequence number */ + historicalData->content._u.bead.sequenceNumber = vmessage->sequenceNumber; + /* Qos settings */ + historicalData->content._u.bead.qos.reliabilityKind = (enum _DDS_ReliabilityQosPolicyKind) v_messageQos_reliabilityKind(vmessage->qos); + historicalData->content._u.bead.qos.ownership.kind = (enum _DDS_OwnershipQosPolicyKind) v_messageQos_ownershipKind(vmessage->qos); + historicalData->content._u.bead.qos.destinationOrderKind = (enum _DDS_DestinationOrderQosPolicyKind) v_messageQos_orderbyKind(vmessage->qos); + historicalData->content._u.bead.qos.writerLifecycleAutoDisposeUnregisteredInstances = v_messageQos_isAutoDispose(vmessage->qos); + historicalData->content._u.bead.qos.durabilityKind = (enum _DDS_DurabilityQosPolicyKind) v_messageQos_durabilityKind(vmessage->qos); + historicalData->content._u.bead.qos.presentation.access_scope = (enum _DDS_PresentationQosPolicyAccessScopeKind) v_messageQos_presentationKind(vmessage->qos); + historicalData->content._u.bead.qos.presentation.coherent_access = v_messageQos_isCoherentAccess(vmessage->qos); + historicalData->content._u.bead.qos.presentation.ordered_access = v_messageQos_isOrderedAccess(vmessage->qos); + historicalData->content._u.bead.qos.liveliness.kind = (enum _DDS_LivelinessQosPolicyKind) v_messageQos_livelinessKind(vmessage->qos); + historicalData->content._u.bead.qos.latencyBudget.duration = os_duration_to_DDS_Duration_t(v_messageQos_getLatencyPeriod(vmessage->qos)); + historicalData->content._u.bead.qos.deadline.period = os_duration_to_DDS_Duration_t(v_messageQos_getDeadlinePeriod(vmessage->qos)); + historicalData->content._u.bead.qos.liveliness.lease_duration = os_duration_to_DDS_Duration_t(v_messageQos_getLivelinessPeriod(vmessage->qos)); + historicalData->content._u.bead.qos.lifespan.duration = os_duration_to_DDS_Duration_t(v_messageQos_getLifespanPeriod(vmessage->qos)); + historicalData->content._u.bead.qos.transportPriority.value = (c_long) v_messageQos_getTransportPriority(vmessage->qos); + /* kind */ + historicalData->content._u.bead.kind = historicalData->messageKind; + /* partitions; just use the partition of the group */ + historicalData->partitions = c_iterNew(historicalData->group->partition); + /* keyHash */ + calculate_key_hash(historicalData->vgroup, historicalData->vmessage, historicalData->content._u.bead.keyHash); + /* serializationFormat, same as in request except when request + * has PAYLOAD_SERIALIZATION_FORMAT_CDR_ANY. In that case use the + * natively supported serialization format. + */ + historicalData->content._u.bead.serializationFormat = historicalDataRequest->serializationFormat; + if (historicalData->content._u.bead.serializationFormat == PAYLOAD_SERIALIZATION_FORMAT_CDR_ANY) { + historicalData->content._u.bead.serializationFormat = (pa_getEndianNess() == pa_endianBig) ? PAYLOAD_SERIALIZATION_FORMAT_CDR_BE : PAYLOAD_SERIALIZATION_FORMAT_CDR_LE; + } + /* payload */ + if (historicalData->beadSize > 0) { + assert(blob != NULL); + historicalData->blob = os_malloc(historicalData->beadSize); + memcpy(historicalData->blob, blob, historicalData->beadSize); + } else { + historicalData->blob = NULL; + } + /* Publish the bead */ + d_historicalDataWrite((c_voidp)historicalData); + /* Cleanup resources */ + os_free(historicalData->blob); + historicalData->content._u.bead.payload = NULL; + if (serializedData) { + sd_cdrSerdataFree(serializedData); + } + return; +} + + +static void +writeLink( + c_voidp userData) +{ + d_historicalData historicalData = d_historicalData(userData); + + historicalData->content._d = HISTORICAL_DATA_KIND_LINK; + if (historicalData->errorCode == D_DDS_RETCDE_NO_ERROR) { + /* No error */ + historicalData->content._u.link.sampleCount = historicalData->count; + historicalData->content._u.link.completeness = historicalData->completeness; + } else { + /* Error */ + historicalData->content._u.link.sampleCount = 0; + historicalData->content._u.link.completeness = 0; + } + historicalData->content._u.link.errorCode = historicalData->errorCode; + /* Write the LINK */ + d_historicalDataWrite((c_voidp)historicalData); + d_printTimedEvent(historicalData->durability, D_LEVEL_FINE, + "WRITE: %d, DISPOSED: %d, WRITE_DISPOSED: %d, REGISTER: %d, UNREGISTER: %d (SKIPPED: %d) with completeness %d and errorCode %d\n", + historicalData->writeCount, historicalData->disposeCount, historicalData->writeDisposeCount, + historicalData->registerCount, historicalData->unregisterCount, historicalData->skipCount, + historicalData->content._u.link.completeness, + historicalData->content._u.link.errorCode); + return; +} + + +static c_bool +collectSamples( + c_object object, + v_groupInstance instance, + v_groupFlushType flushType, + c_voidp userData) +{ + d_historicalData historicalData = d_historicalData(userData); + d_historicalDataRequest historicalDataRequest = historicalData->historicalDataRequest; + v_message message; + v_registration registration; + c_bool process; + v_group vgroup; + vgroup = instance->group; + process = TRUE; + + switch (flushType) { + case V_GROUP_FLUSH_REGISTRATION: + registration = (v_registration)object; + if ( (!OS_TIMEW_ISINVALID(historicalDataRequest->endTime)) && + (os_timeWCompare(registration->writeTime, historicalDataRequest->endTime) == OS_MORE) ) { + /* Don't process if produced after the specified endTime */ + d_printTimedEvent(historicalData->durability, D_LEVEL_FINEST, + "V_GROUP_FLUSH_REGISTRATION writeTime (%"PA_PRItime") later than specified endTime (%"PA_PRItime"), discarding\n", + OS_TIMEW_PRINT(registration->writeTime), OS_TIMEW_PRINT(historicalDataRequest->endTime)); + process = FALSE; + } else if (strcmp(v_groupName(vgroup), "Group<__BUILT-IN PARTITION__,DCPSTopic>") == 0) { + /* Don't process registrations for DCPSTopic as this would introduce a scalability issue since + * there is always an alive writer per federation. If these registrations would be aligned there + * would be n registrations stored per builtin topic instance where n is the number of + * federations in a system. + * The only condition for aligning a registration is when there are multiple writers + * for the same instance. Therefore this is not an issue for other (builtin) topics. + */ + process = FALSE; + } else if ( (!OS_TIMEW_ISINVALID(historicalDataRequest->startTime)) && + (os_timeWCompare(registration->writeTime, historicalDataRequest->startTime) == OS_LESS) ) { + /* Don't process if produced before the specified startTime */ + d_printTimedEvent(historicalData->durability, D_LEVEL_FINEST, + "V_GROUP_FLUSH_REGISTRATION writeTime (%"PA_PRItime") prior to specified startTime (%"PA_PRItime"), discarding\n", + OS_TIMEW_PRINT(registration->writeTime), OS_TIMEW_PRINT(historicalDataRequest->startTime)); + process = FALSE; + } + break; + case V_GROUP_FLUSH_UNREGISTRATION: + registration = (v_registration)object; + if ( (!OS_TIMEW_ISINVALID(historicalDataRequest->endTime)) && + (os_timeWCompare(registration->writeTime, historicalDataRequest->endTime) == OS_MORE) ) { + /* Don't process if produced after the specified endTime */ + d_printTimedEvent(historicalData->durability, D_LEVEL_FINEST, + "V_GROUP_FLUSH_UNREGISTRATION writeTime (%"PA_PRItime") later than specified endTime (%"PA_PRItime"), discarding\n", + OS_TIMEW_PRINT(registration->writeTime), OS_TIMEW_PRINT(historicalDataRequest->endTime)); + process = FALSE; + } else if ( (!OS_TIMEW_ISINVALID(historicalDataRequest->startTime)) && + (os_timeWCompare(registration->writeTime, historicalDataRequest->startTime) == OS_LESS) ) { + /* Don't process if produced before the specified startTime */ + d_printTimedEvent(historicalData->durability, D_LEVEL_FINEST, + "V_GROUP_FLUSH_UNREGISTRATION writeTime (%"PA_PRItime") prior to specified startTime (%"PA_PRItime"), discarding\n", + OS_TIMEW_PRINT(registration->writeTime), OS_TIMEW_PRINT(historicalDataRequest->startTime)); + process = FALSE; + } + break; + case V_GROUP_FLUSH_MESSAGE: + message = (v_message)object; + if ( (!OS_TIMEW_ISINVALID(historicalDataRequest->endTime)) && + (os_timeWCompare(message->writeTime, historicalDataRequest->endTime) == OS_MORE) ) { + /* Don't process if writeTime exceeds specified endTime */ + d_printTimedEvent(historicalData->durability, D_LEVEL_FINEST, + "V_GROUP_FLUSH_MESSAGE writeTime (%"PA_PRItime") later than specified endTime (%"PA_PRItime"), discarding\n", + OS_TIMEW_PRINT(message->writeTime), OS_TIMEW_PRINT(historicalDataRequest->endTime)); + process = FALSE; + } else if ( (!OS_TIMEW_ISINVALID(historicalDataRequest->startTime)) && + (os_timeWCompare(message->writeTime, historicalDataRequest->startTime) == OS_LESS) ) { + /* Don't process if produced before the specified startTime */ + d_printTimedEvent(historicalData->durability, D_LEVEL_FINEST, + "V_GROUP_FLUSH_MESSAGE writeTime (%"PA_PRItime") prior to specified startTime (%"PA_PRItime"), discarding\n", + OS_TIMEW_PRINT(message->writeTime), OS_TIMEW_PRINT(historicalDataRequest->startTime)); + process = FALSE; + } + break; + default: + process = FALSE; + OS_REPORT(OS_ERROR, "durability::d_historicalDataRequestListener::collectSamples", 0, + "Internal error (received unknown message type)"); + break; + } + if (process == TRUE) { + /* Collect the sample data*/ + flushedDataObject *objectData = os_malloc(sizeof(struct flushedDataObject)); + objectData->object = c_keep(object); + objectData->flushType = flushType; + historicalData->list = c_iterAppend(historicalData->list, objectData); + historicalData->instances = c_iterAppend(historicalData->instances, c_keep(instance)); + } else { + /* No need to collect */ + historicalData->skipCount++; + } + return FALSE; +} + + +/** + * Set the completeness of the historicalData based on the completeness on the group. + * + * The historicalData->completeness represents the aggregated completeness of multiple groups. + * + * The aggregated completeness will be the weakest, .i.e, + * if one of the groups is D_DDS_COMPLETENESS_UNKNOWN then the aggregated group will be D_DDS_COMPLETENESS_UNKNOWN. + * if one of the groups is D_DDS_INCOMPLETENESS then the aggregated group will be D_DDS_INCOMPLETENESS + * if all groups are D_DDS_INCOMPLETE hen the aggregated group will be D_DDS_INCOMPLETE + */ +static void +setCompleteness( + d_historicalData historicalData, + _DDS_Completeness_t completeness) +{ + if (historicalData->completeness > completeness) { + historicalData->completeness = completeness; + } + return; +} + + + +/** + * Send a historicalData message for the specified group. + * + * The historicalData to sent is the response to the historicalDataRequest. + **/ +static c_bool +sendHistoricalData( + d_group group, + c_voidp userData) +{ + v_message vmessage; + v_registration registration; + v_groupInstance instance; + c_bool proceed; + + d_historicalData historicalData = d_historicalData(userData); + flushedDataObject *objectData; + d_thread self = d_threadLookupSelf(); + v_resourcePolicyI resourceLimits; + v_historicalDataRequest vrequest; + d_historicalDataRequest historicalDataRequest; + + assert(d_groupIsValid(group)); + assert(d_historicalDataIsValid(historicalData)); + + historicalDataRequest = historicalData->historicalDataRequest; + historicalData->list = c_iterNew(NULL); + historicalData->instances = c_iterNew(NULL); + historicalData->group = d_group(d_objectKeep(d_object(group))); + historicalData->vgroup = d_groupGetKernelGroup(group); + if (historicalData->vgroup) { + d_tracegroup(d_threadsDurability(), historicalData->vgroup, OS_FUNCTION); + /* Use the specified serializer to serialize the data. + * Currently, the only supported serializer is cdr. + * First serialize and compile the topic type, and + * then serialize the bead data. This is only needed + * for the first time for a topic. + */ + /* Currently the only defined serializer is cdr */ + if ((historicalData->cdrInfo = sd_cdrInfoNew(v_topicDataType(historicalData->vgroup->topic))) == NULL) { + goto err_allocCdrInfo; + } + if (sd_cdrCompile(historicalData->cdrInfo) != 0) { + goto err_cdrCompile; + } + /* Set the resourceLimits */ + resourceLimits.v.max_samples = historicalDataRequest->maxSamples; + resourceLimits.v.max_instances = historicalDataRequest->maxInstances; + resourceLimits.v.max_samples_per_instance = historicalDataRequest->maxSamplesPerInstance; + /* Retrieve historical data for this group */ + vrequest = v_historicalDataRequestNew( + v_objectKernel(historicalData->vgroup), + historicalDataRequest->sqlFilter, + (const c_char**)historicalDataRequest->sqlFilterParams, + historicalDataRequest->sqlFilterParamsSize, + historicalDataRequest->startTime, + historicalDataRequest->endTime, + &resourceLimits, + OS_DURATION_ZERO); + (void)d_shmAllocAssert(vrequest, "Allocation of v_historicalDataRequestNew failed."); + v_groupFlushActionWithCondition(historicalData->vgroup, vrequest, collectSamples, historicalData); + c_free(vrequest); + } else { + d_printTimedEvent(historicalData->durability, D_LEVEL_FINEST, + "No kernel group for topic '%s.%s' found (yet), so unable to retrieve historical data for this group\n", + historicalData->group->partition, historicalData->group->topic); + } + /* Send the beads */ + proceed = TRUE; + objectData = c_iterTakeFirst(historicalData->list); + while (objectData && proceed) { + assert(historicalData->vgroup); /* for the benefit of Clang's static analyzer */ + d_threadAwake(self); + instance = c_iterTakeFirst(historicalData->instances); + assert(instance); + if (c_instanceOf(objectData->object, "v_registration")) { + /* Registration or unregistration */ + registration = (v_registration)objectData->object; + vmessage = v_groupInstanceCreateMessage(instance); + if (vmessage) { + vmessage->writerGID = registration->writerGID; + vmessage->qos = c_keep(registration->qos); + vmessage->writeTime = registration->writeTime; + vmessage->sequenceNumber = registration->sequenceNumber; + if (objectData->flushType == V_GROUP_FLUSH_REGISTRATION) { + v_stateSet(v_nodeState(vmessage), L_REGISTER); + } else if(objectData->flushType == V_GROUP_FLUSH_UNREGISTRATION) { + v_stateSet(v_nodeState(vmessage), L_UNREGISTER); + } + if (v_stateTest(registration->state, L_IMPLICIT) == TRUE) { + v_stateSet(v_nodeState(vmessage), L_IMPLICIT); + } + writeBead(vmessage, historicalData); + c_free(vmessage); + } else { + proceed = d_shmAllocAssert(vmessage, "Allocation of sample failed."); + } + } else { + /* Normal data */ + vmessage = v_message(objectData->object); + assert(vmessage); + if (v_stateTest(v_nodeState(vmessage), L_WRITE) || + c_getType(vmessage) != v_kernelType(v_objectKernel(instance), K_MESSAGE)) { + writeBead(vmessage, historicalData); + } else { + /* If the message is a mini-message without keys, temporarily replace it with + * a typed message that does include the keys. That way the bead becomes self- + * describing and so the receiving node can deduct its instance again. + */ + vmessage = v_groupInstanceCreateTypedInvalidMessage(instance, vmessage); + if (vmessage) { + writeBead(vmessage, historicalData); + c_free(vmessage); + } else { + proceed = d_shmAllocAssert(vmessage, "Allocation of sample failed."); + } + } + } + c_free(instance); + c_free(objectData->object); + os_free(objectData); + objectData = c_iterTakeFirst(historicalData->list); + } /* while */ + /* Update the completeness state depending on the completeness state of the group */ + setCompleteness(historicalData, d_mapCompleteness(d_groupGetCompleteness(historicalData->group))); + /* clear objectData */ + objectData = c_iterTakeFirst(historicalData->list); + while (objectData) { + c_free(objectData->object); + os_free(objectData); + objectData = c_iterTakeFirst(historicalData->list); + } + c_iterFree(historicalData->list); + + instance = c_iterTakeFirst(historicalData->instances); + while (instance) { + c_free(instance); + instance = c_iterTakeFirst(historicalData->instances); + } + c_iterFree(historicalData->instances); + + if (historicalData->cdrInfo != NULL) { + sd_cdrInfoFree(historicalData->cdrInfo); + } + c_free(historicalData->vgroup); + d_groupFree(historicalData->group); + return TRUE; + +err_cdrCompile: + sd_cdrInfoFree(historicalData->cdrInfo); +err_allocCdrInfo: + return TRUE; +} + +/* Decides whether the server can answer the request + * + * Returns TRUE if the server can answer the request, FALSE if it is rescheduled + */ +static c_bool +can_answer(d_historicalDataRequest historicalDataRequest) +{ + d_durability durability = d_threadsDurability(); + d_admin admin = durability->admin; + d_configuration config = d_durabilityGetConfiguration(durability); + c_bool answer_now = TRUE; + os_duration readerDetectionPeriod = OS_DURATION_INIT(30,0); /* Use 30 seconds to detect the historicalDataReader */ + + if ((config->waitForRemoteReaders) && (historicalDataRequest->errorCode == D_DDS_RETCDE_NO_ERROR)) { + + c_iterIter iter= c_iterIterGet(historicalDataRequest->requestIds); + c_bool allReadersDetected = TRUE; + d_client client; + struct _DDS_RequestId_t *requestId; + + /* Walk over all requestIds and lookup the corresponding clients. + * As soon as all of them have a discovered reader we will answer the request. + * In case there are one or more reader for which the reader has not yet been + * detected we are going to postpone the answer until all readers have been + * detected. When the reader for one of more clients have not been detected + * after 30 sec an error link will be send using error code D_DDS_RETCDE_READER_NOT_KNOWN + */ + while (((requestId = (struct _DDS_RequestId_t *)c_iterNext(&iter)) != NULL) && (allReadersDetected)) { + if ((client = d_adminFindClientByClientId(admin, requestId->clientId)) != NULL) { + allReadersDetected = (((client->readers) & (D_HISTORICALDATA_READER_FLAG)) == (D_HISTORICALDATA_READER_FLAG)); + } + /* If the client could not be found anymore assume all readers have detected + * to prevent rescheduling of the request */ + } + if ((c_iterLength(historicalDataRequest->requestIds) == 0)) { + /* No clients anymore, send back D_DDS_RETCDE_NO_CLIENTS */ + d_printTimedEvent(durability, D_LEVEL_FINEST, d_threadSelfName(), + "No clients found for historicalDataRequest %p\n", (void*)historicalDataRequest); + historicalDataRequest->errorCode = D_DDS_RETCDE_NO_CLIENTS; + answer_now = TRUE; + } else if (allReadersDetected) { + /* Ready to send the answer */ + answer_now = TRUE; + } else { + /* Not yet all readers detected */ + os_duration diff = os_timeEDiff(os_timeEGet(), historicalDataRequest->receptionTime); + if (os_durationCompare(diff, readerDetectionPeriod) == OS_MORE) { + + d_printTimedEvent(durability, D_LEVEL_FINEST, d_threadSelfName(), + "Unable to detect the client's historicalData reader within %"PA_PRIduration" seconds\n", + OS_DURATION_PRINT(readerDetectionPeriod)); + + historicalDataRequest->errorCode = D_DDS_RETCDE_READER_NOT_KNOWN; + answer_now = TRUE; + } else { + answer_now = FALSE; + } + } + } + return answer_now; +} + + +static c_bool +d_historicalDataRequestListenerAnswer( + d_historicalDataRequestListener listener, + d_historicalDataRequest historicalDataRequest) +{ + d_admin admin; + d_durability durability; + struct collectMatchingGroupsHelper helper; + d_historicalData historicalData; + + assert(d_historicalDataRequestListenerIsValid(listener)); + assert(d_historicalDataRequestIsValid(historicalDataRequest)); + + admin = d_listenerGetAdmin(d_listener(listener)); + durability = d_adminGetDurability(admin); + d_printTimedEvent(durability, D_LEVEL_FINER, + "Going to answer %d historicalDataRequest(s)\n", c_iterLength(historicalDataRequest->requestIds)); + /* Create an historicalData to answer the historicalDataRequest */ + historicalData = d_historicalDataNew(admin, historicalDataRequest); + if (historicalData->errorCode == D_DDS_RETCDE_NO_ERROR) { + /* no error, retrieve matching groups */ + helper.admin = admin; + helper.topic = historicalDataRequest->topic; + helper.partitions = historicalDataRequest->partitions; + if ((helper.matchingGroups = d_tableNew(d_groupCompare, d_groupFree)) == NULL) { + goto err_allocMatchingGroups; + } + helper.forMe = historicalDataRequest->forMe; + helper.forEverybody = historicalDataRequest->forEverybody; + helper.isAligner = FALSE; + helper.isResponsible = FALSE; + helper.masterKnown = FALSE; + helper.groupFound = FALSE; + helper.isHistoricalDataRequest = TRUE; + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Collecting groups that match historicalDataRequest\n"); + /* Collect all matching groups. + * As a side effect, also set isAligner and isReponsible + */ + d_adminCollectMatchingGroups(admin, &helper); + d_printTimedEvent(durability, D_LEVEL_FINER, + "Total %d groups matched historicalDataRequest, publish the response to partition '%s'\n", + d_tableSize(helper.matchingGroups),historicalData->alignmentPartition); + if (d_tableSize(helper.matchingGroups) > 0) { + /* Send historicalData for each matching group. */ + (void)d_tableWalk(helper.matchingGroups, sendHistoricalData, historicalData); + writeLink(historicalData); + } else { + /* No matching group found. + * This can be because the server is not configured as aligner, + * or if the server is not responsible because it is not the master, + * or simply if the server does not know about the group + * Set the proper error code in each case. */ + if (!helper.isAligner) { + d_printTimedEvent(durability, D_LEVEL_FINEST, " No aligner\n"); + historicalData->errorCode = D_DDS_RETCDE_SERVER_IS_NOT_ALIGNER; /* Server is not configured to be an aligner for the requested dataset */ + } else if (!helper.masterKnown) { + d_printTimedEvent(durability, D_LEVEL_FINEST, " No master selected\n"); + historicalData->errorCode = D_DDS_RETCDE_NO_MASTER_SELECTED; /* A master has not yet been determined */ + } else if (!helper.groupFound) { + d_printTimedEvent(durability, D_LEVEL_FINEST, " No matching groups found\n"); + historicalData->errorCode = D_DDS_RETCDE_GROUP_NOT_FOUND ; /* Server is not configured to be an aligner for the requested dataset */ + } else if (!helper.isResponsible) { + d_printTimedEvent(durability, D_LEVEL_FINEST, " Not responsible\n"); + historicalData->errorCode = D_DDS_RETCDE_SERVER_IS_NOT_RESPONSIBLE; /* Request will be handled by a different durability service */ + } + /* TODO: + * if the request contains a wildcard and there no groups found, then the link should be complete with 0 samples. + * if the request does not contains a wildcard and there is no matching group then the link should indicate GROUP_UNKNOWN with 0 samples. + */ + writeLink(historicalData); + } + d_tableFree(helper.matchingGroups); + } else { + /* An error occurred, write a link containing the error */ + writeLink(historicalData); + } + d_historicalDataFree(historicalData); + return FALSE; /* Do not reschedule */ + +err_allocMatchingGroups: + /* Clean up the request and the response*/ + d_historicalDataFree(historicalData); + d_historicalDataRequestFree(historicalDataRequest); + return FALSE; +} + + +/* Implementation of the callback to answer a request + * + * Returns TRUE if request is rescheduled, FALSE when it is handled*/ +c_bool +answer_request( + void *listener, + void *arg) +{ + d_historicalDataRequestListener historicalDataRequestListener = d_historicalDataRequestListener(listener); + d_historicalDataRequest historicalDataRequest = d_historicalDataRequest(arg); + + assert(d_historicalDataRequestListenerIsValid(listener)); + assert(d_historicalDataRequestIsValid(historicalDataRequest)); + + /* Check whether to reschedule or to answer the request */ + if (can_answer(historicalDataRequest)) { + (void)d_historicalDataRequestListenerAnswer(historicalDataRequestListener, historicalDataRequest); + return FALSE; + } else { + /* Reschedule request over 0.5 sec */ + (void)reschedule_request(historicalDataRequestListener, historicalDataRequest, OS_DURATION_INIT(0,500000000)); + return TRUE; + } +} + + +/* Returns: + * - historicalDataRequest, if historicalDataRequest must be answered now + * - NULL, if no historicalDataRequest must be answered now, wait_time contains the time to wait (either finite time or infinite) + * + * It is assumed that the caller locks the request queue. + */ +static struct request_admin_node * +get_request_unlocked( + d_historicalDataRequestListener listener, + os_duration *wait_time) +{ + os_timeE now; + os_timeE expiration_time; + struct request_admin_node *n = NULL; + + assert(d_historicalDataRequestListenerIsValid(listener)); + + expiration_time = time_of_next_request_unlocked(listener); + if (OS_TIMEE_ISINFINITE(expiration_time)) { + *wait_time = OS_DURATION_INFINITE; + return NULL; + } + now = os_timeEGet(); + *wait_time = os_timeEDiff(expiration_time, now); + if (os_durationCompare(*wait_time, ((os_duration) 0x0)) != OS_MORE) { + if ((n = take_next_request_unlocked(listener)) != NULL) { + n->handle_time = now; + } + } + return n; +} + +static void cleanup_node( + struct request_admin_node *n) +{ + assert(n); + + /* Only request must be cleaned up. + * PubInfo nodes are already scheduled for destruction + */ + if (n->callback == answer_request) { + /* cleanup the request */ + cleanup_request(n); + } else if (n->callback == delete_pubinfo) { + cleanup_pubinfo(n); + } +} + + +static void * +d_historicalDataRequestListenerHandlerThread( + void* arg) +{ + d_thread self = d_threadLookupSelf (); + d_historicalDataRequestListener listener; + os_duration wait_time; + struct request_admin_node *n = NULL; + os_result osr; + c_bool rescheduled = FALSE; + + listener = d_historicalDataRequestListener(arg); + + os_mutexLock(&listener->queue_lock); + while (listener->terminate == FALSE) { + /* Take the first element from the queue, but only if it has expired */ + n = get_request_unlocked(listener, &wait_time); + while ((n) && (listener->terminate == FALSE)) { + os_mutexUnlock(&listener->queue_lock); + /* execute the callback */ + if (n->callback) { + d_trace(D_TRACE_PRIO_QUEUE, "%s: handle avlnode %p, insert_time=%"PA_PRItime", expiration_time = %"PA_PRItime"\n", + OS_FUNCTION, (void *)n, OS_TIMEE_PRINT(n->insert_time), OS_TIMEE_PRINT(n->expiration_time)); + rescheduled = n->callback(listener, n->arg); + } + if (rescheduled) { + os_free(n); + } else { + cleanup_node(n); + } + /* Get the next request */ + os_mutexLock(&listener->queue_lock); + n = get_request_unlocked(listener, &wait_time); + } + /* Wait until wait_time expires or the condition is triggered */ + if (listener->terminate == FALSE) { + if (OS_DURATION_ISINFINITE(wait_time)) { + d_condWait(self, &listener->cond, &listener->queue_lock); + } else if ((osr = d_condTimedWait(self, &listener->cond, &listener->queue_lock, wait_time)) == os_resultFail) { + OS_REPORT(OS_CRITICAL, D_CONTEXT_DURABILITY, 0, "d_condTimedWait failed; terminating"); + /* terminate durability */ + d_durabilityTerminate(d_threadsDurability(), TRUE); + } + } + } /* while */ + os_mutexUnlock(&listener->queue_lock); + /* In case the thread is about to terminate it might be that n was still taken */ + if (n) { + cleanup_node(n); + } + return NULL; +} + + +/** + * \brief Add a historicalDataRequest to the list of pending requests. + */ +static void +d_historicalDataRequestListenerAddRequest( + d_historicalDataRequestListener listener, + d_historicalDataRequest historicalDataRequest) +{ + assert(d_historicalDataRequestListenerIsValid(listener)); + assert(d_historicalDataRequestIsValid(historicalDataRequest)); + + /* Insert the request in priority queue and possibly signal the handler thread */ + (void)insert_request(listener, historicalDataRequest); + return; +} + +static +u_actionResult +processHistoricalDataRequest( + c_object o, + c_voidp userData /* listener * */) +{ + d_historicalDataRequestListener listener; + struct _DDS_HistoricalDataRequest *request; + d_historicalDataRequest historicalDataRequest; + v_dataReaderSample s; + v_actionResult result = 0; + v_message message; + d_admin admin; + d_durability durability; + d_client client, duplicate; + d_networkAddress clientAddr; + + listener = d_historicalDataRequestListener(userData); + s = v_dataReaderSample(o); + if (s != NULL) { + admin = d_listenerGetAdmin(d_listener(listener)); + durability = d_adminGetDurability(admin); + v_actionResultSet(result, V_PROCEED); + if (v_dataReaderSampleStateTest(s, L_VALIDDATA) && !(v_dataReaderSampleInstanceStateTest(s, L_DISPOSED))) { + message = v_dataReaderSampleTemplate(s)->message; + + request = (struct _DDS_HistoricalDataRequest *)C_DISPLACE(message, C_MAXALIGNSIZE(sizeof(*message))); + /* create a d_historicalDataRequest object to store the request */ + if ((historicalDataRequest = d_historicalDataRequestNew(admin, request)) == NULL) { + goto alloc_historicalDataRequest; + } + /* Get or create client and store the requestId.clientId */ + clientAddr = d_networkAddressNew(message->writerGID.systemId, 0, 0); + client = d_clientNew(clientAddr); + if ((duplicate = d_adminAddClient(admin, client)) != client) { + d_clientFree(client); + client = duplicate; + } + d_clientSetClientId(client, request->requestId.clientId); + d_printTimedEvent(durability, D_LEVEL_FINE, + "Received historicalDataRequest %lu for topic '%s' from client %lld.%lld at federation %u\n", + request->requestId.requestId, + request->topic ? request->topic : "NULL", + request->requestId.clientId.prefix, + request->requestId.clientId.suffix, + clientAddr->systemId); + /* Check if the request is for me or for everybody*/ + if ((!historicalDataRequest->forMe) && (!historicalDataRequest->forEverybody)) { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "historicalDataRequest %lu for topic '%s' from client %lld.%lld at federation %u is not meant for me, ignoring this request\n", + request->requestId.requestId, + request->requestId.clientId.prefix, + request->requestId.clientId.suffix, + clientAddr->systemId); + goto skip_notMeantForMe; + } + /* The request is meant for me so I must answer, even if the request contains errors. */ + historicalDataRequest->errorCode = d_historicalDataRequestSanityCheck(historicalDataRequest); + /* Calculate the expirationTime based on the historicalData->timeout. + * This must be a valid timeout, otherwise the sanity check has catched it + */ + if (historicalDataRequest->errorCode == D_DDS_RETCDE_NO_ERROR) { + if (os_durationCompare(historicalDataRequest->timeout, OS_DURATION_INFINITE) == OS_EQUAL) { + historicalDataRequest->expirationTime = OS_TIMEE_INFINITE; + } else { + historicalDataRequest->expirationTime = os_timeEAdd(historicalDataRequest->receptionTime, historicalDataRequest->timeout); + } + } else { + /* sanity error encountered, answer immediately */ + historicalDataRequest->expirationTime = OS_TIMEE_ZERO; + } + /* Schedule the answer to the request */ + d_historicalDataRequestListenerAddRequest(listener, historicalDataRequest); + /* Free the stuff */ + d_networkAddressFree(clientAddr); + d_clientFree(client); + } else if (v_dataReaderSampleInstanceStateTest(s, L_DISPOSED)) { + /* The request is disposed, so in this case we should remove pending requests. */ + d_printTimedEvent(durability, D_LEVEL_FINEST, "request is disposed\n"); + } + } + return result; + +skip_notMeantForMe: + d_historicalDataRequestFree(historicalDataRequest); + d_networkAddressFree(clientAddr); +alloc_historicalDataRequest: + return result; +} + + +static c_ulong +d_historicalDataRequestListenerAction( + u_object o, /* the observable that triggered the event */ + v_waitsetEvent event, /* the event that was triggered */ + c_voidp userData /* d_historicalDataRequestListener */) +{ + d_historicalDataRequestListener listener; + u_result ur; + d_admin admin; + d_durability durability; + d_thread self = d_threadLookupSelf(); + + OS_UNUSED_ARG(o); + + listener = d_historicalDataRequestListener(userData); + d_lockLock(d_lock(listener)); + d_threadAwake(self); + /* Read HistoricalDataRequests and process them */ + ur = u_dataReaderTake(listener->dataReader, U_STATE_ANY, processHistoricalDataRequest, listener, OS_DURATION_ZERO); + if (ur != U_RESULT_OK && ur != U_RESULT_NO_DATA) { + admin = d_listenerGetAdmin(d_listener(listener)); + durability = d_adminGetDurability(admin); + OS_REPORT(OS_ERROR, D_CONTEXT_DURABILITY, ur, + "Failed to read data from historicalDataRequestListener (result: %s)", u_resultImage(ur)); + d_durabilityTerminate(durability, TRUE); + } + d_threadAsleep(self, ~0u); + d_lockUnlock(d_lock(listener)); + return event->kind; +} + + +static void +d_historicalDataRequestListenerDeinit( + d_historicalDataRequestListener listener) +{ + assert(d_historicalDataRequestListenerIsValid(listener)); + + /* Stop the historicalDataRequestListener */ + d_historicalDataRequestListenerStop(listener); + + /* Destroyed the historicalDataRequestHandler thread */ + os_mutexLock(&listener->queue_lock); + listener->terminate = TRUE; + (void)os_condBroadcast(&listener->cond); + os_mutexUnlock(&listener->queue_lock); + if (listener->handlerThreadExists) { + d_threadWaitExit(listener->handlerThread, NULL); + } + if (listener->waitsetData) { + d_waitsetEntityFree(listener->waitsetData); + listener->waitsetData = NULL; + } + if (listener->dataReader) { + u_objectFree(u_object(listener->dataReader)); + listener->dataReader = NULL; + } + ut_avlFree(&listener->request_avltreedef, &listener->request_id_tree, cleanup_request); + ut_avlFree(&listener->pubinfo_avltreedef, &listener->pubinfo_tree, cleanup_pubinfo); + /* Destroy mutex and condition */ + (void)os_condDestroy(&listener->cond); + (void)os_mutexDestroy(&listener->queue_lock); + listener->subscriber = NULL; + /* Call super-deinit */ + d_listenerDeinit(d_listener(listener)); +} + +/** + * \brief Create an historicalDataRequestListener object + * + * The listener listens to historicalDataRequest messages that + * are published on the durability partition. Requests that + * originate from the same node as the historicalDataRequestListener + * are discarded. + */ +d_historicalDataRequestListener +d_historicalDataRequestListenerNew( + d_subscriber subscriber) +{ + d_historicalDataRequestListener listener; + v_readerQos readerQos = NULL; + os_threadAttr attr; + os_threadAttr tattr; + os_result osr; + struct _DDS_Gid_t myServerId; + c_value ps[2]; + + /* Tree definition for tree that organises historicalDataRequests based on requestId and topic */ + ut_avlTreedef_t request_avltreedef = UT_AVL_TREEDEF_INITIALIZER_INDKEY ( + offsetof (struct request_admin_node, request_avlnode), /* node in tree containing pending requests */ + offsetof (struct request_admin_node, arg), /* attribute used for comparision */ + compare_request_by_requestId, /* comparison function */ + 0); /* flags */ + ut_avlTreedef_t pubinfo_avltreedef = UT_AVL_TREEDEF_INITIALIZER_INDKEY ( + offsetof (struct request_admin_node, pubinfo_avlnode), /* node in tree containing pending publishers */ + offsetof (struct request_admin_node, arg), /* attribute used for comparision */ + compare_pubinfo_by_partition, /* comparison function */ + 0); /* flags */ + + assert(d_subscriberIsValid(subscriber)); + + /* Allocate historicalDataRequestListener object */ + listener = d_historicalDataRequestListener(os_malloc(C_SIZEOF(d_historicalDataRequestListener))); + /* Call super-init */ + d_listenerInit(d_listener(listener), D_HISTORICAL_DATA_REQ_LISTENER, subscriber, NULL, + (d_objectDeinitFunc)d_historicalDataRequestListenerDeinit); + /* Initialize the historicalDataRequestListener */ + /* Initialize priority queue for requests */ + listener->request_avltreedef = request_avltreedef; + listener->pubinfo_avltreedef = pubinfo_avltreedef; + ut_avlInit (&listener->request_avltreedef, &listener->request_id_tree); + ut_avlInit (&listener->pubinfo_avltreedef, &listener->pubinfo_tree); + ut_fibheapInit (&prioqueue_fhdef, &listener->prioqueue); + /* Create mutexes and condition */ + listener->terminate = FALSE; + if ((osr = os_mutexInit(&listener->queue_lock, NULL)) != os_resultSuccess) { + goto err_mutex_init; + } + if ((osr = os_condInit(&listener->cond, &listener->queue_lock, NULL)) != os_resultSuccess) { + goto err_cond_init; + } + /* start historicalDataRequestHandlerThread */ + os_threadAttrInit(&tattr); + if ((osr = d_threadCreate(&(listener->handlerThread), "historicalDataRequestHandler", &tattr, (void*(*)(void*))d_historicalDataRequestListenerHandlerThread, (void*)listener)) != os_resultSuccess) { + listener->handlerThreadExists = FALSE; + goto err_handler_thread; + } + listener->handlerThreadExists = TRUE; + /* d_readerQosNew does not always return the proper settings. + * The following settings ensure that the reader qos is correct + */ + listener->subscriber = subscriber; + if ((readerQos = d_readerQosNew(V_DURABILITY_VOLATILE, V_RELIABILITY_RELIABLE)) == NULL) { + goto err_readerQos; + } + readerQos->history.v.kind = V_HISTORY_KEEPALL; + readerQos->history.v.depth = V_LENGTH_UNLIMITED; + readerQos->liveliness.v.lease_duration = OS_DURATION_INFINITE; + readerQos->reliability.v.max_blocking_time = OS_DURATION_INIT(0,100000000); + /* Prevent that the historicalDataReader listens to requests from itself. */ + myServerId = d_durabilityGetMyServerId(d_adminGetDurability(subscriber->admin)); + ps[0].kind = V_LONGLONG; + ps[0].is.LongLong = myServerId.prefix; + ps[1].kind = V_LONGLONG; + ps[1].is.LongLong = myServerId.suffix; + listener->dataReader = u_subscriberCreateDataReader( + subscriber->subscriber2, + D_HISTORICAL_DATA_REQUEST_TOPIC_NAME "Reader", + "select * from " D_HISTORICAL_DATA_REQUEST_TOPIC_NAME " where requestId.clientId.prefix <> %0 OR requestId.clientId.suffix <> %1", + ps, 2, + readerQos); + d_readerQosFree(readerQos); + if (listener->dataReader == NULL) { + goto err_dataReader; + } + /* No need to obtain historical data because topic is volatile */ + if(u_entityEnable(u_entity(listener->dataReader)) != U_RESULT_OK) { + goto err_dataReaderEnable; + } + os_threadAttrInit(&attr); + listener->waitsetData = d_waitsetEntityNew( + "historicalDataRequestListener", + u_object(listener->dataReader), + d_historicalDataRequestListenerAction, + V_EVENT_DATA_AVAILABLE, + attr, listener); + if (!listener->waitsetData) { + goto err_waitsetData; + } + return listener; + +err_waitsetData: + /* No undo for u_entityEnable(...) */ +err_dataReaderEnable: +err_dataReader: +err_readerQos: +err_handler_thread: +err_cond_init: +err_mutex_init: + d_historicalDataRequestListenerFree(listener); + return NULL; +} + + +void +d_historicalDataRequestListenerFree( + d_historicalDataRequestListener listener) +{ + assert(d_historicalDataRequestListenerIsValid(listener)); + + d_objectFree(d_object(listener)); +} + + +static void +cleanup_request (void *n) +{ + struct request_admin_node *m = (struct request_admin_node *)n; + + d_trace(D_TRACE_PRIO_QUEUE, "%s: cleanup avlnode %p\n", OS_FUNCTION, (void *)n); + d_historicalDataRequestFree(m->arg); + os_free(m); +} + + +static void +cleanup_pubinfo (void *n) +{ + struct request_admin_node *m = (struct request_admin_node *)n; + struct pubInfo *pubinfo = (struct pubInfo *)(m->arg); + + d_trace(D_TRACE_PRIO_QUEUE, "%s: cleanup avlnode %p\n", OS_FUNCTION, (void *)n); + u_objectFree(u_object(pubinfo->writer)); + u_objectFree(u_object(pubinfo->publisher)); + os_free(pubinfo->partition); + os_free(m); +} + + +static c_bool +d_historicalDataRequestListenerNotifyEvent( + c_ulong event, + d_fellow fellow, + d_nameSpace ns, + d_group group, + c_voidp eventUserData, + c_voidp userData) +{ + d_historicalDataRequestListener listener = d_historicalDataRequestListener(userData); + + assert(d_historicalDataRequestListenerIsValid(listener)); + + OS_UNUSED_ARG(event); + OS_UNUSED_ARG(fellow); + OS_UNUSED_ARG(ns); + OS_UNUSED_ARG(group); + OS_UNUSED_ARG(eventUserData); + OS_UNUSED_ARG(userData); + OS_UNUSED_ARG(listener); + + switch (event) { + case D_GROUP_LOCAL_COMPLETE : +#if 0 + printf("*** %s.%s D_GROUP_LOCAL_COMPLETE\n", d_groupGetPartition(group), d_groupGetTopic(group)); +#endif + /* TODO: move the pending historicalDataRequests with matching partition/topic to the front of the queue */ + break; + case D_FELLOW_REMOVED : +#if 0 + printf("*** D_FELLOW_REMOVED\n"); +#endif + break; + default : ; +#if 0 + printf("*** not triggered\n"); +#endif + } + return TRUE; +} + +c_bool +d_historicalDataRequestListenerStart( + d_historicalDataRequestListener listener) +{ + c_bool result; + d_waitset waitset; + u_result ur; + d_admin admin; + result = FALSE; + + assert(d_historicalDataRequestListenerIsValid(listener)); + + d_lockLock(d_lock(listener)); + if (d_listener(listener)->attached == FALSE) { + waitset = d_subscriberGetWaitset(listener->subscriber); + result = d_waitsetAttach(waitset, listener->waitsetData); + admin = d_listenerGetAdmin(d_listener(listener)); + /* Create an eventListener that reacts to relevant events */ + listener->historicalDataRequestEventListener = d_eventListenerNew(D_GROUP_LOCAL_COMPLETE /* | D_READERS_DETECTED */ | D_FELLOW_REMOVED, d_historicalDataRequestListenerNotifyEvent, listener); + d_adminAddListener(admin, listener->historicalDataRequestEventListener); + + if (result == TRUE) { + /* A V_DATA_AVAILABLE event is only generated when new data + * arrives. It is NOT generated when historical data is inserted. + * In case this durability service receives historical + * DCPSSubscriptions from another durability service that + * was started earlier, all these DCPSSubscriptions are + * inserted in the reader at creation time. To read these + * we must explicitly trigger a take action. + */ + ur = u_dataReaderTake(listener->dataReader, U_STATE_ANY, processHistoricalDataRequest, listener, OS_DURATION_ZERO); + if (ur != U_RESULT_OK && ur != U_RESULT_NO_DATA) { + OS_REPORT(OS_ERROR, D_CONTEXT_DURABILITY, ur, + "Failed to read data from historicalDataRequestListenerReader (result: %s)", u_resultImage(ur)); + } else { + d_listener(listener)->attached = TRUE; + result = TRUE; + } + } + } else { + result = TRUE; + } + d_lockUnlock(d_lock(listener)); + /* Notify the listeners */ + (void)u_observableNotify(u_observable(listener->dataReader)); + return result; +} + + +c_bool +d_historicalDataRequestListenerStop( + d_historicalDataRequestListener listener) +{ + c_bool result = FALSE; + d_admin admin; + d_subscriber subscriber; + d_waitset waitset; + + assert(d_historicalDataRequestListenerIsValid(listener)); + + d_lockLock(d_lock(listener)); + if (d_listener(listener)->attached == TRUE) { + admin = d_listenerGetAdmin(d_listener(listener)); + subscriber = d_adminGetSubscriber(admin); + waitset = d_subscriberGetWaitset(subscriber); + d_lockUnlock(d_lock(listener)); + result = d_waitsetDetach(waitset, listener->waitsetData); + d_lockLock(d_lock(listener)); + assert(result == TRUE); + if (result) { + d_adminRemoveListener(admin, listener->historicalDataRequestEventListener); + d_eventListenerFree(listener->historicalDataRequestEventListener); + d_listener(listener)->attached = FALSE; + result = TRUE; + } + } else { + result = TRUE; + } + d_lockUnlock(d_lock(listener)); + + return result; +} + + + diff --git a/src/services/durability/code/d_listener.c b/src/services/durability/code/d_listener.c new file mode 100644 index 000000000..517e52f61 --- /dev/null +++ b/src/services/durability/code/d_listener.c @@ -0,0 +1,119 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "d__listener.h" +#include "d__subscriber.h" + +void +d_listenerInit( + d_listener listener, + d_listenerKind kind, + d_subscriber subscriber, + d_listenerAction action, + d_objectDeinitFunc deinit) +{ + /* Do not assert the listener because the initialization + * of the listener has not yet completed */ + + if (listener) { + /* Call super-init */ + d_lockInit(d_lock(listener), D_LISTENER, + (d_objectDeinitFunc)deinit); + /* Initialize the listener */ + listener->kind = kind; + listener->admin = d_subscriberGetAdmin(subscriber); + listener->action = action; + listener->attached = FALSE; + } +} + + +void +d_listenerDeinit ( + d_listener listener) +{ + assert(d_listenerIsValid(listener)); + + /* Call super-deinit */ + d_lockDeinit(d_lock(listener)); +} + + +c_bool +d_listenerIsValidKind( + d_listener listener, + d_listenerKind kind) +{ + c_bool result = FALSE; + + assert(d_listenerIsValid(listener)); + + if (listener->kind == kind) { + result = TRUE; + } + return result; +} + + +void +d_listenerLock( + d_listener listener) +{ + assert(d_listenerIsValid(listener)); + + d_lockLock(d_lock(listener)); +} + + +void +d_listenerUnlock( + d_listener listener) +{ + assert(d_listenerIsValid(listener)); + + d_lockUnlock(d_lock(listener)); +} + + +d_listenerAction +d_listenerGetAction( + d_listener listener) +{ + assert(d_listenerIsValid(listener)); + + return listener->action; +} + + +c_bool +d_listenerIsAttached( + d_listener listener) +{ + assert(d_listenerIsValid(listener)); + + return listener->attached; +} + +d_admin +d_listenerGetAdmin( + d_listener listener) +{ + assert(d_listenerIsValid(listener)); + + return listener->admin; +} diff --git a/src/services/durability/code/d_lock.c b/src/services/durability/code/d_lock.c new file mode 100644 index 000000000..adbc08be7 --- /dev/null +++ b/src/services/durability/code/d_lock.c @@ -0,0 +1,96 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "d__lock.h" +#include "d__thread.h" +#include "d__misc.h" +#include "d_object.h" +#include "os_heap.h" +#include "os_report.h" + +void +d_lockInit( + d_lock lock, + d_kind kind, + d_objectDeinitFunc deinit) +{ + if (lock) { + /* Call super-init */ + d_objectInit(d_object(lock), kind, + (d_objectDeinitFunc)deinit); + /* Initialize the lock */ + /* At the moment the return value of os_mutexInit is unchecked + * and hence assumed to succeed always. If this assumption + * is dropped then d_lockInit must return a proper error code + * to the caller indicating that the d_lockInit has failed. + * The caller must then take appropiate action. */ + (void)os_mutexInit(&lock->lock, NULL); +#ifndef NDEBUG + lock->tid = 0U; +#endif + } +} + + +void +d_lockDeinit( + d_lock lock) +{ + assert(d_lockIsValid(lock)); + + /* Deinitialize the lock */ + os_mutexDestroy(&(lock->lock)); + /* Call super-deinit */ + d_objectDeinit(d_object(lock)); +} + + +void +d_lockFree( + d_lock lock) +{ + assert(d_lockIsValid(lock)); + + d_objectFree(d_object(lock)); +} + + +void +d_lockLock( + d_lock lock) +{ + assert(d_lockIsValid(lock)); + + os_mutexLock(&lock->lock); +#ifndef NDEBUG + lock->tid = os_threadIdToInteger(os_threadIdSelf()); +#endif +} + + +void +d_lockUnlock( + d_lock lock) +{ + assert(d_lockIsValid(lock)); + +#ifndef NDEBUG + lock->tid = 0U; +#endif + os_mutexUnlock(&lock->lock); +} diff --git a/src/services/durability/code/d_mergeAction.c b/src/services/durability/code/d_mergeAction.c new file mode 100644 index 000000000..08a7721a0 --- /dev/null +++ b/src/services/durability/code/d_mergeAction.c @@ -0,0 +1,331 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#include "d__mergeAction.h" +#include "d__mergeState.h" +#include "d__nameSpace.h" +#include "d__fellow.h" +#include "d__sampleChainListener.h" +#include "d__table.h" +#include "d__types.h" +#include "d__conflict.h" +#include "os_heap.h" +#include "os_stdlib.h" + +d_mergeAction +d_mergeActionNew( + d_conflict conflict, /* conflict that lead to the creation of this mergeAction */ + d_nameSpace nameSpace, + c_iter fellows, + d_mergeState newState) +{ + d_mergeAction action; + c_ulong i; + d_fellow fellow; + + assert(d_conflictIsValid(conflict)); + assert(d_nameSpaceIsValid(nameSpace)); + assert(fellows); + assert(c_iterLength(fellows)); + + /* Allocate mergeAction object */ + action = d_mergeAction(os_malloc(C_SIZEOF(d_mergeAction))); + /* Call super-init */ + d_lockInit(d_lock(action), D_MERGE_ACTION, + (d_objectDeinitFunc)d_mergeActionDeinit); + /* Initialize mergeAction */ + action->conflict = d_conflict(d_objectKeep(d_object(conflict))); + action->nameSpace = d_nameSpace(d_objectKeep(d_object(nameSpace))); + action->fellows = d_tableNew(d_fellowCompare, d_fellowFree); + /* Initialize the table with the fellows */ + for (i=0;ifellows, fellow); + } + if (newState) { + /* New state value when merge action is completed */ + action->newState = d_mergeStateNew(newState->role, newState->value); + } else { + /* Merge state will be determined */ + action->newState = NULL; + } + action->chains = d_tableNew(d_chainCompare, d_chainFree); + action->stateChanged = FALSE; + return action; +} + + +void +d_mergeActionFree( + d_mergeAction action) +{ + assert(d_mergeActionIsValid(action)); + + d_objectFree(d_object(action)); +} + + +void +d_mergeActionDeinit( + d_mergeAction action) +{ + assert(d_mergeActionIsValid(action)); + + if (action->conflict) { + d_conflictFree(action->conflict); + action->conflict = NULL; + } + if (action->nameSpace) { + d_nameSpaceFree(action->nameSpace); + action->nameSpace = NULL; + } + if (action->fellows) { + d_tableFree(action->fellows); + action->fellows = NULL; + } + if (action->newState) { + d_mergeStateFree(action->newState); + action->newState = NULL; + } + if (action->chains) { + d_tableFree(action->chains); + action->chains = NULL; + } + if (action->newState) { + d_mergeStateFree (action->newState); + action->newState = NULL; + } + /* Call super-deinit */ + d_lockDeinit(d_lock(action)); +} + + +c_bool +d_mergeActionAddChain( + d_mergeAction action, + d_chain chain) +{ + d_chain existing; + c_bool success; + + assert(d_objectIsValid(d_object(action), D_MERGE_ACTION) == TRUE); + + if (action && chain) { + d_lockLock(d_lock(action)); + existing = d_tableInsert(action->chains, d_objectKeep(d_object(chain))); + d_lockUnlock(d_lock(action)); + if (existing) { + /* The chain is a duplicate chain, which means that there + * already exists a chain for a request of the same group. + * In that case undo the keep. */ + d_chainFree(chain); + success = FALSE; + } else { + success = TRUE; + } + } else { + success = FALSE; + } + return success; +} + +c_bool +d_mergeActionRemoveChain( + d_mergeAction action, + d_chain chain) +{ + d_chain found; + c_bool success; + + assert(d_objectIsValid(d_object(action), D_MERGE_ACTION) == TRUE); + + if(action && chain){ + d_lockLock(d_lock(action)); + found = d_tableRemove(action->chains, chain); + d_lockUnlock(d_lock(action)); + + if(found){ + d_chainFree (found); + success = TRUE; + } else { + success = FALSE; + } + } else { + success = FALSE; + } + return success; + +} + +d_chain +d_mergeActionGetChain( + d_mergeAction action, + d_chain dummy) +{ + d_chain chain; + + assert(d_objectIsValid(d_object(action), D_MERGE_ACTION) == TRUE); + + if(action && dummy){ + chain = d_tableFind(action->chains, dummy); + } else { + chain = NULL; + } + return chain; +} + +c_ulong +d_mergeActionGetChainCount( + d_mergeAction action) +{ + c_ulong result; + + assert(d_objectIsValid(d_object(action), D_MERGE_ACTION) == TRUE); + + if(action){ + result = d_tableSize(action->chains); + } else { + result = 0; + } + return result; +} + +void +d_mergeActionChainWalk( + d_mergeAction mergeAction, + c_bool ( * action ) (d_chain chain, c_voidp data), + c_voidp userData) +{ + assert(d_objectIsValid(d_object(mergeAction), D_MERGE_ACTION) == TRUE); + + if(action){ + d_tableWalk(mergeAction->chains, action, userData); + } + return; +} + + +d_nameSpace +d_mergeActionGetNameSpace( + d_mergeAction action) +{ + d_nameSpace nameSpace; + + assert(d_objectIsValid(d_object(action), D_MERGE_ACTION) == TRUE); + + if (action) { + nameSpace = action->nameSpace; + } else { + nameSpace = NULL; + } + return nameSpace; +} + +d_mergeState +d_mergeActionGetNewState( + d_mergeAction action) +{ + d_mergeState newState; + + assert(d_objectIsValid(d_object(action), D_MERGE_ACTION) == TRUE); + + if(action){ + newState = action->newState; + } else { + newState = NULL; + } + return newState; +} + + +/** + * \brief Compare two mergeActions + * + * Two mergeActions are considered equal if their nameSpaces and + * their resulting mergeState are identical. + */ +int +d_mergeActionCompare( + d_mergeAction a1, + d_mergeAction a2) +{ + int result; + + assert(d_mergeActionIsValid(a1)); + assert(d_mergeActionIsValid(a2)); + + if (a1 == a2) { + result = 0; + } else { + /* Compare the namespace */ + result = d_nameSpaceCompare(a1->nameSpace, a2->nameSpace); + if (result == 0) { + /* Compare the resulting merge state */ + result = d_mergeStateCompare(a1->newState, a2->newState); + /* Currently the table of fellows in mergeAction is + * not part of the compare! This may have to change + * in future. */ + } + } + return result; +} + +void +d_mergeActionSetStateChanged( + d_mergeAction action, + c_bool stateChanged) +{ + assert(d_objectIsValid(d_object(action), D_MERGE_ACTION) == TRUE); + + if (action) { + /* Because this current is a one-way set FALSE -> TRUE added assert to + * validate this is true */ + assert(stateChanged || !action->stateChanged); + + action->stateChanged = stateChanged; + } +} + +c_bool +d_mergeActionGetStateChanged( + d_mergeAction action) +{ + assert(d_objectIsValid(d_object(action), D_MERGE_ACTION) == TRUE); + + return action ? action->stateChanged : FALSE; +} + +void +d_mergeActionUpdateMergeCount( + d_mergeAction action) +{ + d_fellow fellow; + d_tableIter iter; + d_nameSpace fellowNameSpace; + c_ulong mergeCount; + + assert(d_objectIsValid(d_object(action), D_MERGE_ACTION)); + + for (fellow = d_tableIterFirst(action->fellows, &iter); + fellow != NULL; + fellow = d_tableIterNext(&iter)) { + fellowNameSpace = d_fellowGetNameSpace(fellow, action->nameSpace); + mergeCount = d_nameSpaceGetMergeCount(fellowNameSpace); + d_nameSpaceSetMergeCount(fellowNameSpace, ++mergeCount); + } +} diff --git a/src/services/durability/code/d_mergeState.c b/src/services/durability/code/d_mergeState.c new file mode 100644 index 000000000..5af77c839 --- /dev/null +++ b/src/services/durability/code/d_mergeState.c @@ -0,0 +1,160 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#include "d__mergeState.h" +#include "os_heap.h" +#include "os_stdlib.h" + +d_mergeState +d_mergeStateNew( + const d_name role, + c_ulong value) +{ + d_mergeState mergeState; + + mergeState = d_mergeState(os_malloc(C_SIZEOF(d_mergeState))); + d_mergeStateInit(mergeState, role, value); + + return mergeState; +} + +void +d_mergeStateInit( + d_mergeState mergeState, + const d_name role, + c_ulong value) +{ + if (mergeState) { + if (role) { + mergeState->role = os_strdup(role); + } else { + mergeState->role = NULL; + } + mergeState->value = value; + } +} + + +void +d_mergeStateFree( + d_mergeState mergeState) +{ + /* Note that mergeState can be NULL. + * Therefore, a NULL check is needed before freeing the mergeState. + */ + if (mergeState) { + d_mergeStateDeinit(mergeState); + os_free(mergeState); + } + return; +} + +void +d_mergeStateDeinit( + d_mergeState mergeState) +{ + if (mergeState) { + if(mergeState->role){ + os_free(mergeState->role); + mergeState->role = NULL; + } + } +} + +void +d_mergeStateSetRole( + d_mergeState mergeState, + d_name role) +{ + if(mergeState){ + if(mergeState->role){ + os_free(mergeState->role); + mergeState->role = NULL; + } + if(role){ + mergeState->role = os_strdup(role); + } + } + return; +} + +void +d_mergeStateSetValue( + d_mergeState mergeState, + c_ulong value) +{ + if(mergeState){ + mergeState->value = value; + } + return; +} + +/* Compares mergeStates only on the role, primarily used in tableCompare */ +int +d_mergeStateCompare( + d_mergeState state1, + d_mergeState state2) +{ + int result; + + if(state1 && state2){ + if(state1->role && state2->role){ + result = strcmp(state1->role, state2->role); + } else if(state1->role){ + result = 1; + } else if(state2->role){ + result = -1; + } else { + result = 0; + } + } else if(state1){ + result = 1; + } else if(state2){ + result = -1; + } else { + result = 0; + } + return result; +} + +/* Compares mergeStates based on role AND value */ +int +d_mergeStateRoleValueCompare( + d_mergeState state1, + d_mergeState state2) +{ + int result; + + result = d_mergeStateCompare(state1, state2); + if (result == 0) { + if ((state1 != NULL) && (state2 != NULL)) { + if (state1->value < state2->value) { + result = -1; + } else if (state1->value > state2->value) { + result = 1; + } else { + result = 0; + } + } else { + /* The only possibility is both state1 == NULL && state2 == NULL */ + assert(state1 == NULL); + assert(state2 == NULL); + result = 0; + } + } + return result; +} diff --git a/src/services/durability/code/d_message.c b/src/services/durability/code/d_message.c new file mode 100644 index 000000000..2f4796da1 --- /dev/null +++ b/src/services/durability/code/d_message.c @@ -0,0 +1,124 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "d_message.h" +#include "d__durability.h" +#include "d__admin.h" +#include "d__configuration.h" +#include "d_networkAddress.h" + +void +d_messageInit( + d_message message, + d_admin admin) +{ + d_networkAddress addr, unAddr; + d_configuration config; + + if (message) { + config = d_durabilityGetConfiguration(d_adminGetDurability(admin)); + addr = d_adminGetMyAddress(admin); + unAddr = d_networkAddressUnaddressed(); + + message->senderState = d_durabilityGetState(d_adminGetDurability(admin)); + message->senderAddress.systemId = addr->systemId; + message->senderAddress.localId = addr->localId; + message->senderAddress.lifecycleId = addr->lifecycleId; + message->addressee.systemId = unAddr->systemId; + message->addressee.localId = unAddr->localId; + message->addressee.lifecycleId = unAddr->lifecycleId; + message->productionTimestamp.seconds = 0l; + message->productionTimestamp.nanoseconds = 0ul; + /* Initialize bits 30 and 31 of the productionTimestamp according to the capabilities */ + if (config->capabilitySupport) { + message->productionTimestamp.nanoseconds = message->productionTimestamp.nanoseconds | (1ul << 31); + } + if (config->capabilityY2038Ready) { + message->productionTimestamp.nanoseconds = message->productionTimestamp.nanoseconds | (1ul << 30); + } + d_networkAddressFree(addr); + d_networkAddressFree(unAddr); + } +} + +void +d_messageSetAddressee( + d_message message, + d_networkAddress addressee) +{ + if(message){ + message->addressee.systemId = addressee->systemId; + message->addressee.localId = addressee->localId; + message->addressee.lifecycleId = addressee->lifecycleId; + } +} + +d_networkAddress +d_messageGetAddressee( + d_message message) +{ + d_networkAddress result; + + result = NULL; + + if (message) { + result = &(message->addressee); + } + + return result; +} + +void +d_messageSetSenderAddress( + d_message message, + d_networkAddress address) +{ + if(message){ + message->senderAddress.systemId = address->systemId; + message->senderAddress.localId = address->localId; + message->senderAddress.lifecycleId = address->lifecycleId; + } +} + + +void +d_messageDeinit( + d_message message) +{ + OS_UNUSED_ARG(message); + assert(message); + return; +} + +/** + * \brief Indicates whether the sender of the message indicates capability support + * + * Capability support is enabled if the most-significant byte of the nanoseconds + * field of the productionTimestamp is set. +*/ +c_bool +d_messageHasCapabilitySupport( + d_message message) +{ + c_bool result = FALSE; + + if (message) { + result = (((message->productionTimestamp.nanoseconds) & (1U << 31)) != 0); + } + return result; +} diff --git a/src/services/durability/code/d_misc.c b/src/services/durability/code/d_misc.c new file mode 100644 index 000000000..3f3dabc16 --- /dev/null +++ b/src/services/durability/code/d_misc.c @@ -0,0 +1,896 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#include "d__misc.h" +#include "d__durability.h" +#include "d__configuration.h" +#include "d__thread.h" +#include "d__admin.h" +#include "d__fellow.h" +#include "d__table.h" +#include "d__nameSpace.h" +#include "d__sampleChainListener.h" +#include "d__mergeAction.h" +#include "u_observable.h" +#include "v_entity.h" +#include "v_group.h" +#include "v_groupInstance.h" +#include "v_topic.h" +#include "v_partition.h" +#include "v_builtin.h" +#include "c_base.h" +#include "c_typebase.h" +#include "os_report.h" +#include "os_stdlib.h" +#include "os_abstract.h" + +const char *d_builtinTopics[] = { + V_TOPICINFO_NAME, + V_PARTICIPANTINFO_NAME, + V_PUBLICATIONINFO_NAME, + V_SUBSCRIPTIONINFO_NAME, + V_CMPARTICIPANTINFO_NAME, + V_CMDATAWRITERINFO_NAME, + V_CMDATAREADERINFO_NAME, + V_CMPUBLISHERINFO_NAME, + V_CMSUBSCRIBERINFO_NAME, + V_HEARTBEATINFO_NAME, + V_DELIVERYINFO_NAME, + NULL /* Must be the last element, used as delimiter */ +}; + +/** + * \brief The error codes and messages used in client durability. + * + * The errorCode is a 32-bit number. + * Bit number 23 is used as differentiator between a syntax error in + * the request and the server being unable to respond to a synatically + * correct message. + * + * Error code 0 indicates no error. + * Error codes 1 - 2^23-1 indicates a syntax error. + * Error codes 2^23 - 2^24-1 indicates a server error. + * Error codes 2^24 - 2^32-1 are reserved for future use. + */ +const struct error d_Error[] = { + /* no error */ + { D_DDS_RETCDE_NO_ERROR, "" }, + /* Syntax errors -- 1 - 8388607 (= 1 .. 2^23-1) */ + { D_DDS_RETCDE_INCOMPATIBLE_VERSION, "Incompatible version" }, + { D_DDS_RETCDE_NO_TOPIC, "topic is NULL"}, + { D_DDS_RETCDE_INVALID_START_TIME, "Invalid startTime" }, + { D_DDS_RETCDE_INVALID_END_TIME, "Invalid endTime" }, + { D_DDS_RETCDE_INVALID_TIME_RANGE, "startTime is later than endTime" }, + { D_DDS_RETCDE_INVALID_SERIAZATION, "Invalid serializationFormat" }, + { D_DDS_RETCDE_NO_PARTITIONS, "Empty 'partitions' field" }, + { D_DDS_RETCDE_INVALID_MAX_SAMPLES, "Invalid maxSamples" }, + { D_DDS_RETCDE_INVALID_MAX_INSTANCES, "Invalid maxInstances" }, + { D_DDS_RETCDE_INVALID_MAX_SAMPLES_PER_INSTANCE, "Invalid maxSamplesPerInstance" }, + /* Syntax OK, but server is not able process -- 8388608 - (= 2^23 - 2^24-1) - */ + { D_DDS_RETCDE_SERVER_IS_NOT_ALIGNER, "Server is not configured to be aligner for the requested dataset" }, + { D_DDS_RETCDE_SERVER_IS_NOT_RESPONSIBLE, "Request will be handled by a different durability service" }, + { D_DDS_RETCDE_READER_NOT_KNOWN, "The HistoricalDataReader(s) have not yet been dicovered by the server" }, + { D_DDS_RETCDE_NO_MASTER_SELECTED, "Currently a master has not been selected" }, + { D_DDS_RETCDE_GROUP_NOT_FOUND, "Currently no group found that match the request" }, + /* Currently unused ... 2^24 - 2^32-1 */ + { D_DDS_RETCDE_INVALID, "Invalid errorCode" } /* END-MARKER, MUST BE THE LAST ELEMENT */ +}; + + +char * +d_getErrorMessage( + c_ulong errorCode) +{ + c_ulong i=0; + char *msg = NULL; + c_bool cont = TRUE; + + while (cont) { + if ( (d_Error[i].errorCode == errorCode) || + (d_Error[i].errorCode == 4294967295) ) { + cont = FALSE; + msg = d_Error[i].errorMessage; + } + i++; + } + return msg; +} + + +#define D_TOTAL_KEYWORDS 12 +#define D_MIN_WORD_LENGTH 9 +#define D_MAX_WORD_LENGTH 16 +#define D_MIN_HASH_VALUE 9 +#define D_MAX_HASH_VALUE 27 +/* maximum key range = 19, duplicates = 0 */ + +#ifdef __GNUC__ +__inline +#else +#ifdef __cplusplus +inline +#endif +#endif +static unsigned int +hashBuiltinTopicNames (str, len) + register const char *str; + register unsigned int len; +{ + static const unsigned char asso_values[] = + { + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 15, 28, 28, 28, 28, 10, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 5, 0, 5, + 28, 28, 28, 28, 28, 0, 28, 28, 0, 28, + 5, 28, 0, 28, 5, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28 + }; + return len + asso_values[(unsigned char)str[6]]; +} + +const char * +d_inBuiltinTopicNames (str, len) + register const char *str; + register size_t len; +{ + /* Names of built-in topics are written here without using the defines + * as the hash function needs updating as well if the topic names change. + */ + static const char * const d_topicWordlist[] = + { + "", "", "", "", "", "", "", "", "", + "DCPSTopic", + "", + "CMPublisher", + "DCPSDelivery", + "CMParticipant", + "", + "DCPSPublication", + "DCPSSubscription", + "CMSubscriber", + "DCPSHeartbeat", + "", + "DCPSParticipant", + "DCPSCandMCommand", + "CMDataWriter", + "", "", "", "", + "CMDataReader" + }; + + if (len <= D_MAX_WORD_LENGTH && len >= D_MIN_WORD_LENGTH){ + unsigned int key = hashBuiltinTopicNames (str, (unsigned) len); + + if (key <= D_MAX_HASH_VALUE){ + register const char *s = d_topicWordlist[key]; + + if (*str == *s && !strcmp (str + 1, s + 1)) + return s; + } + } + return 0; +} + + +void +d_free ( + c_voidp allocated ) +{ + if (allocated) { + os_free(allocated); + } +} + +c_voidp +d_malloc ( + size_t size, + const char * errorText ) +{ + OS_UNUSED_ARG(errorText); + return os_malloc(size); +} + +static void +d_doPrint( + d_configuration config, + const char* format, + va_list args, + const char* header + ) +{ + char description[1024]; + + if(config->tracingOutputFile){ + os_vsnprintf(description, sizeof(description)-1, format, args); + description [sizeof(description)-1] = '\0'; + if (header != NULL) { + fprintf(config->tracingOutputFile, "%s%s", header, description); + } + else { + fprintf(config->tracingOutputFile, "%s", description); + } + fflush(config->tracingOutputFile); + + if (config->tracingSynchronous) { + os_fsync(config->tracingOutputFile); + } + } +} + + +void +d_printTimedEvent( + d_durability durability, + d_level level, + const char *format, + ...) +{ + va_list args; + d_configuration config; + char header[132]; + + config = d_durabilityGetConfiguration(durability); + + if (config && (((c_ulong)level) >= ((c_ulong)config->tracingVerbosityLevel))) + { + d_printState(durability, config, d_threadSelfName(), header); + va_start (args, format); + d_doPrint(config, format, args, header); + va_end (args); + } +} + +void +d_printEvent( + d_durability durability, + d_level level, + const char *format, + ...) +{ + va_list args; + d_configuration config; + + config = d_durabilityGetConfiguration(durability); + + if (config && (((c_ulong)level) >= ((c_ulong)config->tracingVerbosityLevel))) + { + va_start (args, format); + d_doPrint(config, format, args, NULL); + va_end (args); + } +} + +void +d_reportLocalGroup( + _In_ d_durability d, + _In_ _Const_ v_group group) +{ + const c_char* durability; + v_topicQos qos; + + qos = v_topicQosRef(group->topic); + switch(qos->durability.v.kind){ + case V_DURABILITY_VOLATILE: + durability = "VOLATILE"; + break; + case V_DURABILITY_TRANSIENT_LOCAL: + durability = "TRANSIENT LOCAL"; + break; + case V_DURABILITY_TRANSIENT: + durability = "TRANSIENT"; + break; + case V_DURABILITY_PERSISTENT: + durability = "PERSISTENT"; + break; + default: + durability = "<>"; + (void)durability; + assert(FALSE); + break; + } + + d_printTimedEvent(d, D_LEVEL_FINEST, + "Group found: %s.%s (%s)\n", + v_partitionName(v_groupPartition(group)), + v_topicName(v_groupTopic(group)), + durability); +} + + + +void +d_printState( + d_durability durability, + d_configuration config, + const char* threadName, + char* header) +{ + os_timeW time; + d_serviceState kind; + const c_char* state; + + if (config->tracingOutputFile) { + kind = d_durabilityGetState(durability); + + switch(kind){ + case D_STATE_INIT: + state = "INIT"; + break; + case D_STATE_DISCOVER_FELLOWS_GROUPS: + state = "DISCOVER_FELLOWS_GROUPS"; + break; + case D_STATE_DISCOVER_PERSISTENT_SOURCE: + state = "DISCOVER_PERSISTENT_SOURCE"; + break; + case D_STATE_INJECT_PERSISTENT: + state = "INJECT_PERSISTENT"; + break; + case D_STATE_DISCOVER_LOCAL_GROUPS: + state = "DISCOVER_LOCAL_GROUPS"; + break; + case D_STATE_FETCH_INITIAL: + state = "FETCH_INITIAL"; + break; + case D_STATE_FETCH: + state = "FETCH"; + break; + case D_STATE_ALIGN: + state = "ALIGN"; + break; + case D_STATE_FETCH_ALIGN: + state = "FETCH_ALIGN"; + break; + case D_STATE_COMPLETE: + state = "COMPLETE"; + break; + case D_STATE_TERMINATING: + state = "TERMINATING"; + break; + case D_STATE_TERMINATED: + state = "TERMINATED"; + break; + default: + state = "<>"; + break; + } + + if (config->tracingTimestamps == TRUE) { + os_char buf[OS_CTIME_R_BUFSIZE]; + time = os_timeWGet(); + if (config->tracingRelativeTimestamps == TRUE) { + /* relative timestamps, use the monotonic clock for timestamping log messages */ + os_duration delta = os_timeWDiff(time, config->startWTime); + time = os_timeWAdd(OS_TIMEW_ZERO, delta); + } + os_ctimeW_r(&time, buf, OS_CTIME_R_BUFSIZE); + os_sprintf(header, "%s %"PA_PRItime" %s (%s) -> ", + buf, OS_TIMEW_PRINT(time), state, threadName); + } else { + os_sprintf(header, "%s (%s) -> ", state, threadName); + } + } +} + +static void +d_findBaseAction( + v_public entity, + c_voidp args) +{ + struct baseFind* data; + + data = (struct baseFind*)args; + data->base = c_getBase(entity); +} + + +c_base +d_findBase( + d_durability durability) +{ + u_service service; + struct baseFind data; + + service = d_durabilityGetService(durability); + (void)u_observableAction(u_observable(service), d_findBaseAction, &data); + + return data.base; +} + +c_bool +d_patternMatch( + const char* str, + const char* pattern) +{ + c_value p,n,r; + + p.kind = n.kind = V_STRING; + p.is.String = (char *)pattern; + n.is.String = (char *)str; + r = c_valueStringMatch(p,n); + return r.is.Boolean; +} + + +c_bool +d_isBuiltinGroup( + _In_z_ _Const_ d_partition partition, + _In_z_ _Const_ d_topic topic) +{ + assert(partition); + assert(topic); + if(strcmp(partition, V_BUILTIN_PARTITION) != 0) { + return FALSE; + } else { + int i; + for (i = 0; d_builtinTopics[i] != NULL; i++) { + if (strcmp (topic, d_builtinTopics[i]) == 0) { + return TRUE; + } + } + return FALSE; + } +} + +c_bool +d_isHeartbeatGroup( + _In_z_ _Const_ d_partition partition, + _In_z_ _Const_ d_topic topic) +{ + if(strcmp(partition, V_BUILTIN_PARTITION) != 0) { + return FALSE; + } else if (strcmp(topic, V_HEARTBEATINFO_NAME) != 0) { + return FALSE; + } else { + return TRUE; + } +} + +c_bool +d_shmAllocAssert( + c_voidp ptr, + const char* errorMessage) +{ + if(ptr == NULL){ + if(errorMessage){ + d_printTimedEvent(d_threadsDurability(), D_LEVEL_SEVERE, errorMessage); + } + d_printTimedEvent(d_threadsDurability(), D_LEVEL_SEVERE, + "Unrecoverable error: shared memory allocation failed; terminating."); + OS_REPORT(OS_ERROR, D_CONTEXT_DURABILITY, 0, + "Unrecoverable error: shared memory allocation failed; terminating"); + d_durabilityTerminate(d_threadsDurability(), TRUE); + return FALSE; + } + return TRUE; +} + +c_bool +d_shmAllocAllowed(void) +{ + c_base base; + c_memoryThreshold status; + + base = d_findBase(d_threadsDurability()); + + if(base) { + status = c_baseGetMemThresholdStatus(base); + + if(status == C_MEMTHRESHOLD_SERV_REACHED){ + d_printTimedEvent(d_threadsDurability(), D_LEVEL_SEVERE, + "Unrecoverable error: service memory threshold reached; terminating."); + OS_REPORT(OS_ERROR, D_CONTEXT_DURABILITY, 0, + "Unrecoverable error: service memory threshold reached; terminating."); + d_durabilityTerminate(d_threadsDurability(), TRUE); + return FALSE; + } + } + return TRUE; +} + + +/** + * \brief Map a d_completeness value to a _DDS_Completeness_t + * value + * + * The durability service internaly uses d_completeness for the + * completeness of groups. Client-durability uses a _DDS_Completeness_t + * value. + */ +_DDS_Completeness_t +d_mapCompleteness( + d_completeness completeness) +{ + switch (completeness) { + case D_GROUP_KNOWLEDGE_UNDEFINED: + /* D_GROUP_KNOWLEDGE_UNDEFINED is used by durability to indicate + * that the group is not known + */ + return D_DDS_COMPLETENESS_UNKNOWN; + case D_GROUP_UNKNOWN: + case D_GROUP_INCOMPLETE: + /* D_GROUP_UNKNOWN and D_GROUP_INCOMPLETE are used by durability + * to indicate that the group is known but not yet complete + */ + return D_DDS_COMPLETENESS_INCOMPLETE; + case D_GROUP_COMPLETE: + /* D_GROUP_COMPLETE is used by durability to indicate that the + * group is complete + */ + return D_DDS_COMPLETENESS_COMPLETE; + default: + assert(FALSE); + return D_GROUP_KNOWLEDGE_UNDEFINED; + } +} + +unsigned short d_swap2uToBE (unsigned short x) +{ +#ifdef PA_LITTLE_ENDIAN + return (unsigned short) ((x >> 8) | (x << 8)); +#else + return x; +#endif +} + +unsigned d_swap4uToBE (unsigned x) +{ +#ifdef PA_LITTLE_ENDIAN + return (x >> 24) | ((x >> 8) & 0xff00) | ((x << 8) & 0xff0000) | (x << 24); +#else + return x; +#endif +} + + +unsigned long long d_swap8uToBE (unsigned long long x) +{ +#ifdef PA_LITTLE_ENDIAN + const unsigned newhi = d_swap4uToBE ((unsigned) x); + const unsigned newlo = d_swap4uToBE ((unsigned) (x >> 32)); + return ((unsigned long long) newhi << 32) | (unsigned long long) newlo; +#else + return x; +#endif +} + + +/** + * \brief Copy out function for c_sequence + * + * This function copies the sequence of string to + * an iter. + */ +c_bool +sequenceOfStringCopyOut( + c_iter *to, + const c_sequence from) +{ + c_ulong length, i; + size_t len; + c_string *fromStr, toStr; + c_bool result; + + assert(to); + + result = TRUE; + fromStr = (c_string*)from; + /* The generic copy routines do not always handle c_sequenceSize + * correctly, but luckily we can just as well use c_arraySize. + */ + length = c_arraySize(from); + for (i = 0; i < length; i++) { + len = strlen(fromStr[i]); + toStr = os_malloc(len+1); /* add '\0' */ + toStr = os_strncpy(toStr, fromStr[i], len); + toStr[len] = '\0'; + *to = c_iterAppend(*to, toStr); + } /* for */ + return result; +} + + +d_durabilityKind +d_durabilityKindFromKernel( + v_durabilityKind kind) +{ + switch(kind){ + case V_DURABILITY_VOLATILE: return D_DURABILITY_VOLATILE; + case V_DURABILITY_TRANSIENT_LOCAL: return D_DURABILITY_TRANSIENT_LOCAL; + case V_DURABILITY_TRANSIENT: return D_DURABILITY_TRANSIENT; + case V_DURABILITY_PERSISTENT: return D_DURABILITY_PERSISTENT; + } + assert(FALSE); + return D_DURABILITY_VOLATILE; +} + + +const char * +d_compressionKVImage( + d_compressionKV compression) +{ + const char *image; + switch (compression) { + case D_COMPRESSION_NONE: image = "none"; break; + case D_COMPRESSION_LZF: image = "lzf"; break; + case D_COMPRESSION_SNAPPY: image = "snappy"; break; + case D_COMPRESSION_ZLIB: image = "zlib"; break; + case D_COMPRESSION_CUSTOM: image = "custom"; break; + default: image = "(unknown)";break; + } + return image; +} + + +/* Prints trace messages in case the mask fits the trace settting. + * The messages are only printed when verbosity level is D_LEVEL_FINEST + */ +void +d_trace (c_ulong mask, const char *fmt, ...) +{ + d_configuration config; + d_durability durability = d_threadsDurability(); + + assert(d_durabilityIsValid(durability)); + + config = d_durabilityGetConfiguration(durability); + if ((config) && (mask & config->traceMask) && (config->tracingVerbosityLevel == D_LEVEL_FINEST)) { + char message[1024]; + va_list args; + + va_start(args, fmt); + (void)os_vsnprintf(message, sizeof(message)-1, fmt, args); + va_end(args); + message[sizeof(message)-1] = '\0'; + d_printTimedEvent(durability, D_LEVEL_FINEST, "[0x%08lx] %s", mask & config->traceMask, message); + } +} + + + +void d_tracegroupGenKeystr(char *keystr, size_t keystr_size, v_groupInstance gi) +{ + d_durability durability = d_threadsDurability(); + d_configuration config = d_durabilityGetConfiguration(durability); + if (config && (config->traceMask & D_TRACE_GROUP)) { + v_groupInstanceKeyToString(gi, keystr, keystr_size); + } +} + +void d_tracegroupGenMsgKeystr(char *keystr, size_t keystr_size, v_group g, v_message msg) +{ + d_durability durability = d_threadsDurability(); + d_configuration config = d_durabilityGetConfiguration(durability); + if (config && (config->traceMask & D_TRACE_GROUP)) { + c_array messageKeyList = v_topicMessageKeyList(v_groupTopic(g)); + c_ulong i, nrOfKeys = c_arraySize(messageKeyList); + size_t pos = 0; + assert (keystr_size >= 4); /* for ...\0 */ + for (i = 0; i < nrOfKeys; i++) + { + c_value v = c_fieldValue(messageKeyList[i], msg); + char *vimg = c_valueImage(v); + int n = snprintf(keystr + pos, keystr_size - pos, "%s%s", (i == 0) ? "" : ";", vimg); + c_valueFreeRef(v); + os_free(vimg); + if (n > 0) { pos += (size_t)n; } else { break; } + } + if (i < nrOfKeys || pos >= keystr_size) { + if (pos >= keystr_size - 4) { + pos = keystr_size - 4; + } + strcpy(keystr + pos, "..."); + } + } +} + +void d_tracegroupInstance(v_groupInstance gi, d_durability durability, const char *prefix) +{ + d_configuration config = d_durabilityGetConfiguration(durability); + + if (config && (config->traceMask & D_TRACE_GROUP)) { + v_groupSample s; + char keystr[1024]; + d_tracegroupGenKeystr(keystr, sizeof (keystr), gi); + d_trace(D_TRACE_GROUP, "%sInstance %p state=%u epoch=%"PA_PRItime" key={%s}\n", prefix, (void*)gi, gi->state, OS_TIMEE_PRINT(gi->epoch), keystr); + s = v_groupSample(gi->oldest); + while (s != NULL) { + v_message msg = v_groupSampleTemplate(s)->message; + d_trace(D_TRACE_GROUP, "%s Sample %p msg %p state=%u time=%"PA_PRItime" wrgid=%u:%u:%u\n", + prefix, (void*)s, (void*)msg, msg->_parent.nodeState, OS_TIMEW_PRINT(msg->writeTime), msg->writerGID.systemId, msg->writerGID.localId, msg->writerGID.serial); + s = s->newer; + } + } +} + +static c_bool tracegroupHelper(c_object obj, void *durability) +{ + d_tracegroupInstance ((v_groupInstance)obj, durability, " "); + return 1; +} + + +void d_tracegroup(d_durability durability, v_group g, const char *info) +{ + d_configuration config = d_durabilityGetConfiguration(durability); + + if (config && (config->traceMask & D_TRACE_GROUP)) { + d_trace(D_TRACE_GROUP, "Group %s.%s lastDisposeAllTime=%"PA_PRItime" - %s\n", + v_partitionName(v_groupPartition(g)), v_topicName(v_groupTopic(g)), OS_TIMEW_PRINT(g->lastDisposeAllTime), info); + v_groupWalkInstances(g, tracegroupHelper, durability); + } +} + +os_compare +d_qualityCompare( + d_quality q1, + d_quality q2) +{ + /* Quality is internally modelled as an os_timeW */ + return os_timeWCompare(q1, q2); +} + + +void +d_timestampFromTimeW(d_timestamp *t1, os_timeW *t2, c_bool Y2038Ready) +{ + assert(t1 && t2); + + if (Y2038Ready) { + t1->seconds = (c_long)((OS_TIMEW_GET_VALUE(*t2)) >> 32); + t1->nanoseconds = (c_ulong)((OS_TIMEW_GET_VALUE(*t2) & 0xFFFFFFFFU)); + } else { + *t1 = c_timeFromTimeW(*t2); + } +} + + +void +d_timestampToTimeW(os_timeW *t1, d_timestamp *t2, c_bool Y2038Ready) +{ + assert(t1 && t2); + + if (Y2038Ready) { + *t1 = OS_TIMEW_INIT(0, ((os_uint64)((t2->seconds)) << 32) | (os_uint64)(t2->nanoseconds)); + } else { + *t1 = c_timeToTimeW(*t2); + } +} + + +void +d_qualityExtFromQuality(d_qualityExt *q1, d_quality *q2, c_bool Y2038Ready) +{ + /* quality is an os_timeW and qualityExt is a d_timestamp, + * so we can use d_timestampFromTimeW + */ + d_timestampFromTimeW(q1, q2, Y2038Ready); +} + + +void +d_qualityExtToQuality(d_quality *q1, d_qualityExt *q2, c_bool Y2038Ready) +{ + /* qualityExt is a d_timestamp and quality is a os_timeW, + * so we can use d_timestampToTimeW + */ + d_timestampToTimeW(q1, q2, Y2038Ready); +} + + +void +d_productionTimestampToSeqnum(os_uint32 *seqnum, d_timestamp *t) +{ + if ((t->nanoseconds) & (1U << 30)) { + /* Bit 30 of the nanoseconds fields is set so interpret + * the seconds field as a sequence number + */ + *seqnum = (os_uint32)(t->seconds); + } else { + /* No sequence number support, use 0 as sequence number + * to ensure that message are always processed + */ + *seqnum = (os_uint32)0; + } +} + +void +d_productionTimestampFromSeqnum(d_timestamp *t, os_uint32 *seqnum) +{ + if (t->nanoseconds & (1ul << 30)) { + /* Sequence numbers are supported. + * Fill the seconds field of the productionTimestamp + * with the sequence number. The nanoseconds field + * remains unchanged + */ + t->seconds = (c_long)(*seqnum); + } else { + /* No support for sequence numbers. + * Fill the productionTimestamp with the elapsed time + * while retaining the flags. + * NOTE: because seconds are casted to as c_long + * they may not exceed 0x7FFFFFFF. Effectively, this + * means that a node must reboot every 68 years . + */ + os_timeE t1 = os_timeEGet(); + os_uint32 flags = t->nanoseconds & ((1u << 31) | (1u << 30)); + t->seconds = (c_long)OS_TIMEE_GET_SECONDS(t1); + t->nanoseconds = OS_TIMEE_GET_NANOSECONDS(t1); + /* Restore the flags */ + t->nanoseconds = t->nanoseconds | flags; + } +} + +/* Calculate the corresponding elapsed time from a wall clock time. + * + */ +os_timeE +d_timeWToTimeE(os_timeW t) +{ + os_duration d; + os_timeE te; + + d = os_timeWDiff(os_timeWGet(), t); + te = os_timeEAdd(os_timeEGet(), d); + return te; +} + +void d_traceMergeAction (d_mergeAction mergeAction, const char *info) +{ + char str[1024]; + d_tableIter tableIter; + d_fellow fellow; + size_t pos = 0; + d_chain chain; + + /* determine the list of fellows to be addressed */ + str[0] = '\0'; + fellow = d_fellow(d_tableIterFirst(mergeAction->fellows, &tableIter)); + while (fellow) { + int n = snprintf(str + pos, sizeof(str) - pos, "%s%u", (strcmp(str, "") == 0) ? "" : ",", fellow->address->systemId); + if (n > 0) { pos += (size_t)n; } else { break; } + fellow = d_fellow(d_tableIterNext(&tableIter)); + } + /* print the contents of the queue before */ + d_trace(D_TRACE_CHAINS, "%s: merge action %p, conflict %u, nameSpace %s, fellows [%s]\n", + info, (void *)mergeAction, mergeAction->conflict->id, mergeAction->nameSpace->name, str); + + chain = d_chain(d_tableIterFirst(mergeAction->chains, &tableIter)); + while (chain) { + d_traceChain(chain); + chain = d_chain(d_tableIterNext(&tableIter)); + } +} + diff --git a/src/services/durability/code/d_nameSpace.c b/src/services/durability/code/d_nameSpace.c new file mode 100644 index 000000000..e7cdde3d7 --- /dev/null +++ b/src/services/durability/code/d_nameSpace.c @@ -0,0 +1,1504 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#include + +#include "d__misc.h" +#include "d__table.h" +#include "d__admin.h" +#include "d__nameSpace.h" +#include "d__configuration.h" +#include "d__policy.h" +#include "d__element.h" +#include "d__nameSpaces.h" +#include "d_nameSpaces.h" +#include "d_networkAddress.h" +#include "d__mergeState.h" +#include "d__thread.h" +#include "d__durability.h" +#include "os_report.h" +#include "os_stdlib.h" + + +/************************************************************** + * Private functions + **************************************************************/ + +/* PRE: partition and topic are correct values */ +static void +d_nameSpaceAddPartitionTopic( + d_nameSpace nameSpace, + const char * name, + const char * partition, + const char * topic ) +{ + d_element element; + d_element found; + + element = d_elementNew(name, partition, topic); + if (element) { + found = d_tableInsert(nameSpace->elements, element); + if (found) { + d_elementFree(element); /* this was not unique */ + } + } +} + + +/**************************************************************/ + +static c_bool +nameSpaceIsIn( + c_object object, + c_voidp actionArg ) +{ + c_bool continueTheSearch; + d_element element; + d_nameSpaceSearch nameSpaceSearch; + + continueTheSearch = TRUE; + nameSpaceSearch = (d_nameSpaceSearch)actionArg; + element = d_element(object); + + if (d_patternMatch(nameSpaceSearch->partition, element->partition) && + d_patternMatch(nameSpaceSearch->topic, element->topic)){ + nameSpaceSearch->match = TRUE; + continueTheSearch = FALSE; + } + return continueTheSearch; +} + +/**************************************************************/ + +static c_bool +isANameSpace( + d_nameSpace nameSpace ) +{ + return d_objectIsValid(d_object(nameSpace), D_NAMESPACE); +} + +/************************************************************** + * Public functions + **************************************************************/ + +int +d_nameSpaceCompare( + d_nameSpace ns1, + d_nameSpace ns2) +{ + int r; + c_char* partitions1; + c_char* partitions2; + d_policy p1; + d_policy p2; + + + + if((!ns1) && (!ns2)){ + r = 0; + } else if(!ns1){ + r = -1; + } else if(!ns2){ + r = 1; + }else + { + r = strcmp(ns1->name, ns2->name); + if (r == 0) + { + p1 = ns1->policy; + p2 = ns2->policy; + + if (p1->aligner && !(p2->aligner)){ + r = 1; + }else if (!(p1->aligner) && p2->aligner){ + r = -1; + }else if(p1->alignmentKind != p2->alignmentKind){ + if(((c_ulong)p1->alignmentKind) > ((c_ulong)p2->alignmentKind)){ + r = 1; + } else { + r = -1; + } + } else if(p1->durabilityKind != p2->durabilityKind) { + if(((c_ulong)p1->durabilityKind) > ((c_ulong)p2->durabilityKind)){ + r = 1; + } else { + r = -1; + } + } else if((!ns1->elements) && (!ns2->elements)){ + r = 0; + } else if(!ns1->elements){ + r = -1; + } else if(!ns2->elements){ + r = 1; + } else { + partitions1 = d_nameSpaceGetPartitions(ns1); + partitions2 = d_nameSpaceGetPartitions(ns2); + r = strcmp(partitions1, partitions2); + os_free(partitions1); + os_free(partitions2); + } + } + } + + return r; +} + + +static int +d_nameSpaceCompareFull( + d_nameSpace ns1, + d_nameSpace ns2) +{ + int r = 0; + d_element wc = d_elementNew("wildcards", "*", "*"); + d_element e1 = d_tableFind(ns1->elements, wc); + d_element e2 = d_tableFind(ns2->elements, wc); + + d_elementFree(wc); + + if (e1 && e2) { + r = 0; + } else if (e1) { + r = 1; + } else if (e2) { + r = -1; + } else { + c_ulong l1, l2; + + l1 = d_tableSize(ns1->elements); + l2 = d_tableSize(ns2->elements); + + if (l1 < l2) { + r = -1; + } else if (l1 > l2) { + r = 1; + } else { + d_table t = d_tableNew(d_elementCompare, NULL); + d_tableIter tableIter; + d_element e; + + e = d_tableIterFirst(ns1->elements, &tableIter); + while (e) { + d_tableInsert(t, e); + e = d_tableIterNext(&tableIter); + } + + e = d_tableIterFirst(ns2->elements, &tableIter); + while (e && !r) { + if (!d_tableInsert(t, e)) { + r = 1; + } + e = d_tableIterNext(&tableIter); + } + + d_tableFree(t); + } + } + + return r; +} + + +int +d_nameSpaceCompatibilityCompare( + d_nameSpace ns1, + d_nameSpace ns2) +{ + int r; + c_char* partitions1; + c_char* partitions2; + + if((!ns1) && (!ns2)){ + r = 0; + } else if(!ns1){ + r = -1; + } else if(!ns2){ + r = 1; + } + else if((!ns1->elements) && (!ns2->elements)){ + r = 0; + } else if(!ns1->elements){ + r = -1; + } else if(!ns2->elements){ + r = 1; + } else { + partitions1 = d_nameSpaceGetPartitionTopics(ns1); + partitions2 = d_nameSpaceGetPartitionTopics(ns2); + r = strcmp(partitions1, partitions2); + os_free(partitions1); + os_free(partitions2); + if (r != 0) { + r = d_nameSpaceCompareFull(ns1, ns2); + } + } + return r; +} + +int +d_nameSpaceNameCompare( + d_nameSpace ns1, + d_nameSpace ns2) +{ + int r; + + if((!ns1) && (!ns2)){ + r = 0; + } else if(!ns1){ + r = -1; + } else if(!ns2){ + r = 1; + } else if((!ns1->name) && (!ns2->name)){ + r = 0; + } else if(!ns1->name){ + r = -1; + } else if(!ns2->name){ + r = 1; + } else { + r = strcmp(ns1->name, ns2->name); + } + return r; +} + +struct d_nsCompare { + d_nameSpace ns1; + d_nameSpace ns2; + d_nsEquality equality; +}; + +char * +d_nameSpaceGetName( + d_nameSpace nameSpace ) +{ + char * name; + + name = NULL; + if (isANameSpace(nameSpace)) { + name = nameSpace->name; + } + return name; +} + +c_bool +d_nameSpaceGetDelayedAlignment( + d_nameSpace nameSpace) +{ + c_bool result; + + result = FALSE; + + if (isANameSpace(nameSpace)) { + if(nameSpace->policy) { + result = nameSpace->policy->delayedAlignment; + } + } + + return result; +} + +d_policy +d_nameSpaceGetPolicy( + d_nameSpace nameSpace ) +{ + d_policy policy; + + policy = NULL; + + if (isANameSpace(nameSpace)) { + policy = nameSpace->policy; + } + return policy; +} + +c_bool +d_nameSpaceIsAligner( + d_nameSpace nameSpace) +{ + c_bool result = FALSE; + + if (isANameSpace(nameSpace)) { + result = d_policyGetAligner(nameSpace->policy); + } + return result; +} + +d_alignmentKind +d_nameSpaceGetAlignmentKind( + d_nameSpace nameSpace) +{ + d_alignmentKind kind = D_ALIGNEE_INITIAL; + + if (isANameSpace(nameSpace)) { + kind = d_policyGetAlignmentKind (nameSpace->policy); + } + return kind; +} + + +c_bool +d_nameSpaceIsAlignmentNotInitial( + d_nameSpace nameSpace) +{ + c_bool notInitial; + d_alignmentKind alignmentKind; + + alignmentKind = d_policyGetAlignmentKind (nameSpace->policy); + + if (isANameSpace(nameSpace)) { + switch(alignmentKind){ + case D_ALIGNEE_INITIAL: + notInitial = FALSE; + break; + case D_ALIGNEE_LAZY: + /* fallthrough intentional */ + case D_ALIGNEE_ON_REQUEST: + notInitial = TRUE; + break; + default: + OS_REPORT(OS_ERROR, D_CONTEXT, 0, + "Unknown alignment kind '%d' found", + alignmentKind); + notInitial = FALSE; + assert(FALSE); + break; + } + } else { + notInitial = FALSE; + } + return notInitial; +} + +d_durabilityKind +d_nameSpaceGetDurabilityKind( + d_nameSpace nameSpace) +{ + d_durabilityKind kind = D_DURABILITY_ALL; + + if (isANameSpace(nameSpace)) { + kind = d_policyGetDurabilityKind (nameSpace->policy); + } + return kind; +} + +/**************************************************************/ + +/* EXPECTING: + * - (partitionTopic = .) AND (topicGiven == NULL) + * OR + * - (partitionTopic = ) AND (topicGiven = ) + * + * both and may contain wildcards ('?' or'*') + */ +int +d_nameSpaceAddElement( + d_nameSpace nameSpace, + const char * name, + const char * partitionTopic, + const char * topicGiven ) +{ + char * partition; + char * topic; + os_uint32 strlenPartitionTopic; + os_uint32 strlenTopicGiven; + + /* QAC EXPECT 1253; */ + strlenPartitionTopic = (os_uint32) (strlen(partitionTopic) + 1); + if (isANameSpace(nameSpace)) { + /* QAC EXPECT 1253; */ + if (strlenPartitionTopic < D_MAX_STRLEN_NAMESPACE) { + if (topicGiven) { + /* QAC EXPECT 1253; */ + strlenTopicGiven = (os_uint32) (strlen(topicGiven) + 1); + /* QAC EXPECT 1253; */ + if (strlenTopicGiven < D_MAX_STRLEN_NAMESPACE) { + d_nameSpaceAddPartitionTopic(nameSpace, name, partitionTopic, topicGiven); + } + } else { + partition = (char *)d_malloc(strlenPartitionTopic, "Partition"); + if (partition) { + os_strncpy(partition, partitionTopic, strlenPartitionTopic); + /* Make topic point to last character in partition string. + * partition points to first character and strlenPartitionTopic + * includes '\0', so subtract 2 to point to last character. + */ + topic = partition + (strlenPartitionTopic-2); + + /* QAC EXPECT 2106,3123; */ + while ((*topic != '.') && (topic != partition)) { + /* QAC EXPECT 0489; */ + topic--; + } + /* QAC EXPECT 2106,3123; */ + if (*topic == '.') { + *topic = 0; + /* QAC EXPECT 0489; */ + topic++; + /* QAC EXPECT 2106; */ + if (*topic != 0) { + d_nameSpaceAddPartitionTopic(nameSpace, name, partition, topic); + } + else + { + d_free(partition); + return -1; + } + } else { + /* Though was used in the definition of a namespace, only + * a partition is provided. + */ + d_nameSpaceAddPartitionTopic(nameSpace, name, partition, "*"); + } + d_free(partition); + } + } + } + else + { + OS_REPORT(OS_ERROR, D_CONTEXT, 0, "//OpenSplice/DurabilityService/NameSpaces/NameSpace/PartitionTopic length is too long"); + return -1; + } + } + + return 0; +} + +/**************************************************************/ + +c_bool +d_nameSpaceIsEmpty( + d_nameSpace nameSpace ) +{ + c_bool empty = TRUE; + + if (isANameSpace(nameSpace)) { + if(d_tableSize(nameSpace->elements)) { + empty = FALSE; + } + } + return empty; +} + +/**************************************************************/ + +c_bool +d_nameSpaceIsIn( + d_nameSpace nameSpace, + d_partition partition, + d_topic topic ) +{ + c_bool match; + C_STRUCT(d_nameSpaceSearch) nameSpaceSearch; + + match = FALSE; + if (isANameSpace(nameSpace)) { + nameSpaceSearch.match = FALSE; + nameSpaceSearch.partition = partition; + nameSpaceSearch.topic = topic; + d_tableWalk(nameSpace->elements, nameSpaceIsIn, &nameSpaceSearch); + match = nameSpaceSearch.match; + } + return match; +} + +/**************************************************************/ + +void +d_nameSpaceDeinit( + d_nameSpace nameSpace) +{ + assert(d_nameSpaceIsValid(nameSpace)); + + if (nameSpace->master) { + d_networkAddressFree(nameSpace->master); + nameSpace->master = NULL; + } + if (nameSpace->elements) { + d_tableFree(nameSpace->elements); /* frees all */ + nameSpace->elements = NULL; + } + if (nameSpace->mergedRoleStates) { + d_tableFree(nameSpace->mergedRoleStates); + nameSpace->mergedRoleStates = NULL; + } + if (nameSpace->mergeState) { + d_mergeStateFree (nameSpace->mergeState); + nameSpace->mergeState = NULL; + } + if (nameSpace->advertisedMergeState) { + d_mergeStateFree (nameSpace->advertisedMergeState); + nameSpace->advertisedMergeState = NULL; + } + if (nameSpace->name) { + d_free(nameSpace->name); + nameSpace->name = NULL; + } + if (nameSpace->policy) { + d_policyFree(nameSpace->policy); + nameSpace->policy = NULL; + } + /* Call super-deinit */ + d_lockDeinit(d_lock(nameSpace)); +} + +void +d_nameSpaceFree( + d_nameSpace nameSpace) +{ + /* Note: This function can be called with a NULL-nameSpace */ + if (isANameSpace(nameSpace)) { + d_objectFree(d_object(nameSpace)); + } +} + +/**************************************************************/ +d_nameSpace +d_nameSpaceNew( + const char * name, + d_policy policy) +{ + d_nameSpace nameSpace = NULL; + d_durability durability; + d_configuration config; + + assert(name); + + durability = d_threadsDurability(); + config = d_durabilityGetConfiguration(durability); + + if ((policy == NULL) || + (!d_patternMatch(name, d_policyGetNameSpace(policy)))) { + return NULL; + } + + assert(d_policyIsValid(policy)); + + nameSpace = d_nameSpace(d_malloc(C_SIZEOF(d_nameSpace), "NameSpace")); + /* Call super-init */ + d_lockInit(d_lock(nameSpace), D_NAMESPACE, + (d_objectDeinitFunc)d_nameSpaceDeinit); + /* Initialize namespace */ + nameSpace->name = os_strdup(name); + nameSpace->policy = d_policy(d_objectKeep(d_object(policy))); + nameSpace->elements = d_tableNew(d_elementCompare, d_elementFree); + nameSpace->quality = D_QUALITY_ZERO; + nameSpace->master = d_networkAddressUnaddressed(); + nameSpace->masterState = D_STATE_COMPLETE; + nameSpace->masterConfirmed = FALSE; + nameSpace->alignable = d_policyGetAligner(policy) ? TRUE : FALSE; + nameSpace->mustAlignBuiltinTopics = config->mustAlignBuiltinTopics; + nameSpace->mergeState = d_mergeStateNew(config->role, config->initialMergeStateValue); + nameSpace->advertisedMergeState = d_mergeStateNew(config->role, config->initialMergeStateValue); + nameSpace->mergedRoleStates = d_tableNew(d_mergeStateCompare, d_mergeStateFree); + nameSpace->compatibility_check_required = TRUE; + nameSpace->mergeCount = 0; + + return nameSpace; +} + +static c_bool +insertMergeState( + d_mergeState state, + d_table table) +{ + d_tableInsert(table, d_mergeStateNew(state->role, state->value)); + return TRUE; +} + +d_nameSpace +d_nameSpaceCopy( + d_nameSpace ns) +{ + d_nameSpace nameSpace; + + /* Allocate nameSpace object */ + nameSpace = d_nameSpace(d_malloc(C_SIZEOF(d_nameSpace), "NameSpace")); + if (nameSpace != NULL) { + /* Call super-init */ + d_lockInit(d_lock(nameSpace), D_NAMESPACE, + (d_objectDeinitFunc)d_nameSpaceDeinit); + /* Initialize namespace */ + d_objectKeep (d_object(ns->policy)); + d_objectKeep (d_object(ns->elements)); + nameSpace->name = os_strdup(ns->name); + nameSpace->policy = ns->policy; + nameSpace->elements = ns->elements; + nameSpace->quality = ns->quality; + nameSpace->master = d_networkAddressNew(ns->master->systemId, ns->master->localId, + ns->master->lifecycleId); + nameSpace->masterState = ns->masterState; + nameSpace->masterConfirmed = ns->masterConfirmed; + nameSpace->alignable = ns->alignable; + nameSpace->mergeState = d_mergeStateNew(ns->mergeState->role, ns->mergeState->value); + if (ns->advertisedMergeState) { + nameSpace->advertisedMergeState = d_mergeStateNew(ns->advertisedMergeState->role, ns->advertisedMergeState->value); + } else { + nameSpace->advertisedMergeState = NULL; + } + nameSpace->mergedRoleStates = d_tableNew(d_mergeStateCompare, d_mergeStateFree); + d_tableWalk(ns->mergedRoleStates, insertMergeState, nameSpace->mergedRoleStates); + nameSpace->compatibility_check_required = ns->compatibility_check_required; + nameSpace->mustAlignBuiltinTopics = ns->mustAlignBuiltinTopics; + nameSpace->mergeCount = ns->mergeCount; + } + return nameSpace; +} + +void +d_nameSpaceReplaceMergeStates( + d_nameSpace ns1, + d_nameSpace ns2) +{ + d_tableFree (ns1->mergedRoleStates); + + ns1->mergedRoleStates = d_tableNew(d_mergeStateCompare, d_mergeStateFree); + d_tableWalk(ns2->mergedRoleStates, insertMergeState, ns1->mergedRoleStates); +} + +d_nameSpace +d_nameSpaceFromNameSpaces( + d_configuration config, + d_nameSpaces ns) +{ + d_nameSpace nameSpace = NULL; + c_char *partitionTopics, *partitionTopic, *partition, *topic, *savePtr; + c_bool aligner; + d_alignmentKind alignmentKind; + d_durabilityKind durabilityKind; + os_uint32 i; + int count; + const struct d_mergeState_s *ms; + c_ulong masterPriority = D_DEFAULT_MASTER_PRIORITY; + + if(ns){ + /* Allocate nameSpace */ + nameSpace = d_nameSpace(d_malloc(C_SIZEOF(d_nameSpace), "NameSpace")); + if(nameSpace != NULL){ + /* Call super-init */ + d_lockInit(d_lock(nameSpace), D_NAMESPACE, + (d_objectDeinitFunc)d_nameSpaceDeinit); + + aligner = d_nameSpacesIsAligner(ns); + alignmentKind = d_nameSpacesGetAlignmentKind(ns); + durabilityKind = d_nameSpacesGetDurabilityKind(ns); + + if (d_nameSpacesGetName(ns)) { + nameSpace->name = os_strdup(d_nameSpacesGetName(ns)); + }else { + nameSpace->name = NULL; /* LH: This should never happen!!!! */ + } + + /* mergedStates can contain name-value pairs beyond mergedStatesCount + * these name-value pairs are no mergedStates and thus have to be + * parsed separately. + */ + ms = (const struct d_mergeState_s *) ns->mergedStates; + for (i=ns->mergedStatesCount; imergedStates); i++) { + if (ms[i].role) { + if (strcmp(ms[i].role, "masterPriority") == 0) { + masterPriority = ms[i].value; + } + } + } + + nameSpace->policy = d_policyNew ( + NULL, + aligner, + alignmentKind, + FALSE, + durabilityKind, + D_DEFAULT_EQUALITY_CHECK, + masterPriority); + nameSpace->quality = d_nameSpacesGetInitialQuality(ns); + nameSpace->master = d_networkAddressNew( + ns->master.systemId, + ns->master.localId, + ns->master.lifecycleId); + nameSpace->masterState = D_STATE_COMPLETE; + nameSpace->elements = d_tableNew(d_elementCompare, d_elementFree); + nameSpace->mustAlignBuiltinTopics = config->mustAlignBuiltinTopics; + nameSpace->compatibility_check_required = TRUE; + nameSpace->mergeCount = 0; + + partitionTopics = d_nameSpacesGetPartitions(ns); + + /* Legacy versions of the product send a comma-separated list of partitions wheras + * newer versions of the product send a comma-separated list of partition-topic + * combinations where the partition and topic are separated by a '.'. In the former + * case one should interpret the topic expression to be '*'. Additionally, new + * versions only send the partition-expression in case the topic-expression is + * '*' for backwards compatibility reasons. Obviously, the topic-expression + * needs to be interpreted as '*' in that case as well. + */ + partitionTopic = os_strtok_r(partitionTopics, ",", &savePtr); + + while(partitionTopic){ + /* Allocate worst-case sizes for partition and topic expression. */ + partition = os_malloc(strlen(partitionTopic) + 1); + topic = os_malloc(strlen(partitionTopic) + 1); + + if (partition && topic) { + + if(strlen(partitionTopic) == 0){ + /* This means that the default partition (empty string) + * has been configured, without any topic expression + * (leads to "*" as topic expression). + */ + os_sprintf(partition, ""); + os_sprintf(topic, "*"); + + } else if((strlen(partitionTopic) > 0) && (partitionTopic[0] == '.')){ + /* To ensure matching of the default partition (empty + * string) check if expression starts with a dot. If + * that is the case, use empty string as partition and + * strip the dot of the string and interpret the rest as + * the topic expression. + */ + os_sprintf(partition, ""); + os_sprintf(topic, "%s", &partitionTopic[1]); + } else { + /* Match partition and topic parts of the expression.*/ + count = sscanf(partitionTopic, "%[^.].%[^.]", partition, topic); + + /* The partition-topic expression may not have a topic part and + * in that case will not contain a '.' character. The count + * will then be 1. Use '*' as topic-expression in that + * case. + */ + if(count < 2){ + os_sprintf(topic, "*"); + + /* In case count is less than 1, no partition could be + * found either. Match all partitions in that case by + * using '*'. + */ + if(count < 1){ + os_sprintf(partition, "*"); + } + } + } + d_nameSpaceAddElement(nameSpace, "element", partition, topic); + } + os_free(partition); + os_free(topic); + + partitionTopic = os_strtok_r(NULL, ",", &savePtr); + } + os_free(partitionTopics); + + nameSpace->masterConfirmed = ns->masterConfirmed; + + nameSpace->alignable = aligner; + + /* Add merge state for own role */ + nameSpace->mergeState = d_mergeStateNew (ns->state.role, 0); + /* Note that it is NOT necessary to maintain a dedicated advertisedMergeState + * for fellows, because the mergeState in the ns message already contains the + * advertisedMergeState of a fellow. For now we will set the advertisedMergeState + * attribute of fellow namespaces explicitly to NULL. + */ + nameSpace->advertisedMergeState = NULL; + + /* Add merge states for other roles */ + nameSpace->mergedRoleStates = d_tableNew(d_mergeStateCompare, d_mergeStateFree); + d_nameSpaceSetMergeState(nameSpace, &(ns->state)); + for(i=0; imergedStatesCount; i++){ + d_nameSpaceSetMergeState(nameSpace, &((d_mergeState)(ns->mergedStates))[i]); + } + } + } + return nameSpace; +} + +void +d_nameSpaceSetMasterState( + d_nameSpace nameSpace, + d_serviceState serviceState) +{ + if (isANameSpace(nameSpace)) { + d_lockLock(d_lock(nameSpace)); + nameSpace->masterState = serviceState; + d_lockUnlock(d_lock(nameSpace)); + } + return; +} + +d_serviceState +d_nameSpaceGetMasterState( + d_nameSpace nameSpace) +{ + d_serviceState masterState; + + masterState = D_STATE_INIT; + + if (isANameSpace(nameSpace)) { + d_lockLock(d_lock(nameSpace)); + masterState = nameSpace->masterState; + d_lockUnlock(d_lock(nameSpace)); + } + + return masterState; +} + +void +d_nameSpaceSetMaster( + d_nameSpace nameSpace, + d_networkAddress master) +{ + if (isANameSpace(nameSpace)) { + d_lockLock(d_lock(nameSpace)); + d_networkAddressFree(nameSpace->master); + nameSpace->master = d_networkAddressNew(master->systemId, master->localId, + master->lifecycleId); + d_lockUnlock(d_lock(nameSpace)); + } + return; +} + +d_networkAddress +d_nameSpaceGetMaster( + d_nameSpace nameSpace) +{ + d_networkAddress addr = NULL; + + if (isANameSpace(nameSpace)) { + d_lockLock(d_lock(nameSpace)); + addr = d_networkAddressNew( nameSpace->master->systemId, + nameSpace->master->localId, + nameSpace->master->lifecycleId); + d_lockUnlock(d_lock(nameSpace)); + } + return addr; +} + +void +d_nameSpaceMasterConfirmed( + d_nameSpace nameSpace) +{ + if (isANameSpace(nameSpace)) { + d_lockLock (d_lock(nameSpace)); + nameSpace->masterConfirmed = TRUE; + d_lockUnlock(d_lock(nameSpace)); + } +} + +void +d_nameSpaceMasterPending( + d_nameSpace nameSpace) +{ + if (isANameSpace(nameSpace)) { + d_lockLock (d_lock(nameSpace)); + nameSpace->masterConfirmed = FALSE; + d_lockUnlock(d_lock(nameSpace)); + } +} + + +void +d_nameSpaceSetMasterConfirmed( + d_nameSpace nameSpace, + c_bool masterConfirmed) +{ + if (isANameSpace(nameSpace)) { + d_lockLock (d_lock(nameSpace)); + nameSpace->masterConfirmed = masterConfirmed; + d_lockUnlock(d_lock(nameSpace)); + } +} + + +c_bool +d_nameSpaceIsMasterConfirmed( + d_nameSpace nameSpace) +{ + c_bool masterConfirmed; + + masterConfirmed = FALSE; + if (isANameSpace (nameSpace)) { + masterConfirmed = nameSpace->masterConfirmed; + } + + return masterConfirmed; +} + +c_bool +d_nameSpaceMasterIsMe( + d_nameSpace nameSpace, + d_admin admin) +{ + c_bool result; + d_networkAddress myAddr, master; + + if (isANameSpace(nameSpace)) { + myAddr = d_adminGetMyAddress(admin); + master = d_nameSpaceGetMaster(nameSpace); + if (master) { + /* A master has been found. */ + result = d_networkAddressEquals(myAddr, master); + } else { + /* No master found for the namespace. + * This situation can occur when at some point + * in time a master has left the network, and + * the only remaining nodes use the property + * 'aligner="false"' for the namespace. + */ + result = FALSE; + } + d_networkAddressFree(myAddr); + d_networkAddressFree(master); + } else { + assert(FALSE); + result = FALSE; + } + return result; +} + +c_bool +d_nameSpaceMasterIsAddress( + d_nameSpace nameSpace, + d_networkAddress addr) +{ + c_bool result = FALSE; + + assert(d_nameSpaceIsValid(nameSpace)); + assert(addr); + + d_lockLock(d_lock(nameSpace)); + if ((d_networkAddressEquals(nameSpace->master, addr) == TRUE) && + (nameSpace->masterConfirmed == TRUE)) { + result = TRUE; + } + d_lockUnlock(d_lock(nameSpace)); + + return result; +} + +void +d_nameSpaceElementWalk( + d_nameSpace nameSpace, + c_bool ( * action ) (d_element element, c_voidp userData), + c_voidp args) +{ + if (isANameSpace(nameSpace)) { + d_tableWalk(nameSpace->elements, action, args); + } +} + +c_char* +d_nameSpaceGetPartitions( + d_nameSpace nameSpace) +{ + struct d_nameSpaceHelper data; + + data.kind = D_NS_COUNT; + data.count = 0; + data.ns = nameSpace; + d_tableWalk(nameSpace->elements, d_nameSpaceGetPartitionsAction, &data); + + if(data.count == 0){ + data.value = os_malloc(1); + *data.value = '\0'; + } else { + data.kind = D_NS_COPY; + data.value = os_malloc(data.count + 1); + *data.value = '\0'; + d_tableWalk(nameSpace->elements, d_nameSpaceGetPartitionsAction, &data); + } + + return data.value; +} + +/** This function returns a comma-separated list of partition-topic expressions. + * Partition- and topic-expressions are separated by a dot. + * Legacy versions of the durability service do not support the topic + * part of the expression and are expecting a comma-separated list of partition + * expressions. To allow interoperability between legacy and new versions, the + * new versions will use a "*" as topic-expression when interpreting partition- + * expressions and also they will leave out the topic-expression if it is '*'. + * This allows interoperability between new and legacy when only + * configuration is used in name-space configurations. + */ +c_char* +d_nameSpaceGetPartitionTopics( + d_nameSpace nameSpace) +{ + struct d_nameSpaceHelper data; + + data.kind = D_NS_COUNT; + data.count = 0; + data.ns = nameSpace; + d_tableWalk(nameSpace->elements, d_nameSpaceGetPartitionTopicsAction, &data); + + if(data.count == 0){ + data.value = os_malloc(1); + *data.value = '\0'; + } else { + data.kind = D_NS_COPY; + data.value = os_malloc(data.count + 1); + *data.value = '\0'; + d_tableWalk(nameSpace->elements, d_nameSpaceGetPartitionTopicsAction, &data); + } + + return data.value; +} + +struct d_nameSpaceLookupPartitionHelper { + d_element found; + d_partition partition; +}; + +static c_bool +d_nameSpaceComparePartitionAction( + d_element e, + void* args) +{ + struct d_nameSpaceLookupPartitionHelper* data; + data = args; + + if(strcmp(data->partition, e->partition) == 0) { + data->found = e; + } + return data->found == NULL; +} + +static d_element +d_nameSpaceLookupPartition( + d_nameSpace nameSpace, + d_partition partition) +{ + struct d_nameSpaceLookupPartitionHelper walkData; + + walkData.found = NULL; + walkData.partition = partition; + d_tableWalk(nameSpace->elements, d_nameSpaceComparePartitionAction, &walkData); + return walkData.found; +} + + +c_bool +d_nameSpaceGetPartitionsAction( + d_element element, + c_voidp args) +{ + struct d_nameSpaceHelper* data; + + data = (struct d_nameSpaceHelper*)args; + + /* Because of the recently added functionality to support partition.topic expressions to identify + * the scope of a namespace, partitions can have more than one occurrence in the d_nameSpace->elements list. To + * prevent double entries in the partitionstring, lookup the first occurrence of a partition(!) in the elements-list + * and add it only when it equals the current element. + */ + if(element == d_nameSpaceLookupPartition(data->ns, element->partition)) { + switch(data->kind){ + case D_NS_COUNT: + data->count += element->strlenPartition + 1; + break; + case D_NS_COPY: + if(strlen(data->value)){ + os_strcat(data->value, ","); + } + os_strcat(data->value, element->partition); + + break; + } + } + return TRUE; +} + +c_bool +d_nameSpaceGetPartitionTopicsAction( + d_element element, + c_voidp args) +{ + struct d_nameSpaceHelper* data; + + data = (struct d_nameSpaceHelper*)args; + + switch(data->kind){ + case D_NS_COUNT: + if(!element->topic) { + data->count += element->strlenTopic + element->strlenPartition + 1; + }else { + data->count += element->strlenTopic + element->strlenPartition + 1 + 1; + } + break; + case D_NS_COPY: + if(strlen(data->value)){ + os_strcat(data->value, ","); + } + if(!element->topic) { + os_strcat(data->value, element->partition); + os_strcat(data->value, "."); + os_strcat(data->value, "*"); + } else { + os_strcat(data->value, element->partition); + os_strcat(data->value, "."); + os_strcat(data->value, element->topic); + } + break; + } + return TRUE; +} + +void +d_nameSpaceCopyPartitions( + d_nameSpace to, + d_nameSpace from) +{ + /* Keep partitionlist */ + d_objectKeep (d_object(from->elements)); + + /* Free old table */ + if (to->elements) + { + d_tableFree (to->elements); + } + + /* Copy table to 'to' nameSpace */ + to->elements = from->elements; +} + +void +d_nameSpaceSetInitialQuality( + d_nameSpace nameSpace, + d_quality quality) +{ + if (isANameSpace(nameSpace)) { + nameSpace->quality = quality; + } +} + +d_quality +d_nameSpaceGetInitialQuality( + d_nameSpace nameSpace) +{ + d_quality q = D_QUALITY_ZERO; + + if (isANameSpace(nameSpace)) { + q = nameSpace->quality; + } + return q; +} + +d_mergePolicy +d_nameSpaceGetMergePolicy( + d_nameSpace nameSpace, + d_name role) +{ + return d_policyGetMergePolicy (nameSpace->policy, role); +} + +d_name +d_nameSpaceGetRole( + d_nameSpace nameSpace) +{ + assert (isANameSpace(nameSpace)); + return os_strdup(nameSpace->mergeState->role); +} + +/** + * \brief Get the mergeState of a nameSpace + * + * If the role is NULL or equals the role of the native state of the namespace, + * then the native state is returned. + * If the role of the state is not NULL and differs from the role of + * the namespace, then the foreign state is returned. + */ +d_mergeState +d_nameSpaceGetMergeState( + d_nameSpace nameSpace, + d_name role) +{ + d_mergeState dummy; + d_mergeState state = NULL; + + if (isANameSpace(nameSpace)) { + if ((!role) || (strcmp(role, nameSpace->mergeState->role) == 0)) { + /* Native merge state */ + state = nameSpace->mergeState; + /* Do not return your own state if you have cleared the state */ + if (state->value == (c_ulong)-1) { + state = NULL; + } + } else { + /* Foreign merge state */ + dummy = d_mergeStateNew(role, 0); + state = d_tableFind(nameSpace->mergedRoleStates, dummy); + d_mergeStateFree(dummy); + } + if (state) { + state = d_mergeStateNew(state->role, state->value); + } + } + return state; +} + + +/** \brief Get the advertisedMergeState of a nameSpace */ +d_mergeState +d_nameSpaceGetAdvertisedMergeState( + d_nameSpace nameSpace) +{ + d_mergeState state = NULL; + + if (isANameSpace(nameSpace)) { + state = nameSpace->advertisedMergeState; + /* Do not return your own advertised state if you have cleared the state */ + if (state && (state->value == (c_ulong)-1)) { + state = NULL; + } + if (state) { + /* Precondition: when an advertised mergeState exists, it MUST have a role */ + state = d_mergeStateNew(state->role, state->value); + } + } + return state; +} + +/** + * \brief Set the mergeState of a nameSpace + * + * If state is NULL then the merge state value of the native state of + * the namespace is set to -1 to indicate that no aligner is available. + * + * If the role of the state is NULL or equals the role of the namespace, + * then the native state of the nameSpace is set. + * If the role of the state is not NULL and differs from the role of + * the namespace, then the foreign state is set. + */ +void +d_nameSpaceSetMergeState( + d_nameSpace nameSpace, + d_mergeState state) +{ + d_mergeState toAdd, found; + + if (isANameSpace(nameSpace)) { + if (state == NULL) { + /* A mergeState NULL means that no aligner is present. + * This is represented by setting the value of the + * native mergeState to -1. */ + nameSpace->mergeState->value = (c_ulong)-1; + } else { + if ((!state->role) || (strcmp(state->role, nameSpace->mergeState->role) == 0)) { + /* Native state */ + nameSpace->mergeState->value = state->value; + } else { + /* Foreign state */ + toAdd = d_mergeStateNew(state->role, state->value); + found = d_tableInsert(nameSpace->mergedRoleStates, toAdd); + if (found) { + d_mergeStateFree(toAdd); + d_mergeStateSetValue(found, state->value); + } + } + } + } + return; +} + +/** + * \brief Clear the mergeState of the namespace. + * + * If the role is NULL then the namespace for the native state is cleared. + * If the role differs from the role of the native state, then the + * foreign state corresponding to the role is removed. + */ +void +d_nameSpaceClearMergeState( + d_nameSpace nameSpace, + d_name role) +{ + d_mergeState dummy; + + if (isANameSpace(nameSpace)) { + /* Use -1 to clear the namespace for your own role */ + if ((!role) || (strcmp(role, nameSpace->mergeState->role) == 0)) { + /* clear the mergestate for this namespace */ + nameSpace->mergeState->value = (c_ulong)-1; + } else { + /* Apparently the namespace has a different role than my own. + * Remove the namespace from my mergedRoles tables + */ + dummy = d_mergeStateNew (role, 0); + d_tableRemove (nameSpace->mergedRoleStates, dummy); + d_mergeStateFree (dummy); + } + } +} + +struct nsMergeStateDiffHelper +{ + d_table mergedStates; + c_iter diff; +}; + +struct nsFindDiffHelper +{ + c_bool found; + const char* role; +}; + +void +d_nameSpaceFindDiffWalk ( + c_voidp o, + c_voidp userData) +{ + struct nsFindDiffHelper* helper; + d_mergeState state; + + helper = (struct nsFindDiffHelper*)userData; + state = d_mergeState(o); + + /* If role is found in diff, return true */ + if (strcmp (state->role, helper->role) == 0) { + helper->found = TRUE; + } +} + +static c_bool +d_nameSpaceMergeStateDiffWalk( + c_voidp o, + c_voidp userData) +{ + d_mergeState state1; + d_mergeState state2; + struct nsMergeStateDiffHelper* helper; + struct nsFindDiffHelper walkData; + + state1 = (d_mergeState)o; + helper = (struct nsMergeStateDiffHelper*)userData; + + /* Check if role is not already in diff list */ + walkData.role = state1->role; + walkData.found = FALSE; + c_iterWalk(helper->diff, d_nameSpaceFindDiffWalk, &walkData); + + /* Look it up, when a conflict is found, add it to diff list */ + if (!walkData.found) { + state2 = d_tableFind (helper->mergedStates, state1); + if (state2) { + if (state1->value != state2->value) { + helper->diff = c_iterInsert( + helper->diff, d_mergeStateNew(state1->role, state1->value)); + } + } else { + helper->diff = c_iterInsert( + helper->diff, d_mergeStateNew(state1->role, state1->value)); + } + } + return TRUE; +} + +/* Returns a list of conflicting merge states */ +c_iter +d_nameSpaceGetMergedStatesDiff( + d_nameSpace ns1, + d_nameSpace ns2) +{ + c_iter result = NULL; + struct nsMergeStateDiffHelper walkData; + + if ((ns1 == NULL) || (ns2 == NULL)) { + return NULL; + } + + result = c_iterNew(NULL); + + /* 1st walk: check ns 1 */ + walkData.mergedStates = ns2->mergedRoleStates; + walkData.diff = result; + d_tableWalk (ns1->mergedRoleStates, d_nameSpaceMergeStateDiffWalk, &walkData); + + /* 2nd walk: check ns 2 */ + walkData.mergedStates = ns1->mergedRoleStates; + d_tableWalk (ns2->mergedRoleStates, d_nameSpaceMergeStateDiffWalk, &walkData); + + /* If diff list is empty, free iterator */ + if (c_iterLength(result) == 0) { + c_iterFree (result); + result = NULL; + } + + + return result; +} + + +c_bool +d_nameSpaceIsAlignable( + d_nameSpace nameSpace) +{ + assert(d_nameSpaceIsValid(nameSpace)); + + return nameSpace->alignable; +} + + +void +d_nameSpaceSetAlignable( + d_nameSpace nameSpace, + c_bool alignable) +{ + assert(d_nameSpaceIsValid(nameSpace)); + + nameSpace->alignable = alignable; +} + +c_bool +d_nameSpaceGetEqualityCheck( + d_nameSpace nameSpace) +{ + assert (isANameSpace(nameSpace)); + return d_policyGetEqualityCheck(nameSpace->policy); +} + +c_ulong +d_nameSpaceGetMasterPriority( + d_nameSpace nameSpace) +{ + assert (isANameSpace(nameSpace)); + return d_policyGetMasterPriority(nameSpace->policy); +} + +/* Synchronize the value of the advertisedMergeState to that of the mergeState */ +void +d_nameSpaceSyncMergeState( + d_nameSpace nameSpace) +{ + assert(d_nameSpaceIsValid(nameSpace)); + + d_lockLock(d_lock(nameSpace)); + nameSpace->advertisedMergeState->value = nameSpace->mergeState->value; + d_lockUnlock(d_lock(nameSpace)); +} + +void +d_nameSpaceSetMergeCount( + d_nameSpace nameSpace, + c_ulong mergeCount) +{ + assert(d_nameSpaceIsValid(nameSpace)); + nameSpace->mergeCount = mergeCount; +} + +c_ulong +d_nameSpaceGetMergeCount( + d_nameSpace nameSpace) +{ + assert(d_nameSpaceIsValid(nameSpace)); + return nameSpace->mergeCount; +} diff --git a/src/services/durability/code/d_nameSpaces.c b/src/services/durability/code/d_nameSpaces.c new file mode 100644 index 000000000..f8cb36b44 --- /dev/null +++ b/src/services/durability/code/d_nameSpaces.c @@ -0,0 +1,323 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "d_nameSpaces.h" +#include "d__nameSpaces.h" +#include "d__nameSpace.h" +#include "d_networkAddress.h" +#include "d__mergeState.h" +#include "d__admin.h" +#include "d__table.h" +#include "d__misc.h" +#include "d_message.h" +#include "vortex_os.h" + +struct nsWalkHelper { + d_mergeState states; + c_ulong index; +}; + +static c_bool +addMergeState( + d_mergeState state, + struct nsWalkHelper* helper) +{ + d_mergeStateInit(&((helper->states)[helper->index]), state->role, state->value); + helper->index++; + + return TRUE; +} + +d_nameSpaces +d_nameSpacesNew( + d_admin admin, + d_nameSpace nameSpace, + d_quality initialQuality, + c_ulong total) +{ + d_nameSpaces ns = NULL; + d_networkAddress master; + d_mergeState state; + struct nsWalkHelper helper; + c_ulong masterPriority; + c_ulong count; + + if(nameSpace){ + ns = d_nameSpaces(os_malloc(C_SIZEOF(d_nameSpaces))); + + if(ns){ + master = d_networkAddressUnaddressed(); + d_messageInit(d_message(ns), admin); + /* Quality conversion */ + ns->aligner = d_nameSpaceIsAligner(nameSpace); + ns->durabilityKind = d_nameSpaceGetDurabilityKind(nameSpace); + ns->alignmentKind = d_nameSpaceGetAlignmentKind(nameSpace); + /* Convert quality (os_timeW) to qualityExt (c_time) */ + d_qualityExtFromQuality(&ns->initialQuality, &initialQuality, IS_Y2038READY(ns)); + ns->partitions = d_nameSpaceGetPartitionTopics(nameSpace); + masterPriority = d_nameSpaceGetMasterPriority(nameSpace); + ns->total = total; + ns->master.systemId = master->systemId; + ns->master.localId = master->localId; + ns->master.lifecycleId = master->lifecycleId; + ns->isComplete = TRUE; + ns->name = os_strdup (d_nameSpaceGetName(nameSpace)); + ns->masterConfirmed = d_nameSpaceIsMasterConfirmed(nameSpace); + + /* Use the advertisedMergeState as the mergeState to advertise */ + state = d_nameSpaceGetAdvertisedMergeState(nameSpace); + if(state) { + d_mergeStateInit(&ns->state, state->role, state->value); + d_mergeStateFree(state); + } else { + d_name role = d_nameSpaceGetRole(nameSpace); + d_mergeStateInit(&ns->state, role, (c_ulong) -1); + os_free(role); + } + + ns->mergedStatesCount = d_tableSize(nameSpace->mergedRoleStates); + count = ns->mergedStatesCount; + + if (ns->aligner == TRUE) { + count++; + } + + if (count > 0) { + ns->mergedStates = os_malloc(C_SIZEOF(d_mergeState)*count); + + helper.index = 0; + if (ns->mergedStatesCount > 0) { + helper.states = (d_mergeState) ns->mergedStates; + + d_tableWalk(nameSpace->mergedRoleStates, addMergeState, &helper); + } + if (ns->aligner == TRUE) { + d_mergeStateInit(&(((d_mergeState)ns->mergedStates)[helper.index]), + "masterPriority", + masterPriority); + } + } else { + ns->mergedStates = NULL; + } + + d_networkAddressFree(master); + } + } + return ns; +} + +d_networkAddress +d_nameSpacesGetMaster( + d_nameSpaces nameSpaces) +{ + d_networkAddress addr = NULL; + + if(nameSpaces){ + addr = d_networkAddressNew( nameSpaces->master.systemId, + nameSpaces->master.localId, + nameSpaces->master.lifecycleId); + } + return addr; +} + +void +d_nameSpacesSetMaster( + d_nameSpaces nameSpaces, + d_networkAddress master) +{ + if(nameSpaces && master){ + nameSpaces->master.systemId = master->systemId; + nameSpaces->master.localId = master->localId; + nameSpaces->master.lifecycleId = master->lifecycleId; + } + return; +} + +char * +d_nameSpacesGetName( + d_nameSpaces nameSpaces ) +{ + char * name; + + name = NULL; + if (nameSpaces) { + name = nameSpaces->name; + } + return name; +} + + +void +d_nameSpacesSetTotal( + d_nameSpaces nameSpaces, + c_ulong total) +{ + if (nameSpaces) + { + nameSpaces->total = total; + } +} + +d_alignmentKind +d_nameSpacesGetAlignmentKind( + d_nameSpaces nameSpaces) +{ + d_alignmentKind kind = D_ALIGNEE_INITIAL; + + if(nameSpaces){ + kind = nameSpaces->alignmentKind; + } + return kind; +} + +d_durabilityKind +d_nameSpacesGetDurabilityKind( + d_nameSpaces nameSpaces) +{ + d_durabilityKind kind = D_DURABILITY_ALL; + + if(nameSpaces){ + kind = nameSpaces->durabilityKind; + } + return kind; +} + +c_bool +d_nameSpacesIsAligner( + d_nameSpaces nameSpaces) +{ + c_bool aligner = FALSE; + + if(nameSpaces){ + aligner = nameSpaces->aligner; + } + return aligner; +} + +c_ulong +d_nameSpacesGetTotal( + d_nameSpaces nameSpaces) +{ + c_ulong total = 0; + + if(nameSpaces){ + total = nameSpaces->total; + } + return total; +} + +c_char* +d_nameSpacesGetPartitions( + d_nameSpaces nameSpaces) +{ + c_char* partitions = NULL; + + if(nameSpaces){ + if(nameSpaces->partitions){ + partitions = os_strdup(nameSpaces->partitions); + } + } + return partitions; +} + +void +d_nameSpacesFree( + d_nameSpaces nameSpaces) +{ + c_ulong count, i; + + if(nameSpaces){ + if(nameSpaces->name){ + os_free(nameSpaces->name); + } + if(nameSpaces->partitions){ + os_free(nameSpaces->partitions); + nameSpaces->partitions = NULL; + } + d_mergeStateDeinit(&nameSpaces->state); + + count = nameSpaces->mergedStatesCount; + if (nameSpaces->aligner == TRUE) { + count++; + } + + if(count > 0){ + d_mergeState ms = (d_mergeState) nameSpaces->mergedStates; + for(i=0; imergedStates); + d_messageDeinit(d_message(nameSpaces)); + os_free(nameSpaces); + } +} + +d_quality +d_nameSpacesGetInitialQuality( + d_nameSpaces nameSpaces) +{ + d_quality quality = D_QUALITY_ZERO; + + if (nameSpaces) { + /* Convert qualityExt (c_time) to quality (os_timeW) */ + d_qualityExtToQuality(&quality, &nameSpaces->initialQuality, IS_Y2038READY(nameSpaces)); + } + return quality; +} + +int +d_nameSpacesCompare( + d_nameSpaces ns1, + d_nameSpaces ns2) +{ + int r; + + if((!ns1) && (!ns2)){ + r = 0; + } else if(!ns1){ + r = 1; + } else if(!ns2){ + r = -1; + } else if (ns1->aligner && !(ns2->aligner)){ + r = 1; + }else if (!(ns1->aligner) && ns2->aligner){ + r = -1; + } else if(ns1->alignmentKind != ns2->alignmentKind){ + if(((c_ulong)ns1->alignmentKind) > ((c_ulong)ns2->alignmentKind)){ + r = 1; + } else { + r = -1; + } + } else if(ns1->durabilityKind != ns2->durabilityKind) { + if(((c_ulong)ns1->durabilityKind) > ((c_ulong)ns2->durabilityKind)){ + r = 1; + } else { + r = -1; + } + } else if((!ns1->partitions) && (!ns2->partitions)){ + r = 0; + } else if(!ns1->partitions){ + r = 1; + } else if(!ns2->partitions){ + r = -1; + } else { + r = strcmp(ns1->partitions, ns2->partitions); + } + return r; +} diff --git a/src/services/durability/code/d_nameSpacesListener.c b/src/services/durability/code/d_nameSpacesListener.c new file mode 100644 index 000000000..61519aa22 --- /dev/null +++ b/src/services/durability/code/d_nameSpacesListener.c @@ -0,0 +1,705 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "d__nameSpacesListener.h" +#include "d__readerListener.h" +#include "d__listener.h" +#include "d__fellow.h" +#include "d__nameSpace.h" +#include "d__admin.h" +#include "d__publisher.h" +#include "d__subscriber.h" +#include "d__configuration.h" +#include "d__sampleChainListener.h" +#include "d__misc.h" +#include "d__durability.h" +#include "d__mergeState.h" +#include "d__policy.h" +#include "d_networkAddress.h" +#include "d_nameSpaces.h" +#include "d_nameSpacesRequest.h" +#include "d_groupsRequest.h" +#include "d_message.h" +#include "v_time.h" +#include "os_heap.h" +#include "os_report.h" + +/** + * Macro that checks the d_nameSpacesListener validity. + * Because d_nameSpacesListener is a concrete class typechecking is required. + */ +#define d_nameSpacesListenerIsValid(_this) \ + d_listenerIsValidKind(d_listener(_this), D_NAMESPACES_LISTENER) + +/** + * \brief The d_nameSpacesListener cast macro. + * + * This macro casts an object to a d_nameSpacesListener object. + */ +#define d_nameSpacesListener(_this) ((d_nameSpacesListener)(_this)) + + +C_STRUCT(d_nameSpacesListener){ + C_EXTENDS(d_readerListener); +}; + +struct compatibilityHelper { + d_fellow fellow; + c_bool compatible; + d_nameSpace ns; + d_nameSpace fellowNs; /* For easy debugging */ +}; + +/* Walk fellow namespaces */ +static c_bool +isFellowNameSpaceCompatible( + d_nameSpace fellowNs, + c_voidp args) +{ + struct compatibilityHelper* walkData; + walkData = (struct compatibilityHelper*)args; + + /* If nameSpace name is equal, policy of namespace must be equal too */ + if (strcmp (d_nameSpaceGetName(fellowNs), d_nameSpaceGetName(walkData->ns)) == 0) { + walkData->fellowNs = fellowNs; + return (d_nameSpaceCompatibilityCompare(walkData->ns, fellowNs) == 0); + } + + return TRUE; +} + +/* Walk admin namespaces */ +static void +areFellowNameSpacesCompatible( + d_nameSpace adminNs, + c_voidp args) +{ + struct compatibilityHelper* walkData; + d_networkAddress address; + char* localPartitions; + char* remotePartitions; + + walkData = (struct compatibilityHelper*)args; + + walkData->ns = adminNs; + + if (!d_fellowNameSpaceWalk(walkData->fellow, isFellowNameSpaceCompatible, walkData)) + { + walkData->compatible = FALSE; + localPartitions = d_nameSpaceGetPartitionTopics(adminNs); + remotePartitions = d_nameSpaceGetPartitionTopics(walkData->fellowNs); + address = d_fellowGetAddress (walkData->fellow); + + OS_REPORT(OS_ERROR, D_CONTEXT, 0, + "NameSpace configuration of remote durability service '%u' for NameSpace "\ + "'%s' is incompatible with local NameSpace '%s'. Partition(-Topic) expressions "\ + "are '%s'(local) and '%s'(remote).", + address->systemId, d_nameSpaceGetName(walkData->fellowNs), + d_nameSpaceGetName(adminNs), localPartitions, + remotePartitions); + + d_networkAddressFree(address); + os_free (localPartitions); + os_free (remotePartitions); + } +} + +static c_bool +isFellowStateCompatible( + d_durability durability, + d_fellow fellow) +{ + d_serviceState state, fellowState; + + fellowState = d_fellowGetState(fellow); + state = d_durabilityGetState(durability); + + switch(state){ + case D_STATE_INIT: + case D_STATE_DISCOVER_FELLOWS_GROUPS: + switch(fellowState){ + case D_STATE_INIT: + case D_STATE_DISCOVER_FELLOWS_GROUPS: + case D_STATE_INJECT_PERSISTENT: + case D_STATE_FETCH_INITIAL: + case D_STATE_FETCH: + case D_STATE_ALIGN: + case D_STATE_FETCH_ALIGN: + case D_STATE_COMPLETE: + case D_STATE_DISCOVER_LOCAL_GROUPS: + break; + case D_STATE_DISCOVER_PERSISTENT_SOURCE: + case D_STATE_TERMINATING: + case D_STATE_TERMINATED: + break; + default: + assert(FALSE); + break; + } + break; + case D_STATE_INJECT_PERSISTENT: + case D_STATE_DISCOVER_LOCAL_GROUPS: + case D_STATE_FETCH_INITIAL: + case D_STATE_FETCH: + case D_STATE_ALIGN: + case D_STATE_FETCH_ALIGN: + case D_STATE_COMPLETE: + switch(fellowState){ + case D_STATE_INIT: + case D_STATE_DISCOVER_FELLOWS_GROUPS: + case D_STATE_COMPLETE: /* TODO: need to allow other states too? */ + break; + default: + break; + } + break; + case D_STATE_DISCOVER_PERSISTENT_SOURCE: + case D_STATE_TERMINATING: + case D_STATE_TERMINATED: + break; + default: + assert(FALSE); + break; + } + + return TRUE; +} + +struct checkFellowMasterHelper +{ + d_admin admin; + d_fellow fellow; + d_nameSpace oldNameSpace; +}; + +struct checkDelayAlignmentHelper { + d_admin admin; + d_fellow fellow; +}; + +static void +namespace_compatibility_check( + d_admin admin, + struct d_networkAddress_s sender, + d_nameSpace nameSpace) +{ + d_nameSpace localNameSpace; + + if ((localNameSpace = d_adminGetNameSpace(admin, nameSpace->name)) == NULL) { + /* No matching local nameSpace, so masterPriorities cannot be incompatible */ + d_durability durability; + d_configuration config; + + /* Check if local filters overlap namespace. + * This should eventually result in ignoring the namespace instead of administering it locally, + * for now only an error is reported + */ + durability = d_adminGetDurability(admin); + config = d_durabilityGetConfiguration(durability); + if (d_configurationCheckFilterInNameSpace(config, nameSpace)) { + d_printTimedEvent(durability, D_LEVEL_WARNING, + "Received nameSpace '%s' from fellow %u is incompatible with local configured filters, can not be the master of this namespace.\n", + nameSpace->name, sender.systemId); + } + return; + } + if (!localNameSpace->compatibility_check_required) { + /* No compatibility check required anymore */ + d_nameSpaceFree(localNameSpace); + return; + } + if (!d_nameSpaceIsAligner(localNameSpace) || (!d_nameSpaceIsAligner(nameSpace))) { + /* One or both of the nameSpaces is not an aligner, so masterPriority cannot be incompatible */ + d_nameSpaceFree(localNameSpace); + return; + } + if (IS_LEGACY_MASTER_SELECTION(d_nameSpaceGetMasterPriority(nameSpace)) && (!IS_LEGACY_MASTER_SELECTION(d_nameSpaceGetMasterPriority(localNameSpace)))) { + localNameSpace->compatibility_check_required = FALSE; + OS_REPORT(OS_ERROR, OS_FUNCTION, 0, + "I use priorities for namespace '%s' while fellow %u uses the legacy master selection algorithm, this is an incompatible and unsupported configuration", + localNameSpace->name, sender.systemId); + } else if (!IS_LEGACY_MASTER_SELECTION(d_nameSpaceGetMasterPriority(nameSpace)) && (IS_LEGACY_MASTER_SELECTION(d_nameSpaceGetMasterPriority(localNameSpace)))) { + localNameSpace->compatibility_check_required = FALSE; + OS_REPORT(OS_ERROR, OS_FUNCTION, 0, + "I use the legacy master selection algorithm for namespace '%s' while fellow %u uses priorities, this is an incompatible and unsupported configuration", + localNameSpace->name, sender.systemId); + } + d_nameSpaceFree(localNameSpace); +} + +static void +checkFellowDelayAlignmentWalk( + void* o, + c_voidp userData) +{ + d_admin admin; + d_nameSpace nameSpace; + d_fellow fellow; + d_quality q; + struct checkDelayAlignmentHelper* data; + + data = (struct checkDelayAlignmentHelper*)userData; + nameSpace = d_nameSpace(o); + admin = data->admin; + fellow = data->fellow; + + /* Get quality of fellow namespace */ + q = d_nameSpaceGetInitialQuality(nameSpace); + + /* Report potential delayed initial dataset if quality is non-zero and not infinite */ + if (!D_QUALITY_ISZERO(q) && !D_QUALITY_ISINFINITE(q)) { + d_adminReportDelayedInitialSet(admin, nameSpace, fellow); + } +} + +static void +checkFellowMasterWalk( + void* o, + c_voidp userData) +{ + struct checkFellowMasterHelper* helper; + d_networkAddress fellowMasterAddr, fellowAddr; + d_nameSpace fellowNameSpace, nameSpace; + + helper = (struct checkFellowMasterHelper*)userData; + fellowNameSpace = d_nameSpace(o); /* the namespace that was received as a d_nameSpace message from the fellow */ + fellowMasterAddr = d_nameSpaceGetMaster (fellowNameSpace); /* the master of the namespace of the fellow */ + fellowAddr = d_fellowGetAddress(helper->fellow); + + /* The nameSpace that was received as a d_nameSpace message may have + * changed state, so we need to retrieve the current state of the namespace. + * If the nameSpace that was received from the fellow has a confirmed + * master we must check for conflicts. We do not require that I have a + * confirmed master for the nameSpace myself. This is because I may been + * involved in a master conflict with another fellow for the same + * nameSpace, and in the process of solving it I might have set the + * masterConfirmed attribute for the nameSpace to 0 + * (see d_conflictMonitorCheckForConflicts). + */ + nameSpace = d_adminGetNameSpace(helper->admin, fellowNameSpace->name); + if (nameSpace) { + /* When I receive a namespace from a fellow with a confirmed master then check + * for a possible master conflict + */ + if ( d_fellowIsConfirmed(helper->fellow) && /* The fellow is confirmed */ + d_nameSpaceIsMasterConfirmed(fellowNameSpace) ) { /* The master selected by the fellow is confirmed */ + /* Now check for conflicts */ + d_adminReportMaster(helper->admin, helper->fellow, nameSpace); + } + + d_nameSpaceFree(nameSpace); + } + + d_networkAddressFree(fellowMasterAddr); + d_networkAddressFree(fellowAddr); +} + +static void +dynamicNameSpaceWalk( + void* o, + c_voidp userData) +{ + d_nameSpace fellowNameSpace = d_nameSpace(o); + d_admin admin = d_admin(userData); + + d_nameSpace localNameSpace; + d_durability durability; + d_configuration config; + d_policy policy; + char * name; + + durability = d_adminGetDurability(admin); + config = d_durabilityGetConfiguration(durability); + + name = d_nameSpaceGetName(fellowNameSpace); + policy = d_configurationFindPolicyForNameSpace(config, name); + localNameSpace = d_nameSpaceNew(name, policy); + /* If namespace is created, add to administration */ + if (localNameSpace) { + /* Copy partitions to local nameSpace */ + d_nameSpaceCopyPartitions (localNameSpace, fellowNameSpace); + d_adminAddNameSpace (admin, localNameSpace); + d_nameSpaceFree (localNameSpace); + } + d_policyFree(policy); +} + +static c_bool +collectFellowNsWalk( + d_nameSpace nameSpace, + c_voidp userData) +{ + c_iter nsList = (c_iter)userData; + assert(nsList != NULL); + (void)c_iterAppend (nsList, d_nameSpaceCopy(nameSpace)); + return TRUE; +} + +static void +d_nameSpacesListenerAction( + d_listener listener, + d_message message) +{ + d_durability durability; + d_admin admin; + d_fellow fellow = NULL; + c_bool allowed; + d_nameSpace nameSpace, oldFellowNameSpace, fellowNameSpace; + c_ulong count; + d_configuration config; + d_subscriber subscriber; + d_sampleChainListener sampleChainListener; + struct compatibilityHelper helper; + d_adminStatisticsInfo info; + c_bool added; + struct checkFellowMasterHelper fellowMasterHelper; + struct checkDelayAlignmentHelper delayAlignmentHelper; + d_name role; + c_iter fellowNameSpaces; + d_nameSpace ns; + char mergedStatesStr[1024] = ""; + char mergedStatesExtStr[1024] = ""; + d_quality quality; + d_networkAddress fellowAddr; + + assert(d_nameSpacesListenerIsValid(listener)); + +#define MERGED_STATES_STRING(mergedStates, str, begin, end) \ + { \ + const struct d_mergeState_s *ms = (const struct d_mergeState_s *) mergedStates; \ + const c_ulong nms = end; \ + size_t pos = 0; \ + c_ulong i; \ + for (i = begin; i < nms && pos < sizeof(str); i++) { \ + int n = snprintf(str + pos, sizeof(str) - pos, "%s%s, %d", (i == 0) ? "" : "; ", ms[i].role, ms[i].value); \ + if (n > 0) { pos += (size_t)n; } else { break; } \ + } \ + if (i < nms || pos >= sizeof(str)) { \ + assert(sizeof(str) >= 4); \ + if (pos >= sizeof(str) - 4) { \ + pos = sizeof(str) - 4; \ + } \ + strcpy(str + pos, "..."); \ + } \ + } + MERGED_STATES_STRING(d_nameSpaces(message)->mergedStates, mergedStatesStr, 0, d_nameSpaces(message)->mergedStatesCount); + MERGED_STATES_STRING(d_nameSpaces(message)->mergedStates, mergedStatesExtStr, d_nameSpaces(message)->mergedStatesCount, c_sequenceSize(d_nameSpaces(message)->mergedStates)); + + admin = d_listenerGetAdmin(listener); + durability = d_adminGetDurability(admin); + config = d_durabilityGetConfiguration(durability); + fellowNameSpaces = NULL; + nameSpace = d_nameSpaceFromNameSpaces(config, d_nameSpaces(message)); + d_qualityExtToQuality(&quality, &d_nameSpaces(message)->initialQuality, IS_Y2038READY(message)); + d_printTimedEvent (durability, D_LEVEL_FINE, + "Received nameSpace '%s' from fellow %u (his master: %u, confirmed: %d, mergeState: (%s,%d), quality: %"PA_PRItime", mergedStates:{%s}, extensions: {%s}).\n", + d_nameSpaces(message)->name, + message->senderAddress.systemId, + d_nameSpaces(message)->master.systemId, + d_nameSpaces(message)->masterConfirmed, + d_nameSpaces(message)->state.role, + d_nameSpaces(message)->state.value, + OS_TIMEW_PRINT(quality), + mergedStatesStr, + mergedStatesExtStr); + /* Check compatibility */ + namespace_compatibility_check(admin, message->senderAddress, nameSpace); + + fellowAddr = d_networkAddressNew( + message->senderAddress.systemId, + message->senderAddress.localId, + message->senderAddress.lifecycleId); + + fellow = d_durabilityGetOrCreateFellowFromMessage(admin, fellowAddr, message); + /* At this point the fellow must be created unless it has recently + * terminated or is terminating. + */ + if (fellow) { + if (d_fellowNameSpaceCount(fellow) < d_nameSpaces(message)->total && message->addressee.systemId == 0) + { + /* Ignore broadcasted namesapces until at least one explicit name space + * request from me has been answered, as that is what completes the + * capability+namespace handshake + */ + d_printTimedEvent (durability, D_LEVEL_FINEST, + "Ignoring received broadcasted nameSpaces from fellow %u because it hasn't responded to a request from me yet.\n", + message->senderAddress.systemId); + d_nameSpaceFree(nameSpace); + } + /* The last reception time has already been updated in + * d_durabilitySendNSRequestWhenConfirmed. Let´s check whether + * the fellow is approved. + */ + else if (d_fellowGetCommunicationState(fellow) == D_COMMUNICATION_STATE_APPROVED) { + + fellowNameSpace = d_fellowGetNameSpace(fellow, nameSpace); + + /* Update master of fellow nameSpace */ + added = d_fellowAddNameSpace(fellow, nameSpace); + + if (fellowNameSpace) { + /* Get old namespace of fellow */ + oldFellowNameSpace = d_nameSpaceCopy(fellowNameSpace); + + } else { + oldFellowNameSpace = d_nameSpaceCopy(nameSpace); + d_fellowSetExpectedNameSpaces(fellow, d_nameSpaces(message)->total); + subscriber = d_adminGetSubscriber(admin); + sampleChainListener = d_subscriberGetSampleChainListener(subscriber); + + if (sampleChainListener) { + d_sampleChainListenerTryFulfillChains(sampleChainListener, NULL); + } + } + + /* Dynamically learn the nameSpace */ + dynamicNameSpaceWalk(nameSpace, admin); + + /* Check if fellow is a candidate for delayed alignment */ + delayAlignmentHelper.admin = admin; + delayAlignmentHelper.fellow = fellow; + checkFellowDelayAlignmentWalk(nameSpace, &delayAlignmentHelper); + + /* If fellow is master for a namespace, report it to admin */ + fellowMasterHelper.admin = admin; + fellowMasterHelper.fellow = fellow; + fellowMasterHelper.oldNameSpace = oldFellowNameSpace; + checkFellowMasterWalk (nameSpace, &fellowMasterHelper); + + /* If the namespace was not added to the fellow (because it already existed there), free it */ + if (!added) { + d_nameSpaceFree(nameSpace); + } + + d_nameSpaceFree(oldFellowNameSpace); + + } else { + info = d_adminStatisticsInfoNew(); + d_fellowSetExpectedNameSpaces(fellow, d_nameSpaces(message)->total); + + /* Set role of fellow (take native role from namespace) */ + if (!d_fellowGetRole(fellow)) { + role = d_nameSpaceGetRole(nameSpace); + d_fellowSetRole (fellow, role); + os_free (role); + } + + d_fellowAddNameSpace(fellow, nameSpace); + count = d_fellowNameSpaceCount(fellow); + + if (count == d_nameSpaces(message)->total) { + allowed = isFellowStateCompatible(durability, fellow); + + if (allowed == TRUE) { + config = d_durabilityGetConfiguration(durability); + helper.fellow = fellow; + helper.compatible = TRUE; + + d_adminNameSpaceWalk (admin, areFellowNameSpacesCompatible, &helper); + + if (helper.compatible == TRUE) { + + if(config->timeAlignment == TRUE){ + os_timeW srcTime , curTime; + os_duration delta, max_delta; + + curTime = d_readerListener(listener)->lastInsertTime; + srcTime= d_readerListener(listener)->lastSourceTime; + delta = os_durationAbs(os_timeWDiff(curTime, srcTime)); + max_delta = OS_DURATION_INIT(1,0); + + if ( os_durationCompare(delta, max_delta) == OS_MORE) { + d_printTimedEvent (durability, D_LEVEL_WARNING, + "Estimated time difference including latency with " \ + "fellow %u is %f seconds, which is larger then " \ + "expected.\n", + message->senderAddress.systemId, + os_durationToReal(delta)); + OS_REPORT(OS_WARNING, D_CONTEXT, 0, + "Estimated time difference including latency " \ + "with fellow '%u' is larger then expected " \ + "(%f seconds). Durability alignment might not be " \ + "reliable. Please align time between these nodes " \ + "and restart.", + message->senderAddress.systemId, + os_durationToReal(delta)); + } else { + d_printTimedEvent (durability, D_LEVEL_FINEST, + "Estimated time difference including latency with " \ + "fellow %u is %f seconds.\n", + message->senderAddress.systemId, + os_durationToReal(delta)); + } + } + + d_fellowSetCommunicationState(fellow, D_COMMUNICATION_STATE_APPROVED); + info->fellowsApprovedDif += 1; + subscriber = d_adminGetSubscriber(admin); + sampleChainListener = d_subscriberGetSampleChainListener(subscriber); + + if(sampleChainListener){ + d_sampleChainListenerTryFulfillChains(sampleChainListener, NULL); + } + + d_printTimedEvent (durability, D_LEVEL_FINER, + "Received %u of %u nameSpaces from fellow %u.\n", + count, d_nameSpaces(message)->total, + message->senderAddress.systemId); + + /* Check if the fellow is master for one or more namespaces and report this to admin */ + fellowNameSpaces = c_iterNew(NULL); + + /* Collect fellow namespaces */ + d_fellowNameSpaceWalk (fellow, collectFellowNsWalk, fellowNameSpaces); + + /* Dynamically learn the fellow's nameSpaces */ + c_iterWalk(fellowNameSpaces, dynamicNameSpaceWalk, admin); + + /* Check if fellow is a candidate for delayed alignment */ + delayAlignmentHelper.admin = admin; + delayAlignmentHelper.fellow = fellow; + c_iterWalk(fellowNameSpaces, checkFellowDelayAlignmentWalk, &delayAlignmentHelper); + + fellowMasterHelper.admin = admin; + fellowMasterHelper.fellow = fellow; + fellowMasterHelper.oldNameSpace = NULL; + c_iterWalk (fellowNameSpaces, checkFellowMasterWalk, &fellowMasterHelper); + + while ((ns = c_iterTakeFirst(fellowNameSpaces))) { + d_nameSpaceFree(ns); + } + c_iterFree(fellowNameSpaces); + } else { + info->fellowsIncompatibleDataModelDif += 1; + + d_printTimedEvent (durability, D_LEVEL_WARNING, + "Communication with fellow %u NOT approved, because data model is not compatible\n", + message->senderAddress.systemId); + d_fellowSetCommunicationState(fellow, D_COMMUNICATION_STATE_INCOMPATIBLE_DATA_MODEL); + } + } else { + info->fellowsIncompatibleStateDif += 1; + d_printTimedEvent (durability, D_LEVEL_WARNING, + "Communication with fellow %u NOT approved, because state is not compatible my state: %d, fellow state: %d\n", + message->senderAddress.systemId, + d_durabilityGetState(durability), + message->senderState); + d_fellowSetCommunicationState(fellow, D_COMMUNICATION_STATE_INCOMPATIBLE_STATE); + } + } else { + d_printTimedEvent (durability, D_LEVEL_FINEST, + "Received %u of %u nameSpaces from fellow %u.\n", + count, d_nameSpaces(message)->total, + message->senderAddress.systemId); + } + d_adminUpdateStatistics(admin, info); + d_adminStatisticsInfoFree(info); + } + d_fellowFree(fellow); + } else { + d_nameSpaceFree(nameSpace); + } + d_networkAddressFree(fellowAddr); + return; +} + +static void +d_nameSpacesListenerDeinit( + d_nameSpacesListener listener) +{ + assert(d_nameSpacesListenerIsValid(listener)); + + /* Stop the nameSpacesListener */ + d_nameSpacesListenerStop(listener); + /* Nothing to deallocated, call super-deinit */ + d_readerListenerDeinit(d_readerListener(listener)); +} + +static void +d_nameSpacesListenerInit( + d_nameSpacesListener listener, + d_subscriber subscriber) +{ + os_threadAttr attr; + + /* Do not assert the listener because the initialization + * of the listener has not yet completed + */ + + assert(d_subscriberIsValid(subscriber)); + + /* Call super-init */ + os_threadAttrInit(&attr); + d_readerListenerInit( d_readerListener(listener), + D_NAMESPACES_LISTENER, + d_nameSpacesListenerAction, + subscriber, + D_NAMESPACES_TOPIC_NAME, + D_NAMESPACES_TOP_NAME, + V_RELIABILITY_RELIABLE, + V_HISTORY_KEEPALL, + V_LENGTH_UNLIMITED, + attr, + (d_objectDeinitFunc)d_nameSpacesListenerDeinit); +} + +d_nameSpacesListener +d_nameSpacesListenerNew( + d_subscriber subscriber) +{ + d_nameSpacesListener listener; + + assert(d_subscriberIsValid(subscriber)); + + /* Allocate nameSpacesListener object */ + listener = d_nameSpacesListener(os_malloc(C_SIZEOF(d_nameSpacesListener))); + if (listener) { + /* Initialize the nameSpacesListener */ + d_nameSpacesListenerInit(listener, subscriber); + } + return listener; +} + + +void +d_nameSpacesListenerFree( + d_nameSpacesListener listener) +{ + assert(d_nameSpacesListenerIsValid(listener)); + + d_objectFree(d_object(listener)); +} + + +c_bool +d_nameSpacesListenerStart( + d_nameSpacesListener listener) +{ + assert(d_nameSpacesListenerIsValid(listener)); + + return d_readerListenerStart(d_readerListener(listener)); +} + +c_bool +d_nameSpacesListenerStop( + d_nameSpacesListener listener) +{ + assert(d_nameSpacesListenerIsValid(listener)); + + return d_readerListenerStop(d_readerListener(listener)); +} diff --git a/src/services/durability/code/d_nameSpacesRequest.c b/src/services/durability/code/d_nameSpacesRequest.c new file mode 100644 index 000000000..a57bedc62 --- /dev/null +++ b/src/services/durability/code/d_nameSpacesRequest.c @@ -0,0 +1,49 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "d_nameSpacesRequest.h" +#include "d_message.h" +#include "os_heap.h" + +d_nameSpacesRequest +d_nameSpacesRequestNew( + d_admin admin) +{ + d_nameSpacesRequest request; + + request = NULL; + + if(admin){ + request = d_nameSpacesRequest(os_malloc(C_SIZEOF(d_nameSpacesRequest))); + + if(request){ + d_messageInit(d_message(request), admin); + } + } + return request; +} + +void +d_nameSpacesRequestFree( + d_nameSpacesRequest request) +{ + if(request){ + d_messageDeinit(d_message(request)); + os_free(request); + } +} diff --git a/src/services/durability/code/d_nameSpacesRequestListener.c b/src/services/durability/code/d_nameSpacesRequestListener.c new file mode 100644 index 000000000..a6378bc7d --- /dev/null +++ b/src/services/durability/code/d_nameSpacesRequestListener.c @@ -0,0 +1,336 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "d__nameSpacesRequestListener.h" +#include "d__readerListener.h" +#include "d__admin.h" +#include "d__fellow.h" +#include "d__listener.h" +#include "d__nameSpace.h" +#include "d__publisher.h" +#include "d__admin.h" +#include "d__configuration.h" +#include "d__fellow.h" +#include "d__table.h" +#include "d__misc.h" +#include "d__durability.h" +#include "d__thread.h" +#include "d_nameSpaces.h" +#include "d_nameSpacesRequest.h" +#include "d_message.h" +#include "d_networkAddress.h" +#include "v_time.h" +#include "os_heap.h" + +/** + * Macro that checks the d_nameSpacesRequestListener validity. + * Because d_nameSpacesRequestListener is a concrete class typechecking is required. + */ +#define d_nameSpacesRequestListenerIsValid(_this) \ + d_listenerIsValidKind(d_listener(_this), D_NAMESPACES_REQ_LISTENER) + +/** + * \brief The d_nameSpacesRequestListener cast macro. + * + * This macro casts an object to a d_nameSpacesRequestListener object. + */ +#define d_nameSpacesRequestListener(_this) ((d_nameSpacesRequestListener)(_this)) + +C_STRUCT(d_nameSpacesRequestListener){ + C_EXTENDS(d_readerListener); +}; + +static void +cleanNameSpaces ( + c_iter nameSpaces) +{ + d_nameSpaces ns; + + /* Clean old nameSpaces list if exists */ + if (nameSpaces) { + ns = d_nameSpaces(c_iterTakeFirst(nameSpaces)); + + while(ns){ + d_nameSpacesFree(ns); + ns = d_nameSpaces(c_iterTakeFirst(nameSpaces)); + } + + c_iterFree (nameSpaces); + } +} + +struct updateNsWalkData +{ + c_iter nameSpaces; + d_nameSpacesRequestListener listener; +}; + +static void +updateNameSpacesWalk ( + d_nameSpace n, + c_iterActionArg userData) +{ + d_nameSpacesRequestListener listener; + d_admin admin; + d_nameSpaces ns; + d_networkAddress master; + struct updateNsWalkData* walkData; + + walkData = (struct updateNsWalkData*)userData; + listener = walkData->listener; + admin = d_listenerGetAdmin(d_listener(listener)); + + /* Create nameSpaces object from namespace, update total later */ + ns = d_nameSpacesNew(admin, n, d_nameSpaceGetInitialQuality(n), 0); + master = d_nameSpaceGetMaster(n); + d_nameSpacesSetMaster(ns, master); + d_networkAddressFree(master); + + /* Add namespaces object to listener */ + walkData->nameSpaces = c_iterAppend (walkData->nameSpaces, ns); +} + +static void +updateNameSpacesTotalWalk ( + void* o, + c_iterActionArg userData) +{ + c_ulong total; + d_nameSpaces ns; + + ns = d_nameSpaces(o); + + total = *((c_ulong*)userData); + + d_nameSpacesSetTotal(ns, total); +} + +/* TODO: NOT THREAD SAFE */ +static c_iter +updateNameSpaces( + d_nameSpacesRequestListener listener) +{ + d_admin admin; + c_ulong total; + c_iter nameSpaces; + struct updateNsWalkData walkData; + + admin = d_listenerGetAdmin (d_listener(listener)); + + /* Update nameSpaces */ + nameSpaces = c_iterNew (NULL); + walkData.listener = listener; + walkData.nameSpaces = nameSpaces; + + d_adminNameSpaceWalk (admin, updateNameSpacesWalk, &walkData); + total = c_iterLength (walkData.nameSpaces); + + /* Update totals */ + c_iterWalk (walkData.nameSpaces, updateNameSpacesTotalWalk, &total); + + return walkData.nameSpaces; +} + +static void +d_nameSpacesRequestListenerAction( + d_listener listener, + d_message message) +{ + d_durability durability; + d_admin admin; + d_configuration config; + d_fellow fellow; + d_publisher publisher; + c_ulong i, count; + d_nameSpaces ns; + d_networkAddress fellowAddr; + c_iter nameSpaces; + c_bool sendNow = FALSE; + + assert(d_nameSpacesRequestListenerIsValid(listener)); + + admin = d_listenerGetAdmin(listener); + durability = d_adminGetDurability(admin); + config = d_durabilityGetConfiguration(durability); + fellowAddr = d_networkAddressNew(message->senderAddress.systemId, + message->senderAddress.localId, + message->senderAddress.lifecycleId); + publisher = d_adminGetPublisher(admin); + + if (d_networkAddressIsUnaddressed(fellowAddr)) { + /* A nameSpacesRequest from (0,0,0) is received. This is + * interpreted as a request to send all my nameSpaces to + * everybody. */ + d_printTimedEvent(durability, D_LEVEL_FINE, + "Received a request to broadcast my nameSpaces.\n"); + sendNow = TRUE; + } else { + d_printTimedEvent(durability, D_LEVEL_FINE, + "Received nameSpacesRequest from fellow %u.\n", + fellowAddr->systemId); + /* This might be the first message received from the fellow + * Look up the fellow and create it if it did not exist */ + fellow = d_durabilityGetOrCreateFellowFromMessage(admin, fellowAddr, message); + /* At this point the fellow must be created unless it has recently + * terminated or is terminating/terminated. If the fellow is responsive we + * can answer the request and send the namespaces back. + * Otherwise we need to cache the request and sent the namespaces when the fellow + * becomes responsive. There is no need to lock the fellow because this is the only + * thread that can set has_requested_namespaces to TRUE */ + if (fellow) { + sendNow = d_fellowIsResponsive(fellow, config->waitForRemoteReaders); + if ((!sendNow) && (!fellow->has_requested_namespaces)) { + fellow->has_requested_namespaces = TRUE; + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Unable to send my namespace(s) to fellow %u because I have not yet received his capabilities, caching the request\n", + fellowAddr->systemId); + } + d_fellowFree(fellow); + } + } + if (sendNow) { + /* Update nameSpaces list for listener */ + nameSpaces = updateNameSpaces(d_nameSpacesRequestListener(listener)); + count = c_iterLength(nameSpaces); + d_printTimedEvent(durability, D_LEVEL_FINE, + "Sending %d namespace(s) to fellow %u.\n", + count, fellowAddr->systemId); + for(i=0; isystemId = systemId; + addr->localId = localId; + + /* Lifecycle is explicitly not used. A scan on where lifecycleId is used reveals that there is no + * logic depending on the lifecycle, other than comparision operations. It could therefore be + * removed as attribute, although this would mean a change in protocol. */ + OS_UNUSED_ARG(lifecycleId); + addr->lifecycleId = 0; + + return addr; +} + +void +d_networkAddressFree( + d_networkAddress addr) +{ + os_free(addr); +} + +c_bool +d_networkAddressEquals( + d_networkAddress addr1, + d_networkAddress addr2) +{ + c_bool result = FALSE; + + if( (addr1->systemId == addr2->systemId) && + (addr1->localId == addr2->localId) && + (addr1->lifecycleId == addr2->lifecycleId)) + { + result = TRUE; + } + return result; +} + +d_networkAddress +d_networkAddressUnaddressed() +{ + return d_networkAddressNew(0, 0, 0); +} + +c_bool +d_networkAddressIsUnaddressed( + d_networkAddress address) +{ + d_networkAddress addr; + c_bool result; + + addr = d_networkAddressUnaddressed(); + result = d_networkAddressEquals(address, addr); + d_networkAddressFree(addr); + + return result; + +} + +int +d_networkAddressCompare( + d_networkAddress addr1, + d_networkAddress addr2) +{ + int result; + + if(addr1 == addr2) { + result = 0; + } else if(!addr1) { + result = 1; + } else if(!addr2) { + result = -1; + } else if(addr1->systemId > addr2->systemId){ + result = 1; + } else if(addr1->systemId < addr2->systemId){ + result = -1; + } else if(addr1->localId > addr2->localId){ + result = 1; + } else if(addr1->localId < addr2->localId){ + result = -1; + } else if(addr1->lifecycleId > addr2->lifecycleId){ + result = 1; + } else if(addr1->lifecycleId < addr2->lifecycleId){ + result = -1; + } else { + result = 0; + } + return result; +} diff --git a/src/services/durability/code/d_newGroup.c b/src/services/durability/code/d_newGroup.c new file mode 100644 index 000000000..b05d61d14 --- /dev/null +++ b/src/services/durability/code/d_newGroup.c @@ -0,0 +1,118 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "d_newGroup.h" +#include "d_message.h" +#include "os_heap.h" +#include "os_stdlib.h" +#include "d__misc.h" + +_Ret_notnull_ +d_newGroup +d_newGroupNew( + _In_ d_admin admin, + _In_opt_z_ const c_char* partition, + _In_opt_z_ const c_char* topic, + _In_ d_durabilityKind kind, + _In_ d_completeness completeness, + _In_ d_quality quality) +{ + d_newGroup newGroup; + + newGroup = os_malloc(sizeof *newGroup); + d_messageInit(d_message(newGroup), admin); + + newGroup->partition = partition ? os_strdup(partition) : NULL; + newGroup->topic = topic ? os_strdup(topic) : NULL; + newGroup->durabilityKind = kind; + newGroup->completeness = completeness; + newGroup->alignerCount = 0; + /* Quality conversion */ + d_qualityExtFromQuality(&newGroup->quality, &quality, IS_Y2038READY(newGroup)); + + return newGroup; +} + +void +d_newGroupSetAlignerCount( + d_newGroup newGroup, + c_ulong count) +{ + if(newGroup){ + newGroup->alignerCount = count; + } +} + +void +d_newGroupFree( + d_newGroup newGroup) +{ + if(newGroup){ + if(newGroup->partition){ + os_free(newGroup->partition); + } + if(newGroup->topic){ + os_free(newGroup->topic); + } + d_messageDeinit(d_message(newGroup)); + os_free(newGroup); + } +} + +int +d_newGroupCompare( + d_newGroup g1, + d_newGroup g2) +{ + int r; + + if(g1 && g2){ + r = strcmp(g1->partition, g2->partition); + + if(r == 0){ + r = strcmp(g1->topic, g2->topic); + + if(r == 0){ + if(g1->durabilityKind != g2->durabilityKind){ + if(g1->durabilityKind == D_DURABILITY_PERSISTENT){ + r = 1; + } else if(g2->durabilityKind == D_DURABILITY_PERSISTENT){ + r = -1; + } else if(g1->durabilityKind == D_DURABILITY_TRANSIENT){ + r = 1; + } else if(g2->durabilityKind == D_DURABILITY_TRANSIENT){ + r = -1; + } else if(g1->durabilityKind == D_DURABILITY_TRANSIENT_LOCAL){ + r = 1; + } else if(g2->durabilityKind == D_DURABILITY_TRANSIENT_LOCAL){ + r = -1; + } else { + assert(FALSE); + } + } + } + } + } else if(!g1 && !g2){ + r = 0; + } else if(g1){ + r = 1; + } else { + r = -1; + } + return r; +} diff --git a/src/services/durability/code/d_object.c b/src/services/durability/code/d_object.c new file mode 100644 index 000000000..32eea8eb4 --- /dev/null +++ b/src/services/durability/code/d_object.c @@ -0,0 +1,329 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#include "d_object.h" +#include "os_abstract.h" +#include "os_atomics.h" +#include "os_heap.h" + +#define CHECK_REF (0) + +#if CHECK_REF +#include "os_stdlib.h" +#include "os_report.h" +#include "os_abstract.h" +#include "os_process.h" +#include "d__thread.h" +#include + +#define CHECK_REF_DEPTH (64) +static d_kind CHECK_REF_TYPE = D_NAMESPACE; +static char* CHECK_REF_FILE = NULL; +static c_bool CHECK_REF_TIMESTAMP = FALSE; + +#define UT_TRACE(msgFormat, ...) do { \ + void *tr[CHECK_REF_DEPTH];\ + char **strs;\ + int s,i;\ + FILE* stream; \ + \ + if(!CHECK_REF_FILE){ \ + CHECK_REF_FILE = os_malloc(24); \ + os_sprintf(CHECK_REF_FILE, "mem_%u.log", os_procIdSelf()); \ + } \ + s = backtrace(tr, CHECK_REF_DEPTH);\ + strs = backtrace_symbols(tr, s);\ + stream = fopen(CHECK_REF_FILE, "a");\ + if (CHECK_REF_TIMESTAMP) { \ + os_timeM now = os_timeMGet(); \ + fprintf(stream, "%" PA_PRItime " ", OS_TIMEM_PRINT(now)); \ + } \ + fprintf(stream, msgFormat, __VA_ARGS__);\ + for (i=0;iconfidence = D_CONFIDENCE; + object->kind = kind; + pa_st32(&object->refCount, 1); + object->deinit = deinit; +#if CHECK_REF + if (kind == CHECK_REF_TYPE) { + UT_TRACE("============ New(%p) [%s] =============\n", (void*)object, getThreadNameSelf()); + } +#endif + /* Increase the number of objects for this kind. + * The assert will only be activated when NDEBUG flag + * is not set. + */ + assert(doAdd(kind)); + } +} + + +void +d_objectDeinit( + d_object object) +{ + if (object) { + assert(object->confidence == D_CONFIDENCE); + assert(pa_ld32(&object->refCount) == 0); + + object->confidence = D_CONFIDENCE_NULL; + object->kind = D_BAD_TYPE; + /* After the deinit, the deinit cannot be called again. */ + object->deinit = NULL; + } +} + + +/** + * \brief Print an object allocation report when durability terminates + * + * The full report is printed under one of the following conditions + * + * 1. If the number of expected remaining objects is non-zero (specified by 'expected') + * 2. If the number of remaining objects differs from what was expected + * 3. If enable_allocation_report is non-zero. + * + * In all other cases a one-line allocation overview is printed. + * + * @return TRUE, if the remaining allocations coincide with what was expected, + * FALSe, otherwise + * + * NOTE: + * To force printing of a full report in it is possible to set the + * environment variable OSPL_DURABILITY_ALLOCATION_REPORT=1 + */ +c_bool +d_objectValidate( + c_ulong expected, + int enable_allocation_report) +{ + c_ulong i; + int header_printed = 0; + os_uint32 cnt = 0; + + for(i=1; iconfidence == D_CONFIDENCE); + assert(pa_ld32(&object->refCount) >= 1); +#if CHECK_REF || !defined NDEBUG + kind = object->kind; +#endif + refCount = pa_dec32_nv(&(object->refCount)); + /* Check that refCount did not cross zero boundary. */ + assert(refCount + 1 > refCount); + /* Only call deinit when refcount is 0. + * In this case no other thread waits for the object + * so deinitializing the object is safe without + * having to lock the object. + */ + if (refCount == 0) { + /* Call deinit of implementing class */ + if (object->deinit) { + object->deinit(object); + } + /* reset the object fields */ + object->confidence = D_CONFIDENCE_NULL; + object->kind = D_BAD_TYPE; + /* decrease the number of objects for this kind */ + assert(doSub(kind)); + /* free the object */ + os_free(object); + } +#if CHECK_REF + if (kind == CHECK_REF_TYPE) { + UT_TRACE("============ Free(%p): %d -> %d [%s] =============\n", + (void*)object, refCount+1, refCount, getThreadNameSelf()); + } +#endif + } +} + + +d_object +d_objectKeep( + d_object object) +{ + d_object result = NULL; + + if (object) { + assert(object->confidence == D_CONFIDENCE); +#if CHECK_REF + os_uint32 refCount = pa_inc32_nv(&(object->refCount)); + result = object; + if (object->kind == CHECK_REF_TYPE) { + UT_TRACE("============ Keep(%p): %d -> %d [%s] =============\n", + (void*)object, refCount-1, refCount, getThreadNameSelf()); + } +#else + pa_inc32(&(object->refCount)); + result = object; +#endif + } + return result; +} + + +c_bool +d_objectIsValid( + d_object object, + d_kind kind) +{ + c_bool result = FALSE; + + if (object) { + if ((object->kind == kind) && (object->confidence == D_CONFIDENCE)) { + result = TRUE; + } + } + return result; +} diff --git a/src/services/durability/code/d_pQos.c b/src/services/durability/code/d_pQos.c new file mode 100644 index 000000000..8f7f3bcf4 --- /dev/null +++ b/src/services/durability/code/d_pQos.c @@ -0,0 +1,78 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "c_base.h" +#include "v_topicQos.h" +#include "d__pQos.h" + +v_topicQos d_topicQosFromPQos (c_base base, const struct d_persistentTopicQosV0_s *pqos) +{ + struct v_topicInfo info; + info.durability = pqos->durability; + info.durabilityService = pqos->durabilityService; + info.deadline = pqos->deadline; + info.latency_budget = pqos->latency; + info.liveliness = pqos->liveliness; + info.reliability = pqos->reliability; + info.transport_priority = pqos->transport; + info.lifespan = pqos->lifespan; + info.destination_order = pqos->orderby; + info.history = pqos->history; + info.resource_limits = pqos->resource; + info.ownership = pqos->ownership; + info.topic_data.value = pqos->topicData.value; + return v_topicQosFromTopicInfo (base, &info); +} + +d_persistentTopicQosV0 d_pQosFromTopicQos (const struct v_topicQos_s *qos) +{ + c_base base = c_getBase ((c_object) qos); + c_type pqosType; + struct v_topicInfo info; + d_persistentTopicQosV0 pqos; + + pqosType = c_resolve (base, "durabilityModule2::d_persistentTopicQosV0"); + pqos = c_new (pqosType); + c_free (pqosType); + if (pqos == NULL) { + return NULL; + } + + if (v_topicQosFillTopicInfo (&info, qos) != V_RESULT_OK) { + c_free (pqos); + return NULL; + } + + pqos->_parent.kind = V_TOPIC_QOS; + pqos->durability = info.durability; + pqos->durabilityService = info.durabilityService; + pqos->deadline = info.deadline; + pqos->latency = info.latency_budget; + pqos->liveliness = info.liveliness; + pqos->reliability = info.reliability; + pqos->transport = info.transport_priority; + pqos->lifespan = info.lifespan; + pqos->orderby = info.destination_order; + pqos->history = info.history; + pqos->resource = info.resource_limits; + pqos->ownership = info.ownership; + pqos->topicData.value = info.topic_data.value; /* transfer refcount */ + pqos->topicData.size = (c_long) c_arraySize (info.topic_data.value); + + return pqos; +} diff --git a/src/services/durability/code/d_partitionTopicState.c b/src/services/durability/code/d_partitionTopicState.c new file mode 100644 index 000000000..3f9be3a7a --- /dev/null +++ b/src/services/durability/code/d_partitionTopicState.c @@ -0,0 +1,112 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#include "d__partitionTopicState.h" +#include "d__group.h" +#include "d__types.h" +#include "d__durabilityStateRequest.h" +#include "d__durability.h" +#include "d__misc.h" +#include "client_durabilitySplType.h" + + +/** + * \brief Create a partitionTopicState + */ +d_partitionTopicState +d_partitionTopicStateNew( + d_group group) +{ + d_partitionTopicState state; + + assert(d_groupIsValid(group)); + + /* Allocate partitionTopicState */ + state = d_partitionTopicState(os_malloc(C_SIZEOF(d_partitionTopicState))); + if (state) { + /* Call super-init */ + d_objectInit(d_object(state), D_PART_TOPIC_STATE, + (d_objectDeinitFunc)d_partitionTopicStateDeinit); + /* Initialize partitionTopicState */ + state->topic = d_groupGetTopic(group); /* uses os_strdup, so must be freed when deinit is called */ + if (!state->topic) { + goto err_allocPartitionTopicStateTopic; + } + state->partition = d_groupGetPartition(group); /* uses os_strdup, so must be freed when deinit is called */ + if (!state->partition) { + goto err_allocPartitionTopicStatePartition; + } + state->completeness = d_mapCompleteness(d_groupGetCompleteness(group)); + state->extensions = c_iterNew(NULL); + if (!state->extensions) { + goto err_allocPartitionTopicStateExtensions; + } + } + return state; + +err_allocPartitionTopicStateExtensions: +err_allocPartitionTopicStatePartition: +err_allocPartitionTopicStateTopic: + d_partitionTopicStateFree(state); + return NULL; +} + +/** + * \brief Deinitialize a partitionTopicState + */ +void +d_partitionTopicStateDeinit( + d_partitionTopicState state) +{ + struct _DDS_NameValue_t *extension; + + assert(d_partitionTopicStateIsValid(state)); + + if (state->topic) { + os_free(state->topic); + state->topic = NULL; + } + if (state->partition) { + os_free(state->partition); + state->partition = NULL; + } + if (state->extensions) { + extension = (struct _DDS_NameValue_t *)c_iterTakeFirst(state->extensions); + while (extension) { + os_free(extension); + extension = (struct _DDS_NameValue_t *)c_iterTakeFirst(state->extensions); + } + c_iterFree(state->extensions); + state->extensions = NULL; + } + /* call super-deinit */ + d_objectDeinit(d_object(state)); +} + + +/** + * \brief Free the durabilityState + */ +void +d_partitionTopicStateFree( + d_partitionTopicState state) +{ + assert(d_partitionTopicStateIsValid(state)); + + d_objectFree(d_object(state)); +} + diff --git a/src/services/durability/code/d_persistentDataListener.c b/src/services/durability/code/d_persistentDataListener.c new file mode 100644 index 000000000..e5bf035de --- /dev/null +++ b/src/services/durability/code/d_persistentDataListener.c @@ -0,0 +1,1159 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#include "d__persistentDataListener.h" +#include "d__admin.h" +#include "d__configuration.h" +#include "d__nameSpace.h" +#include "d__listener.h" +#include "d__durability.h" +#include "d__waitset.h" +#include "d__misc.h" +#include "d__table.h" +#include "d__thread.h" +#include "d__group.h" +#include "d__subscriber.h" +#include "d__eventListener.h" +#include "d__element.h" +#include "d_store.h" +#include "d_qos.h" +#include "u_groupQueue.h" +#include "u_entity.h" +#include "u_observable.h" +#include "v_observer.h" +#include "v_group.h" +#include "v_topic.h" +#include "v_message.h" +#include "v_partition.h" +#include "v_groupQueue.h" +#include "v_event.h" +#include "v_state.h" +#include "v_time.h" +#include "c_laptime.h" +#include "os_report.h" +#include "os_thread.h" +#include "os_abstract.h" +#include "os_atomics.h" + +/** + * Macro that checks the d_persistentDataListener validity. + * Because d_persistentDataListener is a concrete class typechecking is required. + */ +#define d_persistentDataListenerIsValid(_this) \ + d_listenerIsValidKind(d_listener(_this), D_PERSISTENT_DATA_LISTENER) + +/** + * \brief The d_persistentDataListener cast macro. + * + * This macro casts an object to a d_persistentDataListener object. + */ +#define d_persistentDataListener(_this) ((d_persistentDataListener)(_this)) + +/** + * \brief The d_persistentGroup cast macro. + * + * This macro casts an object to a d_persistentGroup object. + */ +#define d_persistentGroup(_this) ((d_persistentGroup)(_this)) +C_CLASS(d_persistentGroup); + +C_STRUCT(d_persistentGroup){ + v_group group; + c_ulong count; +}; + +struct persistentStatistics { + pa_uint32_t samplesStored; + pa_uint32_t samplesLifespanExpired; + pa_uint32_t instancesDisposed; + pa_uint32_t instancesCleanupDelayExpired; + pa_uint32_t instancesRegistered; + pa_uint32_t instancesUnregistered; + pa_uint32_t eventsDeleteHistoricalData; + pa_uint32_t eventsDisposeAll; + pa_uint32_t eventsTransactionComplete; + os_uint32 storeActions; + os_duration maxStoreTime; + os_duration minStoreTime; + os_duration maxTotalTime; + os_duration minTotalTime; + os_duration avgTotalTime; + os_duration avgStoreTime; +}; + +struct takeData { + d_persistentDataListener listener; + d_store persistentStore; + d_durability durability; +}; + +C_STRUCT(d_persistentDataListener){ + C_EXTENDS(d_listener); + u_groupQueue queue; + struct persistentStatistics pstats; + os_duration totalTime; + os_uint32 totalActions; + pa_uint32_t runCount; + os_mutex pmutex; + os_cond pcond; + os_mutex pauseMutex; + os_cond pauseCond; + d_waitsetEntity waitsetData; + d_table groups; + c_ulong optimizeUpdateInterval; + d_storeResult lastResult; + c_bool logStatistics; + c_bool sessionExpired; /* indicates whether the StoreSessionTime has expired or not; used in SMP */ +}; + +static d_storeResult +d_storeGroupAction( + v_groupAction msg, + d_persistentDataListener listener, + d_store persistentStore, + os_duration waitTime) +{ + d_storeResult result; + os_timeE startTime = os_timeEGet(); + d_thread self = d_threadLookupSelf (); + os_uint64 attempt = 0; + d_durability durability = d_threadsDurability(); + + switch(msg->kind){ + case V_GROUP_ACTION_WRITE: + do { + result = d_storeMessageStore(persistentStore, msg); + + if (result == D_STORE_RESULT_OK) { + pa_inc32(&(listener->pstats.samplesStored)); + } else if (result == D_STORE_RESULT_PRECONDITION_NOT_MET) { + attempt++; + d_sleep(self, waitTime); + } + /* Print log message in case PRECONDITION_NOT_MET has occurred, but only first and last time */ + if (((attempt == 1) && (result == D_STORE_RESULT_PRECONDITION_NOT_MET)) || + ((attempt != 0) && (result == D_STORE_RESULT_OK))) { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "d_storeMessageStore for group %s %s (attempt: %"PA_PRIu64")\n", v_groupName(msg->group), (result == D_STORE_RESULT_OK) ? "succeeded" : "failed", attempt); + } + } while(result == D_STORE_RESULT_PRECONDITION_NOT_MET); + break; + case V_GROUP_ACTION_DISPOSE: + do { + result = d_storeInstanceDispose(persistentStore, msg); + + if(result == D_STORE_RESULT_OK){ + pa_inc32(&(listener->pstats.instancesDisposed)); + } else if(result == D_STORE_RESULT_PRECONDITION_NOT_MET){ + attempt++; + d_sleep(self, waitTime); + } + /* Print log message in case PRECONDITION_NOT_MET has occurred, but only first and last time */ + if (((attempt == 1) && (result == D_STORE_RESULT_PRECONDITION_NOT_MET)) || + ((attempt != 0) && (result == D_STORE_RESULT_OK))) { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "d_storeInstanceDispose for group %s %s (attempt: %"PA_PRIu64")\n", v_groupName(msg->group), (result == D_STORE_RESULT_OK) ? "succeeded" : "failed", attempt); + } + } while(result == D_STORE_RESULT_PRECONDITION_NOT_MET); + + break; + case V_GROUP_ACTION_LIFESPAN_EXPIRE: + do { + result = d_storeMessageExpunge(persistentStore, msg); + + if(result == D_STORE_RESULT_OK){ + pa_inc32(&(listener->pstats.samplesLifespanExpired)); + } else if(result == D_STORE_RESULT_PRECONDITION_NOT_MET){ + attempt++; + d_sleep(self, waitTime); + } + /* Print log message in case PRECONDITION_NOT_MET has occurred, but only first and last time */ + if (((attempt == 1) && (result == D_STORE_RESULT_PRECONDITION_NOT_MET)) || + ((attempt != 0) && (result == D_STORE_RESULT_OK))) { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "d_storeMessageExpunge for group %s %s (attempt: %"PA_PRIu64")\n", v_groupName(msg->group), (result == D_STORE_RESULT_OK) ? "succeeded" : "failed", attempt); + } + } while(result == D_STORE_RESULT_PRECONDITION_NOT_MET); + break; + case V_GROUP_ACTION_CLEANUP_DELAY_EXPIRE: + do { + result = d_storeInstanceExpunge(persistentStore, msg); + + if(result == D_STORE_RESULT_OK){ + pa_inc32(&(listener->pstats.instancesCleanupDelayExpired)); + } else if(result == D_STORE_RESULT_PRECONDITION_NOT_MET){ + attempt++; + d_sleep(self, waitTime); + } + /* Print log message in case PRECONDITION_NOT_MET has occurred, but only first and last time */ + if (((attempt == 1) && (result == D_STORE_RESULT_PRECONDITION_NOT_MET)) || + ((attempt != 0) && (result == D_STORE_RESULT_OK))) { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "d_storeInstanceExpunge for group %s %s (attempt: %"PA_PRIu64")\n", v_groupName(msg->group), (result == D_STORE_RESULT_OK) ? "succeeded" : "failed", attempt); + } + } while(result == D_STORE_RESULT_PRECONDITION_NOT_MET); + break; + case V_GROUP_ACTION_DELETE_DATA: + do { + result = d_storeDeleteHistoricalData(persistentStore, msg); + + if(result == D_STORE_RESULT_OK){ + pa_inc32(&(listener->pstats.eventsDeleteHistoricalData)); + } else if(result == D_STORE_RESULT_PRECONDITION_NOT_MET){ + attempt++; + d_sleep(self, waitTime); + } + /* Print log message in case PRECONDITION_NOT_MET has occurred, but only first and last time */ + if (((attempt == 1) && (result == D_STORE_RESULT_PRECONDITION_NOT_MET)) || + ((attempt != 0) && (result == D_STORE_RESULT_OK))) { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "d_storeDeleteHistoricalData for group %s %s (attempt: %"PA_PRIu64")\n", v_groupName(msg->group), (result == D_STORE_RESULT_OK) ? "succeeded" : "failed", attempt); + } + } while(result == D_STORE_RESULT_PRECONDITION_NOT_MET); + break; + case V_GROUP_ACTION_REGISTER: + do { + result = d_storeInstanceRegister(persistentStore, msg); + + if(result == D_STORE_RESULT_OK){ + pa_inc32(&(listener->pstats.instancesRegistered)); + } else if(result == D_STORE_RESULT_PRECONDITION_NOT_MET){ + attempt++; + d_sleep(self, waitTime); + } + /* Print log message in case PRECONDITION_NOT_MET has occurred, but only first and last time */ + if (((attempt == 1) && (result == D_STORE_RESULT_PRECONDITION_NOT_MET)) || + ((attempt != 0) && (result == D_STORE_RESULT_OK))) { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "d_storeInstanceRegister for group %s %s (attempt: %"PA_PRIu64")\n", v_groupName(msg->group), (result == D_STORE_RESULT_OK) ? "succeeded" : "failed", attempt); + } + } while(result == D_STORE_RESULT_PRECONDITION_NOT_MET); + break; + case V_GROUP_ACTION_UNREGISTER: + do { + result = d_storeInstanceUnregister(persistentStore, msg); + + if(result == D_STORE_RESULT_OK){ + pa_inc32(&(listener->pstats.instancesUnregistered)); + } else if(result == D_STORE_RESULT_PRECONDITION_NOT_MET){ + attempt++; + d_sleep(self, waitTime); + } + /* Print log message in case PRECONDITION_NOT_MET has occurred, but only first and last time */ + if (((attempt == 1) && (result == D_STORE_RESULT_PRECONDITION_NOT_MET)) || + ((attempt != 0) && (result == D_STORE_RESULT_OK))) { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "d_storeInstanceUnregister for group %s %s (attempt: %"PA_PRIu64")\n", v_groupName(msg->group), (result == D_STORE_RESULT_OK) ? "succeeded" : "failed", attempt); + } + } while(result == D_STORE_RESULT_PRECONDITION_NOT_MET); + break; + case V_GROUP_ACTION_TRANSACTION_COMPLETE : + do { + result = d_storeTransactionComplete(persistentStore, msg); + + if(result == D_STORE_RESULT_OK){ + pa_inc32(&(listener->pstats.eventsTransactionComplete)); + } else if(result == D_STORE_RESULT_PRECONDITION_NOT_MET){ + attempt++; + d_sleep(self, waitTime); + } + /* Print log message in case PRECONDITION_NOT_MET has occurred, but only first and last time */ + if (((attempt == 1) && (result == D_STORE_RESULT_PRECONDITION_NOT_MET)) || + ((attempt != 0) && (result == D_STORE_RESULT_OK))) { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "d_storeTransactionComplete for group %s %s (attempt: %"PA_PRIu64")\n", v_groupName(msg->group), (result == D_STORE_RESULT_OK) ? "succeeded" : "failed", attempt); + } + } while(result == D_STORE_RESULT_PRECONDITION_NOT_MET); + break; + default: + OS_REPORT(OS_ERROR, D_CONTEXT, 0, + "storeGroupAction: Unknown or unsupported group action received (%d)", + msg->kind); + assert(FALSE); + result = D_STORE_RESULT_ERROR; + break; + } + if(listener->logStatistics == TRUE){ + os_timeE curTime; + os_duration storeTime, totalTime; + os_duration delta; + + curTime = os_timeEGet(); + storeTime = os_timeEDiff(curTime, startTime); + totalTime = os_timeEDiff(curTime, msg->actionTime); + + d_listenerLock(d_listener(listener)); + + listener->pstats.storeActions++; + + if(listener->pstats.storeActions == 1){ + listener->pstats.avgStoreTime = storeTime; + } else { + delta = os_durationSub(storeTime, listener->pstats.avgStoreTime) / listener->pstats.storeActions; + listener->pstats.avgStoreTime += delta; + } + + if(storeTime > listener->pstats.maxStoreTime){ + listener->pstats.maxStoreTime = storeTime; + } + if(storeTime < listener->pstats.minStoreTime){ + listener->pstats.minStoreTime = storeTime; + } + + if(listener->pstats.storeActions == 1){ + listener->pstats.avgTotalTime = totalTime; + } else { + delta = os_durationSub(totalTime, listener->pstats.avgTotalTime) / listener->pstats.storeActions; + listener->pstats.avgTotalTime += delta; + } + + if(totalTime > listener->pstats.maxTotalTime){ + listener->pstats.maxTotalTime = totalTime; + } + if(totalTime < listener->pstats.minTotalTime){ + listener->pstats.minTotalTime = totalTime; + } + d_listenerUnlock(d_listener(listener)); + } + if(result != D_STORE_RESULT_OK){ + if(listener->lastResult != result){ + OS_REPORT(OS_ERROR, D_CONTEXT, 0, + "storeGroupAction: Error in handling action on persistent storage. Action: '%d' and Reason: '%d'\n", + msg->kind, + result); + listener->lastResult = result; + } + } + return result; +} + +/* Output statistics to tracing. */ +static void d_persistentDataListenerOutputStats( + d_durability durability, + d_persistentDataListener listener, + struct persistentStatistics* oldStats, + os_duration totalTime) +{ + c_ulong samplesStored, samplesLifespanExpired; + c_ulong instancesDisposed, instancesCleanupDelayExpired; + c_ulong instancesRegistered, instancesUnregistered; + c_ulong eventsDeleteHistoricalData, eventsDisposeAll; + c_ulong eventsTransactionComplete; + c_ulong total; + + samplesStored = pa_ld32(&listener->pstats.samplesStored) - pa_ld32(&oldStats->samplesStored); + samplesLifespanExpired = pa_ld32(&listener->pstats.samplesLifespanExpired) - pa_ld32(&oldStats->samplesLifespanExpired); + instancesDisposed = pa_ld32(&listener->pstats.instancesDisposed) - pa_ld32(&oldStats->instancesDisposed); + instancesCleanupDelayExpired = pa_ld32(&listener->pstats.instancesCleanupDelayExpired) - pa_ld32(&oldStats->instancesCleanupDelayExpired); + instancesRegistered = pa_ld32(&listener->pstats.instancesRegistered) - pa_ld32(&oldStats->instancesRegistered); + instancesUnregistered = pa_ld32(&listener->pstats.instancesUnregistered) - pa_ld32(&oldStats->instancesUnregistered); + eventsDeleteHistoricalData = pa_ld32(&listener->pstats.eventsDeleteHistoricalData) - pa_ld32(&oldStats->eventsDeleteHistoricalData); + eventsDisposeAll = pa_ld32(&listener->pstats.eventsDisposeAll) - pa_ld32(&oldStats->eventsDisposeAll); + eventsTransactionComplete = pa_ld32(&listener->pstats.eventsTransactionComplete) - pa_ld32(&oldStats->eventsTransactionComplete); + total = samplesStored + samplesLifespanExpired + instancesDisposed + instancesCleanupDelayExpired + + instancesRegistered + instancesUnregistered + eventsDeleteHistoricalData + eventsDisposeAll; + + if(total != 0){ + listener->totalActions += total; + listener->totalTime = os_durationAdd(listener->totalTime, totalTime); + + if (listener->logStatistics) { + + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Current:\n" \ + "samplesStored=%u, " \ + "samplesLifespanExpired=%u, " \ + "instancesDisposed=%u, " \ + "instancesCleanupDelayExpired=%u, " \ + "instancesRegistered=%u, " \ + "instancesUnregistered=%u, " \ + "eventsDeleteHistoricalData=%u, " \ + "eventsDisposeAll=%u, " \ + "eventsTranactionComplete=%u\n", \ + samplesStored, + samplesLifespanExpired, + instancesDisposed, + instancesCleanupDelayExpired, + instancesRegistered, + instancesUnregistered, + eventsDeleteHistoricalData, + eventsDisposeAll, + eventsTransactionComplete); + + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Current: performed %d persistent store actions in %.6f seconds (%.2f actions/sec)\n", + total, os_durationToReal(totalTime), ((double)total)/os_durationToReal(totalTime)); + + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Total: performed %d persistent store actions in %.6f seconds (%.2f actions/sec)\n", + listener->totalActions, os_durationToReal(listener->totalTime), + ((double)listener->totalActions)/os_durationToReal(listener->totalTime)); + + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Time to get sample persisted after writing: " + "avg: %.3f ms, min: %.3f ms, max: %.3f ms\n", + os_durationToReal(listener->pstats.avgTotalTime) * 1000.000000, + os_durationToReal(listener->pstats.minTotalTime) * 1000.000000, + os_durationToReal(listener->pstats.maxTotalTime) * 1000.000000); + + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Time to get sample persisted after receiving: " + "avg: %.3f ms, min: %.3f ms, max: %.3f ms\n", + os_durationToReal(listener->pstats.avgStoreTime) * 1000.000000, + os_durationToReal(listener->pstats.minStoreTime) * 1000.000000, + os_durationToReal(listener->pstats.maxStoreTime)* 1000.000000); + } + } + +} + +static void +d_getKernelEntity( + v_public entity, + c_voidp args) +{ + v_entity* e; + + e = (v_entity*)args; + *e = v_entity(entity); +} + +static d_persistentGroup +d_persistentGroupNew( + const v_group group) +{ + d_persistentGroup g = NULL; + + g = d_persistentGroup(os_malloc(C_SIZEOF(d_persistentGroup))); + + if(g){ + g->count = 0; + + if(group){ + g->group = c_keep(group); + } else { + g->group = NULL; + } + } + return g; +} + +static void +d_persistentGroupFree( + d_persistentGroup g) +{ + assert(g); + assert(g->group); + + if(g->group){ + c_free (g->group); + } + os_free(g); +} + +static int +d_persistentGroupCompare( + d_persistentGroup g1, + d_persistentGroup g2) +{ + int result; + + assert(g1); + assert(g2); + + result = strcmp(v_partitionName(v_groupPartition(g1->group)), + v_partitionName(v_groupPartition(g2->group))); + + if(result == 0){ + result = strcmp(v_topicName(v_groupTopic(g1->group)), + v_topicName(v_groupTopic(g2->group))); + } + return result; +} + +struct optimizeGroups { + d_store store; + d_admin admin; + c_ulong optimizePoint; +}; + +static c_bool +optimize( + d_persistentGroup group, + c_voidp args) +{ + d_group localGroup; + struct optimizeGroups *og; + d_durability durability; + os_duration duration; + c_bool terminate; + c_bool result = TRUE; + + og = (struct optimizeGroups *)args; + + + if (group->count >= og->optimizePoint) { + localGroup = d_adminGetLocalGroup( + og->admin, + v_partitionName(v_groupPartition(group->group)), + v_topicName(v_groupTopic(group->group)), + D_DURABILITY_PERSISTENT); + if(localGroup){ + os_timeM before = os_timeMGet(); + durability = d_adminGetDurability(og->admin); + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Start optimization of group '%s.%s' after %d writes.\n", + v_partitionName(v_groupPartition(group->group)), + v_topicName(v_groupTopic(group->group)), + group->count); + + d_storeOptimizeGroup(og->store, localGroup); + duration = os_timeMDiff(os_timeMGet(), before); + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Optimization of group '%s.%s' took %f seconds.\n", + v_partitionName(v_groupPartition(group->group)), + v_topicName(v_groupTopic(group->group)), + os_durationToReal(duration)); + + group->count = 0; + terminate = d_durabilityMustTerminate(durability); + + if(terminate){ + result = FALSE; + } + } + } + return result; +} + + +static void +d_persistentDataListenerTake( + v_public entity, + c_voidp args) +{ + d_thread self = d_threadLookupSelf (); + v_groupQueue queue; + v_groupAction msg; + struct takeData* data; + struct optimizeGroups og; + d_storeResult result; + d_persistentGroup pg, pgOld; + c_bool doOptimize = FALSE; + c_bool terminate; + c_bool sessionExpired; + os_duration waitInSessionTime = OS_DURATION_INIT(0, 10000000); /* 10 ms */ + os_duration waitInSleepTime = OS_DURATION_INIT(0, 10000000); /* 10 ms */ + os_duration waitTime = OS_DURATION_INIT(0, 100000000); /* 10 ms */ + os_duration totalTime; + os_timeM startTime, sessionEndTime; + d_configuration config; + struct persistentStatistics stats; + + assert(C_TYPECHECK(entity, v_groupQueue)); + + data = (struct takeData*)args; + queue = v_groupQueue(entity); + config = d_durabilityGetConfiguration(data->durability); + /* Set the waitInSessionTime to min(10ms, 0.1 * StoreSessionTime)). + * This is the time used to check to for expiration of the StoreSessionTime + * while waiting for data during a session */ + if (os_durationCompare(os_durationMul(config->persistentStoreSessionTime, (double)0.1), waitInSessionTime) == OS_LESS) { + waitInSessionTime = os_durationMul(config->persistentStoreSessionTime, (double)0.1); + } + /* Set the waitInSleepTime to min(10ms, 0.1 * StoreSleepTime)). + * This is the time used to check for expiration of the StoreSleepTime + * while in a sleep */ + if (os_durationCompare(os_durationMul(config->persistentStoreSleepTime, (double)0.1), waitInSleepTime) == OS_LESS) { + waitInSleepTime = os_durationMul(config->persistentStoreSleepTime, (double)0.1); + } + + terminate = d_durabilityMustTerminate(data->durability); + while (!terminate && v_groupQueueSize(queue) > 0) { + memcpy(&stats, &(data->listener->pstats), sizeof(struct persistentStatistics)); + startTime = os_timeMGet(); + sessionEndTime = os_timeMAdd(startTime, config->persistentStoreSessionTime); + d_storeActionStart(data->persistentStore); + + /* StoreSessionTime loop */ + do { + d_threadAwake (self); + msg = v_groupQueueTake(queue); + if (msg) { + /* Store message */ + result = d_storeGroupAction(msg, + data->listener, + data->persistentStore, + waitTime); + /* Set the last result */ + data->listener->lastResult = result; + if ((result == D_STORE_RESULT_OK) && (data->listener->optimizeUpdateInterval != 0)) { + /* create a d_persistentGroupNew() (if not yet exists) */ + pg = d_persistentGroupNew(msg->group); + pgOld = d_tableInsert(data->listener->groups, pg); + if (pgOld) { + /* persistent group already existed */ + d_persistentGroupFree(pg); + pg = pgOld; + } + /* update the number of persistent groups */ + pg->count++; + if (pg->count >= data->listener->optimizeUpdateInterval) { + doOptimize = TRUE; + } + } + c_free(msg); + } else { + /* The queue was empty, wait a small amount of time + * before checking again */ + d_sleep(self, waitInSessionTime); + } + sessionExpired = (os_timeMCompare(sessionEndTime, os_timeMGet()) == OS_LESS); + terminate = d_durabilityMustTerminate(data->durability); + } while ((!sessionExpired) && (!terminate)); + + d_storeActionStop(data->persistentStore); /* This can take long when */ + + /* Output statistics to tracing */ + totalTime = os_timeMDiff(os_timeMGet(), startTime); + d_persistentDataListenerOutputStats( + data->durability, + data->listener, + &stats, + totalTime); + + /* If terminate then return. + * Because the d_storeActionStop can take long we are going + * to recheck whether to terminate or not. */ + if ((terminate = d_durabilityMustTerminate(data->durability)) == TRUE) { + return; + } + + /* Optimize when needed */ + if (doOptimize == TRUE) { + og.admin = d_listenerGetAdmin(d_listener(data->listener)); + og.store = data->persistentStore; + og.optimizePoint = data->listener->optimizeUpdateInterval; + if (!d_tableWalk(data->listener->groups, optimize, &og)) + { + OS_REPORT(OS_CRITICAL, "d_persistentDataListenerTake", 0, + "d_tableWalk failed : inconsistent administration"); + d_durabilityTerminate(data->durability, TRUE); + } + } + + /* If terminate then return. + * Because the optimize can take long we are going + * to recheck whether to terminate or not. */ + if ((terminate = d_durabilityMustTerminate(data->durability)) == TRUE) { + return; + } + + if (os_durationCompare(config->persistentStoreSleepTime, OS_DURATION_ZERO) == OS_MORE) { + /* StoreSleepTime loop */ + sessionEndTime = os_timeMAdd(os_timeMGet(), config->persistentStoreSleepTime); + do { + d_sleep(self, waitInSleepTime); + sessionExpired = (os_timeMCompare(sessionEndTime, os_timeMGet()) == OS_LESS); + terminate = d_durabilityMustTerminate(data->durability); + } while ((!sessionExpired) && (!terminate) && (v_groupQueueSize(queue) == 0)); + } + } /* while */ + + terminate = d_durabilityMustTerminate(data->durability); + if (terminate) { + if (queue->size > 0) { + d_printTimedEvent(data->durability, D_LEVEL_FINEST, + "d_persistentDataListenerTake: terminating but '%u' messages are still in the queue.\n", + queue->size); + } + } +} + + +static void +flushRemainingPersistentData( + d_persistentDataListener listener) +{ + os_timeM now, endTime, commitEndTime; + os_duration persistDuration; + os_duration commitDuration = OS_DURATION_INIT(1,0); + os_duration waitTime = OS_DURATION_INIT(0, 100000000); /* 100 ms */ + d_durability durability; + d_admin admin; + d_configuration config; + d_thread self = d_threadLookupSelf (); + c_ulong count = 0; + v_groupAction msg; + v_groupQueue queue; + d_subscriber subscriber; + d_store store; + u_result ures; + c_ulong size; + + admin = d_listenerGetAdmin(d_listener(listener)); + durability = d_adminGetDurability(admin); + config = d_durabilityGetConfiguration(durability); + subscriber = d_adminGetSubscriber(admin); + store = d_subscriberGetPersistentStore(subscriber); + + ures = u_observableAction(u_observable(listener->queue), d_getKernelEntity, &queue); + if (ures != U_RESULT_OK) { + d_printTimedEvent(durability, D_LEVEL_WARNING, + "Out of memory: any remaining persisting data will NOT be saved.\n"); + goto err_get_queue; + } + + if (os_durationCompare(config->serviceTerminatePeriod, OS_DURATION_ZERO) == OS_EQUAL) { + d_printTimedEvent(durability, D_LEVEL_WARNING, + "The service termination period is 0.0s, any remaining persisting data will NOT be saved.\n"); + } else { + now = os_timeMGet(); + /* If there is any persistent data in the queue we try + * to persist the data for a period of 70% of the service + * termination period. While saving the data we will NOT + * respect the StoreSessionTime and StoreSleepTime in an + * attempt to save as much data as possible. To reduce + * the risk of losing data the commit interval is set to + * the min(1s, 10% of the time that is available to commit). + * When persisting the data we do NOT optimize, even if + * config->optimizeUpdateInterval != 0. This is because + * we have limited time and want to use all the available + * time to store data. */ + persistDuration = os_durationMul(config->serviceTerminatePeriod, (double)0.7); + endTime = os_timeMAdd(now, persistDuration); + if (os_durationCompare(os_durationMul(persistDuration, (double)0.1), commitDuration) == OS_LESS) { + commitDuration = os_durationMul(persistDuration, (double)0.1); + } + d_printTimedEvent(durability, D_LEVEL_FINER, + "Trying to persist any available persistent data for %"PA_PRIduration" seconds\n", + OS_DURATION_PRINT(persistDuration)); + /* Set the end marker. Any data AFTER this marker will NOT be persisted. */ + v_groupQueueSetMarker(queue); + size = v_groupQueueSize(queue); + msg = v_groupQueueTake(queue); + now = os_timeMGet(); + while ( (msg != NULL) && + (os_timeMCompare(now, endTime) == OS_LESS) ) { + commitEndTime = os_timeMAdd(now, commitDuration); + if (os_timeMCompare(endTime, commitEndTime) == OS_LESS) { + commitEndTime = endTime; + } + d_storeActionStart(store); + while ((msg != NULL) && + (os_timeMCompare(now, commitEndTime) == OS_LESS)) { + d_threadAwake(self); + /* store message */ + (void)d_storeGroupAction(msg, + listener, + store, + waitTime); + count++; + c_free(msg); + now = os_timeMGet(); + msg = v_groupQueueTake(queue); + } /* while */ + d_storeActionStop(store); + now = os_timeMGet(); + } /* while */ + if (msg == NULL) { + /* All messages are saved within the service termination period */ + d_printTimedEvent(durability, D_LEVEL_FINEST, + "All (%u of %u) persistent messages stored before the service termination period expired.\n", + count, size); + } else { + d_printTimedEvent(durability, D_LEVEL_WARNING, + "Some (%u of %u) persistent messages stored before the service termination period expired.\n", + count, size); + } + } + +err_get_queue: + return; +} + +static c_bool +addElementExpr ( + d_element element, + c_voidp userData) { + c_iter exprList; + + exprList = userData; + + assert(exprList); /* exprList will always exist. */ + + c_iterInsert(exprList, d_elementGetExpression(element)); + + return TRUE; +} + +static c_iter +d_persistentDataListenerGetGroupExpr( + d_persistentDataListener listener) +{ + d_admin admin; + d_nameSpace ns; + d_durabilityKind dkind; + c_iter exprList; + c_ulong i; + c_iter nameSpaces; + + admin = d_listenerGetAdmin(d_listener(listener)); + nameSpaces = NULL; + exprList = c_iterNew(NULL); + + assert (admin); + + /* Collect namespaces */ + nameSpaces = d_adminNameSpaceCollect(admin); + + for(i=0; iqueue) { + u_objectFree(u_object(listener->queue)); + listener->queue = NULL; + } + d_tableFree(listener->groups); + + os_condDestroy(&(listener->pcond)); + os_condDestroy(&(listener->pauseCond)); + os_mutexDestroy(&(listener->pmutex)); + os_mutexDestroy(&(listener->pauseMutex)); + /* Call super-deinit */ + d_listenerDeinit(d_listener(listener)); +} + +static void +freeExpression( + void* o, + void* udata) +{ + OS_UNUSED_ARG(udata); + d_free(o); +} + +static void +d_persistentDataListenerFreeGroupExpr( + c_iter expr) +{ + c_iterWalk(expr, freeExpression, NULL); + c_iterFree(expr); +} + + +static void +d_persistentDataListenerInit( + d_persistentDataListener listener, + d_subscriber subscriber) +{ + u_subscriber usubscriber; + d_configuration config; + d_durability durability; + d_admin admin; + v_readerQos qos; + c_iter expr; + + /* Do not assert the persistentDataListener because + * the initialization of the listener has not yet completed */ + + assert(d_subscriberIsValid(subscriber)); + assert(listener); + + /* Call super-init */ + d_listenerInit(d_listener(listener), D_PERSISTENT_DATA_LISTENER, subscriber, NULL, + (d_objectDeinitFunc)d_persistentDataListenerDeinit); + /* Initialize the persistentDataListener */ + admin = d_listenerGetAdmin(d_listener(listener)); + durability = d_adminGetDurability(admin); + config = d_durabilityGetConfiguration(durability); + listener->groups = d_tableNew(d_persistentGroupCompare, d_persistentGroupFree); + usubscriber = d_subscriberGetPersistentSubscriber(subscriber); + qos = d_readerQosNew(V_DURABILITY_PERSISTENT, V_RELIABILITY_RELIABLE); + /* Collect expressions from matching namespaces */ + expr = d_persistentDataListenerGetGroupExpr(listener); + listener->queue = u_groupQueueNew(usubscriber, "persistentQueue", + config->persistentQueueSize, qos, expr); + /* Free expressionlist */ + d_persistentDataListenerFreeGroupExpr(expr); + + listener->optimizeUpdateInterval = config->persistentUpdateInterval; + listener->lastResult = D_STORE_RESULT_OK; + d_readerQosFree(qos); + pa_st32(&listener->pstats.samplesStored, 0); + pa_st32(&listener->pstats.samplesLifespanExpired, 0); + pa_st32(&listener->pstats.instancesDisposed, 0); + pa_st32(&listener->pstats.instancesCleanupDelayExpired, 0); + pa_st32(&listener->pstats.instancesRegistered, 0); + pa_st32(&listener->pstats.instancesUnregistered, 0); + pa_st32(&listener->pstats.eventsDeleteHistoricalData, 0); + pa_st32(&listener->pstats.eventsDisposeAll, 0); + pa_st32(&listener->pstats.eventsTransactionComplete, 0); + listener->pstats.storeActions = 0; + listener->pstats.avgStoreTime = 0.0; + listener->pstats.maxStoreTime = 0.0; + listener->pstats.minStoreTime = 123456789.0; + listener->pstats.avgTotalTime = 0.0; + listener->pstats.maxTotalTime = 0.0; + listener->pstats.minTotalTime = 123456789.0; + listener->logStatistics = FALSE; + + { + char *p; + if ((p = os_getenv ("OSPL_DURABILITY_LOG_STATISTICS")) != NULL && atoi (p) != 0) { + listener->logStatistics = TRUE; + } + } + + os_mutexInit(&(listener->pmutex), NULL); + os_mutexInit(&(listener->pauseMutex), NULL); + + os_condInit(&(listener->pcond), &(listener->pmutex), NULL); + os_condInit(&(listener->pauseCond), &(listener->pauseMutex), NULL); + + listener->totalTime = OS_DURATION_ZERO; + listener->totalActions = 0; + u_entityEnable(u_entity(listener->queue)); +} + +d_persistentDataListener +d_persistentDataListenerNew( + d_subscriber subscriber) +{ + d_persistentDataListener listener; + + assert(d_subscriberIsValid(subscriber)); + + /* Allocate persistentDataListener object */ + listener = d_persistentDataListener(os_malloc(C_SIZEOF(d_persistentDataListener))); + if (listener) { + /* Initialize the persistentDataListener */ + d_persistentDataListenerInit(listener, subscriber); + } + return listener; +} + +void +d_persistentDataListenerFree( + d_persistentDataListener listener) +{ + assert(d_persistentDataListener(listener)); + + d_objectFree(d_object(listener)); +} + +static void +setMask ( + v_public p, c_voidp arg) +{ + c_ulong mask = *((c_ulong *)arg); + + v_observerSetEventMask(v_observer(p), mask); +} + +c_ulong +d_persistentDataListenerAction( + u_object o, + v_waitsetEvent event, + c_voidp usrData) +{ + d_thread self = d_threadLookupSelf (); + d_persistentDataListener listener; + d_admin admin; + d_subscriber subscriber; + struct takeData data; + c_bool terminate; + d_serviceState state; + os_duration sleepTime = OS_DURATION_INIT(0, 100000000); /* 100 ms */ + + listener = d_persistentDataListener(usrData); + + if ((event->kind & V_EVENT_DATA_AVAILABLE) == V_EVENT_DATA_AVAILABLE) { + admin = d_listenerGetAdmin(d_listener(listener)); + subscriber = d_adminGetSubscriber(admin); + + data.listener = listener; + data.persistentStore = d_subscriberGetPersistentStore(subscriber); + data.durability = d_adminGetDurability(admin); + + terminate = d_durabilityMustTerminate(data.durability); + state = d_durabilityGetState(data.durability); + + /*Do not store persistent data before it has been injected*/ + while((terminate == FALSE) && + ( + (state == D_STATE_INJECT_PERSISTENT) || + (state == D_STATE_INIT) || + (state == D_STATE_DISCOVER_PERSISTENT_SOURCE) || + (state == D_STATE_DISCOVER_FELLOWS_GROUPS) + ) + ) + { + d_sleep(self, sleepTime); + terminate = d_durabilityMustTerminate(data.durability); + state = d_durabilityGetState(data.durability); + } + + + (void)u_observableAction(u_observable(o), d_persistentDataListenerTake, &data); + } + return event->kind; +} + +c_bool +d_persistentDataListenerStart( + d_persistentDataListener listener) +{ + c_bool result; + u_object object; + u_result ur; + + d_admin admin; + d_subscriber subscriber; + c_bool wsResult; + d_waitset waitset; + d_waitsetAction action; + d_durability durability; + d_configuration configuration; + c_ulong mask; + + assert(listener); + result = FALSE; + assert(d_objectIsValid(d_object(listener), D_LISTENER)); + + if(listener){ + d_listenerLock(d_listener(listener)); + if ((object = u_object(listener->queue)) == NULL) { + d_listenerUnlock(d_listener(listener)); + return FALSE; + } + action = d_persistentDataListenerAction; + admin = d_listenerGetAdmin(d_listener(listener)); + durability = d_adminGetDurability(admin); + configuration = d_durabilityGetConfiguration(durability); + subscriber = d_adminGetSubscriber(admin); + + if(d_listener(listener)->attached == FALSE){ + listener->totalTime = OS_DURATION_ZERO; + listener->totalActions = 0; + + mask = V_EVENT_DATA_AVAILABLE; + ur = u_observableAction(u_observable(object), setMask, &mask); + + if(ur == U_RESULT_OK){ + waitset = d_subscriberGetWaitset(subscriber); + listener->waitsetData = d_waitsetEntityNew( + "persistentDataListener", + object, action, + V_EVENT_DATA_AVAILABLE, + configuration->persistentScheduling, listener); + wsResult = d_waitsetAttach(waitset, listener->waitsetData); + + if(wsResult == TRUE) { + ur = U_RESULT_OK; + } else { + ur = U_RESULT_ILL_PARAM; + } + if(ur == U_RESULT_OK){ + d_listener(listener)->attached = TRUE; + result = TRUE; + d_listenerUnlock(d_listener(listener)); + (void) u_observableNotify(u_observable(object)); + } else { + d_listenerUnlock(d_listener(listener)); + } + } else { + d_listenerUnlock(d_listener(listener)); + } + } else { + d_listenerUnlock(d_listener(listener)); + result = TRUE; + } + } + return result; +} + +c_bool +d_persistentDataListenerStop( + d_persistentDataListener listener) +{ + c_bool result; + u_result ur; + d_admin admin; + d_subscriber subscriber; + d_waitset waitset; + + assert(d_objectIsValid(d_object(listener), D_LISTENER)); + result = FALSE; + + if(listener){ + d_listenerLock(d_listener(listener)); + + if(d_listener(listener)->attached == TRUE){ + admin = d_listenerGetAdmin(d_listener(listener)); + subscriber = d_adminGetSubscriber(admin); + waitset = d_subscriberGetWaitset(subscriber); + result = d_waitsetDetach(waitset, listener->waitsetData); + + if(result == TRUE) { + d_waitsetEntityFree(listener->waitsetData); + + os_mutexLock(&(listener->pmutex)); + os_condBroadcast(&(listener->pcond)); + os_mutexUnlock(&(listener->pmutex)); + + ur = U_RESULT_OK; + } else { + ur = U_RESULT_ILL_PARAM; + } + + if(ur == U_RESULT_OK){ + d_listener(listener)->attached = FALSE; + result = TRUE; + } + } else { + result = TRUE; + } + d_listenerUnlock(d_listener(listener)); + } + return result; +} diff --git a/src/services/durability/code/d_policy.c b/src/services/durability/code/d_policy.c new file mode 100644 index 000000000..77b181d38 --- /dev/null +++ b/src/services/durability/code/d_policy.c @@ -0,0 +1,259 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "d__policy.h" +#include "d__misc.h" +#include "d__thread.h" +#include "d__durability.h" +#include "d__configuration.h" + +void +d_policyDeinit ( + d_policy policy) +{ + d_policyMergeRule* mergeRule; + + assert(d_policyIsValid(policy)); + + if (policy->mergePolicyRules) { + mergeRule = (d_policyMergeRule*)c_iterTakeFirst (policy->mergePolicyRules); + while (mergeRule) { + os_free (mergeRule->scope); + d_free (mergeRule); + mergeRule = c_iterTakeFirst (policy->mergePolicyRules); + } + c_iterFree (policy->mergePolicyRules); + } + if (policy->nameSpace) { + os_free(policy->nameSpace); + } + /* Call super-deinit */ + d_objectDeinit(d_object(policy)); +} + +d_policy +d_policyNew ( + const char* namespace, + c_bool aligner, + d_alignmentKind alignmentKind, + c_bool delayedAlignment, + d_durabilityKind durabilityKind, + c_bool equalityCheck, + c_ulong masterPriority) +{ + d_policy policy; + + /* Allocate policy object */ + policy = d_policy(d_malloc(C_SIZEOF(d_policy), "Policy")); + if (policy != NULL){ + /* Call super-init */ + d_objectInit(d_object(policy), D_POLICY, + (d_objectDeinitFunc)d_policyDeinit); + /* Initialize policy object */ + if (namespace != NULL) { + policy->nameSpace = os_strdup(namespace); + } else { + policy->nameSpace = os_strdup("*"); + } + policy->aligner = aligner; + policy->alignmentKind = alignmentKind; + policy->durabilityKind = durabilityKind; + policy->delayedAlignment = delayedAlignment; + policy->mergePolicyRules = NULL; + policy->equalityCheck = equalityCheck; + policy->masterPriority = masterPriority; + } + return policy; +} + +c_bool +d_policyGetAligner ( + d_policy policy) +{ + c_bool aligner; + + aligner = FALSE; + + if (d_objectIsValid(d_object(policy), D_POLICY)){ + aligner = policy->aligner; + } + + return aligner; +} + +c_bool +d_policyGetEqualityCheck ( + d_policy policy) +{ + assert(d_policyIsValid(policy)); + + return policy->equalityCheck; +} + +c_ulong +d_policyGetMasterPriority ( + d_policy policy) +{ + assert(d_policyIsValid(policy)); + + return policy->masterPriority; +} + +d_alignmentKind +d_policyGetAlignmentKind ( + d_policy policy) +{ + d_alignmentKind alignmentKind; + + alignmentKind = D_ALIGNEE_INITIAL; + + if (d_objectIsValid(d_object(policy), D_POLICY)){ + alignmentKind = policy->alignmentKind; + } + + return alignmentKind; +} + +d_durabilityKind +d_policyGetDurabilityKind ( + d_policy policy) +{ + d_durabilityKind durabilityKind; + + durabilityKind = D_DURABILITY_ALL; + + if (d_objectIsValid(d_object(policy), D_POLICY)){ + durabilityKind = policy->durabilityKind; + } + + return durabilityKind; +} + +/* Get namespace pattern from policy */ +c_string +d_policyGetNameSpace ( + d_policy policy) +{ + c_string nameSpace = ""; + + if (d_objectIsValid(d_object(policy), D_POLICY)){ + nameSpace = policy->nameSpace; + } + + return nameSpace; +} + +void +d_policyFree( + d_policy policy ) +{ + if (policy) { + assert(d_policyIsValid(policy)); + } + + d_objectFree(d_object(policy)); +} + +void +d_policyAddMergeRule( + d_policy policy, + d_mergePolicy mergeType, + const char* scope) +{ + d_policyMergeRule* rule; + + rule = os_malloc (sizeof(d_policyMergeRule)); + assert (rule); + + rule->mergeType = mergeType; + rule->scope = os_strdup(scope); + + if (!policy->mergePolicyRules){ + policy->mergePolicyRules = c_iterNew (rule); + }else { + c_iterAppend (policy->mergePolicyRules, rule); + } +} + +struct matchMergePolicyHelper +{ + char* role; + d_mergePolicy mergeType; + c_bool found; +}; + +static void +matchMergePolicyWalk ( + void* o, + c_iterActionArg arg) +{ + d_policyMergeRule* rule; + struct matchMergePolicyHelper* helper; + + rule = (d_policyMergeRule*)o; + helper = (struct matchMergePolicyHelper*)arg; + + if (!helper->found) { + if (d_patternMatch (helper->role, rule->scope)) { + helper->mergeType = rule->mergeType; + helper->found = TRUE; + } + } +} + +/* Get merge rule from policy */ +/* TODO: scope matching should use same algorithm as networking! */ +d_mergePolicy +d_policyGetMergePolicy( + d_policy policy, + char* role) +{ + struct matchMergePolicyHelper helper; + d_mergePolicy result; + + helper.role = role; + helper.found = FALSE; + + /* Find rule for role */ + c_iterWalk (policy->mergePolicyRules, matchMergePolicyWalk, &helper); + + /* If no rule is found, do not merge */ + if (helper.found) { + result = helper.mergeType; + }else { + result = D_MERGE_IGNORE; + } + + return result; +} + +/* Get policy for delayed alignment */ +c_bool +d_policyGetDelayedAlignment ( + d_policy policy) +{ + c_bool delayedAlignment; + + delayedAlignment = FALSE; + + if (d_objectIsValid(d_object(policy), D_POLICY)){ + delayedAlignment = policy->delayedAlignment; + } + + return delayedAlignment; +} diff --git a/src/services/durability/code/d_publisher.c b/src/services/durability/code/d_publisher.c new file mode 100644 index 000000000..729d9c82c --- /dev/null +++ b/src/services/durability/code/d_publisher.c @@ -0,0 +1,2047 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "d__publisher.h" +#include "d__durability.h" +#include "d__configuration.h" +#include "d__admin.h" +#include "d__misc.h" +#include "d__historicalDataRequestListener.h" +#include "d__historicalDataRequest.h" +#include "d__durabilityState.h" +#include "d__partitionTopicState.h" +#include "d__historicalData.h" +#include "d__group.h" +#include "d__capability.h" +#include "d_message.h" +#include "d_status.h" +#include "d_sampleRequest.h" +#include "d_groupsRequest.h" +#include "d_nameSpaces.h" +#include "d_nameSpacesRequest.h" +#include "d__mergeState.h" +#include "d_deleteData.h" +#include "d_qos.h" +#include "d_sampleChain.h" +#include "u_observable.h" +#include "u_publisher.h" +#include "u_participant.h" +#include "u_writer.h" +#include "u_writerQos.h" +#include "v_time.h" +#include "v_writer.h" +#include "v_group.h" +#include "v_state.h" +#include "v_partition.h" +#include "os_heap.h" +#include "os_report.h" + + + +#define HISTORICAL_DATA_KIND_BEAD 0 +#define HISTORICAL_DATA_KIND_LINK 1 + +/* Message type */ +#define MESSAGE_FLAG_WRITE 0 +#define MESSAGE_FLAG_DISPOSE 1 +#define MESSAGE_FLAG_UNREGISTER 2 +#define MESSAGE_FLAG_WRITE_DISPOSE 3 + + +d_publisher +d_publisherNew( + d_admin admin) +{ + d_publisher publisher; + d_durability durability; + d_configuration config; + v_publisherQos publisherQos = NULL; + v_writerQos writerQos = NULL; + u_result result; + d_thread self = d_threadLookupSelf(); + + assert(d_adminIsValid(admin)); + + /* Allocate publisher object */ + publisher = d_publisher(os_malloc(C_SIZEOF(d_publisher))); + if (publisher) { + /* zero fill structure so d_publisherDeinit can safely be invoked */ + memset(publisher, 0, sizeof(C_STRUCT(d_publisher))); + /* Call super-init */ + d_objectInit(d_object(publisher), D_PUBLISHER, + (d_objectDeinitFunc)d_publisherDeinit); + /* Initialize publisher */ + publisher->enabled = TRUE; + publisher->admin = admin; + durability = d_adminGetDurability(admin); + config = d_durabilityGetConfiguration(durability); + /* Create the publisher for the durability protocol */ + publisherQos = d_publisherQosNew(config->partitionName); + if (publisherQos == NULL) { + goto cleanup_publisher; + } + publisher->publisher = u_publisherNew( + u_participant(d_durabilityGetService(durability)), + config->publisherName, publisherQos, TRUE); + d_publisherQosFree(publisherQos); + if (publisher->publisher == NULL) { + goto cleanup_publisher; + } + /* Create the publisher for client durability, but only + * if client durability is enabled. + */ + if (config->clientDurabilityEnabled) { + publisherQos = d_publisherQosNew(config->clientDurabilityPartitionName); + if (publisherQos == NULL) { + goto cleanup_publisher2; + } + publisher->publisher2 = u_publisherNew( + u_participant(d_durabilityGetService(durability)), + D_CLIENT_DURABILITY_PUBLISHER_NAME, publisherQos, TRUE); + d_publisherQosFree(publisherQos); + if (publisher->publisher2 == NULL) { + goto cleanup_publisher2; + } + } else { + publisher->publisher2 = NULL; + } + /* Cache capabilitySupport in the publisher to enable + * fast access in d_publisherInitMessage(). + */ + publisher->capabilitySupport = config->capabilitySupport; + + publisher->statusWriter = NULL; + publisher->newGroupWriter = NULL; + publisher->groupsRequestWriter = NULL; + publisher->sampleRequestWriter = NULL; + publisher->sampleChainWriter = NULL; + publisher->nameSpacesWriter = NULL; + publisher->nameSpacesRequestWriter = NULL; + publisher->deleteDataWriter = NULL; + publisher->durabilityStateWriter = NULL; + publisher->capabilityWriter = NULL; + + /* writerQos for status writer */ + writerQos = d_writerQosNew( + V_DURABILITY_VOLATILE, + V_RELIABILITY_RELIABLE, + V_ORDERBY_RECEPTIONTIME, + config->heartbeatLatencyBudget, + config->heartbeatTransportPriority); + if (writerQos == NULL) { + goto cleanup_publisher; + } + writerQos->history.v.kind = V_HISTORY_KEEPLAST; + writerQos->history.v.depth = 1; + + /* status writer */ + publisher->statusNumber = 0; + publisher->statusWriter = u_writerNew (publisher->publisher, + "statusWriter", + d_adminGetStatusTopic(admin), + writerQos); + if (publisher->statusWriter == NULL) { + goto cleanup_writerQos; + } + result = u_entityEnable(u_entity(publisher->statusWriter)); + if (result != U_RESULT_OK) { + goto cleanup_writerQos; + } + result = u_observableAction(u_observable(publisher->statusWriter), + d_publisherEnsureServicesAttached, + durability); + if (result != U_RESULT_OK) { + goto cleanup_writerQos; + } + /* Cleanup writerQos for statusWriter */ + d_writerQosFree(writerQos); + + /* writerQos for most durability protocol writers */ + writerQos = d_writerQosNew( + V_DURABILITY_VOLATILE, + V_RELIABILITY_RELIABLE, + V_ORDERBY_RECEPTIONTIME, + config->latencyBudget, + config->transportPriority); + if (writerQos == NULL) { + goto cleanup_publisher; + } + + /* Create the capability writer as one of the first writers because + * the capability topic is written as one of the first topic. + * This increases the chance that ddsi can connect to the writer before + * the message is written. + */ + if (config->capabilitySupport) { + /* capability writer, only created if capabilitySupported=TRUE */ + publisher->capabilityNumber = 0; + publisher->capabilityWriter = u_writerNew (publisher->publisher, + "capabilityWriter", + d_adminGetCapabilityTopic(admin), + writerQos); + if (publisher->capabilityWriter == NULL) { + goto cleanup_writerQos; + } + result = u_entityEnable(u_entity(publisher->capabilityWriter)); + if (result != U_RESULT_OK) { + goto cleanup_writerQos; + } + result = u_observableAction(u_observable(publisher->capabilityWriter), + d_publisherEnsureServicesAttached, + durability); + if (result != U_RESULT_OK) { + goto cleanup_writerQos; + } + } + + /* newGroup writer */ + publisher->newGroupNumber = 0; + publisher->newGroupWriter = u_writerNew (publisher->publisher, + "newGroupWriter", + d_adminGetNewGroupTopic(admin), + writerQos); + if (publisher->newGroupWriter == NULL) { + goto cleanup_writerQos; + } + result = u_entityEnable(u_entity(publisher->newGroupWriter)); + if (result != U_RESULT_OK) { + goto cleanup_writerQos; + } + result = u_observableAction(u_observable(publisher->newGroupWriter), + d_publisherEnsureServicesAttached, + durability); + if (result != U_RESULT_OK) { + goto cleanup_writerQos; + } + + /* groupsRequest writer */ + publisher->groupsRequestNumber = 0; + publisher->groupsRequestWriter = u_writerNew (publisher->publisher, + "groupsRequestWriter", + d_adminGetGroupsRequestTopic(admin), + writerQos); + if (publisher->groupsRequestWriter == NULL) { + goto cleanup_writerQos; + } + result = u_entityEnable(u_entity(publisher->groupsRequestWriter)); + if (result != U_RESULT_OK) { + goto cleanup_writerQos; + } + result = u_observableAction(u_observable(publisher->groupsRequestWriter), + d_publisherEnsureServicesAttached, + durability); + if (result != U_RESULT_OK) { + goto cleanup_writerQos; + } + + /* sampleRequest writer */ + publisher->sampleRequestNumber = 0; + publisher->sampleRequestWriter = u_writerNew (publisher->publisher, + "sampleRequestWriter", + d_adminGetSampleRequestTopic(admin), + writerQos); + if (publisher->sampleRequestWriter == NULL) { + d_writerQosFree(writerQos); + goto cleanup_publisher; + } + result = u_entityEnable(u_entity(publisher->sampleRequestWriter)); + if (result != U_RESULT_OK) { + goto cleanup_writerQos; + } + result = u_observableAction(u_observable(publisher->sampleRequestWriter), + d_publisherEnsureServicesAttached, + durability); + if (result != U_RESULT_OK) { + goto cleanup_writerQos; + } + + /* nameSpaces writer */ + publisher->nameSpacesNumber = 0; + publisher->nameSpacesWriter = u_writerNew (publisher->publisher, + "nameSpacesWriter", + d_adminGetNameSpacesTopic(admin), + writerQos); + if (publisher->nameSpacesWriter == NULL) { + goto cleanup_writerQos; + } + result = u_entityEnable(u_entity(publisher->nameSpacesWriter)); + if (result != U_RESULT_OK) { + goto cleanup_writerQos; + } + result = u_observableAction(u_observable(publisher->nameSpacesWriter), + d_publisherEnsureServicesAttached, + durability); + if (result != U_RESULT_OK) { + goto cleanup_writerQos; + } + + /* nameSpacesRequest writer */ + publisher->nameSpacesRequestNumber = 0; + publisher->nameSpacesRequestWriter = u_writerNew (publisher->publisher, + "nameSpacesRequestWriter", + d_adminGetNameSpacesRequestTopic(admin), + writerQos); + if (publisher->nameSpacesRequestWriter == NULL) { + goto cleanup_writerQos; + } + result = u_entityEnable(u_entity(publisher->nameSpacesRequestWriter)); + if (result != U_RESULT_OK) { + goto cleanup_writerQos; + } + result = u_observableAction(u_observable(publisher->nameSpacesRequestWriter), + d_publisherEnsureServicesAttached, + durability); + if (result != U_RESULT_OK) { + goto cleanup_writerQos; + } + + /* deleteData writer */ + publisher->deleteDataNumber = 0; + publisher->deleteDataWriter = u_writerNew (publisher->publisher, + "deleteDataWriter", + d_adminGetDeleteDataTopic(admin), + writerQos); + if (publisher->deleteDataWriter == NULL) { + goto cleanup_writerQos; + } + result = u_entityEnable(u_entity(publisher->deleteDataWriter)); + if (result != U_RESULT_OK) { + goto cleanup_writerQos; + } + result = u_observableAction(u_observable(publisher->deleteDataWriter), + d_publisherEnsureServicesAttached, + durability); + if (result != U_RESULT_OK) { + goto cleanup_writerQos; + } + + /* Cleanup writerQos for most durability protocol writers */ + d_writerQosFree(writerQos); + + if (config->clientDurabilityEnabled) { + + /* Set writerQos for durability state writer */ + writerQos = d_writerQosNew( + V_DURABILITY_VOLATILE, + V_RELIABILITY_RELIABLE, + V_ORDERBY_SOURCETIME, + config->heartbeatLatencyBudget, + config->heartbeatTransportPriority); + if (writerQos == NULL) { + goto cleanup_publisher; + } + + /* d_writerQosNew does not always return the proper settings. + * The following settings ensure that the writer qos is correct + */ + writerQos->reliability.v.max_blocking_time = OS_DURATION_INIT(0,100000000); + /* durabilityState writer */ + assert(publisher->publisher2); + publisher->durabilityStateNumber = 0; + publisher->durabilityStateWriter = u_writerNew(publisher->publisher2, + "durabilityStateWriter", + d_adminGetDurabilityStateTopic(admin), + writerQos); + if (publisher->durabilityStateWriter == NULL) { + goto cleanup_writerQos; + } + result = u_entityEnable(u_entity(publisher->durabilityStateWriter)); + if (result != U_RESULT_OK) { + goto cleanup_writerQos; + } + result = u_observableAction(u_observable(publisher->durabilityStateWriter), + d_publisherEnsureServicesAttached, + durability); + if (result != U_RESULT_OK) { + goto cleanup_writerQos; + } + + /* Cleanup writerQos for set of topics */ + d_writerQosFree(writerQos); + + } + + /* writerQos for sampleChain */ + writerQos = d_writerQosNew( + V_DURABILITY_VOLATILE, + V_RELIABILITY_RELIABLE, + V_ORDERBY_RECEPTIONTIME, + config->alignerLatencyBudget, + config->alignerTransportPriority); + if (writerQos == NULL) { + goto cleanup_publisher; + } + + /* sampleChain writer */ + publisher->sampleChainNumber = 0; + publisher->sampleChainWriter = u_writerNew (publisher->publisher, + "sampleChainWriter", + d_adminGetSampleChainTopic(admin), + writerQos); + if (publisher->sampleChainWriter == NULL) { + goto cleanup_writerQos; + } + result = u_entityEnable(u_entity(publisher->sampleChainWriter)); + if (result != U_RESULT_OK) { + goto cleanup_writerQos; + } + result = u_observableAction(u_observable(publisher->sampleChainWriter), + d_publisherEnsureServicesAttached, + durability); + if (result != U_RESULT_OK) { + goto cleanup_writerQos; + } + + /* Cleanup writerQos for sampleChain */ + d_writerQosFree(writerQos); + + /* WORKAROUND: Increase the possibility that ddsi discovers the writers. + * OSPL-9939 is there to fix this + */ + if (config->waitForRemoteReaders) { + d_sleep(self, 200*OS_DURATION_MILLISECOND); + } + } + return publisher; + + +cleanup_writerQos: + d_writerQosFree(writerQos); +cleanup_publisher2: +cleanup_publisher: + /* Free the publisher */ + d_publisherFree(publisher); + + return NULL; +} + + +void +d_publisherDeinit( + d_publisher publisher) +{ + d_durability durability; + d_configuration config; + + assert(d_publisherIsValid(publisher)); + + durability = d_adminGetDurability(publisher->admin); + config = d_durabilityGetConfiguration(durability); + if (publisher->statusWriter) { + d_printTimedEvent(durability, D_LEVEL_FINEST, "destroying status writer\n"); + u_objectFree(u_object(publisher->statusWriter)); + d_printTimedEvent(durability, D_LEVEL_FINEST, "status writer destroyed\n"); + publisher->statusWriter = NULL; + } + if (publisher->newGroupWriter) { + d_printTimedEvent(durability, D_LEVEL_FINEST, "destroying newGroup writer\n"); + u_objectFree(u_object(publisher->newGroupWriter)); + d_printTimedEvent(durability, D_LEVEL_FINEST, "newGroup writer destroyed\n"); + publisher->newGroupWriter = NULL; + } + if (publisher->groupsRequestWriter) { + d_printTimedEvent(durability, D_LEVEL_FINEST, "destroying groupsRequest writer\n"); + u_objectFree(u_object(publisher->groupsRequestWriter)); + d_printTimedEvent(durability, D_LEVEL_FINEST, "groupsRequest writer destroyed\n"); + publisher->groupsRequestWriter = NULL; + } + if (publisher->sampleChainWriter) { + d_printTimedEvent(durability, D_LEVEL_FINEST, "destroying sampleChain writer\n"); + u_objectFree(u_object(publisher->sampleChainWriter)); + d_printTimedEvent(durability, D_LEVEL_FINEST, "sampleChain writer destroyed\n"); + publisher->sampleChainWriter = NULL; + } + if (publisher->nameSpacesWriter) { + d_printTimedEvent(durability, D_LEVEL_FINEST, "destroying nameSpaces writer\n"); + u_objectFree (u_object(publisher->nameSpacesWriter)); + d_printTimedEvent(durability, D_LEVEL_FINEST, "nameSpaces writer destroyed\n"); + publisher->nameSpacesWriter = NULL; + } + if (publisher->nameSpacesRequestWriter) { + d_printTimedEvent(durability, D_LEVEL_FINEST, "destroying nameSpacesRequest writer\n"); + u_objectFree(u_object(publisher->nameSpacesRequestWriter)); + d_printTimedEvent(durability, D_LEVEL_FINEST, "nameSpacesRequest writer destroyed\n"); + publisher->nameSpacesRequestWriter = NULL; + } + if (publisher->deleteDataWriter) { + d_printTimedEvent(durability, D_LEVEL_FINEST, "destroying deleteData writer\n"); + u_objectFree(u_object(publisher->deleteDataWriter)); + d_printTimedEvent(durability, D_LEVEL_FINEST, "deleteData writer destroyed\n"); + publisher->deleteDataWriter = NULL; + } + if (publisher->sampleRequestWriter) { + d_printTimedEvent(durability, D_LEVEL_FINEST, "destroying sampleRequest writer\n"); + u_objectFree (u_object(publisher->sampleRequestWriter)); + d_printTimedEvent(durability, D_LEVEL_FINEST, "sampleRequest writer destroyed\n"); + publisher->sampleRequestWriter = NULL; + } + if (publisher->durabilityStateWriter) { + d_printTimedEvent(durability, D_LEVEL_FINEST, "destroying durabilityState writer\n"); + u_objectFree (u_object(publisher->durabilityStateWriter)); + d_printTimedEvent(durability, D_LEVEL_FINEST, "durabilityState writer destroyed\n"); + publisher->durabilityStateWriter = NULL; + } + if (config->capabilitySupport) { + if (publisher->capabilityWriter) { + d_printTimedEvent(durability, D_LEVEL_FINEST, "destroying capability writer\n"); + u_objectFree (u_object(publisher->capabilityWriter)); + d_printTimedEvent(durability, D_LEVEL_FINEST, "capability writer destroyed\n"); + publisher->capabilityWriter = NULL; + } + } + if (config->clientDurabilityEnabled) { + if (publisher->publisher2) { + d_printTimedEvent(durability, D_LEVEL_FINEST, "destroying user publisher for client durability\n"); + u_objectFree(u_object(publisher->publisher2)); + d_printTimedEvent(durability, D_LEVEL_FINEST, "user publisher for client durability destroyed\n"); + publisher->publisher2 = NULL; + } + } + if (publisher->publisher) { + d_printTimedEvent(durability, D_LEVEL_FINEST, "destroying user publisher\n"); + u_objectFree(u_object(publisher->publisher)); + d_printTimedEvent(durability, D_LEVEL_FINEST, "user publisher destroyed\n"); + publisher->publisher = NULL; + } + /* Call super-deinit */ + d_objectDeinit(d_object(publisher)); +} + +void +d_publisherFree( + d_publisher publisher) +{ + assert(d_publisherIsValid(publisher)); + + d_objectFree(d_object(publisher)); +} + +static c_bool +d__publisherStatusWrite( + d_publisher publisher, + d_status message, + c_bool resend) +{ + c_bool result = TRUE; + u_result ur; + d_durability durability; + d_thread const self = d_threadLookupSelf (); + + if(publisher && publisher->enabled){ + /* Status messages with TERMINATING or TERMINATED must + * be published, so checking needed on the durability + * state. */ + durability = d_adminGetDurability(publisher->admin); + d_publisherInitMessage(publisher, d_message(message)); + + if (!resend) { + d_message(message)->sequenceNumber = publisher->statusNumber++; + } + + d_threadAwake(self); + ur = u_writerWrite(publisher->statusWriter, + d_publisherStatusWriterCopy, + message, + os_timeWGet(), + U_INSTANCEHANDLE_NIL); + + if (ur == U_RESULT_TIMEOUT) { + result = FALSE; + } else if (ur != U_RESULT_OK) { + d_printTimedEvent(durability, D_LEVEL_SEVERE, + "Write of d_status message FAILED with result %s.\n", u_resultImage(ur)); + OS_REPORT(OS_ERROR, D_CONTEXT_DURABILITY, 0, + "Write of d_status message FAILED with result %s.", u_resultImage(ur)); + d_durabilityTerminate(durability, TRUE); + } + } + return result; +} + +c_bool +d_publisherStatusWrite( + d_publisher publisher, + d_status message, + d_networkAddress addressee) +{ + OS_UNUSED_ARG(addressee); + + assert(d_objectIsValid(d_object(publisher), D_PUBLISHER) == TRUE); + + return d__publisherStatusWrite(publisher, message, FALSE); +} + +c_bool +d_publisherStatusResend( + d_publisher publisher, + d_status message) +{ + assert(d_objectIsValid(d_object(publisher), D_PUBLISHER) == TRUE); + + return d__publisherStatusWrite(publisher, message, TRUE); +} + +c_bool +d_publisherNewGroupWrite( + d_publisher publisher, + d_newGroup message, + d_networkAddress addressee) +{ + c_bool result; + u_result ur; + int resendCount; + c_bool terminate; + d_durability durability; + d_serviceState state; + d_thread const self = d_threadLookupSelf (); + + OS_UNUSED_ARG(addressee); + result = FALSE; + assert(d_objectIsValid(d_object(publisher), D_PUBLISHER) == TRUE); + + if(publisher){ + if(publisher->enabled == TRUE){ + durability = d_adminGetDurability(publisher->admin); + state = d_durabilityGetState(durability); + if ((state != D_STATE_TERMINATING) && (state != D_STATE_TERMINATED)) { + /* The service is not about to terminate, so it is OK to + * publish newGroup messages. + */ + terminate = FALSE; + resendCount = 0; + d_publisherInitMessage(publisher, d_message(message)); + d_message(message)->sequenceNumber = publisher->newGroupNumber++; + + while((!result) && (!terminate)){ + d_threadAwake(self); + ur = u_writerWrite(publisher->newGroupWriter, + d_publisherNewGroupWriterCopy, + message, + os_timeWGet(), + U_INSTANCEHANDLE_NIL); + + if(ur == U_RESULT_OK){ + result = TRUE; + } else if(ur == U_RESULT_TIMEOUT) { + terminate = d_durabilityMustTerminate(durability); + resendCount++; + + if(terminate){ + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Failed to resend d_newGroup message, because durability is terminating.\n"); + } else if((resendCount == 1) || ((resendCount % 5) == 0)){ + d_printTimedEvent(durability, D_LEVEL_WARNING, + "Already tried to resend d_newGroup message '%d' times.\n", resendCount); + + if(resendCount != 1){ + OS_REPORT(OS_WARNING, D_CONTEXT_DURABILITY, 0, + "Already tried to resend d_newGroup message '%d' times.", + resendCount); + } + } + } else { + d_printTimedEvent(durability, D_LEVEL_SEVERE, + "Write of d_newGroup message FAILED with result %d.\n", ur); + OS_REPORT(OS_ERROR, D_CONTEXT_DURABILITY, 0, + "Write of d_newGroup message FAILED with result %d.", ur); + d_durabilityTerminate(durability, TRUE); + terminate = d_durabilityMustTerminate(durability); + } + } + } + } + } + return result; +} + +c_bool +d_publisherGroupsRequestWrite( + d_publisher publisher, + d_groupsRequest message, + d_networkAddress addressee) +{ + c_bool result; + u_result ur; + int resendCount; + c_bool terminate; + d_durability durability; + d_serviceState state; + d_thread const self = d_threadLookupSelf (); + + OS_UNUSED_ARG(addressee); + result = FALSE; + assert(d_objectIsValid(d_object(publisher), D_PUBLISHER) == TRUE); + + if(publisher){ + if(publisher->enabled == TRUE){ + durability = d_adminGetDurability(publisher->admin); + state = d_durabilityGetState(durability); + if ((state != D_STATE_TERMINATING) && (state != D_STATE_TERMINATED)) { + /* The service is not about to terminate, so it is OK to + * publish groupsRequest messages. + */ + terminate = FALSE; + resendCount = 0; + d_publisherInitMessage(publisher, d_message(message)); + d_message(message)->sequenceNumber = publisher->groupsRequestNumber++; + + while((!result) && (!terminate)){ + d_threadAwake(self); + ur = u_writerWrite(publisher->groupsRequestWriter, + d_publisherGroupsRequestWriterCopy, + message, os_timeWGet(), U_INSTANCEHANDLE_NIL); + + if(ur == U_RESULT_OK){ + result = TRUE; + } else if(ur == U_RESULT_TIMEOUT) { + terminate = d_durabilityMustTerminate(durability); + resendCount++; + + if(terminate){ + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Failed to resend d_groupsRequest message, because durability is terminating.\n"); + } else if((resendCount == 1) || ((resendCount % 5) == 0)){ + d_printTimedEvent(durability, D_LEVEL_WARNING, + "Already tried to resend d_groupsRequest message '%d' times.\n", resendCount); + + if(resendCount != 1){ + OS_REPORT(OS_WARNING, D_CONTEXT_DURABILITY, 0, + "Already tried to resend d_groupsRequest message '%d' times.", + resendCount); + } + } + } else { + d_printTimedEvent(durability, D_LEVEL_SEVERE, + "Write of d_groupsRequest message FAILED with result %d.\n", ur); + OS_REPORT(OS_ERROR, D_CONTEXT_DURABILITY, 0, + "Write of d_groupsRequest message FAILED with result %d.", ur); + d_durabilityTerminate(durability, TRUE); + terminate = d_durabilityMustTerminate(durability); + } + } + } + } + } + return result; +} + + +c_bool +d_publisherSampleRequestWrite( + d_publisher publisher, + d_sampleRequest message, + d_networkAddress addressee) +{ + c_bool result; + u_result ur; + int resendCount; + c_bool terminate; + d_durability durability; + d_serviceState state; + d_thread const self = d_threadLookupSelf (); + + OS_UNUSED_ARG(addressee); + result = FALSE; + assert(d_objectIsValid(d_object(publisher), D_PUBLISHER) == TRUE); + + if(publisher){ + if(publisher->enabled == TRUE){ + durability = d_adminGetDurability(publisher->admin); + state = d_durabilityGetState(durability); + if ((state != D_STATE_TERMINATING) && (state != D_STATE_TERMINATED)) { + /* The service is not about to terminate, so it is OK to + * publish sampleRequest messages. + */ + terminate = FALSE; + resendCount = 0; + d_publisherInitMessage(publisher, d_message(message)); + d_message(message)->sequenceNumber = publisher->sampleRequestNumber++; + + while((!result) && (!terminate)){ + d_threadAwake(self); + ur = u_writerWrite(publisher->sampleRequestWriter, + d_publisherSampleRequestWriterCopy, + message, os_timeWGet(), U_INSTANCEHANDLE_NIL); + + if(ur == U_RESULT_OK){ + result = TRUE; + } else if(ur == U_RESULT_TIMEOUT) { + terminate = d_durabilityMustTerminate(durability); + resendCount++; + + if(terminate){ + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Failed to resend d_sampleRequest message, because durability is terminating.\n"); + } else if((resendCount == 1) || ((resendCount % 5) == 0)){ + d_printTimedEvent(durability, D_LEVEL_WARNING, + "Already tried to resend d_sampleRequest message '%d' times.\n", resendCount); + + if(resendCount != 1){ + OS_REPORT(OS_WARNING, D_CONTEXT_DURABILITY, 0, + "Already tried to resend d_sampleRequest message '%d' times.", + resendCount); + } + } + } else { + d_printTimedEvent(durability, D_LEVEL_SEVERE, + "Write of d_sampleRequest message FAILED with result %d.\n", ur); + OS_REPORT(OS_ERROR, D_CONTEXT_DURABILITY, 0, + "Write of d_sampleRequest message FAILED with result %d.", ur); + d_durabilityTerminate(durability, TRUE); + terminate = d_durabilityMustTerminate(durability); + } + } + } + } + } + return result; +} + +c_bool +d_publisherSampleChainWrite( + d_publisher publisher, + d_sampleChain message, + d_networkAddress addressee) +{ + c_bool result; + u_result ur; + int resendCount; + c_bool terminate; + d_durability durability; + d_serviceState state; + d_thread const self = d_threadLookupSelf (); + + OS_UNUSED_ARG(addressee); + + assert(d_publisherIsValid(publisher)); + + result = FALSE; + if (publisher) { + if (publisher->enabled == TRUE) { + durability = d_adminGetDurability(publisher->admin); + state = d_durabilityGetState(durability); + if ((state != D_STATE_TERMINATING) && (state != D_STATE_TERMINATED)) { + /* The service is not about to terminate, so it is OK to + * publish sampleChain messages. + */ + terminate = FALSE; + resendCount = 0; + d_publisherInitMessage(publisher, d_message(message)); + d_message(message)->sequenceNumber = publisher->sampleChainNumber++; + + while((!result) && (!terminate)){ + d_threadAwake(self); + ur = u_writerWrite(publisher->sampleChainWriter, + d_publisherSampleChainWriterCopy, + message, os_timeWGet(), U_INSTANCEHANDLE_NIL); + + if (ur == U_RESULT_OK) { + result = TRUE; + } else { + terminate = d_durabilityMustTerminate(durability); + /* Print a message in the durability log every 100th attempt */ + if ((resendCount % 100) == 0) { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Failed to send d_sampleChain message (result: %s, terminate: %d, resendCount: %d).\n", + u_resultImage(ur), terminate, resendCount); + /* To prevent pollution of the ospl-info log a single entry is logged, + * even if multiple retries occur. You can always inspect the durability + * log to get an indication how long the retry lasts. + */ + if (resendCount == 0) { + OS_REPORT(OS_WARNING, D_CONTEXT_DURABILITY, 0, + "Failed to send d_sampleChain message with result '%s'.\n", u_resultImage(ur)); + } + } + + if (ur == U_RESULT_TIMEOUT) { + /* Retry in case of TIMEOUT */ + resendCount++; + } else { + /* Something bad happened, terminate */ + d_printTimedEvent(durability, D_LEVEL_SEVERE, + "I am going to terminate (result: %s, terminate: %d, resendCount: %d).\n", + u_resultImage(ur), terminate, resendCount); + d_durabilityTerminate(durability, TRUE); + terminate = d_durabilityMustTerminate(durability); + } + } + } /* while */ + if ((!terminate) && (resendCount > 0)) { + + /* Apparently a message has been successfully published after a + * number of retries + */ + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Managed to publish d_sampleChain message after %d resends.\n", + resendCount); + } + } + } + } + return result; +} + +c_bool +d_publisherNameSpacesRequestWrite( + d_publisher publisher, + d_nameSpacesRequest message, + d_networkAddress addressee, + d_serviceState state) +{ + c_bool result; + u_result ur; + int resendCount; + c_bool terminate; + d_durability durability; + d_serviceState myState; + d_thread const self = d_threadLookupSelf (); + + OS_UNUSED_ARG(addressee); + result = FALSE; + assert(d_objectIsValid(d_object(publisher), D_PUBLISHER) == TRUE); + + if(publisher){ + if(publisher->enabled == TRUE){ + durability = d_adminGetDurability(publisher->admin); + myState = d_durabilityGetState(durability); + if ((myState != D_STATE_TERMINATING) && (myState != D_STATE_TERMINATED)) { + /* The service is not about to terminate, so it is OK to + * publish nameSpacesRequest messages. + */ + terminate = FALSE; + resendCount = 0; + d_publisherInitMessage(publisher, d_message(message)); + /* Set the sender state. For normal nameSpacesRequests this is + * usually the state of the current durability service. For + * namespacesRequests that have been generated on behalf of a fellow + * it typically is the fellow's state. + * See e.g., d_fellowCheckInitialResponsiveness() */ + d_message(message)->senderState = state; + d_message(message)->sequenceNumber = publisher->nameSpacesRequestNumber++; + + while((!result) && (!terminate)){ + d_threadAwake(self); + ur = u_writerWrite(publisher->nameSpacesRequestWriter, + d_publisherNameSpacesRequestWriterCopy, + message, os_timeWGet(), U_INSTANCEHANDLE_NIL); + + if(ur == U_RESULT_OK){ + result = TRUE; + } else if(ur == U_RESULT_TIMEOUT) { + terminate = d_durabilityMustTerminate(durability); + resendCount++; + + if (terminate) { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Failed to resend d_nameSpaceRequest message, because durability is terminating.\n"); + } else if ((resendCount == 1) || ((resendCount % 5) == 0)) { + d_printTimedEvent(durability, D_LEVEL_WARNING, + "Already tried to resend d_nameSpaceRequest message '%d' times.\n", resendCount); + + if(resendCount != 1){ + OS_REPORT(OS_WARNING, D_CONTEXT_DURABILITY, 0, + "Already tried to resend d_nameSpaceRequest message '%d' times", + resendCount); + } + } + } else { + d_printTimedEvent(durability, D_LEVEL_SEVERE, + "Write of d_nameSpaceRequest message FAILED with result %d.\n", ur); + OS_REPORT(OS_ERROR, D_CONTEXT_DURABILITY, 0, + "Write of d_nameSpaceRequest message FAILED with result %d.", ur); + d_durabilityTerminate(durability, TRUE); + terminate = d_durabilityMustTerminate(durability); + } + } + } + } + } + return result; +} + +c_bool +d_publisherNameSpacesWrite( + d_publisher publisher, + d_nameSpaces message, + d_networkAddress addressee) +{ + c_bool result; + u_result ur; + int resendCount; + c_bool terminate; + d_durability durability; + d_serviceState state; + d_thread const self = d_threadLookupSelf (); + + OS_UNUSED_ARG(addressee); + result = FALSE; + assert(d_objectIsValid(d_object(publisher), D_PUBLISHER) == TRUE); + + if(publisher){ + if(publisher->enabled == TRUE){ + durability = d_adminGetDurability(publisher->admin); + state = d_durabilityGetState(durability); + if ((state != D_STATE_TERMINATING) && (state != D_STATE_TERMINATED)) { + /* The service is not about to terminate, so it is OK to + * publish nameSpaces messages. + */ + terminate = FALSE; + resendCount = 0; + d_publisherInitMessage(publisher, d_message(message)); + d_message(message)->sequenceNumber = publisher->nameSpacesNumber++; + + while((!result) && (!terminate)){ + d_threadAwake(self); + ur = u_writerWrite(publisher->nameSpacesWriter, + d_publisherNameSpacesWriterCopy, + message, os_timeWGet(), U_INSTANCEHANDLE_NIL); + + if(ur == U_RESULT_OK){ + result = TRUE; + } else if(ur == U_RESULT_TIMEOUT) { + terminate = d_durabilityMustTerminate(durability); + resendCount++; + + if(terminate){ + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Failed to resend d_nameSpaces message, because durability is terminating.\n"); + } else if((resendCount == 1) || ((resendCount % 5) == 0)){ + d_printTimedEvent(durability, D_LEVEL_WARNING, + "Already tried to resend d_nameSpaces message '%d' times.\n", resendCount); + + if(resendCount != 1){ + OS_REPORT(OS_WARNING, D_CONTEXT_DURABILITY, 0, + "Already tried to resend d_nameSpaces message '%d' times.", + resendCount); + } + } + } else { + d_printTimedEvent(durability, D_LEVEL_SEVERE, + "Write of d_nameSpaces message FAILED with result %d.\n", ur); + OS_REPORT(OS_ERROR, D_CONTEXT_DURABILITY, 0, + "Write of d_nameSpaces message FAILED with result %d.", ur); + d_durabilityTerminate(durability, TRUE); + terminate = d_durabilityMustTerminate(durability); + } + } + } + } + } + return result; +} + +c_bool +d_publisherDeleteDataWrite( + d_publisher publisher, + d_deleteData message, + d_networkAddress addressee) +{ + c_bool result; + u_result ur; + int resendCount; + c_bool terminate; + d_durability durability; + d_serviceState state; + d_thread const self = d_threadLookupSelf (); + + OS_UNUSED_ARG(addressee); + result = FALSE; + assert(d_objectIsValid(d_object(publisher), D_PUBLISHER) == TRUE); + + if(publisher){ + if(publisher->enabled == TRUE){ + durability = d_adminGetDurability(publisher->admin); + state = d_durabilityGetState(durability); + if ((state != D_STATE_TERMINATING) && (state != D_STATE_TERMINATED)) { + /* The service is not about to terminate, so it is OK to + * publish deleteData messages. + */ + terminate = FALSE; + resendCount = 0; + d_publisherInitMessage(publisher, d_message(message)); + d_message(message)->sequenceNumber = publisher->deleteDataNumber++; + + while((!result) && (!terminate)){ + d_threadAwake(self); + ur = u_writerWrite(publisher->deleteDataWriter, + d_publisherDeleteDataWriterCopy, + message, os_timeWGet(), U_INSTANCEHANDLE_NIL); + + if(ur == U_RESULT_OK){ + result = TRUE; + } else if(ur == U_RESULT_TIMEOUT) { + terminate = d_durabilityMustTerminate(durability); + resendCount++; + + if (terminate) { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Failed to resend d_deleteData message, because durability is terminating.\n"); + } else if((resendCount == 1) || ((resendCount % 5) == 0)){ + d_printTimedEvent(durability, D_LEVEL_WARNING, + "Already tried to resend d_deleteData message '%d' times.\n", resendCount); + + if(resendCount != 1){ + OS_REPORT(OS_WARNING, D_CONTEXT_DURABILITY, 0, + "Already tried to resend d_deleteData message '%d' times.",resendCount); + } + } + } else { + d_printTimedEvent(durability, D_LEVEL_SEVERE, + "Write of d_deleteData message FAILED with result %d.\n", ur); + OS_REPORT(OS_ERROR, D_CONTEXT_DURABILITY, 0, + "Write of d_deleteData message FAILED with result %d.", ur); + d_durabilityTerminate(durability, TRUE); + terminate = d_durabilityMustTerminate(durability); + } + } + } + } + } + return result; +} + + +c_bool +d_publisherCapabilityWrite( + d_publisher publisher, + d_capability message, + d_networkAddress addressee) +{ + c_bool result = FALSE; + u_result ur; + int resendCount; + c_bool terminate; + d_durability durability; + d_serviceState state; + d_thread const self = d_threadLookupSelf (); + + OS_UNUSED_ARG(addressee); + assert(d_publisherIsValid(publisher)); + + if (publisher) { + if (publisher->enabled == TRUE) { + durability = d_adminGetDurability(publisher->admin); + state = d_durabilityGetState(durability); + if ((state != D_STATE_TERMINATING) && (state != D_STATE_TERMINATED)) { + /* The service is not about to terminate, so it is OK to + * publish capability messages. + */ + terminate = FALSE; + resendCount = 0; + d_publisherInitMessage(publisher, d_message(message)); + d_message(message)->sequenceNumber = publisher->capabilityNumber++; + while ((!result) && (!terminate)) { + d_threadAwake(self); + ur = u_writerWrite(publisher->capabilityWriter, + d_publisherCapabilityWriterCopy, + message, os_timeWGet(), U_INSTANCEHANDLE_NIL); + if (ur == U_RESULT_OK) { + result = TRUE; + } else if (ur == U_RESULT_TIMEOUT) { + terminate = d_durabilityMustTerminate(durability); + resendCount++; + + if (terminate) { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Failed to resend capability message, because durability is terminating.\n"); + } else if ((resendCount == 1) || ((resendCount % 5) == 0)) { + d_printTimedEvent(durability, D_LEVEL_WARNING, + "Already tried to resend capability message '%d' times.\n", resendCount); + + if (resendCount != 1) { + OS_REPORT(OS_WARNING, D_CONTEXT_DURABILITY, 0, + "Already tried to resend capability message '%d' times.", + resendCount); + } + } + } else { + d_printTimedEvent(durability, D_LEVEL_SEVERE, + "Write of capability message FAILED with result %d.\n", ur); + OS_REPORT(OS_ERROR, D_CONTEXT_DURABILITY, 0, + "Write of capability message FAILED with result %d.", ur); + d_durabilityTerminate(durability, TRUE); + terminate = d_durabilityMustTerminate(durability); + } + } + } + } + } + return result; +} + + +static v_copyin_result +d_publisherDurabilityStateWriterCopy( + c_type type, + const void *from, + void *to) +{ + d_durabilityState durabilityState = d_durabilityState(from); + struct _DDS_DurabilityState *msgTo = (struct _DDS_DurabilityState *)to; + c_base base = c_getBase(type); + + /* Copy the version */ + msgTo->version = durabilityState->version; + /* Copy my server gid */ + msgTo->serverId = durabilityState->serverId; + /* Copy the list of requestIds. + * Note that the list of requestIds may not be modified while in this function! + */ + { + c_ulong len = c_iterLength(durabilityState->requestIds); + c_type subtype0; + struct _DDS_RequestId_t *dst0; + + subtype0 = c_type(c_metaResolve (c_metaObject(base), "DDS::RequestId_t")); + dst0 = (struct _DDS_RequestId_t *)c_sequenceNew_s(subtype0, 0, len); + c_free(subtype0); + if (!dst0) { + OS_REPORT (OS_ERROR, "copyIn", 0, "Member 'DurabilityState.requestIds' could not be allocated."); + goto alloc_requestIds; + } + { + c_iterIter iter = c_iterIterGet(durabilityState->requestIds); + struct _DDS_RequestId_t *requestId; + c_ulong i = 0; + + while ((requestId = c_iterNext(&iter)) != NULL) { + dst0[i].clientId = requestId->clientId; + dst0[i].requestId = requestId->requestId; + i++; + } + } + msgTo->requestIds = (c_sequence)dst0; + } + /* Copy the dataState. + * Note that the list of dataState may not be modified while in this function! + */ + { + c_ulong len = c_iterLength(durabilityState->dataState); + c_type subtype0; + struct _DDS_PartitionTopicState_t *dst0; + + subtype0 = c_type(c_metaResolve (c_metaObject(base), "DDS::PartitionTopicState_t")); + dst0 = (struct _DDS_PartitionTopicState_t *)c_sequenceNew_s(subtype0, 0, len); + c_free(subtype0); + if (!dst0) { + OS_REPORT (OS_ERROR, "copyIn", 0, "Member 'DurabilityState.dataState' could not be allocated."); + goto alloc_dataState; + } + { + c_iterIter iter = c_iterIterGet(durabilityState->dataState); + d_partitionTopicState partitionTopicState; + c_ulong i = 0; + + while ((partitionTopicState = d_partitionTopicState(c_iterNext(&iter))) != NULL) { + dst0[i].topic = c_stringNew_s(base, partitionTopicState->topic); + if (!dst0[i].topic) { + OS_REPORT (OS_ERROR, "copyIn", 0, "Member 'DurabilityState.dataState.topic' could not be allocated."); + goto alloc_partitionTopicStateTopic; + } + dst0[i].partition = c_stringNew_s(base, partitionTopicState->partition); + if (!dst0[i].partition) { + OS_REPORT (OS_ERROR, "copyIn", 0, "Member 'DurabilityState.dataState.partition' could not be allocated."); + goto alloc_partitionTopicStatePartition; + } + dst0[i].completeness = partitionTopicState->completeness; + + /* Copy the extensions */ + { + c_type type1; + c_type subtype1; + c_ulong length1; + struct _DDS_NameValue_t *dst1; + + subtype1 = c_type(c_metaResolve (c_metaObject(base), "DDS::NameValue_t")); + type1 = c_metaSequenceTypeNew_s(c_metaObject(base),"C_SEQUENCE",subtype1, 0); + c_free(subtype1); + if (!type1) { + OS_REPORT (OS_ERROR, "copyIn", 0, "Type for 'C_SEQUENCE' could not be allocated."); + goto alloc_partitionTopicStateExtensionsType; + } + + /* TODO: currently always a zero-length sequence is generated. */ + length1 = 0; + dst1 = (struct _DDS_NameValue_t *)c_newSequence_s(c_collectionType(type1), length1); + + if (!dst1) { + OS_REPORT (OS_ERROR, "copyIn", 0, "Member 'DurabilityState.dataState.extensions' could not be allocated."); + goto alloc_partitionTopicStateExtensions; + } + dst0[i].extensions = (c_sequence)dst1; + } + i++; + } + } + msgTo->dataState = (c_sequence)dst0; + } + /* Copy the extensions */ + { + static c_type type0 = NULL; + c_type subtype0; + c_ulong length0; + struct _DDS_NameValue_t *dst0; + + subtype0 = c_type(c_metaResolve (c_metaObject(base), "DDS::NameValue_t")); + type0 = c_metaSequenceTypeNew_s(c_metaObject(base),"C_SEQUENCE",subtype0,0); + c_free(subtype0); + if (!type0) { + OS_REPORT (OS_ERROR, "copyIn", 0, "Type for 'C_SEQUENCE' could not be allocated."); + goto alloc_extensionsType; + } + /* TODO: currently always a zero-length sequence is generated. + * That means that effectivly always a zero-size list of extensions is used + * in the historicalData. + */ + length0 = 0; + dst0 = (struct _DDS_NameValue_t *)c_newSequence_s(c_collectionType(type0), length0); + if (!dst0) { + OS_REPORT (OS_ERROR, "copyIn", 0,"Member 'DurabilityState.extensions' could not be allocated."); + goto alloc_extensions; + } + msgTo->extensions = (c_sequence)dst0; + } + return V_COPYIN_RESULT_OK; + +alloc_extensions: +alloc_extensionsType: +alloc_partitionTopicStateExtensions: +alloc_partitionTopicStateExtensionsType: +alloc_partitionTopicStatePartition: +alloc_partitionTopicStateTopic: +alloc_dataState: +alloc_requestIds: + /* To check if c_free() iteratively frees all subtypes */ + c_free(msgTo); + + return V_COPYIN_RESULT_OUT_OF_MEMORY; +} + + +c_bool +d_publisherDurabilityStateWrite( + d_publisher publisher, + d_durabilityState durabilityState) +{ + c_bool result = FALSE; + u_result ur; + int resendCount; + c_bool terminate; + d_durability durability; + d_serviceState state; + d_thread self = d_threadLookupSelf (); + + assert(d_publisherIsValid(publisher)); + assert(d_durabilityStateIsValid(durabilityState)); + + durability = d_adminGetDurability(publisher->admin); + if (publisher->enabled) { + state = d_durabilityGetState(durability); + if ((state != D_STATE_TERMINATING) && (state != D_STATE_TERMINATED)) { + /* The service is not about to terminate, so it is OK to + * publish durabilityState messages. + */ + d_printTimedEvent(durability, D_LEVEL_FINE, + "Publish durabilityState (#requestIds: %ld, #states: %ld)\n", + c_iterLength(durabilityState->requestIds), c_iterLength(durabilityState->dataState)); + terminate = FALSE; + resendCount = 0; + while ((!result) && (!terminate)) { + d_threadAwake(self); + ur = u_writerWrite(publisher->durabilityStateWriter, + d_publisherDurabilityStateWriterCopy, + durabilityState, os_timeWGet(), U_INSTANCEHANDLE_NIL); + if (ur == U_RESULT_OK) { + result = TRUE; + } else if (ur == U_RESULT_TIMEOUT) { + terminate = d_durabilityMustTerminate(durability); + resendCount++; + if (terminate) { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Failed to send durabilityState message because durability is terminating.\n"); + } else if (resendCount == 1) { + /* Only a single log line in case of resends to prevent log pollution */ + d_printTimedEvent(durability, D_LEVEL_WARNING, + "Failed to publish durabilityState message with result %s, try to resend.\n", u_resultImage(ur)); + OS_REPORT(OS_WARNING, D_CONTEXT_DURABILITY, 0, + "Failed to publish durabilityState message with result %s, try to resend.", u_resultImage(ur)); + } + } else { + d_printTimedEvent(durability, D_LEVEL_SEVERE, + "Publication of durabilityState message FAILED with result %s, I am going to terminate\n", u_resultImage(ur)); + OS_REPORT(OS_ERROR, D_CONTEXT_DURABILITY, 0, + "Publication of durabilityState message FAILED with result %s, I am going to terminate", u_resultImage(ur)); + d_durabilityTerminate(durability, TRUE); + terminate = d_durabilityMustTerminate(durability); + } + } /* while */ + if ((result) && (resendCount > 0) && (!terminate)) { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Publication of durabilityState message succeeded after %d resends\n", resendCount); + } + } + } + return result; +} + + +v_copyin_result +d_publisherSampleChainWriterCopy( + c_type type, + const void *data, + void *to) +{ + d_sampleChain msgFrom = d_sampleChain(data); + d_sampleChain msgTo = d_sampleChain(to); + c_base base = c_getBase(type); + c_type subtype; + c_long valueSize; + + d_publisherMessageWriterCopy(&msgFrom->parentMsg, &msgTo->parentMsg); + + msgTo->partition = c_stringNew_s(base, msgFrom->partition); + if (!msgTo->partition) { + OS_REPORT (OS_ERROR, "copyIn", 0, "Member 'partition' could not be allocated."); + goto err_allocPartition; + } + msgTo->topic = c_stringNew_s(base, msgFrom->topic); + if (!msgTo->topic) { + OS_REPORT (OS_ERROR, "copyIn", 0, "Member 'topic' could not be allocated."); + goto err_allocTopic; + } + msgTo->durabilityKind = msgFrom->durabilityKind; + msgTo->msgBody._d = msgFrom->msgBody._d; + msgTo->addresseesCount = msgFrom->addresseesCount; + + assert(msgTo->addresseesCount > 0); + subtype = c_resolve(base, "durabilityModule2::d_networkAddress_s"); + msgTo->addressees = c_arrayNew_s(subtype, msgTo->addresseesCount); + c_free(subtype); + if (!msgTo->addressees) { + OS_REPORT (OS_ERROR, "copyIn", 0, "Member 'addressees' could not be allocated."); + goto err_allocAddressees; + } + memcpy(msgTo->addressees, msgFrom->addressees, msgTo->addresseesCount*C_SIZEOF(d_networkAddress)); + + msgTo->source.systemId = msgFrom->source.systemId; + msgTo->source.localId = msgFrom->source.localId; + msgTo->source.lifecycleId = msgFrom->source.lifecycleId; + + switch(msgTo->msgBody._d) { + case BEAD: + valueSize = msgFrom->msgBody._u.bead.size; + msgTo->msgBody._u.bead.size = valueSize; + assert(valueSize >= 0); + msgTo->msgBody._u.bead.value = c_arrayNew_s(c_octet_t(base), (c_ulong)valueSize); + if (!msgTo->msgBody._u.bead.value) { + OS_REPORT (OS_ERROR, "copyIn", 0, "Member 'msgBody._u.bead.value' could not be allocated."); + goto err_allocBeadValue; + } + memcpy(msgTo->msgBody._u.bead.value, msgFrom->msgBody._u.bead.value, (c_ulong)valueSize); + break; + case LINK: + msgTo->msgBody._u.link.nrSamples = msgFrom->msgBody._u.link.nrSamples; + msgTo->msgBody._u.link.completeness = msgFrom->msgBody._u.link.completeness; + break; + default: + OS_REPORT(OS_ERROR, "d_publisherSampleChainWriterCopy", 0, + "Illegal message body discriminant value (%d) detected.", + msgTo->msgBody._d); + assert(FALSE); + } + + return V_COPYIN_RESULT_OK; + +err_allocBeadValue: +err_allocAddressees: +err_allocTopic: +err_allocPartition: + return V_COPYIN_RESULT_OUT_OF_MEMORY; +} + +v_copyin_result +d_publisherMessageWriterCopy( + d_message msgFrom, + d_message msgTo) +{ + msgTo->senderAddress.systemId = msgFrom->senderAddress.systemId; + msgTo->senderAddress.localId = msgFrom->senderAddress.localId; + msgTo->senderAddress.lifecycleId = msgFrom->senderAddress.lifecycleId; + + msgTo->addressee.systemId = msgFrom->addressee.systemId; + msgTo->addressee.localId = msgFrom->addressee.localId; + msgTo->addressee.lifecycleId = msgFrom->addressee.lifecycleId; + + msgTo->senderState = msgFrom->senderState; + msgTo->productionTimestamp = msgFrom->productionTimestamp; + msgTo->sequenceNumber = msgFrom->sequenceNumber; + + return V_COPYIN_RESULT_OK; +} + +v_copyin_result +d_publisherStatusWriterCopy( + c_type type, + const void *data, + void *to) +{ + OS_UNUSED_ARG(type); + assert(type); + return d_publisherMessageWriterCopy(&d_status(data)->parentMsg, &d_status(to)->parentMsg); +} + +v_copyin_result +d_publisherNewGroupWriterCopy( + c_type type, + const void *data, + void *to) +{ + v_copyin_result result; + d_newGroup msgFrom = (d_newGroup)data; + d_newGroup msgTo = (d_newGroup)to; + c_base base = c_getBase(type); + + result = d_publisherMessageWriterCopy(&msgFrom->parentMsg, &msgTo->parentMsg); + + if(msgFrom->partition){ + msgTo->partition = c_stringNew_s(base, msgFrom->partition); + if (!msgTo->partition) { + OS_REPORT (OS_ERROR, "copyIn", 0, "Member 'partition' could not be allocated."); + goto err_allocPartition; + } + } else { + msgTo->partition = NULL; + } + + if(msgFrom->topic){ + msgTo->topic = c_stringNew_s(base, msgFrom->topic); + if (!msgTo->topic) { + OS_REPORT (OS_ERROR, "copyIn", 0, "Member 'topic' could not be allocated."); + goto err_allocTopic; + } + } else { + msgTo->topic = NULL; + } + msgTo->completeness = msgFrom->completeness; + msgTo->durabilityKind = msgFrom->durabilityKind; + msgTo->quality = msgFrom->quality; + msgTo->alignerCount = msgFrom->alignerCount; + + return result; + +err_allocTopic: +err_allocPartition: + return V_COPYIN_RESULT_OUT_OF_MEMORY; +} + +v_copyin_result +d_publisherGroupsRequestWriterCopy( + c_type type, + const void *data, + void *to) +{ + v_copyin_result result = V_COPYIN_RESULT_OK; + d_groupsRequest msgFrom = (d_groupsRequest)data; + d_groupsRequest msgTo = (d_groupsRequest)to; + c_base base = c_getBase(type); + + result = d_publisherMessageWriterCopy(&d_groupsRequest(data)->parentMsg, &d_groupsRequest(to)->parentMsg); + + if(msgFrom->partition){ + msgTo->partition = c_stringNew_s(base, msgFrom->partition); + if (!msgTo->partition) { + OS_REPORT (OS_ERROR, "copyIn", 0, "Member 'partition' could not be allocated."); + goto err_allocPartition; + } + } else { + msgTo->partition = NULL; + } + + if(msgFrom->topic){ + msgTo->topic = c_stringNew_s(base, msgFrom->topic); + if (!msgTo->topic) { + OS_REPORT (OS_ERROR, "copyIn", 0, "Member 'topic' could not be allocated."); + goto err_allocTopic; + } + } else { + msgTo->topic = NULL; + } + + return result; + +err_allocTopic: +err_allocPartition: + return V_COPYIN_RESULT_OUT_OF_MEMORY; +} + +v_copyin_result +d_publisherSampleRequestWriterCopy( + c_type type, + const void *data, + void *to) +{ + v_copyin_result result; + c_ulong i; + d_sampleRequest msgFrom = d_sampleRequest(data); + d_sampleRequest msgTo = d_sampleRequest(to); + c_base base = c_getBase(type); + + result = d_publisherMessageWriterCopy(&msgFrom->parentMsg, &msgTo->parentMsg); + + msgTo->partition = c_stringNew_s(base, msgFrom->partition); + if (!msgTo->partition) { + OS_REPORT (OS_ERROR, "copyIn", 0, "Member 'partition' could not be allocated."); + goto err_allocPartition; + } + + msgTo->topic = c_stringNew_s(base, msgFrom->topic); + if (!msgTo->topic) { + OS_REPORT (OS_ERROR, "copyIn", 0, "Member 'topic' could not be allocated."); + goto err_allocTopic; + } + + msgTo->durabilityKind = msgFrom->durabilityKind; + msgTo->requestTime = msgFrom->requestTime; + msgTo->withTimeRange = msgFrom->withTimeRange; + msgTo->beginTime = msgFrom->beginTime; + msgTo->endTime = msgFrom->endTime; + + msgTo->source.systemId = msgFrom->source.systemId; + msgTo->source.localId = msgFrom->source.localId; + msgTo->source.lifecycleId = msgFrom->source.lifecycleId; + + if(msgFrom->filter){ + msgTo->filter = c_stringNew_s(base, msgFrom->filter); + if (!msgTo->filter) { + OS_REPORT (OS_ERROR, "copyIn", 0, "Member 'filter' could not be allocated."); + goto err_allocFilter; + } + } else { + msgTo->filter = NULL; + } + if(msgFrom->filterParams){ + msgTo->filterParamsCount = msgFrom->filterParamsCount; + /* Create array for filters and equalityCheck hash string (+1) */ + msgTo->filterParams = c_arrayNew_s(c_string_t(base), msgFrom->filterParamsCount + 1); + if (!msgTo->filterParams) { + OS_REPORT (OS_ERROR, "copyIn", 0, "Member 'filterParams' could not be allocated."); + goto err_allocFilterParams; + } + + for(i=0; ifilterParamsCount; i++){ + msgTo->filterParams[i] = c_stringNew_s(base, msgFrom->filterParams[i]); + if (!msgTo->filterParams[i]) { + OS_REPORT (OS_ERROR, "copyIn", 0, "Member 'filterParams[%d]' could not be allocated.", i); + goto err_allocFilterParam; + } + } + /* Add equalityCheck hash string as last entry to filterParams sequence */ + msgTo->filterParams[i] = c_stringNew_s(base, msgFrom->filterParams[i]); + if (!msgTo->filterParams[i]) { + OS_REPORT (OS_ERROR, "copyIn", 0, "Member 'filterParams[%d]' could not be allocated.", i); + goto err_allocFilterParam; + } + } + msgTo->maxSamples = msgFrom->maxSamples; + msgTo->maxInstances = msgFrom->maxInstances; + msgTo->maxSamplesPerInstance = msgFrom->maxSamplesPerInstance; + + return result; + +err_allocFilterParam: +err_allocFilterParams: +err_allocFilter: +err_allocTopic: +err_allocPartition: + return V_COPYIN_RESULT_OUT_OF_MEMORY; +} + +v_copyin_result +d_publisherNameSpacesWriterCopy( + c_type type, + const void *data, + void *to) +{ + v_copyin_result result; + + d_nameSpaces msgFrom = d_nameSpaces(data); + d_nameSpaces msgTo = d_nameSpaces(to); + c_base base = c_getBase(type); + c_ulong count = 0; + OS_UNUSED_ARG(type); + + result = d_publisherMessageWriterCopy(&msgFrom->parentMsg, &msgTo->parentMsg); + + msgTo->name = c_stringNew_s(base, msgFrom->name); + if (!msgTo->name) { + OS_REPORT (OS_ERROR, "copyIn", 0, "Member 'name' could not be allocated."); + goto err_allocName; + } + + msgTo->durabilityKind = msgFrom->durabilityKind; + msgTo->alignmentKind = msgFrom->alignmentKind; + msgTo->aligner = msgFrom->aligner; + msgTo->total = msgFrom->total; + msgTo->initialQuality = msgFrom->initialQuality; + msgTo->master.systemId = msgFrom->master.systemId; + msgTo->master.localId = msgFrom->master.localId; + msgTo->master.lifecycleId = msgFrom->master.lifecycleId; + msgTo->isComplete = msgFrom->isComplete; + msgTo->masterConfirmed = msgFrom->masterConfirmed; + msgTo->state.value = msgFrom->state.value; + + if(msgFrom->partitions) { + msgTo->partitions = c_stringNew_s(base, msgFrom->partitions); + if (!msgTo->partitions) { + OS_REPORT (OS_ERROR, "copyIn", 0, "Member 'partitions' could not be allocated."); + goto err_allocPartitions; + } + } else { + msgTo->partitions = NULL; + } + if(msgFrom->state.role) { + msgTo->state.role = c_stringNew_s(base, msgFrom->state.role); + if (!msgTo->state.role) { + OS_REPORT (OS_ERROR, "copyIn", 0, "Member 'state.role' could not be allocated."); + goto err_allocStateRole; + } + } else { + msgTo->state.role = NULL; + } + msgTo->state.value = msgFrom->state.value; + msgTo->mergedStatesCount = msgFrom->mergedStatesCount; + + count = msgTo->mergedStatesCount; + if (msgFrom->aligner == TRUE) { + count++; + } + + if (count > 0) { + c_type mergeStateType = c_resolve(base, "durabilityModule2::d_mergeState_s"); + msgTo->mergedStates = c_arrayNew_s(mergeStateType, count); + c_free(mergeStateType); + if (!msgTo->mergedStates) { + OS_REPORT (OS_ERROR, "copyIn", 0, "Member 'mergedStates' could not be allocated."); + goto err_allocMergedStates; + } + } else { + msgTo->mergedStates = NULL; + } + + { + const struct d_mergeState_s *from = (const struct d_mergeState_s *) msgFrom->mergedStates; + struct d_mergeState_s *to = (struct d_mergeState_s *) msgTo->mergedStates; + c_ulong i; + for(i=0; iparentMsg, &d_nameSpacesRequest(to)->parentMsg); +} + +v_copyin_result +d_publisherDeleteDataWriterCopy( + c_type type, + const void *data, + void *to) +{ + v_copyin_result result; + d_deleteData msgFrom = d_deleteData(data); + d_deleteData msgTo = d_deleteData(to); + c_base base = c_getBase(type); + + result = d_publisherMessageWriterCopy(&msgFrom->parentMsg, &msgTo->parentMsg); + + msgTo->actionTime = msgFrom->actionTime; + + if(msgFrom->partitionExpr) { + msgTo->partitionExpr = c_stringNew_s(base, msgFrom->partitionExpr); + if (!msgTo->partitionExpr) { + OS_REPORT (OS_ERROR, "copyIn", 0, "Member 'partitionExpr' could not be allocated."); + goto err_allocPartitionExpr; + } + } else { + msgTo->partitionExpr = NULL; + } + if(msgFrom->topicExpr) { + msgTo->topicExpr = c_stringNew_s(base, msgFrom->topicExpr); + if (!msgTo->topicExpr) { + OS_REPORT (OS_ERROR, "copyIn", 0, "Member 'topicExpr' could not be allocated."); + goto err_allocTopicExpr; + } + } else { + msgTo->topicExpr = NULL; + } + return result; + +err_allocTopicExpr: +err_allocPartitionExpr: + return V_COPYIN_RESULT_OUT_OF_MEMORY; +} + + +v_copyin_result +d_publisherCapabilityWriterCopy( + c_type type, + const void *data, + void *to) +{ + v_copyin_result result; + d_capability msgFrom = d_capability(data); + d_capability msgTo = d_capability(to); + c_base base = c_getBase(type); + c_type nv_type; + struct d_nameValue_s *nvFrom, *nvTo; + c_ulong i,j; + + result = d_publisherMessageWriterCopy(&msgFrom->parentMsg, &msgTo->parentMsg); + + nv_type = c_resolve (base, "durabilityModule2::d_nameValue_s"); + assert(nv_type); + msgTo->capabilities = c_sequenceNew_s(nv_type, D_NUMBER_OF_CAPABILITIES, D_NUMBER_OF_CAPABILITIES); + c_free(nv_type); + if (!msgTo->capabilities) { + OS_REPORT (OS_ERROR, "copyIn", 0, "Member 'capabilities' could not be allocated."); + goto err_allocCapabilities; + } + nvFrom = (struct d_nameValue_s*)msgFrom->capabilities; + nvTo = (struct d_nameValue_s*)msgTo->capabilities; + + for (i=0; icapabilities); +err_allocCapabilities: + return V_COPYIN_RESULT_OUT_OF_MEMORY; +} + + +void +d_publisherInitMessage( + d_publisher publisher, + d_message message) +{ + os_uint32 seqnum; + + seqnum = d_adminGetNextSeqNum(publisher->admin); + d_productionTimestampFromSeqnum(&d_message(message)->productionTimestamp, &seqnum); + d_message(message)->senderState = d_durabilityGetState(d_adminGetDurability(publisher->admin)); +} + +void +d_publisherEnsureServicesAttached( + v_public entity, + c_voidp args) +{ + v_writer writer; + v_group group; + d_durability durability; + + writer = v_writer(entity); + durability = d_durability(args); + group = writer->groupSet.firstGroup->group; + d_durabilityWaitForAttachToGroup(durability, group); +} + +static void +d__publisherNameSpacesRequestUnregister( + d_publisher publisher, + d_networkAddress addressee) +{ + d_nameSpacesRequest request; + u_instanceHandle handle = U_INSTANCEHANDLE_NIL; + u_result ur; + d_durability durability; + int resendCount = 0; + c_bool terminate; + d_thread self = d_threadLookupSelf (); + + assert(publisher); + assert(d_objectIsValid(d_object(publisher), D_PUBLISHER) == TRUE); + + request = d_nameSpacesRequestNew(publisher->admin); + d_messageSetAddressee(d_message(request), addressee); + /* Unregistration is only needed when the writer exists and it has been used before. + * Therefore we do not care about the output of the lookupInstance as long as the handle + * is set (or not set) */ + (void) u_writerLookupInstance(publisher->nameSpacesRequestWriter, + d_publisherNameSpacesRequestWriterCopy, request, &handle); + d_nameSpacesRequestFree(request); + + if (handle != U_INSTANCEHANDLE_NIL) { + durability = d_adminGetDurability(publisher->admin); + do { + d_threadAwake(self); + ur = u_writerUnregisterInstance(publisher->nameSpacesRequestWriter, NULL, NULL, os_timeWGet(), handle); + if (ur == U_RESULT_TIMEOUT) { + resendCount++; + terminate = d_durabilityMustTerminate(durability); + if (terminate) { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Failed to send d_nameSpacesRequest unregister message, because durability is terminating.\n"); + } else if ((resendCount == 1) || ((resendCount % 5) == 0)){ + d_printTimedEvent(durability, D_LEVEL_WARNING, + "Already tried to send d_nameSpacesRequest unregister message '%d' times.\n", resendCount); + + if(resendCount != 1){ + OS_REPORT(OS_WARNING, D_CONTEXT_DURABILITY, 0, + "Already tried to send d_nameSpacesRequest unregister message '%d' times.", + resendCount); + } + } + } else if (ur != U_RESULT_OK) { + d_printTimedEvent(durability, D_LEVEL_WARNING, + "Unregistration of d_nameSpacesRequest message FAILED with %s\n", u_resultImage(ur)); + OS_REPORT(OS_ERROR, D_CONTEXT_DURABILITY, 0, + "Unregistration of d_nameSpacesRequest message FAILED with %s", u_resultImage(ur)); + } + terminate = d_durabilityMustTerminate(durability); + } while (!terminate && ur == U_RESULT_TIMEOUT); + } +} + +static void +d__publisherStatusUnregister( + d_publisher publisher, + d_networkAddress addressee) +{ + d_status status; + u_instanceHandle handle = U_INSTANCEHANDLE_NIL; + u_result ur; + d_durability durability; + int resendCount = 0; + c_bool terminate; + d_thread self = d_threadLookupSelf (); + + assert(publisher); + assert(d_objectIsValid(d_object(publisher), D_PUBLISHER) == TRUE); + + status = d_statusNew(publisher->admin); + d_messageSetAddressee(d_message(status), addressee); + /* Unregistration is only needed when the writer exists and it has been used before. + * Therefore we do not care about the output of the lookupInstance as long as the handle + * is set (or not set) */ + (void) u_writerLookupInstance(publisher->statusWriter, + d_publisherStatusWriterCopy, status, &handle); + d_statusFree(status); + + if (handle != U_INSTANCEHANDLE_NIL) { + durability = d_adminGetDurability(publisher->admin); + do { + d_threadAwake(self); + ur = u_writerUnregisterInstance(publisher->statusWriter, NULL, NULL, os_timeWGet(), handle); + if (ur == U_RESULT_TIMEOUT) { + resendCount++; + terminate = d_durabilityMustTerminate(durability); + if (terminate) { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Failed to send d_status unregister message, because durability is terminating.\n"); + } else if ((resendCount == 1) || ((resendCount % 5) == 0)){ + d_printTimedEvent(durability, D_LEVEL_WARNING, + "Already tried to send d_status unregister message '%d' times.\n", resendCount); + + if(resendCount != 1){ + OS_REPORT(OS_WARNING, D_CONTEXT_DURABILITY, 0, + "Already tried to send d_status unregister message '%d' times.", + resendCount); + } + } + } else if (ur != U_RESULT_OK) { + d_printTimedEvent(durability, D_LEVEL_WARNING, + "Unregistration of d_status message FAILED with %s\n", u_resultImage(ur)); + OS_REPORT(OS_ERROR, D_CONTEXT_DURABILITY, 0, + "Unregistration of d_status message FAILED with %s", u_resultImage(ur)); + } + terminate = d_durabilityMustTerminate(durability); + } while (!terminate && ur == U_RESULT_TIMEOUT); + } +} + +c_bool +d_publisherUnregisterInstances( + d_publisher publisher, + d_networkAddress addressee) +{ + c_bool result = FALSE; + + if (publisher && publisher->enabled == TRUE) { + d__publisherNameSpacesRequestUnregister(publisher, addressee); + d__publisherStatusUnregister(publisher, addressee); + result = TRUE; + } + + return result; +} diff --git a/src/services/durability/code/d_qos.c b/src/services/durability/code/d_qos.c new file mode 100644 index 000000000..b8774c321 --- /dev/null +++ b/src/services/durability/code/d_qos.c @@ -0,0 +1,160 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "d_qos.h" +#include "os_stdlib.h" + +v_publisherQos +d_publisherQosNew( + const c_char* partition) +{ + v_publisherQos qos = u_publisherQosNew(NULL); + + if (qos) { + qos->presentation.v.access_scope = V_PRESENTATION_TOPIC; + if (qos->partition.v) { + os_free(qos->partition.v); + } + qos->partition.v = os_malloc(strlen(partition)+1); + + if (qos->partition.v == NULL) { + d_publisherQosFree(qos); + qos = NULL; + } else { + /* QAC EXPECT 5007; use of strcpy */ + os_strcpy(qos->partition.v, partition); + } + } + return qos; +} + +void +d_publisherQosFree( + v_publisherQos qos) +{ + if (qos) { + u_publisherQosFree(qos); + } +} + +v_subscriberQos +d_subscriberQosNew( + const c_char* partition) +{ + v_subscriberQos qos = u_subscriberQosNew(NULL); + if (qos) { + qos->entityFactory.v.autoenable_created_entities = FALSE; + if (qos->partition.v) { + os_free(qos->partition.v); + } + if(partition){ + qos->partition.v = os_malloc(strlen(partition)+1); + /* QAC EXPECT 5007; use of strcpy */ + os_strcpy(qos->partition.v, partition); + } else { + qos->partition.v = NULL; + } + } + return qos; +} + +void +d_subscriberQosFree( + v_subscriberQos qos) +{ + if (qos) { + u_subscriberQosFree(qos); + } +} + +v_readerQos +d_readerQosNew( + v_durabilityKind durability, + v_reliabilityKind reliability) +{ + v_readerQos qos = u_readerQosNew(NULL); + if (qos) { + qos->durability.v.kind = durability; + qos->reliability.v.kind = reliability; + qos->latency.v.duration = OS_DURATION_INFINITE; + } + return qos; +} + +void +d_readerQosFree( + v_readerQos qos) +{ + if (qos) { + u_readerQosFree(qos); + } +} + +v_writerQos +d_writerQosNew( + v_durabilityKind durability, + v_reliabilityKind reliability, + v_orderbyKind orderKind, + os_duration latencyBudget, + c_long transportPriority) +{ + v_writerQos qos = u_writerQosNew(NULL); + + if (qos) { + qos->durability.v.kind = durability; + qos->reliability.v.kind = reliability; + qos->reliability.v.max_blocking_time = OS_DURATION_INIT(1,0); + qos->latency.v.duration = latencyBudget; + qos->transport.v.value = transportPriority; + qos->history.v.kind = V_HISTORY_KEEPALL; + qos->orderby.v.kind = orderKind; + qos->resource.v.max_samples = 1; + } + return qos; +} + +void +d_writerQosFree( + v_writerQos qos) +{ + if (qos) { + u_writerQosFree(qos); + } +} + +v_topicQos +d_topicQosNew( + v_durabilityKind durability, + v_reliabilityKind reliability) +{ + v_topicQos qos = u_topicQosNew(NULL); + if (qos) { + qos->durability.v.kind = durability; + qos->reliability.v.kind = reliability; + } + return qos; +} + +void +d_topicQosFree( + v_topicQos qos) +{ + if (qos) { + u_topicQosFree(qos); + } +} diff --git a/src/services/durability/code/d_readerListener.c b/src/services/durability/code/d_readerListener.c new file mode 100644 index 000000000..1317e6005 --- /dev/null +++ b/src/services/durability/code/d_readerListener.c @@ -0,0 +1,387 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "d__readerListener.h" +#include "d__listener.h" +#include "d__admin.h" +#include "d__subscriber.h" +#include "d__waitset.h" +#include "d__misc.h" +#include "d__durability.h" +#include "d_message.h" +#include "d_qos.h" +#include "d_networkAddress.h" +#include "u_observable.h" +#include "u_dataReader.h" +#include "v_event.h" +#include "v_observer.h" +#include "v_readerSample.h" +#include "v_dataReaderSample.h" +#include "v_state.h" +#include "os_report.h" + +/** + * Macro that checks the d_readerListener validity. + * Because d_readerListener is an abstract class no type checking can + * be done. The pointer can only be validated to be non-NULL. + */ +#define d_readerListenerIsValid(_this) (_this != NULL) + +struct createFieldArg +{ + const c_char * typeName; + const c_char * fieldName; + os_size_t fieldOffset; /* result */ +}; + +void +createField( + v_public entity, + c_voidp argument ) +{ + c_type type; + c_metaObject userData; + struct createFieldArg * arg = (struct createFieldArg *)argument; + + type = c_resolve(c_getBase(entity), arg->typeName); + assert(type != NULL); + userData = c_metaResolve(c_metaObject(type), arg->fieldName); + c_free(type); + + arg->fieldOffset = c_property(userData)->offset; + c_free(userData); +} + +static void +d_readerListenerInitField( + d_readerListener listener, + d_subscriber subscriber, + const c_char * typeName) +{ + struct createFieldArg arg; + const c_char* fieldName = "userData"; + + assert(d_objectIsValid(d_object(listener), D_LISTENER)); + arg.typeName = typeName; + arg.fieldName = fieldName; + arg.fieldOffset = 0; + (void)u_observableAction(u_observable(d_durabilityGetService( + d_adminGetDurability( + d_subscriberGetAdmin(subscriber)))), + createField, &arg); + listener->fieldOffset = arg.fieldOffset; +} + +void +d_readerListenerInit( + d_readerListener listener, + d_listenerKind kind, + d_listenerAction action, + d_subscriber subscriber, + const c_char* topicName, + const c_char* fieldName, + v_reliabilityKind reliability, + v_historyQosKind historyKind, + c_long historyDepth, + os_threadAttr attr, + d_objectDeinitFunc deinit) +{ + c_char* readerName; + d_networkAddress addr; + d_admin admin; + + v_readerQos readerQos; + c_char *query; + + assert(d_readerListenerIsValid(listener)); + assert(d_subscriberIsValid(subscriber)); + + if (listener) { + /* Call super-init */ + d_listenerInit(d_listener(listener), kind, subscriber, action, + (d_objectDeinitFunc)deinit); + /* Initialize readerListener */ + admin = d_listenerGetAdmin(d_listener(listener)); + readerName = (c_char*)(os_malloc(strlen(topicName) + 7)); + if (readerName) { + os_sprintf(readerName, "%sReader", topicName); + } + addr = d_adminGetMyAddress(admin); + listener->myAddr = addr->systemId; + d_readerListenerInitField(listener, subscriber, fieldName); + listener->takenSamples = c_iterNew(NULL); + listener->waitsetData = NULL; + listener->name = os_strdup(topicName); + listener->samplesTotal = 0; + listener->samplesFromMe = 0; + listener->samplesForMe = 0; + listener->lastInsertTime = OS_TIMEW_ZERO; + listener->lastSourceTime = OS_TIMEW_ZERO; + listener->attr = attr; + /* Each readerListener uses a DataReader that runs + * on its own thread. Data that is received by the + * DataReader is handled by that thread. + */ + readerQos = d_readerQosNew(V_DURABILITY_VOLATILE, reliability); + readerQos->history.v.kind = historyKind; + readerQos->history.v.depth = historyDepth; + readerQos->lifecycle.v.autopurge_nowriter_samples_delay = OS_DURATION_INIT(60,0); + readerQos->lifecycle.v.autopurge_disposed_samples_delay = OS_DURATION_INIT(10,0); + + /* Message is meant for me or for all and not sent by me */ + +#define FILTER_EXPRESSION "select * from %s where " \ + "parentMsg.addressee.systemId=%u OR " \ + "parentMsg.addressee.systemId=0 AND " \ + "parentMsg.senderAddress.systemId<>%u" + + query = (c_char*)(os_malloc(strlen(listener->name) + strlen(FILTER_EXPRESSION) + 32)); + os_sprintf(query, FILTER_EXPRESSION, topicName, addr->systemId, addr->systemId); +#undef FILTER_EXPRESSION + + listener->dataReader = u_dataReaderNew (d_subscriberGetSubscriber(subscriber), readerName, query, NULL, 0, readerQos); + + if (!listener->dataReader) { + OS_REPORT(OS_ERROR, D_CONTEXT_DURABILITY, 0, "Could not create dataReader"); + } else { + u_entityEnable(u_entity(listener->dataReader)); + } + d_readerQosFree(readerQos); + os_free(query); + d_networkAddressFree(addr); + os_free(readerName); + } +} + +void +d_readerListenerDeinit( + d_readerListener listener) +{ + assert(d_readerListenerIsValid(listener)); + + /* Stop the readerListener */ + d_readerListenerStop(listener); + /* Deallocate */ + if (listener->name) { + os_free(listener->name); + } + /* Remove the datareader that was created in d_readerListenerInitDataReader. */ + if (listener->dataReader) { + d_listenerLock(d_listener(listener)); + u_objectFree(u_object (listener->dataReader)); + d_listenerUnlock(d_listener(listener)); + } + if(listener->takenSamples) { + c_iterFree(listener->takenSamples); + listener->takenSamples = NULL; + } + /* Call super-deinit */ + d_listenerDeinit(d_listener(listener)); +} + +static v_actionResult +d_readerListenerCopyAll( + c_object object, + c_voidp copyArg) +{ + d_readerListener listener; + v_actionResult result = 0; + + if(object != NULL) { + v_actionResultSet(result, V_PROCEED); + if (v_stateTest(v_readerSampleState(object), L_VALIDDATA)) { + listener = d_readerListener(copyArg); + (void)c_iterAppend(listener->takenSamples, c_keep(object)); + listener->processMessage = TRUE; + } + } + return result; +} + +static c_ulong +d_readerListenerActionAll( + u_object o, + u_waitsetEvent event, + c_voidp usrData) +{ + u_result result; + d_readerListener listener; + c_bool proceed; + d_admin admin; + d_durability durability; + c_object sample; + v_message readerMessage; + + listener = d_readerListener(usrData); + admin = d_listenerGetAdmin(d_listener(listener)); + durability = d_adminGetDurability(admin); + + d_listenerLock(d_listener(listener)); + + do { + proceed = FALSE; + listener->processMessage = FALSE; + result = u_dataReaderTake(u_dataReader(o), U_STATE_ANY, d_readerListenerCopyAll, usrData, OS_DURATION_ZERO); + + if(result != U_RESULT_OK && result != U_RESULT_NO_DATA){ + OS_REPORT(OS_ERROR, D_CONTEXT_DURABILITY, 0, "Could not take data from reader (result: %d)", result); + } else if(c_iterLength(listener->takenSamples)!= 0){ + d_listenerAction action = d_listenerGetAction(d_listener(listener)); + sample = (c_object)(c_iterTakeFirst(listener->takenSamples)); + + while(sample && (d_durabilityMustTerminate(durability) == FALSE)){ + readerMessage = v_message(v_dataReaderSampleTemplate(sample)->message); + + listener->lastInsertTime = v_dataReaderSample(sample)->insertTime; + listener->lastSourceTime = readerMessage->writeTime; + listener->value = sample; + + if(action) { + action(d_listener(listener), C_DISPLACE(readerMessage, listener->fieldOffset)); + } + + c_free(sample); + sample = (c_object)(c_iterTakeFirst(listener->takenSamples)); + } + /* If while-loop stops, because durability terminates, free all + * remaining samples; + */ + while(sample){ + c_free(sample); + sample = (c_object)(c_iterTakeFirst(listener->takenSamples)); + } + listener->value = NULL; + proceed = TRUE; + } + } while((result == U_RESULT_OK || result == U_RESULT_NO_DATA) && (proceed == TRUE) && (d_durabilityMustTerminate(durability) == FALSE)); + + d_listenerUnlock(d_listener(listener)); + return (event->kind & V_EVENT_DATA_AVAILABLE); +} + +c_bool +d_readerListenerStart( + d_readerListener listener) +{ + c_bool result; + u_object object; + u_result ur; + c_bool wsResult; + d_waitset waitset; + d_admin admin; + d_subscriber subscriber; + + assert(listener); + result = FALSE; + assert(d_objectIsValid(d_object(listener), D_LISTENER)); + + if(listener){ + d_listenerLock(d_listener(listener)); + object = u_object(listener->dataReader); + if (object) { + if(d_listener(listener)->attached == FALSE){ + ur = u_observableSetListenerMask(u_observable(object), V_EVENT_DATA_AVAILABLE); + + if(ur == U_RESULT_OK){ + listener->value = NULL; + + admin = d_listenerGetAdmin(d_listener(listener)); + subscriber = d_adminGetSubscriber(admin); + waitset = d_subscriberGetWaitset(subscriber); + + listener->waitsetData = d_waitsetEntityNew( + listener->name, + object, d_readerListenerActionAll, + V_EVENT_DATA_AVAILABLE | V_EVENT_TRIGGER, + listener->attr, listener); + + wsResult = d_waitsetAttach(waitset, listener->waitsetData); + + if(wsResult == TRUE) { + ur = U_RESULT_OK; + } else { + ur = U_RESULT_ILL_PARAM; + } + + if(ur == U_RESULT_OK){ + d_listener(listener)->attached = TRUE; + result = TRUE; + d_listenerUnlock(d_listener(listener)); + (void) u_observableNotify(u_observable(object)); + } else { + d_listenerUnlock(d_listener(listener)); + } + } else { + d_listenerUnlock(d_listener(listener)); + } + } else { + d_listenerUnlock(d_listener(listener)); + } + } else { + d_listenerUnlock(d_listener(listener)); + result = TRUE; + } + } + return result; +} + +c_bool +d_readerListenerStop( + d_readerListener listener) +{ + c_bool result; + u_result ur; + d_admin admin; + d_subscriber subscriber; + d_waitset waitset; + + assert(d_objectIsValid(d_object(listener), D_LISTENER)); + result = FALSE; + + if(listener){ + d_listenerLock(d_listener(listener)); + + if(d_listener(listener)->attached == TRUE){ + admin = d_listenerGetAdmin(d_listener(listener)); + subscriber = d_adminGetSubscriber(admin); + waitset = d_subscriberGetWaitset(subscriber); + d_listenerUnlock(d_listener(listener)); + result = d_waitsetDetach(waitset, listener->waitsetData); + d_listenerLock(d_listener(listener)); + + if(result == TRUE) { + d_waitsetEntityFree(listener->waitsetData); + ur = U_RESULT_OK; + } else { + ur = U_RESULT_ILL_PARAM; + } + + if(ur == U_RESULT_OK){ + d_listener(listener)->attached = FALSE; + result = TRUE; + } else { + assert(FALSE); + } + } else { + result = TRUE; + } + d_listenerUnlock(d_listener(listener)); + } + return result; +} + diff --git a/src/services/durability/code/d_readerRequest.c b/src/services/durability/code/d_readerRequest.c new file mode 100644 index 000000000..c3b854448 --- /dev/null +++ b/src/services/durability/code/d_readerRequest.c @@ -0,0 +1,536 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#include "d__readerRequest.h" +#include "d__sampleChainListener.h" +#include "d__table.h" +#include "d__group.h" +#include "d__admin.h" +#include "d__misc.h" +#include "v_dataReader.h" +#include "v_reader.h" +#include "v_topic.h" +#include "v_partition.h" +#include "v_kernel.h" +#include "v_waitset.h" +#include "v_handle.h" +#include "os_heap.h" +#include "os_stdlib.h" + +d_readerRequest +d_readerRequestProxyNew( + v_handle source) +{ + d_readerRequest request; + + /* Allocate readerRequestProxy object */ + request = d_readerRequest(os_malloc(C_SIZEOF(d_readerRequest))); + if (request) { + /* Call super-init */ + d_lockInit(d_lock(request), D_READER_REQUEST, + (d_objectDeinitFunc)d_readerRequestDeinit); + /* Initialize readerRequestProxy */ + request->admin = NULL; + request->readerHandle.index = source.index; + request->readerHandle.serial = source.serial; + request->readerHandle.server = 0; + request->requests = NULL; + request->filter = NULL; + request->filterParams = NULL; + request->filterParamsCount = 0; + request->groups = NULL; + } + return request; +} + +d_readerRequest +d_readerRequestNew( + d_admin admin, + v_waitsetEvent event) +{ + d_readerRequest request; + c_ulong i; + v_handleResult handleResult; + v_reader vreader, *vreaderPtr; + c_iter partitions; + v_partition partition; + v_topic topic; + d_group dgroup; + c_char *topicName; + c_bool remove; + + assert(d_adminIsValid(admin)); + + /* Allocate readerRequest object */ + request = d_readerRequest(os_malloc(C_SIZEOF(d_readerRequest))); + if (request) { + remove = FALSE; + /* Call super-init */ + d_lockInit(d_lock(request), D_READER_REQUEST, + (d_objectDeinitFunc)d_readerRequestDeinit); + /* Initialize readerRequest */ + request->admin = admin; + request->readerHandle = v_waitsetEventSource(event); + request->requests = d_tableNew(d_chainCompare, d_chainFree); + if (v_waitsetEventHistoryRequestFilter(event)) { + request->filter = os_strdup(v_waitsetEventHistoryRequestFilter(event)); + } else { + request->filter = NULL; + } + request->resourceLimits = v_waitsetEventHistoryRequestResourceLimits(event); + request->minSourceTimestamp = c_timeFromTimeW(v_waitsetEventHistoryRequestMinTimestamp(event)); + request->maxSourceTimestamp = c_timeFromTimeW(v_waitsetEventHistoryRequestMaxTimestamp(event)); + /* When maxSourceTimestamp is infinite and minSourceTimestamp is zero set + * the minSourceTimestamp to MIN_INFINITE. In legacy products the + * MIN_INFINITE lower time bound (when no other conditions are set) is used + * to indicate that the request does not contain conditions. When the lower + * time bound is ZERO the request is processed as if it had conditions. + */ + if (c_timeIsInfinite(request->maxSourceTimestamp) && + c_timeIsZero(request->minSourceTimestamp)) { + request->minSourceTimestamp = C_TIME_MIN_INFINITE; + } + + request->filterParamsCount = c_arraySize(v_waitsetEventHistoryRequestFilterParams(event)); + + if (request->filterParamsCount > 0) { + request->filterParams = (c_char**)(os_malloc(request->filterParamsCount*sizeof(c_char*))); + for (i=0; ifilterParamsCount; i++) { + request->filterParams[i] = os_strdup(v_waitsetEventHistoryRequestFilterParams(event)[i]); + } + } else { + request->filterParams = NULL; + } + request->groupsIgnored = FALSE; + request->groups = d_tableNew(d_groupCompare, d_groupFree); + handleResult = v_handleClaim(request->readerHandle, (v_object*)(vreaderPtr = &vreader)); + + if (handleResult == V_HANDLE_OK) { + /* Apparently only reader requests for datareaders are allowed. + * For non-datareaders the current implementation returns NULL. + */ + if (v_objectKind(vreader) == K_DATAREADER) { + topic = v_dataReaderGetTopic(v_dataReader(vreader)); + + if(topic){ + topicName = v_entityName(topic); + partitions = v_readerGetPartitions(vreader); + + if (partitions != NULL) { + partition = v_partition(c_iterTakeFirst(partitions)); + + while (partition) { + dgroup = d_groupNew( + v_entity(partition)->name, topicName, + d_durabilityKindFromKernel (v_topicQosRef(topic)->durability.v.kind), + D_GROUP_KNOWLEDGE_UNDEFINED, D_QUALITY_ZERO); + d_tableInsert(request->groups, dgroup); + c_free(partition); + partition = v_partition(c_iterTakeFirst(partitions)); + } + c_free(topic); + c_iterFree(partitions); + } else { + remove = TRUE; + } + } else { + remove = TRUE; + } + } else { + remove = TRUE; + } + v_handleRelease(request->readerHandle); + } else { + remove = TRUE; + } + if (remove == TRUE) { + d_readerRequestFree(request); + request = NULL; + } + } + return request; +} + +d_admin +d_readerRequestGetAdmin( + d_readerRequest request) +{ + d_admin admin; + + assert(d_readerRequestIsValid(request)); + + if (request) { + admin = request->admin; + } else { + admin = NULL; + } + return admin; +} + +static c_bool +addGroup( + d_group group, + c_voidp args) +{ + d_table table; + + table = d_table(args); + d_tableInsert(table, d_objectKeep(d_object(group))); + return TRUE; +} + +d_table +d_readerRequestGetGroups( + d_readerRequest request) +{ + d_table result; + + assert(d_readerRequestIsValid(request)); + + if (request) { + d_lockLock(d_lock(request)); + result = d_tableNew(d_groupCompare, d_groupFree); + d_tableWalk(request->groups, addGroup, result); + d_lockUnlock(d_lock(request)); + } else { + result = NULL; + } + return result; +} + +void +d_readerRequestRemoveGroup( + d_readerRequest request, + d_group group) +{ + d_group dgroup; + + assert(d_readerRequestIsValid(request)); + + if (request) { + d_lockLock(d_lock(request)); + dgroup = d_tableRemove(request->groups, group); + d_lockUnlock(d_lock(request)); + + if (dgroup) { + d_groupFree(dgroup); + } + } + return; +} + +v_handle +d_readerRequestGetHandle( + d_readerRequest request) +{ + v_handle handle; + + handle.index = request->readerHandle.index; + handle.serial = request->readerHandle.serial; + handle.server = request->readerHandle.server; + return handle; +} + +c_long +d_readerRequestCompare( + d_readerRequest request1, + d_readerRequest request2) +{ + c_long result; + + if (request1 && request2) { + if (request1->readerHandle.index < request2->readerHandle.index) { + result = -1; + } else if (request1->readerHandle.index > request2->readerHandle.index) { + result = 1; + } else if (request1->readerHandle.serial < request2->readerHandle.serial) { + result = -1; + } else if (request1->readerHandle.serial > request2->readerHandle.serial) { + result = 1; + } else { + result = 0; + } + } else if(request1){ + result = 1; + } else if(request2){ + result = -1; + } else { + result = 0; + } + return result; +} + + +void +d_readerRequestDeinit( + d_readerRequest request) +{ + c_ulong i; + + assert(d_readerRequestIsValid(request)); + + if (request->requests) { + d_tableFree(request->requests); + request->requests = NULL; + } + if (request->filter) { + os_free(request->filter); + request->filter = NULL; + } + for (i=0; ifilterParamsCount; i++) { + os_free(request->filterParams[i]); + } + if (request->filterParams) { + os_free(request->filterParams); + request->filterParams = NULL; + } + if (request->groups) { + d_tableFree(request->groups); + request->groups = NULL; + } + /* Call super-deinit */ + d_lockDeinit(d_lock(request)); +} + +void +d_readerRequestFree( + d_readerRequest request) +{ + assert(d_readerRequestIsValid(request)); + + d_objectFree(d_object(request)); +} + +c_bool +d_readerRequestAddChain( + d_readerRequest request, + d_chain chain) +{ + c_bool result; + d_chain found; + + assert(d_readerRequestIsValid(request)); + assert(d_chainIsValid(chain)); + + if (request && chain) { + d_lockLock(d_lock(request)); + found = d_tableInsert(request->requests, chain); + d_lockUnlock(d_lock(request)); + + if (found) { + result = FALSE; + } else { + d_objectKeep(d_object(chain)); + result = TRUE; + } + } else { + result = FALSE; + } + return result; +} + +c_bool +d_readerRequestRemoveChain( + d_readerRequest request, + d_chain chain) +{ + d_chain found; + c_bool result; + + assert(d_readerRequestIsValid(request)); + assert(d_chainIsValid(chain)); + + if (request && chain) { + d_lockLock(d_lock(request)); + found = d_tableRemove(request->requests, chain); + d_lockUnlock(d_lock(request)); + + if (found) { + result = TRUE; + d_chainFree(found); + } else { + result = FALSE; + } + } else { + result = FALSE; + } + return result; +} + +c_bool +d_readerRequestHasChains( + d_readerRequest request) +{ + c_bool result; + + assert(d_readerRequestIsValid(request)); + + if (request) { + d_lockLock(d_lock(request)); + result = (d_tableSize(request->requests) != 0); + d_lockUnlock(d_lock(request)); + } else { + result = FALSE; + } + return result; +} + +static c_bool +checkCompleteness( + d_group group, + c_voidp args) +{ + c_bool result; + + OS_UNUSED_ARG(args); + assert(!args); + + if (d_groupGetCompleteness(group) == D_GROUP_COMPLETE) { + result = TRUE; + } else { + result = FALSE; + } + return result; +} + +c_bool +d_readerRequestAreGroupsComplete( + d_readerRequest request) +{ + c_bool result; + + assert(d_readerRequestIsValid(request)); + + if (request) { + d_lockLock(d_lock(request)); + result = d_tableWalk(request->groups, checkCompleteness, NULL); + d_lockUnlock(d_lock(request)); + } else { + result = FALSE; + } + return result; +} + +c_bool +d_readerRequestAddGroup( + d_readerRequest request, + d_group group) +{ + c_bool result; + d_group found; + + assert(d_readerRequestIsValid(request)); + + if (request) { + d_lockLock(d_lock(request)); + found = d_tableInsert(request->groups, group); + d_lockUnlock(d_lock(request)); + + if (!found) { + d_objectKeep(d_object(group)); + result = TRUE; + } else { + result = FALSE; + } + } else { + result = FALSE; + } + return result; +} + +void +d_readerRequestSetGroupIgnored( + d_readerRequest request) +{ + assert(d_readerRequestIsValid(request)); + request->groupsIgnored = TRUE; +} + +c_bool +d_readerRequestGetGroupIgnored( + d_readerRequest request) +{ + assert(d_readerRequestIsValid(request)); + return request->groupsIgnored; +} + +static c_bool +printGroup( + d_group group, + c_voidp args) +{ + c_char *partition, *topic; + + OS_UNUSED_ARG(args); + assert(!args); + partition = d_groupGetPartition(group); + topic = d_groupGetTopic(group); + + printf(" %s.%s\n", partition, topic); + + os_free(partition); + os_free(topic); + + return TRUE; +} + +void +d_readerRequestPrint( + d_readerRequest request) +{ + c_ulong i; + + assert(d_readerRequestIsValid(request)); + + if (request) { + printf( + "- source:\n"\ + " index : '%d'\n"\ + " serial : '%d'\n"\ + "- filter:\n", + request->readerHandle.index, + request->readerHandle.serial); + + if (request->filter) { + printf(" expression : '%s'\n", request->filter); + } else { + printf(" expression : NULL\n"); + } + if (request->filterParamsCount > 0) { + printf(" params :\n"); + } else { + printf(" params : NULL\n"); + } + + for (i=0; ifilterParamsCount; i++) { + printf(" [%d] : '%s'\n", i, request->filterParams[i]); + } + printf ("- resourceLimits:\n"); + printf (" max_instances : '%d'\n", request->resourceLimits.v.max_instances); + printf (" max_samples : '%d'\n", request->resourceLimits.v.max_samples); + printf (" max_samples_per_instance : '%d'\n", request->resourceLimits.v.max_samples_per_instance); + printf ("- minSourceTimestamp:\n"); + printf (" seconds : '%d'\n", request->minSourceTimestamp.seconds); + printf (" nanoseconds : '%d'\n", C_TIME_NANOS(request->minSourceTimestamp.nanoseconds)); + printf ("- maxSourceTimestamp:\n"); + printf (" seconds : '%d'\n", request->maxSourceTimestamp.seconds); + printf (" nanoseconds : '%d'\n", C_TIME_NANOS(request->maxSourceTimestamp.nanoseconds)); + printf ("- groups involved:\n"); + + d_tableWalk(request->groups, printGroup, NULL); + } +} diff --git a/src/services/durability/code/d_remoteReaderListener.c b/src/services/durability/code/d_remoteReaderListener.c new file mode 100644 index 000000000..4d66044d3 --- /dev/null +++ b/src/services/durability/code/d_remoteReaderListener.c @@ -0,0 +1,454 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "d__remoteReaderListener.h" +#include "d__waitset.h" +#include "d__admin.h" +#include "d__listener.h" +#include "d__durability.h" +#include "d__configuration.h" +#include "d__listener.h" +#include "d__misc.h" +#include "d__table.h" +#include "d__subscriber.h" +#include "d__thread.h" +#include "d_qos.h" +#include "d_networkAddress.h" +#include "d__fellow.h" +#include "d__client.h" +#include "os_heap.h" +#include "os_report.h" +#include "u_participant.h" +#include "u_subscriber.h" +#include "u_listener.h" +#include "u_types.h" +#include "v_builtin.h" +#include "v_event.h" +#include "v_state.h" +#include "v_message.h" +#include "v_dataReaderSample.h" +#include "v_dataReaderInstance.h" +#include "kernelModuleI.h" + +/** + * Macro that checks the d_remoteReaderListener validity. + * Because d_remoteReaderListener is a concrete class typechecking is required. + */ +#define d_remoteReaderListenerIsValid(_this) \ + d_listenerIsValidKind(d_listener(_this), D_REMOTE_READER_LISTENER) + +/** + * \brief The d_remoteReaderListener cast macro. + * + * This macro casts an object to a d_remoteReaderListener object. + */ +#define d_remoteReaderListener(_this) ((d_remoteReaderListener)(_this)) + + +C_STRUCT(d_remoteReaderListener) { + C_EXTENDS(d_listener); + u_dataReader dataReader; + d_waitsetEntity waitsetData; + c_bool terminate; + d_subscriber subscriber; +}; + +static +c_ulong +getReaderFlag( + char *topic_name) +{ + if (topic_name) { + if (strcmp(topic_name, D_NAMESPACES_TOPIC_NAME) == 0) return D_NAMESPACES_READER_FLAG; + if (strcmp(topic_name, D_NAMESPACES_REQ_TOPIC_NAME) == 0) return D_NAMESPACESREQUEST_READER_FLAG; + if (strcmp(topic_name, D_STATUS_TOPIC_NAME) == 0) return D_STATUS_READER_FLAG; + if (strcmp(topic_name, D_GROUPS_REQ_TOPIC_NAME) == 0) return D_GROUPSREQUEST_READER_FLAG; + if (strcmp(topic_name, D_DELETE_DATA_TOPIC_NAME) == 0) return D_DELETEDATA_READER_FLAG; + if (strcmp(topic_name, D_NEWGROUP_TOPIC_NAME) == 0) return D_NEWGROUP_READER_FLAG; + if (strcmp(topic_name, D_SAMPLE_REQ_TOPIC_NAME) == 0) return D_SAMPLREQUEST_READER_FLAG; + if (strcmp(topic_name, D_SAMPLE_CHAIN_TOPIC_NAME) == 0) return D_SAMPLECHAIN_READER_FLAG; + if (strcmp(topic_name, D_CAPABILITY_TOPIC_NAME) == 0) return D_CAPABILITY_READER_FLAG; + if (strcmp(topic_name, D_DURABILITY_STATE_REQUEST_TOPIC_NAME) == 0) return D_DURABILITYSTATEREQUEST_READER_FLAG; + if (strcmp(topic_name, D_HISTORICAL_DATA_REQUEST_TOPIC_NAME) == 0) return D_HISTORICALDATAREQUEST_READER_FLAG; + if (strcmp(topic_name, D_DURABILITY_STATE_TOPIC_NAME) == 0) return D_DURABILITYSTATE_READER_FLAG; + if (strcmp(topic_name, D_HISTORICAL_DATA_TOPIC_NAME) == 0) return D_HISTORICALDATA_READER_FLAG; + } + /* default, no durability reader */ + return 0; +} + + + +static u_actionResult +processSubscriptionInfo( + c_object object, + c_voidp copyArg) +{ + d_remoteReaderListener listener; + d_admin admin; + d_fellow fellow, fellow2; + d_client client, duplicate; + d_networkAddress fellowAddr, clientAddr; + u_actionResult result = V_PROCEED; + v_dataReaderSample sample; + v_dataReaderInstance instance; + v_message message; + v_subscriptionInfoTemplate template; + const struct v_subscriptionInfo *subscriptionInfo; + c_ulong reader; + d_durability durability; + d_configuration config; + + if (object != NULL) { + listener = d_remoteReaderListener(copyArg); + admin = d_listenerGetAdmin(d_listener(listener)); + durability = d_adminGetDurability(admin); + config = d_durabilityGetConfiguration(durability); + sample = v_dataReaderSample(object); + instance = v_readerSampleInstance(sample); + message = v_dataReaderSampleTemplate(object)->message; + template = (v_subscriptionInfoTemplate)message; + + /* The fellow address is NOT the message->writerGID because + * the message is written by the local DDSI service. The address + * of the actual fellow is the address of the subscriptionInfo->participant_key, + * so use that one. */ + if (template) { + subscriptionInfo = &template->userData; + reader = getReaderFlag(subscriptionInfo->topic_name); + + /* Detect durability readers */ + if ((reader & (D_BASIC_DURABILITY_READER_FLAGS | D_CAPABILITY_READER_FLAG)) != 0) { + fellowAddr = d_networkAddressNew(subscriptionInfo->participant_key.systemId, 0, 0); + fellow = d_adminGetUnconfirmedFellow(admin, fellowAddr); + if (!fellow) { + fellow = d_adminGetFellow(admin, fellowAddr); + } + if (!fellow) { + /* The fellow does not yet exist, try to create the fellow + * and add it to the list of unconfirmed fellows + * Assume the state is D_STATE_INIT until an update comes along */ + fellow2 = d_fellowNew(fellowAddr, D_STATE_INIT, FALSE); + fellow = d_adminAddFellow(admin, fellow2); + /* If the fellow is NULL then it is terminating. + In that case we do not have to do anthing */ + if (fellow != fellow2) { + d_fellowFree(fellow2); + } + } + if (fellow) { + if (v_dataReaderInstanceStateTest(instance, L_DISPOSED)) { + /* The durability reader has been disposed. + * Reset the corresponding flag from the fellow */ + d_fellowRemoveReader(fellow, reader); + } else { + /* A durability reader is detected. + * Set the corresponding flag from the fellow */ + d_fellowAddReader(fellow, reader); + } + d_fellowFree(fellow); + } + d_networkAddressFree(fellowAddr); + + /* Detect client-durability readers; only needed when client-durability enabled + * and waitforRemoteReaders is */ + } else if ( (config->clientDurabilityEnabled) && (config->waitForRemoteReaders) && ((reader & D_FULL_CLIENT_DURABILITY_READER_FLAGS) != 0) ) { + clientAddr = d_networkAddressNew(subscriptionInfo->participant_key.systemId, 0, 0); + client = d_clientNew(clientAddr); + if ((duplicate = d_adminAddClient(admin, client)) != client) { + d_clientFree(client); + client = duplicate; + } + /* ClientId will NOT be set yet because no historicalDataRequest of durabilityStateRequest is received */ + if (client) { + if (v_dataReaderInstanceStateTest(instance, L_DISPOSED)) { + d_clientRemoveReader(client, reader); + } else { + d_clientAddReader(client, reader); + } + d_clientFree(client); + } + d_networkAddressFree(clientAddr); + } + } + } + return result; +} + + +void +d_remoteReaderListenerCheckReaders( + d_remoteReaderListener listener) +{ + u_result ur; + d_admin admin = d_listenerGetAdmin(d_listener(listener)); + d_durability durability = d_adminGetDurability(admin); + + assert(d_remoteReaderListenerIsValid(listener)); + + /* Read DCPSSubcriptions and process them */ + d_lockLock(d_lock(listener)); + ur = u_dataReaderTake(listener->dataReader, + U_STATE_ANY_SAMPLE | U_STATE_ANY_VIEW | U_STATE_DISPOSED_INSTANCE, + processSubscriptionInfo, listener, OS_DURATION_ZERO); + if (ur != U_RESULT_OK && ur != U_RESULT_NO_DATA) { + OS_REPORT(OS_ERROR, D_CONTEXT_DURABILITY, ur, + "Failed to read data from DCPSSubscription reader (result: %s)", u_resultImage(ur)); + d_durabilityTerminate(durability, TRUE); + } + ur = u_dataReaderRead(listener->dataReader, U_STATE_ANY, processSubscriptionInfo, + listener, OS_DURATION_ZERO); + if (ur != U_RESULT_OK && ur != U_RESULT_NO_DATA) { + OS_REPORT(OS_ERROR, D_CONTEXT_DURABILITY, ur, + "Failed to read data from DCPSSubscription reader (result: %s)", u_resultImage(ur)); + d_durabilityTerminate(durability, TRUE); + } + d_lockUnlock(d_lock(listener)); +} + +static c_ulong +d_remoteReaderListenerAction( + u_object o, + u_waitsetEvent event, + c_voidp usrData) +{ + d_remoteReaderListener listener; + u_result ur; + d_admin admin; + d_durability durability; + d_thread self = d_threadLookupSelf(); + + listener = d_remoteReaderListener(usrData); + + assert(d_remoteReaderListenerIsValid(listener)); + + d_threadAwake(self); + d_lockLock(d_lock(listener)); + /* Read DCPSSubcriptions and process them */ + ur = u_dataReaderTake(u_dataReader(o), U_STATE_ANY_SAMPLE | U_STATE_ANY_VIEW | U_STATE_DISPOSED_INSTANCE, processSubscriptionInfo, listener, OS_DURATION_ZERO); + if (ur != U_RESULT_OK && ur != U_RESULT_NO_DATA) { + admin = d_listenerGetAdmin(d_listener(listener)); + durability = d_adminGetDurability(admin); + OS_REPORT(OS_ERROR, D_CONTEXT_DURABILITY, ur, + "Failed to read data from dcpsHeartbeatReader (result: %s)", u_resultImage(ur)); + d_durabilityTerminate(durability, TRUE); + } + ur = u_dataReaderRead(u_dataReader(o), U_STATE_NOT_READ_SAMPLE | U_STATE_ANY_VIEW | U_STATE_ANY_INSTANCE, processSubscriptionInfo, listener, OS_DURATION_ZERO); + if (ur != U_RESULT_OK && ur != U_RESULT_NO_DATA) { + admin = d_listenerGetAdmin(d_listener(listener)); + durability = d_adminGetDurability(admin); + OS_REPORT(OS_ERROR, D_CONTEXT_DURABILITY, ur, + "Failed to read data from dcpsHeartbeatReader (result: %s)", u_resultImage(ur)); + d_durabilityTerminate(durability, TRUE); + } + d_lockUnlock(d_lock(listener)); + d_threadAsleep(self, ~0u); + return event->kind; +} + +static void +d_remoteReaderListenerDeinit( + d_remoteReaderListener listener) +{ + assert(d_remoteReaderListenerIsValid(listener)); + + /* Stop the remoteReaderListener */ + d_remoteReaderListenerStop(listener); + + if (listener->waitsetData) { + d_waitsetEntityFree(listener->waitsetData); + listener->waitsetData = NULL; + } + if (listener->dataReader) { + u_objectFree(u_object(listener->dataReader)); + listener->dataReader = NULL; + } + listener->subscriber = NULL; + /* Call super-deinit */ + d_listenerDeinit(d_listener(listener)); +} + +d_remoteReaderListener +d_remoteReaderListenerNew( + d_subscriber subscriber) +{ + d_remoteReaderListener listener; + d_admin admin; + d_durability durability; + u_participant uParticipant; + v_gid gid; + c_value ps[1]; + v_readerQos readerQos = NULL; + os_threadAttr attr; + + assert(d_subscriberIsValid(subscriber)); + + /* Allocate remoteReaderListener object */ + if ((listener = d_remoteReaderListener(os_malloc(C_SIZEOF(d_remoteReaderListener)))) == NULL) { + goto err_alloc_listener; + } + /* Call super-init */ + d_listenerInit(d_listener(listener), D_REMOTE_READER_LISTENER, subscriber, NULL, + (d_objectDeinitFunc)d_remoteReaderListenerDeinit); + /* Initialize remoteReaderListener */ + admin = d_listenerGetAdmin(d_listener(listener)); + durability = d_adminGetDurability(admin); + if ((uParticipant = u_participant(d_durabilityGetService(durability))) == NULL) { + goto err_uparticipant; + } + listener->terminate = FALSE; + listener->subscriber = subscriber; + /* Create a reader that listens to remote DCPSSubscription + * topics. The reader uses the builtin subscriber, and + * only listens to topics that have a different systemId + * than myself. */ + if ((readerQos = d_readerQosNew(V_DURABILITY_TRANSIENT, V_RELIABILITY_RELIABLE)) == NULL) { + goto err_readerQos; + } + readerQos->history.v.kind = V_HISTORY_KEEPLAST; + readerQos->history.v.depth = 1; + gid = u_observableGid((u_observable)subscriber->builtinSubscriber); + ps[0].kind = V_ULONG; + ps[0].is.ULong = gid.systemId; + listener->dataReader = u_subscriberCreateDataReader( + subscriber->builtinSubscriber, + "remoteReaderListenerReader", + "select * from " V_SUBSCRIPTIONINFO_NAME " where key.systemId <> %0", + ps, 1, + readerQos); + if (listener->dataReader == NULL) { + goto err_dataReader; + } + if(u_entityEnable(u_entity(listener->dataReader)) != U_RESULT_OK) { + goto err_dataReaderEnable; + } + os_threadAttrInit(&attr); + listener->waitsetData = d_waitsetEntityNew( + "remoteReader", + u_object(listener->dataReader), + d_remoteReaderListenerAction, + V_EVENT_DATA_AVAILABLE, + attr, listener); + assert(listener->waitsetData); + /* Obtain historical data */ + (void) u_dataReaderWaitForHistoricalData(listener->dataReader, OS_DURATION_ZERO); + d_readerQosFree(readerQos); + return listener; + +err_dataReaderEnable: + u_objectFree(u_object(listener->dataReader)); +err_dataReader: + d_readerQosFree(readerQos); +err_readerQos: +err_uparticipant: + d_remoteReaderListenerFree(listener); +err_alloc_listener: + listener = NULL; + return NULL; +} + + +void +d_remoteReaderListenerFree( + d_remoteReaderListener listener) +{ + assert(d_remoteReaderListenerIsValid(listener)); + + d_objectFree(d_object(listener)); +} + + +c_bool +d_remoteReaderListenerStart( + d_remoteReaderListener listener) +{ + c_bool result; + d_waitset waitset; + u_result ur; + + result = FALSE; + + assert(d_remoteReaderListenerIsValid(listener)); + + if (listener) { + d_lockLock(d_lock(listener)); + + if (d_listener(listener)->attached == FALSE) { + waitset = d_subscriberGetWaitset(listener->subscriber); + result = d_waitsetAttach(waitset, listener->waitsetData); + + if (result == TRUE) { + /* A V_DATA_AVAILABLE event is only generated when new data + * arrives. It is NOT generated when historical data is inserted. + * In case this durability service receives historical + * DCPSSubscriptions from another durability service that + * was started earlier, all these DCPSSubscriptions are + * inserted in the reader at creation time. To read these + * we must explicitly trigger a take action. */ + ur = u_dataReaderRead(listener->dataReader, U_STATE_ANY, processSubscriptionInfo, listener, OS_DURATION_ZERO); + if (ur != U_RESULT_OK && ur != U_RESULT_NO_DATA) { + OS_REPORT(OS_ERROR, D_CONTEXT_DURABILITY, ur, + "Failed to read data from remoteReaderListenerReader (result: %s)", u_resultImage(ur)); + } else { + d_listener(listener)->attached = TRUE; + result = TRUE; + } + } + } else { + result = TRUE; + } + d_lockUnlock(d_lock(listener)); + } + return result; +} + + +c_bool +d_remoteReaderListenerStop( + d_remoteReaderListener listener) +{ + c_bool result; + d_admin admin; + d_subscriber subscriber; + d_waitset waitset; + + assert(d_remoteReaderListenerIsValid(listener)); + + result = FALSE; + + if (listener) { + d_lockLock(d_lock(listener)); + + if (d_listener(listener)->attached == TRUE) { + admin = d_listenerGetAdmin(d_listener(listener)); + subscriber = d_adminGetSubscriber(admin); + waitset = d_subscriberGetWaitset(subscriber); + d_lockUnlock(d_lock(listener)); + result = d_waitsetDetach(waitset, listener->waitsetData); + d_lockLock(d_lock(listener)); + + if (result == TRUE) { + d_listener(listener)->attached = FALSE; + } + } else { + result = TRUE; + } + d_lockUnlock(d_lock(listener)); + } + return result; +} diff --git a/src/services/durability/code/d_sampleChain.c b/src/services/durability/code/d_sampleChain.c new file mode 100644 index 000000000..6963d9107 --- /dev/null +++ b/src/services/durability/code/d_sampleChain.c @@ -0,0 +1,196 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "d_sampleChain.h" +#include "d__admin.h" +#include "d__durability.h" +#include "d__misc.h" +#include "d_message.h" +#include "d_networkAddress.h" +#include "os_report.h" +#include "vortex_os.h" + +d_sampleChain +d_sampleChainNew( + d_admin admin, + const c_char* partition, + const c_char* topic, + d_durabilityKind kind, + d_networkAddress source) +{ + d_sampleChain sampleChain = NULL; + + assert(admin); + assert(partition); + assert(topic); + + if(admin && partition && topic){ + sampleChain = d_sampleChain(os_malloc(C_SIZEOF(d_sampleChain))); + d_messageInit(d_message(sampleChain), admin); + + sampleChain->msgBody._d = BEAD; + sampleChain->msgBody._u.bead.size = 0; + sampleChain->partition = os_strdup(partition); + sampleChain->topic = os_strdup(topic); + sampleChain->durabilityKind = kind; + sampleChain->addressees = NULL; + sampleChain->addresseesCount = 0; + sampleChain->source.systemId = source->systemId; + sampleChain->source.localId = source->localId; + sampleChain->source.lifecycleId = source->lifecycleId; + } + return sampleChain; +} + +void +d_sampleChainFree( + d_sampleChain sampleChain) +{ + assert(sampleChain); + + if(sampleChain){ + if(sampleChain->partition){ + os_free(sampleChain->partition); + } + if(sampleChain->topic){ + os_free(sampleChain->topic); + } + if(sampleChain->addressees){ + os_free(sampleChain->addressees); + } + switch(sampleChain->msgBody._d){ + case LINK: + /*Do nothing here*/ + break; + case BEAD: + if(sampleChain->msgBody._u.bead.size > 0){ + os_free(sampleChain->msgBody._u.bead.value); + } + break; + default: + OS_REPORT(OS_ERROR,"d_sampleChainFree",0, + "Illegal message discriminator value (%d) detected.", + sampleChain->msgBody._d); + assert(FALSE); + break; + } + os_free(sampleChain); + } + return; +} + +int +d_sampleChainCompare( + d_sampleChain sampleChain1, + d_sampleChain sampleChain2) +{ + int result = 0; + if(sampleChain1 != sampleChain2){ + if(!sampleChain1 && !sampleChain2){ + result = 0; + } else if(sampleChain1 && !sampleChain2){ + result = 1; + } else if(!sampleChain1 && sampleChain2) { + result = -1; + } else { + result = strcmp(sampleChain1->partition, sampleChain2->partition); + + if(result == 0){ + result = strcmp(sampleChain1->topic, sampleChain2->topic); + + if(result == 0){ + if(sampleChain1->durabilityKind == sampleChain2->durabilityKind){ + if(d_message(sampleChain1)->senderAddress.systemId == d_message(sampleChain2)->senderAddress.systemId){ + if(d_message(sampleChain1)->addressee.systemId == d_message(sampleChain2)->addressee.systemId){ + if(d_message(sampleChain1)->sequenceNumber == d_message(sampleChain2)->sequenceNumber){ + result = 0; + } + } + } + } else if(sampleChain1->durabilityKind > sampleChain2->durabilityKind){ + result = 1; + } else { + result = -1; + } + } + } + } + } + return result; +} + +c_bool +d_sampleChainContainsAddressee( + d_sampleChain sampleChain, + d_networkAddress addressee) +{ + c_bool found; + c_ulong i; + d_networkAddress address; + + found = FALSE; + + if (sampleChain) { + for(i=0; iaddresseesCount && !found; i++){ + address = &(d_networkAddress(sampleChain->addressees)[i]); + + if (d_networkAddressEquals(address, addressee)) { + found = TRUE; + } + } + } + return found; +} + +int +d_sampleChainPrintAddressees( + c_char *buffer, + c_size length, + d_sampleChain chain) +{ + const c_char *space = ""; + c_size offset = 0; + c_ulong index; + d_networkAddress address; + int count, total = 0; + + assert (buffer != NULL); + assert (chain != NULL); + + for (index = 0; index < chain->addresseesCount && total >= 0; index++) { + address = &d_networkAddress(chain->addressees)[index]; + assert (address != NULL); + + count = snprintf ( + buffer+offset, length-offset, "%s%u", space, address->systemId); + if (count >= 0) { + if ((c_size)count >= (length - offset)) { + offset = length; + } else { + offset += (c_size)count; + } + total += count; + } else { + total = -1; + } + + space = " "; + } + + return total; +} diff --git a/src/services/durability/code/d_sampleChainListener.c b/src/services/durability/code/d_sampleChainListener.c new file mode 100644 index 000000000..132ff45e0 --- /dev/null +++ b/src/services/durability/code/d_sampleChainListener.c @@ -0,0 +1,3387 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#include "vortex_os.h" +#include "d__sampleChainListener.h" +#include "d__readerListener.h" +#include "d__mergeAction.h" +#include "d__group.h" +#include "d__configuration.h" +#include "d__actionQueue.h" +#include "d__durability.h" +#include "d__fellow.h" +#include "d__listener.h" +#include "d__admin.h" +#include "d__nameSpace.h" +#include "d__readerRequest.h" +#include "d__readerListener.h" +#include "d__publisher.h" +#include "d__nameSpacesRequestListener.h" +#include "d__table.h" +#include "d__misc.h" +#include "d__groupLocalListener.h" +#include "d__group.h" +#include "d__eventListener.h" +#include "d__conflictResolver.h" +#include "d_sampleRequest.h" +#include "d_newGroup.h" +#include "d_sampleChain.h" +#include "d_groupsRequest.h" +#include "d_networkAddress.h" +#include "d_message.h" +#include "d__thread.h" +#include "d__groupHash.h" +#include "d_store.h" +#include "v_builtin.h" +#include "v_group.h" +#include "v_groupInstance.h" +#include "v_dataReaderInstance.h" +#include "v_writer.h" +#include "v_topic.h" +#include "v_partition.h" +#include "v_time.h" +#include "v_entry.h" +#include "v_entity.h" +#include "v_message.h" +#include "v_public.h" +#include "v_state.h" +#include "v_reader.h" +#include "v_messageExt.h" +#include "v_kernel.h" +#include "v_historicalDataRequest.h" +#include "sd_serializer.h" +#include "sd_serializerBigE.h" +#include "os_thread.h" +#include "os_heap.h" +#include "os_report.h" +#include "d__thread.h" + +/** + * \brief The d_sampleChainListener cast macro. + * + * This macro casts an object to a d_sampleChainListener object. + */ +#define d_sampleChainListener(_this) ((d_sampleChainListener)(_this)) + +/** + * \brief The d_chainBead cast macro. + * + * This macro casts an object to a d_chainBead object. + */ +#define d_chainBead(_this) ((d_chainBead)(_this)) + +/** + * \brief The d_chainLink cast macro. + * + * This macro casts an object to a d_chainBead object. + */ +#define d_chainLink(_this) ((d_chainLink)(_this)) + +#define d_chainKeep(chain) ((d_objectKeep(d_object(chain)))) + +C_STRUCT(d_sampleChainListener){ + C_EXTENDS(d_readerListener); + d_table chains; + c_iter chainsWaiting; + c_ulong id; + d_eventListener fellowListener; + d_actionQueue resendQueue; + c_iter unfulfilledChains; + d_table mergeActions; +}; + +C_STRUCT(d_chainBead){ + d_table senders; /* list of fellows that sent it (subset of chain->fellows) */ + v_message message; + c_value keyValues[32]; + c_ulong nrOfKeys; + c_ulong refCount; +}; + +C_STRUCT(d_chainLink){ + d_networkAddress sender; + c_ulong sampleCount; + d_admin admin; +}; +C_STRUCT(d_chain){ + C_EXTENDS(d_object); + d_sampleRequest request; + d_table beads; + d_table links; + d_table fellows; /* list of fellows to which a sampleRequest has been send */ + c_long samplesExpect; + c_ulong receivedSize; + c_type xmsgType; + c_type messageType; + sd_serializer serializer; /* serializer used to serialize "normal" data */ + sd_serializer serializerEOT; /* serializer used to serialize EOTs */ + sd_serializer serializerNode; /* serializer used to serialize v_nodeExt for deserializing just the v_message flags */ + v_group vgroup; +}; + +struct chainCleanup{ + d_admin admin; + d_sampleChainListener listener; + d_fellow fellow; + c_iter toRemove; + c_iter beadsToRemove; + c_long dupsFromFellowCount; +}; + +C_CLASS(d_resendAction); +C_STRUCT(d_resendAction){ + c_iter messages; + d_group group; + d_sampleChainListener listener; +}; + +#define d_resendAction(a) ((d_resendAction)(a)) + +void d_traceChain(d_chain chain) +{ + char str[1024]; + d_tableIter tableIter; + d_fellow fellow; + size_t pos = 0; + + /* determine the list of fellows to be addressed */ + str[0] = '\0'; + fellow = d_fellow(d_tableIterFirst(chain->fellows, &tableIter)); + while (fellow) { + int n = snprintf(str + pos, sizeof(str) - pos, "%s%u", (strcmp(str, "") == 0) ? "" : ",", fellow->address->systemId); + if (n > 0) { pos += (size_t)n; } else { break; } + fellow = d_fellow(d_tableIterNext(&tableIter)); + } + + d_trace(D_TRACE_CHAINS, " - chain %p, request %p, group %s.%s fellows [%s] #beads %d, #links %d, receivedSize %d, samplesExpect %d\n", + (void *)chain, (void *)chain->request, chain->request->partition, chain->request->topic, str, + d_tableSize(chain->beads), d_tableSize(chain->links), chain->receivedSize, chain->samplesExpect); +} + +static void +updateGroupStatistics( + d_admin admin, + d_group group) +{ + /*update statistics*/ + d_adminStatisticsInfo info = d_adminStatisticsInfoNew(); + info->kind = D_ADMIN_STATISTICS_GROUP; + + switch(d_groupGetKind(group)){ + case D_DURABILITY_VOLATILE: + info->groupsIncompleteVolatileDif -=1; + info->groupsCompleteVolatileDif +=1; + break; + case D_DURABILITY_TRANSIENT_LOCAL: + case D_DURABILITY_TRANSIENT: + info->groupsIncompleteTransientDif -=1; + info->groupsCompleteTransientDif +=1; + break; + case D_DURABILITY_PERSISTENT: + info->groupsIncompletePersistentDif -=1; + info->groupsCompletePersistentDif +=1; + break; + default: + break; + } + + d_adminUpdateStatistics(admin, info); + d_adminStatisticsInfoFree(info); + + return; +} + +struct readBeadHelper { + d_resendAction action; + v_entry entry; + c_ulong totalCount; + c_ulong writeCount; + c_ulong disposeCount; + c_ulong writeDisposeCount; + c_ulong registerCount; + c_ulong unregisterCount; + c_ulong eotCount; + d_mergePolicy mergePolicy; + d_thread self; +}; + +struct chainRequestHelper{ + d_chain chain; + d_durability durability; + d_fellow fellow; + d_networkAddress master; + d_name role; + d_nameSpace nameSpace; +}; + +static v_writeResult +d_chainBeadInjectTryMessage( + d_durability durability, + v_message message, + v_group group, + v_entry entry); + +static void +d_chainFellowFree( + d_fellow fellow) +{ + d_fellowRequestRemove(fellow); + d_fellowFree(fellow); +} + +static c_bool +d_chainReportStatus( + d_chain chain, + d_durability durability) +{ + assert(d_objectIsValid(d_object(chain), D_CHAIN) == TRUE); + + d_printTimedEvent(durability, D_LEVEL_FINEST, + "- Group: '%s.%s', #Aligners: '%d', #Beads: '%d', #Links: '%d'\n", + chain->request->partition, + chain->request->topic, + d_tableSize(chain->fellows), + d_tableSize(chain->beads), + d_tableSize(chain->links)); + + return TRUE; +} + +/** + * \brief Compare two beads + * + * Two beads are the same if their messages are the same AND + * their keys are the same. + */ +static int +d_chainBeadCompare( + d_chainBead bead1, + d_chainBead bead2) +{ + int result = 0; + c_equality eq; + c_ulong i; + + assert(bead1); + assert(bead2); + + if (bead1->message && bead2->message) { + if ((eq = v_messageCompare(bead1->message, bead2->message)) == C_GT) { + result = 1; + } else if (eq == C_LT) { + result = -1; + } + /* The group administrates combined DISPOSE+UNREGISTER messages in the history of the instance + * AND keeps the v_registration in the unregistrations of the instance. + * Both are aligned and we need to ensure that the DISPOSE++UNREGISTER + * is always injected before the UNREGISTER, hence the extra compares + * below. + */ + else if(v_messageStateTest(bead1->message, L_DISPOSED) && v_messageStateTest(bead1->message, L_UNREGISTER) && (v_messageState(bead1->message) != v_messageState(bead2->message))){ + result = -1; + } else if(v_messageStateTest(bead2->message, L_DISPOSED) && v_messageStateTest(bead2->message, L_UNREGISTER) && (v_messageState(bead1->message) != v_messageState(bead2->message))){ + result = 1; + } else if (v_nodeState(bead1->message) > v_nodeState(bead2->message)) { + result = 1; + } else if (v_nodeState(bead1->message) < v_nodeState(bead2->message)) { + result = -1; + } else { + if (bead1->nrOfKeys == bead2->nrOfKeys) { + for (i = 0; i < bead1->nrOfKeys; i++) { + if ((eq = c_valueCompare(bead1->keyValues[i], bead2->keyValues[i])) != C_EQ) { + result = (eq == C_LT) ? -1 : 1; + break; + } + } + } else { + d_printTimedEvent(d_threadsDurability(), D_LEVEL_SEVERE, + "Unrecoverable error: beads in chain have different numbers of keys."); + OS_REPORT(OS_ERROR, D_CONTEXT_DURABILITY, 0, + "Unrecoverable error: beads in chain have different numbers of keys."); + d_durabilityTerminate(d_threadsDurability(), TRUE); + } + } + } else if (!bead1->message) { + result = -1; + } else { + result = 1; + } + return result; +} + +static void +d_chainDeinit( + d_chain chain) +{ + assert(d_chainIsValid(chain)); + + if (chain->vgroup) { + c_free(chain->vgroup); + chain->vgroup = NULL; + } + if (chain->beads) { + d_tableFree(chain->beads); + chain->beads = NULL; + } + if (chain->links) { + d_tableFree(chain->links); + chain->links = NULL; + } + if (chain->request) { + d_sampleRequestFree(chain->request); + chain->request = NULL; + } + if (chain->fellows) { + d_tableFree(chain->fellows); + chain->fellows = NULL; + } + if (chain->serializer) { + v_messageExtTypeFree (chain->xmsgType); + sd_serializerFree(chain->serializer); + chain->messageType = NULL; /* not ref counted */ + chain->xmsgType = NULL; + chain->serializer = NULL; + } + if (chain->serializerEOT) { + sd_serializerFree(chain->serializerEOT); + chain->serializerEOT = NULL; + } + if (chain->serializerNode) { + sd_serializerFree(chain->serializerNode); + chain->serializerNode = NULL; + } + /* Call super-deinit */ + d_objectDeinit(d_object(chain)); +} + +static int +d_chainLinkCompare( + d_chainLink link1, + d_chainLink link2) +{ + int result = 0; + + if(link1->sender->systemId > link2->sender->systemId){ + result = 1; + } else if(link1->sender->systemId < link2->sender->systemId){ + result = -1; + } else { + if(link1->sender->localId > link2->sender->localId){ + result = 1; + } else if(link1->sender->localId < link2->sender->localId){ + result = -1; + } else { + if(link1->sender->lifecycleId > link2->sender->lifecycleId){ + result = 1; + } else if(link1->sender->lifecycleId < link2->sender->lifecycleId){ + result = -1; + } else { + result = 0; + } + } + } + return result; +} + +static void +d_chainBeadFree( + d_chainBead chainBead) +{ + c_ulong i; + + assert(chainBead); + + /* No parent class, deallocate chainBead */ + if (chainBead->message) { + c_free(chainBead->message); + chainBead->message = NULL; + } + d_tableFree(chainBead->senders); + for (i=0;inrOfKeys;i++) { + c_valueFreeRef(chainBead->keyValues[i]); + } + os_free(chainBead); +} + +static void +d_chainLinkFree( + d_chainLink link) +{ + /* No parent class, deallocate chainLink */ + if (link->sender) { + d_networkAddressFree(link->sender); + link->sender = NULL; + } + os_free(link); +} + +d_chain +d_chainNew( + d_admin admin, + d_sampleRequest request) +{ + d_chain chain; + d_group group; + + assert(request); + + /* Allocate chain object */ + chain = d_chain(os_malloc(C_SIZEOF(d_chain))); + if (chain) { + /* Call super-init */ + d_objectInit(d_object(chain), D_CHAIN, + (d_objectDeinitFunc)d_chainDeinit); + /* Initialize chain object */ + chain->request = request; + chain->beads = d_tableNew(d_chainBeadCompare, d_chainBeadFree); + chain->links = d_tableNew(d_chainLinkCompare, d_chainLinkFree); + chain->fellows = d_tableNew(d_fellowCompare, d_chainFellowFree); + chain->samplesExpect = 0; + chain->receivedSize = 0; + if (admin) { + group = d_adminGetLocalGroup(admin, + request->partition, request->topic, + request->durabilityKind); + chain->vgroup = d_groupGetKernelGroup(group); + chain->xmsgType = v_messageExtTypeNew (v_groupTopic (chain->vgroup)); + chain->messageType = v_topicMessageType (v_groupTopic (chain->vgroup)); + chain->serializer = sd_serializerBigENewTyped (chain->xmsgType); + chain->serializerEOT = sd_serializerBigENewTyped(c_resolve(c_getBase((c_object)chain->vgroup), "kernelModule::v_messageEOTExt")); + chain->serializerNode = sd_serializerBigENewTyped(c_resolve(c_getBase((c_object)chain->vgroup), "kernelModule::v_nodeExt")); + } else { + chain->xmsgType = NULL; + chain->messageType = NULL; + chain->serializer = NULL; + chain->serializerEOT = NULL; + chain->serializerNode = NULL; + chain->vgroup = NULL; + } + } + return chain; +} + +void +d_chainFree( + d_chain chain) +{ + assert(d_chainIsValid(chain)); + + d_objectFree(d_object(chain)); +} + +static c_bool +findAligner( + d_fellow fellow, + c_voidp args) +{ + c_ulong count; + c_bool fellowComplete = FALSE; + c_bool fellowMightKnowGroup = FALSE; + c_bool checkFurther = TRUE; + c_bool fellowHasGroup = FALSE; + struct chainRequestHelper* helper; + d_fellowAlignStatus status = D_ALIGN_FALSE; + d_networkAddress fellowAddress, oldAddress; + d_name fellowRole; + + c_ulong fellowMasterPriority = 0; + + helper = (struct chainRequestHelper*)args; + fellowAddress = d_fellowGetAddress(fellow); + + if (d_fellowGetCommunicationState(fellow) == D_COMMUNICATION_STATE_APPROVED) { + fellowRole = d_fellowGetRole(fellow); + + /* Find a fellow that has the same role as me and + * that is able to align data for the data for the group. + */ + if (fellowRole && strcmp(fellowRole, helper->role) == 0) { + fellowComplete = d_fellowIsCompleteForGroup(fellow, + helper->chain->request->partition, + helper->chain->request->topic, + helper->chain->request->durabilityKind); + status = d_fellowIsAlignerForGroup(fellow, + helper->chain->request->partition, + helper->chain->request->topic, + helper->chain->request->durabilityKind, + &fellowMasterPriority); + fellowHasGroup = d_fellowHasGroup(fellow, + helper->chain->request->partition, + helper->chain->request->topic, + helper->chain->request->durabilityKind); + fellowMightKnowGroup = (status == D_ALIGN_TRUE) || (status == D_ALIGN_UNKNOWN); + d_printTimedEvent(helper->durability, D_LEVEL_FINEST, + "Finding aligner: myRole='%s', fellow=%u, fellowRole='%s', fellowComplete=%d, " + "fellowHasGroup=%d, fellowMightKnowGroup=%d and fellowAlignStatus=%d.\n", + helper->role, fellowAddress->systemId, fellowRole, fellowComplete, + fellowHasGroup, fellowMightKnowGroup, status); + } else { + d_printTimedEvent(helper->durability, D_LEVEL_FINEST, + "Finding aligner: do nothing for fellow %u as its role (%s) is different than mine (%s).\n", + fellowAddress->systemId, fellowRole, helper->role); + d_networkAddressFree(fellowAddress); + return TRUE; + } + } else { + d_printTimedEvent(helper->durability, D_LEVEL_FINEST, + "Finding aligner: fellow %u not approved (yet).\n", + fellowAddress->systemId); + d_networkAddressFree(fellowAddress); + return TRUE; + } + + /* If the fellow can never know the group it is never a suitable candidate */ + if (!fellowMightKnowGroup) { + d_printTimedEvent(helper->durability, D_LEVEL_FINEST, + "Finding aligner: do nothing for fellow %u as it not an aligner.\n", fellowAddress->systemId); + d_networkAddressFree(fellowAddress); + return TRUE; + } + /* The fellow is never a suitable candidate aligner if it has masterPriority 0 and me too */ + else if (helper->nameSpace && + (d_nameSpaceGetMasterPriority(helper->nameSpace) == D_MINIMUM_MASTER_PRIORITY) && + (fellowMasterPriority == D_MINIMUM_MASTER_PRIORITY)) + { + d_printTimedEvent(helper->durability, D_LEVEL_FINEST, + "Finding aligner: do nothing for fellow %u as it has masterPriority 0 and me too.\n", + fellowAddress->systemId); + d_networkAddressFree(fellowAddress); + return TRUE; + } + /* Fellow with non-zero masterPriority that has the set complete + * might be a better candidate than the currently selected one */ + else if ((fellowComplete == TRUE) && (helper->fellow) && + (status != D_ALIGN_FALSE) && (fellowMasterPriority > D_MINIMUM_MASTER_PRIORITY)) + { + /* fellow complete and aligner and old complete fellow exists. */ + count = d_fellowRequestCountGet(helper->fellow); + + if (d_networkAddressEquals(fellowAddress, helper->master)) { + /* select the master. */ + d_printTimedEvent(helper->durability, D_LEVEL_FINEST, + "Finding aligner: select fellow %u as it is the master.\n", + fellowAddress->systemId); + d_tableFree(helper->chain->fellows); + helper->chain->fellows = d_tableNew(d_fellowCompare, d_chainFellowFree); + d_objectKeep(d_object(fellow)); + d_tableInsert(helper->chain->fellows, fellow); + helper->fellow = fellow; + d_fellowRequestAdd(fellow); + checkFurther = FALSE; + } else if (count > d_fellowRequestCountGet(fellow)) { + /* select the one with the least open requests. */ + oldAddress = d_fellowGetAddress(helper->fellow); + d_printTimedEvent(helper->durability, D_LEVEL_FINEST, + "Finding aligner: select fellow %u as it has %u open requests whereas current fellow %u has %u open requests.\n", + fellowAddress->systemId, d_fellowRequestCountGet(fellow), + oldAddress->systemId, count); + d_networkAddressFree(oldAddress); + d_tableFree(helper->chain->fellows); + helper->chain->fellows = d_tableNew(d_fellowCompare, d_chainFellowFree); + d_objectKeep(d_object(fellow)); + d_tableInsert(helper->chain->fellows, fellow); + helper->fellow = fellow; + d_fellowRequestAdd(fellow); + } else { + /* Do nothing here */ + d_printTimedEvent(helper->durability, D_LEVEL_FINEST, + "Finding aligner: do nothing for fellow %u as current selected fellow is better.\n", + fellowAddress->systemId); + } + } else if ((fellowComplete == TRUE) && (status != D_ALIGN_FALSE)) { + /* Fellow complete and no old complete fellow exists */ + d_tableFree(helper->chain->fellows); + helper->chain->fellows = d_tableNew(d_fellowCompare, d_chainFellowFree); + d_objectKeep(d_object(fellow)); + d_tableInsert(helper->chain->fellows, fellow); + helper->fellow = fellow; + d_fellowRequestAdd(fellow); + + if (d_networkAddressEquals(fellowAddress, helper->master)) { + checkFurther = FALSE; + d_printTimedEvent(helper->durability, D_LEVEL_FINEST, + "Finding aligner: selecting fellow %u and not checking further.\n", + fellowAddress->systemId); + } else { + d_printTimedEvent(helper->durability, D_LEVEL_FINEST, + "Finding aligner: selecting fellow %u and checking further.\n", + fellowAddress->systemId); + } + + /* Fellow is an aligner and might know the group, + * so the fellow as an alignment candidate. This also + * covers the case with masterPriority="0" */ + } else if ((fellowMightKnowGroup == TRUE) && (!helper->fellow)) { + /* No complete fellow found (yet). */ + d_objectKeep(d_object(fellow)); + d_fellowRequestAdd(fellow); + d_tableInsert(helper->chain->fellows, fellow); + d_printTimedEvent(helper->durability, D_LEVEL_FINEST, + "Finding aligner: adding fellow %u to list of candidates that is now %u long.\n", + fellowAddress->systemId, d_tableSize(helper->chain->fellows)); + /* Fellow is not suitable */ + } else { + /* Do nothing here */ + d_printTimedEvent(helper->durability, D_LEVEL_FINEST, + "Finding aligner: do nothing for fellow %u as it is not suitable.\n", + fellowAddress->systemId); + } + d_networkAddressFree(fellowAddress); + + return checkFurther; +} + +static d_resendAction +d_resendActionNew( + d_sampleChainListener listener, + const d_group group) +{ + d_resendAction action; + + /* Allocate resendAction */ + action = d_resendAction(os_malloc(C_SIZEOF(d_resendAction))); + if (action) { + /* No parent class, initialize the resend action */ + action->messages = NULL; + action->group = d_group(d_objectKeep(d_object(group))); + action->listener = listener; + } + return action; +} + +static void +d_resendActionFree( + d_resendAction action) +{ + if (action) { + v_message msg; + while ((msg = c_iterTakeFirst(action->messages)) != NULL) { + c_free(msg); + } + c_iterFree(action->messages); + if (action->group) { + d_groupFree(action->group); + } + os_free(action); + } + return; +} + +static void +d_chainBeadInjectEOT( + d_chainBead bead, + v_group group, + struct readBeadHelper *helper) +{ + v_resendScope resendScope = V_RESEND_NONE; /*TODO: resendScope not yet used here beyond this function */ + c_base base = c_getBase (group); + + assert(v_stateTest(v_nodeState(bead->message), L_ENDOFTRANSACTION)); + + d_trace(D_TRACE_GROUP, " Inject msg %p state=%u time=%"PA_PRItime" wrgid=%u:%u:%u EOT\n", + (void*)bead->message, bead->message->_parent.nodeState, + OS_TIMEW_PRINT(bead->message->writeTime), bead->message->writerGID.systemId, + bead->message->writerGID.localId, bead->message->writerGID.serial); + + if (c_baseMakeMemReservation(base, C_MM_RESERVATION_ZERO)) { + /* can use anu v_groupWrite* function as all do the same for EOT messages, + * maybe a special groupWriteEOT is desired. + */ + (void)v_groupWrite(group, bead->message, NULL, V_NETWORKID_ANY, &resendScope); + c_baseReleaseMemReservation(base, C_MM_RESERVATION_ZERO); + } else { + (void)d_shmAllocAssert(NULL, "Write EOT message failed."); + assert(FALSE); + } + helper->totalCount++; + helper->eotCount++; +} + +static void +d_chainBeadInjectSetMessageKeyFields( + v_message message, + v_group group, + c_value keyValues[32]) +{ + c_array messageKeyList = v_topicMessageKeyList(v_groupTopic(group)); + c_ulong nrOfKeys = c_arraySize(messageKeyList); + c_ulong i; + for (i = 0; i < nrOfKeys; i++) { + c_fieldAssign(messageKeyList[i], message, keyValues[i]); + } +} + +static v_writeResult +d_chainBeadInjectTryMessage( + d_durability durability, + v_message message, + v_group group, + v_entry entry) +{ + c_base const base = c_getBase(group); + v_resendScope resendScope; /*TODO: resendScope not yet used here beyond this function */ + char keystr[1024]; + v_writeResult writeResult; + + d_tracegroupGenMsgKeystr(keystr, sizeof (keystr), group, message); + d_trace(D_TRACE_GROUP, " Inject msg %p state=%u time=%"PA_PRItime" wrgid=%u:%u:%u key={%s}\n", + (void*)message, v_messageState(message), + OS_TIMEW_PRINT(message->writeTime), message->writerGID.systemId, + message->writerGID.localId, message->writerGID.serial, keystr); + + { + v_groupInstance instance = NULL; + resendScope = V_RESEND_NONE; + if (c_baseMakeMemReservation(base, C_MM_RESERVATION_ZERO)) { + if (entry) { + writeResult = v_groupWriteHistoricalToReader(group, message, entry); + } else if (v_gidIsNil(message->writerGID)) { + writeResult = v_groupWriteHistoricalData( + group, message, &instance, V_NETWORKID_ANY); + } else { + writeResult = v_groupWrite( + group, message, &instance, V_NETWORKID_ANY, &resendScope); + } + c_baseReleaseMemReservation(base, C_MM_RESERVATION_ZERO); + } else { + (void)d_shmAllocAssert(NULL, "Write bead message failed."); + writeResult = V_WRITE_OUT_OF_RESOURCES; + } + + if (writeResult != V_WRITE_SUCCESS) { + d_trace(D_TRACE_GROUP, " write failed with code %d\n", (int) writeResult); + } else { + d_trace(D_TRACE_GROUP, " bead written\n"); + } + if (instance) { + d_tracegroupInstance(instance, durability, " "); + c_free(instance); + } + } + return writeResult; +} + +static void +d_chainBeadInjectRegular( + d_chainBead bead, + v_group group, + struct readBeadHelper *helper) +{ + d_resendAction action = helper->action; + d_durability durability = d_adminGetDurability(d_listenerGetAdmin((d_listener)action->listener)); + v_message message; + v_message topicMsg = NULL; + + assert(!v_stateTest(v_nodeState(bead->message), L_ENDOFTRANSACTION)); + + /* Mark the message in the bead as required by the policy */ + switch (helper->mergePolicy) { + case D_MERGE_IGNORE: + case D_MERGE_MERGE: + case D_MERGE_DELETE: + break; + case D_MERGE_REPLACE: + v_stateSet(v_nodeState(bead->message), L_REPLACED); + break; + case D_MERGE_CATCHUP: + v_stateSet(v_nodeState(bead->message), L_MARK); + break; + } + + if (c_getType(bead->message) != v_kernelType(v_objectKernel(group), K_MESSAGE)) { + message = bead->message; + } else { + /* If the message is a mini-message without keys, temporarily + * replace it with a typed message that does include the + * keys. That way the bead becomes self- describing and so the + * receiving node can deduct its instance again. + */ + topicMsg = v_topicMessageNew(v_groupTopic(group)); + message = topicMsg; + if (message == NULL) { + d_durabilityTerminate(durability, FALSE); + return; + } else { + memcpy(message, bead->message, sizeof (*message)); + message->qos = c_keep(bead->message->qos); + d_chainBeadInjectSetMessageKeyFields(message, group, bead->keyValues); + } + } + + if (d_chainBeadInjectTryMessage(durability, message, group, helper->entry) != V_WRITE_SUCCESS) { + action->messages = c_iterAppend(action->messages, c_keep(message)); + } + c_free(topicMsg); + + helper->totalCount++; + if((v_stateTest(v_nodeState(bead->message), L_WRITE)) && + (v_stateTest(v_nodeState(bead->message), L_DISPOSED))) { + helper->writeDisposeCount++; + } else if(v_stateTest(v_nodeState(bead->message), L_WRITE)) { + helper->writeCount++; + } else if(v_stateTest(v_nodeState(bead->message), L_DISPOSED)) { + helper->disposeCount++; + } else if(v_stateTest(v_nodeState(bead->message), L_REGISTER)) { + helper->registerCount++; + } else if(v_stateTest(v_nodeState(bead->message), L_UNREGISTER)) { + helper->unregisterCount++; + } +} + +c_bool +d_chainBeadInject( + d_chainBead bead, + c_voidp args) +{ + struct readBeadHelper *helper = (struct readBeadHelper*)args; + v_group group = d_groupGetKernelGroup(helper->action->group); + d_threadAwake (helper->self); + if (v_stateTest(v_nodeState(bead->message), L_ENDOFTRANSACTION)) { + d_chainBeadInjectEOT (bead, group, helper); + } else { + d_chainBeadInjectRegular (bead, group, helper); + } + c_free(group); + return TRUE; +} + +static c_bool +d_resendRejected( + d_action action, + c_bool terminate) +{ + d_thread self = d_threadLookupSelf (); + d_resendAction resendData; + v_message resendMessage; + v_group group; + c_bool callAgain; + d_durability durability; + d_admin admin; + v_resendScope resendScope = V_RESEND_NONE; /* resendScope not yet used here beyond this function */ + + callAgain = TRUE; + resendData = d_resendAction(d_actionGetArgs(action)); + assert(c_iterLength(resendData->messages) != 0); + group = d_groupGetKernelGroup(resendData->group); + admin = d_listenerGetAdmin(d_listener(resendData->listener)); + durability = d_adminGetDurability(admin); + if(terminate == FALSE){ + v_writeResult writeResult = V_WRITE_SUCCESS; + resendMessage = c_iterTakeFirst(resendData->messages); + terminate = d_durabilityMustTerminate(durability); + while(resendMessage && (!terminate)){ + d_threadAwake (self); + writeResult = d_chainBeadInjectTryMessage(durability, resendMessage, group, NULL); + if (writeResult != V_WRITE_SUCCESS) { + resendData->messages = c_iterInsert(resendData->messages, resendMessage); + break; + } else { + c_free(resendMessage); + resendMessage = c_iterTakeFirst(resendData->messages); + } + terminate = d_durabilityMustTerminate(durability); + } + + if (resendMessage == NULL && (!terminate)) { + assert(c_iterLength(resendData->messages) == 0); + d_groupSetComplete(resendData->group, admin); + /*Update statistics*/ + updateGroupStatistics(admin, resendData->group); + d_sampleChainListenerReportGroup(resendData->listener, resendData->group); + d_resendActionFree(resendData); + callAgain = FALSE; + d_printTimedEvent(durability, D_LEVEL_FINEST, + "All data for group '%s.%s' has been resent. " + "Group is complete now.\n", + v_partitionName(v_groupPartition(group)), + v_topicName(v_groupTopic(group))); + } else if (!terminate) { + os_char buf[128] = { '\0' }; + (void)v_resendScopeImage (buf, sizeof(buf), resendScope); + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Resending data for group '%s.%s' failed with code %s. Resend scope (%s) " + "Trying again later.\n", + v_partitionName(v_groupPartition(group)), + v_topicName(v_groupTopic(group)), + v_writeResultString(writeResult), + buf); + } else { + /* Premature termination */ + callAgain = FALSE; + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Going to terminate while resending data for group '%s.%s'\n", + v_partitionName(v_groupPartition(group)), + v_topicName(v_groupTopic(group))); + } + c_free(group); + } else { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Terminating now, but alignment for group '%s.%s' " + "is not complete.\n", + v_partitionName(v_groupPartition(group)), + v_topicName(v_groupTopic(group))); + OS_REPORT(OS_WARNING, D_CONTEXT, 0, + "Terminating now, but alignment for group '%s.%s' " + "is not complete.\n", + v_partitionName(v_groupPartition(group)), + v_topicName(v_groupTopic(group))); + } + return callAgain; +} + +struct findMergeHelper { + d_chain chain; + d_mergeAction action; +}; + +static c_bool +findMergeAction( + d_mergeAction action, + struct findMergeHelper* helper) +{ + d_chain found; + + found = d_mergeActionGetChain(action, helper->chain); + + if(found){ + helper->action = action; + } + return !found; +} + +static d_mergeAction +d_sampleChainListenerGetMergeAction( + d_sampleChainListener listener, + d_chain chain) +{ + struct findMergeHelper helper; + + helper.chain = chain; + helper.action = NULL; + d_tableWalk(listener->mergeActions, findMergeAction, &helper); + return helper.action; +} + +static d_chain +d_sampleChainListenerFindChain( + d_sampleChainListener listener, + d_sampleChain sampleChain) +{ + d_chain chain, dummy; + d_sampleRequest request; + d_admin admin; + d_durability durability; + c_bool forMe; + d_networkAddress myAddr; + + assert(listener); + assert(sampleChain); + + admin = d_listenerGetAdmin(d_listener(listener)); + myAddr = d_adminGetMyAddress(admin); + forMe = d_sampleChainContainsAddressee(sampleChain, myAddr); + + if (forMe) { + /* Create a dummy chain for lookup in listener->chains. */ + request = d_sampleRequestNew(admin, sampleChain->partition, + sampleChain->topic, sampleChain->durabilityKind, OS_TIMEW_ZERO, FALSE, OS_TIMEW_ZERO, OS_TIMEW_ZERO); + d_sampleRequestSetSource(request, &sampleChain->source); + + dummy = d_chainNew(NULL, request); + + chain = d_tableFind(listener->chains, dummy); + + if (!chain) { + durability = d_adminGetDurability(admin); + + d_printTimedEvent(durability, D_LEVEL_WARNING, + "Could not find chain for message where group is: %s.%s, kind is %u and source is (%u,%u,%u)\n", + sampleChain->partition, sampleChain->topic, sampleChain->durabilityKind, + sampleChain->source.systemId, sampleChain->source.localId, sampleChain->source.lifecycleId); + } + /* request is also freed by d_chainFree */ + d_chainFree(dummy); + } else { + chain = NULL; + } + d_networkAddressFree(myAddr); + + return chain; +} + +static d_chainBead +d_chainBeadNew( + d_fellow sender, + v_message message, + d_chain chain) +{ + d_chainBead chainBead = NULL; + c_array messageKeyList; + c_ulong i; + + assert(message); + + /* Allocate chainBead object */ + chainBead = d_chainBead(os_malloc(C_SIZEOF(d_chainBead))); + if (chainBead) { + /* No parent class, initialize chainBead */ + /* Only resolve the keys for non-EOTs because EOTs have no key fields + */ + if (!v_messageStateTest(message, L_ENDOFTRANSACTION)) { + memset(chainBead->keyValues, 0, sizeof(chainBead->keyValues)); + messageKeyList = v_topicMessageKeyList(v_groupTopic(chain->vgroup)); + chainBead->nrOfKeys = c_arraySize(messageKeyList); + if (chainBead->nrOfKeys > 32) { + OS_REPORT(OS_ERROR, + "d_sampleChainListener::d_chainBeadNew",0, + "too many keys %d exceeds limit of 32", + chainBead->nrOfKeys); + } else { + for (i=0;inrOfKeys;i++) { + chainBead->keyValues[i] = c_fieldValue(messageKeyList[i], message); + } + } + } else { + /* EOTs do not have any keys */ + chainBead->nrOfKeys = 0; + } + /* In case of an unregister message, store the instance and an + * untyped sample. + */ + if (v_messageStateTest(message, L_UNREGISTER)) { + chainBead->message = v_groupCreateUntypedInvalidMessage( + v_kernel(v_object(chain->vgroup)->kernel), message); + assert(c_refCount(chainBead->message) == 1); + } else { + chainBead->message = c_keep(message); + } + chainBead->message->allocTime = os_timeEGet(); + /* all senders must be in chain->fellows, so no need to manipulate th + * refcount nor a cleanup function + */ + chainBead->senders = d_tableNew(d_fellowCompare, 0); + d_tableInsert(chainBead->senders, sender); + chainBead->refCount = 1; + } + return chainBead; +} + +static d_chainLink +d_chainLinkNew( + d_networkAddress sender, + c_ulong sampleCount, + d_admin admin) +{ + d_chainLink link; + + /* Allocate chainLink object */ + link = d_chainLink(os_malloc(C_SIZEOF(d_chainLink))); + if (link) { + /* No parent class, initialize chainLink */ + link->sender = d_networkAddressNew( + sender->systemId, + sender->localId, + sender->lifecycleId); + link->sampleCount = sampleCount; + link->admin = admin; + } + return link; +} + +struct takeWaitingChainHelper +{ + d_chain search; + d_chain result; +}; + +static void +d_takeWaitingChainWalk ( + void* o, + c_iterActionArg userData) +{ + d_chain chain; + struct takeWaitingChainHelper* helper; + + chain = d_chain(o); + helper = (struct takeWaitingChainHelper*)userData; + + if (!helper->result) { + if (!d_chainCompare (chain, helper->search)) { + helper->result = chain; + } + } +} + +static d_chain +d_sampleChainListenerRemoveChain( + d_sampleChainListener listener, + d_chain chain) +{ + d_durability durability; + d_admin admin; + d_publisher publisher; + d_networkAddress addressee; + d_chain result; + struct takeWaitingChainHelper walkData; + + assert (listener); + assert (listener->chains); + assert (chain); + + admin = d_listenerGetAdmin (d_listener(listener)); + durability = d_adminGetDurability (admin); + publisher = d_adminGetPublisher(admin); + + /* Remove (complete) chain from listener */ + result = d_tableRemove (listener->chains, chain); + + /* Look for other chain containing same group in chainsWaiting list */ + walkData.search = chain; + walkData.result = NULL; + c_iterWalk (listener->chainsWaiting, d_takeWaitingChainWalk, &walkData); + + if (walkData.result) { + c_iterTake (listener->chainsWaiting, walkData.result); + + /* Insert chain in chains list */ + d_tableInsert (listener->chains, walkData.result); + + /* Publish request */ + addressee = d_messageGetAddressee (d_message(chain->request)); + d_publisherSampleRequestWrite(publisher, chain->request, addressee); + d_printTimedEvent(durability, D_LEVEL_FINE, + "Write delayed samplerequest for group %s.%s to fellow %u using source (%u,%u,%u)\n", + chain->request->partition, + chain->request->topic, + addressee->systemId, + chain->request->source.systemId, + chain->request->source.localId, + chain->request->source.lifecycleId); + } + + return result; +} + +static void +d_sampleChainListenerAction( + d_listener listener, + d_message message) +{ + d_sampleChain sampleChain; + d_sampleChainListener sampleChainListener; + d_chain chain; + d_durability durability; + d_admin admin; + c_bool complete, proceed; + d_chainBead bead; + d_chainBead inserted; + d_chainLink link; + v_message vmessage; + d_fellow fellow, dummy; + d_networkAddress sender; + d_networkAddress myAddr; + d_subscriber subscriber; + d_store store; + d_group group; + c_bool equal; + d_storeResult result; + + admin = d_listenerGetAdmin(listener); + durability = d_adminGetDurability(admin); + sampleChain = d_sampleChain(message); + sampleChainListener = d_sampleChainListener(listener); + chain = d_sampleChainListenerFindChain(sampleChainListener, sampleChain); + + sender = d_networkAddressNew(message->senderAddress.systemId, + message->senderAddress.localId, + message->senderAddress.lifecycleId); + + if (chain) { + dummy = d_fellowNew(sender, D_STATE_COMPLETE, FALSE); + fellow = d_tableFind(chain->fellows, dummy); + if (!fellow) { + chain = NULL; + } + d_fellowFree(dummy); + } + + /* Chain might already have been removed, because this service assumed the + * sender to be dead and chose a new fellow to align with. + */ + if (chain) { + assert(d_objectIsValid(d_object(chain), D_CHAIN) == TRUE); + + proceed = d_shmAllocAllowed(); + + if(proceed){ + /* Keep chain to prevent clean-up during phase the listener is + * unlocked during deserialization of the sample. + */ + d_chainKeep(chain); + + switch(sampleChain->msgBody._d){ + case BEAD: + d_listenerUnlock(listener); + { + v_node msgNode; + msgNode = (v_node) sd_serializerDeserialize(chain->serializerNode, + (sd_serializedData)(sampleChain->msgBody._u.bead.value)); + if (msgNode == NULL) { + vmessage = NULL; + } else { + v_state msgState = msgNode->nodeState; + c_free(msgNode); + if (v_stateTest(msgState, L_ENDOFTRANSACTION)) { + v_messageEOTExt xmsg_eot; + xmsg_eot = (v_messageEOTExt )sd_serializerDeserialize( + chain->serializerEOT, + (sd_serializedData)(sampleChain->msgBody._u.bead.value)); + vmessage = xmsg_eot ? v_messageEOTExtConvertFromExtType (xmsg_eot) : NULL; + } else { + v_messageExt xmsg; + xmsg = (v_messageExt) sd_serializerDeserialize( + chain->serializer, + (sd_serializedData)(sampleChain->msgBody._u.bead.value)); + vmessage = xmsg ? v_messageExtConvertFromExtType (chain->messageType, xmsg) : NULL; + } + } + } + d_listenerLock(listener); + proceed = d_shmAllocAssert(vmessage, "Deserialization of received sample failed."); + assert(!proceed || vmessage != NULL); + if(proceed == TRUE){ + /* Do not insert implicit unregistrations and disposes about yourself that are + * aligned by fellows. Typically, this situation occurs when the fellow's splice + * daemon unregisters (and/or disposes) writers on a node that is disconnected. + * This reflects the state that the fellow THINKS the writers on my node are not + * alive anymore. When connection is restored, the conclusion of the fellow that + * my writer is not alive should NOT be forwarded to me because this implicit + * conclusion was wrong apparently. + */ + myAddr = d_adminGetMyAddress(admin); + if ( ! ( v_messageStateTest(vmessage, L_IMPLICIT) && + (vmessage->writerGID.systemId == myAddr->systemId) ) ) { + /* the message is not implicit or is not supposedly written by + * myself so can be inserted safely + */ + bead = d_chainBeadNew(fellow, vmessage, chain); + inserted = d_tableInsert(chain->beads, bead); + /* Duplicates are not inserted + * A message is considered a duplicate if the writer GID and the + * source timestamp are equal to the ones in the other message. + */ + if (inserted != NULL) { + /* Bead already present, so number of expected samples must + * be lowered. + */ + chain->samplesExpect--; + + if (d_tableInsert(inserted->senders, fellow) == NULL) { + inserted->refCount++; + } + assert(d_tableSize(inserted->senders) == inserted->refCount); + d_chainBeadFree(bead); + } else { + chain->receivedSize += sd_serializedDataGetTotalSize((sd_serializedData)(sampleChain->msgBody._u.bead.value)); + } + } else { + /* The message was an implicit unregister or dispose message with + * a writerGID from myself, so it is a local conclusion by the + * fellow about my presence. No need to add it to the bead, I know + * best whether I am alive or not. + */ + chain->samplesExpect--; + } + d_networkAddressFree(myAddr); + c_free(vmessage); + } + break; + case LINK: + if(sampleChain->msgBody._u.link.completeness == D_GROUP_KNOWLEDGE_UNDEFINED){ + d_printTimedEvent(durability, D_LEVEL_WARNING, + "Received link from fellow %u for group '%s.%s' where " + "it informs me it will not align me. This means that " + "our data model or state is incompatible. I need to " + "disconnect the fellow and discover it again.\n", + sender->systemId, + chain->request->partition, + chain->request->topic); + dummy = d_adminRemoveFellow(admin, fellow, FALSE); + + if(dummy){ + d_fellowFree(dummy); + } + } else { + /* FIXME: should validate things (that e.g., samplesExpect + nrSamples is defined) */ + equal = FALSE; + group = d_adminGetLocalGroup(admin, + chain->request->partition, + chain->request->topic, + chain->request->durabilityKind); + + if (sampleChain->msgBody._u.link.nrSamples == D_GROUP_IS_EQUAL) { + /* Remote group matches local group, no samples expected */ + equal = TRUE; + } else { + chain->samplesExpect += (c_long) sampleChain->msgBody._u.link.nrSamples; + } + + link = d_chainLinkNew(sender, sampleChain->msgBody._u.link.nrSamples, admin); + d_tableInsert(chain->links, link); + d_printTimedEvent(durability, D_LEVEL_FINE, + "Received %slink from fellow %u for group %s.%s containing %u samples. #links == %u\n", + equal ? "equal " : "", + sender->systemId, + chain->request->partition, + chain->request->topic, + (link->sampleCount == D_GROUP_IS_EQUAL) ? 0 : link->sampleCount, + d_tableSize(chain->links)); + + if (d_groupIsStoreMessagesLoaded(group) == TRUE) { + subscriber = d_adminGetSubscriber(admin); + store = d_subscriberGetPersistentStore(subscriber); + result = d_storeMessagesLoadFlush(store, group, equal); + if (result == D_STORE_RESULT_OK) { + d_groupSetStoreMessagesLoaded(group, FALSE); + } else if (equal == TRUE) { + OS_REPORT(OS_ERROR, OS_FUNCTION, result, + "Failed to inject stored messages for group %s.%s\n", + chain->request->partition, + chain->request->topic); + assert(FALSE); + } else { + OS_REPORT(OS_WARNING, OS_FUNCTION, result, + "Failed to reject stored messages for group %s.%s\n", + chain->request->partition, + chain->request->topic); + } + } + } + break; + default: + OS_REPORT(OS_ERROR, "d_sampleChainListenerAction", 0, + "Illegal message discriminator value (%d) detected.", + sampleChain->msgBody._d); + assert(FALSE); + break; + } + } + complete = d_sampleChainListenerCheckChainComplete(sampleChainListener, chain); + d_chainFree(chain); /* Mirror the d_chainKeep earlier on */ + + if (complete == TRUE) { + chain = d_sampleChainListenerRemoveChain (sampleChainListener, chain); + + if(chain){ + assert(d_objectIsValid(d_object(chain), D_CHAIN) == TRUE); + d_chainFree(chain); + } + } + } + d_networkAddressFree(sender); + return; +} + +static void +d_sampleChainListenerDeinit( + d_sampleChainListener listener) +{ + d_admin admin; + d_chain chain; + + assert(d_sampleChainListenerIsValid(listener)); + + /* Stop the listener */ + d_sampleChainListenerStop(listener); + /* Deallocate memory associated with the listener */ + if (listener->fellowListener) { + admin = d_listenerGetAdmin(d_listener(listener)); + d_adminRemoveListener(admin, listener->fellowListener); + d_eventListenerFree(listener->fellowListener); + listener->fellowListener = NULL; + } + if (listener->chains) { + d_tableFree(listener->chains); + listener->chains = NULL; + } + if (listener->chainsWaiting) { + chain = d_chain(c_iterTakeFirst(listener->chainsWaiting)); + while(chain){ + d_chainFree(chain); + chain = d_chain(c_iterTakeFirst(listener->chainsWaiting)); + } + c_iterFree(listener->chainsWaiting); + } + if (listener->unfulfilledChains) { + chain = d_chain(c_iterTakeFirst(listener->unfulfilledChains)); + while(chain){ + d_chainFree(chain); + chain = d_chain(c_iterTakeFirst(listener->unfulfilledChains)); + } + c_iterFree(listener->unfulfilledChains); + } + if (listener->resendQueue) { + d_actionQueueFree(listener->resendQueue); + listener->resendQueue = NULL; + } + if (listener->mergeActions) { + d_tableFree(listener->mergeActions); + listener->mergeActions = NULL; + } + /* Call super-deinit */ + d_readerListenerDeinit(d_readerListener(listener)); +} + +static void +d_sampleChainListenerInit( + d_sampleChainListener listener, + d_subscriber subscriber) +{ + os_duration sleepTime = OS_DURATION_INIT(1,0); + d_admin admin; + d_durability durability; + d_configuration config; + + /* Do not assert the listener because the initialization + * of the listener has not yet completed + */ + + assert(d_subscriberIsValid(subscriber)); + + admin = d_subscriberGetAdmin(subscriber); + assert(d_adminIsValid(admin)); + durability = d_adminGetDurability(admin); + assert(d_durabilityIsValid(durability)); + config = d_durabilityGetConfiguration(durability); + assert(d_configurationIsValid(config)); + /* Call super-init */ + d_readerListenerInit(d_readerListener(listener), + D_SAMPLE_CHAIN_LISTENER, + d_sampleChainListenerAction, + subscriber, + D_SAMPLE_CHAIN_TOPIC_NAME, + D_SAMPLE_CHAIN_TOP_NAME, + V_RELIABILITY_RELIABLE, + V_HISTORY_KEEPALL, + V_LENGTH_UNLIMITED, + config->aligneeScheduling, + (d_objectDeinitFunc)d_sampleChainListenerDeinit); + /* Initialize the sampleChainListener */ + listener->chains = d_tableNew(d_chainCompare, d_chainFree); + assert(listener->chains); + listener->chainsWaiting = c_iterNew(NULL); + assert (listener->chainsWaiting); + listener->id = 0; + listener->fellowListener = NULL; + listener->resendQueue = d_actionQueueNew("resendQueue",sleepTime, config->aligneeScheduling); + assert(listener->resendQueue); + listener->unfulfilledChains = c_iterNew(NULL); + assert(listener->unfulfilledChains); + listener->mergeActions = d_tableNew(d_mergeActionCompare, d_mergeActionFree); + assert(listener->mergeActions); +} + + +d_sampleChainListener +d_sampleChainListenerNew( + d_subscriber subscriber) +{ + d_sampleChainListener listener; + + assert(d_subscriberIsValid(subscriber)); + + /* Allocate sampleChainListener object */ + listener = d_sampleChainListener(os_malloc(C_SIZEOF(d_sampleChainListener))); + if (listener) { + /* Initialize the sampleChainListener */ + d_sampleChainListenerInit(listener, subscriber); + } + return listener; +} + + +void +d_sampleChainListenerFree( + d_sampleChainListener listener) +{ + assert(d_sampleChainListenerIsValid(listener)); + + d_objectFree(d_object(listener)); +} + +static c_bool +d_sampleChainListenerCleanupBeads( + d_chainBead bead, + c_voidp userData) +{ + struct chainCleanup* data = userData; + assert(d_tableSize(bead->senders) == bead->refCount); + if (d_tableRemove(bead->senders, data->fellow) != NULL) { + assert(bead->refCount > 0); + if (--bead->refCount == 0) { + data->beadsToRemove = c_iterInsert(data->beadsToRemove, bead); + } else { + data->dupsFromFellowCount++; + } + } + return TRUE; +} + +static c_bool +d_sampleChainListenerCleanupRequests( + d_chain chain, + c_voidp userData) +{ + d_chainLink link, link2; + d_chainBead bead; + struct chainCleanup* data; + d_durability durability; + c_bool complete; + d_fellow found; + + data = (struct chainCleanup*)userData; + durability = d_adminGetDurability(data->admin); + found = d_tableRemove(chain->fellows, data->fellow); + + if(found){ + if(d_tableSize(chain->fellows) == 0){ + data->toRemove = c_iterInsert(data->toRemove, chain); + } else { + d_networkAddress fellowAddress = d_fellowGetAddress(data->fellow); + link = d_chainLinkNew(fellowAddress, 0, data->admin); + d_networkAddressFree(fellowAddress); + link2 = d_tableRemove(chain->links, link); + if (link->sender) { + d_networkAddressFree(link->sender); + link->sender = NULL; + } + os_free(link); + + if(link2){ + chain->samplesExpect -= (c_long) link2->sampleCount; + + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Fellow %u removed for group '%s.%s', number of expected " + "decreased with %lu\n", + found->address->systemId, chain->request->partition, chain->request->topic, link2->sampleCount); + + d_chainLinkFree(link2); + } + data->beadsToRemove = c_iterNew(NULL); + data->dupsFromFellowCount = 0; + d_tableWalk(chain->beads, d_sampleChainListenerCleanupBeads, data); + + chain->samplesExpect += data->dupsFromFellowCount; + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Fellow %u removed for group '%s.%s', %d duplicate samples were received already, number of expected " + "increased to %u\n", + found->address->systemId, chain->request->partition, chain->request->topic, data->dupsFromFellowCount, chain->samplesExpect); + + bead = c_iterTakeFirst(data->beadsToRemove); + while(bead){ + bead = d_tableRemove(chain->beads, bead); + + if(bead){ + d_chainBeadFree(bead); + } + bead = c_iterTakeFirst(data->beadsToRemove); + } + c_iterFree(data->beadsToRemove); + complete = d_sampleChainListenerCheckChainComplete(data->listener, chain); + + if(complete == TRUE) { + data->toRemove = c_iterInsert(data->toRemove, chain); + } else { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "%u fellows left to answer request for group %s.%s.\n", + d_tableSize(chain->fellows), chain->request->partition, + chain->request->topic); + } + } + d_chainFellowFree(found); + } else { + /* This request has not been sent to the dead fellow.*/ + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Request is not meant for fellow. %u fellows left to answer " \ + "request for group %s.%s.\n", + d_tableSize(chain->fellows), chain->request->partition, + chain->request->topic); + } + return TRUE; +} + +static c_bool +d_sampleChainListenerNotifyFellowRemoved( + c_ulong event, + d_fellow fellow, + d_nameSpace ns, + d_group group, + c_voidp eventUserData, + c_voidp userData) +{ + d_durability durability; + struct chainCleanup data; + d_chain chain; + d_group dgroup; + d_sampleChainListener listener; + d_subscriber subscriber; + d_groupLocalListener glListener; + c_iter requests; + d_sampleRequest sampleRequest; + d_readerRequest readerRequest; + d_networkAddress source; + d_mergeAction mergeAction; + c_ulong chainCount; + + OS_UNUSED_ARG(ns); + OS_UNUSED_ARG(eventUserData); + OS_UNUSED_ARG(event); + OS_UNUSED_ARG(group); + listener = d_sampleChainListener(userData); + + assert(d_sampleChainListenerIsValid(listener)); + + if(listener){ + data.admin = d_listenerGetAdmin(d_listener(listener)); + data.fellow = fellow; + data.listener = listener; + data.toRemove = c_iterNew(NULL); + durability = d_adminGetDurability(data.admin); + + d_printTimedEvent(durability, D_LEVEL_FINE, + "Fellow removed, checking %d requests.\n", d_tableSize(listener->chains)); + + d_listenerLock(d_listener(listener)); + d_tableWalk(listener->chains, d_sampleChainListenerCleanupRequests, &data); + chain = c_iterTakeFirst(data.toRemove); + requests = c_iterNew(NULL); + + while(chain){ + /* Chain might be part of a mergeAction, if so; skip it*/ + mergeAction = d_sampleChainListenerGetMergeAction(listener, chain); + if (mergeAction) { + d_printTimedEvent(durability, D_LEVEL_FINER, + "Removing chain from merge request for group %s.%s\n", + chain->request->partition, chain->request->topic); + d_mergeActionRemoveChain(mergeAction, chain); + chainCount = d_mergeActionGetChainCount(mergeAction); + + if (chainCount == 0) { + d_conflictResolver conflictResolver = data.admin->conflictResolver; + + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Removing merge action.\n"); + d_tableRemove(listener->mergeActions, mergeAction); + /* Indicate that the mergeAction is completed */ + if (conflictResolver) { + d_conflictResolverResetConflictInProgress(conflictResolver, mergeAction->conflict); + } + d_mergeActionFree(mergeAction); + } + + /* Remove chain from chains list */ + if(d_objectIsValid(d_object(chain), D_CHAIN) == TRUE){ + chain = d_sampleChainListenerRemoveChain(listener, chain); + } + + } else { + /* Chain might be freed. This is a valid situation, because the + * fellow that was assumed dead by this service might still send + * some data after all. The sending of data can lead to the + * completeness of a chain. The chain will freed after the + * injection of its data. + * + * The chain is freed between the d_sampleChainListenerCleanupRequests + * and this point. Because this function has the listener lock, it + * is safe to check whether the chain has been freed. + */ + if(d_objectIsValid(d_object(chain), D_CHAIN) == TRUE){ + chain = d_sampleChainListenerRemoveChain(listener, chain); + } + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Finding new aligner for group %s.%s\n", + chain->request->partition, chain->request->topic); + + /* Create a copy of the request. */ + requests = c_iterInsert(requests, d_sampleRequestCopy(chain->request, FALSE)); + + if(d_sampleRequestSpecificReader(chain->request)){ + source = d_networkAddressNew(chain->request->source.systemId, + chain->request->source.localId, + chain->request->source.lifecycleId); + readerRequest = d_adminGetReaderRequest(data.admin, source); + d_networkAddressFree(source); + d_readerRequestRemoveChain(readerRequest, chain); + d_readerRequestFree(readerRequest); + } + } + d_chainFree(chain); + chain = c_iterTakeFirst(data.toRemove); + } + c_iterFree(data.toRemove); + d_listenerUnlock(d_listener(listener)); + + subscriber = d_adminGetSubscriber(data.admin); + glListener = d_subscriberGetGroupLocalListener(subscriber); + + for (sampleRequest = d_sampleRequest(c_iterTakeFirst(requests)); + sampleRequest != NULL; + sampleRequest = d_sampleRequest(c_iterTakeFirst(requests))) + { + dgroup = d_adminGetLocalGroup(data.admin, + sampleRequest->partition, + sampleRequest->topic, + sampleRequest->durabilityKind); + + if(d_sampleRequestSpecificReader(sampleRequest)){ + source = d_networkAddressNew( + sampleRequest->source.systemId, + sampleRequest->source.localId, + sampleRequest->source.lifecycleId); + readerRequest = d_adminGetReaderRequest(data.admin, source); + d_networkAddressFree(source); + d_readerRequestAddGroup(readerRequest, dgroup); + d_groupLocalListenerHandleAlignment(glListener, dgroup, readerRequest); + d_readerRequestFree(readerRequest); + } else { + d_groupLocalListenerHandleAlignment(glListener, dgroup, NULL); + } + d_sampleRequestFree(sampleRequest); + } + c_iterFree(requests); + + d_printTimedEvent(durability, D_LEVEL_FINER, "%d requests left.\n", + d_tableSize(listener->chains)); + + } + return TRUE; +} + + +c_bool +d_sampleChainListenerStart( + d_sampleChainListener listener) +{ + d_admin admin; + c_bool result = FALSE; + + assert(d_sampleChainListenerIsValid(listener)); + + if(listener){ + if(d_listenerIsAttached(d_listener(listener)) == FALSE){ + admin = d_listenerGetAdmin(d_listener(listener)); + listener->fellowListener = d_eventListenerNew( + D_FELLOW_REMOVED, + d_sampleChainListenerNotifyFellowRemoved, + listener); + d_adminAddListener(admin, listener->fellowListener); + result = d_readerListenerStart(d_readerListener(listener)); + } + } + return result; +} + + +c_bool +d_sampleChainListenerStop( + d_sampleChainListener listener) +{ + d_admin admin; + c_bool result = FALSE; + + assert(d_sampleChainListenerIsValid(listener)); + + if (listener) { + if (d_listenerIsAttached(d_listener(listener)) == TRUE) { + admin = d_listenerGetAdmin(d_listener(listener)); + d_adminRemoveListener(admin, listener->fellowListener); + d_eventListenerFree(listener->fellowListener); + listener->fellowListener = NULL; + result = d_readerListenerStop(d_readerListener(listener)); + } + } + return result; +} + + +static void +d_sampleChainListenerAddChain( + d_sampleChainListener listener, + d_chain chain, + d_networkAddress addressee) +{ + d_admin admin; + d_durability durability; + d_publisher publisher; + + admin = d_listenerGetAdmin(d_listener(listener)); + durability = d_adminGetDurability (admin); + publisher = d_adminGetPublisher(admin); + + assert (listener); + assert (listener->chains); + + /* Set addressee */ + d_messageSetAddressee(d_message(chain->request), addressee); + /* Insert chain. Note that the chain is NOT refCounted. */ + (void)d_tableInsert(listener->chains, chain); + /* The chain is new, send the sampleRequest */ + d_publisherSampleRequestWrite(publisher, chain->request, addressee); + if (chain->request->filter) { + d_printTimedEvent(durability, D_LEVEL_FINE, + "Write samplerequest for group %s.%s to fellow %u using source (%u,%u,%u) and filter expression '%s'\n", + chain->request->partition, + chain->request->topic, + d_message(chain->request)->addressee.systemId, + chain->request->source.systemId, + chain->request->source.localId, + chain->request->source.lifecycleId, + chain->request->filter); + } else { + d_printTimedEvent(durability, D_LEVEL_FINE, + "Write samplerequest for group %s.%s to fellow %u using source (%u,%u,%u)\n", + chain->request->partition, + chain->request->topic, + d_message(chain->request)->addressee.systemId, + chain->request->source.systemId, + chain->request->source.localId, + chain->request->source.lifecycleId); + } +} + + +void +d_sampleChainListenerReportGroup( + d_sampleChainListener listener, + d_group group) +{ + d_admin admin; + + admin = d_listenerGetAdmin(d_listener(listener)); + d_adminReportGroup(admin, group); +} + +void +d_sampleChainListenerTryFulfillChains( + d_sampleChainListener listener, + d_group group) +{ + c_iter copy, leftOver; + d_chain chain; + d_admin admin; + d_durability durability; + c_ulong length; + d_topic topic; + d_partition partition; + d_thread self = d_threadLookupSelf (); + + assert(d_sampleChainListenerIsValid(listener)); + + d_threadAwake(self); + if(listener){ + d_listenerLock(d_listener(listener)); + + + /* Check of length must be within lock */ + length = c_iterLength(listener->unfulfilledChains); + + if(length > 0){ + admin = d_listenerGetAdmin(d_listener(listener)); + durability = d_adminGetDurability(admin); + copy = listener->unfulfilledChains; + + d_printTimedEvent(durability, D_LEVEL_FINER, + "Trying to find aligner again for %d groups.\n", + length); + + listener->unfulfilledChains = c_iterNew(NULL); + + if(group){ + partition = d_groupGetPartition(group); + topic = d_groupGetTopic(group); + } else { + partition = NULL; + topic = NULL; + } + d_listenerUnlock(d_listener(listener)); + leftOver = c_iterNew(NULL); + chain = d_chain(c_iterTakeFirst(copy)); + + while(chain){ + if(group){ + if ((strcmp(partition, chain->request->partition) == 0)&& + (strcmp(topic, chain->request->topic) == 0)) + { + d_sampleChainListenerInsertRequest(listener, chain, FALSE); + } else { + leftOver = c_iterInsert(leftOver, chain); + } + } else { + d_sampleChainListenerInsertRequest(listener, chain, FALSE); + } + chain = d_chain(c_iterTakeFirst(copy)); + } + + if(group){ + os_free(partition); + os_free(topic); + } + + /* Do NOT free chains themselves, this is handled by the insertRequest function. */ + c_iterFree(copy); + + d_listenerLock(d_listener(listener)); + chain = d_chain(c_iterTakeFirst(leftOver)); + + while(chain){ + listener->unfulfilledChains = c_iterInsert(listener->unfulfilledChains, chain); + chain = d_chain(c_iterTakeFirst(leftOver)); + } + d_listenerUnlock(d_listener(listener)); + c_iterFree(leftOver); + if (c_iterLength(listener->unfulfilledChains) > 0) { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Still waiting for alignment of %d groups.\n", + c_iterLength(listener->unfulfilledChains)); + } else { + d_printTimedEvent(durability, D_LEVEL_FINER, "All groups are being alignment.\n"); + } + } else { + d_listenerUnlock(d_listener(listener)); + } + } + return; +} + + +static void +requestGroupFromMasterIfUnknown( + d_admin admin, + d_nameSpace nameSpace, + d_partition partition, + d_topic topic, + d_durabilityKind kind) +{ + d_durability durability; + d_publisher publisher; + d_networkAddress master; + d_fellow fellow; + d_group fellowGroup; + d_groupsRequest request; + + assert(d_objectIsValid(d_object(nameSpace), D_NAMESPACE)); + assert(d_objectIsValid(d_object(admin), D_ADMIN)); + + if(admin && nameSpace && partition && topic){ + master = d_nameSpaceGetMaster(nameSpace); + + if(!d_networkAddressIsUnaddressed(master)){ + fellow = d_adminGetFellow(admin, master); + + if(fellow){ + fellowGroup = d_fellowGetGroup(fellow, partition, topic, kind); + + if(fellowGroup){ + /* Group already known; no need to do anything */ + d_groupFree(fellowGroup); + } else { + request = d_groupsRequestNew(admin, partition, topic); + durability = d_adminGetDurability(admin); + publisher = d_adminGetPublisher(admin); + + d_messageSetAddressee(d_message(request), master); + d_publisherGroupsRequestWrite(publisher, request, master); + + d_printTimedEvent(durability, D_LEVEL_FINE, + "Requested info for group %s.%s from master fellow '%u'.\n", + partition, topic, master->systemId); + d_groupsRequestFree(request); + } + d_fellowFree(fellow); + } + } + d_networkAddressFree(master); + } else { + OS_REPORT(OS_ERROR, "durability::requestGroupFromMasterIfUnknown", 0, + "Precondition not met: admin=0x%"PA_PRIxADDR", nameSpace=0x%"PA_PRIxADDR", partition=0x%"PA_PRIxADDR", topic=0x%"PA_PRIxADDR"", + (os_address)admin, (os_address)nameSpace, (os_address)partition, (os_address)topic); + assert(FALSE); + } + return; +} + +struct collectGroupData { + d_sampleRequest request; + c_bool checkTimeRange; + c_bool isBuiltinDCPSTopicGroup; + c_iter list; +}; + +static c_bool +collectGroupsAddList( + c_object object, + v_groupInstance instance, + v_groupFlushType flushType, + c_voidp userData) +{ + v_message message; + v_registration registration; + struct collectGroupData *data; + c_bool process; + + OS_UNUSED_ARG(instance); + + data = (struct collectGroupData*)userData; + process = TRUE; + +#define CHECK_TIME_RANGE(writeTime, beginTime, endTime) \ + (os_timeWCompare(writeTime, endTime) == OS_MORE) ? FALSE : \ + (data->request->withTimeRange == TRUE) && (os_timeWCompare(writeTime, beginTime) == OS_LESS) ? FALSE : \ + TRUE + + switch(flushType){ + case V_GROUP_FLUSH_REGISTRATION: + registration = (v_registration)object; + if (data->isBuiltinDCPSTopicGroup) { + /* Don't process registrations for DCPSTopic as this would introduce a scalability issue since + * there is always an alive writer per federation. If these registrations would be aligned there + * would be n registrations stored per builtin topic instance where n is the number of + * federations in a system. + * The only condition for aligning a registration is when there are multiple writers + * for the same instance. Therefore this is not an issue for other (builtin) topics. + */ + process = FALSE; + } else if (data->checkTimeRange) { + process = CHECK_TIME_RANGE(registration->writeTime, c_timeToTimeW(data->request->beginTime), c_timeToTimeW(data->request->endTime)); + } + break; + case V_GROUP_FLUSH_UNREGISTRATION: + registration = (v_registration)object; + if (data->checkTimeRange) { + process = CHECK_TIME_RANGE(registration->writeTime, c_timeToTimeW(data->request->beginTime), c_timeToTimeW(data->request->endTime)); + } + break; + case V_GROUP_FLUSH_MESSAGE: + message = (v_message)object; + if (data->checkTimeRange) { + process = CHECK_TIME_RANGE(message->writeTime, c_timeToTimeW(data->request->beginTime), c_timeToTimeW(data->request->endTime)); + } + if((process == TRUE) && (data->isBuiltinDCPSTopicGroup == TRUE)){ + v_topicInfoTemplate tmpl = (v_topicInfoTemplate)message; + if (d_inBuiltinTopicNames(tmpl->userData.name, strlen(tmpl->userData.name))) { + /* Don't process messages for DCPSTopic which advertise BuiltinTopics */ + process = FALSE; + } + } + break; + case V_GROUP_FLUSH_TRANSACTION: + message = (v_message)object; + if (data->checkTimeRange) { + process = CHECK_TIME_RANGE(message->writeTime, c_timeToTimeW(data->request->beginTime), c_timeToTimeW(data->request->endTime)); + } + break; + } +#undef CHECK_TIME_RANGE + if (process == TRUE) { + struct v_groupFlushData *flushData = os_malloc(sizeof(struct v_groupFlushData)); + flushData->object = c_keep(object); + flushData->instance = c_keep(instance); + flushData->flushType = flushType; + data->list = c_iterAppend(data->list, flushData); + } + return FALSE; +} + +static c_iter +collectGroups( + d_chain chain) +{ + c_iter list; + v_historicalDataRequest vrequest; + struct collectGroupData data; + v_resourcePolicyI resourceLimits; + + list = c_iterNew(NULL); + /* Collect all data that needs to be sent. */ + data.request = chain->request; + data.list = list; + + data.isBuiltinDCPSTopicGroup = FALSE; + + if ((strcmp(v_entity(chain->vgroup->partition)->name, V_BUILTIN_PARTITION) == 0) && + (strcmp(v_entity(chain->vgroup->topic)->name, V_TOPICINFO_NAME) == 0)) { + data.isBuiltinDCPSTopicGroup = TRUE; + } else { + data.isBuiltinDCPSTopicGroup = FALSE; + } + + if (((d_sampleRequestSpecificReader(chain->request)) && d_sampleRequestHasCondition(chain->request)) || + (chain->request->filter != NULL)) { + /* This a request that originates from a reader OR + * This is a normal alignment request with a static content filter. + */ + data.checkTimeRange = FALSE; + + resourceLimits.v.max_samples = chain->request->maxSamples; + resourceLimits.v.max_instances = chain->request->maxInstances; + resourceLimits.v.max_samples_per_instance = chain->request->maxSamplesPerInstance; + + vrequest = v_historicalDataRequestNew( + v_objectKernel(chain->vgroup), + chain->request->filter, + (const c_char**)chain->request->filterParams, + chain->request->filterParamsCount, + c_timeToTimeW(chain->request->beginTime), + c_timeToTimeW(chain->request->endTime), + &resourceLimits, + OS_DURATION_ZERO); + + (void)d_shmAllocAssert(vrequest, "Allocation of historicalDataRequest failed."); + + v_groupFlushActionWithCondition( + chain->vgroup, vrequest, collectGroupsAddList, &data); + + c_free(vrequest); + } else { + /* This is an alignment request without any filter. + * align all samples in this case + */ + data.checkTimeRange = TRUE; + v_kernelGroupTransactionBeginAccess(v_objectKernel(chain->vgroup)); + v_groupFlushAction(chain->vgroup, collectGroupsAddList, &data); + v_kernelGroupTransactionEndAccess(v_objectKernel(chain->vgroup)); + } + + return list; +} + +static void +freeGroups( + void *o, + c_iterActionArg arg) +{ + struct v_groupFlushData *flushData = (struct v_groupFlushData *)o; + + OS_UNUSED_ARG(arg); + + c_free(flushData->object); + c_free(flushData->instance); +} + +static void +sampleChainAddLocalHash( + d_chain chain) +{ + c_iter list; + struct d_groupHash groupHash; + c_char *hash; + + list = collectGroups(chain); + + d_groupHashCalculate(&groupHash, list); + hash = d_groupHashToString(&groupHash); + d_sampleRequestSetHash(chain->request, hash); + + os_free(hash); + + c_iterWalk(list, freeGroups, NULL); + c_iterFree(list); +} + +static void +sampleChainAddStoreHash( + d_sampleChainListener listener, + d_chain chain) +{ + d_subscriber subscriber; + d_store store; + d_admin admin; + d_group group; + d_storeResult result; + struct d_groupHash groupHash; + c_char *hash; + + assert(d_sampleChainListenerIsValid(listener)); + assert(chain); + + admin = d_listenerGetAdmin(d_listener(listener)); + subscriber = d_adminGetSubscriber(admin); + store = d_subscriberGetPersistentStore(subscriber); + group = d_adminGetLocalGroup(admin, + chain->request->partition, + chain->request->topic, + chain->request->durabilityKind); + + result = d_storeMessagesLoad(store, group, &groupHash); + if (result == D_STORE_RESULT_OK) { + hash = d_groupHashToString(&groupHash); + d_sampleRequestSetHash(chain->request, hash); + d_groupSetStoreMessagesLoaded(group, TRUE); + os_free(hash); + } +} + +static c_bool +fellowHashCapableCheck( + d_fellow fellow, + c_voidp userData) +{ + c_bool *capable = (c_bool *)userData; + + if (d_fellowHasCapabilitySupport(fellow) && + d_fellowHasCapabilityGroupHash(fellow)) { + *capable = TRUE; + } else { + *capable = FALSE; + } + + return (*capable) ? FALSE : TRUE; +} + +/** + * \brief Insert a chain to the sampleChainListener + * + * The chain is used to correlate if all sampleRequests that correspond + * to the chain have been received. + * + * The chain to insert may not yet exist in the sampleChain. + */ +void +d_sampleChainListenerInsertRequest( + d_sampleChainListener listener, + d_chain chain, + c_bool reportGroupWhenUnfullfilled) +{ + d_admin admin = NULL; + d_durability durability = NULL; + d_configuration configuration; + d_networkAddress addressee, source; + struct chainRequestHelper data; + d_group group; + d_readerRequest readerRequest; + c_bool iAmAligner; + d_nameSpace nameSpace; + c_bool notInitial, fulfilled; + v_handle handle; + d_aligneeStatistics as; + d_thread self = d_threadLookupSelf (); + + assert(d_sampleChainListenerIsValid(listener)); + assert(chain); + + d_threadAwake(self); + + if (listener && chain) { + d_listenerLock(d_listener(listener)); + if (d_tableFind(listener->chains, chain) == NULL) { + /* New request. */ + admin = d_listenerGetAdmin(d_listener(listener)); + durability = d_adminGetDurability(admin); + } + if (!admin || !durability) { + /* Request already send out (or failure getting admin/durability). */ + d_listenerUnlock(d_listener(listener)); + } + } + + if (admin && durability) { + configuration = d_durabilityGetConfiguration(durability); + nameSpace = d_adminGetNameSpaceForGroup( + admin, + chain->request->partition, + chain->request->topic); + notInitial = d_nameSpaceIsAlignmentNotInitial(nameSpace); + data.chain = chain; + data.fellow = NULL; + data.role = configuration->role; + data.durability = durability; + data.nameSpace = nameSpace; + + if (nameSpace) { + data.master = d_nameSpaceGetMaster(nameSpace); + + if (d_nameSpaceMasterIsMe(nameSpace, admin)) { + + d_printTimedEvent(durability, D_LEVEL_FINER, + "Trying to find aligners for group %s.%s for nameSpace %s for which I am master.\n", + chain->request->partition, chain->request->topic, d_nameSpaceGetName(nameSpace)); + } else { + d_printTimedEvent(durability, D_LEVEL_FINER, + "Trying to find an aligner for group %s.%s for nameSpace %s that has master %u.\n", + chain->request->partition, chain->request->topic, + d_nameSpaceGetName(nameSpace), + data.master->systemId); + } + } else { + data.master = NULL; + + d_printTimedEvent(durability, D_LEVEL_FINER, + "Trying to find an aligner for group %s.%s for nameSpace %s that has no master.\n", + chain->request->partition, chain->request->topic, + d_nameSpaceGetName(nameSpace)); + } + + d_adminFellowWalk(admin, findAligner, &data); + + if (d_tableSize(chain->fellows) == 0) { + d_printTimedEvent(durability, D_LEVEL_FINER, + "Found no fellow aligners for group %s.%s.\n", + chain->request->partition, chain->request->topic); + + iAmAligner = d_adminGroupInAlignerNS( + admin, + chain->request->partition, + chain->request->topic); + + if (iAmAligner == FALSE) { + d_printTimedEvent(durability, D_LEVEL_FINER, + "Group %s.%s will not be aligned until an aligner fellow becomes available.\n", + chain->request->partition, chain->request->topic); + + if (reportGroupWhenUnfullfilled) { + if (notInitial) { + requestGroupFromMasterIfUnknown(admin, nameSpace, + chain->request->partition, + chain->request->topic, + chain->request->durabilityKind); + } + } + listener->unfulfilledChains = c_iterInsert(listener->unfulfilledChains, chain); + } else { + d_printTimedEvent(durability, D_LEVEL_FINER, + "I am aligner, group %s.%s will be marked as complete as no (potential) fellow aligners exist.\n", + chain->request->partition, chain->request->topic); + group = d_adminGetLocalGroup (admin, + chain->request->partition, + chain->request->topic, + chain->request->durabilityKind); + + d_groupSetComplete(group, admin); + updateGroupStatistics(admin, group); + + if (d_sampleRequestSpecificReader(chain->request)) { + source = d_networkAddressNew( + chain->request->source.systemId, + chain->request->source.localId, + chain->request->source.lifecycleId); + readerRequest = d_adminGetReaderRequest(admin, source); + d_networkAddressFree(source); + assert(readerRequest); + d_readerRequestRemoveChain(readerRequest, chain); + fulfilled = d_adminCheckReaderRequestFulfilled(admin, readerRequest); + + if (fulfilled) { + handle = d_readerRequestGetHandle(readerRequest); + d_printTimedEvent(durability, D_LEVEL_FINE, + "historicalDataRequest from reader [%d, %d] fulfilled.\n", + handle.index, handle.serial); + } + + d_readerRequestFree(readerRequest); + } + d_chainFree(chain); + + if (reportGroupWhenUnfullfilled) { + d_sampleChainListenerReportGroup(listener, group); + } + } + } else { + assert(nameSpace); + as = d_aligneeStatisticsNew(); + + if (data.fellow) { + addressee = d_fellowGetAddress(data.fellow); + + if (d_nameSpaceGetEqualityCheck(nameSpace) && + d_fellowHasCapabilitySupport(data.fellow) && + d_fellowHasCapabilityGroupHash(data.fellow)) { + + if ((d_nameSpaceMasterIsMe(nameSpace, admin) == FALSE) && + (d_durabilityGetState(durability) <= D_STATE_FETCH_INITIAL)) { + if ((d_nameSpaceGetDurabilityKind(nameSpace) == D_DURABILITY_PERSISTENT) || + (d_nameSpaceGetDurabilityKind(nameSpace) == D_DURABILITY_ALL)) { + sampleChainAddStoreHash(listener,chain); + } + } else { + sampleChainAddLocalHash(chain); + } + } + + /* Add chain to listener, send samplerequest when chain becomes active */ + d_sampleChainListenerAddChain(listener, chain, addressee); + + d_printTimedEvent(durability, D_LEVEL_FINER, + "Inserted new sampleRequest for group %s.%s for " \ + "complete fellow %u.\n", + chain->request->partition, chain->request->topic, + d_message(chain->request)->addressee.systemId); + as->aligneeRequestsSentDif = 1; + as->aligneeRequestsOpenDif = 1; + d_networkAddressFree(addressee); + } else if (d_nameSpaceMasterIsMe(nameSpace, admin)) { + c_bool hashCapable = FALSE; + addressee = d_networkAddressUnaddressed(); + + /* Check if at least one of the fellows supports AlignOnChange */ + if (d_nameSpaceGetEqualityCheck(nameSpace)) { + d_adminFellowWalk(admin, fellowHashCapableCheck, &hashCapable); + if (hashCapable) { + sampleChainAddLocalHash(chain); + } + } + + /* Add chain to listener, send samplerequest when chain becomes active */ + d_sampleChainListenerAddChain(listener, chain, addressee); + + d_printTimedEvent(durability, D_LEVEL_FINER, + "No complete fellow found for group %s.%s, but I am the master for this one so inserted request for %u fellows.\n", + chain->request->partition, chain->request->topic, + d_tableSize(chain->fellows)); + as->aligneeRequestsSentDif = 1; + as->aligneeRequestsOpenDif = 1; + d_networkAddressFree(addressee); + } else { + d_printTimedEvent(durability, D_LEVEL_FINER, + "Found %u (potential) fellow aligners for group %s.%s.\n", + d_tableSize(chain->fellows), + chain->request->partition, chain->request->topic); + + d_tableFree(chain->fellows); + chain->fellows = d_tableNew(d_fellowCompare, d_chainFellowFree); + listener->unfulfilledChains = c_iterInsert(listener->unfulfilledChains, chain); + + group = d_adminGetLocalGroup (admin, + chain->request->partition, + chain->request->topic, + chain->request->durabilityKind); + + d_printTimedEvent(durability, D_LEVEL_FINE, + "Group %s.%s will not be aligned until the master fellow becomes complete (reportGroupWhenUnfullfilled=%s, notInitial=%s).\n", + chain->request->partition, chain->request->topic, + reportGroupWhenUnfullfilled?"TRUE":"FALSE", + notInitial?"TRUE":"FALSE"); + + if(reportGroupWhenUnfullfilled){ + d_sampleChainListenerReportGroup(listener, group); + + if (notInitial) { + requestGroupFromMasterIfUnknown(admin, nameSpace, + chain->request->partition, + chain->request->topic, + chain->request->durabilityKind); + } + } + } + as->aligneeRequestsWaiting = c_iterLength(listener->unfulfilledChains); + d_durabilityUpdateStatistics(durability, d_statisticsUpdateAlignee, as); + d_aligneeStatisticsFree(as); + } + if(data.master){ + d_networkAddressFree(data.master); + } + d_listenerUnlock(d_listener(listener)); + } +} + +struct findEntryHelper { + c_char* partition; + c_char* topic; + v_entry current; + v_entry entry; +}; + +static c_bool +findEntryGroup( + v_proxy proxy, + c_voidp args) +{ + v_group vgroup; + v_handleResult handleResult; + c_bool result; + c_string topicName, partitionName; + + struct findEntryHelper *entryHelper; + entryHelper = (struct findEntryHelper*)args; + result = TRUE; + + handleResult = v_handleClaim(proxy->source, (v_object*)(&vgroup)); + + if(handleResult == V_HANDLE_OK){ + topicName = v_entityName(v_groupTopic(vgroup)); + partitionName = v_entityName(v_groupPartition(vgroup)); + + if(topicName && partitionName){ + if(strcmp(entryHelper->topic, topicName) == 0){ + if(strcmp(entryHelper->partition, partitionName) == 0){ + entryHelper->entry = entryHelper->current; + result = FALSE; + } + } + } + v_handleRelease(proxy->source); + } + return result; +} + +static c_bool +findEntry( + v_entry entry, + c_voidp args) +{ + struct findEntryHelper *entryHelper; + entryHelper = (struct findEntryHelper*)args; + entryHelper->current = entry; + + return c_tableWalk(entry->groups, (c_action)findEntryGroup, args); + +} + +static c_bool +calculateEqualCount( + d_chainLink link, + c_voidp args) +{ + c_ulong *count = (c_ulong *) args; + if (link->sampleCount == D_GROUP_IS_EQUAL) { + (*count)++; + } + return TRUE; +} + + +c_bool +d_sampleChainListenerCheckChainComplete( + d_sampleChainListener listener, + d_chain chain) +{ + d_group dgroup; + v_group vgroup; + c_char *partition, *topic; + d_admin admin; + d_durability durability; + c_bool result = FALSE; + d_resendAction resendData; + d_action action; + d_networkAddress source; + d_readerRequest readerRequest; + d_aligneeStatistics as; + v_handle handle; + c_bool fulfilled; + struct readBeadHelper beadHelper; + struct findEntryHelper entryHelper; + v_handleResult handleResult; + v_reader vreader, *vreaderPtr; + d_nameSpace nameSpace, myNameSpace; + d_mergeAction mergeAction; + d_mergeState newState; + d_mergePolicy mergePolicy; + c_ulong chainCount; + v_writeResult writeResult; + d_conflictResolver conflictResolver; + c_ulong equalCount; + c_ulong linkCount; + os_timeW t; + + myNameSpace = NULL; + + assert(d_objectIsValid(d_object(chain), D_CHAIN) == TRUE); + + if (d_tableSize(chain->fellows) == d_tableSize(chain->links)) { + /* All fellows have sent their link */ + admin = d_listenerGetAdmin(d_listener(listener)); + durability = d_adminGetDurability(admin); + conflictResolver = admin->conflictResolver; + dgroup = d_adminGetLocalGroup( + admin, + chain->request->partition, + chain->request->topic, + chain->request->durabilityKind); + if (chain->samplesExpect >= 0) { + if (((c_ulong)chain->samplesExpect) == d_tableSize(chain->beads)) { + /* All samples have been received. */ + vgroup = d_groupGetKernelGroup(dgroup); + partition = d_groupGetPartition(dgroup); + topic = d_groupGetTopic(dgroup); + + d_printTimedEvent(durability, D_LEVEL_FINE, + "Received %u beads for group %s.%s.\n", + d_tableSize(chain->beads), partition, topic); + + resendData = d_resendActionNew(listener, dgroup); + as = d_aligneeStatisticsNew(); + beadHelper.action = resendData; + beadHelper.totalCount = 0; + beadHelper.writeCount = 0; + beadHelper.disposeCount = 0; + beadHelper.writeDisposeCount = 0; + beadHelper.registerCount = 0; + beadHelper.unregisterCount = 0; + beadHelper.eotCount = 0; + beadHelper.entry = NULL; + beadHelper.self = d_threadLookupSelf (); + + if (d_sampleRequestSpecificReader(chain->request)) { + source = d_networkAddressNew( + chain->request->source.systemId, + chain->request->source.localId, + chain->request->source.lifecycleId); + readerRequest = d_adminGetReaderRequest(admin, source); + d_networkAddressFree(source); + assert(readerRequest); + + handle = d_readerRequestGetHandle(readerRequest); + handleResult = v_handleClaim(handle, (v_object*)(vreaderPtr = &vreader)); + + if(handleResult == V_HANDLE_OK){ + entryHelper.partition = chain->request->partition; + entryHelper.topic = chain->request->topic; + entryHelper.entry = NULL; + v_readerWalkEntries(vreader, (c_action)findEntry, &entryHelper); + + if(entryHelper.entry){ + beadHelper.entry = entryHelper.entry; + d_tableWalk(chain->beads, d_chainBeadInject, &beadHelper); + } else { + d_printTimedEvent(durability, D_LEVEL_WARNING, + "Unable to lookup entry for reader "\ + "[%d, %d] for group %s.%s.\n", + handle.index, handle.serial, + chain->request->partition, + chain->request->topic); + } + v_handleRelease(handle); + } + + d_readerRequestRemoveChain(readerRequest, chain); + fulfilled = d_adminCheckReaderRequestFulfilled(admin, readerRequest); + d_resendActionFree(resendData); + d_readerRequestFree(readerRequest); + d_printTimedEvent(durability, D_LEVEL_FINE, + "Reader [%d, %d] has now received requested "\ + "historical data for group %s.%s.\n", + handle.index, handle.serial, + chain->request->partition, chain->request->topic); + + if(fulfilled){ + d_printTimedEvent(durability, D_LEVEL_FINE, + "historicalDataRequest from reader [%d, %d] fulfilled.\n", + handle.index, handle.serial); + } + + d_printTimedEvent(durability, D_LEVEL_FINE, + "Injected: TOTAL: %d, WRITE: %d, DISPOSED: %d, WRITE_DISPOSED: %d, REGISTER: %d, UNREGISTER: %d, EOT: %d.\n", + beadHelper.totalCount, beadHelper.writeCount, + beadHelper.disposeCount, beadHelper.writeDisposeCount, + beadHelper.registerCount, beadHelper.unregisterCount, + beadHelper.eotCount); + + as->aligneeSamplesTotalDif = beadHelper.totalCount; + as->aligneeSamplesRegisterDif = beadHelper.registerCount; + as->aligneeSamplesWriteDif = beadHelper.writeCount; + as->aligneeSamplesDisposeDif = beadHelper.disposeCount; + as->aligneeSamplesWriteDisposeDif = beadHelper.writeDisposeCount; + as->aligneeSamplesUnregisterDif = beadHelper.unregisterCount; + as->aligneeTotalSizeDif = chain->receivedSize; + } else { + /** Need to find out whether this chain is part of a + * mergeAction. + */ + mergeAction = d_sampleChainListenerGetMergeAction(listener, chain); + + if (mergeAction) { + + d_traceMergeAction(mergeAction, "Chain received"); + + equalCount = 0; + linkCount = d_tableSize(chain->links); + d_tableWalk(chain->links, calculateEqualCount, &equalCount); + + nameSpace = d_mergeActionGetNameSpace(mergeAction); + myNameSpace = d_adminGetNameSpace(admin, d_nameSpaceGetName(nameSpace)); + newState = d_mergeActionGetNewState(mergeAction); + mergePolicy = d_nameSpaceGetMergePolicy(myNameSpace, newState->role); + /* set the merge policy in the beadHelper */ + beadHelper.mergePolicy = mergePolicy; + + { + const char *mergePolicyStr; + switch (mergePolicy) { + case D_MERGE_DELETE: mergePolicyStr = "pre DELETE"; break; + case D_MERGE_REPLACE: mergePolicyStr = "pre REPLACE"; break; + case D_MERGE_CATCHUP: mergePolicyStr = "pre CATCHUP"; break; + case D_MERGE_MERGE: mergePolicyStr = "pre MERGE"; break; + case D_MERGE_IGNORE: mergePolicyStr = "pre IGNORE"; break; + default: mergePolicyStr = "pre UNDEFINED"; break; + } + d_tracegroup(durability, vgroup, mergePolicyStr); + } + switch(mergePolicy){ + case D_MERGE_DELETE: + /* apply the DELETE merge policy */ + d_printTimedEvent(durability, D_LEVEL_FINE, + "Applying DELETE merge policy for group %s.%s\n", + chain->request->partition, chain->request->topic); + /* Dispose all data before the requestTime of the + * the sampleRequest that lead to the retrieval of the + * sampleChain. + */ + d_timestampToTimeW(&t, &chain->request->requestTime, IS_Y2038READY(chain->request)); + writeResult = v_groupDisposeAllMatchingInstances(vgroup, t, L_REPLACED, NULL, NULL); + if ( writeResult == V_WRITE_SUCCESS ) { + os_timeE te; + + d_printTimedEvent(durability, D_LEVEL_FINER, + "Samples before timestamp %"PA_PRItime" disposed for group %s.%s\n", + OS_TIMEW_PRINT(t), + chain->request->partition, + chain->request->topic); + /* Delete all historical data for the group with a writeTime up to and + * including timestamp. The timestamp must be an elapsed time, so we + * need to calculate the corresponding elapsed time of t. + */ + te = d_timeWToTimeE(t); + writeResult = v_groupDeleteHistoricalData(vgroup, te); + if ( writeResult == V_WRITE_SUCCESS ) { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Historical data before timestamp %"PA_PRItime" deleted for group %s.%s\n", + OS_TIMEW_PRINT(t), + chain->request->partition, + chain->request->topic); + /* Assume that each DELETE leads to state change of the set */ + d_mergeActionSetStateChanged(mergeAction, TRUE); + } else { + OS_REPORT(OS_ERROR, + "d_sampleChainListenerCheckChainComplete",0, + "Failed to delete historical data before timestamp %"PA_PRItime" for group %s.%s", + OS_TIMEW_PRINT(t), + chain->request->partition, + chain->request->topic); + } + } else { + OS_REPORT(OS_ERROR, + "d_sampleChainListenerCheckChainComplete",0, + "Failed to dispose all instances for group %s.%s", + chain->request->partition, chain->request->topic); + } + break; + case D_MERGE_REPLACE: + /* Apply the REPLACE merge policy */ + d_printTimedEvent(durability, D_LEVEL_FINE, + "Applying REPLACE merge policy for group %s.%s\n", + chain->request->partition, chain->request->topic); + + d_timestampToTimeW(&t, &chain->request->requestTime, IS_Y2038READY(chain->request)); + if (equalCount == 0) { + /* When no equal link is received dispose all data + * before the requestTime of the sampleRequest + * that lead to the retrieval of the sampleChain. + */ + writeResult = v_groupDisposeAllMatchingInstances(vgroup, t, L_REPLACED, NULL, NULL); + } else { + writeResult = V_WRITE_SUCCESS; + } + if (equalCount != linkCount) { + if ( writeResult == V_WRITE_SUCCESS ) { + os_timeE te; + + d_printTimedEvent(durability, D_LEVEL_FINER, + "Samples before timestamp %"PA_PRItime" disposed for group %s.%s\n", + OS_TIMEW_PRINT(t), + chain->request->partition, + chain->request->topic); + /* Mark all reader instances with the L_REPLACED flag to indicate + * that the REPLACE merge policy is about to inject historical samples. + */ + v_groupMarkGroupInstanceStates(vgroup, L_REPLACED); + /* Delete all historical data for the group with a writeTime up to and + * including timestamp. + */ + te = d_timeWToTimeE(t); + writeResult = v_groupDeleteHistoricalData(vgroup, te); + if ( writeResult == V_WRITE_SUCCESS ) { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Historical data before timestamp %"PA_PRItime" deleted for group %s.%s\n", + OS_TIMEW_PRINT(t), + chain->request->partition, + chain->request->topic); + /* Per bead, remove the dispose message that was generated by the + * v_groupDisposeAll() from the reader instance, update the reader + * state, and inject historical data. + */ + d_tableWalk(chain->beads, d_chainBeadInject, &beadHelper); + } else { + OS_REPORT(OS_ERROR, + "d_sampleChainListenerCheckChainComplete",0, + "Failed to delete historical data before timestamp %"PA_PRItime" for group %s.%s", + OS_TIMEW_PRINT(t), + chain->request->partition, + chain->request->topic); + } + /* Reset the marker. */ + v_groupUnmarkReaderInstanceStates(vgroup, L_REPLACED); + /* Assume that the REPLACE always changes the data set */ + d_mergeActionSetStateChanged(mergeAction, TRUE); + } else { + OS_REPORT(OS_ERROR, + "d_sampleChainListenerCheckChainComplete",0, + "Failed to dispose all instances for group %s.%s", + chain->request->partition, chain->request->topic); + } + } else { + d_printTimedEvent(durability, D_LEVEL_FINER, + "No need to do anything for group %s.%s because my current set is equal to the set to inject\n", + chain->request->partition, chain->request->topic); + } + break; + case D_MERGE_CATCHUP: + /* Apply the CATCHUP merge policy */ + d_printTimedEvent(durability, D_LEVEL_FINE, + "Applying CATCHUP merge policy for group %s.%s\n", + chain->request->partition, chain->request->topic); + /* If a different data set is aligned then mark all existing + * instances to indicate that a CATCHUP operation is about to + * take place. Only if a different data set is aligned (i.e., + * no equal link is received) we need to mark our current set + * in order to dispose instances that don't exist later on. + */ + d_timestampToTimeW(&t, &chain->request->requestTime, IS_Y2038READY(chain->request)); + + if (equalCount == 0) { + assert(equalCount != linkCount); + + /* No equal link received */ + v_groupMarkGroupInstanceStates(vgroup, L_MARK); + /* At least one none-equal link has been received, so at + * least one of the aligner fellows has a different set. + * Insert the historical data. While doing so + * clear the L_MARK flag for existing instances, + * and make sure that the instance state is set to L_NEW + * for new instances + */ + d_tableWalk(chain->beads, d_chainBeadInject, &beadHelper); + /* Now dispose all messages before the chain->request->time for + * all instances with the L_MARK flag (these were the instances + * that were untouched by the CATCHUP merge action). Collect + * the instances that are touched and return these in the + * instances argument. + */ + if ((writeResult = v_groupSweepMarkedInstances(vgroup, t)) != V_WRITE_SUCCESS) { + OS_REPORT(OS_ERROR, + "d_sampleChainListenerCheckChainComplete",0, + "Failed to dispose marked instances for group %s.%s", + chain->request->partition, chain->request->topic); + } + /* Reset the marker. */ + v_groupUnmarkGroupInstanceStates(vgroup, L_MARK); + /* Assume that the CATCHUP always changes the data set */ + d_mergeActionSetStateChanged(mergeAction, TRUE); + } else { + d_printTimedEvent(durability, D_LEVEL_FINER, + "No need to do anything for group %s.%s because my current set is equal to the set to inject\n", + chain->request->partition, chain->request->topic); + } + break; + case D_MERGE_MERGE: + /* Apply the MERGE merge policy */ + d_printTimedEvent(durability, D_LEVEL_FINE, + "Applying MERGE merge policy for group %s.%s\n", + chain->request->partition, chain->request->topic); + /* inject the beads */ + if (equalCount != linkCount) { + d_tableWalk(chain->beads, d_chainBeadInject, &beadHelper); + /* Assume that MERGE with a non-empty set leads to a state change */ + if (beadHelper.totalCount != 0) { + d_mergeActionSetStateChanged(mergeAction, TRUE); + } + } else { + d_printTimedEvent(durability, D_LEVEL_FINER, + "No need to do anything for group %s.%s because my current set is equal to the set to inject\n", + chain->request->partition, chain->request->topic); + } + break; + case D_MERGE_IGNORE: + /* Apply the IGNORE merge policy */ + d_printTimedEvent(durability, D_LEVEL_FINE, + "Applying IGNORE merge policy for group %s.%s\n", + chain->request->partition, chain->request->topic); + /* IGNORE never leads to a state change */ + break; + default: + /* A new merge policy? How exciting...*/ + assert(FALSE); + break; + } + d_tracegroup(durability, vgroup, "final state"); + } else { + /* The chain is not part of a mergeAction, but it can be + * an initial merge action. Simply inject the beads + */ + beadHelper.mergePolicy = D_MERGE_IGNORE; + d_tableWalk(chain->beads, d_chainBeadInject, &beadHelper); + } + + /* Messages have been rejected. A resend must be scheduled. */ + if(resendData->messages != NULL){ + os_duration sleepTime = OS_DURATION_INIT(1,0); + os_timeM actionTime = os_timeMAdd(os_timeMGet(), sleepTime); + + action = d_actionNew(actionTime, sleepTime, d_resendRejected, resendData); + d_actionQueueAdd(listener->resendQueue, action); + } else{ + d_resendActionFree(resendData); + d_groupSetComplete(dgroup, admin); + updateGroupStatistics(admin, dgroup); + + d_printTimedEvent(durability, D_LEVEL_FINER, + "Group %s.%s is now complete.\n", partition, topic); + d_printTimedEvent(durability, D_LEVEL_FINE, + "Injected: TOTAL: %d, WRITE: %d, DISPOSE: %d, WRITE_DISPOSE: %d, REGISTER: %d, UNREGISTER: %d, EOT: %d.\n", + beadHelper.totalCount, beadHelper.writeCount, + beadHelper.disposeCount, beadHelper.writeDisposeCount, + beadHelper.registerCount, beadHelper.unregisterCount, + beadHelper.eotCount); + + as->aligneeSamplesTotalDif = beadHelper.totalCount; + as->aligneeSamplesRegisterDif = beadHelper.registerCount; + as->aligneeSamplesWriteDif = beadHelper.writeCount; + as->aligneeSamplesDisposeDif = beadHelper.disposeCount; + as->aligneeSamplesWriteDisposeDif = beadHelper.writeDisposeCount; + as->aligneeSamplesUnregisterDif = beadHelper.unregisterCount; + as->aligneeTotalSizeDif = chain->receivedSize; + d_sampleChainListenerReportGroup(listener, dgroup); + } + + if (mergeAction) { + c_bool success = d_mergeActionRemoveChain(mergeAction, chain); + assert(success); + (void)success; + + chainCount = d_mergeActionGetChainCount(mergeAction); + + if (chainCount == 0) { + + d_trace(D_TRACE_CHAINS, "Removing mergeAction %p\n", (void *)mergeAction); + + d_tableRemove(listener->mergeActions, mergeAction); + nameSpace = d_mergeActionGetNameSpace(mergeAction); + + assert (myNameSpace); + + /* Decide whether or not to update my state */ + if (!d_nameSpaceMasterIsMe (myNameSpace, admin)) { + /* If I am a slave I need to follow my master's merge states */ + + d_printTimedEvent(durability, D_LEVEL_FINER, + "Slaving to my master, set the state of namespace '%s' to '%d' for role '%s'\n", + d_nameSpaceGetName(nameSpace), + d_mergeActionGetNewState(mergeAction)->value, + d_mergeActionGetNewState(mergeAction)->role); + + d_nameSpaceReplaceMergeStates (myNameSpace, nameSpace); + d_nameSpaceSetMergeState(myNameSpace, d_mergeActionGetNewState(mergeAction)); + } else if (!d_mergeActionGetStateChanged(mergeAction)) { + /* I am the master but my state was not changed */ + + d_printTimedEvent(durability, D_LEVEL_FINER, + "No need to update the state of namespace '%s' for role '%s' because I " + "did not change my state while applying my merge policy\n", + d_nameSpaceGetName(nameSpace), d_mergeActionGetNewState(mergeAction)->role); + + } else { + /* I am the master and changed my state, so I need to update my state */ + d_nameSpaceSetMergeState(myNameSpace, d_mergeActionGetNewState(mergeAction)); + + d_printTimedEvent(durability, D_LEVEL_FINE, + "Updating state of namespace '%s' to '%d' for role '%s'\n", + d_nameSpaceGetName(nameSpace), + d_mergeActionGetNewState(mergeAction)->value, + d_mergeActionGetNewState(mergeAction)->role); + } + + d_mergeActionUpdateMergeCount(mergeAction); + + /* Indicate that the mergeAction is completed + * This function will also republish namespaces when necessary + */ + d_conflictResolverResetConflictInProgress(conflictResolver, mergeAction->conflict); + + d_mergeActionFree(mergeAction); + + } + } + + if (myNameSpace) { + d_nameSpaceFree (myNameSpace); + } + } + c_free(vgroup); + + as->aligneeRequestsWaiting = c_iterLength(listener->unfulfilledChains); + as->aligneeRequestsOpenDif = -1; + d_durabilityUpdateStatistics(durability, d_statisticsUpdateAlignee, as); + d_aligneeStatisticsFree(as); + + result = TRUE; + os_free(partition); + os_free(topic); + } else { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Expecting %d samples, received %u so far (1)\n", + chain->samplesExpect, d_tableSize(chain->beads)); + } + } else { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Expecting %d samples, received %u so far (2)\n", + chain->samplesExpect, d_tableSize(chain->beads)); + } + } + return result; +} + +void +d_sampleChainListenerReportStatus( + d_sampleChainListener listener) +{ + d_admin admin; + d_durability durability; + d_chain chain; + c_ulong i; + + assert(d_sampleChainListenerIsValid(listener)); + + if(listener){ + admin = d_listenerGetAdmin(d_listener(listener)); + durability = d_adminGetDurability(admin); + + d_listenerLock(d_listener(listener)); + + d_printTimedEvent(durability, D_LEVEL_FINEST, "The following groups are currently being aligned:\n"); + + d_tableWalk(listener->chains, d_chainReportStatus, durability); + + d_printTimedEvent(durability, D_LEVEL_FINEST, "The following groups have no aligner yet:\n"); + + for(i=0; iunfulfilledChains); i++){ + chain = c_iterObject(listener->unfulfilledChains, i); + d_printTimedEvent(durability, D_LEVEL_FINEST, + "- No aligner yet for group: '%s.%s'.\n", chain->request->partition, chain->request->topic); + } + d_listenerUnlock(d_listener(listener)); + } + return; +} + +struct processChainsHelper { + d_sampleChainListener listener; + d_publisher publisher; + c_iter fellows; + d_durability durability; + d_aligneeStatistics as; + d_mergeAction mergeAction; + d_chain chain; + c_bool equalityCheck; +}; + + +static c_bool +publishSampleRequests( + d_fellow fellow, + c_voidp args) +{ + struct processChainsHelper* helper; + + helper = (struct processChainsHelper*)args; + + if (helper->mergeAction) { + d_printTimedEvent(helper->durability, D_LEVEL_FINE, + "Going to send sampleRequest to fellow %u as part of merge action %p\n", + fellow->address->systemId, (void *)(helper->mergeAction)); + } else { + d_printTimedEvent(helper->durability, D_LEVEL_FINE, + "Going to send sampleRequest to fellow %u\n", + fellow->address->systemId, (void *)(helper->mergeAction)); + } + + /* Update statistics */ + helper->as->aligneeRequestsSentDif += 1; + helper->as->aligneeRequestsOpenDif += 1; + /* Update the fellow with the number of sampleRequests */ + d_fellowRequestAdd(fellow); + /* Add the fellow as the recipient of the sampleRequest */ + if (d_tableInsert(helper->chain->fellows, d_objectKeep(d_object(fellow))) != NULL) { + d_fellowFree(fellow); + } else { + /* Calculate hash when fellow supports hash and when not in request already */ + if ((helper->equalityCheck) && + (d_fellowHasCapabilityGroupHash(fellow)) && + (d_sampleRequestHasHash(helper->chain->request, fellow) == FALSE)) { + sampleChainAddLocalHash(helper->chain); + } + /* Publish the sampleRequest */ + d_sampleChainListenerAddChain(helper->listener, helper->chain, fellow->address); + } + return TRUE; +} + + +/** + * \brief Send a sampleRequest for the chain to all fellows in the mergeAction + */ +static c_bool +processChains( + d_chain chain, + c_voidp args) +{ + struct processChainsHelper* helper; + + assert(d_chainIsValid(chain)); + + helper = (struct processChainsHelper*)args; + helper->chain = chain; + /* Publish sampleRequests for the chain to all fellows + * in the mergeAction. + */ + assert(d_mergeActionIsValid(helper->mergeAction)); + (void)d_tableWalk(helper->mergeAction->fellows, publishSampleRequests, helper); + helper->chain = NULL; + return TRUE; +} + + +static void +remove_non_existent_fellows( + d_admin admin, + d_table fellows) +{ + /* Remove the fellows from the table if they do not exist anymore. + * This is possible because fellows may have left before taking the + * listenerLock. + */ + + d_durability durability; + + durability = d_adminGetDurability(admin); + if (fellows) { + c_iter to_remove = c_iterNew(NULL); + d_tableIter tableIter; + d_fellow fellow, found; + + fellow = d_fellow(d_tableIterFirst(fellows, &tableIter)); + /* First get the fellows that do not exist anymore. */ + while (fellow) { + if ((found = d_adminGetFellow(admin, fellow->address)) == NULL) { + + d_printTimedEvent(durability, D_LEVEL_FINEST, + " - NOT going to send sampleRequest to fellow %u, the fellow disappeared\n", + fellow->address->systemId); + + to_remove = c_iterAppend(to_remove, fellow); + } else { + d_printTimedEvent(durability, D_LEVEL_FINEST, + " - Going to send sampleRequest to fellow %u\n", + fellow->address->systemId); + + d_fellowFree(found); + } + fellow = d_fellow(d_tableIterNext(&tableIter)); + } + /* Next remove the fellows from the table */ + while (((fellow = d_fellow(c_iterTakeFirst(to_remove))) != NULL)) { + (void)d_tableRemove(fellows, fellow); + d_fellowFree(fellow); + } + c_iterFree(to_remove); + } +} + + +c_bool +d_sampleChainListenerInsertMergeAction( + d_sampleChainListener listener, + d_mergeAction action) +{ + d_admin admin; + struct processChainsHelper helper; + d_mergeAction duplicate; + c_bool result; + d_conflictResolver conflictResolver; + d_nameSpace myNameSpace; + d_durability durability; + + assert(d_sampleChainListenerIsValid(listener)); + assert(action); + result = FALSE; + + if (listener && action) { + + /* Lock the sampleChainListener to prevent that chains are removed + * (because fellows are removed) while at the same time sampleRequests + * are being sent to the fellow. Taking the lock at this point in time prevents + * d_sampleChainListenerNotifyFellowRemoved to proceed. Only when the sampleRequests + * for this mergeAction have been sent the lock is released, and + * d_sampleChainListenerNotifyFellowRemoved can proceed to remove any outstanding + * chains for fellows that have been removed. + */ + + d_listenerLock(d_listener(listener)); + admin = d_listenerGetAdmin(d_listener(listener)); + durability = d_adminGetDurability(admin); + conflictResolver = admin->conflictResolver; + + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Determining the target fellows for merge action %p\n", + (void *)action); + + remove_non_existent_fellows(admin, action->fellows); + + if (d_tableSize(action->fellows) == 0) { + d_printTimedEvent(durability, D_LEVEL_FINE, + "All fellows in merge action %p have disappeared, canceling this merge action \n", + (void *)action); + } else { + duplicate = d_mergeAction(d_tableInsert(listener->mergeActions, action)); + + if (duplicate == NULL) { + /* Samples will be requested. Remember that the conflictResolver + * is in progress with handling a conflict to prevent that a new + * conflict is started before the previous one is completed. + * The conflict handling is completed when conflictInProgress is + * set to FALSE (see d_sampleChainListenerCheckChainComplete) + * . */ + d_conflictResolverSetConflictInProgress(conflictResolver, action->conflict); + + helper.mergeAction = action; + helper.as = d_aligneeStatisticsNew(); + helper.durability = d_adminGetDurability(admin); + helper.publisher = d_adminGetPublisher(admin); + helper.listener = listener; + helper.equalityCheck = FALSE; + + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Merge action %p applies to %d fellows\n", + (void *)action, d_tableSize(action->fellows)); + + myNameSpace = d_adminGetNameSpace(admin, d_nameSpaceGetName(action->nameSpace)); + if (myNameSpace) { + helper.equalityCheck = d_nameSpaceGetEqualityCheck(myNameSpace); + } + d_nameSpaceFree(myNameSpace); + + /* Walk over all chains in the mergeAction to send out sample requests */ + d_mergeActionChainWalk(action, processChains, &helper); + + d_durabilityUpdateStatistics(helper.durability, + d_statisticsUpdateAlignee, helper.as); + + d_aligneeStatisticsFree(helper.as); + + result = TRUE; + } + } + d_listenerUnlock(d_listener(listener)); + } + return result; +} + +void +d_sampleChainListenerCheckUnfulfilled( + d_sampleChainListener listener, + d_nameSpace nameSpace, + d_networkAddress fellowAddress) { + + d_admin admin; + d_chain chain; + d_groupsRequest request; + d_publisher publisher; + c_ulong i; + + if (listener) { + admin = d_listenerGetAdmin(d_listener(listener)); + publisher = d_adminGetPublisher(admin); + + d_listenerLock(d_listener(listener)); + + for(i=0; iunfulfilledChains); i++) { + chain = c_iterObject(listener->unfulfilledChains, i); + + if (d_nameSpaceIsIn(nameSpace, chain->request->partition, chain->request->topic)) { + /* Re-request group from (master) fellow so we're sure to have the latest group completeness */ + request = d_groupsRequestNew(admin, chain->request->partition, chain->request->topic); + + /* Write request */ + d_publisherGroupsRequestWrite(publisher, request, fellowAddress); + + /* Free request */ + d_groupsRequestFree(request); + } + } + + d_listenerUnlock(d_listener(listener)); + } +} + + +/** + * \brief Compare two chains. + * + * Two chains are considered equal if the partition, topic, + * durabilityKind and source of their requests are equal. + * + * Note: + * The filter is NOT involved in the sampleChain comparison. + * This is because a chain lookup is done based on an incoming + * samplechain that does not carry a filter (see + * d_sampleChainListenerFindChain). This still works because: + * - if a reader requests historical data with a filter then + * the source of the reader is sufficient to identify the + * outstanding chain + * - for a give partitio/topic there is at most a single + * static content filter, so the filter would not do much + * in the comparison anyway. + */ +int +d_chainCompare( + d_chain chain1, + d_chain chain2) +{ + int result; + + assert(d_chainIsValid(chain1)); + assert(d_chainIsValid(chain2)); + assert(chain1->request); + assert(chain2->request); + + /* Check if partition/topic match */ + result = strcmp(chain1->request->partition, chain2->request->partition); + if (result == 0) { + result = strcmp(chain1->request->topic, chain2->request->topic); + if (result == 0) { + /* Check if durabilityKind matches */ + if (chain1->request->durabilityKind == chain2->request->durabilityKind) { + /* Check if source matches */ + result = d_networkAddressCompare( + &chain1->request->source, &chain2->request->source); + } else if (chain1->request->durabilityKind > chain2->request->durabilityKind) { + result = 1; + } else { + result = -1; + } + } + } + return result; +} + diff --git a/src/services/durability/code/d_sampleRequest.c b/src/services/durability/code/d_sampleRequest.c new file mode 100644 index 000000000..5fe95aca6 --- /dev/null +++ b/src/services/durability/code/d_sampleRequest.c @@ -0,0 +1,519 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#include "d_sampleRequest.h" +#include "d__readerRequest.h" +#include "d__admin.h" +#include "d__misc.h" +#include "d_message.h" +#include "d_networkAddress.h" +#include "d__fellow.h" +#include "d__thread.h" +#include "d__durability.h" +#include "d__configuration.h" +#include "d__groupHash.h" +#include "vortex_os.h" + + +/** + * Compare two filter expressions and their parameters. + * + * Note: This function is called only if the partition, topic and source + * of the sampleRequest already match. + */ +static int +compareFilters( + d_sampleRequest request1, /* the current request in the table */ + d_sampleRequest request2) /* the request to add */ +{ + int result = 0; + c_ulong i; + + assert(request1); + assert(request2); + + if (request1->filter == request2->filter) { + return 0; + } else if (request1->filter == NULL) { + return 1; + } else if (request2->filter == NULL) { + return -1; + } else { + /* request1->filter != NULL and request2->filter != NULL. + * Compare the filter and the parameters + */ + if (request1->filterParamsCount < request2->filterParamsCount) { + return -1; + } else if (request1->filterParamsCount > request2->filterParamsCount) { + return 1; + } else { + result = strcmp(request1->filter, request2->filter); + if (result == 0) { + /* The requests and the number of parameters match, now + * now check if the parameters match + */ + for (i=0; ifilterParamsCount; i++) { + result = strcmp(request1->filterParams[i], request2->filterParams[i]); + if (result != 0) { + /* Not equal */ + break; + } + } /* for */ + } + } + } + return result; +} + + +d_sampleRequest +d_sampleRequestNew( + d_admin admin, + c_char* partition, + c_char* topic, + d_durabilityKind kind, + os_timeW requestTime, + c_bool withTimeRange, + os_timeW beginTime, + os_timeW endTime) +{ + d_sampleRequest sampleRequest = NULL; + char *sqlExpression; + + assert(d_adminIsValid(admin)); + assert(partition); + assert(topic); + + /* Allocate sampleRequest */ + sampleRequest = d_sampleRequest(os_malloc(C_SIZEOF(d_sampleRequest))); + if (sampleRequest) { + /* Initialize to NULL */ + memset(sampleRequest, 0, sizeof(C_STRUCT(d_sampleRequest))); + /* Call super-init */ + d_messageInit(d_message(sampleRequest), admin); + /* Initialize sampleRequest */ + sampleRequest->partition = os_strdup(partition); + sampleRequest->topic = os_strdup(topic); + sampleRequest->durabilityKind = kind; + d_timestampFromTimeW(&sampleRequest->requestTime, &requestTime, IS_Y2038READY(sampleRequest)); + sampleRequest->withTimeRange = withTimeRange; + d_timestampFromTimeW(&sampleRequest->beginTime, &beginTime, IS_Y2038READY(sampleRequest)); + d_timestampFromTimeW(&sampleRequest->endTime, &endTime, IS_Y2038READY(sampleRequest)); + /* Every fellow that responds to a request will copy + * the source in its response. The response will be + * stored in the chain that matches the partition,topic + * and source. + */ + sampleRequest->source.systemId = 0; + sampleRequest->source.localId = 0; + sampleRequest->source.lifecycleId = 0; + sqlExpression = d_adminGetStaticFilterExpression(admin, partition, topic); + if (sqlExpression) { + sampleRequest->filter = os_strdup(sqlExpression); + } else { + sampleRequest->filter = NULL; + } + /* For the feature AlignOnChange/equalityCheck the filterParams string + * sequence is extended with a hash string, this hash string is not included + * in the filterParamsCount. The hash string is the first following entry + * after the filters in the filterParams sequence. The durability capabilities + * topic announces if a hash string is included in the sampleRequest message. + * When announced a hash string should be included in ALL sampleRequest + * messages, when no hash is calculated the string can be empty. + */ + sampleRequest->filterParams = os_malloc(sizeof(c_string)); + sampleRequest->filterParams[0] = os_strdup(""); + sampleRequest->filterParamsCount = 0; + sampleRequest->maxSamples = -1; + sampleRequest->maxInstances = -1; + sampleRequest->maxSamplesPerInstance = -1; + } + return sampleRequest; +} + + +/** + * Create a copy from a sampleRequest + * + * For backwards compatibility reasons an empty hash is included + * in the target if the originating sampleRequest did not have + * a hash. + */ +d_sampleRequest +d_sampleRequestCopy( + d_sampleRequest request, + c_bool inSharedMemory) +{ + d_sampleRequest copy = NULL; + c_ulong i; + + if (request != NULL) { + copy = d_sampleRequest(os_malloc(C_SIZEOF(d_sampleRequest))); + + /* Copy the message header of the request. + * Make sure to also the copy the productionTimestamp because + * bit 30 encodes how time stamps must be interpreted. This + * knowledge is used to answer the request later on. + */ + d_messageSetAddressee(d_message(copy), &(d_message(request)->addressee)); + d_messageSetSenderAddress(d_message(copy), &(d_message(request)->senderAddress)); + d_message(copy)->productionTimestamp = d_message(request)->productionTimestamp; + d_message(copy)->senderState = d_message(request)->senderState; + + copy->partition = os_strdup(request->partition); + copy->topic = os_strdup(request->topic); + copy->durabilityKind = request->durabilityKind; + copy->requestTime = request->requestTime; + copy->withTimeRange = request->withTimeRange; + copy->beginTime = request->beginTime; + copy->endTime = request->endTime; + copy->source.systemId = request->source.systemId; + copy->source.localId = request->source.localId; + copy->source.lifecycleId = request->source.lifecycleId; + + if(request->filter){ + copy->filter = os_strdup(request->filter); + } else { + copy->filter = NULL; + } + + copy->filterParamsCount = request->filterParamsCount; + /* Create sequence for filters and equalityCheck hash string (+1) */ + copy->filterParams = (c_sequence)os_malloc( + (request->filterParamsCount + 1) * sizeof(c_string)); + for(i=0; ifilterParamsCount; i++){ + copy->filterParams[i] = os_strdup(request->filterParams[i]); + } + /* Add equalityCheck hash string as last entry to filterParams sequence. + * Only do this if the originating request has a hash, otherwise assume + * that the hash is empty (which is interpreted as 'there is no hash') + */ + if (!inSharedMemory || c_arraySize (request->filterParams) > request->filterParamsCount) { + copy->filterParams[copy->filterParamsCount] = os_strdup(request->filterParams[request->filterParamsCount]); + } else { + copy->filterParams[copy->filterParamsCount] = os_strdup(""); + } + copy->maxSamples = request->maxSamples; + copy->maxInstances = request->maxInstances; + copy->maxSamplesPerInstance = request->maxSamplesPerInstance; + } + + return copy; +} + + +void +d_sampleRequestSetCondition( + d_sampleRequest request, + d_readerRequest condition) +{ + c_ulong i; + c_string hash; + + if(request){ + if(request->filter){ + os_free(request->filter); + request->filter = NULL; + } + if(condition->filter){ + request->filter = os_strdup(condition->filter); + } + /* filterParams can never be NULL, because of the equalityCheck hash string */ + assert(request->filterParams); + for(i=0; ifilterParamsCount; i++){ + os_free(request->filterParams[i]); + } + hash = request->filterParams[i]; + os_free(request->filterParams); + + /* filterParams can never be NULL, make sure it never is */ + request->filterParamsCount = condition->filterParamsCount; + /* Create sequence for filters and equalityCheck hash string (+1) */ + request->filterParams = (c_sequence)os_malloc( + (condition->filterParamsCount + 1) * sizeof(c_char*)); + + for(i=0; ifilterParamsCount; i++){ + request->filterParams[i] = os_strdup(condition->filterParams[i]); + } + /* Add equalityCheck hash string as last entry to filterParams sequence */ + request->filterParams[i] = hash; + + request->source.systemId = condition->readerHandle.index; + request->source.localId = condition->readerHandle.serial; + request->source.lifecycleId = 0; + request->withTimeRange = TRUE; + request->beginTime = condition->minSourceTimestamp; + request->endTime = condition->maxSourceTimestamp; + request->maxSamples = condition->resourceLimits.v.max_samples; + request->maxInstances = condition->resourceLimits.v.max_instances; + request->maxSamplesPerInstance = condition->resourceLimits.v.max_samples_per_instance; + } + return; +} + +void +d_sampleRequestSetSource( + d_sampleRequest request, + d_networkAddress source) +{ + if (request && source) { + request->source.systemId = source->systemId; + request->source.localId = source->localId; + request->source.lifecycleId = source->lifecycleId; + } + return; +} + +void +d_sampleRequestSetHash( + d_sampleRequest request, + c_string hash) +{ + if (request) { + assert(request->filterParams); + os_free(request->filterParams[request->filterParamsCount]); + request->filterParams[request->filterParamsCount] = os_strdup(hash); + } + return; +} + +c_bool +d_sampleRequestHasHash( + d_sampleRequest request, + d_fellow fellow) +{ + c_bool set = FALSE; + c_string hash; + + assert(fellow); + + if (request && d_fellowHasCapabilityGroupHash(fellow)) { + assert(request->filterParams); + hash = request->filterParams[request->filterParamsCount]; + if (hash[0] != 0) { + set = TRUE; + } + } + return set; +} + +void +d_sampleRequestFree( + d_sampleRequest sampleRequest) +{ + c_ulong i; + + if(sampleRequest){ + if(sampleRequest->partition){ + os_free(sampleRequest->partition); + } + if(sampleRequest->topic){ + os_free(sampleRequest->topic); + } + if(sampleRequest->filter){ + os_free(sampleRequest->filter); + } + if(sampleRequest->filterParams){ + for(i=0; ifilterParamsCount; i++){ + os_free(sampleRequest->filterParams[i]); + } + os_free(sampleRequest->filterParams[i]); + os_free(sampleRequest->filterParams); + } + d_messageDeinit(d_message(sampleRequest)); + os_free(sampleRequest); + } +} + + +c_bool +d_sampleRequestSpecificReader( + d_sampleRequest request) +{ + c_bool result = FALSE; + d_networkAddress source; + + assert(request); + + if (request) { + source = &request->source; + if (d_networkAddressIsUnaddressed(source) || + (source->systemId == 0)) { + /* The request does not originate from a specific reader */ + result = FALSE; + } else { + /* A specific reader originated the request */ + result = TRUE; + } + } + return result; +} + +c_bool +d_sampleRequestHasCondition( + d_sampleRequest request) +{ + c_bool result = FALSE; + + assert(request); + + if (request) { + if ( (request->filter) || + (!c_timeIsMinInfinite(request->beginTime) && !(c_timeIsZero(request->beginTime) && c_timeIsInfinite(request->endTime))) || + (request->maxInstances != -1) || + (request->maxSamples != -1) || + (request->maxSamplesPerInstance != -1)) { + result = TRUE; + } + } + + return result; +} + + +static c_bool +has_matching_capabilities(d_sampleRequest request1, d_sampleRequest request2) +{ + d_fellow fellow1; + d_fellow fellow2; + d_durability durability = d_threadsDurability(); + d_admin admin = durability->admin; + c_bool result = FALSE; /* Initially no match if one of the fellow do not exist */ + + fellow1 = d_adminGetFellow(admin, &d_message(request1)->senderAddress); + fellow2 = d_adminGetFellow(admin, &d_message(request2)->senderAddress); + + if (fellow1 && fellow2) { + /* Assume match until there is a mismatch */ + result = TRUE; + + /* check hash capability mismatch */ + if (d_fellowHasCapabilityGroupHash(fellow1) != d_fellowHasCapabilityGroupHash(fellow2)) { + + d_trace(D_TRACE_COMBINE_REQUESTS, " %s - no matching group hash\n", OS_FUNCTION); + result = FALSE; + + /* check EOT support mismatch */ + } else if (d_fellowHasCapabilityEOTSupport(fellow1) != d_fellowHasCapabilityEOTSupport(fellow2)) { + d_trace(D_TRACE_COMBINE_REQUESTS, " %s - no matching group eot support\n", OS_FUNCTION); + result = FALSE; + } + } + if (fellow1) { + + d_fellowFree(fellow1); + } + if (fellow2) { + d_fellowFree(fellow2); + } + return result; +} + +/* This function is used to check if two sample requests can be combined + * when the group hash is used by the fellows. + * When the group hash is available in the sample requests then the hash + * values of the sample requests are compared and when they are the same + * the sample requests can be combined. When the fellows do not have + * the group hash capability then the function returns TRUE. + * + * The precondition is that either both fellows have the group hash + * capability or both do not have this. + */ +static c_bool +has_matching_hash_values(d_sampleRequest request1, d_sampleRequest request2) +{ + d_fellow fellow1; + d_fellow fellow2; + d_durability durability = d_threadsDurability(); + d_admin admin = durability->admin; + c_bool result = FALSE; + + fellow1 = d_adminGetFellow(admin, &d_message(request1)->senderAddress); + fellow2 = d_adminGetFellow(admin, &d_message(request2)->senderAddress); + + if (fellow1 && fellow2) { + result = TRUE; + if (d_fellowHasCapabilitySupport(fellow1) && d_fellowHasCapabilityGroupHash(fellow1)) { + c_char *hstr1, *hstr2; + struct d_groupHash hash1, hash2; + + assert(d_fellowHasCapabilitySupport(fellow2)); + assert(d_fellowHasCapabilityGroupHash(fellow2)); + + hstr1 = request1->filterParams[request1->filterParamsCount]; + hstr2 = request2->filterParams[request2->filterParamsCount]; + if (d_groupHashFromString(&hash1, hstr1) && d_groupHashFromString(&hash2, hstr2)) { + result = d_groupHashIsEqual(&hash1, &hash2); + } + } + } + + if (fellow1) { + d_fellowFree(fellow1); + } + if (fellow2) { + d_fellowFree(fellow2); + } + + return result; +} + + +/* Check if sampleRequests can be combined */ +c_bool +d_sampleRequestCanCombine( + d_sampleRequest request1, + d_sampleRequest request2) +{ + assert(request1); + assert(request2); + + /* Check for partition match */ + if (strcmp(request1->partition, request2->partition) != 0) { + return FALSE; + } + /* Check for topic match */ + if (strcmp(request1->topic, request2->topic) != 0) { + return FALSE; + } + /* Check if durabilityKind matches */ + if (request1->durabilityKind != request2->durabilityKind) { + return FALSE; + } + /* Check if source matches */ + if (d_networkAddressCompare(&request1->source, &request2->source) != 0) { + return FALSE; + } + /* Check if filter matches */ + if (compareFilters(request1, request2) != 0) { + d_trace(D_TRACE_COMBINE_REQUESTS, "%s - no matching filter\n", OS_FUNCTION); + return FALSE; + } + /* Check if capabilities match */ + if (!has_matching_capabilities(request1, request2)) { + d_trace(D_TRACE_COMBINE_REQUESTS, "%s - no matching capabilities\n", OS_FUNCTION); + return FALSE; + } + + /* Check if hashes match */ + if (!has_matching_hash_values(request1, request2)) { + d_trace(D_TRACE_COMBINE_REQUESTS, "%s - no matching hash values\n", OS_FUNCTION); + return FALSE; + } + + return TRUE; +} diff --git a/src/services/durability/code/d_sampleRequestListener.c b/src/services/durability/code/d_sampleRequestListener.c new file mode 100644 index 000000000..2f24de48b --- /dev/null +++ b/src/services/durability/code/d_sampleRequestListener.c @@ -0,0 +1,1308 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#include "vortex_os.h" +#include "d__sampleRequestListener.h" +#include "d__configuration.h" +#include "d__fellow.h" +#include "d__listener.h" +#include "d__admin.h" +#include "d__durability.h" +#include "d__actionQueue.h" +#include "d__readerListener.h" +#include "d__publisher.h" +#include "d__misc.h" +#include "d__group.h" +#include "d__thread.h" +#include "d__nameSpace.h" +#include "d_sampleRequest.h" +#include "d_sampleChain.h" +#include "d_message.h" +#include "d_networkAddress.h" +#include "v_group.h" +#include "v_topic.h" +#include "v_builtin.h" +#include "v_time.h" +#include "v_state.h" +#include "v_historicalDataRequest.h" +#include "v_groupInstance.h" +#include "v_entity.h" +#include "v_message.h" /* v_message() */ +#include "v_topic.h" +#include "v_group.h" +#include "kernelModuleI.h" +#include "sd_serializer.h" +#include "sd_serializerBigE.h" +#include "os_heap.h" +#include "os_report.h" +#include "c_misc.h" +#include "v_messageExt.h" +#include "d__groupHash.h" + +/** + * Macro that checks the d_sampleRequestListener validity. + * Because d_sampleRequestListener is a concrete class typechecking is required. + */ +#define d_sampleRequestListenerIsValid(_this) \ + d_listenerIsValidKind(d_listener(_this), D_SAMPLE_REQ_LISTENER) + +/** + * \brief The d_sampleRequestListener cast macro. + * + * This macro casts an object to a d_sampleRequestListener object. + */ +#define d_sampleRequestListener(_this) ((d_sampleRequestListener)(_this)) + +/** + * \brief The d_sampleRequestHelper cast macro. + * + * This macro casts an object to a d_sampleRequestHelper object. + */ +#define d_sampleRequestHelper(h) ((d_sampleRequestHelper)(h)) + +C_STRUCT(d_sampleRequestListener){ + C_EXTENDS(d_readerListener); + c_bool mayProceed; + d_action actor; + d_actionQueue actionQueue; + c_iter requests; +}; + +struct writeBeadHelper{ + c_iter list; + + d_sampleRequest request; + c_ulong count; + c_ulong writeCount; + c_ulong disposeCount; + c_ulong writeDisposeCount; + c_ulong registerCount; + c_ulong unregisterCount; + c_ulong eotCount; + c_ulong skipCount; + c_ulong size; + c_type xmsgType; + sd_serializer serializer; /* serializer for "normal" topic data */ + sd_serializer serializerEOT; /* serializer for EOTs */ + d_sampleChain sampleChain; + d_publisher publisher; + d_networkAddress addressee; + c_bool checkTimeRange; + c_bool isDCPSTopicBuiltinGroup; +}; + +C_STRUCT(d_sampleRequestHelper){ + d_sampleRequestListener listener; + d_sampleRequest request; + c_iter addressees; + os_timeM timeToAct; +}; + +static int +isBuiltinTopicSample( + v_topicInfoTemplate tmpl) +{ + const struct v_topicInfo* data; + data = &tmpl->userData; + assert(strlen(data->name) <= OS_MAX_INTEGER(unsigned)); + return (d_inBuiltinTopicNames(data->name, (unsigned) strlen(data->name)) == 0) ? 0 : 1; +} + + +static void d_traceSampleRequestHelper (d_sampleRequestHelper request) +{ + c_iterIter iter; + d_networkAddress addr; + char str[256], tmp_str[256]; + + str[0] = '\0'; + tmp_str[0] = '\0'; + iter = c_iterIterGet(request->addressees); + while ((addr = (d_networkAddress)c_iterNext(&iter)) != NULL) { + strncpy(tmp_str, str, sizeof(str)); + tmp_str[ (sizeof(tmp_str) - 1) ] = '\0'; /* ensure null-terminated */ + if (strncmp(tmp_str, "\0", sizeof(tmp_str)) == 0) { + snprintf(str, sizeof(str), "%u", addr->systemId); + } else { + snprintf(str, sizeof(str), "%s,%u", tmp_str, addr->systemId); + } + } + d_trace(D_TRACE_COMBINE_REQUESTS, " - request %p for %s.%s, addressees [%s] timeToAct=%"PA_PRItime".\n", + (void *)request, request->request->partition, request->request->topic, str, OS_TIMEM_PRINT(request->timeToAct)); +} + +static void d_traceSampleRequestQueue (c_iter requests) +{ + c_iterIter iter; + d_sampleRequestHelper srh; + + /* print the contents of the queue before */ + d_trace(D_TRACE_COMBINE_REQUESTS, "Sample request queue contents\n"); + iter = c_iterIterGet(requests); + while ((srh = d_sampleRequestHelper(c_iterNext(&iter))) != NULL) { + d_traceSampleRequestHelper(srh); + } +} + +static d_sampleRequestHelper +d_sampleRequestHelperNew( + d_sampleRequestListener listener, + const d_sampleRequest request, + os_timeM timeToAct) +{ + d_sampleRequestHelper helper; + d_networkAddress addr; + + assert(request); + assert(d_sampleRequestListenerIsValid(listener)); + + /* Allocate sampleRequestHelper */ + helper = d_sampleRequestHelper(os_malloc(C_SIZEOF(d_sampleRequestHelper))); + helper->listener = listener; + helper->request = d_sampleRequestCopy(request, TRUE); + helper->timeToAct = timeToAct; + addr = d_networkAddressNew(d_message(request)->senderAddress.systemId, + d_message(request)->senderAddress.localId, + d_message(request)->senderAddress.lifecycleId); + d_messageSetAddressee (d_message(helper->request), addr); + helper->addressees = c_iterNew(addr); + return helper; +} + +static c_bool +request_already_pending (d_sampleRequestHelper found, d_sampleRequest request) +{ + d_networkAddress addressee, senderAddress; + c_iterIter addresseeIter; + c_bool result; + + assert(found); + assert(request); + + senderAddress = d_networkAddressNew(d_message(request)->senderAddress.systemId, d_message(request)->senderAddress.localId, d_message(request)->senderAddress.lifecycleId); + /* Check if the senderAddress of the request is already present in the list of + * addressees. If so, there is not need to target the same recipient + * twice. + */ + addresseeIter = c_iterIterGet(found->addressees); + while ((addressee = d_networkAddress(c_iterNext(&addresseeIter))) != NULL) { + if (d_networkAddressEquals(addressee, senderAddress)) { + break; + } + } + result = (addressee != NULL); + d_networkAddressFree(senderAddress); + return result; +} + +/** + * \brief Add a incoming sampleRequest to the table of pending sampleRequests. + * + * If there already exists a sampleRequest for the same partition/topic and + * from the same source then the requests are combined to save bandwidth. + * The answer to the combined request is send to (0,0,0). + * + * @return Returns NULL if added and the inserted one otherwise. + */ +static d_sampleRequestHelper +d_sampleRequestListenerAddRequest( + d_sampleRequestListener listener, + d_sampleRequest request) +{ + d_sampleRequestHelper found = NULL; + d_networkAddress addr; + os_timeM timeToAct; + d_durability durability; + d_admin admin; + d_configuration config; + d_serviceState state; + os_compare eq; + d_alignerStatistics stats; + c_iterIter requestIter; + c_bool foundExistingRequest; + os_timeW found_beginTime, found_endTime, beginTime, endTime; + + assert(d_sampleRequestListenerIsValid(listener)); + + admin = d_listenerGetAdmin(d_listener(listener)); + durability = d_adminGetDurability(admin); + config = d_durabilityGetConfiguration(durability); + + d_traceSampleRequestQueue(listener->requests); + + if (listener) { + stats = d_alignerStatisticsNew(); + foundExistingRequest = FALSE; + /* Start at the head of the listener->request and traverse the list + * until a pending request has been found for the same partition/topic + * and the same source. If so, update the pending request. If no + * pending request is found then add a new request to the list. + */ + requestIter = c_iterIterGet(listener->requests); + found = d_sampleRequestHelper(c_iterNext(&requestIter)); + + while ((foundExistingRequest == FALSE) && (found != NULL)) { + if (d_sampleRequestCanCombine(found->request, request)) { + /* Only combine if the found request is not already targeted + * to the sender of the request */ + if (!request_already_pending(found, request)) { + /* Combine the request in a single response to + * save bandwidth. Make sure to adjust time slot + */ + d_timestampToTimeW(&found_beginTime, &found->request->beginTime, IS_Y2038READY(found->request)); + d_timestampToTimeW(&found_endTime, &found->request->endTime, IS_Y2038READY(found->request)); + d_timestampToTimeW(&beginTime, &request->beginTime, IS_Y2038READY(request)); + d_timestampToTimeW(&endTime, &request->endTime, IS_Y2038READY(request)); + + eq = os_timeWCompare(endTime, found_endTime); + if (eq == OS_MORE) { + found->request->endTime = request->endTime; + } + if (request->withTimeRange || found->request->withTimeRange) { + eq = os_timeWCompare(beginTime, found_beginTime); + if(eq == OS_LESS) { + found->request->beginTime = request->beginTime; + found->request->withTimeRange = TRUE; + } + } + /* Add the origin of the sampleRequest as the addressee */ + if (c_iterLength(found->addressees) == 1) { + stats->alignerRequestsCombinedOpenDif = 1; + } + addr = d_networkAddressNew( + d_message(request)->senderAddress.systemId, + d_message(request)->senderAddress.localId, + d_message(request)->senderAddress.lifecycleId); + + found->addressees = c_iterInsert(found->addressees, addr); + stats->alignerRequestsCombinedDif = 1; + d_printTimedEvent(durability, D_LEVEL_FINER, + "Sample request for group %s.%s from fellow %u combined with existing request.\n", + request->partition, request->topic, d_message(request)->senderAddress.systemId); + } else { + d_printTimedEvent(durability, D_LEVEL_FINER, + "Sample request for group %s.%s from fellow %u not combined because there already exists a pending request from this fellow.\n", + request->partition, request->topic, d_message(request)->senderAddress.systemId); + } + foundExistingRequest = TRUE; + } else { + found = d_sampleRequestHelper(c_iterNext(&requestIter)); + } + } /* while */ + + if (!found) { + assert(foundExistingRequest == FALSE); + /* No pending sampleRequest already exists, add this one. */ + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Sample request for group %s.%s from fellow %u added to queue.\n", + request->partition, request->topic, d_message(request)->senderAddress.systemId); + state = d_durabilityGetState(durability); + if (state == D_STATE_COMPLETE) { + timeToAct = os_timeMAdd(os_timeMGet(), config->operationalRequestCombinePeriod); + } else { + timeToAct = os_timeMAdd(os_timeMGet(), config->initialRequestCombinePeriod); + } + /* Make sure that DCPSTopics are the first to be aligned when + * it is time to act. + */ + if ((strcmp(request->partition, V_BUILTIN_PARTITION) == 0) && + (strcmp(request->topic, V_TOPICINFO_NAME) == 0)) { + d_sampleRequestHelper first = d_sampleRequestHelper(c_iterObject(listener->requests, 0)); + if (first) { + timeToAct = first->timeToAct; + } + /* Add to the front */ + found = d_sampleRequestHelperNew(listener, request, timeToAct); + listener->requests = c_iterInsert(listener->requests, found); + } else { + /* Add to the back */ + found = d_sampleRequestHelperNew(listener, request, timeToAct); + listener->requests = c_iterAppend(listener->requests, found); + } + found = NULL; + } + stats->alignerRequestsOpenDif = 1; + d_durabilityUpdateStatistics(durability, d_statisticsUpdateAligner, stats); + d_alignerStatisticsFree(stats); + } + + d_traceSampleRequestQueue(listener->requests); + + return found; +} + + +/* When flushing the group, the kernel may return both v_messages and v_registrations. When + * a v_registration is flushed this can indicate a register or an unregister which is + * specified by the flushType. The flushed objects are stored in a temporary list which is + * eventually used to align the samples to other nodes. When the function interpreting this list + * encounters a v_registration it must be able to tell whether this was a register or an unregister. + * That information is stored by using this struct. + */ +typedef struct d_sampleRequestAlignData { + c_object object; /* v_message or v_registration */ + v_groupFlushType flushType; /* MESSAGE, REGISTRATION or UNREGISTRATION */ +}d_sampleRequestAlignData; + + +static c_bool +d_sampleRequestListenerWriteBead( + c_object object, + c_voidp userData) +{ + v_message message; + v_messageEOT messageEOT; + struct writeBeadHelper *data; + c_ulong size; + sd_serializedData serializedData; + + message = (v_message)object; + data = (struct writeBeadHelper*)userData; + + if (v_stateTest(v_nodeState(message), L_ENDOFTRANSACTION)) { + v_messageEOTExt xmsg_eot; + messageEOT = (v_messageEOT)message; + xmsg_eot = v_messageEOTExtCopyToExtType(messageEOT); + serializedData = sd_serializerSerialize(data->serializerEOT, xmsg_eot); + v_messageEOTExtFree (xmsg_eot); + } else { + v_messageExt xmsg; + xmsg = v_messageExtCopyToExtType (data->xmsgType, message); + serializedData = sd_serializerSerialize(data->serializer, xmsg); + v_messageExtFree (xmsg); + } + + if (serializedData != NULL) { + data->count++; + + if((v_stateTest(v_nodeState(message), L_WRITE)) && + (v_stateTest(v_nodeState(message), L_DISPOSED))){ + data->writeDisposeCount++; + } else if(v_stateTest(v_nodeState(message), L_WRITE)){ + data->writeCount++; + } else if(v_stateTest(v_nodeState(message), L_DISPOSED)){ + data->disposeCount++; + } else if(v_stateTest(v_nodeState(message), L_REGISTER)){ + data->registerCount++; + } else if(v_stateTest(v_nodeState(message), L_UNREGISTER)){ + data->unregisterCount++; + } else if(v_stateTest(v_nodeState(message), L_ENDOFTRANSACTION)){ + data->eotCount++; + } + + size = sd_serializedDataGetTotalSize(serializedData); + assert(size <= OS_MAX_INTEGER(c_long)); + + data->size += size; + data->sampleChain->msgBody._d = BEAD; + data->sampleChain->msgBody._u.bead.size = (c_long) size; + data->sampleChain->msgBody._u.bead.value = os_malloc(size); + memcpy(data->sampleChain->msgBody._u.bead.value, serializedData, size); + + d_publisherSampleChainWrite(data->publisher, data->sampleChain, data->addressee); + + os_free(data->sampleChain->msgBody._u.bead.value); + data->sampleChain->msgBody._u.bead.value = NULL; + sd_serializedDataFree(serializedData); + } else { + /*This message will be missed by the fellow.*/ + assert(FALSE); + } + return FALSE; +} + +static c_bool +d_sampleRequestListenerAddList( + c_object object, + v_groupInstance instance, + v_groupFlushType flushType, + c_voidp userData) +{ + v_message message; + v_registration registration; + struct writeBeadHelper *data; + c_bool process; + os_timeW beginTime, endTime; + os_compare timeCompared; + + data = (struct writeBeadHelper*)userData; + + process = TRUE; + + d_timestampToTimeW(&beginTime, &data->request->beginTime, IS_Y2038READY(data->request)); + d_timestampToTimeW(&endTime, &data->request->endTime, IS_Y2038READY(data->request)); + switch(flushType){ + case V_GROUP_FLUSH_REGISTRATION: + registration = (v_registration)object; + if(data->checkTimeRange) { + timeCompared = os_timeWCompare(registration->writeTime, endTime); + + if (timeCompared == OS_MORE) { + process = FALSE; + } else if(instance && strcmp(v_groupName(instance->group), "Group<__BUILT-IN PARTITION__,DCPSTopic>") == 0) { + /* Don't process registrations for DCPSTopic as this would introduce a scalability issue since + * there is always an alive writer per federation. If these registrations would be aligned there + * would be n registrations stored per builtin topic instance where n is the number of + * federations in a system. + * The only condition for aligning a registration is when there are multiple writers + * for the same instance. Therefore this is not an issue for other (builtin) topics. + */ + process = FALSE; + } else if(data->request->withTimeRange == TRUE){ + timeCompared = os_timeWCompare(registration->writeTime, beginTime); + + if (timeCompared == OS_LESS) { + process = FALSE; /* produced before the time-range */ + } + } + } + break; + case V_GROUP_FLUSH_UNREGISTRATION: + registration = (v_registration)object; + if(data->checkTimeRange){ + timeCompared = os_timeWCompare(registration->writeTime, endTime); + + if (timeCompared == OS_MORE) { + process = FALSE; + } else if(data->request->withTimeRange == TRUE){ + timeCompared = os_timeWCompare(registration->writeTime, beginTime); + + if (timeCompared == OS_LESS) { + process = FALSE; /* produced before the time-range */ + } + } + } + break; + case V_GROUP_FLUSH_MESSAGE: + message = (v_message)object; + + if(data->checkTimeRange){ + timeCompared = os_timeWCompare(message->writeTime, endTime); + + if(timeCompared == OS_MORE) { + process = FALSE; + } else if(data->request->withTimeRange == TRUE){ + timeCompared = os_timeWCompare(message->writeTime, beginTime); + + if (timeCompared == OS_LESS) { + process = FALSE; /* produced before the time-range */ + } + } + } + if((process == TRUE) && (data->isDCPSTopicBuiltinGroup == TRUE)){ + if(isBuiltinTopicSample((v_topicInfoTemplate)message)){ + process = FALSE; + } + } + break; + case V_GROUP_FLUSH_TRANSACTION: + message = (v_message)object; + + if(data->checkTimeRange){ + timeCompared = os_timeWCompare(message->writeTime, endTime); + + if(timeCompared == OS_MORE) { + process = FALSE; + } else if(data->request->withTimeRange == TRUE){ + timeCompared = os_timeWCompare(message->writeTime, beginTime); + + if (timeCompared == OS_LESS) { + process = FALSE; /* produced before the time-range */ + } + } + } + break; + default: + process = FALSE; + OS_REPORT(OS_ERROR, "durability::d_sampleRequestListenerAddList", 0, + "Internal error (received unknown message type)"); + break; + } + + if(process == TRUE) { + struct v_groupFlushData *objectData = os_malloc(sizeof(struct v_groupFlushData)); + objectData->object = c_keep(object); + objectData->instance = c_keep(instance); + objectData->flushType = flushType; + data->list = c_iterAppend(data->list, objectData); + } else { + data->skipCount++; + } + return FALSE; +} + +static void +d_sampleRequestListenerAnswer( + d_sampleRequestHelper helper) +{ + d_thread self = d_threadLookupSelf (); + d_admin admin; + d_durability durability; + d_publisher publisher; + d_group group; + struct writeBeadHelper data; + d_sampleChain sampleChain; + c_bool sendData; + v_group vgroup; + v_kernel kernel; + struct v_groupFlushData *objectData; + c_ulong i; + d_networkAddress addr; + d_sampleRequestListener listener; + d_sampleRequest request; + d_alignerStatistics stats; + v_historicalDataRequest vrequest; + v_message vmessage; + v_groupInstance instance; + v_registration registration; + v_resourcePolicyI resourceLimits; + c_char *t, *p; + c_bool equalHash = FALSE; + c_ulong dataListLength = 0; + + listener = helper->listener; + request = helper->request; + admin = d_listenerGetAdmin(d_listener(listener)); + durability = d_adminGetDurability(admin); + publisher = d_adminGetPublisher(admin); + group = d_adminGetLocalGroup(admin, request->partition, + request->topic, request->durabilityKind); + data.count = 0; + data.writeCount = 0; + data.disposeCount = 0; + data.writeDisposeCount = 0; + data.registerCount = 0; + data.unregisterCount = 0; + data.eotCount = 0; + data.skipCount = 0; + data.size = 0; + + /* Determine the addressee. */ + assert(c_iterLength(helper->addressees) != 0); + if (c_iterLength(helper->addressees) == 1) { + d_networkAddress addr = d_networkAddress(c_iterObject(helper->addressees, 0)); + data.addressee = d_networkAddressNew(addr->systemId, addr->localId, addr->lifecycleId); + } else { + data.addressee = d_networkAddressUnaddressed(); + } + sampleChain = d_sampleChainNew(admin, request->partition, request->topic, + request->durabilityKind, &request->source); + + stats = d_alignerStatisticsNew(); + + sampleChain->addresseesCount = c_iterLength(helper->addressees); + sampleChain->addressees = os_malloc(sampleChain->addresseesCount*C_SIZEOF(d_networkAddress)); + addr = d_networkAddress(sampleChain->addressees); + /* Retrieve the targeted addressees from the sampleChain */ + for(i=0; iaddresseesCount; i++) { + addr[i] = *d_networkAddress(c_iterObject(helper->addressees, i)); + } + stats->alignerRequestsAnsweredDif = (sampleChain->addresseesCount); + stats->alignerRequestsOpenDif -= (c_long) (sampleChain->addresseesCount); + + if (sampleChain->addresseesCount > 1) { + stats->alignerRequestsCombinedOpenDif = -1; + stats->alignerRequestsCombinedAnsweredDif = 1; + } + + if(!group){ + /* A request was received for a group that is unknown. + * In that case do not send data, just send a LINK + * indicating that no samples are available. + */ + sendData = FALSE; + } else { + /* Only send the data if it is part of an aligner namespace */ + sendData = d_adminGroupInAlignerNS( + admin, request->partition, + request->topic); + } + d_messageSetAddressee(d_message(sampleChain), data.addressee); + + if (sendData == TRUE) { + /* Collect all data that needs to be sent. */ + vgroup = d_groupGetKernelGroup(group); + kernel = v_objectKernel(vgroup); + data.request = request; + data.sampleChain = sampleChain; + data.publisher = publisher; + data.xmsgType = v_messageExtTypeNew(vgroup->topic); + data.serializer = sd_serializerBigENewTyped(data.xmsgType); + data.serializerEOT = sd_serializerBigENewTyped(c_resolve(c_getBase((c_object)vgroup), "kernelModule::v_messageEOTExt")); + data.list = c_iterNew(NULL); + data.isDCPSTopicBuiltinGroup = FALSE; + + p = v_entity(vgroup->partition)->name; + t = v_entity(vgroup->topic)->name; + + if((strlen(p) == strlen(V_BUILTIN_PARTITION)) && + (strlen(t) == strlen(V_TOPICINFO_NAME))){ + if(strncmp(p, V_BUILTIN_PARTITION, strlen(V_BUILTIN_PARTITION)) == 0){ + if(strncmp(t, V_TOPICINFO_NAME, strlen(V_TOPICINFO_NAME)) == 0){ + data.isDCPSTopicBuiltinGroup = TRUE; + } + } + } + if (d_sampleRequestSpecificReader(request)) { + /* This a request that originates from a reader */ + if (!d_sampleRequestHasCondition(request)) { + /* This is an alignment request without any condition. + * align all samples in this case + */ + d_printTimedEvent(durability, D_LEVEL_FINE, + "Sending all samples for group %s.%s to fellow %u using source (%u,%u,%u).\n", + request->partition, request->topic, + data.addressee->systemId, + request->source.systemId, + request->source.localId, + request->source.lifecycleId); + data.checkTimeRange = TRUE; + v_kernelGroupTransactionBeginAccess(kernel); + v_groupFlushAction(vgroup, d_sampleRequestListenerAddList, &data); + v_kernelGroupTransactionEndAccess(kernel); + } else { + d_printTimedEvent(durability, D_LEVEL_FINE, + "Sending conditional set of samples for group %s.%s to fellow %u.\n", + request->partition, request->topic, + data.addressee->systemId); + data.checkTimeRange = FALSE; + + resourceLimits.v.max_samples = request->maxSamples; + resourceLimits.v.max_instances = request->maxInstances; + resourceLimits.v.max_samples_per_instance = request->maxSamplesPerInstance; + + vrequest = v_historicalDataRequestNew( + kernel, + request->filter, + (const c_char**)request->filterParams, + request->filterParamsCount, + c_timeToTimeW(request->beginTime), + c_timeToTimeW(request->endTime), + &resourceLimits, + OS_DURATION_ZERO); + + (void)d_shmAllocAssert(vrequest, "Allocation of historicalDataRequest failed."); + + v_groupFlushActionWithCondition( + vgroup, vrequest, d_sampleRequestListenerAddList, &data); + + c_free(vrequest); + } + } else if (request->filter != NULL) { + /* This is a normal alignment request with a static content filter. */ + d_printTimedEvent(durability, D_LEVEL_FINE, + "Sending samples for group '%s.%s' to fellow %u that match filter expression '%s'.\n", + request->partition, request->topic, + data.addressee->systemId, + request->filter); + data.checkTimeRange = FALSE; + + resourceLimits.v.max_samples = request->maxSamples; + resourceLimits.v.max_instances = request->maxInstances; + resourceLimits.v.max_samples_per_instance = request->maxSamplesPerInstance; + + vrequest = v_historicalDataRequestNew( + kernel, + request->filter, + (const c_char**)request->filterParams, + request->filterParamsCount, + c_timeToTimeW(request->beginTime), + c_timeToTimeW(request->endTime), + &resourceLimits, + OS_DURATION_ZERO); + + (void)d_shmAllocAssert(vrequest, "Allocation of historicalDataRequest failed."); + + v_groupFlushActionWithCondition( + vgroup, vrequest, d_sampleRequestListenerAddList, &data); + + c_free(vrequest); + } else { + /* This is an alignment request without any filter. + * align all samples in this case + */ + d_printTimedEvent(durability, D_LEVEL_FINE, + "Sending all samples for group %s.%s to fellow %u using source (%u,%u,%u).\n", + request->partition, request->topic, + data.addressee->systemId, + request->source.systemId, + request->source.localId, + request->source.lifecycleId); + data.checkTimeRange = TRUE; + v_kernelGroupTransactionBeginAccess(kernel); + v_groupFlushAction(vgroup, d_sampleRequestListenerAddList, &data); + v_kernelGroupTransactionEndAccess(kernel); + } + + c_free(vgroup); + + /* Compare the group hash of the sender with the local one. + * Note that for combined requests (senderAddress 0,0,0) hash checking is skipped. + */ + if (!d_networkAddressIsUnaddressed(d_messageGetAddressee(d_message(sampleChain)))) { + d_fellow fellow = d_adminGetFellow(admin, &(d_message(request)->senderAddress)); + + if (fellow) { + if (d_fellowHasCapabilitySupport(fellow) && + d_fellowHasCapabilityGroupHash(fellow)) { + c_char *hash; + struct d_groupHash senderGroupHash; + struct d_groupHash groupHash; + + hash = request->filterParams[request->filterParamsCount]; + if (d_groupHashFromString(&senderGroupHash, hash) == TRUE) { + dataListLength = c_iterLength(data.list); + if (dataListLength != senderGroupHash.nrSamples) { + d_groupHashCalculate(&groupHash, data.list); + equalHash = d_groupHashIsEqual(&senderGroupHash, &groupHash); + } + } + } + d_fellowFree(fellow); + } + } + + /* The data to send is collected in data.list. + * Now write the beads. + */ + objectData = c_iterTakeFirst(data.list); + while (objectData) { + d_threadAwake (self); + instance = objectData->instance; + + /* Only write beads when hash is unequal */ + if (!equalHash) { + switch(objectData->flushType) { + case V_GROUP_FLUSH_REGISTRATION: + case V_GROUP_FLUSH_UNREGISTRATION: + /* Registration or unregistration */ + registration = (v_registration)objectData->object; + vmessage = v_groupInstanceCreateMessage(instance); + if (vmessage) { + vmessage->writerGID = registration->writerGID; + vmessage->qos = c_keep(registration->qos); + vmessage->writeTime = registration->writeTime; + vmessage->sequenceNumber = registration->sequenceNumber; + if (objectData->flushType == V_GROUP_FLUSH_REGISTRATION) { + v_stateSet(v_nodeState(vmessage), L_REGISTER); + } else if(objectData->flushType == V_GROUP_FLUSH_UNREGISTRATION) { + v_stateSet(v_nodeState(vmessage), L_UNREGISTER); + } + if (v_stateTest(registration->state, L_IMPLICIT) == TRUE) { + v_stateSet(v_nodeState(vmessage), L_IMPLICIT); + } + d_sampleRequestListenerWriteBead(vmessage, &data); + c_free(vmessage); + } else { + d_printTimedEvent(durability, D_LEVEL_SEVERE, + "Failed to allocate message, alignment for group %s.%s to fellow %u will be incomplete.\n", + request->partition, request->topic, + d_message(request)->senderAddress.systemId); + OS_REPORT(OS_ERROR, + "durability::d_sampleRequestListenerAnswer", 0, + "Failed to allocate message, alignment will be incomplete"); + (void)d_shmAllocAssert(vmessage, "Allocation of sample failed."); + } + break; + case V_GROUP_FLUSH_MESSAGE: + /* Normal data */ + vmessage = v_message(objectData->object); + assert(vmessage != NULL); + + if (c_getType(vmessage) != v_kernelType(kernel, K_MESSAGE)) { + d_sampleRequestListenerWriteBead(vmessage, &data); + } else { + /* If the message is a mini-message without keys, temporarily replace it with + * a typed message that does include the keys. That way the bead becomes self- + * describing and so the receiving node can deduct its instance again. + */ + v_message msg= v_groupInstanceCreateTypedInvalidMessage(instance, vmessage); + if (msg) { + d_sampleRequestListenerWriteBead(msg, &data); + c_free(msg); + } else { + d_printTimedEvent(durability, D_LEVEL_SEVERE, + "Failed to allocate message, alignment for group %s.%s to fellow %u will be incomplete.\n", + request->partition, request->topic, + d_message(request)->senderAddress.systemId); + OS_REPORT(OS_ERROR, + "durability::d_sampleRequestListenerAnswer", 0, + "Failed to allocate message, alignment will be incomplete"); + (void)d_shmAllocAssert(msg, "Allocation of sample failed."); + } + } + break; + case V_GROUP_FLUSH_TRANSACTION: + /* Normal data */ + vmessage = v_message(objectData->object); + d_sampleRequestListenerWriteBead(vmessage, &data); + break; + default: + assert(0); + break; + } + } + c_free(instance); + c_free(objectData->object); + os_free(objectData); + objectData = c_iterTakeFirst(data.list); + } /* while */ + c_iterFree(data.list); + v_messageExtTypeFree (data.xmsgType); + sd_serializerFree(data.serializer); + sd_serializerFree(data.serializerEOT); + } else { + d_printTimedEvent(durability, D_LEVEL_FINE, + "Sending no samples for group %s.%s to fellow %u.\n", + request->partition, request->topic, + d_message(request)->senderAddress.systemId); + } + /* Send a LINK */ + sampleChain->msgBody._d = LINK; + sampleChain->msgBody._u.link.nrSamples = data.count; + + if (group) { + sampleChain->msgBody._u.link.completeness = d_groupGetCompleteness(group); + if (equalHash) { + sampleChain->msgBody._u.link.nrSamples = D_GROUP_IS_EQUAL; + } + } else { + sampleChain->msgBody._u.link.completeness = D_GROUP_UNKNOWN; + } + d_publisherSampleChainWrite(publisher, sampleChain, data.addressee); + + if (equalHash) { + c_ulong skipCount = 0; + d_printTimedEvent(durability, D_LEVEL_FINE, + "Group %s.%s (with %u samples) equal to fellow %u (%d fellows total), no samples sent.\n", + request->partition, request->topic, dataListLength, + data.addressee->systemId, + sampleChain->addresseesCount); + skipCount += data.writeCount; + skipCount += data.disposeCount; + skipCount += data.writeDisposeCount; + skipCount += data.registerCount; + skipCount += data.unregisterCount; + skipCount += data.eotCount; + skipCount += data.skipCount; + d_printTimedEvent(durability, D_LEVEL_FINE, + "WRITE: 0, DISPOSED: 0, WRITE_DISPOSED: 0, REGISTER: 0, UNREGISTER:0, EOT: 0 (SKIPPED: %d)\n", + skipCount); + } else { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Sent %d samples for group %s.%s to fellow %u (%d fellows total).\n", + data.count, request->partition, request->topic, + data.addressee->systemId, + sampleChain->addresseesCount); + d_printTimedEvent(durability, D_LEVEL_FINE, + "WRITE: %d, DISPOSED: %d, WRITE_DISPOSED: %d, REGISTER: %d, UNREGISTER: %d EOT: %d (SKIPPED: %d)\n", + data.writeCount, data.disposeCount, data.writeDisposeCount, + data.registerCount, data.unregisterCount, data.eotCount, data.skipCount); + /* Update the statistics */ + stats->alignerSamplesTotalDif = data.count; + stats->alignerSamplesRegisterDif = data.registerCount; + stats->alignerSamplesWriteDif = data.writeCount; + stats->alignerSamplesDisposeDif = data.disposeCount; + stats->alignerSamplesWriteDisposeDif = data.writeDisposeCount; + stats->alignerSamplesUnregisterDif = data.unregisterCount; + stats->alignerTotalSizeDif = data.size; + + } + + d_sampleChainFree(sampleChain); + d_networkAddressFree(data.addressee); + d_durabilityUpdateStatistics(durability, d_statisticsUpdateAligner, stats); + d_alignerStatisticsFree(stats); + + return; +} + + +static void +d_sampleRequestHelperFree( + d_sampleRequestHelper helper) +{ + d_networkAddress addr; + + assert(helper); + + /* The sampleRequestHelper does not inherit from + * d_object, so there is no deinit to call. Simply + * deallocate all stuff that was allocated in + * d_sampleRequestHelperNew. + */ + if (helper->request) { + d_sampleRequestFree(helper->request); + } + /* Clean all addresses */ + addr = d_networkAddress(c_iterTakeFirst(helper->addressees)); + while (addr){ + d_networkAddressFree(addr); + addr = d_networkAddress(c_iterTakeFirst(helper->addressees)); + } + c_iterFree(helper->addressees); + os_free(helper); +} + +/** + * \brief Send responses to pending sampleRequests whose timeToAct has expired + */ +static c_bool +sendAction( + d_action action, + c_bool terminate) +{ + d_thread self = d_threadLookupSelf (); + d_sampleRequestHelper helper = NULL; + d_admin admin; + d_durability durability; + d_sampleRequestListener listener; + d_serviceState state; + os_timeM currentTime; + c_bool mightHaveNext; + + listener = d_sampleRequestListener(d_actionGetArgs(action)); + if (d_objectIsValid(d_object(listener), D_LISTENER)) { + if (terminate == FALSE) { + d_listenerLock(d_listener(listener)); + admin = d_listenerGetAdmin(d_listener(listener)); + durability = d_adminGetDurability(admin); + if (listener->mayProceed == FALSE) { + state = d_durabilityGetState(durability); + if ((state != D_STATE_INIT) && + (state != D_STATE_DISCOVER_FELLOWS_GROUPS) && + (state != D_STATE_DISCOVER_LOCAL_GROUPS) && + (state != D_STATE_DISCOVER_PERSISTENT_SOURCE) && + (state != D_STATE_INJECT_PERSISTENT) && + (state != D_STATE_TERMINATING) && + (state != D_STATE_TERMINATED)) { + /* Only if the state of the durability service has + * progressed 'far enough' it is allowed to send + * responses to a sampleRequest. + */ + listener->mayProceed = TRUE; + } + } + if (listener->mayProceed == TRUE) { + mightHaveNext = TRUE; + + do { + currentTime = os_timeMGet(); + d_threadAwake(self); + helper = d_sampleRequestHelper(c_iterTakeFirst(listener->requests)); + + if(helper != NULL){ + if (os_timeMCompare(helper->timeToAct, currentTime) != OS_MORE) { + c_iterIter iter; + d_networkAddress addr; + char str[256], tmp_str[256]; + + str[0] = '\0'; + tmp_str[0] = '\0'; + iter = c_iterIterGet(helper->addressees); + while ((addr = (d_networkAddress)c_iterNext(&iter)) != NULL) { + strncpy(tmp_str, str, sizeof(str)); + if (strncmp(tmp_str, "\0", sizeof(tmp_str)) == 0) { + snprintf(str, sizeof(str), "%u", addr->systemId); + } else { + snprintf(str, sizeof(str), "%s,%u", tmp_str, addr->systemId); + } + } + + d_printTimedEvent(durability, D_LEVEL_FINER, + "Now sending data for group %s.%s to %d fellow(s) [%s].\n", + helper->request->partition, + helper->request->topic, + c_iterLength(helper->addressees), + str); + + /* Send the answer to the request */ + d_lockUnlock(d_lock(listener)); + d_sampleRequestListenerAnswer(helper); + d_lockLock(d_lock(listener)); + + d_sampleRequestHelperFree(helper); + } else { + /* No time to act yet, so prepend taken action again */ + listener->requests = c_iterInsert(listener->requests, helper); + mightHaveNext = FALSE; + } + } else { + mightHaveNext = FALSE; + } + } while(!d_durabilityMustTerminate(durability) && (mightHaveNext == TRUE)); + } + d_lockUnlock(d_lock(listener)); + } + } + return TRUE; +} + + +static void +d_sampleRequestListenerDeinit( + d_sampleRequestListener listener) +{ + d_sampleRequestHelper helper; + c_bool removed; + + assert(d_sampleRequestListenerIsValid(listener)); + + /* Stop the sampleRequestListener before cleaning up. */ + d_sampleRequestListenerStop(listener); + /* Clean up stuff that was allocated */ + removed = d_actionQueueRemove(listener->actionQueue, listener->actor); + if (removed == TRUE) { + d_actionFree(listener->actor); + } + d_actionQueueFree(listener->actionQueue); + /* Clean up pending requests */ + d_lockLock(d_lock(listener)); + helper = d_sampleRequestHelper(c_iterTakeFirst(listener->requests)); + while (helper) { + d_sampleRequestHelperFree(helper); + helper = d_sampleRequestHelper(c_iterTakeFirst(listener->requests)); + } + c_iterFree(listener->requests); + d_lockUnlock(d_lock(listener)); + /* Call super-deinit */ + d_readerListenerDeinit(d_readerListener(listener)); +} + +static void +d_sampleRequestListenerAction( + d_listener listener, + d_message message) +{ + d_durability durability; + d_admin admin; + d_sampleRequest request; + d_sampleChain sampleChain; + d_networkAddress addr, addr1, addressee; + d_publisher publisher; + d_configuration config; + d_fellow fellow; + d_alignerStatistics stats; + d_name fellowRole; + + assert(d_sampleRequestListenerIsValid(listener)); + + admin = d_listenerGetAdmin(listener); + durability = d_adminGetDurability(admin); + request = d_sampleRequest(message); + publisher = d_adminGetPublisher(admin); + addr = d_networkAddressNew( + message->senderAddress.systemId, + message->senderAddress.localId, + message->senderAddress.lifecycleId); + fellow = d_adminGetFellow(admin, addr); + + fellowRole = d_fellowGetRole(fellow); + config = d_durabilityGetConfiguration(durability); + addressee = d_networkAddressNew( + message->addressee.systemId, + message->addressee.localId, + message->addressee.lifecycleId); + stats = d_alignerStatisticsNew(); + + stats->alignerRequestsReceivedDif = 1; + + if ( (!fellow) || + (d_fellowGetCommunicationState(fellow) == D_COMMUNICATION_STATE_INCOMPATIBLE_STATE) || + (d_fellowGetCommunicationState(fellow) == D_COMMUNICATION_STATE_INCOMPATIBLE_DATA_MODEL)) { + d_printTimedEvent(durability, D_LEVEL_FINE, + "Ignoring sample request for group %s.%s from fellow %u using source (%u,%u,%u)\n", + request->partition, request->topic, + d_message(request)->senderAddress.systemId, + request->source.systemId, + request->source.localId, + request->source.lifecycleId); + + /* Send immediately a LINK message containing 0 samples to + * prevent that the requester keeps waiting. */ + sampleChain = d_sampleChainNew(admin, request->partition, + request->topic, request->durabilityKind, + &request->source); + /* Add the recipient to the link */ + sampleChain->addresseesCount = 1; + sampleChain->addressees = os_malloc(C_SIZEOF(d_networkAddress)); + addr1 = d_networkAddress(sampleChain->addressees); + addr1[0] = *d_networkAddress(addr); + + d_messageSetAddressee(d_message(sampleChain), addr); + + sampleChain->msgBody._d = LINK; + sampleChain->msgBody._u.link.nrSamples = 0; + if (!fellow) { + /* The fellow is not known, so there might non-symmetric + * communication. To let the fellow know that I don't know + * him I sent D_GROUP_KNOWLEDGE_UNDEFINED. This may be + * used by the recipient to act on the non-symmetrical + * communication situation, e.g., by removing me as fellow. + */ + sampleChain->msgBody._u.link.completeness = D_GROUP_KNOWLEDGE_UNDEFINED; + } else { + sampleChain->msgBody._u.link.completeness = D_GROUP_UNKNOWN; + } + d_publisherSampleChainWrite(publisher, sampleChain, addr); + d_sampleChainFree(sampleChain); + + stats->alignerRequestsIgnoredDif = 1; + + if (fellow) { + d_fellowFree(fellow); + } + } + /* If this request was sent to everyone, it is meant for everyone with + * the same role as the role of the sender. Therefore ignore + * the request if my role is not the same as the role of the sender + */ + else if (d_networkAddressIsUnaddressed(addressee) + && fellowRole && strcmp(config->role, fellowRole) != 0) { + d_printTimedEvent(durability, D_LEVEL_FINE, + "Received sample request for group %s.%s from fellow %u %susing source (%u,%u,%u), but " + "my role is '%s' whereas the role of the sender is '%s'. " + "Therefore the request is not meant for me and I am ignoring " + "this request.\n", + request->partition, request->topic, + d_message(request)->senderAddress.systemId, + d_sampleRequestHasHash(request, fellow) ? "with hash " : "", + request->source.systemId, + request->source.localId, + request->source.lifecycleId, + config->role, fellowRole); + d_fellowFree(fellow); + } else { + /* I must respond to the sampleRequest. Let's queue the + * request so it can be handled later. + */ + if (request->filter) { + d_printTimedEvent(durability, D_LEVEL_FINE, + "Received sample request for group %s.%s from fellow %u %susing source (%u,%u,%u) using filter expression '%s', adding it to queue.\n", + request->partition, request->topic, + d_message(request)->senderAddress.systemId, + d_sampleRequestHasHash(request, fellow) ? "with hash " : "", + request->source.systemId, + request->source.localId, + request->source.lifecycleId, + request->filter); + } else { + d_printTimedEvent(durability, D_LEVEL_FINE, + "Received sample request for group %s.%s from fellow %u %susing source (%u,%u,%u), adding it to queue.\n", + request->partition, request->topic, + d_message(request)->senderAddress.systemId, + d_sampleRequestHasHash(request, fellow) ? "with hash " : "", + request->source.systemId, + request->source.localId, + request->source.lifecycleId); + } + d_sampleRequestListenerAddRequest(d_sampleRequestListener(listener), request); + d_fellowFree(fellow); + } + d_durabilityUpdateStatistics(durability, d_statisticsUpdateAligner, stats); + d_alignerStatisticsFree(stats); + d_networkAddressFree(addressee); + d_networkAddressFree(addr); + + return; +} + +static void +d_sampleRequestListenerInit( + d_sampleRequestListener listener, + d_subscriber subscriber) +{ + os_duration sleepTime = OS_DURATION_INIT(0, 50000000); /* 50 ms */ + d_admin admin; + d_durability durability; + d_configuration config; + + /* Do not assert the listener because the initialization + * of the listener has not yet completed + */ + + assert(d_subscriberIsValid(subscriber)); + + admin = d_subscriberGetAdmin(subscriber); + assert(d_adminIsValid(admin)); + durability = d_adminGetDurability(admin); + assert(d_durabilityIsValid(durability)); + config = d_durabilityGetConfiguration(durability); + assert(d_configurationIsValid(config)); + + /* Call super-init */ + d_readerListenerInit( d_readerListener(listener), + D_SAMPLE_REQ_LISTENER, + d_sampleRequestListenerAction, + subscriber, + D_SAMPLE_REQ_TOPIC_NAME, + D_SAMPLE_REQ_TOP_NAME, + V_RELIABILITY_RELIABLE, + V_HISTORY_KEEPALL, + V_LENGTH_UNLIMITED, + config->alignerScheduling, + (d_objectDeinitFunc)d_sampleRequestListenerDeinit); + /* Initialize the sampleRequestListener */ + listener->mayProceed = FALSE; + listener->requests = c_iterNew(NULL); + listener->actionQueue = d_actionQueueNew("sampleRequestHandler", sleepTime, config->alignerScheduling); + listener->actor = d_actionNew(os_timeMGet(), sleepTime, sendAction, listener); + d_actionQueueAdd(listener->actionQueue, listener->actor); +} + +d_sampleRequestListener +d_sampleRequestListenerNew( + d_subscriber subscriber) +{ + d_sampleRequestListener listener; + + assert(d_subscriberIsValid(subscriber)); + + /* Allocate sampleRequestListener object */ + listener = d_sampleRequestListener(os_malloc(C_SIZEOF(d_sampleRequestListener))); + if (listener) { + /* Initialize the sampleRequestListener */ + d_sampleRequestListenerInit(listener, subscriber); + } + return listener; +} + +void +d_sampleRequestListenerFree( + d_sampleRequestListener listener) +{ + assert(d_sampleRequestListenerIsValid(listener)); + + d_objectFree(d_object(listener)); +} + + +c_bool +d_sampleRequestListenerStart( + d_sampleRequestListener listener) +{ + assert(d_sampleRequestListenerIsValid(listener)); + + return d_readerListenerStart(d_readerListener(listener)); +} + +c_bool +d_sampleRequestListenerStop( + d_sampleRequestListener listener) +{ + return d_readerListenerStop(d_readerListener(listener)); +} diff --git a/src/services/durability/code/d_statistics.c b/src/services/durability/code/d_statistics.c new file mode 100644 index 000000000..44aca37a2 --- /dev/null +++ b/src/services/durability/code/d_statistics.c @@ -0,0 +1,421 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#include "d__statistics.h" +#include "d__types.h" +#include "d__admin.h" +#include "d__nameSpace.h" +#include "d__groupCreationQueue.h" +#include "v_maxValue.h" +#include "os_heap.h" + +d_aligneeStatistics +d_aligneeStatisticsNew() +{ + d_aligneeStatistics s; + + /* Allocate aligneeStatistics object */ + s = d_aligneeStatistics(os_malloc(C_SIZEOF(d_aligneeStatistics))); + if (s) { + /* Call super-init */ + d_objectInit(d_object(s), D_ALIGNEE_STATS, + (d_objectDeinitFunc)d_aligneeStatisticsDeinit); + /* Inititialize aligneeStatistics */ + s->aligneeRequestsWaiting = 0; + s->aligneeRequestsSentDif = 0; + s->aligneeRequestsOpenDif = 0; + s->aligneeSamplesTotalDif = 0; + s->aligneeSamplesRegisterDif = 0; + s->aligneeSamplesWriteDif = 0; + s->aligneeSamplesDisposeDif = 0; + s->aligneeSamplesWriteDisposeDif = 0; + s->aligneeSamplesUnregisterDif = 0; + s->aligneeTotalSizeDif = 0; + } + return s; +} + + +void +d_aligneeStatisticsDeinit( + d_aligneeStatistics stats) +{ + assert(d_aligneeStatisticsIsValid(stats)); + + /* Nothing to deallocate */ + /* Call super-deinit */ + d_objectDeinit(d_object(stats)); +} + + +void +d_aligneeStatisticsFree( + d_aligneeStatistics stats) +{ + + assert(d_aligneeStatisticsIsValid(stats)); + + d_objectFree(d_object(stats)); +} + +void +d_statisticsUpdateAlignee( + v_durabilityStatistics s, + c_voidp args) +{ + d_aligneeStatistics as = d_aligneeStatistics(args); + + if(s && args){ + s->aligneeRequestsWaiting = as->aligneeRequestsWaiting; + v_maxValueSetValue(&s->aligneeRequestsWaitingMax, s->aligneeRequestsWaiting); + + if(as->aligneeRequestsSentDif != 0){ + s->aligneeRequestsSent += as->aligneeRequestsSentDif; + } + if(as->aligneeRequestsOpenDif != 0){ + if (as->aligneeRequestsOpenDif >= 0) { + s->aligneeRequestsOpen += (c_ulong) as->aligneeRequestsOpenDif; + } else { + s->aligneeRequestsOpen -= (c_ulong) -as->aligneeRequestsOpenDif; + } + v_maxValueSetValue(&s->aligneeRequestsOpenMax, s->aligneeRequestsOpen); + } + if(as->aligneeSamplesTotalDif != 0){ + s->aligneeSamplesTotal += as->aligneeSamplesTotalDif; + } + if(as->aligneeSamplesRegisterDif != 0){ + s->aligneeSamplesRegister += as->aligneeSamplesRegisterDif; + } + if(as->aligneeSamplesWriteDif != 0){ + s->aligneeSamplesWrite += as->aligneeSamplesWriteDif; + } + if(as->aligneeSamplesDisposeDif != 0){ + s->aligneeSamplesDispose += as->aligneeSamplesDisposeDif; + } + if(as->aligneeSamplesWriteDisposeDif != 0){ + s->aligneeSamplesWriteDispose += as->aligneeSamplesWriteDisposeDif; + } + if(as->aligneeSamplesUnregisterDif != 0){ + s->aligneeSamplesUnregister += as->aligneeSamplesUnregisterDif; + } + if(as->aligneeTotalSizeDif != 0){ + s->aligneeTotalSize += as->aligneeTotalSizeDif; + } + } + return; +} + + +d_alignerStatistics +d_alignerStatisticsNew() +{ + d_alignerStatistics s; + /* Allocate alignerStatistics object */ + s = os_malloc(C_SIZEOF(d_alignerStatistics)); + /* Call super-init */ + d_objectInit(d_object(s), D_ALIGNER_STATS, + (d_objectDeinitFunc)d_alignerStatisticsDeinit); + /* Initialize alignerStatistics */ + s->alignerRequestsReceivedDif = 0; + s->alignerRequestsIgnoredDif = 0; + s->alignerRequestsAnsweredDif = 0; + s->alignerRequestsOpenDif = 0; + s->alignerRequestsCombinedDif = 0; + s->alignerRequestsCombinedOpenDif = 0; + s->alignerRequestsCombinedAnsweredDif = 0; + s->alignerSamplesTotalDif = 0; + s->alignerSamplesRegisterDif = 0; + s->alignerSamplesWriteDif = 0; + s->alignerSamplesDisposeDif = 0; + s->alignerSamplesWriteDisposeDif = 0; + s->alignerSamplesUnregisterDif = 0; + s->alignerTotalSizeDif = 0; + return s; +} + + +void +d_alignerStatisticsDeinit( + d_alignerStatistics stats) +{ + assert(d_alignerStatisticsIsValid(stats)); + + /* Nothing to deallocate */ + /* Call super-deinit */ + d_objectDeinit(d_object(stats)); +} + + +void +d_alignerStatisticsFree( + d_alignerStatistics stats) +{ + assert(d_alignerStatisticsIsValid(stats)); + + d_objectFree(d_object(stats)); +} + +static c_ulong add_dif_to_total (c_ulong total, c_long dif) +{ + if (dif >= 0) { + return total + (c_ulong) dif; + } else { + return total - (c_ulong) -dif; + } +} + +void +d_statisticsUpdateAligner( + v_durabilityStatistics ds, + c_voidp args) +{ + d_alignerStatistics s = d_alignerStatistics(args); + + if(s->alignerRequestsReceivedDif != 0){ + ds->alignerRequestsReceived += s->alignerRequestsReceivedDif; + } + if(s->alignerRequestsIgnoredDif != 0){ + ds->alignerRequestsIgnored += s->alignerRequestsIgnoredDif; + } + if(s->alignerRequestsAnsweredDif != 0){ + ds->alignerRequestsAnswered += s->alignerRequestsAnsweredDif; + } + if(s->alignerRequestsOpenDif != 0){ + ds->alignerRequestsOpen = add_dif_to_total(ds->alignerRequestsOpen, s->alignerRequestsOpenDif); + v_maxValueSetValue(&ds->alignerRequestsOpenMax, ds->alignerRequestsOpen); + } + if(s->alignerRequestsCombinedDif != 0){ + ds->alignerRequestsCombined += s->alignerRequestsCombinedDif; + } + if(s->alignerRequestsCombinedOpenDif != 0){ + ds->alignerRequestsCombinedOpen = add_dif_to_total(ds->alignerRequestsCombinedOpen, s->alignerRequestsCombinedOpenDif); + v_maxValueSetValue(&ds->alignerRequestsCombinedOpenMax, ds->alignerRequestsCombinedOpen); + } + if(s->alignerRequestsCombinedAnsweredDif != 0){ + ds->alignerRequestsCombinedAnswered += s->alignerRequestsCombinedAnsweredDif; + } + if(s->alignerSamplesTotalDif != 0){ + ds->alignerSamplesTotal += s->alignerSamplesTotalDif; + } + if(s->alignerSamplesRegisterDif != 0){ + ds->alignerSamplesRegister += s->alignerSamplesRegisterDif; + } + if(s->alignerSamplesWriteDif != 0){ + ds->alignerSamplesWrite += s->alignerSamplesWriteDif; + } + if(s->alignerSamplesDisposeDif != 0){ + ds->alignerSamplesDispose += s->alignerSamplesDisposeDif; + } + if(s->alignerSamplesWriteDisposeDif != 0){ + ds->alignerSamplesWriteDispose += s->alignerSamplesWriteDisposeDif; + } + if(s->alignerSamplesUnregisterDif != 0){ + ds->alignerSamplesUnregister += s->alignerSamplesUnregisterDif; + } + if(s->alignerTotalSizeDif != 0){ + ds->alignerTotalSize += s->alignerTotalSizeDif; + } + return; +} + +void +d_statisticsUpdateAdmin( + v_durabilityStatistics statistics, + c_voidp args) +{ + d_adminStatisticsInfo info = d_adminStatisticsInfo(args); + + if(info && statistics){ + if(info->kind == D_ADMIN_STATISTICS_FELLOW){ + if(info->fellowsKnownDif != 0){ + statistics->fellowsKnown = add_dif_to_total(statistics->fellowsKnown, info->fellowsKnownDif); + v_maxValueSetValue(&statistics->fellowsKnownMax, statistics->fellowsKnown); + } + if(info->fellowsApprovedDif != 0){ + statistics->fellowsApproved = add_dif_to_total(statistics->fellowsApproved, info->fellowsApprovedDif); + } + if(info->fellowsIncompatibleStateDif != 0){ + statistics->fellowsIncompatibleState = add_dif_to_total(statistics->fellowsIncompatibleState, info->fellowsIncompatibleStateDif); + } + if(info->fellowsIncompatibleDataModelDif != 0){ + statistics->fellowsIncompatibleDataModel = add_dif_to_total(statistics->fellowsIncompatibleDataModel, info->fellowsIncompatibleDataModelDif); + } + } else if(info->kind == D_ADMIN_STATISTICS_GROUP){ + if(info->groupsKnownVolatileDif != 0){ + statistics->groupsKnownVolatile = add_dif_to_total(statistics->groupsKnownVolatile, info->groupsKnownVolatileDif); + statistics->groupsKnownTotal = add_dif_to_total(statistics->groupsKnownTotal, info->groupsKnownVolatileDif); + } + if(info->groupsKnownTransientDif != 0){ + statistics->groupsKnownTransient = add_dif_to_total(statistics->groupsKnownTransient, info->groupsKnownTransientDif); + statistics->groupsKnownTotal = add_dif_to_total(statistics->groupsKnownTotal, info->groupsKnownTransientDif); + } + if(info->groupsKnownPersistentDif != 0){ + statistics->groupsKnownPersistent = add_dif_to_total(statistics->groupsKnownPersistent, info->groupsKnownPersistentDif); + statistics->groupsKnownTotal = add_dif_to_total(statistics->groupsKnownTotal, info->groupsKnownPersistentDif); + } + if(info->groupsCompleteVolatileDif != 0){ + statistics->groupsCompleteVolatile = add_dif_to_total(statistics->groupsCompleteVolatile, info->groupsCompleteVolatileDif); + statistics->groupsCompleteTotal = add_dif_to_total(statistics->groupsCompleteTotal, info->groupsCompleteVolatileDif); + } + if(info->groupsCompleteTransientDif != 0){ + statistics->groupsCompleteTransient = add_dif_to_total(statistics->groupsCompleteTransient, info->groupsCompleteTransientDif); + statistics->groupsCompleteTotal = add_dif_to_total(statistics->groupsCompleteTotal, info->groupsCompleteTransientDif); + } + if(info->groupsCompletePersistentDif != 0){ + statistics->groupsCompletePersistent = add_dif_to_total(statistics->groupsCompletePersistent, info->groupsCompletePersistentDif); + statistics->groupsCompleteTotal = add_dif_to_total(statistics->groupsCompleteTotal, info->groupsCompletePersistentDif); + } + if(info->groupsIncompleteVolatileDif != 0){ + statistics->groupsIncompleteVolatile = add_dif_to_total(statistics->groupsIncompleteVolatile, info->groupsIncompleteVolatileDif); + statistics->groupsIncompleteTotal = add_dif_to_total(statistics->groupsIncompleteTotal, info->groupsIncompleteVolatileDif); + } + if(info->groupsIncompleteTransientDif != 0){ + statistics->groupsIncompleteTransient = add_dif_to_total(statistics->groupsIncompleteTransient, info->groupsIncompleteTransientDif); + statistics->groupsIncompleteTotal = add_dif_to_total(statistics->groupsIncompleteTotal, info->groupsIncompleteTransientDif); + } + if(info->groupsIncompletePersistentDif != 0){ + statistics->groupsIncompletePersistent = add_dif_to_total(statistics->groupsIncompletePersistent, info->groupsIncompletePersistentDif); + statistics->groupsIncompleteTotal = add_dif_to_total(statistics->groupsIncompleteTotal, info->groupsIncompletePersistentDif); + } + if(info->groupsIgnoredVolatileDif != 0){ + statistics->groupsIgnoredVolatile = add_dif_to_total(statistics->groupsIgnoredVolatile, info->groupsIgnoredVolatileDif); + statistics->groupsIgnoredTotal = add_dif_to_total(statistics->groupsIgnoredTotal, info->groupsIgnoredVolatileDif); + } + if(info->groupsIgnoredTransientDif != 0){ + statistics->groupsIgnoredTransient = add_dif_to_total(statistics->groupsIgnoredTransient, info->groupsIgnoredTransientDif); + statistics->groupsIgnoredTotal = add_dif_to_total(statistics->groupsIgnoredTotal, info->groupsIgnoredTransientDif); + } + if(info->groupsIgnoredPersistentDif != 0){ + statistics->groupsIgnoredPersistent = add_dif_to_total(statistics->groupsIgnoredPersistent, info->groupsIgnoredPersistentDif); + statistics->groupsIgnoredTotal = add_dif_to_total(statistics->groupsIgnoredTotal, info->groupsIgnoredPersistentDif); + } + } + } + return; +} + + +d_adminStatisticsInfo +d_adminStatisticsInfoNew() +{ + d_adminStatisticsInfo info; + /* Allocate alignerStatistics object */ + info = os_malloc(C_SIZEOF(d_adminStatisticsInfo)); + /* Call super-init */ + d_objectInit(d_object(info), D_ADMIN_STATS_INFO, + (d_objectDeinitFunc)d_adminStatisticsInfoDeinit); + /* Initialize adminStatisticsInfo */ + info->kind = D_ADMIN_STATISTICS_FELLOW; + info->fellowsKnownDif = 0; + info->fellowsApprovedDif = 0; + info->fellowsIncompatibleStateDif = 0; + info->fellowsIncompatibleDataModelDif = 0; + info->groupsKnownVolatileDif = 0; + info->groupsKnownTransientDif = 0; + info->groupsKnownPersistentDif = 0; + info->groupsCompleteVolatileDif = 0; + info->groupsCompleteTransientDif = 0; + info->groupsCompletePersistentDif = 0; + info->groupsIncompleteVolatileDif = 0; + info->groupsIncompleteTransientDif = 0; + info->groupsIncompletePersistentDif = 0; + info->groupsIgnoredVolatileDif = 0; + info->groupsIgnoredTransientDif = 0; + info->groupsIgnoredPersistentDif = 0; + return info; +} + + +void +d_adminStatisticsInfoDeinit( + d_adminStatisticsInfo info) +{ + assert(d_adminStatisticsInfoIsValid(info)); + + /* Nothing to deallocate */ + /* Call super-deinit */ + d_objectDeinit(d_object(info)); +} + + +void +d_adminStatisticsInfoFree( + d_adminStatisticsInfo info) +{ + assert(d_adminStatisticsInfoIsValid(info)); + + d_objectFree(d_object(info)); +} + + +void +d_statisticsUpdateConfiguration( + v_durabilityStatistics ds, + c_voidp args) +{ + c_ulong i; + c_ulong master, slave; + d_nameSpace ns; + d_admin admin; + c_iter nameSpaces; + c_ulong nameSpaceCount; + + admin = d_admin(args); + master = 0; + slave = 0; + + /* Collect namespaces from administration */ + nameSpaces = d_adminNameSpaceCollect(admin); + nameSpaceCount = c_iterLength(nameSpaces); + + for(i=0; inameSpacesKnown = nameSpaceCount; + ds->nameSpacesMaster = master; + ds->nameSpacesSlave = slave; + + /* Free collected namespaces */ + d_adminNameSpaceCollectFree(admin, nameSpaces); + + return; +} + +void +d_statisticsUpdateGroupsToCreate( + v_durabilityStatistics ds, + c_voidp args) +{ + c_ulong total; + d_groupCreationQueue queue = d_groupCreationQueue(args); + + ds->groupsToCreateVolatile = queue->groupsToCreateVolatile; + total = queue->groupsToCreateVolatile; + ds->groupsToCreateTransient = queue->groupsToCreateTransient; + total += queue->groupsToCreateTransient; + ds->groupsToCreatePersistent = queue->groupsToCreatePersistent; + total += queue->groupsToCreatePersistent; + ds->groupsToCreateTotal = total; + + return; +} diff --git a/src/services/durability/code/d_status.c b/src/services/durability/code/d_status.c new file mode 100644 index 000000000..a42fe793c --- /dev/null +++ b/src/services/durability/code/d_status.c @@ -0,0 +1,44 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "d_status.h" +#include "d_message.h" +#include "os_heap.h" + +d_status +d_statusNew( + d_admin admin) +{ + d_status status = NULL; + + if(admin){ + status = d_status(os_malloc(C_SIZEOF(d_status))); + d_messageInit(d_message(status), admin); + } + return status; +} + +void +d_statusFree( + d_status status) +{ + if(status){ + d_messageDeinit(d_message(status)); + os_free(status); + } +} diff --git a/src/services/durability/code/d_statusListener.c b/src/services/durability/code/d_statusListener.c new file mode 100644 index 000000000..0dbe1d49b --- /dev/null +++ b/src/services/durability/code/d_statusListener.c @@ -0,0 +1,184 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "d__statusListener.h" +#include "d__admin.h" +#include "d__durability.h" +#include "d__readerListener.h" +#include "d__configuration.h" +#include "d__fellow.h" +#include "d__publisher.h" +#include "d__misc.h" +#include "d_status.h" +#include "d__listener.h" +#include "d__actionQueue.h" +#include "d_message.h" +#include "d_networkAddress.h" +#include "d_nameSpacesRequest.h" +#include "d_groupsRequest.h" +#include "v_time.h" +#include "c_time.h" +#include "os_heap.h" +#include "os_thread.h" +#include "os_time.h" + +/** + * Macro that checks the d_statusListener validity. + * Because d_statusListener is a concrete class typechecking is required. + */ +#define d_statusListenerIsValid(_this) \ + d_listenerIsValidKind(d_listener(_this), D_STATUS_LISTENER) + +/** + * \brief The d_statusListener cast macro. + * + * This macro casts an object to a d_statusListener object. + */ +#define d_statusListener(_this) ((d_statusListener)(_this)) + +C_STRUCT(d_statusListener){ + C_EXTENDS(d_readerListener); +}; + +static void +d_statusListenerAction( + d_listener listener, + d_message message) +{ + d_admin admin; + d_fellow fellow = NULL, fellow2; + d_networkAddress fellowAddr; + + assert(d_statusListenerIsValid(listener)); + + admin = d_listenerGetAdmin(listener); + fellowAddr = d_networkAddressNew( + message->senderAddress.systemId, + message->senderAddress.localId, + message->senderAddress.lifecycleId); + fellow = d_durabilityGetOrCreateFellowFromMessage(admin, fellowAddr, message); + if (fellow) { + /* Remove fellow that is about to terminate or terminated */ + if ((message->senderState == D_STATE_TERMINATING) || (message->senderState == D_STATE_TERMINATED)) { + d_fellowSetCommunicationState(fellow, D_COMMUNICATION_STATE_TERMINATED); + fellow2 = d_adminRemoveFellow(admin, fellow, TRUE); + if (fellow2) { + d_fellowFree(fellow2); + } + } + d_fellowFree(fellow); + } + d_networkAddressFree(fellowAddr); + return; +} + +static void +d_statusListenerDeinit( + d_statusListener listener) +{ + assert(d_statusListenerIsValid(listener)); + + d_statusListenerStop(listener); + /* Call super-deinit */ + d_readerListenerDeinit(d_readerListener(listener)); +} + +static void +d_statusListenerInit( + d_statusListener listener, + d_subscriber subscriber) +{ + d_admin admin; + d_durability durability; + d_configuration config; + + /* Do not assert the listener because the initialization + * of the listener has not yet completed */ + + assert(d_subscriberIsValid(subscriber)); + + admin = d_subscriberGetAdmin(subscriber); + assert(d_adminIsValid(admin)); + durability = d_adminGetDurability(admin); + assert(d_durabilityIsValid(durability)); + config = d_durabilityGetConfiguration(durability); + assert(d_configurationIsValid(config)); + /* Call super-init */ + d_readerListenerInit( d_readerListener(listener), + D_STATUS_LISTENER, + d_statusListenerAction, + subscriber, + D_STATUS_TOPIC_NAME, + D_STATUS_TOP_NAME, + V_RELIABILITY_RELIABLE, + V_HISTORY_KEEPLAST, + 1, config->heartbeatScheduling, + (d_objectDeinitFunc)d_statusListenerDeinit); +} + + +d_statusListener +d_statusListenerNew( + d_subscriber subscriber) +{ + d_statusListener listener; + + assert(d_subscriberIsValid(subscriber)); + + /* Allocate statusListener object */ + listener = d_statusListener(os_malloc(C_SIZEOF(d_statusListener))); + if (listener) { + /* Initialize statusListener */ + d_statusListenerInit(listener, subscriber); + } + return listener; +} + +void +d_statusListenerFree( + d_statusListener listener) +{ + assert(d_statusListenerIsValid(listener)); + + d_objectFree(d_object(listener)); +} + +c_bool +d_statusListenerStart( + d_statusListener listener) +{ + assert(d_statusListenerIsValid(listener)); + + return d_readerListenerStart(d_readerListener(listener)); +} + +c_bool +d_statusListenerStop( + d_statusListener listener) +{ + c_bool result; + + assert(d_statusListenerIsValid(listener)); + + result = FALSE; + + if(listener){ + result = d_readerListenerStop(d_readerListener(listener)); + } + return result; +} diff --git a/src/services/durability/code/d_store.c b/src/services/durability/code/d_store.c new file mode 100644 index 000000000..23243a38d --- /dev/null +++ b/src/services/durability/code/d_store.c @@ -0,0 +1,972 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#include "vortex_os.h" + +#include "d__store.h" +#include "d__configuration.h" +#include "d_store.h" + +#include "d_storeXML.h" +#include "d_storeKV.h" + +#include "d__misc.h" +#include "d__lock.h" +#include "d__durability.h" +#include "os_heap.h" +#include "os_report.h" +#include "os_abstract.h" +#include "os_time.h" + + +static void +d_storePrint( + d_store store, + const char* format, + va_list args) +{ + char description[512]; + + if(store->config->tracingOutputFile){ + os_vsnprintf(description, sizeof(description)-1, format, args); + description [sizeof(description)-1] = '\0'; + fprintf(store->config->tracingOutputFile, "%s", description); + } +} + +static void +d_storePrintState( + d_store store) +{ + os_timeW time; + const c_char* state; + + + if(store->config->tracingOutputFile){ + switch(store->type){ + case D_STORE_TYPE_XML: + state = "XML"; + break; + case D_STORE_TYPE_BIG_ENDIAN: + state = "BIG ENDIAN"; + break; + case D_STORE_TYPE_KV: + state = "KV"; + break; + default: + state = "<>"; + break; + } + + if (store->config->tracingTimestamps == TRUE) { + os_char buf[OS_CTIME_R_BUFSIZE]; + if (store->config->tracingRelativeTimestamps == TRUE) { + /* relative timestamps, use the wall clock for timestamping log messages */ + os_duration delta = os_timeWDiff(os_timeWGet(), store->config->startWTime); + time = os_timeWAdd(OS_TIMEW_ZERO, delta); + } else { + time = os_timeWGet(); + } + os_ctimeW_r(&time, buf, OS_CTIME_R_BUFSIZE); + fprintf(store->config->tracingOutputFile, + "%s %"PA_PRItime" PersistentStore (%s) -> ", + buf, OS_TIMEW_PRINT(time), state); + } else { + fprintf(store->config->tracingOutputFile, + "PersistentStore (%s) -> ", state); + } + } +} + +void +d_storeInit( + d_store store, + d_objectDeinitFunc deinit) +{ + /* Call super-init */ + d_lockInit(d_lock(store), D_STORE, + (d_objectDeinitFunc)deinit); +} + +void +d_storeDeinit( + d_store store) +{ + /* Call super deinit */ + d_lockDeinit(d_lock(store)); +} + +d_store +d_storeOpen( + const d_durability durability, + d_storeType storeType) +{ + d_store store; + d_storeResult result; + d_configuration config; + d_admin admin; + + config = durability->configuration; + admin = durability->admin; + + store = NULL; + + switch(storeType){ + case D_STORE_TYPE_XML: + store = d_store(d_storeNewXML(u_participant(d_durabilityGetService(durability)))); + break; + case D_STORE_TYPE_BIG_ENDIAN: + store = NULL; + break; + case D_STORE_TYPE_KV: + store = d_store(d_storeNewKV(u_participant(d_durabilityGetService(durability)))); + break; + default: + OS_REPORT(OS_ERROR, "durability", 0, + "Supplied persistent store type unknown."); + store = NULL; + break; + } + if(store != NULL) { + store->type = storeType; + store->config = config; + store->admin = admin; + + if(store->openFunc) { + result = store->openFunc(store); + + if(result != D_STORE_RESULT_OK){ + switch(storeType){ + case D_STORE_TYPE_XML: + d_storeFreeXML(d_storeXML(store)); + store = NULL; + break; + case D_STORE_TYPE_BIG_ENDIAN: + store = NULL; + break; + case D_STORE_TYPE_KV: + d_storeFreeKV(d_storeKV(store)); + store = NULL; + break; + default: + store = NULL; + assert(FALSE); + break; + } + } + } + } + return store; +} + +d_storeResult +d_storeClose( + d_store store) +{ + d_storeResult result; + + if(store){ + if(store->closeFunc){ + result = store->closeFunc(store); + + if(result == D_STORE_RESULT_OK) { + switch(store->type){ + case D_STORE_TYPE_XML: + result = d_storeFreeXML(d_storeXML(store)); + store = NULL; + break; + case D_STORE_TYPE_BIG_ENDIAN: + break; + case D_STORE_TYPE_KV: + result = d_storeFreeKV(d_storeKV(store)); + store = NULL; + break; + default: + break; + } + } + } else { + result = D_STORE_RESULT_UNSUPPORTED; + } + } else { + result = D_STORE_RESULT_ILL_PARAM; + } + return result; +} + +d_storeResult +d_storeActionStart( + const d_store store) +{ + d_storeResult result; + + if(store){ + if(store->actionStartFunc){ + result = store->actionStartFunc(store); + } else { + result = D_STORE_RESULT_UNSUPPORTED; + } + } else { + result = D_STORE_RESULT_ILL_PARAM; + } + return result; +} + +d_storeResult +d_storeActionStop( + const d_store store) +{ + d_storeResult result; + + if(store){ + if(store->actionStopFunc){ + result = store->actionStopFunc(store); + } else { + result = D_STORE_RESULT_UNSUPPORTED; + } + } else { + result = D_STORE_RESULT_ILL_PARAM; + } + return result; +} + +d_storeResult +d_storeGroupsRead( + const d_store store, + d_groupList *list) +{ + d_storeResult result; + + if(store){ + if(store->groupsReadFunc){ + result = store->groupsReadFunc(store, list); + } else { + result = D_STORE_RESULT_UNSUPPORTED; + } + } else { + result = D_STORE_RESULT_ILL_PARAM; + } + return result; +} + +d_storeResult +d_storeGroupListFree( + const d_store store, + d_groupList list) +{ + d_storeResult result; + + if(store){ + if(store->groupListFreeFunc){ + result = store->groupListFreeFunc(store, list); + } else { + result = D_STORE_RESULT_OK; + } + } else { + result = D_STORE_RESULT_ILL_PARAM; + } + + return result; +} + + +d_storeResult +d_storeGroupInject( + const d_store store, + const c_char* partition, + const c_char* topic, + const u_participant participant, + d_group *group) +{ + d_storeResult result; + + if(store){ + if(store->groupInjectFunc){ + result = store->groupInjectFunc(store, partition, topic, participant, group); + } else { + result = D_STORE_RESULT_UNSUPPORTED; + } + } else { + result = D_STORE_RESULT_ILL_PARAM; + } + return result; +} + +d_storeResult +d_storeGroupStore( + const d_store store, + const d_group group, + const d_nameSpace nameSpace) +{ + d_storeResult result; + + if(store){ + if(store->groupStoreFunc){ + result = store->groupStoreFunc(store, group, nameSpace); + } else { + result = D_STORE_RESULT_UNSUPPORTED; + } + } else { + result = D_STORE_RESULT_ILL_PARAM; + } + return result; +} + +d_storeResult +d_storeGetQuality( + const d_store store, + const d_nameSpace nameSpace, + d_quality* quality) +{ + d_storeResult result; + + if(store){ + if(store->getQualityFunc){ + result = store->getQualityFunc(store, nameSpace, quality); + } else { + result = D_STORE_RESULT_UNSUPPORTED; + } + } else { + result = D_STORE_RESULT_ILL_PARAM; + } + return result; +} + +/* Backup current namespace */ +d_storeResult +d_storeBackup( + const d_store store, + const d_nameSpace nameSpace) +{ + d_storeResult result; + + if(store){ + if(store->backupFunc){ + result = store->backupFunc(store, nameSpace); + } else { + result = D_STORE_RESULT_UNSUPPORTED; + } + } else { + result = D_STORE_RESULT_ILL_PARAM; + } + return result; +} + +/* Check if namespace is complete */ +d_storeResult +d_storeNsIsComplete ( + const d_store store, + const d_nameSpace nameSpace, + c_bool* isComplete) +{ + d_storeResult result; + + if (store){ + if(store->nsIsCompleteFunc){ + result = store->nsIsCompleteFunc (store, nameSpace, isComplete); + }else + { + result = D_STORE_RESULT_UNSUPPORTED; + } + }else + { + result = D_STORE_RESULT_ILL_PARAM; + } + + return result; +} + +/* Mark namespace incomplete or complete */ +d_storeResult +d_storeNsMarkComplete ( + const d_store store, + const d_nameSpace nameSpace, + c_bool isComplete) +{ + d_storeResult result; + + if (store){ + if(store->nsMarkCompleteFunc){ + result = store->nsMarkCompleteFunc (store, nameSpace, isComplete); + }else + { + result = D_STORE_RESULT_UNSUPPORTED; + } + }else + { + result = D_STORE_RESULT_ILL_PARAM; + } + + return result; +} + +/* Restore previously stored namespace */ +d_storeResult +d_storeRestoreBackup( + const d_store store, + const d_nameSpace nameSpace) +{ + d_storeResult result; + + if (store) + { + if (store->restoreBackupFunc) + { + result = store->restoreBackupFunc(store, nameSpace); + if (result == D_STORE_RESULT_OK) + { + /* After restoring, mark namespace as complete */ + result = d_storeNsMarkComplete (store, nameSpace, TRUE); + } + }else + { + result = D_STORE_RESULT_UNSUPPORTED; + } + }else + { + result = D_STORE_RESULT_ILL_PARAM; + } + + return result; +} + +d_storeResult +d_storeMessageStore( + const d_store store, + const v_groupAction message) +{ + d_storeResult result; + + if(store){ + if(store->messageStoreFunc){ + result = store->messageStoreFunc(store, message); + } else { + result = D_STORE_RESULT_UNSUPPORTED; + } + } else { + result = D_STORE_RESULT_ILL_PARAM; + } + return result; +} + +d_storeResult +d_storeInstanceDispose( + const d_store store, + const v_groupAction message) +{ + d_storeResult result; + + if(store){ + if(store->instanceDisposeFunc){ + result = store->instanceDisposeFunc(store, message); + } else { + result = D_STORE_RESULT_UNSUPPORTED; + } + } else { + result = D_STORE_RESULT_ILL_PARAM; + } + return result; +} + +d_storeResult +d_storeInstanceExpunge( + const d_store store, + const v_groupAction message) +{ + d_storeResult result; + + if(store){ + if(store->instanceExpungeFunc){ + result = store->instanceExpungeFunc(store, message); + } else { + result = D_STORE_RESULT_UNSUPPORTED; + } + } else { + result = D_STORE_RESULT_ILL_PARAM; + } + return result; +} + +d_storeResult +d_storeMessageExpunge( + const d_store store, + const v_groupAction message) +{ + d_storeResult result; + + if(store){ + if(store->messageExpungeFunc){ + result = store->messageExpungeFunc(store, message); + } else { + result = D_STORE_RESULT_UNSUPPORTED; + } + } else { + result = D_STORE_RESULT_ILL_PARAM; + } + return result; +} + +d_storeResult +d_storeDeleteHistoricalData( + const d_store store, + const v_groupAction message) +{ + d_storeResult result; + + if(store){ + if(store->deleteHistoricalDataFunc){ + result = store->deleteHistoricalDataFunc(store, message); + } else { + result = D_STORE_RESULT_UNSUPPORTED; + } + } else { + result = D_STORE_RESULT_ILL_PARAM; + } + return result; +} + +d_storeResult +d_storeMessagesInject( + const d_store store, + const d_group group) +{ + d_storeResult result; + + if(store){ + if(store->messagesInjectFunc){ + result = store->messagesInjectFunc(store, group); + } else { + result = D_STORE_RESULT_UNSUPPORTED; + } + } else { + result = D_STORE_RESULT_ILL_PARAM; + } + return result; +} + +d_storeResult +d_storeInstanceRegister( + const d_store store, + const v_groupAction message) +{ + d_storeResult result; + + if(store){ + if(store->instanceRegisterFunc){ + result = store->instanceRegisterFunc(store, message); + } else { + result = D_STORE_RESULT_UNSUPPORTED; + } + } else { + result = D_STORE_RESULT_ILL_PARAM; + } + return result; +} + +d_storeResult +d_storeInstanceUnregister( + const d_store store, + const v_groupAction message) +{ + d_storeResult result; + + if(store){ + if(store->instanceUnregisterFunc){ + result = store->instanceUnregisterFunc(store, message); + } else { + result = D_STORE_RESULT_UNSUPPORTED; + } + } else { + result = D_STORE_RESULT_ILL_PARAM; + } + return result; +} + +d_storeResult +d_storeCreatePersistentSnapshot( + const d_store store, + const c_char* partitionExpr, + const c_char* topicExpr, + const c_char* uri) +{ + d_storeResult result; + + if(store) + { + if(store->createPersistentSnapshotFunc) + { + result = store->createPersistentSnapshotFunc(store, partitionExpr, topicExpr, uri); + } else + { + result = D_STORE_RESULT_UNSUPPORTED; + } + } else + { + result = D_STORE_RESULT_ILL_PARAM; + } + return result; +} + +d_storeResult +d_storeOptimizeGroup( + const d_store store, + const d_group group) +{ + d_storeResult result; + + if(store){ + if(store->optimizeGroupFunc){ + result = store->optimizeGroupFunc(store, group); + } else { + result = D_STORE_RESULT_UNSUPPORTED; + } + } else { + result = D_STORE_RESULT_ILL_PARAM; + } + return result; +} + + +d_storeResult +d_storeTransactionComplete( + const d_store store, + const v_groupAction message) +{ + d_storeResult result; + + if (store) { + if(store->transactionCompleteFunc){ + result = store->transactionCompleteFunc(store, message); + } else { + result = D_STORE_RESULT_UNSUPPORTED; + } + } else { + result = D_STORE_RESULT_ILL_PARAM; + } + return result; +} + + +void +d_storeReport( + const d_store store, + d_level level, + const char *format, + ...) +{ + va_list args; + + if(store->config){ + if(((c_ulong)level) >= ((c_ulong)store->config->tracingVerbosityLevel)){ + d_storePrintState(store); + va_start (args, format); + d_storePrint(store, format, args); + va_end (args); + } + } +} + +d_storeResult +d_storeCopyFile( + os_char* fileStorePath, + os_char* destStorePath) +{ + FILE* source = NULL; + FILE* destination = NULL; + d_storeResult result = D_STORE_RESULT_OK; + + assert(fileStorePath); + assert(destStorePath); + + /* Open the source file for reading */ + source = fopen(fileStorePath, "rb"); + if(source)/* if the source file doesn't exist, we thus return ok, nothing to copy! */ + { + /* Open the destination file for writing */ + if(result == D_STORE_RESULT_OK) + { + destination = fopen(destStorePath, "wb"); + if(!destination) + { + result = D_STORE_RESULT_IO_ERROR; + } + } + /* As long as we have not reached the end of the file of the source file + * continue + */ + while(result == D_STORE_RESULT_OK && !feof(source)) + { + int ch; + + /* Get data from the source file */ + ch = fgetc(source); + if(ferror(source)) + { + result = D_STORE_RESULT_IO_ERROR; + + } else + { + if(!feof(source)) + { + fputc(ch, destination); + if(ferror(destination)) + { + result = D_STORE_RESULT_IO_ERROR; + } + } + } + } + } + /* Close the destination file */ + if(destination) + { + if(fclose(destination) == EOF) + { + result = D_STORE_RESULT_IO_ERROR; + } + } + /* Close the source file */ + if(source) + { + if(fclose(source) == EOF) + { + result = D_STORE_RESULT_IO_ERROR; + } + } + return result; +} + + +c_char* +d_storeDirNew( + d_store store, + const c_char *name) +{ + c_bool result = FALSE; + os_result status; + c_char dirName[OS_PATH_MAX]; + struct os_stat_s statBuf; + c_ulong i; + c_char* pdir = NULL; + size_t len; + + (void)memset(dirName, 0, sizeof(dirName)); + + len = (name == NULL ? 0 : strlen(name)); + if(len > 0){ + result = TRUE; + + for(i=0; i < len && result; i++){ + if((name[i] == OS_FILESEPCHAR) && (i != 0)){ + status = os_stat(dirName, &statBuf); + + if (status != os_resultSuccess) { + os_mkdir(dirName, S_IRWXU | S_IRWXG | S_IRWXO); + status = os_stat(dirName, &statBuf); + } + if (status != os_resultSuccess || !OS_ISDIR (statBuf.stat_mode)) { +#ifdef WIN32 + if((strlen(dirName) == 2) && (dirName[1] == ':')){ + /*This is a device like for instance: 'C:'*/ + } else { + d_storeReport(store, D_LEVEL_SEVERE, + "Directory '%s' is not a directory.\n", + dirName); + OS_REPORT(OS_ERROR, D_CONTEXT, 0, + "Directory '%s' is not a directory.", + dirName); + result = FALSE; + pdir = NULL; + } +#else + d_storeReport(store, D_LEVEL_SEVERE, + "Directory '%s' is not a directory.\n", + dirName); + OS_REPORT(OS_ERROR, D_CONTEXT, 0, + "Directory '%s' is not a directory.", + dirName); + + result = FALSE; + pdir = NULL; +#endif + } + } + dirName[i] = name[i]; + } + if(result){ + if(dirName[len-1] != OS_FILESEPCHAR){ + status = os_stat(dirName, &statBuf); + + if (status != os_resultSuccess) { + os_mkdir(dirName, S_IRWXU | S_IRWXG | S_IRWXO); + status = os_stat(dirName, &statBuf); + } + pdir = os_strdup(name); + + if (status != os_resultSuccess || !OS_ISDIR (statBuf.stat_mode)) { +#ifdef WIN32 + if((strlen(dirName) == 2) && (dirName[1] == ':')){ + /*This is a device like for instance: 'C:'. Check if it exists...*/ + dirName[2] = OS_FILESEPCHAR; + status = os_stat(dirName, &statBuf); + + if(status == os_resultFail){ + d_storeReport(store, D_LEVEL_SEVERE, + "Directory '%s' is not available.\n", + dirName); + OS_REPORT(OS_ERROR, D_CONTEXT, 0, + "Directory '%s' is not available.", + dirName); + result = FALSE; + os_free(pdir); + pdir = NULL; + } + } else { + d_storeReport(store, D_LEVEL_SEVERE, + "'%s' is not a directory.\n", + pdir); + OS_REPORT(OS_ERROR, D_CONTEXT, 0, + "Directory '%s' is not a directory.", + pdir); + result = FALSE; + os_free(pdir); + pdir = NULL; + } +#else + d_storeReport(store, D_LEVEL_SEVERE, + "'%s' is not a directory.\n", + dirName); + OS_REPORT(OS_ERROR, D_CONTEXT, 0, + "'%s' is not a directory.", + dirName); + result = FALSE; + os_free(pdir); + pdir = NULL; +#endif + } + } else { + pdir = (char*)os_malloc(strlen(name)+1); + snprintf(pdir, strlen(name), "%s", name); + } + } + } else { + result = FALSE; + pdir = NULL; + } + + if(result){ + status = os_access(pdir, 2); /*Check whether dir is writable*/ + + if(status != os_resultSuccess){ +#ifdef WIN32 + if((strlen(dirName) == 2) && (dirName[1] == ':')){ + /*This is a device like for instance: 'C:'. Check if it exists...*/ + dirName[2] = OS_FILESEPCHAR; + status = os_stat(dirName, &statBuf); + + if(status == os_resultFail){ + d_storeReport(store, D_LEVEL_SEVERE, + "'%s' cannot be found.\n", + dirName); + OS_REPORT(OS_ERROR, D_CONTEXT, 0, + "'%s' cannot be found.", + dirName); + result = FALSE; + os_free(pdir); + pdir = NULL; + } + } else { + d_storeReport(store, D_LEVEL_SEVERE, + "Specified directory '%s' is not writable.\n", + pdir); + OS_REPORT(OS_ERROR, D_CONTEXT, 0, + "Specified directory '%s' is not writable.", + pdir); + result = FALSE; + os_free(pdir); + pdir = NULL; + } +#else + d_storeReport(store, D_LEVEL_SEVERE, + "Specified directory '%s' is not writable.\n", + pdir); + OS_REPORT(OS_ERROR, D_CONTEXT, 0, + "Specified directory '%s' is not writable.", + pdir); + os_free(pdir); + pdir = NULL; +#endif + } + } + return pdir; +} + + + +void +d_storeGetBase( + v_public entity, + c_voidp args) +{ + struct baseFind* f; + + assert(entity); + + f = (struct baseFind*)args; + + f->base = c_getBase(entity); +} + +d_storeResult +d_storeMessagesLoad( + const d_store store, + const d_group group, + struct d_groupHash *groupHash) +{ + d_storeResult result; + + if (store) { + if(store->messagesLoadFunc){ + result = store->messagesLoadFunc(store, group, groupHash); + } else { + result = D_STORE_RESULT_UNSUPPORTED; + } + } else { + result = D_STORE_RESULT_ILL_PARAM; + } + return result; +} + +d_storeResult +d_storeMessagesLoadFlush( + const d_store store, + const d_group group, + c_bool inject) +{ + d_storeResult result; + + if (store) { + if(store->messagesLoadFlushFunc){ + result = store->messagesLoadFlushFunc(store, group, inject); + } else { + result = D_STORE_RESULT_UNSUPPORTED; + } + } else { + result = D_STORE_RESULT_ILL_PARAM; + } + return result; +} diff --git a/src/services/durability/code/d_storeKV.c b/src/services/durability/code/d_storeKV.c new file mode 100644 index 000000000..d71de9b15 --- /dev/null +++ b/src/services/durability/code/d_storeKV.c @@ -0,0 +1,7314 @@ +/* -*- mode: c; c-file-style: "k&r"; c-basic-offset: 4; -*- */ + +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#include "vortex_os.h" +#include "ut_avl.h" +#include "d__misc.h" +#include "d_storeKV.h" +#include "d_store.h" +#include "d__nameSpace.h" +#include "d__configuration.h" +#include "d__table.h" +#include "d_object.h" +#include "d__types.h" +#include "d__store.h" +#include "d__pQos.h" +#include "d__thread.h" +#include "d__groupHash.h" +#include "u_user.h" +#include "u_group.h" +#include "u_observable.h" +#include "u_entity.h" +#include "u_partition.h" +#include "u_topic.h" +#include "v_public.h" +#include "v_entity.h" +#include "v_time.h" +#include "v_topicQos.h" +#include "v_topic.h" +#include "v_message.h" +#include "v_messageExt.h" +#include "v_partition.h" +#include "v_state.h" +#include "sd_serializer.h" +#include "sd_serializerXML.h" +#include "sd_serializerBigE.h" +#include "c_base.h" +#include "c_laptime.h" +#include "c_field.h" +#include "os_heap.h" +#include "os_time.h" +#include "os_stdlib.h" +#include "os_report.h" +#include "os_socket.h" +#include "sd_cdr.h" +#include "ut_compressor.h" + +#include +#include +#include + + +#define KV_INCLUDE_DUMMY 1 + + +/* Explicitly mapping identifiers to numerical values because the + * numerical values are what is potentially relevant to backwards + * compatibility. */ +typedef enum kv_table { + TABLE_VERSION = 0, + TABLE_TOPIC = 1, TABLE_TOPIC_TYPE = 2, + TABLE_NAMESPACE = 3, TABLE_NAMESPACE_QUALITY = 4, TABLE_NAMESPACE_COMPLETENESS = 5, + TABLE_GROUP = 6, + TABLE_MESSAGE = 7, + TABLE_MESSAGE_EOT = 8, +} kv_table_t; +#define N_TABLES 9 + + +typedef struct kv_key { + enum kv_table table; + os_uint32 gid; /* TABLE_VERSION: 0; else topic, namespace or group id, depending on table */ + os_uint32 iid; /* TABLE_MESSAGE: instance id; others: 0 */ + os_uint64 mid; /* TABLE_MESSAGE: message id; others: 0 */ +} kv_key_t; + +typedef enum kv_kind { + KV_KIND_SQLITE, + KV_KIND_LEVELDB, + KV_KIND_LSDS, + KV_KIND_DUMMY, + KV_KIND_SQLITEMT +} kv_kind_t; + + +typedef enum kv_commit_state { + UNDECIDED, + OPEN, /* Begin marker of transaction received, but no end-marker */ + COMMITTED /* End of transaction has been received */ +} kv_commit_state_t; + + +/* Maximum GID is less than the full range because we reserve the 8 + * bits for encoding the table id, just in case when end up using a + * backing K-V store that benefits from that possibility. 2**24 + * groups should be enough; if it is not, we can reasonably easily + * change this. */ +#define MAX_GID 0x00ffffffu + +/* kv_result: 0 is success, all errors < 0 */ +typedef int kv_result_t; +#define KV_RESULT_ACCESS_DENIED -1 +#define KV_RESULT_NODATA -2 +#define KV_RESULT_ERROR -3 +#define KV_RESULT_CORRUPT -4 +#define KV_RESULT_OUT_OF_RESOURCES -5 + +typedef struct kv_store_common *kv_store_t; +typedef struct kv_iter_common *kv_iter_t; + + +struct transaction_msg { + /* List that contains references to transactional samples + * with the same transactionId. The samples themselves + * are maintained in the instance. There is no need + * for a double-linked list, a single list will do. */ + struct msg *msg_ref; + struct transaction_msg *next; +}; + +struct transaction_list { + v_gid gid; /* the writer that wrote the transaction */ + c_ulong seqNum; /* the transactionId (unique per writer) */ + os_uint64 otid; /* first free id in table of open transactions */ + kv_commit_state_t commit_state; + struct transaction_msg *head; + struct transaction_msg *tail; +}; + +struct msg { + /* Older/newer: double linked list of messages for one instance, + * sorted either on time stamp or in reception order, depending on + * the DESTINATION_ORDER QoS */ + struct msg *older; + struct msg *newer; + + /* Backreference to the instance to which the message belongs */ + struct inst *inst; + + /* Message key used in the K-V store for this message */ + kv_key_t key; + + /* Fields copied from the v_message so we don't have to keep a + * reference to it at all times. For normal persistency, we would + * only have to keep references to data that has to be in shared + * memory anyway, and hence this isn't really necessary. On the + * other hand, if we ever want to use this framework for other + * (logging) purposes, it would become an issue. */ + v_state state; + os_timeW writeTime; + v_gid writerGID; + c_ulong sequenceNumber; + c_ulong transactionId; + + /* During reconstruction/injection, we deserialise the data and + * keep a reference to it until we have inserted it in the + * group. */ + v_message v_msg; +}; + +struct inst { + /* Instance key is next_msg_key.{table,gid,iid}, next_msg_key is + * the next free message id. */ + kv_key_t next_msg_key; + + /* instances_by_iid uses avlnode and has some things maintained by + * inst_augment: lowest and highest iid in subtree and 0 or 1 + an + * unusued iid. */ + ut_avlNode_t avlnode; + os_uint32 iid_min; + os_uint32 iid_max; + os_uint32 iid_holep1; + + /* We treat the key as a blob once it has been extracted from the + * message. Although we do define an ordering over the keyblob so + * that we can use it as a key in, e.g., a binary search tree, it + * is generally not a meaningful one. */ + size_t keysize; + void *keyvalue; + + /* Reference to groupList associated with the instance */ + struct d_groupListKV_s *g; + + /* The messages associated with this instance. writeCount is the + * number of writes and write-disposes -- that is, the number of + * messages with the L_WRITE flag set. Messages that belong to + * a coherent transaction are not counted, so if the L_TRANSACTION + * flag is set the writeCount is not affected. */ + c_long writeCount; + struct msg *oldest; + struct msg *latest; /* undefined if oldest == NULL */ + struct msg *oldest_non_transaction; /* NULL if not present */ + +}; + +struct namespace { + os_uint32 id; /* local numerical id (for TABLE_NAMESPACE) */ + os_uint32 version; /* version number of namespace (for backup/restore), starts at 0 */ + char *name; /* namespace name, as extracted from durability */ + d_quality quality; /* current quality of namespace */ + int on_disk; /* 0 if not yet written to disk */ + struct namespace *next; /* next namespace in list sorted s.t. (id, v) always precedes (id, w) if v > w */ +}; + +struct ser_deser_ctx { + struct sd_cdrInfo *ci; + c_type xmsgType; +}; + +C_STRUCT (d_groupListKV) { + C_EXTENDS (d_groupList); + unsigned group_id; /* local numerical id for group */ + unsigned topic_id; /* same for all groups with this topic */ + d_table instances; /* set of instances in this group */ + ut_avlTree_t instances_by_iid; /* aliases instances, ordered by iid and used for finding free iids */ + struct namespace *namespace; /* versioned namespace to which this group belongs */ + v_group vgroup; /* reference to the corresponding v_group (NOT written to disk)*/ + struct ser_deser_ctx tctx; +}; +C_CLASS (d_groupListKV); + +C_STRUCT (d_storeKV) { + C_EXTENDS (d_store); + c_base base; /* cached base pointer */ + c_bool opened; /* whether currently between ...Open and ...Close */ + d_groupListKV groups; /* discovered groups */ + struct namespace *namespaces; /* discovered namespaces */ + kv_store_t kv; /* backing key-value store */ + c_char *diskStorePath; /* path to persistent directory */ + d_encodingKV encoding; /* payload encoding used in file */ + + /* These are used to emulate a mutex in such a way that we can notify the + * liveliness mechanism we're alive while waiting for the store to become + * unlocked. The problem is that some operations on very large persistent + * data sets can take very long, so long that calling d_lockLock(st) would + * cause the thread to lose liveliness. */ + int locked; + os_mutex lock; + os_cond cond; + + struct hashtable *groupTable; + + /* Next free id for groups, topics and namespaces */ + os_uint32 next_group_id; + os_uint32 next_topic_id; + os_uint32 next_namespace_id; + + /* Cached pointers to the various KV-store specific payload types + * defined in durability.odl, used for (de)serialisation */ + c_type topic_type; + c_type topicinfo_type; + c_type namespace_type; + c_type namespace_quality_type; + c_type namespace_completeness_type; + c_type group_type; + c_type open_transaction_eot_type; + c_type open_transaction_vtid_type; + + struct ser_deser_ctx topic_tctx; + struct ser_deser_ctx topicinfo_tctx; + struct ser_deser_ctx namespace_tctx; + struct ser_deser_ctx namespace_quality_tctx; + struct ser_deser_ctx namespace_completeness_tctx; + struct ser_deser_ctx group_tctx; + struct ser_deser_ctx open_transaction_eot_tctx; + struct ser_deser_ctx open_transaction_vtid_tctx; + + + /* table containing the updated namespaces for which the quality has to be + * updated on disk */ + struct hashtable *updated_namespaces; + + /* Support for benchmark KV store */ + c_bool action_started; + os_timeE first_time; + os_timeE last_time; + + /* Table of open transactions for which no EOT has been received. + * Each entry in the table contains a list of references to + * samples that belong to the transaction. */ + d_table open_transactions; + + /* First free id for open transactions. + * We use a 64-bit of which 63 bits are used for the key + * and 1 bit to indicate if the transaction is open (0) + * or committed (1). This gives 2^63 possible keys which + * is sufficient to generate ids for almost 300 years + * at a rate of 1GHz ... */ + os_uint64 otid; + + d_compressionKV compression; + ut_compressor compressor; +}; + +static void kvlog (const struct d_storeKV_s *st, d_level level, const char *fmt, ...); +static void *serialize (os_uint32 *sz, d_storeKV st, const struct c_type_s *type, struct ser_deser_ctx *ctx, const void *obj); +static kv_result_t deserialize (void **obj, d_storeKV st, const struct c_type_s *type, struct ser_deser_ctx *ctx, os_uint32 sz, const void *val); + +#define ASSERT_STOREKV_NORET(object) do { \ + assert (d_objectIsValid (d_object (object), D_STORE)); \ + assert (((d_store) (object))->type == D_STORE_TYPE_KV); \ + } while (0) + +#define ASSERT_STOREKV(st, object) do { \ + if ((object) == NULL) { \ + return D_STORE_RESULT_ILL_PARAM; \ + } \ + ASSERT_STOREKV_NORET (object); \ + st = (d_storeKV) (object); \ + } while (0) + +static void store_wait_for_lock (struct d_storeKV_s *st) +{ + if (st->locked) { + d_thread self = d_threadLookupSelf (); + const os_duration maxwait = OS_DURATION_INIT(180, 0); /* 3 min */ + os_timeM tnow = os_timeMGet (); + const os_timeM tend = os_timeMAdd (tnow, maxwait); + /* Try to acquire the lock for maxwait sec. while asserting liveliness. */ + os_duration timeout = os_timeMDiff(tend, tnow); + while (st->locked && os_durationCompare (timeout, OS_DURATION_ZERO) == OS_MORE) { + (void) d_condTimedWait (self, &st->cond, &st->lock, timeout); + tnow = os_timeMGet (); + timeout = os_timeMDiff(tend, tnow); + } + if (st->locked) + { + /* After waiting for maxwait, switch to using os_condWait because that one + * doesn't maintain liveliness, and we think something is badly wrong. */ + kvlog (st, D_LEVEL_WARNING, "waiting more than %"PA_PRIduration" s for persistent store lock", + OS_DURATION_PRINT(maxwait)); + while (st->locked) { + os_condWait (&st->cond, &st->lock); + } + } + } + assert (!st->locked); +} + +#define LOCK_OPEN_STOREKV(st, object) do { \ + ASSERT_STOREKV (st, object); \ + os_mutexLock (&st->lock); \ + store_wait_for_lock (st); \ + if (!st->opened) { \ + os_mutexUnlock (&st->lock); \ + return D_STORE_RESULT_PRECONDITION_NOT_MET; \ + } \ + st->locked = 1; \ + os_mutexUnlock (&st->lock); \ + } while (0) + +#define UNLOCK_OPEN_STOREKV(st) do { \ + os_mutexLock (&st->lock); \ + st->locked = 0; \ + os_condSignal (&st->cond); \ + os_mutexUnlock (&st->lock); \ + } while (0) + +#define CONSTR_UINT64(x, y, z) (((os_uint64) (x) * 1000000 + (y)) * 1000000 + (z)) +static const os_uint64 hashTableConst = CONSTR_UINT64(14585777, 916479, 446343); + +void d_storeDeinitKV (d_storeKV store); +d_storeKV d_storeNewKV (u_participant participant); +d_storeResult d_storeFreeKV (d_storeKV store); +d_storeResult d_storeOpenKV (d_store store); +d_storeResult d_storeCloseKV (d_store store); +d_storeResult d_storeActionStartKV (const d_store store); +d_storeResult d_storeActionStopKV (const d_store store); +d_storeResult d_storeGetQualityKV (const d_store store, const d_nameSpace nameSpace, os_timeW* quality); +d_storeResult d_storeBackupKV (const d_store store, const d_nameSpace nameSpace); +d_storeResult d_storeRestoreBackupKV (const d_store store, const d_nameSpace nameSpace); +d_storeResult d_storeGroupsReadKV (const d_store store, d_groupList *list); +d_storeResult d_storeGroupListFreeKV (const d_store store, d_groupList list); +d_storeResult d_storeGroupInjectKV (const d_store store, const c_char* partition, const c_char* topic, const u_participant participant, d_group *group); +d_storeResult d_storeGroupStoreKV (const d_store store, const d_group group, const d_nameSpace nameSpace); +d_storeResult d_storeMessageStoreKV (const d_store store, const v_groupAction message); +d_storeResult d_storeInstanceDisposeKV (const d_store store, const v_groupAction message); +d_storeResult d_storeInstanceExpungeKV (const d_store store, const v_groupAction message); +d_storeResult d_storeMessageExpungeKV (const d_store store, const v_groupAction message); +d_storeResult d_storeDeleteHistoricalDataKV (const d_store store, const v_groupAction message); +d_storeResult d_storeMessagesInjectKV (const d_store store, const d_group group); +d_storeResult d_storeInstanceRegisterKV (const d_store store, const v_groupAction message); +d_storeResult d_storeCreatePersistentSnapshotKV (const d_store store, const c_char* partitionExpr, const c_char* topicExpr, const c_char* uri); +d_storeResult d_storeInstanceUnregisterKV (const d_store store, const v_groupAction message); +d_storeResult d_storeOptimizeGroupKV (const d_store store, const d_group group); +d_storeResult d_storeNsIsCompleteKV (const d_store store, const d_nameSpace nameSpace, c_bool* isComplete); +d_storeResult d_storeNsMarkCompleteKV (const d_store store, const d_nameSpace nameSpace, c_bool isComplete); +d_storeResult d_storeTransactionCompleteKV (const d_store store, const v_groupAction message); +d_storeResult d_storeMessagesLoadKV (const d_store store, const d_group group, struct d_groupHash *groupHash); +d_storeResult d_storeMessagesLoadFlushKV (const d_store store, const d_group group, c_bool inject); + + +static int inst_cmp (const struct inst *a, const struct inst *b); +static void inst_free (struct inst *a); +static void inst_augment (void *vinst, const void *vleft, const void *vright); +static int compare_iid (const void *va, const void *vb); +static int transaction_list_cmp (const struct transaction_list *a, const struct transaction_list *b); +static void transaction_list_free (struct transaction_list *); +static d_storeResult commit_group_transaction (struct d_storeKV_s *st, const struct v_messageEOT_s *msg, int reconstructing); +static d_storeResult commit_writer_transaction (struct d_storeKV_s *st, struct transaction_list *tr_list, int reconstructing); +static struct msg *get_oldest_non_transaction (struct msg *a, struct msg *b, v_orderbyKind order_by) __nonnull((1)) __attribute_returns_nonnull__; + +static int enable_kvdebug = 0; +static int kvlog_statistics = 0; + +static ut_avlTreedef_t group_inst_td = + UT_AVL_TREEDEF_INITIALIZER (offsetof (struct inst, avlnode), offsetof (struct inst, next_msg_key.iid), + compare_iid, inst_augment); + +static void kvlog (const struct d_storeKV_s *st, d_level level, const char *fmt, ...) +{ + char str[512]; + va_list ap; + va_start (ap, fmt); + (void)os_vsnprintf (str, sizeof (str), fmt, ap); + va_end (ap); + if (enable_kvdebug) { + printf ("%s", str); fflush (stdout); + } + d_storeReport ((d_store) st, level, "%s", str); + switch (level) + { + case D_LEVEL_FINEST: case D_LEVEL_FINER: + case D_LEVEL_FINE: case D_LEVEL_CONFIG: + case D_LEVEL_INFO: case D_LEVEL_NONE: + break; + case D_LEVEL_WARNING: + OS_REPORT (OS_WARNING, D_CONTEXT, 0, "%s", str); + break; + case D_LEVEL_SEVERE: + OS_REPORT (OS_ERROR, D_CONTEXT, 0, "%s", str); + break; + } +} + +static void kvdebug (const char *fmt, ...) +{ + if (enable_kvdebug) { + va_list ap; + va_start (ap, fmt); + vprintf (fmt, ap); + va_end (ap); + } +} + +static d_storeResult kv_convert_result(kv_result_t rc) +{ + d_storeResult result = D_STORE_RESULT_ERROR; + + if (rc >= 0) { + return D_STORE_RESULT_OK; + } + + switch (rc) { + case KV_RESULT_ACCESS_DENIED: + result = D_STORE_RESULT_IO_ERROR; + break; + case KV_RESULT_NODATA: + result = D_STORE_RESULT_ERROR; + break; + case KV_RESULT_ERROR: + result = D_STORE_RESULT_ERROR; + break; + case KV_RESULT_CORRUPT: + result = D_STORE_RESULT_MUTILATED; + break; + case KV_RESULT_OUT_OF_RESOURCES: + result = D_STORE_RESULT_OUT_OF_RESOURCES; + break; + default: + assert(FALSE); + break; + } + + return result; +} + +/***************************************************************************** + * + * ID TABLE FUNCTIONS + * + *****************************************************************************/ + +#define IDTABLE_ENTRY_EMPTY UINT32_MAX +#define IDTABLE_INITIAL_SIZE 1024 +#define IDTABLE_INITIAL_BITS 10 +#define IDTABLE_THRESHOLD 10 + +struct idtable { + os_uint32 size; + os_uint32 scale; + os_uint32 count; + os_uint32 *entries; +}; + +static void +idtable_resize ( + struct idtable *tbl) +{ + os_uint32 oldsize = 0; + os_uint32 *entries = NULL; + os_uint32 key; + os_uint32 i; + + if (tbl->size == 0) { + tbl->size = IDTABLE_INITIAL_SIZE; + tbl->scale = IDTABLE_INITIAL_BITS; + + } else { + oldsize = tbl->size; + tbl->size *= 2; + tbl->scale++; + entries = tbl->entries; + } + + tbl->entries = os_malloc(sizeof(unsigned int) * tbl->size); + memset(tbl->entries, -1, sizeof(unsigned int) * tbl->size); + for (i = 0; i < oldsize; i++) { + if (entries[i] != IDTABLE_ENTRY_EMPTY) { + key = (os_uint32)(((entries[i] * hashTableConst) >> (64 - tbl->scale))); + while (tbl->entries[key] != IDTABLE_ENTRY_EMPTY) { + key = (key + 1) % tbl->size; + } + + tbl->entries[key] = entries[i]; + } + } + if (entries) { + os_free(entries); + } +} + +static struct idtable * +idtable_new ( + void) +{ + struct idtable *tbl = os_malloc(sizeof(struct idtable)); + tbl->size = 0; + idtable_resize(tbl); + return tbl; +} + +static void +idtable_free ( + struct idtable *tbl) +{ + if (tbl) { + if (tbl->entries) { + os_free(tbl->entries); + } + os_free(tbl); + } +} + +static int +idtable_put ( + struct idtable *tbl, + os_uint32 id) +{ + os_uint32 key; + + assert(tbl); + + key = (os_uint32)((id * hashTableConst) >> (64 - tbl->scale)); + assert(key < tbl->size); + + if (tbl->entries[key] == id) { + return 1; + } + + if (((tbl->size - tbl->count + 1) * 100) / tbl->size < IDTABLE_THRESHOLD) { + idtable_resize(tbl); + key = (os_uint32)((id * hashTableConst) >> (64 - tbl->scale)); + assert(key < tbl->size); + } + + while (tbl->entries[key] != IDTABLE_ENTRY_EMPTY) { + key = (key + 1) % tbl->size; + } + + tbl->entries[key] = id; + tbl->count++; + + return 1; +} + +static os_uint32 +idtable_get ( + struct idtable *tbl, + os_uint32 id) +{ + os_uint32 key; + + assert(tbl); + + key = (os_uint32)((id * hashTableConst) >> (64 - tbl->scale)); + assert(key < tbl->size); + + while ((tbl->entries[key] != IDTABLE_ENTRY_EMPTY) && (tbl->entries[key] != id)) { + key = (key + 1) % tbl->size; + } + + return tbl->entries[key]; +} + + +/***************************************************************************** + * + * OBJECT HASH TABLE FUNCTIONS + * + *****************************************************************************/ + +#define HASHTABLE_SIZE 1024 + +typedef os_uint32 (*hashtable_key_func_t)(void *obj); +typedef int (*hashtable_cmp_func_t)(void *obj1, void *obj2); +typedef int (*hashtable_action_func_t)(void *obj, void *arg); + + +struct hashtable_entry { + struct hashtable_entry *next; + struct hashtable_entry *link; + void *object; +}; + +struct hashtable { + os_uint32 size; + hashtable_key_func_t keyFunc; + hashtable_cmp_func_t compareFunc; + struct hashtable_entry *chain; + struct hashtable_entry **heads; +}; + + +static struct hashtable * +hashtable_new ( + hashtable_key_func_t keyFunc, + hashtable_cmp_func_t compareFunc) +{ + struct hashtable *tbl = os_malloc(sizeof(struct hashtable)); + tbl->size = HASHTABLE_SIZE; + tbl->keyFunc = keyFunc; + tbl->compareFunc = compareFunc; + tbl->chain = NULL; + tbl->heads = os_malloc(HASHTABLE_SIZE * sizeof(struct hashtable_entry *)); + memset(tbl->heads, 0, HASHTABLE_SIZE * sizeof(struct hashtable_entry *)); + return tbl; +} + +static void +hashtable_free ( + struct hashtable *tbl) +{ + struct hashtable_entry *curr; + struct hashtable_entry *next; + os_uint32 i; + + if (tbl) { + if (tbl->heads) { + for (i = 0; i < tbl->size; i++) { + curr = tbl->heads[i]; + while (curr) { + next = curr->next; + os_free(curr); + curr = next; + } + } + os_free(tbl->heads); + } + os_free(tbl); + } +} + +static void +hashtable_put ( + struct hashtable *tbl, + void *obj) +{ + os_uint32 idx; + struct hashtable_entry *entry = NULL; + + assert(tbl); + assert(obj); + + idx = tbl->keyFunc(obj) % tbl->size; + + for (entry = tbl->heads[idx]; entry; entry = entry->next) { + if (tbl->compareFunc(entry->object, obj)) { + break; + } + } + + if (!entry) { + entry = os_malloc(sizeof(struct hashtable_entry)); + entry->next = tbl->heads[idx]; + tbl->heads[idx] = entry; + entry->link = tbl->chain; + tbl->chain = entry; + entry->object = obj; + } +} + +static void +hashtable_remove_entry ( + struct hashtable *tbl, + os_uint32 idx, + struct hashtable_entry *entry) +{ + struct hashtable_entry *curr; + + assert(tbl); + assert(idx < tbl->size); + assert(entry); + + if (entry != tbl->heads[idx]) { + curr = tbl->heads[idx]; + while (curr && (curr->next != entry)) { + curr = curr->next; + } + if (curr) { + curr->next = entry->next; + } + } else { + tbl->heads[idx] = entry->next; + } + if (entry != tbl->chain) { + curr = tbl->chain; + while (curr && (curr->link != entry)) { + curr = curr->link; + } + if (curr) { + curr->link = entry->link; + } + } else { + tbl->chain = entry->link; + } + + os_free(entry); +} + +static void * +hashtable_del ( + struct hashtable *tbl, + void *obj) +{ + os_uint32 idx; + struct hashtable_entry *entry; + void *object = NULL; + + assert(tbl); + assert(obj); + + idx = tbl->keyFunc(obj) % tbl->size; + + for (entry = tbl->heads[idx]; entry; entry = entry->next) { + if (entry->object == obj) { + object = entry->object; + break; + } + } + + if (entry) { + hashtable_remove_entry(tbl, idx, entry); + } + + return object; +} + + +static void * +hashtable_find ( + struct hashtable *tbl, + os_uint32 key, + hashtable_cmp_func_t compareFunc, + void *arg) +{ + os_uint32 idx; + struct hashtable_entry *entry; + void *object = NULL; + + assert(tbl); + + idx = key % tbl->size; + + for (entry = tbl->heads[idx]; entry; entry = entry->next) { + if (compareFunc(entry->object, arg)) { + object = entry->object; + break; + } + } + + return object; +} + +static void +hashtable_walk ( + struct hashtable *tbl, + hashtable_action_func_t action, + void *arg) +{ + struct hashtable_entry *entry; + + assert(tbl); + assert(action); + + for (entry = tbl->chain; entry; entry = entry->link) { + action(entry->object, arg); + } +} + +static void * +hashtable_take ( + struct hashtable *tbl) +{ + struct hashtable_entry *entry; + void *object = NULL; + + assert(tbl); + + entry = tbl->chain; + if (entry) { + os_uint32 idx; + + object = entry->object; + assert(object); + + idx = tbl->keyFunc(object) % tbl->size; + + hashtable_remove_entry(tbl, idx, entry); + } + + return object; +} + +/***************************************************************************** + * + * SPECIAL COMPARISON FUNCTIONS + * + *****************************************************************************/ + +static int quality_le (const os_timeW *a, const os_timeW *b) +{ + os_compare eq = os_timeWCompare(*a,*b); + return ((eq == OS_LESS) || (eq == OS_EQUAL)); +} + +static int msg_cmp (const struct msg *a, const struct msg *b) +{ + /* Message ordering key precedence: time, gid, sequence number. + * Sequence number may be superfluous in this. */ + c_equality eq; + os_compare cmp; + os_int32 d; + cmp = os_timeWCompare (a->writeTime, b->writeTime); + if (cmp == OS_LESS) { + return -1; + } else if (cmp == OS_MORE) { + return 1; + } + eq = v_gidCompare (a->writerGID, b->writerGID); + if (eq == C_LT) { + return -1; + } else if (eq == C_GT) { + return 1; + } + /* Serial number arithmetic; see: + * + * - RFC 1982; + * - http://en.wikipedia.org/wiki/Serial_number_arithmetic) + * + * It seems the only reasonable way of ordering the sequence + * numbers, although it is not ideal: you can (easily) construct a + * situation in which an arbitrarily large gaps of sequence + * numbers exists between two messages that get stored and a few + * billion is still practically doable. Under those circumstances + * there is no good comparison routine with 32-bit sequence + * numbers. */ + d = (os_int32) (a->sequenceNumber - b->sequenceNumber); + if (d < 0) { + return -1; + } else if (d > 0) { + return 1; + } + return 0; +} + +static int msg_v_message_cmp (const struct msg *a, const struct v_message_s *b) +{ + struct msg b1; + b1.writeTime = b->writeTime; + b1.writerGID = b->writerGID; + b1.sequenceNumber = b->sequenceNumber; + return msg_cmp(a, &b1); +} + +static int msg_lt_v_message (const struct msg *a, const struct v_message_s *b) +{ + return msg_v_message_cmp (a, b) < 0; +} + +/***************************************************************************** + * + * RAW KEY VALUE STORE INTERFACE + * + *****************************************************************************/ + +typedef kv_result_t (*kv_close_t) (kv_store_t gst); +typedef kv_result_t (*kv_commit_t) (kv_store_t gst); +typedef kv_result_t (*kv_get_t) (kv_store_t gst, const kv_key_t *key, os_uint32 *sz, void **val, const struct c_type_s *type); +typedef kv_result_t (*kv_put_t) (kv_store_t gst, const kv_key_t *key, os_uint32 sz, const void *val, const struct c_type_s *type); +typedef kv_result_t (*kv_delete_t) (kv_store_t gst, const kv_key_t *key); +typedef kv_result_t (*kv_bulkdelete_t) (kv_store_t gst, const kv_key_t *first, const kv_key_t *last); +typedef kv_result_t (*kv_iter_new_t) (kv_store_t gst, kv_iter_t *giter, const kv_key_t *first, const kv_key_t *last, const struct c_type_s *type); +typedef kv_result_t (*kv_iter_free_t) (kv_store_t gst, kv_iter_t giter); +typedef kv_result_t (*kv_iter_next_t) (int *hasdata, kv_store_t gst, kv_iter_t giter); +typedef kv_result_t (*kv_iter_getkey_t) (kv_store_t gst, kv_iter_t giter, kv_key_t *key); +typedef kv_result_t (*kv_iter_getvalue_t) (kv_store_t gst, kv_iter_t giter, os_uint32 *sz, void **val); +typedef d_encodingKV (*kv_choose_encoding_t) (kv_store_t gst, d_encodingKV req); + +struct kv_store_common { + int write_access; + kv_kind_t kind; + kv_close_t close; + kv_commit_t commit; + kv_get_t get; + kv_put_t put; + kv_delete_t delete; + kv_bulkdelete_t bulkdelete; + kv_iter_new_t iter_new; + kv_iter_free_t iter_free; + kv_iter_next_t iter_next; + kv_iter_getkey_t iter_getkey; + kv_iter_getvalue_t iter_getvalue; + kv_choose_encoding_t choose_encoding; +}; + +static d_encodingKV kv_choose_encoding_def (kv_store_t gst, d_encodingKV req) +{ + OS_UNUSED_ARG(gst); + return req; +} + +#if KV_INCLUDE_SQLITE || KV_INCLUDE_LEVELDB +struct kv_blobkey { + os_uint32 tab_gid; + os_uint32 iid; + os_uint32 midhigh, midlow; +}; +#endif + +#if KV_INCLUDE_SQLITE +#include + +/****** BLOB-TO-BLOB MAPPING VARIANT ******/ + +static void to_blobkey (struct kv_blobkey *k, const kv_key_t *key) +{ + os_uint32 tab_gid = (key->table << 24) | key->gid; + k->tab_gid = htonl (tab_gid); + k->iid = htonl (key->iid); + k->midhigh = htonl ((os_uint32) (key->mid >> 32)); + k->midlow = htonl ((os_uint32) key->mid); +} + +static void from_blobkey (kv_key_t *key, const struct kv_blobkey *k) +{ + os_uint32 tab_gid = ntohl (k->tab_gid); + key->table = tab_gid >> 24; + key->gid = tab_gid & 0xffffff; + key->iid = ntohl (k->iid); + key->mid = (os_uint64) ntohl (k->midhigh) << 32 | ntohl (k->midlow); +} + +struct kv_store_sqlite { + struct kv_store_common c; + struct d_storeKV_s *logst; + sqlite3 *db; + sqlite3_stmt *pstmt_get; + sqlite3_stmt *pstmt_put; + sqlite3_stmt *pstmt_delete; +}; + +struct kv_iter_sqlite { + kv_table_t table; + sqlite3_stmt *pstmt; +}; + +static kv_result_t sqlite_execsimple (struct kv_store_sqlite *st, const char *sql) +{ + struct sqlite3_stmt *pstmt; + kv_result_t result; + int code; + if ((code = sqlite3_prepare_v2 (st->db, sql, (int) strlen (sql) + 1, &pstmt, NULL)) != SQLITE_OK) { + kvlog (st->logst, D_LEVEL_SEVERE, "sqlite: execsimple: prepare %s failed (%d)\n", code); + return KV_RESULT_ERROR; + } + do { + code = sqlite3_step (pstmt); + } while (code == SQLITE_ROW); + if (code != SQLITE_DONE) { + kvlog (st->logst, D_LEVEL_SEVERE, "sqlite: execsimple: step %s failed (%d)\n", sql, code); + result = KV_RESULT_ERROR; + } else { + result = 0; + } + (void)sqlite3_finalize (pstmt); + return result; +} + +static kv_result_t kv_close_sqlite (kv_store_t gst) +{ + struct kv_store_sqlite *st = (struct kv_store_sqlite *) gst; + (void)sqlite_execsimple (st, "COMMIT"); + (void)sqlite3_finalize (st->pstmt_get); + (void)sqlite3_finalize (st->pstmt_put); + (void)sqlite3_finalize (st->pstmt_delete); + sqlite3_close (st->db); + os_free (st); + return 0; +} + +static kv_result_t kv_commit_sqlite (kv_store_t gst) +{ + struct kv_store_sqlite *st = (struct kv_store_sqlite *) gst; + kv_result_t rc; + /* Commits can take very long if the store session time is long + * enough to accumulate a lot of data in the transaction. Declare + * the thread to be asleep to prevent the liveliness checker from + * complaining. A year is roughly 31e6 seconds - surely the commit + * can complete within a year ... */ + d_threadAsleep (d_threadLookupSelf (), 31000000); + if ((rc = sqlite_execsimple (st, "COMMIT")) >= 0) { + rc = sqlite_execsimple (st, "BEGIN"); + } + d_threadAwake (d_threadLookupSelf ()); + return rc; +} + +static kv_result_t kv_get_sqlite (kv_store_t gst, const kv_key_t *key, os_uint32 *sz, void **val, const struct c_type_s *type) +{ + struct kv_store_sqlite *st = (struct kv_store_sqlite *) gst; + struct sqlite3_stmt *pstmt = st->pstmt_get; + struct kv_blobkey k; + kv_result_t result; + OS_UNUSED_ARG (type); + to_blobkey (&k, key); + if (sqlite3_bind_blob (pstmt, 1, &k, sizeof (k), SQLITE_TRANSIENT) != SQLITE_OK) { + return KV_RESULT_ERROR; + } + switch (sqlite3_step (pstmt)) + { + case SQLITE_DONE: + result = KV_RESULT_NODATA; + break; + case SQLITE_ROW: + { + const void *val_alias; + os_uint32 val_sz; + val_alias = sqlite3_column_blob (pstmt, 0); + val_sz = (os_uint32) sqlite3_column_bytes (pstmt, 0); + if ((*val = os_malloc ((val_sz == 0) ? 1 : val_sz)) == NULL) { + result = KV_RESULT_OUT_OF_RESOURCES; + } else { + *sz = val_sz; + memcpy (*val, val_alias, val_sz); + result = 0; + } + break; + } + default: + result = KV_RESULT_ERROR; + break; + } + sqlite3_reset (pstmt); + return result; +} + +static kv_result_t kv_put_sqlite (kv_store_t gst, const kv_key_t *key, os_uint32 sz, const void *val, const struct c_type_s *type) +{ + struct kv_store_sqlite *st = (struct kv_store_sqlite *) gst; + struct sqlite3_stmt *pstmt = st->pstmt_put; + struct kv_blobkey k; + kv_result_t result; + int result1 = 0; + int result2 = 0; + OS_UNUSED_ARG (type); + to_blobkey (&k, key); + if (((result1 = sqlite3_bind_blob (pstmt, 1, &k, sizeof (k), SQLITE_TRANSIENT)) != SQLITE_OK) || + ((result2 = sqlite3_bind_blob (pstmt, 2, val, (int) sz, SQLITE_TRANSIENT)) != SQLITE_OK)) { + kvlog (st->logst, D_LEVEL_WARNING, "kv_put_sqlite: sqlite3_bind_blob failed, result1 = %d, result2 = %d\n", result1, result2); + return KV_RESULT_ERROR; + } + switch (sqlite3_step (pstmt)) + { + case SQLITE_DONE: + result = 0; + break; + default: + kvlog (st->logst, D_LEVEL_WARNING, "kv_put_sqlite: sqlite3_step does not return SQLITE_DONE\n"); + result = KV_RESULT_ERROR; + break; + } + sqlite3_reset (pstmt); + return result; +} + +static kv_result_t kv_delete_sqlite (kv_store_t gst, const kv_key_t *key) +{ + struct kv_store_sqlite *st = (struct kv_store_sqlite *) gst; + struct sqlite3_stmt *pstmt = st->pstmt_delete; + struct kv_blobkey k; + kv_result_t result; + to_blobkey (&k, key); + if (sqlite3_bind_blob (pstmt, 1, &k, sizeof (k), SQLITE_TRANSIENT) != SQLITE_OK) { + return KV_RESULT_ERROR; + } + switch (sqlite3_step (pstmt)) + { + case SQLITE_DONE: + result = 0; + break; + default: + result = KV_RESULT_ERROR; + break; + } + sqlite3_reset (pstmt); + return result; +} + +static kv_result_t kv_bulkdelete_sqlite (kv_store_t gst, const kv_key_t *first, const kv_key_t *last) +{ + struct kv_store_sqlite *st = (struct kv_store_sqlite *) gst; + const char *sql = "DELETE FROM data WHERE k BETWEEN ? AND ?"; + struct sqlite3_stmt *pstmt; + struct kv_blobkey k0, k1; + kv_result_t result; + if (sqlite3_prepare_v2 (st->db, sql, (int) strlen (sql) + 1, &pstmt, NULL) != SQLITE_OK) { + return KV_RESULT_ERROR; + } + to_blobkey (&k0, first); + to_blobkey (&k1, last); + if (sqlite3_bind_blob (pstmt, 1, &k0, sizeof (k0), SQLITE_TRANSIENT) != SQLITE_OK || + sqlite3_bind_blob (pstmt, 2, &k1, sizeof (k1), SQLITE_TRANSIENT) != SQLITE_OK) { + return KV_RESULT_ERROR; + } + /* Deleting a lot of data in one operation can take very long. Declare + * the thread to be asleep to prevent the liveliness checker from + * complaining. A year is roughly 31e6 seconds - surely that is enough */ + d_threadAsleep (d_threadLookupSelf (), 31000000); + switch (sqlite3_step (pstmt)) + { + case SQLITE_DONE: + result = 0; + break; + default: + result = KV_RESULT_ERROR; + break; + } + d_threadAwake (d_threadLookupSelf ()); + (void)sqlite3_finalize (pstmt); + return result; +} + +static kv_result_t kv_iter_free_sqlite (kv_store_t gst, kv_iter_t giter) +{ + kv_result_t rc = 0; + struct kv_iter_sqlite *it = (struct kv_iter_sqlite *) giter; + OS_UNUSED_ARG (gst); + if (sqlite3_finalize (it->pstmt) != SQLITE_OK) { + rc = KV_RESULT_ERROR; + } + os_free (it); + return rc; +} + +static kv_result_t kv_iter_next_sqlite (int *hasdata, kv_store_t gst, kv_iter_t giter) +{ + struct kv_iter_sqlite *it = (struct kv_iter_sqlite *) giter; + OS_UNUSED_ARG (gst); + switch (sqlite3_step (it->pstmt)) + { + case SQLITE_DONE: + *hasdata = 0; + return 0; + case SQLITE_ROW: + *hasdata = 1; + return 0; + default: + return KV_RESULT_ERROR; + } +} + +static kv_result_t kv_iter_getkey_sqlite (kv_store_t gst, kv_iter_t giter, kv_key_t *key) +{ + struct kv_iter_sqlite *it = (struct kv_iter_sqlite *) giter; + const void *val_alias; + os_uint32 val_sz; + OS_UNUSED_ARG (gst); + val_alias = sqlite3_column_blob (it->pstmt, 0); + val_sz = (os_uint32) sqlite3_column_bytes (it->pstmt, 0); + if (val_sz != sizeof (struct kv_blobkey)) { + return KV_RESULT_ERROR; + } + from_blobkey (key, val_alias); + return 0; +} + +static kv_result_t kv_iter_getvalue_sqlite (kv_store_t gst, kv_iter_t giter, os_uint32 *sz, void **val) +{ + struct kv_iter_sqlite *it = (struct kv_iter_sqlite *) giter; + const void *val_alias; + os_uint32 val_sz; + OS_UNUSED_ARG (gst); + val_alias = sqlite3_column_blob (it->pstmt, 1); + val_sz = (os_uint32) sqlite3_column_bytes (it->pstmt, 1); + if ((*val = os_malloc ((val_sz == 0) ? 1 : val_sz)) == NULL) { + return KV_RESULT_OUT_OF_RESOURCES; + } else { + *sz = val_sz; + memcpy (*val, val_alias, val_sz); + return 0; + } +} + +static kv_result_t kv_iter_new_sqlite (kv_store_t gst, kv_iter_t *giter, const kv_key_t *first, const kv_key_t *last, const struct c_type_s *type) +{ + struct kv_store_sqlite *st = (struct kv_store_sqlite *) gst; + struct kv_iter_sqlite *it; + const char *sql = "SELECT * FROM data WHERE k BETWEEN ? AND ? ORDER BY k"; + struct kv_blobkey k0, k1; + OS_UNUSED_ARG (type); + it = os_malloc (sizeof (*it)); + it->table = first->table; + if (sqlite3_prepare_v2 (st->db, sql, (int) strlen (sql) + 1, &it->pstmt, NULL) != SQLITE_OK) { + os_free (it); + return KV_RESULT_ERROR; + } + to_blobkey (&k0, first); + to_blobkey (&k1, last); + if (sqlite3_bind_blob (it->pstmt, 1, &k0, sizeof (k0), SQLITE_TRANSIENT) != SQLITE_OK || + sqlite3_bind_blob (it->pstmt, 2, &k1, sizeof (k1), SQLITE_TRANSIENT) != SQLITE_OK) { + kv_iter_free_sqlite (gst, (kv_iter_t) it); + return KV_RESULT_ERROR; + } + *giter = (kv_iter_t) it; + return 0; +} + +#define KV_SQLITE_PRAGMA_TEMPLATE "PRAGMA %s;" + +static const char *kv_sqlite_predef_parms[] = { + "locking_mode", + "journal_mode", + "wal_autocheckpoint", + "synchronous" +}; +static unsigned int kv_sqlite_predef_parms_len = sizeof(kv_sqlite_predef_parms)/sizeof(const char *); + +static int kv_configure_sqlite (struct kv_store_sqlite *st, const c_char *parameters) +{ + c_char *str; + c_char *ptr; + c_char *tok; + c_char *expr; + size_t len; + + if (parameters) { + str = os_strdup(parameters); + tok = os_strtok_r(str, ";", &ptr); + while (tok) { + c_char *s; + unsigned int i; + c_bool found = FALSE; + for (s = tok; isspace((unsigned char) *s); ++s); + for (i = 0; !found && (i < kv_sqlite_predef_parms_len); i++) { + found = os_strncasecmp(kv_sqlite_predef_parms[i], s, strlen(kv_sqlite_predef_parms[i])) == 0; + } + if (!found) { + len = strlen(KV_SQLITE_PRAGMA_TEMPLATE) + strlen(tok) + 1; + expr = os_malloc(len); + snprintf(expr, len, KV_SQLITE_PRAGMA_TEMPLATE, tok); + if (sqlite_execsimple (st, expr) < 0) { + kvlog (st->logst, D_LEVEL_WARNING, "Failed to set Sqlite pragma: %s\n", expr); + } + os_free(expr); + } + tok = os_strtok_r(NULL, ";", &ptr); + } + os_free(str); + } + + return 0; +} +#undef KV_SQLITE_PRAGMA_TEMPLATE + +static kv_store_t kv_open_sqlite (struct d_storeKV_s *logst, const char *dir, const c_char *parameters) +{ + const char *filename = "kv.sqlite"; + struct kv_store_sqlite *st; + char *path; + int ret; + size_t len; + + assert (dir); + + len = strlen (dir) + 1 + strlen (filename) + 1; + + path = os_malloc (len); + snprintf (path, len, "%s/%s", dir, filename); + + st = os_malloc (sizeof (*st)); + if ((ret = sqlite3_open (path, &st->db)) != SQLITE_OK) { + sqlite3_close (st->db); + os_free (st); + os_free (path); + return NULL; + } else { + char sql[256]; + int n; + os_free (path); + st->logst = logst; + + { + sqlite3_stmt *pstmt; + int ok; + n = snprintf (sql, sizeof (sql), "CREATE TABLE IF NOT EXISTS data (k BLOB PRIMARY KEY, v BLOB)"); + assert (n < (int) sizeof (sql)); + (void)n; + if ((ret = sqlite3_prepare_v2 (st->db, sql, (int) strlen (sql) + 1, &pstmt, NULL)) != SQLITE_OK) { + sqlite3_close (st->db); + os_free (st); + return NULL; + } + ok = (sqlite3_step (pstmt) == SQLITE_DONE); + (void)sqlite3_finalize (pstmt); + if (!ok) { + sqlite3_close (st->db); + os_free (st); + return NULL; + } + } + + n = snprintf (sql, sizeof (sql), "SELECT v FROM data WHERE k = ?"); + assert (n < (int) sizeof (sql)); + (void)n; + if ((ret = sqlite3_prepare_v2 (st->db, sql, (int) strlen (sql) + 1, &st->pstmt_get, NULL)) != SQLITE_OK) { + sqlite3_close (st->db); + os_free (st); + return NULL; + } + n = snprintf (sql, sizeof (sql), "INSERT OR REPLACE INTO data VALUES (?, ?)"); + assert (n < (int) sizeof (sql)); + (void)n; + if ((ret = sqlite3_prepare_v2 (st->db, sql, (int) strlen (sql) + 1, &st->pstmt_put, NULL)) != SQLITE_OK) { + (void)sqlite3_finalize (st->pstmt_get); + sqlite3_close (st->db); + os_free (st); + return NULL; + } + n = snprintf (sql, sizeof (sql), "DELETE FROM data WHERE k = ?"); + assert (n < (int) sizeof (sql)); + (void)n; + if ((ret = sqlite3_prepare_v2 (st->db, sql, (int) strlen (sql) + 1, &st->pstmt_delete, NULL)) != SQLITE_OK) { + (void)sqlite3_finalize (st->pstmt_get); + (void)sqlite3_finalize (st->pstmt_put); + sqlite3_close (st->db); + os_free (st); + return NULL; + } + + st->c.write_access = 1; + st->c.kind = KV_KIND_SQLITE; + st->c.close = kv_close_sqlite; + st->c.commit = kv_commit_sqlite; + st->c.get = kv_get_sqlite; + st->c.put = kv_put_sqlite; + st->c.delete = kv_delete_sqlite; + st->c.bulkdelete = kv_bulkdelete_sqlite; + st->c.iter_new = kv_iter_new_sqlite; + st->c.iter_free = kv_iter_free_sqlite; + st->c.iter_next = kv_iter_next_sqlite; + st->c.iter_getkey = kv_iter_getkey_sqlite; + st->c.iter_getvalue = kv_iter_getvalue_sqlite; + st->c.choose_encoding = kv_choose_encoding_def; + + if (sqlite_execsimple (st, "PRAGMA locking_mode=EXCLUSIVE") < 0) { + kv_close_sqlite ((kv_store_t) st); + return NULL; + } if (sqlite_execsimple (st, "PRAGMA journal_mode=WAL") < 0) { + kv_close_sqlite ((kv_store_t) st); + return NULL; + } if (sqlite_execsimple (st, "PRAGMA wal_autocheckpoint=4096") < 0) { + kv_close_sqlite ((kv_store_t) st); + return NULL; + } if (sqlite_execsimple (st, "PRAGMA synchronous=NORMAL") < 0) { + kv_close_sqlite ((kv_store_t) st); + return NULL; + } if (kv_configure_sqlite(st, parameters) != 0) { + kv_close_sqlite ((kv_store_t) st); + return NULL; + } else if (sqlite_execsimple (st, "BEGIN") < 0) { + kv_close_sqlite ((kv_store_t) st); + return NULL; + } else { + return (kv_store_t) st; + } + } +} + +/****** MULTI-TABLE VARIANT ******/ + +struct kv_store_sqlitemt { + /* Incorporate blob-to-blob sqlite so we can reuse some functions, + * the get/put/delete fields will be all 0 */ + struct kv_store_sqlite x; + sqlite3_stmt *pstmt_get[N_TABLES]; + sqlite3_stmt *pstmt_put[N_TABLES]; + sqlite3_stmt *pstmt_delete[N_TABLES]; +}; + +struct kv_iter_sqlitemt { + kv_table_t table; + int nkeys; + const struct c_type_s *type; + sqlite3_stmt *pstmt; +}; + +static const struct { + enum kv_table k; + const char *name; + const char *cols; + const char *primkey; + const char *valcols; + const char *kspec; + const char *vspec; +} kv_sqlitemt_tabtab[] = { + { TABLE_VERSION, "version", "tag INTEGER, value BLOB", + "tag", "value", + "tag = ?", + "?, ?" }, + { TABLE_TOPIC, "topics", "topic_id INTEGER, name TEXT, type_name TEXT, keylist TEXT, data TEXT", + "topic_id", "name, type_name, keylist, data", + "topic_id = ?", + "?, ?, ?, ?, ?" }, + { TABLE_TOPIC_TYPE, "topics_type", "topic_id INTEGER, type TEXT", + "topic_id", "type", + "topic_id = ?", + "?, ?" }, + { TABLE_NAMESPACE, "namespaces", "namespace_id INTEGER, namespace_version INTEGER, name TEXT", + "namespace_id, namespace_version", "name", + "namespace_id = ? AND namespace_version = ?", + "?, ?, ?" }, + { TABLE_NAMESPACE_QUALITY, "namespaces_quality", + "namespace_id INTEGER, namespace_version INTEGER, quality_sec INTEGER, quality_nsec INTEGER", + "namespace_id, namespace_version", "quality_sec, quality_nsec", + "namespace_id = ? AND namespace_version = ?", + "?, ?, ?, ?" }, + { TABLE_NAMESPACE_COMPLETENESS, "namespaces_completeness", + "namespace_id INTEGER, namespace_version INTEGER, complete INTEGER", + "namespace_id, namespace_version", "complete", + "namespace_id = ? AND namespace_version = ?", + "?, ?, ?" }, + { TABLE_GROUP, "groups", + "group_id INTEGER, topic_id INTEGER, namespace_id INTEGER, namespace_version INTEGER, partition TEXT, topic TEXT", + "group_id", + "topic_id, namespace_id, namespace_version, partition, topic", + "group_id = ?", + "?, ?, ?, ?, ?, ?" }, + { TABLE_MESSAGE, "messages", "group_id INTEGER, instance_id INTEGER, message_id INTEGER, data TEXT", + "group_id, instance_id, message_id", "data", + "group_id = ? AND instance_id = ? AND message_id = ?", + "?, ?, ?, ?" }, + { TABLE_MESSAGE_EOT, "messages_eot", "xid INTEGER, data TEXT", + "xid", "data", + "xid = ?", + "?, ?" } +}; + +static kv_result_t kv_close_sqlitemt (kv_store_t gst) +{ + struct kv_store_sqlitemt *st = (struct kv_store_sqlitemt *) gst; + int i; + (void)sqlite_execsimple (&st->x, "COMMIT"); + for (i = 0; i < N_TABLES; i++) { + (void)sqlite3_finalize (st->pstmt_get[i]); + (void)sqlite3_finalize (st->pstmt_put[i]); + (void)sqlite3_finalize (st->pstmt_delete[i]); + } + sqlite3_close (st->x.db); + os_free (st); + return 0; +} + +static kv_result_t kv_commit_sqlitemt (kv_store_t gst) +{ + return kv_commit_sqlite (gst); +} + +static void *kv_sqlitemt_ser (os_uint32 *sz, struct kv_store_sqlitemt *st, const struct c_type_s *type, const void *obj) +{ + void *blob; + if ((blob = serialize (sz, st->x.logst, type, NULL, obj)) == NULL) { + abort(); + } + return blob; +} + +static void *kv_sqlitemt_deser (struct kv_store_sqlitemt *st, const struct c_type_s *type, os_uint32 sz, const void *val) +{ + void *vx; + if (deserialize (&vx, st->x.logst, type, NULL, sz, val) < 0) { + abort(); + } + return vx; +} + +static kv_result_t kv_sqlitemt_bind_key (const kv_key_t *key, struct sqlite3_stmt *pstmt) +{ + switch (key->table) { + case TABLE_VERSION: + case TABLE_TOPIC: + case TABLE_TOPIC_TYPE: + case TABLE_GROUP: + assert (key->iid == 0 && key->mid == 0); + if (sqlite3_bind_int (pstmt, 1, (int) key->gid) != SQLITE_OK) { + return KV_RESULT_ERROR; + } + break; + case TABLE_NAMESPACE: + case TABLE_NAMESPACE_QUALITY: + case TABLE_NAMESPACE_COMPLETENESS: + assert (key->mid == 0); + if (sqlite3_bind_int (pstmt, 1, (int) key->gid) != SQLITE_OK || + sqlite3_bind_int (pstmt, 2, (int) key->iid) != SQLITE_OK) { + return KV_RESULT_ERROR; + } + break; + case TABLE_MESSAGE: + if (sqlite3_bind_int (pstmt, 1, (int) key->gid) != SQLITE_OK || + sqlite3_bind_int (pstmt, 2, (int) key->iid) != SQLITE_OK || + sqlite3_bind_int64 (pstmt, 3, (os_int64) key->mid) != SQLITE_OK) { + return KV_RESULT_ERROR; + } + break; + case TABLE_MESSAGE_EOT: + assert (key->gid == 0 && key->iid == 0); + if (sqlite3_bind_int64 (pstmt, 1, (os_int64) key->mid) != SQLITE_OK) { + return KV_RESULT_ERROR; + } + break; + } + return 0; +} + +static void kv_sqlitemt_extract_payload (os_uint32 *sz, void **val, struct kv_store_sqlitemt *st, enum kv_table table, struct sqlite3_stmt *pstmt, const struct c_type_s *type, int coloff) +{ + switch (table) { + case TABLE_VERSION: { + const void *val_alias; + os_uint32 val_sz; + val_alias = sqlite3_column_blob (pstmt, coloff); + val_sz = (os_uint32) sqlite3_column_bytes (pstmt, coloff); + *val = os_malloc ((val_sz == 0) ? 1 : val_sz); + *sz = val_sz; + memcpy (*val, val_alias, val_sz); + break; + } + case TABLE_MESSAGE: + case TABLE_MESSAGE_EOT: + case TABLE_TOPIC: + case TABLE_TOPIC_TYPE: { + const char *val_alias; + os_uint32 val_sz; + int col = (table == TABLE_TOPIC) ? 3 : 0; + val_alias = (const char *) sqlite3_column_text (pstmt, coloff + col); + val_sz = (os_uint32) (strlen (val_alias) + 1); + *val = os_malloc (val_sz); + *sz = val_sz; + memcpy (*val, val_alias, val_sz); + break; + } + case TABLE_GROUP: { + c_base base = c_getBase ((c_object) type); + struct d_groupKV *x = c_new ((c_type) type); + x->topic_id = (c_ulong) sqlite3_column_int (pstmt, coloff + 0); + x->namespace_id = (c_ulong) sqlite3_column_int (pstmt, coloff + 1); + x->namespace_version = (c_ulong) sqlite3_column_int (pstmt, coloff + 2); + x->partition = c_stringNew (base, (const char *) sqlite3_column_text (pstmt, coloff + 3)); + x->topic = c_stringNew (base, (const char *) sqlite3_column_text (pstmt, coloff + 4)); + *val = kv_sqlitemt_ser (sz, st, type, x); + c_free (x); + break; + } + case TABLE_NAMESPACE: { + c_base base = c_getBase ((c_object) type); + struct d_namespaceKV *x = c_new ((c_type) type); + x->name = c_stringNew (base, (const char *) sqlite3_column_text (pstmt, coloff + 0)); + *val = kv_sqlitemt_ser (sz, st, type, x); + c_free (x); + break; + } + case TABLE_NAMESPACE_QUALITY: { + struct d_namespaceQualityKV *x = c_new ((c_type) type); + x->quality.seconds = sqlite3_column_int (pstmt, coloff + 0); + x->quality.nanoseconds = (c_ulong) sqlite3_column_int (pstmt, coloff + 1); + *val = kv_sqlitemt_ser (sz, st, type, x); + c_free (x); + break; + } + case TABLE_NAMESPACE_COMPLETENESS: { + struct d_namespaceCompletenessKV *x = c_new ((c_type) type); + x->complete = (c_bool) sqlite3_column_int (pstmt, coloff + 0); + *val = kv_sqlitemt_ser (sz, st, type, x); + c_free (x); + break; + } + } +} + +static kv_result_t kv_get_sqlitemt (kv_store_t gst, const kv_key_t *key, os_uint32 *sz, void **val, const struct c_type_s *type) +{ + struct kv_store_sqlitemt *st = (struct kv_store_sqlitemt *) gst; + struct sqlite3_stmt *pstmt = st->pstmt_get[key->table]; + kv_result_t result; + if ((int) key->gid < 0 || (int) key->iid < 0 || (os_int64) key->mid < 0) { + return KV_RESULT_ERROR; + } + if ((result = kv_sqlitemt_bind_key (key, pstmt)) < 0) { + return result; + } + switch (sqlite3_step (pstmt)) + { + case SQLITE_DONE: + result = KV_RESULT_NODATA; + break; + case SQLITE_ROW: + result = 0; + kv_sqlitemt_extract_payload (sz, val, st, key->table, pstmt, type, 0); + break; + default: + result = KV_RESULT_ERROR; + break; + } + sqlite3_reset (pstmt); + return result; +} + +static kv_result_t kv_put_sqlitemt (kv_store_t gst, const kv_key_t *key, os_uint32 sz, const void *val, const struct c_type_s *type) +{ + struct kv_store_sqlitemt *st = (struct kv_store_sqlitemt *) gst; + struct sqlite3_stmt *pstmt = st->pstmt_put[key->table]; + kv_result_t result; + if ((int) key->gid < 0 || (int) key->iid < 0 || (os_int64) key->mid < 0) { + return KV_RESULT_ERROR; + } + if ((result = kv_sqlitemt_bind_key (key, pstmt)) < 0) { + return result; + } + result = 0; + switch (key->table) { + case TABLE_VERSION: { + if (sqlite3_bind_blob (pstmt, 2, val, (int) sz, SQLITE_TRANSIENT) != SQLITE_OK) { + result = KV_RESULT_ERROR; + } + break; + } + case TABLE_TOPIC: { + struct d_topicKV *x = kv_sqlitemt_deser (st, type, sz, val); + if (sqlite3_bind_text (pstmt, 2, x->name, -1, SQLITE_TRANSIENT) != SQLITE_OK || + sqlite3_bind_text (pstmt, 3, x->type_name, -1, SQLITE_TRANSIENT) != SQLITE_OK || + sqlite3_bind_text (pstmt, 4, x->keylist, -1, SQLITE_TRANSIENT) != SQLITE_OK || + sqlite3_bind_text (pstmt, 5, val, -1, SQLITE_TRANSIENT) != SQLITE_OK) { + result = KV_RESULT_ERROR; + } + c_free (x); + break; + } + case TABLE_TOPIC_TYPE: { + if (sqlite3_bind_text (pstmt, 2, val, (int) sz, SQLITE_TRANSIENT) != SQLITE_OK) { + result = KV_RESULT_ERROR; + } + break; + } + case TABLE_GROUP: { + struct d_groupKV *x = kv_sqlitemt_deser (st, type, sz, val); + if (sqlite3_bind_int (pstmt, 2, (int) x->topic_id) != SQLITE_OK || + sqlite3_bind_int (pstmt, 3, (int) x->namespace_id) != SQLITE_OK || + sqlite3_bind_int (pstmt, 4, (int) x->namespace_version) != SQLITE_OK || + sqlite3_bind_text (pstmt, 5, x->partition, -1, SQLITE_TRANSIENT) != SQLITE_OK || + sqlite3_bind_text (pstmt, 6, x->topic, -1, SQLITE_TRANSIENT) != SQLITE_OK) { + result = KV_RESULT_ERROR; + } + c_free (x); + break; + } + case TABLE_NAMESPACE: { + struct d_namespaceKV *x = kv_sqlitemt_deser (st, type, sz, val); + if (sqlite3_bind_text (pstmt, 3, x->name, -1, SQLITE_TRANSIENT) != SQLITE_OK) { + result = KV_RESULT_ERROR; + } + c_free (x); + break; + } + case TABLE_NAMESPACE_QUALITY: { + struct d_namespaceQualityKV *x = kv_sqlitemt_deser (st, type, sz, val); + if (sqlite3_bind_int (pstmt, 3, (int) x->quality.seconds) != SQLITE_OK || + sqlite3_bind_int (pstmt, 4, (int) x->quality.nanoseconds) != SQLITE_OK) { + result = KV_RESULT_ERROR; + } + c_free (x); + break; + } + case TABLE_NAMESPACE_COMPLETENESS: { + struct d_namespaceCompletenessKV *x = kv_sqlitemt_deser (st, type, sz, val); + if (sqlite3_bind_int (pstmt, 3, x->complete) != SQLITE_OK) { + result = KV_RESULT_ERROR; + } + c_free (x); + break; + } + case TABLE_MESSAGE: + if (sqlite3_bind_text (pstmt, 4, val, (int) sz, SQLITE_TRANSIENT) != SQLITE_OK) { + result = KV_RESULT_ERROR; + } + break; + case TABLE_MESSAGE_EOT: + if (sqlite3_bind_text (pstmt, 2, val, (int) sz, SQLITE_TRANSIENT) != SQLITE_OK) { + result = KV_RESULT_ERROR; + } + break; + } + if (result < 0) { + return result; + } + switch (sqlite3_step (pstmt)) + { + case SQLITE_DONE: + result = 0; + break; + default: + result = KV_RESULT_ERROR; + break; + } + sqlite3_reset (pstmt); + return result; +} + +static kv_result_t kv_delete_sqlitemt (kv_store_t gst, const kv_key_t *key) +{ + struct kv_store_sqlitemt *st = (struct kv_store_sqlitemt *) gst; + struct sqlite3_stmt *pstmt = st->pstmt_delete[key->table]; + kv_result_t result; + if ((int) key->gid < 0 || (int) key->iid < 0 || (os_int64) key->mid < 0) { + return KV_RESULT_ERROR; + } + if ((result = kv_sqlitemt_bind_key (key, pstmt)) < 0) { + return result; + } + switch (sqlite3_step (pstmt)) + { + case SQLITE_DONE: + result = 0; + break; + default: + result = KV_RESULT_ERROR; + break; + } + sqlite3_reset (pstmt); + return result; +} + +static int kv_sqlitemt_rangequery (char *sql, size_t sqlsize, enum kv_table table, const char *oper, const char *orderby) +{ + int nkeys = 0; + int pos; + char *primkey_copy, *cursor, *tok; + pos = snprintf (sql, sqlsize, "%s %s WHERE", oper, kv_sqlitemt_tabtab[table].name); + primkey_copy = cursor = os_strdup (kv_sqlitemt_tabtab[table].primkey); + for (tok = os_strtok_r (primkey_copy, ", ", &cursor); tok != NULL; tok = os_strtok_r (NULL, ", ", &cursor)) { + assert ((size_t) pos < sqlsize); + pos += snprintf (sql + pos, sqlsize - (size_t) pos, " %s(%s BETWEEN ? AND ?)", (nkeys == 0) ? "" : "AND ", tok); + nkeys++; + } + os_free (primkey_copy); + assert ((size_t) pos < sqlsize); + if (orderby) { + pos += snprintf (sql + pos, sqlsize - (size_t) pos, " ORDER BY %s", orderby); + assert ((size_t) pos < sqlsize); + } + return nkeys; +} + +static kv_result_t kv_sqlitemt_bindrange (struct sqlite3_stmt *pstmt, int nkeys, const kv_key_t *first, const kv_key_t *last) +{ + assert (1 <= nkeys && nkeys <= 3); + if (nkeys >= 1) { + if (sqlite3_bind_int (pstmt, 1, (int) (first->gid & 0x7fffffff)) != SQLITE_OK || + sqlite3_bind_int (pstmt, 2, (int) (last->gid & 0x7fffffff)) != SQLITE_OK) { + return KV_RESULT_ERROR; + } + } + if (nkeys >= 2) { + if (sqlite3_bind_int (pstmt, 3, (int) (first->iid & 0x7fffffff)) != SQLITE_OK || + sqlite3_bind_int (pstmt, 4, (int) (last->iid & 0x7fffffff)) != SQLITE_OK) { + return KV_RESULT_ERROR; + } + } + if (nkeys >= 3) { + if (sqlite3_bind_int64 (pstmt, 5, (os_int64) (first->mid & ~((os_uint64)1 << 63))) != SQLITE_OK || + sqlite3_bind_int64 (pstmt, 6, (os_int64) (last->mid & ~((os_uint64)1 << 63))) != SQLITE_OK) { + return KV_RESULT_ERROR; + } + } + return 0; +} + +static kv_result_t kv_bulkdelete_sqlitemt (kv_store_t gst, const kv_key_t *first, const kv_key_t *last) +{ + struct kv_store_sqlitemt *st = (struct kv_store_sqlitemt *) gst; + struct sqlite3_stmt *pstmt; + int nkeys; + char sql[512]; + kv_result_t result; + + nkeys = kv_sqlitemt_rangequery (sql, sizeof (sql), first->table, "DELETE FROM", NULL); + if (sqlite3_prepare_v2 (st->x.db, sql, -1, &pstmt, NULL) != SQLITE_OK) { + return KV_RESULT_ERROR; + } + if ((result = kv_sqlitemt_bindrange (pstmt, nkeys, first, last)) < 0) { + return result; + } + /* Deleting a lot of data in one operation can take very long. Declare + * the thread to be asleep to prevent the liveliness checker from + * complaining. A year is roughly 31e6 seconds - surely that is enough */ + d_threadAsleep (d_threadLookupSelf (), 31000000); + switch (sqlite3_step (pstmt)) + { + case SQLITE_DONE: + result = 0; + break; + default: + result = KV_RESULT_ERROR; + break; + } + d_threadAwake (d_threadLookupSelf ()); + (void)sqlite3_finalize (pstmt); + return result; +} + +static kv_result_t kv_iter_free_sqlitemt (kv_store_t gst, kv_iter_t giter) +{ + kv_result_t rc = 0; + struct kv_iter_sqlitemt *it = (struct kv_iter_sqlitemt *) giter; + OS_UNUSED_ARG (gst); + if (sqlite3_finalize (it->pstmt) != SQLITE_OK) { + rc = KV_RESULT_ERROR; + } + os_free (it); + return rc; +} + +static kv_result_t kv_iter_next_sqlitemt (int *hasdata, kv_store_t gst, kv_iter_t giter) +{ + struct kv_iter_sqlitemt *it = (struct kv_iter_sqlitemt *) giter; + OS_UNUSED_ARG (gst); + switch (sqlite3_step (it->pstmt)) + { + case SQLITE_DONE: + *hasdata = 0; + return 0; + case SQLITE_ROW: + *hasdata = 1; + return 0; + default: + return KV_RESULT_ERROR; + } +} + +static kv_result_t kv_iter_getkey_sqlitemt (kv_store_t gst, kv_iter_t giter, kv_key_t *key) +{ + struct kv_iter_sqlitemt *it = (struct kv_iter_sqlitemt *) giter; + OS_UNUSED_ARG (gst); + key->table = it->table; + if (it->nkeys >= 1) { + key->gid = (os_uint32) sqlite3_column_int (it->pstmt, 0); + } + if (it->nkeys >= 2) { + key->iid = (os_uint32) sqlite3_column_int (it->pstmt, 1); + } + if (it->nkeys >= 3) { + key->mid = (os_uint64) sqlite3_column_int64 (it->pstmt, 2); + } + return 0; +} + +static kv_result_t kv_iter_getvalue_sqlitemt (kv_store_t gst, kv_iter_t giter, os_uint32 *sz, void **val) +{ + struct kv_store_sqlitemt *st = (struct kv_store_sqlitemt *) gst; + struct kv_iter_sqlitemt *it = (struct kv_iter_sqlitemt *) giter; + OS_UNUSED_ARG (gst); + kv_sqlitemt_extract_payload (sz, val, st, it->table, it->pstmt, it->type, it->nkeys); + return 0; +} + +static kv_result_t kv_iter_new_sqlitemt (kv_store_t gst, kv_iter_t *giter, const kv_key_t *first, const kv_key_t *last, const struct c_type_s *type) +{ + struct kv_store_sqlitemt *st = (struct kv_store_sqlitemt *) gst; + struct kv_iter_sqlitemt *it; + kv_result_t result; + char sql[512]; + it = os_malloc (sizeof (*it)); + it->table = first->table; + it->type = type; + it->nkeys = kv_sqlitemt_rangequery (sql, sizeof (sql), first->table, "SELECT * FROM", kv_sqlitemt_tabtab[first->table].primkey); + if (sqlite3_prepare_v2 (st->x.db, sql, -1, &it->pstmt, NULL) != SQLITE_OK) { + os_free (it); + return KV_RESULT_ERROR; + } + if ((result = kv_sqlitemt_bindrange (it->pstmt, it->nkeys, first, last)) < 0) { + kv_iter_free_sqlite (gst, (kv_iter_t) it); + return result; + } + *giter = (kv_iter_t) it; + return 0; +} + +static d_encodingKV kv_choose_encoding_sqlitemt (kv_store_t gst, d_encodingKV req) +{ + OS_UNUSED_ARG(gst); + OS_UNUSED_ARG(req); + return D_ENCODINGKV_XML_XML; +} + +static kv_store_t kv_open_sqlitemt (struct d_storeKV_s *logst, const char *dir, const c_char *parameters) +{ + const char *filename = "kvmt.sqlite"; + struct kv_store_sqlitemt *st; + char *path; + int ret; + size_t len; + + assert (dir); + + len = strlen (dir) + 1 + strlen (filename) + 1; + + path = os_malloc (len); + snprintf (path, len, "%s/%s", dir, filename); + + st = os_malloc (sizeof (*st)); + if ((ret = sqlite3_open (path, &st->x.db)) != SQLITE_OK) { + sqlite3_close (st->x.db); + os_free (st); + os_free (path); + return NULL; + } else { + char sql[256]; + int i, n; + os_free (path); + st->x.logst = logst; + st->x.pstmt_get = 0; + st->x.pstmt_put = 0; + st->x.pstmt_delete = 0; + for (i = 0; i < N_TABLES; i++) { + st->pstmt_get[i] = 0; + st->pstmt_put[i] = 0; + st->pstmt_delete[i] = 0; + } + + assert (sizeof (kv_sqlitemt_tabtab) / sizeof (kv_sqlitemt_tabtab[0]) == (size_t) N_TABLES); + for (i = 0; i < N_TABLES; i++) { + sqlite3_stmt *pstmt; + int ok; + assert (kv_sqlitemt_tabtab[i].k == (enum kv_table) i); + n = snprintf (sql, sizeof (sql), "CREATE TABLE IF NOT EXISTS \"%s\" (%s, PRIMARY KEY(%s))", kv_sqlitemt_tabtab[i].name, kv_sqlitemt_tabtab[i].cols, kv_sqlitemt_tabtab[i].primkey); + assert (n < (int) sizeof (sql)); + if ((ret = sqlite3_prepare_v2 (st->x.db, sql, (int) (strlen (sql) + 1), &pstmt, NULL)) != SQLITE_OK) { + break; + } + ok = (sqlite3_step (pstmt) == SQLITE_DONE); + (void)sqlite3_finalize (pstmt); + if (!ok) { + break; + } + n = snprintf (sql, sizeof (sql), "SELECT %s FROM %s WHERE %s", kv_sqlitemt_tabtab[i].valcols, kv_sqlitemt_tabtab[i].name, kv_sqlitemt_tabtab[i].kspec); + assert (n < (int) sizeof (sql)); + if ((ret = sqlite3_prepare_v2 (st->x.db, sql, (int) (strlen (sql) + 1), &st->pstmt_get[i], NULL)) != SQLITE_OK) { + break; + } + n = snprintf (sql, sizeof (sql), "INSERT OR REPLACE INTO %s VALUES (%s)", kv_sqlitemt_tabtab[i].name, kv_sqlitemt_tabtab[i].vspec); + assert (n < (int) sizeof (sql)); + if ((ret = sqlite3_prepare_v2 (st->x.db, sql, (int) (strlen (sql) + 1), &st->pstmt_put[i], NULL)) != SQLITE_OK) { + break; + } + n = snprintf (sql, sizeof (sql), "DELETE FROM %s WHERE %s", kv_sqlitemt_tabtab[i].name, kv_sqlitemt_tabtab[i].kspec); + assert (n < (int) sizeof (sql)); + if ((ret = sqlite3_prepare_v2 (st->x.db, sql, (int) (strlen (sql) + 1), &st->pstmt_delete[i], NULL)) != SQLITE_OK) { + break; + } + OS_UNUSED_ARG(n); + } + + if (i != N_TABLES) { + int j; + for (j = 0; j < N_TABLES; j++) { + if (st->pstmt_get[j]) { (void)sqlite3_finalize (st->pstmt_get[j]); } + if (st->pstmt_put[j]) { (void)sqlite3_finalize (st->pstmt_put[j]); } + if (st->pstmt_delete[j]) { (void)sqlite3_finalize (st->pstmt_delete[j]); } + } + sqlite3_close (st->x.db); + os_free (st); + return NULL; + } + + st->x.c.write_access = 1; + st->x.c.kind = KV_KIND_SQLITEMT; + st->x.c.close = kv_close_sqlitemt; + st->x.c.commit = kv_commit_sqlitemt; + st->x.c.get = kv_get_sqlitemt; + st->x.c.put = kv_put_sqlitemt; + st->x.c.delete = kv_delete_sqlitemt; + st->x.c.bulkdelete = kv_bulkdelete_sqlitemt; + st->x.c.iter_new = kv_iter_new_sqlitemt; + st->x.c.iter_free = kv_iter_free_sqlitemt; + st->x.c.iter_next = kv_iter_next_sqlitemt; + st->x.c.iter_getkey = kv_iter_getkey_sqlitemt; + st->x.c.iter_getvalue = kv_iter_getvalue_sqlitemt; + st->x.c.choose_encoding = kv_choose_encoding_sqlitemt; + + if (kv_configure_sqlite (&st->x, parameters) != 0) { + kv_close_sqlitemt ((kv_store_t) st); + return NULL; + } else if (sqlite_execsimple (&st->x, "BEGIN") < 0) { + kv_close_sqlitemt ((kv_store_t) st); + return NULL; + } else { + return (kv_store_t) st; + } + } +} +#endif /* KV_INCLUDE_SQLITE */ + +#if KV_INCLUDE_LEVELDB +#include + +struct kv_store_leveldb { + struct kv_store_common c; + struct d_storeKV_s *logst; + leveldb_t *db; + os_timeW t_last_commit; + leveldb_options_t *options; + leveldb_readoptions_t *readoptions; + leveldb_writeoptions_t *writeoptions; + leveldb_writeoptions_t *writeoptions_sync; +}; + +struct kv_iter_leveldb { + leveldb_iterator_t *iter; + struct kv_blobkey first; + struct kv_blobkey last; + int started; + struct kv_blobkey cursor; +}; + +static kv_result_t kv_leveldb_err (struct kv_store_leveldb *st, char *errptr) +{ + if (errptr == NULL) { + return 0; + } else { + kvlog (st->logst, D_LEVEL_SEVERE, "leveldb: %s\n", errptr); + leveldb_free (errptr); + return KV_RESULT_ERROR; + } +} + +static kv_result_t kv_close_leveldb (kv_store_t gst) +{ + struct kv_store_leveldb *st = (struct kv_store_leveldb *) gst; + leveldb_options_destroy (st->options); + leveldb_readoptions_destroy (st->readoptions); + leveldb_writeoptions_destroy (st->writeoptions); + leveldb_writeoptions_destroy (st->writeoptions_sync); + leveldb_close (st->db); + os_free (st); + return 0; +} + +static kv_result_t kv_commit_leveldb (kv_store_t gst) +{ + const os_duration tdelta = OS_DURATION_INIT(1,0); + struct kv_store_leveldb *st = (struct kv_store_leveldb *) gst; + os_timeW tnow = os_timeWGet (); + if (1 || os_durationCompare (os_timeWDiff (tnow, st->t_last_commit), tdelta) == OS_LESS) { + return 0; + } else { + kv_key_t key; + struct kv_blobkey k; + char val = 0; + char *errptr = NULL; + st->t_last_commit = tnow; + key.table = TABLE_VERSION; + key.gid = MAX_GID; + key.iid = 0; + key.mid = 0; + to_blobkey (&k, &key); + leveldb_put (st->db, st->writeoptions_sync, (char *) &k, sizeof (k), &val, 1, &errptr); + return kv_leveldb_err (st, errptr); + } +} + +static kv_result_t kv_get_leveldb (kv_store_t gst, const kv_key_t *key, os_uint32 *sz, void **val, const struct c_type_s *type) +{ + struct kv_store_leveldb *st = (struct kv_store_leveldb *) gst; + struct kv_blobkey k; + size_t tmpsz; + char *tmpval; + char *errptr = NULL; + OS_UNUSED_ARG (type); + to_blobkey (&k, key); + tmpval = leveldb_get (st->db, st->readoptions, (char *) &k, sizeof (k), &tmpsz, &errptr); + if (errptr) { + return kv_leveldb_err (st, errptr); + } else if (tmpval == NULL) { + return KV_RESULT_NODATA; + } else { + *sz = (os_uint32) tmpsz; + if ((*val = os_malloc (*sz ? *sz : 1)) == NULL) { + leveldb_free (tmpval); + return KV_RESULT_OUT_OF_RESOURCES; + } else { + memcpy (*val, tmpval, *sz); + leveldb_free (tmpval); + return 0; + } + } +} + +static kv_result_t kv_put_leveldb (kv_store_t gst, const kv_key_t *key, os_uint32 sz, const void *val, const struct c_type_s *type) +{ + struct kv_store_leveldb *st = (struct kv_store_leveldb *) gst; + struct kv_blobkey k; + char *errptr = NULL; + OS_UNUSED_ARG (type); + to_blobkey (&k, key); + leveldb_put (st->db, st->writeoptions_sync, (char *) &k, sizeof (k), val, sz, &errptr); + return kv_leveldb_err (st, errptr); +} + +static kv_result_t kv_delete_leveldb (kv_store_t gst, const kv_key_t *key) +{ + struct kv_store_leveldb *st = (struct kv_store_leveldb *) gst; + struct kv_blobkey k; + char *errptr = NULL; + to_blobkey (&k, key); + leveldb_delete (st->db, st->writeoptions, (char *) &k, sizeof (k), &errptr); + return kv_leveldb_err (st, errptr); +} + +static kv_result_t kv_bulkdelete_leveldb (kv_store_t gst, const kv_key_t *first, const kv_key_t *last) +{ + struct kv_store_leveldb *st = (struct kv_store_leveldb *) gst; + struct kv_blobkey k0, k1; + leveldb_iterator_t *iter; + char *errptr = NULL; + to_blobkey (&k0, first); + to_blobkey (&k1, last); + if ((iter = leveldb_create_iterator (st->db, st->readoptions)) == NULL) { + return KV_RESULT_ERROR; + } + leveldb_iter_seek (iter, (char *) &k0, sizeof (k0)); + while (leveldb_iter_valid (iter)) { + const char *tmpkey; + size_t tmpsz; + if ((tmpkey = leveldb_iter_key (iter, &tmpsz)) == NULL) { + leveldb_iter_destroy (iter); + return KV_RESULT_OUT_OF_RESOURCES; + } else if (tmpsz != sizeof (k1)) { + leveldb_iter_destroy (iter); + return KV_RESULT_CORRUPT; + } else if (memcmp (tmpkey, &k1, sizeof (k1)) > 0) { + break; + } + leveldb_iter_next (iter); + leveldb_delete (st->db, st->writeoptions, tmpkey, tmpsz, &errptr); + } + leveldb_iter_get_error (iter, &errptr); + leveldb_iter_destroy (iter); + return kv_leveldb_err (st, errptr); +} + +static kv_result_t kv_iter_free_leveldb (kv_store_t gst, kv_iter_t giter) +{ + struct kv_iter_leveldb *it = (struct kv_iter_leveldb *) giter; + OS_UNUSED_ARG (gst); + leveldb_iter_destroy (it->iter); + os_free (it); + return 0; +} + +static kv_result_t kv_iter_next_leveldb (int *hasdata, kv_store_t gst, kv_iter_t giter) +{ + struct kv_store_leveldb *st = (struct kv_store_leveldb *) gst; + struct kv_iter_leveldb *it = (struct kv_iter_leveldb *) giter; + if (it->started) { + leveldb_iter_next (it->iter); + } else { + leveldb_iter_seek (it->iter, (char *) &it->first, sizeof (it->first)); + it->started = 1; + } + if (!leveldb_iter_valid (it->iter)) { + char *errptr = NULL; + leveldb_iter_get_error (it->iter, &errptr); + *hasdata = 0; + return kv_leveldb_err (st, errptr); + } else { + const char *tmpkey; + size_t tmpsz; + kv_result_t rc; + if ((tmpkey = leveldb_iter_key (it->iter, &tmpsz)) == NULL) { + return KV_RESULT_OUT_OF_RESOURCES; + } + if (tmpsz != sizeof (it->cursor)) { + rc = KV_RESULT_CORRUPT; + } else if (memcmp (tmpkey, &it->last, sizeof (it->last)) > 0) { + *hasdata = 0; + rc = 0; + } else { + memcpy (&it->cursor, tmpkey, sizeof (it->cursor)); + *hasdata = 1; + rc = 0; + } + return rc; + } +} + +static kv_result_t kv_iter_getkey_leveldb (kv_store_t gst, kv_iter_t giter, kv_key_t *key) +{ + struct kv_iter_leveldb *it = (struct kv_iter_leveldb *) giter; + OS_UNUSED_ARG (gst); + from_blobkey (key, &it->cursor); + return 0; +} + +static kv_result_t kv_iter_getvalue_leveldb (kv_store_t gst, kv_iter_t giter, os_uint32 *sz, void **val) +{ + struct kv_iter_leveldb *it = (struct kv_iter_leveldb *) giter; + const char *tmpval; + size_t tmpsz; + kv_result_t rc; + OS_UNUSED_ARG (gst); + if ((tmpval = leveldb_iter_value (it->iter, &tmpsz)) == NULL) { + return KV_RESULT_OUT_OF_RESOURCES; + } + *sz = (os_uint32) tmpsz; + if ((*val = os_malloc (*sz ? *sz : 1)) == NULL) { + rc = KV_RESULT_CORRUPT; + } else { + memcpy (*val, tmpval, tmpsz); + rc = 0; + } + return rc; +} + +static kv_result_t kv_iter_new_leveldb (kv_store_t gst, kv_iter_t *giter, const kv_key_t *first, const kv_key_t *last, const struct c_type_s *type) +{ + struct kv_store_leveldb *st = (struct kv_store_leveldb *) gst; + struct kv_iter_leveldb *it; + OS_UNUSED_ARG (type); + it = os_malloc (sizeof (*it)); + it->started = 0; + to_blobkey (&it->first, first); + to_blobkey (&it->last, last); + memset (&it->cursor, 0, sizeof (it->cursor)); + if ((it->iter = leveldb_create_iterator (st->db, st->readoptions)) == NULL) { + os_free (it); + return KV_RESULT_ERROR; + } + *giter = (kv_iter_t) it; + return 0; +} + +typedef enum { + KV_LEVELDB_PARANOID_CHECKS, + KV_LEVELDB_WRITE_BUFFER_SIZE, + KV_LEVELDB_MAX_OPEN_FILES, + KV_LEVELDB_BLOCK_SIZE, + KV_LEVELDB_VERIFY_CHECKSUMS, + KV_LEVELDB_FILL_CACHE +} kv_leveldb_parm_t; + +struct kv_leveldb_parm { + const char *name; + kv_leveldb_parm_t kind; +}; + +static struct kv_leveldb_parm kv_leveldb_parms[] = { + { "paranoid_checks", KV_LEVELDB_PARANOID_CHECKS }, + { "write_buffer_size", KV_LEVELDB_WRITE_BUFFER_SIZE }, + { "max_open_files", KV_LEVELDB_MAX_OPEN_FILES }, + { "block_size", KV_LEVELDB_BLOCK_SIZE }, + { "verify_checksums", KV_LEVELDB_VERIFY_CHECKSUMS }, + { "fill_cache", KV_LEVELDB_FILL_CACHE } +}; +static unsigned int kv_leveldb_parms_len = sizeof(kv_leveldb_parms)/sizeof(struct kv_leveldb_parm); + + +static int kv_leveldb_get_parameter(const char *pstr, char **key, char **value) +{ + c_char *str; + c_char *p; + c_char kstr[256]; + c_char vstr[256]; + int r = 0; + + *key = NULL; + *value = NULL; + + str = os_strdup(pstr); + p = os_index(str, '='); + if (p) { + *p = ' '; + if (sscanf(str, "%s%s", kstr, vstr) == 2) { + *key = os_strdup(kstr); + *value = os_strdup(vstr); + r = 1; + } + } + os_free(str); + + return r; +} + +static int kv_configure_leveldb (struct kv_store_leveldb *st, const c_char *parameters) +{ + c_char *str; + c_char *ptr; + c_char *tok; + + if (parameters) { + str = os_strdup(parameters); + tok = os_strtok_r(str, ";", &ptr); + while (tok) { + unsigned int i; + c_bool found = FALSE; + c_char *key = NULL; + c_char *value = NULL; + int val; + + if (kv_leveldb_get_parameter(tok, &key, &value)) { + for (i = 0; !found && (i < kv_leveldb_parms_len); i++) { + found = os_strncasecmp(kv_leveldb_parms[i].name, key, strlen(kv_leveldb_parms[i].name)) == 0; + } + } + if (found) { + switch (kv_leveldb_parms[i].kind) { + case KV_LEVELDB_PARANOID_CHECKS: + if (value) { + if (os_strcasecmp(value, "true") == 0) { + leveldb_options_set_paranoid_checks(st->options, 1); + } else if (os_strcasecmp(value, "false") == 0) { + leveldb_options_set_paranoid_checks(st->options, 0); + } + } + break; + case KV_LEVELDB_WRITE_BUFFER_SIZE: + if (value) { + val = atoi(value); + if (val > 0) { + leveldb_options_set_write_buffer_size(st->options, (size_t) val); + } + } + break; + case KV_LEVELDB_MAX_OPEN_FILES: + if (value) { + val = atoi(value); + if (val) { + leveldb_options_set_max_open_files(st->options, val); + } + } + break; + case KV_LEVELDB_BLOCK_SIZE: + if (value) { + val = atoi(value); + if (val > 0) { + leveldb_options_set_block_size(st->options, (size_t) val); + } + } + break; + case KV_LEVELDB_VERIFY_CHECKSUMS: + if (value) { + if (os_strcasecmp(value, "true") == 0) { + leveldb_readoptions_set_verify_checksums(st->readoptions, 1); + } else if (os_strcasecmp(value, "false") == 0) { + leveldb_readoptions_set_verify_checksums(st->readoptions, 1); + } + } + break; + case KV_LEVELDB_FILL_CACHE: + if (value) { + if (os_strcasecmp(value, "true") == 0) { + leveldb_options_set_paranoid_checks(st->options, 1); + } else if (os_strcasecmp(value, "false") == 0) { + leveldb_options_set_paranoid_checks(st->options, 0); + } + } + break; + } + } + os_free(key); + os_free(value); + tok = os_strtok_r(NULL, ";", &ptr); + } + os_free(str); + } + + return 0; +} + + +static kv_store_t kv_open_leveldb (struct d_storeKV_s *logst, const char *dir, const c_char *parameters) +{ + const char *filename = "kv.leveldb"; + struct kv_store_leveldb *st; + char *path; + char *errptr = NULL; + size_t len; + + assert (dir); + + len = strlen (dir) + 1 + strlen (filename) + 1; + + path = os_malloc (len); + snprintf (path, len, "%s/%s", dir, filename); + + st = os_malloc (sizeof (*st)); + st->logst =logst; + st->t_last_commit = os_timeWGet (); + st->options = leveldb_options_create (); + leveldb_options_set_create_if_missing (st->options, 1); + leveldb_options_set_block_size (st->options, 1048576); + + st->readoptions = leveldb_readoptions_create (); + st->writeoptions = leveldb_writeoptions_create (); + st->writeoptions_sync = leveldb_writeoptions_create (); + leveldb_writeoptions_set_sync (st->writeoptions_sync, 1); + + (void)kv_configure_leveldb(st, parameters); + + if ((st->db = leveldb_open (st->options, path, &errptr)) == NULL) { + (void) kv_leveldb_err (st, errptr); + os_free (st); + os_free (path); + return NULL; + } + + st->c.write_access = 1; + st->c.kind = KV_KIND_LEVELDB; + st->c.close = kv_close_leveldb; + st->c.commit = kv_commit_leveldb; + st->c.get = kv_get_leveldb; + st->c.put = kv_put_leveldb; + st->c.delete = kv_delete_leveldb; + st->c.bulkdelete = kv_bulkdelete_leveldb; + st->c.iter_new = kv_iter_new_leveldb; + st->c.iter_free = kv_iter_free_leveldb; + st->c.iter_next = kv_iter_next_leveldb; + st->c.iter_getkey = kv_iter_getkey_leveldb; + st->c.iter_getvalue = kv_iter_getvalue_leveldb; + st->c.choose_encoding = kv_choose_encoding_def; + + os_free(path); + + return (kv_store_t) st; +} +#endif /* KV_INCLUDE_LEVELDB */ + +#if KV_INCLUDE_LSDS +#include + +struct kv_store_lsds { + struct kv_store_common c; + struct d_storeKV_s *logst; + log_t db; +}; + +struct kv_iter_lsds { + int dummy; +}; + +static kv_result_t kv_close_lsds (kv_store_t gst) +{ + struct kv_store_lsds *st = (struct kv_store_lsds *) gst; + closelog (st->db); + os_free (st); + return 0; +} + +static kv_result_t kv_commit_lsds (kv_store_t gst) +{ + OS_UNUSED_ARG (gst); + return 0; +} + +static kv_result_t kv_get_lsds (kv_store_t gst, const kv_key_t *key, os_uint32 *sz, void **val, const struct c_type_s *type) +{ + struct kv_store_lsds *st = (struct kv_store_lsds *) gst; + uint32_t tmpsz; + struct { struct l_insertion hdr; os_uint32 realsize; } *tmpval; + l_key_t k; + OS_UNUSED_ARG (type); + k.size = 0; + k.group = ((os_uint64) key->table << 56) | ((os_uint64) key->gid << 32) | key->iid; + k.id = key->mid; + if ((tmpval = logread (&tmpsz, st->db, &k)) == NULL) { + return KV_RESULT_NODATA; + } else if (tmpsz <= sizeof (*tmpval)) { + free (tmpval); + return KV_RESULT_CORRUPT; + } else { + *sz = tmpval->realsize; + if ((*val = os_malloc (*sz ? *sz : 1)) == NULL) { + free (tmpval); + return KV_RESULT_OUT_OF_RESOURCES; + } else { + memcpy (*val, tmpval + 1, *sz); + free (tmpval); + return 0; + } + } +} + +static kv_result_t kv_put_lsds (kv_store_t gst, const kv_key_t *key, os_uint32 sz, const void *val, const struct c_type_s *type) +{ + struct kv_store_lsds *st = (struct kv_store_lsds *) gst; + l_key_t k; + struct { struct l_insertion hdr; os_uint32 realsize; } *x; + OS_UNUSED_ARG (type); + x = os_malloc (sizeof (*x) + ((sz + 7) & -8)); + x->realsize = sz; + memcpy (x + 1, val, sz); + k.size = sizeof (*x) + ((sz + 7) & -8); + k.group = ((os_uint64) key->table << 56) | ((os_uint64) key->gid << 32) | key->iid; + k.id = key->mid; + loginsertion (st->db, &k, x); + os_free (x); + return 0; +} + +static kv_result_t kv_delete_lsds (kv_store_t gst, const kv_key_t *key) +{ + struct kv_store_lsds *st = (struct kv_store_lsds *) gst; + l_key_t k; + k.size = 0; + k.group = ((os_uint64) key->table << 56) | ((os_uint64) key->gid << 32) | key->iid; + k.id = key->mid; + logdeletion (st->db, &k); + return 0; +} + +static kv_result_t kv_bulkdelete_lsds (kv_store_t gst, const kv_key_t *first, const kv_key_t *last) +{ + OS_UNUSED_ARG (gst); + OS_UNUSED_ARG (first); + OS_UNUSED_ARG (last); + return 0; +} + +static kv_result_t kv_iter_free_lsds (kv_store_t gst, kv_iter_t giter) +{ + struct kv_iter_lsds *it = (struct kv_iter_lsds *) giter; + OS_UNUSED_ARG (gst); + os_free (it); + return 0; +} + +static kv_result_t kv_iter_next_lsds (int *hasdata, kv_store_t gst, kv_iter_t giter) +{ + OS_UNUSED_ARG (gst); + OS_UNUSED_ARG (giter); + *hasdata = 0; + return 0; +} + +static kv_result_t kv_iter_getkey_lsds (kv_store_t gst, kv_iter_t giter, kv_key_t *key) +{ + OS_UNUSED_ARG (gst); + OS_UNUSED_ARG (giter); + OS_UNUSED_ARG (key); + return 0; +} + +static kv_result_t kv_iter_getvalue_lsds (kv_store_t gst, kv_iter_t giter, os_uint32 *sz, void **val) +{ + OS_UNUSED_ARG (gst); + OS_UNUSED_ARG (giter); + OS_UNUSED_ARG (sz); + OS_UNUSED_ARG (val); + return 0; +} + +static kv_result_t kv_iter_new_lsds (kv_store_t gst, kv_iter_t *giter, const kv_key_t *first, const kv_key_t *last, const struct c_type_s *type) +{ + struct kv_iter_lsds *it; + OS_UNUSED_ARG (gst); + OS_UNUSED_ARG (first); + OS_UNUSED_ARG (last); + OS_UNUSED_ARG (type); + it = os_malloc (sizeof (*it)); + *giter = (kv_iter_t) it; + return 0; +} + +static kv_store_t kv_open_lsds (struct d_storeKV_s *logst, const char *dir, const c_char *parameters) +{ + const char *filename = "kv.lsds"; + struct kv_store_lsds *st; + char *path; + + path = os_malloc (strlen (dir) + 1 + strlen (filename) + 1); + sprintf (path, "%s/%s", dir, filename); + + st = os_malloc (sizeof (*st)); + st->logst = logst; + + if (access (path, R_OK | W_OK) == -1) { + if ((st->db = newlog (path, 160 * 1048576, 2 * 1048576, 1, 100, USE_SYNC | MARK_ROOTS | ENABLE_SCAVENGER | OPTIMIZED_SCAVENGER)) == NULL) { + kvlog (logst, D_LEVEL_SEVERE, "lsds: newlog failed\n"); + } + } else if ((st->db = openlog (path, 100, USE_SYNC | MARK_ROOTS)) == NULL) { + kvlog (logst, D_LEVEL_SEVERE, "lsds: openlog failed\n"); + } + if (st->db == NULL) { + os_free (path); + os_free (st); + return NULL; + } + + st->c.write_access = 1; + st->c.kind = KV_KIND_LSDS; + st->c.close = kv_close_lsds; + st->c.commit = kv_commit_lsds; + st->c.get = kv_get_lsds; + st->c.put = kv_put_lsds; + st->c.delete = kv_delete_lsds; + st->c.bulkdelete = kv_bulkdelete_lsds; + st->c.iter_new = kv_iter_new_lsds; + st->c.iter_free = kv_iter_free_lsds; + st->c.iter_next = kv_iter_next_lsds; + st->c.iter_getkey = kv_iter_getkey_lsds; + st->c.iter_getvalue = kv_iter_getvalue_lsds; + st->c.choose_encoding = kv_choose_encoding_def; + + return (kv_store_t) st; +} +#endif /* KV_INCLUDE_LSDS */ + +#if KV_INCLUDE_DUMMY +struct kv_store_dummy { + struct kv_store_common c; +}; + +struct kv_iter_dummy { + int dummy; +}; + +static kv_result_t kv_close_dummy (kv_store_t gst) +{ + os_free (gst); + return 0; +} + +static kv_result_t kv_commit_dummy (kv_store_t gst) +{ + OS_UNUSED_ARG (gst); + return 0; +} + +static kv_result_t kv_get_dummy (kv_store_t gst, const kv_key_t *key, os_uint32 *sz, void **val, const struct c_type_s *type) +{ + OS_UNUSED_ARG (gst); + OS_UNUSED_ARG (key); + OS_UNUSED_ARG (sz); + OS_UNUSED_ARG (val); + OS_UNUSED_ARG (type); + return KV_RESULT_NODATA; +} + +static kv_result_t kv_put_dummy (kv_store_t gst, const kv_key_t *key, os_uint32 sz, const void *val, const struct c_type_s *type) +{ + OS_UNUSED_ARG (gst); + OS_UNUSED_ARG (key); + OS_UNUSED_ARG (sz); + OS_UNUSED_ARG (val); + OS_UNUSED_ARG (type); + return 0; +} + +static kv_result_t kv_delete_dummy (kv_store_t gst, const kv_key_t *key) +{ + OS_UNUSED_ARG (gst); + OS_UNUSED_ARG (key); + return 0; +} + +static kv_result_t kv_bulkdelete_dummy (kv_store_t gst, const kv_key_t *first, const kv_key_t *last) +{ + OS_UNUSED_ARG (gst); + OS_UNUSED_ARG (first); + OS_UNUSED_ARG (last); + return 0; +} + +static kv_result_t kv_iter_free_dummy (kv_store_t gst, kv_iter_t giter) +{ + struct kv_iter_dummy *it = (struct kv_iter_dummy *) giter; + OS_UNUSED_ARG (gst); + os_free (it); + return 0; +} + +static kv_result_t kv_iter_next_dummy (int *hasdata, kv_store_t gst, kv_iter_t giter) +{ + OS_UNUSED_ARG (gst); + OS_UNUSED_ARG (giter); + *hasdata = 0; + return 0; +} + +static kv_result_t kv_iter_getkey_dummy (kv_store_t gst, kv_iter_t giter, kv_key_t *key) +{ + OS_UNUSED_ARG (gst); + OS_UNUSED_ARG (giter); + OS_UNUSED_ARG (key); + return 0; +} + +static kv_result_t kv_iter_getvalue_dummy (kv_store_t gst, kv_iter_t giter, os_uint32 *sz, void **val) +{ + OS_UNUSED_ARG (gst); + OS_UNUSED_ARG (giter); + OS_UNUSED_ARG (sz); + OS_UNUSED_ARG (val); + return 0; +} + +static kv_result_t kv_iter_new_dummy (kv_store_t gst, kv_iter_t *giter, const kv_key_t *first, const kv_key_t *last, const struct c_type_s *type) +{ + struct kv_iter_dummy *it; + OS_UNUSED_ARG (gst); + OS_UNUSED_ARG (first); + OS_UNUSED_ARG (last); + OS_UNUSED_ARG (type); + it = os_malloc (sizeof (*it)); + *giter = (kv_iter_t) it; + return 0; +} + +static kv_store_t kv_open_dummy (struct d_storeKV_s *logst, const char *dir, const c_char *parameters) +{ + struct kv_store_dummy *st; + + OS_UNUSED_ARG (logst); + OS_UNUSED_ARG (parameters); + OS_UNUSED_ARG (dir); + OS_UNUSED_ARG (parameters); + + st = os_malloc (sizeof (*st)); + st->c.write_access = 1; + st->c.kind = KV_KIND_DUMMY; + st->c.close = kv_close_dummy; + st->c.commit = kv_commit_dummy; + st->c.get = kv_get_dummy; + st->c.put = kv_put_dummy; + st->c.delete = kv_delete_dummy; + st->c.bulkdelete = kv_bulkdelete_dummy; + st->c.iter_new = kv_iter_new_dummy; + st->c.iter_free = kv_iter_free_dummy; + st->c.iter_next = kv_iter_next_dummy; + st->c.iter_getkey = kv_iter_getkey_dummy; + st->c.iter_getvalue = kv_iter_getvalue_dummy; + st->c.choose_encoding = kv_choose_encoding_def; + + return (kv_store_t) st; +} +#endif /* KV_INCLUDE_DUMMY */ + +static kv_store_t kv_open (struct d_storeKV_s *logst, const char *dir, kv_kind_t kind, const c_char *parameters) +{ + switch (kind) { + case KV_KIND_SQLITE: +#if KV_INCLUDE_SQLITE + return kv_open_sqlite (logst, dir, parameters); +#else + kvlog (logst, D_LEVEL_SEVERE, "kv: sqlite support not included\n"); + return NULL; +#endif + + case KV_KIND_LEVELDB: +#if KV_INCLUDE_LEVELDB + return kv_open_leveldb (logst, dir, parameters); +#else + kvlog (logst, D_LEVEL_SEVERE, "kv: leveldb support not included\n"); + return NULL; +#endif + case KV_KIND_LSDS: +#if KV_INCLUDE_LSDS + return kv_open_lsds (logst, dir, parameters); +#else + kvlog (logst, D_LEVEL_SEVERE, "kv: lsds support not included\n"); + return NULL; +#endif + case KV_KIND_DUMMY: +#if KV_INCLUDE_DUMMY + return kv_open_dummy (logst, dir, parameters); +#else + kvlog (logst, D_LEVEL_SEVERE, "kv: dummy support not included\n"); + return NULL; +#endif + + case KV_KIND_SQLITEMT: +#if KV_INCLUDE_SQLITE + return kv_open_sqlitemt (logst, dir, parameters); +#else + kvlog (logst, D_LEVEL_SEVERE, "kv: sqlitemt support not included\n"); + return NULL; +#endif + } + + kvlog (logst, D_LEVEL_SEVERE, "kv: undefined kind requested\n"); + return NULL; +} + +static kv_result_t kv_close (kv_store_t st) +{ + return st->close (st); +} + +static kv_result_t kv_commit (kv_store_t st) +{ + return st->commit (st); +} + +static kv_result_t kv_get (kv_store_t st, const kv_key_t *key, os_uint32 *sz, void **val, const struct c_type_s *type) +{ + return st->get (st, key, sz, val, type); +} + +static kv_result_t kv_put (kv_store_t st, const kv_key_t *key, os_uint32 sz, const void *val, const struct c_type_s *type) +{ + if (st->write_access) { + return st->put (st, key, sz, val, type); + } else { + return KV_RESULT_ACCESS_DENIED; + } +} + +static kv_result_t kv_delete (kv_store_t st, const kv_key_t *key) +{ + if (st->write_access) { + return st->delete (st, key); + } else { + return KV_RESULT_ACCESS_DENIED; + } +} + +static kv_result_t kv_bulkdelete (kv_store_t st, const kv_key_t *first, const kv_key_t *last) +{ + if (st->write_access) { + return st->bulkdelete (st, first, last); + } else { + return KV_RESULT_ACCESS_DENIED; + } +} + +static kv_result_t kv_iter_new (kv_store_t st, kv_iter_t *iter, const kv_key_t *first, const kv_key_t *last, const struct c_type_s *type) +{ + /* Iterates over all keys in one table. Not doing any filtering on + * mid, but for consistency require that {first,last}->mid + * correspond to the full range. */ + assert (first->table == last->table); + assert (first->mid == 0); + assert (last->mid == ~(os_uint64)0); + return st->iter_new (st, iter, first, last, type); +} + +static kv_result_t kv_iter_free (kv_store_t st, kv_iter_t iter) +{ + return st->iter_free (st, iter); +} + +static kv_result_t kv_iter_next (int *hasdata, kv_store_t st, kv_iter_t iter) +{ + return st->iter_next (hasdata, st, iter); +} + +static kv_result_t kv_iter_getkey (kv_store_t st, kv_iter_t iter, kv_key_t *key) +{ + return st->iter_getkey (st, iter, key); +} + +static kv_result_t kv_iter_getvalue (kv_store_t st, kv_iter_t iter, os_uint32 *sz, void **val) +{ + return st->iter_getvalue (st, iter, sz, val); +} + +static d_encodingKV kv_choose_encoding (kv_store_t st, d_encodingKV req) +{ + return st->choose_encoding (st, req); +} + +/***************************************************************************** + * + * EASY KEY VALUE STORE INTERFACE + * + *****************************************************************************/ + +static kv_result_t compress (d_storeKV st, os_uint32 src_sz, const void *src, os_uint32 *dest_sz, void **dest) +{ + void *blob = NULL; + os_size_t blob_sz = 0; + os_size_t data_sz; + if (ut_compressorCompress(st->compressor, src, src_sz, &blob, &blob_sz, &data_sz) == UT_RESULT_OK) { + *dest = blob; + *dest_sz = (os_uint32)data_sz; + assert(*dest_sz == data_sz); + return 0; + } else { + return KV_RESULT_ERROR; + } +} + +static kv_result_t uncompress (d_storeKV st, os_uint32 src_sz, const void *src, os_uint32 *dest_sz, void **dest) +{ + void *blob = NULL; + os_size_t blob_sz = 0; + os_size_t data_sz; + if (ut_compressorUncompress(st->compressor, src, src_sz, &blob, &blob_sz, &data_sz) == UT_RESULT_OK) { + *dest = blob; + *dest_sz = (os_uint32)data_sz; + assert(*dest_sz == data_sz); + return 0; + } else { + return KV_RESULT_ERROR; + } +} + +static void init_ser_deser_ctx(struct ser_deser_ctx *ctx) +{ + ctx->xmsgType = NULL; + ctx->ci = NULL; +} + +static void deinit_ser_deser_ctx(struct ser_deser_ctx *ctx) +{ + if (ctx->xmsgType) { + v_messageExtTypeFree (ctx->xmsgType); + } + if (ctx->ci) { + sd_cdrInfoFree(ctx->ci); + } +} + +static void *serialize_clearflag (os_uint32 *sz, d_storeKV st, const struct c_type_s *type, struct ser_deser_ctx *ctx, const void *obj, int clearflag) + __nonnull((1,2,3,5)); + +static void *serialize_clearflag (os_uint32 *sz, d_storeKV st, const struct c_type_s *type, struct ser_deser_ctx *ctx, const void *obj, int clearflag) +{ + sd_serializedData serdata = NULL; + void *blob = NULL; + assert (type == c_getType ((c_object) obj)); + switch (st->encoding) { + case D_ENCODINGKV_XML_XML: { + sd_serializer ser = sd_serializerXMLNewTyped ((c_type) type); + serdata = sd_serializerSerialize (ser, (c_object) obj); + blob = sd_serializerToString (ser, serdata); + *sz = (os_uint32) (strlen (blob) + 1); + sd_serializerFree (ser); + break; + } + case D_ENCODINGKV_BIGE_XML: { + sd_serializer ser = sd_serializerBigENewTyped ((c_type) type); + serdata = sd_serializerSerialize (ser, (c_object) obj); + *sz = sd_serializedDataGetTotalSize (serdata); + blob = os_malloc (*sz); + memcpy (blob, serdata, *sz); + sd_serializerFree (ser); + break; + } + case D_ENCODINGKV_BIGECDR_XML: + case D_ENCODINGKV_BIGECDR_V1: + { + struct sd_cdrSerdata *sd; + const void *blob0; + assert(ctx != NULL); + if (!ctx->ci) { + if ((ctx->ci = sd_cdrInfoNew (type)) == NULL) { + return NULL; + } + if (sd_cdrCompile (ctx->ci) != 0) { + return NULL; + } + } + if (clearflag) { + sd_cdrInfoClearPadding (ctx->ci); + } + if ((sd = sd_cdrSerializeBE (ctx->ci, obj)) == NULL) { + return NULL; + } + *sz = sd_cdrSerdataBlob (&blob0, sd); + blob = os_malloc (*sz); + memcpy (blob, blob0, *sz); + sd_cdrSerdataFree (sd); + } + break; + } + if (serdata) { + sd_serializedDataFree (serdata); + } + + if ((blob) && (*sz > 0) && (st->compression != D_COMPRESSION_NONE)) { + kv_result_t result; + os_uint32 tmp_sz = 0; + void *tmp_blob = NULL; + result = compress(st, *sz, blob, &tmp_sz, &tmp_blob); + /* Check if compression does not mutilate data */ + if ((result == 0) && + (enable_kvdebug)) { + os_uint32 dest_sz; + void *dest; + if (uncompress(st, tmp_sz, tmp_blob, &dest_sz, &dest) == 0) { + if ((dest_sz != *sz) || + ((memcmp(blob, dest, *sz) != 0))) { + kvlog (st, D_LEVEL_SEVERE, "Compression check failed\n"); + assert(FALSE); + } + os_free(dest); + } + } + os_free(blob); + if (result == 0) { + blob = tmp_blob; + *sz = tmp_sz; + } else { + blob = NULL; + *sz = 0; + } + } + + return blob; +} + +static void *serialize (os_uint32 *sz, d_storeKV st, const struct c_type_s *type, struct ser_deser_ctx *ctx, const void *obj) + __nonnull((1,2,3,5)); + +static void *serialize (os_uint32 *sz, d_storeKV st, const struct c_type_s *type, struct ser_deser_ctx *ctx, const void *obj) +{ + return serialize_clearflag (sz, st, type, ctx, obj, 0); +} + +static kv_result_t deserialize (void **obj, d_storeKV st, const struct c_type_s *type, struct ser_deser_ctx *ctx, os_uint32 sz, const void *val) + __nonnull((1,2,3,6)); + +static kv_result_t deserialize (void **obj, d_storeKV st, const struct c_type_s *type, struct ser_deser_ctx *ctx, os_uint32 sz, const void *val) +{ + sd_serializer ser = NULL; + sd_serializedData serdata; + kv_result_t rc = KV_RESULT_ERROR; + const void *blob = val; + void *tmp_blob = NULL; + + assert(blob); + + if ((sz > 0) && (st->compression != D_COMPRESSION_NONE)) { + os_uint32 tmp_sz; + if ((rc = uncompress(st, sz, blob, &tmp_sz, &tmp_blob)) >= 0) { + blob = tmp_blob; + sz = tmp_sz; + } else { + return rc; + } + } + + switch (st->encoding) { + case D_ENCODINGKV_XML_XML: + if (sz == 0 || ((char *) blob)[sz-1] != 0 || strlen (blob) + 1 != sz) { + return KV_RESULT_CORRUPT; + } + ser = sd_serializerXMLNewTyped ((c_type) type); + serdata = sd_serializerFromString (ser, blob); + *obj = sd_serializerDeserialize (ser, serdata); + sd_serializedDataFree (serdata); + sd_serializerFree (ser); + if (*obj == NULL) { + rc = KV_RESULT_CORRUPT; + } else { + rc = 0; + } + break; + case D_ENCODINGKV_BIGE_XML: + ser = sd_serializerBigENewTyped ((c_type) type); + *obj = sd_serializerDeserialize (ser, (sd_serializedData) blob); + sd_serializerFree (ser); + if (*obj == NULL) { + rc = KV_RESULT_CORRUPT; + } else { + rc = 0; + } + break; + case D_ENCODINGKV_BIGECDR_XML: + case D_ENCODINGKV_BIGECDR_V1: + { + assert(ctx != NULL); + if (!ctx->ci) { + if ((ctx->ci = sd_cdrInfoNew (type)) == NULL) { + return KV_RESULT_ERROR; + } + if (sd_cdrCompile (ctx->ci) != 0) { + return KV_RESULT_ERROR; + } + } + if (sd_cdrDeserializeObjectBE (obj, ctx->ci, sz, blob) < 0) { + rc = KV_RESULT_CORRUPT; + } else { + rc = 0; + } + } + break; + } + os_free(tmp_blob); + + return rc; +} + +static kv_result_t get_deser (d_storeKV st, const kv_key_t *key, const struct c_type_s *type, struct ser_deser_ctx *ctx, void **obj) +{ + kv_result_t rc; + os_uint32 sz; + void *val; + if ((rc = kv_get (st->kv, key, &sz, &val, type)) >= 0) { + rc = deserialize (obj, st, type, ctx, sz, val); + os_free (val); + } + return rc; +} + +static kv_result_t get1_deser (d_storeKV st, kv_table_t table, os_uint32 k0, const struct c_type_s *type, struct ser_deser_ctx *ctx, void **obj) +{ + kv_key_t key; + key.table = table; key.gid = k0; key.iid = 0; key.mid = 0; + return get_deser (st, &key, type, ctx, obj); +} + +static kv_result_t get2_deser (d_storeKV st, kv_table_t table, os_uint32 k0, os_uint32 k1, const struct c_type_s *type, struct ser_deser_ctx *ctx, void **obj) +{ + kv_key_t key; + key.table = table; key.gid = k0; key.iid = k1; key.mid = 0; + return get_deser (st, &key, type, ctx, obj); +} + +static kv_result_t iter_value_deser (d_storeKV st, kv_iter_t iter, const struct c_type_s *type, struct ser_deser_ctx *ctx, void **obj) +{ + kv_result_t rc; + os_uint32 sz; + void *val; + if ((rc = kv_iter_getvalue (st->kv, iter, &sz, &val)) < 0) { + return rc; + } else { + rc = deserialize (obj, st, type, ctx, sz, val); + os_free (val); + return rc; + } +} + +static kv_result_t put_ser (d_storeKV st, const kv_key_t *key, const struct c_type_s *type, struct ser_deser_ctx *ctx, const void *obj) +{ + void *blob; + os_uint32 sz; + kv_result_t rc; + if ((blob = serialize (&sz, st, type, ctx, obj)) == NULL) { + rc = KV_RESULT_OUT_OF_RESOURCES; + } else { + rc = kv_put (st->kv, key, sz, blob, type); + os_free (blob); + } + return rc; +} + +static kv_result_t put_ser_vmsg (d_storeKV st, const kv_key_t *key, v_topic vtopic, struct ser_deser_ctx *ctx, const struct v_message_s *vmsg) +{ + void *blob = NULL; + c_type type = NULL; + os_uint32 sz = 0; + kv_result_t rc; + switch (st->encoding) { + case D_ENCODINGKV_XML_XML: + case D_ENCODINGKV_BIGE_XML: + case D_ENCODINGKV_BIGECDR_XML: + { + v_messageExt xmsg; + if (ctx->xmsgType == NULL) { + if ((ctx->xmsgType = v_messageExtTypeNew (vtopic)) == NULL) { + return KV_RESULT_OUT_OF_RESOURCES; + } + } + if ((xmsg = v_messageExtCopyToExtType (ctx->xmsgType, vmsg)) == NULL) { + return KV_RESULT_OUT_OF_RESOURCES; + } + type = ctx->xmsgType; + if ((blob = serialize (&sz, st, type, ctx, xmsg)) == NULL) { + c_free (xmsg); + return KV_RESULT_OUT_OF_RESOURCES; + } + } + break; + case D_ENCODINGKV_BIGECDR_V1: + type = c_getType ((v_message) vmsg); + if ((blob = serialize (&sz, st, type, ctx, vmsg)) == NULL) { + return KV_RESULT_OUT_OF_RESOURCES; + } + break; + } + rc = kv_put (st->kv, key, sz, blob, type); + os_free (blob); + return rc; +} + +static kv_result_t put1_ser (d_storeKV st, kv_table_t table, os_uint32 k0, const struct c_type_s *type, struct ser_deser_ctx *ctx, const void *obj) +{ + kv_key_t key; + key.table = table; key.gid = k0; key.iid = 0; key.mid = 0; + return put_ser (st, &key, type, ctx, obj); +} + +static kv_result_t put2_ser (d_storeKV st, kv_table_t table, os_uint32 k0, os_uint32 k1, const struct c_type_s *type, struct ser_deser_ctx *ctx, const void *obj) +{ + kv_key_t key; + key.table = table; key.gid = k0; key.iid = k1; key.mid = 0; + return put_ser (st, &key, type, ctx, obj); +} + +/***************************************************************************** + * + * TOPIC MANAGEMENT + * + * Note: independent treatment of namespaces and backup/restore + * functionality can lead to inconsistent topic definitions in an + * otherwise consistent persistent data store. + * + * FIXME: since we're not (yet) maintaining a topic administration in + * memory that mirrors the one on disk, topic management is sort-of + * absent. Instead, we just scan the list of the groups, which is a + * bit inefficient and silly. + * + *****************************************************************************/ + +static d_persistentTopicQosV0 d_pQosFromTopicInfo (d_storeKV st, const struct d_topicInfoKV *info) +{ + v_topicQos qos; + if ((qos = v_topicQosFromTopicInfo (st->base, &info->info)) == NULL) { + return NULL; + } else { + d_persistentTopicQosV0 pqos = d_pQosFromTopicQos (qos); + c_free (qos); + return pqos; + } +} + +static struct d_topicInfoKV *d_topicInfoFromPQos (d_storeKV st, const struct d_persistentTopicQosV0_s *pqos) +{ + v_topicQos qos; + struct d_topicInfoKV *info; + if ((qos = d_topicQosFromPQos (st->base, pqos)) == NULL) { + return NULL; + } else if ((info = c_new (st->topicinfo_type)) == NULL) { + c_free (qos); + return NULL; + } else if (v_topicQosFillTopicInfo (&info->info, qos) != V_RESULT_OK) { + c_free (info); + c_free (qos); + return NULL; + } else { + c_free (qos); + return info; + } +} + +static struct d_topicInfoKV *make_topicInfoKV (d_storeKV st, v_topic topic) +{ + struct d_topicInfoKV *info; + if ((info = c_new (st->topicinfo_type)) == NULL) { + kvlog (st, D_LEVEL_SEVERE, "Store of metadata of topic %s failed: out of memory (1)\n", v_topicName (topic)); + return NULL; + } + if ((v_topicFillTopicInfo (&info->info, topic)) != V_RESULT_OK) { + kvlog (st, D_LEVEL_SEVERE, "Store of metadata of topic %s failed: out of memory (2)\n", v_topicName (topic)); + return NULL; + } + + /* We don't want to persist the key: it is of no value whatsoever, + * and with it being absent from the old format it only creates + * problems. */ + info->info.key.systemId = + info->info.key.localId = + info->info.key.serial = 0; + return info; +} + +static int put_topicInfoKV (d_storeKV st, os_uint32 topic_id, const struct d_topicInfoKV *tp) +{ + switch (st->encoding) { + case D_ENCODINGKV_XML_XML: + case D_ENCODINGKV_BIGE_XML: + case D_ENCODINGKV_BIGECDR_XML: + { + kv_key_t topic_key, tptype_key; + void *topic_blob; + os_uint32 topic_sz; + struct d_topicKV *tp_old; + int rc = -1; + topic_key.table = TABLE_TOPIC; topic_key.gid = topic_id; topic_key.iid = 0; topic_key.mid = 0; + tptype_key.table = TABLE_TOPIC_TYPE; tptype_key.gid = topic_id; tptype_key.iid = 0; tptype_key.mid = 0; + if ((tp_old = c_new (st->topic_type)) == NULL) { + kvlog (st, D_LEVEL_SEVERE, "Storing topic %u (%s) failed: out of resources\n", topic_id, tp->info.name); + goto err_newtopic; + } + tp_old->name = c_keep (tp->info.name); + tp_old->type_name = c_keep (tp->info.type_name); + tp_old->keylist = c_keep (tp->info.key_list); + if ((tp_old->qos = d_pQosFromTopicInfo (st, tp)) == NULL) { + kvlog (st, D_LEVEL_SEVERE, "Storing topic %u (%s) failed: out of resources (qos)\n", topic_id, tp->info.name); + goto err_convqos; + } + if ((topic_blob = serialize (&topic_sz, st, st->topic_type, &st->topic_tctx, tp_old)) == NULL) { + kvlog (st, D_LEVEL_SEVERE, "Storing topic %u (%s) failed: out of resources (topic)\n", topic_id, tp->info.name); + goto err_sertopic; + } + if (kv_put (st->kv, &tptype_key, (os_uint32) strlen (tp->info.meta_data) + 1, tp->info.meta_data, c_string_t (st->base)) < 0) { + kvlog (st, D_LEVEL_SEVERE, "Storing topic type %u (%s) failed\n", topic_id, tp->info.name); + goto err_puttype; + } + if (kv_put (st->kv, &topic_key, topic_sz, topic_blob, st->topic_type) < 0) { + kvlog (st, D_LEVEL_SEVERE, "Storing topic %u (%s) failed\n", topic_id, tp->info.name); + goto err_puttopic; + } + rc = 0; + err_puttopic: + err_puttype: + os_free (topic_blob); + err_sertopic: + err_convqos: + c_free (tp_old); + err_newtopic: + return rc; + } + case D_ENCODINGKV_BIGECDR_V1: + { + kv_key_t topic_key; + void *topic_blob; + os_uint32 topic_sz; + int rc; + topic_key.table = TABLE_TOPIC; topic_key.gid = topic_id; topic_key.iid = 0; topic_key.mid = 0; + if ((topic_blob = serialize (&topic_sz, st, st->topicinfo_type, &st->topicinfo_tctx, tp)) == NULL) { + kvlog (st, D_LEVEL_SEVERE, "Storing topic %u (%s) failed: out of resources (topic)\n", topic_id, tp->info.name); + return -1; + } + if ((rc = kv_put (st->kv, &topic_key, topic_sz, topic_blob, st->topicinfo_type)) < 0) { + kvlog (st, D_LEVEL_SEVERE, "Storing topic %u (%s) failed\n", topic_id, tp->info.name); + } + os_free (topic_blob); + return rc; + } + } + assert (0); + return -1; +} + +static struct d_topicInfoKV *get_topicInfoKV (d_storeKV st, unsigned topic_id, const c_char *topic_name) +{ + switch (st->encoding) { + case D_ENCODINGKV_XML_XML: + case D_ENCODINGKV_BIGE_XML: + case D_ENCODINGKV_BIGECDR_XML: + { + kv_key_t tptype_key; + void *type_blob; + os_uint32 type_sz; + void *obj; + struct d_topicKV *old; + struct d_topicInfoKV *info; + tptype_key.table = TABLE_TOPIC_TYPE; tptype_key.gid = topic_id; tptype_key.iid = 0; tptype_key.mid = 0; + if (get1_deser (st, TABLE_TOPIC, topic_id, st->topic_type, &st->topic_tctx, &obj) < 0) { + kvlog (st, D_LEVEL_SEVERE, "Retrieval of topic %u (%s) failed: no definition found\n", topic_id, topic_name); + return NULL; + } + if (kv_get (st->kv, &tptype_key, &type_sz, &type_blob, c_string_t (st->base)) < 0) { + kvlog (st, D_LEVEL_SEVERE, "Retrieval of topic type %u (%s) failed\n", topic_id, topic_name); + c_free (obj); + return NULL; + } + if (type_sz == 0 || ((char *) type_blob)[type_sz-1] != 0) { + kvlog (st, D_LEVEL_SEVERE, "Retrieval of topic type %u (%s) failed: invalid string\n", topic_id, topic_name); + os_free (type_blob); + c_free (obj); + return NULL; + } + old = obj; + if ((info = d_topicInfoFromPQos (st, old->qos)) == NULL) { + kvlog (st, D_LEVEL_SEVERE, "Retrieval of topic %u (%s) failed: out of memory\n", topic_id, topic_name); + os_free (type_blob); + c_free (obj); + return NULL; + } + info->info.name = c_keep (old->name); + info->info.type_name = c_keep (old->type_name); + info->info.key_list = c_keep (old->keylist); + info->info.meta_data = c_stringNew (st->base, type_blob); + os_free (type_blob); + c_free (old); + return info; + } + case D_ENCODINGKV_BIGECDR_V1: + { + void *obj; + if (get1_deser (st, TABLE_TOPIC, topic_id, st->topicinfo_type, &st->topicinfo_tctx, &obj) < 0) { + kvlog (st, D_LEVEL_SEVERE, "Retrieval of topic %u (%s) failed: no definition found\n", topic_id, topic_name); + return NULL; + } + return obj; + } + } + assert (0); + return NULL; +} + +/***************************************************************************** + * + * NAMESPACES + * + *****************************************************************************/ + +struct get_namespace_helper_arg { + const char *partition; + const char *topic; + os_uint32 rank; + d_nameSpace namespace; + int found; +}; + +static struct namespace *find_namespace (const struct d_storeKV_s *st, const d_nameSpace nameSpace) +{ + /* Namespaces sorted s.t. (id,v) precedes (id,w) if v>w. + * Therefore, returns latest version of name space. */ + const char *nsname = d_nameSpaceGetName (nameSpace); + struct namespace *ns; + for (ns = st->namespaces; ns; ns = ns->next) { + if (strcmp (ns->name, nsname) == 0) { + return ns; + } + } + return NULL; +} + +static struct namespace *find_namespace_by_id (const struct d_storeKV_s *st, os_uint32 nsid) +{ + /* Namespaces sorted s.t. (id,v) precedes (id,w) if v>w. + * Therefore, returns latest version of name space. */ + struct namespace *ns; + for (ns = st->namespaces; ns; ns = ns->next) { + if (ns->id == nsid) { + return ns; + } + } + return NULL; +} + +static struct namespace *find_namespace_by_id_version (const struct d_storeKV_s *st, os_uint32 nsid, os_uint32 nsversion) +{ + struct namespace *ns; + for (ns = st->namespaces; ns; ns = ns->next) { + if (ns->id == nsid && ns->version == nsversion) { + return ns; + } + } + return NULL; +} + +#ifndef NDEBUG +static int namespace_id_is_free (const struct d_storeKV_s *st, os_uint32 nsid) +{ + struct namespace *ns; + for (ns = st->namespaces; ns; ns = ns->next) { + if (ns->id == nsid) { + return 0; + } + } + return 1; +} +#endif + +static struct namespace *new_namespace_common (struct d_storeKV_s *st, os_uint32 nsid, os_uint32 version, const char *name, const os_timeW *quality, int on_disk) +{ + struct namespace *ns; + assert (namespace_id_is_free (st, nsid) || version > find_namespace_by_id (st, nsid)->version); + ns = os_malloc (sizeof (*ns)); + ns->id = nsid; + ns->version = version; + ns->name = os_strdup (name); + if (quality) { + ns->quality = *quality; + } else { + ns->quality = OS_TIMEW_ZERO; + } + ns->on_disk = on_disk; + /* Insert at head maintains sort order */ + ns->next = st->namespaces; + st->namespaces = ns; + if (nsid >= st->next_namespace_id) { + st->next_namespace_id = nsid + 1; + } + return ns; +} + +static struct namespace *new_namespace (struct d_storeKV_s *st, os_uint32 nsid, const char *name, const os_timeW *quality, int on_disk) +{ + return new_namespace_common (st, nsid, 0, name, quality, on_disk); +} + +static struct namespace *new_namespace_version (struct d_storeKV_s *st, const struct namespace *old_version) +{ + return new_namespace_common (st, old_version->id, old_version->version + 1, old_version->name, NULL, 0); +} + +static struct namespace *find_or_create_namespace (struct d_storeKV_s *st, const d_nameSpace nameSpace) +{ + struct namespace *ns; + if ((ns = find_namespace (st, nameSpace)) == NULL) { + ns = new_namespace (st, st->next_namespace_id, d_nameSpaceGetName (nameSpace), NULL, 0); + } + return ns; +} + +static d_storeResult store_namespace_quality (d_storeKV st, struct namespace *ns) +{ + struct d_namespaceQualityKV *q; + d_storeResult result; + kv_result_t rc; + + kvdebug ("Namespace %s id %u/%u quality %"PA_PRItime" updating-disk\n", + ns->name, ns->id, ns->version, OS_TIMEW_PRINT(ns->quality)); + q = c_new (st->namespace_quality_type); + /* Map quality to c_time, store quality as extended time (64-bit) */ + d_qualityExtFromQuality(&q->quality, &ns->quality, TRUE); + if ((rc = put2_ser (st, TABLE_NAMESPACE_QUALITY, ns->id, ns->version, st->namespace_quality_type, &st->namespace_quality_tctx, q)) < 0) { + result = kv_convert_result(rc); + } else { + result = D_STORE_RESULT_OK; + } + c_free (q); + return result; +} + + +static d_storeResult set_namespace_quality (d_storeKV st, struct namespace *ns, const os_timeW *quality) +{ + if (quality_le (quality, &ns->quality)) { + return D_STORE_RESULT_OK; + } + + ns->quality = *quality; + if (ns->on_disk) { + return store_namespace_quality (st, ns); + } else { + kvdebug ("Namespace %s id %u/%u quality %"PA_PRItime" not-updating-disk\n", + ns->name, ns->id, ns->version, OS_TIMEW_PRINT(*quality)); + return D_STORE_RESULT_OK; + } +} + +static d_storeResult set_namespace_quality_deferred (d_storeKV st, struct namespace *ns, const os_timeW *quality) +{ + if (quality_le (quality, &ns->quality)) { + return D_STORE_RESULT_OK; + } + + ns->quality = *quality; + if (ns->on_disk) { + hashtable_put(st->updated_namespaces, ns); + } else { + kvdebug ("Namespace %s id %u/%u quality %"PA_PRItime" not-updating-disk\n", ns->name, ns->id, ns->version, OS_TIMEW_PRINT(*quality)); + } + + return D_STORE_RESULT_OK; +} + + +static d_storeResult store_namespace (struct d_storeKV_s *st, struct namespace *ns) +{ + d_storeResult result; + kv_result_t rc; + + if (ns->on_disk) { + kvlog (st, D_LEVEL_FINEST, "Namespace %s id %u/%u already on disk\n", ns->name, ns->id, ns->version); + result = D_STORE_RESULT_OK; + } else { + struct d_namespaceKV *d; + d = c_new (st->namespace_type); + d->name = c_stringNew (c_getBase (d), ns->name); + if ((rc = put2_ser (st, TABLE_NAMESPACE, ns->id, ns->version, st->namespace_type, &st->namespace_tctx, d)) < 0) { + result = kv_convert_result(rc); + kvlog (st, D_LEVEL_SEVERE, "Namespace %s id %u/%u could not be written to disk\n", ns->name, ns->id, ns->version); + } else { + result = D_STORE_RESULT_OK; + kvlog (st, D_LEVEL_FINEST, "Namespace %s id %u/%u written to disk\n", ns->name, ns->id, ns->version); + ns->on_disk = 1; + } + c_free (d); + } + return result; +} + +static void free_namespace (struct namespace *ns) +{ + if (ns) { + os_free (ns->name); + os_free (ns); + } +} + +static os_uint32 get_namespace_key (const struct namespace *ns) +{ + return ns->id; +} + +static int compare_namespace_by_name (const struct namespace *ns1, const struct namespace *ns2) +{ + assert(ns1); + assert(ns2); + + return strcmp(ns1->name, ns2->name) == 0; +} + +static int compare_namespace_by_id (const struct namespace *ns1, const struct namespace *ns2) +{ + assert(ns1); + assert(ns2); + + return ns1->id == ns2->id; +} + + +/***************************************************************************** + * + * LOCAL GROUP MANAGEMENT + * + * Note: see comment at TOPIC MANAGEMENT. Furthermore, the use of a + * mostly-unsorted linked list is a bit silly. It would be much + * better to use a hash table, or even an balanced binary tree. + * + *****************************************************************************/ +static os_uint32 get_partition_topic_key (const char *partition, const char *topic) +{ + os_uint32 result = 5381; + const char *ptr; + unsigned c; + + ptr = partition; + while((c = (unsigned char) *ptr++)) { + result = ((result << 5) + result) ^ c; + } + + ptr = topic; + while((c = (unsigned char) *ptr++)) { + result = ((result << 5) + result) ^ c; + } + + return result; +} + +static os_uint32 get_group_key (const struct d_groupListKV_s *g) +{ + assert (g); + return get_partition_topic_key(g->_parent.partition, g->_parent.topic); +} + + +static int compare_group (const struct d_groupListKV_s *g1, const struct d_groupListKV_s *g2) +{ + assert(g1); + assert(g2); + + return (strcmp (g1->_parent.topic, g2->_parent.topic) == 0 && strcmp (g1->_parent.partition, g2->_parent.partition) == 0); +} + +struct find_group_helper_arg { + const char *partition; + const char *topic; +}; + +static int find_group_helper (const struct d_groupListKV_s *g, struct find_group_helper_arg *arg) +{ + assert(g); + assert(arg); + + return (strcmp (g->_parent.topic, arg->topic) == 0 && strcmp (g->_parent.partition, arg->partition) == 0); +} + +static int group_latest_namespace_version (const struct d_storeKV_s *st, const struct d_groupListKV_s *g) +{ + const struct namespace *ns; + for (ns = st->namespaces; ns; ns = ns->next) { + if (ns->id == g->namespace->id) { + break; + } + } + assert (ns != NULL); + return ns == g->namespace; +} + +static d_groupListKV find_group (const struct d_storeKV_s *st, const char *partition, const char *topic) +{ + const struct d_groupListKV_s *g; + os_uint32 key; + struct find_group_helper_arg arg; + + key = get_partition_topic_key(partition, topic); + arg.partition = partition; + arg.topic = topic; + + if ((g = hashtable_find(st->groupTable, key, (hashtable_cmp_func_t)find_group_helper, &arg)) != NULL) { + return (d_groupListKV) (group_latest_namespace_version (st, g) ? g : NULL); + } + + return NULL; +} + +static d_groupListKV find_group_w_topic (const struct d_storeKV_s *st, const char *topic) +{ + /* FIXME: Should do a proper in-memory topic name -> id mapping that + * is kept consistent with the data on disk. */ + const struct d_groupListKV_s *g; + for (g = st->groups; g != NULL; g = g->_parent.next) { + if (strcmp (g->_parent.topic, topic) == 0) { + return (d_groupListKV) (group_latest_namespace_version (st, g) ? g : NULL); + } + } + return NULL; +} + +static d_groupListKV find_group_w_kernelgroup (const struct d_storeKV_s *st, const struct v_group_s *group) +{ + /* FIXME: Should do a proper in-memory topic name -> id mapping that + * is kept consistent with the data on disk. */ + return find_group (st, v_partitionName (v_groupPartition ((c_object)group)), v_topicName (v_groupTopic ((c_object)group))); +} + +static d_storeResult new_group (d_groupListKV *pg, d_storeKV st, os_uint32 group_id, struct namespace *ns, const char *partition, os_uint32 topic_id, const char *topic, const os_timeW *quality) +{ + d_storeResult result; + d_groupListKV g; + struct d_groupListKV_s *PresentGroupInList = NULL; + os_uint32 key; + struct find_group_helper_arg arg; + assert (find_group (st, partition, topic) == NULL); + if ((g = os_malloc (sizeof (*g))) == NULL) { + result = D_STORE_RESULT_OUT_OF_RESOURCES; + } else if ((result = set_namespace_quality (st, ns, quality)) != D_STORE_RESULT_OK) { + os_free (g); + } else { + g->_parent.partition = os_strdup (partition); + g->_parent.topic = os_strdup (topic); + g->_parent.quality = *quality; + g->_parent.completeness = D_GROUP_INCOMPLETE; + g->_parent.optimized = FALSE; + g->_parent.next = st->groups; + g->group_id = group_id; + g->topic_id = topic_id; + g->instances = d_tableNew(inst_cmp, inst_free); + ut_avlInit (&group_inst_td, &g->instances_by_iid); + g->namespace = ns; + g->vgroup = NULL; + init_ser_deser_ctx (&g->tctx); + g->tctx.ci = NULL; + st->groups = g; + *pg = g; + + key = get_partition_topic_key(partition, topic); + arg.partition = partition; + arg.topic = topic; + PresentGroupInList = hashtable_find(st->groupTable, key, (hashtable_cmp_func_t)find_group_helper, &arg); + if (PresentGroupInList != NULL) { + /* check version of namespace from same group */ + if (PresentGroupInList->namespace->version < ns->version) { + /* old group present with lower version nr in hash table, needs to be overwritten by newer one, delete old one */ + (void)hashtable_del(st->groupTable, PresentGroupInList); + } + } + /* always put new group, if same already present this one will be ignored */ + hashtable_put(st->groupTable, g); + } + return result; +} + +static void free_group (struct d_groupListKV_s *g, d_storeKV st) +{ + void* pvTest = NULL; + /* be sure freed group is not in hash table anymore */ + pvTest = hashtable_del(st->groupTable, g); + if (pvTest != NULL) { + /* this group was also in hash table, find lower version group if present to insert in hash table (rollback?) */ + struct d_groupListKV_s *fg = st->groups; + struct d_groupListKV_s *pstNewGroupToInsert = NULL; + while (fg) { + if ((fg != g) && (strcmp(fg->_parent.topic, g->_parent.topic) == 0) && (strcmp(fg->_parent.partition, g->_parent.partition) == 0)) { + if (pstNewGroupToInsert == NULL) { + pstNewGroupToInsert = fg; + } + else if (fg->namespace->version > pstNewGroupToInsert->namespace->version) { + pstNewGroupToInsert = fg; + } + } + fg = fg->_parent.next; + } + if (pstNewGroupToInsert != NULL) { + hashtable_put(st->groupTable, pstNewGroupToInsert); + } + } + d_tableFree(g->instances); + deinit_ser_deser_ctx (&g->tctx); + os_free (g->_parent.partition); + os_free (g->_parent.topic); + os_free (g); +} + +/***************************************************************************** + * + * LOCAL INSTANCE MANAGEMENT + * + *****************************************************************************/ + +static d_storeResult get_blobkey (size_t *psz, void **pval, const struct v_group_s *group, const struct v_message_s *msg) +{ + c_size sz = 0; + c_ulong i, nkeys; + c_array keylist; + char *ptr; + + assert (psz && pval && group && msg); + + keylist = v_topicMessageKeyList (v_groupTopic ((c_object)group)); + (void)c_getType ((v_message) msg); + nkeys = c_arraySize (keylist); + + /* First determine size of key blob. We don't care what the + * ordering looks like to a human, only that it is a total + * ordering of instances. Hence we can get away by simply + * concatenating the binary representation of all fields. Strings + * will vary in length, so fields won't be in the same place all + * the time. FIXME: is this really safe, or should I do the + * scalars first? + * + * Allocate at least 1 byte to be certain that we don't get a null + * pointer because we want to pass them straight into memcmp, + * which has undefined behaviour when passed a null pointer even + * when the number of bytes to compare is 0. */ + for (i = 0; i < nkeys; i++) { + sz += c_fieldBlobSize (keylist[i], (c_object) msg); + } + *psz = (size_t) sz; + if ((*pval = os_malloc (sz == 0 ? 1 : sz)) == NULL) { + return D_STORE_RESULT_OUT_OF_RESOURCES; + } + ptr = *pval; + for (i = 0; i < nkeys; i++) { + ptr += c_fieldBlobCopy (keylist[i], (c_object) msg, ptr); + } + return D_STORE_RESULT_OK; +} + + +static int transaction_list_cmp (const struct transaction_list *a, const struct transaction_list *b) +{ + c_equality eq; + + /* comparision of transaction lists is based on writerGID and transactionId */ + eq = v_gidCompare (a->gid, b->gid); + if (eq == C_LT) { + return -1; + } else if (eq == C_GT) { + return 1; + } else if (a->seqNum < b->seqNum) { + return -1; + } else if (a->seqNum > b->seqNum) { + return 1; + } + return 0; +} + + +static int inst_cmp (const struct inst *a, const struct inst *b) +{ + /* All we need is a total ordering of instances, and the only time + * we need to lookup an inst is when we get a v_message and need + * the corresponding inst. Hence the instance compare function + * is based on the real key rather than the (unique) instance_id. + * The key is treated as a blob, on which we do memcmp. */ + size_t sz = (a->keysize < b->keysize) ? a->keysize : b->keysize; + int eq = memcmp (a->keyvalue, b->keyvalue, sz); + if (eq < 0) { + return -1; + } else if (eq > 0) { + return 1; + } else if (a->keysize < b->keysize) { + return -1; + } else if (a->keysize > b->keysize) { + return 1; + } else { + return 0; + } +} + +static int compare_iid (const void *va, const void *vb) +{ + const os_uint32 *a = va; + const os_uint32 *b = vb; + return (*a == *b) ? 0 : (*a < *b) ? -1 : 1; +} + +static void inst_augment (void *vinst, const void *vleft, const void *vright) +{ + struct inst *inst = vinst; + const struct inst *left = vleft; + const struct inst *right = vright; + const os_uint32 iid = inst->next_msg_key.iid; + os_uint32 holep1; + + if (left && left->iid_holep1) { + holep1 = left->iid_holep1; + } else if (left && iid > left->iid_max + 1) { + holep1 = iid; + } else if (right && iid + 1 < right->iid_min) { + holep1 = right->iid_min; + } else if (right && right->iid_holep1) { + holep1 = right->iid_holep1; + } else { + holep1 = 0; + } + + inst->iid_holep1 = holep1; + inst->iid_min = left ? left->iid_min : iid; + inst->iid_max = right ? right->iid_max : iid; +} + +static int new_instance_id (struct d_storeKV_s *st, os_uint32 *iid, const struct d_groupListKV_s *g, const os_uint32 *p_iid) +{ + int ok; + if (p_iid) { + if (ut_avlLookup (&group_inst_td, &g->instances_by_iid, p_iid) == NULL) { + *iid = *p_iid; + ok = 1; + } else { + kvlog (st, D_LEVEL_SEVERE, "new_instance_id: required id %u already in use\n", *p_iid); + ok = 0; + } + } else if (ut_avlIsEmpty (&g->instances_by_iid)) { + *iid = 0; + ok = 1; + } else { + struct inst *r = ut_avlRoot (&group_inst_td, &g->instances_by_iid); + if (r->iid_min) { + *iid = r->iid_min - 1; + ok = 1; + } else if (r->iid_holep1) { + *iid = r->iid_holep1 - 1; + ok = 1; + } else if (r->iid_max != 0xffffffff) { + *iid = r->iid_max + 1; + ok = 1; + } else { + kvlog (st, D_LEVEL_SEVERE, "new_instance_id: no available instance id\n"); + ok = 0; + } + } + assert (!ok || ut_avlLookup (&group_inst_td, &g->instances_by_iid, iid) == NULL); + return ok; +} + + +static struct inst *new_instance (struct d_storeKV_s *st, struct d_groupListKV_s *g, size_t keysize, void *keyvalue, const os_uint32 *p_iid) +{ + struct inst *inst; + + inst = os_malloc (sizeof (*inst)); + inst->next_msg_key.table = TABLE_MESSAGE; + inst->next_msg_key.gid = g->group_id; + if (!new_instance_id (st, &inst->next_msg_key.iid, g, p_iid)) { + os_free (inst); + return NULL; + } + inst->next_msg_key.mid = 0; + + inst->keysize = keysize; + inst->keyvalue = keyvalue; + + inst->g = g; + + inst->writeCount = 0; + inst->oldest = NULL; + inst->latest = NULL; + inst->oldest_non_transaction = NULL; + + return inst; +} + +static d_storeResult find_instance (struct inst **inst, struct d_groupListKV_s *g, const struct v_group_s *group, const struct v_message_s *msg) +{ + d_storeResult result; + size_t sz; + void *val; + if ((result = get_blobkey (&sz, &val, group, msg)) == D_STORE_RESULT_OK) { + struct inst tmp; + tmp.keysize = sz; + tmp.keyvalue = val; + *inst = d_tableFind (g->instances, &tmp); + os_free (val); + } + return result; +} + +static d_storeResult find_or_create_instance (struct inst **inst, struct d_storeKV_s *st, struct d_groupListKV_s *g, const struct v_group_s *group, const struct v_message_s *msg, const os_uint32 *p_iid) +{ + d_storeResult result; + size_t sz; + void *val; + if ((result = get_blobkey (&sz, &val, group, msg)) == D_STORE_RESULT_OK) { + struct inst tmp; + tmp.keysize = sz; + tmp.keyvalue = val; + if ((*inst = d_tableFind (g->instances, &tmp)) != NULL) { + assert (p_iid == NULL || (*inst)->next_msg_key.iid == *p_iid); + assert (ut_avlLookup (&group_inst_td, &g->instances_by_iid, &(*inst)->next_msg_key.iid) == *inst); + os_free (val); + } else if ((*inst = new_instance (st, g, sz, val, p_iid)) == NULL) { + os_free (val); + result = D_STORE_RESULT_OUT_OF_RESOURCES; + } else if (d_tableInsert (g->instances, *inst) != NULL) { + kvlog (st, D_LEVEL_SEVERE, "find_or_create_instance: inconsistent instance table\n"); + inst_free (*inst); + result = D_STORE_RESULT_MUTILATED; + } else { + assert (ut_avlLookup (&group_inst_td, &g->instances_by_iid, &(*inst)->next_msg_key.iid) == NULL); + ut_avlInsert (&group_inst_td, &g->instances_by_iid, *inst); + } + } + return result; +} + + +static void msg_free (struct msg *m) +{ + if (m->v_msg) { + c_free (m->v_msg); + } + os_free (m); +} + +static void inst_free (struct inst *a) +{ + while (a->oldest) { + struct msg *m = a->oldest; + a->oldest = m->newer; + msg_free (m); + } + os_free (a->keyvalue); + os_free (a); +} + + +static void transaction_list_free (struct transaction_list *a) { + struct transaction_msg *tr_msg; + + tr_msg = a->head; + while (tr_msg) { + struct transaction_msg *tr_m = tr_msg; + tr_msg = tr_msg->next; + os_free(tr_m); + } + os_free(a); +} + +static d_storeResult init_namespaces (d_storeKV st) +{ + /* Note: iteration of keys is in ascending order, therefore newer + * versions of a namespace are inserted later than older versions, + * which matches the assumption in new_namespace() */ + d_storeResult result = D_STORE_RESULT_OK; + struct d_namespaceQualityKV *default_nsq; + kv_key_t min, max; + kv_iter_t iter; + int hasdata; + os_timeW quality; + + kvlog (st, D_LEVEL_FINE, "Loading namespaces ...\n"); + assert (st->groups == NULL); + + min.table = TABLE_NAMESPACE; + min.gid = 0; + min.iid = 0; + min.mid = 0; + max.table = TABLE_NAMESPACE; + max.gid = MAX_GID; + max.iid = ~(os_uint32)0; + max.mid = ~(os_uint64)0; + + default_nsq = c_new (st->namespace_quality_type); + default_nsq->quality.seconds = 0; + default_nsq->quality.nanoseconds = 0; + kv_iter_new (st->kv, &iter, &min, &max, st->namespace_type); + while (result == D_STORE_RESULT_OK && kv_iter_next (&hasdata, st->kv, iter) >= 0 && hasdata) { + kv_key_t k; + void *obj; + kv_iter_getkey (st->kv, iter, &k); + if (iter_value_deser (st, iter, st->namespace_type, &st->namespace_tctx, &obj) < 0) { + kvlog (st, D_LEVEL_SEVERE, "namespace {%u:%u:%llu:%llu}: stored data is corrupt\n", + (unsigned) k.table, k.gid, k.iid, k.mid); + result = D_STORE_RESULT_MUTILATED; + } else { + const struct d_namespaceKV *nskv = obj; + struct d_namespaceQualityKV *nsq; + struct namespace *ns; + void *tmp; + if (get2_deser (st, TABLE_NAMESPACE_QUALITY, k.gid, k.iid, st->namespace_quality_type, &st->namespace_quality_tctx, &tmp) >= 0) { + nsq = tmp; + } else { + nsq = c_keep (default_nsq); + } + /* Map qualityExt to quality, use extended time (64-bit) */ + d_qualityExtToQuality(&quality, &nsq->quality, TRUE); + if ((ns = new_namespace_common (st, k.gid, k.iid, nskv->name, &quality, 1)) == NULL) { + kvlog (st, D_LEVEL_SEVERE, "namespace %s id %u/%u: out of resources\n", nskv->name, k.gid, k.iid); + } else { + kvlog (st, D_LEVEL_FINE, " namespace %s id %u/%u quality %"PA_PRItime"\n", nskv->name, k.gid, k.iid, OS_TIMEW_PRINT(quality)); + } + c_free (nsq); + c_free (obj); + } + } + kv_iter_free (st->kv, iter); + c_free (default_nsq); + return result; +} + +static d_storeResult init_groups (d_storeKV st) +{ + d_storeResult result = D_STORE_RESULT_OK; + kv_key_t min, max; + kv_iter_t iter; + int hasdata; + + kvlog (st, D_LEVEL_FINE, "Loading groups ...\n"); + assert (st->groups == NULL); + + min.table = TABLE_GROUP; + min.gid = 0; + min.iid = 0; + min.mid = 0; + max.table = TABLE_GROUP; + max.gid = MAX_GID; + max.iid = ~(os_uint32)0; + max.mid = ~(os_uint64)0; + + kv_iter_new (st->kv, &iter, &min, &max, st->group_type); + while (result == D_STORE_RESULT_OK && kv_iter_next (&hasdata, st->kv, iter) >= 0 && hasdata) { + kv_key_t k; + void *obj; + kv_iter_getkey (st->kv, iter, &k); + if (iter_value_deser (st, iter, st->group_type, &st->group_tctx, &obj) < 0) { + kvlog (st, D_LEVEL_SEVERE, "group {%u:%u:%llu:%llu}: stored data is corrupt\n", (unsigned) k.table, k.gid, k.iid, k.mid); + result = D_STORE_RESULT_MUTILATED; + } else { + const struct d_groupKV *gd = obj; + struct namespace *ns; + d_groupListKV gg; + if ((ns = find_namespace_by_id_version (st, gd->namespace_id, gd->namespace_version)) == NULL) { + kvlog (st, D_LEVEL_WARNING, "group %s.%s (%u): namespace id %u missing, assuming partial delete of namespace\n", gd->partition, gd->topic, k.gid, gd->namespace_id); + /* Normally, next_namespace_id is updated by + * new_namespace and groups refer to existing + * namespaces. However, now it is referring to a + * non-existent one, and that may be one with a higher + * id than we have seen so far */ + if (gd->namespace_id >= st->next_namespace_id) { + st->next_namespace_id = gd->namespace_id + 1; + } + } else if ((result = new_group (&gg, st, k.gid, ns, gd->partition, gd->topic_id, gd->topic, &ns->quality)) != D_STORE_RESULT_OK) { + kvlog (st, D_LEVEL_SEVERE, "group %s.%s (%u): out of resources or worse\n", gd->partition, gd->topic, k.gid); + } else { + kvlog (st, D_LEVEL_FINE, " group %s.%s (%u) namespace %s id %u/%u quality %"PA_PRItime"\n", gd->partition, gd->topic, k.gid, ns->name, ns->id, ns->version, OS_TIMEW_PRINT(ns->quality)); + + /* Reading keys in ascending order, so group id must + * be >= next_group_id */ + assert (k.gid >= st->next_group_id); + st->next_group_id = k.gid + 1; + + /* Introduction of a new group is the only way a new + * topic can be introduced, but an old topic can + * always be referenced by a new group. Therefore, + * only conditionally update next_topic_id. */ + if (gd->topic_id >= st->next_topic_id) { + st->next_topic_id = gd->topic_id + 1; + } + } + c_free (obj); + } + } + kv_iter_free (st->kv, iter); + return result; +} + +d_storeKV d_storeNewKV (u_participant participant) +{ + d_storeKV st; + struct baseFind f; + + { + char *p; + if ((p = os_getenv ("OSPL_KVDEBUG")) != NULL && atoi (p) != 0) { + enable_kvdebug = 1; + } + } + + { + char *p; + if ((p = os_getenv ("OSPL_DURABILITY_LOG_STATISTICS")) != NULL && atoi (p) != 0) { + kvlog_statistics = 1; + } + } + + st = os_malloc (C_SIZEOF (d_storeKV)); + if (os_mutexInit (&st->lock, NULL) != os_resultSuccess) { + kvlog (st, D_LEVEL_SEVERE, "storeNewKV: mutexInit failed\n"); + goto err_storeNewKV_early; + } + if (os_condInit (&st->cond, &st->lock, NULL) != os_resultSuccess) { + kvlog (st, D_LEVEL_SEVERE, "storeNewKV: condInit failed\n"); + os_mutexDestroy (&st->lock); + goto err_storeNewKV_early; + } + + d_storeInit ((d_store) st, (d_objectDeinitFunc)d_storeDeinitKV); + (void)u_observableAction (u_observable(participant), d_storeGetBase, &f); + st->base = f.base; + st->opened = 0; + st->groups = NULL; + st->namespaces = NULL; + st->kv = NULL; + st->diskStorePath = NULL; + st->updated_namespaces = NULL; + st->groupTable = NULL; + st->locked = 0; + st->compression = D_COMPRESSION_NONE; + st->compressor = NULL; + init_ser_deser_ctx(&st->topic_tctx); + init_ser_deser_ctx(&st->topicinfo_tctx); + init_ser_deser_ctx(&st->namespace_tctx); + init_ser_deser_ctx(&st->namespace_quality_tctx); + init_ser_deser_ctx(&st->namespace_completeness_tctx); + init_ser_deser_ctx(&st->group_tctx); + init_ser_deser_ctx(&st->open_transaction_eot_tctx); + init_ser_deser_ctx(&st->open_transaction_vtid_tctx); + + st->next_group_id = 0; + st->next_topic_id = 0; + st->next_namespace_id = 0; + + st->otid = 0; /* The first free open transaction id */ + + if ((st->updated_namespaces = hashtable_new ((hashtable_key_func_t)get_namespace_key, (hashtable_cmp_func_t)compare_namespace_by_id)) == NULL) { + kvlog (st, D_LEVEL_SEVERE, "d_storeNewKV: allocation failed.\n"); + goto err_storeNewKV; + + } + + if ((st->groupTable = hashtable_new ((hashtable_key_func_t)get_group_key, (hashtable_cmp_func_t)compare_group)) == NULL) { + kvlog (st, D_LEVEL_SEVERE, "d_storeNewKV: allocation failed.\n"); + goto err_storeNewKV; + } + + if ((st->open_transactions = d_tableNew(transaction_list_cmp, transaction_list_free)) == NULL) { + kvlog (st, D_LEVEL_SEVERE, "d_storeNewKV: allocation failed.\n"); + goto err_storeNewKV; + } + + + st->topic_type = c_resolve (f.base, "durabilityModule2::d_topicKV"); + st->topicinfo_type = c_resolve (f.base, "durabilityModule2::d_topicInfoKV"); + st->namespace_type = c_resolve (f.base, "durabilityModule2::d_namespaceKV"); + st->namespace_quality_type = c_resolve (f.base, "durabilityModule2::d_namespaceQualityKV"); + st->namespace_completeness_type = c_resolve (f.base, "durabilityModule2::d_namespaceCompletenessKV"); + st->group_type = c_resolve (f.base, "durabilityModule2::d_groupKV"); + st->open_transaction_eot_type = c_resolve (f.base, "kernelModuleI::v_messageEOT"); + st->open_transaction_vtid_type = c_resolve (f.base, "kernelModule::v_tid"); + + { + d_store s = &st->_parent; + s->openFunc = d_storeOpenKV; + s->closeFunc = d_storeCloseKV; + s->groupsReadFunc = d_storeGroupsReadKV; + s->groupListFreeFunc = d_storeGroupListFreeKV; + s->groupInjectFunc = d_storeGroupInjectKV; + s->groupStoreFunc = d_storeGroupStoreKV; + s->getQualityFunc = d_storeGetQualityKV; + s->backupFunc = d_storeBackupKV; + s->restoreBackupFunc = d_storeRestoreBackupKV; + s->actionStartFunc = d_storeActionStartKV; + s->actionStopFunc = d_storeActionStopKV; + s->messageStoreFunc = d_storeMessageStoreKV; + s->instanceDisposeFunc = d_storeInstanceDisposeKV; + s->instanceExpungeFunc = d_storeInstanceExpungeKV; + s->messageExpungeFunc = d_storeMessageExpungeKV; + s->deleteHistoricalDataFunc = d_storeDeleteHistoricalDataKV; + s->messagesInjectFunc = d_storeMessagesInjectKV; + s->instanceRegisterFunc = d_storeInstanceRegisterKV; + s->createPersistentSnapshotFunc = d_storeCreatePersistentSnapshotKV; + s->instanceUnregisterFunc = d_storeInstanceUnregisterKV; + s->optimizeGroupFunc = d_storeOptimizeGroupKV; + s->nsIsCompleteFunc = d_storeNsIsCompleteKV; + s->nsMarkCompleteFunc = d_storeNsMarkCompleteKV; + s->transactionCompleteFunc = d_storeTransactionCompleteKV; + s->messagesLoadFunc = d_storeMessagesLoadKV; + s->messagesLoadFlushFunc = d_storeMessagesLoadFlushKV; + } + + return st; + +err_storeNewKV: + d_storeDeinitKV (st); +err_storeNewKV_early: + os_free (st); + return NULL; +} + +void d_storeDeinitKV (d_storeKV st) +{ + kvdebug ("d_storeDeinitKV %p\n", (void *) st); + + ASSERT_STOREKV_NORET (st); + + assert (st->groups == NULL); + assert (st->namespaces == NULL); + + c_free (st->topic_type); + c_free (st->topicinfo_type); + c_free (st->namespace_type); + c_free (st->namespace_quality_type); + c_free (st->namespace_completeness_type); + c_free (st->group_type); + c_free (st->open_transaction_eot_type); + c_free (st->open_transaction_vtid_type); + + deinit_ser_deser_ctx(&st->topic_tctx); + deinit_ser_deser_ctx(&st->topicinfo_tctx); + deinit_ser_deser_ctx(&st->namespace_tctx); + deinit_ser_deser_ctx(&st->namespace_completeness_tctx); + deinit_ser_deser_ctx(&st->group_tctx); + deinit_ser_deser_ctx(&st->open_transaction_eot_tctx); + deinit_ser_deser_ctx(&st->open_transaction_vtid_tctx); + + hashtable_free(st->updated_namespaces); + hashtable_free(st->groupTable); + + d_tableFree(st->open_transactions); + + os_mutexDestroy (&st->lock); + os_condDestroy (&st->cond); + /* call super-deinit */ + d_storeDeinit(d_store(st)); +} + +d_storeResult d_storeFreeKV (d_storeKV store) +{ + d_storeKV st; + + ASSERT_STOREKV (st, store); + + kvdebug ("d_storeFreeKV %p\n", (void *) st); + + if (store->opened) { + return D_STORE_RESULT_PRECONDITION_NOT_MET; + } else { + d_objectFree(d_object(store)); + return D_STORE_RESULT_OK; + } +} + +#define VERSION_GET_ENCODING(x) ( (x)&0x000000FF) +#define VERSION_GET_COMPRESSION(x) (((x)&0x0000FF00) >> 8) +#define MAKE_VERSION(encoding, compression) (((encoding) & 0x000000FF) | (((compression) & 0x000000FF)<<8)) + +static d_storeResult getset_version (struct d_versionKV *out, d_storeKV st) +{ + d_storeResult result = D_STORE_RESULT_ERROR; + const kv_key_t k = { TABLE_VERSION, 0, 0, 0 }; + kv_result_t rc; + os_uint32 sz, tbuf[2]; + void *buf; + if ((rc = kv_get (st->kv, &k, &sz, &buf, 0)) >= 0) { + if (sz != sizeof (tbuf)) { + kvlog (st, D_LEVEL_SEVERE, "getset_version: version from file corrupt\n"); + result = D_STORE_RESULT_MUTILATED; + } else { + int valid = 0; + memcpy (tbuf, buf, sz); + out->version = ntohl (tbuf[0]); + out->encoding = (enum d_encodingKV) VERSION_GET_ENCODING(ntohl (tbuf[1])); + out->compression = (enum d_compressionKV) VERSION_GET_COMPRESSION(ntohl (tbuf[1])); + switch (out->encoding) { + case D_ENCODINGKV_XML_XML: + case D_ENCODINGKV_BIGE_XML: + case D_ENCODINGKV_BIGECDR_XML: + case D_ENCODINGKV_BIGECDR_V1: + valid = 1; + break; + /* intentionally no default case: that results in + * warning with most compilers when the set of + * encodings is extended without updating this + * validation function */ + } + if (valid) { + valid = 0; + switch (out->compression) { + case D_COMPRESSION_NONE: + case D_COMPRESSION_LZF: + case D_COMPRESSION_SNAPPY: + case D_COMPRESSION_ZLIB: + case D_COMPRESSION_CUSTOM: + valid = 1; + break; + /* intentionally no default case: that results in + * warning with most compilers when the set of + * compression is extended without updating this + * validation function */ + } + if (valid) { + result = D_STORE_RESULT_OK; + } else { + kvlog (st, D_LEVEL_SEVERE, "getset_version: unknown compression %d\n", (int) out->compression); + result = D_STORE_RESULT_UNSUPPORTED; + } + } else { + kvlog (st, D_LEVEL_SEVERE, "getset_version: unknown encoding %d\n", (int) out->encoding); + result = D_STORE_RESULT_UNSUPPORTED; + } + } + kvlog (st, D_LEVEL_FINEST, "getset_version: version read from file\n"); + os_free (buf); + } else { + switch (rc) { + case KV_RESULT_NODATA: + kvlog (st, D_LEVEL_FINE, "getset_version: no version in file yet\n"); + out->version = 0; + out->encoding = kv_choose_encoding (st->kv, D_ENCODINGKV_BIGECDR_V1); + out->compression = (out->encoding != D_ENCODINGKV_XML_XML) ? st->compression : D_COMPRESSION_NONE; + tbuf[0] = htonl (out->version); + tbuf[1] = htonl ((os_uint32)MAKE_VERSION(out->encoding, out->compression)); + rc = kv_put (st->kv, &k, sizeof (tbuf), tbuf, 0); + if (rc >= 0) { + kvlog (st, D_LEVEL_FINEST, "getset_version: version written\n"); + result = D_STORE_RESULT_OK; + } else { + kvlog (st, D_LEVEL_SEVERE, "getset_version: write of version failed\n"); + result = kv_convert_result(rc); + } + break; + default: + kvlog (st, D_LEVEL_SEVERE, "getset_version: read of version failed\n"); + result = kv_convert_result(rc); + break; + } + } + return result; +} + +static d_storeResult submode_to_kind (kv_kind_t *k, const struct d_store_s *gstore) +{ + const char *sm = gstore->config->persistentKVStoreStorageType; + if (sm == NULL || os_strcasecmp (sm, "sqlite") == 0 || os_strcasecmp (sm, "sqlite3") == 0) { + *k = KV_KIND_SQLITE; + } else if (os_strcasecmp (sm, "sqlitemt") == 0) { + *k = KV_KIND_SQLITEMT; + } else if (os_strcasecmp (sm, "leveldb") == 0) { + *k = KV_KIND_LEVELDB; + } else if (os_strcasecmp (sm, "lsds") == 0) { + *k = KV_KIND_LSDS; + } else if (os_strcasecmp (sm, "dummy") == 0) { + *k = KV_KIND_DUMMY; + } else { + kvlog ((const struct d_storeKV_s *) gstore, D_LEVEL_SEVERE, "unknown kvstore submode '%s' configured\n", sm); + return D_STORE_RESULT_ILL_PARAM; + } + return D_STORE_RESULT_OK; +} + +d_storeResult d_storeOpenKV (d_store gstore) +{ + d_storeResult result; + d_storeKV st; + c_char* resultDir; + struct d_versionKV version; + kv_kind_t kind; + memset (&version, 0, sizeof (version)); + + ASSERT_STOREKV (st, gstore); + + if (st->opened) { + result = D_STORE_RESULT_PRECONDITION_NOT_MET; + } else if (gstore->config->persistentStoreDirectory == NULL) { + result = D_STORE_RESULT_ILL_PARAM; + } else if ((result = submode_to_kind (&kind, gstore)) != D_STORE_RESULT_OK) { + ; + } else if ((resultDir = d_storeDirNew (gstore, gstore->config->persistentStoreDirectory)) == NULL) { + kvlog (st, D_LEVEL_SEVERE, "Persistent store directory '%s' could not be created.\n", gstore->config->persistentStoreDirectory); + result = D_STORE_RESULT_PRECONDITION_NOT_MET; + } else { + os_free (gstore->config->persistentStoreDirectory); + gstore->config->persistentStoreDirectory = resultDir; + kvlog (st, D_LEVEL_INFO, "Persistent store directory '%s' opened.\n", gstore->config->persistentStoreDirectory); + st->diskStorePath = os_strdup (gstore->config->persistentStoreDirectory); + st->opened = 1; + + if (gstore->config->persistentKVStoreCompressionEnabled) { + st->compression = gstore->config->persistentKVStoreCompressionAlgorithm; + switch(st->compression) { + case D_COMPRESSION_LZF: + st->compressor = ut_compressorNew(NULL, "lzf", NULL); + break; + case D_COMPRESSION_SNAPPY: + st->compressor = ut_compressorNew(NULL, "snappy", NULL); + break; + case D_COMPRESSION_ZLIB: + st->compressor = ut_compressorNew(NULL, "zlib", NULL); + break; + case D_COMPRESSION_CUSTOM: + /* fall through, custom not (yet) supported */ + default: + st->compressor = NULL; + break; + } + } else { + st->compression = D_COMPRESSION_NONE; + } + + if ((st->compression != D_COMPRESSION_NONE) && (st->compressor == NULL)) { + kvlog (st, D_LEVEL_SEVERE, "Requested compressor '%s' could not be loaded\n", d_compressionKVImage(st->compression)); + result = D_STORE_RESULT_ERROR; + } else if ((st->kv = kv_open (st, st->diskStorePath, kind, gstore->config->persistentKVStoreStorageParameters)) == NULL) { + kvlog (st, D_LEVEL_SEVERE, "Persistent store '%s' could not be created.\n", gstore->config->persistentStoreDirectory); + result = D_STORE_RESULT_ERROR; + } else if ((result = getset_version (&version, st)) == D_STORE_RESULT_OK) { + kvlog (st, D_LEVEL_INFO, "encoding %d compression %d version %d\n", (int) version.encoding, (int) version.compression, (int) version.version); + st->encoding = version.encoding; + if (st->compression != version.compression) { + kvlog (st, D_LEVEL_SEVERE, "d_storeOpenKV: store compression does not match requested compression\n"); + result = D_STORE_RESULT_UNSUPPORTED; + } else { + result = init_namespaces (st); + if (result == D_STORE_RESULT_OK) { + result = init_groups (st); + } + kvlog (st, D_LEVEL_INFO, "next available ids: namespace %u group %u topic %u\n", st->next_namespace_id, st->next_group_id, st->next_topic_id); + } + } + } + + return result; +} + +d_storeResult d_storeCloseKV (d_store gstore) +{ + d_storeKV st; + LOCK_OPEN_STOREKV (st, gstore); + + kvdebug ("d_storeCloseKV %p\n", (void *) gstore); + + kv_close (st->kv); + if (st->compression != D_COMPRESSION_NONE) { + ut_compressorFree(st->compressor); + } + st->opened = 0; + os_free (st->diskStorePath); + st->diskStorePath = NULL; + + + while (st->groups) { + d_groupListKV g = st->groups; + st->groups = g->_parent.next; + free_group (g, st); + } + + while (st->namespaces) { + struct namespace *ns = st->namespaces; + st->namespaces = ns->next; + free_namespace (ns); + } + + UNLOCK_OPEN_STOREKV (st); + return D_STORE_RESULT_OK; +} + +d_storeResult d_storeActionStartKV (const d_store gstore) +{ + d_storeKV st; + + if (kvlog_statistics) { + LOCK_OPEN_STOREKV (st, gstore); + + st->action_started = TRUE; + st->first_time = OS_TIMEE_ZERO; + st->last_time = OS_TIMEE_ZERO; + + UNLOCK_OPEN_STOREKV (st); + } + + return D_STORE_RESULT_OK; +} + +d_storeResult d_storeActionStopKV (const d_store gstore) +{ + d_storeKV st; + d_storeResult result = D_STORE_RESULT_OK; + struct namespace *ns; + os_duration diff; + + LOCK_OPEN_STOREKV (st, gstore); + + ns = (struct namespace *) hashtable_take (st->updated_namespaces); + while (ns) { + store_namespace_quality(st, ns); + ns = (struct namespace *) hashtable_take (st->updated_namespaces); + } + st->action_started = FALSE; + + if (kvlog_statistics) { + kvlog(st, D_LEVEL_FINEST, "Start time %"PA_PRItime"\n", OS_TIMEE_PRINT(st->first_time)); + kvlog(st, D_LEVEL_FINEST, "End time %"PA_PRItime"\n", OS_TIMEE_PRINT(st->last_time)); + diff = os_timeEDiff(st->last_time, st->first_time); + kvlog(st, D_LEVEL_FINEST, "Diff time %"PA_PRIduration" seconds \n", OS_DURATION_PRINT(diff)); + } + if (kv_commit (st->kv) < 0) { + kvlog (st, D_LEVEL_SEVERE, "store-message: commit failed\n"); + result = D_STORE_RESULT_IO_ERROR; + } + UNLOCK_OPEN_STOREKV (st); + return result; +} + +d_storeResult d_storeGroupsReadKV (const d_store gstore, d_groupList *list) +{ + d_storeKV st; + const struct d_groupListKV_s *g; + if (list == NULL) { + return D_STORE_RESULT_ILL_PARAM; + } + LOCK_OPEN_STOREKV (st, gstore); + + kvlog (st, D_LEVEL_INFO, "groups-read: building list of non-backup groups\n"); + + *list = NULL; + for (g = st->groups; g; g = g->_parent.next) { + char buf[256]; + snprintf (buf, sizeof (buf), "groups-read: considering group %s.%s id %u namespace %s id %u/%u: ", + g->_parent.partition, g->_parent.topic, g->group_id, + g->namespace->name, g->namespace->id, g->namespace->version); + if (group_latest_namespace_version (st, g)) { + d_groupList tmp; + kvlog (st, D_LEVEL_FINEST, "%scurrent\n", buf); + tmp = os_malloc (sizeof (*tmp)); + *tmp = g->_parent; + tmp->next = *list; + *list = tmp; + } else { + kvlog (st, D_LEVEL_FINEST, "%sbackup\n", buf); + } + } + + UNLOCK_OPEN_STOREKV (st); + return D_STORE_RESULT_OK; +} + +d_storeResult d_storeGroupListFreeKV (const d_store gstore, d_groupList list) +{ + d_groupList next; + + ASSERT_STOREKV_NORET(gstore); + OS_UNUSED_ARG(gstore); + + next = list; + while (next) { + list = list->next; + os_free(next); + next = list; + } + + return D_STORE_RESULT_OK; +} + +static void set_kernel_group (v_public entity, c_voidp args) +{ + d_group group = d_group (args); + d_groupSetKernelGroup (group, v_group (entity)); +} + +d_storeResult d_storeGroupInjectKV (const d_store gstore, const c_char *partition, const c_char *topic, const u_participant participant, d_group *pgroup) +{ + d_groupListKV g; + struct d_topicInfoKV *tp; + d_storeResult result; + u_topic utopic; + u_group ugroup; + u_partition upartition; + v_partitionQos partitionQos; + d_storeKV st; + if (participant == NULL || partition == NULL || topic == NULL || pgroup == NULL) { + return D_STORE_RESULT_ILL_PARAM; + } + LOCK_OPEN_STOREKV (st, gstore); + + kvdebug ("groupinject %s.%s\n", partition, topic); + + *pgroup = NULL; + + if ((g = find_group (st, partition, topic)) == NULL) { + kvdebug (" group not found\n"); + result = D_STORE_RESULT_ERROR; + goto err_getgroup; + } + kvdebug (" group %p topic_id %d\n", (void *) g, (int) g->topic_id); + if ((tp = get_topicInfoKV (st, g->topic_id, g->_parent.topic)) == NULL) { + kvdebug (" get_topic failed\n"); + result = D_STORE_RESULT_MUTILATED; /* FIXME - not really a critical error, but "mutilated" sounds very bad */ + goto err_readTopicMetadata; + } + kvdebug (" topic %p\n", (void *) tp); + kvdebug (" typename %s keylist %s\n", tp->info.type_name, tp->info.key_list); + if ((utopic = u_topicNewFromTopicInfo (participant, &tp->info, TRUE)) == NULL) { + kvlog (st, D_LEVEL_SEVERE, "Topic '%s' with typeName '%s' and keylist '%s' could NOT be created.\n", tp->info.name, tp->info.type_name, tp->info.key_list); + result = D_STORE_RESULT_METADATA_MISMATCH; + goto err_topicNew; + } + kvlog (st, D_LEVEL_FINE, "Topic %s created.\n", tp->info.name); + + if ((partitionQos = u_partitionQosNew (NULL)) == NULL) { + kvlog (st, D_LEVEL_SEVERE, "PartitionQos could NOT be created.\n"); + result = D_STORE_RESULT_OUT_OF_RESOURCES; + goto err_partitionQosNew; + } + kvlog (st, D_LEVEL_FINE, "PartitionQoS created.\n"); + if ((upartition = u_partitionNew (participant, partition, partitionQos)) == NULL) { + kvlog (st, D_LEVEL_SEVERE, "Partition %s could NOT be created.\n", partition); + result = D_STORE_RESULT_ERROR; + goto err_partitionNew; + } + kvlog (st, D_LEVEL_FINE, "Partition %s created.\n", partition); + + if ((ugroup = u_groupNew (participant, partition, topic, OS_DURATION_ZERO)) == NULL) { + kvlog (st, D_LEVEL_SEVERE, "Group %s.%s could NOT be created.\n", partition, tp->info.name); + result = D_STORE_RESULT_ERROR; + goto err_groupNew; + } + kvlog (st, D_LEVEL_INFO, "Group %s.%s created.\n", partition, tp->info.name); + + + *pgroup = d_groupNew (partition, topic, D_DURABILITY_PERSISTENT, g->_parent.completeness, g->_parent.quality); + result = D_STORE_RESULT_OK; + + u_observableAction (u_observable (ugroup), set_kernel_group, *pgroup); + /* FIXME: enable again after fix is in place (See OSPL-2750) + u_objectFree (u_object (ugroup)); */ +err_groupNew: + u_objectFree(u_object (upartition)); +err_partitionNew: + u_partitionQosFree (partitionQos); +err_partitionQosNew: + (void)u_objectFree (u_object (utopic)); +err_topicNew: + c_free (tp); +err_readTopicMetadata: +err_getgroup: + UNLOCK_OPEN_STOREKV (st); + return result; +} + +d_storeResult d_storeGetQualityKV (const d_store gstore, const d_nameSpace nameSpace, os_timeW *quality) +{ + /* TODO: what is returned if there are no namespaces or strcmp() fails */ + d_storeKV st; + struct namespace *ns; + char *name; + if (quality == NULL || nameSpace == NULL) { + return D_STORE_RESULT_ILL_PARAM; + } + name = d_nameSpaceGetName (nameSpace); + LOCK_OPEN_STOREKV (st, gstore); + for (ns = st->namespaces; ns; ns = ns->next) { + if (strcmp (ns->name, name) == 0) { + *quality = ns->quality; + break; + } + } + UNLOCK_OPEN_STOREKV (st); + return D_STORE_RESULT_OK; +} + +d_storeResult d_storeGroupStoreKV (const d_store gstore, const d_group dgroup, const d_nameSpace nameSpace) +{ + c_char *topicName = NULL; + c_char *partitionName = NULL; + v_group group; + d_storeResult result = D_STORE_RESULT_ERROR; + kv_result_t rc; + os_timeW quality; + d_storeKV st; + os_uint32 topic_id; + os_int ret; + struct namespace *ns; + if (dgroup == NULL) { + return D_STORE_RESULT_ILL_PARAM; + } + + LOCK_OPEN_STOREKV (st, gstore); + + quality = os_timeWGet(); + + group = d_groupGetKernelGroup (dgroup); + topicName = v_topicName (v_groupTopic (group)); + partitionName = v_partitionName (v_groupPartition (group)); + kvlog (st, D_LEVEL_FINE, "Storing group (partition.topic): '%s.%s'\n", partitionName, topicName); + + /* If we already have the group on-disk (not sure that can + * happen), no need to do anything. */ + if (find_group (st, partitionName, topicName) != NULL) { + kvlog (st, D_LEVEL_FINE, "Group '%s.%s' already known on-disk\n", partitionName, topicName); + result = D_STORE_RESULT_OK; + goto out; + } + + /* Need a topic_id; need to ensure topic metadata is on-disk. + * + * FIXME: should be a bit more sensible in handling + * topics/topic_ids. This scanning of a list of groups ok but + * can be improved (it is functionally correct, though). */ + { + d_groupListKV g = find_group_w_topic (st, topicName); + if (g != NULL) { + topic_id = g->topic_id; + kvlog (st, D_LEVEL_FINER, "No need to store topic metadata because of existence of %s.%s; topic_id = %u\n", g->_parent.partition, topicName, topic_id); + } else { + struct d_topicInfoKV *tp; + topic_id = st->next_topic_id; + kvlog (st, D_LEVEL_FINER, "Must store topic metadata for '%s.%s'; topic_id = %u\n", + partitionName, topicName, topic_id); + if ((tp = make_topicInfoKV (st, v_groupTopic (group))) == NULL) { + kvlog (st, D_LEVEL_SEVERE, "Couldn't store topic metadata for topic '%s': out of resources\n", topicName); + result = D_STORE_RESULT_OUT_OF_RESOURCES; + goto out; + } else { + ret = put_topicInfoKV (st, topic_id, tp); + c_free (tp); + if (ret < 0) { + kvlog (st, D_LEVEL_SEVERE, "Couldn't store topic metadata for topic '%s'\n", topicName); + result = D_STORE_RESULT_PRECONDITION_NOT_MET; + goto out; + } else { + kvlog (st, D_LEVEL_FINE, "Stored metadata for topic '%s'\n", topicName); + st->next_topic_id++; + } + } + } + } + + /* See if this is a new name space; if it is, store it */ + if ((ns = find_or_create_namespace (st, nameSpace)) == NULL) { + kvlog (st, D_LEVEL_SEVERE, "No namespace found for group '%s.%s'\n", partitionName, topicName); + goto out; + } else if ((result = store_namespace (st, ns)) != D_STORE_RESULT_OK) { + goto out; + } + + + /* Default completeness is INCOMPLETE, so no need to store + * completeness. But we do need to store the quality. */ + { + struct d_namespaceQualityKV *q; + q = c_new (st->namespace_quality_type); + /* Convert quality to c_time */ + d_qualityExtFromQuality(&q->quality, &quality, TRUE); + if ((rc = put2_ser (st, TABLE_NAMESPACE_QUALITY, ns->id, ns->version, st->namespace_quality_type, &st->namespace_quality_tctx, q)) < 0) { + kvlog (st, D_LEVEL_SEVERE, "Could not store quality for namespace '%s' id %u/%u\n", ns->name, ns->id, ns->version); + result = kv_convert_result(rc); + c_free (q); + goto out; + } + c_free (q); + kvlog (st, D_LEVEL_FINEST, "Namespace '%s' id %u/%u quality written to disk\n", ns->name, ns->id, ns->version); + kvlog (st, D_LEVEL_FINE, "Group '%s.%s' has quality: %"PA_PRItime"\n", partitionName, topicName, OS_TIMEW_PRINT(quality)); + } + + /* Topic and namespace written to disk - so can now write group as + * well. Note that we already know it is a new group. */ + { + os_uint32 group_id = st->next_group_id; + struct d_groupKV *g; + g = c_new (st->group_type); + g->topic_id = topic_id; + g->namespace_id = ns->id; + g->namespace_version = ns->version; + g->partition = c_stringNew (c_getBase (g), partitionName); + g->topic = c_stringNew (c_getBase (g), topicName); + if ((rc = put1_ser (st, TABLE_GROUP, group_id, st->group_type, &st->group_tctx, g)) < 0) { + kvlog (st, D_LEVEL_SEVERE, "Could not store group '%s.%s' id %u\n", partitionName, topicName, group_id); + result = kv_convert_result(rc); + } else { + d_groupListKV gg; + kvlog (st, D_LEVEL_FINEST, "Group '%s.%s' id %u written to disk\n", partitionName, topicName, group_id); + st->next_group_id++; + result = new_group (&gg, st, group_id, ns, partitionName, topic_id, topicName, &quality); + } + c_free (g); + } + + /* Commit whatever outstanding transactions there are */ + if (kv_commit (st->kv) < 0) { + kvlog (st, D_LEVEL_SEVERE, "store-group: commit failed\n"); + result = D_STORE_RESULT_IO_ERROR; + } + +out: + c_free(group); + UNLOCK_OPEN_STOREKV (st); + return result; +} + +static int history_is_keepall (const struct v_topicQos_s *topicQos) +{ + return + topicQos->durabilityService.v.history_kind == V_HISTORY_KEEPALL || + topicQos->durabilityService.v.history_depth == V_LENGTH_UNLIMITED; +} + +static int history_is_keeplast (const struct v_topicQos_s *topicQos) +{ + return !history_is_keepall (topicQos); +} + +static struct msg *find_insertafter_point (const struct inst *inst, const struct v_message_s *msg) +{ + if (inst->oldest == NULL) { + /* Trivial case: empty sequence */ + return NULL; + } else if (os_timeWCompare (inst->latest->writeTime, msg->writeTime) == OS_LESS) { + /* Expected case: msg is more recent than latest */ + return inst->latest; + } else { + /* Scan the list from new to old to find the insertion point: + * the assumption is that it will be more likely that it is a + * recent message than that it is a very old one. Major key + * is writeTime, but id and sequence number are factored in as + * well to guarantee a total order, which is needed for + * duplicate detection. */ + struct msg *mprev = inst->latest; + while (mprev && msg_lt_v_message (mprev, msg)) { + mprev = mprev->older; + } + return mprev; + } +} + +#ifndef NDEBUG +static int mid_is_available (const struct inst *inst, os_uint64 mid) +{ + struct msg *m; + for (m = inst->oldest; m; m = m->newer) { + if (m->key.mid == mid) { + return 0; + } + } + return 1; +} +#endif + +static d_storeResult add_message_to_instance (struct msg **pm, d_storeKV st, struct d_groupListKV_s *g, v_topic vtopic, struct inst *inst, struct msg *mprev, const struct v_message_s *msg, const os_uint64 *p_mid, const v_orderbyKind order_by) +{ + const int reconstructing = (p_mid != NULL); + struct msg *m, *oldest_non_transaction; + struct transaction_list *tr_list, *tr_list_found; + struct transaction_msg *tr_msg; + kv_result_t rc; + c_bool tr_list_created = FALSE; + + *pm = NULL; /* Needed to satisfy strict compiler rules */ + if ((m = os_malloc (sizeof (*m))) == NULL) { + return D_STORE_RESULT_OUT_OF_RESOURCES; + } + m->key = inst->next_msg_key; + if (p_mid != NULL) { + /* Overrule MID part of key; but do check it is unique */ + assert (*p_mid >= m->key.mid || mid_is_available (inst, *p_mid)); + m->key.mid = *p_mid; + } + m->state = v_nodeState ((c_object)msg); + m->writeTime = msg->writeTime; + m->writerGID = msg->writerGID; + m->sequenceNumber = msg->sequenceNumber; + m->transactionId = msg->transactionId; + m->inst = inst; + + if (m->state & L_TRANSACTION) { + /* The message is an open transactional message so we + * must add it to the list of open transaction + * messages. The open transaction message contains a + * reference to the actual message, which is inserted + * in the instance. The actual message has the L_TRANSACTION + * flag set. This flag is reset once the transaction becomes + * complete. */ + tr_list = os_malloc(sizeof(*tr_list)); + tr_list->seqNum = msg->transactionId; + tr_list->gid = msg->writerGID; + tr_list->head = NULL; + tr_list->tail = NULL; + tr_list->commit_state = reconstructing ? UNDECIDED : OPEN; + tr_list->otid = ((st->otid % 2) == 0) ? st->otid : st->otid+1; /* unique id, 63-bits, always even for open transaction message */ + st->otid = tr_list->otid + 1; + if ((tr_list_found = d_tableInsert(st->open_transactions, tr_list)) != NULL) { + os_free(tr_list); + tr_list = tr_list_found; + } else { + tr_list_created = TRUE; + } + tr_msg = os_malloc(sizeof(*tr_msg)); + if (p_mid == NULL) { + if (tr_list_created) { + /* A new transaction list is generated, not reconstructing. + * Write an entry in the journal for the open transaction. */ + + struct v_tid *tid; + kv_key_t key; + + tid = c_new (st->open_transaction_vtid_type); + tid->wgid = tr_list->gid; + tid->seqnr = tr_list->seqNum; + key.table = TABLE_MESSAGE_EOT; + key.gid = 0; + key.iid = 0; + key.mid = tr_list->otid; /* unique id, 63-bits transactionId and 1-bit open/close */ + if ((rc = put_ser (st, &key, st->open_transaction_vtid_type, &st->open_transaction_vtid_tctx, tid)) < 0) { + os_free(m); + os_free(tr_msg); + c_free(tid); + return kv_convert_result(rc); + } + kvdebug(" add tid msg to journal with key=%"PA_PRIu32":%"PA_PRIu32":%"PA_PRIu64" for gid=(%d, %d, %d), transaction=%u\n", + key.gid, key.iid, key.mid, tr_list->gid.systemId, tr_list->gid.localId, tr_list->gid.serial, tr_list->seqNum); + c_free(tid); + } else { + kvdebug(" transaction %d for gid=(%d, %d, %d) already open, NOT adding tid to journal\n", tr_list->seqNum, tr_list->gid.systemId, tr_list->gid.localId, tr_list->gid.serial); + } + } + /* Add the message to the transaction list */ + tr_msg->msg_ref = m; + tr_msg->next = NULL; + if (tr_list->head == NULL) { + assert(tr_list->tail == NULL); + tr_list->head = tr_msg; + } else { + assert(tr_list->tail != NULL); + tr_list->tail->next = tr_msg; + } + tr_list->tail = tr_msg; + } + + /* When reconstructing state, we keep the v_message but do not + * write it to the store. Once we start injecting the data + * properly, the v_messages we kept in shared memory will be + * referenced by the group, then we drop the reference, and we + * will never need significantly more memory than what the kernel + * needs to store the persistent data anyway. */ + if (reconstructing) { + m->v_msg = c_keep ((v_message) msg); + } else { + m->v_msg = NULL; + if ((rc = put_ser_vmsg (st, &m->key, vtopic, &g->tctx, msg)) < 0) { + os_free (m); + return kv_convert_result(rc); + } + } + + if (mprev == NULL) { + /* new oldest of possibly empty list */ + m->older = NULL; + m->newer = inst->oldest; + inst->oldest = m; + if (m->newer) { + m->newer->older = m; + } else { + inst->latest = m; + } + } else { + m->newer = mprev->newer; + if (m->newer) { + m->newer->older = m; + } else { + inst->latest = m; + } + m->older = mprev; + m->older->newer = m; + } + /* Only increase the writeCount for write messages that are + * not part of a coherent transaction. */ + if ((!(m->state & L_TRANSACTION)) && (m->state & L_WRITE)) { + inst->writeCount++; + + /* Update the oldest_non_transaction when needed */ + oldest_non_transaction = inst->oldest_non_transaction; + /* Maintain the oldest_non_transaction */ + inst->oldest_non_transaction = get_oldest_non_transaction(m, inst->oldest_non_transaction, order_by); + if (oldest_non_transaction != inst->oldest_non_transaction) { + kvdebug(" oldest_non_transaction set to %p\n", (void *)inst->oldest_non_transaction); + } + } + if (m->key.mid >= inst->next_msg_key.mid) { + inst->next_msg_key.mid = m->key.mid + 1; + } + *pm = m; + return D_STORE_RESULT_OK; +} + + +/** + * Find the oldest non_transactional write message, starting from msg + * (not considering msg as a candidate itself) + * + * A non-transaction write message is a write message with the L_WRITE flag set + * and the L_TRANSACTION not set. + * + * This function returns the oldest non-transaction write message by starting + * from msg and work your way upwards (to newer) messages. + * + * If no such message can be found NULL is returned. + */ +static struct msg *find_oldest_non_transaction (const struct inst *inst, struct msg *msg) +{ + struct msg *m; + + OS_UNUSED_ARG(inst); + + assert(msg); /* If the message */ + + /* Start at msg and work your way up to newer messages + * until you find a message with L_WRITE but not L_TRANSACTION. */ + m = (msg->newer) ? msg->newer : NULL; + while ( (m != NULL) && !(((m->state & L_WRITE) && (!(m->state & L_TRANSACTION)))) ) { + m = m->newer; + } + return m; +} + + +static d_storeResult drop_just_message (d_storeKV st, struct inst *inst, struct msg *m, int reconstructing) +{ + kv_result_t rc; + + assert(m); + if (m->older == NULL) { + inst->oldest = m->newer; + } else { + m->older->newer = m->newer; + } + if (m->newer == NULL) { + inst->latest = m->older; + } else { + m->newer->older = m->older; + } + /* Decrease the writecount only for non-transactional write messages. */ + if ((!(m->state & L_TRANSACTION)) && (m->state & L_WRITE)) { + assert (inst->writeCount > 0); + inst->writeCount--; + } + /* Going to the oldest_non_transaction, recalculate a new one */ + if (m == inst->oldest_non_transaction) { + inst->oldest_non_transaction = find_oldest_non_transaction(inst, m); + } + /* FIXME: during reconstruction, there is an argument to be made + * that messages that get dropped should be deleted, to avoid + * leaking them. However, there is also an argument to be made + * that reconstructing with the store in read-only mode is + * attractive. The risk of leakage is very low, at worst means + * one data message and some disposes at every crash. */ + rc = reconstructing ? 0 : kv_delete (st->kv, &m->key); + msg_free (m); + return kv_convert_result(rc); +} + +static d_storeResult drop_message (d_storeKV st, struct d_groupListKV_s *g, struct inst **inst, struct msg *m, int reconstructing) +{ + d_storeResult result; + if ((result = drop_just_message (st, *inst, m, reconstructing)) != D_STORE_RESULT_OK) { + return result; + } + if ((*inst)->oldest == NULL) { + assert (ut_avlLookup (&group_inst_td, &g->instances_by_iid, &(*inst)->next_msg_key.iid) == *inst); + ut_avlDelete (&group_inst_td, &g->instances_by_iid, *inst); + d_tableRemove (g->instances, *inst); + inst_free (*inst); + *inst = NULL; + } + return result; +} + +static struct msg *find_message (const struct inst *inst, const struct v_message_s *msg) +{ + const struct msg *m; + for (m = inst->oldest; m; m = m->newer) { + int cmp = msg_v_message_cmp (m, msg); + if (cmp == 0) { + return (struct msg *) m; + } else if (cmp > 0) { + return NULL; + } + } + return NULL; +} + + +static d_storeResult check_and_update_history (struct d_storeKV_s *st, struct inst *inst, const os_int32 depth, const int reconstructing) +{ + d_storeResult result; + + kvdebug (" keeplast, checking history\n"); + assert(depth > 0); + assert(inst->writeCount <= depth + 1); + if (inst->writeCount == depth + 1) { + assert(inst->oldest_non_transaction); + /* Drop the oldest_non_transaction_message. + * A new oldest_non_transaction message is automatically selected */ + kvdebug (" drop msg %p\n", (void *) inst->oldest_non_transaction); + if ((result = drop_message (st, inst->g, &inst, inst->oldest_non_transaction, reconstructing)) != D_STORE_RESULT_OK) { + kvdebug (" drop failed\n"); + return result; + } + } + assert(inst->writeCount <= depth); + /* Drop outdated disposes that do not apply anymore, but only + * if the dispose does not belong to a transaction. */ + while (inst && (inst->writeCount == depth && !(inst->oldest->state & L_WRITE) && !(inst->oldest->state & L_TRANSACTION))) { + kvdebug (" drop oldest msg %p\n", (void *) inst->oldest); + if ((result = drop_message (st, inst->g, &inst, inst->oldest, reconstructing)) != D_STORE_RESULT_OK) { + kvdebug (" drop failed\n"); + return result; + } + } + return D_STORE_RESULT_OK; +} + + +static d_storeResult store_message (struct d_storeKV_s *st, struct v_group_s *group, const struct v_message_s *msg, struct d_groupListKV_s *g, const os_uint32 *p_iid, const os_uint64 *p_mid) +{ + + const int reconstructing = (p_iid != NULL); + v_topic vtopic = v_groupTopic ((c_object) group); + struct v_topicQos_s const * const topicQos = v_topicQosRef (vtopic); + const os_int32 depth = topicQos->durabilityService.v.history_depth; + struct inst *inst; + struct msg *m, *mprev; + d_storeResult result; + v_orderbyKind order_by; + + assert (g); + assert ((p_iid == NULL && p_mid == NULL) || (p_iid != NULL && p_mid != NULL)); + assert (c_getType (c_object (msg)) == v_topicMessageType (v_groupTopic ((c_object)group))); + + kvdebug ("store_message: group %p vmsg %p state %d (reconstructing=%d)\n", (void *) group, (void *) msg, v_nodeState((c_object)msg), reconstructing); + + if (reconstructing) { + kvdebug (" [reconstructing iid %u mid %llu]\n", *p_iid, *p_mid); + } + +#if 0 + if (!reconstructing && (d_tableSize(g->instances) == 0)) { + kvlog(st, D_LEVEL_FINE, "No data exists yet on disk for group '%s.%s'\n", g->_parent.partition, g->_parent.topic); + } +#endif + kvdebug (" groupKV %p\n", (void *) g); + if ((result = find_or_create_instance (&inst, st, g, group, msg, p_iid)) != D_STORE_RESULT_OK) { + kvdebug (" find_or_create_instance failure\n"); + return result; + } + + assert (history_is_keepall (topicQos) || inst->writeCount <= depth); + + /* Decide whether to add MSG to the on-disk store and at what + * location in the in-memory sequence to adminster it. If the + * order_by kind is BY_RECEPTIONTIME then the message should + * always be added. If it is the first message non-transactional + * message and the order is BY_RECEPTIONTIME then it is by + * definition the oldest non-transaction message until it + * gets pushed out of the history. */ + order_by = topicQos->orderby.v.kind; + if (order_by == V_ORDERBY_RECEPTIONTIME) { + /* oldest == NULL => latest is undefined */ + mprev = inst->oldest ? inst->latest : NULL; + kvdebug (" by-reception mprev msg %p\n", (void *) mprev); + } else { + mprev = find_insertafter_point (inst, msg); + kvdebug (" by-source mprev msg %p\n", (void *) mprev); + if (mprev != NULL && msg_v_message_cmp (mprev, msg) == 0) { + /* Discard duplicates. */ + kvdebug (" drop: duplicate vmsg %p\n", (void *)msg); + return D_STORE_RESULT_OK; + } + /* Messages that belong to a coherent transaction may always + * be added. In all other cases check whether adding the message + * is allowed */ + if (!(v_nodeState ((c_object)msg) & L_TRANSACTION)) { + if ((mprev == NULL) && (history_is_keeplast (topicQos)) && (inst->writeCount >= depth)) { + /* Msg is the oldest message in the list and the history is + * full, drop it immediately. */ + kvdebug (" drop: vmsg %p too old, won't fit\n", (void *)msg); + return D_STORE_RESULT_OK; + } else if ((inst->oldest_non_transaction != NULL) && (msg_v_message_cmp(inst->oldest_non_transaction, msg) > 0) && (history_is_keeplast (topicQos)) && (inst->writeCount >= depth)) { + /* Msg is older than the oldest non-transaction message + * and the history is full, drop it immediately. */ + kvdebug (" drop: vmsg %p too old, won't fit\n", (void *)msg); + return D_STORE_RESULT_OK; + } + } + } + /* Now we can safely add the message, but we may have to push out + * the oldest non-transaction message to meet the resource limits. */ + + kvdebug (" adding ...\n"); + + /* Add the new one, potentially growing the size of the history + * beyond what is allowed. If we crash after this write is stable + * but before the following deletes are, then we will have too + * much data on disk. + * + * A "dumb" injection process will reproduce all this messages, + * and that is application-visible (if the user starts a clean + * system in which an application has history KEEP_ALL while the + * durability service has history setting KEEP_LAST, and the + * application exists before the persistent data gets injected). + * + * There are multiple approaches to solving this. The obvious one + * is to use transactions to ensure this situation can never + * occur. But that significantly increases the requirements on the + * underlying key-value store. + * + * Another one is to rebuild the in-memory state first by reading + * what's in the on-disk store, without writing anything to + * disk. Note that the actual user data is not needed for + * this. Any data that is pushed out of the memory by definition + * is data that should've been deleted from the on-disk store -- + * and if desired, these can be removed later on. + * + * After this, the in-memory state contains just the messages that + * need to be republished, so that it becomes a matter of + * retrieving the payload for each of the message keys and + * republishing it. + * + * A side-effect of this procedure is that it builds up enough + * state in-memory to recognise injected data so that it can be + * ignored rather than written to disk again. Thereby, the master + * could essentially be read-only while injecting data. */ + if ((result = add_message_to_instance (&m, st, g, vtopic, inst, mprev, msg, p_mid, order_by)) != D_STORE_RESULT_OK) { + kvdebug (" add failed\n"); + return result; + } + + kvdebug(" msg %p for vmsg %p added to instance %p\n", (void *)m, (void *)msg, (void *)inst); + + /* If the history is full then drop the oldest non-transaction + * message. Keep dropping non-transactional messages until the history + * is no longer overfull. When the number of writes equals the history + * depth, we have no use for disposes at the beginning of the sequence, + * so drop everything until the history is no longer overful and + * there. But do not drop message when the is L_TRANSACTION + * flag set */ + + if (history_is_keeplast (topicQos)) { + if ((result = check_and_update_history(st, inst, depth, reconstructing)) != D_STORE_RESULT_OK) { + return result; + } + } + + /* Update namespace quality. FIXME: I don't think there's much use + * for updating it on-disk each time, but do so for now. */ + if (!reconstructing) { + os_timeW quality; + quality = os_timeWGet (); + set_namespace_quality_deferred (st, g->namespace, &quality); + } + return D_STORE_RESULT_OK; +} + + +d_storeResult d_storeMessageStoreKV (const d_store gstore, const v_groupAction msg) +{ + d_storeKV st; + d_storeResult result; + d_groupListKV g; + + kvdebug("d_storeMessageStoreKV\n"); + + if (msg == NULL || msg->group == NULL || msg->message == NULL) { + return D_STORE_RESULT_ILL_PARAM; + } + + /* Analysis of v_group.c, v_writer.c, d_persistentDataListener.c + * says this is either a WRITE or a WRITE_DISPOSE, and may + * have TRANSACTION and/or SYNCHRONOUS and/or ALIGN set, but nothing else. */ + assert (v_nodeState (msg->message) & L_WRITE); + assert ((v_nodeState (msg->message) & ~(L_WRITE | L_DISPOSED | L_TRANSACTION | L_SYNCHRONOUS)) == 0); + + LOCK_OPEN_STOREKV (st, gstore); + + /* Code used to benchmark KV store (DDS1582) */ + if (kvlog_statistics && st->action_started) { + st->first_time = os_timeEGet(); + st->action_started = FALSE; + } + /* end of benchmark code */ + + if ((g = find_group_w_kernelgroup (st, msg->group)) == NULL) { + result = D_STORE_RESULT_PRECONDITION_NOT_MET; + } else { + /* Store the kernel group in the groupListKV for easy access */ + g->vgroup = msg->group; + + result = store_message (st, msg->group, msg->message, g, NULL, NULL); + + /* Code used to benchmark KV store (DDS1582) */ + if (kvlog_statistics) { + st->last_time = os_timeEGet(); + } + /* end of benchmark code */ + } + + UNLOCK_OPEN_STOREKV (st); + return result; +} + +d_storeResult d_storeInstanceDisposeKV (const d_store gstore, const v_groupAction msg) +{ + d_storeKV st; + d_storeResult result; + d_groupListKV g; + + if (msg == NULL || msg->group == NULL || msg->message == NULL) { + return D_STORE_RESULT_ILL_PARAM; + } + + /* Analysis of v_group.c, v_writer.c, d_persistentDataListener.c + * says that this is DISPOSE, and may have TRANSACTION and/or + * SYNCHRONOUS and/or ALIGNED set, but nothing else. */ + assert (v_nodeState (msg->message) & L_DISPOSED); + assert ((v_nodeState (msg->message) & ~(L_DISPOSED | L_TRANSACTION | L_SYNCHRONOUS)) == 0); + + LOCK_OPEN_STOREKV (st, gstore); + if ((g = find_group_w_kernelgroup (st, msg->group)) == NULL) { + result = D_STORE_RESULT_PRECONDITION_NOT_MET; + } else { + /* Store the kernel group in the groupListKV for easy access */ + g->vgroup = msg->group; + + result = store_message (st, msg->group, msg->message, g, NULL, NULL); + } + UNLOCK_OPEN_STOREKV (st); + return result; +} + +d_storeResult d_storeInstanceExpungeKV (const d_store gstore, const v_groupAction msg) +{ + d_storeKV st; + d_storeResult result; + struct d_groupListKV_s *g; + struct inst *inst; + + if (msg == NULL || msg->group == NULL || msg->message == NULL) { + return D_STORE_RESULT_ILL_PARAM; + } + + kvdebug ("d_storeInstanceExpungeKV\n"); + + LOCK_OPEN_STOREKV (st, gstore); + if ((g = find_group_w_kernelgroup (st, msg->group)) == NULL) { + result = D_STORE_RESULT_PRECONDITION_NOT_MET; + } else if ((result = find_instance (&inst, g, msg->group, msg->message)) != D_STORE_RESULT_OK || inst == NULL) { + ; /* skip */ + } else { + result = D_STORE_RESULT_OK; + while ((result == D_STORE_RESULT_OK) && + (inst) && + (inst->oldest)) { + result = drop_message (st, g, &inst, inst->oldest, 0); + } + if (result == D_STORE_RESULT_OK && kv_commit (st->kv) < 0) { + kvlog (st, D_LEVEL_SEVERE, "instance-expunge: commit failed\n"); + result = D_STORE_RESULT_IO_ERROR; + } + } + UNLOCK_OPEN_STOREKV (st); + return result; +} + +d_storeResult d_storeMessageExpungeKV (const d_store gstore, const v_groupAction msg) +{ + d_storeKV st; + d_storeResult result; + struct d_groupListKV_s *g; + struct inst *inst; + struct msg *m; + + if (msg == NULL || msg->group == NULL || msg->message == NULL) { + return D_STORE_RESULT_ILL_PARAM; + } + + kvdebug ("d_storeMessageExpungeKV\n"); + + LOCK_OPEN_STOREKV (st, gstore); + if ((g = find_group_w_kernelgroup (st, msg->group)) == NULL) { + result = D_STORE_RESULT_PRECONDITION_NOT_MET; + } else if ((result = find_instance (&inst, g, msg->group, msg->message)) != D_STORE_RESULT_OK || inst == NULL) { + ; /* skip */ + } else if ((m = find_message (inst, msg->message)) != NULL) { + result = drop_message (st, g, &inst, m, 0); + if (result == D_STORE_RESULT_OK && kv_commit (st->kv) < 0) { + kvlog (st, D_LEVEL_SEVERE, "message-expunge: commit failed\n"); + result = D_STORE_RESULT_IO_ERROR; + } + } else { + result = D_STORE_RESULT_OK; + } + UNLOCK_OPEN_STOREKV (st); + return result; +} + +struct delete_historical_data_helper_arg { + struct d_storeKV_s *st; + os_timeW delete_time; + c_iter instances_to_delete; + d_storeResult result; +}; + + +static c_bool delete_historical_data_helper (struct inst *inst, struct delete_historical_data_helper_arg *arg) +{ + struct msg *m; + m = inst->oldest; + while (m && arg->result == D_STORE_RESULT_OK) { + struct msg *mnext = m->newer; + if (os_timeWCompare (m->writeTime, arg->delete_time) != OS_MORE) { + arg->result = drop_just_message (arg->st, inst, m, 0); + } + m = mnext; + } + if (inst->oldest == NULL) { + /* Instance is empty, but the table walk routine doesn't allow + * for deleting data while walking the tree. So remember the + * instance as one that has to be deleted after the walk + * completes. */ + arg->instances_to_delete = c_iterInsert (arg->instances_to_delete, inst); + } + return (arg->result == D_STORE_RESULT_OK); +} + + +d_storeResult d_storeDeleteHistoricalDataKV (const d_store gstore, const v_groupAction msg) +{ + d_storeKV st; + d_storeResult result; + struct d_groupListKV_s *g; + os_duration d; + struct delete_historical_data_helper_arg arg; + struct inst *inst; + + if (msg == NULL || msg->group == NULL) { + return D_STORE_RESULT_ILL_PARAM; + } + + LOCK_OPEN_STOREKV (st, gstore); + if ((g = find_group_w_kernelgroup (st, msg->group)) == NULL) { + result = D_STORE_RESULT_PRECONDITION_NOT_MET; + goto err_group; + } + arg.st = st; + /* The actiontime indicates the deleteTime as elapsed time. + * We need to calculate the corresponding wall clock time */ + d = os_timeEDiff(os_timeEGet(), msg->actionTime); + arg.delete_time = os_timeWSub(os_timeWGet(), d); + if (OS_TIMEW_ISINVALID(arg.delete_time)) { + result = D_STORE_RESULT_ERROR; + kvlog (st, D_LEVEL_SEVERE, "delete-historical-data: invalid time\n"); + goto err_delete_time; + } + arg.instances_to_delete = c_iterNew (NULL); + arg.result = D_STORE_RESULT_OK; + (void)d_tableWalk (g->instances, delete_historical_data_helper, &arg); + if (arg.result != D_STORE_RESULT_OK) { + kvlog (st, D_LEVEL_SEVERE, "delete-historical-data: failed to delete data\n"); + } + while ((inst = (struct inst *) c_iterTakeFirst (arg.instances_to_delete)) != NULL) { + assert (ut_avlLookup (&group_inst_td, &g->instances_by_iid, &inst->next_msg_key.iid) == inst); + ut_avlDelete (&group_inst_td, &g->instances_by_iid, inst); + d_tableRemove (g->instances, inst); + inst_free (inst); + } + c_iterFree (arg.instances_to_delete); + result = arg.result; + if (result == D_STORE_RESULT_OK && kv_commit (st->kv) < 0) { + kvlog (st, D_LEVEL_SEVERE, "delete-historical-data: commit failed\n"); + result = D_STORE_RESULT_IO_ERROR; + } + +err_delete_time: +err_group: + UNLOCK_OPEN_STOREKV (st); + return result; +} + +d_storeResult d_storeInstanceRegisterKV (const d_store gstore, const v_groupAction msg) +{ + OS_UNUSED_ARG (gstore); + OS_UNUSED_ARG (msg); + return D_STORE_RESULT_OK; +} + +d_storeResult d_storeInstanceUnregisterKV (const d_store gstore, const v_groupAction msg) +{ + OS_UNUSED_ARG (gstore); + OS_UNUSED_ARG (msg); + return D_STORE_RESULT_OK; +} + +d_storeResult d_storeOptimizeGroupKV (const d_store gstore, const d_group group) +{ + OS_UNUSED_ARG (gstore); + OS_UNUSED_ARG (group); + return D_STORE_RESULT_OK; +} + +d_storeResult d_storeNsIsCompleteKV (const d_store gstore, const d_nameSpace nameSpace, c_bool *isComplete) +{ + d_storeKV st; + d_storeResult result; + struct namespace *ns; + + if (nameSpace == NULL) { + return D_STORE_RESULT_ILL_PARAM; + } + + LOCK_OPEN_STOREKV (st, gstore); + if ((ns = find_or_create_namespace (st, nameSpace)) == NULL) { + kvlog (st, D_LEVEL_SEVERE, "is-complete: namespace %s unknown\n", d_nameSpaceGetName (nameSpace)); + result = D_STORE_RESULT_PRECONDITION_NOT_MET; + } else { + kv_result_t rc; + void *obj; + rc = get2_deser (st, TABLE_NAMESPACE_COMPLETENESS, ns->id, ns->version, st->namespace_completeness_type, &st->namespace_completeness_tctx, &obj); + switch (rc) { + case 0: + *isComplete = ((struct d_namespaceCompletenessKV *) obj)->complete; + kvlog (st, D_LEVEL_FINEST, "is-complete: namespace %s %scomplete\n", ns->name, *isComplete ? "" : "in"); + result = D_STORE_RESULT_OK; + c_free (obj); + break; + case KV_RESULT_NODATA: + kvlog (st, D_LEVEL_INFO, "is-complete: namespace %s defaulting to incomplete\n", ns->name); + *isComplete = 0; + result = D_STORE_RESULT_OK; + break; + default: + *isComplete = 0; + result = kv_convert_result(rc); + break; + } + } + + UNLOCK_OPEN_STOREKV (st); + if (result != D_STORE_RESULT_OK) { + kvlog (st, D_LEVEL_WARNING, "is-complete: namespace %s get completeness failed\n", d_nameSpaceGetName (nameSpace)); + } + return result; +} + +d_storeResult d_storeNsMarkCompleteKV (const d_store gstore, const d_nameSpace nameSpace, c_bool isComplete) +{ + d_storeKV st; + d_storeResult result; + kv_result_t rc; + struct namespace *ns; + struct d_namespaceCompletenessKV *v; + + if (nameSpace == NULL) { + return D_STORE_RESULT_ILL_PARAM; + } + + LOCK_OPEN_STOREKV (st, gstore); + if ((ns = find_or_create_namespace (st, nameSpace)) == NULL) { + kvlog (st, D_LEVEL_SEVERE, "mark-complete: namespace %s unknown\n", d_nameSpaceGetName (nameSpace)); + result = D_STORE_RESULT_PRECONDITION_NOT_MET; + } else if ((v = c_new (st->namespace_completeness_type)) == NULL) { + result = D_STORE_RESULT_OUT_OF_RESOURCES; + } else { + v->complete = (isComplete != 0); + if ((rc = put2_ser (st, TABLE_NAMESPACE_COMPLETENESS, ns->id, ns->version, st->namespace_completeness_type, &st->namespace_completeness_tctx, v)) < 0) { + result = kv_convert_result(rc); + } else { + kvlog (st, D_LEVEL_FINEST, "mark-complete: namespace %s marked %scomplete\n", ns->name, isComplete ? "" : "in"); + if (kv_commit (st->kv) < 0) { + kvlog (st, D_LEVEL_SEVERE, "mark-complete: commit failed\n"); + result = D_STORE_RESULT_IO_ERROR; + } else { + result = D_STORE_RESULT_OK; + } + } + c_free (v); + } + + UNLOCK_OPEN_STOREKV (st); + if (result != D_STORE_RESULT_OK) { + kvlog (st, D_LEVEL_WARNING, "mark-complete: store completeness failed, result=%d\n", result); + } + return result; +} + +static int topic_definition_matches (d_storeKV st, v_group group, os_uint32 topic_id, const char *topic_name) +{ + const char *failmsg = NULL; + os_uint32 disk_sz, shm_sz; + void *disk, *shm; + struct d_topicInfoKV *tpdisk, *tpshm; + + if ((tpdisk = get_topicInfoKV (st, topic_id, topic_name)) == NULL) { + failmsg = "no topic definition found / out of memory (disk)"; goto fail_disk_topic; + } + if ((tpshm = make_topicInfoKV (st, v_groupTopic (group))) == NULL) { + failmsg = "out of memory (shm)"; goto fail_shm_topic; + } + + if ((disk = serialize_clearflag (&disk_sz, st, st->topicinfo_type, &st->topicinfo_tctx, tpdisk, 1)) == NULL) { + failmsg = "out of memory (re-serialize disk)"; goto fail_ser_disk; + } + if ((shm = serialize_clearflag (&shm_sz, st, st->topicinfo_type, &st->topicinfo_tctx, tpshm, 1)) == NULL) { + failmsg = "out of memory (serialize shm)"; goto fail_ser_shm; + } + /* ... and do a byte-wise comparison of the two. Explicitly + * check the sizes and do a memcmp instead of a simple strcmp + * to catch cases where the on-disk data has been + * (deliberately?) mutilated. */ + if (disk_sz != shm_sz || memcmp (disk, shm, shm_sz) != 0) { + failmsg = "mismatch between definitions"; goto fail_compare; + } + +fail_compare: + os_free (shm); +fail_ser_shm: + os_free (disk); +fail_ser_disk: + c_free (tpshm); +fail_shm_topic: + c_free (tpdisk); +fail_disk_topic: + if (failmsg) { + kvlog (st, D_LEVEL_SEVERE, "Topic %u (%s): verification: %s\n", topic_id, topic_name, failmsg); + } + return failmsg == NULL; +} + +static d_storeResult reconstruct_instances (struct d_storeKV_s *st, struct d_groupListKV_s *g, struct v_group_s *group) +{ + struct c_type_s *mtype, *xtype = NULL /* shut up compiler */; + d_storeResult result = D_STORE_RESULT_OK; + kv_key_t min, max; + kv_iter_t iter; + int hasdata; + struct transaction_list *tr_list; + + kvdebug ("reconstruct_instances ...\n"); + mtype = v_topicMessageType (v_groupTopic ((c_object)group)); + switch (st->encoding) + { + case D_ENCODINGKV_XML_XML: + case D_ENCODINGKV_BIGE_XML: + case D_ENCODINGKV_BIGECDR_XML: + if ((xtype = v_messageExtTypeNew (v_groupTopic ((c_object)group))) == NULL) { + kvlog (st, D_LEVEL_SEVERE, "out of resources (allocation of xmsg type)\n"); + return D_STORE_RESULT_OUT_OF_RESOURCES; + } + break; + case D_ENCODINGKV_BIGECDR_V1: + xtype = mtype; + break; + } + + min.table = TABLE_MESSAGE; + min.gid = g->group_id; + min.iid = 0; + min.mid = 0; + max.table = TABLE_MESSAGE; + max.gid = g->group_id; + max.iid = ~(os_uint32)0; + max.mid = ~(os_uint64)0; + kv_iter_new (st->kv, &iter, &min, &max, xtype); + /* Store all messages that are present in the TABLE_MESSAGE table */ + kvdebug(" reading all messages\n"); + while (result == D_STORE_RESULT_OK && kv_iter_next (&hasdata, st->kv, iter) >= 0 && hasdata) { + kv_key_t k; + void *x_msg; + kv_iter_getkey (st->kv, iter, &k); + kvdebug (" %u:%u:%llu\n", k.gid, k.iid, k.mid); + if (iter_value_deser (st, iter, xtype, &g->tctx, &x_msg) < 0) { + kvlog (st, D_LEVEL_SEVERE, " message {%u:%u:%llu:%llu}: stored data is corrupt\n", (unsigned) k.table, k.gid, k.iid, k.mid); + result = D_STORE_RESULT_MUTILATED; + } else { + void *v_msg = (xtype == mtype) ? x_msg : v_messageExtConvertFromExtType (mtype, x_msg); + result = store_message (st, group, v_msg, g, &k.iid, &k.mid); + c_free (v_msg); + } + } + kvdebug (" done\n"); + kv_iter_free (st->kv, iter); + if (xtype != mtype) { + v_messageExtTypeFree (xtype); + } + + /* Iterate over all EOT messages and commit the transactions + * that have finished */ + kvdebug ("Processing transaction records\n"); + min.table = TABLE_MESSAGE_EOT; + min.gid = 0; + min.iid = 0; + min.mid = 0; + max.table = TABLE_MESSAGE_EOT; + max.gid = 0; + max.iid = 0; + max.mid = ~(os_uint64)0; + kv_iter_new (st->kv, &iter, &min, &max, st->open_transaction_eot_type); + while (result == D_STORE_RESULT_OK && kv_iter_next (&hasdata, st->kv, iter) >= 0 && hasdata) { + kv_key_t k; + + kv_iter_getkey (st->kv, iter, &k); + if (k.mid >= st->otid) { + /* Set otid to next free number */ + st->otid = k.mid + 1; + } + kvdebug (" process %s journal msg with key %"PA_PRIu32":%"PA_PRIu32":%"PA_PRIu64"\n", k.mid & 1 ? "'commit'" : "'begin'", k.gid, k.iid, k.mid); + if (k.mid & 1) { + /* The message is an EOT message, so the transaction + * can be committed (C). If the commit succeeds the + * entry is removed from the list of open_transactions. */ + void *v_msgEOT; + + if (iter_value_deser (st, iter, st->open_transaction_eot_type, &st->open_transaction_eot_tctx, &v_msgEOT) < 0) { + kvlog (st, D_LEVEL_SEVERE, "MessageEOT {%u:%u:%llu:%llu}: stored data is corrupt\n", (unsigned) k.table, k.gid, k.iid, k.mid); + result = D_STORE_RESULT_MUTILATED; + } else { + result = commit_group_transaction (st, v_msgEOT, 1); + c_free (v_msgEOT); + } + } else { + /* The message is the begin (B) of a transaction, in which + * case the payload contains the v_tid. The transaction is considered + * OPEN until it becomes COMMITTED */ + void *tid; + + if (iter_value_deser (st, iter, st->open_transaction_vtid_type, &st->open_transaction_vtid_tctx, &tid) < 0) { + kvlog (st, D_LEVEL_SEVERE, "Message {%u:%u:%llu:%llu}: stored data is corrupt\n", (unsigned) k.table, k.gid, k.iid, k.mid); + result = D_STORE_RESULT_MUTILATED; + } else { + struct v_tid *vtid = tid; + struct transaction_list tr_list_template; + tr_list_template.gid = vtid->wgid; + tr_list_template.seqNum = vtid->seqnr; + if ((tr_list = d_tableFind(st->open_transactions, &tr_list_template)) != NULL) { + tr_list->commit_state = OPEN; + } + c_free (tid); + } + } + } + /* Now walk over all open transactions that are not yet + * yet committed */ + while ((result == D_STORE_RESULT_OK) && ((tr_list = d_tableTake (st->open_transactions)) != NULL)) { + if (tr_list->commit_state != OPEN) { + assert(tr_list->commit_state != COMMITTED); + result = commit_writer_transaction (st, tr_list, 1); + } else { + /* The transaction is OPEN and no EOT has + * been received. No EOT will come anymore + * so we do not have to maintain the + * transaction administration. */ + struct transaction_msg *msg; + while ((msg = tr_list->head) != NULL) { + tr_list->head = msg->next; + os_free (msg); + } + os_free (tr_list); + } + } + kvdebug (" done\n"); + kv_iter_free (st->kv, iter); + return result; +} + +struct inject_messages_helper_arg { + struct d_storeKV_s *st; + struct v_group_s *group; + d_storeResult result; + c_bool store_msg; +}; + +struct pending_unregister { + v_message protomsg; + c_ulong sequenceNumber; + os_timeW writeTime; +}; + +static int pending_unregister_cmp (const struct pending_unregister *a, const struct pending_unregister *b) +{ + c_equality eq; + eq = v_gidCompare (a->protomsg->writerGID, b->protomsg->writerGID); + if (eq == C_LT) { + return -1; + } else if (eq == C_GT) { + return 1; + } + eq = v_gidCompare (a->protomsg->writerInstanceGID, b->protomsg->writerInstanceGID); + if (eq == C_LT) { + return -1; + } else if (eq == C_GT) { + return 1; + } + return 0; +} + +static void pending_unregister_free (struct pending_unregister *a) +{ + kvdebug (" pending_unregister_free %p\n", (void *) a); + c_free (a->protomsg); + os_free (a); +} + +static d_storeResult schedule_unregister (d_table tab, const struct v_message_s *msg) +{ + struct pending_unregister tmp, *pu; + tmp.protomsg = (v_message) msg; + if ((pu = d_tableFind (tab, &tmp)) != NULL) { + kvdebug (" schedule_unregister: %d:%d:%d already scheduled\n", msg->writerGID.systemId, msg->writerGID.localId, msg->writerGID.serial); + if (pu->sequenceNumber <= msg->sequenceNumber) { + pu->sequenceNumber = msg->sequenceNumber + 1; + kvdebug (" updating seq num\n"); + } + if (os_timeWCompare (pu->writeTime, msg->writeTime) == OS_LESS) { + pu->writeTime = msg->writeTime; + kvdebug (" updating time\n"); + } + return D_STORE_RESULT_OK; + } else { + pu = os_malloc (sizeof (*pu)); + pu->protomsg = c_keep (v_message ((c_object)msg)); + pu->sequenceNumber = msg->sequenceNumber + 1; + pu->writeTime = msg->writeTime; + (void) d_tableInsert (tab, pu); + kvdebug (" schedule_unregister: %d:%d:%d new\n", msg->writerGID.systemId, msg->writerGID.localId, msg->writerGID.serial); + return D_STORE_RESULT_OK; + } +} + +static c_bool inject_unregister_helper (struct pending_unregister *pu, struct inject_messages_helper_arg *arg) +{ + /* Create unregister message for given writer id, sequence number + * and time stamp, and inject it. */ + const os_duration poll_intv = OS_DURATION_INIT(1,0); + const os_duration inc = OS_DURATION_INIT(0, 100); + c_base base = c_getBase(arg->group); + c_array keys; + c_ulong i, nkeys; + v_message msg; + v_writeResult wr; + + msg = v_topicMessageNew (v_groupTopic (arg->group)); + keys = v_topicMessageKeyList (v_groupTopic (arg->group)); + nkeys = c_arraySize (keys); + for (i = 0; i < nkeys; i++) { + c_fieldAssign (keys[i], msg, c_fieldValue (keys[i], pu->protomsg)); + } + msg->writerGID = pu->protomsg->writerGID; + msg->writerInstanceGID = pu->protomsg->writerInstanceGID; + msg->qos = c_keep ((v_qos) pu->protomsg->qos); + msg->writeTime = os_timeWAdd(pu->writeTime, inc); + msg->sequenceNumber = pu->sequenceNumber; + v_nodeState (msg) = L_UNREGISTER; + if (v_messageStateTest (pu->protomsg, L_TRANSACTION)) { + v_stateSet (v_nodeState (msg), L_TRANSACTION); + msg->transactionId = pu->protomsg->transactionId; + } + + kvdebug (" inject_unregister_helper: %d:%d:%d state=%d\n", msg->writerGID.systemId, msg->writerGID.localId, msg->writerGID.serial, msg->_parent.nodeState); + + do { + if (c_baseMakeMemReservation(base, C_MM_RESERVATION_ZERO)) { + wr = v_groupWriteNoStream (arg->group, msg, NULL, V_NETWORKID_ANY); + c_baseReleaseMemReservation(base, C_MM_RESERVATION_ZERO); + if (wr == V_WRITE_REJECTED) { + ospl_os_sleep (poll_intv); + } + } else { + wr = V_WRITE_OUT_OF_RESOURCES; + } + } while (wr == V_WRITE_REJECTED); + + if (wr != V_WRITE_SUCCESS && wr != V_WRITE_REGISTERED && wr != V_WRITE_UNREGISTERED) { + kvlog (arg->st, D_LEVEL_SEVERE, "Unable to write unregister messaged to group. (result: '%d')\n", wr); + arg->result = D_STORE_RESULT_ERROR; + } else { + arg->result = D_STORE_RESULT_OK; + } + + c_free (msg); + return (arg->result == D_STORE_RESULT_OK); +} + + +static c_bool inject_messages_helper (const struct inst *inst, struct inject_messages_helper_arg *arg) +{ + d_table pending_unregisters; + struct msg *m; + struct d_groupListKV_s *g = NULL; + c_base base = c_getBase(arg->group); + + kvdebug (" inst %u\n", inst->next_msg_key.iid); + /* Find group when messages needs to be added to store, group + * should already exist. */ + if ((arg->store_msg == TRUE) && + (g = find_group_w_kernelgroup (arg->st, arg->group)) == NULL) { + kvlog (arg->st, D_LEVEL_SEVERE, "Unable to find group while it existed earlier.\n"); + arg->result = D_STORE_RESULT_ERROR; + return FALSE; + } + + pending_unregisters = d_tableNew (pending_unregister_cmp, pending_unregister_free); + for (m = inst->oldest; m; m = m->newer) { + const os_duration poll_intv = OS_DURATION_INIT(1,0); + v_writeResult wr; + + assert (m->v_msg != NULL); + kvdebug (" msg %llu\n", m->key.mid); + kvdebug (" inject_messages_helper: %d:%d:%d state=%d\n", m->v_msg->writerGID.systemId, m->v_msg->writerGID.localId, m->v_msg->writerGID.serial, m->v_msg->_parent.nodeState); + do { + if (c_baseMakeMemReservation(base, C_MM_RESERVATION_ZERO)) { + wr = v_groupWriteNoStream (arg->group, m->v_msg, NULL, V_NETWORKID_ANY); + c_baseReleaseMemReservation(base, C_MM_RESERVATION_ZERO); + if (wr == V_WRITE_REJECTED) { + ospl_os_sleep (poll_intv); + } + } else { + wr = V_WRITE_OUT_OF_RESOURCES; + } + } while (wr == V_WRITE_REJECTED); + + if (wr != V_WRITE_SUCCESS && wr != V_WRITE_REGISTERED && wr != V_WRITE_UNREGISTERED) { + kvlog (arg->st, D_LEVEL_SEVERE, "Unable to write persistent data to group. (result: '%d')\n", wr); + arg->result = D_STORE_RESULT_ERROR; + } else { + if (g) { + d_storeResult result; + kvdebug (" inject_messages_helper: inject loaded message in KV store\n"); + result = store_message (arg->st, arg->group, m->v_msg, g, NULL, NULL); + if (result != D_STORE_RESULT_OK) { + kvlog (arg->st, D_LEVEL_SEVERE, "Unable to inject loaded message in KV store. (result: '%d')\n", result); + arg->result = D_STORE_RESULT_ERROR; + } + } + arg->result = schedule_unregister (pending_unregisters, m->v_msg); + } + + c_free (m->v_msg); + m->v_msg = NULL; + } + + if (arg->result == D_STORE_RESULT_OK) { + (void)d_tableWalk (pending_unregisters, inject_unregister_helper, arg); + } + d_tableFree (pending_unregisters); + return (arg->result == D_STORE_RESULT_OK); +} + + +static d_storeResult inject_messages (struct d_storeKV_s *st, const struct d_groupListKV_s *g, struct v_group_s *group, c_bool store_msg) +{ + struct inject_messages_helper_arg arg; + kvdebug ("injecting messages ...\n"); + arg.st = st; + arg.group = group; + arg.result = D_STORE_RESULT_OK; + arg.store_msg = store_msg; + (void)d_tableWalk (g->instances, inject_messages_helper, &arg); + if (arg.result == D_STORE_RESULT_OK) { + kvlog(st, D_LEVEL_FINEST, "injected %d instance(s) for group '%s.%s'\n", d_tableSize(g->instances), g->_parent.partition, g->_parent.topic); + } + kvdebug (" done\n"); + return arg.result; +} + +d_storeResult d_storeMessagesInjectKV (const d_store gstore, const d_group dgroup) +{ + d_storeKV st; + d_storeResult result = D_STORE_RESULT_OK; + c_char *topicName; + c_char *partitionName; + v_group group; + os_uint32 topic_id; + d_groupListKV g; + + if (gstore == NULL || dgroup == NULL) { + return D_STORE_RESULT_ILL_PARAM; + } + + LOCK_OPEN_STOREKV (st, gstore); + + group = d_groupGetKernelGroup (dgroup); + topicName = v_topicName (v_groupTopic (group)); + partitionName = v_partitionName (v_groupPartition (group)); + kvlog (st, D_LEVEL_FINE, "inject-messages group '%s.%s'\n", partitionName, topicName); + + /* We need the topic_id, and the easiest way to find that is to + * enumerate the in-memory representation of the groups. Those get + * initialised from the disk as soon as the store is opened, and + * so if we can't find it there, it doesn't exist on disk. + * + * I think it would be slightly odd to get a request for injecting + * data for a group we know nothing about, but it is + * conceivable. Since we know there is no data for this group on + * disk, just say we injected all we had. */ + if ((g = find_group (st, partitionName, topicName)) == NULL) { + kvlog (st, D_LEVEL_WARNING, "inject messages: group '%s.%s' unknown (guaranteed no data)\n", partitionName, topicName); + result = D_STORE_RESULT_OK; + goto out; + } + topic_id = g->topic_id; + kvdebug (" topic_id = %u\n", topic_id); + + /* If we know of the group, we must still verify that the topic + * definitions in the kernel and on-disk match: there is no + * guarantee some other process hasn't already defined the topic + * in an incompatible way. */ + if (!topic_definition_matches (st, group, topic_id, topicName)) { + kvlog (st, D_LEVEL_WARNING, "inject messages: topic '%s' definitions do not match, not injecting\n", topicName); + result = D_STORE_RESULT_METADATA_MISMATCH; + goto out; + } + kvdebug (" topic definitions match\n"); + + /* Store the kernel group in the d_groupListKV. This makes lookup + * of the kernel group very easy. */ + g->vgroup = group; + + /* Two options for injecting data: first is to reconstruct the + * instances in-memory, then regenerate the messages that matter + * (there could be crash just before dropping some message, + * leading to too much persistent data); the other is to simply + * regenerate everything and accepting the potential publication + * of a few messages more than we should. + * + * The first also gives us the option of re-using the data stored + * on disk. For a first version, it is the nicer choice. */ + reconstruct_instances (st, g, group); + + /* Once we have everything in-memory start injecting */ + result = inject_messages (st, g, group, FALSE); + + kvdebug (" done\n"); +out: + UNLOCK_OPEN_STOREKV (st); + return result; +} + +static int topic_referenced_in_groups_p (const struct d_groupListKV_s *gs, os_uint32 topic_id) +{ + /* FIXME: stupid way of finding unreferenced topics */ + const struct d_groupListKV_s *g; + for (g = gs; g; g = (const struct d_groupListKV_s *) g->_parent.next) { + if (g->topic_id == topic_id) { + return 1; + } + } + return 0; +} + +static d_storeResult delete_namespace_version (struct d_storeKV_s *st, struct namespace *ns) +{ + /* Near all failures to delete data are but a warning, because the + * first delete ensures the namespace version is no longer visible + * when opening the store. */ + kv_key_t key; + struct d_groupListKV_s *gs = NULL; + + kvlog (st, D_LEVEL_INFO, "delete-namespace-version: namespace %s id %u/%u\n", ns->name, ns->id, ns->version); + + /* Delete namespace quality, completeness from disk store: that + * way this version will be considered incomplete and of minimal + * quality if we crash during this operation. */ + key.gid = ns->id; key.iid = ns->version; key.mid = 0; + key.table = TABLE_NAMESPACE; + if (kv_delete (st->kv, &key) < 0) { + kvlog (st, D_LEVEL_SEVERE, "delete-namespace-version: delete namespace failed\n"); + return D_STORE_RESULT_ERROR; + } + key.table = TABLE_NAMESPACE_COMPLETENESS; + if (kv_delete (st->kv, &key) < 0) { + kvlog (st, D_LEVEL_WARNING, "delete-namespace-version: delete namespace completeness failed\n"); + } + key.table = TABLE_NAMESPACE_QUALITY; + if (kv_delete (st->kv, &key) < 0) { + kvlog (st, D_LEVEL_WARNING, "delete-namespace-version: delete namespace quality failed\n"); + } + + /* Remove namespace from list of namespaces */ + { + struct namespace **pn = &st->namespaces; + while (*pn != ns) { + pn = &(*pn)->next; + } + *pn = ns->next; + } + /* Remove groups referring to namespace NS from list of groups, + * transferring them to GS */ + { + struct d_groupListKV_s **pg = &st->groups, *g = *pg; + while (g) { + if (g->namespace == ns) { + *pg = g->_parent.next; + g->_parent.next = gs; + gs = g; + } else { + pg = (struct d_groupListKV_s **) &g->_parent.next; + } + g = *pg; + } + } + + /* Delete messages, group definitions, topic definitions from the + * on-disk representation */ + { + const struct d_groupListKV_s *g; + for (g = gs; g; g = (struct d_groupListKV_s *) g->_parent.next) { + kv_key_t first, last; + kvlog (st, D_LEVEL_INFO, "delete-namespace-version: deleting messages group %s.%s (%u)\n", + g->_parent.partition, g->_parent.topic, g->group_id); + first.table = last.table = TABLE_MESSAGE; + first.gid = last.gid = g->group_id; + first.iid = 0; last.iid = ~0u; + first.mid = 0; last.mid = ~(os_uint64) 0; + if (kv_bulkdelete (st->kv, &first, &last) < 0) { + kvlog (st, D_LEVEL_WARNING, "delete-namespace-version: delete messages group %s.%s (%u) failed\n", + g->_parent.partition, g->_parent.topic, g->group_id); + } + + kvlog (st, D_LEVEL_INFO, "delete-namespace-version: deleting group %s.%s (%u)\n", + g->_parent.partition, g->_parent.topic, g->group_id); + key.table = TABLE_GROUP; key.gid = g->group_id; key.iid = 0; key.mid = 0; + if (kv_delete (st->kv, &key) < 0) { + kvlog (st, D_LEVEL_WARNING, "delete-namespace-version: delete group %s.%s (%u) failed\n", + g->_parent.partition, g->_parent.topic, g->group_id); + } + } + + for (g = gs; g; g = (struct d_groupListKV_s *) g->_parent.next) { + /* Second term is only for pretty printing: without it, + * the same topic can be deleted multiple times (where + * only the first time has effect) */ + if (!topic_referenced_in_groups_p (st->groups, g->topic_id) && + !topic_referenced_in_groups_p ((struct d_groupListKV_s *) g->_parent.next, g->topic_id)) { + kvlog (st, D_LEVEL_INFO, "delete-namespace-version: topic %s (%u) no longer needed\n", + g->_parent.topic, g->topic_id); + key.gid = g->topic_id; key.iid = 0; key.mid = 0; + key.table = TABLE_TOPIC; + if (kv_delete (st->kv, &key) < 0) { + kvlog (st, D_LEVEL_WARNING, "delete-namespace-version: delete topic %s (%u) failed\n", + g->_parent.topic, g->topic_id); + } + key.table = TABLE_TOPIC_TYPE; + if (kv_delete (st->kv, &key) < 0) { + kvlog (st, D_LEVEL_WARNING, "delete-namespace-version: delete topic %s (%u) failed\n", + g->_parent.topic, g->topic_id); + } + } + } + } + + /* Free memory -- need not be done this late. */ + while (gs) { + struct d_groupListKV_s *g = gs; + gs = (struct d_groupListKV_s *) gs->_parent.next; + free_group (g, st); + } + free_namespace (ns); + kvlog (st, D_LEVEL_INFO, "delete-namespace-version: delete namespace done\n"); + return D_STORE_RESULT_OK; +} + +static struct namespace *find_older_namespace_version (const struct namespace *ns) +{ + struct namespace *ns0; + for (ns0 = ns->next; ns0; ns0 = ns0->next) { + if (ns0->id == ns->id) { + return ns0; + } + } + return NULL; +} + +d_storeResult d_storeBackupKV (const d_store gstore, const d_nameSpace nameSpace) +{ + /* ASSUMPTION: + * + * Backup(NS) is only called by durability when it will NOT be + * injecting data for namespace NS, but regardless of its being + * complete. It then calls d_storeGroupStore and + * d_storeMessageStore to store the new groups and the data in + * those groups. After that, it expects namespace NS to be empty. + * + * All we need to do to generate the backup and to start afresh is + * generate a new version of the matching namespace. The old + * group definition is then no longer accessible because it is of + * the wrong namespace version, therefore GroupStore(G) will not + * re-use it, therefore a new group id gets allocated. Since + * topics are (currently anyway) still stored in memory accessible + * only via groups, this will then also force the creation of new + * topics. */ + d_storeKV st; + d_storeResult result; + struct namespace *ns, *ns1; + + if (nameSpace == NULL) { + return D_STORE_RESULT_ILL_PARAM; + } + + LOCK_OPEN_STOREKV (st, gstore); + if ((ns = find_namespace (st, nameSpace)) == NULL) { + kvlog (st, D_LEVEL_INFO, "store-backup: namespace %s unknown\n", d_nameSpaceGetName (nameSpace)); + result = D_STORE_RESULT_OK; + } else if ((ns1 = new_namespace_version (st, ns)) == NULL) { + kvlog (st, D_LEVEL_SEVERE, "store-backup: backup of namespace %s failed: out of memory\n", d_nameSpaceGetName (nameSpace)); + result = D_STORE_RESULT_PRECONDITION_NOT_MET; + } else { + kvlog (st, D_LEVEL_FINEST, "store-backup: namespace %s new id %u/%u\n", ns1->name, ns1->id, ns1->version); + if ((result = store_namespace (st, ns1)) != D_STORE_RESULT_OK) { + /* failed to store namespace, do not delete anything; + * error already logged by store_namespace() */ + } else { + /* see if we have a backups preceding NS, and if so, delete them */ + struct namespace *ns0; + while (result == D_STORE_RESULT_OK && (ns0 = find_older_namespace_version (ns)) != NULL) { + result = delete_namespace_version (st, ns0); + } + if (result == D_STORE_RESULT_OK) { + kvlog (st, D_LEVEL_INFO, "store-backup: no older backups\n"); + } + } + } + UNLOCK_OPEN_STOREKV (st); + return result; +} + +d_storeResult d_storeRestoreBackupKV (const d_store gstore, const d_nameSpace nameSpace) +{ + /* ASSUMPTION: + * + * RestoreBackup(NS) is only called by durability when it faces an + * incomplete persistent store. The XML store leaves the primary + * copy unchanged if there is no backup, but does return an error. + * + * To restore a backup, all we need to do is drop the latest + * version of nameSpace, provided there is an older version (that + * condition ensures we retain what we have if there is no + * backup). */ + d_storeKV st; + d_storeResult result; + struct namespace *ns; + + if (nameSpace == NULL) { + return D_STORE_RESULT_ILL_PARAM; + } + + LOCK_OPEN_STOREKV (st, gstore); + if ((ns = find_namespace (st, nameSpace)) == NULL) { + kvlog (st, D_LEVEL_INFO, "restore-backup: namespace %s unknown\n", d_nameSpaceGetName (nameSpace)); + result = D_STORE_RESULT_OK; + } else { + if (find_older_namespace_version (ns) == NULL) { + if (!ns->on_disk) { + result = D_STORE_RESULT_OK; + } else { + kvlog (st, D_LEVEL_WARNING, "restore-backup: no backup available, keeping current data\n"); + result = D_STORE_RESULT_IO_ERROR; + } + } else { + result = delete_namespace_version (st, ns); + } + } + UNLOCK_OPEN_STOREKV (st); + return result; +} + + +/** + * \brief Store and commit journal entries for the EOT message + * + * Only EOT messages for which open transactions exist are committed. + */ +static d_storeResult journal_message_EOT (struct d_storeKV_s *st, const struct v_messageEOT_s *msg, os_uint64 *commit_mid) +{ + struct transaction_list tr_list_template, *tr_list; + c_ulong i; + kv_result_t rc; + kv_key_t key; + c_bool toStore = FALSE; + + /* As the key of the EOT message we use 64-bits. + * The first 63 MSB bits will be used as a sequence number. + * This LSB-bit will be used to indicate whether + * message processing is busy (0) or has completed (1). + * This will give in total 2^63 possible open transactions + * to be stored. */ + + kvdebug ("journal_message_EOT: vmsg %p\n", (void *) msg); + + /* Iterate over the list of writerGIDs in the EOT message, + * and commit all open transaction messages that match + * the writerGID and transactionId. */ + for (i=0; i < c_arraySize(msg->tidList); i++) { + struct v_tid *vtid; + + /* Find the transaction list */ + vtid = &(((struct v_tid *)msg->tidList)[i]); + tr_list_template.gid = vtid->wgid; + tr_list_template.seqNum = vtid->seqnr; + tr_list_template.head = NULL; + tr_list_template.tail = NULL; + if ((tr_list = d_tableFind(st->open_transactions, &tr_list_template)) != NULL) { + /* The EOT message contains an open transaction for which + * messages are present in my administration. Store the EOT + * message in the MESSAGE_EOT table to indicate that the EOT + * has been received. */ + toStore = TRUE; + break; + } + } + if (!toStore) { + *commit_mid = 0; /* can't ever be 0 for a real one */ + } else { + key.table = TABLE_MESSAGE_EOT; + key.gid = 0; + key.iid = 0; + key.mid = (st->otid % 2) == 0 ? st->otid+1 : st->otid; /* unique id, 63-bits transactionId, always odd for eot message */ + st->otid = key.mid + 1; + *commit_mid = key.mid; + if ((rc = put_ser (st, &key, st->open_transaction_eot_type, &st->open_transaction_eot_tctx, msg)) < 0) { + return kv_convert_result(rc); + } + + kvdebug(" adding eot %p to journal, key = %u\n", (void *)msg, key.mid); + + /* Commit the updates associated with the transaction */ + if (kv_commit (st->kv) < 0) { + kvlog (st, D_LEVEL_SEVERE, "journal_message_EOT: commit failed\n"); + return D_STORE_RESULT_IO_ERROR; + } + kvdebug(" add eot msg to journal with key=%d:%d:%d\n", key.gid, key.iid, key.mid); + + + } + return D_STORE_RESULT_OK; +} + +static struct msg *get_oldest_non_transaction (struct msg *a, struct msg *b, v_orderbyKind order_by) +{ + /* A must be a committed write, hence have L_WRITE set and L_TRANSACTION clear; B must be same if provided */ + assert((a->state & L_WRITE) && !(a->state & L_TRANSACTION)); + assert((b == NULL) || ((b->state & L_WRITE) && !(b->state & L_TRANSACTION))); + if (b == NULL) { + return a; + } else { + switch (order_by) { + case V_ORDERBY_RECEPTIONTIME: + /* message ids (mid) are monotonically increasing (per instance) over the lifetime of persistent store */ + return (a->key.mid < b->key.mid) ? a : b; + case V_ORDERBY_SOURCETIME: + return (msg_cmp(a, b) < 0) ? a : b; + } + assert(FALSE); + return a; + } +} + +static d_storeResult commit_writer_transaction_message (struct d_storeKV_s *st, const struct transaction_msg *tr_msg, int reconstructing) +{ + struct v_topicQos_s *topicQos; + v_orderbyKind order_by; + os_int32 depth; + struct inst *inst; + d_storeResult result; + struct msg *oldest_non_transaction; + + + assert(tr_msg->msg_ref); + inst = tr_msg->msg_ref->inst; + /* Verify that the L_TRANSACTION flag is set. */ + assert(tr_msg->msg_ref->state & L_TRANSACTION); + + topicQos = v_topicQosRef (v_groupTopic (inst->g->vgroup)); + depth = topicQos->durabilityService.v.history_depth; + order_by = topicQos->orderby.v.kind; + /* Reset the L_TRANSACTION flag and update the writeCount */ + tr_msg->msg_ref->state = tr_msg->msg_ref->state & ~L_TRANSACTION; + if (reconstructing) { + tr_msg->msg_ref->v_msg->_parent.nodeState &= ~L_TRANSACTION; + } else { + assert (tr_msg->msg_ref->v_msg == NULL); + } + + kvdebug(" msg %p state %x\n", (void *)tr_msg->msg_ref, tr_msg->msg_ref->state); + + if (tr_msg->msg_ref->state & L_WRITE) { + inst->writeCount++; + oldest_non_transaction = inst->oldest_non_transaction; + /* Maintain the oldest_non_transaction */ + inst->oldest_non_transaction = get_oldest_non_transaction(tr_msg->msg_ref, inst->oldest_non_transaction, order_by); + if (oldest_non_transaction != inst->oldest_non_transaction) { + kvdebug(" oldest_non_transaction set to %p\n", (void *)inst->oldest_non_transaction); + } + } + /* Check the history depth and push out the oldest_non_transaction + * if it does not fit */ + if (history_is_keeplast(topicQos)) { + if ((result = check_and_update_history(st, inst, depth, reconstructing)) != D_STORE_RESULT_OK) { + return result; + } + } + + return D_STORE_RESULT_OK; +} + +static d_storeResult commit_writer_transaction (struct d_storeKV_s *st, struct transaction_list *tr_list, int reconstructing) +{ + d_storeResult result = D_STORE_RESULT_OK; + + kvdebug(" commit_writer_transaction\n"); + + while ((tr_list->head != NULL) && (result == D_STORE_RESULT_OK)) { + struct transaction_msg *tr_msg = tr_list->head; + tr_list->head = tr_msg->next; + result = commit_writer_transaction_message (st, tr_msg, reconstructing); + os_free (tr_msg); + } + if (result == D_STORE_RESULT_OK && !reconstructing) + { + /* All messages that belong to the writer and transaction have been committed. + * Now it is safe to throw away the entry. */ + kv_key_t k; + + tr_list->commit_state = COMMITTED; + k.table = TABLE_MESSAGE_EOT; + k.gid = 0; + k.iid = 0; + k.mid = tr_list->otid; + if (kv_delete (st->kv, &k) < 0) { + kvlog (st, D_LEVEL_SEVERE, "Failed to delete message {%u:%u:%llu:%llu}\n", k.table, k.gid, k.iid, k.mid); + } + } + os_free(tr_list); + return result; +} + +/** + * \brief Insert the transaction messages that belong to the group transaction + * as "normal" messages. + * + * A side-effect of this operation is that the L_TRANSACTION flag + * of the message that belongs to the transaction is cleared, and + * samples may be pushed out of the history. + */ +static d_storeResult commit_group_transaction (struct d_storeKV_s *st, const struct v_messageEOT_s *msg, int reconstructing) +{ + struct transaction_list tr_list_template, *tr_list; + const struct v_tid *tidlist = (const struct v_tid *)msg->tidList; + c_ulong i; + d_storeResult result = D_STORE_RESULT_OK; + + kvdebug ("commit_group_transaction: vmsg %p\n", (void *) msg); + + for (i=0; i < c_arraySize(msg->tidList) && (result == D_STORE_RESULT_OK); i++) { + /* Find the transaction list */ + tr_list_template.gid = tidlist[i].wgid; + tr_list_template.seqNum = tidlist[i].seqnr; + if ((tr_list = d_tableRemove(st->open_transactions, &tr_list_template)) == NULL) { + kvdebug (" no transaction found, skip\n"); + } else { + result = commit_writer_transaction (st, tr_list, reconstructing); + } + } /* for */ + return result; +} + +static d_storeResult unjournal_message_EOT (struct d_storeKV_s *st, os_uint64 commit_mid) +{ + /* TODO: drop all completed transaction entries in the list of open transactions. */ + + /* All transactions related to this EOT message have been + * handled, now delete the EOT message from the MESSAGE_EOT + * table to indicate that the message has been handled */ + + kv_key_t key; + + key.table = TABLE_MESSAGE_EOT; + key.gid = 0; + key.iid = 0; + key.mid = commit_mid; + /* delete the open transaction */ + if (kv_delete (st->kv, &key) < 0) { + kvlog (st, D_LEVEL_SEVERE, "Failed to delete message {%u:%u:%llu:%llu}\n", key.table, key.gid, key.iid, key.mid); + } + + return D_STORE_RESULT_OK; +} + + +d_storeResult d_storeTransactionCompleteKV (const d_store gstore, const v_groupAction msg) +{ + d_storeKV st; + d_storeResult result; + os_uint64 commit_mid; + + if (msg == NULL || msg->group == NULL || msg->message == NULL) { + return D_STORE_RESULT_ILL_PARAM; + } + + /* The message must have the L_ENDOFTRANSACTION flag */ + assert (v_nodeState (msg->message) & L_ENDOFTRANSACTION); + + LOCK_OPEN_STOREKV (st, gstore); + + if (kvlog_statistics && st->action_started) { + st->first_time = os_timeEGet(); + st->action_started = FALSE; + } + + if ((result = journal_message_EOT (st, (const struct v_messageEOT_s *)msg->message, &commit_mid)) != D_STORE_RESULT_OK) { + /* skip */ + } else if (commit_mid) { + if ((result = commit_group_transaction (st, (const struct v_messageEOT_s *)msg->message, 0)) != D_STORE_RESULT_OK) { + /* skip */ + } else if ((result = unjournal_message_EOT(st, commit_mid)) != D_STORE_RESULT_OK) { + /* skip */ + } + } + + if (kvlog_statistics) { + st->last_time = os_timeEGet(); + } + + UNLOCK_OPEN_STOREKV (st); + return result; +} + + + +/***************************************************************************** + * + * SNAPSHOT FUNCTIONS + * + *****************************************************************************/ + +static d_storeResult snapshot_copy_version(const d_storeKV st, kv_store_t snapshot) +{ + d_storeResult result = D_STORE_RESULT_OK; + const kv_key_t k = { TABLE_VERSION, 0, 0, 0 }; + kv_result_t rc; + os_uint32 sz; + void *buf; + + if ((rc = kv_get (st->kv, &k, &sz, &buf, 0)) >= 0) { + if (sz != 2 * sizeof (os_uint32)) { + kvlog (st, D_LEVEL_SEVERE, "snapshot: version from orig file corrupt\n"); + result = D_STORE_RESULT_MUTILATED; + } else { + rc = kv_put (snapshot, &k, sz, buf, 0); + if (rc >= 0) { + return D_STORE_RESULT_OK; + } else { + kvlog (st, D_LEVEL_SEVERE, "snapshot: write of version failed\n"); + return D_STORE_RESULT_ERROR; + } + } + os_free (buf); + } else { + kvlog (st, D_LEVEL_SEVERE, "snapshot: read of version failed\n"); + return D_STORE_RESULT_ERROR; + } + + return result; +} + +static d_storeResult snapshot_copy_topic_info(d_storeKV st, kv_store_t snapshot, unsigned topic_id, const char *topic_name) +{ + kv_result_t rc; + kv_key_t key; + void *blob; + os_uint32 sz; + + assert(snapshot); + + key.table = TABLE_TOPIC; + key.gid = topic_id; + key.iid = 0; + key.mid = 0; + + { + c_type type = NULL; + switch (st->encoding) { + case D_ENCODINGKV_XML_XML: + case D_ENCODINGKV_BIGE_XML: + case D_ENCODINGKV_BIGECDR_XML: + type = st->topic_type; + break; + case D_ENCODINGKV_BIGECDR_V1: + type = st->topicinfo_type; + break; + } + if ((rc = kv_get (st->kv, &key, &sz, &blob, type)) < 0) { + kvlog (st, D_LEVEL_SEVERE, "Retrieval of topic %u (%s) failed\n", topic_id, topic_name); + return kv_convert_result(rc); + } else if ((rc = kv_put (snapshot, &key, sz, blob, type)) < 0) { + os_free(blob); + kvlog (st, D_LEVEL_SEVERE, "Storage of topic %u (%s) failed\n", topic_id, topic_name); + return kv_convert_result(rc); + } + os_free(blob); + } + + switch (st->encoding) { + case D_ENCODINGKV_XML_XML: + case D_ENCODINGKV_BIGE_XML: + case D_ENCODINGKV_BIGECDR_XML: + key.table = TABLE_TOPIC_TYPE; + if ((rc = kv_get (st->kv, &key, &sz, &blob, c_string_t (st->base))) < 0) { + kvlog (st, D_LEVEL_SEVERE, "Retrieval of topic type %u (%s) failed\n", topic_id, topic_name); + return kv_convert_result(rc); + } else if ((rc = kv_put (snapshot, &key, sz, blob, c_string_t (st->base))) < 0) { + os_free(blob); + kvlog (st, D_LEVEL_SEVERE, "Storage of topic type %u (%s) failed\n", topic_id, topic_name); + return kv_convert_result(rc); + } + os_free(blob); + break; + case D_ENCODINGKV_BIGECDR_V1: + /* TABLE_TOPIC_TYPE eliminated in this encoding */ + break; + } + + kvlog (st, D_LEVEL_FINEST, "Snapshot copied info related to topic '%s'\n", topic_name); + + return D_STORE_RESULT_OK; +} + +static d_storeResult snapshot_copy_group_info(d_storeKV st, kv_store_t snapshot, const struct d_groupListKV_s *g) +{ + kv_result_t rc; + kv_key_t key; + void *blob; + os_uint32 sz; + + assert(snapshot); + + key.table = TABLE_GROUP; + key.gid = g->group_id; + key.iid = 0; + key.mid = 0; + + if ((rc = kv_get (st->kv, &key, &sz, &blob, st->group_type)) < 0) { + kvlog (st, D_LEVEL_SEVERE, "Retrieval of group %u (%s.%s) failed\n", g->group_id, g->_parent.partition, g->_parent.topic); + return kv_convert_result(rc); + } else if ((rc = kv_put (snapshot, &key, sz, blob, st->group_type)) < 0) { + os_free(blob); + kvlog (st, D_LEVEL_SEVERE, "Storage of group %u (%s.%s) failed\n", g->_parent.partition, g->_parent.topic); + return kv_convert_result(rc); + } + os_free(blob); + + kvlog (st, D_LEVEL_FINEST, "Snapshot copied info related to group '%s.%s'\n", g->_parent.partition, g->_parent.topic); + + return D_STORE_RESULT_OK; +} + +static d_storeResult snapshot_copy_message_info(d_storeKV st, kv_store_t snapshot, const struct d_groupListKV_s *g) +{ + d_storeResult result = D_STORE_RESULT_OK; + kv_result_t rc; + kv_key_t min, max; + kv_iter_t iter; + int hasdata; + + min.table = TABLE_MESSAGE; + min.gid = g->group_id; + min.iid = 0; + min.mid = 0; + max.table = TABLE_MESSAGE; + max.gid = g->group_id; + max.iid = ~(os_uint32)0; + max.mid = ~(os_uint64)0; + + kv_iter_new (st->kv, &iter, &min, &max, 0); + while (result == D_STORE_RESULT_OK && kv_iter_next (&hasdata, st->kv, iter) >= 0 && hasdata) { + kv_key_t k; + os_uint32 sz; + void *val; + + kv_iter_getkey (st->kv, iter, &k); + kvdebug (" %u:%u:%llu\n", k.gid, k.iid, k.mid); + + if (kv_iter_getvalue (st->kv, iter, &sz, &val) < 0) { + kvlog (st, D_LEVEL_SEVERE, "Message {%u:%u:%llu:%llu}: stored data is corrupt\n", (unsigned) k.table, k.gid, k.iid, k.mid); + result = D_STORE_RESULT_MUTILATED; + } else { + if ((rc = kv_put (snapshot, &k, sz, val, 0)) < 0) { + kvlog (st, D_LEVEL_SEVERE, "Message {%u:%u:%llu:%llu} could not be written to disk\n", (unsigned) k.table, k.gid, k.iid, k.mid); + result = kv_convert_result(rc); + } + os_free (val); + } + } + kvdebug (" done\n"); + kv_iter_free (st->kv, iter); + + if (result == D_STORE_RESULT_OK) { + kvlog (st, D_LEVEL_FINEST, "Snapshot copied info messages of group '%s.%s'\n", g->_parent.partition, g->_parent.topic); + } + + return result; +} + +static d_storeResult snapshot_copy_transaction_journal(d_storeKV st, kv_store_t snapshot) +{ + d_storeResult result = D_STORE_RESULT_OK; + kv_result_t rc; + kv_key_t min, max; + kv_iter_t iter; + int hasdata; + + min.table = TABLE_MESSAGE_EOT; + min.gid = 0; + min.iid = 0; + min.mid = 0; + max.table = TABLE_MESSAGE_EOT; + max.gid = ~(os_uint32)0; + max.iid = ~(os_uint32)0; + max.mid = ~(os_uint64)0; + + kv_iter_new (st->kv, &iter, &min, &max, st->open_transaction_eot_type); + while (result == D_STORE_RESULT_OK && kv_iter_next (&hasdata, st->kv, iter) >= 0 && hasdata) { + kv_key_t k; + os_uint32 sz; + void *val; + + kv_iter_getkey (st->kv, iter, &k); + kvdebug (" %u:%u:%llu\n", k.gid, k.iid, k.mid); + + if (kv_iter_getvalue (st->kv, iter, &sz, &val) < 0) { + kvlog (st, D_LEVEL_SEVERE, "Journal message {%u:%u:%llu:%llu}: stored data is corrupt\n", (unsigned) k.table, k.gid, k.iid, k.mid); + result = D_STORE_RESULT_MUTILATED; + } else { + if ((rc = kv_put (snapshot, &k, sz, val, st->open_transaction_eot_type)) < 0) { + kvlog (st, D_LEVEL_SEVERE, "journal message {%u:%u:%llu:%llu} could not be written to disk\n", (unsigned) k.table, k.gid, k.iid, k.mid); + result = kv_convert_result(rc); + } + os_free (val); + } + } + kvdebug (" done\n"); + kv_iter_free (st->kv, iter); + + if (result == D_STORE_RESULT_OK) { + kvlog (st, D_LEVEL_FINEST, "Snapshot copied journal messages\n"); + } + + return result; +} + + + +struct namespace_action_arg { + d_storeKV st; + kv_store_t snapshot; + d_storeResult result; +}; + +static void snapshot_namespace_action(struct namespace *ns, struct namespace_action_arg *arg) +{ + d_storeResult result = arg->result; + kv_result_t rc; + kv_key_t key; + os_uint32 sz; + void *blob = NULL; + + assert(ns); + assert(ns->name); + + /* copy from NAMESPACE TABLE the corresponding namespace */ + if (result == D_STORE_RESULT_OK) { + key.table = TABLE_NAMESPACE; + key.gid = ns->id; + key.iid = ns->version; + key.mid = 0; + + if ((rc = kv_get (arg->st->kv, &key, &sz, &blob, arg->st->namespace_type)) < 0) { + kvlog (arg->st, D_LEVEL_SEVERE, "Retrieval of namespace %u (%s) failed\n", ns->id, ns->name); + result = D_STORE_RESULT_MUTILATED; + } else if ((rc = kv_put (arg->snapshot, &key, sz, blob, arg->st->namespace_type)) < 0) { + kvlog (arg->st, D_LEVEL_SEVERE, "Storage of namespace %u (%s) failed\n", ns->id, ns->name); + result = kv_convert_result(rc); + } + os_free(blob); + } + + /* copy from NAMESPACE_QUALITY TABLE the corresponding quality */ + if (result == D_STORE_RESULT_OK) { + key.table = TABLE_NAMESPACE_QUALITY; + key.gid = ns->id; + key.iid = ns->version; + key.mid = 0; + blob = NULL; + + if ((rc = kv_get (arg->st->kv, &key, &sz, &blob, arg->st->namespace_quality_type)) < 0) { + kvlog (arg->st, D_LEVEL_SEVERE, "Retrieval of namespace quality %u (%s) failed\n", ns->id, ns->name); + result = D_STORE_RESULT_MUTILATED; + } else if ((rc = kv_put (arg->snapshot, &key, sz, blob, arg->st->namespace_quality_type)) < 0) { + kvlog (arg->st, D_LEVEL_SEVERE, "Storage of namespace quality %u (%s) failed\n", ns->id, ns->name); + result = kv_convert_result(rc); + } + os_free(blob); + } + + /* copy from NAMESPACE_COMPLETENESS TABLE the corresponding completeness */ + if (result == D_STORE_RESULT_OK) { + key.table = TABLE_NAMESPACE_COMPLETENESS; + key.gid = ns->id; + key.iid = ns->version; + key.mid = 0; + blob = NULL; + + if ((rc = kv_get (arg->st->kv, &key, &sz, &blob, arg->st->namespace_completeness_type)) < 0) { + kvlog (arg->st, D_LEVEL_SEVERE, "Retrieval of namespace completeness %u (%s) failed\n", ns->id, ns->name); + result = D_STORE_RESULT_MUTILATED; + } else if ((rc = kv_put (arg->snapshot, &key, sz, blob, arg->st->namespace_completeness_type)) < 0) { + kvlog (arg->st, D_LEVEL_SEVERE, "Storage of namespace completeness %u (%s) failed\n", ns->id, ns->name); + result = kv_convert_result(rc); + } + os_free(blob); + } + + if (arg->result == D_STORE_RESULT_OK) { + kvlog (arg->st, D_LEVEL_FINEST, "Snapshot copied namespace '%s'\n", ns->name); + } + + arg->result = result; +} + + + +d_storeResult d_storeCreatePersistentSnapshotKV (const d_store gstore, const c_char *partitionExpr, const c_char *topicExpr, const c_char *uri) +{ + d_storeResult result = D_STORE_RESULT_OK; + d_storeKV st; + kv_store_t snapshot = NULL; + c_char *resultDir = NULL; + struct idtable *pth = NULL; + struct hashtable *nh = NULL; + + LOCK_OPEN_STOREKV (st, gstore); + + assert(gstore); + assert(topicExpr); + assert(partitionExpr); + assert(uri); + assert(d_objectIsValid(d_object(gstore), D_STORE)); + assert(gstore->type == D_STORE_TYPE_KV); + + if (strcmp(st->diskStorePath, uri) == 0) { + kvlog (st, D_LEVEL_SEVERE, "snapshot: cannot create snapshot in current store directory %s\n", uri); + result = D_STORE_RESULT_PRECONDITION_NOT_MET; + } else if ((resultDir = d_storeDirNew (gstore, uri)) == NULL) { + kvlog (st, D_LEVEL_SEVERE, "snapshot: directory '%s' could not be created.\n", uri); + result = D_STORE_RESULT_PRECONDITION_NOT_MET; + } else if ((pth = idtable_new ()) == NULL) { + kvlog (st, D_LEVEL_SEVERE, "create-snapshot: allocation failed.\n"); + result = D_STORE_RESULT_OUT_OF_RESOURCES; + } else if ((nh = hashtable_new ((hashtable_key_func_t)get_namespace_key, (hashtable_cmp_func_t)compare_namespace_by_name)) == NULL) { + kvlog (st, D_LEVEL_SEVERE, "snapshot: allocation failed.\n"); + result = D_STORE_RESULT_OUT_OF_RESOURCES; + } else { + + assert(st->kv); + + if ((snapshot = kv_open(st, uri, st->kv->kind, NULL)) == NULL) { + kvlog (st, D_LEVEL_SEVERE, "snapshot: store '%s' could not be created.\n", uri); + result = D_STORE_RESULT_ERROR; + } else { + result = snapshot_copy_version(st, snapshot); + } + } + + if (result == D_STORE_RESULT_OK) { + const struct d_groupListKV_s *g; + + /* walk group list */ + for (g = st->groups; g != NULL; g = g->_parent.next) { + struct namespace *ns; + + /* check if group references namespace with highest version */ + assert(g->namespace); + ns = find_namespace_by_id (st, g->namespace->id); + if (ns != g->namespace) { + continue; + } + + /* check if group matches partition and topic expression */ + if (!d_patternMatch(g->_parent.partition, (c_string)partitionExpr) || + !d_patternMatch(g->_parent.topic, (c_string)topicExpr)) { + continue; + } + + /* check if topic information is present in snapshot */ + if (idtable_get(pth, g->topic_id) != g->topic_id) { + if ((result = snapshot_copy_topic_info (st, snapshot, g->topic_id, g->_parent.topic)) != D_STORE_RESULT_OK) { + break; + } + idtable_put(pth, g->topic_id); + } + + /* copy from GROUP TABLE the corresponding group */ + if ((result = snapshot_copy_group_info (st, snapshot, g)) != D_STORE_RESULT_OK) { + break; + } + + /* copy from MESSAGE TABLE all corresponding messages */ + if ((result = snapshot_copy_message_info (st, snapshot, g)) != D_STORE_RESULT_OK) { + break; + } + + hashtable_put(nh, ns); + } /* for */ + + } + + if (result == D_STORE_RESULT_OK) { + struct namespace_action_arg argument; + + argument.result = D_STORE_RESULT_OK; + argument.st = st; + argument.snapshot = snapshot; + + /* walk list of namespaces to be copied to snapshot */ + hashtable_walk (nh, (hashtable_action_func_t)snapshot_namespace_action, &argument); + + result = argument.result; + } + + if (result == D_STORE_RESULT_OK) { + /* Copy transaction journal messages */ + result = snapshot_copy_transaction_journal(st, snapshot); + } + + if (snapshot) { + kv_close (snapshot); + } + + idtable_free (pth); + hashtable_free (nh); + os_free (resultDir); + + if (result == D_STORE_RESULT_OK) { + kvlog (st, D_LEVEL_FINE, "Created snapshot for expression '%s.%s' in '%s'\n", partitionExpr, topicExpr, uri); + } + + UNLOCK_OPEN_STOREKV (st); + + return result; +} + + +/***************************************************************************** + * + * LOAD FUNCTIONS + * + *****************************************************************************/ + +struct hash_helper_arg { + v_group group; + c_iter list; +}; + +static c_bool create_hash_helper (const struct inst *inst, c_iter list) +{ + struct msg *m; + + assert(inst); + assert(list); + + for (m = inst->oldest; m; m = m->newer) { + struct v_groupFlushData *flushData = os_malloc(sizeof(struct v_groupFlushData)); + assert (m->v_msg != NULL); + + flushData->object = c_keep(m->v_msg); + flushData->instance = NULL; + flushData->flushType = V_GROUP_FLUSH_MESSAGE; + list = c_iterAppend(list, flushData); + } + return TRUE; +} + +static void free_hash_helper (void *o, c_iterActionArg arg) +{ + struct v_groupFlushData *flushData = (struct v_groupFlushData *)o; + + OS_UNUSED_ARG(arg); + + if (flushData) { + c_free(flushData->object); + c_free(flushData->instance); + os_free(flushData); + } +} + +static d_storeResult calculate_hash (struct d_storeKV_s *st, const struct d_groupListKV_s *g, struct d_groupHash *groupHash) +{ + c_iter list; + + OS_UNUSED_ARG(st); + + list = c_iterNew(NULL); + (void)d_tableWalk (g->instances, create_hash_helper, list); + d_groupHashCalculate(groupHash, list); + c_iterWalk(list, free_hash_helper, NULL); + c_iterFree(list); + + return D_STORE_RESULT_OK; +} + +static d_groupListKV find_older_group_version (const d_groupListKV g) +{ + d_groupListKV entry; + + for (entry = g->_parent.next; entry; entry = entry->_parent.next) { + if ((strcmp(g->_parent.topic, entry->_parent.topic) == 0) && + (strcmp(g->_parent.partition, entry->_parent.partition) == 0)) { + if (g->namespace->version > entry->namespace->version) { + return entry; + } + } + } + + return NULL; +} + +d_storeResult d_storeMessagesLoadKV (const d_store gstore, const d_group dgroup, struct d_groupHash *groupHash) +{ + d_storeKV st; + d_storeResult result = D_STORE_RESULT_OK; + c_char *topicName; + c_char *partitionName; + v_group group; + os_uint32 topic_id; + d_groupListKV g, g0; + + assert(groupHash); + + if (gstore == NULL || dgroup == NULL) { + return D_STORE_RESULT_ILL_PARAM; + } + + LOCK_OPEN_STOREKV (st, gstore); + + group = d_groupGetKernelGroup (dgroup); + topicName = v_topicName (v_groupTopic (group)); + partitionName = v_partitionName (v_groupPartition (group)); + kvlog (st, D_LEVEL_FINE, "load messages for group '%s.%s'\n", partitionName, topicName); + + /* We need the topic_id, and the easiest way to find that is to + * enumerate the in-memory representation of the groups. Those get + * initialised from the disk as soon as the store is opened, and + * so if we can't find it there, it doesn't exist on disk. */ + if ((g = find_group (st, partitionName, topicName)) == NULL) { + kvlog (st, D_LEVEL_WARNING, "load messages: group '%s.%s' unknown (guaranteed no data)\n", partitionName, topicName); + memset(groupHash, 0, sizeof(struct d_groupHash)); + result = D_STORE_RESULT_OK; + goto out; + } + + if ((g0 = find_older_group_version(g)) == NULL) { + kvlog (st, D_LEVEL_WARNING, "load messages: group '%s.%s' is new (guaranteed no data)\n", partitionName, topicName); + memset(groupHash, 0, sizeof(struct d_groupHash)); + result = D_STORE_RESULT_OK; + goto out; + } + topic_id = g0->topic_id; + kvdebug (" topic_id = %u\n", topic_id); + + /* If we know of the group, we must still verify that the topic + * definitions in the kernel and on-disk match: there is no + * guarantee some other process hasn't already defined the topic + * in an incompatible way. */ + if (!topic_definition_matches (st, group, topic_id, topicName)) { + kvlog (st, D_LEVEL_WARNING, "load messages: topic '%s' definitions do not match, not injecting\n", topicName); + result = D_STORE_RESULT_METADATA_MISMATCH; + goto out; + } + kvdebug (" topic definitions match\n"); + + /* Store the kernel group in the d_groupListKV. This makes lookup + * of the kernel group very easy. */ + g0->vgroup = group; + + /* Reconstruct the instances for the older group in-memory */ + reconstruct_instances (st, g0, group); + + /* Once we have everything in-memory calculate hash */ + calculate_hash (st, g0, groupHash); + + kvdebug (" done\n"); +out: + UNLOCK_OPEN_STOREKV (st); + return result; +} + +static c_bool free_messages_helper (const struct inst *inst, c_voidp userData) +{ + struct msg *m; + + OS_UNUSED_ARG(userData); + + for (m = inst->oldest; m; m = m->newer) { + assert (m->v_msg != NULL); + c_free (m->v_msg); + m->v_msg = NULL; + } + return TRUE; +} + +d_storeResult d_storeMessagesLoadFlushKV (const d_store gstore, const d_group dgroup, c_bool inject) +{ + d_storeKV st; + d_storeResult result = D_STORE_RESULT_OK; + c_char *topicName; + c_char *partitionName; + v_group group; + d_groupListKV g, g0; + + if (gstore == NULL || dgroup == NULL) { + return D_STORE_RESULT_ILL_PARAM; + } + + LOCK_OPEN_STOREKV (st, gstore); + group = d_groupGetKernelGroup (dgroup); + topicName = v_topicName (v_groupTopic (group)); + partitionName = v_partitionName (v_groupPartition (group)); + + if ((g = find_group (st, partitionName, topicName)) == NULL) { + kvlog (st, D_LEVEL_WARNING, "load-flush messages: group '%s.%s' unknown (guaranteed no data)\n", partitionName, topicName); + result = D_STORE_RESULT_OK; + goto out; + } + + if ((g0 = find_older_group_version(g)) == NULL) { + kvlog (st, D_LEVEL_WARNING, "load-flush messages: group '%s.%s' is new (guaranteed no data)\n", partitionName, topicName); + result = D_STORE_RESULT_OK; + goto out; + } + + if (inject == TRUE) { + /* Inject the older in-memory reconstructed instances into + * the current group and store them in the active store. */ + result = inject_messages (st, g0, group, TRUE); + } else { + (void)d_tableWalk (g->instances, free_messages_helper, NULL); + result = D_STORE_RESULT_OK; + } + +out: + UNLOCK_OPEN_STOREKV (st); + return result; +} diff --git a/src/services/durability/code/d_storeXML.c b/src/services/durability/code/d_storeXML.c new file mode 100644 index 000000000..f6ddaa822 --- /dev/null +++ b/src/services/durability/code/d_storeXML.c @@ -0,0 +1,5312 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#include "vortex_os.h" +#include "d__misc.h" +#include "d__storeXML.h" +#include "d__lock.h" +#include "d__configuration.h" +#include "d__admin.h" +#include "d__nameSpace.h" +#include "d__table.h" +#include "d_storeXML.h" +#include "d_store.h" +#include "d_object.h" +#include "d__pQos.h" +#include "d__thread.h" +#include "u_user.h" +#include "u_group.h" +#include "u_observable.h" +#include "u_entity.h" +#include "u_partition.h" +#include "u_topic.h" +#include "v_public.h" +#include "v_entity.h" +#include "v_time.h" +#include "v_topicQos.h" +#include "v_topic.h" +#include "v_message.h" +#include "v_partition.h" +#include "v_state.h" +#include "sd_serializer.h" +#include "sd_serializerXML.h" +#include "sd_serializerXMLMetadata.h" +#include "sd_serializerXMLTypeinfo.h" +#include "v_messageExt.h" +#include "c_base.h" +#include "c_laptime.h" +#include "os_heap.h" +#include "os_time.h" +#include "os_stdlib.h" +#include "os_report.h" + +#include + +#ifdef WIN32 +#define D_SEEK_LENGTH (-10) +#else +#define D_SEEK_LENGTH (-9) +#endif + +C_CLASS(d_topicMetadata); + +C_STRUCT(d_topicMetadata) { + c_char* name; + c_char* typeName; + c_char* keyList; + v_topicQos qos; + c_type type; +}; + +#define RESULT_IGNORE(x) if ((x) == 0) { ; } + +#define d_topicMetadata(t) ((d_topicMetadata)(t)) + +C_CLASS(persistentInstance); + +C_STRUCT(persistentInstance) { + c_char* keyValue; + v_groupAction newMessage; + c_iter messages; /* v_message */ + d_storeResult result; + c_long writeCount; + c_long disposeCount; + c_long registerCount; + c_long unregisterCount; +}; + +C_CLASS(groupExpungeActions); + +C_STRUCT(groupExpungeActions){ + c_char* partition; + c_char* topic; + d_table instances; /**/ +}; + +#define groupExpungeActions(i) ((groupExpungeActions)(i)) +#define persistentInstance(i) ((persistentInstance)(i)) + +static d_storeResult +groupsReadXMLUnsafe( + const d_store store, + d_groupList *list); + +static c_char* +getDataFileNameBasedOnPath( + const c_char* storeDir, + const c_char* partition, + const c_char* topic); + +static c_char* +getBakFileNameBasedOnPath( + const c_char* storeDir, + const c_char* partition, + const c_char* topic); + +static c_char* +getMetaFileNameBasedOnPath( + const c_char* storeDir, + const c_char* partition, + const c_char* topic); + +static d_storeResult +d_storeNsMarkCompleteXMLBasedOnPath( + const c_char* storeDir, + const d_nameSpace nameSpace, + c_bool isComplete); + +static d_storeResult +getDataVersion( + const d_storeXML persistentStore, + const c_char* partition, + const c_char* topic, + c_ulong* version); + +static d_storeFile +d_storeFileNew( + const c_char* path, + FILE* fdes, + const c_char* mode) +{ + d_storeFile f; + + assert(path); + + f = d_storeFile(os_malloc(C_SIZEOF(d_storeFile))); + f->path = os_strdup(path); + + if(fdes){ + f->fdes = fdes; + } else { + f->fdes = NULL; + } + if(mode){ + f->mode = os_strdup(mode); + } else { + f->mode = NULL; + } + + return f; +} + +static void +d_storeFileFree( + d_storeFile f) +{ + if(f){ + if(f->path){ + os_free(f->path); + } + if(f->mode){ + os_free(f->mode); + } + if(f->fdes){ + fclose(f->fdes); + } + os_free(f); + } + return; +} + +static int +d_storeFileCompare( + d_storeFile f1, + d_storeFile f2) +{ + int result; + + if(f1 && f2){ + if(f1->path && f2->path){ + result = strcmp(f1->path, f2->path); + } else if(f1->path){ + result = 1; + } else if(f2->path){ + result = -1; + } else { + result = 0; + } + } else if(f1){ + result = 1; + } else if(f2){ + result = -1; + } else { + result = 0; + } + return result; +} + +static d_storeResult +actionStopUnlocked( + d_storeXML store) +{ + d_storeXML(store)->sessionAlive = FALSE; + d_tableFree(store->openedFiles); + store->openedFiles = NULL; + return D_STORE_RESULT_OK; +} + +static c_bool +isDeprecatedMetadataFormat( + c_char* meta) +{ + c_bool result; + + if(meta && strlen(meta) > 26){ + if(os_strncasecmp(meta, "", 26) == 0){ + result = FALSE; + } else { + result = TRUE; + } + } else { + result = TRUE; + } + return result; +} + + +static void +setKernelGroup( + v_public entity, + c_voidp args) +{ + d_group group; + + group = d_group(args); + d_groupSetKernelGroup(group,v_group(entity)); +} + + +static c_char* +stringKeyEscape( + const c_char* str, + c_bool escapeComma) +{ + os_size_t i, length, index, allocLength; + c_char c; + c_char* result = NULL; + + if(str){ + length = strlen(str); + allocLength = length; + result = (c_char*)(os_malloc(length + 1)); + index = 0; + + for(i=0; i= allocLength){ + allocLength += length; + result = os_realloc(result, allocLength + 1); + } + if(result == NULL){ + break; + } + c = str[i]; + + switch(c){ + case '\n': + result[index++] = '%'; + result[index++] = '0'; + result[index++] = '1'; + result[index++] = '0'; + break; + case '%': + result[index++] = '%'; + result[index++] = '0'; + result[index++] = '3'; + result[index++] = '7'; + break; + case '&': + result[index++] = '%'; + result[index++] = '0'; + result[index++] = '3'; + result[index++] = '8'; + break; + case ',': + if(escapeComma){ + result[index++] = '%'; + result[index++] = '0'; + result[index++] = '4'; + result[index++] = '4'; + } else { + result[index++] = c; + } + break; + case '<': + result[index++] = '%'; + result[index++] = '0'; + result[index++] = '6'; + result[index++] = '0'; + break; + case '>': + result[index++] = '%'; + result[index++] = '0'; + result[index++] = '6'; + result[index++] = '2'; + break; + default: + result[index++] = c; + break; + } + } + if(result){ + result[index++] = '\0'; + } + } + return result; +} + +#if 0 +static c_char* +stringKeyUnescape( + const c_char* escaped) +{ + int i, length, index, code; + c_char c; + c_char *tmp; + c_char *str = NULL; + c_char codeString[4]; + + if(escaped){ + length = (int)strlen(escaped); + index = 0; + + tmp = os_malloc(length+1); + + for(i=0; i 63 ? + 64 @ 65 A 66 B 67 C 68 D 69 E 70 F 71 G + 72 H 73 I 74 J 75 K 76 L 77 M 78 N 79 O + 80 P 81 Q 82 R 83 S 84 T 85 U 86 V 87 W + 88 X 89 Y 90 Z 91 [ 92 \ 93 ] 94 ^ 95 _ + 96 ` 97 a 98 b 99 c 100 d 101 e 102 f 103 g + 104 h 105 i 106 j 107 k 108 l 109 m 110 n 111 o + 112 p 113 q 114 r 115 s 116 t 117 u 118 v 119 w + 120 x 121 y 122 z 123 { 124 | 125 } 126 ~ 127 DEL + +*****************************************************************************/ + +static c_char* +stringToURI( + const c_char* str) +{ + int i, length, index; + c_char c; + c_char tmp[512]; + c_char* uri = NULL; + + if(str){ + length = (int)strlen(str); + index = 0; + + for(i=0; i': + tmp[index++] = '%'; + tmp[index++] = '0'; + tmp[index++] = '6'; + tmp[index++] = '2'; + break; + case '@': + tmp[index++] = '%'; + tmp[index++] = '0'; + tmp[index++] = '6'; + tmp[index++] = '4'; + break; + case '[': + tmp[index++] = '%'; + tmp[index++] = '0'; + tmp[index++] = '9'; + tmp[index++] = '1'; + break; + case '\\': + tmp[index++] = '%'; + tmp[index++] = '0'; + tmp[index++] = '9'; + tmp[index++] = '2'; + break; + case ']': + tmp[index++] = '%'; + tmp[index++] = '0'; + tmp[index++] = '9'; + tmp[index++] = '3'; + break; + case '^': + tmp[index++] = '%'; + tmp[index++] = '0'; + tmp[index++] = '9'; + tmp[index++] = '4'; + break; + case '`': + tmp[index++] = '%'; + tmp[index++] = '0'; + tmp[index++] = '9'; + tmp[index++] = '6'; + break; + case '{': + tmp[index++] = '%'; + tmp[index++] = '1'; + tmp[index++] = '2'; + tmp[index++] = '3'; + break; + case '|': + tmp[index++] = '%'; + tmp[index++] = '1'; + tmp[index++] = '2'; + tmp[index++] = '4'; + break; + case '}': + tmp[index++] = '%'; + tmp[index++] = '1'; + tmp[index++] = '2'; + tmp[index++] = '5'; + break; + case '~': + tmp[index++] = '%'; + tmp[index++] = '1'; + tmp[index++] = '2'; + tmp[index++] = '6'; + break; + default: + tmp[index++] = c; + break; + } + } + tmp[index++] = '\0'; + uri = (c_char*)(os_malloc(strlen(tmp) + 1)); + os_sprintf(uri, "%s", tmp); + } + return uri; +} + +static c_char* +URIToString( + const c_char* uri) +{ + size_t i, length, index; + int code; + c_char c; + c_char *tmp; + c_char *str = NULL; + c_char codeString[4]; + + if(uri){ + length = strlen(uri); + index = 0; + + tmp = os_malloc(length+1); + + for(i=0; i 0){ + data[slen-1] = '\0'; + } + return; +} + +static void +readObject( + FILE* fdes, + size_t szlen, + c_char* data) +{ + int slen, len; + c_char* buf; + + assert(data); + assert(fdes); + assert(szlen <= OS_MAX_INTEGER(int)); + len = (int) szlen; + + do { + data[0] = '\0'; + RESULT_IGNORE(fgets(data, len, fdes)); + slen = (int) strlen(data); + } while ((slen > 0) && ((slen < 8) || (strncmp(data, "", 8) != 0))); + + if (slen > 0){ + buf = data; + + while ((slen > 0) && ((slen < 10) || (strncmp(&(buf[slen-10]), "\n", 10) != 0))) { + buf += slen; + if (fgets(buf, len, fdes) != NULL) { + slen = (int) strlen(buf); + } else { + slen = 0; + } + } + if ((slen >= 10) && (strncmp(&(buf[slen-10]), "\n", 10) == 0)) { + buf[slen-1] = '\0'; + } else { + data[0] = '\0'; + } + } + + return; +} + +static c_char* +getSubString( + const c_char* str, + os_ssize_t startIndexS, + os_ssize_t endIndexS) +{ + c_char* result; + c_char *tmp; + + result = NULL; + + if(str){ + if((startIndexS >= 0) && (endIndexS >= startIndexS)){ + size_t startIndex = (size_t) startIndexS; + size_t endIndex = (size_t) endIndexS; + if(strlen(str) >= endIndex){ + result = os_malloc(endIndex - startIndex + 1); + tmp = (c_char*)(str + startIndex); + os_strncpy(result, tmp, endIndex-startIndex); + result[(endIndex-startIndex)] = '\0'; + } + } + } + return result; +} + +static c_char* +getDirectoryNameForStoreDir( + const c_char* storeDir, + const c_char* partition) +{ + c_char* directoryName; + c_char* partitionURI; + const c_char* filesep; + + assert(storeDir); + assert(partition); + + directoryName = NULL; + if(strlen(partition) == 0) + { + directoryName = (c_char*)(os_malloc(strlen(storeDir) + 1)); + os_sprintf(directoryName, "%s", storeDir); + } else + { + filesep = os_fileSep(); + partitionURI = stringToURI(partition); + directoryName = (c_char*)(os_malloc(strlen(storeDir) + 1 + strlen(partitionURI) + 1)); + os_sprintf(directoryName, "%s%s%s", storeDir, filesep, partitionURI); + os_free(partitionURI); + } + return directoryName; +} + +static c_bool +createDirectoryIfNecessaryForStoreDir( + const c_char* storeDir, + const c_char* partition) +{ + c_bool result; + c_char *dirName; + os_result status; + struct os_stat_s statBuf; + + if(storeDir) + { + dirName = getDirectoryNameForStoreDir(storeDir, partition); + } else + { + dirName = NULL; + } + status = os_stat(dirName, &statBuf); + + if (status != os_resultSuccess) { + status = os_mkdir(dirName, S_IRWXU | S_IRWXG | S_IRWXO) == 0 ? os_resultSuccess:os_resultFail; + } + os_free(dirName); + + if(status == os_resultSuccess){ + result = TRUE; + } else { + result = FALSE; + } + return result; +} + +static c_bool +createDirectoryIfNecessary( + const d_storeXML store, + const c_char* partition) +{ + c_bool result; + c_char *storeDir; + + if(store) + { + storeDir = d_store(store)->config->persistentStoreDirectory; + } else + { + storeDir = NULL; + } + result = createDirectoryIfNecessaryForStoreDir(storeDir, partition); + return result; +} + +static c_char* +getDataFileName( + const d_storeXML store, + const c_char* partition, + const c_char* topic) +{ + c_char* fileName = NULL; + c_char* storeDir; + + assert(partition); + assert(topic); + assert(store); + + if(store) + { + storeDir = d_store(store)->config->persistentStoreDirectory; + fileName = getDataFileNameBasedOnPath(storeDir, partition, topic); + } + + return fileName; +} + +c_char* +getDataFileNameBasedOnPath( + const c_char* storeDir, + const c_char* partition, + const c_char* topic) +{ + c_char* fileName = NULL; + c_char* partitionURI; + c_char* topicURI; + const c_char* filesep; + + assert(partition); + assert(topic); + assert(storeDir); + + filesep = os_fileSep(); + topicURI = stringToURI(topic); + if(strlen(partition) == 0) + { + fileName = (c_char*)(os_malloc(strlen(storeDir) + 1 + strlen(topicURI) + 5)); + if(fileName) + { + os_sprintf(fileName, "%s%s%s.xml", storeDir, filesep, topicURI); + } + } else + { + partitionURI = stringToURI(partition); + if(partitionURI) + { + fileName = (c_char*)(os_malloc(strlen(storeDir) + 1 + strlen(partitionURI) + 1 + strlen(topicURI) + 5)); + if(fileName) + { + os_sprintf(fileName, "%s%s%s%s%s.xml", storeDir, filesep, partitionURI, filesep, topicURI); + } + os_free(partitionURI); + } + } + os_free(topicURI); + return fileName; +} + +static c_char* +getOptimizeFileName( + const d_storeXML store, + const c_char* partition, + const c_char* topic) +{ + c_char* fileName; + c_char* storeDir; + c_char* partitionURI; + c_char* topicURI; + const c_char* filesep; + + assert(partition); + assert(topic); + assert(store); + + fileName = NULL; + + if(store && topic && partition){ + filesep = os_fileSep(); + storeDir = d_store(store)->config->persistentStoreDirectory; + + topicURI = stringToURI(topic); + if(strlen(partition) == 0){ + fileName = (c_char*)(os_malloc(strlen(storeDir) + 1 + strlen(topicURI) + 14)); + + if(fileName){ + os_sprintf(fileName, "%s%s%s_optimize.txt", storeDir, filesep, topicURI); + } + } else { + partitionURI = stringToURI(partition); + + if(partitionURI){ + fileName = (c_char*)(os_malloc(strlen(storeDir) + 1 + strlen(partitionURI) + 1 + strlen(topicURI) + 14)); + + if(fileName){ + os_sprintf(fileName, "%s%s%s%s%s_optimize.txt", storeDir, filesep, partitionURI, filesep, topicURI); + } + os_free(partitionURI); + } + } + os_free(topicURI); + } + return fileName; +} + +static c_char* +getTmpFileName( + const d_storeXML store, + const c_char* partition, + const c_char* topic) +{ + c_char* fileName; + c_char* storeDir; + c_char* partitionURI; + c_char* topicURI; + const c_char* filesep; + + assert(partition); + assert(topic); + assert(store); + + fileName = NULL; + + if(store){ + filesep = os_fileSep(); + storeDir = d_store(store)->config->persistentStoreDirectory; + + topicURI = stringToURI(topic); + if(strlen(partition) == 0){ + fileName = (c_char*)(os_malloc(strlen(storeDir) + 1 + strlen(topicURI) + 5)); + os_sprintf(fileName, "%s%s%s.tmp", storeDir, filesep, topicURI); + } else { + partitionURI = stringToURI(partition); + fileName = (c_char*)(os_malloc(strlen(storeDir) + 1 + strlen(partitionURI) + 1 + strlen(topicURI) + 5)); + os_sprintf(fileName, "%s%s%s%s%s.tmp", storeDir, filesep, partitionURI, filesep, topicURI); + os_free(partitionURI); + } + os_free(topicURI); + } + return fileName; +} + +static c_char* +getBakFileName( + const d_storeXML store, + const c_char* partition, + const c_char* topic) +{ + c_char* fileName = NULL; + c_char* storeDir; + + assert(partition); + assert(topic); + assert(store); + + if(store) + { + storeDir = d_store(store)->config->persistentStoreDirectory; + fileName = getBakFileNameBasedOnPath(storeDir, partition, topic); + } + + return fileName; +} + +c_char* +getBakFileNameBasedOnPath( + const c_char* storeDir, + const c_char* partition, + const c_char* topic) +{ + c_char* fileName; + c_char* partitionURI; + c_char* topicURI; + const c_char* filesep; + + assert(partition); + assert(topic); + assert(storeDir); + + fileName = NULL; + + if(storeDir) + { + filesep = os_fileSep(); + + topicURI = stringToURI(topic); + if(strlen(partition) == 0){ + fileName = (c_char*)(os_malloc(strlen(storeDir) + 1 + strlen(topicURI) + 5)); + os_sprintf(fileName, "%s%s%s.bak", storeDir, filesep, topicURI); + } else { + partitionURI = stringToURI(partition); + fileName = (c_char*)(os_malloc(strlen(storeDir) + 1 + strlen(partitionURI) + 1 + strlen(topicURI) + 5)); + os_sprintf(fileName, "%s%s%s%s%s.bak", storeDir, filesep, partitionURI, filesep, topicURI); + os_free(partitionURI); + } + os_free(topicURI); + } + return fileName; +} + +static c_char* +getMetaFileName( + const d_storeXML store, + const c_char* partition, + const c_char* topic) +{ + c_char* fileName = NULL; + c_char* storeDir; + + assert(partition); + assert(topic); + assert(store); + + if(store) + { + storeDir = d_store(store)->config->persistentStoreDirectory; + fileName = getMetaFileNameBasedOnPath(storeDir, partition, topic); + } + + return fileName; +} + +c_char* +getMetaFileNameBasedOnPath( + const c_char* storeDir, + const c_char* partition, + const c_char* topic) +{ + c_char* fileName; + c_char* partitionURI; + c_char* topicURI; + const c_char* filesep; + + assert(partition); + assert(topic); + assert(storeDir); + + fileName = NULL; + + if(storeDir){ + filesep = os_fileSep(); + + topicURI = stringToURI(topic); + if(strlen(partition) == 0){ + fileName = (c_char*)(os_malloc(strlen(storeDir) + 1 + strlen(topicURI) + 10)); + os_sprintf(fileName, "%s%s%s_meta.xml", storeDir, filesep, topicURI); + } else { + partitionURI = stringToURI(partition); + fileName = (c_char*)(os_malloc(strlen(storeDir) + 1 + strlen(partitionURI) + 1 + strlen(topicURI) + 10)); + os_sprintf(fileName, "%s%s%s%s%s_meta.xml", storeDir, filesep, partitionURI, filesep, topicURI); + os_free(partitionURI); + } + os_free(topicURI); + + } + return fileName; +} + + +static c_char * +getMessageMetadata( + const c_type type ) +{ + c_char * str; + c_type metaType; + sd_serializer serializer; + sd_serializedData serData; + c_property userDataAttr; + + metaType = c_getType(type); + userDataAttr = c_property(c_metaResolve(c_metaObject(type), "userData")); + serializer = sd_serializerXMLTypeinfoNew(c_getBase(metaType), FALSE); + serData = sd_serializerSerialize(serializer, userDataAttr->type); + str = sd_serializerToString(serializer, serData); + sd_serializedDataFree(serData); + sd_serializerFree(serializer); + c_free(userDataAttr); + return(str); +} + +static c_char * +getMessageMetadataDeprecated( + const c_type type ) +{ + c_char * str; + c_type metaType; + sd_serializer serializer; + sd_serializedData serData; + c_property userDataAttr; + + metaType = c_getType(type); + userDataAttr = c_property(c_metaResolve(c_metaObject(type), "userData")); + serializer = sd_serializerXMLMetadataNew(c_getBase(metaType)); + serData = sd_serializerSerialize(serializer, userDataAttr->type); + str = sd_serializerToString(serializer, serData); + sd_serializedDataFree(serData); + sd_serializerFree(serializer); + c_free(userDataAttr); + return(str); +} + +static d_topicMetadata +readTopicMetadata( + d_storeXML persistentStore, + u_participant participant, + const c_char* partitionName, + const c_char* topicName) +{ + d_topicMetadata metadata; + struct os_stat_s statBuf; + FILE * fdes; + c_char * data; + c_char * fileStorePath; + c_char * tmp; + os_result ret; + size_t size; + c_bool useDeprecatedSerializer; + sd_serializer serializer; + sd_serializedData serData; + struct baseFind f; + c_type qosType; + + metadata = NULL; + fileStorePath = getMetaFileName(persistentStore, partitionName, topicName); + ret = os_stat(fileStorePath, &statBuf); + + if (ret == os_resultSuccess) { + char * filename = os_fileNormalize(fileStorePath); + fdes = fopen(filename, "r"); + os_free(filename); + + if (fdes != NULL) { + size = statBuf.stat_size + EXTRA_BACKSLS; + data = (c_char *)os_malloc(size); + + if (data) { + readLine(fdes, size, data); + + if(strncmp(data, "", 10) == 0){ + readLine(fdes, size, data); + + if(strncmp(data, "", 6) == 0){ + metadata = d_topicMetadata(os_malloc(C_SIZEOF(d_topicMetadata))); + metadata->name = getSubString(data, 6, (os_ssize_t)strlen(data)-7); + + readLine(fdes, size, data); + + if(strncmp(data, "", 9) == 0){ + metadata->keyList = getSubString(data, 9, (os_ssize_t)strlen(data)-10); + + readLine(fdes, size, data); + + if(strncmp(data, "", 5) == 0){ + d_persistentTopicQosV0 pqos; + tmp = getSubString(data, 5, (os_ssize_t)strlen(data)-6); + + (void)u_observableAction(u_observable(participant), d_storeGetBase, &f); + assert(f.base); + qosType = c_resolve(f.base, "durabilityModule2::d_persistentTopicQosV0"); + + serializer = sd_serializerXMLNewTyped(qosType); + serData = sd_serializerFromString(serializer, tmp); + pqos = (d_persistentTopicQosV0)(sd_serializerDeserialize(serializer, serData)); + os_free(tmp); + + if(pqos != NULL){ + sd_serializedDataFree(serData); + sd_serializerFree(serializer); + c_free(qosType); + + metadata->qos = d_topicQosFromPQos (f.base, pqos); + c_free (pqos); + + readLine(fdes, size, data); + + if(strncmp(data, "", 6) == 0){ + tmp = getSubString(data, 6, (os_ssize_t)strlen(data) - 7); + + useDeprecatedSerializer = isDeprecatedMetadataFormat(tmp); + + /* Instantiate deprecated serializer only if meta-data format is old. */ + if(useDeprecatedSerializer){ + serializer = sd_serializerXMLMetadataNew(f.base); + } else{ + serializer = sd_serializerXMLTypeinfoNew(f.base, FALSE); + } + serData = sd_serializerFromString(serializer, tmp); + metadata->type = (c_type)(sd_serializerDeserialize(serializer, serData)); + os_free(tmp); + + if(metadata->type == NULL){ + d_storeReport(d_store(persistentStore), + D_LEVEL_SEVERE, + "Reconstruction of Topic failed. Topic type on disk is not valid.\nReason: %s\nError: %s\n", + sd_serializerLastValidationMessage(serializer), + sd_serializerLastValidationLocation(serializer)); + OS_REPORT(OS_ERROR, D_CONTEXT, 0, + "Reconstruction of Topic failed. Topic type on disk is not valid.\nReason: %s\nError: %s\n", + sd_serializerLastValidationMessage(serializer), + sd_serializerLastValidationLocation(serializer)); + os_free(metadata->name); + os_free(metadata->keyList); + v_topicQosFree(metadata->qos); + os_free(metadata); + metadata = NULL; + } else if(useDeprecatedSerializer){ + metadata->typeName = c_metaScopedName(c_metaObject(metadata->type)); + } else { + readLine(fdes, size, data); + + if(strncmp(data, "", 10) == 0){ + metadata->typeName = getSubString(data, 10, (os_ssize_t)strlen(data)-11); + } else { + os_free(metadata->name); + os_free(metadata->keyList); + v_topicQosFree(metadata->qos); + c_free(metadata->type); + os_free(metadata); + metadata = NULL; + } + } + sd_serializedDataFree(serData); + sd_serializerFree(serializer); + } else { + os_free(metadata->name); + os_free(metadata->keyList); + v_topicQosFree(metadata->qos); + os_free(metadata); + metadata = NULL; + } + } else { + d_storeReport(d_store(persistentStore), + D_LEVEL_SEVERE, + "Reconstruction of TopicQos failed.\nReason: %s\nError: %s\n", + sd_serializerLastValidationMessage(serializer), + sd_serializerLastValidationLocation(serializer)); + sd_serializedDataFree(serData); + sd_serializerFree(serializer); + c_free(qosType); + + os_free(metadata->name); + os_free(metadata->keyList); + os_free(metadata); + metadata = NULL; + } + } else { + os_free(metadata->name); + os_free(metadata->keyList); + os_free(metadata); + metadata = NULL; + } + } else { + os_free(metadata->name); + os_free(metadata); + metadata = NULL; + } + } else { + os_free(metadata); + metadata = NULL; + } + } + os_free(data); + } + fclose(fdes); + } + } + d_free(fileStorePath); + + return metadata; +} + +c_type +getTopicUserType ( + v_topic topic) +{ + c_type type = NULL; + c_metaObject obj = NULL; + assert(topic != NULL); + assert(C_TYPECHECK(topic,v_topic)); + obj = c_metaResolve(c_metaObject(v_topicMessageType(topic)),"userData"); + type = c_property(obj)->type; + c_free(obj); + return type; +} + +static c_bool +storeTopicMetadata( + d_storeXML persistentStore, + v_group group) +{ + FILE * fdes = NULL; + c_char * topicName = NULL; + c_char * typeName = NULL; + c_char * keyExpr = NULL; + c_char * partitionName = NULL; + c_char * fileStorePath; + c_char * qos; + c_char* str; + c_bool result; + sd_serializer serializer; + sd_serializedData data; + v_topic topic; + + topic = v_groupTopic(group); + topicName = v_topicName(topic); + partitionName = v_partitionName(v_groupPartition(group)); + keyExpr = v_topicKeyExpr(topic); + typeName = c_metaScopedName(c_metaObject(getTopicUserType(topic))); + + if(!keyExpr){ + keyExpr = ""; + } + if(topicName && partitionName && typeName){ + char * filename; + d_persistentTopicQosV0 pqos; + + pqos = d_pQosFromTopicQos (v_topicQosRef(topic)); + serializer = sd_serializerXMLNewTyped(c_getType(pqos)); + data = sd_serializerSerialize(serializer, pqos); + qos = sd_serializerToString(serializer, data); + sd_serializedDataFree(data); + sd_serializerFree(serializer); + c_free (pqos); + + fileStorePath = getMetaFileName(persistentStore, + partitionName, + topicName); + + + filename = os_fileNormalize(fileStorePath); + if(filename){ + fdes = fopen(filename, "w+"); + os_free(filename); + } + if (fdes == NULL) { + d_storeReport(d_store(persistentStore), + D_LEVEL_SEVERE, + RR_COULD_NOT_WRITE_META_DATA, + topicName); + OS_REPORT(OS_ERROR, + STORE_STORE_TOPIC_XML, 0, + RR_COULD_NOT_WRITE_META_DATA, + topicName); + result = FALSE; + } else { + str = getMessageMetadata(v_topicMessageType(topic)); + + if(str){ + fprintf(fdes, "\n"); + fprintf(fdes, "%s\n", topicName); + fprintf(fdes, "%s\n", keyExpr); + fprintf(fdes, "%s\n", qos); + fprintf(fdes, "%s\n", str); + fprintf(fdes, "%s\n", typeName); + fprintf(fdes, "\n"); + os_fsync(fdes); + os_free(str); + result = TRUE; + } else { + result = FALSE; + } + fclose(fdes); + } + if(qos){ + os_free(qos); + } + if(fileStorePath){ + os_free(fileStorePath); + } + } else { + result = FALSE; + } + if(typeName){ + os_free(typeName); + } + return result; +} + +/* TODO: Update to support new format*/ +static c_bool +metaDataIsCorrect( + const c_type type, + const d_storeXML persistentStore, + c_char * topicName, + c_char * partitionName, + c_char * keyList, + v_topicQos qos ) +{ + struct os_stat_s statBuf; + FILE * fdes; + c_char * data; + c_char * fileStorePath; + os_result ret; + size_t size; + c_char * str; + c_char * tmpKeys; + c_char * tmpQos; + c_char* tmpType; + c_bool result; + c_bool noError; + c_bool isDeprecated; + c_type qosType; + sd_serializer ser; + sd_serializedData serData; + c_char* xmlQos; + + result = FALSE; + fileStorePath = getMetaFileName(persistentStore, partitionName, topicName); + ret = os_stat(fileStorePath, &statBuf); + + if (ret == os_resultSuccess) { + char * filename = os_fileNormalize(fileStorePath); + fdes = fopen(filename, "r"); + os_free(filename); + + if (fdes != NULL) { + size = (c_ulong)statBuf.stat_size + EXTRA_BACKSLS; + data = (c_char *)os_malloc(size); + + if (data) { + readLine(fdes, size, data); + + if(strncmp(data, "", 10) == 0){ + readLine(fdes, size, data); + + if(strncmp(data, "", 6) == 0){ + readLine(fdes, size, data); + + if(strncmp(data, "", 9) == 0){ + tmpKeys = getSubString(data, 9, (os_ssize_t)strlen(data) - 10); + + if(strcmp(tmpKeys, keyList) == 0){ + readLine(fdes, size, data); + + if(strncmp(data, "", 5) == 0){ + d_persistentTopicQosV0 pqos; + tmpQos = getSubString(data, 5, (os_ssize_t)strlen(data) - 6); + pqos = d_pQosFromTopicQos (qos); + qosType = c_getType(pqos); + ser = sd_serializerXMLNewTyped(qosType); + serData = sd_serializerSerialize(ser, pqos); + xmlQos = sd_serializerToString(ser, serData); + sd_serializedDataFree(serData); + sd_serializerFree(ser); + c_free (pqos); + /* c_free(qosType); c_getType() does not keep type; */ + + if(strcmp(xmlQos, tmpQos) == 0){ + readLine(fdes, size, data); /* */ + + if(strncmp(data, "", 6) == 0){ + tmpType = getSubString(data, 6, (os_ssize_t)strlen(data) - 7); + isDeprecated = isDeprecatedMetadataFormat(tmpType); + + if(isDeprecated){ + str = getMessageMetadataDeprecated(type); + } else { + str = getMessageMetadata(type); + } + if(str) { + size = (c_ulong) strlen(str); + + if(strncmp(str, tmpType, size) == 0) { + noError = TRUE; + /* The new format also has a line + * to store the typeName + */ + if(isDeprecated == FALSE){ + readLine(fdes, size, data); /* */ + + if(strncmp(data, "", 10) != 0){ + noError = FALSE; + d_storeReport(d_store(persistentStore), + D_LEVEL_SEVERE, + "type-name of topic with name '%s' is missing\n", + topicName); + } + } + if(noError){ + readLine(fdes, size, data); /* */ + + if(strncmp(data, "", 11) == 0){ + result = TRUE; + d_storeReport(d_store(persistentStore), + D_LEVEL_FINE, + "metaDataIsCorrect for '%s' OK\n", topicName); + } else { + d_storeReport(d_store(persistentStore), + D_LEVEL_SEVERE, + " missing for topic '%s'\n", topicName); + } + } + } else { + d_storeReport(d_store(persistentStore), + D_LEVEL_SEVERE, + "types of topics with name '%s' do not match\n", topicName); + } + os_free(str); + + } else { + d_storeReport(d_store(persistentStore), + D_LEVEL_SEVERE, + "type missing for topic '%s'\n", topicName); + } + os_free(tmpType); + } else { + d_storeReport(d_store(persistentStore), + D_LEVEL_SEVERE, + " missing for topic '%s'\n", topicName); + } + } else { + d_storeReport(d_store(persistentStore), + D_LEVEL_SEVERE, + "qos-ses of topics with name '%s' do not match.\n", topicName); + } + os_free(xmlQos); + os_free(tmpQos); + } else { + d_storeReport(d_store(persistentStore), + D_LEVEL_SEVERE, + " missing for topic '%s'\n", topicName); + } + } else { + d_storeReport(d_store(persistentStore), + D_LEVEL_SEVERE, + "keylists of topics with name '%s' not equal ('%s' versus '%s')\n", + topicName, keyList, tmpKeys); + } + os_free(tmpKeys); + } else { + d_storeReport(d_store(persistentStore), + D_LEVEL_SEVERE, + " missing for topic '%s'\n", topicName); + } + } else { + d_storeReport(d_store(persistentStore), + D_LEVEL_SEVERE, + " missing for topic '%s'\n", topicName); + } + } else { + d_storeReport(d_store(persistentStore), + D_LEVEL_SEVERE, + " missing for topic '%s'\n", topicName); + } + os_free(data); + } else { + d_storeReport(d_store(persistentStore), + D_LEVEL_SEVERE, + "Could not allocate.\n"); + } + fclose(fdes); + } else { + d_storeReport(d_store(persistentStore), + D_LEVEL_SEVERE, + "Metadata not accessible for topic '%s'\n", topicName); + } + } else { + d_storeReport(d_store(persistentStore), + D_LEVEL_SEVERE, + "Metadata missing on disk for topic '%s'\n", topicName); + } + d_free(fileStorePath); + + return result; +} + +static void +forAllDirectoryEntries ( + d_storeXML persistentStore, + const char * workingDir, + const char * parent, + /* QAC EXPECT 3672; non-const pointer to function */ + void (* processEntry )(d_storeXML persistentStore, + const char * path, + const char * parent, + const char * entryName, + struct os_stat_s * status), + c_bool usePWD) +{ + char *full_file_path = NULL; + os_dirHandle d_descr; + struct os_dirent d_entry; + struct os_stat_s status; + os_result r; + + r = os_opendir(workingDir, &d_descr); + if (r == os_resultSuccess) { /* accessable */ + r = os_readdir(d_descr, &d_entry); + while (r == os_resultSuccess) { + full_file_path = (char*) os_malloc(strlen(workingDir) + 1 + strlen(d_entry.d_name) + 1 ); + /* QAC EXPECT 5007; use of strcpy*/ + os_strcpy(full_file_path, workingDir); + /* QAC EXPECT 5007; use of os_strcat */ + os_strcat(full_file_path, os_fileSep()); + /* QAC EXPECT 5007; use of os_strcat */ + os_strcat(full_file_path, d_entry.d_name); + + if (os_stat (full_file_path, &status) == os_resultSuccess) { /* accessable */ + /* QAC EXPECT 5007; use of strcmp */ + if ((strcmp(d_entry.d_name, ".") != 0) && + /* QAC EXPECT 5007; use of strcmp */ + (strcmp(d_entry.d_name, "..") != 0)) { + processEntry(persistentStore, full_file_path, parent, d_entry.d_name, &status); + } + } + r = os_readdir(d_descr, &d_entry); + + os_free(full_file_path); + } + if(usePWD == TRUE){ + if(os_stat(workingDir, &status) == os_resultSuccess){ + processEntry(persistentStore, workingDir, parent, "", &status); + } + } + os_closedir (d_descr); + } +} + +static c_bool +topicIsProperlyTagged( + FILE * fDes, + struct os_stat_s * status ) +{ + /* QAC EXPECT 1259; */ + c_char testText[STRLEN_NEEDED_FOR_A_BIG_TAG]; + c_bool isProperlyTagged; + int result; + + /* check the file contents */ + testText[0] = '\0'; + isProperlyTagged = FALSE; + /* QAC EXPECT 0702,1259; */ + RESULT_IGNORE(fread ((c_voidp) &testText[0], sizeof (c_char), STRLEN_TOPIC_TAG_OPEN, fDes)); + /* QAC EXPECT 1259; */ + result = strncmp(testText, TOPIC_TAG_OPEN, STRLEN_TOPIC_TAG_OPEN); + if (result == 0 && status->stat_size >= STRLEN_TOPIC_TAG_CLOSE - STRLEN_BACKSLASH_N) { + /* QAC EXPECT 3892,3784,1259; */ + size_t pos = status->stat_size - STRLEN_TOPIC_TAG_CLOSE - STRLEN_BACKSLASH_N; + assert(pos <= OS_MAX_INTEGER(long)); + fseek(fDes, (long)pos, SEEK_SET); + RESULT_IGNORE(fscanf(fDes, "%s", testText)); + /* QAC EXPECT 1259; */ + result = strncmp(testText, TOPIC_TAG_CLOSE, STRLEN_TOPIC_TAG_CLOSE); + if (result == 0) { + isProperlyTagged = TRUE; + } + } + return isProperlyTagged; +} + +static c_bool +fileNameIsOK( + const char * topic, /* input : name with extension */ + c_char * topicName ) /* output : name without extension */ +{ + c_bool nameIsOK; + int result; + os_uint32 length; + const char * tail; + + /* Name must end with ".xml" */ + nameIsOK = FALSE; + length = (os_uint32) strlen(topic); + /* QAC EXPECT 1259; */ + if (length > STRLEN_DOT_XML) { + /* QAC EXPECT 0488,1259; */ + tail = topic + length - STRLEN_DOT_XML; + /* QAC EXPECT 3757,1259; */ + result = strncmp(tail, DOT_XML, STRLEN_DOT_XML); + /* QAC EXPECT 2100; */ + if (result == 0) { + nameIsOK = TRUE; + os_strncpy(topicName, topic, length); + /* QAC EXPECT 1259; */ + topicName[length - STRLEN_DOT_XML] = '\0'; + } + } + return nameIsOK; +} + +static d_groupList +getPartitionTopic( + d_storeXML persistentStore, + const char * partition, + const char * topic ) +{ + d_groupList persistentGroup; + d_groupList foundGroup; + int result; + + foundGroup = NULL; + persistentGroup = persistentStore->groups; + + while((persistentGroup) && (foundGroup == NULL)) { + /* QAC EXPECT 5007; */ + result = strcmp(persistentGroup->topic, topic); + if (result == 0) { + /* QAC EXPECT 5007; */ + result = strcmp(persistentGroup->partition, partition); + if (result == 0) { + foundGroup = persistentGroup; + } + } + persistentGroup = persistentGroup->next; + } + return foundGroup; +} + +static void +setPartitionTopicQuality( + d_storeXML persistentStore, + const char * partition, + const char * topic, + d_quality quality, + d_completeness completeness ) +{ + d_groupList persistentGroup; + + persistentGroup = getPartitionTopic(persistentStore, partition, topic); + + if (persistentGroup) { + if (d_qualityCompare(quality, persistentGroup->quality) == OS_MORE) { + persistentGroup->quality = quality; + + d_storeReport(d_store(persistentStore), D_LEVEL_FINE, "Group '%s.%s' has quality: %"PA_PRItime"\n", + partition, topic, OS_TIMEW_PRINT(quality)); + } + } else { + persistentGroup = d_groupList(os_malloc(C_SIZEOF(d_groupList))); + + if (persistentGroup) { + persistentGroup->partition = os_strdup(partition); + persistentGroup->topic = os_strdup(topic); + persistentGroup->quality = quality; + persistentGroup->completeness = completeness; + persistentGroup->next = persistentStore->groups; + persistentGroup->optimized = FALSE; + persistentStore->groups = persistentGroup; + } + } +} + +static void +processFile( + d_storeXML persistentStore, + FILE * fDes, + const char * partition, /* = */ + const char * topic, /* = _meta.xml or .xml */ + struct os_stat_s *status ) +{ + c_char topicName[OS_PATH_MAX + 1]; + c_char* topicDataFileName; + c_char* strPartition; + c_char* strTopic; + struct os_stat_s s; + d_quality quality; + + topicName[0] = '\0'; + /* QAC EXPECT 2100; */ + + if ((fileNameIsOK(topic, topicName) == TRUE)) { + + + if ((topicIsProperlyTagged(fDes, status) == TRUE)) { + strPartition = URIToString(partition); + strTopic = URIToString(topicName); + topicDataFileName = getDataFileName(persistentStore, strPartition, strTopic); + + if(os_stat(topicDataFileName, &s) == os_resultSuccess){ + quality = s.stat_mtime; + + d_storeReport(d_store(persistentStore), D_LEVEL_FINER, + "Found group '%s.%s' with quality %"PA_PRItime".\n", + strPartition, strTopic, OS_TIMEW_PRINT(quality)); + } else { + quality = D_QUALITY_ZERO; + + d_storeReport(d_store(persistentStore), D_LEVEL_FINER, + "Found group '%s.%s' that does not have data on disk so quality is %"PA_PRItime".\n", + strPartition, strTopic, OS_TIMEW_PRINT(quality)); + } + os_free(topicDataFileName); + + setPartitionTopicQuality(persistentStore, strPartition, strTopic, + quality, D_GROUP_INCOMPLETE); + os_free(strPartition); + os_free(strTopic); + } else { + d_storeReport(d_store(persistentStore), D_LEVEL_FINEST, "No tag.\n"); + d_storeReport(d_store(persistentStore), D_LEVEL_FINEST, "Is not a meta file\n"); + } + } +} + +static void +processTopic( + d_storeXML persistentStore, + const char * path, + const char * partition, + const char * topic, + struct os_stat_s *status ) +{ + FILE * fDes; + + /* QAC EXPECT 1253,1277; */ + if (OS_ISREG(status->stat_mode)) { + char * filename = os_fileNormalize(path); + + if(filename){ + fDes = fopen(filename, "r"); + os_free(filename); + if (fDes == NULL) { + /* (INACCESSABLE */ + } else { + /* (REGULAR_FILE */ + processFile(persistentStore, fDes, partition, topic, status); + fclose (fDes); + } + } + } +} + +static void +processPartition( + d_storeXML persistentStore, + const char * path, + const char * parent__UNUSED_PARAMETER, + const char * partition, + struct os_stat_s *status ) +{ + if (parent__UNUSED_PARAMETER == NULL) { + } + /* QAC EXPECT 1253,1277; */ + if (OS_ISDIR(status->stat_mode) || OS_ISLNK(status->stat_mode)) { + d_storeReport(d_store(persistentStore), D_LEVEL_FINE, "partition: %s\n", path); + forAllDirectoryEntries(persistentStore, path, partition, processTopic, FALSE); + } +} + + +/* TODO: Update implementation to use stringKeyEscape() for each key-value + * that is a string + */ +static c_char* +determineInstance( + const v_groupAction msg) +{ + v_message message; + v_group group; + c_ulong nrOfKeys, i; + c_char* keyValues; + c_value value; + c_char* valueImage, *notEscaped; + c_array keyList; + c_iter keyValuesIter; + os_size_t totalSize; + c_bool proceed = TRUE; + + keyValues = NULL; + + if(msg){ + message = msg->message; + group = msg->group; + keyList = v_topicMessageKeyList(group->topic); + nrOfKeys = c_arraySize(keyList); + + if (nrOfKeys < 1) { + keyValues = (c_char *)os_malloc(strlen(KEY_START_TAG) + + + strlen(KEY_END_TAG) + 1); + if(keyValues){ + os_sprintf(keyValues, "%s%s", KEY_START_TAG, KEY_END_TAG); + } + } else { + totalSize = 0; + keyValuesIter = c_iterNew(NULL); + + if(keyValuesIter){ + for (i = 0; (i < nrOfKeys) && (proceed == TRUE); i++) { + value = c_fieldValue(keyList[i], (c_object)message); + + switch(value.kind){ + case V_STRING: + /*fallthrough on purpose */ + case V_CHAR: + notEscaped = c_valueImage(value); + valueImage = stringKeyEscape(notEscaped, TRUE); + os_free(notEscaped); + break; + default: + valueImage = c_valueImage(value); + break; + } + if(valueImage){ + totalSize += strlen(valueImage) + 1; + c_iterAppend(keyValuesIter, valueImage); + } else { + proceed = FALSE; + break; + } + c_valueFreeRef(value); + } + if(proceed == TRUE){ + keyValues = (c_char *)os_malloc(strlen(KEY_START_TAG) + + totalSize + strlen(KEY_END_TAG) + 1); + + if(keyValues){ + keyValues[0] = '\0'; + os_strncat(keyValues, KEY_START_TAG, strlen(KEY_START_TAG)); + assert(c_iterLength(keyValuesIter) == nrOfKeys); + + for (i=0;inewMessage = c_keep(message); + instance->messages = c_iterNew(NULL); + instance->keyValue = determineInstance(message); + instance->result = D_STORE_RESULT_OK; + instance->writeCount = 0; + instance->disposeCount = 0; + instance->registerCount = 0; + instance->unregisterCount = 0; + + return instance; +} + +static persistentInstance +persistentInstanceDummyNew( + c_char* keyValue) +{ + persistentInstance instance; + + instance = persistentInstance(os_malloc(C_SIZEOF(persistentInstance))); + + instance->newMessage = NULL; + instance->messages = c_iterNew(NULL); + + if(keyValue){ + instance->keyValue = os_strdup(keyValue); + } else { + instance->keyValue = NULL; + } + instance->result = D_STORE_RESULT_OK; + instance->writeCount = 0; + instance->disposeCount = 0; + instance->registerCount = 0; + instance->unregisterCount = 0; + + return instance; +} + +static c_bool +persistentInstanceInsertUnregister( + persistentInstance instance, + v_message message) +{ + v_message reg, tmp; + c_ulong i; + c_bool added; + + assert(v_stateTest(v_nodeState(message), L_UNREGISTER)); + + if(instance->registerCount != 0){ + reg = NULL; + + for(i=0; imessages) && !reg; i++){ + reg = c_iterObject(instance->messages, i); + + if( (!v_stateTest(v_nodeState(reg), L_REGISTER)) || + ((v_gidCompare(reg->writerGID, message->writerGID) != C_EQ))) + { + reg = NULL; + } + } + if(!reg){ + /*No registration found for unregistration, no need to insert*/ + added = FALSE; + } else if(os_timeWCompare(message->writeTime, reg->writeTime) != OS_LESS){ + tmp = c_iterTake(instance->messages, reg); + assert(tmp == reg); + (void)tmp; + c_free(reg); + instance->registerCount--; + + /* There is no need to store the unregister if there is no data + * anymore for the instance + */ + if( (instance->registerCount == 0) && + (instance->writeCount == 0) && + (instance->disposeCount == 0)) + { + added = FALSE; + } else { + instance->messages = c_iterAppend(instance->messages, message); + instance->unregisterCount++; + added = TRUE; + } + } else { + /*No need to add unregistration, since there is a newer registration*/ + added = FALSE; + } + } else { + /*No registration found for unregistration, no need to insert if there is no data */ + if( (instance->writeCount == 0) && + (instance->disposeCount == 0)) + { + added = FALSE; + } else { + instance->messages = c_iterAppend(instance->messages, message); + instance->unregisterCount++; + added = TRUE; + } + } + return added; +} + +static c_bool +persistentInstanceInsertRegister( + persistentInstance instance, + v_message message) +{ + v_message unreg, tmp; + c_ulong i; + c_bool added; + + assert(v_stateTest(v_nodeState(message), L_REGISTER)); + + if(instance->unregisterCount != 0){ + unreg = NULL; + + for(i=0; imessages) && !unreg; i++){ + unreg = c_iterObject(instance->messages, i); + + if( (!v_stateTest(v_nodeState(unreg), L_UNREGISTER)) || + ((v_gidCompare(unreg->writerGID, message->writerGID) != C_EQ))) + { + unreg = NULL; + } + } + if(!unreg){ + instance->messages = c_iterAppend(instance->messages, message); + instance->registerCount++; + added = TRUE; + } else if(os_timeWCompare(message->writeTime, unreg->writeTime) != OS_LESS){ + tmp = c_iterTake(instance->messages, unreg); + assert(tmp == unreg); + (void)tmp; + c_free(unreg); + instance->messages = c_iterAppend(instance->messages, message); + instance->unregisterCount--; + instance->registerCount++; + added = TRUE; + } else { + added = FALSE; + } + } else { + instance->messages = c_iterAppend(instance->messages, message); + instance->registerCount++; + added = TRUE; + } + return added; +} + +static c_bool +persistentInstanceInsert( + persistentInstance instance, + v_topicQos topicQos, + v_message message) +{ + c_bool added, checkCounters; + v_message tmp, oldest; + c_iter newList; + + added = FALSE; + checkCounters = FALSE; + + if(v_stateTest(v_nodeState(message), L_REGISTER)){ + added = persistentInstanceInsertRegister(instance, message); + } else if(v_stateTest(v_nodeState(message), L_UNREGISTER)){ + added = persistentInstanceInsertUnregister(instance, message); + } else if(instance->writeCount == 0) { /*no write messages for instance yet; add it*/ + instance->messages = c_iterAppend(instance->messages, message); + added = TRUE; + checkCounters = TRUE; + } else if(topicQos->durabilityService.v.history_kind == V_HISTORY_KEEPALL){ /*KEEP_ALL; add it*/ + instance->messages = c_iterAppend(instance->messages, message); + added = TRUE; + checkCounters = TRUE; + } else { /*KEEP_LAST*/ + if( (instance->writeCount < topicQos->durabilityService.v.history_depth) || /*There is still room; add it*/ + (topicQos->durabilityService.v.history_depth == V_LENGTH_UNLIMITED) ) + { + instance->messages = c_iterAppend(instance->messages, message); + added = TRUE; + checkCounters = TRUE; + } else if(topicQos->orderby.v.kind == V_ORDERBY_RECEPTIONTIME) {/* V_ORDERBY_RECEPTIONTIME */ + if(!v_stateTest(v_nodeState(message), L_WRITE)){ /* Not a WRITE message; add it*/ + instance->messages = c_iterAppend(instance->messages, message); + added = TRUE; + checkCounters = TRUE; + } else { + /* This is a WRITE message; throw away last received write message, + * which is this one. Simply don't add it. + */ + + /* Remove first sample */ + tmp = c_iterTakeFirst(instance->messages); + c_free(tmp); + tmp = NULL; + + /* Insert last sample */ + instance->messages = c_iterAppend(instance->messages, message); + + added = TRUE; + checkCounters = TRUE; + } + } else { /* V_ORDERBY_SOURCETIME */ + if(!v_stateTest(v_nodeState(message), L_WRITE)){ /* Not a WRITE message; add it*/ + instance->messages = c_iterAppend(instance->messages, message); + added = TRUE; + checkCounters = TRUE; + } else { /* This is a WRITE message; throw away write message with oldest write time*/ + assert(topicQos->durabilityService.v.history_depth == instance->writeCount); + + oldest = message; + newList = c_iterNew(NULL); + tmp = c_iterTakeFirst(instance->messages); + + while(tmp){ + if(v_stateTest(v_nodeState(tmp), L_WRITE)){ + if(v_messageCompare(tmp, oldest) == C_LT){ + oldest = tmp; + } else { + newList = c_iterAppend(newList, tmp); + } + } else { + newList = c_iterAppend(newList, tmp); + } + tmp = c_iterTakeFirst(instance->messages); + } + if(oldest != message){ + newList = c_iterAppend(newList, message); + c_free(oldest); + added = TRUE; + } + c_iterFree(instance->messages); + instance->messages = newList; + } + } + } + if(checkCounters){ + if(v_stateTest(v_nodeState(message), L_WRITE)){ + instance->writeCount++; + + if(v_stateTest(v_nodeState(message), L_DISPOSED)){ + instance->disposeCount++; + } + } else if(v_stateTest(v_nodeState(message), L_DISPOSED)){ + instance->disposeCount++; + } else if(v_stateTest(v_nodeState(message), L_REGISTER)){ + /*Do nothing here*/ + } else if(v_stateTest(v_nodeState(message), L_UNREGISTER)){ + /*Do nothing here*/ + } else { + OS_REPORT(OS_ERROR, "durability", 0, + "Found message with state %d.", + v_nodeState(message)); + assert(FALSE); + } + } + return added; +} + +static int +persistentInstanceCompare( + persistentInstance i1, + persistentInstance i2) +{ + int result; + + if(i1 && i2){ + if(i1->keyValue && i2->keyValue){ + result = strcmp(i1->keyValue, i2->keyValue); + } else if(i1->keyValue){ + result = 1; + } else { + result = -1; + } + } else if(i1){ + result = 1; + } else { + result = -1; + } + return result; +} + +static void +persistentInstanceFree( + persistentInstance instance) +{ + v_message message; + + if(instance){ + message = (v_message)(c_iterTakeFirst(instance->messages)); + + while(message){ + if(instance->newMessage){ + if(message != (instance->newMessage->message)){ + c_free(message); + } + } else { + c_free(message); + } + message = (v_message)(c_iterTakeFirst(instance->messages)); + } + c_iterFree(instance->messages); + + if(instance->newMessage){ + c_free(instance->newMessage); + } + if(instance->keyValue){ + os_free(instance->keyValue); + } + os_free(instance); + } + return; +} + +static persistentInstance +persistentInstanceFindKey( + persistentInstance instance, + c_char* key) +{ + persistentInstance result; + + assert(key); + result = NULL; + + if(strcmp(instance->keyValue, key) == 0){ + result = instance; + } + return result; +} + +static groupExpungeActions +groupExpungeActionsNew( + const c_char* partition, + const c_char* topic) +{ + groupExpungeActions g; + + assert(partition); + assert(topic); + + g = groupExpungeActions(os_malloc(C_SIZEOF(groupExpungeActions))); + g->partition = os_strdup(partition); + g->topic = os_strdup(topic); + g->instances = d_tableNew(persistentInstanceCompare, persistentInstanceFree); + + return g; +} + +static void +groupExpungeActionsFree( + groupExpungeActions gea) +{ + if(gea){ + if(gea->partition){ + os_free(gea->partition); + } + if(gea->topic){ + os_free(gea->topic); + } + if(gea->instances){ + d_tableFree(gea->instances); + } + os_free(gea); + } +} + +static int +groupExpungeActionsCompare( + groupExpungeActions g1, + groupExpungeActions g2) +{ + int result; + + if(g1 != g2){ + result = strcmp(g1->partition, g2->partition); + + if(result == 0){ + result = strcmp(g1->topic, g2->topic); + } + } else { + result = 0; + } + return result; +} + +static void +groupExpungeActionsAdd( + const d_storeXML persistentStore, + const v_groupAction action) +{ + groupExpungeActions gea, dummy; + persistentInstance instance, found; + v_topicQos topicQos; + + gea = groupExpungeActionsNew(v_partitionName(v_groupPartition(action->group)), + v_topicName(v_groupTopic(action->group))); + dummy = d_tableInsert(persistentStore->expungeActions, gea); + + if(dummy){ /*Group already exists*/ + groupExpungeActionsFree(gea); + gea = dummy; + } + instance = persistentInstanceNew(action); + found = d_tableInsert(gea->instances, instance); + + if(found){ + persistentInstanceFree(instance); + topicQos = v_topicQosRef(v_groupTopic(action->group)); + + if(topicQos->orderby.v.kind == V_ORDERBY_RECEPTIONTIME){ + c_free(found->newMessage); + found->newMessage = c_keep(action); + } else if(os_timeWCompare(found->newMessage->message->writeTime, + action->message->writeTime) == OS_LESS){ + c_free(found->newMessage); + found->newMessage = c_keep(action); + } + } +} + +static FILE* +getStoreFile( + d_storeXML persistentStore, + const c_char* path, + const c_char* mode) +{ + d_storeFile result = NULL; + FILE* fdes = NULL; + + assert(path); + assert(mode); + + if(persistentStore->sessionAlive == TRUE){ + persistentStore->dummyFile->path = (c_char*)path; + result = d_tableFind(persistentStore->openedFiles, + persistentStore->dummyFile); + + if(result){ + if(result->mode){ + if(strcmp(result->mode, mode) != 0){ + result = d_tableRemove(persistentStore->openedFiles, + result); + d_storeFileFree(result); + result = NULL; + } + } else { + result = d_tableRemove(persistentStore->openedFiles, result); + d_storeFileFree(result); + result = NULL; + } + } + persistentStore->dummyFile->path = NULL; + } + + if(result){ + fdes = result->fdes; + } else { + char * filename = os_fileNormalize(path); + if(filename){ + fdes = fopen(filename, mode); + os_free(filename); + if(fdes && (persistentStore->sessionAlive == TRUE)){ + result = d_storeFileNew(path, fdes, mode); + d_tableInsert(persistentStore->openedFiles, result); + } + } + } + return fdes; +} + +static int +openFile( + d_storeXML persistentStore, + v_group group, + FILE ** fdes) +{ + c_char * topicName; + c_char * partitionName; + c_char * fileStorePath; + c_char testEnd[15]; + struct os_stat_s statBuf; + os_result status; + + testEnd[0] = '\0'; + + topicName = v_topicName(v_groupTopic(group)); + partitionName = v_partitionName(v_groupPartition(group)); + fileStorePath = getDataFileName(persistentStore, + partitionName, + topicName); + status = os_stat(fileStorePath, &statBuf); + + if (status != os_resultSuccess) { + d_storeReport(d_store(persistentStore), D_LEVEL_FINE, RR_TOPIC_NOT_YET_KNOWN, topicName); + *fdes = NULL; + } else if (statBuf.stat_size > 0x7fffffff || statBuf.stat_size < 10) { + d_storeReport(d_store(persistentStore), D_LEVEL_FINE, RR_TOPIC_FILESIZE_INVALID, topicName); + *fdes = NULL; + } else if ((*fdes = getStoreFile(persistentStore, fileStorePath, "r")) == NULL) { + d_storeReport(d_store(persistentStore), D_LEVEL_FINE, RR_TOPIC_NOT_YET_KNOWN, topicName); + } else { + int cmpres; + fseek(*fdes, (long)(statBuf.stat_size - 10), SEEK_SET); + testEnd[14] = '\0'; + RESULT_IGNORE(fscanf(*fdes, "%s", testEnd)); + cmpres = strncmp(testEnd, D_STORE_END_STRING_NO_NL, strlen(D_STORE_END_STRING_NO_NL)); + + if (cmpres != 0) { + OS_REPORT(OS_WARNING, D_CONTEXT, 0, + "Data for group '%s.%s' on disk mutilated " + "(expected=\"%s\", found=\"%s\"), some data might be lost.", + partitionName, topicName, + D_STORE_END_STRING_NO_NL, testEnd); + } + fseek(*fdes, 0, SEEK_SET); + } + + os_free(fileStorePath); + + return *fdes ? (int) statBuf.stat_size : -1; +/* QAC EXPECT 5101,5103; Complexity and too many lines of code */ +} + +static FILE* +openPersistentFile( + d_storeXML persistentStore, + const c_char* partition, + const c_char* topic, + const c_char* flags) +{ + FILE* fdes; + c_char* fileStorePath; + + fdes = NULL; + fileStorePath = getDataFileName(persistentStore, partition, topic); + fdes = getStoreFile(persistentStore, fileStorePath, flags); + os_free(fileStorePath); + + return fdes; +} + +static FILE* +openPersistentTempFile( + const d_storeXML persistentStore, + const c_char* partition, + const c_char* topic, + const c_char* flags) +{ + FILE* fdes; + c_char* fileStorePath; + + fdes = NULL; + fileStorePath = getTmpFileName(persistentStore, partition, topic); + fdes = getStoreFile(persistentStore, fileStorePath, flags); + os_free(fileStorePath); + + return fdes; +} + +static void +closeFile( + const d_storeXML persistentStore, + FILE* fdes) +{ + d_thread self = d_threadLookupSelf(); + /* Syncing data to disk can take quite a while, depending on how many writes + * have been accumulated and the performance of the underlying hardware. + * Since this is basically outside the control of the service, thread + * liveliness is suspended while the persistent store file is closed. + */ + d_threadAsleep(self, UT_SLEEP_INDEFINITELY); + if(persistentStore->sessionAlive == FALSE){ + fflush(fdes); + os_fsync(fdes); + fclose(fdes); + } else { + fflush(fdes); + } + d_threadAwake(self); +} + +static c_bool +renameTempToActual( + const d_storeXML persistentStore, + const c_char* partition, + const c_char* topic) +{ + c_char* fileStorePath; + c_char* tmpStorePath; + struct os_stat_s statBuf; + os_result osResult; + d_storeFile storeFile, found; + + fileStorePath = getDataFileName(persistentStore, partition, topic); + tmpStorePath = getTmpFileName(persistentStore, partition, topic); + + /* tmpFile must exist */ + if ((osResult = os_stat(tmpStorePath, &statBuf)) != os_resultSuccess) { + goto err; + } + /* Update persistentStore administration */ + storeFile = d_storeFileNew(fileStorePath, NULL, NULL); + if ((found = d_tableRemove(persistentStore->openedFiles, storeFile)) != NULL) { + if(found->fdes){ + d_storeFileFree(found); + } + } + d_storeFileFree(storeFile); + storeFile = d_storeFileNew(tmpStorePath, NULL, NULL); + if ((found = d_tableRemove(persistentStore->openedFiles, storeFile)) != NULL) { + if(found->fdes){ + d_storeFileFree(found); + } + } + d_storeFileFree(storeFile); + /* Delete file named fileStorePath if exists */ + if ((osResult = os_stat(fileStorePath, &statBuf)) == os_resultSuccess) { + if ((osResult = os_remove(fileStorePath)) != os_resultSuccess) { + goto err; + } + } + /* Rename tmpStorePath to fileStorePath */ + if ((osResult = os_rename(tmpStorePath, fileStorePath)) != os_resultSuccess) { + goto err; + } + os_free(fileStorePath); + os_free(tmpStorePath); + return TRUE; + +err: + os_free(fileStorePath); + os_free(tmpStorePath); + return FALSE; +} + + +static d_storeResult +setOptimizeTime( + const d_storeXML persistentStore, + const c_char* partition, + const c_char* topic, + const os_timeM optimizeTime) +{ + d_storeResult result; + c_char* optfname; + FILE* fdes; + + optfname = getOptimizeFileName(persistentStore, partition, topic); + + if(optfname){ + char * filename = os_fileNormalize(optfname); + fdes = fopen(filename, "w"); + os_free(filename); + + if(fdes){ + fprintf(fdes, "%" PA_PRIu64, OS_TIMEM_GET_SECONDS(optimizeTime)); + os_fsync(fdes); + fclose(fdes); + result = D_STORE_RESULT_OK; + } else { + result = D_STORE_RESULT_IO_ERROR; + } + os_free(optfname); + } else { + result = D_STORE_RESULT_ERROR; + } + return result; +} + +static c_bool +isOptimized( + const d_storeXML persistentStore, + const c_char* partition, + const c_char* topic) +{ + c_bool result; + c_char *optfname, *dataFileName; + FILE* fdes; + os_uint64 seconds; + struct os_stat_s statBuf; + os_result statResult; + + dataFileName = getDataFileName(persistentStore, partition, topic); + optfname = getOptimizeFileName(persistentStore, partition, topic); + + if(optfname && optfname){ + char * filename = os_fileNormalize(optfname); + fdes = fopen(filename, "r"); + + if(fdes){ + RESULT_IGNORE(fscanf(fdes, "%" PA_PRIu64, &seconds)); + fclose(fdes); + statResult = os_stat(dataFileName, &statBuf); + + if((statResult == os_resultSuccess) && (OS_TIMEW_GET_SECONDS(statBuf.stat_mtime) <= seconds)){ + result = TRUE; + } else { + result = FALSE; + } + } else { + result = FALSE; + } + os_free(filename); + os_free(optfname); + os_free(dataFileName); + } else if(dataFileName){ + os_free(dataFileName); + result = FALSE; + } else if(optfname){ + os_free(optfname); + result = FALSE; + } else { + result = FALSE; + } + return result; +} + +static d_storeResult +deleteHistoricalData( + const d_storeXML persistentStore, + const v_groupAction msg) +{ + v_group group; + FILE *fdes, *tmpfdes; + c_char *data, *partition, *topic, *keys; + c_type type; + sd_serializer serializer; + v_message perData; + sd_serializedData serData; + c_long status1; + os_timeW deleteTime; + c_bool renameSuccess; + d_storeResult result; + c_bool success; + os_duration duration; + + group = msg->group; + partition = v_partitionName(v_groupPartition(group)); + topic = v_topicName(v_groupTopic(group)); + fdes = openPersistentFile(persistentStore, partition, topic, "r"); + tmpfdes = openPersistentTempFile(persistentStore, partition, topic, "w"); + result = D_STORE_RESULT_OK; + + /* The actionTime contains an elapsed time. + * All data that was published prior to this time must be deleted. + * To select the data to be deleted the elapsed time must be + * transformed to a wall clock time. + */ + duration = os_timeEDiff(os_timeEGet(), msg->actionTime); + deleteTime = os_timeWSub(os_timeWGet(), duration); + if (OS_TIMEW_ISINVALID(deleteTime)) { + d_storeReport(d_store(persistentStore), + D_LEVEL_SEVERE, "Invalid timestamp, unable to delete data from the persistent store\n"); + return D_STORE_RESULT_ERROR; + } + if (fdes && tmpfdes) { + /* data exists and temp file can be openend */ + type = v_topicMessageType(group->topic); + data = persistentStore->dataBuffer; + data[0] = '\0'; + keys = persistentStore->keyBuffer; + keys[0] = '\0'; + + if ((data == NULL) || (keys == NULL)) { + d_storeReport(d_store(persistentStore), + D_LEVEL_SEVERE, + RR_COULD_NOT_READ_TOPIC" \n", + topic); + OS_REPORT(OS_ERROR, STORE_READ_TOPIC_XML, 0, + RR_COULD_NOT_READ_TOPIC" \n", topic); + result = D_STORE_RESULT_ERROR; + } else { + c_type xmsgType; + xmsgType = v_messageExtTypeNew (group->topic); + serializer = sd_serializerXMLNewTyped (xmsgType); + data[0] = '\0'; + readLine(fdes, MAX_KEY_SIZE, data); + status1 = strncmp(data, "", 7); + + if (status1 != 0) { + d_storeReport(d_store(persistentStore), D_LEVEL_SEVERE, + RR_TOPIC_SHOULD_BEGIN_WITH_TOPIC_TAG, topic); + OS_REPORT(OS_ERROR, STORE_READ_TOPIC_XML, 0, + RR_TOPIC_SHOULD_BEGIN_WITH_TOPIC_TAG, topic); + result = D_STORE_RESULT_MUTILATED; + } else { + fprintf(tmpfdes, D_STORE_START_STRING); + data[0] = '\0'; + /* read keys */ + readLine(fdes, MAX_KEY_SIZE, keys); + status1 = feof(fdes); + + if(strncmp(keys, D_STORE_END_STRING_NO_NL, strlen(D_STORE_END_STRING_NO_NL)) != 0){ + while (status1 == 0) { + /* read data */ + v_messageExt xmsg; + readObject(fdes, MAX_MESSAGE_SIZE, data); + serData = sd_serializerFromString(serializer, data); + xmsg = sd_serializerDeserialize(serializer, serData); + perData = xmsg ? v_messageExtConvertFromExtType (type, xmsg) : NULL; + if (perData) { + if(os_timeWCompare(perData->writeTime, deleteTime) == OS_MORE){ + fprintf(tmpfdes, "%s\n", keys); /* write keys */ + fprintf(tmpfdes, "%s\n", data); /* write data */ + } + c_free(perData); + } else { + fprintf(tmpfdes, "%s\n", keys); /* write keys */ + fprintf(tmpfdes, "%s\n", data); /* write data */ + OS_REPORT(OS_CRITICAL, D_CONTEXT, U_RESULT_OUT_OF_MEMORY, + "Failed to deleteHistoricalData sample for group '%s.%s': out of memory.", + partition, topic); + } + sd_serializedDataFree(serData); + keys[0] = '\0'; + data[0] = '\0'; + /* read keys */ + readLine(fdes, MAX_KEY_SIZE, keys); + status1 = feof(fdes); + + if(status1 == 0){ + if(strncmp(keys, D_STORE_END_STRING_NO_NL, strlen(D_STORE_END_STRING_NO_NL)) == 0){ + status1 = -1; + } + } + } /* while */ + } + } + sd_serializerFree(serializer); + v_messageExtTypeFree (xmsgType); + } + fprintf(tmpfdes, D_STORE_END_STRING); + } else if (tmpfdes) { + /* data does not exist and temp file can be openend. + * Create an empty store in this case + */ + d_storeReport(d_store(persistentStore), D_LEVEL_FINE, "No data exists yet on disk for group '%s.%s' (2)\n", partition, topic); + success = createDirectoryIfNecessary(persistentStore, partition); + if (success) { + success = storeTopicMetadata(persistentStore, group); + if (success) { + fprintf(tmpfdes, D_STORE_START_STRING); + fprintf(tmpfdes, D_STORE_END_STRING); + } else { + d_storeReport(d_store(persistentStore), + D_LEVEL_SEVERE, "Could not store metadata to disk.\n"); + result = D_STORE_RESULT_IO_ERROR; + } + } else { + d_storeReport(d_store(persistentStore), D_LEVEL_SEVERE, "Could not create directory.\n"); + result = D_STORE_RESULT_IO_ERROR; + } + } else if (fdes) { + /* data does exist and temp file cannot be openend. + * This means I cannot create a new store. + */ + d_storeReport(d_store(persistentStore), D_LEVEL_SEVERE, "Could not open file for writing.\n"); + result = D_STORE_RESULT_IO_ERROR; + } + /* Now the close the files that were openend */ + if (fdes) { + closeFile(persistentStore, fdes); + } + if (tmpfdes) { + closeFile(persistentStore, tmpfdes); + } + /* Rename the file */ + if (result == D_STORE_RESULT_OK) { + renameSuccess = renameTempToActual(persistentStore, partition, topic); + if (!renameSuccess) { + d_storeReport(d_store(persistentStore), D_LEVEL_SEVERE, "Could not rename file.\n"); + result = D_STORE_RESULT_ERROR; + } + /* empty the expunge list */ + d_tableFree(persistentStore->expungeActions); + persistentStore->expungeActions = d_tableNew(groupExpungeActionsCompare, groupExpungeActionsFree); + } + return result; +} + +typedef void (*InstanceReadCallback)(persistentInstance, v_message); + +static void +handleInstanceMessageByMessage( + persistentInstance instance, + v_message message) __nonnull_all__; + +static void +handleInstanceMessageByMessage( + persistentInstance instance, + v_message message) +{ + v_message newMessage = v_message(instance->newMessage->message); + + if (v_messageCompare(message, newMessage) != C_EQ) { + c_iterAppend(instance->messages, message); + } +} + +static void +handleInstanceMessageBySourceTime( + persistentInstance instance, + v_message message) __nonnull_all__; + +static void +handleInstanceMessageBySourceTime( + persistentInstance instance, + v_message message) +{ + v_message newMessage = v_message(instance->newMessage->message); + + if (os_timeWCompare(message->writeTime, newMessage->writeTime) != OS_LESS) { + c_iterAppend(instance->messages, message); + } +} + +static persistentInstance +persistentInstanceRead( + const d_storeXML persistentStore, + const v_groupAction msg, + InstanceReadCallback action) __nonnull((1,2)); + +static persistentInstance +persistentInstanceRead( + const d_storeXML persistentStore, + const v_groupAction msg, + InstanceReadCallback action) +{ + persistentInstance instance; + v_group group; + FILE *fdes, *tmpfdes; + c_char *data, *partition, *topic; + c_type type; + sd_serializer serializer; + v_message perData; + sd_serializedData serData; + c_long status1; + persistentInstance pInstance; + c_bool success; + c_bool reported = FALSE; + + instance = persistentInstanceNew(msg); + group = msg->group; + partition = v_partitionName(v_groupPartition(group)); + topic = v_topicName(v_groupTopic(group)); + + fdes = openPersistentFile(persistentStore, partition, topic, "r"); + tmpfdes = openPersistentTempFile(persistentStore, partition, topic, "w"); + + if(fdes && tmpfdes) { + type = v_topicMessageType(group->topic); + data = persistentStore->dataBuffer; + data[0] = '\0'; + + if (data == NULL) { + d_storeReport(d_store(persistentStore), + D_LEVEL_SEVERE, + RR_COULD_NOT_READ_TOPIC" \n", + topic); + OS_REPORT(OS_ERROR, STORE_READ_TOPIC_XML, 0, + RR_COULD_NOT_READ_TOPIC" \n", topic); + } else { + c_type xmsgType; + xmsgType = v_messageExtTypeNew (group->topic); + serializer = sd_serializerXMLNewTyped (xmsgType); + + if(serializer){ + data[0] = '\0'; + readLine(fdes, MAX_MESSAGE_SIZE, data); + status1 = strncmp(data, "", 7); + + if (status1 != 0) { + d_storeReport(d_store(persistentStore), D_LEVEL_SEVERE, + RR_TOPIC_SHOULD_BEGIN_WITH_TOPIC_TAG, topic); + OS_REPORT(OS_ERROR, STORE_READ_TOPIC_XML, 0, + RR_TOPIC_SHOULD_BEGIN_WITH_TOPIC_TAG, topic); + } else { + fprintf(tmpfdes, D_STORE_START_STRING); + data[0] = '\0'; + /* read keys */ + readLine(fdes, MAX_KEY_SIZE, data); + status1 = feof(fdes); + + if(strncmp(data, D_STORE_END_STRING_NO_NL, strlen(D_STORE_END_STRING_NO_NL)) != 0){ + + while (status1 == 0) { + pInstance = persistentInstanceFindKey(instance, data); + + if(pInstance){ + v_messageExt xmsg; + readObject(fdes, MAX_MESSAGE_SIZE, data); + serData = sd_serializerFromString(serializer, data); + xmsg = sd_serializerDeserialize(serializer, serData); + perData = xmsg ? v_messageExtConvertFromExtType (type, xmsg) : NULL; + if (perData) { + if (action) { + action(pInstance, perData); + } + + if(v_stateTest(v_nodeState(perData), L_WRITE)){ + pInstance->writeCount++; + } else if(v_stateTest(v_nodeState(perData), L_DISPOSED)){ + pInstance->disposeCount++; + } else if(v_stateTest(v_nodeState(perData), L_REGISTER)){ + pInstance->registerCount++; + } else if(v_stateTest(v_nodeState(perData), L_UNREGISTER)){ + pInstance->unregisterCount++; + } else { + OS_REPORT(OS_ERROR, "durability", 0, + "Found message with state %d.", + v_nodeState(perData)); + assert(FALSE); + } + } else { + /* Could not create message. Thus keep message in store */ + fprintf(tmpfdes, "%s\n", data); /* write keys */ + /* read data */ + readObject(fdes, MAX_MESSAGE_SIZE, data); + fprintf(tmpfdes, "%s\n", data); /* write data */ + if (!reported) { + OS_REPORT(OS_CRITICAL, D_CONTEXT, U_RESULT_OUT_OF_MEMORY, + "Failed to create message for '%s.%s': out of memory.", + partition, topic); + reported = TRUE; + } + } + sd_serializedDataFree(serData); + } else { + fprintf(tmpfdes, "%s\n", data); /* write keys */ + /* read data */ + readObject(fdes, MAX_MESSAGE_SIZE, data); + fprintf(tmpfdes, "%s\n", data); /* write data */ + } + data[0] = '\0'; + /* read keys */ + readLine(fdes, MAX_KEY_SIZE, data); + status1 = feof(fdes); + + if(status1 == 0){ + if(strncmp(data, D_STORE_END_STRING_NO_NL, strlen(D_STORE_END_STRING_NO_NL)) == 0){ + status1 = -1; + } + } + } + } + } + sd_serializerFree(serializer); + } + v_messageExtTypeFree (xmsgType); + } + closeFile(persistentStore, fdes); + closeFile(persistentStore, tmpfdes); + } else { + d_storeReport(d_store(persistentStore), D_LEVEL_FINE, + "No data exists yet on disk for group '%s.%s' (2)\n", partition, topic); + success = createDirectoryIfNecessary(persistentStore, partition); + + if(success){ + success = storeTopicMetadata(persistentStore, group); + + if(success){ + tmpfdes = openPersistentTempFile(persistentStore, partition, topic, "w"); + + if(tmpfdes){ + fprintf(tmpfdes, D_STORE_START_STRING); + closeFile(persistentStore, tmpfdes); + } + } + } + } + return instance; +} + +static d_storeResult +persistentInstanceStore( + const d_storeXML persistentStore, + persistentInstance instance) +{ + FILE* tmpfdes; + v_group group; + sd_serializer serializer; + sd_serializedData serData; + c_char *partition, *topic, *data; + d_storeResult result; + c_bool renameSuccess; + v_message message; + + group = instance->newMessage->group; + partition = v_partitionName(v_groupPartition(group)); + topic = v_topicName(v_groupTopic(group)); + + tmpfdes = openPersistentTempFile(persistentStore, partition, topic, "a"); + + if(tmpfdes){ + c_type xmsgType; + xmsgType = v_messageExtTypeNew (group->topic); + serializer = sd_serializerXMLNewTyped(xmsgType); + + if(serializer){ + message = (v_message)c_iterTakeFirst(instance->messages); + + while(message){ + v_messageExt xmsg = v_messageExtCopyToExtType (xmsgType, message); + serData = sd_serializerSerialize(serializer, (c_object)xmsg); + v_messageExtFree (xmsg); + data = sd_serializerToString(serializer, serData); + + if(data){ + fprintf(tmpfdes, "%s\n%s\n", instance->keyValue, data); + sd_serializedDataFree(serData); + os_free(data); + } + if(message != instance->newMessage->message){ + c_free(message); + } + message = (v_message)c_iterTakeFirst(instance->messages); + } + sd_serializerFree(serializer); + fprintf(tmpfdes, D_STORE_END_STRING); + closeFile(persistentStore, tmpfdes); + renameSuccess = renameTempToActual(persistentStore, partition, topic); + + if(renameSuccess == TRUE){ + result = D_STORE_RESULT_OK; + } else { + result = D_STORE_RESULT_IO_ERROR; + } + } else { + result = D_STORE_RESULT_OUT_OF_RESOURCES; + } + + v_messageExtTypeFree (xmsgType); + } else { + result = D_STORE_RESULT_MUTILATED; + } + return result; +} + +static d_storeResult +appendMessage( + const d_storeXML persistentStore, + const v_groupAction msg) +{ + FILE *fdes; + c_char *data, *partition, *topic, *keys; + sd_serializer serializer; + sd_serializedData serData; + d_storeResult result; + c_bool success; + int res; + + partition = v_partitionName(v_groupPartition(msg->group)); + topic = v_topicName(v_groupTopic(msg->group)); + fdes = openPersistentFile(persistentStore, partition, topic, "r+"); + + if(!fdes){ + d_storeReport(d_store(persistentStore), D_LEVEL_FINE, "No data exists yet on disk for group '%s.%s' (2)\n", partition, topic); + success = createDirectoryIfNecessary(persistentStore, partition); + + if(success){ + success = storeTopicMetadata(persistentStore, msg->group); + + if(success) { + fdes = openPersistentFile(persistentStore, partition, topic, "w"); + + if(fdes){ + c_type xmsgType = v_messageExtTypeNew (v_groupTopic (msg->group)); + fprintf(fdes, D_STORE_START_STRING); + serializer = sd_serializerXMLNewTyped(xmsgType); + + if(serializer){ + v_messageExt xmsg = v_messageExtCopyToExtType (xmsgType, msg->message); + serData = sd_serializerSerialize(serializer, (c_object)xmsg); + v_messageExtFree (xmsg); + + if(serData){ + data = sd_serializerToString(serializer, serData); + + if(data){ + keys = determineInstance(msg); + + if(keys){ + fprintf(fdes, "%s\n%s\n", keys, data); + fprintf(fdes, D_STORE_END_STRING); + os_free(keys); + closeFile(persistentStore, fdes); + result = D_STORE_RESULT_OK; + } else { + result = D_STORE_RESULT_OUT_OF_RESOURCES; + } + os_free(data); + } else { + result = D_STORE_RESULT_OUT_OF_RESOURCES; + } + sd_serializedDataFree(serData); + } else { + result = D_STORE_RESULT_OUT_OF_RESOURCES; + } + sd_serializerFree(serializer); + } else { + result = D_STORE_RESULT_OUT_OF_RESOURCES; + } + + v_messageExtTypeFree (xmsgType); + } else { + d_storeReport(d_store(persistentStore), D_LEVEL_SEVERE, + "Unable to open persistent file for writing for group '%s.%s' (2)\n", + partition, topic); + OS_REPORT(OS_ERROR, D_CONTEXT, 0, + "Unable to open persistent file for writing for group '%s.%s' (2)\n", + partition, topic); + result = D_STORE_RESULT_IO_ERROR; + } + } else { + result = D_STORE_RESULT_IO_ERROR; + } + } else { + result = D_STORE_RESULT_IO_ERROR; + } + } else { + c_type xmsgType; + res = fseek(fdes, D_SEEK_LENGTH, SEEK_END); + assert(res == 0); + (void)res; + + xmsgType = v_messageExtTypeNew (v_groupTopic(msg->group)); + serializer = sd_serializerXMLNewTyped(xmsgType); + + if(serializer){ + v_messageExt xmsg = v_messageExtCopyToExtType (xmsgType, msg->message); + serData = sd_serializerSerialize(serializer, (c_object)xmsg); + v_messageExtFree (xmsg); + + if(serData){ + data = sd_serializerToString(serializer, serData); + + if(data){ + keys = determineInstance(msg); + + if(keys){ + fprintf(fdes, "%s\n%s\n", keys, data); + fprintf(fdes, D_STORE_END_STRING); + os_free(keys); + closeFile(persistentStore, fdes); + result = D_STORE_RESULT_OK; + } else { + result = D_STORE_RESULT_OUT_OF_RESOURCES; + } + os_free(data); + } else { + result = D_STORE_RESULT_OUT_OF_RESOURCES; + } + sd_serializedDataFree(serData); + } else { + result = D_STORE_RESULT_OUT_OF_RESOURCES; + } + sd_serializerFree(serializer); + } else { + result = D_STORE_RESULT_OUT_OF_RESOURCES; + } + + v_messageExtTypeFree (xmsgType); + } + return result; +} + +static d_storeResult +expungeMessage( + const d_storeXML persistentStore, + const v_groupAction msg, + c_bool messageOnly) +{ + persistentInstance instance; + v_topicQos qos; + d_storeResult result; + v_group group; + + if (msg->message) { + if (messageOnly) { + instance = persistentInstanceRead(persistentStore, msg, handleInstanceMessageByMessage); + } else { + group = v_group(msg->group); + qos = v_topicQosRef(group->topic); + + if(qos->orderby.v.kind == V_ORDERBY_RECEPTIONTIME) { + instance = persistentInstanceRead(persistentStore, msg, NULL); + } else { + instance = persistentInstanceRead(persistentStore, msg, handleInstanceMessageBySourceTime); + } + } + + if(instance){ + result = persistentInstanceStore(persistentStore, instance); + persistentInstanceFree(instance); + } else { + result = D_STORE_RESULT_OUT_OF_RESOURCES; + } + } else { + result = D_STORE_RESULT_OUT_OF_RESOURCES; + } + return result; +} + +static d_storeResult +expungeMessageOptimized( + const d_storeXML persistentStore, + const v_groupAction msg, + c_bool messageOnly) +{ + d_storeResult result; + + if(persistentStore->sessionAlive == TRUE){ + groupExpungeActionsAdd(persistentStore, msg); + result = D_STORE_RESULT_OK; + } else { + result = expungeMessage(persistentStore, msg, messageOnly); + } + return result; +} + +static c_bool +processExpungeAction( + groupExpungeActions g, + d_storeXML persistentStore) +{ + FILE *fdes, *tmpfdes; + c_char *data, *partition, *topic, *key; + c_type type; + sd_serializer serializer; + v_message perData; + sd_serializedData serData; + c_long status1; + int cleanupCount, totalCount; + persistentInstance pInstance, instance; + + partition = g->partition; + topic = g->topic; + cleanupCount = 0; + totalCount = 0; + + fdes = openPersistentFile(persistentStore, partition, topic, "r"); + tmpfdes = openPersistentTempFile(persistentStore, partition, topic, "w"); + + if(fdes && tmpfdes) { + pInstance = d_tableFirst(g->instances); + + if(pInstance && pInstance->newMessage){ + c_type xmsgType; + + type = c_getType(pInstance->newMessage->message); + xmsgType = v_messageExtTypeNew (v_groupTopic(pInstance->newMessage->group)); + pInstance = NULL; + + data = persistentStore->dataBuffer; + key = persistentStore->keyBuffer; + data[0] = '\0'; + key[0] = '\0'; + + serializer = sd_serializerXMLNewTyped(xmsgType); + if(serializer){ + readLine(fdes, MAX_MESSAGE_SIZE, data); + status1 = strncmp(data, "", 7); + + if (status1 != 0) { + d_storeReport(d_store(persistentStore), D_LEVEL_SEVERE, + RR_TOPIC_SHOULD_BEGIN_WITH_TOPIC_TAG, topic); + OS_REPORT(OS_ERROR, STORE_READ_TOPIC_XML, 0, + RR_TOPIC_SHOULD_BEGIN_WITH_TOPIC_TAG, topic); + } else { + fprintf(tmpfdes, D_STORE_START_STRING); + data[0] = '\0'; + key[0] = '\0'; + /* read keys */ + readLine(fdes, MAX_KEY_SIZE, key); + status1 = feof(fdes); + + if(strncmp(key, D_STORE_END_STRING_NO_NL, strlen(D_STORE_END_STRING_NO_NL)) != 0){ + while (status1 == 0) { + instance = persistentInstanceDummyNew(key); + pInstance = d_tableFind(g->instances, instance); + persistentInstanceFree(instance); + + if(pInstance){ + c_bool doWrite = FALSE; + v_messageExt xmsg; + readObject(fdes, MAX_MESSAGE_SIZE, data); + serData = sd_serializerFromString(serializer, data); + xmsg = sd_serializerDeserialize(serializer, serData); + perData = xmsg ? v_messageExtConvertFromExtType (type, xmsg) : NULL; + sd_serializedDataFree(serData); + + if (perData) { + switch(pInstance->newMessage->kind){ + case V_GROUP_ACTION_CLEANUP_DELAY_EXPIRE: + doWrite = (os_timeECompare(perData->allocTime, pInstance->newMessage->actionTime) == OS_MORE); + break; + case V_GROUP_ACTION_LIFESPAN_EXPIRE: + doWrite = (os_timeWCompare(perData->writeTime, pInstance->newMessage->message->writeTime) == OS_MORE); + break; + default: + /* Message should not be in this list */ + assert(pInstance->newMessage->kind == pInstance->newMessage->kind || + pInstance->newMessage->kind == V_GROUP_ACTION_LIFESPAN_EXPIRE); + break; + } + } else { + doWrite = TRUE; + OS_REPORT(OS_CRITICAL, D_CONTEXT, U_RESULT_OUT_OF_MEMORY, + "Failed to determine for topic '%s.%s' the sample expiry time: out of memory.", + partition, topic); + } + + if(doWrite){ + /* write it */ + fprintf(tmpfdes, "%s\n", key); /* write keys */ + fprintf(tmpfdes, "%s\n", data); /* write data */ + } else { + /*throw away*/ + cleanupCount++; + } + c_free(perData); + totalCount++; + } else { + fprintf(tmpfdes, "%s\n", key); /* write keys */ + /* read data */ + readObject(fdes, MAX_MESSAGE_SIZE, data); + fprintf(tmpfdes, "%s\n", data); /* write data */ + } + + data[0] = '\0'; + key[0] = '\0'; + /* read keys */ + readLine(fdes, MAX_KEY_SIZE, key); + status1 = feof(fdes); + + if(status1 == 0){ + if(strncmp(key, D_STORE_END_STRING_NO_NL, strlen(D_STORE_END_STRING_NO_NL)) == 0){ + status1 = -1; + } + } + } + } + } + sd_serializerFree(serializer); + } else { + d_storeReport(d_store(persistentStore), D_LEVEL_SEVERE, + "Unable to allocate serializer\n"); + } + fprintf(tmpfdes, D_STORE_END_STRING); + + v_messageExtTypeFree (xmsgType); + } else { + d_storeReport(d_store(persistentStore), D_LEVEL_SEVERE, + "Unable to get instance for group %s.%s' (2)\n", partition, topic); + } + closeFile(persistentStore, fdes); + closeFile(persistentStore, tmpfdes); + renameTempToActual(persistentStore, partition, topic); + } else { + d_storeReport(d_store(persistentStore), D_LEVEL_FINE, "No data exists yet on disk for group '%s.%s' (2)\n", partition, topic); + } + return TRUE; +} + +static c_bool +processGroupExpungeActions( + d_storeXML persistentStore) +{ + c_bool result; + + result = d_tableWalk(persistentStore->expungeActions, processExpungeAction, persistentStore); + + return result; +} + +/* Helper struct for unregister walk function */ +typedef struct unregisterFindData +{ + v_message writeMsg; + v_message unregisterMsg; +} unregisterFindData; + +/* Search for a writer in registration list */ +static void +unregisterLookupWalk ( + void* o, + c_iterActionArg userData) +{ + unregisterFindData* walkData; + v_message message; + + message = v_message(o); + walkData = (unregisterFindData*)userData; + + /* Only search if no unregister message has is found */ + if (!(walkData->unregisterMsg)) + { + /* If message is a unregister message and has equal GID, + * this is a valid unregister message for writeMessage + */ + if (message && + (v_stateTest(v_nodeState(message), L_UNREGISTER)) && + (v_gidEqual(walkData->writeMsg->writerGID, message->writerGID))) { + + walkData->unregisterMsg = message; + } + } +} + +/* Create unregister message from write message */ +static v_message +createUnregisterMessage( + v_group group, + v_message message) +{ + c_array messageKeyList; + c_ulong i, nrOfKeys; + v_message unregisterMessage; + + assert(!v_stateTest(v_nodeState(message), L_UNREGISTER)); + + /* Create new message objec */ + unregisterMessage = v_topicMessageNew_s + (group->topic); + if (unregisterMessage) { + /* Copy keyvalues to unregistermessage */ + messageKeyList = v_topicMessageKeyList(v_groupTopic(group)); + nrOfKeys = c_arraySize(messageKeyList); + for (i=0;iwriterGID = + message->writerGID; + unregisterMessage->writerInstanceGID = + message->writerInstanceGID; + + /* Copy messageQos */ + c_keep (message->qos); + unregisterMessage->qos = message->qos; + + /* Set nodestate to unregister */ + v_nodeState(unregisterMessage) = L_UNREGISTER; + } + + return unregisterMessage; +} + +/* PRE: The v_group exists */ +static d_storeResult +d_storeXMLOptimizeGroup( + d_storeXML persistentStore, + v_group group, + d_partition partition, + d_topic topic, + c_bool inject, + c_bool optimize, + c_ulong dataVersion) +{ + FILE * fdes, *tmpfdes; + c_char * data, *data2, *newKeyList; + c_long len; + c_type type; + sd_serializer serializer; + v_message message, perData; + sd_serializedData serData; + c_long status1, status2; + c_bool renameSuccess, added; + d_storeResult result; + d_table instances; + persistentInstance dummy, instance; + v_topicQos topicQos; + os_timeM optimizeTime; + v_writeResult wr; + unregisterFindData walkData; + c_bool reported = FALSE; + d_thread self = d_threadLookupSelf(); + + message = NULL; + perData = NULL; + result = D_STORE_RESULT_OK; + tmpfdes = NULL; + len = openFile(persistentStore, group, &fdes); + + /* Do not create temporary file for optimizing when no optimization is required */ + if (optimize) { + tmpfdes = openPersistentTempFile(persistentStore, partition, topic, "w"); + } + + /* Store file exists and is not empty, if store needs optimization tmp file must exist */ + if ((len > 0) && fdes && (tmpfdes || !optimize)) { + type = v_topicMessageType(group->topic); + topicQos = v_topicQosRef(group->topic); + data = (c_char *)d_malloc((os_uint32)(len + EXTRA_BACKSLS), "readData"); + if (data == NULL) { + result = D_STORE_RESULT_OUT_OF_RESOURCES; + d_storeReport(d_store(persistentStore), D_LEVEL_SEVERE, "No more resources\n"); + OS_REPORT(OS_ERROR, D_CONTEXT, 0, "No more resources available\n"); + + } else { + c_type xmsgType = v_messageExtTypeNew(group->topic); + serializer = sd_serializerXMLNewTyped(xmsgType); + + if(serializer){ + data[0] = '\0'; + readLine(fdes, (size_t) len, data); + status1 = strncmp(data, "", 7); + + if (status1 != 0) { + result = D_STORE_RESULT_MUTILATED; + d_storeReport(d_store(persistentStore), D_LEVEL_SEVERE, + RR_TOPIC_SHOULD_BEGIN_WITH_TOPIC_TAG, topic); + OS_REPORT(OS_ERROR, STORE_READ_TOPIC_XML, 0, + RR_TOPIC_SHOULD_BEGIN_WITH_TOPIC_TAG, topic); + } else { + instances = d_tableNew(persistentInstanceCompare, persistentInstanceFree); + data[0] = '\0'; + readLine(fdes, (size_t) len, data); /* read keys */ + status1 = feof(fdes); + + while (status1 == 0) { + if(dataVersion < 6){ + /* convert key-values */ + newKeyList = NULL; + (void)convertOldToNewKeyList(data, &newKeyList); + dummy = persistentInstanceDummyNew(newKeyList); + os_free(newKeyList); + } else { + dummy = persistentInstanceDummyNew(data); + } + instance = d_tableInsert(instances, dummy); + + if(instance){ + persistentInstanceFree(dummy); + } else { + instance = dummy; + } + data[0] = '\0'; + readObject(fdes, (size_t) len, data); /* read object*/ + status2 = strncmp(data, "", 8); + + if (status2 == 0) { + serData = sd_serializerFromString(serializer, data); + + if(serData){ + v_messageExt xmsg; + xmsg = sd_serializerDeserialize(serializer, serData); + perData = xmsg ? v_messageExtConvertFromExtType (type, xmsg) : NULL; + if(perData) { + /* Dispose messages caused by dispose_all_data have no inline qos, + * but make sure all the other messages do. + */ + if (perData->qos != NULL || (v_nodeState(perData) == L_DISPOSED && v_nodeState(perData) != L_WRITE)) { + added = persistentInstanceInsert(instance, topicQos, perData); + if(!added){ + c_free(perData); + } + } else { + OS_REPORT(OS_ERROR, D_CONTEXT, 0, + "Data for group '%s.%s' on disk is mutilated. " + "Found valid data without QoS value.", + partition, topic); + assert(0); + c_free(perData); + } + + } else if (!reported) { + OS_REPORT(OS_ERROR, D_CONTEXT, 0, + "Data for group '%s.%s' on disk is mutilated. " + "Some data might be lost.", + partition, topic); + d_storeReport(d_store(persistentStore), D_LEVEL_SEVERE, + "Data for group '%s.%s' on disk is mutilated. " + "Some data might be lost.\n", + partition, topic); + reported = TRUE; + } + sd_serializedDataFree(serData); + } + } + data[0] = '\0'; + readLine(fdes, (size_t) len, data); /* read keys */ + status1 = feof(fdes); + } + closeFile(persistentStore, fdes); + + d_storeReport(d_store(persistentStore), D_LEVEL_FINEST, + "Optimizing: found %d instances for group '%s.%s'\n", + d_tableSize(instances), + partition, topic); + + perData = NULL; + + if (optimize) { + fprintf(tmpfdes, D_STORE_START_STRING); + } + + if(serializer){ + instance = d_tableTake(instances); + + while(instance){ + message = (v_message)c_iterTakeFirst(instance->messages); + + while(message){ + /* Inject data */ + if(inject == TRUE){ + c_base base = c_getBase(group); + + do { + if (c_baseMakeMemReservation(base, C_MM_RESERVATION_ZERO)) { + wr = v_groupWriteNoStream(group, message, NULL, V_NETWORKID_ANY); + if (wr == V_WRITE_REJECTED) { + d_sleep(self, OS_DURATION_INIT(1,0)); + } + c_baseReleaseMemReservation(base, C_MM_RESERVATION_ZERO); + } else { + wr = V_WRITE_OUT_OF_RESOURCES; + } + } while (wr == V_WRITE_REJECTED); + + if((wr != V_WRITE_SUCCESS) && + (wr != V_WRITE_REGISTERED) && + (wr != V_WRITE_UNREGISTERED)) { + OS_REPORT(OS_ERROR, D_CONTEXT, 0, + "Unable to write persistent data to group. (result: '%d')\n", + wr); + result = D_STORE_RESULT_ERROR; + } else { + /* If a sample is written or registered, add unregister action */ + if (!v_stateTest(v_nodeState(message), L_UNREGISTER)) { + /* Prepare walkdata */ + walkData.writeMsg = message; + walkData.unregisterMsg = NULL; + + /* Lookup unregister message */ + c_iterWalk ( + instance->messages, + unregisterLookupWalk, + &walkData); + + /* Create unregister message if none found */ + if (!(walkData.unregisterMsg)) { + walkData.unregisterMsg = + createUnregisterMessage (group, message); + if (walkData.unregisterMsg) { + c_iterAppend (instance->messages, walkData.unregisterMsg); + } else { + OS_REPORT(OS_ERROR, D_CONTEXT, U_RESULT_OUT_OF_MEMORY, + "Unable to write persistent data to group: out of memory\n"); + result = D_STORE_RESULT_ERROR; + } + } + + if (walkData.unregisterMsg) { + /* Set valid sequence number */ + if (message->sequenceNumber >= + walkData.unregisterMsg->sequenceNumber) { + walkData.unregisterMsg->sequenceNumber = + message->sequenceNumber + 1; + } + + /* Set valid write time */ + if (os_timeWCompare (walkData.unregisterMsg->writeTime, message->writeTime) == OS_LESS) { + walkData.unregisterMsg->writeTime = message->writeTime; + } + walkData.unregisterMsg->allocTime = os_timeEGet(); + } + } + } + } + + /* Write optimized data */ + if (optimize) { + v_messageExt xmsg; + xmsg = v_messageExtCopyToExtType (xmsgType, message); + serData = sd_serializerSerialize(serializer, (c_object) xmsg); + v_messageExtFree (xmsg); + + if(serData){ + data2 = sd_serializerToString(serializer, serData); + + if(data2){ + fprintf(tmpfdes, "%s\n%s\n", instance->keyValue, data2); + os_free(data2); + } + sd_serializedDataFree(serData); + c_free(message); + } + } + message = (v_message)c_iterTakeFirst(instance->messages); + } + + persistentInstanceFree(instance); + instance = d_tableTake(instances); + } + d_tableFree(instances); + } else { + result = D_STORE_RESULT_OUT_OF_RESOURCES; + } + + if (optimize) + { + fprintf(tmpfdes, D_STORE_END_STRING); + closeFile(persistentStore, tmpfdes); + renameSuccess = renameTempToActual(persistentStore, partition, topic); + + if(renameSuccess == TRUE && optimize){ + optimizeTime = os_timeMGet(); + result = setOptimizeTime(persistentStore, partition, topic, optimizeTime); + } else { + result = D_STORE_RESULT_IO_ERROR; + } + } + } + sd_serializerFree(serializer); + } else { + result = D_STORE_RESULT_OUT_OF_RESOURCES; + } + v_messageExtTypeFree (xmsgType); + } + d_free(data); + } else if(len == -1) { + d_storeReport(d_store(persistentStore), D_LEVEL_FINE, "No data exists yet on disk for group %s.%s\n", partition, topic); + result = D_STORE_RESULT_OK; + } + return result; +} + +/* PRE: The v_group exists */ +static d_storeResult +d_storeXMLInjectTopicXML( + d_storeXML persistentStore, + v_group group, + d_partition partition, + d_topic topic ) +{ + c_type type; + c_bool check; + d_storeResult result; + c_char* keys; + c_bool optimized; + c_ulong dataVersion; + + optimized = isOptimized(persistentStore, partition, topic); + + result = getDataVersion(persistentStore, partition, topic, &dataVersion); + + if(result == D_STORE_RESULT_OK){ + type = v_topicMessageType(group->topic); + keys = v_topicKeyExpr(group->topic); + + if(!keys){ + check = metaDataIsCorrect(type, persistentStore, topic, partition, + "", v_topicQosRef(group->topic)); + } else { + check = metaDataIsCorrect(type, persistentStore, topic, partition, + keys, v_topicQosRef(group->topic)); + } + if (check == FALSE) { + d_storeReport(d_store(persistentStore), D_LEVEL_SEVERE, RR_META_DATA_MISMATCH, topic); + OS_REPORT(OS_ERROR, STORE_READ_TOPIC_XML, 0, RR_META_DATA_MISMATCH, topic); + result = D_STORE_RESULT_METADATA_MISMATCH; + /* metaData is not OK: should the maintainer remove topic and meta data ?? */ + } else { + /* Inject XML and optimize if necessary */ + result = d_storeXMLOptimizeGroup(persistentStore, group, partition, topic, TRUE, !optimized, dataVersion); + } + } else if(result == D_STORE_RESULT_PRECONDITION_NOT_MET){ + /* There is no data on disk for this group, so all is well. */ + result = D_STORE_RESULT_OK; + } else { + d_storeReport(d_store(persistentStore), D_LEVEL_SEVERE, "Unable to resolve persistent data version."); + OS_REPORT(OS_ERROR, STORE_READ_TOPIC_XML, 0, "Unable to resolve persistent data version."); + } + return result; +/* QAC EXPECT 5102; too many local variables */ +} + +static void +d_storeXMLInitGroups( + d_storeXML store) +{ + forAllDirectoryEntries(store, d_store(store)->config->persistentStoreDirectory, + NULL, processPartition, TRUE); +} + +static d_storeResult +d_storeGetQualityXMLUnlocked( + const d_groupList list, + const d_nameSpace nameSpace, + d_quality* quality) +{ + d_groupList groupList; + c_bool isIn; + + *quality = D_QUALITY_ZERO; + + groupList = list; + + while(groupList) { + isIn = d_nameSpaceIsIn(nameSpace, groupList->partition, groupList->topic); + if(isIn == TRUE){ + if (d_qualityCompare(groupList->quality, *quality) == OS_MORE) { + *quality = groupList->quality; + } + } + groupList = d_groupList(groupList->next); + } + return D_STORE_RESULT_OK; +} + +static void +correctGroupQuality( + d_nameSpace nameSpace, + c_voidp userData) +{ + d_groupList list, next; + c_bool isIn; + d_quality quality; + + list = d_groupList(userData); + + next = list; + + while(next){ + isIn = d_nameSpaceIsIn(nameSpace, next->partition, next->topic); + + if(isIn == TRUE){ + d_storeGetQualityXMLUnlocked(list, nameSpace, &quality); + if (d_qualityCompare(quality, next->quality) == OS_MORE) { + next->quality = quality; + } + } + next = next->next; + } +} + +d_storeXML +d_storeNewXML(u_participant participant) +{ + d_storeXML storeXML; + d_store store; + os_result resultInit; + + OS_UNUSED_ARG(participant); + + storeXML = d_storeXML(os_malloc(C_SIZEOF(d_storeXML))); + store = d_store(storeXML); + d_storeInit(store, (d_objectDeinitFunc)d_storeDeinitXML); + + storeXML->diskStorePath = NULL; + storeXML->maxPathLen = 0; + storeXML->groups = NULL; + storeXML->opened = FALSE; + storeXML->sessionAlive = FALSE; + storeXML->openedFiles = NULL; + storeXML->dummyFile = d_storeFileNew("", NULL, NULL); + os_free(storeXML->dummyFile->path); + storeXML->dummyFile->path = NULL; + storeXML->dataBuffer = (c_char *)os_malloc((os_uint32)MAX_MESSAGE_SIZE); + assert(storeXML->dataBuffer); + storeXML->keyBuffer = (c_char *)os_malloc((os_uint32)MAX_KEY_SIZE); + assert(storeXML->keyBuffer); + resultInit = os_mutexInit(&(storeXML->mutex), NULL); + if(resultInit != os_resultSuccess) + { + OS_REPORT(OS_ERROR, "durability", 0, "Failed to init mutex for XML store."); + } + store->openFunc = d_storeOpenXML; + store->closeFunc = d_storeCloseXML; + store->groupsReadFunc = d_storeGroupsReadXML; + store->groupListFreeFunc = NULL; + store->groupInjectFunc = d_storeGroupInjectXML; + store->groupStoreFunc = d_storeGroupStoreXML; + store->getQualityFunc = d_storeGetQualityXML; + store->backupFunc = d_storeBackupXML; + store->restoreBackupFunc = d_storeRestoreBackupXML; + store->actionStartFunc = d_storeActionStartXML; + store->actionStopFunc = d_storeActionStopXML; + store->messageStoreFunc = d_storeMessageStoreXML; + store->instanceDisposeFunc = d_storeInstanceDisposeXML; + store->instanceExpungeFunc = d_storeInstanceExpungeXML; + store->messageExpungeFunc = d_storeMessageExpungeXML; + store->deleteHistoricalDataFunc = d_storeDeleteHistoricalDataXML; + store->messagesInjectFunc = d_storeMessagesInjectXML; + store->instanceRegisterFunc = d_storeInstanceRegisterXML; + store->createPersistentSnapshotFunc = d_storeCreatePersistentSnapshotXML; + store->instanceUnregisterFunc = d_storeInstanceUnregisterXML; + store->optimizeGroupFunc = d_storeOptimizeGroupXML; + store->nsIsCompleteFunc = d_storeNsIsCompleteXML; + store->nsMarkCompleteFunc = d_storeNsMarkCompleteXML; + store->transactionCompleteFunc = NULL; /* unsupported for XML store */ + store->messagesLoadFunc = NULL; + store->messagesLoadFlushFunc = NULL; + + return storeXML; +} + +void +d_storeDeinitXML( + d_storeXML store) +{ + assert(d_objectIsValid(d_object(store), D_STORE)); + assert(d_store(store)->type == D_STORE_TYPE_XML); + + d_storeFileFree(store->dummyFile); + os_free(store->dataBuffer); + os_free(store->keyBuffer); + os_mutexDestroy (&(store->mutex)); + /* Call super-deinit */ + d_storeDeinit(d_store(store)); +} + +d_storeResult +d_storeFreeXML( + d_storeXML store) +{ + d_storeResult result; + + assert(d_objectIsValid(d_object(store), D_STORE)); + assert(d_store(store)->type == D_STORE_TYPE_XML); + + if(store) { + d_lockLock(d_lock(store)); + + if(store->opened == TRUE) { + d_lockUnlock(d_lock(store)); + result = D_STORE_RESULT_PRECONDITION_NOT_MET; + } else { + d_lockUnlock(d_lock(store)); + + d_objectFree(d_object(store)); + result = D_STORE_RESULT_OK; + } + } else { + result = D_STORE_RESULT_ILL_PARAM; + } + return result; +} + +d_storeResult +d_storeOpenXML( + d_store store) +{ + d_storeResult result; + d_storeXML storeXML; + c_char* resultDir; + + assert(d_objectIsValid(d_object(store), D_STORE)); + assert(store->type == D_STORE_TYPE_XML); + + if(store != NULL){ + storeXML = d_storeXML(store); + d_lockLock(d_lock(store)); + + if(storeXML->opened == TRUE) { + result = D_STORE_RESULT_PRECONDITION_NOT_MET; + } else if(store->config->persistentStoreDirectory == NULL ){ + result = D_STORE_RESULT_ILL_PARAM; + } else { + resultDir = d_storeDirNew(store, store->config->persistentStoreDirectory); + + if(resultDir){ + os_free(store->config->persistentStoreDirectory); + store->config->persistentStoreDirectory = resultDir; + d_storeReport(store, D_LEVEL_INFO, + "Persistent store directory '%s' openened.\n", + store->config->persistentStoreDirectory); + storeXML->opened = TRUE; + result = D_STORE_RESULT_OK; + } else { + d_storeReport(store, D_LEVEL_SEVERE, + "Persistent store directory '%s' could not be created.\n", + store->config->persistentStoreDirectory); + result = D_STORE_RESULT_PRECONDITION_NOT_MET; + } + } + if(result == D_STORE_RESULT_OK) { + storeXML->maxPathLen = (c_ulong)D_PERSISTENT_STORE_DIR_SIZE + + (c_ulong)strlen(store->config->persistentStoreDirectory); + + storeXML->diskStorePath = (c_char *)os_malloc((os_uint32) + ((c_long)strlen(store->config->persistentStoreDirectory) + 1)); + os_strncpy(storeXML->diskStorePath, store->config->persistentStoreDirectory, + (os_uint32)((c_long)strlen(store->config->persistentStoreDirectory)+1)); + d_storeXMLInitGroups(storeXML); + + /* Walk namespaces in administration */ + d_adminNameSpaceWalk (store->admin, correctGroupQuality, storeXML->groups); + } + + d_lockUnlock(d_lock(store)); + } else { + d_storeReport(store, D_LEVEL_SEVERE, "Supplied parameter(s) not valid.\n"); + result = D_STORE_RESULT_ILL_PARAM; + } + return result; +} + +d_storeResult +d_storeCloseXML( + d_store store) +{ + d_storeResult result; + d_groupList groupList, next; + + assert(d_objectIsValid(d_object(store), D_STORE)); + assert(store->type == D_STORE_TYPE_XML); + + if(store != NULL){ + d_lockLock(d_lock(store)); + if(d_storeXML(store)->opened == FALSE) { + result = D_STORE_RESULT_PRECONDITION_NOT_MET; + } else { + if(d_storeXML(store)->sessionAlive == TRUE){ + actionStopUnlocked(d_storeXML(store)); + } + d_storeXML(store)->opened = FALSE; + os_free(d_storeXML(store)->diskStorePath); + d_storeXML(store)->diskStorePath = NULL; + + groupList = d_storeXML(store)->groups; + + while(groupList){ + next = groupList->next; + os_free(groupList->partition); + os_free(groupList->topic); + os_free(groupList); + groupList = next; + } + result = D_STORE_RESULT_OK; + } + d_lockUnlock(d_lock(store)); + } else { + result = D_STORE_RESULT_ILL_PARAM; + } + return result; +} + +d_storeResult +d_storeActionStartXML( + const d_store store) +{ + d_storeResult result; + + assert(d_objectIsValid(d_object(store), D_STORE)); + assert(store->type == D_STORE_TYPE_XML); + + if(store != NULL){ + os_mutexLock(&(d_storeXML(store)->mutex)); + d_lockLock(d_lock(store)); + if(d_storeXML(store)->opened == FALSE) { + result = D_STORE_RESULT_PRECONDITION_NOT_MET; + } else { + d_storeXML(store)->sessionAlive = TRUE; + + d_storeXML(store)->openedFiles = d_tableNew(d_storeFileCompare, d_storeFileFree); + d_storeXML(store)->expungeActions = d_tableNew(groupExpungeActionsCompare, groupExpungeActionsFree); + result = D_STORE_RESULT_OK; + } + d_lockUnlock(d_lock(store)); + } else { + result = D_STORE_RESULT_ILL_PARAM; + } + return result; +} + +d_storeResult +d_storeActionStopXML( + const d_store store) +{ + d_storeResult result; + + assert(d_objectIsValid(d_object(store), D_STORE)); + assert(store->type == D_STORE_TYPE_XML); + if(store != NULL){ + d_lockLock(d_lock(store)); + if(d_storeXML(store)->opened == FALSE) { + result = D_STORE_RESULT_PRECONDITION_NOT_MET; + } else { + if(d_storeXML(store)->sessionAlive == TRUE){ + result = actionStopUnlocked(d_storeXML(store)); + processGroupExpungeActions(d_storeXML(store)); + d_tableFree(d_storeXML(store)->expungeActions); + } else { + result = D_STORE_RESULT_OK; + } + } + d_lockUnlock(d_lock(store)); + os_mutexUnlock(&(d_storeXML(store)->mutex)); + } else { + result = D_STORE_RESULT_ILL_PARAM; + } + return result; +} + +d_storeResult +d_storeGroupsReadXML( + const d_store store, + d_groupList *list) +{ + d_storeResult result; + + assert(d_objectIsValid(d_object(store), D_STORE)); + assert(store->type == D_STORE_TYPE_XML); + + if(store != NULL){ + d_lockLock(d_lock(store)); + result = groupsReadXMLUnsafe(store, list); + d_lockUnlock(d_lock(store)); + } else { + result = D_STORE_RESULT_ILL_PARAM; + } + + return result; +} + +d_storeResult +groupsReadXMLUnsafe( + const d_store store, + d_groupList *list) +{ + d_storeResult result; + + assert(d_objectIsValid(d_object(store), D_STORE)); + assert(store->type == D_STORE_TYPE_XML); + + if(store) + { + if(d_storeXML(store)->opened == FALSE) + { + result = D_STORE_RESULT_PRECONDITION_NOT_MET; + } else if(list == NULL) + { + result = D_STORE_RESULT_ILL_PARAM; + } else + { + *list = d_storeXML(store)->groups; + result = D_STORE_RESULT_OK; + } + } else + { + result = D_STORE_RESULT_ILL_PARAM; + } + return result; +} + +d_storeResult +d_storeGroupInjectXML( + const d_store store, + const c_char* partition, + const c_char* topic, + const u_participant participant, + d_group *group) +{ + d_groupList groupList; + d_storeResult result; + d_topicMetadata metadata; + u_topic utopic; + u_group ugroup; + u_partition upartition; + u_partitionQos partitionQos; + + assert(d_objectIsValid(d_object(store), D_STORE)); + assert(store->type == D_STORE_TYPE_XML); + + *group = NULL; + result = D_STORE_RESULT_ERROR; + + if(store != NULL){ + d_lockLock(d_lock(store)); + + if(d_storeXML(store)->opened == FALSE) { + result = D_STORE_RESULT_PRECONDITION_NOT_MET; + } else if((participant == NULL) || (partition == NULL) || (topic == NULL) || (group == NULL)) { + result = D_STORE_RESULT_ILL_PARAM; + } else { + groupList = getPartitionTopic(d_storeXML(store), partition, topic); + + if(groupList) { + metadata = readTopicMetadata(d_storeXML(store), participant, partition, topic); + + if(metadata) { + utopic = u_topicNew(participant, metadata->name, + metadata->typeName, + metadata->keyList, metadata->qos); + if(utopic) { + d_storeReport(store, D_LEVEL_FINE, "Topic %s created.\n", metadata->name); + partitionQos = u_partitionQosNew(NULL); + + if(partitionQos) { + d_storeReport(store, D_LEVEL_FINE, "PartitionQoS created.\n"); + upartition = u_partitionNew(participant, partition, partitionQos); + + if(upartition) { + d_storeReport(store, D_LEVEL_FINE, "Partition %s created.\n", partition); + + ugroup = u_groupNew(participant, partition, topic, 0); + + if(ugroup) { + d_storeReport(store, D_LEVEL_INFO, "Group %s.%s created.\n", partition, metadata->name); + *group = d_groupNew(partition, topic, + D_DURABILITY_PERSISTENT, + groupList->completeness, + groupList->quality); + u_observableAction(u_observable(ugroup), setKernelGroup, *group); + /* FIXME: enable again after fix is in place (See OSPL-2750) + u_objectFree(u_object(ugroup));*/ + result = D_STORE_RESULT_OK; + } else { + d_storeReport(store, D_LEVEL_SEVERE, "Group %s.%s could NOT be created.\n", partition, metadata->name); + } + u_objectFree (u_object (upartition)); + } else { + d_storeReport(store, D_LEVEL_SEVERE, "Partition %s could NOT be created.\n", partition); + } + u_partitionQosFree(partitionQos); + } else { + d_storeReport(store, D_LEVEL_SEVERE, "PartitionQos could NOT be created.\n"); + } + u_objectFree (u_object (utopic)); + } else { + d_storeReport(store, D_LEVEL_SEVERE, + "Topic '%s' with typeName '%s' and keyList '%s' could NOT be created.\n", + metadata->name, metadata->typeName, metadata->keyList); + result = D_STORE_RESULT_METADATA_MISMATCH; + } + os_free(metadata->typeName); + os_free(metadata->name); + os_free(metadata->keyList); + v_topicQosFree(metadata->qos); + c_free(metadata->type); + os_free(metadata); + } else { + result = D_STORE_RESULT_MUTILATED; + } + } + } + d_lockUnlock(d_lock(store)); + } else { + result = D_STORE_RESULT_ILL_PARAM; + } + return result; +} + +d_storeResult +d_storeGetQualityXML( + const d_store store, + const d_nameSpace nameSpace, + d_quality* quality) +{ + d_storeResult result; + + assert(d_objectIsValid(d_object(store), D_STORE)); + assert(store->type == D_STORE_TYPE_XML); + + if(store != NULL){ + d_lockLock(d_lock(store)); + + if(d_storeXML(store)->opened == FALSE) { + result = D_STORE_RESULT_PRECONDITION_NOT_MET; + } else if((quality == NULL) || (nameSpace == NULL)) { + result = D_STORE_RESULT_ILL_PARAM; + } else { + result = d_storeGetQualityXMLUnlocked(d_storeXML(store)->groups, nameSpace, quality); + } + d_lockUnlock(d_lock(store)); + } else { + result = D_STORE_RESULT_ILL_PARAM; + } + return result; +} + +d_storeResult +d_storeGroupStoreXML( + const d_store store, + const d_group dgroup, + const d_nameSpace nameSpace) +{ + c_char * topicName = NULL; + c_char * partitionName = NULL; + c_bool storeMetaSuccess; + v_group group; + d_storeResult result; + d_quality quality; + d_storeXML persistentStore; + + OS_UNUSED_ARG(nameSpace); + + assert(d_objectIsValid(d_object(store), D_STORE)); + assert(store->type == D_STORE_TYPE_XML); + + if(store != NULL) { + persistentStore = d_storeXML(store); + d_lockLock(d_lock(persistentStore)); + + if(persistentStore->opened == FALSE) { + result = D_STORE_RESULT_PRECONDITION_NOT_MET; + } else if(dgroup == NULL) { + result = D_STORE_RESULT_ILL_PARAM; + } else { + group = d_groupGetKernelGroup(dgroup); + topicName = v_topicName(v_groupTopic(group)); + partitionName = v_partitionName(v_groupPartition(group)); + d_storeReport(store, D_LEVEL_FINE, + "Storing group (partition.topic): %s.%s\n", + partitionName, topicName); + + createDirectoryIfNecessary(d_storeXML(store), partitionName); + storeMetaSuccess = storeTopicMetadata(d_storeXML(store), group); + + if(storeMetaSuccess == TRUE) { + quality = os_timeWGet(); + setPartitionTopicQuality(persistentStore, + partitionName, topicName, + quality, D_GROUP_INCOMPLETE); + result = D_STORE_RESULT_OK; + } else { + d_storeReport(d_store(persistentStore), + D_LEVEL_SEVERE, + RR_COULD_NOT_WRITE_META_DATA, + topicName); + OS_REPORT(OS_ERROR, + STORE_STORE_TOPIC_XML, 0, + RR_COULD_NOT_WRITE_META_DATA, + topicName); + result = D_STORE_RESULT_PRECONDITION_NOT_MET; + } + c_free(group); + } + d_lockUnlock(d_lock(persistentStore)); + } else { + result = D_STORE_RESULT_ILL_PARAM; + } + return result; +} + + +d_storeResult +d_storeBackupXML( + const d_store store, + const d_nameSpace nameSpace) +{ + d_storeResult result; + d_storeXML persistentStore; + d_groupList groupList; + c_char* fileStorePath; + c_char* backupStorePath; + + assert(d_objectIsValid(d_object(store), D_STORE)); + assert(store->type == D_STORE_TYPE_XML); + + result = D_STORE_RESULT_OK; + if(store != NULL) { + persistentStore = d_storeXML(store); + d_lockLock(d_lock(persistentStore)); + + if(persistentStore->opened == FALSE) { + result = D_STORE_RESULT_PRECONDITION_NOT_MET; + } else if(nameSpace == NULL) { + result = D_STORE_RESULT_ILL_PARAM; + } else { + groupList = persistentStore->groups; + + while(groupList) { + if(d_nameSpaceIsIn(nameSpace, groupList->partition, groupList->topic)) { + fileStorePath = getDataFileName(persistentStore, groupList->partition, groupList->topic); + backupStorePath = getBakFileName(persistentStore, groupList->partition, groupList->topic); + + if (os_rename(fileStorePath, backupStorePath) == os_resultFail) + { + result = D_STORE_RESULT_IO_ERROR; + } + + os_free(fileStorePath); + os_free(backupStorePath); + } + groupList = groupList->next; + } + } + d_lockUnlock(d_lock(persistentStore)); + } else { + result = D_STORE_RESULT_ILL_PARAM; + } + return result; +} + +/* Restore backed up files */ +d_storeResult +d_storeRestoreBackupXML ( + const d_store store, + const d_nameSpace nameSpace) +{ + d_storeResult result; + d_storeXML persistentStore; + d_groupList groupList; + c_char* fileStorePath; + c_char* backupStorePath; + + assert(d_objectIsValid(d_object(store), D_STORE)); + assert(store->type == D_STORE_TYPE_XML); + + if(store != NULL) { + persistentStore = d_storeXML(store); + d_lockLock(d_lock(persistentStore)); + + if(persistentStore->opened == FALSE) { + result = D_STORE_RESULT_PRECONDITION_NOT_MET; + } else if(nameSpace == NULL) { + result = D_STORE_RESULT_ILL_PARAM; + } else { + groupList = persistentStore->groups; + + result = D_STORE_RESULT_OK; + + while(groupList) { + if(d_nameSpaceIsIn(nameSpace, groupList->partition, groupList->topic)) { + fileStorePath = getDataFileName(persistentStore, groupList->partition, groupList->topic); + backupStorePath = getBakFileName(persistentStore, groupList->partition, groupList->topic); + + if (os_rename(backupStorePath, fileStorePath) == os_resultFail) + { + result = D_STORE_RESULT_IO_ERROR; + } + + os_free(fileStorePath); + os_free(backupStorePath); + } + /* Reset quality */ + groupList->quality = D_QUALITY_ZERO; + groupList = groupList->next; + } + + /* Re-determine quality of groups */ + d_storeXMLInitGroups(persistentStore); + + /* Walk namespaces in administration */ + d_adminNameSpaceWalk (store->admin, correctGroupQuality, persistentStore->groups); + } + d_lockUnlock(d_lock(persistentStore)); + } else { + result = D_STORE_RESULT_ILL_PARAM; + } + return result; +} + +d_storeResult +d_storeMessageStoreXML( + const d_store store, + const v_groupAction msg) +{ + d_storeResult result; + + assert(d_objectIsValid(d_object(store), D_STORE)); + assert(store->type == D_STORE_TYPE_XML); + + if(store != NULL) { + d_lockLock(d_lock(store)); + + if(d_storeXML(store)->opened == FALSE) { + result = D_STORE_RESULT_PRECONDITION_NOT_MET; + } else if((msg == NULL) || (msg->group == NULL) || (msg->message == NULL)) { + result = D_STORE_RESULT_ILL_PARAM; + } else { + result = appendMessage(d_storeXML(store), msg); + } + d_lockUnlock(d_lock(store)); + } else { + result = D_STORE_RESULT_ILL_PARAM; + } + return result; +} + +d_storeResult +d_storeInstanceDisposeXML( + const d_store store, + const v_groupAction msg) +{ + d_storeResult result; + + assert(d_objectIsValid(d_object(store), D_STORE)); + assert(store->type == D_STORE_TYPE_XML); + + if(store != NULL) { + d_lockLock(d_lock(store)); + + if(d_storeXML(store)->opened == FALSE) { + result = D_STORE_RESULT_PRECONDITION_NOT_MET; + } else if((msg == NULL) || (msg->group == NULL) || (msg->message == NULL)) { + result = D_STORE_RESULT_ILL_PARAM; + } else { + result = appendMessage(d_storeXML(store), msg); + } + d_lockUnlock(d_lock(store)); + } else { + result = D_STORE_RESULT_ILL_PARAM; + } + return result; +} + +d_storeResult +d_storeInstanceExpungeXML( + const d_store store, + const v_groupAction msg) +{ + d_storeResult result; + + assert(d_objectIsValid(d_object(store), D_STORE)); + assert(store->type == D_STORE_TYPE_XML); + + if(store != NULL) { + d_lockLock(d_lock(store)); + + if(d_storeXML(store)->opened == FALSE) { + result = D_STORE_RESULT_PRECONDITION_NOT_MET; + } else if((msg == NULL) || (msg->group == NULL) || (msg->message == NULL)) { + result = D_STORE_RESULT_ILL_PARAM; + } else { + result = expungeMessageOptimized(d_storeXML(store), msg, FALSE); + } + d_lockUnlock(d_lock(store)); + } else { + result = D_STORE_RESULT_ILL_PARAM; + } + return result; +} + +d_storeResult +d_storeMessageExpungeXML( + const d_store store, + const v_groupAction msg) +{ + d_storeResult result; + + assert(d_objectIsValid(d_object(store), D_STORE)); + assert(store->type == D_STORE_TYPE_XML); + + if(store != NULL) { + d_lockLock(d_lock(store)); + + if(d_storeXML(store)->opened == FALSE) { + result = D_STORE_RESULT_PRECONDITION_NOT_MET; + } else if((msg == NULL) || (msg->group == NULL)) { + result = D_STORE_RESULT_ILL_PARAM; + } else { + if(msg->kind == V_GROUP_ACTION_DELETE_DATA){ + result = deleteHistoricalData(d_storeXML(store), msg); + } else { + result = expungeMessageOptimized(d_storeXML(store), msg, TRUE); + } + } + d_lockUnlock(d_lock(store)); + } else { + result = D_STORE_RESULT_ILL_PARAM; + } + return result; +} + +d_storeResult +d_storeDeleteHistoricalDataXML( + const d_store store, + const v_groupAction msg) +{ + d_storeResult result; + + assert(d_objectIsValid(d_object(store), D_STORE)); + assert(store->type == D_STORE_TYPE_XML); + + if(store != NULL) { + d_lockLock(d_lock(store)); + + if(d_storeXML(store)->opened == FALSE) { + result = D_STORE_RESULT_PRECONDITION_NOT_MET; + } else if((msg == NULL) || (msg->group == NULL)) { + result = D_STORE_RESULT_ILL_PARAM; + } else { + result = deleteHistoricalData(d_storeXML(store), msg); + } + d_lockUnlock(d_lock(store)); + } else { + result = D_STORE_RESULT_ILL_PARAM; + } + return result; +} + +d_storeResult +d_storeInstanceRegisterXML( + const d_store store, + const v_groupAction msg) +{ + d_storeResult result; + + assert(d_objectIsValid(d_object(store), D_STORE)); + assert(store->type == D_STORE_TYPE_XML); + + if(store != NULL) { + d_lockLock(d_lock(store)); + + if(d_storeXML(store)->opened == FALSE) { + result = D_STORE_RESULT_PRECONDITION_NOT_MET; + } else if((msg == NULL) || (msg->group == NULL) || (msg->message == NULL)) { + result = D_STORE_RESULT_ILL_PARAM; + } else { + result = appendMessage(d_storeXML(store), msg); + } + d_lockUnlock(d_lock(store)); + } else { + result = D_STORE_RESULT_ILL_PARAM; + } + return result; +} + +d_storeResult +d_storeCreatePersistentSnapshotXML( + const d_store store, + const c_char* partitionExpr, + const c_char* topicExpr, + const c_char* uri) +{ + d_storeResult result; + c_bool match; + os_char* fileStorePath; + os_char* destStorePath; + d_groupList listIter; + c_ulong length; + c_ulong i; + d_nameSpace nameSpace; + d_durabilityKind dkind; + c_iter nameSpaces; + + assert(store); + assert(topicExpr); + assert(partitionExpr); + assert(uri); + assert(d_objectIsValid(d_object(store), D_STORE)); + assert(store->type == D_STORE_TYPE_XML); + + if(store) + { + d_durability durability = d_adminGetDurability(store->admin); + d_printTimedEvent(durability, D_LEVEL_INFO, "debug", + "d_storeCreatePersistentSnapshotXML-1: partitionExpr='%s', topicExpr ='%s', uri = '%s'\n", partitionExpr, topicExpr, uri); + + os_mutexLock(&(d_storeXML(store)->mutex)); + d_lockLock(d_lock(store)); + if(d_storeXML(store)->opened == FALSE) + { + result = D_STORE_RESULT_PRECONDITION_NOT_MET; + } else + { + result = groupsReadXMLUnsafe(store, &listIter); + while(result == D_STORE_RESULT_OK && listIter) + { + match = d_patternMatch(listIter->partition, (c_string)partitionExpr); + if(match) + { + match = d_patternMatch(listIter->topic, (c_string)topicExpr); + if(match) + { + c_char* tmp; + tmp = d_storeDirNew(store, uri); + if(tmp) + { + os_free(tmp); + createDirectoryIfNecessaryForStoreDir(uri, listIter->partition); + /* Copy data file */ + fileStorePath = getDataFileName(d_storeXML(store), listIter->partition, listIter->topic); + destStorePath = getDataFileNameBasedOnPath(uri, listIter->partition, listIter->topic); + result = d_storeCopyFile(fileStorePath, destStorePath); + + d_printTimedEvent(durability, D_LEVEL_INFO, "debug", + "d_storeCreatePersistentSnapshotXML-2: listIter=->partition='%s', listIter->topic='%s', fileStorePath='%s', destStorePath ='%s', result = %d\n", + listIter->partition, listIter->topic, fileStorePath, destStorePath, result); + + os_free(fileStorePath); + os_free(destStorePath); + if(result == D_STORE_RESULT_OK) + { + /* Copy meta file */ + fileStorePath = getMetaFileName(d_storeXML(store), listIter->partition, listIter->topic); + destStorePath = getMetaFileNameBasedOnPath(uri, listIter->partition, listIter->topic); + result = d_storeCopyFile(fileStorePath, destStorePath); + + d_printTimedEvent(durability, D_LEVEL_INFO, "debug", + "d_storeCreatePersistentSnapshotXML-3: listIter=->partition='%s', listIter->topic='%s', fileStorePath='%s', destStorePath ='%s', result = %d\n", + listIter->partition, listIter->topic, fileStorePath, destStorePath, result); + + os_free(fileStorePath); + os_free(destStorePath); + /* Store the complete file for the namespace */ + if(result == D_STORE_RESULT_OK) + { + /* Collect namespaces */ + nameSpaces = d_adminNameSpaceCollect(store->admin); + length = c_iterLength(nameSpaces); + for(i = 0; i < length; i++) + { + nameSpace = d_nameSpace(c_iterObject(nameSpaces, i)); + dkind = d_nameSpaceGetDurabilityKind(nameSpace); + if(dkind == D_DURABILITY_PERSISTENT || dkind == D_DURABILITY_ALL) + { + if(d_nameSpaceIsIn(nameSpace, listIter->partition, listIter->topic)) + { + /* always mark the namespace as complete for a snapshot */ + result = d_storeNsMarkCompleteXMLBasedOnPath ( + uri, + nameSpace, + TRUE); + + d_printTimedEvent(durability, D_LEVEL_INFO, "debug", + "d_storeCreatePersistentSnapshotXML-3: listIter=->partition='%s', listIter->topic='%s', uri='%s', nameSpace ='%s', result = %d\n", + listIter->partition, listIter->topic, uri, d_nameSpaceGetName(nameSpace), result); + + } + } + } + + /* Free namespace list */ + d_adminNameSpaceCollectFree(store->admin, nameSpaces); + } + } + } else + { + result = D_STORE_RESULT_IO_ERROR; + } + } + } + listIter = d_groupList(listIter->next); + } + } + d_lockUnlock(d_lock(store)); + os_mutexUnlock(&(d_storeXML(store)->mutex)); + } else { + result = D_STORE_RESULT_ILL_PARAM; + } + return result; +} + +d_storeResult +d_storeInstanceUnregisterXML( + const d_store store, + const v_groupAction msg) +{ + d_storeResult result; + + assert(d_objectIsValid(d_object(store), D_STORE)); + assert(store->type == D_STORE_TYPE_XML); + + if(store != NULL) { + d_lockLock(d_lock(store)); + + if(d_storeXML(store)->opened == FALSE) { + result = D_STORE_RESULT_PRECONDITION_NOT_MET; + } else if((msg == NULL) || (msg->group == NULL) || (msg->message == NULL)) { + result = D_STORE_RESULT_ILL_PARAM; + } else { + result = appendMessage(d_storeXML(store), msg); + } + d_lockUnlock(d_lock(store)); + } else { + result = D_STORE_RESULT_ILL_PARAM; + } + return result; +} + +d_storeResult +d_storeMessagesInjectXML( + const d_store store, + const d_group group) +{ + d_storeResult result; + v_group vgroup; + d_partition partition; + d_topic topic; + c_char *fileStorePath; + d_storeXML persistentStore; + + assert(d_objectIsValid(d_object(store), D_STORE)); + assert(store->type == D_STORE_TYPE_XML); + + if(store != NULL) { + d_lockLock(d_lock(store)); + + if(d_storeXML(store)->opened == FALSE) { + result = D_STORE_RESULT_PRECONDITION_NOT_MET; + } else if(group == NULL) { + result = D_STORE_RESULT_ILL_PARAM; + } else { + persistentStore = d_storeXML(store); + vgroup = d_groupGetKernelGroup(group); + + if(vgroup){ + topic = v_topicName(v_groupTopic(vgroup)); + partition = v_partitionName(v_groupPartition(vgroup)); + + result = d_storeXMLInjectTopicXML(persistentStore, + vgroup, + partition, topic); + + if(result != D_STORE_RESULT_OK){ + OS_REPORT(OS_ERROR, D_CONTEXT, 0, + "Unable to insert persistent data from disk for group '%s.%s'. Reason: '%d'. Removing data for this group...", + partition, topic, result); + d_storeReport(store, + D_LEVEL_SEVERE, + "Unable to insert persistent data from disk for group '%s.%s'. Reason: '%d'. Removing data for this group...", + partition, topic, result); + fileStorePath = getDataFileName(persistentStore, partition, topic); + os_remove(fileStorePath); + os_free(fileStorePath); + } + + c_free(vgroup); + } else { + result = D_STORE_RESULT_ILL_PARAM; + } + } + d_lockUnlock(d_lock(store)); + } else { + result = D_STORE_RESULT_ILL_PARAM; + } + return result; +} + +d_storeResult +d_storeOptimizeGroupXML( + const d_store store, + const d_group group) +{ + d_storeResult result; + v_group vgroup; + d_partition partition; + d_topic topic; + c_bool isOptimal; + c_ulong dataVersion; + + assert(d_objectIsValid(d_object(store), D_STORE)); + assert(store->type == D_STORE_TYPE_XML); + + if(store != NULL) { + d_lockLock(d_lock(store)); + + if(d_storeXML(store)->opened == FALSE) { + result = D_STORE_RESULT_PRECONDITION_NOT_MET; + } else if(group == NULL) { + result = D_STORE_RESULT_ILL_PARAM; + } else { + vgroup = d_groupGetKernelGroup(group); + + if(vgroup){ + topic = v_topicName(v_groupTopic(vgroup)); + partition = v_partitionName(v_groupPartition(vgroup)); + + isOptimal = isOptimized(d_storeXML(store), partition, topic); + + result = getDataVersion(d_storeXML(store), partition, topic, &dataVersion); + + if(result == D_STORE_RESULT_OK){ + if((isOptimal == FALSE) || (dataVersion < D_STORE_VERSION)){ + result = d_storeXMLOptimizeGroup(d_storeXML(store), + vgroup, + partition, topic, + FALSE, + TRUE, + dataVersion); + } else { + result = D_STORE_RESULT_OK; + } + } + c_free(vgroup); + } else { + result = D_STORE_RESULT_ILL_PARAM; + } + } + d_lockUnlock(d_lock(store)); + } else { + result = D_STORE_RESULT_ILL_PARAM; + } + return result; +} + + +/* Return filename for namespace complete indicator file */ +static +d_storeResult +d_storeNsCompleteFileName( + const char* storeDir, + const d_nameSpace nameSpace, + char nameBuff[]) +{ + d_storeResult result; + + if (storeDir && nameSpace) + { + nameBuff[0] = '\0'; + + /* Copy path of persistent store to buffer */ + strcat (nameBuff, storeDir); + + /* Copy '/' character */ + strcat (nameBuff, os_fileSep()); + + /* Copy namespace name */ + strcat (nameBuff, d_nameSpaceGetName(nameSpace)); + + /* Copy postfix for completefile */ + strcat (nameBuff, "_complete"); + + result = D_STORE_RESULT_OK; + }else + { + result = D_STORE_RESULT_ILL_PARAM; + } + + return result; +} + +/* Check if namespace complete indicator file exists */ +static +c_bool +d_storeNsCompleteFileExists ( + const char completeFile[]) +{ + c_bool result; + os_result osResult; + struct os_stat_s buf; + + result = FALSE; + + osResult = os_stat (completeFile, &buf); + if (osResult == os_resultSuccess) + { + result = TRUE; + } + + return result; +} + +/* Create or remove namespace completefile */ +static +d_storeResult +d_storeNsMarkComplete_w_name ( + const char completeFile[], + c_bool isComplete) +{ + d_storeResult result; + c_bool completeFileExists; + FILE* hFile; + + result = D_STORE_RESULT_OK; + + completeFileExists = d_storeNsCompleteFileExists (completeFile); + + /* Remove existing complete file if namespace is incomplete, otherwise create it */ + if (isComplete) + { + if (!completeFileExists) + { + hFile = fopen (completeFile, "w"); + if (!hFile) + { + result = D_STORE_RESULT_IO_ERROR; + }else + { + fclose (hFile); + } + } + }else + { + if (completeFileExists && (os_remove (completeFile) == os_resultFail)) + { + result = D_STORE_RESULT_IO_ERROR; + } + } + + return result; +} + +/* Check if namespace is complete */ +d_storeResult +d_storeNsIsCompleteXML ( + const d_store store, + const d_nameSpace nameSpace, + c_bool* isComplete) +{ + char completeFile[OS_PATH_MAX]; + d_storeResult result; + + if(store) + { + d_lockLock(d_lock(store)); + + if (isComplete) + { + *isComplete = FALSE; + + /* Get completeFile name */ + result = d_storeNsCompleteFileName ( + store->config->persistentStoreDirectory, + nameSpace, + completeFile); + if (result == D_STORE_RESULT_OK) + { + *isComplete = d_storeNsCompleteFileExists (completeFile); + } + }else + { + result = D_STORE_RESULT_ILL_PARAM; + } + d_lockUnlock(d_lock(store)); + } else + { + result = D_STORE_RESULT_ILL_PARAM; + } + + return result; +} + +d_storeResult +d_storeNsMarkCompleteXMLBasedOnPath( + const c_char* storeDir, + const d_nameSpace nameSpace, + c_bool isComplete) +{ + d_storeResult result; + char completeFile[OS_PATH_MAX]; + + /* Get completeFile name */ + result = d_storeNsCompleteFileName (storeDir, nameSpace, completeFile); + if (result == D_STORE_RESULT_OK) + { + result = d_storeNsMarkComplete_w_name (completeFile, isComplete); + } + return result; +} + +/* Mark namespace incomplete or complete */ +d_storeResult +d_storeNsMarkCompleteXML ( + const d_store store, + const d_nameSpace nameSpace, + c_bool isComplete) +{ + d_storeResult result; + + if(store) + { + d_lockLock(d_lock(store)); + result = d_storeNsMarkCompleteXMLBasedOnPath( + store->config->persistentStoreDirectory, + nameSpace, + isComplete); + d_lockUnlock(d_lock(store)); + } else + { + result = D_STORE_RESULT_ILL_PARAM; + } + + return result; +} + +static d_storeResult +getDataVersion( + const d_storeXML persistentStore, + const c_char* partition, + const c_char* topic, + c_ulong* version) +{ + c_long status; + FILE *fdes; + c_char *data, *dataFileName; + d_storeResult result; + int dataVersionFound; + size_t len; + + dataFileName = getDataFileName(persistentStore, partition, topic); + + if(dataFileName){ + fdes = fopen(dataFileName, "r"); + + if (fdes) { + len = 4096; + data = (c_char *)d_malloc(len, "readData"); + + if (data == NULL) { + d_storeReport(d_store(persistentStore), D_LEVEL_SEVERE, "No more resources\n"); + OS_REPORT(OS_ERROR, D_CONTEXT, 0, "No more resources available\n"); + result = D_STORE_RESULT_OUT_OF_RESOURCES; + } else { + data[0] = '\0'; + readLine(fdes, len, data); + status = strncmp(data, "", 7); + + if (status != 0) { + d_storeReport(d_store(persistentStore), D_LEVEL_SEVERE, + RR_TOPIC_SHOULD_BEGIN_WITH_TOPIC_TAG, topic); + OS_REPORT(OS_ERROR, STORE_READ_TOPIC_XML, 0, + RR_TOPIC_SHOULD_BEGIN_WITH_TOPIC_TAG, topic); + result = D_STORE_RESULT_MUTILATED; + } else { + dataVersionFound = sscanf(data, " 0){ + result = (c_char*)(os_malloc(length + 1)); + result[0] = '\0'; + j = 0; + + for(i=0; isubscriber); + admin = subscriber->admin; + durability = d_adminGetDurability(admin); + i = ((struct initialQualityWalkData*)userData)->i; + + if( (d_nameSpaceGetDurabilityKind(ns) == D_DURABILITY_PERSISTENT) || + (d_nameSpaceGetDurabilityKind(ns) == D_DURABILITY_ALL)) + { + result = d_storeGetQuality(subscriber->persistentStore, ns, &quality); + + if(result == D_STORE_RESULT_OK){ + d_nameSpaceSetInitialQuality(ns, quality); + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Initial quality for nameSpace %d is %"PA_PRItime"\n", + i, OS_TIMEW_PRINT(quality)); + } else { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "Unable to get quality from persistent store for nameSpace %d.\n", + i); + } + } else { + d_printTimedEvent(durability, D_LEVEL_FINEST, + "nameSpace %d does not hold persistent data.\n", i); + } + ((struct initialQualityWalkData*)userData)->i++; +} + +d_subscriber +d_subscriberNew( + d_admin admin) +{ + d_subscriber subscriber; + d_durability durability; + d_configuration config; + v_subscriberQos subscriberQos, psubscriberQos; + c_char* partitionExpr; + struct initialQualityWalkData walkData; + d_storeResult result; + d_nameSpace nameSpace; + c_iter nameSpaces; + c_bool nsComplete; + d_durabilityKind dkind; + + assert(d_adminIsValid(admin)); + + subscriber = NULL; + /* Allocate subscriber object */ + subscriber = d_subscriber(os_malloc(C_SIZEOF(d_subscriber))); + if (subscriber) { + memset(subscriber, 0, (os_uint32)sizeof(C_STRUCT(d_subscriber))); + /* Call super-init */ + d_objectInit(d_object(subscriber), D_SUBSCRIBER, + (d_objectDeinitFunc)d_subscriberDeinit); + /* Initialize the subscriber */ + subscriber->admin = admin; + durability = d_adminGetDurability(admin); + config = d_durabilityGetConfiguration(durability); + /* Create the subscriber for the durability protocol */ + subscriberQos = d_subscriberQosNew(config->partitionName); + if (subscriberQos == NULL) { + goto err_allocSubscriberQos; + } + subscriber->subscriber = u_subscriberNew (u_participant(d_durabilityGetService(durability)), + config->subscriberName, + subscriberQos); + d_subscriberQosFree(subscriberQos); + if (subscriber->subscriber == NULL) { + goto err_allocSubscriber; + } + + if(u_entityEnable(u_entity(subscriber->subscriber)) != U_RESULT_OK) { + goto err_allocSubscriber; + } + + /* Create the subscriber for client durability, but only + * if client durability is enabled. */ + if (config->clientDurabilityEnabled) { + subscriberQos = d_subscriberQosNew(config->clientDurabilityPartitionName); + if (subscriberQos == NULL) { + goto err_allocSubscriberQos2; + } + subscriber->subscriber2 = u_subscriberNew(u_participant(d_durabilityGetService(durability)), + D_CLIENT_DURABILITY_SUBSCRIBER_NAME, + subscriberQos); + d_subscriberQosFree(subscriberQos); + if (subscriber->subscriber2 == NULL) { + goto err_allocSubscriber2; + } + if(u_entityEnable(u_entity(subscriber->subscriber2)) != U_RESULT_OK) { + goto err_allocSubscriber2; + } + } else { + subscriber->subscriber2 = NULL; + } + /* Create the builtin subscriber for DCPSSubscriptions, DCPSHeartbeats and + * DCPSPublications. */ + subscriberQos = d_subscriberQosNew(V_BUILTIN_PARTITION); + if (subscriberQos == NULL) { + goto err_allocSubscriberQos3; + } + subscriber->builtinSubscriber = u_subscriberNew(u_participant(d_durabilityGetService(durability)), + D_DURABILITY_BUILTIN_SUBSCRIBER_NAME, + subscriberQos); + d_subscriberQosFree(subscriberQos); + if (subscriber->builtinSubscriber == NULL) { + goto err_builtinSubscriber; + } + if(u_entityEnable(u_entity(subscriber->builtinSubscriber)) != U_RESULT_OK) { + goto err_builtinSubscriber; + } + /* Create the waitset */ + subscriber->waitset = d_waitsetNew(subscriber); + if (subscriber->waitset == NULL) { + goto err_allocWaitset; + } + /* Open the persistent store (if any) */ + subscriber->persistentStore = d_storeOpen(durability, config->persistentStoreMode); + if (subscriber->persistentStore) { + partitionExpr = getPersistentPartitionExpression(admin, durability); + psubscriberQos = d_subscriberQosNew(partitionExpr); + if (psubscriberQos == NULL) { + os_free(partitionExpr); + partitionExpr = NULL; + goto err_allocPSubscriberQos; + } + os_free(partitionExpr); + partitionExpr = NULL; + if (psubscriberQos->partition.v) { + /* Collect nameSpaces from admin. */ + nameSpaces = d_adminNameSpaceCollect(admin); + /* Loop nameSpaces */ + while ((nameSpace = c_iterTakeFirst(nameSpaces))) { + dkind = d_nameSpaceGetDurabilityKind(nameSpace); + /* Walk only over persistent nameSpaces */ + if ((dkind == D_DURABILITY_PERSISTENT) || (dkind == D_DURABILITY_ALL)) { + /* If persistent nameSpace is not complete, restore backup */ + result = d_storeNsIsComplete (subscriber->persistentStore, nameSpace, &nsComplete); + if ( (result == D_STORE_RESULT_OK) && !nsComplete) { + /* Incomplete namespace, restore backup. */ + d_printTimedEvent(durability, D_LEVEL_WARNING, + "Namespace '%s' is incomplete, trying to restore backup.\n", + d_nameSpaceGetName(nameSpace)); + if (d_storeRestoreBackup (subscriber->persistentStore, nameSpace) != D_STORE_RESULT_OK) { + d_printTimedEvent(durability, D_LEVEL_WARNING, + "Backup for namespace '%s' could not be restored as no complete backup did exist on disk. Marking namespace as incomplete and continuing.\n", + d_nameSpaceGetName(nameSpace)); + OS_REPORT(OS_WARNING, D_CONTEXT_DURABILITY, 0, + "Backup for namespace '%s' could not be restored as no complete backup did exist on disk. Marking namespace as incomplete and continuing.\n", + d_nameSpaceGetName (nameSpace)); + /* If backup fails, mark master state for nameSpace !D_STATE_COMPLETE */ + d_nameSpaceSetMasterState (nameSpace, D_STATE_INIT); + } + } + } + d_nameSpaceFree(nameSpace); + } /* while */ + /* Free nameSpaces iterator */ + assert(c_iterLength(nameSpaces) == 0); + c_iterFree(nameSpaces); + /* create the persistent subscriber */ + subscriber->persistentSubscriber = u_subscriberNew(u_participant(d_durabilityGetService(durability)), + config->subscriberName, + psubscriberQos); + if (!subscriber->persistentSubscriber) { + goto err_allocPersistentSubscriber; + } + if(u_entityEnable(u_entity(subscriber->persistentSubscriber)) != U_RESULT_OK) { + goto err_allocPersistentSubscriber; + } + } else { + subscriber->persistentSubscriber = NULL; + } + walkData.subscriber = subscriber; + walkData.i = 0; + d_adminNameSpaceWalk(admin, nsInitialQualityWalk, &walkData); + d_subscriberQosFree(psubscriberQos); + } else { + subscriber->persistentSubscriber = NULL; + } + subscriber->statusListener = NULL; + subscriber->groupLocalListener = NULL; + subscriber->groupRemoteListener = NULL; + subscriber->groupsRequestListener = NULL; + subscriber->sampleRequestListener = NULL; + subscriber->sampleChainListener = NULL; + subscriber->nameSpacesRequestListener = NULL; + subscriber->nameSpacesListener = NULL; + subscriber->persistentDataListener = NULL; + subscriber->deleteDataListener = NULL; + subscriber->remoteReaderListener = NULL; + subscriber->historicalDataRequestListener = NULL; + subscriber->durabilityStateRequestListener = NULL; + subscriber->dcpsHeartbeatListener = NULL; + subscriber->dcpsPublicationListener = NULL; + subscriber->capabilityListener = NULL; + } + return subscriber; + +err_allocPersistentSubscriber: +err_allocPSubscriberQos: +err_allocWaitset: +err_builtinSubscriber: +err_allocSubscriberQos3: +err_allocSubscriber2: +err_allocSubscriberQos2: +err_allocSubscriber: +err_allocSubscriberQos: + d_subscriberFree(subscriber); + return NULL; +} + + +void +d_subscriberDeinit( + d_subscriber subscriber) +{ + d_durability durability; + d_configuration config; + + assert(d_subscriberIsValid(subscriber)); + + durability = d_adminGetDurability(subscriber->admin); + assert(d_durabilityIsValid(durability)); + config = d_durabilityGetConfiguration(durability); + assert(d_configurationIsValid(config)); + if (subscriber->persistentStore) { + d_storeClose(subscriber->persistentStore); + d_printTimedEvent(durability, D_LEVEL_FINEST, "persistent store closed\n"); + subscriber->persistentStore = NULL; + } + if (subscriber->waitset) { + d_waitsetFree(subscriber->waitset); + d_printTimedEvent(durability, D_LEVEL_FINEST, "waitset freed\n"); + subscriber->waitset = NULL; + } + if (subscriber->persistentSubscriber) { + u_objectFree(u_object(subscriber->persistentSubscriber)); + d_printTimedEvent(durability, D_LEVEL_FINEST, "user persistent subscriber freed\n"); + subscriber->persistentSubscriber = NULL; + } + if (subscriber->subscriber2) { + u_objectFree(u_object(subscriber->subscriber2)); + d_printTimedEvent(durability, D_LEVEL_FINEST, "%s freed\n", config->clientDurabilitySubscriberName); + subscriber->subscriber2 = NULL; + } + if (subscriber->subscriber) { + u_objectFree(u_object(subscriber->subscriber)); + d_printTimedEvent(durability, D_LEVEL_FINEST, "%s freed\n", config->subscriberName); + subscriber->subscriber = NULL; + } + if (subscriber->builtinSubscriber) { + u_objectFree(u_object(subscriber->builtinSubscriber)); + d_printTimedEvent(durability, D_LEVEL_FINEST, "%s freed\n", D_DURABILITY_BUILTIN_SUBSCRIBER_NAME); + subscriber->builtinSubscriber = NULL; + } + /* Call super-deinit */ + d_objectDeinit(d_object(subscriber)); +} + + +void +d_subscriberFree( + d_subscriber subscriber) +{ + assert(d_subscriberIsValid(subscriber)); + + d_objectFree(d_object(subscriber)); +} + + +d_admin +d_subscriberGetAdmin( + d_subscriber subscriber) +{ + assert(d_objectIsValid(d_object(subscriber), D_SUBSCRIBER) == TRUE); + return subscriber->admin; +} + +d_waitset +d_subscriberGetWaitset( + d_subscriber subscriber) +{ + assert(d_objectIsValid(d_object(subscriber), D_SUBSCRIBER) == TRUE); + return subscriber->waitset; +} + +u_subscriber +d_subscriberGetSubscriber( + d_subscriber subscriber) +{ + assert(d_objectIsValid(d_object(subscriber), D_SUBSCRIBER) == TRUE); + return subscriber->subscriber; +} + +u_subscriber +d_subscriberGetPersistentSubscriber( + d_subscriber subscriber) +{ + assert(d_objectIsValid(d_object(subscriber), D_SUBSCRIBER) == TRUE); + return subscriber->persistentSubscriber; +} + +#define _INIT_LISTENER_(listener) \ + if (!subscriber->listener) { \ + subscriber->listener = d_##listener##New(subscriber); \ + assert(subscriber->listener); \ + } + +#define _START_LISTENER_(listener) \ + if (subscriber->listener) { \ + if (!d_##listener##Start(subscriber->listener)) { \ + result = FALSE; \ + assert(0); \ + } \ + } + +c_bool +d_subscriberStartListeners( + d_subscriber subscriber) +{ + d_durability durability; + c_bool result = TRUE; + assert(d_objectIsValid(d_object(subscriber), D_SUBSCRIBER) == TRUE); + if (subscriber) { + durability = d_adminGetDurability(subscriber->admin); + if (durability->configuration->capabilitySupport) { + _INIT_LISTENER_(capabilityListener); + } + _INIT_LISTENER_(nameSpacesListener); + _INIT_LISTENER_(nameSpacesRequestListener); + _INIT_LISTENER_(statusListener); + _INIT_LISTENER_(groupsRequestListener); + if(subscriber->persistentSubscriber) { + _INIT_LISTENER_(persistentDataListener); + } + _INIT_LISTENER_(deleteDataListener); + _INIT_LISTENER_(groupRemoteListener); + _INIT_LISTENER_(sampleRequestListener); + _INIT_LISTENER_(sampleChainListener); + _INIT_LISTENER_(groupLocalListener); + _INIT_LISTENER_(dcpsHeartbeatListener); + if (durability->configuration->waitForRemoteReaders) { + _INIT_LISTENER_(remoteReaderListener); + } + if (durability->configuration->clientDurabilityEnabled) { + _INIT_LISTENER_(dcpsPublicationListener); + _INIT_LISTENER_(durabilityStateRequestListener); + _INIT_LISTENER_(historicalDataRequestListener); + } + if (durability->splicedRunning == TRUE) { + subscriber->admin->conflictResolver = d_conflictResolverNew(subscriber->admin); + assert(subscriber->admin->conflictResolver); + _START_LISTENER_(capabilityListener); + _START_LISTENER_(groupsRequestListener); + _START_LISTENER_(nameSpacesListener); + _START_LISTENER_(nameSpacesRequestListener); + _START_LISTENER_(statusListener); + _START_LISTENER_(persistentDataListener); + _START_LISTENER_(groupRemoteListener); + _START_LISTENER_(sampleChainListener); + _START_LISTENER_(sampleRequestListener); + _START_LISTENER_(deleteDataListener); + _START_LISTENER_(dcpsHeartbeatListener); + _START_LISTENER_(remoteReaderListener); + _START_LISTENER_(dcpsPublicationListener); + _START_LISTENER_(durabilityStateRequestListener); + _START_LISTENER_(historicalDataRequestListener); + } + } + return result; +} + +#define _STOP_LISTENER_(listener) \ + if (subscriber->listener) { \ + (void)d_##listener##Stop(subscriber->listener); \ + } + +#define _FREE_LISTENER_(listener) \ + if (subscriber->listener) { \ + d_##listener##Free(subscriber->listener); \ + subscriber->listener = NULL; \ + } + +void d_subscriberStopListeners( + d_subscriber subscriber) +{ + assert(d_objectIsValid(d_object(subscriber), D_SUBSCRIBER) == TRUE); + + if(subscriber){ + _STOP_LISTENER_(capabilityListener); + _STOP_LISTENER_(dcpsPublicationListener); + _STOP_LISTENER_(durabilityStateRequestListener); + _STOP_LISTENER_(historicalDataRequestListener); + _STOP_LISTENER_(remoteReaderListener); + _STOP_LISTENER_(deleteDataListener); + _STOP_LISTENER_(sampleRequestListener); + _STOP_LISTENER_(sampleChainListener); + _STOP_LISTENER_(groupRemoteListener); + _STOP_LISTENER_(statusListener); + _STOP_LISTENER_(nameSpacesRequestListener); + _STOP_LISTENER_(nameSpacesListener); + _STOP_LISTENER_(groupsRequestListener); + _STOP_LISTENER_(persistentDataListener); + _STOP_LISTENER_(groupLocalListener); + + _FREE_LISTENER_(capabilityListener); + _FREE_LISTENER_(dcpsPublicationListener); + _FREE_LISTENER_(durabilityStateRequestListener); + _FREE_LISTENER_(historicalDataRequestListener); + _FREE_LISTENER_(remoteReaderListener); + _FREE_LISTENER_(deleteDataListener); + _FREE_LISTENER_(sampleRequestListener); + _FREE_LISTENER_(sampleChainListener); + _FREE_LISTENER_(groupRemoteListener); + _FREE_LISTENER_(statusListener); + _FREE_LISTENER_(nameSpacesRequestListener); + _FREE_LISTENER_(nameSpacesListener); + _FREE_LISTENER_(groupsRequestListener); + _FREE_LISTENER_(persistentDataListener); + _FREE_LISTENER_(groupLocalListener); + } +} + +d_store +d_subscriberGetPersistentStore( + d_subscriber subscriber) +{ + d_store store; + + assert(subscriber); + store = NULL; + + if(subscriber){ + store = subscriber->persistentStore; + } + return store; +} + +d_groupLocalListener +d_subscriberGetGroupLocalListener( + d_subscriber subscriber) +{ + d_groupLocalListener listener = NULL; + + assert(d_objectIsValid(d_object(subscriber), D_SUBSCRIBER) == TRUE); + + if(subscriber){ + listener = subscriber->groupLocalListener; + } + return listener; +} + +d_sampleChainListener +d_subscriberGetSampleChainListener( + d_subscriber subscriber) +{ + d_sampleChainListener listener = NULL; + + assert(d_objectIsValid(d_object(subscriber), D_SUBSCRIBER) == TRUE); + + if(subscriber){ + listener = subscriber->sampleChainListener; + } + return listener; +} + +d_nameSpacesRequestListener +d_subscriberGetNameSpacesRequestListener( + d_subscriber subscriber) +{ + d_nameSpacesRequestListener listener = NULL; + + assert(d_objectIsValid(d_object(subscriber), D_SUBSCRIBER) == TRUE); + + if(subscriber){ + listener = subscriber->nameSpacesRequestListener; + } + return listener; +} + + +d_historicalDataRequestListener +d_subscriberGetHistoricalDataRequestListener( + d_subscriber subscriber) +{ + assert(d_subscriberIsValid(subscriber)); + + return subscriber->historicalDataRequestListener; +} + + +c_bool +d_subscriberAreRemoteGroupsHandled( + d_subscriber subscriber) +{ + c_bool result = FALSE; + + assert(d_objectIsValid(d_object(subscriber), D_SUBSCRIBER) == TRUE); + + if(subscriber){ + if(subscriber->groupRemoteListener) { + result = d_groupRemoteListenerAreRemoteGroupsHandled(subscriber->groupRemoteListener); + } + } + return result; +} diff --git a/src/services/durability/code/d_table.c b/src/services/durability/code/d_table.c new file mode 100644 index 000000000..ac752b351 --- /dev/null +++ b/src/services/durability/code/d_table.c @@ -0,0 +1,279 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#include +#include "ut_avl.h" +#include "d__misc.h" +#include "d__table.h" + + + + +/************************************************************** + * Public functions + **************************************************************/ + +c_ulong +d_tableSize( + d_table table ) +{ + c_ulong size; + + size = 0; + if (table) { + /* QAC EXPECT 3892; */ + assert(d_tableIsValid(table)); + size = (c_ulong) ut_avlCCount (&table->tree); + } + return size; +} + +/*********************************************************************** + ***********************************************************************/ + +/** returns zero if the entry is added */ +c_voidp +d_tableInsert( + d_table table, + c_voidp object ) +{ + c_voidp existingItem; + + existingItem = object; + if (table) { + d_tableNode node; + ut_avlIPath_t p; + /* QAC EXPECT 3892; */ + assert(d_tableIsValid(table)); + if ((node = ut_avlCLookupIPath (&table->td, &table->tree, object, &p)) != NULL) { + existingItem = node->object; + } else if ((node = d_malloc (sizeof (*node), "d_tableNode")) != NULL) { + node->object = object; + ut_avlCInsertIPath (&table->td, &table->tree, node, &p); + existingItem = NULL; + } + } + return existingItem; +} + +/*********************************************************************** + ***********************************************************************/ + +c_voidp +d_tableFind( + d_table table, + c_voidp arg ) +{ + c_voidp dataFound; + + dataFound = NULL; + if (arg && table) { + d_tableNode node; + /* QAC EXPECT 3892; */ + assert(d_tableIsValid(table)); + if ((node = ut_avlCLookup (&table->td, &table->tree, arg)) != NULL) { + dataFound = node->object; + } + } + return dataFound; +} + +/*********************************************************************** + ***********************************************************************/ + +c_voidp +d_tableFirst( + d_table table ) +{ + c_voidp dataFound; + + dataFound = NULL; + if (table) { + d_tableNode node; + /* QAC EXPECT 3892; */ + assert(d_tableIsValid(table)); + if ((node = ut_avlCFindMin (&table->td, &table->tree)) != NULL) { + dataFound = node->object; + } + } + return dataFound; +} + +/*********************************************************************** + ***********************************************************************/ + +c_bool +d_tableWalk( + d_table table, + c_bool ( * action ) (), + c_voidp userData ) +{ + c_bool result; + + if (table) { + ut_avlCIter_t it; + d_tableNode n; + /* QAC EXPECT 3892; */ + assert(d_tableIsValid(table)); + result = TRUE; + for (n = ut_avlCIterFirst (&table->td, &table->tree, &it); + n && result; + n = ut_avlCIterNext (&it)) { + result = action (n->object, userData); + } + } else { + result = FALSE; + } + return result; +} + +/*********************************************************************** + ***********************************************************************/ + +c_voidp +d_tableRemove( + d_table table, + c_voidp arg ) +{ + c_voidp result; + + result = NULL; + if (table) { + d_tableNode node; + ut_avlDPath_t p; + /* QAC EXPECT 3892; */ + assert(d_tableIsValid(table)); + if ((node = ut_avlCLookupDPath (&table->td, &table->tree, arg, &p)) != NULL) { + result = node->object; + ut_avlCDeleteDPath (&table->td, &table->tree, node, &p); + d_free (node); + } + } + return result; +} + +/*********************************************************************** + ***********************************************************************/ + +c_voidp +d_tableTake( + d_table table) +{ + c_voidp result; + + result = NULL; + if (table) { + /* Delete an arbitrarily chosen node: the obvious candidates + are: root, min and max. */ + d_tableNode node; + if ((node = ut_avlCRoot (&table->td, &table->tree)) != NULL) { + result = node->object; + ut_avlCDelete (&table->td, &table->tree, node); + d_free(node); + } + } + return result; +} + +/*********************************************************************** + ***********************************************************************/ + +static void d_tableFreeHelper (void *vnode, void *varg) +{ + d_tableNode node = vnode; + d_table table = varg; + if (table->cleanAction) { + table->cleanAction (node->object); + } + d_free (node); +} + +void +d_tableDeinit( + d_table table) +{ + assert(d_tableIsValid(table)); + + if (table) { + /* Clean up all stuff that was allocated */ + ut_avlCFreeArg (&table->td, &table->tree, d_tableFreeHelper, table); + /* Call super-deinit */ + d_objectDeinit(d_object(table)); + } +} + +void +d_tableFree( + d_table table ) +{ + assert(d_tableIsValid(table)); + + if (table) { + d_objectFree(d_object(table)); + } +} + +/*********************************************************************** + ***********************************************************************/ + +d_table +d_tableNew( + int ( * compare )(), + void ( * cleanAction )() ) +{ + d_table table; + + assert(compare != 0); + /* Allocate table object */ + table = (d_table)d_malloc(C_SIZEOF(d_table), "Table"); + if (table) { + /* QAC EXPECT 3892; */ + /* Call super-init */ + d_objectInit(d_object(table), D_TABLE, + (d_objectDeinitFunc)d_tableDeinit); + /* Initialize table object */ + ut_avlCTreedefInit (&table->td, + offsetof (C_STRUCT(d_tableNode), avlnode), offsetof (C_STRUCT(d_tableNode), object), + (int (*) (const void *, const void *)) compare, 0, + UT_AVL_TREEDEF_FLAG_INDKEY); + ut_avlCInit (&table->td, &table->tree); + table->cleanAction = cleanAction; + } + return table; +} + + +void * +d_tableIterFirst( + d_table table, + d_tableIter *iter) +{ + if (table == NULL) { + return NULL; + } else { + d_tableNode n = ut_avlCIterFirst(&table->td, &table->tree, &iter->it); + return n ? n->object : NULL; + } +} + +void * +d_tableIterNext( + d_tableIter *iter) +{ + d_tableNode n = ut_avlCIterNext(&iter->it); + return n ? n->object : NULL; +} diff --git a/src/services/durability/code/d_thread.c b/src/services/durability/code/d_thread.c new file mode 100644 index 000000000..4b46da0ed --- /dev/null +++ b/src/services/durability/code/d_thread.c @@ -0,0 +1,306 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "os_time.h" +#include "os_report.h" + +#include "d__misc.h" +#include "d__types.h" +#include "d__thread.h" +#include "u_service.h" + +/* Maximum number of threads has a hard-coded limit for simplicity in + thread management code. Overestimating it means a little more + memory is used and that the service lease renewing touches a bit + more memory (and takes a bit more time). */ +#define D_MAX_THREADS 32 + +#ifndef D_LOG_STACKTRACE +#define log_stacktrace(...) +#else +static void log_stacktrace(const char*, os_threadId); +#endif + +static ut_threads d_threads = NULL; + +d_thread d_threadLookupId (os_threadId tid) +{ + assert(d_threads); + return (d_thread)ut_threadLookupId(d_threads, tid); +} + +d_thread d_threadLookupSelf (void) +{ + assert(d_threads); + return (d_thread)ut_threadLookupSelf(d_threads); +} + +d_durability d_threadsDurability() +{ + assert(d_threads); + return (d_durability)ut_threadsUserData(d_threads); +} + +os_result d_threadsInit (d_durability durability) +{ + os_result osr = os_resultSuccess; + d_threads = ut_threadsNew("ospl_durability", UT_SLEEP_INDEFINITELY, D_MAX_THREADS, (void*)durability); + if (d_threads == NULL) { + OS_REPORT(OS_ERROR, D_CONTEXT, 0, "Could not create durability threads management."); + osr = os_resultFail; + } + return osr; +} + +void d_threadsDeinit (void) +{ + if (d_threads != NULL) { + ut_threadsFree(d_threads); + d_threads = NULL; + } +} + +struct d_threadArguments { + u_domainId_t domainId; + os_threadRoutine start_routine; + void *arguments; +}; + +static void * +d_threadWrapperRoutine( + void *args) +{ + struct d_threadArguments *ti = args; + os_threadRoutine start_routine; + void *arguments; + + assert(ti); + + u_serviceThreadSetDomainId(ti->domainId); + + start_routine = ti->start_routine; + arguments = ti->arguments; + + os_free(ti); + + return start_routine(arguments); +} + +os_result d_threadCreate (os_threadId *threadId, const char *name, const os_threadAttr *threadAttr, os_threadRoutine start_routine, void *arg) +{ + os_result osr = os_resultFail; + ut_thread thr; + struct d_threadArguments *ti; + + assert(d_threads); + + ti = os_malloc(sizeof(*ti)); + ti->domainId = u_serviceThreadGetDomainId(); + ti->start_routine = start_routine; + ti->arguments = arg; + + ut_threadCreate(d_threads, &thr, name, threadAttr, d_threadWrapperRoutine, ti); + if (thr != NULL) { + *threadId = ut_threadGetId(thr); + osr = os_resultSuccess; + } else { + os_free(ti); + } + return osr; +} + +os_result d_threadWaitExit (os_threadId threadId, void **thread_result) +{ + os_result osr = os_resultFail; + ut_thread thr; + assert(d_threads); + thr = ut_threadLookupId(d_threads, threadId); + if (thr != NULL) { + osr = ut_threadWaitExit(thr, thread_result); + } + return osr; +} + +void d_threadLivelinessInit (os_duration min_intv) +{ + assert(d_threads); + ut_threadsSetInterval(d_threads, min_intv); +} + +#define D_REPORT_BUFFER_SIZE (2048) + +typedef struct { + char *buffer; + os_uint32 size; + os_uint32 pos; + os_timeM currentTime; + os_duration updateInterval; +} d_threadReportArg; + +static void +d_threadsReport( + ut_thread thread, + os_boolean alive, + os_boolean changed, + const char *info, + const char *caller, + void *reportdata, + void *userdata) +{ + static os_timeM lastReport = {OS_TIME_ZERO}; + struct d_durability_s * durability = (struct d_durability_s*)userdata; + d_threadReportArg *report = (d_threadReportArg*)reportdata; + os_uint32 length = (report->size > report->pos) ? report->size - report->pos : 0; + os_uint32 start = report->pos; + os_boolean print; + + OS_UNUSED_ARG(caller); + + assert(length != 0); /* size of the buffer is too small */ + + /* No need to do anything if nothing changed and + * no periodic thread overview required */ + if (!changed && (os_durationCompare(report->updateInterval, OS_DURATION_ZERO) != OS_MORE)) { + return; + } + + /* Decide whether to print an overview now */ + print = (os_durationCompare(os_timeMDiff(report->currentTime, lastReport), report->updateInterval) == OS_MORE); + + /* Always print log message when liveliness of a thread has changed + * In case a message must be printed periodically we need to build up a string + * containing the relevant liveliness information for this thread */ + if (thread != NULL) { + if (changed || print) { + report->pos += ut_threadToString(thread, + alive, + info, + &(report->buffer[start]), + length); + } + if (changed) { + d_printTimedEvent(durability, alive ? D_LEVEL_INFO : D_LEVEL_WARNING, "Progress changed: %s\n", &(report->buffer[start])); + } + } + else if (print) { + (void)snprintf(&(report->buffer[start]), length, " [%s]", alive ? "OK" : "NOK"); + d_printTimedEvent(durability, alive ? D_LEVEL_INFO : D_LEVEL_WARNING, "Threads info: %s\n", report->buffer); + /* Remember the last reported liveliness */ + lastReport = report->currentTime; + } +} + +/** + * \brief This operation checks if all threads are alive and generates + * a periodic durability report message. + * + * \param currentTime : Current timestamp used for determining if report should be generated. + * \param updateInterval : Minimum period between generated report messages. + * + * \return : TRUE when all threads are alive + * FALSE otherwise + */ +os_boolean d_threadLivelinessCheck (os_timeM currentTime, os_duration updateInterval) +{ + d_threadReportArg arg; + char buffer[D_REPORT_BUFFER_SIZE]; + + assert(d_threads); + + buffer[0] = '\0'; + arg.buffer = &buffer[0]; + arg.size = D_REPORT_BUFFER_SIZE; + arg.currentTime = currentTime; + arg.updateInterval = updateInterval; + arg.pos = 0; + + return ut_threadsAllIsWell(d_threads, d_threadsReport, &arg); +} + +const char* d_threadSelfName() +{ + static char t_main[] = "
    "; /* printed when d_threads not yet initialized (only occurs for main thread) */ + static char t_unknown[] = ""; /* printed when d_threads initialized but lookup failed */ + ut_thread thr; + if (!d_threads) { + return t_main; + } + thr = ut_threadLookupSelf(d_threads); + if (thr) { + return ut_threadGetName(thr); + } + return t_unknown; +} + +#ifdef D_LOG_STACKTRACE + +#include +#include + +static pa_uint32_t log_stacktrace_flag = PA_UINT32_INIT(0); + +static void log_stacktrace_sigh (int sig __attribute__ ((unused))) +{ + void *stk[64]; + char **strs; + int i, n; + struct d_durability_s *durability; + const char *thrName; + + assert(d_threads); + durability = (struct d_durability_s*)ut_threadsUserData(d_threads); + thrName = d_threadSelfName(); + + d_printTimedEvent(durability, D_LEVEL_FINEST, thrName, "-- stack trace follows --\n"); + n = backtrace (stk, (int) (sizeof (stk) / sizeof (*stk))); + strs = backtrace_symbols (stk, n); + for (i = 0; i < n; i++) { + d_printTimedEvent(durability, D_LEVEL_FINEST, thrName, "%s\n", strs[i]); + } + + free (strs); + d_printTimedEvent(durability, D_LEVEL_FINEST, thrName, "-- end of stack trace -- \n"); + pa_inc32 (&log_stacktrace_flag); +} + +static void log_stacktrace (const char *name, os_threadId tid) +{ + const os_duration d = OS_DURATION_INIT(0, 1000000); + struct sigaction act, oact; + struct d_durability_s *durability; + const char *thrName; + + assert(d_threads); + durability = (struct d_durability_s*)ut_threadsUserData(d_threads); + thrName = d_threadSelfName(); + + d_printTimedEvent(durability, D_LEVEL_FINEST, thrName, "-- stack trace of %s requested --\n", name); + act.sa_handler = log_stacktrace_sigh; + act.sa_flags = 0; + (void)sigfillset (&act.sa_mask); + while (!pa_cas32 (&log_stacktrace_flag, 0, 1)) + ospl_os_sleep (d); + sigaction (SIGXCPU, &act, &oact); + pthread_kill (tid, SIGXCPU); + while (!pa_cas32 (&log_stacktrace_flag, 2, 3)) + ospl_os_sleep (d); + sigaction (SIGXCPU, &oact, NULL); + pa_st32 (&log_stacktrace_flag, 0); +} + +#endif /* D_LOG_STACKTRACE */ diff --git a/src/services/durability/code/d_waitset.c b/src/services/durability/code/d_waitset.c new file mode 100644 index 000000000..ad7c91ef9 --- /dev/null +++ b/src/services/durability/code/d_waitset.c @@ -0,0 +1,373 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#include "d__waitset.h" +#include "d__subscriber.h" +#include "d__admin.h" +#include "d__durability.h" +#include "d__misc.h" +#include "d__thread.h" +#include "u_waitset.h" +#include "u_participant.h" +#include "u_entity.h" +#include "u_observable.h" +#include "v_event.h" +#include "v_observer.h" +#include "os_heap.h" +#include "os_stdlib.h" +#include "os_thread.h" +#include "os_report.h" + +C_CLASS(d_waitsetHelper); + +C_STRUCT(d_waitsetHelper) { + d_waitset waitset; + u_waitset userWaitset; + d_waitsetEntity entity; + os_threadId tid; + c_bool terminate; +}; + +#define d_waitsetHelper(h) ((d_waitsetHelper)(h)) + +static void +resetFlags( + v_public p, c_voidp arg) +{ + OS_UNUSED_ARG(arg); + (void)v_observerClearEventFlags(v_observer(p)); +} + +static void +process_events( + v_waitsetEvent e, + void *arg) +{ + d_thread self = d_threadLookupSelf (); + d_waitsetEntity we = (d_waitsetEntity)arg; + + d_threadAwake(self); + we->action(we->object, e, we->usrData); + d_threadAsleep(self, 1); +} + +static void* +d_waitsetEventHandler( + void* userData) +{ + d_thread self = d_threadLookupSelf (); + d_subscriber subscriber; + d_durability durability; + d_admin admin; + d_waitsetHelper helper; + d_waitsetEntity we; + u_result ur; + os_duration timeout; + + helper = d_waitsetHelper(userData); + subscriber = d_waitsetGetSubscriber(helper->waitset); + admin = d_subscriberGetAdmin(subscriber); + durability = d_adminGetDurability(admin); + we = helper->entity; + timeout = OS_DURATION_INIT(1,0); /* wake up every second to assert liveliness */ + ur = U_RESULT_OK; + + while ((helper->terminate == FALSE) && (ur == U_RESULT_OK)) { + (void)u_observableAction(u_observable(we->object), resetFlags, NULL); + /* Assert liveliness every 1 second while waiting for events */ + d_threadAsleep(self, (os_uint32) OS_DURATION_GET_SECONDS(timeout) + (OS_DURATION_GET_NANOSECONDS(timeout) > 0)); + ur = u_waitsetWaitAction(helper->userWaitset, process_events, we, timeout); + if (ur == U_RESULT_TIMEOUT) { + ur = U_RESULT_OK; + } + d_threadAwake(self); + } /* while */ + if (ur != U_RESULT_OK) { + d_printTimedEvent(durability, D_LEVEL_SEVERE, we->name, + "Waitset no longer available (result: %s). Fatal error, terminating now...\n", + u_resultImage(ur)); + OS_REPORT(OS_ERROR, D_CONTEXT_DURABILITY, 0, + "Waitset no longer available (result: %s). Fatal error, terminating now...\n", + u_resultImage(ur)); + d_durabilityTerminate(durability, TRUE); + d_printTimedEvent(durability, D_LEVEL_SEVERE, we->name, + "Waitset no longer available (result: %s). Fatal error, terminating now...\n", + u_resultImage(ur)); + } + return NULL; +} + + +void +d_waitsetDeinit( + d_waitset waitset) +{ + d_waitsetEntity we; + d_waitsetHelper helper; + + assert(d_waitsetIsValid(waitset)); + + waitset->terminate = TRUE; + if (waitset->threads) { + /* Stop all threads */ + helper = d_waitsetHelper(c_iterTakeFirst(waitset->threads)); + while (helper) { + helper->terminate = TRUE; + u_waitsetNotify(helper->userWaitset, NULL); + d_threadWaitExit(helper->tid, NULL); + u_waitsetDetach(helper->userWaitset, u_observable(helper->entity->object)); + u_objectFree(u_object(helper->userWaitset)); + os_free(helper); + helper = d_waitsetHelper(c_iterTakeFirst(waitset->threads)); + } + c_iterFree(waitset->threads); + waitset->threads = NULL; + } + /* Lock the waitset while removing entities */ + d_lockLock(d_lock(waitset)); + if (waitset->entities) { + /* Remove the entities associated with the waitset */ + we = d_waitsetEntity(c_iterTakeFirst(waitset->entities)); + while(we) { + d_waitsetEntityFree(we); + we = d_waitsetEntity(c_iterTakeFirst(waitset->entities)); + } + c_iterFree(waitset->entities); + waitset->entities = NULL; + } + /* Unlock the waitset */ + d_lockUnlock(d_lock(waitset)); + /* Call super-deinit */ + d_lockDeinit(d_lock(waitset)); +} + +void +d_waitsetFree( + d_waitset waitset) +{ + assert(d_waitsetIsValid(waitset)); + + d_objectFree(d_object(waitset)); +} + +d_waitset +d_waitsetNew( + d_subscriber subscriber) +{ + d_waitset waitset = NULL; + + assert(d_subscriberIsValid(subscriber)); + + if (subscriber) { + /* Allocate waitset */ + waitset = d_waitset(os_malloc(C_SIZEOF(d_waitset))); + if (waitset) { + /* Call super-init */ + d_lockInit(d_lock(waitset), D_WAITSET, + (d_objectDeinitFunc)d_waitsetDeinit); + /* Initialize waitset */ + waitset->terminate = FALSE; + waitset->subscriber = subscriber; + waitset->entities = c_iterNew(NULL); + waitset->threads = c_iterNew(NULL); + } + } + return waitset; +} + +c_bool +d_waitsetAttach( + d_waitset waitset, + d_waitsetEntity we) +{ + c_bool result = FALSE; + u_result ur; + os_result osr; + d_waitsetHelper helper; + + assert(d_waitsetIsValid(waitset)); + assert(d_waitsetEntityIsValid(we)); + + if (waitset && we) { + d_lockLock(d_lock(waitset)); + if (!we->waitset) { + if (c_iterContains(waitset->entities, we) == FALSE) { + waitset->entities = c_iterInsert(waitset->entities, we); + + helper = os_malloc(C_SIZEOF(d_waitsetHelper)); + helper->waitset = waitset; + helper->entity = we; + helper->terminate = FALSE; + helper->tid = OS_THREAD_ID_NONE; + helper->userWaitset = u_waitsetNew(); + u_waitsetSetEventMask(helper->userWaitset, we->mask); + ur = u_waitsetAttach(helper->userWaitset, + u_observable(we->object), + (c_voidp)we->object); + if (ur == U_RESULT_OK) { + waitset->threads = c_iterInsert(waitset->threads, helper); + /* Create a thread for the waitset */ + osr = d_threadCreate(&(helper->tid), + we->name, + &(we->attr), + d_waitsetEventHandler, helper); + + if (osr == os_resultSuccess) { + result = TRUE; + } else { + c_iterTake(waitset->threads, helper); + u_waitsetDetach(helper->userWaitset, u_observable(we->object)); + u_objectFree(u_object(helper->userWaitset)); + os_free(helper); + } + } else { + assert(FALSE); + u_objectFree(u_object(helper->userWaitset)); + os_free(helper); + } + } + } + d_lockUnlock(d_lock(waitset)); + } + return result; +} + +c_bool +d_waitsetDetach( + d_waitset waitset, + d_waitsetEntity we) +{ + d_waitsetEntity found; + u_result ur; + c_bool result = FALSE; + d_waitsetHelper helper; + u_eventMask mask; + c_ulong i; + + assert(d_waitsetIsValid(waitset)); + assert(d_waitsetEntityIsValid(we)); + + if (waitset && we) { + d_lockLock(d_lock(waitset)); + found = c_iterTake(waitset->entities, we); + if (found == we) { + helper = NULL; + for (i=0; ithreads) && !helper; i++) { + helper = d_waitsetHelper(c_iterObject(waitset->threads, i)); + if (helper->entity != we) { + helper = NULL; + } + } + assert(helper); + c_iterTake(waitset->threads, helper); + helper->terminate = TRUE; + /* Be sure that the helper reacts on our notification. */ + (void)u_waitsetGetEventMask(helper->userWaitset, &mask); + mask |= V_EVENT_TRIGGER; + (void)u_waitsetSetEventMask(helper->userWaitset, mask); + /* Now, wake up the helper thread. */ + u_waitsetNotify(helper->userWaitset, NULL); + d_threadWaitExit(helper->tid, NULL); + ur = u_waitsetDetach_s(helper->userWaitset, u_observable(we->object)); + u_objectFree(u_object (helper->userWaitset)); + os_free(helper); + we->waitset = NULL; + if (ur == U_RESULT_OK || ur == U_RESULT_OUT_OF_MEMORY) { + result = TRUE; + } + } + d_lockUnlock(d_lock(waitset)); + } + return result; +} + +d_subscriber +d_waitsetGetSubscriber( + d_waitset waitset) +{ + d_subscriber subscriber = NULL; + + assert(d_waitsetIsValid(waitset)); + + if (waitset) { + subscriber = waitset->subscriber; + } + return subscriber; +} + +d_waitsetEntity +d_waitsetEntityNew( + const c_char* name, + u_object object, + d_waitsetAction action, + c_ulong mask, + os_threadAttr attr, + c_voidp usrData) +{ + d_waitsetEntity we = NULL; + + assert(object); + assert(action); + + if (object && action) { + /* Allocate waitsetEntity object */ + we = d_waitsetEntity(os_malloc(C_SIZEOF(d_waitsetEntity))); + if (we) { + /* Call super-init */ + d_objectInit(d_object(we), D_WAITSET_ENTITY, + (d_objectDeinitFunc)d_waitsetEntityDeinit); + /* Initialize waitsetEntity */ + if (name) { + we->name = os_strdup(name); + } else { + we->name = os_strdup("waitsetEntity"); + } + we->action = action; + we->object = object; + we->mask = mask; + we->usrData = usrData; + we->attr = attr; + we->waitset = NULL; + } + } + return we; +} + +void +d_waitsetEntityDeinit( + d_waitsetEntity we) +{ + assert(d_waitsetEntityIsValid(we)); + + if (we->name) { + os_free(we->name); + } + if (we->waitset) { + d_waitsetDetach(we->waitset, we); + } + /* Call super-deinit */ + d_objectDeinit(d_object(we)); +} + +void +d_waitsetEntityFree( + d_waitsetEntity we) +{ + assert(d_waitsetEntityIsValid(we)); + + d_objectFree(d_object(we)); +} diff --git a/src/services/durability/code/durability.int b/src/services/durability/code/durability.int new file mode 100644 index 000000000..5b3032148 --- /dev/null +++ b/src/services/durability/code/durability.int @@ -0,0 +1,24 @@ +Kernel + Filename DynamicDownload +EndKernel + +AddressSpace + Name durability + Filename durability + MemoryPoolSize 0x100000 + MaximumPriority 254 + MaximumWeight 65535 + Language C + HeapSize 0x200000 + + Object + MemoryRegion + Name .argsection + Section .argsection + EndObject + + Task Initial + StartIt true + StackSize 0x10000 + EndTask +EndAddressSpace diff --git a/src/services/durability/code/durability.odl b/src/services/durability/code/durability.odl new file mode 100644 index 000000000..cb9576b25 --- /dev/null +++ b/src/services/durability/code/durability.odl @@ -0,0 +1,401 @@ +/* -*- c++ -*- */ +#include "v_kernel.odl" + + +/** + * \file durability.odl + * + * This file contains data definitions for durability protocol messages. + * + */ +module durabilityModule2 { + typedef c_time d_timestamp; + typedef c_time d_qualityExt; + typedef c_string d_name; + typedef c_string d_partition; + typedef c_string d_topic; + + /** + * Each entity is globally uniquely identified by a global id, the following + * durability network address data structure holds the attributes that together + * implement the globally unique id. This structure is used in protocol messages + * to identify the durability service (that sends messages, i.e. the source, or + * that shall receive the message i.e. destination). + */ + struct d_networkAddress_s { + c_ulong systemId; + c_ulong localId; + c_ulong lifecycleId; + }; + + /** + * Name-value pairs are used as generic extension attributes of messages. + * The use of name-value pairs are NOT part of the 'old' durability + * protocol. It is a good pratice to use extensions in topics that are + * newly defined, unless there are reasons not to use it. + */ + struct d_nameValue_s { + c_string name; + sequence value; + }; + + /** + * The service state specifies the operational state of the durability service and is + * an attribute of all protocol messages. + * The operational state will start with INIT and then progress trough several states + * which identify the steps to get the state of the data aligned with the rest of the + * system until it gets to the COMPLETE state. + * The Complete state is the normal (full) operational state, from this state it has + * all data and can align others. + * The service will end in the TERMINATED state, it can reach this state from any + * other state going through the terminating state. + */ + enum d_serviceState { + D_STATE_INIT, + D_STATE_DISCOVER_FELLOWS_GROUPS, + D_STATE_DISCOVER_LOCAL_GROUPS, + D_STATE_DISCOVER_PERSISTENT_SOURCE, + D_STATE_INJECT_PERSISTENT, + D_STATE_FETCH_INITIAL, + D_STATE_COMPLETE, + D_STATE_FETCH, + D_STATE_ALIGN, + D_STATE_FETCH_ALIGN, + D_STATE_TERMINATING, + D_STATE_TERMINATED + }; + + /** + * This enumeration is used by several protocol messages to indicate the state of a group. + * The completeness of a group tells if the durability service has and knows he has all + * the data in the system belonging to the group. + */ + enum d_completeness { + D_GROUP_KNOWLEDGE_UNDEFINED, + D_GROUP_UNKNOWN, + D_GROUP_INCOMPLETE, + D_GROUP_COMPLETE + }; + + /** + * This enumeration is used by several protocol messages to indicate the durability quality + * of service applicable in for that protocol message. So the exact meaning depends on the + * protocol, it can be used as an exact value or as a limitation value. + * When used as a limitation value it defines the maximum durability strength of a range, + * e.g. if the value is D_DURABILITY_TRANSIENT it implies also TRANSIENT_LOCAL and VOLATILE. + */ + enum d_durabilityKind { + D_DURABILITY_VOLATILE, + D_DURABILITY_TRANSIENT_LOCAL, + D_DURABILITY_TRANSIENT, + D_DURABILITY_PERSISTENT, + D_DURABILITY_ALL + }; + + /** + * This enumeration is used by the namespace exchange protocol to communicate the + * alignment policy used by the fellow durability service sending the namespace information. + */ + enum d_alignmentKind { + D_ALIGNEE_INITIAL, + D_ALIGNEE_LAZY, + D_ALIGNEE_ON_REQUEST + }; + + enum d_mergePolicy { + D_MERGE_IGNORE, + D_MERGE_MERGE, + D_MERGE_DELETE, + D_MERGE_REPLACE, + D_MERGE_CATCHUP + }; + + struct d_mergeState_s { + d_name role; + c_ulong value; + }; + + /** + * The d_message_s structure defines the header of all durability protocol messages. + * All protocol messages define the first field to be of this type and named: parentMsg. + * + * Although the productionTimestamp is a timestamp it is not used as such. Instead, various + * bits in the productionTimestamp have special meanings. + * + * Bit 31 in the nanoseconds field of the production timestamp + * If bit 31 is set, then the durability service has a reader for capability topic. + * Durability services that receive a message from a fellow durability service where + * this bit is set now know that they can send their capabilities to this fellow. + * + * Bit 30 in the nanoseconds field of the production timestamp. + * If bit 30 is set, then the seconds field in the production timestamp will contains + * a 32-bit unsigned service-specific sequence number. Fellow durability services can use + * this sequence number to order message from the fellow. The maximum allowed valid + * sequence number is 0xFFFFFFFE. Sequence number wrapping is supported. + * + * Furthermore, if bit 30 is set, then all times in durability messages are capable + * to specify times until approximately 2262. This holds for example of the beginTime + * and endTime in sampleRequests, and the quality of namespaces and groups. + * See https://confluence.prismtech.com/display/VO/Durability+and+timestamps+beyond+2038 + * for a detailed explanation how 64-bit times are implemented. + */ + struct d_message_s { + d_networkAddress_s addressee; /* the destination (fellow durability service) */ + d_networkAddress_s senderAddress; /* the source (this durability service) */ + d_serviceState senderState; /* the state of this durability service */ + d_timestamp productionTimestamp; /* publication time at this durability service */ + c_ulong sequenceNumber; /* a durability service and protocol message type specific sequence number. */ + }; + + struct d_status_s { + d_message_s parentMsg; + }; + + /** + * The following two protocol message types are exchanged between the durability service + * and a (aligner) fellow to align namespace information. + * The durability service sends a d_nameSpacesRequest_s message to a fellow durability service + * and the fellow will respond with a d_nameSpace_s message per namespace. + * Note that a non-aligner fellow will not send any information. + * The namespace message describes the definition of the namespace (topic and partition definitions) + * and describes how the durability service manages the namespace and the actual state of the namespace. + */ + struct d_nameSpacesRequest_s{ + d_message_s parentMsg; + }; + + struct d_nameSpaces_s{ + d_message_s parentMsg; + c_string name; + c_string partitions; + d_durabilityKind durabilityKind; + c_bool aligner; + d_alignmentKind alignmentKind; + d_qualityExt initialQuality; + c_ulong total; + d_networkAddress_s master; + c_bool isComplete; + c_bool masterConfirmed; + d_mergeState_s state; + sequence mergedStates; + c_ulong mergedStatesCount; + }; + + /** + * The following two protocol message types are exchanged between the durability service + * and a (aligner) fellow to lookup group information of the fellow. + * The durability service sends a d_groupRequest_s message to a fellow durability service + * on which the fellow will respond by sending a d_newGroup message for each group. + * Note that a non-aligner fellow will not send any information. + */ + struct d_groupsRequest_s { + d_message_s parentMsg; + d_partition partition; + d_topic topic; + }; + + struct d_newGroup_s { + d_message_s parentMsg; + d_partition partition; + d_topic topic; + d_completeness completeness; + d_durabilityKind durabilityKind; + d_qualityExt quality; + c_ulong alignerCount; + }; + + /** + * The following two protocol message types are exchanged between the durability service + * and a (aligner) fellow to align data from a group from the fellow. + * The durability service sends a d_sampleRequest_s message to a fellow durability service + * to request data for a specific group and the fellow will respond by sending a + * chain of d_sampleChain_s messages for each group. + * The chain consists of d_sampleChain_s messages each containing a data message and + * together contain all data from a group. The last d_sampleChain message doesn't contain + * data but instead the number of messages the chain contains, this is needed by the receiving + * durability service to verify if the chain is completely received. + * Note that a non-aligner fellow will not send any information. + */ + struct d_sampleRequest_s { + d_message_s parentMsg; + d_partition partition; + d_topic topic; + d_durabilityKind durabilityKind; + d_timestamp requestTime; + c_bool withTimeRange; + d_timestamp beginTime; + d_timestamp endTime; + d_networkAddress_s source; + c_string filter; + sequence filterParams; + c_ulong filterParamsCount; + c_long maxSamples; + c_long maxInstances; + c_long maxSamplesPerInstance; + }; + + struct d_sampleChainBead { + sequence value; + c_long size; + }; + + /** + * This value is used by the d_sampleChainTrailer messages to indicate groups are equal. + * When this value is sent as nrSamples this indicates that no samples will be aligned + * as the samples on the aligner and alignee are equal. + */ + const c_ulong D_GROUP_IS_EQUAL = 0xffffffff; + + struct d_sampleChainTrailer { + c_ulong nrSamples; + d_completeness completeness; + }; + + struct d_sampleChain_s { + d_message_s parentMsg; + c_string partition; + c_string topic; + d_durabilityKind durabilityKind; + sequence addressees; + c_ulong addresseesCount; + d_networkAddress_s source; + + union messageContent switch ( enum content { BEAD, LINK } ) + { + case BEAD: + d_sampleChainBead bead; + case LINK: + d_sampleChainTrailer link; + } msgBody; + }; + + /** + * The following protocol message type is send from the durability service to + * all other fellow durability services. When a durability service receives a + * local dispose data request it will perform the dispose action locally and + * send this message to the rest to perform a system wide action. + */ + struct d_deleteData_s { + d_message_s parentMsg; + d_timestamp actionTime; + c_string partitionExpr; + c_string topicExpr; + }; + + /* XML, KV store: retain compatibility with stores written using + v_topicQos rather than v_topicInfo. The values of + kernelModuleI::v_qosKind are mostly irrelevant, the XML + representation simply requires that V_TOPIC_QOS is among them. */ + + struct d_persistentTopicDataPolicyV0 { + ARRAY value; + c_long size; + }; + + class d_persistentQosV0 { + attribute kernelModuleI::v_qosKind kind; + }; + + class d_persistentTopicQosV0 extends d_persistentQosV0 { + attribute d_persistentTopicDataPolicyV0 topicData; + attribute kernelModule::v_durabilityPolicy durability; + attribute kernelModule::v_durabilityServicePolicy durabilityService; + attribute kernelModule::v_deadlinePolicy deadline; + attribute kernelModule::v_latencyPolicy latency; + attribute kernelModule::v_livelinessPolicy liveliness; + attribute kernelModule::v_reliabilityPolicy reliability; + attribute kernelModule::v_orderbyPolicy orderby; + attribute kernelModule::v_historyPolicy history; + attribute kernelModule::v_resourcePolicy resource; + attribute kernelModule::v_transportPolicy transport; + attribute kernelModule::v_lifespanPolicy lifespan; + attribute kernelModule::v_ownershipPolicy ownership; + }; + + /** + * The capability protocol message types are used to communicate capabilities + * between durability services. When a durability services receives a + * d_message where the most significant bit of the productionTimestamp + * attribute is set, then the sending durability service supports the + * capabilities interface. This means that the sending durability service + * has implemented a reader and writer for the d_capability topic. + * When the isRequest attribute of the topic i set to TRUE, then the + * message is considered a reuqest, otherwise it is a response. + * The capabilityMask attribute is a mask that specifies the categories + * of capabilities (there can be 32 of them). + * The capabilities attribute contain the attributes. + */ + struct d_capability_s { + d_message_s parentMsg; + sequence capabilities; + }; + + /*****************************/ + /* KV store data definitions */ + /*****************************/ + + /* d_storeKV wants to have everything serialisable with the same + serialisers (but unfortunately, the regular serialiser can't + handle c_types, so we need to treat the topic type specially). + + Note: table to integer mapping is + V = 0 + T = 1 TT = 2 + N = 3 NQ = 4 NC = 5 + G = 6 + M = 7 + We reserve 8 bits, just in case. Note also that this means the + version tag is key 0:0:0:0. */ + enum d_encodingKV { + /* Encoding of payload; encoding of types, file format in + general is up to the underlying KV store. The + {XML,BIGE{,CDR}_XML} versions use v_messageExt and + d_topicKV/v_topicQos; BIGECDR_XML_V1 intentionally uses the + internal v_message type to avoid an extra copy, and uses + v_topicInfo to represent the topic information. */ + D_ENCODINGKV_XML_XML, /* data XML, v_messageExt, d_topicKV, d_topicTypeKV */ + D_ENCODINGKV_BIGE_XML, /* data BigE, v_messageExt, d_topicKV, d_topicTypeKV */ + D_ENCODINGKV_BIGECDR_XML, /* data BigE CDR, v_messageExt, d_topicKV, d_topicTypeKV */ + D_ENCODINGKV_BIGECDR_V1 /* data BigE CDR, v_message, d_topicInfoKV */ + }; + enum d_compressionKV { + D_COMPRESSION_NONE, + D_COMPRESSION_LZF, + D_COMPRESSION_SNAPPY, + D_COMPRESSION_ZLIB, + D_COMPRESSION_CUSTOM + }; + struct d_versionKV { /* key = V:0:0:0; payload is encoded as CDR BE */ + c_ulong version; + d_encodingKV encoding; + d_compressionKV compression; + }; + struct d_topicKV { /* key = T:topic_id:0:0 */ + string name; + string type_name; + string keylist; + d_persistentTopicQosV0 qos; + }; + struct d_topicTypeKV { /* key = TT:topic_id:0:0; uses a special serialiser => no payload other than type */ + c_type type; + }; + struct d_topicInfoKV { /* key = T:topic_id:0:0 */ + kernelModule::v_topicInfo info; + }; + struct d_namespaceKV { /* key = N:namespace_id:namespace_version:0 */ + string name; + }; + struct d_namespaceQualityKV { /* key = NQ:namespace_id:namespace_version:0 */ + d_qualityExt quality; + }; + struct d_namespaceCompletenessKV { /* key = NC:namespace_id:namespace_version:0 */ + c_bool complete; + }; + struct d_groupKV { /* key = G:group_id:0:0 */ + c_ulong topic_id; + c_ulong namespace_id; + c_ulong namespace_version; + string partition; + string topic; + }; +}; diff --git a/src/services/durability/code/tmpl/d_storeKV.tmpl.c b/src/services/durability/code/tmpl/d_storeKV.tmpl.c new file mode 100644 index 000000000..72661cebc --- /dev/null +++ b/src/services/durability/code/tmpl/d_storeKV.tmpl.c @@ -0,0 +1,35 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "os_defs.h" +#include "d__store.h" +#include "d_storeKV.h" +#include "u_user.h" + + +d_storeKV d_storeNewKV (u_participant participant) +{ + OS_UNUSED_ARG(participant); + return NULL; +} + +d_storeResult d_storeFreeKV (d_storeKV store) +{ + OS_UNUSED_ARG(store); + return D_STORE_RESULT_OK; +} diff --git a/src/services/durability/include/d_deleteData.h b/src/services/durability/include/d_deleteData.h new file mode 100644 index 000000000..89cafd2d2 --- /dev/null +++ b/src/services/durability/include/d_deleteData.h @@ -0,0 +1,40 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#ifndef D_DELETEDATA_H +#define D_DELETEDATA_H + +#include "d__types.h" + +#if defined (__cplusplus) +extern "C" { +#endif + +#define d_deleteData(s) ((d_deleteData)(s)) + +d_deleteData d_deleteDataNew (d_admin admin, + os_timeW actionTime, + const c_char* partitionExpr, + const c_char* topicExpr); + +void d_deleteDataFree (d_deleteData deleteData); + +#if defined (__cplusplus) +} +#endif + +#endif /*D_DELETEDATA_H*/ diff --git a/src/services/durability/include/d_durability.h b/src/services/durability/include/d_durability.h new file mode 100644 index 000000000..2eff2b902 --- /dev/null +++ b/src/services/durability/include/d_durability.h @@ -0,0 +1,50 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + + +#ifndef D_DURABILITY_H +#define D_DURABILITY_H + +#include "u_user.h" +#include "d__types.h" +#include "v_durabilityStatistics.h" +#include "v_kernel.h" +#include "vortex_os.h" + +#if defined (__cplusplus) +extern "C" { +#endif + +#include "os_if.h" + +#ifdef OSPL_BUILD_DURABILITY +#define OS_API OS_API_EXPORT +#else +#define OS_API OS_API_IMPORT +#endif +/* !!!!!!!!NOTE From here no more includes are allowed!!!!!!! */ + +OS_API OPENSPLICE_ENTRYPOINT_DECL(ospl_durability); + +#undef OS_API + +#if defined (__cplusplus) +} +#endif + +#endif /* D_DURABILITY_H */ diff --git a/src/services/durability/include/d_groupsRequest.h b/src/services/durability/include/d_groupsRequest.h new file mode 100644 index 000000000..dcea0ee2d --- /dev/null +++ b/src/services/durability/include/d_groupsRequest.h @@ -0,0 +1,40 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef D_GROUPSREQUEST_H +#define D_GROUPSREQUEST_H + +#include "d__types.h" + +#if defined (__cplusplus) +extern "C" { +#endif + +#define d_groupsRequest(s) ((d_groupsRequest)(s)) + +d_groupsRequest d_groupsRequestNew (d_admin admin, + d_partition partition, + d_topic topic); + +void d_groupsRequestFree (d_groupsRequest groupsRequest); + +#if defined (__cplusplus) +} +#endif + +#endif /* D_GROUPSREQUEST_H */ diff --git a/src/services/durability/include/d_message.h b/src/services/durability/include/d_message.h new file mode 100644 index 000000000..c273cf0f0 --- /dev/null +++ b/src/services/durability/include/d_message.h @@ -0,0 +1,54 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef D_MESSAGE_H +#define D_MESSAGE_H + +#include "u_user.h" +#include "d__types.h" + +#if defined (__cplusplus) +extern "C" { +#endif + +/* Macro to check if the message uses time stamps beyond 2038. + * The check consist of checking bit 30 of the nanoseconds field of the message */ +#define IS_Y2038READY(d) ((c_bool)(((d_message(d)->productionTimestamp.nanoseconds) & (1u << 30)) == (1u << 30))) + +#define d_message(d) ((d_message)(d)) + +void d_messageInit (d_message message, + d_admin admin); + +void d_messageDeinit (d_message message); + +void d_messageSetAddressee (d_message message, + d_networkAddress addressee); + +d_networkAddress d_messageGetAddressee (d_message message); + +void d_messageSetSenderAddress (d_message message, + d_networkAddress address); + +c_bool d_messageHasCapabilitySupport (d_message message); + +#if defined (__cplusplus) +} +#endif + +#endif /* D_MESSAGE_H */ diff --git a/src/services/durability/include/d_nameSpaces.h b/src/services/durability/include/d_nameSpaces.h new file mode 100644 index 000000000..7fb27b3c1 --- /dev/null +++ b/src/services/durability/include/d_nameSpaces.h @@ -0,0 +1,73 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef D_NAMESPACES_H +#define D_NAMESPACES_H + +#include "d__types.h" +#include "d__misc.h" + +#if defined (__cplusplus) +extern "C" { +#endif + +#define d_nameSpaces(n) ((d_nameSpaces)(n)) +#define d_nsElement(e) ((d_nsElement)(e)) +#define d_nsPartition(e) ((d_nsPartition)(e)) + +typedef enum d_nsEquality_s{ + D_LESS, D_GREATER, D_EQUAL, D_INTERSECT, D_DIFFERENT +} d_nsEquality; + +d_nameSpaces d_nameSpacesNew (d_admin admin, + d_nameSpace nameSpace, + d_quality initialQuality, + c_ulong total); + +void d_nameSpacesFree (d_nameSpaces namespaces); + +int d_nameSpacesCompare (d_nameSpaces ns1, + d_nameSpaces ns2); + +d_alignmentKind d_nameSpacesGetAlignmentKind (d_nameSpaces nameSpaces); + +d_durabilityKind d_nameSpacesGetDurabilityKind (d_nameSpaces nameSpaces); + +c_bool d_nameSpacesIsAligner (d_nameSpaces nameSpaces); + +c_ulong d_nameSpacesGetTotal (d_nameSpaces nameSpaces); + +c_char* d_nameSpacesGetPartitions (d_nameSpaces nameSpaces); + +d_quality d_nameSpacesGetInitialQuality (d_nameSpaces nameSpaces); + +d_networkAddress d_nameSpacesGetMaster (d_nameSpaces nameSpaces); + +char* d_nameSpacesGetName (d_nameSpaces nameSpaces); + +void d_nameSpacesSetMaster (d_nameSpaces nameSpaces, + d_networkAddress master); + +void d_nameSpacesSetTotal (d_nameSpaces nameSpaces, + c_ulong total); + +#if defined (__cplusplus) +} +#endif + +#endif /*D_NAMESPACES_H*/ diff --git a/src/services/durability/include/d_nameSpacesRequest.h b/src/services/durability/include/d_nameSpacesRequest.h new file mode 100644 index 000000000..dfe6c123c --- /dev/null +++ b/src/services/durability/include/d_nameSpacesRequest.h @@ -0,0 +1,38 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef D_NAMESPACESREQUEST_H +#define D_NAMESPACESREQUEST_H + +#include "d__types.h" + +#if defined (__cplusplus) +extern "C" { +#endif + +#define d_nameSpacesRequest(s) ((d_nameSpacesRequest)(s)) + +d_nameSpacesRequest d_nameSpacesRequestNew (d_admin admin); + +void d_nameSpacesRequestFree (d_nameSpacesRequest request); + +#if defined (__cplusplus) +} +#endif + +#endif /*D_NAMESPACESREQUEST_H*/ diff --git a/src/services/durability/include/d_networkAddress.h b/src/services/durability/include/d_networkAddress.h new file mode 100644 index 000000000..7e93c0e01 --- /dev/null +++ b/src/services/durability/include/d_networkAddress.h @@ -0,0 +1,50 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef D_NETWORKADDRESS_H +#define D_NETWORKADDRESS_H + +#include "d__types.h" + +#if defined (__cplusplus) +extern "C" { +#endif + +#define d_networkAddress(a) ((d_networkAddress)(a)) + +d_networkAddress d_networkAddressNew (c_ulong systemId, + c_ulong localId, + c_ulong lifecycleId); + +void d_networkAddressFree (d_networkAddress addr); + +c_bool d_networkAddressIsUnaddressed (d_networkAddress addr); + +d_networkAddress d_networkAddressUnaddressed (); + +c_bool d_networkAddressEquals (d_networkAddress addr1, + d_networkAddress addr2); + +int d_networkAddressCompare (d_networkAddress addr1, + d_networkAddress addr2); + +#if defined (__cplusplus) +} +#endif + +#endif /*D_NETWORKADDRESS_H*/ diff --git a/src/services/durability/include/d_newGroup.h b/src/services/durability/include/d_newGroup.h new file mode 100644 index 000000000..31ba96533 --- /dev/null +++ b/src/services/durability/include/d_newGroup.h @@ -0,0 +1,51 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef D_NEWGROUP_H +#define D_NEWGROUP_H + +#include "d__types.h" +#include "d__misc.h" + +#if defined (__cplusplus) +extern "C" { +#endif + +#define d_newGroup(n) ((d_newGroup)(n)) + +_Ret_notnull_ +d_newGroup d_newGroupNew (_In_ d_admin admin, + _In_opt_z_ const c_char* partition, + _In_opt_z_ const c_char* topic, + _In_ d_durabilityKind kind, + _In_ d_completeness completeness, + _In_ d_quality quality); + +void d_newGroupSetAlignerCount (d_newGroup newGroup, + c_ulong count); + +void d_newGroupFree (d_newGroup group); + +int d_newGroupCompare (d_newGroup g1, + d_newGroup g2); + +#if defined (__cplusplus) +} +#endif + +#endif /* D_NEWGROUP_H */ diff --git a/src/services/durability/include/d_object.h b/src/services/durability/include/d_object.h new file mode 100644 index 000000000..c0d94b332 --- /dev/null +++ b/src/services/durability/include/d_object.h @@ -0,0 +1,106 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef D_OBJECT_H +#define D_OBJECT_H + +#include "d__types.h" + +#if defined (__cplusplus) +extern "C" { +#endif + +typedef enum d_kind{ + D_BAD_TYPE, /* Must be the first element */ + D_DURABILITY, + D_CONFIGURATION, + D_FELLOW, + D_ADMIN, + D_GROUP, + D_LISTENER, + D_POLICY, + D_NAMESPACE, + D_PUBLISHER, + D_SUBSCRIBER, + D_TABLE, + D_CHAIN, + D_EVENT_LISTENER, + D_ADMIN_EVENT, + D_STORE, + D_WAITSET, + D_WAITSET_ENTITY, + D_ACTION, + D_ACTION_QUEUE, + D_GROUP_CREATION_QUEUE, + D_READER_REQUEST, + D_MERGE_ACTION, + D_ALIGNER_STATS, + D_ALIGNEE_STATS, + D_ADMIN_STATS_INFO, + D_CONFLICT, + D_CONFLICT_MONITOR, + D_CONFLICT_RESOLVER, + D_HISTORICAL_DATA_REQ, + D_HISTORICAL_DATA, + D_DURABILITY_STATE_REQ, + D_DURABILITY_STATE, + D_PART_TOPIC_STATE, + D_FILTER, + D_CLIENT, + D_KINDCOUNT /* Must be the last element! */ +} d_kind; + +C_CLASS(d_object); + +typedef void (*d_objectDeinitFunc) (d_object object); + +C_STRUCT(d_object){ + c_ulong confidence; + d_kind kind; + pa_uint32_t refCount; + d_objectDeinitFunc deinit; +}; + +/** + * \brief The d_object cast macro. + * + * This macro casts an object to a d_object object. + */ +#define d_object(d) ((d_object)(d)) + +void d_objectInit (d_object object, + d_kind kind, + d_objectDeinitFunc deinit); + +void d_objectDeinit (d_object object); + +void d_objectFree (d_object object); + +c_bool d_objectIsValid (d_object object, + d_kind kind); + +d_object d_objectKeep (d_object object); + +c_bool d_objectValidate (c_ulong expected, + int enable_allocation_report); + +#if defined (__cplusplus) +} +#endif + +#endif /* D_OBJECT_H */ diff --git a/src/services/durability/include/d_qos.h b/src/services/durability/include/d_qos.h new file mode 100644 index 000000000..ebc0f6bf7 --- /dev/null +++ b/src/services/durability/include/d_qos.h @@ -0,0 +1,80 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef D_QOS_H +#define D_QOS_H + +#include "d__types.h" +#include "v_qos.h" +#include "u_user.h" + +#if defined (__cplusplus) +extern "C" { +#endif + +v_publisherQos +d_publisherQosNew ( + const c_char* partition); + +void +d_publisherQosFree ( + v_publisherQos qos); + +v_subscriberQos +d_subscriberQosNew ( + const c_char* partition); + +void +d_subscriberQosFree ( + v_subscriberQos qos); + +v_readerQos +d_readerQosNew ( + v_durabilityKind durability, + v_reliabilityKind reliability); + +void +d_readerQosFree ( + v_readerQos qos); + +v_writerQos +d_writerQosNew ( + v_durabilityKind durability, + v_reliabilityKind reliability, + v_orderbyKind orderKind, + os_duration latencyBudget, + c_long transportPriority); + +void +d_writerQosFree ( + v_writerQos qos); + +v_topicQos +d_topicQosNew ( + v_durabilityKind durability, + v_reliabilityKind reliability); + +void +d_topicQosFree ( + v_topicQos qos); + +#if defined (__cplusplus) +} +#endif + +#endif /* D_QOS_H */ diff --git a/src/services/durability/include/d_sampleChain.h b/src/services/durability/include/d_sampleChain.h new file mode 100644 index 000000000..d4d3f2d63 --- /dev/null +++ b/src/services/durability/include/d_sampleChain.h @@ -0,0 +1,52 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef D_SAMPLECHAIN_H +#define D_SAMPLECHAIN_H + +#include "d__types.h" + +#if defined (__cplusplus) +extern "C" { +#endif + +#define d_sampleChain(s) ((d_sampleChain)(s)) + +d_sampleChain d_sampleChainNew (d_admin admin, + const c_char* partition, + const c_char* topic, + d_durabilityKind kind, + d_networkAddress source); + +void d_sampleChainFree (d_sampleChain sampleChain); + +int d_sampleChainCompare (d_sampleChain sampleChain1, + d_sampleChain sampleChain2); + +c_bool d_sampleChainContainsAddressee (d_sampleChain sampleChain, + d_networkAddress addressee); + +int d_sampleChainPrintAddressees (c_char *buffer, + c_size length, + d_sampleChain chain); + +#if defined (__cplusplus) +} +#endif + +#endif /* D_SAMPLECHAIN_H */ diff --git a/src/services/durability/include/d_sampleRequest.h b/src/services/durability/include/d_sampleRequest.h new file mode 100644 index 000000000..9d3e5cb29 --- /dev/null +++ b/src/services/durability/include/d_sampleRequest.h @@ -0,0 +1,73 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef D_SAMPLEREQUEST_H +#define D_SAMPLEREQUEST_H + +#include "d__types.h" + +#if defined (__cplusplus) +extern "C" { +#endif + + +/** + * \brief The d_sampleRequest cast macro. + * + * This macro casts an object to a d_sampleRequest object. + */ +#define d_sampleRequest(s) ((d_sampleRequest)(s)) + +d_sampleRequest d_sampleRequestNew (d_admin admin, + c_char* partition, + c_char* topic, + d_durabilityKind kind, + os_timeW requestTime, + c_bool withTimeRange, + os_timeW beginTime, + os_timeW endTime); + +d_sampleRequest d_sampleRequestCopy (d_sampleRequest request, + c_bool inSharedMemory); + +void d_sampleRequestFree (d_sampleRequest sampleRequest); + +void d_sampleRequestSetCondition (d_sampleRequest request, + d_readerRequest condition); + +c_bool d_sampleRequestSpecificReader (d_sampleRequest request); + +c_bool d_sampleRequestHasCondition (d_sampleRequest request); + +void d_sampleRequestSetSource (d_sampleRequest request, + d_networkAddress source); + +void d_sampleRequestSetHash (d_sampleRequest request, + c_string hash); + +c_bool d_sampleRequestHasHash (d_sampleRequest request, + d_fellow fellow); + +c_bool d_sampleRequestCanCombine (d_sampleRequest request1, + d_sampleRequest request2); + +#if defined (__cplusplus) +} +#endif + +#endif /* D_SAMPLEREQUEST_H */ diff --git a/src/services/durability/include/d_status.h b/src/services/durability/include/d_status.h new file mode 100644 index 000000000..f9ddc0b20 --- /dev/null +++ b/src/services/durability/include/d_status.h @@ -0,0 +1,38 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef D_STATUS_H +#define D_STATUS_H + +#include "d__types.h" + +#if defined (__cplusplus) +extern "C" { +#endif + +#define d_status(s) ((d_status)(s)) + +d_status d_statusNew (d_admin admin); + +void d_statusFree (d_status status); + +#if defined (__cplusplus) +} +#endif + +#endif /* D_STATUS_H */ diff --git a/src/services/durability/include/d_store.h b/src/services/durability/include/d_store.h new file mode 100644 index 000000000..dd2887392 --- /dev/null +++ b/src/services/durability/include/d_store.h @@ -0,0 +1,157 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef D_STORE_H +#define D_STORE_H + +#include "d__types.h" +#include "d__group.h" +#include "d__misc.h" +#include "d__groupHash.h" +#include "u_participant.h" + +#if defined (__cplusplus) +extern "C" { +#endif + +C_STRUCT(d_groupList){ + d_partition partition; + d_topic topic; + d_quality quality; + d_completeness completeness; + c_bool optimized; + c_voidp next; +}; + +#define d_groupList(g) ((d_groupList)(g)) +#define d_store(s) ((d_store)(s)) + +d_store d_storeOpen (const d_durability durability, + const d_storeType storeType); + +void d_storeDeinit (d_store store); + +d_storeResult d_storeClose (d_store store); + +d_storeResult d_storeGetQuality (const d_store store, + const d_nameSpace nameSpace, + d_quality* quality); + +d_storeResult d_storeBackup (const d_store store, + const d_nameSpace nameSpace); + +d_storeResult d_storeGroupsRead (const d_store store, + d_groupList *list); + +d_storeResult d_storeGroupInject (const d_store store, + const c_char* partition, + const c_char* topic, + const u_participant participant, + d_group *group); + +d_storeResult d_storeActionStart (const d_store store); + +d_storeResult d_storeActionStop (const d_store store); + +d_storeResult d_storeGroupStore (const d_store store, + const d_group group, + const d_nameSpace nameSpace); + +d_storeResult d_storeGroupListFree (const d_store store, + d_groupList list); + + +d_storeResult d_storeMessageStore (const d_store store, + const v_groupAction message); + +d_storeResult d_storeInstanceDispose (const d_store store, + const v_groupAction message); + +d_storeResult d_storeInstanceRegister (const d_store store, + const v_groupAction message); + +d_storeResult d_storeInstanceUnregister (const d_store store, + const v_groupAction message); + +d_storeResult d_storeMessageExpunge (const d_store store, + const v_groupAction message); + +d_storeResult d_storeInstanceExpunge (const d_store store, + const v_groupAction message); + +d_storeResult d_storeDeleteHistoricalData (const d_store store, + const v_groupAction message); + +d_storeResult d_storeMessagesInject (const d_store store, + const d_group group); + +d_storeResult d_storeOptimizeGroup (const d_store store, + const d_group group); + +d_storeResult d_storeTransactionComplete (const d_store store, + const v_groupAction message); + +void d_storeReport (const d_store store, + d_level level, + const char * eventText, + ...); + +d_storeResult d_storeMessagesLoad (const d_store store, + const d_group group, + struct d_groupHash *groupHash); + +d_storeResult d_storeMessagesLoadFlush (const d_store store, + const d_group group, + c_bool inject); + +d_storeResult +d_storeCreatePersistentSnapshot( + const d_store store, + const c_char* partitionExpr, + const c_char* topicExpr, + const c_char* uri); + +d_storeResult +d_storeCopyFile( + os_char* fileStorePath, + os_char* destStorePath); + + +d_storeResult d_storeNsIsComplete (const d_store store, + const d_nameSpace nameSpace, + c_bool* isComplete); + +d_storeResult d_storeNsMarkComplete (const d_store store, + const d_nameSpace nameSpace, + c_bool isComplete); + +d_storeResult d_storeRestoreBackup (const d_store store, + const d_nameSpace nameSpace); + +c_char* d_storeDirNew(d_store store, const c_char *name); + + +void d_storeGetBase(v_public entity, c_voidp args); + + + +#if defined (__cplusplus) +} +#endif + +#endif /* D_STORE_H */ diff --git a/src/services/durability/include/d_storeKV.h b/src/services/durability/include/d_storeKV.h new file mode 100644 index 000000000..cc3152ab0 --- /dev/null +++ b/src/services/durability/include/d_storeKV.h @@ -0,0 +1,41 @@ +/* -*- mode: c; c-file-style: "k&r"; c-basic-offset: 4; -*- */ + +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef D_STOREKV_H +#define D_STOREKV_H + +#include "d__types.h" +#include "u_participant.h" + +#if defined (__cplusplus) +extern "C" { +#endif + +#define d_storeKV(s) ((d_storeKV)(s)) + +d_storeKV d_storeNewKV (u_participant participant); + +d_storeResult d_storeFreeKV (d_storeKV store); + +#if defined (__cplusplus) +} +#endif + +#endif /* D_STOREKV_H */ diff --git a/src/services/durability/include/d_storeXML.h b/src/services/durability/include/d_storeXML.h new file mode 100644 index 000000000..7a3c2492a --- /dev/null +++ b/src/services/durability/include/d_storeXML.h @@ -0,0 +1,38 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef D_STOREXML_H +#define D_STOREXML_H + +#include "d__types.h" + +#if defined (__cplusplus) +extern "C" { +#endif + +#define d_storeXML(s) ((d_storeXML)(s)) + +d_storeXML d_storeNewXML (u_participant participant); + +d_storeResult d_storeFreeXML (d_storeXML store); + +#if defined (__cplusplus) +} +#endif + +#endif /* D_STOREXML_H */ diff --git a/src/services/durability/makefile b/src/services/durability/makefile new file mode 100644 index 000000000..b5eaab61f --- /dev/null +++ b/src/services/durability/makefile @@ -0,0 +1,10 @@ +-include $(OSPL_HOME)/setup/makefiles/makefile.mak + +all link: bld/$(SPLICE_TARGET)/makefile + @$(MAKE) -C bld/$(SPLICE_TARGET) $@ + + +clean: + @rm -rf bld/$(SPLICE_TARGET) + +include makefile.plugin diff --git a/src/services/durability/makefile.ext b/src/services/durability/makefile.ext new file mode 100644 index 000000000..2767e8613 --- /dev/null +++ b/src/services/durability/makefile.ext @@ -0,0 +1,11 @@ +ifeq ($(INCLUDE_SQLITE), yes) +DURABILITY_PLUGIN_LIBS += -lsqlite3-ospl +DURABILITY_PLUGIN_CINCS += -I$(SQLITE_HOME) +DURABILITY_PLUGIN_CPPFLAGS += -DKV_INCLUDE_SQLITE=1 +endif + +ifeq ($(INCLUDE_LEVELDB), yes) +DURABILITY_PLUGIN_LIBS += -lleveldb-ospl +DURABILITY_PLUGIN_CINCS += -I$(LEVELDB_HOME)/include +DURABILITY_PLUGIN_CPPFLAGS += -DKV_INCLUDE_LEVELDB=1 +endif diff --git a/src/services/durability/makefile.mak b/src/services/durability/makefile.mak new file mode 100644 index 000000000..0a0166e26 --- /dev/null +++ b/src/services/durability/makefile.mak @@ -0,0 +1,44 @@ +TARGET_DLIB := durability +ODL_MODULES := durabilityModule2 +IDL_DIR = ../../code:$(OSPL_HOME)/etc/idl +IDL_FILES = dds_builtinTopics.idl dds_dcps_builtintopics.idl client_durability.idl + +# Get the default idlpp setting +include $(OSPL_HOME)/setup/makefiles/test_idl_c.mak + +# Use the following settings to parse the client-durability idl +IDL_C = +IDL_H = $(IDL_TYPE_FILES) $(IDL_LOAD_FILES) +IDLPPFLAGS += -I$(OSPL_HOME)/etc/idl -N + +# Build durability library +include $(OSPL_HOME)/setup/makefiles/target.mak +-include $(OSPL_OUTER_HOME)/setup/makefiles/commercial.mak + +CPPFLAGS += -DOSPL_BUILD_DURABILITY -DMODEL_durabilityModule2_IMPLEMENTATION $(DURABILITY_PLUGIN_CPPFLAGS) + +CFLAGS += $(SHCFLAGS) +CFLAGS += $(CFLAGS_XSTRICT) $(CFLAGS_W_ERROR) + +CINCS += -I$(OSPL_HOME)/src/utilities/include +CINCS += -I$(OSPL_HOME)/src/database/serialization/include +CINCS += -I$(OSPL_HOME)/src/database/database/include +CINCS += -I$(OSPL_HOME)/src/kernel/include +CINCS += -I$(OSPL_HOME)/src/user/include +CINCS += -I$(OSPL_HOME)/src/configuration/config/include +CINCS += -I$(OSPL_HOME)/src/services/durability/bld/$(SPLICE_TARGET) +CINCS += $(DDS_DURABILITY_TMPL_INC) $(DURABILITY_PLUGIN_CINCS) + +SPPODL_FLAGS += -I$(OSPL_HOME)/src/kernel/code -I$(OSPL_HOME)/src/abstraction/os/include + +vpath %.odl $(OSPL_HOME)/src/kernel/code +durabilityModule2.h: v_kernel.odl + +LDFLAGS += $(SHLDFLAGS) +LDLIBS += $(SHLDLIBS) +LDLIBS += -l$(DDS_CORE) +LDLIBS += $(DURABILITY_PLUGIN_LIBS) + +include ../../makefile.ext + +-include $(DEPENDENCIES) diff --git a/src/services/durability/makefile.plugin b/src/services/durability/makefile.plugin new file mode 100644 index 000000000..95cc12e7c --- /dev/null +++ b/src/services/durability/makefile.plugin @@ -0,0 +1,114 @@ + +ifeq ($(INCLUDE_SQLITE), yes) +all link: sqlite +clean: clean_sqlite +endif + +ifeq ($(INCLUDE_LEVELDB), yes) +all link: leveldb +clean: clean_leveldb +endif + +SQLITE_TARGET = $(DLIB_PREFIX)sqlite3-ospl$(DLIB_POSTFIX) +SQLITE_BUILD_DIR = bld/$(SPLICE_TARGET)/sqlite + +SQLITE_CFLAGS = $(filter-out -D%, $(CFLAGS)) +SQLITE_LDFLAGS = $(LDFLAGS) + +ifneq (,$(or $(findstring win32,$(SPLICE_TARGET)), $(findstring win64,$(SPLICE_TARGET)))) +WIN_SQLITE_LIB = sqlite3-ospl.lib +WIN_SQLITE_PDB = sqlite3-ospl.pdb +SQLITE_CFLAGS += -D"SQLITE_API=__declspec(dllexport)" +SQLITE_LDFLAGS += -dll +endif + +ifeq "$(GCC_HAS_NO_MAYBE_UNINITIALIZED)" "yes" +SQLITE_CFLAGS += -Wno-maybe-uninitialized +SQLITE_LDFLAGS += -Wno-maybe-uninitialized +endif + +ifneq (,$(findstring linux,$(SPLICE_TARGET))) +SQLITE_CFLAGS += -fPIC +SQLITE_LDFLAGS += -shared +GCCVERSION := $(shell expr `gcc -dumpversion | cut -f1 -d.` \>= 4) +ifeq (x86_64,$(and $(findstring x86.linux, $(SPLICE_TARGET)), $(findstring x86_64,$(shell uname -m)))) +LEVELDB_CROSS_COMPILE=yes +endif +else +GCCVERSION := 1 +SQLITE_CFLAGS += $(SHCFLAGS) +SQLITE_LDFLAGS += $(SHLDFLAGS) +endif + +ifneq (,$(findstring darwin,$(SPLICE_TARGET))) +SQLITE_LDFLAGS += -install_name @rpath/$(SQLITE_TARGET) +LEVELDB_INSTALL_PATH = @rpath +endif + +ifneq (,$(and $(findstring solaris,$(SPLICE_TARGET)), $(findstring studio,$(SPLICE_TARGET)))) +SQLITE_LDFLAGS += -G -xcode=pic32 -Bdynamic +endif +ifneq (,$(findstring solaris,$(SPLICE_TARGET))) +SQLITE_CFLAGS := $(filter-out -xc99, $(SQLITE_CFLAGS)) +SQLITE_CFLAGS := $(filter-out -std=c99, $(SQLITE_CFLAGS)) +SQLITE_CFLAGS := $(filter-out -std=gnu99, $(SQLITE_CFLAGS)) +endif + +sqlite: $(OSPL_HOME)/lib/$(SPLICE_TARGET)/$(SQLITE_TARGET) + +clean_sqlite: + @rm -rf bld/$(SPLICE_TARGET)/sqlite + @rm -f $(OSPL_HOME)/lib/$(SPLICE_TARGET)/$(SQLITE_TARGET) + +$(OSPL_HOME)/lib/$(SPLICE_TARGET)/$(SQLITE_TARGET): $(SQLITE_BUILD_DIR)/sqlite3-ospl$(OBJ_POSTFIX) + $(LD_SO) $(SQLITE_LDFLAGS) $(SQLITE_BUILD_DIR)/sqlite3-ospl$(OBJ_POSTFIX) -o $(SQLITE_BUILD_DIR)/$(SQLITE_TARGET) + cp $(SQLITE_BUILD_DIR)/$(SQLITE_TARGET) $(OSPL_HOME)/lib/$(SPLICE_TARGET)/$(SQLITE_TARGET) +ifneq (,$(or $(findstring win32,$(SPLICE_TARGET)), $(findstring win64,$(SPLICE_TARGET)))) + ospl_wincmd mt -manifest $(addsuffix .manifest, $(SQLITE_BUILD_DIR)/$(SQLITE_TARGET)) "-outputresource:$@;#2" + cp $(SQLITE_BUILD_DIR)/$(WIN_SQLITE_LIB) $(OSPL_HOME)/lib/$(SPLICE_TARGET)/$(WIN_SQLITE_LIB) +endif + +$(SQLITE_BUILD_DIR)/sqlite3-ospl$(OBJ_POSTFIX): $(SQLITE_HOME)/sqlite3.c $(SQLITE_BUILD_DIR)/.STAMP + $(CC) -c $(SQLITE_CFLAGS) -I$(SQLITE_HOME) $< -o $@ + +$(SQLITE_BUILD_DIR)/.STAMP: bld/$(SPLICE_TARGET)/.STAMP + mkdir $(SQLITE_BUILD_DIR) + touch $(SQLITE_BUILD_DIR)/.STAMP + + +LEVELDB_TARGET = $(DLIB_PREFIX)leveldb-ospl$(DLIB_POSTFIX) +LEVELDB_BUILD_DIR = bld/$(SPLICE_TARGET)/leveldb + +FILTER := -D% -W% -pedantic% $(CFLAGS_DEBUG) $(CFLAGS_OPT) +LEVELDB_CFLAGS := $(filter-out $(FILTER), $(CFLAGS)) +LEVELDB_CXXFLAGS := $(filter-out $(FILTER), $(CXXFLAGS)) +LEVELDB_CFLAGS_OPT := $(CFLAGS_OPT) $(filter-out -D%, $(CFLAGS_DEBUG)) + +leveldb: $(OSPL_HOME)/lib/$(SPLICE_TARGET)/$(LEVELDB_TARGET) + +clean_leveldb: + @rm -rf bld/$(SPLICE_TARGET)/leveldb + @rm -f $(OSPL_HOME)/lib/$(SPLICE_TARGET)/$(LEVELDB_TARGET) + +$(OSPL_HOME)/lib/$(SPLICE_TARGET)/$(LEVELDB_TARGET): $(LEVELDB_BUILD_DIR)/.STAMP + @CC="$(CC)" CFLAGS="$(LEVELDB_CFLAGS)" CXX="$(CXX)" CXXFLAGS="$(LEVELDB_CXXFLAGS)" OPT="$(LEVELDB_CFLAGS_OPT)" INSTALL_PATH="$(LEVELDB_INSTALL_PATH)" $(MAKE) -C bld/$(SPLICE_TARGET)/leveldb + cp $(LEVELDB_BUILD_DIR)/$(LEVELDB_TARGET) $(OSPL_HOME)/lib/$(SPLICE_TARGET)/$(LEVELDB_TARGET) + +$(LEVELDB_BUILD_DIR)/.STAMP: bld/$(SPLICE_TARGET)/.STAMP + mkdir $(LEVELDB_BUILD_DIR) + touch $(LEVELDB_BUILD_DIR)/.STAMP + cp -r $(LEVELDB_HOME)/* $(LEVELDB_BUILD_DIR) + (cd $(LEVELDB_BUILD_DIR); sed -i.bak '/PLATFORM_SHARED_VERSIONED/s/true/false/' build_detect_platform) + (cd $(LEVELDB_BUILD_DIR); sed -i.bak '/^SHARED1/s/= .*/= $(LEVELDB_TARGET)/' Makefile) + (cd $(LEVELDB_BUILD_DIR); sed -i.bak '/^SHARED2/s/= .(SHARED1)/= $(LEVELDB_TARGET)/' Makefile) + echo '.NOTPARALLEL:' >> $(LEVELDB_BUILD_DIR)/Makefile +ifneq "$(GCCVERSION)" "1" + (cd $(LEVELDB_BUILD_DIR); sed -i.bak 's/\(DOS_LINUX\)/\1 -fno-access-control/' build_detect_platform) +endif +ifeq ($(LEVELDB_CROSS_COMPILE), yes) + (cd $(LEVELDB_BUILD_DIR); sed -i.bak '/^PLATFORM_CCFLAGS=.*PLATFORM/s/="/="-m32 /' build_detect_platform) + (cd $(LEVELDB_BUILD_DIR); sed -i.bak '/^PLATFORM_CXXFLAGS=.*PLATFORM/s/="/="-m32 /' build_detect_platform) +endif + + +.PHONY: sqlite clean_sqlite leveldb clean_leveldb diff --git a/src/services/executables/cmsoap/code/mainWrapper.c b/src/services/executables/cmsoap/code/mainWrapper.c new file mode 100644 index 000000000..3935c1bf5 --- /dev/null +++ b/src/services/executables/cmsoap/code/mainWrapper.c @@ -0,0 +1,25 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#include "cmsoap.h" +#include "os_process.h" + +OPENSPLICE_MAIN(ospl_cmsoap) +{ + os_procInitializeOpenSpliceService(OS_FALSE); + return OPENSPLICE_ENTRYPOINTCALL( ospl_cmsoap, argc, argv); +} diff --git a/src/services/executables/cmsoap/makefile b/src/services/executables/cmsoap/makefile new file mode 100644 index 000000000..36d4fe8ce --- /dev/null +++ b/src/services/executables/cmsoap/makefile @@ -0,0 +1,10 @@ +include $(OSPL_HOME)/setup/makefiles/makefile.mak + +all link: bld/$(SPLICE_TARGET)/makefile + @$(MAKE) -C bld/$(SPLICE_TARGET) $@ + +clean: + @rm -rf bld/$(SPLICE_TARGET) + @rm -rf bldinc/$(SPLICE_TARGET) + @rm -rf soapinclude/$(SPLICE_TARGET) + @rm -f $(OSPL_HOME)/exec/$(SPLICE_TARGET)/cmsoap diff --git a/src/services/executables/cmsoap/makefile.mak b/src/services/executables/cmsoap/makefile.mak new file mode 100644 index 000000000..99964377a --- /dev/null +++ b/src/services/executables/cmsoap/makefile.mak @@ -0,0 +1,9 @@ +TARGET_EXEC := cmsoap + +include $(OSPL_HOME)/setup/makefiles/target.mak + +CINCS += -I$(OSPL_HOME)/src/services/cmsoap/include + +LDLIBS += -l$(DDS_CMSOAP) -l$(DDS_CMXML) $(DDS_RRSTORAGE_LIBS) -l$(DDS_CORE) +LDLIBS += $(LDLIBS_CMS) + diff --git a/src/services/executables/ddsi2/code/mainWrapper.c b/src/services/executables/ddsi2/code/mainWrapper.c new file mode 100644 index 000000000..6aa19e6fc --- /dev/null +++ b/src/services/executables/ddsi2/code/mainWrapper.c @@ -0,0 +1,25 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#include "q_ddsi2.h" +#include "os_process.h" + +OPENSPLICE_MAIN (ospl_ddsi2) +{ + os_procInitializeOpenSpliceService(OS_FALSE); + return OPENSPLICE_ENTRYPOINTCALL( ospl_ddsi2, argc, argv); +} diff --git a/src/api/dcps/sacs/api_quick_test/makefile b/src/services/executables/ddsi2/makefile old mode 100755 new mode 100644 similarity index 100% rename from src/api/dcps/sacs/api_quick_test/makefile rename to src/services/executables/ddsi2/makefile diff --git a/src/services/executables/ddsi2/makefile.mak b/src/services/executables/ddsi2/makefile.mak new file mode 100644 index 000000000..8ff29ffe9 --- /dev/null +++ b/src/services/executables/ddsi2/makefile.mak @@ -0,0 +1,20 @@ +TARGET_EXEC := ddsi2 + +include $(OSPL_HOME)/setup/makefiles/target.mak + +CINCS += -I$(OSPL_HOME)/src/services/ddsi2/code +CINCS += -I$(OSPL_HOME)/src/user/include +CINCS += -I$(OSPL_HOME)/src/kernel/include +CINCS += -I$(OSPL_HOME)/src/database/database/include +CINCS += -I$(OSPL_HOME)/src/database/serialization/include +CINCS += -I$(OSPL_HOME)/src/utilities/include +## workaround until v__networkQueue.h has moved from code/ to include/ +CINCS += -I$(OSPL_HOME)/src/kernel/code +CINCS += -I$(OSPL_HOME)/src/user/code + +LDLIBS := -l$(DDS_DDSI2) -l$(DDS_CORE) $(LDLIBS_NW) $(LDLIBS) + +ifeq "$(INCLUDE_SECURITY)" "yes" +LDLIBS += $(LDLIBS_NW_SEC) +endif + diff --git a/src/services/executables/ddsi2e/code/mainWrapper.c b/src/services/executables/ddsi2e/code/mainWrapper.c new file mode 100644 index 000000000..38d759294 --- /dev/null +++ b/src/services/executables/ddsi2e/code/mainWrapper.c @@ -0,0 +1,25 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#include "q_ddsi2.h" +#include "os_process.h" + +OPENSPLICE_MAIN (ospl_ddsi2e) +{ + os_procInitializeOpenSpliceService(OS_FALSE); + return OPENSPLICE_ENTRYPOINTCALL( ospl_ddsi2e, argc, argv); +} diff --git a/src/services/executables/ddsi2e/makefile b/src/services/executables/ddsi2e/makefile new file mode 100644 index 000000000..14c055721 --- /dev/null +++ b/src/services/executables/ddsi2e/makefile @@ -0,0 +1,8 @@ +include $(OSPL_HOME)/setup/makefiles/makefile.mak + +all link: bld/$(SPLICE_TARGET)/makefile + @$(MAKE) -C bld/$(SPLICE_TARGET) $@ + + +clean: + @rm -rf bld/$(SPLICE_TARGET) diff --git a/src/services/executables/ddsi2e/makefile.mak b/src/services/executables/ddsi2e/makefile.mak new file mode 100644 index 000000000..e9f0ecd0c --- /dev/null +++ b/src/services/executables/ddsi2e/makefile.mak @@ -0,0 +1,17 @@ +TARGET_EXEC := ddsi2e + +include $(OSPL_HOME)/setup/makefiles/target.mak + +CINCS += -I$(OSPL_HOME)/src/services/ddsi2e/code +CINCS += -I$(OSPL_HOME)/src/user/include +CINCS += -I$(OSPL_HOME)/src/kernel/include +CINCS += -I$(OSPL_HOME)/src/database/database/include +CINCS += -I$(OSPL_HOME)/src/database/serialization/include +CINCS += -I$(OSPL_HOME)/src/utilities/include +## workaround until v__networkQueue.h has moved from code/ to include/ +CINCS += -I$(OSPL_HOME)/src/kernel/code +CINCS += -I$(OSPL_HOME)/src/user/code + +CPPFLAGS += -DDDSI2E_OR_NOT2E + +LDLIBS := -l$(DDS_DDSI2E) -l$(DDS_CORE) $(LDLIBS_NW) $(LDLIBS) $(LDLIBS_NW_SEC) diff --git a/src/services/executables/durability/code/mainWrapper.c b/src/services/executables/durability/code/mainWrapper.c new file mode 100644 index 000000000..702a10075 --- /dev/null +++ b/src/services/executables/durability/code/mainWrapper.c @@ -0,0 +1,25 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#include "d_durability.h" +#include "os_process.h" + +OPENSPLICE_MAIN (ospl_durability) +{ + os_procInitializeOpenSpliceService(OS_FALSE); + return OPENSPLICE_ENTRYPOINTCALL( ospl_durability, argc, argv); +} diff --git a/src/services/executables/durability/makefile b/src/services/executables/durability/makefile new file mode 100644 index 000000000..63cb7d9ed --- /dev/null +++ b/src/services/executables/durability/makefile @@ -0,0 +1,8 @@ +-include $(OSPL_HOME)/setup/makefiles/makefile.mak + +all link: bld/$(SPLICE_TARGET)/makefile + @$(MAKE) -C bld/$(SPLICE_TARGET) $@ + + +clean: + @rm -rf bld/$(SPLICE_TARGET) diff --git a/src/services/executables/durability/makefile.mak b/src/services/executables/durability/makefile.mak new file mode 100644 index 000000000..7818e4a4e --- /dev/null +++ b/src/services/executables/durability/makefile.mak @@ -0,0 +1,28 @@ +TARGET_EXEC := durability + +include $(OSPL_HOME)/setup/makefiles/target.mak + +ifeq ($(INCLUDE_SQLITE), yes) +DURABILITY_PLUGIN_LIBS += -lsqlite3-ospl +DURABILITY_PLUGIN_CINCS += -I$(SQLITE_HOME) +DURABILITY_PLUGIN_CPPFLAGS += -DKV_INCLUDE_SQLITE=1 +endif + +ifeq ($(INCLUDE_LEVELDB), yes) +DURABILITY_PLUGIN_LIBS += -lleveldb-ospl +DURABILITY_PLUGIN_CINCS += -I$(LEVELDB_HOME)/include +DURABILITY_PLUGIN_CPPFLAGS += -DKV_INCLUDE_LEVELDB=1 +endif + +LD_EXE = $(LD_CXX) # c++ binary (because of LevelDB) + +CINCS += -I$(OSPL_HOME)/src/database/serialization/include +CINCS += -I$(OSPL_HOME)/src/database/database/include +CINCS += -I$(OSPL_HOME)/src/kernel/include +CINCS += -I$(OSPL_HOME)/src/user/include +CINCS += -I$(OSPL_HOME)/src/services/durability/include +CINCS += -I$(OSPL_HOME)/src/services/durability/code +CINCS += -I$(OSPL_HOME)/src/services/durability/bld/$(SPLICE_TARGET) +CINCS += -I$(OSPL_HOME)/src/configuration/config/include + +LDLIBS := -l$(DDS_DURABILITY) $(DURABILITY_PLUGIN_LIBS) -l$(DDS_CORE) $(LDLIBS) diff --git a/src/services/executables/makefile b/src/services/executables/makefile new file mode 100644 index 000000000..29f152672 --- /dev/null +++ b/src/services/executables/makefile @@ -0,0 +1,32 @@ +# +# Set subsystems to be processed +# +SUBSYSTEMS := spliced + +ifeq ($(INCLUDE_SERVICES_DDSI),yes) +SUBSYSTEMS += ddsi2 +endif + +ifeq ($(INCLUDE_SERVICES_DDSI2E),yes) +SUBSYSTEMS += ddsi2e +endif + +ifeq ($(INCLUDE_SERVICES_DURABILITY),yes) +SUBSYSTEMS += durability +endif + +ifeq ($(INCLUDE_SERVICES_CMSOAP),yes) +SUBSYSTEMS += cmsoap +endif + +ifeq ($(INCLUDE_SERVICES_NWBRIDGE),yes) +SUBSYSTEMS += nwbridge +endif + +ifndef OSPL_OUTER_HOME +ifeq ($(INCLUDE_SERVICES_WRAPPER_LIB),yes) +SUBSYSTEMS += servicesWrapperLib +endif +endif + +include $(OSPL_HOME)/setup/makefiles/subsystem.mak diff --git a/src/services/executables/nwbridge/code/mainWrapper.c b/src/services/executables/nwbridge/code/mainWrapper.c new file mode 100644 index 000000000..4d7d9bb56 --- /dev/null +++ b/src/services/executables/nwbridge/code/mainWrapper.c @@ -0,0 +1,25 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#include "nb_service.h" +#include "os_process.h" + +OPENSPLICE_MAIN (ospl_nwbridge) +{ + os_procInitializeOpenSpliceService(OS_FALSE); + return OPENSPLICE_ENTRYPOINTCALL(ospl_nwbridge, argc, argv); +} diff --git a/src/services/executables/nwbridge/makefile b/src/services/executables/nwbridge/makefile new file mode 100644 index 000000000..63cb7d9ed --- /dev/null +++ b/src/services/executables/nwbridge/makefile @@ -0,0 +1,8 @@ +-include $(OSPL_HOME)/setup/makefiles/makefile.mak + +all link: bld/$(SPLICE_TARGET)/makefile + @$(MAKE) -C bld/$(SPLICE_TARGET) $@ + + +clean: + @rm -rf bld/$(SPLICE_TARGET) diff --git a/src/services/executables/nwbridge/makefile.mak b/src/services/executables/nwbridge/makefile.mak new file mode 100644 index 000000000..3d5793325 --- /dev/null +++ b/src/services/executables/nwbridge/makefile.mak @@ -0,0 +1,8 @@ +TARGET_EXEC := nwbridge + +include $(OSPL_HOME)/setup/makefiles/target.mak + +CINCS += -I$(OSPL_HOME)/src/services/nwbridge/include +CINCS += -I$(OSPL_HOME)/src/services/nwbridge/bld/$(SPLICE_TARGET) + +LDLIBS += -l$(DDS_NWBRIDGE) -l$(DDS_CORE) diff --git a/src/services/executables/servicesWrapperLib/makefile b/src/services/executables/servicesWrapperLib/makefile new file mode 100644 index 000000000..14c055721 --- /dev/null +++ b/src/services/executables/servicesWrapperLib/makefile @@ -0,0 +1,8 @@ +include $(OSPL_HOME)/setup/makefiles/makefile.mak + +all link: bld/$(SPLICE_TARGET)/makefile + @$(MAKE) -C bld/$(SPLICE_TARGET) $@ + + +clean: + @rm -rf bld/$(SPLICE_TARGET) diff --git a/src/services/executables/servicesWrapperLib/makefile.mak b/src/services/executables/servicesWrapperLib/makefile.mak new file mode 100644 index 000000000..c2c923bab --- /dev/null +++ b/src/services/executables/servicesWrapperLib/makefile.mak @@ -0,0 +1,25 @@ +# included by bld/$(SPLICE_TARGET)/makefile + +TARGET_DLIB := $(DDS_SERVICES_WRAPPER) + +OBJECTS += ../../../spliced/bld/$(SPLICE_TARGET)/mainWrapper$(OBJ_POSTFIX) + +ifeq ($(INCLUDE_SERVICES_DDSI),yes) +OBJECTS += ../../../ddsi2/bld/$(SPLICE_TARGET)/mainWrapper$(OBJ_POSTFIX) +endif + +ifeq ($(INCLUDE_SERVICES_DDSI2E),yes) +OBJECTS += ../../../ddsi2e/bld/$(SPLICE_TARGET)/mainWrapper$(OBJ_POSTFIX) +endif + +ifeq ($(INCLUDE_SERVICES_DURABILITY),yes) +OBJECTS += ../../../durability/bld/$(SPLICE_TARGET)/mainWrapper$(OBJ_POSTFIX) +endif + +ifeq ($(INCLUDE_SERVICES_CMSOAP),yes) +OBJECTS += ../../../cmsoap/bld/$(SPLICE_TARGET)/mainWrapper$(OBJ_POSTFIX) +endif + +include $(OSPL_HOME)/setup/makefiles/target.mak + +-include $(DEPENDENCIES) diff --git a/src/services/executables/spliced/code/mainWrapper.c b/src/services/executables/spliced/code/mainWrapper.c new file mode 100644 index 000000000..86c055139 --- /dev/null +++ b/src/services/executables/spliced/code/mainWrapper.c @@ -0,0 +1,35 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#include "spliced.h" +#include "os_process.h" + +OPENSPLICE_MAIN (ospl_spliced) +{ + os_exitStatus status; + +#ifdef _WRS_KERNEL + setCPUAffinityHook(); + os_procInstallHook(); +#endif + + os_procInitializeOpenSpliceService(OS_TRUE); + + status = OPENSPLICE_ENTRYPOINTCALL( ospl_spliced, argc, argv); + os_procExit(status); + return status; +} diff --git a/src/services/executables/spliced/makefile b/src/services/executables/spliced/makefile new file mode 100644 index 000000000..63cb7d9ed --- /dev/null +++ b/src/services/executables/spliced/makefile @@ -0,0 +1,8 @@ +-include $(OSPL_HOME)/setup/makefiles/makefile.mak + +all link: bld/$(SPLICE_TARGET)/makefile + @$(MAKE) -C bld/$(SPLICE_TARGET) $@ + + +clean: + @rm -rf bld/$(SPLICE_TARGET) diff --git a/src/services/executables/spliced/makefile.mak b/src/services/executables/spliced/makefile.mak new file mode 100644 index 000000000..ce8a0a2ad --- /dev/null +++ b/src/services/executables/spliced/makefile.mak @@ -0,0 +1,16 @@ +TARGET_EXEC := spliced + +include $(OSPL_HOME)/setup/makefiles/target.mak + +CINCS += -I$(OSPL_HOME)/src/services/spliced/code +CINCS += -I$(OSPL_HOME)/src/database/database/include +CINCS += -I$(OSPL_HOME)/src/database/serialization/include +CINCS += -I$(OSPL_HOME)/src/kernel/include +CINCS += -I$(OSPL_HOME)/src/user/include +CINCS += -I$(OSPL_HOME)/src/utilities/include + +LDLIBS := -l$(DDS_SPLICED) -l$(DDS_CORE) $(LDLIBS) + +ifdef STATIC_LIB_ONLY +spliced:$(OSPL_HOME)/lib/$(SPLICE_TARGET)/libspliced.a +endif diff --git a/src/services/makefile b/src/services/makefile index 78411172a..d4bdbf0a0 100644 --- a/src/services/makefile +++ b/src/services/makefile @@ -7,6 +7,14 @@ ifeq ($(INCLUDE_SERVICES_DDSI),yes) SUBSYSTEMS += ddsi2 endif +ifeq ($(INCLUDE_SERVICES_DDSI2E),yes) +SUBSYSTEMS += ddsi2e +endif + +ifeq ($(INCLUDE_SERVICES_DURABILITY),yes) +SUBSYSTEMS += durability +endif + ifeq ($(INCLUDE_SERVICES_CMSOAP),yes) SUBSYSTEMS += cmsoap endif @@ -15,4 +23,13 @@ ifeq ($(INCLUDE_SERVICES_CMAGENT),yes) SUBSYSTEMS += cmagent endif +ifeq ($(INCLUDE_SERVICES_NWBRIDGE),yes) +SUBSYSTEMS += nwbridge +endif + +# Now build the process executables for these services where required +ifeq ($(INCLUDE_SERVICES_AS_EXECUTABLES),yes) +SUBSYSTEMS += executables +endif + include $(OSPL_HOME)/setup/makefiles/subsystem.mak diff --git a/src/services/nwbridge/code/NetworkingBridge.odl b/src/services/nwbridge/code/NetworkingBridge.odl new file mode 100644 index 000000000..3338dcaef --- /dev/null +++ b/src/services/nwbridge/code/NetworkingBridge.odl @@ -0,0 +1,20 @@ +module NetworkingBridge { + /************************ ENUMERATIONS ************************/ + + /* ServiceState contains the possible states of an R&R service */ + enum ServiceState { + SERVICE_INITIALISING, /* Service is starting */ + SERVICE_OPERATIONAL, /* Builtin-scenario is started, service is able to receive commands */ + SERVICE_TERMINATING, /* Service is stopping all scenarios and shutting down */ + SERVICE_TERMINATED /* Service is terminated */ + }; + + /************************ TYPES ************************/ + + /* Topic used to monitor the status of a NetworkingBridge service */ + struct ServiceStatus { + string serviceId; /* Name identifying the service */ + ServiceState state; /* Current state of the service */ + }; +#pragma keylist ServiceStatus serviceId +}; diff --git a/src/services/nwbridge/code/nb__common.h b/src/services/nwbridge/code/nb__common.h new file mode 100644 index 000000000..7a59a7c7d --- /dev/null +++ b/src/services/nwbridge/code/nb__common.h @@ -0,0 +1,43 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#ifndef NB__COMMON_H_ +#define NB__COMMON_H_ + +#define NB_PARTITION "NetworkingBridge" +/* The partition name for statuses */ +#define NB_STATUS_PARTITION NB_PARTITION + +#define NB_SERVICE_STATUS_TOPIC_NAME "nb_serviceStatus" +#define NB_SERVICE_STATUS_TOPIC_TYPE_NAME "NetworkingBridge::ServiceStatus" +#define NB_SERVICE_STATUS_TOPIC_KEY_LIST "serviceId" +#define NB_SERVICE_STATUS_WRITER NB_SERVICE_STATUS_TOPIC_NAME "Writer" +#define NB_STATUS_PUBLISHER "StatusPublisher" + +/* The names for the subscription to publication info */ +#define NB_INTEREST_PARTITION V_BUILTIN_PARTITION +#define NB_INTEREST_SUBSCRIBER "BuiltinSubscriber" +#define NB_INTEREST_READER_SUFFIX "Reader" +#define NB_INTEREST_WRITER_SUFFIX "Writer" +#define NB_INTEREST_PUBREADER "DCPSPublicationReader" +#define NB_INTEREST_SUBREADER "DCPSSubscriptionReader" +#define NB_INTEREST_CMREADER "CMDataReaderReader" +/* The entity names of the interest publisher */ +#define NB_INTEREST_PUBLISHER "InterestPublisher" +#define NB_INTEREST_SUBWRITER "InterestWriter" + +#endif /* NB__COMMON_H_ */ diff --git a/src/services/nwbridge/code/nb__configuration.h b/src/services/nwbridge/code/nb__configuration.h new file mode 100644 index 000000000..62731b234 --- /dev/null +++ b/src/services/nwbridge/code/nb__configuration.h @@ -0,0 +1,66 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#ifndef NB__CONFIGURATION_H_ +#define NB__CONFIGURATION_H_ + +#include "nb__object.h" +#include "nb__log.h" + +#include "vortex_os.h" + +#include "u_participant.h" + +#define NB_MAXTHREADS 30 + +nb_configuration nb_configurationNew(nb_service service); +#define nb_configurationFree(s) nb_objectFree(s) +void nb_configurationPrint(nb_configuration _this); + +os_char* nb_configurationTracingFileName(nb_configuration _this); +nb_logcat nb_configurationTracingCategories(nb_configuration _this); +c_bool nb_configurationTracingAppend(nb_configuration _this); + +char ** nb_configurationIncludes(nb_configuration _this) + __nonnull_all__ + __attribute_malloc__ + __attribute_returns_nonnull__; + +char ** nb_configurationExcludes(nb_configuration _this) + __nonnull_all__ + __attribute_malloc__ + __attribute_returns_nonnull__; + +os_threadAttr nb_configurationWatchdogSchedAttr(nb_configuration _this); + +os_duration nb_configurationLeaseUpdateInterval(nb_configuration _this); +os_duration nb_configurationLeaseExpiryTime(nb_configuration _this); + +C_STRUCT(nb_logConfig) +{ + struct { + FILE *file; + nb_logcat categories; + } tracing; +}; + +void nb_logConfigInit(nb_logConfig _this) __nonnull_all__; + +void nb_logConfigDeinit(nb_logConfig _this) __nonnull_all__; + + +#endif /* NB__CONFIGURATION_H_ */ diff --git a/src/services/nwbridge/code/nb__log.h b/src/services/nwbridge/code/nb__log.h new file mode 100644 index 000000000..95ec8fc61 --- /dev/null +++ b/src/services/nwbridge/code/nb__log.h @@ -0,0 +1,161 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#ifndef NB__LOG_H_ +#define NB__LOG_H_ + +#include "os_report.h" +#include "nb__util.h" +#include "nb__types.h" +#include "os_errno.h" + +/* Log categories */ +#define LOG_NONE 0U +#define LOG_FATAL 1U +#define LOG_ERROR 2U +#define LOG_WARNING 4U +#define LOG_INFO 8U +#define LOG_CONFIG 16U +#define LOG_TRACE (LOG_FATAL | LOG_ERROR | LOG_WARNING | LOG_INFO | LOG_CONFIG) + +typedef unsigned nb_logcat; + +/* + * NB_TRACE macro: goes to trace log only, if configured level is LL_FINEST + * NB_INFO macro's: go to trace log as LL_INFO and to OpenSplice log as OS_INFO + * NB_WARNING macro's: go to trace log as LL_WARNING and to OpenSplice log as OS_WARNING + * NB_ERROR macro's: go to trace log as LL_SEVERE and to OpenSplice log as OS_ERROR + * NB_FATAL macro's: go to trace log as LL_SEVERE and to OpenSplice log as OS_FATAL and abort is called + */ + +typedef unsigned nb_loglevel; + +typedef struct nb_logbuf_t { + char buf[2048]; + size_t bufsz; + size_t pos; + os_timeW tstamp; +} *nb_logbuf; + +nb_logbuf nb_logbufNew(void) __attribute_malloc__ + __attribute_returns_nonnull__; + +void nb_logbufInit(nb_logbuf lb) __nonnull_all__; + +void nb_logbufFree(nb_thread self, nb_logbuf lb) __nonnull_all__; + +/* Converts verbosity string from configfile to nb_loglevel (and vice-versa) */ +nb_loglevel nb_logVerbosityFromString(const os_char *str) __attribute_pure__ + __nonnull_all__; + +os_char* nb_logVerbosityToString(nb_loglevel verbosity) __attribute_malloc__ + __attribute_returns_nonnull__; + +/* Converts category string from config file to nb_logcat (and vice-versa) */ +nb_logcat nb_logCategoryFromString(os_char *str) __nonnull_all__; + +os_char* nb_logCategoryToString(nb_logcat category) __attribute_malloc__ + __attribute_returns_nonnull__; + +int nb_log(nb_loglevel level, const char *fmt, ...) __attribute_format__((printf, 2, 3)); + +int nb_trace(const char *fmt, ...) __attribute_format__((printf, 1, 2)); + +#define NB_TRACE(args) (nb_trace args) +#define NB_KEYFMT "{systemId=%u, localId=%u}" + +/* TODO rewrite all os_report to use one of the macros below */ + +#define NB_INFO(context, fmt) do { \ + nb_log(LOG_INFO, (fmt)); \ + OS_REPORT(OS_INFO, context, 0, (fmt)); \ + } while (0) + +#define NB_INFO_1(context, fmt, a) do { \ + nb_log(LOG_INFO, (fmt), a); \ + OS_REPORT(OS_INFO, context, 0, (fmt), a); \ + } while (0) + +#define NB_INFO_2(context, fmt, a, b) do { \ + nb_log(LOG_INFO, (fmt), a, b); \ + OS_REPORT(OS_INFO, context, 0, (fmt), a, b); \ + } while (0) + +#define NB_INFO_3(context, fmt, a, b, c) do { \ + nb_log(LOG_INFO, (fmt), a, b, c); \ + OS_REPORT(OS_INFO, context, 0, (fmt), a, b, c); \ + } while (0) + +#define NB_WARNING(context, fmt) do { \ + nb_log(LOG_WARNING, (fmt)); \ + OS_REPORT(OS_WARNING, context, 0, (fmt)); \ + } while (0) + +#define NB_WARNING_1(context, fmt, a) do { \ + nb_log(LOG_WARNING, (fmt), a); \ + OS_REPORT(OS_WARNING, context, 0, (fmt), a); \ + } while (0) + +#define NB_WARNING_2(context, fmt, a, b) do { \ + nb_log(LOG_WARNING, (fmt), a, b); \ + OS_REPORT(OS_WARNING, context, 0, (fmt), a, b); \ + } while (0) + +#define NB_WARNING_3(context, fmt, a, b, c) do { \ + nb_log(LOG_WARNING, (fmt), a, b, c); \ + OS_REPORT(OS_WARNING, context, 0, (fmt), a, b, c); \ + } while (0) + +#define NB_ERROR(context, fmt) do { \ + nb_log(LOG_ERROR, (fmt)); \ + OS_REPORT(OS_ERROR, context, 0, (fmt)); \ + } while (0) + +#define NB_ERROR_1(context, fmt, a) do { \ + nb_log(LOG_ERROR, (fmt), a); \ + OS_REPORT(OS_ERROR, context, 0, (fmt), a); \ + } while (0) + +#define NB_ERROR_2(context, fmt, a, b) do { \ + nb_log(LOG_ERROR, (fmt), a, b); \ + OS_REPORT(OS_ERROR, context, 0, (fmt), a, b); \ + } while (0) + +#define NB_ERROR_3(context, fmt, a, b, c) do { \ + nb_log(LOG_ERROR, (fmt), a, b, c); \ + OS_REPORT(OS_ERROR, context, 0, (fmt), a, b, c); \ + } while (0) + +#define NB_FATAL(context, fmt) do { \ + nb_log(LOG_FATAL, (fmt)); \ + OS_REPORT(OS_FATAL, context, 0, (fmt)); \ + abort(); \ + } while (0) + +#define NB_FATAL_1(context, fmt, a) do { \ + nb_log(LOG_FATAL, (fmt), a); \ + OS_REPORT(OS_FATAL, context, 0, (fmt), a); \ + abort(); \ + } while (0) + +#define NB_FATAL_2(context, fmt, a, b) do { \ + nb_log(LOG_FATAL, (fmt), a, b); \ + OS_REPORT(OS_FATAL, context, 0, (fmt), a, b); \ + abort(); \ + } while (0) + +#endif /* NB__LOG_H_ */ diff --git a/src/services/nwbridge/code/nb__object.h b/src/services/nwbridge/code/nb__object.h new file mode 100644 index 000000000..5c6f0e98c --- /dev/null +++ b/src/services/nwbridge/code/nb__object.h @@ -0,0 +1,198 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#ifndef NB__OBJECT_H_ +#define NB__OBJECT_H_ + +#include "nb__types.h" +#include "u_types.h" + +#include "v_readerSample.h" /* for v_actionResult */ + +#ifndef NDEBUG +#define NB_OBJECT_VALIDKIND(k) (((k) > NB_OBJECT_INVALID) && ((k) < NB_OBJECT_COUNT)) +#define NB_OBJECT_CONFIDENCE (3123123123U) +#else +#define NB_OBJECT_VALIDKIND(k) +#endif + +typedef enum nb_objectKind_e { +#ifndef NDEBUG + NB_OBJECT_INVALID, +#endif + NB_OBJECT_SERVICE, + NB_OBJECT_THREAD, + NB_OBJECT_LOGBUF, + NB_OBJECT_CONFIGURATION, + NB_OBJECT_GROUP, + NB_TOPIC_OBJECT_DCPS_TOPIC, + NB_TOPIC_OBJECT_DCPS_PARTICIPANT, + NB_TOPIC_OBJECT_CM_PARTICIPANT, + NB_TOPIC_OBJECT_DCPS_PUBLICATION, + NB_TOPIC_OBJECT_CM_WRITER, + NB_TOPIC_OBJECT_DCPS_SUBSCRIPTION, + NB_TOPIC_OBJECT_CM_READER, + NB_TOPIC_OBJECT_CM_PUBLISHER, + NB_TOPIC_OBJECT_CM_SUBSCRIBER /* No comma */ +#ifndef NDEBUG + , NB_OBJECT_COUNT +#endif +} nb_objectKind; + +typedef void (* nb_objectDeinitFunc)(nb_object); + +C_STRUCT(nb_object) { +#ifndef NDEBUG + os_uint32 confidence; +#endif /* NDEBUG */ + /* The reference count of this object. It is initialized at 1 and once it reaches 0 it will trigger the + * registered destroy operation. */ + pa_uint32_t refCount; + /* The destroy operation that will be executed once an object reference count reaches zero. */ + nb_objectDeinitFunc deinit; + /* The enum value which identifies the subclass of this object. */ + nb_objectKind kind; +}; + +#define nb_object(o) ((nb_object)(o)) + +/** + * \brief Initializes the object + * + * This operation will set the class id, destroy function pointer, reference count to 1 and the alive boolean to true + * + * \param _this the object to operate on + * \param classId The class ID of the (bottom most) child object + * \param deinit The function to call when the reference count of this object reaches zero. + */ +void nb__objectInit (nb_object _this, + nb_objectKind kind, + nb_objectDeinitFunc deinit) __nonnull_all__; + +/** + * \Brief Deinitializes the object + * + * \param _this the object to operate on + */ +void nb__objectDeinit(nb_object _this) __nonnull_all__; + +nb_objectKind nb__objectKind(nb_object _this) __nonnull_all__; + +void nb__objectSetDeinit(nb_object _this, + nb_objectDeinitFunc deinit) __nonnull_all__; + +/* \brief This operation increases the reference count of the provided object by one. + * + * For every call to this operation the r_objectRelease(...) operation must be called once. + * + * \param _this The object for which the reference count has to be increased. + * + * \return _this + */ +nb_object nb__objectKeep(nb_object _this) __attribute_returns_nonnull__ + __nonnull_all__; + +/* Convenience macro to not having to do a cast on every keep */ +#define nb_objectKeep(o) nb__objectKeep(nb_object(o)) + +/* \brief This operation decreases the reference count of the provided object with one. + * + * \param _this The object for which the reference count has to be decreased. + */ +void nb__objectFree(nb_object _this); + +/* Convenience macro for not having to do a cast on every free */ +#define nb_objectFree(o) nb__objectFree(nb_object(o)) + +#ifndef NDEBUG +c_bool nb__objectIsValid(nb_object _this) __attribute_pure__; +c_bool nb__objectIsValidKind(nb_object _this, nb_objectKind kind) __attribute_pure__; +#else +#define nb__objectIsValid(o) (TRUE) +#define nb__objectIsValidKind(o, k) (TRUE) +#endif /* NDEBUG */ + +/* Convenience macro to not having to do a cast on every validation */ +#define nb_objectIsValid(o) assert(nb__objectIsValid(nb_object(o))) +#define nb_objectIsValidKind(o, k) assert(nb__objectIsValidKind(nb_object(o), k)) + +const char* nb__objectKindImage(nb_object _this) __nonnull_all__ + __attribute_pure__; +/* Convenience macro for not having to do a cast */ +#define nb_objectKindImage(o) nb__objectKindImage(nb_object(o)) + +/****** nb_topicObject ******/ + +typedef nb_topicObject (* nb_topicObjectAllocFunc)(void); + +typedef u_result (* nb_topicObjectCopyOutFunc)(nb_topicObject, const void *) __nonnull((1)); +typedef v_copyin_result (* nb_topicObjectCopyInFunc)(c_type, nb_topicObject, void *) __nonnull_all__; + +/* Objects that can be published and/or subscribed to should extend from the + * abstract nb_topicObject class. Classes implementing the copyOut interface + * should provide nb_xxxAlloc routine (init done by copyOut. */ +C_STRUCT(nb_topicObject){ + C_EXTENDS(nb_object); + c_char * name; + v_state state; + os_timeW writeTime; + /* Copy-out routine (out from database/shared memory) */ + nb_topicObjectCopyOutFunc copyOut; + /* Copy-in routine (into database/shared memory) */ + nb_topicObjectCopyInFunc copyIn; +}; + +#define nb_topicObject(o) ((nb_topicObject)(o)) + +void nb__topicObjectInit (nb_topicObject _this, + nb_objectKind kind, + nb_objectDeinitFunc deinit, + const c_char * name, + nb_topicObjectCopyOutFunc copyOut, + nb_topicObjectCopyInFunc copyIn) __nonnull((1,3,4)); + +void nb__topicObjectDeinit (nb_object _this) __nonnull_all__; + +/* TODO: add more versatile return type? */ +u_result nb_topicObjectCopyOut (nb_topicObject _this, + const void * from) __nonnull((1)); + +v_copyin_result nb_topicObjectCopyIn (c_type type, + const void * from, /* nb_topicObject */ + void * to) __nonnull_all__; + +u_result nb_topicObjectWrite (u_writer writer, + nb_topicObject _this) __nonnull_all__; + +const c_char * nb_topicObjectName (nb_topicObject _this) __nonnull_all__ + __attribute_returns_nonnull__; + +v_state nb_topicObjectState (nb_topicObject _this) __nonnull_all__; + +v_actionResult nb_topicObjectReaderAction(c_object o, + c_voidp copyArg, /* c_iter * */ + nb_topicObjectAllocFunc allocFunc) + __nonnull((2,3)); + +#ifndef NDEBUG +void nb_topicObjectFree (nb_topicObject _this); +#else +#define nb_topicObjectFree(s) nb_objectFree(s) +#endif + + +#endif /* NB__OBJECT_H_ */ diff --git a/src/services/nwbridge/code/nb__service.h b/src/services/nwbridge/code/nb__service.h new file mode 100644 index 000000000..33ac10593 --- /dev/null +++ b/src/services/nwbridge/code/nb__service.h @@ -0,0 +1,74 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#ifndef NB__SERVICE_H +#define NB__SERVICE_H + +#include "nb_service.h" +#include "nb__object.h" + +#include "NetworkingBridge.h" + +#include "u_participant.h" + +#if defined (__cplusplus) +extern "C" { +#endif + +#ifndef NDEBUG +#define nb_service(o) (assert(nb__objectKind(nb_object(o)) == NB_OBJECT_SERVICE), (nb_service)(o)) +#else +#define nb_service(o) ((nb_service)(o)) +#endif + +#define nb_serviceFree(s) nb_objectFree(s) + +const os_char* nb_serviceName(nb_service _this) __nonnull_all__ + __attribute_returns_nonnull__; + +u_service nb_serviceService(nb_service _this) __nonnull_all__ + __attribute_returns_nonnull__; + +#define nb_serviceParticipant(_this) u_participant(nb_serviceService(_this)) + +/** + * \brief This operation will change the state of the service AND write a new service status topic + * + * \param _this The nwbridge service object to operate on + * \param exception This exception struct will be filled if an error occurs. Caller must check this struct by + * performing a R_Exception_PROPAGATE directly after this call or by using the + * r_exceptionIsRaised(...) functionality. + * \param state The new state to apply + */ +c_bool nb__serviceChangeState(nb_service _this, + ServiceState state) __nonnull_all__; + +/* \brief Return a reference to the service participant (not a copy). + * + * This function returns a reference to the service participant. This reference may not + * be freed. It also may not be used once the reference to the owning nwbridge service object + * is released or once the service has been deinited (aka when r_objectIsAlive return OS_FALSE) + * + * \param _this The nwbridge service object to operate on' + */ +/* u_participant nb_serviceParticipant(nb_service _this); */ + +#if defined (__cplusplus) +} +#endif + +#endif /* NB__SERVICE_H */ diff --git a/src/services/nwbridge/code/nb__thread.h b/src/services/nwbridge/code/nb__thread.h new file mode 100644 index 000000000..5c8e86bf1 --- /dev/null +++ b/src/services/nwbridge/code/nb__thread.h @@ -0,0 +1,68 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#ifndef NB__THREAD_H_ +#define NB__THREAD_H_ + +#include "nb__object.h" +#include "nb__log.h" /* for nb_logbuf; should come from nb__types.h */ + +typedef void* (*nb_threadRoutine)(void *arg); + +#ifndef NDEBUG +# define nb_thread(o) (assert(nb__objectKind(nb_object(o)) == NB_OBJECT_THREAD), (nb_thread)(o)) +#else +# define nb_thread(o) ((nb_thread)(o)) +#endif + +#define nb_threadStates(o) ((nb_threadStates)(o)) + +nb_threadStates nb_threadStatesAlloc(void) __attribute_malloc__ + __attribute_returns_nonnull__; + +os_result nb_threadStatesInit(nb_threadStates _this, + unsigned maxthreads, + nb_logConfig gc) __nonnull_all__; + +void nb_threadStatesDeinit(nb_threadStates ts) __nonnull_all__; + +void nb_threadStatesDealloc(nb_threadStates ts) __nonnull_all__; + +void nb_threadUpgrade(nb_threadStates ts) __nonnull_all__; + +void nb_threadDowngrade(void); + +nb_thread nb_threadLookup(void); + +nb_logConfig nb_threadLogConfig(nb_thread thread) __nonnull_all__ + __attribute_returns_nonnull__; + +const char * nb_threadName(nb_thread thread) __nonnull_all__ + __attribute_returns_nonnull__; + +nb_logbuf nb_threadLogbuf(nb_thread _this) __nonnull_all__ + __attribute_returns_nonnull__; + +os_result nb_threadCreate(const char *name, + nb_thread *thread, + const nb_threadRoutine func, + void *arg) __nonnull((1,2,3)); + +os_result nb_threadJoin(nb_thread thread, + void **retval ) __nonnull((1)); + +#endif /* NB__THREAD_H_ */ diff --git a/src/services/nwbridge/code/nb__topic.h b/src/services/nwbridge/code/nb__topic.h new file mode 100644 index 000000000..2818264fc --- /dev/null +++ b/src/services/nwbridge/code/nb__topic.h @@ -0,0 +1,363 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#ifndef NB__TOPIC_H +#define NB__TOPIC_H + +#include "kernelModule.h" + +#include "nb__object.h" + +#if defined (__cplusplus) +extern "C" { +#endif + +#ifndef NDEBUG +#define nb_dcpsTopic(o) (assert(nb__objectKind(nb_object(o)) == NB_TOPIC_OBJECT_DCPS_TOPIC), (nb_dcpsTopic)(o)) +#else +#define nb_dcpsTopic(o) ((nb_dcpsTopic)(o)) +#endif + +nb_dcpsTopic nb_dcpsTopicNew(void) __attribute_returns_nonnull__ + __attribute_malloc__; + +nb_dcpsTopic nb_dcpsTopicAlloc(void) __attribute_returns_nonnull__ + __attribute_malloc__; + +void nb_dcpsTopicInit(nb_dcpsTopic _this) __nonnull_all__; + +void nb_dcpsTopicDeinit(nb_object _this) __nonnull_all__; + +const c_char * nb_dcpsTopicTopicName(nb_dcpsTopic _this) __nonnull_all__; + +const v_builtinTopicKey * nb_dcpsTopicKey(nb_dcpsTopic _this) + __nonnull_all__ + __attribute_const__ + __attribute_returns_nonnull__; + +v_actionResult nb_dcpsTopicReaderAction(c_object o, + c_voidp copyArg /* c_iter * */) + __nonnull((2)); + +#ifndef NDEBUG +void nb_dcpsTopicFree (nb_dcpsTopic _this); +#else +#define nb_dcpsTopicFree(s) nb_objectFree(s) +#endif + +#ifndef NDEBUG +#define nb_dcpsParticipant(o) (assert(nb__objectKind(nb_object(o)) == NB_TOPIC_OBJECT_DCPS_PARTICIPANT), (nb_dcpsParticipant)(o)) +#else +#define nb_dcpsParticipant(o) ((nb_dcpsParticipant)(o)) +#endif + +nb_dcpsParticipant nb_dcpsParticipantNew(void) __attribute_returns_nonnull__ + __attribute_malloc__; + +nb_dcpsParticipant nb_dcpsParticipantAlloc(void) __attribute_returns_nonnull__ + __attribute_malloc__; + +void nb_dcpsParticipantInit(nb_dcpsParticipant _this) __nonnull_all__; + +void nb_dcpsParticipantDeinit(nb_object _this) __nonnull_all__; + +const v_builtinTopicKey * nb_dcpsParticipantKey(nb_dcpsParticipant _this) + __nonnull_all__ + __attribute_const__ + __attribute_returns_nonnull__; + +v_actionResult nb_dcpsParticipantReaderAction(c_object o, + c_voidp copyArg /* c_iter * */) + __nonnull((2)); + +#ifndef NDEBUG +void nb_dcpsParticipantFree (nb_dcpsParticipant _this); +#else +#define nb_dcpsParticipantFree(s) nb_objectFree(s) +#endif + +#ifndef NDEBUG +#define nb_cmParticipant(o) (assert(nb__objectKind(nb_object(o)) == NB_TOPIC_OBJECT_CM_PARTICIPANT), (nb_cmParticipant)(o)) +#else +#define nb_cmParticipant(o) ((nb_cmParticipant)(o)) +#endif + +nb_cmParticipant nb_cmParticipantNew(void) __attribute_returns_nonnull__ + __attribute_malloc__; + +nb_cmParticipant nb_cmParticipantAlloc(void) __attribute_returns_nonnull__ + __attribute_malloc__; + +void nb_cmParticipantInit(nb_cmParticipant _this) __nonnull_all__; + +void nb_cmParticipantDeinit(nb_object _this) __nonnull_all__; + +const v_builtinTopicKey * nb_cmParticipantKey(nb_cmParticipant _this) + __nonnull_all__ + __attribute_const__ + __attribute_returns_nonnull__; + +v_actionResult nb_cmParticipantReaderAction(c_object o, + c_voidp copyArg /* c_iter * */) + __nonnull((2)); + +#ifndef NDEBUG +void nb_cmParticipantFree (nb_cmParticipant _this); +#else +#define nb_cmParticipantFree(s) nb_objectFree(s) +#endif + + +#ifndef NDEBUG +#define nb_dcpsSubscription(o) (assert(nb__objectKind(nb_object(o)) == NB_TOPIC_OBJECT_DCPS_SUBSCRIPTION), (nb_dcpsSubscription)(o)) +#else +#define nb_dcpsSubscription(o) ((nb_dcpsSubscription)(o)) +#endif + +nb_dcpsSubscription nb_dcpsSubscriptionNew(void) __attribute_returns_nonnull__ + __attribute_malloc__; + +nb_dcpsSubscription nb_dcpsSubscriptionAlloc(void) __attribute_returns_nonnull__ + __attribute_malloc__; + +void nb_dcpsSubscriptionInit(nb_dcpsSubscription _this) __nonnull_all__; + +void nb_dcpsSubscriptionDeinit(nb_object _this) __nonnull_all__; + +const c_char * nb_dcpsSubscriptionTopicName(nb_dcpsSubscription _this) __nonnull_all__; + +const v_builtinTopicKey * nb_dcpsSubscriptionKey(nb_dcpsSubscription _this) + __nonnull_all__ + __attribute_const__ + __attribute_returns_nonnull__; + +const v_builtinTopicKey * nb_dcpsSubscriptionParticipantKey(nb_dcpsSubscription _this) + __nonnull_all__ + __attribute_const__ + __attribute_returns_nonnull__; + +const char * const * nb_dcpsSubscriptionPartitions(nb_dcpsSubscription _this, + c_ulong *len) __nonnull_all__; + +c_bool nb_dcpsSubscriptionGetInterested( + nb_dcpsSubscription _this) + __nonnull_all__; + +void nb_dcpsSubscriptionSetInterested( + nb_dcpsSubscription _this, + const char * const * includes, + const char * const * excludes) + __nonnull_all__; + +v_actionResult nb_dcpsSubscriptionReaderAction(c_object o, + c_voidp copyArg /* c_iter * */) + __nonnull((2)); + +#ifndef NDEBUG +void nb_dcpsSubscriptionFree (nb_dcpsSubscription _this); +#else +#define nb_dcpsSubscriptionFree(s) nb_objectFree(s) +#endif + +#ifndef NDEBUG +#define nb_dcpsPublication(o) (assert(nb__objectKind(nb_object(o)) == NB_TOPIC_OBJECT_DCPS_PUBLICATION), (nb_dcpsPublication)(o)) +#else +#define nb_dcpsPublication(o) ((nb_dcpsPublication)(o)) +#endif + +nb_dcpsPublication nb_dcpsPublicationNew(void) __attribute_returns_nonnull__ + __attribute_malloc__; + +nb_dcpsPublication nb_dcpsPublicationAlloc(void) __attribute_returns_nonnull__ + __attribute_malloc__; + +void nb_dcpsPublicationInit(nb_dcpsPublication _this) __nonnull_all__; + +void nb_dcpsPublicationDeinit(nb_object _this) __nonnull_all__; + +const c_char * nb_dcpsPublicationTopicName(nb_dcpsPublication _this) __nonnull_all__; + +const v_builtinTopicKey * nb_dcpsPublicationKey(nb_dcpsPublication _this) + __nonnull_all__ + __attribute_const__ + __attribute_returns_nonnull__; + +const v_builtinTopicKey * nb_dcpsPublicationParticipantKey(nb_dcpsPublication _this) + __nonnull_all__ + __attribute_const__ + __attribute_returns_nonnull__; + +const char * const * nb_dcpsPublicationPartitions(nb_dcpsPublication _this, + c_ulong *len) __nonnull_all__; + +c_bool nb_dcpsPublicationGetInterested(nb_dcpsPublication _this) __nonnull_all__; + +void nb_dcpsPublicationSetInterested(nb_dcpsPublication _this, + const char * const * includes, + const char * const * excludes) __nonnull_all__; + +v_actionResult nb_dcpsPublicationReaderAction(c_object o, + c_voidp copyArg /* c_iter * */) + __nonnull((2)); + +#ifndef NDEBUG +void nb_dcpsPublicationFree (nb_dcpsPublication _this); +#else +#define nb_dcpsPublicationFree(s) nb_objectFree(s) +#endif + +#ifndef NDEBUG +#define nb_cmReader(o) (assert(nb__objectKind(nb_object(o)) == NB_TOPIC_OBJECT_CM_READER), (nb_cmReader)(o)) +#else +#define nb_cmReader(o) ((nb_cmReader)(o)) +#endif + +nb_cmReader nb_cmReaderNew(void) __attribute_returns_nonnull__ + __attribute_malloc__; + +nb_cmReader nb_cmReaderAlloc(void) __attribute_returns_nonnull__ + __attribute_malloc__; + +void nb_cmReaderInit(nb_cmReader _this) __nonnull_all__; + +void nb_cmReaderDeinit(nb_object _this) __nonnull_all__; + +const v_builtinTopicKey * nb_cmReaderKey(nb_cmReader _this) __nonnull_all__ + __attribute_const__ + __attribute_returns_nonnull__; + +const v_builtinTopicKey * nb_cmReaderSubscriberKey(nb_cmReader _this) + __nonnull_all__ + __attribute_const__ + __attribute_returns_nonnull__; + +v_actionResult nb_cmReaderReaderAction(c_object o, + c_voidp copyArg /* c_iter * */) + __nonnull((2)); + +#ifndef NDEBUG +void nb_cmReaderFree (nb_cmReader _this); +#else +#define nb_cmReaderFree(s) nb_objectFree(s) +#endif + +#ifndef NDEBUG +#define nb_cmWriter(o) (assert(nb__objectKind(nb_object(o)) == NB_TOPIC_OBJECT_CM_WRITER), (nb_cmWriter)(o)) +#else +#define nb_cmWriter(o) ((nb_cmWriter)(o)) +#endif + +nb_cmWriter nb_cmWriterNew(void) __attribute_returns_nonnull__ + __attribute_malloc__; + +nb_cmWriter nb_cmWriterAlloc(void) __attribute_returns_nonnull__ + __attribute_malloc__; + +void nb_cmWriterInit(nb_cmWriter _this) __nonnull_all__; + +void nb_cmWriterDeinit(nb_object _this) __nonnull_all__; + +const v_builtinTopicKey * nb_cmWriterKey(nb_cmWriter _this) __nonnull_all__ + __attribute_const__ + __attribute_returns_nonnull__; + +const v_builtinTopicKey * nb_cmWriterPublisherKey(nb_cmWriter _this) __nonnull_all__ + __attribute_const__ + __attribute_returns_nonnull__; + +v_actionResult nb_cmWriterReaderAction(c_object o, + c_voidp copyArg /* c_iter * */) + __nonnull((2)); + +#ifndef NDEBUG +void nb_cmWriterFree (nb_cmWriter _this); +#else +#define nb_cmWriterFree(s) nb_objectFree(s) +#endif + + +#ifndef NDEBUG +#define nb_cmPublisher(o) (assert(nb__objectKind(nb_object(o)) == NB_TOPIC_OBJECT_CM_PUBLISHER), (nb_cmPublisher)(o)) +#else +#define nb_cmPublisher(o) ((nb_cmPublisher)(o)) +#endif + +nb_cmPublisher nb_cmPublisherNew(void) __attribute_returns_nonnull__ + __attribute_malloc__; + +nb_cmPublisher nb_cmPublisherAlloc(void) __attribute_returns_nonnull__ + __attribute_malloc__; + +void nb_cmPublisherInit(nb_cmPublisher _this) __nonnull_all__; + +void nb_cmPublisherDeinit(nb_object _this) __nonnull_all__; + +const v_builtinTopicKey * nb_cmPublisherKey(nb_cmPublisher _this) __nonnull_all__ + __attribute_const__ + __attribute_returns_nonnull__; + +const v_builtinTopicKey * nb_cmPublisherParticipantKey(nb_cmPublisher _this) + __nonnull_all__ + __attribute_const__ + __attribute_returns_nonnull__; + +v_actionResult nb_cmPublisherReaderAction(c_object o, + c_voidp copyArg /* c_iter * */) + __nonnull((2)); + +#ifndef NDEBUG +void nb_cmPublisherFree (nb_cmPublisher _this); +#else +#define nb_cmPublisherFree(s) nb_objectFree(s) +#endif + + +#ifndef NDEBUG +#define nb_cmSubscriber(o) (assert(nb__objectKind(nb_object(o)) == NB_TOPIC_OBJECT_CM_SUBSCRIBER), (nb_cmSubscriber)(o)) +#else +#define nb_cmSubscriber(o) ((nb_cmSubscriber)(o)) +#endif + +nb_cmSubscriber nb_cmSubscriberNew(void) __attribute_returns_nonnull__ + __attribute_malloc__; + +nb_cmSubscriber nb_cmSubscriberAlloc(void) __attribute_returns_nonnull__ + __attribute_malloc__; + +void nb_cmSubscriberInit(nb_cmSubscriber _this) __nonnull_all__; + +void nb_cmSubscriberDeinit(nb_object _this) __nonnull_all__; + +const v_builtinTopicKey * nb_cmSubscriberKey(nb_cmSubscriber _this) __nonnull_all__ + __attribute_const__ + __attribute_returns_nonnull__; + +v_actionResult nb_cmSubscriberReaderAction(c_object o, + c_voidp copyArg /* c_iter * */) + __nonnull((2)); + +#ifndef NDEBUG +void nb_cmSubscriberFree (nb_cmSubscriber _this); +#else +#define nb_cmSubscriberFree(s) nb_objectFree(s) +#endif + +#if defined (__cplusplus) +} +#endif + +#endif /* NB__TOPIC_H */ diff --git a/src/services/nwbridge/code/nb__types.h b/src/services/nwbridge/code/nb__types.h new file mode 100644 index 000000000..b20859566 --- /dev/null +++ b/src/services/nwbridge/code/nb__types.h @@ -0,0 +1,49 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#ifndef NB__TYPES_H_ +#define NB__TYPES_H_ + +#include "c_typebase.h" + +#define C_TYPEDEF(type, name) C_STRUCT(type) *name +/* C_SIZEOF uses C_STRUCT to determine the size; this is not safe for nb_object; + * instead the macro could be defined as C_SIZEOF(name) sizeof(*name), but to + * prevent confusion the macro is undeffed. */ +#undef C_SIZEOF + +C_CLASS(nb_object); +C_CLASS(nb_topicObject); /* Abstract class */ + C_CLASS(nb_dcpsTopic); + C_CLASS(nb_dcpsParticipant); + C_CLASS(nb_cmParticipant); + C_CLASS(nb_dcpsPublication); + C_CLASS(nb_cmWriter); + C_CLASS(nb_dcpsSubscription); + C_CLASS(nb_cmReader); + C_CLASS(nb_cmPublisher); + C_CLASS(nb_cmSubscriber); +C_CLASS(nb_thread); +C_CLASS(nb_service); +C_CLASS(nb_configuration); +C_CLASS(nb_group); + +/* Classes that aren't reference-counted */ +C_CLASS(nb_threadStates); +C_CLASS(nb_logConfig); + +#endif /* NB__TYPES_H_ */ diff --git a/src/services/nwbridge/code/nb__util.c b/src/services/nwbridge/code/nb__util.c new file mode 100644 index 000000000..989e3075e --- /dev/null +++ b/src/services/nwbridge/code/nb__util.c @@ -0,0 +1,153 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#include "nb__util.h" +#include "nb__log.h" + +#include "u_cfNode.h" +#include "v_public.h" + +#include "c_stringSupport.h" + +os_equality +nb_compareByName( + void *o1, + void *o2, + void *arg) +{ + os_equality result; + int equal; + + OS_UNUSED_ARG(arg); + assert(o1); + assert(o2); + + equal = strcmp((os_char*)o1, (os_char*)o2); + + if (equal > 0) { + result = OS_GT; + } else if (equal < 0) { + result = OS_LT; + } else { + result = OS_EQ; + } + + return result; +} + +/* This compile-time constraint assures that the cast from c_equality to + * os_equality is allowed. */ +struct os_equality_equals_c_equality_constraint { + char require_value_OS_LT_eq_value_C_LT [OS_LT == (os_equality)C_LT]; + char require_value_OS_EQ_eq_value_C_EQ [OS_EQ == (os_equality)C_EQ]; + char require_value_OS_GT_eq_value_C_GT [OS_GT == (os_equality)C_GT]; + char require_value_OS_NE_eq_value_C_NE [OS_NE == (os_equality)C_NE]; + char non_empty_dummy_last_member[1]; +}; + +os_equality +nb_compareByGid( + void *o1, + void *o2, + void *arg) +{ + OS_UNUSED_ARG(arg); + assert(o1); + assert(o2); + + /* v_gidCompare does consider the serial, which isn't the meaning of the + * gid per se. */ + return (os_equality)v_gidCompare(*(v_gid *)o1, *(v_gid *)o2);; +} + +c_bool +nb_match( + const char * const * partitions, /* partExpr */ + c_ulong partitionsLen, + const char *topicName, /* Absolute topicName */ + const char * const * includes, /* NULL-terminated partExpr.topExpr */ + const char * const * excludes) /* NULL-terminated partExpr.topExpr */ +{ + c_ulong i, j; + const char *topExpr; + const char *partTopExpr; /* partExpr.topExpr */ + char *partExpr; + + assert(partitions); + assert(topicName); + assert(includes); + assert(excludes); + + j = 0; + while((partTopExpr = excludes[j++]) != NULL){ + topExpr = strrchr(partTopExpr, '.'); + assert(topExpr); /* partTopExpr MUST have a dot */ + + if(!c_stringMatchesExpression(topicName, topExpr + 1)) continue; + + partExpr = os_strndup(partTopExpr, (os_size_t)(topExpr - partTopExpr)); + for(i = 0; i < partitionsLen; i++){ + if(c_stringMatchesExpression(partitions[i], partExpr)){ + NB_TRACE(("'%s.%s' excluded since it matches exclude expression '%s%s'\n", + partitions[i], topicName, + partExpr, topExpr + )); + os_free(partExpr); + goto exclude_matched; + } + } + os_free(partExpr); + } + + j = 0; + while((partTopExpr = includes[j++]) != NULL){ + topExpr = strrchr(partTopExpr, '.'); + assert(topExpr); /* partTopExpr MUST have a dot */ + + if(!c_stringMatchesExpression(topicName, topExpr + 1)) continue; + + partExpr = os_strndup(partTopExpr, (os_size_t)(topExpr - partTopExpr)); + for(i = 0; i < partitionsLen; i++){ + if(c_stringMatchesExpression(partitions[i], partExpr)){ + NB_TRACE(("'%s.%s' included since it matches include expression '%s%s'\n", + partitions[i], topicName, + partExpr, topExpr + )); + os_free(partExpr); + return TRUE; + } + } + os_free(partExpr); + } + + NB_TRACE(("Topic '%s' didn't match any include or exclude expression, so it is excluded\n", topicName)); + +exclude_matched: + return FALSE; +} + +void +nb_cfNodeIterFree( + c_iter iter) +{ + u_cfNode node; + assert(iter); + while ((node = c_iterTakeFirst(iter))) { + u_cfNodeFree(node); + } + c_iterFree(iter); +} diff --git a/src/services/nwbridge/code/nb__util.h b/src/services/nwbridge/code/nb__util.h new file mode 100644 index 000000000..2022e1c6d --- /dev/null +++ b/src/services/nwbridge/code/nb__util.h @@ -0,0 +1,74 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#ifndef NB__UTIL_H_ +#define NB__UTIL_H_ + +#include "nb__common.h" +#include "c_typebase.h" +#include "c_iterator.h" + +#include "vortex_os.h" +#include "os_iterator.h" /* For os_equality */ + +#define NB_SET_STATEBASED_TOPICQOS(qos) \ + do { \ + (qos)->durability.v.kind = V_DURABILITY_TRANSIENT; \ + (qos)->history.v.kind = V_HISTORY_KEEPLAST; \ + (qos)->history.v.depth = 1; \ + (qos)->reliability.v.kind = V_RELIABILITY_RELIABLE; \ + (qos)->reliability.v.max_blocking_time = OS_DURATION_INIT(0,100000000); /* 100ms */ \ + (qos)->orderby.v.kind = V_ORDERBY_RECEPTIONTIME; \ + /* This is required to match the default qos from DDS API */ \ + (qos)->liveliness.v.lease_duration = OS_DURATION_INFINITE; \ + } while (0) + +#define NB_SET_STATEBASED_WRITERQOS(qos) \ + do { \ + /* Copy from topic-QoS */ \ + NB_SET_STATEBASED_TOPICQOS(qos); \ + /* This allows an event-based reader to see all status updates; ultra convenient :). */ \ + (qos)->history.v.kind = V_HISTORY_KEEPALL; \ + } while (0) + +#define NB_SET_STATEBASED_READERQOS(qos) \ + do { \ + NB_SET_STATEBASED_WRITERQOS(qos); \ + } while (0) + +/* Compare function for ut_table elements using a string as key */ +os_equality nb_compareByName(void *o1, + void *o2, + void *arg) __nonnull((1,2)) + __attribute_pure__; + +os_equality nb_compareByGid(void *o1, + void *o2, + void *arg) __nonnull((1,2)) + __attribute_pure__; + +c_bool nb_match(const char * const * partitions, + c_ulong partitionsLen, + const char *topicName, + const char * const * includes, + const char * const * excludes) __nonnull_all__ + __attribute_pure__; + +/* Free a c_iter containing u_cfNode */ +void nb_cfNodeIterFree(c_iter iter) __nonnull_all__; + +#endif /* NB__UTIL_H_ */ diff --git a/src/services/nwbridge/code/nb_configuration.c b/src/services/nwbridge/code/nb_configuration.c new file mode 100644 index 000000000..0a2ae9517 --- /dev/null +++ b/src/services/nwbridge/code/nb_configuration.c @@ -0,0 +1,1574 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#include + +#include "nb__configuration.h" +#include "nb__service.h" +#include "nb__util.h" +#include "nb__log.h" + +#include "vortex_os.h" +#include "os_report.h" + +#include "ut_collection.h" +#include "cfg_parser.h" +#include "u_domain.h" +#include "u_cfNode.h" +#include "u_cfData.h" + +#include "ut_avl.h" + +#ifdef __GNUC__ +#define UNUSED_ARG(x) x __attribute__ ((unused)) +#else +#define UNUSED_ARG(x) x +#endif + +void +nb_logConfigInit( + nb_logConfig _this) +{ + assert(_this); + + /* Trace output to stderr until configuration is read */ + _this->tracing.categories = LOG_ERROR | LOG_FATAL; + _this->tracing.file = stderr; +} + +void +nb_logConfigDeinit( + nb_logConfig _this) +{ + assert(_this); + + if (_this->tracing.file) { + fclose(_this->tracing.file); + } +} + +/* FIXME: should eventually move to abstraction layer */ +typedef enum q__schedPrioClass { + Q__SCHED_PRIO_RELATIVE, + Q__SCHED_PRIO_ABSOLUTE +} q__schedPrioClass; + +struct nb_config_include_exclude_listelem +{ + struct nb_config_include_exclude_listelem *next; + char *partition_topic; +}; + +struct cfgst; + +C_STRUCT(nb_configuration) +{ + C_EXTENDS(nb_object); + int valid; + struct cfgst *cfgst; /* a bit yucky ... */ + + const os_char* serviceName; /* Don't free; unmanaged backref */ + u_participant participant; + struct { + os_timeReal expiry; + os_float updateFactor; + } serviceLease; + struct { + /* Tracing options */ + os_char* outputFileName; /* Name of tracing logfile */ + c_bool appendToFile; + nb_logcat categories; + } tracing; + + struct nb_config_include_exclude_listelem *included_groups; + struct nb_config_include_exclude_listelem *excluded_groups; + + /* not used by; user layer directly accesses + the configuration tree */ + os_schedClass watchdog_sched_class; + os_int32 watchdog_sched_priority; + q__schedPrioClass watchdog_sched_priority_class; +}; + +/******************* DDSI-DERIVED CONFIG STUFF *******************/ +#define WARN_DEPRECATED_ALIAS 1 +#define WARN_DEPRECATED_UNIT 1 +#define MAX_PATH_DEPTH 10 /* max nesting level of configuration elements */ + +struct cfgelem; +struct cfgst; + +typedef int (*init_fun_t) (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem); +typedef int (*update_fun_t) (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int first, const char *value); +typedef void (*free_fun_t) (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem); +typedef void (*print_fun_t) (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int is_default); + +struct unit { + const char *name; + os_int64 multiplier; +}; + +struct cfgelem { + const char *name; + const struct cfgelem *children; + const struct cfgelem *attributes; + int multiplicity; + const char *defvalue; /* NULL -> no default */ + int relative_offset; + int elem_offset; + init_fun_t init; + update_fun_t update; + free_fun_t free; + print_fun_t print; + const char *description; +}; + +struct cfgst_nodekey { + const struct cfgelem *e; +}; + +/* config_listelem must be an overlay for all used listelem types */ +struct config_listelem { + struct config_listelem *next; +}; + +struct cfgst_node { + ut_avlNode_t avlnode; + struct cfgst_nodekey key; + int count; + int failed; + int is_default; +}; + +struct cfgst { + ut_avlTree_t found; + nb_configuration cfg; + + /* Servicename is used by uf_service_name to use as a default value + when the supplied string is empty, which happens when the service + is started without a NetworkingBridge configuration item, i.e. when + everything is left at the default. */ + const char *servicename; + + /* path_depth, isattr and path together control the formatting of + error messages by cfg_error() */ + int path_depth; + int isattr[MAX_PATH_DEPTH]; + const struct cfgelem *path[MAX_PATH_DEPTH]; + void *parent[MAX_PATH_DEPTH]; +}; + +/* "trace" is special: it enables (nearly) everything */ +static const char *logcat_names[] = { + "fatal", "error", "warning", "config", "info", "trace", NULL +}; +static const nb_logcat logcat_codes[] = { + LOG_FATAL, LOG_ERROR, LOG_WARNING, LOG_CONFIG, LOG_INFO, LOG_TRACE, 0 +}; + +static int cfgst_node_cmp (const void *va, const void *vb); +static const ut_avlTreedef_t cfgst_found_treedef = UT_AVL_TREEDEF_INITIALIZER (offsetof (struct cfgst_node, avlnode), offsetof (struct cfgst_node, key), cfgst_node_cmp, 0); + +#define DU(fname) static int fname (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int first, const char *value) +DU (uf_nopstring); +DU (uf_boolean); +DU (uf_partition_topic); +DU (uf_tracingOutputFileName); +DU (uf_verbosity); +DU (uf_logcat); +DU (uf_float); +DU (uf_timeReal); +DU (uf_int32); +DU (uf_sched_prio_class); +DU (uf_sched_class); +#undef DU + +#define DF(fname) static void fname (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem) +DF (ff_free); +#undef DF + +#define DI(fname) static int fname (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem) +DI (if_include_exclude_entry); +#undef DI + +#define PF(fname) static void fname (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int is_default) +PF (pf_nop); +PF (pf_string); +PF (pf_logcat); +PF (pf_boolean); +PF (pf_float); +PF (pf_timeReal); +PF (pf_int32); +PF (pf_sched_prio_class); +PF (pf_sched_class); +#undef PF + +#define CO(name) ((int) offsetof (struct nb_configuration_s, name)) +#define ABSOFF(name) 0, CO (name) +#define RELOFF(parent,name) 1, ((int) offsetof (struct parent, name)) +#define NODATA 1, NULL, 0, 0, 0, 0, 0, 0 +#define END_MARKER { NULL, NULL, NULL, NODATA, NULL } +#define WILDCARD { "*", NULL, NULL, NODATA, NULL } +#define LEAF(name) name, NULL, NULL +#define LEAF_W_ATTRS(name, attrs) name, NULL, attrs +#define GROUP(name, children) name, children, NULL, 1, NULL, 0, 0, 0, 0, 0, 0 +#define MGROUP(name, children, attrs) name, children, attrs +#define ATTR(name) name, NULL, NULL +static const struct cfgelem tracing_cfgelems[] = { + { LEAF ("EnableCategory"), 1, "", 0, 0, 0, uf_logcat, 0, pf_logcat, + "

    This element enables individual logging categories. These are enabled in addition to those enabled by Tracing/Verbosity. Recognised categories are:\n\ +

    • fatal: all fatal errors, errors causing immediate termination
    • \n\ +
    • error: failures probably impacting correctness but not necessarily causing immediate termination
    • \n\ +
    • warning: abnormal situations that will likely not impact correctness
    • \n\ +
    • config: full dump of the configuration
    • \n\ +
    • info: general informational notices
    \n\ +In addition, there is the keyword trace that enables all but radmin

    " }, + { LEAF ("Verbosity"), 1, "none", 0, 0, 0, uf_verbosity, 0, pf_nop, + "

    This element enables standard groups of categories, based on a desired verbosity level. This is in addition to the categories enabled by the Tracing/EnableCategory setting. Recognised verbosity levels and the categories they map to are:\n\ +

    • none: no NetworkingBridge log
    • \n\ +
    • severe: error and fatal
    • \n\ +
    • warning: severe + warning
    • \n\ +
    • info: warning + general information messages
    • \n\ +
    • config: info + config
    • \n\ +
    • fine: equivalent to config
    • \n\ +
    • finest: fine + trace
    \n\ +While noneprevents any message from being written to a NetworkingBridge log file, warnings and errors are still logged in the ospl-info.log and ospl-error.log files.

    " }, + { LEAF ("OutputFile"), 1, "nwbridge.log", ABSOFF (tracing.outputFileName), 0, uf_tracingOutputFileName, ff_free, pf_string, + "

    This option specifies where the logging is printed to. Note that stdout and stderr are treated as special values, representing \"standard out\" and \"standard error\" respectively. No file is created unless logging categories are enabled using the Tracing/Verbosity or Tracing/EnabledCategory settings.

    " }, + { LEAF ("AppendToFile"), 1, "false", ABSOFF (tracing.appendToFile), 0, uf_boolean, 0, pf_boolean, + "

    This option specifies whether the output is to be appended to an existing log file. The default is to create a new log file each time, which is generally the best option if a detailed log is generated.

    " }, + END_MARKER +}; + +static const struct cfgelem sched_prio_cfgattrs[] = { + { ATTR ("priority_kind"), 1, "relative", ABSOFF (watchdog_sched_priority_class), 0, uf_sched_prio_class, 0, pf_sched_prio_class, + "

    This attribute specifies whether the specified Priority is a relative or absolute priority.

    " }, + END_MARKER +}; + +static const struct cfgelem sched_cfgelems[] = { + { LEAF ("Class"), 1, "default", ABSOFF (watchdog_sched_class), 0, uf_sched_class, 0, pf_sched_class, + "

    This element specifies the thread scheduling class that will be used by the watchdog thread. The user may need the appropriate privileges from the underlying operating system to be able to assign some of the privileged scheduling classes.

    " }, + { LEAF_W_ATTRS ("Priority", sched_prio_cfgattrs), 1, "0", ABSOFF (watchdog_sched_priority), 0, uf_int32, 0, pf_int32, + "

    This element specifies the thread priority. Only priorities that are supported by the underlying operating system can be assigned to this element. The user may need special privileges from the underlying operating system to be able to assign some of the privileged priorities.

    " }, + END_MARKER +}; + +static const struct cfgelem watchdog_cfgelems[] = { + { GROUP ("Scheduling", sched_cfgelems), + "

    This element specifies the type of OS scheduling class will be used by the thread that announces its liveliness periodically.

    " }, + END_MARKER +}; + +static const struct cfgelem include_exclude_entry_cfgattrs[] = { + { ATTR ("DCPSPartitionTopic"), 1, NULL, RELOFF (nb_config_include_exclude_listelem, partition_topic), 0, uf_partition_topic, ff_free, pf_string, + "

    This attribute specifies a partition and a topic expression, separated by a single '.', that are used to determine if a given partition and topic will be ignored or not. The expressions may use the usual wildcards '*' and '?'.

    " }, + END_MARKER +}; + +static const struct cfgelem include_cfgelems[] = { + { MGROUP ("Entry", NULL, include_exclude_entry_cfgattrs), 0, NULL, ABSOFF (included_groups), if_include_exclude_entry, 0, 0, 0, + "

    This element configures a single partition/topic combination for inclusion in the set of forwarded partition/topic combinations.

    " }, + END_MARKER +}; + +static const struct cfgelem exclude_cfgelems[] = { + { MGROUP ("Entry", NULL, include_exclude_entry_cfgattrs), 0, NULL, ABSOFF (excluded_groups), if_include_exclude_entry, 0, 0, 0, + "

    This element configures a single partition/topic combination for exclusion in the set of forwarded partition/topic combinations.

    " }, + END_MARKER +}; + +static const struct cfgelem nb_cfgelems[] = { + { GROUP ("Tracing", tracing_cfgelems), + "

    The Tracing element controls the amount and type of information that is written into the tracing log by the DDSI service. This is useful to track the DDSI service during application development.

    " }, + { GROUP ("Watchdog", watchdog_cfgelems), + "

    This element specifies the type of OS scheduling class will be used by the thread that announces its liveliness periodically.

    " }, + { GROUP ("Include", include_cfgelems), + "

    This element specifies which partition/topic combinations are to be forwarded, provided they are not listed in the Exclude section.

    " }, + { GROUP ("Exclude", exclude_cfgelems), + "

    This element specifies which partition/topic combinations may not be forwarded.

    " }, + END_MARKER +}; + +/* Note: using 2e-1 instead of 0.2 to avoid use of the decimal + separator, which is locale dependent. */ +static const struct cfgelem lease_expiry_time_cfgattrs[] = { + { ATTR ("update_factor"), 1, "2e-1", ABSOFF (serviceLease.updateFactor), 0, uf_float, 0, pf_float, NULL }, + END_MARKER +}; + +static const struct cfgelem lease_cfgelems[] = { + { LEAF_W_ATTRS ("ExpiryTime", lease_expiry_time_cfgattrs), 1, "10", ABSOFF (serviceLease.expiry), 0, uf_timeReal, 0, pf_timeReal, NULL }, + END_MARKER +}; + +static const struct cfgelem domain_cfgelems[] = { + { GROUP ("Lease", lease_cfgelems), NULL }, + WILDCARD, + END_MARKER +}; + +static const struct cfgelem nb_cfgattrs[] = { + { ATTR ("name"), 1, NULL, ABSOFF (serviceName), 0, uf_nopstring, 0, pf_string, + "

    This attribute identifies the configuration for the Networking Bridge Service. Multiple service configurations can be specified in one single XML file. The actual applicable configuration is determined by the value of the name attribute, which must match the specified under the element OpenSplice/Domain/Service[@name] in the Domain Service configuration.

    " }, + END_MARKER +}; + +static const struct cfgelem root_cfgelems[] = { + { "NetworkingBridgeService", nb_cfgelems, nb_cfgattrs, NODATA, + "

    The root element of a networking bridge service configuration.

    " }, + { "Domain", domain_cfgelems, NULL, NODATA, NULL }, + END_MARKER +}; + +static const struct cfgelem root_cfgelem = +{ NULL, root_cfgelems, NULL, NODATA, "root" }; + +#undef ATTR +#undef GROUP +#undef LEAF_W_ATTRS +#undef LEAF +#undef WILDCARD +#undef END_MARKER +#undef NODATA +#undef RELOFF +#undef ABSOFF +#undef CO + +static void cfgst_push (struct cfgst *cfgst, int isattr, const struct cfgelem *elem, void *parent) +{ + assert (cfgst->path_depth < MAX_PATH_DEPTH); + assert (isattr == 0 || isattr == 1); + cfgst->isattr[cfgst->path_depth] = isattr; + cfgst->path[cfgst->path_depth] = elem; + cfgst->parent[cfgst->path_depth] = parent; + cfgst->path_depth++; +} + +static void cfgst_pop (struct cfgst *cfgst) +{ + assert (cfgst->path_depth > 0); + cfgst->path_depth--; +} + +static const struct cfgelem *cfgst_tos (const struct cfgst *cfgst) +{ + assert (cfgst->path_depth > 0); + return cfgst->path[cfgst->path_depth-1]; +} + +static void *cfgst_parent (const struct cfgst *cfgst) +{ + assert (cfgst->path_depth > 0); + return cfgst->parent[cfgst->path_depth-1]; +} + +struct cfg_note_buf { + size_t bufpos; + size_t bufsize; + char *buf; +}; + +static size_t cfg_note_vsnprintf (struct cfg_note_buf *bb, const char *fmt, va_list ap) +{ + int x; + x = os_vsnprintf (bb->buf + bb->bufpos, bb->bufsize - bb->bufpos, fmt, ap); + if (x >= 0 && (size_t)x >= bb->bufsize - bb->bufpos) + { + size_t nbufsize = ((bb->bufsize + (size_t)x + 1) + 1023) & (size_t)-1024; + char *nbuf = os_realloc (bb->buf, nbufsize); + bb->buf = nbuf; + bb->bufsize = nbufsize; + return nbufsize; + } + if (x < 0) + NB_FATAL ("nwbridge_config", "cfg_note_vsnprintf: os_vsnprintf failed\n"); + else + bb->bufpos += (size_t) x; + return 0; +} + +static void cfg_note_snprintf (struct cfg_note_buf *bb, const char *fmt, ...) +{ + /* The reason the 2nd call to os_vsnprintf is here and not inside + cfg_note_vsnprintf is because I somehow doubt that all platforms + implement va_copy() */ + va_list ap; + size_t r; + va_start (ap, fmt); + r = cfg_note_vsnprintf (bb, fmt, ap); + va_end (ap); + if (r > 0) + { + int s; + va_start (ap, fmt); + s = os_vsnprintf (bb->buf + bb->bufpos, bb->bufsize - bb->bufpos, fmt, ap); + if (s < 0 || (size_t) s >= bb->bufsize - bb->bufpos) + NB_FATAL ("nwbridge_config", "cfg_note_snprintf: os_vsnprintf failed\n"); + va_end (ap); + bb->bufpos += (size_t) s; + } +} + +static size_t cfg_note (struct cfgst *cfgst, nb_logcat cat, size_t bsz, const char *fmt, va_list ap) +{ + /* Have to snprintf our way to a single string so we can OS_REPORT + as well as nn_log. Otherwise configuration errors will be lost + completely on platforms where stderr doesn't actually work for + outputting error messages (this includes Windows because of the + way "ospl start" does its thing). */ + struct cfg_note_buf bb; + int i, sidx; + size_t r; + + bb.bufpos = 0; + bb.bufsize = (bsz == 0) ? 1024 : bsz; + if ((bb.buf = os_malloc (bb.bufsize)) == NULL) + NB_FATAL ("nwbridge_config", "cfg_note: out of memory\n"); + + cfg_note_snprintf (&bb, "config: "); + + /* Path to element/attribute causing the error. Have to stop once an + attribute is reached: a NULL marker may have been pushed onto the + stack afterward in the default handling. */ + sidx = 0; + while (sidx < cfgst->path_depth && cfgst->path[sidx]->name == NULL) + sidx++; + for (i = sidx; i < cfgst->path_depth && (i == sidx || !cfgst->isattr[i-1]); i++) + { + if (cfgst->path[i] == NULL) + { + assert (i > sidx); + cfg_note_snprintf (&bb, "/#text"); + } + else if (cfgst->isattr[i]) + { + cfg_note_snprintf (&bb, "[@%s]", cfgst->path[i]->name); + } + else + { + const char *p = strchr (cfgst->path[i]->name, '|'); + int n = p ? (int) (p - cfgst->path[i]->name) : (int) strlen (cfgst->path[i]->name); + cfg_note_snprintf (&bb, "%s%*.*s", (i == sidx) ? "" : "/", n, n, cfgst->path[i]->name); + } + } + + cfg_note_snprintf (&bb, ": "); + if ((r = cfg_note_vsnprintf (&bb, fmt, ap)) > 0) + { + /* Can't reset ap ... and va_copy isn't widely available - so + instead abort and hope the caller tries again with a larger + initial buffer */ + os_free (bb.buf); + return r; + } + + switch (cat) + { + case LOG_CONFIG: + nb_log (cat, "%s\n", bb.buf); + break; + case LOG_WARNING: + NB_WARNING_1 ("nwbridge_config", "%s\n", bb.buf); + break; + case LOG_ERROR: + NB_ERROR_1 ("nwbridge_config", "%s\n", bb.buf); + break; + default: + NB_FATAL_2 ("nwbridge_config", "cfg_note unhandled category %u for message %s\n", (unsigned) cat, bb.buf); + break; + } + + os_free (bb.buf); + return 0; +} + +#if WARN_DEPRECATED_ALIAS || WARN_DEPRECATED_UNIT +static void cfg_warning (struct cfgst *cfgst, const char *fmt, ...) +{ + va_list ap; + size_t bsz = 0; + do { + va_start (ap, fmt); + bsz = cfg_note (cfgst, LOG_WARNING, bsz, fmt, ap); + va_end (ap); + } while (bsz > 0); +} +#endif + +static int cfg_error (struct cfgst *cfgst, const char *fmt, ...) +{ + va_list ap; + size_t bsz = 0; + do { + va_start (ap, fmt); + bsz = cfg_note (cfgst, LOG_ERROR, bsz, fmt, ap); + va_end (ap); + } while (bsz > 0); + return 0; +} + +static int cfg_log (struct cfgst *cfgst, const char *fmt, ...) +{ + va_list ap; + size_t bsz = 0; + do { + va_start (ap, fmt); + bsz = cfg_note (cfgst, LOG_CONFIG, bsz, fmt, ap); + va_end (ap); + } while (bsz > 0); + return 0; +} + +static int list_index (const char *list[], const char *elem) +{ + int i; + for (i = 0; list[i] != NULL; i++) + { + if (os_strcasecmp (list[i], elem) == 0) + return i; + } + return -1; +} + +static void *cfg_address (UNUSED_ARG (struct cfgst *cfgst), void *parent, struct cfgelem const * const cfgelem) +{ + assert (cfgelem->multiplicity == 1); + return (char *) parent + cfgelem->elem_offset; +} + +static void *cfg_deref_address (UNUSED_ARG (struct cfgst *cfgst), void *parent, struct cfgelem const * const cfgelem) +{ + assert (cfgelem->multiplicity != 1); + return *((void **) ((char *) parent + cfgelem->elem_offset)); +} + +static void *if_common (UNUSED_ARG (struct cfgst *cfgst), void *parent, struct cfgelem const * const cfgelem, unsigned size) +{ + struct config_listelem **current = (struct config_listelem **) ((char *) parent + cfgelem->elem_offset); + struct config_listelem *new = os_malloc (size); + new->next = *current; + *current = new; + return new; +} + +static int if_include_exclude_entry (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem) +{ + struct nb_config_include_exclude_listelem *new = if_common (cfgst, parent, cfgelem, sizeof (*new)); + if (new == NULL) + return -1; + new->partition_topic = NULL; + return 0; +} + +static void ff_free (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem) +{ + void **elem = cfg_address (cfgst, parent, cfgelem); + os_free (*elem); +} + +static int uf_nopstring (UNUSED_ARG (struct cfgst *cfgst), UNUSED_ARG (void *parent), UNUSED_ARG (struct cfgelem const * const cfgelem), UNUSED_ARG (int first), UNUSED_ARG (const char *value)) +{ + return 1; +} + +static int uf_boolean (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, UNUSED_ARG (int first), const char *value) +{ + static const char *vs[] = { "false", "true", NULL }; + int *elem = cfg_address (cfgst, parent, cfgelem); + int idx = list_index (vs, value); + if (idx < 0) + return cfg_error (cfgst, "'%s': undefined value", value); + else + { + *elem = idx; + return 1; + } +} + +static int uf_float (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, UNUSED_ARG (int first), const char *value) +{ + float *elem = cfg_address (cfgst, parent, cfgelem); + char *endptr; + float f = (float) strtod (value, &endptr); + if (*value == 0 || *endptr != 0) + return cfg_error (cfgst, "%s: not a floating point number", value); + *elem = f; + return 1; +} + +static int uf_timeReal (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, UNUSED_ARG (int first), const char *value) +{ + os_timeReal *elem = cfg_address (cfgst, parent, cfgelem); + char *endptr; + os_timeReal f = (os_timeReal) strtod (value, &endptr); + if (*value == 0 || *endptr != 0) + return cfg_error (cfgst, "%s: not a floating point number", value); + *elem = f; + return 1; +} + +static int uf_int32 (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, UNUSED_ARG (int first), const char *value) +{ + os_int32 *elem = cfg_address (cfgst, parent, cfgelem); + char *endptr; + long v = strtol (value, &endptr, 10); + if (*value == 0 || *endptr != 0) + return cfg_error (cfgst, "%s: not a decimal integer", value); + if (v != (int) v) + return cfg_error (cfgst, "%s: value out of range", value); + *elem = (int) v; + return 1; +} + +static int uf_logcat (struct cfgst *cfgst, UNUSED_ARG (void *parent), UNUSED_ARG (struct cfgelem const * const cfgelem), UNUSED_ARG (int first), const char *value) +{ + static const char **vs = logcat_names; + static const nb_logcat *lc = logcat_codes; + char *copy = os_strdup (value), *cursor = copy, *tok; + while ((tok = os_strsep (&cursor, ",")) != NULL) + { + int idx = list_index (vs, tok); + if (idx < 0) + { + int ret = cfg_error (cfgst, "'%s' in '%s' undefined", tok, value); + os_free (copy); + return ret; + } + cfgst->cfg->tracing.categories |= lc[idx]; + } + os_free (copy); + return 1; +} + +static int uf_verbosity (struct cfgst *cfgst, UNUSED_ARG (void *parent), UNUSED_ARG (struct cfgelem const * const cfgelem), UNUSED_ARG (int first), const char *value) +{ + static const char *vs[] = { + "finest", "fine", "config", "info", "warning", "severe", "none", NULL + }; + static const nb_logcat lc[] = { + LOG_TRACE, 0, LOG_CONFIG, LOG_INFO, LOG_WARNING, LOG_ERROR | LOG_FATAL, 0, 0 + }; + int idx = list_index (vs, value); + assert (sizeof (vs) / sizeof (*vs) == sizeof (lc) / sizeof (*lc)); + if (idx < 0) + return cfg_error (cfgst, "'%s': undefined value", value); + else + { + int i; + for (i = (int) (sizeof (vs) / sizeof (*vs)) - 1; i >= idx; i--) + cfgst->cfg->tracing.categories |= lc[i]; + return 1; + } +} + +static int uf_partition_topic (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, UNUSED_ARG (int first), const char *value) +{ + char **elem = cfg_address (cfgst, parent, cfgelem); + const char *p = strchr (value, '.'); + if (p == NULL || *(p + 1) == 0) { + return cfg_error (cfgst, "'%s': not a valid partition/topic specification", value); + } else { + *elem = os_strdup (value); + return 1; + } +} + +static int uf_tracingOutputFileName (struct cfgst *cfgst, UNUSED_ARG (void *parent), UNUSED_ARG (struct cfgelem const * const cfgelem), UNUSED_ARG (int first), const char *value) +{ + nb_configuration cfg = cfgst->cfg; + if (os_strcasecmp (value, "stdout") != 0 && os_strcasecmp (value, "stderr") != 0) { + cfg->tracing.outputFileName = os_fileNormalize (value); + } else { + cfg->tracing.outputFileName = os_strdup (value); + } + return 1; +} + +static int uf_sched_prio_class (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem,UNUSED_ARG (int first), const char *value) +{ + int ret; + q__schedPrioClass *prio; + + assert (value != NULL); + + prio = cfg_address (cfgst, parent, cfgelem); + + if (os_strcasecmp (value, "relative") == 0) { + *prio = Q__SCHED_PRIO_RELATIVE; + ret = 1; + } else if (os_strcasecmp (value, "absolute") == 0) { + *prio = Q__SCHED_PRIO_ABSOLUTE; + ret = 1; + } else { + ret = cfg_error (cfgst, "'%s': undefined value", value); + } + + return ret; +} + +static void pf_sched_prio_class (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int is_default) +{ + char *str; + q__schedPrioClass *prio = cfg_address (cfgst, parent, cfgelem); + + if (*prio == Q__SCHED_PRIO_RELATIVE) { + str = "relative"; + } else if (*prio == Q__SCHED_PRIO_ABSOLUTE) { + str = "absolute"; + } else { + str = "INVALID"; + } + + cfg_log (cfgst, "%s%s", str, is_default ? " [def]" : ""); +} + +static int uf_sched_class (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, UNUSED_ARG (int first), const char *value) +{ + static const char *vs[] = { "realtime", "timeshare", "default" }; + static const os_schedClass ms[] = { OS_SCHED_REALTIME, OS_SCHED_TIMESHARE, OS_SCHED_DEFAULT }; + int idx = list_index (vs, value); + os_schedClass *elem = cfg_address (cfgst, parent, cfgelem); + assert (sizeof (vs) / sizeof (*vs) == sizeof (ms) / sizeof (*ms)); + if (idx < 0) + return cfg_error (cfgst, "'%s': undefined value", value); + *elem = ms[idx]; + return 1; +} + +static void pf_sched_class (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int is_default) +{ + os_schedClass *p = cfg_address (cfgst, parent, cfgelem); + const char *str = "INVALID"; + switch (*p) + { + case OS_SCHED_DEFAULT: str = "default"; break; + case OS_SCHED_TIMESHARE: str = "timeshare"; break; + case OS_SCHED_REALTIME: str = "realtime"; break; + } + cfg_log (cfgst, "%s%s", str, is_default ? " [def]" : ""); +} + + +static void pf_float (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int is_default) +{ + float *p = cfg_address (cfgst, parent, cfgelem); + cfg_log (cfgst, "%f%s", *p, is_default ? " [def]" : ""); +} + +static void pf_timeReal (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int is_default) +{ + os_timeReal *p = cfg_address (cfgst, parent, cfgelem); + cfg_log (cfgst, "%f%s", *p, is_default ? " [def]" : ""); +} + +static void pf_int32 (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int is_default) +{ + os_int32 *p = cfg_address (cfgst, parent, cfgelem); + cfg_log (cfgst, "%d%s", *p, is_default ? " [def]" : ""); +} + +static int do_update (struct cfgst *cfgst, update_fun_t upd, void *parent, struct cfgelem const * const cfgelem, const char *value, int is_default) +{ + struct cfgst_node *n; + struct cfgst_nodekey key; + ut_avlIPath_t np; + int ok; + key.e = cfgelem; + if ((n = ut_avlLookupIPath (&cfgst_found_treedef, &cfgst->found, &key, &np)) == NULL) + { + if ((n = os_malloc (sizeof (*n))) == NULL) + return cfg_error (cfgst, "out of memory"); + + n->key = key; + n->count = 0; + n->failed = 0; + n->is_default = is_default; + ut_avlInsertIPath (&cfgst_found_treedef, &cfgst->found, n, &np); + } + if (cfgelem->multiplicity == 0 || n->count < cfgelem->multiplicity) + ok = upd (cfgst, parent, cfgelem, (n->count == n->failed), value); + else + ok = cfg_error (cfgst, "only %d instance(s) allowed",cfgelem->multiplicity); + n->count++; + if (!ok) + { + n->failed++; + } + return ok; +} + +static int set_default (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem) +{ + if (cfgelem->defvalue == NULL) + return cfg_error (cfgst, "element missing in configuration"); + return do_update (cfgst, cfgelem->update, parent, cfgelem, cfgelem->defvalue, 1); +} + +static int set_defaults (struct cfgst *cfgst, void *parent, int isattr, struct cfgelem const * const cfgelem, int clear_found) +{ + const struct cfgelem *ce; + int ok = 1; + for (ce = cfgelem; ce && ce->name; ce++) + { + struct cfgst_node *n; + struct cfgst_nodekey key; + key.e = ce; + cfgst_push (cfgst, isattr, ce, parent); + if (ce->multiplicity == 1) + { + if (ut_avlLookup (&cfgst_found_treedef, &cfgst->found, &key) == NULL) + { + if (ce->update) + { + int ok1; + cfgst_push (cfgst, 0, NULL, NULL); + ok1 = set_default (cfgst, parent, ce); + cfgst_pop (cfgst); + ok = ok && ok1; + } + } + if ((n = ut_avlLookup (&cfgst_found_treedef, &cfgst->found, &key)) != NULL) + { + if (clear_found) + { + ut_avlDelete (&cfgst_found_treedef, &cfgst->found, n); + os_free (n); + } + } + if (ce->children) + { + int ok1 = set_defaults (cfgst, parent, 0, ce->children, clear_found); + ok = ok && ok1; + } + if (ce->attributes) + { + int ok1 = set_defaults (cfgst, parent, 1, ce->attributes, clear_found); + ok = ok && ok1; + } + } + cfgst_pop (cfgst); + } + return ok; +} + +static void pf_nop (UNUSED_ARG (struct cfgst *cfgst), UNUSED_ARG (void *parent), UNUSED_ARG (struct cfgelem const * const cfgelem), UNUSED_ARG (int is_default)) +{ +} + +static void pf_string (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int is_default) +{ + char **p = cfg_address (cfgst, parent, cfgelem); + cfg_log (cfgst, "%s%s", *p ? *p : "(null)", is_default ? " [def]" : ""); +} + +static void pf_boolean (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem, int is_default) +{ + int *p = cfg_address (cfgst, parent, cfgelem); + cfg_log (cfgst, "%s%s", *p ? "true" : "false", is_default ? " [def]" : ""); +} + +static void pf_logcat (struct cfgst *cfgst, UNUSED_ARG (void *parent), UNUSED_ARG (struct cfgelem const * const cfgelem), UNUSED_ARG (int is_default)) +{ + nb_configuration config = cfgst->cfg; + nb_logcat remaining = config->tracing.categories; + char res[256] = "", *resp = res; + const char *prefix = ""; + size_t i; +#ifndef NDEBUG + { + size_t max; + for (i = 0, max = 0; i < sizeof (logcat_codes) / sizeof (*logcat_codes); i++) + max += logcat_codes[i] ? (1 + strlen (logcat_names[i])) : 0; + max += 11; /* ,0x%x */ + max += 1; /* \0 */ + assert (max <= sizeof (res)); + } +#endif + /* TRACE enables ALLCATS, all the others just one */ + if ((remaining & LOG_TRACE) == LOG_TRACE) + { + resp += sprintf (resp, "%strace", prefix); + remaining &= ~LOG_TRACE; + prefix = ","; + } + for (i = 0; i < sizeof (logcat_codes) / sizeof (*logcat_codes); i++) + { + if (remaining & logcat_codes[i]) + { + resp += sprintf (resp, "%s%s", prefix, logcat_names[i]); + remaining &= ~logcat_codes[i]; + prefix = ","; + } + } + if (remaining) + { + resp += sprintf (resp, "%s0x%x", prefix, (unsigned) remaining); + } + assert (resp <= res + sizeof (res)); + /* can't do default indicator: user may have specified Verbosity, in + which case EnableCategory is at default, but for these two + settings, I don't mind. */ + cfg_log (cfgst, "%s", res); +} + +static void print_configitems (struct cfgst *cfgst, void *parent, int isattr, struct cfgelem const * const cfgelem, int unchecked) +{ + const struct cfgelem *ce; + for (ce = cfgelem; ce && ce->name; ce++) + { + struct cfgst_nodekey key; + struct cfgst_node *n; + key.e = ce; + cfgst_push (cfgst, isattr, ce, parent); + if (ce->multiplicity == 1) + { + if ((n = ut_avlLookup (&cfgst_found_treedef, &cfgst->found, &key)) != NULL) + { + cfgst_push (cfgst, 0, NULL, NULL); + ce->print (cfgst, parent, ce, n->is_default); + cfgst_pop (cfgst); + } + else + { + if (unchecked && ce->print) + { + cfgst_push (cfgst, 0, NULL, NULL); + ce->print (cfgst, parent, ce, 0); + cfgst_pop (cfgst); + } + } + + if (ce->children) + print_configitems (cfgst, parent, 0, ce->children, unchecked); + if (ce->attributes) + print_configitems (cfgst, parent, 1, ce->attributes, unchecked); + } + else + { + struct config_listelem *p = cfg_deref_address (cfgst, parent, ce); + while (p) + { + cfgst_push (cfgst, 0, NULL, NULL); + if (ce->print) + { + ce->print (cfgst, p, ce, 0); + } + cfgst_pop (cfgst); + if (ce->attributes) + print_configitems (cfgst, p, 1, ce->attributes, 1); + if (ce->children) + print_configitems (cfgst, p, 0, ce->children, 1); + p = p->next; + } + } + cfgst_pop (cfgst); + } +} + +static void free_all_elements (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem) +{ + const struct cfgelem *ce; + + for (ce = cfgelem; ce && ce->name; ce++) + { + if (ce->free) + ce->free (cfgst, parent, ce); + + if (ce->multiplicity == 1) + { + if (ce->children) + free_all_elements (cfgst, parent, ce->children); + if (ce->attributes) + free_all_elements (cfgst, parent, ce->attributes); + } + else + { + struct config_listelem *p = cfg_deref_address (cfgst, parent, ce); + struct config_listelem *r ; + while (p) { + if (ce->attributes) + free_all_elements (cfgst, p, ce->attributes); + if (ce->children) + free_all_elements (cfgst, p, ce->children); + r = p; + p = p->next; + os_free(r); + } + } + } +} + +static void free_configured_elements (struct cfgst *cfgst, void *parent, struct cfgelem const * const cfgelem) +{ + const struct cfgelem *ce; + for (ce = cfgelem; ce && ce->name; ce++) + { + struct cfgst_nodekey key; + struct cfgst_node *n; + key.e = ce; + if ((n = ut_avlLookup (&cfgst_found_treedef, &cfgst->found, &key)) != NULL) + { + if (ce->free && n->count > n->failed) + ce->free (cfgst, parent, ce); + } + + if (ce->multiplicity == 1) + { + if (ce->children) + free_configured_elements (cfgst, parent, ce->children); + if (ce->attributes) + free_configured_elements (cfgst, parent, ce->attributes); + } + else + { + struct config_listelem *p = cfg_deref_address (cfgst, parent, ce); + struct config_listelem *r; + while (p) + { + if (ce->attributes) + free_all_elements (cfgst, p, ce->attributes); + if (ce->children) + free_all_elements (cfgst, p, ce->children); + r = p; + p = p->next; + os_free(r); + } + } + } +} + +static int matching_name_index (const char *name_w_aliases, const char *name) +{ + const char *ns = name_w_aliases, *p = strchr (ns, '|'); + int idx = 0; + while (p) + { + if (os_strncasecmp (ns, name, (os_uint32) (p-ns)) == 0 && name[p-ns] == 0) + { + /* ns upto the pipe symbol is a prefix of name, and name is terminated at that point */ + return idx; + } + /* If primary name followed by '||' instead of '|', aliases are non-warning */ + ns = p + 1 + (idx == 0 && p[1] == '|'); + p = strchr (ns, '|'); + idx++; + } + return (os_strcasecmp (ns, name) == 0) ? idx : -1; +} + +static int proc_elem_open (void *varg, const char *name) +{ + struct cfgst * const cfgst = varg; + const struct cfgelem *cfgelem = cfgst_tos (cfgst); + const struct cfgelem *cfg_subelem; + if (cfgelem == NULL) + { + /* Ignoring, but do track the structure so we can know when to stop ignoring */ + cfgst_push (cfgst, 0, NULL, NULL); + return 1; + } + for (cfg_subelem = cfgelem->children; + cfg_subelem && cfg_subelem->name && strcmp (cfg_subelem->name, "*") != 0; + cfg_subelem++) + { + int idx = matching_name_index (cfg_subelem->name, name); +#if WARN_DEPRECATED_ALIAS + if (idx > 0) + { + int n = (int) (strchr (cfg_subelem->name, '|') - cfg_subelem->name); + if (cfg_subelem->name[n+1] != '|') + { + cfg_warning (cfgst, "'%s': deprecated alias for '%*.*s'", name, n, n, cfg_subelem->name); + } + } +#endif + if (idx >= 0) + { + break; + } + } + if (cfg_subelem == NULL || cfg_subelem->name == NULL) + return cfg_error (cfgst, "%s: unknown element", name); + else if (strcmp (cfg_subelem->name, "*") == 0) + { + /* Push a marker that we are to ignore this part of the DOM tree */ + cfgst_push (cfgst, 0, NULL, NULL); + return 1; + } + else + { + void *parent = cfgst_parent (cfgst); + void *dynparent; + + assert (cfgelem->init || cfgelem->multiplicity == 1); /*multi-items must have an init-func */ + + if (cfg_subelem->init) + { + if (cfg_subelem->init (cfgst, parent, cfg_subelem) < 0) + return 0; + } + + if (cfg_subelem->multiplicity != 1) + dynparent = cfg_deref_address (cfgst, parent, cfg_subelem); + else + dynparent = parent; + + cfgst_push (cfgst, 0, cfg_subelem, dynparent); + return 1; + } +} + +static int proc_attr (void *varg, const char *name, const char *value) +{ + /* All attributes are processed immediately after opening the element */ + struct cfgst * const cfgst = varg; + const struct cfgelem *cfgelem = cfgst_tos (cfgst); + const struct cfgelem *cfg_attr; + if (cfgelem == NULL) + return 1; + for (cfg_attr = cfgelem->attributes; cfg_attr && cfg_attr->name; cfg_attr++) + { + if (os_strcasecmp (cfg_attr->name, name) == 0) + break; + } + if (cfg_attr == NULL || cfg_attr->name == NULL) + return cfg_error (cfgst, "%s: unknown attribute", name); + else + { + void *parent = cfgst_parent (cfgst); + int ok; + cfgst_push (cfgst, 1, cfg_attr, parent); + ok = do_update (cfgst, cfg_attr->update, parent, cfg_attr, value, 0); + cfgst_pop (cfgst); + return ok; + } +} + +static int proc_elem_data (void *varg, const char *value) +{ + struct cfgst * const cfgst = varg; + const struct cfgelem *cfgelem = cfgst_tos (cfgst); + if (cfgelem == NULL) + return 1; + if (cfgelem->update == 0) + return cfg_error (cfgst, "%s: no data expected", value); + else + { + void *parent = cfgst_parent (cfgst); + int ok; + cfgst_push (cfgst, 0, NULL, parent); + ok = do_update (cfgst, cfgelem->update, parent, cfgelem, value, 0); + cfgst_pop (cfgst); + return ok; + } +} + +static int proc_elem_close (void *varg) +{ + struct cfgst * const cfgst = varg; + const struct cfgelem * cfgelem = cfgst_tos (cfgst); + int ok = 1; + if (cfgelem && cfgelem->multiplicity != 1) + { + void *parent = cfgst_parent (cfgst); + int ok1; + ok1 = set_defaults (cfgst, parent, 1, cfgelem->attributes, 1); + ok = ok && ok1; + ok1 = set_defaults (cfgst, parent, 0, cfgelem->children, 1); + ok = ok && ok1; + } + cfgst_pop (cfgst); + return ok; +} + +static int walk_element (struct cfgst *cfgst, const char *name, u_cfElement elem); + +static int walk_attributes (struct cfgst *cfgst, u_cfElement base) +{ + c_iter iter; + u_cfNode child; + int ok = 1; + iter = u_cfElementGetAttributes (base); + child = u_cfNode (c_iterTakeFirst (iter)); + while (child) + { + u_cfAttribute attr; + c_char *name, *value; + int ok1 = 0; + name = u_cfNodeName (child); + assert (name != NULL); + assert (u_cfNodeKind (child) == V_CFATTRIBUTE); + attr = u_cfAttribute (child); + if (!u_cfAttributeStringValue (attr, &value)) + ok1 = cfg_error (cfgst, "failed to extract data"); + else + { + ok1 = proc_attr (cfgst, name, value); + os_free (value); + } + ok = ok && ok1; + os_free (name); + u_cfNodeFree (child); + child = u_cfNode (c_iterTakeFirst (iter)); + } + c_iterFree (iter); + return ok; +} + +static int walk_children (struct cfgst *cfgst, u_cfElement base) +{ + c_iter iter; + u_cfNode child; + int ok = 1; + iter = u_cfElementGetChildren (base); + child = u_cfNode (c_iterTakeFirst (iter)); + while (child) + { + c_char *child_name; + int ok1 = 0; + child_name = u_cfNodeName (child); + assert (child_name != NULL); + switch (u_cfNodeKind (child)) + { + case V_CFELEMENT: + { + u_cfElement elem = u_cfElement (child); + ok1 = walk_element (cfgst, child_name, elem); + break; + } + case V_CFDATA: + { + u_cfData data = u_cfData (child); + c_char *value; + if (!u_cfDataStringValue (data, &value)) + ok1 = cfg_error (cfgst, "failed to extract data"); + else + { + if (strspn (value, " \t\r\n") != strlen (value)) + ok1 = proc_elem_data (cfgst, value); + else + ok1 = 1; + os_free (value); + } + break; + } + default: + abort (); + } + ok = ok && ok1; + os_free (child_name); + u_cfNodeFree (child); + child = u_cfNode (c_iterTakeFirst (iter)); + } + c_iterFree (iter); + return ok; +} + +static int walk_element (struct cfgst *cfgst, const char *name, u_cfElement elem) +{ + if (!proc_elem_open (cfgst, name)) + return 0; + else + { + int ok; + ok = walk_attributes (cfgst, elem) && walk_children (cfgst, elem); + if (!proc_elem_close (cfgst)) + ok = 0; + return ok; + } +} + +static int cfgst_node_cmp (const void *va, const void *vb) +{ + return memcmp (va, vb, sizeof (struct cfgst_nodekey)); +} + +static struct cfgst * nb_config_init(/* C_STRUCT (u_participant) const * */u_participant participant, const char *servicename, nb_configuration config) +{ + /* pre: all parameters in config should be 0 */ + int ok = 1; + struct cfgst *cfgst; + u_cfElement root, elem; + c_iter iter; + int rootidx; + assert (participant != NULL); + + config->valid = 0; + + cfgst = os_malloc (sizeof (*cfgst)); + memset (cfgst, 0, sizeof (*cfgst)); + + ut_avlInit (&cfgst_found_treedef, &cfgst->found); + cfgst->cfg = config; + cfgst->servicename = servicename; + + if ((root = u_participantGetConfiguration ((u_participant) participant)) == NULL) + { + NB_ERROR ("nwbridge_config", "nb_config_init: u_participantGetConfiguration failed"); + ut_avlFree (&cfgst_found_treedef, &cfgst->found, os_free); + os_free (cfgst); + return NULL; + } + + /* Only suitable for Domain (without a attributes) and a service + with a matching name attribute */ + cfgst_push (cfgst, 0, &root_cfgelem, config); + for (rootidx = 0; root_cfgelems[rootidx].name; rootidx++) + { + const struct cfgelem *root_cfgelem = &root_cfgelems[rootidx]; + char *copy = os_strdup (root_cfgelem->name), *cursor = copy, *tok; + while ((tok = os_strsep (&cursor, "|")) != NULL) + { + iter = u_cfElementXPath (root, tok); + elem = u_cfElement (c_iterTakeFirst (iter)); + while (elem) + { + c_char *str; + if (root_cfgelem->attributes == NULL) + { + /* Domain element */ + int ok1; + char *name = u_cfNodeName (u_cfNode (elem)); + ok1 = walk_element (cfgst, name, elem); + os_free (name); + ok = ok && ok1; + } + else if (u_cfElementAttributeStringValue (elem, "name", &str)) + { + int ok1; + if (os_strcasecmp (servicename, str) != 0) + ok1 = 1; + else + { + char *name = u_cfNodeName (u_cfNode (elem)); + ok1 = walk_element (cfgst, name, elem); + os_free (name); + } + ok = ok && ok1; + os_free (str); + } + u_cfElementFree (elem); + elem = u_cfElement (c_iterTakeFirst (iter)); + } + c_iterFree (iter); + } + os_free (copy); + } + cfgst_pop (cfgst); + u_cfElementFree (root); + + /* Set defaults for everything not set that we have a default value + for, signal errors for things unset but without a default. */ + { + int ok1 = set_defaults (cfgst, cfgst->cfg, 0, root_cfgelems, 0); + ok = ok && ok1; + } + + if (!ok) + { + free_configured_elements (cfgst, cfgst->cfg, root_cfgelems); + } + + if (ok) + { + config->valid = 1; + return cfgst; + } + else + { + ut_avlFree (&cfgst_found_treedef, &cfgst->found, os_free); + os_free (cfgst); + return NULL; + } +} + +static void nb_config_print_and_free_cfgst (struct cfgst *cfgst) +{ + if (cfgst == NULL) + return; + print_configitems (cfgst, cfgst->cfg, 0, root_cfgelems, 0); + ut_avlFree (&cfgst_found_treedef, &cfgst->found, os_free); + os_free (cfgst); +} + +static void nb_config_fini (nb_configuration config) +{ + if (config->valid) + { + struct cfgst cfgst; + cfgst.cfg = config; + free_all_elements (&cfgst, cfgst.cfg, root_cfgelems); + } +} + +/***************** END DDSI-DERIVED CONFIG STUFF *****************/ + +/******************* PRIVATE FUNCTIONS *******************/ +static void nb__configurationDeinit(nb_configuration _this); + +/***************** END PRIVATE FUNCTIONS *****************/ + +nb_configuration +nb_configurationNew( + nb_service service) +{ + nb_configuration _this; + struct cfgst *cfgst; + + nb_objectIsValidKind(service, NB_OBJECT_SERVICE); + + _this = os_malloc(sizeof *_this); + + /* Super-init */ + nb__objectInit((nb_object)_this, NB_OBJECT_CONFIGURATION, (nb_objectDeinitFunc)nb__configurationDeinit); + memset (&_this->_parent + 1, 0, sizeof (*_this) - sizeof (_this->_parent)); + + /* Object-init */ + _this->valid = 0; + _this->participant = nb_serviceParticipant(service); + _this->serviceName = nb_serviceName(service); /* reference to name: service always outlives configuration object */ + + if ((cfgst = nb_config_init (_this->participant, _this->serviceName, _this)) == NULL) { + os_free (_this); + return NULL; + } else { + _this->cfgst = cfgst; + return _this; + } +} + +static void +nb__configurationDeinit( + nb_configuration _this) +{ + assert(_this); + + nb_config_fini (_this); + + /* _this->participant freed by nb_service */ + /* _this->serviceName freed by nb_service */ + + nb__objectDeinit((nb_object)_this); +} + +os_char* +nb_configurationTracingFileName( + nb_configuration _this) +{ + nb_objectIsValidKind(_this, NB_OBJECT_CONFIGURATION); + return _this->tracing.outputFileName; +} + +c_bool +nb_configurationTracingAppend( + nb_configuration _this) +{ + nb_objectIsValidKind(_this, NB_OBJECT_CONFIGURATION); + return _this->tracing.appendToFile; +} + +nb_logcat +nb_configurationTracingCategories( + nb_configuration _this) +{ + nb_objectIsValidKind(_this, NB_OBJECT_CONFIGURATION); + return _this->tracing.categories; +} + +os_duration +nb_configurationLeaseExpiryTime( + nb_configuration _this) +{ + nb_objectIsValidKind(_this, NB_OBJECT_CONFIGURATION); + return os_realToDuration(_this->serviceLease.expiry); +} + +os_duration +nb_configurationLeaseUpdateInterval( + nb_configuration _this) +{ + nb_objectIsValidKind(_this, NB_OBJECT_CONFIGURATION); + return os_durationMul(os_realToDuration(_this->serviceLease.expiry), _this->serviceLease.updateFactor); +} + +void +nb_configurationPrintStorage( + u_cfNode node) +{ + /* todo implement */ + OS_UNUSED_ARG(node); + return; +} + +void +nb_configurationPrint( + nb_configuration _this) +{ + nb_config_print_and_free_cfgst (_this->cfgst); + _this->cfgst = NULL; +} + +static unsigned count_groups (const struct nb_config_include_exclude_listelem *list) +{ + unsigned n = 0; + while (list) { + list = list->next; + n++; + } + return n; +} + +static char ** copy_groups (const struct nb_config_include_exclude_listelem *list) + __attribute_malloc__ + __attribute_returns_nonnull__; + +static char ** +copy_groups ( + const struct nb_config_include_exclude_listelem *list) +{ + const struct nb_config_include_exclude_listelem *elem; + int i; + char ** result; + + result = os_malloc ((count_groups (list) + 1) * sizeof (*result)); + i = 0; + for (elem = list; elem; elem = elem->next) { + result[i++] = os_strdup (elem->partition_topic); + } + result[i] = NULL; + + return result; +} + +char ** +nb_configurationIncludes( + nb_configuration _this) +{ + assert(_this); + + return copy_groups (_this->included_groups); +} + +char ** +nb_configurationExcludes( + nb_configuration _this) +{ + assert(_this); + + return copy_groups (_this->excluded_groups); +} diff --git a/src/services/nwbridge/code/nb_log.c b/src/services/nwbridge/code/nb_log.c new file mode 100644 index 000000000..6188178dd --- /dev/null +++ b/src/services/nwbridge/code/nb_log.c @@ -0,0 +1,214 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#include "nb__log.h" +#include "nb__thread.h" +#include "nb__configuration.h" + +#include "vortex_os.h" +#include "os_report.h" + +#define DATE_SIZE (OS_CTIME_R_BUFSIZE) +#define MAX_TIMESTAMP_LENGTH (10 + 1 + 6) +#define MAX_TID_LENGTH 15 +#define MAX_HDR_LENGTH (DATE_SIZE + 1 + MAX_TIMESTAMP_LENGTH + 1 + MAX_TID_LENGTH + 2) + +#define BUF_OFFSET MAX_HDR_LENGTH + +static void nb__logbufFlushReal(nb_thread self, + nb_logbuf lb) __nonnull_all__; + +static void nb__logbufFlush(nb_thread self, + nb_logbuf lb) __nonnull_all__; + + +static void nb_vlogb(nb_thread self, + const char *fmt, + va_list ap) __nonnull((1, 2)) + __attribute_format__((printf, 2, 0)); + +nb_logbuf +nb_logbufNew(void) +{ + nb_logbuf lb = os_malloc(sizeof *lb); + + nb_logbufInit(lb); + + return lb; +} + +void +nb_logbufInit( + nb_logbuf lb) +{ + assert(lb); + + lb->bufsz = sizeof(lb->buf); + lb->pos = BUF_OFFSET; + lb->tstamp = OS_TIMEW_INVALID; + lb->buf[lb->pos] = 0; +} + +static void +nb__logbufFlushReal( + nb_thread self, + nb_logbuf lb) +{ + nb_logConfig gc; + + nb_objectIsValidKind(self, NB_OBJECT_THREAD); + assert(lb); + + gc = nb_threadLogConfig(self); + + if (gc->tracing.file) { + char hdr[MAX_HDR_LENGTH + 1]; + char date[DATE_SIZE]; + os_int32 n; + os_uint32 tsec, tusec; + + if (OS_TIMEW_ISINVALID(lb->tstamp)) { + lb->tstamp = os_timeWGet(); + } + + tsec = (os_uint32)OS_TIMEW_GET_SECONDS(lb->tstamp); + tusec = (os_uint32)OS_TIMEW_GET_NANOSECONDS(lb->tstamp) / 1000; + lb->tstamp = OS_TIMEW_INVALID; + os_ctimeW_r(&lb->tstamp, date, DATE_SIZE); + n = snprintf(hdr, sizeof(hdr), "%s %u.%06u/%*.*s: ", date, tsec, tusec, MAX_TID_LENGTH, MAX_TID_LENGTH, nb_threadName(self)); + assert(0 < n && n <= BUF_OFFSET); + memcpy(lb->buf + BUF_OFFSET - (size_t)n, hdr, (size_t)n); + fwrite(lb->buf + BUF_OFFSET - (size_t)n, 1, lb->pos - BUF_OFFSET + (size_t)n, gc->tracing.file); + fflush(gc->tracing.file); + } + lb->pos = BUF_OFFSET; + lb->buf[lb->pos] = 0; +} + + +static void +nb__logbufFlush( + nb_thread self, + nb_logbuf lb) +{ + nb_objectIsValidKind(self, NB_OBJECT_THREAD); + assert(lb); + + if (lb->pos > BUF_OFFSET) { + if (lb->pos < (int)sizeof(lb->buf)) { + lb->buf[lb->pos++] = '\n'; + } else { + lb->buf[sizeof(lb->buf)-1] = '\n'; + } + nb__logbufFlushReal(self, lb); + } +} + +void +nb_logbufFree( + nb_thread thread, + nb_logbuf lb) +{ + nb_objectIsValidKind(thread, NB_OBJECT_THREAD); + assert(lb); + + nb__logbufFlush(thread, lb); + os_free(lb); +} + +/* LOGGING ROUTINES */ +static void +nb_vlogb( + nb_thread self, + const char *fmt, + va_list ap) +{ + int n, trunc = 0; + size_t nrem; + nb_logbuf lb; + + assert(self); + assert(fmt); + + if (*fmt == 0) { + return; + } + lb = nb_threadLogbuf(self); + + /* Copy message to log buffer */ + nrem = lb->bufsz - lb->pos; + if (nrem > 0) { + n = os_vsnprintf(lb->buf + lb->pos, nrem, fmt, ap); + if (n >= 0 && (size_t) n < nrem) { + lb->pos += (size_t) n; + } else { + lb->pos += nrem; + trunc = 1; + } + if (trunc) { + static const char msg[] = "(trunc)\n"; + const size_t msglen = sizeof(msg) - 1; + assert(lb->pos <= lb->bufsz); + assert(lb->pos >= msglen); + memcpy(lb->buf + lb->pos - msglen, msg, msglen); + } + } + + /* Flush on newline */ + if (fmt[strlen(fmt) - 1] == '\n') { + nb__logbufFlushReal(self, lb); + } +} + +int +nb_log( + nb_logcat cat, + const char *fmt, ...) +{ + nb_thread self = nb_threadLookup(); + + if(self){ + nb_logConfig gc = nb_threadLogConfig(self); + + if (gc->tracing.categories & cat) { + va_list ap; + va_start(ap, fmt); + nb_vlogb(self, fmt, ap); + va_end(ap); + } + } + return 0; +} + +int +nb_trace (const char *fmt, ...) +{ + nb_thread self = nb_threadLookup(); + + if(self){ + nb_logConfig gc = nb_threadLogConfig(self); + + if (gc->tracing.categories & LOG_TRACE) { + va_list ap; + va_start(ap, fmt); + nb_vlogb(self, fmt, ap); + va_end(ap); + } + } + + return 0; +} diff --git a/src/services/nwbridge/code/nb_object.c b/src/services/nwbridge/code/nb_object.c new file mode 100644 index 000000000..3e79c8b88 --- /dev/null +++ b/src/services/nwbridge/code/nb_object.c @@ -0,0 +1,339 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#include "nb__object.h" +#include "nb__util.h" +#include "nb__log.h" + +#include "os_heap.h" +#include "os_defs.h" +#include "os_abstract.h" +#include "os_atomics.h" +#include + +#include "v_state.h" /* for status flags */ +#include "v_dataReaderSample.h" + +#include "u_writer.h" + +void +nb__objectInit( + nb_object _this, + nb_objectKind kind, + nb_objectDeinitFunc deinit) +{ + assert(_this); + assert(NB_OBJECT_VALIDKIND(kind)); + assert(deinit); + +#ifndef NDEBUG + _this->confidence = NB_OBJECT_CONFIDENCE; +#endif /* NDEBUG */ + pa_st32(&_this->refCount, 1); + _this->deinit = deinit; + _this->kind = kind; + +} + +void +nb__objectDeinit( + nb_object _this) +{ +#ifndef NDEBUG + assert(nb__objectIsValid(_this)); + _this->confidence = 0; +#else + OS_UNUSED_ARG(_this); +#endif /* NDEBUG */ +} + +nb_objectKind +nb__objectKind ( + nb_object _this) +{ + assert(nb__objectIsValid(_this)); + return _this->kind; +} + +void +nb__objectSetDeinit( + nb_object _this, + nb_objectDeinitFunc deinit) +{ + assert(nb__objectIsValid(_this)); + + _this->deinit = deinit; +} + +nb_object +nb__objectKeep( + nb_object _this) +{ + assert(nb__objectIsValid(_this)); + + pa_inc32(&(_this->refCount)); + + return _this; +} + +void +nb__objectFree( + nb_object _this) +{ + if(_this){ + os_uint32 refCount; + + assert(nb__objectIsValid(_this)); + + refCount = pa_dec32_nv(&(_this->refCount)); + if(refCount == 0) { + assert(_this->deinit); + _this->deinit(_this); + os_free(_this); + } + } +} + +#ifndef NDEBUG +c_bool +nb__objectIsValid( + nb_object _this) +{ + if(!_this) return FALSE; + if(!(_this->confidence == NB_OBJECT_CONFIDENCE)) return FALSE; + if(!NB_OBJECT_VALIDKIND(_this->kind)) return FALSE; + return TRUE; +} + +c_bool +nb__objectIsValidKind( + nb_object _this, + nb_objectKind kind) +{ + if(!nb__objectIsValid(_this)) return FALSE; + if(nb__objectKind(_this) != kind) return FALSE; + return TRUE; +} + +#endif /* NDEBUG */ + +const char* +nb__objectKindImage( + nb_object _this) +{ + const char* image; + + assert(nb__objectIsValid(_this)); + +#define _NB_IMAGE_STR_(k) ((char*)((os_address)(#k) + strlen("NB_OBJECT_"))) +#define _NB_IMAGE_STR_CASE(k) case (k): image = _NB_IMAGE_STR_(k); break; + switch(_this->kind) { + _NB_IMAGE_STR_CASE(NB_OBJECT_SERVICE); + _NB_IMAGE_STR_CASE(NB_OBJECT_THREAD); + _NB_IMAGE_STR_CASE(NB_OBJECT_LOGBUF); + _NB_IMAGE_STR_CASE(NB_OBJECT_CONFIGURATION); + _NB_IMAGE_STR_CASE(NB_OBJECT_GROUP); + _NB_IMAGE_STR_CASE(NB_TOPIC_OBJECT_DCPS_TOPIC); + _NB_IMAGE_STR_CASE(NB_TOPIC_OBJECT_DCPS_SUBSCRIPTION); + _NB_IMAGE_STR_CASE(NB_TOPIC_OBJECT_CM_READER); + _NB_IMAGE_STR_CASE(NB_TOPIC_OBJECT_DCPS_PUBLICATION); + default: + image = "(invalid kind)"; + break; + } +#undef _NB_IMAGE_STR_CASE +#undef _NB_IMAGE_STR_ + return image; +} + +void +nb__topicObjectInit ( + nb_topicObject _this, + nb_objectKind kind, + nb_objectDeinitFunc deinit, + const c_char * name, + nb_topicObjectCopyOutFunc copyOut, + nb_topicObjectCopyInFunc copyIn) +{ + /* super-init */ + nb__objectInit(nb_object(_this), kind, deinit); + + assert(name); + + _this->name = os_strdup(name); + _this->state = 0; + _this->writeTime = OS_TIMEW_INVALID; + _this->copyOut = copyOut; + _this->copyIn = copyIn; +} + +void +nb__topicObjectDeinit ( + nb_object _this) +{ + os_free(nb_topicObject(_this)->name); + + /* super-deinit */ + nb__objectDeinit(_this); +} + +u_result +nb_topicObjectCopyOut( + nb_topicObject _this, + const void * from) +{ + u_result result = U_RESULT_UNSUPPORTED; + + assert(_this); + + if (_this->copyOut) { + result = _this->copyOut(_this, from); + } + + return result; +} + +v_copyin_result +nb_topicObjectCopyIn( + c_type type, + const void *from, /* nb_topicObject */ + void *to) +{ + nb_topicObject _this = nb_topicObject(from); + v_copyin_result result = V_COPYIN_RESULT_OK; + + assert(_this); + assert(from); + assert(to); + + if (_this->copyIn) { + result = _this->copyIn(type, _this, to); + } + + if(!V_COPYIN_RESULT_IS_OK(result)){ + NB_TRACE(("nb_topicObjectCopyIn for %s failed\n", nb_objectKindImage(_this))); + } + + return result; +} + +u_result +nb_topicObjectWrite( + u_writer writer, + nb_topicObject _this) +{ + u_result result = U_RESULT_UNSUPPORTED; + os_timeW timestamp; + + assert(writer); + nb_objectIsValid(_this); + + timestamp = _this->writeTime; + + if(v_stateTest(_this->state, L_REGISTER)){ + result = u_writerRegisterInstance( + writer, + nb_topicObjectCopyIn, + _this, + timestamp, + U_INSTANCEHANDLE_NIL); + } else if(v_stateTest(_this->state, L_WRITE) && v_stateTest(_this->state, L_DISPOSED)){ + result = u_writerWriteDispose( + writer, + nb_topicObjectCopyIn, + _this, + timestamp, + U_INSTANCEHANDLE_NIL); + } else if(v_stateTest(_this->state, L_WRITE)) { + result = u_writerWrite( + writer, + nb_topicObjectCopyIn, + _this, + timestamp, + U_INSTANCEHANDLE_NIL); + } else if(v_stateTest(_this->state, L_DISPOSED)) { + result = u_writerDispose( + writer, + nb_topicObjectCopyIn, + _this, + timestamp, + U_INSTANCEHANDLE_NIL); + } + + return result; +} + +const c_char * +nb_topicObjectName( + nb_topicObject _this) +{ + nb_objectIsValid(_this); + + assert(_this->name); + return _this->name; +} + +v_state +nb_topicObjectState( + nb_topicObject _this) +{ + nb_objectIsValid(_this); + + return _this->state; +} + +v_actionResult +nb_topicObjectReaderAction( + c_object o, + c_voidp copyArg, /* c_iter * */ + nb_topicObjectAllocFunc allocFunc) +{ + nb_topicObject to; + v_actionResult result = 0; + + assert(allocFunc); + + if(o != NULL){ + c_iter *iter; + v_dataReaderSample s = v_dataReaderSample(o); + v_message message = v_dataReaderSampleMessage(s); + const void * from = C_DISPLACE (message, C_MAXALIGNSIZE(sizeof(*message))); + + iter = (c_iter*)copyArg; + assert(iter); + + v_actionResultSet(result, V_PROCEED); + to = allocFunc(); + to->state = v_nodeState(message); + to->writeTime = message->writeTime; + + nb_topicObjectCopyOut(to, from); + + *iter = c_iterAppend(*iter, to); + } + return result; +} + +#ifndef NDEBUG +void +nb_topicObjectFree ( + nb_topicObject _this) +{ + /* TODO: check proper inheritance? */ + nb_objectFree(_this); +} +#endif diff --git a/src/services/nwbridge/code/nb_service.c b/src/services/nwbridge/code/nb_service.c new file mode 100644 index 000000000..2460f050c --- /dev/null +++ b/src/services/nwbridge/code/nb_service.c @@ -0,0 +1,2152 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +/* abstraction layer includes */ +#include "vortex_os.h" +#include "os_report.h" +#include "os_version.h" +#include "os_gitrev.h" +#include "os_atomics.h" + +/* User layer includes */ +#include "u_user.h" +#include "u_group.h" +#include "u_nwbridge.h" +#include "u_service.h" + +/* nwbridge service includes */ +#include "nb__service.h" +#include "nb__topic.h" +#include "nb__configuration.h" +#include "nb__thread.h" +#include "nb__util.h" +#include "nb__log.h" + +#include "v_service.h" /* for service state */ +#include "v_builtin.h" /* for built-in partition and topic names */ +#include "v_entity.h" +#include "v_event.h" +#include "v_kernel.h" +#include "v_partition.h" +#include "v_topic.h" +#include "v_state.h" +#include "v_dataReaderSample.h" +#include "v_groupSet.h" + +#include "ut_collection.h" + +/* FIXME: built-in topics for Subscriber and Publisher entities are specific to OpenSplice, + and we therefore can't really rely on their presence. These two exist to "document" this */ +static const c_bool requireContainingEntities = FALSE; + +/* When toggled to 1, an exit of the process was requested, meaning all + * networkings within the process must terminate. */ +static int nb_proc_must_exit; + +typedef u_result (*nb__serviceHandleTopicObjectFunc)(nb_service _this, nb_topicObject top) __nonnull_all__; + +struct nb_serviceInterestTopic { + const c_char *topicName; + u_dataReader reader; + u_dataReaderAction action; + c_iter toHandle; + nb__serviceHandleTopicObjectFunc handleFunc; + u_writer writer; + c_ulong subscriptionsMatched; + c_bool alwaysForward; + ut_table handled; +}; + +#define NB_SERVICE_NUM_ENTITIES sizeof(struct nb_serviceInterestTopics)/sizeof(struct nb_serviceInterestTopic) + + + +C_STRUCT(nb_service) +{ + C_EXTENDS(nb_object); + os_char* name; + u_service service; + u_subscriber subscriber; + u_publisher publisher; + u_writer statusWriter; + volatile int terminate; + os_signalHandlerExitRequestHandle erh; + os_signalHandlerExceptionHandle eh; + nb_configuration config; + char ** includes; + char ** excludes; + os_mutex configLock; + u_waitset ws; + nb_thread leaseRenewalThr; + struct { + u_topic serviceStatus; + } topics; + struct nb_serviceInterest { + u_subscriber subscriber; /* Used to subscribe to __BUILT-IN PARTITION__ */ + u_publisher publisher; + union { + struct nb_serviceInterestTopics { + struct nb_serviceInterestTopic DCPSTopic; + struct nb_serviceInterestTopic DCPSParticipant; + struct nb_serviceInterestTopic CMParticipant; + struct nb_serviceInterestTopic CMPublisher; + struct nb_serviceInterestTopic CMDataWriter; + struct nb_serviceInterestTopic DCPSPublication; + struct nb_serviceInterestTopic CMSubscriber; + struct nb_serviceInterestTopic CMDataReader; + struct nb_serviceInterestTopic DCPSSubscription; + } named; + struct nb_serviceInterestTopic array[NB_SERVICE_NUM_ENTITIES]; + } entities; + } interest; /* Initialized by nb__serviceInterestInit */ +}; + +#define NB_TOPIC_OBJECT_DCPS_SUBSCRIPTION_INDEX 0 +#define NB_TOPIC_OBJECT_CM_READER_INDEX 1 +#define NB_TOPIC_OBJECT_CM_SUBSCRIBER_INDEX 2 +#define NB_TOPIC_OBJECT_DCPS_PUBLICATION_INDEX 3 +#define NB_TOPIC_OBJECT_CM_WRITER_INDEX 4 +#define NB_TOPIC_OBJECT_CM_PUBLISHER_INDEX 5 +#define NB_TOPIC_OBJECT_DCPS_PARTICIPANT_INDEX 6 +#define NB_TOPIC_OBJECT_CM_PARTICIPANT_INDEX 7 +#define NB_TOPIC_OBJECT_DCPS_TOPIC_INDEX 8 + +#define NB_TOPIC_INDEX(top) top##_INDEX + + +/***************** PRIVATE FUNCTIONS *****************/ +/******************** NB_SERVICE *********************/ +static nb_service nb__serviceNew(const os_char* uri, + const os_char* serviceName) + __nonnull((2)) + __attribute_malloc__; + +static void nb__serviceDeinit(nb_service _this) __nonnull_all__; + +/* Utility functions */ +static void nb__serviceLoadMetaData(v_public vpublic, + c_voidp arg /* c_bool* */) + __nonnull_all__; + +static void nb__serviceWatchSpliced(v_serviceStateKind state, + c_voidp userData) + __nonnull_all__; + +static os_result nb__serviceOpenTracingFile(nb_service _this) + __nonnull_all__; + +static void* nb__serviceUpdateLease(c_voidp args) + __nonnull_all__; + +static v_serviceStateKind nb__ServiceStateToKernelServiceStateKind(ServiceState state) + __attribute_const__; + +static void nb__serviceMain(nb_service _this) __nonnull_all__; + +static void nb__serviceCreateGroups(nb_service _this, + const char * const * partitions, + c_ulong len, + const char * topicName, + const v_builtinTopicKey *pubkey) + __nonnull((1,4,5)); + +static u_result nb__serviceHandleServiceInterestTopic(const char *type, + const struct nb_serviceInterestTopic *top, + const v_builtinTopicKey *key, + nb_topicObject toHandle) + __nonnull_all__; + +/* nb__serviceHandleTopicObjectFunc signature wrapper */ +static u_result nb__serviceHandleDcpsTopicFunc(nb_service _this, nb_topicObject top) __nonnull_all__; +static u_result nb__serviceHandleDcpsTopic(nb_service _this, nb_dcpsTopic top) __nonnull_all__; + +/* nb__serviceHandleTopicObjectFunc signature wrapper */ +static u_result nb__serviceHandleDcpsParticipantFunc(nb_service _this, nb_topicObject top) __nonnull_all__; +static u_result nb__serviceHandleDcpsParticipant(nb_service _this, nb_dcpsParticipant part) __nonnull_all__; + +/* nb__serviceHandleTopicObjectFunc signature wrapper */ +static u_result nb__serviceHandleCmParticipantFunc(nb_service _this, nb_topicObject top) __nonnull_all__; +static u_result nb__serviceHandleCmParticipant(nb_service _this, nb_cmParticipant cmp) __nonnull_all__; + +/* nb__serviceHandleTopicObjectFunc signature wrapper */ +static u_result nb__serviceHandleDcpsPublicationFunc(nb_service _this, nb_topicObject top) __nonnull_all__; +static u_result nb__serviceHandleDcpsPublication(nb_service _this, nb_dcpsPublication pub) __nonnull_all__; + +/* nb__serviceHandleTopicObjectFunc signature wrapper */ +static u_result nb__serviceHandleCmWriterFunc(nb_service _this, nb_topicObject top) __nonnull_all__; +static u_result nb__serviceHandleCmWriter(nb_service _this, nb_cmWriter toHandle) __nonnull_all__; + +/* nb__serviceHandleTopicObjectFunc signature wrapper */ +static u_result nb__serviceHandleDcpsSubscriptionFunc(nb_service _this, nb_topicObject top) __nonnull_all__; +static u_result nb__serviceHandleDcpsSubscription(nb_service _this, nb_dcpsSubscription sub) __nonnull_all__; + +/* nb__serviceHandleTopicObjectFunc signature wrapper */ +static u_result nb__serviceHandleCmReaderFunc(nb_service _this, nb_topicObject top) __nonnull_all__; +static u_result nb__serviceHandleCmReader(nb_service _this, nb_cmReader cmr) __nonnull_all__; + +/* nb__serviceHandleTopicObjectFunc signature wrapper */ +static u_result nb__serviceHandleCmPublisherFunc(nb_service _this, nb_topicObject top) __nonnull_all__; +static u_result nb__serviceHandleCmPublisher(nb_service _this, nb_cmPublisher cmp) __nonnull_all__; + +/* nb__serviceHandleTopicObjectFunc signature wrapper */ +static u_result nb__serviceHandleCmSubscriberFunc(nb_service _this, nb_topicObject top) __nonnull_all__; +static u_result nb__serviceHandleCmSubscriber(nb_service _this, nb_cmSubscriber cms) __nonnull_all__; + +static void nb__serviceHandleBuiltinTopics (nb_service _this) __nonnull_all__; + +static c_bool ServiceStatusCopyIn( + c_type type, + struct ServiceStatus *data, + struct ServiceStatus *to) + __nonnull_all__; + +static u_topic nb__serviceInterestFindTopic(u_participant participant, + const c_char * name) + __nonnull_all__; + +static u_result nb__serviceInterestTopicInit( + struct nb_serviceInterestTopic *interest, + u_participant participant, + u_waitset waitset, + u_publisher publisher, + u_writerQos writerQos, + u_subscriber subscriber, + u_readerQos readerQos) __nonnull_all__; + +static void nb__serviceInterestTopicDeinit( + struct nb_serviceInterestTopic *interest, + u_waitset waitset) __nonnull_all__; + +static os_result nb__serviceInterestInit(struct nb_serviceInterest* interest, + u_participant participant, + u_waitset waitset) __nonnull_all__; + +static os_result nb__exceptionHandler(void *callingThreadContext, + void * arg); + +static v_result nb__serviceWriterGetMatchedStatus( + c_voidp info /* struct v_topicMatchInfo* */, + c_voidp arg /* c_bool* */) __nonnull_all__; + +static const char * const * nb__serviceIncludes(nb_service _this) + __nonnull_all__ + __attribute_returns_nonnull__; + +static const char * const * nb__serviceExcludes(nb_service _this) + __nonnull_all__ + __attribute_returns_nonnull__; + +static void nb__serviceInterestTopicObjectFreeFunc(void *o, void *arg); + +/***************** END PRIVATE FUNCTIONS *****************/ + +static u_result +nb__serviceHandleServiceInterestTopic( + const char *type, + const struct nb_serviceInterestTopic *top, + const v_builtinTopicKey *key, + nb_topicObject toHandle) +{ + v_builtinTopicKey *k; + v_state s; + u_result uresult = U_RESULT_OK; + void *removed; + + s = nb_topicObjectState(toHandle); + k = (v_builtinTopicKey *) /* discard const */ key; + + if(v_stateTest(s, L_DISPOSED)) { + /* It is not guaranteed that a builtin-topic stored in the collection + * has been written yet. This means that potentially a dispose is + * sent for a topic that was never written, but this shouldn't hurt. */ + if((removed = ut_remove((ut_collection)top->handled, k)) != NULL){ + NB_TRACE(("Removed %s %s={key="NB_KEYFMT"}\n", + nb_topicObjectName(toHandle), type, + v_gidSystemId(*k), v_gidLocalId(*k))); + nb_objectFree(removed); + + /* Forward the dispose */ + uresult = nb_topicObjectWrite(top->writer, toHandle); + } + } else if(v_stateTest(s, L_WRITE)){ + if(ut_tableInsert(top->handled, k, toHandle)){ + NB_TRACE(("Stored %s %s={key="NB_KEYFMT"}\n", + nb_topicObjectName(toHandle), type, + v_gidSystemId(*k), v_gidLocalId(*k))); + nb_objectKeep(toHandle); + + if (top->alwaysForward) { + NB_TRACE(("Forwarding %s %s={key="NB_KEYFMT"}\n", + nb_topicObjectName(toHandle), type, + v_gidSystemId(*k), v_gidLocalId(*k))); + uresult = nb_topicObjectWrite(top->writer, toHandle); + } + } + } + + return uresult; +} + + +static u_result nb__serviceHandleDcpsTopicFunc(nb_service _this, nb_topicObject top) { return nb__serviceHandleDcpsTopic(_this, nb_dcpsTopic(top)); } + +static u_result +nb__serviceHandleDcpsTopic( + nb_service _this, + nb_dcpsTopic toHandle) +{ + u_result ures; + u_writer writer; + const char * const partitions[] = {"*"}; + v_state s; + + nb_objectIsValidKind(_this, NB_OBJECT_SERVICE); + nb_objectIsValidKind(toHandle, NB_TOPIC_OBJECT_DCPS_TOPIC); + + s = nb_topicObjectState(nb_topicObject(toHandle)); + writer = _this->interest.entities.named.DCPSTopic.writer; + + if(v_stateTest(s, L_VALIDDATA)){ + if(nb_match(partitions, 1, nb_dcpsTopicTopicName(toHandle), nb__serviceIncludes(_this), nb__serviceExcludes(_this))){ + /* Currently all DCPSTopics that potentially match a filter are forwarded, + * so no need to store them in _this->interest.entities.named.DCPSTopic.handled + * for now. */ + ures = nb_topicObjectWrite(writer, nb_topicObject(toHandle)); + NB_TRACE(("Written (%s) %s for topic '%s'\n", + u_resultImage(ures), + nb_topicObjectName(nb_topicObject(toHandle)), + nb_dcpsTopicTopicName(toHandle))); + assert(ures == U_RESULT_OK); + } else { + NB_TRACE(("Ignored %s for topic '%s'\n", + nb_topicObjectName(nb_topicObject(toHandle)), + nb_dcpsTopicTopicName(toHandle))); + + ures = U_RESULT_OK; + } + } else { + ures = nb_topicObjectWrite(writer, nb_topicObject(toHandle)); + assert(ures == U_RESULT_OK); + } + + + return ures; +} + +static u_result nb__serviceHandleDcpsParticipantFunc(nb_service _this, nb_topicObject top) { return nb__serviceHandleDcpsParticipant(_this, nb_dcpsParticipant(top)); } + +static u_result +nb__serviceHandleDcpsParticipant( + nb_service _this, + nb_dcpsParticipant toHandle) +{ + u_result ur; + + nb_objectIsValidKind(_this, NB_OBJECT_SERVICE); + nb_objectIsValidKind(toHandle, NB_TOPIC_OBJECT_DCPS_PARTICIPANT); + + ur = nb__serviceHandleServiceInterestTopic( + "nb_dcpsParticipant", + &_this->interest.entities.named.DCPSParticipant, + nb_dcpsParticipantKey(toHandle), + nb_topicObject(toHandle)); + + return ur; +} + +static u_result nb__serviceHandleCmParticipantFunc(nb_service _this, nb_topicObject top) { return nb__serviceHandleCmParticipant(_this, nb_cmParticipant(top)); } + +static u_result +nb__serviceHandleCmParticipant( + nb_service _this, + nb_cmParticipant toHandle) +{ + u_result ur; + + nb_objectIsValidKind(_this, NB_OBJECT_SERVICE); + nb_objectIsValidKind(toHandle, NB_TOPIC_OBJECT_CM_PARTICIPANT); + + ur = nb__serviceHandleServiceInterestTopic( + "nb_cmParticipant", + &_this->interest.entities.named.CMParticipant, + nb_cmParticipantKey(toHandle), + nb_topicObject(toHandle)); + + return ur; +} + +static u_result nb__serviceHandleDcpsPublicationFunc(nb_service _this, nb_topicObject top) { return nb__serviceHandleDcpsPublication(_this, nb_dcpsPublication(top)); } + +static u_result +nb__serviceHandleDcpsPublication( + nb_service _this, + nb_dcpsPublication pub) +{ + u_result ures; + u_topic topic; + const char * const *partitions; + c_ulong len; + void *entry; + nb_dcpsParticipant part; + nb_cmParticipant cmpart; + nb_cmPublisher cmp; + nb_cmWriter cmw; + u_writer writer; + const v_builtinTopicKey *key; + const v_builtinTopicKey *pubkey; + const char * topObjName; + v_state s; + void * removed; + nb_dcpsPublication oldPub; + + nb_objectIsValidKind(_this, NB_OBJECT_SERVICE); + nb_objectIsValidKind(pub, NB_TOPIC_OBJECT_DCPS_PUBLICATION); + + s = nb_topicObjectState(nb_topicObject(pub)); + pubkey = nb_dcpsPublicationKey(pub); + topObjName = nb_topicObjectName(nb_topicObject(pub)); + + if(v_stateTest(s, L_DISPOSED)){ + removed = ut_remove((ut_collection)_this->interest.entities.named.DCPSPublication.handled, (void *) /* remove const */ pubkey); + if(removed){ + oldPub = nb_dcpsPublication(removed); + NB_TRACE(("Removed %s nb_dcpsPublication={key="NB_KEYFMT"}\n", + topObjName, v_gidSystemId(*pubkey), v_gidLocalId(*pubkey))); + if(nb_dcpsPublicationGetInterested(oldPub)){ + /* Forward the dispose */ + ures = nb_topicObjectWrite(_this->interest.entities.named.DCPSPublication.writer, nb_topicObject(pub)); + if(ures != U_RESULT_OK) NB_TRACE(("nb_topicObjectWrite returned %s for %s\n", u_resultImage(ures), nb_topicObjectName(nb_topicObject(pub)))); + } + nb_objectFree(oldPub); + } + return U_RESULT_OK; + } else if(v_stateTest(s, L_WRITE)){ + const char * topicName = nb_dcpsPublicationTopicName(pub); + + /* Set interest */ + nb_dcpsPublicationSetInterested(pub, nb__serviceIncludes(_this), nb__serviceExcludes(_this)); + + if(nb_dcpsPublicationGetInterested(pub)){ + /* Check pre-conditions */ + NB_TRACE(("Checking pre-conditions for nb_dcpsPublication={key="NB_KEYFMT"}" + " for forwarding of %s for topic \'%s\'\n", + v_gidSystemId(*pubkey), v_gidLocalId(*pubkey), + topObjName, topicName + )); + + key = nb_dcpsPublicationParticipantKey(pub); + entry = ut_get((ut_collection)_this->interest.entities.named.DCPSParticipant.handled, (void*) /* discard const */ key); + if(entry == NULL && requireContainingEntities){ + NB_TRACE(("nb_dcpsPublication={key="NB_KEYFMT"}: Can't find nb_dcpsParticipant={" + "key="NB_KEYFMT"} needed for forwarding of %s for topic '%s' yet\n", + v_gidSystemId(*pubkey), v_gidLocalId(*pubkey), + v_gidSystemId(*key), v_gidLocalId(*key), + topObjName, topicName + )); + goto err_lookup; + } + part = entry ? nb_dcpsParticipant(entry) : NULL; + + key = nb_dcpsPublicationParticipantKey(pub); + entry = ut_get((ut_collection)_this->interest.entities.named.CMParticipant.handled, (void*) /* discard const */ key); + if(entry == NULL && requireContainingEntities){ + NB_TRACE(("nb_dcpsPublication={key="NB_KEYFMT"}: Can't find nb_cmParticipant={" + "key="NB_KEYFMT"} needed for forwarding of %s for topic '%s' yet\n", + v_gidSystemId(*pubkey), v_gidLocalId(*pubkey), + v_gidSystemId(*key), v_gidLocalId(*key), + topObjName, topicName + )); + goto err_lookup; + } + cmpart = entry ? nb_cmParticipant(entry) : NULL; + + key = nb_dcpsPublicationKey(pub); + entry = ut_get((ut_collection)_this->interest.entities.named.CMDataWriter.handled, (void*) /* discard const */ key); + if(entry == NULL){ + NB_TRACE(("nb_dcpsPublication={key="NB_KEYFMT"}: Can't find nb_cmWriter={" + "key="NB_KEYFMT"} needed for forwarding of %s for topic '%s' yet\n", + v_gidSystemId(*pubkey), v_gidLocalId(*pubkey), + v_gidSystemId(*key), v_gidLocalId(*key), + topObjName, topicName + )); + goto err_lookup; + } + cmw = entry ? nb_cmWriter(entry) : NULL; + + if (cmw == NULL) { + cmp = NULL; + } else { + key = nb_cmWriterPublisherKey(cmw); + entry = ut_get((ut_collection)_this->interest.entities.named.CMPublisher.handled, (void*) /* discard const */ key); + if(entry == NULL && requireContainingEntities){ + NB_TRACE(("nb_dcpsPublication={key="NB_KEYFMT"}: Can't find nb_cmPublisher={" + "key="NB_KEYFMT"} needed for forwarding of %s for topic '%s' yet\n", + v_gidSystemId(*pubkey), v_gidLocalId(*pubkey), + v_gidSystemId(*key), v_gidLocalId(*key), + topObjName, topicName + )); + goto err_lookup; + } + cmp = entry ? nb_cmPublisher(entry) : NULL; + } + + if((topic = nb__serviceInterestFindTopic(nb_serviceParticipant(_this), topicName)) == NULL){ + NB_TRACE(("nb_dcpsPublication={key="NB_KEYFMT"}: Can't find u_topic '%s'\n", + v_gidSystemId(*pubkey), v_gidLocalId(*pubkey), + topicName + )); + goto err_lookup; + } + + NB_TRACE(("nb_dcpsPublication={key="NB_KEYFMT"}: Found all entities needed to forward %s for topic '%s'\n", + v_gidSystemId(*pubkey), v_gidLocalId(*pubkey), + topObjName, topicName + )); + + /* The topic-definition is available, so for all absolute partition- + * expressions u_groupNew should succeed. */ + partitions = nb_dcpsPublicationPartitions(pub, &len); + nb__serviceCreateGroups(_this, partitions, len, topicName, pubkey); + + if (!_this->interest.entities.named.DCPSParticipant.alwaysForward && part != NULL) { + writer = _this->interest.entities.named.DCPSParticipant.writer; + ures = nb_topicObjectWrite(writer, nb_topicObject(part)); + if(ures != U_RESULT_OK) NB_TRACE(("nb_topicObjectWrite returned %s for %s\n", u_resultImage(ures), nb_topicObjectName(nb_topicObject(part)))); + } + + if (!_this->interest.entities.named.CMParticipant.alwaysForward && cmpart != NULL) { + writer = _this->interest.entities.named.CMParticipant.writer; + ures = nb_topicObjectWrite(writer, nb_topicObject(cmpart)); + if(ures != U_RESULT_OK) NB_TRACE(("nb_topicObjectWrite returned %s for %s\n", u_resultImage(ures), nb_topicObjectName(nb_topicObject(cmpart)))); + } + + if (!_this->interest.entities.named.CMDataWriter.alwaysForward && cmw != NULL) { + writer = _this->interest.entities.named.CMDataWriter.writer; + ures = nb_topicObjectWrite(writer, nb_topicObject(cmw)); + if(ures != U_RESULT_OK) NB_TRACE(("nb_topicObjectWrite returned %s for %s\n", u_resultImage(ures), nb_topicObjectName(nb_topicObject(cmw)))); + } + + if (!_this->interest.entities.named.CMPublisher.alwaysForward && cmp != NULL) { + writer = _this->interest.entities.named.CMPublisher.writer; + ures = nb_topicObjectWrite(writer, nb_topicObject(cmp)); + if(ures != U_RESULT_OK) NB_TRACE(("nb_topicObjectWrite returned %s for %s\n", u_resultImage(ures), nb_topicObjectName(nb_topicObject(cmp)))); + } + + writer = _this->interest.entities.named.DCPSPublication.writer; + ures = nb_topicObjectWrite(writer, nb_topicObject(pub)); + if(ures != U_RESULT_OK) NB_TRACE(("nb_topicObjectWrite returned %s for %s\n", u_resultImage(ures), nb_topicObjectName(nb_topicObject(pub)))); + + (void)u_objectFree(u_object(topic)); + } + + key = nb_dcpsPublicationKey(pub); + if(ut_tableInsert(_this->interest.entities.named.DCPSPublication.handled, (void*) /* discard const */ key, pub)){ + NB_TRACE(("nb_dcpsPublication={key="NB_KEYFMT"}: Stored and processed %s nb_dcpsPublication={key="NB_KEYFMT", topic_name=\"%s\"}\n", + v_gidSystemId(*pubkey), v_gidLocalId(*pubkey), + topObjName, + v_gidSystemId(*pubkey), v_gidLocalId(*pubkey), + topicName + )); + nb_objectKeep(pub); + } else { + /* An update to an existing publication is not stored, just forwarded. */ + NB_TRACE(("nb_dcpsPublication={key="NB_KEYFMT"}: Processed %s nb_dcpsPublication={key="NB_KEYFMT", topic_name=\"%s\"}\n", + v_gidSystemId(*pubkey), v_gidLocalId(*pubkey), + topObjName, + v_gidSystemId(*pubkey), v_gidLocalId(*pubkey), + topicName + )); + } + return U_RESULT_OK; + + /* Error handling */ + err_lookup: + NB_TRACE(("nb_dcpsPublication={key="NB_KEYFMT"}: Handling of %s deferred for nb_dcpsPublication={key="NB_KEYFMT", topic_name=\"%s\"}\n", + v_gidSystemId(*pubkey), v_gidLocalId(*pubkey), + topObjName, + v_gidSystemId(*pubkey), v_gidLocalId(*pubkey), + topicName + )); + return U_RESULT_TIMEOUT; + } else { + return U_RESULT_OK; + } +} + +static u_result nb__serviceHandleCmWriterFunc(nb_service _this, nb_topicObject top) { return nb__serviceHandleCmWriter(_this, nb_cmWriter(top)); } + +static u_result +nb__serviceHandleCmWriter( + nb_service _this, + nb_cmWriter toHandle) +{ + u_result ur; + + nb_objectIsValidKind(_this, NB_OBJECT_SERVICE); + nb_objectIsValidKind(toHandle, NB_TOPIC_OBJECT_CM_WRITER); + + ur = nb__serviceHandleServiceInterestTopic( + "nb_cmWriter", + &_this->interest.entities.named.CMDataWriter, + nb_cmWriterKey(toHandle), + nb_topicObject(toHandle)); + + return ur; +} + +static u_result nb__serviceHandleDcpsSubscriptionFunc(nb_service _this, nb_topicObject top) { return nb__serviceHandleDcpsSubscription(_this, nb_dcpsSubscription(top)); } + +static u_result +nb__serviceHandleDcpsSubscription( + nb_service _this, + nb_dcpsSubscription sub) +{ + u_result ures; + u_topic topic; + const char * const *partitions; + c_ulong len; + void *entry; + nb_dcpsParticipant part; + nb_cmParticipant cmpart; + nb_cmSubscriber cms; + nb_cmReader cmr; + u_writer writer; + const v_builtinTopicKey *key; + const v_builtinTopicKey *subkey; + const char * topObjName; + v_state s; + void * removed; + nb_dcpsSubscription oldSub; + + s = nb_topicObjectState(nb_topicObject(sub)); + topObjName = nb_topicObjectName(nb_topicObject(sub)); + subkey = nb_dcpsSubscriptionKey(sub); + + nb_objectIsValidKind(_this, NB_OBJECT_SERVICE); + nb_objectIsValidKind(sub, NB_TOPIC_OBJECT_DCPS_SUBSCRIPTION); + + if(v_stateTest(s, L_DISPOSED)){ + removed = ut_remove((ut_collection)_this->interest.entities.named.DCPSSubscription.handled, (void *) /* remove const */ subkey); + if(removed){ + oldSub = nb_dcpsSubscription(removed); + NB_TRACE(("Removed %s nb_dcpsSubscription={key="NB_KEYFMT"}\n", + topObjName, v_gidSystemId(*subkey), v_gidLocalId(*subkey))); + if(nb_dcpsSubscriptionGetInterested(oldSub)){ + /* Forward the dispose */ + ures = nb_topicObjectWrite(_this->interest.entities.named.DCPSSubscription.writer, nb_topicObject(sub)); + if(ures != U_RESULT_OK) NB_TRACE(("nb_topicObjectWrite returned %s for %s\n", u_resultImage(ures), nb_topicObjectName(nb_topicObject(sub)))); + } + nb_objectFree(oldSub); + } + return U_RESULT_OK; + } else if(v_stateTest(s, L_WRITE)){ + const char * topicName = nb_dcpsSubscriptionTopicName(sub); + + /* Set interest */ + nb_dcpsSubscriptionSetInterested(sub, nb__serviceIncludes(_this), nb__serviceExcludes(_this)); + + if(nb_dcpsSubscriptionGetInterested(sub)){ + /* Check pre-conditions */ + NB_TRACE(("Checking pre-conditions for nb_dcpsSubscription={key="NB_KEYFMT"}" + " for forwarding of %s for topic \'%s\'\n", + v_gidSystemId(*subkey), v_gidLocalId(*subkey), + topObjName, topicName + )); + + key = nb_dcpsSubscriptionParticipantKey(sub); + entry = ut_get((ut_collection)_this->interest.entities.named.DCPSParticipant.handled, (void*) /* discard const */ key); + if(entry == NULL && requireContainingEntities){ + NB_TRACE(("nb_dcpsSubscription={key="NB_KEYFMT"}: Can't find nb_dcpsParticipant={" + "key="NB_KEYFMT"} needed for forwarding of %s for topic '%s' yet\n", + v_gidSystemId(*subkey), v_gidLocalId(*subkey), + v_gidSystemId(*key), v_gidLocalId(*key), + topObjName, topicName + )); + goto err_lookup; + } + part = entry ? nb_dcpsParticipant(entry) : NULL; + + key = nb_dcpsSubscriptionParticipantKey(sub); + entry = ut_get((ut_collection)_this->interest.entities.named.CMParticipant.handled, (void*) /* discard const */ key); + if(entry == NULL && requireContainingEntities){ + NB_TRACE(("nb_dcpsSubscription={key="NB_KEYFMT"}: Can't find nb_cmParticipant={" + "key="NB_KEYFMT"} needed for forwarding of %s for topic '%s' yet\n", + v_gidSystemId(*subkey), v_gidLocalId(*subkey), + v_gidSystemId(*key), v_gidLocalId(*key), + topObjName, topicName + )); + goto err_lookup; + } + cmpart = entry ? nb_cmParticipant(entry) : NULL; + + key = nb_dcpsSubscriptionKey(sub); + entry = ut_get((ut_collection)_this->interest.entities.named.CMDataReader.handled, (void*) /* discard const */ key); + if(entry == NULL){ + NB_TRACE(("nb_dcpsSubscription={key="NB_KEYFMT"}: Can't find nb_cmReader={" + "key="NB_KEYFMT"} needed for forwarding of %s for topic '%s' yet\n", + v_gidSystemId(*subkey), v_gidLocalId(*subkey), + v_gidSystemId(*key), v_gidLocalId(*key), + topObjName, topicName + )); + goto err_lookup; + } + cmr = entry ? nb_cmReader(entry) : NULL; + + if (cmr == NULL) { + cms = NULL; + } else { + key = nb_cmReaderSubscriberKey(cmr); + entry = ut_get((ut_collection)_this->interest.entities.named.CMSubscriber.handled, (void*) /* discard const */ key); + if(entry == NULL && requireContainingEntities){ + NB_TRACE(("nb_dcpsSubscription={key="NB_KEYFMT"}: Can't find nb_cmSubscriber={" + "key="NB_KEYFMT"} needed for forwarding of %s for topic '%s' yet\n", + v_gidSystemId(*subkey), v_gidLocalId(*subkey), + v_gidSystemId(*key), v_gidLocalId(*key), + topObjName, topicName + )); + goto err_lookup; + } + cms = entry ? nb_cmSubscriber(entry) : NULL; + } + + if((topic = nb__serviceInterestFindTopic(nb_serviceParticipant(_this), topicName)) == NULL){ + NB_TRACE(("nb_dcpsSubscription={key="NB_KEYFMT"}: Can't find u_topic '%s'\n", + v_gidSystemId(*subkey), v_gidLocalId(*subkey), + topicName + )); + goto err_lookup; + } + + NB_TRACE(("nb_dcpsSubscription={key="NB_KEYFMT"}: Found all entities needed to forward %s for topic '%s'\n", + v_gidSystemId(*subkey), v_gidLocalId(*subkey), + topObjName, topicName + )); + + /* The topic-definition is available, so for all absolute partition- + * expressions u_groupNew should succeed. */ + partitions = nb_dcpsSubscriptionPartitions(sub, &len); + nb__serviceCreateGroups(_this, partitions, len, topicName, subkey); + + if (!_this->interest.entities.named.DCPSParticipant.alwaysForward && part != NULL) { + writer = _this->interest.entities.named.DCPSParticipant.writer; + ures = nb_topicObjectWrite(writer, nb_topicObject(part)); + if(ures != U_RESULT_OK) NB_TRACE(("nb_topicObjectWrite returned %s for %s\n", u_resultImage(ures), nb_topicObjectName(nb_topicObject(part)))); + } + + if (!_this->interest.entities.named.CMParticipant.alwaysForward && cmpart != NULL) { + writer = _this->interest.entities.named.CMParticipant.writer; + ures = nb_topicObjectWrite(writer, nb_topicObject(cmpart)); + if(ures != U_RESULT_OK) NB_TRACE(("nb_topicObjectWrite returned %s for %s\n", u_resultImage(ures), nb_topicObjectName(nb_topicObject(cmpart)))); + } + + if (!_this->interest.entities.named.CMDataReader.alwaysForward && cmr != NULL) { + writer = _this->interest.entities.named.CMDataReader.writer; + ures = nb_topicObjectWrite(writer, nb_topicObject(cmr)); + if(ures != U_RESULT_OK) NB_TRACE(("nb_topicObjectWrite returned %s for %s\n", u_resultImage(ures), nb_topicObjectName(nb_topicObject(cmr)))); + } + + if (!_this->interest.entities.named.CMSubscriber.alwaysForward && cms != NULL) { + writer = _this->interest.entities.named.CMSubscriber.writer; + ures = nb_topicObjectWrite(writer, nb_topicObject(cms)); + if(ures != U_RESULT_OK) NB_TRACE(("nb_topicObjectWrite returned %s for %s\n", u_resultImage(ures), nb_topicObjectName(nb_topicObject(cms)))); + } + + writer = _this->interest.entities.named.DCPSSubscription.writer; + ures = nb_topicObjectWrite(writer, nb_topicObject(sub)); + if(ures != U_RESULT_OK) NB_TRACE(("nb_topicObjectWrite returned %s for %s\n", u_resultImage(ures), nb_topicObjectName(nb_topicObject(sub)))); + + (void)u_objectFree(u_object(topic)); + } + + key = nb_dcpsSubscriptionKey(sub); + if(ut_tableInsert(_this->interest.entities.named.DCPSSubscription.handled, (void*) /* discard const */ key, sub)){ + NB_TRACE(("nb_dcpsSubscription={key="NB_KEYFMT"}: Stored and processed %s nb_dcpsSubscription={key="NB_KEYFMT", topic_name=\"%s\"}\n", + v_gidSystemId(*subkey), v_gidLocalId(*subkey), + nb_topicObjectName(nb_topicObject(sub)), + v_gidSystemId(*subkey), v_gidLocalId(*subkey), + topicName + )); + nb_objectKeep(sub); + } else { + /* An update to an existing subscription is not stored, just forwarded. */ + NB_TRACE(("nb_dcpsSubscription={key="NB_KEYFMT"}: Processed %s nb_dcpsSubscription={key="NB_KEYFMT", topic_name=\"%s\"}\n", + v_gidSystemId(*subkey), v_gidLocalId(*subkey), + nb_topicObjectName(nb_topicObject(sub)), + v_gidSystemId(*subkey), v_gidLocalId(*subkey), + topicName + )); + } + return U_RESULT_OK; + + /* Error handling */ + err_lookup: + NB_TRACE(("nb_dcpsSubscription={key="NB_KEYFMT"}: Handling of %s deferred for nb_dcpsSubscription={key="NB_KEYFMT", topic_name=\"%s\"}\n", + v_gidSystemId(*subkey), v_gidLocalId(*subkey), + nb_topicObjectName(nb_topicObject(sub)), + v_gidSystemId(*subkey), v_gidLocalId(*subkey), + topicName + )); + return U_RESULT_TIMEOUT; + } else { + return U_RESULT_OK; + } +} + +static u_result nb__serviceHandleCmReaderFunc(nb_service _this, nb_topicObject top) { return nb__serviceHandleCmReader(_this, nb_cmReader(top)); } + +static u_result +nb__serviceHandleCmReader( + nb_service _this, + nb_cmReader toHandle) +{ + u_result ur; + + nb_objectIsValidKind(_this, NB_OBJECT_SERVICE); + nb_objectIsValidKind(toHandle, NB_TOPIC_OBJECT_CM_READER); + + ur = nb__serviceHandleServiceInterestTopic( + "nb_cmReader", + &_this->interest.entities.named.CMDataReader, + nb_cmReaderKey(toHandle), + nb_topicObject(toHandle)); + + return ur; +} + +static u_result nb__serviceHandleCmPublisherFunc(nb_service _this, nb_topicObject top) { return nb__serviceHandleCmPublisher(_this, nb_cmPublisher(top)); } + +static u_result +nb__serviceHandleCmPublisher( + nb_service _this, + nb_cmPublisher toHandle) +{ + u_result ur; + + nb_objectIsValidKind(_this, NB_OBJECT_SERVICE); + nb_objectIsValidKind(toHandle, NB_TOPIC_OBJECT_CM_PUBLISHER); + + ur = nb__serviceHandleServiceInterestTopic( + "nb_cmPublisher", + &_this->interest.entities.named.CMPublisher, + nb_cmPublisherKey(toHandle), + nb_topicObject(toHandle)); + + return ur; +} + +static u_result nb__serviceHandleCmSubscriberFunc(nb_service _this, nb_topicObject top) { return nb__serviceHandleCmSubscriber(_this, nb_cmSubscriber(top)); } + +static u_result +nb__serviceHandleCmSubscriber( + nb_service _this, + nb_cmSubscriber toHandle) +{ + u_result ur; + + nb_objectIsValidKind(_this, NB_OBJECT_SERVICE); + nb_objectIsValidKind(toHandle, NB_TOPIC_OBJECT_CM_SUBSCRIBER); + + ur = nb__serviceHandleServiceInterestTopic( + "nb_cmSubscriber", + &_this->interest.entities.named.CMSubscriber, + nb_cmSubscriberKey(toHandle), + nb_topicObject(toHandle)); + + return ur; +} + +static void +nb__serviceHandleBuiltinTopics ( + nb_service _this) +{ + size_t i; + nb_topicObject topObj; + c_iter toHandle; + struct nb_serviceInterestTopic *topic; + u_result ures; + c_bool somethingChanged; + + nb_objectIsValidKind(_this, NB_OBJECT_SERVICE); + + /* The service handles built-in topics by storing all samples with L_WRITE + * state in the relevant handled-table. The DCPSPublication- and + * DCPSSubscription-topics are only stored when they match the interest + * expressions and all other related built-in topics are stored already. If + * that is the case, the built-in topics are retrieved and forwarded. */ + do { + somethingChanged = FALSE; + for(i = 0; i < NB_SERVICE_NUM_ENTITIES; i++){ + topic = &_this->interest.entities.array[i]; + if(topic->subscriptionsMatched){ + toHandle = NULL; + while((topObj = c_iterTakeFirst(topic->toHandle)) != NULL){ + ures = topic->handleFunc(_this, topObj); + + if(ures == U_RESULT_OK){ + nb_topicObjectFree(topObj); + somethingChanged = TRUE; + } else { + toHandle = c_iterAppend(toHandle, topObj); + } + } + assert(c_iterLength(topic->toHandle) == 0); + c_iterFree(topic->toHandle); + topic->toHandle = toHandle; + } + } + } while (somethingChanged); +} + +static os_result +nb__exitRequestHandler( + os_callbackArg ignore, + void *callingThreadContext, + void * arg) +{ + nb_service _this = nb_service(arg); + + OS_UNUSED_ARG(ignore); + OS_UNUSED_ARG(callingThreadContext); + + assert(_this); + + _this->terminate = 1; + (void) u_waitsetNotify(_this->ws, NULL); + + return os_resultSuccess; /* the main thread will take care of termination */ +} + +static os_result +nb__exceptionHandler( + void *callingThreadContext, void * arg) +{ + nb_service _this = nb_service(arg); + + OS_UNUSED_ARG(callingThreadContext); + assert(_this); + + (void) u_serviceChangeState(_this->service, STATE_DIED); + + return os_resultSuccess; +} + +static v_result +nb__serviceWriterGetMatchedStatus( + c_voidp info /* struct v_topicMatchInfo* */, + c_voidp arg /* c_ulong* */) +{ + const struct v_topicMatchInfo *from = (struct v_topicMatchInfo *)info; + + assert(from); + assert(arg); + + /* currentCount can never become negative, so we can safely cast to c_ulong */ + *(c_ulong *)arg = (c_ulong)from->currentCount; + + return V_RESULT_OK; +} + +static const char * const * +nb__serviceIncludes( + nb_service _this) +{ + nb_objectIsValidKind(_this, NB_OBJECT_SERVICE); + + if(!_this->includes){ + _this->includes = nb_configurationIncludes(_this->config); + } + + return (const char * const *) _this->includes; +} + +static const char * const * +nb__serviceExcludes( + nb_service _this) +{ + nb_objectIsValidKind(_this, NB_OBJECT_SERVICE); + + if(!_this->excludes){ + _this->excludes = nb_configurationExcludes(_this->config); + } + + return (const char * const *) _this->excludes; +} + +static u_result +nb__serviceHandleEvents ( + nb_service _this, + u_waitsetEvent event) +{ + u_result uresult = U_RESULT_OK; + size_t i; + + if (v_eventTest(event->kind, V_EVENT_DATA_AVAILABLE)) { + for(i = 0; i < NB_SERVICE_NUM_ENTITIES; i++){ + struct nb_serviceInterestTopic *topic = &_this->interest.entities.array[i]; + if (event->userData == u_entity(topic->reader)) { + uresult = u_dataReaderTake(topic->reader, V_MASK_ANY, topic->action, &topic->toHandle, OS_DURATION_ZERO); + if (uresult == U_RESULT_NO_DATA) { + uresult = U_RESULT_OK; + } + /* TODO: flush? */ + break; + } + } + nb__serviceHandleBuiltinTopics(_this); + } else if (v_eventTest(event->kind, V_EVENT_PUBLICATION_MATCHED)) { + for(i = 0; i < NB_SERVICE_NUM_ENTITIES; i++){ + struct nb_serviceInterestTopic *topic = &_this->interest.entities.array[i]; + if (event->userData == u_entity(topic->writer)) { + uresult = u_writerGetPublicationMatchStatus(topic->writer, TRUE, nb__serviceWriterGetMatchedStatus, &topic->subscriptionsMatched); + NB_TRACE(("%s-writer has %u matching subscription(s), so will %spublish %s's now.\n", + topic->topicName, + topic->subscriptionsMatched, + topic->subscriptionsMatched ? "" : "not ", + topic->topicName)); + break; + } + } + } else if (v_eventTest(event->kind, V_EVENT_TRIGGER)) { + _this->terminate = 1; + } else { + NB_ERROR_1("nb__serviceMain", + "Received unexpected event %d\n", + (int) event->kind); + uresult = U_RESULT_INTERNAL_ERROR; + } + if(uresult != U_RESULT_OK){ + if(uresult == U_RESULT_ALREADY_DELETED){ + nb_log(LOG_WARNING, "nb__serviceMain: Processing of event failed: %s\n", u_resultImage(uresult)); + } else { + NB_WARNING_1("nb__serviceMain", "Processing of event failed: %s\n", u_resultImage(uresult)); + } + } + return uresult; +} + +struct nb__serviceHandleEventsActionArg { + nb_service service; + u_result result; +}; + +static void +nb__serviceHandleEventsAction ( + u_waitsetEvent event, + void *varg) +{ + struct nb__serviceHandleEventsActionArg *arg = varg; + arg->result = nb__serviceHandleEvents (arg->service, event); +} + +static void +nb__serviceMain( + nb_service _this) +{ + size_t i; + u_result uresult; + struct nb__serviceHandleEventsActionArg argument; + + argument.service = _this; + + nb_log(LOG_INFO, "nb__serviceMain started\n"); + + nb__serviceChangeState(_this, SERVICE_OPERATIONAL); + + /* Workaround for OSPL-5132. These calls can be removed when OSPL-5132 is fixed. */ + for(i = 0; i < NB_SERVICE_NUM_ENTITIES; i++){ + struct nb_serviceInterestTopic *topic = &_this->interest.entities.array[i]; + uresult = u_dataReaderTake(topic->reader, V_MASK_ANY, topic->action, &topic->toHandle, OS_DURATION_ZERO); + assert(uresult == U_RESULT_OK || uresult == U_RESULT_NO_DATA); + uresult = u_writerGetPublicationMatchStatus(topic->writer, TRUE, nb__serviceWriterGetMatchedStatus, &topic->subscriptionsMatched); + assert(uresult == U_RESULT_OK); + } + /* End of workaround. */ + + while (uresult == U_RESULT_OK && !_this->terminate) { + /* Handle pending builtin topics */ + nb__serviceHandleBuiltinTopics(_this); + + /* Wait for events to occur */ + uresult = u_waitsetWaitAction (_this->ws, nb__serviceHandleEventsAction, &argument, OS_DURATION_INFINITE); + + if (uresult == U_RESULT_OK) { + uresult = argument.result; + } else if (uresult == U_RESULT_DETACHING) { + NB_INFO("nb__serviceMain", "u_waitsetTimedWaitEvents detected termination\n"); + _this->terminate = 1; + } else if (uresult == U_RESULT_TIMEOUT) { + uresult = U_RESULT_OK; + } else { + NB_ERROR_1("nb__serviceMain", + "u_waitsetTimedWaitEvents failed (%s)\n", u_resultImage(uresult)); + } + } + + nb_log(LOG_INFO, "nb__serviceMain finished\n"); + + return; +} + +static void +nb__serviceCreateGroups( + nb_service _this, + const char * const * partitions, + c_ulong len, + const char * topicName, + const v_builtinTopicKey *pubkey) +{ + c_ulong i; + const char * partition; + u_group group; + + nb_objectIsValidKind(_this, NB_OBJECT_SERVICE); + + assert(partitions || len == 0); + assert(topicName); + assert(pubkey); + + for(i = 0; i < len; i++){ + partition = partitions[i]; + + /* Check that the partition-expression is absolute; wildcards are not + * supported during creation. */ + if (strchr(partition, '*') == NULL && strchr(partition, '?') == NULL) { + if(nb_match(&partition, 1, topicName, nb__serviceIncludes(_this), nb__serviceExcludes(_this))){ + group = u_groupNew(nb_serviceParticipant(_this), partition, topicName, 0); + assert(group); /* u_participantFindTopic passed, so this one should as well */ + NB_TRACE(("nb_dcpsPublication={key="NB_KEYFMT"}: New group created based on DCPSPublication: Group<%s,%s>\n", + v_gidSystemId(*pubkey), v_gidLocalId(*pubkey), + partition, topicName + )); + NB_TRACE(("nb_serviceCreateGroups: enabling forwarding on Group<%s,%s>\n", partition, topicName)); + u_groupSetRoutingEnabled(group, TRUE, NULL); + u_objectFree((u_object) group); + } else { + NB_TRACE(("nb_dcpsPublication={key="NB_KEYFMT"}: New group not created for DCPSPublication: Group<%s,%s>\n", + v_gidSystemId(*pubkey), v_gidLocalId(*pubkey), + partition, topicName)); + } + } else { + NB_TRACE(("nb_dcpsPublication={key="NB_KEYFMT"}: Ignored wildcard partition-expression: '%s' for topic '%s' is not supported\n", + v_gidSystemId(*pubkey), v_gidLocalId(*pubkey), + partition, topicName + )); + } + } +} + +OPENSPLICE_SERVICE_ENTRYPOINT (ospl_nwbridge, nwbridge) +{ + /* Exit status: 0: OK, 1: abnormal termination. + * Default to OK (normal termination), then override if + * that is inappropriate. + */ + os_int32 exitStatus = EXIT_SUCCESS; + nb_service service; + os_char* uri = NULL; + os_char* serviceName; + u_result uresult; + C_STRUCT(nb_logConfig) gc; + nb_threadStates ts; + + os_osInit(); + +#ifdef EVAL_V + OS_REPORT(OS_INFO, "Networking Bridge Service", 0, + "++++++++++++++++++++++++++++++++++++++++++++++++++" OS_REPORT_NL + "++ Networking Bridge Service EVALUATION VERSION ++" OS_REPORT_NL + "++++++++++++++++++++++++++++++++++++++++++++++++++"); +#endif + + if(argc <= 1) { + OS_REPORT(OS_WARNING, "Networking Bridge Service", 0, + "No service-name supplied, defaulting to '%s'. Usage: '%s ()'.", argv[0], argv[0]); + serviceName = argv[0]; + } + if(argc > 1) { + serviceName = argv[1]; + } + if(argc > 2) { + uri = argv[2]; + } + + ts = nb_threadStatesAlloc(); + + nb_logConfigInit(&gc); + + /* Create the threads administration (and promote the main thread) */ + if (nb_threadStatesInit(ts, NB_MAXTHREADS, &gc) != os_resultSuccess) { /* todo make max number of threads configurable? */ + OS_REPORT(OS_FATAL, "ospl_nwbridge", 0, + "Failed to initialize threads administration"); + goto err_thrstatesinit; + } + nb_threadUpgrade(ts); + + /* Create the nwbridge service object. This will create all needed DDS entities and insert the + * nwbridge topic meta data into the domain. */ + service = nb__serviceNew(uri, serviceName); + if(!service) { + fprintf(stderr, "Failed to create the service. Is the domain running?\n"); + /* Error reported by nb_serviceNew */ + goto err_serviceNew; + } + + /* Write our init-status; no way to detect failure... */ + nb__serviceChangeState(service, SERVICE_INITIALISING); + + /* The service must monitor the splice daemon for liveliness. If the SPLICE-daemon disappears, the service should + * react to this. */ + uresult = u_serviceWatchSpliceDaemon(service->service, nb__serviceWatchSpliced, (c_voidp)service); + if(uresult != U_RESULT_OK){ + /* Error reported by u_serviceWatchSpliceDaemon; TODO: check whether report contains enough info. */ + nb__serviceChangeState(service, SERVICE_TERMINATING); + goto err_serviceWatchSpliced; + } + + /* Now the main thread of the nwbridge service will wait until the terminate flag of the nwbridge service has been set to true. */ + nb__serviceMain(service); + + nb__serviceChangeState(service, SERVICE_TERMINATING); + + u_serviceWatchSpliceDaemon(service->service, NULL, (c_voidp)service); + +err_serviceWatchSpliced: + nb_serviceFree(service); +err_serviceNew: + nb_threadDowngrade(); + nb_threadStatesDeinit(ts); +err_thrstatesinit: + nb_logConfigDeinit(&gc); + nb_threadStatesDealloc(ts); + + os_osExit(); + return exitStatus; +} + +const os_char * +nb_serviceName( + nb_service _this) +{ + nb_objectIsValidKind(_this, NB_OBJECT_SERVICE); + + return _this->name; +} + +u_service +nb_serviceService( + nb_service _this) +{ + nb_objectIsValidKind(_this, NB_OBJECT_SERVICE); + + return _this->service; +} + +void +nb__serviceLoadMetaData( + v_public vpublic, + c_voidp arg /* c_bool* */) +{ + c_base base; + c_bool *result = (c_bool*)arg; + + assert(vpublic); + assert(result); + + base = c_getBase((c_object) vpublic); + *result = loadNetworkingBridge(base); + + if (!*result) { + NB_ERROR("nb_serviceLoadMetaData", "Failed to load NetworkingBridge-module\n"); + } +} + +void +nb__serviceWatchSpliced( + v_serviceStateKind state, + c_voidp userData /* nb_service */) +{ + nb_service _this; + + nb_objectIsValidKind(userData, NB_OBJECT_SERVICE); + + _this = nb_service(userData); + + switch(state) + { + case STATE_TERMINATING: + case STATE_TERMINATED: + case STATE_DIED: + NB_TRACE(("nb__serviceWatchSpliced: spliced is terminating. nwbridge service '%s' %s.", + _this->name, _this->terminate ? "is already terminating" : "will terminate too")); + /* Set the terminate flag */ + _this->terminate = 1; + break; + default: + /* do nothing */ + break; + } +} + +static v_serviceStateKind +nb__ServiceStateToKernelServiceStateKind( + ServiceState state) +{ + v_serviceStateKind kind; + + switch(state){ + case SERVICE_INITIALISING: + kind = STATE_INITIALISING; + break; + case SERVICE_OPERATIONAL: + kind = STATE_OPERATIONAL; + break; + case SERVICE_TERMINATING: + kind = STATE_TERMINATING; + break; + case SERVICE_TERMINATED: + kind = STATE_TERMINATED; + break; + default: + assert(FALSE); + kind = STATE_NONE; + break; + } + return kind; +} + +c_bool +nb__serviceChangeState( + nb_service _this, + ServiceState state) +{ + c_bool stateChanged; + + nb_objectIsValidKind(_this, NB_OBJECT_SERVICE); + assert(_this->service); + + /* TODO: fix u_serviceChangeState; currently it cannot be distinguished whether the + * change failed or the state just didn't change. */ + stateChanged = u_serviceChangeState(_this->service, nb__ServiceStateToKernelServiceStateKind(state)); + if (stateChanged) { + u_result result; + struct ServiceStatus status; + + status.serviceId = _this->name; + + status.state = state; + + assert(_this->statusWriter); + + if (state != SERVICE_TERMINATED) { + result = u_writerWrite ( + _this->statusWriter, + (u_writerCopy)ServiceStatusCopyIn, + (void*)&status, + OS_TIMEW_INVALID, + U_INSTANCEHANDLE_NIL); + } else { + result = u_writerWriteDispose ( + _this->statusWriter, + (u_writerCopy)ServiceStatusCopyIn, + (void*)&status, + OS_TIMEW_INVALID, + U_INSTANCEHANDLE_NIL); + } + + if(result != U_RESULT_OK){ + OS_REPORT(OS_WARNING, "nb__serviceChangeState", result, + "Failed to publish service state-change; write returned '%s'.", u_resultImage(result)); + } + } + return stateChanged; +} + +static c_bool +ServiceStatusCopyIn( + c_type type, + struct ServiceStatus *data, + struct ServiceStatus *to) +{ + assert(type); + assert(data); + assert(to); + + memcpy(to, data, sizeof(*to)); + to->serviceId = c_stringNew(c_getBase(type), data->serviceId); + + return TRUE; +} + +static u_topic +nb__serviceInterestFindTopic( + u_participant participant, + const c_char * name) +{ + c_iter topics; + u_topic topic; + + assert(participant); + assert(name); + + topics = u_participantFindTopic(participant, name, 0); + assert(c_iterLength(topics) <= 1); + topic = u_topic(c_iterTakeFirst(topics)); + c_iterFree(topics); + + return topic; +} + +static u_result +nb__serviceInterestTopicInit( + struct nb_serviceInterestTopic *interest, + u_participant participant, + u_waitset waitset, + u_publisher publisher, + u_writerQos writerQos, + u_subscriber subscriber, + u_readerQos readerQos) +{ + u_result result = U_RESULT_INTERNAL_ERROR; + c_char *entityName; + c_char *expression; + u_topic topic; + + assert(interest); + assert(interest->topicName); + assert(participant); + assert(waitset); + assert(publisher); + assert(writerQos); + assert(subscriber); + assert(readerQos); + + interest->toHandle = NULL; + interest->alwaysForward = FALSE; + + interest->handled = (ut_table)ut_tableNew(nb_compareByGid, NULL, 0, NULL, nb__serviceInterestTopicObjectFreeFunc, NULL); + if(!interest->handled){ + OS_REPORT(OS_FATAL, "nb__serviceInterestTopicInit", 0, "Out of resources. Could not allocate table."); + goto err_tableNew; + } + + topic = nb__serviceInterestFindTopic(participant, interest->topicName); + if(!topic){ + /* Out-of-memory and no topics found cannot be distinguished currently. + * Both are wrong however, so report and fail. */ + OS_REPORT(OS_FATAL, "nb__serviceInterestTopicInit", 0, "Out of resources or failed to retrieve %s-topic.", interest->topicName); + goto err_findTopic; + } + + entityName = os_malloc(strlen(interest->topicName) + strlen(NB_INTEREST_WRITER_SUFFIX) + 1); + (void) sprintf(entityName, "%s" NB_INTEREST_WRITER_SUFFIX, interest->topicName); + + /* Create the DCPSSubscription Writer and Reader */ + interest->writer = u_writerNew( + publisher, + entityName, + topic, + writerQos); + + os_free(entityName); + u_objectFree(u_object(topic)); + + if(!interest->writer){ + /* Error reported by u_writerNew */ + goto err_writerNew; + } + u_writerEnable (interest->writer); + interest->subscriptionsMatched = 0; + + result = u_waitsetAttach(waitset, u_observable(interest->writer), u_entity(interest->writer)); + if(result != U_RESULT_OK){ + OS_REPORT(OS_FATAL, "nb__serviceInterestTopicInit", result, "Could not attach writer to waitset: result %s", + u_resultImage(result)); + goto err_waitsetattachWriter; + } + + entityName = os_malloc(strlen(interest->topicName) + strlen(NB_INTEREST_READER_SUFFIX) + 1); + (void) sprintf(entityName, "%s" NB_INTEREST_READER_SUFFIX, interest->topicName); + + expression = os_malloc(strlen(interest->topicName) + strlen("select * from ") + 1); + (void) sprintf(expression, "select * from %s", interest->topicName); + + interest->reader = u_subscriberCreateDataReader( + subscriber, + entityName, + expression, + NULL, 0, + readerQos); + + os_free(entityName); + os_free(expression); + + if(!interest->reader){ + /* Error reported by u_subscriberCreateDataReader */ + goto err_readerNew; + } + + if(u_entityEnable(u_entity(interest->reader)) != U_RESULT_OK) { + goto err_readerEnable; + } + + result = u_waitsetAttach(waitset, u_observable(interest->reader), u_entity(interest->reader)); + if(result != U_RESULT_OK){ + OS_REPORT(OS_FATAL, "nb__serviceInterestTopicInit", result, "Could not attach reader to waitset: result %s", + u_resultImage(result)); + goto err_waitsetattachReader; + } + + return result; + +/* Error-handling */ +err_waitsetattachReader: +err_readerEnable: + u_objectFree(u_object(interest->reader)); +err_readerNew: + u_waitsetDetach(waitset, u_observable(interest->writer)); +err_waitsetattachWriter: + u_objectFree(u_object(interest->writer)); +err_writerNew: +err_findTopic: + ut_tableFree(interest->handled); +err_tableNew: + return result; +} + +/* ut_freeElementFunc wrapper */ +static void +nb__serviceInterestTopicObjectFreeFunc( + void *o, + void *arg) +{ + OS_UNUSED_ARG(arg); + + nb_topicObjectFree(nb_topicObject(o)); +} + + +static void +nb__serviceInterestTopicDeinit( + struct nb_serviceInterestTopic *interest, + u_waitset waitset) +{ + nb_topicObject topObj; + + assert(interest); + assert(waitset); + + /* Free remaining builtin topics */ + while((topObj = c_iterTakeFirst(interest->toHandle)) != NULL) { + NB_TRACE(("Could not handle %s for topic %s\n", nb_topicObjectName(topObj), interest->topicName)); + nb_topicObjectFree(topObj); + } + c_iterFree(interest->toHandle); + + ut_tableFree(interest->handled); + + (void) u_waitsetDetach(waitset, u_observable(interest->reader)); + (void) u_objectFree(u_object(interest->reader)); + (void) u_waitsetDetach(waitset, u_observable(interest->writer)); + (void) u_objectFree(u_object(interest->writer)); +} + +static os_result +nb__serviceInterestInit( + struct nb_serviceInterest* interest, + u_participant participant, + u_waitset waitset) +{ + v_subscriberQos subscriberQos; + v_readerQos readerQos; + v_publisherQos publisherQos; + v_writerQos writerQos; + c_char fedSpecPart[U_DOMAIN_FEDERATIONSPECIFICPARTITIONNAME_MINBUFSIZE]; + u_result result; + c_ulong mask; + size_t i; + + { /* Create and initialize the QoS's */ + + /* Publisher-QoS */ + publisherQos = u_publisherQosNew(NULL); + if (!publisherQos) { + OS_REPORT(OS_FATAL, "nb__serviceInterestInit", 0, "Out of resources. Could not allocate default publisherQos."); + goto err_publisherQosNew; + } + + /* Retrieve the federation specific partition-name */ + /* If bufSize is at least U_DOMAIN_FEDERATIONSPECIFICPARTITIONNAME_MINBUFSIZE, + * the full partition-name is guaranteed to be returned. */ + result = u_participantFederationSpecificPartitionName ( + participant, fedSpecPart, sizeof (fedSpecPart)); + assert(result == U_RESULT_OK); + + publisherQos->presentation.v.access_scope = V_PRESENTATION_TOPIC; + os_free(publisherQos->partition.v); + publisherQos->partition.v = os_strdup(fedSpecPart); + + /* Writer-QoS */ + writerQos = u_writerQosNew(NULL); + if(!writerQos){ + OS_REPORT(OS_FATAL, "nb__serviceInterestInit", 0, "Out of resources. Could not allocate default writerQos."); + goto err_writerQosNew; + } + + /* Set interest writer QoS. Should be VOLATILE and autodispose = TRUE */ + assert(writerQos->durability.v.kind == V_DURABILITY_VOLATILE); + /* This writer is meant to be attached to a node-local partition, so + * reliability shouldn't really matter. */ + writerQos->reliability.v.kind = V_RELIABILITY_RELIABLE; + assert(writerQos->lifecycle.v.autodispose_unregistered_instances == TRUE); + + + /* Subscriber-QoS */ + subscriberQos = u_subscriberQosNew(NULL); + if (!subscriberQos) { + OS_REPORT(OS_FATAL, "nb__serviceInterestInit", 0, "Out of resources. Could not allocate default subscriberQos."); + goto err_subscriberQosNew; + } + os_free(subscriberQos->partition.v); + subscriberQos->presentation.v.access_scope = V_PRESENTATION_TOPIC; + subscriberQos->partition.v = os_strdup(V_BUILTIN_PARTITION); + + /* Reader-QoS */ + readerQos = u_readerQosNew (NULL); + if (!readerQos){ + OS_REPORT(OS_FATAL, "nb__serviceInterestInit", 0, "Out of resources. Could not allocate default readerQos."); + goto err_readerQosNew; + } + + /* Set the proper QoS for the DCPSPublication-topic */ + readerQos->durability.v.kind = V_DURABILITY_TRANSIENT; + readerQos->reliability.v.kind = V_RELIABILITY_RELIABLE; + readerQos->history.v.kind = V_HISTORY_KEEPLAST; + readerQos->history.v.depth = 1; + + } + + { /* Create the Publisher and Subscriber */ + + /* Publisher */ + interest->publisher = u_publisherNew(participant, NB_INTEREST_PUBLISHER, publisherQos, TRUE); + if (!interest->publisher) { + /* Error reported by u_publisherNew */ + goto err_publisherNew; + } + + /* Subscriber */ + interest->subscriber = u_subscriberNew(participant, NB_INTEREST_SUBSCRIBER, subscriberQos); + if (!interest->subscriber) { + /* Error reported by u_subscriberNew */ + goto err_subscriberNew; + } + if(u_entityEnable(u_entity(interest->subscriber)) != U_RESULT_OK) { + goto err_subscriberEnable; + } + } + + { /* Set proper masks on WaitSet */ + + assert(waitset); + + result = u_waitsetGetEventMask(waitset, &mask); + if (result != U_RESULT_OK) { + OS_REPORT(OS_FATAL, "nb__serviceInterestInit", result, "Could not get event mask for waitset: result %s", + u_resultImage(result)); + goto err_eventmask; + } + + /* V_EVENT_DATA_AVAILABLE for the readers; V_EVENT_PUBLICATION_MATCHED for the writers */ + result = u_waitsetSetEventMask(waitset, mask | V_EVENT_DATA_AVAILABLE | V_EVENT_PUBLICATION_MATCHED); + if (result != U_RESULT_OK) { + OS_REPORT(OS_FATAL, "nb__serviceInterestInit", result, "Could not set event mask for waitset: result %s", + u_resultImage(result)); + goto err_eventmask; + } + } + + /* Initializes topic-names and actions */ + interest->entities.named.DCPSTopic.topicName = V_TOPICINFO_NAME; + interest->entities.named.DCPSParticipant.topicName = V_PARTICIPANTINFO_NAME; + interest->entities.named.CMParticipant.topicName = V_CMPARTICIPANTINFO_NAME; + interest->entities.named.DCPSPublication.topicName = V_PUBLICATIONINFO_NAME; + interest->entities.named.CMDataWriter.topicName = V_CMDATAWRITERINFO_NAME; + interest->entities.named.DCPSSubscription.topicName = V_SUBSCRIPTIONINFO_NAME; + interest->entities.named.CMDataReader.topicName = V_CMDATAREADERINFO_NAME; + interest->entities.named.CMPublisher.topicName = V_CMPUBLISHERINFO_NAME; + interest->entities.named.CMSubscriber.topicName = V_CMSUBSCRIBERINFO_NAME; + + for(i = 0; i < NB_SERVICE_NUM_ENTITIES; i++){ + struct nb_serviceInterestTopic *topic = &interest->entities.array[i]; + /* topicName must be set! */ + result = nb__serviceInterestTopicInit(topic, participant, waitset, interest->publisher, writerQos, interest->subscriber, readerQos); + if(result != U_RESULT_OK){ + OS_REPORT(OS_FATAL, "nb__serviceInterestInit", result, "Could not create entities for topic %s: result %s", topic->topicName, u_resultImage(result)); + goto err_topic; + } + } + + interest->entities.named.DCPSTopic.action = nb_dcpsTopicReaderAction; + interest->entities.named.DCPSTopic.handleFunc = nb__serviceHandleDcpsTopicFunc; + interest->entities.named.DCPSParticipant.action = nb_dcpsParticipantReaderAction; + interest->entities.named.DCPSParticipant.handleFunc = nb__serviceHandleDcpsParticipantFunc; + interest->entities.named.CMParticipant.action = nb_cmParticipantReaderAction; + interest->entities.named.CMParticipant.handleFunc = nb__serviceHandleCmParticipantFunc; + interest->entities.named.DCPSPublication.action = nb_dcpsPublicationReaderAction; + interest->entities.named.DCPSPublication.handleFunc = nb__serviceHandleDcpsPublicationFunc; + interest->entities.named.CMDataWriter.action = nb_cmWriterReaderAction; + interest->entities.named.CMDataWriter.handleFunc = nb__serviceHandleCmWriterFunc; + interest->entities.named.DCPSSubscription.action = nb_dcpsSubscriptionReaderAction; + interest->entities.named.DCPSSubscription.handleFunc = nb__serviceHandleDcpsSubscriptionFunc; + interest->entities.named.CMDataReader.action = nb_cmReaderReaderAction; + interest->entities.named.CMDataReader.handleFunc = nb__serviceHandleCmReaderFunc; + interest->entities.named.CMPublisher.action = nb_cmPublisherReaderAction; + interest->entities.named.CMPublisher.handleFunc = nb__serviceHandleCmPublisherFunc; + interest->entities.named.CMSubscriber.action = nb_cmSubscriberReaderAction; + interest->entities.named.CMSubscriber.handleFunc = nb__serviceHandleCmSubscriberFunc; + + interest->entities.named.DCPSParticipant.alwaysForward = TRUE; + interest->entities.named.CMParticipant.alwaysForward = TRUE; + interest->entities.named.CMPublisher.alwaysForward = TRUE; + interest->entities.named.CMSubscriber.alwaysForward = TRUE; + + u_writerQosFree(writerQos); + u_publisherQosFree(publisherQos); + u_readerQosFree(readerQos); + u_subscriberQosFree(subscriberQos); + + return os_resultSuccess; + +/* Error handling */ +err_topic: + while(i-- > 0){ + nb__serviceInterestTopicDeinit(&interest->entities.array[i], waitset); + } + u_waitsetSetEventMask(waitset, mask); +err_eventmask: + /* No undo for u_entityEnable(...) */ +err_subscriberEnable: + u_objectFree(u_object(interest->subscriber)); +err_subscriberNew: + u_objectFree(u_object(interest->publisher)); +err_publisherNew: + u_readerQosFree(readerQos); +err_readerQosNew: + u_subscriberQosFree(subscriberQos); +err_subscriberQosNew: + u_writerQosFree(writerQos); +err_writerQosNew: + u_publisherQosFree(publisherQos); +err_publisherQosNew: + return os_resultFail; +} + + +static void +nb__serviceInterestDeinit( + struct nb_serviceInterest* interest, + u_waitset waitset) +{ + c_ulong i; + + assert(interest); + assert(waitset); + + for(i = 0; i < NB_SERVICE_NUM_ENTITIES; i++){ + nb__serviceInterestTopicDeinit(&interest->entities.array[i], waitset); + } + + (void) u_objectFree(u_object(interest->publisher)); + (void) u_objectFree(u_object(interest->subscriber)); +} + +nb_service +nb__serviceNew( + const os_char* uri, + const os_char* serviceName) +{ + nb_service _this; + v_publisherQos publisherQos; + v_topicQos topicQos; + v_writerQos writerQos; + u_result uresult; + c_long timeout = 3; /* TODO: Make this a sensible value from some config? */ + + assert(serviceName); + + _this = os_malloc(sizeof *_this); + + /* Super-init */ + nb__objectInit(nb_object(_this), NB_OBJECT_SERVICE, (nb_objectDeinitFunc)nb__serviceDeinit); + { + /* Create the service object */ + _this->name = os_strdup(serviceName); + + u_userInitialise(); + + _this->terminate = 0; + + /* Create the u_service object; this will attach to the DDS domain */ + _this->service = u_nwbridgeNew(uri, U_DOMAIN_ID_ANY, timeout, serviceName, NULL, TRUE); + if (!_this->service) { + /* Error reported by u_serviceNew */ + goto err_uservicenew; + } + + /* Create the waitset */ + _this->ws = u_waitsetNew(); + if(!_this->ws){ + OS_REPORT(OS_FATAL, "nb_serviceNew", 0, "Could not create waitset."); + goto err_waitsetnew; + } + + uresult = u_waitsetSetEventMask(_this->ws, V_EVENT_TRIGGER); + if (uresult != U_RESULT_OK) { + OS_REPORT(OS_FATAL, "nb_serviceNew", uresult, + "Could not set event mask for waitset: result %s", + u_resultImage(uresult)); + goto err_service_eventmask; + } + + uresult = u_waitsetAttach(_this->ws, u_observable(_this->service), _this->service); + if(uresult != U_RESULT_OK){ + OS_REPORT(OS_FATAL, "nb_serviceNew", uresult, + "Could not attach service to waitset: result %s", + u_resultImage(uresult)); + goto err_waitsetattachService; + } + + if (!os_serviceGetSingleProcess()) { + /* As long as termination doesn't work correctly in SP, don't try to do cleanup. */ + _this->erh = os_signalHandlerRegisterExitRequestCallback(nb__exitRequestHandler, NULL, NULL, NULL, _this); + _this->eh = os_signalHandlerRegisterExceptionCallback(nb__exceptionHandler, NULL, NULL, NULL, _this); + } else { + _this->erh = os_signalHandlerExitRequestHandleNil; + _this->eh = os_signalHandlerExceptionHandleNil; + } + } + + { + /* Create the publisher */ + publisherQos = u_publisherQosNew(NULL); + if (!publisherQos) { + OS_REPORT(OS_FATAL, "nb_serviceNew", 0, "Out of resources. Could not allocate default publisherQos."); + goto err_pubqosnew; + } + os_free(publisherQos->partition.v); + publisherQos->partition.v = os_strdup(NB_STATUS_PARTITION); + + /* Create the status-publisher */ + _this->publisher = u_publisherNew(u_participant(_this->service), NB_STATUS_PUBLISHER, publisherQos, TRUE); + if (!_this->publisher) { + /* Error reported by u_publisherNew */ + goto err_publisher; + } + } + + if(nb__serviceInterestInit(&_this->interest, u_participant(_this->service), _this->ws) != os_resultSuccess){ + /* Errors reported by nb__serviceInterestInit */ + goto err_serviceInterestInit; + } + + { /* Inject the metadata and create the topics used by the service for status + * changes and the API. This is done here for OSPL-1091; ease of use when + * the C&M API is used. */ + c_bool result; + + /* Inject metadata */ + uresult = u_observableAction(u_observable(_this->service), nb__serviceLoadMetaData, &result); + if (uresult != U_RESULT_OK) { + OS_REPORT(OS_FATAL, "nb_serviceNew", 0, + "Unable to load module 'nwbridge', u_entityAction failed: '%s' (%d).", + u_resultImage(uresult) /* TODO: Rename u_resultImage; this is odd... */, + uresult); + goto err_loadmeta; + } + if (!result) { + OS_REPORT(OS_FATAL, "nb_serviceNew", 0, + "Unable to load module 'nwbridge', loadnwbridge failed."); + goto err_loadmeta; + } + + /* Initialize the topic-QoS for status topics */ + topicQos = u_topicQosNew(NULL); + if (!topicQos) { + OS_REPORT(OS_FATAL, "nb_serviceNew", 0, + "Out of resources. Could not allocate default topicQos."); + goto err_topicqos_new; + } + + /* Set proper QoS for state-based data */ + NB_SET_STATEBASED_TOPICQOS(topicQos); + + /* Create the serviceStatus topic */ + _this->topics.serviceStatus = u_topicNew(u_participant(_this->service), + NB_SERVICE_STATUS_TOPIC_NAME, + NB_SERVICE_STATUS_TOPIC_TYPE_NAME, + NB_SERVICE_STATUS_TOPIC_KEY_LIST, + topicQos); + if (!_this->topics.serviceStatus) { + /* Error reported by u_topicNew */ + goto err_serviceStatusTopic_new; + } + + } + + { + /* Create status writer */ + writerQos = u_writerQosNew(NULL); + if(!writerQos){ + OS_REPORT(OS_FATAL, "nb_serviceNew", 0, "Out of resources. Could not allocate default writerQos."); + goto err_writerqos_new; + } + + /* Set proper QoS for state-based data */ + NB_SET_STATEBASED_WRITERQOS(writerQos); + + _this->statusWriter = u_writerNew( + _this->publisher, + NB_SERVICE_STATUS_WRITER, + _this->topics.serviceStatus, + writerQos); + if(!_this->statusWriter){ + /* Error reported by u_writerNew */ + goto err_statuswriter; + } + u_writerEnable (_this->statusWriter); + } + + /* Create the initial service configuration */ + { + _this->config = nb_configurationNew(_this); + if (!_this->config) { + OS_REPORT(OS_FATAL, "nb_serviceNew", 0, + "Failed to initialize service configuration of Networking Bridge service '%s'", + serviceName); + goto err_confignew; + } + + if (os_mutexInit(&(_this->configLock), NULL) != os_resultSuccess) { + OS_REPORT(OS_FATAL, "nb_serviceNew", 0, + "Failed to initialize mutex for configuration of service '%s'", serviceName); + goto err_cfgmutexinit; + } + + _this->includes = NULL; + _this->excludes = NULL; + } + + /* Open tracing file */ + { + if (nb__serviceOpenTracingFile(_this) != os_resultSuccess) { + /* error reported by nb_serviceOpenTracingFile */ + goto err_tracingopen; + } +#if defined(OSPL_INNER_REV) && defined (OSPL_OUTER_REV) + nb_log(LOG_INFO, "Started Networking Bridge Service (OpenSplice " OSPL_VERSION_STR ", build " OSPL_INNER_REV_STR "/" OSPL_OUTER_REV_STR ")\n"); +#else + nb_log(LOG_INFO, "Started Networking Bridge Service (OpenSplice " OSPL_VERSION_STR ", non-PrismTech build)\n"); +#endif + nb_configurationPrint(_this->config); + } + + /* Create service lease renewal thread */ + { + os_result result = nb_threadCreate("LeaseRenew", &(_this->leaseRenewalThr), nb__serviceUpdateLease, _this); + if (result != os_resultSuccess) { + NB_ERROR_1("nb_serviceNew", "Failed to create service lease renewal thread of service '%s'\n", serviceName); + goto err_leasethread; + } + } + + /* Cleanup local resources */ + u_writerQosFree(writerQos); + u_topicQosFree(topicQos); + u_publisherQosFree(publisherQos); + + return _this; + + /************************************************/ +err_leasethread: +err_tracingopen: + os_mutexDestroy(&(_this->configLock)); +err_cfgmutexinit: + nb_configurationFree(_this->config); +err_confignew: + u_objectFree(u_object(_this->statusWriter)); +err_statuswriter: + u_writerQosFree(writerQos); + writerQos = NULL; +err_writerqos_new: + u_objectFree(u_object(_this->topics.serviceStatus)); +err_serviceStatusTopic_new: + u_topicQosFree(topicQos); +err_topicqos_new: + /* Unfortunately no undo for loading of a module */ +err_loadmeta: + nb__serviceInterestDeinit(&_this->interest, _this->ws); +err_serviceInterestInit: + u_objectFree(u_object(_this->publisher)); +err_publisher: + /* publisherQos->partition is freed by u_publisherQosFree */ + u_publisherQosFree(publisherQos); +err_pubqosnew: + os_signalHandlerUnregisterExceptionCallback(_this->eh); + os_signalHandlerUnregisterExitRequestCallback(_this->erh); + u_waitsetDetach(_this->ws, u_observable(nb_serviceService(_this))); +err_waitsetattachService: + /* No undo needed for setting the event-mask */ +err_service_eventmask: + u_objectFree(u_object(_this->ws)); +err_waitsetnew: + u_objectFree(u_object(_this->service)); +err_uservicenew: + os_free(_this->name); + nb__objectDeinit((nb_object) _this); + os_free(_this); + return NULL; +} + +void +nb__serviceDeinit( + nb_service _this) +{ + nb_objectIsValidKind(_this, NB_OBJECT_SERVICE); + + if (nb_threadJoin(_this->leaseRenewalThr, NULL) != os_resultSuccess) { + NB_WARNING("nb__serviceDeinit", + "Failed to join service lease renewal thread\n"); + } + + /* This is our last update on our status */ + nb__serviceChangeState(_this, SERVICE_TERMINATED); + + nb__serviceInterestDeinit(&_this->interest, _this->ws); + + u_objectFree(u_object(_this->statusWriter)); + u_objectFree(u_object(_this->publisher)); + + u_objectFree(u_object(_this->topics.serviceStatus)); + + /* Free configuration */ + nb_configurationFree(_this->config); + + { /* Free cached includes and excludes */ + if(_this->includes){ + int i = 0; + while(_this->includes[i]){ + os_free(_this->includes[i]); + i++; + } + os_free(_this->includes); + } + + if(_this->excludes){ + int i = 0; + while(_this->excludes[i]){ + os_free(_this->excludes[i]); + i++; + } + os_free(_this->excludes); + } + } + + os_signalHandlerUnregisterExceptionCallback(_this->eh); + os_signalHandlerUnregisterExitRequestCallback(_this->erh); + + u_waitsetDetach(_this->ws, u_observable(_this->service)); + + if (u_objectFree_s(u_object(_this->ws)) != U_RESULT_OK) { + NB_WARNING("nb__serviceDeinit", + "Failed to free service waitset\n"); + } + u_objectFree(u_object(_this->service)); + os_free(_this->name); + + /* Call super-deinit */ + nb__objectDeinit((nb_object) _this); +} + +static os_result +nb__serviceOpenTracingFile( + nb_service _this) +{ + os_result result; + os_char *filename; + const char *mode; + nb_logConfig gc = nb_threadLogConfig(nb_threadLookup()); + + nb_objectIsValidKind(_this, NB_OBJECT_SERVICE); + + result = os_resultSuccess; + filename = nb_configurationTracingFileName(_this->config); + gc->tracing.categories = nb_configurationTracingCategories(_this->config); + + if(!filename || gc->tracing.categories == LOG_NONE) { + /* Tracing is not enabled */ + gc->tracing.file = NULL; + gc->tracing.categories = 0; + } else if (os_strcasecmp(filename, "stdout") == 0) { + gc->tracing.file = stdout; + } else if (os_strcasecmp(filename, "stderr") == 0) { + gc->tracing.file = stderr; + } else { + mode = (nb_configurationTracingAppend(_this->config)) ? "a" : "w"; + gc->tracing.file = fopen(filename, mode); + if (!gc->tracing.file) { + const os_char *msg = os_getErrno() ? os_strError(os_getErrno()) : NULL; + NB_ERROR_2("nb_serviceOpenTracingFile", "Cannot open tracing logfile '%s' (%s)\n", + filename, msg ? msg : "unknown reason"); + result = os_resultFail; + } + } + if(result == os_resultSuccess) { + NB_TRACE(("Opened NetworkingBridge tracing file '%s'\n", filename)); + } + return result; +} + +static void* +nb__serviceUpdateLease( + c_voidp arg /* nb_service */) +{ + nb_service _this; + os_duration expiry; + os_duration sleep; + + nb_objectIsValidKind(arg, NB_OBJECT_SERVICE); + + _this = nb_service(arg); + + expiry = nb_configurationLeaseExpiryTime(_this->config); + sleep = nb_configurationLeaseUpdateInterval(_this->config); + NB_TRACE(("Started service-lease renewal thread\n")); + + while(!_this->terminate && !nb_proc_must_exit) { + u_serviceRenewLease(nb_serviceService(_this), expiry); + ospl_os_sleep(sleep); + } + + /* Set longer expiry for during termination */ + expiry = OS_DURATION_INIT(20, 0); + u_serviceRenewLease(nb_serviceService(_this), expiry); + + NB_TRACE(("Terminating service-lease renewal thread\n")); + + return NULL; +} diff --git a/src/services/nwbridge/code/nb_thread.c b/src/services/nwbridge/code/nb_thread.c new file mode 100644 index 000000000..259d2e4c8 --- /dev/null +++ b/src/services/nwbridge/code/nb_thread.c @@ -0,0 +1,545 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#include "nb__thread.h" +#include "nb__util.h" +#include "nb__log.h" +#include "nb__configuration.h" + +#include "vortex_os.h" +#include "os_report.h" +#include "os_thread.h" +#include "os_mutex.h" +#include "u_service.h" + +struct nb_threadContext { + nb_thread self; + nb_threadRoutine func; + void *arg; +}; + +/* Things don't go wrong if CACHE_LINE_SIZE is defined incorrectly, + they just run slower because of false cache-line sharing. It can be + discovered at run-time, but in practice it's 64 for most CPUs and + 128 for some. */ +#define CACHE_LINE_SIZE 64 + +typedef os_uint32 nb_vtime; +typedef os_int32 nb_svtime; /* signed version */ + +enum nb_threadState { + NB_THREAD_STATE_ZERO, + NB_THREAD_STATE_ALIVE +}; + +/* + * watchdog indicates progress for the service lease liveliness mechsanism, while vtime + * indicates progress for the Garbage collection purposes. + * vtime even : thread awake + * vtime odd : thread asleep + */ +#define THREAD_BASE \ + nb_threadStates ts; \ + volatile nb_vtime vtime; \ + volatile nb_vtime watchdog; \ + os_threadId tid; \ + os_threadId extTid; \ + enum nb_threadState state; \ + nb_logbuf logbuf; \ + char *name /* note: no semicolon! */ + +struct nb_threadStateBase { + THREAD_BASE; +}; + +C_STRUCT(nb_thread) { + C_EXTENDS(nb_object); + THREAD_BASE; + char pad[CACHE_LINE_SIZE + * ((sizeof (struct nb_threadStateBase) + CACHE_LINE_SIZE - 1) + / CACHE_LINE_SIZE) + - sizeof (struct nb_threadStateBase)]; +}; + +#undef THREAD_BASE + +C_STRUCT(nb_threadStates) { + os_mutex lock; + nb_logConfig gc; + unsigned nthreads; + nb_thread threads; /* [nthreads] */ +}; + +#if OS_HAS_TSD_USING_THREAD_KEYWORD +__thread nb_thread nb_threadSelf; +#endif + +static void nb__threadReapState(nb_thread thread, + c_bool sync_lease) __nonnull_all__; + +static void* nb__mallocCachelineAligned(os_size_t size) + __attribute_malloc__ + __attribute_returns_nonnull__ + __attribute_assume_aligned__((CACHE_LINE_SIZE)); + +static void nb__freeCachelineAligned(void *ptr) __nonnull_all__; + +static void nb_threadInit(nb_thread thread, + nb_threadStates ts) __nonnull_all__; + +/* Helper function with nb_objectDeinitFunc signature */ +static void nb__threadDeinitFunc(nb_object _this) __nonnull_all__; + +static void nb_threadDeinit(nb_thread _this) __nonnull_all__; + +static int nb_threadStatesFindFreeSlot(nb_threadStates ts, + const char *name) __nonnull_all__; + +static nb_threadStates nb_threadStatesLookup(void) __attribute_returns_nonnull__; + +static void* +nb__mallocCachelineAligned( + os_size_t size) +{ + /* This wastes some space, but we use it only once and it isn't a + huge amount of memory, just a little over a cache line. + Alternatively, we good use valloc() and have it aligned to a page + boundary, but that one isn't part of the O/S abstraction layer ... */ + const os_address clm1 = CACHE_LINE_SIZE - 1; + os_address ptrA; + void **pptr; + void *ptr; + + ptr = os_malloc (size + CACHE_LINE_SIZE + sizeof (void *)); + ptrA = ((os_address) ptr + sizeof (void *) + clm1) & ~clm1; + pptr = (void **) ptrA; + pptr[-1] = ptr; + return (void *) ptrA; +} + +static void +nb__freeCachelineAligned( + void *ptr) +{ + void **pptr = ptr; + os_free (pptr[-1]); +} + +#if 0 +static int +nb__vtime_asleep_p( + nb_vtime vtime) +{ + return (vtime % 2) == 1; +} +#endif + +static void +nb__threadDeinitFunc( + nb_object _this) +{ + nb_objectIsValidKind(_this, NB_OBJECT_THREAD); + + nb_threadDeinit(nb_thread(_this)); +} + + +static void +nb_threadInit( + nb_thread thread, + nb_threadStates ts) +{ + assert(thread); + assert(ts); + + /* Note: memory for all threads is allocated by nb_threadStatesInit in one alloc, aligned to cache-line size, re-usable */ + nb__objectInit(nb_object(thread), NB_OBJECT_THREAD, nb__threadDeinitFunc); + thread->ts = ts; + thread->state = NB_THREAD_STATE_ZERO; + thread->vtime = 1; + thread->watchdog = 1; + thread->logbuf = NULL; + thread->name = NULL; +} + +static void +nb_threadDeinit( + nb_thread _this) +{ + nb_objectIsValidKind(_this, NB_OBJECT_THREAD); + + /* nb_thread objects are reused during service lifespan and all threads must be joined at service exit + * Memory for nb_thread objects is allocated/deallocated once for all threads (see nb_threadStatesInit/Deinit) + * Pointers in nb_thread objects are freed when a thread is joined, so the object can be reused for new threads + * nb_objectFree must be used (as that frees memory of individual objects) + */ + nb__objectDeinit(nb_object(_this)); +} + +nb_threadStates +nb_threadStatesAlloc(void) +{ + nb_threadStates _this = os_malloc(sizeof *_this); + + return _this; +} + +os_result +nb_threadStatesInit( + nb_threadStates _this, + unsigned maxthreads, + nb_logConfig gc) +{ + unsigned i; + + assert(_this); + + if (os_mutexInit(&_this->lock, NULL) != os_resultSuccess) { + goto err_mutexinit; + } + + _this->gc = gc; + _this->nthreads = maxthreads; + _this->threads = nb__mallocCachelineAligned(maxthreads * sizeof(*_this->threads)); + + memset(_this->threads, 0, maxthreads * sizeof(*_this->threads)); + for (i = 0; i < _this->nthreads; i++) { + nb_threadInit(&_this->threads[i], _this); + } + + return os_resultSuccess; + +/* Error handling */ +err_mutexinit: + return os_resultFail; +} + +void +nb_threadStatesDeinit( + nb_threadStates _this) +{ + unsigned i; + + assert(_this); + + for (i = 0; i < _this->nthreads; i++) { + assert(_this->threads[i].state != NB_THREAD_STATE_ALIVE); + nb_threadDeinit(&(_this->threads[i])); + } + + os_mutexDestroy(&_this->lock); + nb__freeCachelineAligned(_this->threads); + + _this->threads = NULL; +} + +void +nb_threadStatesDealloc( + nb_threadStates ts) +{ + assert(ts); + + os_free(ts); +} + +#if 0 +static int +nb_threadEqual( + os_threadId a, + os_threadId b) +{ + os_ulong_int ai = os_threadIdToInteger(a); + os_ulong_int bi = os_threadIdToInteger(b); + return ai == bi; +} +#endif + +static int +nb_threadStatesFindFreeSlot( + nb_threadStates _this, + const char *name) +{ + unsigned i; + int idx; + + assert(_this); + assert(name); + assert(_this->nthreads < OS_MAX_INTEGER(int)); + + for (i = 0, idx = -1; i < _this->nthreads; i++) { + if (_this->threads[i].state != NB_THREAD_STATE_ALIVE) { + idx = (int) i; + } + if (_this->threads[i].state == NB_THREAD_STATE_ZERO) { + break; + } + } + + if (idx == -1) { + OS_REPORT(OS_FATAL, "nb__find_free_slot", idx, + "Unable to find free slot for thread '%s'", + name); + } + + return idx; +} + + +nb_thread +nb_threadLookup (void) +{ + nb_thread *self; +#if OS_HAS_TSD_USING_THREAD_KEYWORD + self = &nb_threadSelf; +#else + self = os_threadMemGet(OS_THREAD_STATE); +#endif + + return self ? *self : NULL; /* May be NULL for non-NB thread (e.g., listeners) */ +} + +nb_logConfig +nb_threadLogConfig( + nb_thread _this) +{ + nb_objectIsValidKind(_this, NB_OBJECT_THREAD); + + return _this->ts->gc; +} + +const char * +nb_threadName( + nb_thread _this) +{ + nb_objectIsValidKind(_this, NB_OBJECT_THREAD); + + return _this->name; +} + +nb_logbuf +nb_threadLogbuf( + nb_thread _this) +{ + nb_objectIsValidKind(_this, NB_OBJECT_THREAD); + + return _this->logbuf; +} + +static nb_threadStates +nb_threadStatesLookup (void) +{ + nb_thread self = nb_threadLookup(); + + /* This call should only be invoked from threads started as nb_thread. + * Listener-threads should never touch code that invokes this. */ + nb_objectIsValidKind(self, NB_OBJECT_THREAD); + + if(!self){ + abort(); + } + + return self->ts; +} + +static void +nb__threadReapState( + nb_thread thread, + c_bool sync_lease) +{ + nb_objectIsValidKind(thread, NB_OBJECT_THREAD); + + OS_UNUSED_ARG(sync_lease); + + os_mutexLock(&thread->ts->lock); + thread->state = NB_THREAD_STATE_ZERO; + + os_free(thread->name); + thread->name = NULL; + + nb_logbufFree(thread, thread->logbuf); + thread->logbuf = NULL; + + os_mutexUnlock(&thread->ts->lock); +} + +void +nb_threadUpgrade( + nb_threadStates ts) +{ + int idx; + nb_thread thread; + + assert(ts); + + os_mutexLock(&ts->lock); + + idx = nb_threadStatesFindFreeSlot(ts, "main"); + + /* There should be free indices, since threads should only be started + * after the main-thread is upgraded. */ + assert(idx >= 0); + + thread = &ts->threads[idx]; + +#if OS_HAS_TSD_USING_THREAD_KEYWORD + assert(nb_threadSelf == NULL); + nb_threadSelf = thread; +#else + { + nb_thread *self; + assert(os_threadMemGet(OS_THREAD_STATE) == NULL); + self = os_threadMemMalloc(OS_THREAD_STATE, sizeof(*self), NULL, NULL); + *self = thread; + } +#endif + + thread->state = NB_THREAD_STATE_ALIVE; + thread->tid = os_threadIdSelf(); + thread->logbuf = nb_logbufNew(); + thread->name = os_strdup("main"); + + os_mutexUnlock(&ts->lock); +} + +void +nb_threadDowngrade( + void) +{ + nb_thread self = nb_threadLookup(); + + nb__threadReapState(self, FALSE); + +#if !OS_HAS_TSD_USING_THREAD_KEYWORD + os_threadMemFree(OS_THREAD_STATE); +#else + nb_threadSelf = NULL; +#endif +} + +os_result +nb_threadJoin( + nb_thread thread, + void **retval) +{ + os_result result; + + nb_objectIsValidKind(thread, NB_OBJECT_THREAD); + + assert(thread->state == NB_THREAD_STATE_ALIVE); + NB_TRACE(("Joining thread '%s'...", thread->name)); + result = os_threadWaitExit(thread->extTid, retval); + NB_TRACE((" %s\n", os_resultImage(result))); + nb__threadReapState(thread, FALSE); + return result; +} + +static void* +nb__threadStartRoutine( + struct nb_threadContext *context) +{ + void *rc; + nb_thread *self; + + assert(context); + +#if OS_HAS_TSD_USING_THREAD_KEYWORD + self = &nb_threadSelf; +#else + assert(os_threadMemGet(OS_THREAD_STATE) == NULL); + self = os_threadMemMalloc(OS_THREAD_STATE, sizeof(*self), NULL, NULL); +#endif + + *self = context->self; + + context->self->tid = os_threadIdSelf(); + rc = context->func(context->arg); + os_free(context); + return rc; +} + +os_result +nb_threadCreate( + const char *name, + nb_thread *thread, + const nb_threadRoutine func, + void *arg) +{ + int idx; + os_threadAttr tattr; + os_threadId tid; + os_result result; + struct nb_threadContext *context; + nb_threadStates ts = nb_threadStatesLookup(); + + assert(ts); + assert(name); + assert(thread); + assert(func); + + context = os_malloc(sizeof *context); + + os_mutexLock(&ts->lock); + + if ((idx = nb_threadStatesFindFreeSlot(ts, name)) < 0) { + /* Error reported by nb__find_free_slot */ + goto err_nofreeslot; + } + + *thread = &(ts->threads[idx]); + + context->self = *thread; + context->func = func; + context->arg = arg; + + if (((*thread)->name = os_strdup(name)) == NULL) { + NB_ERROR_1("nb_threadCreate", "Out of memory while creating thread '%s'\n", name); + goto err_strdup; + } + + if (((*thread)->logbuf = nb_logbufNew()) == NULL) { + /* Error reported by nb_logbufNew */ + goto err_logbufcreate; + } + + os_threadAttrInit(&tattr); + (*thread)->state = NB_THREAD_STATE_ALIVE; + + result = u_serviceThreadCreate(&tid, name, &tattr, (nb_threadRoutine)nb__threadStartRoutine, context); + if (result != os_resultSuccess) { + (*thread)->state = NB_THREAD_STATE_ZERO; + NB_ERROR_2("nb_threadCreate", "Failed to create thread '%s': os_threadCreate returned %s\n", + name, os_resultImage(result)); + goto err_thrcreate; + } + + NB_TRACE(("Created new thread '%s' (%lu, at index %d)\n", name, os_threadIdToInteger(tid), idx)); + (*thread)->extTid = tid; + os_mutexUnlock(&ts->lock); + return os_resultSuccess; + +/* Error handling */ +err_thrcreate: + nb_logbufFree(*thread, (*thread)->logbuf); +err_logbufcreate: + os_free((*thread)->name); +err_strdup: +err_nofreeslot: + os_mutexUnlock(&ts->lock); + os_free(context); + *thread = NULL; + return os_resultFail; +} diff --git a/src/services/nwbridge/code/nb_topic.c b/src/services/nwbridge/code/nb_topic.c new file mode 100644 index 000000000..6f9f3a889 --- /dev/null +++ b/src/services/nwbridge/code/nb_topic.c @@ -0,0 +1,2620 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "nb__topic.h" +#include "nb__service.h" +#include "nb__util.h" +#include "nb__log.h" + +#include "u_writer.h" +#include "ut_collection.h" +#include "c_iterator.h" +#include "c_stringSupport.h" +#include "v_builtin.h" /* for built-in partition and topic names */ + +#include /* for offsetof */ + +typedef struct lenField_s { + c_ulong len; +} lenField; + +/**************** nb_dcpsTopic ****************/ +C_STRUCT(nb_dcpsTopic) { + C_EXTENDS(nb_topicObject); + c_bool interested; + lenField topic_data; + /* This will be used to store a copy of the kernel-struct. Strings are + * strdup'd, sequences are copied as arrays. The length of the arrays is + * maintained in the above lenField's. */ + struct v_topicInfo info; +}; + +static nb_topicObject nb__dcpsTopicAllocFunc(void) __attribute_returns_nonnull__ + __attribute_malloc__; +static v_copyin_result nb__dcpsTopicCopyIn ( + c_type type, + nb_topicObject _from, /* nb_dcpsTopic */ + void * _to /* struct v_topicInfo* */) + __nonnull_all__; + +static u_result nb__dcpsTopicCopyOut( + nb_topicObject _to, /* nb_dcpsTopic */ + const void * _from /* struct v_topicInfo * */) + __nonnull((1)); + +/**************** nb_dcpsParticipant ****************/ +C_STRUCT(nb_dcpsParticipant) { + C_EXTENDS(nb_topicObject); + struct v_participantInfo info; +}; + +static nb_topicObject nb__dcpsParticipantAllocFunc(void) __attribute_returns_nonnull__ + __attribute_malloc__; +static v_copyin_result nb__dcpsParticipantCopyIn ( + c_type type, + nb_topicObject _from, /* nb_dcpsParticipant */ + void * _to /* struct v_participantInfo* */) + __nonnull_all__; + +static u_result nb__dcpsParticipantCopyOut( + nb_topicObject _to, /* nb_dcpsParticipant */ + const void * _from /* struct v_participantInfo* */) + __nonnull((1)); + +/**************** nb_cmParticipant ****************/ +C_STRUCT(nb_cmParticipant) { + C_EXTENDS(nb_topicObject); + struct v_participantCMInfo info; +}; + +static nb_topicObject nb__cmParticipantAllocFunc(void) __attribute_returns_nonnull__ + __attribute_malloc__; +static v_copyin_result nb__cmParticipantCopyIn ( + c_type type, + nb_topicObject _from, /* nb_cmParticipant */ + void * _to /* struct v_topicInfo* */) + __nonnull_all__; + +static u_result nb__cmParticipantCopyOut( + nb_topicObject _to, /* nb_cmParticipant */ + const void * _from /* struct v_topicInfo * */) + __nonnull((1)); + +/**************** nb_dcpsSubscription ****************/ +C_STRUCT(nb_dcpsSubscription) { + C_EXTENDS(nb_topicObject); + c_bool interested; + lenField user_data; + lenField partition; + lenField topic_data; + lenField group_data; + /* This will be used to store a copy of the kernel-struct. Strings are + * strdup'd, sequences are copied as arrays. The length of the arrays is + * maintained in the above lenField's. */ + struct v_subscriptionInfo info; +}; + +static nb_topicObject nb__dcpsSubscriptionAllocFunc(void) __attribute_returns_nonnull__ + __attribute_malloc__; +static v_copyin_result nb__dcpsSubscriptionCopyIn ( + c_type type, + nb_topicObject _from, /* nb_dcpsSubscription */ + void * _to /* struct v_subscriptionInfo* */) + __nonnull_all__; + +static u_result nb__dcpsSubscriptionCopyOut( + nb_topicObject _to, /* nb_dcpsSubscription */ + const void * _from /* struct v_publicationInfo * */) + __nonnull((1)); + +/***************** nb_dcpsPublication ****************/ +C_STRUCT(nb_dcpsPublication) { + C_EXTENDS(nb_topicObject); + c_bool interested; + lenField user_data; + lenField partition; + lenField topic_data; + lenField group_data; + /* This will be used to store a copy of the kernel-struct. Strings are + * strdup'd, sequences are copied as arrays. The length of the arrays is + * maintained in the above lenField's. */ + struct v_publicationInfo info; +}; + +static nb_topicObject nb__dcpsPublicationAllocFunc(void) __attribute_returns_nonnull__ + __attribute_malloc__; +static v_copyin_result nb__dcpsPublicationCopyIn ( + c_type type, + nb_topicObject _from, /* nb_dcpsPublication */ + void * _to /* struct v_publicationInfo* */) + __nonnull_all__; + +static u_result nb__dcpsPublicationCopyOut( + nb_topicObject _to, /* nb_dcpsPublication */ + const void * _from /* struct v_publicationInfo * */) + __nonnull((1)); + + +/******************** nb_cmReader ********************/ +C_STRUCT(nb_cmReader) { + C_EXTENDS(nb_topicObject); + /* This will be used to store a copy of the kernel-struct. Strings are + * strdup'd. */ + struct v_dataReaderCMInfo info; +}; + +static nb_topicObject nb__cmReaderAllocFunc(void) __attribute_returns_nonnull__ + __attribute_malloc__; +static v_copyin_result nb__cmReaderCopyIn ( + c_type type, + nb_topicObject _from, /* nb_cmReader */ + void * _to /* struct v_dataReaderCMInfo* */) + __nonnull_all__; + +static u_result nb__cmReaderCopyOut( + nb_topicObject _to, /* nb_cmReader */ + const void * _from /* struct v_dataReaderCMInfo * */) + __nonnull((1)); + +/******************** nb_cmWriter ********************/ +C_STRUCT(nb_cmWriter) { + C_EXTENDS(nb_topicObject); + /* This will be used to store a copy of the kernel-struct. Strings are + * strdup'd. */ + struct v_dataWriterCMInfo info; +}; + +static nb_topicObject nb__cmWriterAllocFunc(void) __attribute_returns_nonnull__ + __attribute_malloc__; +static v_copyin_result nb__cmWriterCopyIn ( + c_type type, + nb_topicObject _from, /* nb_cmWriter */ + void * _to /* struct v_dataWriterCMInfo* */) + __nonnull_all__; + +static u_result nb__cmWriterCopyOut( + nb_topicObject _to, /* nb_cmWriter */ + const void * _from /* struct v_dataWriterCMInfo * */) + __nonnull((1)); + +/******************** nb_cmPublisher ********************/ +C_STRUCT(nb_cmPublisher) { + C_EXTENDS(nb_topicObject); + lenField partition; + /* This will be used to store a copy of the kernel-struct. Strings are + * strdup'd. */ + struct v_publisherCMInfo info; +}; + +static nb_topicObject nb__cmPublisherAllocFunc(void) __attribute_returns_nonnull__ + __attribute_malloc__; +static v_copyin_result nb__cmPublisherCopyIn ( + c_type type, + nb_topicObject _from, /* nb_cmPublisher */ + void * _to /* struct v_publisherCMInfo* */) + __nonnull_all__; + +static u_result nb__cmPublisherCopyOut( + nb_topicObject _to, /* nb_cmPublisher */ + const void * _from /* struct v_publisherCMInfo * */) + __nonnull((1)); + +/******************** nb_cmSubscriber ********************/ +C_STRUCT(nb_cmSubscriber) { + C_EXTENDS(nb_topicObject); + /* This will be used to store a copy of the kernel-struct. Strings are + * strdup'd. */ + lenField partition; + struct v_subscriberCMInfo info; +}; + +static nb_topicObject nb__cmSubscriberAllocFunc(void) __attribute_returns_nonnull__ + __attribute_malloc__; +static v_copyin_result nb__cmSubscriberCopyIn ( + c_type type, + nb_topicObject _from, /* nb_cmSubscriber */ + void * _to /* struct v_subscriberCMInfo* */) + __nonnull_all__; + +static u_result nb__cmSubscriberCopyOut( + nb_topicObject _to, /* nb_cmSubscriber */ + const void * _from /* struct v_subscriberCMInfo * */) + __nonnull((1)); + +static v_copyin_result +nb__dcpsTopicCopyIn ( + c_type type, + nb_topicObject _from, /* nb_dcpsTopic */ + void * _to /* struct v_topicInfo* */) +{ + const nb_dcpsTopic top = nb_dcpsTopic(_from); + /* This is a *HEAP* copy of the kernel-struct. Strings are malloc'd, + * sequences have an accompanying len and are arrays. */ + struct v_topicInfo const * const from = &top->info; + struct v_topicInfo *to = (struct v_topicInfo *)_to; + c_base base = c_getBase(type); + c_type seqOctetType = NULL; + c_type octetType = c_octet_t(base); + + assert(octetType); + + assert(from); + assert(to); + + *to = *from; + + /* Copy all references by hand; it seems to be impossible to generate + * proper copy-routines on SAC for the kernel-types. */ + to->name = c_stringNew_s(base, from->name); + if(from->name && !to->name){ + /* Out of shared memory; warning reported by memory-manager. */ + goto err_name_copy; + } + + to->type_name = c_stringNew_s(base, from->type_name); + if(from->type_name && !to->type_name){ + /* Out of shared memory; warning reported by memory-manager. */ + goto err_typename_copy; + } + + assert(top->topic_data.len || from->topic_data.value == NULL); + if(top->topic_data.len) { + if(!seqOctetType){ + /* TODO: should be C_SEQUENCE; now it's consistent with the + * comment in kernelModule.h, but it is strange. */ + seqOctetType = c_metaArrayTypeNew(c_metaObject(base), "C_ARRAY", octetType, 0); + } + assert(seqOctetType); /* This should be resolvable, so no need to check */ + to->topic_data.value = c_newArray_s(c_collectionType(seqOctetType), top->topic_data.len); + if (!to->topic_data.value) { + /* Out of shared memory; warning reported by memory-manager. */ + goto err_topic_data_copy; + } + memcpy(to->topic_data.value, from->topic_data.value, top->topic_data.len); + } + + to->meta_data = c_stringNew_s(base, from->meta_data); + if(from->meta_data && !to->meta_data){ + /* Out of shared memory; warning reported by memory-manager. */ + goto err_meta_data_copy; + } + + to->key_list = c_stringNew_s(base, from->key_list); + if(from->key_list && !to->key_list){ + /* Out of shared memory; warning reported by memory-manager. */ + goto err_key_list_copy; + } + + c_free(seqOctetType); + return V_COPYIN_RESULT_OK; + +/* Error handling */ +err_key_list_copy: + c_free(to->meta_data); + to->meta_data = NULL; +err_meta_data_copy: + c_free(to->topic_data.value); + to->topic_data.value = NULL; +err_topic_data_copy: + c_free(to->type_name); + to->type_name = NULL; +err_typename_copy: + c_free(to->name); + to->name = NULL; +err_name_copy: + c_free(seqOctetType); + return V_COPYIN_RESULT_OUT_OF_MEMORY; +} + +static u_result +nb__dcpsTopicCopyOut( + nb_topicObject _to, /* nb_dcpsTopic */ + const void * _from /* struct v_topicInfo * */) +{ + const nb_dcpsTopic top = nb_dcpsTopic(_to); + struct v_topicInfo * const to = &top->info; + struct v_topicInfo const * const from = (struct v_topicInfo *)_from; + + assert(top); + + if(from){ + *to = *from; + + if(from->name) { + to->name = os_strdup(from->name); + } + if(from->type_name) { + to->type_name = os_strdup(from->type_name); + } + + /* topic_data */ + top->topic_data.len = c_sequenceSize(from->topic_data.value); + if(top->topic_data.len) { + to->topic_data.value = os_malloc(top->topic_data.len * sizeof(*to->topic_data.value)); + memcpy(to->topic_data.value, from->topic_data.value, top->topic_data.len * sizeof(*to->topic_data.value)); + } + + if(from->meta_data) { + to->meta_data = os_strdup(from->meta_data); + } + + if(from->key_list){ + to->key_list = os_strdup(from->key_list); + } + + /* Successfully initialized object now; set proper deinit */ + nb__objectSetDeinit(nb_object(top), nb_dcpsTopicDeinit); + } else { + /* Initialize all fields to default values */ + nb_dcpsTopicInit(top); + } + + return U_RESULT_OK; +} + +/* Allocates memory for a new nb_dcpsTopic. This doesn't initialize + * the object fully. */ +nb_dcpsTopic +nb_dcpsTopicAlloc(void) +{ + nb_dcpsTopic _this; + + _this = os_malloc(sizeof *_this); + + /* Only init nb_topicObject */ + nb__topicObjectInit( + (nb_topicObject)_this, + NB_TOPIC_OBJECT_DCPS_TOPIC, + nb__topicObjectDeinit, /* Should be reset to nb_dcpsTopicDeinit after full init by copyOut */ + V_TOPICINFO_NAME, + nb__dcpsTopicCopyOut, + nb__dcpsTopicCopyIn); + + /* TODO: match interest */ + _this->interested = TRUE; + + return _this; +} + +/* nb_topicObjectAllocFunc signature wrapper */ +static nb_topicObject nb__dcpsTopicAllocFunc(void) { return nb_topicObject(nb_dcpsTopicAlloc()); } + +/* Allocates and initializes (to 0) a new nb_dcpsTopic */ +nb_dcpsTopic +nb_dcpsTopicNew(void) +{ + nb_dcpsTopic _this; + + _this = os_malloc(sizeof *_this); + + nb_dcpsTopicInit(_this); + + return _this; +} + +/* Initializes all nb_dcpsTopic fields of _this to 0. */ +void +nb_dcpsTopicInit( + nb_dcpsTopic _this) +{ + assert(_this); + + /* Super-init */ + nb__topicObjectInit( + nb_topicObject(_this), + NB_TOPIC_OBJECT_DCPS_TOPIC, + nb_dcpsTopicDeinit, + V_TOPICINFO_NAME, + nb__dcpsTopicCopyOut, + nb__dcpsTopicCopyIn); + + /* This compile-time constraint assures that _parent is the first member + * of nb_serviceTopic and thus sizeof(_this->_parent) can be used + * to determine the offset. */ + { + struct nb_dcpsTopic_parent_offset_constraint { + char _parent_member_at_offset_0 [offsetof(C_STRUCT(nb_dcpsTopic), _parent) == 0]; + char non_empty_dummy_last_member[1]; + }; + } + + /* Only memset the non-_parent part */ + memset((void*)((os_address)_this + sizeof(_this->_parent)), 0, sizeof(*_this) - sizeof(_this->_parent)); + + /* TODO: match interest */ + _this->interested = TRUE; +} + +void +nb_dcpsTopicDeinit( + nb_object o /* nb_dcpsTopic */) +{ + nb_dcpsTopic _this = nb_dcpsTopic(o); + + assert(_this); + + /* Object-deinit */ + os_free(_this->info.name); + os_free(_this->info.type_name); + os_free(_this->info.topic_data.value); + os_free(_this->info.meta_data); + os_free(_this->info.key_list); + + /* Super-deinit */ + nb__topicObjectDeinit(o); +} + +#ifndef NDEBUG +/* Type-checking free function */ +void +nb_dcpsTopicFree ( + nb_dcpsTopic _this) +{ + if(_this){ + nb_objectIsValidKind(_this, NB_TOPIC_OBJECT_DCPS_TOPIC); + nb_objectFree(_this); + } +} +#endif /* NDEBUG */ + +const c_char * +nb_dcpsTopicTopicName( + nb_dcpsTopic _this) +{ + nb_objectIsValidKind(_this, NB_TOPIC_OBJECT_DCPS_TOPIC); + + return _this->info.name; +} + +const v_builtinTopicKey * +nb_dcpsTopicKey( + nb_dcpsTopic _this) +{ + nb_objectIsValidKind(_this, NB_TOPIC_OBJECT_DCPS_TOPIC); + + return &_this->info.key; +} + +v_actionResult +nb_dcpsTopicReaderAction( + c_object o, + c_voidp copyArg /* c_iter * */) +{ + return nb_topicObjectReaderAction(o, copyArg, nb__dcpsTopicAllocFunc); +} + + +static v_copyin_result +nb__dcpsParticipantCopyIn ( + c_type type, + nb_topicObject _from, /* nb_dcpsParticipant */ + void * _to /* struct v_participantInfo* */) +{ + const nb_dcpsParticipant part = nb_dcpsParticipant(_from); + /* This is a *HEAP* copy of the kernel-struct. Strings are malloc'd, + * sequences have an accompanying len and are arrays. */ + struct v_participantInfo const * const from = &part->info; + struct v_participantInfo *to = (struct v_participantInfo *)_to; + c_base base = c_getBase(type); + c_type seqOctetType = NULL; + c_type octetType = c_octet_t(base); + + assert(octetType); + + assert(from); + assert(to); + + *to = *from; + + assert(from->user_data.size || from->user_data.value == NULL); + if(from->user_data.size) { + if(!seqOctetType){ + /* TODO: should be C_SEQUENCE; now it's consistent with the + * comment in kernelModule.h, but it is strange. */ + seqOctetType = c_metaArrayTypeNew(c_metaObject(base), "C_ARRAY", octetType, 0); + } + assert(seqOctetType); /* This should be resolvable, so no need to check */ + assert(from->user_data.size >= 0); + to->user_data.value = c_newArray_s(c_collectionType(seqOctetType), (c_ulong)from->user_data.size); + if (!to->user_data.value) { + /* Out of shared memory; warning reported by memory-manager. */ + goto err_user_data_copy; + } + memcpy(to->user_data.value, from->user_data.value, (c_ulong)from->user_data.size); + } + + c_free(seqOctetType); + return V_COPYIN_RESULT_OK; + +/* Error handling */ +err_user_data_copy: + c_free(seqOctetType); + return V_COPYIN_RESULT_OUT_OF_MEMORY; +} + +static u_result +nb__dcpsParticipantCopyOut( + nb_topicObject _to, /* nb_dcpsParticipant */ + const void * _from /* struct v_participantInfo * */) +{ + const nb_dcpsParticipant part = nb_dcpsParticipant(_to); + struct v_participantInfo * const to = &part->info; + struct v_participantInfo const * const from = (struct v_participantInfo *)_from; + + assert(part); + + if(from){ + *to = *from; + + /* user_data */ + assert(from->user_data.size || from->user_data.value == NULL); + + if(from->user_data.size > 0) { + to->user_data.value = os_malloc((c_ulong)from->user_data.size); + memcpy(to->user_data.value, from->user_data.value, (c_ulong)from->user_data.size); + } + + /* Successfully initialized object now; set proper deinit */ + nb__objectSetDeinit(nb_object(part), nb_dcpsParticipantDeinit); + } else { + /* Initialize all fields to default values */ + nb_dcpsParticipantInit(part); + } + + return U_RESULT_OK; +} + +/* Allocates memory for a new nb_dcpsParticipant. This doesn't initialize + * the object fully. */ +nb_dcpsParticipant +nb_dcpsParticipantAlloc(void) +{ + nb_dcpsParticipant _this; + + _this = os_malloc(sizeof *_this); + + /* Only init nb_topicObject */ + nb__topicObjectInit( + (nb_topicObject)_this, + NB_TOPIC_OBJECT_DCPS_PARTICIPANT, + nb__topicObjectDeinit, /* Should be reset to nb_dcpsParticipantDeinit after full init by copyOut */ + V_PARTICIPANTINFO_NAME, + nb__dcpsParticipantCopyOut, + nb__dcpsParticipantCopyIn); + + return _this; +} + +/* nb_topicObjectAllocFunc signature wrapper */ +static nb_topicObject nb__dcpsParticipantAllocFunc(void) { return nb_topicObject(nb_dcpsParticipantAlloc()); } + +/* Allocates and initializes (to 0) a new nb_dcpsParticipant */ +nb_dcpsParticipant +nb_dcpsParticipantNew(void) +{ + nb_dcpsParticipant _this; + + _this = os_malloc(sizeof *_this); + + nb_dcpsParticipantInit(_this); + + return _this; +} + +/* Initializes all nb_dcpsParticipant fields of _this to 0. */ +void +nb_dcpsParticipantInit( + nb_dcpsParticipant _this) +{ + assert(_this); + + /* Super-init */ + nb__topicObjectInit( + nb_topicObject(_this), + NB_TOPIC_OBJECT_DCPS_PARTICIPANT, + nb_dcpsParticipantDeinit, + V_PARTICIPANTINFO_NAME, + nb__dcpsParticipantCopyOut, + nb__dcpsParticipantCopyIn); + + /* This compile-time constraint assures that _parent is the first member + * of nb_serviceParticipant and thus sizeof(_this->_parent) can be used + * to determine the offset. */ + { + struct nb_dcpsParticipant_parent_offset_constraint { + char _parent_member_at_offset_0 [offsetof(C_STRUCT(nb_dcpsParticipant), _parent) == 0]; + char non_empty_dummy_last_member[1]; + }; + } + + /* Only memset the non-_parent part */ + memset((void*)((os_address)_this + sizeof(_this->_parent)), 0, sizeof(*_this) - sizeof(_this->_parent)); +} + +void +nb_dcpsParticipantDeinit( + nb_object o /* nb_dcpsParticipant */) +{ + nb_dcpsParticipant _this = nb_dcpsParticipant(o); + + assert(_this); + + /* Object-deinit */ + os_free(_this->info.user_data.value); + + /* Super-deinit */ + nb__topicObjectDeinit(o); +} + +#ifndef NDEBUG +/* Type-checking free function */ +void +nb_dcpsParticipantFree ( + nb_dcpsParticipant _this) +{ + if(_this){ + nb_objectIsValidKind(_this, NB_TOPIC_OBJECT_DCPS_PARTICIPANT); + nb_objectFree(_this); + } +} +#endif /* NDEBUG */ + +const v_builtinTopicKey * +nb_dcpsParticipantKey( + nb_dcpsParticipant _this) +{ + nb_objectIsValidKind(_this, NB_TOPIC_OBJECT_DCPS_PARTICIPANT); + + return &_this->info.key; +} + +v_actionResult +nb_dcpsParticipantReaderAction( + c_object o, + c_voidp copyArg /* c_iter * */) +{ + return nb_topicObjectReaderAction(o, copyArg, nb__dcpsParticipantAllocFunc); +} + +static v_copyin_result +nb__cmParticipantCopyIn ( + c_type type, + nb_topicObject _from, /* nb_cmParticipant */ + void * _to /* struct v_participantCMInfo* */) +{ + const nb_cmParticipant part = nb_cmParticipant(_from); + /* This is a *HEAP* copy of the kernel-struct. Strings are malloc'd, + * sequences have an accompanying len and are arrays. */ + struct v_participantCMInfo const * const from = &part->info; + struct v_participantCMInfo *to = (struct v_participantCMInfo *)_to; + c_base base = c_getBase(type); + + assert(from); + assert(to); + + *to = *from; + + /* Copy all references by hand; it seems to be impossible to generate + * proper copy-routines on SAC for the kernel-types. */ + to->product.value = c_stringNew_s(base, from->product.value); + if(from->product.value && !to->product.value){ + /* Out of shared memory; warning reported by memory-manager. */ + goto err_product_copy; + }; + + return V_COPYIN_RESULT_OK; + +/* Error handling */ +err_product_copy: + return V_COPYIN_RESULT_OUT_OF_MEMORY; +} + +static u_result +nb__cmParticipantCopyOut( + nb_topicObject _to, /* nb_cmParticipant */ + const void * _from /* struct v_participantInfo * */) +{ + const nb_cmParticipant part = nb_cmParticipant(_to); + struct v_participantCMInfo * const to = &part->info; + struct v_participantCMInfo const * const from = (struct v_participantCMInfo *)_from; + + assert(part); + + if(from){ + *to = *from; + + if(from->product.value){ + to->product.value = os_strdup(from->product.value); + } + + /* Successfully initialized object now; set proper deinit */ + nb__objectSetDeinit(nb_object(part), nb_cmParticipantDeinit); + } else { + /* Initialize all fields to default values */ + nb_cmParticipantInit(part); + } + + return U_RESULT_OK; +} + +/* Allocates memory for a new nb_cmParticipant. This doesn't initialize + * the object fully. */ +nb_cmParticipant +nb_cmParticipantAlloc(void) +{ + nb_cmParticipant _this; + + _this = os_malloc(sizeof *_this); + + /* Only init nb_topicObject */ + nb__topicObjectInit( + (nb_topicObject)_this, + NB_TOPIC_OBJECT_CM_PARTICIPANT, + nb__topicObjectDeinit, /* Should be reset to nb_cmParticipantDeinit after full init by copyOut */ + V_CMPARTICIPANTINFO_NAME, + nb__cmParticipantCopyOut, + nb__cmParticipantCopyIn); + + return _this; +} + +/* nb_topicObjectAllocFunc signature wrapper */ +static nb_topicObject +nb__cmParticipantAllocFunc(void) +{ + return nb_topicObject(nb_cmParticipantAlloc()); +} + + +/* Allocates and initializes (to 0) a new nb_cmParticipant */ +nb_cmParticipant +nb_cmParticipantNew(void) +{ + nb_cmParticipant _this; + + _this = os_malloc(sizeof *_this); + + nb_cmParticipantInit(_this); + + return _this; +} + +/* Initializes all nb_cmParticipant fields of _this to 0. */ +void +nb_cmParticipantInit( + nb_cmParticipant _this) +{ + assert(_this); + + /* Super-init */ + nb__topicObjectInit( + nb_topicObject(_this), + NB_TOPIC_OBJECT_CM_PARTICIPANT, + nb_cmParticipantDeinit, + V_CMPARTICIPANTINFO_NAME, + nb__cmParticipantCopyOut, + nb__cmParticipantCopyIn); + + /* This compile-time constraint assures that _parent is the first member + * of nb_serviceParticipant and thus sizeof(_this->_parent) can be used + * to determine the offset. */ + { + struct nb_cmParticipant_parent_offset_constraint { + char _parent_member_at_offset_0 [offsetof(C_STRUCT(nb_cmParticipant), _parent) == 0]; + char non_empty_dummy_last_member[1]; + }; + } + + /* Only memset the non-_parent part */ + memset((void*)((os_address)_this + sizeof(_this->_parent)), 0, sizeof(*_this) - sizeof(_this->_parent)); +} + +void +nb_cmParticipantDeinit( + nb_object o /* nb_cmParticipant */) +{ + nb_cmParticipant _this = nb_cmParticipant(o); + + assert(_this); + + /* Object-deinit */ + os_free(_this->info.product.value); + + /* Super-deinit */ + nb__topicObjectDeinit(o); +} + +#ifndef NDEBUG +/* Type-checking free function */ +void +nb_cmParticipantFree ( + nb_cmParticipant _this) +{ + if(_this){ + nb_objectIsValidKind(_this, NB_TOPIC_OBJECT_CM_PARTICIPANT); + nb_objectFree(_this); + } +} +#endif /* NDEBUG */ + +const v_builtinTopicKey * +nb_cmParticipantKey( + nb_cmParticipant _this) +{ + nb_objectIsValidKind(_this, NB_TOPIC_OBJECT_CM_PARTICIPANT); + + return &_this->info.key; +} + +v_actionResult +nb_cmParticipantReaderAction( + c_object o, + c_voidp copyArg /* c_iter * */) +{ + return nb_topicObjectReaderAction(o, copyArg, nb__cmParticipantAllocFunc); +} + +static v_copyin_result +nb__dcpsSubscriptionCopyIn ( + c_type type, + nb_topicObject _from, /* nb_dcpsSubscription */ + void * _to /* struct v_subscriptionInfo* */) +{ + const nb_dcpsSubscription sub = nb_dcpsSubscription(_from); + /* This is a *HEAP* copy of the kernel-struct. Strings are malloc'd, + * sequences have an accompanying len and are arrays. */ + struct v_subscriptionInfo const * const from = &sub->info; + struct v_subscriptionInfo *to = (struct v_subscriptionInfo *)_to; + c_base base = c_getBase(type); + c_type seqOctetType = NULL; + c_type octetType = c_octet_t(base); + c_type stringType = c_string_t(base); + c_type seqStringType; + + assert(octetType); + assert(stringType); + + assert(from); + assert(to); + + *to = *from; + + /* Copy all references by hand; it seems to be impossible to generate + * proper copy-routines on SAC for the kernel-types. */ + to->topic_name = c_stringNew_s(base, from->topic_name); + if(from->topic_name && !to->topic_name){ + /* Out of shared memory; warning reported by memory-manager. */ + goto err_topicname_copy; + } + + to->type_name = c_stringNew_s(base, from->type_name); + if(from->type_name && !to->type_name){ + /* Out of shared memory; warning reported by memory-manager. */ + goto err_typename_copy; + } + + assert(sub->user_data.len || from->user_data.value == NULL); + if(sub->user_data.len) { + if(!seqOctetType){ + /* TODO: should be C_SEQUENCE; now it's consistent with the + * comment in kernelModule.h, but it is strange. */ + seqOctetType = c_metaArrayTypeNew(c_metaObject(base), "C_ARRAY", octetType, 0); + } + assert(seqOctetType); /* This should be resolvable, so no need to check */ + to->user_data.value = c_newArray_s(c_collectionType(seqOctetType), sub->user_data.len); + if (!to->user_data.value) { + /* Out of shared memory; warning reported by memory-manager. */ + goto err_user_data_copy; + } + memcpy(to->user_data.value, from->user_data.value, sub->user_data.len); + } + + assert(sub->partition.len || from->partition.name == NULL); + if(sub->partition.len) { + seqStringType = c_metaSequenceTypeNew(c_metaObject(base), "C_SEQUENCE", stringType, 0); + assert(seqStringType); /* This should be resolvable, so no need to check */ + to->partition.name = c_newSequence_s(c_collectionType(seqStringType), sub->partition.len); + c_free(seqStringType); + if (!to->partition.name) { + /* Out of shared memory; warning reported by memory-manager. */ + goto err_partition_seq_new; + } + + { + c_ulong i; + + for(i = 0; i < sub->partition.len; i++){ + to->partition.name[i] = c_stringNew_s(base, from->partition.name[i]); + if(from->partition.name[i] && !to->partition.name[i]){ + /* Out of shared memory; warning reported by memory-manager. */ + goto err_partition_copy; + } + } + } + } + + assert(sub->topic_data.len || from->topic_data.value == NULL); + if(sub->topic_data.len) { + if(!seqOctetType){ + /* TODO: should be C_SEQUENCE; now it's consistent with the + * comment in kernelModule.h, but it is strange. */ + seqOctetType = c_metaArrayTypeNew(c_metaObject(base), "C_ARRAY", octetType, 0); + } + assert(seqOctetType); /* This should be resolvable, so no need to check */ + to->topic_data.value = c_newArray_s(c_collectionType(seqOctetType), sub->topic_data.len); + if (!to->topic_data.value) { + /* Out of shared memory; warning reported by memory-manager. */ + goto err_topic_data_copy; + } + memcpy(to->topic_data.value, from->topic_data.value, sub->topic_data.len); + } + + assert(sub->group_data.len || from->group_data.value == NULL); + if(sub->group_data.len) { + if(!seqOctetType){ + /* TODO: should be C_SEQUENCE; now it's consistent with the + * comment in kernelModule.h, but it is strange. */ + seqOctetType = c_metaArrayTypeNew(c_metaObject(base), "C_ARRAY", octetType, 0); + } + assert(seqOctetType); /* This should be resolvable, so no need to check */ + to->group_data.value = c_newArray_s(c_collectionType(seqOctetType), sub->group_data.len); + if (!to->group_data.value) { + /* Out of shared memory; warning reported by memory-manager. */ + goto err_group_data_copy; + } + memcpy(to->group_data.value, from->group_data.value, sub->group_data.len); + } + + c_free(seqOctetType); + return V_COPYIN_RESULT_OK; + +err_group_data_copy: + c_free(to->topic_data.value); + to->topic_data.value = NULL; +err_topic_data_copy: + /* Sequence-members are freed by c_free */ +err_partition_copy: + c_free(to->partition.name); + to->partition.name = NULL; +err_partition_seq_new: + c_free(to->user_data.value); + to->user_data.value = NULL; +err_user_data_copy: + c_free(to->type_name); + to->type_name = NULL; +err_typename_copy: + c_free(to->topic_name); + to->topic_name = NULL; +err_topicname_copy: + c_free(seqOctetType); + return V_COPYIN_RESULT_OUT_OF_MEMORY; +} + +static u_result +nb__dcpsSubscriptionCopyOut( + nb_topicObject _to, /* nb_dcpsSubscription */ + const void * _from /* struct v_subscribtionInfo * */) +{ + const nb_dcpsSubscription sub = nb_dcpsSubscription(_to); + struct v_subscriptionInfo * const to = &sub->info; + struct v_subscriptionInfo const * const from = (struct v_subscriptionInfo *)_from; + + assert(sub); + + if(from){ + *to = *from; + + if(from->topic_name) { + to->topic_name = os_strdup(from->topic_name); + } + + if(from->type_name) { + to->type_name = os_strdup(from->type_name); + } + + /* user_data */ + sub->user_data.len = c_sequenceSize(from->user_data.value); + if(sub->user_data.len) { + to->user_data.value = os_malloc(sub->user_data.len * sizeof(*to->user_data.value)); + memcpy(to->user_data.value, from->user_data.value, sub->user_data.len * sizeof(*to->user_data.value)); + } + + /* partition */ + sub->partition.len = c_arraySize(from->partition.name); + if(sub->partition.len){ + c_ulong i; + + to->partition.name = os_malloc(sub->partition.len * sizeof(*to->partition.name)); + + for(i = 0; i < sub->partition.len; i++){ + assert(from->partition.name[i]); + to->partition.name[i] = os_strdup(from->partition.name[i]); + } + } + + /* topic_data */ + sub->topic_data.len = c_sequenceSize(from->topic_data.value); + if(sub->topic_data.len) { + to->topic_data.value = os_malloc(sub->topic_data.len * sizeof(*to->topic_data.value)); + memcpy(to->topic_data.value, from->topic_data.value, sub->topic_data.len * sizeof(*to->topic_data.value)); + } + + /* group_data */ + sub->group_data.len = c_sequenceSize(from->group_data.value); + if(sub->group_data.len) { + to->group_data.value = os_malloc(sub->group_data.len * sizeof(*to->group_data.value)); + memcpy(to->group_data.value, from->group_data.value, sub->group_data.len * sizeof(*to->group_data.value)); + } + + /* Successfully initialized object now; set proper deinit */ + nb__objectSetDeinit(nb_object(sub), nb_dcpsSubscriptionDeinit); + } else { + /* Initialize all fields to default values */ + nb_dcpsSubscriptionInit(sub); + } + + return U_RESULT_OK; +} + +/* Allocates memory for a new nb_dcpsSubscription. This doesn't initialize + * the object fully. */ +nb_dcpsSubscription +nb_dcpsSubscriptionAlloc(void) +{ + nb_dcpsSubscription _this; + + _this = os_malloc(sizeof *_this); + + /* Only init nb_topicObject */ + nb__topicObjectInit( + (nb_topicObject)_this, + NB_TOPIC_OBJECT_DCPS_SUBSCRIPTION, + nb__topicObjectDeinit, /* Should be reset to nb_dcpsSubscriptionDeinit after full init by copyOut */ + V_SUBSCRIPTIONINFO_NAME, + nb__dcpsSubscriptionCopyOut, + nb__dcpsSubscriptionCopyIn); + + /* TODO: match interest */ + _this->interested = TRUE; + + return _this; +} + +/* nb_topicObjectAllocFunc signature wrapper */ +static nb_topicObject nb__dcpsSubscriptionAllocFunc(void) { return nb_topicObject(nb_dcpsSubscriptionAlloc()); } + +/* Allocates and initializes (to 0) a new nb_dcpsSubscription */ +nb_dcpsSubscription +nb_dcpsSubscriptionNew(void) +{ + nb_dcpsSubscription _this; + + _this = os_malloc(sizeof *_this); + + nb_dcpsSubscriptionInit(_this); + + return _this; +} + +/* Initializes all nb_dcpsSubscription fields of _this to 0. */ +void +nb_dcpsSubscriptionInit( + nb_dcpsSubscription _this) +{ + assert(_this); + + /* Super-init */ + nb__topicObjectInit( + nb_topicObject(_this), + NB_TOPIC_OBJECT_DCPS_SUBSCRIPTION, + nb_dcpsSubscriptionDeinit, + V_SUBSCRIPTIONINFO_NAME, + nb__dcpsSubscriptionCopyOut, + nb__dcpsSubscriptionCopyIn); + + /* This compile-time constraint assures that _parent is the first member + * of nb_serviceSubscription and thus sizeof(_this->_parent) can be used + * to determine the offset. */ + { + struct nb_dcpsSubscription_parent_offset_constraint { + char _parent_member_at_offset_0 [offsetof(C_STRUCT(nb_dcpsSubscription), _parent) == 0]; + char non_empty_dummy_last_member[1]; + }; + } + + /* Only memset the non-_parent part */ + memset((void*)((os_address)_this + sizeof(_this->_parent)), 0, sizeof(*_this) - sizeof(_this->_parent)); + + /* TODO: match interest */ + _this->interested = TRUE; +} + +void +nb_dcpsSubscriptionDeinit( + nb_object o /* nb_dcpsSubscription */) +{ + nb_dcpsSubscription _this = nb_dcpsSubscription(o); + + assert(_this); + + /* Object-deinit */ + os_free(_this->info.topic_name); + os_free(_this->info.type_name); + os_free(_this->info.user_data.value); + + /* partition */ + { + c_ulong i; + + for(i = 0; i < _this->partition.len; i++){ + os_free(_this->info.partition.name[i]); + } + os_free(_this->info.partition.name); + } + os_free(_this->info.topic_data.value); + os_free(_this->info.group_data.value); + + /* Super-deinit */ + nb__topicObjectDeinit(o); +} + +#ifndef NDEBUG +/* Type-checking free function */ +void +nb_dcpsSubscriptionFree ( + nb_dcpsSubscription _this) +{ + if(_this){ + nb_objectIsValidKind(_this, NB_TOPIC_OBJECT_DCPS_SUBSCRIPTION); + nb_objectFree(_this); + } +} +#endif /* NDEBUG */ + + +const c_char * +nb_dcpsSubscriptionTopicName( + nb_dcpsSubscription _this) +{ + nb_objectIsValidKind(_this, NB_TOPIC_OBJECT_DCPS_SUBSCRIPTION); + + return _this->info.topic_name; +} + +const v_builtinTopicKey * +nb_dcpsSubscriptionKey( + nb_dcpsSubscription _this) +{ + nb_objectIsValidKind(_this, NB_TOPIC_OBJECT_DCPS_SUBSCRIPTION); + + return &_this->info.key; +} + +const v_builtinTopicKey * +nb_dcpsSubscriptionParticipantKey( + nb_dcpsSubscription _this) +{ + nb_objectIsValidKind(_this, NB_TOPIC_OBJECT_DCPS_SUBSCRIPTION); + + return &_this->info.participant_key; +} + +const char * const * +nb_dcpsSubscriptionPartitions( + nb_dcpsSubscription _this, + c_ulong *len) +{ + nb_objectIsValidKind(_this, NB_TOPIC_OBJECT_DCPS_SUBSCRIPTION); + assert(len); + + *len = _this->partition.len; + + return (const char * const *) _this->info.partition.name; +} + +c_bool +nb_dcpsSubscriptionGetInterested( + nb_dcpsSubscription _this) +{ + nb_objectIsValidKind(_this, NB_TOPIC_OBJECT_DCPS_SUBSCRIPTION); + + return _this->interested; +} + +void +nb_dcpsSubscriptionSetInterested( + nb_dcpsSubscription _this, + const char * const * includes, + const char * const * excludes) +{ + c_bool interested; + + nb_objectIsValidKind(_this, NB_TOPIC_OBJECT_DCPS_SUBSCRIPTION); + assert(includes); + assert(excludes); + + interested = nb_match( + (const char * const *)_this->info.partition.name, + _this->partition.len, + nb_dcpsSubscriptionTopicName(_this), + includes, + excludes); + + NB_TRACE(("nb_dcpsSubscription={key="NB_KEYFMT"} %s interest for forwarding of %s for topic \'%s\'\n", + v_gidSystemId(*nb_dcpsSubscriptionKey(_this)), + v_gidLocalId(*nb_dcpsSubscriptionKey(_this)), + interested ? "matches" : "doesn't match", + nb_topicObjectName(nb_topicObject(_this)), + nb_dcpsSubscriptionTopicName(_this) + )); + + _this->interested = interested; +} + +v_actionResult +nb_dcpsSubscriptionReaderAction( + c_object o, + c_voidp copyArg /* c_iter * */) +{ + return nb_topicObjectReaderAction(o, copyArg, nb__dcpsSubscriptionAllocFunc); +} + +/* nb_dcpsPublication */ +static v_copyin_result +nb__dcpsPublicationCopyIn ( + c_type type, + nb_topicObject _from, /* nb_dcpsPublication */ + void * _to /* struct v_publicationInfo* */) +{ + const nb_dcpsPublication pub = nb_dcpsPublication(_from); + /* This is a *HEAP* copy of the kernel-struct. Strings are malloc'd, + * sequences have an accompanying len and are arrays. */ + struct v_publicationInfo const * const from = &pub->info; + struct v_publicationInfo *to = (struct v_publicationInfo *)_to; + c_base base = c_getBase(type); + c_type seqOctetType = NULL; + c_type octetType = c_octet_t(base); + c_type stringType = c_string_t(base); + c_type seqStringType; + + assert(octetType); + assert(stringType); + + assert(from); + assert(to); + + *to = *from; + + /* Copy all references by hand; it seems to be impossible to generate + * proper copy-routines on SAC for the kernel-types. */ + to->topic_name = c_stringNew_s(base, from->topic_name); + if(from->topic_name && !to->topic_name){ + /* Out of shared memory; warning reported by memory-manager. */ + goto err_topicname_copy; + } + + to->type_name = c_stringNew_s(base, from->type_name); + if(from->type_name && !to->type_name){ + /* Out of shared memory; warning reported by memory-manager. */ + goto err_typename_copy; + } + + assert(pub->user_data.len || from->user_data.value == NULL); + if(pub->user_data.len) { + if(!seqOctetType){ + /* TODO: should be C_SEQUENCE; now it's consistent with the + * comment in kernelModule.h, but it is strange. */ + seqOctetType = c_metaArrayTypeNew(c_metaObject(base), "C_ARRAY", octetType, 0); + } + assert(seqOctetType); /* This should be resolvable, so no need to check */ + to->user_data.value = c_newArray_s(c_collectionType(seqOctetType), pub->user_data.len); + if (!to->user_data.value) { + /* Out of shared memory; warning reported by memory-manager. */ + goto err_user_data_copy; + } + memcpy(to->user_data.value, from->user_data.value, pub->user_data.len); + } + + assert(pub->partition.len || from->partition.name == NULL); + if(pub->partition.len) { + seqStringType = c_metaSequenceTypeNew(c_metaObject(base), "C_SEQUENCE", stringType, 0); + assert(seqStringType); /* This should be resolvable, so no need to check */ + to->partition.name = c_newSequence_s(c_collectionType(seqStringType), pub->partition.len); + c_free(seqStringType); + if (!to->partition.name) { + /* Out of shared memory; warning reported by memory-manager. */ + goto err_partition_seq_new; + } + + { + c_ulong i; + + for(i = 0; i < pub->partition.len; i++){ + to->partition.name[i] = c_stringNew_s(base, from->partition.name[i]); + if(from->partition.name[i] && !to->partition.name[i]){ + /* Out of shared memory; warning reported by memory-manager. */ + goto err_partition_copy; + } + } + } + } + + assert(pub->topic_data.len || from->topic_data.value == NULL); + if(pub->topic_data.len) { + if(!seqOctetType){ + /* TODO: should be C_SEQUENCE; now it's consistent with the + * comment in kernelModule.h, but it is strange. */ + seqOctetType = c_metaArrayTypeNew(c_metaObject(base), "C_ARRAY", octetType, 0); + } + assert(seqOctetType); /* This should be resolvable, so no need to check */ + to->topic_data.value = c_newArray_s(c_collectionType(seqOctetType), pub->topic_data.len); + if (!to->topic_data.value) { + /* Out of shared memory; warning reported by memory-manager. */ + goto err_topic_data_copy; + } + memcpy(to->topic_data.value, from->topic_data.value, pub->topic_data.len); + } + + assert(pub->group_data.len || from->group_data.value == NULL); + if(pub->group_data.len) { + if(!seqOctetType){ + /* TODO: should be C_SEQUENCE; now it's consistent with the + * comment in kernelModule.h, but it is strange. */ + seqOctetType = c_metaArrayTypeNew(c_metaObject(base), "C_ARRAY", octetType, 0); + } + assert(seqOctetType); /* This should be resolvable, so no need to check */ + to->group_data.value = c_newArray_s(c_collectionType(seqOctetType), pub->group_data.len); + if (!to->group_data.value) { + /* Out of shared memory; warning reported by memory-manager. */ + goto err_group_data_copy; + } + memcpy(to->group_data.value, from->group_data.value, pub->group_data.len); + } + + c_free(seqOctetType); + return V_COPYIN_RESULT_OK; + +err_group_data_copy: + c_free(to->topic_data.value); + to->topic_data.value = NULL; +err_topic_data_copy: + /* Sequence-members are freed by c_free */ +err_partition_copy: + c_free(to->partition.name); + to->partition.name = NULL; +err_partition_seq_new: + c_free(to->user_data.value); + to->user_data.value = NULL; +err_user_data_copy: + c_free(to->type_name); + to->type_name = NULL; +err_typename_copy: + c_free(to->topic_name); + to->topic_name = NULL; +err_topicname_copy: + c_free(seqOctetType); + return V_COPYIN_RESULT_OUT_OF_MEMORY; +} + +static u_result +nb__dcpsPublicationCopyOut( + nb_topicObject _to, /* nb_dcpsPublication */ + const void * _from /* struct v_publicationInfo * */) +{ + const nb_dcpsPublication pub = nb_dcpsPublication(_to); + struct v_publicationInfo * const to = &pub->info; + struct v_publicationInfo const * const from = (struct v_publicationInfo *)_from; + + assert(pub); + + if(from){ + *to = *from; + + if(from->topic_name) { + to->topic_name = os_strdup(from->topic_name); + } + if(from->type_name) { + to->type_name = os_strdup(from->type_name); + } + + /* user_data */ + pub->user_data.len = c_sequenceSize(from->user_data.value); + if(pub->user_data.len) { + to->user_data.value = os_malloc(pub->user_data.len * sizeof(*to->user_data.value)); + memcpy(to->user_data.value, from->user_data.value, pub->user_data.len * sizeof(*to->user_data.value)); + } + + /* partition */ + pub->partition.len = c_arraySize(from->partition.name); + if(pub->partition.len){ + c_ulong i; + + to->partition.name = os_malloc(pub->partition.len * sizeof(*to->partition.name)); + + for(i = 0; i < pub->partition.len; i++){ + assert(from->partition.name[i]); + to->partition.name[i] = os_strdup(from->partition.name[i]); + } + } + + /* topic_data */ + pub->topic_data.len = c_sequenceSize(from->topic_data.value); + if(pub->topic_data.len) { + to->topic_data.value = os_malloc(pub->topic_data.len * sizeof(*to->topic_data.value)); + memcpy(to->topic_data.value, from->topic_data.value, pub->topic_data.len * sizeof(*to->topic_data.value)); + } + + /* group_data */ + pub->group_data.len = c_sequenceSize(from->group_data.value); + if(pub->group_data.len) { + to->group_data.value = os_malloc(pub->group_data.len * sizeof(*to->group_data.value)); + memcpy(to->group_data.value, from->group_data.value, pub->group_data.len * sizeof(*to->group_data.value)); + } + + /* Successfully initialized object now; set proper deinit */ + nb__objectSetDeinit(nb_object(pub), nb_dcpsPublicationDeinit); + } else { + /* Initialize all fields to default values */ + nb_dcpsPublicationInit(pub); + } + + return U_RESULT_OK; +} + +/* Allocates memory for a new nb_dcpsPublication. This doesn't initialize + * the object fully. */ +nb_dcpsPublication +nb_dcpsPublicationAlloc(void) +{ + nb_dcpsPublication _this; + + _this = os_malloc(sizeof *_this); + + /* Only init nb_topicObject */ + nb__topicObjectInit( + (nb_topicObject)_this, + NB_TOPIC_OBJECT_DCPS_PUBLICATION, + nb__topicObjectDeinit, /* Should be reset to nb_dcpsPublicationDeinit after full init by copyOut */ + V_PUBLICATIONINFO_NAME, + nb__dcpsPublicationCopyOut, + nb__dcpsPublicationCopyIn); + + return _this; +} + +/* nb_topicObjectAllocFunc signature wrapper */ +static nb_topicObject nb__dcpsPublicationAllocFunc(void) { return nb_topicObject(nb_dcpsPublicationAlloc()); } + +/* Allocates and initializes (to 0) a new nb_dcpsPublication */ +nb_dcpsPublication +nb_dcpsPublicationNew(void) +{ + nb_dcpsPublication _this; + + _this = os_malloc(sizeof *_this); + + nb_dcpsPublicationInit(_this); + + return _this; +} + +/* Initializes all nb_dcpsPublication fields of _this to 0. */ +void +nb_dcpsPublicationInit( + nb_dcpsPublication _this) +{ + assert(_this); + + /* Super-init */ + nb__topicObjectInit( + nb_topicObject(_this), + NB_TOPIC_OBJECT_DCPS_PUBLICATION, + nb_dcpsPublicationDeinit, + V_PUBLICATIONINFO_NAME, + nb__dcpsPublicationCopyOut, + nb__dcpsPublicationCopyIn); + + /* This compile-time constraint assures that _parent is the first member + * of nb_serviceSubscription and thus sizeof(_this->_parent) can be used + * to determine the offset. */ + { + struct nb_dcpsPublication_parent_offset_constraint { + char _parent_member_at_offset_0 [offsetof(C_STRUCT(nb_dcpsPublication), _parent) == 0]; + char non_empty_dummy_last_member[1]; + }; + } + + /* Only memset the non-_parent part */ + memset((void*)((os_address)_this + sizeof(_this->_parent)), 0, sizeof(*_this) - sizeof(_this->_parent)); +} + +void +nb_dcpsPublicationDeinit( + nb_object o /* nb_dcpsPublication */) +{ + nb_dcpsPublication _this = nb_dcpsPublication(o); + + assert(_this); + + /* Object-deinit */ + os_free(_this->info.topic_name); + os_free(_this->info.type_name); + os_free(_this->info.user_data.value); + + /* partition */ + { + c_ulong i; + + for(i = 0; i < _this->partition.len; i++){ + os_free(_this->info.partition.name[i]); + } + os_free(_this->info.partition.name); + } + os_free(_this->info.topic_data.value); + os_free(_this->info.group_data.value); + + /* Super-deinit */ + nb__topicObjectDeinit(o); +} + +#ifndef NDEBUG +/* Type-checking free function */ +void +nb_dcpsPublicationFree ( + nb_dcpsPublication _this) +{ + if(_this){ + nb_objectIsValidKind(_this, NB_TOPIC_OBJECT_DCPS_PUBLICATION); + nb_objectFree(_this); + } +} +#endif /* NDEBUG */ + + +const c_char * +nb_dcpsPublicationTopicName( + nb_dcpsPublication _this) +{ + nb_objectIsValidKind(_this, NB_TOPIC_OBJECT_DCPS_PUBLICATION); + + return _this->info.topic_name; +} + +const v_builtinTopicKey * +nb_dcpsPublicationKey( + nb_dcpsPublication _this) +{ + nb_objectIsValidKind(_this, NB_TOPIC_OBJECT_DCPS_PUBLICATION); + + return &_this->info.key; +} + +const v_builtinTopicKey * +nb_dcpsPublicationParticipantKey( + nb_dcpsPublication _this) +{ + nb_objectIsValidKind(_this, NB_TOPIC_OBJECT_DCPS_PUBLICATION); + + return &_this->info.participant_key; +} + +const char * const * +nb_dcpsPublicationPartitions( + nb_dcpsPublication _this, + c_ulong *len) +{ + nb_objectIsValidKind(_this, NB_TOPIC_OBJECT_DCPS_PUBLICATION); + assert(len); + + *len = _this->partition.len; + + return (const char * const *) _this->info.partition.name; +} + +c_bool +nb_dcpsPublicationGetInterested( + nb_dcpsPublication _this) +{ + nb_objectIsValidKind(_this, NB_TOPIC_OBJECT_DCPS_PUBLICATION); + + return _this->interested; +} + +void +nb_dcpsPublicationSetInterested( + nb_dcpsPublication _this, + const char * const * includes, + const char * const * excludes) +{ + c_bool interested; + + nb_objectIsValidKind(_this, NB_TOPIC_OBJECT_DCPS_PUBLICATION); + assert(includes); + assert(excludes); + + interested = nb_match( + (const char * const *)_this->info.partition.name, + _this->partition.len, + nb_dcpsPublicationTopicName(_this), + includes, + excludes); + + NB_TRACE(("nb_dcpsPublication={key="NB_KEYFMT"} %s interest for forwarding of %s for topic \'%s\'\n", + v_gidSystemId(*nb_dcpsPublicationKey(_this)), + v_gidLocalId(*nb_dcpsPublicationKey(_this)), + interested ? "matches" : "doesn't match", + nb_topicObjectName(nb_topicObject(_this)), + nb_dcpsPublicationTopicName(_this) + )); + + _this->interested = interested; +} + + +v_actionResult +nb_dcpsPublicationReaderAction( + c_object o, + c_voidp copyArg /* c_iter * */) +{ + return nb_topicObjectReaderAction(o, copyArg, nb__dcpsPublicationAllocFunc); +} + +/* nb_cmReader */ +static v_copyin_result +nb__cmReaderCopyIn ( + c_type type, + nb_topicObject _from, /* nb_cmReader */ + void * _to /* struct v_dataReaderCMInfo* */) +{ + const nb_cmReader cmr = nb_cmReader(_from); + /* This is a *HEAP* copy of the kernel-struct. Strings are malloc'd. */ + struct v_dataReaderCMInfo const * const from = &cmr->info; + struct v_dataReaderCMInfo *to = (struct v_dataReaderCMInfo *)_to; + c_base base = c_getBase(type); + + assert(from); + assert(to); + + *to = *from; + + /* Copy all references by hand; it seems to be impossible to generate + * proper copy-routines on SAC for the kernel-types. */ + to->product.value = c_stringNew_s(base, from->product.value); + if(from->product.value && !to->product.value){ + /* Out of shared memory; warning reported by memory-manager. */ + goto err_product_copy; + }; + + to->name = c_stringNew_s(base, from->name); + if(from->name && !to->name){ + /* Out of shared memory; warning reported by memory-manager. */ + goto err_name_copy; + } + + to->subscription_keys.expression = c_stringNew_s(base, from->subscription_keys.expression); + if(from->subscription_keys.expression && !to->subscription_keys.expression){ + /* Out of shared memory; warning reported by memory-manager. */ + goto err_subscription_keys_copy; + } + + to->share.name = c_stringNew_s(base, from->share.name); + if(from->share.name && !to->share.name){ + /* Out of shared memory; warning reported by memory-manager. */ + goto err_share_copy; + } + + return V_COPYIN_RESULT_OK; + +err_share_copy: + c_free(to->subscription_keys.expression); + to->subscription_keys.expression = NULL; +err_subscription_keys_copy: + c_free(to->name); + to->name = NULL; +err_name_copy: + c_free(to->product.value); + to->product.value = NULL; +err_product_copy: + return V_COPYIN_RESULT_OUT_OF_MEMORY; +} + +static u_result +nb__cmReaderCopyOut( + nb_topicObject _to, /* nb_cmReader */ + const void * _from /* struct v_dataReaderCMInfo * */) +{ + const nb_cmReader cmr = nb_cmReader(_to); + struct v_dataReaderCMInfo * const to = &cmr->info; + struct v_dataReaderCMInfo const * const from = (struct v_dataReaderCMInfo *)_from; + + assert(cmr); + + if(from){ + *to = *from; + + if(from->product.value){ + to->product.value = os_strdup(from->product.value); + } + + if(from->name){ + to->name = os_strdup(from->name); + } + + if(from->subscription_keys.expression){ + to->subscription_keys.expression = os_strdup(from->subscription_keys.expression); + } + + if(from->share.name){ + to->share.name = os_strdup(from->share.name); + } + + /* Successfully initialized object now; set proper deinit */ + nb__objectSetDeinit(nb_object(cmr), nb_cmReaderDeinit); + } else { + /* Initialize all fields to default values */ + nb_cmReaderInit(cmr); + } + + return U_RESULT_OK; +} + +/* Allocates memory for a new nb_cmReader. This doesn't initialize + * the object fully. */ +nb_cmReader +nb_cmReaderAlloc(void) +{ + nb_cmReader _this; + + _this = os_malloc(sizeof *_this); + + /* Only init nb_topicObject */ + nb__topicObjectInit( + (nb_topicObject)_this, + NB_TOPIC_OBJECT_CM_READER, + nb__topicObjectDeinit, /* Should be reset to nb_cmReaderDeinit after full init by copyOut */ + V_CMDATAREADERINFO_NAME, + nb__cmReaderCopyOut, + nb__cmReaderCopyIn); + + return _this; +} + +/* nb_topicObjectAllocFunc signature wrapper */ +static nb_topicObject +nb__cmReaderAllocFunc(void) +{ + return nb_topicObject(nb_cmReaderAlloc()); +} + +/* Allocates and initializes (to 0) a new nb_cmReader */ +nb_cmReader +nb_cmReaderNew(void) +{ + nb_cmReader _this; + + _this = os_malloc(sizeof *_this); + + nb_cmReaderInit(_this); + + return _this; +} + +/* Initializes all nb_cmReader fields of _this to 0. */ +void +nb_cmReaderInit( + nb_cmReader _this) +{ + assert(_this); + + /* Super-init */ + nb__topicObjectInit( + nb_topicObject(_this), + NB_TOPIC_OBJECT_CM_READER, + nb_cmReaderDeinit, + V_CMDATAREADERINFO_NAME, + nb__cmReaderCopyOut, + nb__cmReaderCopyIn); + + /* This compile-time constraint assures that _parent is the first member + * of nb_serviceSubscription and thus sizeof(_this->_parent) can be used + * to determine the offset. */ + { + struct nb_cmReader_parent_offset_constraint { + char _parent_member_at_offset_0 [offsetof(C_STRUCT(nb_cmReader), _parent) == 0]; + char non_empty_dummy_last_member[1]; + }; + } + + /* Only memset the non-_parent part */ + memset((void*)((os_address)_this + sizeof(_this->_parent)), 0, sizeof(*_this) - sizeof(_this->_parent)); +} + +void +nb_cmReaderDeinit( + nb_object o /* nb_cmReader */) +{ + nb_cmReader _this = nb_cmReader(o); + + assert(_this); + + /* Object-deinit */ + os_free(_this->info.product.value); + os_free(_this->info.name); + os_free(_this->info.subscription_keys.expression); + os_free(_this->info.share.name); + + /* Super-deinit */ + nb__topicObjectDeinit(o); +} + +#ifndef NDEBUG +/* Type-checking free function */ +void +nb_cmReaderFree ( + nb_cmReader _this) +{ + if(_this){ + nb_objectIsValidKind(_this, NB_TOPIC_OBJECT_CM_READER); + nb_objectFree(_this); + } +} +#endif /* NDEBUG */ + + +const v_builtinTopicKey * +nb_cmReaderKey( + nb_cmReader _this) +{ + nb_objectIsValidKind(_this, NB_TOPIC_OBJECT_CM_READER); + + return &_this->info.key; +} + +const v_builtinTopicKey * +nb_cmReaderSubscriberKey( + nb_cmReader _this) +{ + nb_objectIsValidKind(_this, NB_TOPIC_OBJECT_CM_READER); + + return &_this->info.subscriber_key; +} + + +v_actionResult +nb_cmReaderReaderAction( + c_object o, + c_voidp copyArg /* c_iter * */) +{ + return nb_topicObjectReaderAction(o, copyArg, nb__cmReaderAllocFunc); +} + +/* nb_cmWriter */ +static v_copyin_result +nb__cmWriterCopyIn ( + c_type type, + nb_topicObject _from, /* nb_cmWriter */ + void * _to /* struct v_dataWriterCMInfo* */) +{ + const nb_cmWriter cmr = nb_cmWriter(_from); + /* This is a *HEAP* copy of the kernel-struct. Strings are malloc'd. */ + struct v_dataWriterCMInfo const * const from = &cmr->info; + struct v_dataWriterCMInfo *to = (struct v_dataWriterCMInfo *)_to; + c_base base = c_getBase(type); + + assert(from); + assert(to); + + *to = *from; + + /* Copy all references by hand; it seems to be impossible to generate + * proper copy-routines on SAC for the kernel-types. */ + to->product.value = c_stringNew_s(base, from->product.value); + if(from->product.value && !to->product.value){ + /* Out of shared memory; warning reported by memory-manager. */ + goto err_product_copy; + }; + + to->name = c_stringNew_s(base, from->name); + if(from->name && !to->name){ + /* Out of shared memory; warning reported by memory-manager. */ + goto err_name_copy; + } + return V_COPYIN_RESULT_OK; + +err_name_copy: + c_free(to->product.value); + to->product.value = NULL; +err_product_copy: + return V_COPYIN_RESULT_OUT_OF_MEMORY; +} + +static u_result +nb__cmWriterCopyOut( + nb_topicObject _to, /* nb_cmWriter */ + const void * _from /* struct v_dataWriterCMInfo * */) +{ + const nb_cmWriter cmw = nb_cmWriter(_to); + struct v_dataWriterCMInfo * const to = &cmw->info; + struct v_dataWriterCMInfo const * const from = (struct v_dataWriterCMInfo *)_from; + + assert(cmw); + + if(from){ + *to = *from; + + if(from->product.value){ + to->product.value = os_strdup(from->product.value); + } + + if(from->name){ + to->name = os_strdup(from->name); + } + + /* Successfully initialized object now; set proper deinit */ + nb__objectSetDeinit(nb_object(cmw), nb_cmWriterDeinit); + } else { + /* Initialize all fields to default values */ + nb_cmWriterInit(cmw); + } + + return U_RESULT_OK; +} + +/* Allocates memory for a new nb_cmWriter. This doesn't initialize + * the object fully. */ +nb_cmWriter +nb_cmWriterAlloc(void) +{ + nb_cmWriter _this; + + _this = os_malloc(sizeof *_this); + + /* Only init nb_topicObject */ + nb__topicObjectInit( + (nb_topicObject)_this, + NB_TOPIC_OBJECT_CM_WRITER, + nb__topicObjectDeinit, /* Should be reset to nb_cmWriterDeinit after full init by copyOut */ + V_CMDATAWRITERINFO_NAME, + nb__cmWriterCopyOut, + nb__cmWriterCopyIn); + + return _this; +} + +/* nb_topicObjectAllocFunc signature wrapper */ +static nb_topicObject nb__cmWriterAllocFunc(void) { return nb_topicObject(nb_cmWriterAlloc()); } + +/* Allocates and initializes (to 0) a new nb_cmWriter */ +nb_cmWriter +nb_cmWriterNew(void) +{ + nb_cmWriter _this; + + _this = os_malloc(sizeof *_this); + + nb_cmWriterInit(_this); + + return _this; +} + +/* Initializes all nb_cmWriter fields of _this to 0. */ +void +nb_cmWriterInit( + nb_cmWriter _this) +{ + assert(_this); + + /* Super-init */ + nb__topicObjectInit( + nb_topicObject(_this), + NB_TOPIC_OBJECT_CM_WRITER, + nb_cmWriterDeinit, + V_CMDATAWRITERINFO_NAME, + nb__cmWriterCopyOut, + nb__cmWriterCopyIn); + + /* This compile-time constraint assures that _parent is the first member + * of nb_serviceSubscription and thus sizeof(_this->_parent) can be used + * to determine the offset. */ + { + struct nb_cmWriter_parent_offset_constraint { + char _parent_member_at_offset_0 [offsetof(C_STRUCT(nb_cmWriter), _parent) == 0]; + char non_empty_dummy_last_member[1]; + }; + } + + /* Only memset the non-_parent part */ + memset((void*)((os_address)_this + sizeof(_this->_parent)), 0, sizeof(*_this) - sizeof(_this->_parent)); +} + +void +nb_cmWriterDeinit( + nb_object o /* nb_cmWriter */) +{ + nb_cmWriter _this = nb_cmWriter(o); + + assert(_this); + + /* Object-deinit */ + os_free(_this->info.product.value); + os_free(_this->info.name); + + /* Super-deinit */ + nb__topicObjectDeinit(o); +} + +#ifndef NDEBUG +/* Type-checking free function */ +void +nb_cmWriterFree ( + nb_cmWriter _this) +{ + if(_this){ + nb_objectIsValidKind(_this, NB_TOPIC_OBJECT_CM_WRITER); + nb_objectFree(_this); + } +} +#endif /* NDEBUG */ + + +const v_builtinTopicKey * +nb_cmWriterKey( + nb_cmWriter _this) +{ + nb_objectIsValidKind(_this, NB_TOPIC_OBJECT_CM_WRITER); + + return &_this->info.key; +} + +const v_builtinTopicKey * +nb_cmWriterPublisherKey( + nb_cmWriter _this) +{ + nb_objectIsValidKind(_this, NB_TOPIC_OBJECT_CM_WRITER); + + return &_this->info.publisher_key; +} + +v_actionResult +nb_cmWriterReaderAction( + c_object o, + c_voidp copyArg /* c_iter * */) +{ + return nb_topicObjectReaderAction(o, copyArg, nb__cmWriterAllocFunc); +} + +/* nb_cmPublisher */ +static v_copyin_result +nb__cmPublisherCopyIn ( + c_type type, + nb_topicObject _from, /* nb_cmPublisher */ + void * _to /* struct v_publisherCMInfo* */) +{ + const nb_cmPublisher cmp = nb_cmPublisher(_from); + /* This is a *HEAP* copy of the kernel-struct. Strings are malloc'd. */ + struct v_publisherCMInfo const * const from = &cmp->info; + struct v_publisherCMInfo *to = (struct v_publisherCMInfo *)_to; + c_base base = c_getBase(type); + c_type stringType = c_string_t(base); + c_type seqStringType; + + assert(stringType); + + assert(from); + assert(to); + + *to = *from; + + /* Copy all references by hand; it seems to be impossible to generate + * proper copy-routines on SAC for the kernel-types. */ + to->product.value = c_stringNew_s(base, from->product.value); + if(from->product.value && !to->product.value){ + /* Out of shared memory; warning reported by memory-manager. */ + goto err_product_copy; + }; + + to->name = c_stringNew_s(base, from->name); + if(from->name && !to->name){ + /* Out of shared memory; warning reported by memory-manager. */ + goto err_name_copy; + } + + assert(cmp->partition.len || from->partition.name == NULL); + if(cmp->partition.len) { + seqStringType = c_metaSequenceTypeNew(c_metaObject(base), "C_SEQUENCE", stringType, 0); + assert(seqStringType); /* This should be resolvable, so no need to check */ + to->partition.name = c_newSequence_s(c_collectionType(seqStringType), cmp->partition.len); + c_free(seqStringType); + if (!to->partition.name) { + /* Out of shared memory; warning reported by memory-manager. */ + goto err_partition_seq_new; + } + + { + c_ulong i; + + for(i = 0; i < cmp->partition.len; i++){ + to->partition.name[i] = c_stringNew_s(base, from->partition.name[i]); + if(from->partition.name[i] && !to->partition.name[i]){ + /* Out of shared memory; warning reported by memory-manager. */ + goto err_partition_copy; + } + } + } + } + + return V_COPYIN_RESULT_OK; + +/* Error handling */ +err_partition_copy: + c_free(to->partition.name); + to->partition.name = NULL; +err_partition_seq_new: + c_free(to->name); + to->name = NULL; +err_name_copy: + c_free(to->product.value); + to->product.value = NULL; +err_product_copy: + return V_COPYIN_RESULT_OUT_OF_MEMORY; +} + +static u_result +nb__cmPublisherCopyOut( + nb_topicObject _to, /* nb_cmPublisher */ + const void * _from /* struct v_publisherCMInfo * */) +{ + const nb_cmPublisher cmp = nb_cmPublisher(_to); + struct v_publisherCMInfo * const to = &cmp->info; + struct v_publisherCMInfo const * const from = (struct v_publisherCMInfo *)_from; + + assert(cmp); + + if(from){ + *to = *from; + + if(from->product.value){ + to->product.value = os_strdup(from->product.value); + } + + if(from->name){ + to->name = os_strdup(from->name); + } + + /* partition */ + cmp->partition.len = c_arraySize(from->partition.name); + if(cmp->partition.len){ + c_ulong i; + + to->partition.name = os_malloc(cmp->partition.len * sizeof(*to->partition.name)); + + for(i = 0; i < cmp->partition.len; i++){ + assert(from->partition.name[i]); + to->partition.name[i] = os_strdup(from->partition.name[i]); + } + } + + /* Successfully initialized object now; set proper deinit */ + nb__objectSetDeinit(nb_object(cmp), nb_cmPublisherDeinit); + } else { + /* Initialize all fields to default values */ + nb_cmPublisherInit(cmp); + } + + return U_RESULT_OK; +} + +/* Allocates memory for a new nb_cmPublisher. This doesn't initialize + * the object fully. */ +nb_cmPublisher +nb_cmPublisherAlloc(void) +{ + nb_cmPublisher _this; + + _this = os_malloc(sizeof *_this); + + /* Only init nb_topicObject */ + nb__topicObjectInit( + (nb_topicObject)_this, + NB_TOPIC_OBJECT_CM_PUBLISHER, + nb__topicObjectDeinit, /* Should be reset to nb_cmPublisherDeinit after full init by copyOut */ + V_CMPUBLISHERINFO_NAME, + nb__cmPublisherCopyOut, + nb__cmPublisherCopyIn); + + return _this; +} + +/* nb_topicObjectAllocFunc signature wrapper */ +static nb_topicObject +nb__cmPublisherAllocFunc(void) +{ + return nb_topicObject(nb_cmPublisherAlloc()); +} + +/* Allocates and initializes (to 0) a new nb_cmPublisher */ +nb_cmPublisher +nb_cmPublisherNew(void) +{ + nb_cmPublisher _this; + + _this = os_malloc(sizeof *_this); + + nb_cmPublisherInit(_this); + + return _this; +} + +/* Initializes all nb_cmPublisher fields of _this to 0. */ +void +nb_cmPublisherInit( + nb_cmPublisher _this) +{ + assert(_this); + + /* Super-init */ + nb__topicObjectInit( + nb_topicObject(_this), + NB_TOPIC_OBJECT_CM_PUBLISHER, + nb_cmPublisherDeinit, + V_CMPUBLISHERINFO_NAME, + nb__cmPublisherCopyOut, + nb__cmPublisherCopyIn); + + /* This compile-time constraint assures that _parent is the first member + * of nb_serviceSubscription and thus sizeof(_this->_parent) can be used + * to determine the offset. */ + { + struct nb_cmPublisher_parent_offset_constraint { + char _parent_member_at_offset_0 [offsetof(C_STRUCT(nb_cmPublisher), _parent) == 0]; + char non_empty_dummy_last_member[1]; + }; + } + + /* Only memset the non-_parent part */ + memset((void*)((os_address)_this + sizeof(_this->_parent)), 0, sizeof(*_this) - sizeof(_this->_parent)); +} + +void +nb_cmPublisherDeinit( + nb_object o /* nb_cmPublisher */) +{ + nb_cmPublisher _this = nb_cmPublisher(o); + + assert(_this); + + /* Object-deinit */ + os_free(_this->info.product.value); + os_free(_this->info.name); + + /* partition */ + { + c_ulong i; + + for(i = 0; i < _this->partition.len; i++){ + os_free(_this->info.partition.name[i]); + } + os_free(_this->info.partition.name); + } + + /* Super-deinit */ + nb__topicObjectDeinit(o); +} + +#ifndef NDEBUG +/* Type-checking free function */ +void +nb_cmPublisherFree ( + nb_cmPublisher _this) +{ + if(_this){ + nb_objectIsValidKind(_this, NB_TOPIC_OBJECT_CM_PUBLISHER); + nb_objectFree(_this); + } +} +#endif /* NDEBUG */ + +const v_builtinTopicKey * +nb_cmPublisherKey( + nb_cmPublisher _this) +{ + nb_objectIsValidKind(_this, NB_TOPIC_OBJECT_CM_PUBLISHER); + + return &_this->info.key; +} + +const v_builtinTopicKey * +nb_cmPublisherParticipantKey( + nb_cmPublisher _this) +{ + nb_objectIsValidKind(_this, NB_TOPIC_OBJECT_CM_PUBLISHER); + + return &_this->info.participant_key; +} + +v_actionResult +nb_cmPublisherReaderAction( + c_object o, + c_voidp copyArg /* c_iter * */) +{ + return nb_topicObjectReaderAction(o, copyArg, nb__cmPublisherAllocFunc); +} + + +/* nb_cmSubscriber */ +static v_copyin_result +nb__cmSubscriberCopyIn ( + c_type type, + nb_topicObject _from, /* nb_cmSubscriber */ + void * _to /* struct v_subscriberCMInfo* */) +{ + const nb_cmSubscriber cms = nb_cmSubscriber(_from); + /* This is a *HEAP* copy of the kernel-struct. Strings are malloc'd. */ + struct v_subscriberCMInfo const * const from = &cms->info; + struct v_subscriberCMInfo *to = (struct v_subscriberCMInfo *)_to; + c_base base = c_getBase(type); + c_type stringType = c_string_t(base); + c_type seqStringType; + + assert(stringType); + + assert(from); + assert(to); + + *to = *from; + + /* Copy all references by hand; it seems to be impossible to generate + * proper copy-routines on SAC for the kernel-types. */ + to->product.value = c_stringNew_s(base, from->product.value); + if(from->product.value && !to->product.value){ + /* Out of shared memory; warning reported by memory-manager. */ + goto err_product_copy; + }; + + to->name = c_stringNew_s(base, from->name); + if(from->name && !to->name){ + /* Out of shared memory; warning reported by memory-manager. */ + goto err_name_copy; + } + + to->share.name = c_stringNew_s(base, from->share.name); + if(from->share.name && !to->share.name){ + /* Out of shared memory; warning reported by memory-manager. */ + goto err_share_copy; + } + + assert(cms->partition.len || from->partition.name == NULL); + if(cms->partition.len) { + seqStringType = c_metaSequenceTypeNew(c_metaObject(base), "C_SEQUENCE", stringType, 0); + assert(seqStringType); /* This should be resolvable, so no need to check */ + to->partition.name = c_newSequence_s(c_collectionType(seqStringType), cms->partition.len); + c_free(seqStringType); + if (!to->partition.name) { + /* Out of shared memory; warning reported by memory-manager. */ + goto err_partition_seq_new; + } + + { + c_ulong i; + + for(i = 0; i < cms->partition.len; i++){ + to->partition.name[i] = c_stringNew_s(base, from->partition.name[i]); + if(from->partition.name[i] && !to->partition.name[i]){ + /* Out of shared memory; warning reported by memory-manager. */ + goto err_partition_copy; + } + } + } + } + + return V_COPYIN_RESULT_OK; + +/* Error handling */ +err_partition_copy: + c_free(to->partition.name); + to->partition.name = NULL; +err_partition_seq_new: + c_free(to->share.name); + to->share.name = NULL; +err_share_copy: + c_free(to->name); + to->name = NULL; +err_name_copy: + c_free(to->product.value); + to->product.value = NULL; +err_product_copy: + return V_COPYIN_RESULT_OUT_OF_MEMORY; +} + +static u_result +nb__cmSubscriberCopyOut( + nb_topicObject _to, /* nb_cmSubscriber */ + const void * _from /* struct v_subscriberCMInfo * */) +{ + const nb_cmSubscriber cms = nb_cmSubscriber(_to); + struct v_subscriberCMInfo * const to = &cms->info; + struct v_subscriberCMInfo const * const from = (struct v_subscriberCMInfo *)_from; + + assert(cms); + + if(from){ + *to = *from; + + if(from->product.value){ + to->product.value = os_strdup(from->product.value); + } + + if(from->name){ + to->name = os_strdup(from->name); + } + + if(from->share.name){ + to->share.name = os_strdup(from->share.name); + } + + /* partition */ + cms->partition.len = c_arraySize(from->partition.name); + if(cms->partition.len){ + c_ulong i; + + to->partition.name = os_malloc(cms->partition.len * sizeof(*to->partition.name)); + + for(i = 0; i < cms->partition.len; i++){ + assert(from->partition.name[i]); + to->partition.name[i] = os_strdup(from->partition.name[i]); + } + } + + + /* Successfully initialized object now; set proper deinit */ + nb__objectSetDeinit(nb_object(cms), nb_cmSubscriberDeinit); + } else { + /* Initialize all fields to default values */ + nb_cmSubscriberInit(cms); + } + + return U_RESULT_OK; +} + +/* Allocates memory for a new nb_cmSubscriber. This doesn't initialize + * the object fully. */ +nb_cmSubscriber +nb_cmSubscriberAlloc(void) +{ + nb_cmSubscriber _this; + + _this = os_malloc(sizeof *_this); + + /* Only init nb_topicObject */ + nb__topicObjectInit( + (nb_topicObject)_this, + NB_TOPIC_OBJECT_CM_SUBSCRIBER, + nb__topicObjectDeinit, /* Should be reset to nb_cmSubscriberDeinit after full init by copyOut */ + V_CMSUBSCRIBERINFO_NAME, + nb__cmSubscriberCopyOut, + nb__cmSubscriberCopyIn); + + return _this; +} + +/* nb_topicObjectAllocFunc signature wrapper */ +static nb_topicObject +nb__cmSubscriberAllocFunc(void) +{ + return nb_topicObject(nb_cmSubscriberAlloc()); +} + +/* Allocates and initializes (to 0) a new nb_cmSubscriber */ +nb_cmSubscriber +nb_cmSubscriberNew(void) +{ + nb_cmSubscriber _this; + + _this = os_malloc(sizeof *_this); + + nb_cmSubscriberInit(_this); + + return _this; +} + +/* Initializes all nb_cmSubscriber fields of _this to 0. */ +void +nb_cmSubscriberInit( + nb_cmSubscriber _this) +{ + assert(_this); + + /* Super-init */ + nb__topicObjectInit( + nb_topicObject(_this), + NB_TOPIC_OBJECT_CM_SUBSCRIBER, + nb_cmSubscriberDeinit, + V_CMSUBSCRIBERINFO_NAME, + nb__cmSubscriberCopyOut, + nb__cmSubscriberCopyIn); + + /* This compile-time constraint assures that _parent is the first member + * of nb_serviceSubscription and thus sizeof(_this->_parent) can be used + * to determine the offset. */ + { + struct nb_cmSubscriber_parent_offset_constraint { + char _parent_member_at_offset_0 [offsetof(C_STRUCT(nb_cmSubscriber), _parent) == 0]; + char non_empty_dummy_last_member[1]; + }; + } + + /* Only memset the non-_parent part */ + memset((void*)((os_address)_this + sizeof(_this->_parent)), 0, sizeof(*_this) - sizeof(_this->_parent)); +} + +void +nb_cmSubscriberDeinit( + nb_object o /* nb_cmSubscriber */) +{ + nb_cmSubscriber _this = nb_cmSubscriber(o); + + assert(_this); + + /* Object-deinit */ + os_free(_this->info.product.value); + os_free(_this->info.name); + os_free(_this->info.share.name); + + /* partition */ + { + c_ulong i; + + for(i = 0; i < _this->partition.len; i++){ + os_free(_this->info.partition.name[i]); + } + os_free(_this->info.partition.name); + } + + /* Super-deinit */ + nb__topicObjectDeinit(o); +} + +#ifndef NDEBUG +/* Type-checking free function */ +void +nb_cmSubscriberFree ( + nb_cmSubscriber _this) +{ + if(_this){ + nb_objectIsValidKind(_this, NB_TOPIC_OBJECT_CM_SUBSCRIBER); + nb_objectFree(_this); + } +} +#endif /* NDEBUG */ + +const v_builtinTopicKey * +nb_cmSubscriberKey( + nb_cmSubscriber _this) +{ + nb_objectIsValidKind(_this, NB_TOPIC_OBJECT_CM_SUBSCRIBER); + + return &_this->info.key; +} + +v_actionResult +nb_cmSubscriberReaderAction( + c_object o, + c_voidp copyArg /* c_iter * */) +{ + return nb_topicObjectReaderAction(o, copyArg, nb__cmSubscriberAllocFunc); +} diff --git a/src/services/nwbridge/include/nb_service.h b/src/services/nwbridge/include/nb_service.h new file mode 100644 index 000000000..28ccb6286 --- /dev/null +++ b/src/services/nwbridge/include/nb_service.h @@ -0,0 +1,47 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#ifndef NB_SERVICE_H +#define NB_SERVICE_H + +#include "vortex_os.h" + +#if defined (__cplusplus) +extern "C" { +#endif + +#include "os_if.h" + +#ifdef OSPL_BUILD_NWBRIDGE_SERVICE +#define OS_API OS_API_EXPORT +#else +#define OS_API OS_API_IMPORT +#endif /* OSPL_BUILD_NWBRIDGE_SERVICE */ + +/* !!!!!!!!NOTE From here no more includes are allowed!!!!!!! */ + +OS_API OPENSPLICE_ENTRYPOINT_DECL(ospl_nwbridge); + +OS_API void ospl_nwbridgeAtExit(void); + +#undef OS_API + +#if defined (__cplusplus) +} +#endif + +#endif /* NB_SERVICE_H */ diff --git a/src/services/nwbridge/makefile b/src/services/nwbridge/makefile new file mode 100644 index 000000000..8b5b8df39 --- /dev/null +++ b/src/services/nwbridge/makefile @@ -0,0 +1,11 @@ +-include $(OSPL_HOME)/setup/makefiles/makefile.mak + +all link: bld/$(SPLICE_TARGET)/makefile + @$(MAKE) -C bld/$(SPLICE_TARGET) $@ + + +clean: + @rm -rf bld/$(SPLICE_TARGET) + +osplconf osplconf-update: bld/$(SPLICE_TARGET)/makefile + @$(MAKE) -C bld/$(SPLICE_TARGET) $@ diff --git a/src/services/nwbridge/makefile.mak b/src/services/nwbridge/makefile.mak new file mode 100644 index 000000000..c6b01e409 --- /dev/null +++ b/src/services/nwbridge/makefile.mak @@ -0,0 +1,53 @@ +TARGET_DLIB := nwbridge +ODL_MODULES := NetworkingBridge + +include $(OSPL_HOME)/setup/makefiles/target.mak + +ifdef ELINOS42 +CFLAGS += -std=c99 +endif + +LDFLAGS += $(LDFLAGS_T_RLM) $(SHLDFLAGS) +LDLIBS += $(SHLDLIBS) +LDLIBS += -l$(DDS_CORE) $(LDLIBS_T_RLM) + +CPPFLAGS += $(CPPFLAGS_T_RLM) +CFLAGS += $(CFLAGS_T_RLM) + +CPPFLAGS += -DOSPL_BUILD_NWBRIDGE_SERVICE + +CFLAGS += $(SHCFLAGS) +CFLAGS += $(CFLAGS_XSTRICT) + +CINCS += -I$(OSPL_HOME)/src/user/include +CINCS += -I$(OSPL_HOME)/src/kernel/include +CINCS += -I$(OSPL_HOME)/src/osplcore/bld/$(SPLICE_TARGET) +CINCS += -I$(OSPL_HOME)/src/database/database/include +CINCS += -I$(OSPL_HOME)/src/database/serialization/include +CINCS += -I$(OSPL_HOME)/src/utilities/include +CINCS += -I$(OSPL_HOME)/src/configuration/parser/include +CINCS += -I$(OSPL_HOME)/src/configuration/config/include +CINCS += -I$(OSPL_HOME)/src/services/nwbridge/bld/$(SPLICE_TARGET) + +ifneq (,$(findstring int5,$(SPLICE_TARGET))) +CFLAGS += -DCOMPILE_ENTRYPOINT_AS_MAIN +endif + +# automagic generation/updating of osplconf input +METACONFIG := splice_metaconfig_$(firstword $(subst ., , $(patsubst V%, %, $(PACKAGE_VERSION)))).1.xml + +.PHONY: osplconf osplconf-update +osplconf: $(METACONFIG) + +# don't want a cyclical dependency +osplconf-update: $(METACONFIG) + if [ $(METACONFIG) -nt $(OSPL_HOME)/src/tools/cm/config/code/$(METACONFIG) ] ; then \ + cp -p $< $(OSPL_HOME)/src/tools/cm/config/code/$(METACONFIG) ; \ + $(MAKE) -C $(OSPL_HOME)/src/tools/cm/config ; \ + fi + +$(METACONFIG): ../../../ddsi2e/extract-configurator-xml.awk ../../code/nb_configuration.c $(OSPL_HOME)/src/tools/cm/config/code/$(METACONFIG) ../../../ddsi2e/merge-metaconfig + gawk -vversion=COMMERCIAL -f ../../../ddsi2e/extract-configurator-xml.awk ../../code/nb_configuration.c >config-nwbridge.xml + $(SHELL) ../../../ddsi2e/merge-metaconfig $(OSPL_HOME)/src/tools/cm/config/code/$(METACONFIG) config-nwbridge.xml >$@ + +-include $(DEPENDENCIES) diff --git a/src/services/spliced/code/report.h b/src/services/spliced/code/report.h index eab505282..27bdafe9d 100644 --- a/src/services/spliced/code/report.h +++ b/src/services/spliced/code/report.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/services/spliced/code/s_configuration.c b/src/services/spliced/code/s_configuration.c index 39e9b97a7..43ee82340 100644 --- a/src/services/spliced/code/s_configuration.c +++ b/src/services/spliced/code/s_configuration.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -201,71 +202,6 @@ s_configurationValueLong( c_iterFree(iter); } -#if 0 -static void -s_configurationValueULong( - s_configuration configuration, - u_cfElement element, - const char *tag, - void (* const setAction)(s_configuration config, c_ulong longValue)) -{ - c_iter iter; - u_cfData data; - c_long longValue; - c_ulong ulongValue; - c_bool found; - - iter = u_cfElementXPath(element, tag); - data = u_cfData(c_iterTakeFirst(iter)); - while (data != NULL) { - found = u_cfDataLongValue(data, &longValue); - /* QAC EXPECT 2100; */ - if (found == TRUE) { - if (longValue < 0) { - longValue = -longValue; - if (longValue < 0) { - longValue++; - longValue = -longValue; - } - } - ulongValue = (c_ulong)longValue; - setAction(configuration, ulongValue); - } - u_cfDataFree(data); - data = u_cfData(c_iterTakeFirst(iter)); - } - c_iterFree(iter); -} -#endif - -#if 0 -static void -s_configurationValueSize( - s_configuration configuration, - u_cfElement element, - const char *tag, - void (* const setAction)(s_configuration config, c_size size)) -{ - c_iter iter; - u_cfData data; - c_size size; - c_bool found; - - iter = u_cfElementXPath(element, tag); - data = u_cfData(c_iterTakeFirst(iter)); - while (data != NULL) { - found = u_cfDataSizeValue(data, &size); - /* QAC EXPECT 2100; */ - if (found == TRUE) { - setAction(configuration, size); - } - u_cfDataFree(data); - data = u_cfData(c_iterTakeFirst(iter)); - } - c_iterFree(iter); -} -#endif - static void s_configurationValueFloat( s_configuration configuration, @@ -386,7 +322,7 @@ s_configurationSetHeartbeatExpiryTime( * Sets the heartbeat update interval, which is defined by * Heartbeat.ExpiryTime * Heartbeat.ExpiryTime@update_factor. * After this call the renewal period will be set to - * Heartbeat.ExpiryTime * MIN(S_CFG_HEARTBEAT_UPDATE_FACTOR_MAXIMUM, + * Heartbeat.ExpiryTime * MIN(S_CFG_HEARTBEAT_UPDATE_FACTOR_MAXIMUM, * MAX(S_CFG_HEARTBEAT_UPDATE_FACTOR_MINIMUM, update_factor)). * @param config The configuration struct to store the heartbeat update interval in * @param update_factor The update-factor that needs to be applied to the ExpiryTime @@ -827,7 +763,6 @@ s_configurationInit( config->enableCandMCommandThread = TRUE; config->durablePolicies = NULL; - /*s_printTimedEvent(daemon, S_RPTLEVEL_FINER, S_THREAD_MAIN, "Initializing configuration...\n");*/ s_configurationSetDuration(&(config->serviceTerminatePeriod), S_CFG_SERVICETERMINATEPERIOD_DEFAULT); s_configurationSetLeasePeriod(config, S_CFG_LEASE_EXPIRYTIME_DEFAULT); s_configurationSetLeaseRenewalPeriod(config, S_CFG_LEASE_UPDATE_FACTOR_DEFAULT); diff --git a/src/services/spliced/code/s_configuration.h b/src/services/spliced/code/s_configuration.h index 01f0ab394..69edcc3d7 100644 --- a/src/services/spliced/code/s_configuration.h +++ b/src/services/spliced/code/s_configuration.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -43,12 +44,6 @@ extern "C" { #define S_CFG_HEARTBEAT_UPDATE_FACTOR_DEFAULT (0.2F) #define S_CFG_HEARTBEAT_UPDATE_FACTOR_MAXIMUM (1.0F) -#if 0 -#define S_CFG_HEARTBEAT_LATENCY_BUDGET_MINIMUM (0.0F) -#define S_CFG_HEARTBEAT_LATENCY_BUDGET_DEFAULT (0.0F) -#define S_CFG_HEARTBEAT_LATENCY_BUDGET_MAXIMUM (2147483647.2147483647F) -#endif - #define S_CFG_HEARTBEAT_TRANSPORT_PRIORITY_MINIMUM (0) #define S_CFG_HEARTBEAT_TRANSPORT_PRIORITY_DEFAULT (0) #define S_CFG_HEARTBEAT_TRANSPORT_PRIORITY_MAXIMUM (2147483647) diff --git a/src/services/spliced/code/s_gc.c b/src/services/spliced/code/s_gc.c index a83f31e68..b106e19a1 100644 --- a/src/services/spliced/code/s_gc.c +++ b/src/services/spliced/code/s_gc.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -33,9 +34,6 @@ C_STRUCT(s_garbageCollector) { spliced spliced; }; -/************************************************************** - * Private functions - **************************************************************/ static void * garbageCollector( void *arg) @@ -51,13 +49,6 @@ garbageCollector( return NULL; } -/************************************************************** - * constructor/destructor - **************************************************************/ - -/************************************************************** - * Protected functions - **************************************************************/ s_garbageCollector s_garbageCollectorNew( spliced daemon) @@ -94,16 +85,31 @@ s_garbageCollectorNew( return NULL; } -void +os_boolean s_garbageCollectorFree( s_garbageCollector gc) { + os_boolean result = OS_TRUE; + s_configuration config; + os_result osr; + if (gc) { /* gc might be NULL, when spliced has detected other spliced */ - ut_threadWaitExit(gc->thr, NULL); - os_condDestroy(&gc->cv); - os_mutexDestroy(&gc->mtx); - os_free(gc); + config = splicedGetConfiguration(gc->spliced); + osr = ut_threadTimedWaitExit(gc->thr, config->serviceTerminatePeriod, NULL); + if (osr == os_resultSuccess) { + os_condDestroy(&gc->cv); + os_mutexDestroy(&gc->mtx); + os_free(gc); + } else { + OS_REPORT(OS_ERROR, OS_FUNCTION, osr, + "Failed to join thread \"%s\":0x%" PA_PRIxADDR " (%s)", + ut_threadGetName(gc->thr), + (os_address)os_threadIdToInteger(ut_threadGetId(gc->thr)), + os_resultImage(osr)); + result = OS_FALSE; + } } + return result; } void @@ -122,7 +128,3 @@ s_garbageCollectorWaitForActive( } os_mutexUnlock(&gc->mtx); } - -/************************************************************** - * Public functions - **************************************************************/ diff --git a/src/services/spliced/code/s_gc.h b/src/services/spliced/code/s_gc.h index 1065eca5e..ebb59db54 100644 --- a/src/services/spliced/code/s_gc.h +++ b/src/services/spliced/code/s_gc.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -32,7 +33,7 @@ s_garbageCollector s_garbageCollectorNew( spliced daemon); -void +os_boolean s_garbageCollectorFree( s_garbageCollector gc); diff --git a/src/services/spliced/code/s_kernelManager.c b/src/services/spliced/code/s_kernelManager.c index bd87e4e5f..019a82898 100644 --- a/src/services/spliced/code/s_kernelManager.c +++ b/src/services/spliced/code/s_kernelManager.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -41,9 +42,6 @@ C_STRUCT(s_kernelManager) { #define S_RESENDMANAGER (1 << 1) #define S_CANDMCMDMANAGER (1 << 2) -/************************************************************** - * Private functions - **************************************************************/ static void * kernelManager( void *arg) @@ -92,14 +90,6 @@ cAndMCommandManager( return NULL; } - -/************************************************************** - * constructor/destructor - **************************************************************/ - -/************************************************************** - * Protected functions - **************************************************************/ s_kernelManager s_kernelManagerNew( spliced daemon) @@ -180,25 +170,57 @@ s_kernelManagerNew( return NULL; } -void +os_boolean s_kernelManagerFree( s_kernelManager km) { + os_boolean result = OS_TRUE; + s_configuration config; + os_result osr; assert(km); + config = splicedGetConfiguration(km->internal_spliced); if(km->expected & S_KERNELMANAGER){ - ut_threadWaitExit(km->thr, NULL); + osr = ut_threadTimedWaitExit(km->thr, config->serviceTerminatePeriod, NULL); + if (osr != os_resultSuccess) { + OS_REPORT(OS_ERROR, OS_FUNCTION, osr, + "Failed to join thread \"%s\":0x%" PA_PRIxADDR " (%s)", + ut_threadGetName(km->thr), + (os_address)os_threadIdToInteger(ut_threadGetId(km->thr)), + os_resultImage(osr)); + result = OS_FALSE; + } } - if(km->expected & S_RESENDMANAGER){ - ut_threadWaitExit(km->resendManager, NULL); + if(result && (km->expected & S_RESENDMANAGER)) { + osr = ut_threadTimedWaitExit(km->resendManager, config->serviceTerminatePeriod, NULL); + if (osr != os_resultSuccess) { + OS_REPORT(OS_ERROR, OS_FUNCTION, osr, + "Failed to join thread \"%s\":0x%" PA_PRIxADDR " (%s)", + ut_threadGetName(km->resendManager), + (os_address)os_threadIdToInteger(ut_threadGetId(km->resendManager)), + os_resultImage(osr)); + result = OS_FALSE; + } } - if(km->expected & S_CANDMCMDMANAGER){ + if(result && (km->expected & S_CANDMCMDMANAGER)){ u_splicedCAndMCommandDispatcherQuit(km->spliced); - ut_threadWaitExit(km->cAndMCommandManager, NULL); + osr = ut_threadTimedWaitExit(km->cAndMCommandManager, config->serviceTerminatePeriod, NULL); + if (osr != os_resultSuccess) { + OS_REPORT(OS_ERROR, OS_FUNCTION, osr, + "Failed to join thread \"%s\":0x%" PA_PRIxADDR " (%s)", + ut_threadGetName(km->cAndMCommandManager), + (os_address)os_threadIdToInteger(ut_threadGetId(km->cAndMCommandManager)), + os_resultImage(osr)); + result = OS_FALSE; + } } - os_condDestroy(&km->cv); - os_mutexDestroy(&km->mtx); - os_free(km); + if (result) { + os_condDestroy(&km->cv); + os_mutexDestroy(&km->mtx); + os_free(km); + } + + return result; } void @@ -224,7 +246,3 @@ s_kernelManagerWaitForActive( } os_mutexUnlock(&km->mtx); } - -/************************************************************** - * Public functions - **************************************************************/ diff --git a/src/services/spliced/code/s_kernelManager.h b/src/services/spliced/code/s_kernelManager.h index 6b5b3a542..900644b03 100644 --- a/src/services/spliced/code/s_kernelManager.h +++ b/src/services/spliced/code/s_kernelManager.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -31,7 +32,8 @@ extern "C" { s_kernelManager s_kernelManagerNew( spliced daemon); -void + +os_boolean s_kernelManagerFree( s_kernelManager km); diff --git a/src/services/spliced/code/s_misc.h b/src/services/spliced/code/s_misc.h index 65fe041e5..48a4c16d1 100644 --- a/src/services/spliced/code/s_misc.h +++ b/src/services/spliced/code/s_misc.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/services/spliced/code/s_report.c b/src/services/spliced/code/s_report.c index b97363edb..a2bdf42e6 100644 --- a/src/services/spliced/code/s_report.c +++ b/src/services/spliced/code/s_report.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/services/spliced/code/s_shmMonitor.c b/src/services/spliced/code/s_shmMonitor.c index f0428a598..a46d8d026 100644 --- a/src/services/spliced/code/s_shmMonitor.c +++ b/src/services/spliced/code/s_shmMonitor.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -35,9 +36,9 @@ #include "spliced.h" #if 0 - #define TRACE_PKILL printf +#define TRACE_PKILL printf #else - #define TRACE_PKILL(...) +#define TRACE_PKILL(...) #endif typedef enum { @@ -97,8 +98,7 @@ shmMonitorMain( os_mutexUnlock(&_this->mutex); - /* - * Allow the u_splicedCleanupProcessInfo() to take as + /* Allow the u_splicedCleanupProcessInfo() to take as * long as MAX(leasePeriod, serviceTerminatePeriod). * This is set in the threadsMonitor as the threads * interval. @@ -148,8 +148,9 @@ shmMonitorMain( } else if (result == os_resultUnavailable) { /* client list is empty so we need to give up some cpu time - in order that it can be initialised on non timesliced systems - e.g. vxworks kernel builds */ + * in order that it can be initialised on non timesliced systems + * e.g. vxworks kernel builds + */ ut_sleep(_this->thr, 100*OS_DURATION_MICROSECOND); } } @@ -206,22 +207,37 @@ s_shmMonitorNew( return NULL; } -void +os_boolean s_shmMonitorFree( s_shmMonitor _this) { + os_boolean result = OS_TRUE; + s_configuration config; + os_result osr; + if (_this != NULL) { + config = splicedGetConfiguration(_this->spliceDaemon); os_mutexLock(&_this->mutex); _this->terminate = OS_TRUE; os_mutexUnlock(&_this->mutex); if (_this->thr != NULL) { - (void)ut_threadWaitExit(_this->thr, NULL); - _this->thr = NULL; + osr = ut_threadTimedWaitExit(_this->thr, config->serviceTerminatePeriod, NULL); + if (osr != os_resultSuccess) { + OS_REPORT(OS_ERROR, OS_FUNCTION, osr, + "Failed to join thread \"%s\":0x%" PA_PRIxADDR " (%s)", + ut_threadGetName(_this->thr), + (os_address)os_threadIdToInteger(ut_threadGetId(_this->thr)), + os_resultImage(osr)); + result = OS_FALSE; + } + } + if (result) { + os_mutexDestroy(&_this->mutex); + os_condDestroy(&_this->cleanCondition); + os_free(_this); } - os_mutexDestroy(&_this->mutex); - os_condDestroy(&_this->cleanCondition); - os_free(_this); } + return result; } /** diff --git a/src/services/spliced/code/s_shmMonitor.h b/src/services/spliced/code/s_shmMonitor.h index d7baaa133..365aaaf63 100644 --- a/src/services/spliced/code/s_shmMonitor.h +++ b/src/services/spliced/code/s_shmMonitor.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -33,7 +34,7 @@ s_shmMonitor s_shmMonitorNew( spliced splicedaemon); -void +os_boolean s_shmMonitorFree( s_shmMonitor _this); diff --git a/src/services/spliced/code/s_threadsMonitor.c b/src/services/spliced/code/s_threadsMonitor.c old mode 100644 new mode 100755 index c6834dc53..588b9fdc5 --- a/src/services/spliced/code/s_threadsMonitor.c +++ b/src/services/spliced/code/s_threadsMonitor.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -57,6 +58,7 @@ C_STRUCT(s_threadsMonitor) /* number of seconds before going into error state. */ static const os_duration POLL_LIMIT = OS_DURATION_INIT(1, 0); +static const os_duration POLL_INITIAL = OS_DURATION_INIT(1*60, 0); static void s_threadsReport( @@ -73,6 +75,31 @@ s_threadsWatchdogMain( void* arg); +void +s_threadsMonitorSetInterval( + spliced splicedaemon) +{ + s_configuration config; + ut_threads threads; + os_duration interval; + + assert(splicedaemon); + + config = splicedGetConfiguration(splicedaemon); + threads = splicedGetThreads(splicedaemon); + assert(config); + /* Set allowed thread progress delay interval. + * This will be the thread checking polling interval as well. + */ + interval = (os_durationCompare(config->leasePeriod, config->serviceTerminatePeriod) == OS_MORE) ? + config->leasePeriod : + config->serviceTerminatePeriod; + interval = (os_durationCompare(interval, POLL_LIMIT) == OS_MORE) ? + interval : + POLL_LIMIT; + ut_threadsSetInterval(threads, interval); +} + s_threadsMonitor s_threadsMonitorNew( spliced splicedaemon) @@ -93,14 +120,7 @@ s_threadsMonitorNew( _this->threads = splicedGetThreads(splicedaemon); _this->main = ut_threadLookupSelf(_this->threads); - /* Set allowed thread progress delay interval. - * This will be the thread checking polling interval as well. */ - _this->interval = (os_durationCompare(config->leasePeriod, config->serviceTerminatePeriod) == OS_MORE) ? - config->leasePeriod : - config->serviceTerminatePeriod; - _this->interval = (os_durationCompare(_this->interval, POLL_LIMIT) == OS_MORE) ? - config->leasePeriod : - POLL_LIMIT; + _this->interval = POLL_INITIAL; ut_threadsSetInterval(_this->threads, _this->interval); result = os_mutexInit(&_this->terminate.mtx, NULL); @@ -115,7 +135,8 @@ s_threadsMonitorNew( } /* Use the shared memory monitor thread attribute. - * We will mainly be monitoring that thread anyway. */ + * We will mainly be monitoring that thread anyway. + */ ut_threadCreate(splicedGetThreads(splicedaemon), &(_this->watchdog), "threadsWatchdog", &config->shmMonitorAttribute, s_threadsWatchdogMain, _this); if (_this->watchdog == NULL) { OS_REPORT(OS_ERROR, OSRPT_CNTXT_SPLICED, 0, "Failed to start threads watchdog"); @@ -135,12 +156,16 @@ s_threadsMonitorNew( return NULL; } - -void +os_boolean s_threadsMonitorFree( s_threadsMonitor _this) { + os_boolean result = OS_TRUE; + s_configuration config; + os_result osr; + if (_this != NULL) { + config = splicedGetConfiguration(_this->spliced); /* Stop watchdog thread. */ os_mutexLock(&_this->terminate.mtx); _this->terminate.stop = OS_TRUE; @@ -148,14 +173,23 @@ s_threadsMonitorFree( os_mutexUnlock(&_this->terminate.mtx); /* Wait for the watchdog thread. */ - (void)ut_threadWaitExit(_this->watchdog, NULL); - _this->watchdog = NULL; - - /* Delete variables. */ - os_mutexDestroy(&_this->terminate.mtx); - os_condDestroy(&_this->terminate.cnd); - os_free(_this); + osr = ut_threadTimedWaitExit(_this->watchdog, config->serviceTerminatePeriod, NULL); + if (osr != os_resultSuccess) { + OS_REPORT(OS_ERROR, OS_FUNCTION, osr, + "Failed to join thread \"%s\":0x%" PA_PRIxADDR " (%s)", + ut_threadGetName(_this->watchdog), + (os_address)os_threadIdToInteger(ut_threadGetId(_this->watchdog)), + os_resultImage(osr)); + result = OS_FALSE; + } else { + _this->watchdog = NULL; + /* Delete variables. */ + os_mutexDestroy(&_this->terminate.mtx); + os_condDestroy(&_this->terminate.cnd); + os_free(_this); + } } + return result; } static void @@ -202,14 +236,13 @@ s_threadsReport( if ((thread != NULL) && (changed) && (!alive)) { #ifndef S_DEBUG_THREADS - ut_threadToString(thread, alive, info, report->bfr, S_REPORT_BUFFER_SIZE); + ut_threadToString(thread, alive, info, report->bfr, sizeof(report->bfr)); s_printEvent(splicedaemon, S_RPTLEVEL_SEVERE, "Thread deadlocked: %s\n", report->bfr); OS_REPORT(OS_ERROR, caller, 0, "Thread deadlocked: %s", report->bfr); TRACE_THREADS("Thread deadlocked: %s\n", report->bfr); #endif - /* - * When a thread fails to make progress, you'd still like to shutdown + /* When a thread fails to make progress, you'd still like to shutdown * as much and as cleanly as possible. * This can be done by signaling the spliced to terminate when a thread * deadlocks (see s_threadsWatchdogMain()). @@ -221,7 +254,7 @@ s_threadsReport( s_printEvent(splicedaemon, S_RPTLEVEL_SEVERE, "The spliced main thread found not-responding. " "A clean shutdown is highly unlikely. " "Best action left: abort!\n"); - OS_REPORT(OS_ERROR, caller, 0, "The spliced main thread found not-responding. " + OS_REPORT(OS_FATAL, caller, 0, "The spliced main thread found not-responding. " "A clean shutdown is highly unlikely. " "Best action left: abort!"); TRACE_THREADS("The spliced main thread found not-responding. " @@ -252,8 +285,9 @@ s_threadsWatchdogMain( while(_this->terminate.stop == OS_FALSE) { /* Sleep until polling time or termination. */ osr = ut_condTimedWait(_this->watchdog, &_this->terminate.cnd, &_this->terminate.mtx, POLL_LIMIT); - if (osr == os_resultSuccess) { - /* Condition triggered: likely a termination request. */ + if ((osr == os_resultSuccess) || + (_this->terminate.stop == OS_TRUE)) { + /* No action required */ } else if (osr == os_resultTimeout) { /* Condition timed out: poll the threads progress. */ report.bfr[0] = '\0'; diff --git a/src/services/spliced/code/s_threadsMonitor.h b/src/services/spliced/code/s_threadsMonitor.h old mode 100644 new mode 100755 index ed0c4178c..01332870e --- a/src/services/spliced/code/s_threadsMonitor.h +++ b/src/services/spliced/code/s_threadsMonitor.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,11 +30,16 @@ extern "C" { extern const char* s_main_tread_name; +void +s_threadsMonitorSetInterval( + spliced splicedaemon); + + s_threadsMonitor s_threadsMonitorNew( spliced splicedaemon); -void +os_boolean s_threadsMonitorFree( s_threadsMonitor _this); diff --git a/src/services/spliced/code/s_types.h b/src/services/spliced/code/s_types.h index 6678550e8..1a26e23c7 100644 --- a/src/services/spliced/code/s_types.h +++ b/src/services/spliced/code/s_types.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/services/spliced/code/serviceMonitor.c b/src/services/spliced/code/serviceMonitor.c index b17c1ce03..79f128419 100644 --- a/src/services/spliced/code/serviceMonitor.c +++ b/src/services/spliced/code/serviceMonitor.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -37,9 +38,6 @@ C_STRUCT(serviceMonitor) u_serviceManager serviceManager; }; -/************************************************************** - * Private functions - **************************************************************/ static c_ulong serviceMonitorMain( u_observable o, @@ -119,9 +117,9 @@ waitForDiedService( * up to 10 seconds. */ sleepTime = 100*OS_DURATION_MILLISECOND; - while (((result = os_procCheckStatus(info->procId, &dummy) == os_resultBusy)) && (count < 100)) { + while (((result = os_procCheckStatus(info->procId, &dummy)) == os_resultBusy) && (count < 100)) { count++; - os_sleep(sleepTime); + ospl_os_sleep(sleepTime); } #if !defined OS_WIN32_DEFS_H @@ -131,7 +129,7 @@ waitForDiedService( count = 0; while (((result = os_procCheckStatus(info->procId, &dummy) == os_resultBusy)) && (count < 100)) { count++; - os_sleep(sleepTime); + ospl_os_sleep(sleepTime); } } #endif @@ -185,7 +183,8 @@ serviceMonitorProcessDiedservice( } else { OS_REPORT(OS_INFO, "os_procServiceDestroy", 0, "Service %s (%d) is about to die, executing died script '%s' succeeded", info->name, info->procId, diedscript); /* wait until the script has finished or wait max. 5 sec - * before actually killing the process */ + * before actually killing the process + */ now = os_timeMGet(); endTime = os_timeMAdd(now, 5*OS_DURATION_SECOND); while (os_timeMCompare(now, endTime) == OS_LESS) { @@ -193,7 +192,7 @@ serviceMonitorProcessDiedservice( if (result != os_resultBusy) { break; } - os_sleep(100*OS_DURATION_MILLISECOND); + ospl_os_sleep(100*OS_DURATION_MILLISECOND); now = os_timeMGet(); } } @@ -218,7 +217,8 @@ serviceMonitorProcessDiedservice( waitForDiedService(info); /* Only restart the service when shm is clean, when unclean the - * domain will terminate. */ + * domain will terminate. + */ if ((s_shmMonitorIsClean(splicedGetShmMonitor(monitor->spliceDaemon))) && (!splicedIsDoingSystemHalt(monitor->spliceDaemon))) { result = os_procCreate(info->command, info->name, args, &info->procAttr, &info->procId); @@ -262,9 +262,6 @@ serviceMonitorProcessDiedservice( } } -/************************************************************** - * constructor/destructor - **************************************************************/ serviceMonitor serviceMonitorNew( spliced spliceDaemon) @@ -276,9 +273,8 @@ serviceMonitorNew( if (this != NULL) { this->spliceDaemon = spliceDaemon; this->serviceManager = splicedGetServiceManager(this->spliceDaemon); - u_observableSetListenerMask(u_observable(this->serviceManager), - V_EVENT_SERVICESTATE_CHANGED); u_observableAddListener(u_observable(this->serviceManager), + V_EVENT_SERVICESTATE_CHANGED, serviceMonitorMain, (c_voidp)this); } @@ -292,26 +288,17 @@ serviceMonitorFree( { if (this != NULL) { /* stop listening for services */ - u_observableSetListenerMask(u_observable(this->serviceManager), 0); u_observableRemoveListener(u_observable(this->serviceManager), serviceMonitorMain); os_free(this); } } -/************************************************************** - * Protected functions - **************************************************************/ - -/************************************************************** - * Public functions - **************************************************************/ void serviceMonitorStop( serviceMonitor this) { if (this != NULL) { - u_observableSetListenerMask(u_observable(this->serviceManager), 0); u_observableRemoveListener(u_observable(this->serviceManager), serviceMonitorMain); + ut_threadAwake(ut_threadLookupSelf(splicedGetThreads(this->spliceDaemon))); } - ut_threadAwake(ut_threadLookupSelf(splicedGetThreads(this->spliceDaemon))); } diff --git a/src/services/spliced/code/serviceMonitor.h b/src/services/spliced/code/serviceMonitor.h index 58f4682c9..9b3110189 100644 --- a/src/services/spliced/code/serviceMonitor.h +++ b/src/services/spliced/code/serviceMonitor.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/services/spliced/code/spliced.c b/src/services/spliced/code/spliced.c old mode 100644 new mode 100755 index 399ae640d..b21072b95 --- a/src/services/spliced/code/spliced.c +++ b/src/services/spliced/code/spliced.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -47,6 +48,9 @@ #include "os_signalHandler.h" #include "sr_componentInfo.h" #include "ut_thread.h" +#ifdef OSPL_ENTRY_OVERRIDE +#include "ospl_entry_override.h" +#endif #ifdef OSPL_ENV_SHMT #include @@ -84,10 +88,6 @@ C_STRUCT(spliced) s_threadsMonitor threadsMonitor; }; -/************************************************************** - * Private functions - **************************************************************/ - static int argumentsCheck( spliced _this, @@ -148,7 +148,8 @@ leaseRenewThread( self = ut_threadLookupSelf(_this->threads); /* Set the previous renew-time to maximum value that can be passed to - * os_timeMDiff(...), so no lag is reported for the first lease renewal. */ + * os_timeMDiff(...), so no lag is reported for the first lease renewal. + */ prevRenewed = OS_TIMEM_INFINITE; do { @@ -170,20 +171,19 @@ leaseRenewThread( OS_DURATION_GET_SECONDS(lag), OS_DURATION_GET_NANOSECONDS(lag)); } /* Terminate flag is also accessed outside the mutex lock. This is no problem, - * protection guarantees no wait entry while setting the flag. */ + * protection guarantees no wait entry while setting the flag. + */ os_mutexLock(&_this->terminate.mtx); if ((flag = _this->terminate.flag) == SPLICED_EXIT_CODE_CONTINUE) { - ut_condTimedWait(self, &_this->terminate.cond, &_this->terminate.mtx, _this->config->leaseRenewalPeriod); + (void)ut_condTimedWait(self, &_this->terminate.cond, &_this->terminate.mtx, _this->config->leaseRenewalPeriod); } os_mutexUnlock(&_this->terminate.mtx); } while ((flag == SPLICED_EXIT_CODE_CONTINUE) && (result == U_RESULT_OK)); - { - result = u_serviceRenewLease(u_service(_this->service), 300*OS_DURATION_SECOND); - if (result != U_RESULT_OK) { - OS_REPORT(OS_ERROR, OSRPT_CNTXT_SPLICED, 0, - "Failed to update service lease"); - } + result = u_serviceRenewLease(u_service(_this->service), 300*OS_DURATION_SECOND); + if (result != U_RESULT_OK) { + OS_REPORT(OS_ERROR, OSRPT_CNTXT_SPLICED, 0, + "Failed to update service lease"); } return NULL; @@ -264,10 +264,13 @@ startHeartbeatManager( return started; } -static void +static os_boolean stopHeartbeatManager( - spliced _this) + spliced _this) { + os_boolean result = OS_TRUE; + s_configuration config; + os_result osr; v_leaseManager lm; u_splicedStopHeartbeat(_this->service); @@ -276,11 +279,24 @@ stopHeartbeatManager( if (lm != NULL) { v_leaseManagerNotify(lm, NULL, V_EVENT_TERMINATE); if (_this->heartbeatManager != NULL) { - ut_threadWaitExit(_this->heartbeatManager, NULL); + config = splicedGetConfiguration(_this); + osr = ut_threadTimedWaitExit(_this->heartbeatManager, config->serviceTerminatePeriod, NULL); + if (osr == os_resultSuccess) { + OS_REPORT(OS_ERROR, OS_FUNCTION, 0, + "Failed to join thread \"%s\":0x%" PA_PRIxADDR " (%s)", + ut_threadGetName(_this->heartbeatManager), + (os_address)os_threadIdToInteger(ut_threadGetId(_this->heartbeatManager)), + os_resultImage(osr)); + result = OS_FALSE; + } + } + if (result) { + c_free(lm); } - c_free(lm); } ut_threadAwake(ut_threadLookupSelf(_this->threads)); + + return result; } /* The function below is intended to retrieve the federation @@ -341,7 +357,7 @@ durabilityClientStart(spliced _this) _this->service, _this->config->durablePolicies, requestPartition, - "clientDurabilityPartition", /* LH: Global partition, currently not used */ + "clientDurabilityPartition", privatePartition); os_free(requestPartition); @@ -370,21 +386,35 @@ durabilityClientStart(spliced _this) return (_this->durabilityClient != NULL); } -static void +static os_boolean durabilityClientStop(spliced _this) { - u_result u_res; + os_boolean result = OS_TRUE; + s_configuration config; + os_result osr; + u_result ures; if (_this->durabilityClient != NULL) { - u_res = u_splicedDurabilityClientTerminate(_this->service); - if (u_res == U_RESULT_OK) { - (void)ut_threadWaitExit(_this->durabilityClient, NULL); + ures = u_splicedDurabilityClientTerminate(_this->service); + if (ures == U_RESULT_OK) { + config = splicedGetConfiguration(_this); + osr = ut_threadTimedWaitExit(_this->durabilityClient, config->serviceTerminatePeriod, NULL); + if (osr != os_resultSuccess) { + OS_REPORT(OS_ERROR, OS_FUNCTION, osr, + "Failed to join thread \"%s\":0x%" PA_PRIxADDR " (%s)", + ut_threadGetName(_this->durabilityClient), + (os_address)os_threadIdToInteger(ut_threadGetId(_this->durabilityClient)), + os_resultImage(osr)); + result = OS_FALSE; + } } else { OS_REPORT(OS_WARNING, "spliced::durabilityClientStop", 0, "Failed to terminate durability client"); } } ut_threadAwake(ut_threadLookupSelf(_this->threads)); + + return result; } const os_char* @@ -401,16 +431,19 @@ splicedGetDomainName( static os_result exitRequestHandler( os_callbackArg ignore, + void *callingThreadContext, void * arg) { struct terminate *terminate; + OS_UNUSED_ARG(callingThreadContext); OS_UNUSED_ARG(ignore); terminate = (struct terminate*) arg; /* The os_callbackArg can be ignored, because setting the below flag will - * cause proper exit of the spliced. */ + * cause proper exit of the spliced. + */ os_mutexLock(&terminate->mtx); terminate->flag = SPLICED_EXIT_CODE_OK; os_condBroadcast(&terminate->cond); @@ -560,8 +593,8 @@ deployLibrary( os_libraryAttrInit(&libraryAttr); /* Applications can have their library overriden if the user - * specifies the library attribute */ - + * specifies the library attribute + */ if (!info->isService && info->library && strlen(info->library) > 0) { libraryName = info->library; @@ -580,7 +613,8 @@ deployLibrary( { /* Derive entry point name from Command. When deploying a service * we use the "ospl_" prefix as we have full control over the - * names of these libraries */ + * names of these libraries + */ entryPoint = os_malloc (sizeof (char*) * (strlen(info->command) + 6)); sprintf (entryPoint, "ospl_%s", info->command); } @@ -620,7 +654,8 @@ deployLibrary( { info->threadId = id; /* Don't believe that a wait/sleep is required here. - * historically there was one */ + * historically there was one + */ } } else { result = os_resultFail; @@ -672,11 +707,10 @@ startServices( } #endif - /* - In case we haven't logged anything yet we call these methods now - before we start any other domain services - to (potentially) remove the previous versions of the files - */ + /* In case we haven't logged anything yet we call these methods now + * before we start any other domain services + * to (potentially) remove the previous versions of the files + */ os_free(os_reportGetInfoFileName()); os_free(os_reportGetErrorFileName()); @@ -834,9 +868,6 @@ startApplications( } } -/************************************************************** - * configuration - **************************************************************/ static void getSingleProcessValue( spliced _this, @@ -971,9 +1002,6 @@ readConfiguration( } } -/************************************************************** - * Public functions - **************************************************************/ s_configuration splicedGetConfiguration( spliced spliceDaemon) @@ -1160,33 +1188,6 @@ splicedGetServiceInfo( return ci; } -#if 0 -static c_bool -deleteContainedEntitiesForApplParticipants( - u_participant participant, - c_voidp arg) -{ - u_result result; - - assert(participant); - - OS_UNUSED_ARG(arg); - - if(u_objectKind(u_object(participant)) != U_SERVICE) { - result = u_participantDeleteContainedEntities(participant); - if(result != U_RESULT_OK) { - OS_REPORT(OS_ERROR, OSRPT_CNTXT_SPLICED, 0, - "An error occurred during termination. Unable to delete " - "contained entities of participant '0x%x'; " - "u_participantDeleteContainedEntities(...) returned %s.", - participant, os_resultImage(result)); - } /* when this fails, continue with the next participant */ - } - return TRUE; -} -#endif - - static void waitForServices( spliced _this) @@ -1209,10 +1210,8 @@ waitForServices( stopTime = os_timeMAdd(curTime, _this->config->serviceTerminatePeriod); terminateCount = 0; - ut_threadAsleep(self, (os_uint32)OS_DURATION_GET_SECONDS(_this->config->serviceTerminatePeriod)); do { - /* Wait for services to reach final state TERMINATED. - */ + /* Wait for services to reach final state TERMINATED. */ names = u_serviceManagerGetServices(_this->serviceManager, STATE_TERMINATED); name = c_iterTakeFirst(names); while (name != NULL) { @@ -1244,11 +1243,10 @@ waitForServices( curTime = os_timeMGet(); if( (os_timeMCompare(curTime, stopTime) == OS_LESS) && (terminateCount < _this->nrKnownServices)) { - os_sleep(pollDelay); + ut_sleep(self, pollDelay); } curTime = os_timeMGet(); } while ((os_timeMCompare(curTime, stopTime) == OS_LESS) && (terminateCount < (_this->nrKnownServices - _this->nrTerminatedServices))); - ut_threadAwake(self); } } @@ -1268,6 +1266,7 @@ killServices( OS_REPORT(OS_WARNING, OSRPT_CNTXT_SPLICED, 0, "Service '%s' did not terminate within serviceTerminatePeriod, thread will be forcefully destroyed.", _this->knownServices[j]->name); + count++; } } } else { @@ -1397,10 +1396,7 @@ setState( return ok; } -/************************************************************** - * Main - **************************************************************/ -OPENSPLICE_ENTRYPOINT (ospl_spliced) +OPENSPLICE_SERVICE_ENTRYPOINT (ospl_spliced, spliced) { os_sharedHandle shm = NULL; spliced _this; @@ -1410,6 +1406,8 @@ OPENSPLICE_ENTRYPOINT (ospl_spliced) u_result uresult; ut_thread self; os_signalHandlerExitRequestHandle erh = os_signalHandlerExitRequestHandleNil; + os_boolean result = OS_TRUE; + os_uint32 runCount = 0; /* Set the flag in the user layer that spliced is running in this process. * For a hybrid multi-domain SHM and SP deployment this is not OK. */ @@ -1505,7 +1503,7 @@ OPENSPLICE_ENTRYPOINT (ospl_spliced) if(!_this->isSingleProcess){ #ifndef INTEGRITY - erh = os_signalHandlerRegisterExitRequestCallback(exitRequestHandler, &_this->terminate); + erh = os_signalHandlerRegisterExitRequestCallback(exitRequestHandler, NULL, NULL, NULL, &_this->terminate); #endif if ((_this->shmMonitor = s_shmMonitorNew(_this)) == NULL) { /* Error reported by s_shmMonitorNew(...). */ @@ -1587,12 +1585,20 @@ OPENSPLICE_ENTRYPOINT (ospl_spliced) /* Start applications specified in XML on a best effort basis. Note * this will only succeed if this is a SingleProcess configuration, - * and leave warning messages otherwise. */ + * and leave warning messages otherwise. + */ startApplications(_this); + /**************************************************************************/ /* RUNNING PHASE */ /**************************************************************************/ + /* Set thread monitor interval to configured value. It starts with an interval + ** of 60 seconds as sometimes startin up takes a while (e.g. when Valgrind is used + ** As all threads are started now, ajust polling time to respone quicker on + ** a hanging thread + */ + s_threadsMonitorSetInterval(_this); os_mutexLock(&_this->terminate.mtx); while (_this->terminate.flag == SPLICED_EXIT_CODE_CONTINUE) { (void)ut_condWait(self, &_this->terminate.cond, &_this->terminate.mtx); @@ -1618,62 +1624,117 @@ OPENSPLICE_ENTRYPOINT (ospl_spliced) err_startServices: assert(splicedGetTerminateFlag(_this) != SPLICED_EXIT_CODE_CONTINUE); setState(_this, STATE_TERMINATING); - if(stopServices(_this, OS_TRUE) > 0) { + runCount = stopServices(_this, OS_TRUE); + if (runCount > 0) { shm = sharedMemoryHandle(_this); + /* not all services terminated successfully. if this occurs in single + * process mode, do not cleanup to avoid threads reading or writing + * corrupt memory. instead report to the application that it failed so + * that it can cleanup it's resources and abort. + */ + if(_this->isSingleProcess){ + goto fatal_svcsNok; + } } + err_changeStateOperational: assert(splicedGetTerminateFlag(_this) != SPLICED_EXIT_CODE_CONTINUE); - (void) ut_threadWaitExit(lrt, NULL); + osresult = ut_threadTimedWaitExit(lrt, _this->config->serviceTerminatePeriod, NULL); + if (osresult != os_resultSuccess) { + OS_REPORT(OS_ERROR, OS_FUNCTION, osresult, + "Failed to join thread \"%s\":0x%" PA_PRIxADDR " (%s)", + ut_threadGetName(lrt), + (os_address)os_threadIdToInteger(ut_threadGetId(lrt)), + os_resultImage(osresult)); + result = OS_FALSE; + } setState(_this, STATE_TERMINATING); err_startLeaseRenewThread: - durabilityClientStop(_this); + if (result) { + durabilityClientStop(_this); + } err_startDurabilityClient: - stopHeartbeatManager(_this); + if (result) { + result = stopHeartbeatManager(_this); + } err_startHeartbeatManager: - serviceMonitorStop(_this->serviceMon); - serviceMonitorFree(_this->serviceMon); + if (result) { + serviceMonitorStop(_this->serviceMon); + serviceMonitorFree(_this->serviceMon); + } err_serviceMonitorNew: u_splicedPrepareTermination(_this->service); - s_garbageCollectorFree(_this->gc); + if (result) { + result = s_garbageCollectorFree(_this->gc); + } err_garbageCollectorNew: u_splicedPrepareTermination(_this->service); - s_kernelManagerFree(_this->km); + if (result) { + result = s_kernelManagerFree(_this->km); + } err_kernelManagerNew: - u_objectFree(_this->serviceManager); + if (result) { + u_objectFree(_this->serviceManager); + } err_userviceManagerNew: - s_shmMonitorFree(_this->shmMonitor); + if (result) { + result = s_shmMonitorFree(_this->shmMonitor); + } err_shmMonitor: - splicedKnownServicesFree(_this); - splicedApplicationsFree(_this); + if (runCount == 0) { + splicedKnownServicesFree(_this); + splicedApplicationsFree(_this); + } err_changeStateInitializing: setState(_this, STATE_TERMINATED); u_splicedSetInProcess(FALSE); os_signalHandlerUnregisterExitRequestCallback(erh); - u_objectFree(_this->service); + if (result) { + u_objectFree(_this->service); + } if(shm){ /* Normally SHM is expected to be gone if spliced terminates normally. * If however one of the services was killed during shutdown, we try a - * little harder to wipe the traces. */ + * little harder to wipe the traces. + */ forcedShmDestroy(shm); } err_usplicedNew: - os_free(_this->cfg_handle.uri); + if (result) { + os_free(_this->cfg_handle.uri); + } err_nameOrUri: - s_threadsMonitorFree(_this->threadsMonitor); + if (result) { + result = s_threadsMonitorFree(_this->threadsMonitor); + } err_threadsMonitor: - ut_threadsFree(_this->threads); + if (result) { + ut_threadsFree(_this->threads); + } else { + ut_thread self = ut_threadLookupSelf(_this->threads); + ut_threadAsleep(self, UT_SLEEP_INDEFINITELY); + } err_threadsManager: - s_configurationFree(_this->config); + if (result) { + s_configurationFree(_this->config); + } err_configurationNew: assert(splicedGetTerminateFlag(_this) != SPLICED_EXIT_CODE_CONTINUE); retCode = splicedGetTerminateFlag(_this); - os_condDestroy(&_this->terminate.cond); + if (result) { + os_condDestroy(&_this->terminate.cond); + } err_condInit: - os_mutexDestroy(&_this->terminate.mtx); + if (result) { + os_mutexDestroy(&_this->terminate.mtx); + } err_mutexInit: - os_free(_this); + if (result) { + os_free(_this); + } /* No explicit undo for u_userInitialize(). */ err_userInitialize: + return retCode; @@ -1682,12 +1743,18 @@ OPENSPLICE_ENTRYPOINT (ospl_spliced) /**************************************************************************/ fatal_shmNok: /* Resources are leaked in this case */ - if(stopServices(_this, OS_FALSE) > 0 ){ + if(stopServices(_this, OS_FALSE) > 0){ shm = sharedMemoryHandle(_this); - forcedShmDestroy(shm); + if (shm) { + forcedShmDestroy(shm); + } } retCode = splicedGetTerminateFlag(_this); return retCode; + +fatal_svcsNok: /* one or more service threads did not stop */ + retCode = SPLICED_EXIT_CODE_UNRECOVERABLE_ERROR; + return retCode; } diff --git a/src/services/spliced/code/spliced.h b/src/services/spliced/code/spliced.h index 143015ab3..e6ee746a4 100644 --- a/src/services/spliced/code/spliced.h +++ b/src/services/spliced/code/spliced.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -56,7 +57,7 @@ extern "C" { #define SPLICED_EXIT_CODE_UNRECOVERABLE_ERROR (33) -#define SPLICED_EXIT_CODE_INAPPLICABLE_CONFIGURATION 34 +#define SPLICED_EXIT_CODE_INAPPLICABLE_CONFIGURATION (34) #define SPLICED_SHM_OK (1) #define SPLICED_SHM_NOK (0) diff --git a/src/services/spliced/code/sr_componentInfo.c b/src/services/spliced/code/sr_componentInfo.c index 1dc0b3868..0bb08b7f4 100644 --- a/src/services/spliced/code/sr_componentInfo.c +++ b/src/services/spliced/code/sr_componentInfo.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -41,9 +42,6 @@ #define RR_RESTART_STR "restart" #define RR_HALT_STR "systemhalt" -/************************************************************** - * Private functions - **************************************************************/ static c_bool cfgGetCommand( sr_componentInfo ci, @@ -430,7 +428,8 @@ cfgGetServiceComponentInfo( u_cfElementAttributeBoolValue(info, ATTR_ENABLED, &enabled); /* Services have support for name, command, configuration, arguments - * schedule, priority and restart rule */ + * schedule, priority and restart rule + */ if (enabled) { r = cfgGetCommand(ci, info); if (r == TRUE) { @@ -481,9 +480,6 @@ cfgGetApplicationComponentInfo( return !((int)r); } -/************************************************************** - * constructor/destructor - **************************************************************/ sr_componentInfo sr_componentInfoServiceNew( u_cfElement info, @@ -541,12 +537,3 @@ sr_componentInfoFree( os_free(componentInfo); } } - -/************************************************************** - * Protected functions - **************************************************************/ - -/************************************************************** - * Public functions - **************************************************************/ - diff --git a/src/services/spliced/code/sr_componentInfo.h b/src/services/spliced/code/sr_componentInfo.h index 58b73fe1c..a1c616399 100644 --- a/src/services/spliced/code/sr_componentInfo.h +++ b/src/services/spliced/code/sr_componentInfo.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/services/spliced/makefile.mak b/src/services/spliced/makefile.mak index 710a942fb..67a5a18ad 100644 --- a/src/services/spliced/makefile.mak +++ b/src/services/spliced/makefile.mak @@ -13,11 +13,13 @@ IDLPPTYPES = DDS::Time_t,DDS::Duration_t IDLPPFLAGS := -N -S -l c include $(OSPL_HOME)/setup/makefiles/target.mak +-include $(OSPL_OUTER_HOME)/setup/makefiles/commercial.mak CPPFLAGS += -DOSPL_BUILD_SPLICED CFLAGS += $(SHCFLAGS) CFLAGS += $(CFLAGS_XSTRICT) +CFLAGS += $(CFLAGS_W_ERROR) LDFLAGS += $(SHLDFLAGS) LDLIBS += $(SHLDLIBS) @@ -31,5 +33,4 @@ CINCS += -I$(OSPL_HOME)/src/user/code CINCS += -I$(OSPL_HOME)/src/utilities/include CINCS += -I$(OSPL_HOME)/src/configuration/config/include - -include $(DEPENDENCIES) diff --git a/src/tools/cm/common/code/org/opensplice/common/CommonException.java b/src/tools/cm/common/code/org/opensplice/common/CommonException.java index 3cba96541..d6fdd0b16 100644 --- a/src/tools/cm/common/code/org/opensplice/common/CommonException.java +++ b/src/tools/cm/common/code/org/opensplice/common/CommonException.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cm/common/code/org/opensplice/common/SampleModelSizeException.java b/src/tools/cm/common/code/org/opensplice/common/SampleModelSizeException.java index 31c00cff3..772ec123f 100644 --- a/src/tools/cm/common/code/org/opensplice/common/SampleModelSizeException.java +++ b/src/tools/cm/common/code/org/opensplice/common/SampleModelSizeException.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cm/common/code/org/opensplice/common/controller/AssignmentResult.java b/src/tools/cm/common/code/org/opensplice/common/controller/AssignmentResult.java index 0c10aaf0a..6a5622034 100644 --- a/src/tools/cm/common/code/org/opensplice/common/controller/AssignmentResult.java +++ b/src/tools/cm/common/code/org/opensplice/common/controller/AssignmentResult.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cm/common/code/org/opensplice/common/controller/CoherentPublishControllerCommon.java b/src/tools/cm/common/code/org/opensplice/common/controller/CoherentPublishControllerCommon.java index c99e3ffc1..b56157571 100644 --- a/src/tools/cm/common/code/org/opensplice/common/controller/CoherentPublishControllerCommon.java +++ b/src/tools/cm/common/code/org/opensplice/common/controller/CoherentPublishControllerCommon.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -70,7 +71,6 @@ public void setView(CoherentPublishFrameCommon _view) { @Override public void actionPerformed(ActionEvent e){ String command = e.getActionCommand(); -// logger.logp(Level.INFO, "CoherentSetPublisher", "actionPerformed", command); try{ if(command.equals("cancel")){ @@ -204,7 +204,7 @@ private void maybeShowPopup(MouseEvent e) { if (selectionIndex > -1) { Writer selected = (Writer) writerList.getModel().getElementAt(selectionIndex); writerList.setSelectedValue(selected, false); - view.getWriterListPopup(lastPopup).show(writerList, e.getX(), e.getY()); + view.getWriterListPopup(lastPopup).show(writerList, e.getX(), e.getY()); } } else if(source.equals(view.getCoherentSetTable())){ JTable coherentSetTable = (JTable)source; diff --git a/src/tools/cm/common/code/org/opensplice/common/controller/ConnectionNotifier.java b/src/tools/cm/common/code/org/opensplice/common/controller/ConnectionNotifier.java index 508baa26f..3175e11a7 100644 --- a/src/tools/cm/common/code/org/opensplice/common/controller/ConnectionNotifier.java +++ b/src/tools/cm/common/code/org/opensplice/common/controller/ConnectionNotifier.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cm/common/code/org/opensplice/common/controller/EntityInfoListener.java b/src/tools/cm/common/code/org/opensplice/common/controller/EntityInfoListener.java index 9c3791072..d35abfc04 100644 --- a/src/tools/cm/common/code/org/opensplice/common/controller/EntityInfoListener.java +++ b/src/tools/cm/common/code/org/opensplice/common/controller/EntityInfoListener.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cm/common/code/org/opensplice/common/controller/EntityTreeCellRenderer.java b/src/tools/cm/common/code/org/opensplice/common/controller/EntityTreeCellRenderer.java index bb590db0b..4b39ac868 100644 --- a/src/tools/cm/common/code/org/opensplice/common/controller/EntityTreeCellRenderer.java +++ b/src/tools/cm/common/code/org/opensplice/common/controller/EntityTreeCellRenderer.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -42,6 +43,7 @@ public class EntityTreeCellRenderer extends DefaultTreeCellRenderer { private final Color hideRelationsColor = Config.getInactiveColor(); private final Color showRelationsColor = Config.getActiveColor(); + private final Color entityDisabledColor = Config.getWarningColor(); /** * Constructs a new EntityTreeCellRenderer. * @@ -90,9 +92,9 @@ public Component getTreeCellRendererComponent( label = ((JLabel)result); label.setText(str); label.setToolTipText(str); - + if(!(e.isEnabled())){ - label.setFont(label.getFont().deriveFont(Font.ITALIC)); + label.setForeground(entityDisabledColor); } } if (tree instanceof EntityTree) { diff --git a/src/tools/cm/common/code/org/opensplice/common/controller/EntityTreeExpansionListener.java b/src/tools/cm/common/code/org/opensplice/common/controller/EntityTreeExpansionListener.java index 4687da999..6405e5e83 100644 --- a/src/tools/cm/common/code/org/opensplice/common/controller/EntityTreeExpansionListener.java +++ b/src/tools/cm/common/code/org/opensplice/common/controller/EntityTreeExpansionListener.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cm/common/code/org/opensplice/common/controller/EntityTreeWillExpandListener.java b/src/tools/cm/common/code/org/opensplice/common/controller/EntityTreeWillExpandListener.java index d5717b6b8..4a957f9c2 100644 --- a/src/tools/cm/common/code/org/opensplice/common/controller/EntityTreeWillExpandListener.java +++ b/src/tools/cm/common/code/org/opensplice/common/controller/EntityTreeWillExpandListener.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -31,29 +32,29 @@ import org.opensplice.common.view.entity.tree.EntityTreeNode; /** - * Provides a listener that listens for collapse and expansion events in + * Provides a listener that listens for collapse and expansion events in * a EntityTree object. Its responsibility is to refresh the expanded tree * nodes and its expanded descendants. - * + * * @date Sep 1, 2004 */ public class EntityTreeWillExpandListener implements TreeWillExpandListener { /** * Creates a new listener that listens for expansions and collapses in the * associated entity tree. - * + * * @param _tree The tree, which events are being handled by this listener. */ public EntityTreeWillExpandListener(EntityTree _tree){ tree = _tree; logger = Logger.getLogger("org.opensplice.common.model"); } - + /** * Sets the expanded state of the tree node that collapsed to false. - * This function is called before a tree node collapses in the attached + * This function is called before a tree node collapses in the attached * EntityTree. - * + * * @param event The event that has occurred. * @throws ExpandVetoException Thrown when the node may not be collapsed. */ @@ -61,27 +62,26 @@ public EntityTreeWillExpandListener(EntityTree _tree){ public void treeWillCollapse(TreeExpansionEvent event) throws ExpandVetoException { EntityTreeNode node = ((EntityTreeNode)(event.getPath().getLastPathComponent())); - logger.logp(Level.FINEST, "EntityTreeWillExpandListener", "treeWillCollapse", + logger.logp(Level.FINEST, "EntityTreeWillExpandListener", "treeWillCollapse", "Collapse event. " + node.getUserObject()); node.setExpanded(false); - //tree.refresh(node); } - - + + /** - * Sets the expanded state of the tree node that expanded to true and - * refreshes the node and its expanded children. This function is called + * Sets the expanded state of the tree node that expanded to true and + * refreshes the node and its expanded children. This function is called * before a tree node expands in the attached EntityTree. - * + * * @param event The event that has occurred. * @throws ExpandVetoException Thrown when the node may not be expanded. */ @Override public void treeWillExpand(TreeExpansionEvent event) throws ExpandVetoException { - + EntityTreeNode node = ((EntityTreeNode)(event.getPath().getLastPathComponent())); int childCount = node.getChildCount(); - logger.logp(Level.FINEST, "EntityTreeWillExpandListener", "treeWillExpand", + logger.logp(Level.FINEST, "EntityTreeWillExpandListener", "treeWillExpand", "Expansion event. " + node.getUserObject() + " childCount: " + childCount); node.setExpanded(true); try { @@ -91,13 +91,13 @@ public void treeWillExpand(TreeExpansionEvent event) throws ExpandVetoException + node.getUserObject() + " childCount: " + childCount); } } - + /** * The tree, which collapse/expansion events are being handled by this * listener */ private final EntityTree tree; - + /** * Logging facilities */ diff --git a/src/tools/cm/common/code/org/opensplice/common/controller/MainWindowOpener.java b/src/tools/cm/common/code/org/opensplice/common/controller/MainWindowOpener.java index fc0d80019..f64093727 100644 --- a/src/tools/cm/common/code/org/opensplice/common/controller/MainWindowOpener.java +++ b/src/tools/cm/common/code/org/opensplice/common/controller/MainWindowOpener.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cm/common/code/org/opensplice/common/controller/QoSTableCellRenderer.java b/src/tools/cm/common/code/org/opensplice/common/controller/QoSTableCellRenderer.java index 22e3d4c51..272b0e2af 100644 --- a/src/tools/cm/common/code/org/opensplice/common/controller/QoSTableCellRenderer.java +++ b/src/tools/cm/common/code/org/opensplice/common/controller/QoSTableCellRenderer.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cm/common/code/org/opensplice/common/controller/QoSTableEditor.java b/src/tools/cm/common/code/org/opensplice/common/controller/QoSTableEditor.java index 462921cd4..b0a81877a 100644 --- a/src/tools/cm/common/code/org/opensplice/common/controller/QoSTableEditor.java +++ b/src/tools/cm/common/code/org/opensplice/common/controller/QoSTableEditor.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -62,9 +63,9 @@ /** * Editor for a QoSTable component. It allows a user to edit the QoS within - * the QoSTable. - * - * @date Feb 2, 2005 + * the QoSTable. + * + * @date Feb 2, 2005 */ public class QoSTableEditor extends AbstractCellEditor implements TableCellEditor, ActionListener, KeyListener { private Object curValue = null; @@ -75,7 +76,7 @@ public class QoSTableEditor extends AbstractCellEditor implements TableCellEdito private StatusPanel status = null; private int editRow, editColumn; private Component curEditor = null; - + /** * Constructs a new QoSTableEditor. * @@ -86,21 +87,21 @@ public QoSTableEditor(QoSTable view){ this.view = view; this.model = (EntityQoSTableModel)view.getModel(); } - + /** - * Stores the supplied object that will receive validation and assigment + * Stores the supplied object that will receive validation and assignment * information from now. - * + * * @param _status The component that will receive the information. */ public void setStatusListener(StatusPanel _status){ status = _status; } - + @Override public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { Component result = null; - + editRow = row; editColumn = column; curValue = value; @@ -138,7 +139,7 @@ public Component getTableCellEditorComponent(JTable table, Object value, boolean curEditor = result; curEditor.setBackground(editColor); curEditor.addKeyListener(this); - + return result; } @@ -155,10 +156,10 @@ public void actionPerformed(ActionEvent e) { } /** - * Called when the user releases a key on the keyboard. When currently + * Called when the user releases a key on the keyboard. When currently * editing a field, the input is validated. When a status listener is * attached status information is provided to that listener. - * + * * @param e The key event that occurred. */ @Override @@ -166,16 +167,16 @@ public void keyReleased(KeyEvent e) { if(curEditor != null){ if(e.getSource() instanceof JTextField){ AssignmentResult test = this.testAssignment(); - + if(test.isValid()){ curEditor.setBackground(editColor); - + if(status != null){ status.setStatus("Current input valid.", false, false); } } else { curEditor.setBackground(errorColor); - + if(status != null){ status.setStatus(test.getErrorMessage(), false, false); } @@ -183,17 +184,17 @@ public void keyReleased(KeyEvent e) { } else if(e.getSource() instanceof JComboBox){ /*Do nothing.*/ } - } + } } - + /** * Validates whether the current value in the editor is valid. - * + * * @return Whether or not the value in the editor can be assigned. */ public AssignmentResult testAssignment(){ AssignmentResult result = new AssignmentResult(true, null); - + if(curEditor != null){ try{ if(curValue instanceof Integer){ @@ -219,7 +220,7 @@ public AssignmentResult testAssignment(){ } return result; } - + /** * Called when editing has been cancelled. */ @@ -227,19 +228,19 @@ public AssignmentResult testAssignment(){ public void cancelCellEditing(){ super.cancelCellEditing(); curEditor = null; - + if(status != null){ status.setStatus("Editing cancelled", false, false); } } - + /** * Called when editing has been stopped. */ @Override public boolean stopCellEditing(){ boolean result = true; - + if(curEditor != null){ result = this.assign().isValid(); } @@ -249,13 +250,13 @@ public boolean stopCellEditing(){ } return result; } - + /** * Does nothing. */ @Override public void keyTyped(KeyEvent e) {} - + /** * Does nothing. */ @@ -265,12 +266,12 @@ public void keyPressed(KeyEvent e) {} public boolean isEditing(){ return (curEditor != null); } - + private AssignmentResult assign(){ String name, field; Object value = null; AssignmentResult test = this.testAssignment(); - + if(test.isValid()){ if(status != null){ status.setStatus("Input valid.", false, false); @@ -283,9 +284,7 @@ private AssignmentResult assign(){ QoS qos = model.getQoS(); name = (String)model.getValueAt(editRow, editColumn-2); field = (String)model.getValueAt(editRow, editColumn-1); - - //model.setUserDataField( (String)model.getValueAt(editRow, editColumn-1), (String)curValue); - + if(qos instanceof ParticipantQoS){ curValue = this.assignParticipant(name, field, value); } else if(qos instanceof PublisherQoS){ @@ -308,11 +307,11 @@ private AssignmentResult assign(){ } return test; } - + private Component getTimeEditor(Object value){ return this.getTextFieldEditor(value); } - + private Component getCheckboxEditor(Object value) { JCheckBox result = new JCheckBox(); result.setSelected((Boolean) value); @@ -321,87 +320,87 @@ private Component getCheckboxEditor(Object value) { private Component getBooleanEditor(Object value){ Object bool[] = {Boolean.TRUE, Boolean.FALSE}; - + return this.getEnumEditor(value, bool); } - + private Component getTextFieldEditor(Object value){ JTextField result = null; result = new JTextField(); result.setText(value.toString()); - + return result; } - + private Component getEnumEditor(Object defaultValue, Object[] values){ JComboBox result = new JComboBox(values); result.setSelectedItem(defaultValue); - + return result; } - + private Component getDurabilityKindEditor(Object value){ - Object[] values = { DurabilityKind.VOLATILE, + Object[] values = { DurabilityKind.VOLATILE, DurabilityKind.TRANSIENT_LOCAL, - DurabilityKind.TRANSIENT, + DurabilityKind.TRANSIENT, DurabilityKind.PERSISTENT}; return this.getEnumEditor(value, values); } - + private Component getPresentationKindEditor(Object value){ - Object[] values = { PresentationKind.INSTANCE, + Object[] values = { PresentationKind.INSTANCE, PresentationKind.TOPIC, PresentationKind.GROUP}; return this.getEnumEditor(value, values); } - + private Component getLivelinessKindEditor(Object value){ - Object[] values = { LivelinessKind.AUTOMATIC, + Object[] values = { LivelinessKind.AUTOMATIC, LivelinessKind.PARTICIPANT, LivelinessKind.TOPIC}; return this.getEnumEditor(value, values); } - + private Component getReliabilityKindEditor(Object value){ Object[] values = { ReliabilityKind.BESTEFFORT, ReliabilityKind.RELIABLE}; return this.getEnumEditor(value, values); } - + private Component getOwnershipKindEditor(Object value){ Object[] values = { OwnershipKind.SHARED, OwnershipKind.EXCLUSIVE}; return this.getEnumEditor(value, values); } - + private Component getHistoryQosKindEditor(Object value){ Object[] values = { HistoryQosKind.KEEPLAST, HistoryQosKind.KEEPALL}; return this.getEnumEditor(value, values); } - + private Component getOrderbyKindEditor(Object value){ Object[] values = { OrderbyKind.BY_RECEPTION_TIMESTAMP, OrderbyKind.BY_SOURCE_TIMESTAMP}; return this.getEnumEditor(value, values); } - + private Component getScheduleKindEditor(Object value){ Object[] values = {ScheduleKind.DEFAULT, ScheduleKind.TIMESHARING, ScheduleKind.REALTIME }; return this.getEnumEditor(value, values); } - + private Component getSchedulePriorityKindEditor(Object value){ Object[] values = {SchedulePriorityKind.RELATIVE, SchedulePriorityKind.ABSOLUTE }; return this.getEnumEditor(value, values); } - + private byte[] getByteArray(String value) throws NumberFormatException { byte[] result = null; - + if (value == null || value.length() < 3) { throw new NumberFormatException("Value not valid."); } else if("NULL".equalsIgnoreCase(value)){ @@ -417,11 +416,11 @@ private byte[] getByteArray(String value) throws NumberFormatException { String val = value.substring(1, value.length()-1); StringTokenizer tokenizer = new StringTokenizer(val, ",", true); ArrayList list = new ArrayList(); - - + + while(tokenizer.hasMoreTokens()){ token = tokenizer.nextToken(); - + if(prevComma){ Byte.parseByte(token); list.add(token); @@ -433,19 +432,19 @@ private byte[] getByteArray(String value) throws NumberFormatException { prevComma = true; } } - + if(prevComma){ throw new NumberFormatException("Comma's not valid"); } result = new byte[list.size()]; - + for(int i=0; iget method. + /** + * Compute the value to be returned by the get method. */ public abstract Object construct(); @@ -81,14 +82,14 @@ public void interrupt() { } /** - * Return the value created by the construct method. + * Return the value created by the construct method. * Returns null if either the constructing thread or the current * thread was interrupted before a value was produced. - * + * * @return the value created by the construct method */ public Object get() { - while (true) { + while (true) { Thread t = threadVar.get(); if (t == null) { return getValue(); diff --git a/src/tools/cm/common/code/org/opensplice/common/controller/UserDataEditTableEditor.java b/src/tools/cm/common/code/org/opensplice/common/controller/UserDataEditTableEditor.java index 841c7972a..f0ccad5d0 100644 --- a/src/tools/cm/common/code/org/opensplice/common/controller/UserDataEditTableEditor.java +++ b/src/tools/cm/common/code/org/opensplice/common/controller/UserDataEditTableEditor.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -52,8 +53,8 @@ /** * Represents an editor that handles user editing in an UserDataEditTable. It * validates input and assigns valid values to the fields in the data. - * - * @date Nov 9, 2004 + * + * @date Nov 9, 2004 */ public class UserDataEditTableEditor extends AbstractCellEditor implements TableCellEditor, ActionListener, KeyListener { @@ -68,11 +69,11 @@ public class UserDataEditTableEditor extends AbstractCellEditor implements Table private Component curEditor = null; private final Color editColor = Config.getInputColor(); private final Color errorColor = Config.getIncorrectColor(); - + /** * Constructs a new editor for that is able to edit UserData of the supplied * type. - * + * * @param _type The type of the UserData that must be edited. * @param _view The table that displays the graphical representation of the * data. @@ -87,7 +88,9 @@ public UserDataEditTableEditor(MetaType _type, UserDataEditTable _view){ @Override public boolean isCellEditable(EventObject e) { JFrame frame = (JFrame) SwingUtilities.getRoot(status); - frame.firePropertyChange("enableSaveButton", 0, 1); + if (frame != null) { + frame.firePropertyChange("enableSaveButton", 0, 1); + } return true; } @@ -97,13 +100,13 @@ public boolean isCellEditable(EventObject e) { * - Primitive (except boolean): JTextField * - Boolean: JComboBox * - Enumeration: JComboBox - * + * * @param table The table in which the user wants to edit. * @param value The current value in the cell. * @param isSelected Whether or not the cell is currently selected. * @param row The row in the table the user wants to edit. * @param column The column in the table the user wants to edit. - * + * * @return The editor for the supplied cell. */ @Override @@ -152,30 +155,30 @@ public Component getTableCellEditorComponent(JTable table, Object value, boolean /** * Provides access to the current value of the cell that is being edited. - * + * * @return The current value of the field that is being edited. */ @Override public Object getCellEditorValue() { return curValue; } - + /** - * Stores the supplied object that will receive validation and assigment + * Stores the supplied object that will receive validation and assignment * information from now. - * + * * @param _status The component that will receive the information. */ public void setStatusListener(StatusPanel _status){ status = _status; } - + /** * Constructs an editor for a primitive field. - * + * * In case of a boolean a JComboBox with the possible values "TRUE" and "FALSE" * will be returned. In all other cases a JTextField will be returned. - * + * * @param row The row that is being edited. * @param column The column that is being edited. * @param value The current value of the field that is being edited. @@ -185,7 +188,7 @@ public void setStatusListener(StatusPanel _status){ private Component getPrimitiveEditor(int row, int column, Object value){ Component temp; String primType = (String)model.getValueAt(row, 0); - + if("c_bool".equals(primType)){ String[] items = {"FALSE", "TRUE"}; JComboBox combo = new JComboBox(items); @@ -201,12 +204,12 @@ private Component getPrimitiveEditor(int row, int column, Object value){ temp.setBackground(editColor); return temp; } - + /** * Constructs an editor for a enumeration field. - * + * * A JComboBox filled with all possible values will be returned. - * + * * @param row The row that is being edited. * @param column The column that is being edited. * @param value The current value of the field. @@ -221,12 +224,12 @@ private Component getEnumEditor(int row, int column, Object value, MetaEnum edit temp.addActionListener(this); return temp; } - + /** * Constructs an editor for a collection field. - * + * * This is done by looking up the editor for the subtype of the collection. - * + * * @param row The row that is being edited. * @param column The column that is being edited. * @param value The current value of the field. @@ -238,11 +241,11 @@ private Component getCollectionEditor(int row, int column, Object value, MetaCol String name; MetaField subType = editField.getSubType(); Component temp = null; - + while(subType instanceof MetaCollection){ subType = ((MetaCollection)subType).getSubType(); } - + if(subType instanceof MetaEnum){ temp = this.getEnumEditor(row, column, value, (MetaEnum)subType); } else if(subType instanceof MetaStruct){ @@ -250,7 +253,7 @@ private Component getCollectionEditor(int row, int column, Object value, MetaCol } else {//primitive if(subType instanceof MetaUnion){ name = (String)model.getValueAt(row, column-1); - + if(name.endsWith(".switch")){ curUnion = (MetaUnion)subType; } @@ -260,17 +263,17 @@ private Component getCollectionEditor(int row, int column, Object value, MetaCol temp.setBackground(editColor); return temp; } - + private Component getStructEditor(int row, int column, Object value, MetaStruct editField, String nameRest){ String name, nextName; MetaField structField; Component component; - + int index = nameRest.indexOf('['); - + if(index == -1){ index = nameRest.indexOf('.'); - + if(index == -1){ name = nameRest; } else { @@ -279,10 +282,10 @@ private Component getStructEditor(int row, int column, Object value, MetaStruct } else { name = nameRest.substring(0, index); } - - + + structField = editField.getField(name); - + if(structField instanceof MetaStruct){ nextName = nameRest.substring(index+1); component = this.getStructEditor(row, column, value, (MetaStruct)structField, nextName); @@ -295,13 +298,13 @@ private Component getStructEditor(int row, int column, Object value, MetaStruct } return component; } - + /** * Called when a user confirms its input. - * + * * This function validates the input of the user. If it succeeds the value * is assigned to the field, the user will be notified of its error. - * + * * @param e The event that occurred. */ @Override @@ -310,27 +313,27 @@ public void actionPerformed(ActionEvent e){ this.assign(); } } - - + + /** * Called when editing has been cancelled. */ @Override public void cancelCellEditing(){ super.cancelCellEditing(); - + if(status != null){ status.setStatus("Editing cancelled", false, false); } } - + /** * Called when editing has been stopped. */ @Override public boolean stopCellEditing(){ boolean result = true; - + if(curEditor != null){ result = this.assign().isValid(); } @@ -339,10 +342,10 @@ public boolean stopCellEditing(){ } return result; } - + private AssignmentResult assign(){ AssignmentResult test = this.testAssignment(true); - + if(test.isValid()){ if(curEditor instanceof JComboBox){ @@ -367,21 +370,21 @@ private AssignmentResult assign(){ } return test; } - + /** * Checks whether the current value in the editor is valid and will be * accepted as final input. - * + * * @return The AssigmentResult that tells whether the input is valid and - * if not; the reason why. + * if not; the reason why. */ public AssignmentResult testAssignment(boolean updateSource){ AssignmentResult result = new AssignmentResult(true, null); - + if(curEditor != null){ if(curEditor instanceof JTextField){ JTextField source = (JTextField)curEditor; - + String typeName = (String)(model.getValueAt(editRow, editColumn-2)); String typeNameTmp = typeName; @@ -395,27 +398,27 @@ public AssignmentResult testAssignment(boolean updateSource){ typeName = "INVALID"; String text = source.getText(); - + try{ if("c_voidp".equals(typeName)){ source.setText((String)curValue); if(status != null){ status.setStatus("Warning: Void pointers cannot be changed", false, false); } - } + } else if(typeName.startsWith("C_SEQUENCE") || typeName.startsWith("C_ARRAY<")){ String fieldName = (String)(model.getValueAt(editRow, editColumn-1)); MetaCollection mc = (MetaCollection)(type.getField(fieldName)); - + if(mc == null){ mc = (MetaCollection)(type.getField(this.getTypeNameForField(fieldName))); } - + if(mc != null){ if(mc.getMaxSize() == 0){ MetaField subType = mc.getSubType(); String subTypeName = subType.getTypeName(); - + if(text.equals("[]")){ /*Ok, do nothing*/ } else if(text.equals("NULL")){ @@ -427,7 +430,7 @@ else if(typeName.startsWith("C_SEQUENCE") || typeName.startsWith("C_ARRAY<")){ (subTypeName.startsWith("C_STRING<")) || (subTypeName.startsWith("C_WSTRING<"))))) { - + if(text.equals("[]")){ /* Ok, do nothing*/ } else if(text.length() <= 2){ @@ -444,10 +447,10 @@ else if(typeName.startsWith("C_SEQUENCE") || typeName.startsWith("C_ARRAY<")){ } else { throw new NumberFormatException("Invalid value"); } - + } else { source.setText((String)curValue); - + if(status != null){ status.setStatus("Warning: Unbounded sequences of this type not supported. They " + "will be interpreted as an empty sequence.", false, false); @@ -465,29 +468,29 @@ else if(typeName.startsWith("C_SEQUENCE") || typeName.startsWith("C_ARRAY<")){ status.setStatus("Error: Could not resolve type of field '" + fieldName + "'.", false, false); } } - + } else if(typeName.startsWith("C_ARRAY<")){ String fieldName = (String)(model.getValueAt(editRow, editColumn-1)); MetaCollection mc = (MetaCollection)(type.getField(fieldName)); - + if(mc.getMaxSize() == 0){ MetaField subType = mc.getSubType(); - + if(subType instanceof MetaPrimitive){ - + } else if(subType instanceof MetaCollection) { String subTypeName = subType.getTypeName(); - + if( (subTypeName.equals("c_string")) || (subTypeName.equals("c_wstring"))) - + { - + } else if( (subTypeName.startsWith("C_STRING<")) || (subTypeName.startsWith("C_WSTRING<"))) { - + } else { if(status != null){ status.setStatus("Warning: Unbounded arrays not supported. They " + @@ -496,11 +499,11 @@ else if(typeName.startsWith("C_ARRAY<")){ source.setText((String)curValue); } } - + } else { if(status != null){ status.setStatus("Warning: Recursive types not supported. The " + - "first occurrence will be interpreted as a NULL pointer.", + "first occurrence will be interpreted as a NULL pointer.", false, false); } source.setText((String)curValue); @@ -512,7 +515,7 @@ else if(typeName.startsWith("C_ARRAY<")){ } } else { String value = this.handlePrimitive(text, typeName); - + if(updateSource){ source.setText(value); } @@ -539,17 +542,17 @@ else if(curEditor instanceof JComboBox){ } return result; } - + private String getTypeNameForField(String fieldName) { String result = null; String token; int index; StringTokenizer tokenizer = new StringTokenizer(fieldName, "."); - + while(tokenizer.hasMoreTokens()){ token = tokenizer.nextToken(); index = token.indexOf('['); - + if(index == -1){ if(result == null){ result = token; @@ -569,7 +572,7 @@ private String getTypeNameForField(String fieldName) { private String handlePrimitive(String text, String typeName) throws NumberFormatException{ String result; - + if("c_char".equals(typeName)){//TODO: Java char is superset of IDL char if(text.length() != 1 && !text.matches("\\\\[0-3][0-7][0-7]")){ throw new NumberFormatException("Char must be of length 1, or an octal char code \\###."); @@ -577,8 +580,12 @@ private String handlePrimitive(String text, String typeName) throws NumberFormat result = text; } else if("c_octet".equals(typeName)){ - byte test = Byte.parseByte(text); - result = Byte.toString(test); + int test = Integer.parseInt(text); + if (test >= 0 && test <= 255) { + result = Integer.toString(test); + } else { + throw new NumberFormatException("Octet must have a value between 0 and 255."); + } } else if("c_short".equals(typeName)){ short test = Short.parseShort(text); @@ -600,7 +607,7 @@ else if("c_ulong".equals(typeName)){ throw new NumberFormatException("Unsigned long cannot be negative."); } long test = Long.parseLong(text); - + if(test > 4294967295L){ throw new NumberFormatException("Unsigned long max == 4294967295."); } @@ -628,17 +635,17 @@ else if("c_ulonglong".equals(typeName)){//TODO: unsigned long long not available else if("c_float".equals(typeName)){ float test = Float.parseFloat(text); result = Float.toString(test); - } + } else if("c_double".equals(typeName)){ double test = Double.parseDouble(text); result = Double.toString(test); - } + } else if( (typeName.startsWith("C_STRING<")) || (typeName.startsWith("C_WSTRING<"))) { String temp = typeName.substring(typeName.indexOf('<') + 1, typeName.indexOf('>')); int size = Integer.parseInt(temp); - + if(text.length() > size){ throw new NumberFormatException("length " + text.length() + " > " + size); } @@ -646,7 +653,7 @@ else if( (typeName.startsWith("C_STRING<")) || throw new NumberFormatException("String cannot contain ']]>'"); } result = text; - } + } else if("c_string".equals(typeName)){ if(text.indexOf("]]>") != -1){ throw new NumberFormatException("String cannot contain ']]>'"); @@ -655,18 +662,18 @@ else if("c_string".equals(typeName)){ } else { result = text; } - + if(curUnion != null){ if(!curUnion.labelExists(text)){ throw new NumberFormatException("Invalid union switch value"); } } - + return result; } /** - * Called when the user releases a key on the keyboard. When currently + * Called when the user releases a key on the keyboard. When currently * editing a field, the input is validated. When a status listener is * attached status information is provided to that listener. */ @@ -675,12 +682,12 @@ public void keyReleased(KeyEvent e) { if(curEditor != null){ if(e.getSource() instanceof JTextField){ AssignmentResult test = this.testAssignment(false); - + if(test.isValid()){ curEditor.setBackground(editColor); } else { curEditor.setBackground(errorColor); - + if(status != null){ status.setStatus(test.getErrorMessage(), false, false); } @@ -690,7 +697,7 @@ public void keyReleased(KeyEvent e) { if (!curUnion.labelExists((String) ((JComboBox) e .getSource()).getSelectedItem())) { curEditor.setBackground(errorColor); - + if(status != null){ status.setStatus("Error: Invalid union switch value", false, false); } @@ -701,7 +708,7 @@ public void keyReleased(KeyEvent e) { stopCellEditing(); } } - } + } } /** @@ -709,7 +716,7 @@ public void keyReleased(KeyEvent e) { */ @Override public void keyTyped(KeyEvent e) {} - + /** * Does nothing. */ diff --git a/src/tools/cm/common/code/org/opensplice/common/controller/UserDataSingleTableCellRenderer.java b/src/tools/cm/common/code/org/opensplice/common/controller/UserDataSingleTableCellRenderer.java index ba915da50..a25a663e2 100644 --- a/src/tools/cm/common/code/org/opensplice/common/controller/UserDataSingleTableCellRenderer.java +++ b/src/tools/cm/common/code/org/opensplice/common/controller/UserDataSingleTableCellRenderer.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cm/common/code/org/opensplice/common/model/CoherentPublishModel.java b/src/tools/cm/common/code/org/opensplice/common/model/CoherentPublishModel.java index 0618c2cfa..005d46e50 100644 --- a/src/tools/cm/common/code/org/opensplice/common/model/CoherentPublishModel.java +++ b/src/tools/cm/common/code/org/opensplice/common/model/CoherentPublishModel.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cm/common/code/org/opensplice/common/model/CoherentSubscribeModel.java b/src/tools/cm/common/code/org/opensplice/common/model/CoherentSubscribeModel.java index 80e5ddfa8..6483de2df 100644 --- a/src/tools/cm/common/code/org/opensplice/common/model/CoherentSubscribeModel.java +++ b/src/tools/cm/common/code/org/opensplice/common/model/CoherentSubscribeModel.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cm/common/code/org/opensplice/common/model/ModelListener.java b/src/tools/cm/common/code/org/opensplice/common/model/ModelListener.java index 2ff5a71d9..031654bb6 100644 --- a/src/tools/cm/common/code/org/opensplice/common/model/ModelListener.java +++ b/src/tools/cm/common/code/org/opensplice/common/model/ModelListener.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cm/common/code/org/opensplice/common/model/ModelRegister.java b/src/tools/cm/common/code/org/opensplice/common/model/ModelRegister.java index 0bbf4de7e..02e998b4e 100644 --- a/src/tools/cm/common/code/org/opensplice/common/model/ModelRegister.java +++ b/src/tools/cm/common/code/org/opensplice/common/model/ModelRegister.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -28,9 +29,9 @@ * Provides facilities for (de)registering and notifying ModelListener * components. Descendants of this class typically are model components that * need to notify registered components, because the data model changed. This - * class has been defiend abstract, because only descendants of this class may + * class has been defined abstract, because only descendants of this class may * exist. - * + * * @date Sep 21, 2004 */ public abstract class ModelRegister { @@ -50,10 +51,10 @@ public ModelRegister() { /** * Registers the supplied entity in its administration. - * + * * The listener will now receive a notification an every event. If it is * already in its administration, nothing happens. - * + * * @param listener * The listener to add to the administration. */ @@ -65,11 +66,11 @@ public void addListener(ModelListener listener) { /** * Removes the supplied listener from its administration. - * + * * The listener will no longer receive any notifications from this * component. When the listener is not in its administration, nothing will * happen. - * + * * @param listener * The listener to remove from the registration. */ @@ -81,7 +82,7 @@ public void removeListener(ModelListener listener) { /** * Notifies all registered listeners. - * + * * @param description * The message to send to the listeners. */ @@ -103,7 +104,7 @@ protected void notifyListeners(String description) { * Allows external components to send a notification to registered * listeners. This function is typically being used by other model * components then the descendant of ModelRegister itself. - * + * * @param description * The message to send to the listeners. */ diff --git a/src/tools/cm/common/code/org/opensplice/common/model/TypeHandler.java b/src/tools/cm/common/code/org/opensplice/common/model/TypeHandler.java index 6c71d66e1..f3f6f6629 100644 --- a/src/tools/cm/common/code/org/opensplice/common/model/TypeHandler.java +++ b/src/tools/cm/common/code/org/opensplice/common/model/TypeHandler.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cm/common/code/org/opensplice/common/model/UserDataFilter.java b/src/tools/cm/common/code/org/opensplice/common/model/UserDataFilter.java index 89dede349..8ff177078 100644 --- a/src/tools/cm/common/code/org/opensplice/common/model/UserDataFilter.java +++ b/src/tools/cm/common/code/org/opensplice/common/model/UserDataFilter.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cm/common/code/org/opensplice/common/model/sample/DetailSampleModel.java b/src/tools/cm/common/code/org/opensplice/common/model/sample/DetailSampleModel.java index 8cecaff53..19e3d44b6 100644 --- a/src/tools/cm/common/code/org/opensplice/common/model/sample/DetailSampleModel.java +++ b/src/tools/cm/common/code/org/opensplice/common/model/sample/DetailSampleModel.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -52,16 +53,16 @@ * - ArrayList: All added Sample objects are added to this list * so all added Sample objects can be found later * on. - * + * * Its purpose is to: - * - Supply a simplification for the administration of a whole bunch of Sample + * - Supply a simplification for the administration of a whole bunch of Sample * objects. * - Supply a generic interface for reading/taking data from several types of * entities. * - Supply a mechanism to be able to browse through the administration of * samples. - * - * @date Oct 21, 2004 + * + * @date Oct 21, 2004 */ public abstract class DetailSampleModel extends ModelRegister{ public DetailSampleModel(String structName){ @@ -81,20 +82,20 @@ public String getStructDetail() { /** * Reads a Sample from its reader. - * + * * @throws SampleModelSizeException Thrown when no more data can be added * to this model. - * @throws CommonException Thrown when no data could be retreived from the - * + * @throws CommonException Thrown when no data could be retrieved from the + * */ public abstract Sample read() throws CommonException, SampleModelSizeException; /** * Takes a Sample from its entity. - * + * * @throws SampleModelSizeException Thrown when no more data can be added * to this model. - * @throws CommonException Thrown when no data could be retreived from the + * @throws CommonException Thrown when no data could be retrieved from the * reader. */ public abstract Sample take() throws CommonException, SampleModelSizeException; @@ -104,38 +105,38 @@ public String getStructDetail() { /** * Exports the complete content of the model to the specified file in XML * format. - * + * * @param file The file to export the data to. * @return The number of samples that have been exported. - * @throws CommonException Thrown when the file cannot be created or is not + * @throws CommonException Thrown when the file cannot be created or is not * accessible */ public abstract int export(File file) throws CommonException; - + /** * Checks whether the maximum amount of data in the model has been reached. - * - * @throws SampleModelSizeException Thrown when the maximum has been + * + * @throws SampleModelSizeException Thrown when the maximum has been * reached. */ public void checkSize() throws SampleModelSizeException{ int max = 2000; - + if(userDataModel.getRowCount() >= max){ throw new SampleModelSizeException("Maximum #samples in model reached(" + max + ")."); } } /** - * Clears the data in the model. + * Clears the data in the model. */ public void clear(){ userDataModel.clear(); singleUserDataModel.clear(); sampleInfoModel.clear(); - + } - + public void clean() { userDataModel.clean(); singleUserDataModel.clean(); @@ -143,7 +144,7 @@ public void clean() { /** * Clears a part of the data in the model. - * + * * @param beginRow The begin row of the data to remove. * @param endRow The end row of the data to remove. */ @@ -153,7 +154,7 @@ public void clear(int beginRow, int endRow){ userDataModel.clear(beginRow, endRow); } singleUserDataModel.clear(); - sampleInfoModel.clear(); + sampleInfoModel.clear(); } } @@ -162,22 +163,22 @@ public void clear(int beginRow, int endRow){ * with the Sample/Message info of the Sample at the supplied index and * the singleUserDataModel is filled with the UserData within the Sample * at the supplied index. - * + * * @param index The index of the Sample in the list of samples. * @return When the supplied index is not available, false is returned, - * true otherwise. + * true otherwise. */ public boolean setSelectedSample(int index){ Sample s = null; try{ s = userDataModel.getDataAt(index); } catch(IndexOutOfBoundsException e){} - + if(s == null){ return false; } sampleInfoModel.setData(s); - + if(s.getMessage() != null){ singleUserDataModel.setData(s); } @@ -189,21 +190,21 @@ public boolean setSelectedSample(int index){ * with the Sample/Message info of the Sample at the supplied index and * the singleUserDataModel is filled with the UserData within the Sample * at the supplied index. - * + * * @param index The index of the Sample in the list of samples. * @return When the supplied index is not available, false is returned, - * true otherwise. + * true otherwise. */ public boolean setSelectedSample(int index, String struct){ Sample s = null; try{ s = userDataModel.getDataAt(index); } catch(IndexOutOfBoundsException e){} - + if(s == null){ return false; } - + if(s.getMessage() != null){ UserData data = s.getMessage().getUserData(); singleUserDataModel.clear(); @@ -219,7 +220,7 @@ public boolean setSelectedSample(int index, String struct){ /** * Provides access to the Sample at the supplied index in the list * of samples. - * + * * @param index The index of the Sample in the administration. * @return The Sample at the supplied index. */ @@ -233,7 +234,7 @@ public Sample getSampleAt(int index){ /** * Provides access to singleUserDataModel. - * + * * @return Returns the singleUserDataModel. */ public UserDataSingleTableModel getSingleUserDataModel() { @@ -241,7 +242,7 @@ public UserDataSingleTableModel getSingleUserDataModel() { } /** * Provides access to userDataModel. - * + * * @return Returns the userDataModel. */ public UserDataTableModel getUserDataModel() { @@ -250,13 +251,13 @@ public UserDataTableModel getUserDataModel() { /** * Provides access to sampleInfoTableModel. - * + * * @return Returns the sampleInfoTableModel. */ public SampleInfoTableModel getSampleInfoModel() { return sampleInfoModel; } - + protected String getKeyList(Topic t) throws CommonException{ String keys = null; String[] keyList; @@ -279,14 +280,14 @@ protected String getKeyList(Topic t) throws CommonException{ /** * Adds a Sample to the model. - * + * * @param s The Sample to add. * @return true if it was added and is visible (not filtered out by a * UserDataFilter), false otherwise. */ protected boolean addSample(Sample s){ boolean added = userDataModel.setData(s); - + if(added){ singleUserDataModel.setData(s); sampleInfoModel.setData(s); @@ -297,14 +298,14 @@ protected boolean addSample(Sample s){ /** * Adds a Sample to the model. - * + * * @param s The Sample to add. * @return true if it was added and is visible (not filtered out by a * UserDataFilter), false otherwise. */ public boolean addSample(Sample s, String struct) { boolean added = userDataModel.setData(s, struct); - + if(added){ singleUserDataModel.setData(s,struct); sampleInfoModel.setData(s); @@ -315,7 +316,7 @@ public boolean addSample(Sample s, String struct) { /** * Adds a Sample to the model. - * + * * @param s The Sample to add. * @return true if it was added and is visible (not filtered out by a * UserDataFilter), false otherwise. @@ -323,7 +324,7 @@ public boolean addSample(Sample s, String struct) { protected boolean addSample(UserData d, String struct){ setCurrentUserData(d); boolean added = userDataModel.setData(lastReadSample, struct); - + if(added){ singleUserDataModel.setData(lastReadSample,struct); sampleInfoModel.setData(lastReadSample); @@ -334,10 +335,10 @@ protected boolean addSample(UserData d, String struct){ protected String getPartitions(Reader reader){ String partitions = null; Entity entity; - + try { Entity[] entities = reader.getDependantEntities(EntityFilter.SUBSCRIBER); - + if(entities.length > 0){ /*Free all but the first one.*/ for(int i=1; i= max){ throw new SampleModelSizeException("Maximum #samples in model reached(" + max + ")."); } } - + /** - * Clears the data in the model. + * Clears the data in the model. */ public void clear(){ userDataModel.clear(); singleUserDataModel.clear(); sampleInfoModel.clear(); - + } - + /** * Clears a part of the data in the model. - * + * * @param beginRow The begin row of the data to remove. * @param endRow The end row of the data to remove. */ @@ -137,41 +138,41 @@ public void clear(int beginRow, int endRow){ userDataModel.clear(beginRow, endRow); } singleUserDataModel.clear(); - sampleInfoModel.clear(); + sampleInfoModel.clear(); } } - + /** * Selects the Sample at the supplied index. The sampleInfoModel is filled * with the Sample/Message info of the Sample at the supplied index and * the singleUserDataModel is filled with the UserData within the Sample * at the supplied index. - * + * * @param index The index of the Sample in the list of samples. * @return When the supplied index is not available, false is returned, - * true otherwise. + * true otherwise. */ public boolean setSelectedSample(int index){ Sample s = null; try{ s = userDataModel.getDataAt(index); } catch(IndexOutOfBoundsException e){} - + if(s == null){ return false; } sampleInfoModel.setData(s); - + if(s.getMessage() != null){ singleUserDataModel.setData(s); } return true; } - + /** * Provides access to the Sample at the supplied index in the list * of samples. - * + * * @param index The index of the Sample in the administration. * @return The Sample at the supplied index. */ @@ -182,7 +183,7 @@ public Sample getSampleAt(int index){ } catch(IndexOutOfBoundsException e){} return s; } - + /* check if the given name is an collection */ public boolean isCollection(String name, int index) { boolean result = false; @@ -192,7 +193,7 @@ public boolean isCollection(String name, int index) { } return result; } - + /* check if the given name is an unboundedSequence */ public boolean isUnboundedSequence(String name, int index) { boolean result = false; @@ -202,18 +203,18 @@ public boolean isUnboundedSequence(String name, int index) { } return result; } - + public void initiateToBeWrittenUserData(UserData data) { toBeWrittenUserData = data; } - + public UserData getToBeWrittenUserData() { return toBeWrittenUserData; } - + /** * Provides access to singleUserDataModel. - * + * * @return Returns the singleUserDataModel. */ public UserDataSingleTableModel getSingleUserDataModel() { @@ -221,22 +222,22 @@ public UserDataSingleTableModel getSingleUserDataModel() { } /** * Provides access to userDataModel. - * + * * @return Returns the userDataModel. */ public UserDataTableModel getUserDataModel() { return userDataModel; } - + /** * Provides access to sampleInfoTableModel. - * + * * @return Returns the sampleInfoTableModel. */ public SampleInfoTableModel getSampleInfoModel() { return sampleInfoModel; } - + /** * Gets the list of keys for the data type that this SampleModel is holding. * @return A String containing comma separated key values. @@ -264,7 +265,7 @@ public String getKeyList() throws CommonException{ /** * Get the ProtobufFieldProperties for every field name in the data type. * - * @return A Map of field names to their corresponding ProtobufFieldProperties. + * @return A Map of field names to their corresponding ProtobufFieldProperties. * If the Protobuf feature is disabled in this build of Tuner, then returns an empty Map. * @throws CommonException If there is a problem while retrieving the ProtobufFieldProperties * from the protobuf metadata. @@ -273,7 +274,7 @@ public Map getProtobufFieldProperties() throws if (ProtobufDataAdapterFactory.getInstance().isEnabled() && typeInfo.getDataRepresentationId() == TypeInfo.GPB_DATA_ID) { try { - Map result = new HashMap(); + Map result = new HashMap(); for (String fieldName : typeEvolution.getMetaType().getFieldNames()) { result.put(fieldName, ProtobufDataAdapterFactory.getInstance() .getFieldProperties(fieldName, typeEvolution)); @@ -296,14 +297,14 @@ public TypeEvolution getTypeEvolution() { /** * Adds a Sample to the model. - * + * * @param s The Sample to add. * @return true if it was added and is visible (not filtered out by a * UserDataFilter), false otherwise. */ protected boolean addSample(Sample s){ boolean added = userDataModel.setData(s); - + if(added){ singleUserDataModel.setData(s); sampleInfoModel.setData(s); @@ -311,17 +312,17 @@ protected boolean addSample(Sample s){ } return added; } - + /** * Adds a Sample to the model. - * + * * @param s The Sample to add. * @return true if it was added and is visible (not filtered out by a * UserDataFilter), false otherwise. */ protected boolean addSample(Sample s, String struct){ boolean added = userDataModel.setData(s,struct); - + if(added){ singleUserDataModel.setData(s,struct); sampleInfoModel.setData(s); @@ -329,14 +330,14 @@ protected boolean addSample(Sample s, String struct){ } return added; } - + protected String getPartitions(Reader reader){ String partitions = null; Entity entity; - + try { Entity[] entities = reader.getDependantEntities(EntityFilter.SUBSCRIBER); - + if(entities.length > 0){ /*Free all but the first one.*/ for(int i=1; i row){ String row0 = (String)getValueAt(row, 0); String row1 = (String)getValueAt(row, 1); String value; - + if(("".equals(row0)) && ("".equals(row1))){ value = ""; } else if("".equals(row0)){ @@ -106,19 +107,19 @@ public boolean reset(int row, boolean update){ } else if("".equals(row1)){ value = (String)getValueAt(row, 0); } else { - value = (String)this.getValueAt(row, 0) + "." + + value = (String)this.getValueAt(row, 0) + "." + (String)this.getValueAt(row, 1); } - + try { - + if((value.endsWith("Update")) || (value.endsWith("Reset"))){ entity.resetStatistics(value + ".seconds"); entity.resetStatistics(value + ".nanoseconds"); } else { entity.resetStatistics(value); } - + if(update){ result = this.update(); } @@ -131,21 +132,21 @@ public boolean reset(int row, boolean update){ } return result; } - + /** * Resets the complete Statistics of the Entity of this model. - * + * * @param update Whether to update the Statistics in the model after resetting. * @return true if reset succeeded, false otherwise. */ public boolean reset(boolean update){ boolean result = true; - + if(entityHasStatistics){ if(this.getRowCount() > 0){ try { entity.resetStatistics(null); - + if(update){ result = this.update(); } @@ -158,17 +159,17 @@ public boolean reset(boolean update){ } return result; } - + /** * Updates the Statistics in the model by resolving the Statistics of the * Entity again. - * + * * @return true if update succeeded, false otherwise. */ public boolean update(){ boolean result; AbstractValue counter; - + if(entityHasStatistics){ try { statistics = entity.getStatistics(); @@ -208,28 +209,6 @@ public boolean update(){ } else { result = false; } - - /* - for(int i=0; i s = new LinkedHashSet(data.getUserData().keySet()); - for (int i = 0; i < rowCount; i++) { - String fieldName = (String) this.getValueAt(i, 1); - if (ud.getUserDataType().getField(fieldName).getTypeName().startsWith("C_SEQUENCE")) { - this.setValueAt(ud.getFieldValue(fieldName), i, 2); - result = true; - } else { - StringBuilder fieldValue = new StringBuilder(); - LinkedHashSet tmpS = new LinkedHashSet(s); - for (String key : tmpS) { - String value = (data.getUserData().get(key)); - String newKey = key.replaceAll("[\\[0-9]*]", ""); - /* - * if the key is equal to the fieldName we got the same data - * so ignore for GUI - */ - if (newKey.startsWith(fieldName)) { + if(data != null){ + ud.getUserData().putAll(data.getUserData()); + int rowCount = this.getRowCount(); + LinkedHashSet s = new LinkedHashSet(data.getUserData().keySet()); + for (int i = 0; i < rowCount; i++) { + String fieldName = (String) this.getValueAt(i, 1); + try { + if (ud.getUserDataType() != null && fieldName != null && ud.getUserDataType().getField(fieldName).getTypeName().startsWith("C_SEQUENCE")) { + this.setValueAt(ud.getFieldValue(fieldName), i, 2); + result = true; + } else { + StringBuilder fieldValue = new StringBuilder(); + LinkedHashSet tmpS = new LinkedHashSet(s); + for (String key : tmpS) { + String value = (data.getUserData().get(key)); + String newKey = key.replaceAll("[\\[0-9]*]", ""); + /* + * if the key is equal to the fieldName we got the same data + * so ignore for GUI + */ + if (newKey.startsWith(fieldName)) { + if (fieldValue.length() != 0) { + fieldValue.append(","); + } + fieldValue.append(value); + s.remove(key); + } + } if (fieldValue.length() != 0) { - fieldValue.append(","); + this.setValueAt(fieldValue.toString(), i, 2); } - fieldValue.append(value); - s.remove(key); } - } - if (fieldValue.length() != 0) { - this.setValueAt(fieldValue.toString(), i, 2); + } catch (NullPointerException npe) { + // ignore see OSPL-10362 } } + result = true; } - result = true; - } return result; } @@ -231,7 +236,7 @@ public boolean setData(Sample sample, String colName, int index) { /** * Sets the supplied editor as the editor for data in this model. - * + * * @param _editor * The new editor. */ diff --git a/src/tools/cm/common/code/org/opensplice/common/model/table/UserDataSingleTableModel.java b/src/tools/cm/common/code/org/opensplice/common/model/table/UserDataSingleTableModel.java index 62c166164..ec56a0157 100644 --- a/src/tools/cm/common/code/org/opensplice/common/model/table/UserDataSingleTableModel.java +++ b/src/tools/cm/common/code/org/opensplice/common/model/table/UserDataSingleTableModel.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cm/common/code/org/opensplice/common/model/table/UserDataTableModel.java b/src/tools/cm/common/code/org/opensplice/common/model/table/UserDataTableModel.java index 11da8a9ff..86fecb032 100644 --- a/src/tools/cm/common/code/org/opensplice/common/model/table/UserDataTableModel.java +++ b/src/tools/cm/common/code/org/opensplice/common/model/table/UserDataTableModel.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -48,7 +49,7 @@ */ public class UserDataTableModel extends DefaultTableModel { /** - * + * */ private static final long serialVersionUID = -6808068073551184983L; @@ -158,7 +159,7 @@ public UserDataTableModel(MetaType _userDataType, String struct) throws CommonEx for (int i = 0; i < names.length; i++) { invisibleFieldNames.add(names[i]); } - + this.makeAllFieldsVisible(struct); this.sampleInfoModel = new SampleInfoTableModel(); int rowCount = this.sampleInfoModel.getRowCount(); @@ -175,7 +176,7 @@ public UserDataTableModel(MetaType _userDataType, String struct) throws CommonEx * Provides access to the UserData at the specified index. * * @param index The index of the UserData. - * @return The UserData at the supplied ondex, or null if the index was not + * @return The UserData at the supplied index, or null if the index was not * available. */ public Sample getDataAt(int index){ @@ -208,7 +209,7 @@ public int getAllContentCount(){ return content.size(); } } - + public boolean setDataAt(Sample sample, int index){ boolean match = true; String fieldName; @@ -264,7 +265,7 @@ public boolean setDataAt(Sample sample, int index){ } return true; } - + public boolean addNewSample(Object[] o, Sample sample, int index) { boolean match = true; synchronized(content){ @@ -369,7 +370,7 @@ public boolean setData(Sample sample, String colName) { boolean result = true; boolean res = false; - + synchronized(content){ res = !content.contains(sample); } @@ -382,11 +383,15 @@ public boolean setData(Sample sample, String colName) { String columnName = null; int columnCount = this.getColumnCount(); int nrOfRows = 0; - MetaField f = data.getUserDataType().getField(colName); - if (f.getTypeName().startsWith("C_SEQUENCE<")) { - nrOfRows = data.getCollectionRealSize(colName); - } else { - nrOfRows = ((MetaCollection) f).getMaxSize(); + if (data.getUserDataType() != null && colName != null) { + MetaField f = data.getUserDataType().getField(colName); + if (f != null) { + if (f.getTypeName().startsWith("C_SEQUENCE<")) { + nrOfRows = data.getCollectionRealSize(colName); + } else { + nrOfRows = ((MetaCollection) f).getMaxSize(); + } + } } for (int k = 0; k < nrOfRows && result; k++) { @@ -680,7 +685,7 @@ public void addFilter(UserDataFilter filter){ /** * Removes the supplied filter from the data. Data that was filtered out - * of the visibleContent by this filter is readded to the visibleContent. + * of the visibleContent by this filter is re-added to the visibleContent. * * @param filter The filter to remove. */ @@ -784,7 +789,7 @@ public synchronized void clear(){ } } } - + public void clean() { this.getDataVector().removeAllElements(); } diff --git a/src/tools/cm/common/code/org/opensplice/common/model/table/UserDataTableSorter.java b/src/tools/cm/common/code/org/opensplice/common/model/table/UserDataTableSorter.java index 2f1a2c583..eacf0a9f7 100644 --- a/src/tools/cm/common/code/org/opensplice/common/model/table/UserDataTableSorter.java +++ b/src/tools/cm/common/code/org/opensplice/common/model/table/UserDataTableSorter.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,9 +23,9 @@ /** * Tables which contain an instance of UserDataTableSorter can access * the actual model because of this class. The table thinks it is accessing - * its model, but actually it is accessing the UserDataTableSorter that - * translates the call into the right call for its UserDataTableModel. - * + * its model, but actually it is accessing the UserDataTableSorter that + * translates the call into the right call for its UserDataTableModel. + * * It looks like this: @verbatim @@ -42,8 +43,8 @@ | UserDataTableModel | ----------------------- @endverbatim - * - * @date Nov 5, 2004 + * + * @date Nov 5, 2004 */ import java.util.Date; import java.util.Vector; @@ -62,25 +63,25 @@ public class UserDataTableSorter extends TableMap { /** * Contains the mapping between actual index of the rows in the model and - * the sorted index. + * the sorted index. */ protected int indexes[]; - + /** * The list of currently sorted columns. */ protected Vector sortingColumns = new Vector(); - + /** - * The way of the last sort. (ascending -> true, descending -> false) + * The way of the last sort. (ascending -> true, descending -> false) */ protected boolean ascending = true; - + /** * Total number of compares. */ protected int compares; - + /** * Last column that has been sorted. */ @@ -93,8 +94,8 @@ public UserDataTableSorter() { indexes = new int[0]; // for consistency } - /** - * Constructs a new sorter for the supplied model. + /** + * Constructs a new sorter for the supplied model. * * @param model The model to sort. */ @@ -104,14 +105,14 @@ public UserDataTableSorter(TableModel model) { /** * Sets the model to sort. - * + * * @param model The model to sort. */ @Override public void setModel(TableModel model) { - super.setModel(model); + super.setModel(model); reallocateIndexes(); - + if(model instanceof UserDataTableModel){ ((UserDataTableModel)model).setSorter(this); } @@ -124,33 +125,30 @@ public void tableChanged(TableModelEvent e) { super.tableChanged(e); } - /* + /* * The mapping only affects the contents of the data rows. * Pass all requests to these rows through the mapping array: "indexes". */ @Override public Object getValueAt(int aRow, int aColumn) { - checkModel(); return model.getValueAt(indexes[aRow], aColumn); } - + /** * Removes the supplied rows from the model. - * + * * @param row The row to remove. */ public void removeRow(int row) { - checkModel(); - if(model instanceof DefaultTableModel){ ((DefaultTableModel)model).removeRow(indexes[row]); } } - + /** - * Provides access to the row in the sorted model according to the sorted + * Provides access to the row in the sorted model according to the sorted * row. - * + * * @param sorterRow The sorter row. * @return The row index in the actual model. */ @@ -160,14 +158,13 @@ public int getModelRow(int sorterRow){ @Override public void setValueAt(Object aValue, int aRow, int aColumn) { - checkModel(); - model.setValueAt(aValue, indexes[aRow], aColumn); + model.setValueAt(aValue, indexes[aRow], aColumn); } /** * Sorts the supplied column. The ascending boolean is used to determine the * way of sorting. - * + * * @param column The column to sort. */ public void sortByColumn(int column) { @@ -176,7 +173,7 @@ public void sortByColumn(int column) { /** * Sorts the supplied column ascending or descending. - * + * * @param column The column to sort. * @param asc If true, sort ascending, or else sort descending. */ @@ -186,21 +183,21 @@ public void sortByColumn(int column, boolean asc) { sortingColumns.addElement(new Integer(column)); sort(this); lastSortColumn = column; - super.tableChanged(new TableModelEvent(this)); + super.tableChanged(new TableModelEvent(this)); } - + /** - * Reexecutes the last sort action. + * Re-executes the last sort action. */ public void resort(){ if(lastSortColumn != -1){ this.sortByColumn(lastSortColumn, ascending); } } - + /** * Removes the supplied column from the supplied table. - * + * * @param column The column to remove. * @param tableView The table to remove the column from. */ @@ -209,12 +206,12 @@ public void removeColumn(int column, JTable tableView){ TableColumn col = columnModel.getColumn(column); tableView.removeColumn(col); tableView.repaint(); - + if(tableView instanceof UserDataTable){ ((UserDataTable)tableView).repaintHeader(); } } - + private void n2sort() { for (int i = 0; i < getRowCount(); i++) { for (int j = i+1; j < getRowCount(); j++) { @@ -227,7 +224,7 @@ private void n2sort() { /* * Algorithm requires twice the space of an in-place algorithm and makes - * NlogN assigments shuttling the values between the two + * NlogN assignments shuttling the values between the two * arrays. The number of compares appears to vary between N-1 and * NlogN depending on the initial order but the main reason for * using it here is that, unlike qsort, it is stable. @@ -248,12 +245,12 @@ private void shuttlesort(int from[], int to[], int low, int high) { ordered. If so, no further comparisons are needed; the sub-array can just be copied. The array must be copied rather than assigned otherwise sister calls in the recursion might - get out of sinc. When the number of elements is three they - are partitioned so that the first set, [low, mid), has one - element and and the second, [mid, high), has two. We skip the - optimisation when the number of elements is three or less as + get out of sync. When the number of elements is three they + are partitioned so that the first set, [low, mid], has one + element and and the second, [mid, high], has two. We skip the + optimization when the number of elements is three or less as the first compare in the normal merge will produce the same - sequence of steps. This optimisation seems to be worthwhile + sequence of steps. This optimization seems to be worthwhile for partially ordered lists but some analysis is needed to find out how the performance drops to Nlog(N) as the initial order diminishes - it may drop very quickly. */ @@ -265,7 +262,7 @@ find out how the performance drops to Nlog(N) as the initial return; } - // A normal merge. + // A normal merge. for (int i = low; i < high; i++) { if (q >= high || (p < middle && compare(from[p], from[q]) <= 0)) { @@ -282,34 +279,28 @@ private void swap(int i, int j) { indexes[i] = indexes[j]; indexes[j] = tmp; } - - private void checkModel() { - if (indexes.length != model.getRowCount()) { - //System.err.println("Sorter not informed of a change in model."); - } - } - + private int compareRowsByColumn(int row1, int row2, int column) { Class type = model.getColumnClass(column); TableModel data = model; // Check for nulls. - + Object o1 = data.getValueAt(row1, column); - Object o2 = data.getValueAt(row2, column); + Object o2 = data.getValueAt(row2, column); // If both values are null, return 0. if (o1 == null && o2 == null) { - return 0; - } else if (o1 == null) { // Define null less than everything. - return -1; - } else if (o2 == null) { - return 1; + return 0; + } else if (o1 == null) { // Define null less than everything. + return -1; + } else if (o2 == null) { + return 1; } /* * Copy all returned values from the getValue call in case - * an optimised model is reusing one object to return many + * an optimized model is reusing one object to return many * values. The Number subclasses in the JDK are immutable and * so will not be used in this way but other subclasses of * Number might want to do this to save space and avoid @@ -318,12 +309,12 @@ private int compareRowsByColumn(int row1, int row2, int column) { if(model instanceof UserDataTableModel){ String columnName = this.getColumnName(column); MetaField field = ((UserDataTableModel)model).getUserDataType().getField(columnName); - + if(field instanceof MetaPrimitive){ String typeName = field.getTypeName(); - - if( "c_long".equals(typeName) || - "c_ulong".equals(typeName) || + + if( "c_long".equals(typeName) || + "c_ulong".equals(typeName) || "c_octet".equals(typeName) || "c_short".equals(typeName) || "c_ushort".equals(typeName) || @@ -335,7 +326,7 @@ private int compareRowsByColumn(int row1, int row2, int column) { { double d1 = Double.parseDouble((String)data.getValueAt(row1, column)); double d2 = Double.parseDouble((String)data.getValueAt(row2, column)); - + if (d1 < d2) { return -1; } else if (d1 > d2) { @@ -346,11 +337,11 @@ private int compareRowsByColumn(int row1, int row2, int column) { } } } - + if (type.getSuperclass() == java.lang.Number.class) { double d1 = Double.parseDouble((String)data.getValueAt(row1, column)); double d2 = Double.parseDouble((String)data.getValueAt(row2, column)); - + if (d1 < d2) { return -1; } else if (d1 > d2) { @@ -432,15 +423,13 @@ private void reallocateIndexes() { // for the new data model. indexes = new int[rowCount]; - // Initialise with the identity mapping. + // Initialize with the identity mapping. for (int row = 0; row < rowCount; row++) { indexes[row] = row; } } - - private void sort(Object sender) { - checkModel(); + private void sort(Object sender) { compares = 0; shuttlesort(indexes.clone(), indexes, 0, indexes.length); } diff --git a/src/tools/cm/common/code/org/opensplice/common/model/table/WriterHistoryInfoTableModel.java b/src/tools/cm/common/code/org/opensplice/common/model/table/WriterHistoryInfoTableModel.java index 5a1c9ee86..66d8ef98c 100644 --- a/src/tools/cm/common/code/org/opensplice/common/model/table/WriterHistoryInfoTableModel.java +++ b/src/tools/cm/common/code/org/opensplice/common/model/table/WriterHistoryInfoTableModel.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -28,22 +29,22 @@ /** * Model that holds the history of one specific Sample. - * - * @date Nov 17, 2004 + * + * @date Nov 17, 2004 */ public class WriterHistoryInfoTableModel extends SampleInfoTableModel { /** * Constructs a new HistoryTableModel. - * + * */ public WriterHistoryInfoTableModel(){ super(); } - + /** * Administrates the Sample info oof the supplied Sample. It replaces the * possible previous info. - * + * * @param data The Sample, which info must be administrated. * @return true if the supplied Sample and its Message are not null, false * otherwise. @@ -53,32 +54,26 @@ public boolean setData(Sample data){ Message msg = data.getMessage(); boolean success = false; int row = 0; - + if(msg != null){ - /* - State state = data.getState(); - this.setValueAt(this.getSampleState(state), row++, 1); - this.setValueAt(this.getViewState(state), row++, 1); - this.setValueAt(this.getInstanceState(state), row++, 1); - */ this.setValueAt("N/A", row++, 1); this.setValueAt("N/A", row++, 1); this.setValueAt("N/A", row++, 1); - + this.setValueAt("N/A", row++, 1); this.setValueAt("N/A", row++, 1); - + this.setValueAt("N/A", row++, 1); - + String date = "(" + new Date(msg.getWriteTimeSec() * 1000) + ")"; this.setValueAt(Long.toString(msg.getWriteTimeSec()) + "s. " + Long.toString(msg.getWriteTimeNanoSec()) + "ns. " + - date, + date, row++, 1); this.setValueAt("N/A", row++, 1); - + GID gid = msg.getWriterGid(); - + if(gid != null){ this.setValueAt(Long.toString(gid.getLocalId()), row++, 1); this.setValueAt(Long.toString(gid.getSystemId()), row++, 1); @@ -88,7 +83,7 @@ public boolean setData(Sample data){ this.setValueAt("N/A", row++, 1); } gid = msg.getInstanceGid(); - + if(gid != null){ this.setValueAt(Long.toString(gid.getLocalId()), row++, 1); this.setValueAt(Long.toString(gid.getSystemId()), row++, 1); @@ -99,7 +94,7 @@ public boolean setData(Sample data){ } this.setValueAt(Long.toString(msg.getSampleSequenceNumber()), row++, 1); this.setValueAt(msg.getQos().getReliabilityKind().toString(), row++, 1); - + success = true; } return success; diff --git a/src/tools/cm/common/code/org/opensplice/common/model/table/qos/EntityQoSTableModel.java b/src/tools/cm/common/code/org/opensplice/common/model/table/qos/EntityQoSTableModel.java index e7dbcfe26..e04b5114d 100644 --- a/src/tools/cm/common/code/org/opensplice/common/model/table/qos/EntityQoSTableModel.java +++ b/src/tools/cm/common/code/org/opensplice/common/model/table/qos/EntityQoSTableModel.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cm/common/code/org/opensplice/common/model/table/qos/ParticipantQoSTableModel.java b/src/tools/cm/common/code/org/opensplice/common/model/table/qos/ParticipantQoSTableModel.java index f2b51c24c..c6db55ea7 100644 --- a/src/tools/cm/common/code/org/opensplice/common/model/table/qos/ParticipantQoSTableModel.java +++ b/src/tools/cm/common/code/org/opensplice/common/model/table/qos/ParticipantQoSTableModel.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cm/common/code/org/opensplice/common/model/table/qos/PublisherQoSTableModel.java b/src/tools/cm/common/code/org/opensplice/common/model/table/qos/PublisherQoSTableModel.java index 3a3ec8618..2bb26a635 100644 --- a/src/tools/cm/common/code/org/opensplice/common/model/table/qos/PublisherQoSTableModel.java +++ b/src/tools/cm/common/code/org/opensplice/common/model/table/qos/PublisherQoSTableModel.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -203,7 +204,7 @@ public boolean updateDefaultValues(PublisherQoS qos) { if (p != null) { this.setValueAt(p, row++, valueColumn); } else { - this.setValueAt(nill, row++, valueColumn); + this.setValueAt("", row++, valueColumn); } } else { row++; @@ -272,7 +273,7 @@ public boolean update() { if(p != null){ this.setValueAt(p, row++, valueColumn); } else { - this.setValueAt(nill, row++, valueColumn); + this.setValueAt("", row++, valueColumn); } GroupDataPolicy gdp = qos.getGroupData(); diff --git a/src/tools/cm/common/code/org/opensplice/common/model/table/qos/ReaderQoSTableModel.java b/src/tools/cm/common/code/org/opensplice/common/model/table/qos/ReaderQoSTableModel.java index f49a7046b..3c185a034 100644 --- a/src/tools/cm/common/code/org/opensplice/common/model/table/qos/ReaderQoSTableModel.java +++ b/src/tools/cm/common/code/org/opensplice/common/model/table/qos/ReaderQoSTableModel.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cm/common/code/org/opensplice/common/model/table/qos/SubscriberQoSTableModel.java b/src/tools/cm/common/code/org/opensplice/common/model/table/qos/SubscriberQoSTableModel.java index 4105bcde7..f25642827 100644 --- a/src/tools/cm/common/code/org/opensplice/common/model/table/qos/SubscriberQoSTableModel.java +++ b/src/tools/cm/common/code/org/opensplice/common/model/table/qos/SubscriberQoSTableModel.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -230,7 +231,7 @@ public boolean updateDefaultValues(SubscriberQoS qos) { if (p != null) { this.setValueAt(p, row++, valueColumn); } else { - this.setValueAt(nill, row++, valueColumn); + this.setValueAt("", row++, valueColumn); } } else { row++; @@ -325,7 +326,7 @@ public boolean update() { if(p != null){ this.setValueAt(p, row++, valueColumn); } else { - this.setValueAt(nill, row++, valueColumn); + this.setValueAt("", row++, valueColumn); } GroupDataPolicy gdp = qos.getGroupData(); diff --git a/src/tools/cm/common/code/org/opensplice/common/model/table/qos/TopicQoSTableModel.java b/src/tools/cm/common/code/org/opensplice/common/model/table/qos/TopicQoSTableModel.java index 5a81ee780..33754be6b 100644 --- a/src/tools/cm/common/code/org/opensplice/common/model/table/qos/TopicQoSTableModel.java +++ b/src/tools/cm/common/code/org/opensplice/common/model/table/qos/TopicQoSTableModel.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cm/common/code/org/opensplice/common/model/table/qos/WriterQoSTableModel.java b/src/tools/cm/common/code/org/opensplice/common/model/table/qos/WriterQoSTableModel.java index 5723bf2df..a4f2ac125 100644 --- a/src/tools/cm/common/code/org/opensplice/common/model/table/qos/WriterQoSTableModel.java +++ b/src/tools/cm/common/code/org/opensplice/common/model/table/qos/WriterQoSTableModel.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cm/common/code/org/opensplice/common/model/table/status/EntityStatusTableModel.java b/src/tools/cm/common/code/org/opensplice/common/model/table/status/EntityStatusTableModel.java index 5a226cd8b..8912d683b 100644 --- a/src/tools/cm/common/code/org/opensplice/common/model/table/status/EntityStatusTableModel.java +++ b/src/tools/cm/common/code/org/opensplice/common/model/table/status/EntityStatusTableModel.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cm/common/code/org/opensplice/common/model/table/status/PartitionStatusTableModel.java b/src/tools/cm/common/code/org/opensplice/common/model/table/status/PartitionStatusTableModel.java index cf9597c39..fb9091982 100644 --- a/src/tools/cm/common/code/org/opensplice/common/model/table/status/PartitionStatusTableModel.java +++ b/src/tools/cm/common/code/org/opensplice/common/model/table/status/PartitionStatusTableModel.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cm/common/code/org/opensplice/common/model/table/status/ReaderStatusTableModel.java b/src/tools/cm/common/code/org/opensplice/common/model/table/status/ReaderStatusTableModel.java index 082e0550d..d983aee4b 100644 --- a/src/tools/cm/common/code/org/opensplice/common/model/table/status/ReaderStatusTableModel.java +++ b/src/tools/cm/common/code/org/opensplice/common/model/table/status/ReaderStatusTableModel.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cm/common/code/org/opensplice/common/model/table/status/SubscriberStatusTableModel.java b/src/tools/cm/common/code/org/opensplice/common/model/table/status/SubscriberStatusTableModel.java index 19c69cf7a..392366ea5 100644 --- a/src/tools/cm/common/code/org/opensplice/common/model/table/status/SubscriberStatusTableModel.java +++ b/src/tools/cm/common/code/org/opensplice/common/model/table/status/SubscriberStatusTableModel.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cm/common/code/org/opensplice/common/model/table/status/TopicStatusTableModel.java b/src/tools/cm/common/code/org/opensplice/common/model/table/status/TopicStatusTableModel.java index 17da27e10..5a0aa80ae 100644 --- a/src/tools/cm/common/code/org/opensplice/common/model/table/status/TopicStatusTableModel.java +++ b/src/tools/cm/common/code/org/opensplice/common/model/table/status/TopicStatusTableModel.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cm/common/code/org/opensplice/common/model/table/status/WriterStatusTableModel.java b/src/tools/cm/common/code/org/opensplice/common/model/table/status/WriterStatusTableModel.java index 6d978326f..417f9687f 100644 --- a/src/tools/cm/common/code/org/opensplice/common/model/table/status/WriterStatusTableModel.java +++ b/src/tools/cm/common/code/org/opensplice/common/model/table/status/WriterStatusTableModel.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cm/common/code/org/opensplice/common/util/Config.java b/src/tools/cm/common/code/org/opensplice/common/util/Config.java index c54c2d2fc..2344d966e 100644 --- a/src/tools/cm/common/code/org/opensplice/common/util/Config.java +++ b/src/tools/cm/common/code/org/opensplice/common/util/Config.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cm/common/code/org/opensplice/common/util/ConfigValidator.java b/src/tools/cm/common/code/org/opensplice/common/util/ConfigValidator.java index 4dfd0bb69..6dc489561 100644 --- a/src/tools/cm/common/code/org/opensplice/common/util/ConfigValidator.java +++ b/src/tools/cm/common/code/org/opensplice/common/util/ConfigValidator.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,11 +21,11 @@ package org.opensplice.common.util; /** - * Interface that provides routines for validating configuration. - * Implementations of this interface can guarantee that the configuration for + * Interface that provides routines for validating configuration. + * Implementations of this interface can guarantee that the configuration for * an application will be correct. - * - * @date Jan 12, 2005 + * + * @date Jan 12, 2005 */ public interface ConfigValidator { /** @@ -32,29 +33,29 @@ public interface ConfigValidator { * checks if the supplied value is valid. If so, return that value. If not * return a valid one. The Config component calls this routine for each * key it finds when loading a configuration file. - * + * * @param key The key in the configuration. - * @param value The value as it has been found in the confuration file. - * @return A correct value for that key. If null is returned, the Config + * @param value The value as it has been found in the configuration file. + * @return A correct value for that key. If null is returned, the Config * component will remove the key from the configuration. */ public String getValidatedValue(String key, String value); - + /** * Returns the default value for the supplied key. This function is called * by the Config component when an application asks for a property that has * not been defined. - * - * @param key The key where to resolve the default value of. + * + * @param key The key where to resolve the default value of. * @return The default value for the supplied key. */ public String getDefaultValue(String key); - + /** * Checks whether the supplied key/value combination is valid. The Config * component calls this function when an application sets a property in the * configuration. - * + * * @param key The key of the property. * @param value The value of the property. * @return If the combination is valid; true and false otherwise. diff --git a/src/tools/cm/common/code/org/opensplice/common/util/Initializer.java b/src/tools/cm/common/code/org/opensplice/common/util/Initializer.java index 4ae5c42c7..767c087bf 100644 --- a/src/tools/cm/common/code/org/opensplice/common/util/Initializer.java +++ b/src/tools/cm/common/code/org/opensplice/common/util/Initializer.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cm/common/code/org/opensplice/common/util/Report.java b/src/tools/cm/common/code/org/opensplice/common/util/Report.java index d64e54e6e..fe63bf10f 100644 --- a/src/tools/cm/common/code/org/opensplice/common/util/Report.java +++ b/src/tools/cm/common/code/org/opensplice/common/util/Report.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cm/common/code/org/opensplice/common/view/CheckBoxNameValuePanel.java b/src/tools/cm/common/code/org/opensplice/common/view/CheckBoxNameValuePanel.java index eaf63b99c..f0a603133 100644 --- a/src/tools/cm/common/code/org/opensplice/common/view/CheckBoxNameValuePanel.java +++ b/src/tools/cm/common/code/org/opensplice/common/view/CheckBoxNameValuePanel.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cm/common/code/org/opensplice/common/view/CoherentPublishFrameCommon.java b/src/tools/cm/common/code/org/opensplice/common/view/CoherentPublishFrameCommon.java index 02637a392..dc9ff379c 100644 --- a/src/tools/cm/common/code/org/opensplice/common/view/CoherentPublishFrameCommon.java +++ b/src/tools/cm/common/code/org/opensplice/common/view/CoherentPublishFrameCommon.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cm/common/code/org/opensplice/common/view/CommonFileChooser.java b/src/tools/cm/common/code/org/opensplice/common/view/CommonFileChooser.java index 71e7419e7..cb357ffe7 100644 --- a/src/tools/cm/common/code/org/opensplice/common/view/CommonFileChooser.java +++ b/src/tools/cm/common/code/org/opensplice/common/view/CommonFileChooser.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cm/common/code/org/opensplice/common/view/DialogWindow.java b/src/tools/cm/common/code/org/opensplice/common/view/DialogWindow.java index 09b4f3d2d..7fb4e2b5c 100644 --- a/src/tools/cm/common/code/org/opensplice/common/view/DialogWindow.java +++ b/src/tools/cm/common/code/org/opensplice/common/view/DialogWindow.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,7 +19,7 @@ * */ /** - * Contains all SPLICE DDS C&M Tooling common view components. + * Contains all SPLICE DDS C&M Tooling common view components. */ package org.opensplice.common.view; @@ -34,20 +35,20 @@ /** * This class represents a generic dialog window and is meant to provide a fast and - * simple way of constructing dialog windows. - * + * simple way of constructing dialog windows. + * * The window contains a status bar and * 'OK' and 'Cancel' buttons. By providing NameValuePanel objects, the user can - * fill the dialog window with as many fields as he wishes. + * fill the dialog window with as many fields as he wishes. */ -public class DialogWindow extends JFrame { +public class DialogWindow extends JFrame { /** * The constructor of this object. It initializes the window. - * - * @param _controller The controller where to sent actions to. 'cancel' + * + * @param _controller The controller where to sent actions to. 'cancel' * for the Cancel button and _action for the OK button * @param _fields Array of name/value pairs that must be showed in the dialog window. - * @param _action The action that the controller expects when the user clicks th OK button. + * @param _action The action that the controller expects when the user clicks the OK button. * @param _title The title of the dialog window that will be shown in the top. */ public DialogWindow(ActionListener _controller, NameValuePanel[] _fields, String _action, String _title) { @@ -59,7 +60,7 @@ public DialogWindow(ActionListener _controller, NameValuePanel[] _fields, String fieldNameMapping = new HashMap(_fields.length); initialize(); } - + DialogWindow(ActionListener _controller, String _action, String _title){ super(); controller = _controller; @@ -69,9 +70,9 @@ public DialogWindow(ActionListener _controller, NameValuePanel[] _fields, String fieldNameMapping = new HashMap(); initialize(); } - + /** - * This method initializes the dialog window. + * This method initializes the dialog window. */ void initialize() { this.setSize(1200, 1600); @@ -87,33 +88,33 @@ public void windowClosing(WindowEvent e) { }); this.pack(); } - + /** * This method initializes the root content pane - * + * * @return The created or already existing content pane. */ JPanel getJContentPane() { if (jContentPane == null) { jContentPane = new JPanel(); java.awt.GridLayout layGridLayout15 = new java.awt.GridLayout(); - + if(fields != null){ - layGridLayout15.setRows(fields.length); + layGridLayout15.setRows(fields.length); } - + layGridLayout15.setColumns(1); layGridLayout15.setHgap(0); layGridLayout15.setVgap(5); JPanel inputPanel = new JPanel(); inputPanel.setLayout(layGridLayout15); jContentPane.setLayout(new java.awt.BorderLayout()); - + if(fields != null){ for(int i=0; i. */ public HashMap getValues() { HashMap values = new HashMap(); - + for(int i=0; i f = fieldNameMapping.values(); Iterator fIter = f.iterator(); - + while(fIter.hasNext()){ nvp = fIter.next(); test = nvp.getValue(); if(test == null || test.equals("")){ if(!(nvp.isEmptyInputAllowed())){ return false; - } + } } } return true; } - + public NameValuePanel getField(String name){ return fieldNameMapping.get(name); } - + public NameValuePanel[] getFields(){ return fields; } - + /** * The root pane of the dialog window. */ javax.swing.JPanel jContentPane = null; - + /** * The status panel. */ StatusPanel statusPanel = null; - + /** * The panel where the 'OK' and 'Cancel' buttons are placed on. */ JPanel buttonPanel = null; - + /** * The 'Cancel' button. */ JButton cancelButton = null; - + /** * The 'OK' button. */ JButton okButton = null; - + /** * The controller (mvC), where the action command will be sent to when the * user clicks the OK button. */ ActionListener controller = null; - + /** * The title of the dialog window. */ String title = null; - + /** - * The action string that must be sent to the controller + * The action string that must be sent to the controller * when the 'OK' button is clicked. */ String action = null; - + /** * The name/value pairs that are shown in the window. */ - NameValuePanel[] fields = null; - + NameValuePanel[] fields = null; + /** * Fields in the window */ diff --git a/src/tools/cm/common/code/org/opensplice/common/view/FileNameValuePanel.java b/src/tools/cm/common/code/org/opensplice/common/view/FileNameValuePanel.java index f219e2e89..ece6df472 100644 --- a/src/tools/cm/common/code/org/opensplice/common/view/FileNameValuePanel.java +++ b/src/tools/cm/common/code/org/opensplice/common/view/FileNameValuePanel.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -49,32 +50,6 @@ public FileNameValuePanel( this(fieldName, defaultValue, emptyInputAllowed, browseText, parent, new Dimension(50, 20), new Dimension(100, 20)); } - /* - public FileNameValuePanel( - String fieldName, - String defaultValue, - boolean emptyInputAllowed, - String browseText, - JFrame parent, - Dimension labelDim, - Dimension fieldDim) - { - super(fieldName, defaultValue, emptyInputAllowed, labelDim, fieldDim); - - this.parent = parent; - field = new JTextField(); - - if(defaultValue != null){ - ((JTextField)field).setText(defaultValue); - } - field.setMinimumSize(this.fieldDim); - field.setPreferredSize(this.fieldDim); - field.setMaximumSize(this.fieldDim); - - this.add(field, null); - } - */ - public FileNameValuePanel( String fieldName, String defaultValue, diff --git a/src/tools/cm/common/code/org/opensplice/common/view/MainWindow.java b/src/tools/cm/common/code/org/opensplice/common/view/MainWindow.java index 6cf92b4a4..12e6938b3 100644 --- a/src/tools/cm/common/code/org/opensplice/common/view/MainWindow.java +++ b/src/tools/cm/common/code/org/opensplice/common/view/MainWindow.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cm/common/code/org/opensplice/common/view/NameValuePanel.java b/src/tools/cm/common/code/org/opensplice/common/view/NameValuePanel.java index 54a612d6c..d264ec070 100644 --- a/src/tools/cm/common/code/org/opensplice/common/view/NameValuePanel.java +++ b/src/tools/cm/common/code/org/opensplice/common/view/NameValuePanel.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,30 +27,30 @@ /** * This class is meant to provide a standard generic input panel that - * contains a label and a input field. - * - * Input fields that are currently supported are: - * - textfields + * contains a label and a input field. + * + * Input fields that are currently supported are: + * - textfields * - comboboxes. */ public abstract class NameValuePanel extends JPanel { /** * Creates an input panel with a label and a textfield. * @param _fieldName The name of the field that is also used as label. - * @param _emptyInputAllowed Boolean that specifies if empty input is allowed when + * @param _emptyInputAllowed Boolean that specifies if empty input is allowed when * submitted. */ public NameValuePanel( - String fieldName, - Object defaultValue, - boolean emptyInputAllowed, - Dimension labelDim, + String fieldName, + Object defaultValue, + boolean emptyInputAllowed, + Dimension labelDim, Dimension fieldDim) { super(); if(labelDim != null){ this.labelDim = labelDim; - + if(this.labelDim.height != 20){ this.labelDim.height = 20; } @@ -58,7 +59,7 @@ public NameValuePanel( } if(fieldDim != null){ this.fieldDim = fieldDim; - + if(this.fieldDim.height != 20){ this.fieldDim.height = 20; } @@ -71,7 +72,7 @@ public NameValuePanel( this.initLayout(); this.initLabel(); } - + /** * Initializes the layout (FlowLayout is used). */ @@ -80,10 +81,10 @@ protected void initLayout(){ layFlowLayout.setVgap(0); this.setLayout(layFlowLayout); } - + /** * Initializes the label. - * + * * The fieldName is also used as label text. */ protected void initLabel(){ @@ -92,64 +93,64 @@ protected void initLabel(){ label.setPreferredSize(labelDim); this.add(label); } - + /** * Provides access to the name of the field. - * + * * @return The name of the field. */ @Override public String getName(){ return fieldName; } - + /** * Provides access to the emptyInputIsAllowed boolean. - * + * * @return true if the field may be empty when submitted, false otherwise. */ public boolean isEmptyInputAllowed(){ return emptyInputAllowed; } - + /** * Provides access to the editor component for the field value. - * + * * @return The editor component for the field value. */ public JComponent getField(){ return field; } - + public abstract Object getValue(); - + @Override public abstract void setEnabled(boolean enabled); - + /** * The name of the field. */ protected String fieldName = null; - + /** * The input field. */ protected JComponent field = null; - + /** * The label Dimension. */ protected Dimension labelDim = null; - + /** * The field Dimension. */ protected Dimension fieldDim = null; - + /** - * Boolean that specifies if empy input is allowed for this field. + * Boolean that specifies if empty input is allowed for this field. */ protected boolean emptyInputAllowed; - + protected Object defaultValue = null; } diff --git a/src/tools/cm/common/code/org/opensplice/common/view/QoSNameValuePanel.java b/src/tools/cm/common/code/org/opensplice/common/view/QoSNameValuePanel.java index 2a813dd2d..c1276f2dd 100644 --- a/src/tools/cm/common/code/org/opensplice/common/view/QoSNameValuePanel.java +++ b/src/tools/cm/common/code/org/opensplice/common/view/QoSNameValuePanel.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cm/common/code/org/opensplice/common/view/SelectNameValuePanel.java b/src/tools/cm/common/code/org/opensplice/common/view/SelectNameValuePanel.java index c8a7d33b7..c4d16b504 100644 --- a/src/tools/cm/common/code/org/opensplice/common/view/SelectNameValuePanel.java +++ b/src/tools/cm/common/code/org/opensplice/common/view/SelectNameValuePanel.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cm/common/code/org/opensplice/common/view/StatusPanel.java b/src/tools/cm/common/code/org/opensplice/common/view/StatusPanel.java index 43080169d..06397ab96 100644 --- a/src/tools/cm/common/code/org/opensplice/common/view/StatusPanel.java +++ b/src/tools/cm/common/code/org/opensplice/common/view/StatusPanel.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -41,7 +42,7 @@ public class StatusPanel extends JPanel { * Creates a new StatusPanel that can be used to provide information about * the status of the application of a certain action. The StatusPanel * optionally provides a connection light and a progressbar. - * + * * @param width * The width of the panel. * @param _defaultText @@ -171,7 +172,7 @@ public StatusPanel(int width, String _defaultText, /** * Sets the connection light to green when connected and to red if not. - * + * * @param connected * Whether or not the application has a connection. * @param toolTip @@ -202,7 +203,7 @@ public void run() { * Sets the status message to the supplied message and sets the progressbar * to indeterminate mode or resets it. This is done by calling the * setStatus(String, boolean) method as well as the setBusy method. - * + * * @param message * The message to set. * @param persistent @@ -220,9 +221,6 @@ public synchronized void setStatus(String msg, boolean persistent, final boolean b = busy; final boolean p = persistent; - /* - * Runnable runner = new Runnable() { public void run(){ - */ String myMsg = message; if ("".equals(message)) { @@ -293,11 +291,6 @@ public void actionPerformed(ActionEvent e) { lastPersistent = false; } } - /* - * } - * - * }; runner.run(); SwingUtilities.invokeLater(runner); - */ } /** @@ -306,7 +299,7 @@ public void actionPerformed(ActionEvent e) { * not be shown. If the message starts with "Warning:" the background color * will become yellow and the "Warning:" part of the string will not be * displayed. - * + * * @param message * The new status message. * @param persistent @@ -320,11 +313,11 @@ public synchronized void setStatus(String message, boolean persistent) { /** * Sets the progressbar status. When true, the progressbar will go into - * inderminate mode and display 'busy...', when false the progressbar will + * indeterminate mode and display 'busy...', when false the progressbar will * leave indeterminate mode and display 'ready' - * + * * @param busy - * When true, the progressbar will go into inderminate mode + * When true, the progressbar will go into indeterminate mode */ private synchronized void setBusy(boolean busy) { if (progressBar != null) { @@ -343,7 +336,7 @@ private synchronized void setBusy(boolean busy) { /** * Provides access to the current status. - * + * * @return The currently displayed status. */ public synchronized String getStatus() { diff --git a/src/tools/cm/common/code/org/opensplice/common/view/TabbedDialogWindow.java b/src/tools/cm/common/code/org/opensplice/common/view/TabbedDialogWindow.java index d9addb377..9a54e24ae 100644 --- a/src/tools/cm/common/code/org/opensplice/common/view/TabbedDialogWindow.java +++ b/src/tools/cm/common/code/org/opensplice/common/view/TabbedDialogWindow.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cm/common/code/org/opensplice/common/view/TabbedNameValuePanel.java b/src/tools/cm/common/code/org/opensplice/common/view/TabbedNameValuePanel.java index e8f9a573c..6ed903fc8 100644 --- a/src/tools/cm/common/code/org/opensplice/common/view/TabbedNameValuePanel.java +++ b/src/tools/cm/common/code/org/opensplice/common/view/TabbedNameValuePanel.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cm/common/code/org/opensplice/common/view/TextNameValuePanel.java b/src/tools/cm/common/code/org/opensplice/common/view/TextNameValuePanel.java index 4e0f539ec..141a63fc4 100644 --- a/src/tools/cm/common/code/org/opensplice/common/view/TextNameValuePanel.java +++ b/src/tools/cm/common/code/org/opensplice/common/view/TextNameValuePanel.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cm/common/code/org/opensplice/common/view/TypeEvolutionCBViewHolder.java b/src/tools/cm/common/code/org/opensplice/common/view/TypeEvolutionCBViewHolder.java index 4c995de2c..3639fe7f0 100644 --- a/src/tools/cm/common/code/org/opensplice/common/view/TypeEvolutionCBViewHolder.java +++ b/src/tools/cm/common/code/org/opensplice/common/view/TypeEvolutionCBViewHolder.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cm/common/code/org/opensplice/common/view/URINameValuePanel.java b/src/tools/cm/common/code/org/opensplice/common/view/URINameValuePanel.java index 3d512d5b6..e4e4e6610 100644 --- a/src/tools/cm/common/code/org/opensplice/common/view/URINameValuePanel.java +++ b/src/tools/cm/common/code/org/opensplice/common/view/URINameValuePanel.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cm/common/code/org/opensplice/common/view/entity/DataTypeFrame.java b/src/tools/cm/common/code/org/opensplice/common/view/entity/DataTypeFrame.java index d162d57e7..9d15f33d1 100644 --- a/src/tools/cm/common/code/org/opensplice/common/view/entity/DataTypeFrame.java +++ b/src/tools/cm/common/code/org/opensplice/common/view/entity/DataTypeFrame.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -69,7 +70,7 @@ public void setTypeEvolution (TypeEvolutionCBViewHolder _typeEvolutionViewHolder setStatus("Error: " + e.getMessage(), false, false); } } - setStatus(/*"Evolution: " + */typeEvolutionViewHolder.toString() + " (" + typeEvo.getTypeHash() + ")", true, false); + setStatus(typeEvolutionViewHolder.toString() + " (" + typeEvo.getTypeHash() + ")", true, false); dataTypePane.setCaretPosition(0); } diff --git a/src/tools/cm/common/code/org/opensplice/common/view/entity/EntityInfoFormatter.java b/src/tools/cm/common/code/org/opensplice/common/view/entity/EntityInfoFormatter.java index fb91ebe91..e18951b5e 100644 --- a/src/tools/cm/common/code/org/opensplice/common/view/entity/EntityInfoFormatter.java +++ b/src/tools/cm/common/code/org/opensplice/common/view/entity/EntityInfoFormatter.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cm/common/code/org/opensplice/common/view/entity/EntityInfoFormatterHTML.java b/src/tools/cm/common/code/org/opensplice/common/view/entity/EntityInfoFormatterHTML.java index bb6797310..fd02939c2 100644 --- a/src/tools/cm/common/code/org/opensplice/common/view/entity/EntityInfoFormatterHTML.java +++ b/src/tools/cm/common/code/org/opensplice/common/view/entity/EntityInfoFormatterHTML.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cm/common/code/org/opensplice/common/view/entity/EntityInfoFormatterText.java b/src/tools/cm/common/code/org/opensplice/common/view/entity/EntityInfoFormatterText.java index 6457a0be4..b85bf2e95 100644 --- a/src/tools/cm/common/code/org/opensplice/common/view/entity/EntityInfoFormatterText.java +++ b/src/tools/cm/common/code/org/opensplice/common/view/entity/EntityInfoFormatterText.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cm/common/code/org/opensplice/common/view/entity/EntityInfoFrame.java b/src/tools/cm/common/code/org/opensplice/common/view/entity/EntityInfoFrame.java index 0978b2032..d02feb26e 100644 --- a/src/tools/cm/common/code/org/opensplice/common/view/entity/EntityInfoFrame.java +++ b/src/tools/cm/common/code/org/opensplice/common/view/entity/EntityInfoFrame.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -85,7 +86,7 @@ * - Resolve and display Entity status. * - Resolve and display Entity QoS. * - Allow user to change Entity QoS. - * + * * @date Oct 1, 2004 */ public class EntityInfoFrame extends JFrame implements ActionListener, ModelListener { @@ -123,12 +124,12 @@ public class EntityInfoFrame extends JFrame implements ActionListener, ModelList private JButton getQoSButton = null; private JButton setQoSButton = null; private String type = null; - + /** * This is the default constructor that creates a frame that displays - * information about the supplied Entity. Information about changes + * information about the supplied Entity. Information about changes * in the view are communicated to the supplied ModelRegister. - * + * * @param _entity The Entity to display. * @param _register The ModelRegister where to communicate changes to. */ @@ -139,21 +140,21 @@ public EntityInfoFrame(Entity _entity, ModelRegister _register, JFrame _parent) entity = _entity; initialize(); } - + /** * Provides access to the Entity of the frame. - * + * * @return The Entity of the frame. */ public Entity getEntity(){ return entity; } - - + + /** - * Sets the update delay of the frame. The selected tab determines which + * Sets the update delay of the frame. The selected tab determines which * part of the information is being updated. - * + * * @param millis The update delay in milliseconds. If the supplied delay * is smaller then 0, automatic updating is disabled. */ @@ -176,38 +177,38 @@ public synchronized void setUpdateDelay(int millis){ this.fireFrameChanged("update_delay"); } } - + /** * Changes the content type of the EntityInfoPane that is displaying the * data type of the Entity. - * + * * @param contentType The content type to set. Supported content types are * 'text/plain' and 'text/html'. * @return true if applying of the data type succeeded, false otherwise. */ public boolean setDataTypeContentType(String contentType){ boolean result = false; - + if((dataTypeView != null) && (contentType != null)){ result = dataTypeView.getEntityInfoPane().setViewType(contentType); - + } type = contentType; selectContentType(); return result; } - + /** - * This method initializes attributeTable - * + * This method initializes attributeTable + * * @return Table that holds the attributes of the Entity and its current - * values. - */ + * values. + */ public JTable getAttributeTable() { if (attributeTable == null) { attributeTable = new JTable(new EntityAttributeTableModel(entity)); attributeTable.setAutoResizeMode(JTable.AUTO_RESIZE_LAST_COLUMN); - + TableColumnModel cModel = attributeTable.getColumnModel(); cModel.getColumn(0).setPreferredWidth(100); cModel.getColumn(0).setMaxWidth(100); @@ -216,20 +217,20 @@ public JTable getAttributeTable() { } return attributeTable; } - + /** * Handles events that are triggered by the update timer. The selected tab * will be updated and the timer restarted. - * + * * @param e The event that occurred. */ @Override public void actionPerformed(ActionEvent e) { boolean success; - + if(e.getSource().equals(updateTimer)){ success = false; - + if(!iconified && !closed){ if(tabbedPane.getSelectedComponent().equals(statusScrollPane)){ try { @@ -250,7 +251,7 @@ public void actionPerformed(ActionEvent e) { } else { success = true; } - + if(!success){ if(updateTimer != null){ if(updateTimer.isRunning()){ @@ -275,10 +276,10 @@ public void actionPerformed(ActionEvent e) { } } } - + /** * Updates the information in the selected tab. - * + * * @param msg The update message. */ @Override @@ -286,13 +287,13 @@ public void update(String msg){ if(msg != null){ if("tabbed_pane_update".equals(msg)){ Component selected = tabbedPane.getSelectedComponent(); - + if(selected.equals(statusScrollPane)){ refreshItem.setEnabled(false); if(statusTable == null){ setCursor(new Cursor(Cursor.WAIT_CURSOR)); setStatus("Initializing status pane...", true, true); - + Runnable worker = new Runnable(){ @Override public void run(){ @@ -307,16 +308,16 @@ public void run(){ } } }; - SwingUtilities.invokeLater(worker); + SwingUtilities.invokeLater(worker); } refreshItem.setEnabled(true); } else if(selected.equals(dataTypeScrollPane)){ refreshItem.setEnabled(false); - + if(dataTypeView == null){ setCursor(new Cursor(Cursor.WAIT_CURSOR)); setStatus("Initializing data type pane...", true, true); - + Runnable worker = new Runnable(){ @Override public void run(){ @@ -329,11 +330,11 @@ public void run(){ } } else if(selected.equals(qosPanel)){ refreshItem.setEnabled(true); - + if(qosTable == null){ setCursor(new Cursor(Cursor.WAIT_CURSOR)); setStatus("Initializing QoS pane...", true, true); - + Runnable worker = new Runnable(){ @Override public void run(){ @@ -354,11 +355,11 @@ public void run(){ } } else if(selected.equals(statisticsPane)){ refreshItem.setEnabled(true); - + if(statisticsTable == null){ setCursor(new Cursor(Cursor.WAIT_CURSOR)); setStatus("Initializing Statistics pane...", true, true); - + Runnable worker = new Runnable(){ @Override public void run(){ @@ -382,7 +383,7 @@ public void run(){ iconified = true; } else if("window_deiconified".equals(msg)){ iconified = false; - + if(updateTimer != null){ if(!updateTimer.isRunning()){ updateTimer.start(); @@ -396,15 +397,15 @@ public void run(){ } else if("get_qos".equals(msg)){ getQoSButton.setEnabled(false); setQoSButton.setEnabled(false); - + setCursor(new Cursor(Cursor.WAIT_CURSOR)); setStatus("Resolving QoS...", true, true); - + Runnable worker = new Runnable(){ @Override public void run(){ boolean b = qosTable.update(); - + if(b){ setStatus("QoS resolved", false, false); setCursor(new Cursor(Cursor.DEFAULT_CURSOR)); @@ -421,10 +422,10 @@ public void run(){ } else if("set_qos".equals(msg)){ getQoSButton.setEnabled(false); setQoSButton.setEnabled(false); - + setCursor(new Cursor(Cursor.WAIT_CURSOR)); setStatus("Applying new QoS...", true, true); - + Runnable worker = new Runnable(){ @Override public void run(){ @@ -439,13 +440,6 @@ public void run(){ setCursor(new Cursor(Cursor.DEFAULT_CURSOR)); getQoSButton.setEnabled(true); setQoSButton.setEnabled(true); - - - /* - closed = true; - fireFrameChanged("entity_freed"); - dispose(); - */ } } }; @@ -453,7 +447,7 @@ public void run(){ } else if(msg.startsWith("view_")){ final String command = msg.substring(5); setStatus("Changing data type representation to " + type + "...", true, true); - + Runnable worker = new Runnable(){ @Override public void run(){ @@ -464,17 +458,17 @@ public void run(){ SwingUtilities.invokeLater(worker); } else if("refresh".equals(msg)){ Component selected = tabbedPane.getSelectedComponent(); - + if(selected.equals(statusScrollPane)){ refreshItem.setEnabled(false); setCursor(new Cursor(Cursor.WAIT_CURSOR)); setStatus("Resolving Status...", true, true); - + Runnable worker = new Runnable(){ @Override public void run(){ boolean success = ((EntityStatusTableModel)statusTable.getModel()).update(); - + if(success){ setStatus("Status resolved.", false, false); setCursor(new Cursor(Cursor.DEFAULT_CURSOR)); @@ -492,12 +486,12 @@ public void run(){ refreshItem.setEnabled(false); setCursor(new Cursor(Cursor.WAIT_CURSOR)); setStatus("Resolving Statistics...", true, true); - + Runnable worker = new Runnable(){ @Override public void run(){ boolean success = statisticsTable.update(); - + if(success){ setStatus("Statistics resolved.", false, false); setCursor(new Cursor(Cursor.DEFAULT_CURSOR)); @@ -517,12 +511,12 @@ public void run(){ refreshItem.setEnabled(false); setCursor(new Cursor(Cursor.WAIT_CURSOR)); setStatus("Refreshing attributes...", true, true); - + Runnable worker = new Runnable(){ @Override public void run(){ boolean success = ((EntityAttributeTableModel)(getAttributeTable().getModel())).update(); - + if(success){ setStatus("Attributes refreshed.", false, false); setCursor(new Cursor(Cursor.DEFAULT_CURSOR)); @@ -548,31 +542,31 @@ public void run(){ } } } - + /** * Sets the supplied status in the status bar. - * + * * @param msg The message to display. * @param persistent Whether or not the message should be displayed until * another message is set, or should be removed after an * amount of timer * @param busy Whether or not the status bar should display the progressbar - * and set the progress to indeterminate mode. + * and set the progress to indeterminate mode. */ public void setStatus(String msg, boolean persistent, boolean busy){ statusPanel.setStatus(msg, persistent, busy); } - + @Override public String toString(){ String result = this.getTitle(); - + return result; } - + /** * Notifies the ModelRegister about changes in the frame. - * + * * @param description The description about what changed. */ protected void fireFrameChanged(String description){ @@ -580,10 +574,10 @@ protected void fireFrameChanged(String description){ register.pushUpdate("entity_frame_" + description); } } - + /** * This method initializes this - * + * * @return void */ private void initialize() { @@ -596,7 +590,7 @@ private void initialize() { } /** * This method initializes rootPanel - * + * * @return The root panel of the frame. */ private JPanel getRootPanel() { @@ -610,15 +604,15 @@ private JPanel getRootPanel() { } /** - * This method initializes tabbedPane - * - * @return The tabbed pane that holds all views on the attached Entity. - */ + * This method initializes tabbedPane + * + * @return The tabbed pane that holds all views on the attached Entity. + */ private JTabbedPane getTabbedPane() { if (tabbedPane == null) { tabbedPane = new JTabbedPane(); tabbedPane.addTab("Attributes", null, getAttributesScrollPane(), "Entity attributes"); - + if( (entity instanceof Topic) || (entity instanceof Subscriber) || (entity instanceof DataReader) || @@ -638,27 +632,27 @@ private JTabbedPane getTabbedPane() { { tabbedPane.addTab("QoS", null, getQosPanel(), "Entity QoS policies"); } - + if( (entity instanceof Topic) || (entity instanceof DataReader) || - (entity instanceof Queue) || + (entity instanceof Queue) || (entity instanceof Query) || (entity instanceof Writer)) { tabbedPane.addTab("Data type", null, getDataTypeScrollPane(), "Data type"); } - + tabbedPane.addTab("Statistics", null, getStatisticsPane(), "Entity statistics"); - + tabbedPane.addChangeListener(controller); } return tabbedPane; } - + /** - * This method intializes dataTypeView. It is only displayed for Topic, Reader, + * This method initializes dataTypeView. It is only displayed for Topic, Reader, * or Writer entities and displays associated the data type of the entity. - * + * * @return The EntityInfoTabView that displays the data type of the Topic, Writer, or Reader. */ private EntityInfoTabView getDataTypeView(){ @@ -696,12 +690,12 @@ private EntityInfoTabView getDataTypeView(){ } return dataTypeView; } - + /** - * This method initializes attributesScrollPane - * - * @return The pane that holds the attributesTable. - */ + * This method initializes attributesScrollPane + * + * @return The pane that holds the attributesTable. + */ private JScrollPane getAttributesScrollPane() { if (attributesScrollPane == null) { attributesScrollPane = new JScrollPane(); @@ -709,30 +703,29 @@ private JScrollPane getAttributesScrollPane() { } return attributesScrollPane; } - + /** - * This method initializes statusScrollPane - * - * @return Pane that holds the statusTable. - */ + * This method initializes statusScrollPane + * + * @return Pane that holds the statusTable. + */ private JScrollPane getStatusScrollPane() { if (statusScrollPane == null) { statusScrollPane = new JScrollPane(); - //statusScrollPane.setViewportView(getStatusTable()); } return statusScrollPane; } - + /** - * This method initializes statusTable - * - * @return Table that holds the current status of the attached Entity. + * This method initializes statusTable + * + * @return Table that holds the current status of the attached Entity. * @throws CommonException - */ + */ private JTable getStatusTable() throws CommonException { if (statusTable == null) { EntityStatusTableModel model = null; - + if(entity instanceof Partition){ model = new PartitionStatusTableModel((Partition)entity); } else if(entity instanceof Topic){ @@ -756,12 +749,12 @@ private JTable getStatusTable() throws CommonException { } return statusTable; } - + /** - * This method initializes qosPanel - * - * @return Currently an empty panel. - */ + * This method initializes qosPanel + * + * @return Currently an empty panel. + */ private JPanel getQosPanel() { if (qosPanel == null) { qosPanel = new JPanel(); @@ -771,30 +764,29 @@ private JPanel getQosPanel() { } return qosPanel; } - + /** - * This method initializes dataTypeScrollPane - * - * @return Pane that holds the dataTypePane. - */ + * This method initializes dataTypeScrollPane + * + * @return Pane that holds the dataTypePane. + */ private JScrollPane getDataTypeScrollPane() { if (dataTypeScrollPane == null) { dataTypeScrollPane = new JScrollPane(); - //dataTypeScrollPane.setViewportView(getDataTypePane()); } return dataTypeScrollPane; } - + private StatusPanel getStatusPanel(){ if(statusPanel == null){ statusPanel = new StatusPanel(this.getWidth(), "", false, true); } return statusPanel; } - + /** * Provides access to infoMenuBar. - * + * * @return Returns the infoMenuBar. */ private JMenuBar getInfoMenuBar() { @@ -806,61 +798,61 @@ private JMenuBar getInfoMenuBar() { } return infoMenuBar; } - + private JMenu getFileMenu() { if(fileMenu == null) { fileMenu = new JMenu(); fileMenu.setText("File"); fileMenu.setMnemonic(java.awt.event.KeyEvent.VK_F); - + fileMenu.add(getCloseItem()); } return fileMenu; } - + private JMenu getEditMenu() { if(editMenu == null) { editMenu = new JMenu(); editMenu.setText("Edit"); editMenu.setMnemonic(java.awt.event.KeyEvent.VK_E); - + editMenu.add(this.getRefreshItem()); } return editMenu; } - + private JMenu getViewMenu() { if(viewMenu == null) { viewMenu = new JMenu(); viewMenu.setText("View"); viewMenu.setMnemonic(java.awt.event.KeyEvent.VK_V); - + if( (entity instanceof Topic) || (entity instanceof DataReader) || - (entity instanceof Queue) || + (entity instanceof Queue) || (entity instanceof Query) || (entity instanceof Writer)) { ButtonGroup group = new ButtonGroup(); group.add(getContentHtmlItem()); group.add(getContentTextItem()); - + JMenu viewDataTypeMenu = new JMenu(); viewDataTypeMenu.setText("Data type representation"); viewDataTypeMenu.add(getContentTextItem()); viewDataTypeMenu.add(getContentHtmlItem()); viewMenu.add(viewDataTypeMenu); selectContentType(); - + } - + if(parent != null){ viewMenu.add(getViewMainItem()); } } return viewMenu; } - + private JMenuItem getViewMainItem(){ if(viewMainItem == null){ viewMainItem = new JMenuItem(); @@ -874,7 +866,7 @@ private JMenuItem getViewMainItem(){ } /** * Provides access to closeItem. - * + * * @return Returns the closeItem. */ private JMenuItem getCloseItem() { @@ -888,10 +880,10 @@ private JMenuItem getCloseItem() { } return closeItem; } - + /** * Provides access to refreshStatusItem. - * + * * @return Returns the refreshStatusItem. */ private JMenuItem getRefreshItem() { @@ -905,10 +897,10 @@ private JMenuItem getRefreshItem() { } return refreshItem; } - + /** * Provides access to buttonPanel. - * + * * @return Returns the buttonPanel. */ private JPanel getButtonPanel() { @@ -925,7 +917,7 @@ private JPanel getButtonPanel() { } /** * Provides access to getQoSButton. - * + * * @return Returns the getQoSButton. */ private JButton getGetQoSButton() { @@ -945,7 +937,7 @@ private JButton getGetQoSButton() { } /** * Provides access to setQoSButton. - * + * * @return Returns the setQoSButton. */ private JButton getSetQoSButton() { @@ -963,17 +955,17 @@ private JButton getSetQoSButton() { } return setQoSButton; } - + private JScrollPane getQosScrollPane(){ if(qosScrollPane == null){ qosScrollPane = new JScrollPane(); } return qosScrollPane; } - + /** * Provides access to qosTable. - * + * * @return Returns the qosTable. * @throws CommonException */ @@ -983,24 +975,24 @@ private QoSTable getQosTable() throws CommonException { } return qosTable; } - + private JScrollPane getStatisticsPane() { if(statisticsPane == null){ statisticsPane = new JScrollPane(); } return statisticsPane; } - + private StatisticsTable getStatisticsTable() throws CommonException { if(statisticsTable == null){ statisticsTable = new StatisticsTable(entity, this); } return statisticsTable; } - + /** * Provides access to contentHtmlItem. - * + * * @return Returns the contentHtmlItem. */ private JRadioButtonMenuItem getContentHtmlItem() { @@ -1016,7 +1008,7 @@ private JRadioButtonMenuItem getContentHtmlItem() { } /** * Provides access to contentTextItem. - * + * * @return Returns the contentTextItem. */ private JRadioButtonMenuItem getContentTextItem() { @@ -1030,12 +1022,12 @@ private JRadioButtonMenuItem getContentTextItem() { } return contentTextItem; } - + private void selectContentType(){ if(type == null){ type = Config.getInstance().getProperty("data_type_content_type"); } - + if("text/plain".equals(type)){ contentTextItem.setSelected(true); contentHtmlItem.setSelected(false); diff --git a/src/tools/cm/common/code/org/opensplice/common/view/entity/EntityInfoPane.java b/src/tools/cm/common/code/org/opensplice/common/view/entity/EntityInfoPane.java index 1018dba79..badaa3546 100644 --- a/src/tools/cm/common/code/org/opensplice/common/view/entity/EntityInfoPane.java +++ b/src/tools/cm/common/code/org/opensplice/common/view/entity/EntityInfoPane.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,35 +26,35 @@ /** - * Pane that is capable of displaying several representations of an object + * Pane that is capable of displaying several representations of an object * depending on the view type. - * + * * Currently supported views types: * - text/plain * - text/html - * + * * Currently supported objects: * - MetaType * - String - * + * * @date Jun 7, 2004 */ public class EntityInfoPane extends JEditorPane{ /** * Creates a graphical pane where object information can be showed in. * The information depends on the view type. - * + * * @param contentType The content type that specifies in which format the - * information must be shown. + * information must be shown. */ public EntityInfoPane(String contentType){ this.setEditable(false); curObject = null; EditorKit ek = this.getEditorKitForContentType(contentType); this.setEditorKit(ek); - + curContentType = ek.getContentType(); - + if("text/plain".equals(curContentType)){ infoFormatter = new EntityInfoFormatterText(); } @@ -65,22 +66,22 @@ else if("text/html".equals(curContentType)){ } this.setText(infoFormatter.getValue(curObject)); } - - + + /** * Sets the content type to the supplied type. - * + * * @param contentType The content type that specifies in which format the * information must be shown. * @return true if succeeded, false if not . */ public boolean setViewType(String contentType){ boolean result = true; - + if(!(curContentType.equals(contentType))){ final EditorKit ek = this.getEditorKitForContentType(contentType); final EntityInfoPane ep = this; - + /* * Because this is an expensive operation it is executed in a * new thread that is invoked later by the event-dispatching thread. @@ -106,58 +107,44 @@ else if("text/html".equals(curContentType)){ } }; SwingUtilities.invokeLater(worker); - /* - ep.setEditorKit(ek); - curContentType = ek.getContentType(); - if("text/plain".equals(curContentType)){ - infoFormatter = new EntityInfoFormatterText(); - } - else if("text/html".equals(curContentType)){ - infoFormatter = new EntityInfoFormatterHTML(); - } - else{ - infoFormatter = new EntityInfoFormatterText(); - } - ep.setText(infoFormatter.getValue(curObject)); - */ } return result; } - + /** - * Sets selection to supplied object. This is done by asking the current + * Sets selection to supplied object. This is done by asking the current * formatter to format the object. - * + * * @param object The object to select. */ public synchronized void setSelection(Object object){ this.setText(infoFormatter.getValue(object)); curObject = object; } - + /** * Clears the cache of MetaType objects. */ public void clearCache(){ infoFormatter.clearCache(); } - + public String getCurrentContentType() { return curContentType; } - + /** * Current entity formatter. */ private transient EntityInfoFormatter infoFormatter; - + /** * Current content type. Currently supported types: * - text/plain * - text/html */ private String curContentType; - + /** * The currently selected object. */ diff --git a/src/tools/cm/common/code/org/opensplice/common/view/entity/EntityInfoTabView.java b/src/tools/cm/common/code/org/opensplice/common/view/entity/EntityInfoTabView.java index b0de6a705..edf657cb5 100644 --- a/src/tools/cm/common/code/org/opensplice/common/view/entity/EntityInfoTabView.java +++ b/src/tools/cm/common/code/org/opensplice/common/view/entity/EntityInfoTabView.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cm/common/code/org/opensplice/common/view/entity/tree/DependantEntityTreeNode.java b/src/tools/cm/common/code/org/opensplice/common/view/entity/tree/DependantEntityTreeNode.java index a63e07bcb..b3487508a 100644 --- a/src/tools/cm/common/code/org/opensplice/common/view/entity/tree/DependantEntityTreeNode.java +++ b/src/tools/cm/common/code/org/opensplice/common/view/entity/tree/DependantEntityTreeNode.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -33,7 +34,7 @@ * Represents a tree node in an EntityTree. It holds a specific Entity. The * Entity depends on the entities that are contained by the child nodes of * this tree node. This class is a concrete descendant of EntityTreeNode. - * + * * @date Oct 4, 2004 */ public class DependantEntityTreeNode extends EntityTreeNode { @@ -41,18 +42,18 @@ public class DependantEntityTreeNode extends EntityTreeNode { /** * Creates a new DependantEntityTreeNode, which holds the supplied Entity * and is created in the supplied tree. - * + * * @param _e The Entity that the node needs to hold. * @param _tree The tree the node is located in. */ public DependantEntityTreeNode(Entity _e, EntityTree _tree) { super(_e, _tree, _tree.getChildrenVisible()); } - + /** * Creates a new DependantEntityTreeNode, which holds the supplied Entity * and is created in the supplied tree. - * + * * @param _e The Entity that the node needs to hold. * @param _tree The tree the node is located in. * @param childrenVisible Whether the children of this node should be resolved. @@ -60,14 +61,14 @@ public DependantEntityTreeNode(Entity _e, EntityTree _tree) { public DependantEntityTreeNode(Entity _e, EntityTree _tree, boolean childrenVisible) { super(_e, _tree, childrenVisible); } - + /** - * Refreshes this node by resolving the dependant entities of the Entity - * that is associated with this node. When an Entity is not available + * Refreshes this node by resolving the dependent entities of the Entity + * that is associated with this node. When an Entity is not available * anymore it will result in the child node being removed. When an Entity * was found that is not already a child of this node, a new child node is * added to this node. - * + * * When the Entity associated with this node is not available anymore, the * parent node of this node will be refreshed. */ @@ -76,13 +77,13 @@ public void refresh() { Entity entity = (Entity)userObject; Entity[] entities = null; boolean proceed; - + if(this.childrenVisible){ Object rootNode = tree.getTreeModel().getRoot(); - + /* - * Determine whether to resolve dependant entities here. There is - * a cyclomatic reference in the dependant entities. This is as + * Determine whether to resolve dependent entities here. There is + * a cyclomatic reference in the dependent entities. This is as * expected, but tooling should not display it. */ if(this.getParent() instanceof RootTreeNode){ @@ -94,7 +95,7 @@ public void refresh() { } else { proceed = true; } - + if(proceed){ try { entities = entity.getDependantEntities(EntityFilter.ENTITY); @@ -107,21 +108,36 @@ public void refresh() { /* * Don't refresh the parent, because it potentially makes the * application get into a deadlock, when the entity of this node - * is being created and deleted in the splice kernel in the same + * is being created and deleted in the splice kernel in the same * frequency as the refresh action. */ - //p.refresh(); return; } int childCount = entities.length; - + for(int i=0; i node is colored green. + * - Tree visibility == false && node visibility == true --> node is colored green. * - Tree visibility == true && node visibility == false --> node is colored red. * - Tree visibility == node visibility --> node is colored black. * @param visible Whether or not the children of the node should be resolved. @@ -173,11 +174,11 @@ public void setChildrenVisible(boolean visible, boolean recursive) throws Common EntityTreeNode etn; this.childrenVisible = visible; this.recursiveVisible = recursive; - + if(((EntityTreeNode)this.getParent()).isExpanded()){ this.refresh(); } - + if(visible && recursive){ for(int i=0; i protobufProps = null; - + /** * Constructs a new UserDataTable that displays a UserDataTableSorter, * which contains a UserDataTableModel. The sorter is (as the name says) - * able to sort data in the model. + * able to sort data in the model. * * @param sorter The sorter that contains the data and is able to sort the * data in its model. @@ -72,24 +73,24 @@ public UserDataTable(UserDataTableSorter sorter){ this.configureEnclosingScrollPane(); this.setColumnSizes(100); } - + /** * Sets the width of all columns in the table to the supplied size. - * + * * @param size The width to set the columnwidth to. */ private void setColumnSizes(int size){ TableColumnModel tcm = this.getColumnModel(); - + for(int i=0; i 1.5.0. * - It passes on the commandline arguments. Arguments that are supported * are: * -# * * @param args These are passed on to the initialize function of the - * SpliceTuner object. + * SpliceConfig object. */ public static void main(String[] args) { boolean redirect = true; diff --git a/src/tools/cm/config/code/org/opensplice/config/ValidateDataConfiguration.java b/src/tools/cm/config/code/org/opensplice/config/ValidateDataConfiguration.java new file mode 100644 index 000000000..d33765be4 --- /dev/null +++ b/src/tools/cm/config/code/org/opensplice/config/ValidateDataConfiguration.java @@ -0,0 +1,82 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.opensplice.config; + +import java.io.File; + +import org.opensplice.config.data.DataConfiguration; + +public class ValidateDataConfiguration { + + public static void main(String[] args) { + String uri = null; + if (args.length > 0 + && args[0] != null + && args[0].toLowerCase().startsWith("-uri=")) { + uri = args[0].substring(5); /* '-uri=' is 5 characters */ + } + else{ + System.out.println("Invalid parameters, expects format -uri=abc"); + System.exit(1); + } + + ValidateDataConfiguration vdc = new ValidateDataConfiguration(); + boolean isValid = vdc.validateFromUri(uri); + + System.out.println("isValidConfig: "+ isValid); + + if(isValid){ + System.exit(0); + } + else{ + System.exit(-1); + } + + } + + public ValidateDataConfiguration() { + super(); + + } + + private boolean validateFromUri(String uri) { + boolean isValid = true; + + try{ + File file = null; + + if (uri.startsWith("file://")) { + /* strip off file:// */ + uri = uri.substring(7); + } + file = new File(uri); + final File f = file; + new DataConfiguration(f, false); + + }catch(Exception e){ + isValid = false; + } + + return isValid; + } + +} diff --git a/src/tools/cm/config/code/org/opensplice/config/data/DataAttribute.java b/src/tools/cm/config/code/org/opensplice/config/data/DataAttribute.java index 09a0a5bfa..98dafcc30 100644 --- a/src/tools/cm/config/code/org/opensplice/config/data/DataAttribute.java +++ b/src/tools/cm/config/code/org/opensplice/config/data/DataAttribute.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cm/config/code/org/opensplice/config/data/DataConfiguration.java b/src/tools/cm/config/code/org/opensplice/config/data/DataConfiguration.java index cece8cd18..a2e21e319 100644 --- a/src/tools/cm/config/code/org/opensplice/config/data/DataConfiguration.java +++ b/src/tools/cm/config/code/org/opensplice/config/data/DataConfiguration.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -248,7 +249,7 @@ public void fatalError(SAXParseException exception) throws SAXException { createDomainServiceForSerivce(de, de.getMetadata(), serviceName); } } - /* remove commerial items from xml tree in community mode */ + /* remove commercial items from xml tree in community mode */ for (MetaNode m : comServices) { if (m.getVersion().equals(ConfigModeIntializer.COMMERCIAL) && (currentMode == ConfigModeIntializer.COMMUNITY_MODE || currentMode == ConfigModeIntializer.COMMUNITY_MODE_FILE_OPEN)) { @@ -878,7 +879,6 @@ private void init() throws DataException{ this.rootElement = new DataElement(metaElement, domElement); this.rootElement.setOwner(this); - //this.initDataElement(this.rootElement); for(MetaElement me: this.metadata.getServices()){ while(occurrences < me.getMinOccurrences()){ diff --git a/src/tools/cm/config/code/org/opensplice/config/data/DataConfigurationListener.java b/src/tools/cm/config/code/org/opensplice/config/data/DataConfigurationListener.java index 5e88710f4..c0586e670 100644 --- a/src/tools/cm/config/code/org/opensplice/config/data/DataConfigurationListener.java +++ b/src/tools/cm/config/code/org/opensplice/config/data/DataConfigurationListener.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cm/config/code/org/opensplice/config/data/DataElement.java b/src/tools/cm/config/code/org/opensplice/config/data/DataElement.java index 4653440ea..82fab15ce 100644 --- a/src/tools/cm/config/code/org/opensplice/config/data/DataElement.java +++ b/src/tools/cm/config/code/org/opensplice/config/data/DataElement.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cm/config/code/org/opensplice/config/data/DataException.java b/src/tools/cm/config/code/org/opensplice/config/data/DataException.java index c3c18f5da..95eb6d7c1 100644 --- a/src/tools/cm/config/code/org/opensplice/config/data/DataException.java +++ b/src/tools/cm/config/code/org/opensplice/config/data/DataException.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cm/config/code/org/opensplice/config/data/DataNode.java b/src/tools/cm/config/code/org/opensplice/config/data/DataNode.java index b081762b7..338753aa8 100644 --- a/src/tools/cm/config/code/org/opensplice/config/data/DataNode.java +++ b/src/tools/cm/config/code/org/opensplice/config/data/DataNode.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cm/config/code/org/opensplice/config/data/DataValue.java b/src/tools/cm/config/code/org/opensplice/config/data/DataValue.java index 5335e5c05..37a89ac62 100644 --- a/src/tools/cm/config/code/org/opensplice/config/data/DataValue.java +++ b/src/tools/cm/config/code/org/opensplice/config/data/DataValue.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cm/config/code/org/opensplice/config/meta/MetaAttribute.java b/src/tools/cm/config/code/org/opensplice/config/meta/MetaAttribute.java index b095b38d3..7a31e5e89 100644 --- a/src/tools/cm/config/code/org/opensplice/config/meta/MetaAttribute.java +++ b/src/tools/cm/config/code/org/opensplice/config/meta/MetaAttribute.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cm/config/code/org/opensplice/config/meta/MetaConfiguration.java b/src/tools/cm/config/code/org/opensplice/config/meta/MetaConfiguration.java index 1f30446fc..51582590c 100644 --- a/src/tools/cm/config/code/org/opensplice/config/meta/MetaConfiguration.java +++ b/src/tools/cm/config/code/org/opensplice/config/meta/MetaConfiguration.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -110,7 +111,7 @@ private static MetaConfiguration load(String fileName){ public static MetaConfiguration getInstance(){ if (instance == null) { - String fileName = "metaconfig.xml"; + String fileName = "ospl_metaconfig.xml"; instance = MetaConfiguration.load(fileName); } return instance; @@ -332,17 +333,13 @@ private static MetaElement parseElement(Element element, boolean isRootElement, version = element.getAttribute("version"); hidden = Boolean.parseBoolean(element.getAttribute("hidden")); - //if(!isRootElement){ - minOccurrences = Integer.parseInt(element.getAttribute("minOccurrences")); - maxOccurrences = Integer.parseInt(element.getAttribute("maxOccurrences")); + minOccurrences = Integer.parseInt(element.getAttribute("minOccurrences")); + maxOccurrences = Integer.parseInt(element.getAttribute("maxOccurrences")); + + if(maxOccurrences == 0){ + maxOccurrences = Integer.MAX_VALUE; + } - if(maxOccurrences == 0){ - maxOccurrences = Integer.MAX_VALUE; - } - //} else { - // minOccurrences = 0; - // maxOccurrences = Integer.MAX_VALUE; - //} metaChildren = new ArrayList(); children = element.getChildNodes(); diff --git a/src/tools/cm/config/code/org/opensplice/config/meta/MetaElement.java b/src/tools/cm/config/code/org/opensplice/config/meta/MetaElement.java index d033b616f..e39fb371d 100644 --- a/src/tools/cm/config/code/org/opensplice/config/meta/MetaElement.java +++ b/src/tools/cm/config/code/org/opensplice/config/meta/MetaElement.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cm/config/code/org/opensplice/config/meta/MetaException.java b/src/tools/cm/config/code/org/opensplice/config/meta/MetaException.java index c2b5593e7..33d8559eb 100644 --- a/src/tools/cm/config/code/org/opensplice/config/meta/MetaException.java +++ b/src/tools/cm/config/code/org/opensplice/config/meta/MetaException.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cm/config/code/org/opensplice/config/meta/MetaExceptionType.java b/src/tools/cm/config/code/org/opensplice/config/meta/MetaExceptionType.java index dcafb8e72..7c53401e6 100644 --- a/src/tools/cm/config/code/org/opensplice/config/meta/MetaExceptionType.java +++ b/src/tools/cm/config/code/org/opensplice/config/meta/MetaExceptionType.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cm/config/code/org/opensplice/config/meta/MetaNode.java b/src/tools/cm/config/code/org/opensplice/config/meta/MetaNode.java index 243f6c6fb..2702ee145 100644 --- a/src/tools/cm/config/code/org/opensplice/config/meta/MetaNode.java +++ b/src/tools/cm/config/code/org/opensplice/config/meta/MetaNode.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cm/config/code/org/opensplice/config/meta/MetaValue.java b/src/tools/cm/config/code/org/opensplice/config/meta/MetaValue.java index a490b7313..3bfacf3fc 100644 --- a/src/tools/cm/config/code/org/opensplice/config/meta/MetaValue.java +++ b/src/tools/cm/config/code/org/opensplice/config/meta/MetaValue.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cm/config/code/org/opensplice/config/meta/MetaValueBoolean.java b/src/tools/cm/config/code/org/opensplice/config/meta/MetaValueBoolean.java index 85cdb4b81..cd78acb8a 100644 --- a/src/tools/cm/config/code/org/opensplice/config/meta/MetaValueBoolean.java +++ b/src/tools/cm/config/code/org/opensplice/config/meta/MetaValueBoolean.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cm/config/code/org/opensplice/config/meta/MetaValueDouble.java b/src/tools/cm/config/code/org/opensplice/config/meta/MetaValueDouble.java index dc45b235a..74f84e44a 100644 --- a/src/tools/cm/config/code/org/opensplice/config/meta/MetaValueDouble.java +++ b/src/tools/cm/config/code/org/opensplice/config/meta/MetaValueDouble.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cm/config/code/org/opensplice/config/meta/MetaValueEnum.java b/src/tools/cm/config/code/org/opensplice/config/meta/MetaValueEnum.java index 397705c77..ece3717ed 100644 --- a/src/tools/cm/config/code/org/opensplice/config/meta/MetaValueEnum.java +++ b/src/tools/cm/config/code/org/opensplice/config/meta/MetaValueEnum.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cm/config/code/org/opensplice/config/meta/MetaValueFloat.java b/src/tools/cm/config/code/org/opensplice/config/meta/MetaValueFloat.java index 68ac57973..00dc6fb32 100644 --- a/src/tools/cm/config/code/org/opensplice/config/meta/MetaValueFloat.java +++ b/src/tools/cm/config/code/org/opensplice/config/meta/MetaValueFloat.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cm/config/code/org/opensplice/config/meta/MetaValueInt.java b/src/tools/cm/config/code/org/opensplice/config/meta/MetaValueInt.java index aab1b6fb3..77889c829 100644 --- a/src/tools/cm/config/code/org/opensplice/config/meta/MetaValueInt.java +++ b/src/tools/cm/config/code/org/opensplice/config/meta/MetaValueInt.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cm/config/code/org/opensplice/config/meta/MetaValueLong.java b/src/tools/cm/config/code/org/opensplice/config/meta/MetaValueLong.java index b34973f5e..8d52517ae 100644 --- a/src/tools/cm/config/code/org/opensplice/config/meta/MetaValueLong.java +++ b/src/tools/cm/config/code/org/opensplice/config/meta/MetaValueLong.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cm/config/code/org/opensplice/config/meta/MetaValueNatural.java b/src/tools/cm/config/code/org/opensplice/config/meta/MetaValueNatural.java index da1f88c68..f3eb6d4fa 100644 --- a/src/tools/cm/config/code/org/opensplice/config/meta/MetaValueNatural.java +++ b/src/tools/cm/config/code/org/opensplice/config/meta/MetaValueNatural.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cm/config/code/org/opensplice/config/meta/MetaValueSize.java b/src/tools/cm/config/code/org/opensplice/config/meta/MetaValueSize.java index b068551ca..49ccb90f0 100644 --- a/src/tools/cm/config/code/org/opensplice/config/meta/MetaValueSize.java +++ b/src/tools/cm/config/code/org/opensplice/config/meta/MetaValueSize.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cm/config/code/org/opensplice/config/meta/MetaValueString.java b/src/tools/cm/config/code/org/opensplice/config/meta/MetaValueString.java index 42aeb305f..6773da377 100644 --- a/src/tools/cm/config/code/org/opensplice/config/meta/MetaValueString.java +++ b/src/tools/cm/config/code/org/opensplice/config/meta/MetaValueString.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cm/config/code/org/opensplice/config/swing/ConfigTransferHandler.java b/src/tools/cm/config/code/org/opensplice/config/swing/ConfigTransferHandler.java index ea6934f8a..df465b69d 100644 --- a/src/tools/cm/config/code/org/opensplice/config/swing/ConfigTransferHandler.java +++ b/src/tools/cm/config/code/org/opensplice/config/swing/ConfigTransferHandler.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cm/config/code/org/opensplice/config/swing/ConfigUtil.java b/src/tools/cm/config/code/org/opensplice/config/swing/ConfigUtil.java index 0bfbcf3d5..5d0031aeb 100644 --- a/src/tools/cm/config/code/org/opensplice/config/swing/ConfigUtil.java +++ b/src/tools/cm/config/code/org/opensplice/config/swing/ConfigUtil.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cm/config/code/org/opensplice/config/swing/ConfigWindow.java b/src/tools/cm/config/code/org/opensplice/config/swing/ConfigWindow.java index 71a422e1c..28983305e 100644 --- a/src/tools/cm/config/code/org/opensplice/config/swing/ConfigWindow.java +++ b/src/tools/cm/config/code/org/opensplice/config/swing/ConfigWindow.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -109,47 +110,47 @@ public DataConfiguration getConfig() { public void setDataConfiguration(DataConfiguration config){ DataElement[] services; - + if(this.config != null){ this.config.removeDataConfigurationListener(this); int count = mainTabbedPane.getComponentCount(); - + for(int i=0; i < count; i++){ mainTabbedPane.remove(0); } } this.config = config; - + if(this.config != null){ this.config.addDataConfigurationListener(this); services = config.getServices(); - + for(int i=0; i < services.length; i++){ ServicePanel servicePanel = new ServicePanel(services[i], this.statusPanel); servicePanel.setTransferHandler(transferHandler); mainTabbedPane.addTab( - ConfigUtil.getExtendedDataElementString(services[i]), + ConfigUtil.getExtendedDataElementString(services[i]), servicePanel); } } this.updateMenus(); } - + @Override public void nodeAdded(DataElement parent, DataNode nodeAdded) { this.updateMenus(); - + if(parent.equals(this.config.getRootElement())){ if(nodeAdded instanceof DataElement){ final DataElement service = (DataElement)nodeAdded; - + Runnable worker = new Runnable(){ @Override public void run(){ ServicePanel servicePanel = new ServicePanel(service, statusPanel); servicePanel.setTransferHandler(transferHandler); mainTabbedPane.addTab( - ConfigUtil.getExtendedDataElementString(service), + ConfigUtil.getExtendedDataElementString(service), servicePanel); } }; @@ -161,20 +162,20 @@ public void run(){ @Override public void nodeRemoved(DataElement parent, DataNode nodeRemoved) { this.updateMenus(); - + if(parent.equals(this.config.getRootElement())){ if(nodeRemoved instanceof DataElement){ final DataElement service = (DataElement)nodeRemoved; - + Runnable worker = new Runnable(){ @Override public void run(){ ServicePanel servicePanel; boolean found = false; - + for(int i=0; (i nodes; private DataConfiguration configuration; - + public DataElementTableModel(){ super(); this.element = null; @@ -47,7 +48,7 @@ public DataElementTableModel(){ this.nodes = new ArrayList(); this.addColumn("Name"); this.addColumn("Value"); - + } public void setElement(DataElement element){ @@ -57,7 +58,7 @@ public void setElement(DataElement element){ if(element != null){ this.element = element; this.initElement(); - + if(!this.element.getOwner().equals(this.configuration)){ if(this.configuration != null){ this.configuration.removeDataConfigurationListener(this); @@ -67,17 +68,17 @@ public void setElement(DataElement element){ } } } - + @Override public void nodeAdded(DataElement parent, DataNode nodeAdded) { DataNode parentParent; - + if(parent.equals(this.element)){ this.clear(); this.initElement(); } else { parentParent = parent.getParent(); - + if(this.element.equals(parentParent)){ this.clear(); this.initElement(); @@ -97,7 +98,7 @@ public void nodeRemoved(DataElement parent, DataNode nodeRemoved) { this.initElement(); } } - + private boolean containsNodeAsParent(DataNode node){ for(DataNode n: this.nodes){ if(n.getParent().equals(node)){ @@ -109,12 +110,10 @@ private boolean containsNodeAsParent(DataNode node){ @Override public void valueChanged(DataValue data, Object oldValue, Object newValue) { - final int index = this.nodes.indexOf(data); + final int index = this.nodes.indexOf(data); final Object v = newValue; - + if(index != -1){ - /*System.out.println("Value changed: data: " + data + ", oldValue: " + oldValue + " newValue: " + newValue + "(row=" + index +", col=1)");*/ - SwingUtilities.invokeLater(new Runnable(){ @Override public void run() { @@ -123,10 +122,10 @@ public void run() { }); } } - + public DataNode getNodeAt(int index){ DataNode result; - + if(this.nodes.size() >= (index-1)){ result = this.nodes.get(index); } else { @@ -134,11 +133,11 @@ public DataNode getNodeAt(int index){ } return result; } - + @Override public boolean isCellEditable(int row, int column) { boolean result; - + if(column == 1 && ConfigModeIntializer.CONFIGURATOR_MODE == ConfigModeIntializer.COMMERCIAL_MODE) { result = true; } else if (column == 1 && !element.getMetadata().getVersion().equals(ConfigModeIntializer.COMMERCIAL)) { @@ -148,11 +147,11 @@ public boolean isCellEditable(int row, int column) { } return result; } - + private void initElement(){ String elName; Object[] values = new Object[2]; - + for(DataNode dn: this.element.getChildren()){ if(dn instanceof DataAttribute){ values[0] = "@" + ((MetaAttribute)dn.getMetadata()).getName(); @@ -175,7 +174,7 @@ private void initElement(){ ((MetaElement)dn.getMetadata()).hasValueChildren()) { elName = ((MetaElement)dn.getMetadata()).getName(); - + for(DataNode elNode: ((DataElement)dn).getChildren()){ if(elNode instanceof DataValue){ values[0] = elName; @@ -193,15 +192,15 @@ private void initElement(){ } } } - + private void clear(){ int rows = super.getRowCount(); - + for(int i=0; i 0){ this.scrollPathToVisible( new TreePath( @@ -69,10 +70,10 @@ public MetaElementTree(MetaElement rootElement, StatusPanel status){ this.getSelectionModel().addTreeSelectionListener(this); this.setSelectionPath(new TreePath(this.rootNode.getPath())); } - + private void initElement(DefaultMutableTreeNode parent, MetaElement element){ DefaultMutableTreeNode node; - + for(MetaNode child: element.getChildren()){ if(child instanceof MetaElement){ node = new DefaultMutableTreeNode(child); @@ -81,50 +82,49 @@ private void initElement(DefaultMutableTreeNode parent, MetaElement element){ } } } - + @Override public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) { Component result = null; JLabel temp; Object nodeValue; - + if(value instanceof DefaultMutableTreeNode){ nodeValue = ((DefaultMutableTreeNode)value).getUserObject(); - + if(nodeValue instanceof MetaElement){ temp = new JLabel(ConfigUtil.getMetaElementString((MetaElement)nodeValue)); - + if(selected){ temp.setForeground(UIManager.getColor("Tree.selectionForeground")); temp.setBackground(UIManager.getColor("Tree.selectionBackground")); - temp.setOpaque(true); + temp.setOpaque(true); } else { temp.setForeground(UIManager.getColor("Tree.textForeground")); temp.setBackground(UIManager.getColor("Tree.textBackground")); } - //temp.setFont(temp.getFont().deriveFont(Font.PLAIN)); temp.setFont(temp.getFont().deriveFont(Font.BOLD)); result = temp; } } - + if(result == null){ result = initialRenderer.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus); } return result; } - + public MetaElement getSelectedMetaElement(){ MetaElement result = null; TreePath path = this.getSelectionPath(); - + if(path != null){ result = (MetaElement) ((DefaultMutableTreeNode)path.getLastPathComponent()).getUserObject(); } return result; } - + public MetaElement getMetaNodeAt(int x, int y) { MetaElement retVal = null; TreePath path = this.getClosestPathForLocation(x, y); @@ -138,10 +138,10 @@ public MetaElement getMetaNodeAt(int x, int y) { @Override public void valueChanged(TreeSelectionEvent e) { MetaElement me = this.getSelectedMetaElement(); - + if((me != null) && (status != null)){ status.setStatus("Element '" + me.getName() + "' selected.", true); } - + } } diff --git a/src/tools/cm/config/code/org/opensplice/config/swing/MetaNodeDocPane.java b/src/tools/cm/config/code/org/opensplice/config/swing/MetaNodeDocPane.java index cae30027b..56e60721c 100644 --- a/src/tools/cm/config/code/org/opensplice/config/swing/MetaNodeDocPane.java +++ b/src/tools/cm/config/code/org/opensplice/config/swing/MetaNodeDocPane.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cm/config/code/org/opensplice/config/swing/ServicePanel.java b/src/tools/cm/config/code/org/opensplice/config/swing/ServicePanel.java index 207d117dd..0727d902d 100644 --- a/src/tools/cm/config/code/org/opensplice/config/swing/ServicePanel.java +++ b/src/tools/cm/config/code/org/opensplice/config/swing/ServicePanel.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -61,7 +62,7 @@ public class ServicePanel extends JPanel implements TreeSelectionListener, ListS private DataElement serviceElement = null; private DataNodePopup popupController = null; private StatusPanel status = null; - + /** * This is the default constructor */ @@ -72,11 +73,11 @@ public ServicePanel(DataElement serviceElement, StatusPanel status) { this.status = status; initialize(); } - + public DataElement getService(){ return this.serviceElement; } - + public DataElementTable getConfigurationTable() { if (configurationTable == null) { configurationTable = new DataElementTable(this.popupController, serviceElement, this.status); @@ -88,7 +89,7 @@ public DataElementTable getConfigurationTable() { @Override public void valueChanged(TreeSelectionEvent e) { TreePath selectionPath = e.getNewLeadSelectionPath(); - + if(selectionPath != null){ this.getConfigurationTable().getSelectionModel().clearSelection(); DataElement selection = (DataElement)( @@ -104,7 +105,7 @@ public void valueChanged(TreeSelectionEvent e) { public void valueChanged(ListSelectionEvent e) { if(!e.getValueIsAdjusting()){ int selectedRow = this.getConfigurationTable().getSelectedRow(); - + if(selectedRow != -1){ this.getConfigurationElementTree().getSelectionModel().clearSelection(); DataNode selection = this.getConfigurationTable().getDataNodeAt(selectedRow); @@ -112,12 +113,12 @@ public void valueChanged(ListSelectionEvent e) { } } } - + @Override public void setTransferHandler(TransferHandler t){ super.setTransferHandler(t); int count = this.getComponentCount(); - + for(int i=0; i - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/tools/cm/config/code/splice_metaconfig_4.1.xml b/src/tools/cm/config/code/splice_metaconfig_4.1.xml deleted file mode 100644 index 43535a18a..000000000 --- a/src/tools/cm/config/code/splice_metaconfig_4.1.xml +++ /dev/null @@ -1,3685 +0,0 @@ - - - - - OpenSplice utilizes a shared-memory architecture where data is physically - present only once on any machine and where smart administration still - provides each subscriber with his own private view on this data. This - allows a subscribers data cache to be perceived as an individual - database that can content-filtered, queried, etc. (using the - content-subscription profile as supported by OpenSplice). This - shared-memory architecture results in an extremely low footprint, - excellent scalability and optimal performance when compared to - implementations where each reader/writer are communication-end points - each with its own storage (i.e. historical data both at reader and - writer) and where the data itself still has to be moved, even within - the same platform.

    - -

    Shared-memory is not only used to interconnect all applications that - reside within one computing node, but also for a configurable and - extensible set of services. These services provide pluggable functionality - such as networking (providing QoS-driven real-time networking based - on multiple reliable multicast 'channels'), durability (providing - fault-tolerant storage for both real-time state data as well as - persistent settings) and a remote control & monitoring soap-service - (providing remote web-based access using the SOAP protocol from the - OpenSplice Tuner tool).

    - -

    Because of the pluggable architecture, the OpenSplice middleware - can be easily configured on the fly by specifying which services to - be used as well as specifying their optimal configuration for the - application domain (networking parameters, durability levels, etc.). - Typically, there are many nodes within a system.

    - -

    The OpenSplice middleware including its services can be configured - by means of easy maintainable XML-file(s).

    - ]]>
    -
    - - - The Domain service is responsible for creating and initialising a shared nodal administration(in shared memory) - for a specific DDS Domain on a computing node. Without this administration, no other service or application is able - to participate in a DDS Domain.

    - -

    Once the administration has been initialised, the Domain service starts the set of pluggable services. The - lifecycle of the started services is under control of the Domain service, which means it will monitor the health - of all started services, take corrective actions if needed and stop the services when it is terminated.

    - -

    When a shutdown of the OpenSplice Domain service is requested, it will react by announcing the shutdown using the - shared administration. Applications will not be able to use DDS functionality anymore and services are requested - to terminate elegantly. Once this has succeeded, the Domain service will destroy the shared administration and - finally terminate itself.

    - ]]>
    - - - 0 - OpenSpliceV4 - - - - - This element specifies the interval in which services have to announce their liveliness.

    -

    Every OpenSplice service including the Domain service itself has to announce its liveliness regularly. - This allows corrective actions to be taken when one of the services becomes non-responsive. This - element specifies the required interval. Decreasing the interval decreases the time in which - non-responsiveness of a service is detected, but leads to more processing. Increasing it has - the opposite effect.

    - ]]>
    - 20.0 - 0.2 - - update_factor attribute - introduces some elasticity in this mechanism by making the services assert their liveliness more - often than required by the ExpiryTime. Services will report their liveliness every - ExpiryTime multiplied by this update_factor. - ]]> - 0.01 - 1.0 - 0.1 - -
    -
    - - - 1.0 - 60.0 - 10.0 - - - - - - 1048567 - 10485670 - - - This element specifies the start address where the - nodal shared administration is mapped into the virtual - memory for each process that attaches to the current Domain. - The possible values are platform dependent.

    -

    Change this value if the default address is already in - use, for example by another Domain Service or another - product.

    - ]]>
    - 0 - 0x40000000 - 0x80000000 - 0x40000000 -
    - - This element specifies the locking policy of the Database, indicating - whether to lock pages in physical memory or not.

    -

    With the virtual memory architecture, the operating system decides when - to swap memory pages from internal memory to disc. This results in execution - delays for the corresponding code because it has to be paged back into main - memory. The element Locking can be used to avoid such swapping for the - shared memory where the database resides. The user needs the appropriate - privileges from the underlying operating system to be able to use this option.

    -

    The possible values are:

    -
      -
    • True: lock the pages in memory.
    • -
    • False: don't lock the pages in memory.
    • -
    • Default: use the platform-dependent default value.
    • -
    - ]]>
    - True - False - Default - Default -
    -
    - - - - - 64000 - 64000 - - - - - - This attribute specifies the name by which the corresponding service is - identified in the rest of the configuration file.

    -

    In the OpenSplice DDS configuration file, services and their settings - are identified by a name. When the Domain Service starts a particular - service, its corresponding name is passed. The service in question uses - this name in order to find its own configuration settings in the rest of - the configuration file. The name specified here must match the name - attribute of the main element of the corresponding service.

    - ]]>
    - 0 - durability -
    - - This attribute indicates whether the service is actually started or not.

    -

    Toggling a service between enabled and disabled is a quick alternative for - commenting out the corresponding lines in the configuration file.

    - ]]>
    - 0 - true -
    - - This element specifies the command to be executed in order to start the service.

    -

    OpenSplice DDS comes with a set of pluggable services. The Command element specifies - the name of the actual service executable (possibly including its path, but always - including its extension, e.g. ‘.exe’ on the Windows platform). When no path is included, - the Domain Service will search the PATH environment variable for the corresponding - executable. Once located, it will be started as a separate process.

    - ]]>
    - 0 - durability -
    - - CAUTION: GHS INTEGRITY ONLY OPTION!! This element maps directly into the integrate file - for the address space for this service. Consult the GHS Integrate documentation for - further information on this setting. Valid values are decimal or hexadecimal numbers and - they express the number of bytes.

    - ]]>
    - 0 - 0 -
    - - CAUTION: This element should only be used on the GHS Integrity platform!!

    -

    This element maps directly into the integrate file - for the address space for this service. Consult the GHS Integrate documentation for - further information on this setting. Valid values are decimal or hexadecimal numbers and - they express the number of bytes.

    - ]]>
    - 0 - 0 -
    - - CAUTION: GHS INTEGRITY ONLY OPTION!! This element maps directly into the integrate file - for the address space for this service. Consult the GHS Integrate documentation for - further information on this setting. Valid values are decimal or hexadecimal numbers and - they express the number of bytes.

    - ]]>
    - 0 - 0 -
    - - This element allows overriding of the default URI (specified in the - OSPL_URI environment variable, or passed explicitly as command- - line parameter to the ospl executable) with the configuration - resource specified here.

    -

    When the Domain Service is started by the ospl executbale, - by default it passes on its own URI to the services that it starts. - This is valid when the configuration of the service is located in the - same resource file as the configuration of the Domain Service itself. - (This is a convenient situation in most cases).

    -

    If the configuration of the current service is located in a separate - resource file, a separate URI identifying that particular resource file - must be specified in this element.

    - ]]>
    - 0 - ${OSPL_URI} -
    - - - - - 0 - - - Relative - Absolute - Relative - - - - - Timeshare - Realtime - Default - Default - - - - This element specifies the locking policy of the current Service - process, indicating whether pages should be locked in physical memory - or not.

    -

    On platforms with a virtual memory architecture, the operating - system decides when to swap memory pages from internal memory to disk. - This results in execution delays for the corresponding code because it - has to be paged back into main memory. The element Locking can be - used to avoid such swapping for the current Service. The user needs the - appropriate privileges from the underlying operating system to be able - to use this option.

    - ]]>
    - false -
    - - This element specifies what action to take at the moment that the service seems - to have become non-responsive.

    -

    Each service reports its liveliness regularly using the shared administration. - If the service fails to do so, the Domain service will assume the service has - become non-responsive. This element determines what action is taken - by the DomainService in case this happens.

    -

    The following actions are available:

    -
      -
    • skip: Ignore the non-responsiveness and continue.
    • -
    • kill: End the service process by force.
    • -
    • restart: End the service process by force and restart it.
    • -
    • systemhalt: End all OpenSplice services including the Domain service - (for the current DDS Domain on this computing node).
    • -
    - ]]>
    - kill - restart - skip - systemhalt - skip -
    -
    - - - - - true - - - - - - - true - - - - - - - - - true - - - - durability - reader - writer - networking - reader - - - - - - - - - - my_reporter.so - 0 - - - - - - - my_reporter.so - 0 - - - - - - - my_reporter.so - 0 - - - - - - - my_reporter.so - 0 - - - - - - - - * - 0 - - - -
  • none
  • -
  • read
  • -
  • write
  • -
  • readwrite
  • - - ]]>
    - none - read - write - readwrite - readwrite -
    -
    - - - - - - * - 0 - - - -
  • none
  • -
  • read
  • -
  • write
  • -
  • readwrite
  • - - ]]>
    - none - read - write - readwrite - readwrite -
    -
    -
    - - - - OpenSplice/Daemon. Within this root element, the Splice Daemon will - look for several child-elements. Each of these child elements is - listed and explained. - ]]> - - This element specifies the locking policy for the Splice Deamon - process, indicating whether its pages should be locked in physical - memory or not.

    - On platforms with a virtual memory architecture, the operating - system decides when to swap memory pages from internal memory to disk. - This results in execution delays for the corresponding code because it - has to be paged back into main memory. The element Locking can be - used to avoid such swapping for the Splice Deamon. The user needs the - appropriate privileges from the underlying operating system to be able - to use this option. - ]]>
    - false -
    - - This element specifies the behaviour of the KernelManager.

    -

    The kernel manager actively monitors the OpenSplice kernel - and executes administrative tasks:

    -
      -
    • check topic consistency
    • -
    • determine liveliness status of readers and writers
    • -
    • notify readers and writers on incompatible QoS
    • -
    - ]]>
    - - - - - 0 - - - Relative - Absolute - Relative - - - - - Timeshare - Realtime - Default - Default - - -
    - - This element specifies the behaviour of the GarbageCollector.

    -

    The garbage collector is a safety mechanism and is responsible for - reclaiming resources in case an application or remote node does not - terminate properly.

    - ]]>
    - - - - - 0 - - - Relative - Absolute - Relative - - - - - Timeshare - Realtime - Default - Default - - -
    - - - - - - - 0 - - - Relative - Absolute - Relative - - - - - Timeshare - Realtime - Default - Default - - - -
    - - - - OpenSplice/Domain/Service[@name] in the configuration of - the DomainService. - ]]> - 0 - durability - - - - - - - - 0 - - - Relative - Absolute - Relative - - - - - Timeshare - Realtime - Default - Default - - - - - Applications need to be able to gain access to historical data in a system. - When the local DDS service gets connected to a remote DDS service by means - of the Networking service, (parts of) the historical data might not be - consistent between the local and remote Durability services. The Durability - service needs to be able to detect the other available Durability services - and exchange historical data with them to keep and/or restore consistency - in historical data between them.

    - -

    The Network element provides handles to fine-tune the behavior of the - communication between Durability services on different computing nodes on - network level. These settings only apply when the Networking service is active.

    - ]]>
    - - This attribute controls the latency_budget QoS setting - that is used by the Durability service for its communication - with other Durability services.

    -

    It specfies the maximum acceptable delay (in seconds) from - the time the data is written until the data is insterted in the - cache of the receiving Durability service(s) and the receiver is - notified of the fact. The default value is zero, indicating the - delay should be minimized.

    - ]]>
    - 0.0 - 0.0 -
    - - This attribute controls the transport priority QoS - setting that is used by the Durability service for its - communication with other Durability services.

    -

    It indicates the importance of the communication of the - Durability service with other Durability services in the - system. The transport priority specified here will be - interpreted by the Networking service and should be - used to differentiate the priority between communication - of user applications and communication of the Durability - service.

    - ]]>
    - 0 - 0 -
    - - During startup and at runtime, the network topology can change - dynamically. This happens when OpenSplice services are started/stopped - or when a network cable is plugged in/out. The Durability services - need to keep data consistency in that environment. To detect newly - joining services as well as detecting nodes that are leaving, the - Durability service uses a hearbeat mechanism. This element allows - fine-tuning of this mechanism.

    - -

    Please note this heartbeat mechanism is similar to but not the - same as the service liveliness assertion.

    - ]]>
    - - DurabilityService/Network[@latency_budget]. - ]]> - 0.0 - 0.0 - - - DurabilityService/Network[@transport_priorrity]. - ]]> - 0 - 0 - - - - - - 0 - - - Relative - Absolute - Relative - - - - - Timeshare - Realtime - Default - Default - - - - This element specifies the maximum amount of time in - which the Durability service expects a new heartbeat of - other Durability services. This is obviously also the - same amount of time in which the Durability service must - send a heartbeat itself.

    -

    Increasing this value will lead to less networking - traffic and overhead but also to less responsiveness with - respect to the liveliness of a Durability service. Change - this value according to the need of your system with respect - to these aspects.

    - ]]>
    - 10.0 - 0.2 - 20.0 - - In case of a (temporary) high CPU load, the scheduling - behaviour of the operating system might affect the - capability of the Durability service to send its - heartbeat 'on time'. This attribute introduces some - elasticity in this mechanism by making the service - send its heartbeat more often then required by the - ExpiryTime.

    -

    The Durability service will report its liveliness - every ExpiryTime multiplied by this - update_factor.

    - ]]>
    - 0.1 - 0.9 - 0.2 -
    -
    -
    - - To be able to ensure data consistency of historical data, the - Durability service needs to know which other Durability services - are available in the system. The value of this element determines - the amount of time the Durability service takes at startup to get - acquinted with all other Durability services in the system.

    -

    Increasing the value will increase the startup time of the - Durability service, but is required in larger domains where a lot - of network bandwidth is used.

    - ]]>
    - 3.0 - 0.1 - 60.0 -
    - - - - - 0.0 - 0.0 - - - DurabilityService/Network[@transport_priorrity] for the - alignment of data only. - ]]> - 0 - 0 - - - - true - - - - - - 0 - - - Relative - Absolute - Relative - - - - - Timeshare - Realtime - Default - Default - - - - - - - 0 - - - Relative - Absolute - Relative - - - - - Timeshare - Realtime - Default - Default - - - - When the Durability service detects an inconsistency with - another Durability service, it requests that service to align - it. The service that receives this request will restore - consistency by sending the requested information. In some - cases, the Durability service may receive alignment requests - from multiple Durability services for the same information - around the same moment in time. To reduce the processing and - networking load in that case, the Durability service is - capable of aligning multiple Durability services concurrently.

    -

    The RequestCombinePeriod has 2 child-elements: a setting - that is used when the current Durability Service is not yet - aligned with all others (Initial) and one for the period - after that (Operational). These values specify the maximum - amount of time the Durability service is allowed to wait with - alignment after an alignment request has been received.

    -

    Increasing the value will increase the amount of time in - which the Durability service restores from inconsistencies, - but will decrease the processing and network load in - case multiple Durability services need to resolve the - same data around the same time. Increasing the value - is useful in case OpenSplice is started at the same time - with more than two computing nodes.

    - ]]>
    - - - 0.5 - 0.01 - 5.0 - - - - 0.01 - 0.01 - 5.0 - -
    - - - - - - 0 - partition - - - - 0 - 0 - - - - 0.0 - 0.0 - - - - 0 - 0 - - - -
    - - - - DurabilityService/Network/WaitForAttachment/ServiceName - elements are available before sending any data. An error is - logged if one of the services still is unavailable afterwards. - The service will continue after that, but this indicates - a problem in the configuration and the service might not - function correctly anymore. - ]]> - 1 - 1000 - 200 - - - - networking - 0 - - - -
    - - Durable data is divided in transient and persistent data. Transient - data must stay available for as long as at least one Durability - service is available in the system. For persistent data it is - the same, but that type of data must also outlive the downtime - of the system. The Durability service stores the persistent data - on permanent storage to realize this. This element can be used - to fine-tune the behaviour of the Durability service concerning - the persistent properties of the data.

    -

    Note these elements are only available as part of the DDS - persistence profile of OpenSplice.

    - ]]>
    - - - 0 - /tmp/pstore - - - - 60.0 - 5.0 - 20.0 - - - - 10.0 - 0.5 - 2.0 - - - - XML - XML - - - - 1000000000 - 0 - 0 - - - - - - 0 - - - Relative - Absolute - Relative - - - - - Timeshare - Realtime - Default - Default - - - -
    - - - - - - This element specifies how the durability service - manages the data within the NameSpace. The original - durability of the data (determined by the DataWriter - that wrote it) can be 'weakened' (Persistent > Transient - > Transient_local). This is useful to improve - resource usage of the durability service in the - situation where resource usage is more important - then fault-tolerance. This parameter cannot be used - to increase the original durability of samples.

    -

    In case the value of this parameter is larger then - the value a sample was published with, the sample will - be handled as specified in the DataWriter durability - QoS.

    -
      -
    • Persistent: Data is maximally handled as persistent. - In practice this means a sample is - handled exactly as specified in the - DataWriter durability QoS that wrote - it.
    • -
    • Transient: A sample is maximally handled as if it - were published with a transient - durability QoS.
    • -
    • Transient_Local: Data is maximally handled as if it - were published with a - transient_local durability QoS.
    • -
    • Durable: Convenience value that behaves equal to - Persistent.
    • -
    - ]]>
    - Durable - Durable - Persistent - Transient - Transient_Local -
    - - - 0 - myNameSpace - - - This element determines how the durability service manages - the data that matches the namespace. Scalability of durable - data is an issue in large systems. Keeping all historical data - on each node may not be feasible. Often nodes are interested - in a small part of the total system data. They are driven - by both performance (boot time, memory usage, network load, - CPU load) and fault tolerance (the need for replicates).

    -

    The durability service provides the following - mechanisms to request and provide historical data: -

      -
    • Initial_And_Aligner: The durability service requests - historical data at startup and caches it locally. Historical - data will be available relatively fast for new local data - readers and the system is more fault-tolerant. However, - caching of historical data requires a relatively large - amount of resources and a long boot time. The Durability - service will also provide historical data to other - Durability services on a request basis.
    • -
    • Initial: The same as Initial_And_Aligner, except the - Durability service will not provide other Durability services - with historical data. This is useful when applications - on the current node need all the processing and network - bandwidth and dynamic interference is not allowed.
    • -
    • Lazy: The Durability service caches historical data - after local application interest arises for the first - time and a remote Durability service aligns the first - data reader. Historical data is available relatively slow - for the first data reader, but for every new data reader - it is relatively fast. The caching resources are only used - when local interest in the data arises, so it only requires - resources if there is actual local interest. However, - this method provides no fault-tolerance for the domain, - because the local Durability service is only partly a replica - and is not able to provide historical data to remote - Durability service and/or remote data readers.
    • -
    • On_Request: The Durability service will not cache - historical data, but will align each separate DataReader - on a request basis (in the situation where it calls - wait_for_historical_data). Each new DataReader that - wants historical data therefore leads to a new alignment - action. This is a good setting to limit the amount of - resources used on the node, but will potentially lead to - more network traffic. This method provides no - fault-tolerance for the domain.
    • -

    - ]]>
    - Initial_And_Aligner - Initial - Initial_And_Aligner - Lazy - On_Request -
    - - -
  • ignore - No alignment will take place. This is also - the default value if not specified.
  • -
  • merge - Existing data will remain and data from others - will be aligned.
  • -
  • reset - Existing data is removed.
  • -
  • replace - Existing data is removed and data from - others will be aligned.
  • - ]]>
    - ignore - merge - reset - replace - ignore -
    - - - 0 - * - -
    -
    - - - - - 64 - durabilityPublisher - - - - 64 - durabilitySubscriber - - - - 64 - durabilityPartition - - - - - - FALSE - - - - 0 - durability.log - - - - - - true - - true - - - - SEVERE - WARNING - INFO - CONFIG - FINE - FINER - FINEST - INFO - - -
    - - - - - //OpenSplice/Domain/Service[@name] in the configuration of - the DomainService. - ]]> - 0 - networking - - - - - - - - 0 - - - Relative - Absolute - Relative - - - - - Timeshare - Realtime - Default - Default - - - - - - - - 15 - first available - - - - - -
  • false - Specifies that the network service must NOT - resume communication. - (default). -
  • true - Specifies that the network service must - resume communication. - - ]]> - false - - - - - The OpenSplice Networking service is capable of leveraging - the network's multicast and routing capabilities. If some a-priori - knowledge about the participating - nodes and their topic and partition interest is available, then the - networking services in the system can be explicitly instructed to use - specific unicast or multicast addresses for its networking traffic. - This is done by means of so-called network partitions

    -

    A network partition is defined by one or more unicast, multicast - of broadcast IP addresses. Any networking service that is started - will read the network partition settings and, if applicable, join - the required multicast groups. For every sample distributed by the - networking service, both its partition and topic name will be - inspected. In combination with a set of network partition mapping rules, - the service will determine to which network partition the sample is - written. The mapping rules are configurable as well.

    -

    Using - networking configuration, nodes can be disconnected from any - networking partition. If a node is connected via a low speed - interface, it is not capable of receiving high volume data. If - the DCPS partitioning is designed carefully, high volume data is - published into a specific partition, which on its turn is mapped - onto a specific networking partition, which on its turn is only - connected to those nodes that are capable of handling high volume data.

    - ]]>
    - - - - - broadcast - 0 - - - - - - - - - networkPartition - 0 - - - - broadcast - 0 - - - A node can choose to be not connected to a networking - partition by setting the Connected attribute.

    -

    If a node is connected to a networking partition, - it will join the corresponding multicast group and - it will receive data distributed over the partition. - If it is not connected, data distributed over the - partition will not reach the node but will be - filtered by the networking interface or multicast - enabled switches.

    - ]]>
    - true -
    - - -
  • false - No compression is applied. This is - also the default value if not specified.
  • -
  • true - Compression is applicable
  • - - ]]>
    - false -
    -
    -
    - - - - - - - *.* - 0 - - - - - - - This element specifies a mapping between a network partition - and a partition-topic combination.

    -

    In order to give networking partitions a meaning in the context - of DCPS, mappings from DCPS partitions and topics onto networking - partitions should be defined. Networking allows for a set of - partition mappings to be defined.

    - ]]>
    - - - networkPartition - 0 - - - NetworkPartition element. - ]]> - *.* - 0 - -
    -
    -
    - - This element is used to group a set of Channels.

    -

    The set of channels define the behaviour of the 'network' concerning - aspects as priority, reliability and latency budget. By configuring - a set of channels, the Networking service is able to function as a - 'scheduler' for the network bandwidth. It achieves this by using the - application-defined DDS QoS policies of the data to select the most - appropriate channel to send the data.

    - ]]>
    - - This element specifies all properties of an individual Channel.

    -

    The Networking service will make sure messages with a higher - priority precede messages with a lower priority and it uses the - latency budget to assemble multiple messages into one UDP packet - where possible, to optimize the bandwidth usage. Of course, its - performance depends heavily on the compatbility of the configured - channels with the used DDS QoS policies of the applications.

    - ]]>
    - - - 0 - aChannel - - - If this attribute is set to true, the channel sends all messages reliably. - If not, data is sent only once (fire-and-forget).

    -

    The specific channel a message is written into depends on the attached - quality of service. Once a message has arrived in a channel, it will be - transported with the quality of service attached to the channel. If the - reliable attribute happens to be set to true, the message will be sent - over the network using a reliability protocol.

    - ]]>
    - false -
    - - This attribute indicates whether the channel is selected as the - default channel in case no channel offers the quality of service - requested by a message.

    -

    The networking channels should be configured corresponding - to the quality of service settings that are expected to be - requested by the applications. It might happen, however, - that none of the available channels meets the requested - quality of service for a specific message. In that case, - the message will be written into the default channel.

    -

    Note that only one channel is allowed to have this attribute - set to true

    - ]]>
    - false -
    - - - false - - - - 0 - - - - 1 - 65535 - 3367 - - - FragmentSize. These fragments - are sent as datagrams to the UDP stack. OS-settings determine - the maximum datagram size. - ]]> - 200 - 65535 - 1300 - - - The resolution indicates the number of milliseconds that - this channel sleeps between two consecutive resend or - packing actions. Latency budget values are truncated to a - multiple of "Resolution" milliseconds.

    -

    It is considered good practice to specify the ThrottleTreshold consistently throughout - the system.

    - ]]>
    - 1 - 10 -
    - - For reliable channels the receiving side needs to keep the sending - side informed about the received data and the received control messages.

    -

    This is done by means of an "AdminQueue". This setting determines the - size of this queue, and it must be greater than the maximum number of reliable - messages send or received during each "Resolution" milliseconds.

    - ]]>
    - 400 - 4000 -
    - - - - - false - - - - 1 - 400 - - - - 1024 - 200000 - - - - 128 - 10240 - - - This is the number of unprocessed network fragments that a node will store before it will inform - the other nodes in the network that it has trouble processing the incoming data. Those other nodes - can use this information to adjust their throttle values, effectively reducing the amount of incoming - data in case of a temporary overflow, and increasing again when the node is able to catch up.

    -

    It is considered good practice to specify the ThrottleTreshold consistently throughout - the system.

    - ]]>
    - 2 - 50 -
    - - - 1 - 100 - - - - 2 - 3 - - - - 0 - 255 - 0 - - - - True - False - True - - - - 0 - 255 - 0 - - - - - - 0 - - Priority is a relative or absolute priority. - ]]> - Relative - Absolute - Relative - - - - - Timeshare - Realtime - Default - Default - - -
    - - - - - false - - - - 1024 - 1000000 - - - - - - 0 - - Priority is a relative or absolute priority. - ]]> - Relative - Absolute - Relative - - - - - Timeshare - Realtime - Default - Default - - - - - 500 - 5000 - - - - - - true - - - - - 100 - 1000 - - -
    -
    - - - - - true - - - - 1 - 65536 - 3369 - - - - - - 0 - 255 - 0 - - - - True - False - True - - - - 0 - 255 - 0 - - - - false - - - - - - 0 - - Priority is a relative or absolute priority. - ]]> - Relative - Absolute - Relative - - - - - Timeshare - Realtime - Default - Default - - - - - 100 - 333 - - - - 0.2 - 1.0 - 0.9 - - - - 1 - 3 - - - - - - - - false - - - - 0 - - Priority is a relative or absolute priority. - ]]> - Relative - Absolute - Relative - - - - - Timeshare - Realtime - Default - Default - - - - - 1 - 6 - - - - 1 - 1000000 - - - - - - - - - 0 - networking.log - - - - - - true - - true - - - - - - 0 - 6 - 0 - - - Configuration category. - This includes the processing of all NetworkService parameters in the config file. - Level 0 indicates no tracing, level 6 indicates the most detailed level - of tracing. - ]]> - 0 - 6 - 0 - - - Construction category. - This includes the creation of all internal processing entities. - Level 0 indicates no tracing, level 6 indicates the most detailed level - of tracing. - ]]> - 0 - 6 - 0 - - - Destruction category. - This includes the destruction of all internal processing entities when the - NetworkService terminates. Level 0 indicates no tracing, level 6 indicates the - most detailed level of tracing. - ]]> - 0 - 6 - 0 - - - Mainloop category. - This includes information about each of the threads spawned by the NetworkService. - Level 0 indicates no tracing, level 6 indicates the most detailed level - of tracing. - ]]> - 0 - 6 - 0 - - - Groups category. - This includes the management of local groups (partition-topic combinations). - Level 0 indicates no tracing, level 6 indicates the most detailed level - of tracing. - ]]> - 0 - 6 - 0 - - - Send category. - This includes information about outgoing data. - Level 0 indicates no tracing, level 6 indicates the most detailed level - of tracing. - ]]> - 0 - 6 - 0 - - - Receive category. - This includes information about incoming data. - Level 0 indicates no tracing, level 6 indicates the most detailed level - of tracing. - ]]> - 0 - 6 - 0 - - - Test category. - This is a reserved category used for testing purposes. - Level 0 indicates no tracing, level 6 indicates the most detailed level - of tracing. - ]]> - 0 - 6 - 0 - - - Discovery category. - This includes all activity related to the discovery channel. - Level 0 indicates no tracing, level 6 indicates the most detailed level - of tracing. - ]]> - 0 - 6 - 0 - - - - - - - - - - - 0 - ddsi - - - - - - 15 - first available - - - - - - - - - 0 - channel1 - - - - 0 - 1000 - 0 - - - - true - - - - false - - - - 100 - 10000 - 500 - - - - 100 - 10000 - 1200 - - - - 0 - 65535 - 53370 - - - - - - - - true - - - - 0 - 65535 - 7400 - - - - 100 - 10000 - 1200 - - - - - - - false - - - - 0 - ddsi-tracing-output.log - - - - - - - - - 0 - 239.255.0.1 - - - - - - - - - name attribute, which must match the one specified - under the OpenSplice/Domain/Service[@name] in the configuration of - the Domain Service. - ]]> - cmsoap - 0 - - - - - - - - 0 - - - Relative - Absolute - Relative - - - - - Timeshare - Realtime - Default - Default - - - - - - - - 1 - 65535 - 8000 - - - - 0 - 5 - - - - 0 - 1 - 2 - 3 - 4 - 5 - 0 - - - - - - - 1 - 2 - - - - 1 - 2 - - - - 10.0 - 15.0 - - - - - - 0 - - Priority is a relative - or absolute priority. - ]]> - Relative - Absolute - Relative - - - - - Timeshare - Realtime - Default - Default - - - - - - - - - - 0 - - Priority is a relative - or absolute priority. - ]]> - Relative - Absolute - Relative - - - - - Timeshare - Realtime - Default - Default - - - - - - - - - - 0 - - Priority is a relative - or absolute priority. - ]]> - Relative - Absolute - Relative - - - - - Timeshare - Realtime - Default - Default - - - - - - - OpenSplice/DbmsConnectService. Within - this root element, the DbmsConnect Service will look for several child-elements. - Each of these is listed and explained. - ]]> - - OpenSplice/Domain/Service[@name] in the configuration of - the DomainService. - ]]> - 0 - dbmsconnect - - - - - This attribute specifies the default replication mode for - all NameSpaces in the DdsToDbms element.

    -

    When replicating databases through DDS, the NameSpace - elements in the DbmsToDds and DdsToDbms elements - map a Table and Topic circularly. To prevent data-modifications - from continuously cascading, modifications made by the - DBMSConnect service itself should not trigger new updates - in the DBMS nor in the DDS.

    -

    In replication mode, the DBMS-connect service ignores - samples that were published by itself. (Currently that means - that everything that is published on the same node as the - DBMSConnect Service is considered to be of DBMSConnect - origin and therefore ignored). That way, replication of - changes that were copied from Dbms to DDS back into Dbms - is avoided.

    -

    WARNING: This setting does not avoid replication - of changes that were copied from DDS to Dbms back into DDS. - For that purpose, the replication_user attribute of the - DbmsToDds or DbmsToDds/NameSpace elements should - be set appropriately as well!

    - ]]>
    - FALSE -
    - - NameSpace element has to be present in - a DdsToDbms element. - ]]> - - - 0 - (nameless) - - - The service dynamically loads an ODBC library at runtime. This attribute - specifies the name of the ODBC library to be loaded. Platform specific - pre- and postfixes and extensions are automatically added.

    -

    If this attribute is not provided, the service will attempt to load the - generic ODBC library. The resulting behaviour is dependent on the platform - on which the DbmsConnect Service is running.

    - ]]>
    - 0 - -
    - - This attribute specifies an expression that represents one or more DDS - partitions. It is allowed to use wildcards in the expression: a '*' - represents any sequence of characters and a '?' represents one - single character.

    -

    This expression is used to specify the DDS partition(s) from which - DDS samples must be 'bridged' to the DBMS domain.

    - ]]>
    - 0 - * -
    - - This attribute specifies an expression that represents one or more DDS - topic names. It is allowed to use wildcards in the expression: a '*' - represents any sequence of characters and a '?' represents one - single character.

    -

    This expression is used to specify the topics from which DDS - samples must be ‘bridged’ to the DBMS domain. For every matching - topic encountered in one or more of the specified partitions, it - creates a separate table in the DBMS. The table name will match that - of the topic, unless specified otherwise in the table attribute - of a Mapping element.

    - ]]>
    - 0 - * -
    - - - 0.0 - 0.0 - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - This attribute specifies the replication mode for the - current NameSpace element. If not specified, the value - will be inherited from the replication_mode of the parent - DdsToDbms element, which if not explicitly specified - defaults to false

    -

    When replicating databases through DDS, the NameSpace - elements in the DbmsToDds and DdsToDbms elements - map a Table and Topic circularly. To prevent data-modifications - from continuously cascading, modifications made by the - DBMSConnect service itself should not trigger new updates - in the DBMS.

    -

    In replication mode, the DBMS-connect service ignores - samples that were published by itself. (Currently that means - that everything that is published on the same node as the - DBMSConnect Service is considered to be of DBMSConnect - origin and therefore ignored). That way, replication of - changes that were copied from Dbms to DDS back into Dbms - is avoided.

    -

    WARNING: This setting does not avoid replication - of changes that were copied from DDS to Dbms back into DDS. - For that purpose, the replication_user attribute of the - DbmsToDds or DbmsToDds/NameSpace elements should - be set appropriately as well!

    - ]]>
    - FALSE -
    - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - -
    -
    - - - - - - true - - - This attribute specifies the default setting of the event table policy for all NameSpace elements in the current DbmsToDds element.

    -

    An event table (sometimes referred to as ‘change table’ or ‘shadow table’) is a support-table that is slaved to an application-table, adding some status flags that are under the control of a trigger mechanism that responds to creation/modification/ deletion events in the application-table.

    -

    The following policies are currently supported:

    -
      -
    • FULL: (default) An 'event table' will always be created when the service connects, and will always be deleted when the service disconnects. In this mode, the service will replace the table if it already exists.
    • -
    • LAZY: An 'event table' will only be created if it is not available when the service connects, and it will not be deleted when the service disconnects.
    -
  • NONE: An 'event table' will neither be created nor deleted by the service. For each specified NameSpace, the service will poll for the existence of a consistent table with a frequency specified in the coresponding update_frequency attribute. It will start using the table as soon as it is available. With this policy set, no initial data will be published regardless of the value of the applicable publish_initial_data attribute. - - ]]> - FULL - LAZY - NONE - FULL - - - This attribute specifies the default trigger policy for all NameSpace elements in the current DbmsToDds element.

    -

    Triggers are used to to update the event table in case of creation/modification/ deletion events on the application-table.

    -

    The following policies are currently supported:

    -
      -
    • FULL: (default) Triggers will always be created when the service connects, and will always be deleted when the service disconnects. In this mode, the service will replace the triggers if they already exists.
    • -
    • LAZY: Triggers will only be created if they are not available when the service connects, and will not be deleted when the service disconnects.
    -
  • NONE: Triggers will neither be created nor deleted by the service. This allows you to build your own custom triggering mechanism. - - ]]> - FULL - LAZY - NONE - FULL - - - This attribute specifies the default replication user for - all NameSpace elements in the current DdsToDbms - element.

    -

    When replicating databases through DDS, the NameSpace - elements in the DbmsToDds and DdsToDbms elements - map a Table and Topic circularly. To prevent data-modifications - from continuously cascading, modifications made by the - service itself should not trigger new updates in the - DBMS nor in the DDS.

    -

    To distinguish between DBMS updates coming from an - application and DBMS updates coming from DDS, an extra - database user (the replication user) has to be introduced - that differs from the application users. That way, - replication of changes that were copied from DDS to Dbms - back into DDS is avoided. The replication_user attribute - specifies the user name of that replication user. An empty - string (default value) indicates that there is no separate - replication user.

    -

    WARNING: This setting does not avoid replication - of changes that were copied from Dbms to DDS back into Dbms. - For that purpose, the replication_mode attribute of - the DssToDbms or DssToDbms/NameSpace elements - should be set appropriately as well!

    - ]]>
    - 0 - -
    - - NameSpace - element has to be present in a DbmsToDds element. - ]]> - - - 0 - (nameless) - - - The service dynamically loads an ODBC library at runtime. This attribute - specifies the name of the ODBC library to be loaded. Platform specific - pre- and postfixes and extensions are automatically added.

    -

    If this attribute is not provided, the service will attempt to load the - generic ODBC library. The resulting behaviour is dependent on the platform - on which the DbmsConnect Service is running.

    - ]]>
    - 0 - -
    - - This attribute specifies an expression represents one or more DDS partitions. - It is allowed to use wildcards in the expression: a '*' represents any - sequence of characters and a '?' represents one single character.

    -

    This expression is used to specify the DDS partition(s) where DBMS records - will be written to as DDS samples by the service.

    - ]]>
    - 0 - * -
    - - This attribute specifies an expression that represents one or more DBMS - table names. It is allowed to use wildcards in the expression: a '*' - represents any sequence of characters and a '?' represents one single - character.

    -

    This expression is used to specify the tables from which DBMS data must - be 'bridged' to the DDS domain.

    - ]]>
    - 0 - * -
    - - - 0.0 - 2.0 - - - - 0 - - - - - 0 - - - - - 0 - - - - true - Mapping - elements in the current NameSpace element. If not specified, the value - will be inherited from the publish_initial_data of the parent - DbmsToDds element, which defaults to true. The value of this attribute - is ignored when the corresponding event_table_policy is set to NONE. - ]]> - - - true - Mapping elements - in the current NameSpace element with regard to the enforcement of - key equality between table and topic definitions. If true, key definitions - from the table and topic must match, otherwise key definitions may differ. - ]]> - - - This attribute specifies the default setting of the event table policy for all Mapping elements in the current NameSpace element. If not specified, the value will be inherited from the event_table_policy of the parent DbmsToDds element, which if not explicitly specified defaults to FULL.

    -

    An event table (sometimes referred to as ‘change table’ or ‘shadow table’) is a support-table that is slaved to an application-table, adding some status flags that are under the control of a trigger mechanism that responds to creation/modification/ deletion events in the application-table.

    -

    The following policies are currently supported:

    -
      -
    • FULL: An 'event table' will always be created when the service connects, and will always be deleted when the service disconnects. In this mode, the service will replace the table if it already exists.
    • -
    • LAZY: An 'event table' will only be created if it is not available when the service connects, and it will not be deleted when the service disconnects.
    -
  • NONE: An 'event table' will neither be created nor deleted by the service. For each specified NameSpace, the service will poll for the existence of a consistent table with a frequency specified in the coresponding update_frequency attribute. It will start using the table as soon as it is available. With this policy set, no initial data will be published regardless of the value of the applicable publish_initial_data attribute. - - ]]> - FULL - LAZY - NONE - FULL - - - This attribute specifies the default trigger policy for all Mapping elements in the current NameSpace element. If not specified, the value will be inherited from the trigger_policy of the parent DbmsToDds element, which if not explicitly specified defaults to FULL.

    -

    Triggers are used to to update the event table in case of creation/modification/ deletion events on the application-table.

    -

    The following policies are currently supported:

    -
      -
    • FULL: (default) Triggers will always be created when the service connects, and will always be deleted when the service disconnects. In this mode, the service will replace the triggers if they already exists.
    • -
    • LAZY: Triggers will only be created if they are not available when the service connects, and will not be deleted when the service disconnects.
    -
  • NONE: Triggers will neither be created nor deleted by the service. This allows you to build your own custom triggering mechanism. - - ]]> - FULL - LAZY - NONE - FULL - - - - 0 - - - - - 0 - - - - This attribute specifies the default replication user for - all Mapping elements in the current NameSpace - element. If not specified, the value will be inherited from - the replication_user of the parent DbmsToDds element, - which by default has no separate replication user specified.

    -

    When replicating databases through DDS, the NameSpace - elements in the DbmsToDds and DdsToDbms elements - map a Table and Topic circularly. To prevent data-modifications - from continuously cascading, modifications made by the - service itself should not trigger new updates in the - DBMS nor in the DDS.

    -

    To distinguish between DBMS updates coming from an - application and DBMS updates coming from DDS, an extra - database user (the replication user) has to be introduced - that differs from the application users. That way, - replication of changes that were copied from DDS to Dbms - back into DDS is avoided. The replication_user attribute - specifies the user name of that replication user. An empty - string (default value) indicates that there is no separate - replication user.

    -

    WARNING: This setting does not avoid replication - of changes that were copied from Dbms to DDS back into Dbms. - For that purpose, the replication_mode attribute of - the DssToDbms or DssToDbms/NameSpace elements - should be set appropriately as well!

    - ]]>
    - 0 - -
    - - - - - 0 - - - - - 0 - - - - - 0 - - - - true - Mapping element - from DBMS to DDS. If not specified, the value will be inherited from - the publish_initial_data of the parent NameSpace element, - which if not explicitly specified inherits from the publish_initial_data - of the parent DbmsToDds element, which defaults to true. - The value of this attribute is ignored when the corresponding - event_table_policy is set to NONE. - ]]> - - - true - force_key_equality of the parent - NameSpace element, which if not explicitly specified defaults to true. - ]]> - - - This attribute specifies the event table policy in the current Mapping element. If not specified, the value will be inherited from the event_table_policy of the parent NameSpace element, which if not explicitly specified inherits from the event_table_policy of the parent DbmsToDds element, which defaults to FULL.

    -

    An event table (sometimes referred to as ‘change table’ or ‘shadow table’) is a support-table that is slaved to an application-table, adding some status flags that are under the control of a trigger mechanism that responds to creation/modification/ deletion events in the application-table.

    -

    The following policies are currently supported:

    -
      -
    • FULL: An 'event table' will always be created when the service connects, and will always be deleted when the service disconnects. In this mode, the service will replace the table if it already exists.
    • -
    • LAZY: An 'event table' will only be created if it is not available when the service connects, and it will not be deleted when the service disconnects.
    -
  • NONE: An 'event table' will neither be created nor deleted by the service. For the specified table, the service will poll with a frequency specified in the coresponding update_frequency attribute of the parent NameSpace. It will start using the table as soon as it is available. With this policy set, no initial data will be published regardless of the value of the applicable publish_initial_data attribute. - - ]]> - FULL - LAZY - NONE - FULL - - - This attribute specifies the trigger policy for the current Mapping element. If not specified, the value will be inherited from the trigger_policy of the parent DbmsToDds element, which if not explicitly specified inherits from the trigger_policy of the parent DbmsToDds element, which defaults to FULL.

    -

    Triggers are used to to update the event table in case of creation/modification/ deletion events on the application-table.

    -

    The following policies are currently supported:

    -
      -
    • FULL: (default) Triggers will always be created when the service connects, and will always be deleted when the service disconnects. In this mode, the service will replace the triggers if they already exists.
    • -
    • LAZY: Triggers will only be created if they are not available when the service connects, and will not be deleted when the service disconnects.
    -
  • NONE: Triggers will neither be created nor deleted by the service. This allows you to build your own custom triggering mechanism. - - ]]> - FULL - LAZY - NONE - FULL - - - - - - - - - - - - 0 - dbmsconnect.log - - - - - - true - - true - - - - SEVERE - WARNING - INFO - CONFIG - FINE - FINER - FINEST - INFO - - - - - - OpenSplice/UserClockService. Within this root element, - the userclock will look for several child-elements. Each of these is listed - and explained. - ]]> - - name attribute must match the one specified under the - OpenSplice/Domain/Service[@name] in the configuration of the - Domain Service. - ]]> - userclock - 0 - - - - - 0 - - - - - - 0 - clockStart - - - - - - - 0 - clockStop - - - - - - This attribute specifies the name of the function that gets the - current time. This clockGet function should not have any parameters, - and needs to return the current time as an os_time type.

    -

    The definition of the os_time type can be found in os_time.h.

    - ]]>
    - 0 - clockGet -
    -
    -
    - diff --git a/src/tools/cm/config/code/splice_metaconfig_4.1.xsd b/src/tools/cm/config/code/splice_metaconfig_4.1.xsd deleted file mode 100644 index 0257018f0..000000000 --- a/src/tools/cm/config/code/splice_metaconfig_4.1.xsd +++ /dev/null @@ -1,252 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/tools/cm/config/code/splice_metaconfig_5.1.xml b/src/tools/cm/config/code/splice_metaconfig_5.1.xml deleted file mode 100644 index 8d0c081fb..000000000 --- a/src/tools/cm/config/code/splice_metaconfig_5.1.xml +++ /dev/null @@ -1,4541 +0,0 @@ - - - - - OpenSplice utilizes a shared-memory architecture where data is physically - present only once on any machine and where smart administration still - provides each subscriber with his own private view on this data. This - allows a subscribers data cache to be perceived as an individual - database that can content-filtered, queried, etc. (using the - content-subscription profile as supported by OpenSplice). This - shared-memory architecture results in an extremely low footprint, - excellent scalability and optimal performance when compared to - implementations where each reader/writer are communication-end points - each with its own storage (i.e. historical data both at reader and - writer) and where the data itself still has to be moved, even within - the same platform.

    - -

    Shared-memory is not only used to interconnect all applications that - reside within one computing node, but also for a configurable and - extensible set of services. These services provide pluggable functionality - such as networking (providing QoS-driven real-time networking based - on multiple reliable multicast 'channels'), durability (providing - fault-tolerant storage for both real-time state data as well as - persistent settings) and a remote control & monitoring soap-service - (providing remote web-based access using the SOAP protocol from the - OpenSplice Tuner tool).

    - -

    Because of the pluggable architecture, the OpenSplice middleware - can be easily configured on the fly by specifying which services to - be used as well as specifying their optimal configuration for the - application domain (networking parameters, durability levels, etc.). - Typically, there are many nodes within a system.

    - -

    The OpenSplice middleware including its services can be configured - by means of easy maintainable XML-file(s).

    - ]]>
    -
    - - The Domain service is responsible for creating and initialising a shared nodal administration(in shared memory) - for a specific DDS Domain on a computing node. Without this administration, no other service or application is able - to participate in a DDS Domain.

    - -

    Once the administration has been initialised, the Domain service starts the set of pluggable services. The - lifecycle of the started services is under control of the Domain service, which means it will monitor the health - of all started services, take corrective actions if needed and stop the services when it is terminated.

    - -

    When a shutdown of the OpenSplice Domain service is requested, it will react by announcing the shutdown using the - shared administration. Applications will not be able to use DDS functionality anymore and services are requested - to terminate elegantly. Once this has succeeded, the Domain service will destroy the shared administration and - finally terminate itself.

    - ]]>
    - - - 0 - OpenSpliceV5 - - - - 0 - DefaultRole - - - - - This element specifies the interval in which services have to announce their liveliness.

    -

    Every OpenSplice service including the Domain service itself has to announce its liveliness regularly. - This allows corrective actions to be taken when one of the services becomes non-responsive. This - element specifies the required interval. Decreasing the interval decreases the time in which - non-responsiveness of a service is detected, but leads to more processing. Increasing it has - the opposite effect.

    - ]]>
    - 10.0 - 0.2 - - update_factor attribute - introduces some elasticity in this mechanism by making the services assert their liveliness more - often than required by the ExpiryTime. Services will report their liveliness every - ExpiryTime multiplied by this update_factor. - ]]> - 0.01 - 1.0 - 0.2 - -
    -
    - - - - - - - 0 - - - - Timeshare - Realtime - Default - Default - - - - - - 0.0 - 60.0 - 10.0 - - - This element specifies whether the OpenSplice Domain and other OpenSplice - services and applications are intended to be all deployed within the same - process. The default is to start each service in a seperate new process, - but it is an optimisation under certain conditions to be able to have all - OpenSplice components running in the same process.

    -

    Refer to the OpenSplice documentation for more details of how this deployment - style can optimise your system.

    -

    There are two modes of a "Single Process" style deployment:

    -

    Mode 1 : the user starts an application as a new process. In this - case, the create_participant operation will implicitly start the OpenSplice - daemon as a thread in the existing application process. The OpenSplice daemon - thread will then also implicitly start all services (and other applications) - specified in the configuration as threads within the same process.

    -

    Mode 2 : "ospl start" is ran as normal, in which case the OpenSplice - daemon will be started as a new process but will start all services (and other - applications) specified in the configuration as threads within the same process.

    -

    Please note that the Application elements specified under Domain will only - take effect for either mode when this SingleProcess attribute has a value - of true.

    -

    Please note also that the choice to use the SingleProcess deployment also - implies the use of heap memory for the OpenSplice database management rather - than shared memory that is typically used for this purpose. Heap memory is - limited by the Operating System, so the Database element under Domain does - not take effect when SingleProcess has a value of true.

    - ]]>
    - false -
    - - OpenSplice/Daemon. Within this root element, the Splice Daemon will - look for several child-elements. Each of these child elements is - listed and explained. - ]]> - - This element specifies the locking policy for the Splice Deamon - process, indicating whether its pages should be locked in physical - memory or not.

    - On platforms with a virtual memory architecture, the operating - system decides when to swap memory pages from internal memory to disk. - This results in execution delays for the corresponding code because it - has to be paged back into main memory. The element Locking can be - used to avoid such swapping for the Splice Deamon. The user needs the - appropriate privileges from the underlying operating system to be able - to use this option. - ]]>
    - false -
    - - This element specifies the behaviour of the KernelManager.

    -

    The kernel manager actively monitors the OpenSplice kernel - and executes administrative tasks:

    -
      -
    • check topic consistency
    • -
    • determine liveliness status of readers and writers
    • -
    • notify readers and writers on incompatible QoS
    • -
    - ]]>
    - - - - - 0 - - - Relative - Absolute - Relative - - - - - Timeshare - Realtime - Default - Default - - -
    - - This element specifies the behaviour of the GarbageCollector.

    -

    The garbage collector is a safety mechanism and is responsible for - reclaiming resources in case an application or remote node does not - terminate properly.

    - ]]>
    - - - - - 0 - - - Relative - Absolute - Relative - - - - - Timeshare - Realtime - Default - Default - - -
    - - - - - - - 0 - - - Relative - Absolute - Relative - - - - - Timeshare - Realtime - Default - Default - - - -
    - - - - - 0 - 10485760 - - - - 0 - 1048576 - - - This element specifies the start address where the - nodal shared administration is mapped into the virtual - memory for each process that attaches to the current Domain. - The possible values are platform dependent.

    -

    Change this value if the default address is already in - use, for example by another Domain Service or another - product.

    - ]]>
    - 0 - 0x40000000 - 0x80000000 - 0x40000000 -
    - - This element specifies the locking policy of the Database, indicating - whether to lock pages in physical memory or not.

    -

    With the virtual memory architecture, the operating system decides when - to swap memory pages from internal memory to disc. This results in execution - delays for the corresponding code because it has to be paged back into main - memory. The element Locking can be used to avoid such swapping for the - shared memory where the database resides. The user needs the appropriate - privileges from the underlying operating system to be able to use this option.

    -

    The possible values are:

    -
      -
    • True: lock the pages in memory.
    • -
    • False: don't lock the pages in memory.
    • -
    • Default: use the platform-dependent default value.
    • -
    - ]]>
    - True - False - Default - Default -
    -
    - - - - - 64000 - 64000 - - - - - - This attribute specifies the name by which the corresponding service is - identified in the rest of the configuration file.

    -

    In the OpenSplice DDS configuration file, services and their settings - are identified by a name. When the Domain Service starts a particular - service, its corresponding name is passed. The service in question uses - this name in order to find its own configuration settings in the rest of - the configuration file. The name specified here must match the name - attribute of the main element of the corresponding service.

    - ]]>
    - 0 - durability -
    - - This attribute indicates whether the service is actually started or not.

    -

    Toggling a service between enabled and disabled is a quick alternative for - commenting out the corresponding lines in the configuration file.

    - ]]>
    - 0 - true -
    - - This element specifies the command to be executed in order to start the service.

    -

    OpenSplice DDS comes with a set of pluggable services. The Command element specifies - the name of the actual service executable (possibly including its path, but always - including its extension, e.g. ‘.exe’ on the Windows platform). When no path is included, - the Domain Service will search the PATH environment variable for the corresponding - executable. Once located, it will be started as a separate process.

    - ]]>
    - 0 - durability -
    - - CAUTION: GHS INTEGRITY ONLY OPTION!! This element maps directly into the integrate file - for the address space for this service. Consult the GHS Integrate documentation for - further information on this setting. Valid values are decimal or hexadecimal numbers and - they express the number of bytes.

    - ]]>
    - 0 - 0 -
    - - CAUTION: This element should only be used on the GHS Integrity platform!!

    -

    This element maps directly into the integrate file - for the address space for this service. Consult the GHS Integrate documentation for - further information on this setting. Valid values are decimal or hexadecimal numbers and - they express the number of bytes.

    - ]]>
    - 0 - 0 -
    - - CAUTION: GHS INTEGRITY ONLY OPTION!! This element maps directly into the integrate file - for the address space for this service. Consult the GHS Integrate documentation for - further information on this setting. Valid values are decimal or hexadecimal numbers and - they express the number of bytes.

    - ]]>
    - 0 - 0 -
    - - This element allows overriding of the default URI (specified in the - OSPL_URI environment variable, or passed explicitly as command- - line parameter to the ospl executable) with the configuration - resource specified here.

    -

    When the Domain Service is started by the ospl executbale, - by default it passes on its own URI to the services that it starts. - This is valid when the configuration of the service is located in the - same resource file as the configuration of the Domain Service itself. - (This is a convenient situation in most cases).

    -

    If the configuration of the current service is located in a separate - resource file, a separate URI identifying that particular resource file - must be specified in this element.

    - ]]>
    - 0 - ${OSPL_URI} -
    - - - - - 0 - - - Relative - Absolute - Relative - - - - - Timeshare - Realtime - Default - Default - - - - This element specifies the locking policy of the current Service - process, indicating whether pages should be locked in physical memory - or not.

    -

    On platforms with a virtual memory architecture, the operating - system decides when to swap memory pages from internal memory to disk. - This results in execution delays for the corresponding code because it - has to be paged back into main memory. The element Locking can be - used to avoid such swapping for the current Service. The user needs the - appropriate privileges from the underlying operating system to be able - to use this option.

    - ]]>
    - false -
    - - This element specifies what action to take at the moment that the service seems - to have become non-responsive.

    -

    Each service reports its liveliness regularly using the shared administration. - If the service fails to do so, the Domain service will assume the service has - become non-responsive. This element determines what action is taken - by the DomainService in case this happens.

    -

    The following actions are available:

    -
      -
    • skip: Ignore the non-responsiveness and continue.
    • -
    • kill: End the service process by force.
    • -
    • restart: End the service process by force and restart it.
    • -
    • systemhalt: End all OpenSplice services including the Domain service - (for the current DDS Domain on this computing node).
    • -
    - ]]>
    - kill - restart - skip - systemhalt - skip -
    -
    - - The Domain service can deploy DDS applications by dynamically loading application - shared libraries and starting threads within the existing process.

    -

    Note that Applications only take affect when the SingleProcess configuration - is enabled

    - ]]>
    - - The name uniquely identifies the application

    - ]]>
    - 0 - application1 -
    - - This attribute indicates whether the application is actually started or not.

    -

    Toggling an applicatione between enabled and disabled is a quick alternative for - commenting out the corresponding lines in the configuration file.

    - ]]>
    - 0 - true -
    - - Command is the name of both the entry point function to invoked and the name of the - shared library to be dynamically loaded into the process. The signature of the entry - point function is the same as argc/argv usually seen with main.

    -

    For example, if Command is "HelloWorld", OpenSpliceDDS will attempt to load - "libHelloWorld.so" on Unix (or "HelloWorld.dll" on Windows) into the existing process - and then invoke the "HelloWorld" entry point to start that DDS application.

    -

    If the name of the shared library does not have the same name as the entry point the - user is able to override the name of the library by using the Application's Library attribute

    -

    The shared library is located by way of the current working directory, or LD_LIBRARY_PATH - for Unix systems, and PATH for Windows systems.

    - ]]>
    - 0 - application1 -
    - - This optional attribute allows the user to specify arguments to be passed to the - DDS application's entry point when it is invoked.

    -

    For example, if Command is "HelloWorld" and Arguments is "arg1 arg2", OpenSplice will - invoke the HelloWorld function with the argc = 3 and argv = {"HelloWorld", "arg1", "arg2"}

    - ]]>
    - 0 - -
    - - The optional Library attribute allows the user to override the name of the shared - library if it is different to the name of the entry point specified by Command.

    -

    The shared library is located by way of the current working directory, or LD_LIBRARY_PATH - for Unix systems, and PATH for Windows systems.

    - ]]>
    - 0 - application1 -
    -
    - - - - - true - - - - - - - true - - - - - - - - - true - - - - durability - reader - writer - networking - reader - - - - - - - - - - - 0 - - - - - - - - 0 - - - - - 0 - - - - - - - - 0 - - - - - - - - 0 - - - - - false - - - - - - - - - 1 - 5000 - - - - - - - 1 - 5000 - - - - - - - 1 - 5000 - - - - - - - - * - 0 - - - -
  • none
  • -
  • read
  • -
  • write
  • -
  • readwrite
  • - - ]]>
    - none - read - write - readwrite - readwrite -
    -
    - - - - - * - 0 - - - -
  • none
  • -
  • read
  • -
  • write
  • -
  • readwrite
  • - - ]]>
    - none - read - write - readwrite - readwrite -
    -
    -
    - - - - - OpenSplice/Domain/Service[@name] in the configuration of - the DomainService. - ]]> - 0 - durability - - - - - - - - 0 - - - Relative - Absolute - Relative - - - - - Timeshare - Realtime - Default - Default - - - - - Applications need to be able to gain access to historical data in a system. - When the local DDS service gets connected to a remote DDS service by means - of the Networking service, (parts of) the historical data might not be - consistent between the local and remote Durability services. The Durability - service needs to be able to detect the other available Durability services - and exchange historical data with them to keep and/or restore consistency - in historical data between them.

    - -

    The Network element provides handles to fine-tune the behavior of the - communication between Durability services on different computing nodes on - network level. These settings only apply when the Networking service is active.

    - ]]>
    - - This attribute controls the latency_budget QoS setting - that is used by the Durability service for its communication - with other Durability services.

    -

    It specfies the maximum acceptable delay (in seconds) from - the time the data is written until the data is insterted in the - cache of the receiving Durability service(s) and the receiver is - notified of the fact. The default value is zero, indicating the - delay should be minimized.

    - ]]>
    - 0.0 - 0.0 -
    - - This attribute controls the transport priority QoS - setting that is used by the Durability service for its - communication with other Durability services.

    -

    It indicates the importance of the communication of the - Durability service with other Durability services in the - system. The transport priority specified here will be - interpreted by the Networking service and should be - used to differentiate the priority between communication - of user applications and communication of the Durability - service.

    - ]]>
    - 0 - 0 -
    - - During startup and at runtime, the network topology can change - dynamically. This happens when OpenSplice services are started/stopped - or when a network cable is plugged in/out. The Durability services - need to keep data consistency in that environment. To detect newly - joining services as well as detecting nodes that are leaving, the - Durability service uses a hearbeat mechanism. This element allows - fine-tuning of this mechanism.

    - -

    Please note this heartbeat mechanism is similar to but not the - same as the service liveliness assertion.

    - ]]>
    - - DurabilityService/Network[@latency_budget]. - ]]> - 0.0 - 0.0 - - - DurabilityService/Network[@transport_priorrity]. - ]]> - 0 - 0 - - - - - - 0 - - - Relative - Absolute - Relative - - - - - Timeshare - Realtime - Default - Default - - - - This element specifies the maximum amount of time in - which the Durability service expects a new heartbeat of - other Durability services. This is obviously also the - same amount of time in which the Durability service must - send a heartbeat itself.

    -

    Increasing this value will lead to less networking - traffic and overhead but also to less responsiveness with - respect to the liveliness of a Durability service. Change - this value according to the need of your system with respect - to these aspects.

    - ]]>
    - 10.0 - 0.2 - - In case of a (temporary) high CPU load, the scheduling - behaviour of the operating system might affect the - capability of the Durability service to send its - heartbeat 'on time'. This attribute introduces some - elasticity in this mechanism by making the service - send its heartbeat more often then required by the - ExpiryTime.

    -

    The Durability service will report its liveliness - every ExpiryTime multiplied by this - update_factor.

    - ]]>
    - 0.1 - 0.9 - 0.2 -
    -
    -
    - - To be able to ensure data consistency of historical data, the - Durability service needs to know which other Durability services - are available in the system. The value of this element determines - the amount of time the Durability service takes at startup to get - acquinted with all other Durability services in the system.

    -

    Increasing the value will increase the startup time of the - Durability service, but is required in larger domains where a lot - of network bandwidth is used.

    - ]]>
    - 3.0 - 0.1 - 10.0 -
    - - - - - 0.0 - 0.0 - - - DurabilityService/Network[@transport_priorrity] for the - alignment of data only. - ]]> - 0 - 0 - - - - true - - - - - - 0 - - - Relative - Absolute - Relative - - - - - Timeshare - Realtime - Default - Default - - - - - - - 0 - - - Relative - Absolute - Relative - - - - - Timeshare - Realtime - Default - Default - - - - When the Durability service detects an inconsistency with - another Durability service, it requests that service to align - it. The service that receives this request will restore - consistency by sending the requested information. In some - cases, the Durability service may receive alignment requests - from multiple Durability services for the same information - around the same moment in time. To reduce the processing and - networking load in that case, the Durability service is - capable of aligning multiple Durability services concurrently.

    -

    The RequestCombinePeriod has 2 child-elements: a setting - that is used when the current Durability Service is not yet - aligned with all others (Initial) and one for the period - after that (Operational). These values specify the maximum - amount of time the Durability service is allowed to wait with - alignment after an alignment request has been received.

    -

    Increasing the value will increase the amount of time in - which the Durability service restores from inconsistencies, - but will decrease the processing and network load in - case multiple Durability services need to resolve the - same data around the same time. Increasing the value - is useful in case OpenSplice is started at the same time - with more than two computing nodes.

    - ]]>
    - - - 0.5 - 0.01 - 5.0 - - - - 0.01 - 0.01 - 5.0 - -
    - - - - - 0 - partition - - - - 0 - 0 - - - - 0.0 - 0.0 - - - - 0 - 0 - - -
    - - - - DurabilityService/Network/WaitForAttachment/ServiceName - elements are available before sending any data. An error is - logged if one of the services still is unavailable afterwards. - The service will continue after that, but this indicates - a problem in the configuration and the service might not - function correctly anymore. - ]]> - 1 - 1000 - 200 - - - - networking - 0 - - - -
    - - Durable data is divided in transient and persistent data. Transient - data must stay available for as long as at least one Durability - service is available in the system. For persistent data it is - the same, but that type of data must also outlive the downtime - of the system. The Durability service stores the persistent data - on permanent storage to realize this. This element can be used - to fine-tune the behaviour of the Durability service concerning - the persistent properties of the data.

    -

    Note these elements are only available as part of the DDS - persistence profile of OpenSplice.

    - ]]>
    - - - 0 - /tmp/pstore - - - - 60.0 - 5.0 - 20.0 - - - - 10.0 - 0.5 - 2.0 - - - - XML - MMF - XML - - - - 1 - 1 - - - - - - - -
  • all persistent data in your specified namespaces
  • -
  • PLUS a potential backup for all persistent data in - namespaces whose content may be replaced by persistent - data from another master.
  • - -

    As a rule of thumb, you could state that the persistent store should - be twice the size of your combined persistent data in your specified - namespaces. Please note that the operating system should be configured - to support the requested size.

    -

    If this value is not specified, the size of the persistent store will be - set to twice the size of the shared memory segment.

    - ]]>
    - 1048576 - 10485760 -
    - - This element specifies the start address where the - file is mapped into the virtual memory. - The possible values are platform dependent.

    -

    Change this value if the default address is already in - use, for example by another Domain Service or another - product.

    -

    If this value is not specified, the file will be mapped - just after the shared memory segment.

    - ]]>
    - 0 - 0x80000000 -
    -
    - - - 1000000000 - 0 - 0 - - - - - - 0 - - - Relative - Absolute - Relative - - - - - Timeshare - Realtime - Default - Default - - - -
    - - - - - - - 0 - defaultNameSpace - - - - 0 - * - - - - 0 - *.* - - - - - - - Ignore - Ignore - Merge - Delete - Replace - - - 0 - * - - - - - 0 - * - - - This element specifies how the durability service - manages the data within the NameSpace. The original - durability of the data (determined by the DataWriter - that wrote it) can be 'weakened' (Persistent > Transient - > Transient_local). This is useful to improve - resource usage of the durability service in the - situation where resource usage is more important - then fault-tolerance. This parameter cannot be used - to increase the original durability of samples.

    -

    In case the value of this parameter is larger then - the value a sample was published with, the sample will - be handled as specified in the DataWriter durability - QoS.

    -
      -
    • Persistent: Data is maximally handled as persistent. - In practice this means a sample is - handled exactly as specified in the - DataWriter durability QoS that wrote - it.
    • -
    • Transient: A sample is maximally handled as if it - were published with a transient - durability QoS.
    • -
    • Transient_Local: Data is maximally handled as if it - were published with a - transient_local durability QoS.
    • -
    • Durable: Convenience value that behaves equal to - Persistent.
    • -
    - ]]>
    - Durable - Durable - Persistent - Transient - Transient_Local -
    - - - True - - - - False - - - This element determines how the durability service manages - the data that matches the namespace. Scalability of durable - data is an issue in large systems. Keeping all historical data - on each node may not be feasible. Often nodes are interested - in a small part of the total system data. They are driven - by both performance (boot time, memory usage, network load, - CPU load) and fault tolerance (the need for replicates).

    -

    The durability service provides the following - mechanisms to request and provide historical data: -

      -
    • Initial: The durability service requests - historical data at startup and caches it locally. Historical - data will be available relatively fast for new local data - readers and the system is more fault-tolerant. However, - caching of historical data requires a relatively large - amount of resources and a long boot time.
    • -
    • Lazy: The Durability service caches historical data - after local application interest arises for the first - time and a remote Durability service aligns the first - data reader. Historical data is available relatively slow - for the first data reader, but for every new data reader - it is relatively fast. The caching resources are only used - when local interest in the data arises, so it only requires - resources if there is actual local interest. However, - this method provides no fault-tolerance for the domain, - because the local Durability service is only partly a replica - and is not able to provide historical data to remote - Durability service and/or remote data readers.
    • -
    • On_Request: The Durability service will not cache - historical data, but will align each separate DataReader - on a request basis (in the situation where it calls - wait_for_historical_data). Each new DataReader that - wants historical data therefore leads to a new alignment - action. This is a good setting to limit the amount of - resources used on the node, but will potentially lead to - more network traffic. This method provides no - fault-tolerance for the domain.
    • -

    - ]]>
    - Initial - Initial - Lazy - On_Request -
    - - -
  • Ignore - No alignment will take place. This is also - the default value if not specified.
  • -
  • Merge - Existing data will remain and data from others - will be aligned.
  • -
  • Reset - Existing data is removed.
  • -
  • Replace - Existing data is removed and data from - others will be aligned.
  • - ]]>
    - Merge - Merge - Reset - Replace - Ignore -
    -
    -
    - - - - - 64 - durabilityPublisher - - - - 64 - durabilitySubscriber - - - - 64 - durabilityPartition - - - - - - - FALSE - - - - 0 - durability.log - - - - - - true - - true - - - - SEVERE - WARNING - INFO - CONFIG - FINE - FINER - FINEST - NONE - INFO - - -
    - - - - //OpenSplice/Domain/Service[@name] in the configuration of - the DomainService. - ]]> - 0 - networking - - - - - - - - 0 - - - Relative - Absolute - Relative - - - - - Timeshare - Realtime - Default - Default - - - - - - - - 15 - first available - - -
  • false - Specifies that the NetworkInterfaceAddress is first used but when not available another, - when available, is used. - (default). -
  • true - Specifies that only the selected NetworkInterfaceAddress can be used. - - ]]> - false - - - -
  • false - specifies that IPv4 should be used - (default). -
  • true - Specifies that IPv6 should be used. - - This setting will be overriden & ignored if the element NetworkInterfaceAddress has an explicit value - that is unequivocally either an IPv4 or IPv6 address. This attribute is therefore only - optionally required to specify IPv6 communication when special values like "first available" or - an interface name are used instead of IP addresses. - ]]> - false - - - - - - -
  • false - Specifies that the network service must NOT - resume communication. - (default). -
  • true - Specifies that the network service must - resume communication. - - ]]> - false - - - - - The OpenSplice Networking service is capable of leveraging - the network's multicast and routing capabilities. If some a-priori - knowledge about the participating - nodes and their topic and partition interest is available, then the - networking services in the system can be explicitly instructed to use - specific unicast or multicast addresses for its networking traffic. - This is done by means of so-called network partitions

    -

    A network partition is defined by one or more unicast, multicast - of broadcast IP addresses. Any networking service that is started - will read the network partition settings and, if applicable, join - the required multicast groups. For every sample distributed by the - networking service, both its partition and topic name will be - inspected. In combination with a set of network partition mapping rules, - the service will determine to which network partition the sample is - written. The mapping rules are configurable as well.

    -

    Using - networking configuration, nodes can be disconnected from any - networking partition. If a node is connected via a low speed - interface, it is not capable of receiving high volume data. If - the DCPS partitioning is designed carefully, high volume data is - published into a specific partition, which on its turn is mapped - onto a specific networking partition, which on its turn is only - connected to those nodes that are capable of handling high volume data.

    - ]]>
    - - - - - broadcast - 0 - - - - nullProfile - 0 - - - - 0 - 255 - 32 - - - - - - - - - networkPartition - 0 - - - - broadcast - 0 - - - A node can choose to be not connected to a networking - partition by setting the Connected attribute.

    -

    If a node is connected to a networking partition, - it will join the corresponding multicast group and - it will receive data distributed over the partition. - If it is not connected, data distributed over the - partition will not reach the node but will be - filtered by the networking interface or multicast - enabled switches.

    - ]]>
    - true -
    - - -
  • false - No compression is applied. This is - also the default value if not specified.
  • -
  • true - Compression is applicable
  • - - ]]>
    - false -
    - - - nullProfile - 0 - - - - 0 - 255 - 32 - -
    -
    - - - - - - - *.* - 0 - - - - - - - This element specifies a mapping between a network partition - and a partition-topic combination.

    -

    In order to give networking partitions a meaning in the context - of DCPS, mappings from DCPS partitions and topics onto networking - partitions should be defined. Networking allows for a set of - partition mappings to be defined.

    - ]]>
    - - - networkPartition - 0 - - - NetworkPartition element. - ]]> - *.* - 0 - -
    -
    - - - - - - true - false - false - - - - - - 0 - aSecurityProfile - - - • aes128, implements AES cipher with 128 bit cipher-key (16 Bytes, 32 - hexadecimal characters). This cipher will occupy 34 bytes of each UDP packet - being sent.

    -

    • aes192, implements the AES cipher with 192 bit cipher-key (24 Bytes, 48 - hexadecimal characters). This cipher will occupy 34 bytes of each UDP packet - being sent.

    -

    • aes256, implements the AES cipher with 256 bit cipher-key (32 Bytes, 64 - hexadecimal characters. This cipher will occupy 34 bytes of each UDP packet - being sent.

    -

    • blowfish, implements the Blowfish cipher with 128 bit cipher-key (16 Bytes, 32 - hexadecimal characters). This cipher will occupy 26 bytes of each UDP packet - being sent.

    -

    • null, implements the NULL cipher. The only cipher that does not require a - cipher-key. This cipher will occupy 4 bytes of each UDP packet being sent. -

    - All ciphers except for the NULL cipher are combined with SHA1 to achieve data - integrity. Also, the rsa- prefix can be added to the ciphers. In this case, digital - signatures using RSA will be available. - ]]>
    - 0 - aes128 - aes192 - aes256 - blowfish - null - rsa-aes128 - rsa-aes192 - rsa-aes256 - rsa-blowfish - rsa-null - null -
    - - - 0 - - -
    - - - - - true - false - false - - - - 0 - - - - - - - true - false - true - - - - MAC - none - 0 - - - - - - - - true - false - true - - - - - - - - 0 - - - - - 0 - - - - - - 0 - - - - -
    - - This element is used to group a set of Channels.

    -

    The set of channels define the behaviour of the 'network' concerning - aspects as priority, reliability and latency budget. By configuring - a set of channels, the Networking service is able to function as a - 'scheduler' for the network bandwidth. It achieves this by using the - application-defined DDS QoS policies of the data to select the most - appropriate channel to send the data.

    - ]]>
    - - This element specifies all properties of an individual Channel.

    -

    The Networking service will make sure messages with a higher - priority precede messages with a lower priority and it uses the - latency budget to assemble multiple messages into one UDP packet - where possible, to optimize the bandwidth usage. Of course, its - performance depends heavily on the compatbility of the configured - channels with the used DDS QoS policies of the applications.

    - ]]>
    - - - 0 - aChannel - - - If this attribute is set to true, the channel sends all messages reliably. - If not, data is sent only once (fire-and-forget).

    -

    The specific channel a message is written into depends on the attached - quality of service. Once a message has arrived in a channel, it will be - transported with the quality of service attached to the channel. If the - reliable attribute happens to be set to true, the message will be sent - over the network using a reliability protocol.

    - ]]>
    - false -
    - - This attribute indicates whether the channel is selected as the - default channel in case no channel offers the quality of service - requested by a message.

    -

    The networking channels should be configured corresponding - to the quality of service settings that are expected to be - requested by the applications. It might happen, however, - that none of the available channels meets the requested - quality of service for a specific message. In that case, - the message will be written into the default channel.

    -

    Note that only one channel is allowed to have this attribute - set to true

    - ]]>
    - false -
    - - - false - - - - 0 - - - - 1 - 65535 - 53430 - - - FragmentSize. These fragments - are sent as datagrams to the UDP stack. OS-settings determine - the maximum datagram size. - ]]> - 200 - 65535 - 1300 - - - The resolution indicates the number of milliseconds that - this channel sleeps between two consecutive resend or - packing actions. Latency budget values are truncated to a - multiple of "Resolution" milliseconds.

    -

    It is considered good practice to specify the ThrottleTreshold consistently throughout - the system.

    - ]]>
    - 1 - 10 -
    - - For reliable channels the receiving side needs to keep the sending - side informed about the received data and the received control messages.

    -

    This is done by means of an "AdminQueue". This setting determines the - size of this queue, and it must be greater than the maximum number of reliable - messages send or received during each "Resolution" milliseconds.

    - ]]>
    - 400 - 4000 -
    - - - - - false - - - - 1 - 400 - - - - 1024 - 1073741823 - 1073741823 - - - - 128 - 10240 - - - This is the number of unprocessed network fragments that a node will store before it will inform - the other nodes in the network that it has trouble processing the incoming data. Those other nodes - can use this information to adjust their throttle values, effectively reducing the amount of incoming - data in case of a temporary overflow, and increasing again when the node is able to catch up.

    -

    It is considered good practice to specify the ThrottleTreshold consistently throughout - the system.

    - ]]>
    - 2 - 50 -
    - - - 1 - 100 - - - - 2 - 3 - - - - 0 - 255 - 0 - - - - True - False - True - - - - 0 - 255 - 0 - - - - - - 0 - - Priority is a relative or absolute priority. - ]]> - Relative - Absolute - Relative - - - - - Timeshare - Realtime - Default - Default - - -
    - - - - - false - - - - 1024 - 1000000 - - - - - - 0 - - Priority is a relative or absolute priority. - ]]> - Relative - Absolute - Relative - - - - - Timeshare - Realtime - Default - Default - - - - - 500 - 5000 - - - - - - true - - - - - 100 - 1000 - - - - 0 - 0 - - - - 0 - 1000 - - -
    -
    - - - - - true - - - - 512 - - - - - 1 - 65536 - 53450 - - - - 512 - - - - - - - false - - - - 0 - 255 - 0 - - - - True - False - True - - - - 0 - 255 - 0 - - - - - - 0 - - Priority is a relative or absolute priority. - ]]> - Relative - Absolute - Relative - - - - - Timeshare - Realtime - Default - Default - - - - - 100 - 1000 - - - - 0.2 - 1.0 - 0.9 - - - - 1 - 3 - - - - - - false - - - - - - 0 - - Priority is a relative or absolute priority. - ]]> - Relative - Absolute - Relative - - - - - Timeshare - Realtime - Default - Default - - - - - 1 - 6 - - - - 1 - 1000000 - - - - - - - - 0 - networking.log - - - - - - true - - true - - - - - - 0 - 6 - 0 - - - Configuration category. - This includes the processing of all NetworkService parameters in the config file. - Level 0 indicates no tracing, level 6 indicates the most detailed level - of tracing. - ]]> - 0 - 6 - 0 - - - Construction category. - This includes the creation of all internal processing entities. - Level 0 indicates no tracing, level 6 indicates the most detailed level - of tracing. - ]]> - 0 - 6 - 0 - - - Destruction category. - This includes the destruction of all internal processing entities when the - NetworkService terminates. Level 0 indicates no tracing, level 6 indicates the - most detailed level of tracing. - ]]> - 0 - 6 - 0 - - - Mainloop category. - This includes information about each of the threads spawned by the NetworkService. - Level 0 indicates no tracing, level 6 indicates the most detailed level - of tracing. - ]]> - 0 - 6 - 0 - - - Groups category. - This includes the management of local groups (partition-topic combinations). - Level 0 indicates no tracing, level 6 indicates the most detailed level - of tracing. - ]]> - 0 - 6 - 0 - - - Send category. - This includes information about outgoing data. - Level 0 indicates no tracing, level 6 indicates the most detailed level - of tracing. - ]]> - 0 - 6 - 0 - - - Receive category. - This includes information about incoming data. - Level 0 indicates no tracing, level 6 indicates the most detailed level - of tracing. - ]]> - 0 - 6 - 0 - - - Test category. - This is a reserved category used for testing purposes. - Level 0 indicates no tracing, level 6 indicates the most detailed level - of tracing. - ]]> - 0 - 6 - 0 - - - Discovery category. - This includes all activity related to the discovery channel. - Level 0 indicates no tracing, level 6 indicates the most detailed level - of tracing. - ]]> - 0 - 6 - 0 - - - - - - - - - 0 - ddsi2 - - - - - This element specifies which network interface card should - be used.

    -

    Every DDSI2 Networking Service is bound to only one network - interface card (NIC). The card can be uniquely identified by - its corresponding IP address. If the value "AUTO" is entered - here, the OpenSplice middleware will try to look up an - interface that has the required capabilities.

    - ]]>
    - 0 - AUTO -
    - - This element specifies whether the DDSI2 service may use - IP multicasting.

    -

    If set to FALSE, no multicast packets will ever be sent by - the service, but it will still listen to multicast packets - from other nodes. Generally speaking, the peer nodes will have - to be listed as DDSI2Service/Discovery/Peer elements, but - the service will automatically discover multicasting peers - that advertise a unicast address.

    -

    If set to TRUE, multicast is used preferentially. If any Peer - elements are given, they will explicitly be included in the - discovery by means of packets sent to the specified addresses.

    - ]]>
    - 0 - TRUE -
    - - This element specifies whether the DDSI2 service - disable routing of IP packets.

    - ]]>
    - 0 - FALSE -
    - - This element specifies whether the DDSI2 service will allow - IP multicast packets within the node to be visible to all - DDSI participants in the node, including itself.

    -

    It must be TRUE for intra-node multicast communications, but - if a node runs only a single OpenSplice DDSI2 service and does - not host any other DDSI-capable programs, it may be set to - FALSE for improved performance.

    - ]]>
    - 0 - TRUE -
    - - This element specifies whether the OpenSplice DDSI2Service can - operate in conjunction with the OpenSplice NetworkService.

    -

    If FALSE, the DDSI2 service will take care of all - communications, including those between OpenSplice nodes.

    -

    If TRUE, the DDSI2 service will only communicate with DDS - implementations other than OpenSplice. In this case the - NetworkService must be configured as well.

    - ]]>
    - 0 - FALSE -
    - - This element specifies how long the DDSI2 remains in its - "startup" mode, in milliseconds.

    - -

    While in "startup" mode all data published on the - local node, except volatile best-effort data, is - retained as-if it were transient-local data, so - that existing readers on remote nodes can get the - data even though discovering them takes some time.

    - -

    Once the system is stable, the DDSI2 service keeps - track of the existence of remote readers whether or - not matching writers exist locally, avoiding this - discovery delay, and thereby ensuring this is - merely a node startup issue.

    - -

    Setting StartupModeDuration to 0 will disable it.

    - ]]>
    - 0 - 60000 - 2000 -
    -
    - - - - Selects the level of standards conformance of this - instance of the DDSI2 Service. Stricter conformance - typically means less interoperability with other - implementations.

    - -

    Currently three modes are defined: -
      -
    • pedantic very strictly conforms to the - specification, ultimately for compliancy testing, - but currently of little value because it adheres - even to what will most likely turn out to be - editing errors in the DDSI standard. Arguably, as - long as no errata have been published it is the - current text that is in effect, and that is what - pedantic currently does.
    • - -
    • strict takes a slightly less strict view of the - standard than pedantic: it follows the established - behaviour where the standard is obviously in error.
    • - -
    • lax simply tries to provide the smoothest possible - interoperability, anticipating future revisions of - elements in the standard in areas that other - implementations do not adhere to, even though there - is no good reason not to.
    • -

    - -

    The default setting is "lax".

    - ]]>
    - pedantic - strict - lax - lax -
    - - This option specifies whether QoS settings set to - default values are explicitly published in the - discovery protocol. Implementations are to use the - default value for QoS settings not published, which - allows a significant reduction of the amount of - data that needs to be exchanged for the discovery - protocol, but this requires all implementations to - adhere to the default values specified by the - specifications.

    - -

    When interoperability is required with an - implementation that does not follow the - specifications in this regard, setting this option - to true will help.

    - ]]>
    - false -
    - - This option specifies whether a network socket will - be created for each domain participant on a - host. The specification seems to assume that each - participant has a unique address, and setting this - option will ensure this to be the case. This is the - default.

    - -

    Disabling it slightly improves performance and - reduces network traffic somewhat.

    - ]]>
    - true -
    - - This element governs the representation of an - acknowledgement message that does not also - negatively-acknowledge some samples. If set to 0, - the generated acknowledgements have an invalid - form and will be reject by strict mode, but - several other implementation require this setting - for smooth interoperation.

    - -

    If set to 1, all acknowledgements sent by DDSI2 - adhere the form of acknowledgement messages - allowed by the standard, but this causes problems - when interoperating with these other - implementations.

    - -

    The default is 1 in the strict and pedantic - standards conformance modes, 0 in lax mode.

    - ]]>
    - 0 - 1 - 1 -
    - - This option allows a closer mimicking of the - behaviour of some other DDSI implementations, - albeit at the cost of generating even more invalid - messages. Setting it to true ensures a Heartbeat - can be sent at any time when a remote node requests - one, setting it to false delays it until a valid - one can be sent.

    - -

    The latter is fully compliant with the - specification, and no adverse effects have been - observed. It is the default.

    - ]]>
    - false -
    -
    - - - - - 0 - 229 - 0 - - - This element specifies the DDSI participant id used by this - instance of the DDSI2 service for discovery purposes. Only one - such participant id is used, independent of the number of - actual DomainParticipants on the node.

    - -

    It is either "AUTO" (the default), which will attempt to - automatically determine an available participant index, or a - non-negative integer less than 120.

    - ]]>
    - 0 - AUTO -
    - - - 0 - - - - - - - 1 - 65535 - 7400 - - - - 250 - - - - 2 - - - - 0 - - - - 0 - - - - 1 - - - - 11 - - -
    - - - - - severe - warning - info - config - fine - finer - finest - warning - - - - 0 - ddsi-tracing-output.log - - - - true - - - - - - true - - true - - -
    - - - - name attribute, which must match the one specified - under the OpenSplice/Domain/Service[@name] in the configuration of - the Domain Service. - ]]> - cmsoap - 0 - - - - - - - - 0 - - - Relative - Absolute - Relative - - - - - Timeshare - Realtime - Default - Default - - - - - - - - 1 - 65535 - 8000 - - - - 0 - 5 - - - - 0 - 1 - 2 - 3 - 4 - 5 - 0 - - - - - - - 1 - 2 - - - - 1 - 2 - - - - 10.0 - 15.0 - - - - - - 0 - - Priority is a relative - or absolute priority. - ]]> - Relative - Absolute - Relative - - - - - Timeshare - Realtime - Default - Default - - - - - - - - - - 0 - - Priority is a relative - or absolute priority. - ]]> - Relative - Absolute - Relative - - - - - Timeshare - Realtime - Default - Default - - - - - - - - - - 0 - - Priority is a relative - or absolute priority. - ]]> - Relative - Absolute - Relative - - - - - Timeshare - Realtime - Default - Default - - - - - - OpenSplice/DbmsConnectService. Within - this root element, the DbmsConnect Service will look for several child-elements. - Each of these is listed and explained. - ]]> - - OpenSplice/Domain/Service[@name] in the configuration of - the DomainService. - ]]> - 0 - dbmsconnect - - - - - This attribute specifies the default replication mode for - all NameSpaces in the DdsToDbms element.

    -

    When replicating databases through DDS, the NameSpace - elements in the DbmsToDds and DdsToDbms elements - map a Table and Topic circularly. To prevent data-modifications - from continuously cascading, modifications made by the - DBMSConnect service itself should not trigger new updates - in the DBMS nor in the DDS.

    -

    In replication mode, the DBMS-connect service ignores - samples that were published by itself. (Currently that means - that everything that is published on the same node as the - DBMSConnect Service is considered to be of DBMSConnect - origin and therefore ignored). That way, replication of - changes that were copied from Dbms to DDS back into Dbms - is avoided.

    -

    WARNING: This setting does not avoid replication - of changes that were copied from DDS to Dbms back into DDS. - For that purpose, the replication_user attribute of the - DbmsToDds or DbmsToDds/NameSpace elements should - be set appropriately as well!

    - ]]>
    - FALSE -
    - - NameSpace element has to be present in - a DdsToDbms element. - ]]> - - - 0 - (nameless) - - - The service dynamically loads an ODBC library at runtime. This attribute - specifies the name of the ODBC library to be loaded. Platform specific - pre- and postfixes and extensions are automatically added.

    -

    If this attribute is not provided, the service will attempt to load the - generic ODBC library. The resulting behaviour is dependent on the platform - on which the DbmsConnect Service is running.

    - ]]>
    - 0 - -
    - - This attribute specifies an expression that represents one or more DDS - partitions. It is allowed to use wildcards in the expression: a '*' - represents any sequence of characters and a '?' represents one - single character.

    -

    This expression is used to specify the DDS partition(s) from which - DDS samples must be 'bridged' to the DBMS domain.

    - ]]>
    - 0 - * -
    - - This attribute specifies an expression that represents one or more DDS - topic names. It is allowed to use wildcards in the expression: a '*' - represents any sequence of characters and a '?' represents one - single character.

    -

    This expression is used to specify the topics from which DDS - samples must be ‘bridged’ to the DBMS domain. For every matching - topic encountered in one or more of the specified partitions, it - creates a separate table in the DBMS. The table name will match that - of the topic, unless specified otherwise in the table attribute - of a Mapping element.

    - ]]>
    - 0 - * -
    - - - 0.0 - 0.0 - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - This attribute specifies the replication mode for the - current NameSpace element. If not specified, the value - will be inherited from the replication_mode of the parent - DdsToDbms element, which if not explicitly specified - defaults to false

    -

    When replicating databases through DDS, the NameSpace - elements in the DbmsToDds and DdsToDbms elements - map a Table and Topic circularly. To prevent data-modifications - from continuously cascading, modifications made by the - DBMSConnect service itself should not trigger new updates - in the DBMS.

    -

    In replication mode, the DBMS-connect service ignores - samples that were published by itself. (Currently that means - that everything that is published on the same node as the - DBMSConnect Service is considered to be of DBMSConnect - origin and therefore ignored). That way, replication of - changes that were copied from Dbms to DDS back into Dbms - is avoided.

    -

    WARNING: This setting does not avoid replication - of changes that were copied from DDS to Dbms back into DDS. - For that purpose, the replication_user attribute of the - DbmsToDds or DbmsToDds/NameSpace elements should - be set appropriately as well!

    - ]]>
    - FALSE -
    - - - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - -
    -
    - - - - - true - - - This attribute specifies the default setting of the event table policy for all NameSpace elements in the current DbmsToDds element.

    -

    An event table (sometimes referred to as ‘change table’ or ‘shadow table’) is a support-table that is slaved to an application-table, adding some status flags that are under the control of a trigger mechanism that responds to creation/modification/ deletion events in the application-table.

    -

    The following policies are currently supported:

    -
      -
    • FULL: (default) An 'event table' will always be created when the service connects, and will always be deleted when the service disconnects. In this mode, the service will replace the table if it already exists.
    • -
    • LAZY: An 'event table' will only be created if it is not available when the service connects, and it will not be deleted when the service disconnects.
    -
  • NONE: An 'event table' will neither be created nor deleted by the service. For each specified NameSpace, the service will poll for the existence of a consistent table with a frequency specified in the coresponding update_frequency attribute. It will start using the table as soon as it is available. With this policy set, no initial data will be published regardless of the value of the applicable publish_initial_data attribute. - - ]]> - FULL - LAZY - NONE - FULL - - - This attribute specifies the default trigger policy for all NameSpace elements in the current DbmsToDds element.

    -

    Triggers are used to to update the event table in case of creation/modification/ deletion events on the application-table.

    -

    The following policies are currently supported:

    -
      -
    • FULL: (default) Triggers will always be created when the service connects, and will always be deleted when the service disconnects. In this mode, the service will replace the triggers if they already exists.
    • -
    • LAZY: Triggers will only be created if they are not available when the service connects, and will not be deleted when the service disconnects.
    -
  • NONE: Triggers will neither be created nor deleted by the service. This allows you to build your own custom triggering mechanism. - - ]]> - FULL - LAZY - NONE - FULL - - - This attribute specifies the default replication user for - all NameSpace elements in the current DdsToDbms - element.

    -

    When replicating databases through DDS, the NameSpace - elements in the DbmsToDds and DdsToDbms elements - map a Table and Topic circularly. To prevent data-modifications - from continuously cascading, modifications made by the - service itself should not trigger new updates in the - DBMS nor in the DDS.

    -

    To distinguish between DBMS updates coming from an - application and DBMS updates coming from DDS, an extra - database user (the replication user) has to be introduced - that differs from the application users. That way, - replication of changes that were copied from DDS to Dbms - back into DDS is avoided. The replication_user attribute - specifies the user name of that replication user. An empty - string (default value) indicates that there is no separate - replication user.

    -

    WARNING: This setting does not avoid replication - of changes that were copied from Dbms to DDS back into Dbms. - For that purpose, the replication_mode attribute of - the DssToDbms or DssToDbms/NameSpace elements - should be set appropriately as well!

    - ]]>
    - 0 - -
    - - NameSpace - element has to be present in a DbmsToDds element. - ]]> - - - 0 - (nameless) - - - The service dynamically loads an ODBC library at runtime. This attribute - specifies the name of the ODBC library to be loaded. Platform specific - pre- and postfixes and extensions are automatically added.

    -

    If this attribute is not provided, the service will attempt to load the - generic ODBC library. The resulting behaviour is dependent on the platform - on which the DbmsConnect Service is running.

    - ]]>
    - 0 - -
    - - This attribute specifies an expression represents one or more DDS partitions. - It is allowed to use wildcards in the expression: a '*' represents any - sequence of characters and a '?' represents one single character.

    -

    This expression is used to specify the DDS partition(s) where DBMS records - will be written to as DDS samples by the service.

    - ]]>
    - 0 - * -
    - - This attribute specifies an expression that represents one or more DBMS - table names. It is allowed to use wildcards in the expression: a '*' - represents any sequence of characters and a '?' represents one single - character.

    -

    This expression is used to specify the tables from which DBMS data must - be 'bridged' to the DDS domain.

    - ]]>
    - 0 - * -
    - - - 0.0 - 2.0 - - - - 0 - - - - - 0 - - - - - 0 - - - - true - Mapping - elements in the current NameSpace element. If not specified, the value - will be inherited from the publish_initial_data of the parent - DbmsToDds element, which defaults to true. The value of this attribute - is ignored when the corresponding event_table_policy is set to NONE. - ]]> - - - true - Mapping elements - in the current NameSpace element with regard to the enforcement of - key equality between table and topic definitions. If true, key definitions - from the table and topic must match, otherwise key definitions may differ. - ]]> - - - This attribute specifies the default setting of the event table policy for all Mapping elements in the current NameSpace element. If not specified, the value will be inherited from the event_table_policy of the parent DbmsToDds element, which if not explicitly specified defaults to FULL.

    -

    An event table (sometimes referred to as ‘change table’ or ‘shadow table’) is a support-table that is slaved to an application-table, adding some status flags that are under the control of a trigger mechanism that responds to creation/modification/ deletion events in the application-table.

    -

    The following policies are currently supported:

    -
      -
    • FULL: An 'event table' will always be created when the service connects, and will always be deleted when the service disconnects. In this mode, the service will replace the table if it already exists.
    • -
    • LAZY: An 'event table' will only be created if it is not available when the service connects, and it will not be deleted when the service disconnects.
    -
  • NONE: An 'event table' will neither be created nor deleted by the service. For each specified NameSpace, the service will poll for the existence of a consistent table with a frequency specified in the coresponding update_frequency attribute. It will start using the table as soon as it is available. With this policy set, no initial data will be published regardless of the value of the applicable publish_initial_data attribute. - - ]]> - FULL - LAZY - NONE - FULL - - - This attribute specifies the default trigger policy for all Mapping elements in the current NameSpace element. If not specified, the value will be inherited from the trigger_policy of the parent DbmsToDds element, which if not explicitly specified defaults to FULL.

    -

    Triggers are used to to update the event table in case of creation/modification/ deletion events on the application-table.

    -

    The following policies are currently supported:

    -
      -
    • FULL: (default) Triggers will always be created when the service connects, and will always be deleted when the service disconnects. In this mode, the service will replace the triggers if they already exists.
    • -
    • LAZY: Triggers will only be created if they are not available when the service connects, and will not be deleted when the service disconnects.
    -
  • NONE: Triggers will neither be created nor deleted by the service. This allows you to build your own custom triggering mechanism. - - ]]> - FULL - LAZY - NONE - FULL - - - - 0 - - - - - 0 - - - - This attribute specifies the default replication user for - all Mapping elements in the current NameSpace - element. If not specified, the value will be inherited from - the replication_user of the parent DbmsToDds element, - which by default has no separate replication user specified.

    -

    When replicating databases through DDS, the NameSpace - elements in the DbmsToDds and DdsToDbms elements - map a Table and Topic circularly. To prevent data-modifications - from continuously cascading, modifications made by the - service itself should not trigger new updates in the - DBMS nor in the DDS.

    -

    To distinguish between DBMS updates coming from an - application and DBMS updates coming from DDS, an extra - database user (the replication user) has to be introduced - that differs from the application users. That way, - replication of changes that were copied from DDS to Dbms - back into DDS is avoided. The replication_user attribute - specifies the user name of that replication user. An empty - string (default value) indicates that there is no separate - replication user.

    -

    WARNING: This setting does not avoid replication - of changes that were copied from Dbms to DDS back into Dbms. - For that purpose, the replication_mode attribute of - the DssToDbms or DssToDbms/NameSpace elements - should be set appropriately as well!

    - ]]>
    - 0 - -
    - - - - - 0 - - - - - 0 - - - - - 0 - - - - true - Mapping element - from DBMS to DDS. If not specified, the value will be inherited from - the publish_initial_data of the parent NameSpace element, - which if not explicitly specified inherits from the publish_initial_data - of the parent DbmsToDds element, which defaults to true. - The value of this attribute is ignored when the corresponding - event_table_policy is set to NONE. - ]]> - - - true - force_key_equality of the parent - NameSpace element, which if not explicitly specified defaults to true. - ]]> - - - This attribute specifies the event table policy in the current Mapping element. If not specified, the value will be inherited from the event_table_policy of the parent NameSpace element, which if not explicitly specified inherits from the event_table_policy of the parent DbmsToDds element, which defaults to FULL.

    -

    An event table (sometimes referred to as ‘change table’ or ‘shadow table’) is a support-table that is slaved to an application-table, adding some status flags that are under the control of a trigger mechanism that responds to creation/modification/ deletion events in the application-table.

    -

    The following policies are currently supported:

    -
      -
    • FULL: An 'event table' will always be created when the service connects, and will always be deleted when the service disconnects. In this mode, the service will replace the table if it already exists.
    • -
    • LAZY: An 'event table' will only be created if it is not available when the service connects, and it will not be deleted when the service disconnects.
    -
  • NONE: An 'event table' will neither be created nor deleted by the service. For the specified table, the service will poll with a frequency specified in the coresponding update_frequency attribute of the parent NameSpace. It will start using the table as soon as it is available. With this policy set, no initial data will be published regardless of the value of the applicable publish_initial_data attribute. - - ]]> - FULL - LAZY - NONE - FULL - - - This attribute specifies the trigger policy for the current Mapping element. If not specified, the value will be inherited from the trigger_policy of the parent DbmsToDds element, which if not explicitly specified inherits from the trigger_policy of the parent DbmsToDds element, which defaults to FULL.

    -

    Triggers are used to to update the event table in case of creation/modification/ deletion events on the application-table.

    -

    The following policies are currently supported:

    -
      -
    • FULL: (default) Triggers will always be created when the service connects, and will always be deleted when the service disconnects. In this mode, the service will replace the triggers if they already exists.
    • -
    • LAZY: Triggers will only be created if they are not available when the service connects, and will not be deleted when the service disconnects.
    -
  • NONE: Triggers will neither be created nor deleted by the service. This allows you to build your own custom triggering mechanism. - - ]]> - FULL - LAZY - NONE - FULL - - - - - - - - - 0 - dbmsconnect.log - - - - - - true - - true - - - - SEVERE - WARNING - INFO - CONFIG - FINE - FINER - FINEST - INFO - - - - - OpenSplice/UserClockService. Within this root element, - the userclock will look for several child-elements. Each of these is listed - and explained. - ]]> - - name attribute must match the one specified under the - OpenSplice/Domain/Service[@name] in the configuration of the - Domain Service. - ]]> - userclock - 0 - - - - - 0 - - - - - - 0 - clockStart - - - - - - - 0 - clockStop - - - - - - This attribute specifies the name of the function that gets the - current time. This clockGet function should not have any parameters, - and needs to return the current time as an os_time type.

    -

    The definition of the os_time type can be found in os_time.h.

    - ]]>
    - 0 - clockGet -
    -
    -
    - diff --git a/src/tools/cm/config/code/splice_metaconfig_5.1.xsd b/src/tools/cm/config/code/splice_metaconfig_5.1.xsd deleted file mode 100644 index e7d7469f6..000000000 --- a/src/tools/cm/config/code/splice_metaconfig_5.1.xsd +++ /dev/null @@ -1,280 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/tools/cm/config/code/splice_metaconfig_6.1.xml b/src/tools/cm/config/code/splice_metaconfig_6.1.xml index 4b4ed01c4..83a30684c 100644 --- a/src/tools/cm/config/code/splice_metaconfig_6.1.xml +++ b/src/tools/cm/config/code/splice_metaconfig_6.1.xml @@ -3,13 +3,13 @@ OpenSplice DDS is highly configurable, even allowing the architecture of the - DDS middleware to be chosen by the user at deployment time. OpenSplice DDS can +

    Vortex OpenSplice is highly configurable, even allowing the architecture of the + DDS middleware to be chosen by the user at deployment time. Vortex OpenSplice can be configured to run using a shared memory architecture, where both the DDS related administration (including the optional pluggable services) and DDS - applications interface directly with shared memory. Alternatively, OpenSplice - DDS also supports a single process architecture, where one or more DDS - applications, together with the OpenSplice administration and services, can all be + applications interface directly with shared memory. Alternatively, Vortex OpenSplice + also supports a single process architecture, where one or more DDS + applications, together with the Vortex OpenSplice administration and services, can all be grouped into a single operating system process. Both deployment modes support a configurable and extensible set of services, providing functionality such as:

    networking - providing QoS-driven real-time networking based on multiple @@ -17,17 +17,25 @@

    durability - providing fault-tolerant storage for both real-time state data as well as persistent settings

    remote control and monitoring SOAP service - providing remote web-based - access using the SOAP protocol from the OpenSplice Tuner tool

    + access using the SOAP protocol from the Vortex OpenSplice Tuner tool

    dbms service - providing a connection between the real-time and the enterprise domain by bridging data from DDS to DBMS and vice versa

    -

    Because of the pluggable architecture, the OpenSplice middleware +

    Because of the pluggable architecture, the Vortex OpenSplice middleware can be easily configured on the fly by specifying which services to be used as well as specifying their optimal configuration for the application domain (networking parameters, durability levels, etc.). Typically, there are many nodes within a system.

    -

    The OpenSplice middleware including its services can be configured +

    The Vortex OpenSplice middleware including its services can be configured by means of easy maintainable XML-file(s).

    ]]>
    +
    @@ -51,7 +59,7 @@ lifecycle of the started services is under control of the Domain service, which means it will monitor the health of all started services, take corrective actions if needed and stop the services when it is terminated.

    -

    When a shutdown of the OpenSplice Domain service is requested, it will react by announcing the shutdown using the +

    When a shutdown of the Vortex OpenSplice Domain service is requested, it will react by announcing the shutdown using the DDS administration. Applications will not be able to use DDS functionality anymore and services are requested to terminate elegantly. Once this has succeeded, the Domain service will destroy the administration and finally terminate itself.

    @@ -72,8 +80,8 @@ Note - for maximum interoperability it is recommended that you only select a domain Id from the range 0 < n < 230. The domain Id value is used by the DDSI2 service to derive values for the required network communiction endpoints and service reconfiguration is required to use domain id values outside of this range. - Please see section 9.6.1 of the Real-time Publish-Subscribe Wire Protocol DDS Interoperability Wire Protocol specification (DDSI), v2.1, formal/2009-01-05 at - http://www.omg.org/spec/DDSI/2.1/ for further information. + Please see section 9.6.1 of the Real-time Publish-Subscribe Wire Protocol DDS Interoperability Wire Protocol specification (DDSI), v2.1, formal/2009-01-05 + or v2.2, formal/2014-09-01, at http://www.omg.org/spec/DDSI for further information. ]]> 0 2147483646 @@ -105,7 +113,7 @@ This element specifies the interval(in seconds) in which services have to announce their liveliness.

    -

    Every OpenSplice service including the Domain service itself has to announce its liveliness regularly. +

    Every Vortex OpenSplice service including the Domain service itself has to announce its liveliness regularly. This allows corrective actions to be taken when one of the services becomes non-responsive. This element specifies the required interval. Decreasing the interval decreases the time in which non-responsiveness of a service is detected, but leads to more processing. Increasing it has @@ -186,7 +194,7 @@ This may prevent graceful termination and thus leave applications that are still attached to the DDS domain in an undefined state. Consequently the '0' value should only be used when there is - some form of process management on top of OpenSplice DDS. + some form of process management on top of Vortex OpenSplice. ]]> float seconds @@ -196,23 +204,23 @@ The SingleProcess element specifies whether the OpenSplice Domain and other - OpenSplice services and applications are intended to be all deployed within the - same process, known in OpenSplice as a single process.

    +

    The SingleProcess element specifies whether the Vortex OpenSplice Domain and other + Vortex OpenSplice services and applications are intended to be all deployed within the + same process, known in Vortex OpenSplice as a single process.

    Please note that the choice to use the single process deployment also implies - the use of heap memory for the OpenSplice database management instead of shared + the use of heap memory for the Vortex OpenSplice database management instead of shared memory that would be used otherwise. If no database size or size 0 is configured the heap memory is limited by the Operating System, so the Database element under Domain does not take effect when SingleProcess has a value of True. If the database size is configured with a value, a database will be allocated on heap with that size and the domain service will use it's own memory manager to manage that memory

    -

    There are two ways in which to deploy an OpenSplice DDS application as a +

    There are two ways in which to deploy an Vortex OpenSplice application as a single process:

    Single Process Application : The user starts an application as a new process. In this case, the DDS create_participant operation will - implicitly start the OpenSplice Domain Service as a thread in the existing - application process. The OpenSplice Domain Service will then also implicitly + implicitly start the Vortex OpenSplice Domain Service as a thread in the existing + application process. The Vortex OpenSplice Domain Service will then also implicitly start all services specified in the configuration as threads within the same process.

    Single Process Application Cluster : This provides the option to @@ -245,7 +253,7 @@ The InProcessExceptionHandling element determines whether a process that uses OpenSplice will +

    The InProcessExceptionHandling element determines whether a process that uses Vortex OpenSplice will handle exceptions by itself and try to clean up shared resources or not. If the process itself refrains from cleaning up its resources, the splice-daemon will attempt to clean up the application shared resources asynchronously. If the splice-daemon during clean-up determines that shared @@ -732,7 +740,7 @@

    default values per platform:

      -
    • 0x20000000 (Linux2.6 on x86)
    • -
    • 00x140000000 (Linux2.6 on x86_64)
    • -
    • 00x40000000 (Windows on x86)
    • -
    • 00x40000000 (Windows on x86_64)
    • -
    • 00xA0000000 (Solaris on SPARC)
    • -
    • 00xA0000000 (AIX5.3 on POWER5+)
    • -
    • 00x0 (VxWorks 5.5.1 on PowerPC604)
    • -
    • 00x60000000 (VxWorks 6.x on PowerPC604)
    • -
    • 00x20000000 (Integrity on mvme5100)
    +
  • 00x20000000 (Linux)
  • +
  • 00x140000000 (Linux 64-bit)
  • +
  • 00x40000000 (Windows)
  • +
  • 00x140000000 (Windows 64-bit)
  • +
  • 00xA0000000 (Solaris)
  • +
  • 00xA0000000 (AIX5.3)
  • +
  • 00x0 (VxWorks 5.5.1)
  • +
  • 00x60000000 (VxWorks 6.x)
  • +
  • 00x20000000 (Integrity)
  • +
  • 00x20000000 (LynxOS)
  • +
  • 00x140000000 (LynxOS 64-bit)
  • +
  • 00x0 (PikeOS)
  • +
  • 00x60000000 (QXN)
  • +
  • 00x0 (RTEMS)
  • +
  • 00x00220000 (Windows CE)
  • + ]]>
    0 0x0 @@ -821,7 +836,7 @@ This attribute specifies the name by which the corresponding service is identified in the rest of the configuration file.

    -

    In the OpenSplice DDS configuration file, services and their settings +

    In the Vortex OpenSplice configuration file, services and their settings are identified by a name. When the Domain Service starts a particular service, its corresponding name is passed. The service in question uses this name in order to find its own configuration settings in the rest of @@ -844,14 +859,14 @@ This element specifies the command to be executed in order to start the service.

    In shared memory mode, Command element specifies the name of the actual service - executable (possibly including its path, but always including its extension, e.g. - .exe on the Windows platform). When no path is included, the Domain Service - will search the PATH environment variable for the corresponding executable. Once - located, it will be started as a separate process.

    + executable or a script to launch this service (possibly including its path, but always + including its extension, e.g. .exe on the Windows platform). When no path is + included, the Domain Service will search the PATH environment variable for the + corresponding executable. Once located, it will be started as a separate process.

    In single process mode, Command is the name of the entry point function to be invoked and the name of the shared library to be dynamically loaded into the process. The signature of the entry point function is the same as argc/argv usually - seen with main. The OpenSplice services are implemented in such a way that the + seen with main. The Vortex OpenSplice services are implemented in such a way that the entry point name matches that of the shared library, so (for example) specifying durability is all that is required.

    ]]>
    @@ -992,7 +1007,7 @@
  • skip: Ignore the non-responsiveness and continue.
  • kill: End the service process by force.
  • restart: End the service process by force and restart it.
  • -
  • systemhalt: End all OpenSplice services including the Domain service (for the current DDS Domain on this computing node).
  • +
  • systemhalt: End all Vortex OpenSplice services including the Domain service (for the current DDS Domain on this computing node).
  • ]]> kill @@ -1002,13 +1017,24 @@ skip
    + + + This attribute specifies the namespace by which the corresponding groups + will use the writer instance gid as key so that data from different writers + don merge as historical data for late joiners.

    + ]]>
    + 0 + +
    +
    When in the single process deployment mode, the Domain service can deploy DDS applications by dynamically loading application shared libraries and starting threads within the existing process. A user can add a multiple Application elements to the configuration when they want - to 'cluster' multiple DDS applications within an OpenSplice DDS single process. + to 'cluster' multiple DDS applications within an Vortex OpenSplice single process. The entry point and shared library for each Application can be specified by using the Command and Library elements that are described below.>/p>

    Note that Applications only take effect when the single process configuration is enabled by way of the SingleProcess element.

    @@ -1035,7 +1061,7 @@

    Command is the name of both the entry point function to invoked and the name of the shared library to be dynamically loaded into the process. The signature of the entry point function is the same as argc/argv usually seen with main.

    -

    For example, if Command is "HelloWorld", OpenSpliceDDS will attempt to load +

    For example, if Command is "HelloWorld", Vortex OpenSplice will attempt to load "libHelloWorld.so" on Unix (or "HelloWorld.dll" on Windows) into the existing process and then invoke the "HelloWorld" entry point to start that DDS application.

    If the name of the shared library does not have the same name as the entry point the @@ -1052,7 +1078,7 @@ This optional attribute allows the user to specify arguments to be passed to the DDS application's entry point when it is invoked.

    -

    For example, if Command is "HelloWorld" and Arguments is "arg1 arg2", OpenSplice will +

    For example, if Command is "HelloWorld" and Arguments is "arg1 arg2", Vortex OpenSplice will invoke the HelloWorld function with the argc = 3 and argv = {"HelloWorld", "arg1", "arg2"}

    ]]>
    0 @@ -1082,6 +1108,15 @@ ]]> true + + + builtin.log + 0 +
    @@ -1143,7 +1178,7 @@ @@ -1218,7 +1253,7 @@

    int symbol_name (const char *argument, void **context)

    The result value is used to return the status of the call. If it is 0 then the operation was successful. If it is not 0 then there was an error and details of the error and the - result value are reported to the OpenSplice DDS default report service. + result value are reported to the Vortex OpenSplice default report service. The context parameter is an out reference that can be set to plugin-specific data that will subsequently be passed to any of the other plugin functions. The value of the parameter is meaningless to the service @@ -1250,14 +1285,14 @@ resolved, an error message will be generated and the service will not attempt to resolve other symbol_names for the report plugin. The function is invoked slightly differently for applications using the DDS API and - OpenSplice services. OpenSplice services invoke the function once for every report. + Vortex OpenSplice services. Vortex OpenSplice services invoke the function once for every report. For applications using the DDS API the function is invoked once per API call, in which case the XML is extended by one or more DETAIL elements. The implementation of this function must have the following signature:

    int symbol_name (void *context, const char *report)

    The result value is used to return the status of the call. If it is 0 then the operation was successful. If it is not 0 then there was an error and details of the error and the - result value are reported to the OpenSplice DDS default report service. + result value are reported to the Vortex OpenSplice default report service. The context parameter is a reference to the plugin-specific data retrieved from the initialize operation. The report parameter is an XML string representation of the report data. @@ -1328,7 +1363,7 @@

    int symbol_name (void *context)

    The result value is used to return the status of the call. If it is 0 then the operation was successful. If it is not 0 then there was an error and details of the error and the - result value are reported to the OpenSplice DDS default report service. + result value are reported to the Vortex OpenSplice default report service. ]]>
    0 @@ -1352,7 +1387,7 @@ int symbol_name (void *context) The result value is used to return the status of the call. If it is 0 then the operation was successful. If it is not 0 then there was an error and details of the error and the - result value are reported to the OpenSplice DDS default report service. + result value are reported to the Vortex OpenSplice default report service. The context parameter is a reference to the plugin-specific data retrieved from the initialize operation. ]]> @@ -1373,8 +1408,8 @@ false @@ -1562,7 +1597,7 @@ OpenSplice/Domain/UserClock. Within this root element, the userclock will look for several child-elements. Each of these is listed and explained. @@ -1658,7 +1693,7 @@ - + + - + 0 durability - + - + TRUE - + - + 64 durabilityPublisher - + 64 durabilitySubscriber - + - + - + False - + - + 0 - + Relative - +
    - + Applications need to be able to gain access to historical data in a system. When the local DDS service gets connected to a remote DDS service by means @@ -1988,7 +2086,7 @@ communication between Durability services on different computing nodes on network level. These settings only apply when the Networking service is active.

    ]]>
    - + This attribute controls the latency_budget QoS setting that is used by the Durability service for its communication @@ -2003,7 +2101,7 @@ 0.0 seconds - + This attribute controls the transport priority QoS setting that is used by the Durability service for its @@ -2022,10 +2120,10 @@ 0 0 - + During startup and at runtime, the network topology can change - dynamically. This happens when OpenSplice services are started/stopped + dynamically. This happens when Vortex OpenSplice services are started/stopped or when a network cable is plugged in/out. The Durability services need to keep data consistency in that environment. To detect newly joining services as well as detecting nodes that are leaving, the @@ -2035,7 +2133,7 @@

    Please note this heartbeat mechanism is similar to but not the same as the service liveliness assertion.

    ]]>
    - + 0.0 0.0 - + 0 0 - + - + 0 - + Relative - + Default - + This element specifies the maximum amount of time(in seconds) in which the Durability service expects a new heartbeat of @@ -2107,7 +2205,7 @@ ]]> 10.0 0.2 - + In case of a (temporary) high CPU load, the scheduling behaviour of the operating system might affect the @@ -2126,7 +2224,7 @@ - + 10.0 seconds - + - + 0.0 0.0 - + 0 0 - + This attribute specifies whether time on all nodes in the domain can be considered aligned or not. This setting needs to be consistent for all durability services in the domain. In case there is no time alignment, the durability - service needs to align more data since to compensate possible - timing gaps between different nodes in the domain. + service needs to align more data to compensate for possible + timing gaps between different nodes in the domain.

    +

    When using DDSI2(e) networking service it is strongly recommended + to set this value to 'false'. The asynchronous nature of the DDSI2 + discovery protocol in combination with TimeAlignment could lead to a + gap in transient/persistent data when Durability alignment and DDSI2 + discovery coincide, which is normal behavior.

    ]]>
    true
    - + - + 0 - + Relative - + Default - + - + 0 - + Relative - + Default - + When the Durability service detects an inconsistency with another Durability service, it requests that service to align @@ -2296,10 +2399,10 @@ but will decrease the processing and network load in case multiple Durability services need to resolve the same data around the same time. Increasing the value - is useful in case OpenSplice is started at the same time + is useful in case Vortex OpenSplice is started at the same time with more than two computing nodes.

    ]]>
    - + 0.01 5.0 - + 5.0
    - + - + 0 partition - + 0 0 - + 0.0 0.0 - + 0 - + 1.0 - + - + 1000 200 - + - + + For every namespace and role a single node is elected master, the one to + provide historical data. This optional element can be used to fine-fune the + characteristics of the master election algorithm.

    +

    This element is optional, and when used only applies to master election for + namespaces with non-legacy masterPriority (see + //OpenSplice/DurabilityService/NameSpaces/Policy[@masterPriority]).

    + ]]>
    + + + 0.0 + 0.0 + 10.0 + seconds + +
    + Durable data is divided in transient and persistent data. Transient data must stay available for as long as at least one Durability @@ -2454,9 +2582,9 @@ to fine-tune the behaviour of the Durability service concerning the persistent properties of the data.

    Note these elements are only available as part of the DDS - persistence profile of OpenSplice.

    + persistence profile of Vortex OpenSplice.

    ]]>
    - + 0 /tmp/pstore - + 20.0 seconds - + This element specifies the period of time (in seconds) the persistency thread sleeps between two sessions. This allows @@ -2492,39 +2620,21 @@ 0.0 0.0 - + !!! The "MMF" store is deprecated from version 6.3 and was only implemented on linux !!!,

    + persistent data in XML files. With "KV" mode the service will store + persistent data in a key-value store using either sqlite of leveldb + to store the data on disk.

    !!! For "KV" stores, SQLite is supported on linux, Windows, and Solaris; LevelDB is only supported on linux.

    ]]> XML - MMF KV XML - - !!! The "MMF" store is deprecated from version 6.3 and was only implemented on linux !!!,

    - ]]>
    - 1 - 1 -
    - + The "KV" store is currenly only supported on linux (SQLite and LevelDB), Windows (SQLite), and Solaris (SQLite).

    ]]>
    - + The following types can be selected: +
      +
    • sqlite3 -use sqlite3 as the key value store. Data in the store is stored efficiently + as binary blobs. This is the default.
    • +
    • sqlite - same as sqlite3. This option is present for backward compatibility.
    • +
    • sqlitemt - use sqlite3 as the key value store implementation, but + stores the information as readable data. This mode allows a user to inspect the + contents of the store, but the store performance will be lower compared to sqlite3 + because each piece of data must be translated to readable format. This option is + typically used for testing purposes to inspect the contents of the store.
      + (Note: the abbreviation 'mt' stands for 'multi-table').
    • +
    • leveldb - use leveldb as the key value store
    • +

    ]]>
    sqlite3 sqlite + sqlitemt leveldb sqlite3
    - + 0 0 - + This element specifies compression settings for the key-value store.

    Compression for the persistent store can be used to reduce disk I/O and lower disk @@ -2606,11 +2730,11 @@

    Compression is set at store creation time. Changing these settings after the store is created will result in an error.

    ]]>
    - + This attribute specifies the compression algorithm that is used to store the persistent data in the key-value store.

    -

    The lzf and snappy compression algorithms are built into the OpenSplice +

    The lzf and snappy compression algorithms are built into the Vortex OpenSplice installation. To use the zlib algorithm a shared library needs to be available on the system, and it must be locatable by way of the current working directory, or via LD_LIBRARY_PATH (on Unix systems) or PATH (on Windows systems).

    @@ -2620,7 +2744,7 @@ zlib lzf
    - +
    - - The "MMF" store is deprecated from version 6.3. and was only implemented in Linux

    - ]]>
    - - -
  • all persistent data in your specified namespaces
  • -
  • PLUS a potential backup for all persistent data in namespaces whose content may be replaced by persistent data from another master.
  • - -

    As a rule of thumb, you could state that the persistent store should - be twice the size of your combined persistent data in your specified - namespaces. Please note that the operating system should be configured - to support the requested size.

    -

    If this value is not specified, the size of the persistent store will be - set to twice the size of the shared memory segment.

    - ]]>
    - 1048576 - 10485760 -
    - - This element specifies the start address where the - file is mapped into the virtual memory. - The possible values are platform dependent.

    -

    Change this value if the default address is already in - use, for example by another Domain Service or another - product.

    -

    If this value is not specified, the file will be mapped - just after the shared memory segment.

    - ]]>
    - 0 - 0x80000000 -
    -
    - + 0 0 - + - + 0 - + Relative - + - - + - + - + - - + - + ]]> - + @@ -3005,7 +3088,7 @@ Replace Catchup - + * - + 0 * - + This element specifies how the durability service manages the data within the NameSpace. The original @@ -3055,14 +3138,14 @@ Transient Transient_Local - + True - + This element determines how the durability service manages the data that matches the namespace. Scalability of durable @@ -3084,7 +3167,7 @@ This mandatory attribute determines whether the durability service can act as al Lazy On_Request - + False - + False - - -
    - Different filters can be specified for different partition-topic - combinations using the <Filter>-elements.

    - NOTE A side effect can occur when filters are - used in combination with the ability to align data. - In case a node that has retrieved a subset of historical data - using filters becomes the aligner to other nodes at some - point in time, then only this subset will be aligned to the other - nodes. - ]]>
    - 0 - -
    - If no filter is defined for a particular partition-topic then all data will be - aligned for this partition-topic combination. - If multiple filters are defined then the first one that matches will be applied. - ]]>
    - -
    - The following escape sequence can be used in expressions: &lt; - (less than), &gt; (greater than), &quot; (double quote) - &apos; (apostrophe) and &amp; (ampersand).

    - Examples of expressions are: -
      -
    • x=1 or x=2
    • -
    • (id&lt;10) and (name="test")
    • -
    - If an invalid filter expression is provided an error will be logged - in ospl-error.log. - ]]>
    - 0 - -
    - - - 0 - *.* - -
    + + + 0 + 255 + 255 +
    - + - + 64 durabilityPublisher - + 64 durabilitySubscriber - + @@ -3203,14 +3247,14 @@ This mandatory attribute determines whether the durability service can act as al durabilityPartition - + - + FALSE - + 0 durability.log - + - + true - + - 15 + 0 first available True False @@ -3448,7 +3492,7 @@ This mandatory attribute determines whether the durability service can act as al The OpenSplice Secure Networking service is capable of leveraging +

    The Vortex OpenSplice Secure Networking service is capable of leveraging the network's multicast and routing capabilities. If some a-priori knowledge about the participating nodes and their topic and partition interest is available, then the @@ -3545,7 +3589,7 @@ commas (,) semicolons (;) or spaces ( ). Samples for this partition will be sent all addresses that are specified in this list of addresses. To specify the default broadcast address, use the expression "broadcast". Addresses can be entered as 'dotted decimal' IPv4 or 'colon-separated hexadecimal' IPv6 notation or as the -symbolic hostname, in which case OpenSplice will try to resolve the corresponding +symbolic hostname, in which case Vortex OpenSplice will try to resolve the corresponding IP address. ]]> broadcast @@ -3591,11 +3635,11 @@ IP address. security feature has been enabled but no profile is declared, the NULL profile will be used by default. The ordering of network partition declarations in the OSPL configuration file must - be the same for all nodes within the OpenSplice domain. If certain nodes shall not + be the same for all nodes within the Vortex OpenSplice domain. If certain nodes shall not use one of the network partitions, the network partition in question must be declared as connected="false". In this case the declared security profile would not be evaluated or initialized, and the associated secret cipher keys need not to be defined - for the OpenSplice node in question. + for the Vortex OpenSplice node in question. ]]> nullProfile 0 @@ -3696,7 +3740,7 @@ such 'loopback' performance is typically optimized by the operating system NULL cipher does not provide for any level of integrity or confidentiality, but message items will be sent unencrypted. In case of enabled="false" the security feature will not be activated, and the - node acts like any other OpenSplice node not being security aware. Security profiles + node acts like any other Vortex OpenSplice node not being security aware. Security profiles defined in the configuration file will not take effect, but will cause the system to log warnings. ]]> @@ -3724,9 +3768,9 @@ such 'loopback' performance is typically optimized by the operating system have a specific length, 128 bits, 192 bits, 256 bits or none at all. The following case-insensitive values are supported by the current implementation:

      -
    • aes128, implements AES cipher with 128 bit cipher-key (16 Bytes, 32 hexadecimal characters). This cipher will occupy 34 bytes of each UDP packet being sent.
    • +
    • aes128, implements the AES cipher with 128 bit cipher-key (16 Bytes, 32 hexadecimal characters). This cipher will occupy 34 bytes of each UDP packet being sent.
    • aes192, implements the AES cipher with 192 bit cipher-key (24 Bytes, 48 hexadecimal characters). This cipher will occupy 34 bytes of each UDP packet being sent.
    • -
    • aes256, implements the AES cipher with 256 bit cipher-key (32 Bytes, 64 hexadecimal characters. This cipher will occupy 34 bytes of each UDP packet being sent.
    • +
    • aes256, implements the AES cipher with 256 bit cipher-key (32 Bytes, 64 hexadecimal characters). This cipher will occupy 34 bytes of each UDP packet being sent.
    • blowfish, implements the Blowfish cipher with 128 bit cipher-key (16 Bytes, 32 hexadecimal characters). This cipher will occupy 26 bytes of each UDP packet being sent.
    • null, implements the NULL cipher. The only cipher that does not require a cipher-key. This cipher will occupy 4 bytes of each UDP packet being sent.
    @@ -3759,14 +3803,14 @@ such 'loopback' performance is typically optimized by the operating system will be marked as invalid. Moreover, each network partition referring to the invalid Security Profile will not be operational and thus traffic will be blocked to prevent information leaks. - As all OpenSplice applications require read access to the XML configuration file, + As all Vortex OpenSplice applications require read access to the XML configuration file, for security reasons it is recommended to store the secret key in an external file in the file system, referenced by the URI in the configuration file. The file must be protected against read and write access from other users on the host. Verify that access rights are not given to any other user or group on the host. Alternatively, storing the secret key in-place in the XML configuration file will give - read/write access to all DDS applications joining the same OpenSplice node. + read/write access to all DDS applications joining the same Vortex OpenSplice node. Because of this, the 'in-place' method is strongly discouraged. ]]>
    0 @@ -3810,7 +3854,7 @@ such 'loopback' performance is typically optimized by the operating system @@ -3850,7 +3894,7 @@ such 'loopback' performance is typically optimized by the operating system It is recommended that the absolute path is used. A relative path will be interpreted relative to the directory from which the - OpenSplice daemon is started. + Vortex OpenSplice daemon is started. ]]> 0 @@ -3861,7 +3905,7 @@ such 'loopback' performance is typically optimized by the operating system It is recommended that the absolute path is used. A relative path will be interpreted relative to the directory from which the - OpenSplice daemon is started. + Vortex OpenSplice daemon is started. ]]> 0 @@ -3873,7 +3917,7 @@ such 'loopback' performance is typically optimized by the operating system It is recommended that the absolute path is used. A relative path will be interpreted relative to the directory from which the - OpenSplice daemon is started. + Vortex OpenSplice daemon is started. ]]> 0 @@ -4039,7 +4083,7 @@ such 'loopback' performance is typically optimized by the operating system ]]> 0 255 @@ -4159,6 +4203,16 @@ The lost message is resent after Resolution * RecoveryFactor milliseconds. False True + + + True + False + False + @@ -4209,7 +4263,7 @@ The lost message is resent after Resolution * RecoveryFactor milliseconds. ]]> 0 255 @@ -4477,6 +4531,16 @@ to true (see Element Reconnection). False True + + + True + False + False + @@ -4550,7 +4614,7 @@ to true (see Element Reconnection). ]]> 0
    + + The Verbosity attribute sets the level of tracing for all Tracing Catagories. This attribute is an additional method besides the Tracing/Catagories tag to specify trace levels. The difference is that Verbosity sets the level for all catagories similar as by other services whereas the Tracing/Catagories element allows to set the trace level per catagory. The verbosity levels are mapped to Catagory levels as following:

    +
    • none: level 0 (no Networking log)
    • +
    • severe: level 1
    • +
    • warning: level 2
    • +
    • info: level 3
    • +
    • config: level 3
    • +
    • fine: level 4
    • +
    • finer: level 5
    • +
    • finest: level 6
    + ]]>
    + finest + finer + fine + config + info + warning + severe + none + none +

    It is imperative that all nodes exchanging compressed data have the same configuration in this section.

    @@ -5021,7 +5107,7 @@ to true (see Element Reconnection). The OpenSplice NetworkService supports both Internet Protocol +

    The Vortex OpenSplice NetworkService supports both Internet Protocol Versions 4 and 6 (IPv4 & IPv6) where possible. Please refer to the Release Notes (Known Issues section) to see if the IPv6 capability is present on your operating system.

    @@ -5043,7 +5129,7 @@ Domain section of the configuration file (Element Application).
    networking

    The network configuration expects a root element named -OpenSplice/NetworkService. Within this root element, the Network Service +Vortex OpenSplice/NetworkService. Within this root element, the Network Service will look for several child-elements. Each of these is listed and explained. ]]>
    @@ -5111,11 +5197,11 @@ will look for several child-elements. Each of these is listed and explained. Every Networking service is bound to only one network interface card (NIC). The card can be uniquely identified by its corresponding IP address or by its symbolic name (e.g. eth0). If the - value "first available" is entered here, the OpenSplice + value "first available" is entered here, the Vortex OpenSplice middleware will try to look up an interface that has the required capabilities. ]]>
    - 15 + 0 first available True @@ -5220,7 +5306,7 @@ will look for several child-elements. Each of these is listed and explained.
    The OpenSplice Networking service is capable of leveraging +

    The Vortex OpenSplice Networking service is capable of leveraging the network's multicast and routing capabilities. If some a-priori knowledge about the participating nodes and their topic and partition interest is available, then the @@ -5356,11 +5442,11 @@ will look for several child-elements. Each of these is listed and explained. security feature has been enabled but no profile is declared, the NULL profile will be used by default. The ordering of network partition declarations in the OSPL configuration file must - be the same for all nodes within the OpenSplice domain. If certain nodes shall not + be the same for all nodes within the Vortex OpenSplice domain. If certain nodes shall not use one of the network partitions, the network partition in question must be declared as connected="false". In this case the declared security profile would not be evaluated or initialized, and the associated secret cipher keys need not to be defined - for the OpenSplice node in question. + for the Vortex OpenSplice node in question. ]]> nullProfile 0 @@ -5593,7 +5679,7 @@ will look for several child-elements. Each of these is listed and explained. ]]> 0 255 @@ -5692,6 +5778,16 @@ will look for several child-elements. Each of these is listed and explained. False True + + + True + False + False + @@ -5751,7 +5847,7 @@ will look for several child-elements. Each of these is listed and explained. ]]> 0 255 @@ -6034,6 +6130,16 @@ received. False True + + + True + False + False + @@ -6118,7 +6224,7 @@ typical scheduling or network latencies. ]]> 0 + + The Verbosity attribute sets the level of tracing for all Tracing Catagories. This attribute is an additional method besides the Tracing/Catagories tag to specify trace levels. The difference is that Verbosity sets the level for all catagories similar as by other services whereas the Tracing/Catagories element allows to set the trace level per catagory. The verbosity levels are mapped to Catagory levels as following:

    +
    • none: level 0 (no Networking log)
    • +
    • severe: level 1
    • +
    • warning: level 2
    • +
    • info: level 3
    • +
    • config: level 3
    • +
    • fine: level 4
    • +
    • finer: level 5
    • +
    • finest: level 6
    + ]]>
    + finest + finer + fine + config + info + warning + severe + none + none +

    It is imperative that all nodes exchanging compressed data have the same configuration in this section.

    @@ -6784,7 +6912,7 @@ When an application is run without Administrative priveleges then only the diffs This element specifies the number of messages the network queue for this channel can contain. The OpenSplice kernel writes data to be transmitted to the network queue, and DDSI2E takes them from this queue. If this queue is full when an application tries to write a sample, the sample will be dropped or the writer suspended, depending on the QoS settings of the writer. OpenSplice and its services are optimised for a well-balanced system design, where the queue never becomes full.

    +

    This element specifies the number of messages the network queue for this channel can contain. The Vortex OpenSplice kernel writes data to be transmitted to the network queue, and DDSI2E takes them from this queue. If this queue is full when an application tries to write a sample, the sample will be dropped or the writer suspended, depending on the QoS settings of the writer. Vortex OpenSplice and its services are optimised for a well-balanced system design, where the queue never becomes full.

    ]]>
    0
    @@ -6864,10 +6992,18 @@ When an application is run without Administrative priveleges then only the diffs ]]>
    This element controls whether or not DDSI2E advertises writers for the built-in topics from its discovery for backwards compatibility with older OpenSplice versions.

    +

    This element controls whether or not DDSI2E advertises writers for the built-in topics from its discovery for backwards compatibility with older Vortex OpenSplice versions.

    ]]>
    true
    + + This setting controls for how long endpoints discovered via a Cloud discovery service will survive after the discovery service disappeared, allowing reconnect without loss of data when the discovery service restarts (or another instance takes over).

    +

    Valid values are finite durations with an explicit unit or the keyword 'inf' for infinity. Recognised units: ns, us, ms, s, min, hr, day.

    + ]]>
    + 0 + 30 s +
    This element specifies the default multicast address for all traffic other than participant discovery packets. It defaults to Discovery/SPDPMulticastAddress.

    @@ -6893,7 +7029,7 @@ When an application is run without Administrative priveleges then only the diffs

    This element controls which partition is monitored by DDSI2E for built-in topics describing entities the it mirrors in DDSI.

    ]]>
    0 - __BUILT_IN_PARTITION__ + __BUILT-IN PARTITION__
    This element statically configures addresses for discovery.

    +

    Valid values are finite durations with an explicit unit or the keyword 'inf' for infinity. Recognised units: ns, us, ms, s, min, hr, day.

    ]]>
    + 0 This element statically configures a fault tolerant group of addresses for discovery. Each member of the group is tried in sequence until one succeeds.

    @@ -6948,12 +7086,12 @@ When an application is run without Administrative priveleges then only the diffs
    The Ports element allows specifying various parameters related to the port numbers used for discovery. These all have default values specified by the DDSI 2.1 specification and rarely need to be changed.

    +

    The Ports element allows specifying various parameters related to the port numbers used for discovery. These all have default values specified by the DDSI 2.1 (and 2.2) specification and rarely need to be changed.

    ]]>
    0 This element specifies the base port number (refer to the DDSI 2.1 specification, section 9.6.1, constant PB).

    +

    This element specifies the base port number (refer to the DDSI 2.1 or 2.2 specification, section 9.6.1, constant PB).

    ]]>
    1 65535 @@ -6961,37 +7099,37 @@ When an application is run without Administrative priveleges then only the diffs
    This element specifies the domain gain, relating domain ids to sets of port numbers (refer to the DDSI 2.1 specification, section 9.6.1, constant DG).

    +

    This element specifies the domain gain, relating domain ids to sets of port numbers (refer to the DDSI 2.1 or 2.2 specification, section 9.6.1, constant DG).

    ]]>
    250
    This element specifies the port number for multicast meta traffic (refer to the DDSI 2.1 specification, section 9.6.1, constant d2).

    +

    This element specifies the port number for multicast meta traffic (refer to the DDSI 2.1 or 2.2 specification, section 9.6.1, constant d2).

    ]]>
    1
    This element specifies the port number for multicast meta traffic (refer to the DDSI 2.1 specification, section 9.6.1, constant d0).

    +

    This element specifies the port number for multicast meta traffic (refer to the DDSI 2.1 or 2.2 specification, section 9.6.1, constant d0).

    ]]>
    0
    This element specifies the participant gain, relating p0, articipant index to sets of port numbers (refer to the DDSI 2.1 specification, section 9.6.1, constant PG).

    +

    This element specifies the participant gain, relating p0, articipant index to sets of port numbers (refer to the DDSI 2.1 or 2.2 specification, section 9.6.1, constant PG).

    ]]>
    2
    This element specifies the port number for unicast meta traffic (refer to the DDSI 2.1 specification, section 9.6.1, constant d3).

    +

    This element specifies the port number for unicast meta traffic (refer to the DDSI 2.1 or 2.2 specification, section 9.6.1, constant d3).

    ]]>
    11
    This element specifies the port number for unicast meta traffic (refer to the DDSI 2.1 specification, section 9.6.1, constant d1).

    +

    This element specifies the port number for unicast meta traffic (refer to the DDSI 2.1 or 2.2 specification, section 9.6.1, constant d1).

    ]]>
    10
    @@ -7034,7 +7172,7 @@ When an application is run without Administrative priveleges then only the diffs This element specifies whether the DDSI2E service operates in conjunction with the OpenSplice RT Networking service. When "false", the DDSI2E service will take care of all communications, including those between OpenSplice nodes; when "true", the DDSI2E service only communicates with DDS implementations other than OpenSplice. In this case the RT Networking service should be configured as well.

    +

    This element specifies whether the DDSI2E service operates in conjunction with the Vortex OpenSplice RT Networking service. When "false", the DDSI2E service will take care of all communications, including those between Vortex OpenSplice nodes; when "true", the DDSI2E service only communicates with DDS implementations other than Vortex OpenSplice. In this case the RT Networking service should be configured as well.

    ]]>
    false
    @@ -7148,13 +7286,13 @@ When an application is run without Administrative priveleges then only the diffs
    Internal

    This element controls whether to drop a reliable sample from a DDSI2E WHC before all readers have acknowledged it as soon as a later sample becomes available. It only affects DCPS data writers with a history QoS setting of KEEP_LAST with depth 1. The default setting, false, mimics the behaviour of the OpenSplice RT networking and is necessary to make the behaviour of wait_for_acknowledgements() consistent across the networking services.

    +Internal

    This element controls whether to drop a reliable sample from a DDSI2E WHC before all readers have acknowledged it as soon as a later sample becomes available. It only affects DCPS data writers with a history QoS setting of KEEP_LAST with depth 1. The default setting, false, mimics the behaviour of the Vortex OpenSplice RT networking and is necessary to make the behaviour of wait_for_acknowledgements() consistent across the networking services.

    ]]>
    true
    Internal

    This element controls whether to drop a reliable sample from a DDSI2E WHC before all readers have acknowledged it as soon as a later sample becomes available. It only affects DCPS data writers with a history QoS setting of KEEP_LAST with depth 1. The default setting, false, mimics the behaviour of the OpenSplice RT networking and is necessary to make the behaviour of wait_for_acknowledgements() consistent across the networking services.

    +Internal

    This element controls whether to drop a reliable sample from a DDSI2E WHC before all readers have acknowledged it as soon as a later sample becomes available. It only affects DCPS data writers with a history QoS setting of KEEP_LAST with depth 1. The default setting, false, mimics the behaviour of the Vortex OpenSplice RT networking and is necessary to make the behaviour of wait_for_acknowledgements() consistent across the networking services.

    ]]>
    true
    @@ -7165,6 +7303,14 @@ When an application is run without Administrative priveleges then only the diffs 0 + + Internal

    This setting controls the interval with which a reader will continue NACK'ing missing samples in the absence of a response from the writer, as a protection mechanism against writers incorrectly stopping the sending of HEARTBEAT messages.

    +

    Valid values are finite durations with an explicit unit or the keyword 'inf' for infinity. Recognised units: ns, us, ms, s, min, hr, day.

    + ]]>
    + 0 + 1 s +
    Internal

    This element specifies the maximum transmit rate of auxiliary traffic not bound to a specific channel, such as discovery traffic, as well as auxiliary traffic related to a certain channel if that channel has elected to share this global AuxiliaryBandwidthLimit. Bandwidth limiting uses a leaky bucket scheme. The default value "inf" means DDSI2E imposes no limitation, the underlying operating system and hardware will likely limit the maimum transmit rate.

    @@ -7203,9 +7349,23 @@ When an application is run without Administrative priveleges then only the diffs ]]>
    false - + + Internal

    This attribute sets the time until the deaf and mute settings are automatically reset to false

    +

    Valid values are finite durations with an explicit unit or the keyword 'inf' for infinity. Recognised units: ns, us, ms, s, min, hr, day.

    + ]]>
    + 0 + inf +
    + + Internal

    This element controls whether DDSI2E defaults to deaf mode or to normal mode. This controls both the initial behaviour and what behaviour it auto-reverts to.

    + ]]>
    + false +
    + Internal

    This element controls whether DDSI2E defaults to deaf-mute mode or to normal mode. This controls both the initial behaviour and what behaviour it auto-reverts to.

    +Internal

    This element controls whether DDSI2E defaults to mute mode or to normal mode. This controls both the initial behaviour and what behaviour it auto-reverts to.

    ]]>
    false
    @@ -7255,6 +7415,38 @@ When an application is run without Administrative priveleges then only the diffs ]]> true
    + + Internal

    This element sets the base interval for the asynchronous, periodic writer heartbeats when unacknowledged data is present in its writer history cache. The actual interval is dynamically adjusted, the attributes of this element allow further configuration.

    +

    Valid values are finite durations with an explicit unit or the keyword 'inf' for infinity. Recognised units: ns, us, ms, s, min, hr, day.

    + ]]>
    + 0 + 100 ms + + Internal

    This attribute sets the maximum interval for periodic heartbeats.

    +

    Valid values are finite durations with an explicit unit or the keyword 'inf' for infinity. Recognised units: ns, us, ms, s, min, hr, day.

    + ]]>
    + 0 + 8 s +
    + + Internal

    This attribute sets the minimum interval that must have passed since the most recent heartbeat from a writer, before another asynchronous (not directly related to writing) will be sent.

    +

    Valid values are finite durations with an explicit unit or the keyword 'inf' for infinity. Recognised units: ns, us, ms, s, min, hr, day.

    + ]]>
    + 0 + 5 ms +
    + + Internal

    This attribute sets the minimum interval for periodic heartbeats. Other events may still cause heartbeats to go out.

    +

    Valid values are finite durations with an explicit unit or the keyword 'inf' for infinity. Recognised units: ns, us, ms, s, min, hr, day.

    + ]]>
    + 0 + 20 ms +
    +
    Internal

    Ack a sample only when it has been delivered, instead of when committed to delivering it.

    @@ -8151,10 +8343,18 @@ When an application is run without Administrative priveleges then only the diffs ]]>
    This element controls whether or not DDSI2 advertises writers for the built-in topics from its discovery for backwards compatibility with older OpenSplice versions.

    +

    This element controls whether or not DDSI2 advertises writers for the built-in topics from its discovery for backwards compatibility with older Vortex OpenSplice versions.

    ]]>
    true
    + + This setting controls for how long endpoints discovered via a Cloud discovery service will survive after the discovery service disappeared, allowing reconnect without loss of data when the discovery service restarts (or another instance takes over).

    +

    Valid values are finite durations with an explicit unit or the keyword 'inf' for infinity. Recognised units: ns, us, ms, s, min, hr, day.

    + ]]>
    + 0 + 30 s +
    This element specifies the default multicast address for all traffic other than participant discovery packets. It defaults to Discovery/SPDPMulticastAddress.

    @@ -8180,7 +8380,7 @@ When an application is run without Administrative priveleges then only the diffs

    This element controls which partition is monitored by DDSI2 for built-in topics describing entities the it mirrors in DDSI.

    ]]>
    0 - __BUILT_IN_PARTITION__ + __BUILT-IN PARTITION__
    This element statically configures addresses for discovery.

    +

    Valid values are finite durations with an explicit unit or the keyword 'inf' for infinity. Recognised units: ns, us, ms, s, min, hr, day.

    ]]>
    + 0 This element statically configures a fault tolerant group of addresses for discovery. Each member of the group is tried in sequence until one succeeds.

    @@ -8235,12 +8437,12 @@ When an application is run without Administrative priveleges then only the diffs
    The Ports element allows specifying various parameters related to the port numbers used for discovery. These all have default values specified by the DDSI 2.1 specification and rarely need to be changed.

    +

    The Ports element allows specifying various parameters related to the port numbers used for discovery. These all have default values specified by the DDSI 2.1 (and 2.2) specification and rarely need to be changed.

    ]]>
    0 This element specifies the base port number (refer to the DDSI 2.1 specification, section 9.6.1, constant PB).

    +

    This element specifies the base port number (refer to the DDSI 2.1 or 2.2 specification, section 9.6.1, constant PB).

    ]]>
    1 65535 @@ -8248,37 +8450,37 @@ When an application is run without Administrative priveleges then only the diffs
    This element specifies the domain gain, relating domain ids to sets of port numbers (refer to the DDSI 2.1 specification, section 9.6.1, constant DG).

    +

    This element specifies the domain gain, relating domain ids to sets of port numbers (refer to the DDSI 2.1 or 2.2 specification, section 9.6.1, constant DG).

    ]]>
    250
    This element specifies the port number for multicast meta traffic (refer to the DDSI 2.1 specification, section 9.6.1, constant d2).

    +

    This element specifies the port number for multicast meta traffic (refer to the DDSI 2.1 or 2.2 specification, section 9.6.1, constant d2).

    ]]>
    1
    This element specifies the port number for multicast meta traffic (refer to the DDSI 2.1 specification, section 9.6.1, constant d0).

    +

    This element specifies the port number for multicast meta traffic (refer to the DDSI 2.1 or 2.2 specification, section 9.6.1, constant d0).

    ]]>
    0
    This element specifies the participant gain, relating p0, articipant index to sets of port numbers (refer to the DDSI 2.1 specification, section 9.6.1, constant PG).

    +

    This element specifies the participant gain, relating p0, articipant index to sets of port numbers (refer to the DDSI 2.1 or 2.2 specification, section 9.6.1, constant PG).

    ]]>
    2
    This element specifies the port number for unicast meta traffic (refer to the DDSI 2.1 specification, section 9.6.1, constant d3).

    +

    This element specifies the port number for unicast meta traffic (refer to the DDSI 2.1 or 2.2 specification, section 9.6.1, constant d3).

    ]]>
    11
    This element specifies the port number for unicast meta traffic (refer to the DDSI 2.1 specification, section 9.6.1, constant d1).

    +

    This element specifies the port number for unicast meta traffic (refer to the DDSI 2.1 or 2.2 specification, section 9.6.1, constant d1).

    ]]>
    10
    @@ -8321,7 +8523,7 @@ When an application is run without Administrative priveleges then only the diffs
    This element specifies whether the DDSI2 service operates in conjunction with the OpenSplice RT Networking service. When "false", the DDSI2 service will take care of all communications, including those between OpenSplice nodes; when "true", the DDSI2 service only communicates with DDS implementations other than OpenSplice. In this case the RT Networking service should be configured as well.

    +

    This element specifies whether the DDSI2 service operates in conjunction with the Vortex OpenSplice RT Networking service. When "false", the DDSI2 service will take care of all communications, including those between Vortex OpenSplice nodes; when "true", the DDSI2 service only communicates with DDS implementations other than Vortex OpenSplice. In this case the RT Networking service should be configured as well.

    ]]>
    false
    @@ -8435,7 +8637,7 @@ When an application is run without Administrative priveleges then only the diffs Internal

    This element controls whether to drop a reliable sample from a DDSI2 WHC before all readers have acknowledged it as soon as a later sample becomes available. It only affects DCPS data writers with a history QoS setting of KEEP_LAST with depth 1. The default setting, false, mimics the behaviour of the OpenSplice RT networking and is necessary to make the behaviour of wait_for_acknowledgements() consistent across the networking services.

    +Internal

    This element controls whether to drop a reliable sample from a DDSI2 WHC before all readers have acknowledged it as soon as a later sample becomes available. It only affects DCPS data writers with a history QoS setting of KEEP_LAST with depth 1. The default setting, false, mimics the behaviour of the Vortex OpenSplice RT networking and is necessary to make the behaviour of wait_for_acknowledgements() consistent across the networking services.

    ]]>
    false
    @@ -8446,6 +8648,14 @@ When an application is run without Administrative priveleges then only the diffs 0 + + Internal

    This setting controls the interval with which a reader will continue NACK'ing missing samples in the absence of a response from the writer, as a protection mechanism against writers incorrectly stopping the sending of HEARTBEAT messages.

    +

    Valid values are finite durations with an explicit unit or the keyword 'inf' for infinity. Recognised units: ns, us, ms, s, min, hr, day.

    + ]]>
    + 0 + 1 s +
    Internal

    This element controls which participants will have which built-in endpoints for the discovery and liveliness protocols. Valid values are:

    @@ -8476,9 +8686,15 @@ When an application is run without Administrative priveleges then only the diffs ]]>
    false - + Internal

    This element controls whether DDSI2 defaults to deaf-mute mode or to normal mode. This controls both the initial behaviour and what behaviour it auto-reverts to.

    +Internal

    This element controls whether DDSI2 defaults to deaf mode or to normal mode. This controls both the initial behaviour and what behaviour it auto-reverts to.

    + ]]>
    + false +
    + + Internal

    This element controls whether DDSI2 defaults to mute mode or to normal mode. This controls both the initial behaviour and what behaviour it auto-reverts to.

    ]]>
    false
    @@ -8528,6 +8744,38 @@ When an application is run without Administrative priveleges then only the diffs ]]> true
    + + Internal

    This element sets the base interval for the asynchronous, periodic writer heartbeats when unacknowledged data is present in its writer history cache. The actual interval is dynamically adjusted, the attributes of this element allow further configuration.

    +

    Valid values are finite durations with an explicit unit or the keyword 'inf' for infinity. Recognised units: ns, us, ms, s, min, hr, day.

    + ]]>
    + 0 + 100 ms + + Internal

    This attribute sets the maximum interval for periodic heartbeats.

    +

    Valid values are finite durations with an explicit unit or the keyword 'inf' for infinity. Recognised units: ns, us, ms, s, min, hr, day.

    + ]]>
    + 0 + 8 s +
    + + Internal

    This attribute sets the minimum interval that must have passed since the most recent heartbeat from a writer, before another asynchronous (not directly related to writing) will be sent.

    +

    Valid values are finite durations with an explicit unit or the keyword 'inf' for infinity. Recognised units: ns, us, ms, s, min, hr, day.

    + ]]>
    + 0 + 5 ms +
    + + Internal

    This attribute sets the minimum interval for periodic heartbeats. Other events may still cause heartbeats to go out.

    +

    Valid values are finite durations with an explicit unit or the keyword 'inf' for infinity. Recognised units: ns, us, ms, s, min, hr, day.

    + ]]>
    + 0 + 20 ms +
    +
    Internal

    Ack a sample only when it has been delivered, instead of when committed to delivering it.

    @@ -10184,7 +10432,7 @@ Each of these are listed and explained. @@ -10254,7 +10502,7 @@ Each of these are listed and explained. + from the Vortex OpenSplice configuration file always start out with empty statistics.]]>
    0 false diff --git a/src/tools/cm/config/makefile b/src/tools/cm/config/makefile index 69577a63f..982a6c590 100644 --- a/src/tools/cm/config/makefile +++ b/src/tools/cm/config/makefile @@ -12,8 +12,8 @@ META_SRC_DIR =$(CONFIG_DIR)/code META_BLD_DIR =$(CONFIG_DIR)/bld/$(SPLICE_TARGET) META_FILE =splice_metaconfig_6.1.xml META_XSD_FILE =splice_metaconfig_6.1.xsd -DST_META_FILE =metaconfig.xml -DST_META_XSD_FILE=metaconfig.xsd +DST_META_FILE =ospl_metaconfig.xml +DST_META_XSD_FILE=ospl_metaconfig.xsd META_FILES =$(META_BLD_DIR)/$(DST_META_FILE) META_FILES +=$(META_BLD_DIR)/$(DST_META_XSD_FILE) diff --git a/src/tools/cm/dataadapter/code/org/opensplice/cmdataadapter/CmDataException.java b/src/tools/cm/dataadapter/code/org/opensplice/cmdataadapter/CmDataException.java index 04dc4c5a7..c9c7ba2ee 100644 --- a/src/tools/cm/dataadapter/code/org/opensplice/cmdataadapter/CmDataException.java +++ b/src/tools/cm/dataadapter/code/org/opensplice/cmdataadapter/CmDataException.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cm/dataadapter/code/org/opensplice/cmdataadapter/CmDataUtil.java b/src/tools/cm/dataadapter/code/org/opensplice/cmdataadapter/CmDataUtil.java index 71a39eacb..9a70f1656 100644 --- a/src/tools/cm/dataadapter/code/org/opensplice/cmdataadapter/CmDataUtil.java +++ b/src/tools/cm/dataadapter/code/org/opensplice/cmdataadapter/CmDataUtil.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cm/dataadapter/code/org/opensplice/cmdataadapter/ComparableTime.java b/src/tools/cm/dataadapter/code/org/opensplice/cmdataadapter/ComparableTime.java index 5b2815807..be32b3f22 100644 --- a/src/tools/cm/dataadapter/code/org/opensplice/cmdataadapter/ComparableTime.java +++ b/src/tools/cm/dataadapter/code/org/opensplice/cmdataadapter/ComparableTime.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cm/dataadapter/code/org/opensplice/cmdataadapter/TypeInfo.java b/src/tools/cm/dataadapter/code/org/opensplice/cmdataadapter/TypeInfo.java index 3ae006216..5ac354998 100644 --- a/src/tools/cm/dataadapter/code/org/opensplice/cmdataadapter/TypeInfo.java +++ b/src/tools/cm/dataadapter/code/org/opensplice/cmdataadapter/TypeInfo.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cm/dataadapter/code/org/opensplice/cmdataadapter/protobuf/ProtobufDataAdapter.java b/src/tools/cm/dataadapter/code/org/opensplice/cmdataadapter/protobuf/ProtobufDataAdapter.java index 9306c214c..40d94544a 100644 --- a/src/tools/cm/dataadapter/code/org/opensplice/cmdataadapter/protobuf/ProtobufDataAdapter.java +++ b/src/tools/cm/dataadapter/code/org/opensplice/cmdataadapter/protobuf/ProtobufDataAdapter.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cm/dataadapter/code/org/opensplice/cmdataadapter/protobuf/ProtobufDataAdapterFactory.java b/src/tools/cm/dataadapter/code/org/opensplice/cmdataadapter/protobuf/ProtobufDataAdapterFactory.java index c356764e8..76f03e8c5 100644 --- a/src/tools/cm/dataadapter/code/org/opensplice/cmdataadapter/protobuf/ProtobufDataAdapterFactory.java +++ b/src/tools/cm/dataadapter/code/org/opensplice/cmdataadapter/protobuf/ProtobufDataAdapterFactory.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cm/dataadapter/code/org/opensplice/cmdataadapter/protobuf/ProtobufDataAdapterImpl.java.dummy b/src/tools/cm/dataadapter/code/org/opensplice/cmdataadapter/protobuf/ProtobufDataAdapterImpl.java.dummy index af48e4068..4b4f3cb38 100644 --- a/src/tools/cm/dataadapter/code/org/opensplice/cmdataadapter/protobuf/ProtobufDataAdapterImpl.java.dummy +++ b/src/tools/cm/dataadapter/code/org/opensplice/cmdataadapter/protobuf/ProtobufDataAdapterImpl.java.dummy @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cm/dataadapter/code/org/opensplice/cmdataadapter/protobuf/ProtobufDataAdapterImpl.java.tmpl b/src/tools/cm/dataadapter/code/org/opensplice/cmdataadapter/protobuf/ProtobufDataAdapterImpl.java.tmpl index bf454d96b..d648066c2 100644 --- a/src/tools/cm/dataadapter/code/org/opensplice/cmdataadapter/protobuf/ProtobufDataAdapterImpl.java.tmpl +++ b/src/tools/cm/dataadapter/code/org/opensplice/cmdataadapter/protobuf/ProtobufDataAdapterImpl.java.tmpl @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cm/dataadapter/code/org/opensplice/cmdataadapter/protobuf/ProtobufFieldProperties.java b/src/tools/cm/dataadapter/code/org/opensplice/cmdataadapter/protobuf/ProtobufFieldProperties.java index 0adb7afc5..a9d46b4d7 100644 --- a/src/tools/cm/dataadapter/code/org/opensplice/cmdataadapter/protobuf/ProtobufFieldProperties.java +++ b/src/tools/cm/dataadapter/code/org/opensplice/cmdataadapter/protobuf/ProtobufFieldProperties.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/conf2c/code/osplconf2c.c b/src/tools/conf2c/code/osplconf2c.c index f646e0ed9..537d536b3 100644 --- a/src/tools/conf2c/code/osplconf2c.c +++ b/src/tools/conf2c/code/osplconf2c.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/code/ast_boxed_value.cpp b/src/tools/cppgen/code/ast_boxed_value.cpp index 607d91bcb..11af96af6 100644 --- a/src/tools/cppgen/code/ast_boxed_value.cpp +++ b/src/tools/cppgen/code/ast_boxed_value.cpp @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/code/ast_hdrs.cpp b/src/tools/cppgen/code/ast_hdrs.cpp index 14b81db84..3245edf68 100644 --- a/src/tools/cppgen/code/ast_hdrs.cpp +++ b/src/tools/cppgen/code/ast_hdrs.cpp @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/code/ast_initializer.cpp b/src/tools/cppgen/code/ast_initializer.cpp index 40b414a93..252227754 100644 --- a/src/tools/cppgen/code/ast_initializer.cpp +++ b/src/tools/cppgen/code/ast_initializer.cpp @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/code/ast_opaque.cpp b/src/tools/cppgen/code/ast_opaque.cpp index d762031dd..a5a0e4338 100644 --- a/src/tools/cppgen/code/ast_opaque.cpp +++ b/src/tools/cppgen/code/ast_opaque.cpp @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/code/ast_statemember.cpp b/src/tools/cppgen/code/ast_statemember.cpp index 2c5327d1e..f3acdd03c 100644 --- a/src/tools/cppgen/code/ast_statemember.cpp +++ b/src/tools/cppgen/code/ast_statemember.cpp @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/code/ast_value.cpp b/src/tools/cppgen/code/ast_value.cpp index fa1cc1ab1..b7437c49c 100644 --- a/src/tools/cppgen/code/ast_value.cpp +++ b/src/tools/cppgen/code/ast_value.cpp @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/code/ast_value_fwd.cpp b/src/tools/cppgen/code/ast_value_fwd.cpp index a44feaa1b..cef862f82 100644 --- a/src/tools/cppgen/code/ast_value_fwd.cpp +++ b/src/tools/cppgen/code/ast_value_fwd.cpp @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/code/cppgen.cpp b/src/tools/cppgen/code/cppgen.cpp index e145d879c..369abb5bd 100644 --- a/src/tools/cppgen/code/cppgen.cpp +++ b/src/tools/cppgen/code/cppgen.cpp @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/code/drv_param.cpp b/src/tools/cppgen/code/drv_param.cpp index d3b9ffaa1..4f193ad8b 100644 --- a/src/tools/cppgen/code/drv_param.cpp +++ b/src/tools/cppgen/code/drv_param.cpp @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/code/fe_cpp_keyword.c b/src/tools/cppgen/code/fe_cpp_keyword.c index 61b2299cb..85ef10aa2 100644 --- a/src/tools/cppgen/code/fe_cpp_keyword.c +++ b/src/tools/cppgen/code/fe_cpp_keyword.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/code/fe_value_header.cpp b/src/tools/cppgen/code/fe_value_header.cpp index 54dc21cf9..43e6eaba9 100644 --- a/src/tools/cppgen/code/fe_value_header.cpp +++ b/src/tools/cppgen/code/fe_value_header.cpp @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/code/fe_value_inheritance_spec.cpp b/src/tools/cppgen/code/fe_value_inheritance_spec.cpp index 596d9120f..b7950c6d5 100644 --- a/src/tools/cppgen/code/fe_value_inheritance_spec.cpp +++ b/src/tools/cppgen/code/fe_value_inheritance_spec.cpp @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/code/std.cpp b/src/tools/cppgen/code/std.cpp index e0a9e1c44..18476304f 100644 --- a/src/tools/cppgen/code/std.cpp +++ b/src/tools/cppgen/code/std.cpp @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/code/utl_pragmas.cpp b/src/tools/cppgen/code/utl_pragmas.cpp index 310caefbf..201c8414d 100644 --- a/src/tools/cppgen/code/utl_pragmas.cpp +++ b/src/tools/cppgen/code/utl_pragmas.cpp @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/code/utl_stack.cpp b/src/tools/cppgen/code/utl_stack.cpp index db40967ca..43a663ca4 100644 --- a/src/tools/cppgen/code/utl_stack.cpp +++ b/src/tools/cppgen/code/utl_stack.cpp @@ -89,7 +89,7 @@ UTL_ScopeStack::UTL_ScopeStack() UTL_ScopeStack::~UTL_ScopeStack() { if (pd_stack_data != NULL) - delete pd_stack_data; + delete [] pd_stack_data; } /* @@ -119,7 +119,7 @@ UTL_ScopeStack::push(UTL_Scope *el) for (i = 0; i < ostack_data_nalloced; i++) tmp[i] = pd_stack_data[i]; - delete pd_stack_data; + delete [] pd_stack_data; pd_stack_data = tmp; } diff --git a/src/tools/cppgen/code/xbe_arglist.cpp b/src/tools/cppgen/code/xbe_arglist.cpp index f94218b61..0c8c1d6cb 100644 --- a/src/tools/cppgen/code/xbe_arglist.cpp +++ b/src/tools/cppgen/code/xbe_arglist.cpp @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/code/xbe_args.cpp b/src/tools/cppgen/code/xbe_args.cpp index 73baa26bd..5c5825701 100644 --- a/src/tools/cppgen/code/xbe_args.cpp +++ b/src/tools/cppgen/code/xbe_args.cpp @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/code/xbe_argument.cpp b/src/tools/cppgen/code/xbe_argument.cpp index 2a5520715..597509a3b 100644 --- a/src/tools/cppgen/code/xbe_argument.cpp +++ b/src/tools/cppgen/code/xbe_argument.cpp @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/code/xbe_argument2.cpp b/src/tools/cppgen/code/xbe_argument2.cpp index 36b3b664a..2cbf7a42a 100644 --- a/src/tools/cppgen/code/xbe_argument2.cpp +++ b/src/tools/cppgen/code/xbe_argument2.cpp @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/code/xbe_array.cpp b/src/tools/cppgen/code/xbe_array.cpp index 88baf37ea..2970260cb 100644 --- a/src/tools/cppgen/code/xbe_array.cpp +++ b/src/tools/cppgen/code/xbe_array.cpp @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/code/xbe_attribute.cpp b/src/tools/cppgen/code/xbe_attribute.cpp index 329479d0c..64df97853 100644 --- a/src/tools/cppgen/code/xbe_attribute.cpp +++ b/src/tools/cppgen/code/xbe_attribute.cpp @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/code/xbe_classes.cpp b/src/tools/cppgen/code/xbe_classes.cpp index e889e74c4..6da72b06c 100644 --- a/src/tools/cppgen/code/xbe_classes.cpp +++ b/src/tools/cppgen/code/xbe_classes.cpp @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/code/xbe_classgen.cpp b/src/tools/cppgen/code/xbe_classgen.cpp index b1b0fa753..d2bbdcc76 100644 --- a/src/tools/cppgen/code/xbe_classgen.cpp +++ b/src/tools/cppgen/code/xbe_classgen.cpp @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/code/xbe_codegen.cpp b/src/tools/cppgen/code/xbe_codegen.cpp index 6d08b1d60..81a7a3620 100644 --- a/src/tools/cppgen/code/xbe_codegen.cpp +++ b/src/tools/cppgen/code/xbe_codegen.cpp @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/code/xbe_constant.cpp b/src/tools/cppgen/code/xbe_constant.cpp index 462cf7df8..57085c72e 100644 --- a/src/tools/cppgen/code/xbe_constant.cpp +++ b/src/tools/cppgen/code/xbe_constant.cpp @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/code/xbe_cppfwd.cpp b/src/tools/cppgen/code/xbe_cppfwd.cpp index ecbc182a1..915dd70db 100644 --- a/src/tools/cppgen/code/xbe_cppfwd.cpp +++ b/src/tools/cppgen/code/xbe_cppfwd.cpp @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/code/xbe_cppname.cpp b/src/tools/cppgen/code/xbe_cppname.cpp index f9dd38f1a..5cc357c8a 100644 --- a/src/tools/cppgen/code/xbe_cppname.cpp +++ b/src/tools/cppgen/code/xbe_cppname.cpp @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/code/xbe_cppscope.cpp b/src/tools/cppgen/code/xbe_cppscope.cpp index b677de271..e6772935a 100644 --- a/src/tools/cppgen/code/xbe_cppscope.cpp +++ b/src/tools/cppgen/code/xbe_cppscope.cpp @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/code/xbe_cpptype.cpp b/src/tools/cppgen/code/xbe_cpptype.cpp index 5fa7ce356..1d4d4e51d 100644 --- a/src/tools/cppgen/code/xbe_cpptype.cpp +++ b/src/tools/cppgen/code/xbe_cpptype.cpp @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/code/xbe_direction.cpp b/src/tools/cppgen/code/xbe_direction.cpp index e8c862990..1bac6e02a 100644 --- a/src/tools/cppgen/code/xbe_direction.cpp +++ b/src/tools/cppgen/code/xbe_direction.cpp @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/code/xbe_dispatchable.cpp b/src/tools/cppgen/code/xbe_dispatchable.cpp index 0ac215de4..be136126e 100644 --- a/src/tools/cppgen/code/xbe_dispatchable.cpp +++ b/src/tools/cppgen/code/xbe_dispatchable.cpp @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/code/xbe_dispatcher.cpp b/src/tools/cppgen/code/xbe_dispatcher.cpp index d4cc5b470..8063f5fdb 100644 --- a/src/tools/cppgen/code/xbe_dispatcher.cpp +++ b/src/tools/cppgen/code/xbe_dispatcher.cpp @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/code/xbe_enum.cpp b/src/tools/cppgen/code/xbe_enum.cpp index 3ae26660e..f9e00bc28 100644 --- a/src/tools/cppgen/code/xbe_enum.cpp +++ b/src/tools/cppgen/code/xbe_enum.cpp @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/code/xbe_exception.cpp b/src/tools/cppgen/code/xbe_exception.cpp index 1d901c43c..25156701a 100644 --- a/src/tools/cppgen/code/xbe_exception.cpp +++ b/src/tools/cppgen/code/xbe_exception.cpp @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/code/xbe_expr_val.cpp b/src/tools/cppgen/code/xbe_expr_val.cpp index b76868a04..8acc28034 100644 --- a/src/tools/cppgen/code/xbe_expr_val.cpp +++ b/src/tools/cppgen/code/xbe_expr_val.cpp @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/code/xbe_field.cpp b/src/tools/cppgen/code/xbe_field.cpp index 20471a15d..c81ab0e25 100644 --- a/src/tools/cppgen/code/xbe_field.cpp +++ b/src/tools/cppgen/code/xbe_field.cpp @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/code/xbe_generator.cpp b/src/tools/cppgen/code/xbe_generator.cpp index 84c17cce5..c26631008 100644 --- a/src/tools/cppgen/code/xbe_generator.cpp +++ b/src/tools/cppgen/code/xbe_generator.cpp @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/code/xbe_genlist.cpp b/src/tools/cppgen/code/xbe_genlist.cpp index 29dca5b33..6b3a170c9 100644 --- a/src/tools/cppgen/code/xbe_genlist.cpp +++ b/src/tools/cppgen/code/xbe_genlist.cpp @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/code/xbe_globals.cpp b/src/tools/cppgen/code/xbe_globals.cpp index 631be7ca1..d99cacab4 100644 --- a/src/tools/cppgen/code/xbe_globals.cpp +++ b/src/tools/cppgen/code/xbe_globals.cpp @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/code/xbe_hash.cpp b/src/tools/cppgen/code/xbe_hash.cpp index 8a01778b5..984c012e4 100644 --- a/src/tools/cppgen/code/xbe_hash.cpp +++ b/src/tools/cppgen/code/xbe_hash.cpp @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/code/xbe_incl.cpp b/src/tools/cppgen/code/xbe_incl.cpp index 63d82a814..711f0a6cc 100644 --- a/src/tools/cppgen/code/xbe_incl.cpp +++ b/src/tools/cppgen/code/xbe_incl.cpp @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/code/xbe_init.cpp b/src/tools/cppgen/code/xbe_init.cpp index d093607c8..d650f4b61 100644 --- a/src/tools/cppgen/code/xbe_init.cpp +++ b/src/tools/cppgen/code/xbe_init.cpp @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/code/xbe_interface.cpp b/src/tools/cppgen/code/xbe_interface.cpp index 2793c95d6..ece09b1d1 100644 --- a/src/tools/cppgen/code/xbe_interface.cpp +++ b/src/tools/cppgen/code/xbe_interface.cpp @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/code/xbe_interface2.cpp b/src/tools/cppgen/code/xbe_interface2.cpp index 7ccf1f0d4..b8f0187ab 100644 --- a/src/tools/cppgen/code/xbe_interface2.cpp +++ b/src/tools/cppgen/code/xbe_interface2.cpp @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/code/xbe_interface3.cpp b/src/tools/cppgen/code/xbe_interface3.cpp index c1c46c3c5..52a39618a 100644 --- a/src/tools/cppgen/code/xbe_interface3.cpp +++ b/src/tools/cppgen/code/xbe_interface3.cpp @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/code/xbe_invoke.cpp b/src/tools/cppgen/code/xbe_invoke.cpp index 1c9e33d89..5ed9e9cb2 100644 --- a/src/tools/cppgen/code/xbe_invoke.cpp +++ b/src/tools/cppgen/code/xbe_invoke.cpp @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/code/xbe_literals.cpp b/src/tools/cppgen/code/xbe_literals.cpp index 4083bb901..de4671aa8 100644 --- a/src/tools/cppgen/code/xbe_literals.cpp +++ b/src/tools/cppgen/code/xbe_literals.cpp @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/code/xbe_module.cpp b/src/tools/cppgen/code/xbe_module.cpp index 382aeba65..83925996f 100644 --- a/src/tools/cppgen/code/xbe_module.cpp +++ b/src/tools/cppgen/code/xbe_module.cpp @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/code/xbe_operation.cpp b/src/tools/cppgen/code/xbe_operation.cpp index 9103ac4d1..633839ea7 100644 --- a/src/tools/cppgen/code/xbe_operation.cpp +++ b/src/tools/cppgen/code/xbe_operation.cpp @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/code/xbe_opnameset.cpp b/src/tools/cppgen/code/xbe_opnameset.cpp index 485307abe..4649d70f9 100644 --- a/src/tools/cppgen/code/xbe_opnameset.cpp +++ b/src/tools/cppgen/code/xbe_opnameset.cpp @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/code/xbe_predefined.cpp b/src/tools/cppgen/code/xbe_predefined.cpp index 633ff14a9..6b98aedee 100644 --- a/src/tools/cppgen/code/xbe_predefined.cpp +++ b/src/tools/cppgen/code/xbe_predefined.cpp @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/code/xbe_produce.cpp b/src/tools/cppgen/code/xbe_produce.cpp index 4e9f0f7b7..dda03ce99 100644 --- a/src/tools/cppgen/code/xbe_produce.cpp +++ b/src/tools/cppgen/code/xbe_produce.cpp @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/code/xbe_root.cpp b/src/tools/cppgen/code/xbe_root.cpp index 653d064b9..0e032452c 100644 --- a/src/tools/cppgen/code/xbe_root.cpp +++ b/src/tools/cppgen/code/xbe_root.cpp @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/code/xbe_sequence.cpp b/src/tools/cppgen/code/xbe_sequence.cpp index 8189075b4..a6b5de938 100644 --- a/src/tools/cppgen/code/xbe_sequence.cpp +++ b/src/tools/cppgen/code/xbe_sequence.cpp @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/code/xbe_source.cpp b/src/tools/cppgen/code/xbe_source.cpp index 61c15df6c..0c0952d15 100644 --- a/src/tools/cppgen/code/xbe_source.cpp +++ b/src/tools/cppgen/code/xbe_source.cpp @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/code/xbe_string.cpp b/src/tools/cppgen/code/xbe_string.cpp index caee64165..c8088ca17 100644 --- a/src/tools/cppgen/code/xbe_string.cpp +++ b/src/tools/cppgen/code/xbe_string.cpp @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/code/xbe_structure.cpp b/src/tools/cppgen/code/xbe_structure.cpp index 074c7faa4..4ebf71f67 100644 --- a/src/tools/cppgen/code/xbe_structure.cpp +++ b/src/tools/cppgen/code/xbe_structure.cpp @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,6 +28,7 @@ #include "xbe_array.h" #include "xbe_utils.h" #include "xbe_root.h" +#include "xbe_enum.h" #include "xbe_sequence.h" #include "xbe_cppfwd.h" #include "xbe_scopestack.h" @@ -771,10 +773,50 @@ void be_structure::Generate (be_ClientHeader& source) for (mit = m_fields.begin(); mit != m_fields.end(); mit++) { field = *mit; - relativeName = field->StructMemberTypeName (); - - ts << tab <<"::std::vector< " << field->StructMemberTypeName() << " > " << field->get_local_name() << "_ = generate_test_values< " - << field->StructMemberTypeName() << " >();" << nl; + be_Type *fieldType = field->get_be_type(); + + /* Find out if member directly or indirectly references an enumeration. + * In that case, the enumeration bound should be established and enforced + * by invoking the properly specialized generate_test_values functions for enums. + */ + + /* If fieldType is sequence or array, then check its element type. */ + while (fieldType->IsArrayType() || fieldType->IsSequenceType()) { + be_typedef *fieldBase = (be_typedef *) fieldType->narrow((long) & be_typedef::type_id); + if (fieldBase) { + fieldType = be_typedef::_beBase(fieldBase); + } + be_array *fieldArr = (be_array *) fieldType->narrow((long) & be_array::type_id); + if (fieldArr) { + fieldType = be_Type::_narrow(fieldArr->base_type()); + } + be_sequence *fieldSeq = (be_sequence *) fieldType->narrow((long) & be_sequence::type_id); + if (fieldSeq) { + fieldType = be_Type::_narrow(fieldSeq->base_type()); + } + } + + /* If memberType is directly or indirectly an enumeration, then determine bound and enforce it + * by invoking specialized generate_test_values functions for enumerations. + */ + if (fieldType->IsEnumeratedType()) { + be_typedef *fieldBase = (be_typedef *) fieldType->narrow((long) & be_typedef::type_id); + if (fieldBase) { + fieldType = be_typedef::_beBase(fieldBase); + } + be_enum * et = (be_enum *) fieldType->narrow((long) & be_enum::type_id); + UTL_ScopeActiveIterator* i = new UTL_ScopeActiveIterator(et, IK_decls); + int nrLabels = 0; + while (!(i->is_done())) { + nrLabels++; + i->next(); + } + ts << tab <<"::std::vector< " << field->StructMemberTypeName() << " > " << field->get_local_name() << "_ = generate_test_values_e< " + << field->StructMemberTypeName() << " >(" << nrLabels << ");" << nl; + } else { + ts << tab <<"::std::vector< " << field->StructMemberTypeName() << " > " << field->get_local_name() << "_ = generate_test_values< " + << field->StructMemberTypeName() << " >();" << nl; + } ts << tab << "if(" << field->get_local_name() << "_.size() > biggest)" << nl << tab << tab << "biggest = " << field->get_local_name() << "_.size();" << nl; diff --git a/src/tools/cppgen/code/xbe_time.cpp b/src/tools/cppgen/code/xbe_time.cpp index e277898a5..ca819d5be 100644 --- a/src/tools/cppgen/code/xbe_time.cpp +++ b/src/tools/cppgen/code/xbe_time.cpp @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/code/xbe_type.cpp b/src/tools/cppgen/code/xbe_type.cpp index abe1fca6c..0ba9e3a5a 100644 --- a/src/tools/cppgen/code/xbe_type.cpp +++ b/src/tools/cppgen/code/xbe_type.cpp @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/code/xbe_typedef.cpp b/src/tools/cppgen/code/xbe_typedef.cpp index 954dbcb3e..2741904c0 100644 --- a/src/tools/cppgen/code/xbe_typedef.cpp +++ b/src/tools/cppgen/code/xbe_typedef.cpp @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/code/xbe_union.cpp b/src/tools/cppgen/code/xbe_union.cpp index f206a8894..5811c4f19 100644 --- a/src/tools/cppgen/code/xbe_union.cpp +++ b/src/tools/cppgen/code/xbe_union.cpp @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/code/xbe_utils.cpp b/src/tools/cppgen/code/xbe_utils.cpp index 5dbbdb9b0..41686a039 100644 --- a/src/tools/cppgen/code/xbe_utils.cpp +++ b/src/tools/cppgen/code/xbe_utils.cpp @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/code/xbe_value.cpp b/src/tools/cppgen/code/xbe_value.cpp index e475e50f5..5191c4f5e 100644 --- a/src/tools/cppgen/code/xbe_value.cpp +++ b/src/tools/cppgen/code/xbe_value.cpp @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/code/xps_string.cpp b/src/tools/cppgen/code/xps_string.cpp index 71ddb56fb..c9c55551b 100644 --- a/src/tools/cppgen/code/xps_string.cpp +++ b/src/tools/cppgen/code/xps_string.cpp @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/code/xps_vector.cpp b/src/tools/cppgen/code/xps_vector.cpp index f4c18f84a..b98ea30b9 100644 --- a/src/tools/cppgen/code/xps_vector.cpp +++ b/src/tools/cppgen/code/xps_vector.cpp @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/include/Std.h b/src/tools/cppgen/include/Std.h index f232a0e48..9ecbe3ab0 100644 --- a/src/tools/cppgen/include/Std.h +++ b/src/tools/cppgen/include/Std.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/include/StdList.h b/src/tools/cppgen/include/StdList.h index 3754a25c7..d50b34ddd 100644 --- a/src/tools/cppgen/include/StdList.h +++ b/src/tools/cppgen/include/StdList.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/include/StdString.h b/src/tools/cppgen/include/StdString.h index 7dd331ff8..b62c8f18a 100644 --- a/src/tools/cppgen/include/StdString.h +++ b/src/tools/cppgen/include/StdString.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/include/ast_boxed_value.h b/src/tools/cppgen/include/ast_boxed_value.h index 4f8d38b48..f135e75f2 100644 --- a/src/tools/cppgen/include/ast_boxed_value.h +++ b/src/tools/cppgen/include/ast_boxed_value.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/include/ast_hdrs.h b/src/tools/cppgen/include/ast_hdrs.h index d657d1316..2c8028c8d 100644 --- a/src/tools/cppgen/include/ast_hdrs.h +++ b/src/tools/cppgen/include/ast_hdrs.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/include/ast_initializer.h b/src/tools/cppgen/include/ast_initializer.h index 3b096b6a7..1236a7487 100644 --- a/src/tools/cppgen/include/ast_initializer.h +++ b/src/tools/cppgen/include/ast_initializer.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/include/ast_state_member.h b/src/tools/cppgen/include/ast_state_member.h index f7f3116e4..24e4034a6 100644 --- a/src/tools/cppgen/include/ast_state_member.h +++ b/src/tools/cppgen/include/ast_state_member.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/include/ast_value.h b/src/tools/cppgen/include/ast_value.h index 2b419eb7e..8f7b7d507 100644 --- a/src/tools/cppgen/include/ast_value.h +++ b/src/tools/cppgen/include/ast_value.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/include/ast_value_fwd.h b/src/tools/cppgen/include/ast_value_fwd.h index 8c0d9f111..6ddebbd25 100644 --- a/src/tools/cppgen/include/ast_value_fwd.h +++ b/src/tools/cppgen/include/ast_value_fwd.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/include/bool.h b/src/tools/cppgen/include/bool.h index 188dbb551..c654931cd 100644 --- a/src/tools/cppgen/include/bool.h +++ b/src/tools/cppgen/include/bool.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/include/cppgen_counter.h b/src/tools/cppgen/include/cppgen_counter.h index 7683f1a36..755bb7a47 100644 --- a/src/tools/cppgen/include/cppgen_counter.h +++ b/src/tools/cppgen/include/cppgen_counter.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/include/cppgen_fstream.h b/src/tools/cppgen/include/cppgen_fstream.h index b08ad2ffb..1db56b3db 100644 --- a/src/tools/cppgen/include/cppgen_fstream.h +++ b/src/tools/cppgen/include/cppgen_fstream.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/include/cppgen_if.h b/src/tools/cppgen/include/cppgen_if.h index ff2965628..3c2877429 100644 --- a/src/tools/cppgen/include/cppgen_if.h +++ b/src/tools/cppgen/include/cppgen_if.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/include/cppgen_iostream.h b/src/tools/cppgen/include/cppgen_iostream.h index 3b5327177..8a3be9ceb 100644 --- a/src/tools/cppgen/include/cppgen_iostream.h +++ b/src/tools/cppgen/include/cppgen_iostream.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/include/cppgen_string.h b/src/tools/cppgen/include/cppgen_string.h index ecc175a86..bd0642fbf 100644 --- a/src/tools/cppgen/include/cppgen_string.h +++ b/src/tools/cppgen/include/cppgen_string.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/include/fe_value_header.h b/src/tools/cppgen/include/fe_value_header.h index f84c0c507..014e258fc 100644 --- a/src/tools/cppgen/include/fe_value_header.h +++ b/src/tools/cppgen/include/fe_value_header.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/include/fe_value_inheritance_spec.h b/src/tools/cppgen/include/fe_value_inheritance_spec.h index f008cc4c0..5cf139c36 100644 --- a/src/tools/cppgen/include/fe_value_inheritance_spec.h +++ b/src/tools/cppgen/include/fe_value_inheritance_spec.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/include/prototc.h b/src/tools/cppgen/include/prototc.h index 702759c49..c52ef7981 100644 --- a/src/tools/cppgen/include/prototc.h +++ b/src/tools/cppgen/include/prototc.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/include/tlist.h b/src/tools/cppgen/include/tlist.h index b07505078..dbb29897a 100644 --- a/src/tools/cppgen/include/tlist.h +++ b/src/tools/cppgen/include/tlist.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/include/utl_hash.h b/src/tools/cppgen/include/utl_hash.h index 4713a13bd..bfbaf11aa 100644 --- a/src/tools/cppgen/include/utl_hash.h +++ b/src/tools/cppgen/include/utl_hash.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/include/utl_hdrs.h b/src/tools/cppgen/include/utl_hdrs.h index d657d1316..2c8028c8d 100644 --- a/src/tools/cppgen/include/utl_hdrs.h +++ b/src/tools/cppgen/include/utl_hdrs.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/include/utl_incl.h b/src/tools/cppgen/include/utl_incl.h index 7e9e89a3c..8118d2e9b 100644 --- a/src/tools/cppgen/include/utl_incl.h +++ b/src/tools/cppgen/include/utl_incl.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/include/utl_pragmas.h b/src/tools/cppgen/include/utl_pragmas.h index 351371d71..1f708956d 100644 --- a/src/tools/cppgen/include/utl_pragmas.h +++ b/src/tools/cppgen/include/utl_pragmas.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/include/xbe.h b/src/tools/cppgen/include/xbe.h index 692c8c8d5..0e0f841eb 100644 --- a/src/tools/cppgen/include/xbe.h +++ b/src/tools/cppgen/include/xbe.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/include/xbe_arglist.h b/src/tools/cppgen/include/xbe_arglist.h index 74fdd02ae..69ad471e6 100644 --- a/src/tools/cppgen/include/xbe_arglist.h +++ b/src/tools/cppgen/include/xbe_arglist.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/include/xbe_argument.h b/src/tools/cppgen/include/xbe_argument.h index bcad57e6a..0969e8c0c 100644 --- a/src/tools/cppgen/include/xbe_argument.h +++ b/src/tools/cppgen/include/xbe_argument.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/include/xbe_argument2.h b/src/tools/cppgen/include/xbe_argument2.h index 12a1c47f4..6f6bcf7c7 100644 --- a/src/tools/cppgen/include/xbe_argument2.h +++ b/src/tools/cppgen/include/xbe_argument2.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/include/xbe_array.h b/src/tools/cppgen/include/xbe_array.h index 6d1cb9533..02dda2859 100644 --- a/src/tools/cppgen/include/xbe_array.h +++ b/src/tools/cppgen/include/xbe_array.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/include/xbe_attribute.h b/src/tools/cppgen/include/xbe_attribute.h index 9ec3442e6..5387d7ea6 100644 --- a/src/tools/cppgen/include/xbe_attribute.h +++ b/src/tools/cppgen/include/xbe_attribute.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/include/xbe_classes.h b/src/tools/cppgen/include/xbe_classes.h index 044056d11..ddd6ad653 100644 --- a/src/tools/cppgen/include/xbe_classes.h +++ b/src/tools/cppgen/include/xbe_classes.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/include/xbe_classgen.h b/src/tools/cppgen/include/xbe_classgen.h index a3fe4d3ac..816a2a7ff 100644 --- a/src/tools/cppgen/include/xbe_classgen.h +++ b/src/tools/cppgen/include/xbe_classgen.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/include/xbe_codegen.h b/src/tools/cppgen/include/xbe_codegen.h index 44fa59f19..80ec10267 100644 --- a/src/tools/cppgen/include/xbe_codegen.h +++ b/src/tools/cppgen/include/xbe_codegen.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/include/xbe_constant.h b/src/tools/cppgen/include/xbe_constant.h index 91020ef36..b27412c5f 100644 --- a/src/tools/cppgen/include/xbe_constant.h +++ b/src/tools/cppgen/include/xbe_constant.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/include/xbe_cppfwd.h b/src/tools/cppgen/include/xbe_cppfwd.h index 80e0e901c..7a6d1f0a2 100644 --- a/src/tools/cppgen/include/xbe_cppfwd.h +++ b/src/tools/cppgen/include/xbe_cppfwd.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/include/xbe_cppname.h b/src/tools/cppgen/include/xbe_cppname.h index 10c14f98b..a09046c58 100644 --- a/src/tools/cppgen/include/xbe_cppname.h +++ b/src/tools/cppgen/include/xbe_cppname.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/include/xbe_cppscope.h b/src/tools/cppgen/include/xbe_cppscope.h index 4e9561cb1..834c5c6bb 100644 --- a/src/tools/cppgen/include/xbe_cppscope.h +++ b/src/tools/cppgen/include/xbe_cppscope.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/include/xbe_cpptype.h b/src/tools/cppgen/include/xbe_cpptype.h index 2e7f86b70..541d7dfe0 100644 --- a/src/tools/cppgen/include/xbe_cpptype.h +++ b/src/tools/cppgen/include/xbe_cpptype.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/include/xbe_direction.h b/src/tools/cppgen/include/xbe_direction.h index 215e614bb..6ab81668d 100644 --- a/src/tools/cppgen/include/xbe_direction.h +++ b/src/tools/cppgen/include/xbe_direction.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/include/xbe_dispatchable.h b/src/tools/cppgen/include/xbe_dispatchable.h index 0559fcebf..680f08a2d 100644 --- a/src/tools/cppgen/include/xbe_dispatchable.h +++ b/src/tools/cppgen/include/xbe_dispatchable.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/include/xbe_dispatcher.h b/src/tools/cppgen/include/xbe_dispatcher.h index 7a4bd0a20..416e9232e 100644 --- a/src/tools/cppgen/include/xbe_dispatcher.h +++ b/src/tools/cppgen/include/xbe_dispatcher.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/include/xbe_enum.h b/src/tools/cppgen/include/xbe_enum.h index 22fa97eb2..a0abfa171 100644 --- a/src/tools/cppgen/include/xbe_enum.h +++ b/src/tools/cppgen/include/xbe_enum.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/include/xbe_exception.h b/src/tools/cppgen/include/xbe_exception.h index 40e32cc39..81eff15b5 100644 --- a/src/tools/cppgen/include/xbe_exception.h +++ b/src/tools/cppgen/include/xbe_exception.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/include/xbe_exceptionlist.h b/src/tools/cppgen/include/xbe_exceptionlist.h index 0e83f6b1b..fd193b2d0 100644 --- a/src/tools/cppgen/include/xbe_exceptionlist.h +++ b/src/tools/cppgen/include/xbe_exceptionlist.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/include/xbe_expr_val.h b/src/tools/cppgen/include/xbe_expr_val.h index c414f0cff..85834b0a4 100644 --- a/src/tools/cppgen/include/xbe_expr_val.h +++ b/src/tools/cppgen/include/xbe_expr_val.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/include/xbe_field.h b/src/tools/cppgen/include/xbe_field.h index bce17e421..c2556df4f 100644 --- a/src/tools/cppgen/include/xbe_field.h +++ b/src/tools/cppgen/include/xbe_field.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/include/xbe_generator.h b/src/tools/cppgen/include/xbe_generator.h index 84e952c03..57dc0789d 100644 --- a/src/tools/cppgen/include/xbe_generator.h +++ b/src/tools/cppgen/include/xbe_generator.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/include/xbe_genlist.h b/src/tools/cppgen/include/xbe_genlist.h index 6e80f738b..d7915d863 100644 --- a/src/tools/cppgen/include/xbe_genlist.h +++ b/src/tools/cppgen/include/xbe_genlist.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/include/xbe_globals.h b/src/tools/cppgen/include/xbe_globals.h index 495b4ef9a..99f813536 100644 --- a/src/tools/cppgen/include/xbe_globals.h +++ b/src/tools/cppgen/include/xbe_globals.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/include/xbe_hash.h b/src/tools/cppgen/include/xbe_hash.h index b456d9128..eb300dd84 100644 --- a/src/tools/cppgen/include/xbe_hash.h +++ b/src/tools/cppgen/include/xbe_hash.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/include/xbe_incl.h b/src/tools/cppgen/include/xbe_incl.h index a1684a31f..13f360ead 100644 --- a/src/tools/cppgen/include/xbe_incl.h +++ b/src/tools/cppgen/include/xbe_incl.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/include/xbe_interface.h b/src/tools/cppgen/include/xbe_interface.h index 047101e11..794b185ff 100644 --- a/src/tools/cppgen/include/xbe_interface.h +++ b/src/tools/cppgen/include/xbe_interface.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/include/xbe_invoke.h b/src/tools/cppgen/include/xbe_invoke.h index cca4de8f9..58fba42e4 100644 --- a/src/tools/cppgen/include/xbe_invoke.h +++ b/src/tools/cppgen/include/xbe_invoke.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/include/xbe_literals.h b/src/tools/cppgen/include/xbe_literals.h index f19e96801..6394e94a5 100644 --- a/src/tools/cppgen/include/xbe_literals.h +++ b/src/tools/cppgen/include/xbe_literals.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/include/xbe_module.h b/src/tools/cppgen/include/xbe_module.h index 34da6792d..3b0250d8a 100644 --- a/src/tools/cppgen/include/xbe_module.h +++ b/src/tools/cppgen/include/xbe_module.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/include/xbe_operation.h b/src/tools/cppgen/include/xbe_operation.h index 6bd96c110..b0b489dd5 100644 --- a/src/tools/cppgen/include/xbe_operation.h +++ b/src/tools/cppgen/include/xbe_operation.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/include/xbe_opnameset.h b/src/tools/cppgen/include/xbe_opnameset.h index 5655fa126..f8a5bead0 100644 --- a/src/tools/cppgen/include/xbe_opnameset.h +++ b/src/tools/cppgen/include/xbe_opnameset.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/include/xbe_predefined.h b/src/tools/cppgen/include/xbe_predefined.h index 1106b93ee..a81070490 100644 --- a/src/tools/cppgen/include/xbe_predefined.h +++ b/src/tools/cppgen/include/xbe_predefined.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/include/xbe_root.h b/src/tools/cppgen/include/xbe_root.h index eba02230d..07e099beb 100644 --- a/src/tools/cppgen/include/xbe_root.h +++ b/src/tools/cppgen/include/xbe_root.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/include/xbe_scopestack.h b/src/tools/cppgen/include/xbe_scopestack.h index 02b2cc415..83212a540 100644 --- a/src/tools/cppgen/include/xbe_scopestack.h +++ b/src/tools/cppgen/include/xbe_scopestack.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/include/xbe_sequence.h b/src/tools/cppgen/include/xbe_sequence.h index f516faee5..59e19c34c 100644 --- a/src/tools/cppgen/include/xbe_sequence.h +++ b/src/tools/cppgen/include/xbe_sequence.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/include/xbe_source.h b/src/tools/cppgen/include/xbe_source.h index 9911311ac..3141ef68d 100644 --- a/src/tools/cppgen/include/xbe_source.h +++ b/src/tools/cppgen/include/xbe_source.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/include/xbe_string.h b/src/tools/cppgen/include/xbe_string.h index 7043a3e96..bb4de427e 100644 --- a/src/tools/cppgen/include/xbe_string.h +++ b/src/tools/cppgen/include/xbe_string.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/include/xbe_structure.h b/src/tools/cppgen/include/xbe_structure.h index a14e8c1d4..9d19f43d6 100644 --- a/src/tools/cppgen/include/xbe_structure.h +++ b/src/tools/cppgen/include/xbe_structure.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/include/xbe_time.h b/src/tools/cppgen/include/xbe_time.h index e859f9132..57e965825 100644 --- a/src/tools/cppgen/include/xbe_time.h +++ b/src/tools/cppgen/include/xbe_time.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/include/xbe_type.h b/src/tools/cppgen/include/xbe_type.h index 685c8bb11..675cb1be4 100644 --- a/src/tools/cppgen/include/xbe_type.h +++ b/src/tools/cppgen/include/xbe_type.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/include/xbe_typedef.h b/src/tools/cppgen/include/xbe_typedef.h index aaae2efed..b4b9bd96f 100644 --- a/src/tools/cppgen/include/xbe_typedef.h +++ b/src/tools/cppgen/include/xbe_typedef.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/include/xbe_typemap.h b/src/tools/cppgen/include/xbe_typemap.h index d6a6feb4d..ab3494b3e 100644 --- a/src/tools/cppgen/include/xbe_typemap.h +++ b/src/tools/cppgen/include/xbe_typemap.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/include/xbe_union.h b/src/tools/cppgen/include/xbe_union.h index ef3240ed7..f7ba70008 100644 --- a/src/tools/cppgen/include/xbe_union.h +++ b/src/tools/cppgen/include/xbe_union.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/include/xbe_utils.h b/src/tools/cppgen/include/xbe_utils.h index 40f611be1..7a8ef54ee 100644 --- a/src/tools/cppgen/include/xbe_utils.h +++ b/src/tools/cppgen/include/xbe_utils.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/include/xbe_value.h b/src/tools/cppgen/include/xbe_value.h index 0924f2a45..689908339 100644 --- a/src/tools/cppgen/include/xbe_value.h +++ b/src/tools/cppgen/include/xbe_value.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/include/xps_string.h b/src/tools/cppgen/include/xps_string.h index 128f74730..236b46be4 100644 --- a/src/tools/cppgen/include/xps_string.h +++ b/src/tools/cppgen/include/xps_string.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/cppgen/include/xps_vector.h b/src/tools/cppgen/include/xps_vector.h index 4ac6a4487..086b2b1b3 100644 --- a/src/tools/cppgen/include/xps_vector.h +++ b/src/tools/cppgen/include/xps_vector.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/dat/aapi/code/a_anl.c b/src/tools/dat/aapi/code/a_anl.c index d5e9c525c..5b130e101 100644 --- a/src/tools/dat/aapi/code/a_anl.c +++ b/src/tools/dat/aapi/code/a_anl.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/dat/aapi/code/a_api.c b/src/tools/dat/aapi/code/a_api.c index 9bf9afbe7..4bb69ab48 100644 --- a/src/tools/dat/aapi/code/a_api.c +++ b/src/tools/dat/aapi/code/a_api.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/dat/aapi/code/a_bse.c b/src/tools/dat/aapi/code/a_bse.c index b163122f2..61525c278 100644 --- a/src/tools/dat/aapi/code/a_bse.c +++ b/src/tools/dat/aapi/code/a_bse.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/dat/aapi/code/a_fil.c b/src/tools/dat/aapi/code/a_fil.c index 9e33de37c..0c3a1f48c 100644 --- a/src/tools/dat/aapi/code/a_fil.c +++ b/src/tools/dat/aapi/code/a_fil.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/dat/aapi/code/a_hex.c b/src/tools/dat/aapi/code/a_hex.c index 7283e1f16..5a616128c 100644 --- a/src/tools/dat/aapi/code/a_hex.c +++ b/src/tools/dat/aapi/code/a_hex.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/dat/aapi/code/a_hsh.c b/src/tools/dat/aapi/code/a_hsh.c index 4ce5c5eb7..03162c3f6 100644 --- a/src/tools/dat/aapi/code/a_hsh.c +++ b/src/tools/dat/aapi/code/a_hsh.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/dat/aapi/code/a_key.c b/src/tools/dat/aapi/code/a_key.c index fd5be598c..c645bbf16 100644 --- a/src/tools/dat/aapi/code/a_key.c +++ b/src/tools/dat/aapi/code/a_key.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/dat/aapi/code/a_lst.c b/src/tools/dat/aapi/code/a_lst.c index c6c218648..0d4ed269b 100644 --- a/src/tools/dat/aapi/code/a_lst.c +++ b/src/tools/dat/aapi/code/a_lst.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/dat/aapi/code/a_mem.c b/src/tools/dat/aapi/code/a_mem.c index b727791cc..e114fb348 100644 --- a/src/tools/dat/aapi/code/a_mem.c +++ b/src/tools/dat/aapi/code/a_mem.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/dat/aapi/code/a_shm.c b/src/tools/dat/aapi/code/a_shm.c index 7eb360339..c6b2ee1f6 100644 --- a/src/tools/dat/aapi/code/a_shm.c +++ b/src/tools/dat/aapi/code/a_shm.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/dat/aapi/code/a_sts.c b/src/tools/dat/aapi/code/a_sts.c index 64f4c0c1a..3b1231e84 100644 --- a/src/tools/dat/aapi/code/a_sts.c +++ b/src/tools/dat/aapi/code/a_sts.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/dat/aapi/code/a_tre.c b/src/tools/dat/aapi/code/a_tre.c index 8ea02efa0..1bd1072ed 100644 --- a/src/tools/dat/aapi/code/a_tre.c +++ b/src/tools/dat/aapi/code/a_tre.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/dat/aapi/code/a_utl.c b/src/tools/dat/aapi/code/a_utl.c index 7f6cc5fa2..8638825d1 100644 --- a/src/tools/dat/aapi/code/a_utl.c +++ b/src/tools/dat/aapi/code/a_utl.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/dat/aapi/include/a_anl.h b/src/tools/dat/aapi/include/a_anl.h index fe3d7061c..d3462e8d6 100644 --- a/src/tools/dat/aapi/include/a_anl.h +++ b/src/tools/dat/aapi/include/a_anl.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/dat/aapi/include/a_api.h b/src/tools/dat/aapi/include/a_api.h index f575dbb4d..8402adaaf 100644 --- a/src/tools/dat/aapi/include/a_api.h +++ b/src/tools/dat/aapi/include/a_api.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/dat/aapi/include/a_bse.h b/src/tools/dat/aapi/include/a_bse.h index 8408f5799..f0b8aaac7 100644 --- a/src/tools/dat/aapi/include/a_bse.h +++ b/src/tools/dat/aapi/include/a_bse.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/dat/aapi/include/a_def.h b/src/tools/dat/aapi/include/a_def.h index 0ce3598ae..5e2cf0b39 100644 --- a/src/tools/dat/aapi/include/a_def.h +++ b/src/tools/dat/aapi/include/a_def.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/dat/aapi/include/a_fil.h b/src/tools/dat/aapi/include/a_fil.h index 5ff9c6564..787c698eb 100644 --- a/src/tools/dat/aapi/include/a_fil.h +++ b/src/tools/dat/aapi/include/a_fil.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/dat/aapi/include/a_hex.h b/src/tools/dat/aapi/include/a_hex.h index 51a207b17..3bba689f1 100644 --- a/src/tools/dat/aapi/include/a_hex.h +++ b/src/tools/dat/aapi/include/a_hex.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/dat/aapi/include/a_hsh.h b/src/tools/dat/aapi/include/a_hsh.h index 924f57b9f..7a40f068d 100644 --- a/src/tools/dat/aapi/include/a_hsh.h +++ b/src/tools/dat/aapi/include/a_hsh.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/dat/aapi/include/a_key.h b/src/tools/dat/aapi/include/a_key.h index be6a006be..092e9ede1 100644 --- a/src/tools/dat/aapi/include/a_key.h +++ b/src/tools/dat/aapi/include/a_key.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/dat/aapi/include/a_lst.h b/src/tools/dat/aapi/include/a_lst.h index fd92b1344..a2d268f8d 100644 --- a/src/tools/dat/aapi/include/a_lst.h +++ b/src/tools/dat/aapi/include/a_lst.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/dat/aapi/include/a_mem.h b/src/tools/dat/aapi/include/a_mem.h index 33ba2952a..5f0350d2b 100644 --- a/src/tools/dat/aapi/include/a_mem.h +++ b/src/tools/dat/aapi/include/a_mem.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/dat/aapi/include/a_shm.h b/src/tools/dat/aapi/include/a_shm.h index 8d0f4a2d6..eb592ce2e 100644 --- a/src/tools/dat/aapi/include/a_shm.h +++ b/src/tools/dat/aapi/include/a_shm.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/dat/aapi/include/a_sts.h b/src/tools/dat/aapi/include/a_sts.h index 0b465d5ff..8b7faabec 100644 --- a/src/tools/dat/aapi/include/a_sts.h +++ b/src/tools/dat/aapi/include/a_sts.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/dat/aapi/include/a_utl.h b/src/tools/dat/aapi/include/a_utl.h index fe49b2e33..73ae3e5e7 100644 --- a/src/tools/dat/aapi/include/a_utl.h +++ b/src/tools/dat/aapi/include/a_utl.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/dat/dat/code/d_utl.c b/src/tools/dat/dat/code/d_utl.c index 7d5f6fc8c..de2cc92ae 100644 --- a/src/tools/dat/dat/code/d_utl.c +++ b/src/tools/dat/dat/code/d_utl.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/dat/dat/code/d_utl.h b/src/tools/dat/dat/code/d_utl.h index 87f76f649..04761fda0 100644 --- a/src/tools/dat/dat/code/d_utl.h +++ b/src/tools/dat/dat/code/d_utl.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/dat/dat/code/dat.c b/src/tools/dat/dat/code/dat.c index e82f68451..8f0cdadc6 100644 --- a/src/tools/dat/dat/code/dat.c +++ b/src/tools/dat/dat/code/dat.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/debug/common/code/dbg_common.c b/src/tools/debug/common/code/dbg_common.c index c8d2f7381..6fab4758e 100644 --- a/src/tools/debug/common/code/dbg_common.c +++ b/src/tools/debug/common/code/dbg_common.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -108,7 +109,6 @@ printCollection( switch (type->kind) { case OSPL_C_ARRAY: case OSPL_C_SEQUENCE: - /* Walk over all entries */ switch (type->kind) { case OSPL_C_ARRAY: if (type->maxSize == 0) { @@ -432,10 +432,11 @@ printUnion( os_size_t dataOffset; o = c_iterObject(actionData->stack, 0); - /* action for the union itself */ - /* No action, but separate actions for the switch and the data */ - /* action(c_type(v_union), o, actionArg); */ - /* action for the switch */ + /* action for the union itself + * No action, but separate actions for the switch and the data + * action(c_type(v_union), o, actionArg); + * action for the switch + */ printType(v_union->switchType, actionData); printf(": "); diff --git a/src/tools/debug/dbd/code/dbd.c b/src/tools/debug/dbd/code/dbd.c index 4c8f477ef..a78967b83 100644 --- a/src/tools/debug/dbd/code/dbd.c +++ b/src/tools/debug/dbd/code/dbd.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -50,6 +51,7 @@ static void scan_object(v_public public, c_voidp arg); static void resolve_type(v_public public, c_voidp arg); static void trace_object(v_public public, c_voidp arg); static void trace_type(v_public public, c_voidp arg); +static void enable_statistics(v_public public, c_voidp arg); static void print_usage() { @@ -79,6 +81,7 @@ static void print_usage() printf("dbd> R type /* resolve type */\n"); printf("dbd> trace /* trace free/keep of object at */\n"); printf("dbd> tracetype /* set trace on new objects of type */\n"); + printf("dbd> stat /* enable statistics on entity */\n"); printf("dbd> q /* quit */\n"); printf("Example:\n"); printf("dbd> 0x200a2df8 /* Print content of shm address */\n"); @@ -472,6 +475,12 @@ OPENSPLICE_MAIN(ospl_dbd) tgt->act(tgt, toolAction, addr); c_iterTake(history, addr); /* remove if already exist */ history = c_iterInsert(history, addr); + } else if (strcmp(ws[0].buf, "stat") == 0) { + if (gwaddr(&addr, ws[1])) { + tgt->act(tgt, enable_statistics, addr); + } else { + printf("usage: stat
    \n"); + } } else { print_usage(); } @@ -943,16 +952,14 @@ static void lookupWritersAction(v_public entity, c_voidp arg) list = NULL; switch (v_objectKind(o)) { case K_GROUP: - /* v_groupWalkWriters(o, lookupWriter, - * &list); */ + /* TODO : Implement lookup writer for group */ printf("Lookup writer for Group not yet implemented\n"); break; case K_DOMAIN: glist = v_groupSetLookup(kernel->groupSet, v_partitionName(o), "*"); g = c_iterTakeFirst(glist); while (g != NULL) { - /* v_groupWalkWriters(g, - * lookupWriter, &list); */ + /* TODO : Implement lookup writer for partition */ printf("Lookup writer for Partition not yet implemented\n"); c_free(g); g = c_iterTakeFirst(glist); @@ -963,8 +970,7 @@ static void lookupWritersAction(v_public entity, c_voidp arg) glist = v_groupSetLookup(kernel->groupSet, "*", v_topicName(o)); g = c_iterTakeFirst(glist); while (g != NULL) { - /* v_groupWalkWriters(g, - * lookupWriter, &list); */ + /* TODO : Implement lookup writer for Topic*/ printf("Lookup writer for Topic not yet implemented\n"); c_free(g); g = c_iterTakeFirst(glist); @@ -1298,3 +1304,35 @@ static void trace_type(v_public public, c_voidp arg) c_baseTraceObjectsOfType(o); } } + +#include "v_dataReader.h" +#include "v_dataReaderStatistics.h" +#include "v_writer.h" +#include "v_writerStatistics.h" +#include "v_durability.h" +#include "v_durabilityStatistics.h" + +static void enable_statistics(v_public public, c_voidp arg) +{ + v_entity entity = v_entity(public); + c_base base = c_getBase(entity); + c_object o = c_baseCheckPtr(base, arg); + if (o == NULL) { + printf("Given address 0x%" PA_PRIxADDR " is not a database object\n", (os_address)arg); + } else { + switch (v_objectKind(arg)) { + case K_DATAREADER: + v_dataReader(arg)->statistics = v_dataReaderStatisticsNew(v_objectKernel(arg)); + break; + case K_WRITER: + v_writer(arg)->statistics = v_writerStatisticsNew(v_objectKernel(arg)); + break; + case K_DURABILITY: + v_durability(arg)->statistics = v_durabilityStatisticsNew(v_objectKernel(arg)); + break; + default: + printf("sorry; enabling statistics for this entity kind is usupported\n"); + break; + } + } +} diff --git a/src/tools/idlpp/code/idl__genSajMeta.h b/src/tools/idlpp/code/idl__genSajMeta.h index 104c1cd87..35540e6d9 100644 --- a/src/tools/idlpp/code/idl__genSajMeta.h +++ b/src/tools/idlpp/code/idl__genSajMeta.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/idlpp/code/idl_base.l b/src/tools/idlpp/code/idl_base.l index 2171c24e6..b34ff2013 100644 --- a/src/tools/idlpp/code/idl_base.l +++ b/src/tools/idlpp/code/idl_base.l @@ -368,6 +368,7 @@ preprocessor_directive(char *str) } idl_checkKeyListFieldName(mo, fieldName, yyerror); strcat(valueString, fieldName); + os_free(fieldName); if (c_iterLength(pragmaItems)) { strcat(valueString, ","); } @@ -395,6 +396,7 @@ preprocessor_directive(char *str) } idl_checkSimpleFieldName(mo, fieldName, yyerror); strcat(valueString, fieldName); + os_free(fieldName); if (c_iterLength(pragmaItems)) { strcat(valueString, ","); } @@ -424,13 +426,10 @@ preprocessor_directive(char *str) } idl_checkSimpleFieldName(mo, fieldName, yyerror); strcat(valueString, fieldName); + os_free(fieldName); if (c_iterLength(pragmaItems)) { strcat(valueString, ","); } - if(newFieldName){ - os_free(newFieldName); - newFieldName = NULL; - } } } idl_stacDefAdd (idl_stacDefDefGet(), scope, typeName, valueString); diff --git a/src/tools/idlpp/code/idl_base.y b/src/tools/idlpp/code/idl_base.y index 7a784da1a..36cfcbf71 100644 --- a/src/tools/idlpp/code/idl_base.y +++ b/src/tools/idlpp/code/idl_base.y @@ -110,13 +110,6 @@ declareTypeDefs( c_metaObject scope, c_iter typeDefs); -#if 0 -static void -declareAttributes( - c_metaObject scope, - c_iter attributes); -#endif - static void declareType( c_metaObject scope, @@ -2049,23 +2042,6 @@ declareTypeDefs( } } -#if 0 -static void -declareAttributes( - c_metaObject scope, - c_iter attributes) -{ - c_attribute attribute; - - attribute = c_iterTakeFirst(attributes); - while (attribute != NULL) { - declareIfArray(scope, c_property(attribute)->type); - c_free(attribute); - attribute = c_iterTakeFirst(attributes); - } -} -#endif - static void declareType( c_metaObject scope, diff --git a/src/tools/idlpp/code/idl_catsDef.c b/src/tools/idlpp/code/idl_catsDef.c index c8c0889bd..ed6410b8a 100644 --- a/src/tools/idlpp/code/idl_catsDef.c +++ b/src/tools/idlpp/code/idl_catsDef.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -73,8 +74,8 @@ idl_catsDefFindMemberIndexByName( const os_char* name); /* Create a new cats map specified by scope, - type name and catslist -*/ + * type name and catslist + */ static idl_catsMap idl_catsMapNew ( const c_metaObject scope, @@ -142,9 +143,7 @@ idl_catsDefAdd ( } } -/* - * Check if there is a cats applied to the given key. - */ +/* Check if there is a cats applied to the given key. */ c_bool idl_isCatsDefFor( c_metaObject scope, @@ -247,8 +246,8 @@ idl_catsListItemIsMemberLocated( } /* Find the cats list related to the specified typename in - the specified scope -*/ + * the specified scope + */ os_boolean idl_catsListItemIsDefined ( idl_catsDef catsDef, @@ -312,8 +311,8 @@ idl_catsListItemIsDefined ( { /* the typeScope has reached the bottom too, * thus the scopes are equal - */ - /* If no members were defined for this type, then we will + * + * If no members were defined for this type, then we will * interprete this as a request for all char array * members to be converted to a string internally. */ diff --git a/src/tools/idlpp/code/idl_catsDef.h b/src/tools/idlpp/code/idl_catsDef.h index d51cc4c7f..1ace9188a 100644 --- a/src/tools/idlpp/code/idl_catsDef.h +++ b/src/tools/idlpp/code/idl_catsDef.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/idlpp/code/idl_constSpecifier.c b/src/tools/idlpp/code/idl_constSpecifier.c index 643febd6e..ba44e9c57 100644 --- a/src/tools/idlpp/code/idl_constSpecifier.c +++ b/src/tools/idlpp/code/idl_constSpecifier.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -306,14 +307,17 @@ idl_constOperandImage ( image = idl_scopeStackLanguage( idl_constSpecScopeGet(constOperand->constSpec), idl_constSpecName(constOperand->constSpec)); - getter = idl_genLanguageConstGetter(); - if (getter) { - tmp = os_malloc(strlen(image) + strlen(getter) + 1); - os_strcpy(tmp, image); - os_strcat(tmp, getter); - os_free(getter); - os_free(image); - image = tmp; + if (idl_typeSpecType(idl_constSpecTypeGet(constOperand->constSpec)) != idl_tenum || + idl_constSpecOperandGet(constOperand->constSpec)->kind != idl_cLit) { + getter = idl_genLanguageConstGetter(); + if (getter) { + tmp = os_malloc(strlen(image) + strlen(getter) + 1); + os_strcpy(tmp, image); + os_strcat(tmp, getter); + os_free(getter); + os_free(image); + image = tmp; + } } return image; diff --git a/src/tools/idlpp/code/idl_constSpecifier.h b/src/tools/idlpp/code/idl_constSpecifier.h index 4114384ac..bcb40ed4b 100644 --- a/src/tools/idlpp/code/idl_constSpecifier.h +++ b/src/tools/idlpp/code/idl_constSpecifier.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/idlpp/code/idl_databaseValidation.c b/src/tools/idlpp/code/idl_databaseValidation.c index 147fcbaeb..0d7bf5908 100644 --- a/src/tools/idlpp/code/idl_databaseValidation.c +++ b/src/tools/idlpp/code/idl_databaseValidation.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/idlpp/code/idl_databaseValidation.h b/src/tools/idlpp/code/idl_databaseValidation.h index 2701ef423..62ffb5cfc 100644 --- a/src/tools/idlpp/code/idl_databaseValidation.h +++ b/src/tools/idlpp/code/idl_databaseValidation.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/idlpp/code/idl_dependencies.c b/src/tools/idlpp/code/idl_dependencies.c index 76ce2e136..e80de36b4 100644 --- a/src/tools/idlpp/code/idl_dependencies.c +++ b/src/tools/idlpp/code/idl_dependencies.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/idlpp/code/idl_dependencies.h b/src/tools/idlpp/code/idl_dependencies.h index 79db05d91..0c089973f 100644 --- a/src/tools/idlpp/code/idl_dependencies.h +++ b/src/tools/idlpp/code/idl_dependencies.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/idlpp/code/idl_dll.c b/src/tools/idlpp/code/idl_dll.c index 74e897364..1cc600a88 100644 --- a/src/tools/idlpp/code/idl_dll.c +++ b/src/tools/idlpp/code/idl_dll.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/idlpp/code/idl_dll.h b/src/tools/idlpp/code/idl_dll.h index 73cba0c39..702e75217 100644 --- a/src/tools/idlpp/code/idl_dll.h +++ b/src/tools/idlpp/code/idl_dll.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/idlpp/code/idl_fileMap.c b/src/tools/idlpp/code/idl_fileMap.c index 8925c4da6..0da2b3739 100644 --- a/src/tools/idlpp/code/idl_fileMap.c +++ b/src/tools/idlpp/code/idl_fileMap.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -36,9 +37,9 @@ C_STRUCT(idl_fileMap) { }; /* "idl_file" registers all meta objects related to a file, - "fileName" specifies the file name, - "contains" stores all meta data object references. -*/ + * "fileName" specifies the file name, + * "contains" stores all meta data object references. + */ C_STRUCT(idl_file) { c_char *fileName; c_iter contains; @@ -46,8 +47,7 @@ C_STRUCT(idl_file) { C_CLASS(idl_map); -/* "idl_map" contains a filename meta object association -*/ +/* "idl_map" contains a filename meta object association */ C_STRUCT(idl_map) { c_char *fileName; c_baseObject object; @@ -100,8 +100,8 @@ idl_fileFree( } /* Check if the specified object list element is equal to the meta object specified - by object -*/ + * by object + */ static c_equality idl_objectCompare( /* QAC EXPECT 3673; No solution to the message here, but no problem either */ @@ -124,8 +124,8 @@ idl_objectCompare( } /* Check if the specified object list element is equal to the meta object specified - by the map -*/ + * by the map + */ static c_equality idl_objectMap( /* QAC EXPECT 3673; No solution to the message here, but no problem either */ @@ -251,10 +251,10 @@ idl_fileMapAssociation( } /* idl_searchObject will search in the specified "file" - association for the object specified in map->object. - If the object is found, it is returned and the associated - filename is stored in map->fileName. -*/ + * association for the object specified in map->object. + * If the object is found, it is returned and the associated + * filename is stored in map->fileName. + */ static void idl_searchObject( /* QAC EXPECT 3673; No solution to the message here, but no problem either */ @@ -288,8 +288,8 @@ idl_fileMapResolve( map->fileName = NULL; c_iterWalk(fileMap->files, (c_iterWalkAction)idl_searchObject, map); /* map will contain the meta object reference and fileName reference - after the c_iterWalk. - */ + * after the c_iterWalk. + */ fileName = map->fileName; if (fileName == NULL) { /* file name is undefined for implicit defined types */ @@ -302,8 +302,8 @@ idl_fileMapResolve( } /* Check if the specified meta object is specified with associated with - the specified file in the specified file map -*/ + * the specified file in the specified file map + */ c_bool idl_fileMapObject( /* QAC EXPECT 3673; No solution to the message here, but no problem either */ @@ -342,7 +342,7 @@ void idl_fileMapFillList( case M_PARAMETER: break; default: - c_iterInsert(objects, object); + (void)c_iterInsert(objects, object); break; } } @@ -414,7 +414,3 @@ c_bool idl_fileMapCheckFinalized( } return !count; } - - - - diff --git a/src/tools/idlpp/code/idl_fileMap.h b/src/tools/idlpp/code/idl_fileMap.h index 8168a949f..c1a640361 100644 --- a/src/tools/idlpp/code/idl_fileMap.h +++ b/src/tools/idlpp/code/idl_fileMap.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/idlpp/code/idl_genC99Copyout.c b/src/tools/idlpp/code/idl_genC99Copyout.c index 2cc5b5831..0f3f083e2 100644 --- a/src/tools/idlpp/code/idl_genC99Copyout.c +++ b/src/tools/idlpp/code/idl_genC99Copyout.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -1260,6 +1261,51 @@ idl_seqIndex ( return os_strdup(index); } +static void +insertCopyBodySequence( + idl_typeSpec typeSpec, + const char *to, + c_long loop_index, + c_long indent) +{ + c_char source[32]; + idl_typeSpec nextType = idl_typeSeqType(idl_typeSeq(typeSpec)); + c_char *scopedTypeIdent = idl_scopedSplTypeIdent(nextType); + c_char *sequenceIndex = idl_seqIndex(loop_index); + c_char *sequenceIdent = idl_c99SequenceIdent (idl_typeSeq(typeSpec)); + + idl_printIndent (indent); + idl_fileOutPrintf (idl_fileCur(), " c_ulong size%d;\n", loop_index); + idl_printIndent (indent); + idl_fileOutPrintf(idl_fileCur(), " %s *src%d = (%s *)src%d%s;\n", + scopedTypeIdent, loop_index, scopedTypeIdent, loop_index - 1, sequenceIndex); + idl_printIndent (indent); + idl_fileOutPrintf (idl_fileCur(), " %s *dst%d = (%s *)&dst%d->_buffer[i%d];\n", + sequenceIdent, loop_index, sequenceIdent, loop_index-1, loop_index-1); + idl_fileOutPrintf (idl_fileCur(), "\n"); + idl_printIndent (indent); + idl_fileOutPrintf (idl_fileCur(), " size%d = c_arraySize((c_sequence)(src%d));\n", + loop_index, loop_index); + if (idl_typeSeqMaxSize(idl_typeSeq(typeSpec)) == 0) { + /* For unbounded sequence set maximum size */ + idl_printIndent (indent); + idl_fileOutPrintf (idl_fileCur(), " DDS_sequence_replacebuf ((_DDS_sequence) dst%d, (bufferAllocatorType)%s_allocbuf, size%d);\n", + loop_index, sequenceIdent, loop_index); + } else { + idl_printIndent (indent); + idl_fileOutPrintf (idl_fileCur(), " DDS_sequence_replacebuf ((_DDS_sequence) dst%d, (bufferAllocatorType)%s_allocbuf, %d);\n", + loop_index, sequenceIdent, idl_typeSeqMaxSize(idl_typeSeq(typeSpec))); + } + idl_printIndent (indent); + idl_fileOutPrintf (idl_fileCur(), " dst%d->_length = size%d;\n", + loop_index, loop_index); + snprintf (source, sizeof(source), "src%d", loop_index); + idl_seqLoopCopy (nextType, source, to, loop_index+1, indent+1); + os_free(scopedTypeIdent); + os_free(sequenceIndex); + os_free(sequenceIdent); +} + /** @brief Function that generates code for copying sequences. * * Generate code for copying sequence types. @@ -1333,13 +1379,8 @@ idl_seqLoopCopy ( c_long loop_index, c_long indent) { - c_char source[32]; - idl_typeSpec nextType; c_char *scopedName; c_char *corbaTypeName; - c_char *scopedTypeIdent; - c_char *sequenceIdent; - c_char *sequenceIndex; if (idl_isContiguous(idl_typeSpecDef(typeSpec))) { idl_printIndent (indent); @@ -1441,47 +1482,16 @@ idl_seqLoopCopy ( to, loop_index-1, loop_index-1, corbaTypeName, from, loop_index-1); os_free(corbaTypeName); break; + case idl_tseq: + insertCopyBodySequence(idl_typeDefActual(idl_typeDef(typeSpec)), to, loop_index, indent); + break; default: printf ("idl_arrayLoopCopyBody: Unexpected type\n"); assert (0); } break; case idl_tseq: - nextType = idl_typeSeqType(idl_typeSeq(typeSpec)); - scopedTypeIdent = idl_scopedSplTypeIdent(nextType); - sequenceIndex = idl_seqIndex(loop_index); - sequenceIdent = idl_c99SequenceIdent (idl_typeSeq(typeSpec)); - - idl_printIndent (indent); - idl_fileOutPrintf (idl_fileCur(), " c_ulong size%d;\n", loop_index); - idl_printIndent (indent); - idl_fileOutPrintf(idl_fileCur(), " %s *src%d = (%s *)src%d%s;\n", - scopedTypeIdent, loop_index, scopedTypeIdent, loop_index - 1, sequenceIndex); - idl_printIndent (indent); - idl_fileOutPrintf (idl_fileCur(), " %s *dst%d = (%s *)&dst%d->_buffer[i%d];\n", - sequenceIdent, loop_index, sequenceIdent, loop_index-1, loop_index-1); - idl_fileOutPrintf (idl_fileCur(), "\n"); - idl_printIndent (indent); - idl_fileOutPrintf (idl_fileCur(), " size%d = c_arraySize((c_sequence)(src%d));\n", - loop_index, loop_index); - if (idl_typeSeqMaxSize(idl_typeSeq(typeSpec)) == 0) { - /* For unbounded sequence set maximum size */ - idl_printIndent (indent); - idl_fileOutPrintf (idl_fileCur(), " DDS_sequence_replacebuf ((_DDS_sequence) dst%d, (bufferAllocatorType)%s_allocbuf, size%d);\n", - loop_index, sequenceIdent, loop_index); - } else { - idl_printIndent (indent); - idl_fileOutPrintf (idl_fileCur(), " DDS_sequence_replacebuf ((_DDS_sequence) dst%d, (bufferAllocatorType)%s_allocbuf, %d);\n", - loop_index, sequenceIdent, idl_typeSeqMaxSize(idl_typeSeq(typeSpec))); - } - idl_printIndent (indent); - idl_fileOutPrintf (idl_fileCur(), " dst%d->_length = size%d;\n", - loop_index, loop_index); - snprintf (source, sizeof(source), "src%d", loop_index); - idl_seqLoopCopy (nextType, source, to, loop_index+1, indent+1); - os_free(scopedTypeIdent); - os_free(sequenceIndex); - os_free(sequenceIdent); + insertCopyBodySequence(typeSpec, to, loop_index, indent); break; default: assert (0); diff --git a/src/tools/idlpp/code/idl_genC99Copyout.h b/src/tools/idlpp/code/idl_genC99Copyout.h index fd403eac4..e14a97cf3 100644 --- a/src/tools/idlpp/code/idl_genC99Copyout.h +++ b/src/tools/idlpp/code/idl_genC99Copyout.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/idlpp/code/idl_genC99Helper.c b/src/tools/idlpp/code/idl_genC99Helper.c index 1843f373c..dce2a7778 100644 --- a/src/tools/idlpp/code/idl_genC99Helper.c +++ b/src/tools/idlpp/code/idl_genC99Helper.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -30,22 +31,22 @@ static c_char *idl_scopedC99SequenceTypeIdent (const idl_typeSpec typeSpec); /** @todo Correct comment */ /* Return the scoped type specification where for the user types, - scopes are separated by "_" chracters. - IDL strings (bounded and unbounded) are mapped on: c_string, other - basic types are mapped on corresponding splice types - IDL structures are identified by: struct - IDL unions are identified by: struct becuase - the union mapping is: - struct { - _d; - union { - - } _u; - } - IDL enumerations are identified by: enum - IDL typedefs are formed by the scoped type name - IDL sequences are mapped on: c_sequence -*/ + * scopes are separated by "_" chracters. + * IDL strings (bounded and unbounded) are mapped on: c_string, other + * basic types are mapped on corresponding splice types + * IDL structures are identified by: struct + * IDL unions are identified by: struct becuase + * the union mapping is: + * struct { + * _d; + * union { + * + * } _u; + * } + * IDL enumerations are identified by: enum + * IDL typedefs are formed by the scoped type name + * IDL sequences are mapped on: c_sequence + */ c_char * idl_scopedC99TypeIdent ( const idl_typeSpec typeSpec) @@ -83,8 +84,8 @@ idl_scopedC99TypeIdent ( } /* Return the standalone C specific type identifier for the - specified type specification -*/ + * specified type specification + */ c_char * idl_c99TypeFromTypeSpec ( const idl_typeSpec typeSpec) @@ -146,9 +147,9 @@ idl_c99TypeFromTypeSpec ( printf ("idl_c99TypeFromTypeSpec: Unexpected array type handled\n"); } else { /* if a user type is specified build it from its scope and its name. - The type should be one of idl_ttypedef, idl_tenum, idl_tstruct, - idl_tunion. - */ + * The type should be one of idl_ttypedef, idl_tenum, idl_tstruct, + * idl_tunion. + */ typeName = idl_scopeStackC ( idl_typeUserScope(idl_typeUser(typeSpec)), "_", @@ -160,111 +161,88 @@ idl_c99TypeFromTypeSpec ( /* Return the scoped actual type specification where for the user types, - scopes are separated by "_" chracters. - IDL strings (bounded and unbounded) are mapped on: c_string, other - basic types are mapped on corresponding splice types - IDL structures are identified by: struct - IDL unions are identified by: struct becuase - the union mapping is: - struct { - _d; - union { - - } _u; - } - IDL enumerations are identified by: enum - IDL typedefs are formed by the scoped type name - IDL sequences are mapped on: c_sequence -*/ + * scopes are separated by "_" chracters. + * IDL strings (bounded and unbounded) are mapped on: c_string, other + * basic types are mapped on corresponding splice types + * IDL structures are identified by: struct + * IDL unions are identified by: struct becuase + * the union mapping is: + * struct { + * _d; + * union { + * + * } _u; + * } + * IDL enumerations are identified by: enum + * IDL typedefs are formed by the scoped type name + * IDL sequences are mapped on: c_sequence + */ static c_char * idl_scopedC99SequenceElementTypeIdent ( const idl_typeSpec typeSpec) { - c_char scopedTypeIdent[256]; - c_char *ident;; + c_char *typeName; /* QAC EXPECT 3416; No unexpected side effects here */ if (idl_typeSpecType(typeSpec) == idl_tbasic) { switch (idl_typeBasicType(idl_typeBasic(typeSpec))) { case idl_short: - snprintf (scopedTypeIdent, sizeof(scopedTypeIdent), "int16_t"); + typeName = os_strdup("int16_t"); break; case idl_ushort: - snprintf (scopedTypeIdent, sizeof(scopedTypeIdent), "uint16_t"); + typeName = os_strdup("uint16_t"); break; case idl_long: - snprintf (scopedTypeIdent, sizeof(scopedTypeIdent), "int32_t"); + typeName = os_strdup("int32_t"); break; case idl_ulong: - snprintf (scopedTypeIdent, sizeof(scopedTypeIdent), "uint32_t"); + typeName = os_strdup("uint32_t"); break; case idl_longlong: - snprintf (scopedTypeIdent, sizeof(scopedTypeIdent), "int64_t"); + typeName = os_strdup("int64_t"); break; case idl_ulonglong: - snprintf (scopedTypeIdent, sizeof(scopedTypeIdent), "uint64_t"); + typeName = os_strdup("uint64_t"); break; case idl_float: - snprintf (scopedTypeIdent, sizeof(scopedTypeIdent), "float"); + typeName = os_strdup("float"); break; case idl_double: - snprintf (scopedTypeIdent, sizeof(scopedTypeIdent), "double"); + typeName = os_strdup("double"); break; case idl_char: - snprintf (scopedTypeIdent, sizeof(scopedTypeIdent), "char"); + typeName = os_strdup("char"); break; case idl_string: - snprintf (scopedTypeIdent, sizeof(scopedTypeIdent), "char *"); + typeName = os_strdup("char *"); break; case idl_boolean: - snprintf (scopedTypeIdent, sizeof(scopedTypeIdent), "bool"); + typeName = os_strdup("bool"); break; case idl_octet: - snprintf (scopedTypeIdent, sizeof(scopedTypeIdent), "uint8_t"); + typeName = os_strdup("uint8_t"); break; default: - os_strncpy (scopedTypeIdent, "", sizeof(scopedTypeIdent)); + typeName = os_strdup(""); } } else if (idl_typeSpecType(typeSpec) == idl_tstruct || idl_typeSpecType(typeSpec) == idl_tunion || idl_typeSpecType(typeSpec) == idl_tenum) { /* QAC EXPECT 3416; No unexpected side effects here */ - ident = idl_c99TypeFromTypeSpec(idl_typeSpec(typeSpec)); - snprintf (scopedTypeIdent, sizeof(scopedTypeIdent), "%s", ident); - os_free(ident); + typeName = idl_c99TypeFromTypeSpec(idl_typeSpec(typeSpec)); /* QAC EXPECT 3416; No unexpected side effects here */ } else if (idl_typeSpecType(typeSpec) == idl_ttypedef) { - switch (idl_typeSpecType(idl_typeDefRefered (idl_typeDef(typeSpec)))) { - case idl_tarray: - case idl_tseq: - ident = idl_c99TypeFromTypeSpec(typeSpec); - snprintf (scopedTypeIdent, sizeof(scopedTypeIdent), "%s", ident); - os_free(ident); - break; - case idl_ttypedef: - ident = idl_scopedC99SequenceTypeIdent(idl_typeDefRefered (idl_typeDef(typeSpec))); - snprintf (scopedTypeIdent, sizeof(scopedTypeIdent), "%s", ident); - os_free(ident); - break; - default: - ident = idl_c99TypeFromTypeSpec(idl_typeDefActual(idl_typeDef(typeSpec))); - snprintf (scopedTypeIdent, sizeof(scopedTypeIdent), "%s", ident); - os_free(ident); - } + typeName = idl_c99TypeFromTypeSpec(typeSpec); /* QAC EXPECT 3416; No unexpected side effects here */ } else if (idl_typeSpecType(typeSpec) == idl_tarray) { - ident = idl_scopedC99SequenceTypeIdent (idl_typeArrayActual(idl_typeArray(typeSpec))); - snprintf (scopedTypeIdent, sizeof(scopedTypeIdent), "%s", ident); - os_free(ident); + typeName = idl_scopedC99SequenceTypeIdent (idl_typeArrayActual(idl_typeArray(typeSpec))); } else if (idl_typeSpecType(typeSpec) == idl_tseq) { - ident = idl_c99SequenceIdent(idl_typeSeq(typeSpec)); - snprintf (scopedTypeIdent, sizeof(scopedTypeIdent), "%s", ident); - os_free(ident); + typeName = idl_c99SequenceIdent(idl_typeSeq(typeSpec)); } else { - /* Do nothing, only to prevent dangling else-ifs QAC messages */ + typeName = NULL; } - return os_strdup(scopedTypeIdent); + return typeName; } /* Return the scoped actual type specification where for the user types, @@ -376,23 +354,22 @@ idl_scopedC99SequenceSubElementTypeIdent ( } /* Return the scoped actual type specification where for the user types, - scopes are separated by "_" chracters. - IDL strings (bounded and unbounded) are mapped on: c_string, other - basic types are mapped on corresponding splice types - IDL structures are identified by: struct - IDL unions are identified by: struct becuase - the union mapping is: - struct { - _d; - union { - - } _u; - } - IDL enumerations are identified by: enum - IDL typedefs are formed by the scoped type name - IDL sequences are mapped on: c_sequence -*/ - + * scopes are separated by "_" chracters. + * IDL strings (bounded and unbounded) are mapped on: c_string, other + * basic types are mapped on corresponding splice types + * IDL structures are identified by: struct + * IDL unions are identified by: struct becuase + * the union mapping is: + * struct { + * _d; + * union { + * + * } _u; + * } + * IDL enumerations are identified by: enum + * IDL typedefs are formed by the scoped type name + * IDL sequences are mapped on: c_sequence + */ static c_char * idl_scopedC99SequenceTypeIdent ( @@ -452,23 +429,9 @@ idl_scopedC99SequenceTypeIdent ( os_free(ident); /* QAC EXPECT 3416; No unexpected side effects here */ } else if (idl_typeSpecType(typeSpec) == idl_ttypedef) { - switch (idl_typeSpecType(idl_typeDefRefered (idl_typeDef(typeSpec)))) { - case idl_tarray: - case idl_tseq: - ident = idl_c99TypeFromTypeSpec(typeSpec); - snprintf (scopedTypeIdent, sizeof(scopedTypeIdent), "%s", ident); - os_free(ident); - break; - case idl_ttypedef: - ident = idl_scopedC99SequenceTypeIdent(idl_typeDefRefered (idl_typeDef(typeSpec))); - snprintf (scopedTypeIdent, sizeof(scopedTypeIdent), "%s", ident); - os_free(ident); - break; - default: - ident = idl_c99TypeFromTypeSpec(idl_typeDefActual(idl_typeDef(typeSpec))); - snprintf (scopedTypeIdent, sizeof(scopedTypeIdent), "%s", ident); - os_free(ident); - } + ident = idl_c99TypeFromTypeSpec(typeSpec); + snprintf (scopedTypeIdent, sizeof(scopedTypeIdent), "%s", ident); + os_free(ident); /* QAC EXPECT 3416; No unexpected side effects here */ } else if (idl_typeSpecType(typeSpec) == idl_tarray) { ident = idl_scopedC99SequenceTypeIdent (idl_typeArrayActual(idl_typeArray(typeSpec))); @@ -565,8 +528,6 @@ idl_c99SequenceIdent ( sequenceName = os_malloc (len); snprintf (sequenceName, len, "%s%s", "DDS_sequence_", sequenceType); os_free(sequenceType); - } else if (idl_typeSpecType(idl_typeSeqType (typeSeq)) == idl_ttypedef) { - sequenceName = idl_scopedC99TypeIdent(idl_typeSeqType (typeSeq)); } else { sequenceType = idl_scopedC99SequenceTypeIdent(idl_typeSeqType (typeSeq)); len = strlen(sequenceType) + strlen ("DDS_sequence_") + 3; @@ -639,13 +600,13 @@ idl_c99SequenceSupportFunctionsExist ( /* If a type has a related key, that means that readers and * writers have been created, which also means that type * sequence support functions have already been created in - * the other context. */ + * the other context. + */ if (idl_keyDefIncludesType(idl_keyDefDefGet(), elementName)) { exist = TRUE; } - /* - * We should search all scopes of all contexts to be sure that + /* We should search all scopes of all contexts to be sure that * no sequence support functions for this type are defined * anywhere within the hierarchy by means of an actual * 'sequence' definition in an idl file. diff --git a/src/tools/idlpp/code/idl_genC99Helper.h b/src/tools/idlpp/code/idl_genC99Helper.h index e94e71917..7d11ced1f 100644 --- a/src/tools/idlpp/code/idl_genC99Helper.h +++ b/src/tools/idlpp/code/idl_genC99Helper.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/idlpp/code/idl_genC99Tmpl.c b/src/tools/idlpp/code/idl_genC99Tmpl.c index 18f541197..eae287084 100644 --- a/src/tools/idlpp/code/idl_genC99Tmpl.c +++ b/src/tools/idlpp/code/idl_genC99Tmpl.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -62,7 +63,7 @@ idl_fileOpen ( c_char *tmplPath; c_char *tmpl; int tmplFile; - struct os_stat tmplStat; + struct os_stat_s tmplStat; unsigned int nRead; os_char* tmpName; os_uint32 i; diff --git a/src/tools/idlpp/code/idl_genC99Tmpl.h b/src/tools/idlpp/code/idl_genC99Tmpl.h index 11485d71b..b286f193a 100644 --- a/src/tools/idlpp/code/idl_genC99Tmpl.h +++ b/src/tools/idlpp/code/idl_genC99Tmpl.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/idlpp/code/idl_genC99Type.c b/src/tools/idlpp/code/idl_genC99Type.c index 0eafd9d2e..b07222e68 100644 --- a/src/tools/idlpp/code/idl_genC99Type.c +++ b/src/tools/idlpp/code/idl_genC99Type.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -108,7 +109,7 @@ idl_memberDeclaration( } -/* @brief callback function called on opening the IDL input file. +/** @brief callback function called on opening the IDL input file. * * Generate standard file header consisting of: * - mutiple inclusion prevention @@ -137,6 +138,11 @@ idl_fileOpen( idl_fileOutPrintf(idl_fileCur(), "#include \n"); idl_fileOutPrintf(idl_fileCur(), "#include \n"); idl_fileOutPrintf(idl_fileCur(), "\n"); + + idl_fileOutPrintf(idl_fileCur(), "#if defined (__cplusplus)\n"); + idl_fileOutPrintf(idl_fileCur(), "extern \"C\" {\n"); + idl_fileOutPrintf(idl_fileCur(), "#endif\n"); + /* Generate code for inclusion of application specific include files */ for (i = 0; i < idl_depLength(idl_depDefGet()); i++) { idl_fileOutPrintf(idl_fileCur(), "#include \"%sDcps.h\"\n", idl_depGet(idl_depDefGet(), i)); @@ -150,7 +156,7 @@ idl_fileOpen( return idl_explore; } -/* @brief callback function called on closing the IDL input file. +/** @brief callback function called on closing the IDL input file. * * Generate standard file footer consisting of: * - mutiple inclusion prevention closure @@ -160,6 +166,11 @@ idl_fileClose ( void *userData) { OS_UNUSED_ARG(userData); + + idl_fileOutPrintf(idl_fileCur(), "#if defined (__cplusplus)\n"); + idl_fileOutPrintf(idl_fileCur(), "}\n"); + idl_fileOutPrintf(idl_fileCur(), "#endif\n\n"); + /* Generate closure of multiple inclusion prevention code */ idl_fileOutPrintf(idl_fileCur(), "#endif\n"); } @@ -408,6 +419,7 @@ idl_unionOpen( OS_UNUSED_ARG(userData); if (idl_definitionExists("definition", scopedName)) { + os_free(scopedName); return idl_abort; } idl_definitionAdd("definition", scopedName); @@ -639,6 +651,7 @@ idl_enumerationOpen( OS_UNUSED_ARG(userData); if (idl_definitionExists("definition", scopedName)) { + os_free(scopedName); return idl_abort; } idl_definitionAdd("definition", scopedName); @@ -923,10 +936,10 @@ idl_sequenceOpenClose( idl_typeSeq typeSeq, void *userData) { - c_bool genPrototypesOnly = FALSE; - char *scopedTypeIdent; + c_bool prototypeExists = FALSE; char *sequenceElementName; char *sequenceName; + char * sequenceScopedName; OS_UNUSED_ARG(userData); @@ -934,35 +947,18 @@ idl_sequenceOpenClose( sequenceName = idl_c99SequenceIdent(typeSeq); if (idl_definitionExists("definition", sequenceName)) { - os_free(sequenceElementName); - os_free(sequenceName); - return; - } - idl_definitionAdd("definition", sequenceName); + prototypeExists = TRUE; + } else { + idl_definitionAdd("definition", sequenceName); - if (idl_scopeStackSize(scope) > 0) { if ((idl_typeSpecType(idl_typeSeqType(typeSeq)) == idl_tbasic) && ((idl_typeBasicType(idl_typeBasic(idl_typeSeqType(typeSeq))) == idl_octet) || (idl_typeBasicType(idl_typeBasic(idl_typeSeqType(typeSeq))) == idl_string))) { - genPrototypesOnly = TRUE; - } else - /* If the element type of the sequence has a related key, which means that readers and - * writers have been created, and which also means that type sequence support functions - * have already been created. In that case the prototypes for these functions should be - * generated. Otherwise add the scope name of the module where the sequence is defined - * in to the name of these functions. - */ - if (idl_keyDefIncludesType(idl_keyDefDefGet(), sequenceElementName)) { - genPrototypesOnly = TRUE; - } else { - genPrototypesOnly = idl_c99SequenceSupportFunctionsExist(scope, typeSeq, sequenceElementName); - } - } else { - genPrototypesOnly = TRUE; + prototypeExists = TRUE; + } } - - if (idl_typeSpecType(idl_typeSeqType(typeSeq)) != idl_ttypedef) { - scopedTypeIdent = idl_scopedC99TypeIdent(idl_typeSeqType(typeSeq)); + if (!prototypeExists) { + char *scopedTypeIdent = idl_scopedC99TypeIdent(idl_typeSeqType(typeSeq)); idl_fileOutPrintf(idl_fileCur(), "/* Definition for sequence of %s */\n", scopedTypeIdent); idl_fileOutPrintf(idl_fileCur(), "#ifndef _%s_defined\n", @@ -970,10 +966,11 @@ idl_sequenceOpenClose( idl_fileOutPrintf(idl_fileCur(), "#define _%s_defined\n", sequenceName); if (idl_typeSpecType(idl_typeSeqType(typeSeq)) == idl_tstruct) { - /* In case struct is refered, it can be a sequence definition within */ - /* within the structure with a reference to the struct itself. In that */ - /* case the struct or union is not defined yet, and a forward */ - /* definition is required. */ + /* In case struct is refered, it can be a sequence definition within + * within the structure with a reference to the struct itself. In that + * case the struct or union is not defined yet, and a forward + * definition is required. + */ idl_fileOutPrintf(idl_fileCur(), "#ifndef _%s_defined\n", scopedTypeIdent); idl_fileOutPrintf(idl_fileCur(), "#define _%s_defined\n", @@ -985,10 +982,11 @@ idl_sequenceOpenClose( idl_fileOutPrintf(idl_fileCur(), "#endif /* _%s_defined */\n", scopedTypeIdent); } else if (idl_typeSpecType(idl_typeSeqType(typeSeq)) == idl_tunion) { - /* In case struct is refered, it can be a sequence definition within */ - /* within the structure with a reference to the struct itself. In that */ - /* case the struct or union is not defined yet, and a forward */ - /* definition is required. */ + /* In case struct is refered, it can be a sequence definition within + * within the structure with a reference to the struct itself. In that + * case the struct or union is not defined yet, and a forward + * definition is required. + */ idl_fileOutPrintf(idl_fileCur(), "#ifndef _%s_defined\n", scopedTypeIdent); idl_fileOutPrintf(idl_fileCur(), "#define _%s_defined\n", @@ -1007,42 +1005,29 @@ idl_sequenceOpenClose( idl_fileOutPrintf(idl_fileCur(), " bool _release;\n"); idl_fileOutPrintf(idl_fileCur(), "} %s;\n", sequenceName); - os_free(scopedTypeIdent); - - if (genPrototypesOnly) { - idl_fileOutPrintf(idl_fileCur(), "%s %s *%s__alloc (void);\n", - idl_dllGetMacro(), - sequenceName, - sequenceName); - idl_fileOutPrintf(idl_fileCur(), "%s %s *%s_allocbuf (uint32_t len);\n", - idl_dllGetMacro(), - sequenceElementName, - sequenceName); - } else { - char * sequenceScopedName = idl_c99SequenceIdentScoped(scope, typeSeq); + idl_fileOutPrintf(idl_fileCur(), "%s %s *%s__alloc (void);\n", + idl_dllGetMacro(), + sequenceName, + sequenceName); + idl_fileOutPrintf(idl_fileCur(), "%s %s *%s_allocbuf (uint32_t len);\n", + idl_dllGetMacro(), + sequenceElementName, + sequenceName); + idl_fileOutPrintf(idl_fileCur(), "#endif /* _%s_defined */\n", sequenceName); - idl_fileOutPrintf(idl_fileCur(), "%s %s *%s__alloc (void);\n", - idl_dllGetMacro(), - sequenceName, - sequenceScopedName); - idl_fileOutPrintf(idl_fileCur(), "%s %s *%s_allocbuf (uint32_t len);\n", - idl_dllGetMacro(), - sequenceElementName, - sequenceScopedName); + os_free(scopedTypeIdent); + } - idl_fileOutPrintf(idl_fileCur(), "#define %s__alloc %s__alloc\n", - sequenceName, - sequenceScopedName); - idl_fileOutPrintf(idl_fileCur(), "#define %s_allocbuf %s_allocbuf\n", - sequenceName, - sequenceScopedName); + sequenceScopedName = idl_c99SequenceIdentScoped(scope, typeSeq); - os_free(sequenceScopedName); - } + idl_fileOutPrintf(idl_fileCur(), "#define %s__alloc %s__alloc\n", + sequenceScopedName, + sequenceName); + idl_fileOutPrintf(idl_fileCur(), "#define %s_allocbuf %s_allocbuf\n\n", + sequenceScopedName, + sequenceName); - idl_fileOutPrintf(idl_fileCur(), "#endif /* _%s_defined */\n", sequenceName); - idl_fileOutPrintf(idl_fileCur(), "\n"); - } + os_free(sequenceScopedName); os_free(sequenceElementName); os_free(sequenceName); } diff --git a/src/tools/idlpp/code/idl_genC99Type.h b/src/tools/idlpp/code/idl_genC99Type.h index 346767eea..aae82dd15 100644 --- a/src/tools/idlpp/code/idl_genC99Type.h +++ b/src/tools/idlpp/code/idl_genC99Type.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/idlpp/code/idl_genCHelper.c b/src/tools/idlpp/code/idl_genCHelper.c index f41425555..dfb830a5f 100644 --- a/src/tools/idlpp/code/idl_genCHelper.c +++ b/src/tools/idlpp/code/idl_genCHelper.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,6 +21,7 @@ #include "idl_genCHelper.h" #include "idl_genLanguageHelper.h" +#include "os_abstract.h" #include "os_iterator.h" #include "os_heap.h" #include "os_stdlib.h" @@ -36,9 +38,9 @@ static const char *c_keywords[] = { }; /* Translate an IDL identifier into a C language identifier. - The IDL specification states that all identifiers that match - a C keyword must be prepended by "_c_". -*/ + * The IDL specification states that all identifiers that match + * a C keyword must be prepended by "_c_". + */ c_char * idl_cId ( const char *identifier) @@ -65,9 +67,9 @@ idl_cId ( } /* Build a textual presenation of the provided scope stack taking the - C++ keyword identifier translation into account. Further the function - equals "idl_scopeStack". -*/ + * C++ keyword identifier translation into account. Further the function + * equals "idl_scopeStack". + */ c_char * idl_scopeStackC( idl_scope scope, @@ -90,7 +92,7 @@ idl_scopeStackC( /* Translate the scope name to a C identifier */ Id = idl_cId(idl_scopeElementName(idl_scopeIndexed(scope, si))); /* allocate space for the current scope stack + the separator - and the next scope name + * and the next scope name */ /* QAC EXPECT 5007; will not use wrapper */ scopeStack = os_realloc(scopeStack, strlen(scopeStack)+strlen(scopeSepp)+strlen(Id)+1); @@ -107,7 +109,7 @@ idl_scopeStackC( /* Translate the user identifier to a C identifier */ Id = idl_cId(name); /* allocate space for the current scope stack + the separator - and the user identifier + * and the user identifier */ /* QAC EXPECT 5007; will not use wrapper */ scopeStack = os_realloc(scopeStack, strlen(scopeStack)+strlen(scopeSepp)+strlen(Id)+1); @@ -133,8 +135,8 @@ idl_scopeStackC( } /* Return the C specific type identifier for the - specified type specification -*/ + * specified type specification + */ c_char * idl_corbaCTypeFromTypeSpec( idl_typeSpec typeSpec) @@ -239,8 +241,8 @@ idl_corbaCTypeFromTypeSpec( printf("idl_corbaTypeFromTypeSpec: Unexpected type handled\n"); } else { /* if a user type is specified build it from its scope and its name. - The type should be one of idl_ttypedef, idl_tenum, idl_tstruct, - idl_tunion. + * The type should be one of idl_ttypedef, idl_tenum, idl_tstruct, + * idl_tunion. */ typeName = idl_scopeStackC( idl_typeUserScope(idl_typeUser(typeSpec)), @@ -251,6 +253,191 @@ idl_corbaCTypeFromTypeSpec( /* QAC EXPECT 5101; The switch statement is simple, therefor the total complexity is low */ } +c_char * +idl_genCLiteralValueImage( + c_value literal, + c_type type) +{ + c_char * valueImg = NULL; + c_char *val2; + int i; + + if (c_baseObject(type)->kind != M_ENUMERATION) { + switch (literal.kind) { + case V_OCTET: + valueImg = os_malloc (40); + snprintf(valueImg, 40, "%x", literal.is.Octet); + break; + case V_FLOAT: + case V_DOUBLE: + val2 = os_malloc(45); + valueImg = os_malloc(45); + snprintf(val2, 45, "%40.17g", literal.is.Double); + i = 0; + while (val2[i] == ' ') { + i++; + } + os_strncpy(valueImg, &val2[i], 40); + os_free(val2); + if ((strchr(valueImg, '.') == NULL) && (strchr(valueImg, 'E') == NULL)) { + strcat(valueImg, ".0"); + } + break; + case V_STRING: + valueImg = os_malloc(strlen(literal.is.String)+3); + snprintf(valueImg, strlen(literal.is.String)+3, "\"%s\"", literal.is.String); + break; + case V_BOOLEAN: + valueImg = os_malloc(10); + if (literal.is.Boolean) { + snprintf(valueImg, 10, "%s", "TRUE"); + } else { + snprintf (valueImg, 10, "%s", "FALSE"); + } + break; + case V_LONGLONG: + valueImg = os_malloc(40); + switch (c_primitive(type)->kind) { + case P_SHORT: + snprintf(valueImg, 40, "%hu", (c_short)literal.is.LongLong); + break; + case P_USHORT: + snprintf(valueImg, 40, "%huU", (c_ushort)literal.is.LongLong); + break; + case P_LONG: + if ((c_long)literal.is.LongLong != INT_MIN) { + snprintf(valueImg, 40, "%u", (c_long)literal.is.LongLong); + } else { + // We cannot represent minus 2^31 directly, due to the fact that it + // is constructed in two steps: + // 1) the specification of the unsigned literal. + // 2) the application of the minus sign. + // However, due to the inclusion of number 0 the positive range + // is one lower than the negative range and therefore the most + // negative number cannot be expressed as unsigned literal without + // overflow (with subsequent compilation warning). Therefore we + // construct it in 3 steps: + // 1) Specification of most positive value + // 2) Application of the minus sign + // 3) Subtraction of 1 to reach most negative value. + snprintf(valueImg, 40, "2147483647 - 1"); + } + break; + case P_ULONG: + snprintf(valueImg, 40, "%uU", (c_ulong)literal.is.LongLong); + break; + case P_LONGLONG: + if ((c_longlong)literal.is.LongLong != LLONG_MIN) { + snprintf(valueImg, 40, "%"PA_PRIu64"LL", (c_longlong)literal.is.LongLong); + } else { + // We cannot represent minus 2^63 directly, due to the fact that it + // is constructed in two steps: + // 1) the specification of the unsigned literal. + // 2) the application of the minus sign. + // However, due to the inclusion of number 0 the positive range + // is one lower than the negative range and therefore the most + // negative number cannot be expressed as unsigned literal without + // overflow (with subsequent compilation warning). Therefore we + // construct it in 3 steps: + // 1) Specification of most positive value + // 2) Application of the minus sign + // 3) Subtraction of 1 to reach most negative value. + snprintf(valueImg, 40, "9223372036854775807LL - 1LL"); + } + break; + case P_ULONGLONG: + snprintf(valueImg, 40, "%"PA_PRIu64"ULL", (c_ulonglong)literal.is.LongLong); + break; + case P_CHAR: + snprintf(valueImg, 40, "%u", (unsigned char)literal.is.LongLong); + break; + case P_OCTET: + snprintf(valueImg, 40, "%u", (unsigned char)literal.is.LongLong); + break; + case P_ADDRESS: + snprintf(valueImg, 40, PA_ADDRFMT, (PA_ADDRCAST)literal.is.LongLong); + break; + case P_UNDEFINED: + case P_BOOLEAN: + case P_WCHAR: + case P_FLOAT: + case P_DOUBLE: + case P_VOIDP: + case P_MUTEX: + case P_LOCK: + case P_COND: + case P_COUNT: + case P_PA_UINT32: + case P_PA_UINTPTR: + case P_PA_VOIDP: + /* Do nothing */ + break; + } + break; + case V_SHORT: + valueImg = os_malloc(40); + snprintf(valueImg, 40, "%hu", literal.is.Short); + break; + case V_LONG: + valueImg = os_malloc(40); + if ((c_long)literal.is.LongLong != INT_MIN) { + snprintf(valueImg, 40, "%u", literal.is.Long); + } else { + // We cannot represent minus 2^31 directly, due to the fact that it + // is constructed in two steps: + // 1) the specification of the unsigned literal. + // 2) the application of the minus sign. + // However, due to the inclusion of number 0 the positive range + // is one lower than the negative range and therefore the most + // negative number cannot be expressed as unsigned literal without + // overflow (with subsequent compilation warning). Therefore we + // construct it in 3 steps: + // 1) Specification of most positive value + // 2) Application of the minus sign + // 3) Subtraction of 1 to reach most negative value. + snprintf(valueImg, 40, "2147483647 - 1"); + } + break; + case V_USHORT: + valueImg = os_malloc(40); + snprintf(valueImg, 40, "%huU", literal.is.UShort); + break; + case V_ULONG: + valueImg = os_malloc(40); + snprintf(valueImg, 40, "%uU", literal.is.ULong); + break; + case V_ULONGLONG: + valueImg = os_malloc(40); + snprintf(valueImg, 40, "%" PA_PRIu64 "ULL", literal.is.ULongLong); + break; + case V_ADDRESS: + valueImg = os_malloc(40); + snprintf(valueImg, 40, PA_ADDRFMT, (PA_ADDRCAST)literal.is.Address); + break; + case V_CHAR: + valueImg = os_malloc(40); + snprintf(valueImg, 40, "%u", (unsigned char)literal.is.Char); + break; + case V_UNDEFINED: + case V_WCHAR: + case V_WSTRING: + case V_FIXED: + case V_VOIDP: + case V_OBJECT: + case V_COUNT: + /* Invalid types for literal constants*/ + /* FALL THROUGH */ + default: + valueImg = NULL; + break; + } + } else { + valueImg = os_strdup(c_metaObject(c_constant(c_enumeration(type)->elements[literal.is.Long]))->name); + } + + return valueImg; +} + void idl_definitionClean ( void diff --git a/src/tools/idlpp/code/idl_genCHelper.h b/src/tools/idlpp/code/idl_genCHelper.h index 65a964179..f1a7d752d 100644 --- a/src/tools/idlpp/code/idl_genCHelper.h +++ b/src/tools/idlpp/code/idl_genCHelper.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,7 +21,7 @@ #ifndef IDL_GENCHELPER_H #define IDL_GENCHELPER_H -#include "c_typebase.h" +#include "c_base.h" #include "idl_scope.h" #include "idl_program.h" @@ -31,14 +32,17 @@ c_char *idl_scopeStackC(idl_scope scope, const char *scopeSepp, const char *name c_char *idl_corbaCTypeFromTypeSpec(idl_typeSpec typeSpec); +c_char *idl_genCLiteralValueImage(c_value literal, c_type type); + /* clean definitions */ void idl_definitionClean(void); /* add a definition within the specified scope */ void idl_definitionAdd(char *class, char *name); -/* return 1 if the definition already exists within the specified scope */ -/* return 0 if the definition does not exists within the specified scope */ +/* return 1 if the definition already exists within the specified scope + * return 0 if the definition does not exists within the specified scope + */ int idl_definitionExists(char *class, char *name); c_char *idl_genCConstantGetter(void); diff --git a/src/tools/idlpp/code/idl_genCorbaCCopyin.c b/src/tools/idlpp/code/idl_genCorbaCCopyin.c index a8a43e954..2134cccd5 100644 --- a/src/tools/idlpp/code/idl_genCorbaCCopyin.c +++ b/src/tools/idlpp/code/idl_genCorbaCCopyin.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -49,7 +50,7 @@ /** Text indentation level (4 spaces per indent) */ static c_long loopIndent; - /** Index for array loop variables, incremented for each array dimension */ +/** Index for array loop variables, incremented for each array dimension */ static c_long varIndex; @@ -585,7 +586,8 @@ idl_structureMemberOpenClose( fileOut(file," }\n"); } else { /* Calls itself for the actual type in case of typedef */ - /* QAC EXPECT 3670; We wan't to use recursion, the recursion is finite */ + /* QAC EXPECT 3670; We wan't to use recursion, the recursion is finite + */ DEBUG_INFO; idl_structureMemberOpenClose( scope, name, idl_typeDefRefered(idl_typeDef(typeSpec)), userData); } @@ -1092,14 +1094,14 @@ idl_arrayLoopCopyBody( fileOut(file, "if(V_COPYIN_RESULT_IS_OK(result)){\n"); indent++; idl_printIndent(loopIndent + indent); - fileOut(file, "if(%s", from); + fileOut(file, "if((%s)", from); idl_arrayLoopCopyIndex(typeArray); fileOut(file, "){\n"); idl_printIndent(loopIndent + indent); if(maxlen != 0){ DEBUG_INFO; idl_printIndent(loopIndent + indent); - fileOut(file," if(((unsigned int)strlen(%s", from); + fileOut(file," if(((unsigned int)strlen((%s)", from); idl_arrayLoopCopyIndex(typeArray); fileOut(file,")) <= %u){\n", maxlen); idl_printIndent(loopIndent + indent); @@ -1107,14 +1109,14 @@ idl_arrayLoopCopyBody( { fileOut(file," strncpy(((*%s)", to); idl_arrayLoopCopyIndex(typeArray); - fileOut(file,"), (%s", from); + fileOut(file,"), ((%s)", from); idl_arrayLoopCopyIndex(typeArray); fileOut(file,"), %u);\n", (maxlen+1)); } else { fileOut(file," (*%s)", to); idl_arrayLoopCopyIndex(typeArray); - fileOut(file," = c_stringNew_s(base, %s", from); + fileOut(file," = c_stringNew_s(base, (%s)", from); idl_arrayLoopCopyIndex(typeArray); fileOut(file,");\n"); idl_printIndent(loopIndent + indent); @@ -1141,7 +1143,7 @@ idl_arrayLoopCopyBody( idl_printIndent(loopIndent + indent); fileOut(file," (*%s)", to); idl_arrayLoopCopyIndex(typeArray); - fileOut(file," = c_stringNew_s(base, %s", from); + fileOut(file," = c_stringNew_s(base, (%s)", from); idl_arrayLoopCopyIndex(typeArray); fileOut(file,");\n"); idl_printIndent(loopIndent + indent); @@ -1174,18 +1176,18 @@ idl_arrayLoopCopyBody( { fileOut(file," strncpy(((*%s)", to); idl_arrayLoopCopyIndex(typeArray); - fileOut(file,"), (%s", from); + fileOut(file,"), ((%s)", from); idl_arrayLoopCopyIndex(typeArray); fileOut(file,"), %u);\n", (maxlen+1)); } else { fileOut(file," (*%s)", to); idl_arrayLoopCopyIndex(typeArray); - fileOut(file," = c_stringNew_s(base, %s", from); + fileOut(file," = c_stringNew_s(base, (%s)", from); idl_arrayLoopCopyIndex(typeArray); fileOut(file,");\n"); idl_printIndent(loopIndent + indent); - fileOut(file," if ((%s", from); + fileOut(file," if (((%s)", from); idl_arrayLoopCopyIndex(typeArray); fileOut(file," != NULL) && ((*%s)", to); idl_arrayLoopCopyIndex(typeArray); @@ -1204,7 +1206,7 @@ idl_arrayLoopCopyBody( idl_printIndent(loopIndent + indent); fileOut(file," (*%s)", to); idl_arrayLoopCopyIndex(typeArray); - fileOut(file," = %s", from); + fileOut(file," = (%s)", from); idl_arrayLoopCopyIndex(typeArray); fileOut(file,";\n"); } @@ -1382,7 +1384,7 @@ idl_arrayLoopCopyBody( idl_printIndent(total_indent); fileOut(file," c_ulong length0;\n"); idl_printIndent(total_indent); - fileOut(file," %s *src0 = &%s;\n", idl_sequenceIdent(idl_typeSeq(typeSpec)), source); + fileOut(file," const %s *src0 = &%s;\n", idl_sequenceIdent(idl_typeSeq(typeSpec)), source); idl_printIndent(total_indent); fileOut(file," %s *dst0;\n\n", idl_scopedSplTypeName(nextType)); idl_printIndent(total_indent); @@ -1646,7 +1648,7 @@ idl_arrayElements( if (idl_typeBasicType(idl_typeBasic(subType)) == idl_string) { idl_arrayLoopCopy(typeArray, from, to, indent, scope, name, stacRequested, catsRequested, noTypeCaching); } else { - /*stac requested should be covered by the above if statement, as + /* stac requested should be covered by the above if statement, as * stac always involves strings. And if this basic type is not a string * then stac requested can not be true */ @@ -1722,6 +1724,149 @@ idl_arrayElements( } } +static void +insertCopyBodySequence( + idl_typeSpec typeSpec, + const char *from, + c_long loop_index, + c_long indent, + idl_scope scope, + const c_char* name, + os_boolean noTypeCaching) +{ + c_char destin[32]; + idl_typeSpec nextType; + c_ulong maxlen; + c_char *typeName; + + while (idl_typeSpecType (typeSpec) == idl_ttypedef) { + typeSpec = idl_typeDefActual(idl_typeDef(typeSpec)); + } + + nextType = idl_typeSeqType(idl_typeSeq(typeSpec)); + + if (idl_typeSpecType(nextType) == idl_tbasic) { + if (idl_typeBasicMaxlen(idl_typeBasic(nextType)) > 0) { + typeName = idl_scopeStack(idl_typeUserScope(idl_typeUser(nextType)), "::", + idl_typeSpecName(nextType)); + } else { + typeName = idl_typeSpecName(nextType); + } + } else { + typeName = idl_scopeStack(idl_typeUserScope(idl_typeUser(nextType)), "::", + idl_typeSpecName(nextType)); + } + + maxlen = idl_typeSeqMaxSize(idl_typeSeq(typeSpec)); + + DEBUG_INFO; + idl_printIndent(indent); + fileOut(file," %sc_type type%d = NULL;\n", (!noTypeCaching) ? "static " : "", loop_index); + idl_printIndent(indent); + fileOut(file," c_type subtype%d;\n", loop_index); + idl_printIndent(indent); + fileOut(file," c_ulong length%d;\n", loop_index); + idl_printIndent(indent); + fileOut(file," %s *dst%d;\n", idl_scopedSplTypeIdent(nextType), loop_index); + idl_printIndent(indent); + fileOut(file," %s %s%d = &(%s%d)._buffer[i%d];\n", + idl_sequenceIdent(idl_typeSeq(typeSpec)), /* idl_scopedSacTypeIdent(nextType), */ + from, loop_index, from, loop_index-1, loop_index-1); + fileOut(file,"\n"); + idl_printIndent(indent); + fileOut(file," if (type%d == NULL) {\n", loop_index); + idl_printIndent(indent); + fileOut(file," subtype%d = c_type(c_metaResolve(c_metaObject(base), \"%s\"));\n",loop_index, typeName); + idl_printIndent(indent); + if(maxlen > 0){ + fileOut(file," type%d = c_metaSequenceTypeNew(c_metaObject(base),\"C_SEQUENCE<%s,%u>\",subtype%d,%u);\n", loop_index, typeName, maxlen, loop_index, maxlen); + } else { + fileOut(file," type%d = c_metaSequenceTypeNew(c_metaObject(base),\"C_SEQUENCE<%s>\",subtype%d,0);\n", loop_index, typeName, loop_index); + } + idl_printIndent(indent); + fileOut(file," c_free(subtype%d);\n", loop_index); + idl_printIndent(indent); + fileOut(file," }\n"); + idl_printIndent(indent); + + fileOut(file," length%d = (%s%d)._length;\n", loop_index, from, loop_index); + + if(maxlen > 0){ + DEBUG_INFO; + fileOut(file,"#ifdef %s\n", BOUNDSCHECK); + idl_printIndent(indent); + fileOut(file," if(length%d > %u){\n", loop_index, maxlen); + idl_printIndent (indent); + fileOut(file," "); + idl_boundsCheckFail(ELEMENT, scope, (idl_typeSpec)typeSpec, name); + idl_printIndent(indent); + fileOut(file," result = V_COPYIN_RESULT_INVALID;\n"); + idl_printIndent(indent); + fileOut(file," } else {\n"); + idl_printIndent(indent); + fileOut(file," dst%d = (%s *)c_newSequence_s(c_collectionType(type%d),length%d);\n", + loop_index, idl_scopedSplTypeIdent(nextType), loop_index, loop_index); + idl_printIndent(indent); + fileOut(file," if (dst%d != NULL) {\n", loop_index); + snprintf(destin, sizeof(destin), "dst%d", loop_index); + idl_seqLoopCopy(nextType, from, destin, loop_index+1, indent+4, scope, name, noTypeCaching); + idl_printIndent(indent); + fileOut(file," dst%d[i%d] = (c_sequence)dst%d;\n", + loop_index-1, loop_index-1, loop_index); + idl_printIndent(indent); + fileOut(file," } else {\n"); + idl_memoryAllocFailed(scope, (idl_typeSpec)typeSpec, name, indent + 4); + idl_printIndent(indent); + fileOut(file," result = V_COPYIN_RESULT_OUT_OF_MEMORY;\n"); + idl_printIndent(indent); + fileOut(file," }\n"); + idl_printIndent(indent); + fileOut(file," }\n"); + fileOut(file,"#else\n"); + idl_printIndent(indent); + fileOut(file," dst%d = (%s *)c_newSequence_s(c_collectionType(type%d),length%d);\n", + loop_index, idl_scopedSplTypeIdent(nextType), loop_index, loop_index); + idl_printIndent(indent); + fileOut(file," if (dst%d != NULL) {\n", loop_index); + snprintf(destin, sizeof(destin), "dst%d", loop_index); + idl_seqLoopCopy(nextType, from, destin, loop_index+1, indent+3, scope, name, noTypeCaching); + idl_printIndent(indent); + fileOut(file," dst%d[i%d] = (c_sequence)dst%d;\n", + loop_index-1, loop_index-1, loop_index); + idl_printIndent(indent); + fileOut(file," } else {\n"); + idl_memoryAllocFailed(scope, (idl_typeSpec)typeSpec, name, indent + 3); + idl_printIndent(indent); + fileOut(file," result = V_COPYIN_RESULT_OUT_OF_MEMORY;\n"); + idl_printIndent(indent); + fileOut(file," }\n"); + fileOut(file,"#endif\n"); + } else { + DEBUG_INFO; + idl_printIndent(indent); + fileOut(file," dst%d = (%s *)c_newSequence_s(c_collectionType(type%d),length%d);\n", + loop_index, idl_scopedSplTypeIdent(nextType), loop_index, loop_index); + idl_printIndent(indent); + fileOut(file," if (dst%d != NULL) {\n", loop_index); + snprintf(destin, sizeof(destin), "dst%d", loop_index); + idl_seqLoopCopy(nextType, from, destin, loop_index+1, indent+3, scope, name, noTypeCaching); + idl_printIndent(indent); + fileOut(file," dst%d[i%d] = (c_sequence)dst%d;\n", + loop_index-1, loop_index-1, loop_index); + idl_printIndent(indent); + fileOut(file," } else {\n"); + idl_memoryAllocFailed(scope, (idl_typeSpec)typeSpec, name, indent + 3); + idl_printIndent(indent); + fileOut(file," result = V_COPYIN_RESULT_OUT_OF_MEMORY;\n"); + idl_printIndent(indent); + fileOut(file," }\n"); + } + if(noTypeCaching){ + idl_printIndent(indent); + idl_fileOutPrintf(file, " c_free(type%d);\n", loop_index); + } +} + /** @brief Function that generates code for copying sequences. * * Generate code for copying sequence types. @@ -1801,10 +1946,8 @@ idl_seqLoopCopy( const c_char* name, os_boolean noTypeCaching) { - c_char destin[32]; idl_typeSpec nextType; c_ulong maxlen; - c_char *typeName; if (idl_isContiguous(idl_typeSpecDef(typeSpec))) { if(idl_typeSpecType (typeSpec) == idl_tenum){ @@ -1957,7 +2100,11 @@ idl_seqLoopCopy( idl_scopedTypeName(typeSpec), from, loop_index-1, loop_index-1, idl_scopedSplTypeIdent(typeSpec), to, loop_index-1); break; case idl_ttypedef: - switch (idl_typeSpecType(idl_typeDefActual(idl_typeDef(typeSpec)))) { + nextType = idl_typeDefActual(idl_typeDef(typeSpec)); + while (idl_typeSpecType(nextType) == idl_ttypedef) { + nextType = idl_typeDefActual(idl_typeDef(nextType)); + } + switch (idl_typeSpecType(nextType)) { case idl_tstruct: case idl_tunion: case idl_tarray: @@ -2080,6 +2227,9 @@ idl_seqLoopCopy( to, loop_index-1, idl_scopedSplTypeName(typeSpec), from, loop_index-1, loop_index-1); fileOut(file,"#endif\n"); break; + case idl_tseq: + insertCopyBodySequence(typeSpec, from, loop_index, indent, scope, name, noTypeCaching); + break; default: printf ("idl_seqLoopCopy: Unexpected type\n"); assert (0); @@ -2087,128 +2237,7 @@ idl_seqLoopCopy( } break; case idl_tseq: - nextType = idl_typeSeqType(idl_typeSeq(typeSpec)); - - if (idl_typeSpecType(nextType) == idl_tbasic) { - if (idl_typeBasicMaxlen(idl_typeBasic(nextType)) > 0) { - typeName = idl_scopeStack(idl_typeUserScope(idl_typeUser(nextType)), "::", - idl_typeSpecName(nextType)); - } else { - typeName = idl_typeSpecName(nextType); - } - } else { - typeName = idl_scopeStack(idl_typeUserScope(idl_typeUser(nextType)), "::", - idl_typeSpecName(nextType)); - } - - maxlen = idl_typeSeqMaxSize(idl_typeSeq(typeSpec)); - - DEBUG_INFO; - idl_printIndent(indent); - fileOut(file," %sc_type type%d = NULL;\n", (!noTypeCaching) ? "static " : "", loop_index); - idl_printIndent(indent); - fileOut(file," c_type subtype%d;\n", loop_index); - idl_printIndent(indent); - fileOut(file," c_ulong length%d;\n", loop_index); - idl_printIndent(indent); - fileOut(file," %s *dst%d;\n", idl_scopedSplTypeIdent(nextType), loop_index); - idl_printIndent(indent); - fileOut(file," %s %s%d = &(%s%d)._buffer[i%d];\n", - idl_sequenceIdent(idl_typeSeq(typeSpec)), /* idl_scopedSacTypeIdent(nextType), */ - from, loop_index, from, loop_index-1, loop_index-1); - fileOut(file,"\n"); - idl_printIndent(indent); - fileOut(file," if (type%d == NULL) {\n", loop_index); - idl_printIndent(indent); - fileOut(file," subtype%d = c_type(c_metaResolve(c_metaObject(base), \"%s\"));\n",loop_index, typeName); - idl_printIndent(indent); - if(maxlen > 0){ - fileOut(file," type%d = c_metaSequenceTypeNew(c_metaObject(base),\"C_SEQUENCE<%s,%u>\",subtype%d,%u);\n", loop_index, typeName, maxlen, loop_index, maxlen); - } else { - fileOut(file," type%d = c_metaSequenceTypeNew(c_metaObject(base),\"C_SEQUENCE<%s>\",subtype%d,0);\n", loop_index, typeName, loop_index); - } - idl_printIndent(indent); - fileOut(file," c_free(subtype%d);\n", loop_index); - idl_printIndent(indent); - fileOut(file," }\n"); - idl_printIndent(indent); - - fileOut(file," length%d = (%s%d)._length;\n", loop_index, from, loop_index); - - if(maxlen > 0){ - DEBUG_INFO; - fileOut(file,"#ifdef %s\n", BOUNDSCHECK); - idl_printIndent(indent); - fileOut(file," if(length%d > %u){\n", loop_index, maxlen); - idl_printIndent (indent); - fileOut(file," "); - idl_boundsCheckFail(ELEMENT, scope, (idl_typeSpec)typeSpec, name); - idl_printIndent(indent); - fileOut(file," result = V_COPYIN_RESULT_INVALID;\n"); - idl_printIndent(indent); - fileOut(file," } else {\n"); - idl_printIndent(indent); - fileOut(file," dst%d = (%s *)c_newSequence_s(c_collectionType(type%d),length%d);\n", - loop_index, idl_scopedSplTypeIdent(nextType), loop_index, loop_index); - idl_printIndent(indent); - fileOut(file," if (dst%d != NULL) {\n", loop_index); - snprintf(destin, sizeof(destin), "dst%d", loop_index); - idl_seqLoopCopy(nextType, from, destin, loop_index+1, indent+4, scope, name, noTypeCaching); - idl_printIndent(indent); - fileOut(file," dst%d[i%d] = (c_sequence)dst%d;\n", - loop_index-1, loop_index-1, loop_index); - idl_printIndent(indent); - fileOut(file," } else {\n"); - idl_memoryAllocFailed(scope, (idl_typeSpec)typeSpec, name, indent + 4); - idl_printIndent(indent); - fileOut(file," result = V_COPYIN_RESULT_OUT_OF_MEMORY;\n"); - idl_printIndent(indent); - fileOut(file," }\n"); - idl_printIndent(indent); - fileOut(file," }\n"); - fileOut(file,"#else\n"); - idl_printIndent(indent); - fileOut(file," dst%d = (%s *)c_newSequence_s(c_collectionType(type%d),length%d);\n", - loop_index, idl_scopedSplTypeIdent(nextType), loop_index, loop_index); - idl_printIndent(indent); - fileOut(file," if (dst%d != NULL) {\n", loop_index); - snprintf(destin, sizeof(destin), "dst%d", loop_index); - idl_seqLoopCopy(nextType, from, destin, loop_index+1, indent+3, scope, name, noTypeCaching); - idl_printIndent(indent); - fileOut(file," dst%d[i%d] = (c_sequence)dst%d;\n", - loop_index-1, loop_index-1, loop_index); - idl_printIndent(indent); - fileOut(file," } else {\n"); - idl_memoryAllocFailed(scope, (idl_typeSpec)typeSpec, name, indent + 3); - idl_printIndent(indent); - fileOut(file," result = V_COPYIN_RESULT_OUT_OF_MEMORY;\n"); - idl_printIndent(indent); - fileOut(file," }\n"); - fileOut(file,"#endif\n"); - } else { - DEBUG_INFO; - idl_printIndent(indent); - fileOut(file," dst%d = (%s *)c_newSequence_s(c_collectionType(type%d),length%d);\n", - loop_index, idl_scopedSplTypeIdent(nextType), loop_index, loop_index); - idl_printIndent(indent); - fileOut(file," if (dst%d != NULL) {\n", loop_index); - snprintf(destin, sizeof(destin), "dst%d", loop_index); - idl_seqLoopCopy(nextType, from, destin, loop_index+1, indent+3, scope, name, noTypeCaching); - idl_printIndent(indent); - fileOut(file," dst%d[i%d] = (c_sequence)dst%d;\n", - loop_index-1, loop_index-1, loop_index); - idl_printIndent(indent); - fileOut(file," } else {\n"); - idl_memoryAllocFailed(scope, (idl_typeSpec)typeSpec, name, indent + 3); - idl_printIndent(indent); - fileOut(file," result = V_COPYIN_RESULT_OUT_OF_MEMORY;\n"); - idl_printIndent(indent); - fileOut(file," }\n"); - } - if(noTypeCaching){ - idl_printIndent(indent); - idl_fileOutPrintf(file, " c_free(type%d);\n", loop_index); - } + insertCopyBodySequence(typeSpec, from, loop_index, indent, scope, name, noTypeCaching); break; default: assert (0); diff --git a/src/tools/idlpp/code/idl_genCorbaCCopyin.h b/src/tools/idlpp/code/idl_genCorbaCCopyin.h index b5e50c4db..4c2387f80 100644 --- a/src/tools/idlpp/code/idl_genCorbaCCopyin.h +++ b/src/tools/idlpp/code/idl_genCorbaCCopyin.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/idlpp/code/idl_genCorbaCCopyout.c b/src/tools/idlpp/code/idl_genCorbaCCopyout.c index 50d20e7e3..52bbdfda0 100644 --- a/src/tools/idlpp/code/idl_genCorbaCCopyout.c +++ b/src/tools/idlpp/code/idl_genCorbaCCopyout.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -560,7 +561,7 @@ idl_structureMemberOpenClose ( snprintf (type_name, sizeof(type_name), "_%s_seq", name); idl_fileOutPrintf (idl_fileCur(), " {\n"); - idl_fileOutPrintf (idl_fileCur(), " long size0;\n"); + idl_fileOutPrintf (idl_fileCur(), " DDS_unsigned_long size0;\n"); idl_fileOutPrintf (idl_fileCur(), " const %s *src0 = (const %s *)from->%s;\n", idl_scopedSplTypeIdent(nextType), idl_scopedSplTypeIdent(nextType), @@ -932,7 +933,7 @@ idl_arrayLoopCopyBody ( snprintf (destin, sizeof(destin), "(%s)", to); idl_arrayLoopCopyIndexString (destin, typeArray); idl_printIndent (total_indent); - idl_fileOutPrintf (idl_fileCur(), " long size0;\n"); + idl_fileOutPrintf (idl_fileCur(), " DDS_unsigned_long size0;\n"); idl_printIndent (total_indent); snprintf (source, sizeof(source), "(*%s)", from); idl_arrayLoopCopyIndexString (source, typeArray); @@ -1197,6 +1198,59 @@ idl_seqIndex ( return os_strdup(index); } +static void +insertCopyBodySequence( + idl_typeSpec typeSpec, + const char *to, + c_long loop_index, + c_long indent) +{ + c_char source[32]; + + idl_typeSpec nextType = idl_typeSeqType(idl_typeSeq(typeSpec)); + idl_printIndent (indent); + idl_fileOutPrintf (idl_fileCur(), " c_ulong size%d;\n", loop_index); + idl_printIndent (indent); + idl_fileOutPrintf(idl_fileCur(), " %s *src%d = (%s *)src%d%s;\n", + idl_scopedSplTypeIdent(nextType), + loop_index, + idl_scopedSplTypeIdent(nextType), + loop_index - 1, + idl_seqIndex(loop_index)); + idl_printIndent (indent); + idl_fileOutPrintf (idl_fileCur(), " %s *dst%d = (%s *)&dst%d->_buffer[i%d];\n", + idl_sequenceIdent (idl_typeSeq(typeSpec)), + loop_index, + idl_sequenceIdent (idl_typeSeq(typeSpec)), + loop_index-1, + loop_index-1); + idl_fileOutPrintf (idl_fileCur(), "\n"); + idl_printIndent (indent); + idl_fileOutPrintf (idl_fileCur(), " size%d = c_arraySize((c_sequence)(src%d));\n", + loop_index, + loop_index); + if (idl_typeSeqMaxSize(idl_typeSeq(typeSpec)) == 0) { + /* For unbounded sequence set maximum size */ + idl_printIndent (indent); + idl_fileOutPrintf (idl_fileCur(), " DDS_sequence_replacebuf ((_DDS_sequence) dst%d, (bufferAllocatorType)%s_allocbuf, size%d);\n", + loop_index, + idl_sequenceIdent (idl_typeSeq(typeSpec)), + loop_index); + } else { + idl_printIndent (indent); + idl_fileOutPrintf (idl_fileCur(), " DDS_sequence_replacebuf ((_DDS_sequence) dst%d, (bufferAllocatorType)%s_allocbuf, %d);\n", + loop_index, + idl_sequenceIdent (idl_typeSeq(typeSpec)), + idl_typeSeqMaxSize(idl_typeSeq(typeSpec))); + } + idl_printIndent (indent); + idl_fileOutPrintf (idl_fileCur(), " dst%d->_length = size%d;\n", + loop_index, + loop_index); + snprintf (source, sizeof(source), "src%d", loop_index); + idl_seqLoopCopy (nextType, source, to, loop_index+1, indent+1); +} + /** @brief Function that generates code for copying sequences. * * Generate code for copying sequence types. @@ -1270,9 +1324,6 @@ idl_seqLoopCopy ( c_long loop_index, c_long indent) { - c_char source[32]; - idl_typeSpec nextType; - if (idl_isContiguous(idl_typeSpecDef(typeSpec))) { idl_printIndent (indent); idl_fileOutPrintf (idl_fileCur(), "memcpy ((%s%d)._buffer,%s,size%d* sizeof(*((%s%d)._buffer)));\n", @@ -1282,7 +1333,7 @@ idl_seqLoopCopy ( idl_printIndent (indent); idl_fileOutPrintf (idl_fileCur(), "{\n"); idl_printIndent (indent); - idl_fileOutPrintf (idl_fileCur(), " long i%d;\n", loop_index-1); + idl_fileOutPrintf (idl_fileCur(), " DDS_unsigned_long i%d;\n", loop_index-1); idl_printIndent (indent); idl_fileOutPrintf (idl_fileCur(), " for (i%d = 0; i%d < size%d; i%d++) {\n", loop_index-1, @@ -1388,54 +1439,16 @@ idl_seqLoopCopy ( from, loop_index-1); break; + case idl_tseq: + insertCopyBodySequence(idl_typeDefActual(idl_typeDef(typeSpec)), to, loop_index, indent); + break; default: printf ("idl_arrayLoopCopyBody: Unexpected type\n"); assert (0); } break; case idl_tseq: - nextType = idl_typeSeqType(idl_typeSeq(typeSpec)); - idl_printIndent (indent); - idl_fileOutPrintf (idl_fileCur(), " c_ulong size%d;\n", loop_index); - idl_printIndent (indent); - idl_fileOutPrintf(idl_fileCur(), " %s *src%d = (%s *)src%d%s;\n", - idl_scopedSplTypeIdent(nextType), - loop_index, - idl_scopedSplTypeIdent(nextType), - loop_index - 1, - idl_seqIndex(loop_index)); - idl_printIndent (indent); - idl_fileOutPrintf (idl_fileCur(), " %s *dst%d = (%s *)&dst%d->_buffer[i%d];\n", - idl_sequenceIdent (idl_typeSeq(typeSpec)), - loop_index, - idl_sequenceIdent (idl_typeSeq(typeSpec)), - loop_index-1, - loop_index-1); - idl_fileOutPrintf (idl_fileCur(), "\n"); - idl_printIndent (indent); - idl_fileOutPrintf (idl_fileCur(), " size%d = c_arraySize((c_sequence)(src%d));\n", - loop_index, - loop_index); - if (idl_typeSeqMaxSize(idl_typeSeq(typeSpec)) == 0) { - /* For unbounded sequence set maximum size */ - idl_printIndent (indent); - idl_fileOutPrintf (idl_fileCur(), " DDS_sequence_replacebuf ((_DDS_sequence) dst%d, (bufferAllocatorType)%s_allocbuf, size%d);\n", - loop_index, - idl_sequenceIdent (idl_typeSeq(typeSpec)), - loop_index); - } else { - idl_printIndent (indent); - idl_fileOutPrintf (idl_fileCur(), " DDS_sequence_replacebuf ((_DDS_sequence) dst%d, (bufferAllocatorType)%s_allocbuf, %d);\n", - loop_index, - idl_sequenceIdent (idl_typeSeq(typeSpec)), - idl_typeSeqMaxSize(idl_typeSeq(typeSpec))); - } - idl_printIndent (indent); - idl_fileOutPrintf (idl_fileCur(), " dst%d->_length = size%d;\n", - loop_index, - loop_index); - snprintf (source, sizeof(source), "src%d", loop_index); - idl_seqLoopCopy (nextType, source, to, loop_index+1, indent+1); + insertCopyBodySequence(typeSpec, to, loop_index, indent); break; default: assert (0); @@ -1895,7 +1908,7 @@ idl_unionCaseOpenClose ( snprintf (type_name, sizeof(type_name), "_%s_seq", name); idl_fileOutPrintf (idl_fileCur(), " {\n"); - idl_fileOutPrintf (idl_fileCur(), " long size0;\n"); + idl_fileOutPrintf (idl_fileCur(), " DDS_unsigned_long size0;\n"); idl_fileOutPrintf (idl_fileCur(), " const %s *src0 = (const %s *)from->_u.%s;\n", idl_scopedSplTypeName(nextType), idl_scopedSplTypeName(nextType), diff --git a/src/tools/idlpp/code/idl_genCorbaCCopyout.h b/src/tools/idlpp/code/idl_genCorbaCCopyout.h index 986f66731..14bda14fa 100644 --- a/src/tools/idlpp/code/idl_genCorbaCCopyout.h +++ b/src/tools/idlpp/code/idl_genCorbaCCopyout.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/idlpp/code/idl_genCorbaCHelper.c b/src/tools/idlpp/code/idl_genCorbaCHelper.c index 7bb87f3e0..c1e51a2c2 100644 --- a/src/tools/idlpp/code/idl_genCorbaCHelper.c +++ b/src/tools/idlpp/code/idl_genCorbaCHelper.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/idlpp/code/idl_genCorbaCHelper.h b/src/tools/idlpp/code/idl_genCorbaCHelper.h index 8b90570ec..e18546af7 100644 --- a/src/tools/idlpp/code/idl_genCorbaCHelper.h +++ b/src/tools/idlpp/code/idl_genCorbaCHelper.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/idlpp/code/idl_genCorbaCxxCcpp.c b/src/tools/idlpp/code/idl_genCorbaCxxCcpp.c index bc5a7d37f..ae8a64e56 100644 --- a/src/tools/idlpp/code/idl_genCorbaCxxCcpp.c +++ b/src/tools/idlpp/code/idl_genCorbaCxxCcpp.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -72,7 +73,7 @@ idl_fileOpen ( c_char *tmplPath; c_char *orbPath = NULL; int tmplFile; - struct os_stat tmplStat; + struct os_stat_s tmplStat; unsigned int nRead; os_char* tmpName; os_uint32 i; diff --git a/src/tools/idlpp/code/idl_genCorbaCxxCcpp.h b/src/tools/idlpp/code/idl_genCorbaCxxCcpp.h index 9b6b011a1..a3cd3abfa 100644 --- a/src/tools/idlpp/code/idl_genCorbaCxxCcpp.h +++ b/src/tools/idlpp/code/idl_genCorbaCxxCcpp.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/idlpp/code/idl_genCorbaCxxCopyin.c b/src/tools/idlpp/code/idl_genCorbaCxxCopyin.c index 12e1e5077..654794e9e 100644 --- a/src/tools/idlpp/code/idl_genCorbaCxxCopyin.c +++ b/src/tools/idlpp/code/idl_genCorbaCxxCopyin.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -222,7 +223,11 @@ idl_structureOpen ( idl_fileOutPrintf (idl_fileCur(), "v_copyin_result\n"); idl_fileOutPrintf (idl_fileCur(), "__%s__copyIn(\n", idl_scopeStack (scope, "_", name)); - idl_fileOutPrintf (idl_fileCur(), " c_base base,\n"); + if (idl_getIsISOCpp2()) { + idl_fileOutPrintf (idl_fileCur(), " c_type dbType,\n"); + } else { + idl_fileOutPrintf (idl_fileCur(), " c_base base,\n"); + } if (idl_getIsISOCpp() && idl_getIsISOCppTypes()) { idl_fileOutPrintf (idl_fileCur(), " const class %s *from,\n", @@ -237,6 +242,9 @@ idl_structureOpen ( idl_scopeStack(scope, "_", name)); idl_fileOutPrintf (idl_fileCur(), "{\n"); idl_fileOutPrintf (idl_fileCur(), " v_copyin_result result = V_COPYIN_RESULT_OK;\n"); + if (idl_getIsISOCpp2()) { + idl_fileOutPrintf (idl_fileCur(), " c_base base = c_getBase(dbType);\n"); + } idl_fileOutPrintf (idl_fileCur(), " (void) base;\n\n"); return idl_explore; @@ -688,12 +696,14 @@ idl_structureMemberOpenClose ( (idl_typeSpecType(idl_typeDefActual(idl_typeDef(typeSpec))) == idl_tseq)) { idl_fileOutPrintf (idl_fileCur(), " if(V_COPYIN_RESULT_IS_OK(result)){\n"); - idl_fileOutPrintf (idl_fileCur(), " extern v_copyin_result __%s__copyIn(c_base, const %s *, _%s *);\n", + idl_fileOutPrintf (idl_fileCur(), " extern v_copyin_result __%s__copyIn(%s, const %s *, _%s *);\n", idl_scopedTypeName (typeSpec), + idl_getIsISOCpp2() ? "c_type" : "c_base", idl_corbaCxxTypeFromTypeSpec(typeSpec), idl_scopedTypeName (typeSpec)); - idl_fileOutPrintf (idl_fileCur(), " result = __%s__copyIn(base, &from->%s%s, &to->%s);\n", + idl_fileOutPrintf (idl_fileCur(), " result = __%s__copyIn(%s, &from->%s%s, &to->%s);\n", idl_scopedTypeName (typeSpec), + idl_getIsISOCpp2() ? "dbType" : "base", cid, idl_isocppCxxStructMemberSuffix(), cid); @@ -741,12 +751,14 @@ idl_structureMemberOpenClose ( } else if ((idl_typeSpecType(typeSpec) == idl_tstruct) || (idl_typeSpecType(typeSpec) == idl_tunion)) { idl_fileOutPrintf (idl_fileCur(), " if(V_COPYIN_RESULT_IS_OK(result)){\n"); - idl_fileOutPrintf (idl_fileCur(), " extern v_copyin_result __%s__copyIn(c_base, const %s *, _%s *);\n", + idl_fileOutPrintf (idl_fileCur(), " extern v_copyin_result __%s__copyIn(%s, const %s *, _%s *);\n", idl_scopedTypeName (typeSpec), + idl_getIsISOCpp2() ? "c_type" : "c_base", idl_corbaCxxTypeFromTypeSpec(typeSpec), idl_scopedTypeName (typeSpec)); - idl_fileOutPrintf (idl_fileCur(), " result = __%s__copyIn(base, &from->%s%s, &to->%s);\n", + idl_fileOutPrintf (idl_fileCur(), " result = __%s__copyIn(%s, &from->%s%s, &to->%s);\n", idl_scopedTypeName (typeSpec), + idl_getIsISOCpp2() ? "dbType" : "base", cid, idl_isocppCxxStructMemberSuffix(), cid); @@ -1143,8 +1155,9 @@ idl_arrayLoopCopyBody( case idl_tunion: idl_printIndent(loopIndent + indent); varIndex = 0; - idl_fileOutPrintf(idl_fileCur(), "extern v_copyin_result __%s__copyIn(c_base base,\n", - idl_scopedTypeName(typeSpec)); + idl_fileOutPrintf(idl_fileCur(), "extern v_copyin_result __%s__copyIn(%s,\n", + idl_scopedTypeName(typeSpec), + idl_getIsISOCpp2() ? "c_type" : "c_base"); idl_printIndent(indent); idl_fileOutPrintf(idl_fileCur(), "const %s *From,\n", idl_scopeStack(idl_typeUserScope(idl_typeUser(typeSpec)), "::", idl_typeSpecName(typeSpec))); @@ -1154,8 +1167,9 @@ idl_arrayLoopCopyBody( idl_fileOutPrintf(idl_fileCur(), "if(V_COPYIN_RESULT_IS_OK(result)){\n"); indent++; idl_printIndent (loopIndent + indent); - idl_fileOutPrintf (idl_fileCur(),"result = __%s__copyIn(base, (%s *)&(%s)", + idl_fileOutPrintf (idl_fileCur(),"result = __%s__copyIn(%s, (%s *)&(%s)", idl_scopedTypeName(typeSpec), + idl_getIsISOCpp2() ? "dbType" : "base", idl_corbaCxxTypeFromTypeSpec(typeSpec), from); idl_arrayLoopCopyIndex(typeArray); @@ -1207,8 +1221,9 @@ idl_arrayLoopCopyBody( case idl_tarray: case idl_tseq: idl_printIndent (loopIndent + indent); - idl_fileOutPrintf(idl_fileCur(), "extern v_copyin_result __%s__copyIn(c_base base,", - idl_scopedTypeName(typeSpec)); + idl_fileOutPrintf(idl_fileCur(), "extern v_copyin_result __%s__copyIn(%s,", + idl_scopedTypeName(typeSpec), + idl_getIsISOCpp2() ? "c_type" : "c_base"); idl_fileOutPrintf(idl_fileCur(), "const %s *From,", idl_scopeStack(idl_typeUserScope(idl_typeUser(typeSpec)), "::", idl_typeSpecName(typeSpec))); idl_fileOutPrintf(idl_fileCur(), "%s *To);\n\n", @@ -1217,8 +1232,9 @@ idl_arrayLoopCopyBody( idl_fileOutPrintf(idl_fileCur(), "if(V_COPYIN_RESULT_IS_OK(result)){\n"); indent++; idl_printIndent (loopIndent + indent); - idl_fileOutPrintf (idl_fileCur(),"result = __%s__copyIn(base, (%s *)&(%s)", + idl_fileOutPrintf (idl_fileCur(),"result = __%s__copyIn(%s, (%s *)&(%s)", idl_scopedTypeName(typeSpec), + idl_getIsISOCpp2() ? "dbType" : "base", idl_corbaCxxTypeFromTypeSpec(typeSpec), from); idl_arrayLoopCopyIndex(typeArray); @@ -2221,8 +2237,9 @@ idl_seqLoopCopy ( case idl_tunion: varIndex = 0; idl_printIndent (indent); - idl_fileOutPrintf (idl_fileCur(), " extern v_copyin_result __%s__copyIn(c_base base,\n", - idl_scopedTypeName(typeSpec)); + idl_fileOutPrintf (idl_fileCur(), " extern v_copyin_result __%s__copyIn(%s,\n", + idl_scopedTypeName(typeSpec), + idl_getIsISOCpp2() ? "c_type" : "c_base"); idl_printIndent (indent); idl_fileOutPrintf (idl_fileCur(), " const %s *From,\n", idl_scopeStack (idl_typeUserScope(idl_typeUser(typeSpec)), "::", idl_typeSpecName(typeSpec))); @@ -2230,8 +2247,9 @@ idl_seqLoopCopy ( idl_fileOutPrintf (idl_fileCur(), " %s *To);\n\n", idl_scopedSplTypeIdent(typeSpec)); idl_printIndent (indent); - idl_fileOutPrintf (idl_fileCur(), " result = __%s__copyIn(base, &(%s)%s, (%s *)&%s[i%d]);\n", + idl_fileOutPrintf (idl_fileCur(), " result = __%s__copyIn(%s, &(%s)%s, (%s *)&%s[i%d]);\n", idl_scopedTypeName(typeSpec), + idl_getIsISOCpp2() ? "dbType" : "base", from, idl_seqIndex(loop_index), idl_scopedSplTypeIdent(typeSpec), @@ -2246,13 +2264,15 @@ idl_seqLoopCopy ( case idl_tarray: idl_fileOutPrintf (idl_fileCur(), " if(V_COPYIN_RESULT_IS_OK(result)){\n"); idl_printIndent (indent); - idl_fileOutPrintf (idl_fileCur(), " extern v_copyin_result __%s__copyIn(c_base, const %s *, _%s *);\n", + idl_fileOutPrintf (idl_fileCur(), " extern v_copyin_result __%s__copyIn(%s, const %s *, _%s *);\n", idl_scopedTypeName (typeSpec), + idl_getIsISOCpp2() ? "c_type" : "c_base", idl_corbaCxxTypeFromTypeSpec(typeSpec), idl_scopedTypeName (typeSpec)); idl_printIndent (indent); - idl_fileOutPrintf (idl_fileCur(), " result = __%s__copyIn(base, &(%s)%s, (%s *)&%s[i%d]);\n", + idl_fileOutPrintf (idl_fileCur(), " result = __%s__copyIn(%s, &(%s)%s, (%s *)&%s[i%d]);\n", idl_scopedTypeName(typeSpec), + idl_getIsISOCpp2() ? "dbType" : "base", from, idl_seqIndex(loop_index), idl_scopedSplTypeName(typeSpec), @@ -2510,6 +2530,13 @@ idl_seqLoopCopy ( idl_printIndent (indent); idl_fileOutPrintf (idl_fileCur(), " c_free(type%d);\n", loop_index); } + if (idl_typeSpecType(nextType) == idl_tbasic) { + if (idl_typeBasicMaxlen(idl_typeBasic(nextType)) > 0) { + os_free(typeName); + } + } else { + os_free(typeName); + } os_free(scopedName); break; default: @@ -2588,6 +2615,7 @@ idl_seqLoopCopy ( idl_printIndent (indent); idl_fileOutPrintf (idl_fileCur(), " c_free(type%d);\n", loop_index); } + os_free(scopedName); break; default: assert (0); @@ -2745,19 +2773,25 @@ idl_typedefOpenClose ( idl_fileOutPrintf (idl_fileCur(), "v_copyin_result\n"); idl_fileOutPrintf (idl_fileCur(), "__%s__copyIn(\n", idl_scopeStack (scope, "_", name)); - idl_fileOutPrintf (idl_fileCur(), " c_base base,\n"); + if (idl_getIsISOCpp2()) { + idl_fileOutPrintf (idl_fileCur(), " c_type dbType,\n"); + } else { + idl_fileOutPrintf (idl_fileCur(), " c_base base,\n"); + } idl_fileOutPrintf (idl_fileCur(), " const %s *from,\n", idl_scopeStackCxx (scope, "::", name)); idl_fileOutPrintf (idl_fileCur(), " _%s *to)\n", idl_scopeStack(scope, "_", name)); idl_fileOutPrintf (idl_fileCur(), "{\n"); idl_fileOutPrintf (idl_fileCur(), " v_copyin_result result = V_COPYIN_RESULT_OK;\n\n"); - idl_fileOutPrintf (idl_fileCur(), " extern v_copyin_result __%s__copyIn(c_base, const %s *, _%s *);\n", + idl_fileOutPrintf (idl_fileCur(), " extern v_copyin_result __%s__copyIn(%s, const %s *, _%s *);\n", idl_scopedTypeName (idl_typeDefActual(defSpec)), + idl_getIsISOCpp2() ? "c_type" : "c_base", idl_corbaCxxTypeFromTypeSpec(idl_typeDefActual(defSpec)), idl_scopedTypeName (idl_typeDefActual(defSpec))); - idl_fileOutPrintf (idl_fileCur(), " result = __%s__copyIn(base, (%s *)from, (%s *)to);\n", + idl_fileOutPrintf (idl_fileCur(), " result = __%s__copyIn(%s, (%s *)from, (%s *)to);\n", idl_scopedTypeName(idl_typeDefActual(defSpec)), + idl_getIsISOCpp2() ? "dbType" : "base", idl_corbaCxxTypeFromTypeSpec(idl_typeDefActual(defSpec)), idl_scopedSplTypeName(idl_typeDefActual(defSpec))); idl_fileOutPrintf (idl_fileCur(), " return result;\n"); @@ -2768,13 +2802,20 @@ idl_typedefOpenClose ( idl_fileOutPrintf (idl_fileCur(), "v_copyin_result\n"); idl_fileOutPrintf (idl_fileCur(), "__%s__copyIn(\n", idl_scopeStack (scope, "_", name)); - idl_fileOutPrintf (idl_fileCur(), " c_base base,\n"); + if (idl_getIsISOCpp2()) { + idl_fileOutPrintf (idl_fileCur(), " c_type dbType,\n"); + } else { + idl_fileOutPrintf (idl_fileCur(), " c_base base,\n"); + } idl_fileOutPrintf (idl_fileCur(), " const %s *from,\n", - idl_scopeStackCxx (scope, "::", name)); + idl_scopeStackCxx (scope, "::", name)); idl_fileOutPrintf (idl_fileCur(), " _%s *to)\n", - idl_scopeStack(scope, "_", name)); + idl_scopeStack(scope, "_", name)); idl_fileOutPrintf (idl_fileCur(), "{\n"); idl_fileOutPrintf (idl_fileCur(), " v_copyin_result result = V_COPYIN_RESULT_OK;\n"); + if (idl_getIsISOCpp2()) { + idl_fileOutPrintf (idl_fileCur(), " c_base base = c_getBase(dbType);\n\n"); + } idl_fileOutPrintf (idl_fileCur(), " (void) base;\n\n"); idl_arrayElements (scope, idl_typeArray(idl_typeDefActual(defSpec)), "*from", "to", 0, OS_FALSE, OS_FALSE, userData); idl_fileOutPrintf (idl_fileCur(), " return result;\n"); @@ -2785,13 +2826,20 @@ idl_typedefOpenClose ( idl_fileOutPrintf (idl_fileCur(), "v_copyin_result\n"); idl_fileOutPrintf (idl_fileCur(), "__%s__copyIn(\n", idl_scopeStack (scope, "_", name)); - idl_fileOutPrintf (idl_fileCur(), " c_base base,\n"); + if (idl_getIsISOCpp2()) { + idl_fileOutPrintf (idl_fileCur(), " c_type dbType,\n"); + } else { + idl_fileOutPrintf (idl_fileCur(), " c_base base,\n"); + } idl_fileOutPrintf (idl_fileCur(), " const %s *from,\n", - idl_scopeStackCxx (scope, "::", name)); + idl_scopeStackCxx (scope, "::", name)); idl_fileOutPrintf (idl_fileCur(), " _%s *to)\n", - idl_scopeStack(scope, "_", name)); + idl_scopeStack(scope, "_", name)); idl_fileOutPrintf (idl_fileCur(), "{\n"); idl_fileOutPrintf (idl_fileCur(), " v_copyin_result result = V_COPYIN_RESULT_OK;\n"); + if (idl_getIsISOCpp2()) { + idl_fileOutPrintf (idl_fileCur(), " c_base base = c_getBase(dbType);\n\n"); + } idl_fileOutPrintf (idl_fileCur(), " (void) base;\n\n"); idl_seqElements (scope, name, idl_typeSeq(idl_typeDefActual(defSpec)), 0, userData); idl_fileOutPrintf (idl_fileCur(), " return result;\n"); @@ -2870,13 +2918,20 @@ idl_unionOpen ( idl_fileOutPrintf (idl_fileCur(), "v_copyin_result\n"); idl_fileOutPrintf (idl_fileCur(), "__%s__copyIn(\n", idl_scopeStack (scope, "_", name)); - idl_fileOutPrintf (idl_fileCur(), " c_base base,\n"); + if (idl_getIsISOCpp2()) { + idl_fileOutPrintf (idl_fileCur(), " c_type dbType,\n"); + } else { + idl_fileOutPrintf (idl_fileCur(), " c_base base,\n"); + } idl_fileOutPrintf (idl_fileCur(), " const %s *from,\n", idl_scopeStackCxx (scope, "::", name)); idl_fileOutPrintf (idl_fileCur(), " struct _%s *to)\n", idl_scopeStack(scope, "_", name)); idl_fileOutPrintf (idl_fileCur(), "{\n"); idl_fileOutPrintf (idl_fileCur(), " v_copyin_result result = V_COPYIN_RESULT_OK;\n"); + if (idl_getIsISOCpp2()) { + idl_fileOutPrintf (idl_fileCur(), " c_base base = c_getBase(dbType);\n\n"); + } idl_fileOutPrintf (idl_fileCur(), " (void) base;\n\n"); /* QAC EXPECT 3416; No side effect here */ if (idl_typeSpecType(idl_typeUnionSwitchKind(unionSpec)) == idl_tbasic) { @@ -3075,47 +3130,53 @@ idl_unionCaseOpenClose ( } else if (idl_typeSpecType(typeSpec) == idl_ttypedef) { if (idl_typeSpecType(idl_typeDefRefered(idl_typeDef(typeSpec))) == idl_tarray && idl_getIsISOCpp() && idl_getIsISOCppTypes()) { idl_fileOutPrintf (idl_fileCur(), " if(V_COPYIN_RESULT_IS_OK(result)){\n"); - idl_fileOutPrintf (idl_fileCur(), " extern v_copyin_result __%s__copyIn(c_base, const %s *, _%s *);\n", - idl_scopedTypeName (typeSpec), - idl_corbaCxxTypeFromTypeSpec(typeSpec), - idl_scopedTypeName (typeSpec)); + idl_fileOutPrintf (idl_fileCur(), " extern v_copyin_result __%s__copyIn(%s, const %s *, _%s *);\n", + idl_scopedTypeName (typeSpec), + idl_getIsISOCpp2() ? "c_type" : "c_base", + idl_corbaCxxTypeFromTypeSpec(typeSpec), + idl_scopedTypeName (typeSpec)); idl_fileOutPrintf (idl_fileCur(), " const %s &x = from->%s();\n", - idl_corbaCxxTypeFromTypeSpec(typeSpec), - cid); - idl_fileOutPrintf (idl_fileCur(), " result = __%s__copyIn(base, &x, &to->_u.%s);\n", - idl_scopedTypeName (typeSpec), - cid); + idl_corbaCxxTypeFromTypeSpec(typeSpec), + cid); + idl_fileOutPrintf (idl_fileCur(), " result = __%s__copyIn(%s, &x, &to->_u.%s);\n", + idl_scopedTypeName (typeSpec), + idl_getIsISOCpp2() ? "dbType" : "base", + cid); idl_fileOutPrintf (idl_fileCur(), " }\n"); idl_fileOutPrintf (idl_fileCur(), " break;\n"); } /* QAC EXPECT 3416; No side effect here */ else if (idl_typeSpecType(idl_typeDefRefered(idl_typeDef(typeSpec))) == idl_tarray) { idl_fileOutPrintf (idl_fileCur(), " if(V_COPYIN_RESULT_IS_OK(result)){\n"); - idl_fileOutPrintf (idl_fileCur(), " extern v_copyin_result __%s__copyIn(c_base, const %s *, _%s *);\n", + idl_fileOutPrintf (idl_fileCur(), " extern v_copyin_result __%s__copyIn(%s, const %s *, _%s *);\n", idl_scopedTypeName (typeSpec), + idl_getIsISOCpp2() ? "c_type" : "c_base", idl_corbaCxxTypeFromTypeSpec(typeSpec), idl_scopedTypeName (typeSpec)); idl_fileOutPrintf (idl_fileCur(), " const %s *x = (const %s *)from->%s();\n", idl_corbaCxxTypeFromTypeSpec(typeSpec), idl_corbaCxxTypeFromTypeSpec(typeSpec), cid); - idl_fileOutPrintf (idl_fileCur(), " result = __%s__copyIn(base, x, &to->_u.%s);\n", + idl_fileOutPrintf (idl_fileCur(), " result = __%s__copyIn(%s, x, &to->_u.%s);\n", idl_scopedTypeName (typeSpec), + idl_getIsISOCpp2() ? "dbType" : "base", cid); idl_fileOutPrintf (idl_fileCur(), " }\n"); idl_fileOutPrintf (idl_fileCur(), " break;\n"); /* QAC EXPECT 3416; No side effect here */ } else if (idl_typeSpecType(idl_typeDefRefered(idl_typeDef(typeSpec))) == idl_tseq) { idl_fileOutPrintf (idl_fileCur(), " if(V_COPYIN_RESULT_IS_OK(result)){\n"); - idl_fileOutPrintf (idl_fileCur(), " extern v_copyin_result __%s__copyIn(c_base, const %s *, _%s *);\n", + idl_fileOutPrintf (idl_fileCur(), " extern v_copyin_result __%s__copyIn(%s, const %s *, _%s *);\n", idl_scopedTypeName (typeSpec), + idl_getIsISOCpp2() ? "c_type" : "c_base", idl_corbaCxxTypeFromTypeSpec(typeSpec), idl_scopedTypeName (typeSpec)); idl_fileOutPrintf (idl_fileCur(), " const %s &x = from->%s();\n", idl_corbaCxxTypeFromTypeSpec(typeSpec), cid); - idl_fileOutPrintf (idl_fileCur(), " result = __%s__copyIn(base, &x, &to->_u.%s);\n", + idl_fileOutPrintf (idl_fileCur(), " result = __%s__copyIn(%s, &x, &to->_u.%s);\n", idl_scopedTypeName (typeSpec), + idl_getIsISOCpp2() ? "dbType" : "base", cid); idl_fileOutPrintf (idl_fileCur(), " }\n"); idl_fileOutPrintf (idl_fileCur(), " break;\n"); @@ -3156,30 +3217,34 @@ idl_unionCaseOpenClose ( /* QAC EXPECT 3416; No side effect here */ } else if (idl_typeSpecType(typeSpec) == idl_tstruct) { idl_fileOutPrintf (idl_fileCur(), " if(V_COPYIN_RESULT_IS_OK(result)){\n"); - idl_fileOutPrintf (idl_fileCur(), " extern v_copyin_result __%s__copyIn(c_base, const %s *, _%s *);\n", + idl_fileOutPrintf (idl_fileCur(), " extern v_copyin_result __%s__copyIn(%s, const %s *, _%s *);\n", idl_scopedTypeName (typeSpec), + idl_getIsISOCpp2() ? "c_type" : "c_base", idl_corbaCxxTypeFromTypeSpec(typeSpec), idl_scopedTypeName (typeSpec)); idl_fileOutPrintf (idl_fileCur(), " const %s &x = from->%s();\n", idl_corbaCxxTypeFromTypeSpec(typeSpec), cid); - idl_fileOutPrintf (idl_fileCur(), " result = __%s__copyIn(base, &x, &to->_u.%s);\n", + idl_fileOutPrintf (idl_fileCur(), " result = __%s__copyIn(%s, &x, &to->_u.%s);\n", idl_scopedTypeName (typeSpec), + idl_getIsISOCpp2() ? "dbType" : "base", cid); idl_fileOutPrintf (idl_fileCur(), " }\n"); idl_fileOutPrintf (idl_fileCur(), " break;\n"); /* QAC EXPECT 3416; No side effect here */ } else if (idl_typeSpecType(typeSpec) == idl_tunion) { idl_fileOutPrintf (idl_fileCur(), " if(V_COPYIN_RESULT_IS_OK(result)){\n"); - idl_fileOutPrintf (idl_fileCur(), " extern v_copyin_result __%s__copyIn(c_base, const %s *, _%s *);\n", + idl_fileOutPrintf (idl_fileCur(), " extern v_copyin_result __%s__copyIn(%s, const %s *, _%s *);\n", idl_scopedTypeName (typeSpec), + idl_getIsISOCpp2() ? "c_type" : "c_base", idl_corbaCxxTypeFromTypeSpec(typeSpec), idl_scopedTypeName (typeSpec)); idl_fileOutPrintf (idl_fileCur(), " const %s &x = from->%s();\n", idl_corbaCxxTypeFromTypeSpec(typeSpec), cid); - idl_fileOutPrintf (idl_fileCur(), " result = __%s__copyIn(base, &x, &to->_u.%s);\n", + idl_fileOutPrintf (idl_fileCur(), " result = __%s__copyIn(%s, &x, &to->_u.%s);\n", idl_scopedTypeName (typeSpec), + idl_getIsISOCpp2() ? "dbType" : "base", cid); idl_fileOutPrintf (idl_fileCur(), " }\n"); idl_fileOutPrintf (idl_fileCur(), " break;\n"); diff --git a/src/tools/idlpp/code/idl_genCorbaCxxCopyin.h b/src/tools/idlpp/code/idl_genCorbaCxxCopyin.h index adc57ab9a..0d005a99b 100644 --- a/src/tools/idlpp/code/idl_genCorbaCxxCopyin.h +++ b/src/tools/idlpp/code/idl_genCorbaCxxCopyin.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/idlpp/code/idl_genCorbaCxxCopyout.c b/src/tools/idlpp/code/idl_genCorbaCxxCopyout.c index f4ccfe413..27d3269bd 100644 --- a/src/tools/idlpp/code/idl_genCorbaCxxCopyout.c +++ b/src/tools/idlpp/code/idl_genCorbaCxxCopyout.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -1201,7 +1202,7 @@ idl_arrayElements( idl_arrayLoopCopy(typeArray, buf, to, indent, stacRequested, catsRequested); os_free(buf); } else { - idl_printIndent(indent); + idl_printIndent(indent); idl_fileOutPrintf(idl_fileCur(), " memcpy ((void *)%s, %s, sizeof (*%s));\n", cpyTo, from, from); } /* QAC EXPECT 3416; No side effect here */ diff --git a/src/tools/idlpp/code/idl_genCorbaCxxCopyout.h b/src/tools/idlpp/code/idl_genCorbaCxxCopyout.h index cf6c2746e..2586773cf 100644 --- a/src/tools/idlpp/code/idl_genCorbaCxxCopyout.h +++ b/src/tools/idlpp/code/idl_genCorbaCxxCopyout.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/idlpp/code/idl_genCorbaCxxHelper.c b/src/tools/idlpp/code/idl_genCorbaCxxHelper.c index bf7c75454..68c0f7d7d 100644 --- a/src/tools/idlpp/code/idl_genCorbaCxxHelper.c +++ b/src/tools/idlpp/code/idl_genCorbaCxxHelper.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -71,7 +72,7 @@ idl_metaCxxSerialize2XML( if (!metaElmnt->descriptor) { - metaElmnt->descriptor = idl_cutXMLmeta(idl_genXMLmeta(metaElmnt->type), &metaElmnt->nrElements, &metaElmnt->descriptorLength); + metaElmnt->descriptor = idl_cutXMLmeta(idl_genXMLmeta(metaElmnt->type, TRUE), &metaElmnt->nrElements, &metaElmnt->descriptorLength); } } diff --git a/src/tools/idlpp/code/idl_genCorbaCxxHelper.h b/src/tools/idlpp/code/idl_genCorbaCxxHelper.h index bb1cd2809..df4e01f95 100644 --- a/src/tools/idlpp/code/idl_genCorbaCxxHelper.h +++ b/src/tools/idlpp/code/idl_genCorbaCxxHelper.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/idlpp/code/idl_genCorbaCxxStreamsCcpp.c b/src/tools/idlpp/code/idl_genCorbaCxxStreamsCcpp.c index a273ef3b9..8ea1521aa 100644 --- a/src/tools/idlpp/code/idl_genCorbaCxxStreamsCcpp.c +++ b/src/tools/idlpp/code/idl_genCorbaCxxStreamsCcpp.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -71,7 +72,7 @@ idl_fileOpen ( c_char *tmplPath; c_char *orbPath; int tmplFile; - struct os_stat tmplStat; + struct os_stat_s tmplStat; unsigned int nRead; os_char* tmpName; os_uint32 i; diff --git a/src/tools/idlpp/code/idl_genCorbaCxxStreamsCcpp.h b/src/tools/idlpp/code/idl_genCorbaCxxStreamsCcpp.h index eddb1f378..437d4b7a6 100644 --- a/src/tools/idlpp/code/idl_genCorbaCxxStreamsCcpp.h +++ b/src/tools/idlpp/code/idl_genCorbaCxxStreamsCcpp.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/idlpp/code/idl_genCorbaJavaHelper.c b/src/tools/idlpp/code/idl_genCorbaJavaHelper.c index 8927d4ade..ce19201c1 100644 --- a/src/tools/idlpp/code/idl_genCorbaJavaHelper.c +++ b/src/tools/idlpp/code/idl_genCorbaJavaHelper.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/idlpp/code/idl_genCorbaJavaHelper.h b/src/tools/idlpp/code/idl_genCorbaJavaHelper.h index c02d37d86..db06b3b70 100644 --- a/src/tools/idlpp/code/idl_genCorbaJavaHelper.h +++ b/src/tools/idlpp/code/idl_genCorbaJavaHelper.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/idlpp/code/idl_genCxxHelper.c b/src/tools/idlpp/code/idl_genCxxHelper.c index ad0630ccf..e56c49af3 100644 --- a/src/tools/idlpp/code/idl_genCxxHelper.c +++ b/src/tools/idlpp/code/idl_genCxxHelper.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/idlpp/code/idl_genCxxHelper.h b/src/tools/idlpp/code/idl_genCxxHelper.h index 5c9ea5867..fdcdb0f4c 100644 --- a/src/tools/idlpp/code/idl_genCxxHelper.h +++ b/src/tools/idlpp/code/idl_genCxxHelper.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/idlpp/code/idl_genCxxMeta.h b/src/tools/idlpp/code/idl_genCxxMeta.h index 1878d38d3..65d69c19c 100644 --- a/src/tools/idlpp/code/idl_genCxxMeta.h +++ b/src/tools/idlpp/code/idl_genCxxMeta.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/idlpp/code/idl_genCxxStreamsDefs.c b/src/tools/idlpp/code/idl_genCxxStreamsDefs.c index b2d2f80f8..a870c6979 100644 --- a/src/tools/idlpp/code/idl_genCxxStreamsDefs.c +++ b/src/tools/idlpp/code/idl_genCxxStreamsDefs.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -52,7 +53,7 @@ idl_fileOpen( c_char *tmplPath; c_char *orbPath; int tmplFile; - struct os_stat tmplStat; + struct os_stat_s tmplStat; unsigned int nRead; OS_UNUSED_ARG(scope); diff --git a/src/tools/idlpp/code/idl_genCxxStreamsDefs.h b/src/tools/idlpp/code/idl_genCxxStreamsDefs.h index 41eeca5cb..450b4bb2b 100644 --- a/src/tools/idlpp/code/idl_genCxxStreamsDefs.h +++ b/src/tools/idlpp/code/idl_genCxxStreamsDefs.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/idlpp/code/idl_genCxxStreamsIdl.c b/src/tools/idlpp/code/idl_genCxxStreamsIdl.c index 72a844809..143a64223 100644 --- a/src/tools/idlpp/code/idl_genCxxStreamsIdl.c +++ b/src/tools/idlpp/code/idl_genCxxStreamsIdl.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -53,7 +54,7 @@ idl_fileOpen( c_char *tmplPath; c_char *orbPath; int tmplFile; - struct os_stat tmplStat; + struct os_stat_s tmplStat; unsigned int nRead; OS_UNUSED_ARG(scope); diff --git a/src/tools/idlpp/code/idl_genCxxStreamsIdl.h b/src/tools/idlpp/code/idl_genCxxStreamsIdl.h index 68d6d1537..1fb07ebbb 100644 --- a/src/tools/idlpp/code/idl_genCxxStreamsIdl.h +++ b/src/tools/idlpp/code/idl_genCxxStreamsIdl.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/idlpp/code/idl_genCxxStreamsImpl.c b/src/tools/idlpp/code/idl_genCxxStreamsImpl.c index 314d856bb..1d31d9f47 100644 --- a/src/tools/idlpp/code/idl_genCxxStreamsImpl.c +++ b/src/tools/idlpp/code/idl_genCxxStreamsImpl.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -49,7 +50,7 @@ idl_fileOpen( c_char *tmplPath; c_char *orbPath; int tmplFile; - struct os_stat tmplStat; + struct os_stat_s tmplStat; unsigned int nRead; OS_UNUSED_ARG(scope); diff --git a/src/tools/idlpp/code/idl_genCxxStreamsImpl.h b/src/tools/idlpp/code/idl_genCxxStreamsImpl.h index bcef80d75..1596ac994 100644 --- a/src/tools/idlpp/code/idl_genCxxStreamsImpl.h +++ b/src/tools/idlpp/code/idl_genCxxStreamsImpl.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/idlpp/code/idl_genCxxTypedClassDefs.c b/src/tools/idlpp/code/idl_genCxxTypedClassDefs.c index 6965724f4..d4b49e083 100644 --- a/src/tools/idlpp/code/idl_genCxxTypedClassDefs.c +++ b/src/tools/idlpp/code/idl_genCxxTypedClassDefs.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -54,7 +55,7 @@ idl_fileOpen( c_char *tmplPath; c_char *orbPath = NULL; int tmplFile; - struct os_stat tmplStat; + struct os_stat_s tmplStat; unsigned int nRead; (void) scope; /* Unused */ diff --git a/src/tools/idlpp/code/idl_genCxxTypedClassDefs.h b/src/tools/idlpp/code/idl_genCxxTypedClassDefs.h index 1410aac91..555586249 100644 --- a/src/tools/idlpp/code/idl_genCxxTypedClassDefs.h +++ b/src/tools/idlpp/code/idl_genCxxTypedClassDefs.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/idlpp/code/idl_genCxxTypedClassImpl.c b/src/tools/idlpp/code/idl_genCxxTypedClassImpl.c index db85ab595..ff9f7ed29 100644 --- a/src/tools/idlpp/code/idl_genCxxTypedClassImpl.c +++ b/src/tools/idlpp/code/idl_genCxxTypedClassImpl.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -57,7 +58,7 @@ idl_fileOpen( c_char *tmplPath; c_char *orbPath = NULL; int tmplFile; - struct os_stat tmplStat; + struct os_stat_s tmplStat; unsigned int nRead; CxxTypeUserData *cxxUserData = (CxxTypeUserData *)userData;; OS_UNUSED_ARG(scope); diff --git a/src/tools/idlpp/code/idl_genCxxTypedClassImpl.h b/src/tools/idlpp/code/idl_genCxxTypedClassImpl.h index 578ca310b..78681aa1f 100644 --- a/src/tools/idlpp/code/idl_genCxxTypedClassImpl.h +++ b/src/tools/idlpp/code/idl_genCxxTypedClassImpl.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/idlpp/code/idl_genFaceISOCxx2Tmpl.c b/src/tools/idlpp/code/idl_genFaceISOCxx2Tmpl.c index c244f668f..18e4b3800 100644 --- a/src/tools/idlpp/code/idl_genFaceISOCxx2Tmpl.c +++ b/src/tools/idlpp/code/idl_genFaceISOCxx2Tmpl.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -66,7 +67,7 @@ idl_fileOpen ( c_char tmplFacePath[64]; c_char *tmpl; int tmplFile; - struct os_stat tmplStat; + struct os_stat_s tmplStat; unsigned int nRead; os_char* tmpName; os_uint32 i; diff --git a/src/tools/idlpp/code/idl_genFaceISOCxx2Tmpl.h b/src/tools/idlpp/code/idl_genFaceISOCxx2Tmpl.h index cf8b7c5d7..bf1e2a46c 100644 --- a/src/tools/idlpp/code/idl_genFaceISOCxx2Tmpl.h +++ b/src/tools/idlpp/code/idl_genFaceISOCxx2Tmpl.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/idlpp/code/idl_genFaceJava.c b/src/tools/idlpp/code/idl_genFaceJava.c index 721e0181a..c06f039f9 100644 --- a/src/tools/idlpp/code/idl_genFaceJava.c +++ b/src/tools/idlpp/code/idl_genFaceJava.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -150,7 +151,7 @@ idl_genFaceInterface( char fname[128]; char *fullfname; char *javaId; - struct os_stat tmplStat; + struct os_stat_s tmplStat; os_size_t nRead; FILE *fp; diff --git a/src/tools/idlpp/code/idl_genFaceJava.h b/src/tools/idlpp/code/idl_genFaceJava.h index c4a16edfa..083418515 100644 --- a/src/tools/idlpp/code/idl_genFaceJava.h +++ b/src/tools/idlpp/code/idl_genFaceJava.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/idlpp/code/idl_genISOCxx2Copyin.c b/src/tools/idlpp/code/idl_genISOCxx2Copyin.c new file mode 100644 index 000000000..454dfdb0c --- /dev/null +++ b/src/tools/idlpp/code/idl_genISOCxx2Copyin.c @@ -0,0 +1,2588 @@ +/* + * OpenSplice DDS + * + * This software and documentation are Copyright 2006 to 2015 PrismTech + * Limited and its licensees. All rights reserved. See file: + * + * $OSPL_HOME/LICENSE + * + * for full copyright notice and license terms. + * + */ +/** + * @file + * This module generates CORBA C++ CopyIn functions. It handles input types + * that match the IDL/C++ mapping as specified by the OMG and writes the + * data into data types as applicable for the OpenSpliceDDS database. + */ + +#include "idl_program.h" +#include "idl_scope.h" +#include "idl_genISOCxx2Copyin.h" +#include "idl_genISOCxx2Helper.h" +#include "idl_genCxxHelper.h" +#include "idl_genSplHelper.h" +#include "idl_genLanguageHelper.h" +#include "idl_tmplExp.h" +#include "idl_catsDef.h" +#include "idl_stacDef.h" + +#include "c_typebase.h" +#include "os_heap.h" +#include "os_stdlib.h" +#include "os_abstract.h" + +/** Text indentation level (4 spaces per indent) */ +static c_long loopIndent; + /** Index for array loop variables, incremented for each array dimension */ +static c_long varIndex; + +static c_long memberIndex = -1; + +static c_long caseIndex = -1; + +static void +idl_arrayDimensions ( + idl_typeArray typeArray, + os_boolean resolveTypedefs); + +static void +idl_arrayElements ( + idl_scope scope, + idl_typeArray typeArray, + const char *from, + const char *to, + c_long indent, + os_boolean stacRequested, + os_boolean catsRequested, + void *userData); + +static void idl_seqElements (idl_scope scope, const char *name, idl_typeSeq typeSeq, c_long indent, void *userData); +static void idl_seqLoopCopy (idl_scope scope, idl_typeSpec typeSpec, const char *from, const char *to, c_long loop_index, c_long indent, void *userData); + + +/** @brief Generate a string representaion the literal value of a label + * in metadata terms. + * + * @param labelVal Specifies the kind and the value of the label + * @return String representing the image of \b labelVal + */ +static c_char * +idl_valueFromLabelVal ( + idl_labelVal labelVal) +{ + static c_char labelName [1000]; + + /* QAC EXPECT 3416; No side effect here */ + if (idl_labelValType(idl_labelVal(labelVal)) == idl_lenum) { + c_char *labelEnumVal = idl_labelEnumVal(idl_labelEnum(labelVal)); + snprintf (labelName, sizeof(labelName), "_%s", labelEnumVal); + os_free(labelEnumVal); + } else { + switch (idl_labelValueVal(idl_labelValue(labelVal)).kind) { + case V_CHAR: + snprintf (labelName, sizeof(labelName), "%u", idl_labelValueVal(idl_labelValue(labelVal)).is.Char); + break; + case V_SHORT: + snprintf (labelName, sizeof(labelName), "%d", idl_labelValueVal(idl_labelValue(labelVal)).is.Short); + break; + case V_USHORT: + snprintf(labelName, sizeof(labelName), "%u", idl_labelValueVal(idl_labelValue(labelVal) ).is.UShort); + break; + case V_LONG: + snprintf(labelName, sizeof(labelName), "%d", idl_labelValueVal(idl_labelValue(labelVal) ).is.Long); + break; + case V_ULONG: + snprintf(labelName, sizeof(labelName), "%u", idl_labelValueVal(idl_labelValue(labelVal) ).is.ULong); + break; + case V_LONGLONG: + snprintf(labelName, sizeof(labelName), "%"PA_PRId64, idl_labelValueVal(idl_labelValue(labelVal) ).is.LongLong); + break; + case V_ULONGLONG: + snprintf(labelName, sizeof(labelName), "%"PA_PRIu64, idl_labelValueVal(idl_labelValue(labelVal) ).is.ULongLong); + break; + case V_BOOLEAN: + /* QAC EXPECT 3416; No side effect here */ + if ((int) idl_labelValueVal(idl_labelValue(labelVal) ).is.Boolean == OS_C_TRUE) { + snprintf(labelName, sizeof(labelName), "OS_C_TRUE"); + } else { + snprintf(labelName, sizeof(labelName), "OS_C_FALSE"); + } + break; + default: + printf("idl_valueFromLabelVal: Unexpected label type\n"); + break; + } + } + return labelName; + /* QAC EXPECT 5101; Because of the switch statement the real complexity is rather low, no need to change */ +} + +/** @brief callback function called on opening the IDL input file. + * + * Generate code to include standard include files as well as + * OpenSpliceDDS specific include files: + * - v_kernel.h + * - v_topic.h + * - string.h + * + * @param scope Current scope (not used) + * @param name Name of the IDL input file (not used) + * @return Next action for this file (idl_explore) + */ +static idl_action +idl_fileOpen ( + idl_scope scope, + const char *name, + void *userData) +{ + OS_UNUSED_ARG(scope); + OS_UNUSED_ARG(name); + OS_UNUSED_ARG(userData); + + idl_fileOutPrintf (idl_fileCur(), "#include \n"); + idl_fileOutPrintf (idl_fileCur(), "#include \n"); + idl_fileOutPrintf (idl_fileCur(), "#include \n"); + idl_fileOutPrintf (idl_fileCur(), "#include \n"); + idl_fileOutPrintf (idl_fileCur(), "#include \n"); + idl_fileOutPrintf (idl_fileCur(), "\n"); + + return idl_explore; +} + +/** @brief callback function called on module definition in the IDL input file. + * + * Generate code for the following IDL construct: + * @verbatim + => module { + + }; + @endverbatim + * + * No action is required for IDL modules. + * + * @param scope Current scope (and scope of the module definition) + * @param name Name of the defined module + * @return Next action for this module (idl_explore) + */ +static idl_action +idl_moduleOpen ( + idl_scope scope, + const char *name, + void *userData) +{ + OS_UNUSED_ARG(scope); + OS_UNUSED_ARG(name); + OS_UNUSED_ARG(userData); + + return idl_explore; +} + +/** @brief callback function called on structure definition in the IDL input file. + * + * Generate code for the following IDL construct: + * @verbatim + => struct { + ; + ... ... + ; + }; + @endverbatim + * + * For structures a copyIn routine named _____copyIn + * will be prepared. The signature of this copyIn routine is: + * @verbatim + void copyIn (c_base base, + const :: *from, + struct __ *to); + @endverbatim + * + * The copyIn routine signature is generated based upon the input + * parameters which specify the scope and it's name. + * + * @param scope Current scope (and scope of the structure definition) + * @param name Name of the structure + * @param structSpec Specification of the struct holding the amount of members (not used) + * @return Next action for this struct (idl_explore) + */ +static idl_action +idl_structureOpen ( + idl_scope scope, + const char *name, + idl_typeStruct structSpec, + void *userData) +{ + c_char *cScopedName = idl_scopeStack(scope, "_", name); + c_char *cxxScopedName = idl_scopeStackISOCxx2(scope, "::", name); + + OS_UNUSED_ARG(structSpec); + OS_UNUSED_ARG(userData); + + idl_fileOutPrintf (idl_fileCur(), "v_copyin_result\n"); + idl_fileOutPrintf (idl_fileCur(), "__%s__copyIn(\n", cScopedName); + idl_fileOutPrintf (idl_fileCur(), " c_type dbType,\n"); + idl_fileOutPrintf (idl_fileCur(), " const class %s *from,\n", cxxScopedName); + idl_fileOutPrintf (idl_fileCur(), " struct _%s *to)\n", cScopedName); + idl_fileOutPrintf (idl_fileCur(), "{\n"); + idl_fileOutPrintf (idl_fileCur(), " v_copyin_result result = V_COPYIN_RESULT_OK;\n"); + idl_fileOutPrintf (idl_fileCur(), " (void) dbType;\n\n"); + + memberIndex = 0; + + os_free(cxxScopedName); + os_free(cScopedName); + + return idl_explore; +} + +/** @brief callback function called on end of a structure definition in the IDL input file. + * + * Generate code for the following IDL construct: + * @verbatim + struct { + + ... ... + + => }; + @endverbatim + * + * The function finalizes the copyIn routine for the structure by + * generating the closing bracket ('}'). + * + * @param name Name of the structure (not used) + */ +static void +idl_structureClose ( + const char *name, + void *userData) +{ + OS_UNUSED_ARG(name); + OS_UNUSED_ARG(userData); + + idl_fileOutPrintf (idl_fileCur(), " return result;\n"); + idl_fileOutPrintf (idl_fileCur(), "}\n"); + idl_fileOutPrintf (idl_fileCur(), "\n"); + + memberIndex = -1; +} + +/** @brief Generate copy statement for elements of basic type. + * + * The function generates for the provided basic type a copyIn + * statement. The identification of the source and destination + * elements must be provided by the caller. + * + * Basic type elements, apart from string types, are assigned + * immediately. Strings are duplicated calling c_stringNew. + * + * @param scope Scope of the element + * @param name Name of the element + * @param typeBasic Specification of the type of the element + * @param from_id Identification of the source + * @param Identification of the destination + */ +static void +idl_basicMemberType ( + idl_scope scope, + const char *name, + idl_typeBasic typeBasic, + const char *from_id, + const char *to_id, + os_boolean stacRequested) +{ + c_ulong maxlen; + c_char *idlType; + + OS_UNUSED_ARG(stacRequested); + + switch (idl_typeBasicType(typeBasic)) { + case idl_short: + case idl_ushort: + case idl_long: + case idl_ulong: + case idl_longlong: + case idl_ulonglong: + case idl_float: + case idl_double: + case idl_char: + case idl_boolean: + case idl_octet: + idlType = idl_typeFromTypeSpec (idl_typeSpec(typeBasic)); + idl_fileOutPrintf (idl_fileCur(), " %s%s = (%s)%s%s();\n", + to_id, + name, + idlType, + from_id, + name); + os_free(idlType); + break; + case idl_string: + maxlen = idl_typeBasicMaxlen(typeBasic); + if (maxlen != 0) { + idl_fileOutPrintf (idl_fileCur()," if(((unsigned int)%s%s().length()) <= %u){\n", + from_id, + name, + maxlen); + if(stacRequested) + { + idl_fileOutPrintf (idl_fileCur()," /* The strncpy takes a size of the maximum string bounds plus 1, as the database size accomodates this */\n"); + idl_fileOutPrintf(idl_fileCur(), " strncpy((%s%s), %s%s_.c_str(), %u);\n", + to_id, + name, + from_id, + name, + (maxlen+1)); + } else { + idl_fileOutPrintf(idl_fileCur(), " %s%s = c_stringNew(c_getBase(dbType), %s%s_.c_str());\n", + to_id, + name, + from_id, + name); + } + idl_fileOutPrintf (idl_fileCur()," } else {\n"); + idl_fileOutPrintf (idl_fileCur()," "); + idl_boundsCheckFail(MEMBER, scope, (idl_typeSpec)typeBasic, name); + idl_fileOutPrintf (idl_fileCur()," result = V_COPYIN_RESULT_INVALID;\n"); + idl_fileOutPrintf (idl_fileCur()," }\n"); + } else { + idl_fileOutPrintf (idl_fileCur(), " %s%s = c_stringNew(c_getBase(dbType), %s%s_.c_str());\n", + to_id, + name, + from_id, + name); + } + break; + default: + printf ("idl_basicMemberType: Unexpected basic type\n"); + break; + } +} + +/** @brief Generate copy statement for union case of basic type. + * + * The function generates for the provided basic type a copyIn + * statement. The identification of the source and destination + * elements must be provided by the caller. + * + * Basic type elements, apart from string types, are assigned + * immediately. Strings are duplicated calling c_stringNew. + * + * @param scope Scope of the element + * @param name Name of the element + * @param typeBasic Specification of the type of the element + * @param from_id Identification of the source + * @param Identification of the destination + */ +static void +idl_basicCaseType ( + idl_scope scope, + const char *name, + idl_typeBasic typeBasic, + const char *from_id, + const char *to_id) +{ + c_ulong maxlen; + c_char *idlType; + + switch (idl_typeBasicType(typeBasic)) { + case idl_short: + case idl_ushort: + case idl_long: + case idl_ulong: + case idl_longlong: + case idl_ulonglong: + case idl_float: + case idl_double: + case idl_char: + case idl_boolean: + case idl_octet: + idlType = idl_typeFromTypeSpec (idl_typeSpec(typeBasic)); + idl_fileOutPrintf (idl_fileCur(), " %s%s = (%s)%s%s();\n", + to_id, + name, + idl_typeFromTypeSpec (idl_typeSpec(typeBasic)), + from_id, + name); + os_free(idlType); + break; + case idl_string: + maxlen = idl_typeBasicMaxlen(typeBasic); + + if(maxlen != 0){ + idl_fileOutPrintf (idl_fileCur()," if((unsigned int) %s%s().length() <= %u){\n", + from_id, + name, + maxlen); + idl_fileOutPrintf(idl_fileCur(), " %s%s = c_stringNew(c_getBase(dbType), %s%s().c_str());\n", + to_id, + name, + from_id, + name); + idl_fileOutPrintf (idl_fileCur()," } else {\n"); + idl_fileOutPrintf (idl_fileCur()," "); + idl_boundsCheckFail(MEMBER, scope, (idl_typeSpec)typeBasic, name); + idl_fileOutPrintf (idl_fileCur()," result = V_COPYIN_RESULT_INVALID;\n"); + idl_fileOutPrintf (idl_fileCur()," }\n"); + } else { + idl_fileOutPrintf (idl_fileCur(), " %s%s = c_stringNew(c_getBase(dbType), %s%s().c_str());\n", + to_id, + name, + from_id, + name); + } + break; + default: + printf ("idl_basicCaseType: Unexpected basic type\n"); + break; + } +} + +/** @brief callback function called on definition of a structure member in the IDL input file. + * + * Generate code for the following IDL construct: + * @verbatim + struct { + => ; + => ... ... + => ; + }; + @endverbatim + * + * Depending on the type of the structure member, a copy strategy is used: + * - If the type is \b idl_tbasic, \b idl_basicMemberType is called to generate the + * copy code. + * - If the type is \b idl_typedef the copy strategy depends on the refered type. + * When this type is \b idl_tarray or \b idl_tseq a type specific copy routine + * is called. When type is something else, this routine is called recursively with + * with the refered type. + * - If the type is \b idl_tenum, the element is immediately assigned. + * - If the type is \b idl_tstruct or \b idl_tunion, the copyIn routine of that struct + * or union type is called. + * - If the type is \b idl_tarray the array copy context is set and the service + * to copy arrays is called. + * - If the type is \b idl_tseq, the sequence copy context is setup and the + * service to copy sequences is called. + * + * @param scope Current scope + * @param name Name of the structure member + * @param typeSpec Type specification of the structure member + */ +static void +idl_structureMemberOpenClose ( + idl_scope scope, + const char *name, + idl_typeSpec typeSpec, + void *userData) +{ + c_ulong maxlen; + c_char *typeName; + c_char *scopedName; + c_char* cxxName; + + cxxName = idl_ISOCxx2Id(name); + + /* Expected types: idl_tbasic, idl_ttypedef, idl_tenum, idl_tstruct, idl_tunion, idl_tarray, idl_tseq */ + + /* QAC EXPECT 3416; No side effect here */ + if (idl_typeSpecType(typeSpec) == idl_tbasic) { + os_boolean stacRequested = OS_FALSE; + /* is a stac pragma defined for this member? */ + stacRequested = idl_stacDef_isStacDefined(scope, name, typeSpec, NULL); + /* Handles all basic types, inclusive strings */ + idl_basicMemberType (scope, cxxName, idl_typeBasic(typeSpec), "from->", "to->", stacRequested); + /* QAC EXPECT 3416; No side effect here */ + } else if (idl_typeSpecType(typeSpec) == idl_ttypedef) { + os_boolean catsRequested = OS_FALSE; + os_boolean stacRequested = OS_FALSE; + idl_typeSpec typeDereffered; + + /* is a stac pragma defined for this member? */ + stacRequested = idl_stacDef_isStacDefined(scope, name, typeSpec, NULL); + if(!stacRequested) + { + /* Cats and stac def can not be defined over the same member as + * one excepts string types and the other char (array) types + */ + catsRequested = idl_catsDef_isCatsDefined(scope, name, typeSpec); + } + if(catsRequested || stacRequested) + { + /* if cats or stac is defined then resolve the first level of + * typedef and recurse deeper into the operation + */ + typeDereffered = idl_typeDefResolveFully(typeSpec); + idl_structureMemberOpenClose ( + scope, + cxxName, + typeDereffered, + userData); + } else { + /* QAC EXPECT 3416; No side effect here */ + if ((idl_typeSpecType(idl_typeDefActual(idl_typeDef(typeSpec))) == idl_tstruct) || + (idl_typeSpecType(idl_typeDefActual(idl_typeDef(typeSpec))) == idl_tunion) || + (idl_typeSpecType(idl_typeDefActual(idl_typeDef(typeSpec))) == idl_tarray) || + (idl_typeSpecType(idl_typeDefActual(idl_typeDef(typeSpec))) == idl_tseq)) { + scopedName = idl_scopedTypeName (typeSpec); + typeName = idl_ISOCxx2TypeFromTypeSpec(typeSpec); + + idl_fileOutPrintf (idl_fileCur(), " if(V_COPYIN_RESULT_IS_OK(result)){\n"); + idl_fileOutPrintf (idl_fileCur(), " extern v_copyin_result __%s__copyIn(c_type, const %s *, _%s *);\n", + scopedName, + typeName, + scopedName); + idl_fileOutPrintf (idl_fileCur(), " c_type type0 = c_memberType(c_structureMember(c_structure(dbType), %d));\n", memberIndex); + if (idl_typeSpecType(idl_typeDefActual(idl_typeDef(typeSpec))) == idl_tarray) { + idl_fileOutPrintf (idl_fileCur(), " while(c_baseObjectKind(type0) == M_COLLECTION && c_collectionTypeKind(type0) == OSPL_C_ARRAY) {;\n"); + idl_fileOutPrintf (idl_fileCur(), " type0 = c_collectionTypeSubType(type0);\n"); + idl_fileOutPrintf (idl_fileCur(), " }\n"); + } + idl_fileOutPrintf (idl_fileCur(), " result = __%s__copyIn(type0, &from->%s(), &to->%s);\n", + scopedName, + cxxName, + cxxName); + idl_fileOutPrintf (idl_fileCur(), " }\n"); + os_free(typeName); + os_free(scopedName); + } else { + /* Calls itself for the actual type in case of typedef */ + /* QAC EXPECT 3670; We wan't to use recursion, the recursion is finite */ + idl_structureMemberOpenClose ( + scope, + cxxName, + idl_typeDefActual(idl_typeDef(typeSpec)), + userData); + /* Compensate for recursion, where memberIndex will now be incremented twice. */ + memberIndex--; + } + } + /* QAC EXPECT 3416; No side effect here */ + } else if (idl_typeSpecType(typeSpec) == idl_tenum) { + c_char *dbTypeName = idl_scopedSplTypeName (typeSpec); + maxlen = idl_typeEnumNoElements(idl_typeEnum(typeSpec)); + + idl_fileOutPrintf (idl_fileCur(), " if((((c_long)from->%s()) >= 0) && (((c_long)from->%s()) < %d) ){\n", + cxxName , + cxxName, + maxlen); + idl_fileOutPrintf (idl_fileCur(), " to->%s = (%s)from->%s();\n", + cxxName, + dbTypeName, + cxxName); + idl_fileOutPrintf (idl_fileCur(), " } else {\n"); + idl_fileOutPrintf (idl_fileCur()," "); + idl_boundsCheckFail(MEMBER, scope, (idl_typeSpec)typeSpec, cxxName); + idl_fileOutPrintf (idl_fileCur(), " result = V_COPYIN_RESULT_INVALID;\n"); + idl_fileOutPrintf (idl_fileCur(), " }\n"); + + os_free(dbTypeName); + /* QAC EXPECT 3416; No side effect here */ + } else if ((idl_typeSpecType(typeSpec) == idl_tstruct) || + (idl_typeSpecType(typeSpec) == idl_tunion)) { + scopedName = idl_scopedTypeName (typeSpec); + typeName = idl_ISOCxx2TypeFromTypeSpec(typeSpec); + idl_fileOutPrintf (idl_fileCur(), " if(V_COPYIN_RESULT_IS_OK(result)){\n"); + idl_fileOutPrintf (idl_fileCur(), " extern v_copyin_result __%s__copyIn(c_type, const %s *, _%s *);\n", + scopedName, + typeName, + scopedName); + idl_fileOutPrintf (idl_fileCur(), " result = __%s__copyIn(c_memberType(c_structureMember(dbType, %d)), &from->%s(), &to->%s);\n", + scopedName, + memberIndex, + cxxName, + cxxName); + idl_fileOutPrintf (idl_fileCur(), " }\n"); + os_free(typeName); + os_free(scopedName); + /* QAC EXPECT 3416; No side effect here */ + } else if (idl_typeSpecType(typeSpec) == idl_tarray) { + c_char source[256]; + snprintf(source, sizeof(source), "from->%s()", cxxName); + { + os_boolean catsRequested = OS_FALSE; + os_boolean stacRequested = OS_FALSE; + idl_typeSpec baseTypeDereffered = NULL; + + /* is a stac pragma defined for this member? */ + stacRequested = idl_stacDef_isStacDefined(scope, name, typeSpec, &baseTypeDereffered); + if(!stacRequested) + { + /* Cats and stac def can not be defined over the same member as + * one excepts string types and the other char (array) types + */ + catsRequested = idl_catsDef_isCatsDefined(scope, name, typeSpec); + } + if(catsRequested) { + idl_fileOutPrintf(idl_fileCur()," {\n"); + idl_arrayElements (scope, idl_typeArray(typeSpec), source, cxxName, 1, stacRequested, catsRequested, userData); + idl_fileOutPrintf(idl_fileCur()," }\n"); + } else if(stacRequested) { + assert(!catsRequested); + assert(baseTypeDereffered); + idl_fileOutPrintf (idl_fileCur()," {\n"); + idl_fileOutPrintf (idl_fileCur()," typedef c_char _DestType"); + idl_arrayDimensions(idl_typeArray(typeSpec), OS_TRUE); + idl_fileOutPrintf (idl_fileCur(),"[%u]", idl_typeBasicMaxlen(idl_typeBasic(baseTypeDereffered))+1); + idl_fileOutPrintf (idl_fileCur(),";\n"); + idl_fileOutPrintf (idl_fileCur()," _DestType *dest = &to->%s;\n", cxxName); + idl_arrayElements (scope, idl_typeArray(typeSpec), source, "dest", 1, stacRequested, catsRequested, userData); + idl_fileOutPrintf (idl_fileCur()," }\n"); + } else { + idl_typeSpec subType = idl_typeArrayActual(idl_typeArray(typeSpec)); + c_char *dbSubType = idl_scopedSplTypeIdent(subType); + + idl_fileOutPrintf (idl_fileCur(), " {\n"); + idl_fileOutPrintf (idl_fileCur(), " typedef %s _DestType", dbSubType); + idl_arrayDimensions (idl_typeArray(typeSpec), OS_FALSE); + idl_fileOutPrintf (idl_fileCur(), ";\n"); + idl_fileOutPrintf (idl_fileCur(), " _DestType *dest = &to->%s;\n", cxxName); + idl_fileOutPrintf (idl_fileCur(), " c_type type0 = c_memberType(c_structureMember(c_structure(dbType), %d));\n", memberIndex); + idl_fileOutPrintf (idl_fileCur(), " while(c_baseObjectKind(type0) == M_COLLECTION && c_collectionTypeKind(type0) == OSPL_C_ARRAY) {;\n"); + idl_fileOutPrintf (idl_fileCur(), " type0 = c_collectionTypeSubType(type0);\n"); + idl_fileOutPrintf (idl_fileCur(), " }\n"); + idl_arrayElements (scope, idl_typeArray(typeSpec), source, "dest", 1, stacRequested, catsRequested, userData); + idl_fileOutPrintf (idl_fileCur(), " }\n"); + os_free(dbSubType); + } + } + /* QAC EXPECT 3416; No side effect here */ + } else if (idl_typeSpecType(typeSpec) == idl_tseq) { + c_char type_name[256]; + idl_typeSpec nextType; + c_char *cxxScopedName; + + nextType = idl_typeSeqType(idl_typeSeq(typeSpec)); + scopedName = idl_scopedSplTypeName(nextType); + + snprintf (type_name, sizeof(type_name), "_%s_seq", name); + maxlen = idl_typeSeqMaxSize(idl_typeSeq(typeSpec)); + cxxScopedName = idl_scopeStackCxx (scope, "::", type_name); + + if (idl_typeSpecType(nextType) == idl_tbasic) { + if (idl_typeBasicMaxlen(idl_typeBasic(nextType)) > 0) { + typeName = idl_scopeStack(scope, "::", idl_typeSpecName(nextType)); + } else { + typeName = idl_typeSpecName(nextType); + } + } else { + typeName = idl_scopeStack(idl_typeUserScope(idl_typeUser(nextType)), "::", idl_typeSpecName(nextType)); + } + + idl_fileOutPrintf (idl_fileCur(), " {\n"); + idl_fileOutPrintf (idl_fileCur(), " /* Code generated by %s at line %d */\n\n",__FILE__,__LINE__); + idl_fileOutPrintf (idl_fileCur(), " c_type type0 = c_memberType(c_structureMember(c_structure(dbType), %d));\n", memberIndex); + idl_fileOutPrintf (idl_fileCur(), " %s *dest0;\n", scopedName); + idl_fileOutPrintf (idl_fileCur(), " const %s *src = &from->%s();\n\n", cxxScopedName, cxxName); + idl_fileOutPrintf (idl_fileCur(), " c_ulong length0 = (c_ulong)(*src).size();\n"); + if(maxlen){ + idl_printIndent(1); + idl_fileOutPrintf(idl_fileCur(), " if(length0 > %u){\n", maxlen); + idl_printIndent(1); + idl_fileOutPrintf (idl_fileCur()," "); + idl_boundsCheckFail(MEMBER, scope, (idl_typeSpec)typeSpec, name); + idl_printIndent(1); + idl_fileOutPrintf(idl_fileCur(), " result = V_COPYIN_RESULT_INVALID;\n"); + idl_printIndent(1); + idl_fileOutPrintf(idl_fileCur(), " } else {\n"); + idl_printIndent(1); + idl_fileOutPrintf(idl_fileCur(), " dest0 = (%s *)c_newSequence(c_collectionType(type0), length0);\n", scopedName); + idl_seqLoopCopy(scope, nextType, "*src", "dest0", 1, 3, userData); + idl_fileOutPrintf(idl_fileCur(), " to->%s = (c_sequence) dest0;\n", cxxName); + idl_fileOutPrintf(idl_fileCur(), " }\n"); + } else { + idl_printIndent(1); + idl_fileOutPrintf(idl_fileCur(), " dest0 = (%s *)c_newSequence(c_collectionType(type0), length0);\n", scopedName); + idl_seqLoopCopy (scope, nextType, "*src", "dest0", 1, 2, userData); + idl_printIndent(1); + idl_fileOutPrintf (idl_fileCur(), " to->%s = (c_sequence) dest0;\n", + idl_cxxId(name)); + } + idl_fileOutPrintf(idl_fileCur(), " }\n"); + os_free(typeName); + os_free(cxxScopedName); + } else { + /* Do nothing, only to prevent dangling else-ifs QAC reports */ + } + /* QAC EXPECT 5103; Code is clearly separated in a number of cases of which each is maintainable */ + + os_free(cxxName); + memberIndex++; +} + +/** @brief Generate the array dimensions. + * + * Generate the dimensions of the array: + * @verbatim + [][]..[] + @endverbatim + * + * @param typeArray The type specification for the array which holds + * the basic type as wel as the size for each dimension. The first dimension + * is on top of that stack. + */ +static void +idl_arrayDimensions ( + idl_typeArray typeArray, + os_boolean resolveTypedefs) +{ + idl_typeSpec subType; + + idl_fileOutPrintf (idl_fileCur(), "[%u]", idl_typeArraySize(typeArray)); + subType = idl_typeArrayType(typeArray); + while(resolveTypedefs && idl_typeSpecType(subType) == idl_ttypedef) + { + subType = idl_typeDefResolveFully(subType); + } + /* QAC EXPECT 3416; No side effect here */ + if (idl_typeSpecType(subType) == idl_tarray) { + /* QAC EXPECT 3670; Recursive calls is a good practice, the recursion depth is limited here */ + idl_arrayDimensions (idl_typeArray(subType), resolveTypedefs); + } +} + +/** @brief Generate the loop variables for the array copy. + * + * Generate the loop variables for the array copy. Per dimension a + * loop variable named i# is required, where # represents the dimension. + * (I.e. first dimension handled by i1, second by i2, etc.) + * @verbatim + int i1; // dimension-first + int i2; // dimension-first+1 + .. + int i#; // dimension-last + @endverbatim + * + * @param typeArray The type specification for the array which holds + * the basic type as wel as the size for each dimension. The first dimension + * is on top of that stack. + * @param indent Indentation of the output + */ +static void +idl_arrayLoopVariables ( + idl_typeArray typeArray, + c_long indent) +{ + loopIndent++; + idl_printIndent(indent); + idl_fileOutPrintf(idl_fileCur(), " int i%d;\n", loopIndent); + /* QAC EXPECT 3416; No side effect here */ + if (idl_typeSpecType(idl_typeArrayType(typeArray)) == idl_tarray) { + /* QAC EXPECT 3670; Recursive calls is a good practice, the recursion depth is limited here */ + idl_arrayLoopVariables(idl_typeArray(idl_typeArrayType(typeArray)), indent); + } else { + idl_fileOutPrintf(idl_fileCur(), "\n"); + } + loopIndent--; +} + +/** @brief Generate copy loop for an array. + * + * Generate the for statement for copying an array. + * The variable \b loopIndent indicates the actual loop variable for this dimension. + * The variable indent indicates the positional index for the loop. + * @verbatim + for (i1 = 0; i1 < ; i1++) { + for (i2 = 0; i2 < ; i2++) { + .. + for (i# = 0; i# < ; i#++) { + @endverbatim + * + * @param typeArray The type specification for the array which holds + * the basic type as wel as the size for each dimension. The first dimension + * is on top of that stack. + * @param indent Indentation of the output + */ +static void +idl_arrayLoopCopyOpen ( + idl_typeArray typeArray, + c_long indent) +{ + loopIndent++; + idl_printIndent(loopIndent + indent); + idl_fileOutPrintf(idl_fileCur(), "for (i%d = 0; (i%d < %d) && result; i%d++) {\n", + loopIndent, + loopIndent, + idl_typeArraySize(typeArray), + loopIndent); + /* QAC EXPECT 3416; No side effect here */ + if (idl_typeSpecType(idl_typeArrayType(typeArray)) == idl_tarray) { + /* QAC EXPECT 3670; Recursive calls is a good practice, the recursion depth is limited here */ + idl_arrayLoopCopyOpen(idl_typeArray(idl_typeArrayType(typeArray)), indent); + } +} + +/** @brief Generate array index for copying array elements. + * + * Generate array index to the default output file. + * + * @verbatim + [i1][i2]..[i#] + @endverbatim + * + * @param typeArray The type specification for the array which holds + * the basic type as wel as the size for each dimension. The first dimension + * is on top of that stack. + */ +static void +idl_arrayLoopCopyIndex ( + idl_typeArray typeArray) +{ + varIndex++; + idl_fileOutPrintf(idl_fileCur(), "[i%d]", varIndex); + /* QAC EXPECT 3416; No side effect here */ + if (idl_typeSpecType(idl_typeArrayType(typeArray)) == idl_tarray) { + /* QAC EXPECT 3670; Recursive calls is a good practice, the recursion depth is limited here */ + idl_arrayLoopCopyIndex(idl_typeArray(idl_typeArrayType(typeArray))); + } + varIndex--; +} + +/** @brief Generate array index for copying array elements. + * + * Generate array index to string. + * + * @verbatim + [i1][i2]..[i#] + @endverbatim + * + * @param typeArray The type specification for the array which holds + * the basic type as wel as the size for each dimension. The first dimension + * is on top of that stack. + */ +static void +idl_arrayLoopCopyIndexString ( + c_char *indexString, + idl_typeArray typeArray) +{ + c_char arrIndex[16]; + + varIndex++; + snprintf(arrIndex, sizeof(arrIndex), "[i%d]", varIndex); + os_strncat(indexString, arrIndex, sizeof(arrIndex)); + /* QAC EXPECT 3416; No side effect here */ + if (idl_typeSpecType(idl_typeArrayType(typeArray)) == idl_tarray) { + /* QAC EXPECT 3670; Recursive calls is a good practice, the recursion depth is limited here */ + idl_arrayLoopCopyIndexString(indexString, idl_typeArray(idl_typeArrayType(typeArray))); + } + varIndex--; +} + +/** @brief Determine the number of dimensions of the identified array + * + * @param typeArray The type specification for the array which holds + * the basic type as wel as the size for each dimension. The first dimension + * is on top of that stack. + * @return The number of dimensions of the array + */ +static c_long +idl_indexSize( + idl_typeArray typeArray) +{ + c_long return_val = 1; + + /* QAC EXPECT 3416; No side effect here */ + if (idl_typeSpecType(idl_typeArrayType(typeArray)) == idl_tarray) { + /* QAC EXPECT 3670; Recursive calls is a good practice, the recursion depth is limited here */ + return_val = idl_indexSize (idl_typeArray(idl_typeArrayType(typeArray)))+1; + } + return return_val; +} + +/** @brief Generate copy body for an array element. + * + * Generate the body for copying an array element. + * + * Depending on the actual type of the array, one of the following strategies will + * be followed. + * - If the actual type is \b idl_tstruct or \b idl_tunion call the copy routine + * for the struct or union. + * - If the actual type is \b idl_ttypedef depending on the actual type of the typedef, + * for \b idl_tstruct, \b idl_tunion, \b idl_tarray and \b idl_tseq call the copy + * routine for the type. If the actual type is \b idl_tbasic (only if it is a string), + * the string is duplicated. + * - If the actual type is \b idl_tbasic (only a string is expected) a loop + * to copy the strings is created. + * - If the actual type is \b idl_tseq (only a string is expected) a loop + * to copy the sequence is created. + * + * @param typeArray The type specification for the array which holds + * the basic type as wel as the size for each dimension. The first dimension + * is on top of that stack. + * @param from Identification of the source to copy from + * @param to Identification of the destination to copy to + * @param indent Indentation of the output + */ +static void +idl_arrayLoopCopyBody( + idl_typeArray typeArray, + idl_typeSpec typeSpec, + const char *from, + const char *to, + c_long indent, + idl_scope scope, + os_boolean stacRequested, + os_boolean catsRequested, + void *userData) +{ + idl_typeSpec nextType; + c_char source[256]; + c_char destin[256]; + c_char *typeName; + c_char *scopedName; + c_char *dbTypeName; + c_long total_indent; + c_ulong maxlen; + + loopIndent++; + switch (idl_typeSpecType(typeSpec)) { + case idl_tstruct: + case idl_tunion: + scopedName = idl_scopedTypeName(typeSpec); + typeName = idl_scopeStackISOCxx2(idl_typeUserScope(idl_typeUser(typeSpec)), "::", idl_typeSpecName(typeSpec)); + dbTypeName = idl_scopedSplTypeIdent(typeSpec); + idl_printIndent(loopIndent + indent); + varIndex = 0; + idl_fileOutPrintf(idl_fileCur(), "extern v_copyin_result __%s__copyIn(c_type dbType,\n", scopedName); + idl_printIndent(loopIndent + indent + 1); + idl_fileOutPrintf(idl_fileCur(), "const %s *From,\n", typeName); + idl_printIndent(loopIndent + indent + 1); + idl_fileOutPrintf(idl_fileCur(), "%s *To);\n\n", dbTypeName); + idl_printIndent(loopIndent + indent); + idl_fileOutPrintf(idl_fileCur(), "if(V_COPYIN_RESULT_IS_OK(result)){\n"); + indent++; + idl_printIndent (loopIndent + indent); + idl_fileOutPrintf (idl_fileCur(),"result = __%s__copyIn(type0, (%s *)&(%s)", + scopedName, + typeName, + from); + idl_arrayLoopCopyIndex(typeArray); + idl_fileOutPrintf (idl_fileCur(), ", (%s *)&(*%s)", dbTypeName, to); + idl_arrayLoopCopyIndex(typeArray); + idl_fileOutPrintf (idl_fileCur(), ");\n"); + indent--; + idl_printIndent(loopIndent + indent); + idl_fileOutPrintf(idl_fileCur(), "}\n"); + os_free(dbTypeName); + os_free(typeName); + os_free(scopedName); + break; + case idl_ttypedef: + if(stacRequested) { + /* stac found, bypass the typedef and recurse deeper */ + if(idl_typeSpecType(idl_typeDefActual(idl_typeDef(typeSpec))) == idl_tarray) { + /* An array type is not handled by idl_arrayLoopCopyBody operation + * so we have to go up to the idl_arrayElements operation + */ + idl_arrayElements( + scope, + idl_typeArray(idl_typeDefActual(idl_typeDef(typeSpec))), + from, + to, + indent, + stacRequested, + catsRequested, + userData); + } else { + idl_arrayLoopCopyBody( + typeArray, + idl_typeDefActual(idl_typeDef(typeSpec)), + from, + to, + indent, + scope, + stacRequested, + catsRequested, + userData); + } + } else { + switch (idl_typeSpecType(idl_typeDefActual(idl_typeDef(typeSpec)))) { + case idl_tstruct: + case idl_tunion: + case idl_tarray: + case idl_tseq: + scopedName = idl_scopedTypeName(typeSpec); + typeName = idl_scopeStackISOCxx2(idl_typeUserScope(idl_typeUser(typeSpec)), "::", idl_typeSpecName(typeSpec)); + dbTypeName = idl_scopedSplTypeIdent(typeSpec); + + idl_printIndent (loopIndent + indent); + idl_fileOutPrintf(idl_fileCur(), "extern v_copyin_result __%s__copyIn(c_type dbType,", scopedName); + idl_fileOutPrintf(idl_fileCur(), "const %s *From,", typeName); + idl_fileOutPrintf(idl_fileCur(), "%s *To);\n\n", dbTypeName); + idl_printIndent(loopIndent + indent); + idl_fileOutPrintf(idl_fileCur(), "if(V_COPYIN_RESULT_IS_OK(result)){\n"); + indent++; + idl_printIndent (loopIndent + indent); + idl_fileOutPrintf (idl_fileCur(),"result = __%s__copyIn(type0, (%s *)&(%s)", scopedName, typeName, from); + idl_arrayLoopCopyIndex(typeArray); + idl_fileOutPrintf (idl_fileCur(), ", (%s *)&(*%s)", dbTypeName, to); + idl_arrayLoopCopyIndex(typeArray); + idl_fileOutPrintf (idl_fileCur(), ");\n"); + indent--; + idl_printIndent(loopIndent + indent); + idl_fileOutPrintf(idl_fileCur(), "}\n"); + os_free(dbTypeName); + os_free(typeName); + os_free(scopedName); + break; + case idl_tbasic: + /* QAC EXPECT 3416; No side effect here */ + if (idl_typeBasicType(idl_typeBasic(idl_typeDefActual(idl_typeDef(typeSpec)))) == idl_string) { + maxlen = idl_typeBasicMaxlen(idl_typeBasic(idl_typeDefActual(idl_typeDef(typeSpec)))); + + idl_printIndent (loopIndent + indent); + idl_fileOutPrintf (idl_fileCur(), "if(V_COPYIN_RESULT_IS_OK(result)){\n"); + indent++; + if(maxlen != 0){ + idl_printIndent(loopIndent + indent); + idl_fileOutPrintf (idl_fileCur(),"if((unsigned int) (%s", from); + idl_arrayLoopCopyIndex(typeArray); + idl_fileOutPrintf (idl_fileCur(),".length()) <= %u){\n", maxlen); + indent++; + idl_printIndent(loopIndent + indent); + if(stacRequested) + { + idl_fileOutPrintf (idl_fileCur()," strncpy((*%s", to); + idl_arrayLoopCopyIndex(typeArray); + idl_fileOutPrintf (idl_fileCur(),"), (%s", from); + idl_arrayLoopCopyIndex(typeArray); + idl_fileOutPrintf (idl_fileCur(),"), %u);\n", (maxlen+1)); + } else + { + idl_fileOutPrintf(idl_fileCur(), "%s", to); + idl_arrayLoopCopyIndex(typeArray); + idl_fileOutPrintf(idl_fileCur(), " = c_stringNew(c_getBase(dbType), (%s)", from); + idl_arrayLoopCopyIndex(typeArray); + idl_fileOutPrintf (idl_fileCur(),".c_str());\n"); + } + indent--; + idl_printIndent(loopIndent + indent); + idl_fileOutPrintf (idl_fileCur(),"} else {\n"); + indent++; + idl_printIndent(loopIndent + indent); + idl_boundsCheckFail(ELEMENT, scope, (idl_typeSpec)typeSpec, from); + idl_printIndent(loopIndent + indent); + idl_fileOutPrintf (idl_fileCur(),"result = V_COPYIN_RESULT_INVALID;\n"); + indent--; + idl_printIndent(loopIndent + indent); + idl_fileOutPrintf (idl_fileCur(),"}\n"); + } else { + idl_printIndent(loopIndent + indent); + idl_fileOutPrintf (idl_fileCur(), "%s", to); + idl_arrayLoopCopyIndex(typeArray); + idl_fileOutPrintf (idl_fileCur(), " = c_stringNew(c_getBase(dbType), (%s)", from); + idl_arrayLoopCopyIndex(typeArray); + idl_fileOutPrintf (idl_fileCur(),".c_str());\n"); + } + indent--; + idl_printIndent(loopIndent + indent); + idl_fileOutPrintf (idl_fileCur(),"}\n"); + } else { + idl_printIndent(loopIndent + indent); + idl_fileOutPrintf(idl_fileCur(), "(*%s)", to); + idl_arrayLoopCopyIndex(typeArray); + idl_fileOutPrintf(idl_fileCur(), " = %s", from); + idl_arrayLoopCopyIndex(typeArray); + idl_fileOutPrintf(idl_fileCur(), ";\n"); + } + break; + case idl_tenum: + maxlen = idl_typeEnumNoElements(idl_typeEnum(idl_typeDefActual(idl_typeDef(typeSpec)))); + dbTypeName = idl_scopedSplTypeIdent(typeSpec); + + idl_printIndent(loopIndent + indent); + idl_fileOutPrintf(idl_fileCur(), "if( (unsigned)%s", from); + idl_arrayLoopCopyIndex(typeArray); + idl_fileOutPrintf(idl_fileCur(), " < %u){\n", maxlen); + indent++; + idl_printIndent(loopIndent + indent); + idl_fileOutPrintf(idl_fileCur(), "(*%s)", to); + idl_arrayLoopCopyIndex(typeArray); + idl_fileOutPrintf(idl_fileCur(), " = (%s) (%s", dbTypeName, from); + idl_arrayLoopCopyIndex(typeArray); + idl_fileOutPrintf(idl_fileCur(), ");\n"); + indent--; + idl_printIndent(loopIndent + indent); + idl_fileOutPrintf (idl_fileCur(), "} else {\n"); + indent++; + idl_printIndent(loopIndent + indent); + idl_boundsCheckFail(ELEMENT, scope, (idl_typeSpec)typeSpec, from); + idl_printIndent(loopIndent + indent); + idl_fileOutPrintf (idl_fileCur(), "result = V_COPYIN_RESULT_INVALID;\n"); + indent--; + idl_printIndent(loopIndent + indent); + idl_fileOutPrintf (idl_fileCur(), "}\n"); + os_free(dbTypeName); + break; + default: + printf ("idl_loopCopyBody: Unexpected type\n"); + /* QAC EXPECT 3416; No side effect here */ + assert (0); + break; + } + } + break; + case idl_tbasic: + /* This may only be string */ + /* QAC EXPECT 3416; No side effect here */ + if (idl_typeBasicType (idl_typeBasic(typeSpec)) == idl_string) { + maxlen = idl_typeBasicMaxlen(idl_typeBasic(typeSpec)); + + if(maxlen != 0) { + idl_printIndent(loopIndent + indent); + idl_fileOutPrintf(idl_fileCur(), "if((%s)", from); + idl_arrayLoopCopyIndex(typeArray); + idl_fileOutPrintf(idl_fileCur(), ".length() <= %u){\n", maxlen); + indent++; + if(stacRequested) { + idl_fileOutPrintf (idl_fileCur(),"strncpy((*%s)", to); + idl_arrayLoopCopyIndex(typeArray); + idl_fileOutPrintf (idl_fileCur(),", (%s)", from); + idl_arrayLoopCopyIndex(typeArray); + idl_fileOutPrintf (idl_fileCur(),".c_str(), %u);\n", (maxlen+1)); + } else { + idl_printIndent (loopIndent + indent); + idl_fileOutPrintf(idl_fileCur(), "(*%s)", to); + idl_arrayLoopCopyIndex(typeArray); + idl_fileOutPrintf(idl_fileCur(), " = c_stringNew(c_getBase(dbType), (%s)", from); + idl_arrayLoopCopyIndex(typeArray); + idl_fileOutPrintf(idl_fileCur(), ".c_str());\n"); + } + indent--; + idl_printIndent (loopIndent + indent); + idl_fileOutPrintf (idl_fileCur(), "} else {\n"); + indent++; + idl_printIndent (loopIndent + indent); + idl_boundsCheckFail(ELEMENT, scope, (idl_typeSpec)typeSpec, from); + idl_printIndent (loopIndent + indent); + idl_fileOutPrintf (idl_fileCur(), " result = V_COPYIN_RESULT_INVALID;\n"); + indent--; + idl_printIndent (loopIndent + indent); + idl_fileOutPrintf (idl_fileCur(), "}\n"); + } else { + idl_printIndent (loopIndent + indent); + idl_fileOutPrintf(idl_fileCur(), "(*%s)", to); + idl_arrayLoopCopyIndex(typeArray); + idl_fileOutPrintf(idl_fileCur(), " = c_stringNew(c_getBase(dbType), (%s)", from); + idl_arrayLoopCopyIndex(typeArray); + idl_fileOutPrintf(idl_fileCur(), ".c_str());\n"); + } + + } else { + idl_printIndent(loopIndent + indent); + idl_fileOutPrintf(idl_fileCur(), "(*%s)", to); + idl_arrayLoopCopyIndex(typeArray); + idl_fileOutPrintf(idl_fileCur(), " = %s", from); + idl_arrayLoopCopyIndex(typeArray); + idl_fileOutPrintf(idl_fileCur(), ";\n"); + } + break; + case idl_tenum: + maxlen = idl_typeEnumNoElements(idl_typeEnum(typeSpec)); + dbTypeName = idl_scopedSplTypeIdent(typeSpec); + + idl_printIndent(loopIndent + indent); + idl_fileOutPrintf(idl_fileCur(), "if( (unsigned)%s", from); + idl_arrayLoopCopyIndex(typeArray); + idl_fileOutPrintf(idl_fileCur(), " < %u){\n", maxlen); + indent++; + idl_printIndent(loopIndent + indent); + idl_fileOutPrintf(idl_fileCur(), "(*%s)", to); + idl_arrayLoopCopyIndex(typeArray); + idl_fileOutPrintf(idl_fileCur(), " = (%s) (%s", dbTypeName, from); + idl_arrayLoopCopyIndex(typeArray); + idl_fileOutPrintf(idl_fileCur(), ");\n"); + indent--; + idl_printIndent(loopIndent + indent); + idl_fileOutPrintf (idl_fileCur(), "} else {\n"); + indent++; + idl_printIndent(loopIndent + indent); + idl_boundsCheckFail(ELEMENT, scope, (idl_typeSpec)typeSpec, from); + idl_printIndent(loopIndent + indent); + idl_fileOutPrintf (idl_fileCur(), "result = V_COPYIN_RESULT_INVALID;\n"); + indent--; + idl_printIndent(loopIndent + indent); + idl_fileOutPrintf (idl_fileCur(), "}\n"); + os_free(dbTypeName); + break; + case idl_tseq: + nextType = idl_typeSeqType(idl_typeSeq(typeSpec)); + total_indent = indent+idl_indexSize(typeArray); + maxlen = idl_typeSeqMaxSize(idl_typeSeq(typeSpec)); + scopedName = idl_scopedSplTypeName(nextType); + + snprintf(source, sizeof(source), "(%s)", from); + snprintf(destin, sizeof(destin), "(*%s)", to); + + idl_arrayLoopCopyIndexString (source, typeArray); + idl_arrayLoopCopyIndexString (destin, typeArray); + + idl_printIndent (total_indent); + idl_fileOutPrintf (idl_fileCur(), " /* Code generated by %s at line %d */\n\n",__FILE__,__LINE__); + idl_printIndent (total_indent); + idl_fileOutPrintf (idl_fileCur(), " %s *dest0;\n\n", scopedName); + idl_printIndent (total_indent); + maxlen = idl_typeSeqMaxSize(idl_typeSeq(typeSpec)); + idl_fileOutPrintf (idl_fileCur(), " c_ulong length0 = (c_ulong)(%s).size();\n", source); + + if(maxlen){ + idl_fileOutPrintf(idl_fileCur(), " if(length0 > %u){\n", maxlen); + idl_printIndent(total_indent); + idl_fileOutPrintf(idl_fileCur(), " "); + idl_boundsCheckFail(ELEMENT, scope, (idl_typeSpec)typeSpec, from); + idl_printIndent(total_indent); + idl_fileOutPrintf(idl_fileCur(), " result = V_COPYIN_RESULT_INVALID;\n"); + idl_printIndent(total_indent); + idl_fileOutPrintf(idl_fileCur(), " } else {\n"); + idl_printIndent(total_indent); + idl_fileOutPrintf(idl_fileCur(), " dest0 = (%s *)c_newSequence(c_collectionType(type0), length0);\n", scopedName); + idl_seqLoopCopy(scope, nextType, source, "dest0", 1, total_indent+2, userData); + + idl_printIndent(total_indent); + idl_fileOutPrintf(idl_fileCur(), " %s = (c_sequence)dest0;\n", + destin); + idl_fileOutPrintf(idl_fileCur(), " }\n"); + } else { + idl_printIndent(total_indent); + idl_fileOutPrintf(idl_fileCur(), " dest0 = (%s *)c_newSequence(c_collectionType(type0), length0);\n", scopedName); + idl_seqLoopCopy(scope, nextType, source, "dest0", 1, total_indent+1, userData); + + idl_printIndent (total_indent); + idl_fileOutPrintf (idl_fileCur(), " %s = (c_sequence) dest0;\n", destin); + } + os_free(scopedName); + break; + default: + /* QAC EXPECT 3416; No side effect here */ + assert (0); + break; + } + loopIndent--; + /* QAC EXPECT 5101, 5103: Complexity is limited, by independent cases, per case the number of lines is lower */ +} + +/** @brief Generate array loop copy closing code. + * + * For each dimension a closing bracket '}' will be generated at the + * correct indent level. + * + * @verbatim + } + .. + } + } + @endverbatim + * + * @param typeArray The type specification for the array which holds + * the basic type as wel as the size for each dimension. The first dimension + * is on top of that stack. + * @param indent Indentation of the loop. + */ +static void +idl_arrayLoopCopyClose ( + idl_typeArray typeArray, + c_long indent) +{ + idl_printIndent (loopIndent + indent); + loopIndent--; + idl_fileOutPrintf (idl_fileCur(), "}\n"); + /* QAC EXPECT 3416; No side effect here */ + if (idl_typeSpecType(idl_typeArrayType(typeArray)) == idl_tarray) { + /* QAC EXPECT 3670; Recursive calls is a good practice, the recursion depth is limited here */ + idl_arrayLoopCopyClose (idl_typeArray(idl_typeArrayType(typeArray)), indent); + } +} + +/** @brief Generate copy loops for array. + * + * For each array dimension generate a loop copy action. + * An array copy action is construct of: + * - a loop variable (idl_arrayLoopVariables) + * - a loop statement (idl_arrayLoopCopyOpen) + * - copying the array element (idl_arrayLoopCopyBody) + * - closing the loop statement (idl_arrayLoopCopyClose) + * + * This results in the following pattern for copying arrays per element: + * @verbatim + int i1; + int i2; + .. + int i#; + + for (i1 = 0; i1 < ; i1++) { + for (i2 = 0; i2 < ; i2++) { + .. + for (i# = 0; i# < ; i#++) { + // copy array element + to[i1][i2]..[i#] = c_stringNew (from[i1][i2]..[i#]) // for string + ____copyIn (&from[i1][i2]..[i#], &to[i1][i2]..[i#]) // for struct, union + .. // for sequence, see sequence copy construction + } + } + .. + } + @endverbatim + * + * @param typeArray The type specification for the array which holds + * the basic type as wel as the size for each dimension. The first dimension + * is on top of that stack. + * @param from Identification of the source to copy from + * @param to Identification of the destination to copy to + * @param indent Indentation of the output + */ +static void +idl_arrayLoopCopy ( + idl_typeArray typeArray, + const char *from, + const char *to, + c_long indent, + idl_scope scope, + os_boolean stacRequested, + os_boolean catsRequested, + void *userData) +{ + loopIndent = 0; + idl_arrayLoopVariables(typeArray, indent); + idl_arrayLoopCopyOpen(typeArray, indent); + idl_arrayLoopCopyBody(typeArray, idl_typeArrayActual(typeArray), from, to, indent, scope, stacRequested, catsRequested, userData); + idl_arrayLoopCopyClose(typeArray, indent); +} + +/** @brief Generate code for copying an array. + * + * This function is the top level function for copying an array type. + * This function determines the strategy to use, copying by plain + * memory copy (for plain types), or copying element for element (for + * types that contain references). + * + * The copy strategy depends on the actual type of the array: + * - If the actual type is \b idl_tbasic, the depending if it is a + * string or another basic type, an element copy or a plain memory copy + * is used respectively. + * - If the actual type is \b idl_tenum, a plain memory copy is used. + * - If the actual type is \b idl_tstruct or \b idl_tunion, an element + * copy is used. + * - If the actual type is \b idl_ttypedef, the strategy depends on the + * actual type of the typedef. + * - If the actual type is \b idl_tseq, the array will be copied on + * element basis. + * + * @todo When the struct (probably not the union) does not contain a reference, + * a plain memory copy could be used because the memory map is the same in CORBA + * and OpenSpliceDDS. The C++ sequence buffer must be aquired then. + * + * @todo Add bounds checking for enums. See issue dss#175. Grep this issue id in source. + * + * @param typeArray The type specification for the array which holds + * the basic type as wel as the size for each dimension. The first dimension + * is on top of that stack. + * @param from Identification of the source to copy from + * @param to Identification of the destination to copy to + * @param indent Indentation of the output + */ +static void +idl_arrayElements ( + idl_scope scope, + idl_typeArray typeArray, + const char *from_, + const char *to, + c_long indent, + os_boolean stacRequested, + os_boolean catsRequested, + void *userData) +{ + idl_typeSpec subType = idl_typeArrayActual(typeArray); + idl_type idlType; + char *buf; + + char* from; + from = os_malloc(strlen(from_) + strlen("().data()") + 1); + os_sprintf(from, "%s%s%s", "(", from_, ").data()"); + idlType = idl_typeSpecType(subType); + /* if we are dealing with a member for which stac or cats was requested + * and of which the type is a typedef, then we must bypass this typedef + * completely and get to the actual type of the typedef + */ + if(stacRequested || catsRequested) { + if(idlType == idl_ttypedef) { + subType = idl_typeDefResolveFully(subType); + idlType = idl_typeSpecType(subType); + } + } + switch (idlType) { + case idl_tbasic: + /* QAC EXPECT 3416; No side effect here */ + if (idl_typeBasicType(idl_typeBasic(subType)) == idl_string) { + idl_arrayLoopCopy (typeArray, from, to, indent, scope, stacRequested, catsRequested, userData); + } else { + /*stac requested should be covered by the above if statement, as + * stac always involves strings. And if this basic type is not a string + * then stac requested can not be true + */ + assert(!stacRequested); + if(catsRequested) { + idl_fileOutPrintf(idl_fileCur()," /* Allocate the length of the array (and null terminator) as a database\n"); + idl_fileOutPrintf(idl_fileCur()," * string\n"); + idl_fileOutPrintf(idl_fileCur()," */\n"); + idl_fileOutPrintf(idl_fileCur()," to->%s = c_stringMalloc(base, (%u + 1));\n", to, idl_typeArraySize(typeArray)); + idl_fileOutPrintf(idl_fileCur()," if(to->%s)\n", to); + idl_fileOutPrintf(idl_fileCur()," {\n"); + idl_fileOutPrintf(idl_fileCur()," /* Copy the value of the array into the database string */\n"); + idl_fileOutPrintf(idl_fileCur()," strncpy(to->%s, %s, %u);\n", to, from, idl_typeArraySize(typeArray)); + idl_fileOutPrintf(idl_fileCur()," to->%s[%u] = '\\0';\n", to, idl_typeArraySize(typeArray)); + idl_fileOutPrintf(idl_fileCur()," }\n"); + } else if (idl_typeSpecType(idl_typeArrayType(typeArray)) != idl_tarray){ + idl_printIndent (indent); + idl_fileOutPrintf (idl_fileCur(), " memcpy (%s, %s, sizeof (*%s));\n", to, from, to); + } else { + idl_arrayLoopCopy (typeArray, from, to, indent, scope, stacRequested, catsRequested, userData); + } + } + break; + case idl_tenum: + idl_printIndent (indent); + idl_arrayLoopCopy (typeArray, from, to, indent, scope, stacRequested, catsRequested, userData); + break; + case idl_tstruct: + case idl_tunion: + idl_arrayLoopCopy (typeArray, from, to, indent, scope, stacRequested, catsRequested, userData); + break; + case idl_ttypedef: + /* QAC EXPECT 3416; No side effect here */ + if (idl_typeSpecType(idl_typeDefActual(idl_typeDef(subType))) == idl_tbasic) { + if (idl_typeBasicType(idl_typeBasic(idl_typeDefActual(idl_typeDef(subType)))) == idl_string) { + buf = os_malloc(strlen(to)+4); + os_sprintf(buf, "(*%s)", to); + idl_arrayLoopCopy (typeArray, from, buf, indent, scope, stacRequested, catsRequested, userData); + os_free(buf); + } else if (idl_typeSpecType(idl_typeArrayType(typeArray)) != idl_tarray) { + idl_printIndent (indent); + idl_fileOutPrintf (idl_fileCur(), " memcpy (%s, %s, sizeof (*%s));\n", to, from, to); + } else { + idl_arrayLoopCopy (typeArray, from, to, indent, scope, stacRequested, catsRequested, userData); + } + } else { + idl_arrayLoopCopy (typeArray, from, to, indent, scope, stacRequested, catsRequested, userData); + } + break; + case idl_tseq: + idl_arrayLoopCopy (typeArray, from, to, indent, scope, stacRequested, catsRequested, userData); + break; + case idl_tarray: + printf ("idl_arrayElements: Unexpected type idl_tarray\n"); + break; + } + + os_free(from); +} + +/** @brief Function that generates index for addressing sequence elements. + * + * Generate code for addressing sequenece elements by means of the index + * variables i0 .. in. + * + * The index is organized as follows: + * @verbatim + [i0][i1]..[in] + @endverbatim + * + * @param indent Sequence recursion level + * @return image addressing the current sequence element + */ +static char * +idl_seqIndex ( + c_long indent) +{ + c_char index[64]; + c_char is[64]; + c_long i; + + index[0] = 0; + for (i = 0; i < indent; i++) { + snprintf (is, sizeof(is), "[i%d]", i); + /* Remaining size is (total size) - (current string size) - (sizeof('\0')). */ + os_strncat(index, is, sizeof(index) - strlen(index) - 1); + } + return os_strdup(index); +} + +/** @brief Function that generates code for copying sequences. + * + * Generate code for copying sequence types. + * + * The general pattern for copying sequences is as follows: + * @verbatim + static c_type type0 = NULL; + unsigned int i0; + c_long length0; + *dest0; + + if (type0 == NULL) { + type0 = c_type(c_metaResolve (c_metaObject(base), "")); + } + length0 = (c_long)(*src0).length(); + dest0 = ( *)c_sequenceNew(type0, maxlen, length0); + // Body to copy sequence contents from to dest0 + = (c_sequence)dest0; + @endverbatim + * + * Note that in C++, nested sequences are always anonymous. Thus sequence copy routines in + * C++ need to nest the copy actions (in contrast with C). + * The variable names used "i0", "type0", "length0", "dst0" and "src0", suggest otherwise. + * + * This routine only generates the copying code for copying the sequence contents. + * The context arround it as depicted above is expected to be generated by the + * calling function. + * Motivation for this is that are many variations on the pattern depending on + * the situation, for instance if it is an array of an sequence, an array copy loop + * must be coded arround it. + * + * The body to copy the sequence depends on the actual type of the sequence, however + * the framework for copying is always the same: + * @verbatim + for (i0 = 0; i0 < (unsigned int)length0; i0++) { + // Copy sequence element (type specific) + } + @endverbatim + * + * The element copyIn strategy is as follows: + * - If the sequence element type is \b idl_tenum, direct assignment is used + * - If the sequence element type is \b idl_tbasic, depending on wheter it is + * a string or not, elements are duplicated via c_newString or otherwise + * immediately assigned + * - If the sequence element type is \b idl_tstruct or \b idl_tunion the copyIn + * function for that struct or union is called. + * - If the sequence element type is \b idl_ttypedef the strategy depends on the + * actual type of the typedef. For structs unions and arrays the copyIn routine + * for that type is called. For basic string type, the string is duplicated + * via c_stringNew. For other basic types and enumeration it is just assigned. + * - If the sequence element type is \b idl_tseq, a new sequence copy operation + * is setup for the specific sequence type. + * + * Structure types (not unions) that do not contain any reference types are + * copied via a plain memory copy because the sequence elements are located in + * consequtive memory with the same memory map for C CORBA as well as OpenSpliceDDS. + * These are identified using idl_isContiguous(). + * + * @todo Add bounds checking for enums. See issue dss#175. Grep this issue id in source. + * + * @param typeSpec The specification of the actual type of the sequence + * @param from Specifies the identification of the source + * @param to Specifies the identification of the destination + * @param loop_index Specifies the index if the variables when sequence copy + * routines are nested. The top level sequence starts with index 0. + * @param indent Specifies the indentation level + */ +static void +idl_seqLoopCopy ( + idl_scope scope, + idl_typeSpec typeSpec, + const char *from, + const char *to, + c_long loop_index, + c_long indent, + void *userData) +{ + c_char destin[32]; + c_char *typeName; + c_char *scopedName; + c_char *seqIndex; + c_char *funcPrefix; + idl_typeSpec nextType; + c_ulong maxlen; + + if (idl_isContiguous(idl_typeSpecDef(typeSpec)) && idl_typeSpecType (typeSpec) != idl_tenum) { + seqIndex = idl_seqIndex (loop_index - 1); + scopedName = idl_scopedSplTypeName(typeSpec); + idl_printIndent (indent); + idl_fileOutPrintf (idl_fileCur(), "{\n"); + idl_printIndent (indent); + idl_fileOutPrintf (idl_fileCur(), " /* Code generated by %s at line %d */\n",__FILE__,__LINE__); + idl_printIndent (indent); + idl_fileOutPrintf (idl_fileCur(), " if(length0 > 0)\n"); + idl_printIndent (indent); + idl_fileOutPrintf (idl_fileCur(), " {\n"); + indent += 1; + idl_printIndent (indent); + idl_fileOutPrintf (idl_fileCur(), " const %s *buf%d;\n", scopedName, loop_index-1); + idl_printIndent (indent); + idl_fileOutPrintf (idl_fileCur(), " buf%d = reinterpret_cast(&((%s)%s[0]));\n", + loop_index-1, scopedName, from, seqIndex); + + idl_printIndent (indent); + idl_fileOutPrintf (idl_fileCur(), " memcpy (%s,buf%d,length%d* sizeof(*%s));\n", + to, loop_index-1, loop_index-1, to); + + indent -=1; + idl_printIndent (indent); + idl_fileOutPrintf (idl_fileCur(), " }\n"); + idl_printIndent (indent); + idl_fileOutPrintf (idl_fileCur(), "}\n"); + os_free(seqIndex); + os_free(scopedName); + return; + } + + seqIndex = idl_seqIndex (loop_index); + scopedName = idl_scopedSplTypeName(typeSpec); + idl_printIndent (indent); + idl_fileOutPrintf (idl_fileCur(), "{\n"); + idl_printIndent (indent); + idl_fileOutPrintf (idl_fileCur(), " /* Code generated by %s at line %d */\n",__FILE__,__LINE__); + idl_printIndent (indent); + idl_fileOutPrintf (idl_fileCur(), " unsigned int i%d;\n", loop_index-1); + idl_printIndent (indent); + idl_fileOutPrintf (idl_fileCur(), " for (i%d = 0; (i%d < length%d) && result; i%d++) {\n", + loop_index-1, + loop_index-1, + loop_index-1, + loop_index-1); + + switch (idl_typeSpecType (typeSpec)) { + case idl_tenum: + maxlen = idl_typeEnumNoElements(idl_typeEnum(typeSpec)); + + idl_printIndent (indent); + idl_fileOutPrintf (idl_fileCur(), " if((unsigned)((%s)%s) < %u){\n", + from, + seqIndex, + maxlen); + idl_printIndent (indent); + idl_fileOutPrintf (idl_fileCur(), " %s[i%d] = (%s)(%s)%s;\n", + to, + loop_index-1, + scopedName, + from, + seqIndex); + idl_printIndent (indent); + idl_fileOutPrintf (idl_fileCur(), " } else {\n"); + idl_printIndent (indent); + idl_fileOutPrintf (idl_fileCur(), " "); + idl_boundsCheckFail(ELEMENT, scope, (idl_typeSpec)typeSpec, from); + idl_printIndent (indent); + idl_fileOutPrintf (idl_fileCur(), " result = V_COPYIN_RESULT_INVALID;\n"); + idl_printIndent (indent); + idl_fileOutPrintf (idl_fileCur(), " }\n"); + break; + case idl_tbasic: + /* QAC EXPECT 3416; No side effect here */ + if (idl_typeBasicType (idl_typeBasic(typeSpec)) == idl_string) { + maxlen = idl_typeBasicMaxlen(idl_typeBasic(typeSpec)); + + idl_printIndent (indent); + + if(maxlen != 0){ + idl_fileOutPrintf(idl_fileCur(), " if((unsigned int)(%s)%s.length() <= %d){\n", + from, + seqIndex, + maxlen); + + idl_printIndent (indent+1); + idl_fileOutPrintf(idl_fileCur(), " %s[i%d] = c_stringNew(c_getBase(dbType), (%s)%s.c_str());\n", + to, + loop_index-1, + from, + seqIndex); + idl_printIndent (indent + 1); + idl_fileOutPrintf (idl_fileCur(), " } else {\n"); + idl_printIndent (indent + 1); + idl_fileOutPrintf (idl_fileCur(), " "); + idl_boundsCheckFail(ELEMENT, scope, (idl_typeSpec)typeSpec, from); + idl_printIndent (indent + 1); + idl_fileOutPrintf (idl_fileCur(), " result = V_COPYIN_RESULT_INVALID;\n"); + idl_printIndent (indent + 1); + idl_fileOutPrintf (idl_fileCur(), " }\n"); + } else { + idl_fileOutPrintf (idl_fileCur(), " %s[i%d] = c_stringNew(c_getBase(dbType), (%s)%s.c_str());\n", + to, + loop_index-1, + from, + seqIndex); + } + } else { + /* This branch is never executed because the first if statement that is added as a copy improvement + at the top of this method already covers this condition */ + idl_printIndent (indent); + idl_fileOutPrintf (idl_fileCur(), " %s[i%d] = (%s)(%s)%s;\n", + to, + loop_index-1, + scopedName, + from, + seqIndex); + } + break; + case idl_tstruct: + case idl_tunion: + varIndex = 0; + typeName = idl_scopeStackISOCxx2(idl_typeUserScope(idl_typeUser(typeSpec)), "::", idl_typeSpecName(typeSpec)); + funcPrefix = idl_scopedTypeName(typeSpec); + idl_printIndent (indent); + idl_fileOutPrintf (idl_fileCur(), " extern v_copyin_result __%s__copyIn(c_type dbType,\n", funcPrefix); + idl_printIndent (indent); + idl_fileOutPrintf (idl_fileCur(), " const %s *From,\n", + typeName); + idl_printIndent (indent); + idl_fileOutPrintf (idl_fileCur(), " %s *To);\n\n", + scopedName); + idl_printIndent (indent); + idl_fileOutPrintf ( + idl_fileCur(), + " result = __%s__copyIn(c_collectionTypeSubType(type%d), &(%s)%s, (%s *)&%s[i%d]);\n", + funcPrefix, + loop_index - 1, + from, + seqIndex, + scopedName, + to, + loop_index-1); + os_free(funcPrefix); + os_free(typeName); + break; + case idl_ttypedef: + idl_printIndent (indent); + switch (idl_typeSpecType(idl_typeDefActual(idl_typeDef(typeSpec)))) { + case idl_tstruct: + case idl_tunion: + case idl_tarray: + typeName = idl_ISOCxx2TypeFromTypeSpec(typeSpec); + funcPrefix = idl_scopedTypeName(typeSpec); + idl_fileOutPrintf (idl_fileCur(), " if(V_COPYIN_RESULT_IS_OK(result)){\n"); + idl_printIndent (indent); + idl_fileOutPrintf (idl_fileCur(), " extern v_copyin_result __%s__copyIn(c_type, const %s *, %s *);\n", + funcPrefix, + idl_corbaCxxTypeFromTypeSpec(typeSpec), + scopedName); + idl_printIndent (indent); + idl_fileOutPrintf ( + idl_fileCur(), + " result = __%s__copyIn(c_collectionTypeSubType(type%d), &(%s)%s, (%s *)&%s[i%d]);\n", + funcPrefix, + loop_index - 1, + from, + seqIndex, + scopedName, + to, + loop_index-1); + idl_printIndent (indent); + idl_fileOutPrintf (idl_fileCur(), " }\n"); + os_free(funcPrefix); + os_free(typeName); + break; + case idl_tbasic: + /* QAC EXPECT 3416; No side effect here */ + if (idl_typeBasicType(idl_typeBasic(idl_typeDefActual(idl_typeDef(typeSpec)))) == idl_string) { + maxlen = idl_typeBasicMaxlen(idl_typeBasic(idl_typeDefActual(idl_typeDef(typeSpec)))); + + idl_printIndent (indent); + + if(maxlen != 0){ + idl_fileOutPrintf(idl_fileCur(), " if((unsigned int)(%s)%s.length() <= %d){\n", + from, + seqIndex, + maxlen); + idl_printIndent (indent + 1); + idl_fileOutPrintf(idl_fileCur(), " %s[i%d] = c_stringNew(c_getBase(dbType), (%s)%s.c_str());\n", + to, + loop_index-1, + from, + seqIndex); + idl_printIndent (indent + 1); + idl_fileOutPrintf (idl_fileCur(), " } else {\n"); + idl_printIndent (indent + 1); + idl_fileOutPrintf (idl_fileCur(), " "); + idl_boundsCheckFail(ELEMENT, scope, (idl_typeSpec)typeSpec, from); + idl_printIndent (indent + 1); + idl_fileOutPrintf (idl_fileCur(), " result = V_COPYIN_RESULT_INVALID;\n"); + idl_printIndent (indent + 1); + idl_fileOutPrintf (idl_fileCur(), " }\n"); + } else { + idl_fileOutPrintf (idl_fileCur(), " %s[i%d] = c_stringNew(c_getBase(dbType), (%s)%s.c_str());\n", + to, + loop_index-1, + from, + seqIndex); + } + } else { + idl_fileOutPrintf (idl_fileCur(), " %s[i%d] = (%s)(%s)%s;\n", + to, + loop_index-1, + scopedName, + from, + seqIndex); + } + break; + case idl_tenum: + maxlen = idl_typeEnumNoElements(idl_typeEnum(idl_typeDefActual(idl_typeDef(typeSpec)))); + idl_printIndent (indent); + idl_fileOutPrintf (idl_fileCur(), " if((((c_long)((%s)%s)) >= 0) && (((c_long)((%s)%s)) < %u)){\n", + from, + seqIndex, + from, + seqIndex, + maxlen); + idl_printIndent (indent); + idl_fileOutPrintf (idl_fileCur(), " %s[i%d] = (%s)(%s)%s;\n", + to, + loop_index-1, + scopedName, + from, + seqIndex); + idl_printIndent (indent); + idl_fileOutPrintf (idl_fileCur(), " } else {\n"); + idl_printIndent (indent); + idl_fileOutPrintf (idl_fileCur(), " "); + idl_boundsCheckFail(ELEMENT, scope, (idl_typeSpec)typeSpec, from); + idl_printIndent (indent); + idl_fileOutPrintf (idl_fileCur(), " result = V_COPYIN_RESULT_INVALID;\n"); + idl_printIndent (indent); + idl_fileOutPrintf (idl_fileCur(), " }\n"); + break; + case idl_tseq: + nextType = idl_typeSeqType(idl_typeSeq(idl_typeDefActual(idl_typeDef(typeSpec)))); + os_free(scopedName); + scopedName = idl_scopedSplTypeIdent(nextType); + maxlen = idl_typeSeqMaxSize(idl_typeSeq(idl_typeDefActual(idl_typeDef(typeSpec)))); + snprintf (destin, sizeof(destin), "dest%d", loop_index); + + idl_printIndent (indent); + idl_fileOutPrintf (idl_fileCur(), " /* Code generated by %s at line %d */\n\n",__FILE__,__LINE__); + idl_printIndent (indent); + if (loop_index > 0) { + idl_fileOutPrintf ( + idl_fileCur(), + " c_type type%d = c_collectionTypeSubType(type%d);\n", + loop_index, + loop_index - 1); + } else if (memberIndex > -1) { + idl_fileOutPrintf ( + idl_fileCur(), + " c_type type%d = c_memberType(c_structureMember(c_structure(dbType), %d));\n", + loop_index, + memberIndex); + } else if (caseIndex > -1) { + idl_fileOutPrintf ( + idl_fileCur(), + " c_type type%d = c_unionCaseType(c_unionUnionCase(c_union(dbType), %d));\n", + loop_index, + caseIndex); + } else { + assert(0); + } + idl_printIndent (indent); + idl_fileOutPrintf (idl_fileCur(), " %s *dest%d;\n\n", scopedName, loop_index); + idl_printIndent (indent); + idl_fileOutPrintf (idl_fileCur(), " c_long length%d = (%s)%s.size();\n", loop_index, from, seqIndex); + + idl_printIndent (indent); + + if(maxlen > 0){ + idl_fileOutPrintf(idl_fileCur(), " if(length%d > %u){\n", loop_index, maxlen); + idl_printIndent (indent); + idl_fileOutPrintf(idl_fileCur(), " "); + idl_boundsCheckFail(ELEMENT, scope, (idl_typeSpec)typeSpec, from); + idl_printIndent(indent); + idl_fileOutPrintf(idl_fileCur(), " result = V_COPYIN_RESULT_INVALID;"); + idl_printIndent(indent); + idl_fileOutPrintf(idl_fileCur(), " } else {"); + idl_printIndent(indent); + idl_fileOutPrintf (idl_fileCur(), " dest%d = (%s *)c_newSequence(c_collectionType(type%d), length%d);\n", + loop_index, scopedName, loop_index, loop_index); + idl_seqLoopCopy (scope, nextType, from, destin, loop_index+1, indent+3, userData); + idl_printIndent (indent); + idl_fileOutPrintf (idl_fileCur(), " dest%d[i%d] = (c_sequence)dest%d;\n", + loop_index-1, loop_index-1, loop_index); + idl_printIndent(indent); + idl_fileOutPrintf(idl_fileCur(), " }\n"); + } else { + idl_fileOutPrintf (idl_fileCur(), " dest%d = (%s *)c_newSequence(c_collectionType(type%d), length%d);\n", + loop_index, scopedName, loop_index, loop_index); + idl_seqLoopCopy (scope, nextType, from, destin, loop_index+1, indent+2, userData); + idl_printIndent (indent); + idl_fileOutPrintf (idl_fileCur(), " dest%d[i%d] = (c_sequence)dest%d;\n", + loop_index-1, loop_index-1, loop_index); + } + break; + default: + printf ("idl_seqLoopCopy: Unexpected type\n"); + assert (0); + break; + } + break; + case idl_tseq: + nextType = idl_typeSeqType(idl_typeSeq(typeSpec)); + os_free(scopedName); + scopedName = idl_scopedSplTypeIdent(nextType); + maxlen = idl_typeSeqMaxSize(idl_typeSeq(typeSpec)); + + snprintf (destin, sizeof(destin), "dest%d", loop_index); + + idl_printIndent (indent); + idl_fileOutPrintf (idl_fileCur(), " /* Code generated by %s at line %d */\n\n",__FILE__,__LINE__); + idl_printIndent (indent); + if (loop_index > 0) { + idl_fileOutPrintf ( + idl_fileCur(), + " c_type type%d = c_collectionTypeSubType(type%d);\n", + loop_index, + loop_index - 1); + } else if (memberIndex > -1) { + idl_fileOutPrintf ( + idl_fileCur(), + " c_type type%d = c_memberType(c_structureMember(c_structure(dbType), %d));\n", + loop_index, + memberIndex); + } else if (caseIndex > -1) { + idl_fileOutPrintf ( + idl_fileCur(), + " c_type type%d = c_unionCaseType(c_unionUnionCase(c_union(dbType), %d));\n", + loop_index, + caseIndex); + } else { + assert(0); + } + idl_printIndent (indent); + idl_fileOutPrintf (idl_fileCur(), " %s *dest%d;\n\n", scopedName, loop_index); + idl_printIndent (indent); + idl_fileOutPrintf (idl_fileCur(), " c_ulong length%d = (%s)%s.size();\n", loop_index, from, idl_seqIndex(loop_index)); + idl_printIndent (indent); + + idl_fileOutPrintf (idl_fileCur(), " dest%d = (%s *)c_newSequence(c_collectionType(type%d), length%d);\n", + loop_index, scopedName, loop_index, loop_index); + idl_seqLoopCopy (scope, nextType, from, destin, loop_index+1, indent+2, userData); + idl_printIndent (indent); + idl_fileOutPrintf (idl_fileCur(), " dest%d[i%d] = (c_sequence)dest%d;\n", + loop_index-1, loop_index-1, loop_index); + break; + default: + assert (0); + break; + } + idl_printIndent (indent); + idl_fileOutPrintf (idl_fileCur(), " }\n"); + idl_printIndent (indent); + idl_fileOutPrintf (idl_fileCur(), "}\n"); + + os_free(scopedName); + os_free(seqIndex); +} + +/** @brief Function that set up the sequence copy context for a typedef. + * + * Generate code to setup the sequence copy context for a typedef. + * + * @todo Because it is only used by a typedef it would be more clear + * to integrate it with the typedef. If it can be used for more contexts + * the others should be removed and call this function. + * + * @param scope Current scope + * @param name Specifies the name of the type + * @param typeSeq Specifies the type of the sequence + * @param indent Sequence recursion level + */ +static void +idl_seqElements ( + idl_scope scope, + const char *name, + idl_typeSeq typeSeq, + c_long indent, + void *userData) +{ + c_char destin[32]; + c_ulong maxlen; + c_char *dbTypeName; + c_char *scopedName; + idl_typeSpec nextType; + + nextType = idl_typeSeqType(typeSeq); + + dbTypeName = idl_scopedSplTypeName(nextType); + scopedName = idl_scopeStack(scope, "_", name); + snprintf(destin, sizeof(destin), "dest%d", indent); + maxlen = idl_typeSeqMaxSize(typeSeq); + + idl_fileOutPrintf(idl_fileCur(), " /* Code generated by %s at line %d */\n\n",__FILE__,__LINE__); + if (indent == 0) { + idl_fileOutPrintf(idl_fileCur(), " c_type type%d = c_typeDef(dbType)->alias;\n", indent); + } else { + idl_fileOutPrintf(idl_fileCur(), " c_type type%d = c_typeDef(type%d)->alias;\n", indent, indent - 1); + } + idl_fileOutPrintf(idl_fileCur(), " %s *dest%d;\n\n", dbTypeName, indent); + idl_fileOutPrintf(idl_fileCur(), " c_ulong length%d = (*from).size();\n", indent); + + if(maxlen != 0){ + idl_fileOutPrintf(idl_fileCur(), " if(length%d > %u){\n", indent, maxlen); + idl_fileOutPrintf(idl_fileCur(), " "); + idl_boundsCheckFail(ELEMENT, scope, (idl_typeSpec)typeSeq, name); + idl_fileOutPrintf(idl_fileCur(), " result = V_COPYIN_RESULT_INVALID;\n"); + idl_fileOutPrintf(idl_fileCur(), " } else {\n"); + + idl_fileOutPrintf(idl_fileCur(), " dest%d = (%s *)c_newSequence(c_collectionType(type%d), length%d);\n", indent, dbTypeName, indent, indent); + idl_seqLoopCopy(scope, nextType, "*from", destin, 1, indent+2, userData); + idl_fileOutPrintf(idl_fileCur(), " *to = (_%s)dest%d;\n", scopedName, indent); + idl_fileOutPrintf(idl_fileCur(), " }\n"); + } else { + idl_fileOutPrintf(idl_fileCur(), " dest%d = (%s *)c_newSequence(c_collectionType(type%d), length%d);\n", indent, dbTypeName, indent, indent); + idl_seqLoopCopy (scope, nextType, "*from", destin, 1, indent+1, userData); + idl_fileOutPrintf(idl_fileCur(), " *to = (_%s)dest%d;\n", scopedName, indent); + } + os_free(scopedName); + os_free(dbTypeName); +} + +/** @brief callback function called on definition of a named type in the IDL input file. + * + * Generate code for the following IDL construct: + * @verbatim + => typedef ; + @endverbatim + * + * For typedef's the action to copy the data is dependend on the actual type. + * - If the actual type is \b idl_tstruct or \b idl_tunion, a named copy routines + * is generated. The copyIn routines calls the copyIn routine of the struct or union. + * - If the actual type is \b idl_tarray, a named copyIn routine is generated. + * For that copyIn routine, array copy code is generated. + * - If the actual type is \b idl_tseq, a named copyIn routine is generated. + * For that copyIn routine, sequence copy code is generated. + * + * Type definitions of basic type are immediately copied from within the generated + * struct or union copyIn routine. No named copy routine is required. + * + * @param scope Current scope + * @param name Specifies the name of the type + * @param defSpec Specifies the type of the named type + */ +static void +idl_typedefOpenClose ( + idl_scope scope, + const char *name, + idl_typeDef defSpec, + void *userData) +{ + c_char *scopedName = idl_scopeStack (scope, "_", name); + c_char *cxxTypeName = idl_scopeStackISOCxx2 (scope, "::", name); + idl_typeSpec actualType = idl_typeDefActual(defSpec); + + switch (idl_typeSpecType(idl_typeDefActual(defSpec))) { + case idl_tstruct: + case idl_tunion: + idl_fileOutPrintf (idl_fileCur(), "v_copyin_result\n"); + idl_fileOutPrintf (idl_fileCur(), "__%s__copyIn(\n", scopedName); + idl_fileOutPrintf (idl_fileCur(), " c_type dbType,\n"); + idl_fileOutPrintf (idl_fileCur(), " const %s *from,\n", cxxTypeName); + idl_fileOutPrintf (idl_fileCur(), " _%s *to)\n", scopedName); + idl_fileOutPrintf (idl_fileCur(), "{\n"); + idl_fileOutPrintf (idl_fileCur(), " v_copyin_result result = V_COPYIN_RESULT_OK;\n\n"); + os_free(scopedName); + os_free(cxxTypeName); + scopedName = idl_scopedTypeName(actualType); + cxxTypeName = idl_ISOCxx2TypeFromTypeSpec(actualType); + idl_fileOutPrintf (idl_fileCur(), " extern v_copyin_result __%s__copyIn(c_type, const %s *, _%s *);\n", + scopedName, + cxxTypeName, + scopedName); + idl_fileOutPrintf (idl_fileCur(), " result = __%s__copyIn(c_typeDef(dbType)->alias, (%s *)from, (_%s *)to);\n", + scopedName, + cxxTypeName, + scopedName); + idl_fileOutPrintf (idl_fileCur(), " return result;\n"); + idl_fileOutPrintf (idl_fileCur(), "}\n"); + idl_fileOutPrintf (idl_fileCur(), "\n"); + break; + case idl_tarray: + idl_fileOutPrintf (idl_fileCur(), "v_copyin_result\n"); + idl_fileOutPrintf (idl_fileCur(), "__%s__copyIn(\n", scopedName); + idl_fileOutPrintf (idl_fileCur(), " c_type dbType,\n"); + idl_fileOutPrintf (idl_fileCur(), " const %s *from,\n", cxxTypeName); + idl_fileOutPrintf (idl_fileCur(), " _%s *to)\n", scopedName); + idl_fileOutPrintf (idl_fileCur(), "{\n"); + idl_fileOutPrintf (idl_fileCur(), " v_copyin_result result = V_COPYIN_RESULT_OK;\n"); + idl_fileOutPrintf (idl_fileCur(), " c_type type0 = c_typeDef(dbType)->alias;\n\n"); + idl_fileOutPrintf (idl_fileCur(), " while(c_baseObjectKind(type0) == M_COLLECTION && c_collectionTypeKind(type0) == OSPL_C_ARRAY) {;\n"); + idl_fileOutPrintf (idl_fileCur(), " type0 = c_collectionTypeSubType(type0);\n"); + idl_fileOutPrintf (idl_fileCur(), " }\n"); + idl_arrayElements (scope, idl_typeArray(idl_typeDefActual(defSpec)), "*from", "to", 0, OS_FALSE, OS_FALSE, userData); + idl_fileOutPrintf (idl_fileCur(), " return result;\n"); + idl_fileOutPrintf (idl_fileCur(), "}\n"); + idl_fileOutPrintf (idl_fileCur(), "\n"); + break; + case idl_tseq: + idl_fileOutPrintf (idl_fileCur(), "v_copyin_result\n"); + idl_fileOutPrintf (idl_fileCur(), "__%s__copyIn(\n", scopedName); + idl_fileOutPrintf (idl_fileCur(), " c_type dbType,\n"); + idl_fileOutPrintf (idl_fileCur(), " const %s *from,\n", cxxTypeName); + idl_fileOutPrintf (idl_fileCur(), " _%s *to)\n", scopedName); + idl_fileOutPrintf (idl_fileCur(), "{\n"); + idl_fileOutPrintf (idl_fileCur(), " v_copyin_result result = V_COPYIN_RESULT_OK;\n"); + idl_seqElements (scope, name, idl_typeSeq(idl_typeDefActual(defSpec)), 0, userData); + idl_fileOutPrintf (idl_fileCur(), " return result;\n"); + idl_fileOutPrintf (idl_fileCur(), "}\n"); + idl_fileOutPrintf (idl_fileCur(), "\n"); + break; + default: + break; + } + os_free(cxxTypeName); + os_free(scopedName); +} + +/** @brief callback function called on definition of a union in the IDL input file. + * + * Generate code for the following IDL construct: + * @verbatim + => union switch() { + case label1.1; .. case label1.n; + ; + case label2.1; .. case label2.n; + ... ... + case labeln.1; .. case labeln.n; + ; + default: + ; + }; + @endverbatim + * + * For unions a copyIn routine named _____copyIn + * will be prepared. The signature of this copyIn routine is: + * @verbatim + void copyIn ( + c_base base, + :: *from, + struct __ *to); + @endverbatim + * + * The copyIn routine signature is generated based upon the input + * parameters which specify the scope and it's name. + * + * The copyIn routine will first copy the union discriminant from the + * source to the target. This code is also generated by this function. + * The diferent variants of the union are handled by an switch statement + * that is generated by this function. + * + * @verbatim + switch (to->_d) { + case : // handled by idl_unionLabelOpenClose + // copy union case // handled by idl_unionCaseOpenClose + break; // handled by idl_unionCaseOpenClose + case : // handled by idl_unionLabelOpenClose + // copy union case // handled by idl_unionCaseOpenClose + break; // handled by idl_unionCaseOpenClose + default: // handled by idl_unionLabelOpenClose + // copy union case // handled by idl_unionCaseOpenClose + break; // handled by idl_unionCaseOpenClose + } // handled by idl_unionClose + @endverbatim + * + * @param scope Current scope + * @param name Name of the union + * @param unionSpec Specifies the number of union cases and the union switch type + * @return Next action for this union (idl_explore) + */ +static idl_action +idl_unionOpen ( + idl_scope scope, + const char *name, + idl_typeUnion unionSpec, + void *userData) +{ + c_ulong maxlen; + c_char *scopedName; + c_char *cxxTypeName; + c_char *dbTypeName = NULL; + + OS_UNUSED_ARG(userData); + + OS_UNUSED_ARG(userData); + + scopedName = idl_scopeStack (scope, "_", name); + cxxTypeName = idl_scopeStackISOCxx2 (scope, "::", name); + idl_fileOutPrintf (idl_fileCur(), "v_copyin_result\n"); + idl_fileOutPrintf (idl_fileCur(), "__%s__copyIn(\n", scopedName); + idl_fileOutPrintf (idl_fileCur(), " c_type dbType,\n"); + idl_fileOutPrintf (idl_fileCur(), " const %s *from,\n", cxxTypeName); + idl_fileOutPrintf (idl_fileCur(), " struct _%s *to)\n", scopedName); + idl_fileOutPrintf (idl_fileCur(), "{\n"); + idl_fileOutPrintf (idl_fileCur(), " v_copyin_result result = V_COPYIN_RESULT_OK;\n"); + idl_fileOutPrintf (idl_fileCur(), " (void) dbType;\n\n"); + /* QAC EXPECT 3416; No side effect here */ + if (idl_typeSpecType(idl_typeUnionSwitchKind(unionSpec)) == idl_tbasic) { + dbTypeName = idl_scopedSplTypeName (idl_typeUnionSwitchKind(unionSpec)); + /* String is not allowed here */ + idl_fileOutPrintf (idl_fileCur(), " to->_d = (%s)from->_d();\n", dbTypeName); + } else if (idl_typeSpecType(idl_typeUnionSwitchKind(unionSpec)) == idl_tenum) { + maxlen = idl_typeEnumNoElements(idl_typeEnum(idl_typeUnionSwitchKind(unionSpec))); + idl_fileOutPrintf (idl_fileCur(), " if((((c_long)(from->_d())) >= 0) && (((c_long)(from->_d())) < %d)){\n", + maxlen); + dbTypeName = idl_scopedSplTypeName (idl_typeUnionSwitchKind(unionSpec)); + idl_fileOutPrintf (idl_fileCur(), " to->_d = (%s)from->_d();\n", dbTypeName); + idl_fileOutPrintf (idl_fileCur(), " } else {\n"); + idl_fileOutPrintf (idl_fileCur(), " "); + idl_boundsCheckFail(ELEMENT, scope, (idl_typeSpec)unionSpec, name); + idl_fileOutPrintf (idl_fileCur(), " result = V_COPYIN_RESULT_INVALID;\n"); + idl_fileOutPrintf (idl_fileCur(), " }\n"); + } else if ((idl_typeSpecType(idl_typeUnionSwitchKind(unionSpec)) == idl_ttypedef) && + (idl_typeSpecType(idl_typeDefActual(idl_typeDef(idl_typeUnionSwitchKind(unionSpec)))) == idl_tbasic)) { + /* String is not allowed here */ + dbTypeName = idl_scopedSplTypeName (idl_typeDefActual(idl_typeDef(idl_typeUnionSwitchKind(unionSpec)))); + idl_fileOutPrintf (idl_fileCur(), " to->_d = (%s)from->_d();\n", dbTypeName); + } else if ((idl_typeSpecType(idl_typeUnionSwitchKind(unionSpec)) == idl_ttypedef) && + (idl_typeSpecType(idl_typeDefActual(idl_typeDef(idl_typeUnionSwitchKind(unionSpec)))) == idl_tenum)) { + maxlen = idl_typeEnumNoElements(idl_typeEnum(idl_typeDefActual(idl_typeDef(idl_typeUnionSwitchKind(unionSpec))))); + dbTypeName = idl_scopedSplTypeName (idl_typeUnionSwitchKind(unionSpec)); + idl_fileOutPrintf (idl_fileCur(), " if( (((c_long)(from->_d())) >= 0) && (((c_long)(from->_d())) < %d)){\n", + maxlen); + idl_fileOutPrintf (idl_fileCur(), " to->_d = (%s)from->_d();\n", dbTypeName); + idl_fileOutPrintf (idl_fileCur(), " } else {\n"); + idl_fileOutPrintf (idl_fileCur(), " "); + idl_boundsCheckFail(ELEMENT, scope, (idl_typeSpec)unionSpec, name); + idl_fileOutPrintf (idl_fileCur(), " result = V_COPYIN_RESULT_INVALID;\n"); + idl_fileOutPrintf (idl_fileCur(), " }\n"); + } else { + /* Do nothing, only to prevent dangling else-ifs QAC reports */ + } + idl_fileOutPrintf (idl_fileCur(), " switch (to->_d) {\n"); + + caseIndex = 0; + os_free(scopedName); + os_free(cxxTypeName); + os_free(dbTypeName); + + return idl_explore; +} + +/** @brief callback function called on closure of a union in the IDL input file. + * + * Generate code for the following IDL construct: + * @verbatim + union switch() { + case label1.1; .. case label1.n; + ; + case label2.1; .. case label2.n; + ... ... + case labeln.1; .. case labeln.n; + ; + default: + ; + => }; + @endverbatim + * + * The function finalizes the copyIn routine for the union. + * + * @param name Name of the union + */ +static void +idl_unionClose ( + const char *name, + void *userData) +{ + OS_UNUSED_ARG(name); + OS_UNUSED_ARG(userData); + + idl_fileOutPrintf (idl_fileCur(), " }\n"); + idl_fileOutPrintf (idl_fileCur(), " return result;\n"); + idl_fileOutPrintf (idl_fileCur(), "}\n"); + idl_fileOutPrintf (idl_fileCur(), "\n"); + + caseIndex = -1; +} + +/** @brief callback function called on definition of a union case in the IDL input file. + * + * Generate code for the following IDL construct: + * @verbatim + union switch() { + case label1.1; .. case label1.n; + => ; + case label2.1; .. case label2.n; + => ... ... + case labeln.1; .. case labeln.n; + => ; + default: + => ; + }; + @endverbatim + * + * Depending on the type of the union case, a copy strategy is used: + * - If the type is \b idl_tbasic, for a string the string is duplicated + * via c_stringNew, for other basic types \b idl_typeBasicType is called. + * - If the type is \b idl_typedef the copy strategy depends on the refered type. + * When this type is \b idl_tarray or \b idl_tseq a type specific copy routine + * is called. When type is something else, this routine is called recursively with + * with the refered type. + * - If the type is \b idl_tenum, the element is immediately assigned. + * - If the type is \b idl_tstruct or \b idl_tunion, the copyIn routine of that struct + * or union type is called. + * - If the type is \b idl_tarray the array copy context is set and the service + * to generate code for copying arrays is called. + * - If the type is \b idl_tseq, the sequence copy context is setup and the + * service to generate code for copying sequences is called. + * + * @param scope Current scope (the union the union case is defined in) + * @param name Name of the union case + * @param typeSpec Specifies the type of the union case + */ +static void +idl_unionCaseOpenClose ( + idl_scope scope, + const char *name, + idl_typeSpec typeSpec, + void *userData) +{ + c_ulong maxlen; + c_char *scopedName; + c_char* cxxName; + c_char *cxxTypeName; + + cxxName = idl_cxxId(name); + scopedName = idl_scopedTypeName (typeSpec); + cxxTypeName = idl_ISOCxx2TypeFromTypeSpec(typeSpec); + + /* QAC EXPECT 3416; No side effect here */ + if (idl_typeSpecType(typeSpec) == idl_tbasic) { + /* QAC EXPECT 3416; No side effect here */ + idl_basicCaseType (scope, cxxName, idl_typeBasic(typeSpec), "from->", "to->_u."); + idl_fileOutPrintf (idl_fileCur(), " break;\n"); + /* QAC EXPECT 3416; No side effect here */ + } else if (idl_typeSpecType(typeSpec) == idl_ttypedef) { + if (idl_typeSpecType(idl_typeDefRefered(idl_typeDef(typeSpec))) == idl_tarray || + idl_typeSpecType(idl_typeDefRefered(idl_typeDef(typeSpec))) == idl_tseq || + idl_typeSpecType(idl_typeDefRefered(idl_typeDef(typeSpec))) == idl_tstruct || + idl_typeSpecType(idl_typeDefRefered(idl_typeDef(typeSpec))) == idl_tunion) { + idl_fileOutPrintf (idl_fileCur(), " if(V_COPYIN_RESULT_IS_OK(result)){\n"); + idl_fileOutPrintf (idl_fileCur(), " extern v_copyin_result __%s__copyIn(c_type, const %s *, _%s *);\n", + scopedName, + cxxTypeName, + scopedName); + idl_fileOutPrintf (idl_fileCur(), " const %s &x = from->%s();\n", + cxxTypeName, + cxxName); + idl_fileOutPrintf (idl_fileCur(), " result = __%s__copyIn(c_unionCaseType(c_unionUnionCase(dbType, %d)), &x, &to->_u.%s);\n", + scopedName, + caseIndex, + cxxName); + idl_fileOutPrintf (idl_fileCur(), " }\n"); + idl_fileOutPrintf (idl_fileCur(), " break;\n"); + } else { + /* Calls itself for the actual type in case of typedef */ + /* QAC EXPECT 3670; Recursive calls is a good practice, the recursion depth is limited here */ + idl_unionCaseOpenClose ( + scope, + name, + idl_typeDefRefered(idl_typeDef(typeSpec)), + userData); + /* Compensate for recursion, where caseIndex will now be incremented twice. */ + caseIndex--; + } + /* QAC EXPECT 3416; No side effect here */ + } else if (idl_typeSpecType(typeSpec) == idl_tenum) { + maxlen = idl_typeEnumNoElements(idl_typeEnum(typeSpec)); + os_free(scopedName); + scopedName = idl_scopedSplTypeName (typeSpec); + + idl_fileOutPrintf (idl_fileCur(), " if((((c_long)(from->%s())) >= 0) && (((c_long)(from->%s())) < %d)){\n", + cxxName, + cxxName, + maxlen); + idl_fileOutPrintf (idl_fileCur(), " to->_u.%s = (%s)from->%s();\n", + cxxName, + scopedName, + cxxName); + idl_fileOutPrintf (idl_fileCur(), " } else {\n"); + idl_fileOutPrintf (idl_fileCur(), " "); + idl_boundsCheckFail(CASE, scope, (idl_typeSpec)typeSpec, name); + idl_fileOutPrintf (idl_fileCur(), " result = V_COPYIN_RESULT_INVALID;\n"); + idl_fileOutPrintf (idl_fileCur(), " }\n"); + idl_fileOutPrintf (idl_fileCur(), " break;\n"); + /* QAC EXPECT 3416; No side effect here */ + } else if (idl_typeSpecType(typeSpec) == idl_tstruct || + idl_typeSpecType(typeSpec) == idl_tunion) { + idl_fileOutPrintf (idl_fileCur(), " if(V_COPYIN_RESULT_IS_OK(result)){\n"); + idl_fileOutPrintf (idl_fileCur(), " extern v_copyin_result __%s__copyIn(c_type, const %s *, _%s *);\n", + scopedName, + cxxTypeName, + scopedName); + idl_fileOutPrintf (idl_fileCur(), " const %s &x = from->%s();\n", + cxxTypeName, + cxxName); + idl_fileOutPrintf (idl_fileCur(), " result = __%s__copyIn(c_unionCaseType(c_unionUnionCase(dbType, %d)), &x, &to->_u.%s);\n", + scopedName, + caseIndex, + cxxName); + idl_fileOutPrintf (idl_fileCur(), " }\n"); + idl_fileOutPrintf (idl_fileCur(), " break;\n"); + /* QAC EXPECT 3416; No side effect here */ + } else if (idl_typeSpecType(typeSpec) == idl_tarray) { + c_char source[256]; + + os_free(scopedName); + scopedName = idl_scopedSplTypeIdent (idl_typeArrayActual(idl_typeArray(typeSpec))); + snprintf(source, sizeof(source), "from->%s()", name); + idl_fileOutPrintf (idl_fileCur(), " if(V_COPYIN_RESULT_IS_OK(result)){\n"); + idl_fileOutPrintf (idl_fileCur(), " typedef %s _DestType", scopedName); + idl_arrayDimensions (idl_typeArray(typeSpec), OS_FALSE); + idl_fileOutPrintf (idl_fileCur(), ";\n"); + idl_fileOutPrintf (idl_fileCur(), " _DestType *dest = &to->_u.%s;\n", cxxName); + idl_fileOutPrintf (idl_fileCur(), " c_type type0 = c_unionCaseType(c_unionUnionCase(dbType, %d));\n", caseIndex); + idl_fileOutPrintf (idl_fileCur(), " while(c_baseObjectKind(type0) == M_COLLECTION && c_collectionTypeKind(type0) == OSPL_C_ARRAY) {;\n"); + idl_fileOutPrintf (idl_fileCur(), " type0 = c_collectionTypeSubType(type0);\n"); + idl_fileOutPrintf (idl_fileCur(), " }\n"); + idl_arrayElements (scope, idl_typeArray(typeSpec), source, "dest", 2, OS_FALSE, OS_FALSE, userData); + idl_fileOutPrintf (idl_fileCur(), " }\n"); + idl_fileOutPrintf (idl_fileCur(), " break;\n"); + /* QAC EXPECT 3416; No side effect here */ + } else if (idl_typeSpecType(typeSpec) == idl_tseq) { + c_char type_name[256]; + idl_typeSpec nextType; + + os_free(scopedName); + nextType = idl_typeSeqType(idl_typeSeq(typeSpec)); + scopedName = idl_scopedSplTypeName(nextType); + maxlen = idl_typeSeqMaxSize(idl_typeSeq(typeSpec)); + snprintf (type_name, sizeof(type_name), "_%s_seq", name); + + idl_fileOutPrintf (idl_fileCur(), " /* Code generated by %s at line %d */\n\n",__FILE__,__LINE__); + idl_fileOutPrintf (idl_fileCur(), " if(V_COPYIN_RESULT_IS_OK(result)){\n"); + idl_fileOutPrintf (idl_fileCur(), " c_type type0 = c_unionCaseType(c_unionUnionCase(dbType, %d));\n", caseIndex); + idl_fileOutPrintf (idl_fileCur(), " %s *dest0;\n", scopedName); + idl_fileOutPrintf (idl_fileCur(), " const %s *src = &(from->%s());\n\n", cxxTypeName, cxxName); + idl_fileOutPrintf (idl_fileCur(), " c_long length0 = (c_long)(*src).size();\n"); + + if(maxlen != 0){ + idl_fileOutPrintf(idl_fileCur(), " if(length0 > %u){\n", maxlen); + idl_fileOutPrintf(idl_fileCur(), " "); + idl_boundsCheckFail(CASE, scope, (idl_typeSpec)typeSpec, name); + idl_fileOutPrintf(idl_fileCur(), " result = OS_C_FALSE;\n"); + idl_fileOutPrintf(idl_fileCur(), " } else {\n"); + + idl_fileOutPrintf (idl_fileCur(), " dest0 = (%s *)c_newSequence(c_collectionType(type0), length0);\n", scopedName); + idl_seqLoopCopy (scope, nextType, "*src", "dest0", 1, 3, userData); + idl_fileOutPrintf (idl_fileCur(), " to->_u.%s = (c_sequence)dest0;\n", cxxName); + + idl_fileOutPrintf(idl_fileCur(), " }\n"); + } else { + idl_fileOutPrintf (idl_fileCur(), " dest0 = (%s *)c_newSequence(c_collectionType(type0), length0);\n", scopedName); + idl_seqLoopCopy (scope, nextType, "*src", "dest0", 1, 2, userData); + idl_fileOutPrintf (idl_fileCur(), " to->_u.%s = (c_sequence)dest0;\n", cxxName); + } + idl_fileOutPrintf(idl_fileCur(), " }\n"); + idl_fileOutPrintf(idl_fileCur(), " break;\n"); + } else { + /* Do nothing, only to prevent dangling else-ifs QAC reports */ + } + /* QAC EXPECT 5101, 5103: Complexity is limited, by independent cases, per case the number of lines is lower */ + + caseIndex++; + os_free(cxxTypeName); + os_free(scopedName); + os_free(cxxName); +} + +/** @brief callback function called on definition of the union case labels in the IDL input file. + * + * Generate code for the following IDL construct: + * @verbatim + union switch() { + => case label1.1; .. case label1.n; + ; + => case label2.1; .. case label2.n; + ... ... + => case labeln.1; .. case labeln.n; + ; + default: + ; + }; + @endverbatim + * + * The function generates code to produce the switch label related + * to the union case. + * + * @param scope Current scope (the union the labels are defined in) + * @param labelSpec Specifies the number of labels of the union case + */ +static void +idl_unionLabelOpenClose ( + idl_scope ownScope, + idl_labelVal labelVal, + void *userData) +{ + OS_UNUSED_ARG(ownScope); + OS_UNUSED_ARG(userData); + + /* QAC EXPECT 3416; No side effect here */ + if (idl_labelValType(labelVal) == idl_ldefault) { + idl_fileOutPrintf (idl_fileCur(), " default:\n"); + } else { + idl_fileOutPrintf (idl_fileCur(), " case %s:\n", idl_valueFromLabelVal(labelVal)); + } +} + +/** + * Standard control structure to specify that inline + * type definitions are to be processed prior to the + * type itself in contrast with inline. + */ +static idl_programControl idlControl = { + idl_prior + }; + +/** @brief return the program control structure for the CORBA C++ CopyIn generation functions. + */ +static idl_programControl * +idl_getControl( + void *userData) +{ + OS_UNUSED_ARG(userData); + return &idlControl; +} + +static void +idl_artificialDefaultLabelOpenClose( + idl_scope scope, + idl_labelVal labelVal, + idl_typeSpec typeSpec, + void *userData) +{ + OS_UNUSED_ARG(scope); + OS_UNUSED_ARG(labelVal); + OS_UNUSED_ARG(typeSpec); + OS_UNUSED_ARG(userData); + + idl_fileOutPrintf (idl_fileCur(), " default:\n"); + idl_fileOutPrintf (idl_fileCur(), " break;\n"); +} + +/** + * Specifies the callback table for the CORBA C++ CopyIn generation functions. + */ +static struct idl_program +idl_genISOCxx2Copyin = { + idl_getControl, + idl_fileOpen, + NULL, /* idl_fileClose */ + idl_moduleOpen, + NULL, /* idl_moduleClose */ + idl_structureOpen, + idl_structureClose, + idl_structureMemberOpenClose, + NULL, /* idl_enumerationOpen */ + NULL, /* idl_enumerationClose */ + NULL, /* idl_enumerationElementOpenClose */ + idl_unionOpen, + idl_unionClose, + idl_unionCaseOpenClose, + NULL, /* idl_unionLabelsOpenClose */ + idl_unionLabelOpenClose, + idl_typedefOpenClose, + NULL, /* idl_boundedStringOpenClose */ + NULL, /* idl_sequenceOpenClose */ + NULL, /* idl_constantOpenClose */ + idl_artificialDefaultLabelOpenClose, /* idl_artificialDefaultLabelOpenClose */ + NULL /* userData */ +}; + +/** @brief return the callback table for the CORBA C++ CopyIn generation functions. + */ +idl_program +idl_genISOCxx2CopyinProgram ( + void *userData) +{ + idl_genISOCxx2Copyin.userData = userData; + return &idl_genISOCxx2Copyin; +} diff --git a/src/tools/idlpp/code/idl_genISOCxx2Copyin.h b/src/tools/idlpp/code/idl_genISOCxx2Copyin.h new file mode 100644 index 000000000..340a3e691 --- /dev/null +++ b/src/tools/idlpp/code/idl_genISOCxx2Copyin.h @@ -0,0 +1,19 @@ +/* + * OpenSplice DDS + * + * This software and documentation are Copyright 2006 to 2015 PrismTech + * Limited and its licensees. All rights reserved. See file: + * + * $OSPL_HOME/LICENSE + * + * for full copyright notice and license terms. + * + */ +#ifndef IDL_GENISOCXX2COPYIN_H +#define IDL_GENISOCXX2COPYIN_H + +#include "idl_program.h" + +idl_program idl_genISOCxx2CopyinProgram (void *userData); + +#endif /* IDL_GENISOCXX2COPYIN_H */ diff --git a/src/tools/idlpp/code/idl_genISOCxx2Copyout.c b/src/tools/idlpp/code/idl_genISOCxx2Copyout.c index 2fa32107b..1d849a593 100644 --- a/src/tools/idlpp/code/idl_genISOCxx2Copyout.c +++ b/src/tools/idlpp/code/idl_genISOCxx2Copyout.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -45,9 +46,9 @@ /** Text indentation level (4 spaces per indent) */ static c_long loopIndent; - /** Index for array loop variables, incremented for each array dimension */ +/** Index for array loop variables, incremented for each array dimension */ static c_long varIndex; - /** Preset discriminator assignment action */ +/** Preset discriminator assignment action */ static c_char set_discriminator[256]; static void @@ -119,33 +120,52 @@ idl_valueFromLabelVal( return labelName; } -#if 0 -/** @brief Checks if the type is an enum when generating for ISOCpp - * - * @param type specifies the type to check it is an enum - * @return TRUE when generating for ISOcpp and type is an enum - */ -static os_boolean -idl_getIsISOCppEnum( +/*********************************************************** + * Identifies contiguous types for Cxx11. + * Indentifies if a type can be copied straight in or out + * of the internal database rep with a vanilla memcpy on account + * of being laid out exactly the same. For the IDL-Cxx11 mapping + * this has different results than for conventional IDL-C(++) + * language mappings, due to the fact that enums are now mapped + * enum classes and structs consist of classes with encapsulated + * private attributes. + * @param type The definition of the type. + * @return TRUE if it is a contiguous / copyable type, FALSE otherwise. + ***********************************************************/ +c_bool +idl_isCxx11Contiguous( c_type type) { - os_boolean isEnum; - switch (c_baseObject(type)->kind) { - case M_ENUMERATION: - isEnum = OS_TRUE; + case M_EXCEPTION: + case M_STRUCTURE: + /* Since in ISOCPP2 structs are mapped to C++ classes with property getters/setters + * (and not to C++ structs with only members!!!) they cannot be copied blockwise anymore. + * and That means an IDL struct in ISOCPP2 is by definition not contiguous. + */ + return FALSE; + break; + case M_PRIMITIVE: + if (c_primitive(type)->kind == P_BOOLEAN && + idl_getIsISOCpp() && idl_getIsISOCppTypes()) + { + /* Those clever chaps at the STL have optimised + * vector for size. One bit per bool apparently. */ + return FALSE; + } + return TRUE; break; + case M_ENUMERATION: + return FALSE; + break; case M_TYPEDEF: - isEnum = idl_getIsISOCppEnum(c_typeDef(type)->alias); - break; + return idl_isCxx11Contiguous(c_typeDef(type)->alias); + break; default: - isEnum = OS_FALSE; - break; + return FALSE; + break; } - - return isEnum; } -#endif static c_bool idl_requiresInitializedSequence( @@ -158,7 +178,7 @@ idl_requiresInitializedSequence( result = TRUE; } if (idl_typeSpecType(nextType) == idl_tstruct) { - result = !idl_isContiguous(idl_typeSpecDef(nextType)); + result = !idl_isCxx11Contiguous(idl_typeSpecDef(nextType)); } if (idl_typeSpecType(nextType) == idl_ttypedef) { idl_typeSpec alias = idl_typeDefActual(idl_typeDef(nextType)); @@ -167,13 +187,16 @@ idl_requiresInitializedSequence( idl_typeSpecType(alias) == idl_tbasic) { result = TRUE; } else if (idl_typeSpecType(alias) == idl_tseq) { - result = idl_requiresInitializedSequence(idl_typeSeq(nextType)); + result = TRUE; } else if (idl_typeSpecType(alias) == idl_tstruct) { - result = !idl_isContiguous(idl_typeSpecDef(alias)); + result = !idl_isCxx11Contiguous(idl_typeSpecDef(alias)); } } if (idl_typeSpecType(nextType) == idl_tseq) { - result = idl_requiresInitializedSequence(idl_typeSeq(nextType)); + result = TRUE; + } + if (idl_typeSpecType(nextType) == idl_tenum) { + result = TRUE; } return result; @@ -890,7 +913,7 @@ idl_arrayLoopCopyBody( c_char destin[256]; c_long total_indent; c_char *functionPrefix = idl_scopedTypeName(typeSpec); - c_char *dbTypeName; + c_char *dbTypeName, *cxxTypeName; loopIndent++; switch (idl_typeSpecType(typeSpec)) { @@ -910,11 +933,9 @@ idl_arrayLoopCopyBody( idl_fileOutPrintf(idl_fileCur(), ");\n"); break; case idl_ttypedef: - if(stacRequested) - { + if(stacRequested) { /* stac found, bypass the typedef and recurse deeper */ - if(idl_typeSpecType(idl_typeDefActual(idl_typeDef(typeSpec))) == idl_tarray) - { + if(idl_typeSpecType(idl_typeDefActual(idl_typeDef(typeSpec))) == idl_tarray) { /* An array type is not handled by idl_arrayLoopCopyBody operation * so we have to go up to the idl_arrayElements operation */ @@ -925,8 +946,7 @@ idl_arrayLoopCopyBody( indent, stacRequested, catsRequested); - } else - { + } else { idl_arrayLoopCopyBody( typeArray, idl_typeDefActual(idl_typeDef(typeSpec)), @@ -936,10 +956,9 @@ idl_arrayLoopCopyBody( stacRequested, catsRequested); } - } else - { - idl_printIndent(loopIndent + indent); - switch (idl_typeSpecType(idl_typeDefActual(idl_typeDef(typeSpec)))) { + } else { + idl_printIndent(loopIndent + indent); + switch (idl_typeSpecType(idl_typeDefActual(idl_typeDef(typeSpec)))) { case idl_tstruct: case idl_tunion: case idl_tarray: @@ -957,16 +976,20 @@ idl_arrayLoopCopyBody( case idl_tbasic: /* QAC EXPECT 3416; No side effect here */ if (idl_typeBasicType(idl_typeBasic(idl_typeDefActual(idl_typeDef(typeSpec)))) == idl_string) { - idl_fileOutPrintf(idl_fileCur(), "(%s).data()", to); + idl_fileOutPrintf(idl_fileCur(), "(%s)", to); idl_arrayLoopCopyIndex(typeArray); idl_fileOutPrintf(idl_fileCur(), " = ((*%s)", from); idl_arrayLoopCopyIndex(typeArray); idl_fileOutPrintf(idl_fileCur(), ") ? "); - idl_fileOutPrintf(idl_fileCur(), "((*%s)", from); + idl_fileOutPrintf(idl_fileCur(), "(*%s)", from); idl_arrayLoopCopyIndex(typeArray); - idl_fileOutPrintf(idl_fileCur(), ") : \"\";\n"); + idl_fileOutPrintf(idl_fileCur(), " : \"\";\n"); } else { - idl_fileOutPrintf(idl_fileCur(), "%s = %s;\n", to, from); + idl_fileOutPrintf(idl_fileCur(), "(%s)", to); + idl_arrayLoopCopyIndex(typeArray); + idl_fileOutPrintf(idl_fileCur(), " = (*%s)", from); + idl_arrayLoopCopyIndex(typeArray); + idl_fileOutPrintf(idl_fileCur(), ";\n"); } break; case idl_tenum: @@ -989,13 +1012,27 @@ idl_arrayLoopCopyBody( idl_fileOutPrintf(idl_fileCur(), " = ((*%s)", from); idl_arrayLoopCopyIndex(typeArray); idl_fileOutPrintf(idl_fileCur(), ") ? "); - idl_fileOutPrintf(idl_fileCur(), "((*%s)", from); + idl_fileOutPrintf(idl_fileCur(), "(*%s)", from); idl_arrayLoopCopyIndex(typeArray); - idl_fileOutPrintf(idl_fileCur(), ") : \"\";\n"); + idl_fileOutPrintf(idl_fileCur(), " : \"\";\n"); } else { - assert(0); + idl_fileOutPrintf(idl_fileCur(), "(%s)", to); + idl_arrayLoopCopyIndex(typeArray); + idl_fileOutPrintf(idl_fileCur(), " = (*%s)", from); + idl_arrayLoopCopyIndex(typeArray); + idl_fileOutPrintf(idl_fileCur(), ";\n"); } break; + case idl_tenum: + cxxTypeName = idl_ISOCxx2TypeFromTypeSpec(typeSpec); + idl_printIndent(loopIndent + indent); + idl_fileOutPrintf(idl_fileCur(), "(%s)", to); + idl_arrayLoopCopyIndex(typeArray); + idl_fileOutPrintf(idl_fileCur(), " = (%s)(*%s)", cxxTypeName, from); + idl_arrayLoopCopyIndex(typeArray); + idl_fileOutPrintf(idl_fileCur(), ";\n"); + os_free(cxxTypeName); + break; case idl_tseq: nextType = idl_typeSeqType(idl_typeSeq(typeSpec)); total_indent = indent + idl_indexSize(typeArray); @@ -1162,7 +1199,6 @@ idl_arrayElements( os_boolean stacRequested, os_boolean catsRequested) { - char *buf; idl_typeSpec subType; idl_type idlType; @@ -1184,25 +1220,27 @@ idl_arrayElements( case idl_tbasic: /* QAC EXPECT 3416; No side effect here */ if (idl_typeBasicType(idl_typeBasic(subType)) == idl_string) { - loopIndent = 0; idl_arrayLoopCopy(typeArray, from, to, indent, stacRequested, catsRequested); - } else if(catsRequested) - { + } else if(catsRequested) { idl_printIndent(indent); idl_fileOutPrintf(idl_fileCur()," strncpy((char *)(%s).data(), %s, %d);\n", to, from, idl_typeArraySize(typeArray)); - } else - { + } else if (idl_typeSpecType(idl_typeArrayType(typeArray)) != idl_tarray){ idl_printIndent(indent); idl_fileOutPrintf(idl_fileCur(), " memcpy ((void *)(%s).data(), %s, sizeof (*%s));\n", to, from, from); + } else { + idl_arrayLoopCopy(typeArray, from, to, indent, stacRequested, catsRequested); } break; case idl_tenum: idl_printIndent(indent); - idl_fileOutPrintf(idl_fileCur(), " memcpy ((void *)(%s).data(), %s, sizeof (*%s));\n", to, from, from); + if (idl_typeSpecType(idl_typeArrayType(typeArray)) != idl_tarray){ + idl_fileOutPrintf(idl_fileCur(), " memcpy ((void *)(%s).data(), %s, sizeof (*%s));\n", to, from, from); + } else { + idl_arrayLoopCopy(typeArray, from, to, indent, stacRequested, catsRequested); + } break; case idl_tstruct: case idl_tunion: - loopIndent = 0; idl_arrayLoopCopy(typeArray, from, to, indent, stacRequested, catsRequested); break; case idl_ttypedef: @@ -1211,20 +1249,18 @@ idl_arrayElements( /* QAC EXPECT 3416; No side effect here */ if (idl_typeBasicType(idl_typeBasic(idl_typeDefActual(idl_typeDef(subType)))) == idl_string) { loopIndent = 0; - buf = os_malloc(strlen(from)+4); - os_sprintf(buf, "(*%s)", from); - idl_arrayLoopCopy(typeArray, buf, to, indent, stacRequested, catsRequested); - os_free(buf); - } else { + idl_arrayLoopCopy(typeArray, from, to, indent, stacRequested, catsRequested); + } else if (idl_typeSpecType(idl_typeArrayType(typeArray)) != idl_tarray){ idl_printIndent(indent); idl_fileOutPrintf(idl_fileCur(), " memcpy ((void *)(%s).data(), %s, sizeof (*%s));\n", to, from, from); + } else { + idl_arrayLoopCopy(typeArray, from, to, indent, stacRequested, catsRequested); } /* QAC EXPECT 3416; No side effect here */ } else if (idl_typeSpecType(idl_typeDefActual(idl_typeDef(subType))) == idl_tenum) { idl_printIndent(indent); idl_fileOutPrintf(idl_fileCur(), " memcpy ((void *)(%s).data(), %s, sizeof (*%s));\n", to, from, from); } else { - loopIndent = 0; idl_arrayLoopCopy(typeArray, from, to, indent, stacRequested, catsRequested); } break; @@ -1325,7 +1361,7 @@ idl_seqIndex( * Structure types (not unions) that do not contain any reference types (or unions) * are copied via a plain memory copy because the sequence elements are * located in consequtive memory with the same memory map for C++ CORBA and OpenSpliceDDS. - * These cases are identified by idl_isContiguous() + * These cases are identified by idl_isCxx11Contiguous() * * @param typeSpec The specification of the actual type of the sequence * @param from Specifies the identification of the source @@ -1348,31 +1384,25 @@ idl_seqLoopCopy( c_char *cxxTypeName; c_char *functionPrefix; c_char *dbTypeName; - c_char *seqIndex = idl_seqIndex(loop_index); + c_char *seqIndex; - if (idl_isContiguous(idl_typeSpecDef(typeSpec))) { + if (idl_isCxx11Contiguous(idl_typeSpecDef(typeSpec))) { c_char *dbTypeName = idl_scopedSplTypeName(typeSpec); - idl_printIndent(indent); - idl_fileOutPrintf(idl_fileCur(), "{\n"); - idl_printIndent(indent); - idl_fileOutPrintf(idl_fileCur(), " std::vector<%s>* cv = reinterpret_cast< std::vector<%s>* >(%s);\n", - dbTypeName, - dbTypeName, - (strlen(to) > 1) ? to+1 : "&x"); + seqIndex = idl_seqIndex(loop_index-1); idl_printIndent(indent); - idl_fileOutPrintf(idl_fileCur(), " cv->insert(cv->end(), %s, %s + size%d);\n", + idl_fileOutPrintf(idl_fileCur(), " (%s)%s.assign(%s, %s + size%d);\n", + to, seqIndex, from, from, loop_index-1); - idl_printIndent(indent); - idl_fileOutPrintf(idl_fileCur(), "}\n"); os_free(dbTypeName); os_free(seqIndex); return; } + seqIndex = idl_seqIndex(loop_index); idl_printIndent(indent); idl_fileOutPrintf(idl_fileCur(), "{\n"); idl_printIndent(indent); diff --git a/src/tools/idlpp/code/idl_genISOCxx2Copyout.h b/src/tools/idlpp/code/idl_genISOCxx2Copyout.h index 2180de593..a166dacdd 100644 --- a/src/tools/idlpp/code/idl_genISOCxx2Copyout.h +++ b/src/tools/idlpp/code/idl_genISOCxx2Copyout.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/idlpp/code/idl_genISOCxx2Header.c b/src/tools/idlpp/code/idl_genISOCxx2Header.c index 5e47e90e6..d3267f760 100644 --- a/src/tools/idlpp/code/idl_genISOCxx2Header.c +++ b/src/tools/idlpp/code/idl_genISOCxx2Header.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -68,7 +69,7 @@ idl_fileOpen ( c_char *tmplPath; c_char *orbPath; int tmplFile; - struct os_stat tmplStat; + struct os_stat_s tmplStat; unsigned int nRead; os_char* tmpName; os_uint32 i; @@ -104,6 +105,7 @@ idl_fileOpen ( idlpp_macroAttrib = idl_macroAttribNew(IDL_TOKEN_START, IDL_TOKEN_OPEN, IDL_TOKEN_CLOSE); idlpp_macroSet = idl_macroSetNew(); idlpp_inStream = idl_streamInNew(idlpp_template, idlpp_macroAttrib); + os_free(idlpp_template); idl_macroSetAdd(idlpp_macroSet, idl_macroNew("basename", name)); tmpName = os_strdup(name); for(i = 0; i < strlen(tmpName); i++) @@ -129,7 +131,7 @@ idl_fileOpen ( idlpp_template = os_malloc(tmplStat.stat_size+1); tmplFile = open(tmplFileName, O_RDONLY); nRead = (unsigned int)read(tmplFile, idlpp_template, tmplStat.stat_size); - memset(&idlpp_template[nRead], 0, tmplStat.stat_size+1-nRead); + (void)memset(&idlpp_template[nRead], 0, tmplStat.stat_size+1-nRead); close(tmplFile); idlpp_indent_level = 0; @@ -227,6 +229,7 @@ idl_structureOpen( /* Store data-type in iterator for future generation of type descriptor. */ idl_metaCxxAddType(scope, name, idl_typeSpec(structSpec), &cxxUserData->idlpp_metaList); + os_free(scopedTypeName); } return idl_explore; } diff --git a/src/tools/idlpp/code/idl_genISOCxx2Header.h b/src/tools/idlpp/code/idl_genISOCxx2Header.h index 0e47284d7..f7808e194 100644 --- a/src/tools/idlpp/code/idl_genISOCxx2Header.h +++ b/src/tools/idlpp/code/idl_genISOCxx2Header.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/idlpp/code/idl_genISOCxx2Helper.c b/src/tools/idlpp/code/idl_genISOCxx2Helper.c index 7a2b9e871..49a0511c7 100644 --- a/src/tools/idlpp/code/idl_genISOCxx2Helper.c +++ b/src/tools/idlpp/code/idl_genISOCxx2Helper.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,8 +20,10 @@ */ #include "idl_genISOCxx2Helper.h" #include "idl_genLanguageHelper.h" +#include "idl_genCHelper.h" #include "os_heap.h" #include "os_stdlib.h" +#include "os_abstract.h" #include "c_misc.h" #include "c_metabase.h" #include "ut_collection.h" @@ -473,15 +476,35 @@ idl_ISOCxx2ValueFromCValue( case M_PRIMITIVE: switch (c_primitiveKind(t)) { - case P_SHORT: - case P_USHORT: case P_LONG: + cxxValue = os_malloc(40); + if (v.is.Long != INT32_MIN) { + snprintf(cxxValue, 40, "%dL", v.is.Long); + } else { + snprintf(cxxValue, 40, "(-2147483647L - 1L)"); + } + break; case P_ULONG: + cxxValue = os_malloc(40); + snprintf(cxxValue, 40, "%uU", v.is.ULong); + break; case P_LONGLONG: + cxxValue = os_malloc(40); + if (v.is.LongLong != INT64_MIN) { + snprintf(cxxValue, 40, "%"PA_PRId64"LL", v.is.LongLong); + } else { + snprintf(cxxValue, 40, "(-9223372036854775807LL - 1LL)"); + } + break; case P_ULONGLONG: + cxxValue = os_malloc(40); + snprintf(cxxValue, 40, "%"PA_PRIu64"ULL", v.is.ULongLong); + break; case P_OCTET: case P_FLOAT: case P_DOUBLE: + case P_SHORT: + case P_USHORT: cxxValue = c_valueImage(v); break; case P_BOOLEAN: @@ -523,6 +546,28 @@ idl_ISOCxx2ValueFromCValue( return cxxValue; } +c_char * +idl_genISOCxx2LiteralValueImage( + c_value literal, + c_type type) +{ + c_char * valueImg = NULL; + + if (c_baseObject(type)->kind != M_ENUMERATION) { + valueImg = idl_genCLiteralValueImage(literal, type); + } else { + const char *ENUM_TEMPLATE = "OSPL_UNSCOPED_ENUM_LABEL(%s,%s)"; + char *cxxEnumTp = idl_ISOCxx2Id(c_metaObject(type)->name); + char *cxxEnumLabel = idl_ISOCxx2Id(c_metaObject(c_enumeration(type)->elements[literal.is.Long])->name); + size_t valLen = strlen(cxxEnumTp) + strlen(cxxEnumLabel) + strlen(ENUM_TEMPLATE) + 1; + valueImg = os_malloc(valLen); + snprintf(valueImg, valLen, ENUM_TEMPLATE, cxxEnumTp, cxxEnumLabel); + os_free(cxxEnumTp); + os_free(cxxEnumLabel); + } + return valueImg; +} + c_bool idl_ISOCxx2IsRefType( c_type t) diff --git a/src/tools/idlpp/code/idl_genISOCxx2Helper.h b/src/tools/idlpp/code/idl_genISOCxx2Helper.h index a496210d9..66bd1be9c 100644 --- a/src/tools/idlpp/code/idl_genISOCxx2Helper.h +++ b/src/tools/idlpp/code/idl_genISOCxx2Helper.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -39,6 +40,8 @@ c_char *idl_ISOCxx2ValueFromCValue(c_type t, c_value v); c_char *idl_ISOCxx2InTypeFromCType(c_type t); +c_char *idl_genISOCxx2LiteralValueImage(c_value literal, c_type type); + c_bool idl_ISOCxx2IsRefType(c_type t); c_value idl_ISOCxx2LowestUnionDefaultValue(c_type t); diff --git a/src/tools/idlpp/code/idl_genISOCxx2SpliceType.c b/src/tools/idlpp/code/idl_genISOCxx2SpliceType.c new file mode 100644 index 000000000..296ccbb64 --- /dev/null +++ b/src/tools/idlpp/code/idl_genISOCxx2SpliceType.c @@ -0,0 +1,1071 @@ +/* + * OpenSplice DDS + * + * This software and documentation are Copyright 2006 to 2015 PrismTech + * Limited and its licensees. All rights reserved. See file: + * + * $OSPL_HOME/LICENSE + * + * for full copyright notice and license terms. + * + */ +/* + This module generates Splice type definitions related to + an IDL input file. +*/ + +#include "idl_program.h" +/** + * @file + * This module generates Splice data types + * related to an IDL input file. +*/ + +#include "idl_scope.h" +#include "idl_genSpliceType.h" +#include "idl_genLanguageHelper.h" +#include "idl_genSplHelper.h" +#include "idl_tmplExp.h" +#include "idl_dependencies.h" +#include "idl_dll.h" +#include "idl_catsDef.h" +#include "idl_stacDef.h" + +#include +#include "os_stdlib.h" +#include "c_typebase.h" +#include "os_heap.h" + +/** indentation level */ +static c_long indent_level = 0; + /** enumeration element index */ +static c_ulong enum_element = 0; +/* test_mode ensures no dependencies to other idlpp generated files are generated */ +static c_bool test_mode = FALSE; + +void +idl_genISOCxx2SpliceTypeSetTestMode ( + c_bool val) +{ + test_mode = val; +} + +static void idl_arrayDimensions(idl_typeArray typeArray, os_boolean resolveTypedefs); + +/** @brief generate name which will be used as a macro to prevent multiple inclusions + * + * From the specified basename create a macro which will + * be used to prevent multiple inclusions of the generated + * header file. The basename characters are translated + * into uppercase characters and the append string is + * appended to the macro. + * + * @param basename Basename of the IDL file passed (without extension). + * @param append String to append to the basename + * @return string of concatinated \b basename and \b append where basename is first + * converted to uppercase characters + */ +static c_char * +idl_macroFromBasename( + const char *basename, + const char *append) +{ + static c_char macro[200]; + c_long i; + + for (i = 0; i < (c_long)strlen(basename); i++) { + macro[i] = (c_char) toupper(basename[i]); + macro[i+1] = '\0'; + } + os_strncat(macro, append, sizeof(macro)); + + return macro; +} + +/* @brief callback function called on opening the IDL input file. + * + * Generate standard file header consisting of: + * - mutiple inclusion prevention + * - inclusion of Splice type definition files + * - inclusion of application specific include files related to other IDL files + * + * @param scope Current scope (not used) + * @param name Name of the IDL input file + * @return Next action for this file (idl_explore) + */ +static idl_action +idl_fileOpen( + idl_scope scope, + const char *name, + void *userData) +{ + c_ulong i; + OS_UNUSED_ARG(scope); + OS_UNUSED_ARG(userData); + + /* Generate multiple inclusion prevention code */ + idl_fileOutPrintf(idl_fileCur(), "#ifndef %s\n", idl_macroFromBasename(name, "SPLDCPS_H")); + idl_fileOutPrintf(idl_fileCur(), "#define %s\n", idl_macroFromBasename(name, "SPLDCPS_H")); + idl_fileOutPrintf(idl_fileCur(), "\n"); + + /* Generate inclusion of standard OpenSpliceDDS type definition files */ + idl_fileOutPrintf(idl_fileCur(), "#include \n"); + idl_fileOutPrintf(idl_fileCur(), "#include \n"); + idl_fileOutPrintf(idl_fileCur(), "#include \n"); + idl_fileOutPrintf(idl_fileCur(), "#include \n"); + idl_fileOutPrintf(idl_fileCur(), "#include \n"); + idl_fileOutPrintf(idl_fileCur(), "#include \n"); + idl_fileOutPrintf(idl_fileCur(), "\n"); + + idl_fileOutPrintf(idl_fileCur(), "#include \"%s.h\"\n", name); + + /* Generate code for inclusion of application specific include files */ + for (i = 0; i < idl_depLength(idl_depDefGet()); i++) { + /* For ISOCPP2, the main include file should always come first for each dependency. It subsequently includes the others. */ + const char *inclBaseName = idl_depGet (idl_depDefGet(), i); + const char *inclBasePath; + /* If dependency is on our builtin types, then add the relative path to the generated files. */ + if (strcmp(inclBaseName, "dds_builtinTopics") == 0 || strcmp(inclBaseName, "dds_dcps_builtintopics") == 0) { + inclBasePath = "dds/core/detail/"; + } else { + inclBasePath = ""; + } + idl_fileOutPrintf(idl_fileCur(), "#include \"%s%s%s\"\n", inclBasePath, inclBaseName, test_mode ? "Type.h" : "_DCPS.hpp"); + } + if (idl_depLength(idl_depDefGet()) > 0) { + idl_fileOutPrintf(idl_fileCur(), "\n"); + } + if(idl_dllGetHeader() != NULL) + { + idl_fileOutPrintf(idl_fileCur(), "%s\n\n", idl_dllGetHeader()); + } + /* return idl_explore to indicate that the rest of the file needs to be processed */ + return idl_explore; +} + +/* @brief callback function called on closing the IDL input file. + * + * Generate standard file footer consisting of: + * - mutiple inclusion prevention closure + */ +static void +idl_fileClose( + void *userData) +{ + OS_UNUSED_ARG(userData); + /* Generate closure of multiple inclusion prevention code */ + idl_fileOutPrintf(idl_fileCur(), "#undef OS_API\n"); + idl_fileOutPrintf(idl_fileCur(), "#endif\n"); +} + +/** @brief callback function called on module definition in the IDL input file. + * + * Generate code for the following IDL construct: + * @verbatim + => module { + + }; + @endverbatim + * + * This fuction generates the prototype of the function that + * is responsible for loading the metadata into the database. + * The name of the function is: + * @verbatim + ______load + @endverbatim + * For the Splice types, no further actions are required. + * + * @param scope Current scope (and scope of the module definition) + * @param name Name of the defined module + * @return Next action for this module (idl_explore) + */ +static idl_action +idl_moduleOpen( + idl_scope scope, + const char *name, + void *userData) +{ + c_char *baseName, *scopeStack; + + OS_UNUSED_ARG(userData); + + baseName = idl_scopeBasename(scope); + scopeStack = idl_scopeStack(scope, "_", name); + idl_fileOutPrintf(idl_fileCur(), "extern c_metaObject __%s_%s__load (c_base base);\n", baseName, scopeStack); + idl_fileOutPrintf(idl_fileCur(), "\n"); + + os_free(baseName); + os_free(scopeStack); + + /* return idl_explore to indicate that the rest of the module needs to be processed */ + return idl_explore; +} + +/** @brief callback function called on structure definition in the IDL input file. + * + * Generate code for the following IDL construct: + * @verbatim + => struct { + ; + ... ... + ; + }; + @endverbatim + * + * This function generates prototypes for the helper functions to + * load the structures metadata, to determine the structures keys + * and the scoped name of the struct if the struct is defined in + * the global scope or within a module. + * The name of the metadata load function is: + * @verbatim + _____load + @endverbatim + * The name of the key query function is: + * @verbatim + _____keys + @endverbatim + * The name of the name query function is: + * @verbatim + _____name + @endverbatim + * If the struct is defined within another struct or within a + * union, no key nor its name can be queried. Such a structure + * can not be communicated via Splice as a separate entity. + * IDL structs are mapped onto C structs for Splice, therefor + * a struct definition is opened: + * @verbatim + struct _ { + @endverbatim + * + * @param scope Current scope (and scope of the structure definition) + * @param name Name of the structure + * @param structSpec Specification of the struct holding the amount of members + * @return Next action for this structure (idl_explore) + */ +static idl_action +idl_structureOpen( + idl_scope scope, + const char *name, + idl_typeStruct structSpec, + void *userData) +{ + char *fullyScopedName = idl_scopeStack(scope, "_", name); + OS_UNUSED_ARG(structSpec); + OS_UNUSED_ARG(userData); + + if (idl_scopeStackSize(scope) == 0 || idl_scopeElementType (idl_scopeCur(scope)) == idl_tModule) { + idl_fileOutPrintf(idl_fileCur(), "extern const char *%s_metaDescriptor[];\n",fullyScopedName); + idl_fileOutPrintf(idl_fileCur(), "extern const c_ulong %s_metaDescriptorArrLength;\n",fullyScopedName); + idl_fileOutPrintf(idl_fileCur(), "extern const c_ulong %s_metaDescriptorLength;\n",fullyScopedName); + /* define the prototype of the function for metadata load */ + idl_fileOutPrintf(idl_fileCur(), "extern c_metaObject __%s__load (c_base base);\n",fullyScopedName); + if(!test_mode) + { + char *tmpfullyScopedName = idl_scopeStack(scope, "::", name); + + /* define the prototype of the function for performing copyIn/copyOut. This needs to be + * exported as well to ensure it can be access by other (ussually also OpenSplice + * generated) packages + */ + idl_fileOutPrintf( + idl_fileCur(), + "struct _%s ;\n", + fullyScopedName); + + idl_fileOutPrintf( + idl_fileCur(), + "extern %s v_copyin_result __%s__copyIn(c_type dbType, const class %s *from, struct _%s *to);\n", + idl_dllGetMacro(), + fullyScopedName, + tmpfullyScopedName, + fullyScopedName); + idl_fileOutPrintf( + idl_fileCur(), + "extern %s void __%s__copyOut(const void *_from, void *_to);\n", + idl_dllGetMacro(), + fullyScopedName); + os_free(tmpfullyScopedName); + } + + } + idl_printIndent(indent_level); + idl_fileOutPrintf( + idl_fileCur(), + "struct _%s {\n", + fullyScopedName); + indent_level++; + os_free(fullyScopedName); + /* return idl_explore to indicate that the rest of the structure needs to be processed */ + return idl_explore; +} + +/** @brief callback function called on end of a structure definition in the IDL input file. + * + * Generate code for the following IDL construct: + * @verbatim + struct { + + ... ... + + => }; + @endverbatim + * + * The structure is closed: + * @verbatim + }; + @endverbatim + * + * @param name Name of the structure (not used) + */ +static void +idl_structureClose ( + const char *name, + void *userData) +{ + OS_UNUSED_ARG(name); + OS_UNUSED_ARG(userData); + + indent_level--; + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "};\n\n"); +} + +/** @brief callback function called on definition of a structure member in the IDL input file. + * + * Generate code for the following IDL construct: + * @verbatim + struct { + => ; + => ... ... + => ; + }; + @endverbatim + * + * If the type specification is idl_tbasic a standard mapping can be generated: + * @verbatim + string ; => c_string ; + string ; => c_string ; + char ; => c_char ; + octet ; => c_octet ; + short ; => c_short ; + unsigned short ; => c_ushort ; + long ; => c_long ; + unsigned long ; => c_ulong ; + long long ; => c_longlong ; + unsigned long long ; => c_ulonglong ; + float ; => c_float ; + double ; => c_double ; + boolean ; => c_bool ; + @endverbatim + * If the type specification is a user defined idl_ttypedef, idl_tenum, + * idl_tstruct or idl_tunion a scoped name mapping will be generated. + * @verbatim + ; => enum _ ; + ; => enum _ ; + ; => struct _ ; + ; => struct _ ; + @endverbatim + * If the type specification is idl_tarray then generate a scoped name + * with the array specifiers: + * @verbatim + [n1]..[nn]; => _ [n1]..[nn]; + [n1]..[nn]; => [n1]..[nn]; + sequence [n1]..[nn]; => c_array [n1]..[nn]; + sequence [n1]..[nn]; => c_array [n1]..[nn]; + @endverbatim + * If the type specification is idl_tseq then generate a mapping on c_sequence: + * @verbatim + sequence ; => c_sequence ; + sequence ; => c_sequence ; + @endverbatim + * + * @param scope Current scope + * @param name Name of the structure member + * @param typeSpec Type specification of the structure member + */ +static void +idl_structureMemberOpenClose( + idl_scope scope, + const char *name, + idl_typeSpec typeSpec, + void *userData) +{ + c_char *cxxMemberName = idl_languageId(name); + + if (idl_typeSpecType(typeSpec) == idl_ttypedef|| + idl_typeSpecType(typeSpec) == idl_tenum || + idl_typeSpecType(typeSpec) == idl_tstruct || + idl_typeSpecType(typeSpec) == idl_tunion || + idl_typeSpecType(typeSpec) == idl_tbasic) { + os_boolean catsRequested = OS_FALSE; + os_boolean stacRequested = OS_FALSE; + idl_typeSpec baseTypeDereffered = NULL; + idl_typeSpec typeDereffered; + + /* is a stac pragma defined for this member? */ + stacRequested = idl_stacDef_isStacDefined(scope, name, typeSpec, &baseTypeDereffered); + if(!stacRequested) { + /* Cats and stac def can not be defined over the same member as + * one excepts string types and the other char (array) types + */ + catsRequested = idl_catsDef_isCatsDefined(scope, name, typeSpec); + } + + if(catsRequested) { + assert(!stacRequested); + typeDereffered = idl_typeDefResolveFully(typeSpec); + idl_structureMemberOpenClose(scope, name, typeDereffered, userData); + } else if(stacRequested) { + assert(baseTypeDereffered); + typeDereffered = idl_typeDefResolveFully(typeSpec); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "c_char %s", cxxMemberName); + /* potential array bounds */ + if((idl_typeSpecType(typeDereffered) == idl_tarray)) { + idl_arrayDimensions(idl_typeArray(typeDereffered), OS_TRUE); + } + idl_fileOutPrintf(idl_fileCur(), "[%u];\n", idl_typeBasicMaxlen(idl_typeBasic(baseTypeDereffered))+1); + } else { + c_char *dbTypeName = idl_scopedSplTypeIdent(typeSpec); + + /* generate code for a standard mapping or a typedef, enum, struct or union user-type mapping */ + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "%s %s;\n", dbTypeName, cxxMemberName); + os_free(dbTypeName); + } + } else if (idl_typeSpecType(typeSpec) == idl_tarray) { + /* generate code for an array mapping */ + os_boolean catsRequested = OS_FALSE; + os_boolean stacRequested = OS_FALSE; + idl_typeSpec baseTypeDereffered = NULL; + + /* is a stac pragma defined for this member? */ + stacRequested = idl_stacDef_isStacDefined(scope, name, typeSpec, &baseTypeDereffered); + if(!stacRequested) { + /* Cats and stac def can not be defined over the same member as + * one excepts string types and the other char (array) types + */ + catsRequested = idl_catsDef_isCatsDefined(scope, name, typeSpec); + } + if(catsRequested) { + assert(!stacRequested); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "c_string %s;\n", cxxMemberName); + } else if(stacRequested) { + assert(!catsRequested); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "c_char %s", cxxMemberName); + idl_arrayDimensions(idl_typeArray(typeSpec), OS_TRUE); + idl_fileOutPrintf(idl_fileCur(),"[%u]", idl_typeBasicMaxlen(idl_typeBasic(baseTypeDereffered))+1); + idl_fileOutPrintf(idl_fileCur(), ";\n"); + } else { + idl_printIndent(indent_level); + if (idl_typeSpecType(idl_typeArrayActual (idl_typeArray(typeSpec))) != idl_tseq) { + c_char *dbTypeName = idl_scopedSplTypeIdent(idl_typeArrayActual(idl_typeArray(typeSpec))); + + idl_fileOutPrintf( + idl_fileCur(), + "%s %s", + dbTypeName, + cxxMemberName); + os_free(dbTypeName); + } else { + idl_fileOutPrintf(idl_fileCur(), "c_array %s", cxxMemberName); + } + idl_arrayDimensions(idl_typeArray(typeSpec), OS_FALSE); + idl_fileOutPrintf(idl_fileCur(), ";\n"); + } + } else if (idl_typeSpecType(typeSpec) == idl_tseq) { + /* generate code for a sequence mapping */ + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "c_sequence %s;\n", cxxMemberName); + } else { + printf ("idl_structureMemberOpenClose: Unsupported structure member type (member name = %s, type name = %s)\n", + name, idl_scopedTypeName(typeSpec)); + } + + os_free(cxxMemberName); +} + +/** @brief callback function called on definition of a union in the IDL input file. + * + * Generate code for the following IDL construct: + * @verbatim + => union switch() { + case label1.1; .. case label1.n; + ; + case label2.1; .. case label2.n; + ... ... + case labeln.1; .. case labeln.n; + ; + default: + ; + }; + @endverbatim + * + * This function generates prototypes for the helper functions to + * load the unions metadata, to determine the unions keys and the + * scoped name of the union if the union is defined in the global + * scope or within a module. + * The name of the metadata load function is: + * @verbatim + _____load + @endverbatim + * The name of the key query function is: + * @verbatim + _____keys + @endverbatim + * The name of the name query function is: + * @verbatim + _____name + @endverbatim + * If the union is defined within another union or within a + * struct, no key nor its name can be queried. Such a union + * can not be communicated via Splice as a separate entity. + * IDL unions are mapped onto C structs for Splice in the + * following manner: + * @verbatim + struct { + _d; + union { + ; + ... ... + ; + } _u; + }; + @endverbatim + * The union definition is opened: + * @verbatim + struct _ { + @endverbatim + * Then depending on the type of the switch (integral type is required) any of the following: + * @verbatim + enum _d; // for an enumeration + _ _d; // for an typedeffed enum or basic type + _d; // for an integral basic type + @endverbatim + * Then open the union part: + * @verbatim + union { + @endverbatim + * + * @param scope Current scope + * @param name Name of the union + * @param unionSpec Specifies the number of union cases and the union switch type + * @return Next action for this union (idl_explore) + */ +static idl_action +idl_unionOpen( + idl_scope scope, + const char *name, + idl_typeUnion unionSpec, + void *userData) +{ + char *fullyScopedName = idl_scopeStack(scope, "_", name); + OS_UNUSED_ARG(userData); + + if (idl_scopeStackSize(scope) == 0 || idl_scopeElementType (idl_scopeCur(scope)) == idl_tModule) { + idl_fileOutPrintf(idl_fileCur(), "extern const char *%s_metaDescriptor[];\n",fullyScopedName); + idl_fileOutPrintf(idl_fileCur(), "extern const c_ulong %s_metaDescriptorArrLength;\n",fullyScopedName); + idl_fileOutPrintf(idl_fileCur(), "extern const c_ulong %s_metaDescriptorLength;\n",fullyScopedName); + /* define the prototype of the function for metadata load */ + idl_fileOutPrintf(idl_fileCur(), "extern c_metaObject __%s__load (c_base base);\n", fullyScopedName); + /* define the prototype of the function for querying the keys */ + idl_fileOutPrintf(idl_fileCur(), "extern const char * __%s__keys (void);\n", fullyScopedName); + /* define the prototype of the function for querying scoped union name */ + idl_fileOutPrintf(idl_fileCur(), "extern const char * __%s__name (void);\n", fullyScopedName); + } + /* open the struct */ + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "struct _%s {\n", fullyScopedName); + indent_level++; + /* generate code for the switch */ + if (idl_typeSpecType(idl_typeUnionSwitchKind(unionSpec)) == idl_tbasic) { + os_free(fullyScopedName); + fullyScopedName = idl_scopedTypeName(idl_typeUnionSwitchKind(unionSpec)); + idl_printIndent(indent_level); + idl_fileOutPrintf (idl_fileCur(), "%s _d;\n", fullyScopedName); + } else if (idl_typeSpecType(idl_typeUnionSwitchKind(unionSpec)) == idl_tenum) { + os_free(fullyScopedName); + fullyScopedName = idl_scopedSplTypeName(idl_typeUnionSwitchKind(unionSpec)); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "%s _d;\n", fullyScopedName); + } else if (idl_typeSpecType(idl_typeUnionSwitchKind(unionSpec)) == idl_ttypedef) { + switch (idl_typeSpecType(idl_typeDefActual(idl_typeDef(idl_typeUnionSwitchKind(unionSpec))))) { + case idl_tbasic: + case idl_tenum: + os_free(fullyScopedName); + fullyScopedName = idl_scopedSplTypeName(idl_typeUnionSwitchKind(unionSpec)); + idl_printIndent(indent_level); idl_fileOutPrintf (idl_fileCur(), "%s _d;\n", fullyScopedName); + break; + default: + printf ("idl_unionOpen: Unsupported switchkind\n"); + } + } else { + printf ("idl_unionOpen: Unsupported switchkind\n"); + } + /* open the union */ + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "union {\n"); + indent_level++; + os_free(fullyScopedName); + + /* return idl_explore to indicate that the rest of the union needs to be processed */ + return idl_explore; +} + +/** @brief callback function called on closure of a union in the IDL input file. + * + * Generate code for the following IDL construct: + * @verbatim + union switch() { + case label1.1; .. case label1.n; + ; + case label2.1; .. case label2.n; + ... ... + case labeln.1; .. case labeln.n; + ; + default: + ; + => }; + @endverbatim + * + * The union is closed: + * @verbatim + } _u; + }; + @endverbatim + * @param name Name of the union + */ +static void +idl_unionClose ( + const char *name, + void *userData) +{ + OS_UNUSED_ARG(name); + OS_UNUSED_ARG(userData); + + indent_level--; + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "} _u;\n"); + indent_level--; + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "};\n\n"); +} + +/** @brief callback function called on definition of a union case in the IDL input file. + * + * Generate code for the following IDL construct: + * @verbatim + union switch() { + case label1.1; .. case label1.n; + => ; + case label2.1; .. case label2.n; + => ... ... + case labeln.1; .. case labeln.n; + => ; + default: + => ; + }; + @endverbatim + * + * If the type specification is idl_tbasic a standard mapping can be generated: + * @verbatim + string ; => c_string ; + string ; => c_string ; + char ; => c_char ; + octet ; => c_octet ; + short ; => c_short ; + unsigned short ; => c_ushort ; + long ; => c_long ; + unsigned long ; => c_ulong ; + long long ; => c_longlong ; + unsigned long long ; => c_ulonglong ; + float ; => c_float ; + double ; => c_double ; + boolean ; => c_bool ; + @endverbatim + * If the type specification is a user defined idl_ttypedef, idl_tenum, + * idl_tstruct or idl_tunion a scoped name mapping will be generated. + * @verbatim + ; => enum _ ; + ; => enum _ ; + ; => struct _ ; + ; => struct _ ; + @endverbatim + * If the type specification is idl_tarray then generate a scoped name + * with the array specifiers: + * @verbatim + [n1]..[nn]; => _ [n1]..[nn]; + [n1]..[nn]; => [n1]..[nn]; + sequence [n1]..[nn]; => c_array [n1]..[nn]; + sequence [n1]..[nn]; => c_array [n1]..[nn]; + @endverbatim + * If the type specification is idl_tseq then generate a mapping on c_sequence: + * @verbatim + sequence ; => c_sequence ; + sequence ; => c_sequence ; + @endverbatim + * + * @param scope Current scope (the union the union case is defined in) + * @param name Name of the union case + * @param typeSpec Specifies the type of the union case + */ +static void +idl_unionCaseOpenClose( + idl_scope scope, + const char *name, + idl_typeSpec typeSpec, + void *userData) +{ + c_char *cxxMemberName = idl_languageId(name); + + OS_UNUSED_ARG(scope); + OS_UNUSED_ARG(userData); + + if (idl_typeSpecType(typeSpec) == idl_ttypedef || + idl_typeSpecType(typeSpec) == idl_tenum || + idl_typeSpecType(typeSpec) == idl_tstruct || + idl_typeSpecType(typeSpec) == idl_tunion || + idl_typeSpecType(typeSpec) == idl_tbasic) { + /* generate code for a standard mapping or a typedef, enum, struct or union user-type mapping */ + c_char *dbTypeName = idl_scopedSplTypeIdent(typeSpec); + + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "%s %s;\n", dbTypeName, cxxMemberName); + os_free(dbTypeName); + } else if (idl_typeSpecType(typeSpec) == idl_tarray) { + /* generate code for an array mapping */ + idl_printIndent(indent_level); + if (idl_typeSpecType(idl_typeArrayActual (idl_typeArray(typeSpec))) != idl_tseq) { + c_char *dbTypeName = idl_scopedSplTypeIdent(idl_typeArrayActual (idl_typeArray(typeSpec))); + idl_fileOutPrintf(idl_fileCur(), "%s %s", dbTypeName, cxxMemberName); + os_free(dbTypeName); + } else { + idl_fileOutPrintf(idl_fileCur(), "c_array %s", cxxMemberName); + } + idl_arrayDimensions(idl_typeArray(typeSpec), OS_FALSE); + idl_fileOutPrintf(idl_fileCur(), ";\n"); + } else if (idl_typeSpecType(typeSpec) == idl_tseq) { + /* generate code for a sequence mapping */ + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "c_sequence %s;\n", cxxMemberName); + } else { + printf("idl_unionCaseOpenClose: Unsupported union case type (case name = %s, type = %s)\n", + name, idl_scopedTypeName(typeSpec)); + } + os_free(cxxMemberName); +} + +/** @brief callback function called on definition of an enumeration. + * + * Generate code for the following IDL construct: + * @verbatim + => enum { + ; + ... ... + ; + }; + @endverbatim + * + * This function generates a prototype for the helper function to + * load the enumerations metadata if the enumeration is defined + * within the global scope or the scope of a module. + * The name of the metadata load function is: + * @verbatim + _____load + @endverbatim + * The enum definition is opened: + * @verbatim + enum _ { + @endverbatim + * @param scope Current scope + * @param name Name of the enumeration + * @param enumSpec Specifies the number of elements in the enumeration + * @return Next action for this enumeration (idl_explore) + */ +static idl_action +idl_enumerationOpen( + idl_scope scope, + const char *name, + idl_typeEnum enumSpec, + void *userData) +{ + c_char *scopeStack = idl_scopeStack(scope, "_", name); + + OS_UNUSED_ARG(userData); + + if (idl_scopeStackSize(scope) == 0 || idl_scopeElementType (idl_scopeCur(scope)) == idl_tModule) { + idl_fileOutPrintf(idl_fileCur(), "extern c_metaObject __%s__load (c_base base);\n", scopeStack); + } + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "enum _%s {\n", scopeStack); + os_free(scopeStack); + enum_element = idl_typeEnumNoElements(enumSpec); + indent_level++; + + /* return idl_explore to indicate that the rest of the enumeration needs to be processed */ + return idl_explore; +} + +/** @brief callback function called on closure of an enumeration in the IDL input file. + * + * Generate code for the following IDL construct: + * @verbatim + enum { + ; + ... ... + ; + => }; + @endverbatim + * + * The enumeration is closed: + * @verbatim + }; + @endverbatim + * + * @param name Name of the enumeration + */ +static void +idl_enumerationClose( + const char *name, + void *userData) +{ + OS_UNUSED_ARG(name); + OS_UNUSED_ARG(userData); + + indent_level--; + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "};\n\n"); +} + +/** @brief callback function called on definition of an enumeration element in the IDL input file. + * + * Generate code for the following IDL construct: + * @verbatim + enum { + => , + => ... ... + => + }; + @endverbatim + * + * For the last element generate: + * @verbatim + + @endverbatim + * For any but the last element generate: + * @verbatim + , + @endverbatim + * + * @param scope Current scope + * @param name Name of the enumeration element + */ +static void +idl_enumerationElementOpenClose( + idl_scope scope, + const char *name, + void *userData) +{ + c_char *scopeStack = idl_scopeStack(scope, "_", name); + + OS_UNUSED_ARG(userData); + + enum_element--; + if (enum_element == 0) { + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "_%s\n", scopeStack); + } else { + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "_%s,\n", scopeStack); + } + os_free(scopeStack); +} + +/* @brief generate dimension of an array + * + * arrayDimensions is a local support function to generate + * the array dimensions of an array + * + * @param typeArray Specifies the type of the array + */ +static void +idl_arrayDimensions ( + idl_typeArray typeArray, + os_boolean resolveTypedefs) +{ + idl_typeSpec subType; + + idl_fileOutPrintf(idl_fileCur(), "[%d]", idl_typeArraySize(typeArray)); + subType = idl_typeArrayType(typeArray); + while(resolveTypedefs && idl_typeSpecType(subType) == idl_ttypedef) + { + subType = idl_typeDefResolveFully(subType); + } + if (idl_typeSpecType(subType) == idl_tarray) { + idl_arrayDimensions (idl_typeArray(subType), resolveTypedefs); + } +} + +/** @brief callback function called on definition of a named type in the IDL input file. + * + * Generate code for the following IDL construct: + * @verbatim + => typedef ; + @endverbatim + * + * This function generates a prototype for the helper function to + * load the typedef metadata if the typedef is defined + * within the global scope or the scope of a module. + * The name of the metadata load function is: + * @verbatim + _____load + @endverbatim + * If the type specification is idl_tbasic a standard mapping will be applied: + * @verbatim + typedef _; + @endverbatim + * If the type specification is a user defined idl_ttypedef, idl_tenum, + * idl_tstruct or idl_tunion a scoped name mapping will be generated. + * @verbatim + ; => typedef enum _ _; + ; => typedef enum _ _; + ; => typedef struct _ _; + ; => typedef struct _ _; + @endverbatim + * If the type specification is idl_tarray then generate a scoped name + * with the array specifiers: + * @verbatim + [n1]..[nn]; => + typedef _ _[n1]..[nn]; + [n1]..[nn]; => + typedef _[n1]..[nn]; + sequence [n1]..[nn]; => + typedef c_array _[n1]..[nn]; + sequence [n1]..[nn]; => + typedef c_array _[n1]..[nn]; + @endverbatim + * If the type specification is idl_tseq then generate a mapping on c_sequence: + * @verbatim + sequence ; => typedef c_sequence _; + sequence ; => typedef c_sequence _; + @endverbatim + * + * @param scope Current scope + * @param name Specifies the name of the type + * @param defSpec Specifies the type of the named type + */ +static void +idl_typedefOpenClose( + idl_scope scope, + const char *name, + idl_typeDef defSpec, + void *userData) +{ + c_char *scopeStack = idl_scopeStack(scope, "_", name); + + OS_UNUSED_ARG(userData); + + if (idl_scopeStackSize(scope) == 0 || idl_scopeElementType (idl_scopeCur(scope)) == idl_tModule) { + idl_fileOutPrintf(idl_fileCur(), "extern c_metaObject __%s__load (c_base base);\n", scopeStack); + if (idl_typeSpecType(idl_typeDefActual(defSpec)) == idl_tstruct || + idl_typeSpecType(idl_typeDefActual(defSpec)) == idl_tunion) { + /* If this is a typedef of a struct or union */ + /* define the prototype of the function for querying the keys */ + idl_fileOutPrintf(idl_fileCur(), "extern const char * __%s__keys (void);\n", scopeStack); + /* define the prototype of the function for querying scoped structure name */ + idl_fileOutPrintf(idl_fileCur(), "extern const char * __%s__name (void);\n", scopeStack); + } + } + if (idl_typeSpecType(idl_typeSpec(idl_typeDefRefered(defSpec))) == idl_ttypedef || + idl_typeSpecType(idl_typeSpec(idl_typeDefRefered(defSpec))) == idl_tenum || + idl_typeSpecType(idl_typeSpec(idl_typeDefRefered(defSpec))) == idl_tstruct || + idl_typeSpecType(idl_typeSpec(idl_typeDefRefered(defSpec))) == idl_tunion || + idl_typeSpecType(idl_typeSpec(idl_typeDefRefered(defSpec))) == idl_tbasic) { + c_char *dbTypeName = idl_scopedSplTypeIdent(idl_typeSpec(idl_typeDefRefered(defSpec))); + + /* generate code for a standard mapping or a typedef, enum, struct or union user-type mapping */ + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "typedef %s _%s;\n\n", dbTypeName, scopeStack); + os_free(dbTypeName); + } else if (idl_typeSpecType(idl_typeSpec(idl_typeDefRefered(defSpec))) == idl_tarray) { + c_char *dbTypeName = idl_scopedSplTypeIdent(idl_typeArrayActual (idl_typeArray(idl_typeDefRefered(defSpec)))); + + /* generate code for an array mapping */ + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "typedef %s _%s", dbTypeName, scopeStack); + idl_arrayDimensions(idl_typeArray(idl_typeDefRefered(defSpec)), OS_FALSE); + idl_fileOutPrintf(idl_fileCur(), ";\n\n"); + os_free(dbTypeName); + } else if (idl_typeSpecType(idl_typeSpec(idl_typeDefRefered(defSpec))) == idl_tseq) { + /* generate code for a sequence mapping */ + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "typedef c_sequence _%s;\n\n", scopeStack); + } else { + printf("idl_typedefOpenClose: Unsupported typedef type (typename = %s, type = %s)\n", + name, idl_scopedTypeName(idl_typeSpec(defSpec))); + } + os_free(scopeStack); +} + +/** + * Standard control structure to specify that inline + * type definitions are to be processed prior to the + * type itself in contrast with inline. +*/ +static idl_programControl idl_genSpliceLoadControl = { + idl_prior +}; + +/** @brief return the program control structure for the splice type generation functions. + * + * @return The program control structure for the splice type generation functions + */ +static idl_programControl * +idl_getControl( + void *userData) +{ + OS_UNUSED_ARG(userData); + return &idl_genSpliceLoadControl; +} + +/** + * Specifies the callback table for the splice type generation functions. + */ +static struct idl_program +idl_genISOCxx2SpliceType = { + idl_getControl, + idl_fileOpen, + idl_fileClose, + idl_moduleOpen, + NULL, /* idl_moduleClose */ + idl_structureOpen, + idl_structureClose, + idl_structureMemberOpenClose, + idl_enumerationOpen, + idl_enumerationClose, + idl_enumerationElementOpenClose, + idl_unionOpen, + idl_unionClose, + idl_unionCaseOpenClose, + NULL, /* idl_unionLabelsOpenClose */ + NULL, /* idl_unionLabelOpenClose */ + idl_typedefOpenClose, + NULL, /* idl_boundedStringOpenClose */ + NULL, /* idl_sequenceOpenClose */ + NULL, /* idl_constantOpenClose */ + NULL, /* idl_artificialDefaultLabelOpenClose */ + NULL /* userData */ +}; + +/** @brief return the callback table for the splice type generation functions. + * + * @return The callback table for the splice type generation functions + */ +idl_program +idl_genISOCxx2SpliceTypeProgram( + void) +{ + return &idl_genISOCxx2SpliceType; +} diff --git a/src/tools/idlpp/code/idl_genISOCxx2SpliceType.h b/src/tools/idlpp/code/idl_genISOCxx2SpliceType.h new file mode 100644 index 000000000..a09c9f426 --- /dev/null +++ b/src/tools/idlpp/code/idl_genISOCxx2SpliceType.h @@ -0,0 +1,23 @@ +/* + * OpenSplice DDS + * + * This software and documentation are Copyright 2006 to 2015 PrismTech + * Limited and its licensees. All rights reserved. See file: + * + * $OSPL_HOME/LICENSE + * + * for full copyright notice and license terms. + * + */ +#ifndef IDL_ISOCXX2GENSPLICETYPE_H +#define IDL_ISOCXX2GENSPLICETYPE_H + +#include "idl_program.h" + +idl_program idl_genISOCxx2SpliceTypeProgram (void); + +void +idl_genISOCxx2SpliceTypeSetTestMode ( + c_bool val); + +#endif /* IDL_GENSPLICETYPE_H */ diff --git a/src/tools/idlpp/code/idl_genISOCxx2Type.c b/src/tools/idlpp/code/idl_genISOCxx2Type.c index a5c120728..f1a6b677b 100644 --- a/src/tools/idlpp/code/idl_genISOCxx2Type.c +++ b/src/tools/idlpp/code/idl_genISOCxx2Type.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -56,7 +57,13 @@ static char *upperName = NULL; */ static struct idl_program idl_genCxx2Type; -/* @brief callback function called on opening the IDL input file. +struct ISOCxx2ScopeStack_s { + c_type type; + c_bool unionHasArtificialDefault; +}; +typedef struct ISOCxx2ScopeStack_s ISOCxx2ScopeStack; + +/** @brief callback function called on opening the IDL input file. * * Generate standard file header consisting of: * - inclusion of Splice type definition files @@ -82,7 +89,7 @@ idl_fileOpen( upperName[i] = (os_char) toupper (name[i]); } upperName[i] = '\0'; - /* Generate inclusion of standard OpenSplice DDS type definition files */ + /* Generate inclusion of standard Vortex OpenSplice type definition files */ idl_fileOutPrintf(idl_fileCur(), "#ifndef _%s_H_\n", upperName); idl_fileOutPrintf(idl_fileCur(), "#define _%s_H_\n", upperName); idl_fileOutPrintf(idl_fileCur(), "\n"); @@ -469,9 +476,14 @@ idl_structureOpen( { c_char *cxxName; CxxTypeUserData *cxxUserData = (CxxTypeUserData *)userData; + ISOCxx2ScopeStack *scopeStack; OS_UNUSED_ARG(scope); + scopeStack = os_malloc(sizeof(ISOCxx2ScopeStack)); + scopeStack->type = idl_typeSpecDef(idl_typeSpec(structSpec)); + scopeStack->unionHasArtificialDefault = FALSE; + /* Generate the code that opens a sealed class. */ cxxName = idl_ISOCxx2Id(name); idl_printIndent(indent_level); @@ -487,7 +499,7 @@ idl_structureOpen( /* Increase the indentation level. */ indent_level++; - cxxUserData->typeStack = c_iterInsert(cxxUserData->typeStack, idl_typeSpecDef(idl_typeSpec(structSpec))); + cxxUserData->typeStack = c_iterInsert(cxxUserData->typeStack, scopeStack); os_free(cxxName); @@ -524,7 +536,8 @@ idl_structureClose ( c_ulong i; /* Get the meta-data of the members of this datatype from the database. */ - smd.structType = c_type(c_iterTakeFirst(cxxUserData->typeStack)); + ISOCxx2ScopeStack *scopeStack = c_iterTakeFirst(cxxUserData->typeStack); + smd.structType = scopeStack->type; smd.nrMembers = c_structureMemberCount((c_structure) smd.structType); smd.memberTypes = os_malloc(smd.nrMembers * sizeof(*smd.memberTypes)); smd.memberTypeNames = os_malloc(smd.nrMembers * sizeof(*smd.memberTypeNames)); @@ -562,6 +575,7 @@ idl_structureClose ( os_free(smd.memberInTypes); os_free(smd.memberTypeNames); os_free(smd.memberTypes); + os_free(scopeStack); os_free(cxxName); /* Decrease the indentation level back to its original size. */ @@ -589,6 +603,7 @@ typedef struct { c_char **branchNames; struct unionCaseLabels *branchLabels; c_value lowestDefaultValue; + c_bool hasArtificialDefault; } unionMetaDescriptions; static void @@ -698,6 +713,15 @@ createUnionBranchAssignmentFunction(const c_char *name, const unionMetaDescripti idl_printIndent(indent_level); idl_fileOutPrintf(idl_fileCur(), "break;\n"); } + if (umd->hasArtificialDefault) { + idl_printIndent(indent_level - 1); + idl_fileOutPrintf(idl_fileCur(), "default:\n"); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "// empty branch: nothing to be copied...\n"); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "break;\n"); + } + indent_level--; idl_printIndent(indent_level); idl_fileOutPrintf(idl_fileCur(), "}\n"); @@ -748,6 +772,14 @@ createUnionBranchDestructor(const unionMetaDescriptions *umd) idl_printIndent(indent_level); idl_fileOutPrintf(idl_fileCur(), "break;\n"); } + if (umd->hasArtificialDefault) { + idl_printIndent(indent_level - 1); + idl_fileOutPrintf(idl_fileCur(), "default:\n"); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "// empty branch: nothing to be deleted...\n"); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "break;\n"); + } indent_level--; idl_printIndent(indent_level); idl_fileOutPrintf(idl_fileCur(), "}\n"); @@ -904,23 +936,24 @@ createUnionConstructorsAndOperators(const c_char *name, const unionMetaDescripti idl_fileOutPrintf(idl_fileCur(), "if (m__d != _other.m__d) {\n"); idl_printIndent(indent_level + 1); idl_fileOutPrintf(idl_fileCur(), "return false;\n"); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "} else {\n"); + indent_level++; + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "switch (m__d) {\n"); + indent_level++; for (i = 0; i < umd->nrBranches; i++) { - idl_printIndent(indent_level); - idl_fileOutPrintf(idl_fileCur(), "} else "); for (j = 0; j < umd->branchLabels[i].nrLabels; j++) { os_char *labelValue = idl_ISOCxx2ValueFromCValue( umd->discrType, umd->branchLabels[i].labelValues[j]); - if (j == 0) { - idl_fileOutPrintf(idl_fileCur(), "if (m__d == %s", labelValue); - } else { - idl_fileOutPrintf(idl_fileCur(), " ||\n"); - idl_printIndent(indent_level + 2); - idl_fileOutPrintf(idl_fileCur(), "m__d == %s", labelValue); - } + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "case %s:\n", labelValue); os_free(labelValue); } - if (umd->branchLabels[i].nrLabels > 0) idl_fileOutPrintf(idl_fileCur(), ") "); - idl_fileOutPrintf(idl_fileCur(), "{\n"); + if (j == 0) { + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "default: /* In case of explicit default branch. */\n"); + } idl_printIndent(indent_level + 1); if (idl_ISOCxx2IsRefType(umd->branchTypes[i])) { idl_fileOutPrintf(idl_fileCur(), "return (*_union.m_%s == *_other._union.m_%s);\n", @@ -929,15 +962,25 @@ createUnionConstructorsAndOperators(const c_char *name, const unionMetaDescripti idl_fileOutPrintf(idl_fileCur(), "return (_union.m_%s == _other._union.m_%s);\n", umd->branchNames[i], umd->branchNames[i]); } + idl_printIndent(indent_level + 1); + idl_fileOutPrintf(idl_fileCur(), "break;\n"); } - idl_printIndent(indent_level); - idl_fileOutPrintf(idl_fileCur(), "}\n"); - if (j > 0) { + if (umd->hasArtificialDefault) { idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "default: /* In case of implicit default branch. */\n"); + idl_printIndent(indent_level + 1); idl_fileOutPrintf(idl_fileCur(), "return true; /* In case of implicit default branch. */\n"); + idl_printIndent(indent_level + 1); + idl_fileOutPrintf(idl_fileCur(), "break;\n"); } indent_level--; idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "}\n"); + indent_level--; + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "}\n"); + indent_level--; + idl_printIndent(indent_level); idl_fileOutPrintf(idl_fileCur(), "} else {\n"); idl_printIndent(indent_level + 1); idl_fileOutPrintf(idl_fileCur(), "return true;\n"); @@ -1011,11 +1054,11 @@ createUnionDiscrGetterSetter(const unionMetaDescriptions *umd) umd->discrType, umd->branchLabels[i].labelValues[j]); if (j == 0) { idl_printIndent(indent_level); - idl_fileOutPrintf(idl_fileCur(), " if ((m__d != %s)", labelValue); + idl_fileOutPrintf(idl_fileCur(), " if (m__d != %s", labelValue); } else { idl_fileOutPrintf(idl_fileCur(), " &&\n"); idl_printIndent(indent_level ); - idl_fileOutPrintf(idl_fileCur(), " (m__d != %s)", labelValue); + idl_fileOutPrintf(idl_fileCur(), " m__d != %s", labelValue); } os_free(labelValue); } @@ -1049,12 +1092,12 @@ createUnionDiscrGetterSetter(const unionMetaDescriptions *umd) umd->discrType, umd->branchLabels[i].labelValues[j]); if (n == 0) { idl_printIndent(indent_level); - idl_fileOutPrintf(idl_fileCur(), " if ((m__d == %s)", labelValue); + idl_fileOutPrintf(idl_fileCur(), " if (m__d == %s", labelValue); n = 1; } else { idl_fileOutPrintf(idl_fileCur(), " ||\n"); idl_printIndent(indent_level ); - idl_fileOutPrintf(idl_fileCur(), " (m__d == %s)", labelValue); + idl_fileOutPrintf(idl_fileCur(), " m__d == %s", labelValue); } os_free(labelValue); } @@ -1285,9 +1328,18 @@ idl_unionOpen( { c_char *cxxName; CxxTypeUserData *cxxUserData = (CxxTypeUserData *)userData; + ISOCxx2ScopeStack *scopeStack; OS_UNUSED_ARG(scope); + /* Set expectation of implicit default branch to FALSE. + * idl_artificialDefaultLabelOpenClose will set it to TRUE when encountered. + */ + scopeStack = os_malloc(sizeof(ISOCxx2ScopeStack)); + scopeStack->type = idl_typeSpecDef(idl_typeSpec(unionSpec)); + scopeStack->unionHasArtificialDefault = FALSE; + + /* Generate the code that opens a sealed class. */ cxxName = idl_ISOCxx2Id(name); idl_printIndent(indent_level); @@ -1303,14 +1355,50 @@ idl_unionOpen( /* Increase the indentation level. */ indent_level++; - - cxxUserData->typeStack = c_iterInsert(cxxUserData->typeStack, idl_typeSpecDef(idl_typeSpec(unionSpec))); - + cxxUserData->typeStack = c_iterInsert(cxxUserData->typeStack, scopeStack); os_free(cxxName); return idl_explore; } +/** @brief callback function called when no default case is defined in an union + * for which not all possible label values are specified + * + * Generate code for the following IDL construct: + * @verbatim + union switch() { + case label1.1; .. case label1.n; + ; + case label2.1; .. case label2.n; + ... ... + case labeln.1; .. case labeln.n; + ; + }; + @endverbatim + * + * @param scope Current scope (the union the union case is defined in) + * @param labelVal Default value for the label case (lowest possible not used index) + * @param typeSpec Specifies the type of the union switch + */ +static void +idl_artificialDefaultLabelOpenClose( + idl_scope scope, + idl_labelVal labelVal, + idl_typeSpec typeSpec, + void *userData) +{ + CxxTypeUserData *cxxUserData; + ISOCxx2ScopeStack *scopeStack; + + OS_UNUSED_ARG(scope); + OS_UNUSED_ARG(labelVal); + OS_UNUSED_ARG(typeSpec); + + cxxUserData = (CxxTypeUserData *)userData; + scopeStack = (ISOCxx2ScopeStack *) c_iterObject(cxxUserData->typeStack, 0); + scopeStack->unionHasArtificialDefault = TRUE; +} + /** @brief callback function called on closure of a union in the IDL input file. * * Generate code for the following IDL construct: @@ -1345,7 +1433,8 @@ idl_unionClose ( c_ulong i, j, nrLabels; /* Get the meta-data of the members of this union from the database. */ - umd.unionType = c_type(c_iterTakeFirst(cxxUserData->typeStack)); + ISOCxx2ScopeStack *scopeStack = c_iterTakeFirst(cxxUserData->typeStack); + umd.unionType = scopeStack->type; umd.nrBranches = c_unionUnionCaseCount(umd.unionType); umd.discrType = c_unionUnionSwitchType(umd.unionType); umd.discrTypeName = idl_ISOCxx2TypeFromCType(umd.discrType); @@ -1356,6 +1445,7 @@ idl_unionClose ( umd.branchNames = os_malloc(umd.nrBranches * sizeof(*umd.branchNames)); umd.branchLabels = os_malloc(umd.nrBranches * sizeof(*umd.branchLabels)); umd.lowestDefaultValue = idl_ISOCxx2LowestUnionDefaultValue(umd.unionType); + umd.hasArtificialDefault = scopeStack->unionHasArtificialDefault; for (i = 0; i < umd.nrBranches; i++) { /* Get the meta-data of the branches from the database. */ c_unionCase branch = c_unionUnionCase(umd.unionType, i); @@ -1413,6 +1503,7 @@ idl_unionClose ( os_free(umd.branchInTypes); os_free(umd.branchTypeNames); os_free(umd.branchTypes); + os_free(scopeStack); os_free(cxxName); indent_level--; @@ -1641,7 +1732,7 @@ idl_genISOCxx2TypeProgram( idl_genCxx2Type.boundedStringOpenClose = NULL; idl_genCxx2Type.sequenceOpenClose = NULL; idl_genCxx2Type.constantOpenClose = idl_constantOpenClose; - idl_genCxx2Type.artificialDefaultLabelOpenClose = NULL; + idl_genCxx2Type.artificialDefaultLabelOpenClose = idl_artificialDefaultLabelOpenClose; idl_genCxx2Type.userData = userData; return &idl_genCxx2Type; diff --git a/src/tools/idlpp/code/idl_genISOCxx2Type.h b/src/tools/idlpp/code/idl_genISOCxx2Type.h index 03baca377..6ea5e87bf 100644 --- a/src/tools/idlpp/code/idl_genISOCxx2Type.h +++ b/src/tools/idlpp/code/idl_genISOCxx2Type.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/idlpp/code/idl_genISOCxxHeader.c b/src/tools/idlpp/code/idl_genISOCxxHeader.c index 46d585eef..dfdd10cc7 100644 --- a/src/tools/idlpp/code/idl_genISOCxxHeader.c +++ b/src/tools/idlpp/code/idl_genISOCxxHeader.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/idlpp/code/idl_genISOCxxHeader.h b/src/tools/idlpp/code/idl_genISOCxxHeader.h index 2bc1d8e53..d89957bd1 100644 --- a/src/tools/idlpp/code/idl_genISOCxxHeader.h +++ b/src/tools/idlpp/code/idl_genISOCxxHeader.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/idlpp/code/idl_genIdl.c b/src/tools/idlpp/code/idl_genIdl.c index 7474e1a65..5a7a34ea2 100644 --- a/src/tools/idlpp/code/idl_genIdl.c +++ b/src/tools/idlpp/code/idl_genIdl.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -53,7 +54,7 @@ idl_fileOpen( c_char *tmplPath; c_char *idlPath; int tmplFile; - struct os_stat tmplStat; + struct os_stat_s tmplStat; unsigned int nRead; OS_UNUSED_ARG(scope); OS_UNUSED_ARG(userData); diff --git a/src/tools/idlpp/code/idl_genIdl.h b/src/tools/idlpp/code/idl_genIdl.h index f7b4e34f1..9b724d470 100644 --- a/src/tools/idlpp/code/idl_genIdl.h +++ b/src/tools/idlpp/code/idl_genIdl.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/idlpp/code/idl_genIdlHelper.c b/src/tools/idlpp/code/idl_genIdlHelper.c index 842263a95..36b7ab40a 100644 --- a/src/tools/idlpp/code/idl_genIdlHelper.c +++ b/src/tools/idlpp/code/idl_genIdlHelper.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -78,7 +79,7 @@ idl_structureOpen( if (idl_keyResolve(idl_keyDefDefGet(), scope, name) != NULL) { /* keylist defined for this struct */ - + /* Add this key to the list for this idl file */ idl_idlScopeKeyList = os_iterAppend(idl_idlScopeKeyList, idl_scopeDup(scope)); } diff --git a/src/tools/idlpp/code/idl_genIdlHelper.h b/src/tools/idlpp/code/idl_genIdlHelper.h index 0528cd3aa..091e302a0 100644 --- a/src/tools/idlpp/code/idl_genIdlHelper.h +++ b/src/tools/idlpp/code/idl_genIdlHelper.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/idlpp/code/idl_genJavaHelper.c b/src/tools/idlpp/code/idl_genJavaHelper.c index 004b01f62..311e58f95 100644 --- a/src/tools/idlpp/code/idl_genJavaHelper.c +++ b/src/tools/idlpp/code/idl_genJavaHelper.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,12 +24,15 @@ #include "idl_tmplExp.h" #include "idl_typeSpecifier.h" +#include "os_abstract.h" #include "os_iterator.h" #include "os_heap.h" #include "os_stdlib.h" #include "os_string.h" #include "os_errno.h" +#include "c_base.h" + static os_equality idl_genJavaHelperComparePackageRedirect (const void *obj1, const void *obj2); os_iter idl_genJavaHelperPackageRedirects = NULL; @@ -51,9 +55,9 @@ static const char *java_keywords[61] = { }; /* Translate an IDL identifier into a Java language identifier. - The IDL specification states that all identifiers that match - a Java keyword must be prepended by "_". -*/ + * The IDL specification states that all identifiers that match + * a Java keyword must be prepended by "_". + */ c_char * idl_javaId( const char *identifier) @@ -120,9 +124,9 @@ idl_scopeJavaElementName ( } /* Build a textual presentation of the provided scope stack taking the - Java keyword identifier translation into account. Further the function - equals "idl_scopeStack". -*/ + * Java keyword identifier translation into account. Further the function + * equals "idl_scopeStack". + */ c_char * idl_scopeStackJava ( idl_scope scope, @@ -147,7 +151,8 @@ idl_scopeStackJava ( /* Translate the scope name to a C identifier */ Id = idl_javaId(idl_scopeJavaElementName(idl_scopeIndexed(scope, si))); /* allocate space for the current scope stack + the separator - and the next scope name */ + *and the next scope name + */ /* QAC EXPECT 5007; will not use wrapper */ slen = strlen (scopeStack) + strlen (scopeSepp) + strlen (Id); scopeStack = os_realloc(scopeStack, slen + 1); @@ -214,7 +219,8 @@ idl_scopeStackJava ( /* Translate the user identifier to a Java identifier */ Id = idl_javaId(name); /* allocate space for the current scope stack + the separator - and the user identifier */ + * and the user identifier + */ /* QAC EXPECT 5007; will not use wrapper */ scopeStack = os_realloc(scopeStack, strlen(scopeStack)+strlen(scopeSepp)+strlen(Id)+1); /* Concatenate the separator */ @@ -232,8 +238,8 @@ idl_scopeStackJava ( } /* Return the C specific type identifier for the - specified type specification -*/ + * specified type specification + */ c_char * idl_corbaJavaTypeFromTypeSpec ( idl_typeSpec typeSpec) @@ -294,9 +300,9 @@ idl_corbaJavaTypeFromTypeSpec ( return idl_corbaJavaTypeFromTypeSpec (idl_typeDefActual(idl_typeDef (typeSpec))); } else { /* if a user type is specified build it from its scope and its name. - The type should be one of idl_ttypedef, idl_tenum, idl_tstruct, - idl_tunion. - */ + * The type should be one of idl_ttypedef, idl_tenum, idl_tstruct, + * idl_tunion. + */ typeName = idl_scopeStackJava( idl_typeUserScope(idl_typeUser(typeSpec)), ".", @@ -306,6 +312,166 @@ idl_corbaJavaTypeFromTypeSpec ( /* QAC EXPECT 5101; The switch statement is simple, therefor the total complexity is low */ } +c_char * +idl_genJavaLiteralValueImage( + c_value literal, + c_type type) +{ + c_char * valueImg = NULL; + c_char *val2; + int i; + + if (c_baseObject(type)->kind != M_ENUMERATION) { + switch (literal.kind) { + case V_OCTET: + valueImg = os_malloc (40); + snprintf(valueImg, 40, "%d", literal.is.Octet); + break; + case V_FLOAT: + case V_DOUBLE: + val2 = os_malloc(45); + valueImg = os_malloc(45); + snprintf(val2, 45, "%40.17g", literal.is.Double); + i = 0; + while (val2[i] == ' ') { + i++; + } + os_strncpy(valueImg, &val2[i], 40); + os_free(val2); + if ((strchr(valueImg, '.') == NULL) && (strchr(valueImg, 'E') == NULL)) { + strcat(valueImg, ".0"); + } + break; + case V_STRING: + valueImg = os_malloc(strlen(literal.is.String)+3); + snprintf(valueImg, strlen(literal.is.String)+3, "\"%s\"", literal.is.String); + break; + case V_BOOLEAN: + valueImg = os_malloc(40); + if (literal.is.Boolean) { + snprintf(valueImg, 40, "true"); + } else { + snprintf (valueImg, 40, "false"); + } + break; + case V_LONGLONG: + valueImg = os_malloc(40); + switch (c_primitive(type)->kind) { + case P_SHORT: + /* Apply unsigned version, since sign will be applied later as additional minus operand. */ + snprintf(valueImg, 40, "%hu", (c_short)literal.is.LongLong); + break; + case P_USHORT: + /* Apply signed version, since Java has no unsigned types and therefore needs to + * overflow into the negative range. */ + snprintf(valueImg, 40, "%hd", (c_short)literal.is.LongLong); + break; + case P_LONG: + /* Apply unsigned version, since sign will be applied later as additional minus operand. */ + snprintf(valueImg, 40, "%u", (c_long)literal.is.LongLong); + break; + case P_ULONG: + /* Apply signed version, since Java has no unsigned types and therefore needs to + * overflow into the negative range. */ + snprintf(valueImg, 40, "%d", (c_long)literal.is.LongLong); + break; + case P_LONGLONG: + /* Apply unsigned version, since sign will be applied later as additional minus operand. */ + snprintf(valueImg, 40, "%"PA_PRIu64"L", (c_longlong)literal.is.LongLong); + break; + case P_ULONGLONG: + /* Apply signed version, since Java has no unsigned types and therefore needs to + * overflow into the negative range. */ + snprintf(valueImg, 40, "%"PA_PRId64"L", (c_longlong)literal.is.LongLong); + break; + case P_CHAR: + snprintf(valueImg, 40, "%d", (unsigned char)literal.is.LongLong); + break; + case P_OCTET: + snprintf(valueImg, 40, "%d", (unsigned char)literal.is.LongLong); + break; + case P_ADDRESS: + snprintf(valueImg, 40, PA_ADDRFMT, (PA_ADDRCAST)literal.is.LongLong); + break; + case P_UNDEFINED: + case P_BOOLEAN: + case P_WCHAR: + case P_FLOAT: + case P_DOUBLE: + case P_VOIDP: + case P_MUTEX: + case P_LOCK: + case P_COND: + case P_COUNT: + case P_PA_UINT32: + case P_PA_UINTPTR: + case P_PA_VOIDP: + /* Do nothing */ + break; + } + break; + case V_SHORT: + /* Apply unsigned version, since sign will be applied later as additional minus operand. */ + valueImg = os_malloc(40); + snprintf(valueImg, 40, "%hu", literal.is.Short); + break; + case V_LONG: + /* Apply unsigned version, since sign will be applied later as additional minus operand. */ + valueImg = os_malloc(40); + snprintf(valueImg, 40, "%u", (c_long)literal.is.Long); + break; + case V_USHORT: + /* Apply signed version, since Java has no unsigned types and therefore needs to + * overflow into the negative range. */ + valueImg = os_malloc(40); + snprintf(valueImg, 40, "%hd", (c_short)literal.is.UShort); + break; + case V_ULONG: + /* Apply signed version, since Java has no unsigned types and therefore needs to + * overflow into the negative range. */ + valueImg = os_malloc(40); + snprintf(valueImg, 40, "%d", (c_long)literal.is.ULong); + break; + case V_ULONGLONG: + /* Apply signed version, since Java has no unsigned types and therefore needs to + * overflow into the negative range. */ + valueImg = os_malloc(40); + snprintf(valueImg, 40, "%" PA_PRId64, (c_longlong)literal.is.ULongLong); + break; + case V_ADDRESS: + valueImg = os_malloc(40); + snprintf(valueImg, 40, PA_ADDRFMT, (PA_ADDRCAST)literal.is.Address); + break; + case V_CHAR: + valueImg = os_malloc(40); + snprintf(valueImg, 40, "%u", (unsigned char)literal.is.Char); + break; + case V_UNDEFINED: + case V_WCHAR: + case V_WSTRING: + case V_FIXED: + case V_VOIDP: + case V_OBJECT: + case V_COUNT: + /* Invalid types for literal constants*/ + /* FALL THROUGH */ + default: + valueImg = NULL; + break; + } + } else { + const char *ENUM_TEMPLATE = "%s.%s"; + char *javaEnumTp = idl_javaId(c_metaObject(type)->name); + char *javaEnumLabel = idl_javaId(c_metaObject(c_enumeration(type)->elements[literal.is.Long])->name); + size_t valLen = strlen(javaEnumTp) + strlen(javaEnumLabel) + strlen(ENUM_TEMPLATE) + 1; + valueImg = os_malloc(valLen); + snprintf(valueImg, valLen, ENUM_TEMPLATE, javaEnumTp, javaEnumLabel); + os_free(javaEnumTp); + os_free(javaEnumLabel); + } + return valueImg; +} + /* FIXME: replace by os_mkpath once it's merged? */ static int idl_createDir ( @@ -313,7 +479,7 @@ idl_createDir ( { char *pathName; os_result statRes; - struct os_stat statbuf; + struct os_stat_s statbuf; char* outdir; os_char* stackScope; os_char* token; @@ -356,7 +522,7 @@ idl_createDir ( stackScope = token; statRes = os_stat (pathName, &statbuf); if (statRes == os_resultFail) { - /* @todo */ + /* TODO */ /* Assume the file does not exist. On some platforms */ /* a check to see if errno == ENOENT would be more conclusive */ /* That fails on WIN32 however because stat is not fully */ diff --git a/src/tools/idlpp/code/idl_genJavaHelper.h b/src/tools/idlpp/code/idl_genJavaHelper.h index 43aa13ca0..a395a06c6 100644 --- a/src/tools/idlpp/code/idl_genJavaHelper.h +++ b/src/tools/idlpp/code/idl_genJavaHelper.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -42,6 +43,8 @@ c_char *idl_scopeStackJava(idl_scope scope, const char *scopeSepp, const char *n c_char *idl_corbaJavaTypeFromTypeSpec(idl_typeSpec typeSpec); +c_char *idl_genJavaLiteralValueImage(c_value literal, c_type type); + void idl_openJavaPackage(idl_scope scope, const char *name); void idl_closeJavaPackage(void); diff --git a/src/tools/idlpp/code/idl_genLabview.c b/src/tools/idlpp/code/idl_genLabview.c new file mode 100644 index 000000000..c646beb07 --- /dev/null +++ b/src/tools/idlpp/code/idl_genLabview.c @@ -0,0 +1,862 @@ +/* + * OpenSplice DDS + * + * This software and documentation are Copyright 2006 to TO_YEAR PrismTech + * Limited, its affiliated companies and licensors. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +/* + This module generates Splice type definitions related to + an IDL input file. +*/ + +/** + * @file + * This module generates a MATLAB script that outputs a Simulink Bus object + * related to an IDL input file. +*/ + +#include + +#include "os_version.h" +#include "idl_program.h" +#include "idl_scope.h" +#include "idl_dependencies.h" +#include "idl_genLanguageHelper.h" +#include "idl_tmplExp.h" +#include "idl_map.h" +#include "idl_keyDef.h" +#include "idl_genMetaHelper.h" +#include "idl_genLabview.h" + +#include +#include "c_typebase.h" +#include "os_iterator.h" +#include "os_stdlib.h" +#include "os_heap.h" +#include "os_abstract.h" +#include "ut_collection.h" + +/* + * START: code copied from osplo/src/tools/labview/include/labview_cico.h + */ +typedef enum { + CICO_STRUCT_DEF, + CICO_PRIMITIVE, + CICO_STRING, + CICO_STRUCT, + CICO_ARRAY, + CICO_SEQUENCE, +} Cico_Code_t; + +typedef enum { + CICO_PRIM_BOOLEAN, + CICO_PRIM_CHAR, + CICO_PRIM_OCTET, + CICO_PRIM_SHORT, + CICO_PRIM_USHORT, + CICO_PRIM_LONG, + CICO_PRIM_ULONG, + CICO_PRIM_LONGLONG, + CICO_PRIM_ULONGLONG, + CICO_PRIM_FLOAT, + CICO_PRIM_DOUBLE, +} Cico_Primitive_t; + +/* + * END: copied code + */ + +typedef struct entry_info { + Cico_Code_t code; + int value; + const char *ref_qname; +} entry_info_t; + +typedef struct copy_info { + unsigned int nflds; + unsigned int nentries; + entry_info_t *entries; +} copy_info_t; + +static idl_streamOut topicTypeStream; +static idl_streamOut copyInfoStream; +static copy_info_t *current_copy_info; + +static const char *codeToStr(Cico_Code_t code) { + switch (code) { + case CICO_PRIMITIVE: + return "PRIMITIVE"; + case CICO_STRING: + return "STRING"; + case CICO_STRUCT: + return "STRUCT"; + case CICO_ARRAY: + return "ARRAY"; + case CICO_SEQUENCE: + return "SEQUENCE"; + case CICO_STRUCT_DEF: + default: + return ""; + } +} + + +static c_char +*labviewQualifiedElement( + idl_scope scope, + const char *name) +{ + size_t slen = NULL; + idl_scopeType currentScopeType = NULL; + char *scopeStack = os_strdup (""); + if (idl_scopeStackSize(scope) != 0) { + int si; + for (si = 0; si < idl_scopeStackSize(scope); si++) { + char *seName = idl_scopeElementName(idl_scopeIndexed(scope, si)); + + /* 2 for scope separator, 1 for null byte */ + slen = strlen (scopeStack) + 2 + strlen (seName) +1; + scopeStack = os_realloc(scopeStack, slen); + if (strlen(scopeStack) != 0) { + os_strcat(scopeStack, "__"); + } + os_strcat (scopeStack, seName); + } + if(strlen(name) != 0) { + /* 2 for scope separator, 1 for null byte */ + slen = strlen (scopeStack) + 2 + strlen (name) + 1; + scopeStack = os_realloc(scopeStack, slen); + if (strlen(scopeStack) != 0) { + currentScopeType = idl_scopeElementType(idl_scopeCur(scope)); + if(currentScopeType == idl_tStruct) { + os_strcat(scopeStack, "_"); + } else { + os_strcat(scopeStack, "__"); + } + } + os_strcat (scopeStack, name); + } + } else { + os_free(scopeStack); + scopeStack = os_strdup(name); + } + return scopeStack; +} + +/* @brief callback function called on opening the IDL input file. + * + * Generate standard file header consisting of: + * - mutiple inclusion prevention + * - inclusion of Splice type definition files + * - inclusion of application specific include files related to other IDL files + * + * @param scope Current scope (not used) + * @param name Name of the IDL input file + */ +static idl_action +idl_fileOpen( + idl_scope scope, + const char *name, + void *userData) +{ + OS_UNUSED_ARG(scope); + OS_UNUSED_ARG(userData); + + /* TODO: delete these */ + + idl_fileOutPrintf(idl_fileCur(), "\n", name); + idl_fileOutPrintf(idl_fileCur(), + "\n" + " \n"); + + return idl_explore; +} + +static void +idl_fileClose( + void *userData) +{ + OS_UNUSED_ARG(userData); + + idl_fileOutPrintf(idl_fileCur(), + " \n" + "\n" + ); +} + + +/** @brief callback function called on structure definition in the IDL input file. + * + * Generate code for the following IDL construct: + * @verbatim + => struct { + ; + ... ... + ; + }; + @endverbatim + * + * @param scope Current scope (and scope of the structure definition) + * @param name Name of the structure + * @param structSpec Specification of the struct holding the amount of members + */ +static idl_action +idl_structureOpen( + idl_scope scope, + const char *name, + idl_typeStruct structSpec, + void *userData) +{ + char *qname; + const c_char *keys; + + OS_UNUSED_ARG(userData); + + qname = labviewQualifiedElement(scope, name); + + /* alloc'd here, release on structure close */ + current_copy_info = (copy_info_t *)os_malloc(sizeof(copy_info_t)); + current_copy_info->entries = NULL; + current_copy_info->nflds = 0; + current_copy_info->nentries = 0; + + idl_fileOutPrintf(idl_fileCur(), + " \n" + , qname); + + keys = idl_keyResolve(idl_keyDefDefGet(), scope, name); + copyInfoStream = idl_streamOutNew (0); + + if(keys != NULL) { + c_type type = idl_typeSpecDef(idl_typeSpec(structSpec)); + c_char *descriptor = idl_genXMLmeta(type, FALSE); + c_char *scopedTypeName = idl_scopeStack(scope, "::", name); + c_char *cp; + + /* It's a topic type declaration */ + topicTypeStream = idl_streamOutNew (0); + + idl_streamOutPrintf(topicTypeStream, + " \n" + " %s\n" + " %s\n" + " %s\n" + " " + , + scopedTypeName, qname, keys + ); + /* XML encode and write the descriptor */ + for(cp = descriptor; *cp; cp++) { + if(*cp == '<') { + idl_streamOutPut(topicTypeStream, '&'); + idl_streamOutPut(topicTypeStream, 'l'); + idl_streamOutPut(topicTypeStream, 't'); + idl_streamOutPut(topicTypeStream, ';'); + } else if (*cp == '>') { + idl_streamOutPut(topicTypeStream, '&'); + idl_streamOutPut(topicTypeStream, 'g'); + idl_streamOutPut(topicTypeStream, 't'); + idl_streamOutPut(topicTypeStream, ';'); + } else { + (void) idl_streamOutPut(topicTypeStream, *cp); + } + } + idl_streamOutPrintf(topicTypeStream, + "\n" + " \n" + ); + + os_free(descriptor); + os_free(scopedTypeName); + } else { + topicTypeStream = NULL; + } + + os_free(qname); + + return idl_explore; +} + +static void print_copy_info( + copy_info_t* ci) { + unsigned int i; + + idl_streamOutPrintf(copyInfoStream, + " STRUCT_DEF%d\n", + ci->nflds); + for (i = 0; i < ci->nentries; i++) { + if(ci->entries[i].code == CICO_STRUCT) { + idl_streamOutPrintf(copyInfoStream, + " %s%d\n" + " %s%d\n", + codeToStr(ci->entries[i].code), + ci->entries[i].value, + ci->entries[i].ref_qname, + i + 1 + ); + + } else { + idl_streamOutPrintf(copyInfoStream, + " %s%d\n", + codeToStr(ci->entries[i].code), + ci->entries[i].value + ); + } + } +} + +static void free_copy_info(copy_info_t *ci) +{ + if(ci->entries) { + unsigned int i; + for(i = 0; i < ci->nentries; i++) { + if(ci->entries[i].code == CICO_STRUCT) { + os_free((void *)ci->entries[i].ref_qname); + } + } + os_free(ci->entries); + } + os_free(ci); +} + +/** @brief callback function called on end of a structure definition in the IDL input file. + * + * Generate code for the following IDL construct: + * @verbatim + struct { + + ... ... + + => }; + @endverbatim + * + * The structure is closed: + * @verbatim + }; + @endverbatim + * + * @param name Name of the structure (not used) + */ +static void +idl_structureClose( + const char *name, + void *userData) +{ + OS_UNUSED_ARG(name); + OS_UNUSED_ARG(userData); + + /* print copy info */ + idl_streamOutPrintf(copyInfoStream, + " \n" + ); + + print_copy_info(current_copy_info); + + idl_streamOutPrintf(copyInfoStream, + "
    \n" + ); + idl_fileOutPrintf(idl_fileCur(), "%s", idl_streamGet (idl_stream(copyInfoStream))); + idl_streamOutFree(copyInfoStream); + copyInfoStream = NULL; + + if(topicTypeStream) { + /* print type info, if it's a topic type */ + idl_fileOutPrintf(idl_fileCur(), "%s", idl_streamGet (idl_stream(topicTypeStream))); + + idl_streamOutFree(topicTypeStream); + } + topicTypeStream = NULL; + + idl_fileOutPrintf(idl_fileCur(), "
    \n"); + + free_copy_info(current_copy_info); + current_copy_info = NULL; + +} + +idl_typeSpec actualArrayType(idl_typeArray typeArray) { + idl_typeSpec arrayActual = idl_typeArrayType(typeArray); + /* This while loop may be overkill, but doc and code is unclear + * as to whehter idl_typeDefActual goes through all typedefs + */ + while(idl_typeSpecType(arrayActual) == idl_ttypedef) { + arrayActual = idl_typeDefActual(idl_typeDef(arrayActual)); + } + + return arrayActual; +} + +static void print_field_type(idl_typeSpec typeSpec) { + idl_type memberType = idl_typeSpecType(typeSpec); + switch (memberType) { + case idl_tbasic: { + idl_typeBasic typeBasic = idl_typeBasic(typeSpec); + idl_basicType basicType = idl_typeBasicType(typeBasic); + switch (basicType) { + case idl_short: + idl_fileOutPrintf(idl_fileCur(), "int16"); + break; + case idl_ushort: + idl_fileOutPrintf(idl_fileCur(), "uint16"); + break; + case idl_long: + idl_fileOutPrintf(idl_fileCur(), "int32"); + break; + case idl_ulong: + idl_fileOutPrintf(idl_fileCur(), "uint32"); + break; + case idl_longlong: + idl_fileOutPrintf(idl_fileCur(), "int64"); + break; + case idl_ulonglong: + idl_fileOutPrintf(idl_fileCur(), "uint64"); + break; + case idl_float: + idl_fileOutPrintf(idl_fileCur(), "float"); + break; + case idl_double: + idl_fileOutPrintf(idl_fileCur(), "double"); + break; + case idl_char: + idl_fileOutPrintf(idl_fileCur(), "int8"); + break; + case idl_octet: + idl_fileOutPrintf(idl_fileCur(), "uint8"); + break; + case idl_boolean: + idl_fileOutPrintf(idl_fileCur(), ""); + break; + case idl_string: + idl_fileOutPrintf(idl_fileCur(), ""); + break; + } + break; + } + case idl_tenum: { + char* enumQname; + enumQname = labviewQualifiedElement( + idl_typeUserScope(idl_typeUser(typeSpec)), + idl_typeSpecName(typeSpec)); + idl_fileOutPrintf(idl_fileCur(), "%s", enumQname); + os_free(enumQname); + break; + } + case idl_tstruct: { + char* structQname; + structQname = labviewQualifiedElement( + idl_typeUserScope(idl_typeUser(typeSpec)), + idl_typeSpecName(typeSpec)); + idl_fileOutPrintf(idl_fileCur(), "%s", structQname); + os_free(structQname); + break; + } + case idl_tarray: { + idl_typeArray typeArray = idl_typeArray(typeSpec); + idl_typeSpec containedTypeSpec; + int ndims = 1; + for (containedTypeSpec = actualArrayType(typeArray); + idl_typeSpecType(containedTypeSpec) == idl_tarray; + containedTypeSpec = idl_typeArrayType(idl_typeArray(containedTypeSpec))) { + ndims++; + } + idl_fileOutPrintf(idl_fileCur(), "", ndims); + print_field_type(containedTypeSpec); + idl_fileOutPrintf(idl_fileCur(), ""); + break; + } + case idl_tseq: { + idl_typeSpec containedTypeSpec = idl_typeSeqType(idl_typeSeq(typeSpec)); + idl_fileOutPrintf(idl_fileCur(), ""); + print_field_type(containedTypeSpec); + idl_fileOutPrintf(idl_fileCur(), ""); + break; + } + case idl_ttypedef: { + print_field_type(idl_typeDefActual(idl_typeDef(typeSpec))); + break; + } + case idl_tunion: + default: + break; + } +} + +static entry_info_t *grow_entries() { + const unsigned int INCR = 10; + unsigned int idx; + if(current_copy_info->nentries == 0) { + current_copy_info->entries = (entry_info_t *)os_malloc(INCR * sizeof(entry_info_t)); + } else if(current_copy_info->nentries % INCR == 0) { + current_copy_info->entries = (entry_info_t *)os_realloc(current_copy_info->entries, + (current_copy_info->nentries + INCR) * sizeof(entry_info_t)); + } + idx = current_copy_info->nentries++; + return &(current_copy_info->entries[idx]); +} + +static void record_field_info(idl_typeSpec typeSpec) { + idl_type memberType = idl_typeSpecType(typeSpec); + switch (memberType) { + case idl_tbasic: { + entry_info_t *entry = grow_entries(); + idl_typeBasic typeBasic = idl_typeBasic(typeSpec); + idl_basicType basicType = idl_typeBasicType(typeBasic); + switch (basicType) { + case idl_short: + entry->code = CICO_PRIMITIVE; + entry->value = CICO_PRIM_SHORT; + break; + case idl_ushort: + entry->code = CICO_PRIMITIVE; + entry->value = CICO_PRIM_USHORT; + break; + case idl_long: + entry->code = CICO_PRIMITIVE; + entry->value = CICO_PRIM_LONG; + break; + case idl_ulong: + entry->code = CICO_PRIMITIVE; + entry->value = CICO_PRIM_ULONG; + break; + case idl_longlong: + entry->code = CICO_PRIMITIVE; + entry->value = CICO_PRIM_LONGLONG; + break; + case idl_ulonglong: + entry->code = CICO_PRIMITIVE; + entry->value = CICO_PRIM_ULONGLONG; + break; + case idl_float: + entry->code = CICO_PRIMITIVE; + entry->value = CICO_PRIM_FLOAT; + break; + case idl_double: + entry->code = CICO_PRIMITIVE; + entry->value = CICO_PRIM_DOUBLE; + break; + case idl_char: + entry->code = CICO_PRIMITIVE; + entry->value = CICO_PRIM_CHAR; + break; + case idl_octet: + entry->code = CICO_PRIMITIVE; + entry->value = CICO_PRIM_OCTET; + break; + case idl_boolean: + entry->code = CICO_PRIMITIVE; + entry->value = CICO_PRIM_BOOLEAN; + break; + case idl_string: + entry->code = CICO_STRING; + entry->value = (int)idl_typeBasicMaxlen(typeBasic); + break; + } + break; + } + case idl_tenum: { + entry_info_t *entry = grow_entries(); + entry->code = CICO_PRIMITIVE; + entry->value = CICO_PRIM_LONG; + break; + break; + } + case idl_tstruct: { + entry_info_t *entry = grow_entries(); + entry->code = CICO_STRUCT; + entry->value = -1; + entry->ref_qname = idl_scopeStack( + idl_typeUserScope(idl_typeUser(typeSpec)), + "::", + idl_typeSpecName(typeSpec)); +/* + labviewQualifiedElement( + idl_typeUserScope(idl_typeUser(typeSpec)), + idl_typeSpecName(typeSpec)); +*/ + break; + } + case idl_tarray: { + entry_info_t *entry = grow_entries(); + entry->code = CICO_ARRAY; + entry->value = (int)idl_typeArraySize(idl_typeArray(typeSpec)); + record_field_info(idl_typeArrayType(idl_typeArray(typeSpec))); + break; + } + case idl_tseq: { + entry_info_t *entry = grow_entries(); + entry->code = CICO_SEQUENCE; + entry->value = (int)idl_typeSeqMaxSize(idl_typeSeq(typeSpec)); + record_field_info(idl_typeSeqType(idl_typeSeq(typeSpec))); + break; + } + case idl_ttypedef: { + record_field_info(idl_typeDefActual(idl_typeDef(typeSpec))); + break; + } + case idl_tunion: + default: + break; + } +} + +/** @brief callback function called on definition of a structure member in the IDL input file. + * + * Generate code for the following IDL construct: + * @verbatim + struct { + => ; + => ... ... + => ; + }; + @endverbatim + * + * @param scope Current scope + * @param name Name of the structure member + * @param typeSpec Type specification of the structure member + */ +static void +idl_structureMemberOpenClose( + idl_scope scope, + const char *name, + idl_typeSpec typeSpec, + void *userData) +{ + + OS_UNUSED_ARG(scope); + OS_UNUSED_ARG(typeSpec); + OS_UNUSED_ARG(userData); + + + idl_fileOutPrintf(idl_fileCur(), + " " + , name); + + print_field_type(typeSpec); + + idl_fileOutPrintf(idl_fileCur(), + "\n" + ); + + record_field_info(typeSpec); + current_copy_info->nflds++; + + +} + +/** @brief callback function called on definition of an enumeration. + * + * Generate code for the following IDL construct: + * @verbatim + => enum { + ; + ... ... + ; + }; + @endverbatim + * + * @param scope Current scope + * @param name Name of the enumeration + * @param enumSpec Specifies the number of elements in the enumeration + */ +static idl_action +idl_enumerationOpen( + idl_scope scope, + const char *name, + idl_typeEnum enumSpec, + void *userData) +{ + char *qname; + + OS_UNUSED_ARG(enumSpec); + OS_UNUSED_ARG(userData); + + qname = labviewQualifiedElement(scope, name); + + idl_fileOutPrintf(idl_fileCur(), + " \n" + , qname); + + os_free(qname); + /* return idl_explore to indicate that the rest of the structure needs to be processed */ + return idl_explore; +} + +/** @brief callback function called on closure of an enumeration in the IDL input file. + * + * Generate code for the following IDL construct: + * @verbatim + enum { + ; + ... ... + ; + => }; + @endverbatim + * + * @param name Name of the enumeration + */ +static void +idl_enumerationClose( + const char *name, + void *userData) +{ + OS_UNUSED_ARG(name); + OS_UNUSED_ARG(userData); + + + idl_fileOutPrintf(idl_fileCur(), + " \n" + ); +} + +/** @brief callback function called on definition of an enumeration element in the IDL input file. + * + * Generate code for the following IDL construct: + * @verbatim + enum { + => , + => ... ... + => + }; + @endverbatim + * + * For the last element generate: + * @verbatim + + @endverbatim + * For any but the last element generate: + * @verbatim + , + @endverbatim + * + * @param scope Current scope + * @param name Name of the enumeration element + */ +static void +idl_enumerationElementOpenClose ( + idl_scope scope, + const char *name, + void *userData) +{ + OS_UNUSED_ARG(scope); + OS_UNUSED_ARG(name); + OS_UNUSED_ARG(userData); + + idl_fileOutPrintf(idl_fileCur(), + " %s\n" + , name); + +} + +static void +idl_sequenceOpenClose( + idl_scope scope, + idl_typeSeq typeSeq, + void *userData) +{ + OS_UNUSED_ARG(scope); + OS_UNUSED_ARG(typeSeq); + OS_UNUSED_ARG(userData); +} + +/** @brief callback function called on module definition in the IDL input file. + * + * Generate code for the following IDL construct: + * @verbatim + => module { + + }; + @endverbatim + * + * This fuction generates the prototype of the function that + * is responsible for loading the metadata into the database. + * The name of the function is: + * @verbatim + ______load + @endverbatim + * For the Splice types, no further actions are required. + * + * @param scope Current scope (and scope of the module definition) + * @param name Name of the defined module + */ +static idl_action +idl_moduleOpen( + idl_scope scope, + const char *name, + void *userData) +{ + OS_UNUSED_ARG(scope); + OS_UNUSED_ARG(name); + OS_UNUSED_ARG(userData); + /* return idl_explore to indicate that the rest of the module needs to be processed */ + return idl_explore; +} + +/** + * Standard control structure to specify that inline + * type definitions are to be processed prior to the + * type itself in contrast with inline. +*/ +static idl_programControl idl_genLabVIEWLoadControl = { + idl_prior +}; + +/** @brief return the program control structure for the splice type generation functions. + */ +static idl_programControl * +idl_getControl( + void *userData) +{ + OS_UNUSED_ARG(userData); + return &idl_genLabVIEWLoadControl; +} + +/** + * Specifies the callback table for the splice type generation functions. + */ +static struct idl_program +idl_genLabVIEW = { + idl_getControl, + idl_fileOpen, + idl_fileClose, + idl_moduleOpen, + NULL, /* idl_moduleClose */ + idl_structureOpen, + idl_structureClose, + idl_structureMemberOpenClose, + idl_enumerationOpen, + idl_enumerationClose, + idl_enumerationElementOpenClose, + NULL, /* idl_unionOpen */ + NULL, /* idl_unionClose */ + NULL, /* idl_unionCaseOpenClose */ + NULL, /* idl_unionLabelsOpenClose */ + NULL, /* idl_unionLabelOpenClose */ + NULL, /* idl_typedefOpenClose */ + NULL, /* idl_boundedStringOpenClose */ + idl_sequenceOpenClose, /* idl_sequenceOpenClose */ + NULL, /* idl_constantOpenClose */ + NULL, /* idl_artificialDefaultLabelOpenClose */ + NULL /* userData */ +}; + +/** @brief return the callback table for the splice type generation functions. + */ +idl_program +idl_genLabVIEWProgram( + void) +{ + return &idl_genLabVIEW; +} diff --git a/src/tools/idlpp/code/idl_genLabview.h b/src/tools/idlpp/code/idl_genLabview.h new file mode 100644 index 000000000..4f714385c --- /dev/null +++ b/src/tools/idlpp/code/idl_genLabview.h @@ -0,0 +1,27 @@ +/* + * OpenSplice DDS + * + * This software and documentation are Copyright 2006 to TO_YEAR PrismTech + * Limited, its affiliated companies and licensors. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#ifndef IDL_GENLABVIEW_H +#define IDL_GENLABVIEW_H + +#include "idl_program.h" + +idl_program idl_genLabVIEWProgram (void); + +#endif /* IDL_GENLABVIEW_H */ diff --git a/src/tools/idlpp/code/idl_genLanguageHelper.c b/src/tools/idlpp/code/idl_genLanguageHelper.c index bb096d25b..5502cb795 100644 --- a/src/tools/idlpp/code/idl_genLanguageHelper.c +++ b/src/tools/idlpp/code/idl_genLanguageHelper.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,16 +21,15 @@ #include "idl_genLanguageHelper.h" #include "idl_genCHelper.h" #include "idl_genCxxHelper.h" +#include "idl_genISOCxx2Helper.h" #include "idl_genSACSHelper.h" #include "idl_genJavaHelper.h" +#include "idl_genPythonHelper.h" #include "os_stdlib.h" static IDL_LANGUAGE lang = IDL_LANG_UNKNOWN; static IDL_CORBA_MODE corba_mode = IDL_MODE_UNKNOWN; -/** @internal - * @bug OSPL-3369 Handle both below as other modes and languages once - * re-engineered and no side effects confirmed */ static os_boolean is_isocpp = OS_FALSE; static os_boolean is_isocpp2 = OS_FALSE; static os_boolean is_isocpp_types = OS_FALSE; @@ -38,8 +38,8 @@ static os_boolean is_isocpp_testmethods = OS_FALSE; static os_boolean is_face = OS_FALSE; static os_boolean is_isocpp_streams = OS_FALSE; /* columns are the IDL_MODE attributes - rows are the IDL_LANG attributes -*/ + * rows are the IDL_LANG attributes + */ static int idl_supportedLanguageAndMode[IDL_LANG_COUNT][IDL_MODE_COUNT] = { /* IDL_LANG_UNKNOWN */ {0, 0, 0}, /* IDL_LANG_C */ {0, 0, 1}, @@ -48,7 +48,12 @@ static int idl_supportedLanguageAndMode[IDL_LANG_COUNT][IDL_MODE_COUNT] = { /* IDL_LANG_JAVA */ {0, 1, 1}, /* IDL_LANG_ISOCPP2 */ {0, 0, 1}, /* IDL_LANG_LITE_CXX */ {0, 0, 1}, - /* IDL_LANG_C99 */ {0, 0, 1} + /* IDL_LANG_C99 */ {0, 0, 1}, + /* IDL_LANG_SIMULINK */ {0, 0, 1}, + /* IDL_LANG_MATLAB */ {0, 0, 1}, + /* IDL_LANG_PYTHON_DESCRIPTORS*/{0, 0, 1}, + /* IDL_LANG_LABVIEW */ {0, 0, 1}, + /* IDL_LANG_PYTHON */ {0, 0, 1}, }; @@ -89,6 +94,21 @@ idl_getLanguageStr(void) case IDL_LANG_ISOCPP2: str = "ISOCPP"; break; + case IDL_LANG_SIMULINK: + str = "SIMULINK"; + break; + case IDL_LANG_MATLAB: + str = "MATLAB"; + break; + case IDL_LANG_PYTHON_DESCRIPTORS: + str = "PYTHON_DESCRIPTORS"; + break; + case IDL_LANG_LABVIEW: + str = "LABVIEW"; + break; + case IDL_LANG_PYTHON: + str = "PYTHON"; + break; case IDL_LANG_UNKNOWN: default: str = ""; @@ -115,9 +135,6 @@ idl_getCorbaModeStr(void) { const char *str = NULL; - /** @internal - * @bug OSPL-3369 Have confirmed this is only used in output (where - * it leaked previously) */ if (idl_getIsISOCppTypes()) return "ISO/IEC C++ 2003"; @@ -143,8 +160,6 @@ idl_languageAndModeSupported(void) int is_ok = idl_supportedLanguageAndMode[lang][corba_mode]; if (is_ok) { - /** @internal - * @bug OSPL-3369 Temporary sanity check for isocpp settings */ if (idl_getIsISOCppTypes() && lang != IDL_LANG_CXX && lang != IDL_LANG_ISOCPP2 @@ -157,9 +172,9 @@ idl_languageAndModeSupported(void) } /* Translate an IDL identifier into a language specific identifier. - The IDL specification states that all identifiers that match - a language keyword must be prepended by a language specific prefix. -*/ + * The IDL specification states that all identifiers that match + * a language keyword must be prepended by a language specific prefix. + */ c_char * idl_languageId( const char *identifier) @@ -172,16 +187,21 @@ idl_languageId( id = idl_cId (identifier); break; case IDL_LANG_CXX: - case IDL_LANG_ISOCPP2: case IDL_LANG_LITE_CXX: id = idl_cxxId (identifier); break; + case IDL_LANG_ISOCPP2: + id = idl_ISOCxx2Id (identifier); + break; case IDL_LANG_CS: id = idl_CsharpId (identifier, FALSE, FALSE); break; case IDL_LANG_JAVA: id = idl_javaId (identifier); break; + case IDL_LANG_PYTHON: + id = idl_pythonId(identifier); + break; case IDL_LANG_UNKNOWN: default: break; @@ -190,9 +210,9 @@ idl_languageId( } /* Build a textual presenation of the provided scope stack taking the - language keyword identifier translation into account. Further the function - equals "idl_scopeStack". -*/ + * language keyword identifier translation into account. Further the function + * equals "idl_scopeStack". + */ c_char * idl_scopeStackLanguage( idl_scope scope, @@ -206,15 +226,20 @@ idl_scopeStackLanguage( id = idl_scopeStackC (scope, "_", name); break; case IDL_LANG_CXX: - case IDL_LANG_ISOCPP2: id = idl_scopeStackCxx (scope, "::", name); break; + case IDL_LANG_ISOCPP2: + id = idl_scopeStackISOCxx2 (scope, "::", name); + break; case IDL_LANG_CS: id = idl_scopeStackCsharp(scope, ".", name); break; case IDL_LANG_JAVA: id = idl_scopeStackJava (scope, ".", name); break; + case IDL_LANG_PYTHON: + id = idl_scopeStackPython (scope, ".", name); + break; case IDL_LANG_UNKNOWN: default: break; @@ -223,8 +248,8 @@ idl_scopeStackLanguage( } /* Return the Language specific type identifier for the - specified type specification -*/ + * specified type specification + */ c_char * idl_corbaLanguageTypeFromTypeSpec ( idl_typeSpec typeSpec) @@ -251,6 +276,45 @@ idl_corbaLanguageTypeFromTypeSpec ( return id; } +c_char * +idl_genLanguageLiteralValueImage( + c_value literal, + c_type type, + void *userData) +{ + c_char * valueImg = NULL; + + switch (lang) { + case IDL_LANG_C: + case IDL_LANG_C99: + case IDL_LANG_CXX: + case IDL_LANG_PYTHON_DESCRIPTORS: + case IDL_LANG_SIMULINK: + case IDL_LANG_MATLAB: + case IDL_LANG_LABVIEW: + valueImg = idl_genCLiteralValueImage(literal, type); + break; + case IDL_LANG_ISOCPP2: + case IDL_LANG_LITE_CXX: + valueImg = idl_genISOCxx2LiteralValueImage(literal, type); + break; + case IDL_LANG_CS: + valueImg = idl_genCsharpLiteralValueImage(literal, type, userData); + break; + case IDL_LANG_JAVA: + valueImg = idl_genJavaLiteralValueImage(literal, type); + break; + case IDL_LANG_PYTHON: + valueImg = idl_genPythonLiteralValueImage(literal, type); + break; + case IDL_LANG_UNKNOWN: + default: + break; + } + + return valueImg; +} + /* Return the language specific constant value getter */ c_char * idl_genLanguageConstGetter(void) diff --git a/src/tools/idlpp/code/idl_genLanguageHelper.h b/src/tools/idlpp/code/idl_genLanguageHelper.h index 0c4c64677..c3b913d6e 100644 --- a/src/tools/idlpp/code/idl_genLanguageHelper.h +++ b/src/tools/idlpp/code/idl_genLanguageHelper.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -32,9 +33,14 @@ typedef enum { IDL_LANG_CS, IDL_LANG_JAVA, IDL_LANG_ISOCPP2, - /** IDL_LANG_ISOCPP, I am not adding this yet. I wish to re-use C++ with tweaks @bug OSPL-3369 */ + /* IDL_LANG_ISOCPP, TODO Can this be removed. Wish to re-use C++ with tweaks */ IDL_LANG_LITE_CXX, IDL_LANG_C99, + IDL_LANG_SIMULINK, + IDL_LANG_MATLAB, + IDL_LANG_PYTHON_DESCRIPTORS, + IDL_LANG_LABVIEW, + IDL_LANG_PYTHON, IDL_LANG_COUNT /* should always be the last in the enumeration!!! */ } IDL_LANGUAGE; @@ -42,10 +48,11 @@ typedef enum { IDL_MODE_UNKNOWN, IDL_MODE_ORB_BOUND, IDL_MODE_STANDALONE, - /** IDL_MODE_NEW, I am not adding this yet. I wish to re-use C++ with tweaks @bug OSPL-3369 - Also: I don't like the designation 'New' but we're using vanilla - get_opt and all the good characters are taken. - This way we can re-use for Java 5 PSM */ + /** IDL_MODE_NEW, TODO Can this removed. I wish to re-use C++ with tweaks + * Also: I don't like the designation 'New' but we're using vanilla + * get_opt and all the good characters are taken. + * This way we can re-use for Java 5 PSM + */ IDL_MODE_COUNT /* should always be the last in the enumeration!!! */ } IDL_CORBA_MODE; @@ -67,6 +74,7 @@ int idl_languageAndModeSupported(void); c_char *idl_languageId(const char *identifier); c_char *idl_scopeStackLanguage(idl_scope scope, const char *name); c_char *idl_corbaLanguageTypeFromTypeSpec(idl_typeSpec typeSpec); +c_char *idl_genLanguageLiteralValueImage(c_value literal, c_type type, void *userData); c_char *idl_genLanguageConstGetter(void); void idl_setIsISOCpp(os_boolean itIs); diff --git a/src/tools/idlpp/code/idl_genLiteCxxCopyin.c b/src/tools/idlpp/code/idl_genLiteCxxCopyin.c index 97a802ce4..d739ee9d2 100644 --- a/src/tools/idlpp/code/idl_genLiteCxxCopyin.c +++ b/src/tools/idlpp/code/idl_genLiteCxxCopyin.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -42,7 +43,7 @@ /** Text indentation level (4 spaces per indent) */ static c_long loopIndent; - /** Index for array loop variables, incremented for each array dimension */ +/** Index for array loop variables, incremented for each array dimension */ static c_long varIndex; static c_char * @@ -60,17 +61,10 @@ idl_seqAllocBuffer( tmp_string, length, tmp_string); - + os_free(tmp_string); return buffer; } -#if 0 -static void -idl_arrayDimensions ( - idl_typeArray typeArray, - os_boolean resolveTypedefs); -#endif - static void idl_arrayElements ( idl_scope scope, @@ -81,17 +75,6 @@ idl_arrayElements ( c_long indent, void *userData); -#if 0 -static void -idl_arrayElementsIndirect ( - idl_scope scope, - idl_typeArray typeArray, - const char *from, - const char *to, - c_long indent, - void *userData); -#endif - static void idl_seqElements (idl_scope scope, const char *name, idl_typeDef typeDef, c_long indent, void *userData); static void idl_seqLoopCopy (idl_scope scope, idl_typeSpec typeSpec, const char *from, const char *to, c_long loop_index, c_long indent, void *userData); @@ -289,19 +272,11 @@ idl_basicMemberType ( case idl_string: maxlen = idl_typeBasicMaxlen(typeBasic); if (maxlen == 0) { -#if 0 - idl_fileOutPrintf(idl_fileCur(), " %s%s = dds_string_dup(%s%s);\n", - to_id, - cid, - from_id, - cid); -#else idl_fileOutPrintf(idl_fileCur(), " %s%s = (char *)((%s%s).in());\n", to_id, cid, from_id, cid); -#endif } else { /* TODO: bounded strings */ @@ -371,17 +346,19 @@ idl_structureMemberOpenClose ( /* QAC EXPECT 3416; No side effect here */ if ((idl_typeSpecType(idl_typeDefActual(idl_typeDef(typeSpec))) == idl_tstruct) || (idl_typeSpecType(idl_typeDefActual(idl_typeDef(typeSpec))) == idl_tseq)) { + char *scopedTypeName = idl_scopedTypeName (typeSpec); idl_fileOutPrintf (idl_fileCur(), " {\n"); IDL_PRINTLINE (indent); idl_fileOutPrintf (idl_fileCur(), " extern void __%s__copyIn(const %s *, %s *);\n", - idl_scopedTypeName (typeSpec), + scopedTypeName, idl_corbaCxxTypeFromTypeSpec(typeSpec), idl_scopedLiteTypeName (typeSpec)); idl_fileOutPrintf (idl_fileCur(), " __%s__copyIn(&from->%s, &to->%s);\n", - idl_scopedTypeName (typeSpec), + scopedTypeName, cid, cid); idl_fileOutPrintf (idl_fileCur(), " }\n"); + os_free(scopedTypeName); } else { /* Calls itself for the actual type in case of typedef */ /* QAC EXPECT 3670; We wan't to use recursion, the recursion is finite */ @@ -420,21 +397,6 @@ idl_structureMemberOpenClose ( snprintf(src, sizeof(src), "from->%s", name); idl_fileOutPrintf (idl_fileCur(), " {\n"); IDL_PRINTLINE (indent); -#if 0 - { - idl_typeSpec subType = idl_typeArrayActual(idl_typeArray(typeSpec)); - if (idl_typeSpecType(subType) == idl_tseq) { - c_char sname[32]; - snprintf(sname, sizeof(sname), "_%s", cid); - idl_fileOutPrintf (idl_fileCur(), " typedef const %s _SrcType", - idl_scopeStack(idl_typeUserScope(idl_typeUser(subType)), "::", sname)); - //idl_arrayDimensions (idl_typeArray(typeSpec), OS_FALSE); - idl_fileOutPrintf (idl_fileCur(), ";\n"); - idl_fileOutPrintf (idl_fileCur(), " _SrcType *src = &from->%s;\n", cid); - } - } -#endif - idl_arrayElements (scope, idl_typeArray(typeSpec), src, dest, FALSE, indent, userData); idl_fileOutPrintf (idl_fileCur(), " }\n"); @@ -451,20 +413,6 @@ idl_structureMemberOpenClose ( if (maxlen == 0) { idl_fileOutPrintf (idl_fileCur(), " {\n"); -#if 0 - IDL_PRINTLINE (indent); - idl_fileOutPrintf (idl_fileCur(), " const %s *src = &from->%s;\n", idl_scopeStackCxx (scope, "::", type_name), cid); - idl_fileOutPrintf (idl_fileCur(), " %s *dest0;\n", scopedName); - idl_fileOutPrintf (idl_fileCur(), " uint32_t length0;\n\n"); - idl_fileOutPrintf (idl_fileCur(), " length0 = (uint32_t)(*src).length();\n"); - idl_fileOutPrintf (idl_fileCur(), " dest0 = %s_allocbuf(length0);\n", idl_scopedLiteTypeName(typeSpec)); - idl_seqLoopCopy (scope, nextType, "*src", "dest0", 1, 2, userData); - idl_fileOutPrintf (idl_fileCur(), " to->%s._maximum = (uint32_t)(*src).maximum();\n", cid); - idl_fileOutPrintf (idl_fileCur(), " to->%s._length = length0;\n", cid); - idl_fileOutPrintf (idl_fileCur(), " to->%s._buffer = (uint8_t *)dest0;\n", cid); - idl_fileOutPrintf (idl_fileCur(), " to->%s._release = false;\n", cid); -#endif -#if 1 if (((idl_typeSpecType(nextType) == idl_tbasic) && (idl_typeBasicType(idl_typeBasic(nextType)) != idl_string)) || (idl_typeSpecType(nextType) == idl_tenum)) { @@ -480,19 +428,13 @@ idl_structureMemberOpenClose ( idl_fileOutPrintf (idl_fileCur(), " %s *dest0;\n", scopedName); idl_fileOutPrintf (idl_fileCur(), " uint32_t length0;\n\n"); idl_fileOutPrintf (idl_fileCur(), " length0 = (uint32_t)(*src).length();\n"); -#if 0 - idl_fileOutPrintf (idl_fileCur(), " dest0 = %s_allocbuf(length0);\n", idl_scopedLiteTypeName(typeSpec)); -#else - idl_fileOutPrintf (idl_fileCur(), " dest0 = %s;\n", - idl_seqAllocBuffer(idl_typeSeq(typeSpec), "length0", buffer, sizeof(buffer))); -#endif + idl_fileOutPrintf (idl_fileCur(), " dest0 = %s;\n", idl_seqAllocBuffer(idl_typeSeq(typeSpec), "length0", buffer, sizeof(buffer))); idl_seqLoopCopy (scope, nextType, "*src", "dest0", 1, 2, userData); idl_fileOutPrintf (idl_fileCur(), " to->%s._maximum = (uint32_t)(*src).maximum();\n", cid); idl_fileOutPrintf (idl_fileCur(), " to->%s._length = length0;\n", cid); idl_fileOutPrintf (idl_fileCur(), " to->%s._buffer = (uint8_t *)dest0;\n", cid); idl_fileOutPrintf (idl_fileCur(), " to->%s._release = false;\n", cid); } -#endif idl_fileOutPrintf (idl_fileCur(), " }\n"); } else { /* TODO: bounded sequences */ @@ -506,39 +448,6 @@ idl_structureMemberOpenClose ( os_free(cid); } -#if 0 -/** @brief Generate the array dimensions. - * - * Generate the dimensions of the array: - * @verbatim - [][]..[] - @endverbatim - * - * @param typeArray The type specification for the array which holds - * the basic type as wel as the size for each dimension. The first dimension - * is on top of that stack. - */ -static void -idl_arrayDimensions ( - idl_typeArray typeArray, - os_boolean resolveTypedefs) -{ - idl_typeSpec subType; - - idl_fileOutPrintf (idl_fileCur(), "[%d]", idl_typeArraySize(typeArray)); - subType = idl_typeArrayType(typeArray); - while(resolveTypedefs && idl_typeSpecType(subType) == idl_ttypedef) - { - subType = idl_typeDefResolveFully(subType); - } - /* QAC EXPECT 3416; No side effect here */ - if (idl_typeSpecType(subType) == idl_tarray) { - /* QAC EXPECT 3670; Recursive calls is a good practice, the recursion depth is limited here */ - idl_arrayDimensions (idl_typeArray(subType), resolveTypedefs); - } -} -#endif - /** @brief Generate the loop variables for the array copy. * * Generate the loop variables for the array copy. Per dimension a @@ -725,7 +634,7 @@ idl_arrayLoopCopyBody( idl_typeSpec nextType; c_ulong maxlen; c_long total_indent; - + char* scopedTypeName = idl_scopedTypeName(typeSpec); loopIndent++; switch (idl_typeSpecType(typeSpec)) { case idl_tstruct: @@ -734,11 +643,11 @@ idl_arrayLoopCopyBody( IDL_PRINTLINE (loopIndent + indent); idl_printIndent(loopIndent + indent); idl_fileOutPrintf(idl_fileCur(), "extern void __%s__copyIn(const void *, void *)\n\n", - idl_scopedTypeName(typeSpec)); + scopedTypeName); idl_printIndent (loopIndent + indent); idl_fileOutPrintf (idl_fileCur(),"__%s__copyIn(&(%s)", - idl_scopedTypeName(typeSpec), from); + scopedTypeName, from); idl_arrayLoopCopyIndex(typeArray); idl_fileOutPrintf (idl_fileCur(), ", &(%s)", to); idl_arrayLoopCopyIndex(typeArray); @@ -760,11 +669,6 @@ idl_arrayLoopCopyBody( idl_fileOutPrintf(idl_fileCur(), " = dds_string_dup(((%s))", from); idl_arrayLoopCopyIndex(typeArray); idl_fileOutPrintf(idl_fileCur(), ");\n"); -#if 0 - idl_fileOutPrintf(idl_fileCur(), " = (char *)(%s)", from); - idl_arrayLoopCopyIndex(typeArray); - idl_fileOutPrintf(idl_fileCur(), ".in();\n"); -#endif } else { /* TODO: support bounded strings */ } @@ -777,10 +681,10 @@ idl_arrayLoopCopyBody( IDL_PRINTLINE (loopIndent + indent-1); idl_printIndent (loopIndent + indent); idl_fileOutPrintf(idl_fileCur(), "extern void __%s__copyIn(const void *, void *)\n\n", - idl_scopedTypeName(typeSpec)); + scopedTypeName); idl_printIndent(loopIndent + indent); idl_fileOutPrintf (idl_fileCur(),"__%s__copyIn(&(%s)", - idl_scopedTypeName(typeSpec), + scopedTypeName, from); idl_arrayLoopCopyIndex(typeArray); idl_fileOutPrintf (idl_fileCur(), ", &(%s)", @@ -795,14 +699,14 @@ idl_arrayLoopCopyBody( IDL_PRINTLINE (loopIndent + indent-1); idl_printIndent (loopIndent + indent); idl_fileOutPrintf(idl_fileCur(), "extern void __%s__copyIn(", - idl_scopedTypeName(typeSpec)); + scopedTypeName); idl_fileOutPrintf(idl_fileCur(), "const %s *,", idl_scopeStack(idl_typeUserScope(idl_typeUser(typeSpec)), "::", idl_typeSpecName(typeSpec))); idl_fileOutPrintf(idl_fileCur(), "%s *);\n\n", idl_scopedLiteTypeName(typeSpec)); idl_printIndent(loopIndent + indent); idl_fileOutPrintf (idl_fileCur(),"__%s__copyIn((%s *)&(%s)", - idl_scopedTypeName(typeSpec), + scopedTypeName, idl_corbaCxxTypeFromTypeSpec(typeSpec), from); idl_arrayLoopCopyIndex(typeArray); @@ -833,11 +737,6 @@ idl_arrayLoopCopyBody( idl_fileOutPrintf(idl_fileCur(), " = dds_string_dup((%s)", from); idl_arrayLoopCopyIndex(typeArray); idl_fileOutPrintf(idl_fileCur(), ");\n"); -#if 0 - idl_fileOutPrintf(idl_fileCur(), " = (char *)(%s)", from); - idl_arrayLoopCopyIndex(typeArray); - idl_fileOutPrintf(idl_fileCur(), ".in();\n"); -#endif } else { /* TODO: support bounded strings */ } @@ -871,12 +770,8 @@ idl_arrayLoopCopyBody( idl_arrayLoopCopyIndex(typeArray); idl_fileOutPrintf (idl_fileCur(), ".length();\n"); idl_printIndent (total_indent); -#if 0 - idl_fileOutPrintf (idl_fileCur(), " dest0 = %s_allocbuf(length0)\n", idl_scopedLiteTypeName(typeSpec)); -#else idl_fileOutPrintf (idl_fileCur(), " dest0 = %s;\n", idl_seqAllocBuffer(idl_typeSeq(typeSpec), "length0", buffer, sizeof(buffer))); -#endif idl_seqLoopCopy (scope, nextType, source, "dest0", 1, loopIndent+1, userData); idl_printIndent (total_indent); idl_fileOutPrintf (idl_fileCur(), " (%s)", to); @@ -899,75 +794,6 @@ idl_arrayLoopCopyBody( idl_arrayLoopCopyIndex(typeArray); idl_fileOutPrintf (idl_fileCur(), "._release = false;\n"); -#if 0 - if (((idl_typeSpecType(nextType) == idl_tbasic) && - (idl_typeBasicType(idl_typeBasic(nextType)) != idl_string)) || - (idl_typeSpecType(nextType) == idl_tenum)) { - IDL_PRINTLINE (total_indent); - idl_printIndent (total_indent); - idl_fileOutPrintf (idl_fileCur(), " (%s)", to); - idl_arrayLoopCopyIndex(typeArray); - idl_fileOutPrintf (idl_fileCur(), "._maximum = (uint32_t)(%s)", from); - idl_arrayLoopCopyIndex(typeArray); - idl_fileOutPrintf (idl_fileCur(), ".maximum();\n"); - idl_printIndent (total_indent); - idl_fileOutPrintf (idl_fileCur(), " (%s)", to); - idl_arrayLoopCopyIndex(typeArray); - idl_fileOutPrintf (idl_fileCur(), "._length = (uint32_t)(%s)", from); - idl_arrayLoopCopyIndex(typeArray); - idl_fileOutPrintf (idl_fileCur(), ".length();\n"); - idl_printIndent (total_indent); - idl_fileOutPrintf (idl_fileCur(), " (%s)", to); - idl_arrayLoopCopyIndex(typeArray); - idl_fileOutPrintf (idl_fileCur(), "._buffer = (uint8_t *)(%s)", from); - idl_arrayLoopCopyIndex(typeArray); - idl_fileOutPrintf (idl_fileCur(), ".get_buffer();\n"); - idl_printIndent (total_indent); - idl_fileOutPrintf (idl_fileCur(), " (%s)", to); - idl_arrayLoopCopyIndex(typeArray); - idl_fileOutPrintf (idl_fileCur(), "._release = false;\n"); - } else { - char source[256]; - - snprintf(source, sizeof(source), "(%s)", from); - idl_arrayLoopCopyIndexString(source, typeArray); - - IDL_PRINTLINE (total_indent); - idl_printIndent (total_indent); - idl_fileOutPrintf (idl_fileCur(), " uint32_t length0;\n"); - - idl_printIndent (total_indent); - idl_fileOutPrintf (idl_fileCur(), " %s *dest0;\n\n", - idl_scopedLiteTypeName(nextType)); - idl_printIndent (total_indent); - idl_fileOutPrintf (idl_fileCur(), " length0 = (uint32_t)(%s)", from); - idl_arrayLoopCopyIndex(typeArray); - idl_fileOutPrintf (idl_fileCur(), ".length();\n", from); - idl_printIndent (total_indent); - idl_fileOutPrintf (idl_fileCur(), " dest0 = %s_allocbuf(length0)\n", idl_scopedLiteTypeName(typeSpec)); - idl_seqLoopCopy (scope, nextType, source, "dest0", 1, loopIndent, userData); - idl_printIndent (total_indent); - idl_fileOutPrintf (idl_fileCur(), " (%s)", to); - idl_arrayLoopCopyIndex(typeArray); - idl_fileOutPrintf (idl_fileCur(), "._maximum = (uint32_t)(%s)", from); - idl_arrayLoopCopyIndex(typeArray); - idl_fileOutPrintf (idl_fileCur(), ".maximum();\n"); - idl_printIndent (total_indent); - idl_fileOutPrintf (idl_fileCur(), " (%s)", to); - idl_arrayLoopCopyIndex(typeArray); - idl_fileOutPrintf (idl_fileCur(), "._length = (uint32_t)(%s)", from); - idl_arrayLoopCopyIndex(typeArray); - idl_fileOutPrintf (idl_fileCur(), ".length();\n", to); - idl_printIndent (total_indent); - idl_fileOutPrintf (idl_fileCur(), " (%s)", to); - idl_arrayLoopCopyIndex(typeArray); - idl_fileOutPrintf (idl_fileCur(), "._buffer = (uint8_t *)dest0;\n", to); - idl_printIndent (total_indent); - idl_fileOutPrintf (idl_fileCur(), " (%s)", to); - idl_arrayLoopCopyIndex(typeArray); - idl_fileOutPrintf (idl_fileCur(), "._release = false;\n"); - } -#endif } else { /* TODO: bounded sequences */ } @@ -979,6 +805,7 @@ idl_arrayLoopCopyBody( } loopIndent--; /* QAC EXPECT 5101, 5103: Complexity is limited, by independent cases, per case the number of lines is lower */ + os_free(scopedTypeName); } /** @brief Generate array loop copy closing code. @@ -1240,7 +1067,8 @@ idl_seqLoopCopy ( c_char *scopedName; idl_typeSpec nextType; c_ulong maxlen; - + char* scopedTypeName = idl_scopedTypeName(typeSpec); + if (idl_isContiguous(idl_typeSpecDef(typeSpec))) { idl_printIndent (indent); idl_fileOutPrintf (idl_fileCur(), "{\n"); @@ -1303,13 +1131,6 @@ idl_seqLoopCopy ( loop_index-1, from, idl_seqIndex(loop_index)); -#if 0 - idl_fileOutPrintf (idl_fileCur(), " %s[j%d] = (%s)%s.in();\n", - to, - loop_index-1, - from, - idl_seqIndex(loop_index)); -#endif } } break; @@ -1318,10 +1139,10 @@ idl_seqLoopCopy ( varIndex = 0; idl_printIndent (indent); idl_fileOutPrintf (idl_fileCur(), " extern void __%s__copyIn(const void *, void *);\n", - idl_scopedTypeName(typeSpec)); + scopedTypeName); idl_printIndent (indent); idl_fileOutPrintf (idl_fileCur(), " __%s__copyIn(&(%s)%s, (%s *)&%s[j%d]);\n", - idl_scopedTypeName(typeSpec), + scopedTypeName, from, idl_seqIndex(loop_index), idl_scopedLiteTypeName(typeSpec), @@ -1341,7 +1162,7 @@ idl_seqLoopCopy ( idl_scopedTypeName (typeSpec)); idl_printIndent (indent); idl_fileOutPrintf (idl_fileCur(), " __%s__copyIn(&(%s)%s, (%s *)&%s[j%d]);\n", - idl_scopedTypeName(typeSpec), + scopedTypeName, from, idl_seqIndex(loop_index), idl_scopedLiteTypeName(typeSpec), @@ -1394,17 +1215,11 @@ idl_seqLoopCopy ( free(scopedName); idl_printIndent (indent); idl_fileOutPrintf (idl_fileCur(), " length%d = (uint32_t)(%s)%s.length();\n", loop_index, from, idl_seqIndex(loop_index)); -#if 0 - idl_printIndent (indent); - idl_fileOutPrintf (idl_fileCur(), " dest%d = (%s *)%s_allocbuf(length%d);\n", - loop_index, scopedName, idl_scopedLiteTypeName(typeSpec), loop_index); -#else idl_printIndent (indent); sprintf(length, "length%d", loop_index); idl_fileOutPrintf (idl_fileCur(), " dest%d = %s;\n", loop_index, idl_seqAllocBuffer(idl_typeSeq(typeSpec), length, buffer, sizeof(buffer))); -#endif idl_seqLoopCopy (scope, nextType, from, destin, loop_index+1, indent+1, userData); idl_printIndent (indent); idl_fileOutPrintf (idl_fileCur(), " dest%d[j%d]._length = length%d;\n", @@ -1428,6 +1243,7 @@ idl_seqLoopCopy ( idl_fileOutPrintf (idl_fileCur(), " }\n"); idl_printIndent (indent); idl_fileOutPrintf (idl_fileCur(), "}\n"); + os_free(scopedTypeName); } /** @brief Function that set up the sequence copy context for a typedef. @@ -1478,80 +1294,13 @@ idl_seqElements ( idl_fileOutPrintf (idl_fileCur(), " %s *dest0;\n", scopedName); idl_fileOutPrintf (idl_fileCur(), " uint32_t length0;\n\n"); idl_fileOutPrintf (idl_fileCur(), " length0 = (uint32_t)(*src).length();\n"); -#if 0 - idl_fileOutPrintf (idl_fileCur(), " dest0 = %s_allocbuf(length0);\n", idl_scopedLiteTypeName(idl_typeSpec(typeDef))); -#else idl_fileOutPrintf (idl_fileCur(), " dest0 = %s;\n", idl_seqAllocBuffer(typeSeq, "length0", buffer, sizeof(buffer))); -#endif idl_seqLoopCopy (scope, nextType, "*src", "dest0", 1, 2, userData); idl_fileOutPrintf (idl_fileCur(), " to->_maximum = (uint32_t)(*src).maximum();\n"); idl_fileOutPrintf (idl_fileCur(), " to->_length = length0;\n"); idl_fileOutPrintf (idl_fileCur(), " to->_buffer = dest0;\n"); idl_fileOutPrintf (idl_fileCur(), " to->_release = false;\n"); - - -#if 0 - if (idl_typeSpecType(nextType) == idl_tbasic) { - if (idl_typeBasicType(idl_typeBasic(nextType)) == idl_string) { - idl_fileOutPrintf (idl_fileCur(), " %s *dest0;\n", scopedName); - idl_fileOutPrintf (idl_fileCur(), " uint32_t length0;\n\n"); - idl_fileOutPrintf (idl_fileCur(), " length0 = (uint32_t)(*src).length();\n"); - idl_fileOutPrintf (idl_fileCur(), " dest0 = %s_allocbuf(length0);\n", idl_scopedLiteTypeName(idl_typeSpec(typeDef))); - idl_seqLoopCopy (scope, nextType, "*src", "dest0", 1, 2, userData); - idl_fileOutPrintf (idl_fileCur(), " to->_maximum = (uint32_t)(*src).maximum();\n"); - idl_fileOutPrintf (idl_fileCur(), " to->_length = (uint32_t)(*src).length();\n"); - idl_fileOutPrintf (idl_fileCur(), " to->_buffer = dest0;\n"); - idl_fileOutPrintf (idl_fileCur(), " to->_release = false;\n"); - } else { - idl_fileOutPrintf (idl_fileCur(), " to->_maximum = (uint32_t)(*src).maximum();\n"); - idl_fileOutPrintf (idl_fileCur(), " to->_length = (uint32_t)(*src).length();\n"); - idl_fileOutPrintf (idl_fileCur(), " to->_buffer = (*src).get_buffer();\n"); - idl_fileOutPrintf (idl_fileCur(), " to->_release = false;\n"); - } - } else if (idl_typeSpecType(nextType) == idl_tenum) { - idl_fileOutPrintf (idl_fileCur(), "\n"); - idl_fileOutPrintf (idl_fileCur(), " to->_maximum = (uint32_t)(*src).maximum();\n"); - idl_fileOutPrintf (idl_fileCur(), " to->_length = (uint32_t)(*src).length();\n"); - idl_fileOutPrintf (idl_fileCur(), " to->_buffer = (*src).get_buffer();\n"); - idl_fileOutPrintf (idl_fileCur(), " to->_release = false;\n"); - } else if (idl_typeSpecType(nextType) == idl_tstruct) { - idl_fileOutPrintf (idl_fileCur(), " %s *dest0;\n", scopedName); - idl_fileOutPrintf (idl_fileCur(), " uint32_t length0;\n\n"); - idl_fileOutPrintf (idl_fileCur(), " length0 = (uint32_t)(*src).length();\n"); - idl_fileOutPrintf (idl_fileCur(), " dest0 = %s_allocbuf(length0);\n", idl_scopedLiteTypeName(idl_typeSpec(typeDef))); - idl_seqLoopCopy (scope, nextType, "*src", "dest0", 1, 2, userData); - idl_fileOutPrintf (idl_fileCur(), " to->_maximum = (uint32_t)(*src).maximum();\n"); - idl_fileOutPrintf (idl_fileCur(), " to->_length = length0;\n"); - idl_fileOutPrintf (idl_fileCur(), " to->_buffer = dest0;\n"); - idl_fileOutPrintf (idl_fileCur(), " to->_release = false;\n"); - } else if (idl_typeSpecType(nextType) == idl_ttypedef) { - idl_fileOutPrintf (idl_fileCur(), " %s *dest0;\n", scopedName); - idl_fileOutPrintf (idl_fileCur(), " uint32_t length0;\n\n"); - - idl_fileOutPrintf (idl_fileCur(), " length0 = (uint32_t)(*src).length();\n"); - idl_fileOutPrintf (idl_fileCur(), " dest0 = %s_allocbuf(length0);\n", idl_scopedLiteTypeName(idl_typeSpec(typeDef))); - idl_seqLoopCopy (scope, nextType, "*src", "dest0", 1, 2, userData); - idl_fileOutPrintf (idl_fileCur(), " to->_maximum = (uint32_t)(*src).maximum();\n"); - idl_fileOutPrintf (idl_fileCur(), " to->_length = length0;\n"); - idl_fileOutPrintf (idl_fileCur(), " to->_buffer = dest0;\n"); - idl_fileOutPrintf (idl_fileCur(), " to->_release = false;\n"); - } else if (idl_typeSpecType(nextType) == idl_tseq) { - idl_fileOutPrintf (idl_fileCur(), " %s *dest0;\n", idl_scopedLiteTypeName(idl_typeSpec(typeSeq))); - idl_fileOutPrintf (idl_fileCur(), " uint32_t length0;\n\n"); - - idl_fileOutPrintf (idl_fileCur(), " length0 = (uint32_t)(*src).length();\n"); - idl_fileOutPrintf (idl_fileCur(), " dest0 = %s_allocbuf(length0);\n", idl_scopedLiteTypeName(idl_typeSpec(typeDef))); - idl_seqLoopCopy (scope, nextType, "*src", "dest0", 1, 2, userData); - idl_fileOutPrintf (idl_fileCur(), " to->_maximum = (uint32_t)(*src).maximum();\n"); - idl_fileOutPrintf (idl_fileCur(), " to->_length = length0;\n"); - idl_fileOutPrintf (idl_fileCur(), " to->_buffer = dest0;\n"); - idl_fileOutPrintf (idl_fileCur(), " to->_release = false;\n"); - } else { - /* Do nothing, only to prevent dangling else-ifs QAC reports */ - } -#endif - idl_fileOutPrintf (idl_fileCur(), " }\n"); } else { /* TODO: bounded sequences */ diff --git a/src/tools/idlpp/code/idl_genLiteCxxCopyin.h b/src/tools/idlpp/code/idl_genLiteCxxCopyin.h index 9d21247f7..79d9cb02e 100644 --- a/src/tools/idlpp/code/idl_genLiteCxxCopyin.h +++ b/src/tools/idlpp/code/idl_genLiteCxxCopyin.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/idlpp/code/idl_genLiteCxxCopyout.c b/src/tools/idlpp/code/idl_genLiteCxxCopyout.c index b8ac72d1b..f9186bca6 100644 --- a/src/tools/idlpp/code/idl_genLiteCxxCopyout.c +++ b/src/tools/idlpp/code/idl_genLiteCxxCopyout.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -45,9 +46,9 @@ /** Text indentation level (4 spaces per indent) */ static c_long loopIndent; - /** Index for array loop variables, incremented for each array dimension */ +/** Index for array loop variables, incremented for each array dimension */ static c_long varIndex; - /** Indicates if the generation of a type should be skipped until the following type */ +/** Indicates if the generation of a type should be skipped until the following type */ static c_bool skip; @@ -440,10 +441,6 @@ idl_structureMemberOpenClose( idl_corbaCxxTypeFromTypeSpec(typeSpec), idl_cxxId(name)); /* QAC EXPECT 3416; No side effect here */ -#if 0 - } else if ((idl_typeSpecType(typeSpec) == idl_tstruct) || - (idl_typeSpecType(typeSpec) == idl_tunion)) { -#endif } else if (idl_typeSpecType(typeSpec) == idl_tstruct) { IDL_PRINTLINE(indent); idl_printIndent(indent); @@ -477,8 +474,6 @@ idl_structureMemberOpenClose( snprintf(sname, sizeof(sname), "_%s_seq", idl_cxxId(name)); idl_fileOutPrintf (idl_fileCur(), " typedef %s _SrcType", tmp_string); -// idl_fileOutPrintf (idl_fileCur(), " typedef %s _SrcType", -// idl_scopeStack(idl_typeUserScope(idl_typeUser(subType)), "::", sname)); } else { idl_fileOutPrintf (idl_fileCur(), " typedef %s _SrcType", tmp_string); } diff --git a/src/tools/idlpp/code/idl_genLiteCxxCopyout.h b/src/tools/idlpp/code/idl_genLiteCxxCopyout.h index ccaabcac7..371add8cf 100644 --- a/src/tools/idlpp/code/idl_genLiteCxxCopyout.h +++ b/src/tools/idlpp/code/idl_genLiteCxxCopyout.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/idlpp/code/idl_genLiteHelper.c b/src/tools/idlpp/code/idl_genLiteHelper.c index 9cad67904..b009a5f09 100644 --- a/src/tools/idlpp/code/idl_genLiteHelper.c +++ b/src/tools/idlpp/code/idl_genLiteHelper.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/idlpp/code/idl_genLiteHelper.h b/src/tools/idlpp/code/idl_genLiteHelper.h index f918bec62..052601284 100644 --- a/src/tools/idlpp/code/idl_genLiteHelper.h +++ b/src/tools/idlpp/code/idl_genLiteHelper.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/idlpp/code/idl_genLiteISOCxxCopyin.c b/src/tools/idlpp/code/idl_genLiteISOCxxCopyin.c index cfb704e49..12ef0264e 100644 --- a/src/tools/idlpp/code/idl_genLiteISOCxxCopyin.c +++ b/src/tools/idlpp/code/idl_genLiteISOCxxCopyin.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -43,7 +44,7 @@ /** Text indentation level (4 spaces per indent) */ static c_long loopIndent; - /** Index for array loop variables, incremented for each array dimension */ +/** Index for array loop variables, incremented for each array dimension */ static c_long varIndex; static c_char * @@ -169,12 +170,14 @@ idl_structureOpen ( idl_typeStruct structSpec, void *userData) { + char *scopeStack = idl_scopeStack(scope, "_", name); + char *scopeStackCxx = idl_scopeStackCxx (scope, "::", name); OS_UNUSED_ARG(structSpec); OS_UNUSED_ARG(userData); - + idl_fileOutPrintf (idl_fileCur(), "void\n"); idl_fileOutPrintf (idl_fileCur(), "__%s__copyIn(\n", - idl_scopeStack (scope, "_", name)); + scopeStack); idl_fileOutPrintf (idl_fileCur(), " const void *_from,\n"); idl_fileOutPrintf (idl_fileCur(), " void *_to)\n"); @@ -183,16 +186,18 @@ idl_structureOpen ( idl_fileOutPrintf (idl_fileCur(), "{\n"); idl_fileOutPrintf (idl_fileCur(), " const class %s *from;\n", - idl_scopeStackCxx (scope, "::", name)); + scopeStackCxx); idl_fileOutPrintf (idl_fileCur(), " %s *to;\n\n", - idl_scopeStack(scope, "_", name)); + scopeStack); idl_fileOutPrintf (idl_fileCur(), " from = (const class %s *)_from;\n", - idl_scopeStackCxx (scope, "::", name)); + scopeStackCxx); idl_fileOutPrintf (idl_fileCur(), " to = (%s *)_to;\n\n", - idl_scopeStack(scope, "_", name)); + scopeStack); + os_free(scopeStack); + os_free(scopeStackCxx); return idl_explore; @@ -278,19 +283,11 @@ idl_basicMemberType ( case idl_string: maxlen = idl_typeBasicMaxlen(typeBasic); if (maxlen == 0) { -#if 0 - idl_fileOutPrintf(idl_fileCur(), " %s%s = dds_string_dup(%s%s);\n", - to_id, - cid, - from_id, - cid); -#else idl_fileOutPrintf(idl_fileCur(), " %s%s = (char *)((%s%s()).c_str());\n", to_id, cid, from_id, cid); -#endif } else { /* TODO: bounded strings */ @@ -347,7 +344,7 @@ idl_structureMemberOpenClose ( c_char *scopedName; c_char* cid; c_long indent = 1; - + char *scopedTypeName = idl_scopedTypeName (typeSpec); cid = idl_cxxId(name); /* Expected types: idl_tbasic, idl_ttypedef, idl_tenum, idl_tstruct, idl_tunion, idl_tarray, idl_tseq */ @@ -365,12 +362,12 @@ idl_structureMemberOpenClose ( IDL_PRINTLINE (indent); tmp_string = idl_corbaCxxTypeFromTypeSpec(typeSpec); idl_fileOutPrintf (idl_fileCur(), " extern void __%s__copyIn(const %s *, %s *);\n", - idl_scopedTypeName (typeSpec), + scopedTypeName, tmp_string, idl_scopedLiteTypeName (typeSpec)); free(tmp_string); idl_fileOutPrintf (idl_fileCur(), " __%s__copyIn(&from->%s(), &to->%s);\n", - idl_scopedTypeName (typeSpec), + scopedTypeName, cid, cid); idl_fileOutPrintf (idl_fileCur(), " }\n"); @@ -388,16 +385,16 @@ idl_structureMemberOpenClose ( } else if (idl_typeSpecType(typeSpec) == idl_tenum) { idl_fileOutPrintf (idl_fileCur(), " to->%s = (%s)from->%s();\n", cid, - idl_scopedTypeName (typeSpec), + scopedTypeName, cid); /* QAC EXPECT 3416; No side effect here */ } else if (idl_typeSpecType(typeSpec) == idl_tstruct) { idl_fileOutPrintf (idl_fileCur(), " {\n"); IDL_PRINTLINE (indent); idl_fileOutPrintf (idl_fileCur(), " extern void __%s__copyIn(const void *, void *);\n", - idl_scopedTypeName (typeSpec)); + scopedTypeName); idl_fileOutPrintf (idl_fileCur(), " __%s__copyIn(&from->%s, &to->%s);\n", - idl_scopedTypeName (typeSpec), + scopedTypeName, cid, cid); idl_fileOutPrintf (idl_fileCur(), " }\n"); @@ -415,18 +412,6 @@ idl_structureMemberOpenClose ( snprintf(src, (size_t)sizeof(src), "from->%s()", name); idl_fileOutPrintf (idl_fileCur(), " {\n"); IDL_PRINTLINE (indent); -#if 0 - if (idl_typeSpecType(subType) == idl_tseq) { - c_char sname[32]; - snprintf(sname, (size_t) sizeof(sname), "_%s", cid); - idl_fileOutPrintf (idl_fileCur(), " typedef const %s _SrcType", - idl_scopeStack(idl_typeUserScope(idl_typeUser(subType)), "::", sname)); - //idl_arrayDimensions (idl_typeArray(typeSpec), OS_FALSE); - idl_fileOutPrintf (idl_fileCur(), ";\n"); - idl_fileOutPrintf (idl_fileCur(), " _SrcType *src = &from->%s;\n", cid); - } -#endif - idl_arrayElements (scope, idl_typeArray(typeSpec), src, dest, FALSE, indent, userData); idl_fileOutPrintf (idl_fileCur(), " }\n"); @@ -442,49 +427,32 @@ idl_structureMemberOpenClose ( maxlen = idl_typeSeqMaxSize(idl_typeSeq(typeSpec)); if (maxlen == 0) { + char * scopeStackCxx = idl_scopeStackCxx (scope, "::", type_name); idl_fileOutPrintf (idl_fileCur(), " {\n"); -#if 0 - IDL_PRINTLINE (indent); - idl_fileOutPrintf (idl_fileCur(), " const %s *src = &from->%s;\n", idl_scopeStackCxx (scope, "::", type_name), cid); - idl_fileOutPrintf (idl_fileCur(), " %s *dest0;\n", scopedName); - idl_fileOutPrintf (idl_fileCur(), " uint32_t length0;\n\n"); - idl_fileOutPrintf (idl_fileCur(), " length0 = (uint32_t)(*src).length();\n"); - idl_fileOutPrintf (idl_fileCur(), " dest0 = %s_allocbuf(length0);\n", idl_scopedLiteTypeName(typeSpec)); - idl_seqLoopCopy (scope, nextType, "*src", "dest0", 1, 2, userData); - idl_fileOutPrintf (idl_fileCur(), " to->%s._maximum = (uint32_t)(*src).maximum();\n", cid); - idl_fileOutPrintf (idl_fileCur(), " to->%s._length = length0;\n", cid); - idl_fileOutPrintf (idl_fileCur(), " to->%s._buffer = (uint8_t *)dest0;\n", cid); - idl_fileOutPrintf (idl_fileCur(), " to->%s._release = false;\n", cid); -#endif -#if 1 if (((idl_typeSpecType(nextType) == idl_tbasic) && (idl_typeBasicType(idl_typeBasic(nextType)) != idl_string)) || (idl_typeSpecType(nextType) == idl_tenum)) { IDL_PRINTLINE (indent); - idl_fileOutPrintf (idl_fileCur(), " const %s *src = &from->%s();\n\n", idl_scopeStackCxx (scope, "::", type_name), cid); + idl_fileOutPrintf (idl_fileCur(), " const %s *src = &from->%s();\n\n", scopeStackCxx, cid); idl_fileOutPrintf (idl_fileCur(), " to->%s._maximum = (uint32_t)(*src).max_size();\n", cid); idl_fileOutPrintf (idl_fileCur(), " to->%s._length = (uint32_t)(*src).size();\n", cid); idl_fileOutPrintf (idl_fileCur(), " to->%s._buffer = (uint8_t *)&((*src)[0]);\n", cid); idl_fileOutPrintf (idl_fileCur(), " to->%s._release = false;\n", cid); } else { IDL_PRINTLINE (indent); - idl_fileOutPrintf (idl_fileCur(), " const %s *src = &from->%s();\n", idl_scopeStackCxx (scope, "::", type_name), cid); + idl_fileOutPrintf (idl_fileCur(), " const %s *src = &from->%s();\n", scopeStackCxx, cid); idl_fileOutPrintf (idl_fileCur(), " %s *dest0;\n", scopedName); idl_fileOutPrintf (idl_fileCur(), " uint32_t length0;\n\n"); idl_fileOutPrintf (idl_fileCur(), " length0 = (uint32_t)(*src).size();\n"); -#if 0 - idl_fileOutPrintf (idl_fileCur(), " dest0 = %s_allocbuf(length0);\n", idl_scopedLiteTypeName(typeSpec)); -#else idl_fileOutPrintf (idl_fileCur(), " dest0 = %s;\n", idl_seqAllocBuffer(idl_typeSeq(typeSpec), "length0", buffer, sizeof(buffer))); -#endif idl_seqLoopCopy (scope, nextType, "*src", "dest0", 1, 2, userData); idl_fileOutPrintf (idl_fileCur(), " to->%s._maximum = (uint32_t)(*src).max_size();\n", cid); idl_fileOutPrintf (idl_fileCur(), " to->%s._length = length0;\n", cid); idl_fileOutPrintf (idl_fileCur(), " to->%s._buffer = (uint8_t *)dest0;\n", cid); idl_fileOutPrintf (idl_fileCur(), " to->%s._release = false;\n", cid); } -#endif + os_free(scopeStackCxx); idl_fileOutPrintf (idl_fileCur(), " }\n"); } else { /* TODO: bounded sequences */ @@ -494,7 +462,7 @@ idl_structureMemberOpenClose ( /* Do nothing, only to prevent dangling else-ifs QAC reports */ } /* QAC EXPECT 5103; Code is clearly separated in a number of cases of which each is maintainable */ - + os_free(scopedTypeName); os_free(cid); } @@ -684,6 +652,8 @@ idl_arrayLoopCopyBody( idl_typeSpec nextType; c_long total_indent; c_ulong maxlen; + char *scopedLiteTypeName = idl_scopedLiteTypeName(typeSpec); + char *scopedTypeName = idl_scopedTypeName(typeSpec); loopIndent++; switch (idl_typeSpecType(typeSpec)) { @@ -693,11 +663,11 @@ idl_arrayLoopCopyBody( IDL_PRINTLINE (loopIndent + indent); idl_printIndent(loopIndent + indent); idl_fileOutPrintf(idl_fileCur(), "extern void __%s__copyIn(const void *, void *);\n\n", - idl_scopedTypeName(typeSpec)); + scopedTypeName); idl_printIndent (loopIndent + indent); idl_fileOutPrintf (idl_fileCur(),"__%s__copyIn(&(%s)", - idl_scopedTypeName(typeSpec), from); + scopedTypeName, from); idl_arrayLoopCopyIndex(typeArray); idl_fileOutPrintf (idl_fileCur(), ", &(%s)", to); idl_arrayLoopCopyIndex(typeArray); @@ -719,11 +689,6 @@ idl_arrayLoopCopyBody( idl_fileOutPrintf(idl_fileCur(), " = dds_string_dup(((%s))", from); idl_arrayLoopCopyIndex(typeArray); idl_fileOutPrintf(idl_fileCur(), ");\n"); -#if 0 - idl_fileOutPrintf(idl_fileCur(), " = (char *)(%s)", from); - idl_arrayLoopCopyIndex(typeArray); - idl_fileOutPrintf(idl_fileCur(), ".in();\n"); -#endif } else { /* TODO: support bounded strings */ } @@ -736,10 +701,10 @@ idl_arrayLoopCopyBody( IDL_PRINTLINE (loopIndent + indent-1); idl_printIndent (loopIndent + indent); idl_fileOutPrintf(idl_fileCur(), "extern void __%s__copyIn(const void *, void *);\n\n", - idl_scopedTypeName(typeSpec)); + scopedTypeName); idl_printIndent(loopIndent + indent); idl_fileOutPrintf (idl_fileCur(),"__%s__copyIn(&(%s)", - idl_scopedTypeName(typeSpec), + scopedTypeName, from); idl_arrayLoopCopyIndex(typeArray); idl_fileOutPrintf (idl_fileCur(), ", &(%s)", @@ -754,19 +719,19 @@ idl_arrayLoopCopyBody( IDL_PRINTLINE (loopIndent + indent-1); idl_printIndent (loopIndent + indent); idl_fileOutPrintf(idl_fileCur(), "extern void __%s__copyIn(", - idl_scopedTypeName(typeSpec)); + scopedTypeName); idl_fileOutPrintf(idl_fileCur(), "const %s *,", idl_scopeStack(idl_typeUserScope(idl_typeUser(typeSpec)), "::", idl_typeSpecName(typeSpec))); idl_fileOutPrintf(idl_fileCur(), "%s *);\n\n", - idl_scopedLiteTypeName(typeSpec)); + scopedLiteTypeName); idl_printIndent(loopIndent + indent); idl_fileOutPrintf (idl_fileCur(),"__%s__copyIn((%s *)&(%s)", - idl_scopedTypeName(typeSpec), + scopedLiteTypeName, idl_corbaCxxTypeFromTypeSpec(typeSpec), from); idl_arrayLoopCopyIndex(typeArray); idl_fileOutPrintf (idl_fileCur(), ", (%s *)&(%s)", - idl_scopedLiteTypeName(typeSpec), + scopedLiteTypeName, to); idl_arrayLoopCopyIndex(typeArray); idl_fileOutPrintf (idl_fileCur(), ");\n"); @@ -792,11 +757,6 @@ idl_arrayLoopCopyBody( idl_fileOutPrintf(idl_fileCur(), " = dds_string_dup((%s)", from); idl_arrayLoopCopyIndex(typeArray); idl_fileOutPrintf(idl_fileCur(), ".c_str());\n"); -#if 0 - idl_fileOutPrintf(idl_fileCur(), " = (char *)(%s)", from); - idl_arrayLoopCopyIndex(typeArray); - idl_fileOutPrintf(idl_fileCur(), ".in();\n"); -#endif } else { /* TODO: support bounded strings */ } @@ -830,12 +790,8 @@ idl_arrayLoopCopyBody( idl_arrayLoopCopyIndex(typeArray); idl_fileOutPrintf (idl_fileCur(), ".length();\n"); idl_printIndent (total_indent); -#if 0 - idl_fileOutPrintf (idl_fileCur(), " dest0 = %s_allocbuf(length0)\n", idl_scopedLiteTypeName(typeSpec)); -#else idl_fileOutPrintf (idl_fileCur(), " dest0 = %s;\n", idl_seqAllocBuffer(idl_typeSeq(typeSpec), "length0", buffer, sizeof(buffer))); -#endif idl_seqLoopCopy (scope, nextType, source, "dest0", 1, loopIndent+1, userData); idl_printIndent (total_indent); idl_fileOutPrintf (idl_fileCur(), " (%s)", to); @@ -857,76 +813,6 @@ idl_arrayLoopCopyBody( idl_fileOutPrintf (idl_fileCur(), " (%s)", to); idl_arrayLoopCopyIndex(typeArray); idl_fileOutPrintf (idl_fileCur(), "._release = false;\n"); - -#if 0 - if (((idl_typeSpecType(nextType) == idl_tbasic) && - (idl_typeBasicType(idl_typeBasic(nextType)) != idl_string)) || - (idl_typeSpecType(nextType) == idl_tenum)) { - IDL_PRINTLINE (total_indent); - idl_printIndent (total_indent); - idl_fileOutPrintf (idl_fileCur(), " (%s)", to); - idl_arrayLoopCopyIndex(typeArray); - idl_fileOutPrintf (idl_fileCur(), "._maximum = (uint32_t)(%s)", from); - idl_arrayLoopCopyIndex(typeArray); - idl_fileOutPrintf (idl_fileCur(), ".maximum();\n"); - idl_printIndent (total_indent); - idl_fileOutPrintf (idl_fileCur(), " (%s)", to); - idl_arrayLoopCopyIndex(typeArray); - idl_fileOutPrintf (idl_fileCur(), "._length = (uint32_t)(%s)", from); - idl_arrayLoopCopyIndex(typeArray); - idl_fileOutPrintf (idl_fileCur(), ".length();\n"); - idl_printIndent (total_indent); - idl_fileOutPrintf (idl_fileCur(), " (%s)", to); - idl_arrayLoopCopyIndex(typeArray); - idl_fileOutPrintf (idl_fileCur(), "._buffer = (uint8_t *)(%s)", from); - idl_arrayLoopCopyIndex(typeArray); - idl_fileOutPrintf (idl_fileCur(), ".get_buffer();\n"); - idl_printIndent (total_indent); - idl_fileOutPrintf (idl_fileCur(), " (%s)", to); - idl_arrayLoopCopyIndex(typeArray); - idl_fileOutPrintf (idl_fileCur(), "._release = false;\n"); - } else { - char source[256]; - - snprintf(source, (size_t)sizeof(source), "(%s)", from); - idl_arrayLoopCopyIndexString(source, typeArray); - - IDL_PRINTLINE (total_indent); - idl_printIndent (total_indent); - idl_fileOutPrintf (idl_fileCur(), " uint32_t length0;\n"); - - idl_printIndent (total_indent); - idl_fileOutPrintf (idl_fileCur(), " %s *dest0;\n\n", - idl_scopedLiteTypeName(nextType)); - idl_printIndent (total_indent); - idl_fileOutPrintf (idl_fileCur(), " length0 = (uint32_t)(%s)", from); - idl_arrayLoopCopyIndex(typeArray); - idl_fileOutPrintf (idl_fileCur(), ".length();\n", from); - idl_printIndent (total_indent); - idl_fileOutPrintf (idl_fileCur(), " dest0 = %s_allocbuf(length0)\n", idl_scopedLiteTypeName(typeSpec)); - idl_seqLoopCopy (scope, nextType, source, "dest0", 1, loopIndent, userData); - idl_printIndent (total_indent); - idl_fileOutPrintf (idl_fileCur(), " (%s)", to); - idl_arrayLoopCopyIndex(typeArray); - idl_fileOutPrintf (idl_fileCur(), "._maximum = (uint32_t)(%s)", from); - idl_arrayLoopCopyIndex(typeArray); - idl_fileOutPrintf (idl_fileCur(), ".maximum();\n"); - idl_printIndent (total_indent); - idl_fileOutPrintf (idl_fileCur(), " (%s)", to); - idl_arrayLoopCopyIndex(typeArray); - idl_fileOutPrintf (idl_fileCur(), "._length = (uint32_t)(%s)", from); - idl_arrayLoopCopyIndex(typeArray); - idl_fileOutPrintf (idl_fileCur(), ".length();\n", to); - idl_printIndent (total_indent); - idl_fileOutPrintf (idl_fileCur(), " (%s)", to); - idl_arrayLoopCopyIndex(typeArray); - idl_fileOutPrintf (idl_fileCur(), "._buffer = (uint8_t *)dest0;\n", to); - idl_printIndent (total_indent); - idl_fileOutPrintf (idl_fileCur(), " (%s)", to); - idl_arrayLoopCopyIndex(typeArray); - idl_fileOutPrintf (idl_fileCur(), "._release = false;\n"); - } -#endif } else { /* TODO: bounded sequences */ } @@ -938,6 +824,8 @@ idl_arrayLoopCopyBody( } loopIndent--; /* QAC EXPECT 5101, 5103: Complexity is limited, by independent cases, per case the number of lines is lower */ + os_free(scopedTypeName); + os_free(scopedLiteTypeName); } /** @brief Generate array loop copy closing code. @@ -1199,17 +1087,18 @@ idl_seqLoopCopy ( c_char *scopedName; idl_typeSpec nextType; c_ulong maxlen; - + char * scopedLiteTypeName = idl_scopedLiteTypeName(typeSpec); + char * scopedTypeName = idl_scopedTypeName(typeSpec); if (idl_isContiguous(idl_typeSpecDef(typeSpec))) { idl_printIndent (indent); idl_fileOutPrintf (idl_fileCur(), "{\n"); IDL_PRINTLINE (indent); idl_printIndent (indent); idl_fileOutPrintf (idl_fileCur(), " const %s *buf%d;\n", - idl_scopedLiteTypeName(typeSpec),loop_index-1); + scopedLiteTypeName,loop_index-1); idl_printIndent (indent); idl_fileOutPrintf (idl_fileCur(), " buf%d = (const %s *)(%s)%s.data();\n", - loop_index-1, idl_scopedLiteTypeName(typeSpec), from, idl_seqIndex (loop_index-1)); + loop_index-1, scopedLiteTypeName, from, idl_seqIndex (loop_index-1)); if(idl_typeSpecType (typeSpec) == idl_tenum){ idl_printIndent (indent); @@ -1246,7 +1135,7 @@ idl_seqLoopCopy ( idl_fileOutPrintf (idl_fileCur(), " %s[j%d] = (%s)(%s)%s;\n", to, loop_index-1, - idl_scopedLiteTypeName(typeSpec), + scopedLiteTypeName, from, idl_seqIndex(loop_index)); break; @@ -1278,13 +1167,13 @@ idl_seqLoopCopy ( varIndex = 0; idl_printIndent (indent); idl_fileOutPrintf (idl_fileCur(), " extern void __%s__copyIn(const void *, void *);\n", - idl_scopedTypeName(typeSpec)); + scopedTypeName); idl_printIndent (indent); idl_fileOutPrintf (idl_fileCur(), " __%s__copyIn(&(%s)%s, (%s *)&%s[j%d]);\n", - idl_scopedTypeName(typeSpec), + scopedTypeName, from, idl_seqIndex(loop_index), - idl_scopedLiteTypeName(typeSpec), + scopedLiteTypeName, to, loop_index-1); break; @@ -1301,10 +1190,10 @@ idl_seqLoopCopy ( idl_scopedTypeName (typeSpec)); idl_printIndent (indent); idl_fileOutPrintf (idl_fileCur(), " __%s__copyIn(&(%s)%s, (%s *)&%s[j%d]);\n", - idl_scopedTypeName(typeSpec), + scopedTypeName, from, idl_seqIndex(loop_index), - idl_scopedLiteTypeName(typeSpec), + scopedLiteTypeName, to, loop_index-1); break; @@ -1315,7 +1204,7 @@ idl_seqLoopCopy ( idl_fileOutPrintf (idl_fileCur(), " %s[j%d] = (%s)(%s)%s;\n", to, loop_index-1, - idl_scopedLiteTypeName(typeSpec), + scopedLiteTypeName, from, idl_seqIndex(loop_index)); break; @@ -1356,17 +1245,11 @@ idl_seqLoopCopy ( idl_fileOutPrintf (idl_fileCur(), " %s *dest%d;\n\n", scopedName, loop_index); idl_printIndent (indent); idl_fileOutPrintf (idl_fileCur(), " length%d = (uint32_t)(%s)%s.size();\n", loop_index, from, idl_seqIndex(loop_index)); -#if 0 - idl_printIndent (indent); - idl_fileOutPrintf (idl_fileCur(), " dest%d = (%s *)%s_allocbuf(length%d);\n", - loop_index, scopedName, idl_scopedLiteTypeName(typeSpec), loop_index); -#else idl_printIndent (indent); sprintf(length, "length%d", loop_index); idl_fileOutPrintf (idl_fileCur(), " dest%d = %s;\n", loop_index, idl_seqAllocBuffer(idl_typeSeq(typeSpec), length, buffer, sizeof(buffer))); -#endif idl_seqLoopCopy (scope, nextType, from, destin, loop_index+1, indent+1, userData); idl_printIndent (indent); idl_fileOutPrintf (idl_fileCur(), " dest%d[j%d]._length = length%d;\n", @@ -1392,6 +1275,8 @@ idl_seqLoopCopy ( idl_fileOutPrintf (idl_fileCur(), " }\n"); idl_printIndent (indent); idl_fileOutPrintf (idl_fileCur(), "}\n"); + os_free(scopedLiteTypeName); + os_free(scopedTypeName); } /** @brief Function that set up the sequence copy context for a typedef. @@ -1445,12 +1330,8 @@ idl_seqElements ( idl_fileOutPrintf (idl_fileCur(), " %s *dest0;\n", scopedName); idl_fileOutPrintf (idl_fileCur(), " uint32_t length0;\n\n"); idl_fileOutPrintf (idl_fileCur(), " length0 = (uint32_t)(*src).size();\n"); -#if 0 - idl_fileOutPrintf (idl_fileCur(), " dest0 = %s_allocbuf(length0);\n", idl_scopedLiteTypeName(idl_typeSpec(typeDef))); -#else idl_fileOutPrintf (idl_fileCur(), " dest0 = %s;\n", idl_seqAllocBuffer(typeSeq, "length0", buffer, sizeof(buffer))); -#endif idl_seqLoopCopy (scope, nextType, "*src", "dest0", 1, 2, userData); idl_fileOutPrintf (idl_fileCur(), " to->_maximum = (uint32_t)(*src).max_size();\n"); idl_fileOutPrintf (idl_fileCur(), " to->_length = length0;\n"); @@ -1458,67 +1339,6 @@ idl_seqElements ( idl_fileOutPrintf (idl_fileCur(), " to->_release = false;\n"); -#if 0 - if (idl_typeSpecType(nextType) == idl_tbasic) { - if (idl_typeBasicType(idl_typeBasic(nextType)) == idl_string) { - idl_fileOutPrintf (idl_fileCur(), " %s *dest0;\n", scopedName); - idl_fileOutPrintf (idl_fileCur(), " uint32_t length0;\n\n"); - idl_fileOutPrintf (idl_fileCur(), " length0 = (uint32_t)(*src).length();\n"); - idl_fileOutPrintf (idl_fileCur(), " dest0 = %s_allocbuf(length0);\n", idl_scopedLiteTypeName(idl_typeSpec(typeDef))); - idl_seqLoopCopy (scope, nextType, "*src", "dest0", 1, 2, userData); - idl_fileOutPrintf (idl_fileCur(), " to->_maximum = (uint32_t)(*src).maximum();\n"); - idl_fileOutPrintf (idl_fileCur(), " to->_length = (uint32_t)(*src).length();\n"); - idl_fileOutPrintf (idl_fileCur(), " to->_buffer = dest0;\n"); - idl_fileOutPrintf (idl_fileCur(), " to->_release = false;\n"); - } else { - idl_fileOutPrintf (idl_fileCur(), " to->_maximum = (uint32_t)(*src).maximum();\n"); - idl_fileOutPrintf (idl_fileCur(), " to->_length = (uint32_t)(*src).length();\n"); - idl_fileOutPrintf (idl_fileCur(), " to->_buffer = (*src).get_buffer();\n"); - idl_fileOutPrintf (idl_fileCur(), " to->_release = false;\n"); - } - } else if (idl_typeSpecType(nextType) == idl_tenum) { - idl_fileOutPrintf (idl_fileCur(), "\n"); - idl_fileOutPrintf (idl_fileCur(), " to->_maximum = (uint32_t)(*src).maximum();\n"); - idl_fileOutPrintf (idl_fileCur(), " to->_length = (uint32_t)(*src).length();\n"); - idl_fileOutPrintf (idl_fileCur(), " to->_buffer = (*src).get_buffer();\n"); - idl_fileOutPrintf (idl_fileCur(), " to->_release = false;\n"); - } else if (idl_typeSpecType(nextType) == idl_tstruct) { - idl_fileOutPrintf (idl_fileCur(), " %s *dest0;\n", scopedName); - idl_fileOutPrintf (idl_fileCur(), " uint32_t length0;\n\n"); - idl_fileOutPrintf (idl_fileCur(), " length0 = (uint32_t)(*src).length();\n"); - idl_fileOutPrintf (idl_fileCur(), " dest0 = %s_allocbuf(length0);\n", idl_scopedLiteTypeName(idl_typeSpec(typeDef))); - idl_seqLoopCopy (scope, nextType, "*src", "dest0", 1, 2, userData); - idl_fileOutPrintf (idl_fileCur(), " to->_maximum = (uint32_t)(*src).maximum();\n"); - idl_fileOutPrintf (idl_fileCur(), " to->_length = length0;\n"); - idl_fileOutPrintf (idl_fileCur(), " to->_buffer = dest0;\n"); - idl_fileOutPrintf (idl_fileCur(), " to->_release = false;\n"); - } else if (idl_typeSpecType(nextType) == idl_ttypedef) { - idl_fileOutPrintf (idl_fileCur(), " %s *dest0;\n", scopedName); - idl_fileOutPrintf (idl_fileCur(), " uint32_t length0;\n\n"); - - idl_fileOutPrintf (idl_fileCur(), " length0 = (uint32_t)(*src).length();\n"); - idl_fileOutPrintf (idl_fileCur(), " dest0 = %s_allocbuf(length0);\n", idl_scopedLiteTypeName(idl_typeSpec(typeDef))); - idl_seqLoopCopy (scope, nextType, "*src", "dest0", 1, 2, userData); - idl_fileOutPrintf (idl_fileCur(), " to->_maximum = (uint32_t)(*src).maximum();\n"); - idl_fileOutPrintf (idl_fileCur(), " to->_length = length0;\n"); - idl_fileOutPrintf (idl_fileCur(), " to->_buffer = dest0;\n"); - idl_fileOutPrintf (idl_fileCur(), " to->_release = false;\n"); - } else if (idl_typeSpecType(nextType) == idl_tseq) { - idl_fileOutPrintf (idl_fileCur(), " %s *dest0;\n", idl_scopedLiteTypeName(idl_typeSpec(typeSeq))); - idl_fileOutPrintf (idl_fileCur(), " uint32_t length0;\n\n"); - - idl_fileOutPrintf (idl_fileCur(), " length0 = (uint32_t)(*src).length();\n"); - idl_fileOutPrintf (idl_fileCur(), " dest0 = %s_allocbuf(length0);\n", idl_scopedLiteTypeName(idl_typeSpec(typeDef))); - idl_seqLoopCopy (scope, nextType, "*src", "dest0", 1, 2, userData); - idl_fileOutPrintf (idl_fileCur(), " to->_maximum = (uint32_t)(*src).maximum();\n"); - idl_fileOutPrintf (idl_fileCur(), " to->_length = length0;\n"); - idl_fileOutPrintf (idl_fileCur(), " to->_buffer = dest0;\n"); - idl_fileOutPrintf (idl_fileCur(), " to->_release = false;\n"); - } else { - /* Do nothing, only to prevent dangling else-ifs QAC reports */ - } -#endif - idl_fileOutPrintf (idl_fileCur(), " }\n"); } else { /* TODO: bounded sequences */ diff --git a/src/tools/idlpp/code/idl_genLiteISOCxxCopyin.h b/src/tools/idlpp/code/idl_genLiteISOCxxCopyin.h index 5d5203108..b3df3f621 100644 --- a/src/tools/idlpp/code/idl_genLiteISOCxxCopyin.h +++ b/src/tools/idlpp/code/idl_genLiteISOCxxCopyin.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/idlpp/code/idl_genLiteISOCxxCopyout.c b/src/tools/idlpp/code/idl_genLiteISOCxxCopyout.c index 8b39de199..0bcffca10 100644 --- a/src/tools/idlpp/code/idl_genLiteISOCxxCopyout.c +++ b/src/tools/idlpp/code/idl_genLiteISOCxxCopyout.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -45,9 +46,9 @@ /** Text indentation level (4 spaces per indent) */ static c_long loopIndent; - /** Index for array loop variables, incremented for each array dimension */ +/** Index for array loop variables, incremented for each array dimension */ static c_long varIndex; - /** Indicates if the generation of a type should be skipped until the following type */ +/** Indicates if the generation of a type should be skipped until the following type */ static c_bool skip; @@ -438,10 +439,6 @@ idl_structureMemberOpenClose( idl_corbaCxxTypeFromTypeSpec(typeSpec), idl_cxxId(name)); /* QAC EXPECT 3416; No side effect here */ -#if 0 - } else if ((idl_typeSpecType(typeSpec) == idl_tstruct) || - (idl_typeSpecType(typeSpec) == idl_tunion)) { -#endif } else if (idl_typeSpecType(typeSpec) == idl_tstruct) { IDL_PRINTLINE(indent); idl_printIndent(indent); @@ -474,8 +471,6 @@ idl_structureMemberOpenClose( snprintf(sname, (size_t) sizeof(sname), "_%s_seq", idl_cxxId(name)); idl_fileOutPrintf (idl_fileCur(), " typedef %s _SrcType", idl_scopedLiteTypeName(subType)); -// idl_fileOutPrintf (idl_fileCur(), " typedef %s _SrcType", -// idl_scopeStack(idl_typeUserScope(idl_typeUser(subType)), "::", sname)); } else { idl_fileOutPrintf (idl_fileCur(), " typedef %s _SrcType", idl_scopedLiteTypeName(subType)); } @@ -753,7 +748,8 @@ idl_arrayLoopCopyBody( c_long total_indent; char* tmp_string = 0; - + char* scopedTypeName = idl_scopedTypeName(typeSpec); + char* scopedLiteTypeName = idl_scopedLiteTypeName(typeSpec); loopIndent++; switch (idl_typeSpecType(typeSpec)) { case idl_tstruct: @@ -762,10 +758,10 @@ idl_arrayLoopCopyBody( idl_printIndent(loopIndent + indent); varIndex = 0; idl_fileOutPrintf(idl_fileCur(), "extern void __%s__copyOut(const void *, void *);\n", - idl_scopedTypeName(typeSpec)); + scopedTypeName); idl_printIndent(loopIndent + indent); idl_fileOutPrintf(idl_fileCur(), "__%s__copyOut((const void *)&(*%s)", - idl_scopedTypeName(typeSpec), + scopedTypeName, from); idl_arrayLoopCopyIndex(typeArray); idl_fileOutPrintf(idl_fileCur(), ", (void *)&(%s)", to); @@ -781,10 +777,10 @@ idl_arrayLoopCopyBody( case idl_tarray: case idl_tseq: idl_fileOutPrintf(idl_fileCur(), "extern void __%s__copyOut(const void *, void *);\n", - idl_scopedTypeName(typeSpec)); + scopedTypeName); idl_printIndent(loopIndent + indent); idl_fileOutPrintf(idl_fileCur(), "__%s__copyOut((const void *)&(*%s)", - idl_scopedTypeName(typeSpec), from); + scopedTypeName, from); idl_arrayLoopCopyIndex(typeArray); idl_fileOutPrintf(idl_fileCur(), ", (void *)&(%s)", to); idl_arrayLoopCopyIndex(typeArray); @@ -844,8 +840,8 @@ idl_arrayLoopCopyBody( snprintf(source, (size_t)sizeof(source), "&(%s)", from); idl_arrayLoopCopyIndexString(source, typeArray); idl_fileOutPrintf(idl_fileCur(), " %s *src0 = (%s *)%s;\n\n", - idl_scopedLiteTypeName(typeSpec), - idl_scopedLiteTypeName(typeSpec), + scopedLiteTypeName, + scopedLiteTypeName, source); idl_printIndent(total_indent); idl_fileOutPrintf(idl_fileCur()," size0 = (*src0)._length;\n"); @@ -874,6 +870,7 @@ idl_arrayLoopCopyBody( break; } loopIndent--; + os_free(scopedTypeName); } /** @brief Generate array loop copy closing code. @@ -1179,7 +1176,8 @@ idl_seqLoopCopy( c_char source[32]; idl_typeSpec nextType; char* tmp_string = 0; - + char * scopedTypeName = idl_scopedTypeName(typeSpec); + if (idl_isContiguous(idl_typeSpecDef(typeSpec))) { idl_printIndent(indent); idl_fileOutPrintf(idl_fileCur(), "{\n"); @@ -1248,10 +1246,10 @@ idl_seqLoopCopy( IDL_PRINTLINE(indent); idl_printIndent(indent); idl_fileOutPrintf(idl_fileCur(), " extern void __%s__copyOut(const void *from, void *to);\n", - idl_scopedTypeName(typeSpec)); + scopedTypeName); idl_printIndent(indent); idl_fileOutPrintf(idl_fileCur(), " __%s__copyOut((const void *)&(*%s)[j%d], (void *)&(%s)%s);\n", - idl_scopedTypeName(typeSpec), + scopedTypeName, from, loop_index-1, to, @@ -1267,10 +1265,10 @@ idl_seqLoopCopy( IDL_PRINTLINE(indent); idl_printIndent(indent); idl_fileOutPrintf(idl_fileCur(), " extern void __%s__copyOut(const void *, void *);\n", - idl_scopedTypeName(typeSpec)); + scopedTypeName); idl_printIndent(indent); idl_fileOutPrintf(idl_fileCur(), " __%s__copyOut((const void *)&((*%s)[j%d]), (void *)&(%s)%s);\n", - idl_scopedTypeName(typeSpec), + scopedTypeName, from, loop_index-1, to, @@ -1385,6 +1383,7 @@ idl_seqLoopCopy( idl_printIndent(indent); idl_fileOutPrintf(idl_fileCur(), "}\n"); + os_free(scopedTypeName); /* QAC EXPECT 5101, 5103: Complexity is limited, by independent cases, per case the number of lines is lower */ } diff --git a/src/tools/idlpp/code/idl_genLiteISOCxxCopyout.h b/src/tools/idlpp/code/idl_genLiteISOCxxCopyout.h index 4080112c1..7451b631e 100644 --- a/src/tools/idlpp/code/idl_genLiteISOCxxCopyout.h +++ b/src/tools/idlpp/code/idl_genLiteISOCxxCopyout.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/idlpp/code/idl_genMatlab.c b/src/tools/idlpp/code/idl_genMatlab.c new file mode 100644 index 000000000..19e44ad0b --- /dev/null +++ b/src/tools/idlpp/code/idl_genMatlab.c @@ -0,0 +1,606 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "idl_genMatlab.h" +#include "idl_genMatlabHelper.h" + +#include "idl_genMetaHelper.h" +#include "idl_keyDef.h" +#include "idl_tmplExp.h" + +#include +#include + +/* enumeration data */ +static c_long enum_element = 0; + +/* struct data */ +static idl_typeStruct active_structSpec; +static idl_scope active_structScope; +static idl_streamOut structPublicFunctionsStream; +static idl_streamOut structConstructorStream; +static idl_streamOut structAsStructStream; +static idl_streamOut structOffsetsStream; + +/** + * Standard control structure to specify that inline + * type definitions are to be processed prior to the + * type itself in contrast with inline. +*/ +static idl_programControl idl_genMatlabLoadControl = { + idl_prior +}; + +/** @brief return the program control structure for the splice type generation functions. + */ +static idl_programControl * +idl_getControl( + void *userData) +{ + OS_UNUSED_ARG(userData); + return &idl_genMatlabLoadControl; +} + +/** @brief callback function called on opening the IDL input file. + * + * Generate standard file header consisting of: + * - mutiple inclusion prevention + * - inclusion of Splice type definition files + * - inclusion of application specific include files related to other IDL files + * + * @param scope Current scope (not used) + * @param name Name of the IDL input file + */ +static idl_action +idl_fileOpen( + idl_scope scope, + const char *name, + void *userData) +{ + OS_UNUSED_ARG(scope); + OS_UNUSED_ARG(name); + OS_UNUSED_ARG(userData); + + /* return idl_explore to indicate that the rest of the file needs to be processed */ + return idl_explore; +} + +/** @brief callback function called on module definition in the IDL input file. + * + * Generate code for the following IDL construct: + * @verbatim + => module { + + }; + @endverbatim + * + * This fuction generates the prototype of the function that + * is responsible for loading the metadata into the database. + * The name of the function is: + * @verbatim + ______load + @endverbatim + * For the Splice types, no further actions are required. + * + * @param scope Current scope (and scope of the module definition) + * @param name Name of the defined module + */ +static idl_action +idl_moduleOpen( + idl_scope scope, + const char *name, + void *userData) +{ + OS_UNUSED_ARG(scope); + OS_UNUSED_ARG(name); + OS_UNUSED_ARG(userData); + + /* return idl_explore to indicate that the rest of the module needs to be processed */ + return idl_explore; +} + +/* Matlab class template: + classdef struct_name < Vortex.AbstractType + properties + FIELD1 FIELD1Type = initDimensions + FIELD2 (1) + end + + methods (Static) + function keys = getKey + keys = 'STRUCT_KEY_STRING'; + end + end + end +*/ + +/** @brief callback function called on structure definition in the IDL input file. + * + * Generate code for the following IDL construct: + * @verbatim + => struct { + ; + ... ... + ; + }; + @endverbatim + * + * @param scope Current scope (and scope of the structure definition) + * @param name Name of the structure + * @param structSpec Specification of the struct holding the amount of members + */ +static idl_action +idl_structureOpen( + idl_scope scope, + const char *name, + idl_typeStruct structSpec, + void *userData) +{ + c_char *mlName; + const c_char *keys; + + OS_UNUSED_ARG(name); + OS_UNUSED_ARG(structSpec); + OS_UNUSED_ARG(userData); + + keys = idl_keyResolve(idl_keyDefDefGet(), scope, name); + + /* Open file for used scope, if needed create the directories */ + mlName = idl_matlabId(name); + idl_openMatlabPackage(scope, mlName); + if (idl_fileCur() == NULL) { + os_free(mlName); + return idl_abort; + } + + if(keys) { + idl_fileOutPrintf(idl_fileCur(), "classdef %s < Vortex.AbstractType\n", mlName); + } else { + idl_fileOutPrintf(idl_fileCur(), "classdef %s\n", mlName); + } + idl_fileOutPrintf(idl_fileCur(), " properties\n"); + os_free(mlName); + + /* save info for the close method */ + active_structSpec = structSpec; + active_structScope = scope; + + /* set up stream for struct offsets */ + structOffsetsStream = idl_streamOutNew (0); + structPublicFunctionsStream = idl_streamOutNew (0); + structConstructorStream = idl_streamOutNew(0); + structAsStructStream = idl_streamOutNew(0); + + /* return idl_explore to indicate that the rest of the structure needs to be processed */ + return idl_explore; +} + +/** @brief callback function called on end of a structure definition in the IDL input file. + * + * Generate code for the following IDL construct: + * @verbatim + struct { + + ... ... + + => }; + @endverbatim + * + * The structure is closed: + * @verbatim + }; + @endverbatim + * + * @param name Name of the structure (not used) + */ +static void +idl_structureClose( + const char *name, + void *userData) +{ + const c_char *keys = ""; + c_char *descriptor; + char *id = idl_matlabId(name); + OS_UNUSED_ARG(name); + OS_UNUSED_ARG(userData); + + keys = idl_keyResolve(idl_keyDefDefGet(), active_structScope, name); + if (keys != NULL) { + c_type type = idl_typeSpecDef(idl_typeSpec(active_structSpec)); + descriptor = idl_genXMLmeta(type, FALSE); + } else { + descriptor = os_strdup(""); + } + + + idl_fileOutPrintf(idl_fileCur(), " end\n"); /*properties*/ + idl_fileOutPrintf(idl_fileCur(), "\n"); + idl_fileOutPrintf(idl_fileCur(), " methods\n"); + idl_fileOutPrintf(idl_fileCur(), " function obj = %s(opt_struct)\n", id); + idl_fileOutPrintf(idl_fileCur(), " if nargin == 1\n"); + idl_fileOutPrintf(idl_fileCur(), "%s", idl_streamGet (idl_stream(structConstructorStream))); + idl_fileOutPrintf(idl_fileCur(), " end\n"); + idl_fileOutPrintf(idl_fileCur(), " end\n\n"); + idl_fileOutPrintf(idl_fileCur(), " function struct_copy = asStruct(obj)\n"); + idl_fileOutPrintf(idl_fileCur(), "%s", idl_streamGet (idl_stream(structAsStructStream))); + idl_fileOutPrintf(idl_fileCur(), " end\n\n"); + idl_fileOutPrintf(idl_fileCur(), "%s", idl_streamGet (idl_stream(structPublicFunctionsStream))); + idl_fileOutPrintf(idl_fileCur(), " end\n"); /*public methods*/ + idl_fileOutPrintf(idl_fileCur(), "\n"); + + idl_fileOutPrintf(idl_fileCur(), " methods (Static)\n"); + if(keys != NULL) { + idl_fileOutPrintf(idl_fileCur(), " function keys = getKey\n"); + idl_fileOutPrintf(idl_fileCur(), " keys = '%s';\n", keys); + idl_fileOutPrintf(idl_fileCur(), " end\n"); + idl_fileOutPrintf(idl_fileCur(), "\n"); + idl_fileOutPrintf(idl_fileCur(), " function xml = getTopicDescriptor\n"); + idl_fileOutPrintf(idl_fileCur(), " xml = '%s';\n", descriptor); + idl_fileOutPrintf(idl_fileCur(), " end\n"); + idl_fileOutPrintf(idl_fileCur(), "\n"); + } + /* TODO: code proper getTypeInfo */ + idl_fileOutPrintf(idl_fileCur(), " function info = getTypeInfo(name)\n"); + idl_fileOutPrintf(idl_fileCur(), " import Vortex.internal.ml_type_info_kind;\n"); + idl_fileOutPrintf(idl_fileCur(), " switch(name)\n"); + idl_fileOutPrintf(idl_fileCur(), "%s", idl_streamGet (idl_stream(structOffsetsStream))); + idl_fileOutPrintf(idl_fileCur(), " end\n"); + idl_fileOutPrintf(idl_fileCur(), " end\n"); + idl_fileOutPrintf(idl_fileCur(), " end\n"); /* static functions */ + idl_fileOutPrintf(idl_fileCur(), "end\n"); /*classdef*/ + + idl_streamOutFree(structOffsetsStream); + idl_streamOutFree(structPublicFunctionsStream); + idl_streamOutFree(structConstructorStream); + idl_streamOutFree(structAsStructStream); + structOffsetsStream = NULL; + structPublicFunctionsStream = NULL; + structConstructorStream = NULL; + structAsStructStream = NULL; + active_structSpec = NULL; + active_structScope = NULL; + + os_free(id); + os_free(descriptor); +} + +/** @brief callback function called on definition of a structure member in the IDL input file. + * + * Generate code for the following IDL construct: + * @verbatim + struct { + => ; + => ... ... + => ; + }; + @endverbatim + * + * @param scope Current scope + * @param name Name of the structure member + * @param typeSpec Type specification of the structure member + */ +static void +idl_structureMemberOpenClose( + idl_scope scope, + const char *name, + idl_typeSpec typeSpec, + void *userData) +{ + c_char *id; + c_char *mlTypeName = idl_matlabTypeName(typeSpec); + int shouldBeCell = (idl_matlabShouldBeCellArray(typeSpec) == 1); + c_char *type = shouldBeCell ? "cell" : mlTypeName; + c_char *initialization = idl_matlabFieldInitialization(typeSpec); + c_char *dims_string = idl_matlabFormattedDimensions(typeSpec); + + OS_UNUSED_ARG(scope); + OS_UNUSED_ARG(userData); + + id = idl_matlabId(name); + + idl_fileOutPrintf(idl_fileCur(), " %s %s = %s\n", id, + shouldBeCell ? "cell" : type, + initialization); + + /* do setter functions */ + idl_streamOutPrintf(structPublicFunctionsStream, + " function obj = set.%s(obj,value)\n", id); + if (idl_matlabIsArrayOfSequences(typeSpec)) { + idl_streamOutPrintf(structPublicFunctionsStream, + " Vortex.check_seq_array(value,2);\n"); + idl_streamOutPrintf(structPublicFunctionsStream, + " for i = 1:numel(value)\n"); + /* TODO: check sequence */ + idl_streamOutPrintf(structPublicFunctionsStream, + " %%TODO: check sequence\n"); + idl_streamOutPrintf(structPublicFunctionsStream, + " end\n"); + } else if(idl_matlabIsSequence(typeSpec)) { + /* TODO: check sequence */ + idl_streamOutPrintf(structPublicFunctionsStream, + " %%TODO: check sequence\n"); + } else if (idl_matlabIsString(typeSpec)) { + unsigned long bound = idl_matlabStringBound(typeSpec); + idl_streamOutPrintf(structPublicFunctionsStream, + " Vortex.check_string(value, %s, %lu);\n", dims_string, bound); + } else { + idl_streamOutPrintf(structPublicFunctionsStream, + " Vortex.check_dims(value, %s);\n", dims_string); + } + idl_streamOutPrintf(structPublicFunctionsStream, + " obj.%s = value;\n", id); + idl_streamOutPrintf(structPublicFunctionsStream, + " end\n\n"); + + /* Do constructor, and asStruct copying */ + if(idl_matlabIsStruct(typeSpec)) { + if(idl_matlabIsNotMultiValued(typeSpec)) { + /* Constructor */ + idl_streamOutPrintf(structConstructorStream, " obj.%s = %s(opt_struct.%s);\n", id, mlTypeName, id); + /* asStruct method */ + idl_streamOutPrintf(structAsStructStream, " struct_copy.%s = obj.%s.asStruct;\n", id, id); + } else if(idl_matlabIsArrayOfSequences(typeSpec)) { + printf("ERROR: Unsupported - arrays of sequences of structures.\n"); + exit(1); + } else if(idl_matlabIsSequence(typeSpec)) { + /* Constructor */ + idl_streamOutPrintf(structConstructorStream, " %s_local = %s.empty();\n", id, mlTypeName); + idl_streamOutPrintf(structConstructorStream, " for i = numel(opt_struct.%s):-1:1\n", id); + idl_streamOutPrintf(structConstructorStream, " %s_local(i) = %s(opt_struct.%s(i));\n", id, mlTypeName, id); + idl_streamOutPrintf(structConstructorStream, " end\n"); + idl_streamOutPrintf(structConstructorStream, " obj.%s = %s_local;\n", id, id); + /* asStruct method */ + idl_streamOutPrintf(structAsStructStream, " %s_local = Vortex.init_field('%s',0);\n", id, mlTypeName); + idl_streamOutPrintf(structAsStructStream, " for i = numel(obj.%s):-1:1\n", id); + idl_streamOutPrintf(structAsStructStream, " %s_local(i) = obj.%s(i).asStruct;\n", id, id); + idl_streamOutPrintf(structAsStructStream, " end\n"); + idl_streamOutPrintf(structAsStructStream, " struct_copy.%s = %s_local;\n", id, id); + } else if(idl_matlabIsArray(typeSpec)) { + /* Constructor */ + idl_streamOutPrintf(structConstructorStream, " %s_local = %s;\n", id, initialization); + idl_streamOutPrintf(structConstructorStream, " for i = 1:numel(opt_struct.%s)\n", id); + idl_streamOutPrintf(structConstructorStream, " %s_local(i) = %s(opt_struct.%s(i));\n", id, mlTypeName, id); + idl_streamOutPrintf(structConstructorStream, " end\n"); + idl_streamOutPrintf(structConstructorStream, " obj.%s = %s_local\n", id, id); + /* asStruct method */ + idl_streamOutPrintf(structAsStructStream, " struct_copy.%s = obj.%s.asStruct;\n", id, id); + idl_streamOutPrintf(structAsStructStream, " for i = numel(obj.%s):-1:1", id); + idl_streamOutPrintf(structAsStructStream, " a_struct_local(i) = obj.a_struct(i).asStruct();\n"); + idl_streamOutPrintf(structAsStructStream, " end\n"); + idl_streamOutPrintf(structAsStructStream, " struct_copy.%s = reshape(%s_local,size(obj.%s));\n", id, id, id); + } else { + /* Constructor */ + idl_streamOutPrintf(structConstructorStream, " %%TODO: copy %s\n", id); + /* asStruct method */ + idl_streamOutPrintf(structAsStructStream, " %%TODO: copy %s\n", id); + } + } else if(idl_matlabIsEnum(typeSpec)) { + /* Constructor */ + idl_streamOutPrintf(structConstructorStream, " obj.%s = opt_struct.%s;\n", id, id); + /* asStruct method */ + idl_streamOutPrintf(structAsStructStream, " struct_copy.%s = int32(obj.%s);\n", id, id); + } else { + /* Constructor */ + idl_streamOutPrintf(structConstructorStream, " obj.%s = opt_struct.%s;\n", id, id); + /* asStruct method */ + idl_streamOutPrintf(structAsStructStream, " struct_copy.%s = obj.%s;\n", id, id); + } + + idl_streamOutTypeInfoEntries(structOffsetsStream, name, typeSpec); + + os_free((void*)mlTypeName); + os_free((void*)initialization); + os_free((void*)dims_string); + os_free(id); +} + +/** @brief callback function called on definition of an enumeration. + * + * Generate code for the following IDL construct: + * @verbatim + => enum { + ; + ... ... + ; + }; + @endverbatim + * + * @param scope Current scope + * @param name Name of the enumeration + * @param enumSpec Specifies the number of elements in the enumeration + */ +static idl_action +idl_enumerationOpen( + idl_scope scope, + const char *name, + idl_typeEnum enumSpec, + void *userData) +{ + c_char *mlName; + OS_UNUSED_ARG(userData); + OS_UNUSED_ARG(enumSpec); + + /* Open file for used scope, if needed create the directories */ + mlName = idl_matlabId(name); + idl_openMatlabPackage(scope, mlName); + if (idl_fileCur() == NULL) { + os_free(mlName); + return idl_abort; + } + /* Matlab Enum class template: + classdef EnumName < int32 + enumeration + FIELD1 (0) % use ordinal value from IDLPP + FIELD2 (1) + end + end + */ + + idl_fileOutPrintf(idl_fileCur(), "classdef %s < int32\n", mlName); + idl_fileOutPrintf(idl_fileCur(), " enumeration\n"); + os_free(mlName); + enum_element = 0; + + /* return idl_explore to indicate that the rest of the enumeration needs to be processed */ + return idl_explore; +} + +/** @brief callback function called on closure of an enumeration in the IDL input file. + * + * Generate code for the following IDL construct: + * @verbatim + enum { + ; + ... ... + ; + => }; + @endverbatim + * + * @param name Name of the enumeration + */ +static void +idl_enumerationClose( + const char *name, + void *userData) +{ + OS_UNUSED_ARG(name); + OS_UNUSED_ARG(userData); + + idl_fileOutPrintf(idl_fileCur(), " end\n"); + idl_fileOutPrintf(idl_fileCur(), "end\n"); + /* close file */ + idl_closeMatlabPackage(); + +} + +/** @brief callback function called on definition of an enumeration element in the IDL input file. + * + * Generate code for the following IDL construct: + * @verbatim + enum { + => , + => ... ... + => + }; + @endverbatim + * + * For the last element generate: + * @verbatim + + @endverbatim + * For any but the last element generate: + * @verbatim + , + @endverbatim + * + * @param scope Current scope + * @param name Name of the enumeration element + */ +static void +idl_enumerationElementOpenClose ( + idl_scope scope, + const char *name, + void *userData) +{ + OS_UNUSED_ARG(scope); + OS_UNUSED_ARG(userData); + + idl_fileOutPrintf(idl_fileCur()," %s (%d)\n", name, enum_element); + + enum_element++; +} + +/** @brief callback function called on definition of a named type in the IDL input file. + * + * Generate code for the following IDL construct: + * @verbatim + => typedef ; + @endverbatim + * + * @param scope Current scope + * @param name Specifies the name of the type + * @param defSpec Specifies the type of the named type + */ +static void +idl_typedefOpenClose( + idl_scope scope, + const char *name, + idl_typeDef defSpec, + void *userData) +{ + /* TODO: Implement */ + OS_UNUSED_ARG(scope); + OS_UNUSED_ARG(name); + OS_UNUSED_ARG(defSpec); + OS_UNUSED_ARG(userData); +} + +static void +idl_sequenceOpenClose ( + idl_scope scope, + idl_typeSeq typeSeq, + void *userData) +{ + /* TODO: Implement */ + OS_UNUSED_ARG(scope); + OS_UNUSED_ARG(typeSeq); + OS_UNUSED_ARG(userData); +} + + +/** + * Specifies the callback table for the splice type generation functions. + */ +static struct idl_program +idl_genMatlabType = { + idl_getControl, + idl_fileOpen, + NULL, /* idl_fileClose */ + idl_moduleOpen, + NULL, /* idl_moduleClose */ + idl_structureOpen, + idl_structureClose, + idl_structureMemberOpenClose, + idl_enumerationOpen, + idl_enumerationClose, + idl_enumerationElementOpenClose, + NULL, /*idl_unionOpen */ + NULL, /* idl_unionClose */ + NULL, /* idl_unionCaseOpenClose */ + NULL, /* idl_unionLabelsOpenClose */ + NULL, /* idl_unionLabelOpenClose */ + idl_typedefOpenClose, /* idl_typedefOpenClose */ + NULL, /* idl_boundedStringOpenClose */ + idl_sequenceOpenClose, + NULL, /* idl_constantOpenClose */ + NULL, /* idl_artificialDefaultLabelOpenClose */ + NULL /* userData */ +}; + +/** @brief return the callback table for the splice type generation functions. + */ +idl_program +idl_genMatlabProgram ( + void) +{ + return &idl_genMatlabType; +} + diff --git a/src/tools/idlpp/code/idl_genMatlab.h b/src/tools/idlpp/code/idl_genMatlab.h new file mode 100644 index 000000000..ed900d261 --- /dev/null +++ b/src/tools/idlpp/code/idl_genMatlab.h @@ -0,0 +1,28 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#ifndef IDL_GENMATLAB_H +#define IDL_GENMATLAB_H + +#include "idl_program.h" + +idl_program idl_genMatlabProgram (void); + +#endif /* IDL_GENMATLAB_H */ diff --git a/src/tools/idlpp/code/idl_genMatlabHelper.c b/src/tools/idlpp/code/idl_genMatlabHelper.c new file mode 100644 index 000000000..ec05adfe8 --- /dev/null +++ b/src/tools/idlpp/code/idl_genMatlabHelper.c @@ -0,0 +1,911 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "idl_genMatlabHelper.h" +#include "idl_genSimulinkHelper.h" + +#include "idl_tmplExp.h" + +#include "os_iterator.h" +#include "os_heap.h" +#include "os_stdlib.h" +#include "os_string.h" +#include "os_errno.h" + +#include +#include + + +/* Specify a list of all C keywords */ +static const char *matlab_keywords[] = { + /* MATLAB keywords - output from command: iskeyword */ + "break", + "case", + "catch", + "classdef", + "continue", + "else", + "elseif", + "end", + "for", + "function", + "global", + "if", + "otherwise", + "parfor", + "persistent", + "return", + "spmd", + "switch", + "try", + "while", +}; + +static idl_typeSpec +stripTypedefs( + idl_typeSpec typeSpec) +{ + /* navigate through any obscuring typedefs */ + while(idl_ttypedef == idl_typeSpecType(typeSpec)) { + typeSpec = idl_typeDefActual(idl_typeDef(typeSpec)); + } + return typeSpec; +} + +int +idl_matlabIsSequence( + idl_typeSpec typeSpec) +{ + switch(idl_typeSpecType(typeSpec)) { + case idl_tseq: + return 1; + case idl_tbasic: + case idl_tenum: + case idl_tstruct: + case idl_tunion: + return 0; + case idl_tarray: + return idl_matlabIsSequence(idl_typeArrayActual(idl_typeArray(typeSpec))); + case idl_ttypedef: + return idl_matlabIsSequence(idl_typeDefActual(idl_typeDef(typeSpec))); + } + return 0; +} + +int +idl_matlabIsArray( + idl_typeSpec typeSpec) +{ + switch(idl_typeSpecType(typeSpec)) { + case idl_tseq: + return idl_matlabIsArray(idl_typeSeqActual(idl_typeSeq(typeSpec))); + case idl_tbasic: + case idl_tenum: + case idl_tstruct: + case idl_tunion: + return 0; + case idl_tarray: + return 1; + case idl_ttypedef: + return idl_matlabIsArray(idl_typeDefActual(idl_typeDef(typeSpec))); + } + return 0; +} + + +idl_typeSpec +idl_matlabFindArrayWrappedType(idl_typeSpec typeSpec) +{ + switch(idl_typeSpecType(typeSpec)) { + case idl_tarray: + return idl_matlabFindArrayWrappedType(idl_typeArrayType(idl_typeArray(typeSpec))); + case idl_ttypedef: + return idl_matlabFindArrayWrappedType(idl_typeDefActual(idl_typeDef(typeSpec))); + default: + break; + } + return typeSpec; +} + +idl_typeSpec +idl_matlabFindSequenceWrappedType(idl_typeSpec typeSpec) +{ + switch(idl_typeSpecType(typeSpec)) { + case idl_tseq: + return idl_typeSeqType(idl_typeSeq(typeSpec)); + case idl_ttypedef: + return idl_matlabFindSequenceWrappedType(idl_typeDefActual(idl_typeDef(typeSpec))); + case idl_tarray: + return idl_matlabFindSequenceWrappedType(idl_typeArrayActual(idl_typeArray(typeSpec))); + default: + break; + } + return typeSpec; +} + +int +idl_matlabIsArrayOfSequences( + idl_typeSpec typeSpec) +{ + if(idl_matlabIsArray(typeSpec)) { + idl_typeSpec wrapped = idl_matlabFindArrayWrappedType(typeSpec); + return idl_matlabIsSequence(wrapped); + } else { + return 0; + } +} + +int +idl_scopeIsInStruct( + idl_scope scope) +{ + return idl_tStruct == idl_scopeElementType(idl_scopeCur(scope)); +} + +int +idl_matlabIsStruct(idl_typeSpec typeSpec) +{ + switch(idl_typeSpecType(typeSpec)) { + case idl_tstruct: + return 1; + case idl_tarray: + return idl_matlabIsStruct(idl_typeArrayType(idl_typeArray(typeSpec))); + case idl_tseq: + return idl_matlabIsStruct(idl_typeSeqType(idl_typeSeq(typeSpec))); + case idl_ttypedef: + return idl_matlabIsStruct(idl_typeDefActual(idl_typeDef(typeSpec))); + default: + break; + } + return 0; +} + +int +idl_matlabIsEnum( + idl_typeSpec typeSpec) +{ + switch(idl_typeSpecType(typeSpec)) { + case idl_tenum: + return 1; + case idl_tarray: + return idl_matlabIsEnum(idl_typeArrayType(idl_typeArray(typeSpec))); + case idl_tseq: + return idl_matlabIsEnum(idl_typeSeqType(idl_typeSeq(typeSpec))); + case idl_ttypedef: + return idl_matlabIsEnum(idl_typeDefActual(idl_typeDef(typeSpec))); + default: + break; + } + return 0; +} + +int +idl_matlabIsNotMultiValued( + idl_typeSpec typeSpec) +{ + switch(idl_typeSpecType(typeSpec)) { + case idl_tarray: + case idl_tseq: + return 0; + case idl_ttypedef: + return idl_matlabIsNotMultiValued(idl_typeDefActual(idl_typeDef(typeSpec))); + default: + break; + } + return 1; +} + +int +idl_matlabIsString( + idl_typeSpec typeSpec) +{ + switch(idl_typeSpecType(typeSpec)) { + case idl_tbasic: + return idl_string == idl_typeBasicType(idl_typeBasic(typeSpec)); + case idl_tarray: + return idl_matlabIsString(idl_typeArrayType(idl_typeArray(typeSpec))); + case idl_ttypedef: + return idl_matlabIsString(idl_typeDefActual(idl_typeDef(typeSpec))); + default: + break; + } + return 0; + +} + +c_ulong +idl_matlabStringBound( + idl_typeSpec typeSpec) +{ + switch(idl_typeSpecType(typeSpec)) { + case idl_tbasic: + if(idl_string == idl_typeBasicType(idl_typeBasic(typeSpec))) { + return idl_typeBasicMaxlen(idl_typeBasic(typeSpec)); + } else { + return 0; + } + case idl_tarray: + return idl_matlabStringBound(idl_typeArrayType(idl_typeArray(typeSpec))); + case idl_ttypedef: + return idl_matlabStringBound(idl_typeDefActual(idl_typeDef(typeSpec))); + default: + break; + } + return 0; +} + +c_ulong +idl_matlabSequenceBound( + idl_typeSpec typeSpec) +{ + switch(idl_typeSpecType(typeSpec)) { + case idl_tseq: + return idl_typeSeqMaxSize(idl_typeSeq(typeSpec)); + case idl_tarray: + return idl_matlabStringBound(idl_typeArrayType(idl_typeArray(typeSpec))); + case idl_ttypedef: + return idl_matlabStringBound(idl_typeDefActual(idl_typeDef(typeSpec))); + default: + break; + } + return 0; +} + +static void +idl_matlabNumel( + idl_typeSpec typeSpec, + c_ulong *numel) +{ + idl_type type = idl_typeSpecType(typeSpec); + + switch(type) { + case idl_tarray: + idl_matlabNumel(idl_typeArrayType(idl_typeArray(typeSpec)), numel); + *numel *= idl_typeArraySize(idl_typeArray(typeSpec)); + break; + case idl_ttypedef: + idl_matlabNumel(idl_typeDefRefered(idl_typeDef(typeSpec)), numel); + break; + default: + break; + } +} + +int +idl_matlabShouldBeCellArray( + idl_typeSpec typeSpec) +{ + const int NO = 0; + const int YES = 1; + const int IF_WRAPPED = 2; + const int IF_SEQUENCE_WRAPPED = 3; + + idl_type type = idl_typeSpecType(typeSpec); + switch(type) { + case idl_tbasic: + return idl_typeBasicType(idl_typeBasic(typeSpec)) == idl_string + ? IF_WRAPPED : NO; + case idl_tenum: + case idl_tstruct: + case idl_tunion: + return NO; + case idl_ttypedef: + return idl_matlabShouldBeCellArray(idl_typeDefActual(idl_typeDef(typeSpec))); + case idl_tseq: + { + idl_typeSpec wrappedType = idl_typeSeqType(idl_typeSeq(typeSpec)); + int wrappedTypeDecision = idl_matlabShouldBeCellArray(wrappedType); + if(wrappedTypeDecision == YES + || wrappedTypeDecision == IF_SEQUENCE_WRAPPED + || wrappedTypeDecision == IF_WRAPPED) { + return YES; + } else { + return NO; + } + } + case idl_tarray: + { + idl_typeSpec wrappedType = idl_typeArrayActual(idl_typeArray(typeSpec)); + int wrappedTypeDecision = idl_matlabShouldBeCellArray(wrappedType); + if(wrappedTypeDecision == YES || wrappedTypeDecision == IF_WRAPPED) { + return YES; + } else { + return IF_SEQUENCE_WRAPPED; + } + } + } + + return NO; +} + +static int +is_string(idl_typeSpec typeSpec) +{ + typeSpec = stripTypedefs(typeSpec); + return idl_tbasic == idl_typeSpecType(typeSpec) + && idl_string == idl_typeBasicType(idl_typeBasic(typeSpec)); + +} + +static int +forcesSequenceToCell(idl_typeSpec typeSpec) +{ + idl_type type; + + typeSpec = stripTypedefs(typeSpec); + type = idl_typeSpecType(typeSpec); + return is_string(typeSpec) || idl_tseq == type || idl_tarray == type; +} + +c_char * +idl_matlabFieldInitialization( + idl_typeSpec typeSpec) +{ + char buffer[256]; + c_char *mlType = idl_matlabTypeName(typeSpec); + char *dims_string = idl_matlabFormattedDimensions(typeSpec); + char *init_string; + idl_type type; + + typeSpec = stripTypedefs(typeSpec); + + type = idl_typeSpecType(typeSpec); + if(idl_tseq == type) { + if(forcesSequenceToCell(idl_typeSeqType(idl_typeSeq(typeSpec)))) { + init_string = "SEQUENCE"; + } else { + init_string = mlType; + os_free((void*)dims_string); + dims_string = os_strdup("0"); + } + } else if(idl_tarray == type) { + idl_typeSpec wrappedType = idl_typeArrayActual(idl_typeArray(typeSpec)); + if(is_string(wrappedType)) { + init_string = "STRING"; + } else if(idl_matlabIsSequence(wrappedType)) { + init_string = "SEQUENCE"; + } else { + init_string = mlType; + } + } else if(is_string(typeSpec)) { + init_string = "STRING"; + } else { + init_string = mlType; + } + + os_sprintf(buffer, "Vortex.init_field('%s', %s)", init_string, dims_string); + + os_free((void*)mlType); + os_free((void*)dims_string); + return os_strdup(buffer); +} +/* Return the matlab type name for the given typeSpec */ +c_char * +idl_matlabTypeName( + idl_typeSpec typeSpec + ) +{ + idl_type type = idl_typeSpecType(typeSpec); + switch(type) { + case idl_tbasic: + { + idl_typeBasic typeBasic = idl_typeBasic(typeSpec); + idl_basicType basicType = idl_typeBasicType(typeBasic); + switch(basicType) { + case idl_boolean: + return os_strdup("logical"); + case idl_string: + return os_strdup("char"); + case idl_char: + return os_strdup("int8"); + case idl_octet: + return os_strdup("uint8"); + case idl_short: + return os_strdup("int16"); + case idl_ushort: + return os_strdup("uint16"); + case idl_long: + return os_strdup("int32"); + case idl_ulong: + return os_strdup("uint32"); + case idl_longlong: + return os_strdup("int64"); + case idl_ulonglong: + return os_strdup("uint64"); + case idl_float: + return os_strdup("single"); + case idl_double: + return os_strdup("double"); + } + } + break; + case idl_tstruct: + case idl_tenum: + { + idl_typeUser typeUser = idl_typeUser(typeSpec); + return idl_scopeStackMatlab(idl_typeUserScope(typeUser), ".", idl_typeSpecName(typeSpec)); + } + case idl_tarray: + { + idl_typeArray typeArray = idl_typeArray(typeSpec); + idl_typeSpec actualType = idl_typeArrayActual(typeArray); + return idl_matlabTypeName(actualType); + } + case idl_tseq: + { + idl_typeSeq typeSeq = idl_typeSeq(typeSpec); + return idl_matlabTypeName(idl_typeSeqActual(typeSeq)); + } + case idl_ttypedef: + { + idl_typeDef typeDef = idl_typeDef(typeSpec); + return idl_matlabTypeName(idl_typeDefActual(typeDef)); + } + case idl_tunion: + printf("idl_genMatlabHelper.c:idl_matlabTypeName: Union types are unsupported" + " for MATLAB binding.\n"); + exit(1); + } + return os_strdup(""); /* won't get here, but keep the compiler happy */ +} + +static c_char * +idl_matlabTypeInfoKind( + idl_typeSpec typeSpec) +{ + idl_type type = idl_typeSpecType(typeSpec); + switch(type) { + case idl_tbasic: + { + idl_typeBasic typeBasic = idl_typeBasic(typeSpec); + idl_basicType basicType = idl_typeBasicType(typeBasic); + switch(basicType) { + case idl_boolean: + return os_strdup("dds_boolean"); + case idl_string: + { + c_ulong maxlen = idl_typeBasicMaxlen(typeBasic); + if(maxlen == 0) { + return os_strdup("dds_string"); + } else { + return os_strdup("dds_bstring"); + } + } + case idl_char: + return os_strdup("dds_char"); + case idl_octet: + return os_strdup("dds_octet"); + case idl_short: + return os_strdup("dds_short"); + case idl_ushort: + return os_strdup("dds_ushort"); + case idl_long: + return os_strdup("dds_long"); + case idl_ulong: + return os_strdup("dds_ulong"); + case idl_longlong: + return os_strdup("dds_longlong"); + case idl_ulonglong: + return os_strdup("dds_ulonglong"); + case idl_float: + return os_strdup("dds_float"); + case idl_double: + return os_strdup("dds_double"); + } + } + break; + case idl_tstruct: + return os_strdup("dds_struct"); + case idl_tenum: + return os_strdup("dds_enum"); + case idl_tarray: + { + idl_typeArray typeArray = idl_typeArray(typeSpec); + return idl_matlabTypeInfoKind(idl_typeArrayActual(typeArray)); + } + case idl_tseq: + { + idl_typeSeq typeSeq = idl_typeSeq(typeSpec); + c_ulong maxSize = idl_typeSeqMaxSize(typeSeq); + if(maxSize == 0) { + return os_strdup("dds_sequence"); + } else { + return os_strdup("dds_bsequence"); + } + } + case idl_ttypedef: + { + idl_typeDef typeDef = idl_typeDef(typeSpec); + return idl_matlabTypeInfoKind(idl_typeDefActual(typeDef)); + } + case idl_tunion: + printf("idl_genMatlabHelper.c:idl_matlabTypeInfoKind: Union types are unsupported" + " for MATLAB binding.\n"); + exit(1); + } + return os_strdup(""); /* won't get here, but keep the compiler happy */ +} + + +static c_ulong +idl_matlabNDimensions( + idl_typeSpec typeSpec) +{ + idl_type type = idl_typeSpecType(typeSpec); + if(type == idl_tarray) { + idl_typeArray typeArray = idl_typeArray(typeSpec); + idl_typeSpec wrappedTypeSpec = idl_typeArrayType(typeArray); + idl_type wrappedType = idl_typeSpecType(wrappedTypeSpec); + if(wrappedType == idl_tarray) { + return 1 + idl_matlabNDimensions(wrappedTypeSpec); + } else { + return 1; + } + } else if(type == idl_ttypedef) { + return idl_matlabNDimensions(idl_typeDefRefered(idl_typeDef(typeSpec))); + } else { + return 1; + } +} + +static void +idl_matlabGetDimensions( + idl_typeSpec typeSpec, + c_ulong dimensions[]) +{ + if(idl_typeSpecType(typeSpec) == idl_tarray) { + idl_typeArray typeArray = idl_typeArray(typeSpec); + idl_typeSpec wrappedTypeSpec = idl_typeArrayType(typeArray); + idl_type wrappedType = idl_typeSpecType(wrappedTypeSpec); + + dimensions[0] = idl_typeArraySize(typeArray); + if(wrappedType == idl_tarray) { + idl_matlabGetDimensions(wrappedTypeSpec, &dimensions[1]); + } + } else if(idl_typeSpecType(typeSpec) == idl_ttypedef) { + idl_matlabGetDimensions(idl_typeDefRefered(idl_typeDef(typeSpec)), dimensions); + } else { + dimensions[0] = 1; + } +} + +c_char * +idl_matlabFormattedDimensions( + idl_typeSpec typeSpec) +{ + c_ulong ndims = idl_matlabNDimensions(typeSpec); + c_ulong *dims = (c_ulong *)os_malloc(ndims * sizeof(c_ulong)); + c_char *formatted_dims = NULL; + + idl_matlabGetDimensions(typeSpec, dims); + formatted_dims = simulink_formatDimensions(dims, ndims); + os_free((void*)dims); + + return formatted_dims; +} + +/* Return matlab values for 'type info' entries */ +void +idl_streamOutTypeInfoEntries( + idl_streamOut so, + const char *name, + idl_typeSpec typeSpec) +{ +#define TYPE_INFO_FORMAT \ + " case '%s'\n"\ + " info = struct('datatype', '%s', ...\n"\ + " 'kind', ml_type_info_kind.%s, ...\n"\ + " 'bound', %" PA_PA_PRIu32 ", ...\n"\ + " 'numel', %" PA_PA_PRIu32 ", ...\n"\ + " 'ndims', %" PA_PA_PRIu32 ", ...\n"\ + " 'size', %s);\n" + + c_char *typeInfoKind = idl_matlabTypeInfoKind(typeSpec); + c_char *mlTypeName = idl_matlabTypeName(typeSpec); + c_ulong numel = 1; + c_ulong ndims = idl_matlabNDimensions(typeSpec); + c_char *dims_ml_str = idl_matlabFormattedDimensions(typeSpec); + + c_ulong bound = idl_matlabIsString(typeSpec) ? idl_matlabStringBound(typeSpec) : + idl_matlabIsSequence(typeSpec) ? idl_matlabSequenceBound(typeSpec) : 0; + + idl_matlabNumel(typeSpec, &numel); + + idl_streamOutPrintf(so, TYPE_INFO_FORMAT, + name, mlTypeName, typeInfoKind, bound, numel, ndims, dims_ml_str); + + if(idl_matlabIsSequence(typeSpec)) { + int i = 1; + char *wrapped_name = (char *)os_malloc(strlen(name) + sizeof(" wrapped ") + 10); + idl_typeSpec currentTypeSpec = typeSpec; + do { + idl_typeSpec wrappedTypeSpec = idl_matlabFindSequenceWrappedType(currentTypeSpec); + c_char *wrapped_mlTypeName = idl_matlabTypeName(wrappedTypeSpec); + c_char *wrapped_typeInfoKind = idl_matlabTypeInfoKind(wrappedTypeSpec); + c_char *wrapped_dims_ml_str = idl_matlabFormattedDimensions(wrappedTypeSpec); + c_ulong wrapped_bound = idl_matlabIsString(wrappedTypeSpec) ? idl_matlabStringBound(wrappedTypeSpec) : + idl_matlabIsSequence(wrappedTypeSpec) ? idl_matlabSequenceBound(wrappedTypeSpec) : 0; + c_ulong wrapped_numel = 1; + idl_matlabNumel(wrappedTypeSpec, &wrapped_numel); + os_sprintf(wrapped_name,"%s wrapped %d", name, i++); + idl_streamOutPrintf(so, TYPE_INFO_FORMAT, + wrapped_name, + wrapped_mlTypeName, + wrapped_typeInfoKind, + wrapped_bound, + wrapped_numel, + idl_matlabNDimensions(wrappedTypeSpec), + wrapped_dims_ml_str); + os_free((void*)wrapped_mlTypeName); + os_free((void*)wrapped_dims_ml_str); + + if(idl_matlabIsSequence(wrappedTypeSpec)) { + + } + currentTypeSpec = wrappedTypeSpec; + } while (idl_matlabIsSequence(currentTypeSpec)); + os_free((void*)wrapped_name); + } + os_free((void*)mlTypeName); + os_free((void*)typeInfoKind); + os_free((void*)dims_ml_str); + +} +/* Translate an IDL identifier into a MATLAB language identifier. + * All identifiers that match a MATLAB keyword must be append by "_". + */ +c_char * +idl_matlabId( + const char *identifier) +{ + size_t i; + char *matlabId; + char *packageEnding; + + /* search through the Java keyword list */ + /* QAC EXPECT 5003; Bypass qactools error, why is this a violation */ + for (i = 0; i < sizeof(matlab_keywords) / sizeof(c_char *); i++) { + /* QAC EXPECT 5007, 3416; will not use wrapper, no side effects here */ + if (strcmp(matlab_keywords[i], identifier) == 0) { + /* If a keyword matches the specified identifier, append _ */ + /* QAC EXPECT 5007; will not use wrapper */ + matlabId = os_malloc(strlen(identifier) + 1 + 1); + snprintf(matlabId, strlen(identifier) + 1 + 1, "%s_", identifier); + return matlabId; + } + } + /* Check for reserved endings + * - Package + */ + packageEnding = strstr("Package", identifier); + if ((packageEnding && strcmp(packageEnding, "Package") == 0)) { + matlabId = os_malloc(strlen(identifier) + 1 + 1); + snprintf(matlabId, strlen(identifier) + 1 + 1, "%s_", identifier); + } else { + /* No match with a keyword is found, thus return the identifier itself */ + matlabId = os_strdup(identifier); + } + return matlabId; + /* QAC EXPECT 2006; performance is selected above rules here */ +} + + +static c_char * +idl_scopeMatlabElementName ( + idl_scopeElement scope) +{ + c_char *scopeName; + c_char *scopeMatlabName; + + scopeName = idl_scopeElementName(scope); + if ((idl_scopeElementType(scope) == idl_tStruct) + || (idl_scopeElementType(scope) == idl_tUnion)) { + scopeMatlabName = os_malloc(strlen(scopeName) + 8); + sprintf(scopeMatlabName, "%sPackage", scopeName); + } else { + scopeMatlabName = os_strdup(scopeName); + } + return scopeMatlabName; +} + +/* Build a textual presentation of the provided scope stack taking the + * Matlab keyword identifier translation into account. Further the function + * equals "idl_scopeStack". + */ +c_char * +idl_scopeStackMatlab ( + idl_scope scope, + const char *scopeSepp, + const char *name) +{ + c_long si; + c_long sz; + c_char *scopeStack = NULL; + c_char *Id; + c_bool isFsPath; + + assert (scopeSepp != NULL); + isFsPath = (strcmp(scopeSepp,".") != 0); + scopeStack = os_strdup (""); + + for (si = 0, sz = idl_scopeStackSize(scope); si < sz; si++) { + size_t slen; + c_char *mElName = idl_scopeMatlabElementName(idl_scopeIndexed(scope, si)); + /* Translate the scope name to a C identifier */ + Id = idl_matlabId(mElName); + os_free(mElName); + /* allocate space for the current scope stack + the separator + * and the next scope name + */ + /* QAC EXPECT 5007; will not use wrapper */ + slen = strlen (scopeStack) + strlen (scopeSepp) + strlen (Id) + + (isFsPath ? 1 : 0) /* add room for the + prefix */; + scopeStack = os_realloc(scopeStack, slen + 1); + /* Concatenate the separator */ + /* QAC EXPECT 5007; will not use wrapper */ + if (strlen(scopeStack)) { + os_strcat(scopeStack, scopeSepp); + } + if (isFsPath) { + os_strcat(scopeStack, "+"); + } + /* Concatenate the scope name */ + /* QAC EXPECT 5007; will not use wrapper */ + os_strcat (scopeStack, Id); + os_free(Id); + } + + if (name) { + /* A user identifier is specified */ + /* Translate the user identifier to a Java identifier */ + Id = idl_matlabId(name); + /* allocate space for the current scope stack + the separator + * and the user identifier + */ + /* QAC EXPECT 5007; will not use wrapper */ + scopeStack = os_realloc(scopeStack, strlen(scopeStack)+strlen(scopeSepp)+strlen(Id)+1); + /* Concatenate the separator */ + /* QAC EXPECT 5007; will not use wrapper */ + if (strlen(scopeStack)) { + os_strcat(scopeStack, scopeSepp); + } + /* Concatenate the user identifier */ + /* QAC EXPECT 5007; will not use wrapper */ + os_strcat (scopeStack, Id); + os_free(Id); + } + + /* return the scope stack representation */ + return scopeStack; +} + +static int +idl_createDir ( + os_char* fname) +{ + char *pathName; + os_result statRes; + struct os_stat_s statbuf; + char* outdir; + os_char* stackScope; + os_char* token; + const os_char* osSep; + + /* to allow nested modules which may potentially lead to very long paths, + * pathName is not allocated fixed-size on stack + * but dynamically on heap + */ + pathName = os_malloc(1); + pathName[0] = '\0'; + outdir = idl_dirOutCur(); + if(outdir){ + pathName = os_realloc(pathName, strlen(outdir) + strlen(os_fileSep()) + 1); + os_sprintf(pathName, "%s%s", outdir, os_fileSep()); + } + /* make sure that we replace the os file seperator with a simple character + * like '/', this will allow us to parse easier later. + */ + osSep = os_fileSep(); + stackScope = os_str_replace (fname, osSep, "/", 0); + + if(stackScope[0] != '\0'){ /* strlen(stackScope) > 0 */ + do + { + token = strchr(stackScope, '/'); + /* make sure this is not the last part of the file name, for example + * for the file name org/opensplice/foo.java we only want to create + * directories for org and opensplice, the foo.java part is not a + * directory. So we can simply state if no '/' char can be + * found then we must be at the end part of the file name! + */ + if(token) + { + *token = '\0'; + token++; + /* reallocate pathName to include stackScope */ + pathName = os_realloc(pathName, strlen(pathName) + strlen(stackScope) + 1); + os_strcat (pathName, stackScope); + stackScope = token; + statRes = os_stat (pathName, &statbuf); + if (statRes == os_resultFail) { + /* @todo */ + /* Assume the file does not exist. On some platforms */ + /* a check to see if errno == ENOENT would be more conclusive */ + /* That fails on WIN32 however because stat is not fully */ + /* compatible. Only an os_stat implementation can solve that. */ + + os_mkdir(pathName, 0777); + statRes = os_stat(pathName, &statbuf); + } else { + if (!OS_ISDIR(statbuf.stat_mode)) { + printf ("File %s already exists, but is not a directory\n", pathName); + os_free(pathName); + return 0; + } + } + if (statRes == os_resultFail) { + printf ("Error when creating directory %s\n", pathName); + os_free(pathName); + return 0; + } + /* reallocate pathName to include os_fileSep() */ + pathName = os_realloc(pathName, strlen(pathName) + strlen(stackScope) + strlen(os_fileSep()) + 1); + os_strcat (pathName, os_fileSep()); + } + } while(token); + } + /* free the memory allocated to pathName */ + os_free(pathName); + return 1; +} + +void +idl_openMatlabPackage ( + idl_scope scope, + const char *name) +{ + os_char *fname = NULL; + os_char *package_file = NULL; + + package_file = idl_scopeStackMatlab(scope, os_fileSep(), name); + fname = os_malloc(strlen (package_file) + strlen (".m") + 1); + os_strcpy(fname, package_file); + os_strcat(fname, ".m"); + if (idl_createDir(fname)) { + idl_fileSetCur(idl_fileOutNew (fname, "w")); + if (idl_fileCur() == NULL) { + idl_fileOpenError(fname); + } + } else { + idl_fileSetCur(NULL); + } + os_free(package_file); + os_free(fname); +} + +void +idl_closeMatlabPackage ( + void) +{ + if (idl_fileCur()) { + idl_fileOutFree(idl_fileCur()); + } +} diff --git a/src/tools/idlpp/code/idl_genMatlabHelper.h b/src/tools/idlpp/code/idl_genMatlabHelper.h new file mode 100644 index 000000000..ca6876518 --- /dev/null +++ b/src/tools/idlpp/code/idl_genMatlabHelper.h @@ -0,0 +1,50 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef CODE_IDL_GENMATLABHELPER_H_ +#define CODE_IDL_GENMATLABHELPER_H_ + +#include "idl_scope.h" +#include "idl_tmplExp.h" +#include "idl_program.h" + +c_char * idl_matlabId(const char *identifier); +c_char *idl_scopeStackMatlab (idl_scope scope, const char *scopeSepp, const char *name); +void idl_openMatlabPackage (idl_scope scope, const char *name); +void idl_closeMatlabPackage (void); +c_char *idl_matlabTypeName(idl_typeSpec typeSpec); +void idl_streamOutTypeInfoEntries(idl_streamOut so, const char *name, idl_typeSpec typeSpec); +int idl_matlabIsSequence(idl_typeSpec typeSpec); +int idl_matlabIsArray(idl_typeSpec typeSpec); +int idl_matlabIsArrayOfSequences(idl_typeSpec typeSpec); +int idl_matlabIsString(idl_typeSpec typeSpec); +int idl_matlabIsStruct(idl_typeSpec typeSpec); +int idl_matlabIsEnum(idl_typeSpec typeSpec); +int idl_matlabIsNotMultiValued(idl_typeSpec typeSpec); +idl_typeSpec idl_matlabFindArrayWrappedType(idl_typeSpec typeSpec); +idl_typeSpec idl_matlabFindSequenceWrappedType(idl_typeSpec typeSpec); +c_ulong idl_matlabStringBound(idl_typeSpec typeSpec); +c_ulong idl_matlabSequenceBound(idl_typeSpec typeSpec); +int idl_scopeIsInStruct(idl_scope scope); +int idl_matlabShouldBeCellArray(idl_typeSpec typeSpec); +c_char *idl_matlabFormattedDimensions(idl_typeSpec typeSpec); +c_char *idl_matlabFieldInitialization(idl_typeSpec typeSpec); +#endif /* CODE_IDL_GENMATLABHELPER_H_ */ diff --git a/src/tools/idlpp/code/idl_genMetaHelper.c b/src/tools/idlpp/code/idl_genMetaHelper.c index a9c351113..da91cdcf4 100644 --- a/src/tools/idlpp/code/idl_genMetaHelper.c +++ b/src/tools/idlpp/code/idl_genMetaHelper.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -77,7 +78,8 @@ idl_cutXMLmeta ( * let's cut it between two tags. * So let's find a '>' after the first MIN_SUBMETA_LENGTH chars after we check that are * sufficient chars to do this, if not it means we have split it sufficiently and just - * use the remaining chars. */ + * use the remaining chars. + */ if(currentPosLength > MIN_SUBMETA_LENGTH) { tmp = strchr(currentPos + MIN_SUBMETA_LENGTH, '>'); @@ -111,7 +113,8 @@ idl_cutXMLmeta ( char * idl_genXMLmeta ( - c_type type) + c_type type, + c_bool escapeQuote) { sd_serializer metaSer; sd_serializedData serData; @@ -121,14 +124,15 @@ idl_genXMLmeta ( replaceInfo = idl_catsDefConvertAll(idl_catsDefDefGet()); replaceInfoStac = idl_stacDefConvertAll(idl_stacDefDefGet()); - metaSer = sd_serializerXMLTypeinfoNew (c_getBase(c_object(type)), TRUE); + metaSer = sd_serializerXMLTypeinfoNew (c_getBase(c_object(type)), escapeQuote); if (metaSer) { serData = sd_serializerSerialize (metaSer, c_object(type)); if (serData) { - metaDescription = sd_serializerToString (metaSer, serData); - } + metaDescription = sd_serializerToString (metaSer, serData); + sd_serializedDataFree(serData); + } sd_serializerFree (metaSer); } idl_catsDefRestoreAll(idl_catsDefDefGet(), replaceInfo); diff --git a/src/tools/idlpp/code/idl_genMetaHelper.h b/src/tools/idlpp/code/idl_genMetaHelper.h index a79f5c020..202a64b31 100644 --- a/src/tools/idlpp/code/idl_genMetaHelper.h +++ b/src/tools/idlpp/code/idl_genMetaHelper.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,7 +25,7 @@ #include "c_metabase.h" -char *idl_genXMLmeta (c_type type); +char *idl_genXMLmeta (c_type type, c_bool escapeQuote); /* * dds#2745 diff --git a/src/tools/idlpp/code/idl_genPython.c b/src/tools/idlpp/code/idl_genPython.c new file mode 100644 index 000000000..d02efd0fd --- /dev/null +++ b/src/tools/idlpp/code/idl_genPython.c @@ -0,0 +1,2359 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "idl_genPython.h" + +#include "idl_genMetaHelper.h" +#include "idl_keyDef.h" +#include "idl_tmplExp.h" +#include "ut_stack.h" +#include "ut_collection.h" +#include "idl_constSpecifier.h" + +#include "os_abstract.h" + +#include +#include +#include + +typedef struct file_stack_entry_t { + idl_fileOut cur_file; + ut_set includes; + idl_scope scope; + idl_streamOut moduleContents; +} file_stack_entry_t; + +typedef struct union_case_t union_case_t; +typedef struct union_case_label_t { + union_case_t *union_case; + c_bool is_default; + char *value; +} union_case_label_t; + +struct union_case_t { + const char *name; + const char *ddstype; + const char *pytype; + const char *pydefault; + const char *pack_string; + const char *serialize; + const char *deserialize; + const char *checker; + c_ulong nlabels; + union_case_label_t *labels; + union_case_label_t *default_label; +}; + +typedef struct union_info_t { + const char *name; + const char *d_ddstype; + const char *d_pytype; + const char *d_pydefault; + const char *d_pack_string; + const char *d_pack_discriminator; + const char *d_deserialize; + const char *d_checker; + c_ulong ncases; + union_case_t *cases; + union_case_t *artificial_case; +} union_info_t; +static ut_stack fileStack = NULL; +static int unionCaseLabelNext = 0; +static int unionCaseNext = 0; +static union_case_t *unionCase = NULL; +static union_info_t *unionInfo = NULL; +static ut_set includes = NULL; +static idl_scope fileScope = NULL; +static const char *baseModuleDir = NULL; +static idl_streamOut moduleContents = NULL; +static idl_streamOut fieldInits = NULL; +static idl_streamOut fieldNames = NULL; +static idl_streamOut fieldPackString = NULL; +static idl_streamOut fieldDeserialize = NULL; +static idl_streamOut fieldPackValues = NULL; +static int idlEnumFieldCount = 0; + +static void union_case_label_free(union_case_label_t *c) +{ + os_free((void*)c->value); +} + +static void union_case_free(union_case_t *c, void *arg) +{ + c_ulong i; + + OS_UNUSED_ARG(arg); + + os_free((void*)c->ddstype); + os_free((void*)c->deserialize); + os_free((void*)c->name); + os_free((void*)c->pack_string); + os_free((void*)c->pydefault); + os_free((void*)c->pytype); + os_free((void*)c->serialize); + os_free((void*)c->checker); + + for(i = 0; i < c->nlabels; i++) { + union_case_label_free(&c->labels[i]); + } + if(c->default_label) { + union_case_label_free(c->default_label); + os_free(c->default_label); + } + if(c->labels) { + os_free((void*)c->labels); + } +} + +static void union_info_free(union_info_t *ui, void *arg) +{ + c_ulong i; + + OS_UNUSED_ARG(arg); + + os_free((void*)ui->name); + os_free((void*)ui->d_ddstype); + os_free((void*)ui->d_pytype); + os_free((void*)ui->d_pydefault); + os_free((void*)ui->d_pack_string); + os_free((void*)ui->d_deserialize); + os_free((void*)ui->d_pack_discriminator); + os_free((void*)ui->d_checker); + + for(i = 0; i < ui->ncases; i++) { + union_case_free(&ui->cases[i],NULL); + } + os_free(ui->cases); + if(ui->artificial_case) { + union_case_free(ui->artificial_case, NULL); + os_free(ui->artificial_case); + } + + os_free(ui); +} + +static void +idl_genPythonMkpath(const char *dir_path) +{ + c_char *outCur = idl_dirOutCur(); + char *full_path_name; + + if(outCur) { + full_path_name = os_malloc(strlen(outCur) + strlen(os_fileSep()) + strlen(dir_path) + 1); + os_sprintf(full_path_name, "%s%s%s", outCur, os_fileSep(), dir_path); + } else { + full_path_name = os_strdup(dir_path); + } + + if(os_mkpath(full_path_name, 0777) == os_resultFail) { + printf("Error: Could not create path %s\n", full_path_name); + os_free(full_path_name); + exit(-1); + } + os_free(full_path_name); +} + +static os_equality includesCompare (void *o1, void *o2, void *args) +{ + char *s1 = (char *)o1; + char *s2 = (char *)o2; + int cmp = strcmp(s1, s2); + + OS_UNUSED_ARG(args); + + if(cmp < 0) { + return OS_LT; + } else if(cmp == 0) { + return OS_EQ; + } else { + return OS_GT; + } +} + +static void +includesFree(void *o, void *arg) +{ + OS_UNUSED_ARG(arg); + os_free(o); +} + +static ut_set +includesNew() +{ + return ut_setNew(includesCompare, NULL, includesFree, NULL); + +} + +static void +includesAdd(char *include) +{ + if(!ut_contains(ut_collection(includes), include)) { + char *to_insert = os_strdup(include); /* make a copy for the set */ + (void)ut_setInsert(includes, to_insert); + } +} + +static os_int32 includesPrint_action(void *o, void *arg) +{ + char *include = (char *)o; + idl_fileOut fileOut = (idl_fileOut) arg; + idl_fileOutPrintf(fileOut, "import %s\n", include); + + return 1; +} + +static void +includesPrint(idl_fileOut fileOut) +{ + if(ut_count(ut_collection(includes)) > 0) { + ut_walk(ut_collection(includes), includesPrint_action, (void *)fileOut); + idl_fileOutPrintf(fileOut, "\n"); + } +} + +static char * +idl_genPythonPyQName(idl_typeSpec typeSpec) { + idl_typeUser typeUser = idl_typeUser(typeSpec); + idl_scope scope = idl_typeUserScope(typeUser); + + if(idl_scopeEqual(scope, fileScope)) { + return os_strdup(idl_typeSpecName(typeSpec)); + } else { + char *include = idl_scopeStack(idl_typeUserScope(typeUser), ".", NULL); + char *ddsQname = idl_scopeStack(idl_typeUserScope(typeUser), ".", idl_typeSpecName(typeSpec)); + const char *basename = idl_scopeBasename(scope); + char *pyQname = os_malloc(strlen(basename) + 1 + strlen(ddsQname) + 1); + char *pyInclude = os_malloc(strlen(basename) + 1 + strlen(include) + 1); + + os_sprintf(pyQname, "%s.%s", basename, ddsQname); + if(strlen(include) == 0) { + os_sprintf(pyInclude, "%s", basename); + } else { + os_sprintf(pyInclude, "%s.%s", basename, include); + } + includesAdd(pyInclude); + os_free(pyInclude); + os_free(include); + os_free(ddsQname); + os_free((void*)basename); + return pyQname; + } +} + +static void +idl_genPythonPushCurFile(idl_scope scope, const char *file_path) +{ + idl_fileOut newOut; + file_stack_entry_t *entry = (file_stack_entry_t *)os_malloc(sizeof(file_stack_entry_t)); + + if(fileStack == NULL) { + fileStack = ut_stackNew(UT_STACK_DEFAULT_INC); + } + + newOut = idl_fileOutNew(file_path, "w"); + if(newOut == NULL) { + printf("Error: Could not open \"%s\" for write.\n", file_path); + exit(-1); + } + + entry->cur_file = idl_fileCur(); + entry->includes = includes; + entry->scope = fileScope; + entry->moduleContents = moduleContents; + ut_stackPush(fileStack, entry); + + idl_fileSetCur(newOut); + includes = includesNew(); + fileScope = idl_scopeDup(scope); + moduleContents = idl_streamOutNew(0); +} + +static void +idl_genPythonPopCurFile() +{ + file_stack_entry_t *entry = (file_stack_entry_t *)((fileStack && !ut_stackIsEmpty(fileStack)) ? ut_stackPop(fileStack) : NULL); + if(entry) { + idl_fileOut curFile = entry->cur_file; + + /* close current file */ + if(idl_fileCur()) { + idl_fileOutFree(idl_fileCur()); + } + idl_fileSetCur(curFile); + + if(includes != NULL) { + ut_setFree(includes); + } + includes = entry->includes; + + if(fileScope) { + c_char *basename = idl_scopeBasename(fileScope); + if(basename) { + os_free((void*)basename); + } + idl_scopeFree(fileScope); + } + fileScope = entry->scope; + + if (moduleContents) { + idl_streamOutFree(moduleContents); + } + moduleContents = entry->moduleContents; + + os_free(entry); + } + + /* free the stack, if it's empty */ + if(fileStack && ut_stackIsEmpty(fileStack)) { + ut_stackFree(fileStack); + fileStack = NULL; + } +} + +static const char* +idl_genPythonDDSType( + idl_scope scope, + const char *name, + idl_typeSpec typeSpec) +{ + OS_UNUSED_ARG(scope); + OS_UNUSED_ARG(name); + + switch(idl_typeSpecType(typeSpec)) { + case idl_tbasic: { + switch(idl_typeBasicType(idl_typeBasic(typeSpec))) { + case idl_short: + return os_strdup("short"); + case idl_ushort: + return os_strdup("unsigned short"); + case idl_long: + return os_strdup("long"); + case idl_ulong: + return os_strdup("unsigned long"); + case idl_longlong: + return os_strdup("long long"); + case idl_ulonglong: + return os_strdup("unsigned long long"); + case idl_float: + return os_strdup("float"); + case idl_double: + return os_strdup("double"); + case idl_char: + return os_strdup("char"); + case idl_string: + return os_strdup("string"); + case idl_boolean: + return os_strdup("boolean"); + case idl_octet: + return os_strdup("octet"); + } + } + case idl_ttypedef: { + return idl_genPythonDDSType(scope, name, idl_typeDefActual(idl_typeDef(typeSpec))); + } + case idl_tenum: + case idl_tunion: + case idl_tstruct: { + idl_typeUser typeUser = idl_typeUser(typeSpec); + return idl_scopeStack(idl_typeUserScope(typeUser), "::", idl_typeSpecName(typeSpec)); + } + case idl_tarray: { +#define FMT_DDS_TYPE_ARRAY "%s[%d]" + const char *inner = idl_genPythonDDSType(scope, name, idl_typeArrayType(idl_typeArray(typeSpec))); + c_ulong dim = idl_typeArraySize(idl_typeArray(typeSpec)); + char *buffer = os_malloc(strlen(FMT_DDS_TYPE_ARRAY) + strlen(inner) + 10 /*dim max*/ + 1); + os_sprintf(buffer, FMT_DDS_TYPE_ARRAY, inner, dim); + os_free((void *)inner); + return buffer; + } + case idl_tseq: { +#define FMT_DDS_TYPE_SEQ "sequence<%s>" +#define FMT_DDS_TYPE_SEQ_BOUNDED "sequence<%s, %d>" + const char *inner = idl_genPythonDDSType(scope, name, idl_typeSeqType(idl_typeSeq(typeSpec))); + c_ulong size = idl_typeSeqMaxSize(idl_typeSeq(typeSpec)); + char *buffer = size == 0 ? os_malloc(strlen(FMT_DDS_TYPE_SEQ) + strlen(inner) + 1) + : os_malloc(strlen(FMT_DDS_TYPE_SEQ_BOUNDED) + strlen(inner) + 10 /*dim max*/ + 1); + if(size == 0) { + os_sprintf(buffer, FMT_DDS_TYPE_SEQ, inner); + } else { + os_sprintf(buffer, FMT_DDS_TYPE_SEQ_BOUNDED, inner, size); + } + os_free((void *)inner); + return buffer; + } + } + + return os_strdup(""); +} + +static const char* +idl_genPythonPyType( + idl_scope scope, + const char *name, + idl_typeSpec typeSpec) +{ + OS_UNUSED_ARG(scope); + OS_UNUSED_ARG(name); + + switch(idl_typeSpecType(typeSpec)) { + case idl_tbasic: { + switch(idl_typeBasicType(idl_typeBasic(typeSpec))) { + case idl_short: + case idl_ushort: + case idl_long: + case idl_ulong: + case idl_longlong: + case idl_ulonglong: + case idl_octet: + return os_strdup("int"); + case idl_float: + case idl_double: + return os_strdup("float"); + case idl_char: + return os_strdup("str"); + case idl_string: + return os_strdup("str"); + case idl_boolean: + return os_strdup("bool"); + } + } + case idl_ttypedef: { + return idl_genPythonPyType(scope, name, idl_typeDefActual(idl_typeDef(typeSpec))); + } + case idl_tenum: + case idl_tstruct: + case idl_tunion: + return idl_genPythonPyQName(typeSpec); + case idl_tarray: + return os_strdup("list"); + case idl_tseq: + return os_strdup("list"); + } + return os_strdup(""); +} + +static const char* +idl_genPythonPyDefault( + idl_scope scope, + const char *name, + idl_typeSpec typeSpec) +{ + OS_UNUSED_ARG(scope); + OS_UNUSED_ARG(name); + + switch(idl_typeSpecType(typeSpec)) { + case idl_tbasic: { + switch(idl_typeBasicType(idl_typeBasic(typeSpec))) { + case idl_short: + case idl_ushort: + case idl_long: + case idl_ulong: + case idl_longlong: + case idl_ulonglong: + case idl_octet: + return os_strdup("0"); + case idl_float: + case idl_double: + return os_strdup("0.0"); + case idl_char: + return os_strdup("'\\0'"); + case idl_string: + return os_strdup("''"); + case idl_boolean: + return os_strdup("False"); + } + } + case idl_ttypedef: { + return idl_genPythonPyDefault(scope, name, idl_typeDefActual(idl_typeDef(typeSpec))); + } + case idl_tenum: { +#define FMT_PYDEFAULT_ENUM "%s(0)" + char *pyQName = idl_genPythonPyQName(typeSpec); + char *buffer = os_malloc(strlen(FMT_PYDEFAULT_ENUM) - 2 + strlen(pyQName) + 1); + os_sprintf(buffer, FMT_PYDEFAULT_ENUM, pyQName); + os_free(pyQName); + return buffer; + } + case idl_tstruct: + case idl_tunion: { +#define FMT_PYDEFAULT_STRUCT "%s()" + char *pyQName = idl_genPythonPyQName(typeSpec); + char *buffer = os_malloc(strlen(FMT_PYDEFAULT_STRUCT) - 2 + strlen(pyQName) + 1); + os_sprintf(buffer, FMT_PYDEFAULT_STRUCT, pyQName); + os_free(pyQName); + return buffer; + } + case idl_tarray: { +#define FMT_PYDEFAULT_ARRAY "[%s for _ in range(%d)]" + const char *nestedDefault = idl_genPythonPyDefault(scope, name, idl_typeArrayType(idl_typeArray(typeSpec))); + char *buffer = os_malloc(strlen(FMT_PYDEFAULT_ARRAY) + strlen(nestedDefault) + 10/*max int len*/ + 1); + os_sprintf(buffer, FMT_PYDEFAULT_ARRAY, nestedDefault, idl_typeArraySize(idl_typeArray(typeSpec))); + os_free((void*)nestedDefault); + return buffer; + } + case idl_tseq: + /* [] */ + return os_strdup("[]"); + } + return os_strdup(""); +} + +static idl_typeSpec +idl_genPythonArrayActual(idl_typeArray typeArray) +{ + idl_typeSpec typeSpec = idl_typeArrayActual(typeArray); + /* may have navigated into a typedef. Find it's actual type */ + if (idl_typeSpecType(typeSpec) == idl_ttypedef) { + typeSpec = idl_typeDefActual(idl_typeDef(typeSpec)); + } + /* there was a typedef, it may have refered to an array. recurse */ + if (idl_typeSpecType(typeSpec) == idl_tarray) { + return idl_genPythonArrayActual(idl_typeArray(typeSpec)); + } else { + return typeSpec; + } +} + +static int idl_genPythonArrayDims(idl_typeArray typeArray) +{ + int ndims = 1; + idl_type type; + + idl_typeSpec typeSpec = idl_typeArrayType(typeArray); + for(type = idl_typeSpecType(typeSpec); type == idl_tarray || type == idl_ttypedef; type = idl_typeSpecType(typeSpec)) { + if(type == idl_tarray) { + typeSpec = idl_typeArrayType(idl_typeArray(typeSpec)); + ndims += 1; + } else { + typeSpec = idl_typeDefActual(idl_typeDef(typeSpec)); + } + } + return ndims; +} + +static c_ulong idl_genPythonArrayNumElements(idl_typeArray typeArray) +{ + c_ulong nele = idl_typeArraySize(typeArray); + idl_type type; + + idl_typeSpec typeSpec = idl_typeArrayType(typeArray); + for(type = idl_typeSpecType(typeSpec); type == idl_tarray || type == idl_ttypedef; type = idl_typeSpecType(typeSpec)) { + if(type == idl_tarray) { + nele *= idl_typeArraySize(idl_typeArray(typeSpec)); + typeSpec = idl_typeArrayType(idl_typeArray(typeSpec)); + } else { + typeSpec = idl_typeDefActual(idl_typeDef(typeSpec)); + } + } + return nele; +} + +static int +idl_genPythonPyPackNeedsAlign( + idl_typeSpec typeSpec) +{ + switch(idl_typeSpecType(typeSpec)) { + case idl_tstruct: + case idl_tseq: + return 1; + case idl_tarray: + return idl_genPythonPyPackNeedsAlign(idl_typeArrayActual(idl_typeArray(typeSpec))); + case idl_ttypedef: + return idl_genPythonPyPackNeedsAlign(idl_typeDefActual(idl_typeDef(typeSpec))); + default: + return 0; + } +} + +static const char* +idl_genPythonPyPackString( + idl_scope scope, + const char *name, + idl_typeSpec typeSpec) +{ + OS_UNUSED_ARG(scope); + OS_UNUSED_ARG(name); + + switch(idl_typeSpecType(typeSpec)) { + case idl_tbasic: { + switch(idl_typeBasicType(idl_typeBasic(typeSpec))) { + case idl_short: + return os_strdup("'h'"); + case idl_ushort: + return os_strdup("'H'"); + case idl_long: + return os_strdup("'i'"); + case idl_ulong: + return os_strdup("'I'"); + case idl_longlong: + return os_strdup("'q'"); + case idl_ulonglong: + return os_strdup("'Q'"); + case idl_float: + return os_strdup("'f'"); + case idl_double: + return os_strdup("'d'"); + case idl_char: + return os_strdup("'c'"); + case idl_string: + return os_strdup("'P'"); + case idl_boolean: + return os_strdup("'?'"); + case idl_octet: + return os_strdup("'B'"); + } + } + case idl_ttypedef: { + return idl_genPythonPyPackString(scope, name, idl_typeDefActual(idl_typeDef(typeSpec))); + } + case idl_tenum: + return os_strdup("'i'"); + case idl_tstruct: + case idl_tunion: { +#define FMT_PYPACK_STRUCT "%s._get_packing_fmt()" + char *full_name = idl_genPythonPyQName(typeSpec); + char *result = os_malloc(strlen(FMT_PYPACK_STRUCT) + strlen(full_name) + 1 - 2); + os_sprintf(result, FMT_PYPACK_STRUCT, full_name); + os_free(full_name); + return result; + } + case idl_tarray: { +#define FMT_PYPACK_ARRAY "%s * %d" + c_ulong nele = idl_genPythonArrayNumElements(idl_typeArray(typeSpec)); + idl_typeSpec typeSpecActual = idl_genPythonArrayActual(idl_typeArray(typeSpec)); + const char *nestedDefault = idl_genPythonPyPackString(scope, name, typeSpecActual); + char *buffer = os_malloc(strlen(FMT_PYPACK_ARRAY) + strlen(nestedDefault) + 10/*max int len*/ + 1); + os_sprintf(buffer, FMT_PYPACK_ARRAY, nestedDefault, nele); + os_free((void*)nestedDefault); + return buffer; + } + case idl_tseq: + return os_strdup("ddsutil._pad_fmt('iiP?')"); + } + return os_strdup(""); +} + +static const char* +idl_genPythonPyDeserialize( + idl_scope scope, + const char *name, + idl_typeSpec typeSpec, + const char *data_var) +{ + OS_UNUSED_ARG(scope); + OS_UNUSED_ARG(name); + + switch(idl_typeSpecType(typeSpec)) { + case idl_tbasic: { + switch(idl_typeBasicType(idl_typeBasic(typeSpec))) { + case idl_short: + case idl_ushort: + case idl_long: + case idl_ulong: + case idl_longlong: + case idl_ulonglong: + case idl_float: + case idl_double: + case idl_octet: + case idl_boolean: { +#define FMT_PYDESERIALIZE_PRIM "%s.pop(0)" + char *buffer = os_malloc(strlen(FMT_PYDESERIALIZE_PRIM) + strlen(data_var) + 1); + os_sprintf(buffer, FMT_PYDESERIALIZE_PRIM, data_var); + return buffer; + } + case idl_string: { +#define FMT_PYDESERIALIZE_STRING "ddsutil._ptr_to_bytes(%s.pop(0)).decode('ISO-8859-1')" + char *buffer = os_malloc(strlen(FMT_PYDESERIALIZE_STRING) + strlen(data_var) + 1); + os_sprintf(buffer, FMT_PYDESERIALIZE_STRING, data_var); + return buffer; + } + case idl_char: { +#define FMT_PYDESERIALIZE_CHAR "%s.pop(0).decode('ISO-8859-1')" + char *buffer = os_malloc(strlen(FMT_PYDESERIALIZE_CHAR) + strlen(data_var) + 1); + os_sprintf(buffer, FMT_PYDESERIALIZE_CHAR, data_var); + return buffer; + + } + } + break; + } + case idl_ttypedef: { + return idl_genPythonPyDeserialize(scope, name, idl_typeDefActual(idl_typeDef(typeSpec)), data_var); + } + case idl_tenum: { +#define FMT_PYDESERIALIZE_ENUM "%s(%s.pop(0))" + char *pyQName = idl_genPythonPyQName(typeSpec); + char *buffer = os_malloc(strlen(FMT_PYDESERIALIZE_ENUM) + strlen(pyQName) + strlen(data_var) + 1); + os_sprintf(buffer, FMT_PYDESERIALIZE_ENUM, pyQName, data_var); + os_free(pyQName); + return buffer; + } + case idl_tunion: + case idl_tstruct: { +#define FMT_PYDESERIALIZE_STRUCT "%s()._deserialize(%s)" + char *pyQName = idl_genPythonPyQName(typeSpec); + char *buffer = os_malloc(strlen(FMT_PYDESERIALIZE_STRUCT) + strlen(pyQName) + strlen(data_var)+ 1); + os_sprintf(buffer, FMT_PYDESERIALIZE_STRUCT, pyQName, data_var); + os_free(pyQName); + return buffer; + } + case idl_tarray: { +#define FMT_PYDESERIALIZE_ARRAY "[%s for _ in range (%d)]" + /* TODO: need to check if array type is struct or seq, and do like struct */ + idl_typeSpec nestedType = idl_typeArrayType(idl_typeArray(typeSpec)); + const char *inner = idl_genPythonPyDeserialize(scope, name, nestedType, data_var); + char *buffer = os_malloc(strlen(FMT_PYDESERIALIZE_ARRAY) + strlen(inner) + 10/*max int len*/ + 1); + os_sprintf(buffer, FMT_PYDESERIALIZE_ARRAY, inner, idl_typeArraySize(idl_typeArray(typeSpec))); + os_free((void*)inner); + return buffer; + } + case idl_tseq: { +#define FMT_PYDESERIALIZE_SEQ "ddsutil._deserialize_seq(%s, %s, lambda seq_data: %s)" + idl_typeSpec nestedType = idl_typeSeqType(idl_typeSeq(typeSpec)); + const char *inner = idl_genPythonPyDeserialize(scope, name, nestedType, "seq_data"); + const char *packFmt = idl_genPythonPyPackString(scope, name, nestedType); + char *buffer = os_malloc(strlen(FMT_PYDESERIALIZE_SEQ) + strlen(data_var) + strlen(packFmt) + strlen(inner) + 1); + os_sprintf(buffer, FMT_PYDESERIALIZE_SEQ, data_var, packFmt, inner); + os_free((void*)packFmt); + os_free((void*)inner); + return buffer; + } + } + return os_strdup(""); +} + +static const char* +idl_genPythonPyPackField( + idl_scope scope, + const char *name, + idl_typeSpec typeSpec, + const char *arg_expr, + const char *field_expr) +{ + OS_UNUSED_ARG(scope); + OS_UNUSED_ARG(name); + + switch(idl_typeSpecType(typeSpec)) { + case idl_tbasic: { + switch(idl_typeBasicType(idl_typeBasic(typeSpec))) { + case idl_short: + case idl_ushort: + case idl_long: + case idl_ulong: + case idl_longlong: + case idl_ulonglong: + case idl_float: + case idl_double: + case idl_octet: + case idl_boolean: { +#define PKG_FLD_BASIC "%s.append(%s)" + char *result = os_malloc(strlen(PKG_FLD_BASIC) + strlen(arg_expr) + strlen(field_expr) + 1 - 2); + os_sprintf(result, PKG_FLD_BASIC, arg_expr, field_expr); + return result; + } + case idl_string: { +#define PKG_FLD_STRING "%s.append(ddsutil._bytes_to_ptr(%s.encode('ISO-8859-1')))" + /* FIXME: Does this preserve the string data? Only if the string field is bytes, I think */ + char *result = os_malloc(strlen(PKG_FLD_STRING) + strlen(arg_expr) + strlen(field_expr) + 1 - 2); + os_sprintf(result, PKG_FLD_STRING, arg_expr, field_expr); + return result; + } + case idl_char: { +#define PKG_FLD_CHAR "%s.append(%s.encode('ISO-8859-1'))" + char *result = os_malloc(strlen(PKG_FLD_CHAR) + strlen(arg_expr) + strlen(field_expr) + 1 - 2); + os_sprintf(result, PKG_FLD_CHAR, arg_expr, field_expr); + return result; + } + } + break; + } + case idl_ttypedef: { + return idl_genPythonPyPackField(scope, name, idl_typeDefActual(idl_typeDef(typeSpec)), arg_expr, field_expr); + } + case idl_tenum: { +#define PACK_FLD_ENUM "%s.append(%s.value)" + char *result = os_malloc(strlen(PACK_FLD_ENUM) + strlen(arg_expr) + strlen(field_expr) + 1 - 2); + os_sprintf(result, PACK_FLD_ENUM, arg_expr, field_expr); + return result; + } + case idl_tunion: + case idl_tstruct: { +#define PACK_FLD_STRUCT "%s.extend(%s._get_packing_args())" + char *result = os_malloc(strlen(PACK_FLD_STRUCT) - 2 + strlen(arg_expr) + strlen(field_expr) + 1); + os_sprintf(result, PACK_FLD_STRUCT, arg_expr, field_expr); + return result; + } + case idl_tarray: { +#define PACK_FLD_ARRAY "ddsutil._lin_map_array(%s, %d, lambda v: %s)" + idl_typeSpec innerType = idl_genPythonArrayActual(idl_typeArray(typeSpec)); + int ndims = idl_genPythonArrayDims(idl_typeArray(typeSpec)); + const char *inner = idl_genPythonPyPackField(scope, name, innerType, arg_expr, "v"); + char *result = os_malloc(strlen(PACK_FLD_ARRAY) + strlen(field_expr) + strlen(inner) + 10/*dims*/ + 1); + os_sprintf(result, PACK_FLD_ARRAY, field_expr, ndims, inner); + os_free((void*)inner); + return result; + } + case idl_tseq: { +#define PACK_FLD_SEQ "%s.extend(ddsutil._serialize_seq(%s, %s, lambda seq_args, v: %s))" + idl_typeSpec nestedType = idl_typeSeqType(idl_typeSeq(typeSpec)); + const char *nestedPack = idl_genPythonPyPackField(scope, name, nestedType, "seq_args", "v"); + const char *packFmt = idl_genPythonPyPackString(scope, name, nestedType); + char *buffer = os_malloc(strlen(PACK_FLD_SEQ) + strlen(arg_expr) + strlen(field_expr) + strlen(packFmt) + strlen(nestedPack) + 1); + os_sprintf(buffer, PACK_FLD_SEQ, arg_expr, field_expr, packFmt, nestedPack); + os_free((void*)packFmt); + os_free((void*)nestedPack); + return buffer; + } + } + return os_strdup(""); +} + +static const char* +idl_genPythonPyFieldChecker( + idl_scope scope, + const char *name, + idl_typeSpec typeSpec) +{ + switch(idl_typeSpecType(typeSpec)) { + case idl_tbasic: { + switch(idl_typeBasicType(idl_typeBasic(typeSpec))) { + case idl_short: + return os_strdup("ddsutil._short_checker"); + case idl_ushort: + return os_strdup("ddsutil._ushort_checker"); + case idl_long: + return os_strdup("ddsutil._long_checker"); + case idl_ulong: + return os_strdup("ddsutil._ulong_checker"); + case idl_longlong: + return os_strdup("ddsutil._longlong_checker"); + case idl_ulonglong: + return os_strdup("ddsutil._ulonglong_checker"); + case idl_float: + return os_strdup("ddsutil._float_checker"); + case idl_double: + return os_strdup("ddsutil._float_checker"); + case idl_octet: + return os_strdup("ddsutil._octet_checker"); + case idl_boolean: + return os_strdup("ddsutil._bool_checker"); + case idl_string: { +#define FMT_CHECKER_BSTRING "ddsutil._bounded_str_checker(%d)" + c_ulong bound = idl_typeBasicMaxlen(idl_typeBasic(typeSpec)); + if(bound == 0) { + return os_strdup("ddsutil._str_checker"); + } else { + char *result = os_malloc(strlen(FMT_CHECKER_BSTRING) + 10 + 1); + os_sprintf(result, FMT_CHECKER_BSTRING, bound); + return result; + } + } + case idl_char: + return os_strdup("ddsutil._char_checker"); + } + break; + } + case idl_ttypedef: { + return idl_genPythonPyFieldChecker(scope, name, idl_typeDefActual(idl_typeDef(typeSpec))); + } + case idl_tenum: + case idl_tunion: + case idl_tstruct: { +#define FMT_CHECKER_CLASS "ddsutil._class_checker(%s)" + char *checker_type = idl_genPythonPyQName(typeSpec); + char *result = os_malloc(strlen(FMT_CHECKER_CLASS) + strlen(checker_type) + 1); + os_sprintf(result, FMT_CHECKER_CLASS, checker_type); + os_free((void*)checker_type); + return result; + } + case idl_tarray: { +#define FMT_CHECKER_ARRAY "ddsutil._array_checker(%d,%s)" + idl_typeSpec innerType = idl_typeArrayType(idl_typeArray(typeSpec)); + c_ulong size = idl_typeArraySize(idl_typeArray(typeSpec)); + const char *inner = idl_genPythonPyFieldChecker(scope, name, innerType); + char *result = os_malloc(strlen(FMT_CHECKER_ARRAY) + 10/*size*/ + strlen(inner) + 1); + os_sprintf(result, FMT_CHECKER_ARRAY, size, inner); + os_free((void*)inner); + return result; + } + case idl_tseq: { +#define FMT_CHECKER_SEQ "ddsutil._seq_checker(%d,%s)" + idl_typeSpec innerType = idl_typeSeqType(idl_typeSeq(typeSpec)); + c_ulong size = idl_typeSeqMaxSize(idl_typeSeq(typeSpec)); + const char *inner = idl_genPythonPyFieldChecker(scope, name, innerType); + char *result = os_malloc(strlen(FMT_CHECKER_SEQ) + 10/*size*/ + strlen(inner) + 1); + os_sprintf(result, FMT_CHECKER_SEQ, size, inner); + os_free((void*)inner); + return result; + } + } + return os_strdup(""); + +} + +/** + * Standard control structure to specify that inline + * type definitions are to be processed prior to the + * type itself in contrast with inline. +*/ +static idl_programControl idl_genPythonLoadControl = { + idl_prior +}; + +/** @brief return the program control structure for the splice type generation functions. + */ +static idl_programControl * +idl_getControl( + void *userData) +{ + OS_UNUSED_ARG(userData); + return &idl_genPythonLoadControl; +} + +/** @brief callback function called on opening the IDL input file. + * + * Generate standard file header consisting of: + * - mutiple inclusion prevention + * - inclusion of Splice type definition files + * - inclusion of application specific include files related to other IDL files + * + * @param scope Current scope (not used) + * @param name Name of the IDL input file + */ +static idl_action +idl_fileOpen( + idl_scope scope, + const char *name, + void *userData) +{ + idl_pythonUserData *pythonUserData = (idl_pythonUserData *)userData; + const char *init_py = "__init__.py"; + char *baseModule; + idl_scope base_scope = idl_scopeDup(scope); + + OS_UNUSED_ARG(scope); + /*idl_scopePush(base_scope, idl_scopeElementNew(name, idl_tFile));*/ + + baseModuleDir = (pythonUserData && pythonUserData->baseModuleName) ? pythonUserData->baseModuleName : name; + + idl_genPythonMkpath(baseModuleDir); + + baseModule = os_malloc(strlen(baseModuleDir) + strlen(os_fileSep()) + strlen(init_py) + 1); + os_sprintf(baseModule, "%s%s%s", baseModuleDir, os_fileSep(), init_py); + idl_genPythonPushCurFile(base_scope, baseModule); + idl_scopeFree(base_scope); + + os_free(baseModule); + + /* return idl_explore to indicate that the rest of the file needs to be processed */ + return idl_explore; +} + +/** @brief callback function called on closing the IDL input file. + * + * Generate standard file footer consisting of: + * - mutiple inclusion prevention closure + */ +static void +idl_fileClose ( + void *userData) +{ + OS_UNUSED_ARG(userData); + /* Generate closure of multiple inclusion prevention code */ + + includesPrint(idl_fileCur()); + idl_fileOutPrintf(idl_fileCur(), "%s", idl_streamGet(idl_stream(moduleContents))); + + idl_genPythonPopCurFile(); + + baseModuleDir = NULL; + +} + +/** @brief callback function called on module definition in the IDL input file. + * + * Generate code for the following IDL construct: + * @verbatim + => module { + + }; + @endverbatim + * + * This fuction generates the prototype of the function that + * is responsible for loading the metadata into the database. + * The name of the function is: + * @verbatim + ______load + @endverbatim + * For the Splice types, no further actions are required. + * + * @param scope Current scope (and scope of the module definition) + * @param name Name of the defined module + */ +static idl_action +idl_moduleOpen( + idl_scope scope, + const char *name, + void *userData) +{ + c_char *modPath = idl_scopeStack(scope, os_fileSep(), name); + size_t moduleDirSize = strlen(baseModuleDir) + strlen(os_fileSep()) + strlen(modPath); + const char *init_py = "__init__.py"; + char *moduleDir = os_malloc(moduleDirSize + 1); + char *moduleFile = os_malloc(moduleDirSize + strlen(os_fileSep()) + strlen(init_py) + 1); + idl_scope moduleScope = idl_scopeDup(scope); + + idl_scopePush(moduleScope, idl_scopeElementNew(name, idl_tModule)); + + OS_UNUSED_ARG(scope); + OS_UNUSED_ARG(userData); + + os_sprintf(moduleDir, "%s%s%s", baseModuleDir, os_fileSep(), modPath); + idl_genPythonMkpath(moduleDir); + + os_sprintf(moduleFile, "%s%s%s", moduleDir, os_fileSep(), init_py); + idl_genPythonPushCurFile(moduleScope, moduleFile); + idl_scopeFree(moduleScope); + + os_free(modPath); + os_free(moduleDir); + os_free(moduleFile); + + + /* return idl_explore to indicate that the rest of the module needs to be processed */ + return idl_explore; +} + +static void +idl_moduleClose( + void *userData) +{ + OS_UNUSED_ARG(userData); + + includesPrint(idl_fileCur()); + idl_fileOutPrintf(idl_fileCur(), "%s", idl_streamGet(idl_stream(moduleContents))); + + idl_genPythonPopCurFile(); +} + +/** @brief callback function called on structure definition in the IDL input file. + * + * Generate code for the following IDL construct: + * @verbatim + => struct { + ; + ... ... + ; + }; + @endverbatim + * + * @param scope Current scope (and scope of the structure definition) + * @param name Name of the structure + * @param structSpec Specification of the struct holding the amount of members + */ +static idl_action +idl_structureOpen( + idl_scope scope, + const char *name, + idl_typeStruct structSpec, + void *userData) +{ + const char* keylist; + + OS_UNUSED_ARG(userData); + + /* setup streams to collect field information we will apply on idl_structureClose */ + fieldInits = idl_streamOutNew(0); + fieldNames = idl_streamOutNew(0); + fieldPackString = idl_streamOutNew(0); + fieldDeserialize = idl_streamOutNew(0); + fieldPackValues = idl_streamOutNew(0); + + keylist = idl_keyResolve(idl_keyDefDefGet(), scope, name); + if(keylist) { + /* There's a #pragma keylist, so it's a topic class */ + c_char *typename = idl_scopeStack(scope,"::",name); + c_type type = idl_typeSpecDef(idl_typeSpec(structSpec)); + c_char *metadescriptor = idl_genXMLmeta(type, FALSE); + + includesAdd("dds"); + includesAdd("struct"); + idl_streamOutPrintf(moduleContents, + "class %s__TypeSupport(dds.TypeSupport):\n" + "\n" + " _typename = '%s'\n" + " _keylist = '%s'\n" + " _metadescriptor = '%s'\n" + "\n" + " def __init__(self):\n" + " super(%s__TypeSupport, self).__init__(self._typename,\n" + " self._keylist,\n" + " self._metadescriptor,\n" + " struct.calcsize(%s()._get_packing_fmt()))\n" + "\n" + " def _serialize(self, o):\n" + " if not isinstance(o, %s):\n" + " raise TypeError('Incorrect data type')\n" + " result = o._serialize()\n" + " return result\n" + "\n" + " def _deserialize(self, buf):\n" + " result = %s()\n" + " data = struct.unpack(result._get_packing_fmt(), buf)\n" + " result._deserialize(list(data))\n" + " return result\n" + "\n", + name, + typename, + keylist, + metadescriptor, + name, + name, + name, + name + ); + os_free(metadescriptor); + os_free(typename); + } + + includesAdd("ddsutil"); + idl_streamOutPrintf(moduleContents, + "class %s(ddsutil.TopicDataClass):\n" + "\n", + name); + + if(keylist) { + idl_streamOutPrintf(moduleContents, + " @staticmethod\n" + " def get_type_support():\n" + " ''' Return type support information required for dds.Topic constructor '''\n" + " return %s__TypeSupport()\n" + "\n", + name); + + } + /* return idl_explore to indicate that the rest of the structure needs to be processed */ + return idl_explore; +} + +/** @brief callback function called on end of a structure definition in the IDL input file. + * + * Generate code for the following IDL construct: + * @verbatim + struct { + + ... ... + + => }; + @endverbatim + * + * The structure is closed: + * @verbatim + }; + @endverbatim + * + * @param name Name of the structure (not used) + */ +static void +idl_structureClose( + const char *name, + void *userData) +{ + OS_UNUSED_ARG(name); + OS_UNUSED_ARG(userData); + + idl_streamOutPrintf(moduleContents, + " _member_attributes = (%s)\n" + "\n" + , + idl_streamGet(idl_stream(fieldNames)) + ); + idl_streamOutPrintf(moduleContents, + " def __init__(self, **kwargs):\n" + " ''' Create a %s instance, optionally initializing fields by name '''\n" + " # init attributes to default value\n" + "%s" + " # set values for attributes passed in\n" + " for key, value in kwargs.items():\n" + " if key not in self._member_attributes:\n" + " raise TypeError('Invalid argument name : %%s' %%(key))\n" + " setattr(self, key, value)\n" + "\n" + , + name, + idl_streamGet(idl_stream(fieldInits)) + ); + idl_streamOutPrintf(moduleContents, + " _packing_fmt = None\n" + "\n" + " @staticmethod\n" + " def _get_packing_fmt():\n" + " ''' Returns packing format of this class data '''\n" + " if %s._packing_fmt is not None:\n" + " return %s._packing_fmt\n" + " fmt = ''\n" + "%s\n" + " %s._packing_fmt = ddsutil._pad_fmt(fmt)\n" + " return %s._packing_fmt\n" + "\n" + , + name, + name, + idl_streamGet(idl_stream(fieldPackString)), + name, + name + ); + includesAdd("struct"); + idl_streamOutPrintf(moduleContents, + " def _serialize(self):\n" + " ''' Serialize data for writing '''\n" + " fmt = self._get_packing_fmt()\n" + " args = self._get_packing_args()\n" + " result = struct.pack(fmt, *args)\n" + " return result\n" + "\n" + ); + idl_streamOutPrintf(moduleContents, + " def _deserialize(self, data):\n" + " ''' Initialize values from data returned by struct.unpack()'''\n" + "%s" + " return self;\n" + "\n" + , + idl_streamGet(idl_stream(fieldDeserialize)) + ); + idl_streamOutPrintf(moduleContents, + " def _get_packing_args(self):\n" + " ''' Return an list of data suitable for struct.pack '''\n" + " args = []\n" + "%s" + " return args\n" + "\n", + idl_streamGet(idl_stream(fieldPackValues)) + ); + idl_streamOutFree(fieldNames); + idl_streamOutFree(fieldInits); + idl_streamOutFree(fieldPackString); + idl_streamOutFree(fieldDeserialize); + idl_streamOutFree(fieldPackValues); +} + +/** @brief callback function called on definition of a structure member in the IDL input file. + * + * Generate code for the following IDL construct: + * @verbatim + struct { + => ; + => ... ... + => ; + }; + @endverbatim + * + * @param scope Current scope + * @param name Name of the structure member + * @param typeSpec Type specification of the structure member + */ +static void +idl_structureMemberOpenClose( + idl_scope scope, + const char *name, + idl_typeSpec typeSpec, + void *userData) +{ + const char *ddstype = idl_genPythonDDSType(scope, name, typeSpec); + const char *pytype = idl_genPythonPyType(scope, name, typeSpec); + const char *pydefault = idl_genPythonPyDefault(scope, name, typeSpec); + const char *pydeserialize = idl_genPythonPyDeserialize(scope, name, typeSpec, "data"); + char *field_ref = os_malloc(strlen("self.") + strlen(name) + 1); + const char *pypackfield; + const char *pypackstring = idl_genPythonPyPackString(scope, name, typeSpec); + const char *pychecker = idl_genPythonPyFieldChecker(scope, name, typeSpec); + int alignpackstring = idl_genPythonPyPackNeedsAlign(typeSpec); + + OS_UNUSED_ARG(scope); + OS_UNUSED_ARG(typeSpec); + OS_UNUSED_ARG(userData); + + os_sprintf(field_ref, "self.%s", name); + pypackfield = idl_genPythonPyPackField(scope, name, typeSpec, "args", field_ref); + os_free(field_ref); + + /* maintain values accumulated for idl_structureClose */ + idl_streamOutPrintf(fieldNames, + "%s'%s'", + idl_streamLength(idl_stream(fieldNames)) > 0 + ? ", " : "", + name + ); + idl_streamOutPrintf(fieldInits, + " self.%s = %s\n", + name, + pydefault + ); + if(alignpackstring) { + idl_streamOutPrintf(fieldPackString, " fmt += ddsutil._align(fmt, %s)\n", pypackstring); + } else { + idl_streamOutPrintf(fieldPackString, " fmt += %s\n", pypackstring); + } + idl_streamOutPrintf(fieldDeserialize, + " self.%s = %s\n", + name, + pydeserialize); + idl_streamOutPrintf(fieldPackValues, + " %s\n", + pypackfield); + + /* write member-specific code */ + idl_streamOutPrintf(moduleContents, + " @property\n" + " def %s(self):\n" + " '''\n" + " a DDS %s value\n" + " @rtype: %s\n" + " '''\n" + " return self._%s_\n" + "\n", + name, + ddstype, + pytype, + name); + idl_streamOutPrintf(moduleContents, + " _%s_checker = %s\n" + " @%s.setter\n" + " def %s(self, value):\n" + " self._%s_checker(value)\n" + " self._%s_ = value\n" + "\n", + name, + pychecker, + name, + name, + name, + name + ); + + os_free((void*)pytype); + os_free((void*)pydefault); + os_free((void*)pypackstring); + os_free((void*)pydeserialize); + os_free((void*)pypackfield); + os_free((void*)ddstype); +} + +/** @brief callback function called on definition of an enumeration. + * + * Generate code for the following IDL construct: + * @verbatim + => enum { + ; + ... ... + ; + }; + @endverbatim + * + * @param scope Current scope + * @param name Name of the enumeration + * @param enumSpec Specifies the number of elements in the enumeration + */ +static idl_action +idl_enumerationOpen( + idl_scope scope, + const char *name, + idl_typeEnum enumSpec, + void *userData) +{ + OS_UNUSED_ARG(scope); + OS_UNUSED_ARG(name); + OS_UNUSED_ARG(enumSpec); + OS_UNUSED_ARG(userData); + + includesAdd("enum"); + idl_streamOutPrintf(moduleContents, + "class %s(enum.Enum):\n", + name); + idlEnumFieldCount = 0; + + /* return idl_explore to indicate that the rest of the enumeration needs to be processed */ + return idl_explore; +} + +/** @brief callback function called on closure of an enumeration in the IDL input file. + * + * Generate code for the following IDL construct: + * @verbatim + enum { + ; + ... ... + ; + => }; + @endverbatim + * + * @param name Name of the enumeration + */ +static void +idl_enumerationClose( + const char *name, + void *userData) +{ + OS_UNUSED_ARG(name); + OS_UNUSED_ARG(userData); + + if(idlEnumFieldCount > 0) { + idl_streamOutPrintf(moduleContents, "\n"); + } +} + +/** @brief callback function called on definition of an enumeration element in the IDL input file. + * + * Generate code for the following IDL construct: + * @verbatim + enum { + => , + => ... ... + => + }; + @endverbatim + * + * For the last element generate: + * @verbatim + + @endverbatim + * For any but the last element generate: + * @verbatim + , + @endverbatim + * + * @param scope Current scope + * @param name Name of the enumeration element + */ +static void +idl_enumerationElementOpenClose ( + idl_scope scope, + const char *name, + void *userData) +{ + OS_UNUSED_ARG(scope); + OS_UNUSED_ARG(userData); + + + idl_streamOutPrintf(moduleContents, + " %s = %d\n", + name, + idlEnumFieldCount++); +} +/** @brief callback function called on definition of a union in the IDL input file. + * + * Generate code for the following IDL construct: + * @verbatim + => union switch() { + case label1.1; .. case label1.n; + ; + case label2.1; .. case label2.n; + ... ... + case labeln.1; .. case labeln.n; + ; + default: + ; + }; + @endverbatim + * + * @param scope Current scope + * @param name Name of the union + * @param unionSpec Specifies the number of union cases and the union switch type + */ +static idl_action +idl_unionOpen( + idl_scope scope, + const char *name, + idl_typeUnion unionSpec, + void *userData) +{ + idl_typeSpec typeSpec = idl_typeUnionSwitchKind(unionSpec); + + OS_UNUSED_ARG(userData); + + unionInfo = os_malloc(sizeof(union_info_t)); + memset(unionInfo, 0, sizeof(union_info_t)); + unionInfo->name = os_strdup(name); + unionInfo->d_ddstype = idl_genPythonDDSType(scope, name, typeSpec); + unionInfo->d_pytype = idl_genPythonPyType(scope, name, typeSpec); + unionInfo->d_pydefault = idl_genPythonPyDefault(scope, name, typeSpec); + unionInfo->d_pack_string = idl_genPythonPyPackString(scope, name, typeSpec); + unionInfo->d_pack_discriminator = idl_genPythonPyPackField(scope, name, typeSpec, "args", "self._d"); + unionInfo->d_deserialize = idl_genPythonPyDeserialize(scope, name, typeSpec, "data"); + unionInfo->d_checker = idl_genPythonPyFieldChecker(scope, name, typeSpec); + unionInfo->ncases = idl_typeUnionNoCases(unionSpec); + unionInfo->cases = os_malloc(unionInfo->ncases * sizeof(union_case_t)); + memset(unionInfo->cases, 0, unionInfo->ncases * sizeof(union_case_t)); + unionCaseNext = 0; + + return idl_explore; +} + +static void idl_genPythonUnionLabelMapEntry( + union_case_t *c, + union_case_label_t *cl) +{ + idl_streamOutPrintf(moduleContents, + " %s: {\n", + cl->is_default ? "'__default__'" : cl->value + ); + idl_streamOutPrintf(moduleContents, + " 'initializer': lambda: %s,\n" + " 'case_attr_set': lambda o,v: setattr(o,'%s',v),\n" + " 'to_str': lambda o: '%s={}'.format(o.%s),\n" + " 'packing_fmt': lambda: %s,\n" + " 'pack_case_fld': lambda args, o: %s,\n" + " 'unpack_data': lambda data, o: o.set_%s(%s, o.discriminator),\n", + c->pydefault, + c->name, + c->name, c->name, + c->pack_string, + c->serialize, + c->name, c->deserialize + ); + idl_streamOutPrintf(moduleContents, + " },\n" + ); +} + +static void idl_genPythonUnionLabelArtificialMapEntry() +{ + idl_streamOutPrintf(moduleContents, + " %s: {\n" + " 'initializer': lambda: None,\n" + " 'case_attr_set': lambda o,v: None,\n" + " 'to_str': lambda o: None,\n" + " 'packing_fmt': lambda: '',\n" + " 'pack_case_fld': lambda args, o: None,\n" + " 'unpack_data': lambda data, o: None,\n" + " },\n", + "'__default__'" + ); +} + +/** @brief create a Python tuple containing the listed labels */ +static char *idl_genPythonUnionLabelTuple(c_ulong num_labels, char **labels) +{ + c_ulong i; + char *result; + size_t total_label_size = 0; + + for(i = 0; i < num_labels; i++) { + total_label_size += strlen(labels[i]); + } + + /* allocate space for ([label,]*) */ + result = os_malloc(2 + total_label_size + num_labels + 1); + os_strcpy(result, "("); + for(i = 0; i < num_labels; i++) { + os_strcat(result, labels[i]); + /* Note: always appending a comma handles the pathological Python case of a single element tuple, + * which is indistinguishable from a parenthesized expression. A trailing comma is + * ugly, but essential in that case */ + if(i == 0 || i != num_labels - 1) { + os_strcat(result, ","); + } + } + os_strcat(result,")"); + + return result; +} +/** + * @brief return a Python tuple of all the + */ +static char *idl_genPythonUnionNonDefaultLabels( + union_info_t *ui + ) +{ + c_ulong i, j, num_labels = 0, ii; + char **labels = NULL; + char *result; + + for(i = 0; i < ui->ncases; i++) { + union_case_t *c = &ui->cases[i]; + if(!c->default_label) { + /* only process cases without a default label */ + num_labels += c->nlabels; + } + } + + labels = os_malloc(num_labels * sizeof(char*)); + ii = 0; + for(i = 0; i < ui->ncases; i++) { + union_case_t *c = &ui->cases[i]; + if(!c->default_label) { + /* only process cases without a default label */ + for(j = 0; j < c->nlabels; j++) { + union_case_label_t *cl = &c->labels[j]; + labels[ii++] = cl->value; + } + } + } + + result = idl_genPythonUnionLabelTuple(num_labels, labels); + os_free(labels); + return result; +} + +/** @brief return a Python value that selects the given union case */ +static char *idl_genPythonUnionCaseDefaultSelector( + union_case_t *c + ) +{ + if(c->nlabels > 0) { + return c->labels[0].value; + } else { + return c->default_label->value; + } +} + +static char *idl_genPythonUnionCaseAllSelectors( + union_case_t *c + ) +{ + c_ulong i; + c_ulong num_labels = c->nlabels; + char **labels = os_malloc(num_labels * sizeof(char*)); + char *result; + + for(i = 0; i < num_labels; i++) { + union_case_label_t *cl = &c->labels[i]; + labels[i] = cl->value; + } + + result = idl_genPythonUnionLabelTuple(num_labels, labels); + os_free(labels); + return result; + +} +/** @brief callback function called on closure of a union in the IDL input file. + * + * Generate code for the following IDL construct: + * @verbatim + union switch() { + case label1.1; .. case label1.n; + ; + case label2.1; .. case label2.n; + ... ... + case labeln.1; .. case labeln.n; + ; + default: + ; + => }; + @endverbatim + * + * The union is closed: + * @verbatim + } _u; + }; + @endverbatim + * @param name Name of the union + */ +static void +idl_unionClose ( + const char *name, + void *userData) +{ + c_ulong i, j; + char *nonDefaultLabelSelectors = idl_genPythonUnionNonDefaultLabels(unionInfo); + + OS_UNUSED_ARG(name); + OS_UNUSED_ARG(userData); + + includesAdd("ddsutil"); + + /* output the union 'label_map' variable */ + idl_streamOutPrintf(moduleContents, + "_%s__label_map = {\n", + unionInfo->name + ); + for(i = 0; i < unionInfo->ncases; i++) { + union_case_t *c = &unionInfo->cases[i]; + for(j = 0; j < c->nlabels; j++) { + union_case_label_t *cl = &c->labels[j]; + idl_genPythonUnionLabelMapEntry(c, cl); + } + if(c->default_label) { + idl_genPythonUnionLabelMapEntry(c, c->default_label); + } + } + if(unionInfo->artificial_case) { + idl_genPythonUnionLabelArtificialMapEntry(); + } + idl_streamOutPrintf(moduleContents, + "}\n\n" + ); + idl_streamOutPrintf(moduleContents, + "_%s__packing_fmt, _%s__label_to_padded_packing_fmt = ddsutil._calc_union_formats(%s,_%s__label_map)\n\n", + unionInfo->name, + unionInfo->name, + unionInfo->d_pack_string, + unionInfo->name + ); + /* output the union itself */ + idl_streamOutPrintf(moduleContents, + "class %s(object):\n" + " '''\n" + " Implementation of DDS union %s, with a DDS %s discriminator\n" + " '''\n\n" + "" + " def _label_switch(self, selector, *args):\n" + " v = _%s__label_map.get(self.discriminator, _%s__label_map.get('__default__'))\n" + " return v[selector](*args)\n\n" + "" + " def __init__(self,d=None,v=None,**kwargs):\n" + " '''\n" + " %s()\n" + " %s(descriminator, value)\n", + unionInfo->name, + unionInfo->name, + unionInfo->d_ddstype, + unionInfo->name, + unionInfo->name, + unionInfo->name, + unionInfo->name + ); + + for(i = 0; i < unionInfo->ncases; i++) { + union_case_t *c = &unionInfo->cases[i]; + idl_streamOutPrintf(moduleContents, + " %s(%s=value)\n", + unionInfo->name, + c->name + ); + } + idl_streamOutPrintf(moduleContents, + " @raise ValueError: if discriminator or value is incorrect\n" + " @raise NameError: if a keyword argument is not a union case field\n" + " @raise RuntimeError: if the function invocation is not one of the above formats\n" + " '''\n" + " if d is None and v is None and len(kwargs) == 0:\n" + " self.discriminator = %s\n" /* d_pydefault */ + " elif d is not None and len(kwargs) > 0 or len(kwargs) > 1:\n" + " raise RuntimeError('Incorrect call format')\n" + " elif d is not None:\n" + " if not isinstance(d, %s):\n" /* d_pytype */ + " raise ValueError('First argument is not of type %s')\n" /* d_pytype */ + " self._d = d\n" + " self._label_switch('case_attr_set', self, v)\n" + " elif len(kwargs) == 1:\n" + " cases = [p for p in dir(%s) if isinstance(getattr(%s,p),property) and p != 'discriminator']\n" + " for k, v in kwargs.items():\n" + " if k in cases:\n" + " setattr(self, k, v)\n" + " else:\n" + " raise NameError('Unknown case field: ' + k)\n" + " else:\n" + " raise RuntimeError('Incorrect call format')\n\n" + "", + unionInfo->d_pydefault, + unionInfo->d_pytype, + unionInfo->d_pytype, + unionInfo->name, unionInfo->name + ); + + idl_streamOutPrintf(moduleContents, + " @property\n" + " def discriminator(self):\n" + " '''\n" + " Union discriminator - a DDS %s\n" + " @rtype: %s\n" + " @return: The current descriptor value\n" + " '''\n" + " return self._d\n\n" + "" + " _discriminator_checker = %s\n" + " @discriminator.setter\n" + " def discriminator(self, value):\n" + " '''\n" + " Set the union discriminator - a DDS %s\n" + " @param value: a new discriminator value\n" + " @type value: %s\n" + " '''\n" + " self._discriminator_checker(value)\n" + " self._d = value\n" + " self._v = self._label_switch('initializer')\n\n" + "", + unionInfo->d_ddstype, + unionInfo->d_pytype, + unionInfo->d_checker, + unionInfo->d_ddstype, + unionInfo->d_pytype + ); + + for(i = 0; i < unionInfo->ncases; i++) { + union_case_t *c = &unionInfo->cases[i]; + c_char *defaultCaseSelector = idl_genPythonUnionCaseDefaultSelector(c); + const char *caseSelectors = idl_genPythonUnionCaseAllSelectors(c); + const char *containment_condition = c->default_label ? "not in" : "in"; + const char *containment_condition_neg = c->default_label ? "in" : "not in"; + idl_streamOutPrintf(moduleContents, + " @property\n" + " def %s(self):\n" + " '''\n" + " Union case for discriminator %s %s\n" + " a DDS %s\n" + " @rtype: %s\n", + c->name, + containment_condition, + c->default_label ? nonDefaultLabelSelectors : caseSelectors, + c->ddstype, + c->pytype); + idl_streamOutPrintf(moduleContents, + " @return: an %s representing a DDS %s\n" + " @raise AttributeError: if discriminator does not select this case\n" + " '''\n", + c->pytype, c->ddstype); + idl_streamOutPrintf(moduleContents, + " if self.discriminator %s %s:\n" + " raise AttributeError('discriminator value does not select this attribute')\n" + " return self._v\n\n" + "", + containment_condition_neg, + c->default_label ? nonDefaultLabelSelectors : caseSelectors + ); + idl_streamOutPrintf(moduleContents, + " _%s_checker = %s\n", + c->name, c->checker); + idl_streamOutPrintf(moduleContents, + " @%s.setter\n" + " def %s(self,value):\n" + " '''\n", + c->name, + c->name); + idl_streamOutPrintf(moduleContents, + " Set the union case %s and union discriminator to %s\n" + " @param value: an DDS %s\n" + " @type value: %s'''\n", + c->name, + defaultCaseSelector, + c->ddstype, + c->pytype); + idl_streamOutPrintf(moduleContents, + " if not isinstance(value,%s):\n" + " raise TypeError('Value is not of type %s')\n" + " self.set_%s(value, %s)\n\n" + "", + c->pytype, + c->pytype, + c->name, + defaultCaseSelector + ); + idl_streamOutPrintf(moduleContents, + " def set_%s(self, value, d):\n" + " '''\n" + " Set union case %s with an appropriate discriminator value\n", + c->name, + c->name); + idl_streamOutPrintf(moduleContents, + " @param value: a DDS %s\n" + " @type value: %s\n" + " @param d: a DDS %s, whose value is %s %s\n" + " @type d: %s\n" + " '''\n", + c->ddstype, + c->pytype, + unionInfo->d_ddstype, + containment_condition, + c->default_label ? nonDefaultLabelSelectors : caseSelectors, + unionInfo->d_pytype); + idl_streamOutPrintf(moduleContents, + " if d %s %s:\n" + " raise ValueError('Value 1 does not select case %s')\n", + containment_condition_neg, + c->default_label ? nonDefaultLabelSelectors : caseSelectors, + c->name); + idl_streamOutPrintf(moduleContents, + " if not isinstance(value,%s):\n" + " raise TypeError('Value 2 is not of type %s')\n", + c->pytype, + c->pytype); + idl_streamOutPrintf(moduleContents, + " if not isinstance(d, %s):\n" + " raise TypeError('Value 2 is not of type %s')\n" + " self._d = d\n" + " self._v = value\n\n" + "", + unionInfo->d_pytype, + unionInfo->d_pytype); + os_free((void*)caseSelectors); + } + if(unionInfo->artificial_case) { + c_char *defaultCaseSelector = idl_genPythonUnionCaseDefaultSelector(unionInfo->artificial_case); + idl_streamOutPrintf(moduleContents, + " def set_default(self, d=%s):\n" + " '''\n" + " Set union implicit default case with an appropriate discriminator value\n" + " @param d: a DDS %s, whose value is not in %s\n" + " @type d: %s\n" + " '''\n" + " if d in %s:\n" + " raise ValueError('Value 1 does not select implicit default case')\n" + " self._d = d\n" + " self._v = None\n\n" + "", + defaultCaseSelector, + unionInfo->d_ddstype, + nonDefaultLabelSelectors, + unionInfo->d_pytype, + nonDefaultLabelSelectors + ); + + } + idl_streamOutPrintf(moduleContents, + " def __str__(self):\n" + " formatted = '%s(discrimitator={}'.format(self.discriminator)\n" + " s = self._label_switch('to_str',self)\n" + " if s is not None:\n" + " formatted += ', ' + s\n" + " formatted += ')'\n" + " return formatted\n\n" + "", + unionInfo->name); + idl_streamOutPrintf(moduleContents, + " @staticmethod\n" + " def _get_packing_fmt():\n" + " ''' Returns packing format of this class data '''\n" + " return _%s__packing_fmt\n\n" + "", + unionInfo->name); + idl_streamOutPrintf(moduleContents, + " def _get_case_fmt(self):\n" + " return _%s__label_to_padded_packing_fmt.get(self.discriminator, _%s__label_to_padded_packing_fmt.get('__default__'))\n\n" + "", + unionInfo->name, + unionInfo->name); + idl_streamOutPrintf(moduleContents, + " def _get_packing_args(self):\n" + " args = []\n" + " %s\n" + " fargs = []\n" + " self._label_switch('pack_case_fld', fargs, self)\n" + " args.extend(struct.pack(self._get_case_fmt(), *fargs))\n" + " return args\n\n" + "", + unionInfo->d_pack_discriminator); + idl_streamOutPrintf(moduleContents, + " def _serialize(self):\n" + " ''' Serialize data for writing '''\n" + " fmt = self._get_packing_fmt()\n" + " args = self._get_packing_args()\n" + " result = struct.pack(fmt, *args)\n" + " return result\n\n" + "" + " def _deserialize(self, data):\n" + " ''' Initialize values from data returned by struct.unpack()'''\n" + " self.discriminator = %s\n" + " ffmt = self._get_case_fmt()\n" + " ubuffer = bytes([data.pop(0) for _ in range (struct.calcsize(ffmt))])\n" + " udata = list(struct.unpack(ffmt, ubuffer))\n" + " self._label_switch('unpack_data', udata, self)\n" + " return self\n\n", + unionInfo->d_deserialize + ); + + os_free(nonDefaultLabelSelectors); + union_info_free(unionInfo, NULL); + unionInfo = NULL; +} + +/** @brief callback function called on definition of a union case in the IDL input file. + * + * Generate code for the following IDL construct: + * @verbatim + union switch() { + case label1.1; .. case label1.n; + => ; + case label2.1; .. case label2.n; + => ... ... + case labeln.1; .. case labeln.n; + => ; + default: + => ; + }; + @endverbatim + * + * @param scope Current scope (the union the union case is defined in) + * @param name Name of the union case + * @param typeSpec Specifies the type of the union case + */ +static void +idl_unionCaseOpenClose( + idl_scope scope, + const char *name, + idl_typeSpec typeSpec, + void *userData) +{ + char *field_ref = os_malloc(strlen("o.") + strlen(name) + 1); + + OS_UNUSED_ARG(userData); + + os_sprintf(field_ref, "o.%s", name); + + unionCase->ddstype = idl_genPythonDDSType(scope, name, typeSpec); + unionCase->pytype = idl_genPythonPyType(scope, name, typeSpec); + unionCase->pydefault = idl_genPythonPyDefault(scope, name, typeSpec); + unionCase->name = os_strdup(name); + unionCase->pack_string = idl_genPythonPyPackString(scope, name, typeSpec); + unionCase->deserialize = idl_genPythonPyDeserialize(scope, name, typeSpec, "data"); + unionCase->serialize = idl_genPythonPyPackField(scope, name, typeSpec, "args", field_ref); + unionCase->checker = idl_genPythonPyFieldChecker(scope, name, typeSpec); + + os_free(field_ref); + + unionCase = NULL; +} + +static c_char * +idl_valueFromLabelVal ( + idl_labelVal labelVal) +{ + static c_char labelName [1000]; + + /* QAC EXPECT 3416; No side effect here */ + if (idl_labelValType(idl_labelVal(labelVal)) == idl_lenum) { + /* TODO: do something similar to idl_genPythonPyQName */ + snprintf (labelName, sizeof(labelName), "%s", idl_labelEnumImage(idl_labelEnum(labelVal))); + } else { + switch (idl_labelValueVal(idl_labelValue(labelVal)).kind) { + case V_CHAR: + snprintf (labelName, sizeof(labelName), "%u", idl_labelValueVal(idl_labelValue(labelVal)).is.Char); + break; + case V_SHORT: + snprintf (labelName, sizeof(labelName), "%d", idl_labelValueVal(idl_labelValue(labelVal)).is.Short); + break; + case V_USHORT: + snprintf (labelName, sizeof(labelName), "%u", idl_labelValueVal(idl_labelValue(labelVal)).is.UShort); + break; + case V_LONG: + snprintf (labelName, sizeof(labelName), "%d", idl_labelValueVal(idl_labelValue(labelVal)).is.Long); + break; + case V_ULONG: + snprintf (labelName, sizeof(labelName), "%u", idl_labelValueVal(idl_labelValue(labelVal)).is.ULong); + break; + case V_LONGLONG: + snprintf (labelName, sizeof(labelName), "%"PA_PRId64, idl_labelValueVal(idl_labelValue(labelVal)).is.LongLong); + break; + case V_ULONGLONG: + snprintf (labelName, sizeof(labelName), "%"PA_PRIu64, idl_labelValueVal(idl_labelValue(labelVal)).is.ULongLong); + break; + case V_BOOLEAN: + /* QAC EXPECT 3416; No side effect here */ + if (idl_labelValueVal(idl_labelValue(labelVal)).is.Boolean == TRUE) { + snprintf (labelName, sizeof(labelName), "True"); + } else { + snprintf (labelName, sizeof(labelName), "False"); + } + break; + default: + break; + } + } + return labelName; +} + +/** @brief return a Python expression representative of the given label value */ +static char * +idl_genPythonLabelValue( + union_info_t *ui, + idl_labelVal labelVal + ) +{ + idl_labelType labelType = idl_labelValType(labelVal); + switch(labelType) { + case idl_lenum: { + c_char *value = idl_valueFromLabelVal(labelVal); + char *result = os_malloc(strlen(ui->d_pytype) + 1 + strlen(value) + 1); + os_sprintf(result, "%s.%s", ui->d_pytype, value); + return result; + } + case idl_lvalue: { + if(strcmp(ui->d_ddstype,"char") == 0) { + c_char *value = idl_valueFromLabelVal(labelVal); + char *result = os_malloc(strlen("chr()") + strlen(value) + 1); + os_sprintf(result, "chr(%s)", value); + return result; + } else { + return os_strdup(idl_valueFromLabelVal(labelVal)); + } + } + case idl_ldefault: + default: + return idl_genPythonLabelValue(ui, idl_labelDefaultAlternative(idl_labelDefault(labelVal))); + } +} + +/** @brief callback function called on definition of the union case labels in the IDL input file. + * + * Generate code for the following IDL construct: + * @verbatim + union switch() { + => case label1.1; .. case label1.n; + ; + => case label2.1; .. case label2.n; + ... ... + => case labeln.1; .. case labeln.n; + ; + default: + ; + }; + @endverbatim + * + * @param scope Current scope (the union the labels are defined in) + * @param labelSpec Specifies the number of labels of the union case + */ +static void +idl_unionLabelOpenClose( + idl_scope ownScope, + idl_labelVal labelVal, + void *userData) +{ + idl_labelType labelType = idl_labelValType(labelVal); + union_case_label_t *case_label; + + OS_UNUSED_ARG(ownScope); + OS_UNUSED_ARG(userData); + + if(labelType == idl_ldefault) { + case_label = os_malloc(sizeof(union_case_label_t)); + unionCase->default_label = case_label; + } else { + case_label = &unionCase->labels[unionCaseLabelNext++]; + } + case_label->value = idl_genPythonLabelValue(unionInfo, labelVal); + case_label->is_default = labelType == idl_ldefault; +} + +/** @brief callback function called on definition of the union case labels in the IDL input file. + * + * Generate code for the following IDL construct: + * @verbatim + union switch() { + => case label1.1; .. case label1.n; + ; + => case label2.1; .. case label2.n; + ... ... + => case labeln.1; .. case labeln.n; + ; + default: + ; + }; + @endverbatim + * + * @param scope Current scope (the union the labels are defined in) + * @param labelSpec Specifies the number of labels of the union case + */ +static void +idl_unionLabelsOpenClose( + idl_scope scope, + idl_labelSpec labelSpec, + void *userData) +{ + OS_UNUSED_ARG(scope); + OS_UNUSED_ARG(userData); + + unionCase = &unionInfo->cases[unionCaseNext++]; + unionCaseLabelNext = 0; + memset(unionCase, 0, sizeof(union_case_t)); + unionCase->nlabels = idl_labelSpecNoLabels(labelSpec); + unionCase->labels = os_malloc(unionCase->nlabels * sizeof(union_case_label_t)); + memset(unionCase->labels, 0, unionCase->nlabels * sizeof(union_case_label_t)); +} + +/** @brief callback function called when no default case is defined in an union + * for which not all possible label values are specified + * + * Generate code for the following IDL construct: + * @verbatim + union switch() { + case label1.1; .. case label1.n; + ; + case label2.1; .. case label2.n; + ... ... + case labeln.1; .. case labeln.n; + ; + }; + @endverbatim + * + * @param scope Current scope (the union the union case is defined in) + * @param labelVal Default value for the label case (lowest possible not used index) + * @param typeSpec Specifies the type of the union switch + */ +static void +idl_artificialDefaultLabelOpenClose( + idl_scope scope, + idl_labelVal labelVal, + idl_typeSpec typeSpec, + void *userData) +{ + union_case_t *union_case = NULL; + + OS_UNUSED_ARG(scope); + OS_UNUSED_ARG(typeSpec); + OS_UNUSED_ARG(userData); + + union_case = unionInfo->artificial_case = os_malloc(sizeof(union_case_t)); + + union_case->ddstype = os_strdup("__NONE__"); + union_case->pytype = os_strdup("__NONE__"); + union_case->pydefault = os_strdup("None"); + union_case->name = os_strdup("__NONE__"); + union_case->pack_string = os_strdup(""); + union_case->deserialize = os_strdup("None"); + union_case->serialize = os_strdup("None"); + union_case->checker = os_strdup("None"); + union_case->nlabels = 0; + union_case->labels = NULL; + + union_case->default_label = os_malloc(sizeof(union_case_label_t)); + union_case->default_label->value = idl_genPythonLabelValue(unionInfo, labelVal); + union_case->default_label->is_default = TRUE; +} + +/** @brief callback function called on definition of a named type in the IDL input file. + * + * Generate code for the following IDL construct: + * @verbatim + => typedef ; + @endverbatim + * + * @param scope Current scope + * @param name Specifies the name of the type + * @param defSpec Specifies the type of the named type + */ +static void +idl_typedefOpenClose( + idl_scope scope, + const char *name, + idl_typeDef defSpec, + void *userData) +{ + OS_UNUSED_ARG(scope); + OS_UNUSED_ARG(name); + OS_UNUSED_ARG(defSpec); + OS_UNUSED_ARG(userData); + +} + +static void +idl_sequenceOpenClose ( + idl_scope scope, + idl_typeSeq typeSeq, + void *userData) +{ + OS_UNUSED_ARG(scope); + OS_UNUSED_ARG(typeSeq); + OS_UNUSED_ARG(userData); +} + +/* constantOpenClose callback + + Generate dependencies for the following IDL construct: + => const ; + For determine if it is specified in the same file as + this const definition self. If it is defined in another file, add + a dependency to the dependency list. +*/ +static void +idl_constantOpenClose( + idl_scope scope, + idl_constSpec constantSpec, + void *userData) +{ + idl_typeSpec typeSpec = idl_constSpecTypeGet(constantSpec); + idl_type type = idl_typeSpecType(typeSpec); + + OS_UNUSED_ARG(scope); + OS_UNUSED_ARG(userData); + + if(type == idl_tbasic) { + char *image = idl_constSpecImage(constantSpec); + idl_basicType basicType = idl_typeBasicType(idl_typeBasic(typeSpec)); + if(basicType == idl_char) { + char *new_image; + new_image = os_malloc(strlen(image) + strlen("chr()") + 1); + os_sprintf(new_image, "chr(%s)", image); + os_free((void*)image); + image = new_image; + } + idl_streamOutPrintf(moduleContents, + "%s = %s\n\n", + idl_constSpecName(constantSpec), + image + ); + os_free((void*)image); + } else if(type == idl_tenum) { + char *image = idl_constSpecImage(constantSpec); + char *enumQname = idl_genPythonPyQName(typeSpec); + + idl_streamOutPrintf(moduleContents, + "%s = %s.%s\n\n", + idl_constSpecName(constantSpec), + enumQname, + image + ); + os_free((void*)image); + os_free((void*)enumQname); + } else { + printf("should not get here. idl_type == %d\n", type); + exit(1); + } +} + +/** + * Specifies the callback table for the splice type generation functions. + */ +static struct idl_program +idl_genPythonType = { + idl_getControl, + idl_fileOpen, + idl_fileClose, + idl_moduleOpen, + idl_moduleClose, + idl_structureOpen, + idl_structureClose, + idl_structureMemberOpenClose, + idl_enumerationOpen, + idl_enumerationClose, + idl_enumerationElementOpenClose, + idl_unionOpen, + idl_unionClose, + idl_unionCaseOpenClose, + idl_unionLabelsOpenClose, + idl_unionLabelOpenClose, + idl_typedefOpenClose, + NULL, /* idl_boundedStringOpenClose */ + idl_sequenceOpenClose, + idl_constantOpenClose, + idl_artificialDefaultLabelOpenClose, + NULL /* userData */ +}; + +/** @brief return the callback table for the splice type generation functions. + */ +idl_program +idl_genPythonProgram ( + void) +{ + return &idl_genPythonType; +} + diff --git a/src/tools/idlpp/code/idl_genPython.h b/src/tools/idlpp/code/idl_genPython.h new file mode 100644 index 000000000..5016c95a3 --- /dev/null +++ b/src/tools/idlpp/code/idl_genPython.h @@ -0,0 +1,32 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#ifndef IDL_GENPYTHON_H +#define IDL_GENPYTHON_H + +#include "idl_program.h" + +typedef struct idl_pythonUserData { + char *baseModuleName; +} idl_pythonUserData; + +idl_program idl_genPythonProgram (void); + +#endif /* IDL_GENPYTHON_H */ diff --git a/src/tools/idlpp/code/idl_genPythonDescriptors.c b/src/tools/idlpp/code/idl_genPythonDescriptors.c new file mode 100644 index 000000000..7df1b8d33 --- /dev/null +++ b/src/tools/idlpp/code/idl_genPythonDescriptors.c @@ -0,0 +1,395 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "idl_genPythonDescriptors.h" + +#include "idl_genMetaHelper.h" +#include "idl_keyDef.h" + +#include + +/** + * Standard control structure to specify that inline + * type definitions are to be processed prior to the + * type itself in contrast with inline. +*/ +static idl_programControl idl_genPythonDescriptorsLoadControl = { + idl_prior +}; + +/** @brief return the program control structure for the splice type generation functions. + */ +static idl_programControl * +idl_getControl( + void *userData) +{ + OS_UNUSED_ARG(userData); + return &idl_genPythonDescriptorsLoadControl; +} + +/* @brief callback function called on opening the IDL input file. + * + * Generate standard file header consisting of: + * - mutiple inclusion prevention + * - inclusion of Splice type definition files + * - inclusion of application specific include files related to other IDL files + * + * @param scope Current scope (not used) + * @param name Name of the IDL input file + */ +static idl_action +idl_fileOpen( + idl_scope scope, + const char *name, + void *userData) +{ + OS_UNUSED_ARG(scope); + OS_UNUSED_ARG(name); + OS_UNUSED_ARG(userData); + + printf("\n"); + + /* return idl_explore to indicate that the rest of the file needs to be processed */ + return idl_explore; +} + +static void +idl_fileClose( + void *userData) +{ + OS_UNUSED_ARG(userData); + + printf("\n"); +} + +/** @brief callback function called on module definition in the IDL input file. + * + * Generate code for the following IDL construct: + * @verbatim + => module { + + }; + @endverbatim + * + * This fuction generates the prototype of the function that + * is responsible for loading the metadata into the database. + * The name of the function is: + * @verbatim + ______load + @endverbatim + * For the Splice types, no further actions are required. + * + * @param scope Current scope (and scope of the module definition) + * @param name Name of the defined module + */ +static idl_action +idl_moduleOpen( + idl_scope scope, + const char *name, + void *userData) +{ + OS_UNUSED_ARG(scope); + OS_UNUSED_ARG(name); + OS_UNUSED_ARG(userData); + + /* return idl_explore to indicate that the rest of the module needs to be processed */ + return idl_explore; +} + +/* Matlab class template: + classdef struct_name < Vortex.AbstractType + properties + FIELD1 FIELD1Type = initDimensions + FIELD2 (1) + end + + methods (Static) + function keys = getKey + keys = 'STRUCT_KEY_STRING'; + end + end + end +*/ + +/** @brief callback function called on structure definition in the IDL input file. + * + * Generate code for the following IDL construct: + * @verbatim + => struct { + ; + ... ... + ; + }; + @endverbatim + * + * @param scope Current scope (and scope of the structure definition) + * @param name Name of the structure + * @param structSpec Specification of the struct holding the amount of members + */ +static idl_action +idl_structureOpen( + idl_scope scope, + const char *name, + idl_typeStruct structSpec, + void *userData) +{ + c_char *id; + const c_char *keys; + c_char *descriptor; + + OS_UNUSED_ARG(userData); + + keys = idl_keyResolve(idl_keyDefDefGet(), scope, name); + if (keys != NULL) { + c_type type = idl_typeSpecDef(idl_typeSpec(structSpec)); + descriptor = idl_genXMLmeta(type, FALSE); + id = idl_scopeStack (scope, "::", name); + + printf( " \n" + " %s\n" + " %s\n" + " \n" + " \n", + id, keys, descriptor); + + os_free(id); + os_free(descriptor); + } + + /* return idl_explore to indicate that the rest of the structure needs to be processed */ + return idl_explore; +} + +/** @brief callback function called on end of a structure definition in the IDL input file. + * + * Generate code for the following IDL construct: + * @verbatim + struct { + + ... ... + + => }; + @endverbatim + * + * The structure is closed: + * @verbatim + }; + @endverbatim + * + * @param name Name of the structure (not used) + */ +/*static void +idl_structureClose( + const char *name, + void *userData) +{ + OS_UNUSED_ARG(name); + OS_UNUSED_ARG(userData); +}*/ + +/** @brief callback function called on definition of a structure member in the IDL input file. + * + * Generate code for the following IDL construct: + * @verbatim + struct { + => ; + => ... ... + => ; + }; + @endverbatim + * + * @param scope Current scope + * @param name Name of the structure member + * @param typeSpec Type specification of the structure member + */ +/*static void +idl_structureMemberOpenClose( + idl_scope scope, + const char *name, + idl_typeSpec typeSpec, + void *userData) +{ + OS_UNUSED_ARG(scope); + OS_UNUSED_ARG(name); + OS_UNUSED_ARG(typeSpec); + OS_UNUSED_ARG(userData); +}*/ + +/** @brief callback function called on definition of an enumeration. + * + * Generate code for the following IDL construct: + * @verbatim + => enum { + ; + ... ... + ; + }; + @endverbatim + * + * @param scope Current scope + * @param name Name of the enumeration + * @param enumSpec Specifies the number of elements in the enumeration + */ +/*static idl_action +idl_enumerationOpen( + idl_scope scope, + const char *name, + idl_typeEnum enumSpec, + void *userData) +{ + OS_UNUSED_ARG(scope); + OS_UNUSED_ARG(name); + OS_UNUSED_ARG(enumSpec); + OS_UNUSED_ARG(userData); + + return idl_explore; +}*/ + +/** @brief callback function called on closure of an enumeration in the IDL input file. + * + * Generate code for the following IDL construct: + * @verbatim + enum { + ; + ... ... + ; + => }; + @endverbatim + * + * @param name Name of the enumeration + */ +/*static void +idl_enumerationClose( + const char *name, + void *userData) +{ + OS_UNUSED_ARG(name); + OS_UNUSED_ARG(userData); +}*/ + +/** @brief callback function called on definition of an enumeration element in the IDL input file. + * + * Generate code for the following IDL construct: + * @verbatim + enum { + => , + => ... ... + => + }; + @endverbatim + * + * For the last element generate: + * @verbatim + + @endverbatim + * For any but the last element generate: + * @verbatim + , + @endverbatim + * + * @param scope Current scope + * @param name Name of the enumeration element + */ +/*static void +idl_enumerationElementOpenClose ( + idl_scope scope, + const char *name, + void *userData) +{ + OS_UNUSED_ARG(scope); + OS_UNUSED_ARG(name); + OS_UNUSED_ARG(userData); +}*/ + +/** @brief callback function called on definition of a named type in the IDL input file. + * + * Generate code for the following IDL construct: + * @verbatim + => typedef ; + @endverbatim + * + * @param scope Current scope + * @param name Specifies the name of the type + * @param defSpec Specifies the type of the named type + */ +/*static void +idl_typedefOpenClose( + idl_scope scope, + const char *name, + idl_typeDef defSpec, + void *userData) +{ + OS_UNUSED_ARG(scope); + OS_UNUSED_ARG(name); + OS_UNUSED_ARG(defSpec); + OS_UNUSED_ARG(userData); +}*/ + +/*static void +idl_sequenceOpenClose ( + idl_scope scope, + idl_typeSeq typeSeq, + void *userData) +{ + OS_UNUSED_ARG(scope); + OS_UNUSED_ARG(typeSeq); + OS_UNUSED_ARG(userData); +}*/ + + +/** + * Specifies the callback table for the splice type generation functions. + */ +static struct idl_program +idl_genPythonDescriptorsType = { + idl_getControl, + idl_fileOpen, + idl_fileClose, + idl_moduleOpen, + NULL, /* idl_moduleClose */ + idl_structureOpen, + NULL, /* idl_structureClose */ + NULL, /* idl_structureMemberOpenClose */ + NULL, /* idl_enumerationOpen */ + NULL, /* idl_enumerationClose */ + NULL, /* idl_enumerationElementOpenClose */ + NULL, /*idl_unionOpen */ + NULL, /* idl_unionClose */ + NULL, /* idl_unionCaseOpenClose */ + NULL, /* idl_unionLabelsOpenClose */ + NULL, /* idl_unionLabelOpenClose */ + NULL, /* idl_typedefOpenClose */ + NULL, /* idl_boundedStringOpenClose */ + NULL, /* idl_sequenceOpenClose */ + NULL, /* idl_constantOpenClose */ + NULL, /* idl_artificialDefaultLabelOpenClose */ + NULL /* userData */ +}; + +/** @brief return the callback table for the splice type generation functions. + */ +idl_program +idl_genPythonDescriptorsProgram ( + void) +{ + return &idl_genPythonDescriptorsType; +} + diff --git a/src/tools/idlpp/code/idl_genPythonDescriptors.h b/src/tools/idlpp/code/idl_genPythonDescriptors.h new file mode 100644 index 000000000..e36401588 --- /dev/null +++ b/src/tools/idlpp/code/idl_genPythonDescriptors.h @@ -0,0 +1,28 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#ifndef IDL_GENPYTHONDESCRIPTORS_H +#define IDL_GENPYTHONDESCRIPTORS_H + +#include "idl_program.h" + +idl_program idl_genPythonDescriptorsProgram (void); + +#endif /* IDL_GENPYTHONDESCRIPTORS_H */ diff --git a/src/tools/idlpp/code/idl_genPythonHelper.c b/src/tools/idlpp/code/idl_genPythonHelper.c new file mode 100644 index 000000000..f26e5c578 --- /dev/null +++ b/src/tools/idlpp/code/idl_genPythonHelper.c @@ -0,0 +1,183 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#include "idl_genPythonHelper.h" +#include "idl_genJavaHelper.h" +#include "os_stdlib.h" +#include "os_heap.h" + +#include "idl_scope.h" +/* + * Python keywords. This declaration is generated by the following Python script: + +def python_keywords(): + import keyword + print('static const char *python_keywords[%d] = {' % (len(keyword.kwlist))) + for kw in keyword.kwlist: + print(' "{}",'.format(kw)) + print('};') + +python_keywords() + + */ +static const char *python_keywords[33] = { + "False", + "None", + "True", + "and", + "as", + "assert", + "break", + "class", + "continue", + "def", + "del", + "elif", + "else", + "except", + "finally", + "for", + "from", + "global", + "if", + "import", + "in", + "is", + "lambda", + "nonlocal", + "not", + "or", + "pass", + "raise", + "return", + "try", + "while", + "with", + "yield", +}; + +c_char * +idl_pythonId( + const char *identifier) +{ + size_t i; + + for(i = 0; i < sizeof(python_keywords)/sizeof(char*); i ++) { + if(strcmp(identifier,python_keywords[i]) == 0) { + char *result = os_malloc(strlen(identifier) + 2); + os_sprintf("%s_", identifier); + return result; + } + } + + return os_strdup(identifier); +} + +static c_char * +idl_scopePythonElementName ( + idl_scopeElement scope) +{ + return idl_scopeElementName(scope); +} + + +c_char *idl_scopeStackPython( + idl_scope scope, + const char *scopeSepp, + const char *name) +{ + c_long si; + c_long sz; + c_char *scopeStack = NULL; + c_char *Id; + c_char *basename; + + assert (scopeSepp != NULL); + basename = idl_scopeBasename(scope); + scopeStack = idl_pythonId(basename); + os_free(basename); + + for (si = 0, sz = idl_scopeStackSize(scope); si < sz; si++) { + size_t slen; + + /* Translate the scope name to a Python identifier */ + Id = idl_pythonId(idl_scopePythonElementName(idl_scopeIndexed(scope, si))); + /* allocate space for the current scope stack + the separator + *and the next scope name + */ + /* QAC EXPECT 5007; will not use wrapper */ + slen = strlen (scopeStack) + strlen (scopeSepp) + strlen (Id); + scopeStack = os_realloc(scopeStack, slen + 1); + /* Concatenate the separator */ + /* QAC EXPECT 5007; will not use wrapper */ + if (strlen(scopeStack)) { + os_strcat(scopeStack, scopeSepp); + } + /* Concatenate the scope name */ + /* QAC EXPECT 5007; will not use wrapper */ + os_strcat (scopeStack, Id); + os_free((void*)Id); + } + + if (name) { + /* A user identifier is specified */ + /* Translate the user identifier to a Java identifier */ + Id = idl_pythonId(name); + /* allocate space for the current scope stack + the separator + * and the user identifier + */ + /* QAC EXPECT 5007; will not use wrapper */ + scopeStack = os_realloc(scopeStack, strlen(scopeStack)+strlen(scopeSepp)+strlen(Id)+1); + /* Concatenate the separator */ + /* QAC EXPECT 5007; will not use wrapper */ + if (strlen(scopeStack)) { + os_strcat(scopeStack, scopeSepp); + } + /* Concatenate the user identifier */ + /* QAC EXPECT 5007; will not use wrapper */ + os_strcat (scopeStack, Id); + os_free((void*)Id); + } + + /* return the scope stack representation */ + return scopeStack; + +} + +c_char * +idl_genPythonLiteralValueImage( + c_value literal, + c_type type) +{ + c_char * valueImg = NULL; + + if (literal.kind != V_BOOLEAN) { + valueImg = idl_genJavaLiteralValueImage(literal, type); + } else { + valueImg = os_malloc(10); + if (literal.is.Boolean) { + snprintf(valueImg, 10, "True"); + } else { + snprintf (valueImg, 10, "False"); + } + } + return valueImg; +} + diff --git a/src/tools/idlpp/code/idl_genPythonHelper.h b/src/tools/idlpp/code/idl_genPythonHelper.h new file mode 100644 index 000000000..b12c896ef --- /dev/null +++ b/src/tools/idlpp/code/idl_genPythonHelper.h @@ -0,0 +1,31 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#ifndef IDL_GENPYTHONHELPER_H +#define IDL_GENPYTHONHELPER_H + +#include "c_typebase.h" +#include "idl_scope.h" + +c_char *idl_pythonId(const char *identifier); +c_char *idl_scopeStackPython(idl_scope scope, const char *scopeSepp, const char *name); +c_char *idl_genPythonLiteralValueImage(c_value literal, c_type type); + +#endif /* IDL_GENPYTHONHELPER_H */ diff --git a/src/tools/idlpp/code/idl_genSACPPType.c b/src/tools/idlpp/code/idl_genSACPPType.c index a7e46e3ed..8f93e9da1 100644 --- a/src/tools/idlpp/code/idl_genSACPPType.c +++ b/src/tools/idlpp/code/idl_genSACPPType.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -72,7 +73,7 @@ struct idl_genSACPPStructSpec { c_bool hasRef; }; -/* @brief generate dimension of an array slice +/** @brief generate dimension of an array slice * * arraySliceDimensions is a local support function to generate * the array dimensions of an array slice @@ -90,7 +91,7 @@ idl_arraySliceDimensions( idl_fileOutPrintf(idl_fileCur(), "[%d]", idl_typeArraySize(typeArray)); } -/* @brief generate dimension of an array +/** @brief generate dimension of an array * * arrayDimensions is a local support function to generate * the array dimensions of an array @@ -262,7 +263,7 @@ idl_macroFromBasename( return macro; } -/* @brief callback function called on opening the IDL input file. +/** @brief callback function called on opening the IDL input file. * * Generate standard file header consisting of: * - mutiple inclusion prevention @@ -294,7 +295,7 @@ idl_fileOpen( idl_fileOutPrintf(idl_fileCur(), "#ifndef %s\n", idl_macroFromBasename(name, "DCPS_H")); idl_fileOutPrintf(idl_fileCur(), "#define %s\n", idl_macroFromBasename(name, "DCPS_H")); idl_fileOutPrintf(idl_fileCur(), "\n"); - /* Generate inclusion of standard OpenSplice DDS type definition files */ + /* Generate inclusion of standard Vortex OpenSplice type definition files */ idl_fileOutPrintf(idl_fileCur(), "#include \n"); idl_fileOutPrintf(idl_fileCur(), "\n"); #ifndef RP @@ -313,7 +314,7 @@ idl_fileOpen( return idl_explore; } -/* @brief callback function called on closing the IDL input file. +/** @brief callback function called on closing the IDL input file. * * Generate standard file footer consisting of: * - mutiple inclusion prevention closure @@ -832,8 +833,6 @@ idl_enumerationClose ( OS_UNUSED_ARG(name); -/* idl_printIndent(arg->indent_level); - idl_fileOutPrintf(idl_fileCur(), "EORB_FORCE_ENUM32(__%s)\n", name);*/ arg->indent_level--; idl_printIndent(arg->indent_level); idl_fileOutPrintf(idl_fileCur(), "};\n"); @@ -1026,7 +1025,7 @@ idl_constantOpenClose ( * Standard control structure to specify that inline * type definitions are to be processed prior to the * type itself in contrast with inline. -*/ + */ static idl_programControl idl_genSACPPLoadControl = { idl_prior }; @@ -1079,8 +1078,7 @@ idl_genSacppTypeProgram( return &idl_genSacppType; } -/* - * Implementation Considerations: +/* Implementation Considerations: * * - Mapping structures: * The members of a structure have a type, which can be arrays, sequences, strings @@ -1089,5 +1087,4 @@ idl_genSacppTypeProgram( * all compilers can handle this. Therefore we will generate these type-defs at the module * level of the structure. The structure definition it self will be built on heap and written * to the output file in the idl_structureClose() callback. - * */ diff --git a/src/tools/idlpp/code/idl_genSACPPType.h b/src/tools/idlpp/code/idl_genSACPPType.h index 4021003f5..e98c79770 100644 --- a/src/tools/idlpp/code/idl_genSACPPType.h +++ b/src/tools/idlpp/code/idl_genSACPPType.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/idlpp/code/idl_genSACPPTypeImpl.c b/src/tools/idlpp/code/idl_genSACPPTypeImpl.c index 19d9f25d8..47e870d03 100644 --- a/src/tools/idlpp/code/idl_genSACPPTypeImpl.c +++ b/src/tools/idlpp/code/idl_genSACPPTypeImpl.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -253,7 +254,7 @@ idl_arrayTypeImpl( idl_fileOutPrintf(idl_fileCur(),"}\n\n"); } -/* @brief callback function called on opening the IDL input file. +/** @brief callback function called on opening the IDL input file. * * Generate standard file header consisting of: * - mutiple inclusion prevention @@ -285,7 +286,7 @@ idl_fileOpen( return idl_explore; } -/* @brief callback function called on closing the IDL input file. +/** @brief callback function called on closing the IDL input file. * * Generate standard file footer consisting of: * - mutiple inclusion prevention closure @@ -716,8 +717,7 @@ idl_genSacppTypeImplProgram( return &idl_genSacppTypeImpl; } -/* - * Implementation Considerations: +/* Implementation Considerations: * * - Mapping structures: * The members of a structure have a type, which can be arrays, sequences, strings @@ -726,5 +726,4 @@ idl_genSacppTypeImplProgram( * all compilers can handle this. Therefore we will generate these type-defs at the module * level of the structure. The structure definition it self will be built on heap and written * to the output file in the idl_structureClose() callback. - * */ diff --git a/src/tools/idlpp/code/idl_genSACPPTypeImpl.h b/src/tools/idlpp/code/idl_genSACPPTypeImpl.h index c7d3db7b8..7f7e3215f 100644 --- a/src/tools/idlpp/code/idl_genSACPPTypeImpl.h +++ b/src/tools/idlpp/code/idl_genSACPPTypeImpl.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/idlpp/code/idl_genSACPPTypedClassDefs.c b/src/tools/idlpp/code/idl_genSACPPTypedClassDefs.c index 241924cac..13643019f 100644 --- a/src/tools/idlpp/code/idl_genSACPPTypedClassDefs.c +++ b/src/tools/idlpp/code/idl_genSACPPTypedClassDefs.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -52,7 +53,7 @@ idl_fileOpen( c_char *tmplPath; c_char *orbPath; int tmplFile; - struct os_stat tmplStat; + struct os_stat_s tmplStat; unsigned int nRead; OS_UNUSED_ARG(scope); OS_UNUSED_ARG(userData); diff --git a/src/tools/idlpp/code/idl_genSACPPTypedClassDefs.h b/src/tools/idlpp/code/idl_genSACPPTypedClassDefs.h index 000bd3f73..1b0ae3e45 100644 --- a/src/tools/idlpp/code/idl_genSACPPTypedClassDefs.h +++ b/src/tools/idlpp/code/idl_genSACPPTypedClassDefs.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/idlpp/code/idl_genSACPPTypedClassImpl.c b/src/tools/idlpp/code/idl_genSACPPTypedClassImpl.c index a52f793fd..0a28342dd 100644 --- a/src/tools/idlpp/code/idl_genSACPPTypedClassImpl.c +++ b/src/tools/idlpp/code/idl_genSACPPTypedClassImpl.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -51,7 +52,7 @@ idl_fileOpen( c_char *tmplPath; c_char *orbPath; int tmplFile; - struct os_stat tmplStat; + struct os_stat_s tmplStat; unsigned int nRead; OS_UNUSED_ARG(scope); OS_UNUSED_ARG(userData); diff --git a/src/tools/idlpp/code/idl_genSACPPTypedClassImpl.h b/src/tools/idlpp/code/idl_genSACPPTypedClassImpl.h index dac041a46..a07380028 100644 --- a/src/tools/idlpp/code/idl_genSACPPTypedClassImpl.h +++ b/src/tools/idlpp/code/idl_genSACPPTypedClassImpl.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/idlpp/code/idl_genSACSHelper.c b/src/tools/idlpp/code/idl_genSACSHelper.c index 5ccf34381..8812c3816 100644 --- a/src/tools/idlpp/code/idl_genSACSHelper.c +++ b/src/tools/idlpp/code/idl_genSACSHelper.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,6 +20,7 @@ */ #include "idl_genSACSHelper.h" #include "idl_genLanguageHelper.h" +#include "idl_genSACSType.h" #include "idl_scope.h" #include "idl_tmplExp.h" #include "idl_typeSpecifier.h" @@ -26,14 +28,19 @@ #include "idl_genMetaHelper.h" #include + +#include "os_abstract.h" #include "os_iterator.h" #include "os_heap.h" #include "os_stdlib.h" + +#include "c_base.h" + #include /* Allocate a metaData structure used for generation of typeDescriptors outside - the scope of the idl_walk. + * the scope of the idl_walk. */ idl_metaCsharp * idl_metaCsharpNew(c_type type, c_char *descriptor) @@ -45,8 +52,8 @@ idl_metaCsharpNew(c_type type, c_char *descriptor) } /* Add a copy of the specified metadata for datatypes that serve as topics - (i.e. have a keylist). This list if metadata will be used for later processing, - when the type's lock is available again. + * (i.e. have a keylist). This list if metadata will be used for later processing, + * when the type's lock is available again. */ void idl_metaCharpAddType( @@ -75,8 +82,10 @@ idl_metaCsharpSerialize2XML( { c_ulong nrElements; size_t descrLength; + char * genXMLmeta = idl_genXMLmeta(metaElmnt->type, TRUE); - metaElmnt->descriptor = idl_cutXMLmeta(idl_genXMLmeta(metaElmnt->type), &nrElements, &descrLength); + metaElmnt->descriptor = idl_cutXMLmeta(genXMLmeta, &nrElements, &descrLength); + os_free(genXMLmeta); } } @@ -103,7 +112,6 @@ idl_CsharpRemovePrefix ( p = name + strlen(prefix); newLength = strlen(name) - strlen(prefix); - /* (for loop over new element length) */ for (i = 0, j = 0; i <= newLength; i++, j++) { if (j == 0 && p[i] == '_') { /* On first underscore, skip. */ @@ -128,7 +136,8 @@ toPascalCase(c_char *name) } /* Now go to UpperCase when necessary. - * (for loop includes '\0' terminator.) */ + * (for loop includes '\0' terminator.) + */ for (i = 0, j = 0; i <= strlen(name); i++, j++) { /* Start out with capital. */ if (i == 0) { @@ -176,9 +185,9 @@ static const c_char *Csharp_keywords[] = { #define NR_CSHARP_KEYWORDS sizeof(Csharp_keywords)/sizeof(c_char *) /* Translate an IDL identifier into a C# language identifier. - The IDL specification often states that all identifiers that - match a native keyword must be prepended by "_". -*/ + * The IDL specification often states that all identifiers that + * match a native keyword must be prepended by "_". + */ c_char * idl_CsharpId( const c_char *identifier, @@ -299,11 +308,53 @@ idl_toCsharpScopingOperator(c_char *scopedName) c_char * idl_scopeStackFromCType(c_type dataType) { - c_char *scopedName = os_strdup(c_metaScopedName(c_metaObject(dataType))); + c_char *scopedName = c_metaScopedName(c_metaObject(dataType)); idl_toCsharpScopingOperator(scopedName); return scopedName; } +c_char * +idl_CsharpScopeStackFromCType( + c_type dataType, + c_bool customPSM, + c_bool isCType, + c_bool fullyScoped) +{ + c_metaObject curScope = c_metaObject(dataType); + c_char *fullyScopedName = NULL; + c_char *idlName = c_metaName(curScope); + + if (idlName) { + fullyScopedName = idl_CsharpId(idlName, customPSM, isCType); + } else { + fullyScopedName = os_strdup(""); + } + + while (c_metaName(curScope->definedIn) != NULL && + (fullyScoped || c_baseObjectKind(curScope->definedIn) != M_MODULE)) { + size_t newLen; + c_char *scopeName; + const c_char *template; + c_char *temp = fullyScopedName; + + curScope = curScope->definedIn; + if (isCType && (c_baseObjectKind(curScope) == M_STRUCTURE || c_baseObjectKind(curScope) == M_UNION)) { + scopeName = idl_CsharpId(c_metaName(curScope), customPSM, TRUE); + template = "%s%s"; + } else { + scopeName = idl_CsharpId(c_metaName(curScope), customPSM, FALSE); + template = "%s.%s"; + } + newLen = strlen(scopeName) + strlen(template) + strlen(temp) + 1; + fullyScopedName = os_malloc(newLen); + snprintf(fullyScopedName, newLen, template, scopeName, temp); + os_free(scopeName); + os_free(temp); + } + c_free(idlName); + return fullyScopedName; +} + /* Build a textual presentation of the provided scope stack taking the * C# keyword identifier translation into account. Further the function * equals "idl_scopeStack". @@ -434,12 +485,12 @@ idl_translateIfPredefined( } /* Return the C# specific type identifier for the - specified type specification. The substPredefs - parameter determines whether the function should - attempt to translate IDL types that already have - a predefined representation into this predefined - representation. -*/ + * specified type specification. The substPredefs + * parameter determines whether the function should + * attempt to translate IDL types that already have + * a predefined representation into this predefined + * representation. + */ c_char * idl_CsharpTypeFromTypeSpec ( idl_typeSpec typeSpec, @@ -517,7 +568,7 @@ idl_CsharpTypeFromTypeSpec ( os_free(tmp); } else { /* if a user type is specified, build it from its scope and its name. - The type should be one of idl_tenum, idl_tstruct, idl_tunion. + * The type should be one of idl_tenum, idl_tstruct, idl_tunion. */ typeName = idl_scopeStackCsharp( idl_typeUserScope(idl_typeUser(typeSpec)), @@ -539,6 +590,162 @@ idl_CsharpTypeFromTypeSpec ( /* QAC EXPECT 5101; The switch statement is simple, therefore the total complexity is low */ } +c_char * +idl_genCsharpLiteralValueImage( + c_value literal, + c_type type, + void *userData) +{ + SACSTypeUserData* csUserData = (SACSTypeUserData *) userData; + c_char * valueImg = NULL; + c_char *val2; + int i; + + if (c_baseObject(type)->kind != M_ENUMERATION) { + switch (literal.kind) { + case V_OCTET: + valueImg = os_malloc (40); + snprintf(valueImg, 40, "%d", literal.is.Octet); + break; + case V_FLOAT: + case V_DOUBLE: + val2 = os_malloc(45); + valueImg = os_malloc(45); + snprintf(val2, 45, "%40.17g", literal.is.Double); + i = 0; + while (val2[i] == ' ') { + i++; + } + os_strncpy(valueImg, &val2[i], 40); + os_free(val2); + if ((strchr(valueImg, '.') == NULL) && (strchr(valueImg, 'E') == NULL)) { + strcat(valueImg, ".0"); + } + break; + case V_STRING: + valueImg = os_malloc(strlen(literal.is.String)+3); + snprintf(valueImg, strlen(literal.is.String)+3, "\"%s\"", literal.is.String); + break; + case V_BOOLEAN: + valueImg = os_malloc(40); + if (literal.is.Boolean) { + snprintf(valueImg, 40, "true"); + } else { + snprintf (valueImg, 40, "false"); + } + break; + case V_LONGLONG: + valueImg = os_malloc(40); + switch (c_primitive(type)->kind) { + case P_SHORT: + /* Apply unsigned version, since sign will be applied later as additional minus operand. */ + snprintf(valueImg, 40, "%hu", (c_short)literal.is.LongLong); + break; + case P_USHORT: + snprintf(valueImg, 40, "%hu", (c_short)literal.is.LongLong); + break; + case P_LONG: + /* Apply unsigned version, since sign will be applied later as additional minus operand. */ + snprintf(valueImg, 40, "%u", (c_long)literal.is.LongLong); + break; + case P_ULONG: + snprintf(valueImg, 40, "%u", (c_long)literal.is.LongLong); + break; + case P_LONGLONG: + /* Apply unsigned version, since sign will be applied later as additional minus operand. */ + snprintf(valueImg, 40, "%"PA_PRIu64"L", (c_longlong)literal.is.LongLong); + break; + case P_ULONGLONG: + snprintf(valueImg, 40, "%"PA_PRIu64"UL", (c_longlong)literal.is.LongLong); + break; + case P_CHAR: + snprintf(valueImg, 40, "%d", (unsigned char)literal.is.LongLong); + break; + case P_OCTET: + snprintf(valueImg, 40, "%d", (unsigned char)literal.is.LongLong); + break; + case P_ADDRESS: + snprintf(valueImg, 40, PA_ADDRFMT, (PA_ADDRCAST)literal.is.LongLong); + break; + case P_UNDEFINED: + case P_BOOLEAN: + case P_WCHAR: + case P_FLOAT: + case P_DOUBLE: + case P_VOIDP: + case P_MUTEX: + case P_LOCK: + case P_COND: + case P_COUNT: + case P_PA_UINT32: + case P_PA_UINTPTR: + case P_PA_VOIDP: + /* Do nothing */ + break; + } + break; + case V_SHORT: + /* Apply unsigned version, since sign will be applied later as additional minus operand. */ + valueImg = os_malloc(40); + snprintf(valueImg, 40, "%hu", literal.is.Short); + break; + case V_LONG: + /* Apply unsigned version, since sign will be applied later as additional minus operand. */ + valueImg = os_malloc(40); + snprintf(valueImg, 40, "%u", (c_long)literal.is.Long); + break; + case V_USHORT: + valueImg = os_malloc(40); + snprintf(valueImg, 40, "%hu", (c_short)literal.is.UShort); + break; + case V_ULONG: + valueImg = os_malloc(40); + snprintf(valueImg, 40, "%u", (c_long)literal.is.ULong); + break; + case V_ULONGLONG: + valueImg = os_malloc(40); + snprintf(valueImg, 40, "%" PA_PRIu64, (c_longlong)literal.is.ULongLong); + break; + case V_ADDRESS: + valueImg = os_malloc(40); + snprintf(valueImg, 40, PA_ADDRFMT, (PA_ADDRCAST)literal.is.Address); + break; + case V_CHAR: + valueImg = os_malloc(40); + snprintf(valueImg, 40, "%u", (unsigned char)literal.is.Char); + break; + case V_UNDEFINED: + case V_WCHAR: + case V_WSTRING: + case V_FIXED: + case V_VOIDP: + case V_OBJECT: + case V_COUNT: + /* Invalid types for literal constants*/ + /* FALL THROUGH */ + default: + valueImg = NULL; + break; + } + } else { + const char *ENUM_TEMPLATE = "%s.%s"; + char *csEnumTp = idl_CsharpId( + c_metaObject(type)->name, + csUserData ? csUserData->customPSM : FALSE, + FALSE); + char *csEnumLabel = idl_CsharpId( + c_metaObject(c_enumeration(type)->elements[literal.is.Long])->name, + csUserData ? csUserData->customPSM : FALSE, + FALSE); + size_t valLen = strlen(csEnumTp) + strlen(csEnumLabel) + strlen(ENUM_TEMPLATE) + 1; + valueImg = os_malloc(valLen); + snprintf(valueImg, valLen, ENUM_TEMPLATE, csEnumTp, csEnumLabel); + os_free(csEnumTp); + os_free(csEnumLabel); + } + return valueImg; +} + c_char * idl_genCsharpConstantGetter(void) { @@ -657,3 +864,24 @@ idl_arrayCsharpIndexString ( return str; } + +c_char * +idl_labelCsharpEnumVal ( + const char *typeEnum, + idl_labelEnum labelVal, + c_bool customPSM) +{ + c_char *name; + c_char *scopedName; + + name = os_malloc(strlen(typeEnum) + strlen(idl_labelEnumImage(labelVal)) + 2); + os_strcpy(name, typeEnum); + os_strcat(name, "."); + os_strcat(name,idl_labelEnumImage(labelVal)); + + scopedName = idl_CsharpId(name, customPSM, FALSE); + + os_free(name); + + return scopedName; +} diff --git a/src/tools/idlpp/code/idl_genSACSHelper.h b/src/tools/idlpp/code/idl_genSACSHelper.h index 459256ae5..90b9c0703 100644 --- a/src/tools/idlpp/code/idl_genSACSHelper.h +++ b/src/tools/idlpp/code/idl_genSACSHelper.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,6 +23,7 @@ #define IDL_GENSACSHELPER_H_ #include "c_typebase.h" +#include "c_iterator.h" #include "idl_scope.h" #include "idl_program.h" @@ -36,6 +38,15 @@ typedef struct { c_char *descriptor; } idl_metaCsharp; +struct SACSTypeUserData_s { + os_iter idlpp_metaList; + c_char *tmplPrefix; + c_bool customPSM; + c_iter typeStack; +}; + +typedef struct SACSTypeUserData_s SACSTypeUserData; + idl_metaCsharp * idl_metaCsharpNew(c_type type, c_char *descriptor); @@ -67,6 +78,13 @@ idl_toCsharpScopingOperator(c_char *scopedName); c_char * idl_scopeStackFromCType(c_type dataType); +c_char * +idl_CsharpScopeStackFromCType( + c_type dataType, + c_bool customPSM, + c_bool isCType, + c_bool fullyScoped); + c_char *idl_scopeStackCsharp( idl_scope scope, const c_char *scopeSepp, @@ -76,6 +94,12 @@ c_char *idl_CsharpTypeFromTypeSpec( idl_typeSpec typeSpec, c_bool customPSM); +c_char * +idl_genCsharpLiteralValueImage( + c_value literal, + c_type type, + void *userData); + c_char *idl_genCsharpConstantGetter(void); c_char *idl_sequenceCsharpIndexString( @@ -87,6 +111,12 @@ c_char * idl_arrayCsharpIndexString ( idl_typeSpec typeSpec, SACS_INDEX_POLICY policy); +c_char * +idl_labelCsharpEnumVal ( + const char *typeEnum, + idl_labelEnum labelVal, + c_bool customPSM); + const c_char * idl_translateIfPredefined( const c_char *scopedName); @@ -95,4 +125,5 @@ c_bool idl_isPredefined( const c_char *scopedName); + #endif /* IDL_GENSACSHELPER_H_ */ diff --git a/src/tools/idlpp/code/idl_genSACSSplDcps.c b/src/tools/idlpp/code/idl_genSACSSplDcps.c index 8fd3199f5..86ac69039 100644 --- a/src/tools/idlpp/code/idl_genSACSSplDcps.c +++ b/src/tools/idlpp/code/idl_genSACSSplDcps.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -49,19 +50,42 @@ /** indentation level */ static c_long indent_level = 0; +/** static variables for union generation */ +struct SACSUnionMetaDescriptionSplDcps_s { + c_type gUnionType; + c_bool gUnionGenDefault; + idl_scope gUnionScope; + c_char *fullyScopedName; +}; +typedef struct SACSUnionMetaDescriptionSplDcps_s SACSUnionMetaDescriptionSplDcps; + static void idl_generateDatabaseRepresentation ( idl_typeStruct typeSpec, - const c_char *structName, - SACSSplDcpsUserData *csUserData); + const c_char *structDBName, + SACSTypeUserData *csUserData); + + +static void +idl_generateUnionDatabaseRepresentation ( + c_type unionType, + const c_char *unionDBName); static void idl_generateMarshaler ( idl_typeStruct typeSpec, + const c_char *structDBName, + const c_char *fullyScopedName, + SACSTypeUserData *csUserData); + +static void +idl_generateUnionMarshaler ( + c_type unionType, const c_char *structName, - SACSSplDcpsUserData *csUserData); + SACSTypeUserData *csUserData, + SACSUnionMetaDescriptionSplDcps *umd); -/* @brief callback function called on opening the IDL input file. +/** @brief callback function called on opening the IDL input file. * * Generate standard file header consisting of: * - inclusion of Splice type definition files @@ -79,7 +103,7 @@ idl_fileOpen( OS_UNUSED_ARG(name); OS_UNUSED_ARG(userData); - /* Generate inclusion of standard OpenSplice DDS type definition files */ + /* Generate inclusion of standard Vortex OpenSplice type definition files */ idl_fileOutPrintf(idl_fileCur(), "using DDS;\n"); idl_fileOutPrintf(idl_fileCur(), "using DDS.OpenSplice.CustomMarshalers;\n"); idl_fileOutPrintf(idl_fileCur(), "using DDS.OpenSplice.Database;\n"); @@ -110,7 +134,7 @@ idl_moduleOpen( const char *name, void *userData) { - SACSSplDcpsUserData *csUserData = (SACSSplDcpsUserData *) userData; + SACSTypeUserData *csUserData = (SACSTypeUserData *) userData; OS_UNUSED_ARG(scope); OS_UNUSED_ARG(scope); @@ -177,9 +201,10 @@ idl_structureOpen( { char *scopedStructName; idl_action action; - SACSSplDcpsUserData *csUserData = (SACSSplDcpsUserData *) userData; + SACSTypeUserData *csUserData = (SACSTypeUserData *) userData; OS_UNUSED_ARG(scope); + OS_UNUSED_ARG(name); scopedStructName = idl_scopeStackCsharp( idl_typeUserScope(idl_typeUser(structSpec)), @@ -190,27 +215,175 @@ idl_structureOpen( action = idl_abort; } else { /* Translate the name of the struct into a valid C# identifier. */ - c_char *structName = idl_CsharpId(name, csUserData->customPSM, FALSE); + c_type structType = idl_typeSpecDef(idl_typeSpec(structSpec)); + c_char *structDBName = idl_CsharpScopeStackFromCType(structType, csUserData->customPSM, TRUE, FALSE); /* Generate the Database representation of the datatype. */ - idl_generateDatabaseRepresentation(structSpec, structName, csUserData); + idl_generateDatabaseRepresentation(structSpec, structDBName, csUserData); /* Generate the Marshaler for the datatype. */ - idl_generateMarshaler(structSpec, structName, csUserData); + idl_generateMarshaler(structSpec, structDBName, scopedStructName, csUserData); /* return idl_explore to indicate that the rest of the structure needs to be processed. */ action = idl_explore; - os_free(structName); + os_free(structDBName); } os_free(scopedStructName); return action; } + +/** @brief callback function called on definition of a union in the IDL input file. + * + * Generate code for the following IDL construct: + * @verbatim + => union switch() { + case label1.1; .. case label1.n; + ; + case label2.1; .. case label2.n; + ... ... + case labeln.1; .. case labeln.n; + ; + default: + ; + }; + @endverbatim + * + * @param scope Current scope + * @param name Name of the union + * @param unionSpec Specifies the number of union cases and the union switch type + */ +static idl_action +idl_unionOpen( + idl_scope scope, + const char *name, + idl_typeUnion unionSpec, + void *userData) +{ + char *scopedUnionName; + idl_action action; + SACSTypeUserData* csUserData = (SACSTypeUserData *) userData; + SACSUnionMetaDescriptionSplDcps *umd = NULL; + + OS_UNUSED_ARG(name); + + scopedUnionName = idl_scopeStackCsharp( + idl_typeUserScope(idl_typeUser(unionSpec)), + ".", + idl_typeSpecName(idl_typeSpec(unionSpec))); + if (idl_isPredefined(scopedUnionName)) { + /* return idl_abort to indicate that the structure does not need to be processed. */ + os_free(scopedUnionName); + action = idl_abort; + } else { + umd = os_malloc(sizeof(SACSUnionMetaDescriptionSplDcps)); + memset(umd, 0, sizeof(SACSUnionMetaDescriptionSplDcps)); + umd->gUnionType = idl_typeSpecDef(idl_typeSpec(unionSpec)); + umd->gUnionScope = scope; + umd->fullyScopedName = scopedUnionName; + csUserData->typeStack = c_iterInsert(csUserData->typeStack, umd); + /* return idl_explore to indicate that the rest of the structure needs to be processed. */ + action = idl_explore; + } + return action; +} + +/** @brief callback function called on closure of a union in the IDL input file. + * + * Generate code for the following IDL construct: + * @verbatim + union switch() { + case label1.1; .. case label1.n; + ; + case label2.1; .. case label2.n; + ... ... + case labeln.1; .. case labeln.n; + ; + default: + ; + => }; + @endverbatim + * + * The union is closed: + * @verbatim + } _u; + }; + @endverbatim + * @param name Name of the union + */ +static void +idl_unionClose ( + const char *name, + void *userData) +{ + SACSTypeUserData *csUserData = (SACSTypeUserData *) userData; + SACSUnionMetaDescriptionSplDcps *umd; + c_char *unionDBName; + + OS_UNUSED_ARG(name); + + /* Translate the name of the struct into a valid C# identifier. */ + umd = (SACSUnionMetaDescriptionSplDcps *) c_iterTakeFirst(csUserData->typeStack); + assert(umd->gUnionType); + unionDBName = idl_CsharpScopeStackFromCType(umd->gUnionType, csUserData->customPSM, TRUE, FALSE); + + /* Generate the Database representation of the datatype. */ + idl_generateUnionDatabaseRepresentation(umd->gUnionType, unionDBName); + + /* Generate the Marshaler for the datatype. */ + idl_generateUnionMarshaler(umd->gUnionType, unionDBName, csUserData, umd); + + os_free(unionDBName); + umd->gUnionType = NULL; + umd->gUnionGenDefault = FALSE; + os_free(umd->fullyScopedName); + os_free(umd); +} + + +/** @brief callback function called when no default case is defined in an union + * for which not all possible label values are specified + * + * Generate code for the following IDL construct: + * @verbatim + union switch() { + case label1.1; .. case label1.n; + ; + case label2.1; .. case label2.n; + ... ... + case labeln.1; .. case labeln.n; + ; + }; + @endverbatim + * + * @param scope Current scope (the union the union case is defined in) + * @param labelVal Default value for the label case (lowest possible not used index) + * @param typeSpec Specifies the type of the union switch + */ +static void +idl_artificialDefaultLabelOpenClose( + idl_scope scope, + idl_labelVal labelVal, + idl_typeSpec typeSpec, + void *userData) +{ + SACSTypeUserData *csUserData = (SACSTypeUserData *) userData; + SACSUnionMetaDescriptionSplDcps *umd; + + OS_UNUSED_ARG(scope); + OS_UNUSED_ARG(labelVal); + OS_UNUSED_ARG(typeSpec); + + umd = (SACSUnionMetaDescriptionSplDcps *) c_iterObject(csUserData->typeStack, 0); + umd->gUnionGenDefault = TRUE; +} + + /** * Standard control structure to specify that inline * type definitions are to be processed prior to the * type itself in contrast with inline. -*/ + */ static idl_programControl idl_genSACSLoadControl = { idl_prior }; @@ -234,7 +407,7 @@ static struct idl_program idl_genSACSSplDcps; */ idl_program idl_genSACSSplDcpsProgram( - SACSSplDcpsUserData *userData) + void *userData) { idl_genSACSSplDcps.idl_getControl = idl_getControl; idl_genSACSSplDcps.fileOpen = idl_fileOpen; @@ -247,8 +420,8 @@ idl_genSACSSplDcpsProgram( idl_genSACSSplDcps.enumerationOpen = NULL; idl_genSACSSplDcps.enumerationClose = NULL; idl_genSACSSplDcps.enumerationElementOpenClose = NULL; - idl_genSACSSplDcps.unionOpen = NULL; - idl_genSACSSplDcps.unionClose = NULL; + idl_genSACSSplDcps.unionOpen = idl_unionOpen; + idl_genSACSSplDcps.unionClose = idl_unionClose; idl_genSACSSplDcps.unionCaseOpenClose = NULL; idl_genSACSSplDcps.unionLabelsOpenClose = NULL; idl_genSACSSplDcps.unionLabelOpenClose = NULL; @@ -256,7 +429,7 @@ idl_genSACSSplDcpsProgram( idl_genSACSSplDcps.boundedStringOpenClose = NULL; idl_genSACSSplDcps.sequenceOpenClose = NULL; idl_genSACSSplDcps.constantOpenClose = NULL; - idl_genSACSSplDcps.artificialDefaultLabelOpenClose = NULL; + idl_genSACSSplDcps.artificialDefaultLabelOpenClose = idl_artificialDefaultLabelOpenClose; idl_genSACSSplDcps.userData = userData; return &idl_genSACSSplDcps; @@ -265,10 +438,9 @@ idl_genSACSSplDcpsProgram( static c_char * idl_cTypeToCSharpDatabaseRepresentation( c_type memberType, - const c_char *memberTypeName, - SACSSplDcpsUserData *csUserData) + c_bool fullyScoped) { - c_char *dbType = NULL, *memberTypeNameTmp; + c_char *dbType = NULL; memberType = c_typeActualType(memberType); switch (c_baseObjectKind(memberType)) @@ -315,10 +487,14 @@ idl_cTypeToCSharpDatabaseRepresentation( break; case M_STRUCTURE: case M_UNION: - if (idl_isPredefined(memberTypeName)) { - dbType = os_strdup(idl_translateIfPredefined(memberTypeName)); + dbType = idl_CsharpScopeStackFromCType(memberType, FALSE, FALSE, fullyScoped); + if (idl_isPredefined(dbType)) { + c_char *tmp = os_strdup(idl_translateIfPredefined(dbType)); + os_free(dbType); + dbType = tmp; } else { - dbType = idl_CsharpId(memberTypeName, csUserData->customPSM, TRUE); + os_free(dbType); + dbType = idl_CsharpScopeStackFromCType(memberType, FALSE, TRUE, fullyScoped); } break; case M_COLLECTION: @@ -334,9 +510,7 @@ idl_cTypeToCSharpDatabaseRepresentation( { memberType = c_typeActualType(c_collectionTypeSubType(memberType)); } - memberTypeNameTmp = idl_scopeStackFromCType(memberType); - dbType = idl_cTypeToCSharpDatabaseRepresentation(memberType, memberTypeNameTmp, csUserData); - os_free(memberTypeNameTmp); + dbType = idl_cTypeToCSharpDatabaseRepresentation(memberType, TRUE); break; default: /* Unsupported structure member type */ @@ -353,91 +527,6 @@ idl_cTypeToCSharpDatabaseRepresentation( return dbType; } -#if 0 -static const c_char * -idl_cTypeToBaseType( - c_type memberType, - const char *memberTypeName) -{ - const c_char *baseType = NULL; - - switch (c_baseObjectKind(memberType)) - { - case M_PRIMITIVE: - switch (c_primitiveKind(memberType)) - { - case P_BOOLEAN: - baseType = os_strdup("Boolean"); - break; - case P_CHAR: - baseType = os_strdup("Char"); - break; - case P_OCTET: - baseType = os_strdup("Byte"); - break; - case P_SHORT: - baseType = os_strdup("Int16"); - break; - case P_USHORT: - baseType = os_strdup("UInt16"); - break; - case P_LONG: - baseType = os_strdup("Int32"); - break; - case P_ULONG: - baseType = os_strdup("UInt32"); - break; - case P_LONGLONG: - baseType = os_strdup("Int64"); - break; - case P_ULONGLONG: - baseType = os_strdup("UInt64"); - break; - case P_FLOAT: - baseType = os_strdup("Single"); - break; - case P_DOUBLE: - baseType = os_strdup("Double"); - break; - default: - /* Unsupported structure member type */ - assert(FALSE); - } - break; - case M_STRUCTURE: - if (strcmp(memberTypeName, "DDS.Duration_t") == 0) { - baseType = "Duration"; - } else if (strcmp(memberTypeName, "DDS.Time_t") == 0) { - baseType = "Time"; - } else if (strcmp(memberTypeName, "DDS.InstanceHandle_t") == 0) { - baseType = "InstanceHandle"; - } else { - /* This part of the code should never be reached for non-predefined types. */ - assert(FALSE); - } - break; - case M_COLLECTION: - switch(c_collectionTypeKind(memberType)) - { - case C_STRING: - baseType = "String"; - break; - default: - /* Other collection types should never reach this part of the code. */ - assert(FALSE); - break; - } - break; - default: - /* This part of the code should never be reached for other types. */ - assert(FALSE); - break; - } - - return baseType; -} -#endif - static c_ulonglong idl_determineDatabaseFlatArraySize(c_type arrayType) { @@ -456,12 +545,132 @@ idl_determineDatabaseFlatArraySize(c_type arrayType) return nrElements; } +static c_ulonglong +idl_determineDatabaseSize( + c_type type) +{ + c_ulonglong size; + + if (c_baseObjectKind(type) == M_COLLECTION && c_collectionTypeKind(type) == OSPL_C_ARRAY) { + c_ulonglong nrElements = 1; + + while (c_baseObjectKind(type) == M_COLLECTION && c_collectionTypeKind(type) == OSPL_C_ARRAY) { + nrElements *= c_collectionTypeMaxSize(type); + type = c_typeActualType(c_collectionTypeSubType(type)); + } + size = nrElements * type->size; + } else { + size = c_typeActualType(type)->size; + } + return size; +} + +static c_type +idl_getArrayElementType( + c_type arrayType) +{ + assert(c_baseObjectKind(arrayType) == M_COLLECTION && c_collectionTypeKind(arrayType) == OSPL_C_ARRAY); + + while (c_baseObjectKind(arrayType) == M_COLLECTION && c_collectionTypeKind(arrayType) == OSPL_C_ARRAY) { + arrayType = c_typeActualType(c_collectionTypeSubType(arrayType)); + } + + return arrayType; +} + +static c_char * +idl_genAttrElemVarName( + const c_char *item, + c_ulong index, + c_ulong level) +{ + c_char *name; + os_size_t size; + + size = 8 + strlen(item) + 2 *10 + 1; + name = os_malloc(size); + snprintf(name, size, "attr%uElem%u%s", index, level, item); + + return name; +} + + +static c_char * +idl_genAttrArrVarName( + const c_char *item, + c_ulong index, + c_ulong level) +{ + c_char *name; + os_size_t size; + + size = 7 + strlen(item) + 2 *10 + 1; + name = os_malloc(size); + snprintf(name, size, "attr%uVar%u%s", index, level, item); + + return name; +} + +static c_char * +idl_genAttrSeqVarName( + const c_char *item, + c_ulong index, + c_ulong level) +{ + c_char *name; + os_size_t size; + + size = 7 + strlen(item) + 2 *10 + 1; + name = os_malloc(size); + snprintf(name, size, "attr%uSeq%u%s", index, level, item); + + return name; +} + +static c_char * +idl_genAttrColVarName( + const c_char *item, + c_ulong index, + c_ulong level) +{ + c_char *name; + os_size_t size; + + size = 7 + strlen(item) + 2 *10 + 1; + name = os_malloc(size); + snprintf(name, size, "attr%uCol%u%s", index, level, item); + + return name; +} + +static c_char * +idl_genTypeNameFromCType(c_type type) +{ + idl_typeSpec typeSpec = idl_makeTypeSpec(type); + c_char *tName = idl_CsharpTypeFromTypeSpec(typeSpec, FALSE); + idl_freeTypeSpec(typeSpec); + + return tName; +} + +static c_type +idl_genGetContainerType(c_type collStartType, c_ulong dimension) +{ + c_type containerType = collStartType; + c_ulong i; + + for (i = 0; i < dimension; i++) { + assert(c_baseObjectKind(containerType) == M_COLLECTION); + containerType = c_typeActualType(c_collectionTypeSubType(containerType)); + } + return containerType; +} static void idl_generateDatabaseRepresentation ( idl_typeStruct typeSpec, - const c_char *structName, - SACSSplDcpsUserData *csUserData) + const c_char *structDBName, + SACSTypeUserData *csUserData) { /* Get the meta-data of this datatype from the database. */ c_type structType = idl_typeSpecDef(idl_typeSpec(typeSpec)); @@ -469,14 +678,14 @@ idl_generateDatabaseRepresentation ( /* Generate the C# code that opens a sealed class. */ idl_printIndent(indent_level); - idl_fileOutPrintf(idl_fileCur(), "#region __%s\n", structName); + idl_fileOutPrintf(idl_fileCur(), "#region %s\n", structDBName); idl_printIndent(indent_level); idl_fileOutPrintf(idl_fileCur(), "[StructLayout(LayoutKind.Sequential)]\n"); idl_printIndent(indent_level); idl_fileOutPrintf( idl_fileCur(), - "public struct __%s\n", - structName); + "public struct %s\n", + structDBName); idl_printIndent(indent_level); idl_fileOutPrintf(idl_fileCur(), "{\n"); @@ -486,7 +695,6 @@ idl_generateDatabaseRepresentation ( /* Loop over the attributes of the datatype and process each attribute. */ for (i = 0; i < nrMembers; i++) { c_char *dbType; - c_char *memberTypeName; /* Get the meta-data of the attribute from the database. */ c_member structMember = c_structureMember(structType, i); @@ -497,8 +705,7 @@ idl_generateDatabaseRepresentation ( FALSE); /* Now find and generate the corresponding database representation. */ - memberTypeName = idl_scopeStackFromCType(memberType); - dbType = idl_cTypeToCSharpDatabaseRepresentation(memberType, memberTypeName, csUserData); + dbType = idl_cTypeToCSharpDatabaseRepresentation(memberType, TRUE); /* generate the the database representation for the attribute. */ idl_printIndent(indent_level); @@ -514,7 +721,6 @@ idl_generateDatabaseRepresentation ( } os_free(dbType); - os_free(memberTypeName); os_free(memberName); } @@ -526,6 +732,83 @@ idl_generateDatabaseRepresentation ( idl_fileOutPrintf (idl_fileCur(), "#endregion\n\n"); } + +static void +idl_generateUnionDatabaseRepresentation ( + c_type unionType, + const c_char *unionDBName) +{ + /* Get the meta-data of this datatype from the database. */ + c_ulong i, nrMembers = c_unionUnionCaseCount((c_union)unionType); + c_ulonglong maxSize = 0; + + for (i = 0; i < nrMembers; i++) { + c_ulonglong size; + + c_unionCase unionCase = c_unionUnionCase(unionType, i); + c_type unionCaseType = c_typeActualType(c_unionCaseType(unionCase)); + + size = idl_determineDatabaseSize(unionCaseType); + maxSize = (size > maxSize) ? size : maxSize; + } + + + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "#region %s\n", unionDBName); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "[StructLayout(LayoutKind.Explicit, Pack=1)]\n"); + + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "public struct %s\n", unionDBName); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "{\n"); + + /* Increase the indentation level. */ + indent_level++; + + { + c_char *dbType; + c_type unionDiscrType = c_typeActualType(c_unionUnionSwitchType((c_union)unionType)); + + /* Now find and generate the corresponding database representation. */ + dbType = idl_cTypeToCSharpDatabaseRepresentation(unionDiscrType, TRUE); + + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "[FieldOffset(0)]\n"); + + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "public %s _d;\n", dbType); + + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "[FieldOffset(%"PA_PRIuSIZE")]\n", sizeof(void *)); + + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), + "[MarshalAs(UnmanagedType.ByValArray, SizeConst=%"PA_PRIu64")]\n", maxSize); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "public byte[] _u;\n"); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "public void Init()\n"); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "{\n"); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), " _u = new byte[%"PA_PRIu64"];\n", maxSize); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "}\n"); + + os_free(dbType); + } + + /* Decrease the indentation level and generate the closing bracket. */ + indent_level--; + + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "}\n"); + idl_printIndent(indent_level); + idl_fileOutPrintf (idl_fileCur(), "#endregion\n\n"); +} + + static void idl_determineFullyScopedName( c_type structType) @@ -541,11 +824,23 @@ idl_determineFullyScopedName( os_free(fullyScopedName); } +static c_longlong +determineNrEventualElements(c_type collType) +{ + c_longlong nrEventualElements = 1; + + while (c_baseObjectKind(collType) == M_COLLECTION && c_collectionTypeKind(collType) == OSPL_C_ARRAY) { + nrEventualElements *= c_collectionTypeMaxSize(collType); + collType = c_typeActualType(c_collectionTypeSubType(collType)); + } + return nrEventualElements; +} + static void idl_CreateAttributes( c_type structType, const c_char *structName, - SACSSplDcpsUserData *csUserData) + SACSTypeUserData *csUserData) { c_bool isPredefined = FALSE; c_ulong i, j, nrMembers = c_structureMemberCount((c_structure) structType); @@ -558,22 +853,26 @@ idl_CreateAttributes( /* Get the meta-data of the attribute from the database. */ c_member structMember = c_structureMember(structType, i); c_type memberType = c_memberType(structMember); - c_char *memberTypeName = idl_scopeStackFromCType(memberType); - c_char *memberName = idl_CsharpId( - c_specifierName(structMember), - csUserData->customPSM, - FALSE); + c_char *memberTypeName = idl_CsharpScopeStackFromCType(memberType, FALSE, FALSE, TRUE); if (idl_isPredefined(memberTypeName)) { isPredefined = TRUE; + } else { + isPredefined = FALSE; + os_free(memberTypeName); + memberTypeName = idl_CsharpScopeStackFromCType(memberType, FALSE, TRUE, TRUE); } /* Dereference possible typedefs first. */ while (c_baseObjectKind(memberType) == M_TYPEDEF && !isPredefined) { os_free(memberTypeName); memberType = c_typeDef(memberType)->alias; - memberTypeName = idl_scopeStackFromCType(memberType); + memberTypeName = idl_CsharpScopeStackFromCType(memberType, FALSE, FALSE, TRUE); if (idl_isPredefined(memberTypeName)) { isPredefined = TRUE; + } else { + isPredefined = FALSE; + os_free(memberTypeName); + memberTypeName = idl_CsharpScopeStackFromCType(memberType, FALSE, TRUE, TRUE); } } @@ -581,34 +880,28 @@ idl_CreateAttributes( { case M_COLLECTION: /* Iterate to the element type of the collection. */ - nrElements = 1; for (j = 0; c_baseObjectKind(memberType) == M_COLLECTION; j++) { - /* For sequences, cache the database type for CopyIn. */ - if (c_collectionTypeKind(memberType) == OSPL_C_SEQUENCE) { - c_char *subTypeName; - c_char *subTypeCSName; - + if (c_collectionTypeKind(memberType) == OSPL_C_SEQUENCE || + c_collectionTypeKind(memberType) == OSPL_C_ARRAY) { c_type subType = c_typeActualType(c_collectionTypeSubType(memberType)); - while (c_baseObjectKind(subType) == M_COLLECTION && c_collectionTypeKind(subType) == OSPL_C_ARRAY) { - nrElements *= (c_longlong) c_collectionTypeMaxSize(subType); - subType = c_typeActualType(c_collectionTypeSubType(subType)); - } - subTypeName = idl_scopeStackFromCType(subType); - subTypeCSName = idl_cTypeToCSharpDatabaseRepresentation(subType, subTypeName, csUserData); + c_char *subTypeName = idl_CsharpScopeStackFromCType(subType, FALSE, FALSE, TRUE); + c_char *subTypeDBName = idl_cTypeToCSharpDatabaseRepresentation(subType, TRUE); + nrElements = determineNrEventualElements(subType); idl_printIndent(indent_level); idl_fileOutPrintf(idl_fileCur(), - "private IntPtr attr%dSeq%dType = IntPtr.Zero;\n", i, j); + "private IntPtr attr%dCol%dType = IntPtr.Zero;\n", i, j); idl_printIndent(indent_level); idl_fileOutPrintf(idl_fileCur(), - "private static readonly int attr%dSeq%dSize = %"PA_PRId64" * Marshal.SizeOf(typeof(%s));\n", i, j, nrElements, subTypeCSName); - os_free(subTypeCSName); + "private static readonly int attr%dCol%dSize = %"PA_PRId64" * Marshal.SizeOf(typeof(%s));\n", i, j, nrElements, subTypeDBName); + if (idl_isPredefined(subTypeName)) isPredefined = TRUE; + os_free(subTypeDBName); os_free(subTypeName); } memberType = c_typeActualType(c_collectionTypeSubType(memberType)); os_free(memberTypeName); - memberTypeName = idl_scopeStackFromCType(memberType); + memberTypeName = idl_CsharpScopeStackFromCType(memberType, csUserData->customPSM, TRUE, TRUE); } - if (c_baseObjectKind(memberType) != M_STRUCTURE) { + if (c_baseObjectKind(memberType) != M_STRUCTURE && c_baseObjectKind(memberType) != M_UNION) { break; } else { /* No break statement here!! @@ -617,7 +910,8 @@ idl_CreateAttributes( */ } case M_STRUCTURE: - if (!idl_isPredefined(memberTypeName)) { + case M_UNION: + if (!isPredefined) { idl_printIndent(indent_level); idl_fileOutPrintf( @@ -629,7 +923,6 @@ idl_CreateAttributes( /* Fine: constructor doesn't need to do anything in particular here. */ break; } - os_free(memberName); os_free(memberTypeName); } idl_fileOutPrintf(idl_fileCur(), "\n"); @@ -638,8 +931,7 @@ idl_CreateAttributes( static void idl_CreateInitEmbeddedMarshalers( c_type structType, - const c_char *structName, - SACSSplDcpsUserData *csUserData) + const c_char *structName) { c_bool isPredefined; c_ulong i, nrMembers = c_structureMemberCount((c_structure) structType); @@ -660,16 +952,14 @@ idl_CreateInitEmbeddedMarshalers( /* Get the meta-data of the attribute from the database. */ c_member structMember = c_structureMember(structType, i); c_type memberType = c_memberType(structMember); - c_char *memberTypeName = idl_scopeStackFromCType(memberType); - c_char *memberName = idl_CsharpId( - c_specifierName(structMember), - csUserData->customPSM, - FALSE); + c_char *memberTypeName = idl_CsharpScopeStackFromCType(memberType, FALSE, FALSE, TRUE); if (idl_isPredefined(memberTypeName)) { isPredefined = TRUE; } else { isPredefined = FALSE; + os_free(memberTypeName); + memberTypeName = idl_CsharpScopeStackFromCType(memberType, FALSE, TRUE, TRUE); } /* Dereference possible typedefs/arrays/sequences first. */ @@ -684,18 +974,23 @@ idl_CreateInitEmbeddedMarshalers( } else if (c_baseObjectKind(memberType) == M_COLLECTION) { memberType = c_collectionTypeSubType(memberType); } - memberTypeName = idl_scopeStackFromCType(memberType); + memberTypeName = idl_CsharpScopeStackFromCType(memberType, FALSE, FALSE, TRUE); if (idl_isPredefined(memberTypeName)) { isPredefined = TRUE; + } else { + isPredefined = FALSE; + os_free(memberTypeName); + memberTypeName = idl_CsharpScopeStackFromCType(memberType, FALSE, TRUE, TRUE); } } switch(c_baseObjectKind(memberType)) { case M_STRUCTURE: - if (!idl_isPredefined(memberTypeName)) { + case M_UNION: + if (!isPredefined) { os_char *prevTypeName = memberTypeName; - memberTypeName = idl_CsharpId(prevTypeName, csUserData->customPSM, FALSE); + memberTypeName = idl_CsharpId(prevTypeName, FALSE, FALSE); os_free(prevTypeName); idl_printIndent(indent_level); idl_fileOutPrintf(idl_fileCur(), "if (attr%dMarshaler == null) {\n",i); @@ -733,7 +1028,6 @@ idl_CreateInitEmbeddedMarshalers( /* Fine: constructor doesn't need to do anything in particular here. */ break; } - os_free(memberName); os_free(memberTypeName); } @@ -804,6 +1098,47 @@ idl_CreateCSharpArrayIterationIndex( os_strncat(result, "]", maxResultLength); return result; +#undef IDL_INDEX_BUFFER_LENGTH +} + +static void +idl_genColTypeInitialization( + const c_char *colTypeName, + const c_char *idlFieldName, + c_ulong index, + c_ulong dimension) +{ + /* Locate the database type-definition of the sequence. */ + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "if (%s == IntPtr.Zero) {\n", colTypeName); + indent_level++; + idl_printIndent(indent_level); + if (dimension == 0) { + idl_fileOutPrintf(idl_fileCur(), + "IntPtr memberOwnerType = DDS.OpenSplice.Database.c.resolve(c.getBase(typePtr), fullyScopedName);\n"); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), + "IntPtr specifier = DDS.OpenSplice.Database.c.metaResolveSpecifier(memberOwnerType, \"%s\");\n", + idlFieldName); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), + "IntPtr specifierType = DDS.OpenSplice.Database.c.specifierType(specifier);\n"); + } else { + idl_fileOutPrintf(idl_fileCur(), + "DDS.OpenSplice.Database.c_collectionType colType = (DDS.OpenSplice.Database.c_collectionType) Marshal.PtrToStructure(\n"); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), + " attr%dCol%dType, typeof(DDS.OpenSplice.Database.c_collectionType));\n", index, dimension -1); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "IntPtr specifierType = colType.subType;\n"); + } + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), + "%s = DDS.OpenSplice.Database.c.typeActualType(specifierType);\n", + colTypeName); + indent_level--; + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "}\n"); } static c_char * @@ -811,27 +1146,17 @@ idl_CreateDatabaseArrayIterationIndex( c_type collStartType, c_ulong dimension) { - c_ulong i; + c_ulong i, j; c_type nextType; c_type currentType = c_typeActualType(collStartType); - - /* maxResultLength = '\0' + '[' + ']' + (dimension -1 ) * (2 * nrDecimals(MaxInt) + 'i' + '*' + ' + ') + 'i' + nrDecimals(MaxInt) */ - c_ulong maxResultLength = 1 + 2 + (dimension - 1) * (2 * 10 + 1 + 1 + 3) + 1 + 10; - c_char *result = os_malloc(maxResultLength); - c_char *format = NULL; - c_char postfix[IDL_INDEX_BUFFER_LENGTH]; - - assert (result != NULL); + c_char *indexStr; + c_char *prevIndexStr = os_strdup(""); /* If no dimension specified, return an empty string. */ - result[0] = '\0'; - if (dimension < 1) return result; + if (dimension < 1) return prevIndexStr; /* Assert that startType is always a collection type and has at least * the specified number of dimensions. */ - maxResultLength -= 1; - os_strncat(result, "[", maxResultLength); - maxResultLength -= 1; for (i = 0; i < (dimension - 1); i++) { /* Iterate to the subtype. */ nextType = c_typeActualType(c_collectionTypeSubType(currentType)); @@ -840,36 +1165,42 @@ idl_CreateDatabaseArrayIterationIndex( switch (c_collectionTypeKind(currentType)) { case OSPL_C_SEQUENCE: - format = "][i%d"; - (void)snprintf (postfix, IDL_INDEX_BUFFER_LENGTH, format, i); + (void)os_asprintf (&indexStr, "%si%d][", prevIndexStr, i); break; case OSPL_C_ARRAY: - if (c_collectionTypeKind(nextType) == OSPL_C_ARRAY) - { - format = "i%d*%d + "; - (void)snprintf (postfix, IDL_INDEX_BUFFER_LENGTH, format, i, c_collectionTypeMaxSize(currentType)); + if (c_collectionTypeKind(nextType) == OSPL_C_ARRAY) { + c_type iteratorType = nextType; + (void)os_asprintf (&indexStr, "%si%d", prevIndexStr, i); + for (j = i; j < dimension - 1; j++) { + os_free(prevIndexStr); + prevIndexStr = indexStr; + (void)os_asprintf (&indexStr, "%s*%d", prevIndexStr, c_collectionTypeMaxSize(iteratorType)); + iteratorType = c_typeActualType(c_collectionTypeSubType(iteratorType)); + if (c_baseObjectKind(iteratorType) != M_COLLECTION || + c_collectionTypeKind(iteratorType) != OSPL_C_ARRAY) break; + } + os_free(prevIndexStr); + prevIndexStr = indexStr; + (void)os_asprintf (&indexStr, "%s + ", prevIndexStr); } - else - { - format = "][i%d"; - (void)snprintf (postfix, IDL_INDEX_BUFFER_LENGTH, format, i); + else { + (void)os_asprintf (&indexStr, "%s][i%d", prevIndexStr, i); } break; default: /* Unsupported Collection type. */ + indexStr = NULL; assert(FALSE); + break; } currentType = nextType; - os_strncat (result, postfix, maxResultLength); + os_free(prevIndexStr); + prevIndexStr = indexStr; } + (void)os_asprintf (&indexStr, "[%si%d]", prevIndexStr, i); + os_free(prevIndexStr); - format = "i%d]"; - (void)snprintf (postfix, IDL_INDEX_BUFFER_LENGTH, format, i); - os_strncat(result, postfix, maxResultLength); - - return result; - -#undef IDL_INDEX_BUFFER_LENGTH + return indexStr; } static void @@ -879,7 +1210,9 @@ idl_CreateArrayMemberWriteInnerLoopBody( c_metaKind collKind, c_ulong index, c_ulong dimension, - const c_char *fieldName) + const c_char *fieldName, + const c_char *bufName, + c_bool isSeqOfArray) { c_ulong maxSize; c_char *cSharpArrayBrackets = idl_CreateCSharpArrayIterationIndex(collStartType, dimension); @@ -889,30 +1222,46 @@ idl_CreateArrayMemberWriteInnerLoopBody( switch(collKind) { case M_STRUCTURE: - collTypeName = idl_scopeStackFromCType(collType); + case M_UNION: + collTypeName = idl_CsharpScopeStackFromCType(collType, FALSE, TRUE, TRUE); idl_printIndent(indent_level); if (idl_isPredefined((collTypeName))) { idl_fileOutPrintf(idl_fileCur(), "to.%s%s = from.%s%s;\n", fieldName, databaseArrayBrackets, fieldName, cSharpArrayBrackets); } else { - idl_fileOutPrintf(idl_fileCur(), "{\n"); - idl_printIndent(indent_level + 1); - idl_fileOutPrintf(idl_fileCur(), - "V_COPYIN_RESULT result = attr%dMarshaler.CopyIn(typePtr, from.%s%s, ref to.%s%s);\n", - index, fieldName, cSharpArrayBrackets, fieldName, databaseArrayBrackets); - idl_printIndent(indent_level + 1); + if (isSeqOfArray) { + idl_fileOutPrintf(idl_fileCur(), + "V_COPYIN_RESULT result = attr%dMarshaler.CopyIn(typePtr, from.%s%s, %s);\n", + index, fieldName, cSharpArrayBrackets, bufName); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), + "%s = new IntPtr(%s.ToInt64() + attr%dCol%dSize);\n", + bufName, bufName, index, dimension); + } else { + idl_fileOutPrintf(idl_fileCur(), + "V_COPYIN_RESULT result = attr%dMarshaler.CopyIn(typePtr, from.%s%s, ref to.%s%s);\n", + index, fieldName, cSharpArrayBrackets, fieldName, databaseArrayBrackets); + } + idl_printIndent(indent_level); idl_fileOutPrintf(idl_fileCur(), "if (result != V_COPYIN_RESULT.OK) return result;\n"); - idl_printIndent(indent_level); - idl_fileOutPrintf(idl_fileCur(), "}\n"); } os_free(collTypeName); break; case M_ENUMERATION: idl_printIndent(indent_level); - idl_fileOutPrintf(idl_fileCur(), - "to.%s%s = (uint) from.%s%s;\n", - fieldName, databaseArrayBrackets, fieldName, cSharpArrayBrackets); + if (isSeqOfArray) { + idl_fileOutPrintf(idl_fileCur(), + "Marshal.WriteInt32(%s, 0, (int) from.%s%s);\n", + bufName, fieldName, cSharpArrayBrackets); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), + "%s = new IntPtr(%s.ToInt64() + 4);\n", bufName, bufName); + } else { + idl_fileOutPrintf(idl_fileCur(), + "to.%s%s = (uint) from.%s%s;\n", + fieldName, databaseArrayBrackets, fieldName, cSharpArrayBrackets); + } break; case M_PRIMITIVE: /* Generate code to handle a primitive. */ @@ -992,22 +1341,19 @@ idl_CreateSequenceMemberWriteInnerLoopBody( switch(collKind) { case M_STRUCTURE: + case M_UNION: collTypeName = idl_scopeStackFromCType(collType); idl_printIndent(indent_level); if (idl_isPredefined((collTypeName))) { idl_fileOutPrintf(idl_fileCur(), "Write(%s, 0, from.%s%s);\n", bufName, fieldName, cSharpArrayBrackets); } else { - idl_fileOutPrintf(idl_fileCur(), "{\n"); - idl_printIndent(indent_level + 1); idl_fileOutPrintf(idl_fileCur(), "V_COPYIN_RESULT result = attr%dMarshaler.CopyIn(typePtr, from.%s%s, %s);\n", index, fieldName, cSharpArrayBrackets, bufName); - idl_printIndent(indent_level + 1); + idl_printIndent(indent_level); idl_fileOutPrintf(idl_fileCur(), "if (result != V_COPYIN_RESULT.OK) return result;\n"); - idl_printIndent(indent_level); - idl_fileOutPrintf(idl_fileCur(), "}\n"); } os_free(collTypeName); break; @@ -1081,13 +1427,14 @@ idl_CreateArrayMemberWrite( c_type collType, c_ulong index, c_ulong dimension, - const c_char *fieldName, - const c_char *bufName) + const c_char *idlFieldName, + const c_char *csFieldName, + const c_char *bufName, + c_bool isSeqOfArray) { - c_ulong arrLength, seqMaxLength, nextBufTypeSizeLen; - c_ulong seqLengthNameSize, seqTypeNameSize; - c_char *seqLengthName, *seqTypeName, *nextBufTypeSize, *iterationIndex; - c_type subType, actualType; + c_ulong arrLength, seqMaxLength; + c_char *seqLengthName, *colTypeName, *nextBufTypeSize, *iterationIndex; + c_type subType, actualType, arrElemType; c_metaKind actualTypeKind; c_metaKind collKind = c_baseObjectKind(collType); @@ -1096,8 +1443,9 @@ idl_CreateArrayMemberWrite( case M_STRUCTURE: case M_ENUMERATION: case M_PRIMITIVE: + case M_UNION: idl_CreateArrayMemberWriteInnerLoopBody( - collStartType, collType, collKind, index, dimension, fieldName); + collStartType, collType, collKind, index, dimension, csFieldName, bufName, isSeqOfArray); break; case M_COLLECTION: /* Handle Collection type. */ @@ -1106,28 +1454,43 @@ idl_CreateArrayMemberWrite( case OSPL_C_STRING: /* Handle strings. */ idl_CreateArrayMemberWriteInnerLoopBody( - collStartType, collType, collKind, index, dimension, fieldName); + collStartType, collType, collKind, index, dimension, csFieldName, bufName, isSeqOfArray); break; case OSPL_C_ARRAY: /* Handle arrays. */ arrLength = c_collectionTypeMaxSize(collType); subType = c_collectionTypeSubType(collType); actualType = c_typeActualType(subType); + arrElemType = idl_getArrayElementType(collType); - /* Open a for loop to walk over the current dimension and increase the indent. */ - idl_printIndent(indent_level); - idl_fileOutPrintf(idl_fileCur(), "for (int i%d = 0; i%d < %d; i%d++) {\n", - dimension, dimension, arrLength, dimension); - indent_level++; + colTypeName = idl_genAttrColVarName("Type", index, dimension); + idl_genColTypeInitialization(colTypeName, idlFieldName, index, dimension); - /* Generate the the body to process the next dimension. */ - idl_CreateArrayMemberWrite(collStartType, actualType, index, - dimension + 1, fieldName, bufName); + if (c_baseObjectKind(arrElemType) == M_PRIMITIVE && + c_primitiveKind(arrElemType) != P_BOOLEAN && + c_primitiveKind(arrElemType) != P_CHAR) { + c_char *primName = idl_genTypeNameFromCType(subType); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "System.Buffer.BlockCopy(from.%s, 0, to.%s, 0, (%"PA_PRIu64" * Marshal.SizeOf(typeof(%s))));\n", + csFieldName, csFieldName, idl_determineDatabaseFlatArraySize(collStartType), primName); + os_free(primName); + } else { + /* Open a for loop to walk over the current dimension and increase the indent. */ + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "for (int i%d = 0; i%d < %d; i%d++) {\n", + dimension, dimension, arrLength, dimension); + indent_level++; - /* Close the for loop and decrease the indent level back to its original. */ - indent_level--; - idl_printIndent(indent_level); - idl_fileOutPrintf(idl_fileCur(), "}\n"); + /* Generate the the body to process the next dimension. */ + idl_CreateArrayMemberWrite(collStartType, actualType, index, + dimension + 1, idlFieldName, csFieldName, bufName, isSeqOfArray); + + /* Close the for loop and decrease the indent level back to its original. */ + indent_level--; + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "}\n"); + } + os_free(colTypeName); break; case OSPL_C_SEQUENCE: /* Handle sequences. */ @@ -1135,13 +1498,8 @@ idl_CreateArrayMemberWrite( actualType = c_typeActualType(subType); actualTypeKind = c_baseObjectKind(actualType); - seqLengthNameSize = 13 + 2 * 10 + 1; /* tmpl-size + 2 * MAX_INT + '\0'. */ - seqLengthName = os_malloc(seqLengthNameSize); - snprintf(seqLengthName, seqLengthNameSize, "attr%uSeq%uLength", index, dimension); - - seqTypeNameSize = 11 + 2 * 10 + 1; /* tmpl-size + 2 * MAX_INT + '\0'. */ - seqTypeName = os_malloc(seqTypeNameSize); - snprintf(seqTypeName, seqTypeNameSize, "attr%uSeq%uType", index, dimension); + seqLengthName = idl_genAttrSeqVarName("Length", index, dimension); + colTypeName = idl_genAttrColVarName("Type", index, dimension); seqMaxLength = c_collectionTypeMaxSize(collType); iterationIndex = idl_CreateCSharpArrayIterationIndex(collStartType, dimension); @@ -1149,12 +1507,12 @@ idl_CreateArrayMemberWrite( /* Check whether the sequence is valid. */ idl_printIndent(indent_level); idl_fileOutPrintf(idl_fileCur(), "if (from.%s%s == null) return V_COPYIN_RESULT.INVALID;\n", - fieldName, iterationIndex); + csFieldName, iterationIndex); /* Get its Length, and check it for validity. */ idl_printIndent(indent_level); idl_fileOutPrintf(idl_fileCur(), "int %s = from.%s%s.Length;\n", - seqLengthName, fieldName, iterationIndex); + seqLengthName, csFieldName, iterationIndex); if (seqMaxLength == 0) { idl_printIndent(indent_level); @@ -1166,46 +1524,22 @@ idl_CreateArrayMemberWrite( idl_fileOutPrintf(idl_fileCur(), "if (%s > %u) return V_COPYIN_RESULT.INVALID;\n", seqLengthName, seqMaxLength); } - /* Locate the database type-definition of the sequence. */ - idl_printIndent(indent_level); - idl_fileOutPrintf(idl_fileCur(), "if (%s == IntPtr.Zero) {\n", seqTypeName); - indent_level++; - idl_printIndent(indent_level); - if (dimension == 0) { - idl_fileOutPrintf(idl_fileCur(), - "IntPtr memberOwnerType = DDS.OpenSplice.Database.c.resolve(c.getBase(typePtr), fullyScopedName);\n"); - idl_printIndent(indent_level); - idl_fileOutPrintf(idl_fileCur(), - "IntPtr specifier = DDS.OpenSplice.Database.c.metaResolveSpecifier(memberOwnerType, \"%s\");\n", - fieldName); - idl_printIndent(indent_level); - idl_fileOutPrintf(idl_fileCur(), - "IntPtr specifierType = DDS.OpenSplice.Database.c.specifierType(specifier);\n"); - } else { - idl_fileOutPrintf(idl_fileCur(), - "DDS.OpenSplice.Database.c_collectionType colType = (DDS.OpenSplice.Database.c_collectionType) Marshal.PtrToStructure(\n"); - idl_printIndent(indent_level); - idl_fileOutPrintf(idl_fileCur(), - " attr%dSeq%dType, typeof(DDS.OpenSplice.Database.c_collectionType));\n", index, dimension -1); - idl_printIndent(indent_level); - idl_fileOutPrintf(idl_fileCur(), "IntPtr specifierType = colType.subType;\n"); - } - idl_printIndent(indent_level); - idl_fileOutPrintf(idl_fileCur(), - "%s = DDS.OpenSplice.Database.c.typeActualType(specifierType);\n", - seqTypeName); - indent_level--; - idl_printIndent(indent_level); - idl_fileOutPrintf(idl_fileCur(), "}\n"); + idl_genColTypeInitialization(colTypeName, idlFieldName, index, dimension); /* Allocate a matching array in the database. */ idl_printIndent(indent_level); idl_fileOutPrintf(idl_fileCur(), "IntPtr %s = DDS.OpenSplice.Database.c.newSequence(%s, %s);\n", - bufName, seqTypeName, seqLengthName); + bufName, colTypeName, seqLengthName); idl_printIndent(indent_level); idl_fileOutPrintf(idl_fileCur(), "if (%s == IntPtr.Zero) return V_COPYIN_RESULT.OUT_OF_MEMORY;\n", bufName); + if (dimension == 0 || + c_collectionTypeKind(idl_genGetContainerType(collStartType, dimension - 1)) == OSPL_C_ARRAY) { + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), + "to.%s%s = %s;\n", csFieldName, iterationIndex, bufName); + } switch(actualTypeKind) { @@ -1227,7 +1561,7 @@ idl_CreateArrayMemberWrite( idl_printIndent(indent_level); idl_fileOutPrintf(idl_fileCur(), "Marshal.Copy((%s[]) (Array) from.%s%s, 0, %s, %s);\n", - signedCounterPart, fieldName, iterationIndex, bufName, seqLengthName); + signedCounterPart, csFieldName, iterationIndex, bufName, seqLengthName); break; } case P_SHORT: @@ -1238,7 +1572,7 @@ idl_CreateArrayMemberWrite( case P_OCTET: idl_printIndent(indent_level); idl_fileOutPrintf(idl_fileCur(), - "Marshal.Copy(from.%s%s, 0, %s, %s);\n", fieldName, iterationIndex, bufName, seqLengthName); + "Marshal.Copy(from.%s%s, 0, %s, %s);\n", csFieldName, iterationIndex, bufName, seqLengthName); break; default: /* Intentionally fall through to the default handler. */ @@ -1246,28 +1580,31 @@ idl_CreateArrayMemberWrite( } if (c_primitiveKind(actualType) != P_BOOLEAN && c_primitiveKind(actualType) != P_CHAR) break; default: - nextBufTypeSizeLen = 10 + 2 * 10 + 1; /* tmpl-size + 2 * MAX_INT + '\0'. */ - nextBufTypeSize = os_malloc(nextBufTypeSizeLen); - snprintf(nextBufTypeSize, nextBufTypeSizeLen, "attr%uSeq%uSize", index, dimension); + nextBufTypeSize = idl_genAttrColVarName("Size", index, dimension); idl_printIndent(indent_level); idl_fileOutPrintf(idl_fileCur(), "for (int i%u = 0; i%u < %s; i%u++) {\n", dimension, dimension, seqLengthName, dimension); indent_level++; if (actualTypeKind == M_COLLECTION && c_collectionTypeKind(actualType) != OSPL_C_STRING) { subType = c_typeActualType(c_collectionTypeSubType(actualType)); - if (c_collectionTypeKind(actualType) == OSPL_C_ARRAY && c_baseObjectKind(subType) == M_PRIMITIVE) { - os_free(iterationIndex); - iterationIndex = idl_CreateCSharpArrayIterationIndex(collStartType, dimension + 1); - idl_printIndent(indent_level); - idl_fileOutPrintf(idl_fileCur(), "Marshal.Copy(from.%s%s, 0, %s, %d);\n", - fieldName, iterationIndex, bufName, c_collectionTypeMaxSize(actualType)); + if (c_collectionTypeKind(actualType) == OSPL_C_ARRAY) { + if (c_baseObjectKind(subType) == M_PRIMITIVE) { + os_free(iterationIndex); + iterationIndex = idl_CreateCSharpArrayIterationIndex(collStartType, dimension + 1); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "Marshal.Copy(from.%s%s, 0, %s, %d);\n", + csFieldName, iterationIndex, bufName, c_collectionTypeMaxSize(actualType)); + } else { + idl_CreateArrayMemberWrite( + collStartType, actualType, index, dimension + 1, idlFieldName, csFieldName, bufName, TRUE); + } } else { c_ulong seqBufNameSize = 10 + 2 * 10 + 1; /* tmpl-size + 2 * MAX_INT + '\0'. */ c_char *seqBufName = os_malloc(seqBufNameSize); snprintf(seqBufName, seqBufNameSize, "attr%uSeq%uBuf", index, dimension + 1); idl_CreateArrayMemberWrite(collStartType, actualType, index, - dimension + 1, fieldName, seqBufName); - if (c_collectionTypeKind(actualType) == OSPL_C_SEQUENCE) { + dimension + 1, idlFieldName, csFieldName, seqBufName, isSeqOfArray); + if (c_collectionTypeKind(collType) == OSPL_C_SEQUENCE) { if (c_baseObjectKind(subType) == M_PRIMITIVE) { idl_printIndent(indent_level); idl_fileOutPrintf(idl_fileCur(), @@ -1275,7 +1612,7 @@ idl_CreateArrayMemberWrite( } else { idl_printIndent(indent_level); idl_fileOutPrintf(idl_fileCur(), - "Marshal.WriteIntPtr(%s, new IntPtr(%s.ToInt64() - ((long) attr%dSeq%dSize * (long) attr%dSeq%dLength)));\n", + "Marshal.WriteIntPtr(%s, new IntPtr(%s.ToInt64() - ((long) attr%dCol%dSize * (long) attr%dSeq%dLength)));\n", bufName, seqBufName, index, dimension + 1, index, dimension + 1); } } @@ -1284,11 +1621,13 @@ idl_CreateArrayMemberWrite( } else { idl_CreateSequenceMemberWriteInnerLoopBody( collStartType, actualType, actualTypeKind, index, dimension + 1, - fieldName, bufName); + csFieldName, bufName); + } + if (actualTypeKind != M_COLLECTION || c_collectionTypeKind(actualType) != OSPL_C_ARRAY) { + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), + "%s = new IntPtr(%s.ToInt64() + %s);\n", bufName, bufName, nextBufTypeSize); } - idl_printIndent(indent_level); - idl_fileOutPrintf(idl_fileCur(), - "%s = new IntPtr(%s.ToInt64() + %s);\n", bufName, bufName, nextBufTypeSize); indent_level--; idl_printIndent(indent_level); idl_fileOutPrintf(idl_fileCur(), "}\n"); @@ -1297,7 +1636,7 @@ idl_CreateArrayMemberWrite( } os_free(iterationIndex); - os_free(seqTypeName); + os_free(colTypeName); os_free(seqLengthName); break; default: @@ -1313,14 +1652,16 @@ idl_CreateArrayMemberWrite( } } + static void idl_CreateStructMemberWrite( c_type memberType, - const c_char * memberName, + const char *idlMemberName, + const char *csMemberName, c_ulong index, - SACSSplDcpsUserData *csUserData) + SACSTypeUserData *csUserData) { - c_ulong bufNameLength, maxSize, dimension; + c_ulong maxSize, dimension; c_ulonglong totalNrElements; c_char *bufName = NULL; c_bool isPredefined = FALSE; @@ -1346,11 +1687,12 @@ idl_CreateStructMemberWrite( switch(c_baseObjectKind(memberType)) { case M_STRUCTURE: + case M_UNION: if (isPredefined) { /* Generate code to use the predefined Write operation in the base marshaler. */ idl_printIndent(indent_level); - idl_fileOutPrintf(idl_fileCur(), "to.%s = from.%s;\n", memberName, memberName); + idl_fileOutPrintf(idl_fileCur(), "to.%s = from.%s;\n", csMemberName, csMemberName); } else { @@ -1361,8 +1703,8 @@ idl_CreateStructMemberWrite( idl_fileOutPrintf(idl_fileCur(), "V_COPYIN_RESULT result = attr%dMarshaler.CopyIn(typePtr, from.%s, ref to.%s);\n", index, - memberName, - memberName); + csMemberName, + csMemberName); idl_printIndent(indent_level + 1); idl_fileOutPrintf(idl_fileCur(), "if (result != V_COPYIN_RESULT.OK) return result;\n"); @@ -1375,8 +1717,8 @@ idl_CreateStructMemberWrite( idl_printIndent(indent_level); idl_fileOutPrintf(idl_fileCur(), "to.%s = (uint) from.%s;\n", - memberName, - memberName); + csMemberName, + csMemberName); break; case M_PRIMITIVE: /* Generate code to handle a primitive. */ @@ -1386,12 +1728,12 @@ idl_CreateStructMemberWrite( idl_printIndent(indent_level); idl_fileOutPrintf(idl_fileCur(), "to.%s = from.%s ? (byte) 1 : (byte) 0;\n", - memberName, - memberName); + csMemberName, + csMemberName); break; case P_CHAR: idl_printIndent(indent_level); - idl_fileOutPrintf(idl_fileCur(), "to.%s = (byte) from.%s;\n", memberName, memberName); + idl_fileOutPrintf(idl_fileCur(), "to.%s = (byte) from.%s;\n", csMemberName, csMemberName); break; case P_OCTET: case P_SHORT: case P_USHORT: @@ -1399,7 +1741,7 @@ idl_CreateStructMemberWrite( case P_LONGLONG: case P_ULONGLONG: case P_FLOAT: case P_DOUBLE: idl_printIndent(indent_level); - idl_fileOutPrintf(idl_fileCur(), "to.%s = from.%s;\n", memberName, memberName); + idl_fileOutPrintf(idl_fileCur(), "to.%s = from.%s;\n", csMemberName, csMemberName); break; default: /* Unsupported primitive type. */ @@ -1414,7 +1756,7 @@ idl_CreateStructMemberWrite( case OSPL_C_STRING: /* Generate code to handle strings. */ idl_printIndent(indent_level); - idl_fileOutPrintf(idl_fileCur(), "if (from.%s == null) return V_COPYIN_RESULT.INVALID;\n", memberName); + idl_fileOutPrintf(idl_fileCur(), "if (from.%s == null) return V_COPYIN_RESULT.INVALID;\n", csMemberName); /* Generate code to check for bounds if a maximum bound was specified. */ maxSize = c_collectionTypeMaxSize(memberType); idl_printIndent(indent_level); @@ -1422,7 +1764,7 @@ idl_CreateStructMemberWrite( { idl_fileOutPrintf(idl_fileCur(), "if (from.%s.Length > %d) return V_COPYIN_RESULT.INVALID;\n", - memberName, + csMemberName, maxSize); } else @@ -1432,13 +1774,13 @@ idl_CreateStructMemberWrite( idl_printIndent(indent_level); idl_fileOutPrintf(idl_fileCur(), "if (!Write(c.getBase(typePtr), ref to.%s, from.%s)) return V_COPYIN_RESULT.OUT_OF_MEMORY;\n", - memberName, - memberName); + csMemberName, + csMemberName); break; case OSPL_C_ARRAY: /* Check that the input is non-null. */ idl_printIndent(indent_level); - idl_fileOutPrintf(idl_fileCur(), "if (from.%s == null) return V_COPYIN_RESULT.INVALID;\n", memberName); + idl_fileOutPrintf(idl_fileCur(), "if (from.%s == null) return V_COPYIN_RESULT.INVALID;\n", csMemberName); /* Check that the input has the correct array size. */ arrType = memberType; @@ -1446,38 +1788,36 @@ idl_CreateStructMemberWrite( { idl_printIndent(indent_level); idl_fileOutPrintf(idl_fileCur(), "if (from.%s.GetLength(%d) != %d) return V_COPYIN_RESULT.INVALID;\n", - memberName, dimension, c_collectionTypeMaxSize(arrType)); + csMemberName, dimension, c_collectionTypeMaxSize(arrType)); arrType = c_typeActualType(c_collectionTypeSubType(arrType)); } /* Initialize the database sample to the correct Array size. */ totalNrElements = idl_determineDatabaseFlatArraySize(memberType); - bufName = idl_cTypeToCSharpDatabaseRepresentation(memberType, memberTypeName, csUserData); + bufName = idl_cTypeToCSharpDatabaseRepresentation(memberType, TRUE); idl_printIndent(indent_level); - idl_fileOutPrintf(idl_fileCur(), "to.%s = new %s[%"PA_PRIu64"];\n", memberName, bufName, totalNrElements); + idl_fileOutPrintf(idl_fileCur(), "to.%s = new %s[%"PA_PRIu64"];\n", csMemberName, bufName, totalNrElements); /* Generate the body of the copying loop. */ idl_CreateArrayMemberWrite( - memberType, memberType, index, 0, memberName, memberName); + memberType, memberType, index, 0, idlMemberName, csMemberName, csMemberName, FALSE); os_free(bufName); break; case OSPL_C_SEQUENCE: - bufNameLength = 10 + 2 * 10 + 1; /* tmpl-size + 2 * MAX_INT + '\0'. */ - bufName = os_malloc(bufNameLength); - snprintf(bufName, bufNameLength, "attr%dSeq%dBuf", index, 0); + bufName = idl_genAttrSeqVarName("Buf", index, 0); idl_CreateArrayMemberWrite( - memberType, memberType, index, 0, memberName, bufName); + memberType, memberType, index, 0, idlMemberName, csMemberName, bufName, FALSE); - if (c_baseObjectKind(c_typeActualType(c_collectionTypeSubType(memberType))) != M_PRIMITIVE) { + arrType = c_typeActualType(c_collectionTypeSubType(memberType)); + if (c_baseObjectKind(arrType) == M_PRIMITIVE && + c_primitiveKind(arrType) != P_BOOLEAN && c_primitiveKind(arrType) != P_CHAR) { idl_printIndent(indent_level); - idl_fileOutPrintf(idl_fileCur(), - "to.%s = new IntPtr(%s.ToInt64() - ((long) attr%dSeq0Size * (long) attr%dSeq0Length));\n", - memberName, bufName, index, index); + idl_fileOutPrintf(idl_fileCur(),"to.%s = %s;\n", csMemberName, bufName); } - os_free(bufName); break; + default: /* Unsupported Collection type. */ assert(FALSE); @@ -1495,8 +1835,9 @@ idl_CreateStructMemberWrite( static void idl_CreateCopyIn( c_type structType, - const c_char *structName, - SACSSplDcpsUserData *csUserData) + const c_char *structDBName, + const c_char *fullyScopedName, + SACSTypeUserData *csUserData) { c_ulong i, nrMembers = c_structureMemberCount((c_structure) structType); @@ -1511,7 +1852,7 @@ idl_CreateCopyIn( idl_printIndent(indent_level); idl_fileOutPrintf(idl_fileCur(), "GCHandle tmpGCHandle = GCHandle.FromIntPtr(from);\n"); idl_printIndent(indent_level); - idl_fileOutPrintf(idl_fileCur(), "%s fromData = tmpGCHandle.Target as %s;\n", structName, structName); + idl_fileOutPrintf(idl_fileCur(), "%s fromData = tmpGCHandle.Target as %s;\n", fullyScopedName, fullyScopedName); idl_printIndent(indent_level); idl_fileOutPrintf(idl_fileCur(), "return CopyIn(typePtr, fromData, to);\n"); /* Decrease the indent level back to its original value and close the 1st CopyIn operation. */ @@ -1521,12 +1862,12 @@ idl_CreateCopyIn( /* Generate code that creates a C# projection of the database, invoke the 3rd CopyIn with it, and marshal it into unmanaged memory. */ idl_printIndent(indent_level); - idl_fileOutPrintf(idl_fileCur(), "public V_COPYIN_RESULT CopyIn(System.IntPtr typePtr, %s from, System.IntPtr to)\n", structName); + idl_fileOutPrintf(idl_fileCur(), "public V_COPYIN_RESULT CopyIn(System.IntPtr typePtr, %s from, System.IntPtr to)\n", fullyScopedName); idl_printIndent(indent_level); idl_fileOutPrintf(idl_fileCur(), "{\n"); indent_level++; idl_printIndent(indent_level); - idl_fileOutPrintf(idl_fileCur(), "__%s nativeImg = new __%s();\n", structName, structName); + idl_fileOutPrintf(idl_fileCur(), "%s nativeImg = new %s();\n", structDBName, structDBName); idl_printIndent(indent_level); idl_fileOutPrintf(idl_fileCur(), "V_COPYIN_RESULT result = CopyIn(typePtr, from, ref nativeImg);\n"); idl_printIndent(indent_level); @@ -1549,7 +1890,7 @@ idl_CreateCopyIn( /* Open the 2nd CopyIn operation and increase the indent. */ idl_printIndent(indent_level); - idl_fileOutPrintf(idl_fileCur(), "public V_COPYIN_RESULT CopyIn(System.IntPtr typePtr, %s from, ref __%s to)\n", structName, structName); + idl_fileOutPrintf(idl_fileCur(), "public V_COPYIN_RESULT CopyIn(System.IntPtr typePtr, %s from, ref %s to)\n", fullyScopedName, structDBName); idl_printIndent(indent_level); idl_fileOutPrintf(idl_fileCur(), "{\n"); indent_level++; @@ -1567,7 +1908,7 @@ idl_CreateCopyIn( c_specifierName(structMember), csUserData->customPSM, FALSE); - idl_CreateStructMemberWrite(memberType, memberName, i, csUserData); + idl_CreateStructMemberWrite(memberType, c_specifierName(structMember), memberName, i, csUserData); os_free(memberName); } @@ -1639,7 +1980,7 @@ idl_CreateArrayInitialization( const c_char *fieldName, const c_char *seqLengthName, const c_char *arrayBrackets, - SACSSplDcpsUserData *csUserData) + SACSTypeUserData *csUserData) { c_char *arrayIndex = NULL, *arrayCtor; c_type subType = c_typeActualType(c_collectionTypeSubType(currentType)); @@ -1677,6 +2018,7 @@ idl_CreateArrayInitialization( break; /* Object kind, try to recycle elements as much as possible. */ case M_STRUCTURE: + case M_UNION: subTypeName = idl_scopeStackFromCType(subType); if (idl_isPredefined(subTypeName)) { idl_printIndent(indent_level); @@ -1700,6 +2042,69 @@ idl_CreateArrayInitialization( idl_typeArrayFree(idl_typeArray(typeSpec)); } +static void +idl_generateArrayStatusCheck( + c_type collStartType, + c_type collType, + c_type *eventualElementType, + c_ulong dimension, + const c_char *fieldName, + SACSTypeUserData *csUserData) +{ + c_ulong i; + c_char *arrayBrackets = idl_CreateCSharpArrayIterationIndex(collStartType, dimension); + + /* Check if this dimension is part of a prior rectangular array by checking + * whether its parent is also an array. + */ + c_type parentType = collStartType; + for (i = 1; i < dimension; i++) + { + parentType = c_typeActualType(c_collectionTypeSubType(parentType)); + } + if (parentType == collType || + (c_baseObjectKind(parentType) != M_COLLECTION || + c_collectionTypeKind(parentType) != OSPL_C_ARRAY)) + { + /* If no prior rectangular dimensions, then check the current dimensions. */ + c_ulong curDim; + os_size_t dimensionCheckSize = 15 + strlen(fieldName) + strlen (arrayBrackets) + 1; + c_char *dimensionCheck = os_malloc(dimensionCheckSize); + snprintf(dimensionCheck, dimensionCheckSize, + "to.%s%s == null", fieldName, arrayBrackets); + *eventualElementType = c_typeActualType(collType); + for (i = 0; c_baseObjectKind(*eventualElementType) == M_COLLECTION && + c_collectionTypeKind(*eventualElementType) == OSPL_C_ARRAY; i++) + { + c_char *prevdimensionCheck = dimensionCheck; + curDim = c_collectionTypeMaxSize(*eventualElementType); + dimensionCheckSize = strlen(prevdimensionCheck) + 26 + strlen(fieldName) + + strlen(arrayBrackets) + 2 * 10 /* MAX_INT */ + 1; + dimensionCheck = os_malloc(dimensionCheckSize); + snprintf(dimensionCheck, dimensionCheckSize, + "%s || to.%s%s.GetLength(%d) != %d", + prevdimensionCheck, fieldName, arrayBrackets, i, curDim); + os_free(prevdimensionCheck); + *eventualElementType = c_typeActualType(c_collectionTypeSubType(*eventualElementType)); + } + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "if (%s) {\n", dimensionCheck); + indent_level++; + idl_CreateArrayInitialization(collType, fieldName, "", arrayBrackets, csUserData); + indent_level--; + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "}\n"); + os_free(dimensionCheck); + } + else + { + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), + "// Not the start of a rectangular array: initialization not required...\n"); + } + os_free(arrayBrackets); +} + static void idl_CreateArrayMemberReadInnerLoopBody( c_type collStartType, @@ -1709,11 +2114,11 @@ idl_CreateArrayMemberReadInnerLoopBody( c_ulong dimension, const c_char *fieldName, const c_char *bufName, - SACSSplDcpsUserData *csUserData) + c_bool isSeqOfArray) { c_char *cSharpArrayBrackets = idl_CreateCSharpArrayIterationIndex(collStartType, dimension); c_char *databaseArrayBrackets = idl_CreateDatabaseArrayIterationIndex(collStartType, dimension); - c_char *colTypeName = idl_scopeStackFromCType(collType); + c_char *colTypeName = idl_CsharpScopeStackFromCType(collType, FALSE, FALSE, TRUE); OS_UNUSED_ARG(index); OS_UNUSED_ARG(bufName); @@ -1721,27 +2126,47 @@ idl_CreateArrayMemberReadInnerLoopBody( switch(collKind) { case M_STRUCTURE: + case M_UNION: + idl_printIndent(indent_level); if (idl_isPredefined(colTypeName)) { - idl_printIndent(indent_level); idl_fileOutPrintf(idl_fileCur(), "to.%s%s = from.%s%s;\n", fieldName, cSharpArrayBrackets, fieldName, databaseArrayBrackets); } else { /* Get the CSharp specific name of the member type. */ - c_char *prevColTypeName = colTypeName; - colTypeName = idl_CsharpId(prevColTypeName, csUserData->customPSM, FALSE); - os_free(prevColTypeName); - idl_printIndent(indent_level); - idl_fileOutPrintf(idl_fileCur(), - "%sMarshaler.CopyOut(ref from.%s%s, ref to.%s%s);\n", - colTypeName, fieldName, databaseArrayBrackets, fieldName, cSharpArrayBrackets); + if (isSeqOfArray) { + idl_fileOutPrintf(idl_fileCur(), + "attr%dMarshaler.CopyOut(%s, ref to.%s%s);\n", + index, bufName, fieldName, cSharpArrayBrackets); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), + "%s = new IntPtr(%s.ToInt64() + attr%dCol%dSize);\n", + bufName, bufName, index, dimension); + } else { + c_char *colTypeDbName = idl_CsharpScopeStackFromCType(collType, FALSE, TRUE, TRUE); + idl_fileOutPrintf(idl_fileCur(), + "%sMarshaler.CopyOut(ref from.%s%s, ref to.%s%s);\n", + colTypeDbName, fieldName, databaseArrayBrackets, fieldName, cSharpArrayBrackets); + os_free(colTypeDbName); + } } break; case M_ENUMERATION: idl_printIndent(indent_level); - idl_fileOutPrintf(idl_fileCur(), - "to.%s%s = (%s) from.%s%s;\n", - fieldName, cSharpArrayBrackets, colTypeName, fieldName, databaseArrayBrackets); + if (isSeqOfArray) { + c_char *targetEnumType = idl_CsharpScopeStackFromCType(collType, FALSE, FALSE, TRUE); + idl_fileOutPrintf(idl_fileCur(), + "to.%s%s = (%s) Marshal.ReadInt32(%s);\n", + fieldName, cSharpArrayBrackets, targetEnumType, bufName); + os_free(targetEnumType); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), + "%s = new IntPtr(%s.ToInt64() + 4);\n", bufName, bufName); + } else { + idl_fileOutPrintf(idl_fileCur(), + "to.%s%s = (%s) from.%s%s;\n", + fieldName, cSharpArrayBrackets, colTypeName, fieldName, databaseArrayBrackets); + } break; case M_PRIMITIVE: /* Generate code to handle a primitive. */ @@ -1751,11 +2176,11 @@ idl_CreateArrayMemberReadInnerLoopBody( case P_BOOLEAN: idl_fileOutPrintf(idl_fileCur(), "to.%s%s = (from.%s%s != 0 ? true : false);\n", - fieldName, databaseArrayBrackets, fieldName, cSharpArrayBrackets); + fieldName, cSharpArrayBrackets, fieldName, databaseArrayBrackets); break; case P_CHAR: idl_fileOutPrintf(idl_fileCur(), "(to.%s%s) = (char) (from.%s%s);\n", - fieldName, databaseArrayBrackets, fieldName, cSharpArrayBrackets); + fieldName, cSharpArrayBrackets, fieldName, databaseArrayBrackets); break; case P_OCTET: case P_SHORT: case P_USHORT: @@ -1797,17 +2222,18 @@ idl_CreateSequenceMemberReadInnerLoopBody( c_ulong dimension, const c_char *fieldName, const c_char *bufName, - SACSSplDcpsUserData *csUserData) + SACSTypeUserData *csUserData) { c_char *cSharpArrayBrackets = idl_CreateCSharpArrayIterationIndex(collStartType, dimension); - c_char *colTypeName = idl_scopeStackFromCType(collType); + c_char *colTypeName = idl_CsharpScopeStackFromCType(collType, csUserData->customPSM, FALSE, TRUE); OS_UNUSED_ARG(index); switch(collKind) { case M_STRUCTURE: + case M_UNION: idl_printIndent(indent_level); if (idl_isPredefined(colTypeName)) { /* Function below returns const string, so no need to free it afterward. */ @@ -1817,19 +2243,18 @@ idl_CreateSequenceMemberReadInnerLoopBody( "to.%s%s = Read%s(%s, 0);\n", fieldName, cSharpArrayBrackets, &predefinedTypeName[4], bufName); } else { + c_char *colDbTypeName = idl_CsharpScopeStackFromCType(collType, csUserData->customPSM, TRUE, TRUE); /* Get the CSharp specific name of the member type. */ - c_char *prevColTypeName = colTypeName; - colTypeName = idl_CsharpId(prevColTypeName, csUserData->customPSM, FALSE); - os_free(prevColTypeName); idl_fileOutPrintf(idl_fileCur(), "%sMarshaler.StaticCopyOut(%s, ref to.%s%s);\n", - colTypeName, bufName, fieldName, cSharpArrayBrackets); + colDbTypeName, bufName, fieldName, cSharpArrayBrackets); + os_free(colDbTypeName); } break; case M_ENUMERATION: idl_printIndent(indent_level); idl_fileOutPrintf(idl_fileCur(), - "to.%s%s = (%s) ReadInt32(%s);\n", + "to.%s%s = (%s) Marshal.ReadInt32(%s);\n", fieldName, cSharpArrayBrackets, colTypeName, bufName); break; case M_PRIMITIVE: @@ -1881,14 +2306,13 @@ idl_CreateArrayMemberRead( c_ulong dimension, const c_char *fieldName, const c_char *bufName, - SACSSplDcpsUserData *csUserData) + c_bool isSeqOfArray, + SACSTypeUserData *csUserData) { - c_ulong i, arrLength; - os_size_t dimensionCheckSize; + c_ulong arrLength; c_ulong seqLengthNameSize, nextBufTypeSizeLen; - c_char *seqLengthName, *nextBufTypeSize, *arrayBrackets; - c_char *dimensionCheck; - c_type subType, actualType, parentType; + c_char *seqLengthName, *nextBufTypeSize, *arrayBrackets, *nextBuf; + c_type subType, actualType, eventualElementType; c_metaKind actualTypeKind; c_metaKind collKind = c_baseObjectKind(collType); @@ -1897,8 +2321,9 @@ idl_CreateArrayMemberRead( case M_STRUCTURE: case M_ENUMERATION: case M_PRIMITIVE: + case M_UNION: idl_CreateArrayMemberReadInnerLoopBody(collStartType, collType, collKind, - index, dimension, fieldName, bufName, csUserData); + index, dimension, fieldName, bufName, isSeqOfArray); break; case M_COLLECTION: /* Handle Collection type. */ @@ -1907,72 +2332,43 @@ idl_CreateArrayMemberRead( case OSPL_C_STRING: /* Handle strings. */ idl_CreateArrayMemberReadInnerLoopBody(collStartType, collType, collKind, - index, dimension, fieldName, bufName, csUserData); + index, dimension, fieldName, bufName, isSeqOfArray); break; case OSPL_C_ARRAY: - /* Handle arrays. */ arrLength = c_collectionTypeMaxSize(collType); subType = c_collectionTypeSubType(collType); actualType = c_typeActualType(subType); - arrayBrackets = idl_CreateCSharpArrayIterationIndex(collStartType, dimension); - - /* Check if this dimension is part of a prior rectangular array by checking - * whether its parent is also an array. - */ - parentType = collStartType; - for (i = 0; i < dimension; i++) - { - parentType = c_typeActualType(c_collectionTypeSubType(parentType)); - } - if (parentType == collStartType || - (c_baseObjectKind(parentType) != M_COLLECTION && - c_collectionTypeKind(parentType) != OSPL_C_ARRAY)) - { - /* If no prior rectangular dimensions, then check the current dimensions. */ - c_ulong curDim; - subType = c_typeActualType(collType); - dimensionCheckSize = 15 + strlen(fieldName) + strlen (arrayBrackets) + 1; - dimensionCheck = os_malloc(dimensionCheckSize); - snprintf(dimensionCheck, dimensionCheckSize, - "to.%s%s == null", fieldName, arrayBrackets); - for (i = 0; c_baseObjectKind(subType) == M_COLLECTION && - c_collectionTypeKind(subType) == OSPL_C_ARRAY; i++) - { - c_char *prevdimensionCheck = dimensionCheck; - curDim = c_collectionTypeMaxSize(subType); - dimensionCheckSize = strlen(prevdimensionCheck) + 26 + strlen(fieldName) + - strlen(arrayBrackets) + 2 * 10 /* MAX_INT */ + 1; - dimensionCheck = os_malloc(dimensionCheckSize); - snprintf(dimensionCheck, dimensionCheckSize, - "%s || to.%s%s.GetLength(%d) != %d", - prevdimensionCheck, fieldName, arrayBrackets, i, curDim); - os_free(prevdimensionCheck); - subType = c_typeActualType(c_collectionTypeSubType(subType)); + eventualElementType = actualType; + idl_generateArrayStatusCheck(collStartType, collType, &eventualElementType, dimension, fieldName, csUserData); + if (c_baseObjectKind(eventualElementType) == M_PRIMITIVE && + c_primitiveKind(eventualElementType) != P_BOOLEAN && + c_primitiveKind(eventualElementType) != P_CHAR) { + c_char *primName = idl_genTypeNameFromCType(eventualElementType); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "System.Buffer.BlockCopy(from.%s, 0, to.%s, 0, (%"PA_PRIu64" * Marshal.SizeOf(typeof(%s))));\n", + fieldName, fieldName, idl_determineDatabaseFlatArraySize(collStartType), primName); + os_free(primName); + } else { + if (c_baseObjectKind(actualType) == M_COLLECTION && c_collectionTypeKind(actualType) == OSPL_C_SEQUENCE) { + c_char *bufIndex = idl_CreateDatabaseArrayIterationIndex(collStartType, dimension + 1); + size_t bufNameLength = strlen(bufName) + strlen(bufIndex) + 1; + nextBuf = os_malloc(bufNameLength); + snprintf(nextBuf, bufNameLength, "%s%s", bufName, bufIndex); + os_free(bufIndex); + } else { + nextBuf = os_strdup(bufName); } idl_printIndent(indent_level); - idl_fileOutPrintf(idl_fileCur(), "if (%s) {\n", dimensionCheck); + idl_fileOutPrintf(idl_fileCur(), "for (int i%d = 0; i%d < %d; i%d++) {\n", + dimension, dimension, arrLength, dimension); indent_level++; - idl_CreateArrayInitialization(collType, fieldName, "", arrayBrackets, csUserData); + idl_CreateArrayMemberRead(collStartType, actualType, index, + dimension + 1, fieldName, nextBuf, isSeqOfArray, csUserData); + os_free(nextBuf); indent_level--; idl_printIndent(indent_level); idl_fileOutPrintf(idl_fileCur(), "}\n"); } - else - { - idl_printIndent(indent_level); - idl_fileOutPrintf(idl_fileCur(), - "// Not the start of a rectangular array: initialization not required...\n"); - } - idl_printIndent(indent_level); - idl_fileOutPrintf(idl_fileCur(), "for (int i%d = 0; i%d < %d; i%d++) {\n", - dimension, dimension, arrLength, dimension); - indent_level++; - idl_CreateArrayMemberRead(collStartType, actualType, index, - dimension + 1, fieldName, bufName, csUserData); - indent_level--; - idl_printIndent(indent_level); - idl_fileOutPrintf(idl_fileCur(), "}\n"); - os_free(arrayBrackets); break; case OSPL_C_SEQUENCE: /* Handle sequences. */ @@ -2041,19 +2437,24 @@ idl_CreateArrayMemberRead( default: nextBufTypeSizeLen = 10 + 2 * 10 + 1; /* tmpl-size + 2 * MAX_INT + '\0'. */ nextBufTypeSize = os_malloc(nextBufTypeSizeLen); - snprintf(nextBufTypeSize, nextBufTypeSizeLen, "attr%uSeq%uSize", index, dimension); + snprintf(nextBufTypeSize, nextBufTypeSizeLen, "attr%uCol%uSize", index, dimension); idl_printIndent(indent_level); idl_fileOutPrintf(idl_fileCur(), "for (int i%d = 0; i%d < %s; i%d++) {\n", dimension, dimension, seqLengthName, dimension); indent_level++; if (actualTypeKind == M_COLLECTION && c_collectionTypeKind(actualType) != OSPL_C_STRING) { subType = c_typeActualType(c_collectionTypeSubType(actualType)); - if (c_collectionTypeKind(actualType) == OSPL_C_ARRAY && c_baseObjectKind(subType) == M_PRIMITIVE) { - os_free(arrayBrackets); - arrayBrackets = idl_CreateCSharpArrayIterationIndex(collStartType, dimension + 1); - idl_printIndent(indent_level); - idl_fileOutPrintf(idl_fileCur(), "Marshal.Copy(%s, to.%s%s, 0, %d);\n", - bufName, fieldName, arrayBrackets, c_collectionTypeMaxSize(actualType)); + if (c_collectionTypeKind(actualType) == OSPL_C_ARRAY) { + if (c_baseObjectKind(subType) == M_PRIMITIVE) { + os_free(arrayBrackets); + arrayBrackets = idl_CreateCSharpArrayIterationIndex(collStartType, dimension + 1); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "Marshal.Copy(%s, to.%s%s, 0, %d);\n", + bufName, fieldName, arrayBrackets, c_collectionTypeMaxSize(actualType)); + } else { + idl_CreateArrayMemberRead(collStartType, actualType, index, + dimension + 1, fieldName, bufName, TRUE, csUserData); + } } else { c_ulong seqBufNameSize = 10 + 2 * 10 + 1; /* tmpl-size + 2 * MAX_INT + '\0'. */ c_char *seqBufName = os_malloc(seqBufNameSize); @@ -2064,7 +2465,7 @@ idl_CreateArrayMemberRead( "IntPtr %s = Marshal.ReadIntPtr(%s);\n", seqBufName, bufName); } idl_CreateArrayMemberRead(collStartType, actualType, index, - dimension + 1, fieldName, seqBufName, csUserData); + dimension + 1, fieldName, seqBufName, isSeqOfArray, csUserData); os_free(seqBufName); } } else { @@ -2072,9 +2473,11 @@ idl_CreateArrayMemberRead( collStartType, actualType, actualTypeKind, index, dimension + 1, fieldName, bufName, csUserData); } - idl_printIndent(indent_level); - idl_fileOutPrintf(idl_fileCur(), - "%s = new IntPtr(%s.ToInt64() + %s);\n", bufName, bufName, nextBufTypeSize); + if (actualTypeKind != M_COLLECTION || c_collectionTypeKind(actualType) != OSPL_C_ARRAY) { + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), + "%s = new IntPtr(%s.ToInt64() + %s);\n", bufName, bufName, nextBufTypeSize); + } indent_level--; idl_printIndent(indent_level); idl_fileOutPrintf(idl_fileCur(), "}\n"); @@ -2102,12 +2505,12 @@ idl_CreateStructMemberRead( c_type memberType, const char *memberName, c_ulong index, - SACSSplDcpsUserData *csUserData) + SACSTypeUserData *csUserData) { - c_ulong bufNameLength; + os_size_t bufNameLength; c_char *bufName = NULL; c_bool isPredefined = FALSE; - c_char *memberTypeName = idl_scopeStackFromCType(memberType); + c_char *memberTypeName = idl_CsharpScopeStackFromCType(memberType, FALSE, FALSE, TRUE); if (idl_isPredefined(memberTypeName)) { isPredefined = TRUE; @@ -2117,7 +2520,7 @@ idl_CreateStructMemberRead( while (c_baseObjectKind(memberType) == M_TYPEDEF && !isPredefined) { os_free(memberTypeName); memberType = c_typeDef(memberType)->alias; - memberTypeName = idl_scopeStackFromCType(memberType); + memberTypeName = idl_CsharpScopeStackFromCType(memberType, csUserData->customPSM, FALSE, TRUE); if (idl_isPredefined(memberTypeName)) { isPredefined = TRUE; } @@ -2126,6 +2529,7 @@ idl_CreateStructMemberRead( switch(c_baseObjectKind(memberType)) { case M_STRUCTURE: + case M_UNION: if (isPredefined) /* Predefined types can use specialized Read operations. */ { @@ -2136,16 +2540,15 @@ idl_CreateStructMemberRead( else /* Other types should use their corresponding Marshaler. */ { - /* Get the CSharp specific name of the member type. */ - c_char *prevTypeName = memberTypeName; - memberTypeName = idl_CsharpId(prevTypeName, csUserData->customPSM, FALSE); - os_free(prevTypeName); + /* Get the Database specific name of the member type. */ + c_char *dbTypeName = idl_CsharpScopeStackFromCType(memberType, csUserData->customPSM, TRUE, TRUE); /* Invoke the Marshaler. */ idl_printIndent(indent_level); idl_fileOutPrintf(idl_fileCur(), "%sMarshaler.CopyOut(ref from.%s, ref to.%s);\n", - memberTypeName, memberName, memberName); + dbTypeName, memberName, memberName); + os_free(dbTypeName); } break; case M_ENUMERATION: @@ -2190,8 +2593,12 @@ idl_CreateStructMemberRead( "to.%s = ReadString(from.%s);\n", memberName, memberName); break; case OSPL_C_ARRAY: + bufNameLength = 5 + strlen(memberName) + 1; /* "from." + memberName + '\0'. */ + bufName = os_malloc(bufNameLength); + snprintf(bufName, bufNameLength, "from.%s", memberName); idl_CreateArrayMemberRead( - memberType, memberType, index, 0, memberName, memberName, csUserData); + memberType, memberType, index, 0, memberName, bufName, FALSE, csUserData); + os_free(bufName); break; case OSPL_C_SEQUENCE: bufNameLength = 10 + 2 * 10 + 1; /* tmpl-size + 2 * MAX_INT + '\0'. */ @@ -2203,7 +2610,7 @@ idl_CreateStructMemberRead( "IntPtr %s = from.%s;\n", bufName, memberName); idl_CreateArrayMemberRead( - memberType, memberType, index, 0, memberName, bufName, csUserData); + memberType, memberType, index, 0, memberName, bufName, FALSE, csUserData); os_free(bufName); break; @@ -2222,8 +2629,9 @@ idl_CreateStructMemberRead( static void idl_CreateCopyOut( c_type structType, - const c_char *structName, - SACSSplDcpsUserData *csUserData) + const c_char *structDBName, + const c_char *fullyScopedName, + SACSTypeUserData *csUserData) { c_ulong i, nrMembers = c_structureMemberCount((c_structure) structType); @@ -2236,12 +2644,12 @@ idl_CreateCopyOut( /* Generate a body that retrieves the C# object and invokes the appropriate CopyOut. */ idl_printIndent(indent_level); - idl_fileOutPrintf(idl_fileCur(), "__%s nativeImg = (__%s) Marshal.PtrToStructure(from, typeof(__%s));\n", - structName, structName, structName); + idl_fileOutPrintf(idl_fileCur(), "%s nativeImg = (%s) Marshal.PtrToStructure(from, typeof(%s));\n", + structDBName, structDBName, structDBName); idl_printIndent(indent_level); idl_fileOutPrintf(idl_fileCur(), "GCHandle tmpGCHandleTo = GCHandle.FromIntPtr(to);\n"); idl_printIndent(indent_level); - idl_fileOutPrintf(idl_fileCur(), "%s toObj = tmpGCHandleTo.Target as %s;\n", structName, structName); + idl_fileOutPrintf(idl_fileCur(), "%s toObj = tmpGCHandleTo.Target as %s;\n", fullyScopedName, fullyScopedName); idl_printIndent(indent_level); idl_fileOutPrintf(idl_fileCur(), "CopyOut(ref nativeImg, ref toObj);\n"); idl_printIndent(indent_level); @@ -2254,15 +2662,15 @@ idl_CreateCopyOut( /* Open the 2nd CopyOut operation and increase the indent. */ idl_printIndent(indent_level); - idl_fileOutPrintf(idl_fileCur(), "public override void CopyOut(System.IntPtr from, ref %s to)\n", structName); + idl_fileOutPrintf(idl_fileCur(), "public override void CopyOut(System.IntPtr from, ref %s to)\n", fullyScopedName); idl_printIndent(indent_level); idl_fileOutPrintf(idl_fileCur(), "{\n"); indent_level++; /* Generate a body that retrieves the C# object and invokes the appropriate CopyOut. */ idl_printIndent(indent_level); - idl_fileOutPrintf(idl_fileCur(), "__%s nativeImg = (__%s) Marshal.PtrToStructure(from, typeof(__%s));\n", - structName, structName, structName); + idl_fileOutPrintf(idl_fileCur(), "%s nativeImg = (%s) Marshal.PtrToStructure(from, typeof(%s));\n", + structDBName, structDBName, structDBName); idl_printIndent(indent_level); idl_fileOutPrintf(idl_fileCur(), "CopyOut(ref nativeImg, ref to);\n"); @@ -2273,15 +2681,15 @@ idl_CreateCopyOut( /* Open the 3rd CopyOut operation and increase the indent. */ idl_printIndent(indent_level); - idl_fileOutPrintf(idl_fileCur(), "public static void StaticCopyOut(System.IntPtr from, ref %s to)\n", structName); + idl_fileOutPrintf(idl_fileCur(), "public static void StaticCopyOut(System.IntPtr from, ref %s to)\n", fullyScopedName); idl_printIndent(indent_level); idl_fileOutPrintf(idl_fileCur(), "{\n"); indent_level++; /* Generate a body that retrieves the C# object and invokes the appropriate CopyOut. */ idl_printIndent(indent_level); - idl_fileOutPrintf(idl_fileCur(), "__%s nativeImg = (__%s) Marshal.PtrToStructure(from, typeof(__%s));\n", - structName, structName, structName); + idl_fileOutPrintf(idl_fileCur(), "%s nativeImg = (%s) Marshal.PtrToStructure(from, typeof(%s));\n", + structDBName, structDBName, structDBName); idl_printIndent(indent_level); idl_fileOutPrintf(idl_fileCur(), "CopyOut(ref nativeImg, ref to);\n"); @@ -2292,7 +2700,7 @@ idl_CreateCopyOut( /* Open the 4th CopyOut operation and increase the indent. */ idl_printIndent(indent_level); - idl_fileOutPrintf(idl_fileCur(), "public static void CopyOut(ref __%s from, ref %s to)\n", structName, structName); + idl_fileOutPrintf(idl_fileCur(), "public static void CopyOut(ref %s from, ref %s to)\n", structDBName, fullyScopedName); idl_printIndent(indent_level); idl_fileOutPrintf(idl_fileCur(), "{\n"); indent_level++; @@ -2302,7 +2710,7 @@ idl_CreateCopyOut( idl_fileOutPrintf(idl_fileCur(), "if (to == null) {\n"); indent_level++; idl_printIndent(indent_level); - idl_fileOutPrintf(idl_fileCur(), "to = new %s();\n", structName); + idl_fileOutPrintf(idl_fileCur(), "to = new %s();\n", fullyScopedName); indent_level--; idl_printIndent(indent_level); idl_fileOutPrintf(idl_fileCur(), "}\n"); @@ -2329,20 +2737,21 @@ idl_CreateCopyOut( static void idl_generateMarshaler ( idl_typeStruct typeSpec, - const c_char *structName, - SACSSplDcpsUserData *csUserData) + const c_char *structDBName, + const c_char *fullyScopedName, + SACSTypeUserData *csUserData) { /* Get the meta-data of this datatype from the database. */ c_type structType = idl_typeSpecDef(idl_typeSpec(typeSpec)); /* Generate the C# code that opens a sealed class. */ idl_printIndent(indent_level); - idl_fileOutPrintf(idl_fileCur(), "#region %sMarshaler\n", structName); + idl_fileOutPrintf(idl_fileCur(), "#region %sMarshaler\n", structDBName); idl_printIndent(indent_level); idl_fileOutPrintf( idl_fileCur(), "public sealed class %sMarshaler : DDS.OpenSplice.CustomMarshalers.FooDatabaseMarshaler<%s>\n", - structName, structName); + structDBName, fullyScopedName); idl_printIndent(indent_level); idl_fileOutPrintf(idl_fileCur(), "{\n"); @@ -2351,10 +2760,10 @@ idl_generateMarshaler ( /* Create the constructor of the Marshaler. */ idl_determineFullyScopedName(structType); - idl_CreateAttributes(structType, structName, csUserData); - idl_CreateInitEmbeddedMarshalers(structType, structName, csUserData); - idl_CreateCopyIn(structType, structName, csUserData); - idl_CreateCopyOut(structType, structName, csUserData); + idl_CreateAttributes(structType, structDBName, csUserData); + idl_CreateInitEmbeddedMarshalers(structType, structDBName); + idl_CreateCopyIn(structType, structDBName, fullyScopedName, csUserData); + idl_CreateCopyOut(structType, structDBName, fullyScopedName, csUserData); /* Decrease the indentation level and generate the closing bracket. */ indent_level--; @@ -2364,3 +2773,2451 @@ idl_generateMarshaler ( idl_fileOutPrintf (idl_fileCur(), "#endregion\n\n"); } + +/** @brief Generate a string representaion the literal value of a label + * in metadata terms. + * + * @param labelVal Specifies the kind and the value of the label + * @return String representing the image of \b labelVal + */ +static void +idl_printCaseLabel ( + c_literal label) +{ + switch (label->value.kind) { + case V_CHAR: + idl_fileOutPrintf(idl_fileCur(), "case %u:\n", label->value.is.Char); + break; + case V_BOOLEAN: + idl_fileOutPrintf(idl_fileCur(), "case %d:\n", label->value.is.Boolean); + break; + default: + { + char *value = c_valueImage(label->value); + idl_fileOutPrintf(idl_fileCur(), "case %s:\n", value); + os_free(value); + } + break; + } +} + + +static char * +idl_getCSharpLabelValue ( + c_literal label) +{ + char buf[16]; + char *value; + + switch (label->value.kind) { + case V_CHAR: + snprintf(buf, sizeof(buf), "'%c'", label->value.is.Char); + value = os_strdup(buf); + break; + case V_BOOLEAN: + snprintf(buf, sizeof(buf), "%s", label->value.is.Boolean ? "true" : "false"); + value = os_strdup(buf); + break; + default: + value = c_valueImage(label->value); + break; + } + return value; +} + + +/** @brief Return a C# typename corresponging to a case field the IDL type specification + * + * @param typeSpec IDL type specification + * @param customPSM Use custom PSM or not + */ +static char * +idl_unionCaseTypeFromTypeSpec( + idl_typeSpec typeSpec, + c_bool customPSM) +{ + char typeName[512]; + char *tname; + c_bool isPredefined = FALSE; + + tname = idl_CsharpTypeFromTypeSpec(typeSpec, customPSM); + + /* Dereference possible typedefs first. */ + while (idl_typeSpecType(typeSpec) == idl_ttypedef && !isPredefined) { + if (!idl_isPredefined(tname)) { + typeSpec = idl_typeDefRefered(idl_typeDef(typeSpec)); + os_free (tname); + tname = idl_CsharpTypeFromTypeSpec(typeSpec, customPSM); + } else { + isPredefined = TRUE; + } + } + + if (idl_typeSpecType(typeSpec) == idl_tbasic) { + snprintf(typeName, sizeof(typeName), "%s", tname); + } else if (idl_typeSpecType(typeSpec) == idl_tseq) { + char *str_no_idx = idl_sequenceCsharpIndexString(typeSpec, SACS_EXCLUDE_INDEXES, NULL); + assert (str_no_idx); + snprintf (typeName, sizeof(typeName), "%s%s", tname, str_no_idx); + os_free(str_no_idx); + } else if (idl_typeSpecType(typeSpec) == idl_tarray) { + char *str_no_idx = idl_arrayCsharpIndexString(typeSpec, SACS_EXCLUDE_INDEXES); + assert (str_no_idx); + snprintf(typeName, sizeof(typeName), "%s%s", tname, str_no_idx); + os_free(str_no_idx); + } else if (idl_typeSpecType(typeSpec) == idl_ttypedef) { + /* This state should only be reachable for predefined types. */ + assert(isPredefined); + snprintf(typeName, sizeof(typeName), "%s", tname); + } else { + if ((idl_typeSpecType(typeSpec) == idl_tstruct) || + (idl_typeSpecType (typeSpec) == idl_tunion) || + (idl_typeSpecType (typeSpec) == idl_tenum)) { + snprintf(typeName, sizeof(typeName), "%s", tname); + } else { + printf ("idl_unionCaseTypeFromTypeSpec: Unexpected type %d\n", + idl_typeSpecType(typeSpec)); + } + } + + os_free(tname); + + return os_strdup(typeName); +} + +static c_char * +idl_CsharpTypeFromCType( + c_type ctype, + c_bool customPSM) +{ + c_char *tName; + idl_typeSpec typeSpec = idl_makeTypeSpec(ctype); + tName = idl_unionCaseTypeFromTypeSpec(typeSpec, customPSM); + idl_freeTypeSpec(typeSpec); + + return tName; +} + + +static void +idl_UnionUseRecycledArray( + idl_typeSpec typeSpec, + c_type currentType, + c_type subType, + const c_char *dest, + const c_char *seqLengthName, + const c_char *arrayBrackets, + const c_char *arrayIndex, + const c_char *arrayCtor) +{ + c_char *arrayNoIndex; + + switch (c_collectionTypeKind(currentType)) { + case OSPL_C_SEQUENCE: + arrayNoIndex = idl_sequenceCsharpIndexString( + typeSpec, SACS_EXCLUDE_INDEXES, seqLengthName); + break; + case OSPL_C_ARRAY: + arrayNoIndex = idl_arrayCsharpIndexString( + typeSpec, SACS_EXCLUDE_INDEXES); + break; + default: + assert(FALSE); /* Unsupported collection type. */ + arrayNoIndex = NULL; + break; + } + + if (arrayNoIndex != NULL) { + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "%s%s target = new %s%s;\n", + arrayCtor, arrayNoIndex, arrayCtor, arrayIndex); + if (c_collectionTypeKind(currentType) == OSPL_C_ARRAY && + c_baseObjectKind(subType) == M_COLLECTION && + c_collectionTypeKind(subType) == OSPL_C_ARRAY) + { + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "// Rectangular array: recycling not yet possible...\n"); + } + else + { + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "initObjectSeq(%s%s, target);\n", + dest, arrayBrackets); + } + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "%s%s = target;\n", + dest, arrayBrackets); + os_free(arrayNoIndex); + } +} + +static void +idl_UnionCreateArrayInitialization( + c_type currentType, + const c_char *dstName, + const c_char *seqLengthName, + const c_char *arrayBrackets, + SACSTypeUserData *csUserData) +{ + c_char *arrayIndex = NULL, *arrayCtor; + c_type subType = c_typeActualType(c_collectionTypeSubType(currentType)); + idl_typeSpec typeSpec = idl_makeTypeCollection(c_collectionType(currentType)); + c_char *subTypeName; + + /* Resolve the typename of the current collection. */ + arrayCtor = idl_CsharpTypeFromTypeSpec(typeSpec, csUserData->customPSM); + + /* Resolve the index representation for the current collection. */ + switch (c_collectionTypeKind(currentType)) + { + case OSPL_C_SEQUENCE: + arrayIndex = idl_sequenceCsharpIndexString( + typeSpec, SACS_INCLUDE_INDEXES, seqLengthName); + break; + case OSPL_C_ARRAY: + arrayIndex = idl_arrayCsharpIndexString(typeSpec, SACS_INCLUDE_INDEXES); + break; + default: + /* Unsupported collection type. */ + assert(FALSE); + break; + } + + /* The initialization code for the current collection depends on its subtype. */ + switch (c_baseObjectKind(subType)) + { + /* Primitive kind, no need to recycle elements. */ + case M_ENUMERATION: + case M_PRIMITIVE: + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "%s%s = new %s%s;\n", + dstName, arrayBrackets, arrayCtor, arrayIndex); + break; + /* Object kind, try to recycle elements as much as possible. */ + case M_STRUCTURE: + case M_UNION: + subTypeName = idl_scopeStackFromCType(subType); + if (idl_isPredefined(subTypeName)) { + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "%s%s = new %s%s;\n", + dstName, arrayBrackets, arrayCtor, arrayIndex); + } else { + idl_UnionUseRecycledArray(typeSpec, currentType, subType, dstName, seqLengthName, arrayBrackets, arrayIndex, arrayCtor); + } + os_free(subTypeName); + break; + case M_COLLECTION: + idl_UnionUseRecycledArray(typeSpec, currentType, subType, dstName, seqLengthName, arrayBrackets, arrayIndex, arrayCtor); + break; + default: + /* Unsupported collection type. */ + assert(FALSE); + break; + } + os_free(arrayIndex); + os_free(arrayCtor); + idl_freeTypeSpec(typeSpec); +} + +static void +idl_generateUnionArrayStatusCheck( + c_type collStartType, + c_type collType, + c_type *eventualElementType, + c_ulong dimension, + const c_char *dstName, + SACSTypeUserData *csUserData) +{ + c_ulong i; + c_char *arrayBrackets = idl_CreateCSharpArrayIterationIndex(collStartType, dimension); + /* Check if this dimension is part of a prior rectangular array by checking + * whether its parent is also an array. + */ + c_type parentType = collStartType; + for (i = 1; i < dimension; i++) + { + parentType = c_typeActualType(c_collectionTypeSubType(parentType)); + } + + if (parentType == collType || + (c_baseObjectKind(parentType) != M_COLLECTION || + c_collectionTypeKind(parentType) != OSPL_C_ARRAY)) + { + /* If no prior rectangular dimensions, then check the current dimensions. */ + c_ulong curDim; + os_size_t dimensionCheckSize = 15 + strlen(dstName) + strlen (arrayBrackets) + 1; + c_char *dimensionCheck = os_malloc(dimensionCheckSize); + snprintf(dimensionCheck, dimensionCheckSize, "%s%s == null", dstName, arrayBrackets); + *eventualElementType = c_typeActualType(collType); + for (i = 0; c_baseObjectKind(*eventualElementType) == M_COLLECTION && + c_collectionTypeKind(*eventualElementType) == OSPL_C_ARRAY; i++) + { + c_char *prevdimensionCheck = dimensionCheck; + curDim = c_collectionTypeMaxSize(*eventualElementType); + dimensionCheckSize = strlen(prevdimensionCheck) + 26 + strlen(dstName) + + strlen(arrayBrackets) + 2 * 10 /* MAX_INT */ + 1; + dimensionCheck = os_malloc(dimensionCheckSize); + snprintf(dimensionCheck, dimensionCheckSize, + "%s || %s%s.GetLength(%d) != %d", + prevdimensionCheck, dstName, arrayBrackets, i, curDim); + os_free(prevdimensionCheck); + *eventualElementType = c_typeActualType(c_collectionTypeSubType(*eventualElementType)); + } + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "if (%s) {\n", dimensionCheck); + indent_level++; + idl_UnionCreateArrayInitialization(collType, dstName, "", arrayBrackets, csUserData); + indent_level--; + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "}\n"); + os_free(dimensionCheck); + } else { + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), + "// Not the start of a rectangular array: initialization not required...\n"); + } + os_free(arrayBrackets); +} + +static void +idl_UnionCreateArrayMemberWriteInnerLoopBody( + c_type collStartType, + c_type collType, + c_metaKind collKind, + c_ulong index, + c_ulong dimension, + const c_char *fieldName, + const c_char *srcName, + const c_char *dstName) +{ + c_ulong maxSize; + c_char *cSharpArrayBrackets = idl_CreateCSharpArrayIterationIndex(collStartType, dimension); + c_char *databaseArrayBrackets = idl_CreateDatabaseArrayIterationIndex(collStartType, dimension); + c_char *collTypeName; + + OS_UNUSED_ARG(fieldName); + + switch(collKind) + { + case M_STRUCTURE: + case M_UNION: + collTypeName = idl_scopeStackFromCType(collType); + + idl_printIndent(indent_level); + if (idl_isPredefined((collTypeName))) { + idl_fileOutPrintf(idl_fileCur(), "Write(%s, 0, %s%s);\n", dstName, srcName, cSharpArrayBrackets); + } else { + idl_fileOutPrintf(idl_fileCur(), "{\n"); + idl_printIndent(indent_level + 1); + idl_fileOutPrintf(idl_fileCur(), + "V_COPYIN_RESULT result = attr%dMarshaler.CopyIn(typePtr, %s%s, %s);\n", + index, srcName, cSharpArrayBrackets, dstName); + idl_printIndent(indent_level + 1); + idl_fileOutPrintf(idl_fileCur(), + "if (result != V_COPYIN_RESULT.OK) return result;\n"); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "}\n"); + } + os_free(collTypeName); + break; + case M_ENUMERATION: + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "Marshal.WriteInt32(%s, (int) %s%s);\n", dstName, srcName, cSharpArrayBrackets); + break; + case M_PRIMITIVE: + /* Generate code to handle a primitive. */ + idl_printIndent(indent_level); + switch (c_primitiveKind(collType)) + { + case P_CHAR: + idl_fileOutPrintf(idl_fileCur(),"Write(%s, 0, (byte) (%s%s));\n", + dstName, srcName, cSharpArrayBrackets); + break; + case P_BOOLEAN: + idl_fileOutPrintf(idl_fileCur(),"Write(%s, 0, (%s%s));\n", + dstName, srcName, cSharpArrayBrackets); + break; + case P_OCTET: + case P_SHORT: case P_USHORT: + case P_LONG: case P_ULONG: + case P_LONGLONG: case P_ULONGLONG: + case P_FLOAT: case P_DOUBLE: + idl_fileOutPrintf(idl_fileCur(), + "Write(%s, 0, %s%s);\n", + dstName, srcName, cSharpArrayBrackets); + break; + default: + assert(0); + break; + } + break; + case M_COLLECTION: + /* Assert that this collection is always of type string!! */ + assert(c_collectionTypeKind(collType) == OSPL_C_STRING); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), + "if (%s%s == null) return V_COPYIN_RESULT.INVALID;\n", srcName, cSharpArrayBrackets); + maxSize = c_collectionTypeMaxSize(collType); + /* Check for bounds if a maximum bound was specified. */ + if (maxSize > 0) + { + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), + "if (%s%s.Length > %u) return V_COPYIN_RESULT.INVALID;\n", srcName, cSharpArrayBrackets, maxSize); + } + else + { + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "// Unbounded string: bounds check not required...\n"); + } + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "if (!Write(c.getBase(typePtr), %s, 0, ref %s%s)) return V_COPYIN_RESULT.OUT_OF_MEMORY;\n", + dstName, srcName, cSharpArrayBrackets); + break; + default: + /* Unsupported array type. */ + assert(FALSE); + break; + } + + os_free(databaseArrayBrackets); + os_free(cSharpArrayBrackets); +} + +static void +idl_UnionCreateSequenceMemberWriteInnerLoopBody( + c_type collStartType, + c_type collType, + c_metaKind collKind, + c_ulong index, + c_ulong dimension, + const c_char *fieldName, + const c_char *srcName, + const c_char *dstName) +{ + c_ulong maxSize; + c_char *cSharpArrayBrackets = idl_CreateCSharpArrayIterationIndex(collStartType, dimension); + c_char *collTypeName; + + OS_UNUSED_ARG(fieldName); + + switch(collKind) + { + case M_STRUCTURE: + case M_UNION: + collTypeName = idl_scopeStackFromCType(collType); + idl_printIndent(indent_level); + if (idl_isPredefined((collTypeName))) { + idl_fileOutPrintf(idl_fileCur(), + "Write(%s, 0, %s%s);\n", dstName, srcName, cSharpArrayBrackets); + } else { + idl_fileOutPrintf(idl_fileCur(), "{\n"); + idl_printIndent(indent_level + 1); + idl_fileOutPrintf(idl_fileCur(), + "V_COPYIN_RESULT result = attr%dMarshaler.CopyIn(typePtr, %s%s, %s);\n", + index, srcName, cSharpArrayBrackets, dstName); + idl_printIndent(indent_level + 1); + idl_fileOutPrintf(idl_fileCur(), + "if (result != V_COPYIN_RESULT.OK) return result;\n"); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "}\n"); + } + os_free(collTypeName); + break; + case M_ENUMERATION: + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), + "Marshal.WriteInt32(%s, (int) %s%s);\n", dstName, srcName, cSharpArrayBrackets); + break; + case M_PRIMITIVE: + switch(c_primitiveKind(collType)) + { + case P_BOOLEAN: + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), + "Marshal.WriteByte(%s, from.%s()%s ? (byte) 1 : (byte) 0);\n", + dstName, fieldName, cSharpArrayBrackets); + break; + case P_CHAR: + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), + "Marshal.WriteByte(%s, (byte) from.%s()%s);\n", + dstName, fieldName, cSharpArrayBrackets); + break; + /* Other primitives should have been handled by the caller already, using Marshal.Copy. */ + default: + assert(0); + break; + } + break; + case M_COLLECTION: + /* Assert that this collection is always of type string!! */ + assert(c_collectionTypeKind(collType) == OSPL_C_STRING); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), + "if (%s%s == null) return V_COPYIN_RESULT.INVALID;\n", srcName, cSharpArrayBrackets); + maxSize = c_collectionTypeMaxSize(collType); + /* Check for bounds if a maximum bound was specified. */ + if (maxSize > 0) { + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), + "if (%s%s.Length > %u) return V_COPYIN_RESULT.INVALID;\n", srcName, cSharpArrayBrackets, maxSize); + } else { + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "// Unbounded string: bounds check not required...\n"); + } + + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "if (!Write(c.getBase(typePtr), %s, 0, ref %s%s)) return V_COPYIN_RESULT.OUT_OF_MEMORY;\n", + dstName, srcName, cSharpArrayBrackets); + + break; + default: + /* Unsupported array type. */ + assert(FALSE); + break; + } + + os_free(cSharpArrayBrackets); +} + +static void +idl_UnionCreateArrayMemberWriteInner( + c_type collStartType, + c_type collType, + c_ulong index, + c_ulong dimension, + const c_char *idlFieldName, + const c_char *csFieldName, + const c_char *srcName, + const c_char *dstName) +{ + c_ulong arrLength, seqMaxLength; + c_char *seqLengthName, *seqTypeName, *nextBufTypeSize, *iterationIndex; + c_char *curBufName, *elemSize; + c_type subType, actualType, arrElemType; + c_metaKind actualTypeKind; + + c_metaKind collKind = c_baseObjectKind(collType); + switch(collKind) + { + case M_PRIMITIVE: + case M_STRUCTURE: + case M_ENUMERATION: + case M_UNION: + idl_UnionCreateArrayMemberWriteInnerLoopBody( + collStartType, collType, collKind, index, dimension, csFieldName, srcName, dstName); + break; + case M_COLLECTION: + /* Handle Collection type. */ + switch (c_collectionTypeKind(collType)) + { + case OSPL_C_STRING: + /* Handle strings. */ + idl_UnionCreateArrayMemberWriteInnerLoopBody( + collStartType, collType, collKind, index, dimension, csFieldName, srcName, dstName); + break; + case OSPL_C_ARRAY: + /* Handle arrays. */ + arrLength = c_collectionTypeMaxSize(collType); + subType = c_collectionTypeSubType(collType); + actualType = c_typeActualType(subType); + arrElemType = idl_getArrayElementType(collType); + + if (c_baseObjectKind(arrElemType) == M_PRIMITIVE && + c_primitiveKind(arrElemType) != P_BOOLEAN && c_primitiveKind(arrElemType)!= P_CHAR) { + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), + "Marshal.Copy(%s, 0, %s, %d);\n", srcName, dstName, c_collectionTypeMaxSize(collType)); + } else { + + curBufName = idl_genAttrArrVarName("Buf", index, dimension); + elemSize = idl_genAttrColVarName("Size", index, dimension); + + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "IntPtr %s = new IntPtr(%s.ToInt64());\n", curBufName, dstName); + + if (c_baseObjectKind(arrElemType) == M_COLLECTION && c_collectionTypeKind(arrElemType) == OSPL_C_SEQUENCE) { + c_char *arrTypeName = idl_genAttrColVarName("Type", index, dimension); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "if (%s == IntPtr.Zero) {\n", arrTypeName); + indent_level++; + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), + "IntPtr memberOwnerType = DDS.OpenSplice.Database.c.resolve(c.getBase(typePtr), fullyScopedName);\n"); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), + "IntPtr specifier = DDS.OpenSplice.Database.c.metaResolveSpecifier(memberOwnerType, \"%s\");\n", + idlFieldName); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), + "IntPtr specifierType = DDS.OpenSplice.Database.c.specifierType(specifier);\n"); + + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "%s = DDS.OpenSplice.Database.c.typeActualType(specifierType);\n", arrTypeName); + indent_level--; + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "}\n"); + os_free(arrTypeName); + } + + /* Open a for loop to walk over the current dimension and increase the indent. */ + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "for (int i%d = 0; i%d < %d; i%d++) {\n", + dimension, dimension, arrLength, dimension); + indent_level++; + /* Generate the the body to process the next dimension. */ + idl_UnionCreateArrayMemberWriteInner( + collStartType, actualType, index, dimension + 1, idlFieldName, csFieldName, srcName, curBufName); + idl_printIndent(indent_level); + + idl_fileOutPrintf(idl_fileCur(), "%s = new IntPtr(%s.ToInt64() + %s);\n", + curBufName, curBufName, elemSize); + /* Close the for loop and decrease the indent level back to its original. */ + indent_level--; + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "}\n"); + os_free(curBufName); + os_free(elemSize); + } + break; + case OSPL_C_SEQUENCE: + /* Handle sequences. */ + subType = c_collectionTypeSubType(collType); + actualType = c_typeActualType(subType); + actualTypeKind = c_baseObjectKind(actualType); + + seqLengthName = idl_genAttrSeqVarName("Length", index, dimension); + seqTypeName = idl_genAttrColVarName("Type", index, dimension); + curBufName = idl_genAttrSeqVarName("Buf", index, dimension); + + seqMaxLength = c_collectionTypeMaxSize(collType); + iterationIndex = idl_CreateCSharpArrayIterationIndex(collStartType, dimension); + + /* Check whether the sequence is valid. */ + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "if (%s%s == null) return V_COPYIN_RESULT.INVALID;\n", + srcName, iterationIndex); + + /* Get its Length, and check it for validity. */ + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "int %s = %s%s.Length;\n", seqLengthName, srcName, iterationIndex); + if (seqMaxLength == 0) { + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "// Unbounded sequence: bounds check not required...\n"); + } else { + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "if (%s > %u) return V_COPYIN_RESULT.INVALID;\n", seqLengthName, seqMaxLength); + } + + /* Locate the database type-definition of the sequence. */ + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "if (%s == IntPtr.Zero) {\n", seqTypeName); + indent_level++; + idl_printIndent(indent_level); + if (dimension == 0) { + idl_fileOutPrintf(idl_fileCur(), + "IntPtr memberOwnerType = DDS.OpenSplice.Database.c.resolve(c.getBase(typePtr), fullyScopedName);\n"); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), + "IntPtr specifier = DDS.OpenSplice.Database.c.metaResolveSpecifier(memberOwnerType, \"%s\");\n", + idlFieldName); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), + "IntPtr specifierType = DDS.OpenSplice.Database.c.specifierType(specifier);\n"); + } else { + idl_fileOutPrintf(idl_fileCur(), + "DDS.OpenSplice.Database.c_collectionType colType = (DDS.OpenSplice.Database.c_collectionType) Marshal.PtrToStructure(\n"); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), + " attr%dCol%dType, typeof(DDS.OpenSplice.Database.c_collectionType));\n", index, dimension -1); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "IntPtr specifierType = colType.subType;\n"); + } + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), + "%s = DDS.OpenSplice.Database.c.typeActualType(specifierType);\n", + seqTypeName); + indent_level--; + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "}\n"); + + /* Allocate a matching array in the database. */ + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), + "IntPtr %s = DDS.OpenSplice.Database.c.newSequence(%s, %s);\n", + curBufName, seqTypeName, seqLengthName); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), + "if (%s == IntPtr.Zero) return V_COPYIN_RESULT.OUT_OF_MEMORY;\n", curBufName); + + switch(actualTypeKind) + { + case M_PRIMITIVE: + switch (c_primitiveKind(actualType)) + { + case P_USHORT: + case P_ULONG: + case P_ULONGLONG: + { + const char *signedCounterPart; + if (c_primitiveKind(actualType) == P_USHORT) { + signedCounterPart = "Int16"; + } else if (c_primitiveKind(actualType) == P_ULONG) { + signedCounterPart = "Int32"; + } else { + signedCounterPart = "Int64"; + } + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), + "Marshal.Copy((%s[]) (Array) %s%s, 0, %s, %s);\n", + signedCounterPart, srcName, iterationIndex, curBufName, seqLengthName); + break; + } + case P_SHORT: + case P_LONG: + case P_LONGLONG: + case P_FLOAT: + case P_DOUBLE: + case P_OCTET: + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), + "Marshal.Copy(%s%s, 0, %s, %s);\n", srcName, iterationIndex, curBufName, seqLengthName); + break; + default: + /* Intentionally fall through to the default handler. */ + break; + } + if (c_primitiveKind(actualType) != P_BOOLEAN && c_primitiveKind(actualType) != P_CHAR) { + if (dimension > 0) { + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "Marshal.WriteIntPtr(%s, %s);\n", dstName, curBufName); + } + break; + } + default: + if (dimension > 0) { + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "Marshal.WriteIntPtr(%s, %s);\n", dstName, curBufName); + } + nextBufTypeSize = idl_genAttrColVarName("Size", index, dimension); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "for (int i%u = 0; i%u < %s; i%u++) {\n", + dimension, dimension, seqLengthName, dimension); + indent_level++; + if (actualTypeKind == M_COLLECTION) { + if (c_collectionTypeKind(actualType) != OSPL_C_STRING) { + subType = c_typeActualType(c_collectionTypeSubType(actualType)); + if (c_collectionTypeKind(actualType) == OSPL_C_ARRAY && c_baseObjectKind(subType) == M_PRIMITIVE) { + os_free(iterationIndex); + iterationIndex = idl_CreateCSharpArrayIterationIndex(collStartType, dimension + 1); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "Marshal.Copy(%s%s, 0, %s, %d);\n", + srcName, iterationIndex, dstName, c_collectionTypeMaxSize(actualType)); + } else { + idl_UnionCreateArrayMemberWriteInner(collStartType, actualType, index, + dimension + 1, idlFieldName, csFieldName, srcName, curBufName); + } + } else { + idl_UnionCreateArrayMemberWriteInner(collStartType, actualType, index, + dimension + 1, idlFieldName, csFieldName, srcName, curBufName); + } + } else { + idl_UnionCreateSequenceMemberWriteInnerLoopBody( + collStartType, actualType, actualTypeKind, index, dimension + 1, + csFieldName, srcName, curBufName); + } + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), + "%s = new IntPtr(%s.ToInt64() + %s);\n", curBufName, curBufName, nextBufTypeSize); + indent_level--; + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "}\n"); + os_free(nextBufTypeSize); + break; + } + + os_free(iterationIndex); + os_free(seqTypeName); + os_free(seqLengthName); + os_free(curBufName); + break; + default: + /* Unsupported Collection type. */ + assert(FALSE); + break; + } + break; + default: + /* Unsupported Array type. */ + assert(FALSE); + break; + } +} + + +static void +idl_UnionCreateArrayMemberWrite( + c_type collStartType, + c_type collType, + c_ulong index, + c_ulong dimension, + const c_char *idlFieldName, + const c_char *csFieldName, + const c_char *srcName, + const c_char *dstName) +{ + c_ulong arrLength; + c_type subType, actualType, arrElemType; + + /* Handle arrays. */ + arrLength = c_collectionTypeMaxSize(collType); + subType = c_collectionTypeSubType(collType); + actualType = c_typeActualType(subType); + arrElemType = idl_getArrayElementType(collType); + + if (c_baseObjectKind(arrElemType) == M_PRIMITIVE && + c_primitiveKind(arrElemType) != P_BOOLEAN && c_primitiveKind(arrElemType)!= P_CHAR) { + c_char *primName = idl_genTypeNameFromCType(arrElemType); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "System.Buffer.BlockCopy(%s, 0, %s, 0, (%"PA_PRIu64" * Marshal.SizeOf(typeof(%s))));\n", + srcName, dstName, idl_determineDatabaseFlatArraySize(collType), primName); + os_free(primName); + } else { + c_char *curBufName = idl_genAttrArrVarName("Buf", index, dimension); + c_char *elemSize = idl_genAttrColVarName("Size", index, dimension); + c_char *handleName = idl_genAttrArrVarName("Handle", index, dimension); + + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "GCHandle %s = GCHandle.Alloc(%s, GCHandleType.Pinned);\n", handleName, dstName); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "IntPtr %s = %s.AddrOfPinnedObject();\n", curBufName, handleName); + + if (c_baseObjectKind(arrElemType) == M_COLLECTION && c_collectionTypeKind(arrElemType) == OSPL_C_SEQUENCE) { + c_char *arrTypeName = idl_genAttrColVarName("Type", index, dimension); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "if (%s == IntPtr.Zero) {\n", arrTypeName); + indent_level++; + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), + "IntPtr memberOwnerType = DDS.OpenSplice.Database.c.resolve(c.getBase(typePtr), fullyScopedName);\n"); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), + "IntPtr specifier = DDS.OpenSplice.Database.c.metaResolveSpecifier(memberOwnerType, \"%s\");\n", + idlFieldName); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), + "IntPtr specifierType = DDS.OpenSplice.Database.c.specifierType(specifier);\n"); + + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "%s = DDS.OpenSplice.Database.c.typeActualType(specifierType);\n", arrTypeName); + indent_level--; + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "}\n"); + os_free(arrTypeName); + } + + /* Open a for loop to walk over the current dimension and increase the indent. */ + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "for (int i%d = 0; i%d < %d; i%d++) {\n", + dimension, dimension, arrLength, dimension); + indent_level++; + /* Generate the the body to process the next dimension. */ + idl_UnionCreateArrayMemberWriteInner(collStartType, actualType, index, dimension + 1, idlFieldName, csFieldName, srcName, curBufName); + + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "%s = new IntPtr(%s.ToInt64() + %s);\n", + curBufName, curBufName, elemSize); + /* Close the for loop and decrease the indent level back to its original. */ + + indent_level--; + + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "}\n"); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "%s.Free();\n", handleName); + os_free(curBufName); + os_free(elemSize); + os_free(handleName); + } +} + + +static void +idl_UnionCreateSequenceMemberWrite( + c_type collStartType, + c_type collType, + c_ulong index, + c_ulong dimension, + const c_char *idlFieldName, + const c_char *csFieldName, + const c_char *srcName, + const c_char *dstName) +{ + c_ulong seqMaxLength; + c_char *seqLengthName, *seqTypeName, *nextBufTypeSize, *iterationIndex; + c_char *curBufName; + c_type subType, actualType; + c_metaKind actualTypeKind; + + /* Handle sequences. */ + subType = c_collectionTypeSubType(collType); + actualType = c_typeActualType(subType); + actualTypeKind = c_baseObjectKind(actualType); + + seqLengthName = idl_genAttrSeqVarName("Length", index, dimension); + seqTypeName = idl_genAttrColVarName("Type", index, dimension); + curBufName = idl_genAttrSeqVarName("Buf", index, dimension); + + seqMaxLength = c_collectionTypeMaxSize(collType); + iterationIndex = idl_CreateCSharpArrayIterationIndex(collStartType, dimension); + + /* Check whether the sequence is valid. */ + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "if (%s%s == null) return V_COPYIN_RESULT.INVALID;\n", + srcName, iterationIndex); + + /* Get its Length, and check it for validity. */ + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "int %s = %s%s.Length;\n", seqLengthName, srcName, iterationIndex); + if (seqMaxLength == 0) { + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "// Unbounded sequence: bounds check not required...\n"); + } else { + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "if (%s > %u) return V_COPYIN_RESULT.INVALID;\n", seqLengthName, seqMaxLength); + } + + /* Locate the database type-definition of the sequence. */ + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "if (%s == IntPtr.Zero) {\n", seqTypeName); + indent_level++; + + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), + "IntPtr memberOwnerType = DDS.OpenSplice.Database.c.resolve(c.getBase(typePtr), fullyScopedName);\n"); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), + "IntPtr specifier = DDS.OpenSplice.Database.c.metaResolveSpecifier(memberOwnerType, \"%s\");\n", + csFieldName); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), + "IntPtr specifierType = DDS.OpenSplice.Database.c.specifierType(specifier);\n"); + + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "%s = DDS.OpenSplice.Database.c.typeActualType(specifierType);\n", seqTypeName); + + indent_level--; + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "}\n"); + + /* Allocate a matching array in the database. */ + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "IntPtr %s = DDS.OpenSplice.Database.c.newSequence(%s, %s);\n", + curBufName, seqTypeName, seqLengthName); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "if (%s == IntPtr.Zero) return V_COPYIN_RESULT.OUT_OF_MEMORY;\n", curBufName); + + switch(actualTypeKind) + { + case M_PRIMITIVE: + switch (c_primitiveKind(actualType)) + { + case P_USHORT: + case P_ULONG: + case P_ULONGLONG: + { + const char *signedCounterPart; + if (c_primitiveKind(actualType) == P_USHORT) { + signedCounterPart = "Int16"; + } else if (c_primitiveKind(actualType) == P_ULONG) { + signedCounterPart = "Int32"; + } else { + signedCounterPart = "Int64"; + } + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), + "Marshal.Copy((%s[]) (Array) %s%s, 0, %s, %s);\n", + signedCounterPart, srcName, iterationIndex, curBufName, seqLengthName); + break; + } + case P_SHORT: + case P_LONG: + case P_LONGLONG: + case P_FLOAT: + case P_DOUBLE: + case P_OCTET: + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), + "Marshal.Copy(%s%s, 0, %s, %s);\n", srcName, iterationIndex, curBufName, seqLengthName); + break; + default: + /* Intentionally fall through to the default handler. */ + break; + } + if (c_primitiveKind(actualType) != P_BOOLEAN && c_primitiveKind(actualType) != P_CHAR) { + if (dimension > 0) { + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "Marshal.WriteIntPtr(%s, %s);\n", dstName, curBufName); + } + break; + } + default: + nextBufTypeSize = idl_genAttrColVarName("Size", index, dimension); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "for (int i%u = 0; i%u < %s; i%u++) {\n", + dimension, dimension, seqLengthName, dimension); + indent_level++; + if (actualTypeKind == M_COLLECTION) { + if (c_collectionTypeKind(actualType) != OSPL_C_STRING) { + subType = c_typeActualType(c_collectionTypeSubType(actualType)); + if (c_collectionTypeKind(actualType) == OSPL_C_ARRAY && c_baseObjectKind(subType) == M_PRIMITIVE) { + os_free(iterationIndex); + iterationIndex = idl_CreateCSharpArrayIterationIndex(collStartType, dimension + 1); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "Marshal.Copy(%s%s, 0, %s, %d);\n", + srcName, iterationIndex, dstName, c_collectionTypeMaxSize(actualType)); + } else { + idl_UnionCreateArrayMemberWriteInner(collStartType, actualType, index, + dimension + 1, idlFieldName, csFieldName, srcName, curBufName); + } + } else { + idl_UnionCreateArrayMemberWriteInner(collStartType, actualType, index, + dimension + 1, idlFieldName, csFieldName, srcName, curBufName); + } + } else { + idl_UnionCreateSequenceMemberWriteInnerLoopBody( + collStartType, actualType, actualTypeKind, index, dimension + 1, + csFieldName, srcName, curBufName); + } + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), + "%s = new IntPtr(%s.ToInt64() + %s);\n", curBufName, curBufName, nextBufTypeSize); + indent_level--; + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "}\n"); + os_free(nextBufTypeSize); + break; + } + + os_free(iterationIndex); + os_free(seqTypeName); + os_free(seqLengthName); + os_free(curBufName); +} + +static void +idl_UnionCreateArrayMemberReadInnerLoopBody( + c_type collStartType, + c_type collType, + c_metaKind collKind, + c_ulong index, + c_ulong dimension, + const c_char *fieldName, + const c_char *dstName, + const c_char *srcName, + SACSTypeUserData *csUserData) +{ + c_char *cSharpArrayBrackets = idl_CreateCSharpArrayIterationIndex(collStartType, dimension); + c_char *databaseArrayBrackets = idl_CreateDatabaseArrayIterationIndex(collStartType, dimension); + c_char *colTypeName = idl_CsharpScopeStackFromCType(collType, csUserData->customPSM, FALSE, TRUE); + + OS_UNUSED_ARG(index); + OS_UNUSED_ARG(fieldName); + + switch(collKind) + { + case M_STRUCTURE: + case M_UNION: + if (idl_isPredefined(colTypeName)) { + const c_char *predefinedTypeName = idl_translateIfPredefined(colTypeName); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "%s%s = Read%s(%s, 0);\n", + dstName, cSharpArrayBrackets, &predefinedTypeName[4], srcName); + } else { + /* Get the CSharp specific name of the member type. */ + c_char *colTypeDBName = idl_CsharpScopeStackFromCType(collType, csUserData->customPSM, TRUE, TRUE); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "%sMarshaler.StaticCopyOut(%s, ref %s%s);\n", + colTypeDBName, srcName, dstName, cSharpArrayBrackets); + os_free(colTypeDBName); + } + break; + case M_ENUMERATION: + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "%s%s = (%s) Marshal.ReadInt32(%s);\n", + dstName, cSharpArrayBrackets, colTypeName, srcName); + break; + case M_PRIMITIVE: + switch (c_primitiveKind(collType)) { + case P_CHAR: + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "%s%s = ReadChar(%s, 0);\n", + dstName, cSharpArrayBrackets, srcName); + break; + case P_BOOLEAN: + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "%s%s = ReadBoolean(%s, 0);\n", + dstName, cSharpArrayBrackets, srcName); + break; + default: + assert(0); + } + break; + case M_COLLECTION: /* Assert that this collection is always of type string!! */ + assert(c_collectionTypeKind(collType) == OSPL_C_STRING); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "%s%s = ReadString(Marshal.ReadIntPtr(%s));\n", + dstName, cSharpArrayBrackets, srcName); + break; + default: + /* Unsupported Array type. */ + assert(FALSE); + break; + } + os_free(colTypeName); + os_free(databaseArrayBrackets); + os_free(cSharpArrayBrackets); +} + +static void +idl_UnionCreateSequenceMemberReadInnerLoopBody( + c_type collStartType, + c_type collType, + c_metaKind collKind, + c_ulong index, + c_ulong dimension, + const c_char *fieldName, + const c_char *dstName, + const c_char *srcName, + SACSTypeUserData *csUserData) +{ + c_char *cSharpArrayBrackets = idl_CreateCSharpArrayIterationIndex(collStartType, dimension); + c_char *colTypeName = idl_CsharpScopeStackFromCType(collType, csUserData->customPSM, FALSE, TRUE); + + OS_UNUSED_ARG(index); + OS_UNUSED_ARG(fieldName); + + switch(collKind) + { + case M_STRUCTURE: + case M_UNION: + idl_printIndent(indent_level); + if (idl_isPredefined(colTypeName)) { + /* Function below returns const string, so no need to free it afterward. */ + const c_char *predefinedTypeName = idl_translateIfPredefined(colTypeName); + /* Now remove the preceeding 'DDS.' from the typename, so start reading at character position 4. */ + idl_fileOutPrintf(idl_fileCur(), "%s%s = Read%s(%s, 0);\n", + dstName, cSharpArrayBrackets, &predefinedTypeName[4], srcName); + } else { + /* Get the CSharp specific name of the member type. */ + c_char *colTypeDBName = idl_CsharpScopeStackFromCType(collType, csUserData->customPSM, TRUE, TRUE); + idl_fileOutPrintf(idl_fileCur(), "%sMarshaler.StaticCopyOut(%s, ref %s%s);\n", + colTypeDBName, srcName, dstName, cSharpArrayBrackets); + os_free(colTypeDBName); + } + break; + case M_ENUMERATION: + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), + "%s%s = (%s) Marshal.ReadInt32(%s);\n", + dstName, cSharpArrayBrackets, colTypeName, srcName); + break; + case M_PRIMITIVE: + switch (c_primitiveKind(collType)) + { + case P_BOOLEAN: + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "%s%s = Marshal.ReadByte(%s) != 0 ? true : false;\n", + dstName, cSharpArrayBrackets, srcName); + break; + case P_CHAR: + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "%s%s = (char) Marshal.ReadByte(%s);\n", + dstName, cSharpArrayBrackets, srcName); + break; + /* Other primitives should have been handled by the caller already, using Marshal.Copy. */ + default: + assert(0); + break; + } + break; + case M_COLLECTION: /* Assert that this collection is always of type string!! */ + assert(c_collectionTypeKind(collType) == OSPL_C_STRING); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "IntPtr stringElementPtr = Marshal.ReadIntPtr(%s);\n", srcName); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "%s%s = ReadString(stringElementPtr);\n", dstName, cSharpArrayBrackets); + break; + default: + /* Unsupported Array type. */ + assert(FALSE); + break; + } + os_free(colTypeName); + os_free(cSharpArrayBrackets); +} + + +static void +idl_UnionCreateArrayMemberRead( + c_type collStartType, + c_type collType, + c_ulong index, + c_ulong dimension, + const c_char *fieldName, + const c_char *dstName, + const c_char *srcName, + SACSTypeUserData *csUserData) +{ + c_ulong arrLength; + c_char *seqLengthName, *seqBufName, *nextBufTypeSize, *arrayBrackets; + c_type subType, actualType, eventualElementType; + c_metaKind actualTypeKind; + + c_metaKind collKind = c_baseObjectKind(collType); + switch(collKind) + { + case M_STRUCTURE: + case M_ENUMERATION: + case M_PRIMITIVE: + case M_UNION: + idl_UnionCreateArrayMemberReadInnerLoopBody(collStartType, collType, collKind, + index, dimension, fieldName, dstName, srcName, csUserData); + break; + case M_COLLECTION: + /* Handle Collection type. */ + switch (c_collectionTypeKind(collType)) + { + case OSPL_C_STRING: + /* Handle strings. */ + idl_UnionCreateArrayMemberReadInnerLoopBody(collStartType, collType, collKind, + index, dimension, fieldName, dstName, srcName, csUserData); + break; + case OSPL_C_ARRAY: + /* Handle arrays. */ + arrLength = c_collectionTypeMaxSize(collType); + subType = c_collectionTypeSubType(collType); + actualType = c_typeActualType(subType); + eventualElementType = actualType; + arrayBrackets = idl_CreateCSharpArrayIterationIndex(collStartType, dimension); + + idl_generateUnionArrayStatusCheck(collStartType, collType, &eventualElementType, dimension, dstName, csUserData); + + if (c_baseObjectKind(eventualElementType) == M_PRIMITIVE && + c_primitiveKind(eventualElementType) != P_CHAR && c_primitiveKind(eventualElementType) != P_BOOLEAN) { + idl_printIndent(indent_level); + if (dimension == 0) { + c_char *primName = idl_genTypeNameFromCType(subType); + idl_fileOutPrintf(idl_fileCur(), "System.Buffer.BlockCopy(%s, 0, %s, 0, (%"PA_PRIu64" * Marshal.SizeOf(typeof(%s))));\n", + srcName, dstName, idl_determineDatabaseFlatArraySize(collStartType), primName); + os_free(primName); + } else { + idl_fileOutPrintf(idl_fileCur(), "Marshal.Copy(%s,%s%s, 0, %d);\n", + srcName, dstName, arrayBrackets, c_collectionTypeMaxSize(collType)); + } + } else { + c_char *handleName = idl_genAttrArrVarName("Handle", index, dimension); + c_char *bufName = idl_genAttrArrVarName("Buf", index, dimension); + c_char *elemSize = idl_genAttrColVarName("Size", index, dimension); + + if (dimension == 0) { + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "GCHandle %s = GCHandle.Alloc(from._u, GCHandleType.Pinned);\n", handleName); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "IntPtr %s = %s.AddrOfPinnedObject();\n", bufName, handleName); + } else { + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "IntPtr %s = new IntPtr(%s.ToInt64());\n", bufName, srcName); + } + + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "for (int i%d = 0; i%d < %d; i%d++) {\n", + dimension, dimension, arrLength, dimension); + indent_level++; + + idl_UnionCreateArrayMemberRead(collStartType, actualType, index, + dimension + 1, fieldName, dstName, bufName, csUserData); + + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "%s = new IntPtr(%s.ToInt64() + %s);\n", bufName, bufName, elemSize); + + indent_level--; + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "}\n"); + + if (dimension == 0) { + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "%s.Free();\n", handleName); + } + + os_free(bufName); + os_free(handleName); + os_free(elemSize); + } + + os_free(arrayBrackets); + break; + case OSPL_C_SEQUENCE: + /* Handle sequences. */ + subType = c_collectionTypeSubType(collType); + actualType = c_typeActualType(subType); + actualTypeKind = c_baseObjectKind(actualType); + + seqLengthName = idl_genAttrSeqVarName("Length", index, dimension); + + arrayBrackets = idl_CreateCSharpArrayIterationIndex(collStartType, dimension); + + if (dimension > 0) { + seqBufName = idl_genAttrSeqVarName("Buf", index, dimension); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), + "IntPtr %s = Marshal.ReadIntPtr(%s);\n", seqBufName, srcName); + srcName = seqBufName; + } else { + seqBufName = os_strdup(srcName); + } + + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), + "int %s = DDS.OpenSplice.Database.c.arraySize(%s);\n", + seqLengthName, srcName); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), + "if (%s%s == null || %s%s.Length != %s) {\n", + dstName, arrayBrackets, dstName, arrayBrackets, seqLengthName); + indent_level++; + idl_UnionCreateArrayInitialization(collType, dstName, seqLengthName, arrayBrackets, csUserData); + indent_level--; + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "}\n"); + switch(actualTypeKind) + { + case M_PRIMITIVE: + switch (c_primitiveKind(actualType)) + { + case P_USHORT: + case P_ULONG: + case P_ULONGLONG: + { + const char *signedCounterPart; + if (c_primitiveKind(actualType) == P_USHORT) { + signedCounterPart = "short"; + } else if (c_primitiveKind(actualType) == P_ULONG) { + signedCounterPart = "int"; + } else { + signedCounterPart = "long"; + } + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), + "if(%s > 0) Marshal.Copy(%s, (%s[]) (Array) %s%s, 0, %s);\n", + seqLengthName, srcName, signedCounterPart, dstName, arrayBrackets, seqLengthName); + break; + } + case P_SHORT: + case P_LONG: + case P_LONGLONG: + case P_FLOAT: + case P_DOUBLE: + case P_OCTET: + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), + "if(%s > 0) Marshal.Copy(%s, %s%s, 0, %s);\n", + seqLengthName, srcName, dstName, arrayBrackets, seqLengthName); + break; + default: + /* Intentionally break through to use the default handler. */ + break; + } + if (c_primitiveKind(actualType) != P_BOOLEAN && c_primitiveKind(actualType) != P_CHAR) break; + default: + nextBufTypeSize = idl_genAttrColVarName("Size", index, dimension); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "for (int i%d = 0; i%d < %s; i%d++) {\n", + dimension, dimension, seqLengthName, dimension); + indent_level++; + if (actualTypeKind == M_COLLECTION && c_collectionTypeKind(actualType) != OSPL_C_STRING) { + idl_UnionCreateArrayMemberRead(collStartType, actualType, index, + dimension + 1, fieldName, dstName, seqBufName, csUserData); + + } else { + idl_UnionCreateSequenceMemberReadInnerLoopBody( + collStartType, actualType, actualTypeKind, index, dimension + 1, + fieldName, dstName, srcName, csUserData); + } + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "%s = new IntPtr(%s.ToInt64() + %s);\n", + srcName, srcName, nextBufTypeSize); + indent_level--; + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "}\n"); + os_free(nextBufTypeSize); + break; + } + os_free(arrayBrackets); + os_free(seqLengthName); + os_free(seqBufName); + break; + default: + /* Unsupported Collection type. */ + assert(FALSE); + break; + } + break; + default: + /* Unsupported Array type. */ + assert(FALSE); + break; + } +} + +static void +idl_CreateUnionAttributes( + c_type unionType, + const c_char *unionName, + SACSTypeUserData *csUserData) +{ + c_ulong i, j, nrCases = c_unionUnionCaseCount((c_union) unionType); + c_longlong nrElements; + c_collKind seqKind; + + OS_UNUSED_ARG(unionName); + + /* Loop over the attributes of the datatype and process each attribute. */ + for (i = 0; i < nrCases; i++) { + /* Get the meta-data of the attribute from the database. */ + c_unionCase unionCase = c_unionUnionCase(unionType, i); + c_type unionCaseType = c_memberType(unionCase); + c_char *unionCaseTypeName = idl_CsharpScopeStackFromCType(unionCaseType, csUserData->customPSM, TRUE, TRUE); + c_char *unionCaseName = idl_CsharpId(c_specifierName(unionCase), csUserData->customPSM, FALSE); + + while (c_baseObjectKind(unionCaseType) == M_TYPEDEF) { + os_free(unionCaseTypeName); + unionCaseType = c_typeDef(unionCaseType)->alias; + unionCaseTypeName = idl_CsharpScopeStackFromCType(unionCaseType, csUserData->customPSM, TRUE, TRUE); + } + + seqKind = OSPL_C_UNDEFINED; + j = 0; + + switch(c_baseObjectKind(unionCaseType)) + { + case M_COLLECTION: + /* Iterate to the element type of the collection. */ + for (j = 0; c_baseObjectKind(unionCaseType) == M_COLLECTION; j++) { + /* For sequences, cache the database type for CopyIn. */ + if (c_collectionTypeKind(unionCaseType) == OSPL_C_SEQUENCE) { + c_char *subTypeDBName; + c_type subType; + + seqKind = OSPL_C_SEQUENCE; + + subType = c_typeActualType(c_collectionTypeSubType(unionCaseType)); + subTypeDBName = idl_cTypeToCSharpDatabaseRepresentation(subType, TRUE); + + nrElements = determineNrEventualElements(subType); + + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), + "private IntPtr attr%dCol%dType = IntPtr.Zero;\n", i, j); + if (c_baseObjectKind(c_typeActualType(c_collectionTypeSubType(unionCaseType))) != M_PRIMITIVE || + c_primitiveKind(c_typeActualType(c_collectionTypeSubType(unionCaseType))) == P_CHAR || + c_primitiveKind(c_typeActualType(c_collectionTypeSubType(unionCaseType))) == P_BOOLEAN) { + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), + "private static readonly int attr%dCol%dSize = %"PA_PRId64" * Marshal.SizeOf(typeof(%s));\n", + i, j, nrElements, subTypeDBName); + } + os_free(subTypeDBName); + unionCaseType = c_typeActualType(c_collectionTypeSubType(unionCaseType)); + os_free(unionCaseTypeName); + unionCaseTypeName = idl_CsharpScopeStackFromCType(unionCaseType, csUserData->customPSM, TRUE, TRUE); + } else { + c_char *subTypeDBName; + c_type subType = c_typeActualType(c_collectionTypeSubType(unionCaseType)); + + seqKind = OSPL_C_ARRAY; + + nrElements = determineNrEventualElements(subType); + if (c_baseObjectKind(subType) != M_PRIMITIVE || + c_primitiveKind(subType) == P_CHAR || c_primitiveKind(subType) == P_BOOLEAN ) { + subTypeDBName = idl_cTypeToCSharpDatabaseRepresentation(unionCaseType, TRUE); + + if (c_baseObjectKind(subType) == M_COLLECTION && c_collectionTypeKind(subType) == OSPL_C_SEQUENCE) { + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), + "private IntPtr attr%dCol%dType = IntPtr.Zero;\n", i, j); + } + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), + "private static readonly int attr%dCol%uSize = %"PA_PRId64" * Marshal.SizeOf(typeof(%s));\n", + i, j, nrElements, subTypeDBName); + os_free(subTypeDBName); + } + + unionCaseType = c_typeActualType(c_collectionTypeSubType(unionCaseType)); + os_free(unionCaseTypeName); + unionCaseTypeName = idl_CsharpScopeStackFromCType(unionCaseType, csUserData->customPSM, TRUE, TRUE); + } + } + if (c_baseObjectKind(unionCaseType) != M_STRUCTURE && c_baseObjectKind(unionCaseType) != M_UNION) { + break; + } else { + /* No break statement here!! + * This break-through is intentional, since in case the sequence + * type is a structure, its Marshaler must also be cached. + */ + } + case M_STRUCTURE: + case M_UNION: + if (!idl_isPredefined(unionCaseTypeName)) { + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "private %sMarshaler attr%dMarshaler;\n", unionCaseTypeName, i); + } else { + /* Generate type variable for collections of predefined types */ + switch (seqKind) { + case OSPL_C_SEQUENCE: + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), + "private IntPtr attr%uSeq%uType = IntPtr.Zero;\n", i, j); + break; + default: + break; + } + } + break; + default: + /* Fine: constructor doesn't need to do anything in particular here. */ + break; + } + os_free(unionCaseName); + os_free(unionCaseTypeName); + } + idl_fileOutPrintf(idl_fileCur(), "\n"); +} + + + +static void +idl_CreateUnionInitEmbeddedMarshalers( + c_type unionType, + const c_char *unionName, + SACSTypeUserData *csUserData) +{ + c_bool isPredefined; + c_ulong i, nrCases = c_unionUnionCaseCount((c_union) unionType); + + OS_UNUSED_ARG(unionName); + + /* Open the constructor itself and increase the indent. */ + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), + "public override void InitEmbeddedMarshalers(IDomainParticipant participant)\n"); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "{\n"); + indent_level++; + + /* Loop over the attributes of the datatype and process each attribute. */ + for (i = 0; i < nrCases; i++) { + /* Get the meta-data of the attribute from the database. */ + c_unionCase unionCase = c_unionUnionCase(unionType, i); + c_type unionCaseType = c_unionCaseType(unionCase); + c_char *unionCaseTypeName = idl_CsharpScopeStackFromCType(unionCaseType, csUserData->customPSM, TRUE, TRUE); + c_char *unionCaseName = idl_CsharpId(c_specifierName(unionCase), csUserData->customPSM, FALSE); + + if (idl_isPredefined(unionCaseName)) { + isPredefined = TRUE; + } else { + isPredefined = FALSE; + } + + /* Dereference possible typedefs/arrays/sequences first. */ + while ( !isPredefined && + ( c_baseObjectKind(unionCaseType) == M_TYPEDEF || + ( c_baseObjectKind(unionCaseType) == M_COLLECTION && + ( c_collectionTypeKind(unionCaseType) == OSPL_C_ARRAY || + c_collectionTypeKind(unionCaseType) == OSPL_C_SEQUENCE) ) ) ) { + os_free(unionCaseTypeName); + if (c_baseObjectKind(unionCaseType) == M_TYPEDEF) { + unionCaseType = c_typeDef(unionCaseType)->alias; + } else if (c_baseObjectKind(unionCaseType) == M_COLLECTION) { + unionCaseType = c_collectionTypeSubType(unionCaseType); + } + unionCaseTypeName = idl_CsharpScopeStackFromCType(unionCaseType, csUserData->customPSM, TRUE, TRUE); + if (idl_isPredefined(unionCaseTypeName)) { + isPredefined = TRUE; + } + } + + switch(c_baseObjectKind(unionCaseType)) + { + case M_STRUCTURE: + case M_UNION: + if (!idl_isPredefined(unionCaseTypeName)) { + os_char *prevTypeName = unionCaseTypeName; + unionCaseTypeName = idl_CsharpId(prevTypeName, csUserData->customPSM, FALSE); + os_free(prevTypeName); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "if (attr%dMarshaler == null) {\n",i); + indent_level++; + idl_printIndent(indent_level); + idl_fileOutPrintf( + idl_fileCur(), + "attr%dMarshaler = DatabaseMarshaler.GetMarshaler(participant, typeof(%s)) as %sMarshaler;\n", + i, unionCaseTypeName, unionCaseTypeName); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "if (attr%dMarshaler == null) {\n", i); + indent_level++; + idl_printIndent(indent_level); + idl_fileOutPrintf( + idl_fileCur(), + "attr%dMarshaler = new %sMarshaler();\n", + i, unionCaseTypeName); + idl_printIndent(indent_level); + idl_fileOutPrintf( + idl_fileCur(), + "DatabaseMarshaler.Add(participant, typeof(%s), attr%dMarshaler);\n", + unionCaseTypeName, i); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), + "attr%dMarshaler.InitEmbeddedMarshalers(participant);\n", i); + indent_level--; + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "}\n"); + indent_level--; + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "}\n"); + } + break; + default: + /* Fine: constructor doesn't need to do anything in particular here. */ + break; + } + os_free(unionCaseName); + os_free(unionCaseTypeName); + } + + /* Decrease the indent level back to its original value and close the constructor. */ + indent_level--; + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "}\n\n"); +} + + + +static void +idl_CreateUnionCaseWrite( + c_unionCase unionCase, + c_ulong index, + SACSTypeUserData *csUserData) +{ + c_type unionCaseType = c_unionCaseType(unionCase); + c_char *unionCaseName; + c_ulong maxSize, dimension; + c_char *varName, *handleName, *ptrName; + c_ulong nrLabels, i; + c_char *tName; + c_char *bufName = NULL; + c_bool isPredefined = FALSE; + c_char *unionCaseTypeName; + c_type arrType; + + unionCaseName = idl_CsharpId(c_specifierName(unionCase), csUserData->customPSM, FALSE); + unionCaseTypeName = idl_scopeStackFromCType(unionCaseType); + + if (idl_isPredefined(unionCaseTypeName)) { + isPredefined = TRUE; + } + + /* Dereference possible typedefs first. */ + while (c_baseObjectKind(unionCaseType) == M_TYPEDEF && !isPredefined) { + os_free(unionCaseTypeName); + unionCaseType = c_typeDef(unionCaseType)->alias; + unionCaseTypeName = idl_scopeStackFromCType(unionCaseType); + if (idl_isPredefined(unionCaseTypeName)) { + isPredefined = TRUE; + } + } + + nrLabels = c_arraySize(unionCase->labels); + + if (nrLabels > 0) { + for (i = 0; i < nrLabels; i++) { + c_literal label = c_literal(unionCase->labels[i]); + idl_printIndent(indent_level); + idl_printCaseLabel(label); + } + } else { + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "default:\n"); + } + + indent_level++; + + varName = idl_genAttrElemVarName("Var", index, 0); + handleName = idl_genAttrElemVarName("Handle", index, 0); + ptrName = idl_genAttrElemVarName("Buf", index, 0); + + switch(c_baseObjectKind(unionCaseType)) + { + case M_STRUCTURE: + case M_UNION: + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "{\n"); + + if (isPredefined) { + idl_printIndent(indent_level+1); + idl_fileOutPrintf(idl_fileCur(), "GCHandle %s = GCHandle.Alloc(to._u, GCHandleType.Pinned);\n", handleName); + idl_printIndent(indent_level+1); + idl_fileOutPrintf(idl_fileCur(), "IntPtr %s = %s.AddrOfPinnedObject();\n", ptrName, handleName); + /* Generate code to use the predefined Write operation in the base marshaler. */ + idl_printIndent(indent_level+1); + idl_fileOutPrintf(idl_fileCur(), "Write(%s, 0, from.%s());\n", ptrName, unionCaseName); + } else { + + idl_printIndent(indent_level+1); + idl_fileOutPrintf(idl_fileCur(), "%s %s = from.%s();\n", unionCaseTypeName, varName, unionCaseName); + idl_printIndent(indent_level+1); + idl_fileOutPrintf(idl_fileCur(), "GCHandle %s = GCHandle.Alloc(to._u, GCHandleType.Pinned);\n", handleName); + idl_printIndent(indent_level+1); + idl_fileOutPrintf(idl_fileCur(), "IntPtr %s = %s.AddrOfPinnedObject();\n", ptrName, handleName); + /* Otherwise generate code to use the dedicated marshaler. */ + idl_printIndent(indent_level+1); + idl_fileOutPrintf(idl_fileCur(), + "V_COPYIN_RESULT result = attr%dMarshaler.CopyIn(typePtr, %s, %s);\n", + index, varName, ptrName); + idl_printIndent(indent_level+1); + idl_fileOutPrintf(idl_fileCur(), "if (result != V_COPYIN_RESULT.OK) return result;\n"); + } + idl_printIndent(indent_level+1); + idl_fileOutPrintf(idl_fileCur(), "%s.Free();\n", handleName); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "}\n"); + break; + case M_ENUMERATION: + /* Generate code to handle an enum. */ + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "{\n"); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), " GCHandle %s = GCHandle.Alloc(to._u, GCHandleType.Pinned);\n", handleName); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), " IntPtr %s = %s.AddrOfPinnedObject();\n", ptrName, handleName); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), " BaseMarshaler.Write(%s, 0, (int)from.%s());\n", ptrName, unionCaseName); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), " %s.Free();\n", handleName); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "}\n"); + break; + case M_PRIMITIVE: + /* Generate code to handle a primitive. */ + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "{\n"); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), " GCHandle %s = GCHandle.Alloc(to._u, GCHandleType.Pinned);\n", handleName); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), " IntPtr %s = %s.AddrOfPinnedObject();\n", ptrName, handleName); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), " BaseMarshaler.Write(%s, 0, from.%s());\n", ptrName, unionCaseName); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), " %s.Free();\n", handleName); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "}\n"); + break; + case M_COLLECTION: + /* Generate code to handle Collection types. */ + switch (c_collectionTypeKind(unionCaseType)) + { + case OSPL_C_STRING: + /* Generate code to handle strings. */ + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "{\n"); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), " string %s = from.%s();\n", varName, unionCaseName); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), " if (%s == null) return V_COPYIN_RESULT.INVALID;\n", varName); + /* Generate code to check for bounds if a maximum bound was specified. */ + maxSize = c_collectionTypeMaxSize(unionCaseType); + idl_printIndent(indent_level); + if (maxSize > 0){ + idl_fileOutPrintf(idl_fileCur(), + " if (%s.Length > %d) return V_COPYIN_RESULT.INVALID;\n", varName, maxSize); + } else { + idl_fileOutPrintf(idl_fileCur(), " // Unbounded string: bounds check not required...\n"); + } + + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), " GCHandle %s = GCHandle.Alloc(to._u, GCHandleType.Pinned);\n", handleName); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), " IntPtr %s = %s.AddrOfPinnedObject();\n", ptrName, handleName); + + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), + " if (!Write(c.getBase(typePtr), %s , 0, ref %s)) return V_COPYIN_RESULT.OUT_OF_MEMORY;\n", ptrName, varName); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), " %s.Free();\n", handleName); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "}\n"); + break; + case OSPL_C_ARRAY: + + tName = idl_CsharpTypeFromCType(unionCaseType, csUserData->customPSM); + + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "{\n"); + + indent_level++; + + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "%s %s = from.%s();\n", tName, varName, unionCaseName); + + /* Check that the input is non-null. */ + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "if (%s == null) return V_COPYIN_RESULT.INVALID;\n", varName); + + /* Check that the input has the correct array size. */ + arrType = unionCaseType; + for (dimension = 0; c_baseObjectKind(arrType) == M_COLLECTION && c_collectionTypeKind(arrType) == OSPL_C_ARRAY; dimension++) + { + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "if (%s.GetLength(%d) != %d) return V_COPYIN_RESULT.INVALID;\n", + varName, dimension, c_collectionTypeMaxSize(arrType)); + arrType = c_typeActualType(c_collectionTypeSubType(arrType)); + } + + /* Generate the body of the copying loop. */ + idl_UnionCreateArrayMemberWrite( + unionCaseType, unionCaseType, index, 0, c_specifierName(unionCase), unionCaseName, varName, "to._u"); + + indent_level--; + + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "}\n"); + + os_free(tName); + break; + case OSPL_C_SEQUENCE: + + tName = idl_CsharpTypeFromCType(unionCaseType, csUserData->customPSM); + + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "{\n"); + + indent_level++; + + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "%s %s = from.%s();\n", tName, varName, unionCaseName); + + bufName = idl_genAttrSeqVarName("Buf", index, 0); + + idl_UnionCreateSequenceMemberWrite( + unionCaseType, unionCaseType, index, 0, c_specifierName(unionCase), unionCaseName, varName, bufName); + + arrType = c_typeActualType(c_collectionTypeSubType(unionCaseType)); + if (c_baseObjectKind(arrType) != M_PRIMITIVE || + c_primitiveKind(arrType) == P_BOOLEAN || c_primitiveKind(arrType)== P_CHAR) { + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), + "%s = new IntPtr(%s.ToInt64() - ((long) attr%dCol0Size * (long) attr%dSeq0Length));\n", + bufName, bufName, index, index); + } + + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "GCHandle %s = GCHandle.Alloc(to._u, GCHandleType.Pinned);\n", handleName); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "IntPtr %s = %s.AddrOfPinnedObject();\n", ptrName, handleName); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "Marshal.WriteIntPtr(%s, %s);\n", ptrName, bufName); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "%s.Free();\n", handleName); + + indent_level--; + + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "}\n"); + + os_free(bufName); + os_free(tName); + break; + + default: + /* Unsupported Collection type. */ + assert(FALSE); + break; + } + break; + default: + /* Unsupported Base type. */ + assert(FALSE); + break; + } + + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "break;\n"); + + indent_level--; + + os_free(unionCaseTypeName); + os_free(unionCaseName); + os_free(varName); + os_free(handleName); + os_free(ptrName); +} + +static void +idl_CreateUnionCopyIn( + c_type unionType, + const c_char *unionDBName, + SACSTypeUserData *csUserData, + SACSUnionMetaDescriptionSplDcps *umd) +{ + c_ulong i, nrCases = c_unionUnionCaseCount((c_union) unionType); + c_type unionDiscrType = c_typeActualType(c_unionUnionSwitchType((c_union)unionType)); + + /* Open the 1st CopyIn operation and increase the indent. */ + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "public override V_COPYIN_RESULT CopyIn(System.IntPtr typePtr, System.IntPtr from, System.IntPtr to)\n"); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "{\n"); + indent_level++; + + /* Generate code that obtains a C# object from a C pointer and then invokes the 2nd CopyIn. */ + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "GCHandle tmpGCHandle = GCHandle.FromIntPtr(from);\n"); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "%s fromData = tmpGCHandle.Target as %s;\n", umd->fullyScopedName, umd->fullyScopedName); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "return CopyIn(typePtr, fromData, to);\n"); + /* Decrease the indent level back to its original value and close the 1st CopyIn operation. */ + indent_level--; + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "}\n\n"); + + /* Generate code that creates a C# projection of the database, invoke the 3rd CopyIn with it, and marshal it into unmanaged memory. */ + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "public V_COPYIN_RESULT CopyIn(System.IntPtr typePtr, %s from, System.IntPtr to)\n", umd->fullyScopedName); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "{\n"); + indent_level++; + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "%s nativeImg = new %s();\n", unionDBName, unionDBName); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "V_COPYIN_RESULT result = CopyIn(typePtr, from, ref nativeImg);\n"); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "if (result == V_COPYIN_RESULT.OK)\n"); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "{\n"); + indent_level++; + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "Marshal.StructureToPtr(nativeImg, to, false);\n"); + indent_level--; + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "}\n"); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "return result;\n"); + + /* Decrease the indent level back to its original value and close the 2nd CopyIn operation. */ + indent_level--; + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "}\n\n"); + + /* Open the 2nd CopyIn operation and increase the indent. */ + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "public V_COPYIN_RESULT CopyIn(System.IntPtr typePtr, %s from, ref %s to)\n", umd->fullyScopedName, unionDBName); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "{\n"); + indent_level++; + + /* Generate code that checks whether the C# input is a valid object. */ + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "if (from == null) return V_COPYIN_RESULT.INVALID;\n"); + + idl_printIndent(indent_level); + if ((c_baseObjectKind(unionDiscrType) == M_PRIMITIVE) && + (c_primitiveKind(unionDiscrType) == P_BOOLEAN)) { + idl_fileOutPrintf(idl_fileCur(), "to._d = (from.Discriminator ? (byte)1 :(byte)0);\n"); + } else { + char *dbType = idl_cTypeToCSharpDatabaseRepresentation(unionDiscrType, TRUE); + idl_fileOutPrintf(idl_fileCur(), "to._d = (%s)from.Discriminator;\n", dbType); + os_free(dbType); + } + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "to.Init();\n"); + + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "switch (to._d)\n"); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "{\n"); + + indent_level++; + + /* Now generate the code that loops through the attributes and generates the appropriate instructions. */ + for (i = 0; i < nrCases; i++) { + /* Get the meta-data of the attribute from the database. */ + c_unionCase unionCase = c_unionUnionCase(unionType, i); + idl_CreateUnionCaseWrite(unionCase, i, csUserData); + } + + /* create default case */ + if (umd->gUnionGenDefault) { + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "default:\n"); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), " break;\n"); + } + + indent_level--; + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "}\n"); + + /* Generate code that returns true when everything went fine so far. */ + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "return V_COPYIN_RESULT.OK;\n"); + + /* Decrease the indent level back to its original value and close the 3rd CopyIn operation. */ + indent_level--; + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "}\n\n"); +} + +static void +idl_CreateUnionCaseRead( + c_unionCase unionCase, + c_ulong index, + c_char *unionDiscrTypeName, + SACSTypeUserData *csUserData) +{ + c_type unionCaseType = c_unionCaseType(unionCase); + c_char *unionCaseName; + c_ulong nrLabels, i; + c_char *bufName = NULL; + c_char *varName = NULL, *handleName = NULL, *ptrName = NULL; + c_bool isPredefined = FALSE; + c_char *unionCaseTypeName; + c_char *tName; + c_char *discr = os_strdup(""); + c_bool isArray; + + unionCaseName = idl_CsharpId(c_specifierName(unionCase), csUserData->customPSM, FALSE); + unionCaseTypeName = idl_scopeStackFromCType(unionCaseType); + + if (idl_isPredefined(unionCaseTypeName)) { + isPredefined = TRUE; + } + + /* Dereference possible typedefs first. */ + while (c_baseObjectKind(unionCaseType) == M_TYPEDEF && !isPredefined) { + os_free(unionCaseTypeName); + unionCaseType = c_typeDef(unionCaseType)->alias; + unionCaseTypeName = idl_scopeStackFromCType(unionCaseType); + if (idl_isPredefined(unionCaseTypeName)) { + isPredefined = TRUE; + } + } + + nrLabels = c_arraySize(unionCase->labels); + + if (nrLabels > 0) { + for (i = 0; i < nrLabels; i++) { + c_literal label = c_literal(unionCase->labels[i]); + idl_printIndent(indent_level); + idl_printCaseLabel(label); + } + if (nrLabels > 1) { + os_size_t l = strlen(unionDiscrTypeName) + strlen("()from._d, ") + 1; + os_free(discr); + discr = os_malloc(l); + snprintf(discr, l, "(%s)from._d, ", unionDiscrTypeName); + } + } else { + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "default:\n"); + } + + isArray = (c_baseObjectKind(unionCaseType) == M_COLLECTION) && (c_collectionTypeKind(unionCaseType) == OSPL_C_ARRAY); + + varName = idl_genAttrElemVarName("Var", index, 0); + handleName = idl_genAttrElemVarName("Handle", index, 0); + ptrName = idl_genAttrSeqVarName("Buf", index, 0); + + indent_level++; + + if (!isArray) { + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "{\n"); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), " GCHandle %s = GCHandle.Alloc(from._u, GCHandleType.Pinned);\n", handleName); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), " IntPtr %s = %s.AddrOfPinnedObject();\n", ptrName, handleName); + } + + switch(c_baseObjectKind(unionCaseType)) + { + case M_STRUCTURE: + case M_UNION: + if (isPredefined) { + /* Predefined types can use specialized Read operations. */ + const c_char *predefinedTypeName = idl_translateIfPredefined(unionCaseTypeName); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), " to.%s(Read%s(%s, 0));\n", unionCaseName, &predefinedTypeName[4], ptrName); + } else { + /* Other types should use their corresponding Marshaler. */ + /* Get the CSharp specific name of the member type. */ + c_char *unionCaseTypeDBName = idl_CsharpScopeStackFromCType(unionCaseType, csUserData->customPSM, TRUE, TRUE); + + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), " %s %s = new %s();\n", + unionCaseTypeName, varName, unionCaseTypeName); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), " %sMarshaler.StaticCopyOut(%s, ref %s);\n", + unionCaseTypeDBName, ptrName, varName); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), " to.%s(%s%s);\n", unionCaseName, discr, varName); + os_free(unionCaseTypeDBName); + } + break; + case M_ENUMERATION: + /* Enums are read as Int32 types. */ + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), " to.%s((%s)BaseMarshaler.ReadInt32(%s, 0));\n", unionCaseName, unionCaseTypeName, ptrName); + break; + case M_PRIMITIVE: + /* Handle primitive. */ + idl_printIndent(indent_level); + switch (c_primitiveKind(unionCaseType)) + { + case P_BOOLEAN: + idl_fileOutPrintf(idl_fileCur(), " to.%s(BaseMarshaler.ReadBoolean(%s, 0));\n", unionCaseName, ptrName); + break; + case P_CHAR: + idl_fileOutPrintf(idl_fileCur(), " to.%s(BaseMarshaler.ReadChar(%s, 0));\n", unionCaseName, ptrName); + break; + case P_OCTET: + idl_fileOutPrintf(idl_fileCur(), " to.%s(BaseMarshaler.ReadByte(%s, 0));\n", unionCaseName, ptrName); + break; + case P_SHORT: + idl_fileOutPrintf(idl_fileCur(), " to.%s(BaseMarshaler.ReadInt16(%s, 0));\n", unionCaseName, ptrName); + break; + case P_USHORT: + idl_fileOutPrintf(idl_fileCur(), " to.%s(BaseMarshaler.ReadUInt16(%s, 0));\n", unionCaseName, ptrName); + break; + case P_LONG: + idl_fileOutPrintf(idl_fileCur(), " to.%s(BaseMarshaler.ReadInt32(%s, 0));\n", unionCaseName, ptrName); + break; + case P_ULONG: + idl_fileOutPrintf(idl_fileCur(), " to.%s(BaseMarshaler.ReadUInt32(%s, 0));\n", unionCaseName, ptrName); + break; + case P_LONGLONG: + idl_fileOutPrintf(idl_fileCur(), " to.%s(BaseMarshaler.ReadInt64(%s, 0));\n", unionCaseName, ptrName); + break; + case P_ULONGLONG: + idl_fileOutPrintf(idl_fileCur(), " to.%s(BaseMarshaler.ReadUInt64(%s, 0));\n", unionCaseName, ptrName); + break; + case P_FLOAT: + idl_fileOutPrintf(idl_fileCur(), " to.%s(BaseMarshaler.ReadFloat(%s, 0));\n", unionCaseName, ptrName); + break; + case P_DOUBLE: + idl_fileOutPrintf(idl_fileCur(), " to.%s(BaseMarshaler.ReadDouble(%s,0));\n", unionCaseName, ptrName); + break; + default: + /* Unsupported primitive type. */ + assert(FALSE); + break; + } + break; + case M_COLLECTION: + /* Handle Collection type. */ + switch (c_collectionTypeKind(unionCaseType)) + { + case OSPL_C_STRING: + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), " to.%s(ReadString(Marshal.ReadIntPtr(%s)));\n", unionCaseName, ptrName); + break; + case OSPL_C_ARRAY: + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "{\n"); + + indent_level++; + + tName = idl_CsharpTypeFromCType(unionCaseType, csUserData->customPSM); + + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "%s %s = null;\n", tName, varName); + nrLabels = c_arraySize(unionCase->labels); + if (nrLabels > 0) { + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "if ("); + for (i = 0; i < nrLabels; i++) { + c_literal label = c_literal(unionCase->labels[i]); + char *value = idl_getCSharpLabelValue(label); + if (i == 0) { + idl_fileOutPrintf(idl_fileCur(), "to.Discriminator == (%s)%s", unionDiscrTypeName, value); + } else { + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "\n || to.Discriminator == (%s)%s", unionDiscrTypeName, value); + } + os_free(value); + } + idl_fileOutPrintf(idl_fileCur(),") {\n"); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), " %s = to.%s();\n", varName, unionCaseName); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(),"}\n"); + } + + os_free(tName); + + idl_UnionCreateArrayMemberRead( + unionCaseType, unionCaseType, index, 0, unionCaseName, varName, "from._u", csUserData); + + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "to.%s(%s);\n", unionCaseName, varName); + + indent_level--; + + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "}\n"); + break; + case OSPL_C_SEQUENCE: + indent_level++; + + tName = idl_CsharpTypeFromCType(unionCaseType, csUserData->customPSM); + + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "%s %s = null;\n", tName, varName); + nrLabels = c_arraySize(unionCase->labels); + if (nrLabels > 0) { + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "if ("); + for (i = 0; i < nrLabels; i++) { + c_literal label = c_literal(unionCase->labels[i]); + char *value = idl_getCSharpLabelValue(label); + if (i == 0) { + idl_fileOutPrintf(idl_fileCur(), "to.Discriminator == (%s)%s", unionDiscrTypeName, value); + } else { + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "\n || to.Discriminator == (%s)%s", unionDiscrTypeName, value); + } + os_free(value); + } + idl_fileOutPrintf(idl_fileCur(),") {\n"); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), " %s = to.%s();\n", varName, unionCaseName); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(),"}\n"); + } + os_free(tName); + + bufName = idl_genAttrSeqVarName("Buf", index, 0); + + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "%s = Marshal.ReadIntPtr(%s);\n", bufName, bufName); + + idl_UnionCreateArrayMemberRead( + unionCaseType, unionCaseType, index, 0, unionCaseName, varName, bufName, csUserData); + + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "to.%s(%s);\n", unionCaseName, varName); + + indent_level--; + os_free(bufName); + break; + default: + /* Unsupported Collection type. */ + assert(FALSE); + } + break; + default: + /* Unsupported Base type. */ + assert(FALSE); + } + + if (!isArray) { + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), " %s.Free();\n", handleName); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "}\n"); + } + + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "break;\n"); + + indent_level--; + + os_free(unionCaseTypeName); + os_free(unionCaseName); + os_free(varName); + os_free(handleName); + os_free(ptrName); + os_free(discr); +} + +static void +idl_CreateUnionCopyOut( + c_type unionType, + const c_char *unionDBName, + SACSTypeUserData *csUserData, + SACSUnionMetaDescriptionSplDcps *umd) +{ + c_ulong i, nrCases = c_unionUnionCaseCount((c_union) unionType); + c_type unionDiscrType = c_typeActualType(c_unionUnionSwitchType((c_union)unionType)); + idl_typeSpec unionDiscrSpec = idl_makeTypeSpec(unionDiscrType); + c_char *unionDiscrTypeName = idl_CsharpTypeFromTypeSpec(unionDiscrSpec, csUserData->customPSM); + idl_freeTypeSpec(unionDiscrSpec); + + /* Open the 1st CopyOut operation and increase the indent. */ + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "public override void CopyOut(System.IntPtr from, System.IntPtr to)\n"); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "{\n"); + indent_level++; + + /* Generate a body that retrieves the C# object and invokes the appropriate CopyOut. */ + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "%s nativeImg = (%s) Marshal.PtrToStructure(from, typeof(%s));\n", + unionDBName, unionDBName, unionDBName); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "GCHandle tmpGCHandleTo = GCHandle.FromIntPtr(to);\n"); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "%s toObj = tmpGCHandleTo.Target as %s;\n", umd->fullyScopedName, umd->fullyScopedName); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "CopyOut(ref nativeImg, ref toObj);\n"); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "tmpGCHandleTo.Target = toObj;\n"); + + /* Decrease the indent level back to its original value and close the CopyOut operation. */ + indent_level--; + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "}\n\n"); + + /* Open the 2nd CopyOut operation and increase the indent. */ + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "public override void CopyOut(System.IntPtr from, ref %s to)\n", umd->fullyScopedName); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "{\n"); + indent_level++; + + /* Generate a body that retrieves the C# object and invokes the appropriate CopyOut. */ + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "%s nativeImg = (%s) Marshal.PtrToStructure(from, typeof(%s));\n", + unionDBName, unionDBName, unionDBName); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "CopyOut(ref nativeImg, ref to);\n"); + + /* Decrease the indent level back to its original value and close the CopyOut operation. */ + indent_level--; + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "}\n\n"); + + /* Open the 3rd CopyOut operation and increase the indent. */ + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "public static void StaticCopyOut(System.IntPtr from, ref %s to)\n", umd->fullyScopedName); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "{\n"); + indent_level++; + + /* Generate a body that retrieves the C# object and invokes the appropriate CopyOut. */ + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "%s nativeImg = (%s) Marshal.PtrToStructure(from, typeof(%s));\n", + unionDBName, unionDBName, unionDBName); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "CopyOut(ref nativeImg, ref to);\n"); + + /* Decrease the indent level back to its original value and close the CopyOut operation. */ + indent_level--; + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "}\n\n"); + + /* Open the 4th CopyOut operation and increase the indent. */ + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "public static void CopyOut(ref %s from, ref %s to)\n", unionDBName, umd->fullyScopedName); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "{\n"); + indent_level++; + + /* Cast the object to its proper type and if no yet allocated, allocate it. */ + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "if (to == null) {\n"); + indent_level++; + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "to = new %s();\n", umd->fullyScopedName); + indent_level--; + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "}\n"); + + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "switch (from._d)\n"); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "{\n"); + + indent_level++; + + + /* Now generate the code that loops through the attributes and generates the appropriate instructions. */ + for (i = 0; i < nrCases; i++) { + /* Get the meta-data of the attribute from the database. */ + c_unionCase unionCase = c_unionUnionCase(unionType, i); + idl_CreateUnionCaseRead(unionCase, i, unionDiscrTypeName, csUserData); + } + + /* create default case */ + if (umd->gUnionGenDefault) { + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "default:\n"); + idl_printIndent(indent_level); + if ((c_baseObjectKind(unionDiscrType) == M_PRIMITIVE) && (c_primitiveKind(unionDiscrType) == P_BOOLEAN)) { + idl_fileOutPrintf(idl_fileCur(), " to.Default(((from._d != 0) ? true : false));\n"); + } else { + idl_fileOutPrintf(idl_fileCur(), " to.Default((%s)from._d);\n", unionDiscrTypeName); + } + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), " break;\n"); + } + + /* Decrease the indent level back to its original value and close the CopyOut operation. */ + indent_level--; + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "}\n\n"); + + indent_level--; + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "}\n\n"); + + os_free(unionDiscrTypeName); +} + +static void +idl_generateUnionMarshaler ( + c_type unionType, + const c_char *unionDBName, + SACSTypeUserData *csUserData, + SACSUnionMetaDescriptionSplDcps *umd) +{ + /* Generate the C# code that opens a sealed class. */ + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "#region %sMarshaler\n", unionDBName); + idl_printIndent(indent_level); + idl_fileOutPrintf( + idl_fileCur(), + "public sealed class %sMarshaler : DDS.OpenSplice.CustomMarshalers.FooDatabaseMarshaler<%s>\n", + unionDBName, umd->fullyScopedName); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "{\n"); + + /* Increase the indentation level. */ + indent_level++; + + /* Create the constructor of the Marshaler. */ + idl_determineFullyScopedName(unionType); + idl_CreateUnionAttributes(unionType, unionDBName, csUserData); + idl_CreateUnionInitEmbeddedMarshalers(unionType, unionDBName, csUserData); + idl_CreateUnionCopyIn(unionType, unionDBName, csUserData, umd); + idl_CreateUnionCopyOut(unionType, unionDBName, csUserData, umd); + + /* Decrease the indentation level and generate the closing bracket. */ + indent_level--; + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "}\n"); + idl_printIndent(indent_level); + idl_fileOutPrintf (idl_fileCur(), "#endregion\n\n"); +} diff --git a/src/tools/idlpp/code/idl_genSACSSplDcps.h b/src/tools/idlpp/code/idl_genSACSSplDcps.h index cec59095b..68c071027 100644 --- a/src/tools/idlpp/code/idl_genSACSSplDcps.h +++ b/src/tools/idlpp/code/idl_genSACSSplDcps.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,13 +23,7 @@ #include "idl_program.h" -struct SACSSplDcpsUserData_s { - c_bool customPSM; -}; - -typedef struct SACSSplDcpsUserData_s SACSSplDcpsUserData; - idl_program -idl_genSACSSplDcpsProgram(SACSSplDcpsUserData *userData); +idl_genSACSSplDcpsProgram(void *userData); #endif /* IDL_GENSACSSPLDCPS_H_ */ diff --git a/src/tools/idlpp/code/idl_genSACSType.c b/src/tools/idlpp/code/idl_genSACSType.c index 9bdb1ff4b..627b91801 100644 --- a/src/tools/idlpp/code/idl_genSACSType.c +++ b/src/tools/idlpp/code/idl_genSACSType.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -38,11 +39,14 @@ #include "idl_dependencies.h" #include "idl_genLanguageHelper.h" #include "idl_dll.h" +#include "idl_map.h" + #include "vortex_os.h" #include #include "c_typebase.h" + /** indentation level */ static c_long indent_level = 0; /** enumeration element index */ @@ -50,7 +54,148 @@ static c_ulong enum_element = 0; /** enumeration enum name */ static char *enum_enumName = NULL; -/* @brief callback function called on opening the IDL input file. + +struct SACSUnionMetaDescription_s { + idl_map unionCaseMap; + char *unionSwitchType; + char *union1stCaseValue; + idl_typeSpec union1stCaseType; + char *union1stCaseIdent; + os_iter labelIter; + os_iter labelsUsedIter; + c_bool caseIsDefault; + c_ulong unionCaseOffset; +}; +typedef struct SACSUnionMetaDescription_s SACSUnionMetaDescription; + + + +/** @brief function to find out whether the elements of an array + * require initialization. + * + * idl_arrayElementsNeedInitialization is a local support function to find out + * whether the specified array is of a type for which all elements need to be + * initialized individually. If the array is of a primitive type, this is never + * necessary, but if the array contains a reference type and no underlying + * sequences (which will be initialized to 0 elements) then for loops will + * need to be created to explicitly initialize all of these attributes. + * + * @param typeSpec Specifies the attribute type that needs to be investigated. + */ +static int +idl_arrayElementsNeedInitialization( + idl_typeArray typeArray) +{ + int initRequired = FALSE; + + /* Obtain the type of the array. */ + idl_typeSpec typeSpec = idl_typeArrayType(typeArray); + + /* Resolve potential typedefs. */ + while (idl_typeSpecType(typeSpec) == idl_ttypedef) { + typeSpec = idl_typeDefRefered(idl_typeDef(typeSpec)); + } + + if (idl_typeSpecType(typeSpec) == idl_tarray) { + initRequired = idl_arrayElementsNeedInitialization(idl_typeArray(typeSpec)); + } else if (idl_typeSpecType(typeSpec) == idl_tstruct || + idl_typeSpecType(typeSpec) == idl_tunion || + idl_typeSpecType(typeSpec) == idl_tenum || + (idl_typeSpecType(typeSpec) == idl_tbasic && + idl_typeBasicType(idl_typeBasic (typeSpec)) == idl_string)) { + initRequired = TRUE; + } + + return initRequired; +} + +/** @brief generate initialization of array elements. + * + * idl_arrayElementInit generates for-loops that initialize + * each attribute of an array explicitly. + * + * @param typeArray Specifies the type of the array + */ +static void +idl_arrayElementInit( + idl_typeSpec typeSpec, + const char *elementName, + int dimCount, + int indent, + c_bool customPSM) +{ + c_char *tName; + + while (idl_typeSpecType(typeSpec) == idl_ttypedef) { + typeSpec = idl_typeDefRefered(idl_typeDef(typeSpec)); + } + + if (idl_typeSpecType(typeSpec) == idl_tarray) { + idl_fileOutPrintf( + idl_fileCur(), "%*sfor(int i%d = 0; i%d < %d; i%d++) {\n", + indent, "", dimCount, dimCount, idl_typeArraySize(idl_typeArray(typeSpec)), dimCount); + idl_arrayElementInit(idl_typeArrayType(idl_typeArray(typeSpec)), elementName, dimCount + 1, indent + 4, customPSM); + idl_fileOutPrintf(idl_fileCur(), "%*s}\n", indent, ""); + } else { + int j; + + idl_fileOutPrintf(idl_fileCur(), "%*s_%s[", indent, "", elementName); + for (j = 1; j < dimCount; j++) { + if (j == 1) { + idl_fileOutPrintf(idl_fileCur(), "i%d", j); + } else { + idl_fileOutPrintf(idl_fileCur(), ",i%d", j); + } + } + if (idl_typeSpecType(typeSpec) == idl_tbasic && idl_typeBasicType(idl_typeBasic(typeSpec)) == idl_string) { + idl_fileOutPrintf(idl_fileCur(), "] = \"\";\n"); + } else if (idl_typeSpecType(typeSpec) == idl_tunion || idl_typeSpecType(typeSpec) == idl_tstruct ) { + tName = idl_CsharpTypeFromTypeSpec(typeSpec, customPSM); + idl_fileOutPrintf(idl_fileCur(), "] = new %s();\n", tName); + os_free(tName); + } else if (idl_typeSpecType(typeSpec) == idl_tenum) { + tName = idl_CsharpTypeFromTypeSpec(typeSpec, customPSM); + idl_fileOutPrintf(idl_fileCur(), "] = (%s)(0);\n", tName); + os_free(tName); + } + } +} + + +/** @brief generate initialization of array elements. + * + * idl_arrayInitializeElements is a local support function to initialize + * the elements of non-primitive array types, if appropriate. + * + * @param typeSpec Type of the attribute that might need to be initialized. + * @param elementName Name of the attribute that might need to be initialized. + */ +static void +idl_arrayInitializeElements( + idl_typeSpec typeSpec, + const char *elementName, + c_bool customPSM) +{ + int dimCount = 1; + int indent = (indent_level + 1) * 4; + + while (idl_typeSpecType(typeSpec) == idl_ttypedef) { + typeSpec = idl_typeDefRefered(idl_typeDef(typeSpec)); + } + + if ( idl_typeSpecType(typeSpec) == idl_tarray) { + if (idl_arrayElementsNeedInitialization(idl_typeArray(typeSpec))) { + idl_arrayElementInit(typeSpec, elementName, dimCount, indent, customPSM); + } + } +} + + + + + + +/** @brief callback function called on opening the IDL input file. * * Generate standard file header consisting of: * - inclusion of Splice type definition files @@ -68,7 +213,7 @@ idl_fileOpen( OS_UNUSED_ARG(name); OS_UNUSED_ARG(userData); - /* Generate inclusion of standard OpenSplice DDS type definition files */ + /* Generate inclusion of standard Vortex OpenSplice type definition files */ idl_fileOutPrintf(idl_fileCur(), "using DDS;\n"); idl_fileOutPrintf(idl_fileCur(), "using System.Runtime.InteropServices;\n"); idl_fileOutPrintf(idl_fileCur(), "\n"); @@ -389,6 +534,131 @@ idl_structureMemberOpenClose ( } } +/** @brief Generate a string representaion the literal value of a label + * in metadata terms. + * + * @param labelVal Specifies the kind and the value of the label + * @return String representing the image of \b labelVal + */ +#define maxLabelNameSize 100 + +static c_char * +idl_valueFromLabelVal ( + idl_labelVal labelVal, + SACSUnionMetaDescription *umd, + c_bool customPSM) +{ + c_char *labelName; + + if (idl_labelValType(idl_labelVal(labelVal)) == idl_lenum) { + labelName = idl_labelCsharpEnumVal(umd->unionSwitchType, idl_labelEnum(labelVal), customPSM); + } else { + labelName = os_malloc(maxLabelNameSize); + switch (idl_labelValueVal(idl_labelValue(labelVal)).kind) { + case V_CHAR: + snprintf(labelName, maxLabelNameSize, "%u", + idl_labelValueVal(idl_labelValue(labelVal)).is.Char); + break; + case V_SHORT: + snprintf(labelName, maxLabelNameSize, "%d", + idl_labelValueVal(idl_labelValue(labelVal)).is.Short); + break; + case V_USHORT: + snprintf(labelName, maxLabelNameSize, "%u", + idl_labelValueVal(idl_labelValue(labelVal)).is.UShort); + break; + case V_LONG: + snprintf(labelName, maxLabelNameSize, "%d", + idl_labelValueVal(idl_labelValue(labelVal)).is.Long); + break; + case V_ULONG: + snprintf(labelName, maxLabelNameSize, "%u", + idl_labelValueVal(idl_labelValue(labelVal)).is.ULong); + break; + case V_LONGLONG: + snprintf(labelName, maxLabelNameSize, "%"PA_PRId64"", + idl_labelValueVal(idl_labelValue(labelVal)).is.LongLong); + break; + case V_ULONGLONG: + snprintf(labelName, maxLabelNameSize, "%"PA_PRIu64"", + idl_labelValueVal(idl_labelValue(labelVal)).is.ULongLong); + break; + case V_BOOLEAN: + /* QAC EXPECT 3416; No side effect here */ + if (idl_labelValueVal(idl_labelValue(labelVal)).is.Boolean == TRUE) { + snprintf(labelName, maxLabelNameSize, "true"); + } else { + snprintf(labelName, maxLabelNameSize, "false"); + } + break; + default: + break; + } + } + return labelName; +} + +/** @brief Return a C# typename corresponging to a case field the IDL type specification + * + * @param typeSpec IDL type specification + * @param customPSM Use custom PSM or not + */ +static char * +idl_unionCaseTypeFromTypeSpec( + idl_typeSpec typeSpec, + c_bool customPSM) +{ + char typeName[512]; + char *tname; + c_bool isPredefined = FALSE; + + tname = idl_CsharpTypeFromTypeSpec(typeSpec, customPSM); + + /* Dereference possible typedefs first. */ + while (idl_typeSpecType(typeSpec) == idl_ttypedef && !isPredefined) { + if (!idl_isPredefined(tname)) { + typeSpec = idl_typeDefRefered(idl_typeDef(typeSpec)); + os_free (tname); + tname = idl_CsharpTypeFromTypeSpec(typeSpec, customPSM); + } else { + isPredefined = TRUE; + } + } + + if (idl_typeSpecType(typeSpec) == idl_tbasic) { + snprintf(typeName, sizeof(typeName), "%s", tname); + } else if (idl_typeSpecType(typeSpec) == idl_tseq) { + char *str_no_idx = idl_sequenceCsharpIndexString(typeSpec, SACS_EXCLUDE_INDEXES, NULL); + assert (str_no_idx); + snprintf (typeName, sizeof(typeName), "%s%s", tname, str_no_idx); + os_free(str_no_idx); + } else if (idl_typeSpecType(typeSpec) == idl_tarray) { + char *str_no_idx = idl_arrayCsharpIndexString(typeSpec, SACS_EXCLUDE_INDEXES); + assert (str_no_idx); + snprintf(typeName, sizeof(typeName), "%s%s", tname, str_no_idx); + os_free(str_no_idx); + } else if (idl_typeSpecType(typeSpec) == idl_ttypedef) { + /* This state should only be reachable for predefined types. */ + assert(isPredefined); + snprintf(typeName, sizeof(typeName), "%s", tname); + } else { + if ((idl_typeSpecType(typeSpec) == idl_tstruct) || + (idl_typeSpecType (typeSpec) == idl_tunion) || + (idl_typeSpecType (typeSpec) == idl_tenum)) { + snprintf(typeName, sizeof(typeName), "%s", tname); + } else { + printf ("idl_unionCaseTypeFromTypeSpec: Unexpected type %d\n", + idl_typeSpecType(typeSpec)); + } + } + + os_free(tname); + + return os_strdup(typeName); +} + + + /** @brief callback function called on definition of a union in the IDL input file. * * Generate code for the following IDL construct: @@ -418,6 +688,7 @@ idl_unionOpen( { char *unionTypeName, *discrTypeName; SACSTypeUserData* csUserData = (SACSTypeUserData *) userData; + SACSUnionMetaDescription *umd = NULL; if (idl_definitionExists("definition", idl_scopeStack (scope, ".", name))) { return idl_abort; @@ -425,19 +696,23 @@ idl_unionOpen( idl_definitionAdd("definition", idl_scopeStack (scope, ".", name)); unionTypeName = idl_CsharpId(name, csUserData->customPSM, FALSE); - discrTypeName = idl_CsharpTypeFromTypeSpec( - idl_typeUnionSwitchKind(unionSpec), - csUserData->customPSM); + discrTypeName = idl_CsharpTypeFromTypeSpec(idl_typeUnionSwitchKind(unionSpec), csUserData->customPSM); + + umd = os_malloc(sizeof(SACSUnionMetaDescription)); + memset(umd, 0, sizeof(SACSUnionMetaDescription)); + umd->unionCaseMap = idl_mapNew(NULL, 1, 1); + umd->unionCaseOffset = (idl_typeSpecDef(idl_typeUnionSwitchKind(unionSpec))->size > 4) ? 8 : 4; + umd->unionSwitchType = os_strdup(discrTypeName); + umd->labelsUsedIter = os_iterNew(NULL); + csUserData->typeStack = c_iterInsert(csUserData->typeStack, umd); /* Generate the C# code that opens a sealed class. */ idl_printIndent(indent_level); idl_fileOutPrintf(idl_fileCur(), "#region %s\n", unionTypeName); idl_printIndent(indent_level); - idl_fileOutPrintf(idl_fileCur(), "[StructLayout(LayoutKind.Explicit)]\n"); + idl_fileOutPrintf(idl_fileCur(), "[StructLayout(LayoutKind.Sequential)]\n"); idl_printIndent(indent_level); - idl_fileOutPrintf( - idl_fileCur(), - "public sealed struct %s\n", unionTypeName); + idl_fileOutPrintf(idl_fileCur(), "public sealed class %s\n", unionTypeName); idl_printIndent(indent_level); idl_fileOutPrintf(idl_fileCur(), "{\n"); @@ -446,23 +721,17 @@ idl_unionOpen( /* Generate the discriminator and its getter property. */ idl_printIndent(indent_level); - idl_fileOutPrintf(idl_fileCur(),"[FieldOffset(0)]\n"); + idl_fileOutPrintf(idl_fileCur(), "private %s _d;\n", discrTypeName); idl_printIndent(indent_level); - idl_fileOutPrintf( - idl_fileCur(), - "private %s _d;\n", - discrTypeName); + idl_fileOutPrintf(idl_fileCur(), "private _Fields _u;\n\n"); idl_printIndent(indent_level); - idl_fileOutPrintf( - idl_fileCur(), - "public %s Discriminator\n", - discrTypeName); + idl_fileOutPrintf(idl_fileCur(), "public %s Discriminator\n", discrTypeName); idl_printIndent(indent_level); idl_fileOutPrintf(idl_fileCur(),"{\n"); idl_printIndent(++indent_level); idl_fileOutPrintf(idl_fileCur(), "get { return _d; }\n"); idl_printIndent(--indent_level); - idl_fileOutPrintf(idl_fileCur(),"}\n"); + idl_fileOutPrintf(idl_fileCur(),"}\n\n"); os_free(discrTypeName); os_free(unionTypeName); @@ -471,6 +740,7 @@ idl_unionOpen( return idl_explore; } + /** @brief callback function called on closure of a union in the IDL input file. * * Generate code for the following IDL construct: @@ -499,15 +769,104 @@ idl_unionClose ( const char *name, void *userData) { - OS_UNUSED_ARG(name); - OS_UNUSED_ARG(userData); + SACSTypeUserData* csUserData = (SACSTypeUserData *) userData; + SACSUnionMetaDescription *umd; + char *unionTypeName; + char *labelImage; + char *tName; + idl_mapIter mapIter; + + unionTypeName = idl_CsharpId(name, csUserData->customPSM, FALSE); + umd = (SACSUnionMetaDescription *) c_iterTakeFirst(csUserData->typeStack); + + assert(umd->union1stCaseType); + assert(umd->union1stCaseValue); + assert(umd->union1stCaseIdent); + + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "public %s () {\n", unionTypeName); + + idl_printIndent(indent_level); + if (idl_typeSpecType(umd->union1stCaseType) == idl_tbasic) { + /* generate code for a standard empty ("") string. */ + if (idl_typeBasicType(idl_typeBasic (umd->union1stCaseType)) == idl_string) { + idl_fileOutPrintf(idl_fileCur(), " _u.%s = \"\";\n", umd->union1stCaseIdent); + } else if (idl_typeBasicType(idl_typeBasic (umd->union1stCaseType)) == idl_boolean) { + idl_fileOutPrintf(idl_fileCur(), " _u.%s = false;\n", umd->union1stCaseIdent); + } else if (idl_typeBasicType(idl_typeBasic (umd->union1stCaseType)) == idl_char) { + idl_fileOutPrintf(idl_fileCur(), " _u.%s = '\\0';\n", umd->union1stCaseIdent); + } else { + idl_fileOutPrintf(idl_fileCur(), " _u.%s = 0;\n", umd->union1stCaseIdent); + } + } else if (idl_typeSpecType(umd->union1stCaseType) == idl_tseq || + idl_typeSpecType(umd->union1stCaseType) == idl_tarray) { + char *str_idx = idl_arrayCsharpIndexString (umd->union1stCaseType, SACS_INCLUDE_INDEXES); + assert (str_idx); + + tName = idl_CsharpTypeFromTypeSpec(umd->union1stCaseType, csUserData->customPSM); + idl_fileOutPrintf(idl_fileCur(), " _u.%s = new %s%s", umd->union1stCaseIdent, tName, str_idx); + idl_fileOutPrintf(idl_fileCur(), ";\n"); + idl_arrayInitializeElements(umd->union1stCaseType, umd->union1stCaseIdent, csUserData->customPSM); + os_free(tName); + os_free(str_idx); + } else if (idl_typeSpecType(umd->union1stCaseType) == idl_tstruct || + idl_typeSpecType(umd->union1stCaseType) == idl_tunion) { + tName = idl_CsharpTypeFromTypeSpec(umd->union1stCaseType, csUserData->customPSM); + idl_fileOutPrintf(idl_fileCur(), " _u.%s = new %s();\n", umd->union1stCaseIdent, tName); + os_free(tName); + } else if (idl_typeSpecType(umd->union1stCaseType) == idl_tenum) { + tName = idl_CsharpTypeFromTypeSpec(umd->union1stCaseType, csUserData->customPSM); + idl_fileOutPrintf(idl_fileCur(), " _u.%s = (%s)0;\n", umd->union1stCaseIdent, tName); + os_free(tName); + } + + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), " _d = (%s)%s;\n", umd->unionSwitchType, umd->union1stCaseValue); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "}\n\n"); + + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "[StructLayout(LayoutKind.Sequential)]\n"); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "struct _Fields\n"); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "{\n"); + + mapIter = idl_mapFirst(umd->unionCaseMap); + while (idl_mapIterObject(mapIter)) { + char *tName = idl_mapIterObject(mapIter); + char *fName = idl_mapIterKey(mapIter); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), " public %s %s;\n", tName, fName); + idl_mapIterNext(mapIter); + } + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "}\n"); + + idl_mapIterFree(mapIter); + idl_mapFree(umd->unionCaseMap); indent_level--; - idl_printIndent(indent_level); idl_fileOutPrintf(idl_fileCur(), "} _u;\n"); - indent_level--; - idl_printIndent(indent_level); idl_fileOutPrintf(idl_fileCur(), "};\n\n"); + idl_printIndent(indent_level); idl_fileOutPrintf(idl_fileCur(), "};\n"); + idl_printIndent(indent_level); idl_fileOutPrintf(idl_fileCur(), "#endregion\n\n"); + + os_free(unionTypeName); + os_free(umd->union1stCaseValue); + os_free(umd->union1stCaseIdent); + if (umd->unionSwitchType) { + os_free(umd->unionSwitchType); + } + + labelImage = os_iterTakeFirst(umd->labelsUsedIter); + while (labelImage) { + os_free(labelImage); + labelImage = os_iterTakeFirst(umd->labelsUsedIter); + } + os_iterFree(umd->labelsUsedIter); + os_free(umd); } + /** @brief callback function called on definition of a union case in the IDL input file. * * Generate code for the following IDL construct: @@ -535,12 +894,304 @@ idl_unionCaseOpenClose( idl_typeSpec typeSpec, void *userData) { + SACSTypeUserData* csUserData = (SACSTypeUserData *) userData; + SACSUnionMetaDescription *umd; + char *caseTypename; + char *caseField; + c_ulong nrElements, i; + char *labelImage; + OS_UNUSED_ARG(scope); - OS_UNUSED_ARG(name); - OS_UNUSED_ARG(typeSpec); - OS_UNUSED_ARG(userData); + + caseTypename = idl_unionCaseTypeFromTypeSpec(typeSpec, csUserData->customPSM); + caseField = idl_CsharpId(name, csUserData->customPSM, FALSE); + + umd = (SACSUnionMetaDescription *) c_iterObject(csUserData->typeStack, 0); + idl_mapAdd(umd->unionCaseMap, os_strdup(caseField), os_strdup(caseTypename)); + + nrElements = os_iterLength(umd->labelIter); + labelImage = os_iterObject(umd->labelIter, 0); + + if (!umd->union1stCaseType) { + umd->union1stCaseType = typeSpec; + umd->union1stCaseValue = os_strdup(os_iterObject(umd->labelIter, 0)); + umd->union1stCaseIdent = os_strdup(caseField); + } + + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "public %s %s ()\n", caseTypename, caseField); + + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "{\n"); + idl_printIndent(indent_level); + if (umd->caseIsDefault == FALSE) { + idl_fileOutPrintf(idl_fileCur(), " if (_d != (%s)%s", umd->unionSwitchType, labelImage); + for (i = 1; i < nrElements; i++) { + labelImage = os_iterObject(umd->labelIter, i); + idl_fileOutPrintf(idl_fileCur(), " &&\n"); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), " _d != (%s)%s", umd->unionSwitchType, labelImage); + } + idl_fileOutPrintf(idl_fileCur(), ") {\n"); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), " throw new System.InvalidOperationException();\n"); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), " }\n"); + } else { + if(os_iterLength(umd->labelsUsedIter)) { + labelImage = os_iterObject(umd->labelsUsedIter, 0); + idl_fileOutPrintf(idl_fileCur(), " if (_d == (%s)%s", umd->unionSwitchType, labelImage); + nrElements = os_iterLength(umd->labelsUsedIter); + for (i = 1; i < nrElements; i++) { + labelImage = os_iterObject(umd->labelsUsedIter, i); + idl_fileOutPrintf(idl_fileCur(), " ||\n"); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), " _d == (%s)%s", umd->unionSwitchType, labelImage); + } + idl_fileOutPrintf(idl_fileCur(), ") {\n"); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), " throw new System.InvalidOperationException();\n"); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), " }\n"); + } + } + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), " return _u.%s;\n", caseField); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "}\n\n"); + + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "public void %s (%s val)\n", caseField, caseTypename); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "{\n"); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), " _u.%s = val;\n", caseField); + labelImage = os_iterObject(umd->labelIter, 0); + idl_printIndent(indent_level); + assert(labelImage); + idl_fileOutPrintf(idl_fileCur(), " _d = (%s)%s;\n", umd->unionSwitchType, labelImage); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "}\n\n"); + + if (nrElements > 1) { + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "public void %s (%s d, %s val)\n", caseField, umd->unionSwitchType, caseTypename); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "{\n"); + idl_printIndent(indent_level); + if (umd->caseIsDefault == FALSE) { + labelImage = os_iterTakeFirst(umd->labelIter); + idl_fileOutPrintf(idl_fileCur(), " if (d != (%s)%s", umd->unionSwitchType, labelImage); + os_free(labelImage); + labelImage = os_iterTakeFirst(umd->labelIter); + while (labelImage) { + idl_fileOutPrintf(idl_fileCur(), " &&\n"); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), " d != (%s)%s", umd->unionSwitchType, labelImage); + os_free(labelImage); + labelImage = os_iterTakeFirst (umd->labelIter); + } + idl_fileOutPrintf(idl_fileCur(), ") {\n"); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), " throw new System.InvalidOperationException();\n"); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), " }\n"); + } else { + if(os_iterLength(umd->labelsUsedIter)) { + labelImage = os_iterTakeFirst(umd->labelsUsedIter); + idl_fileOutPrintf(idl_fileCur(), " if (d == (%s)%s", umd->unionSwitchType, labelImage); + os_free(labelImage); + labelImage = os_iterTakeFirst(umd->labelsUsedIter); + while (labelImage) { + idl_fileOutPrintf(idl_fileCur(), " ||\n"); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), " d == (%s)%s", umd->unionSwitchType, labelImage); + os_free(labelImage); + labelImage = os_iterTakeFirst(umd->labelsUsedIter); + } + idl_fileOutPrintf(idl_fileCur(), ") {\n"); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), " throw new System.InvalidOperationException();\n"); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), " }\n"); + } + } + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), " _u.%s = val;\n", caseField); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), " _d = d;\n"); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "}\n\n"); + } + + os_free(caseTypename); + os_free(caseField); + + labelImage = os_iterTakeFirst(umd->labelIter); + while (labelImage) { + os_free(labelImage); + labelImage = os_iterTakeFirst(umd->labelIter); + } + os_iterFree(umd->labelIter); + umd->labelIter = NULL; +} + +/** @brief callback function called on definition of the union case labels in the IDL input file. + * + * Generate code for the following IDL construct: + * @verbatim + union switch() { + => case label1.1; .. case label1.n; + ; + => case label2.1; .. case label2.n; + ... ... + => case labeln.1; .. case labeln.n; + ; + default: + ; + }; + @endverbatim + * + * @param scope Current scope (the union the labels are defined in) + * @param labelSpec Specifies the number of labels of the union case + */ +static void +idl_unionLabelOpenClose( + idl_scope ownScope, + idl_labelVal labelVal, + void *userData) +{ + SACSTypeUserData* csUserData = (SACSTypeUserData *) userData; + SACSUnionMetaDescription *umd; + + OS_UNUSED_ARG(ownScope); + + umd = (SACSUnionMetaDescription *) c_iterObject(csUserData->typeStack, 0); + if (idl_labelValType(labelVal) != idl_ldefault) { + umd->caseIsDefault = FALSE; + umd->labelIter = os_iterAppend(umd->labelIter, idl_valueFromLabelVal(labelVal, umd, csUserData->customPSM)); + umd->labelsUsedIter = os_iterAppend(umd->labelsUsedIter, idl_valueFromLabelVal(labelVal, umd, csUserData->customPSM)); + } else { + umd->caseIsDefault = TRUE; + umd->labelIter = os_iterAppend(umd->labelIter, + idl_valueFromLabelVal(idl_labelDefaultAlternative(idl_labelDefault(labelVal)), umd, csUserData->customPSM)); + } } +/** @brief callback function called on definition of the union case labels in the IDL input file. + * + * Generate code for the following IDL construct: + * @verbatim + union switch() { + => case label1.1; .. case label1.n; + ; + => case label2.1; .. case label2.n; + ... ... + => case labeln.1; .. case labeln.n; + ; + default: + ; + }; + @endverbatim + * + * @param scope Current scope (the union the labels are defined in) + * @param labelSpec Specifies the number of labels of the union case + */ +static void +idl_unionLabelsOpenClose( + idl_scope scope, + idl_labelSpec labelSpec, + void *userData) +{ + SACSTypeUserData* csUserData = (SACSTypeUserData *) userData; + SACSUnionMetaDescription *umd; + + OS_UNUSED_ARG(scope); + OS_UNUSED_ARG(labelSpec); + + umd = (SACSUnionMetaDescription *) c_iterObject(csUserData->typeStack, 0); + umd->labelIter = os_iterNew(NULL); +} + + +/** @brief callback function called when no default case is defined in an union + * for which not all possible label values are specified + * + * Generate code for the following IDL construct: + * @verbatim + union switch() { + case label1.1; .. case label1.n; + ; + case label2.1; .. case label2.n; + ... ... + case labeln.1; .. case labeln.n; + ; + }; + @endverbatim + * + * @param scope Current scope (the union the union case is defined in) + * @param labelVal Default value for the label case (lowest possible not used index) + * @param typeSpec Specifies the type of the union switch + */ +static void +idl_artificialDefaultLabelOpenClose( + idl_scope scope, + idl_labelVal labelVal, + idl_typeSpec typeSpec, + void *userData) +{ + SACSTypeUserData* csUserData = (SACSTypeUserData *) userData; + SACSUnionMetaDescription *umd; + char *caseTypename; + char *labelImage; + + OS_UNUSED_ARG(scope); + + umd = (SACSUnionMetaDescription *) c_iterObject(csUserData->typeStack, 0); + caseTypename = idl_unionCaseTypeFromTypeSpec(typeSpec, csUserData->customPSM); + + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "public void Default ()\n"); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "{\n"); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), " _d = (%s)%s;\n", umd->unionSwitchType, + idl_valueFromLabelVal(labelVal, umd, csUserData->customPSM)); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "}\n\n"); + + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "public void Default (%s d)\n", caseTypename); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "{\n"); + + idl_printIndent(indent_level); + if(os_iterLength(umd->labelsUsedIter)) { + labelImage = os_iterTakeFirst(umd->labelsUsedIter); + idl_fileOutPrintf(idl_fileCur(), " if (d == (%s)%s", umd->unionSwitchType, labelImage); + labelImage = os_iterTakeFirst(umd->labelsUsedIter); + while (labelImage) { + idl_fileOutPrintf(idl_fileCur(), " ||\n"); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), " d == (%s)%s", umd->unionSwitchType, labelImage); + labelImage = os_iterTakeFirst(umd->labelsUsedIter); + } + idl_fileOutPrintf(idl_fileCur(), ") {\n"); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), " throw new System.InvalidOperationException();\n"); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), " }\n"); + } + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), " _d = d;\n"); + idl_printIndent(indent_level); + idl_fileOutPrintf(idl_fileCur(), "}\n\n"); + + os_free(caseTypename); +} + + + /** @brief callback function called on definition of an enumeration. * * Generate code for the following IDL construct: @@ -682,21 +1333,26 @@ idl_constantOpenClose ( void *userData) { SACSTypeUserData* csUserData = (SACSTypeUserData *) userData; + char *constName = idl_constSpecName(constantSpec); char *constTypeName = idl_CsharpTypeFromTypeSpec( idl_constSpecTypeGet(constantSpec), csUserData->customPSM); - OS_UNUSED_ARG(scope); + char *constSpecImage = idl_constSpecImage(constantSpec); OS_UNUSED_ARG(scope); idl_printIndent(indent_level); idl_fileOutPrintf( idl_fileCur(), - "public struct %s { public static readonly %s value = %s; }\n\n", - idl_constSpecName(constantSpec), + "public struct %s { public static readonly %s value = (%s) %s; }\n\n", + constName, constTypeName, - idl_constSpecImage(constantSpec)); + constTypeName, + constSpecImage); + + os_free(constSpecImage); os_free(constTypeName); + os_free(constName); } /** @@ -705,7 +1361,7 @@ idl_constantOpenClose ( * type itself in contrast with inline. */ static idl_programControl idl_genSACSLoadControl = { - idl_prior + idl_inline }; /** @brief return the program control structure for the splice type generation functions. @@ -743,13 +1399,13 @@ idl_genSACSTypeProgram( idl_genSACSType.unionOpen = idl_unionOpen; idl_genSACSType.unionClose = idl_unionClose; idl_genSACSType.unionCaseOpenClose = idl_unionCaseOpenClose; - idl_genSACSType.unionLabelsOpenClose = NULL; - idl_genSACSType.unionLabelOpenClose = NULL; + idl_genSACSType.unionLabelsOpenClose = idl_unionLabelsOpenClose; + idl_genSACSType.unionLabelOpenClose = idl_unionLabelOpenClose; idl_genSACSType.typedefOpenClose = NULL; idl_genSACSType.boundedStringOpenClose = NULL; idl_genSACSType.sequenceOpenClose = NULL; idl_genSACSType.constantOpenClose = idl_constantOpenClose; - idl_genSACSType.artificialDefaultLabelOpenClose = NULL; + idl_genSACSType.artificialDefaultLabelOpenClose = idl_artificialDefaultLabelOpenClose; idl_genSACSType.userData = userData; return &idl_genSACSType; diff --git a/src/tools/idlpp/code/idl_genSACSType.h b/src/tools/idlpp/code/idl_genSACSType.h index 79d21e2d3..549a0a6b1 100644 --- a/src/tools/idlpp/code/idl_genSACSType.h +++ b/src/tools/idlpp/code/idl_genSACSType.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,14 +22,8 @@ #define IDL_GENSACSTYPE_H #include "idl_program.h" - -struct SACSTypeUserData_s { - os_iter idlpp_metaList; - c_char *tmplPrefix; - c_bool customPSM; -}; - -typedef struct SACSTypeUserData_s SACSTypeUserData; +#include "c_iterator.h" +#include "idl_genSACSHelper.h" idl_program idl_genSACSTypeProgram(SACSTypeUserData *userData); diff --git a/src/tools/idlpp/code/idl_genSACSTypedClassDefs.c b/src/tools/idlpp/code/idl_genSACSTypedClassDefs.c index b98bf8572..7002a12b7 100644 --- a/src/tools/idlpp/code/idl_genSACSTypedClassDefs.c +++ b/src/tools/idlpp/code/idl_genSACSTypedClassDefs.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -55,7 +56,7 @@ idl_fileOpen( c_char *tmplPath; c_char *orbPath; int tmplFile; - struct os_stat tmplStat; + struct os_stat_s tmplStat; unsigned int nRead; SACSTypeUserData* csUserData = (SACSTypeUserData *) userData; OS_UNUSED_ARG(scope); @@ -189,12 +190,14 @@ idl_structureOpen( c_char spaces[128]; idl_tmplExp te; SACSTypeUserData* csUserData = (SACSTypeUserData *) userData; + c_type structType = idl_typeSpecDef(idl_typeSpec(structSpec)); char *scopeName = idl_CsharpId( idl_scopeElementName(idl_scopeCur(scope)), csUserData->customPSM, FALSE); char *structName = idl_CsharpId(name, csUserData->customPSM, FALSE); char *scopedTypeName = idl_scopeStack(scope, "::", name); + char *dbTypeName = idl_CsharpScopeStackFromCType(structType, csUserData->customPSM, TRUE, FALSE); const char *internalTypeName = idl_internalTypeNameForBuiltinTopic(scopedTypeName); const char *keyList = idl_keyResolve(idl_keyDefDefGet(), scope, name); if ((strlen(internalTypeName) != 0) && @@ -207,6 +210,7 @@ idl_structureOpen( te = idl_tmplExpNew(idlpp_macroSet); idl_macroSetAdd(idlpp_macroSet, idl_macroNew("scope", scopeName)); idl_macroSetAdd(idlpp_macroSet, idl_macroNew("typename", structName)); + idl_macroSetAdd(idlpp_macroSet, idl_macroNew("dbTypename", dbTypeName)); idl_macroSetAdd( idlpp_macroSet, idl_macroNew("scoped-meta-type-name", scopedTypeName)); @@ -228,9 +232,10 @@ idl_structureOpen( idl_streamInFree(idlpp_inStream); idl_tmplExpFree(te); + os_free(dbTypeName); os_free(scopedTypeName); - os_free(scopeName); os_free(structName); + os_free(scopeName); } return idl_abort; } diff --git a/src/tools/idlpp/code/idl_genSACSTypedClassDefs.h b/src/tools/idlpp/code/idl_genSACSTypedClassDefs.h index ee05d3076..ca39c69db 100644 --- a/src/tools/idlpp/code/idl_genSACSTypedClassDefs.h +++ b/src/tools/idlpp/code/idl_genSACSTypedClassDefs.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/idlpp/code/idl_genSacHelper.c b/src/tools/idlpp/code/idl_genSacHelper.c index 725a6e64b..8230ed3d5 100644 --- a/src/tools/idlpp/code/idl_genSacHelper.c +++ b/src/tools/idlpp/code/idl_genSacHelper.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -30,22 +31,22 @@ static c_char *idl_scopedSacSequenceTypeIdent (const idl_typeSpec typeSpec); /** @todo Correct comment */ /* Return the scoped type specification where for the user types, - scopes are separated by "_" chracters. - IDL strings (bounded and unbounded) are mapped on: c_string, other - basic types are mapped on corresponding splice types - IDL structures are identified by: struct - IDL unions are identified by: struct becuase - the union mapping is: - struct { - _d; - union { - - } _u; - } - IDL enumerations are identified by: enum - IDL typedefs are formed by the scoped type name - IDL sequences are mapped on: c_sequence -*/ + * scopes are separated by "_" chracters. + * IDL strings (bounded and unbounded) are mapped on: c_string, other + * basic types are mapped on corresponding splice types + * IDL structures are identified by: struct + * IDL unions are identified by: struct becuase + * the union mapping is: + * struct { + * _d; + * union { + * + * } _u; + * } + * IDL enumerations are identified by: enum + * IDL typedefs are formed by the scoped type name + * IDL sequences are mapped on: c_sequence + */ c_char * idl_scopedSacTypeIdent ( const idl_typeSpec typeSpec) @@ -79,123 +80,107 @@ idl_scopedSacTypeIdent ( } /* Return the scoped actual type specification where for the user types, - scopes are separated by "_" chracters. - IDL strings (bounded and unbounded) are mapped on: c_string, other - basic types are mapped on corresponding splice types - IDL structures are identified by: struct - IDL unions are identified by: struct becuase - the union mapping is: - struct { - _d; - union { - - } _u; - } - IDL enumerations are identified by: enum - IDL typedefs are formed by the scoped type name - IDL sequences are mapped on: c_sequence -*/ + * scopes are separated by "_" chracters. + * IDL strings (bounded and unbounded) are mapped on: c_string, other + * basic types are mapped on corresponding splice types + * IDL structures are identified by: struct + * IDL unions are identified by: struct becuase + * the union mapping is: + * struct { + * _d; + * union { + * + * } _u; + * } + * IDL enumerations are identified by: enum + * IDL typedefs are formed by the scoped type name + * IDL sequences are mapped on: c_sequence + */ static c_char * idl_scopedSacSequenceElementTypeIdent ( const idl_typeSpec typeSpec) { - c_char scopedTypeIdent[256]; + c_char *typeName; /* QAC EXPECT 3416; No unexpected side effects here */ if (idl_typeSpecType(typeSpec) == idl_tbasic) { - switch (idl_typeBasicType(idl_typeBasic(typeSpec))) { - case idl_short: - snprintf (scopedTypeIdent, sizeof(scopedTypeIdent), "DDS_short"); - break; - case idl_ushort: - snprintf (scopedTypeIdent, sizeof(scopedTypeIdent), "DDS_unsigned_short"); - break; - case idl_long: - snprintf (scopedTypeIdent, sizeof(scopedTypeIdent), "DDS_long"); - break; - case idl_ulong: - snprintf (scopedTypeIdent, sizeof(scopedTypeIdent), "DDS_unsigned_long"); - break; - case idl_longlong: - snprintf (scopedTypeIdent, sizeof(scopedTypeIdent), "DDS_long_long"); - break; - case idl_ulonglong: - snprintf (scopedTypeIdent, sizeof(scopedTypeIdent), "DDS_unsigned_long_long"); - break; - case idl_float: - snprintf (scopedTypeIdent, sizeof(scopedTypeIdent), "DDS_float"); - break; - case idl_double: - snprintf (scopedTypeIdent, sizeof(scopedTypeIdent), "DDS_double"); - break; - case idl_char: - snprintf (scopedTypeIdent, sizeof(scopedTypeIdent), "DDS_char"); - break; - case idl_string: - snprintf (scopedTypeIdent, sizeof(scopedTypeIdent), "DDS_string"); - break; - case idl_boolean: - snprintf (scopedTypeIdent, sizeof(scopedTypeIdent), "DDS_boolean"); - break; - case idl_octet: - snprintf (scopedTypeIdent, sizeof(scopedTypeIdent), "DDS_octet"); - break; - default: - os_strncpy (scopedTypeIdent, "", sizeof(scopedTypeIdent)); - } + switch (idl_typeBasicType(idl_typeBasic(typeSpec))) { + case idl_short: + typeName = os_strdup("DDS_short"); + break; + case idl_ushort: + typeName = os_strdup("DDS_unsigned_short"); + break; + case idl_long: + typeName = os_strdup("DDS_long"); + break; + case idl_ulong: + typeName = os_strdup("DDS_unsigned_long"); + break; + case idl_longlong: + typeName = os_strdup("DDS_long_long"); + break; + case idl_ulonglong: + typeName = os_strdup("DDS_unsigned_long_long"); + break; + case idl_float: + typeName = os_strdup("DDS_float"); + break; + case idl_double: + typeName = os_strdup("DDS_double"); + break; + case idl_char: + typeName = os_strdup("DDS_char"); + break; + case idl_string: + typeName = os_strdup("DDS_string"); + break; + case idl_boolean: + typeName = os_strdup("DDS_boolean"); + break; + case idl_octet: + typeName = os_strdup("DDS_octet"); + break; + default: + typeName = os_strdup(""); + } } else if (idl_typeSpecType(typeSpec) == idl_tstruct || - idl_typeSpecType(typeSpec) == idl_tunion || - idl_typeSpecType(typeSpec) == idl_tenum) { - /* QAC EXPECT 3416; No unexpected side effects here */ - snprintf (scopedTypeIdent, sizeof(scopedTypeIdent), "%s", - idl_sacTypeFromTypeSpec(idl_typeSpec(typeSpec))); + idl_typeSpecType(typeSpec) == idl_tunion || + idl_typeSpecType(typeSpec) == idl_tenum) { + /* QAC EXPECT 3416; No unexpected side effects here */ + typeName = idl_sacTypeFromTypeSpec(idl_typeSpec(typeSpec)); /* QAC EXPECT 3416; No unexpected side effects here */ } else if (idl_typeSpecType(typeSpec) == idl_ttypedef) { - switch (idl_typeSpecType(idl_typeDefRefered (idl_typeDef(typeSpec)))) { - case idl_tarray: - case idl_tseq: - snprintf (scopedTypeIdent, sizeof(scopedTypeIdent), "%s", - idl_sacTypeFromTypeSpec(typeSpec)); - break; - case idl_ttypedef: - snprintf (scopedTypeIdent, sizeof(scopedTypeIdent), "%s", - idl_scopedSacSequenceTypeIdent(idl_typeDefRefered (idl_typeDef(typeSpec)))); - break; - default: - snprintf (scopedTypeIdent, sizeof(scopedTypeIdent), "%s", - idl_sacTypeFromTypeSpec(idl_typeDefActual(idl_typeDef(typeSpec)))); - } - /* QAC EXPECT 3416; No unexpected side effects here */ + typeName = idl_sacTypeFromTypeSpec(typeSpec); + /* QAC EXPECT 3416; No unexpected side effects here */ } else if (idl_typeSpecType(typeSpec) == idl_tarray) { - snprintf (scopedTypeIdent, sizeof(scopedTypeIdent), "%s", - idl_scopedSacSequenceTypeIdent (idl_typeArrayActual(idl_typeArray(typeSpec)))); + typeName = idl_scopedSacSequenceTypeIdent (idl_typeArrayActual(idl_typeArray(typeSpec))); } else if (idl_typeSpecType(typeSpec) == idl_tseq) { - snprintf (scopedTypeIdent, sizeof(scopedTypeIdent), "%s", - idl_sequenceIdent(idl_typeSeq(typeSpec))); + typeName = idl_sequenceIdent(idl_typeSeq(typeSpec)); } else { - /* Do nothing, only to prevent dangling else-ifs QAC messages */ + typeName = NULL; } - return os_strdup(scopedTypeIdent); + return typeName; } /* Return the scoped actual type specification where for the user types, - scopes are separated by "_" characters. - IDL strings (bounded and unbounded) are mapped on: c_string, other - basic types are mapped on corresponding splice types - IDL structures are identified by: struct - IDL unions are identified by: struct because - the union mapping is: - struct { - _d; - union { - - } _u; - } - IDL enumerations are identified by: enum - IDL typedefs are formed by the scoped type name - IDL sequences are mapped on: c_sequence -*/ + * scopes are separated by "_" characters. + * IDL strings (bounded and unbounded) are mapped on: c_string, other + * basic types are mapped on corresponding splice types + * IDL structures are identified by: struct + * IDL unions are identified by: struct because + * the union mapping is: + * struct { + * _d; + * union { + * + * } _u; + * } + * IDL enumerations are identified by: enum + * IDL typedefs are formed by the scoped type name + * IDL sequences are mapped on: c_sequence + */ static c_char * idl_scopedSacSequenceSubElementTypeIdent ( const idl_typeSpec typeSpec) @@ -281,7 +266,7 @@ idl_scopedSacSequenceSubElementTypeIdent ( } /* Return the scoped actual type specification where for the user types, - scopes are separated by "_" chracters. + scopes are separated by "_" chracters. IDL strings (bounded and unbounded) are mapped on: c_string, other basic types are mapped on corresponding splice types IDL structures are identified by: struct @@ -305,77 +290,63 @@ idl_scopedSacSequenceTypeIdent ( /* QAC EXPECT 3416; No unexpected side effects here */ if (idl_typeSpecType(typeSpec) == idl_tbasic) { - switch (idl_typeBasicType(idl_typeBasic(typeSpec))) { - case idl_short: - snprintf (scopedTypeIdent, sizeof(scopedTypeIdent), "short"); - break; - case idl_ushort: - snprintf (scopedTypeIdent, sizeof(scopedTypeIdent), "unsigned_short"); - break; - case idl_long: - snprintf (scopedTypeIdent, sizeof(scopedTypeIdent), "long"); - break; - case idl_ulong: - snprintf (scopedTypeIdent, sizeof(scopedTypeIdent), "unsigned_long"); - break; - case idl_longlong: - snprintf (scopedTypeIdent, sizeof(scopedTypeIdent), "long_long"); - break; - case idl_ulonglong: - snprintf (scopedTypeIdent, sizeof(scopedTypeIdent), "unsigned_long_long"); - break; - case idl_float: - snprintf (scopedTypeIdent, sizeof(scopedTypeIdent), "float"); - break; - case idl_double: - snprintf (scopedTypeIdent, sizeof(scopedTypeIdent), "double"); - break; - case idl_char: - snprintf (scopedTypeIdent, sizeof(scopedTypeIdent), "char"); - break; - case idl_string: - snprintf (scopedTypeIdent, sizeof(scopedTypeIdent), "string"); - break; - case idl_boolean: - snprintf (scopedTypeIdent, sizeof(scopedTypeIdent), "boolean"); - break; - case idl_octet: - snprintf (scopedTypeIdent, sizeof(scopedTypeIdent), "octet"); - break; - default: - os_strncpy (scopedTypeIdent, "", sizeof(scopedTypeIdent)); - } - } else if (idl_typeSpecType(typeSpec) == idl_tstruct || - idl_typeSpecType(typeSpec) == idl_tunion || - idl_typeSpecType(typeSpec) == idl_tenum) { - /* QAC EXPECT 3416; No unexpected side effects here */ - snprintf (scopedTypeIdent, sizeof(scopedTypeIdent), "%s", - idl_sacTypeFromTypeSpec(idl_typeSpec(typeSpec))); - /* QAC EXPECT 3416; No unexpected side effects here */ - } else if (idl_typeSpecType(typeSpec) == idl_ttypedef) { - switch (idl_typeSpecType(idl_typeDefRefered (idl_typeDef(typeSpec)))) { - case idl_tarray: - case idl_tseq: - snprintf (scopedTypeIdent, sizeof(scopedTypeIdent), "%s", - idl_sacTypeFromTypeSpec(typeSpec)); - break; - case idl_ttypedef: - snprintf (scopedTypeIdent, sizeof(scopedTypeIdent), "%s", - idl_scopedSacSequenceTypeIdent(idl_typeDefRefered (idl_typeDef(typeSpec)))); - break; - default: - snprintf (scopedTypeIdent, sizeof(scopedTypeIdent), "%s", - idl_sacTypeFromTypeSpec(idl_typeDefActual(idl_typeDef(typeSpec)))); - } - /* QAC EXPECT 3416; No unexpected side effects here */ - } else if (idl_typeSpecType(typeSpec) == idl_tarray) { - snprintf (scopedTypeIdent, sizeof(scopedTypeIdent), "%s", - idl_scopedSacSequenceTypeIdent (idl_typeArrayActual(idl_typeArray(typeSpec)))); - } else if (idl_typeSpecType(typeSpec) == idl_tseq) { - snprintf (scopedTypeIdent, sizeof(scopedTypeIdent), "%s", - idl_sequenceIdent(idl_typeSeq(typeSpec))); + switch (idl_typeBasicType(idl_typeBasic(typeSpec))) { + case idl_short: + snprintf (scopedTypeIdent, sizeof(scopedTypeIdent), "short"); + break; + case idl_ushort: + snprintf (scopedTypeIdent, sizeof(scopedTypeIdent), "unsigned_short"); + break; + case idl_long: + snprintf (scopedTypeIdent, sizeof(scopedTypeIdent), "long"); + break; + case idl_ulong: + snprintf (scopedTypeIdent, sizeof(scopedTypeIdent), "unsigned_long"); + break; + case idl_longlong: + snprintf (scopedTypeIdent, sizeof(scopedTypeIdent), "long_long"); + break; + case idl_ulonglong: + snprintf (scopedTypeIdent, sizeof(scopedTypeIdent), "unsigned_long_long"); + break; + case idl_float: + snprintf (scopedTypeIdent, sizeof(scopedTypeIdent), "float"); + break; + case idl_double: + snprintf (scopedTypeIdent, sizeof(scopedTypeIdent), "double"); + break; + case idl_char: + snprintf (scopedTypeIdent, sizeof(scopedTypeIdent), "char"); + break; + case idl_string: + snprintf (scopedTypeIdent, sizeof(scopedTypeIdent), "string"); + break; + case idl_boolean: + snprintf (scopedTypeIdent, sizeof(scopedTypeIdent), "boolean"); + break; + case idl_octet: + snprintf (scopedTypeIdent, sizeof(scopedTypeIdent), "octet"); + break; + default: + os_strncpy (scopedTypeIdent, "", sizeof(scopedTypeIdent)); + } } else { - /* Do nothing, only to prevent dangling else-ifs QAC messages */ + char *typeName = NULL; + + if (idl_typeSpecType(typeSpec) == idl_tstruct || + idl_typeSpecType(typeSpec) == idl_tunion || + idl_typeSpecType(typeSpec) == idl_tenum || + idl_typeSpecType(typeSpec) == idl_ttypedef) { + typeName = idl_sacTypeFromTypeSpec(idl_typeSpec(typeSpec)); + snprintf (scopedTypeIdent, sizeof(scopedTypeIdent), "%s", typeName); + } else if (idl_typeSpecType(typeSpec) == idl_tarray) { + typeName = idl_scopedSacSequenceTypeIdent (idl_typeArrayActual(idl_typeArray(typeSpec))); + snprintf (scopedTypeIdent, sizeof(scopedTypeIdent), "%s", typeName); + } else if (idl_typeSpecType(typeSpec) == idl_tseq) { + typeName = idl_sequenceIdent(idl_typeSeq(typeSpec)); + snprintf (scopedTypeIdent, sizeof(scopedTypeIdent), "%s", typeName); + } + os_free(typeName); } return os_strdup(scopedTypeIdent); @@ -575,7 +546,7 @@ idl_sequenceIdentScoped ( } snprintf (&sequenceName[pos], len, "%s%s", "sequence_", sequenceType); - + os_free(sequenceType); return sequenceName; } @@ -599,13 +570,13 @@ idl_sequenceSupportFunctionsExist ( /* If a type has a related key, that means that readers and * writers have been created, which also means that type * sequence support functions have already been created in - * the other context. */ + * the other context. + */ if (idl_keyDefIncludesType(idl_keyDefDefGet(), elementName)) { exist = TRUE; } - /* - * We should search all scopes of all contexts to be sure that + /* We should search all scopes of all contexts to be sure that * no sequence support functions for this type are defined * anywhere within the hierarchy by means of an actual * 'sequence' definition in an idl file. diff --git a/src/tools/idlpp/code/idl_genSacHelper.h b/src/tools/idlpp/code/idl_genSacHelper.h index de262bf4a..62ffe08ba 100644 --- a/src/tools/idlpp/code/idl_genSacHelper.h +++ b/src/tools/idlpp/code/idl_genSacHelper.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/idlpp/code/idl_genSacMeta.c b/src/tools/idlpp/code/idl_genSacMeta.c index 8cdd02aad..adc79aa75 100644 --- a/src/tools/idlpp/code/idl_genSacMeta.c +++ b/src/tools/idlpp/code/idl_genSacMeta.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -64,7 +65,7 @@ idl_genMeta( c_ulong nrElements; size_t descrLength; int tmplFile; - struct os_stat tmplStat; + struct os_stat_s tmplStat; unsigned int nRead; tmplPath = os_getenv("OSPL_TMPL_PATH"); @@ -80,7 +81,7 @@ idl_genMeta( idlpp_macroSet = idl_macroSetNew(); idl_macroSetAdd(idlpp_macroSet, idl_macroNew("type_name", idl_scopeStackC(meta->scope, "_", meta->name))); - metaXML = idl_genXMLmeta(meta->type); + metaXML = idl_genXMLmeta(meta->type, TRUE); idl_macroSetAdd(idlpp_macroSet, idl_macroNew("meta-descriptor", idl_cutXMLmeta(metaXML, &nrElements, &descrLength))); snprintf(intToStr, MAX_ULONG_STRLENGTH, "%u", nrElements); idl_macroSetAdd(idlpp_macroSet, idl_macroNew("meta-descriptorArrLength", intToStr)); diff --git a/src/tools/idlpp/code/idl_genSacMeta.h b/src/tools/idlpp/code/idl_genSacMeta.h index 20345253c..dc80c35b5 100644 --- a/src/tools/idlpp/code/idl_genSacMeta.h +++ b/src/tools/idlpp/code/idl_genSacMeta.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/idlpp/code/idl_genSacObjectControl.c b/src/tools/idlpp/code/idl_genSacObjectControl.c index 45a1e9888..4f4b86430 100644 --- a/src/tools/idlpp/code/idl_genSacObjectControl.c +++ b/src/tools/idlpp/code/idl_genSacObjectControl.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -135,7 +136,7 @@ idl_inlineBoundedString( return maxlen > 0; } -/* @brief callback function called on opening the IDL input file. +/** @brief callback function called on opening the IDL input file. * * @param scope Current scope (not used) * @param name Name of the IDL input file @@ -1007,8 +1008,7 @@ idl_sequenceOpenClose( sequenceElementName = idl_sequenceElementIdent(idl_typeSeqType(typeSeq)); sequenceName = idl_sequenceIdent(typeSeq); - /* - * The purpose of this function is to create type sequence support functions. + /* The purpose of this function is to create type sequence support functions. * * The type, however, can be in a different file than this sequence. Let's * call that context. The context can be checked by getting the base of a @@ -1032,7 +1032,8 @@ idl_sequenceOpenClose( */ /* Check if current sequence support functions are already defined within - * the current working context. */ + * the current working context. + */ if (idl_definitionExists("objManagImpl", sequenceName)) { createFunctions = FALSE; } else { @@ -1099,7 +1100,9 @@ idl_sequenceOpenClose( idl_fileOutPrintf(idl_fileCur(), " %s *b = (%s *)buffer;\n", sequenceElementName, sequenceElementName); idl_fileOutPrintf(idl_fileCur(), " DDS_unsigned_long i;\n"); - if (idl_typeSpecType(idl_typeSeqType(typeSeq)) == idl_tseq) { + if (idl_typeSpecType(idl_typeSeqType(typeSeq)) == idl_tseq || + ((idl_typeSpecType(idl_typeSeqType(typeSeq)) == idl_ttypedef) && + (idl_typeSpecType(idl_typeDefResolveFully(idl_typeSeqType(typeSeq))) == idl_tseq))) { idl_fileOutPrintf(idl_fileCur(), " for (i = 0; i < *count; i++) {\n"); idl_fileOutPrintf(idl_fileCur(), " DDS_sequence_free ((_DDS_sequence)&b[i]);\n"); idl_fileOutPrintf(idl_fileCur(), " }\n"); @@ -1138,7 +1141,7 @@ idl_sequenceOpenClose( * Standard control structure to specify that inline * type definitions are to be processed prior to the * type itself in contrast with inline. -*/ + */ static idl_programControl idl_genSacLoadControl = { idl_prior }; diff --git a/src/tools/idlpp/code/idl_genSacObjectControl.h b/src/tools/idlpp/code/idl_genSacObjectControl.h index be5f27987..d89ac4965 100644 --- a/src/tools/idlpp/code/idl_genSacObjectControl.h +++ b/src/tools/idlpp/code/idl_genSacObjectControl.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/idlpp/code/idl_genSacType.c b/src/tools/idlpp/code/idl_genSacType.c index 3a8a76631..a30227b64 100644 --- a/src/tools/idlpp/code/idl_genSacType.c +++ b/src/tools/idlpp/code/idl_genSacType.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -117,7 +118,7 @@ idl_fileOpen( return idl_explore; } -/* @brief callback function called on closing the IDL input file. +/** @brief callback function called on closing the IDL input file. * * Generate standard file footer consisting of: * - mutiple inclusion prevention closure @@ -363,6 +364,7 @@ idl_unionOpen( OS_UNUSED_ARG(userData); if (idl_definitionExists("definition", scopedName)) { + os_free(scopedName); return idl_abort; } idl_definitionAdd("definition", scopedName); @@ -581,6 +583,7 @@ idl_enumerationOpen( OS_UNUSED_ARG(userData); if (idl_definitionExists("definition", scopedName)) { + os_free(scopedName); return idl_abort; } idl_definitionAdd("definition", scopedName); @@ -667,7 +670,7 @@ idl_enumerationElementOpenClose ( } } -/* @brief generate dimension of an array +/** @brief generate dimension of an array * * arrayDimensions is a local support function to generate * the array dimensions of an array @@ -684,7 +687,7 @@ idl_arrayDimensions( } } -/* @brief generate dimension of an array slice +/** @brief generate dimension of an array slice * * arraySliceDimensions is a local support function to generate * the array dimensions of an array slice @@ -802,12 +805,14 @@ idl_typedefOpenClose( scopedName); } } else if (idl_typeSpecType(idl_typeDefRefered(defSpec)) == idl_tseq) { + char *sequenceElementIdent = idl_sequenceElementIdent(idl_typeSeqType(idl_typeSeq(idl_typeDefRefered(defSpec)))); + char *sequenceIdent = idl_sequenceIdent(idl_typeSeq(idl_typeDefRefered(defSpec))); /* generate code for a sequence mapping */ idl_printIndent(indent_level); idl_fileOutPrintf( idl_fileCur(), "typedef %s %s;\n", - idl_sequenceIdent(idl_typeSeq(idl_typeDefRefered(defSpec))), + sequenceIdent, scopedName); /* define the prototype of the function allocate the typedefed type */ idl_fileOutPrintf( @@ -821,8 +826,10 @@ idl_typedefOpenClose( idl_fileCur(), "%s %s *%s_allocbuf (DDS_unsigned_long len);\n\n", idl_dllGetMacro(), - idl_sequenceElementIdent(idl_typeSeqType(idl_typeSeq(idl_typeDefRefered(defSpec)))), + sequenceElementIdent, scopedName); + os_free(sequenceElementIdent); + os_free(sequenceIdent); } else { printf ("idl_typedefOpenClose: Unsupported typedef type (typename = %s, type = %s)\n", name, idl_scopedTypeName(idl_typeSpec(defSpec))); @@ -837,9 +844,10 @@ idl_sequenceOpenClose( idl_typeSeq typeSeq, void *userData) { - c_bool genPrototypesOnly = FALSE; + c_bool prototypeExists = FALSE; char *sequenceElementName; char *sequenceName; + char * sequenceScopedName; OS_UNUSED_ARG(userData); @@ -847,99 +855,82 @@ idl_sequenceOpenClose( sequenceName = idl_sequenceIdent(typeSeq); if (idl_definitionExists("definition", sequenceName)) { - os_free(sequenceElementName); - os_free(sequenceName); - return; - } - idl_definitionAdd("definition", sequenceName); - - if (idl_scopeStackSize(scope) > 0) { + prototypeExists = TRUE; + } else { + idl_definitionAdd("definition", sequenceName); if ((idl_typeSpecType(idl_typeSeqType(typeSeq)) == idl_tbasic) && ((idl_typeBasicType(idl_typeBasic(idl_typeSeqType(typeSeq))) == idl_octet) || (idl_typeBasicType(idl_typeBasic(idl_typeSeqType(typeSeq))) == idl_string))) { - genPrototypesOnly = TRUE; - } else - /* If the element type of the sequence has a related key, which means that readers and - * writers have been created, and which also means that type sequence support functions - * have already been created. In that case the prototypes for these functions should be - * generated. Otherwise add the scope name of the module where the sequence is defined - * in to the name of these functions. - */ - if (idl_keyDefIncludesType(idl_keyDefDefGet(), sequenceElementName)) { - genPrototypesOnly = TRUE; - } else { - genPrototypesOnly = idl_sequenceSupportFunctionsExist(scope, typeSeq, sequenceElementName); - } - } else { - genPrototypesOnly = TRUE; + prototypeExists = TRUE; + } } - idl_fileOutPrintf( - idl_fileCur(), - "/* Definition for sequence of %s */\n", - idl_scopedSacTypeIdent(idl_typeSeqType(typeSeq))); - idl_fileOutPrintf( - idl_fileCur(), - "#ifndef _%s_defined\n", - sequenceName); - idl_fileOutPrintf( - idl_fileCur(), - "#define _%s_defined\n", - sequenceName); - if (idl_typeSpecType(idl_typeSeqType(typeSeq)) == idl_tstruct) { - /* In case struct is refered, it can be a sequence definition within */ - /* within the structure with a reference to the struct itself. In that */ - /* case the struct or union is not defined yet, and a forward */ - /* definition is required. */ + if (!prototypeExists) { idl_fileOutPrintf( idl_fileCur(), - "#ifndef _%s_defined\n", - idl_scopedSacTypeIdent(idl_typeSeqType(typeSeq))); - idl_fileOutPrintf( - idl_fileCur(), - "#define _%s_defined\n", - idl_scopedSacTypeIdent(idl_typeSeqType(typeSeq))); - idl_printIndent(indent_level); - idl_fileOutPrintf( - idl_fileCur(), - "typedef struct %s %s;\n", - idl_scopedSacTypeIdent(idl_typeSeqType(typeSeq)), - idl_scopedSacTypeIdent(idl_typeSeqType(typeSeq))); - idl_fileOutPrintf( - idl_fileCur(), - "#endif /* _%s_defined */\n", - idl_scopedSacTypeIdent(idl_typeSeqType(typeSeq))); - } else if (idl_typeSpecType(idl_typeSeqType(typeSeq)) == idl_tunion) { - /* In case struct is refered, it can be a sequence definition within */ - /* within the structure with a reference to the struct itself. In that */ - /* case the struct or union is not defined yet, and a forward */ - /* definition is required. */ + "/* Definition for sequence of %s */\n", + sequenceElementName); idl_fileOutPrintf( idl_fileCur(), "#ifndef _%s_defined\n", - idl_scopedSacTypeIdent(idl_typeSeqType(typeSeq))); + sequenceName); idl_fileOutPrintf( idl_fileCur(), "#define _%s_defined\n", - idl_scopedSacTypeIdent(idl_typeSeqType(typeSeq))); - idl_printIndent(indent_level); - idl_fileOutPrintf( - idl_fileCur(), - "typedef struct %s %s;\n", - idl_scopedSacTypeIdent(idl_typeSeqType(typeSeq)), - idl_scopedSacTypeIdent(idl_typeSeqType(typeSeq))); - idl_fileOutPrintf(idl_fileCur(), - "#endif /* _%s_defined */\n", - idl_scopedSacTypeIdent(idl_typeSeqType(typeSeq))); - } - idl_fileOutPrintf(idl_fileCur(), "typedef struct {\n"); - idl_fileOutPrintf(idl_fileCur(), " DDS_unsigned_long _maximum;\n"); - idl_fileOutPrintf(idl_fileCur(), " DDS_unsigned_long _length;\n"); - idl_fileOutPrintf(idl_fileCur(), " %s *_buffer;\n", sequenceElementName); - idl_fileOutPrintf(idl_fileCur(), " DDS_boolean _release;\n"); - idl_fileOutPrintf(idl_fileCur(), "} %s;\n", sequenceName); + sequenceName); + if (idl_typeSpecType(idl_typeSeqType(typeSeq)) == idl_tstruct) { + /* In case struct is refered, it can be a sequence definition within */ + /* within the structure with a reference to the struct itself. In that */ + /* case the struct or union is not defined yet, and a forward */ + /* definition is required. */ + idl_fileOutPrintf( + idl_fileCur(), + "#ifndef _%s_defined\n", + sequenceElementName); + idl_fileOutPrintf( + idl_fileCur(), + "#define _%s_defined\n", + sequenceElementName); + idl_printIndent(indent_level); + idl_fileOutPrintf( + idl_fileCur(), + "typedef struct %s %s;\n", + sequenceElementName, + sequenceElementName); + idl_fileOutPrintf( + idl_fileCur(), + "#endif /* _%s_defined */\n", + sequenceElementName); + } else if (idl_typeSpecType(idl_typeSeqType(typeSeq)) == idl_tunion) { + /* In case struct is refered, it can be a sequence definition within */ + /* within the structure with a reference to the struct itself. In that */ + /* case the struct or union is not defined yet, and a forward */ + /* definition is required. */ + idl_fileOutPrintf( + idl_fileCur(), + "#ifndef _%s_defined\n", + sequenceElementName); + idl_fileOutPrintf( + idl_fileCur(), + "#define _%s_defined\n", + sequenceElementName); + idl_printIndent(indent_level); + idl_fileOutPrintf( + idl_fileCur(), + "typedef struct %s %s;\n", + sequenceElementName, + sequenceElementName); + idl_fileOutPrintf(idl_fileCur(), + "#endif /* _%s_defined */\n", + sequenceElementName); + } + idl_fileOutPrintf(idl_fileCur(), "typedef struct {\n"); + idl_fileOutPrintf(idl_fileCur(), " DDS_unsigned_long _maximum;\n"); + idl_fileOutPrintf(idl_fileCur(), " DDS_unsigned_long _length;\n"); + idl_fileOutPrintf(idl_fileCur(), " %s *_buffer;\n", sequenceElementName); + idl_fileOutPrintf(idl_fileCur(), " DDS_boolean _release;\n"); + idl_fileOutPrintf(idl_fileCur(), "} %s;\n", sequenceName); - if (genPrototypesOnly) { idl_fileOutPrintf(idl_fileCur(), "%s %s *%s__alloc (void);\n", idl_dllGetMacro(), @@ -950,35 +941,21 @@ idl_sequenceOpenClose( idl_dllGetMacro(), sequenceElementName, sequenceName); - } else { - char * sequenceScopedName = idl_sequenceIdentScoped(scope, typeSeq); - idl_fileOutPrintf(idl_fileCur(), - "%s %s *%s__alloc (void);\n", - idl_dllGetMacro(), - sequenceName, - sequenceScopedName); - idl_fileOutPrintf(idl_fileCur(), - "%s %s *%s_allocbuf (DDS_unsigned_long len);\n", - idl_dllGetMacro(), - sequenceElementName, - sequenceScopedName); - - idl_fileOutPrintf(idl_fileCur(), - "#define %s__alloc %s__alloc\n", - sequenceName, - sequenceScopedName); - idl_fileOutPrintf(idl_fileCur(), - "#define %s_allocbuf %s_allocbuf\n", - sequenceName, - sequenceScopedName); - - os_free(sequenceScopedName); + idl_fileOutPrintf(idl_fileCur(), "#endif /* _%s_defined */\n", sequenceName); } + sequenceScopedName = idl_sequenceIdentScoped(scope, typeSeq); - idl_fileOutPrintf(idl_fileCur(), "#endif /* _%s_defined */\n", sequenceName); - idl_fileOutPrintf(idl_fileCur(), "\n"); + idl_fileOutPrintf(idl_fileCur(), + "#define %s__alloc %s__alloc\n", + sequenceScopedName, + sequenceName); + idl_fileOutPrintf(idl_fileCur(), + "#define %s_allocbuf %s_allocbuf\n\n", + sequenceScopedName, + sequenceName); + os_free(sequenceScopedName); os_free(sequenceElementName); os_free(sequenceName); } diff --git a/src/tools/idlpp/code/idl_genSacType.h b/src/tools/idlpp/code/idl_genSacType.h index 751805d12..390c0b288 100644 --- a/src/tools/idlpp/code/idl_genSacType.h +++ b/src/tools/idlpp/code/idl_genSacType.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/idlpp/code/idl_genSacTypedClassDefs.c b/src/tools/idlpp/code/idl_genSacTypedClassDefs.c index 0a700cb89..c5561471b 100644 --- a/src/tools/idlpp/code/idl_genSacTypedClassDefs.c +++ b/src/tools/idlpp/code/idl_genSacTypedClassDefs.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -52,7 +53,7 @@ idl_fileOpen( c_char *tmplPath; c_char *orbPath; int tmplFile; - struct os_stat tmplStat; + struct os_stat_s tmplStat; unsigned int nRead; OS_UNUSED_ARG(scope); OS_UNUSED_ARG(userData); diff --git a/src/tools/idlpp/code/idl_genSacTypedClassDefs.h b/src/tools/idlpp/code/idl_genSacTypedClassDefs.h index 4a557f149..c11e59faf 100644 --- a/src/tools/idlpp/code/idl_genSacTypedClassDefs.h +++ b/src/tools/idlpp/code/idl_genSacTypedClassDefs.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/idlpp/code/idl_genSacTypedClassImpl.c b/src/tools/idlpp/code/idl_genSacTypedClassImpl.c index 40276e48c..6ac71c4b8 100644 --- a/src/tools/idlpp/code/idl_genSacTypedClassImpl.c +++ b/src/tools/idlpp/code/idl_genSacTypedClassImpl.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -52,7 +53,7 @@ idl_fileOpen( c_char *tmplPath; c_char *orbPath; int tmplFile; - struct os_stat tmplStat; + struct os_stat_s tmplStat; unsigned int nRead; OS_UNUSED_ARG(scope); OS_UNUSED_ARG(userData); diff --git a/src/tools/idlpp/code/idl_genSacTypedClassImpl.h b/src/tools/idlpp/code/idl_genSacTypedClassImpl.h index 5daf157d4..40288d6fd 100644 --- a/src/tools/idlpp/code/idl_genSacTypedClassImpl.h +++ b/src/tools/idlpp/code/idl_genSacTypedClassImpl.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/idlpp/code/idl_genSajHolder.c b/src/tools/idlpp/code/idl_genSajHolder.c index 120c68942..ca77324dc 100644 --- a/src/tools/idlpp/code/idl_genSajHolder.c +++ b/src/tools/idlpp/code/idl_genSajHolder.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -41,7 +42,7 @@ #include "idl_dependencies.h" #include "idl_genLanguageHelper.h" -/* @brief callback function called on opening the IDL input file. +/** @brief callback function called on opening the IDL input file. * * Generate standard file header consisting of: * - mutiple inclusion prevention diff --git a/src/tools/idlpp/code/idl_genSajHolder.h b/src/tools/idlpp/code/idl_genSajHolder.h index 6db3360d1..bf95ff71b 100644 --- a/src/tools/idlpp/code/idl_genSajHolder.h +++ b/src/tools/idlpp/code/idl_genSajHolder.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/idlpp/code/idl_genSajMeta.c b/src/tools/idlpp/code/idl_genSajMeta.c index 0c2273301..9e319e3f1 100644 --- a/src/tools/idlpp/code/idl_genSajMeta.c +++ b/src/tools/idlpp/code/idl_genSajMeta.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -59,7 +60,7 @@ idl_genSajXMLMeta( char *ptr; os_size_t i; - meta = idl_genXMLmeta(type); + meta = idl_genXMLmeta(type, TRUE); len = strlen(meta); pcs = (len/IDL_MAX_JSTRING_META_SIZE); if ((len % IDL_MAX_JSTRING_META_SIZE) != 0) { @@ -104,7 +105,7 @@ idl_genMeta ( c_char *tmplPath; c_char *orbPath; int tmplFile; - struct os_stat tmplStat; + struct os_stat_s tmplStat; unsigned int nRead; tmplPath = os_getenv("OSPL_TMPL_PATH"); diff --git a/src/tools/idlpp/code/idl_genSajType.c b/src/tools/idlpp/code/idl_genSajType.c index ceb746c02..6404322f2 100644 --- a/src/tools/idlpp/code/idl_genSajType.c +++ b/src/tools/idlpp/code/idl_genSajType.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -47,7 +48,7 @@ #include "os_abstract.h" static idl_map map = NULL; - /** enumeration element index */ +/** enumeration element index */ static c_long enum_element = 0; static char *enum_def = NULL; @@ -61,7 +62,7 @@ static void java_arrayDimensions(idl_typeSpec typeSeq); static c_char *idl_valueFromLabelVal(idl_labelVal labelVal); static void idl_ifArrayInitializeElements(idl_typeSpec typeSpec, const char *elementName); -/* @brief callback function called on opening the IDL input file. +/** @brief callback function called on opening the IDL input file. * * Generate standard file header consisting of: * - mutiple inclusion prevention @@ -150,12 +151,6 @@ idl_structureOpen( /* setup iterator to hold field names and correcsponding type names */ map = idl_mapNew(NULL, 1, 1); /* Write package name */ -#if 0 - idl_fileOutPrintf (idl_fileCur(), "/*\n"); - idl_fileOutPrintf (idl_fileCur(), " * Generated by OpenSpliceDDS "OSPL_VERSION_STR"\n"); - idl_fileOutPrintf (idl_fileCur(), " */\n\n"); -#endif - /* public final class { */ idl_fileOutPrintf(idl_fileCur(), "public final class %s {\n\n", idl_javaId(name)); /* return idl_explore to indicate that the rest of the structure needs to be processed */ return idl_explore; @@ -474,11 +469,6 @@ idl_unionOpen( map = idl_mapNew(NULL, 1, 1); /* Write package name */ -#if 0 - idl_fileOutPrintf(idl_fileCur(), "/*\n"); - idl_fileOutPrintf(idl_fileCur(), " * Generated by OpenSpliceDDS "OSPL_VERSION_STR"\n"); - idl_fileOutPrintf(idl_fileCur(), " */\n\n"); -#endif idl_fileOutPrintf(idl_fileCur(), "import org.opensplice.dds.dcps.Utilities;\n\n"); /* public final class { */ idl_fileOutPrintf(idl_fileCur(), "public final class %s {\n\n", idl_javaId(name)); @@ -736,13 +726,10 @@ idl_unionCaseOpenClose( if (labelImage) { idl_fileOutPrintf(idl_fileCur(), " _d = (%s)%s;\n", unionSwitchType, labelImage); } else { -/* Theoretically this branch should never be reached: also the code - underneath doesn't make any sense. That's why an assert has - now been substituted. - - labelImage = os_iterObject(labelsUsedIter, 0); - idl_fileOutPrintf(idl_fileCur(), " _d = (%s)%s;\n", unionSwitchType, labelImage); -*/ + /* Theoretically this branch should never be reached: also the code + * underneath doesn't make any sense. That's why an assert has + * now been substituted. + */ assert(FALSE); } idl_fileOutPrintf(idl_fileCur(), " }\n\n"); @@ -1122,7 +1109,7 @@ idl_enumerationElementOpenClose ( enum_element++; } -/* @brief generate dimension of an array or a sequence +/** @brief generate dimension of an array or a sequence * * java_arrayDimensions is a local support function to generate * the dimensions of a java Array representing an IDL sequence or @@ -1149,7 +1136,7 @@ java_arrayDimensions( } } -/* @brief function to find out whether the elements of an array +/** @brief function to find out whether the elements of an array * require initialization. * * idl_arrayElementsNeedInitialization is a local support function to find out @@ -1188,7 +1175,7 @@ idl_arrayElementsNeedInitialization( return initRequired; } -/* @brief generate initialization of array elements. +/** @brief generate initialization of array elements. * * idl_arrayElementInit generates for-loops that initialize * each attribute of an array explicitly. @@ -1258,7 +1245,7 @@ idl_arrayElementInit( } } -/* @brief generate initialization of array elements. +/** @brief generate initialization of array elements. * * idl_ifArrayInitializeElements is a local support function to initialize * the elements of non-primitive array types, if appropriate. @@ -1335,13 +1322,8 @@ idl_constantOpenClose( /* Open file for used scope, if needed create the directories */ idl_openJavaPackage(scope, idl_javaId(idl_constSpecName(constantSpec))); /* Write package name */ -#if 0 - idl_fileOutPrintf(idl_fileCur(), "/*\n"); - idl_fileOutPrintf(idl_fileCur(), " * Generated by OpenSpliceDDS "OSPL_VERSION_STR"\n"); - idl_fileOutPrintf(idl_fileCur(), " */\n\n"); -#endif idl_fileOutPrintf(idl_fileCur(), "public interface %s {\n", - idl_constSpecName(constantSpec)); + idl_constSpecName(constantSpec)); if (idl_typeSpecType(idl_constSpecTypeGet(constantSpec)) == idl_tbasic && idl_typeBasicType(idl_typeBasic(idl_constSpecTypeGet(constantSpec))) == idl_string) { diff --git a/src/tools/idlpp/code/idl_genSajType.h b/src/tools/idlpp/code/idl_genSajType.h index 264d46589..0f50d1608 100644 --- a/src/tools/idlpp/code/idl_genSajType.h +++ b/src/tools/idlpp/code/idl_genSajType.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/idlpp/code/idl_genSajTypedClass.c b/src/tools/idlpp/code/idl_genSajTypedClass.c index 26b1e3755..84ad4f251 100644 --- a/src/tools/idlpp/code/idl_genSajTypedClass.c +++ b/src/tools/idlpp/code/idl_genSajTypedClass.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -104,29 +105,35 @@ idl_genInterface( c_char *tmplPath; c_char *orbPath; int tmplFile; - struct os_stat tmplStat; + struct os_stat_s tmplStat; unsigned int nRead; os_char *redirects; char *scopedMetaTypeName; const char *internalTypeName; const char *keyList; - + char *scopeStackJavaDot = idl_scopeStackJava(scope, ".", name); + char *scopeStackJavaSlash = idl_scopeStackJava(scope, "/", name); + char *typeSpecName = idl_typeSpecName(typeSpec); + char *javaId = idl_javaId(name); + int result = 0; tmplPath = os_getenv("OSPL_TMPL_PATH"); orbPath = os_getenv("OSPL_ORB_PATH"); if (tmplPath == NULL) { printf("OSPL_TMPL_PATH not defined\n"); - return -1; + result = -1; + goto err_exit; } if (orbPath == NULL) { printf("OSPL_ORB_PATH not defined\n"); - return -1; + result = -1; + goto err_exit; } idlpp_macroSet = idl_macroSetNew(); - idl_macroSetAdd(idlpp_macroSet, idl_macroNew("type-name", idl_javaId(name))); - idl_macroSetAdd(idlpp_macroSet, idl_macroNew("actual-type-name", idl_typeSpecName(typeSpec))); - idl_macroSetAdd(idlpp_macroSet, idl_macroNew("scoped-type-name", idl_scopeStackJava(scope, ".", name))); - idl_macroSetAdd(idlpp_macroSet, idl_macroNew("java-class-name", idl_scopeStackJava(scope, "/", name))); + idl_macroSetAdd(idlpp_macroSet, idl_macroNew("type-name", javaId)); + idl_macroSetAdd(idlpp_macroSet, idl_macroNew("actual-type-name", typeSpecName)); + idl_macroSetAdd(idlpp_macroSet, idl_macroNew("scoped-type-name", scopeStackJavaDot)); + idl_macroSetAdd(idlpp_macroSet, idl_macroNew("java-class-name", scopeStackJavaSlash)); redirects = idl_packageRedirects (); idl_macroSetAdd(idlpp_macroSet, idl_macroNew("java-package-redirects", redirects)); @@ -148,10 +155,11 @@ idl_genInterface( /* Generate only in standalone mode */ if (idl_getCorbaMode() == IDL_MODE_STANDALONE) { - snprintf(pname, sizeof (pname), "%s%s", idl_javaId(name), class_base); + snprintf(pname, sizeof (pname), "%s%s", javaId, class_base); idl_openJavaPackage(scope, pname); if (idl_fileCur() == NULL) { - return -1; + result = -1; + goto err_exit; } /* Prepare Interface class */ if (generateInterfaceClass) { @@ -160,7 +168,8 @@ idl_genInterface( if ((os_stat(tmplFileName, &tmplStat) != os_resultSuccess) || (os_access(tmplFileName, OS_ROK) != os_resultSuccess)) { printf ("No template found or protection violation (%s)\n", tmplFileName); - return -1; + result = -1; + goto err_exit; } /* QAC EXPECT 5007; will not use wrapper */ idlpp_template = os_malloc(tmplStat.stat_size+1); @@ -175,13 +184,15 @@ idl_genInterface( idl_tmplExpProcessTmpl(te, idlpp_inStream, idl_fileCur()); idl_streamInFree(idlpp_inStream); idl_tmplExpFree(te); + os_free(idlpp_template); } idl_closeJavaPackage(); - snprintf(pname, sizeof(pname), "%s%sHolder", idl_javaId(name), class_base); + snprintf(pname, sizeof(pname), "%s%sHolder", javaId, class_base); idl_openJavaPackage(scope, pname); if (idl_fileCur() == NULL) { - return -1; + result = -1; + goto err_exit; } /* Prepare typeSupportHolder class */ snprintf(tmplFileName, sizeof(tmplFileName), "%s%c%s%ctmpl%sHolder.java", tmplPath, OS_FILESEPCHAR, orbPath, OS_FILESEPCHAR, class_base); @@ -189,7 +200,8 @@ idl_genInterface( if ((os_stat(tmplFileName, &tmplStat) != os_resultSuccess) || (os_access(tmplFileName, OS_ROK) != os_resultSuccess)) { printf ("No template found or protection violation (%s)\n", tmplFileName); - return -1; + result = -1; + goto err_exit; } /* QAC EXPECT 5007; will not use wrapper */ idlpp_template = os_malloc(tmplStat.stat_size+1); @@ -199,6 +211,7 @@ idl_genInterface( close(tmplFile); idlpp_macroAttrib = idl_macroAttribNew(IDL_TOKEN_START, IDL_TOKEN_OPEN, IDL_TOKEN_CLOSE); idlpp_inStream = idl_streamInNew(idlpp_template, idlpp_macroAttrib); + os_free(idlpp_template); te = idl_tmplExpNew(idlpp_macroSet); idl_tmplExpProcessTmpl(te, idlpp_inStream, idl_fileCur()); @@ -206,10 +219,11 @@ idl_genInterface( idl_tmplExpFree(te); idl_closeJavaPackage(); - snprintf(pname, sizeof(pname), "%s%sHelper", idl_javaId(name), class_base); + snprintf(pname, sizeof(pname), "%s%sHelper", javaId, class_base); idl_openJavaPackage(scope, pname); if (idl_fileCur() == NULL) { - return -1; + result = -1; + goto err_exit; } /* Prepare typeSupportHelper class */ snprintf(tmplFileName, sizeof(tmplFileName), "%s%c%s%ctmpl%sHelper.java", tmplPath, OS_FILESEPCHAR, orbPath, OS_FILESEPCHAR, class_base); @@ -217,7 +231,8 @@ idl_genInterface( if ((os_stat(tmplFileName, &tmplStat) != os_resultSuccess) || (os_access(tmplFileName, OS_ROK) != os_resultSuccess)) { printf ("No template found or protection violation (%s)\n", tmplFileName); - return -1; + result = -1; + goto err_exit; } /* QAC EXPECT 5007; will not use wrapper */ idlpp_template = os_malloc(tmplStat.stat_size+1); @@ -227,6 +242,7 @@ idl_genInterface( close(tmplFile); idlpp_macroAttrib = idl_macroAttribNew(IDL_TOKEN_START, IDL_TOKEN_OPEN, IDL_TOKEN_CLOSE); idlpp_inStream = idl_streamInNew(idlpp_template, idlpp_macroAttrib); + os_free(idlpp_template); te = idl_tmplExpNew(idlpp_macroSet); idl_tmplExpProcessTmpl(te, idlpp_inStream, idl_fileCur()); @@ -234,10 +250,11 @@ idl_genInterface( idl_tmplExpFree(te); idl_closeJavaPackage(); - snprintf(pname, sizeof(pname), "%s%sOperations", idl_javaId(name), class_base); + snprintf(pname, sizeof(pname), "%s%sOperations", javaId, class_base); idl_openJavaPackage(scope, pname); if (idl_fileCur() == NULL) { - return (idl_abort); + result = idl_abort; + goto err_exit; } /* Prepare typeSupportOperations class */ snprintf(tmplFileName, sizeof(tmplFileName), "%s%c%s%ctmpl%sOperations.java", tmplPath, OS_FILESEPCHAR, orbPath, OS_FILESEPCHAR, class_base); @@ -245,7 +262,8 @@ idl_genInterface( if ((os_stat(tmplFileName, &tmplStat) != os_resultSuccess) || (os_access(tmplFileName, OS_ROK) != os_resultSuccess)) { printf ("No template found or protection violation (%s)\n", tmplFileName); - return -1; + result = -1; + goto err_exit; } /* QAC EXPECT 5007; will not use wrapper */ idlpp_template = os_malloc(tmplStat.stat_size+1); @@ -255,6 +273,7 @@ idl_genInterface( close(tmplFile); idlpp_macroAttrib = idl_macroAttribNew(IDL_TOKEN_START, IDL_TOKEN_OPEN, IDL_TOKEN_CLOSE); idlpp_inStream = idl_streamInNew(idlpp_template, idlpp_macroAttrib); + os_free(idlpp_template); te = idl_tmplExpNew(idlpp_macroSet); idl_tmplExpProcessTmpl(te, idlpp_inStream, idl_fileCur()); @@ -265,14 +284,15 @@ idl_genInterface( if (generateInterfaceClass) { /* Implementation with Impl extension */ - snprintf(pname, sizeof(pname), "%s%sImpl", idl_javaId(name), class_base); + snprintf(pname, sizeof(pname), "%s%sImpl", javaId, class_base); } else { /* Implementation without Impl extension */ - snprintf(pname, sizeof(pname), "%s%s", idl_javaId(name), class_base); + snprintf(pname, sizeof(pname), "%s%s", javaId, class_base); } idl_openJavaPackage(scope, pname); if (idl_fileCur() == NULL) { - return -1; + result = -1; + goto err_exit; } /* Prepare typeSupportStub class */ snprintf(tmplFileName, sizeof(tmplFileName), "%s%c%s%ctmpl%sImpl.java", tmplPath, OS_FILESEPCHAR, orbPath, OS_FILESEPCHAR, class_base); @@ -280,7 +300,8 @@ idl_genInterface( if ((os_stat(tmplFileName, &tmplStat) != os_resultSuccess) || (os_access(tmplFileName, OS_ROK) != os_resultSuccess)) { printf("No template found or protection violation (%s)\n", tmplFileName); - return (idl_abort); + result = idl_abort; + goto err_exit; } /* QAC EXPECT 5007; will not use wrapper */ idlpp_template = os_malloc(tmplStat.stat_size+1); @@ -290,14 +311,20 @@ idl_genInterface( close(tmplFile); idlpp_macroAttrib = idl_macroAttribNew(IDL_TOKEN_START, IDL_TOKEN_OPEN, IDL_TOKEN_CLOSE); idlpp_inStream = idl_streamInNew(idlpp_template, idlpp_macroAttrib); + os_free(idlpp_template); te = idl_tmplExpNew(idlpp_macroSet); idl_tmplExpProcessTmpl(te, idlpp_inStream, idl_fileCur()); idl_streamInFree(idlpp_inStream); idl_tmplExpFree(te); idl_closeJavaPackage(); +err_exit: + os_free(javaId); + os_free(scopeStackJavaDot); + os_free(scopeStackJavaSlash); + - return 0; + return result; } static int @@ -312,7 +339,7 @@ idl_genTypeSeqHolder( c_char *tmplPath; c_char *orbPath; int tmplFile; - struct os_stat tmplStat; + struct os_stat_s tmplStat; unsigned int nRead; tmplPath = os_getenv("OSPL_TMPL_PATH"); diff --git a/src/tools/idlpp/code/idl_genSajTypedClass.h b/src/tools/idlpp/code/idl_genSajTypedClass.h index 463f3e02e..6ef4c32e7 100644 --- a/src/tools/idlpp/code/idl_genSajTypedClass.h +++ b/src/tools/idlpp/code/idl_genSajTypedClass.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/idlpp/code/idl_genSimulink.c b/src/tools/idlpp/code/idl_genSimulink.c new file mode 100755 index 000000000..54739d8af --- /dev/null +++ b/src/tools/idlpp/code/idl_genSimulink.c @@ -0,0 +1,590 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +/* + This module generates Splice type definitions related to + an IDL input file. +*/ + +/** + * @file + * This module generates a MATLAB script that outputs a Simulink Bus object + * related to an IDL input file. +*/ + +#include "os_version.h" +#include "idl_program.h" +#include "idl_scope.h" +#include "idl_dependencies.h" +#include "idl_genLanguageHelper.h" +#include "idl_tmplExp.h" +#include "idl_map.h" +#include "idl_keyDef.h" +#include "idl_genMetaHelper.h" +#include "idl_genSimulinkHelper.h" + +#include +#include "c_typebase.h" +#include "os_iterator.h" +#include "os_stdlib.h" +#include "os_heap.h" +#include "os_abstract.h" +#include "ut_collection.h" + +#define MAX_UNBOUNDED_STR_DEFAULT 256 + +static int busIdx; +static int enumIdx; +static int busElemIdx; +static c_ulong enumNumElements; +static c_ulong enumElemIdx; +static char *enumScopeStack; +static const c_char *enumFileAnnotation; + +static void +simulink_arrayDimensions( + idl_typeSpec typeSpec, + char* dimensions) +{ + while (idl_typeSpecType(typeSpec) == idl_ttypedef) { + typeSpec = idl_typeDefRefered(idl_typeDef(typeSpec)); + } + + if (idl_typeSpecType(typeSpec) == idl_tarray) { + idl_typeArray typeArray = idl_typeArray(typeSpec); + c_ulong n = simulink_arrayNDimensions(typeArray); + c_ulong *dims = (c_ulong *)os_malloc(n * sizeof(c_ulong)); + c_char *formatted = NULL; + simulink_arrayGetDimensions(typeArray, dims); + formatted = simulink_formatDimensions(dims, n); + os_free((void*)dims); + strcpy(dimensions, formatted); + os_free(formatted); + } +} + +/** @brief callback function called on opening the IDL input file. + * + * Generate standard file header consisting of: + * - mutiple inclusion prevention + * - inclusion of Splice type definition files + * - inclusion of application specific include files related to other IDL files + * + * @param scope Current scope (not used) + * @param name Name of the IDL input file + */ +static idl_action +idl_fileOpen( + idl_scope scope, + const char *name, + void *userData) +{ + OS_UNUSED_ARG(scope); + OS_UNUSED_ARG(userData); + + simulink_propertiesTable = simulink_createTable(); + simulink_nameTable = simulink_createTable(); + + /*sizeof(“.propertiesâ€) includes the null-byte */ + simulink_propertiesFileName = (char *)os_malloc(strlen(name) + sizeof(".properties")); + os_sprintf(simulink_propertiesFileName, "%s.properties", name); + + simulink_readProperties(simulink_propertiesFileName, simulink_propertiesTable); + + busIdx = 1; + enumIdx = 1; + return idl_explore; +} + +static void +idl_fileClose( + void *userData) +{ + OS_UNUSED_ARG(userData); + + if(simulink_propertiesFileName != NULL) { + simulink_writeProperties(simulink_propertiesTable, simulink_propertiesFileName); + os_free((void*)simulink_propertiesFileName); + } +} + + +/** @brief callback function called on structure definition in the IDL input file. + * + * Generate code for the following IDL construct: + * @verbatim + => struct { + ; + ... ... + ; + }; + @endverbatim + * + * @param scope Current scope (and scope of the structure definition) + * @param name Name of the structure + * @param structSpec Specification of the struct holding the amount of members + */ +static idl_action +idl_structureOpen( + idl_scope scope, + const char *name, + idl_typeStruct structSpec, + void *userData) +{ + c_ulong showWarning = OS_TRUE; + char *scopeStack = simulinkScope(scope); + const c_char *keyAnnotation = simulinkKeyListAnnotation(scope, name); + const c_char *idlFileAnnotation = simulinkIdlFileAnnotation(scope); + const char *busName = simulink_getClassNameFromName(scope, name, showWarning); + + OS_UNUSED_ARG(userData); + + busElemIdx = 1; + + idl_fileOutPrintf(idl_fileCur(), "busses{1,%d} = '%s';\n", busIdx, busName); + idl_fileOutPrintf(idl_fileCur(), "busses{2,%d} = Simulink.Bus;\n", busIdx); + idl_fileOutPrintf(idl_fileCur(), "busses{2,%d}.Description = '%s%s%s';\n", + busIdx, scopeStack, keyAnnotation, idlFileAnnotation); + idl_fileOutPrintf(idl_fileCur(), "busses{2,%d}.DataScope = 'Auto';\n", busIdx); + idl_fileOutPrintf(idl_fileCur(), "busses{2,%d}.HeaderFile = '';\n", busIdx); + idl_fileOutPrintf(idl_fileCur(), "busses{2,%d}.Alignment = -1;\n", busIdx); + os_free((void*)scopeStack); + os_free((void*)keyAnnotation); + os_free((void*)idlFileAnnotation); + + if (idl_keyResolve(idl_keyDefDefGet(), scope, name) != NULL) { + c_type type = idl_typeSpecDef(idl_typeSpec(structSpec)); + char *typedesc = idl_genXMLmeta(type, FALSE); + + idl_fileOutPrintf(idl_fileCur(), "busses{3,%d} = '%s';\n", busIdx, typedesc); + os_free(typedesc); + } else { + idl_fileOutPrintf(idl_fileCur(), "busses{3,%d} = '';\n", busIdx); + } + return idl_explore; +} + +/** @brief callback function called on end of a structure definition in the IDL input file. + * + * Generate code for the following IDL construct: + * @verbatim + struct { + + ... ... + + => }; + @endverbatim + * + * The structure is closed: + * @verbatim + }; + @endverbatim + * + * @param name Name of the structure (not used) + */ +static void +idl_structureClose( + const char *name, + void *userData) +{ + OS_UNUSED_ARG(name); + OS_UNUSED_ARG(userData); + + idl_fileOutPrintf(idl_fileCur(), "busses{2,%d}.Elements = saveVarsTmp;\n", busIdx); + idl_fileOutPrintf(idl_fileCur(), "clear saveVarsTmp;\n\n"); + busIdx++; +} + +/** @brief callback function called on definition of a structure member in the IDL input file. + * + * Generate code for the following IDL construct: + * @verbatim + struct { + => ; + => ... ... + => ; + }; + @endverbatim + * + * @param scope Current scope + * @param name Name of the structure member + * @param typeSpec Type specification of the structure member + */ +static void +idl_structureMemberOpenClose( + idl_scope scope, + const char *name, + idl_typeSpec typeSpec, + void *userData) +{ + char* simulinkType = NULL; + char* description = ""; + char dimensions[256] = "1"; + + OS_UNUSED_ARG(scope); + OS_UNUSED_ARG(userData); + /* Dereference possible typedefs first. */ + while (idl_typeSpecType(typeSpec) == idl_ttypedef) { + typeSpec = idl_typeDefRefered(idl_typeDef(typeSpec)); + } + + if(!simulink_containSeqType(typeSpec)) { + simulink_recordStringBound(typeSpec, scope, name); + } + + description = simulinkTypeAnnotation(typeSpec); + if ((idl_typeSpecType(typeSpec) == idl_tbasic)) { + simulinkType = idl_SimulinkTypeFromTypeSpec(typeSpec); + if (idl_typeBasicType(idl_typeBasic (typeSpec)) == idl_string) { + c_ulong maxlen = idl_typeBasicMaxlen(idl_typeBasic(typeSpec)); + os_sprintf(dimensions, "%d", maxlen ? maxlen : simulink_getStrMaxDimension()); + } + } else if (idl_typeSpecType(typeSpec) == idl_tseq) { + c_ulong showWarning = OS_FALSE; + simulinkType = simulinkSeqClassRef(idl_typeSeq(typeSpec), showWarning); + } else if (idl_typeSpecType(typeSpec) == idl_tarray) { + simulinkType = idl_SimulinkTypeFromTypeSpec(typeSpec); + simulink_arrayDimensions(typeSpec, dimensions); + } else if (idl_typeSpecType(typeSpec) == idl_tstruct) { + simulinkType = simulinkGetDataType(typeSpec); + } else if (idl_typeSpecType(typeSpec) == idl_tenum) { + simulinkType = simulinkGetDataType(typeSpec); + } else if (idl_typeSpecType (typeSpec) == idl_tunion) { + printf("idl_genSimulink.c:idl_structureMemberOpenClose: %s Union types are unsupported" + " for Simulink binding.\n", + name); + exit(1); + } else { + printf("idl_genSimulink.c:idl_structureMemberOpenClose: Unexpected type %d\n", + idl_typeSpecType(typeSpec)); + } + + if (!simulinkType) { + simulinkType = os_strdup(""); + } + + /* Set the Simulink bus properties. */ + idl_fileOutPrintf(idl_fileCur(), "saveVarsTmp(%d) = Simulink.BusElement;\n", busElemIdx); + idl_fileOutPrintf(idl_fileCur(), "saveVarsTmp(%d).Name = '%s';\n", busElemIdx, name); + idl_fileOutPrintf(idl_fileCur(), "saveVarsTmp(%d).Dimensions = %s;\n", busElemIdx, dimensions); + idl_fileOutPrintf(idl_fileCur(), "saveVarsTmp(%d).DataType = '%s';\n", busElemIdx, simulinkType); + idl_fileOutPrintf(idl_fileCur(), "saveVarsTmp(%d).Description = '%s';\n", busElemIdx, description); + + /* Other Simulink bus properties that we don't modify. */ + idl_fileOutPrintf(idl_fileCur(), "saveVarsTmp(%d).Complexity = 'real';\n", busElemIdx); + idl_fileOutPrintf(idl_fileCur(), "saveVarsTmp(%d).Min = [];\n", busElemIdx); + idl_fileOutPrintf(idl_fileCur(), "saveVarsTmp(%d).Max = [];\n", busElemIdx); + idl_fileOutPrintf(idl_fileCur(), "saveVarsTmp(%d).DimensionsMode = 'Fixed';\n", busElemIdx); + idl_fileOutPrintf(idl_fileCur(), "saveVarsTmp(%d).SamplingMode = 'Sample based';\n", busElemIdx); + idl_fileOutPrintf(idl_fileCur(), "saveVarsTmp(%d).SampleTime = -1;\n", busElemIdx); + idl_fileOutPrintf(idl_fileCur(), "saveVarsTmp(%d).DocUnits = '';\n", busElemIdx); + + simulink_setStrMaxDimension(MAX_UNBOUNDED_STR_DEFAULT); + busElemIdx++; + os_free(simulinkType); +} + +/** @brief callback function called on definition of an enumeration. + * + * Generate code for the following IDL construct: + * @verbatim + => enum { + ; + ... ... + ; + }; + @endverbatim + * + * @param scope Current scope + * @param name Name of the enumeration + * @param enumSpec Specifies the number of elements in the enumeration + */ +static idl_action +idl_enumerationOpen( + idl_scope scope, + const char *name, + idl_typeEnum enumSpec, + void *userData) +{ + c_ulong showWarning = OS_TRUE; + const char *enumName = simulink_getClassNameFromName(scope, name, showWarning); + OS_UNUSED_ARG(userData); + enumFileAnnotation = simulinkIdlFileAnnotation(scope); + + idl_fileOutPrintf(idl_fileCur(), "enums{%d} = '%s';\n", enumIdx, enumName); + enumIdx++; + enumScopeStack = simulinkScope(scope); + enumNumElements = idl_typeEnumNoElements (enumSpec); + enumElemIdx = 0; + idl_fileOutPrintf(idl_fileCur(), "Simulink.defineIntEnumType('%s',{", enumName); + + /* return idl_explore to indicate that the rest of the structure needs to be processed */ + return idl_explore; +} + +/** @brief callback function called on closure of an enumeration in the IDL input file. + * + * Generate code for the following IDL construct: + * @verbatim + enum { + ; + ... ... + ; + => }; + @endverbatim + * + * @param name Name of the enumeration + */ +static void +idl_enumerationClose( + const char *name, + void *userData) +{ + c_ulong i; + OS_UNUSED_ARG(name); + OS_UNUSED_ARG(userData); + + idl_fileOutPrintf(idl_fileCur(), "},["); + for (i = 0; i < enumNumElements; i++) { + idl_fileOutPrintf(idl_fileCur(), "%d", i); + if (i != enumNumElements - 1) { + idl_fileOutPrintf(idl_fileCur(), ";"); + } + } + idl_fileOutPrintf(idl_fileCur(), "]"); + idl_fileOutPrintf(idl_fileCur(), ", 'Description', '%s%s'", enumScopeStack, enumFileAnnotation); + os_free((void*)enumScopeStack); + os_free((void*)enumFileAnnotation); + + idl_fileOutPrintf(idl_fileCur(),");\n\n"); +} + +/** @brief callback function called on definition of an enumeration element in the IDL input file. + * + * Generate code for the following IDL construct: + * @verbatim + enum { + => , + => ... ... + => + }; + @endverbatim + * + * For the last element generate: + * @verbatim + + @endverbatim + * For any but the last element generate: + * @verbatim + , + @endverbatim + * + * @param scope Current scope + * @param name Name of the enumeration element + */ +static void +idl_enumerationElementOpenClose ( + idl_scope scope, + const char *name, + void *userData) +{ + OS_UNUSED_ARG(scope); + OS_UNUSED_ARG(userData); + + idl_fileOutPrintf(idl_fileCur(), "'%s'", name); + if (enumElemIdx != enumNumElements - 1) { + idl_fileOutPrintf(idl_fileCur(), ","); + } + enumElemIdx++; +} + +static void +idl_sequenceOpenClose( + idl_scope scope, + idl_typeSeq typeSeq, + void *userData) +{ + c_ulong seqMax; + c_char *wrappedTypeDimensions; + c_ulong showWarning = OS_TRUE; + const c_char *idlFileAnnotation = simulinkIdlFileAnnotation(scope); + c_char *seqAnnotation = simulinkTypeAnnotation(idl_typeSpec(typeSeq)); + c_char *name = simulinkSeqClassName(typeSeq); + idl_typeSpec wrappedTypeSpec = idl_typeSeqType(typeSeq); + c_char* wrappedTypeName = simulinkSeqWrappedTypeNameRef(wrappedTypeSpec); + c_char *wrappedTypeAnnotation = simulinkTypeAnnotation(wrappedTypeSpec); + const c_char *busName = simulink_getClassNameFromName(scope, name, showWarning); + if(!simulink_containSeqType(idl_typeSeqActual(typeSeq))) { + simulink_recordStringBound(idl_typeSpec(typeSeq), scope, name); + } + seqMax = simulink_seqTypeBound(typeSeq, scope, name); + wrappedTypeDimensions = simulink_sequenceTypeDimensions(wrappedTypeSpec, seqMax); + + OS_UNUSED_ARG(userData); + + /* TODO: check whether we've seen this class before */ + + busElemIdx = 1; + + idl_fileOutPrintf(idl_fileCur(), "busses{1,%d} = '%s';\n", busIdx, busName); + idl_fileOutPrintf(idl_fileCur(), "busses{2,%d} = Simulink.Bus;\n", busIdx); + idl_fileOutPrintf(idl_fileCur(), "busses{2,%d}.Description = '%s%s';\n", + busIdx, seqAnnotation, idlFileAnnotation); + idl_fileOutPrintf(idl_fileCur(), "busses{2,%d}.DataScope = 'Auto';\n", busIdx); + idl_fileOutPrintf(idl_fileCur(), "busses{2,%d}.HeaderFile = '';\n", busIdx); + idl_fileOutPrintf(idl_fileCur(), "busses{2,%d}.Alignment = -1;\n", busIdx); + os_free((void*)idlFileAnnotation); + + idl_fileOutPrintf(idl_fileCur(), "busses{3,%d} = '';\n", busIdx); + + /* fields */ + /* Set the 'length' bus properties. */ + idl_fileOutPrintf(idl_fileCur(), "saveVarsTmp(%d) = Simulink.BusElement;\n", busElemIdx); + idl_fileOutPrintf(idl_fileCur(), "saveVarsTmp(%d).Name = 'length';\n", busElemIdx); + idl_fileOutPrintf(idl_fileCur(), "saveVarsTmp(%d).Dimensions = 1;\n", busElemIdx); + idl_fileOutPrintf(idl_fileCur(), "saveVarsTmp(%d).DataType = 'uint32';\n", busElemIdx); + idl_fileOutPrintf(idl_fileCur(), "saveVarsTmp(%d).Description = '';\n", busElemIdx); + idl_fileOutPrintf(idl_fileCur(), "saveVarsTmp(%d).Complexity = 'real';\n", busElemIdx); + idl_fileOutPrintf(idl_fileCur(), "saveVarsTmp(%d).Min = [];\n", busElemIdx); + idl_fileOutPrintf(idl_fileCur(), "saveVarsTmp(%d).Max = [];\n", busElemIdx); + idl_fileOutPrintf(idl_fileCur(), "saveVarsTmp(%d).DimensionsMode = 'Fixed';\n", busElemIdx); + idl_fileOutPrintf(idl_fileCur(), "saveVarsTmp(%d).SamplingMode = 'Sample based';\n", busElemIdx); + idl_fileOutPrintf(idl_fileCur(), "saveVarsTmp(%d).SampleTime = -1;\n", busElemIdx); + idl_fileOutPrintf(idl_fileCur(), "saveVarsTmp(%d).DocUnits = '';\n", busElemIdx); + + busElemIdx++; + + /* Set the 'buffer' bus properties. */ + idl_fileOutPrintf(idl_fileCur(), "saveVarsTmp(%d) = Simulink.BusElement;\n", busElemIdx); + idl_fileOutPrintf(idl_fileCur(), "saveVarsTmp(%d).Name = 'buffer';\n", busElemIdx); + idl_fileOutPrintf(idl_fileCur(), "saveVarsTmp(%d).Dimensions = %s;\n", busElemIdx, wrappedTypeDimensions); + idl_fileOutPrintf(idl_fileCur(), "saveVarsTmp(%d).DataType = '%s';\n", busElemIdx, wrappedTypeName); + idl_fileOutPrintf(idl_fileCur(), "saveVarsTmp(%d).Description = '%s';\n", busElemIdx, wrappedTypeAnnotation); + idl_fileOutPrintf(idl_fileCur(), "saveVarsTmp(%d).Complexity = 'real';\n", busElemIdx); + idl_fileOutPrintf(idl_fileCur(), "saveVarsTmp(%d).Min = [];\n", busElemIdx); + idl_fileOutPrintf(idl_fileCur(), "saveVarsTmp(%d).Max = [];\n", busElemIdx); + idl_fileOutPrintf(idl_fileCur(), "saveVarsTmp(%d).DimensionsMode = 'Fixed';\n", busElemIdx); + idl_fileOutPrintf(idl_fileCur(), "saveVarsTmp(%d).SamplingMode = 'Sample based';\n", busElemIdx); + idl_fileOutPrintf(idl_fileCur(), "saveVarsTmp(%d).SampleTime = -1;\n", busElemIdx); + idl_fileOutPrintf(idl_fileCur(), "saveVarsTmp(%d).DocUnits = '';\n", busElemIdx); + + busElemIdx++; + + /* finish up*/ + idl_fileOutPrintf(idl_fileCur(), "busses{2,%d}.Elements = saveVarsTmp;\n", busIdx); + idl_fileOutPrintf(idl_fileCur(), "clear saveVarsTmp;\n\n"); + busIdx++; + + simulink_setStrMaxDimension(MAX_UNBOUNDED_STR_DEFAULT); + + os_free((void *)name); + os_free((void *)wrappedTypeDimensions); + os_free((void *)wrappedTypeName); +} + +/** @brief callback function called on module definition in the IDL input file. + * + * Generate code for the following IDL construct: + * @verbatim + => module { + + }; + @endverbatim + * + * This fuction generates the prototype of the function that + * is responsible for loading the metadata into the database. + * The name of the function is: + * @verbatim + ______load + @endverbatim + * For the Splice types, no further actions are required. + * + * @param scope Current scope (and scope of the module definition) + * @param name Name of the defined module + */ +static idl_action +idl_moduleOpen( + idl_scope scope, + const char *name, + void *userData) +{ + OS_UNUSED_ARG(scope); + OS_UNUSED_ARG(name); + OS_UNUSED_ARG(userData); + /* return idl_explore to indicate that the rest of the module needs to be processed */ + return idl_explore; +} + +/** + * Standard control structure to specify that inline + * type definitions are to be processed prior to the + * type itself in contrast with inline. +*/ +static idl_programControl idl_genSimulinkLoadControl = { + idl_prior +}; + +/** @brief return the program control structure for the splice type generation functions. + */ +static idl_programControl * +idl_getControl( + void *userData) +{ + OS_UNUSED_ARG(userData); + return &idl_genSimulinkLoadControl; +} + +/** + * Specifies the callback table for the splice type generation functions. + */ +static struct idl_program +idl_genSimulink = { + idl_getControl, + idl_fileOpen, + idl_fileClose, + idl_moduleOpen, + NULL, /* idl_moduleClose */ + idl_structureOpen, + idl_structureClose, + idl_structureMemberOpenClose, + idl_enumerationOpen, + idl_enumerationClose, + idl_enumerationElementOpenClose, + NULL, /* idl_unionOpen */ + NULL, /* idl_unionClose */ + NULL, /* idl_unionCaseOpenClose */ + NULL, /* idl_unionLabelsOpenClose */ + NULL, /* idl_unionLabelOpenClose */ + NULL, /* idl_typedefOpenClose */ + NULL, /* idl_boundedStringOpenClose */ + idl_sequenceOpenClose, /* idl_sequenceOpenClose */ + NULL, /* idl_constantOpenClose */ + NULL, /* idl_artificialDefaultLabelOpenClose */ + NULL /* userData */ +}; + +/** @brief return the callback table for the splice type generation functions. + */ +idl_program +idl_genSimulinkProgram( + void) +{ + return &idl_genSimulink; +} diff --git a/src/tools/idlpp/code/idl_genSimulink.h b/src/tools/idlpp/code/idl_genSimulink.h new file mode 100644 index 000000000..74f0ac4b9 --- /dev/null +++ b/src/tools/idlpp/code/idl_genSimulink.h @@ -0,0 +1,28 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#ifndef IDL_GENSIMULINK_H +#define IDL_GENSIMULINK_H + +#include "idl_program.h" + +idl_program idl_genSimulinkProgram (void); + +#endif /* IDL_GENSIMULINK_H */ diff --git a/src/tools/idlpp/code/idl_genSimulinkHelper.c b/src/tools/idlpp/code/idl_genSimulinkHelper.c new file mode 100755 index 000000000..eea69bcd4 --- /dev/null +++ b/src/tools/idlpp/code/idl_genSimulinkHelper.c @@ -0,0 +1,932 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "idl_genSimulinkHelper.h" +#include "idl_keyDef.h" +#include "idl_typeSpecifier.h" +#include "os_stdlib.h" +#include "os_string.h" +#include "os_heap.h" + +c_char +*simulinkScope( + idl_scope scope) +{ + char *scopeStack = os_strdup (""); + if (idl_scopeStackSize(scope) != 0) { + char *sPrefix = "@Scope("; + int si; + scopeStack = os_realloc(scopeStack, strlen(sPrefix) + 1); + os_strcat(scopeStack, sPrefix); + for (si = 0; si < idl_scopeStackSize(scope); si++) { + size_t slen; + char *seName = idl_scopeElementName(idl_scopeIndexed(scope, si)); + + /* 2 for scope separator, 1 for trailing parentheses */ + slen = strlen (scopeStack) + 2 + strlen (seName) + 1; + scopeStack = os_realloc(scopeStack, slen + 1); + if (strlen(scopeStack) != strlen(sPrefix)) { + os_strcat(scopeStack, "::"); + } + os_strcat (scopeStack, seName); + } + os_strcat (scopeStack, ")"); + } + return scopeStack; +} + +static c_char +*simulinkQualifiedElement( + idl_scope scope, + const char *name) +{ + size_t slen = NULL; + idl_scopeType currentScopeType = NULL; + char *scopeStack = os_strdup (""); + if (idl_scopeStackSize(scope) != 0) { + int si; + for (si = 0; si < idl_scopeStackSize(scope); si++) { + char *seName = idl_scopeElementName(idl_scopeIndexed(scope, si)); + + /* 2 for scope separator, 1 for null byte */ + slen = strlen (scopeStack) + 2 + strlen (seName) +1; + scopeStack = os_realloc(scopeStack, slen); + if (strlen(scopeStack) != 0) { + os_strcat(scopeStack, "::"); + } + os_strcat (scopeStack, seName); + } + if(strlen(name) != 0) { + /* 2 for scope separator, 1 for null byte */ + slen = strlen (scopeStack) + 2 + strlen (name) + 1; + scopeStack = os_realloc(scopeStack, slen); + if (strlen(scopeStack) != 0) { + currentScopeType = idl_scopeElementType(idl_scopeCur(scope)); + if(currentScopeType == idl_tStruct) { + os_strcat(scopeStack, "."); + } else { + os_strcat(scopeStack, "::"); + } + } + os_strcat (scopeStack, name); + } + } else { + os_free(scopeStack); + scopeStack = os_strdup(name); + } + return scopeStack; +} + +static os_equality +table_cmpFunc( + void *o1, + void *o2, + void *args) +{ + os_equality result; + os_int cmp = strcmp((char*)o1,(char*)o2); + + OS_UNUSED_ARG(args); + + if (cmp < 0) { + result = OS_LT; + } else if (cmp > 0) { + result = OS_GT; + } else { + result = OS_EQ; + } + return result; +} + +static c_char * +simulink_getTableValue( + ut_table table, + const char *key) +{ + char *value = NULL; + if(table != NULL) + { + value = (char *) ut_get (ut_collection(table), (void *) key); + if(value != NULL) { + return value; + } + } + return NULL; +} + +static void +freeTableKeys( + void *e, + void *arg) +{ + OS_UNUSED_ARG(arg); + if(e != NULL) { + os_free(e); + } +} + +static void +freeTableValues( + void *e, + void *arg) +{ + OS_UNUSED_ARG(arg); + if(e != NULL) { + os_free(e); + } +} + +ut_table +simulink_createTable() +{ + ut_table table = NULL; + table = ut_tableNew(table_cmpFunc, NULL, freeTableKeys, NULL, freeTableValues, NULL); + return table; +} + +static void +simulink_insertTableValue( + ut_table table, + const char* key, + const char* value) +{ + (void) ut_tableInsert(table, (void *) key, (void *) value); +} + +static char** +getTokens( + char *line) +{ + static char *tokens[2]; + const char *token0 = NULL; + char* value = strchr(line,'='); + + if(value == NULL) + { + return NULL; + } + + token0 = os_strndup(line, (os_size_t)(value - line)); /* string before the '=' sign */ + tokens[0] = os_str_trim(token0, NULL); /* removes white spaces from beginning and end of the string */ + if( tokens[0] == token0) { + tokens[0] = os_strdup(tokens[0]); + } + os_free((void *)token0); + + tokens[1] = os_str_trim(value + 1, NULL); /* removes white spaces from beginning and end of the second token */ + if( tokens[1] == value + 1) { + tokens[1] = os_strdup(tokens[1]); + } + + return tokens; +} + +static void +readPropertiesFile( + FILE *file, + ut_table table) +{ + char line[1024]; + + while (fgets(line, sizeof(line), file) != NULL) + { + char **value = getTokens(line); + if(value != NULL && strlen(value[0]) > 0 && strlen(value[1]) > 0) + { + if(value[0][0]=='#') + { + //free tokens that don't get insert to table + os_free((void *)value[0]); + os_free((void *)value[1]); + continue; + } + simulink_insertTableValue(table, value[0], value[1]); + } + } +} + +void +simulink_readProperties( + char *fileName, + ut_table table) +{ + FILE *file; + if (fileName != 0 && (file = fopen(fileName, "r")) != 0) + { + readPropertiesFile(file, table); + (void) fclose(file); + } +} + +static os_int32 +tc_tableWalkAction ( + void *k, + void *v, + void *arg) +{ + fprintf((FILE *)arg, "%s = %s\n", (char*)k, (char*)v); + return 1; +} + +void +simulink_writeProperties( + ut_table table, + const os_char *fileName) +{ + os_int32 elementCount = ut_count((ut_collection)table); + + FILE *file; + if(elementCount > 0) + { + if (fileName != 0 && (file = fopen(fileName, "w")) != 0) + { + fprintf(file, "# Each line in this file defines a key-value pair that determines how Simulink names are\n" + "# generated or how IDL unbounded String fields have bounds set in Simulink.\n" + "#\n" + "# Names: Because the Simulink namespace is 'flat', multiple IDL elements may map to the\n" + "# same Simulink name. The IDL import operation will report an error in such cases.\n" + "#\n" + "# String bounds: Simulink cannot fully support IDL unbounded strings. Because every\n" + "# Simulink bus must fixed size, IDLPP specifies a maximum size for unbounded strings. The\n" + "# default is 256 characters. This file allows you change the maximum for an unbound string.\n" + "#\n" + "# The file format is as follows:\n" + "#\n" + "# 1) lines are of the format: = . Spaces at the beginning or end of the line,\n" + "# or around the equals sign are ignored.\n" + "# 2) for lines with key's of the form #name, the value is the Simulink\n" + "# name assigned to the generated Simulink element.\n" + "# 3) for lines with key's of the form #stringMax, the value is the\n" + "# Simulink an integer specifying the maximum size for an unbounded string.\n" + "#\n" + "# To change the generated Simulink element, change one or more values in this file, and then\n" + "# re-run the IDL import.\n\n"); + (void) ut_tableKeyValueWalk(table, tc_tableWalkAction, file); + (void) fclose(file); + } + } +} + + +#define KEY_LIST_ANNOTATION "@Key(%s)" +const c_char * +simulinkKeyListAnnotation( + idl_scope scope, + const char *name) +{ + const c_char *key_list = idl_keyResolve(idl_keyDefDefGet(), scope, name); + c_char *result = NULL; + if(key_list != NULL) { + result = (c_char *)os_malloc(sizeof(KEY_LIST_ANNOTATION) + strlen(key_list)); + os_sprintf(result, KEY_LIST_ANNOTATION, key_list); + } else { + result = os_strdup(""); + } + return (const c_char*)result; +} + +#define IDL_FILE_ANNOTATION "@IdlFile(%s.idl)" +const c_char * +simulinkIdlFileAnnotation( + idl_scope scope) { + c_char *baseName = idl_scopeBasename(scope); + c_char *result = (c_char *)os_malloc(sizeof(IDL_FILE_ANNOTATION) + strlen(baseName)); + os_sprintf(result, IDL_FILE_ANNOTATION, baseName); + os_free((void*)baseName); + return (const c_char *)result; +} + +const c_char +*simulink_getClassNameFromName( + idl_scope scope, + const char *name, + c_ulong showWarning) +{ + const char *className; + char *tableValue; + char *qualifiedName = simulinkQualifiedElement(scope, name); + /*sizeof(“#nameâ€) includes the null-byte */ + qualifiedName = (char *)os_realloc(qualifiedName, strlen(qualifiedName) + sizeof("#name")); + os_strcat(qualifiedName, "#name"); + + className = simulink_getTableValue(simulink_propertiesTable, qualifiedName); + if(className == NULL) + { + className = name; + simulink_insertTableValue(simulink_propertiesTable, os_strdup(qualifiedName), os_strdup(className)); + } + if(showWarning) { + tableValue = simulink_getTableValue(simulink_nameTable, className); + if(tableValue != NULL) { + fprintf(stderr, "Error: IDL element %.*s translates to the Simulink artifact named %s,\n" + "which already corresponds to another IDL element %.*s.\n" + "Edit the %s file to assign unique Simulink names to each IDL element.\n", + (int)(strlen(qualifiedName)-strlen("#name")), qualifiedName, className, + (int)(strlen(tableValue)-strlen("#name")), tableValue, simulink_propertiesFileName); + } else { + simulink_insertTableValue(simulink_nameTable, os_strdup(className), os_strdup(qualifiedName)); + } + } + os_free((void*)qualifiedName); + return className; +} + +c_char +*simulinkGetDataType( + idl_typeSpec typeSpec) +{ + char *idlSpecName = NULL; + char *dataType = NULL; + size_t len; + + idl_typeUser typeUser = idl_typeUser(typeSpec); + idl_scope type_scope = idl_typeUserScope(typeUser); + char *qualifiedTypeSpecName = simulinkQualifiedElement(type_scope, (char *)idl_typeSpecName(typeSpec)); + qualifiedTypeSpecName = os_realloc(qualifiedTypeSpecName, strlen(qualifiedTypeSpecName) + sizeof("#name")); + os_strcat(qualifiedTypeSpecName, "#name"); + + idlSpecName = simulink_getTableValue(simulink_propertiesTable, qualifiedTypeSpecName); + if(idlSpecName == NULL) { + idlSpecName = idl_typeSpecName(typeSpec); + simulink_insertTableValue(simulink_propertiesTable, os_strdup(qualifiedTypeSpecName), os_strdup(idlSpecName)); + } + + len = strlen(idlSpecName); + if (idl_typeSpecType(typeSpec) == idl_tstruct) { + dataType = os_malloc(sizeof("Bus: ") + len); /*sizeof("Bus: ") includes null byte*/ + os_sprintf(dataType, "Bus: %s", idlSpecName); + } else if (idl_typeSpecType(typeSpec) == idl_tenum) { + dataType = os_malloc(sizeof("Enum: ") + len);/*sizeof("Enum: ") includes null byte*/ + os_sprintf(dataType, "Enum: %s", idlSpecName); + } else { + printf("idl_genSimulinkHelper.c:simulinkClassName: Unexpected type %d\n", + idl_typeSpecType(typeSpec)); + } + + os_free(qualifiedTypeSpecName); + + return dataType; +} + +c_char +*simulinkClassName( + idl_typeSpec typeSpec) +{ + const char *idlSpecName = idl_typeSpecName(typeSpec); + size_t len = strlen(idlSpecName); + char *dataType = NULL; + if (idl_typeSpecType(typeSpec) == idl_tstruct) { + dataType = os_malloc(sizeof("Bus: ") + len); /*sizeof("Bus: ") includes null byte*/ + os_sprintf(dataType, "Bus: %s", idlSpecName); + } else if (idl_typeSpecType(typeSpec) == idl_tenum) { + dataType = os_malloc(sizeof("Enum: ") + len);/*sizeof("Enum: ") includes null byte*/ + os_sprintf(dataType, "Enum: %s", idlSpecName); + } else { + printf("idl_genSimulinkHelper.c:simulinkClassName: Unexpected type %d\n", + idl_typeSpecType(typeSpec)); + } + return dataType; +} + +c_ulong +simulink_containSeqType( + idl_typeSpec typeSpec) { + if (idl_typeSpecType(typeSpec) == idl_tbasic) { + /* if the specified type is a basic type */ + return OS_FALSE; + } else if (idl_typeSpecType(typeSpec) == idl_ttypedef) { + return simulink_containSeqType(idl_typeDefActual(idl_typeDef(typeSpec))); + } else if (idl_typeSpecType(typeSpec) == idl_tarray) { + return simulink_containSeqType (idl_typeArrayActual(idl_typeArray(typeSpec))); + } else if(idl_typeSpecType(typeSpec) == idl_tseq) { + return OS_TRUE; + } + + return OS_FALSE; +} + +static idl_typeBasic +simulink_typeBasicFromTypeSpec( + idl_typeSpec typeSpec) +{ + if (idl_typeSpecType(typeSpec) == idl_tbasic) { + /* if the specified type is a basic type */ + return idl_typeBasic(typeSpec); + } else if (idl_typeSpecType(typeSpec) == idl_ttypedef) { + return simulink_typeBasicFromTypeSpec(idl_typeDefActual(idl_typeDef(typeSpec))); + } else if (idl_typeSpecType(typeSpec) == idl_tarray) { + return simulink_typeBasicFromTypeSpec (idl_typeArrayActual(idl_typeArray(typeSpec))); + } else if(idl_typeSpecType(typeSpec) == idl_tseq) { + return simulink_typeBasicFromTypeSpec (idl_typeSeqActual(idl_typeSeq(typeSpec))); + } + return NULL; +} + +c_char +*idl_SimulinkTypeFromTypeSpec( + idl_typeSpec typeSpec) +{ + c_char *typeName = NULL; + + if (idl_typeSpecType(typeSpec) == idl_tbasic) { + /* if the specified type is a basic type */ + switch (idl_typeBasicType(idl_typeBasic(typeSpec))) { + case idl_short: + typeName = os_strdup("int16"); + break; + case idl_ushort: + typeName = os_strdup("uint16"); + break; + case idl_long: + typeName = os_strdup("int32"); + break; + case idl_ulong: + typeName = os_strdup("uint32"); + break; + case idl_longlong: + case idl_ulonglong: + typeName = os_strdup("double"); + break; + case idl_float: + typeName = os_strdup("single"); + break; + case idl_double: + typeName = os_strdup("double"); + break; + case idl_char: + typeName = os_strdup("int8"); + break; + case idl_string: + typeName = os_strdup("int8"); + break; + case idl_boolean: + typeName = os_strdup("boolean"); + break; + case idl_octet: + typeName = os_strdup("uint8"); + break; + default: + /* No processing required, empty statement to satisfy QAC */ + break; + /* QAC EXPECT 2016; Default case must be empty here */ + } + } else if (idl_typeSpecType(typeSpec) == idl_tarray) { + return idl_SimulinkTypeFromTypeSpec (idl_typeArrayActual(idl_typeArray (typeSpec))); + } else if (idl_typeSpecType(typeSpec) == idl_tstruct || + idl_typeSpecType(typeSpec) == idl_tenum) { + return simulinkClassName(typeSpec); + } else if (idl_typeSpecType(typeSpec) == idl_ttypedef) { + return idl_SimulinkTypeFromTypeSpec (idl_typeDefActual(idl_typeDef (typeSpec))); + } else if(idl_typeSpecType(typeSpec) == idl_tseq) { + c_ulong showWarning = OS_FALSE; + return simulinkSeqClassRef(idl_typeSeq(typeSpec), showWarning); + } else { + printf("idl_genSimulinkHelper.c:idl_SimulinkTypeFromTypeSpec: Unexpected type %d\n", + idl_typeSpecType(typeSpec)); + } + return typeName; +} + +c_char * +simulinkSeqTypeName( + idl_typeSpec typeSpec) +{ + idl_type type = idl_typeSpecType(typeSpec); + switch(type) { + case idl_tbasic: + switch(idl_typeBasicType(idl_typeBasic(typeSpec))) { + case idl_boolean: + return ("boolean"); + case idl_char: + return ("int8"); + case idl_octet: + return ("uint8"); + case idl_short: + return ("int16"); + case idl_ushort: + return ("uint16"); + case idl_long: + return ("int32"); + case idl_ulong: + return ("uint32"); + case idl_longlong: + return ("double"); /*int64*/ + case idl_ulonglong: + return ("double"); /*uint64*/ + case idl_float: + return ("single"); + case idl_double: + return ("double"); + case idl_string: + { + static char buffer[30]; + idl_typeBasic basicSpec = idl_typeBasic(typeSpec); + c_ulong strMax = idl_typeBasicMaxlen(basicSpec); + if(strMax) { + sprintf(buffer, "string%u", strMax); + } else { + sprintf(buffer, "string"); + } + return buffer; + } + } + break; + case idl_tenum: + case idl_tstruct: + return idl_typeSpecName(typeSpec); + case idl_ttypedef: + { + idl_typeSpec actualSpec = idl_typeDefActual(idl_typeDef(typeSpec)); + return simulinkSeqTypeName(actualSpec); + } + case idl_tarray: + { + static c_char formatted_name[256]; /* TODO: Dynamically allocate this, and all return values */ + idl_typeArray typeArray = idl_typeArray(typeSpec); + idl_typeSpec actualSpec = idl_typeArrayActual(typeArray); + c_ulong n = simulink_arrayNDimensions(typeArray); + c_ulong *dims = (c_ulong *)os_malloc(n * sizeof(c_ulong)); + c_char *formatted_dims = (c_char *)os_malloc(n * (20 + 1) + 1); + c_ulong i; + + idl_typeBasic typeBasic = simulink_typeBasicFromTypeSpec(typeSpec); + if(typeBasic != NULL && idl_typeBasicType(typeBasic) == idl_string && !simulink_containSeqType(typeSpec)) { + n--; + } + + simulink_arrayGetDimensions(typeArray, dims); + *formatted_dims = '\0'; + for(i = 0; i < n; i++) { + c_char formatted_number[21]; + os_strcat(formatted_dims, "_"); + sprintf(formatted_number, "%u", dims[i]); + os_strcat(formatted_dims, formatted_number); + } + sprintf(formatted_name, "%s%s", simulinkSeqTypeName(actualSpec), formatted_dims); + os_free((void*)formatted_dims); + os_free((void*)dims); + return formatted_name; + } + case idl_tseq: + { + idl_typeSeq typeSeq = idl_typeSeq(typeSpec); + return simulinkSeqClassName(typeSeq); + } + case idl_tunion: + printf("idl_genSimulinkHelper.c:simulinkSeqTypeName: Unsupported type in sequence: %d\n", + idl_typeSpecType(typeSpec)); + exit(1); + return ""; + } + return ""; +} + +c_char * +simulinkSeqWrappedTypeNameRef( + idl_typeSpec typeSpec) +{ + idl_type type = idl_typeSpecType(typeSpec); + switch(type) { + case idl_tenum: + { + c_char *wrappedTypeName = simulinkSeqTypeName(typeSpec); + c_char *result = (c_char *)os_malloc(strlen(wrappedTypeName) + sizeof("Enum: ")); + sprintf(result, "Enum: %s", wrappedTypeName); + return result; + } + break; + case idl_tstruct: + { + c_char *wrappedTypeName = simulinkSeqTypeName(typeSpec); + c_char *result = (c_char *)os_malloc(strlen(wrappedTypeName) + sizeof("Bus: ")); + sprintf(result, "Bus: %s", wrappedTypeName); + return result; + } + break; + case idl_tseq: + { + c_ulong showWarning = OS_FALSE; + idl_typeSeq seqSpec = idl_typeSeq(typeSpec); + c_char *simulinkType = simulinkSeqClassRef(seqSpec, showWarning); + return simulinkType; + } + break; + case idl_tbasic: + return idl_SimulinkTypeFromTypeSpec(typeSpec); + case idl_ttypedef: + { + while (idl_typeSpecType(typeSpec) == idl_ttypedef) { + typeSpec = idl_typeDefRefered(idl_typeDef(typeSpec)); + } + return simulinkSeqWrappedTypeNameRef(typeSpec); + } + case idl_tarray: + { + idl_typeArray typeArray = idl_typeArray(typeSpec); + return simulinkSeqWrappedTypeNameRef(idl_typeArrayActual(typeArray)); + } + default: + printf("*** ERROR *** Should not get here. idl_type = %d\n", type); + exit(1); + break; + } + + return NULL; +} + +c_ulong +simulinkSequenceMax( + idl_typeSeq typeSeq) +{ + c_ulong seqMax = idl_typeSeqMaxSize(typeSeq); + return seqMax; +} + +c_ulong +simulinkStringMax( + idl_typeBasic typeString) +{ + c_ulong seqMax = idl_typeBasicMaxlen(typeString); + + if(!seqMax) { + /* TODO: figure out if there is a user provided override for seqMax */ + seqMax = simulink_getStrMaxDimension(); + } + return seqMax; +} + +#define SEQ_CLASS_NAME_FMT "seq%s_%s" +c_char * +simulinkSeqClassName( + idl_typeSeq typeSeq) +{ + c_char* wrappedTypeName = simulinkSeqTypeName(idl_typeSeqType(typeSeq)); + c_char *className; + c_ulong seqMax = simulinkSequenceMax(typeSeq); + c_char max_bound[20] = ""; + if(seqMax) { + sprintf(max_bound, "%u", seqMax); + } + className = os_malloc(sizeof(SEQ_CLASS_NAME_FMT) + strlen(max_bound) + strlen(wrappedTypeName)); + sprintf(className, SEQ_CLASS_NAME_FMT, max_bound, wrappedTypeName); + + return className; +} + +#define SEQ_CLASS_REF_FMT "Bus: %s" +c_char * +simulinkSeqClassRef( + idl_typeSeq typeSeq, + c_ulong showWarning) +{ + c_char* className = simulinkSeqClassName(typeSeq); + idl_typeUser typeUser = idl_typeUser(typeSeq); + idl_scope scope = idl_typeUserScope(typeUser); + const char *busName = simulink_getClassNameFromName(scope, className, showWarning); + + c_char *classRef = (c_char *)os_malloc(sizeof(SEQ_CLASS_REF_FMT) + strlen(busName)); + sprintf(classRef, SEQ_CLASS_REF_FMT, busName); + os_free((void*)className); + + return classRef; +} + +c_char * +simulinkSeqDimensions( + idl_typeSeq typeSeq) +{ + static c_char buffer[40]; + c_ulong seqMax = simulinkSequenceMax(typeSeq); + idl_typeSpec wrappedType = idl_typeSeqType(typeSeq); + idl_type type = idl_typeSpecType(wrappedType); + if(type == idl_tbasic + && idl_typeBasicType(idl_typeBasic(wrappedType)) == idl_string) { + sprintf(buffer, "[%u, %u]", seqMax, simulinkStringMax(idl_typeBasic(wrappedType))); + } else if(type == idl_tarray) { + idl_typeArraySize(idl_typeArray(wrappedType)); + } else { + sprintf(buffer, "%u", seqMax); + } + + return buffer; + +} + +c_char * +simulinkTypeAnnotation( + idl_typeSpec typeSpec) +{ + c_char *annotation = ""; + idl_type type = idl_typeSpecType(typeSpec); + if(type == idl_tbasic) { + idl_typeBasic basicSpec = idl_typeBasic(typeSpec); + idl_basicType basicType = idl_typeBasicType(basicSpec); + if(basicType == idl_string) { + annotation = idl_typeBasicMaxlen(basicSpec) ? "@BString" : "@String"; + } + } else if(type == idl_tseq) { + annotation = idl_typeSeqMaxSize(idl_typeSeq(typeSpec)) ? "@BSequence" : "@Sequence"; + } else if(type == idl_tarray) { + annotation = simulinkTypeAnnotation(idl_typeArrayActual(idl_typeArray (typeSpec))); + } + + return annotation; +} + +c_ulong +simulink_arrayNDimensions( + idl_typeArray typeArray) +{ + idl_typeSpec wrappedTypeSpec = idl_typeArrayType(typeArray); + idl_type wrappedType = idl_typeSpecType(wrappedTypeSpec); + if(wrappedType == idl_tarray) { + return 1 + simulink_arrayNDimensions(idl_typeArray(wrappedTypeSpec)); + } else if(wrappedType == idl_tbasic) { + idl_typeBasic typeBasic = idl_typeBasic(wrappedTypeSpec); + return idl_typeBasicType(typeBasic) == idl_string ? 2 : 1; + } else { + return 1; + } +} + +static c_ulong str_max_dimension = 256; +c_ulong +simulink_getStrMaxDimension() +{ + return str_max_dimension; +} + +void +simulink_setStrMaxDimension( + c_ulong stringMax) +{ + str_max_dimension = stringMax; +} + +#define MAX_UNBOUNDED_STR_DEFAULT 256 +void +simulink_recordStringBound( + idl_typeSpec typeSpec, + idl_scope scope, + const char *name) +{ + idl_typeBasic typeBasic = simulink_typeBasicFromTypeSpec(typeSpec); + if(typeBasic != NULL && idl_typeBasicType(typeBasic) == idl_string) { + if(idl_typeBasicMaxlen(typeBasic) == NULL) { + c_char *stringDims; + c_char *qualifiedElement = simulinkQualifiedElement(scope, name); + qualifiedElement = (char *)os_realloc(qualifiedElement, strlen(qualifiedElement) + sizeof("#stringMax")); + os_strcat(qualifiedElement, "#stringMax"); + + stringDims = simulink_getTableValue(simulink_propertiesTable, qualifiedElement); + if(stringDims == NULL) + { + stringDims = (char *) os_malloc(sizeof(MAX_UNBOUNDED_STR_DEFAULT)); + os_sprintf(stringDims, "%d", MAX_UNBOUNDED_STR_DEFAULT); + simulink_insertTableValue(simulink_propertiesTable, os_strdup(qualifiedElement), stringDims); + } else if (os_strtoull(stringDims, (char **)NULL, 10) == 0) { + fprintf(stderr, "Error: Entered value for %s is not a valid integer to set the maximum size for an unbounded string.\n" + "Edit the %s file to assign an integer to specify the maximum size for %.*s.\n", + qualifiedElement, simulink_propertiesFileName, (int)(strlen(qualifiedElement) - strlen("#stringMax")), qualifiedElement); + } + simulink_setStrMaxDimension((c_ulong) os_strtoull(stringDims, (char **)NULL, 10)); + os_free((void *) qualifiedElement); + } + } +} + +#define MAX_UNBOUNDED_SEQ_DEFAULT 16 +c_ulong +simulink_seqTypeBound( + idl_typeSeq typeSeq, + idl_scope scope, + const char *name) +{ + c_ulong seqMax = idl_typeSeqMaxSize(typeSeq); + if(seqMax == NULL) + { + c_char *seqDims; + c_char *qualifiedSeqName = simulinkQualifiedElement(scope, name); + qualifiedSeqName = (char *)os_realloc(qualifiedSeqName, strlen(qualifiedSeqName) + sizeof("#seqMax")); + os_strcat(qualifiedSeqName, "#seqMax"); + + seqDims = simulink_getTableValue(simulink_propertiesTable, qualifiedSeqName); + if(seqDims == NULL) { + seqDims = (char *) os_malloc(sizeof(MAX_UNBOUNDED_SEQ_DEFAULT)); + os_sprintf(seqDims, "%d", MAX_UNBOUNDED_SEQ_DEFAULT); + simulink_insertTableValue(simulink_propertiesTable, os_strdup(qualifiedSeqName), seqDims); + } else if (os_strtoull(seqDims, (char **)NULL, 10) == 0) { + fprintf(stderr, "Error: Entered value for %s is not a valid integer to set the maximum dimension for an unbounded sequence.\n" + "Edit the %s file to assign an integer to specify the maximum dimension for %.*s.\n", + qualifiedSeqName, simulink_propertiesFileName, (int)(strlen(qualifiedSeqName) - strlen("#seqMax")), qualifiedSeqName); + } + os_free((void *)qualifiedSeqName); + seqMax = (c_ulong) os_strtoull(seqDims, (char **)NULL, 10); + } + return seqMax; +} + +void +simulink_arrayGetDimensions( + idl_typeArray typeArray, + c_ulong dimensions[]) +{ + idl_typeSpec wrappedTypeSpec = idl_typeArrayType(typeArray); + idl_type wrappedType = idl_typeSpecType(wrappedTypeSpec); + + dimensions[0] = idl_typeArraySize(typeArray); + if(wrappedType == idl_tarray) { + simulink_arrayGetDimensions(idl_typeArray(wrappedTypeSpec), &dimensions[1]); + } else if(wrappedType == idl_tbasic) { + idl_typeBasic typeBasic = idl_typeBasic(wrappedTypeSpec); + if(idl_typeBasicType(typeBasic) == idl_string) { + c_ulong strMax = idl_typeBasicMaxlen(typeBasic); + dimensions[1] = strMax ? strMax : simulink_getStrMaxDimension(); + } + } +} + +c_char * +simulink_formatDimensions( + c_ulong dimensions[], + c_ulong nDimensions) +{ + /* Format is: n + * or + * [n1 n2 n3 n4] + * + * Worst case size of a dimension is 20 characters (ULONG_MAX is 20 digits). + * Worst case string to alloc is: nDimensions * (20 + 1) + 1 + */ + c_char *formatted = (c_char *)os_malloc(nDimensions * (20 + 1) + 1 + 1); + + if(nDimensions == 1) { + sprintf(formatted, "%u", dimensions[0]); + } else { + c_char formatted_number[21]; /* ULONG_MAX is 20 digits */ + c_ulong i; + sprintf(formatted, "["); + for(i = 0; i < nDimensions; i++) { + sprintf(formatted_number, "%u", dimensions[i]); + if(i > 0) { + os_strcat(formatted, " "); + } + os_strcat(formatted, formatted_number); + } + os_strcat(formatted, "]"); + } + return formatted; +} + +c_char *simulink_sequenceTypeDimensions( + idl_typeSpec typeSpec, + c_ulong seqMax) { + c_char formatted_number[20 + 1]; + + while (idl_typeSpecType(typeSpec) == idl_ttypedef) { + typeSpec = idl_typeDefRefered(idl_typeDef(typeSpec)); + } + + if(idl_typeSpecType(typeSpec) == idl_tarray) { + idl_typeArray typeArray = idl_typeArray(typeSpec); + /* allocation must include the space for seqMax */ + c_ulong n = simulink_arrayNDimensions(typeArray) + 1; + c_ulong *dims = (c_ulong *)malloc(n * sizeof(c_ulong)); + c_char *formatted = NULL; + dims[0] = seqMax; + simulink_arrayGetDimensions(typeArray, &dims[1]); + formatted = simulink_formatDimensions(dims, n); + free((void *)dims); + return formatted; + } + if(idl_typeSpecType(typeSpec) == idl_tbasic) { + idl_typeBasic typeBasic = idl_typeBasic(typeSpec); + if(idl_typeBasicType(typeBasic) == idl_string) { + c_char formatted[2 * 20 + 3 + 1]; + c_ulong strMax = idl_typeBasicMaxlen(typeBasic); + sprintf(formatted, "[%u %u]", seqMax, strMax ? strMax : simulink_getStrMaxDimension()); + return os_strdup(formatted); + } + } + + sprintf(formatted_number, "%u", seqMax); + return os_strdup(formatted_number); +} diff --git a/src/tools/idlpp/code/idl_genSimulinkHelper.h b/src/tools/idlpp/code/idl_genSimulinkHelper.h new file mode 100755 index 000000000..d025c5968 --- /dev/null +++ b/src/tools/idlpp/code/idl_genSimulinkHelper.h @@ -0,0 +1,62 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#ifndef IDL_GENSIMULINKHELPER_H +#define IDL_GENSIMULINKHELPER_H + +#include "c_typebase.h" +#include "c_iterator.h" +#include "idl_scope.h" +#include "idl_program.h" +#include "idl_typeSpecifier.h" +#include "ut_collection.h" + +ut_table simulink_propertiesTable; +ut_table simulink_nameTable; +char *simulink_propertiesFileName; + +c_char *simulinkScope(idl_scope typeSpec); +ut_table simulink_createTable(); +void simulink_readProperties(char *fileName, ut_table table); +void simulink_writeProperties(ut_table table, const os_char *fileName); +c_char *simulinkGetDataType(idl_typeSpec typeSpec); +c_char *simulinkClassName(idl_typeSpec typeSpec); +c_char *idl_SimulinkTypeFromTypeSpec(idl_typeSpec typeSpec); +const c_char *simulinkKeyListAnnotation(idl_scope scope,const char *typeName); +const c_char *simulinkIdlFileAnnotation(idl_scope scope); +c_char *simulinkSeqClassName(idl_typeSeq seqSpec); +c_char *simulinkSeqClassRef(idl_typeSeq seqSpec, c_ulong showWarning); +c_ulong simulinkSequenceMax(idl_typeSeq typeSeq); +c_ulong simulinkStringMax(idl_typeBasic typeString); +c_char *simulinkSeqTypeName(idl_typeSpec typeSpec); +c_char *simulinkSeqWrappedTypeNameRef(idl_typeSpec typeSpec); +c_char *simulinkSeqDimensions(idl_typeSeq typeSeq); +c_char *simulinkTypeAnnotation(idl_typeSpec typeSpec); +c_ulong simulink_arrayNDimensions(idl_typeArray typeArray); +c_ulong simulink_getStrMaxDimension(); +void simulink_setStrMaxDimension(c_ulong stringMax); +c_ulong simulink_containSeqType(idl_typeSpec typeSpec); +const c_char *simulink_getClassNameFromName(idl_scope scope, const char *name, c_ulong showWarning); +void simulink_recordStringBound(idl_typeSpec typeSpec, idl_scope scope, const char *name); +c_ulong simulink_seqTypeBound(idl_typeSeq typeSeq, idl_scope scope, const char *name); +void simulink_arrayGetDimensions(idl_typeArray typeArray,c_ulong dimensions[]); +c_char *simulink_formatDimensions(c_ulong dimensions[],c_ulong nDimensions); +c_char *simulink_sequenceTypeDimensions(idl_typeSpec typeSpec,c_ulong seqMax); +#endif /* IDL_GENSIMULINKHELPER_H */ diff --git a/src/tools/idlpp/code/idl_genSplHelper.c b/src/tools/idlpp/code/idl_genSplHelper.c index 62a5da263..c0ccf6ea0 100644 --- a/src/tools/idlpp/code/idl_genSplHelper.c +++ b/src/tools/idlpp/code/idl_genSplHelper.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -80,8 +81,7 @@ idl_boundsCheckFail( os_free(scopeName); } -/* Print a BOUNDSCHECK NULL error message to the default output file -*/ +/* Print a BOUNDSCHECK NULL error message to the default output file */ void idl_boundsCheckFailNull( enum idl_boundsCheckFailKind kind, @@ -163,8 +163,8 @@ idl_memoryAllocFailed( /* Print the specified indentation the the default output file, - the indent is specified in units of 4 space characters -*/ + * the indent is specified in units of 4 space characters + */ void idl_printIndent ( c_long indent) @@ -185,8 +185,8 @@ idl_typeFromTypeSpec ( } /* Return the scoped type name where for the user types, - scopes are separated by "_" chracters. -*/ + * scopes are separated by "_" chracters. + */ c_char * idl_scopedTypeName ( const idl_typeSpec typeSpec) @@ -220,8 +220,8 @@ idl_scopedTypeName ( } /* Return the scoped type name where for the user types, - scopes are separated by "_" chracters. -*/ + * scopes are separated by "_" chracters. + */ c_char * idl_scopedSplTypeName ( const idl_typeSpec typeSpec) @@ -268,22 +268,22 @@ idl_scopedSplTypeName ( } /* Return the scoped type specification where for the user types, - scopes are separated by "_" chracters. - IDL strings (bounded and unbounded) are mapped on: c_string, other - basic types are mapped on corresponding splice types - IDL structures are identified by: struct - IDL unions are identified by: struct becuase - the union mapping is: - struct { - _d; - union { - - } _u; - } - IDL enumerations are identified by: enum - IDL typedefs are formed by the scoped type name - IDL sequences are mapped on: c_sequence -*/ + * scopes are separated by "_" chracters. + * IDL strings (bounded and unbounded) are mapped on: c_string, other + * basic types are mapped on corresponding splice types + * IDL structures are identified by: struct + * IDL unions are identified by: struct becuase + * the union mapping is: + * struct { + * _d; + * union { + * + * } _u; + * } + * IDL enumerations are identified by: enum + * IDL typedefs are formed by the scoped type name + * IDL sequences are mapped on: c_sequence + */ c_char * idl_scopedTypeIdent ( const idl_typeSpec typeSpec) @@ -338,22 +338,22 @@ idl_scopedTypeIdent ( } /* Return the scoped type specification where for the user types, - scopes are separated by "_" chracters. - IDL strings (bounded and unbounded) are mapped on: c_string, other - basic types are mapped on corresponding splice types - IDL structures are identified by: struct - IDL unions are identified by: struct becuase - the union mapping is: - struct { - _d; - union { - - } _u; - } - IDL enumerations are identified by: enum - IDL typedefs are formed by the scoped type name - IDL sequences are mapped on: c_sequence -*/ + * scopes are separated by "_" chracters. + * IDL strings (bounded and unbounded) are mapped on: c_string, other + * basic types are mapped on corresponding splice types + * IDL structures are identified by: struct + * IDL unions are identified by: struct becuase + * the union mapping is: + * struct { + * _d; + * union { + * + * } _u; + * } + * IDL enumerations are identified by: enum + * IDL typedefs are formed by the scoped type name + * IDL sequences are mapped on: c_sequence + */ c_char * idl_scopedSplTypeIdent ( diff --git a/src/tools/idlpp/code/idl_genSplHelper.h b/src/tools/idlpp/code/idl_genSplHelper.h index 29eab9b9d..e73916b44 100644 --- a/src/tools/idlpp/code/idl_genSplHelper.h +++ b/src/tools/idlpp/code/idl_genSplHelper.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/idlpp/code/idl_genSpliceDep.c b/src/tools/idlpp/code/idl_genSpliceDep.c index e3182218e..9257b5820 100644 --- a/src/tools/idlpp/code/idl_genSpliceDep.c +++ b/src/tools/idlpp/code/idl_genSpliceDep.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -407,42 +408,41 @@ idl_getControl( /* idl_genSpliceDep specifies the local callback routines */ -static struct idl_program -idl_genSpliceDep = { - /* The following control is required to allow idl_walk */ - /* to analyse anonymous types within structs and unions */ - /* A special program for that would be more clear but */ - /* also slower */ - idl_getControl, - idl_fileOpen, - NULL, /* idl_fileClose */ - idl_moduleOpen, - NULL, /* idl_moduleClose */ - idl_structureOpen, - NULL, /* idl_structureClose */ - idl_structureMemberOpenClose, - NULL, /* idl_enumerationOpen */ - NULL, /* idl_enumerationClose */ - NULL, /* idl_enumerationElementOpenClose */ - idl_unionOpen, - NULL, /* idl_unionClose */ - idl_unionCaseOpenClose, - NULL, /* idl_unionLabelsOpenClose */ - NULL, /* idl_unionLabelOpenClose */ - idl_typedefOpenClose, - NULL, /* idl_boundedStringOpenClose */ - NULL, /* idl_sequenceOpenClose */ - idl_constantOpenClose, - NULL, /* idl_artificialDefaultLabelOpenClose */ - NULL /* userData */ -}; +static struct idl_program idl_genSpliceDep; /* genSpliceDepProgram returns the local table of callback routines. */ idl_program idl_genSpliceDepProgram( - void) + void *userData) { + /* The following control is required to allow idl_walk */ + /* to analyse anonymous types within structs and unions */ + /* A special program for that would be more clear but */ + /* also slower */ + idl_genSpliceDep.idl_getControl = idl_getControl; + idl_genSpliceDep.fileOpen = idl_fileOpen; + idl_genSpliceDep.fileClose = NULL; + idl_genSpliceDep.moduleOpen = idl_moduleOpen; + idl_genSpliceDep.moduleClose = NULL; + idl_genSpliceDep.structureOpen = idl_structureOpen; + idl_genSpliceDep.structureClose = NULL; + idl_genSpliceDep.structureMemberOpenClose = idl_structureMemberOpenClose; + idl_genSpliceDep.enumerationOpen = NULL; + idl_genSpliceDep.enumerationClose = NULL; + idl_genSpliceDep.enumerationElementOpenClose = NULL; + idl_genSpliceDep.unionOpen = idl_unionOpen; + idl_genSpliceDep.unionClose = NULL; + idl_genSpliceDep.unionCaseOpenClose = idl_unionCaseOpenClose; + idl_genSpliceDep.unionLabelsOpenClose = NULL; + idl_genSpliceDep.unionLabelOpenClose = NULL; + idl_genSpliceDep.typedefOpenClose = idl_typedefOpenClose; + idl_genSpliceDep.boundedStringOpenClose = NULL; + idl_genSpliceDep.sequenceOpenClose = NULL; + idl_genSpliceDep.constantOpenClose = idl_constantOpenClose; + idl_genSpliceDep.artificialDefaultLabelOpenClose = NULL; + idl_genSpliceDep.userData = userData; + return &idl_genSpliceDep; } diff --git a/src/tools/idlpp/code/idl_genSpliceDep.h b/src/tools/idlpp/code/idl_genSpliceDep.h index 609982a14..ab8f5b6cb 100644 --- a/src/tools/idlpp/code/idl_genSpliceDep.h +++ b/src/tools/idlpp/code/idl_genSpliceDep.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,6 +23,6 @@ #include "idl_program.h" -idl_program idl_genSpliceDepProgram (void); +idl_program idl_genSpliceDepProgram (void *userData); #endif /* IDL_GENSPLICEDEP_H */ diff --git a/src/tools/idlpp/code/idl_genSpliceLiteType.c b/src/tools/idlpp/code/idl_genSpliceLiteType.c index c3c9499ef..a9079802e 100644 --- a/src/tools/idlpp/code/idl_genSpliceLiteType.c +++ b/src/tools/idlpp/code/idl_genSpliceLiteType.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -107,7 +108,7 @@ idl_macroFromBasename( return macro; } -/* @brief callback function called on opening the IDL input file. +/** @brief callback function called on opening the IDL input file. * * Generate standard file header consisting of: * - mutiple inclusion prevention @@ -155,7 +156,7 @@ idl_fileOpen( return idl_explore; } -/* @brief callback function called on closing the IDL input file. +/** @brief callback function called on closing the IDL input file. * * Generate standard file footer consisting of: * - mutiple inclusion prevention closure diff --git a/src/tools/idlpp/code/idl_genSpliceLiteType.h b/src/tools/idlpp/code/idl_genSpliceLiteType.h index 0def7a89a..97dd97c5a 100644 --- a/src/tools/idlpp/code/idl_genSpliceLiteType.h +++ b/src/tools/idlpp/code/idl_genSpliceLiteType.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/idlpp/code/idl_genSpliceLoad.c b/src/tools/idlpp/code/idl_genSpliceLoad.c index 115839514..d8c43a4fd 100644 --- a/src/tools/idlpp/code/idl_genSpliceLoad.c +++ b/src/tools/idlpp/code/idl_genSpliceLoad.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -38,8 +39,8 @@ /* The following IDL to metadata type mapping applies to all routines. * * IDL type splice-type meta data - * - * char c_char c_primitive->kind P_CHAR + * + * char c_char c_primitive->kind P_CHAR * octet c_octet c_primitive->kind P_OCTET * boolean c_bool c_primitive->kind P_BOOLEAN * short c_short c_primitive->kind P_SHORT @@ -133,7 +134,7 @@ typedef enum { sc_base, sc_scope, - sc_struct + sc_struct } sc_scoping; /** Index for the member of a structure */ @@ -179,19 +180,19 @@ idl_valueFromLabelVal( idl_labelValueVal(idl_labelValue(labelVal)).is.Char); break; case V_SHORT: - snprintf (labelName, sizeof(labelName), "c_shortValue (%d)", + snprintf (labelName, sizeof(labelName), "c_shortValue (%d)", idl_labelValueVal(idl_labelValue(labelVal)).is.Short); break; case V_USHORT: - snprintf (labelName, sizeof(labelName), "c_ushortValue (%u)", + snprintf (labelName, sizeof(labelName), "c_ushortValue (%u)", idl_labelValueVal(idl_labelValue(labelVal)).is.UShort); break; case V_LONG: - snprintf (labelName, sizeof(labelName), "c_longValue (%d)", + snprintf (labelName, sizeof(labelName), "c_longValue (%d)", idl_labelValueVal(idl_labelValue(labelVal)).is.Long); break; case V_ULONG: - snprintf (labelName, sizeof(labelName), "c_ulongValue (%u)", + snprintf (labelName, sizeof(labelName), "c_ulongValue (%u)", idl_labelValueVal(idl_labelValue(labelVal)).is.ULong); break; case V_LONGLONG: @@ -431,7 +432,7 @@ idl_structureOpen( @endverbatim * - * The function finalizes the meta data definition of the structure + * The function finalizes the meta data definition of the structure * by assigning the members, then finalizing the structure. * * The function then again finds the structure in the meta data. @@ -716,7 +717,7 @@ idl_unionOpen( => }; @endverbatim * - * The function finalizes the meta data definition of the union + * The function finalizes the meta data definition of the union * by assigning the union cases, then finalizing the union. * * The function then again finds the union in the meta data. @@ -1042,7 +1043,7 @@ idl_enumerationOpen( return idl_explore; } - + /** @brief callback function called on closure of an enumeration in the IDL input file. * * Generate code for the following IDL construct: @@ -1054,7 +1055,7 @@ idl_enumerationOpen( => }; @endverbatim * - * The function finalizes the meta data definition of the enumeration + * The function finalizes the meta data definition of the enumeration * by assigning the elements, then finalizing the enumeration. * * The function then again finds the enumeration in the meta data. @@ -1198,9 +1199,10 @@ idl_arrayLoad( sType = idl_scopeElementType(idl_scopeCur(idl_typeUserScope(idl_typeUser(arrayType)))); /* QAC EXPECT 3416; No side effect here */ if ((sType == idl_tStruct) || (sType == idl_tUnion)) { - /* If the bounded string is defined within a structure or union then load - the structure or union metadata. The structure or union is the scope of - the bounded string */ + /* If the bounded string is defined within a structure or union then load + * the structure or union metadata. The structure or union is the scope of + * the bounded string + */ idl_fileOutPrintf( idl_fileCur(), " tscope = __%s_%u__load (o)->definedIn;\n", @@ -1208,7 +1210,8 @@ idl_arrayLoad( idl_typeBasicMaxlen(idl_typeBasic(idl_typeArrayType(idl_typeArray(typeSpec))))); } else { /* If the bounded string is defined within an other user type then load - the user type metadata. The user type scope is the scope of the bounded string */ + * the user type metadata. The user type scope is the scope of the bounded string + */ idl_fileOutPrintf( idl_fileCur(), " tscope = __%s_%u__load (scope)->definedIn;\n", @@ -1259,8 +1262,8 @@ idl_arrayLoad( } idl_printIndent(indent); /* Resolve the subtype of the array based upon the determined scope of the subtype and set the - arrays subType attribute - */ + * arrays subType attribute + */ idl_fileOutPrintf(idl_fileCur(), " c_collectionType(%c)->subType = ResolveType(tscope,\"%s\");\n", IDL_INDEX_VAR+indent, idl_typeSpecName(arrayType)); @@ -1329,13 +1332,13 @@ idl_seqLoad( sType = idl_scopeElementType(idl_scopeCur(scope)); if ((sType == idl_tStruct) || (sType == idl_tUnion)) { /* The sequence is defined within a structure or union, therefor the - scope is the structure or union. - */ + * scope is the structure or union. + */ scoping = sc_struct; } else { /* The sequence is not defined within a structure or union, therefor the - scope is defined by the "scope" variable. - */ + * scope is defined by the "scope" variable. + */ scoping = sc_scope; } /* QAC EXPECT 3416; No side effect here */ @@ -1369,8 +1372,8 @@ idl_seqLoad( /* QAC EXPECT 3416; No side effect here */ if (idl_typeSpecType(idl_typeSpec(seqType)) == idl_tseq) { /* If the subtype of the sequence is a sequence then determine the scope of - the subtype and resolve the type to set the subtype of the sequence - */ + * the subtype and resolve the type to set the subtype of the sequence + */ idl_printIndent(indent); idl_fileOutPrintf(idl_fileCur(), " tscope = %s;\n", scopeName[scoping]); idl_printIndent(indent); @@ -1407,7 +1410,7 @@ idl_seqLoad( /* check for recursive single or multi level definition */ scope_index = idl_scopeStackSize(scope) - 1; subType_defined = 0; - while ((scope_index >= 0) && + while ((scope_index >= 0) && ((idl_scopeElementType(idl_scopeIndexed(scope,scope_index)) == idl_tStruct) || (idl_scopeElementType(idl_scopeIndexed(scope,scope_index)) == idl_tUnion))) { /* QAC EXPECT 3416; No side effect here */ @@ -1439,7 +1442,7 @@ idl_seqLoad( } if (subType_defined == 0) { idl_printIndent(indent); - if (((sType == idl_tStruct) || (sType == idl_tUnion)) && + if (((sType == idl_tStruct) || (sType == idl_tUnion)) && idl_scopeEqual(scope, idl_typeUserScope(idl_typeUser(seqType))) == TRUE) { idl_fileOutPrintf( idl_fileCur(), @@ -1570,8 +1573,8 @@ idl_typedefOpenClose( idl_fileOutPrintf(idl_fileCur(), " c_metaObject(o)->definedIn = scope;\n"); idl_fileOutPrintf(idl_fileCur(), " tscope = scope;\n"); /* Resolve the subtype of the type definition based on its scope and set the alias attribute - of the type definition - */ + * of the type definition + */ idl_fileOutPrintf( idl_fileCur(), " c_typeDef(o)->alias = ResolveType(tscope,\"%s\");\n", @@ -1608,7 +1611,7 @@ idl_typedefOpenClose( */ idl_fileOutPrintf(idl_fileCur(), " c_typeDef(o)->alias = ResolveType(tscope,\"%s\");\n", idl_typeFromTypeSpec(idl_typeSpec(idl_typeDefRefered(defSpec)))); - } + } /* Finalize the type definition */ idl_fileOutPrintf(idl_fileCur(), " c_metaFinalize(o);\n"); idl_fileOutPrintf(idl_fileCur(), " found = c_metaBind(scope,\"%s\",o);\n",name); @@ -1692,7 +1695,7 @@ idl_getControl( return &idl_genSpliceLoadControl; } -/** +/** * Specifies the callback table for the metadata generation functions. */ static struct idl_program diff --git a/src/tools/idlpp/code/idl_genSpliceLoad.h b/src/tools/idlpp/code/idl_genSpliceLoad.h index fc1570156..d6a4c9bdc 100644 --- a/src/tools/idlpp/code/idl_genSpliceLoad.h +++ b/src/tools/idlpp/code/idl_genSpliceLoad.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/idlpp/code/idl_genSpliceType.c b/src/tools/idlpp/code/idl_genSpliceType.c index d04fa8a97..9aa883790 100644 --- a/src/tools/idlpp/code/idl_genSpliceType.c +++ b/src/tools/idlpp/code/idl_genSpliceType.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -107,7 +108,7 @@ idl_macroFromBasename( return macro; } -/* @brief callback function called on opening the IDL input file. +/** @brief callback function called on opening the IDL input file. * * Generate standard file header consisting of: * - mutiple inclusion prevention @@ -311,9 +312,10 @@ idl_structureOpen( { idl_fileOutPrintf( idl_fileCur(), - "extern %s v_copyin_result __%s__copyIn(c_base base, const class %s *from, struct _%s *to);\n", + "extern %s v_copyin_result __%s__copyIn(%s, const class %s *from, struct _%s *to);\n", idl_dllGetMacro(), fullyScopedName, + idl_getIsISOCpp2() ? "c_type dbType" : "c_base base", tmpfullyScopedName, fullyScopedName); } @@ -786,7 +788,9 @@ idl_unionCaseOpenClose( idl_typeSpecType(typeSpec) == idl_tstruct || idl_typeSpecType(typeSpec) == idl_tunion || idl_typeSpecType(typeSpec) == idl_tbasic) { - /* generate code for a standard mapping or a typedef, enum, struct or union user-type mapping */ + /* generate code for a standard mapping or a typedef, + * enum, struct or union user-type mapping + */ idl_printIndent(indent_level); idl_fileOutPrintf( idl_fileCur(), @@ -952,7 +956,7 @@ idl_enumerationElementOpenClose( } } -/* @brief generate dimension of an array +/** @brief generate dimension of an array * * arrayDimensions is a local support function to generate * the array dimensions of an array diff --git a/src/tools/idlpp/code/idl_genSpliceType.h b/src/tools/idlpp/code/idl_genSpliceType.h index 0d761cff2..a88618738 100644 --- a/src/tools/idlpp/code/idl_genSpliceType.h +++ b/src/tools/idlpp/code/idl_genSpliceType.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/idlpp/code/idl_genTypeDescriptors.c b/src/tools/idlpp/code/idl_genTypeDescriptors.c index 040adc7bc..1c73df4f1 100644 --- a/src/tools/idlpp/code/idl_genTypeDescriptors.c +++ b/src/tools/idlpp/code/idl_genTypeDescriptors.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -71,7 +72,7 @@ idl_structureOpen( /* QAC EXPECT 3416; No side effects here */ if (idl_keyResolve(idl_keyDefDefGet(), scope, name) != NULL) { - /* keylist defined for this struct */ + /* keylist defined for this struct */ /* Store data-type in iterator for future generation of type descriptor. */ idl_metaCxxAddType(scope, name, idl_typeSpec(structSpec), &cxxUserData->idlpp_metaList); } diff --git a/src/tools/idlpp/code/idl_genTypeDescriptors.h b/src/tools/idlpp/code/idl_genTypeDescriptors.h index 8a47ee022..6f93b0379 100644 --- a/src/tools/idlpp/code/idl_genTypeDescriptors.h +++ b/src/tools/idlpp/code/idl_genTypeDescriptors.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/idlpp/code/idl_genTypeSize.c b/src/tools/idlpp/code/idl_genTypeSize.c index c457f18bc..24e3ddd5e 100644 --- a/src/tools/idlpp/code/idl_genTypeSize.c +++ b/src/tools/idlpp/code/idl_genTypeSize.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -238,6 +239,7 @@ idl_genTypeSize( } key = c_iterTakeFirst(keyIter); } + c_iterFree(keyIter); printf(" Total key size = \t%"PA_PRIuSIZE"\n\n", keySize); } else { printf("Type size calculation failed, no type specified!\n\n"); diff --git a/src/tools/idlpp/code/idl_genTypeSize.h b/src/tools/idlpp/code/idl_genTypeSize.h index 44082757d..d2a8b79ae 100644 --- a/src/tools/idlpp/code/idl_genTypeSize.h +++ b/src/tools/idlpp/code/idl_genTypeSize.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/idlpp/code/idl_keyDef.c b/src/tools/idlpp/code/idl_keyDef.c index 3a35e2218..4a72d7c20 100644 --- a/src/tools/idlpp/code/idl_keyDef.c +++ b/src/tools/idlpp/code/idl_keyDef.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/idlpp/code/idl_keyDef.h b/src/tools/idlpp/code/idl_keyDef.h index e5ed35ae9..92674c481 100644 --- a/src/tools/idlpp/code/idl_keyDef.h +++ b/src/tools/idlpp/code/idl_keyDef.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/idlpp/code/idl_main.c b/src/tools/idlpp/code/idl_main.c index 05f875ebd..6e1676a56 100644 --- a/src/tools/idlpp/code/idl_main.c +++ b/src/tools/idlpp/code/idl_main.c @@ -1,7 +1,8 @@ -/* * OpenSplice DDS +/* * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -53,9 +54,11 @@ #include "idl_genISOCxxHeader.h" /* ISOCPP2 related support */ +#include "idl_genISOCxx2SpliceType.h" #include "idl_genTypeDescriptors.h" #include "idl_genISOCxx2Header.h" #include "idl_genISOCxx2Type.h" +#include "idl_genISOCxx2Copyin.h" #include "idl_genISOCxx2Copyout.h" /* ISOCPP2 face support */ #include "idl_genFaceISOCxx2Tmpl.h" @@ -102,6 +105,21 @@ /* Java face support */ #include "idl_genFaceJava.h" +/* Simulink related support */ +#include "idl_genSimulink.h" + +/* MATLAB related support */ +#include "idl_genMatlab.h" + +/* PYTHONDESCRIPTORS related support */ +#include "idl_genPythonDescriptors.h" + +/* LabVIEW related support */ +#include "idl_genLabview.h" + +/* PYHTON related support */ +#include "idl_genPython.h" + /* IDL related support */ #include "idl_genIdl.h" #include "idl_genIdlHelper.h" @@ -151,7 +169,7 @@ print_usage( #endif printf("Usage: %s [-b ORB-template-path]\n" " [-n ] [-I path] [-D macro[=definition]] [-S | -C] \n" - " [-l (c | c99 | c++ | cpp | isocpp | isoc++ | isocpp2 | isoc++2 | cs | java )] [-F] [-j [old]:] [-d directory] [-i] \n" + " [-l (c | c99 | c++ | cpp | isocpp | isoc++ | isocpp2 | isoc++2 | cs | java | python | simulink | matlab)] [-F] [-j [old]:] [-d directory] [-i] \n" #ifdef ENABLE_DEPRECATED_OPTION_DDS_TYPES " [-P dll_macro_name[,]] [-o (dds-types | custom-psm | no-equality | deprecated-c++11-mapping)] \n", name); #else @@ -286,7 +304,8 @@ print_help( " by the also deprecated isocpp/isoc++ PSM. This option only\n" " makes sense when migrating from isocpp/isoc++ to isocpp2/isoc++2\n"); printf( - " -l (c | c++ | cpp | isocpp | isoc++ | isocpp2 | isoc++2 | cs | java)\n" + " -l (c | c++ | cpp | isocpp | isoc++ | isocpp2 | isoc++2 | cs | java\n" + " | python | simulink | matlab)\n" " Defines the target language. Value 'cs' represents C-sharp\n" " and 'cpp' is an alias for 'c++'.\n" " The value 'isoc++' (or isocpp, isoc++2, isocpp2) means that the\n" @@ -305,22 +324,25 @@ print_help( " Specifies the IDL input file to process.\n"); printf("\n" " Supported languages, ORBs and modes:\n" - " Lang ORB mode library OSPL_ORB_PATH\n" - " ---------------------------------------------------\n" - " c N.A. S dcpssac SAC\n" - " c99 N.A. S dcpsc99 & SAC\n" - " dcpssac\n"); + " Lang ORB mode library OSPL_ORB_PATH\n" + " ----------------------------------------------------\n" + " c N.A. S dcpssac SAC\n" + " c99 N.A. S dcpsc99 & SAC\n" + " dcpssac\n"); printf( - " c++ N.A. C dcpsccpp CCPP%s%s\n" - " cpp N.A. C dcpsccpp CCPP%s%s\n" - " c++ N.A. S dcpssacpp SACPP\n" - " cpp N.A. S dcpssacpp SACPP\n" - " isocpp N.A. S dcpsisocpp SACPP\n" - " isoc++ N.A. S dcpsisocpp SACPP\n" - " isocpp2 N.A. S dcpsisocpp2 ISOCPP2\n" - " isoc++2 N.A. S dcpsisocpp2 ISOCPP2\n" - " cs N.A. S dcpssacs SACS\n" - " Java JacOrb C dcpscj SAJ\n", + " c++ N.A. C dcpsccpp CCPP%s%s\n" + " cpp N.A. C dcpsccpp CCPP%s%s\n" + " c++ N.A. S dcpssacpp SACPP\n" + " cpp N.A. S dcpssacpp SACPP\n" + " isocpp N.A. S dcpsisocpp SACPP\n" + " isoc++ N.A. S dcpsisocpp SACPP\n" + " isocpp2 N.A. S dcpsisocpp2 ISOCPP2\n" + " isoc++2 N.A. S dcpsisocpp2 ISOCPP2\n" + " cs N.A. S dcpssacs SACS\n" + " Java JacOrb C dcpscj SAJ\n" + " simulink N.A N.A N.A N.A\n" + " matlab N.A N.A N.A N.A\n" + " python N.A N.A N.A N.A\n", os_fileSep(), DEFAULT_ORB, os_fileSep(), DEFAULT_ORB); } @@ -381,19 +403,20 @@ preLoadSpliceDdsDefinitions( exit (1); } /* preload DDS definitions. Hopefully this loads #includes too. - * @todo Sort this out + * TODO Sort this out */ snprintf(fname, sizeof(fname), "%s%c..%cidl%c%s", templ_path, OS_FILESEPCHAR, OS_FILESEPCHAR, OS_FILESEPCHAR, DDS_DCPS_DEF); base = idl_parseFile(fname, 0); OS_UNUSED_ARG(base); - /** @todo Free existing file relations */ - /* With idl_fileMapDefGet retrieve current relations */ - /* which can be freed then before setting to NULL */ - - /* Forget file relations so that no include directives */ - /* will be generated when DDS-DCPS types are referred */ + /** TODO Free existing file relations + * With idl_fileMapDefGet retrieve current relations + * which can be freed then before setting to NULL + * + * Forget file relations so that no include directives + * will be generated when DDS-DCPS types are referred + */ idl_fileMapDefSet(NULL); } #endif @@ -445,7 +468,8 @@ getDefaultCcppOrbPath() char* splice_orb; /* The env setup scripts define SPLICE_ORB to indicate the CPP ORB - this - is more appropriate than a hardcode default. */ + * is more appropriate than a hardcode default. + */ if ((splice_orb = os_getenv ("SPLICE_ORB")) == NULL) { /* Not defined - fall back on the hard code default. */ @@ -705,6 +729,16 @@ OPENSPLICE_MAIN (ospl_idlpp) if (os_getenv("OSPL_ORB_PATH") == NULL) { os_putenv("OSPL_ORB_PATH=SAJ"); } + } else if (strcmp(optarg, "simulink") == 0) { + idl_setLanguage(IDL_LANG_SIMULINK); + } else if (strcmp(optarg, "matlab") == 0) { + idl_setLanguage(IDL_LANG_MATLAB); + } else if (strcmp(optarg, "pythondesc") == 0) { + idl_setLanguage(IDL_LANG_PYTHON_DESCRIPTORS); + } else if (strcmp(optarg, "labview") == 0) { + idl_setLanguage(IDL_LANG_LABVIEW); + } else if (strcmp(optarg, "python") == 0) { + idl_setLanguage(IDL_LANG_PYTHON); } else { print_usage(argv[0]); idl_exit(-1); @@ -737,7 +771,7 @@ OPENSPLICE_MAIN (ospl_idlpp) idl_exit(-1); } idl_setCorbaMode(IDL_MODE_ORB_BOUND); - idl_setIsISOCppTypes(OS_FALSE); /** @internal @bug OSPL-3369 */ + idl_setIsISOCppTypes(OS_FALSE); break; case 'P': if (idl_dllSetOption(optarg)) { @@ -827,10 +861,10 @@ OPENSPLICE_MAIN (ospl_idlpp) moduleName = splitArg(optarg, i); while (moduleName != NULL) { /* The next arguments specify the modules that have - to be processed, they are explicitely specified - because the metadata database does not contain a - mapping to files as the preprocessor generally keeps - */ + * to be processed, they are explicitely specified + * because the metadata database does not contain a + * mapping to files as the preprocessor generally keeps + */ idl_walkPresetModule(moduleName); i++; moduleName = splitArg(optarg, i); @@ -851,26 +885,26 @@ OPENSPLICE_MAIN (ospl_idlpp) break; case 'a': /* specifies the template directory. This path can also be - specified by the environment variable OSPL_TMPL_PATH. This - option overrules the environment variable. - */ + * specified by the environment variable OSPL_TMPL_PATH. This + * option overrules the environment variable. + */ snprintf(orb, sizeof(orb), "OSPL_TMPL_PATH=%s", optarg); os_putenv(orb); break; case 'b': /* specifies the ORB specific path within the template directory, - e.g. TAO for a TAO specific template. This path can also be - specified by the environment variable OSPL_ORB_PATH. This - option overrules the environment variable. The complete applied - template path = $OSPL_TMPL_PATH/$OSPL_ORB_PATH. - */ + * e.g. TAO for a TAO specific template. This path can also be + * specified by the environment variable OSPL_ORB_PATH. This + * option overrules the environment variable. The complete applied + * template path = $OSPL_TMPL_PATH/$OSPL_ORB_PATH. + */ snprintf(orb, sizeof(orb), "OSPL_ORB_PATH=%s", optarg); os_putenv(orb); break; case 'D': /* Define a Macro, which is used while preprocessing the IDL - input file. The macro definition is stored via an iterator. - */ + * input file. The macro definition is stored via an iterator. + */ if (addDefine(optarg)) { print_usage(argv[0]); idl_exit(-1); @@ -879,8 +913,8 @@ OPENSPLICE_MAIN (ospl_idlpp) break; case 'I': /* Define an include PATH, which is used while preprocessing the IDL - input file. The include path is stored via an iterator. - */ + * input file. The include path is stored via an iterator. + */ /* also append it to the preprocessor include path */ /* remove ending '\' that VS adds to the path see dds3125*/ @@ -1000,10 +1034,10 @@ OPENSPLICE_MAIN (ospl_idlpp) fpathNorm = os_fileNormalize(argv[optind]); /* Determine the start of the IDL input filename, removing all path related stuff. - The information is used to determine the basename of the input IDL file. The - basename is the filename of the input file without path and extension. - Also take into account non-alphanum characters and replace with '_' - */ + * The information is used to determine the basename of the input IDL file. The + * basename is the filename of the input file without path and extension. + * Also take into account non-alphanum characters and replace with '_' + */ includeIdlDir = os_strdup(fpathNorm); ptr = os_rindex(fpathNorm, OS_FILESEPCHAR); if (ptr == NULL) { @@ -1053,11 +1087,11 @@ OPENSPLICE_MAIN (ospl_idlpp) } /* Determine the input file with path excluding any preceding "./" path - elements. The C preprocessor also removes this information from the - file information tags in the processed input file. This information - is used to determine if the specified meta objects relate to the - input file. - */ + * elements. The C preprocessor also removes this information from the + * file information tags in the processed input file. This information + * is used to determine if the specified meta objects relate to the + * input file. + */ i = 0; while ((fpathNorm[i] == '.') && (fpathNorm[i+1] == OS_FILESEPCHAR)) { i += 2; @@ -1130,9 +1164,9 @@ OPENSPLICE_MAIN (ospl_idlpp) /* Initialize class to determine depedencies with other files */ idl_depDefInit(); /* Walk through metadata to determine depedencies with other files, - the dependencies are used to generate include statements - */ - idl_walk(base, filename, source, traceWalk, idl_genSpliceDepProgram()); + * the dependencies are used to generate include statements + */ + idl_walk(base, filename, source, traceWalk, idl_genSpliceDepProgram(NULL)); if (makeAll) { /* Do normal generation */ @@ -1153,7 +1187,7 @@ OPENSPLICE_MAIN (ospl_idlpp) /* Generate the file that defines all DCPS specialized classes for the - user types + * user types */ snprintf(fname, strlen(basename) + MAX_FILE_POSTFIX_LENGTH, "%sDcps_impl.h", basename); @@ -1166,8 +1200,8 @@ OPENSPLICE_MAIN (ospl_idlpp) idl_fileOutFree(idl_fileCur()); /* Generate the file that implements all DCPS specialized classes for the - user types - */ + * user types + */ snprintf(fname, strlen(basename) + MAX_FILE_POSTFIX_LENGTH, "%sDcps_impl.cpp", basename); idl_fileSetCur(idl_fileOutNew(fname, "w")); if (idl_fileCur() == NULL) { @@ -1177,7 +1211,7 @@ OPENSPLICE_MAIN (ospl_idlpp) idl_fileOutFree(idl_fileCur()); /* Generate the file that specifies all Splice specialized data types for the - user types + * user types */ snprintf(fname, strlen(basename) + MAX_FILE_POSTFIX_LENGTH, "%sSplDcps.h", basename); idl_fileSetCur(idl_fileOutNew (fname, "w")); @@ -1202,8 +1236,8 @@ OPENSPLICE_MAIN (ospl_idlpp) idl_fileOutFree(idl_fileCur()); /* Generate the file that implements all metadata load functions, Splice helper - functions as well as C++/CORBA copy routines to/from Splice for the user types - */ + * functions as well as C++/CORBA copy routines to/from Splice for the user types + */ snprintf(fname, strlen(basename) + MAX_FILE_POSTFIX_LENGTH, "%sSplDcps.cpp", basename); @@ -1225,8 +1259,7 @@ OPENSPLICE_MAIN (ospl_idlpp) idl_fileOutFree(idl_fileCur()); - /* Generate the file that includes ORB specific generated header files - */ + /* Generate the file that includes ORB specific generated header files */ if (idl_getIsISOCpp()) { snprintf(fname, strlen(basename) + MAX_FILE_POSTFIX_LENGTH, @@ -1250,8 +1283,7 @@ OPENSPLICE_MAIN (ospl_idlpp) idl_fileOutFree(idl_fileCur()); - /* Expand IDL based application TypeSupport, DataReader and DataWriter interfaces - */ + /* Expand IDL based application TypeSupport, DataReader and DataWriter interfaces */ /* Create a list of keys and streams existing only in this idl file */ idl_walk(base, filename, source, traceWalk, idl_genIdlHelperProgram()); @@ -1405,8 +1437,8 @@ OPENSPLICE_MAIN (ospl_idlpp) cxxUserData.typeStack = NULL; /* Generate the file that specifies all Splice specialized data types for the - user types - */ + * user types + */ snprintf(fname, strlen(basename) + MAX_FILE_POSTFIX_LENGTH, "%sSplDcps.h", basename); idl_fileSetCur(idl_fileOutNew (fname, "w")); if (idl_fileCur() == NULL) { @@ -1417,14 +1449,17 @@ OPENSPLICE_MAIN (ospl_idlpp) mainInclude = os_malloc(strlen(basename)+inclTmpltLen); snprintf (mainInclude, strlen(basename)+inclTmpltLen, "%s_DCPS.hpp", basename); - idl_genSpliceTypeSetIncludeFileName(mainInclude); - - idl_walk(base, filename, source, traceWalk, idl_genSpliceTypeProgram()); + if (deprecatedCxx11Mapping) { + idl_genSpliceTypeSetIncludeFileName(mainInclude); + idl_walk(base, filename, source, traceWalk, idl_genSpliceTypeProgram()); + } else { + idl_walk(base, filename, source, traceWalk, idl_genISOCxx2SpliceTypeProgram()); + } idl_fileOutFree(idl_fileCur()); /* Generate the file that implements all metadata load functions, Splice helper - functions as well as C++/CORBA copy routines to/from Splice for the user types - */ + * functions as well as C++/CORBA copy routines to/from Splice for the user types + */ snprintf(fname, strlen(basename) + MAX_FILE_POSTFIX_LENGTH, "%sSplDcps.cpp", basename); @@ -1435,16 +1470,17 @@ OPENSPLICE_MAIN (ospl_idlpp) idl_fileOutPrintf(idl_fileCur(), "#include \"%s\"\n", mainInclude); idl_fileOutPrintf(idl_fileCur(), "\n"); - idl_walk(base, filename, source, traceWalk, idl_genCorbaCxxCopyinProgram(&cxxUserData)); if (deprecatedCxx11Mapping) { + idl_walk(base, filename, source, traceWalk, idl_genCorbaCxxCopyinProgram(&cxxUserData)); idl_walk(base, filename, source, traceWalk, idl_genCorbaCxxCopyoutProgram()); } else { + idl_walk(base, filename, source, traceWalk, idl_genISOCxx2CopyinProgram(&cxxUserData)); idl_walk(base, filename, source, traceWalk, idl_genISOCxx2CopyoutProgram()); } idl_fileOutFree(idl_fileCur()); - /* Generate the file that includes ORB specific generated header files + /* Generate the file that includes generated header files */ snprintf(fname, strlen(basename) + MAX_FILE_POSTFIX_LENGTH, @@ -1519,8 +1555,7 @@ OPENSPLICE_MAIN (ospl_idlpp) } if (!deprecatedCxx11Mapping) { - /* Generate the file that implements the C++11 compliant representation of the IDL. - */ + /* Generate the file that implements the C++11 compliant representation of the IDL. */ snprintf(fname, strlen(basename) + MAX_FILE_POSTFIX_LENGTH, "%s.h", basename); @@ -1583,7 +1618,7 @@ OPENSPLICE_MAIN (ospl_idlpp) cxxUserData.typeStack = NULL; /* Generate the file that defines all DCPS specialized classes for the - user types + * user types */ snprintf(fname, strlen(basename) + MAX_FILE_POSTFIX_LENGTH, "%sDcps_impl.h", basename); @@ -1596,7 +1631,7 @@ OPENSPLICE_MAIN (ospl_idlpp) idl_fileOutFree(idl_fileCur()); /* Generate the file that implements all DCPS specialized classes for the - user types + * user types */ snprintf(fname, strlen(basename) + MAX_FILE_POSTFIX_LENGTH, "%sDcps_impl.cpp", basename); idl_fileSetCur(idl_fileOutNew(fname, "w")); @@ -1607,7 +1642,7 @@ OPENSPLICE_MAIN (ospl_idlpp) idl_fileOutFree(idl_fileCur()); /* Generate the file that specifies all Splice specialized data types for the - user types + * user types */ snprintf(fname, strlen(basename) + MAX_FILE_POSTFIX_LENGTH, "%sSplDcps.h", basename); idl_fileSetCur(idl_fileOutNew (fname, "w")); @@ -1631,7 +1666,7 @@ OPENSPLICE_MAIN (ospl_idlpp) idl_fileOutFree(idl_fileCur()); /* Generate the file that implements all metadata load functions, Splice helper - functions as well as C++/CORBA copy routines to/from Splice for the user types + * functions as well as C++/CORBA copy routines to/from Splice for the user types */ snprintf(fname, strlen(basename) + MAX_FILE_POSTFIX_LENGTH, @@ -1681,8 +1716,7 @@ OPENSPLICE_MAIN (ospl_idlpp) idl_fileOutFree(idl_fileCur()); - /* Generate the file that includes ORB specific generated header files - */ + /* Generate the file that includes ORB specific generated header files */ if (idl_getIsISOCpp()) { snprintf(fname, strlen(basename) + MAX_FILE_POSTFIX_LENGTH, @@ -1705,8 +1739,7 @@ OPENSPLICE_MAIN (ospl_idlpp) } idl_fileOutFree(idl_fileCur()); - /* Expand IDL based application TypeSupport, DataReader and DataWriter interfaces - */ + /* Expand IDL based application TypeSupport, DataReader and DataWriter interfaces */ /* Create a list of keys and streams existing only in this idl file */ idl_walk(base, filename, source, traceWalk, idl_genIdlHelperProgram()); @@ -1826,8 +1859,8 @@ OPENSPLICE_MAIN (ospl_idlpp) idl_fileOutFree(idl_fileCur()); /* Generate the file that defines all DCPS specialized classes for the - user types - */ + * user types + */ snprintf(fname, strlen(basename) + MAX_FILE_POSTFIX_LENGTH, "%sDcps.h", basename); @@ -1839,8 +1872,8 @@ OPENSPLICE_MAIN (ospl_idlpp) idl_fileOutFree(idl_fileCur()); /* Generate the file that specifies all Standalone C specialized data types for the - user types - */ + * user types + */ snprintf(fname, strlen(basename) + MAX_FILE_POSTFIX_LENGTH, "%sSplDcps.h", basename); @@ -1860,8 +1893,8 @@ OPENSPLICE_MAIN (ospl_idlpp) idl_fileOutFree(idl_fileCur()); /* Generate the file that implements all metadata load functions, Splice helper - functions as well as C/CORBA copy routines to/from Splice for the user types - */ + * functions as well as C/CORBA copy routines to/from Splice for the user types + */ snprintf(fname, strlen(basename) + MAX_FILE_POSTFIX_LENGTH, "%sSplDcps.c", basename); @@ -1899,8 +1932,8 @@ OPENSPLICE_MAIN (ospl_idlpp) idl_fileOutFree(idl_fileCur()); /* Generate the file that defines all DCPS specialized classes for the - user types - */ + * user types + */ snprintf(fname, strlen(basename) + MAX_FILE_POSTFIX_LENGTH, "%sSacDcps.h", basename); @@ -1912,8 +1945,8 @@ OPENSPLICE_MAIN (ospl_idlpp) idl_fileOutFree(idl_fileCur()); /* Generate the file that implements all DCPS specialized classes for the - user types - */ + * user types + */ snprintf(fname, (size_t)((int)strlen(basename)+20), "%sSacDcps.c", basename); idl_fileSetCur(idl_fileOutNew(fname, "w")); if (idl_fileCur() == NULL) { @@ -1961,8 +1994,8 @@ OPENSPLICE_MAIN (ospl_idlpp) idl_fileOutFree(idl_fileCur()); /* Generate the file that defines all DCPS specialized classes for the - user types - */ + * user types + */ snprintf(fname, strlen(basename) + MAX_FILE_POSTFIX_LENGTH, "%sDcps.h", basename); @@ -1974,8 +2007,8 @@ OPENSPLICE_MAIN (ospl_idlpp) idl_fileOutFree(idl_fileCur()); /* Generate the file that specifies all Standalone C specialized data types for the - user types - */ + * user types + */ snprintf(fname, strlen(basename) + MAX_FILE_POSTFIX_LENGTH, "%sSplDcps.h", basename); @@ -1995,8 +2028,8 @@ OPENSPLICE_MAIN (ospl_idlpp) idl_fileOutFree(idl_fileCur()); /* Generate the file that implements all metadata load functions, Splice helper - functions as well as C/CORBA copy routines to/from Splice for the user types - */ + * functions as well as C/CORBA copy routines to/from Splice for the user types + */ snprintf(fname, strlen(basename) + MAX_FILE_POSTFIX_LENGTH, "%sSplDcps.c", basename); @@ -2034,8 +2067,8 @@ OPENSPLICE_MAIN (ospl_idlpp) idl_fileOutFree(idl_fileCur()); /* Generate the file that defines all DCPS specialized classes for the - user types - */ + * user types + */ snprintf(fname, strlen(basename) + MAX_FILE_POSTFIX_LENGTH, "%sSacDcps.h", basename); @@ -2047,8 +2080,8 @@ OPENSPLICE_MAIN (ospl_idlpp) idl_fileOutFree(idl_fileCur()); /* Generate the file that implements all DCPS specialized classes for the - user types - */ + * user types + */ snprintf(fname, (size_t)((int)strlen(basename)+20), "%sSacDcps.c", basename); idl_fileSetCur(idl_fileOutNew(fname, "w")); if (idl_fileCur() == NULL) { @@ -2090,7 +2123,6 @@ OPENSPLICE_MAIN (ospl_idlpp) idl_fileOutFree(idl_fileCur()); } else if (idl_getLanguage() == IDL_LANG_CS) { SACSTypeUserData csUserData; - SACSSplDcpsUserData splUserData; /** * It is not possible to generate type-descriptors while walking over @@ -2105,6 +2137,7 @@ OPENSPLICE_MAIN (ospl_idlpp) csUserData.idlpp_metaList = NULL; csUserData.tmplPrefix = NULL; csUserData.customPSM = customPSM; + csUserData.typeStack = NULL; idl_definitionClean(); @@ -2121,12 +2154,13 @@ OPENSPLICE_MAIN (ospl_idlpp) idl_walk(base, filename, source, traceWalk, idl_genSACSTypeProgram(&csUserData)); idl_fileOutFree(idl_fileCur()); + c_iterFree(csUserData.typeStack); + csUserData.typeStack = NULL; /* Generate the file that defines the database representation of * the IDL data, and that contains the marshalers that translate * between database representation and C# representation. */ - splUserData.customPSM = customPSM; snprintf(fname, strlen(basename) + MAX_FILE_POSTFIX_LENGTH, "%sSplDcps.cs", basename); @@ -2135,7 +2169,7 @@ OPENSPLICE_MAIN (ospl_idlpp) idl_fileOpenError(fname); } - idl_walk(base, filename, source, traceWalk, idl_genSACSSplDcpsProgram(&splUserData)); + idl_walk(base, filename, source, traceWalk, idl_genSACSSplDcpsProgram(&csUserData)); idl_fileOutFree(idl_fileCur()); /* Expand Typed Csharp TypeSupport, DataReader and DataWriter @@ -2192,6 +2226,20 @@ OPENSPLICE_MAIN (ospl_idlpp) if (idl_getIsFace()) { idl_walk(base, filename, source, traceWalk, idl_genFaceJavaTmplProgram()); } + } else if (idl_getLanguage() == IDL_LANG_SIMULINK) { + snprintf(fname, strlen(basename) + MAX_FILE_POSTFIX_LENGTH, "idlImport_%s.m", basename); + idl_fileSetCur(idl_fileOutNew(fname, "w")); + idl_walk(base, filename, source, traceWalk, idl_genSimulinkProgram()); + } else if (idl_getLanguage() == IDL_LANG_LABVIEW) { + snprintf(fname, strlen(basename) + MAX_FILE_POSTFIX_LENGTH, "%s.idl.xml", basename); + idl_fileSetCur(idl_fileOutNew(fname, "w")); + idl_walk(base, filename, source, traceWalk, idl_genLabVIEWProgram()); + } else if(idl_getLanguage() == IDL_LANG_MATLAB) { + idl_walk(base, filename, source, traceWalk, idl_genMatlabProgram()); + } else if(idl_getLanguage() == IDL_LANG_PYTHON_DESCRIPTORS) { + idl_walk(base, filename, source, traceWalk, idl_genPythonDescriptorsProgram()); + } else if(idl_getLanguage() == IDL_LANG_PYTHON) { + idl_walk(base, filename, source, traceWalk, idl_genPythonProgram()); } } @@ -2582,7 +2630,7 @@ int runCppGen ( osr = os_procCheckStatus(cppgenProcId, &cppgenExitStatus); if (osr != os_resultSuccess) { - os_sleep(sleepTime); + ospl_os_sleep(sleepTime); } } while (osr != os_resultSuccess); diff --git a/src/tools/idlpp/code/idl_map.c b/src/tools/idlpp/code/idl_map.c index 5a5bc401d..ecfe7e82f 100644 --- a/src/tools/idlpp/code/idl_map.c +++ b/src/tools/idlpp/code/idl_map.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -155,7 +156,7 @@ idl_mapRemove ( } return; } - + int idl_mapIsEmpty ( idl_map map @@ -314,7 +315,7 @@ idl_mapIterRemove ( idl_mapRemove(mapIter->map,mapIter->key); mapIter->length = os_iterLength (mapIter->map->map); - + if (mapIter->index < (mapIter->length)) { entry = os_iterObject (mapIter->map->map, mapIter->index); mapIter->key = entry->key; diff --git a/src/tools/idlpp/code/idl_map.h b/src/tools/idlpp/code/idl_map.h index c88862238..d4f2a1499 100644 --- a/src/tools/idlpp/code/idl_map.h +++ b/src/tools/idlpp/code/idl_map.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/idlpp/code/idl_parser.c b/src/tools/idlpp/code/idl_parser.c index 63f1cbd39..aef786189 100644 --- a/src/tools/idlpp/code/idl_parser.c +++ b/src/tools/idlpp/code/idl_parser.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/idlpp/code/idl_parser.h b/src/tools/idlpp/code/idl_parser.h index d9d6b4ad0..84777c1ad 100644 --- a/src/tools/idlpp/code/idl_parser.h +++ b/src/tools/idlpp/code/idl_parser.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/idlpp/code/idl_program.h b/src/tools/idlpp/code/idl_program.h index 584f56074..547d85db7 100644 --- a/src/tools/idlpp/code/idl_program.h +++ b/src/tools/idlpp/code/idl_program.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/idlpp/code/idl_registerType.c b/src/tools/idlpp/code/idl_registerType.c index ac5f380e6..d19c0f812 100644 --- a/src/tools/idlpp/code/idl_registerType.c +++ b/src/tools/idlpp/code/idl_registerType.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/idlpp/code/idl_registerType.h b/src/tools/idlpp/code/idl_registerType.h index 1d4c50f8e..5e2c07931 100644 --- a/src/tools/idlpp/code/idl_registerType.h +++ b/src/tools/idlpp/code/idl_registerType.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/idlpp/code/idl_scope.c b/src/tools/idlpp/code/idl_scope.c index 3ba04ad00..0c2446d82 100644 --- a/src/tools/idlpp/code/idl_scope.c +++ b/src/tools/idlpp/code/idl_scope.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -147,7 +148,7 @@ idl_scope idl_scopeDup ( idl_scope scope) { - idl_scope newScope = idl_scopeNew(idl_scopeBasename(scope)); + idl_scope newScope = idl_scopeNew(scope->baseName); c_long si; for (si = 0; si < (scope->scopePointer+1); si++) { diff --git a/src/tools/idlpp/code/idl_scope.h b/src/tools/idlpp/code/idl_scope.h index 1594854a9..098c996b6 100644 --- a/src/tools/idlpp/code/idl_scope.h +++ b/src/tools/idlpp/code/idl_scope.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/idlpp/code/idl_sematicRules.c b/src/tools/idlpp/code/idl_sematicRules.c index c79e4f694..cac95a887 100644 --- a/src/tools/idlpp/code/idl_sematicRules.c +++ b/src/tools/idlpp/code/idl_sematicRules.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,175 +19,174 @@ * */ /* -// * 1 Introduction -// * -// * This document analyses the semantic checks required for the OpenSpliceDDS IDL pre-processor on the IDL input. -// * The analysis is based upon OMG Spec "The Common Object Request Broker: Archtecture and Specification", V2.3.1. -// * Semantic rules are identified by a [] enclosed number. -// * -// * 2 Generic -// * -// * [1] OMG IDL file must have "idl" extension. (3-3 3.1) -// * function: Will not be checked -// * -// * [2] OMG IDL uses ASCII charset. (3-3 3.1) -// * function: Will not be checked -// * -// * [3] OMG IDL identifiers consist of an arbitrary long sequence of ASCII alphabetic, digit and underscore -// * characters. (3-6 3.2.3) -// * function: Is checked by the scanner -// * -// * [4] OMG IDL identifiers must start with an ASCII alphabetic character. (3-6 3.2.3) -// * function: Is checked by the scanner -// * -// * [5] Uppercase and lowercase characters are treated as the same letter, but OMG IDL identifiers that only -// * differ in case collide. Identifiers for a given definition must be spelled identically with respect -// * to the case. (3-6 3.2.3) -// * funtion: idl_checkReferencedIdentifier -// * -// * [6] An identifier may be used only once within a namespace. There is only one namespace for each -// * identifier in each scope. (3-6 3.2.3) -// * A type name may be redefined in a nested scope. (3-50 3.15.3) -// * function: idl_checkModuleDefinition -// * function: idl_checkConstantDefinition -// * function: idl_checkTypeDefinition -// * function: idl_checkinterfaceDefinition -// * function: idl_checkEnumerationElementDefinition -// * function: idl_checkExceptionDefinition -// * function: idl_checkOperationDefinition -// * -// * 3 Constant Declaration -// * -// * [7] The in the production must be a previously defined name of an , -// * , , , , , , -// * , or constant. (3-29 3.9.2) -// * function: checked by the parser -// * -// * [8] An infix operator can combine two integers, floats or fixeds, but not mixtures of these. (3-29 3.9.2) -// * function: idl_checkBinaryExpression -// * -// * [9] Infix operators are applicable only to integer, float and fixed types. (3-29 3.9.2) -// * function: idl_checkBinaryExpression -// * -// * [10] It is an error if a sub-expression of an integer or float constant declaration exceeds the precision -// * of the target type. (3-29 3.9.2) -// * function: idl_checkBinaryExpression -// * -// * [11] Unary '+' and '-' and binary '*', '/', '+' and '-' are applicable in floating-point and fixed-point -// * expressions. (3-30 3.9.2) -// * function: idl_checkUnaryExpression -// * -// * [12] Unary '+', '-' and '~' and binary '*', '/', '%', '+', '-', '<<', '>>', '&', '|' and '^' operations -// * are applicable in integer expressions. (3-30 3.9.2) -// * function: idl_checkUnaryExpression -// * function: idl_checkBinaryExpression -// * -// * [13] The right hand operand value of the ">>" and "<<" binary operator must be in the range 0..63. (3-31 3.9.2) -// * function: idl_checkBinaryExpression -// * -// * [14] must evaluate to a positive integer constant. (3-31 3.9.2) -// * function: idl_checkConstantDeclaration -// * -// * [15] Values for an octet constant outside the range 0..255 shall cause a compile-time error. (3-31 3.9.2) -// * function: idl_checkConstantDeclaration -// * -// * [16] The constant name for the right hand side of an enumerated constant definition must denote one of the -// * enumerators defined for the enumerated type of the constant. (3-31 3.9.2) -// * function: idl_checkConstantDeclaration -// * -// * [17] The char data type can take an 8 bit quantity (0-255). (3-34 3.10.1.3) -// * function: idl_checkConstantDeclaration -// * -// * [18] The boolean data type can take one of the values "TRUE" and "FALSE". (3-34 3.10.1.5) -// * function: idl_checkConstantDeclaration -// * -// * 4 Type Declaration -// * -// * [19] The in must be a previously defined type. (3-31 3.10) -// * funtion: Checked by the parser -// * -// * 4.1 Constructed Type -// * -// * [20] The only recursion allowed is via the use of the sequence template type. (3-35 3.10.2) -// * -// * 4.2 Structures -// * -// * [21] Structure member declarators in a particular structure must be unique. (3-35 3.10.2.1) -// * function: idl_checkStructDeclaratorDefinition -// * -// * 4.3 Discriminated Unions -// * -// * [22] The in a must be consistent with the . (3-36 3.10.2.2) -// * function: idl_checkConstantOperand -// * -// * [23] A default case can appear at most once. (3-36 3.10.2.2) -// * function: idl_checkUnionCaseDefinition -// * -// * [24] The in the must be a previously defined integer, char, boolean -// * or enum type. (3-36 3.10.2.2) -// * function: idl_checkUnionCaseDefinition -// * -// * [25] Case labels must match or be automatically castable to the defined type of the discriminator -// * (see table 3-12). (3-36 3.10.2.2) -// * function: idl_checkConstantOperand -// * -// * [26] Element declarators in a particular union must be unique. (3-37 3.10.2.2) -// * function: idl_checkUnionDeclaratorDefinition -// * -// * [27] If the is an , the identifier for the enumeration is in the scope of -// * the union; as a result, it must be distinct from the element declarators (3-37 3.10.2.2). -// * function: idl_checkUnionDeclaratorDefinition -// * -// * [28] It is illegal to specify a union with the default case label if the set of case labels completely -// * covers the possible values for the discriminant. (IDL to Java Language Mapping Specification 1-21 1.9) -// * function: idl_checkUnionDeclaratorDefinition -// * -// * 4.4 Enumerations -// * -// * [29] A maximum of 2^32 identifiers may be specified. (3-37 3.10.2.3) -// * function: idl_checkEnumerationElementCount -// * -// * 4.5 Template Types -// * -// * [30] Value of must evaluate to a positive integer constant. (3-38 3.10.3.1) -// * function: idl_checkIntegerPositive -// * -// * [31] Value of must evaluate to a positive integer constant. (3-38 3.10.3.2) -// * function: idl_checkIntegerPositive -// * -// * [32] Value of must evaluate to a positive integer constant. (3-39 3.10.3.3) -// * function: idl_checkIntegerPositive -// * -// * 4.6 Complex Declarator -// * -// * [33] Value of must evaluate to a positive integer constant. (3-39 3.10.4.1) -// * function: idl_checkIntegerPositive -// * -// * 5 Keylist -// * -// * The following syntax is assumed: #pragma keylist * -// * -// * [34] The must be the name a previously defined type of which the actual type is a -// * structure type or an union type. -// * function: idl_checkKeyListTypeName -// * -// * [35] The is the name of a member of the structure that is specified with . -// * function: idl_checkKeyListFieldName -// * -// * [36] The syntax should also allow ',' as seperator for the -// * -// * [37] The member specified by the should be one of the following types: -// * - primitive types: boolean, char, long, octet, -// * - enumeration -// * -// * 6 Unsupported types -// * -// * [38] The preprocessor shall not generate code for the following primitive types or -// * constructed types using these primitive types: -// * - valuetype, long double, wchar, any, Object, wstring, fixed, ValueBase -// * function: checkUnsupportedTypeUsage (called from idl_checkKeyListTypeName) -// -*/ + * 1 Introduction + * + * This document analyses the semantic checks required for the OpenSpliceDDS IDL pre-processor on the IDL input. + * The analysis is based upon OMG Spec "The Common Object Request Broker: Archtecture and Specification", V2.3.1. + * Semantic rules are identified by a [] enclosed number. + * + * 2 Generic + * + * [1] OMG IDL file must have "idl" extension. (3-3 3.1) + * function: Will not be checked + * + * [2] OMG IDL uses ASCII charset. (3-3 3.1) + * function: Will not be checked + * + * [3] OMG IDL identifiers consist of an arbitrary long sequence of ASCII alphabetic, digit and underscore + * characters. (3-6 3.2.3) + * function: Is checked by the scanner + * + * [4] OMG IDL identifiers must start with an ASCII alphabetic character. (3-6 3.2.3) + * function: Is checked by the scanner + * + * [5] Uppercase and lowercase characters are treated as the same letter, but OMG IDL identifiers that only + * differ in case collide. Identifiers for a given definition must be spelled identically with respect + * to the case. (3-6 3.2.3) + * funtion: idl_checkReferencedIdentifier + * + * [6] An identifier may be used only once within a namespace. There is only one namespace for each + * identifier in each scope. (3-6 3.2.3) + * A type name may be redefined in a nested scope. (3-50 3.15.3) + * function: idl_checkModuleDefinition + * function: idl_checkConstantDefinition + * function: idl_checkTypeDefinition + * function: idl_checkinterfaceDefinition + * function: idl_checkEnumerationElementDefinition + * function: idl_checkExceptionDefinition + * function: idl_checkOperationDefinition + * + * 3 Constant Declaration + * + * [7] The in the production must be a previously defined name of an , + * , , , , , , + * , or constant. (3-29 3.9.2) + * function: checked by the parser + * + * [8] An infix operator can combine two integers, floats or fixeds, but not mixtures of these. (3-29 3.9.2) + * function: idl_checkBinaryExpression + * + * [9] Infix operators are applicable only to integer, float and fixed types. (3-29 3.9.2) + * function: idl_checkBinaryExpression + * + * [10] It is an error if a sub-expression of an integer or float constant declaration exceeds the precision + * of the target type. (3-29 3.9.2) + * function: idl_checkBinaryExpression + * + * [11] Unary '+' and '-' and binary '*', '/', '+' and '-' are applicable in floating-point and fixed-point + * expressions. (3-30 3.9.2) + * function: idl_checkUnaryExpression + * + * [12] Unary '+', '-' and '~' and binary '*', '/', '%', '+', '-', '<<', '>>', '&', '|' and '^' operations + * are applicable in integer expressions. (3-30 3.9.2) + * function: idl_checkUnaryExpression + * function: idl_checkBinaryExpression + * + * [13] The right hand operand value of the ">>" and "<<" binary operator must be in the range 0..63. (3-31 3.9.2) + * function: idl_checkBinaryExpression + * + * [14] must evaluate to a positive integer constant. (3-31 3.9.2) + * function: idl_checkConstantDeclaration + * + * [15] Values for an octet constant outside the range 0..255 shall cause a compile-time error. (3-31 3.9.2) + * function: idl_checkConstantDeclaration + * + * [16] The constant name for the right hand side of an enumerated constant definition must denote one of the + * enumerators defined for the enumerated type of the constant. (3-31 3.9.2) + * function: idl_checkConstantDeclaration + * + * [17] The char data type can take an 8 bit quantity (0-255). (3-34 3.10.1.3) + * function: idl_checkConstantDeclaration + * + * [18] The boolean data type can take one of the values "TRUE" and "FALSE". (3-34 3.10.1.5) + * function: idl_checkConstantDeclaration + * + * 4 Type Declaration + * + * [19] The in must be a previously defined type. (3-31 3.10) + * funtion: Checked by the parser + * + * 4.1 Constructed Type + * + * [20] The only recursion allowed is via the use of the sequence template type. (3-35 3.10.2) + * + * 4.2 Structures + * + * [21] Structure member declarators in a particular structure must be unique. (3-35 3.10.2.1) + * function: idl_checkStructDeclaratorDefinition + * + * 4.3 Discriminated Unions + * + * [22] The in a must be consistent with the . (3-36 3.10.2.2) + * function: idl_checkConstantOperand + * + * [23] A default case can appear at most once. (3-36 3.10.2.2) + * function: idl_checkUnionCaseDefinition + * + * [24] The in the must be a previously defined integer, char, boolean + * or enum type. (3-36 3.10.2.2) + * function: idl_checkUnionCaseDefinition + * + * [25] Case labels must match or be automatically castable to the defined type of the discriminator + * (see table 3-12). (3-36 3.10.2.2) + * function: idl_checkConstantOperand + * + * [26] Element declarators in a particular union must be unique. (3-37 3.10.2.2) + * function: idl_checkUnionDeclaratorDefinition + * + * [27] If the is an , the identifier for the enumeration is in the scope of + * the union; as a result, it must be distinct from the element declarators (3-37 3.10.2.2). + * function: idl_checkUnionDeclaratorDefinition + * + * [28] It is illegal to specify a union with the default case label if the set of case labels completely + * covers the possible values for the discriminant. (IDL to Java Language Mapping Specification 1-21 1.9) + * function: idl_checkUnionDeclaratorDefinition + * + * 4.4 Enumerations + * + * [29] A maximum of 2^32 identifiers may be specified. (3-37 3.10.2.3) + * function: idl_checkEnumerationElementCount + * + * 4.5 Template Types + * + * [30] Value of must evaluate to a positive integer constant. (3-38 3.10.3.1) + * function: idl_checkIntegerPositive + * + * [31] Value of must evaluate to a positive integer constant. (3-38 3.10.3.2) + * function: idl_checkIntegerPositive + * + * [32] Value of must evaluate to a positive integer constant. (3-39 3.10.3.3) + * function: idl_checkIntegerPositive + * + * 4.6 Complex Declarator + * + * [33] Value of must evaluate to a positive integer constant. (3-39 3.10.4.1) + * function: idl_checkIntegerPositive + * + * 5 Keylist + * + * The following syntax is assumed: #pragma keylist * + * + * [34] The must be the name a previously defined type of which the actual type is a + * structure type or an union type. + * function: idl_checkKeyListTypeName + * + * [35] The is the name of a member of the structure that is specified with . + * function: idl_checkKeyListFieldName + * + * [36] The syntax should also allow ',' as seperator for the + * + * [37] The member specified by the should be one of the following types: + * - primitive types: boolean, char, long, octet, + * - enumeration + * + * 6 Unsupported types + * + * [38] The preprocessor shall not generate code for the following primitive types or + * constructed types using these primitive types: + * - valuetype, long double, wchar, any, Object, wstring, fixed, ValueBase + * function: checkUnsupportedTypeUsage (called from idl_checkKeyListTypeName) + */ #include "c_iterator.h" #include "c_metabase.h" #include "c_misc.h" @@ -1161,83 +1161,6 @@ objectName( return ""; } -#if 0 -static void -checkUnsupportedTypeUsage( - c_metaObject metaObject, - c_metaWalkActionArg arg) -{ - struct unsupportedArg *a = (struct unsupportedArg *)arg; - int i; - c_metaObject mo; - - if ((metaObject->name != NULL) && - (strncmp(IDL_UNSUP_PREFIX, metaObject->name, strlen(IDL_UNSUP_PREFIX)) == 0)) { - a->unsupported = TRUE; - a->typeName = idl_unsupportedTypeActualName(metaObject->name); - return; - } - switch (c_baseObject(metaObject)->kind) { - case M_COLLECTION: - checkUnsupportedTypeUsage(c_metaObject(c_collectionType(metaObject)->subType), arg); - break; - case M_CONSTANT: - checkUnsupportedTypeUsage(c_metaObject(c_constant(metaObject)->type), arg); - break; - case M_MEMBER: - checkUnsupportedTypeUsage(c_metaObject(c_specifier(metaObject)->type), arg); - break; - case M_TYPEDEF: - mo = c_metaObject(c_typeActualType(c_type(metaObject))); - checkUnsupportedTypeUsage(mo, arg); - break; - case M_UNION: - i = 0; - while ((i < c_arraySize(c_union(metaObject)->cases)) && - (a->unsupported == FALSE)) { - checkUnsupportedTypeUsage(c_metaObject(c_union(metaObject)->cases[i]), arg); - i++; - } - break; - case M_STRUCTURE: - i = 0; - while ((i < c_arraySize(c_structure(metaObject)->members)) && - (a->unsupported == FALSE)) { - checkUnsupportedTypeUsage(c_metaObject(c_structure(metaObject)->members[i]), arg); - i++; - } - break; - case M_UNIONCASE: - checkUnsupportedTypeUsage(c_metaObject(c_specifier(metaObject)->type), arg); - break; - /* supported by default */ - case M_ENUMERATION: - case M_LITERAL: - case M_PRIMITIVE: - /* do nothing */ - break; - /* unsupported by default */ - case M_UNDEFINED: - case M_ATTRIBUTE: - case M_CLASS: - case M_CONSTOPERAND: - case M_EXCEPTION: - case M_EXPRESSION: - case M_INTERFACE: - case M_MODULE: - case M_OPERATION: - case M_PARAMETER: - case M_RELATION: - case M_BASE: - case M_COUNT: - default: - a->unsupported = TRUE; - a->typeName = metaObject->name; - break; - } -} -#else - static ut_result checkRecursion( void *o, @@ -1335,7 +1258,6 @@ checkUnsupportedTypeUsage( } } /* else recursion detected, so skip this metaobject */ } -#endif /************************************************************************************************* * Global Functions *************************************************************************************************/ diff --git a/src/tools/idlpp/code/idl_sematicRules.h b/src/tools/idlpp/code/idl_sematicRules.h index 3bcba4114..bf4c75cac 100644 --- a/src/tools/idlpp/code/idl_sematicRules.h +++ b/src/tools/idlpp/code/idl_sematicRules.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/idlpp/code/idl_stacDef.c b/src/tools/idlpp/code/idl_stacDef.c index 765b0f6e2..87253f56e 100644 --- a/src/tools/idlpp/code/idl_stacDef.c +++ b/src/tools/idlpp/code/idl_stacDef.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -95,8 +96,8 @@ idl_stacDefIsFieldExcluded( const os_char* member); /* Create a new stac map specified by scope, - type name and staclist -*/ + * type name and staclist + */ static idl_stacMap idl_stacMapNew ( const c_metaObject scope, @@ -164,9 +165,7 @@ idl_stacDefAdd ( } } -/* - * Check if there is a stac applied to the given key. - */ +/* Check if there is a stac applied to the given key. */ c_bool idl_isStacDefFor( c_metaObject scope, @@ -364,7 +363,7 @@ idl_stacListItemIsDefined ( } if (si == -1) { - /* bottom of the stack is reached */ + /* bottom of the stack is reached */ if (typeScope == NULL || typeScope->name == NULL) { /* the typeScope has reached the bottom too, diff --git a/src/tools/idlpp/code/idl_stacDef.h b/src/tools/idlpp/code/idl_stacDef.h index ce82d5c6d..6b4463d0d 100644 --- a/src/tools/idlpp/code/idl_stacDef.h +++ b/src/tools/idlpp/code/idl_stacDef.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/idlpp/code/idl_streamsDef.c b/src/tools/idlpp/code/idl_streamsDef.c index a048f6d0f..3c1baa27b 100644 --- a/src/tools/idlpp/code/idl_streamsDef.c +++ b/src/tools/idlpp/code/idl_streamsDef.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -65,7 +66,7 @@ idl_streamsDefAdd ( { if(streamsDef) { - c_iterInsert (streamsDef->streamsList, idl_streamsMapNew(scope, typeName)); + streamsDef->streamsList = c_iterInsert (streamsDef->streamsList, idl_streamsMapNew(scope, typeName)); } } diff --git a/src/tools/idlpp/code/idl_streamsDef.h b/src/tools/idlpp/code/idl_streamsDef.h index 5a92effca..03668ec67 100644 --- a/src/tools/idlpp/code/idl_streamsDef.h +++ b/src/tools/idlpp/code/idl_streamsDef.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/idlpp/code/idl_tmplExp.c b/src/tools/idlpp/code/idl_tmplExp.c index 2e66ec05a..2271e0d7a 100644 --- a/src/tools/idlpp/code/idl_tmplExp.c +++ b/src/tools/idlpp/code/idl_tmplExp.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -400,6 +401,42 @@ idl_streamOutPut ( return str->curpos; } +void +idl_streamOutPrintf ( + /* QAC EXPECT 3673; Can not be solved here */ + const idl_streamOut stream, + const c_char *format, + ...) +{ + va_list args; + + if(stream) + { + size_t bufSize = 0; + c_char *buffer; + c_char *p; + + /* figure out how much buffer to allocate */ + va_start (args, format); + bufSize = (size_t)os_vsnprintf (NULL, 0, format, args); + va_end (args); + + buffer = os_malloc(bufSize + 1); + + /* do the actual printf */ + va_start (args, format); + (void)os_vsnprintf (buffer, bufSize + 1, format, args); + va_end (args); + + for(p = buffer; *p; p++) { + idl_streamOutPut(stream, *p); + } + + os_free(buffer); + } +} + + /**************************************************************** * File Output Stream Class Implementation * ****************************************************************/ @@ -433,12 +470,12 @@ idl_dirOutNew( c_bool result; os_result status; char dirName[OS_PATH_MAX]; - struct os_stat statBuf; + struct os_stat_s statBuf; unsigned int i; memset(dirName, 0, OS_PATH_MAX); - if (name) { + if ((name) && (strlen(name))) { result = TRUE; for (i=0; ilabelType = idl_ldefault; - - return labelVal; -} -#endif - /** @brief free an idl_labelVal instance * * @param labelVal Class to operate on @@ -1194,7 +1178,8 @@ idl_isContiguous( * vector for size. One bit per bool apparently. */ return FALSE; } - /* Drop through... */ + return TRUE; + break; case M_ENUMERATION: return TRUE; break; diff --git a/src/tools/idlpp/code/idl_typeSpecifier.h b/src/tools/idlpp/code/idl_typeSpecifier.h index 9ba624647..f8c60a5ba 100644 --- a/src/tools/idlpp/code/idl_typeSpecifier.h +++ b/src/tools/idlpp/code/idl_typeSpecifier.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/idlpp/code/idl_unsupported.c b/src/tools/idlpp/code/idl_unsupported.c index a8ce27dc4..4bb0cda83 100644 --- a/src/tools/idlpp/code/idl_unsupported.c +++ b/src/tools/idlpp/code/idl_unsupported.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/idlpp/code/idl_unsupported.h b/src/tools/idlpp/code/idl_unsupported.h index 63bf64631..b7caf676d 100644 --- a/src/tools/idlpp/code/idl_unsupported.h +++ b/src/tools/idlpp/code/idl_unsupported.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/idlpp/code/idl_walk.c b/src/tools/idlpp/code/idl_walk.c index 76437855e..a84e29b53 100644 --- a/src/tools/idlpp/code/idl_walk.c +++ b/src/tools/idlpp/code/idl_walk.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -37,6 +38,10 @@ #include "idl_genLanguageHelper.h" #include "idl_unsupported.h" +#include "idl_genISOCxx2Helper.h" + +#include "limits.h" + /*********************************************************************** * * Global function implementations @@ -80,11 +85,10 @@ void idl_unionSwitch (c_type o, idl_context context); void idl_unionLabel (c_type t, c_literal o, idl_context context); void idl_enumerationElement (c_enumeration e, c_constant o, idl_context context); -static idl_operand idl_makeConstExpression (c_expression operand, c_type type); -static idl_operand idl_makeConstLiteral (c_literal operand, c_type type); -static idl_constSpec idl_makeConstSpec (c_constant o); -static idl_operand idl_makeConstOperand (c_constant operand); -static idl_typeSpec idl_makeTypeSpec (c_type type); +static idl_operand idl_makeConstExpression (c_expression operand, c_type type, void *userData); +static idl_operand idl_makeConstLiteral (c_literal operand, c_type type, void *userData); +static idl_constSpec idl_makeConstSpec (c_constant o, void *userData); +static idl_operand idl_makeConstOperand (c_constant operand, void *userData); static c_iter presetModules = NULL; static c_char *presetFilename = NULL; @@ -777,7 +781,7 @@ idl_makeTypeTypedef( return typeDef; } -static idl_typeSpec +idl_typeSpec idl_makeTypeSpec( c_type type) { @@ -1093,7 +1097,7 @@ idl_expressionKind ( break; default: /* set kind to fix warning. undefined behavior - * warning: ‘kind’ may be used uninitialized in this function [-Wuninitialized] + * warning: kind may be used uninitialized in this function [-Wuninitialized] */ kind = idl_not; printf("idl_expressionKind: Unknown expression kind %d\n", expr->kind); @@ -1104,7 +1108,8 @@ idl_expressionKind ( static idl_operand idl_makeConstExpression( c_expression expr, - c_type type) + c_type type, + void *userData) { idl_constExpression constExpr; c_ulong i; @@ -1116,16 +1121,16 @@ idl_makeConstExpression( exprOper = c_operand(expr->operands[i]); switch (c_baseObject(exprOper)->kind) { case M_CONSTANT: - operand = idl_makeConstOperand(c_constant(exprOper)); + operand = idl_makeConstOperand(c_constant(exprOper), userData); break; case M_CONSTOPERAND: - operand = idl_makeConstOperand(c_constOperand(exprOper)->constant); + operand = idl_makeConstOperand(c_constOperand(exprOper)->constant, userData); break; case M_LITERAL: - operand = idl_makeConstLiteral(c_literal(exprOper), type); + operand = idl_makeConstLiteral(c_literal(exprOper), type, userData); break; case M_EXPRESSION: - operand = idl_makeConstExpression(c_expression(exprOper), type); + operand = idl_makeConstExpression(c_expression(exprOper), type, userData); break; default: printf("idl_makeConstExpression: Unexpected %d operand\n", c_baseObject(exprOper)->kind); @@ -1139,259 +1144,62 @@ idl_makeConstExpression( static idl_operand idl_makeConstLiteral( c_literal operand, - c_type type) + c_type type, + void *userData) { - idl_constLiteral constLit; - char *val = NULL; - char *val2; - int i; - - if (c_baseObject(type)->kind != M_ENUMERATION) { - switch (operand->value.kind) { - case V_OCTET: - val = os_malloc (40); - if (idl_getLanguage() == IDL_LANG_JAVA || idl_getLanguage() == IDL_LANG_CS) { - snprintf(val, 40, "%d", operand->value.is.Octet); - } else { - snprintf(val, 40, "%x", operand->value.is.Octet); - } - break; - case V_FLOAT: - case V_DOUBLE: - val2 = os_malloc(45); - val = os_malloc(45); - snprintf(val2, 45, "%40.17g", operand->value.is.Double); - i = 0; - while (val2[i] == ' ') { - i++; - } - os_strncpy(val, &val2[i], 40); - os_free(val2); - if ((strchr(val, '.') == NULL) && (strchr(val, 'E') == NULL)) { - strcat(val, ".0"); - } - break; - case V_STRING: - val = os_malloc(strlen(operand->value.is.String)+3); - snprintf(val, strlen(operand->value.is.String)+3, "\"%s\"", operand->value.is.String); - break; - case V_BOOLEAN: - val = os_malloc(40); - if (idl_getLanguage() == IDL_LANG_JAVA || idl_getLanguage() == IDL_LANG_CS) { - if (operand->value.is.Boolean) { - snprintf(val, 40, "true"); - } else { - snprintf (val, 40, "false"); - } - } else { - if (operand->value.is.Boolean) { - snprintf(val, 40, "TRUE"); - } else { - snprintf (val, 40, "FALSE"); - } - } - break; - case V_LONGLONG: - val = os_malloc(40); - if (idl_getLanguage() == IDL_LANG_JAVA || idl_getLanguage() == IDL_LANG_CS) { - switch (c_primitive(type)->kind) { - case P_SHORT: - snprintf(val, 40, "%hd", (c_short)operand->value.is.LongLong); - break; - case P_USHORT: - snprintf(val, 40, "%hd", (c_short)operand->value.is.LongLong); - break; - case P_LONG: - snprintf(val, 40, "%d", (c_long)operand->value.is.LongLong); - break; - case P_ULONG: - snprintf(val, 40, "%d", (c_long)operand->value.is.LongLong); - break; - case P_LONGLONG: - snprintf(val, 40, "%"PA_PRId64"", (c_longlong)operand->value.is.LongLong); - break; - case P_ULONGLONG: - snprintf(val, 40, "%"PA_PRId64"", (c_longlong)operand->value.is.LongLong); - break; - case P_CHAR: - snprintf(val, 40, "%d", (unsigned char)operand->value.is.LongLong); - break; - case P_OCTET: - snprintf(val, 40, "%d", (unsigned char)operand->value.is.LongLong); - break; - case P_ADDRESS: - snprintf(val, 40, PA_ADDRFMT, (PA_ADDRCAST)operand->value.is.LongLong); - break; - case P_UNDEFINED: - case P_BOOLEAN: - case P_WCHAR: - case P_FLOAT: - case P_DOUBLE: - case P_VOIDP: - case P_MUTEX: - case P_LOCK: - case P_COND: - case P_COUNT: - case P_PA_UINT32: - case P_PA_UINTPTR: - case P_PA_VOIDP: - /* Do nothing */ - break; - } - } else { - switch (c_primitive(type)->kind) { - case P_SHORT: - snprintf(val, 40, "%hu", (c_short)operand->value.is.LongLong); - break; - case P_USHORT: - snprintf(val, 40, "%huU", (c_ushort)operand->value.is.LongLong); - break; - case P_LONG: - snprintf(val, 40, "%uL", (c_long)operand->value.is.LongLong); - break; - case P_ULONG: - snprintf(val, 40, "%uUL", (c_ulong)operand->value.is.LongLong); - break; - case P_LONGLONG: - snprintf(val, 40, "%"PA_PRIu64"LL", (c_longlong)operand->value.is.LongLong); - break; - case P_ULONGLONG: - snprintf(val, 40, "%"PA_PRIu64"ULL", (c_ulonglong)operand->value.is.LongLong); - break; - case P_CHAR: - snprintf(val, 40, "%u", (unsigned char)operand->value.is.LongLong); - break; - case P_OCTET: - snprintf(val, 40, "%u", (unsigned char)operand->value.is.LongLong); - break; - case P_ADDRESS: - snprintf(val, 40, PA_ADDRFMT, (PA_ADDRCAST)operand->value.is.LongLong); - break; - case P_UNDEFINED: - case P_BOOLEAN: - case P_WCHAR: - case P_FLOAT: - case P_DOUBLE: - case P_VOIDP: - case P_MUTEX: - case P_LOCK: - case P_COND: - case P_COUNT: - case P_PA_UINT32: - case P_PA_UINTPTR: - case P_PA_VOIDP: - /* Do nothing */ - break; - } - } - break; - case V_SHORT: - val = os_malloc(40); - snprintf(val, 40, "%hd", operand->value.is.Short); - break; - case V_LONG: - val = os_malloc(40); - if (idl_getLanguage() == IDL_LANG_JAVA || idl_getLanguage() == IDL_LANG_CS) { - snprintf(val, 40, "%d", (c_long)operand->value.is.Long); - } else { - snprintf(val, 40, "%dL", operand->value.is.Long); - } - break; - case V_USHORT: - val = os_malloc(40); - if (idl_getLanguage() == IDL_LANG_JAVA || idl_getLanguage() == IDL_LANG_CS) { - snprintf(val, 40, "%hd", (c_short)operand->value.is.UShort); - } else { - snprintf(val, 40, "%huU", operand->value.is.UShort); - } - break; - case V_ULONG: - val = os_malloc(40); - if (idl_getLanguage() == IDL_LANG_JAVA || idl_getLanguage() == IDL_LANG_CS) { - snprintf(val, 40, "%d", (c_long)operand->value.is.ULong); - } else { - snprintf(val, 40, "%uUL", operand->value.is.ULong); - } - break; - case V_ULONGLONG: - val = os_malloc(40); - if (idl_getLanguage() == IDL_LANG_JAVA || idl_getLanguage() == IDL_LANG_CS) { - snprintf(val, 40, "%" PA_PRId64, (c_longlong)operand->value.is.ULongLong); - } else { - snprintf(val, 40, "%" PA_PRIu64 "ULL", operand->value.is.ULongLong); - } - break; - case V_ADDRESS: - val = os_malloc(40); - snprintf(val, 40, PA_ADDRFMT, (PA_ADDRCAST)operand->value.is.Address); - break; - case V_CHAR: - val = os_malloc(40); - snprintf(val, 40, "%u", (unsigned char)operand->value.is.Char); - break; - case V_UNDEFINED: - case V_WCHAR: - case V_WSTRING: - case V_FIXED: - case V_VOIDP: - case V_OBJECT: - case V_COUNT: - /* Invalid types for literal constants*/ - /* FALL THROUGH */ - default: - val = NULL; - break; - } - } else { - val = os_strdup(c_metaObject(c_constant(c_enumeration(type)->elements[operand->value.is.Long]))->name); - } - constLit = idl_constLiteralNew(val); + char *val = idl_genLanguageLiteralValueImage(operand->value, type, userData); + idl_constLiteral constLit = idl_constLiteralNew(val); + os_free(val); return (idl_operand)constLit; } static idl_operand idl_makeConstOperand( - c_constant operand) + c_constant operand, + void *userData) { idl_constOperand constOper; idl_constSpec constSpec; - constSpec = idl_makeConstSpec(operand); + constSpec = idl_makeConstSpec(operand, userData); constOper = idl_constOperandNew(constSpec); return (idl_operand)constOper; } static idl_constSpec idl_makeConstSpec( - c_constant o) + c_constant o, + void *userData) { idl_constSpec constSpec; idl_typeSpec typeSpec; idl_operand operand = NULL; + char *name = os_strdup(c_metaObject(o)->name); typeSpec = idl_makeTypeSpec(o->type); - constSpec = idl_constSpecNew(c_metaObject(o)->name, typeSpec, idl_buildScope(c_metaObject(o))); switch (c_baseObject(o->operand)->kind) { case M_CONSTANT: - operand = idl_makeConstOperand(c_constant(o->operand)); + operand = idl_makeConstOperand(c_constant(o->operand), userData); break; case M_CONSTOPERAND: - operand = idl_makeConstOperand(c_constOperand(o->operand)->constant); + operand = idl_makeConstOperand(c_constOperand(o->operand)->constant, userData); break; case M_LITERAL: - if (c_baseObject(o->operand)->kind == M_ENUMERATION) { - operand = idl_makeConstOperand(c_constant(o->operand)); - } else { - operand = idl_makeConstLiteral(c_literal(o->operand), c_typeActualType(o->type)); + operand = idl_makeConstLiteral(c_literal(o->operand), c_typeActualType(o->type), userData); + if (c_baseObject(o->type)->kind == M_ENUMERATION) { + os_free(name); + name = idl_constLiteralImage(idl_constLiteral(operand)); } break; case M_EXPRESSION: - operand = idl_makeConstExpression(c_expression(o->operand), c_typeActualType(o->type)); + operand = idl_makeConstExpression(c_expression(o->operand), c_typeActualType(o->type), userData); break; default: printf("idl_makeConstSpec: Unexpected %d operand\n", c_baseObject(o->operand)->kind); } + constSpec = idl_constSpecNew(name, typeSpec, idl_buildScope(c_metaObject(o))); idl_constSpecOperandSet(constSpec, operand); + os_free(name); return constSpec; } @@ -1567,7 +1375,7 @@ idl_constant( if ((c_baseObject(o->type)->kind != M_ENUMERATION) || ((c_baseObject(o->type)->kind == M_ENUMERATION) && (c_baseObject(o->operand)->kind == M_CONSTANT))) { /* Ignore enumeration elements */ - constSpec = idl_makeConstSpec (o); + constSpec = idl_makeConstSpec (o, context->program->userData); if (context->program->constantOpenClose) { context->program->constantOpenClose(context->ownScope, constSpec, context->program->userData); } @@ -1605,6 +1413,7 @@ idl_typedef( if (context->program->typedefOpenClose) { idl_typeDef typeDef = idl_makeTypeTypedef(o); context->program->typedefOpenClose(context->ownScope, c_metaObject(o)->name, typeDef, context->program->userData); + idl_typeDefFree(typeDef); } } @@ -1616,6 +1425,7 @@ idl_boundedString( if (context->program->boundedStringOpenClose) { idl_typeBasic typeBasic = idl_makeTypeBasic(c_type(o)); context->program->boundedStringOpenClose(context->ownScope, typeBasic, context->program->userData); + idl_typeBasicFree(typeBasic); } } @@ -1755,16 +1565,19 @@ idl_unionCase( if (context->program->unionLabelsOpenClose) { idl_labelSpec labelSpec = idl_labelSpecNew(labelType, labelCount); context->program->unionLabelsOpenClose(context->ownScope, labelSpec, context->program->userData); + idl_labelSpecFree(labelSpec); } if (labelCount == 0) { if (idl_contextTrace(context)) { printf(" idl_unionCase: default\n"); } if (context->program->unionLabelOpenClose) { + idl_labelVal alternativeVal = idl_switchLabel(defaultLabelVal); idl_labelVal labelVal = idl_labelVal(idl_labelDefaultNew(alternativeVal)); context->program->unionLabelOpenClose(context->ownScope, labelVal, context->program->userData); + idl_labelDefaultFree(idl_labelDefault(labelVal)); } } else { for (li = 0; li < labelCount; li++) { @@ -1780,9 +1593,11 @@ idl_unionCase( labelVal = idl_labelEnumNew(idl_buildScope(c_metaObject(u->switchType)), c_metaObject(c_constant(e))->name); context->program->unionLabelOpenClose(context->ownScope, idl_labelVal(labelVal), context->program->userData); + idl_labelEnumFree(labelVal); } else { idl_labelValue labelVal = idl_labelValueNew(c_literal(o->labels[li])->value); context->program->unionLabelOpenClose(context->ownScope, idl_labelVal(labelVal), context->program->userData); + idl_labelValueFree(labelVal); } } } @@ -1954,8 +1769,8 @@ idl_emulateScopesAdd(c_iter objects, c_metaObject from, c_metaObject to) { if(to != from) { idl_emulateScopesAdd(objects, from, to->definedIn); - c_iterAppend(objects, to); - c_iterAppend(objects, SCOPE_OPEN); + (void)c_iterAppend(objects, to); + (void)c_iterAppend(objects, SCOPE_OPEN); } } @@ -1983,7 +1798,7 @@ idl_emulateScopesEnter(c_metaObject from, c_metaObject to, idl_emulateScopesWalk /* Add zero-markers from 'from' to the common scope (exit scope) */ scope = from; while(scope != sFrom) { - c_iterAppend(userData->objects, SCOPE_CLOSE); + userData->objects = c_iterAppend(userData->objects, SCOPE_CLOSE); scope = scope->definedIn; } @@ -2066,7 +1881,7 @@ idl_emulateScopes( /* Start with base */ walkData.scope = c_metaObject(base); walkData.objects = c_iterNew(SCOPE_OPEN); - c_iterWalk(objects, (c_iterWalkAction)idl_emulateScopesWalk, &walkData); + (void)c_iterWalk(objects, (c_iterWalkAction)idl_emulateScopesWalk, &walkData); return walkData.objects; } @@ -2126,7 +1941,7 @@ static void idl_insertModuleObject(c_metaObject o, c_iter objects) { /* Fallthrough on purpose */ default: - c_iterInsert(objects, o); + (void)c_iterInsert(objects, o); break; } } diff --git a/src/tools/idlpp/code/idl_walk.h b/src/tools/idlpp/code/idl_walk.h index bac2db4ca..9e1d2ac5d 100644 --- a/src/tools/idlpp/code/idl_walk.h +++ b/src/tools/idlpp/code/idl_walk.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -47,6 +48,14 @@ idl_typeSpec idl_makeTypeCollection( c_collectionType type); +idl_typeSpec +idl_makeTypeSpec( + c_type type); + +void +idl_freeTypeSpec( + idl_typeSpec typeSpec); + idl_scope idl_buildScope ( c_metaObject o); diff --git a/src/tools/idlpp/include/idl_genSajMeta.h b/src/tools/idlpp/include/idl_genSajMeta.h index a7983bcdc..d3d95f6dd 100644 --- a/src/tools/idlpp/include/idl_genSajMeta.h +++ b/src/tools/idlpp/include/idl_genSajMeta.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/makefile b/src/tools/makefile index 9c424d3d5..b20cd35c8 100644 --- a/src/tools/makefile +++ b/src/tools/makefile @@ -23,6 +23,7 @@ endif ifeq ($(INCLUDE_TOOLS_DEBUG),yes) SUBSYSTEMS += debug +SUBSYSTEMS += topmon endif ifneq (,$(findstring devdat,$(SPLICE_TARGET))) diff --git a/src/tools/mmstat/common/code/mm_metakindNames.c b/src/tools/mmstat/common/code/mm_metakindNames.c index 4d8089c96..45dade036 100644 --- a/src/tools/mmstat/common/code/mm_metakindNames.c +++ b/src/tools/mmstat/common/code/mm_metakindNames.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/mmstat/common/include/mm_metakindNames.h b/src/tools/mmstat/common/include/mm_metakindNames.h index 348f2ad72..8513ca645 100644 --- a/src/tools/mmstat/common/include/mm_metakindNames.h +++ b/src/tools/mmstat/common/include/mm_metakindNames.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/mmstat/unix/code/mm_metakindNames.c b/src/tools/mmstat/unix/code/mm_metakindNames.c index a5f4f43e4..f4fa8dbf5 100644 --- a/src/tools/mmstat/unix/code/mm_metakindNames.c +++ b/src/tools/mmstat/unix/code/mm_metakindNames.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/mmstat/unix/code/mm_ms.c b/src/tools/mmstat/unix/code/mm_ms.c index f79323af2..23242de98 100644 --- a/src/tools/mmstat/unix/code/mm_ms.c +++ b/src/tools/mmstat/unix/code/mm_ms.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -289,12 +290,12 @@ monitor_msAction ( MM_MS_NEWLINE , timbuf, - (unsigned long)(s.size - msData->prevState.size), + s.size - msData->prevState.size, s.count - msData->prevState.count, - (unsigned long)(s.used - msData->prevState.used), - (unsigned long)(s.preallocated - msData->prevState.preallocated), - (unsigned long)(s.maxUsed - msData->prevState.maxUsed), - (unsigned long)(s.garbage - msData->prevState.garbage), + s.used - msData->prevState.used, + s.preallocated - msData->prevState.preallocated, + s.maxUsed - msData->prevState.maxUsed, + s.garbage - msData->prevState.garbage, s.fails - msData->prevState.fails); msData->prevState = s; @@ -309,11 +310,11 @@ monitor_msAction ( MM_MS_NEWLINE , timbuf, - (unsigned long)(s.size - msData->prevState.size), + s.size - msData->prevState.size, s.count - msData->prevState.count, - (unsigned long)(s.used - msData->prevState.used), - (unsigned long)(s.maxUsed - msData->prevState.maxUsed), - (unsigned long)(s.garbage - msData->prevState.garbage), + s.used - msData->prevState.used, + s.maxUsed - msData->prevState.maxUsed, + s.garbage - msData->prevState.garbage, s.fails - msData->prevState.fails); msData->prevState = s; diff --git a/src/tools/mmstat/unix/code/mm_ms.h b/src/tools/mmstat/unix/code/mm_ms.h index 17480d236..6dee01ee8 100644 --- a/src/tools/mmstat/unix/code/mm_ms.h +++ b/src/tools/mmstat/unix/code/mm_ms.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/mmstat/unix/code/mm_orc.c b/src/tools/mmstat/unix/code/mm_orc.c index a7a240e50..0beedab71 100644 --- a/src/tools/mmstat/unix/code/mm_orc.c +++ b/src/tools/mmstat/unix/code/mm_orc.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/mmstat/unix/code/mm_orc.h b/src/tools/mmstat/unix/code/mm_orc.h index b599cffaf..24d98efb3 100644 --- a/src/tools/mmstat/unix/code/mm_orc.h +++ b/src/tools/mmstat/unix/code/mm_orc.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/mmstat/unix/code/mm_trc.c b/src/tools/mmstat/unix/code/mm_trc.c index a54f117cf..85dd959b6 100644 --- a/src/tools/mmstat/unix/code/mm_trc.c +++ b/src/tools/mmstat/unix/code/mm_trc.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/mmstat/unix/code/mm_trc.h b/src/tools/mmstat/unix/code/mm_trc.h index 1dab18e67..041b743e1 100644 --- a/src/tools/mmstat/unix/code/mm_trc.h +++ b/src/tools/mmstat/unix/code/mm_trc.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/mmstat/unix/code/mmstat.c b/src/tools/mmstat/unix/code/mmstat.c index f7d329640..31ba63c38 100644 --- a/src/tools/mmstat/unix/code/mmstat.c +++ b/src/tools/mmstat/unix/code/mmstat.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/mmstat/win32/code/mm_metakindNames.c b/src/tools/mmstat/win32/code/mm_metakindNames.c index a5f4f43e4..f4fa8dbf5 100644 --- a/src/tools/mmstat/win32/code/mm_metakindNames.c +++ b/src/tools/mmstat/win32/code/mm_metakindNames.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/mmstat/win32/code/mm_ms.c b/src/tools/mmstat/win32/code/mm_ms.c index 60c2671ee..e737917a7 100644 --- a/src/tools/mmstat/win32/code/mm_ms.c +++ b/src/tools/mmstat/win32/code/mm_ms.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/mmstat/win32/code/mm_ms.h b/src/tools/mmstat/win32/code/mm_ms.h index 17480d236..6dee01ee8 100644 --- a/src/tools/mmstat/win32/code/mm_ms.h +++ b/src/tools/mmstat/win32/code/mm_ms.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/mmstat/win32/code/mm_orc.c b/src/tools/mmstat/win32/code/mm_orc.c index 1b710b154..4b47387a2 100644 --- a/src/tools/mmstat/win32/code/mm_orc.c +++ b/src/tools/mmstat/win32/code/mm_orc.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/mmstat/win32/code/mm_orc.h b/src/tools/mmstat/win32/code/mm_orc.h index b599cffaf..24d98efb3 100644 --- a/src/tools/mmstat/win32/code/mm_orc.h +++ b/src/tools/mmstat/win32/code/mm_orc.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/mmstat/win32/code/mm_trc.c b/src/tools/mmstat/win32/code/mm_trc.c index 0654e2ed6..1d75f917b 100644 --- a/src/tools/mmstat/win32/code/mm_trc.c +++ b/src/tools/mmstat/win32/code/mm_trc.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/mmstat/win32/code/mm_trc.h b/src/tools/mmstat/win32/code/mm_trc.h index 23507645c..deef66f60 100644 --- a/src/tools/mmstat/win32/code/mm_trc.h +++ b/src/tools/mmstat/win32/code/mm_trc.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/mmstat/win32/code/mmstat.c b/src/tools/mmstat/win32/code/mmstat.c index a4cbf2594..1e13a987b 100644 --- a/src/tools/mmstat/win32/code/mmstat.c +++ b/src/tools/mmstat/win32/code/mmstat.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -387,7 +388,7 @@ main (int argc, char *argv[]) if (no_break && interval) { delay -= 100; - (void)os_sleep (SLEEP_INTERVAL); + (void)ospl_os_sleep (SLEEP_INTERVAL); } } else diff --git a/src/tools/protobuf/gpb/code/com/prismtech/dds/protobuf/CompilerPlugin.java b/src/tools/protobuf/gpb/code/com/prismtech/dds/protobuf/CompilerPlugin.java index 41b629129..afbc4ba91 100644 --- a/src/tools/protobuf/gpb/code/com/prismtech/dds/protobuf/CompilerPlugin.java +++ b/src/tools/protobuf/gpb/code/com/prismtech/dds/protobuf/CompilerPlugin.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/protobuf/gpb/code/com/prismtech/dds/protobuf/Logger.java b/src/tools/protobuf/gpb/code/com/prismtech/dds/protobuf/Logger.java index cfdf47fcb..a4246c164 100644 --- a/src/tools/protobuf/gpb/code/com/prismtech/dds/protobuf/Logger.java +++ b/src/tools/protobuf/gpb/code/com/prismtech/dds/protobuf/Logger.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/protobuf/gpb/code/com/prismtech/dds/protobuf/ProtoParseException.java b/src/tools/protobuf/gpb/code/com/prismtech/dds/protobuf/ProtoParseException.java index 763af9d60..914895298 100644 --- a/src/tools/protobuf/gpb/code/com/prismtech/dds/protobuf/ProtoParseException.java +++ b/src/tools/protobuf/gpb/code/com/prismtech/dds/protobuf/ProtoParseException.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/protobuf/gpb/code/com/prismtech/dds/protobuf/Util.java b/src/tools/protobuf/gpb/code/com/prismtech/dds/protobuf/Util.java index b5d7fcb37..24ab477aa 100644 --- a/src/tools/protobuf/gpb/code/com/prismtech/dds/protobuf/Util.java +++ b/src/tools/protobuf/gpb/code/com/prismtech/dds/protobuf/Util.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/protobuf/gpb/code/com/prismtech/dds/protobuf/backend/CodeGenerator.java b/src/tools/protobuf/gpb/code/com/prismtech/dds/protobuf/backend/CodeGenerator.java index 73b89075b..26cbb7336 100644 --- a/src/tools/protobuf/gpb/code/com/prismtech/dds/protobuf/backend/CodeGenerator.java +++ b/src/tools/protobuf/gpb/code/com/prismtech/dds/protobuf/backend/CodeGenerator.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/protobuf/gpb/code/com/prismtech/dds/protobuf/backend/Idlpp.java b/src/tools/protobuf/gpb/code/com/prismtech/dds/protobuf/backend/Idlpp.java index 15832815c..a800c2074 100644 --- a/src/tools/protobuf/gpb/code/com/prismtech/dds/protobuf/backend/Idlpp.java +++ b/src/tools/protobuf/gpb/code/com/prismtech/dds/protobuf/backend/Idlpp.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/protobuf/gpb/code/com/prismtech/dds/protobuf/backend/cafe/CafeJava5CodeGenerator.java b/src/tools/protobuf/gpb/code/com/prismtech/dds/protobuf/backend/cafe/CafeJava5CodeGenerator.java index 7b3ad657f..f763a2b50 100644 --- a/src/tools/protobuf/gpb/code/com/prismtech/dds/protobuf/backend/cafe/CafeJava5CodeGenerator.java +++ b/src/tools/protobuf/gpb/code/com/prismtech/dds/protobuf/backend/cafe/CafeJava5CodeGenerator.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/protobuf/gpb/code/com/prismtech/dds/protobuf/backend/cafe/CafeJava5Idlpp.java b/src/tools/protobuf/gpb/code/com/prismtech/dds/protobuf/backend/cafe/CafeJava5Idlpp.java index ee49ba835..3293c288c 100644 --- a/src/tools/protobuf/gpb/code/com/prismtech/dds/protobuf/backend/cafe/CafeJava5Idlpp.java +++ b/src/tools/protobuf/gpb/code/com/prismtech/dds/protobuf/backend/cafe/CafeJava5Idlpp.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/protobuf/gpb/code/com/prismtech/dds/protobuf/backend/lite/LiteIsocppCodeGenerator.java b/src/tools/protobuf/gpb/code/com/prismtech/dds/protobuf/backend/lite/LiteIsocppCodeGenerator.java index 416e36e2e..a73a3f8a6 100644 --- a/src/tools/protobuf/gpb/code/com/prismtech/dds/protobuf/backend/lite/LiteIsocppCodeGenerator.java +++ b/src/tools/protobuf/gpb/code/com/prismtech/dds/protobuf/backend/lite/LiteIsocppCodeGenerator.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/protobuf/gpb/code/com/prismtech/dds/protobuf/backend/lite/LiteIsocppIdlpp.java b/src/tools/protobuf/gpb/code/com/prismtech/dds/protobuf/backend/lite/LiteIsocppIdlpp.java index 8f9368e33..d4998204c 100644 --- a/src/tools/protobuf/gpb/code/com/prismtech/dds/protobuf/backend/lite/LiteIsocppIdlpp.java +++ b/src/tools/protobuf/gpb/code/com/prismtech/dds/protobuf/backend/lite/LiteIsocppIdlpp.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/protobuf/gpb/code/com/prismtech/dds/protobuf/backend/ospl/OsplIdlpp.java b/src/tools/protobuf/gpb/code/com/prismtech/dds/protobuf/backend/ospl/OsplIdlpp.java index 4edc4d7e4..56d37ecdf 100644 --- a/src/tools/protobuf/gpb/code/com/prismtech/dds/protobuf/backend/ospl/OsplIdlpp.java +++ b/src/tools/protobuf/gpb/code/com/prismtech/dds/protobuf/backend/ospl/OsplIdlpp.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/protobuf/gpb/code/com/prismtech/dds/protobuf/backend/ospl/OsplIsocppCodeGenerator.java b/src/tools/protobuf/gpb/code/com/prismtech/dds/protobuf/backend/ospl/OsplIsocppCodeGenerator.java index ff36353b4..2ef4fdf2a 100644 --- a/src/tools/protobuf/gpb/code/com/prismtech/dds/protobuf/backend/ospl/OsplIsocppCodeGenerator.java +++ b/src/tools/protobuf/gpb/code/com/prismtech/dds/protobuf/backend/ospl/OsplIsocppCodeGenerator.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -230,41 +231,50 @@ private String getIncludes() { return buffer.toString(); } - private String getProtobufMetaHash(MetaFile file, MetaMessage message) - throws ProtoParseException { + private String byteArrToString(byte[] meta) { String tab = CodeGenerator.IDL_TAB + CodeGenerator.IDL_TAB; - String tabPlusOne = tab + CodeGenerator.IDL_TAB; + String tab2 = tab + CodeGenerator.IDL_TAB; + StringBuffer buffer = new StringBuffer(); + int size = meta.length; + int len = 0; + int ub; + + buffer.append("static const os_uchar metaArr[" + size + "] = {\n"); + buffer.append(tab2); + for (int i=0; i= 120) { + buffer.append("\n"); + buffer.append(tab2); + len = 0; + } + ub = meta[i] & 0xff; + buffer.append(String.format("%d", ub)); + len += (ub < 10) ? 1 : (ub < 100) ? 2 : 3; + if (i != (size-1)) { + buffer.append(","); + len++; + } + } + buffer.append("\n"); + buffer.append(tab); + buffer.append("};\n"); + buffer.append(tab); + buffer.append("::std::vector val(&metaArr[0], &metaArr[" + size + "]);\n\n"); + buffer.append(tab); + buffer.append("return val;"); + + return buffer.toString(); + } + + private String getProtobufMetaHash(MetaFile file, MetaMessage message) + throws ProtoParseException { try { byte[] metaDescriptor = message.getProtobufMetaDescriptor(); MessageDigest md = MessageDigest.getInstance("MD5"); byte[] md5hash = md.digest(metaDescriptor); - StringBuffer buffer = new StringBuffer(); - int size = md5hash.length; - buffer.append("unsigned int tmp;\n"); - buffer.append(tab); - buffer.append("const char *hexMetaHash = \""); - for (final byte b : md5hash) { - buffer.append(String.format("%02x", b & 0xff)); - } - buffer.append("\", *pos = hexMetaHash;\n"); - buffer.append(tab); - buffer.append("::std::vector val(" + size + ");\n\n"); - buffer.append(tab); - buffer.append("for(size_t count = 0; count < val.size(); count++) {\n"); - buffer.append(tabPlusOne); - buffer.append("sscanf(pos, \"%2x\", &tmp);\n"); - buffer.append(tabPlusOne); - buffer.append("val[count] = (os_uchar)tmp;\n"); - buffer.append(tabPlusOne); - buffer.append("pos += 2;\n"); - buffer.append(tab); - buffer.append("}\n"); - buffer.append(tab); - buffer.append("return val;"); - - return buffer.toString(); + return byteArrToString(md5hash); } catch (NoSuchAlgorithmException e) { throw new ProtoParseException( "Unable to generate MD5 hash for message '" @@ -370,68 +380,7 @@ private String getProtobufKeySetters(MetaMessage message) { } private String getProtobufMetaDescriptor(MetaFile file) { - String metaDescriptor = file.getMetaDescriptorAsString(); - StringBuffer buffer = new StringBuffer(); - int length = metaDescriptor.length(); - String tab = CodeGenerator.IDL_TAB + CodeGenerator.IDL_TAB; - String tabPlusOne = tab + CodeGenerator.IDL_TAB; - String tabPlusTwo = tabPlusOne + CodeGenerator.IDL_TAB; - int index = 0; - int charsPerLine = 500; - - buffer.append("unsigned int tmp;\n"); - buffer.append(tab); - buffer.append("const char *hexMetaDescriptor[] = {"); - - while (index + charsPerLine < length) { - if (index != 0) { - buffer.append(","); - } - buffer.append("\n" + tabPlusOne + "\"" - + metaDescriptor.substring(index, index + charsPerLine) - + "\""); - index += charsPerLine; - } - if (length > (index - 1)) { - buffer.append(",\n" + tabPlusOne + "\"" - + metaDescriptor.substring(index) - + "\"}, *pos = hexMetaDescriptor[0];\n"); - } else { - buffer.append("\"}, *pos;\n"); - } - buffer.append(tab); - buffer.append("::std::vector val(" + length / 2 + ");\n"); - buffer.append(tab); - buffer.append("int element = 0;\n"); - buffer.append(tab); - buffer.append("size_t strIndex = " + charsPerLine - + " - 2, index = strIndex;\n\n"); - buffer.append(tab); - buffer.append("for(size_t count = 0; count < val.size(); count++) {\n"); - buffer.append(tabPlusOne); - buffer.append("if(index == strIndex) {\n"); - buffer.append(tabPlusTwo); - buffer.append("pos = hexMetaDescriptor[element++];\n"); - buffer.append(tabPlusTwo); - buffer.append("index = 0;\n"); - buffer.append(tabPlusOne); - buffer.append("} else {\n"); - buffer.append(tabPlusTwo); - buffer.append("pos += 2;\n"); - buffer.append(tabPlusTwo); - buffer.append("index += 2;\n"); - buffer.append(tabPlusOne); - buffer.append("}\n"); - buffer.append(tabPlusOne); - buffer.append("sscanf(pos, \"%2x\", &tmp);\n"); - buffer.append(tabPlusOne); - buffer.append("val[count] = (os_uchar)tmp;\n"); - buffer.append(tab); - buffer.append("}\n"); - buffer.append(tab); - buffer.append("return val;"); - - return buffer.toString(); + return byteArrToString(file.getMetaDescriptor()); } private String getProtobufExtensions(MetaFile file, MetaMessage message) { diff --git a/src/tools/protobuf/gpb/code/com/prismtech/dds/protobuf/backend/ospl/OsplIsocppIdlpp.java b/src/tools/protobuf/gpb/code/com/prismtech/dds/protobuf/backend/ospl/OsplIsocppIdlpp.java index d560ecc5e..2a7700863 100644 --- a/src/tools/protobuf/gpb/code/com/prismtech/dds/protobuf/backend/ospl/OsplIsocppIdlpp.java +++ b/src/tools/protobuf/gpb/code/com/prismtech/dds/protobuf/backend/ospl/OsplIsocppIdlpp.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/protobuf/gpb/code/com/prismtech/dds/protobuf/backend/ospl/OsplJava5CodeGenerator.java b/src/tools/protobuf/gpb/code/com/prismtech/dds/protobuf/backend/ospl/OsplJava5CodeGenerator.java index be7d08d41..061e320ad 100644 --- a/src/tools/protobuf/gpb/code/com/prismtech/dds/protobuf/backend/ospl/OsplJava5CodeGenerator.java +++ b/src/tools/protobuf/gpb/code/com/prismtech/dds/protobuf/backend/ospl/OsplJava5CodeGenerator.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/protobuf/gpb/code/com/prismtech/dds/protobuf/backend/ospl/OsplJavaIdlpp.java b/src/tools/protobuf/gpb/code/com/prismtech/dds/protobuf/backend/ospl/OsplJavaIdlpp.java index 996a8037d..11ca263f9 100644 --- a/src/tools/protobuf/gpb/code/com/prismtech/dds/protobuf/backend/ospl/OsplJavaIdlpp.java +++ b/src/tools/protobuf/gpb/code/com/prismtech/dds/protobuf/backend/ospl/OsplJavaIdlpp.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/protobuf/gpb/code/com/prismtech/dds/protobuf/frontend/MetaField.java b/src/tools/protobuf/gpb/code/com/prismtech/dds/protobuf/frontend/MetaField.java index 2b9b248ab..7566859b1 100644 --- a/src/tools/protobuf/gpb/code/com/prismtech/dds/protobuf/frontend/MetaField.java +++ b/src/tools/protobuf/gpb/code/com/prismtech/dds/protobuf/frontend/MetaField.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/protobuf/gpb/code/com/prismtech/dds/protobuf/frontend/MetaFile.java b/src/tools/protobuf/gpb/code/com/prismtech/dds/protobuf/frontend/MetaFile.java index 67d6a5da5..902279780 100644 --- a/src/tools/protobuf/gpb/code/com/prismtech/dds/protobuf/frontend/MetaFile.java +++ b/src/tools/protobuf/gpb/code/com/prismtech/dds/protobuf/frontend/MetaFile.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/protobuf/gpb/code/com/prismtech/dds/protobuf/frontend/MetaMessage.java b/src/tools/protobuf/gpb/code/com/prismtech/dds/protobuf/frontend/MetaMessage.java index bf3cc648b..3c3fd5b8c 100644 --- a/src/tools/protobuf/gpb/code/com/prismtech/dds/protobuf/frontend/MetaMessage.java +++ b/src/tools/protobuf/gpb/code/com/prismtech/dds/protobuf/frontend/MetaMessage.java @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -66,10 +67,10 @@ public MetaMessage(MetaFile file, MetaMessage parent, * Type names need to start with a dot to indicate absolute * scope. The scope is assumed relative to the scope of the * message otherwise. - * + * * Names have to start with a through z or A through Z, followed * by a word character [a-zA-Z_0-9]. - * + * * Examples: are "MyType", ".MyType", ".some.scope2.MyType", * "scope.MyType4" */ @@ -83,7 +84,7 @@ public MetaMessage(MetaFile file, MetaMessage parent, this.setupDDSFields(this.file.getProtoFile(), message, new ArrayList(), - new HashMap()); + new HashMap(),null); } else { this.ddsMessageOptions = null; } @@ -91,14 +92,15 @@ public MetaMessage(MetaFile file, MetaMessage parent, private void setupDDSFields(FileDescriptorProto protoFile, DescriptorProto message, List scope, - HashMap fieldNames) + HashMap fieldNames, FieldDescriptorProto dfproto) throws InvalidProtocolBufferException, ProtoParseException { - Logger.getInstance().log( - "Message '" + message.getName() + "' already in cache.\n", - Level.FINEST); - - if (this.descriptorCache.contains(message)) { + if (this.descriptorCache.contains(message) && dfproto != null && dfproto.getLabel() != + com.google.protobuf.DescriptorProtos.FieldDescriptorProto.Label.LABEL_REQUIRED) { + /* only add required messages for a second time as they might contain key fields*/ + Logger.getInstance().log( + "Message '" + message.getName() + "' already in cache.\n", + Level.FINEST); return; } Logger.getInstance().log( @@ -114,6 +116,9 @@ private void setupDDSFields(FileDescriptorProto protoFile, for (FieldDescriptorProto field : fieldList) { Field ddsFieldOption = field.getOptions().getUnknownFields() .getField(DescriptorProtos.MEMBER_FIELD_NUMBER); + Logger.getInstance().log( + "Adding field '" + message.getName() + " " + field.getLabel() +"' to cache.\n", + Level.FINEST); if (ddsFieldOption.getLengthDelimitedList().size() != 0) { MetaField mf = new MetaField(scope, protoFile, message, field, @@ -121,7 +126,6 @@ private void setupDDSFields(FileDescriptorProto protoFile, this.ddsFields.add(mf); MetaField existing = fieldNames.put(mf.getDDSName(), mf); - Logger.getInstance().log( "- DDS name: '" + mf.getDDSName() + "': ", Level.FINER); @@ -154,7 +158,7 @@ private void setupDDSFields(FileDescriptorProto protoFile, + field.getName() + "'."); } this.setupDDSFields(messageType.getFile(), - messageType.getMessage(), scope, fieldNames); + messageType.getMessage(), scope, fieldNames,field); scope.remove(s); } } diff --git a/src/tools/protobuf/gpb/templates/ISOCPP2/ProtoTopicTraits.hpp b/src/tools/protobuf/gpb/templates/ISOCPP2/ProtoTopicTraits.hpp index a08c5cdd5..6b126f782 100644 --- a/src/tools/protobuf/gpb/templates/ISOCPP2/ProtoTopicTraits.hpp +++ b/src/tools/protobuf/gpb/templates/ISOCPP2/ProtoTopicTraits.hpp @@ -1,7 +1,7 @@ namespace org { namespace opensplice { namespace topic { -typedef v_copyin_result (*copyInFunction)(c_base base, const void *, void *); +typedef v_copyin_result (*copyInFunction)(c_type dbType, const void *, void *); typedef void (*copyOutFunction)(const void *, void *); template<> @@ -81,7 +81,7 @@ class TopicTraits< ${proto-type-name} > { return; } - static v_copyin_result protoCopyIn(c_base base, const void *from, void *to) + static v_copyin_result protoCopyIn(c_type dbType, const void *from, void *to) { ${dds-type-name} dds; v_copyin_result result = V_COPYIN_RESULT_INVALID; @@ -89,7 +89,7 @@ class TopicTraits< ${proto-type-name} > { copyInFunction copyIn = ::org::opensplice::topic::TopicTraits< ${dds-type-name} >::getCopyIn(); if(protobufToDds((const ${proto-type-name}*)from, &dds)){ - result = copyIn(base, &dds , to); + result = copyIn(dbType, &dds , to); } return result; } diff --git a/src/tools/shmdump/code/shmdump.c b/src/tools/shmdump/code/shmdump.c index c18fa6a24..bff140dc5 100644 --- a/src/tools/shmdump/code/shmdump.c +++ b/src/tools/shmdump/code/shmdump.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/tools/topmon/code/topmon.c b/src/tools/topmon/code/topmon.c new file mode 100644 index 000000000..e8850c433 --- /dev/null +++ b/src/tools/topmon/code/topmon.c @@ -0,0 +1,1215 @@ + + +#include +#include + +#include "os_stdlib.h" +#include "os_process.h" +#include "os_thread.h" + +#include +#include + +#include "dds_dcps.h" +#include "dds_dcps_private.h" + +typedef struct config { + DDS_DomainParticipant participant; + DDS_Subscriber builtin_subscriber; + DDS_Subscriber subscriber; + DDS_Publisher publisher; + DDS_WaitSet waitset; + FILE *logfile; + char *partition; +} *topmon_config; + +typedef struct logger { + topmon_config config; + char *topic_name; + DDS_DataReader builtin_reader; + DDS_StatusCondition builtin_status_condition; + DDS_DataWriter topmon_writer; + DDS_DataReader topmon_reader; + DDS_StatusCondition topmon_status_condition; +} *topmon_logger; + +static DDS_DomainParticipantFactory factory = NULL; +static DDS_DomainParticipant dp = NULL; + +static topmon_logger DCPSParticipant_logger = NULL; +static topmon_logger DCPSTopic_logger = NULL; +static topmon_logger DCPSPublication_logger = NULL; +static topmon_logger DCPSSubscription_logger = NULL; +static topmon_logger CMPublisher_logger = NULL; +static topmon_logger CMSubscriber_logger = NULL; +static topmon_logger CMDataWriter_logger = NULL; +static topmon_logger CMDataReader_logger = NULL; +static topmon_logger CMParticipant_logger = NULL; +static topmon_logger DCPSType_logger = NULL; + +static DDS_ConditionSeq *cs = NULL; + +#if 0 +static topmon_participantDataWriter wrtTm = NULL; +static topmon_participantDataReader rdrTm = NULL; +#endif + +typedef struct _publicationInfo *publicationInfo; +struct _publicationInfo { + DDS_BuiltinTopicKey_t key; + DDS_PublicationBuiltinTopicData data; + DDS_CMDataWriterBuiltinTopicData cmdata; + publicationInfo next; +}; + +const char * +instanceState_image( + DDS_SampleInfo *info) +{ + if (info->view_state == DDS_NEW_VIEW_STATE) { + switch (info->instance_state) { + case DDS_ALIVE_INSTANCE_STATE: return "NEW"; + case DDS_NOT_ALIVE_DISPOSED_INSTANCE_STATE: return "NEW DISPOSED"; + case DDS_NOT_ALIVE_NO_WRITERS_INSTANCE_STATE: return "NEW NOT ALIVE"; + default : return "INVALID STATE"; + } + } else { + switch (info->instance_state) { + case DDS_ALIVE_INSTANCE_STATE: return "UPDATE"; + case DDS_NOT_ALIVE_DISPOSED_INSTANCE_STATE: return "DISPOSED"; + case DDS_NOT_ALIVE_NO_WRITERS_INSTANCE_STATE: return "NOT ALIVE"; + default : return "INVALID STATE"; + } + } +} + +const char * +DDS_DurabilityQosPolicyKind_image( + DDS_DurabilityQosPolicyKind kind) +{ + switch (kind) { + case DDS_VOLATILE_DURABILITY_QOS: return "VOLATILE"; + case DDS_TRANSIENT_LOCAL_DURABILITY_QOS: return "TRANSIENT_LOCAL"; + case DDS_TRANSIENT_DURABILITY_QOS: return "TRANSIENT"; + case DDS_PERSISTENT_DURABILITY_QOS: return "PERSISTENT"; + } + return NULL; +} + +const char * +DDS_ReliabilityQosPolicyKind_image( + DDS_ReliabilityQosPolicyKind kind) +{ + switch (kind) { + case DDS_BEST_EFFORT_RELIABILITY_QOS: return "BESTEFFORT"; + case DDS_RELIABLE_RELIABILITY_QOS: return "RELIABLE"; + } + return NULL; +} + +const char * +DDS_HistoryQosPolicyKind_image( + DDS_HistoryQosPolicyKind kind) +{ + switch (kind) { + case DDS_KEEP_LAST_HISTORY_QOS: return "KEEPLAST"; + case DDS_KEEP_ALL_HISTORY_QOS: return "KEEPALL"; + } + return NULL; +} + +const char * +DDS_DestinationOrderQosPolicyKind_image( + DDS_DestinationOrderQosPolicyKind kind) +{ + switch (kind) { + case DDS_BY_RECEPTION_TIMESTAMP_DESTINATIONORDER_QOS: return "BY_RECEPTION"; + case DDS_BY_SOURCE_TIMESTAMP_DESTINATIONORDER_QOS: return "BY_SOURCE"; + } + return NULL; +} + +const char * +DDS_OwnershipQosPolicyKind_image( + DDS_OwnershipQosPolicyKind kind) +{ + switch (kind) { + case DDS_SHARED_OWNERSHIP_QOS: return "SHARED"; + case DDS_EXCLUSIVE_OWNERSHIP_QOS: return "EXCLUSIVE"; + } + return NULL; +} + +char * +DDS_PartitionQosPolicy_image( + DDS_PartitionQosPolicy partitions) +{ + unsigned int i, len; + char *image; + + len = 0; + for (i=0; i 0) { + image = os_malloc(len); + len = sprintf(image,"%s",partitions.name._buffer[0]); + for (i=1; iconfig->logfile, + "%llu %s Participant id[%d,%d,%d] time[%u,%u]\n", + (info->publication_handle << 32), + instanceState_image(info), + data->key[0], data->key[1], data->key[2], + info->source_timestamp.sec, info->source_timestamp.nanosec); +} + +static void +logTopic( + DDS_TopicBuiltinTopicData *data, + DDS_SampleInfo *info) +{ + /* + * struct DDS_TopicBuiltinTopicData { + * DDS_BuiltinTopicKey_t key; + * DDS_string name; + * DDS_string type_name; + * DDS_DurabilityQosPolicy durability; + * DDS_DurabilityServiceQosPolicy durability_service; + * DDS_DeadlineQosPolicy deadline; + * DDS_LatencyBudgetQosPolicy latency_budget; + * DDS_LivelinessQosPolicy liveliness; + * DDS_ReliabilityQosPolicy reliability; + * DDS_TransportPriorityQosPolicy transport_priority; + * DDS_LifespanQosPolicy lifespan; + * DDS_DestinationOrderQosPolicy destination_order; + * DDS_HistoryQosPolicy history; + * DDS_ResourceLimitsQosPolicy resource_limits; + * DDS_OwnershipQosPolicy ownership; + * DDS_TopicDataQosPolicy topic_data; + * }; + */ + fprintf(DCPSTopic_logger->config->logfile, + "%llu %s Topic id[%u,%u,%u] time[%u,%u] name[%s] type[%s] policies[%s,%s,%s,%s,%s] limits[%d,%d,%d]\n", + (info->publication_handle << 32), + instanceState_image(info), + data->key[0], data->key[1], data->key[2], + info->source_timestamp.sec, info->source_timestamp.nanosec, + data->name, data->type_name, + DDS_DurabilityQosPolicyKind_image(data->durability.kind), + DDS_ReliabilityQosPolicyKind_image(data->reliability.kind), + DDS_HistoryQosPolicyKind_image(data->history.kind), + DDS_DestinationOrderQosPolicyKind_image(data->destination_order.kind), + DDS_OwnershipQosPolicyKind_image(data->ownership.kind), + data->resource_limits.max_samples, data->resource_limits.max_instances, data->resource_limits.max_samples_per_instance); +} + +static os_boolean +processParticipant( + DDS_StatusCondition condition) +{ + DDS_ParticipantBuiltinTopicDataDataReader reader = NULL; + DDS_sequence_DDS_ParticipantBuiltinTopicData *dataList = NULL; + DDS_sequence_DDS_SampleInfo *infoList = NULL; + DDS_ParticipantBuiltinTopicData *data; + DDS_SampleInfo *info; + DDS_ReturnCode_t result; + + dataList = DDS_sequence_DDS_ParticipantBuiltinTopicData__alloc(); + infoList = DDS_sequence_DDS_SampleInfo__alloc(); + + if (condition == DCPSParticipant_logger->builtin_status_condition) { + reader = DCPSParticipant_logger->builtin_reader; + } else if (condition == DCPSParticipant_logger->topmon_status_condition) { + reader = DCPSParticipant_logger->topmon_reader; + } else { + return OS_FALSE; + } + result = DDS_ParticipantBuiltinTopicDataDataReader_take( + reader, dataList, infoList, + DDS_LENGTH_UNLIMITED, + DDS_ANY_SAMPLE_STATE, + DDS_ANY_VIEW_STATE, + DDS_ANY_INSTANCE_STATE); + + if ( result == DDS_RETCODE_OK ) { + unsigned int i; + for (i=0; i_length; i++) { + data = &(dataList->_buffer[i]); + info = &(infoList->_buffer[i]); + if (reader == DCPSParticipant_logger->builtin_reader && DCPSParticipant_logger->config->publisher) { + switch (info->instance_state) { + case DDS_ALIVE_INSTANCE_STATE: + DDS_ParticipantBuiltinTopicDataDataWriter_write(DCPSParticipant_logger->topmon_writer, data, NULL); + break; + case DDS_NOT_ALIVE_DISPOSED_INSTANCE_STATE: + DDS_ParticipantBuiltinTopicDataDataWriter_dispose(DCPSParticipant_logger->topmon_writer, data, NULL); + break; + case DDS_NOT_ALIVE_NO_WRITERS_INSTANCE_STATE: + DDS_ParticipantBuiltinTopicDataDataWriter_unregister_instance(DCPSParticipant_logger->topmon_writer, data, NULL); + break; + } + } else { + logParticipant(data, info); +#if 0 + /* + * struct DDS_ParticipantBuiltinTopicData { + * DDS_BuiltinTopicKey_t key; + * DDS_UserDataQosPolicy user_data; + * }; + * struct DDS_UserDataQosPolicy { + * DDS_octSeq value; + * }; + */ + fprintf(DCPSParticipant_logger->config->logfile, + "%llu %s Participant id[%d,%d,%d] time[%u,%u]\n", + (info->publication_handle << 32), + instanceState_image(info), + data->key[0], data->key[1], data->key[2], + info->source_timestamp.sec, info->source_timestamp.nanosec); +#endif + } + } + DDS_ParticipantBuiltinTopicDataDataReader_return_loan(DCPSParticipant_logger->builtin_reader, + dataList, infoList); + } + DDS_free(dataList); + DDS_free(infoList); + return OS_TRUE; +} + +static os_boolean +processTopic( + DDS_StatusCondition condition) +{ + DDS_TopicBuiltinTopicDataDataReader reader = NULL; + DDS_sequence_DDS_TopicBuiltinTopicData *dataList = NULL; + DDS_sequence_DDS_SampleInfo *infoList = NULL; + DDS_TopicBuiltinTopicData *data; + DDS_SampleInfo *info; + DDS_ReturnCode_t result; + + dataList = DDS_sequence_DDS_TopicBuiltinTopicData__alloc(); + infoList = DDS_sequence_DDS_SampleInfo__alloc(); + + if (condition == DCPSTopic_logger->builtin_status_condition) { + reader = DCPSTopic_logger->builtin_reader; + } else if (condition == DCPSTopic_logger->topmon_status_condition) { + reader = DCPSTopic_logger->topmon_reader; + } else { + return OS_FALSE; + } + result = DDS_TopicBuiltinTopicDataDataReader_take( + reader, dataList, infoList, + DDS_LENGTH_UNLIMITED, + DDS_ANY_SAMPLE_STATE, + DDS_ANY_VIEW_STATE, + DDS_ANY_INSTANCE_STATE); + + if ( result == DDS_RETCODE_OK ) { + unsigned int i; + for (i=0; i_length; i++) { + data = &(dataList->_buffer[i]); + info = &(infoList->_buffer[i]); + if (reader == DCPSTopic_logger->builtin_reader && DCPSTopic_logger->config->publisher) { + switch (info->instance_state) { + case DDS_ALIVE_INSTANCE_STATE: + DDS_TopicBuiltinTopicDataDataWriter_write(DCPSTopic_logger->topmon_writer, data, NULL); + break; + case DDS_NOT_ALIVE_DISPOSED_INSTANCE_STATE: + DDS_TopicBuiltinTopicDataDataWriter_dispose(DCPSTopic_logger->topmon_writer, data, NULL); + break; + case DDS_NOT_ALIVE_NO_WRITERS_INSTANCE_STATE: + DDS_TopicBuiltinTopicDataDataWriter_unregister_instance(DCPSTopic_logger->topmon_writer, data, NULL); + break; + } + } else { + logTopic(data, info); +#if 0 + /* + * struct DDS_TopicBuiltinTopicData { + * DDS_BuiltinTopicKey_t key; + * DDS_string name; + * DDS_string type_name; + * DDS_DurabilityQosPolicy durability; + * DDS_DurabilityServiceQosPolicy durability_service; + * DDS_DeadlineQosPolicy deadline; + * DDS_LatencyBudgetQosPolicy latency_budget; + * DDS_LivelinessQosPolicy liveliness; + * DDS_ReliabilityQosPolicy reliability; + * DDS_TransportPriorityQosPolicy transport_priority; + * DDS_LifespanQosPolicy lifespan; + * DDS_DestinationOrderQosPolicy destination_order; + * DDS_HistoryQosPolicy history; + * DDS_ResourceLimitsQosPolicy resource_limits; + * DDS_OwnershipQosPolicy ownership; + * DDS_TopicDataQosPolicy topic_data; + * }; + */ + fprintf(DCPSTopic_logger->config->logfile, + "%llu %s Topic id[%u,%u,%u] time[%u,%u] name[%s] type[%s] policies[%s,%s,%s,%s,%s] limits[%d,%d,%d]\n", + (info->publication_handle << 32), + instanceState_image(info), + data->key[0], data->key[1], data->key[2], + info->source_timestamp.sec, info->source_timestamp.nanosec, + data->name, data->type_name, + DDS_DurabilityQosPolicyKind_image(data->durability.kind), + DDS_ReliabilityQosPolicyKind_image(data->reliability.kind), + DDS_HistoryQosPolicyKind_image(data->history.kind), + DDS_DestinationOrderQosPolicyKind_image(data->destination_order.kind), + DDS_OwnershipQosPolicyKind_image(data->ownership.kind), + data->resource_limits.max_samples, data->resource_limits.max_instances, data->resource_limits.max_samples_per_instance); +#endif + } + } + DDS_TopicBuiltinTopicDataDataReader_return_loan(DCPSTopic_logger->builtin_reader, dataList, infoList); + } + DDS_free(dataList); + DDS_free(infoList); + return OS_TRUE; +} + +static os_boolean +processPublication( + DDS_StatusCondition condition) +{ + DDS_PublicationBuiltinTopicDataDataReader reader = NULL; + DDS_sequence_DDS_PublicationBuiltinTopicData *dataList = NULL; + DDS_sequence_DDS_SampleInfo *infoList = NULL; + DDS_PublicationBuiltinTopicData *data; + DDS_SampleInfo *info; + DDS_ReturnCode_t result; + + dataList = DDS_sequence_DDS_PublicationBuiltinTopicData__alloc(); + infoList = DDS_sequence_DDS_SampleInfo__alloc(); + + if (condition == DCPSPublication_logger->builtin_status_condition) { + reader = DCPSPublication_logger->builtin_reader; + } else if (condition == DCPSPublication_logger->topmon_status_condition) { + reader = DCPSPublication_logger->topmon_reader; + } else { + return OS_FALSE; + } + result = DDS_PublicationBuiltinTopicDataDataReader_take( + reader, dataList, infoList, + DDS_LENGTH_UNLIMITED, + DDS_ANY_SAMPLE_STATE, + DDS_ANY_VIEW_STATE, + DDS_ANY_INSTANCE_STATE); + + if ( result == DDS_RETCODE_OK ) { + unsigned int i; + for (i=0; i_length; i++) { + data = &(dataList->_buffer[i]); + info = &(infoList->_buffer[i]); + if (reader == DCPSPublication_logger->builtin_reader && DCPSPublication_logger->config->publisher) { + switch (info->instance_state) { + case DDS_ALIVE_INSTANCE_STATE: + DDS_PublicationBuiltinTopicDataDataWriter_write(DCPSPublication_logger->topmon_writer, data, NULL); + break; + case DDS_NOT_ALIVE_DISPOSED_INSTANCE_STATE: + DDS_PublicationBuiltinTopicDataDataWriter_dispose(DCPSPublication_logger->topmon_writer, data, NULL); + break; + case DDS_NOT_ALIVE_NO_WRITERS_INSTANCE_STATE: + DDS_PublicationBuiltinTopicDataDataWriter_unregister_instance(DCPSPublication_logger->topmon_writer, data, NULL); + break; + } + } else { + char *partition = NULL; + /* + * struct DDS_PublicationBuiltinTopicData { + * DDS_BuiltinTopicKey_t key; + * DDS_BuiltinTopicKey_t participant_key; + * DDS_string topic_name; + * DDS_string type_name; + * DDS_DurabilityQosPolicy durability; + * DDS_DeadlineQosPolicy deadline; + * DDS_LatencyBudgetQosPolicy latency_budget; + * DDS_LivelinessQosPolicy liveliness; + * DDS_ReliabilityQosPolicy reliability; + * DDS_LifespanQosPolicy lifespan; + * DDS_DestinationOrderQosPolicy destination_order; + * DDS_UserDataQosPolicy user_data; + * DDS_OwnershipQosPolicy ownership; + * DDS_OwnershipStrengthQosPolicy ownership_strength; + * DDS_PresentationQosPolicy presentation; + * DDS_PartitionQosPolicy partition; + * DDS_TopicDataQosPolicy topic_data; + * DDS_GroupDataQosPolicy group_data; + * }; + */ + partition = DDS_PartitionQosPolicy_image(data->partition); + fprintf(DCPSPublication_logger->config->logfile, + "%llu %s DataWriter id[%d,%d,%d] time[%u,%u] topic[%s] partition[%s] policies[%s,%s,%s,%s]\n", + (info->publication_handle << 32), + instanceState_image(info), + data->key[0], data->key[1], data->key[2], + info->source_timestamp.sec, info->source_timestamp.nanosec, + data->topic_name, + partition, + DDS_DurabilityQosPolicyKind_image(data->durability.kind), + DDS_ReliabilityQosPolicyKind_image(data->reliability.kind), + DDS_DestinationOrderQosPolicyKind_image(data->destination_order.kind), + DDS_OwnershipQosPolicyKind_image(data->ownership.kind)); + os_free(partition); + } + } + DDS_PublicationBuiltinTopicDataDataReader_return_loan(DCPSPublication_logger->builtin_reader, dataList, infoList); + } + DDS_free(dataList); + DDS_free(infoList); + return OS_TRUE; +} + +static os_boolean +processSubscription( + DDS_StatusCondition condition) +{ + DDS_SubscriptionBuiltinTopicDataDataReader reader = NULL; + DDS_sequence_DDS_SubscriptionBuiltinTopicData *dataList = NULL; + DDS_sequence_DDS_SampleInfo *infoList = NULL; + DDS_SubscriptionBuiltinTopicData *data; + DDS_SampleInfo *info; + DDS_ReturnCode_t result; + + dataList = DDS_sequence_DDS_SubscriptionBuiltinTopicData__alloc(); + infoList = DDS_sequence_DDS_SampleInfo__alloc(); + + if (condition == DCPSSubscription_logger->builtin_status_condition) { + reader = DCPSSubscription_logger->builtin_reader; + } else if (condition == DCPSSubscription_logger->topmon_status_condition) { + reader = DCPSSubscription_logger->topmon_reader; + } else { + return OS_FALSE; + } + result = DDS_SubscriptionBuiltinTopicDataDataReader_take( + reader, dataList, infoList, + DDS_LENGTH_UNLIMITED, + DDS_ANY_SAMPLE_STATE, + DDS_ANY_VIEW_STATE, + DDS_ANY_INSTANCE_STATE); + + if ( result == DDS_RETCODE_OK ) { + unsigned int i; + for (i=0; i_length; i++) { + data = &(dataList->_buffer[i]); + info = &(infoList->_buffer[i]); + if (reader == DCPSSubscription_logger->builtin_reader && DCPSSubscription_logger->config->publisher) { + switch (info->instance_state) { + case DDS_ALIVE_INSTANCE_STATE: + DDS_SubscriptionBuiltinTopicDataDataWriter_write(DCPSSubscription_logger->topmon_writer, data, NULL); + break; + case DDS_NOT_ALIVE_DISPOSED_INSTANCE_STATE: + DDS_SubscriptionBuiltinTopicDataDataWriter_dispose(DCPSSubscription_logger->topmon_writer, data, NULL); + break; + case DDS_NOT_ALIVE_NO_WRITERS_INSTANCE_STATE: + DDS_SubscriptionBuiltinTopicDataDataWriter_unregister_instance(DCPSSubscription_logger->topmon_writer, data, NULL); + break; + } + } else { + char *partition = NULL; + /* + * struct DDS_SubscriptionBuiltinTopicData { + * DDS_BuiltinTopicKey_t key; + * DDS_BuiltinTopicKey_t participant_key; + * DDS_string topic_name; + * DDS_string type_name; + * DDS_DurabilityQosPolicy durability; + * DDS_DeadlineQosPolicy deadline; + * DDS_LatencyBudgetQosPolicy latency_budget; + * DDS_LivelinessQosPolicy liveliness; + * DDS_ReliabilityQosPolicy reliability; + * DDS_OwnershipQosPolicy ownership; + * DDS_DestinationOrderQosPolicy destination_order; + * DDS_UserDataQosPolicy user_data; + * DDS_TimeBasedFilterQosPolicy time_based_filter; + * DDS_PresentationQosPolicy presentation; + * DDS_PartitionQosPolicy partition; + * DDS_TopicDataQosPolicy topic_data; + * DDS_GroupDataQosPolicy group_data; + * }; + */ + partition = DDS_PartitionQosPolicy_image(data->partition); + fprintf(DCPSSubscription_logger->config->logfile, + "%llu %s DataReader id[%d,%d,%d] time[%u,%u] participant[%d,%d,%d] topic[%s] partition[%s] policies[%s,%s,%s,%s]\n", + (info->publication_handle << 32), + instanceState_image(info), + data->key[0], data->key[1], data->key[2], + info->source_timestamp.sec, info->source_timestamp.nanosec, + data->participant_key[0], data->participant_key[1], data->participant_key[2], + data->topic_name, + partition, + DDS_DurabilityQosPolicyKind_image(data->durability.kind), + DDS_ReliabilityQosPolicyKind_image(data->reliability.kind), + DDS_DestinationOrderQosPolicyKind_image(data->destination_order.kind), + DDS_OwnershipQosPolicyKind_image(data->ownership.kind)); + os_free(partition); + } + } + DDS_SubscriptionBuiltinTopicDataDataReader_return_loan(DCPSSubscription_logger->builtin_reader, dataList, infoList); + } + DDS_free(dataList); + DDS_free(infoList); + return OS_TRUE; +} + +static os_boolean +processCmPublisher( + DDS_StatusCondition condition) +{ + DDS_CMPublisherBuiltinTopicDataDataReader reader = NULL; + DDS_sequence_DDS_CMPublisherBuiltinTopicData *dataList = NULL; + DDS_sequence_DDS_SampleInfo *infoList = NULL; + DDS_CMPublisherBuiltinTopicData *data; + DDS_SampleInfo *info; + DDS_ReturnCode_t result; + + dataList = DDS_sequence_DDS_CMPublisherBuiltinTopicData__alloc(); + infoList = DDS_sequence_DDS_SampleInfo__alloc(); + + if (condition == CMPublisher_logger->builtin_status_condition) { + reader = CMPublisher_logger->builtin_reader; + } else if (condition == CMPublisher_logger->topmon_status_condition) { + reader = CMPublisher_logger->topmon_reader; + } else { + return OS_FALSE; + } + result = DDS_CMPublisherBuiltinTopicDataDataReader_take( + reader, dataList, infoList, + DDS_LENGTH_UNLIMITED, + DDS_ANY_SAMPLE_STATE, + DDS_ANY_VIEW_STATE, + DDS_ANY_INSTANCE_STATE); + + /* + * struct DDS_CMPublisherBuiltinTopicData { + * DDS_BuiltinTopicKey_t key; + * DDS_ProductDataQosPolicy product; + * DDS_BuiltinTopicKey_t participant_key; + * DDS_string name; + * DDS_EntityFactoryQosPolicy entity_factory; + * DDS_PartitionQosPolicy partition; + * }; + */ + if ( result == DDS_RETCODE_OK ) { + unsigned int i; + for (i=0; i_length; i++) { + data = &(dataList->_buffer[i]); + info = &(infoList->_buffer[i]); + if (reader == CMPublisher_logger->builtin_reader && CMPublisher_logger->config->publisher) { + switch (info->instance_state) { + case DDS_ALIVE_INSTANCE_STATE: + DDS_CMPublisherBuiltinTopicDataDataWriter_write(CMPublisher_logger->topmon_writer, data, NULL); + break; + case DDS_NOT_ALIVE_DISPOSED_INSTANCE_STATE: + DDS_CMPublisherBuiltinTopicDataDataWriter_dispose(CMPublisher_logger->topmon_writer, data, NULL); + break; + case DDS_NOT_ALIVE_NO_WRITERS_INSTANCE_STATE: + DDS_CMPublisherBuiltinTopicDataDataWriter_unregister_instance(CMPublisher_logger->topmon_writer, data, NULL); + break; + } + } else { + fprintf(CMPublisher_logger->config->logfile, + "%llu %s Publisher id[%u,%u,%u] time[%u,%u] name[%s] product[%s]\n", + (info->publication_handle << 32), + instanceState_image(info), + data->key[0], data->key[1], data->key[2], + info->source_timestamp.sec, info->source_timestamp.nanosec, + data->name, + data->product.value ? data->product.value : ""); + } + } + DDS_CMPublisherBuiltinTopicDataDataReader_return_loan(CMPublisher_logger->builtin_reader, dataList, infoList); + } + DDS_free(dataList); + DDS_free(infoList); + return OS_TRUE; +} + +static os_boolean +processCmSubscriber( + DDS_StatusCondition condition) +{ + DDS_CMSubscriberBuiltinTopicDataDataReader reader = NULL; + DDS_sequence_DDS_CMSubscriberBuiltinTopicData *dataList = NULL; + DDS_sequence_DDS_SampleInfo *infoList = NULL; + DDS_CMSubscriberBuiltinTopicData *data; + DDS_SampleInfo *info; + DDS_ReturnCode_t result; + + dataList = DDS_sequence_DDS_CMSubscriberBuiltinTopicData__alloc(); + infoList = DDS_sequence_DDS_SampleInfo__alloc(); + + if (condition == CMSubscriber_logger->builtin_status_condition) { + reader = CMSubscriber_logger->builtin_reader; + } else if (condition == CMSubscriber_logger->topmon_status_condition) { + reader = CMSubscriber_logger->topmon_reader; + } else { + return OS_FALSE; + } + result = DDS_CMSubscriberBuiltinTopicDataDataReader_take( + reader, dataList, infoList, + DDS_LENGTH_UNLIMITED, + DDS_ANY_SAMPLE_STATE, + DDS_ANY_VIEW_STATE, + DDS_ANY_INSTANCE_STATE); + + if ( result == DDS_RETCODE_OK ) { + unsigned int i; + for (i=0; i_length; i++) { + data = &(dataList->_buffer[i]); + info = &(infoList->_buffer[i]); + if (reader == CMSubscriber_logger->builtin_reader && CMSubscriber_logger->config->publisher) { + switch (info->instance_state) { + case DDS_ALIVE_INSTANCE_STATE: + DDS_CMSubscriberBuiltinTopicDataDataWriter_write(CMSubscriber_logger->topmon_writer, data, NULL); + break; + case DDS_NOT_ALIVE_DISPOSED_INSTANCE_STATE: + DDS_CMSubscriberBuiltinTopicDataDataWriter_dispose(CMSubscriber_logger->topmon_writer, data, NULL); + break; + case DDS_NOT_ALIVE_NO_WRITERS_INSTANCE_STATE: + DDS_CMSubscriberBuiltinTopicDataDataWriter_unregister_instance(CMSubscriber_logger->topmon_writer, data, NULL); + break; + } + } else { + /* + * struct DDS_CMSubscriberBuiltinTopicData { + * DDS_BuiltinTopicKey_t key; + * DDS_ProductDataQosPolicy product; + * DDS_BuiltinTopicKey_t participant_key; + * DDS_string name; + * DDS_EntityFactoryQosPolicy entity_factory; + * DDS_ShareQosPolicy share; + * DDS_PartitionQosPolicy partition; + * }; + */ + fprintf(CMSubscriber_logger->config->logfile, + "%llu %s Subscriber id[%u,%u,%u] time[%u,%u] name[%s] product[%s]\n", + (info->publication_handle << 32), + instanceState_image(info), + data->key[0], data->key[1], data->key[2], + info->source_timestamp.sec, info->source_timestamp.nanosec, + data->name, + data->product.value ? data->product.value : ""); + } + } + DDS_CMSubscriberBuiltinTopicDataDataReader_return_loan(CMSubscriber_logger->builtin_reader, dataList, infoList); + } + DDS_free(dataList); + DDS_free(infoList); + return OS_TRUE; +} + +static os_boolean +processCmWriter( + DDS_StatusCondition condition) +{ + DDS_CMDataWriterBuiltinTopicDataDataReader reader = NULL; + DDS_sequence_DDS_CMDataWriterBuiltinTopicData *dataList = NULL; + DDS_sequence_DDS_SampleInfo *infoList = NULL; + DDS_CMDataWriterBuiltinTopicData *data; + DDS_SampleInfo *info; + DDS_ReturnCode_t result; + + dataList = DDS_sequence_DDS_CMDataWriterBuiltinTopicData__alloc(); + infoList = DDS_sequence_DDS_SampleInfo__alloc(); + + if (condition == CMDataWriter_logger->builtin_status_condition) { + reader = CMDataWriter_logger->builtin_reader; + } else if (condition == CMDataWriter_logger->topmon_status_condition) { + reader = CMDataWriter_logger->topmon_reader; + } else { + return OS_FALSE; + } + result = DDS_CMDataWriterBuiltinTopicDataDataReader_take( + reader, dataList, infoList, + DDS_LENGTH_UNLIMITED, + DDS_ANY_SAMPLE_STATE, + DDS_ANY_VIEW_STATE, + DDS_ANY_INSTANCE_STATE); + + if ( result == DDS_RETCODE_OK ) { + unsigned int i; + for (i=0; i_length; i++) { + data = &(dataList->_buffer[i]); + info = &(infoList->_buffer[i]); + if (reader == CMDataWriter_logger->builtin_reader && CMDataWriter_logger->config->publisher) { + switch (info->instance_state) { + case DDS_ALIVE_INSTANCE_STATE: + DDS_CMDataWriterBuiltinTopicDataDataWriter_write(CMDataWriter_logger->topmon_writer, data, NULL); + break; + case DDS_NOT_ALIVE_DISPOSED_INSTANCE_STATE: + DDS_CMDataWriterBuiltinTopicDataDataWriter_dispose(CMDataWriter_logger->topmon_writer, data, NULL); + break; + case DDS_NOT_ALIVE_NO_WRITERS_INSTANCE_STATE: + DDS_CMDataWriterBuiltinTopicDataDataWriter_unregister_instance(CMDataWriter_logger->topmon_writer, data, NULL); + break; + } + } else { + /* + * struct DDS_CMDataWriterBuiltinTopicData { + * DDS_BuiltinTopicKey_t key; + * DDS_ProductDataQosPolicy product; + * DDS_BuiltinTopicKey_t publisher_key; + * DDS_string name; + * DDS_HistoryQosPolicy history; + * DDS_ResourceLimitsQosPolicy resource_limits; + * DDS_WriterDataLifecycleQosPolicy writer_data_lifecycle; + * }; + */ + fprintf(CMDataWriter_logger->config->logfile, + "%llu %s DataWriter id[%u,%u,%u] time[%u,%u] name[%s] policies[%s] product[%s] limits[%d,%d,%d]\n", + (info->publication_handle << 32), + instanceState_image(info), + data->key[0], data->key[1], data->key[2], + info->source_timestamp.sec, info->source_timestamp.nanosec, + data->name, + DDS_HistoryQosPolicyKind_image(data->history.kind), + data->product.value ? data->product.value : "", + data->resource_limits.max_samples, data->resource_limits.max_instances, data->resource_limits.max_samples_per_instance); + } + } + DDS_CMDataWriterBuiltinTopicDataDataReader_return_loan(CMDataWriter_logger->builtin_reader, dataList, infoList); + } + DDS_free(dataList); + DDS_free(infoList); + return OS_TRUE; +} + +static os_boolean +processCmReader( + DDS_StatusCondition condition) +{ + DDS_CMDataReaderBuiltinTopicDataDataReader reader = NULL; + DDS_sequence_DDS_CMDataReaderBuiltinTopicData *dataList = NULL; + DDS_sequence_DDS_SampleInfo *infoList = NULL; + DDS_CMDataReaderBuiltinTopicData *data; + DDS_SampleInfo *info; + DDS_ReturnCode_t result; + + dataList = DDS_sequence_DDS_CMDataReaderBuiltinTopicData__alloc(); + infoList = DDS_sequence_DDS_SampleInfo__alloc(); + + if (condition == CMDataReader_logger->builtin_status_condition) { + reader = CMDataReader_logger->builtin_reader; + } else if (condition == CMDataReader_logger->topmon_status_condition) { + reader = CMDataReader_logger->topmon_reader; + } else { + return OS_FALSE; + } + result = DDS_CMDataReaderBuiltinTopicDataDataReader_take( + reader, dataList, infoList, + DDS_LENGTH_UNLIMITED, + DDS_ANY_SAMPLE_STATE, + DDS_ANY_VIEW_STATE, + DDS_ANY_INSTANCE_STATE); + + if ( result == DDS_RETCODE_OK ) { + unsigned int i; + for (i=0; i_length; i++) { + data = &(dataList->_buffer[i]); + info = &(infoList->_buffer[i]); + if (reader == CMDataReader_logger->builtin_reader && CMDataReader_logger->config->publisher) { + switch (info->instance_state) { + case DDS_ALIVE_INSTANCE_STATE: + DDS_CMDataReaderBuiltinTopicDataDataWriter_write(CMDataReader_logger->topmon_writer, data, NULL); + break; + case DDS_NOT_ALIVE_DISPOSED_INSTANCE_STATE: + DDS_CMDataReaderBuiltinTopicDataDataWriter_dispose(CMDataReader_logger->topmon_writer, data, NULL); + break; + case DDS_NOT_ALIVE_NO_WRITERS_INSTANCE_STATE: + DDS_CMDataReaderBuiltinTopicDataDataWriter_unregister_instance(CMDataReader_logger->topmon_writer, data, NULL); + break; + } + } else { + /* + * struct DDS_CMDataReaderBuiltinTopicData { + * DDS_BuiltinTopicKey_t key; + * DDS_ProductDataQosPolicy product; + * DDS_BuiltinTopicKey_t subscriber_key; + * DDS_string name; + * DDS_HistoryQosPolicy history; + * DDS_ResourceLimitsQosPolicy resource_limits; + * DDS_ReaderDataLifecycleQosPolicy reader_data_lifecycle; + * DDS_UserKeyQosPolicy subscription_keys; + * DDS_ReaderLifespanQosPolicy reader_lifespan; + * DDS_ShareQosPolicy share; + * }; + */ + fprintf(CMDataReader_logger->config->logfile, + "%llu %s DataReader id[%u,%u,%u] time[%u,%u] name[%s] policies[%s] product[%s] limits[%d,%d,%d]\n", + (info->publication_handle << 32), + instanceState_image(info), + data->key[0], data->key[1], data->key[2], + info->source_timestamp.sec, info->source_timestamp.nanosec, + data->name, + DDS_HistoryQosPolicyKind_image(data->history.kind), + data->product.value ? data->product.value : "", + data->resource_limits.max_samples, data->resource_limits.max_instances, data->resource_limits.max_samples_per_instance); + } + } + DDS_CMDataReaderBuiltinTopicDataDataReader_return_loan(CMDataReader_logger->builtin_reader, dataList, infoList); + } + DDS_free(dataList); + DDS_free(infoList); + return OS_TRUE; +} + +static os_boolean +processCmParticipant( + DDS_StatusCondition condition) +{ + DDS_CMParticipantBuiltinTopicDataDataReader reader = NULL; + DDS_sequence_DDS_CMParticipantBuiltinTopicData *dataList = NULL; + DDS_sequence_DDS_SampleInfo *infoList = NULL; + DDS_CMParticipantBuiltinTopicData *data; + DDS_SampleInfo *info; + DDS_ReturnCode_t result; + + dataList = DDS_sequence_DDS_CMParticipantBuiltinTopicData__alloc(); + infoList = DDS_sequence_DDS_SampleInfo__alloc(); + + if (condition == CMParticipant_logger->builtin_status_condition) { + reader = CMParticipant_logger->builtin_reader; + } else if (condition == CMParticipant_logger->topmon_status_condition) { + reader = CMParticipant_logger->topmon_reader; + } else { + return OS_FALSE; + } + result = DDS_CMParticipantBuiltinTopicDataDataReader_take( + reader, dataList, infoList, + DDS_LENGTH_UNLIMITED, + DDS_ANY_SAMPLE_STATE, + DDS_ANY_VIEW_STATE, + DDS_ANY_INSTANCE_STATE); + + /* + * struct DDS_CMParticipantBuiltinTopicData { + * DDS_BuiltinTopicKey_t key; + * DDS_ProductDataQosPolicy product; + * }; + */ + if ( result == DDS_RETCODE_OK ) { + unsigned int i; + for (i=0; i_length; i++) { + data = &(dataList->_buffer[i]); + info = &(infoList->_buffer[i]); + if (reader == CMParticipant_logger->builtin_reader && CMParticipant_logger->config->publisher) { + switch (info->instance_state) { + case DDS_ALIVE_INSTANCE_STATE: + DDS_CMParticipantBuiltinTopicDataDataWriter_write(CMParticipant_logger->topmon_writer, data, NULL); + break; + case DDS_NOT_ALIVE_DISPOSED_INSTANCE_STATE: + DDS_CMParticipantBuiltinTopicDataDataWriter_dispose(CMParticipant_logger->topmon_writer, data, NULL); + break; + case DDS_NOT_ALIVE_NO_WRITERS_INSTANCE_STATE: + DDS_CMParticipantBuiltinTopicDataDataWriter_unregister_instance(CMParticipant_logger->topmon_writer, data, NULL); + break; + } + } else { + fprintf(CMParticipant_logger->config->logfile, + "%llu %s Participant id[%u,%u,%u] time[%u,%u] product[%s]\n", + (info->publication_handle << 32), + instanceState_image(info), + data->key[0], data->key[1], data->key[2], + info->source_timestamp.sec, info->source_timestamp.nanosec, + data->product.value ? data->product.value : ""); + } + } + DDS_CMParticipantBuiltinTopicDataDataReader_return_loan(CMParticipant_logger->builtin_reader, dataList, infoList); + } + DDS_free(dataList); + DDS_free(infoList); + return OS_TRUE; +} + +static os_boolean +processType( + DDS_StatusCondition condition) +{ + DDS_TypeBuiltinTopicDataDataReader reader = NULL; + DDS_sequence_DDS_TypeBuiltinTopicData *dataList = NULL; + DDS_sequence_DDS_SampleInfo *infoList = NULL; + DDS_TypeBuiltinTopicData *data; + DDS_SampleInfo *info; + DDS_ReturnCode_t result; + + dataList = DDS_sequence_DDS_TypeBuiltinTopicData__alloc(); + infoList = DDS_sequence_DDS_SampleInfo__alloc(); + + if (condition == DCPSType_logger->builtin_status_condition) { + reader = DCPSType_logger->builtin_reader; + } else if (condition == DCPSType_logger->topmon_status_condition) { + reader = DCPSType_logger->topmon_reader; + } else { + return OS_FALSE; + } + result = DDS_TypeBuiltinTopicDataDataReader_take( + reader, dataList, infoList, + DDS_LENGTH_UNLIMITED, + DDS_ANY_SAMPLE_STATE, + DDS_ANY_VIEW_STATE, + DDS_ANY_INSTANCE_STATE); + + if ( result == DDS_RETCODE_OK ) { + unsigned int i; + for (i=0; i_length; i++) { + data = &(dataList->_buffer[i]); + info = &(infoList->_buffer[i]); + if (reader == DCPSType_logger->builtin_reader && DCPSType_logger->config->publisher) { + switch (info->instance_state) { + case DDS_ALIVE_INSTANCE_STATE: + DDS_TypeBuiltinTopicDataDataWriter_write(DCPSType_logger->topmon_writer, data, NULL); + break; + case DDS_NOT_ALIVE_DISPOSED_INSTANCE_STATE: + DDS_TypeBuiltinTopicDataDataWriter_dispose(DCPSType_logger->topmon_writer, data, NULL); + break; + case DDS_NOT_ALIVE_NO_WRITERS_INSTANCE_STATE: + DDS_TypeBuiltinTopicDataDataWriter_unregister_instance(DCPSType_logger->topmon_writer, data, NULL); + break; + } + } else { + /* + * struct DDS_TypeBuiltinTopicData { + * DDS_string name; + * DDS_DataRepresentationId_t data_representation_id; + * DDS_TypeHash type_hash; + * DDS_octSeq meta_data; + * DDS_octSeq extentions; + * }; + */ + fprintf(DCPSType_logger->config->logfile, + "%llu %s DCPSType name[%s] time[%u,%u]\n", + (info->publication_handle << 32), + instanceState_image(info), + data->name, + info->source_timestamp.sec, info->source_timestamp.nanosec); + } + } + DDS_TypeBuiltinTopicDataDataReader_return_loan(DCPSType_logger->builtin_reader, dataList, infoList); + } + DDS_free(dataList); + DDS_free(infoList); + return OS_TRUE; +} + +topmon_config +topmon_configNew( + DDS_DomainParticipant participant, + char *partition, + FILE *logfile) +{ + topmon_config config = NULL; + + config = os_malloc(sizeof(*config)); + config->participant = participant; + config->partition = partition ? strdup(partition) : NULL; + config->logfile = logfile ? logfile : stdout; + config->builtin_subscriber = DDS_DomainParticipant_get_builtin_subscriber(participant); + config->waitset = DDS_WaitSet__alloc(); + + if (partition) { + DDS_PublisherQos *pqos; + DDS_SubscriberQos *sqos; + + pqos = DDS_PublisherQos__alloc(); + (void)DDS_DomainParticipant_get_default_publisher_qos(dp, pqos); + pqos->partition.name._maximum = 1; + pqos->partition.name._length = 1; + pqos->partition.name._buffer = DDS_StringSeq_allocbuf(1); + pqos->partition.name._buffer[0] = DDS_string_dup(partition); + + sqos = DDS_SubscriberQos__alloc(); + (void)DDS_DomainParticipant_get_default_subscriber_qos(dp, sqos); + sqos->partition.name._maximum = 1; + sqos->partition.name._length = 1; + sqos->partition.name._buffer = DDS_StringSeq_allocbuf(1); + sqos->partition.name._buffer[0] = DDS_string_dup(partition); + + config->publisher = DDS_DomainParticipant_create_publisher(participant, pqos, NULL, 0); + config->subscriber = DDS_DomainParticipant_create_subscriber(participant, sqos, NULL, 0); + } else { + config->publisher = NULL; + config->subscriber = NULL; + } + return config; +} + +topmon_logger +topmon_loggerNew( + topmon_config config, + const char *topic_name) +{ + DDS_ReturnCode_t result; + topmon_logger _this = NULL; + DDS_Topic topic; + + _this = os_malloc(sizeof(*_this)); + if (_this) { + _this->config = config; + _this->topic_name = strdup(topic_name); + _this->builtin_reader = + DDS_Subscriber_lookup_datareader(config->builtin_subscriber, topic_name); + _this->builtin_status_condition = + DDS_ParticipantBuiltinTopicDataDataReader_get_statuscondition(_this->builtin_reader); + result = DDS_StatusCondition_set_enabled_statuses(_this->builtin_status_condition, DDS_DATA_AVAILABLE_STATUS); + if (result != DDS_RETCODE_OK) { + printf("Error faild to set status conditions on builtin_status_condition\n"); + } + result = DDS_WaitSet_attach_condition(config->waitset, _this->builtin_status_condition); + if (result != DDS_RETCODE_OK) { + printf("Error faild to attach builtin_status_condition to waitset\n"); + } + topic = DDS_DomainParticipant_lookup_topicdescription(config->participant, topic_name); + if (config->publisher) { + _this->topmon_writer = + DDS_Publisher_create_datawriter(config->publisher, topic, DDS_DATAWRITER_QOS_USE_TOPIC_QOS, NULL, 0); + } else { + _this->topmon_writer = NULL; + } + if (config->subscriber) { + DDS_DataReaderQos rqos; + + memset(&rqos,0, sizeof(rqos)); + result = DDS_Subscriber_get_default_datareader_qos(config->subscriber, &rqos); + rqos.history.kind = DDS_KEEP_ALL_HISTORY_QOS; + + _this->topmon_reader = + DDS_Subscriber_create_datareader(config->subscriber, topic, &rqos, NULL, 0); + _this->topmon_status_condition = + DDS_ParticipantBuiltinTopicDataDataReader_get_statuscondition(_this->topmon_reader); + result = DDS_StatusCondition_set_enabled_statuses(_this->topmon_status_condition, DDS_DATA_AVAILABLE_STATUS); + if (result != DDS_RETCODE_OK) { + printf("Error faild to set status conditions on topmon_status_condition\n"); + } + result = DDS_WaitSet_attach_condition(config->waitset, _this->topmon_status_condition); + if (result != DDS_RETCODE_OK) { + printf("Error faild to attach topmon_status_condition to waitset\n"); + } + } else { + _this->topmon_reader = NULL; + _this->topmon_status_condition = NULL; + } + DDS_free(topic); + } + return _this; +} + + +int +main(int argc, char *argv[]) +{ + DDS_Duration_t infinite = DDS_DURATION_INFINITE; + DDS_ReturnCode_t result; + topmon_config config; + FILE *logfile = NULL; + int opt; + char *partition = NULL; + + while ((opt = getopt (argc, argv, "p:f:")) != -1) { + switch (opt) { + case 'p': partition = strdup(optarg); break; + case 'f': logfile = fopen(optarg, "w"); break; + case '?': printf("**** topmon usage: ****\n*\n"); + printf("* topmon [-p ] [-f ]\n*\n"); + printf("* topmon\n"); + printf("* -- print local topology state changes to stdout\n*\n"); + printf("* topmon -f \n"); + printf("* -- log local topology state changes to \n*\n"); + printf("* topmon -p \n"); + printf("* -- re-publish local topology state changes to \n*\n"); + printf("* topmon -p -f \n"); + printf("* -- re-publish local topology state changes to and log global topology state changes to \n*\n"); + printf("***********************\n"); + return 0; + break; + default: break; + } + } + + factory = DDS_DomainParticipantFactory_get_instance(); + dp = DDS_DomainParticipantFactory_create_participant( + factory, + DDS_DOMAIN_ID_DEFAULT, + DDS_PARTICIPANT_QOS_DEFAULT, + NULL, + 0); + + config = topmon_configNew(dp, partition, logfile); + + DCPSParticipant_logger = topmon_loggerNew(config, "DCPSParticipant"); + DCPSTopic_logger = topmon_loggerNew(config, "DCPSTopic"); + DCPSPublication_logger = topmon_loggerNew(config, "DCPSPublication"); + DCPSSubscription_logger = topmon_loggerNew(config, "DCPSSubscription"); + CMPublisher_logger = topmon_loggerNew(config, "CMPublisher"); + CMSubscriber_logger = topmon_loggerNew(config, "CMSubscriber"); + CMDataWriter_logger = topmon_loggerNew(config, "CMDataWriter"); + CMDataReader_logger = topmon_loggerNew(config, "CMDataReader"); + CMParticipant_logger = topmon_loggerNew(config, "CMParticipant"); + DCPSType_logger = topmon_loggerNew(config, "DCPSType"); + + /***********************************************************************************************/ + cs = DDS_ConditionSeq__alloc(); + + while (TRUE) { + result = DDS_WaitSet_wait (config->waitset, cs, &infinite); + if (result == DDS_RETCODE_OK) { + unsigned int i; + for (i = 0; i < cs->_length; i++) { + if (!processParticipant(cs->_buffer[i]) && + !processTopic(cs->_buffer[i]) && + !processPublication(cs->_buffer[i]) && + !processSubscription(cs->_buffer[i]) && + !processCmPublisher(cs->_buffer[i]) && + !processCmSubscriber(cs->_buffer[i]) && + !processCmWriter(cs->_buffer[i]) && + !processCmReader(cs->_buffer[i]) && + !processCmParticipant(cs->_buffer[i]) && + !processType(cs->_buffer[i])) + { + abort(); + } + } + } + } + + result = DDS_DomainParticipant_delete_contained_entities(dp); + if ( result != DDS_RETCODE_OK ) { + } + + result = DDS_DomainParticipantFactory_delete_participant(factory, dp); + if ( result != DDS_RETCODE_OK ) { + } + DDS_DomainParticipantFactory_delete_contained_entities(factory); + return 0; +} + +//static void +//reportResultCode(DDS_ReturnCode_t code) +//{ + //const char *image; + //image = DDS_ReturnCode_image(code); + //test_message(FW_NOTE, image); +//} diff --git a/src/tools/topmon/makefile b/src/tools/topmon/makefile new file mode 100644 index 000000000..7b3fcdfda --- /dev/null +++ b/src/tools/topmon/makefile @@ -0,0 +1,9 @@ +include $(OSPL_HOME)/setup/makefiles/makefile.mak + +all link: bld/$(SPLICE_TARGET)/makefile + @$(MAKE) -C bld/$(SPLICE_TARGET) $@ + + +clean: + @rm -rf bld/$(SPLICE_TARGET) + diff --git a/src/tools/topmon/makefile.mak b/src/tools/topmon/makefile.mak new file mode 100644 index 000000000..224921de5 --- /dev/null +++ b/src/tools/topmon/makefile.mak @@ -0,0 +1,17 @@ +# included by bld/$(SPLICE_HOST)/makefile + +TARGET_EXEC := topmon + +include $(OSPL_HOME)/setup/makefiles/target.mak + +LDLIBS += $(CORE_LIBS) -l$(DDS_DCPSSAC) -l$(DDS_CORE) + +CINCS += -I$(OSPL_HOME)/src/api/dcps/sac/include +CINCS += -I$(OSPL_HOME)/src/api/dcps/sac/bld/$(SPLICE_TARGET) +CINCS += -I$(OSPL_HOME)/src/database/database/include +CINCS += -I$(OSPL_HOME)/src/user/include +CINCS += -I$(OSPL_HOME)/src/kernel/include +CINCS += -I$(OSPL_HOME)/src/configuration/config/include +CINCS += -I$(OSPL_HOME)/src/utilities/include + +-include $(DEPENDENCIES) diff --git a/src/user/code/u__cfAttribute.h b/src/user/code/u__cfAttribute.h index d9f5b5f81..aa4d37483 100644 --- a/src/user/code/u__cfAttribute.h +++ b/src/user/code/u__cfAttribute.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/user/code/u__cfData.h b/src/user/code/u__cfData.h index 19edcd050..19e538785 100644 --- a/src/user/code/u__cfData.h +++ b/src/user/code/u__cfData.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/user/code/u__cfElement.h b/src/user/code/u__cfElement.h index 3f16d6402..a36ae2069 100644 --- a/src/user/code/u__cfElement.h +++ b/src/user/code/u__cfElement.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/user/code/u__cfNode.h b/src/user/code/u__cfNode.h index 75debdbf1..bc1c85867 100644 --- a/src/user/code/u__cfNode.h +++ b/src/user/code/u__cfNode.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/user/code/u__cfValue.h b/src/user/code/u__cfValue.h index 28ab242d5..b1cce0dd7 100644 --- a/src/user/code/u__cfValue.h +++ b/src/user/code/u__cfValue.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/user/code/u__dataReader.h b/src/user/code/u__dataReader.h index 06b659c40..8dd711c10 100644 --- a/src/user/code/u__dataReader.h +++ b/src/user/code/u__dataReader.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/user/code/u__dispatcher.h b/src/user/code/u__dispatcher.h index 38e1ce307..e583bfb85 100644 --- a/src/user/code/u__dispatcher.h +++ b/src/user/code/u__dispatcher.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,7 +24,12 @@ #include "u_observable.h" #include "u_entity.h" -#include "u_dispatcher.h" + +/* Returns mask of events that have been handled by the listener. */ +typedef u_eventMask (*u_dispatcherListener)(u_dispatcher o, u_eventMask event, void *usrData); +typedef void (*u_dispatcherThreadAction)(u_dispatcher o, void *usrData); + +#define u_dispatcher(o) ((u_dispatcher)(o)) u_dispatcher u_dispatcherNew( @@ -33,5 +39,17 @@ u_result u_dispatcherFree( u_dispatcher _this); +u_result +u_dispatcherInsertListener( + const u_dispatcher _this, + const u_eventMask eventMask, + const u_observableListener l, + void *userData); + +u_result +u_dispatcherRemoveListener( + const u_dispatcher _this, + const u_observableListener l); + #endif diff --git a/src/user/code/u__domain.h b/src/user/code/u__domain.h index 293083b2e..11b9ef72b 100644 --- a/src/user/code/u__domain.h +++ b/src/user/code/u__domain.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,6 +27,9 @@ #include "u_entity.h" #include "vortex_os.h" +void +u__domainMutexInit(); + u_result u_domainOpenForService( u_domain *domain, @@ -113,9 +117,12 @@ u_bool u_domainProtectAllowed( _In_ u_domain _this); +typedef void (*u_domainPreDeadlockAction)(void *actionArg); + u_bool -u_domainProtectAllowedClaimed( - _In_ u_domain _this); +u_domainProtectAllowedAction( + _In_ u_domain _this, + _In_ const u_domainPreDeadlockAction action); u_result u_domainDetach ( @@ -130,10 +137,6 @@ os_address u_domainHandleServer( _In_ u_domain _this); -os_address -u_domainAddress( - const u_domain _this); - u_result u_domainFederationSpecificPartitionName ( u_domain _this, @@ -144,4 +147,8 @@ void u_domainIdSetThreadSpecific( _In_ u_domain domain); +u_bool +u_domainIsSingleProcess( + _In_ u_domain domain); + #endif diff --git a/src/user/code/u__entity.h b/src/user/code/u__entity.h index 7d7e75bc2..f74444367 100644 --- a/src/user/code/u__entity.h +++ b/src/user/code/u__entity.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/user/code/u__handle.h b/src/user/code/u__handle.h index 181ec57d3..54f6ff6f5 100644 --- a/src/user/code/u__handle.h +++ b/src/user/code/u__handle.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/user/code/u__instanceHandle.h b/src/user/code/u__instanceHandle.h index f7b0d3cd8..c8c8413cc 100644 --- a/src/user/code/u__instanceHandle.h +++ b/src/user/code/u__instanceHandle.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/user/code/u__object.h b/src/user/code/u__object.h index 7c3789ba3..080f28d44 100644 --- a/src/user/code/u__object.h +++ b/src/user/code/u__object.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/user/code/u__observable.h b/src/user/code/u__observable.h index 885ad4ecf..393e9ecb2 100644 --- a/src/user/code/u__observable.h +++ b/src/user/code/u__observable.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -83,7 +84,7 @@ u__observableProxyFreeW( * Observable observable does not exist anymore. * \return the result value of the claim operation */ -u_result +OS_API u_result u_observableWriteClaim( const u_observable _this, v_public* vObject, diff --git a/src/user/code/u__participant.h b/src/user/code/u__participant.h index ef54928e0..56195d7da 100644 --- a/src/user/code/u__participant.h +++ b/src/user/code/u__participant.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/user/code/u__publisher.h b/src/user/code/u__publisher.h index f9889396b..2fe3709c7 100644 --- a/src/user/code/u__publisher.h +++ b/src/user/code/u__publisher.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/user/code/u__reader.h b/src/user/code/u__reader.h index dde14ada8..1173ff7b2 100644 --- a/src/user/code/u__reader.h +++ b/src/user/code/u__reader.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/user/code/u__service.h b/src/user/code/u__service.h index ed890818e..1d9d6b6a6 100644 --- a/src/user/code/u__service.h +++ b/src/user/code/u__service.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/user/code/u__serviceManager.h b/src/user/code/u__serviceManager.h index ab99de6e5..eb9b02122 100644 --- a/src/user/code/u__serviceManager.h +++ b/src/user/code/u__serviceManager.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -32,12 +33,6 @@ u_serviceManagerGetServiceState( const u_serviceManager s, const c_char *name); -u_result -u_serviceManagerSetListener( - const u_serviceManager _this, - const u_serviceSplicedaemonListener callback, - const void *usrData); - #if defined (__cplusplus) } #endif diff --git a/src/user/code/u__topic.h b/src/user/code/u__topic.h index 08be0c041..cc87674d9 100644 --- a/src/user/code/u__topic.h +++ b/src/user/code/u__topic.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/user/code/u__types.h b/src/user/code/u__types.h index 9a3405ab5..8315fcbac 100644 --- a/src/user/code/u__types.h +++ b/src/user/code/u__types.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -192,13 +193,13 @@ C_STRUCT(u_participant) C_STRUCT(u_serviceManager) { C_EXTENDS(u_entity); - u_serviceSplicedaemonListener callback; - void *usrData; }; C_STRUCT(u_service) { C_EXTENDS(u_participant); u_serviceManager serviceManager; + u_serviceSplicedaemonListener callback; + void *usrData; }; C_STRUCT(u_spliced) { @@ -212,6 +213,8 @@ C_STRUCT(u_spliced) { #define U_DOMAIN_DELETE_ENTITIES ((os_uint32)(1 << 30)) #define U_DOMAIN_BLOCK_IN_KERNEL ((os_uint32)(1 << 31)) +C_CLASS(u_splicedThread); + C_STRUCT(u_domain) { C_EXTENDS(u_entity); pa_uint32_t refCount; /* number of domain pointers in user layer objects */ @@ -223,15 +226,15 @@ C_STRUCT(u_domain) { * this purpose. */ v_kernel kernel; v_processInfo procInfo; + os_uint32 serial; /* copy of procInfo->serial stored outside kernel */ os_sharedHandle shm; - os_threadId spliced_thread; /* OS_THREAD_ID_NONE for SHM domains */ + u_splicedThread spliced_thread; /* NULL for SHM domains*/ c_iter participants; c_iter waitsets; os_char *uri; os_char *name; os_lockPolicy lockPolicy; os_uint32 protectCount; - os_uint32 serial; u_domainId_t id; os_boolean owner; /* Used by u_domainClose to destroy SHM if called by spliced */ os_mutex mutex; @@ -254,6 +257,7 @@ C_STRUCT(u_domain) { pa_uint32_t claimed; /* Used to protect access to the process info */ os_threadId threadWithAccess; c_iter reportPlugins; + os_duration serviceTerminatePeriod; }; #endif diff --git a/src/user/code/u__user.h b/src/user/code/u__user.h index 33562d46c..60c978f97 100644 --- a/src/user/code/u__user.h +++ b/src/user/code/u__user.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/user/code/u__usrClock.h b/src/user/code/u__usrClock.h index f34d8298f..e33f6adbc 100644 --- a/src/user/code/u__usrClock.h +++ b/src/user/code/u__usrClock.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/user/code/u__usrReportPlugin.h b/src/user/code/u__usrReportPlugin.h index 3d9886ffa..58b6eb153 100644 --- a/src/user/code/u__usrReportPlugin.h +++ b/src/user/code/u__usrReportPlugin.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/user/code/u__waitset.h b/src/user/code/u__waitset.h index ced33137e..e349bc815 100644 --- a/src/user/code/u__waitset.h +++ b/src/user/code/u__waitset.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/user/code/u_builtin.c b/src/user/code/u_builtin.c index e94571038..300d9f301 100644 --- a/src/user/code/u_builtin.c +++ b/src/user/code/u_builtin.c @@ -2,11 +2,14 @@ #include "vortex_os.h" #include "os_report.h" +#include "os_atomics.h" +#include "v_time.h" #include "v_service.h" #include "v_participant.h" #include "v_publisher.h" #include "v_writer.h" #include "v_builtin.h" +#include "v_state.h" #include "u__user.h" #include "u__object.h" #include "u__observable.h" @@ -36,13 +39,14 @@ u__builtinWriterInit( } /* Each "networking" service that sees a given node (and possibly spliced) has - it's own registration for the DCPSHeartbeat instance declaring that node. - Only when all "networking" services have unregistered this instance will - become not alive, indicating to whoever is interested that the node no - longer exists (for example, triggering spliced to dispose it). Thus, it is - necessary that all networking services have their own writers. This is - merely a convenience function to ensure that all "networking" services use - the same QoS settings. */ + * it's own registration for the DCPSHeartbeat instance declaring that node. + * Only when all "networking" services have unregistered this instance will + * become not alive, indicating to whoever is interested that the node no + * longer exists (for example, triggering spliced to dispose it). Thus, it is + * necessary that all networking services have their own writers. This is + * merely a convenience function to ensure that all "networking" services use + * the same QoS settings. + */ u_writer u_builtinWriterNew( const u_publisher publisher, @@ -72,7 +76,8 @@ u_builtinWriterNew( kernel = v_objectKernel(vPublisher); /* Retrieve builtin DCPSHeartbeat writer created by spliced, so that - the QoS can be copied. */ + * the QoS can be copied. + */ vBuiltinWriter = v_builtinWriterLookup (kernel->builtin, infoId); assert (vBuiltinWriter != NULL); vWriterQos = v_writerGetQos(vBuiltinWriter); @@ -129,7 +134,6 @@ u_builtinWriterNew( return _this; } - struct u__builtinHeartbeatArgument { c_ulong systemId; v_state state; @@ -142,10 +146,21 @@ u__builtinWriteFakeHeartbeat( void *varg) { struct u__builtinHeartbeatArgument *arg = varg; + v_kernel k; + + if(arg->state & L_WRITE) { + k = v_objectKernel(_this); + assert(k != NULL); + /* Disable purging by increasing the purgeSuppressCount and writing a + * DCPSHeartbeat. + */ + pa_inc32(&k->purgeSuppressCount); + } /* Write a fake heartbeat with an infinite duration to prevent spliced - from generating a fake heartbeat with a finite duration. It MUST - remain local to the machine, therefore v_groupWrite must be used. */ + * from generating a fake heartbeat with a finite duration. It MUST + * remain local to the machine, therefore v_groupWrite must be used. + */ arg->result = v_builtinWriteHeartbeat( v_writer (_this), arg->systemId, os_timeWGet (), OS_DURATION_INFINITE, arg->state); } @@ -165,8 +180,7 @@ u_builtinWriteFakeHeartbeat( arg.state = state; arg.result = V_WRITE_ERROR; - result = u_observableAction ( - u_observable (_this), &u__builtinWriteFakeHeartbeat, &arg); + result = u_observableAction (u_observable (_this), &u__builtinWriteFakeHeartbeat, &arg); if (result == U_RESULT_OK) { result = u_resultFromKernelWriteResult(arg.result); } diff --git a/src/user/code/u_cfAttribute.c b/src/user/code/u_cfAttribute.c index 0a98da5c6..9e61d23b0 100644 --- a/src/user/code/u_cfAttribute.c +++ b/src/user/code/u_cfAttribute.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/user/code/u_cfData.c b/src/user/code/u_cfData.c index 42f60a7f0..c0e553710 100644 --- a/src/user/code/u_cfData.c +++ b/src/user/code/u_cfData.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/user/code/u_cfElement.c b/src/user/code/u_cfElement.c index 4a2388cc9..a9cee126d 100644 --- a/src/user/code/u_cfElement.c +++ b/src/user/code/u_cfElement.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/user/code/u_cfNode.c b/src/user/code/u_cfNode.c index 3107e676c..415f62332 100644 --- a/src/user/code/u_cfNode.c +++ b/src/user/code/u_cfNode.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/user/code/u_cfValue.c b/src/user/code/u_cfValue.c index b7a0ef1ba..c31827a59 100644 --- a/src/user/code/u_cfValue.c +++ b/src/user/code/u_cfValue.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -50,9 +51,6 @@ #define CF_FORMAT(x) CF_FORMAT_##x -/************************************************************** - * Private functions - **************************************************************/ /* Special routine for scanning booleans */ /* scanf does not support this */ static u_bool @@ -79,18 +77,6 @@ u_cfValueScanBoolean( return result; } -/************************************************************** - * constructor/destructor - **************************************************************/ - -/************************************************************** - * Protected functions - **************************************************************/ - -/************************************************************** - * Public functions - **************************************************************/ - #define __CASE__(kind,type) \ case V_##kind: \ { \ diff --git a/src/user/code/u_cmsoap.c b/src/user/code/u_cmsoap.c index 6a3c0bb63..c99737ef1 100644 --- a/src/user/code/u_cmsoap.c +++ b/src/user/code/u_cmsoap.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/user/code/u_dataReader.c b/src/user/code/u_dataReader.c index 8191d3c2b..7f892415e 100644 --- a/src/user/code/u_dataReader.c +++ b/src/user/code/u_dataReader.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -82,8 +83,8 @@ u_dataReaderNew( const os_char *name, const os_char *expr, const c_value params[], - const u_readerQos qos, - u_bool enable) + os_uint32 nrOfParams, + const u_readerQos qos) { u_dataReader _this = NULL; v_subscriber ks = NULL; @@ -99,7 +100,7 @@ u_dataReaderNew( result = u_observableWriteClaim(u_observable(s), (v_public *)(&ks), C_MM_RESERVATION_HIGH); if (result == U_RESULT_OK) { assert(ks); - reader = v_dataReaderNewBySQL(ks, name, expr, params, qos, enable); + reader = v_dataReaderNewBySQL(ks, name, expr, params, nrOfParams, qos); if (reader != NULL) { _this = u_objectAlloc(sizeof(*_this), U_READER, u__dataReaderDeinitW, u__dataReaderFreeW); if (_this != NULL) { @@ -401,7 +402,7 @@ u_dataReaderWaitForHistoricalData( result = u_dataReaderReadClaim(_this, &reader, C_MM_RESERVATION_ZERO); if (result == U_RESULT_OK) { - result = u_resultFromKernel(v_readerWaitForHistoricalData(v_reader(reader), timeout)); + result = u_resultFromKernel(v_readerWaitForHistoricalData(v_reader(reader), timeout, FALSE)); u_dataReaderRelease(_this, C_MM_RESERVATION_ZERO); } return result; @@ -432,7 +433,7 @@ u_dataReaderWaitForHistoricalDataWithCondition( v_reader(reader), filter, params, paramsLength, minSourceTime, maxSourceTime, max_samples, max_instances, max_samples_per_instance, - timeout)); + timeout, FALSE)); u_dataReaderRelease(_this, C_MM_RESERVATION_ZERO); } return result; @@ -461,39 +462,44 @@ u_dataReaderLookupInstance( result = u_dataReaderReadClaim(_this, &reader, C_MM_RESERVATION_LOW); if (result == U_RESULT_OK) { topic = v_dataReaderGetTopic(reader); - message = v_topicMessageNew_s(topic); - if (message) { - to = (void *) (message + 1); - copyResult = copyIn(v_topicDataType(topic), keyTemplate, to); - if (V_COPYIN_RESULT_IS_OK(copyResult)) { - instance = v_dataReaderLookupInstance(reader, message); - *handle = u_instanceHandleNew(v_public(instance)); - c_free(instance); - } else { - if (V_COPYIN_RESULT_IS_OUT_OF_MEMORY(copyResult)) { - result = U_RESULT_OUT_OF_MEMORY; - OS_REPORT(OS_ERROR, "u_dataReaderLookupInstance", result, - "Out of memory: unable to create message for Topic: '%s'.", - v_entityName2(topic)); + + if(topic){ + message = v_topicMessageNew_s(topic); + if (message) { + to = (void *) (message + 1); + copyResult = copyIn(v_topicDataType(topic), keyTemplate, to); + if (V_COPYIN_RESULT_IS_OK(copyResult)) { + instance = v_dataReaderLookupInstance(reader, message); + *handle = u_instanceHandleNew(v_public(instance)); + c_free(instance); } else { - result = U_RESULT_ILL_PARAM; - OS_REPORT(OS_ERROR, "u_dataReaderLookupInstance", result, - "Invalid key: unable to create message for Topic: '%s'.", - v_entityName2(topic)); + if (V_COPYIN_RESULT_IS_OUT_OF_MEMORY(copyResult)) { + result = U_RESULT_OUT_OF_MEMORY; + OS_REPORT(OS_ERROR, "u_dataReaderLookupInstance", result, + "Out of memory: unable to create message for Topic: '%s'.", + v_entityName2(topic)); + } else { + result = U_RESULT_ILL_PARAM; + OS_REPORT(OS_ERROR, "u_dataReaderLookupInstance", result, + "Invalid key: unable to create message for Topic: '%s'.", + v_entityName2(topic)); + } } + c_free(message); + } else { + c_char *name = v_topicName(topic); + if (name == NULL) { + name = "No Name"; + } + result = U_RESULT_OUT_OF_MEMORY; + OS_REPORT(OS_ERROR, "u_dataReaderLookupInstance", result, + "Out of memory: unable to create message for Topic: '%s'.", + name); } - c_free(message); + c_free(topic); } else { - c_char *name = v_topicName(topic); - if (name == NULL) { - name = "No Name"; - } - result = U_RESULT_OUT_OF_MEMORY; - OS_REPORT(OS_ERROR, "u_dataReaderLookupInstance", result, - "Out of memory: unable to create message for Topic: '%s'.", - name); + result = U_RESULT_ALREADY_DELETED; } - c_free(topic); u_dataReaderRelease(_this, C_MM_RESERVATION_LOW); } else { OS_REPORT(OS_WARNING, "u_dataReaderLookupInstance", U_RESULT_INTERNAL_ERROR, @@ -584,7 +590,7 @@ u_dataReaderSetQos ( result = u_dataReaderReadClaim(_this, &reader,C_MM_RESERVATION_HIGH); if (result == U_RESULT_OK) { - result = u_resultFromKernel(v_readerSetQos(v_reader(reader), qos)); + result = u_resultFromKernel(v_dataReaderSetQos(reader, qos)); u_dataReaderRelease(_this, C_MM_RESERVATION_HIGH); } return result; diff --git a/src/user/code/u_dataView.c b/src/user/code/u_dataView.c index d5e84226f..8a665727b 100644 --- a/src/user/code/u_dataView.c +++ b/src/user/code/u_dataView.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -33,7 +34,6 @@ #include "v_public.h" #include "v_dataView.h" -#include "v_dataViewInstance.h" #include "v_dataReader.h" #include "os_report.h" @@ -59,6 +59,8 @@ u_dataViewInstanceAction( v_dataView view; struct instanceActionArg *a = (struct instanceActionArg *)arg; + OS_UNUSED_ARG(timeout); + result = u_observableReadClaim(u_observable(a->view),(v_public*)(&view), C_MM_RESERVATION_LOW); if (result == U_RESULT_OK) { handle = u_instanceHandleFix(handle,v_collection(view)); @@ -66,7 +68,7 @@ u_dataViewInstanceAction( result = u_instanceHandleClaim(handle, &instance); if ((result == U_RESULT_OK) && (instance != NULL)) { assert(instance != NULL); - action(v_dataViewInstance(instance),arg, timeout); + action((v_dataViewInstance)instance,arg, timeout); u_instanceHandleRelease(handle); } } @@ -330,15 +332,6 @@ u_dataViewReadInstance( instanceActionArg.readerAction = readAction; instanceActionArg.readerActionArg = &arg; result = u_dataViewInstanceAction(handle, u_readInstanceAction, (c_voidp)&instanceActionArg, timeout); -#if 0 - if (result == U_RESULT_HANDLE_EXPIRED) { - /* Error propagation moves the role of the handle from - * being the object to being a parameter, this affect the - * already deleted status into ill parameter status. - */ - result = U_RESULT_ILL_PARAM; - } -#endif return result; } @@ -398,15 +391,6 @@ u_dataViewTakeInstance( result = u_dataViewInstanceAction(handle, u_takeInstanceAction, (c_voidp)&instanceActionArg, timeout); -#if 0 - if (result == U_RESULT_HANDLE_EXPIRED) { - /* Error propagation moves the role of the handle from - * being the object to being a parameter, this affect the - * already deleted status into ill parameter status. - */ - result = U_RESULT_ILL_PARAM; - } -#endif return result; } @@ -624,26 +608,31 @@ u_dataViewLookupInstance( if (result == U_RESULT_OK) { assert(view); topic = v_dataReaderGetTopic(view->reader); - message = v_topicMessageNew_s(topic); - if (message) { - to = (void *) (message + 1); - copyIn(v_topicDataType(topic), keyTemplate, to); - instance = v_dataViewLookupInstance(view, message); - *handle = u_instanceHandleNew(v_public(instance)); - c_free(instance); - c_free(message); - } else { - c_char *name = v_topicName(topic); - if (name == NULL) { - name = "No Name"; + + if(topic){ + message = v_topicMessageNew_s(topic); + if (message) { + to = (void *) (message + 1); + copyIn(v_topicDataType(topic), keyTemplate, to); + instance = v_dataViewLookupInstance(view, message); + *handle = u_instanceHandleNew(v_public(instance)); + c_free(instance); + c_free(message); + } else { + c_char *name = v_topicName(topic); + if (name == NULL) { + name = "No Name"; + } + result = U_RESULT_OUT_OF_MEMORY; + OS_REPORT(OS_ERROR, + "u_dataViewLookupInstance", result, + "Out of memory: unable to create message for Topic '%s'.", + name); } - result = U_RESULT_OUT_OF_MEMORY; - OS_REPORT(OS_ERROR, - "u_dataViewLookupInstance", result, - "Out of memory: unable to create message for Topic '%s'.", - name); + c_free(topic); + } else { + result = U_RESULT_ALREADY_DELETED; } - c_free(topic); u_observableRelease(u_observable(_this), C_MM_RESERVATION_ZERO); } else { OS_REPORT(OS_WARNING, "u_dataViewLookupInstance", result, diff --git a/src/user/code/u_dataViewQos.c b/src/user/code/u_dataViewQos.c index 78943ff8d..dc32083f2 100644 --- a/src/user/code/u_dataViewQos.c +++ b/src/user/code/u_dataViewQos.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/user/code/u_dbmsconnect.c b/src/user/code/u_dbmsconnect.c new file mode 100644 index 000000000..3db90e4a8 --- /dev/null +++ b/src/user/code/u_dbmsconnect.c @@ -0,0 +1,49 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#include "u_dbmsconnect.h" +#include "u__domain.h" +#include "u__object.h" +#include "u__observable.h" +#include "u__service.h" + +#include "v_service.h" +#include "v_dbmsconnect.h" +#include "v_configuration.h" +#include "os_report.h" + +static void *wrapper(v_kernel kernel, const c_char *name, const c_char *extStateName, v_participantQos qos, c_bool enable, void *varg) +{ + OS_UNUSED_ARG(varg); + return v_dbmsconnectNew(kernel, name, extStateName, qos, enable); +} + +u_service +u_dbmsconnectNew ( + const os_char *uri, + const u_domainId_t id, + const os_int32 timeout, /* in seconds */ + const os_char *name, + const u_participantQos qos, + c_bool enable) +{ + return u_serviceNewSpecialized(wrapper, "DBMSConnectService", uri, id, timeout, name, qos, enable, NULL); +} + diff --git a/src/user/code/u_dispatcher.c b/src/user/code/u_dispatcher.c index 89a281314..848c1b76c 100644 --- a/src/user/code/u_dispatcher.c +++ b/src/user/code/u_dispatcher.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,12 +21,11 @@ #include "u_user.h" #include "u__dispatcher.h" -#include "u__types.h" #include "u__observable.h" +#include "u__types.h" #include "u__entity.h" #include "v_entity.h" -#include "v_observable.h" #include "v_observer.h" #include "v_event.h" @@ -34,11 +34,9 @@ C_CLASS(u_callback); C_STRUCT(u_callback) { - u_observableListener listener; - void *usrData; /* data specific for a user, just - passed as value to the function - listener - */ + u_observableListener listener; + u_eventMask eventMask; + void *usrData; /* data specific for a user, just passed as value to the function listener */ }; struct callbackExecArg { @@ -177,6 +175,7 @@ u_dispatcherFree( u_result u_dispatcherInsertListener( const u_dispatcher _this, + const u_eventMask eventMask, const u_observableListener listener, void *userData) { @@ -193,71 +192,31 @@ u_dispatcherInsertListener( callback = os_malloc(C_SIZEOF(u_callback)); callback->listener = listener; callback->usrData = userData; + callback->eventMask = eventMask; _this->callbacks = c_iterInsert(_this->callbacks,callback); - if (os_threadIdToInteger(_this->threadId) == 0U) { - result = u_observableReadClaim(_this->observable, (v_public *)(&ke), C_MM_RESERVATION_ZERO); - if(result == U_RESULT_OK) { - assert(ke); + result = u_observableReadClaim(_this->observable, (v_public *)(&ke), C_MM_RESERVATION_ZERO); + if(result == U_RESULT_OK) { + assert(ke); + if (os_threadIdToInteger(_this->threadId) == 0U) { name = v_entityName(ke); if (name == NULL) { name = "NoName"; } os_threadAttrInit(&attr); - os_threadCreate(&_this->threadId, - name, - &attr,dispatch, - (void *)_this); - u_observableRelease(_this->observable, C_MM_RESERVATION_ZERO); - } else { - OS_REPORT(OS_WARNING, "u_dispatcherInsertListener", result, - "Failed to claim Dispatcher."); + os_threadCreate(&_this->threadId, name, &attr,dispatch, (void *)_this); } + v_observerSetEvent(ke,eventMask); + u_observableRelease(_this->observable, C_MM_RESERVATION_ZERO); + } else { + OS_REPORT(OS_WARNING, "u_dispatcherInsertListener", result, + "Failed to claim Dispatcher."); } os_mutexUnlock(&_this->mutex); return result; } -u_result -u_dispatcherAppendListener( - const u_dispatcher _this, - const u_observableListener listener, - void *userData) -{ - u_callback callback; - os_threadAttr attr; - v_observer ko; - u_result result = U_RESULT_OK; - - assert(_this != NULL); - assert(listener != NULL); - - os_mutexLock(&_this->mutex); - callback = os_malloc(C_SIZEOF(u_callback)); - callback->listener = listener; - callback->usrData = userData; - _this->callbacks = c_iterAppend(_this->callbacks,callback); - if (os_threadIdToInteger(_this->threadId) == 0U) { - result = u_observableReadClaim(_this->observable, (v_public *)(&ko), C_MM_RESERVATION_ZERO); - if(result == U_RESULT_OK) { - assert(ko); - os_threadAttrInit(&attr); - os_threadCreate(&_this->threadId, - v_entityName(ko), - &attr, - dispatch, - (void *)_this); - u_observableRelease(_this->observable, C_MM_RESERVATION_ZERO); - } else { - OS_REPORT(OS_WARNING, "u_dispatcherAppendListener", result, - "Failed to claim Dispatcher."); - } - } - os_mutexUnlock(&_this->mutex); - return result; -} - static c_equality compare( c_voidp o, @@ -297,6 +256,7 @@ u_dispatcherRemoveListener( result = u_observableReadClaim(_this->observable, (v_public *)(&ko), C_MM_RESERVATION_ZERO); if(result == U_RESULT_OK) { assert(ko); + v_observerClearEvent(ko,callback->eventMask); /* Wakeup the dispatch thread */ v_observerLock(ko); v_observerNotify(ko, NULL, NULL); @@ -317,72 +277,3 @@ u_dispatcherRemoveListener( } return result; } - -u_result -u_dispatcherNotify( - const u_dispatcher _this) -{ - v_observer ko; - u_result result = U_RESULT_OK; - - assert(_this != NULL); - - result = u_observableReadClaim(_this->observable, (v_public *)(&ko),C_MM_RESERVATION_ZERO); - if (result == U_RESULT_OK) { - assert(ko); - /* Wakeup the dispatch thread */ - v_observerLock(ko); - v_observerNotify(ko, NULL, NULL); - v_observerUnlock(ko); - u_observableRelease(_this->observable, C_MM_RESERVATION_ZERO); - } else { - OS_REPORT(OS_WARNING, "u_dispatcherNotify", result, - "Failed to claim Dispatcher."); - } - return result; -} - -u_result -u_dispatcherSetEventMask( - const u_dispatcher _this, - u_eventMask eventMask) -{ - v_observer ko; - u_result result = U_RESULT_OK; - - assert(_this != NULL); - - result = u_observableReadClaim(_this->observable, (v_public *)(&ko), C_MM_RESERVATION_ZERO); - if (result == U_RESULT_OK) { - assert(ko); - v_observerSetEventMask(ko,eventMask); - u_observableRelease(_this->observable,C_MM_RESERVATION_ZERO); - } else { - OS_REPORT(OS_WARNING, "u_dispatcherSetEventMask", result, - "Failed to claim Dispatcher."); - } - return result; -} - -u_result -u_dispatcherGetEventMask( - const u_dispatcher _this, - u_eventMask *eventMask) -{ - v_observer ko; - u_result result = U_RESULT_OK; - - assert(_this != NULL); - assert(eventMask != NULL); - - result = u_observableReadClaim(_this->observable, (v_public *)(&ko), C_MM_RESERVATION_ZERO); - if (result == U_RESULT_OK) { - assert(ko); - *eventMask = v_observerGetEventMask(ko); - u_observableRelease(_this->observable, C_MM_RESERVATION_ZERO); - } else { - OS_REPORT(OS_WARNING, "u_dispatcherGetEventMask", result, - "Failed to claim Dispatcher."); - } - return result; -} diff --git a/src/user/code/u_domain.c b/src/user/code/u_domain.c index 5c717e746..f08f0de0c 100755 --- a/src/user/code/u_domain.c +++ b/src/user/code/u_domain.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -66,6 +67,8 @@ static os_boolean processConfigAlreadySet = OS_FALSE; static pa_uint32_t domainSerial = PA_UINT32_INIT(0); +static pa_uint32_t _ospl_SplicedInitCount = PA_UINT32_INIT(0); +static os_mutex mutex; static void printThreadMessage( @@ -78,10 +81,13 @@ printThreadMessage( } } +C_CLASS(u_domainConfig); C_STRUCT(u_domainConfig) { + const os_char *uri; os_char *name; u_size dbSize; u_size dbFreeMemThreshold; + os_sharedAttr shmAttr; os_address address; os_lockPolicy lockPolicy; u_bool heap; @@ -91,7 +97,10 @@ C_STRUCT(u_domainConfig) { u_bool idReadFromConfig; c_bool maintainObjectCount; u_bool inProcessExceptionHandling; + c_iter reportPlugins; + cf_element processConfig; struct v_systemIdConfig systemIdConfig; + os_duration serviceTerminatePeriod; }; C_STRUCT(attributeCopyArg) { @@ -99,9 +108,40 @@ C_STRUCT(attributeCopyArg) { v_cfElement element; }; -/************************************************************** - * Private functions - **************************************************************/ +C_STRUCT(u_splicedThread) { + os_threadId tid; + pa_uint32_t terminated; + struct ut_entryPointWrapperArg *mwa; +}; + +static void +u_domainCfgInit( + u_domainConfig _this, + const os_char *uri, + const u_domainId_t id) +{ + /* Initialize the set of default configuration values. */ + _this->uri = uri; + _this->lockPolicy = OS_LOCK_DEFAULT; + _this->builtinTopicEnabled = TRUE; + _this->prioInherEnabled = FALSE; + _this->id = id; + _this->idReadFromConfig = FALSE; + _this->heap = FALSE; + _this->dbSize = DATABASE_SIZE; + _this->dbFreeMemThreshold = DATABASE_FREE_MEM_THRESHOLD; + _this->maintainObjectCount = 1; + _this->inProcessExceptionHandling = TRUE; + _this->name = os_strdup(U_DOMAIN_NAME); + _this->systemIdConfig.min = 1; + _this->systemIdConfig.max = 0x7fffffffu; + _this->systemIdConfig.entropySize = 0; + _this->systemIdConfig.entropy = NULL; + _this->reportPlugins = NULL; + _this->processConfig = NULL; + _this->serviceTerminatePeriod = 10*OS_DURATION_SECOND; + os_sharedAttrInit(&_this->shmAttr); +} static void GetDomainConfigSystemId( @@ -156,11 +196,10 @@ GetDomainConfigSystemId( } } -static void +static u_result GetDomainConfig( - const cf_element config, - C_STRUCT(u_domainConfig) *domainConfig, - os_sharedAttr *shm_attr) + u_domainConfig domainConfig, + const os_boolean validate) { cf_element dc = NULL; cf_element child; @@ -180,13 +219,30 @@ GetDomainConfig( os_boolean sizeSet = OS_FALSE; os_boolean defaultThresholdsize = OS_TRUE; os_int32 cfDomainId = -1; + u_result result = U_RESULT_OK; + cfgprs_status s; - assert(config != NULL); assert(domainConfig != NULL); assert(domainConfig->name != NULL); - assert(shm_attr != NULL); - dc = cf_element(cf_elementChild(config, CFG_DOMAIN)); + s = cfg_parse_ospl(domainConfig->uri, &domainConfig->processConfig); + if (s == CFGPRS_OK) { + if (validate) { + s = cfg_validateConfiguration(domainConfig->processConfig); + if (s != CFGPRS_OK) { + result = U_RESULT_ILL_PARAM; + OS_REPORT(OS_ERROR, "user::u_domain::GetDomainConfig",result, + "Error in configuration file \'%s\'\n", domainConfig->uri); + } + } + } else { + result = U_RESULT_ILL_PARAM; + OS_REPORT(OS_ERROR, "user::u_domain::GetDomainConfig", result, + "Invalid URI specified: \"%s\".", domainConfig->uri); + } + if (result == U_RESULT_OK) { + dc = cf_element(cf_elementChild(domainConfig->processConfig, CFG_DOMAIN)); + } if (dc != NULL) { name = cf_element(cf_elementChild(dc, CFG_NAME)); if (name != NULL) { @@ -278,33 +334,30 @@ GetDomainConfig( value = cf_dataValue(elementData); if ( (strlen(value.is.String) > 2) && (strncmp("0x", value.is.String, 2) == 0) ) { - sscanf(value.is.String, "0x" PA_ADDRFMT, &domainConfig->address); + sscanf(value.is.String, "0x" PA_ADDRFMT, (os_address *)&domainConfig->shmAttr.map_address); } else { - sscanf(value.is.String, PA_ADDRFMT, &domainConfig->address); + sscanf(value.is.String, PA_ADDRFMT, (os_address *)&domainConfig->shmAttr.map_address); } - shm_attr->map_address = (void*)domainConfig->address; } } locked = cf_element(cf_elementChild(child, CFG_LOCKING)); - domainConfig->lockPolicy = OS_LOCK_DEFAULT; if (locked != NULL) { elementData = cf_data(cf_elementChild(locked, "#text")); if (elementData != NULL) { value = cf_dataValue(elementData); if (os_strncasecmp(value.is.String, "TRUE", 4) == 0) { - domainConfig->lockPolicy = OS_LOCKED; + domainConfig->shmAttr.lockPolicy = OS_LOCKED; } else if (os_strncasecmp(value.is.String, "FALSE", 5) == 0) { - domainConfig->lockPolicy = OS_UNLOCKED; + domainConfig->shmAttr.lockPolicy = OS_UNLOCKED; } else if (os_strncasecmp(value.is.String, "DEFAULT", 7) == 0) { - domainConfig->lockPolicy = OS_LOCK_DEFAULT; + domainConfig->shmAttr.lockPolicy = OS_LOCK_DEFAULT; } else { OS_REPORT(OS_WARNING, OSRPT_CNTXT_USER, U_RESULT_INTERNAL_ERROR, "Incorrect parameter for Domain: \"%s\"," " using default locking",value.is.String); } } - } /* else: keep the platform dependent default OS_LOCK_DEFAULT */ - shm_attr->lockPolicy = domainConfig->lockPolicy; + } maintainObjectCount = cf_element(cf_elementChild(child, CFG_MAINTAINOBJECTCOUNT)); domainConfig->maintainObjectCount = 1; if (maintainObjectCount != NULL) { @@ -331,7 +384,7 @@ GetDomainConfig( if (os_strncasecmp(value.is.String, "TRUE", 4) == 0) { /* A SingleProcess value of True implies that Heap is to be used */ domainConfig->heap = TRUE; - shm_attr->sharedImpl = OS_MAP_ON_HEAP; + domainConfig->shmAttr.sharedImpl = OS_MAP_ON_HEAP; os_serviceSetSingleProcess(); /* default db size in single process mode is 0 */ if (sizeSet == OS_FALSE) { @@ -364,6 +417,17 @@ GetDomainConfig( } /* No attribute enabled, so use default value */ } /* No 'PriorityInheritance' element, so use default value */ + child = cf_element(cf_elementChild(dc, CFG_TERMPERIOD)); + if (child != NULL) { + elementData = cf_data(cf_elementChild(child, "#text")); + if (elementData != NULL) { + value = cf_dataValue(elementData); + if (value.kind == V_FLOAT) { + domainConfig->serviceTerminatePeriod = os_realToDuration(value.is.Float); + } + } + } + GetDomainConfigSystemId(dc, domainConfig); child = cf_element(cf_elementChild(dc, CFG_REPORT)); @@ -403,6 +467,7 @@ GetDomainConfig( } } } + return result; } static void @@ -505,7 +570,8 @@ lockSharedMemory( } } else { /* this should not happen, as this would mean - * we are not attached to shared memory at all */ + * we are not attached to shared memory at all + */ assert(0); result = 1; /* fail */ } @@ -532,7 +598,8 @@ unlockSharedMemory( } } else { /* this should not happen, as this would mean - we are not attach to shared memory at all */ + * we are not attach to shared memory at all + */ assert(0); result = os_resultFail; } @@ -549,17 +616,66 @@ unlockSharedMemory( return result; } +static void * +splicedThreadWrapper(void *arg) +{ + void *result; + u_splicedThread spliced_thread = (u_splicedThread)arg; + result = ut_entryPointWrapper(spliced_thread->mwa); + pa_st32(&spliced_thread->terminated, 1); + return result; +} + +static u_result +splicedThreadJoin( + u_splicedThread spliced_thread, + os_duration timeout) +{ + u_result result = U_RESULT_INTERNAL_ERROR; + os_duration delay = 10*OS_DURATION_MILLISECOND; + os_timeM stopTime; + os_uint32 terminated; + os_address retcode; + os_result osr; + + stopTime = os_timeMAdd(os_timeMGet(), timeout); + + while ((!(terminated = pa_ld32(&spliced_thread->terminated))) && + (os_timeMCompare(os_timeMGet(), stopTime) == OS_LESS)) { + ospl_os_sleep(delay); + } + if (terminated) { + osr = os_threadWaitExit(spliced_thread->tid, (void **)&retcode); + if (osr == os_resultSuccess) { + if (retcode == 0) { + result = U_RESULT_OK; + } else { + OS_REPORT(OS_WARNING, OS_FUNCTION, result, + "Splice daemon thread terminated and reporting error code %d", + (int)retcode); + } + } + os_free(spliced_thread); + } else { + OS_REPORT(OS_WARNING, OS_FUNCTION, result, + "Splice daemon thread(0x%" PA_PRIxADDR ") did not terminate within serviceTerminatePeriod", + (os_address)os_threadIdToInteger(spliced_thread->tid)); + } + + return result; +} + static u_result startSplicedWithinProcess( - os_threadId *tid, + u_splicedThread *spliced_thread, const os_char *uri) { os_library libraryHandle; os_libraryAttr libraryAttr; - struct ut_entryPointWrapperArg *mwa; os_threadAttr threadAttr; os_result osr; u_result result; + u_splicedThread splicedThread = NULL; char * spliced = "spliced"; char * entryPoint = "ospl_spliced"; @@ -570,7 +686,9 @@ startSplicedWithinProcess( result = U_RESULT_OK; } if (result == U_RESULT_OK) { - mwa = os_malloc(sizeof(struct ut_entryPointWrapperArg)); + splicedThread = os_malloc(C_SIZEOF(u_splicedThread)); + splicedThread->mwa = os_malloc(sizeof(struct ut_entryPointWrapperArg)); + pa_st32(&splicedThread->terminated, 0); /* Initialise the library attributes */ os_libraryAttrInit(&libraryAttr); @@ -594,8 +712,8 @@ startSplicedWithinProcess( * Corrigendum 1) workaround; see the Rationale for the * POSIX specification of dlsym(). */ - *(void **)(&mwa->entryPoint) = os_libraryGetSymbol(libraryHandle, entryPoint); - if (mwa->entryPoint == NULL) { + *(void **)(&splicedThread->mwa->entryPoint) = os_libraryGetSymbol(libraryHandle, entryPoint); + if (splicedThread->mwa->entryPoint == NULL) { result = U_RESULT_INTERNAL_ERROR; OS_REPORT(OS_ERROR,"user::u_domain::startSplicedInProcess",result, "Error opening '%s' entry point\n", entryPoint); @@ -604,20 +722,28 @@ startSplicedWithinProcess( if (result == U_RESULT_OK) { os_threadAttrInit(&threadAttr); - mwa->argc = 2; - mwa->argv = os_malloc((unsigned)(mwa->argc + 1)*sizeof(char *)); - mwa->argv[0] = spliced; - mwa->argv[1] = (char*)uri; - mwa->argv[2] = NULL; + splicedThread->mwa->argc = 2; + splicedThread->mwa->argv = os_malloc((unsigned)(splicedThread->mwa->argc + 1)*sizeof(char *)); + splicedThread->mwa->argv[0] = spliced; + splicedThread->mwa->argv[1] = (char*)uri; + splicedThread->mwa->argv[2] = NULL; /* Invoke the spliced entry point as a new thread in the current process */ - osr = os_threadCreate(tid, spliced, &threadAttr, ut_entryPointWrapper, mwa); + osr = os_threadCreate(&splicedThread->tid, spliced, &threadAttr, splicedThreadWrapper, splicedThread); if (osr != os_resultSuccess) { result = U_RESULT_INTERNAL_ERROR; OS_REPORT(OS_ERROR,"user::u_domain::startSplicedInProcess",result, "Error starting thread for '%s'\n", spliced); + } else { + *spliced_thread = splicedThread; } } + if ((result != U_RESULT_OK) && + (splicedThread)) { + os_free(splicedThread->mwa); + os_free(splicedThread); + } + return result; } @@ -629,7 +755,7 @@ report_startup_message( char addrStr[100]; char infoStr[1024]; - os_sprintf(addrStr, "0x" PA_ADDRFMT, (PA_ADDRCAST)domainCfg->address); + os_sprintf(addrStr, "0x" PA_ADDRFMT, (PA_ADDRCAST)domainCfg->shmAttr.map_address); os_sprintf(infoStr, "%s" "Domain (id) : %s (%u)" OS_REPORT_NL @@ -656,13 +782,9 @@ report_startup_message( domainCfg->prioInherEnabled ? "true" : "false", systemId, domainCfg->systemIdConfig.min, domainCfg->systemIdConfig.max, domainCfg->systemIdConfig.entropy ? " (user entropy source present)" : ""); - OS_REPORT_WID(OS_INFO,"The OpenSplice domain service", 0, domainCfg->id, "%s", infoStr); + OS_REPORT_NOW(OS_INFO,"The OpenSplice domain service", 0, domainCfg->id, "%s", infoStr); } -/************************************************************** - * Public functions - **************************************************************/ - static u_result u__domainDeinitW(void *_this) { OS_UNUSED_ARG(_this); @@ -676,25 +798,126 @@ static void u__domainFreeW(void *_this) assert(0); } +static u_result +checkDomainId( + const u_domainId_t id) +{ + u_result result = U_RESULT_OK; + if ( (id != U_DOMAIN_ID_ANY) && ( (id < 0) || (id > 230))) { + result = U_RESULT_ILL_PARAM; + } + return result; +} + +static u_result +u_domainReadConfig( + u_domainConfig domainCfg, + const os_char *uri, + const os_boolean validate) +{ + u_result result = U_RESULT_OK; + + u_domainCfgInit(domainCfg, uri, U_DOMAIN_ID_DEFAULT); + if (uri != NULL) { + result = GetDomainConfig(domainCfg, validate); + if (result == U_RESULT_OK) { + if (processConfigAlreadySet == OS_FALSE) { + u_usrClockInit (domainCfg->processConfig); +#ifdef INCLUDE_PLUGGABLE_REPORTING + result = u_usrReportPluginReadAndRegister(domainCfg->processConfig, + domainCfg->id, &domainCfg->reportPlugins); + if (result != U_RESULT_OK) { + OS_REPORT_WID(OS_ERROR, "user::u_domain::u_domainReadConfig",result,domainCfg->id, + "ReportPlugin registration failed for Domain %s - return code %d\n", + domainCfg->name, result); + } +#endif + processConfigAlreadySet = OS_TRUE; + } + } + } + return result; +} + +static u_domain +u_domainAlloc( + v_kernel kernel, + u_domainConfig domainCfg, + os_sharedHandle shm) +{ + u_result result = U_RESULT_OK; + u_domain domain = NULL; + + domain = u_objectAlloc(sizeof(*domain), U_DOMAIN, u__domainDeinitW, u__domainFreeW); + if (domain == NULL) { + result = U_RESULT_OUT_OF_MEMORY; + OS_REPORT_WID(OS_ERROR, "user::u_domain::u_domainAlloc", U_RESULT_OUT_OF_MEMORY, domainCfg->id, + "initialization of configuration admin failed for domain %s.", domainCfg->name); + } else { + result = u_entityInit(u_entity(domain), v_entity(kernel), domain); + if (result != U_RESULT_OK) { + domain = NULL; + } + } + if (result == U_RESULT_OK) { + os_uint32 serial; + if (os_mutexInit(&domain->mutex, NULL) != os_resultSuccess) { goto err_init; } + if (os_condInit(&domain->cond, &domain->mutex, NULL) != os_resultSuccess) { goto err_init; } + if (os_mutexInit(&domain->deadlock, NULL) != os_resultSuccess) { goto err_init; } + os_mutexLock(&domain->deadlock); /* Don't unlock; deadlocks on purpose. */ + domain->openCount = 1; + domain->closing = 0; + pa_st32(&domain->refCount, 1); + domain->kernel = kernel; + domain->shm = shm; + domain->participants = NULL; + domain->waitsets = NULL; + domain->lockPolicy = domainCfg->lockPolicy; + domain->procInfo = v_kernelGetOwnProcessInfoWeakRef(kernel); + domain->protectCount = 0; + domain->inProcessExceptionHandling = domainCfg->inProcessExceptionHandling; + domain->y2038Ready = c_baseGetY2038Ready(c_getBase(kernel)); + domain->uri = (domainCfg->uri == NULL ? NULL : os_strdup(domainCfg->uri)); + domain->name = os_strdup(domainCfg->name); + domain->id = domainCfg->id; + assert(domain->id < 0xFF); + serial = pa_add32_nv(&domainSerial, 0x100); + assert((serial & 0xFF) == 0); + domain->procInfo->serial = serial | (c_ulong)domain->id; + /* Allow reading serial without accessing kernel */ + domain->serial = domain->procInfo->serial; + pa_st32(&domain->state, U_DOMAIN_STATE_ALIVE); + pa_st32(&domain->claimed, 0); + domain->reportPlugins = domainCfg->reportPlugins; + u_userAddDomain(domain); + } + return domain; + +err_init: + u_objectFree(domain); + return NULL; +} + +void +u__domainMutexInit() +{ + (void)os_mutexInit(&mutex, NULL); +} + u_result u_domainNew( u_domain *domain, const os_char *uri) { os_sharedHandle shm; - os_sharedAttr shm_attr; os_address sharedMemAddress = 0; c_base base; v_kernel kernel = NULL; u_result result; - cf_element processConfig; v_configuration configuration; v_cfElement rootElement; - v_processInfo procInfo; + v_processInfo procInfo = NULL; C_STRUCT(u_domainConfig) domainCfg; -#ifdef INCLUDE_PLUGGABLE_REPORTING - c_iter reportPlugins = NULL; -#endif #ifndef INTEGRITY os_result sharedMemLock = os_resultUnavailable; #endif @@ -703,89 +926,21 @@ u_domainNew( *domain = NULL; base = NULL; - processConfig = NULL; shm = NULL; - os_sharedAttrInit(&shm_attr); - domainCfg.name = NULL; result = u_userInitialise(); + os_report_stack_open(NULL, 0, NULL, NULL); if (result != U_RESULT_OK) { OS_REPORT(OS_ERROR, "u_domainNew",result, - "implicit u_userInitialise failed, result = %s, uri = %s", - u_resultImage(result), uri ? uri : "NULL"); - } -/* - * Initialize a temporary working set of default configuration values. - */ - if (result == U_RESULT_OK) { - domainCfg.lockPolicy = OS_LOCK_DEFAULT; - domainCfg.builtinTopicEnabled = TRUE; - domainCfg.prioInherEnabled = FALSE; - domainCfg.id = U_DOMAIN_ID_DEFAULT; - domainCfg.address = (os_address) shm_attr.map_address; - domainCfg.idReadFromConfig = FALSE; - domainCfg.heap = FALSE; - domainCfg.dbSize = DATABASE_SIZE; - domainCfg.dbFreeMemThreshold = DATABASE_FREE_MEM_THRESHOLD; - domainCfg.maintainObjectCount = 1; - domainCfg.inProcessExceptionHandling = TRUE; - domainCfg.name = os_strdup(DOMAIN_NAME); - domainCfg.systemIdConfig.min = 1; - domainCfg.systemIdConfig.max = 0x7fffffffu; - domainCfg.systemIdConfig.entropySize = 0; - domainCfg.systemIdConfig.entropy = NULL; - if (domainCfg.name == NULL) { - result = U_RESULT_OUT_OF_MEMORY; - OS_REPORT(OS_ERROR, "user::u_domain::u_domainNew",result, - "memory allocation failed, result = %s, uri = %s", - u_resultImage(result), uri ? uri : "NULL"); - } - } -/* - * Read the actual Configuration values specified by the URI. - */ - if ((result == U_RESULT_OK) && (uri != NULL)) { - if (strlen(uri) > 0) { - cfgprs_status s; - s = cfg_parse_ospl(uri, &processConfig); - if (s == CFGPRS_OK) { - s = cfg_validateConfiguration(processConfig); - } - if (s == CFGPRS_OK) { - GetDomainConfig(processConfig, &domainCfg, &shm_attr); - if ((domainCfg.id >= 0 ) && (domainCfg.id <= 230)) { - if (processConfigAlreadySet == OS_FALSE) { - u_usrClockInit (processConfig); - #ifdef INCLUDE_PLUGGABLE_REPORTING - result = u_usrReportPluginReadAndRegister(processConfig, domainCfg.id, &reportPlugins); - #endif - if (result != U_RESULT_OK) { - OS_REPORT_WID(OS_ERROR, "user::u_domain::u_domainNew",result, domainCfg.id, - "ReportPlugin registration failed for Domain %s - return code %d\n", - domainCfg.name, result); - } - processConfigAlreadySet = OS_TRUE; - } - } else { - result = U_RESULT_ILL_PARAM; - OS_REPORT(OS_ERROR, "user::u_domain::u_domainNew", result, - "Invalid value for domainId in configuration from URI: \"%s\". Valid values are from 0 to 230, value used = %d", uri, domainCfg.id ); - } - } else { - result = U_RESULT_ILL_PARAM; - OS_REPORT(OS_ERROR, "user::u_domain::u_domainNew", result, - "Syntax error in configuration from URI: \"%s\".",uri); - } - } else { - result = U_RESULT_ILL_PARAM; - OS_REPORT(OS_ERROR, "user::u_domain::u_domainNew", result, - "Invalid URI specified: \"%s\".",uri); - } + "u_userInitialise failed, result = %s, uri = %s", + u_resultImage(result), uri ? uri : "NULL"); + return result; } -/* - * Sanity check, a domain can only be create once so if it already exists this - * operation is already executed before by this process and this call will be aborted. - */ + /* Read the actual Configuration values specified by the URI. */ + result = u_domainReadConfig(&domainCfg, uri, OS_TRUE); + /* Sanity check, a domain can only be create once so if it already exists this + * operation is already executed before by this process and this call will be aborted. + */ if (result == U_RESULT_OK) { u_domain dom; if ((dom = u_userLookupDomain(domainCfg.id)) != NULL) { @@ -796,9 +951,7 @@ u_domainNew( (void)u_domainClose(dom); } } -/* - * Initialize (shared) memory configuration. - */ + /* Initialize (shared) memory configuration.*/ if (result == U_RESULT_OK) { if (domainCfg.heap == TRUE) { os_serviceSetSingleProcess(); @@ -806,18 +959,15 @@ u_domainNew( /* start for windows the named pipe : only required when multiple * processes require communication. */ - if (os_serviceStart(domainCfg.name) == os_resultSuccess) - { - shm = os_sharedCreateHandle(domainCfg.name, &shm_attr, domainCfg.id); + if (os_serviceStart(domainCfg.name) == os_resultSuccess) { + shm = os_sharedCreateHandle(domainCfg.name, &domainCfg.shmAttr, domainCfg.id); if (shm == NULL) { result = U_RESULT_UNDEFINED; OS_REPORT_WID(OS_ERROR, "user::u_domain::u_domainNew", result, domainCfg.id, "os_sharedCreateHandle failed for domain %s.", domainCfg.name); } - } - else - { + } else { result = U_RESULT_UNDEFINED; OS_REPORT_WID(OS_ERROR, "user::u_domain::u_domainNew", result, domainCfg.id, "Create service pipe failed for domain %s, " @@ -896,9 +1046,7 @@ u_domainNew( } } } -/* - * Create Domain Database in initialized memory. - */ + /* Create Domain Database in initialized memory. */ if (result == U_RESULT_OK) { base = c_create(DATABASE_NAME, (c_voidp)sharedMemAddress, @@ -909,8 +1057,7 @@ u_domainNew( } } #ifndef INTEGRITY - /* - * succesfull created file handle is 0 or greater. Failed situation gives -1 + /* succesfull created file handle is 0 or greater. Failed situation gives -1 * If file handle isn't -2 anymore, it is used at creation. Always delete to * prevent stale files. */ @@ -918,10 +1065,9 @@ u_domainNew( os_sharedMemoryUnlock(shm); } #endif -/* - * Initialize Domain administration (Kernel) in the Domain Database in disabled state. Attaching processes - * will be blocked until enabled. - */ + /* Initialize Domain administration (Kernel) in the Domain Database in disabled state. Attaching processes + * will be blocked until enabled. + */ if (result == U_RESULT_OK) { C_STRUCT(v_kernelQos) kernelQos; c_baseSetMaintainObjectCount (base, domainCfg.maintainObjectCount); @@ -933,18 +1079,9 @@ u_domainNew( OS_REPORT_WID(OS_ERROR, "user::u_domain::u_domainNew",result,domainCfg.id, "v_kernelNew failed for domain %s.", domainCfg.name); - } else { - os_uint32 serial; - - serial = pa_add32_nv(&domainSerial, 0x100); - assert(domainCfg.id < 0xFF); - assert((serial & 0xFF) == 0); - procInfo->serial = serial | (c_ulong)domainCfg.id; } } -/* - * Copy configuration to Domain administration (Kernel). - */ + /* Copy configuration to Domain administration (Kernel). */ if (result == U_RESULT_OK) { configuration = v_configurationNew(kernel); if (configuration == NULL) { @@ -955,7 +1092,7 @@ u_domainNew( } if (result == U_RESULT_OK) { rootElement = NULL; - result = copyConfiguration(cf_node(processConfig), + result = copyConfiguration(cf_node(domainCfg.processConfig), configuration, (v_cfNode *)&rootElement); if (result != U_RESULT_OK) { @@ -979,56 +1116,25 @@ u_domainNew( } } } -/* - * Enable the kernel, so attaching processes will proceed with a config loaded kernel. - */ + /* Enable the kernel, so attaching processes will proceed with a config loaded kernel. */ if (result == U_RESULT_OK) { - v_kernelEnable(kernel, KERNEL_NAME); + v_entityEnable(v_entity(kernel)); } - -/* - * Create a local Domain proxy interface. - */ + /* Create a local Domain proxy interface. */ if (result == U_RESULT_OK) { - *domain = u_objectAlloc(sizeof(**domain), U_DOMAIN, u__domainDeinitW, u__domainFreeW); - u_userSetupSignalHandling(TRUE); - result = u_entityInit(u_entity(*domain), v_entity(kernel), *domain); - os_mutexInit(&(*domain)->mutex, NULL); - os_condInit(&(*domain)->cond, &(*domain)->mutex, NULL); - os_mutexInit(&(*domain)->deadlock, NULL); - os_mutexLock(&(*domain)->deadlock); /* Don't unlock; deadlocks on purpose. */ - (*domain)->openCount = 1; - (*domain)->closing = 0; - pa_st32(&(*domain)->refCount, 1); - (*domain)->kernel = kernel; - (*domain)->shm = shm; - (*domain)->participants = NULL; - (*domain)->waitsets = NULL; - (*domain)->lockPolicy = domainCfg.lockPolicy; - (*domain)->procInfo = procInfo; - (*domain)->serial = procInfo->serial; - (*domain)->inProcessExceptionHandling = domainCfg.inProcessExceptionHandling; - (*domain)->y2038Ready = c_baseGetY2038Ready(c_getBase(kernel)); - - if (uri == NULL) { - (*domain)->uri = NULL; - } else { - (*domain)->uri = os_strdup(uri); + *domain = u_domainAlloc(kernel, &domainCfg, shm); + if (*domain == NULL) { + result = U_RESULT_INTERNAL_ERROR; } - (*domain)->name = os_strdup(domainCfg.name); - (*domain)->id = domainCfg.id; + } + if (result == U_RESULT_OK) { + u_userSetupSignalHandling(TRUE); (*domain)->owner = TRUE; - pa_st32(&(*domain)->state, U_DOMAIN_STATE_ALIVE); - pa_st32(&(*domain)->claimed, 0); (*domain)->isService = TRUE; (*domain)->threadWithAccess = OS_THREAD_ID_NONE; -#ifdef INCLUDE_PLUGGABLE_REPORTING - (*domain)->reportPlugins = reportPlugins; - reportPlugins = NULL; -#endif + (*domain)->serviceTerminatePeriod = domainCfg.serviceTerminatePeriod; - u_userAddDomain(*domain); report_startup_message(&domainCfg, kernel->GID.systemId); if((*domain)->inProcessExceptionHandling == FALSE){ @@ -1038,26 +1144,27 @@ u_domainNew( } if ((result != U_RESULT_OK) && (shm != NULL)) { /* Don't detach or destroy shared memory when another domain has - * created it. */ + * created it. + */ if (result != U_RESULT_PRECONDITION_NOT_MET) { os_sharedMemoryDetach(shm); os_sharedMemoryDestroy(shm); } os_sharedDestroyHandle(shm); } - if (processConfig != NULL) { - cf_elementFree(processConfig); + if (domainCfg.processConfig != NULL) { + cf_elementFree(domainCfg.processConfig); } if (domainCfg.name != NULL) { os_free(domainCfg.name); } -#ifdef INCLUDE_PLUGGABLE_REPORTING - if (reportPlugins != NULL) { + if (result != U_RESULT_OK && domainCfg.reportPlugins != NULL) { /* report plugins not registered on domain ? */ - u_usrReportPluginUnregister(reportPlugins); - c_iterFree(reportPlugins); + u_usrReportPluginUnregister(domainCfg.reportPlugins); + c_iterFree(domainCfg.reportPlugins); } -#endif + os_report_flush(result != U_RESULT_OK, "u_domainNew", __FILE__, __LINE__, domainCfg.id); + return result; } @@ -1077,7 +1184,7 @@ onSharedMemoryServerDied( if (!domain->isService) { OS_REPORT(OS_INFO, "user::u_domain::onSharedMemoryServerDied", 0, - "Shared memory server not running anymore, detaching from domain \"%s\".", domain->name); + "Spliced not running anymore, detaching from domain \"%s\".", domain->name); idx = u__userDomainIndex(domain); if (idx > 0) { u_result result; @@ -1091,8 +1198,61 @@ onSharedMemoryServerDied( } else { OS_REPORT(OS_INFO, "user::u_domain::onSharedMemoryServerDied", 0, - "Shared memory server not running anymore for domain \"%s\".", domain->name); + "Spliced not running anymore for domain \"%s\".", domain->name); + } +} + + +static u_domain +startProcessDomain( + u_domainConfig domainCfg) +{ + os_duration delay_100ms = OS_DURATION_INIT(0, 100000000); + u_splicedThread spliced_thread = NULL; + u_domain domain = NULL; + u_result result = U_RESULT_OK; + os_uint32 sleepCounter = 0; + os_uint32 initCount; + + /* in case multiple participants are created at the same time only 1 can start spliced */ + initCount = pa_inc32_nv(&_ospl_SplicedInitCount); + if (initCount == 1) { + result = startSplicedWithinProcess(&spliced_thread, domainCfg->uri); + if (result == U_RESULT_OK) { + /* wait for up to 10 seconds for the domain to be available in this process */ + while ((domain = u_userLookupDomain(domainCfg->id)) == NULL && (++sleepCounter < 100)) { + ospl_os_sleep(delay_100ms); + } + if (domain) { + domain->spliced_thread = spliced_thread; + } + } +#if 1 +{ + /* This piece of code is black magic, without it durability sometimes fail to become complete. + * This code replaces historical code which was already in without a clear description. + * Must be replaced to avoid unwanted delays and possible failures by a proper synchronisation. + */ + int n; + for (n=0; n<10; n++) { + ospl_os_sleep(delay_100ms); + } +} +#endif + pa_dec32(&_ospl_SplicedInitCount); + } else { + pa_dec32(&_ospl_SplicedInitCount); + /* wait for up to 30 seconds for the spliced to be available in this process */ + while ((domain = u_userLookupDomain(domainCfg->id)) == NULL && (++sleepCounter < 300)) { + ospl_os_sleep(delay_100ms); + } + } + if (domain == NULL) { + OS_REPORT_WID(OS_ERROR,"user::u_domain::startSpliceThread",result,domainCfg->id, + "Failed to start Spliced for domain '%s' within %d seconds, result = %s\n", + domainCfg->name, sleepCounter / 10, u_resultImage(result)); } + return domain; } @@ -1102,428 +1262,305 @@ u__userDetachWrapper(void) u_userDetach(U_USER_DELETE_ENTITIES); } -u_result -u__domainOpen( - u_domain *domain, - const os_char *uri, - const u_domainId_t id, - const u_bool isService, +static os_sharedHandle +attachSharedMemory( + u_domainConfig domainCfg, os_int32 timeout) { + os_duration pollDelay = OS_DURATION_INIT(0,100000000); os_sharedHandle shm = NULL; - os_sharedAttr shm_attr; - u_result result; - cf_element processConfig; - os_threadId spliced_thread = OS_THREAD_ID_NONE; - C_STRUCT(u_domainConfig) domainCfg; - v_processInfo procInfo; -#ifdef INCLUDE_PLUGGABLE_REPORTING - /** @todo - Fix properly. See: OSPL-1222 */ - static os_boolean singleProcessLoggerRegDoneHack = OS_FALSE; - c_iter reportPlugins = NULL; -#endif - os_char *name; - os_char *config_source = "specified by process"; - assert(domain != NULL); - *domain = NULL; + os_char *name = NULL; + os_result osr; -/* - * Initialize a temporary working set of default configuration values. - */ - if ( (id != U_DOMAIN_ID_ANY) && ((id < 0) || (id > 230))) { - OS_REPORT(OS_ERROR, "user::u_domain::u_domainOpen",U_RESULT_ILL_PARAM, - "Invalid value for domainId passed to domain open. Valid values are from 0 to 230, value used = %d", id ); - return U_RESULT_ILL_PARAM; - } - domainCfg.lockPolicy = OS_LOCK_DEFAULT; - domainCfg.builtinTopicEnabled = TRUE; - domainCfg.prioInherEnabled = FALSE; - domainCfg.id = id; - domainCfg.address = 0; /* NULL */ - domainCfg.idReadFromConfig = FALSE; - domainCfg.heap = FALSE; - /* DATABASE_SIZE is default in shm mode. - * In singleprocess mode this is set back to 0 as default if no size is configured*/ - domainCfg.dbSize = DATABASE_SIZE; - domainCfg.dbFreeMemThreshold = DATABASE_FREE_MEM_THRESHOLD; - domainCfg.inProcessExceptionHandling = TRUE; - domainCfg.name = os_strdup(DOMAIN_NAME); - domainCfg.systemIdConfig.min = 1; - domainCfg.systemIdConfig.max = 0x7fffffffu; - domainCfg.systemIdConfig.entropySize = 0; - domainCfg.systemIdConfig.entropy = NULL; - if (domainCfg.name == NULL) { - OS_REPORT(OS_ERROR, "user::u_domain::u_domainOpen",U_RESULT_OUT_OF_MEMORY, - "memory allocation failed, result = U_RESULT_OUT_OF_MEMORY"); - return U_RESULT_OUT_OF_MEMORY; + /* Create a shm handle based on the configuration */ + shm = os_sharedCreateHandle(domainCfg->name, &(domainCfg->shmAttr), domainCfg->id); + if (shm == NULL) { + OS_REPORT_WID(OS_ERROR, "user::u_domain::attachSharedMemory", U_RESULT_INTERNAL_ERROR, + domainCfg->id, "Operation os_sharedCreateHandle failed"); + } else { + /* Try to get the shm domain name from the existing shared memory segment. */ + if (os_sharedMemoryGetNameFromId(shm,&name) == os_resultSuccess) { + if ((name != NULL) && (strlen(name)>0) && (strcmp(domainCfg->name,name) != 0)){ + /* Apperently the configured domain name does not match the actual name used by the available + * domain which is identified by the domain id. + * Now use the actual name for the shm handle otherwise attaching to shared memory will fail. + */ + (void)os_sharedDestroyHandle(shm); + shm = os_sharedCreateHandle(name, &(domainCfg->shmAttr), domainCfg->id); + if (shm == NULL) { + OS_REPORT_WID(OS_ERROR, "user::u_domain::attachSharedMemory", U_RESULT_INTERNAL_ERROR, + domainCfg->id, "Operation os_sharedCreateHandle failed"); + } + } else { + os_free(name); + } + } } - - result = u_userInitialise(); - if (result != U_RESULT_OK) { - OS_REPORT(OS_ERROR, - "user::u_domain::u_domainOpen",result, - "u_userInitialise failed, result = %s", u_resultImage(result)); - return result; + /* Try to attach to existing shared memory segment. */ + if (shm) { + osr = os_sharedMemoryAttach(shm); + IGNORE_THREAD_MESSAGE; + while ((timeout > 0) && (osr != os_resultSuccess)) { + ospl_os_sleep(pollDelay); + osr = os_sharedMemoryAttach(shm); + timeout--; + PRINT_THREAD_MESSAGE("u_domainOpen"); + } + if (osr != os_resultSuccess) { + (void)os_sharedDestroyHandle(shm); + shm = NULL; + OS_REPORT_WID(OS_ERROR, + "user::u_domain::attachSharedMemory", + U_RESULT_INTERNAL_ERROR, domainCfg->id, + "Cannot connect to domainId (%d) and domainName (%s).\n " + "Please make sure to start OpenSplice before creating a DomainParticipant.", + domainCfg->id, domainCfg->name?domainCfg->name:"No name specified"); + } } - processConfig = NULL; - os_sharedAttrInit(&shm_attr); + return shm; +} -/* - * If uri is NULL then try to get uri from environment - */ - if (uri == NULL) { - uri = os_getenv ("OSPL_URI"); - } - if (uri) { - if (strlen(uri) == 0) { - uri = NULL; +/* Try to open existing Domain Database. */ +static u_domain +attachToFederatedDomain( + u_domainConfig domainCfg, + os_boolean isService, + os_int32 timeout) +{ + os_duration pollDelay = OS_DURATION_INIT(0,100000000); + os_sharedHandle shm = NULL; + u_splicedThread spliced_thread = NULL; + c_base base = NULL; + v_kernel kernel = NULL; + const os_char *uri = NULL; + v_configuration config = NULL; + u_domain domain = NULL; + u_result result = U_RESULT_OK; + v_processInfo procInfo = NULL; + + timeout = timeout * 10; /* convert timeout from second domain to 100ms domain. */ + /* Attach to federated Domain (shared memory connection). */ + assert(!domainCfg->heap); + /* set pipename for windows */ + os_createPipeNameFromDomainName(domainCfg->name); + shm = attachSharedMemory(domainCfg, timeout); + if (shm == NULL) { + OS_REPORT_WID(OS_ERROR, "user::u_domain::attachToFederatedDomain", result, + domainCfg->id, "Attach to shared memory segment failed"); + result = U_RESULT_INTERNAL_ERROR; + } else { + /* Try to open existing Domain Database. */ + while ((base = c_open(DATABASE_NAME, os_sharedAddress(shm))) == NULL && timeout > 0) { + ospl_os_sleep(pollDelay); + timeout--; + } + if (base == NULL) { + result = U_RESULT_INTERNAL_ERROR; + OS_REPORT_WID(OS_ERROR, "user::u_domain::attachToFederatedDomain", result, + domainCfg->id, "Creation of internal Domain Database failed."); } else { - config_source = "specified by OSPL_URI"; + /* Try to attach to existing Domain administration (kernel). */ + kernel = v_kernelAttach(base, KERNEL_NAME, (timeout*pollDelay), &procInfo); + if (kernel == NULL) { + result = U_RESULT_INTERNAL_ERROR; + OS_REPORT_WID(OS_ERROR, "user::u_domain::attachToFederatedDomain", result, + domainCfg->id, "v_kernelAttach failed"); + } } } -#ifdef CONF_PARSER_NOFILESYS - if ( uri == NULL ) - { - uri = os_strdup("osplcfg://ospl.xml"); - } -#endif -/* - * If a uri is specified then read the actual configuration. - */ - if (result == U_RESULT_OK) { - if (uri != NULL) { + /* Try to find uri from shared memory when not set. */ + if ((result == U_RESULT_OK) && (domainCfg->uri == NULL)) { + config = v_getConfiguration(kernel); + uri = v_configurationGetUri(config); + if (uri != NULL && (strlen(uri) > 0)) { cfgprs_status s; - /* Do we have to free processConfig just like in u_domainNew()??? */ + cf_element processConfig = NULL; s = cfg_parse_ospl(uri, &processConfig); if (s == CFGPRS_OK) { - GetDomainConfig(processConfig, &domainCfg, &shm_attr); - if ( (domainCfg.id == U_DOMAIN_ID_ANY) || ( (domainCfg.id >= 0) && (domainCfg.id <= 230))) { - if (processConfigAlreadySet == OS_FALSE) { - u_usrClockInit (processConfig); - if (domainCfg.prioInherEnabled) { - os_mutexSetPriorityInheritanceMode(OS_TRUE); - } - #ifdef INCLUDE_PLUGGABLE_REPORTING - /** @todo - Fix properly. See: OSPL-1222 */ - if (!domainCfg.heap || singleProcessLoggerRegDoneHack == OS_FALSE) { - result = u_usrReportPluginReadAndRegister(processConfig, domainCfg.id, &reportPlugins); - if (result != U_RESULT_OK) { - OS_REPORT_WID(OS_ERROR, "user::u_domain::u_domainOpen",result,domainCfg.id, - "ReportPlugin registration failed for Domain %s - return code %d\n", - domainCfg.name, result); - } - } - #endif - processConfigAlreadySet = OS_TRUE; - } - } else { - result = U_RESULT_ILL_PARAM; - OS_REPORT(OS_ERROR, "user::u_domain::u_domainNew", result, - "Invalid value for domainId in configuration from URI: \"%s\". Valid values are from 0 to 230, value used = %d", uri, domainCfg.id ); +#ifdef INCLUDE_PLUGGABLE_REPORTING + /** @todo - Fix properly. See: OSPL-1222 */ + result = u_usrReportPluginReadAndRegister(processConfig, + domainCfg->id, + &domainCfg->reportPlugins); + if (result != U_RESULT_OK) { + OS_REPORT_WID(OS_ERROR, "user::u_domain::attachToFederatedDomain",result,domainCfg->id, + "ReportPlugin registration failed for Domain %s - return code %d\n", + domainCfg->name, result); } +#endif cf_elementFree(processConfig); - } else { - result = U_RESULT_ILL_PARAM; - OS_REPORT(OS_ERROR, "user::u_domain::u_domainOpen",result, - "Error in configuration file \'%s\' %s\n", - uri, config_source); } - } else { - /* No uri specified so domainCfg.id could not be found so reset it to any. */ - domainCfg.id = U_DOMAIN_ID_ANY; } } + /* Create a local Domain proxy interface. */ + if (result == U_RESULT_OK) { + domain = u_domainAlloc(kernel, domainCfg, shm); + if (domain == NULL) { + result = U_RESULT_INTERNAL_ERROR; + } + } + if (result == U_RESULT_OK) { + u_userSetupSignalHandling(isService); + domain->owner = FALSE; + domain->isService = isService; + domain->spliced_thread = spliced_thread; + if (!domain->isService) { + char name[256]; + os_procGetProcessName(name, sizeof(name)); + OS_REPORT_NOW(OS_INFO, OS_FUNCTION, 0, domain->id, + "Process '%s' <%d> attached to shared memory", + name, os_procIdSelf()); + } + } + if (result == U_RESULT_OK) { + os_result osres; + osres = os_sharedMemoryRegisterServerDiedCallback(shm, onSharedMemoryServerDied, domain); + if (osres != os_resultSuccess && osres != os_resultUnavailable) { + result = U_RESULT_INTERNAL_ERROR; + OS_REPORT_WID(OS_ERROR, "user::u_domain::attachToFederatedDomain", result, + domainCfg->id, "Failed to register server died callback for domain %s.", + domainCfg->name); + } + } + if (result != U_RESULT_OK) { + if (shm) { + (void)os_sharedMemoryDetach(shm); + (void)os_sharedDestroyHandle(shm); + if (domain) { + (void)u_userRemoveDomain(domain); + (void)u_domainFree(domain); + domain = NULL; + } + } + } + return domain; +} + +u_result +u__domainOpen( + u_domain *domain, + const os_char *uri, + const u_domainId_t id, + const u_bool isService, + os_int32 timeout) +{ + u_result result; + C_STRUCT(u_domainConfig) domainCfg; + assert(domain != NULL); + *domain = NULL; + + /* Initialize a temporary working set of default configuration values. */ + result = u_userInitialise(); + if (result != U_RESULT_OK) { + OS_REPORT(OS_ERROR, "user::u_domain::u_domainOpen",result, + "u_userInitialise failed, result = %s", u_resultImage(result)); + return result; + } + + /* If uri is NULL then try to get uri from environment */ + if (uri == NULL) { + uri = os_getenv ("OSPL_URI"); + } + if (uri && strlen(uri) == 0) { + uri = NULL; + } +#ifdef CONF_PARSER_NOFILESYS + if (uri == NULL) { + uri = os_strdup("osplcfg://ospl.xml"); + } +#endif + /* Iinialize domain config and load from uri if specified. */ + result = checkDomainId(id); if (result == U_RESULT_OK) { - if (id == U_DOMAIN_ID_ANY) { - /* Any id is ok to connect to. */ - if (domainCfg.id == U_DOMAIN_ID_ANY) { - /* domain not specified neither by parameter nor by configuration. - * So use default domain. - */ - domainCfg.id = U_DOMAIN_ID_DEFAULT; - } else { - /* A domain id is found in the given configuration - * so will connect to that domain. - */ - } - } else { - /* A specific domain id is requested. */ - if (domainCfg.id != id) { - /* did not yet found a domain configuration for the requested id. */ - /* So create a temporary shm handle and try to discover the id in running domains. */ + result = u_domainReadConfig(&domainCfg, uri, OS_FALSE); + if (result == U_RESULT_OK) { + if (id != U_DOMAIN_ID_ANY) { domainCfg.id = id; - shm = os_sharedCreateHandle(domainCfg.name, &shm_attr,domainCfg.id); - if (os_sharedMemoryGetNameFromId(shm,&name) == os_resultSuccess) { - if ((name != NULL) && (strlen(name)>0)){ - os_free(domainCfg.name); - domainCfg.name = name; - } else { - os_free(name); - } - } else { - /* The requested domain id is also not found in running domains - * so cannot connect to the domain. - */ - result = U_RESULT_PRECONDITION_NOT_MET; - } - (void)os_sharedDestroyHandle(shm); } + } else { + OS_REPORT(OS_ERROR, "u__domainOpen", result, + "Failed to initialize domain configuration for domain %d", + id); + goto err_domainConfig; } + } else { + OS_REPORT(OS_ERROR, "u__domainOpen", result, + "Given value %d for domainId is invalid, valid values are from 0 to 230", + id); + goto err_domainConfig; } -/* - * Check if the domain is already attached to the process. - */ + /* Check if the domain is already attached to the process. */ if (result == U_RESULT_OK) { *domain = u_userLookupDomain(domainCfg.id); if (*domain != NULL) { if ((*domain)->kernel->splicedRunning == FALSE) { /* Found domain is not running, mark as state - * and detach from shared memory. */ - result = u__userDomainDetach(u__userDomainIndex(*domain), TRUE); - if (result != U_RESULT_OK) { - OS_REPORT_WID(OS_INFO, - "user::u_domain::u_domainOpen",result,domainCfg.id, - "Detaching from already attached domain failed, result = %s", u_resultImage(result)); + * and detach from shared memory. + */ + result = u__userDomainDetach(u__userDomainIndex(*domain), TRUE); + if (result != U_RESULT_OK) { + OS_REPORT_WID(OS_INFO, "user::u_domain::u_domainOpen",result,domainCfg.id, + "Detaching from already attached domain failed, result = %s", + u_resultImage(result)); result = U_RESULT_OK; /* Ignore failure for now. */ - } + } *domain = NULL; } else { - os_free(domainCfg.name); + if (domainCfg.processConfig != NULL) { + cf_elementFree(domainCfg.processConfig); + } + if (domainCfg.name != NULL) { + os_free(domainCfg.name); + } return U_RESULT_OK; } } } -/* - * Start attaching to the domain. - */ + /* Start attaching to the domain. */ if (result == U_RESULT_OK) { if (domainCfg.prioInherEnabled) { os_mutexSetPriorityInheritanceMode(OS_TRUE); } + } + if (result == U_RESULT_OK) { if (domainCfg.heap) { -/* - * Startup Single process Domain. - */ - /* Start the signal handler to only handle exit signals */ - u_userSetupSignalHandling(FALSE); - result = startSplicedWithinProcess(&spliced_thread, uri); - if (result == U_RESULT_OK) { - int count = 0; - os_duration delay_100ms = OS_DURATION_INIT(0, 100000000); - - /* wait for up to 5 seconds for the domain to be available in this process */ - while (count < 50) { - os_sleep(delay_100ms); - if (*domain == NULL) { - *domain = u_userLookupDomain(domainCfg.id); - } - if ((*domain != NULL) && (count > 10)) { - os_free(domainCfg.name); - (*domain)->spliced_thread = spliced_thread; -#ifdef INCLUDE_PLUGGABLE_REPORTING - (*domain)->reportPlugins = reportPlugins; -#endif - return U_RESULT_OK; - } - count++; - } - result = U_RESULT_INTERNAL_ERROR; - OS_REPORT_WID(OS_ERROR,"user::u_domain::u_domainOpen",result,domainCfg.id, - "Domain '%s' has not been started successfully\n", domainCfg.name); - } else { - OS_REPORT_WID(OS_ERROR,"user::u_domain::u_domainOpen",result,domainCfg.id, - "Starting Domain '%s' failed, result = %s\n", - domainCfg.name, u_resultImage(result)); - } + /* Startup Single process Domain. */ + u_userSetupSignalHandling(FALSE); /* Start the signal handler to only handle exit signals */ + *domain = startProcessDomain(&domainCfg); } else { -/* - * Attach to federated Domain (shared memory connection). - */ + /* On a regular exit of an application, all SHM entities should + * be properly cleaned up (and more importantly, there should be + * no more threads accessing SHM). This is a fallback case for + * when the application doesn't properly clean up the resources. + * + * This only needs to be done at first connection to a SHM domain, + * but that's a minor optimisation. + */ + os_procAtExit(&u__userDetachWrapper); - /* On a regular exit of an application, all SHM entities should - * be properly cleaned up (and more importantly, there should be - * no more threads accessing SHM). This is a fallback case for - * when the application doesn't properly clean up the resources. - * - * This only needs to be done at first connection to a SHM domain, - * but that's a minor optimisation. */ - os_procAtExit(&u__userDetachWrapper); - - /* set pipename for windows */ - os_createPipeNameFromDomainName(domainCfg.name); - shm = os_sharedCreateHandle(domainCfg.name, &shm_attr,domainCfg.id); - if (shm == NULL) { - result = U_RESULT_INTERNAL_ERROR; - OS_REPORT_WID(OS_ERROR, "user::u_domain::u_domainOpen",result,domainCfg.id, - "Operation os_sharedCreateHandle failed"); - } + /* Attach to federated Domain (shared memory connection). */ + *domain = attachToFederatedDomain(&domainCfg, isService, timeout); } -/* - * Try to attach to existing shared memory segment. - */ - if (result == U_RESULT_OK) { - os_duration pollDelay = OS_DURATION_INIT(1,0); - os_result osr; - - osr = os_sharedMemoryAttach(shm); - IGNORE_THREAD_MESSAGE; - while ((timeout > 0) && (osr != os_resultSuccess)) { - os_sleep(pollDelay); - osr = os_sharedMemoryAttach(shm); - timeout--; - PRINT_THREAD_MESSAGE("u_domainOpen"); - } - if (osr != os_resultSuccess) { - result = U_RESULT_INTERNAL_ERROR; - OS_REPORT_WID(OS_ERROR, - "user::u_domain::u_domainOpen",result,domainCfg.id, - "os_sharedMemoryAttach failed for domainId (%d) and domainName (%s)", - domainCfg.id, domainCfg.name?domainCfg.name:"No name specified"); - } -/* - * Try to open existing Domain Database. - */ - if (result == U_RESULT_OK) { - c_base base; - v_kernel kernel; - - base = c_open(DATABASE_NAME, os_sharedAddress(shm)); - while ((timeout > 0) && (base == NULL)) { - os_sleep(pollDelay); - base = c_open(DATABASE_NAME, os_sharedAddress(shm)); - timeout--; - } - if (base == NULL) { - result = U_RESULT_INTERNAL_ERROR; - OS_REPORT_WID(OS_ERROR, "user::u_domain::u_domainOpen",result,domainCfg.id, - "Creation of internal Domain Database failed."); - } -/* - * Try to attach to existing Domain administration (kernel). - */ - if (result == U_RESULT_OK) { - kernel = v_kernelAttach(base, KERNEL_NAME, &procInfo); - while ((timeout > 0) && (kernel == NULL)) { - os_sleep(pollDelay); - kernel = v_kernelAttach(base, KERNEL_NAME, &procInfo); - timeout--; - } - if (kernel == NULL) { - result = U_RESULT_INTERNAL_ERROR; - OS_REPORT_WID(OS_ERROR, - "user::u_domain::u_domainOpen", result,domainCfg.id, - "v_kernelAttach failed"); - } else { - os_uint32 serial; - - serial = pa_add32_nv(&domainSerial, 0x100); - assert(domainCfg.id < 0xFF); - assert((serial & 0xFF) == 0); - procInfo->serial = serial | (c_ulong)domainCfg.id; - } - } - -/* - * Try to find uri from shared memory when not set. - */ - if ((result == U_RESULT_OK) && - (uri == NULL)) { - v_configuration config = v_getConfiguration(kernel); - uri = v_configurationGetUri(config); - if (uri != NULL && (strlen(uri) > 0)) { - cfgprs_status s; - s = cfg_parse_ospl(uri, &processConfig); - if (s == CFGPRS_OK) { -#ifdef INCLUDE_PLUGGABLE_REPORTING - /** @todo - Fix properly. See: OSPL-1222 */ - if (singleProcessLoggerRegDoneHack == OS_FALSE) { - result = u_usrReportPluginReadAndRegister(processConfig, domainCfg.id, &reportPlugins); - if (result != U_RESULT_OK) { - OS_REPORT_WID(OS_ERROR, "user::u_domain::u_domainOpen",result,domainCfg.id, - "ReportPlugin registration failed for Domain %s - return code %d\n", - domainCfg.name, result); - } - } -#endif - cf_elementFree(processConfig); - } - } - } -/* - * Create a local Domain proxy interface. - */ - if (result == U_RESULT_OK) { - *domain = u_objectAlloc(sizeof(**domain), U_DOMAIN, u__domainDeinitW, u__domainFreeW); - if (*domain == NULL) { - result = U_RESULT_OUT_OF_MEMORY; - OS_REPORT_WID(OS_ERROR, "user::u_domain::u_domainOpen",result,domainCfg.id, - "initialization of configuration admin failed for domain %s.", - domainCfg.name); - } else { - u_userSetupSignalHandling(isService); - result = u_entityInit(u_entity(*domain), v_entity(kernel), *domain); - os_mutexInit(&(*domain)->mutex, NULL); - os_condInit(&(*domain)->cond, &(*domain)->mutex, NULL); - os_mutexInit(&(*domain)->deadlock, NULL); - os_mutexLock(&(*domain)->deadlock); /* Don't unlock; deadlocks on purpose. */ - (*domain)->openCount = 1; - (*domain)->closing = 0; - pa_st32(&(*domain)->refCount, 1); - (*domain)->kernel = kernel; - (*domain)->shm = shm; - (*domain)->procInfo = procInfo; - (*domain)->protectCount = 0; - (*domain)->serial = procInfo->serial; - (*domain)->participants = NULL; - (*domain)->waitsets = NULL; - (*domain)->lockPolicy = OS_LOCK_DEFAULT; /* don't care! */ - (*domain)->inProcessExceptionHandling = domainCfg.inProcessExceptionHandling; - (*domain)->y2038Ready = c_baseGetY2038Ready(c_getBase(kernel)); - (*domain)->id = domainCfg.id; - (*domain)->owner = FALSE; - pa_st32(&(*domain)->state, U_DOMAIN_STATE_ALIVE); - pa_st32(&(*domain)->claimed, 0); - (*domain)->isService = isService; - (*domain)->spliced_thread = spliced_thread; -#ifdef INCLUDE_PLUGGABLE_REPORTING - (*domain)->reportPlugins = reportPlugins; -#endif - /* Recheck 'uri', maybe it is retrieved from v_configuration */ - if (uri != NULL) { - (*domain)->uri = os_strdup(uri); - } else { - (*domain)->uri = NULL; - } - (*domain)->name = os_strdup(domainCfg.name); - u_userAddDomain(*domain); - } - } - if (result != U_RESULT_OK) { - (void)os_sharedMemoryDetach(shm); - } - } - if (result != U_RESULT_OK) { - (void)os_sharedDestroyHandle(shm); - } + if (*domain == NULL) { + result = U_RESULT_INTERNAL_ERROR; } } - if (result == U_RESULT_OK) { - os_result osres = os_sharedMemoryRegisterServerDiedCallback(shm, onSharedMemoryServerDied, *domain); - if (osres != os_resultSuccess && osres != os_resultUnavailable) { - OS_REPORT_WID(OS_ERROR, "user::u_domain::u_domainOpen",result,domainCfg.id, - "Failed to register server died callback for domain %s.", - domainCfg.name); - } + if (domainCfg.processConfig != NULL) { + cf_elementFree(domainCfg.processConfig); } - if (domainCfg.name != NULL) { os_free(domainCfg.name); } - + if (result != U_RESULT_OK && domainCfg.reportPlugins != NULL) { + /* report plugins not registered on domain ? */ + u_usrReportPluginUnregister(domainCfg.reportPlugins); + c_iterFree(domainCfg.reportPlugins); + } +err_domainConfig: return result; } @@ -1534,7 +1571,13 @@ u_domainOpen( const u_domainId_t id, os_int32 timeout) { - return u__domainOpen(domain,uri,id,FALSE,timeout); + u_result result; + + os_mutexLock(&mutex); + result = u__domainOpen(domain,uri,id,FALSE,timeout); + os_mutexUnlock(&mutex); + + return result; } u_result @@ -1572,7 +1615,7 @@ static void u_domainCloseTimeout (c_ulong protectCount) } #endif -static void u__domainDeinitWait (_In_ u_domain _this) +static u_result u__domainDeinitWait (_In_ u_domain _this) { const os_duration relTimeout = OS_DURATION_INIT(10,0); const os_timeM absTimeout = os_timeMAdd(os_timeMGet(), relTimeout); @@ -1581,6 +1624,7 @@ static void u__domainDeinitWait (_In_ u_domain _this) #endif c_ulong protectCount; u_bool first = TRUE; + u_result result = U_RESULT_OK; /* Check the claimed counter which indicates if a thread is currently * performing a u_domainProtect call. The u_domainProtect will access @@ -1589,7 +1633,7 @@ static void u__domainDeinitWait (_In_ u_domain _this) */ while (pa_ld32(&_this->claimed) > 0) { static const os_duration d = OS_DURATION_INIT(0, 10 * 1000 * 1000); /* 0.01 s */ - os_sleep(d); + ospl_os_sleep(d); } protectCount = u_domainProtectCount(_this); @@ -1602,26 +1646,33 @@ static void u__domainDeinitWait (_In_ u_domain _this) } #endif /* First time don't try to wake the threads. This has already happened, - * but we didn't yield our processing yet. */ + * but we didn't yield our processing yet. + */ if(!first && (pa_ld32(&_this->state) & U_DOMAIN_BLOCK_IN_KERNEL)) { u__domainWakeThreads(_this); } first = FALSE; - os_sleep(pollPeriod); + ospl_os_sleep(pollPeriod); protectCount = u_domainProtectCount(_this); } + if (protectCount > 0) { + /* at least one thread is still active in the kernel */ + result = U_RESULT_INTERNAL_ERROR; + OS_REPORT(OS_WARNING,"u_domainClose", 0, "%u threads did not detach from domain \"%s\" (%u).", protectCount, _this->name, _this->id); u__domainReportThreads(_this); #ifndef NDEBUG u_domainCloseTimeout(protectCount); #endif - } else if (os_threadIdToInteger(_this->spliced_thread) != os_threadIdToInteger(OS_THREAD_ID_NONE)) { - /* If spliced is in-process and we timed out, we have no idea whether or not spliced will - terminate or not. Calling threadWaitExit unconditionally would therefore defeat the - purpose of the timeout */ - (void) os_threadWaitExit(_this->spliced_thread, NULL); + } else if (_this->spliced_thread) { + /* the fact that no threads were active in the kernel (protectCount + * equals zero) does not guarantee that no threads are still active. + */ + result = splicedThreadJoin(_this->spliced_thread, _this->serviceTerminatePeriod); } + + return result; } static void @@ -1640,7 +1691,6 @@ u__domainThreadProtectCount ( return v_kernelThreadProtectCount(_this->serial); } - _Must_inspect_result_ static u_bool u__domainMustDelete( @@ -1687,7 +1737,11 @@ u__domainDelete( u__domainWakeThreads(_this); } (void) u_userRemoveDomain(_this); - u__domainDeinitWait(_this); + + r = u__domainDeinitWait(_this); + /* threads/processes were still active (not necessarily in the kernel for + * single process mode) if result does not equal U_RESULT_OK + */ { v_kernel kernel = _this->kernel; os_sharedHandle shm = _this->shm; @@ -1743,6 +1797,12 @@ u__domainDelete( _this->name, _this->id, os_resultImage(osResult)); r = U_RESULT_INTERNAL_ERROR; + } else if (!_this->isService) { + char name[256]; + os_procGetProcessName(name, sizeof(name)); + OS_REPORT_NOW(OS_INFO, OS_FUNCTION, 0, _this->id, + "Process '%s' <%d> detached from shared memory", + name, os_procIdSelf()); } if (destroy) { osResult = os_sharedMemoryDestroy(shm); @@ -1759,9 +1819,7 @@ u__domainDelete( } os_sharedDestroyHandle(shm); } -#ifdef INCLUDE_PLUGGABLE_REPORTING u_usrReportPluginUnregister(_this->reportPlugins); -#endif processConfigAlreadySet = FALSE; } @@ -1769,7 +1827,11 @@ u__domainDelete( _this->threadWithAccess = OS_THREAD_ID_NONE; os_mutexUnlock(&_this->mutex); - return clean ? r : U_RESULT_TIMEOUT; + if (r == U_RESULT_OK && !clean) { + r = U_RESULT_TIMEOUT; + } + + return r; } u_result @@ -1781,10 +1843,12 @@ u_domainClose ( assert(_this != NULL); + os_mutexLock(&mutex); mustDelete = u__domainMustDelete(_this, FALSE); if(mustDelete) { /* Set the flag that drives the cleanup behaviour. On closing the last - * participant entities are normally deleted. */ + * participant entities are normally deleted. + */ pa_or32(&_this->state, U_DOMAIN_DELETE_ENTITIES); r = u__domainDelete(_this); } @@ -1802,6 +1866,8 @@ u_domainClose ( u_domainFree(_this); } + os_mutexUnlock(&mutex); + return r; } @@ -1821,9 +1887,7 @@ u_domainFree ( c_iterFree(_this->participants); c_iterFree(_this->waitsets); -#ifdef INCLUDE_PLUGGABLE_REPORTING c_iterFree(_this->reportPlugins); -#endif os_free(_this->uri); os_free(_this->name); os_mutexUnlock(&_this->mutex); @@ -1845,6 +1909,13 @@ u_domainThreadFlags( return v_kernelThreadFlags(mask, enable); } +static void +domainClaimFinalize( + void * domain) +{ + pa_dec32(&((u_domain)domain)->claimed); +} + u_result u_domainProtect( const u_domain _this) @@ -1860,7 +1931,7 @@ u_domainProtect( */ if (_this) { pa_inc32(&_this->claimed); - if (u_domainProtectAllowedClaimed(_this)) + if (u_domainProtectAllowedAction(_this, domainClaimFinalize)) { assert(_this->id == (u_domainId_t)(_this->procInfo->serial & V_KERNEL_THREAD_FLAG_DOMAINID)); result = u_resultFromKernel(v_kernelProtect(_this->procInfo, &_this->state, U_DOMAIN_BLOCK_IN_KERNEL, &_this->deadlock, _this)); @@ -1880,8 +1951,9 @@ u_domainUnprotect(void) if(_this) { flags = u_domainThreadFlags(V_KERNEL_THREAD_FLAGS_GET, V_KERNEL_THREAD_FLAGS_GET); if( !(flags & V_KERNEL_THREAD_FLAG_SERVICETHREAD)) { - (void)u_domainProtectAllowed(_this); + (void)u_domainProtectAllowedAction(_this, v_kernelUnprotectFinalize); } + v_kernelUnprotectFinalize((void *)_this); } } @@ -1897,7 +1969,8 @@ u_domainProtectCount( /* If blockWaits is set, and threads have no access, the protectCount * can only go down and waitCount can only go up (but never higher * than protectCount). That means we can safely subtract both even - * though they weren't read atomically. */ + * though they weren't read atomically. + */ bc = pa_ld32(&_this->procInfo->blockedCount); } return pc - bc; @@ -2069,6 +2142,7 @@ u_domainRemoveParticipant( assert(_this->openCount > 0); + result = U_RESULT_OK; u_participantDecUseCount(p); arg.count = 0; @@ -2092,18 +2166,29 @@ u_domainRemoveParticipant( /* FIXME: wait for openCount to drop to 1, or wait for participants to become empty? */ /* Services mustn't wait because spliced waits for the services to terminate */ if (u_objectKind (p) == U_PARTICIPANT) { + os_timeM endTime = os_timeMAdd(os_timeMGet(), _this->serviceTerminatePeriod); + os_compare compare; + os_mutexLock(&_this->mutex); - while (c_iterLength(_this->participants) > 0) { + while ((c_iterLength(_this->participants) > 0) && + ((compare = os_timeMCompare(os_timeMGet(), endTime)) == OS_LESS)) { const os_duration d = OS_DURATION_INIT( 0, 100000000 ); os_mutexUnlock(&_this->mutex); - os_sleep(d); + ospl_os_sleep(d); os_mutexLock(&_this->mutex); } + if ((c_iterLength(_this->participants) > 0) && + (compare != OS_LESS)) { + OS_REPORT(OS_ERROR, "user::u_domain::u_domainRemoveParticipant", result, + "Internal error: %u participants still connected to domain \"%s\" (%u).", + c_iterLength(_this->participants), + _this->name, _this->id); + result = U_RESULT_INTERNAL_ERROR; + } os_mutexUnlock(&_this->mutex); + } } - - result = U_RESULT_OK; } } else { result = U_RESULT_INTERNAL_ERROR; @@ -2175,6 +2260,7 @@ collect_participants( { a->participants = c_iterInsert(a->participants, p); } + os_free(name); } } @@ -2235,6 +2321,7 @@ u_domainId( if (_this == NULL) { return -1; } + return _this->id; } @@ -2245,13 +2332,14 @@ u_domainName( if (_this == NULL) { return ""; } + return _this->name; } u_bool u_domainCompareId( - const u_domain _this, - const u_domainId_t id) + _In_ const u_domain _this, + _In_ const u_domainId_t id) { assert(_this != NULL); return (_this->id == id); @@ -2327,7 +2415,8 @@ u_domainProtectAllowed( if(pa_ld32(&_this->state) & U_DOMAIN_BLOCK_IN_USER) { /* If this thread is within a nested protect, then don't deadlock but - * fail the protect instead. The top-level unprotect will deadlock. */ + * fail the protect instead. The top-level unprotect will deadlock. + */ if(u__domainThreadProtectCount(_this) == 0) { u__domainDeadlock(_this); } @@ -2336,23 +2425,29 @@ u_domainProtectAllowed( return pa_ld32(&_this->state) == U_DOMAIN_STATE_ALIVE; } -/* This function is used when the domain has been claimed when performing - * a u_domainProtect. In case the function blocks the claim count has to - * be decremented. +/* This function can be used when an action has to be performed before the + * thread is deadlocked. */ u_bool -u_domainProtectAllowedClaimed( - _In_ u_domain _this) +u_domainProtectAllowedAction( + _In_ u_domain _this, + _In_ const u_domainPreDeadlockAction action) { - if(os_threadIdToInteger(_this->threadWithAccess) == os_threadIdToInteger(os_threadIdSelf())) { + if (_this == NULL) { + return FALSE; + } + if (os_threadIdToInteger(_this->threadWithAccess) == os_threadIdToInteger(os_threadIdSelf())) { return TRUE; } - if(pa_ld32(&_this->state) & U_DOMAIN_BLOCK_IN_USER) { + if (pa_ld32(&_this->state) & U_DOMAIN_BLOCK_IN_USER) { /* If this thread is within a nested protect, then don't deadlock but - * fail the protect instead. The top-level unprotect will deadlock. */ - if(u__domainThreadProtectCount(_this) == 0) { - pa_dec32(&_this->claimed); + * fail the protect instead. The top-level unprotect will deadlock. + */ + if (u__domainThreadProtectCount(_this) == 0) { + if (action) { + action(_this); + } u__domainDeadlock(_this); } } @@ -2421,7 +2516,8 @@ u_domainDetach ( /* If threads are blocked *within* the kernel, the deletion of the * domain must be forced, since the domain-count may never reach 0. * Otherwise the last one doing a u_domainClose() (triggered by deletion - * of kernel-entities) will do the deletion. */ + * of kernel-entities) will do the deletion. + */ if(u__domainMustDelete(_this, TRUE)) { uresult = u__domainDelete(_this); } else { @@ -2449,14 +2545,6 @@ u_domainHandleServer( return (os_address)_this->kernel->handleServer; } -os_address -u_domainAddress( - const u_domain _this) -{ - assert(_this != NULL); - return (os_address)_this->kernel; -} - void * u_domainMemoryAddress( const u_domain _this) @@ -2542,18 +2630,10 @@ u_domainFederationSpecificPartitionName ( if (bufsize < U_DOMAIN_FEDERATIONSPECIFICPARTITIONNAME_MINBUFSIZE) { return U_RESULT_ILL_PARAM; } -/* - if ((result = u_entityLock (u_entity (_this))) != U_RESULT_OK) { - return result; - } -*/ systemId = _this->_parent._parent.gid.systemId; n = snprintf (buf, bufsize, "__NODE%08"PA_PRIx32" BUILT-IN PARTITION__", systemId); assert (n < (int) bufsize); OS_UNUSED_ARG(n); -/* - u_entityUnlock (u_entity (_this)); -*/ return result; } @@ -2704,6 +2784,77 @@ u_domainEnableStatistics( return result; } +u_result +u_domainGetAlignedState( + const u_domain _this, + os_boolean *aligned) +{ + u_result result; + v_kernel kernel; + + assert(_this != NULL); + assert(aligned != NULL); + + result = u_observableReadClaim(u_observable(_this), (v_public*)(&kernel), C_MM_RESERVATION_ZERO); + if (result == U_RESULT_OK) { + assert(kernel); + *aligned = (v_kernelGetAlignedState(kernel) == FALSE) ? OS_FALSE : OS_TRUE; + u_observableRelease(u_observable(_this), C_MM_RESERVATION_ZERO); + } else { + OS_REPORT(OS_WARNING, OS_FUNCTION, result, + "Failed to claim Domain."); + } + + return result; +} + +u_result +u_domainSetAlignedState( + const u_domain _this, + os_boolean aligned) +{ + u_result result; + v_kernel kernel; + c_bool state; + + assert(_this != NULL); + + result = u_observableWriteClaim(u_observable(_this), (v_public*)(&kernel), C_MM_RESERVATION_ZERO); + if (result == U_RESULT_OK) { + assert(kernel); + state = (aligned == OS_FALSE) ? FALSE : TRUE; + v_kernelSetAlignedState(kernel, state); + u_observableRelease(u_observable(_this), C_MM_RESERVATION_ZERO); + } else { + OS_REPORT(OS_WARNING, OS_FUNCTION, result, + "Failed to claim Domain."); + } + + return result; +} + +u_result +u_domainTransactionsPurge( + const u_domain _this) +{ + u_result result; + v_kernel kernel; + + assert(_this != NULL); + + result = u_observableWriteClaim(u_observable(_this), (v_public*)(&kernel), C_MM_RESERVATION_ZERO); + if (result == U_RESULT_OK) { + assert(kernel); + v_kernelTransactionsPurge(kernel); + u_observableRelease(u_observable(_this), C_MM_RESERVATION_ZERO); + } else { + OS_REPORT(OS_WARNING, OS_FUNCTION, result, + "Failed to claim Domain."); + } + + return result; +} + void u_domainIdSetThreadSpecific( _In_ u_domain domain) @@ -2715,3 +2866,65 @@ u_domainIdSetThreadSpecific( u_domainUnprotect(); } } + +u_bool +u_domainIsSingleProcess( + _In_ u_domain domain) +{ + assert(domain); + + return (domain->shm == NULL); +} + +u_result +u_domainRead( + _In_ const u_domain _this, + _In_ const os_char *partition, + _In_ const os_char *topic, + _In_ const os_char *query, + _In_ const u_domainReadAction action, + _In_ const void *actionArg) +{ + u_result result; + v_kernel kernel; + + assert(_this != NULL); + + result = u_observableWriteClaim(u_observable(_this), (v_public*)(&kernel), C_MM_RESERVATION_ZERO); + if (result == U_RESULT_OK) { + v_result vresult; + assert(kernel); + vresult = v_kernelRead(kernel, partition, topic, query, (v_domainReadAction)action, actionArg); + result = u_resultFromKernel(vresult); + u_observableRelease(u_observable(_this), C_MM_RESERVATION_ZERO); + } else { + OS_REPORT(OS_WARNING, OS_FUNCTION, result, "Failed to claim Domain."); + } + return result; +} + +u_result +u_domainGroupRead( + _In_ const u_domain _this, + _In_ const os_char *partition, + _In_ const os_char *topic, + _In_ const u_domainGroupReadAction action, + _In_ const void *actionArg) +{ + u_result result; + v_kernel kernel; + + assert(_this != NULL); + + result = u_observableWriteClaim(u_observable(_this), (v_public*)(&kernel), C_MM_RESERVATION_ZERO); + if (result == U_RESULT_OK) { + v_result vresult; + assert(kernel); + vresult = v_kernelGroupRead(kernel, partition, topic, (v_domainGroupReadAction)action, actionArg); + result = u_resultFromKernel(vresult); + u_observableRelease(u_observable(_this), C_MM_RESERVATION_ZERO); + } else { + OS_REPORT(OS_WARNING, OS_FUNCTION, result, "Failed to claim Domain."); + } + return result; +} diff --git a/src/user/code/u_durability.c b/src/user/code/u_durability.c index 1a2d0b8f5..7bf0873d0 100644 --- a/src/user/code/u_durability.c +++ b/src/user/code/u_durability.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,6 +28,7 @@ #include "v_durability.h" #include "v_configuration.h" #include "os_report.h" +#include "os_atomics.h" static void *wrapper(v_kernel kernel, const c_char *name, const c_char *extStateName, v_participantQos qos, c_bool enable, void *varg) { @@ -46,3 +48,38 @@ u_durabilityNew ( return u_serviceNewSpecialized(wrapper, "DurabilityService", uri, id, timeout, name, qos, enable, NULL); } +static void +u__durabilityDecreasePurgeSuppression( + v_public _this, + void *varg) +{ + v_kernel k; + os_uint32 *purgeSuppressionCount = (os_uint32 *)varg; + os_uint32 psc; + + k = v_objectKernel(_this); + assert(k != NULL); + assert(v_kernelHasDurabilityService(k)); + + /* Decrease the purgeSuppressCount to signal that durability processed (an + * update to) a DCPSHeartbeart. + */ + psc = pa_dec32_nv(&k->purgeSuppressCount); + + if(purgeSuppressionCount) { + *purgeSuppressionCount = psc; + } +} + +u_result +u_durabilityHeartbeatProcessed ( + _In_ u_service durability, + _Out_opt_ os_uint32 *purgeSuppressionCount ) +{ + u_result result; + + result = u_observableAction (u_observable (durability), &u__durabilityDecreasePurgeSuppression, purgeSuppressionCount); + + return result; +} + diff --git a/src/user/code/u_entity.c b/src/user/code/u_entity.c index 331002839..5a39f8c2e 100644 --- a/src/user/code/u_entity.c +++ b/src/user/code/u_entity.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -251,9 +252,9 @@ u_entityGetInstanceHandle( result = u_observableReadClaim(u_observable(_this), (v_public *)&ke, C_MM_RESERVATION_ZERO); if (result == U_RESULT_OK) { -/* TODO : the handle retrieval is incorrect, - * must be retrieved from build-in reader. - */ + /* TODO : the handle retrieval is incorrect, + * must be retrieved from build-in reader. + */ handle = u_instanceHandleFromGID(v_publicGid(v_public(ke))); u_observableRelease(u_observable(_this), C_MM_RESERVATION_ZERO); } else { @@ -381,3 +382,41 @@ u_entityDisableCallbacks( } return triggered; } + +u_result +u_entityGetProperty( + _In_ const u_entity _this, + _In_ const os_char * name, + _Out_ os_char ** value) +{ + u_result result = U_RESULT_ILL_PARAM; + v_entity ke; + assert(_this != NULL); + result = u_observableWriteClaim(u_observable(_this), (v_public*)(&ke), C_MM_RESERVATION_ZERO); + if (result == U_RESULT_OK) { + result = u_resultFromKernel(v_entityGetProperty(ke, name, value )); + u_observableRelease(u_observable(_this), C_MM_RESERVATION_ZERO); + } else { + OS_REPORT(OS_WARNING, OS_FUNCTION, result, "Failed to claim Domain."); + } + return result; +} + +u_result +u_entitySetProperty( + _In_ const u_entity _this, + _In_ const os_char * name, + _In_ const os_char * value) +{ + u_result result = U_RESULT_ILL_PARAM; + v_entity ke; + assert(_this != NULL); + result = u_observableWriteClaim(u_observable(_this), (v_public*)(&ke), C_MM_RESERVATION_ZERO); + if (result == U_RESULT_OK) { + result = u_resultFromKernel(v_entitySetProperty(ke, name, value )); + u_observableRelease(u_observable(_this), C_MM_RESERVATION_ZERO); + } else { + OS_REPORT(OS_WARNING, OS_FUNCTION, result, "Failed to claim Domain."); + } + return result; +} diff --git a/src/user/code/u_group.c b/src/user/code/u_group.c index a5b4ef5eb..0b0c29e7b 100644 --- a/src/user/code/u_group.c +++ b/src/user/code/u_group.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -63,7 +64,8 @@ u_groupInit( /* -------------------------- "Normal" functions ---------------------------- */ /* These functions can be called by any application having a u_group entity. - * The functions themselves do the protecting */ + * The functions themselves do the protecting + */ u_group u_groupNew( @@ -92,7 +94,7 @@ u_groupNew( topics = v_resolveTopics(kernel,topicName); if (c_iterLength(topics) == 0) { c_iterFree(topics); - os_sleep(timeout); + ospl_os_sleep(timeout); topics = v_resolveTopics(v_objectKernel(kparticipant), topicName); } diff --git a/src/user/code/u_groupQueue.c b/src/user/code/u_groupQueue.c index 0318b9b0a..3a5a4357a 100644 --- a/src/user/code/u_groupQueue.c +++ b/src/user/code/u_groupQueue.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -108,3 +109,19 @@ u_groupQueueNew( return _this; } +u_result +u_groupQueueSize( + u_groupQueue _this, + c_ulong * size) +{ + u_result result; + v_groupQueue kq; + + result = u_observableWriteClaim(u_observable(_this),(v_public *)(&kq), C_MM_RESERVATION_ZERO); + if (result == U_RESULT_OK) { + *size = v_groupQueueSize(kq); + u_observableRelease(u_observable(_this), C_MM_RESERVATION_ZERO); + } + + return result; +} diff --git a/src/user/code/u_handle.c b/src/user/code/u_handle.c index 65cdc0951..6b9c15829 100644 --- a/src/user/code/u_handle.c +++ b/src/user/code/u_handle.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/user/code/u_instanceHandle.c b/src/user/code/u_instanceHandle.c index 217d6537c..a70017016 100644 --- a/src/user/code/u_instanceHandle.c +++ b/src/user/code/u_instanceHandle.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,6 +24,7 @@ #include "u__domain.h" #include "u__user.h" #include "v_dataView.h" +#include "v_instance.h" #include "v_handle.h" #include "v_public.h" #include "v_dataReader.h" @@ -209,15 +211,52 @@ u_instanceHandleFix( reader = v_collection(v_dataViewGetReader(v_dataView(reader))); } topic = v_dataReaderGetTopic(v_dataReader(reader)); - message = v_topicMessageNew(topic); - data = (void *) (message + 1); - data->key = u_instanceHandleToGID(_this); - instance = (v_public)v_dataReaderLookupInstance(v_dataReader(reader), - message); - translator.handle = u_instanceHandleNew(instance); - c_free(instance); - c_free(topic); - c_free(message); + + if(topic){ + message = v_topicMessageNew(topic); + data = (void *) (message + 1); + data->key = u_instanceHandleToGID(_this); + instance = (v_public)v_dataReaderLookupInstance(v_dataReader(reader), + message); + translator.handle = u_instanceHandleNew(instance); + c_free(instance); + c_free(topic); + c_free(message); + } else { + translator.handle = U_INSTANCEHANDLE_NIL; + } } return translator.handle; } + +u_result +u_instanceHandleSetUserData( + u_instanceHandle _this, + void *userData) +{ + u_result result; + v_instance instance; + + result = u_instanceHandleClaim(_this, &instance); + if (result == U_RESULT_OK) { + (void)v_instanceSetUserData(instance, userData); + (void)u_instanceHandleRelease(_this); + } + return result; +} + +void * +u_instanceHandleGetUserData( + u_instanceHandle _this) +{ + u_result result; + v_instance instance; + void *userData = NULL; + + result = u_instanceHandleClaim(_this, &instance); + if (result == U_RESULT_OK) { + userData = v_instanceGetUserData(instance); + (void)u_instanceHandleRelease(_this); + } + return userData; +} diff --git a/src/user/code/u_listener.c b/src/user/code/u_listener.c index 3a53e319d..c31d1e718 100644 --- a/src/user/code/u_listener.c +++ b/src/user/code/u_listener.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -110,7 +111,7 @@ u_listenerNotify( r = u_observableReadClaim(u_observable(_this), (v_public *)(&kl), C_MM_RESERVATION_ZERO); if (r == U_RESULT_OK) { assert(kl); - v_listenerTrigger(kl); + v_listenerNotify(kl, NULL, NULL); u_observableRelease(u_observable(_this), C_MM_RESERVATION_ZERO); } return r; @@ -122,21 +123,15 @@ u_listenerTrigger( { u_result result = U_RESULT_OK; v_listener vListener; - C_STRUCT(v_event) vEvent; assert (_this != NULL); - result = u_observableTriggerClaim( - u_observable(_this), (v_public *)&vListener, C_MM_RESERVATION_ZERO); + result = u_observableTriggerClaim(u_observable(_this), (v_public *)&vListener, C_MM_RESERVATION_ZERO); if (result == U_RESULT_OK) { assert (vListener != NULL); - vEvent.kind = V_EVENT_TRIGGER; - vEvent.source = NULL; - vEvent.data = NULL; - v_listenerNotify(vListener, &vEvent, NULL); + v_listenerNotify(vListener, NULL, NULL); u_observableRelease(u_observable(_this), C_MM_RESERVATION_ZERO); } - return result; } diff --git a/src/user/code/u_networkReader.c b/src/user/code/u_networkReader.c index 3807d4471..c34033aca 100644 --- a/src/user/code/u_networkReader.c +++ b/src/user/code/u_networkReader.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/user/code/u_networking.c b/src/user/code/u_networking.c index 8ec6f10b1..0bf5d4ac7 100644 --- a/src/user/code/u_networking.c +++ b/src/user/code/u_networking.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/user/code/u_nwbridge.c b/src/user/code/u_nwbridge.c index bc68c54bf..a3eebf24b 100644 --- a/src/user/code/u_nwbridge.c +++ b/src/user/code/u_nwbridge.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/user/code/u_object.c b/src/user/code/u_object.c index 7de5dbe06..79a524569 100644 --- a/src/user/code/u_object.c +++ b/src/user/code/u_object.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/user/code/u_observable.c b/src/user/code/u_observable.c index fc488574b..22cb1378f 100644 --- a/src/user/code/u_observable.c +++ b/src/user/code/u_observable.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -48,6 +49,7 @@ #include "v_nwbridge.h" #include "v_cmsoap.h" #include "v_rnr.h" +#include "v_dbmsconnect.h" #include "v_dataReader.h" #include "v_dataReaderQuery.h" #include "v_dataViewQuery.h" @@ -117,6 +119,7 @@ u_observableCreateProxy ( case K_NWBRIDGE: kind = U_SERVICE; sz = sizeof(struct u_service_s); break; case K_CMSOAP: kind = U_SERVICE; sz = sizeof(struct u_service_s); break; case K_RNR: kind = U_SERVICE; sz = sizeof(struct u_service_s); break; + case K_DBMSCONNECT: kind = U_SERVICE; sz = sizeof(struct u_service_s); break; case K_SERVICE: kind = U_SERVICE; sz = sizeof(struct u_service_s); break; case K_SPLICED: kind = U_SPLICED; sz = sizeof(struct u_spliced_s); break; case K_WAITSET: kind = U_WAITSETENTRY; sz = sizeof(struct u_waitsetEntry_s); break; @@ -200,6 +203,7 @@ publicFree( case K_NWBRIDGE: _FREE_(v_nwbridge); case K_CMSOAP: _FREE_(v_cmsoap); case K_RNR: _FREE_(v_rnr); + case K_DBMSCONNECT: _FREE_(v_dbmsconnect); case K_WRITERSTATUS: _FREE_(v_status); case K_DATAVIEWQUERY: _FREE_(v_dataViewQuery); case K_DATAREADERQUERY: _FREE_(v_dataReaderQuery); @@ -307,9 +311,6 @@ u_observableClaimCommon( const os_uint32 checks, os_address memoryClaim) { -#if 0 - static os_boolean serviceWarningGiven = OS_FALSE; -#endif static os_boolean appWarningGiven = OS_FALSE; u_result r; u_kind kind; @@ -344,8 +345,7 @@ u_observableClaimCommon( } } else if (r == U_RESULT_ALREADY_DELETED) { os_reportType verbosity = OS_WARNING; - /* - * This return value is quite valid when considering the next situation: + /* This return value is quite valid when considering the next situation: * - The last participant of a domain is deinitted * - Causing the domain to be freed * - Causing a call to u_objectFree with that domain @@ -360,7 +360,7 @@ u_observableClaimCommon( if (kind == U_DOMAIN) { verbosity = OS_INFO; } - /* OSPL-6199 : For the Java ListenerDispatcher it is perfectly + /* For the Java ListenerDispatcher it is perfectly * valid that the claim of the listener can return ALREADY_DELETED, * returning a WARNING is in that case incorrect. * For a listener the report is suppressed when the domain has been @@ -607,6 +607,7 @@ u_observableHandle ( u_result u_observableAddListener( const u_observable _this, + const u_eventMask eventMask, const u_observableListener listener, void *userData) { @@ -616,7 +617,7 @@ u_observableAddListener( if (_this->dispatcher == NULL) { _this->dispatcher = u_dispatcherNew(_this); } - return u_dispatcherInsertListener(_this->dispatcher, listener, userData); + return u_dispatcherInsertListener(_this->dispatcher, eventMask, listener, userData); } u_result @@ -637,7 +638,7 @@ u_observableRemoveListener( } u_result -u_observableNotifyListener( +u_observableNotify( const u_observable _this) { u_result result; diff --git a/src/user/code/u_participant.c b/src/user/code/u_participant.c index 315182bed..c57ba2686 100644 --- a/src/user/code/u_participant.c +++ b/src/user/code/u_participant.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,6 +22,7 @@ #include "u_subscriber.h" #include "u_writer.h" #include "u__participant.h" +#include "u__instanceHandle.h" #include "u__topic.h" #include "u__types.h" #include "u__object.h" @@ -126,7 +128,7 @@ u__participantFreeW ( while (pa_ld32(&p->useCount) > 0) { os_duration t = OS_DURATION_INIT(0, 100000000); - os_sleep(t); + ospl_os_sleep(t); } u__entityFreeW(_this); @@ -150,8 +152,10 @@ u__participantDeinitW ( r = u_participantDetach(p); if (r == U_RESULT_OK) { u__entityDeinitW(_this); - (void) u_domainRemoveParticipant(domain, p); - r = u_domainClose(domain); + r = u_domainRemoveParticipant(domain, p); + if (r == U_RESULT_OK) { + r = u_domainClose(domain); + } } else if (r == U_RESULT_ALREADY_DELETED) { r = U_RESULT_OK; } @@ -217,45 +221,21 @@ u_participantNew( (void)u_domainClose(domain); } } else { - const c_char *uri_string; - if (uri) { - uri_string = uri; + char idstr[16]; + if (id == U_DOMAIN_ID_ANY) { + sprintf(idstr, ""); } else { - uri_string = ""; + sprintf(idstr, "%d", id); } OS_REPORT(OS_ERROR,"u_participantNew",r, - "Failure to open the domain, domain id = %d and URI=\"%s\" " - "The most common cause of this error is that OpenSpliceDDS " - "is not running (when using shared memory mode). " - "Please make sure to start OpenSplice before creating a " - "DomainParticipant.", - id, uri_string); + "Unable to connect to domain id = %s.\n " + "The most common causes of this error are an incorrect configuration file or\n " + "that OpenSpliceDDS is not running (when using shared memory mode).", + idstr); } return p; } -static c_ulong -u_participantNewGroupListener( - u_observable _this, - c_ulong event, - c_voidp usrData) -{ - u_result r; - v_participant kp; - - OS_UNUSED_ARG(event); - OS_UNUSED_ARG(usrData); - - r = u_observableWriteClaim(_this, (v_public*)(&kp),C_MM_RESERVATION_HIGH); - if(r == U_RESULT_OK) - { - assert(kp); - v_participantConnectNewGroup(kp,NULL); - u_observableRelease(_this, C_MM_RESERVATION_HIGH); - } - return r; -} - u_result u_participantInit ( const u_participant _this, @@ -267,7 +247,6 @@ u_participantInit ( os_mutexAttr mutexAttr; os_condAttr condAttr; os_result osr; - c_ulong mask; assert(_this != NULL); assert(domain != NULL); @@ -324,12 +303,6 @@ u_participantInit ( "Watchdog thread could not be started.\n"); } - (void)u_observableGetListenerMask(u_observable(_this), &mask); - (void)u_observableAddListener(u_observable(_this), u_participantNewGroupListener, NULL); - mask |= V_EVENT_NEW_GROUP; - mask |= V_EVENT_CONNECT_WRITER; - (void)u_observableSetListenerMask(u_observable(_this), mask); - while (_this->threadWaitCount > 0) { os_condWait(&_this->cv, &_this->mutex); } @@ -564,7 +537,7 @@ u_participantFindTopic( retry = 0; /* topic found or error */ } if (retry) { - os_sleep(tryPeriod); + ospl_os_sleep(tryPeriod); } } else { retry = 0; @@ -645,7 +618,7 @@ u_participantRegisterTypeRepresentation ( assert(tr->metaData != NULL); assert(tr->metaDataLen != 0); - result = u_participantReadClaim(_this, &kp, C_MM_RESERVATION_LOW); + result = u_participantWriteClaim(_this, &kp, C_MM_RESERVATION_LOW); if (result == U_RESULT_OK) { ktr = v_typeRepresentationNew(kp, tr->typeName, @@ -694,14 +667,100 @@ u_participantFederationSpecificPartitionName ( { u_result result; u_domain domain; -#if 0 - if ((result = u_entityLock (u_entity(_this))) == U_RESULT_OK) { -#endif - domain = u_observableDomain(u_observable(_this)); - result = u_domainFederationSpecificPartitionName(domain, buf, bufsize); -#if 0 - u_entityUnlock (u_entity (_this)); - } -#endif + + domain = u_observableDomain(u_observable(_this)); + result = u_domainFederationSpecificPartitionName(domain, buf, bufsize); return result; } + +u_result +u_participantIgnoreParticipant( + const u_participant _this, + const u_instanceHandle handle) +{ + u_result r; + v_participant kp; + v_gid gid = {V_PUBLIC_ILLEGAL_GID, V_PUBLIC_ILLEGAL_GID, V_PUBLIC_ILLEGAL_GID}; + + assert(_this != NULL); + + r = u_participantReadClaim(_this, &kp, C_MM_RESERVATION_ZERO); + if(r == U_RESULT_OK) { + assert(kp); + gid = u_instanceHandleToGID(handle); + r = v_participantIgnoreParticipant(kp,gid); + u_participantRelease(_this, C_MM_RESERVATION_ZERO); + } else { + OS_REPORT(OS_WARNING, "u_participantIgnoreParticipant", r, "Failed to claim Participant."); + } + return r; +} + +u_result +u_participantIgnoreTopic( + const u_participant _this, + const u_instanceHandle handle) +{ + u_result r; + v_participant kp; + v_gid gid = {V_PUBLIC_ILLEGAL_GID, V_PUBLIC_ILLEGAL_GID, V_PUBLIC_ILLEGAL_GID}; + + assert(_this != NULL); + + r = u_participantReadClaim(_this, &kp, C_MM_RESERVATION_ZERO); + if(r == U_RESULT_OK) { + assert(kp); + gid = u_instanceHandleToGID(handle); + r = v_participantIgnoreTopic(kp,gid); + u_participantRelease(_this, C_MM_RESERVATION_ZERO); + } else { + OS_REPORT(OS_WARNING, "u_participantIgnoreTopic", r, "Failed to claim Participant."); + } + return r; +} + +u_result +u_participantIgnoreSubscription( + const u_participant _this, + const u_instanceHandle handle) +{ + u_result r; + v_participant kp; + v_gid gid = {V_PUBLIC_ILLEGAL_GID, V_PUBLIC_ILLEGAL_GID, V_PUBLIC_ILLEGAL_GID}; + + assert(_this != NULL); + + r = u_participantReadClaim(_this, &kp, C_MM_RESERVATION_ZERO); + if(r == U_RESULT_OK) { + assert(kp); + gid = u_instanceHandleToGID(handle); + r = v_participantIgnoreSubscription(kp,gid); + u_participantRelease(_this, C_MM_RESERVATION_ZERO); + } else { + OS_REPORT(OS_WARNING, "u_participantIgnoreSubscription", r, "Failed to claim Participant."); + } + return r; +} + +u_result +u_participantIgnorePublication( + const u_participant _this, + const u_instanceHandle handle) +{ + u_result r; + v_participant kp; + v_gid gid = {V_PUBLIC_ILLEGAL_GID, V_PUBLIC_ILLEGAL_GID, V_PUBLIC_ILLEGAL_GID}; + + assert(_this != NULL); + + r = u_participantReadClaim(_this, &kp, C_MM_RESERVATION_ZERO); + if(r == U_RESULT_OK) { + assert(kp); + gid = u_instanceHandleToGID(handle); + r = v_participantIgnorePublication(kp,gid); + u_participantRelease(_this, C_MM_RESERVATION_ZERO); + } else { + OS_REPORT(OS_WARNING, "u_participantIgnorePublication", r, "Failed to claim Participant."); + } + return r; +} diff --git a/src/user/code/u_participantQos.c b/src/user/code/u_participantQos.c index 2fe5471e7..556ddcec3 100644 --- a/src/user/code/u_participantQos.c +++ b/src/user/code/u_participantQos.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/user/code/u_partition.c b/src/user/code/u_partition.c index 451050c8d..984a255bb 100644 --- a/src/user/code/u_partition.c +++ b/src/user/code/u_partition.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/user/code/u_partitionQos.c b/src/user/code/u_partitionQos.c index 4f59dcead..6ed8a9fd7 100644 --- a/src/user/code/u_partitionQos.c +++ b/src/user/code/u_partitionQos.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/user/code/u_publisher.c b/src/user/code/u_publisher.c old mode 100644 new mode 100755 index f052a83a1..93bed3621 --- a/src/user/code/u_publisher.c +++ b/src/user/code/u_publisher.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -155,6 +156,9 @@ u_publisherGetQos ( c_free(vQos); u_publisherRelease(_this, C_MM_RESERVATION_ZERO); } + // Coverity false positive: leaking qos: vQos is freed locally, + // qos is passed to caller and is freed there + // coverity [leaked_storage : FALSE] return result; } diff --git a/src/user/code/u_publisherQos.c b/src/user/code/u_publisherQos.c index 31edc9e92..eb43270ba 100644 --- a/src/user/code/u_publisherQos.c +++ b/src/user/code/u_publisherQos.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/user/code/u_query.c b/src/user/code/u_query.c index f27d35c63..29a0488df 100644 --- a/src/user/code/u_query.c +++ b/src/user/code/u_query.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,7 +30,6 @@ #include "v_collection.h" #include "v_dataReader.h" #include "v_dataView.h" -#include "v_dataViewInstance.h" #include "u__types.h" #include "q_expr.h" diff --git a/src/user/code/u_reader.c b/src/user/code/u_reader.c index 0f74d69fb..11dcce4e4 100644 --- a/src/user/code/u_reader.c +++ b/src/user/code/u_reader.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -237,31 +238,14 @@ u_readerGetMatchedPublications ( void *arg) { v_dataReader reader; - v_spliced spliced; - v_kernel kernel; u_result result; - c_iter participants; - v_participant participant; assert(_this); assert(action); result = u_observableReadClaim(u_observable(_this), (v_public *)(&reader), C_MM_RESERVATION_ZERO); if ((result == U_RESULT_OK) && (reader != NULL)) { - kernel = v_objectKernel(reader); - - participants = v_resolveParticipants(kernel, V_SPLICED_NAME); - assert(c_iterLength(participants) == 1); - participant = v_participant(c_iterTakeFirst(participants)); - spliced = v_spliced(participant); - c_free(participant); - c_iterFree(participants); - - result = u_resultFromKernel( - v_splicedGetMatchedPublications(spliced, - v_dataReader(reader), - action, - arg)); + result = u_resultFromKernel(v_dataReaderReadMatchedPublications(v_dataReader(reader), action, arg)); u_observableRelease(u_observable(_this), C_MM_RESERVATION_ZERO); } return result; @@ -275,32 +259,17 @@ u_readerGetMatchedPublicationData ( void *arg) { v_dataReader reader; - v_spliced spliced; - v_kernel kernel; u_result result; - c_iter participants; - v_participant participant; assert(_this); assert(action); result = u_observableReadClaim(u_observable(_this), (v_public *)(&reader), C_MM_RESERVATION_ZERO); if ((result == U_RESULT_OK) && (reader != NULL)) { - kernel = v_objectKernel(reader); - - participants = v_resolveParticipants(kernel, V_SPLICED_NAME); - assert(c_iterLength(participants) == 1); - participant = v_participant(c_iterTakeFirst(participants)); - spliced = v_spliced(participant); - c_free(participant); - c_iterFree(participants); - result = u_resultFromKernel( - v_splicedGetMatchedPublicationData(spliced, - v_dataReader(reader), - u_instanceHandleToGID(publication_handle), - action, - arg)); + v_dataReaderReadMatchedPublicationData(reader, + u_instanceHandleToGID(publication_handle), + action, arg)); u_observableRelease(u_observable(_this), C_MM_RESERVATION_ZERO); } return result; diff --git a/src/user/code/u_readerQos.c b/src/user/code/u_readerQos.c index df4f2899a..c85e01962 100644 --- a/src/user/code/u_readerQos.c +++ b/src/user/code/u_readerQos.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/user/code/u_rnr.c b/src/user/code/u_rnr.c index 54ff63cbe..069f45c5f 100644 --- a/src/user/code/u_rnr.c +++ b/src/user/code/u_rnr.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/user/code/u_service.c b/src/user/code/u_service.c index 838b986ec..8696c5f41 100644 --- a/src/user/code/u_service.c +++ b/src/user/code/u_service.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -48,10 +49,6 @@ #define SERVICE_PATH "Domain/Service[@name='%s']" -/************************************************************** - * global data - **************************************************************/ - struct atExitInfo { u_service service; u_serviceAtExitAction action; @@ -61,10 +58,6 @@ struct atExitInfo { static c_iter atExitInfoList = NULL; static os_mutex atExitMutex; -/************************************************************** - * private functions - **************************************************************/ - static c_ulong u_serviceSpliceListener( const u_observable o, @@ -72,16 +65,16 @@ u_serviceSpliceListener( const c_voidp usrData) { v_serviceStateKind kind; - u_serviceManager serviceManager = u_serviceManager(usrData); + u_service service = u_service(usrData); OS_UNUSED_ARG(o); OS_UNUSED_ARG(event); - assert(serviceManager != NULL); + assert(service != NULL); - kind = u_serviceManagerGetServiceStateKind(serviceManager, V_SPLICED_NAME); + kind = u_serviceManagerGetServiceStateKind(service->serviceManager, V_SPLICED_NAME); if ((kind != STATE_INITIALISING) && (kind != STATE_OPERATIONAL)) { - serviceManager->callback(kind, serviceManager->usrData); + service->callback(kind, service->usrData); } return V_EVENT_SERVICESTATE_CHANGED; } @@ -168,7 +161,8 @@ serviceAtExitInfoRemove( struct atExitInfo *info; /* See the comment at the start of u_service.h for more - * information about serviceAtExit functionality. */ + * information about serviceAtExit functionality. + */ os_mutexLock(&atExitMutex); info = c_iterTakeAction(atExitInfoList, @@ -191,14 +185,14 @@ serviceAtExitInfoAdd( struct atExitInfo *info; /* See the comment at the start of u_service.h for more - * information about serviceAtExit functionality. */ + * information about serviceAtExit functionality. + */ info = os_malloc(sizeof(struct atExitInfo)); - /* Don't c_keep this service, otherwise it will never be - * freed. - * Anyway, it will be removed from the list in the related - * deinit anyway. */ + /* Don't c_keep this service, otherwise it will never be freed. + * Anyway, it will be removed from the list in the related deinit anyway. + */ info->service = _this; info->action = action; info->data = privateData; @@ -223,66 +217,6 @@ serviceAtExitWalkAction( info->action(info->service, info->data); } - -#if 0 /* need to review if this is still needed */ -static void -freeKernelServiceObject ( - v_public e, - c_voidp argument) -{ - OS_UNUSED_ARG(argument); - v_serviceFree(v_service(e)); -} - -static os_result -u__serviceExceptionCallbackWrapper( - void * arg) -{ - os_result result = os_resultSuccess; - u_observable serviceEntity = (u_observable)arg; - v_participant kp; - v_leaseManager lm; - - assert(serviceEntity); - - /* do not detach when using single process as this does not function correctly for single process*/ - if(!os_serviceGetSingleProcess()) { - OS_REPORT(OS_ERROR, "u__serviceExceptionCallbackWrapper", U_RESULT_INTERNAL_ERROR, - "Exception occurred, will detach service from domain."); - - /* before freeing the service object be sure the attached processes from the lease manager and resend manager are stopped */ - if (U_RESULT_OK == u_participantReadClaim(u_entity(serviceEntity), (v_entity*)(&kp))) { - if (kp != NULL) { - lm = v_participantGetLeaseManager(kp); - if (lm != NULL) { - v_leaseManagerNotify(lm, NULL, V_EVENT_TERMINATE); - - } - v_participantResendManagerQuit(kp); - if (lm != NULL) { - os_threadWaitExit(u_participant(serviceEntity)->threadId, NULL); - c_free(lm); - } else { - OS_REPORT(OS_ERROR, "v_participantGetLeaseManager", - U_RESULT_INTERNAL_ERROR, "Access to lease manager failed."); - } - os_threadWaitExit(u_participant(serviceEntity)->threadIdResend, NULL); - u_participantRelease(serviceEntity); - } - } - /* calling the kernel service free directly because only the kernel administration needs to be removed */ - if (u_observableAction(serviceEntity,freeKernelServiceObject,NULL) != U_RESULT_OK){ - result = os_resultFail; - } - } - return result; -} -#endif - -/************************************************************** - * internal public funcions - **************************************************************/ - void u__serviceInitialise(void) { @@ -306,7 +240,7 @@ u__serviceExit( /* Wait for the services to be terminated. */ while (c_iterLength(atExitInfoList) > 0) { os_mutexUnlock(&atExitMutex); - os_sleep(delay); + ospl_os_sleep(delay); os_mutexLock(&atExitMutex); } @@ -319,11 +253,6 @@ u__serviceExit( os_mutexDestroy(&atExitMutex); } - -/************************************************************** - * constructor/destructor - **************************************************************/ - u_result u__serviceDeinitW( void *_vthis) @@ -399,6 +328,7 @@ u_serviceNewSpecialized ( } c_free(kQos); + c_free(kService); u_observableRelease(u_observable(domain), C_MM_RESERVATION_HIGH); return service; @@ -459,7 +389,7 @@ u_serviceInit( if (r == U_RESULT_OK) { name = v_serviceGetName(ks); if (name != NULL) { - path = (c_char *)os_malloc(strlen(SERVICE_PATH) + strlen(name)); + path = (c_char *)os_malloc(strlen(SERVICE_PATH) + strlen(name) + 1); /* NULL terminator is covered by '%s' in SERVICE_PATH constant */ os_sprintf(path, SERVICE_PATH, name); if (lockPages(v_objectKernel(ks), path)) { @@ -486,9 +416,6 @@ u_serviceInit( return r; } -/************************************************************** - * Public functions - **************************************************************/ u_bool u_serviceChangeState( const u_service _this, @@ -545,30 +472,18 @@ u_serviceWatchSpliceDaemon( const void *usrData) { u_result r = U_RESULT_OK; - u_eventMask mask; assert(_this != NULL); - r = u_observableGetListenerMask(u_observable(_this), &mask); - if (r == U_RESULT_OK) { - if (listener == NULL) { - r = u_observableRemoveListener(u_observable(_this),u_serviceSpliceListener); - if (r == U_RESULT_OK) { - mask &= ~V_EVENT_SERVICESTATE_CHANGED; - r = u_serviceManagerSetListener(_this->serviceManager, NULL, NULL); - } - } else { - r = u_serviceManagerSetListener(_this->serviceManager, listener, usrData); - if (r == U_RESULT_OK) { - mask |= V_EVENT_SERVICESTATE_CHANGED; - r = u_observableAddListener(u_observable(_this), - u_serviceSpliceListener, - _this->serviceManager); - } - } - if (r == U_RESULT_OK) { - r = u_observableSetListenerMask(u_observable(_this), mask); - } + if (listener == NULL) { + r = u_observableRemoveListener(u_observable(_this),u_serviceSpliceListener); + } else { + _this->callback = listener; + _this->usrData = (void *)usrData; + r = u_observableAddListener(u_observable(_this), + V_EVENT_SERVICESTATE_CHANGED, + u_serviceSpliceListener, + _this); } return r; } @@ -612,7 +527,8 @@ u_serviceAtExit( assert(action != NULL); /* See the comment at the start of u_service.h for more - * information about serviceAtExit functionality. */ + * information about serviceAtExit functionality. + */ r = u_observableWriteClaim(u_observable(_this), (v_public *)(&kernelService), C_MM_RESERVATION_ZERO); if(r == U_RESULT_OK) @@ -657,7 +573,7 @@ u_serviceThreadSetDomainId( domain = u_userLookupDomain(domainId); if (domain) { u_domainIdSetThreadSpecific(domain); - u_domainClose(domain); + (void)u_domainClose(domain); } } } @@ -706,7 +622,7 @@ u_serviceThreadWrapper( domain = u_userLookupDomain(tinfo->domainId); if (domain) { u_domainIdSetThreadSpecific(domain); - u_domainClose(domain); + (void)u_domainClose(domain); } } @@ -738,3 +654,24 @@ u_serviceThreadCreate( return r; } + +u_result +u_serviceFillNewGroups( + const u_service _this) +{ + u_result r; + v_service kservice; + + assert(_this != NULL); + + r = u_observableReadClaim(u_observable(_this), (v_public *)(&kservice), C_MM_RESERVATION_ZERO); + if(r == U_RESULT_OK) { + assert(kservice); + v_serviceFillNewGroups(kservice); + u_observableRelease(u_observable(_this), C_MM_RESERVATION_ZERO); + } else { + OS_REPORT(OS_WARNING, "u_serviceFillNewGroups", r, "Failed to claim service."); + } + return r; +} + diff --git a/src/user/code/u_serviceManager.c b/src/user/code/u_serviceManager.c index d5f61e50e..65b7d8ffa 100644 --- a/src/user/code/u_serviceManager.c +++ b/src/user/code/u_serviceManager.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -59,8 +60,6 @@ u_serviceManagerInit( assert(_this != NULL); result = u_entityInit(u_entity(_this), v_entity(sm), u_observableDomain(u_observable(participant))); - _this->callback = NULL; - _this->usrData = NULL; return result; } @@ -171,18 +170,6 @@ u_serviceManagerGetServices( return names; } -u_result -u_serviceManagerSetListener( - const u_serviceManager _this, - const u_serviceSplicedaemonListener callback, - const void *usrData) -{ - assert(_this != NULL); - _this->callback = (u_serviceSplicedaemonListener)callback; - _this->usrData = (void *)usrData; - return U_RESULT_OK; -} - c_bool u_serviceManagerRemoveService( const u_serviceManager _this, diff --git a/src/user/code/u_spliced.c b/src/user/code/u_spliced.c index 0b63bf8c0..621471d99 100644 --- a/src/user/code/u_spliced.c +++ b/src/user/code/u_spliced.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -40,10 +41,6 @@ static u_bool splicedStartedInThisProcess = FALSE; -/************************************************************** - * Private functions - **************************************************************/ - static u_result u_splicedInit( u_spliced spliced, @@ -96,10 +93,6 @@ getKernelSplicedaemon( return spliced; } -/************************************************************** - * constructor/destructor - **************************************************************/ - #define SPLICED_NAME "spliced" u_result @@ -143,13 +136,6 @@ u_splicedNew( #undef SPLICED_NAME -/************************************************************** - * Protected functions - **************************************************************/ - -/************************************************************** - * Public functions - **************************************************************/ u_result u_splicedKernelManager( const u_spliced spliced) @@ -380,7 +366,8 @@ u_splicedCleanupProcessInfo( * controls the lifecycle of SHM. In case cleanup of resources of another * process causes a deadlock, spliced should still be able to stop its own * threads, so cleanup by proxy shouldn't be done using u_observableAction(...), - * because that modifies the protectCount for this process. */ + * because that modifies the protectCount for this process. + */ handle = u_observableHandle(u_observable(spliced)); if((ures = u_handleClaim(handle, &entity)) == U_RESULT_OK){ ures = (u_result)v_kernelDetach(v_objectKernel(entity), procId); diff --git a/src/user/code/u_statusCondition.c b/src/user/code/u_statusCondition.c index 6efbc8e41..d38cc5cfa 100644 --- a/src/user/code/u_statusCondition.c +++ b/src/user/code/u_statusCondition.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,13 +21,12 @@ #include "u_statusCondition.h" #include "u__types.h" #include "u__object.h" -#include "u__observable.h" #include "u__entity.h" #include "u__participant.h" #include "u__domain.h" -#include "v_statusCondition.h" -#include "v_observable.h" +#include "u__observable.h" #include "v_observer.h" +#include "v_statusCondition.h" #include "v_entity.h" #include "v_event.h" #include "os_report.h" @@ -68,11 +68,11 @@ u_statusConditionNew( if (result == U_RESULT_OK) { kCond = v_public(v_statusConditionNew(kEntity)); if (kCond != NULL) { - v_observerSetEventMask(v_observer(kCond), V_EVENTMASK_ALL); _this = u_objectAlloc(sizeof(*_this), U_STATUSCONDITION, u__statusConditionDeinitW, u__statusConditionFreeW); if (_this) { u_domain domain = u_observableDomain(u_observable(entity)); - u_result result = u_observableInit(u_observable(_this), kCond, domain); + v_observerSetEventMask(v_observer(kCond), V_EVENTMASK_ALL); + result = u_observableInit(u_observable(_this), kCond, domain); if (result != U_RESULT_OK) { u_objectFree(_this); _this = NULL; diff --git a/src/user/code/u_subscriber.c b/src/user/code/u_subscriber.c index ae1de226a..00ac5798c 100644 --- a/src/user/code/u_subscriber.c +++ b/src/user/code/u_subscriber.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -71,8 +72,7 @@ u_subscriber u_subscriberNew( const u_participant participant, const os_char *name, - const u_subscriberQos qos, - u_bool enable) + const u_subscriberQos qos) { u_subscriber _this = NULL; v_subscriber ks; @@ -88,7 +88,7 @@ u_subscriberNew( result = u_observableWriteClaim(u_observable(participant),(v_public*)(&kp), C_MM_RESERVATION_LOW); if (result == U_RESULT_OK) { assert(kp); - ks = v_subscriberNew(kp, name, qos, enable); + ks = v_subscriberNew(kp, name, qos); if (ks != NULL) { _this = u_objectAlloc(sizeof(*_this), U_SUBSCRIBER, u__subscriberDeinitW, u__subscriberFreeW); if (_this != NULL) { @@ -203,11 +203,11 @@ u_subscriberCreateDataReader ( const os_char *name, const os_char *expression, const c_value params[], - const u_readerQos qos, - u_bool enable) + os_uint32 nrOfParams, + const u_readerQos qos) { assert(_this); - return u_dataReaderNew(_this, name, expression, params, qos, enable); + return u_dataReaderNew(_this, name, expression, params, nrOfParams, qos); } static c_bool diff --git a/src/user/code/u_subscriberQos.c b/src/user/code/u_subscriberQos.c index 92af014b5..352656830 100644 --- a/src/user/code/u_subscriberQos.c +++ b/src/user/code/u_subscriberQos.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/user/code/u_topic.c b/src/user/code/u_topic.c index 50c6e20ac..cf159acdb 100644 --- a/src/user/code/u_topic.c +++ b/src/user/code/u_topic.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -33,8 +34,6 @@ #include "v_topicQos.h" #include "v_entity.h" #include "v_filter.h" -#include "v_observable.h" -#include "v_observer.h" #include "os_report.h" #define u_topicReadClaim(_this, topic, claim) \ @@ -52,52 +51,24 @@ u__topicDeinitW( { u_result result; u_topic topic; - u_participant p; - v_participant kp; - v_topic kt; assert(_this != NULL); topic = u_topic(_this); - p = topic->participant; - result = u_observableWriteClaim(u_observable(p), (v_public *)(&kp), C_MM_RESERVATION_NO_CHECK); + + result = u__entityDeinitW(_this); if (result == U_RESULT_OK) { - assert(kp); - result = u_observableWriteClaim(u_observable(_this), (v_public *)(&kt), C_MM_RESERVATION_NO_CHECK); - if (result == U_RESULT_OK) { - assert(kt); - (void)v_observableRemoveObserver(v_observable(kt), v_observer(kp), NULL); - u_observableRelease(u_observable(_this), C_MM_RESERVATION_NO_CHECK); - } else { - OS_REPORT(OS_WARNING, "u__topicDeinitW", result, - "Claim topic failed. " - "Topic = 0x%"PA_PRIxADDR"", (os_address)_this); + if (topic->name) { + os_free(topic->name); + topic->name = NULL; } - u_observableRelease(u_observable(p), C_MM_RESERVATION_NO_CHECK); } else { - OS_REPORT(OS_WARNING, "u__topicDeinitW", result, - "Claim participant failed. " - "Topic = 0x%"PA_PRIxADDR"", (os_address)_this); + OS_REPORT(OS_WARNING, + "u__topicDeinitW", result, + "Operation u__topicDeinitW failed. " + "Topic = 0x%"PA_PRIxADDR"", + (os_address)_this); } - - if ((result == U_RESULT_OK) || - (result == U_RESULT_ALREADY_DELETED) || - (result == U_RESULT_OUT_OF_MEMORY)) { - result = u__entityDeinitW(_this); - if (result == U_RESULT_OK) { - if (topic->name) { - os_free(topic->name); - topic->name = NULL; - } - } else { - OS_REPORT(OS_WARNING, - "u__topicDeinitW", result, - "Operation u__topicDeinitW failed. " - "Topic = 0x%"PA_PRIxADDR"", - (os_address)_this); - } - } - return result; } @@ -130,14 +101,7 @@ u_topicNewFromTopicInfo( _this = u_objectAlloc(sizeof(*_this), U_TOPIC, u__topicDeinitW, u__topicFreeW); if (_this != NULL) { result = u_topicInit(_this,info->name,kt,p); - if (result == U_RESULT_OK) { - result = u_observableWriteClaim(u_observable(p), (v_public *)(&kp), C_MM_RESERVATION_ZERO); - if (result == U_RESULT_OK) { - assert(kp); - v_observableAddObserver(v_observable(kt), v_observer(kp), NULL); - u_observableRelease(u_observable(p), C_MM_RESERVATION_ZERO); - } - } else { + if (result != U_RESULT_OK) { OS_REPORT(OS_ERROR, "u_topicNew", result, "Initialisation failed. " "For Topic: <%s>", info->name); @@ -209,14 +173,7 @@ u_topicNew( _this = u_objectAlloc(sizeof(*_this), U_TOPIC, u__topicDeinitW, u__topicFreeW); if (_this != NULL) { result = u_topicInit(_this,name,kt,p); - if (result == U_RESULT_OK) { - result = u_observableWriteClaim(u_observable(p), (v_public *)(&kp), C_MM_RESERVATION_LOW); - if (result == U_RESULT_OK) { - assert(kp); - v_observableAddObserver(v_observable(kt), v_observer(kp), NULL); - u_observableRelease(u_observable(p), C_MM_RESERVATION_LOW); - } - } else { + if (result != U_RESULT_OK) { OS_REPORT(OS_ERROR, "u_topicNew", result, "Initialisation failed. " "For Topic: <%s>", name); @@ -432,7 +389,8 @@ u_bool u_topicContentFilterValidate ( const u_topic _this, const q_expr expr, - const c_value params[]) + const c_value params[], + os_uint32 nrOfParams) { v_topic topic; u_bool result; @@ -453,7 +411,7 @@ u_topicContentFilterValidate ( subexpr = q_getPar(expr, i); /* get rid of Q_EXPR_PROGRAM */ while ((term = q_getPar(subexpr, i++)) != NULL) { if (q_getTag(term) == Q_EXPR_WHERE) { - filter = v_filterNew(topic, term, params); + filter = v_filterNew(v_topicMessageType(topic), v_topicMessageKeyList(topic), term, params, nrOfParams); } } u_topicRelease(_this, C_MM_RESERVATION_LOW); @@ -469,7 +427,8 @@ u_bool u_topicContentFilterValidate2 ( const u_topic _this, const q_expr expr, - const c_value params[]) + const c_value params[], + os_uint32 nrOfParams) { v_topic topic; u_bool result; @@ -484,7 +443,7 @@ u_topicContentFilterValidate2 ( uResult = u_topicReadClaim(_this, &topic, C_MM_RESERVATION_LOW); if (uResult == U_RESULT_OK) { assert(topic); - filter = v_filterNew(topic, expr, params); + filter = v_filterNew(v_topicMessageType(topic), v_topicMessageKeyList(topic), expr, params, nrOfParams); u_topicRelease(_this, C_MM_RESERVATION_LOW); } if (filter != NULL) { diff --git a/src/user/code/u_topicQos.c b/src/user/code/u_topicQos.c index c425073b4..3de0b0113 100644 --- a/src/user/code/u_topicQos.c +++ b/src/user/code/u_topicQos.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/user/code/u_types.c b/src/user/code/u_types.c index 5c12ed126..405f57dec 100644 --- a/src/user/code/u_types.c +++ b/src/user/code/u_types.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,7 +21,6 @@ #include "u__types.h" #include "v_state.h" #include "v_instance.h" -#include "v_dataViewSample.h" const c_char * u_resultImage( diff --git a/src/user/code/u_user.c b/src/user/code/u_user.c index 5135f9719..fb7e3290c 100644 --- a/src/user/code/u_user.c +++ b/src/user/code/u_user.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -37,6 +38,7 @@ C_CLASS(u_domainAdmin); C_STRUCT(u_domainAdmin) { /* protected by global user lock */ u_domain domain; + os_address kernel; }; C_CLASS(u_user); @@ -46,8 +48,7 @@ C_STRUCT(u_user) { */ os_mutex mutex; os_cond cond; - /* - * The domainList attribute holds information about all connected domains. + /* The domainList attribute holds information about all connected domains. * The domainCount attribute specifies the max index in the domainList. * So any search range on the list can be limited to 1..domainCount. * domains that are detached are removed from the list and the entry in the @@ -65,14 +66,27 @@ C_STRUCT(u_user) { /* Should only be modified by pa_(in/de)crement! */ os_uint32 protectCount; /* The detachThreadId will have to be set by the detaching thread while - * holding the user->mutex and be re-set to NULL before releasing the + * holding the user->mutex and be re-set to 0 before releasing the * lock. A lock-boundary should thus never be crossed with detachThreadId * set to a different value than when the lock was acquired! */ - os_threadId detachThreadId; + os_ulong_int detachThreadId; os_uint detached; os_boolean detachingDomain; /* Indicates whether u_userSetupSignalHandling has been called */ os_boolean signalHandlingSetup; + os_boolean initialized; +}; + +C_CLASS(u_exceptionThreadContext); +C_STRUCT(u_exceptionThreadContext) { + os_ulong_int threadId; + c_bool isInProtectedArea; + os_int32 domainId; +}; + +C_CLASS(u_exitRequestThreadContext); +C_STRUCT(u_exitRequestThreadContext) { + os_ulong_int threadId; }; /** \brief Counter that keeps track of number of times user-layer is initialized. @@ -87,7 +101,8 @@ static pa_uint32_t _ospl_userInitCount = PA_UINT32_INIT(0); * This reference is only initialized once and implements the root to * all user (process) specific information. */ -void *user = NULL; +void * user = NULL; +static C_STRUCT(u_user) userAdmin; /* This method will lock the user-layer and return the reference to the user-layer object if successful. * If this method returns NULL then the user-layer is either not initialized or @@ -106,11 +121,11 @@ u__userLock(void) r = os_mutexLock_s(&u->mutex); if (r != os_resultSuccess) { /* The mutex is not valid so apparently the user-layer is either - * destroyed or in process of destruction. */ + * destroyed or in process of destruction. + */ u = NULL; - } else if (u->detached || (os_threadIdToInteger(u->detachThreadId) != 0 && - (os_threadIdToInteger(u->detachThreadId) != - os_threadIdToInteger(os_threadIdSelf())))) + } else if (u->detached || (u->detachThreadId != 0 && + (u->detachThreadId != os_threadIdToInteger(os_threadIdSelf())))) { /* Another thread is busy destroying the user-layer or the user- * layer is already destroyed. No access is allowed (anymore). @@ -123,8 +138,7 @@ u__userLock(void) return u; } -/* This method will unlock the user-layer. - */ +/* This method will unlock the user-layer. */ static void u__userUnlock(void) { @@ -139,7 +153,8 @@ u__userUnlock(void) static u_result u__userDetach( - _In_ os_uint32 flags) + _In_ os_uint32 flags, + _In_ os_ulong_int detachingThread) { u_user u; os_uint32 i; @@ -149,15 +164,23 @@ u__userDetach( u = u_user(user); os_mutexLock(&u->mutex); + if ((flags & U_USER_EXCEPTION) && detachingThread != 0 && detachingThread == u->detachThreadId) { + OS_REPORT(OS_ERROR, "u__userDetach", U_RESULT_INTERNAL_ERROR, + "Exception occurred, but u_userDetach already in progress. Bailing out."); + os_mutexUnlock(&u->mutex); + return U_RESULT_ALREADY_DELETED; + } + /* Disable access to user-layer for all other threads except for this thread. * Any following user access from other threads is gracefully - * aborted. */ - if(os_threadIdToInteger(u->detachThreadId) != 0) { + * aborted. + */ + if(u->detachThreadId != 0) { while(!u->detached) { os_condWait(&u->cond, &u->mutex); } } else { - u->detachThreadId = os_threadIdSelf(); + u->detachThreadId = os_threadIdToInteger(os_threadIdSelf()); /* Unlock the user-layer * Part of following code requires to unlock the user object @@ -173,7 +196,8 @@ u__userDetach( } /* Now signal other threads waiting on u__userDetach(...) that the - * work is done. */ + * work is done. + */ os_mutexLock(&u->mutex); u->detached = 1; os_condBroadcast(&u->cond); @@ -197,6 +221,12 @@ u__userDomainDetach( u = u__userLock(); if (u) { domain = u->domainList[idx].domain; + + if (domain && u_domainIsSingleProcess(domain)) { + u__userUnlock(); + return U_RESULT_OK; + } + if (domain) { detach = u_domainSetDetaching(domain, flags); } @@ -233,9 +263,10 @@ u__userGetDetachThreadId(void) r = os_mutexLock_s(&u->mutex); if (r != os_resultSuccess) { /* The mutex is not valid so apparently the user-layer is either - * destroyed or in process of destruction. Let id be 0*/ + * destroyed or in process of destruction. Let id be 0 + */ } else { - threadId = os_threadIdToInteger(u->detachThreadId); + threadId = u->detachThreadId; } os_mutexUnlock(&u->mutex); return threadId; @@ -248,29 +279,36 @@ u_userDetach( u_result result = U_RESULT_OK; if(!os_serviceGetSingleProcess()) { - result = u__userDetach(flags); + result = u__userDetach(flags, 0); } - return result; } static os_result -u__userExceptionHandler( - os_callbackArg exceptionCallbackArg, - void *unused) +u__userExceptionHandler(void *callingThreadContext, void *arg) { - OS_UNUSED_ARG(unused); + u_exceptionThreadContext thrContext = (u_exceptionThreadContext) callingThreadContext; - if ((exceptionCallbackArg.ThreadId == 0) || - (exceptionCallbackArg.ThreadId != u__userGetDetachThreadId())) - { + OS_UNUSED_ARG(arg); + + /** + * Because we are handling a synchronous exception here, which means the thread receiving the signal + * is now blocked on the signal handler, we can safely access its thread specific context here. + * If there is no thread specific context, then the thread in question has never accessed shared + * memory, so we can safely detach. If the proctectCount is 0, then the thread in question is currently + * not accessing any shared memory, and so we can also safely detach. In all other cases, shared + * memory is at risk, just bail out immediately (without detaching) in order to dump shared memory + * contents as intact as possible. + */ + assert(thrContext); + if (!thrContext->isInProtectedArea) { OS_REPORT(OS_ERROR, "u__userExceptionHandler", U_RESULT_INTERNAL_ERROR, - "An exception occurred, the process will now disconnects from all DDS domains"); - u__userDetach(U_USER_BLOCK_OPERATIONS | U_USER_EXCEPTION); - } else { + "An exception occurred, the process will now disconnect from all DDS domains"); + u__userDetach(U_USER_BLOCK_OPERATIONS | U_USER_EXCEPTION, thrContext->threadId); + } + else { OS_REPORT(OS_ERROR, "u__userExceptionHandler", U_RESULT_INTERNAL_ERROR, - "An exception occurred within the detach operation, " - "the Exception Handler cannot contineu and will ignore this signal."); + "Exception occurred while accessing shared memory: bailing out immediately"); } return os_resultSuccess; @@ -279,32 +317,69 @@ u__userExceptionHandler( static os_result u__userExitRequestHandler( os_callbackArg exitCallbackArg, - void *unused) + void *callingThreadContext, + void * unused) { + u_exitRequestThreadContext thrContext = (u_exitRequestThreadContext) callingThreadContext; + OS_UNUSED_ARG(unused); - if (!os_serviceGetSingleProcess()) { - /* Only in shared memory configuration there is a need to detach from the service. - * This is the user layers responsibility and is performed by the u_userDetach operation. - * Exit request is a normal condition so inform the u_userDetach operation to delete all - * remaining entities that belong to this process. - */ - if ((exitCallbackArg.ThreadId == 0) || - (exitCallbackArg.ThreadId != u__userGetDetachThreadId())) - { - OS_REPORT(OS_INFO, "u__userExitRequestHandler", U_RESULT_OK, - "Process received a termination signal and will detach from all DDS domains."); - u__userDetach(U_USER_DELETE_ENTITIES); - } else { - OS_REPORT(OS_WARNING, "u__userExitRequestHandler", U_RESULT_OK, - "Process received a termination signal from within the detach operation, " - "the Exit Handler will ignore this signal and NOT detach from the DDS domains."); - } + if ((thrContext->threadId == 0) || (thrContext->threadId != u__userGetDetachThreadId())) { + OS_REPORT(OS_WARNING, "u__userExitRequestHandler", U_RESULT_OK, + "Process received a termination signal and will detach from all DDS domains."); + u__userDetach(U_USER_DELETE_ENTITIES, thrContext->threadId); + } + else { + OS_REPORT(OS_WARNING, "u__userExitRequestHandler", U_RESULT_OK, + "Process received a termination signal from within the detach operation, " + "the Exit Handler will ignore this signal and NOT detach from the DDS domains."); } return os_signalHandlerFinishExitRequest(exitCallbackArg); } +static void * +u__userExceptionAllocThreadContextHandler() +{ + return os_malloc(C_SIZEOF(u_exceptionThreadContext)); +} + +static void +u__userExceptionGetThreadContextHandler(void *threadContext) +{ + u_exceptionThreadContext callingThreadContext = (u_exceptionThreadContext) threadContext; + + callingThreadContext->threadId = os_threadIdToInteger(os_threadIdSelf()); + callingThreadContext->domainId = v_kernelThreadInfoGetDomainId(); + callingThreadContext->isInProtectedArea = v_kernelThreadInProtectedArea(); +} + +static void +u__userExceptionFreeThreadContextHandler(void *threadContext) +{ + os_free(threadContext); +} + +static void * +u__userExitRequestAllocThreadContextHandler() +{ + return os_malloc(C_SIZEOF(u_exitRequestThreadContext)); +} + +static void +u__userExitRequestGetThreadContextHandler(void *threadContext) +{ + u_exitRequestThreadContext callingThreadContext = (u_exitRequestThreadContext) threadContext; + + callingThreadContext->threadId = os_threadIdToInteger(os_threadIdSelf()); +} + +static void +u__userExitRequestFreeThreadContextHandler(void *threadContext) +{ + os_free(threadContext); +} + /* This operation starts the os abstraction signal handler if not already started and * registers the user layer exit-request and exception handler depending on the type of process. * Processes can be applications or services and can be deployed as single process or shm configuration. @@ -326,10 +401,20 @@ u_userSetupSignalHandling( (void) os_signalHandlerNew(); if (!os_serviceGetSingleProcess()) { (void) os_signalHandlerEnableExceptionSignals(); - (void) os_signalHandlerRegisterExceptionCallback(u__userExceptionHandler, NULL); + (void) os_signalHandlerRegisterExceptionCallback( + u__userExceptionHandler, + u__userExceptionAllocThreadContextHandler, + u__userExceptionGetThreadContextHandler, + u__userExceptionFreeThreadContextHandler, + NULL); } if (!isService) { - (void) os_signalHandlerRegisterExitRequestCallback(u__userExitRequestHandler, NULL); + (void) os_signalHandlerRegisterExitRequestCallback( + u__userExitRequestHandler, + u__userExitRequestAllocThreadContextHandler, + u__userExitRequestGetThreadContextHandler, + u__userExitRequestFreeThreadContextHandler, + NULL); } } u__userUnlock(); @@ -354,10 +439,8 @@ u_result u_userInitialise( void) { - u_user u; u_result rm = U_RESULT_OK; os_uint32 initCount; - void* initUser; initCount = pa_inc32_nv(&_ospl_userInitCount); /* Any participant being an application or service may call this operation but @@ -383,46 +466,49 @@ u_userInitialise( /* Prepare the service component. */ u__serviceInitialise(); + /* Prepare the u_domain component. */ + u__domainMutexInit(); + /* Use indirection, as user != NULL is a precondition for user-layer * functions, so make sure it only holds true when the user-layer is - * initialized. */ - initUser = os_malloc(sizeof(C_STRUCT(u_user))); + * initialized. + */ - u = u_user(initUser); - os_mutexInit(&u->mutex, NULL); - os_condInit(&u->cond ,&u->mutex, NULL); - u->domainCount = 0; - u->protectCount = 0; - u->detachThreadId = OS_THREAD_ID_NONE; - u->detached = 0; - u->detachingDomain = OS_FALSE; - u->signalHandlingSetup = OS_FALSE; + os_mutexInit(&userAdmin.mutex, NULL); + os_condInit(&userAdmin.cond, &userAdmin.mutex, NULL); + userAdmin.domainCount = 0; + userAdmin.protectCount = 0; + userAdmin.detachThreadId = 0; + userAdmin.detached = 0; + userAdmin.detachingDomain = OS_FALSE; + userAdmin.signalHandlingSetup = OS_FALSE; - memset(u->domainList, 0, sizeof u->domainList); + memset(userAdmin.domainList, 0, sizeof userAdmin.domainList); os_procAtExit(u__userAtExitHandler); /* This will mark the user-layer initialized */ - user = initUser; + user = &userAdmin; } else { if(user == NULL){ - os_duration sleep = OS_DURATION_INIT(0, 100000); /* 100ms */ + os_duration sleep = OS_DURATION_INIT(0, 100000000); /* 100ms */ /* Another thread is currently initializing the user-layer. Since * user != NULL is a precondition for calls after u_userInitialise(), * a sleep is performed, to ensure that (if succeeded) successive - * user-layer calls will also actually pass.*/ - os_sleep(sleep); + * user-layer calls will also actually pass. + */ + ospl_os_sleep(sleep); } if(user == NULL){ /* Initialization did not succeed, undo increment and return error */ - initCount = pa_dec32_nv(&_ospl_userInitCount); rm = U_RESULT_INTERNAL_ERROR; OS_REPORT(OS_ERROR,"u_userInitialise", rm, "Internal error: User-layer should be initialized " "(initCount = %d), but user == NULL (waited 100ms).", initCount); } + (void) pa_dec32_nv(&_ospl_userInitCount); /* Decrement when > 1 to avoid possible overflow. */ } return rm; } @@ -443,9 +529,19 @@ u_userAddDomain( if (u->domainCount + 1 < MAX_DOMAINS) { u->domainCount++; for (index = 1;(index < MAX_DOMAINS) && (u->domainList[index].domain != NULL); index++) { } - ka = &u->domainList[index]; - ka->domain = domain; - u_domainIdSetThreadSpecific(domain); + if (index == MAX_DOMAINS) { + result = U_RESULT_OUT_OF_MEMORY; + OS_REPORT(OS_ERROR, + "u_userAddDomain",result, + "Max connected Domains (%d) reached!", MAX_DOMAINS - 1); + } else { + ka = &u->domainList[index]; + ka->domain = domain; + /* Cache the address to prevent locking for (read-only) lookups in multi-domain context, + * when the u_domain is already freed */ + ka->kernel = (os_address)domain->kernel; + u_domainIdSetThreadSpecific(domain); + } } else { /* Isn't it possible that if I have added and removed a domain 128 times, that you * have a domainList that is empty, but with a count of max? @@ -608,7 +704,7 @@ u_userServerId( kernel = v_objectKernel(o); for (i=1; idomainList[i].domain) { - if (u_domainAddress(u->domainList[i].domain) == (os_address)kernel) { + if (u->domainList[i].kernel == (os_address)kernel) { id = i << 24; } } @@ -654,7 +750,8 @@ u_userGetProcessName(void) size = os_procFigureIdentity(name, _INITIAL_LENGTH_); if(size >= _INITIAL_LENGTH_){ /* Output was truncated, only realloc once, since the identity is - * not changing. */ + * not changing. + */ name = os_realloc(name, (unsigned) size + 1); size = os_procFigureIdentity(name, (unsigned) size + 1); } diff --git a/src/user/code/u_usrClock.c b/src/user/code/u_usrClock.c index 662811df5..cc9c52db1 100644 --- a/src/user/code/u_usrClock.c +++ b/src/user/code/u_usrClock.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,9 +26,7 @@ #include "u__usrClock.h" #include "u__user.h" -/* User clock isn't a separate service anymore, to be compatible with old service name check both names - * see ticket OSPL-7348 - */ +/* User clock isn't a separate service anymore, to be compatible with old service name check both names */ #define U_CONF_USRCLOCK_SERVICENAME "UserClock" #define U_CONF_USRCLOCK_SERVICENAME_OLD "UserClockService" #define U_CONF_USRCLOCK_SERVICEMODULENAME "UserClockModule" @@ -123,6 +122,7 @@ u_usrClockInit ( const char *domainY2038 = NULL; os_boolean y2038Ready = OS_FALSE; os_boolean domainY2038Ready = OS_FALSE; + os_boolean ignoreUserClockforReportStack=OS_FALSE; assert(config != NULL); dc = cf_element(cf_elementChild(config, CFG_DOMAIN)); @@ -134,8 +134,13 @@ u_usrClockInit ( OS_REPORT(OS_WARNING, "u_usrClockInit", 0, "Found deprecated tag 'UserClockService' in configuration. Please use 'UserClock'"); } + } if (cfgUsrClockService != NULL) { + ignoreUserClockforReportStack = u_usrClockConfigElementAttributeStringToBoolean(cfgUsrClockService, "reporting", OS_TRUE); + if ( ignoreUserClockforReportStack == OS_FALSE) { + os_reportIgnoreUserClock(); + } cfgUsrClockModule = cf_element(cf_elementChild(cfgUsrClockService, U_CONF_USRCLOCK_SERVICEMODULENAME)); cfgUsrClockStart = cf_element(cf_elementChild(cfgUsrClockService, U_CONF_USRCLOCK_SERVICESTARTNAME)); cfgUsrClockStop = cf_element(cf_elementChild(cfgUsrClockService, U_CONF_USRCLOCK_SERVICESTOPNAME)); diff --git a/src/user/code/u_usrReportPlugin.c b/src/user/code/u_usrReportPlugin.c index 7f24c0531..a3779d9a7 100644 --- a/src/user/code/u_usrReportPlugin.c +++ b/src/user/code/u_usrReportPlugin.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/user/code/u_waitset.c b/src/user/code/u_waitset.c index 9d01863fe..8b1425371 100644 --- a/src/user/code/u_waitset.c +++ b/src/user/code/u_waitset.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -75,60 +76,47 @@ u__waitsetDeinitW( u_waitset _this; u_waitsetEntry entry; u_result result = U_RESULT_OK; - os_duration maxWaitDelay = OS_DURATION_INIT(10, 0); - os_timeW maxWaitTime = os_timeWAdd(os_timeWGet(), maxWaitDelay); _this = u_waitset(_vthis); os_mutexLock(&_this->mutex); _this->alive = FALSE; - while (_this->waitBusy && (os_timeWCompare(maxWaitTime, os_timeWGet()) == OS_MORE)) { + while (_this->waitBusy) { waitset_notify(_this, NULL); - os_condTimedWait(&_this->waitCv, &_this->mutex, maxWaitDelay); + os_condWait(&_this->waitCv, &_this->mutex); } - if (!_this->waitBusy) { - entry = c_iterTakeFirst(_this->entries); - while (entry != NULL) { - u_domain domain = u_observableDomain(u_observable(entry)); - result = u_domainRemoveWaitset(domain, _this); - if (result != U_RESULT_OK) { - OS_REPORT(OS_ERROR, - "u__waitsetDeinitW", result, - "Operation u_domainRemoveWaitset failed: " - "Waitset = 0x%"PA_PRIxADDR", result = %s", - (os_address)_this, u_resultImage(result)); - assert(FALSE); - } - result = u_objectFree_s(entry); - if (result == U_RESULT_ALREADY_DELETED) { - result = U_RESULT_OK; - } else if (result != U_RESULT_OK) { - OS_REPORT(OS_ERROR, - "u__waitsetDeinitW", result, - "Operation u_waitsetEntryFree failed: " - "Waitset = 0x%"PA_PRIxADDR", result = %s", - (os_address)_this, u_resultImage(result)); - result = U_RESULT_OK; - (void)result; - assert(FALSE); - } - entry = c_iterTakeFirst(_this->entries); + entry = c_iterTakeFirst(_this->entries); + while (entry != NULL) { + u_domain domain = u_observableDomain(u_observable(entry)); + result = u_domainRemoveWaitset(domain, _this); + if (result != U_RESULT_OK) { + OS_REPORT(OS_ERROR, + "u__waitsetDeinitW", result, + "Operation u_domainRemoveWaitset failed: " + "Waitset = 0x%"PA_PRIxADDR", result = %s", + (os_address)_this, u_resultImage(result)); + assert(FALSE); } - c_iterFree(_this->entries); - _this->entries = NULL; - - os_mutexUnlock(&_this->mutex); - u__objectDeinitW(_this); - } else { - result = U_RESULT_PRECONDITION_NOT_MET; - OS_REPORT(OS_ERROR, - "u__waitsetDeinitW", result, - "Operation u_waitsetEntryFree failed because threads still accessing the waitset: " - "Waitset = 0x%"PA_PRIxADDR", result = %s", - (os_address)_this, u_resultImage(result)); - os_mutexUnlock(&_this->mutex); + result = u_objectFree_s(entry); + if (result == U_RESULT_ALREADY_DELETED) { + result = U_RESULT_OK; + } else if (result != U_RESULT_OK) { + OS_REPORT(OS_ERROR, + "u__waitsetDeinitW", result, + "Operation u_waitsetEntryFree failed: " + "Waitset = 0x%"PA_PRIxADDR", result = %s", + (os_address)_this, u_resultImage(result)); + result = U_RESULT_OK; + (void)result; + assert(FALSE); + } + entry = c_iterTakeFirst(_this->entries); } + c_iterFree(_this->entries); + _this->entries = NULL; + os_mutexUnlock(&_this->mutex); + u__objectDeinitW(_this); return result; } @@ -139,17 +127,15 @@ u__waitsetFreeW( u_waitset w; w = u_waitset(_this); - if (!w->waitBusy) { - while (pa_ld32(&w->useCount) > 0) { - os_duration t = OS_DURATION_INIT(0, 100000000); - os_sleep(t); - } - - (void) os_condDestroy(&w->waitCv); - (void) os_condDestroy(&w->cv); - (void) os_mutexDestroy(&w->mutex); - u__objectFreeW(_this); + while (pa_ld32(&w->useCount) > 0) { + os_duration t = OS_DURATION_INIT(0, 100000000); + ospl_os_sleep(t); } + + (void) os_condDestroy(&w->waitCv); + (void) os_condDestroy(&w->cv); + (void) os_mutexDestroy(&w->mutex); + u__objectFreeW(_this); } u_waitset @@ -282,7 +268,6 @@ u_waitsetWaitAction2 ( a.count = 0; assert(_this != NULL); - assert(action != NULL); assert(OS_DURATION_ISPOSITIVE(timeout)); osr = os_mutexLock_s(&_this->mutex); @@ -302,7 +287,8 @@ u_waitsetWaitAction2 ( * If you don't do that, it's possible that this wait call sets * the waitBusy flag before the detach can wake up of its waitBusy * loop, meaning that the detach will block at least until the - * waitset is triggered again. */ + * waitset is triggered again. + */ while (_this->detachCnt > 0) { os_condWait(&_this->waitCv, &_this->mutex); } @@ -418,7 +404,8 @@ u_waitsetWaitAction ( * If you don't do that, it's possible that this wait call sets * the waitBusy flag before the detach can wake up of its waitBusy * loop, meaning that the detach will block at least until the - * waitset is triggered again. */ + * waitset is triggered again. + */ while (_this->detachCnt > 0) { os_condWait(&_this->waitCv, &_this->mutex); } diff --git a/src/user/code/u_waitsetEntry.c b/src/user/code/u_waitsetEntry.c index f58936b02..1afc12a06 100644 --- a/src/user/code/u_waitsetEntry.c +++ b/src/user/code/u_waitsetEntry.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,7 +28,7 @@ #include "u_participant.h" #include "v_waitset.h" -#include "v_observable.h" +#include "v_observer.h" #include "os_heap.h" #include "os_report.h" @@ -71,7 +72,7 @@ u_waitsetEntryRun( * just wait until all application waits has finished before starting. */ os_mutexUnlock(&_this->mutex); - os_sleep(delay); + ospl_os_sleep(delay); os_mutexLock(&_this->mutex); } while (os_threadIdToInteger(_this->thread) != os_threadIdToInteger(OS_THREAD_ID_NONE) && @@ -103,6 +104,30 @@ u_waitsetEntryRun( return NULL; } +static u_result +_waitsetEntryPrepareDestroy( + const u_waitsetEntry _this, + c_voidp eventArg) +{ + u_result result; + u_domain domain; + v_waitset kWaitset; + + assert(_this != NULL); + + domain = u_observableDomain(u_observable(_this)); + result = u_domainProtect(domain); + if (result == U_RESULT_OK) { + result = u_handleClaim(_this->handle, &kWaitset); + if (result == U_RESULT_OK) { + v_waitsetPrepareDestroy(kWaitset, eventArg); + (void)u_handleRelease(_this->handle); + } + u_domainUnprotect(); + } + return result; +} + static u_result u__waitsetEntryDeinitW ( void *_vthis) @@ -114,11 +139,11 @@ u__waitsetEntryDeinitW ( _this->alive = FALSE; thread = _this->thread; _this->thread = OS_THREAD_ID_NONE; - result = u_waitsetEntryTrigger(_this,NULL); + result = _waitsetEntryPrepareDestroy(_this,NULL); while (_this->waitCount != 0) { const os_duration delay = OS_DURATION_INIT(0, 1 * 1000 * 1000); os_mutexUnlock(&_this->mutex); - os_sleep(delay); + ospl_os_sleep(delay); os_mutexLock(&_this->mutex); } os_mutexUnlock(&_this->mutex); @@ -200,8 +225,7 @@ u_waitsetEntrySetMode( if ((multimode == TRUE) && (os_threadIdToInteger(_this->thread) == os_threadIdToInteger(OS_THREAD_ID_NONE))) { - /* Switch to multi domain mode and start waitset entry thread. - */ + /* Switch to multi domain mode and start waitset entry thread. */ os_threadAttrInit(&osThreadAttr); osResult = os_threadCreate( &_this->thread, @@ -219,8 +243,7 @@ u_waitsetEntrySetMode( if ((multimode == FALSE) && (os_threadIdToInteger(_this->thread) != os_threadIdToInteger(OS_THREAD_ID_NONE))) { - /* Switch to single domain mode and stop waitset entry thread. - */ + /* Switch to single domain mode and stop waitset entry thread. */ u_domain domain = u_observableDomain(u_observable(_this)); result = u_domainProtect(domain); if (result == U_RESULT_OK) { @@ -310,8 +333,13 @@ u_waitsetEntryDetach ( result = U_RESULT_UNSUPPORTED; } u_observableRelease(observable, C_MM_RESERVATION_NO_CHECK); + } else if (result == U_RESULT_ALREADY_DELETED) { + /* The end result of detaching an already deleted condition is not incorrect. + * So don't report an error in this case and return OK. + */ + result = V_RESULT_OK; } else { - OS_REPORT(OS_ERROR, "u_waitsetEntryDetach", result, + OS_REPORT(OS_WARNING, "u_waitsetEntryDetach", result, "Could not claim supplied entity (0x%"PA_PRIxADDR").", (os_address)observable); } @@ -356,7 +384,7 @@ u_waitsetEntryWait( result = u_resultFromKernel(kr); os_mutexLock(&_this->mutex); _this->waitCount--; - u_handleRelease(_this->handle); + (void)u_handleRelease(_this->handle); os_mutexUnlock(&_this->mutex); } else { os_mutexUnlock(&_this->mutex); @@ -423,7 +451,7 @@ u_waitsetEntryTrigger( result = u_handleClaim(_this->handle, &kWaitset); if (result == U_RESULT_OK) { v_waitsetTrigger(kWaitset, eventArg); - u_handleRelease(_this->handle); + (void)u_handleRelease(_this->handle); } u_domainUnprotect(); } diff --git a/src/user/code/u_waitsetEntry.h b/src/user/code/u_waitsetEntry.h index df9b9d286..7f8313f1c 100644 --- a/src/user/code/u_waitsetEntry.h +++ b/src/user/code/u_waitsetEntry.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/user/code/u_writer.c b/src/user/code/u_writer.c index 6185c4520..f18b3db71 100644 --- a/src/user/code/u_writer.c +++ b/src/user/code/u_writer.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -266,9 +267,8 @@ u_writeWithHandleAction( assert(_this != NULL); assert(action != NULL); - assert(copy != NULL); - result = u_observableWriteClaim(u_observable(_this), (v_public *)(&writer), C_MM_RESERVATION_ZERO); + result = u_observableWriteClaim(u_observable(_this), (v_public *)(&writer), C_MM_RESERVATION_HIGH); if ((result == U_RESULT_OK) && (writer != NULL)) { if (u_instanceHandleIsNil(handle)) { instance = NULL; @@ -288,7 +288,6 @@ u_writeWithHandleAction( /* if the instance is already deleted, * then the result of an unregister is PRECONDITION_NOT_MET. - * RP : is that statment correct in this generic function? */ result = U_RESULT_PRECONDITION_NOT_MET; OS_REPORT(OS_ERROR, "u_writeWithHandleAction", result, @@ -299,6 +298,8 @@ u_writeWithHandleAction( if (result == U_RESULT_OK) { if (data != NULL) { + assert(copy != NULL); + message = v_topicMessageNew_s(writer->topic); if (message) { to = (void *) (message + 1); @@ -352,7 +353,7 @@ u_writeWithHandleAction( } u_instanceHandleRelease(handle); } - u_observableRelease(u_observable(_this), C_MM_RESERVATION_ZERO); + u_observableRelease(u_observable(_this), C_MM_RESERVATION_HIGH); } return result; } @@ -782,11 +783,7 @@ u_writerGetMatchedSubscriptions ( void *arg) { v_writer writer; - v_spliced spliced; - v_kernel kernel; u_result result; - c_iter participants; - v_participant participant; assert(_this != NULL); assert(action != NULL); @@ -794,17 +791,7 @@ u_writerGetMatchedSubscriptions ( result = u_writerReadClaim(_this, &writer, C_MM_RESERVATION_HIGH); if (result == U_RESULT_OK) { assert(writer); - kernel = v_objectKernel(writer); - - participants = v_resolveParticipants(kernel, V_SPLICED_NAME); - assert(c_iterLength(participants) == 1); - participant = v_participant(c_iterTakeFirst(participants)); - spliced = v_spliced(participant); - c_free(participant); - c_iterFree(participants); - - result = u_resultFromKernel( - v_splicedGetMatchedSubscriptions(spliced, writer, action, arg)); + result = u_resultFromKernel(v_writerReadMatchedSubscriptions(writer, action, arg)); u_writerRelease(_this, C_MM_RESERVATION_HIGH); } return result; @@ -818,11 +805,7 @@ u_writerGetMatchedSubscriptionData ( void *arg) { v_writer writer; - v_spliced spliced; - v_kernel kernel; u_result result; - c_iter participants; - v_participant participant; assert(_this != NULL); assert(action != NULL); @@ -830,22 +813,10 @@ u_writerGetMatchedSubscriptionData ( result = u_writerReadClaim(_this, &writer, C_MM_RESERVATION_HIGH); if (result == U_RESULT_OK) { assert(writer); - kernel = v_objectKernel(writer); - - participants = v_resolveParticipants(kernel, V_SPLICED_NAME); - assert(c_iterLength(participants) == 1); - participant = v_participant(c_iterTakeFirst(participants)); - spliced = v_spliced(participant); - c_free(participant); - c_iterFree(participants); - result = u_resultFromKernel( - v_splicedGetMatchedSubscriptionData( - spliced, - writer, - u_instanceHandleToGID(subscription_handle), - action, - arg)); + v_writerReadMatchedSubscriptionData(writer, + u_instanceHandleToGID(subscription_handle), + action, arg)); u_writerRelease(_this, C_MM_RESERVATION_HIGH); } return result; diff --git a/src/user/code/u_writerQos.c b/src/user/code/u_writerQos.c index 491274c40..ca77dcdb7 100644 --- a/src/user/code/u_writerQos.c +++ b/src/user/code/u_writerQos.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/user/include/u_builtin.h b/src/user/include/u_builtin.h index 1762b0c3f..237294dbb 100644 --- a/src/user/include/u_builtin.h +++ b/src/user/include/u_builtin.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/user/include/u_cfAttribute.h b/src/user/include/u_cfAttribute.h index 938402f43..5e1004663 100644 --- a/src/user/include/u_cfAttribute.h +++ b/src/user/include/u_cfAttribute.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/user/include/u_cfData.h b/src/user/include/u_cfData.h index ff61b8aeb..f381b48fa 100644 --- a/src/user/include/u_cfData.h +++ b/src/user/include/u_cfData.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/user/include/u_cfElement.h b/src/user/include/u_cfElement.h index 1d1606abe..2ce2c4469 100644 --- a/src/user/include/u_cfElement.h +++ b/src/user/include/u_cfElement.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/user/include/u_cfNode.h b/src/user/include/u_cfNode.h index db8cca459..ca4206a76 100644 --- a/src/user/include/u_cfNode.h +++ b/src/user/include/u_cfNode.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/user/include/u_cmsoap.h b/src/user/include/u_cmsoap.h index a3ed8a2fe..93ccee9c5 100755 --- a/src/user/include/u_cmsoap.h +++ b/src/user/include/u_cmsoap.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/user/include/u_dataReader.h b/src/user/include/u_dataReader.h index 276c6bca6..068a1cf3e 100644 --- a/src/user/include/u_dataReader.h +++ b/src/user/include/u_dataReader.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -71,8 +72,8 @@ u_dataReaderNew( const os_char *name, const os_char *expr, const c_value params[], - const u_readerQos qos, - u_bool enable); + os_uint32 nrOfParams, + const u_readerQos qos); OS_API u_result u_dataReaderGetQos ( diff --git a/src/user/include/u_dataView.h b/src/user/include/u_dataView.h index d24c10aa0..e590f02e2 100644 --- a/src/user/include/u_dataView.h +++ b/src/user/include/u_dataView.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -38,7 +39,7 @@ extern "C" { #define u_dataView(o) \ ((u_dataView)u_objectCheckType(u_object(o),U_DATAVIEW)) -OS_API u_dataView +OS_API u_dataView u_dataViewNew( const u_dataReader r, const os_char *name, @@ -54,15 +55,15 @@ u_dataViewSetQos ( const u_dataView _this, const u_dataViewQos qos); -OS_API u_result +OS_API u_result u_dataViewRead( const u_dataView _this, u_sampleMask mask, u_readerAction action, void *actionArg, const os_duration timeout); - -OS_API u_result + +OS_API u_result u_dataViewTake( const u_dataView _this, u_sampleMask mask, @@ -70,7 +71,7 @@ u_dataViewTake( void *actionArg, const os_duration timeout); -OS_API u_result +OS_API u_result u_dataViewReadInstance( const u_dataView _this, u_instanceHandle h, @@ -78,8 +79,8 @@ u_dataViewReadInstance( u_readerAction action, void *actionArg, const os_duration timeout); - -OS_API u_result + +OS_API u_result u_dataViewTakeInstance( const u_dataView _this, u_instanceHandle h, @@ -87,8 +88,8 @@ u_dataViewTakeInstance( u_readerAction action, void *actionArg, const os_duration timeout); - -OS_API u_result + +OS_API u_result u_dataViewReadNextInstance( const u_dataView _this, u_instanceHandle h, @@ -96,8 +97,8 @@ u_dataViewReadNextInstance( u_readerAction action, void *actionArg, const os_duration timeout); - -OS_API u_result + +OS_API u_result u_dataViewTakeNextInstance( const u_dataView _this, u_instanceHandle h, @@ -112,8 +113,8 @@ u_dataViewLookupInstance( void *keyTemplate, u_copyIn copyIn, u_instanceHandle *handle); - -#undef OS_API + +#undef OS_API #if defined (__cplusplus) } diff --git a/src/user/include/u_dataViewQos.h b/src/user/include/u_dataViewQos.h index f585ad451..301c080cf 100644 --- a/src/user/include/u_dataViewQos.h +++ b/src/user/include/u_dataViewQos.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/user/include/u_dbmsconnect.h b/src/user/include/u_dbmsconnect.h new file mode 100644 index 000000000..282b74eeb --- /dev/null +++ b/src/user/include/u_dbmsconnect.h @@ -0,0 +1,52 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#ifndef U_DBMSCONNECT_H +#define U_DBMSCONNECT_H + +#include "u_types.h" + +#if defined (__cplusplus) +extern "C" { +#endif + +#ifdef OSPL_BUILD_CORE +#define OS_API OS_API_EXPORT +#else +#define OS_API OS_API_IMPORT +#endif +/* !!!!!!!!NOTE From here no more includes are allowed!!!!!!! */ + +OS_API u_service +u_dbmsconnectNew ( + const os_char *uri, + const u_domainId_t id, + const os_int32 timeout, /* in seconds */ + const os_char *name, + const u_participantQos qos, + c_bool enable); + +#undef OS_API + +#if defined (__cplusplus) +} +#endif + +#endif /* U_DBMSCONNECT_H */ diff --git a/src/user/include/u_dispatcher.h b/src/user/include/u_dispatcher.h deleted file mode 100644 index beb58daff..000000000 --- a/src/user/include/u_dispatcher.h +++ /dev/null @@ -1,81 +0,0 @@ -/* - * OpenSplice DDS - * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -#ifndef U_DISPATCHER_H -#define U_DISPATCHER_H - -#include "u_types.h" - -#if defined (__cplusplus) -extern "C" { -#endif -#include "os_if.h" - -#ifdef OSPL_BUILD_CORE -#define OS_API OS_API_EXPORT -#else -#define OS_API OS_API_IMPORT -#endif -/* !!!!!!!!NOTE From here no more includes are allowed!!!!!!! */ - -/* Returns mask of events that have been handled by the listener. */ -typedef u_eventMask (*u_dispatcherListener)(u_dispatcher o, u_eventMask event, void *usrData); -typedef void (*u_dispatcherThreadAction)(u_dispatcher o, void *usrData); - -#define u_dispatcher(o) ((u_dispatcher)(o)) - -OS_API u_result -u_dispatcherInsertListener( - const u_dispatcher o, - const u_observableListener l, - void *userData); - -OS_API u_result -u_dispatcherAppendListener( - const u_dispatcher o, - const u_observableListener l, - void *userData); - -OS_API u_result -u_dispatcherRemoveListener( - const u_dispatcher o, - const u_observableListener l); - -OS_API u_result -u_dispatcherNotify( - const u_dispatcher o); - -OS_API u_result -u_dispatcherSetEventMask( - const u_dispatcher o, - u_eventMask eventMask); - -OS_API u_result -u_dispatcherGetEventMask( - const u_dispatcher o, - u_eventMask *eventMask); - -#undef OS_API - -#if defined (__cplusplus) -} -#endif - -#endif - diff --git a/src/user/include/u_domain.h b/src/user/include/u_domain.h index 32000b8a5..70d50e2f4 100644 --- a/src/user/include/u_domain.h +++ b/src/user/include/u_domain.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -38,7 +39,7 @@ extern "C" { #define u_domain(p) ((u_domain)(p)) -#define DOMAIN_NAME "The default Domain" +#define U_DOMAIN_NAME "The default Domain" #define U_DOMAIN_ID_DEFAULT 0 #define U_DOMAIN_ID_ANY 0x7fffffff #define U_DOMAIN_ID_INVALID -1 @@ -204,7 +205,7 @@ OS_API u_result u_domainWalkParticipants( const u_domain _this, const u_participantAction action, - void *actionArg); + void *actionArg); OS_API u_participant u_domainCreateParticipant ( @@ -232,23 +233,58 @@ u_domain_get_xml_descriptor ( OS_API u_domainId_t u_domainId( - _In_ const u_domain _this) __nonnull_all__; + _In_ const u_domain _this); OS_API const char * u_domainName( - _In_ const u_domain _this) __nonnull_all__; + _In_ const u_domain _this); OS_API c_type u_domain_lookup_type( const u_domain _this, const os_char *type_name); +/** \brief The Domain Read Operation + * + * This operation performs a read action on durable messages matching a given interest. + * The interest is specified by partition-topic expression and message query. + * + * \param domain the domain containing the durable data. + * \param partition an expression specifying partition interest. + * \param topic an expression specifying topic interest. + * \param query an expression specifying message interest. + * \param action the action function that is executed on each matching message. + * \param actionArg a user data context that is passed to each invokation of the action function. + * + * \return the result of this operation. + */ +typedef u_result (*u_domainReadAction)(const v_group group, const v_groupInstance instance, const v_message msg, void *actionArg); + +OS_API u_result +u_domainRead( + _In_ const u_domain _this, + _In_ const os_char *partition, + _In_ const os_char *topic, + _In_ const os_char *query, + _In_ const u_domainReadAction action, + _In_ const void *actionArg); + +typedef u_result (*u_domainGroupReadAction)(const v_group group, void *actionArg); + +OS_API u_result +u_domainGroupRead( + _In_ const u_domain _this, + _In_ const os_char *partition, + _In_ const os_char *topic, + _In_ const u_domainGroupReadAction action, + _In_ const void *actionArg); + /** \brief Compare domainId with the domain domainURI and domainName. */ OS_API u_bool u_domainCompareId( - const u_domain _this, - const u_domainId_t id); + _In_ const u_domain _this, + _In_ const u_domainId_t id); OS_API os_sharedHandle u_domainSharedMemoryHandle ( @@ -267,6 +303,24 @@ u_domainEnableStatistics( const u_domain _this, const os_char *categoryName); +OS_API u_result +u_domainGetAlignedState( + const u_domain _this, + os_boolean *aligned); + +OS_API u_result +u_domainSetAlignedState( + const u_domain _this, + os_boolean aligned); + +OS_API u_result +u_domainTransactionsPurge( + const u_domain _this); + +#define U_ISOLATE_NONE V_ISOLATE_NONE +#define U_ISOLATE_DEAF V_ISOLATE_DEAF +#define U_ISOLATE_MUTE V_ISOLATE_MUTE +#define U_ISOLATE_ALL V_ISOLATE_ALL #undef OS_API #if defined (__cplusplus) diff --git a/src/user/include/u_durability.h b/src/user/include/u_durability.h index 4f81f70cd..622de759d 100644 --- a/src/user/include/u_durability.h +++ b/src/user/include/u_durability.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -51,6 +52,19 @@ u_durabilityNew ( const u_participantQos qos, c_bool enable); +/** + * @param purgeSuppressionCount optional pointer to store new-value of purge- + * suppression counter. ONLY FOR LOGGING.s + */ +OS_API u_result +u_durabilityHeartbeatProcessed ( + _In_ u_service durability, + _Out_opt_ os_uint32 *purgeSuppressionCount ); + +OS_API u_result +u_durabilityReportKernelGroupCompleteness ( + _In_ u_service durability); + #undef OS_API #if defined (__cplusplus) diff --git a/src/user/include/u_entity.h b/src/user/include/u_entity.h index bdb0e41ab..c044c34bc 100644 --- a/src/user/include/u_entity.h +++ b/src/user/include/u_entity.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -127,8 +128,7 @@ u_entityWalkEntities ( u_bool (*action)(v_entity e, void *arg), void *arg); -/* - * Like u_entityWalkEntities, this function is also DEPRECATED. It is +/* Like u_entityWalkEntities, this function is also DEPRECATED. It is * currently still used by the C&M API, but should be removed in the future. */ OS_API u_result @@ -175,6 +175,18 @@ OS_API u_bool u_entityDisableCallbacks ( const u_entity _this); +OS_API u_result +u_entityGetProperty( + _In_ const u_entity _this, + _In_ const os_char * name, + _Out_ os_char ** value); + +OS_API u_result +u_entitySetProperty( + _In_ const u_entity _this, + _In_ const os_char * name, + _In_ const os_char * value); + #undef OS_API #if defined (__cplusplus) diff --git a/src/user/include/u_group.h b/src/user/include/u_group.h index 592d953fc..a0edb9840 100644 --- a/src/user/include/u_group.h +++ b/src/user/include/u_group.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/user/include/u_groupQueue.h b/src/user/include/u_groupQueue.h index d8989a1fd..21e089956 100644 --- a/src/user/include/u_groupQueue.h +++ b/src/user/include/u_groupQueue.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -44,7 +45,12 @@ u_groupQueueNew ( c_ulong queueSize, const u_readerQos qos, c_iter expr); - + +OS_API u_result +u_groupQueueSize( + u_groupQueue _this, + c_ulong * size); + #undef OS_API #if defined (__cplusplus) diff --git a/src/user/include/u_instanceHandle.h b/src/user/include/u_instanceHandle.h index d41298009..b73117f47 100644 --- a/src/user/include/u_instanceHandle.h +++ b/src/user/include/u_instanceHandle.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -30,8 +31,8 @@ extern "C" { typedef c_longlong u_instanceHandle; #define U_INSTANCEHANDLE_NIL (0) +#include "u_types.h" -#include "u_user.h" #ifdef OSPL_BUILD_CORE #define OS_API OS_API_EXPORT @@ -61,6 +62,16 @@ OS_API u_instanceHandle u_instanceHandleNew( v_public object); +/* This function will assign application specific user data to the instance handle and return the old value. */ +OS_API u_result +u_instanceHandleSetUserData( + u_instanceHandle _this, + void *userData); + +/* This function will return the user data assigned to this instance handle. */ +OS_API void * +u_instanceHandleGetUserData( + u_instanceHandle _this); #undef OS_API diff --git a/src/user/include/u_listener.h b/src/user/include/u_listener.h index 9533007e8..96b43becf 100644 --- a/src/user/include/u_listener.h +++ b/src/user/include/u_listener.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/user/include/u_networkReader.h b/src/user/include/u_networkReader.h index c11a5dea2..92ef7a09a 100644 --- a/src/user/include/u_networkReader.h +++ b/src/user/include/u_networkReader.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -43,8 +44,8 @@ u_networkReaderNew( const os_char *name, const u_readerQos qos, u_bool ignoreReliabilityQoS); - -OS_API u_result + +OS_API u_result u_networkReaderCreateQueue( const u_networkReader _this, os_uint32 queueSize, @@ -55,17 +56,17 @@ u_networkReaderCreateQueue( u_bool useAsDefault, os_uint32 *queueId, /* out */ const os_char *name); - -OS_API u_result + +OS_API u_result u_networkReaderTrigger( const u_networkReader _this, os_uint32 queueId); - -OS_API u_result + +OS_API u_result u_networkReaderRemoteActivityDetected( const u_networkReader _this); - -OS_API u_result + +OS_API u_result u_networkReaderRemoteActivityLost( const u_networkReader _this); diff --git a/src/user/include/u_networking.h b/src/user/include/u_networking.h index 94d9d68fe..61ed02eb9 100644 --- a/src/user/include/u_networking.h +++ b/src/user/include/u_networking.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/user/include/u_nwbridge.h b/src/user/include/u_nwbridge.h index 108c4e0d4..eee716f64 100644 --- a/src/user/include/u_nwbridge.h +++ b/src/user/include/u_nwbridge.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/user/include/u_object.h b/src/user/include/u_object.h index 9bb6b7878..3ddb77514 100644 --- a/src/user/include/u_object.h +++ b/src/user/include/u_object.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/user/include/u_observable.h b/src/user/include/u_observable.h index 4757ce240..15044c7b7 100644 --- a/src/user/include/u_observable.h +++ b/src/user/include/u_observable.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -153,6 +154,7 @@ u_observableGid ( OS_API u_result u_observableAddListener( const u_observable _this, + const u_eventMask eventMask, const u_observableListener listener, void *userData); @@ -162,7 +164,7 @@ u_observableRemoveListener( const u_observableListener listener); OS_API u_result -u_observableNotifyListener( +u_observableNotify( const u_observable _this); OS_API u_result diff --git a/src/user/include/u_participant.h b/src/user/include/u_participant.h index f4522b188..cf03c37cd 100644 --- a/src/user/include/u_participant.h +++ b/src/user/include/u_participant.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -46,6 +47,7 @@ #include "u_cfElement.h" #include "u_types.h" +#include "u_instanceHandle.h" #include "u_object.h" #include "u_topic.h" #include "u_publisher.h" @@ -234,6 +236,26 @@ u_domainParticipant_create_copy_cache( void* arg ); +OS_API u_result +u_participantIgnoreParticipant( + const u_participant _this, + const u_instanceHandle handle); + +OS_API u_result +u_participantIgnoreTopic( + const u_participant _this, + const u_instanceHandle handle); + +OS_API u_result +u_participantIgnoreSubscription( + const u_participant _this, + const u_instanceHandle handle); + +OS_API u_result +u_participantIgnorePublication( + const u_participant _this, + const u_instanceHandle handle); + #undef OS_API #if defined (__cplusplus) diff --git a/src/user/include/u_participantQos.h b/src/user/include/u_participantQos.h index 9418834f0..1ac6b3fc3 100644 --- a/src/user/include/u_participantQos.h +++ b/src/user/include/u_participantQos.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/user/include/u_partition.h b/src/user/include/u_partition.h index e6e9869bc..d21454712 100644 --- a/src/user/include/u_partition.h +++ b/src/user/include/u_partition.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/user/include/u_partitionQos.h b/src/user/include/u_partitionQos.h index 452ced23c..cb90cb94a 100644 --- a/src/user/include/u_partitionQos.h +++ b/src/user/include/u_partitionQos.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/user/include/u_publisher.h b/src/user/include/u_publisher.h index 25ee6cacf..c14a92eb9 100644 --- a/src/user/include/u_publisher.h +++ b/src/user/include/u_publisher.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/user/include/u_publisherQos.h b/src/user/include/u_publisherQos.h index dbe80a78d..42a6d5941 100644 --- a/src/user/include/u_publisherQos.h +++ b/src/user/include/u_publisherQos.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/user/include/u_query.h b/src/user/include/u_query.h index 6ba3ca246..a3fc41236 100644 --- a/src/user/include/u_query.h +++ b/src/user/include/u_query.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/user/include/u_reader.h b/src/user/include/u_reader.h index 018e45853..d20921bd9 100644 --- a/src/user/include/u_reader.h +++ b/src/user/include/u_reader.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/user/include/u_readerQos.h b/src/user/include/u_readerQos.h index 5ef19b8fb..bdf65f48e 100644 --- a/src/user/include/u_readerQos.h +++ b/src/user/include/u_readerQos.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/user/include/u_rnr.h b/src/user/include/u_rnr.h index 930873628..545eb4462 100644 --- a/src/user/include/u_rnr.h +++ b/src/user/include/u_rnr.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/user/include/u_service.h b/src/user/include/u_service.h index e9b93d3bc..45d06b3cd 100644 --- a/src/user/include/u_service.h +++ b/src/user/include/u_service.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -284,6 +285,10 @@ u_serviceAtExit( u_serviceAtExitAction action, void *privateData); +OS_API u_result +u_serviceFillNewGroups( + const u_service _this); + typedef struct u_service_cmdopts { char *uri; diff --git a/src/user/include/u_serviceManager.h b/src/user/include/u_serviceManager.h index 7623ca1f6..ba5e079be 100644 --- a/src/user/include/u_serviceManager.h +++ b/src/user/include/u_serviceManager.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/user/include/u_spliced.h b/src/user/include/u_spliced.h index 330c187dd..3d3ca231d 100644 --- a/src/user/include/u_spliced.h +++ b/src/user/include/u_spliced.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/user/include/u_statusCondition.h b/src/user/include/u_statusCondition.h index 0dd90aad9..42d596b00 100644 --- a/src/user/include/u_statusCondition.h +++ b/src/user/include/u_statusCondition.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/user/include/u_subscriber.h b/src/user/include/u_subscriber.h index 95c1bf864..d37819cdb 100644 --- a/src/user/include/u_subscriber.h +++ b/src/user/include/u_subscriber.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -42,8 +43,7 @@ OS_API u_subscriber u_subscriberNew ( const u_participant _scope, const os_char *name, - const u_subscriberQos qos, - u_bool enable); + const u_subscriberQos qos); OS_API u_result u_subscriberGetQos ( @@ -69,8 +69,8 @@ u_subscriberCreateDataReader ( const os_char *name, const os_char *expression, const c_value params[], - const u_readerQos qos, - u_bool enable); + os_uint32 nrOfParams, + const u_readerQos qos); OS_API u_result u_subscriberGetDataReaders ( diff --git a/src/user/include/u_subscriberQos.h b/src/user/include/u_subscriberQos.h index 98a3539c8..77c0728de 100644 --- a/src/user/include/u_subscriberQos.h +++ b/src/user/include/u_subscriberQos.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/user/include/u_topic.h b/src/user/include/u_topic.h index f801c162c..bf6c6ecfb 100644 --- a/src/user/include/u_topic.h +++ b/src/user/include/u_topic.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -102,13 +103,15 @@ OS_API u_bool u_topicContentFilterValidate ( const u_topic _this, const q_expr expr, - const c_value params[]); + const c_value params[], + os_uint32 nrOfParams); OS_API u_bool u_topicContentFilterValidate2 ( const u_topic _this, const q_expr expr, - const c_value params[]); + const c_value params[], + os_uint32 nrOfParams); #undef OS_API diff --git a/src/user/include/u_topicQos.h b/src/user/include/u_topicQos.h index 23a68dc46..0a38f0584 100644 --- a/src/user/include/u_topicQos.h +++ b/src/user/include/u_topicQos.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/user/include/u_types.h b/src/user/include/u_types.h index 425b12fff..fae513248 100644 --- a/src/user/include/u_types.h +++ b/src/user/include/u_types.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/user/include/u_user.h b/src/user/include/u_user.h index b56040fa4..aa3652ed3 100644 --- a/src/user/include/u_user.h +++ b/src/user/include/u_user.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/user/include/u_waitset.h b/src/user/include/u_waitset.h index cb6e072a2..0f7106298 100644 --- a/src/user/include/u_waitset.h +++ b/src/user/include/u_waitset.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/user/include/u_writer.h b/src/user/include/u_writer.h index af460a53d..8bdced94f 100644 --- a/src/user/include/u_writer.h +++ b/src/user/include/u_writer.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/user/include/u_writerQos.h b/src/user/include/u_writerQos.h index 25a0d29e2..7ffcdc440 100644 --- a/src/user/include/u_writerQos.h +++ b/src/user/include/u_writerQos.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/utilities/code/ut__set.h b/src/utilities/code/ut__set.h index a12f4e4cb..ed3c1881e 100644 --- a/src/utilities/code/ut__set.h +++ b/src/utilities/code/ut__set.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/utilities/code/ut__stack.h b/src/utilities/code/ut__stack.h index 9cf552f6d..1604c355e 100644 --- a/src/utilities/code/ut__stack.h +++ b/src/utilities/code/ut__stack.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/utilities/code/ut__wrapper_lzf.h b/src/utilities/code/ut__wrapper_lzf.h index 776d2ec7d..61c9ac12b 100644 --- a/src/utilities/code/ut__wrapper_lzf.h +++ b/src/utilities/code/ut__wrapper_lzf.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/utilities/code/ut__wrapper_snappy.h b/src/utilities/code/ut__wrapper_snappy.h index 3c896615b..99fc6b232 100644 --- a/src/utilities/code/ut__wrapper_snappy.h +++ b/src/utilities/code/ut__wrapper_snappy.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/utilities/code/ut__wrapper_zlib.h b/src/utilities/code/ut__wrapper_zlib.h index ff644be24..28e1feaf4 100644 --- a/src/utilities/code/ut__wrapper_zlib.h +++ b/src/utilities/code/ut__wrapper_zlib.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/utilities/code/ut_avl.c b/src/utilities/code/ut_avl.c index fc738f562..265e030c5 100644 --- a/src/utilities/code/ut_avl.c +++ b/src/utilities/code/ut_avl.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -42,27 +43,6 @@ static int comparenk (const ut_avlTreedef_t *td, const ut_avlNode_t *a, const vo } } -#if 0 -static int comparenn_direct (const ut_avlTreedef_t *td, const ut_avlNode_t *a, const ut_avlNode_t *b) -{ - return td->comparekk (LOAD_DIRKEY (a, td), LOAD_DIRKEY (b, td)); -} - -static int comparenn_indirect (const ut_avlTreedef_t *td, const ut_avlNode_t *a, const ut_avlNode_t *b) -{ - return td->comparekk (LOAD_INDKEY (a, td), LOAD_INDKEY (b, td)); -} - -static int comparenn (const ut_avlTreedef_t *td, const ut_avlNode_t *a, const ut_avlNode_t *b) -{ - if (IS_INDKEY (td->keyoffset)) { - return comparenn_indirect (td, a, b); - } else { - return comparenn_direct (td, a, b); - } -} -#endif - static ut_avlNode_t *node_from_onode (const ut_avlTreedef_t *td, char *onode) { if (onode == NULL) { @@ -177,14 +157,15 @@ static void augment (const ut_avlTreedef_t *td, ut_avlNode_t *n) static ut_avlNode_t *rotate_single (const ut_avlTreedef_t *td, ut_avlNode_t **pnode, ut_avlNode_t *node, int dir) { /* rotate_single(N, dir) performs one rotation, e.g., for dir=1, a - right rotation as depicted below, for dir=0 a left rotation: - - N _ND' - _ND v ==> u N' - u _ND_D _ND_D v - - Since a right rotation is only ever done with the left side is - overweight, _ND must be != NULL. */ + * right rotation as depicted below, for dir=0 a left rotation: + * + * N _ND' + * _ND v ==> u N' + * u _ND_D _ND_D v + * + * Since a right rotation is only ever done with the left side is + * overweight, _ND must be != NULL. + */ ut_avlNode_t * const parent = node->parent; ut_avlNode_t * const node_ND = node->cs[1-dir]; ut_avlNode_t * const node_ND_D = node_ND->cs[dir]; @@ -209,21 +190,22 @@ static ut_avlNode_t *rotate_single (const ut_avlTreedef_t *td, ut_avlNode_t **pn static ut_avlNode_t *rotate_double (const ut_avlTreedef_t *td, ut_avlNode_t **pnode, ut_avlNode_t *node, int dir) { /* rotate_double() performs one double rotation, which is slightly - faster when written out than the equivalent: - - rotate_single(N->cs[1-dir], 1-dir) - rotate_single(N, dir) - - A right double rotation therefore means: - - N N' _ND_D'' - _ND v => _ND_D' v => _ND'' N'' - u _ND_D _ND' y u x y v - x y u x - - Since a right double rotation is only ever done with the N is - overweight on the left side and _ND is overweight on the right - side, both _ND and _ND_D must be != NULL. */ + * faster when written out than the equivalent: + * + * rotate_single(N->cs[1-dir], 1-dir) + * rotate_single(N, dir) + * + * A right double rotation therefore means: + * + * N N' _ND_D'' + * _ND v => _ND_D' v => _ND'' N'' + * u _ND_D _ND' y u x y v + * x y u x + * + * Since a right double rotation is only ever done with the N is + * overweight on the left side and _ND is overweight on the right + * side, both _ND and _ND_D must be != NULL. + */ ut_avlNode_t * const parent = node->parent; ut_avlNode_t * const node_ND = node->cs[1-dir]; ut_avlNode_t * const node_ND_D = node_ND->cs[dir]; @@ -260,9 +242,10 @@ static ut_avlNode_t *rotate_double (const ut_avlTreedef_t *td, ut_avlNode_t **pn static ut_avlNode_t *rotate (const ut_avlTreedef_t *td, ut_avlNode_t **pnode, ut_avlNode_t *node, int dir) { /* _D => child in the direction of rotation (1 for right, 0 for - left); _ND => child in the opposite direction. So in a right - rotation, _ND_D means the grandchild that is the right child of - the left child. */ + * left); _ND => child in the opposite direction. So in a right + * rotation, _ND_D means the grandchild that is the right child of + * the left child. + */ ut_avlNode_t * const node_ND = node->cs[1-dir]; ut_avlNode_t * const node_ND_ND = node_ND->cs[1-dir]; ut_avlNode_t * const node_ND_D = node_ND->cs[dir]; @@ -290,10 +273,11 @@ static ut_avlNode_t *rebalance_one (const ut_avlTreedef_t *td, ut_avlNode_t **pn return rotate (td, pnode, node, 0); } else { /* Rebalance happens only on insert & delete, and augment needs to - be called during rotations. Therefore, rebalancing integrates - calling augment, and because of that, includes running all the - way up to the root even when not needed for the rebalancing - itself. */ + * be called during rotations. Therefore, rebalancing integrates + * calling augment, and because of that, includes running all the + * way up to the root even when not needed for the rebalancing + * itself. + */ int height = (height_L < height_R ? height_R : height_L) + 1; if (td->augment == 0 && height == node->height) { return NULL; @@ -371,8 +355,9 @@ void *ut_avlLookupIPath (const ut_avlTreedef_t *td, const ut_avlTree_t *tree, co { const ut_avlNode_t *node = lookup_path (td, tree, key, &path->p); /* If no duplicates allowed, path may not be used for insertion, - and hence there is no need to continue descending the tree. - Since we can invalidate it very efficiently, do so. */ + * and hence there is no need to continue descending the tree. + * Since we can invalidate it very efficiently, do so. + */ if (node) { if (!(td->flags & UT_AVL_TREEDEF_FLAG_ALLOWDUPS)) { path->p.pnode[path->p.depth] = NULL; @@ -525,8 +510,9 @@ void ut_avlSwapNode (const ut_avlTreedef_t *td, ut_avlTree_t *tree, void *vold, ut_avlNode_t *new = node_from_onode (td, vnew); *nodeptr_from_node (tree, old) = new; /* use memmove so partially overlap between old & new is allowed - (yikes!, but exploited by the memory allocator, and not a big - deal to get right) */ + * (yikes!, but exploited by the memory allocator, and not a big + * deal to get right) + */ memmove (new, old, sizeof (*new)); if (new->cs[0]) { new->cs[0]->parent = new; @@ -648,14 +634,16 @@ void ut_avlWalk (const ut_avlTreedef_t *td, ut_avlTree_t *tree, ut_avlWalk_t f, n = n->cs[0]; } /* Then process it and its parents until a node N is hit that has - a right subtree, with (by definition) key values in between N - and the parent of N */ + * a right subtree, with (by definition) key values in between N + * and the parent of N + */ do { right = (*todop)->cs[1]; f ((void *) conode_from_node (td, *todop), a); } while (todop-- > todo+1 && right == NULL); /* Continue with right subtree rooted at 'right' before processing - the parent node of the last node processed in the loop above */ + * the parent node of the last node processed in the loop above + */ *++todop = right; } } @@ -696,7 +684,8 @@ static const ut_avlNode_t *fixup_predsucceq (const ut_avlTreedef_t *td, const vo return tmp; } else { /* key exists - but it there's no guarantee we hit the first - one in the in-order enumeration of the tree */ + * one in the in-order enumeration of the tree + */ cand = tmp; tmp = tmp->cs[1-dir]; while (tmp) { @@ -757,8 +746,9 @@ static const ut_avlNode_t *fixup_predsucc (const ut_avlTreedef_t *td, const void return tmp; } else { /* Duplicates allowed, therefore: if tmp has no right subtree, - cand else scan the right subtree for the minimum larger - than key, return cand if none can be found */ + * cand else scan the right subtree for the minimum larger + * than key, return cand if none can be found + */ tmp = tmp->cs[dir]; while (tmp) { if (comparenk (td, tmp, key) != 0) { @@ -842,7 +832,8 @@ void *ut_avlIterSuccEq (const ut_avlTreedef_t *td, const ut_avlTree_t *tree, ut_ *++iter->todop = (ut_avlNode_t *) tmp; if (td->flags & UT_AVL_TREEDEF_FLAG_ALLOWDUPS) { /* key exists - but it there's no guarantee we hit the - first one in the in-order enumeration of the tree */ + * first one in the in-order enumeration of the tree + */ tmp = tmp->cs[0]; while (tmp) { if (comparenk (td, tmp, key) != 0) { diff --git a/src/utilities/code/ut_collection.c b/src/utilities/code/ut_collection.c index 6e792523f..a120b51db 100644 --- a/src/utilities/code/ut_collection.c +++ b/src/utilities/code/ut_collection.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -314,20 +315,21 @@ ut_bagNew ( #if 1 /* The original interface has type (os_equality (*) (void *, void *, - void *)), but the compare functions all do treat the first two - parameters as const. - - Currently os_equality is defined s.t. OS_LT < 0, OS_EQ = 0 and - OS_GT > 0, which matches the requirements and usually allows using - a ut_compareElementsFunc as if it were a "C standard" compare - function returning an int. - - To avoid nasty surprises, we check two things at compile time: that - the enum constants indeed satisfy this requirement, and that the - sizeof of the return type matches. - - The wrapper is sitting pretty here in case we run into a platform - on which the constraints don't hold. */ + * void *)), but the compare functions all do treat the first two + * parameters as const. + * + * Currently os_equality is defined s.t. OS_LT < 0, OS_EQ = 0 and + * OS_GT > 0, which matches the requirements and usually allows using + * a ut_compareElementsFunc as if it were a "C standard" compare + * function returning an int. + * + * To avoid nasty surprises, we check two things at compile time: that + * the enum constants indeed satisfy this requirement, and that the + * sizeof of the return type matches. + * + * The wrapper is sitting pretty here in case we run into a platform + * on which the constraints don't hold. + */ struct tableCmp_constraints { char require_LT_lt_0[-1+2*((int) OS_LT < 0)]; char require_EQ_eq_0[-1+2*((int) OS_EQ == 0)]; diff --git a/src/utilities/code/ut_compressor.c b/src/utilities/code/ut_compressor.c index eac86165b..c360c0dc4 100644 --- a/src/utilities/code/ut_compressor.c +++ b/src/utilities/code/ut_compressor.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/utilities/code/ut_crc.c b/src/utilities/code/ut_crc.c index 176f1b839..e12bf96c2 100644 --- a/src/utilities/code/ut_crc.c +++ b/src/utilities/code/ut_crc.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/utilities/code/ut_entryPoint.c b/src/utilities/code/ut_entryPoint.c index 2e8fda68b..7da7656b8 100644 --- a/src/utilities/code/ut_entryPoint.c +++ b/src/utilities/code/ut_entryPoint.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/utilities/code/ut_expand_envvars.c b/src/utilities/code/ut_expand_envvars.c index f8bc0eac8..45c5765e4 100644 --- a/src/utilities/code/ut_expand_envvars.c +++ b/src/utilities/code/ut_expand_envvars.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/utilities/code/ut_fibheap.c b/src/utilities/code/ut_fibheap.c index 36352e28d..c6e01d093 100644 --- a/src/utilities/code/ut_fibheap.c +++ b/src/utilities/code/ut_fibheap.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,10 +25,11 @@ #include "ut_fibheap.h" /* max degree: n >= F_{d+2} >= \phi^d ==> d <= log_\phi n, where \phi - (as usual) is the golden ratio ~= 1.618. We know n <= (size of - address space) / sizeof (fh_node), log_\phi 2 ~= 1.44, sizeof - (fh_node) >= 4, therefore max degree < log_2 (size of address - space). */ + * (as usual) is the golden ratio ~= 1.618. We know n <= (size of + * address space) / sizeof (fh_node), log_\phi 2 ~= 1.44, sizeof + * (fh_node) >= 4, therefore max degree < log_2 (size of address + * space). + */ #define MAX_DEGREE ((unsigned) (sizeof (void *) * CHAR_BIT - 1)) static int cmp (const ut_fibheapDef_t *fhdef, const ut_fibheapNode_t *a, const ut_fibheapNode_t *b) @@ -97,8 +99,9 @@ void ut_fibheapMerge (const ut_fibheapDef_t *fhdef, ut_fibheap_t *a, ut_fibheap_ void ut_fibheapInsert (const ut_fibheapDef_t *fhdef, ut_fibheap_t *fh, const void *vnode) { /* fibheap node is opaque => nothing in node changes as far as - caller is concerned => declare as const argument, then drop the - const qualifier */ + * caller is concerned => declare as const argument, then drop the + * const qualifier + */ ut_fibheapNode_t *node = (ut_fibheapNode_t *) ((char *) vnode + fhdef->offset); /* new heap of degree 0 (i.e., only containing NODE) */ @@ -141,8 +144,9 @@ void *ut_fibheapExtractMin (const ut_fibheapDef_t *fhdef, ut_fibheap_t *fh) unsigned min_degree_noninit = 0; /* empty heap => return that, alternative would be to require the - heap to contain at least one element, but this is probably nicer - in practice */ + * heap to contain at least one element, but this is probably nicer + * in practice + */ if (min == NULL) { return NULL; } @@ -160,7 +164,8 @@ void *ut_fibheapExtractMin (const ut_fibheapDef_t *fhdef, ut_fibheap_t *fh) locality of reference by scanning lists only once */ /* insert min'schildren as new roots -- must fix parent pointers, - and reset marks because roots are always unmarked */ + * and reset marks because roots are always unmarked + */ if (min->children) { ut_fibheapNode_t * const mark = min->children; ut_fibheapNode_t *n = mark; @@ -173,8 +178,7 @@ void *ut_fibheapExtractMin (const ut_fibheapDef_t *fhdef, ut_fibheap_t *fh) ut_fibheap_merge_nonempty_list (&fh->roots, min->children); } - /* iteratively merge roots of equal degree, completely messing up - fh->roots, ... */ + /* iteratively merge roots of equal degree, completely messing up fh->roots, ... */ { ut_fibheapNode_t *const mark = fh->roots; ut_fibheapNode_t *n = mark; @@ -182,7 +186,8 @@ void *ut_fibheapExtractMin (const ut_fibheapDef_t *fhdef, ut_fibheap_t *fh) ut_fibheapNode_t * const n1 = n->next; /* if n is first root with this high a degree, there's certainly - not going to be another root to merge with yet */ + * not going to be another root to merge with yet + */ while (n->degree < min_degree_noninit && roots[n->degree]) { unsigned const degree = n->degree; ut_fibheapNode_t *u, *v; @@ -198,8 +203,9 @@ void *ut_fibheapExtractMin (const ut_fibheapDef_t *fhdef, ut_fibheap_t *fh) } /* n may have changed, hence need to retest whether or not - enough of roots has been initialised -- note that - initialising roots[n->degree] is unnecessary, but easier */ + * enough of roots has been initialised -- note that + * initialising roots[n->degree] is unnecessary, but easier + */ assert (n->degree <= MAX_DEGREE); while (min_degree_noninit <= n->degree) { roots[min_degree_noninit++] = NULL; @@ -210,8 +216,9 @@ void *ut_fibheapExtractMin (const ut_fibheapDef_t *fhdef, ut_fibheap_t *fh) } /* ... but we don't mind because we have roots[], we can scan linear - memory at an astonishing rate, and we need to compare the root - keys anyway to find the minimum */ + * memory at an astonishing rate, and we need to compare the root + * keys anyway to find the minimum + */ { ut_fibheapNode_t *mark, *cursor, *newmin; unsigned i; @@ -258,14 +265,14 @@ static void ut_fibheap_cutnode (ut_fibheap_t *fh, ut_fibheapNode_t *node) node->next = node->prev = node; /* we assume heap properties haven't been violated, and therefore - none of the nodes we cut can become the new minimum */ + * none of the nodes we cut can become the new minimum + */ ut_fibheap_merge_nonempty_list (&fh->roots, node); node = parent; } - /* if we stopped because we hit an unmarked interior node, we must - mark it */ + /* if we stopped because we hit an unmarked interior node, we must mark it */ if (node->parent) { node->mark = 1; } @@ -274,8 +281,9 @@ static void ut_fibheap_cutnode (ut_fibheap_t *fh, ut_fibheapNode_t *node) void ut_fibheapDecreaseKey (const ut_fibheapDef_t *fhdef, ut_fibheap_t *fh, const void *vnode) { /* fibheap node is opaque => nothing in node changes as far as - caller is concerned => declare as const argument, then drop the - const qualifier */ + * caller is concerned => declare as const argument, then drop the + * const qualifier + */ ut_fibheapNode_t *node = (ut_fibheapNode_t *) ((char *) vnode + fhdef->offset); if (node->parent && cmp (fhdef, node->parent, node) <= 0) { @@ -283,8 +291,9 @@ void ut_fibheapDecreaseKey (const ut_fibheapDef_t *fhdef, ut_fibheap_t *fh, cons } else { if (node->parent) { /* heap property violated by decreasing the key, but we cut it - pretending nothing has happened yet, then fix up the minimum if - this node is the new minimum */ + * pretending nothing has happened yet, then fix up the minimum if + * this node is the new minimum + */ ut_fibheap_cutnode (fh, node); } if (cmp (fhdef, node, fh->roots) < 0) { @@ -296,13 +305,15 @@ void ut_fibheapDecreaseKey (const ut_fibheapDef_t *fhdef, ut_fibheap_t *fh, cons void ut_fibheapDelete (const ut_fibheapDef_t *fhdef, ut_fibheap_t *fh, const void *vnode) { /* fibheap node is opaque => nothing in node changes as far as - caller is concerned => declare as const argument, then drop the - const qualifier */ + * caller is concerned => declare as const argument, then drop the + * const qualifier + */ ut_fibheapNode_t *node = (ut_fibheapNode_t *) ((char *) vnode + fhdef->offset); - + /* essentially decreasekey(node);extractmin while pretending the - node key is -infinity. That means we can't directly call - decreasekey, because it considers the actual value of the key. */ + * node key is -infinity. That means we can't directly call + * decreasekey, because it considers the actual value of the key. + */ if (node->parent != NULL) { ut_fibheap_cutnode (fh, node); } diff --git a/src/utilities/code/ut_hex.c b/src/utilities/code/ut_hex.c new file mode 100644 index 000000000..39a70c456 --- /dev/null +++ b/src/utilities/code/ut_hex.c @@ -0,0 +1,63 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include + +#include "ut_hex.h" + +int +ut_hexenc( + char *xbuf, + unsigned int xlen, + const unsigned char *buf, + unsigned int len) +{ + int xdec, cnt = -1; + unsigned int pos; + char xchr; + + assert(xbuf != NULL); + assert(buf != NULL); + + if ((xlen / 2) >= len) { + cnt = 0; + for (pos = 0; pos < len; pos++) { + if (((unsigned int)cnt) < xlen) { + xdec = (buf[pos] & 0xf0) >> 4; + xchr = (char)(xdec < 10 ? xdec + '0' : (xdec - 10) + 'a'); + xbuf[cnt] = xchr; + } + cnt++; + if (((unsigned int)cnt) < xlen) { + xdec = (buf[pos] & 0x0f); + xchr = (char)(xdec < 10 ? xdec + '0' : (xdec - 10) + 'a'); + xbuf[cnt] = xchr; + } + cnt++; + } + + /* null terminate if space is available */ + if (((unsigned int)cnt) < xlen) { + xbuf[cnt] = '\0'; + } + } + + return cnt; +} diff --git a/src/utilities/code/ut_hopscotch.c b/src/utilities/code/ut_hopscotch.c index 27716eeb9..d359d2803 100644 --- a/src/utilities/code/ut_hopscotch.c +++ b/src/utilities/code/ut_hopscotch.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -167,8 +168,9 @@ void ut_chhFree (struct ut_chh * UT_HH_RESTRICT hh) static void ut_chhLockBucket (struct ut_chh *rt, os_uint32 bidx) { /* Lock: MSB <=> LOCKBIT, LSBs <=> wait count; note that - (o&LOCKBIT)==0 means a thread can sneak in when there are - already waiters, changing it to o==0 would avoid that. */ + * (o&LOCKBIT)==0 means a thread can sneak in when there are + * already waiters, changing it to o==0 would avoid that. + */ struct ut_chhBucketArray * const bsary = pa_ldvoidp (&rt->buckets); struct ut_chhBucket * const b = &bsary->bs[bidx]; struct ut_chhBackingLock * const s = &rt->backingLocks[bidx % N_BACKING_LOCKS]; @@ -214,11 +216,12 @@ static void ut_chhUnlockBucket (struct ut_chh *rt, os_uint32 bidx) } else { os_mutexLock (&s->lock); /* Need to broadcast because the CV is shared by multiple buckets - and the kernel wakes an arbitrary thread, it may be a thread - waiting for another bucket's lock that gets woken up, and that - can result in all threads waiting with all locks unlocked. - Broadcast avoids that, and with significantly more CVs than - cores, it shouldn't happen often. */ + * and the kernel wakes an arbitrary thread, it may be a thread + * waiting for another bucket's lock that gets woken up, and that + * can result in all threads waiting with all locks unlocked. + * Broadcast avoids that, and with significantly more CVs than + * cores, it shouldn't happen often. + */ os_condBroadcast (&s->cv); os_mutexUnlock (&s->lock); } @@ -246,8 +249,9 @@ static void *ut_chhLookupInternal (struct ut_chh * rt, const os_uint32 bucket, c } while (timestamp != pa_ld32 (&bs[bucket].timestamp) && ++try_counter < CHH_MAX_TRIES); if (try_counter == CHH_MAX_TRIES) { /* Note: try_counter would not have been incremented to - CHH_MAX_TRIES if we ended the loop because the two timestamps - were equal, but this avoids loading the timestamp again */ + * CHH_MAX_TRIES if we ended the loop because the two timestamps + * were equal, but this avoids loading the timestamp again + */ for (idx = 0; idx < HH_HOP_RANGE; idx++) { const os_uint32 bidx = (bucket + idx) & idxmask; void *data = pa_ldvoidp (&bs[bidx].data); @@ -318,10 +322,11 @@ static os_uint32 ut_chhFindCloserFreeBucket (struct ut_chh *rt, os_uint32 free_b static void ut_chhResize (struct ut_chh *rt) { /* doubles the size => bucket index gains one bit at the msb => - start bucket is unchanged or moved into the added half of the set - => those for which the (new) msb is 0 are guaranteed to fit, and - so are those for which the (new) msb is 1 => never have to resize - recursively */ + * start bucket is unchanged or moved into the added half of the set + * => those for which the (new) msb is 0 are guaranteed to fit, and + * so are those for which the (new) msb is 1 => never have to resize + * recursively + */ struct ut_chhBucketArray * const bsary0 = pa_ldvoidp (&rt->buckets); struct ut_chhBucket * const bs0 = bsary0->bs; struct ut_chhBucketArray *bsary1; @@ -343,8 +348,7 @@ static void ut_chhResize (struct ut_chh *rt) idxmask1 = bsary1->size - 1; for (i = 0; i < bsary0->size; i++) { void *data = pa_ldvoidp (&bs0[i].data); - assert (data != CHH_BUSY); - if (data) { + if (data && data != CHH_BUSY) { const os_uint32 hash = rt->hash (data); const os_uint32 old_start_bucket = hash & idxmask0; const os_uint32 new_start_bucket = hash & idxmask1; @@ -569,6 +573,7 @@ static os_uint32 ut_hhFindCloserFreeBucket (struct ut_hh *rt, os_uint32 free_buc os_uint32 new_free_bucket = (move_bucket + move_free_distance) & idxmask; rt->buckets[move_bucket].hopinfo |= 1u << free_dist; rt->buckets[free_bucket].data = rt->buckets[new_free_bucket].data; + rt->buckets[new_free_bucket].data = NULL; rt->buckets[move_bucket].hopinfo &= ~(1u << move_free_distance); *free_distance -= free_dist - move_free_distance; return new_free_bucket; @@ -809,7 +814,7 @@ static os_uint32 ut_ehhFindCloserFreeBucket (struct ut_ehh *rt, os_uint32 free_b mb->hopinfo |= 1u << free_dist; fb->inuse = 1; memcpy (fb->data, nfb->data, rt->elemsz); - fb->inuse = 0; /* FIXME: without this, I think the case where hopping ultimately fails otherwise leaks an element (see also other impls, they should suffer from the same) */ + nfb->inuse = 0; mb->hopinfo &= ~(1u << move_free_distance); *free_distance -= free_dist - move_free_distance; return new_free_bucket; diff --git a/src/utilities/code/ut_md5.c b/src/utilities/code/ut_md5.c new file mode 100644 index 000000000..69cb07a2d --- /dev/null +++ b/src/utilities/code/ut_md5.c @@ -0,0 +1,402 @@ +/* Minimal changes introduced, for which: + * + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +/* + Copyright (C) 1999, 2000, 2002 Aladdin Enterprises. All rights reserved. + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + L. Peter Deutsch + ghost@aladdin.com + + */ +/* $Id: md5.c,v 1.6 2002/04/13 19:20:28 lpd Exp $ */ +/* + Independent implementation of MD5 (RFC 1321). + + This code implements the MD5 Algorithm defined in RFC 1321, whose + text is available at + http://www.ietf.org/rfc/rfc1321.txt + The code is derived from the text of the RFC, including the test suite + (section A.5) but excluding the rest of Appendix A. It does not include + any code or documentation that is identified in the RFC as being + copyrighted. + + The original and principal author of md5.c is L. Peter Deutsch + . Other authors are noted in the change history + that follows (in reverse chronological order): + + 2002-04-13 lpd Clarified derivation from RFC 1321; now handles byte order + either statically or dynamically; added missing #include + in library. + 2002-03-11 lpd Corrected argument list for main(), and added int return + type, in test program and T value program. + 2002-02-21 lpd Added missing #include in test program. + 2000-07-03 lpd Patched to eliminate warnings about "constant is + unsigned in ANSI C, signed in traditional"; made test program + self-checking. + 1999-11-04 lpd Edited comments slightly for automatic TOC extraction. + 1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5). + 1999-05-03 lpd Original version. + */ + +#include "ut_md5.h" +#include "os_stdlib.h" +#include "os_abstract.h" /* big or little endianness */ + +/* Byte order stuff hacked to use OSPL's macros */ +#undef BYTE_ORDER /* 1 = big-endian, -1 = little-endian, 0 = unknown */ +#ifdef PA_BIG_ENDIAN +# define BYTE_ORDER 1 +#endif +#ifdef PA_LITTLE_ENDIAN +# define BYTE_ORDER -1 +#endif + +#define T_MASK ((ut_md5_word_t)~0) +#define T1 /* 0xd76aa478 */ (T_MASK ^ 0x28955b87) +#define T2 /* 0xe8c7b756 */ (T_MASK ^ 0x173848a9) +#define T3 0x242070db +#define T4 /* 0xc1bdceee */ (T_MASK ^ 0x3e423111) +#define T5 /* 0xf57c0faf */ (T_MASK ^ 0x0a83f050) +#define T6 0x4787c62a +#define T7 /* 0xa8304613 */ (T_MASK ^ 0x57cfb9ec) +#define T8 /* 0xfd469501 */ (T_MASK ^ 0x02b96afe) +#define T9 0x698098d8 +#define T10 /* 0x8b44f7af */ (T_MASK ^ 0x74bb0850) +#define T11 /* 0xffff5bb1 */ (T_MASK ^ 0x0000a44e) +#define T12 /* 0x895cd7be */ (T_MASK ^ 0x76a32841) +#define T13 0x6b901122 +#define T14 /* 0xfd987193 */ (T_MASK ^ 0x02678e6c) +#define T15 /* 0xa679438e */ (T_MASK ^ 0x5986bc71) +#define T16 0x49b40821 +#define T17 /* 0xf61e2562 */ (T_MASK ^ 0x09e1da9d) +#define T18 /* 0xc040b340 */ (T_MASK ^ 0x3fbf4cbf) +#define T19 0x265e5a51 +#define T20 /* 0xe9b6c7aa */ (T_MASK ^ 0x16493855) +#define T21 /* 0xd62f105d */ (T_MASK ^ 0x29d0efa2) +#define T22 0x02441453 +#define T23 /* 0xd8a1e681 */ (T_MASK ^ 0x275e197e) +#define T24 /* 0xe7d3fbc8 */ (T_MASK ^ 0x182c0437) +#define T25 0x21e1cde6 +#define T26 /* 0xc33707d6 */ (T_MASK ^ 0x3cc8f829) +#define T27 /* 0xf4d50d87 */ (T_MASK ^ 0x0b2af278) +#define T28 0x455a14ed +#define T29 /* 0xa9e3e905 */ (T_MASK ^ 0x561c16fa) +#define T30 /* 0xfcefa3f8 */ (T_MASK ^ 0x03105c07) +#define T31 0x676f02d9 +#define T32 /* 0x8d2a4c8a */ (T_MASK ^ 0x72d5b375) +#define T33 /* 0xfffa3942 */ (T_MASK ^ 0x0005c6bd) +#define T34 /* 0x8771f681 */ (T_MASK ^ 0x788e097e) +#define T35 0x6d9d6122 +#define T36 /* 0xfde5380c */ (T_MASK ^ 0x021ac7f3) +#define T37 /* 0xa4beea44 */ (T_MASK ^ 0x5b4115bb) +#define T38 0x4bdecfa9 +#define T39 /* 0xf6bb4b60 */ (T_MASK ^ 0x0944b49f) +#define T40 /* 0xbebfbc70 */ (T_MASK ^ 0x4140438f) +#define T41 0x289b7ec6 +#define T42 /* 0xeaa127fa */ (T_MASK ^ 0x155ed805) +#define T43 /* 0xd4ef3085 */ (T_MASK ^ 0x2b10cf7a) +#define T44 0x04881d05 +#define T45 /* 0xd9d4d039 */ (T_MASK ^ 0x262b2fc6) +#define T46 /* 0xe6db99e5 */ (T_MASK ^ 0x1924661a) +#define T47 0x1fa27cf8 +#define T48 /* 0xc4ac5665 */ (T_MASK ^ 0x3b53a99a) +#define T49 /* 0xf4292244 */ (T_MASK ^ 0x0bd6ddbb) +#define T50 0x432aff97 +#define T51 /* 0xab9423a7 */ (T_MASK ^ 0x546bdc58) +#define T52 /* 0xfc93a039 */ (T_MASK ^ 0x036c5fc6) +#define T53 0x655b59c3 +#define T54 /* 0x8f0ccc92 */ (T_MASK ^ 0x70f3336d) +#define T55 /* 0xffeff47d */ (T_MASK ^ 0x00100b82) +#define T56 /* 0x85845dd1 */ (T_MASK ^ 0x7a7ba22e) +#define T57 0x6fa87e4f +#define T58 /* 0xfe2ce6e0 */ (T_MASK ^ 0x01d3191f) +#define T59 /* 0xa3014314 */ (T_MASK ^ 0x5cfebceb) +#define T60 0x4e0811a1 +#define T61 /* 0xf7537e82 */ (T_MASK ^ 0x08ac817d) +#define T62 /* 0xbd3af235 */ (T_MASK ^ 0x42c50dca) +#define T63 0x2ad7d2bb +#define T64 /* 0xeb86d391 */ (T_MASK ^ 0x14792c6e) + + +static void +md5_process(ut_md5_state_t *pms, const ut_md5_byte_t *data /*[64]*/) +{ + ut_md5_word_t + a = pms->abcd[0], b = pms->abcd[1], + c = pms->abcd[2], d = pms->abcd[3]; + ut_md5_word_t t; +#if BYTE_ORDER > 0 + /* Define storage only for big-endian CPUs. */ + ut_md5_word_t X[16]; +#else + /* Define storage for little-endian or both types of CPUs. */ + ut_md5_word_t xbuf[16]; + const ut_md5_word_t *X; +#endif + + { +#if BYTE_ORDER == 0 + /* + * Determine dynamically whether this is a big-endian or + * little-endian machine, since we can use a more efficient + * algorithm on the latter. + */ + static const int w = 1; + + if (*((const ut_md5_byte_t *)&w)) /* dynamic little-endian */ +#endif +#if BYTE_ORDER <= 0 /* little-endian */ + { + /* + * On little-endian machines, we can process properly aligned + * data without copying it. + */ + if (!((data - (const ut_md5_byte_t *)0) & 3)) { + /* data are properly aligned */ + X = (const ut_md5_word_t *)data; + } else { + /* not aligned */ + memcpy(xbuf, data, 64); + X = xbuf; + } + } +#endif +#if BYTE_ORDER == 0 + else /* dynamic big-endian */ +#endif +#if BYTE_ORDER >= 0 /* big-endian */ + { + /* + * On big-endian machines, we must arrange the bytes in the + * right order. + */ + const ut_md5_byte_t *xp = data; + int i; + +# if BYTE_ORDER == 0 + X = xbuf; /* (dynamic only) */ +# else +# define xbuf X /* (static only) */ +# endif + for (i = 0; i < 16; ++i, xp += 4) + xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24); + } +#endif + } + +#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n)))) + + /* Round 1. */ + /* Let [abcd k s i] denote the operation + a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */ +#define F(x, y, z) (((x) & (y)) | (~(x) & (z))) +#define SET(a, b, c, d, k, s, Ti)\ + t = a + F(b,c,d) + X[k] + Ti;\ + a = ROTATE_LEFT(t, s) + b + /* Do the following 16 operations. */ + SET(a, b, c, d, 0, 7, T1); + SET(d, a, b, c, 1, 12, T2); + SET(c, d, a, b, 2, 17, T3); + SET(b, c, d, a, 3, 22, T4); + SET(a, b, c, d, 4, 7, T5); + SET(d, a, b, c, 5, 12, T6); + SET(c, d, a, b, 6, 17, T7); + SET(b, c, d, a, 7, 22, T8); + SET(a, b, c, d, 8, 7, T9); + SET(d, a, b, c, 9, 12, T10); + SET(c, d, a, b, 10, 17, T11); + SET(b, c, d, a, 11, 22, T12); + SET(a, b, c, d, 12, 7, T13); + SET(d, a, b, c, 13, 12, T14); + SET(c, d, a, b, 14, 17, T15); + SET(b, c, d, a, 15, 22, T16); +#undef SET + + /* Round 2. */ + /* Let [abcd k s i] denote the operation + a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */ +#define G(x, y, z) (((x) & (z)) | ((y) & ~(z))) +#define SET(a, b, c, d, k, s, Ti)\ + t = a + G(b,c,d) + X[k] + Ti;\ + a = ROTATE_LEFT(t, s) + b + /* Do the following 16 operations. */ + SET(a, b, c, d, 1, 5, T17); + SET(d, a, b, c, 6, 9, T18); + SET(c, d, a, b, 11, 14, T19); + SET(b, c, d, a, 0, 20, T20); + SET(a, b, c, d, 5, 5, T21); + SET(d, a, b, c, 10, 9, T22); + SET(c, d, a, b, 15, 14, T23); + SET(b, c, d, a, 4, 20, T24); + SET(a, b, c, d, 9, 5, T25); + SET(d, a, b, c, 14, 9, T26); + SET(c, d, a, b, 3, 14, T27); + SET(b, c, d, a, 8, 20, T28); + SET(a, b, c, d, 13, 5, T29); + SET(d, a, b, c, 2, 9, T30); + SET(c, d, a, b, 7, 14, T31); + SET(b, c, d, a, 12, 20, T32); +#undef SET + + /* Round 3. */ + /* Let [abcd k s t] denote the operation + a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */ +#define H(x, y, z) ((x) ^ (y) ^ (z)) +#define SET(a, b, c, d, k, s, Ti)\ + t = a + H(b,c,d) + X[k] + Ti;\ + a = ROTATE_LEFT(t, s) + b + /* Do the following 16 operations. */ + SET(a, b, c, d, 5, 4, T33); + SET(d, a, b, c, 8, 11, T34); + SET(c, d, a, b, 11, 16, T35); + SET(b, c, d, a, 14, 23, T36); + SET(a, b, c, d, 1, 4, T37); + SET(d, a, b, c, 4, 11, T38); + SET(c, d, a, b, 7, 16, T39); + SET(b, c, d, a, 10, 23, T40); + SET(a, b, c, d, 13, 4, T41); + SET(d, a, b, c, 0, 11, T42); + SET(c, d, a, b, 3, 16, T43); + SET(b, c, d, a, 6, 23, T44); + SET(a, b, c, d, 9, 4, T45); + SET(d, a, b, c, 12, 11, T46); + SET(c, d, a, b, 15, 16, T47); + SET(b, c, d, a, 2, 23, T48); +#undef SET + + /* Round 4. */ + /* Let [abcd k s t] denote the operation + a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */ +#define I(x, y, z) ((y) ^ ((x) | ~(z))) +#define SET(a, b, c, d, k, s, Ti)\ + t = a + I(b,c,d) + X[k] + Ti;\ + a = ROTATE_LEFT(t, s) + b + /* Do the following 16 operations. */ + SET(a, b, c, d, 0, 6, T49); + SET(d, a, b, c, 7, 10, T50); + SET(c, d, a, b, 14, 15, T51); + SET(b, c, d, a, 5, 21, T52); + SET(a, b, c, d, 12, 6, T53); + SET(d, a, b, c, 3, 10, T54); + SET(c, d, a, b, 10, 15, T55); + SET(b, c, d, a, 1, 21, T56); + SET(a, b, c, d, 8, 6, T57); + SET(d, a, b, c, 15, 10, T58); + SET(c, d, a, b, 6, 15, T59); + SET(b, c, d, a, 13, 21, T60); + SET(a, b, c, d, 4, 6, T61); + SET(d, a, b, c, 11, 10, T62); + SET(c, d, a, b, 2, 15, T63); + SET(b, c, d, a, 9, 21, T64); +#undef SET + + /* Then perform the following additions. (That is increment each + of the four registers by the value it had before this block + was started.) */ + pms->abcd[0] += a; + pms->abcd[1] += b; + pms->abcd[2] += c; + pms->abcd[3] += d; +} + +void +ut_md5_init(ut_md5_state_t *pms) +{ + pms->count[0] = pms->count[1] = 0; + pms->abcd[0] = 0x67452301; + pms->abcd[1] = /*0xefcdab89*/ T_MASK ^ 0x10325476; + pms->abcd[2] = /*0x98badcfe*/ T_MASK ^ 0x67452301; + pms->abcd[3] = 0x10325476; +} + +void +ut_md5_append(ut_md5_state_t *pms, const ut_md5_byte_t *data, unsigned nbytes) +{ + const ut_md5_byte_t *p = data; + unsigned left = nbytes; + unsigned offset = (pms->count[0] >> 3) & 63; + ut_md5_word_t nbits = (ut_md5_word_t)(nbytes << 3); + + if (nbytes <= 0) + return; + + /* Update the message length. */ + pms->count[1] += nbytes >> 29; + pms->count[0] += nbits; + if (pms->count[0] < nbits) + pms->count[1]++; + + /* Process an initial partial block. */ + if (offset) { + unsigned copy = (offset + nbytes > 64 ? 64 - offset : nbytes); + + memcpy(pms->buf + offset, p, copy); + if (offset + copy < 64) + return; + p += copy; + left -= copy; + md5_process(pms, pms->buf); + } + + /* Process full blocks. */ + for (; left >= 64; p += 64, left -= 64) + md5_process(pms, p); + + /* Process a final partial block. */ + if (left) + memcpy(pms->buf, p, left); +} + +void +ut_md5_finish(ut_md5_state_t *pms, ut_md5_byte_t digest[16]) +{ + static const ut_md5_byte_t pad[64] = { + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; + ut_md5_byte_t data[8]; + int i; + + /* Save the length before padding. */ + for (i = 0; i < 8; ++i) + data[i] = (ut_md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3)); + /* Pad to 56 bytes mod 64. */ + ut_md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1); + /* Append the length. */ + ut_md5_append(pms, data, 8); + for (i = 0; i < 16; ++i) + digest[i] = (ut_md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3)); +} diff --git a/src/utilities/code/ut_result.c b/src/utilities/code/ut_result.c index fe91c397b..16a112f6f 100644 --- a/src/utilities/code/ut_result.c +++ b/src/utilities/code/ut_result.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/utilities/code/ut_stack.c b/src/utilities/code/ut_stack.c index 75fd0130c..3f6b8e613 100644 --- a/src/utilities/code/ut_stack.c +++ b/src/utilities/code/ut_stack.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,13 +25,6 @@ #include #include -/************************************************************** - * Private functions - **************************************************************/ - -/************************************************************** - * constructor/destructor - **************************************************************/ ut_stack ut_stackNew( os_uint32 increment) @@ -57,14 +51,6 @@ ut_stackFree( return UT_RESULT_OK; } - -/************************************************************** - * Protected functions - **************************************************************/ - -/************************************************************** - * Public functions - **************************************************************/ ut_result ut_stackPush( ut_stack stack, @@ -76,7 +62,7 @@ ut_stackPush( assert(stack->ptr <= stack->depth); if (stack->ptr == stack->depth) { - newStack = os_malloc(sizeof(void *) * + newStack = os_malloc(sizeof(void *) * (stack->depth + stack->increment)); if (newStack != NULL) { memcpy(newStack, stack->stack, (sizeof(void *) * stack->depth)); @@ -128,16 +114,11 @@ ut_stackWalk( void *arg) { ut_result utr; - os_uint32 i; - + os_uint32 i = stack->ptr; + utr = UT_RESULT_OK; - if (stack->ptr > 0) { - i = stack->ptr-1; - while ((i > 0) && (utr == UT_RESULT_OK)) { - utr = action(stack->stack[i], arg); - i--; - } - utr = action(stack->stack[i], arg); - } + if (i) do { + utr = action(stack->stack[--i], arg); + } while (i > 0 && utr == UT_RESULT_OK); return utr; } diff --git a/src/utilities/code/ut_thread.c b/src/utilities/code/ut_thread.c index 2dde9db89..1d7a05965 100644 --- a/src/utilities/code/ut_thread.c +++ b/src/utilities/code/ut_thread.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -30,16 +31,18 @@ #include "ut_thread.h" /* Things don't go wrong if CACHE_LINE_SIZE is defined incorrectly, - they just run slower because of false cache-line sharing. It can be - discovered at run-time, but in practice it's 64 for most CPUs and - 128 for some. */ + * they just run slower because of false cache-line sharing. It can be + * discovered at run-time, but in practice it's 64 for most CPUs and + * 128 for some. + */ #define UT_CACHE_LINE_SIZE 64 /* GCC has a nifty feature allowing the specification of the required - alignment: __attribute__ ((aligned (CACHE_LINE_SIZE))) in this - case. Many other compilers implement it as well, but it is by no - means a standard feature. So we do it the old-fashioned way. */ + * alignment: __attribute__ ((aligned (CACHE_LINE_SIZE))) in this + * case. Many other compilers implement it as well, but it is by no + * means a standard feature. So we do it the old-fashioned way. + */ enum ut_threadStateEnum { UT_THREAD_STATE_ZERO, @@ -57,9 +60,8 @@ struct ut_threadLiveliness { }; -/* - * drowsyCnt even : thread awake - * drowsyCnt odd : thread asleep +/* drowsyCnt even : thread awake + * drowsyCnt odd : thread asleep */ #define UT_THREAD_BASE \ volatile os_uint32 drowsyCnt; \ @@ -69,6 +71,7 @@ struct ut_threadLiveliness { volatile enum ut_threadStateEnum state; \ void *threads; \ char *name; \ + os_cond cond; \ void * (*f) (void *arg); \ void *f_arg /* note: no semicolon! */ @@ -91,7 +94,7 @@ OS_STRUCT(ut_threads) { os_mutex lock; os_threadId main; void *userdata; - os_uint32 size; + os_int32 size; os_duration interval; os_timeM lastCheck; OS_STRUCT(ut_thread) *pool; @@ -104,24 +107,21 @@ __thread ut_thread ut_tsdThreadState; #endif -/* - * Sleep is managed in seconds. Non-null nanoseconds adds one second lag. - */ +/* Sleep is managed in seconds. Non-null nanoseconds adds one second lag. */ #define UT_SLEEPSEC_FROM_DURATION(d) ((os_uint32)(OS_DURATION_GET_SECONDS(d) + (OS_DURATION_GET_NANOSECONDS(d) != 0))) -/* - * snprintf can return negative values. Only update position with non-negative values. - */ +/* snprintf can return negative values. Only update position with non-negative values. */ #define UT_RET_POSITIVE(n) (((n) > 0) ? (unsigned)n : 0) static void* ut_mallocAligned(os_size_t size) { /* This wastes some space, but we use it only once and it isn't a - huge amount of memory, just a little over a cache line. - Alternatively, we good use valloc() and have it aligned to a - page boundary, but that one isn't part of the O/S abstraction - layer ... */ + * huge amount of memory, just a little over a cache line. + * Alternatively, we good use valloc() and have it aligned to a + * page boundary, but that one isn't part of the O/S abstraction + * layer ... + */ const os_address clm1 = UT_CACHE_LINE_SIZE - 1; os_address ptrA; void **pptr; @@ -171,13 +171,17 @@ ut_threadWrapper (void *vself) ut_threadAsleep(self, UT_SLEEP_INDEFINITELY); pa_fence(); self->state = UT_THREAD_STATE_REAP; + os_mutexLock(&(((ut_threads)(self->threads))->lock)); + os_condBroadcast(&self->cond); + os_mutexUnlock (&(((ut_threads)(self->threads))->lock)); + return ret; } static ut_thread ut_threadFindFreeSlot(ut_threads threads, const char *name) { - os_uint32 i; + os_int32 i; assert(name); assert(threads); for (i = 0; i < threads->size; i++) { @@ -231,14 +235,16 @@ ut_threadToString(ut_thread thr, os_boolean alive, const char *info, char *buf, assert(buf); if (info != NULL) { ret = snprintf(buf, size, - " \"%s\":%c:%s", + " \"%s\"(0x%" PA_PRIxADDR "):%c:%s", thr->name, + (os_address)os_threadIdToInteger(thr->tid), alive ? 'a' : 'd', info); } else { ret = snprintf(buf, size, - " \"%s\":%c", + " \"%s\"(0x%" PA_PRIxADDR "):%c", thr->name, + (os_address)os_threadIdToInteger(thr->tid), alive ? 'a' : 'd'); } return (ret > 0) ? (os_uint32)ret : 0; @@ -267,8 +273,10 @@ ut_threadCreate(ut_threads threads, ut_thread *thr, const char *name, const os_t (*thr)->state = UT_THREAD_STATE_ALIVE; } else { OS_REPORT(OS_ERROR, OS_FUNCTION, 0, "%s: failed to create thread: %s", name, os_resultImage(rc)); - os_free((*thr)); + os_free((*thr)->name); (*thr)->name = NULL; + (*thr)->f = NULL; + (*thr)->f_arg = NULL; (*thr) = NULL; } } else { @@ -284,14 +292,43 @@ ut_threadCreate(ut_threads threads, ut_thread *thr, const char *name, const os_t os_result ut_threadWaitExit(ut_thread thr, void **result) { - os_result r = os_resultBusy; + os_result r; + assert(thr); - if (thr->liveliness.alive) { + + r = os_threadWaitExit(thr->tid, result); + if (r == os_resultSuccess) { + ut_threadStateSet(thr, UT_THREAD_STATE_ZERO, OS_THREAD_ID_NONE, NULL); + } + + return r; +} + +os_result +ut_threadTimedWaitExit(ut_thread thr, os_duration timeout, void **result) +{ + os_result r = os_resultSuccess; + ut_threads threads = (ut_threads)thr->threads; + ut_thread self; + assert(thr); + + self = ut_threadLookupSelf(threads); + os_mutexLock(&threads->lock); + if (thr->state != UT_THREAD_STATE_REAP) { + r = ut_condTimedWait(self, &thr->cond, &threads->lock, timeout); + } + os_mutexUnlock(&threads->lock); + if (r == os_resultSuccess) { r = os_threadWaitExit(thr->tid, result); } + if (r == os_resultSuccess) { + ut_threadStateSet(thr, UT_THREAD_STATE_ZERO, OS_THREAD_ID_NONE, NULL); + } + return r; } + os_result ut_sleep(ut_thread thr, os_duration delay) { @@ -299,7 +336,7 @@ ut_sleep(ut_thread thr, os_duration delay) assert(thr); assert(ut_drowsyAwake(thr->drowsyCnt)); ut_threadAsleep(thr, UT_SLEEPSEC_FROM_DURATION(delay)); - r = os_sleep(delay); + r = ospl_os_sleep(delay); ut_threadAwake(thr); return r; } @@ -329,7 +366,7 @@ ut_condWait(ut_thread thr, os_cond *cv, os_mutex *mtx) ut_thread ut_threadLookupId(ut_threads threads, os_threadId tid) { - os_uint32 i; + os_int32 i; assert(threads); if (threads->pool) { for (i = 0; i < threads->size; i++) { @@ -402,10 +439,10 @@ ut_threadsAllIsWell(ut_threads threads, ut_threadReport reportCb, void *reportDa os_timeM tnow; os_duration tdelta; const char *caller = ""; - os_boolean ok = FALSE; + os_boolean ok = OS_FALSE; os_uint32 changeCnt = 0; - os_uint32 aliveCnt = 0; - os_uint32 i; + os_int32 aliveCnt = 0; + os_int32 i; assert(threads); assert(threads->pool); @@ -425,8 +462,7 @@ ut_threadsAllIsWell(ut_threads threads, ut_threadReport reportCb, void *reportDa caller = self->name; } - /* Check whether all threads have made progress (or have declared themselves to be - asleep). */ + /* Check whether all threads have made progress (or have declared themselves to be asleep). */ for (i = 0; i < threads->size; i++) { ut_thread thr = &(threads->pool[i]); switch (thr->state) { @@ -438,7 +474,8 @@ ut_threadsAllIsWell(ut_threads threads, ut_threadReport reportCb, void *reportDa os_boolean alive; /* Bracket reading of sleepSec with reading drowsyCnt, so that we can - detect races with the other thread. */ + * detect races with the other thread. + */ dCnt0 = thr->drowsyCnt; pa_fence_acq (); sleepSec = thr->sleepSec; @@ -449,12 +486,14 @@ ut_threadsAllIsWell(ut_threads threads, ut_threadReport reportCb, void *reportDa /* thread has declared itself awake */ if (dCnt != thr->liveliness.prevDrowsyCnt) { /* drowsyCnt has changed, so thread has declared - * itself awake within the interval: restart */ + * itself awake within the interval: restart + */ thr->liveliness.awakeCum = 0; - alive = TRUE; + alive = OS_TRUE; } else { /* accumulate awake time and check if the interval - hasn't passed yet */ + * hasn't passed yet + */ thr->liveliness.awakeCum += tdelta; alive = (thr->liveliness.awakeCum < threads->interval); } @@ -462,22 +501,25 @@ ut_threadsAllIsWell(ut_threads threads, ut_threadReport reportCb, void *reportDa /* thread has declared itself asleep */ if (dCnt == thr->liveliness.sleepCnt) { /* accumulate sleep time and check it is - within bounds + interval period */ + * within bounds + interval period + */ thr->liveliness.sleepCum += tdelta; alive = ((sleepSec == 0) || (thr->liveliness.sleepCum < (OS_DURATION_INIT(sleepSec, 0) + threads->interval))); } else if (dCnt == dCnt0) { /* sleepSec we read is consistent with drowsyCnt (since the drowsyCnt - read before and after we read sleepSec are equal) */ + * read before and after we read sleepSec are equal) + */ thr->liveliness.sleepCnt = dCnt; thr->liveliness.sleepCum = 0; - alive = TRUE; + alive = OS_TRUE; } else { /* inconsistent sleep state which means the thread must have been - awake at that point; we update sleepCnt to avoid (with - certainty) a race with the other thread where we eventually - erroneously conclude that its drowsyCnt equals our sleepCnt */ + * awake at that point; we update sleepCnt to avoid (with + * certainty) a race with the other thread where we eventually + * erroneously conclude that its drowsyCnt equals our sleepCnt + */ thr->liveliness.sleepCnt = dCnt - 2; - alive = TRUE; + alive = OS_TRUE; } } @@ -506,7 +548,6 @@ ut_threadsAllIsWell(ut_threads threads, ut_threadReport reportCb, void *reportDa } break; case UT_THREAD_STATE_REAP: - ut_threadStateSet(thr, UT_THREAD_STATE_ZERO, thr->tid, NULL); /* FALLSTHROUGH */ case UT_THREAD_STATE_ZERO: /* Simulate alive. */ @@ -536,36 +577,53 @@ ut_threadsAllIsWell(ut_threads threads, ut_threadReport reportCb, void *reportDa ut_threads -ut_threadsNew(const char *selfname, os_duration interval, os_uint32 maxthreads, void *userdata) +ut_threadsNew(const char *selfname, os_duration interval, os_int32 maxthreads, void *userdata) { ut_threads threads = os_malloc(OS_SIZEOF(ut_threads)); + os_result osr; + assert(selfname); assert(maxthreads > 0); if (threads) { - os_uint32 i; + os_int32 i; memset(threads, 0, OS_SIZEOF(ut_threads)); - if (os_mutexInit(&(threads->lock), NULL) != os_resultSuccess) { - OS_REPORT (OS_ERROR, OS_FUNCTION, 0, "failed to initialize mutex"); + osr = os_mutexInit(&(threads->lock), NULL); + if (osr != os_resultSuccess) { + OS_REPORT (OS_ERROR, OS_FUNCTION, 0, "failed to initialize mutex '%s'", os_resultImage(osr)); os_free(threads); return NULL; } - threads->pool = ut_mallocAligned(maxthreads * OS_SIZEOF(ut_thread)); + threads->pool = ut_mallocAligned((os_size_t)maxthreads * OS_SIZEOF(ut_thread)); if (threads->pool == NULL) { os_mutexDestroy(&(threads->lock)); OS_REPORT(OS_ERROR, OS_FUNCTION, 0, "failed to initialize threads table"); os_free(threads); return NULL; } - memset(threads->pool, 0, maxthreads * OS_SIZEOF(ut_thread)); - for (i = 0; i < maxthreads; i++) + memset(threads->pool, 0, (os_size_t)maxthreads * OS_SIZEOF(ut_thread)); + for (i = 0; i < maxthreads && osr == os_resultSuccess; i++) { ut_thread thr = &(threads->pool[i]); thr->state = UT_THREAD_STATE_ZERO; thr->drowsyCnt = 1; thr->name = NULL; thr->threads = (void*)threads; - thr->liveliness.alive = TRUE; + thr->liveliness.alive = OS_TRUE; + osr = os_condInit(&thr->cond, &threads->lock, NULL); + } + if (osr != os_resultSuccess) { + os_int32 j; + OS_REPORT (OS_ERROR, OS_FUNCTION, 0, "failed to initialize cond[%d] '%s'", i, os_resultImage(osr)); + for (j = i; j >= i; j--) { + ut_thread thr = &(threads->pool[i]); + os_condDestroy(&thr->cond); + } + ut_freeAligned(threads->pool); + os_mutexDestroy(&(threads->lock)); + os_free(threads); + return NULL; } + threads->size = maxthreads; threads->userdata = userdata; threads->interval = interval; @@ -585,7 +643,7 @@ ut_threadsNew(const char *selfname, os_duration interval, os_uint32 maxthreads, void ut_threadsFree(ut_threads threads) { - os_uint32 i; + os_int32 i; if (threads) { assert(threads->pool); @@ -595,17 +653,19 @@ ut_threadsFree(ut_threads threads) ut_thread thr = ut_threadLookupSelf(threads); assert(thr == ut_threadLookupId(threads, threads->main)); ut_threadAsleep(thr, UT_SLEEP_INDEFINITELY); - ut_threadStateSet(thr, UT_THREAD_STATE_REAP, OS_THREAD_ID_NONE, NULL); + ut_threadStateSet(thr, UT_THREAD_STATE_ZERO, OS_THREAD_ID_NONE, NULL); } for (i = 0; i < threads->size; i++) { ut_thread thr = &(threads->pool[i]); /* Just a sanity check. */ assert(thr->state != UT_THREAD_STATE_ALIVE); + assert(thr->state != UT_THREAD_STATE_REAP); if (thr->name != NULL) { os_free(thr->name); thr->name = NULL; } + os_condDestroy(&thr->cond); } /* Now, cleanup the threads object. */ diff --git a/src/utilities/code/ut_thread_pool.c b/src/utilities/code/ut_thread_pool.c index a67c59695..d66cba771 100644 --- a/src/utilities/code/ut_thread_pool.c +++ b/src/utilities/code/ut_thread_pool.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -109,10 +110,8 @@ static os_result ut_thread_pool_new_thread (ut_thread_pool pool) if (res == os_resultSuccess) { - os_mutexLock (&pool->m_mutex); pool->m_threads++; pool->m_waiting++; - os_mutexUnlock (&pool->m_mutex); } return res; @@ -148,6 +147,7 @@ ut_thread_pool ut_thread_pool_new os_sem_init (&pool->m_sem, 0); os_threadAttrInit (&pool->m_attr); os_mutexInit (&pool->m_mutex, NULL); + os_mutexLock (&pool->m_mutex); if (attr) { @@ -160,15 +160,18 @@ ut_thread_pool ut_thread_pool_new { if (ut_thread_pool_new_thread (pool) != os_resultSuccess) { + os_mutexUnlock (&pool->m_mutex); ut_thread_pool_free (pool); pool = NULL; - break; + goto err_resource_claim; } job = os_malloc (sizeof (*job)); job->m_next_job = pool->m_free; pool->m_free = job; } + os_mutexUnlock (&pool->m_mutex); +err_resource_claim: return pool; } @@ -219,7 +222,7 @@ void ut_thread_pool_free (ut_thread_pool pool) { break; } - os_sleep (delay); + ospl_os_sleep (delay); } /* Delete all free jobs from queue */ diff --git a/src/utilities/code/ut_tmplExp.c b/src/utilities/code/ut_tmplExp.c index fc7221ddf..5492d57f3 100644 --- a/src/utilities/code/ut_tmplExp.c +++ b/src/utilities/code/ut_tmplExp.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -403,6 +404,7 @@ ut_dirOutFree(void) { if (ut_outputdir) { os_free(ut_outputdir); + ut_outputdir = NULL; } return; } @@ -414,12 +416,12 @@ ut_dirOutNew( os_int32 result; os_result status; char dirName[OS_PATH_MAX]; - struct os_stat statBuf; + struct os_stat_s statBuf; os_uint32 i; memset(dirName, 0, OS_PATH_MAX); - if (name) { + if ((name) && (strlen(name))){ result = 1; for (i = 0; i < strlen(name) && result; i++) { @@ -427,7 +429,7 @@ ut_dirOutNew( status = os_stat(dirName, &statBuf); if (status != os_resultSuccess) { - os_mkdir(dirName, S_IRWXU | S_IRWXG | S_IRWXO); + (void)os_mkdir(dirName, S_IRWXU | S_IRWXG | S_IRWXO); status = os_stat(dirName, &statBuf); } if (status != os_resultSuccess || !OS_ISDIR (statBuf.stat_mode)) { @@ -437,12 +439,12 @@ ut_dirOutNew( } else { printf("'%s' is not a directory\n", dirName); result = 0; - ut_outputdir = NULL; + ut_dirOutFree(); } #else printf("'%s' is not a directory\n", dirName); result = 0; - ut_outputdir = NULL; + ut_dirOutFree(); #endif } } @@ -453,7 +455,7 @@ ut_dirOutNew( status = os_stat(dirName, &statBuf); if (status != os_resultSuccess) { - os_mkdir(dirName, S_IRWXU | S_IRWXG | S_IRWXO); + (void)os_mkdir(dirName, S_IRWXU | S_IRWXG | S_IRWXO); status = os_stat(dirName, &statBuf); } ut_outputdir = os_strdup(name); @@ -468,17 +470,17 @@ ut_dirOutNew( if (status == os_resultFail) { printf("'%s' is not available", dirName); result = 0; - ut_outputdir = NULL; + ut_dirOutFree(); } } else { printf("'%s' is not a directory.\n", ut_outputdir); result = 0; - ut_outputdir = NULL; + ut_dirOutFree(); } #else printf("'%s' is not a directory\n", dirName); result = 0; - ut_outputdir = NULL; + ut_dirOutFree(); #endif } } else { @@ -488,7 +490,7 @@ ut_dirOutNew( } } else { result = 0; - ut_outputdir = NULL; + ut_dirOutFree(); } if (result) { @@ -504,17 +506,15 @@ ut_dirOutNew( if (status == os_resultFail) { printf("'%s' cannot be found", dirName); result = 0; - ut_outputdir = NULL; } } else { printf("Specified output directory '%s' is not writable.\n", ut_outputdir); result = 0; - ut_outputdir = NULL; } #else printf("Specified output directory '%s' is not writable.\n", ut_outputdir); result = 0; - ut_outputdir = NULL; + ut_dirOutFree(); #endif } } diff --git a/src/utilities/code/ut_trace.c b/src/utilities/code/ut_trace.c index 8a5bc41db..625bae096 100644 --- a/src/utilities/code/ut_trace.c +++ b/src/utilities/code/ut_trace.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/utilities/code/ut_wrapper_lzf.c b/src/utilities/code/ut_wrapper_lzf.c index ab0b9e07c..6b87b416f 100644 --- a/src/utilities/code/ut_wrapper_lzf.c +++ b/src/utilities/code/ut_wrapper_lzf.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -32,8 +33,7 @@ typedef struct wrapper_lzf { _lzf_decompress decompress; } wrapper_lzf; -/* - * The lzf compress wrapper will return a buffer which the +/* The lzf compress wrapper will return a buffer which the * following layout: * +===================================================== * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | ... | n @@ -300,6 +300,8 @@ ut__wrapper_lzf_init ( OS_REPORT(OS_ERROR, OS_FUNCTION, result, "At least one of required functions 'lzf_compress,lzf_decompress' not found"); } + } else { + os_free(wrapper); } return result; } diff --git a/src/utilities/code/ut_wrapper_snappy.c b/src/utilities/code/ut_wrapper_snappy.c index 7be9e4aa1..d2ec400dd 100644 --- a/src/utilities/code/ut_wrapper_snappy.c +++ b/src/utilities/code/ut_wrapper_snappy.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -43,8 +44,7 @@ typedef struct wrapper_snappy { _snappy_max_compressed_length max_compressed_length; } wrapper_snappy; -/* - * The lzf compress wrapper will return a buffer which the +/* The lzf compress wrapper will return a buffer which the * following layout: * +============================= * | 0 | 1 | 2 | ... | n @@ -288,6 +288,8 @@ ut__wrapper_snappy_init ( "At least one of required functions 'snappy_init_env,snappy_free_env,snappy_uncompress" ",snappy_compress,snappy_uncompressed_length,snappy_max_compressed_length' not found"); } + } else { + os_free(wrapper); } return result; diff --git a/src/utilities/code/ut_wrapper_zlib.c b/src/utilities/code/ut_wrapper_zlib.c index 2a6e71849..6fd46e644 100644 --- a/src/utilities/code/ut_wrapper_zlib.c +++ b/src/utilities/code/ut_wrapper_zlib.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -46,8 +47,7 @@ typedef struct wrapper_zlib { _zlibVersion zlibVersion; } wrapper_zlib; -/* - * The zlib compress wrapper will return a buffer which the +/* The zlib compress wrapper will return a buffer which the * following layout: * +===================================================== * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | ... | n @@ -334,6 +334,8 @@ ut__wrapper_zlib_init ( OS_REPORT(OS_ERROR, OS_FUNCTION, result, "At least one of required functions 'compress2,uncompress,compressBound,zlibVersion' not found"); } + } else { + os_free(wrapper); } return result; diff --git a/src/utilities/code/ut_xmlparser.c b/src/utilities/code/ut_xmlparser.c index c000e30dd..c3c72de86 100644 --- a/src/utilities/code/ut_xmlparser.c +++ b/src/utilities/code/ut_xmlparser.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -188,7 +189,8 @@ static int make_chars_available (struct ut_xmlpState *st, size_t nmin) st->cbuf = os_realloc (st->cbuf, st->cbufmax); } /* try to refill buffer if a backing file is present; eof (or end-of-string) is - reached when this doesn't add any bytes to the buffer */ + * reached when this doesn't add any bytes to the buffer + */ if (st->fp != NULL) { n = fread (st->cbuf + st->cbufn, 1, st->cbufmax - st->cbufn, st->fp); st->cbufn += n; @@ -506,7 +508,7 @@ static void drop_peek_token (struct ut_xmlpState *st) static int next_token (struct ut_xmlpState *st, char **payload) { /* Always return a valid pointer to allocated memory or a null - pointer, regardless of token type */ + * pointer, regardless of token type */ if (payload) { *payload = NULL; } @@ -639,7 +641,8 @@ static int parse_element (struct ut_xmlpState *st, os_address parentinfo) } } /* if the mark-up happens to be a CDATA, consume it, and gobble up characters - until the closing marker is reached, which then also gets consumed */ + * until the closing marker is reached, which then also gets consumed + */ if (peek_chars (st, "", 1) && peek_char (st) != TOK_EOF) { if (append_to_payload (st, next_char (st), 1) < 0) { diff --git a/src/utilities/include/ut_avl.h b/src/utilities/include/ut_avl.h index d82ae0831..2f3483b1d 100644 --- a/src/utilities/include/ut_avl.h +++ b/src/utilities/include/ut_avl.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/utilities/include/ut_collection.h b/src/utilities/include/ut_collection.h index 73a181fce..3669651a8 100644 --- a/src/utilities/include/ut_collection.h +++ b/src/utilities/include/ut_collection.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/utilities/include/ut_compressor.h b/src/utilities/include/ut_compressor.h index 42919ad24..753e981bf 100644 --- a/src/utilities/include/ut_compressor.h +++ b/src/utilities/include/ut_compressor.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/utilities/include/ut_crc.h b/src/utilities/include/ut_crc.h index d2b173d34..3ab56f183 100644 --- a/src/utilities/include/ut_crc.h +++ b/src/utilities/include/ut_crc.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/utilities/include/ut_entryPoint.h b/src/utilities/include/ut_entryPoint.h index d09f79725..91666e14d 100644 --- a/src/utilities/include/ut_entryPoint.h +++ b/src/utilities/include/ut_entryPoint.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/utilities/include/ut_expand_envvars.h b/src/utilities/include/ut_expand_envvars.h index c8687d674..5865bd3cb 100644 --- a/src/utilities/include/ut_expand_envvars.h +++ b/src/utilities/include/ut_expand_envvars.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/utilities/include/ut_fibheap.h b/src/utilities/include/ut_fibheap.h index 0979e4ef3..504c8ea60 100644 --- a/src/utilities/include/ut_fibheap.h +++ b/src/utilities/include/ut_fibheap.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/utilities/include/ut_hex.h b/src/utilities/include/ut_hex.h new file mode 100644 index 000000000..54192b688 --- /dev/null +++ b/src/utilities/include/ut_hex.h @@ -0,0 +1,62 @@ +/* + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#ifndef UT_HEX_H +#define UT_HEX_H + +#include "os_defs.h" + +#if defined (__cplusplus) +extern "C" { +#endif + +#ifdef OSPL_BUILD_CORE +#define OS_API OS_API_EXPORT +#else +#define OS_API OS_API_IMPORT +#endif +/* !!!!!!!!NOTE From here no more includes are allowed!!!!!!! */ + +/** + * \brief Encodes input as hexadecimal and returns number of bytes written. + * + * os_hexenc encodes the input as hexadecimal ascii and returns the number of + * bytes that are required to encode the input, even if the output buffer is + * not large enough. If the output buffer is large enough it's null terminated. + * + * Precondition: + * None + * Postcondition: + * None + */ +OS_API int +ut_hexenc( + char *xbuf, + unsigned int xlen, + const unsigned char *buf, + unsigned int len); + +#undef OS_API + +#if defined (__cplusplus) +} +#endif + +#endif /* UT_HEX_H */ diff --git a/src/utilities/include/ut_hopscotch.h b/src/utilities/include/ut_hopscotch.h index e6ade5a60..fa415a60d 100644 --- a/src/utilities/include/ut_hopscotch.h +++ b/src/utilities/include/ut_hopscotch.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/utilities/include/ut_md5.h b/src/utilities/include/ut_md5.h new file mode 100644 index 000000000..1f08168e7 --- /dev/null +++ b/src/utilities/include/ut_md5.h @@ -0,0 +1,120 @@ +/* Minimal changes introduced, for which: + * + * Vortex OpenSplice + * + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. + * + * Licensed under the ADLINK Software License Agreement Rev 2.7 2nd October + * 2014 (the "License"); you may not use this file except in compliance with + * the License. + * You may obtain a copy of the License at: + * $OSPL_HOME/LICENSE + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +/* + Copyright (C) 1999, 2002 Aladdin Enterprises. All rights reserved. + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + L. Peter Deutsch + ghost@aladdin.com + + */ +/* $Id: md5.h,v 1.4 2002/04/13 19:20:28 lpd Exp $ */ +/* + Independent implementation of MD5 (RFC 1321). + + This code implements the MD5 Algorithm defined in RFC 1321, whose + text is available at + http://www.ietf.org/rfc/rfc1321.txt + The code is derived from the text of the RFC, including the test suite + (section A.5) but excluding the rest of Appendix A. It does not include + any code or documentation that is identified in the RFC as being + copyrighted. + + The original and principal author of md5.h is L. Peter Deutsch + . Other authors are noted in the change history + that follows (in reverse chronological order): + + 2002-04-13 lpd Removed support for non-ANSI compilers; removed + references to Ghostscript; clarified derivation from RFC 1321; + now handles byte order either statically or dynamically. + 1999-11-04 lpd Edited comments slightly for automatic TOC extraction. + 1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5); + added conditionalization for C++ compilation from Martin + Purschke . + 1999-05-03 lpd Original version. + */ + +#ifndef UT_MD5_H +#define UT_MD5_H + +#include "os_defs.h" + +/* + * This package supports both compile-time and run-time determination of CPU + * byte order. If ARCH_IS_BIG_ENDIAN is defined as 0, the code will be + * compiled to run only on little-endian CPUs; if ARCH_IS_BIG_ENDIAN is + * defined as non-zero, the code will be compiled to run only on big-endian + * CPUs; if ARCH_IS_BIG_ENDIAN is not defined, the code will be compiled to + * run on either big- or little-endian CPUs, but will run slightly less + * efficiently on either one than if ARCH_IS_BIG_ENDIAN is defined. + */ + +typedef unsigned char ut_md5_byte_t; /* 8-bit byte */ +typedef unsigned int ut_md5_word_t; /* 32-bit word */ + +/* Define the state of the MD5 Algorithm. */ +typedef struct ut_md5_state_s { + ut_md5_word_t count[2]; /* message length in bits, lsw first */ + ut_md5_word_t abcd[4]; /* digest buffer */ + ut_md5_byte_t buf[64]; /* accumulate block */ +} ut_md5_state_t; + +#ifdef __cplusplus +extern "C" +{ +#endif + +#ifdef OSPL_BUILD_CORE +#define OS_API OS_API_EXPORT +#else +#define OS_API OS_API_IMPORT +#endif +/* !!!!!!!!NOTE From here no more includes are allowed!!!!!!! */ + +/* Initialize the algorithm. */ +OS_API void ut_md5_init(ut_md5_state_t *pms); + +/* Append a string to the message. */ +OS_API void ut_md5_append(ut_md5_state_t *pms, const ut_md5_byte_t *data, unsigned nbytes); + +/* Finish the message and return the digest. */ +OS_API void ut_md5_finish(ut_md5_state_t *pms, ut_md5_byte_t digest[16]); + +#undef OS_API + +#ifdef __cplusplus +} /* end extern "C" */ +#endif + +#endif /* UT_MD5_H */ diff --git a/src/utilities/include/ut_result.h b/src/utilities/include/ut_result.h index b013d7a63..77e96451f 100644 --- a/src/utilities/include/ut_result.h +++ b/src/utilities/include/ut_result.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/utilities/include/ut_snappy-compat.h b/src/utilities/include/ut_snappy-compat.h index 79db1b201..1b9601998 100644 --- a/src/utilities/include/ut_snappy-compat.h +++ b/src/utilities/include/ut_snappy-compat.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/utilities/include/ut_snappy.h b/src/utilities/include/ut_snappy.h index 6595057ae..19cfbda43 100644 --- a/src/utilities/include/ut_snappy.h +++ b/src/utilities/include/ut_snappy.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/utilities/include/ut_stack.h b/src/utilities/include/ut_stack.h index 6c2db6771..37bcaf69d 100644 --- a/src/utilities/include/ut_stack.h +++ b/src/utilities/include/ut_stack.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/utilities/include/ut_thread.h b/src/utilities/include/ut_thread.h index 50e562541..1a70223ea 100644 --- a/src/utilities/include/ut_thread.h +++ b/src/utilities/include/ut_thread.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -37,15 +38,13 @@ extern "C" { #endif -/* - * An ut_threads object contains information about the threads that were +/* An ut_threads object contains information about the threads that were * created in that objects' context. It can be used to detect if the related * threads make progress or are likely deadlocked. */ OS_CLASS(ut_threads); -/* - * An ut_thread object contains information about a specific thread. +/* An ut_thread object contains information about a specific thread. * * An ut_thread should call ut_threadAwake() periodically to let the utility * know that the thread is not deadlocked. This 'periodically' means within @@ -63,8 +62,7 @@ OS_CLASS(ut_threads); OS_CLASS(ut_thread); -/* - * If a caller is interested in the states of its threads, it can provide +/* If a caller is interested in the states of its threads, it can provide * a report callback when calling ut_threadsAllIsWell(). * * This is the callback type. @@ -97,15 +95,13 @@ typedef void void *userdata); -/* - * When not knowing when the thread should wake up again, UT_SLEEP_INDEFINITELY +/* When not knowing when the thread should wake up again, UT_SLEEP_INDEFINITELY * can be passed to ut_threadAsleep(). */ #define UT_SLEEP_INDEFINITELY (0) -/* - * Create a new threads object with which to manage and check threads. +/* Create a new threads object with which to manage and check threads. * * The calling thread is automatically added as an awake thread to the threads * object. The thread is added under the assumed name 'selfname'. @@ -121,10 +117,9 @@ typedef void * New threads managing object. */ OS_API ut_threads -ut_threadsNew(const char* selfname, os_duration interval, os_uint32 maxthreads, void *userdata); +ut_threadsNew(const char* selfname, os_duration interval, os_int32 maxthreads, void *userdata); -/* - * Frees the threads managing object. +/* Frees the threads managing object. * * All related threads should have stopped. * @@ -137,8 +132,7 @@ ut_threadsNew(const char* selfname, os_duration interval, os_uint32 maxthreads, OS_API void ut_threadsFree(ut_threads threads); -/* - * Overrules the interval set when calling ut_threadsNew. +/* Overrules the interval set when calling ut_threadsNew. * * Parameters: * threads - The threads managing object. @@ -150,8 +144,7 @@ ut_threadsFree(ut_threads threads); OS_API void ut_threadsSetInterval(ut_threads threads, os_duration interval); -/* - * Checks the threads that are related to the managing object. +/* Checks the threads that are related to the managing object. * * All is well when all threads have either announced themselves awake within * the required interval (provided when calling ut_threadsNew) or asleep (and @@ -186,8 +179,7 @@ ut_threadsSetInterval(ut_threads threads, os_duration interval); OS_API os_boolean ut_threadsAllIsWell(ut_threads threads, ut_threadReport reportCb, void *reportData); -/* - * Returns the userdata provided when calling ut_threadsNew(). +/* Returns the userdata provided when calling ut_threadsNew(). * * Parameters: * threads - The threads managing object. @@ -218,8 +210,7 @@ ut_threadsUserData(ut_threads threads); OS_API void ut_threadCreate(ut_threads threads, ut_thread *thr, const char *name, const os_threadAttr *threadAttr, os_threadRoutine startRoutine, void *arg); -/* - * Finds and returns the thread info identified by the OS thread ID. +/* Finds and returns the thread info identified by the OS thread ID. * * Parameters: * threads - The threads managing object. @@ -233,8 +224,7 @@ ut_threadCreate(ut_threads threads, ut_thread *thr, const char *name, const os_t OS_API ut_thread ut_threadLookupId(ut_threads threads, os_threadId tid); -/* - * Finds and returns the thread info of the calling thread. +/* Finds and returns the thread info of the calling thread. * * Parameters: * threads - The threads managing object. @@ -246,8 +236,7 @@ ut_threadLookupId(ut_threads threads, os_threadId tid); OS_API ut_thread ut_threadLookupSelf(ut_threads threads); -/* - * Indicate that the thread will sleep for a number of seconds and thus will +/* Indicate that the thread will sleep for a number of seconds and thus will * not announce itself awake in that period. * * Parameters: @@ -260,8 +249,7 @@ ut_threadLookupSelf(ut_threads threads); OS_API void ut_threadAsleep(ut_thread thr, os_uint32 sec); -/* - * Indicate that the thread is still awake. +/* Indicate that the thread is still awake. * * Parameters: * thr - The thread that is still awake. @@ -272,8 +260,7 @@ ut_threadAsleep(ut_thread thr, os_uint32 sec); OS_API void ut_threadAwake(ut_thread thr); -/* - * Return the OS thread ID of the given utilities thread. +/* Return the OS thread ID of the given utilities thread. * * Parameters: * thr - The thread to get the ID from. @@ -284,8 +271,7 @@ ut_threadAwake(ut_thread thr); OS_API os_threadId ut_threadGetId(ut_thread thr); -/* - * Return the name of the given utilities thread. +/* Return the name of the given utilities thread. * * Be aware that the pointer is only valid as long as the thread is running. * @@ -298,8 +284,7 @@ ut_threadGetId(ut_thread thr); OS_API const char* ut_threadGetName(ut_thread thr); -/* - * Suspend the execution of the calling thread for the specified time. +/* Suspend the execution of the calling thread for the specified time. * * It is registered that the thread will not indicate progress while it * is sleeping. @@ -319,8 +304,7 @@ ut_threadGetName(ut_thread thr); OS_API os_result ut_sleep(ut_thread thr, os_duration delay); -/* - * Wait for the condition +/* Wait for the condition * * It is registered that the thread will not indicate progress while it * is waiting on the condition. @@ -344,8 +328,7 @@ ut_sleep(ut_thread thr, os_duration delay); OS_API void ut_condWait(ut_thread thr, os_cond *cv, os_mutex *mtx); -/* - * Wait for the condition but return when the specified time has expired +/* Wait for the condition but return when the specified time has expired * before the condition is triggered * * It is registered that the thread will not indicate progress while it @@ -372,8 +355,7 @@ ut_condWait(ut_thread thr, os_cond *cv, os_mutex *mtx); OS_API os_result ut_condTimedWait(ut_thread thr, os_cond *cv, os_mutex *mtx, os_duration timeout); -/* - * Wait for the termination of the identified thread +/* Wait for the termination of the identified thread * * If the identified thread is still running, wait for its termination else * return immediately. In thread_result it returns the exit status of the @@ -398,8 +380,10 @@ ut_condTimedWait(ut_thread thr, os_cond *cv, os_mutex *mtx, os_duration timeout) OS_API os_result ut_threadWaitExit(ut_thread thr, void **result); -/* - * Translate the given thread information into a string and copy it into the +OS_API os_result +ut_threadTimedWaitExit(ut_thread thr, os_duration timeout, void **result); + +/* Translate the given thread information into a string and copy it into the * given buffer. * * It does not write more than size bytes (including the terminating null byte diff --git a/src/utilities/include/ut_thread_pool.h b/src/utilities/include/ut_thread_pool.h index eb1b01451..3fbb4841a 100644 --- a/src/utilities/include/ut_thread_pool.h +++ b/src/utilities/include/ut_thread_pool.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -37,14 +38,13 @@ extern "C" { OS_CLASS(ut_thread_pool); -/* - ut_thread_pool_new: Creates a new thread pool. Returns NULL if - cannot create initial set of threads. Threads are created with - the optional atribute argument. Additional threads may be created - on demand up to max_threads. -*/ +/* ut_thread_pool_new: Creates a new thread pool. Returns NULL if + * cannot create initial set of threads. Threads are created with + * the optional atribute argument. Additional threads may be created + * on demand up to max_threads. + */ -OS_API ut_thread_pool ut_thread_pool_new +OS_API ut_thread_pool ut_thread_pool_new ( os_uint32 threads, /* Initial number of threads in pool (can be 0) */ os_uint32 max_threads, /* Maximum number of threads in pool (0 == infinite) */ @@ -60,13 +60,12 @@ OS_API void ut_thread_pool_free (ut_thread_pool pool); OS_API void ut_thread_pool_purge (ut_thread_pool pool); -/* - ut_thread_pool_submit: Submit a thread function and associated argument - to be invoked by a thread from the pool. If no threads are available a - new thread will be created on demand to handle the function unless the - pool thread maximum has been reached, in which case the function is queued. - Note that if the pool queue has reached it's maximum os_resultBusy is returned. -*/ +/* ut_thread_pool_submit: Submit a thread function and associated argument + * to be invoked by a thread from the pool. If no threads are available a + * new thread will be created on demand to handle the function unless the + * pool thread maximum has been reached, in which case the function is queued. + * Note that if the pool queue has reached it's maximum os_resultBusy is returned. + */ OS_API os_result ut_thread_pool_submit ( diff --git a/src/utilities/include/ut_tmplExp.h b/src/utilities/include/ut_tmplExp.h index c8821d6a2..eb3f847ad 100644 --- a/src/utilities/include/ut_tmplExp.h +++ b/src/utilities/include/ut_tmplExp.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/utilities/include/ut_trace.h b/src/utilities/include/ut_trace.h index 5c43dae77..fd00f3d22 100644 --- a/src/utilities/include/ut_trace.h +++ b/src/utilities/include/ut_trace.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,8 +24,6 @@ #define UT_TRACE_ENABLED (0) /* to enable basic backtraceing set this to 1 */ -/* removed UT_TRACE_EXTENSION See OSPL-5656 and OSPL-987 */ - #if UT_TRACE_ENABLED #define UT_TRACE_MAX_STACK 64 diff --git a/src/utilities/include/ut_xmlparser.h b/src/utilities/include/ut_xmlparser.h index 56430a7b6..2b4668a63 100644 --- a/src/utilities/include/ut_xmlparser.h +++ b/src/utilities/include/ut_xmlparser.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -56,7 +57,7 @@ extern "C" { OS_API int ut_xmlUnescapeInsitu (char *buffer, size_t *n); #undef OS_API - + #if defined (__cplusplus) } #endif diff --git a/testsuite/tests/dds2497/app/pub/code/dds2497_pub.c b/testsuite/tests/dds2497/app/pub/code/dds2497_pub.c index 662913f4d..2f499072a 100755 --- a/testsuite/tests/dds2497/app/pub/code/dds2497_pub.c +++ b/testsuite/tests/dds2497/app/pub/code/dds2497_pub.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/testsuite/tests/dds2497/app/sub/code/dds2497_sub.c b/testsuite/tests/dds2497/app/sub/code/dds2497_sub.c index aaaa870cd..fe1463f62 100755 --- a/testsuite/tests/dds2497/app/sub/code/dds2497_sub.c +++ b/testsuite/tests/dds2497/app/sub/code/dds2497_sub.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/testsuite/tests/docs/epydocs/class-tree.html b/testsuite/tests/docs/epydocs/class-tree.html index fbe7ad467..a6b86be38 100755 --- a/testsuite/tests/docs/epydocs/class-tree.html +++ b/testsuite/tests/docs/epydocs/class-tree.html @@ -34,7 +34,7 @@ + >DDS Community Edition
    test_ospl
    @@ -116,7 +116,7 @@

    Class Hierarchy

    + >DDS Community Edition
    test_ospl
    diff --git a/testsuite/tests/docs/epydocs/help.html b/testsuite/tests/docs/epydocs/help.html index e18fb7fe2..6f488dff3 100755 --- a/testsuite/tests/docs/epydocs/help.html +++ b/testsuite/tests/docs/epydocs/help.html @@ -34,7 +34,7 @@ + >DDS Community Edition
    test_ospl
    @@ -249,7 +249,7 @@

    The Navigation Bar

    + >DDS Community Edition
    test_ospl
    diff --git a/testsuite/tests/docs/epydocs/identifier-index.html b/testsuite/tests/docs/epydocs/identifier-index.html index a1da245b2..5d45df9b5 100755 --- a/testsuite/tests/docs/epydocs/identifier-index.html +++ b/testsuite/tests/docs/epydocs/identifier-index.html @@ -34,7 +34,7 @@ + >DDS Community Edition
    test_ospl
    @@ -333,7 +333,7 @@

    Identifier Index

    + >DDS Community Edition
    test_ospl
    diff --git a/testsuite/tests/docs/epydocs/module-tree.html b/testsuite/tests/docs/epydocs/module-tree.html index 3ab2c6a9c..b0b5f4adf 100755 --- a/testsuite/tests/docs/epydocs/module-tree.html +++ b/testsuite/tests/docs/epydocs/module-tree.html @@ -34,7 +34,7 @@ + >DDS Community Edition
    test_ospl
    @@ -86,7 +86,7 @@

    Module Hierarchy

    + >DDS Community Edition
    test_ospl
    diff --git a/testsuite/tests/docs/epydocs/test_ospl-module.html b/testsuite/tests/docs/epydocs/test_ospl-module.html index 59e9cbcbc..82adfe551 100755 --- a/testsuite/tests/docs/epydocs/test_ospl-module.html +++ b/testsuite/tests/docs/epydocs/test_ospl-module.html @@ -34,7 +34,7 @@ + >DDS Community Edition
    test_ospl
    @@ -168,7 +168,7 @@

    Module test_ospl

    + >DDS Community Edition
    test_ospl
    diff --git a/testsuite/tests/docs/epydocs/test_ospl-pysrc.html b/testsuite/tests/docs/epydocs/test_ospl-pysrc.html index 95c07fa82..ddf82e56f 100755 --- a/testsuite/tests/docs/epydocs/test_ospl-pysrc.html +++ b/testsuite/tests/docs/epydocs/test_ospl-pysrc.html @@ -34,7 +34,7 @@ + >DDS Community Edition
    test_ospl
    @@ -460,7 +460,7 @@

    Source Code for Module test_o + >DDS Community Edition
    test_ospl
    diff --git a/testsuite/tests/docs/epydocs/test_ospl.Process-class.html b/testsuite/tests/docs/epydocs/test_ospl.Process-class.html index bb3a06c63..e3860d14e 100755 --- a/testsuite/tests/docs/epydocs/test_ospl.Process-class.html +++ b/testsuite/tests/docs/epydocs/test_ospl.Process-class.html @@ -34,7 +34,7 @@ + >DDS Community Edition
    test_ospl
    @@ -487,7 +487,7 @@

    set_working_dir + >DDS Community Edition
    test_ospl
    diff --git a/testsuite/tests/docs/epydocs/test_ospl.TestError-class.html b/testsuite/tests/docs/epydocs/test_ospl.TestError-class.html index 4ca7bf534..156942dd5 100755 --- a/testsuite/tests/docs/epydocs/test_ospl.TestError-class.html +++ b/testsuite/tests/docs/epydocs/test_ospl.TestError-class.html @@ -34,7 +34,7 @@ + >DDS Community Edition
    test_ospl
    @@ -267,7 +267,7 @@

    __str__( + >DDS Community Edition
    test_ospl
    diff --git a/testsuite/tests/docs/epydocs/test_ospl.TestNode-class.html b/testsuite/tests/docs/epydocs/test_ospl.TestNode-class.html index 4d4c98f7f..5694dd697 100755 --- a/testsuite/tests/docs/epydocs/test_ospl.TestNode-class.html +++ b/testsuite/tests/docs/epydocs/test_ospl.TestNode-class.html @@ -34,7 +34,7 @@ + >DDS Community Edition
    test_ospl
    @@ -409,7 +409,7 @@

    path_sep( + >DDS Community Edition
    test_ospl
    diff --git a/testsuite/tests/docs/epydocs/test_ospl.TestRun-class.html b/testsuite/tests/docs/epydocs/test_ospl.TestRun-class.html index b14283d02..537be4781 100755 --- a/testsuite/tests/docs/epydocs/test_ospl.TestRun-class.html +++ b/testsuite/tests/docs/epydocs/test_ospl.TestRun-class.html @@ -34,7 +34,7 @@ + >DDS Community Edition
    test_ospl
    @@ -167,7 +167,7 @@

    Class TestRun

    + >DDS Community Edition
    test_ospl
    diff --git a/testsuite/tests/docs/epydocs/test_ospl.TestScenario-class.html b/testsuite/tests/docs/epydocs/test_ospl.TestScenario-class.html index 86f5e0001..ba2e4744f 100755 --- a/testsuite/tests/docs/epydocs/test_ospl.TestScenario-class.html +++ b/testsuite/tests/docs/epydocs/test_ospl.TestScenario-class.html @@ -34,7 +34,7 @@ + >DDS Community Edition
    test_ospl
    @@ -461,7 +461,7 @@

    requires_multiple_no + >DDS Community Edition
    test_ospl
    diff --git a/testsuite/tests/durability/common/fwctrl/code/os_firewall.c b/testsuite/tests/durability/common/fwctrl/code/os_firewall.c index 384ed4a17..aed52b3db 100644 --- a/testsuite/tests/durability/common/fwctrl/code/os_firewall.c +++ b/testsuite/tests/durability/common/fwctrl/code/os_firewall.c @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -53,11 +54,12 @@ getFirewall() idx = 0; if ((pipeRead = popen("/sbin/iptables-save", "r")) == NULL) { perror("getFirewall"); + os_free(dst); dst = NULL; } /* Read firewall line by line */ - while ((fgets(buff, LINESIZE, pipeRead)) && (dst != NULL)) { + while ((dst != NULL) && (fgets(buff, LINESIZE, pipeRead))) { len = strnlen(buff, LINESIZE); buff[len-1] = '\0'; /* remove newline-char */ dst = os_realloc(dst, (idx+1) * sizeof(char*)); @@ -69,6 +71,7 @@ getFirewall() dst = os_realloc(dst, (idx+1) * sizeof(char*)); dst[idx] = NULL; } else { + os_free(dst); dst = NULL; } @@ -131,7 +134,7 @@ newRule( int prot, os_portState state) { - char *protStr, *portStr, *hostStr, *actionStr, *prefix; + char *protStr, *portStr, *hostStr, *actionStr=NULL, *prefix; char *tmp, *mask; char *fwRule; @@ -179,6 +182,16 @@ newRule( prefix = "-A INPUT "; fwRule = os_malloc((strlen(prefix) + strlen(hostStr) + strlen(protStr) + strlen(portStr) + strlen(actionStr) + 1) * sizeof(char)); sprintf(fwRule, "-A INPUT %s%s%s%s", hostStr, protStr, portStr, actionStr); + if(actionStr) { + os_free(actionStr); + } + if (host) { + os_free(hostStr); + os_free(portStr); + } + if (prot) { + os_free(protStr); + } return fwRule; } @@ -287,15 +300,20 @@ os_setPort( } if (!done) { /* Build a new rule and insert it*/ + char **old_fw = fw; + fwRule = newRule(&host, prot, state); if (fwRule != NULL && (fw = insertRule(fw, fwRule)) != NULL) { setFirewall(fw); + os_free(fwRule); + os_free(old_fw); } else { printf("Failed to insert new rule\n"); if(fwRule == NULL) { printf("Rule creation failed\n"); } else { printf("Rule insertion failed\n"); + os_free(fwRule); } result = os_resultFail; } @@ -314,7 +332,7 @@ os_setPort( struct sockaddr_in resolveHost(char *hostStr, int port) { - struct sockaddr_in result; + struct sockaddr_in result={0}; result.sin_family = AF_INET; result.sin_port = htons(port); if (hostStr != NULL) { diff --git a/testsuite/tests/durability/common/fwctrl/code/os_firewall.h b/testsuite/tests/durability/common/fwctrl/code/os_firewall.h index fc048c3a1..a55361ed8 100644 --- a/testsuite/tests/durability/common/fwctrl/code/os_firewall.h +++ b/testsuite/tests/durability/common/fwctrl/code/os_firewall.h @@ -1,8 +1,9 @@ /* - * OpenSplice DDS + * Vortex OpenSplice * - * This software and documentation are Copyright 2006 to TO_YEAR PrismTech - * Limited, its affiliated companies and licensors. All rights reserved. + * This software and documentation are Copyright 2006 to TO_YEAR ADLINK + * Technology Limited, its affiliated companies and licensors. All rights + * reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/testsuite/tests/stax/epydoc.sh b/testsuite/tests/stax/epydoc.sh index 66d62a751..b07c2ee81 100755 --- a/testsuite/tests/stax/epydoc.sh +++ b/testsuite/tests/stax/epydoc.sh @@ -2,6 +2,6 @@ -epydoc -v -o ../docs/epydocs --name test_ospl --css white --url http://www.opensplice.org --dotpath /cygdrive/c/Program\ Files/Graphviz2.26.3/bin/ --inheritance listed --graph all test_ospl +epydoc -v -o ../docs/epydocs --name test_ospl --css white --url http://www.prismtech.com/dds-community --dotpath /cygdrive/c/Program\ Files/Graphviz2.26.3/bin/ --inheritance listed --graph all test_ospl diff --git a/testsuite/tests/stax/test_ospl.html b/testsuite/tests/stax/test_ospl.html index 1d78f8545..763d7bddf 100644 --- a/testsuite/tests/stax/test_ospl.html +++ b/testsuite/tests/stax/test_ospl.html @@ -570,7 +570,7 @@

    test_ospl.xml

    location

    - The STAF URL of the machine of which you wish to start OpenSplice DDS on + The STAF URL of the machine of which you wish to start Vortex OpenSplice on

    NoNo'local' @@ -624,7 +624,7 @@

    test_ospl.xml

    location

    - The STAF daemon URI of the machine of which you wish to stop an OpenSplice DDS domain on. + The STAF daemon URI of the machine of which you wish to stop a Vortex OpenSplice domain on.

    NoNo'local' @@ -752,4 +752,4 @@

    test_ospl.xml

    - \ No newline at end of file + diff --git a/testsuite/tests/stax/test_ospl.xml b/testsuite/tests/stax/test_ospl.xml index 185a8b3ab..8df455699 100755 --- a/testsuite/tests/stax/test_ospl.xml +++ b/testsuite/tests/stax/test_ospl.xml @@ -4,7 +4,7 @@